Repository: OpenFreeEnergy/openfe Branch: main Commit: cb10892e79a2 Files: 465 Total size: 4.5 MB Directory structure: gitextract_wx9d1k3u/ ├── .dockerignore ├── .git-blame-ignore-revs ├── .gitattributes ├── .github/ │ ├── CONTRIBUTING.md │ ├── PULL_REQUEST_TEMPLATE/ │ │ └── release_template.md │ ├── pull_request_template.md │ └── workflows/ │ ├── aws-cpu-long-tests.yaml │ ├── aws-gpu-integration-tests.yaml │ ├── ci.yaml │ ├── clean-pr-caches.yaml │ ├── cron-conda.yaml │ ├── cron-docker.yaml │ ├── cron-feedstock-build-tests.yaml │ ├── cron-package-test.yaml │ ├── griffe-api-break.yaml │ ├── mypy.yaml │ ├── release-docker-image.yaml │ ├── release-installers.yaml │ ├── release-make-condalock.yaml │ ├── release-prep-examplenotebooks.yaml │ └── release-prep-feedstock.yaml ├── .gitignore ├── .pre-commit-config.yaml ├── .readthedocs.yaml ├── CITATION.cff ├── Code_of_Conduct.md ├── LICENSE ├── MANIFEST.in ├── README.md ├── codecov.yml ├── devtools/ │ ├── data/ │ │ ├── fix_rbfe_results.py │ │ └── gen_serialized_results.py │ ├── debug_openmm.sh │ └── installer/ │ └── construct.yaml ├── docs/ │ ├── CHANGELOG.rst │ ├── Makefile │ ├── _ext/ │ │ └── sass.py │ ├── _sass/ │ │ └── deflist-flowchart.scss │ ├── _templates/ │ │ └── autosummary/ │ │ ├── base.rst │ │ └── class.rst │ ├── conf.py │ ├── cookbook/ │ │ ├── bespoke_parameters.nblink │ │ ├── choose_protocol.nblink │ │ ├── create_alchemical_network.nblink │ │ ├── dumping_transformation.rst │ │ ├── generate_ligand_network.nblink │ │ ├── hand_write_ligand_network.nblink │ │ ├── index.rst │ │ ├── jq_inspection.rst │ │ ├── ligandnetwork_vis.nblink │ │ ├── loading_molecules.nblink │ │ ├── network_from_orion_fepp.nblink │ │ ├── rfe_alchemical_planners.nblink │ │ └── user_charges.nblink │ ├── environment.yaml │ ├── guide/ │ │ ├── cli/ │ │ │ ├── cli_basics.rst │ │ │ ├── cli_yaml.rst │ │ │ └── index.rst │ │ ├── execution/ │ │ │ ├── execution_theory.rst │ │ │ ├── index.rst │ │ │ └── quickrun_execution.rst │ │ ├── index.rst │ │ ├── introduction.rst │ │ ├── protocols/ │ │ │ ├── absolutebinding.rst │ │ │ ├── absolutesolvation.rst │ │ │ ├── index.rst │ │ │ ├── plainmd.rst │ │ │ ├── relativehybridtopology.rst │ │ │ └── septop.rst │ │ ├── results/ │ │ │ ├── index.rst │ │ │ ├── working_with_networks.rst │ │ │ └── working_with_results.rst │ │ ├── setup/ │ │ │ ├── alchemical_network_model.rst │ │ │ ├── chemical_systems_and_thermodynamic_cycles.rst │ │ │ ├── creating_atom_mappings_and_scores.rst │ │ │ ├── creating_ligand_networks.rst │ │ │ ├── defining_protocols.rst │ │ │ └── index.rst │ │ ├── troubleshooting.rst │ │ └── under_the_hood.rst │ ├── index.rst │ ├── installation.rst │ ├── make.bat │ ├── reference/ │ │ ├── api/ │ │ │ ├── alchemical_network_planning.rst │ │ │ ├── atom_mappers.rst │ │ │ ├── defining_and_executing_simulations.rst │ │ │ ├── index.rst │ │ │ ├── ligand_network.rst │ │ │ ├── openmm_binding_afe.rst │ │ │ ├── openmm_md.rst │ │ │ ├── openmm_protocol_settings.rst │ │ │ ├── openmm_rfe.rst │ │ │ ├── openmm_septop.rst │ │ │ ├── openmm_solvation_afe.rst │ │ │ └── systems_and_components.rst │ │ ├── cli/ │ │ │ ├── charge_molecules.rst │ │ │ ├── gather.rst │ │ │ ├── index.rst │ │ │ ├── plan_rbfe_network.rst │ │ │ ├── plan_rhfe_network.rst │ │ │ └── quickrun.rst │ │ └── index.rst │ └── tutorials/ │ ├── .gitignore │ ├── abfe_analysis_tutorial.nblink │ ├── abfe_tutorial.nblink │ ├── ahfe_tutorial.nblink │ ├── charge_molecules_cli_tutorial.rst │ ├── index.rst │ ├── md_tutorial.nblink │ ├── plotting_with_cinnabar.nblink │ ├── rbfe_cli_tutorial.rst │ ├── rbfe_membrane_protein.nblink │ ├── rbfe_python_tutorial.nblink │ ├── septop_analysis_tutorial.nblink │ ├── septop_tutorial.nblink │ └── showcase_notebook.nblink ├── environment.yml ├── news/ │ └── TEMPLATE.rst ├── production/ │ ├── Dockerfile │ └── environment.yml ├── pyproject.toml ├── rever.xsh └── src/ ├── openfe/ │ ├── __init__.py │ ├── analysis/ │ │ ├── __init__.py │ │ └── plotting.py │ ├── data/ │ │ ├── __init__.py │ │ ├── _downloader.py │ │ └── _registry.py │ ├── due.py │ ├── orchestration/ │ │ └── __init__.py │ ├── protocols/ │ │ ├── __init__.py │ │ ├── openmm_afe/ │ │ │ ├── __init__.py │ │ │ ├── abfe_units.py │ │ │ ├── afe_protocol_results.py │ │ │ ├── ahfe_units.py │ │ │ ├── base_afe_units.py │ │ │ ├── equil_afe_settings.py │ │ │ ├── equil_binding_afe_method.py │ │ │ └── equil_solvation_afe_method.py │ │ ├── openmm_md/ │ │ │ ├── __init__.py │ │ │ ├── plain_md_methods.py │ │ │ └── plain_md_settings.py │ │ ├── openmm_rfe/ │ │ │ ├── __init__.py │ │ │ ├── _rfe_utils/ │ │ │ │ ├── __init__.py │ │ │ │ ├── lambdaprotocol.py │ │ │ │ ├── multistate.py │ │ │ │ ├── relative.py │ │ │ │ └── topologyhelpers.py │ │ │ ├── equil_rfe_methods.py │ │ │ ├── equil_rfe_settings.py │ │ │ ├── hybridtop_protocol_results.py │ │ │ ├── hybridtop_protocols.py │ │ │ └── hybridtop_units.py │ │ ├── openmm_septop/ │ │ │ ├── __init__.py │ │ │ ├── base_units.py │ │ │ ├── equil_septop_method.py │ │ │ ├── equil_septop_settings.py │ │ │ ├── septop_protocol_results.py │ │ │ ├── septop_units.py │ │ │ └── utils.py │ │ ├── openmm_utils/ │ │ │ ├── __init__.py │ │ │ ├── charge_generation.py │ │ │ ├── mdtraj_utils.py │ │ │ ├── multistate_analysis.py │ │ │ ├── omm_compute.py │ │ │ ├── omm_settings.py │ │ │ ├── serialization.py │ │ │ ├── settings_validation.py │ │ │ ├── system_creation.py │ │ │ └── system_validation.py │ │ └── restraint_utils/ │ │ ├── __init__.py │ │ ├── geometry/ │ │ │ ├── __init__.py │ │ │ ├── base.py │ │ │ ├── boresch/ │ │ │ │ ├── __init__.py │ │ │ │ ├── geometry.py │ │ │ │ ├── guest.py │ │ │ │ └── host.py │ │ │ ├── flatbottom.py │ │ │ ├── harmonic.py │ │ │ └── utils.py │ │ ├── openmm/ │ │ │ ├── __init__.py │ │ │ ├── omm_forces.py │ │ │ └── omm_restraints.py │ │ └── settings.py │ ├── setup/ │ │ ├── __init__.py │ │ ├── alchemical_network_planner/ │ │ │ ├── __init__.py │ │ │ ├── abstract_alchemical_network_planner.py │ │ │ └── relative_alchemical_network_planner.py │ │ ├── atom_mapping/ │ │ │ ├── __init__.py │ │ │ ├── ligandatommapper.py │ │ │ ├── lomap_mapper.py │ │ │ ├── lomap_scorers.py │ │ │ ├── perses_mapper.py │ │ │ └── perses_scorers.py │ │ ├── chemicalsystem_generator/ │ │ │ ├── __init__.py │ │ │ ├── abstract_chemicalsystem_generator.py │ │ │ └── easy_chemicalsystem_generator.py │ │ └── ligand_network_planning.py │ ├── storage/ │ │ ├── __init__.py │ │ ├── metadatastore.py │ │ ├── resultclient.py │ │ └── resultserver.py │ ├── tests/ │ │ ├── __init__.py │ │ ├── analysis/ │ │ │ ├── __init__.py │ │ │ └── test_plotting.py │ │ ├── conftest.py │ │ ├── data/ │ │ │ ├── 181l_only.pdb │ │ │ ├── CN.sdf │ │ │ ├── __init__.py │ │ │ ├── a2a/ │ │ │ │ └── __init__.py │ │ │ ├── benzene_modifications.sdf │ │ │ ├── cdk8/ │ │ │ │ ├── __init__.py │ │ │ │ ├── cdk8_ligands.sdf │ │ │ │ └── cdk8_protein.pdb │ │ │ ├── eg5/ │ │ │ │ ├── __init__.py │ │ │ │ ├── eg5_cofactor.sdf │ │ │ │ ├── eg5_ligands.sdf │ │ │ │ └── eg5_protein.pdb │ │ │ ├── external_formats/ │ │ │ │ ├── __init__.py │ │ │ │ └── somebenzenes_edges.edge │ │ │ ├── htf/ │ │ │ │ ├── __init__.py │ │ │ │ ├── chloroethane.sdf │ │ │ │ ├── ethane.sdf │ │ │ │ ├── fluoroethane.sdf │ │ │ │ └── t4_lysozyme_data/ │ │ │ │ ├── benzene.sdf │ │ │ │ ├── chlorobenzene.sdf │ │ │ │ └── fluorobenzene.sdf │ │ │ ├── lomap_basic/ │ │ │ │ ├── 1,3,7-trimethylnaphthalene.mol2 │ │ │ │ ├── 1-butyl-4-methylbenzene.mol2 │ │ │ │ ├── 2,6-dimethylnaphthalene.mol2 │ │ │ │ ├── 2-methyl-6-propylnaphthalene.mol2 │ │ │ │ ├── 2-methylnaphthalene.mol2 │ │ │ │ ├── 2-naftanol.mol2 │ │ │ │ ├── README.md │ │ │ │ ├── __init__.py │ │ │ │ ├── methylcyclohexane.mol2 │ │ │ │ └── toluene.mol2 │ │ │ ├── multi_molecule.sdf │ │ │ ├── openmm_afe/ │ │ │ │ ├── T4_abfe_system.xml.bz2 │ │ │ │ └── __init__.py │ │ │ ├── openmm_md/ │ │ │ │ └── __init__.py │ │ │ ├── openmm_rfe/ │ │ │ │ ├── __init__.py │ │ │ │ ├── benzene_toluene_hybrid_top/ │ │ │ │ │ ├── hybrid_topology_atoms.csv │ │ │ │ │ └── hybrid_topology_bonds.txt │ │ │ │ ├── charged_benzenes.sdf │ │ │ │ ├── dummy_charge_ligand_23.sdf │ │ │ │ ├── dummy_charge_ligand_55.sdf │ │ │ │ ├── ligand_23.sdf │ │ │ │ ├── ligand_55.sdf │ │ │ │ ├── malt1_shapefit_1832577-09-9.sdf │ │ │ │ ├── malt1_shapefit_Pfizer-01-01.sdf │ │ │ │ ├── reference.xml │ │ │ │ ├── vacuum_nocoord.nc │ │ │ │ └── vacuum_nocoord_checkpoint.nc │ │ │ ├── openmm_septop/ │ │ │ │ ├── __init__.py │ │ │ │ └── system.xml.bz2 │ │ │ └── serialization/ │ │ │ ├── __init__.py │ │ │ ├── ethane_template.sdf │ │ │ └── network_template.graphml │ │ ├── dev/ │ │ │ ├── __init__.py │ │ │ └── serialization_test_templates.py │ │ ├── protocols/ │ │ │ ├── __init__.py │ │ │ ├── conftest.py │ │ │ ├── openmm_abfe/ │ │ │ │ ├── __init__.py │ │ │ │ ├── conftest.py │ │ │ │ ├── test_abfe_energies.py │ │ │ │ ├── test_abfe_protocol.py │ │ │ │ ├── test_abfe_protocol_results.py │ │ │ │ ├── test_abfe_settings.py │ │ │ │ ├── test_abfe_slow.py │ │ │ │ ├── test_abfe_tokenization.py │ │ │ │ ├── test_abfe_validation.py │ │ │ │ └── utils.py │ │ │ ├── openmm_ahfe/ │ │ │ │ ├── __init__.py │ │ │ │ ├── test_ahfe_protocol.py │ │ │ │ ├── test_ahfe_protocol_results.py │ │ │ │ ├── test_ahfe_resume.py │ │ │ │ ├── test_ahfe_settings.py │ │ │ │ ├── test_ahfe_slow.py │ │ │ │ ├── test_ahfe_tokenization.py │ │ │ │ ├── test_ahfe_validation.py │ │ │ │ └── utils.py │ │ │ ├── openmm_md/ │ │ │ │ ├── __init__.py │ │ │ │ ├── test_plain_md_protocol.py │ │ │ │ ├── test_plain_md_resume.py │ │ │ │ ├── test_plain_md_slow.py │ │ │ │ └── test_plain_md_tokenization.py │ │ │ ├── openmm_rfe/ │ │ │ │ ├── __init__.py │ │ │ │ ├── helpers.py │ │ │ │ ├── test_hybrid_factory.py │ │ │ │ ├── test_hybrid_top_protocol.py │ │ │ │ ├── test_hybrid_top_resume.py │ │ │ │ ├── test_hybrid_top_slow.py │ │ │ │ ├── test_hybrid_top_tokenization.py │ │ │ │ └── test_hybrid_top_validation.py │ │ │ ├── openmm_septop/ │ │ │ │ ├── __init__.py │ │ │ │ ├── conftest.py │ │ │ │ ├── test_septop_protocol.py │ │ │ │ ├── test_septop_protocol_results.py │ │ │ │ ├── test_septop_resume.py │ │ │ │ ├── test_septop_settings.py │ │ │ │ ├── test_septop_slow.py │ │ │ │ ├── test_septop_tokenization.py │ │ │ │ ├── test_septop_validation.py │ │ │ │ └── utils.py │ │ │ ├── restraints/ │ │ │ │ ├── __init__.py │ │ │ │ ├── test_geometry_base.py │ │ │ │ ├── test_geometry_boresch.py │ │ │ │ ├── test_geometry_boresch_guest.py │ │ │ │ ├── test_geometry_boresch_host.py │ │ │ │ ├── test_geometry_flatbottom.py │ │ │ │ ├── test_geometry_harmonic.py │ │ │ │ ├── test_geometry_utils.py │ │ │ │ ├── test_omm_restraints.py │ │ │ │ ├── test_openmm_forces.py │ │ │ │ └── test_settings.py │ │ │ ├── test_openmm_settings.py │ │ │ ├── test_openmmutils.py │ │ │ └── test_openmmutils_serialization.py │ │ ├── setup/ │ │ │ ├── __init__.py │ │ │ ├── alchemical_network_planner/ │ │ │ │ ├── __init__.py │ │ │ │ ├── edge_types.py │ │ │ │ └── test_relative_alchemical_network_planner.py │ │ │ ├── atom_mapping/ │ │ │ │ ├── __init__.py │ │ │ │ ├── conftest.py │ │ │ │ ├── test_atommapper.py │ │ │ │ ├── test_lomap_atommapper.py │ │ │ │ ├── test_lomap_scorers.py │ │ │ │ ├── test_perses_atommapper.py │ │ │ │ └── test_perses_scorers.py │ │ │ ├── chemicalsystem_generator/ │ │ │ │ ├── __init__.py │ │ │ │ ├── component_checks.py │ │ │ │ └── test_easy_chemicalsystem_generator.py │ │ │ └── test_network_planning.py │ │ ├── storage/ │ │ │ ├── __init__.py │ │ │ ├── conftest.py │ │ │ ├── test_metadatastore.py │ │ │ ├── test_resultclient.py │ │ │ └── test_resultserver.py │ │ └── utils/ │ │ ├── __init__.py │ │ ├── conftest.py │ │ ├── test_atommapping_network_plotting.py │ │ ├── test_duecredit.py │ │ ├── test_log_control.py │ │ ├── test_network_plotting.py │ │ ├── test_optional_imports.py │ │ ├── test_remove_oechem.py │ │ ├── test_system_probe.py │ │ └── test_visualization_3D.py │ └── utils/ │ ├── __init__.py │ ├── atommapping_network_plotting.py │ ├── custom_typing.py │ ├── ligand_utils.py │ ├── logging_control.py │ ├── network_plotting.py │ ├── optional_imports.py │ ├── remove_oechem.py │ ├── silence_root_logging.py │ ├── system_probe.py │ └── visualization_3D.py └── openfecli/ ├── README.md ├── __init__.py ├── cli.py ├── clicktypes/ │ ├── __init__.py │ └── hyphenchoice.py ├── commands/ │ ├── __init__.py │ ├── atommapping.py │ ├── fetch.py │ ├── gather.py │ ├── gather_abfe.py │ ├── gather_septop.py │ ├── generate_partial_charges.py │ ├── plan_rbfe_network.py │ ├── plan_rhfe_network.py │ ├── quickrun.py │ ├── test.py │ └── view_ligand_network.py ├── data/ │ ├── __init__.py │ └── _registry.py ├── fetchables.py ├── fetching.py ├── parameters/ │ ├── __init__.py │ ├── mapper.py │ ├── misc.py │ ├── mol.py │ ├── molecules.py │ ├── output.py │ ├── output_dir.py │ ├── plan_network_options.py │ ├── protein.py │ └── utils.py ├── plan_alchemical_networks_utils.py ├── plugins.py ├── tests/ │ ├── __init__.py │ ├── clicktypes/ │ │ └── test_hyphenchoice.py │ ├── commands/ │ │ ├── __init__.py │ │ ├── conftest.py │ │ ├── test_atommapping.py │ │ ├── test_charge_generation.py │ │ ├── test_gather/ │ │ │ ├── test_abfe_full_results_multiple_units_dg_.tsv │ │ │ ├── test_abfe_full_results_multiple_units_raw_.tsv │ │ │ ├── test_abfe_full_results_single_unit_dg_.tsv │ │ │ ├── test_abfe_full_results_single_unit_raw_.tsv │ │ │ ├── test_abfe_single_repeat_multiple_units_dg_.tsv │ │ │ ├── test_abfe_single_repeat_multiple_units_raw_.tsv │ │ │ ├── test_abfe_single_repeat_single_unit_dg_.tsv │ │ │ ├── test_abfe_single_repeat_single_unit_raw_.tsv │ │ │ ├── test_cmet_failed_edge_ddg_.tsv │ │ │ ├── test_cmet_failed_edge_raw_.tsv │ │ │ ├── test_cmet_full_results_ddg_.tsv │ │ │ ├── test_cmet_full_results_dg_.tsv │ │ │ ├── test_cmet_full_results_raw_.tsv │ │ │ ├── test_cmet_missing_all_complex_legs_allow_partial_ddg_.tsv │ │ │ ├── test_cmet_missing_all_complex_legs_fail_ddg_.tsv │ │ │ ├── test_cmet_missing_all_complex_legs_fail_dg_.tsv │ │ │ ├── test_cmet_missing_complex_leg_ddg_.tsv │ │ │ ├── test_cmet_missing_complex_leg_dg_.tsv │ │ │ ├── test_cmet_missing_complex_leg_raw_.tsv │ │ │ ├── test_cmet_missing_edge_ddg_.tsv │ │ │ ├── test_cmet_missing_edge_dg_.tsv │ │ │ ├── test_cmet_missing_edge_raw_.tsv │ │ │ ├── test_septop_full_results_ddg_current_.tsv │ │ │ ├── test_septop_full_results_ddg_pre_openfe_v1_11_.tsv │ │ │ ├── test_septop_full_results_dg_current_.tsv │ │ │ ├── test_septop_full_results_dg_pre_openfe_v1_11_.tsv │ │ │ ├── test_septop_full_results_raw_current_.tsv │ │ │ ├── test_septop_full_results_raw_pre_openfe_v1_11_.tsv │ │ │ ├── test_septop_single_repeat_ddg_current_.tsv │ │ │ ├── test_septop_single_repeat_ddg_pre_openfe_v1_11_.tsv │ │ │ ├── test_septop_single_repeat_dg_current_.tsv │ │ │ ├── test_septop_single_repeat_dg_pre_openfe_v1_11_.tsv │ │ │ ├── test_septop_single_repeat_raw_current_.tsv │ │ │ └── test_septop_single_repeat_raw_pre_openfe_v1_11_.tsv │ │ ├── test_gather.py │ │ ├── test_ligand_network_viewer.py │ │ ├── test_plan_rbfe_network.py │ │ ├── test_plan_rhfe_network.py │ │ ├── test_quickrun.py │ │ └── test_test.py │ ├── conftest.py │ ├── data/ │ │ ├── __init__.py │ │ ├── bad_transformation.json │ │ ├── rbfe_tutorial/ │ │ │ ├── __init__.py │ │ │ ├── tyk2_ligands.sdf │ │ │ └── tyk2_protein.pdb │ │ └── transformation.json │ ├── dev/ │ │ ├── __init__.py │ │ └── write_transformation_json.py │ ├── parameters/ │ │ ├── __init__.py │ │ ├── test_mapper.py │ │ ├── test_mol.py │ │ ├── test_molecules.py │ │ ├── test_output.py │ │ ├── test_output_dir.py │ │ ├── test_plan_network_options.py │ │ ├── test_protein.py │ │ └── test_utils.py │ ├── test_cli.py │ ├── test_fetchables.py │ ├── test_fetching.py │ ├── test_plugins.py │ ├── test_rbfe_tutorial.py │ ├── test_utils.py │ └── utils.py └── utils.py ================================================ FILE CONTENTS ================================================ ================================================ FILE: .dockerignore ================================================ # Ignore everything * # Only allow !production/environment.yml ================================================ FILE: .git-blame-ignore-revs ================================================ # https://github.com/OpenFreeEnergy/openfe/pull/1604 - ruff formatting part 1 3a08b6809fc57662e4146db3c7ccedfbc7c7c8df # https://github.com/OpenFreeEnergy/openfe/pull/1610 - ruff formatting part 2 2311a2f2d956dd30e95c180841ce19b921d89e1f # https://github.com/OpenFreeEnergy/openfe/pull/1622 - ruff formatting part 3 d7196d119e2f65d88e488afc665f2521e4f68042 # https://github.com/OpenFreeEnergy/openfe/pull/1623 - ruff formatting part 4 036869ae81670c6dcfa2532f125ee88c3f35936c # https://github.com/OpenFreeEnergy/openfe/pull/1665 - ruff isort 588f552ca9200a99fd77aed993ea3766b154ee53 # https://github.com/OpenFreeEnergy/openfe/pull/1667 - ruff f-strings and whitespace 18f211db974cdde38a5d88d6e74aaaf78fda8897 # https://github.com/OpenFreeEnergy/openfe/pull/1668 - ruff pycodestyle changes b693d37c8ac0e30283bd8b5f13386fdc98901cf8 ================================================ FILE: .gitattributes ================================================ ================================================ FILE: .github/CONTRIBUTING.md ================================================ # Contributing to OpenFE Thanks for contributing to the OpenFE software project! Read our [code of conduct](../Code_of_Conduct.md) to understand the standards you must adhere to. ## Questions If you have any questions on using the OpenFE package, reach out on the "Discussions" tab above to start a conversation! We are happy to get you started in using our software. ## Issues If you think you have encountered a software issue, please raise this on the "Issues" tab in Github. In general the more details you can provide the better, we recommend reading section 3.3 of [this article](https://livecomsjournal.org/index.php/livecoms/article/view/v3i1e1473) to understand the problem solving process. ## Contributing We welcome any fixes or code contributions. Note that any contributions made must be made under a MIT license. Feel free to reach out to the developer team who can assist you in this process. ================================================ FILE: .github/PULL_REQUEST_TEMPLATE/release_template.md ================================================ Make the PR: * [ ] Create a new release prep branch corresponding to the version name, e.g. `release/v1.2.0`. Note: please follow [semantic versioning](https://semver.org/). * [ ] Check that all user-relevant updates are included in the `news/` rever `.rst` files. You can backfill any additional items by making a new .rst, e.g. `backfill.rst` * [ ] Run [rever](https://regro.github.io/rever-docs/index.html#), e.g. `rever 1.2.0`. This will auto-commit `docs/CHANGELOG.md` and remove the `.rst` files from `news/`. * [ ] Verify that`docs/CHANGELOG.rst` looks correct and that it renders as expected in the docs preview. * [ ] If needed, create a release of the [example notebooks repository](https://github.com/OpenFreeEnergy/ExampleNotebooks) and update the pinned release version in the `openfe/docs/conf.py`. * [ ] Make the PR and verify that CI/CD passes. * [ ] [feedstock packaging tests](https://github.com/OpenFreeEnergy/openfe/actions/workflows/release-prep-feedstock.yaml) * [ ] [example notebooks](https://github.com/OpenFreeEnergy/openfe/actions/workflows/release-prep-examplenotebooks.yaml) * [ ] [GPU tests](https://github.com/OpenFreeEnergy/openfe/actions/workflows/aws-gpu-integration-tests.yaml) * [ ] Merge the PR into `main`. After Merging the PR [follow this guide](https://github.com/OpenFreeEnergy/openfe/wiki/How-to-create-a-new-release) ================================================ FILE: .github/pull_request_template.md ================================================ Checklist * [ ] All new code is appropriately documented (user-facing code _must_ have complete docstrings). * [ ] Added a ``news`` entry, or the changes are not user-facing. * [ ] Ran pre-commit: you can run [pre-commit](https://pre-commit.com) locally or comment on this PR with `pre-commit.ci autofix`. Manual Tests: these are slow so don't need to be run every commit, only before merging and when relevant changes are made (generally at reviewer-discretion). * [ ] [GPU integration tests](https://github.com/OpenFreeEnergy/openfe/actions/workflows/aws-gpu-integration-tests.yaml) * [ ] [example notebook testing](https://github.com/OpenFreeEnergy/openfe/actions/workflows/release-prep-examplenotebooks.yaml) * [ ] [packaging tests](https://github.com/OpenFreeEnergy/openfe/actions/workflows/cron-package-test.yaml): run this for any large feature PRs or PRs that add test data. ## Developers certificate of origin - [ ] I certify that this contribution is covered by the MIT License [here](https://github.com/OpenFreeEnergy/openfe/blob/main/LICENSE) and the **Developer Certificate of Origin** at . ================================================ FILE: .github/workflows/aws-cpu-long-tests.yaml ================================================ name: "manual AWS: CPU long tests" on: workflow_dispatch: jobs: start-aws-runner: runs-on: ubuntu-latest permissions: id-token: write contents: read outputs: mapping: ${{ steps.aws-start.outputs.mapping }} steps: - name: Configure AWS credentials uses: aws-actions/configure-aws-credentials@v4 with: role-to-assume: arn:aws:iam::010438489691:role/GHARunnerAWS aws-region: us-east-2 - name: Create cloud runner id: aws-start uses: omsf/start-aws-gha-runner@v1.0.0 with: aws_image_id: ami-0b7f661c228e6a4bb aws_instance_type: c7i.xlarge aws_home_dir: /home/ubuntu aws_root_device_size: 125 env: GH_PAT: ${{ secrets.GH_PAT }} self-hosted-test: runs-on: self-hosted timeout-minutes: 720 # 12 hours defaults: run: shell: bash -leo pipefail {0} env: OE_LICENSE: ${{ github.workspace }}/oe_license.txt needs: - start-aws-runner steps: - uses: actions/checkout@v4 - name: Print disk usage run: "df -h" - name: Print Docker details run: "docker version || true" - name: "Setup Micromamba" uses: mamba-org/setup-micromamba@v2 with: environment-file: environment.yml environment-name: openfe_env condarc: | channels: - conda-forge - openeye create-args: >- espaloma_charge==0.0.8 espaloma==0.4.0 openeye-toolkits python=3.12 - name: "Check if OpenMM can get a GPU" run: python -m openmm.testInstallation - name: "Install" run: python -m pip install --no-deps -e . - name: "Test imports" run: | # if we add more to this, consider changing to for + env vars python -Ic "import openfe; print(openfe.__version__)" - name: "Environment Information" run: | micromamba info micromamba list pip list - name: Test OE License & Write License to File env: OE_LICENSE_TEXT: ${{ secrets.OE_LICENSE }} run: | echo "${OE_LICENSE_TEXT}" > ${OE_LICENSE} python -c "import openeye; assert openeye.oechem.OEChemIsLicensed(), 'OpenEye license checks failed!'" - name: "Run tests" env: OFE_SLOW_TESTS: "true" DUECREDIT_ENABLE: 'yes' OFE_INTEGRATION_TESTS: FALSE run: | pytest -n logical -vv --durations=10 --runslow src/openfecli/tests/ src/openfe/tests/ stop-aws-runner: runs-on: ubuntu-latest permissions: id-token: write contents: read needs: - start-aws-runner - self-hosted-test if: ${{ always() }} steps: - name: Configure AWS credentials uses: aws-actions/configure-aws-credentials@v4 with: role-to-assume: arn:aws:iam::010438489691:role/GHARunnerAWS aws-region: us-east-2 - name: Stop instances uses: omsf/stop-aws-gha-runner@v1.0.0 with: instance_mapping: ${{ needs.start-aws-runner.outputs.mapping }} env: GH_PAT: ${{ secrets.GH_PAT }} ================================================ FILE: .github/workflows/aws-gpu-integration-tests.yaml ================================================ name: "manual AWS: GPU integration tests" on: workflow_dispatch: jobs: start-aws-runner: runs-on: ubuntu-latest permissions: id-token: write contents: read outputs: mapping: ${{ steps.aws-start.outputs.mapping }} steps: - name: Configure AWS credentials uses: aws-actions/configure-aws-credentials@v4 with: role-to-assume: arn:aws:iam::010438489691:role/GHARunnerAWS aws-region: us-east-2 - name: Create cloud runner id: aws-start uses: omsf/start-aws-gha-runner@v1.0.0 with: aws_image_id: ami-076a54ed41e67782d aws_instance_type: g4dn.xlarge aws_home_dir: /home/ubuntu aws_root_device_size: 125 env: GH_PAT: ${{ secrets.GH_PAT }} self-hosted-test: runs-on: self-hosted timeout-minutes: 720 # 12 hours defaults: run: shell: bash -leo pipefail {0} env: OE_LICENSE: ${{ github.workspace }}/oe_license.txt needs: - start-aws-runner steps: - uses: actions/checkout@v4 - name: Print disk usage run: "df -h" - name: Print Docker details run: "docker version || true" - name: Check for nvidia-smi run: "nvidia-smi" - name: "Setup Micromamba" uses: mamba-org/setup-micromamba@v2 with: environment-file: environment.yml environment-name: openfe_env condarc: | channels: - conda-forge - openeye create-args: >- espaloma_charge==0.0.8 espaloma==0.4.0 openeye-toolkits python=3.12 cuda-version=12.8 - name: "Check if OpenMM can get a GPU" run: python -m openmm.testInstallation - name: "Install" run: python -m pip install --no-deps -e . - name: "Test imports" run: | # if we add more to this, consider changing to for + env vars python -Ic "import openfe; print(openfe.__version__)" - name: "Environment Information" run: | micromamba info micromamba list pip list - name: Test OE License & Write License to File env: OE_LICENSE_TEXT: ${{ secrets.OE_LICENSE }} run: | echo "${OE_LICENSE_TEXT}" > ${OE_LICENSE} python -c "import openeye; assert openeye.oechem.OEChemIsLicensed(), 'OpenEye license checks failed!'" - name: "Run tests" env: DUECREDIT_ENABLE: 'yes' OFE_INTEGRATION_TESTS: TRUE run: | # The -m flag will only run tests with @pytest.mark.integration pytest -n logical -vv --durations=10 -m integration src/openfecli/tests/ src/openfe/tests/ stop-aws-runner: runs-on: ubuntu-latest permissions: id-token: write contents: read needs: - start-aws-runner - self-hosted-test if: ${{ always() }} steps: - name: Configure AWS credentials uses: aws-actions/configure-aws-credentials@v4 with: role-to-assume: arn:aws:iam::010438489691:role/GHARunnerAWS aws-region: us-east-2 - name: Stop instances uses: omsf/stop-aws-gha-runner@v1.0.0 with: instance_mapping: ${{ needs.start-aws-runner.outputs.mapping }} env: GH_PAT: ${{ secrets.GH_PAT }} ================================================ FILE: .github/workflows/ci.yaml ================================================ name: "CI" on: pull_request: # Skip CI if changed files only affect the following folders # - docs: documentation changes don't need code validation # See here for more details: https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#example-excluding-paths paths-ignore: - "docs/*" - "news/*" - ".readthedocs.yaml" - ".github/workflows/cpu-long-tests.yaml" - ".github/workflows/gpu-integration-tests.yaml" push: branches: - main schedule: - cron: "0 4 * * *" workflow_dispatch: release: types: - published concurrency: group: "${{ github.workflow }}-${{ github.ref }}" cancel-in-progress: true defaults: run: shell: bash -leo pipefail {0} jobs: tests: runs-on: ${{ matrix.os }} name: "💻-${{matrix.os }} 🐍-${{ matrix.python-version }} oechem: ${{ matrix.openeye }}" strategy: fail-fast: false matrix: os: ["ubuntu-latest"] openeye: ["no"] python-version: - "3.11" - "3.12" - "3.13" include: - os: "ubuntu-latest" python-version: "3.13" openeye: "yes" - os: "macos-latest" python-version: "3.12" openeye: "no" env: OE_LICENSE: ${{ github.workspace }}/oe_license.txt steps: - uses: actions/checkout@v4 with: fetch-depth: 0 - name: Get current date id: date run: echo "date=$(date +%Y-%m-%d)" >> "${GITHUB_OUTPUT}" - name: "Setup Micromamba" if: ${{ matrix.python-version != '3.13' }} uses: mamba-org/setup-micromamba@v2 with: environment-file: environment.yml environment-name: openfe_env cache-environment: true cache-downloads: true cache-environment-key: environment-${{ steps.date.outputs.date }} cache-downloads-key: downloads-${{ steps.date.outputs.date }} create-args: >- espaloma=0.4.0 python=${{ matrix.python-version }} pydantic=${{ matrix.pydantic-version }} init-shell: bash - name: "Setup Micromamba" # Can't install espaloma with python 3.13 if: ${{ matrix.python-version == '3.13' }} uses: mamba-org/setup-micromamba@v2 with: environment-file: environment.yml environment-name: openfe_env cache-environment: true cache-downloads: true cache-environment-key: environment-${{ steps.date.outputs.date }} cache-downloads-key: downloads-${{ steps.date.outputs.date }} create-args: >- python=${{ matrix.python-version }} pydantic=${{ matrix.pydantic-version }} init-shell: bash - name: "Install OpenEye" if: ${{ !github.event.pull_request.head.repo.fork && matrix.openeye == 'yes' }} env: OE_LICENSE_TEXT: ${{ secrets.OE_LICENSE }} run: | echo "${OE_LICENSE_TEXT}" > ${OE_LICENSE} micromamba install -c openeye openeye-toolkits python -c "import openeye; assert openeye.oechem.OEChemIsLicensed(), 'oechem license check failed!'" - name: "Install" run: python -m pip install --no-deps -e . - name: "Environment Information" run: | micromamba info micromamba list pip list - name: "Test imports" run: | # if we add more to this, consider changing to for + env vars python -Ic "import openfe; print(openfe.__version__)" - name: Cache Pooch data uses: actions/cache@v4 with: path: | # linux cache location ~/.cache/openfe # osx cache location ~/Library/Caches/openfe # When files are added or changed in a pooch registry # bump this key to create a new cache, for example if # the key is pooch-${{ matrix.os }}-1 change it to pooch-${{ matrix.os }}-2 key: pooch-${{ matrix.os }}-1 - name: "Run tests" env: # Set the OFE_SLOW_TESTS to True if running a Cron job OFE_SLOW_TESTS: ${{ fromJSON('{"false":"false","true":"true"}')[github.event_name != 'pull_request'] }} DUECREDIT_ENABLE: 'yes' run: | pytest -n auto -v --cov=openfe --cov=openfecli --cov-report=xml --durations=10 - name: codecov-pr if: ${{ github.repository == 'OpenFreeEnergy/openfe' && github.event_name == 'pull_request' }} uses: codecov/codecov-action@v4 with: token: ${{ secrets.CODECOV_TOKEN }} file: coverage.xml fail_ci_if_error: False verbose: True flags: fast-tests - name: codecov-merge # we only want to upload a slow report if # 1) it isn't a schedule run # 2) it wasn't from a PR (we don't run slow tests on PRs) if: ${{ github.repository == 'OpenFreeEnergy/openfe' && github.event_name != 'schedule' && github.event_name != 'pull_request' }} uses: codecov/codecov-action@v4 with: token: ${{ secrets.CODECOV_TOKEN }} file: coverage.xml fail_ci_if_error: False verbose: True flags: slow-tests ================================================ FILE: .github/workflows/clean-pr-caches.yaml ================================================ # from https://docs.github.com/en/actions/how-tos/manage-workflow-runs/manage-caches#force-deleting-cache-entries name: "clean up github runner caches on closed pull requests" on: workflow_dispatch: pull_request: types: - closed jobs: cleanup: runs-on: ubuntu-latest permissions: actions: write steps: - name: Cleanup run: | echo "Fetching list of cache keys" cacheKeysForPR=$(gh cache list --ref $BRANCH --limit 100 --json id --jq '.[].id') ## Setting this to not fail the workflow while deleting cache keys. set +e echo "Deleting caches..." for cacheKey in $cacheKeysForPR do gh cache delete $cacheKey done echo "Done" env: GH_TOKEN: ${{ github.token }} GH_REPO: ${{ github.repository }} BRANCH: refs/pull/${{ github.event.pull_request.number }}/merge ================================================ FILE: .github/workflows/cron-conda.yaml ================================================ name: "cron: conda builds daily tests" on: workflow_dispatch: schedule: # At 05:00 UTC every day - cron: "0 5 * * *" concurrency: group: "${{ github.workflow }}-${{ github.ref }}" cancel-in-progress: true defaults: run: shell: bash -leo pipefail {0} jobs: condacheck: runs-on: ${{ matrix.OS }} name: "daily conda check" strategy: fail-fast: false matrix: os: ['ubuntu-latest'] python-version: - "3.11" - "3.12" - "3.13" include: - os: "macos-latest" python-version: "3.12" openeye: "no" steps: - name: Checkout Code uses: actions/checkout@v4 with: fetch-depth: 0 path: openfe_repo - name: Get Latest Version id: latest-version working-directory: openfe_repo run: | REPO="${{ github.repository }}" VERSION=$(curl -s -H "Authorization: Bearer ${{ secrets.GITHUB_TOKEN }}" \ "https://api.github.com/repos/$REPO/releases/latest" | jq -r '.tag_name | ltrimstr("v")') echo $VERSION echo "VERSION=$VERSION" >> $GITHUB_OUTPUT - name: Setup Micromamba and Install openfe uses: mamba-org/setup-micromamba@v2 with: environment-name: openfe create-args: >- python=${{ matrix.python-version }} openfe=${{ steps.latest-version.outputs.VERSION }} pytest pytest-xdist condarc: | channels: - conda-forge init-shell: bash - name: "env info" run: | micromamba info micromamba list - id: run-tests name: "Run tests" run: | # note: this only runs the fast tests pytest -n auto --pyargs openfe openfecli ================================================ FILE: .github/workflows/cron-docker.yaml ================================================ name: "cron: docker image daily tests" on: push: branches: - main schedule: # nightly tests - cron: "0 14 * * 0" workflow_dispatch: defaults: run: shell: bash -leo pipefail {0} env: REGISTRY: ghcr.io IMAGE_NAME: openfreeenergy/openfe jobs: build-and-push-image: runs-on: ubuntu-latest permissions: contents: read packages: write steps: - name: Checkout repository uses: actions/checkout@v4 - name: Use dev tag for nightly builds id: latest-version run: | VERSION=dev echo $VERSION echo "VERSION=$VERSION" >> $GITHUB_OUTPUT - name: Print Latest Version run: echo ${{ steps.latest-version.outputs.VERSION }} - name: Create fully qualified image registry path id: fqirp run: | FQIRP=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.latest-version.outputs.VERSION }} echo "FQIRP=$FQIRP" >> $GITHUB_OUTPUT - name: Print FQIRP run: echo ${{ steps.fqirp.outputs.FQIRP }} - name: Log in to the Container registry uses: docker/login-action@f054a8b539a109f9f41c372932f1ae047eff08c9 with: registry: ${{ env.REGISTRY }} username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} - name: Extract metadata (tags, labels) for Docker id: meta uses: docker/metadata-action@98669ae865ea3cffbcbaa878cf57c20bbf1c6c38 with: images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} tags: | type=schedule,pattern=nightly,enable=true,priority=1000 type=ref,event=branch,enable=true,priority=600 type=ref,event=tag,enable=true,priority=600 type=ref,event=pr,prefix=pr-,enable=true,priority=600 type=semver,pattern={{major}}.{{minor}} type=semver,pattern={{version}} type=sha ${{ steps.latest-version.outputs.VERSION }} - name: Build and export to Docker uses: docker/build-push-action@v6 with: context: . file: production/Dockerfile load: true tags: ${{ steps.meta.outputs.tags }} labels: ${{ steps.meta.outputs.labels }} - name: Test image run: | docker run --rm ${{ steps.fqirp.outputs.FQIRP }} openfe --help docker run --rm ${{ steps.fqirp.outputs.FQIRP }} openfe --version docker run --rm ${{ steps.fqirp.outputs.FQIRP }} python -c "import gufe; print(f'{gufe.__version__=}')" docker run --rm ${{ steps.fqirp.outputs.FQIRP }} pytest --pyargs gufe -v docker run --rm ${{ steps.fqirp.outputs.FQIRP }} pytest --pyargs openfe -v ================================================ FILE: .github/workflows/cron-feedstock-build-tests.yaml ================================================ # tests this openfe commit and gufe main to check for # conda-feedstock build issues name: "cron: weekly feedstock package build tests" concurrency: group: "${{ github.workflow }}-${{ github.ref }}" cancel-in-progress: true defaults: run: shell: bash -leo pipefail {0} on: workflow_dispatch: schedule: # 3 am weekly on monday - cron: "0 3 * * MON" jobs: test-conda-build: runs-on: ubuntu-latest steps: - name: Checkout openfe repository uses: actions/checkout@v4 with: path: openfe - name: Checkout conda-forge feedstock uses: actions/checkout@v4 with: repository: conda-forge/openfe-feedstock path: openfe-feedstock - name: Set up Python uses: actions/setup-python@v5 with: python-version: '3.x' - name: Install conda-build dependencies run: | pip install pyyaml # TODO just checkout the repo where we need it? - name: Copy source code to recipe folder run: cp -r openfe openfe-feedstock/recipe/openfe_source - name: Modify feedstock to use local path run: | cd openfe-feedstock # Backup original recipe.yaml cp recipe/recipe.yaml recipe/recipe.yaml.bak # NOTE: now that we use v1 feedstock, we can use yq to directly parse the YAML here. # Add path after source: and delete url line sed -i '/^source:/a\ path: ./openfe_source' recipe/recipe.yaml sed -i '/^ url:/d' recipe/recipe.yaml echo "Modified recipe.yaml:" cat recipe/recipe.yaml - name: Run conda-forge build test run: | cd openfe-feedstock python build-locally.py continue-on-error: true id: build_test # Uncomment if build_artifacts is needed to troubleshoot build # - name: Upload build logs # if: always() # uses: actions/upload-artifact@v4 # with: # name: conda-build-logs # path: | # openfe-feedstock/build_artifacts/ # openfe-feedstock/recipe/recipe.yaml # openfe-feedstock/recipe/recipe.yaml.bak # if-no-files-found: warn - name: Check build status if: steps.build_test.outcome == 'failure' run: | echo "❌ Conda forge build test failed. Check the uploaded logs for details." exit 1 ================================================ FILE: .github/workflows/cron-package-test.yaml ================================================ name: "cron: package install daily tests" on: workflow_dispatch: schedule: # At 03:00 UTC daily - cron: "0 3 * * *" concurrency: group: "${{ github.workflow }}-${{ github.ref }}" cancel-in-progress: true defaults: run: shell: bash -leo pipefail {0} jobs: package-tests: runs-on: ubuntu-latest name: "main branch long tests" steps: - uses: actions/checkout@v4 - name: Get current date id: date run: echo "date=$(date +%Y-%m-%d)" >> "${GITHUB_OUTPUT}" - name: "Setup Micromamba" uses: mamba-org/setup-micromamba@v2 with: environment-file: environment.yml environment-name: openfe_env cache-environment: true cache-downloads: true cache-environment-key: environment-${{ steps.date.outputs.date }} cache-downloads-key: downloads-${{ steps.date.outputs.date }} create-args: >- python=3.12 init-shell: bash - name: "install extra deps" run: pip install pipx wheel twine readme-renderer - name: "build sdist" run: pipx run build --sdist --outdir dist - name: "check package build" run: | dist=$(ls -t1 dist/openfe-*tar.gz | head -n1) test -n "${dist}" || { echo "no distribution found"; exit 1; } twine check $dist - name: "install from source dist" working-directory: ./dist run: python -m pip install openfe-*tar.gz - name: "run tests" working-directory: ./dist env: OFE_SLOW_TESTS: "true" run: | pytest -n auto -v --pyargs openfe.tests pytest -n auto -v --pyargs openfecli.tests ================================================ FILE: .github/workflows/griffe-api-break.yaml ================================================ name: "PR: griffe check for API breaks" on: pull_request_target: branches: - main jobs: check: runs-on: ubuntu-latest permissions: pull-requests: write steps: - uses: actions/checkout@v4 with: fetch-depth: 0 - run: git fetch --depth=1 --tags - uses: actions/setup-python@v5 with: python-version: "3.13" - name: Check for API breaks continue-on-error: true id: check run: | pip install griffe griffe check "openfe" -s src --verbose -a origin/main griffe check "openfecli" -s src --verbose -a origin/main - name: Manage PR Comments uses: actions/github-script@v7 with: script: | const prNumber = context.payload.pull_request.number; const identifier = ''; const runUrl = `${context.serverUrl}/${context.repo.owner}/${context.repo.repo}/actions/runs/${context.runId}`; const stepUrl = `${runUrl}#step:check`; // Determine the outcome of the check step const checkStepOutcome = '${{ steps.check.outcome }}'; // List existing comments const { data: comments } = await github.rest.issues.listComments({ owner: context.repo.owner, repo: context.repo.repo, issue_number: prNumber, }); // Delete previous comments from this action for (const comment of comments) { if (comment.body.includes(identifier)) { await github.rest.issues.deleteComment({ owner: context.repo.owner, repo: context.repo.repo, comment_id: comment.id, }); } } // Post a new comment only if the check step failed if (checkStepOutcome === 'failure') { await github.rest.issues.createComment({ owner: context.repo.owner, repo: context.repo.repo, issue_number: prNumber, body: `${identifier}\n🚨 API breaking changes detected! 🚨\n[View logs for this step](${stepUrl})` }); } else { await github.rest.issues.createComment({ owner: context.repo.owner, repo: context.repo.repo, issue_number: prNumber, body: `${identifier}\nNo API break detected ✅` }); } ================================================ FILE: .github/workflows/mypy.yaml ================================================ name: "PR: mypy static type checking" on: pull_request: branches: - main push: branches: - main concurrency: group: "${{ github.workflow }}-${{ github.ref }}" cancel-in-progress: true defaults: run: shell: bash -leo pipefail {0} jobs: mypy: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Get current date id: date run: echo "date=$(date +%Y-%m-%d)" >> "${GITHUB_OUTPUT}" - name: "Setup Micromamba" uses: mamba-org/setup-micromamba@v2 with: environment-file: environment.yml environment-name: openfe_env cache-environment: true cache-downloads: true cache-environment-key: environment-${{ steps.date.outputs.date }} cache-downloads-key: downloads-${{ steps.date.outputs.date }} create-args: >- python=3.12 mypy>=1.17.0 init-shell: bash - name: "Install steps" run: | python -m pip install --no-deps -e . - name: "Environment Information" run: | micromamba info micromamba list - name: "Lint with mypy" run: mypy ================================================ FILE: .github/workflows/release-docker-image.yaml ================================================ # This workflow uses actions that are not certified by GitHub. # They are provided by a third-party and are governed by # separate terms of service, privacy policy, and support # documentation. # GitHub recommends pinning actions to a commit SHA. # To get a newer version, you will need to update the SHA. # You can also reference a tag or branch, but the action may change without warning. # Workflow to automate docker image building during the openfe release process. name: "release: create and publish a docker image" on: workflow_dispatch: defaults: run: shell: bash -leo pipefail {0} env: REGISTRY: ghcr.io IMAGE_NAME: openfreeenergy/openfe jobs: build-and-push-image: runs-on: ubuntu-latest permissions: contents: read packages: write steps: # see https://dev.to/mathio/squeezing-disk-space-from-github-actions-runners-an-engineers-guide-3pjg - name: Aggressive cleanup run: | # remove unneeded packages to avoid running out of memory # Remove Java (JDKs) sudo rm -rf /usr/lib/jvm # Remove .NET SDKs sudo rm -rf /usr/share/dotnet # Remove Swift toolchain sudo rm -rf /usr/share/swift # Remove Haskell (GHC) sudo rm -rf /usr/local/.ghcup # Remove Julia sudo rm -rf /usr/local/julia* # Remove Android SDKs sudo rm -rf /usr/local/lib/android # Remove Chromium (optional if not using for browser tests) sudo rm -rf /usr/local/share/chromium # Remove Microsoft/Edge and Google Chrome builds sudo rm -rf /opt/microsoft /opt/google # Remove Azure CLI sudo rm -rf /opt/az # Remove PowerShell sudo rm -rf /usr/local/share/powershell # Remove CodeQL and other toolcaches sudo rm -rf /opt/hostedtoolcache docker system prune -af || true docker builder prune -af || true df -h - name: Checkout repository uses: actions/checkout@v4 with: fetch-depth: 0 - name: Get Latest Version id: latest-version run: | REPO="${{ github.repository }}" VERSION=$(curl -s -H "Authorization: Bearer ${{ secrets.GITHUB_TOKEN }}" \ "https://api.github.com/repos/$REPO/releases/latest" | jq -r '.tag_name | ltrimstr("v")') echo $VERSION echo "VERSION=$VERSION" >> $GITHUB_OUTPUT - name: Print Latest Version run: echo ${{ steps.latest-version.outputs.VERSION }} - name: Create fully qualified image registry path id: fqirp run: | FQIRP=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.latest-version.outputs.VERSION }} echo "FQIRP=$FQIRP" >> $GITHUB_OUTPUT - name: Print FQIRP run: echo ${{ steps.fqirp.outputs.FQIRP }} - name: Log in to the Container registry uses: docker/login-action@f054a8b539a109f9f41c372932f1ae047eff08c9 with: registry: ${{ env.REGISTRY }} username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} - name: Extract metadata (tags, labels) for Docker id: meta uses: docker/metadata-action@98669ae865ea3cffbcbaa878cf57c20bbf1c6c38 with: images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} tags: | type=schedule,pattern=nightly,enable=true,priority=1000 type=ref,event=branch,enable=true,priority=600 type=ref,event=tag,enable=true,priority=600 type=ref,event=pr,prefix=pr-,enable=true,priority=600 type=semver,pattern={{major}}.{{minor}} type=semver,pattern={{version}} type=sha ${{ steps.latest-version.outputs.VERSION }} - name: Build and export to Docker uses: docker/build-push-action@v6 with: context: . file: production/Dockerfile load: true push: false tags: ${{ steps.meta.outputs.tags }} labels: ${{ steps.meta.outputs.labels }} build-args: | VERSION=${{ steps.latest-version.outputs.VERSION }} - name: Test image run: | docker run --rm ${{ steps.fqirp.outputs.FQIRP }} openfe --help docker run --rm ${{ steps.fqirp.outputs.FQIRP }} openfe --version docker run --rm ${{ steps.fqirp.outputs.FQIRP }} python -c "import gufe; print(f'{gufe.__version__=}')" docker run --rm ${{ steps.fqirp.outputs.FQIRP }} pytest --pyargs gufe -v docker run --rm ${{ steps.fqirp.outputs.FQIRP }} pytest --pyargs openfe openfecli -v - name: Push Docker image uses: docker/build-push-action@ad44023a93711e3deb337508980b4b5e9bcdc5dc with: context: . file: production/Dockerfile push: true tags: ${{ steps.meta.outputs.tags }} labels: ${{ steps.meta.outputs.labels }} build-args: | VERSION=${{ steps.latest-version.outputs.VERSION }} - name: Setup Apptainer uses: eWaterCycle/setup-apptainer@v2 with: apptainer-version: 1.3.4 - name: Build Apptainer Image run: singularity build openfe_${{ steps.latest-version.outputs.VERSION }}.sif docker-daemon:${{ steps.fqirp.outputs.FQIRP }} - name: Test & Push Apptainer Image run: | mkdir test_apptainer cd test_apptainer singularity run ../openfe_${{ steps.latest-version.outputs.VERSION }}.sif openfe --help singularity run ../openfe_${{ steps.latest-version.outputs.VERSION }}.sif openfe --version singularity run ../openfe_${{ steps.latest-version.outputs.VERSION }}.sif pytest --pyargs openfe openfecli -v -n auto echo ${{ secrets.GITHUB_TOKEN }} | singularity remote login -u ${{ secrets.GHCR_USERNAME }} --password-stdin oras://ghcr.io singularity push ../openfe_${{ steps.latest-version.outputs.VERSION }}.sif oras://${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.latest-version.outputs.VERSION }}-apptainer singularity push ../openfe_${{ steps.latest-version.outputs.VERSION }}.sif oras://${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest-apptainer ================================================ FILE: .github/workflows/release-installers.yaml ================================================ name: "release: make single-file installers" on: workflow_dispatch: defaults: run: shell: bash -leo pipefail {0} jobs: test: name: Building single file installer on ${{ matrix.os }} runs-on: ${{ matrix.os }} strategy: fail-fast: false matrix: os: [macos-latest, ubuntu-latest] steps: - name: Checkout Code uses: actions/checkout@v4 with: fetch-depth: 0 - name: Get Latest Version id: latest-version run: | REPO="${{ github.repository }}" VERSION=$(curl -s -H "Authorization: Bearer ${{ secrets.GITHUB_TOKEN }}" \ "https://api.github.com/repos/$REPO/releases/latest" | jq -r '.tag_name | ltrimstr("v")') echo $VERSION echo "VERSION=$VERSION" >> $GITHUB_OUTPUT - name: Install constructor environment with Micromamba uses: mamba-org/setup-micromamba@v2 with: environment-name: installer create-args: >- python=3.11 jinja2 constructor init-shell: bash - name: Create installer run: VERSION=${{ steps.latest-version.outputs.VERSION }} constructor devtools/installer/ - name: Get installer file name id: file-name run: | # This should work as long as we don't have any *.sh files in our root dir FILE_NAME=$(find * -maxdepth 0 -type f -name "*.sh") echo $FILE_NAME echo "FILE_NAME=$FILE_NAME" >> $GITHUB_OUTPUT - name: Test installer run: | chmod +x ${{ steps.file-name.outputs.FILE_NAME }} ./${{ steps.file-name.outputs.FILE_NAME }} -b export PATH="$HOME/openfeforge/bin:$PATH" OFE_SLOW_TESTS=FALSE pytest -v --pyargs openfe # Copy for "latest" release by removing version # Inspired by https://github.com/conda-forge/miniforge/blob/main/.github/workflows/ci.yml cp ${{ steps.file-name.outputs.FILE_NAME }} $(echo ${{ steps.file-name.outputs.FILE_NAME }} | sed -e 's/-[^-]*//') - uses: actions/upload-artifact@v4 with: name: ${{ steps.file-name.outputs.FILE_NAME }} path: OpenFEforge* if-no-files-found: error - name: Upload openfe forge to release uses: svenstaro/upload-release-action@v2 with: repo_token: ${{ secrets.GITHUB_TOKEN }} file: OpenFEforge* tag: ${{ github.ref }} overwrite: true file_glob: true if: startsWith(github.ref, 'refs/tags/') ================================================ FILE: .github/workflows/release-make-condalock.yaml ================================================ name: "release: create openfe conda-lock file" on: workflow_dispatch: defaults: run: shell: bash -leo pipefail {0} jobs: create-conda-lock-file-and-test-linux: runs-on: ubuntu-latest steps: - name: Install conda-lock with Micromamba uses: mamba-org/setup-micromamba@v2 with: environment-name: conda-lock create-args: >- conda-lock # This saves me some time since we only need the latest tag - name: Get latest tag id: latest-version run: | REPO="${{ github.repository }}" VERSION=$(curl -s -H "Authorization: Bearer ${{ secrets.GITHUB_TOKEN }}" \ "https://api.github.com/repos/$REPO/releases/latest" | jq -r '.tag_name | ltrimstr("v")') echo $VERSION echo "VERSION=$VERSION" >> $GITHUB_OUTPUT - name: Print Latest Version run: echo ${{ steps.latest-version.outputs.VERSION }} - name: Create environment file to lock run: | cat > environment-to-lock.yaml << 'EOF' name: openfe_env channels: - conda-forge platforms: - linux-64 - osx-arm64 dependencies: - openfe==${{ steps.latest-version.outputs.VERSION }} - python=3.12 EOF - name: Generate lock files run: | conda lock --with-cuda 11.8 -f environment-to-lock.yaml --lockfile openfe-conda-lock.yml cp openfe-conda-lock.yml openfe-${{ steps.latest-version.outputs.VERSION }}-conda-lock.yml - name: Test lock file (linux) run: | conda-lock install -p /home/runner/micromamba/envs/lf-test openfe-conda-lock.yml micromamba activate /home/runner/micromamba/envs/lf-test openfe test - name: Upload file as artifact uses: actions/upload-artifact@v4 with: name: conda-lock-files path: "*conda-lock.yml" test-osx-lock-file: needs: create-conda-lock-file-and-test-linux runs-on: macos-latest steps: - name: Download artifact uses: actions/download-artifact@v4 with: name: conda-lock-files - name: Install conda-lock with Micromamba uses: mamba-org/setup-micromamba@v2 with: environment-name: conda-lock create-args: >- conda-lock - name: Test lock file (osx) run: | conda-lock install -p /Users/runner/micromamba/envs/lf-test openfe-conda-lock.yml micromamba activate /Users/runner/micromamba/envs/lf-test openfe test - name: Upload lock files to release uses: svenstaro/upload-release-action@v2 if: startsWith(github.ref, 'refs/tags/') with: repo_token: ${{ secrets.GITHUB_TOKEN }} file: "*conda-lock.yml" tag: ${{ github.ref }} overwrite: true file_glob: true ================================================ FILE: .github/workflows/release-prep-examplenotebooks.yaml ================================================ name: "release prep: test example notebooks" on: workflow_dispatch: concurrency: group: "${{ github.workflow }}-${{ github.ref }}" cancel-in-progress: true defaults: run: shell: bash -leo pipefail {0} jobs: test-example-notebooks: runs-on: ubuntu-latest steps: - name: Checkout openfe repository uses: actions/checkout@v4 with: path: openfe - name: Checkout example notebooks uses: actions/checkout@v4 with: repository: openfreeenergy/ExampleNotebooks path: example-notebooks - name: Setup Micromamba uses: mamba-org/setup-micromamba@v2 with: environment-file: openfe/environment.yml environment-name: openfe_env create-args: >- python=3.12 nbval init-shell: bash - name: Install OpenFE run: python -m pip install --no-deps -e ./openfe - name: Environment Information run: | micromamba info micromamba list - name: Run example notebooks run: | cd example-notebooks python -m pytest -v --nbval-lax --nbval-cell-timeout=3000 -n auto --dist loadscope ================================================ FILE: .github/workflows/release-prep-feedstock.yaml ================================================ # tests this openfe commit with the latest gufe release # meant to be used for release prep to catch feedstock issues before releasing on github name: "release prep: test conda-forge package build" concurrency: group: "${{ github.workflow }}-${{ github.ref }}" cancel-in-progress: true defaults: run: shell: bash -leo pipefail {0} on: workflow_dispatch: # TODO: run when "release prep" label is added jobs: test-conda-build: runs-on: ubuntu-latest steps: - name: Checkout openfe repository uses: actions/checkout@v4 with: path: openfe - name: Checkout conda-forge feedstock uses: actions/checkout@v4 with: repository: conda-forge/openfe-feedstock path: openfe-feedstock - name: Set up Python uses: actions/setup-python@v5 with: python-version: '3.x' - name: Install conda-build dependencies run: | pip install pyyaml # TODO just checkout the repo where we need it? - name: Copy source code to recipe folder run: cp -r openfe openfe-feedstock/recipe/openfe_source - name: Get Latest gufe Version id: latest-gufe-version run: | REPO="openfreeenergy/gufe" VERSION=$(curl -s -H "Authorization: Bearer ${{ secrets.GITHUB_TOKEN }}" \ "https://api.github.com/repos/$REPO/releases/latest" | jq -r '.tag_name | ltrimstr("v")') echo $VERSION echo "VERSION=$VERSION" >> $GITHUB_OUTPUT - name: Modify feedstock to use local path and latest gufe uses: mikefarah/yq@master with: cmd: | cd openfe-feedstock # Backup original recipe.yaml cp recipe/recipe.yaml recipe/recipe.yaml.bak # Add path after 'source:' and delete url line yq -i '.source.path="./openfe_source"' recipe/recipe.yaml yq -i 'del(.source.url)' recipe/recipe.yaml # remove existing gufe entry and add the gufe pin we want yq -i 'del(.outputs.[0].requirements.run[] | select(. =="*gufe*"))' recipe/recipe.yaml yq -i '.outputs.[0].requirements.run += "gufe==${{ steps.latest-gufe-version.outputs.VERSION }}"' recipe/recipe.yaml echo "Modified recipe.yaml:" cat recipe/recipe.yaml - name: Run conda-forge build test run: | cd openfe-feedstock python build-locally.py continue-on-error: true id: build_test # Uncomment if build_artifacts is needed to troubleshoot build # - name: Upload build logs # if: always() # uses: actions/upload-artifact@v4 # with: # name: conda-build-logs # path: | # openfe-feedstock/build_artifacts/ # openfe-feedstock/recipe/recipe.yaml # openfe-feedstock/recipe/recipe.yaml.bak # if-no-files-found: warn - name: Check build status if: steps.build_test.outcome == 'failure' run: | echo "❌ Conda forge build test failed. Check the uploaded logs for details." exit 1 ================================================ FILE: .gitignore ================================================ # custom ignores .duecredit.p .xxrun .idea/ .vscode/ # Byte-compiled / optimized / DLL files __pycache__/ *.py[cod] *$py.class *~ # C extensions *.so # Distribution / packaging .Python build/ develop-eggs/ dist/ downloads/ eggs/ .eggs/ lib/ lib64/ parts/ sdist/ var/ wheels/ share/python-wheels/ *.egg-info/ .installed.cfg *.egg MANIFEST # PyInstaller # Usually these files are written by a python script from a template # before PyInstaller builds the exe, so as to inject date/other infos into it. *.manifest *.spec # Installer logs pip-log.txt pip-delete-this-directory.txt # Unit test / coverage reports htmlcov/ .tox/ .nox/ .coverage .coverage.* .cache nosetests.xml coverage.xml *.cover *.py,cover .hypothesis/ .pytest_cache/ cover/ # Translations *.mo *.pot # Django stuff: *.log local_settings.py db.sqlite3 db.sqlite3-journal # Flask stuff: instance/ .webassets-cache # Scrapy stuff: .scrapy # Sphinx documentation docs/_build/ docs/reference/api/generated docs/tutorials/*.png # PyBuilder .pybuilder/ target/ # Jupyter Notebook .ipynb_checkpoints # IPython profile_default/ ipython_config.py # pyenv # For a library or package, you might want to ignore these files since the code is # intended to run in multiple environments; otherwise, check them in: # .python-version # pipenv # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. # However, in case of collaboration, if having platform-specific dependencies or dependencies # having no cross-platform support, pipenv may install dependencies that don't work, or not # install all needed dependencies. #Pipfile.lock # poetry # Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control. # This is especially recommended for binary packages to ensure reproducibility, and is more # commonly ignored for libraries. # https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control #poetry.lock # PEP 582; used by e.g. github.com/David-OConnor/pyflow __pypackages__/ # Celery stuff celerybeat-schedule celerybeat.pid # SageMath parsed files *.sage.py # Environments .env .venv env/ venv/ ENV/ env.bak/ venv.bak/ # Spyder project settings .spyderproject .spyproject # Rope project settings .ropeproject # mkdocs documentation /site # mypy .mypy_cache/ .dmypy.json dmypy.json # Pyre type checker .pyre/ # pytype static type analyzer .pytype/ # Cython debug symbols cython_debug/ # PyCharm # JetBrains specific template is maintainted in a separate JetBrains.gitignore that can # be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore # and can be added to the global gitignore or merged into this file. For a more nuclear # option (not recommended) you can uncomment the following to ignore the entire idea folder. #.idea/ # vim *.swp # vscode .vscode/ # Example notebooks docs/ExampleNotebooks/ # duecredit .duecredit.p # Some charge stuff *.model.pt # Rever rever/ ================================================ FILE: .pre-commit-config.yaml ================================================ ci: autoupdate_schedule: quarterly # comment / label "pre-commit.ci autofix" to a pull request to manually trigger auto-fixing autofix_prs: false skip: [] submodules: false repos: - repo: https://github.com/pre-commit/pre-commit-hooks rev: v6.0.0 hooks: - id: check-added-large-files args: ["--maxkb=900"] - id: check-case-conflict - id: check-executables-have-shebangs - id: check-symlinks - id: check-toml - id: check-yaml exclude: devtools/installer/construct.yaml # not a true YAML file - id: debug-statements - repo: https://github.com/tox-dev/pyproject-fmt rev: "v2.21.0" hooks: - id: pyproject-fmt - repo: https://github.com/astral-sh/ruff-pre-commit rev: v0.15.9 hooks: # Run the linter. - id: ruff args: [--fix ] # Run the formatter. - id: ruff-format ================================================ FILE: .readthedocs.yaml ================================================ version: 2 build: os: "ubuntu-24.04" tools: python: "miniconda3-3.12-24.9" sphinx: configuration: docs/conf.py fail_on_warning: true conda: environment: docs/environment.yaml python: # Install our python package before building the docs install: - method: pip path: . ================================================ FILE: CITATION.cff ================================================ cff-version: 1.2.0 message: "If you use this software, please cite it as below." authors: - family-names: "Alibay" given-names: "Irfan" orcid: "https://orcid.org/0000-0001-5787-9130" - family-names: "Gowers" given-names: "Richard J." orcid: "https://orcid.org/0000-0002-3241-1846" - family-names: "Swenson" given-names: "David W.H." orcid: "https://orcid.org/0000-0001-9922-7923" - family-names: "Henry" given-names: "Michael M." orcid: "https://orcid.org/0000-0002-3870-9993" - family-names: "Ries" given-names: "Benjamin" orcid: "https://orcid.org/0000-0002-0945-8304" - family-names: "Baumann" given-names: "Hannah M." orcid: "https://orcid.org/0000-0002-1736-7744" - family-names: "Eastwood" given-names: "James R. B." orcid: "https://orcid.org/0000-0003-3895-5227" - given-names: "Ashley" family-names: "Mitchell" orcid: 'https://orcid.org/0000-0002-8246-5113' - given-names: "David" family-names: "Dotson" orcid: "https://orcid.org/0000-0001-5879-2942" - given-names: Joshua T. family-names: Horton orcid: 'https://orcid.org/0000-0001-8694-7200' - given-names: Matthew family-names: Thompson orcid: 'https://orcid.org/0000-0002-1460-3983' - given-names: Alyssa family-names: Travitz orcid: 'https://orcid.org/0000-0001-5953-8807' title: "The Open Free Energy library" version: 1.7.0 date-released: 2025-04-25 url: "https://openfree.energy/" repository-code: "https://github.com/openfreeEnergy/openfe" doi: 10.5281/zenodo.8344247 ================================================ FILE: Code_of_Conduct.md ================================================ ## Code of Conduct ## This project is dedicated to providing a welcoming and supportive environment for all people, regardless of background or identity. Members do not tolerate harassment for any reason, but especially harassment based on gender, sexual orientation, disability, physical appearance, body size, race, nationality, sex, color, ethnic or social origin, pregnancy, citizenship, familial status, veteran status, genetic information, religion or belief, political or any other opinion, membership of a national minority, property, age, or preference of text editor. ### Expected Behavior ### All participants in our events and communications are expected to show respect and courtesy to others. All interactions should be professional regardless of platform: either online or in-person. In order to foster a positive and professional working environment we encourage the following kinds of behaviors in all work events, activities, and platforms: * Use welcoming and inclusive language * Be respectful of different viewpoints and experiences * Gracefully accept constructive criticism * Focus on what is best for the community * Show courtesy and respect towards other community members Note: See the [four social rules](https://www.recurse.com/manual#sub-sec-social-rules) for further recommendations. ### Unacceptable Behavior ### Harassment is any form of behavior intended to exclude, intimidate, or cause discomfort. Prohibited harassing behavior includes, but is not limited to: * written or verbal comments which have the effect of excluding people * causing someone to fear for their safety, such as through stalking, following, or intimidating * the display of sexual or violent images * unwelcome sexual attention * non-consensual or unwelcome physical contact * sustained disruption of talks, events, or communications * incitement to violence, suicide, or self-harm * continuing to initiate interaction (including photography or recording) with someone after being asked to stop and * publication of private comment without consent This list should not be taken to be exhaustive, but rather as a guide to make it easier to enrich our community and all those in which we participate. All interactions should be professional regardless of location: Harassment is prohibited whether it occurs on or offline, and the same standards apply to both. Enforcement of this Code of Conduct will be respectful and not include any harassing behaviors. You deserve sincere thanks for helping to make this a welcoming, friendly community for all. This Code of Conduct was adapted from the [cmelab](https://github.com/cmelab/getting-started/blob/master/wiki/pages/Code_of_Conduct.md). ================================================ FILE: LICENSE ================================================ MIT License Copyright (c) 2022 OpenFreeEnergy Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ================================================ FILE: MANIFEST.in ================================================ recursive-include src/openfe/tests/data/ *.sdf recursive-include src/openfe/tests/data/ *.bz2 recursive-include src/openfe/tests/data/ *.csv recursive-include src/openfe/tests/data/ *.pdb recursive-include src/openfe/tests/data/ *.mol2 recursive-include src/openfe/tests/data/ *.xml recursive-include src/openfe/tests/data/ *.graphml recursive-include src/openfe/tests/data/ *.edge recursive-include src/openfe/tests/data/ *.dat recursive-include src/openfe/tests/data/ *.txt recursive-include src/openfe/tests/data/ *.gz recursive-include src/openfe/tests/data/ *json_results.gz include src/openfecli/tests/data/*.json include src/openfecli/tests/data/*.tar.gz include src/openfecli/tests/commands/test_gather/*.tsv recursive-include src/openfecli/tests/ *.sdf recursive-include src/openfecli/tests/ *.pdb include src/openfe/tests/data/openmm_rfe/vacuum_nocoord.nc ================================================ FILE: README.md ================================================ [![Logo](https://img.shields.io/badge/OSMF-OpenFreeEnergy-%23002f4a)](https://openfree.energy/) [![build](https://github.com/OpenFreeEnergy/openfe/actions/workflows/ci.yaml/badge.svg?branch=main)](https://github.com/OpenFreeEnergy/openfe/actions/workflows/ci.yaml) [![coverage](https://codecov.io/gh/OpenFreeEnergy/openfe/branch/main/graph/badge.svg)](https://codecov.io/gh/OpenFreeEnergy/openfe) [![documentation](https://readthedocs.org/projects/openfe/badge/?version=stable)](https://docs.openfree.energy/en/stable/?badge=stable) [![DOI](https://zenodo.org/badge/DOI/10.5281/zenodo.8344248.svg)](https://doi.org/10.5281/zenodo.17258732) # `openfe` - A Python package for executing alchemical free energy calculations. The `openfe` package is the flagship project of [Open Free Energy](https://openfree.energy), a pre competitive consortium aiming to provide robust, permissively licensed open source tools for molecular simulation in the drug discovery field. Using `openfe` you can easily plan and execute alchemical free energy calculations. See our [website](https://openfree.energy/) for more information on the project, [try for yourself](https://try.openfree.energy) from the comfort of your browser, and we have [documentation on using the package](https://docs.openfree.energy/en/latest/index.html). ## License This library is made available under the [MIT](https://opensource.org/licenses/MIT) open source license. ## Install ### Latest release The latest release of `openfe` can be installed via `mamba`, `docker`, or a `single file installer`. See [our installation instructions](https://docs.openfree.energy/en/stable/installation.html) for more details. Dependencies can be installed via conda through: ### Development version The development version of `openfe` can be installed directly from the `main` branch of this repository. First install the package dependencies using `mamba`: ```bash mamba env create -f environment.yml ``` The openfe library can then be installed via: ``` python -m pip install --no-deps . ``` ## Authors The OpenFE development team. ## Acknowledgements OpenFE is an [Open Molecular Software Foundation](https://omsf.io/) hosted project. ================================================ FILE: codecov.yml ================================================ coverage: status: project: off ================================================ FILE: devtools/data/fix_rbfe_results.py ================================================ """A script to fix up rbfe_results.tar.gz Useful if Settings are ever changed in a backwards-incompatible way Will expect "rbfe_results.tar.gz" in this directory, will overwrite this file """ import glob import json import os.path import tarfile from gufe.tokenization import JSON_HANDLER from openfe.protocols import openmm_rfe def untar(fn): """extract tarfile called *fn*""" with tarfile.open(fn) as f: f.extractall() def retar(loc, name): """create tar.gz called *name* of directory *loc*""" with tarfile.open(name, mode="w:gz") as f: f.add(loc, arcname=os.path.basename(loc)) def replace_settings(fn, new_settings): """replace settings instances in *fn* with *new_settings*""" with open(fn, "r") as f: data = json.load(f) for k in data["protocol_result"]["data"]: data["protocol_result"]["data"][k][0]["inputs"]["settings"] = new_settings for k in data["unit_results"]: data["unit_results"][k]["inputs"]["settings"] = new_settings with open(fn, "w") as f: json.dump(data, f, cls=JSON_HANDLER.encoder) def fix_rbfe_results(): untar("rbfe_results.tar.gz") # generate valid settings as defaults new_settings = openmm_rfe.RelativeHybridTopologyProtocol.default_settings() # walk over all result jsons for fn in glob.glob("./results/*json"): # replace instances of settings within with valid settings replace_settings(fn, new_settings) retar("results", "rbfe_results.tar.gz") if __name__ == "__main__": fix_rbfe_results() ================================================ FILE: devtools/data/gen_serialized_results.py ================================================ """ Dev script to generate some result jsons that are used for testing Generates - ABFEProtocol_json_results.gz - used in abfe_results_json fixture - SepTopProtocol_json_results.gy - used in septop_json fixture - AHFEProtocol_json_results.gz - used in afe_solvation_json fixture - RHFEProtocol_json_results.gz - used in rfe_transformation_json fixture - MDProtocol_json_results.gz - used in md_json fixture """ import gzip import json import logging import pathlib import sys import tempfile import gufe from gufe.tokenization import JSON_HANDLER from kartograf import KartografAtomMapper from kartograf.atom_aligner import align_mol_shape from openff.toolkit import AmberToolsToolkitWrapper, Molecule, RDKitToolkitWrapper from openff.toolkit.utils.toolkit_registry import ToolkitRegistry, toolkit_registry_manager from openff.units import unit from rdkit import Chem import openfe from openfe.protocols.openmm_afe import ( AbsoluteBindingProtocol, AbsoluteSolvationProtocol, ) from openfe.protocols.openmm_md.plain_md_methods import PlainMDProtocol from openfe.protocols.openmm_rfe import RelativeHybridTopologyProtocol from openfe.protocols.openmm_septop import SepTopProtocol from openfecli.utils import configure_logger # avoid problems with output not showing if queueing system kills a job sys.stdout.reconfigure(line_buffering=True) stdout_handler = logging.StreamHandler(sys.stdout) configure_logger("gufekey", handler=stdout_handler) configure_logger("gufe", handler=stdout_handler) configure_logger("openfe", handler=stdout_handler) configure_logger("openmmtools.multistate.multistatereporter", level=logging.DEBUG, handler=stdout_handler) # fmt: skip configure_logger("openmmtools.multistate.multistatesampler", level=logging.DEBUG, handler=stdout_handler) # fmt: skip logger = logging.getLogger(__name__) LIGA = "[H]C([H])([H])C([H])([H])C(=O)C([H])([H])C([H])([H])[H]" LIGB = "[H]C([H])([H])C(=O)C([H])([H])C([H])([H])C([H])([H])[H]" amber_rdkit = ToolkitRegistry([RDKitToolkitWrapper(), AmberToolsToolkitWrapper()]) def get_molecule(smi, name): with toolkit_registry_manager(amber_rdkit): m = Molecule.from_smiles(smi) m.generate_conformers() m.assign_partial_charges(partial_charge_method="am1bcc") return openfe.SmallMoleculeComponent.from_openff(m, name=name) def get_hif2a_inputs(): with gzip.open("inputs/hif2a_protein.pdb.gz", "r") as f: protcomp = openfe.ProteinComponent.from_pdb_file(f, name="hif2a_prot") with gzip.open("inputs/hif2a_ligands.sdf.gz", "r") as f: smcs = [ openfe.SmallMoleculeComponent(mol) for mol in list(Chem.ForwardSDMolSupplier(f, removeHs=False)) ] return smcs, protcomp def execute_and_serialize( dag, protocol, simname, new_serialization: bool = False ): # fmt: skip """ Execute & serialize a DAG Parameters ---------- dag : gufe.ProtocolDAG The DAG to execute & serialize. protocol : gufe.Protocol The Protocol to which the DAG belongs. simname : str The name of the simulation, used for the serialized file name. new_serialization : bool Whether or not we should use the "new" `to_json` serialization. Default is False (for now). """ logger.info(f"running {simname}") with tempfile.TemporaryDirectory() as tmpdir: workdir = pathlib.Path(tmpdir) dagres = gufe.protocols.execute_DAG( dag, shared_basedir=workdir, scratch_basedir=workdir, keep_shared=True, raise_error=True, n_retries=2, ) protres = protocol.gather([dagres]) if new_serialization: protres.to_json(f"{simname}_json_results.json") else: outdict = { "estimate": protres.get_estimate(), "uncertainty": protres.get_uncertainty(), "protocol_result": protres.to_dict(), "unit_results": { unit.key: unit.to_keyed_dict() for unit in dagres.protocol_unit_results } } # fmt: skip with gzip.open(f"{simname}_json_results.gz", "wt") as zipfile: json.dump(outdict, zipfile, cls=JSON_HANDLER.encoder) def generate_md_settings(): settings = PlainMDProtocol.default_settings() settings.simulation_settings.equilibration_length_nvt = 0.01 * unit.nanosecond settings.simulation_settings.equilibration_length = 0.01 * unit.nanosecond settings.simulation_settings.production_length = 0.01 * unit.nanosecond settings.forcefield_settings.nonbonded_method = "nocutoff" return settings def generate_md_json(smc): protocol = PlainMDProtocol(settings=generate_md_settings()) system = openfe.ChemicalSystem({"ligand": smc}) dag = protocol.create(stateA=system, stateB=system, mapping=None) execute_and_serialize(dag, protocol, "MDProtocol") def generate_abfe_settings(): settings = AbsoluteBindingProtocol.default_settings() settings.solvent_equil_simulation_settings.equilibration_length_nvt = 10 * unit.picosecond settings.solvent_equil_simulation_settings.equilibration_length = 10 * unit.picosecond settings.solvent_equil_simulation_settings.production_length = 10 * unit.picosecond settings.solvent_simulation_settings.equilibration_length = 100 * unit.picosecond settings.solvent_simulation_settings.production_length = 500 * unit.picosecond settings.solvent_simulation_settings.time_per_iteration = 2.5 * unit.ps settings.complex_equil_simulation_settings.equilibration_length_nvt = 10 * unit.picosecond settings.complex_equil_simulation_settings.equilibration_length = 10 * unit.picosecond settings.complex_equil_simulation_settings.production_length = 100 * unit.picosecond settings.complex_simulation_settings.equilibration_length = 100 * unit.picosecond settings.complex_simulation_settings.production_length = 500 * unit.picosecond settings.complex_simulation_settings.time_per_iteration = 2.5 * unit.ps settings.solvent_solvation_settings.box_shape = "dodecahedron" settings.complex_solvation_settings.box_shape = "dodecahedron" settings.solvent_solvation_settings.solvent_padding = 1.5 * unit.nanometer settings.complex_solvation_settings.solvent_padding = 1.0 * unit.nanometer settings.forcefield_settings.nonbonded_cutoff = 0.8 * unit.nanometer settings.protocol_repeats = 3 settings.engine_settings.compute_platform = "CUDA" return settings def generate_abfe_json(): ligands, protein = get_hif2a_inputs() protocol = AbsoluteBindingProtocol(settings=generate_abfe_settings()) sysA = openfe.ChemicalSystem( { "ligand": ligands[0], "protein": protein, "solvent": openfe.SolventComponent(), } ) sysB = openfe.ChemicalSystem( { "protein": protein, "solvent": openfe.SolventComponent(), } ) dag = protocol.create(stateA=sysA, stateB=sysB, mapping=None) execute_and_serialize(dag, protocol, "ABFEProtocol", new_serialization=True) def generate_ahfe_settings(): settings = AbsoluteSolvationProtocol.default_settings() settings.solvent_equil_simulation_settings.equilibration_length_nvt = 10 * unit.picosecond settings.solvent_equil_simulation_settings.equilibration_length = 10 * unit.picosecond settings.solvent_equil_simulation_settings.production_length = 10 * unit.picosecond settings.solvent_simulation_settings.equilibration_length = 10 * unit.picosecond settings.solvent_simulation_settings.production_length = 500 * unit.picosecond settings.vacuum_equil_simulation_settings.equilibration_length = 10 * unit.picosecond settings.vacuum_equil_simulation_settings.production_length = 10 * unit.picosecond settings.vacuum_simulation_settings.equilibration_length = 10 * unit.picosecond settings.vacuum_simulation_settings.production_length = 1000 * unit.picosecond settings.lambda_settings.lambda_elec = [0.0, 0.25, 0.5, 0.75, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0] # fmt: skip settings.lambda_settings.lambda_vdw = [0.0, 0.0, 0.0, 0.0, 0.0, 0.12, 0.24, 0.36, 0.48, 0.6, 0.7, 0.77, 0.85, 1.0] # fmt: skip settings.protocol_repeats = 3 settings.solvent_simulation_settings.n_replicas = 14 settings.vacuum_simulation_settings.n_replicas = 14 settings.solvent_simulation_settings.early_termination_target_error = 0.12 * unit.kilocalorie_per_mole # fmt: skip settings.vacuum_simulation_settings.early_termination_target_error = 0.12 * unit.kilocalorie_per_mole # fmt: skip settings.vacuum_engine_settings.compute_platform = "CPU" settings.solvent_engine_settings.compute_platform = "CUDA" return settings def generate_ahfe_json(smc): protocol = AbsoluteSolvationProtocol(settings=generate_ahfe_settings()) sysA = openfe.ChemicalSystem({"ligand": smc, "solvent": openfe.SolventComponent()}) sysB = openfe.ChemicalSystem({"solvent": openfe.SolventComponent()}) dag = protocol.create(stateA=sysA, stateB=sysB, mapping=None) execute_and_serialize(dag, protocol, "AHFEProtocol") def generate_rfe_settings(): settings = RelativeHybridTopologyProtocol.default_settings() settings.simulation_settings.equilibration_length = 10 * unit.picosecond settings.simulation_settings.production_length = 250 * unit.picosecond settings.forcefield_settings.nonbonded_method = "nocutoff" return settings def generate_rfe_json(smcA, smcB): protocol = RelativeHybridTopologyProtocol(settings=generate_rfe_settings()) a_smcB = align_mol_shape(smcB, ref_mol=smcA) mapper = KartografAtomMapper(atom_map_hydrogens=True) mapping = next(mapper.suggest_mappings(smcA, a_smcB)) systemA = openfe.ChemicalSystem({"ligand": smcA}) systemB = openfe.ChemicalSystem({"ligand": a_smcB}) dag = protocol.create(stateA=systemA, stateB=systemB, mapping=mapping) execute_and_serialize(dag, protocol, "RHFEProtocol") def generate_septop_settings(): settings = SepTopProtocol.default_settings() settings.solvent_equil_simulation_settings.equilibration_length_nvt = 10 * unit.picosecond settings.solvent_equil_simulation_settings.equilibration_length = 10 * unit.picosecond settings.solvent_equil_simulation_settings.production_length = 10 * unit.picosecond settings.solvent_simulation_settings.equilibration_length = 10 * unit.picosecond settings.solvent_simulation_settings.production_length = 50 * unit.picosecond settings.solvent_simulation_settings.time_per_iteration = 2.5 * unit.ps settings.complex_equil_simulation_settings.equilibration_length_nvt = 10 * unit.picosecond settings.complex_equil_simulation_settings.equilibration_length = 10 * unit.picosecond settings.complex_equil_simulation_settings.production_length = 10 * unit.picosecond settings.complex_simulation_settings.equilibration_length = 10 * unit.picosecond settings.complex_simulation_settings.production_length = 50 * unit.picosecond settings.complex_simulation_settings.time_per_iteration = 2.5 * unit.ps settings.solvent_solvation_settings.box_shape = "dodecahedron" settings.complex_solvation_settings.box_shape = "dodecahedron" settings.solvent_solvation_settings.solvent_padding = 1.2 * unit.nanometer settings.complex_solvation_settings.solvent_padding = 1.0 * unit.nanometer settings.forcefield_settings.nonbonded_cutoff = 0.9 * unit.nanometer settings.protocol_repeats = 1 settings.engine_settings.compute_platform = "CUDA" return settings def generate_septop_json(): hif2a_ligands, hif2a_protein = get_hif2a_inputs() protocol = SepTopProtocol(settings=generate_septop_settings()) sysA = openfe.ChemicalSystem( { "ligand_A": hif2a_ligands[0], "protein": hif2a_protein, "solvent": openfe.SolventComponent(), } ) sysB = openfe.ChemicalSystem( { "ligand_B": hif2a_ligands[1], "protein": hif2a_protein, "solvent": openfe.SolventComponent(), } ) dag = protocol.create(stateA=sysA, stateB=sysB, mapping=None) execute_and_serialize(dag, protocol, "SepTopProtocol") if __name__ == "__main__": molA = get_molecule(LIGA, "ligandA") molB = get_molecule(LIGB, "ligandB") generate_md_json(molA) generate_abfe_json() generate_ahfe_json(molA) generate_rfe_json(molA, molB) generate_septop_json() ================================================ FILE: devtools/debug_openmm.sh ================================================ #!/usr/bin/env bash echo "Run this script with your conda env activated" echo "Invoke the script like this: " echo "./debug_openmm.sh | tee -a debug.log" echo "Then send us debug.log" set -euo pipefail date which -a python conda info -a || echo "no conda" mamba info -a || echo "no mamba" micromamba info || echo "no micromamba" nvidia-smi || echo "no nvidia-smi, are you on a gpu node?" echo "test openmm" python -m openmm.testInstallation || echo "testing openmm" echo "checking plugin load failures" python -c "import openmm; print(openmm.Platform.getPluginLoadFailures())" || echo "plugin load failures" echo "checking which platforms support mixed precision" python -c "import openmmtools; [print(_.getName()) for _ in openmmtools.utils.get_available_platforms(minimum_precision='mixed')]" || echo "openmm errors" conda list || echo "no conda" mamba list || echo "no mamba" micromamba list || echo "no micromamba" ================================================ FILE: devtools/installer/construct.yaml ================================================ name: OpenFEforge version: {{ environ["VERSION"] }} company: OpenFE license_file: ../../LICENSE channels: - conda-forge write_condarc: True keep_pkgs: True transmute_file_type: .conda specs: - conda - jupyterlab - mamba - notebook <7 - openfe=={{ environ["VERSION"] }} - pip - pytest - pytest-xdist # python needs to match https://github.com/googlecolab/backend-info/blob/main/os-info.txt # until colab pushes a fix - python 3.12.11 # Not building an .exe for windows or a .pkg for macOS installer_type: sh ================================================ FILE: docs/CHANGELOG.rst ================================================ ========= Changelog ========= .. current developments v1.11.1 ==================== **Fixed:** * Fixed slow response time of CLI commands (`PR #1972 `_). v1.11.0 ==================== * **openfe v1.11.0** introduces support for protein-membrane systems both with the Python API and the CLI. See our tutorial `RBFE calculations of a Protein-Membrane System `_ for details. The `ability to resume execution of incomplete transformations `_ that was introduced in ``openfe v1.10.0`` is now available for the plain MD and SepTop protocols. See below for the full changelog for this release: **Added:** * Added support for systems with membranes to the following protocols: PlainMDProtocol, RelativeHybridTopologyProtocol, SepTopProtocol, and AbsoluteBindingProtocol (`PR #1561 `_). * Added support for membrane systems to ``openfe plan-rbfe-network``. Use ``--protein-membrane`` instead of the ``--protein`` argument, and see the tutorial on preparing membrane systems (`PR #1896 `_). * Added API support for resuming the PlainMDProtocol (`PR #1884 `_). * Added API support for resuming the SepTopProtocol. (`PR #1949 `_). * The ``validate`` method for the SepTopProtocol has been implemented. This means that settings and system validation can mostly be done prior to Protocol execuation by calling ``SepTopProtocol.validate(stateA, stateB, mapping=None)`` (`PR #1946 `_). **Changed:** * The SepTopProtocol now has a dedicated Analysis unit. At the top level API, this does not change behavior, but if you are directly interfacing with th ProtocolUnits, you will have to account for this change. The SepTopProtocolResult now solely uses the Analysis units (`PR #1937 `_). * Updated the chemical systems user guide and the defining protocols user guide to reflect recent protocol updates, including adding membrane support (`PR #1933 `_). * The default value for the Hybrid TopologyProtocol setting ``turn_off_core_unique_exceptions`` has been changed to ``True``. This means 1-4 interactions involving the unique alchemical atoms and core regions will now be interpolated on/off accordingly by default (`PR #1856 `_). **Deprecated:** * Perses atom mapper and scorer functionality is deprecated, now slated to be removed in ``openfe v1.12``. This includes ``PersesAtomMapper`` and ``default_perses_scorer`` (`PR #1857 `_). **Fixed:** * Fix erroneous logging information message which would mention setting up the alchemical system when running simulation or analysis units with the hybrid topology, AHFE or ABFE Protocols (`PR #1915 `_). * System equality checks on resuming no longer expect complete equality in the force parameters. This fixes a scenario where small changes in precision due to running on different machines would prevent users from restarting their simulations (`PR #1914 `_). v1.10.0 ==================== This release introduces the ability to resume execution of an incomplete transformation using ``openfe quickrun`` with the ``--resume`` flag. See the `quickrun documentation `_ details. **Added:** * Added ``--resume`` flag to ``openfe quickrun``. Quickrun now temporarily caches ``protocolDAG`` information and, when used with the ``--resume`` flag, quickrun will attempt to resume execution of an incomplete transformation (`PR #1848 `_). * Added API support to resume ``RelativeHybridTopologyProtocol`` simulations (`PR #1774 `_). * Added API support to resume ``AbsoluteBindingProtocol`` and ``AbsoluteSolvationProtocol`` simulations (`PR #1808 `_). **Deprecated:** * Perses atom mapper and scorer functionality is deprecated, slated to be removed in ``openfe v2.0``. This includes ``PersesAtomMapper`` and ``default_perses_scorer`` (`PR #1857 `_). **Fixed:** * Fixed bug introduced in v1.9.0 to ``openfe gather-abfe --report=raw`` where additional unit results for Setup and Simulation units would be shown. This fix restores the behavior prior to v1.9.0 (`PR #1876 `_). v1.9.1 ==================== **Fixed:** * Fixed a bug in Protocol termination for the HybridTop and AFE Protocols which would unnecessarily declare an ``UnboundLocalError``. * Updated ``openfe_analysis`` dependency to fix issue with RMSD analysis (`Issue #1834 `_). v1.9.0 ==================== **Added:** * The ``validate`` method for the RelativeHybridTopologyProtocol has been implemented. This means that settings and system validation can mostly be done prior to Protocol execution by calling ``RelativeHybridTopologyProtocol.validate(stateA, stateB, mapping)`` (`PR #1740 `_). * Added ``openfe test --download-only`` flag, which downloads all test data stored remotely to the local cache (`PR #1814 `_). **Changed:** * The absolute free energy protocols (AbsoluteBindingProtocol and AbsoluteSolvationProtocol) have been broken into multiple protocol units, allowing for setup, run, and analysis to happen separately in the future when relevant changes to protocol execution are made (`PR #1776 `_). * The relative free energy protocol (RelativeHybridTopologyProtocol) has been broken into multiple protocol units, allowing for the setup, run, analysis to happen separately (`PR #1773 `_). **Fixed:** * Fixed bug in ligand network visualization (such as with ``openfe view-ligand-network``) so that ligand names are no longer cut off by the plot border (`PR #1822 `_). * Endstates in the RelativeHybridTopologyProtocol are now being created in a manner that allows for isomorphic molecules that differ between endstates to have different parameters (`PR #1772 `_). v1.8.1 ==================== **Added:** * Added a progress bar for ``openfe gather`` JSON loading (`PR #1786 `_). **Fixed:** * Due to issues with OpenFF's handling of toolkit registries with NAGL, the use of NAGL models (e.g. AshGC) when OpenEye is installed but not requested as the charge backend has been disabled (Issue #1760, `PR #1762 `_). * Fixed bug in ligand network visualization (such as with ``openfe view-ligand-network``) so that ligand names are no longer cut off by the plot border (`PR #1822 `_). v1.8.0 ==================== **Added:** * The ``HybridTopologyFactory`` supports building hybrid OpenMM systems which contain ``CMAPTorsionForces`` on non-alchemical atoms. This should allow for simulations using Amber ff19SB (`PR #1695 `_). * Added experimental features ``openfe gather-septop`` and ``openfe gather-abfe``, which are analogous to ``openfe gather`` and allow for gathering results generated by the Separated Topologies and Absolute Binding Free Energy protocols, respectively. These commands are experimental and are liable to be changed in a future release. * Emit a clarifying log message when a user gets a warning from JAX (`PR #1585 `_, fixes `Issue #1499 `_). * Disable JAX acceleration by default, see https://docs.openfree.energy/en/latest/guide/troubleshooting.html#pymbar-disable-jax for more information (`PR #1694 `_). * New options have been added to the ``AlchemicalSettings`` of the ``SepTopProtocol``, ``AbsoluteSolvationProtocol`` and ``AbsoluteBindingProtocol``. Notably, these options allow users to control the softcore parameters as well as the use of long range dispersion corrections (`PR #1742 `_). **Changed:** * ``openfe gather`` is now more rigorous in extracting ligand names and run types. These are now determined directly from component attributes, rather than relying on naming conventions. (`PR #1691 `_). * Updated installation docs to recommend ``miniconda`` with ``conda-lock`` as the preferred installation method (`PR #1692 `_). v1.7.0 ==================== This release brings several long awaited features to OpenFE, including the SepTop and ABFE Protocols, as well as the adoption of more computationally efficient settings in the CLI and across the Python API. The v1.7.0 release also comes with some API changes and breaks, including: * "CUDA" is now the default platform in the settings, you will need to change this if you run on a non-NVIDIA-powered platform. * The default solvation cutoff is now 1.5 nm, to avoid issues with small boxes when dealing with ligands in solvent. When calculating complexes using the MD or HybridTopology Protocols with the API, you will need to reduce this value to ~ 1 nm to avoid excessively large water boxes. * The API has fully migrated to Pydantic V2 and the ``GufeQuantity`` scheme. This only affects Protocol developers. If needed, please see the `gufe typing documentation `_ for more details. Note that if you want to use NAGL to assign partial charges, you must use ``python >= 3.11``. Python 3.10 support is no longer maintained according to `SPEC 0 `_ guidelines. The openfe lock file and docker and apptainer images use Python 3.12, and so charge assignment with NAGL will work without intervention. **Added:** * Addition of an Absolute Binding Free Energy Protocol (`PR #1045 `_). * Added `a cookbook for using jq to inspect JSON files `_. * The AbsoluteSolvationProtocol now properly implements the ``validate`` method, allowing users to verify inputs by calling the method directly (`PR #1572 `_). * Added a new RBFE protocol based on Separated Topologies (`PR #1057 `_). **Changed:** * The default atom mapper used in the CLI has been changed from ``LomapAtomMapper`` to ``KartografAtomMapper`` in line with the recommended defaults from the industry benchmarking paper. Users who wish to continue to use ``LomapAtomMapper`` can do so via the YAML configuration file. See the `documentation `_ for details (`PR #1530 `_). * An improved error message is now shown when a mapping involving a changing constraint length cannot be fixed (`PR #1529 `_). * The default platform for OpenMM-based Protocols is now CUDA and will fail by default on a non-Nvidia GPU enabled system (`PR #1576 `_). * Remove unnecessary limit on residues ids (``resids``) when getting mappings from topology in ``topology_helpers.py`` utility module (`PR #1539 `_). * The relative hybrid topology protocol no longer runs the FIRE minimizer when ``dry=True`` (`PR #1468 `_). * Units must be explicitly assigned when defining ``Settings`` parameters, and values will be converted to match the default units for a given field. For example, use ``1.0 * units.bar`` or ``"1 bar"`` for pressure, and ``300 * unit.kelvin`` or ``"300 kelvin"`` for temperature. * For protocol developers: ``FloatQuantity`` is no longer supported. Instead, use ``GufeQuantity`` and ``specify_quantity_units()`` to make a ``TypeAlias``. See the `gufe typing documentation `_ for more details. * The default ``time_per_iteration`` setting of the ``MultiStateSimulationSettings`` class has been increased from 1.0 ps to 2.5 ps as part of the fast settings update (`PR #1523 `_). * The default ``box_shape`` setting of the ``OpenMMSolvationSettings`` class has been changed from ``cubic`` to ``dodecahedron`` to improve simulation efficiency as part of the fast settings update (`PR #1523 `_). * The default ``solvent_padding`` settings of the ``OpenMMSolvationSettings`` class has been increased from 1.2 nm to 1.5 nm to be compatible with the new ``box_shape`` default as part of the fast settings update (`PR #1523 `_). * The default ``nonbonded_cutoff`` setting of the ``OpenMMSystemGeneratorFFSettings`` class has been decreased to 0.9 nm from 1.0 nm, in line with current force fields best practices and our newly validated fast settings (`PR #1523 `_). * When calling the CLI ``openfe plan_rbfe_network``, the ``RelativeHybridTopologyProtocol`` settings now reflects the above "fast" settings updates. This includes; * Dodecahedron box solvation * Solvation cutoff of 1.5 nm in solvent-only legs, and 1.0 nm in complex legs * A replica exchange rate of 2.5 ps * A 0.9 nm nonbonded cutoff **Deprecated:** * Deprecated ``openfe.utils.visualization_3D.view_mapping_3d()``. Use the method ``LigandAtomMapping.view_3d()`` instead (`PR #1592 `_). * Deprecated ``openfe.utils.ligand_utils.get_alchemical_charge_difference()``, which is replaced by ``LigandAtomMapping.get_alchemical_charge_difference()`` in ``gufe`` (`PR #1479 `_). **Fixed:** * Charged molecules are now explicitly disallowed in the AbsoluteSolvationProtocol(`PR #1572 `_). v1.6.1 ==================== This release includes minor fixes and updates to tests. **Added:** * Added a cookbook for using ``jq`` to inspect JSON files. **Changed:** * Remove unnecessary limit on residues ids (``resids``) when getting mappings from topology in ``topology_helpers.py`` utility module. * The relative hybrid topology protocol no longer runs the FIRE minimizer when ``dry=True``. **Fixed:** * Updated tests to expect to find NAGL, now that it is supported. v1.6.0 ==================== This release adds support for OpenMM 8.3.0 and Python 3.13. **Added:** * Added support for openmm 8.3.0 (benchmarking results at `Issue #1377 `_. * Added support for ``python 3.13`` (we no longer guarantee support for ``python 3.10``). * Adds a new internal API for defining alchemical restraints (`PR #1043 `_). v1.5.0 ==================== This release includes support for openmm 8.2 and numpy v2. Checkpoint interval default frequency has changed, resulting in much smaller file sizes. There are also a few minor changes as a result of migrating to use **konnektor** as the backend for many network generators. **Added:** * Added support for openmm 8.2 (`PR #1366 `_) * Added optional ``n_processes`` (number of parallel processes to use when generating the network) arguments for network planners (`PR #927 `_). * Added optional ``progress`` (whether to show progress bar) for ``openfe.setup.ligand_network_planning.generate_radial_network`` (default= ``False``, such that there is no default behavior change)(`PR #927 `_). * Added compatibility for numpy v2 (`PR #1260 `_). **Changed:** * The checkpoint interval default frequency has been increased to every nanosecond. ``real_time_analysis_interval`` no longer needs to be divisible by the checkpoint interval, allowing users of the ``HybridTopologyProtocol`` and ``AbsoluteSolvationProtocol`` to write checkpoints less frequently and yielding smaller file sizes. * `konnektor `_ is now used as the backend for all network generation (`PR #927 `_). * ``openfe.setup.ligand_network_planning.generate_maximal_network`` now returns the *best* mapping for each edge, rather than *all possible* mappings for each edge. If multiple mappers are passed but no scorer, the first mapper passed will be used, and a warning will be raised (`PR #927 `_). **Fixed:** * Absolute free energy calculations (e.g. ``AbsoluteSolvationProtocol``) now correctly pass the equilibrated box vectors to the alchemical simulation. In the past default vectors were used, which in some cases led to random crashes due to an abrupt volume change. We do not believe that this significantly affected free energy results (`PR #1275 `_). v1.4.0 ==================== This release includes significant quality of life improvements for the CLI's ``openfe gather`` command. **Added:** * ``openfe gather`` now accepts any number of filepaths and/or directories containing results JSON files, instead of only accepting one results directory (`PR #1212 `_). * When running ``openfe gather --report=dg`` and result edges have fewer than 2 replicates, an error will be thrown up-front instead of failing downstream with a ``numpy.linalg.LinAlgError: SVD did not converge`` error (`PR #1243 `_). * ``openfe gather`` includes failed simulations in its output, with ``Error`` listed in place of a computed value, instead of simply omitting those results from the output table (`PR #1227 `_). * ``openfe gather --report=dg`` (the default) checks for connectivity of the results network and throws an error if the network is disconnected or has fewer than 3 edges (`PR #1227 `_). * ``openfe gather`` prints warnings for all results JSONs whose simulations have failed or are otherwise invalid (`PR #1227 `_ ). * ``openfe gather`` now throws an error up-front if no valid results are provided, instead of returning an empty table (`PR #1245 `_). **Changed:** * Improved formatting of ``openfe gather`` output tables. Use ``--tsv`` to instead view the raw tsv formatted output (this was the default behavior as of v1.3.x) (`PR #1246 `_). * Improved responsiveness of several CLI commands (`PR #1254 `_). v1.3.1 ==================== Bugfix release - Improved error handling and code cleanup. We are also dropping official support for MacOSX-x86_64. Any platform-specific bugs will be addressed when possible, but as a low priority. **Added:** * ``openfe gather`` now detects failed simulations up-front and prints warnings to stdout (`PR #1207 `_). **Changed:** * Temporarily disabled bootstrap uncertainties in forward/reverse analysis due to solver loop issues when dealing with too small a set of samples (`PR #1174 `_). **Removed:** * Dropped official support for MacOSX-x86_64. Any platform-specific bugs will be addressed when possible, but as a low priority. * Unused trajectory handling code was removed from ``openfe.utils``, please use ``openfe-analysis`` instead (`PR #1182 `_). **Fixed:** * Fixed `issue #1178 `_ -- The GPU system probe is now more robust to different ways the ``nvidia-smi`` command can fail (`PR #1186 `_) * Fixed bug where openmm protocols using default settings would re-load from JSON as a different gufe key due to unit name string representation discrepancies (`PR #1210 `_) v1.3.0 ==================== **Added:** * Added CLI support for ``generate_lomap_network``. This option can be specified as a `YAML-defined setting `_ * Added ``--n-protocol-repeats`` CLI option to allow user-defined number of repeats per quickrun execution. This allows for parallelizing execution of repeats by setting ``--n-protocol-repeats=1`` and calling ``quickrun`` on the same input file multiple times. * Added a new CLI command (``charge-molecules``) to bulk assign partial charges to molecules `PR#1068 `_ * CLI setup will raise warnings for unsupported top-level YAML fields. * OpenMMEngineSettings now has a `gpu_device_index` attribute allowing users to pass through a list of ``ints`` to select the GPU devices to run their simulations on. * Add support for variable position/velocity trajectory writing. * ``openfe gather`` now supports replicates that have been submitted in parallel across separate directories. **Changed:** * Networks planned using the CLI will now automatically use an extended protocol for transformations involving a net charge change `PR#1053 `_ * The ``plan-rhfe-network`` and ``plan-rbfe-network`` CLI commands will now assign partial charges before planning the network if charges are not present, the charge assignment method can be controlled via the yaml settings file `PR#1068 `_ * `openfe.protocols.openmm_rfe._rfe_utils.compute` has been moved to `openfe.protocols.openmm_utils.omm_compute`. * ``openfe gather`` now includes *all* edges with missing runs (instead of just the first failing edge) when raising a "missing runs" error. * ``openfe quickrun`` now creates the parent directory as-needed for user-defined output json paths (``-o``). * The MBAR bootstrap (1000 iterations) error is used to estimate protocol uncertainty instead of the statistical uncertainty (one standard deviation) and pymbar3 is no longer supported `PR#1077 `_ * CLI network planners' default names use prefixes `rbfe_` or `rhfe_` , instead of `easy_rbfe` or `easy_rhfe`, to simplify default transformation names. **Removed:** * openfe is no longer tested against macos-12. macos support is, for now, limited to osx-arm64 (macos-14+). **Fixed:** * ``openfe quickrun`` now creates the parent directory as-needed for user-defined output json paths (``-o``). * OpenMM CPU vacuum calculations now enforce the use of a single CPU to avoid large performance losses. v1.2.0 ==================== **Added:** * New `cookbook featuring bespokefit `_ **Fixed:** * Improved responsiveness of CLI calls * Fixed bug where `openfe gather --report raw` was only including first replicates. v1.1.0 ==================== **Added:** * Extended system solvation tooling, including support for; non-cubic boxes, explicitly defining the number of waters added, the box vectors, and box size as supported by `Modeller.addSolvent` in OpenMM 8.0 and above. **Changed:** * Improved documentation of the OpenMMSolvationSettings. * The `PersesAtomMapper` now uses openff.units inline with the rest of the package. * Structural analysis data is no longer written to `structural_analysis.json` but rather a 32bit numpy compressed file named `structural_analysis.npz` (`PR #937 `_). * Structural analysis array data is no longer directly returned in the RelativeHybridTopologyProtocol result dictionary. Instead it should be accessed from the serialized NPZ file `structural_analysis.npz`. The `structural_analysis` key now contains a path to the NPZ file, if the structural analysis did not fail (the `structural_analysis_error` key will instead be present on failure) (`PR #937 `_). * Add duecredit citations for pymbar when calling `openfe.protocols.openmm_utils.multistate_analysis`. **Fixed:** * 2D RMSD plotting now allows for fewer than 5 states (`PR #896 `_). * 2D RMSD plotting no longer draws empty axes when the number of states - 1 is not divisible by 4 (`PR #896 `_). * The RelativeHybridTopologyProtocol result unit is now much smaller, due to the removal of structural analysis data (`PR #937 `_). v1.0.1 ==================== **Added:** * Debug script in devtools to test OpenMM installation. * Use rever to manage changelog. **Changed:** * Updated docs to reference miniforge instead of mambaforge since they are the same now, see https://github.com/conda-forge/miniforge?tab=readme-ov-file#whats-the-difference-between-mambaforge-and-miniforge. * The LomapAtomMapper defaults have now changed to better reflect real-life usage. Key kwarg changes include; `max3d=1.0` and `shift=False`. **Fixed:** * Calling `get_forward_and_reverse_energy_analysis` in the RFE and AFE protocols now results a warning if any results are ``None`` due to MBAR convergence issues. * Checkpoint interval default value has been set to 250 ps instead of 1 ps. This better matches the previous default for openfe versions < 1.0rc (See `issue #772 `_ ). ================================================ FILE: docs/Makefile ================================================ # Minimal makefile for Sphinx documentation # # You can set these variables from the command line, and also # from the environment for the first two. SPHINXOPTS ?= -v -W --keep-going SPHINXBUILD ?= sphinx-build SOURCEDIR = . BUILDDIR = _build # Put it first so that "make" without argument is like "make help". help: @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) .PHONY: help Makefile # Catch-all target: route all unknown targets to Sphinx using the new # "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). %: Makefile @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) ================================================ FILE: docs/_ext/sass.py ================================================ """ sphinxcontrib-sass https://github.com/attakei-lab/sphinxcontrib-sass Kayuza Takei Apache 2.0 Modified to: - Write directly to Sphinx output directory - Infer targets if not given - Ensure ``target: Path`` in ``configure_path()`` - Return version number and thread safety from ``setup()`` - Use compressed style by default - More complete type checking """ from os import PathLike from pathlib import Path from typing import Optional, Union import sass from sphinx.application import Sphinx from sphinx.environment import BuildEnvironment from sphinx.util import logging logger = logging.getLogger(__name__) def configure_path(conf_dir: str, src: Optional[Union[PathLike, Path]]) -> Path: if src is None: target = Path(conf_dir) else: target = Path(src) if not target.is_absolute(): target = Path(conf_dir) / target return target def get_targets(app: Sphinx) -> dict[Path, Path]: src_dir = configure_path(app.confdir, app.config.sass_src_dir) dst_dir = configure_path(app.outdir, app.config.sass_out_dir) if isinstance(app.config.sass_targets, dict): targets = app.config.sass_targets else: targets = { path: path.relative_to(src_dir).with_suffix(".css") for path in src_dir.glob("**/[!_]*.s[ca]ss") } return {src_dir / src: dst_dir / dst for src, dst in targets.items()} def build_sass_sources(app: Sphinx, env: BuildEnvironment): logger.debug("Building stylesheet files") include_paths = [str(p) for p in app.config.sass_include_paths] targets = get_targets(app) output_style = app.config.sass_output_style # Build css files for src, dst in targets.items(): content = src.read_text() css = sass.compile( string=content, output_style=output_style, include_paths=[str(src.parent)] + include_paths, ) dst.parent.mkdir(exist_ok=True, parents=True) dst.write_text(css) def setup(app: Sphinx): """ Setup function for this extension. """ logger.debug(f"Using {__name__}") app.add_config_value("sass_include_paths", [], "html") app.add_config_value("sass_src_dir", None, "html") app.add_config_value("sass_out_dir", None, "html") app.add_config_value("sass_targets", None, "html") app.add_config_value("sass_output_style", "compressed", "html") app.connect("env-updated", build_sass_sources) return { "version": "0.3.4ofe", "parallel_read_safe": True, "parallel_write_safe": True, } ================================================ FILE: docs/_sass/deflist-flowchart.scss ================================================ :root { --arrow-thickness: 4px; --arrow-head-size: 7px; --arrow-length: 2em; --arrow-multiple-gap: 20px; --arrow-color: var(--pst-color-text-muted); --arrow-fade-dist: 0px; --flowchart-def-bg-color: var(--pst-color-surface); --flowchart-bg-color: var(--pst-color-background); --flowchart-def-border-color: var(--pst-color-border); --flowchart-unit-width: 45px; --flowchart-spacing: 0.5rem; --flowchart-column-gap: calc(1.5 * var(--flowchart-spacing)); --flowchart-top-label-space: 26px; } .arrow.thick { --arrow-thickness: 6px; --arrow-head-size: 10px; } .deflist-flowchart ul, ul.deflist-flowchart { display: flex; flex-direction: column; justify-content: space-between; height: 100%; grid-column-gap: var(--flowchart-column-gap); margin: 0; padding: 0; } .deflist-flowchart { margin: 1em 0; p:first-child { margin-top: 0; } p:last-child { margin-bottom: 0; } li, li ul { margin: 0; padding: 0; } li:empty:not([class]) { display: None; } li { list-style: none; } .arrow-down::after, .arrow-up::after, .arrow-multiple.arrow-down::before, .arrow-multiple.arrow-up::before, .arrow-cycle::after, .arrow-cycle::before { content: ""; } .arrow-down, .arrow-up, .arrow-cycle { --arrow-head-size-clamped: calc(min(var(--arrow-head-size), var(--arrow-length) / 2)); display: flex; justify-content: center; align-items: center; flex-grow: 1; min-height: var(--arrow-length); width: 100%; margin: calc(2 * var(--flowchart-spacing)) auto; position: relative; z-index: 1; padding: calc(var(--arrow-length) / 4) 0; &::before, &::after { --actual-arrow-length: max(var(--arrow-length), 100%); --arrow-tail-gradient: linear-gradient( 45deg, transparent calc(50% - var(--arrow-thickness)/2), var(--arrow-color) calc(50% - var(--arrow-thickness)/2), var(--arrow-color) calc(50% + var(--arrow-thickness)/2), transparent calc(50% + var(--arrow-thickness)/2) ); --arrow-head-gradient: linear-gradient( -45deg, var(--arrow-color) var(--arrow-head-size-clamped), transparent var(--arrow-head-size-clamped) ); height: calc(var(--actual-arrow-length)/1.4142); width: auto; aspect-ratio: 1; padding: 0; display: inline-block; transform: rotate(45deg); background-image: var(--arrow-tail-gradient), var(--arrow-head-gradient); position: absolute; top: 0; left: 50%; transform-origin: 0 0; z-index: -1; } &.arrow-tail { &::before, &::after { background-image: var(--arrow-tail-gradient); } } > p { background: linear-gradient( transparent, var(--flowchart-bg-color) var(--arrow-fade-dist), var(--flowchart-bg-color) calc(100% - var(--arrow-fade-dist)), transparent, ); line-height: 1.5; z-index: 10; } } .arrow-down:not(.arrow-tail), .arrow-cycle { padding-bottom: calc(var(--arrow-head-size-clamped) + var(--arrow-length) / 4); } .arrow-up:not(.arrow-tail), .arrow-cycle { padding-top: calc(var(--arrow-head-size-clamped) + var(--arrow-length) / 4); } .arrow-cycle, .arrow-multiple { &::after { translate: calc(0.5 * var(--arrow-multiple-gap)) 0; } &::before { translate: calc(-0.5 * var(--arrow-multiple-gap)) 0; } } .arrow-up::after, .arrow-multiple.arrow-up::before, .arrow-cycle::before { transform: rotate(-135deg); translate: 0 calc(var(--actual-arrow-length) + 2 * var(--flowchart-spacing) + var(--arrow-head-size-clamped) / 2); } .arrow-cycle::before { translate: calc(-0.5 * var(--arrow-multiple-gap)) 140%; } .arrow-aside { margin-left: calc(8 * var(--arrow-head-size-clamped)); &::after { left: calc(-4 * var(--arrow-head-size-clamped)); } } .arrow-multiple-combine { &::before { content: ""; width: var(--arrow-multiple-gap); border: var(--arrow-thickness) solid var(--arrow-color); height: calc(var(--arrow-length) / 2); background: var(--flowchart-bg-color); transform: none; left: auto; z-index: 2; } &.arrow-down { padding-top: calc(0.75 * var(--arrow-length) - var(--arrow-head-size-clamped) / 2); padding-bottom: calc(0.5 * var(--arrow-head-size-clamped) + 0.25 * var(--arrow-length)); &::before { border-top: 1px solid var(--flowchart-bg-color); } } &.arrow-up { &::before { border-bottom: 1px solid var(--flowchart-bg-color); top: auto; bottom: -1px; } } } .arrow-tail { &.arrow-down { margin-bottom: 0; } &.arrow-up { margin-top: 0; } } .arrow-head { &.arrow-up { margin-bottom: 0; } &.arrow-down { margin-top: 0; } } .arrow-combine, .arrow-combine-left, .arrow-combine-right { &.arrow-down.arrow-tail, &.arrow-up.arrow-head { --arrow-combine-gradient-angle: 0deg; padding-bottom: calc(0.5 * var(--arrow-thickness)); margin-bottom: calc(-0.5 * var(--arrow-thickness)); } &.arrow-up.arrow-tail, &.arrow-down.arrow-head { --arrow-combine-gradient-angle: 180deg; padding-top: calc(0.5 * var(--arrow-thickness)); margin-top: calc(-0.5 * var(--arrow-thickness)); } background-image: linear-gradient( var(--arrow-combine-gradient-angle), var(--arrow-color) var(--arrow-thickness), transparent var(--arrow-thickness) ); background-repeat: no-repeat; width: calc(max(100% + 2 * var(--flowchart-column-gap), var(--flowchart-unit-width))); margin-left: calc(-1 * var(--flowchart-column-gap)); &.arrow-combine-left, &.arrow-combine-right { background-size: 50%; &.arrow-multiple { background-size: calc(50% + 0.5 * var(--arrow-multiple-gap)); } } &.arrow-combine-right { background-position-x: 100%; } } > ul > li { &.arrow-down, &.arrow-up, &.arrow-cycle { width: calc(100% - var(--flowchart-top-label-space)); margin-left: 0; } } dl { display: flex; flex-direction: row-reverse; margin: 0; padding: 0 var(--flowchart-spacing); } dt { display: inline-block; writing-mode: vertical-rl; margin-top: .25rem; flex-grow: 0; width: var(--flowchart-top-label-space); font-size: 1.1em; } dd { text-align: center; position: relative; border: 1px solid var(--flowchart-def-border-color); border-radius: .25rem; margin: 0; display: inline-block; flex-grow: 1; container-type: inline-size; container-name: flowchart; overflow-x: auto; } dd dl { background-color: var(--flowchart-def-bg-color); border-radius: 4px; box-shadow: 0 6px 10px 0 rgba(0,0,0,0.14), 0 1px 18px 0 rgba(0,0,0,0.12), 0 3px 5px -1px rgba(0,0,0,0.4); display: block; margin: 0 auto; padding: calc(var(--flowchart-spacing) / 2); max-width: calc(100cqw - 2 * var(--flowchart-spacing)); min-width: calc(2 * var(--flowchart-unit-width) + var(--flowchart-column-gap)); } dd dt { writing-mode: horizontal-tb; display: block; margin-top: 0; width: unset; font-size: unset; } dd dd { border: none; display: block; container-type: unset; overflow-x: unset; padding: calc(var(--flowchart-spacing) / 2); } dd > ul { width: fit-content; padding: var(--flowchart-spacing); margin: 0 auto; overflow: hidden; } dd dd > ul { min-width: unset; padding: 0; margin: 0; } dl a, a { font-weight: bold; } div.flowchart-sidebyside > ul:only-child { display: flex; flex-direction: row; flex-wrap: nowrap; justify-content: space-between; } .flowchart-spacer { height: 100%; flex-shrink: 9999; min-height: calc(2 * var(--flowchart-spacing)) } .width-1 { width: calc(var(--flowchart-unit-width)); } .width-2 { width: calc(2 * var(--flowchart-unit-width) + var(--flowchart-column-gap)); } .width-3 { width: calc(3 * var(--flowchart-unit-width) + 2 * var(--flowchart-column-gap)); } .width-4 { width: calc(4 * var(--flowchart-unit-width) + 3 * var(--flowchart-column-gap)); } .width-5 { width: calc(5 * var(--flowchart-unit-width) + 4 * var(--flowchart-column-gap)); } .width-6 { width: calc(6 * var(--flowchart-unit-width) + 5 * var(--flowchart-column-gap)); } .width-7 { width: calc(7 * var(--flowchart-unit-width) + 6 * var(--flowchart-column-gap)); } .width-8 { width: calc(8 * var(--flowchart-unit-width) + 7 * var(--flowchart-column-gap)); } .width-9 { width: calc(9 * var(--flowchart-unit-width) + 8 * var(--flowchart-column-gap)); } .width-10 { width: calc(10 * var(--flowchart-unit-width) + 9 * var(--flowchart-column-gap)); } li { &.width-2, &.width-3, &.width-4, &.width-5, &.width-6, &.width-7, &.width-8, &.width-9, &.width-10, &.width-full { > dl { max-width: unset; } } } } ================================================ FILE: docs/_templates/autosummary/base.rst ================================================ .. title:: {{ objname }} .. currentmodule:: {{ module }} .. auto{{ objtype }}:: {{ objname }} ================================================ FILE: docs/_templates/autosummary/class.rst ================================================ .. title:: {{ objname }} .. currentmodule:: {{ module }} .. auto{{ objtype }}:: {{ objname }} ================================================ FILE: docs/conf.py ================================================ # Configuration file for the Sphinx documentation builder. # # This file only contains a selection of the most common options. For a full # list see the documentation: # https://www.sphinx-doc.org/en/master/usage/configuration.html # -- Path setup -------------------------------------------------------------- # If extensions (or modules to document with autodoc) are in another directory, # add these directories to sys.path here. If the directory is relative to the # documentation root, use os.path.abspath to make it absolute, like shown here. # import os import sys from importlib.metadata import version from inspect import cleandoc from pathlib import Path import git import nbformat import nbsphinx from packaging.version import parse sys.path.insert(0, os.path.abspath("../")) os.environ["SPHINX"] = "True" # -- Project information ----------------------------------------------------- project = "OpenFE" copyright = "2022, The OpenFE Development Team" author = "The OpenFE Development Team" # don't include patch version (https://github.com/OpenFreeEnergy/openfe/issues/1261) version = f"{parse(version('openfe')).major}.{parse(version('openfe')).minor}" # -- General configuration --------------------------------------------------- # Add any Sphinx extension module names here, as strings. They can be # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom # ones. extensions = [ "sphinx.ext.autodoc", "sphinx.ext.napoleon", "sphinx_click.ext", "sphinxcontrib.autodoc_pydantic", "sphinx_toolbox.collapse", "sphinx.ext.autosectionlabel", "sphinx_design", "sphinx.ext.intersphinx", "sphinx.ext.autosummary", "docs._ext.sass", "myst_parser", "nbsphinx", "nbsphinx_link", "sphinx.ext.mathjax", ] suppress_warnings = ["config.cache"] # https://github.com/sphinx-doc/sphinx/issues/12300 intersphinx_mapping = { "python": ("https://docs.python.org/3.9", None), "numpy": ("https://numpy.org/doc/stable", None), "scikit.learn": ("https://scikit-learn.org/stable", None), "openmm": ("https://docs.openmm.org/latest/api-python/", None), "rdkit": ("https://www.rdkit.org/docs", None), "openeye": ("https://docs.eyesopen.com/toolkits/python/", None), "mdtraj": ("https://www.mdtraj.org/1.9.5/", None), "openff.units": ("https://docs.openforcefield.org/projects/units/en/stable", None), "gufe": ("https://gufe.openfree.energy/en/latest/", None), } autoclass_content = "both" # Make sure labels are unique # https://www.sphinx-doc.org/en/master/usage/extensions/autosectionlabel.html#confval-autosectionlabel_prefix_document autosectionlabel_prefix_document = True autodoc_pydantic_model_show_json = False autodoc_default_options = { "members": True, "member-order": "bysource", "inherited-members": "GufeTokenizable,BaseModel", "undoc-members": True, "special-members": "__call__", } toc_object_entries_show_parents = "hide" # Add any paths that contain templates here, relative to this directory. templates_path = ["_templates"] # List of patterns, relative to source directory, that match files and # directories to ignore when looking for source files. # This pattern also affects html_static_path and html_extra_path. exclude_patterns = [ "_build", "**/Thumbs.db", "**/.DS_Store", "_ext", "_sass", "**/README.md", "ExampleNotebooks", ] autodoc_mock_imports = [ "cinnabar", "dill", "MDAnalysis", "matplotlib", "mdtraj", "openfe_analysis", "openmmforcefields", "openmmtools", "pymbar", "openff.interchange", "openmmforcefields", "psutil", "py3Dmol", "zstandard", ] # Extensions for the myst parser myst_enable_extensions = [ "dollarmath", "colon_fence", "smartquotes", "replacements", "deflist", "attrs_inline", ] myst_heading_anchors = 3 # -- Options for HTML output ------------------------------------------------- # The theme to use for HTML and HTML Help pages. See the documentation for # a list of builtin themes. # html_theme = "ofe_sphinx_theme" html_theme_options = { "logo": {"text": "OpenFE docs"}, "icon_links": [ { "name": "GitHub", "url": "https://github.com/OpenFreeEnergy/openfe", "icon": "fa-brands fa-square-github", "type": "fontawesome", } ], "accent_color": "cantina-purple", "navigation_with_keys": False, } html_logo = "_static/OFE-color-icon.svg" html_favicon = "_static/OFE-color-icon.svg" # temporary fix, see https://github.com/pydata/pydata-sphinx-theme/issues/1662 html_sidebars = { "installation": [], "CHANGELOG": [], } # Add any paths that contain custom static files (such as style sheets) here, # relative to this directory. They are copied after the builtin static files, # so a file named "default.css" will overwrite the builtin "default.css". # html_static_path = ['_static'] # replace macros rst_prolog = """ .. |rdkit.mol| replace:: :class:`rdkit.Chem.rdchem.Mol` """ # Add any paths that contain custom static files (such as style sheets) here, # relative to this directory. They are copied after the builtin static files, # so a file named "default.css" will overwrite the builtin "default.css". html_static_path = ["_static"] html_css_files = [ "css/custom.css", "css/custom-api.css", "css/deflist-flowchart.css", ] # custom-api.css is compiled from custom-api.scss sass_src_dir = "_sass" sass_out_dir = "_static/css" # Clone or update ExampleNotebooks example_notebooks_path = Path("ExampleNotebooks") try: if example_notebooks_path.exists(): repo = git.Repo(example_notebooks_path) try: repo.remote("origin").pull() except git.exc.GitCommandError: # cannot pull if on a tag pass else: repo = git.Repo.clone_from( "https://github.com/OpenFreeEnergy/ExampleNotebooks.git", branch="2026.04.28", to_path=example_notebooks_path, ) except Exception as e: from sphinx.util.logging import getLogger filename = e.__traceback__.tb_frame.f_code.co_filename lineno = e.__traceback__.tb_lineno getLogger("sphinx.ext.openfe_git").warning( f"Getting ExampleNotebooks failed in {filename} line {lineno}: {e}" ) # First, create links at top of notebook pages # All notebooks are in ExampleNotebooks repo, so link to that # Finally, add sphinx reference anchor in prolog so that we can make refs nbsphinx_prolog = cleandoc(r""" {%- set gh_repo = "OpenFreeEnergy/ExampleNotebooks" -%} {%- set gh_branch = "main" -%} {%- set path = env.doc2path(env.docname, base=None) -%} {%- if path.endswith(".nblink") -%} {%- set path = env.metadata[env.docname]["nbsphinx-link-target"] -%} {%- endif -%} {%- if path.startswith("ExampleNotebooks/") -%} {%- set path = path.replace("ExampleNotebooks/", "", 1) -%} {%- endif -%} {%- set gh_url = "https://www.github.com/" ~ gh_repo ~ "/blob/" ~ gh_branch ~ "/" ~ path -%} {%- set dl_url = "https://raw.githubusercontent.com/" ~ gh_repo ~ "/" ~ gh_branch ~ "/" ~ path -%} .. container:: ofe-top-of-notebook .. button-link:: {{gh_url}} :color: primary :shadow: :outline: :octicon:`mark-github` View on GitHub .. button-link:: {{dl_url}} :color: primary :shadow: :outline: :octicon:`download` Download Notebook .. _{{ env.doc2path(env.docname, base=None) }}: """) ================================================ FILE: docs/cookbook/bespoke_parameters.nblink ================================================ { "path": "../ExampleNotebooks/cookbook/bespoke_parameters_showcase.ipynb" } ================================================ FILE: docs/cookbook/choose_protocol.nblink ================================================ { "path": "../ExampleNotebooks/cookbook/choose_protocol.ipynb" } ================================================ FILE: docs/cookbook/create_alchemical_network.nblink ================================================ { "path": "../ExampleNotebooks/cookbook/create_alchemical_network.ipynb" } ================================================ FILE: docs/cookbook/dumping_transformation.rst ================================================ .. _dumping_transformations: Dumping a ``Transformation`` to JSON ==================================== If you're trying to run a full campaign of simulations representing an alchemical network, we generally recommend saving objects using our storage tools, when avoids saving duplicate information to disk. .. TODO: add links to storage tools once they're complete However, there are situations where it is reasonable to serialize a single :class:`.Transformation`. For example, this can be useful when trying to compare results run on different machines. This also provides a trivial way for a user to run edges in parallel, if they don't want to use the more sophisticated techniques we have developed. For these cases, we have made it very easy for a user to dump a transformation to JSON. Simply use the method :meth:`.Transformation.to_json`. For example: .. code:: transformation.to_json("mytransformation.json") When you do dump a single transformation, it can be reloaded into memory with the :meth:`.Transformation.from_json` method: .. code:: transformation = Transformation.from_json("mytransformation.json") Once you've saved to it JSON, you can also run this transformation with the ``openfe`` command line tool's :ref:`cli_quickrun`, e.g.: .. code:: bash $ openfe quickrun mytransformation.json -d dir_for_files -o output.json ================================================ FILE: docs/cookbook/generate_ligand_network.nblink ================================================ { "path": "../ExampleNotebooks/cookbook/generate_ligand_network.ipynb" } ================================================ FILE: docs/cookbook/hand_write_ligand_network.nblink ================================================ { "path": "../ExampleNotebooks/cookbook/hand_write_ligand_network.ipynb" } ================================================ FILE: docs/cookbook/index.rst ================================================ .. _cookbooks: Cookbook ======== This section describes common tasks involving the OpenFE Python API. The :any:`OpenFE CLI` provides a simple way to perform the most common procedures for free energy calculations, but does not provide much flexibility for fine-tuning your approach or combining OpenFE with other tools. The :any:`Python API` allows that flexibility, but using it is more complex. This cookbook breaks down common steps that would be implemented in Python to help navigate that complexity. .. note:: This section is a work-in-progress. .. module:: openfe :noindex: The Basic Workflow ------------------ The typical way to use the Python API is to load a number of molecules you want to calculate free energies of, construct a :class:`LigandNetwork` connecting them in an efficient way, and then combine that with information for how each ligand should be simulated to construct an :class:`AlchemicalNetwork`, which specifies the entire simulation campaign. This provides a lot of flexibility in how molecules are specified, mapped, connected, and simulated, without exposing a great deal of complexity. OpenFE recommends this workflow for most users. .. container:: deflist-flowchart * Setup - .. container:: flowchart-sidebyside - - .. rst-class:: flowchart-spacer - .. rst-class:: arrow-down arrow-from-nothing - :any:`choose_protocol` - :class:`Protocol` Simulation procedure for an alchemic mutation. .. rst-class:: arrow-down arrow-tail arrow-combine-right - - - .. rst-class:: width-8 - Chemical component definition SDF, PDB, RDKit, OpenFF Molecule, solvent spec, etc. - .. container:: flowchart-sidebyside - .. rst-class:: width-3 - .. rst-class:: arrow-down arrow-multiple - :any:`Loading proteins`, :any:`Defining solvents` - :class:`SolventComponent` and :class:`ProteinComponent` Other chemical components needed to simulate the ligand. .. rst-class:: arrow-down arrow-multiple arrow-tail arrow-combine - - - .. container:: flowchart-sidebyside - .. rst-class:: width-5 - .. rst-class:: arrow-down arrow-multiple - :any:`Loading small molecules` - :class:`SmallMoleculeComponent` The ligands that will be mutated. - .. rst-class:: width-3 - .. rst-class:: flowchart-spacer - - Orion/FEP+ Network from another tool. - .. container:: flowchart-sidebyside - .. rst-class:: width-2 - .. rst-class:: arrow-down arrow-multiple - :any:`generate_ligand_network` - .. rst-class:: width-2 - .. rst-class:: arrow-down arrow-multiple - :any:`hand_write_ligand_network` - .. rst-class:: width-1 - .. rst-class:: arrow-down arrow-tail arrow-multiple arrow-combine-right - .. rst-class:: flowchart-spacer - - .. rst-class:: width-3 - .. rst-class:: arrow-down arrow-tail arrow-combine-left - .. rst-class:: arrow-down arrow-head flowchart-spacer - :any:`network_from_orion_fepp` - :class:`LigandNetwork ` A network of ligand transformations. - .. container:: flowchart-sidebyside - - .. rst-class:: arrow-down arrow-tail arrow-combine-left width-4 - - - .. rst-class:: arrow-cycle width-4 - - :any:`ligandnetwork_vis` .. rst-class:: arrow-down arrow-head - :any:`create_alchemical_network` - :class:`AlchemicalNetwork` A complete simulation campaign. .. rst-class:: arrow-down * :any:`dumping_transformations` * Run - :any:`openfe quickrun ` OpenFE recommends using the ``openfe quickrun`` CLI command to execute a transformation. .. rst-class:: arrow-down * * Gather - :any:`openfe gather ` OpenFE recommends using the ``openfe gather`` CLI command to collect the results of a transformation. List of Cookbooks ----------------- .. toctree:: :maxdepth: 1 loading_molecules dumping_transformation jq_inspection choose_protocol generate_ligand_network rfe_alchemical_planners network_from_orion_fepp hand_write_ligand_network ligandnetwork_vis create_alchemical_network user_charges bespoke_parameters ================================================ FILE: docs/cookbook/jq_inspection.rst ================================================ .. _jq_inspection: Using ``jq`` to inspect OpenFE JSONs ============================================== Sometimes you may want to get a sense of the contents of JSON files, but the files are too unwieldy to inspect one-by-one in a code editor. `jq `_ is a helpful command-line tool that we recommend for for quickly inspecting JSON files. Below is a common use-case to get you started, but you can do much more by checking out the `jq manual `_. To view all the top-level JSON keys, use ``jq "keys" filename.json``, for example with a results JSON from the tutorial: .. code:: bash $ jq "keys" rbfe_lig_ejm_46_solvent_lig_jmc_28_solvent.json [ "estimate", "protocol_result", "uncertainty", "unit_results" ] .. note:: You can use ``"keys[]"`` instead of ``"keys"`` for a cleaner output. Now that you know ``estimate`` is at the top-level of the JSON, you can use the following pattern to see the next level of keys: .. code:: bash $ jq ".estimate | keys " rbfe_lig_ejm_46_solvent_lig_jmc_28_solvent.json { "magnitude", "unit":, ":is_custom:":, "pint_unit_registry": } If you want to show all the keys _and_ their values, simply omit ``| key`` from the query: .. code:: bash $ jq ".estimate" rbfe_lig_ejm_46_solvent_lig_jmc_28_solvent.json { "magnitude": 23.347074789078682, "unit": "kilocalorie / mole", ":is_custom:": true, "pint_unit_registry": "openff_units" } This can be very helpful for quickly checking results for many files, for example: .. code:: bash $ jq ".estimate.magnitude" rbfe*.json -14.925911852820793 -40.72063957254803 -27.76541486479537 -16.023754604070007 -57.38608716292447 -15.748326155729705 -39.933880531487326 -27.780933075807425 -16.76023951588401 -58.36294851896545 -19.038006312251575 -20.26856586311034 17.338257573349775 15.775784163095102 23.134622420900932 17.071712542470248 15.873122071409249 23.347074789078682 ================================================ FILE: docs/cookbook/ligandnetwork_vis.nblink ================================================ { "path": "../ExampleNotebooks/cookbook/ligandnetwork_vis.ipynb" } ================================================ FILE: docs/cookbook/loading_molecules.nblink ================================================ { "path": "../ExampleNotebooks/cookbook/loading_molecules.ipynb" } ================================================ FILE: docs/cookbook/network_from_orion_fepp.nblink ================================================ { "path": "../ExampleNotebooks/cookbook/network_from_orion_fepp.ipynb" } ================================================ FILE: docs/cookbook/rfe_alchemical_planners.nblink ================================================ { "path": "../ExampleNotebooks/cookbook/rfe_alchemical_planners.ipynb" } ================================================ FILE: docs/cookbook/user_charges.nblink ================================================ { "path": "../ExampleNotebooks/cookbook/user_charges.ipynb" } ================================================ FILE: docs/environment.yaml ================================================ name: openfe-docs channels: - https://conda.anaconda.org/conda-forge # explicit pins to speed up build: dependencies: - autodoc-pydantic >= 2.1 - docutils == 0.20 - gitpython - libsass - myst-parser - nbsphinx - nbsphinx-link - openff-toolkit-base == 0.17.0 - openff-units == 0.3.1 - openmm == 8.3.1 - packaging - pip - plugcli >= 0.2.1 - python - pydantic >=2.0.0, <2.12.0 # https://github.com/openforcefield/openff-interchange/issues/1346 - sphinx ==7.2.6 # TODO: debug "duplicate object" warning with later versions - sphinx-click - sphinx-design - sphinx-toolbox - threadpoolctl - tqdm - pip: - git+https://github.com/OpenFreeEnergy/gufe@main - git+https://github.com/OpenFreeEnergy/ofe-sphinx-theme@v0.3.1 # pip install these so that we can make sure docs build on main while these packages' docs are under development - git+https://github.com/OpenFreeEnergy/kartograf@main - git+https://github.com/OpenFreeEnergy/konnektor@main - git+https://github.com/OpenFreeEnergy/lomap@main # These are added automatically by RTD, so we include them here # for a consistent environment. - mock - pillow # - sphinx # - sphinx_rtd_theme ================================================ FILE: docs/guide/cli/cli_basics.rst ================================================ CLI basics ========== The ``openfe`` command consists of several subcommands. This is similar to tools like ``gmx``, which has subcommands like ``gmx mdrun``, or ``conda``, which has subcommands like ``conda install``. To get a list of the subcommands and their descriptions, call ``openfe`` (or ``openfe -h``): .. TODO autogenerate using sphinxcontrib-programoutput .. code:: none Usage: openfe [OPTIONS] COMMAND [ARGS]... This is the command line tool to provide easy access to functionality from the OpenFE Python library. Options: --version Show the version and exit. --log PATH logging configuration file -h, --help Show this message and exit. Network Planning Commands: plan-rhfe-network Plan a relative hydration free energy network, saved as JSON files for the quickrun command. plan-rbfe-network Plan a relative binding free energy network, saved as JSON files for the quickrun command. view-ligand-network Visualize a ligand network Quickrun Executor Commands: gather Gather result jsons for network of RFE results into a TSV file quickrun Run a given transformation, saved as a JSON file Miscellaneous Commands: fetch Fetch tutorial or other resource. charge-molecules Generate partial charges for a set of molecules. test Run the OpenFE test suite The ``--log`` option takes a logging configuration file and sets that logging behavior. If you use it, it must come before the subcommand name. You can find out more about each subcommand by putting ``--help`` *after* the subcommand name, e.g., ``openfe quickrun --help``, which returns .. code:: none Usage: openfe quickrun [OPTIONS] TRANSFORMATION Run the transformation (edge) in the given JSON file. Simulation JSON files can be created with the :ref:`cli_plan-rbfe-network` or from Python a :class:`.Transformation` can be saved using its to_json method:: transformation.to_json("filename.json") That will save a JSON file suitable to be input for this command. Running this command will execute the simulation defined in the JSON file, creating a directory for each individual task (``Unit``) in the workflow. For example, when running the OpenMM HREX Protocol a directory will be created for each repeat of the sampling process (by default 3). Options: -d, --work-dir DIRECTORY Directory in which to store files in (defaults to current directory). If the directory does not exist, it will be created at runtime. -o PATH Filepath at which to create and write the JSON- formatted results. --resume Attempt to resume this transformation's execution using the cache. -h, --help Show this message and exit. For more details on various commands, see the :ref:`cli-reference`. ================================================ FILE: docs/guide/cli/cli_yaml.rst ================================================ .. _userguide_cli_yaml_interface: Customising CLI planning with YAML settings =========================================== The planning commands in the CLI can be made more powerful by supplying YAML-formatted files to customise the planning algorithms. This settings file has a series of sections for customising the different algorithms. For example, the settings file which re-specifies the default behaviour would look like :: network: method: generate_minimal_spanning_network mapper: method: LomapAtomMapper settings: time: 1 threed: True max3d: 0.95 element_change: True partial_charge: method: am1bcc settings: off_toolkit_backend: ambertools The name of the algorithm is given behind the ``method:`` key and the arguments to the algorithm are then optionally given behind the ``settings:`` key. All sections of the file ``network:``, ``mapper:`` and ``partial_charge:`` are optional. The settings YAML file is then provided to the ``-s`` option of ``openfe plan-rbfe-network``: :: openfe plan-rbfe-network -M molecules.sdf -p protein.pdb -s settings.yaml Customising the atom mapper --------------------------- There is a choice to be made as to which atom mapper is used, currently included are the :class:`.LomapAtomMapper` and the :class:`.KartografAtomMapper` (full details in the `Kartograf documentation`_.) .. _Kartograf documentation: https://kartograf.readthedocs.io/en/latest/api/kartograf.mappers.html#kartograf.atom_mapper.KartografAtomMapper For example, to switch to using the ``Kartograf`` atom mapper, this settings YAML could be used :: mapper: method: KartografAtomMapper settings: atom_max_distance: 0.95 atom_map_hydrogens: True map_hydrogens_on_hydrogens_only: False map_exact_ring_matches_only: True Customising the network planner ------------------------------- There are a variety of network planning options available, including :func:`.generate_radial_network`, :func:`.generate_minimal_spanning_network`, and :func:`.generate_minimal_redundant_network`. For example, to plan a radial network using a ligand called 'CHEMBL1078774' as the central ligand, this settings YAML could be given :: network: method: generate_radial_network settings: central_ligand: CHEMBL1078774 Where the required ``central_ligand`` argument has been passed inside the ``settings:`` section. Note that there is a subtle distinction when ligand names could be interpreted as integers. To select the first ligand, the **integer** 0 can be given :: network: method: generate_radial_network settings: central_ligand: 0 Whereas if we wanted to specify the ligand named "0", we would instead explicitly pass this as **a string** to the YAML settings file :: network: method: generate_radial_network settings: central_ligand: '0' Customising the partial charge generation ----------------------------------------- There are a range of partial charge generation schemes available, including * ``am1bcc`` * ``am1bccelf10`` (only possible if ``off_toolkit_backend`` in settings is set to ``openeye``) * ``nagl`` (must have ``openff-nagl`` installed) * ``espaloma`` (must have ``espaloma_charge`` installed) The following settings can also be set * ``off_toolkit_backend`` The backend to use for partial charge generation. Choose from ``ambertools`` (default), ``openeye`` or ``rdkit``. * ``number_of_conformers`` The number of conformers to use for partial charge generation. If unset (default), the input conformer will be used. * ``nagl_model``: The NAGL model to use. If unset (default), the latest available production charge model will be used. For example, to generate the partial charges using the ``am1bccelf10`` method from ``openeye`` the following should be added to the YAML settings file :: partial_charge: method: am1bccelf10 settings: off_toolkit_backend: openeye For more information on the different options, please refer to the :class:`.OpenFFPartialChargeSettings`. ================================================ FILE: docs/guide/cli/index.rst ================================================ .. _userguide_cli_interface: CLI Interface ============= In addition to the powerful Python API, OpenFE provides a simple command line interface to facilitate some more common (and less complicated) tasks. The Python API tries to be as easy to use as possible, but the CLI provides wrappers around some parts of the Python API to make it easier to integrate into non-Python workflows. .. toctree:: cli_basics cli_yaml ================================================ FILE: docs/guide/execution/execution_theory.rst ================================================ .. _userguide_execution_theory: Protocols and the Execution Model Theory ======================================== Protocols in OpenFE are built on a flexible execution model. Result objects are shaped by this model, and therefore some basic background on it can be useful when looking into the details of simulation results. In general, most users don't need to work with the details of the execution model, but the general ideas can be useful. .. TODO figure showing an example dag Each protocol involves a number of steps (called ``ProtocolUnit``\ s) which occur in some order. Formally, this is described by a directed acyclic graph (DAG), so the collection of steps to run is called a ``ProtocolDAG``. A :class:`.Protocol` creates the ``ProtocolDAG``, and a single ``ProtocolDAG`` should give information necessary to obtain an estimate of the desired thermodynamic observable. Over the course of a campaign, a single :class:`.Protocol` may create multiple ``ProtocolDAG``\ s, e.g., to extend a simulation. NB: While independent runs can be created as separate ``ProtocolDAG``\ s, the recommend way to do independent runs is as a ``repeats`` part of the settings for the protocol, which puts the independent runs in a single ``ProtocolDAG``. .. TODO review recommendation for repeats in context of NEQ protocol There are results objects at each level of this: so the :class:`.ProtocolResult` is associated with the :class:`.Protocol`. Just as the :class:`.Protocol` may create one or more ``ProtocolDAG``\ s, the :class:`.ProtocolResult` will be made from one or more :class:`.ProtocolDAGResult`\ s. Finally, each :class:`.ProtocolDAGResult` may carry information about multiple :class:`.ProtocolUnitResult`\ s, just a single ``ProtocolDAG`` may involve multiple ``ProtocolUnit``\ s. .. TODO FUTURE: figure showing the relations of protocol objects and result objects .. TODO FUTURE: add information about scratch/shared/permanent storage once that becomes relevant ================================================ FILE: docs/guide/execution/index.rst ================================================ .. _userguide_execution: Execution ========= With a :class:`.Transformation` defined, the next step is to execute this. The easiest way to run it is to use the :ref:`quickrun CLI tool `. More advanced options are available through first considering the :ref:`theory of the execution model` then :ref:`reading on the available Python functions`. .. toctree:: quickrun_execution execution_theory ================================================ FILE: docs/guide/execution/quickrun_execution.rst ================================================ .. _userguide_quickrun: Execution with Quickrun ======================= The planning and preparation of a campaign of alchemical simulations using ``openfe`` is intended to be achievable on a local workstation in a matter of minutes. The *execution* of these simulations however requires a large amount of computational power, and beyond running single calculations locally, is intended to be distributed across a HPC environment. Doing this requires storing and sending the details of the simulation from the local workstation to a HPC environment, which can be done via the :func:`.Transformation.to_json` function which :ref:`creates a saved JSON version of the data`. These serialized JSON files are the currency of executing a campaign of simulations and contain all the information required to execute a single simulation. To read the ``Transformation`` information and execute the simulation, the command line interface provides the ``openfe quickrun`` command, the full details of which are given in :ref:`the CLI reference section`. Basic quickrun usage -------------------- The ``quickrun`` command takes in the ``Transformation`` information represented as JSON, then executes a simulation according to those specifications. For example, the following command executes a simulation defined by ``transformation.json`` and produces a results file named ``results.json``. :: > openfe quickrun transformation.json -d workdir/ -o workdir/results.json The ``-d`` / ``--work-dir`` flag controls where working files (checkpoints, trajectory data, etc...) are written. If it is omitted, the current directory will be used. The ``-o`` flag controls where the results file will be written. If it is omitted, results are written to a file named ``_results.json`` in the working directory, where ```` is a unique identifier. Resuming a halted job --------------------- When ``openfe quickrun`` starts, it saves a plan of the simulation to a cache file before execution begins: .. code:: bash /quickrun_cache/dag-cache-.json Where ```` is a unique identifier based on the ``-o`` file path and Transformation. This cache is automatically removed once the job completes. If a job is interrupted (e.g. due to a wall-time limit, node failure, or manual cancellation), you can resume the interrupted job by passing the ``--resume`` flag: .. code:: bash > openfe quickrun transformation.json -d workdir/ -o workdir/results.json --resume The planned simulation cache will be used to identify where in the simulation process it left off and, if supported by the Transformation Protocol, how to resume. .. note:: The same ``-d`` / ``--work-dir`` and ``-o`` flag arguments used in the original run must be specified so that ``quickrun`` can locate the cache file. If you pass ``--resume`` but no cache file is found (e.g. the job never started), the following warning is printed and a fresh execution begins. .. code:: bash openfe quickrun was run with --resume, but no cached results found at . Starting new execution. If the cache file is corrupted (e.g. due to an incomplete write at the moment of interruption), ``quickrun --resume`` will raise an error with instructions to rerun the simulation: .. code:: bash Recovery failed, please remove /quickrun_cache/dag-cache-.json before executing a new transformation simulation. If you do not pass the ``--resume`` flag, the code will detect the partially complete transformation and prevent you from accidentally starting a duplicate run. The following error will be raised: .. code:: bash Transformation has been started but is incomplete. Please remove /quickrun_cache/dag-cache-.json and rerun, or resume execution using the ``--resume`` flag. Executing within a job submission script ---------------------------------------- You may need to submit computational jobs to a queueing engine, such as Slurm. The ``openfe quickrun`` command can be used within a submission script as follows: .. code-block:: bash #!/bin/bash #SBATCH --job-name="openfe job" #SBATCH --mem-per-cpu=2G # activate an appropriate conda environment, or any "module load" commands required to conda activate openfe_env openfe quickrun transformation.json -d workdir/ -o workdir/results.json Parallel execution of repeats with Quickrun =========================================== Serial execution of multiple repeats of a transformation can be inefficient when simulation times are long. Higher throughput can be achieved with parallel execution by running one repeat per HPC job. Most protocols are set up to run three repeats in serial by default, but this can be changed by either: 1. Defining the protocol setting ``protocol_repeats`` - see the :ref:`protocol configuration guide ` for more details. 2. Using the ``openfe plan-rhfe-network`` (or ``plan-rbfe-network``) command line flag ``--n-protocol-repeats``. Each transformation can then be executed multiple times via the ``openfe quickrun`` command to produce a set of repeats. However, **you must use unique results files for each repeat to ensure they don't overwrite each other**. We recommend using folders named ``results_x`` where x is 0-2 to store the repeated calculations as our :ref:`openfe gather ` command also supports this file structure. Below is an example of a simple script that will create and submit a separate job script (``\*.job`` named file) for every alchemical transformation (for the simplest SLURM use case) in a network running each repeat in parallel and writing the results to a unique folder: .. code-block:: bash for file in network_setup/transformations/*.json; do relpath="${file:30}" # strip off "network_setup/" dirpath=${relpath%.*} # strip off final ".json" jobpath="network_setup/transformations/${dirpath}.job" if [ -f "${jobpath}" ]; then echo "${jobpath} already exists" exit 1 fi for repeat in {0..2}; do cmd="openfe quickrun ${file} -o results_${repeat}/${relpath} -d results_${repeat}/${dirpath} --n-protocol-repeats 1" echo -e "#!/usr/bin/env bash\n${cmd}" > "${jobpath}" sbatch "${jobpath}" done done This should result in the following file structure after execution: :: results_parallel ├── results_0 │   ├── rbfe_lig_ejm_31_complex_lig_ejm_42_complex.json │   ├── shared_HybridTopologyMultiStateAnalysisUnit-5e0825de1dd045818cdc3428205c1cf7_attempt_0 │   │   ├── forward_reverse_convergence.png │   │   ├── ligand_RMSD.png │   │   ├── mbar_overlap_matrix.png │   │   ├── replica_exchange_matrix.png │   │   ├── replica_state_timeseries.png │   │   └── structural_analysis.npz │   ├── shared_HybridTopologyMultiStateSimulationUnit-144be594cf024cb19152cfe5e0b3fb7d_attempt_0 │   │   ├── checkpoint.chk │   │   ├── simulation.nc │  │  └── simulation_real_time_analysis.yaml │   └── shared_HybridTopologySetupUnit-01b5afe1972c4e2f9d0943da43b4b19c_attempt_0 │   ├── A_db.json │   ├── B_db.json │   ├── hybrid_positions.npy │   ├── hybrid_system.pdb │   └── hybrid_system.xml.bz2 ├── results_1 │   ├── rbfe_lig_ejm_31_complex_lig_ejm_42_complex.json │   ├── shared_HybridTopologyMultiStateAnalysisUnit-7986bec616a74929aee85e900535f4a2_attempt_0 │   │   ├── forward_reverse_convergence.png │   │   ├── ligand_RMSD.png │   │   ├── mbar_overlap_matrix.png │   │   ├── replica_exchange_matrix.png │   │   ├── replica_state_timeseries.png │   │   └── structural_analysis.npz │   ├── shared_HybridTopologyMultiStateSimulationUnit-18eb295b7123444f9ac66ff3caffcab8_attempt_0 │   │   ├── checkpoint.chk │   │   ├── simulation.nc │  │  └── simulation_real_time_analysis.yaml │   └── shared_HybridTopologySetupUnit-3d8ccb1ef5124bd4ba20e0047aad0b5f_attempt_0 │   ├── A_db.json │   ├── B_db.json │   ├── hybrid_positions.npy │   ├── hybrid_system.pdb │   └── hybrid_system.xml.bz2 └── results_2 ├── rbfe_lig_ejm_31_complex_lig_ejm_42_complex.json ├── shared_HybridTopologyMultiStateAnalysisUnit-ac5fad8ad1fb49598f80018713dce070_attempt_0 │   ├── forward_reverse_convergence.png │   ├── ligand_RMSD.png │   ├── mbar_overlap_matrix.png │   ├── replica_exchange_matrix.png │   ├── replica_state_timeseries.png │   └── structural_analysis.npz ├── shared_HybridTopologyMultiStateSimulationUnit-73abea21b423444881bd8f21415c937f_attempt_0 │   ├── checkpoint.chk    │   ├── simulation.nc   │  └── simulation_real_time_analysis.yaml └── shared_HybridTopologySetupUnit-79bc9b63321945338a3b69d9f94ee15b_attempt_0 ├── A_db.json ├── B_db.json ├── hybrid_positions.npy ├── hybrid_system.pdb └── hybrid_system.xml.bz2 The results of which can be gathered from the CLI using the ``openfe gather`` command, in this case you should direct it to the root directory which includes the repeat results and it will automatically collate the information :: > openfe gather results_parallel Optimizing GPU performance with NVIDIA MPS ========================================== You can further optimize execution of ``openfe quickrun`` using NVIDIA's Multi-Process Service (MPS). See NVIDIA's documentation on `MPS for OpenFE free energy calculations `_ for details. See Also -------- - :ref:`userguide_results` - details on inspecting these results. - :ref:`cli-reference` - full CLI reference for ``openfe quickrun`` - :ref:`rbfe_cli_tutorial` - a tutorial on how to use the CLI to run hybrid topology relative binding free energy calculations. ================================================ FILE: docs/guide/index.rst ================================================ User\ |nbsp|\ Guide =================== .. toctree:: :maxdepth: 2 introduction setup/index execution/index results/index cli/index protocols/index under_the_hood troubleshooting .. |nbsp| unicode:: 0xA0 .. copyright sign :trim: ================================================ FILE: docs/guide/introduction.rst ================================================ .. _guide-introduction: Introduction ============ Here we present an overview of the workflow for calculating free energies in OpenFE in the broadest strokes possible. This workflow is reflected in both the Python API and in the command line interface, and so we have a section for each. Workflow overview ----------------- The overall workflow of OpenFE involves three stages: 1. :ref:`Simulation setup `: Defining the simulation campaign you are going to run. 2. :ref:`Execution `: Running and performing initial analysis of your simulation campaign. 3. :ref:`Gather results `: Assembling the results from the simulation campaign for further analysis. In many use cases, these stages may be done on different machines. For example, you are likely to make use of HPC or cloud computing resources to run the simulation campaign. Because of this, each stage has a defined output which is then the input for the next stage: .. TODO make figure .. .. figure:: ??? :alt: Setup -> (AlchemicalNetwork) -> Execution -> (ProtocolResults) -> Gather The main stages of a free energy calculation in OpenFE, and the intermediates between them. The output of the :ref:`simulation setup ` stage is an :class:`.AlchemicalNetwork`. This contains all the information about what is being simulated (e.g., what ligands, host proteins, solvation details, etc.) and the information about how to perform the simulation (the Protocol). The output of the :ref:`execution ` stage is the basic results from each edge. This can depend of the specific analysis intended, but will either involve a :class:`.ProtocolResult` representing the calculated :math:`\Delta G` for each edge or the :class:`.ProtocolDAGResult` linked to the data needed to calculate that :math:`\Delta G`. The :ref:`gather results ` stage aggregates the individual results for further analysis. For example, the CLI's ``gather`` command will create a table of the :math:`\Delta G` for each leg. For more workflow details, see :ref:`under-the-hood`. .. TODO: Should the CLI workflow be moved to under "CLI Interface"? CLI Workflow ------------ We have separate CLI commands for each stage of setup, execution, and gathering results. With the CLI, the Python objects of :class:`.AlchemicalNetwork` and :class:`.ProtocolResult` are stored to disk in an intermediate representation between the commands. .. TODO make figure .. .. figure:: ??? :alt: [NetworkPlanner -> AlchemicalNetwork] -> Transformation JSON -> quickrun -> Result JSON -> gather The CLI workflow, with intermediates. The setup stage uses a network planner to generate the network, before saving each transformation as a JSON file. The commands used to generate an :class:`.AlchemicalNetwork` using the CLI are: * :ref:`cli_plan-rbfe-network` * :ref:`cli_plan-rhfe-network` .. note:: To ensure a consistent set of partial charges are used for each molecule across different transformations, the CLI network planners will now automatically generate charges ahead of planning the network. The partial charge generation scheme can be configured using the :ref:`YAML settings `. We also provide tooling to generate the partial charges as a separate CLI step which can be run before network planning, see the :ref:`tutorial ` for more details. For example, you can create a relative binding free energy (RBFE) network using .. code:: bash $ openfe plan-rbfe-network -p protein.pdb -M dir_with_sdfs/ This will save the alchemical network represented as a JSON file for each edge of the :class:`.AlchemicalNetwork` (i.e., each leg of the alchemical cycle). To run a given transformation, use the :ref:`cli_quickrun`; for example: .. code:: bash $ openfe quickrun mytransformation.json -d dir_for_files -o output.json In many cases, you will want to create a job script for a queuing system (e.g., SLURM) that wraps that command. You can do this for all JSON files from the network planning command with something like this: .. TODO Link to example here. I think this is waiting on the CLI example being merged into example notebooks? Finally, assuming all results (and only results) are in the `results/` directory, use the :ref:`cli_gather` to generate a summary table: .. code:: bash $ openfe gather ./results/ -o final_results.tsv This will output a tab-separated file with the ligand pair, the estimated :math:`\Delta G` and the uncertainty in that estimate. The CLI provides a very straightforward user experience that works with the most simple use cases. For use cases that need more workflow customization, the Python API makes it relatively straightforward to define exactly the simulation you want to run. The next sections of this user guide will illustrate how to customize the behavior to your needs. ================================================ FILE: docs/guide/protocols/absolutebinding.rst ================================================ .. _userguide_abfe_protocol: Absolute Binding Protocol ========================= Overview -------- The :class:`AbsoluteBindingProtocol <.AbsoluteBindingProtocol>` calculates the absolute binding free energy, which is the free energy difference between a ligand in solution and the ligand bound to a protein. The absolute binding free energy is calculated through a thermodynamic cycle. In this cycle, the interactions of the molecule are decoupled, meaning turned off, using a partial annihilation scheme (see below) both in the solvent and in the complex phases. Restraints are required to keep the weakly coupled and fully decoupled ligand in the binding site region and thereby reduce the phase space that needs to be sampled. In the :class:`AbsoluteBindingProtocol <.AbsoluteBindingProtocol>` we apply orientational, or Boresch-style, restraints, as described below. The absolute binding free energy is then obtained via summation of free energy differences along the thermodynamic cycle. .. figure:: img/abfe-cycle.png :scale: 50% Thermodynamic cycle for the absolute binding free energy protocol. Scientific Details ------------------ Orientational restraints ~~~~~~~~~~~~~~~~~~~~~~~~ Orientational, or Boresch-style, restraints are automatically (unless manually specified) applied between three protein and three ligand atoms using one bond, two angle, and three dihedral restraints. Reference atoms are picked based on different criteria, such as the root mean squared fluctuation of the atoms in a short MD simulation, the secondary structure of the protein, and the distance between atoms, based on heuristics from Baumann et al. [1]_ and Alibay et al. [2]_. Two strategies for selecting protein atoms are available, either picking atoms that are bonded to each other or that can span multiple residues. This can be specified using the ``restraint_settings.anchor_finding_strategy`` settings. Partial annihilation scheme ~~~~~~~~~~~~~~~~~~~~~~~~~~~ In the :class:`.AbsoluteBindingProtocol` the coulombic interactions of the molecule are fully turned off (annihilated). The Lennard-Jones interactions are instead decoupled, meaning the intermolecular interactions are turned off, keeping the intramolecular Lennard-Jones interactions. The lambda schedule ~~~~~~~~~~~~~~~~~~~ Molecular interactions are turned off during an alchemical path using a discrete set of lambda windows. For the transformation in the binding site, the following steps are carried out, starting with the ligand fully interacting in the binding site. 1. Restrain the ligand using orientational restraints. 2. Turn off the electrostatic interactions of the ligand. 3. Decouple Lennard-Jones interactions of the ligand. 4. Release the restraints of the now dummy ligand analytically. The lambda schedule in the solvent phase is similar to the one in the complex, except that no restraints are applied. A soft-core potential is applied to the Lennard-Jones potential to avoid instablilites in intermediate lambda windows. The soft-core potential function from Beutler et al. [3]_ is used by default. The lambda schedule is defined in the ``lambda_settings`` objects ``lambda_elec``, ``lambda_vdw``, and ``lambda_restraints``. Simulation overview ~~~~~~~~~~~~~~~~~~~ The :class:`.ProtocolDAG` of the :class:`.AbsoluteBindingProtocol` contains :class:`.ProtocolUnit`\ s from both the complex and solvent transformations. This means that both legs of the thermodynamic cycle are constructed and run concurrently in the same :class:`.ProtocolDAG`. This is different from the :class:`.RelativeHybridTopologyProtocol` where the :class:`.ProtocolDAG` only runs a single leg of a thermodynamic cycle. If multiple ``protocol_repeats`` are run (default: ``protocol_repeats=3``), the :class:`.ProtocolDAG` contains multiple :class:`.ProtocolUnit`\ s of both complex and solvent transformations. Simulation steps """""""""""""""" Each :class:`.ProtocolUnit` (whether complex or solvent) carries out the following steps: 1. Parameterize the system using `OpenMMForceFields `_ and `Open Force Field `_. 2. Equilibrate the fully interacting system using a short MD simulation using the same approach as the :class:`.PlainMDProtocol` (including rounds of NVT and NPT equilibration). 3. Create an alchemical system. 4. Add orientational restraints to the complex system. 5. Minimize the alchemical system. 6. Equilibrate and production simulate the alchemical system using the chosen multistate sampling method (under NPT conditions). 7. Analyze results for the transformation. .. note:: Three different types of multistate sampling (i.e. replica swapping between lambda states) methods can be chosen; HREX, SAMS, and independent (no lambda swaps attempted). By default the HREX approach is selected, this can be altered using ``solvent_simulation_settings.sampler_method`` or ``complex_simulation_settings.sampler_method`` (default: ``repex``). Simulation details """""""""""""""""" Here are some details of how the simulation is carried out which are not detailed in the :class:`.AbsoluteBindingSettings`: * The protocol applies a `LangevinMiddleIntegrator `_ which uses Langevin dynamics, with the LFMiddle discretization [4]_. * A MonteCarloBarostat is used in the NPT ensemble to maintain constant pressure. Getting the free energy estimate ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ The free energy differences are obtained from simulation data using the `MBAR estimator `_ (multistate Bennett acceptance ratio estimator) as implemented in the `PyMBAR package `_. Both the MBAR estimates of the two legs of the thermodynamic cycle, and the overall absolute binding free energy (of the entire cycle) are obtained, which is different compared to the results in the :class:`.RelativeHybridTopologyProtocol` where results from two legs of the thermodynamic cycle are obtained separately. In addition to the estimates of the free energy changes and their uncertainty, the protocol also returns some metrics to help assess convergence of the results, these are detailed in the :ref:`multistate analysis section `. See Also -------- **Setting up AFE calculations** * :ref:`Defining the Protocol ` **Tutorials** * :any:`Absolute Binding Free Energies tutorial <../../tutorials/abfe_tutorial>` **Cookbooks** :ref:`Cookbooks ` **API Documentation** * :ref:`OpenMM Absolute Binding Free Energy ` * :ref:`OpenMM Protocol Settings ` References ---------- * `pymbar `_ * `yank `_ * `OpenMMTools `_ * `OpenMM `_ .. [1] Broadening the Scope of Binding Free Energy Calculations Using a Separated Topologies Approach, H. Baumann, E. Dybeck, C. McClendon, F. Pickard IV, V. Gapsys, L. Pérez-Benito, D. Hahn, G. Tresadern, A. Mathiowetz, D. Mobley, J. Chem. Theory Comput., 2023, 19, 15, 5058–5076 .. [2] Evaluating the use of absolute binding free energy in the fragment optimisation process, I. Alibay, A. Magarkar, D. Seeliger, P. Biggin, Commun Chem 5, 105 (2022) .. [3] Avoiding singularities and numerical instabilities in free energy calculations based on molecular simulations, T.C. Beutler, A.E. Mark, R.C. van Schaik, P.R. Greber, and W.F. van Gunsteren, Chem. Phys. Lett., 222 529–539 (1994) .. [4] Unified Efficient Thermostat Scheme for the Canonical Ensemble with Holonomic or Isokinetic Constraints via Molecular Dynamics, Zhijun Zhang, Xinzijian Liu, Kangyu Yan, Mark E. Tuckerman, and Jian Liu, J. Phys. Chem. A 2019, 123, 28, 6056-6079 ================================================ FILE: docs/guide/protocols/absolutesolvation.rst ================================================ Absolute Solvation Protocol =========================== Overview -------- The :class:`AbsoluteSolvationProtocol <.AbsoluteSolvationProtocol>` calculates the free energy change associate with transferring a molecule from vacuum into a solvent. .. note:: Currently, water is the only supported solvent, however, more solvents might be possible in the future. The absolute solvation free energy is calculated through a thermodynamic cycle. In this cycle, the interactions of the molecule are decoupled, meaning turned off, using a partial annihilation scheme (see below) both in the solvent and in the vacuum phases. The absolute solvation free energy is then obtained via summation of free energy differences along the thermodynamic cycle. .. figure:: img/ahfe_thermocycle.png :scale: 80% Thermodynamic cycle for the absolute solvation free energy protocol. Scientific Details ------------------ Partial annihilation scheme ~~~~~~~~~~~~~~~~~~~~~~~~~~~ In the :class:`.AbsoluteSolvationProtocol` the coulombic interactions of the molecule are fully turned off (annihilated). The Lennard-Jones interactions are instead decoupled, meaning the intermolecular interactions turned off, keeping the intramolecular Lennard-Jones interactions. The lambda schedule ~~~~~~~~~~~~~~~~~~~ Molecular interactions are turned off during an alchemical path using a discrete set of lambda windows. The electrostatic interactions are turned off first, followed by the decoupling of the Lennard-Jones interactions. A soft-core potential is applied to the Lennard-Jones potential to avoid instablilites in intermediate lambda windows. Both the soft-core potential functions from Beutler et al. [1]_ and from Gapsys et al. [2]_ are available and can be specified in the ``alchemical_settings.softcore_LJ`` settings (default: ``gapsys``). The lambda schedule is defined in the ``lambda_settings`` objects ``lambda_elec`` and ``lambda_vdw``. Note that the ``lambda_restraints`` setting is ignored for the :class:`.AbsoluteSolvationProtocol`. Simulation overview ~~~~~~~~~~~~~~~~~~~ The :class:`.ProtocolDAG` of the :class:`.AbsoluteSolvationProtocol` contains :class:`.ProtocolUnit`\ s from both the vacuum and solvent transformations. This means that both legs of the thermodynamic cycle are constructed and run concurrently in the same :class:`.ProtocolDAG`. This is different from the :class:`.RelativeHybridTopologyProtocol` where the :class:`.ProtocolDAG` only runs a single leg of a thermodynamic cycle. If multiple ``protocol_repeats`` are run (default: ``protocol_repeats=3``), the :class:`.ProtocolDAG` contains multiple :class:`.ProtocolUnit`\ s of both vacuum and solvent transformations. Simulation steps """""""""""""""" Each :class:`.ProtocolUnit` (whether vacuum or solvent) carries out the following steps: 1. Parameterize the system using `OpenMMForceFields `_ and `Open Force Field `_. 2. Equilibrate the fully interacting system using a short MD simulation using the same approach as the :class:`.PlainMDProtocol` (in the solvent leg this will include rounds of NVT and NPT equilibration). 3. Create an alchemical system. 4. Minimize the alchemical system. 5. Equilibrate and production simulate the alchemical system using the chosen multistate sampling method (under NPT conditions if solvent is present). 6. Analyze results for the transformation. Note: three different types of multistate sampling (i.e. replica swapping between lambda states) methods can be chosen; HREX, SAMS, and independent (no lambda swaps attempted). By default the HREX approach is selected, this can be altered using ``solvent_simulation_settings.sampler_method`` or ``vacuum_simulation_settings.sampler_method`` (default: ``repex``). Simulation details """""""""""""""""" Here are some details of how the simulation is carried out which are not detailed in the :class:`.AbsoluteSolvationSettings`: * The protocol applies a `LangevinMiddleIntegrator `_ which uses Langevin dynamics, with the LFMiddle discretization [3]_. * A MonteCarloBarostat is used in the NPT ensemble to maintain constant pressure. Getting the free energy estimate ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ The free energy differences are obtained from simulation data using the `MBAR estimator `_ (multistate Bennett acceptance ratio estimator) as implemented in the `PyMBAR package `_. Both the MBAR estimates of the two legs of the thermodynamic cycle, and the overall absolute solvation free energy (of the entire cycle) are obtained, which is different compared to the results in the :class:`.RelativeHybridTopologyProtocol` where results from two legs of the thermodynamic cycle are obtained separately. In addition to the estimates of the free energy changes and their uncertainty, the protocol also returns some metrics to help assess convergence of the results, these are detailed in the :ref:`multistate analysis section `. .. todo: issue 792 change this reference to point to the new results section See Also -------- **Setting up AFE calculations** * :ref:`Defining the Protocol ` .. To be added: Setting up AHFE calculations **Tutorials** * :any:`Absolute Hydration Free Energies tutorial <../../tutorials/ahfe_tutorial>` **Cookbooks** :ref:`Cookbooks ` **API Documentation** * :ref:`OpenMM Absolute Solvation Free Energy ` * :ref:`OpenMM Protocol Settings ` References ---------- * `pymbar `_ * `yank `_ * `OpenMMTools `_ * `OpenMM `_ .. [1] Avoiding singularities and numerical instabilities in free energy calculations based on molecular simulations, T.C. Beutler, A.E. Mark, R.C. van Schaik, P.R. Greber, and W.F. van Gunsteren, Chem. Phys. Lett., 222 529–539 (1994) .. [2] New Soft-Core Potential Function for Molecular Dynamics Based Alchemical Free Energy Calculations, V. Gapsys, D. Seeliger, and B.L. de Groot, J. Chem. Theor. Comput., 8 2373-2382 (2012) .. [3] Unified Efficient Thermostat Scheme for the Canonical Ensemble with Holonomic or Isokinetic Constraints via Molecular Dynamics, Zhijun Zhang, Xinzijian Liu, Kangyu Yan, Mark E. Tuckerman, and Jian Liu, J. Phys. Chem. A 2019, 123, 28, 6056-6079 ================================================ FILE: docs/guide/protocols/index.rst ================================================ .. _userguide_protocols: Details of Specific Protocols ============================= Details on the theory and behaviour of different Protocols are listed here. .. toctree:: relativehybridtopology absolutebinding absolutesolvation septop plainmd ================================================ FILE: docs/guide/protocols/plainmd.rst ================================================ Plain MD Protocol ================= Overview -------- The :class:`.PlainMDProtocol` enables the user to run a Molecular Dynamics (MD) simulation of a :class:`.ChemicalSystem`, which can contain e.g. a solvated protein-ligand complex, a molecule and water, or a molecule in vacuum. .. todo: Later add ref to ChemicalSystem section Scientific Details ------------------ The :class:`.PlainMDProtocol` runs MD simulations of a system either in solvent or vacuum, depending on the input provided by the user in the :class:`.ChemicalSystem`. The protocol applies a `LangevinMiddleIntegrator `_ which uses Langevin dynamics, with the LFMiddle discretization [1]_. Simulation Steps and Outputs ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ If there is a ``SolventComponent`` in the :class:`.ChemicalSystem`, the each :class:`.ProtocolUnit` carries out the following steps: .. list-table:: :widths: 50 50 :header-rows: 1 * - Step - Outputs (with default names) * - 1. Parameterize the system using `OpenMMForceFields `_ and `Open Force Field `_ - Forcefield cache (``db.json``) * - 2. OpenMM object creation - Structure of the full system (``system.pdb``) * - 3. Minimize the system - Minimized Structure (``minimized.pdb``) * - 4. Equilibrate in the canonical (NVT) ensemble - NVT equilibrated structure (``equil_nvt.pdb``) * - 5. Equilibrate the system under isobaric-isothermal (NPT) conditions - NPT equilibrated structure (``equil_npt.pdb``) * - 6. Production simulate the system under isobaric-isothermal (NPT) conditions - Simulation trajectory (``simulation.xtc``), Checkpoint file (``checkpoint.chk``), Log output (``simulation.log``) A MonteCarloBarostat is used in the NPT ensemble to maintain constant pressure. Relevant settings under solvent conditions include the solvation settings that control the ``solvent_model`` and ``solvent_padding``. If the :class:`.ChemicalSystem` does not contain a ``SolventComponent``, the protocol runs an MD simulation in vacuum. After a minimization, the protocol performs an equilibration, followed by a production run with no periodic boundary conditions and infinite cutoffs. Settings that control the barostat or the solvation are ignored for vacuum MD simulations. Performance consideration for gas phase MD simulations ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ For gas phase MD simulations, we suggest setting ``OPENMM_CPU_THREADS=1`` to obtain good performance. See Also -------- **Tutorials** * :any:`MD tutorial <../../tutorials/md_tutorial>` **API Documentation** * :ref:`OpenMM plain MD protocol ` * :ref:`OpenMM Protocol Settings ` References ---------- * `OpenMMTools `_ * `OpenMM `_ .. [1] Unified Efficient Thermostat Scheme for the Canonical Ensemble with Holonomic or Isokinetic Constraints via Molecular Dynamics, Zhijun Zhang, Xinzijian Liu, Kangyu Yan, Mark E. Tuckerman, and Jian Liu, J. Phys. Chem. A 2019, 123, 28, 6056-6079 ================================================ FILE: docs/guide/protocols/relativehybridtopology.rst ================================================ .. _userguide_relative_hybrid_topology_protocol: Relative Hybrid Topology Protocol ================================= Overview -------- The relative free energy calculation approach calculates the difference in free energy between two similar ligands. Depending on the :class:`.ChemicalSystem` provided, the protocol either calculates the relative binding free energy (RBFE), or the relative hydration free energy (RHFE). Further information on constructing chemical systems to define thermodynamic cycles, see :ref:`userguide_chemicalsystems_and_components` In a thermodynamic cycle, one ligand is converted into the other ligand by alchemically transforming the atoms that vary between the two ligands. The transformation is carried out in both environments, meaning both in the solvent (ΔG\ :sub:`solv`\) and in the binding site (ΔG\ :sub:`site`\) for RBFE calculations and in the solvent (ΔG\ :sub:`solv`\) and vacuum (ΔG\ :sub:`vacuum`\) for RHFE calculations. .. _label: Thermodynamic cycle for the relative binding free energy protocol .. figure:: img/rbfe_thermocycle.png :scale: 50% Thermodynamic cycle for the relative binding free energy protocol. Scientific Details ------------------ This :class:`.RelativeHybridTopologyProtocol` is based off the `Perses implementation `_. The Hybrid Topology approach ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ The :class:`.RelativeHybridTopologyProtocol` uses a hybrid topology approach to represent the two ligands, meaning that a single set of coordinates is used to represent the common core of the two ligands while the atoms that differ between the two ligands are represented separately. An atom map defines which atoms belong to the core (mapped atoms) and which atoms are unique and represented separately (see :ref:`Creating atom mappings `). During the alchemical transformation, mapped atoms are interpolated from their type in the ligand at state A to the type in the other ligand at state B, while unique atoms atoms (commonly known as dummy atoms) are switched, inserted or uncoupled, depending on which ligand they belong to. By default all nonbonded interactions between the dummy region and the core region are removed to avoid coupling their motion. .. note:: In this hybrid topology approach, all bonded interactions between the dummy region and the core region are kept. As pointed out by Fleck et al. [1]_, this can lead to systematic errors if the contribution of the dummy group does not cancel out in the thermodynamic cycle (no separability of the partition function). We are currently working on fixing this issue. The lambda schedule ~~~~~~~~~~~~~~~~~~~ The protocol interpolates molecular interactions between the initial and final state of the perturbation using a discrete set of lambda windows. A function describes how the different lambda components (bonded and nonbonded terms) are interpolated. Only parameters that differ between state A (``lambda=0``) and state B (``lambda=1``) are interpolated. In the default lambda function in the :class:`.RelativeHybridTopologyProtocol`, first the electrostatic interactions of state A are turned off while simultaneously turning on the steric interactions of state B. Then, the steric interactions of state A are turned off while simultaneously turning on the electrostatic interactions of state B. Bonded interactions are interpolated linearly between ``lambda=0`` and ``lambda=1``. The ``lambda_settings`` ``lambda_functions`` and ``lambda_windows`` define the alchemical pathway. A soft-core potential is applied to the Lennard-Jones potential to avoid instablilites in intermediate lambda windows. Both the soft-core potential functions from Beutler et al. [2]_ and from Gapsys et al. [3]_ are available and can be specified in the ``alchemical_settings.softcore_LJ`` settings (default: ``gapsys``). Simulation overview ~~~~~~~~~~~~~~~~~~~ The :class:`.ProtocolDAG` of the :class:`.RelativeHybridTopologyProtocol` contains the :class:`.ProtocolUnit`\ s from one leg of the thermodynamic cycle. This means that each :class:`.ProtocolDAG` only runs a single leg of a thermodynamic cycle and therefore two Protocol instances need to be run to get the overall relative free energy difference, ΔΔG. If multiple ``protocol_repeats`` are run (default: ``protocol_repeats=3``), the :class:`.ProtocolDAG` contains multiple :class:`.ProtocolUnit`\ s of both vacuum and solvent transformations. Simulation Steps """""""""""""""" Each :class:`.ProtocolUnit` carries out the following steps: 1. Parameterize the system using `OpenMMForceFields `_ and `Open Force Field `_. 2. Create an alchemical system (hybrid topology). 3. Minimize the alchemical system. 4. Equilibrate and production simulate the alchemical system using the chosen multistate sampling method (under NPT conditions if solvent is present). .. note:: **Equilibration method:** The current implementation uses a simple equilibration protocol **without any positional restraints** or **temperature annealing**. The system is equilibrated directly under the target thermodynamic conditions, therefore the input structures should be stable under these conditions. 5. Analyze results for the transformation (for a single leg in the thermodynamic cycle). Note: three different types of multistate sampling (i.e. replica swapping between lambda states) methods can be chosen; HREX, SAMS, and independent (no lambda swaps attempted). By default the HREX approach is selected, this can be altered using ``simulation_settings.sampler_method`` (default: ``repex``). Simulation details """""""""""""""""" Here are some details of how the simulation is carried out which are not detailed in the :class:`.RelativeHybridTopologySettings`: * The protocol applies a `LangevinMiddleIntegrator `_ which uses Langevin dynamics, with the LFMiddle discretization [4]_. * A MonteCarloBarostat is used in the NPT ensemble to maintain constant pressure. Getting the free energy estimate ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ The free energy differences are obtained from simulation data using the `MBAR estimator `_ (multistate Bennett acceptance ratio estimator) as implemented in the `PyMBAR package `_. In addition to the MBAR estimates of the two legs of the thermodynamic cycle and the overall relative binding free energy difference, the protocol also returns some metrics to help assess convergence of the results, these are detailed in the :ref:`multistate analysis section `. .. note:: The MBAR uncertainty of each individual transformation is estimated using bootstrapping for 1000 iterations, this leads to larger errors compared to the previous error estimate method. The only exception are the forward and reverse convergence plots which use the MBAR analytical error. .. todo: issue 792, consolidate this page into its own analysis page and link both RBFE and AFE pages to it .. _multistate_analysis: Analysis ~~~~~~~~ As standard, some analysis of the each simulation repeat is performed. This analysis is made available through either the dictionary of results in the execution output, or through some ready-made plots for quick inspection. This analysis can be categorised as relating to the energetics of the different lambda states that were sampled, or to the analysis of the change in structural conformation over time in each state. Energetic and replica exchange analysis """"""""""""""""""""""""""""""""""""""" These analyses consider the swapping and energetic overlap between the different simulated states to help assess the convergence and correctness of the estimate of free energy difference produced. .. list-table:: Energetic Analysis examples :widths: 75 25 :header-rows: 1 * - Description - Example * - **MBAR overlap matrix.** This plot is used to assess if the different lambda states simulated overlapped energetically. Each matrix element represents the probability of a sample from a given row state being observable in a given column state. Since the accuracy of the MBAR estimator depends on sufficient overlap between lambda states, this is a very important metric. This plot should show that the diagonal of the matrix has some "width" so that the two end states are connected, with elements adjacent to the diagonal being at least 0.03 [5]_. - .. image:: img/mbar_overlap_matrix.png * - **Replica exchange probability matrix** (for replica exchange sampler simulations only). Similar to the MBAR overlap matrix, this shows the probability of a given lambda state being exchanged with another. Again, the diagonal of this matrix should be at least tridiagonal wide for the two end states to be connected. - .. image:: img/replica_exchange_matrix.png * - **Forward and reverse convergence of free energy estimates.** Using increasingly larger portions of the total data, this analysis calculates the free energy difference, both in forward and backward directions. In this analysis, forward and backward estimates that agree within error using only a fraction of the total data suggest convergence [5]_. Note: the error bars reported in this plot are MBAR analytical errors instead of bootstrap errors. - .. image:: img/forward_reverse_convergence.png * - **Timeseries of replica states.** This plot shows the time evolution of the different system configurations as they are exchanged between different lambda states. This plot should show that the states are freely mixing and that there are no cliques forming. - .. image:: img/replica_state_timeseries.png Structural analysis """"""""""""""""""" If a protein was present, these analyses first center and align the system so that the protein is considered the frame of reference. Further analysis can be performed by inspecting the ``simulation.nc`` and ``hybrid_system.pdb`` files, which contain a multistate trajectory and topology for the hybrid system respectively. These files can be loaded into an MDAnalysis Universe object using the `openfe_analysis`_ package. .. list-table:: Structural Analysis examples :widths: 75 25 :header-rows: 1 * - Description - Example * - **Ligand RMSD.** This produces a plot called ``ligand_RMSD.png`` and a results entry ``ligand_RMSD`` which gives the RMSD of the ligand molecule over time relative to the first frame of the production phase, for each simulated state. Large RMSD values, e.g. greater than 5 angstrom (system dependent), would indicate an unstable ligand binding mode. - .. image:: img/ligand_RMSD.png * - **Ligand COM drift.** For simulations with a protein present, this metric gives the total distance of the ligand COM from its initial starting (docked) position. If this metric increases over the course of the simulation (beyond 5 angstrom) it indicates that the ligand drifted from the binding pocket, and the simulation is unreliable. This produces a plot called ``ligand_COM_drift.png`` and a results entry ``ligand_COM_drift``. - .. image:: img/ligand_COM_drift.png * - **Protein 2D RMSD.** For simulations with a protein present, this metric gives, for each lambda state, the RMSD of the protein structure over time, using each frame analysed as a reference frame, to produce a 2 dimensional heatmap. This plot should show no significant spikes in RMSD (which will appear as brightly coloured areas). - .. image:: img/protein_2D_RMSD.png See Also -------- **Setting up RFE calculations** * :ref:`Setting up alchemical networks ` **Tutorials** * :any:`Relative Free Energies with the OpenFE CLI ` * :any:`Relative Free Energies with the OpenFE Python API ` **Cookbooks** :ref:`Cookbooks ` **API Documentation** * :ref:`OpenMM Relative Hybrid Topology Protocol ` * :ref:`OpenMM Protocol Settings ` References ---------- * `pymbar `_ * `perses `_ * `OpenMMTools `_ * `OpenMM `_ .. [1] Dummy Atoms in Alchemical Free Energy Calculations, Markus Fleck, Marcus Wieder, and Stefan Boresch, J. Chem. Theory Comput.2021, 17, 4403−4419 .. [2] Avoiding singularities and numerical instabilities in free energy calculations based on molecular simulations, T.C. Beutler, A.E. Mark, R.C. van Schaik, P.R. Greber, and W.F. van Gunsteren, Chem. Phys. Lett., 222 529–539 (1994) .. [3] New Soft-Core Potential Function for Molecular Dynamics Based Alchemical Free Energy Calculations, V. Gapsys, D. Seeliger, and B.L. de Groot, J. Chem. Theor. Comput., 8 2373-2382 (2012) .. [4] Unified Efficient Thermostat Scheme for the Canonical Ensemble with Holonomic or Isokinetic Constraints via Molecular Dynamics, Zhijun Zhang, Xinzijian Liu, Kangyu Yan, Mark E. Tuckerman, and Jian Liu, J. Phys. Chem. A 2019, 123, 28, 6056-6079 .. [5] Guidelines for the analysis of free energy calculations, Pavel V. Klimovich, Michael R. Shirts, and David L. Mobley, J Comput Aided Mol Des. 2015 May; 29(5):397-411. doi: 10.1007/s10822-015-9840-9 .. _openfe_analysis: https://github.com/OpenFreeEnergy/openfe_analysis ================================================ FILE: docs/guide/protocols/septop.rst ================================================ .. _userguide_septop_protocol: Separated Topologies Protocol ============================= Overview -------- The :class:`SepTopProtocol <.SepTopProtocol>` [1]_, [2]_ calculates the difference in binding free energy between two ligands. This protocol essentially performs two absolute binding free energy calculations simultaneously in opposite directions, by (alchemically) inserting one ligand into the binding site, while removing the other ligand at the same time. In contrast to the :ref:`RelativeHybridTopologyProtocol `, the two ligand topologies are completely separate (meaning there is no common core), making atom mapping unnecessary and allowing transformations between chemically diverse ligands. The relative binding free energy is calculated through a thermodynamic cycle by transforming one ligand into the other ligand both in the solvent and in the binding site. Restraints are required to keep the weakly coupled and fully decoupled ligand in the binding site region and thereby reduce the phase space that needs to be sampled. In the :class:`SepTopProtocol <.SepTopProtocol>` we apply orientational, or Boresch-style, restraints, as described below. In this cycle, the interactions of one molecule are turned off while simultaneously turning on interactions of the other molecule both in the solvent and complex phases. The relative binding free energy is then obtained via summation of free energy differences along the thermodynamic cycle. .. figure:: img/septop_cycle.png :scale: 50% Thermodynamic cycle for the SepTop free energy protocol. Scientific Details ------------------ Orientational restraints ~~~~~~~~~~~~~~~~~~~~~~~~ Orientational, or Boresch-style, restraints are automatically (unless manually specified) applied between three protein and three ligand atoms using one bond, two angle, and three dihedral restraints. Reference atoms are picked based on different criteria, such as the root mean squared fluctuation of the atoms in a short MD simulation, the secondary structure of the protein, and the distance between atoms, based on heuristics from Baumann et al. [2]_ and Alibay et al. [3]_. Two strategies for selecting protein atoms are available, either picking atoms that are bonded to each other or that can span multiple residues. This can be specified using the ``restraint_settings.anchor_finding_strategy`` settings. Partial annihilation scheme ~~~~~~~~~~~~~~~~~~~~~~~~~~~ In the :class:`SepTopProtocol <.SepTopProtocol>` the coulombic interactions of the molecules are fully turned off (annihilated) in the respective non-interacting end states. The Lennard-Jones interactions are instead decoupled, meaning the intermolecular interactions are turned off, keeping the intramolecular Lennard-Jones interactions. The lambda schedule ~~~~~~~~~~~~~~~~~~~ Molecular interactions are modified along an alchemical path using a discrete set of lambda windows. For the transformation of ligand A to ligand B in the binding site, the following steps are carried out, starting with ligand A being fully interacting in the binding site while ligand B is decoupled. 1. Restrain the non-interacting dummy ligand B in the binding site. The contribution of the restraints is calculated analytically. 2. Turn on the van der Waals (vdW) interactions of ligand B while also turning on orientational restraints on ligand A. 3. Turn on the electrostatic interactions of ligand B while at the same time turning off the electrostatics of ligand A. 4. Turn off vdW interactions of ligand A while simultaneously releasing restraints on ligand B. 5. Release the restraints of the now dummy ligand A analytically. The lambda schedule in the solvent phase is similar to the one in the complex, except that a single harmonic distance restraint is applied between the respective central atom in the two ligands to keep the ligands apart while doing the alchemical transformation. A soft-core potential from Beutler et al. [4]_ is applied to the Lennard-Jones potential to avoid instablilites in intermediate lambda windows. The lambda schedule is defined in the ``lambda_settings`` objects ``lambda_elec_A``, ``lambda_elec_B``, ``lambda_vdw_A``, ``lambda_vdw_B``, ``lambda_restraints_A``, and ``lambda_restraints_B``. Simulation overview ~~~~~~~~~~~~~~~~~~~ The :class:`.ProtocolDAG` of the :class:`SepTopProtocol <.SepTopProtocol>` contains :class:`.ProtocolUnit`\ s from both the complex and solvent transformations. This means that both legs of the thermodynamic cycle are constructed and run sequentially in the same :class:`.ProtocolDAG`. This is different from the :class:`.RelativeHybridTopologyProtocol` where the :class:`.ProtocolDAG` only runs a single leg of a thermodynamic cycle. If multiple ``protocol_repeats`` are run (default: ``protocol_repeats=3``), the :class:`.ProtocolDAG` contains multiple :class:`.ProtocolUnit`\ s of both complex and solvent transformations. In that case, every :class:`.ProtocolUnit` would be run N times, where N is the number of ``protocol_repeats``. This means that also the selection of the atoms for restraints would be performed multiple times. Simulation steps """""""""""""""" Each :class:`.ProtocolUnit` (whether complex or solvent) carries out the following steps: 1. Parameterize the system using `OpenMMForceFields `_ and `Open Force Field `_. 2. Equilibrate the fully interacting system using a short MD simulation using the same approach as the :class:`.PlainMDProtocol` (in the solvent leg this will include rounds of NVT and NPT equilibration). 3. Add restraints to the system: Orientational restraints in the complex, a single harmonic distance restraint in the solvent leg. 4. Create an alchemical system. 5. Minimize the alchemical system. 6. Equilibrate and production simulate the alchemical system using the chosen multistate sampling method (under NPT conditions). 7. Analyze results for the transformation. .. note:: Three different types of multistate sampling (i.e. replica swapping between lambda states) methods can be chosen; HREX, SAMS, and independent (no lambda swaps attempted). By default the HREX approach is selected, this can be altered using ``solvent_simulation_settings.sampler_method`` or ``complex_simulation_settings.sampler_method`` (default: ``repex``). Simulation details """""""""""""""""" Here are some details of how the simulation is carried out which are not detailed in the :class:`SepTopProtocol <.SepTopProtocol>`: * The protocol applies a `LangevinMiddleIntegrator `_ which uses Langevin dynamics, with the LFMiddle discretization [5]_. * A `Monte Carlo barostat `_ is used in the NPT ensemble to maintain constant pressure. Getting the free energy estimate ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ The free energy differences are obtained from simulation data using the `MBAR estimator `_ (multistate Bennett acceptance ratio estimator) as implemented in the `PyMBAR package `_. Both the MBAR estimates of the two legs of the thermodynamic cycle, and the overall relative binding free energy (of the entire cycle) are obtained, which is different compared to the results in the :class:`.RelativeHybridTopologyProtocol` where results from two legs of the thermodynamic cycle are obtained separately. In addition to the estimates of the free energy changes and their uncertainty, the protocol also returns some metrics to help assess convergence of the results, these are detailed in the :ref:`multistate analysis section `. See Also -------- **Tutorials** * :any:`Separated Topologies Free Energies tutorial <../../tutorials/septop_tutorial>` **Cookbooks** :ref:`Cookbooks ` **API Documentation** * :ref:`OpenMM Protocol Settings ` References ---------- * `pymbar `_ * `yank `_ * `OpenMMTools `_ * `OpenMM `_ .. [1] Separated topologies--a method for relative binding free energy calculations using orientational restraints, G. Rocklin, D. Mobley, K. Dill; Chem Phys, 2013; 138(8):085104. doi: 10.1063/1.4792251. .. [2] Broadening the Scope of Binding Free Energy Calculations Using a Separated Topologies Approach, H. Baumann, E. Dybeck, C. McClendon, F. Pickard IV, V. Gapsys, L. Pérez-Benito, D. Hahn, G. Tresadern, A. Mathiowetz, D. Mobley, J. Chem. Theory Comput., 2023, 19, 15, 5058–5076 .. [3] Evaluating the use of absolute binding free energy in the fragment optimisation process, I. Alibay, A. Magarkar, D. Seeliger, P. Biggin, Commun Chem 5, 105 (2022) .. [4] Avoiding singularities and numerical instabilities in free energy calculations based on molecular simulations, T.C. Beutler, A.E. Mark, R.C. van Schaik, P.R. Greber, and W.F. van Gunsteren, Chem. Phys. Lett., 222 529–539 (1994) .. [5] Unified Efficient Thermostat Scheme for the Canonical Ensemble with Holonomic or Isokinetic Constraints via Molecular Dynamics, Zhijun Zhang, Xinzijian Liu, Kangyu Yan, Mark E. Tuckerman, and Jian Liu, J. Phys. Chem. A 2019, 123, 28, 6056-6079 ================================================ FILE: docs/guide/results/index.rst ================================================ .. _userguide_results: Results Gathering ================= With simulations completed, the results of individual simulations can be inspected, and entire networks of results analysed. .. toctree:: working_with_results working_with_networks ================================================ FILE: docs/guide/results/working_with_networks.rst ================================================ .. _userguide_result_networks: Working with networks of results ================================ After running a **network** of free energy calculations, we often want to analyse the corresponding network of results. .. _userguide_MLE: Converting relative results to absolute estimates ------------------------------------------------- When a network of relative free energies has been calculated, a commonly performed task is to transform these pairwise estimations of **relative** free energy differences (:math:`\Delta \Delta G`) into **absolute** free energy differences (:math:`\Delta G`). This is done using a maximum likelihood estimator (MLE) [1]_, as implemented in the `cinnabar`_ package. This approach uses the matrix of relative pairwise measurements and their uncertainties, to estimate the overall ranking of ligands. To use this approach the network of pairwise measurements needs to be fully connected, i.e. there should be a way to trace a path along pairwise measurements between any two nodes (ligands) on the network. .. note:: The results of a MLE estimation will have a **mean** of 0.0, meaning that there will be some estimates with positive values and some estimates with negative values. These predictions (:math:`\Delta G_{pred}`) can be shifted to match the magnitude of the experimental data, to satisfy the below equation where the sum is performed over N molecules that have experimental data (:math:`\Delta G_{exp}`) [2]_. .. math:: \sum_i^N \Delta G^i_{exp} = \sum_i^N \Delta G^i_{pred} Gathering using the command line -------------------------------- After running calculations using the :ref:`quickrun command `, the :ref:`openfe gather ` command offers a way to collate information across many different individual simulations and prepare a table of results. The tool offers a summary of the relative binding affinities (``--report ddg``), or their :ref:`corresponding MLE values ` (``--report dg``). Using cinnabar directly ----------------------- The `cinnabar`_ package can be used from within Python to manipulate networks of free energy estimates. A tutorial on using this is provided here :ref:`here ` See also -------- For handling the results of a single calculation, please consult :ref:`userguide_individual_results` .. [1] Optimal Measurement Network of Pairwise Differences, Huafeng Xu, J. Chem. Inf. Model. 2019, 59, 11, 4720-4728 .. [2] Accurate and Reliable Prediction of Relative Ligand Binding Potency in Prospective Drug Discovery by Way of a Modern Free-Energy Calculation Protocol and Force Field Lingle Wang, Yujie Wu, Yuqing Deng, Byungchan Kim, Levi Pierce, Goran Krilov, Dmitry Lupyan, Shaughnessy Robinson, Markus K. Dahlgren, Jeremy Greenwood, Donna L. Romero, Craig Masse, Jennifer L. Knight, Thomas Steinbrecher, Thijs Beuming, Wolfgang Damm, Ed Harder, Woody Sherman, Mark Brewer, Ron Wester, Mark Murcko, Leah Frye, Ramy Farid, Teng Lin, David L. Mobley, William L. Jorgensen, Bruce J. Berne, Richard A. Friesner, and Robert Abel Journal of the American Chemical Society 2015 137 (7), 2695-2703 DOI: 10.1021/ja512751q .. _cinnabar: https://github.com/OpenFreeEnergy/cinnabar ================================================ FILE: docs/guide/results/working_with_results.rst ================================================ .. _userguide_individual_results: Working with individual results =============================== With :ref:`execution of your calculations ` completed, we can now start looking at what has been produced. The majority of Protocols will produce estimates of free energy differences between two or more ``ChemicalSystem`` \s (the current exception being the :class:`.PlainMDProtocol` which just simulates the dynamics of a single system). Beyond this, the exact data produced by a given Protocol can vary significantly, for example the :class:`.RelativeHybridTopologyProtocol` protocol will produce graphs to assess the quality of the simulation, alongside trajectory data files. By comparison, the :class:`.PlainMDProtocol` will only produce the latter. For exact details on what is produced consult the :ref:`pages for each Protocol`. .. todo crossref to HREX and MD Protocol docs from issue 743 How you can inspect these results depends on whether you have executed your simulations from the command line or a Python script. From command line execution --------------------------- If you had executed your calculation using the :ref:`quickrun ` command, then a ``.json`` results log file as well as a directory of files will have been produced. This directory will have various plots and results of analysis, the exact details of which are described in the :ref:`pages for each Protocol`. Most importantly, the ``.json`` results file has ``estimate`` and ``uncertainty`` keys, which serve the same purpose as the ``get_estimate()`` and ``get_uncertainty()`` methods described below. The full ``json`` results file can be reloaded into a Python session as:: >>> import gufe >>> import json >>> >>> with open('././Transformation-97d7223f918bbdb0570edc2a49bbc43e_results.json', 'r') as f: ... results = json.load(f, cls=gufe.tokenization.JSON_HANDLER.decoder) >>> results['estimate'] -19.889719513104342 >>> results['uncertainty'] 0.574685524681712 From Python execution --------------------- Executing a :class:`.ProtocolDAG` using :func:`openfe.execute_DAG` will produce a :class:`.ProtocolDAGResult`, representing a single iteration of estimating the free energy difference. One or more of these can be put into the ``.gather()`` method of the ``Protocol`` to form a :class:`.ProtocolResult`, this class takes care of the averaging and concatenation of different iterations of the estimation process. This ``ProtocolResult`` class has ``.get_estimate()`` and ``.get_uncertainty()`` methods which return the estimates of free energy difference along with its uncertainty. See Also -------- For how to deal with multiple results forming a network consult the :ref:`working with networks` page. ================================================ FILE: docs/guide/setup/alchemical_network_model.rst ================================================ .. _alchemical_network_model: Alchemical Networks: Planning a Simulation Campaign =================================================== The ultimate goal of the setup stage is to create an :class:`.AlchemicalNetwork`, which contains all the information needed for a campaign of simulations, including the ``openfe`` objects that define the chemical systems and alchemical transformations. .. TODO provide a written or image based comparison between alchemical and thermodynamic cycles Like any network, an :class:`.AlchemicalNetwork` can be described in terms of nodes and edges between nodes. The nodes are :class:`.ChemicalSystem`\s, which describe the specific molecules involved. The edges are :class:`.Transformation` objects, which carry all the information about how the simulation is to be performed. .. figure:: img/AlchemicalNetwork.png In practice, nodes must be associated with a transformation in order to be relevant in an alchemical network; that is, there are no disconnected nodes. This means that the alchemical network can be fully described by just the edges (which contain information on the nodes they connect). Note that this does not mean that the entire network must be fully connected -- just that there are no solitary nodes. Each :class:`.Transformation` represents everything that is needed to calculate the free energy differences between the two :class:`.ChemicalSystem`\ s that are the nodes for that edge. In addition to containing the information for each :class:`.ChemicalSystem`, the :class:`.Transformation` also contains a :class:`.Protocol` and, when relevant, atom mapping information for alchemical transformations. The latter is often done through a :class:`.LigandNetwork`. .. _alchemical_network_creation: 3 Ways to Create an Alchemical Network -------------------------------------- 1. Python API ^^^^^^^^^^^^^ You can manually create a :class:`.AlchemicalNetwork` by creating a list of :class:`.Transformation` objects. For examples using the Python API, see :ref:`cookbook on creating alchemical networks `. 2. Python ``NetworkPlanner`` Convenience Classes ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ OpenFE also provides the convenience classes :class:`.RBFEAlchemicalNetworkPlanner` and :class:`.RHFEAlchemicalNetworkPlanner`, which use the :class:`.RelativeHybridTopologyProtocol` for creating :class:`.AlchemicalNetwork`\s. For example usage of these convenience classes, see :ref:`Relative Alchemical Network Planners cookbook `. .. note:: The Network Planners are provided for user convenience. While they cover majority of use cases, they may not currently offer the complete range of options available through the Python API. 3. Command Line ``NetworkPlanner`` ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ The Alchemical Network Planners can also be called directly from the :ref:`command line interface `. For example, you can create a Relative Hydration Free Energy (RHFE) network using: .. code:: bash $ openfe plan-rhfe-network -M dir_with_sdfs/ or a Relative Binding Free Energy (RBFE) network using: .. code:: bash $ openfe plan-rbfe-network -p protein.pdb -M dir_with_sdfs/ For more CLI details, see :ref:`RBFE CLI tutorial ` and the :ref:`userguide_cli_interface`. See Also -------- * :ref:`Alchemical Network API reference ` * :ref:`Chemical Systems UserGuide entry ` ================================================ FILE: docs/guide/setup/chemical_systems_and_thermodynamic_cycles.rst ================================================ .. _userguide_chemicalsystems_and_components: Components, Chemical Systems and Thermodynamic Cycles ===================================================== This page describes the core building blocks used to define simulation states in openfe: :class:`.Component`\s, which describe what is physically present in a system; :class:`.ChemicalSystem`\s, which combine components into a complete end state; and thermodynamic cycles, which connect end states via alchemical transformations. .. _userguide_components: Components ---------- Components are the composable building blocks that define the chemical composition of a simulated system. Splitting a system into components serves three purposes: 1. Alchemical transformations can be easily understood by comparing the differences in components. 2. Components can be reused to compose different systems. 3. :class:`.Protocol`\s can apply component-specific behaviour, e.g. different force fields per component. Component types — overview ~~~~~~~~~~~~~~~~~~~~~~~~~~ .. list-table:: :header-rows: 1 :widths: 25 30 45 * - Component - Role - Key notes * - :class:`.ProteinComponent` - Biological assembly - Typically the contents of a PDB file. May include crystallographic waters and ions (defined as HETATM entries), and disulfide bonds (defined via CONECT records). * - :class:`.SmallMoleculeComponent` - Ligands and cofactors - Can optionally contain atomic partial charges. If present, those will be used in the simulation. * - :class:`.SolventComponent` - Abstract solvent definition - Defines solvent conditions and ion concentration. Does **not** include coordinates or box vectors. Solvent is added by the protocol at runtime. * - :class:`.SolvatedPDBComponent` - Explicitly solvated system - Includes atomic coordinates and box vectors. Solvent is already present, the protocol does not add any further solvation. * - :class:`.ProteinMembraneComponent` - Protein-membrane complex - Subclass of :class:`.SolvatedPDBComponent`. Includes protein, membrane, solvent, and box vectors. Replaces :class:`.ProteinComponent` in membrane systems. .. _userguide_solvation_models: Abstract vs explicit solvation ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ These two approaches are **mutually exclusive**: * **Abstract solvation** — use a :class:`.SolventComponent`. The protocol adds solvent during system preparation. * **Explicit solvation** — use a :class:`.SolvatedPDBComponent` or :class:`.ProteinMembraneComponent`. Solvent molecule coordinates (waters and ions) are explicitly defined in the inputs. Either define the solvent abstractly, or provide a fully solvated system — do not mix both for the same leg of a transformation. .. note:: Some protocols, such as :class:`.SepTopProtocol` and :class:`.AbsoluteBindingProtocol`, use a single :class:`.ChemicalSystem` to represent both the complex and solvent legs. In this case, a :class:`.ChemicalSystem` may contain both a :class:`.SolventComponent` and a :class:`.ProteinMembraneComponent`. However, these apply to *different* legs: the :class:`.SolventComponent` is used only for the solvent leg, and the :class:`.ProteinMembraneComponent` (which is already explicitly solvated) is used only for the complex leg. The mutual exclusivity rule still holds per leg. Box vectors for explicitly solvated systems ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ The components :class:`.SolvatedPDBComponent` and :class:`.ProteinMembraneComponent` require periodic box vectors. These can be provided in three ways: 1. **CRYST record in the PDB file** — OpenMM reads box vectors automatically. No additional arguments are needed:: membrane_protein = openfe.ProteinMembraneComponent.from_pdb_file('./protein_membrane.pdb') 2. **Manual specification** — box vectors can be provided explicitly as numpy arrays with OpenFF units in OpenMM format via the ``box_vectors`` argument:: import numpy as np import openff.units as offunit box_vectors = np.array([ [6.9587, 0.0, 0.0], [0.0, 5.9164, 0.0], [0.0, 0.0, 9.2692] ]) * offunit.nanometer membrane_protein = openfe.ProteinMembraneComponent.from_pdb_file( './protein_membrane.pdb', box_vectors=box_vectors ) 3. **Inference from atomic coordinates** — box vectors can be estimated from the atomic positions by passing ``infer_box_vectors=True``:: membrane_protein = openfe.ProteinMembraneComponent.from_pdb_file( './protein_membrane.pdb', infer_box_vectors=True ) .. warning:: Inferring box vectors from atomic positions can be inaccurate if the PDB originates from a previous simulation where atoms may be distributed across periodic images. .. _userguide_chemical_systems: ChemicalSystem -------------- A :class:`.ChemicalSystem` is composed of components that together describe a model of the system to be simulated. simulated system. It represents the **end state** of an alchemical transformation and is the primary input a :class:`.Protocol` consumes to define a simulation state. **What a ChemicalSystem defines** * Exact atomic information (including protonation state) of protein, ligands, cofactors, and any crystallographic waters. * Atomic positions of all explicitly defined components such as ligands or proteins. * The abstract or explicit definition of the solvent environment (SolventComponent). **What a ChemicalSystem does NOT define**, and are instead handled by the Protocol: Any simulation parameters including: * Forcefield applied to any component, including water model or virtual particles. * Thermodynamic conditions (e.g. temperature or pressure). * These are handled by the :class:`.Protocol`. .. _userguide_system_composition: System composition examples --------------------------- The components that make up each :class:`.ChemicalSystem` depend on the protocol and the nature of the system. The table below summarises the composition for each combination. .. note:: Protocol-specific behaviour: For :class:`.SepTopProtocol` and :class:`.AbsoluteBindingProtocol`, a single :class:`.ChemicalSystem` represents both legs of the thermodynamic cycle. The protocol determines internally what is the complex leg and what is the solvent leg. This differs from the :class:`.RelativeHybridTopologyProtocol`, where each leg (e.g. complex and solvent) is defined by separate :class:`.ChemicalSystem`\s. This behaviour is expected to change in future versions. .. list-table:: :header-rows: 1 :widths: 20 40 40 * - System - :ref:`RBFE ` (:class:`.RelativeHybridTopologyProtocol`) - :ref:`SepTop ` / :ref:`ABFE ` (:class:`.SepTopProtocol`, :class:`.AbsoluteBindingProtocol`) * - **Standard protein–ligand** - | **Complex leg:** | :class:`.ProteinComponent` + :class:`.SmallMoleculeComponent`\s + :class:`.SolventComponent` | | **Solvent leg:** | :class:`.SmallMoleculeComponent`\s + :class:`.SolventComponent` - | **Single ChemicalSystem (both legs):** | :class:`.ProteinComponent` + :class:`.SmallMoleculeComponent`\s + :class:`.SolventComponent` * - **Membrane system** - | **Complex leg:** | :class:`.ProteinMembraneComponent` + :class:`.SmallMoleculeComponent`\s | *(no* :class:`.SolventComponent` *— already explicitly solvated)* | | **Solvent leg:** | :class:`.SmallMoleculeComponent`\s + :class:`.SolventComponent` - | **Single ChemicalSystem (both legs):** | :class:`.ProteinMembraneComponent` + :class:`.SmallMoleculeComponent`\s + :class:`.SolventComponent` | *(protocol applies* :class:`.SolventComponent` *only in the solvent leg)* Thermodynamic Cycles -------------------- A thermodynamic cycle can be described as a set of :class:`.ChemicalSystem`\s (nodes) connected by alchemical transformations (edges). The :class:`.Protocol` defines how the :class:`.ChemicalSystem`\s map onto the cycle and how they are used in practice. The same :class:`.ChemicalSystem` can be reused across multiple thermodynamic states depending on the protocol. For details of which end states to construct, consult the :ref:`pages for each specific Protocol `. Hybrid topology RBFE example ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ As an example, the relative binding free energy cycle requires four :class:`.ChemicalSystem`\s — one for each node in the cycle: .. figure:: ../protocols/img/rbfe_thermocycle.png :scale: 40% :alt: RBFE thermodynamic cycle Illustration of the relative binding free energy thermodynamic cycles and the chemical systems at each end state. :: import openfe # two small molecules defined in a molfile format ligand_A = openfe.SmallMoleculeComponent.from_sdf_file('./ligand_A.sdf') ligand_B = openfe.SmallMoleculeComponent.from_sdf_file('./ligand_B.sdf') # a complete biological assembly protein = openfe.ProteinComponent.from_pdb_file('./protein.pdb') # defines an aqueous solvent environment, with a concentration of ions solvent = openfe.SolventComponent(smiles='O') # ligand_A + protein + solvent ligand_A_complex = openfe.ChemicalSystem(components={'ligand': ligand_A, 'protein': protein, 'solvent': solvent}) # ligand_B + protein + solvent ligand_B_complex = openfe.ChemicalSystem(components={'ligand': ligand_B, 'protein': protein, 'solvent': solvent}) # ligand_A + solvent ligand_A_solvent = openfe.ChemicalSystem(components={'ligand': ligand_A, 'solvent': solvent}) # ligand_B + solvent ligand_B_solvent = openfe.ChemicalSystem(components={'ligand': ligand_B, 'solvent': solvent}) Explicitly solvated variant ~~~~~~~~~~~~~~~~~~~~~~~~~~~ When using a :class:`.SolvatedPDBComponent` or :class:`.ProteinMembraneComponent`, replace :class:`.ProteinComponent` and :class:`.SolventComponent` for the complex leg. No separate :class:`.SolventComponent` is required: :: # explicitly solvated protein-membrane complex (box vectors read from CRYST1 record) protein_membrane = openfe.ProteinMembraneComponent.from_pdb_file('./protein_membrane.pdb') # ligand_A + explicitly solvated protein-membrane — no SolventComponent needed ligand_A_complex = openfe.ChemicalSystem(components={'ligand': ligand_A, 'protein_membrane': protein_membrane}) See Also -------- * To see how to construct a :class:`.ChemicalSystem` from your files, see :ref:`the cookbook entry on loading molecules ` * For details of which thermodynamic cycles to construct, consult the :ref:`pages for each specific Protocol ` ================================================ FILE: docs/guide/setup/creating_atom_mappings_and_scores.rst ================================================ .. _userguide_mappings: .. _Creating Atom Mappings: Creating Atom Mappings ====================== ``Atom Mapping`` objects are used to define the relationship between :ref:`components ` from different :class:`.ChemicalSystem`\s. This guide will show how ``Atom Mappings`` can describe the transformation between a pair of ligands. Generating Mappings ------------------- The :class:`.LigandAtomMapper` takes pairs of :class:`openfe.SmallMoleculeComponent`\s and returns zero (in the case that no mapping can be found) or more possible mappings. Built in to the ``openfe`` package are bindings to the `Lomap `_ package, including the :class:`.openfe.setup.LomapAtomMapper`, which uses an MCS approach based on RDKit. .. TODO: insert example output This is how we can create a mapping between two ligands: .. code:: import openfe from openfe import setup # as previously detailed, load a pair of ligands m1 = SmallMoleculeComponent(...) m2 = SmallMoleculeComponent(...) # first create an atom mapper mapper = setup.LomapAtomMapper(threed=True) # this returns an iterable of possible mappings mapping_gen = mapper.suggest_mappings(m1, m2) # extract all possible mappings into a list mappings = list(mapping_gen) # Lomap always produces a single Mapping, so extract it from the list mapping = mappings[0] The two molecules passed into the ``suggest_mappings()`` method are then referred to as ``componentA`` and ``componentB`` (in the above example, ``m1`` is ``componentA`` and ``m2`` is ``componentB``). The atom mapping can be accessed through the ``componentA_to_componentB`` attribute, which returns a dictionary where keys refer to the indices of atoms in the "A" component, and values refer to indices of atoms in the "B" component. If a given index does not appear, then it is unmapped. .. note:: Like the Component objects, a Mapping object is immutable once created! Visualising Mappings -------------------- In an interactive notebook we can view a 2D representation of the mapping. In this view, atoms that are deleted are coloured red, while atoms that undergo an elemental transformation are coloured blue. Similarly, bonds that are deleted are coloured red, while bonds that change (either bond order change or element change), are coloured blue. .. image:: img/2d_mapping.png :width: 90% :align: center :alt: Sample output of 2d mapping visualisation These 2D mappings can be saved to file using the :func:`LigandAtomMapping.draw_to_file()` method. With the ``py3dmol`` package, we can inspect the spatial overlap of the mapping in 3D. In a notebook, this produces an interactive rotatable view of the mapping. The left and rightmost views show the "A" and "B" molecules with coloured spheres on each showing the correspondence between atoms. The centre view shows both molecules overlaid, allowing the spatial correspondence to be directly viewed. .. code:: from openfe.utils import visualization_3D view = mapping.view_3d() .. image:: img/3d_mapping.png :width: 90% :align: center :alt: Sample output of view_3d() function The cartesian distance between pairs of atom mapping is also available via the :meth:`.get_distances()` method. This returns a numpy array. .. code:: mapping.get_distances() .. _Scoring Atom Mappings: Scoring Mappings ---------------- Mapping **scorers**, or "scoring functions", evaluate the quality of an atom mapping and can be used as objective functions for optimizing ligand networks. **Scorers** take a :class:`.LigandAtomMapping` object and return a value from 0.0 (indicating a terrible mapping) to 1.0 (indicating a great mapping). Because **scorers** are normalized, it is possible to use multiple **scorers** together. For example, the built-in Lomap scorer :func:`default_lomap_score` combines several criteria (such as the number of heavy atoms, if certain chemical changes are present, and if ring sizes are being mutated), into a single value. It is possible to combine scoring functions in this way because each scoring function returns a normalized value. .. code:: from openfe.setup.lomap_scorers mapping = next(mapper.suggest_mappings(m1, m2)) score = lomap_scorers.default_lomap_scorer(mapping) ================================================ FILE: docs/guide/setup/creating_ligand_networks.rst ================================================ .. _userguide_ligand_network: Defining the Ligand Network =========================== A :class:`.LigandNetwork` is a network where nodes are :class:`.SmallMoleculeComponent`\ s and edges are :class:`.LigandAtomMapping`\ s. For example, a :class:`.LigandNetwork` with drug candidates as nodes can be used to conduct a free energy campaign and compute ligand rankings. **openfe** includes an interface to common :any:`Ligand Network Planners`, which are implemented in OpenFE's `konnektor `_ package. (See `konnektor's documentation `_ for more information on network generators.) A :class:`.LigandNetwork` is constructed from :class:`.SmallMoleculeComponent`, which represent the nodes and optionally :class:`.LigandAtomMapping`, which represent the edges of the network. A :class:`.LigandAtomMapping` can have a :ref:`score associated with the mapping ` which can be used by some network generators to construct more efficient network topologies. Below is an example of a ``LigandNetwork`` with scores assigned to each atom mapping: .. image:: img/ligand_network.png :width: 80% :align: center :alt: Concept of a simple MST ligand network Generating Ligand Networks -------------------------- :class:`.LigandNetwork` generation can typically described by three steps: 1. Generate the :ref:`Atom Mappings` of all pairwise combinations of :class:`.SmallMoleculeComponent`\ s 2. :ref:`Calculate scores` for each :class:`.LigandAtomMapping` 3. Build a :class:`.LigandNetwork` with all possible mappings directed by their scores. .. code:: python import openfe from openfe import setup # load a set of ligands mols = [SmallMoleculeComponent.from_rdkit(x) for x in rdmols] # generate the required mapper, scorer, and planner objects mapper = setup.KartografAtomMapper() scorer = setup.lomap_scorers.default_lomap_score network_planner = setup.ligand_network_planning.generate_minimal_spanning_network # plan the ligand network ligand_network = network_planner(ligands=mols, mappers=[mapper], scorer=scorer) Practical information on generating ligand networks can be found in our :ref:`cookbook for ligand network generation `. .. note:: Like the Component objects, a ``LigandNetwork`` object is immutable once created! ================================================ FILE: docs/guide/setup/defining_protocols.rst ================================================ .. _defining-protocols: Protocols in OpenFE ============================ A :class:`.Protocol` is a computational method for estimating the free energy difference between two chemical systems. Just as there are multiple possible methods for estimating free energy differences, there are multiple available ``Protocol``\s to choose from. For example, included in the ``openfe`` package are the following: * :class:`.RelativeHybridTopologyProtocol` * :class:`.AbsoluteBindingProtocol` * :class:`.SepTopProtocol` * :class:`.AbsoluteSolvationProtocol` * :class:`.PlainMDProtocol` More protocols are in development, and a full list of available protocols can be found at :ref:`userguide_protocols`. Because :class:`.Protocol`\s share a common interface for how they are created and executed, it is relatively straightforward to try out a new method, or benchmark several to choose the best for a particular project. Defining Settings and Creating Protocols ---------------------------------------- A ``Settings`` object contains all the parameters needed by a ``Protocol``. Each ``Protocol`` has a ``.default_settings()`` method, which will provide a sensible default starting point and relevant documentation. .. TODO: print what a settings object looks like, or how you might define custom settings For example, to create an instance of the OpenMM RFE Protocol with default settings:: from openfe.protocols import openmm_rfe settings = openmm_rfe.RelativeHybridTopologyProtocol.default_settings() protocol = openmm_rfe.RelativeHybridTopologyProtocol(settings) ``Protocol`` objects **cannot be modified once created**. This is crucial for data provenance. Therefore, the ``Settings`` objects must be customised *before* the ``Protocol`` object is created. For example, to customise the production run length of the RFE Protocol:: from openfe.protocols import openmm_rfe settings = openmm_rfe.RelativeHybridTopologyProtocol.default_settings() settings.simulation_settings.production_length = '10 ns' protocol = openmm_rfe.RelativeHybridTopologyProtocol(settings) Adaptive Settings ~~~~~~~~~~~~~~~~~ .. warning:: The ``_adaptive_settings()`` method is experimental and subject to change. In addition to the ``.default_settings()`` method, some protocols provide an ``_adaptive_settings`` method. This method generates recommended settings based on properties of the input :class:`.ChemicalSystem`\s and, where required, the :class:`.AtomMapping`. For example:: from openfe.protocols import openmm_rfe settings = openmm_rfe.RelativeHybridTopologyProtocol._adaptive_settings( stateA=stateA, stateB=stateB, mapping=mapping, ) protocol = openmm_rfe.RelativeHybridTopologyProtocol(settings) The adaptive settings may modify parameters based on properties of the input systems. For example (:class:`.RelativeHybridTopologyProtocol`): * Transformations involving a change in net charge use a larger number of lambda windows and longer production simulations. * If both states contain a :class:`.ProteinComponent`, the solvation padding is set to 1 nm. Optionally, you can pass a preexisting settings object to the ``_adaptive_settings`` method via the ``initial_settings`` argument. If provided, an adapted copy of these settings will be returned instead of using the default settings. In systems containing membrane-protein complexes (i.e. using a :class:`.ProteinMembraneComponent`), adaptive settings select a membrane-appropriate barostat, the ``MonteCarloMembraneBarostat``. Creating Transformations from Protocols ----------------------------------------- With only ``settings`` defined, a ``Protocol`` contains no chemistry-specific information. This means that a single ``Protocol`` object can be applied to multiple pairs of ``ChemicalSystem`` objects to measure each free energy difference. The :class:`.Transformation` class connects two ``ChemicalSystem`` objects with a ``Protocol``, and often a :ref:`AtomMapping ` (depending on the system). A ``Transformation`` object is then capable of creating computational work via the :func:`.Transformation.create()` method. For further details on this, refer to the :ref:`userguide_execution` section. Finally, a ``Protocol`` is responsible for using the data generated in this process to perform further analysis, such as generating an estimate of the free energy difference. For further details on this refer to the :ref:`userguide_results` section, or the details of each method in :ref:`userguide_protocols`. ================================================ FILE: docs/guide/setup/index.rst ================================================ .. _userguide_setup: Simulation Setup ================ This section provides details on how to set up a free energy calculation or MD simulations. All protocols in OpenFE follow the same general structure: * Reading in input structures and creating :class:`.ChemicalSystem` \s * Defining the :class:`.Protocol` with specific `ProtocolSettings`. * Creating :class:`.LigandAtomMapping` \s for relative free energy calculation `Protocols`. .. image:: img/setup_1x.png :width: 70% :align: center :alt: Concept of a ChemicalSystems and Transformations The image below demonstrates how, for relative free energy calculations, you plan a network of ligand transformations starting from input SDF / MOL2 / PDB files: .. image:: img/setup_2x.png :width: 70% :align: center :alt: Concept of a LigandNetwork and AlchemicalNetwork The procedure for setting up a simulation depends on the type of free energy calculation you are running. More detailed instructions can be found in the following sections: .. toctree:: :maxdepth: 1 chemical_systems_and_thermodynamic_cycles creating_atom_mappings_and_scores defining_protocols creating_ligand_networks alchemical_network_model To set up your alchemical network using the Python interface, but run it using the CLI, you will need to export the network in the same format used by the CLI. See :ref:`dumping transformations ` for more details. ================================================ FILE: docs/guide/troubleshooting.rst ================================================ Troubleshooting Simulations =========================== This guide covers tips and strategies for troubleshooting simulation failures. Log Debug information --------------------- .. note:: When using a scheduler (e.g. SLURM), be sure to specify output files for standard out and standard error. For example, when using SLURM both ``--output=`` and ``--error=`` must be set to view errors. One of the first troubleshooting steps is to increase the verbosity of the logging. ``openfe`` uses Python's native logging library which can be `configured `_ either using a Python API or a configuration file. .. warning:: **We do not recommend setting the log level to debug for production runs,** as the logging may slow down the simulation and add a lot of noise to the output. When using ``openfe quickrun``, the configuration file is more convenient. Below is an example logging configuration file that can be used to set the log level to ``DEBUG``: .. code-block:: ini [loggers] keys=root [handlers] keys=stdout [formatters] keys=standardFormatter,msgOnly [handler_stdout] class=StreamHandler level=DEBUG formatter=standardFormatter args=(sys.stdout,) [logger_root] level=DEBUG handlers=stdout [formatter_standardFormatter] format=%(asctime)s %(levelname)s %(name)s: %(message)s [formatter_msgOnly] format=%(message)s Save this configuration file as ``debug_logging.conf`` and then run ``openfe quickrun`` with the ``--log`` flag, for example: .. code-block:: bash $ openfe --log debug_logging.conf quickrun -d results/ -o results/result_lig_ejm_31_solvent_lig_ejm_42_solvent.json transformations/rbfe_lig_ejm_31_solvent_lig_ejm_42_solvent.json Note that the ``--log debug_logging.conf`` argument goes between ``openfe`` and ``quickrun`` on the command line. This will cause every package to log at the debug level, which may be quite verbose and noisy but should aid in identify what is going on right before the exception is thrown. JAX warnings ------------ We use ``pymbar`` to analyze the free energy of the system. ``pymbar`` uses JAX to accelerate computation. The JAX library can utilize a GPU to further accelerate computation. If the necessary libraries for GPU acceleration are not installed and JAX detects a GPU, JAX will print a warning like this: .. code-block:: bash WARNING:2025-06-10 09:01:40,857:jax._src.xla_bridge:966: An NVIDIA GPU may be present on this machine, but a CUDA-enabled jaxlib is not installed. Falling back to cpu. This warning does not mean that the *molecular dynamics* simulation will fall back to using the CPU. The simulation will still use the computing platform specified in the settings. PYMBAR_DISABLE_JAX ------------------ Due to a suspected memory leak in the JAX acceleration code in ``pymbar`` we disable JAX acceleration by default. This memory leak may result in the simulation crashing, wasting compute time. The error message may look like this: .. code-block:: bash LLVM compilation error: Cannot allocate memory LLVM ERROR: Unable to allocate section memory! We have decided to disable JAX acceleration by default to prevent wasted compute. However, if you wish to use the JAX acceleration, you may set ``PYMBAR_DISABLE_JAX`` to ``TRUE`` (e.g. put ``export PYMBAR_DISABLE_JAX=FALSE`` in your submission script before running ``openfe quickrun``). For more information, see these issues on github: - https://github.com/choderalab/pymbar/issues/564 - https://github.com/OpenFreeEnergy/openfe/issues/1534 - https://github.com/OpenFreeEnergy/openfe/issues/1654 ================================================ FILE: docs/guide/under_the_hood.rst ================================================ .. _under-the-hood: Under the Hood ============== .. module:: openfe :noindex: If you want to implement your own atom mapper or free energy procedure, or you want to do something a bit more bespoke, it's helpful to understand how OpenFE thinks about individual alchemic mutation specifications. A :class:`Transformation` stores all the information needed to run an alchemic mutation from one chemical system to another and is the basic unit of an OpenFE simulation campaign. Indeed, :class:`Transformation` objects describe the edges of the graph in the :class:`AlchemicalNetwork` class. .. container:: deflist-flowchart * Setup - .. container:: flowchart-sidebyside - - .. rst-class:: flowchart-spacer - - :class:`Protocol` Simulation procedure for an alchemic mutation. .. rst-class:: arrow-down arrow-tail arrow-combine-right - - - Chemical component definition SDF, PDB, RDKit, OpenFF Molecule, solvent spec, etc. .. rst-class:: arrow-down arrow-tail - :any:`Loading Molecules` - .. container:: flowchart-sidebyside - - .. rst-class:: arrow-down arrow-head arrow-combine-right - - :class:`SmallMoleculeComponent` The ligands that will be mutated. .. rst-class:: arrow-down - :any:`Creating Atom Mappings` - :class:`LigandAtomMapping` Corresponds atoms in one small molecule to those in another. .. rst-class:: arrow-down arrow-tail arrow-combine - - - .. rst-class:: arrow-down arrow-head arrow-combine-left - - :class:`SmallMoleculeComponent`, :class:`SolventComponent` and :class:`ProteinComponent` The components that make up the chemical system. .. rst-class:: arrow-down arrow-multiple-combine - :any:`Assembling into ChemicalSystems` - :class:`ChemicalSystem` Each of the chemical systems, composed of components, that the :class:`Transformation` mutates between. .. rst-class:: arrow-down arrow-tail arrow-combine-left arrow-multiple - .. rst-class:: arrow-down arrow-head - - :class:`Transformation` A single alchemic mutation from one chemical system to another. .. rst-class:: arrow-down * * Run - :class:`Transformation` A single alchemic mutation from one chemical system to another. .. rst-class:: arrow-down - - :class:`ProtocolDAG` A directed acyclic graph describing how to compute a :class:`Transformation`. - .. container:: flowchart-sidebyside - - .. rst-class:: arrow-down arrow-multiple - - :class:`ProtocolUnit` A single unit of computation within a :class:`ProtocolDAG` .. rst-class:: arrow-down - - :class:`ProtocolUnitResult` The result of a completed :class:`ProtocolUnit` .. rst-class:: arrow-down arrow-multiple-combine - - - .. rst-class:: arrow-down - :any:`executors` - :class:`ProtocolDAGResult` A completed transformation. .. rst-class:: arrow-down * * Gather - .. container:: flowchart-sidebyside - - :class:`Transformation` The specification for the alchemic mutation. .. rst-class:: arrow-down - - :class:`Protocol` A completed single run of a transformation. .. rst-class:: arrow-down arrow-combine-right arrow-tail - - - :class:`ProtocolResult` A completed single run of a transformation. .. rst-class:: arrow-down arrow-combine-left arrow-multiple arrow-tail - .. rst-class:: arrow-down arrow-head - - :class:`ProtocolDAGResult` A completed transformation with multiple user-defined replicas. ================================================ FILE: docs/index.rst ================================================ .. template taken from SciPy who took it from Pandas (keep the chain going) .. module:: openfe ===================================== Welcome to OpenFE's documentation! ===================================== The **OpenFE** toolkit provides a free and open-source framework for alchemical free energy calculations. Using this toolkit you can plan, execute, and analyze free energy calculations using a variety of methods. **Useful Links**: `OpenFE Website `__ | `Example Tutorial notebooks `__ | `Source Repository `__ | `Issues & Ideas `__ .. grid:: 1 2 2 4 :gutter: 3 .. grid-item-card:: :fas:`download` Install openfe :text-align: center :link: installation :link-type: doc Follow our installation guide to get **openfe** running on your machine! .. grid-item-card:: :fas:`laptop-code` CLI Quickstart :text-align: center :link: tutorials/rbfe_cli_tutorial :link-type: doc Get started with **openfe**\'s command line interface. .. grid-item-card:: :fas:`person-chalkboard` Tutorials :text-align: center :link: tutorials/index :link-type: doc Step-by-step examples showing how to use the OpenFE toolkit. .. grid-item-card:: :fas:`book-open-reader` User Guide :text-align: center :link: guide/index :link-type: doc Explanations of key concept underlying the OpenFE toolkit. .. grid-item-card:: :fas:`table-list` Cookbooks :text-align: center :link: cookbook/index :link-type: doc How-to guides for common tasks. .. grid-item-card:: :fas:`code` API Reference :text-align: center :link: reference/index :link-type: doc Comprehensive details of the **openfe** Python and CLI APIs. .. grid-item-card:: :fas:`gears` Protocols :text-align: center :link: guide/protocols/index :link-type: doc Details of the specific Free Energy Protocols included in **openfe**. .. grid-item-card:: :fas:`clock-rotate-left` Changelog :text-align: center :link: CHANGELOG :link-type: doc A history of **openfe** releases. .. toctree:: :maxdepth: 2 :hidden: installation tutorials/index guide/index cookbook/index reference/index CHANGELOG Other OpenFE Ecosystem Projects: -------------------------------- **openfe** is Open Free Energy's user-facing software for performing alchemical free energy calculations. Below are other software projects the Open Free Energy team maintains, many of which are used by **openfe** itself. * `konnektor `_: free energy network planning, modification, and analysis * `kartograf `_: atom mappings focusing on 3D geometries * `Lomap `_: planning perturbation networks for free energy calculations * `cinnabar `_ (formerly arsenic): plotting free energy calculation results * `gufe `_ : data structures and models underlying the OpenFE ecosystem Community-Developed Projects: ----------------------------- * `alchemiscale `_: high-throughput alchemical free energy execution, developed by `Datryllic `_. ================================================ FILE: docs/installation.rst ================================================ Installation ============ **openfe** is currently only compatible with POSIX systems (macOS and UNIX/Linux). See `Supported Hardware`_ for more details. We try to follow `SPEC0 `_ as far as minimum supported dependencies, with the following caveats: - OpenMM 8.0, 8.1.2, 8.2, and 8.4 - **OpenMM v8.3.0 is not supported** When you install **openfe** through any of the methods described below, you will install both the core library and the command line interface (CLI). Installation with ``micromamba`` (recommended) ---------------------------------------------- OpenFE recommends ``micromamba`` as a package manager for most users, as it is a lightweight version of ``mamba``, which is a must faster drop-in replacement for ``conda`` . If you prefer to use ``mamba`` or ``conda`` instead of ``micromamba`` because of its additional functionality, we suggest following our `Miniforge Installation Guide`_. In the instructions below, we will use the ``micromamba`` command, but you can use ``conda`` or ``mamba`` in the same way. Once you have one of `micromamba `_, `mamba `_, or `conda `_ installed, you can continue to the **openfe** installation instructions below. .. note:: After installing, you must run ``micromamba activate openfe`` in each shell session where you want to use **openfe**! Reproducible builds with a ``conda-lock`` file ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .. _conda-lock: https://github.com/conda/conda-lock?tab=readme-ov-file#conda-lock We recommend building from **openfe**'s ``conda-lock`` file in most cases, since it allows for building packages in a reproducible way on multiple platforms. Unlike the single file installer, an internet connection is required to install from a ``conda-lock`` file. The ``conda-lock`` files for the latest version of **openfe** can be downloaded with :: $ curl -LOJ https://github.com/OpenFreeEnergy/openfe/releases/latest/download/openfe-conda-lock.yml If a particular version is required, the URL will look like this (using the ``openfe 1.6.1`` release as an example) :: $ curl -LOJ https://github.com/OpenFreeEnergy/openfe/releases/download/v1.6.1/openfe-1.6.1-conda-lock.yml ``micromamba`` supports ``conda-lock`` files and can be used directly to create a virtual environment :: $ micromamba create -n openfe --file openfe-conda-lock.yml $ micromamba activate openfe .. note:: If you are having trouble building from the conda-lock file, you may need to build directly with ``conda-lock``. We recommend installing ``conda-lock`` in a new virtual environment. This will reduce the chance of dependency conflicts :: $ # Install conda lock into a virtual environment $ micromamba create -n conda-lock conda-lock $ # Activate the environment to use the conda-lock command $ micromamba activate conda-lock $ conda-lock install -n openfe openfe-conda-lock.yml $ micromamba activate openfe To make sure everything is working, :ref:`run the tests `. With that, you should be ready to use **openfe**! Standard Installation with ``micromamba`` ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ There may be some instances where you don't want to use a lock-file, e.g. you may want to specify a dependency that differs from the lock file. In these cases, you can simply install **openfe** from conda-forge: .. parsed-literal:: micromamba create -c conda-forge -n openfe openfe=\ |version| micromamba activate openfe Single file installer --------------------- .. warning:: The single file installer may modify your ``.bashrc`` in a way that requires manual intervention to access your previous ``conda`` installation .. _releases on GitHub: https://github.com/OpenFreeEnergy/openfe/releases Single file installers are available for x86_64 Linux and MacOS. They are attached to our `releases on GitHub`_ and can be downloaded with a browser or ``curl`` (or similar tool). For example, the Linux installer can be downloaded with :: $ curl -LOJ https://github.com/OpenFreeEnergy/openfe/releases/latest/download/OpenFEforge-Linux-x86_64.sh And the MacOS (arm64) installer :: $ curl -LOJ https://github.com/OpenFreeEnergy/openfe/releases/latest/download/OpenFEforge-MacOSX-arm64.sh MacOS x86_64 is no longer supported. The single file installer contains all of the dependencies required for **openfe** and does not require internet access to use. Both ``conda`` and ``mamba`` are also available in the environment created by the single file installer and can be used to install additional packages. The installer can be installed in batch mode or interactively :: $ chmod +x ./OpenFEforge-Linux-x86_64.sh # Make installer executable $ ./OpenFEforge-Linux-x86_64.sh # Run the installer Example installer output is shown below (click to expand "Installer Output") .. collapse:: Installer Output .. code-block:: Welcome to OpenFEforge 0.7.4 In order to continue the installation process, please review the license agreement. Please, press ENTER to continue >>> MIT License Copyright (c) 2022 OpenFreeEnergy Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. Do you accept the license terms? [yes|no] [no] >>> yes .. note:: The install location will be different when you run the installer. .. code-block:: OpenFEforge will now be installed into this location: /home/mmh/openfeforge - Press ENTER to confirm the location - Press CTRL-C to abort the installation - Or specify a different location below [/home/mmh/openfeforge] >>> PREFIX=/home/mmh/openfeforge Unpacking payload ... Installing base environment... Downloading and Extracting Packages Downloading and Extracting Packages Preparing transaction: done Executing transaction: \ By downloading and using the CUDA Toolkit conda packages, you accept the terms and conditions of the CUDA End User License Agreement (EULA): https://docs.nvidia.com/cuda/eula/index.html | Enabling notebook extension jupyter-js-widgets/extension... - Validating: OK done installation finished. Do you wish the installer to initialize OpenFEforge by running conda init? [yes|no] [no] >>> yes no change /home/mmh/openfeforge/condabin/conda no change /home/mmh/openfeforge/bin/conda no change /home/mmh/openfeforge/bin/conda-env no change /home/mmh/openfeforge/bin/activate no change /home/mmh/openfeforge/bin/deactivate no change /home/mmh/openfeforge/etc/profile.d/conda.sh no change /home/mmh/openfeforge/etc/fish/conf.d/conda.fish no change /home/mmh/openfeforge/shell/condabin/Conda.psm1 no change /home/mmh/openfeforge/shell/condabin/conda-hook.ps1 no change /home/mmh/openfeforge/lib/python3.9/site-packages/xontrib/conda.xsh no change /home/mmh/openfeforge/etc/profile.d/conda.csh modified /home/mmh/.bashrc ==> For changes to take effect, close and re-open your current shell. <== __ __ __ __ / \ / \ / \ / \ / \/ \/ \/ \ ███████████████/ /██/ /██/ /██/ /████████████████████████ / / \ / \ / \ / \ \____ / / \_/ \_/ \_/ \ o \__, / _/ \_____/ ` |/ ███╗ ███╗ █████╗ ███╗ ███╗██████╗ █████╗ ████╗ ████║██╔══██╗████╗ ████║██╔══██╗██╔══██╗ ██╔████╔██║███████║██╔████╔██║██████╔╝███████║ ██║╚██╔╝██║██╔══██║██║╚██╔╝██║██╔══██╗██╔══██║ ██║ ╚═╝ ██║██║ ██║██║ ╚═╝ ██║██████╔╝██║ ██║ ╚═╝ ╚═╝╚═╝ ╚═╝╚═╝ ╚═╝╚═════╝ ╚═╝ ╚═╝ mamba (1.4.2) supported by @QuantStack GitHub: https://github.com/mamba-org/mamba Twitter: https://twitter.com/QuantStack █████████████████████████████████████████████████████████████ no change /home/mmh/openfeforge/condabin/conda no change /home/mmh/openfeforge/bin/conda no change /home/mmh/openfeforge/bin/conda-env no change /home/mmh/openfeforge/bin/activate no change /home/mmh/openfeforge/bin/deactivate no change /home/mmh/openfeforge/etc/profile.d/conda.sh no change /home/mmh/openfeforge/etc/fish/conf.d/conda.fish no change /home/mmh/openfeforge/shell/condabin/Conda.psm1 no change /home/mmh/openfeforge/shell/condabin/conda-hook.ps1 no change /home/mmh/openfeforge/lib/python3.9/site-packages/xontrib/conda.xsh no change /home/mmh/openfeforge/etc/profile.d/conda.csh no change /home/mmh/.bashrc No action taken. Added mamba to /home/mmh/.bashrc ==> For changes to take effect, close and re-open your current shell. <== If you'd prefer that conda's base environment not be activated on startup, set the auto_activate_base parameter to false: conda config --set auto_activate_base false Thank you for installing OpenFEforge! After the installer completes, close and reopen your shell. To check if your path is setup correctly, run ``which python`` your output should look something like this :: (base) $ which python /home/mmh/openfeforge/bin/python .. note:: Your path will be different, but the important part is ``openfeforge/bin/python`` Now the CLI tool should work as well :: (base) $ openfe --help Usage: openfe [OPTIONS] COMMAND [ARGS]... This is the command line tool to provide easy access to functionality from the OpenFE Python library. Options: --version Show the version and exit. --log PATH logging configuration file -h, --help Show this message and exit. Network Planning Commands: plan-rhfe-network Plan a relative hydration free energy network, saved as JSON files for the quickrun command. plan-rbfe-network Plan a relative binding free energy network, saved as JSON files for the quickrun command. view-ligand-network Visualize a ligand network Quickrun Executor Commands: gather Gather result jsons for network of RFE results into a TSV file quickrun Run a given transformation, saved as a JSON file Miscellaneous Commands: fetch Fetch tutorial or other resource. charge-molecules Generate partial charges for a set of molecules. test Run the OpenFE test suite To make sure everything is working, :ref:`run the tests `. With that, you should be ready to use **openfe**! .. _installation:containers: Containerized Distributions ---------------------------- We provide an official docker and Apptainer (formerly Singularity) image. The docker image is tagged with the version of **openfe** on the image and can be pulled with :: $ docker pull ghcr.io/openfreeenergy/openfe:latest The Apptainer image is pre-built and can be pulled with :: $ singularity pull oras://ghcr.io/openfreeenergy/openfe:latest-apptainer .. warning:: For production use, we recommend using version tags to prevent disruptions in workflows e.g. .. parsed-literal:: $ docker pull ghcr.io/openfreeenergy/openfe:\ |version| $ singularity pull oras://ghcr.io/openfreeenergy/openfe:\ |version|-apptainer We recommend testing the container to ensure that it can access a GPU (if desired). This can be done with the following command :: $ singularity run --nv openfe_latest-apptainer.sif python -m openmm.testInstallation OpenMM Version: 8.0 Git Revision: a7800059645f4471f4b91c21e742fe5aa4513cda There are 3 Platforms available: 1 Reference - Successfully computed forces 2 CPU - Successfully computed forces 3 CUDA - Successfully computed forces Median difference in forces between platforms: Reference vs. CPU: 6.29328e-06 Reference vs. CUDA: 6.7337e-06 CPU vs. CUDA: 7.44698e-07 All differences are within tolerance. The ``--nv`` flag is required for the Apptainer image to access the GPU on the host. Your output may produce different values for the forces, but should list the CUDA platform if everything is working properly. You can access the **openfe** CLI from the Singularity image with :: $ singularity run --nv openfe_latest-apptainer.sif openfe --help To make sure everything is working, run the tests :: $ singularity run --nv openfe_latest-apptainer.sif openfe test You can also run the long tests with ``openfe test --long``, as explained in `Testing Your Installation`_. With that, you should be ready to use **openfe**! .. note:: If building a custom docker image, you may need to need to add ``--ulimit nofile=262144:262144`` to the ``docker build`` command. See this `issue `_ for details. HPC Environments ---------------- When using High Performance Computing resources, jobs are typically submitted to a queue from a "login node" and then run at a later time, often on different hardware and in a different software environment. This can complicate installation as getting something working on the login node does not guarantee it will work in the job. We recommend using `Apptainer (formerly Singularity) `_ when running **openfe** workflows in HPC environments. This images provide a software environment that is isolated from the host which can make workflow execution easier to setup and more reproducible. See our guide on :ref:`containers ` for how to get started using Apptainer/Singularity. .. _installation:mamba_hpc: ``micromamba`` in HPC Environments ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .. _virtual packages: https://docs.conda.io/projects/conda/en/latest/user-guide/tasks/manage-virtual.html#managing-virtual-packages We recommend using a :ref:`container ` to install **openfe** in HPC environments. Nonetheless, **openfe** can be installed via Conda Forge on these environments also. Conda Forge distributes its own CUDA binaries for interfacing with the GPU, rather than use the host drivers. ``conda``, ``mamba`` and ``micromamba`` all use `virtual packages`_ to detect and specify which version of CUDA should be installed. This is a common point of difference in hardware between the login and job nodes in an HPC environment. In order to determine the correct ``cuda-version`` version, we recommend connecting to the node where the simulation will be executed and run ``nvidia-smi``. For example :: $ nvidia-smi Tue Mar 31 19:46:32 2026 +-----------------------------------------------------------------------------------------+ | NVIDIA-SMI 590.48.01 Driver Version: 590.48.01 CUDA Version: 13.1 | +-----------------------------------------+------------------------+----------------------+ | GPU Name Persistence-M | Bus-Id Disp.A | Volatile Uncorr. ECC | | Fan Temp Perf Pwr:Usage/Cap | Memory-Usage | GPU-Util Compute M. | | | | MIG M. | |=========================================+========================+======================| | 0 NVIDIA A100 80GB PCIe On | 00000000:65:00.0 Off | 0 | | N/A 32C P0 44W / 300W | 0MiB / 81920MiB | 0% Default | | | | Disabled | +-----------------------------------------+------------------------+----------------------+ +-----------------------------------------------------------------------------------------+ | Processes: | | GPU GI CI PID Type Process name GPU Memory | | ID ID Usage | |=========================================================================================| | No running processes found | +-----------------------------------------------------------------------------------------+ in this output of ``nvidia-smi`` we can see in the upper right of the output ``CUDA Version: 13.1`` which means the installed driver will support a CUDA version up to ``13.1``. To install a version of **openfe** which is compatible with CUDA ``13.1``, run: .. parsed-literal:: $ micromamba create -n openfe cuda-version=13.1 openfe=\ |version| Developer install ----------------- If you're going to be developing for **openfe**, you will want an installation where your changes to the code are immediately reflected in the functionality. This is called a "developer" or "editable" installation. Getting a developer installation for **openfe** first installing the requirements, and then creating the editable installation. We recommend doing that with ``micromamba`` using the following procedure: First, clone the **openfe** repository, and switch into its root directory:: $ git clone https://github.com/OpenFreeEnergy/openfe.git $ cd openfe Next create a ``conda`` environment containing the requirements from the specification in that directory:: $ micromamba create -f environment.yml Then activate the openfe environment with:: $ micromamba activate openfe_env Finally, create the editable installation:: $ python -m pip install --no-deps -e . Note the ``.`` at the end of that command, which indicates the current directory. .. _testing: Testing Your Installation ------------------------- After installing **openfe**, make sure everything is working as expected by running the test suite with :: $ openfe test The test suite contains several hundred individual tests. This will take a few minutes, and all tests should complete with status either passed, skipped, or xfailed (expected fail). The very first time you run this, the initial check that you can import ``openfe`` will take a while, because some code is compiled the first time it is encountered. That compilation only happens once per installation, and so subsequent calls to ``openfe`` will be faster. A more expansive test suite can be run using :: $ openfe test --long This test suite contains several hundred individual tests. This may take up to an hour, and all tests should complete with status either passed, skipped, or xfailed (expected fail). This "long" test suite should be run as a job on the compute hardware intended to run openfe jobs, as it will test GPU specific features. Troubleshooting Your Installation --------------------------------- We have created a script that can be run locally to assist in troubleshooting errors. The script does not upload any information and the output may be inspected before the output is sent to us. We recommend running the script in the same environment where the error was observed. For example, if you had an error when creating a system on your local workstation, run the script locally with the same conda environment active as when the error occurred. If the error occurred when running the job on an HPC resource, then run the script (ideally) on the same node where the problem occurred. This helps to debug issues such as a CUDA and NVIDIA driver mismatch (which would be impossible to diagnose if the script was ran on a login node without a GPU). The script is available here: https://github.com/OpenFreeEnergy/openfe/blob/main/devtools/debug_openmm.sh For your convenience, this command will download the script and save the output as ``debug.log`` .. parsed-literal:: $ bash -c "$(curl -Ls https://raw.githubusercontent.com/OpenFreeEnergy/openfe/main/devtools/debug_openmm.sh)" | tee -a debug.log The output of the script will also be printed to standard out as it is executed. While no sensitive information is extracted, it is good practice to review the output before sending it or posting it to ensure that nothing needs to be redacted. For example, if your python path was ``/data/SECRET_COMPOUND_NAME/python`` then that would show up in ``debug.log``. Common Errors ------------- .. parsed-literal:: openmm.OpenMMException: Error loading CUDA module: CUDA_ERROR_UNSUPPORTED_PTX_VERSION (222) This error likely means that the CUDA version that ``openmm`` was built with is incompatible with the CUDA driver. Try re-making the environment while specifying the correct CUDA toolkit version for your hardware and driver. See :ref:`installation:mamba_hpc` for more details. Optional dependencies --------------------- Certain functionalities are only available if you also install other, optional packages. * **perses tools**: To use perses, you need to install perses and OpenEye, and you need a valid OpenEye license. To install both packages, use:: $ mamba install -c openeye perses openeye-toolkits Supported Hardware ------------------ We currently support the following CPU architectures: * ``linux-64`` * ``osx-arm64`` For simulation preparation, any supported platform is suitable. We test our software regularly by performing vacuum transformations on ``linux-64`` using the OpenMM CUDA platform. While OpenMM supports OpenCL, we do not regularly test that platform (the CUDA platform is more performant) so we do not recommend using that platform without performing your own verification of correctness. For production use, we recommend the ``linux-64`` platform with NVIDIA GPUs for optimal performance. When using an OpenMM based protocol on NVIDIA GPUs, we recommend driver version ``525.60.13`` or greater. The minimum driver version required when installing from conda-forge is ``450.36.06``, but newer versions of OpenMM may not support that driver version as CUDA 11 will be removed the build matrix. Miniforge Installation Guide ---------------------------- .. _Miniforge: https://github.com/conda-forge/miniforge?tab=readme-ov-file#miniforge `Miniforge`_ provides minimal installers for either ``conda`` or ``mamba``, and enables easy installation of other software that ``openfe`` needs, such as OpenMM and AmberTools. We recommend using ``miniforge`` to install ``mamaba`` because it is faster than ``conda`` and comes preconfigured to use ``conda-forge``. To install and configure ``miniforge``, you need to know your operating system, your machine architecture (output of ``uname -m``), and your shell (in most cases, can be determined from ``echo $SHELL``). Select your operating system and architecture from the tool below, and run the commands it suggests. .. raw:: html
You should then close your current session and open a fresh login to ensure that everything is properly registered. You can now proceed to use ``mamba`` commands as instructed above. ================================================ FILE: docs/make.bat ================================================ @ECHO OFF pushd %~dp0 REM Command file for Sphinx documentation if "%SPHINXBUILD%" == "" ( set SPHINXBUILD=sphinx-build ) set SOURCEDIR=. set BUILDDIR=_build if "%1" == "" goto help %SPHINXBUILD% >NUL 2>NUL if errorlevel 9009 ( echo. echo.The 'sphinx-build' command was not found. Make sure you have Sphinx echo.installed, then set the SPHINXBUILD environment variable to point echo.to the full path of the 'sphinx-build' executable. Alternatively you echo.may add the Sphinx directory to PATH. echo. echo.If you don't have Sphinx installed, grab it from echo.https://www.sphinx-doc.org/ exit /b 1 ) %SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% goto end :help %SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% :end popd ================================================ FILE: docs/reference/api/alchemical_network_planning.rst ================================================ .. _Alchemical Network Planning: Simulation Campaign Planning ============================ While a :class:`LigandNetwork` describes a network of ligands and their atom mappings, a :class:`AlchemicalNetwork` describes a single replicate of a simulation campaign. It includes all the information needed to perform the simulation, and so implicitly includes the :class:`LigandNetwork`. Alchemical Simulations ~~~~~~~~~~~~~~~~~~~~~~ Descriptions of anticipated alchemical simulation campaigns. .. module:: openfe :noindex: .. autosummary:: :nosignatures: :toctree: generated/ Transformation AlchemicalNetwork Alchemical Network Planners --------------------------- Alchemical network planners are objects that pull all the ideas in OpenFE into a quick setup for simulation. The goal is to create the :class:`.AlchemicalNetwork` that represents an entire simulation campaign, starting from a bare amount of user input. .. module:: openfe.setup :noindex: .. autosummary:: :nosignatures: :toctree: generated/ RBFEAlchemicalNetworkPlanner RHFEAlchemicalNetworkPlanner ================================================ FILE: docs/reference/api/atom_mappers.rst ================================================ .. _Atom Mappers: Atom Mappings ============= Tools for mapping atoms in one molecule to those in another. Used to generate efficient ligand networks. .. module:: openfe.setup.atom_mapping .. rubric:: Abstract Base Class .. autosummary:: :nosignatures: :toctree: generated/ LigandAtomMapper .. rubric:: Implementations .. autosummary:: :nosignatures: :toctree: generated/ KartografAtomMapper LomapAtomMapper PersesAtomMapper .. rubric:: Data Types .. autosummary:: :nosignatures: :toctree: generated/ LigandAtomMapping .. _Atom Map Scorers: Atom Map Scorers ---------------- Scoring functions for a mapping between ligands. These are used as objective functions for :any:`Ligand Network Planners`. Lomap Scorers ~~~~~~~~~~~~~ Scorers implemented by the `LOMAP `_ package. .. apparently we need the atom_mapping because internally autofunction is trying ``import openfe.setup.lomap_scorers``, which doesn't work (whereas ``from openfe.setup import lomap_scorers`` does) .. module:: openfe.setup.atom_mapping.lomap_scorers .. autosummary:: :nosignatures: :toctree: generated/ default_lomap_score ecr_score mcsr_score mncar_score atomic_number_score hybridization_score sulfonamides_score heterocycles_score transmuting_methyl_into_ring_score transmuting_ring_sizes_score Perses Scorers ~~~~~~~~~~~~~~ Scorers implemented by the `Perses `_ package. .. module:: openfe.setup.atom_mapping.perses_scorers .. autosummary:: :nosignatures: :toctree: generated/ default_perses_scorer ================================================ FILE: docs/reference/api/defining_and_executing_simulations.rst ================================================ .. _reference_execution: Defining and Executing Simulations ================================== .. _executors: Executing Simulations --------------------- .. module:: openfe :noindex: .. autosummary:: :nosignatures: :toctree: generated/ execute_DAG General classes --------------- .. module:: openfe :noindex: .. autosummary:: :nosignatures: :toctree: generated/ ProtocolDAG ProtocolUnitResult ProtocolUnitFailure ProtocolDAGResult Specialised classes ------------------- These classes are abstract classes that are specialised (subclassed) for an individual Protocol. .. module:: openfe :noindex: .. autosummary:: :nosignatures: :toctree: generated/ Protocol ProtocolUnit ProtocolResult ================================================ FILE: docs/reference/api/index.rst ================================================ .. _api: .. note:: We have reproduced API documentation from the `gufe`_ package here for convenience. `gufe`_ serves as a foundation layer for openfe, providing abstract base classes and object models, and so might be more useful for developers. Python API Reference ==================== .. toctree:: :maxdepth: 2 systems_and_components atom_mappers ligand_network alchemical_network_planning defining_and_executing_simulations openmm_rfe openmm_solvation_afe openmm_binding_afe openmm_septop openmm_md openmm_protocol_settings .. _gufe: https://gufe.openfree.energy/en/stable/api.html ================================================ FILE: docs/reference/api/ligand_network.rst ================================================ Ligand Network Tools ==================== .. module:: openfe.setup :noindex: Ligand Network -------------- A network of mutations between ligands. .. autosummary:: :nosignatures: :toctree: generated/ LigandNetwork .. _Ligand Network Planners: Network Planners ~~~~~~~~~~~~~~~~ .. module:: openfe.setup.ligand_network_planning Functions that build a :class:`.LigandNetwork` from a collection of :class:`SmallMoleculeComponents` by optimizing over a `scoring function `_. .. autosummary:: :nosignatures: :toctree: generated/ generate_radial_network generate_maximal_network generate_minimal_spanning_network generate_minimal_redundant_network generate_lomap_network .. _Ligand Network Loaders: Network Loaders ~~~~~~~~~~~~~~~ Functions to load a :class:`.LigandNetwork` from equivalent classes in other packages, or to specify one by hand. .. autosummary:: :nosignatures: :toctree: generated/ generate_network_from_names generate_network_from_indices load_orion_network load_fepplus_network ================================================ FILE: docs/reference/api/openmm_binding_afe.rst ================================================ OpenMM Absolute Binding Free Energy Protocol ============================================ .. _afe binding protocol api: This section provides details about the OpenMM Absolute Binding Free Energy Protocol implemented in OpenFE. Protocol API specification -------------------------- .. module:: openfe.protocols.openmm_afe.equil_binding_afe_method .. autosummary:: :nosignatures: :toctree: generated/ AbsoluteBindingProtocol ABFEComplexAnalysisUnit ABFEComplexSetupUnit ABFEComplexSimUnit ABFESolventAnalysisUnit ABFESolventSetupUnit ABFESolventSimUnit AbsoluteBindingProtocolResult Protocol Settings ----------------- Below are the settings which can be tweaked in the protocol. The default settings (accessed using :meth:`AbsoluteBindingProtocol.default_settings`) will automatically populate settings which we have found to be useful for running binding free energy calculations. There will however be some cases (such as when calculating difficult to converge systems) where you will need to tweak some of the following settings. .. module:: openfe.protocols.openmm_afe.equil_afe_settings .. autopydantic_model:: AbsoluteBindingSettings :model-show-json: False :model-show-field-summary: False :model-show-config-member: False :model-show-config-summary: False :model-show-validator-members: False :model-show-validator-summary: False :field-list-validators: False :inherited-members: SettingsBaseModel :exclude-members: get_defaults :member-order: bysource ================================================ FILE: docs/reference/api/openmm_md.rst ================================================ OpenMM Molecular Dynamics (MD) Protocol ======================================= .. _md protocol api: A Protocol for running MD simulation using OpenMM. Protocol API Specification -------------------------- .. module:: openfe.protocols.openmm_md .. autosummary:: :nosignatures: :toctree: generated/ PlainMDProtocol PlainMDSetupUnit PlainMDSimulationUnit PlainMDProtocolResult Protocol Settings ----------------- .. module:: openfe.protocols.openmm_md.plain_md_settings .. autopydantic_model:: PlainMDProtocolSettings :model-show-json: False :model-show-field-summary: False :model-show-config-member: False :model-show-config-summary: False :model-show-validator-members: False :model-show-validator-summary: False :field-list-validators: False :inherited-members: SettingsBaseModel :exclude-members: get_defaults :member-order: bysource ================================================ FILE: docs/reference/api/openmm_protocol_settings.rst ================================================ OpenMM Protocol Settings ======================== .. _openmm protocol settings api: This page documents the Settings classes used by OpenMM-based Protocols. Details on which of these Settings classes are used by a given Protocol can be found on the individual Protocol API reference documentation pages: * :ref:`OpenMM Absolute Solvation Free Energy ` * :ref:`OpenMM Relative Free Energy ` * :ref:`OpenMM Relative Free Energy using SepTop ` * :ref:`OpenMM Molecular Dynamics Protocol ` Shared OpenMM Protocol Settings ------------------------------- The following are Settings classes which are shared between multiple OpenMM-based Protocols. Please note that not all Protocols use these Settings classes. .. module:: openfe.protocols.openmm_utils.omm_settings .. autopydantic_model:: IntegratorSettings :model-show-json: False :model-show-field-summary: False :model-show-config-member: False :model-show-config-summary: False :model-show-validator-members: False :model-show-validator-summary: False :field-list-validators: False :inherited-members: SettingsBaseModel :member-order: bysource .. autopydantic_model:: MDOutputSettings :model-show-json: False :model-show-field-summary: False :model-show-config-member: False :model-show-config-summary: False :model-show-validator-members: False :model-show-validator-summary: False :field-list-validators: False :inherited-members: SettingsBaseModel :member-order: bysource .. autopydantic_model:: MDSimulationSettings :model-show-json: False :model-show-field-summary: False :model-show-config-member: False :model-show-config-summary: False :model-show-validator-members: False :model-show-validator-summary: False :field-list-validators: False :inherited-members: SettingsBaseModel :member-order: bysource .. autopydantic_model:: OpenMMEngineSettings :model-show-json: False :model-show-field-summary: False :model-show-config-member: False :model-show-config-summary: False :model-show-validator-members: False :model-show-validator-summary: False :field-list-validators: False :inherited-members: SettingsBaseModel :member-order: bysource .. autopydantic_model:: OpenFFPartialChargeSettings :model-show-json: False :model-show-field-summary: False :model-show-config-member: False :model-show-config-summary: False :model-show-validator-members: False :model-show-validator-summary: False :field-list-validators: False :inherited-members: SettingsBaseModel :member-order: bysource .. autopydantic_model:: OpenMMSolvationSettings :model-show-json: False :model-show-field-summary: False :model-show-config-member: False :model-show-config-summary: False :model-show-validator-members: False :model-show-validator-summary: False :field-list-validators: False :inherited-members: SettingsBaseModel :member-order: bysource .. autopydantic_model:: OpenMMSystemGeneratorFFSettings :model-show-json: False :model-show-field-summary: False :model-show-config-member: False :model-show-config-summary: False :model-show-validator-members: False :model-show-validator-summary: False :field-list-validators: False :inherited-members: SettingsBaseModel :member-order: bysource .. autopydantic_model:: ThermoSettings :model-show-json: False :model-show-field-summary: False :model-show-config-member: False :model-show-config-summary: False :model-show-validator-members: False :model-show-validator-summary: False :field-list-validators: False :inherited-members: SettingsBaseModel :member-order: bysource Shared MultiState OpenMM Protocol Settings ------------------------------------------ Protocol Settings shared between MultiState simulation protocols. These currently include the following Protocols: * :ref:`OpenMM Absolute Solvation Free Energy ` * :ref:`OpenMM Relative Free Energy ` * :ref:`OpenMM Relative Free Energy using SepTop ` .. autopydantic_model:: MultiStateOutputSettings :model-show-json: False :model-show-field-summary: False :model-show-config-member: False :model-show-config-summary: False :model-show-validator-members: False :model-show-validator-summary: False :field-list-validators: False :inherited-members: SettingsBaseModel :member-order: bysource .. autopydantic_model:: MultiStateSimulationSettings :model-show-json: False :model-show-field-summary: False :model-show-config-member: False :model-show-config-summary: False :model-show-validator-members: False :model-show-validator-summary: False :field-list-validators: False :inherited-members: SettingsBaseModel :member-order: bysource ================================================ FILE: docs/reference/api/openmm_rfe.rst ================================================ OpenMM Relative Free Energy Protocol ==================================== .. _rfe protocol api: This section provides details about the OpenMM Relative Free Energy Protocol implemented in OpenFE. Protocol API specification -------------------------- .. module:: openfe.protocols.openmm_rfe.equil_rfe_methods .. autosummary:: :nosignatures: :toctree: generated/ RelativeHybridTopologyProtocol HybridTopologySetupUnit HybridTopologyMultiStateSimulationUnit HybridTopologyMultiStateAnalysisUnit RelativeHybridTopologyProtocolResult Protocol Settings ----------------- Below are the settings which can be tweaked in the protocol. The default settings (accessed using :meth:`RelativeHybridTopologyProtocol.default_settings`) will automatically populate a settings which we have found to be useful for running relative binding free energies using explicit solvent. There will however be some cases (such as when doing gas phase calculations) where you will need to tweak some of the following settings. .. autopydantic_model:: openfe.protocols.openmm_rfe.equil_rfe_settings.RelativeHybridTopologyProtocolSettings :model-show-json: False :model-show-field-summary: False :model-show-config-member: False :model-show-config-summary: False :model-show-validator-members: False :model-show-validator-summary: False :field-list-validators: False :inherited-members: SettingsBaseModel :exclude-members: get_defaults :member-order: bysource Protocol Specific Settings Classes ---------------------------------- Below are Settings classes which are unique to the ``RelativeHybridTopologyProtocol``. .. autopydantic_model:: openfe.protocols.openmm_rfe.equil_rfe_settings.AlchemicalSettings :model-show-json: False :model-show-field-summary: False :model-show-config-member: False :model-show-config-summary: False :model-show-validator-members: False :model-show-validator-summary: False :field-list-validators: False :inherited-members: SettingsBaseModel :member-order: bysource .. autopydantic_model:: openfe.protocols.openmm_rfe.equil_rfe_settings.LambdaSettings :model-show-json: False :model-show-field-summary: False :model-show-config-member: False :model-show-config-summary: False :model-show-validator-members: False :model-show-validator-summary: False :field-list-validators: False :inherited-members: SettingsBaseModel :member-order: bysource ================================================ FILE: docs/reference/api/openmm_septop.rst ================================================ OpenMM Separated Topologies Protocol ==================================== .. _septop protocol api: This section provides details about the OpenMM Separated Topologies Protocol implemented in OpenFE. Protocol API specification -------------------------- .. module:: openfe.protocols.openmm_septop.equil_septop_method .. autosummary:: :nosignatures: :toctree: generated/ SepTopProtocol SepTopComplexSetupUnit SepTopComplexRunUnit SepTopComplexAnalysisUnit SepTopSolventSetupUnit SepTopSolventRunUnit SepTopSolventAnalysisUnit SepTopProtocolResult Protocol Settings ----------------- Below are the settings which can be tweaked in the protocol. The default settings (accessed using :meth:`SepTopProtocol.default_settings`) will automatically populate settings which we have found to be useful for running a Separated Topologies free energy calculation. There will however be some cases (such as when calculating difficult to converge systems) where you will need to tweak some of the following settings. .. module:: openfe.protocols.openmm_septop.equil_septop_settings .. autopydantic_model:: SepTopSettings :model-show-json: False :model-show-field-summary: False :model-show-config-member: False :model-show-config-summary: False :model-show-validator-members: False :model-show-validator-summary: False :field-list-validators: False :inherited-members: SettingsBaseModel :exclude-members: get_defaults :member-order: bysource Protocol Specific Settings Classes ---------------------------------- Below are Settings classes which are unique to the `SepTopProtocol`. .. autopydantic_model:: AlchemicalSettings :model-show-json: False :model-show-field-summary: False :model-show-config-member: False :model-show-config-summary: False :model-show-validator-members: False :model-show-validator-summary: False :field-list-validators: False :inherited-members: SettingsBaseModel :member-order: bysource .. autopydantic_model:: LambdaSettings :model-show-json: False :model-show-field-summary: False :model-show-config-member: False :model-show-config-summary: False :model-show-validator-members: False :model-show-validator-summary: False :field-list-validators: False :inherited-members: SettingsBaseModel :member-order: bysource .. autopydantic_model:: SepTopEquilOutputSettings :model-show-json: False :model-show-field-summary: False :model-show-config-member: False :model-show-config-summary: False :model-show-validator-members: False :model-show-validator-summary: False :field-list-validators: False :inherited-members: SettingsBaseModel :member-order: bysource ================================================ FILE: docs/reference/api/openmm_solvation_afe.rst ================================================ OpenMM Absolute Solvation Free Energy Protocol ============================================== .. _afe solvation protocol api: This section provides details about the OpenMM Absolute Solvation Free Energy Protocol implemented in OpenFE. Protocol API specification -------------------------- .. module:: openfe.protocols.openmm_afe.equil_solvation_afe_method .. autosummary:: :nosignatures: :toctree: generated/ AbsoluteSolvationProtocol AHFESolventAnalysisUnit AHFESolventSetupUnit AHFESolventSimUnit AHFEVacuumAnalysisUnit AHFEVacuumSetupUnit AHFEVacuumSimUnit AbsoluteSolvationProtocolResult Protocol Settings ----------------- Below are the settings which can be tweaked in the protocol. The default settings (accessed using :meth:`AbsoluteSolvationProtocol.default_settings`) will automatically populate settings which we have found to be useful for running solvation free energy calculations. There will however be some cases (such as when calculating difficult to converge systems) where you will need to tweak some of the following settings. .. autopydantic_model:: openfe.protocols.openmm_afe.equil_afe_settings.AbsoluteSolvationSettings :model-show-json: False :model-show-field-summary: False :model-show-config-member: False :model-show-config-summary: False :model-show-validator-members: False :model-show-validator-summary: False :field-list-validators: False :inherited-members: SettingsBaseModel :exclude-members: get_defaults :member-order: bysource Protocol Specific Settings Classes ---------------------------------- Below are Settings classes which are unique to the ``AbsoluteSolvationProtocol``. .. autopydantic_model:: openfe.protocols.openmm_afe.equil_afe_settings.AlchemicalSettings :model-show-json: False :model-show-field-summary: False :model-show-config-member: False :model-show-config-summary: False :model-show-validator-members: False :model-show-validator-summary: False :field-list-validators: False :inherited-members: SettingsBaseModel :member-order: bysource .. autopydantic_model:: openfe.protocols.openmm_afe.equil_afe_settings.LambdaSettings :model-show-json: False :model-show-field-summary: False :model-show-config-member: False :model-show-config-summary: False :model-show-validator-members: False :model-show-validator-summary: False :field-list-validators: False :inherited-members: SettingsBaseModel :member-order: bysource ================================================ FILE: docs/reference/api/systems_and_components.rst ================================================ Chemical Systems and Components =============================== We describe a chemical system as being made up of one or more "components," e.g., solvent, protein, or small molecule. The :class:`.ChemicalSystem` object joins components together into a simulation system. .. module:: openfe :noindex: .. autosummary:: :nosignatures: :toctree: generated/ ChemicalSystem Transformation Component SmallMoleculeComponent ProteinComponent ProteinMembraneComponent SolventComponent SolvatedPDBComponent Chemical System Generators -------------------------- .. module:: openfe.setup.chemicalsystem_generator .. autosummary:: :nosignatures: :toctree: generated/ EasyChemicalSystemGenerator ================================================ FILE: docs/reference/cli/charge_molecules.rst ================================================ .. _cli_charge_molecules: ``charge-molecules`` command ============================ .. click:: openfecli.commands.generate_partial_charges:charge_molecules :prog: openfe charge-molecules ================================================ FILE: docs/reference/cli/gather.rst ================================================ .. _cli_gather: ``gather`` command ==================== Currently, ``openfe gather`` is only able to gather results from Relative Binding Free Energy (RBFE) calculations. To gather results from ABFE or SepTop protocols, you may use the experimental :ref:`openfe gather-abfe ` and :ref:`openfe gather-septop ` CLI commands, but please note that these commands are still under development and liable to change in future releases, and meant to be used only for exploratory work. .. click:: openfecli.commands.gather:gather :prog: openfe gather .. _gather-abfe: .. click:: openfecli.commands.gather_abfe:gather_abfe :prog: openfe gather-abfe .. _gather-septop: .. click:: openfecli.commands.gather_septop:gather_septop :prog: openfe gather-septop ================================================ FILE: docs/reference/cli/index.rst ================================================ .. _cli-reference: CLI Reference ============= .. toctree:: :maxdepth: 1 charge_molecules plan_rhfe_network plan_rbfe_network quickrun gather ================================================ FILE: docs/reference/cli/plan_rbfe_network.rst ================================================ .. _cli_plan-rbfe-network: ``plan-rbfe-network`` command ============================= .. click:: openfecli.commands.plan_rbfe_network:plan_rbfe_network :prog: openfe plan-rbfe-network ================================================ FILE: docs/reference/cli/plan_rhfe_network.rst ================================================ .. _cli_plan-rhfe-network: ``plan-rhfe-network`` command ============================= .. click:: openfecli.commands.plan_rhfe_network:plan_rhfe_network :prog: openfe plan-rhfe-network ================================================ FILE: docs/reference/cli/quickrun.rst ================================================ .. _cli_quickrun: ``quickrun`` command ==================== .. click:: openfecli.commands.quickrun:quickrun :prog: openfe quickrun ================================================ FILE: docs/reference/index.rst ================================================ Reference ========= This contains details of the Python API as well as a reference to the command line interface. .. note:: We have reproduced API documentation from the `gufe`_ package here for convenience. `gufe`_ serves as a foundation layer for openfe, providing abstract base classes and object models, and so might be more useful for developers. .. toctree:: :maxdepth: 2 api/index cli/index .. _gufe: https://gufe.readthedocs.io/en/latest/api.html ================================================ FILE: docs/tutorials/.gitignore ================================================ assets/ inputs/ ================================================ FILE: docs/tutorials/abfe_analysis_tutorial.nblink ================================================ { "path": "../ExampleNotebooks/abfe_tutorial/abfe_analysis.ipynb" } ================================================ FILE: docs/tutorials/abfe_tutorial.nblink ================================================ { "path": "../ExampleNotebooks/abfe_tutorial/abfe_tutorial.ipynb", "extra-media": [ "../ExampleNotebooks/abfe_tutorial/abfe-cycle.png" ] } ================================================ FILE: docs/tutorials/ahfe_tutorial.nblink ================================================ { "path": "../ExampleNotebooks/ahfe_tutorial/ahfe_tutorial.ipynb", "extra-media": [ "../ExampleNotebooks/ahfe_tutorial/ahfe_cycle.png" ] } ================================================ FILE: docs/tutorials/charge_molecules_cli_tutorial.rst ================================================ .. _charge_molecules_cli_tutorial: .. include:: /ExampleNotebooks/cli_tutorials/cli_charge_molecules.md :parser: myst_parser.sphinx_ ================================================ FILE: docs/tutorials/index.rst ================================================ Tutorials ========= .. todo: make sure we can inline the tutorial, for now we only provide links Below is a collection of tutorials that demonstrate key elements of OpenFE tooling. You can clone the `Example Notebooks Repository `_ to explore any of these tutorials interactively. Relative Free Energies ---------------------- - :any:`Python API Showcase `: Start here! An introduction to OpenFE's Python API and approach to performing a relative binding free energy calculation. - :any:`RBFE using the Python API `: A step-by-step tutorial for using the Python API to calculate relative binding free energies for TYK2. - :ref:`RBFE using the CLI `: A step-by-step tutorial for using the OpenFE command line interface (CLI) to calculate relative binding free energies for TYK2. - :any:`RBFE with membrane systems `: A step-by-step guide to setting up an RBFE calculation with special considerations for membrane systems. Absolute Free Energies ---------------------- - :any:`Absolute Absolute Free Energy Protocol `: A walk-through of calculating the absolute binding free energy of toluene to T4 Lysozyme. - :any:`Absolute Solvation Free Energy Protocol `: A walk-through of calculating the hydration free energy of a benzene ligand. Relative Free Energies using Separated Topologies ------------------------------------------------- - :any:`SepTop Protocol `: A walk-through of calculating the relative binding free energy between TYK2 ligands using a Separated Topologies approach. Molecular Dynamics (MD) ----------------------- - :any:`MD protocol `: A walk-through of running a conventional (non-alchemical) MD simulation of benzene bound to T4-lysozyme L99A. Post-Simulation Analysis ------------------------ - :any:`Cinnabar tutorial `: A tutorial for using the `cinnabar `_ Python package to analyze (e.g. generating MLE estimates of absolute free energies) and plot networks of relative free energy results. Generating Partial Charges -------------------------- .. todo: this should be in cookbook - :ref:`Generating Partial Charges CLI tutorial `: how to use the CLI to assign and store partial charges for mall molecules which can be used throughout the OpenFE ecosystem. .. toctree:: :maxdepth: 1 :hidden: showcase_notebook rbfe_python_tutorial rbfe_cli_tutorial rbfe_membrane_protein abfe_tutorial abfe_analysis_tutorial ahfe_tutorial septop_tutorial septop_analysis_tutorial md_tutorial plotting_with_cinnabar charge_molecules_cli_tutorial ================================================ FILE: docs/tutorials/md_tutorial.nblink ================================================ { "path": "../ExampleNotebooks/openmm_md/plain_md.ipynb", "extra-media": [ "../ExampleNotebooks/openmm_md/assets/" ] } ================================================ FILE: docs/tutorials/plotting_with_cinnabar.nblink ================================================ { "path": "../ExampleNotebooks/plotting_rbfes_with_cinnabar/PlottingFreeEnergiesUsingCinnabar.ipynb" } ================================================ FILE: docs/tutorials/rbfe_cli_tutorial.rst ================================================ .. _rbfe_cli_tutorial: .. include:: /ExampleNotebooks/rbfe_tutorial/cli_tutorial.md :parser: myst_parser.sphinx_ ================================================ FILE: docs/tutorials/rbfe_membrane_protein.nblink ================================================ { "path": "../ExampleNotebooks/membranes/rbfe_membrane_protein.ipynb" } ================================================ FILE: docs/tutorials/rbfe_python_tutorial.nblink ================================================ { "path": "../ExampleNotebooks/rbfe_tutorial/rbfe_python_tutorial.ipynb" } ================================================ FILE: docs/tutorials/septop_analysis_tutorial.nblink ================================================ { "path": "../ExampleNotebooks/openmm_septop/septop_analysis.ipynb" } ================================================ FILE: docs/tutorials/septop_tutorial.nblink ================================================ { "path": "../ExampleNotebooks/openmm_septop/septop_tutorial.ipynb", "extra-media": [ "../ExampleNotebooks/openmm_septop/septop_cycle.png" ] } ================================================ FILE: docs/tutorials/showcase_notebook.nblink ================================================ { "path": "../ExampleNotebooks/showcase/openfe_showcase.ipynb", "extra-media": [ "../ExampleNotebooks/showcase/tyk2.png", "../ExampleNotebooks/showcase/OFE-color-horizontal.png", "../ExampleNotebooks/showcase/inputs" ] } ================================================ FILE: environment.yml ================================================ name: openfe_env channels: - conda-forge dependencies: - cinnabar ~=0.5.0 - click >=8.2.0 - coverage - dask>=2025 # temporary fix for https://github.com/openforcefield/openff-units/issues/140 - duecredit<0.10 - kartograf>=1.2.0 - konnektor~=0.2.0 - lomap2>=3.2.1 - networkx - numpy - openfe-analysis>=0.4.0 # min pin https://github.com/OpenFreeEnergy/openfe/issues/1834#issuecomment-3920079481, no max to check issues with new versions - openff-interchange-base >=0.5.0,!= 0.5.1 # https://github.com/openforcefield/openff-interchange/issues/1450 and https://github.com/OpenFreeEnergy/openfe/pull/1901 - openff-nagl-base >=0.3.3 - openff-nagl-models>=0.1.2 - openff-toolkit-base >=0.16.2 - openff-units==0.3.1 # https://github.com/OpenFreeEnergy/openfe/pull/1374 - openmm ~=8.4.0 # omit 8.3.0 and 8.3.1 due to https://github.com/openmm/openmm/pull/5069 - openmmforcefields >=0.15.1 # min needed for https://github.com/openmm/openmmforcefields/pull/414 - openmmtools >=0.26 # fix to support membrane barostat: https://github.com/choderalab/openmmtools/pull/798 - packaging - pandas - parmed >=4.3.1 # fix to support numpy >=2.3: https://github.com/ParmEd/ParmEd/pull/1387 - perses>=0.10.3 - plugcli - pint>=0.24.0 - pip - pooch >= 1.9.0 # min needed for https://github.com/fatiando/pooch/issues/502 - py3dmol - pydantic >= 2.0.0, <2.12.0 # https://github.com/openforcefield/openff-interchange/issues/1346 - pygraphviz - pytest - pytest-xdist - pytest-cov - pytest-regressions - pytest-rerunfailures - pyyaml - rdkit - rich - tqdm - typing-extensions - zstandard # Issue #443 - pymbar>4.0 # docs - autodoc-pydantic>=2.0 - pydata-sphinx-theme - sphinx-click - sphinx-toolbox # Control blas/openmp threads - threadpoolctl - pip: - git+https://github.com/OpenFreeEnergy/gufe@main - run_constrained: # drop this pin when handled upstream in espaloma-feedstock - smirnoff99frosst>=1.1.0.1 #https://github.com/openforcefield/smirnoff99Frosst/issues/109 ================================================ FILE: news/TEMPLATE.rst ================================================ **Added:** * **Changed:** * **Deprecated:** * **Removed:** * **Fixed:** * **Security:** * ================================================ FILE: production/Dockerfile ================================================ FROM mambaorg/micromamba:1.4.1 LABEL org.opencontainers.image.source=https://github.com/OpenFreeEnergy/openfe LABEL org.opencontainers.image.description="A Python package for executing alchemical free energy calculations." LABEL org.opencontainers.image.licenses=MIT # OpenFE Version we want to build ARG VERSION # install ps USER root RUN apt-get update && apt-get install -y --no-install-recommends \ procps \ && rm -rf /var/lib/apt/lists/* USER $MAMBA_USER # Don't buffer stdout & stderr streams, so if there is a crash no partial buffer output is lost # https://docs.python.org/3/using/cmdline.html#cmdoption-u ENV PYTHONUNBUFFERED=1 COPY --chown=$MAMBA_USER:$MAMBA_USER production/environment.yml /tmp/env.yaml RUN micromamba install -y -n base git "openfe==$VERSION" -f /tmp/env.yaml && \ micromamba clean --all --yes # Ensure that conda environment is automatically activated # https://github.com/mamba-org/micromamba-docker#running-commands-in-dockerfile-within-the-conda-environment ARG MAMBA_DOCKERFILE_ACTIVATE=1 ================================================ FILE: production/environment.yml ================================================ name: openfe_env channels: - conda-forge dependencies: - cudatoolkit==11.8 - jupyterlab - notebook - openfe - pip - py3dmol - pytest - pytest-xdist - python==3.12.* - rdkit==2025.09.1 ================================================ FILE: pyproject.toml ================================================ [build-system] build-backend = "setuptools.build_meta" requires = [ "setuptools>=77.0.3", "setuptools-scm>=8", ] [project] name = "openfe" description = "" readme = "README.md" license = "MIT" license-files = [ "LICENSE" ] authors = [ { name = "The OpenFE developers", email = "openfreeenergy@omsf.io" } ] requires-python = ">=3.11" classifiers = [ "Development Status :: 5 - Production/Stable", "Intended Audience :: Science/Research", "Operating System :: POSIX", "Programming Language :: Python :: 3 :: Only", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", "Programming Language :: Python :: 3.13", "Programming Language :: Python :: 3.14", "Topic :: Scientific/Engineering :: Bio-Informatics", "Topic :: Scientific/Engineering :: Chemistry", ] dynamic = [ "version" ] urls = { Homepage = "https://github.com/OpenFreeEnergy/openfe" } scripts.openfe = "openfecli.cli:main" [tool.setuptools] zip-safe = false include-package-data = true package-data.openfe = [ '"./src/openfe/tests/data/lomap_basic/toluene.mol2"' ] packages.find.where = [ "src" ] packages.find.namespaces = false [tool.setuptools_scm] fallback_version = "0.0.0" [tool.ruff] line-length = 100 format.docstring-code-format = true # Enable Pyflakes (`F`) and a subset of the pycodestyle (`E`) codes by default. lint.select = [ "E", # pycodestyle errors "F", # Pyflakes "I", # isort "W", # pycodestyle warnings # "C901" # mccabe complexity TODO: add this back in # "UP", # TODO: add this in ] lint.ignore = [ "E402", # module-level import not at top (conflicts w/ isort) "E501", # line length too long, resolve this for comments "F401", # unused imports (TODO: we should fix these) "F811", "F841", "UP03", # pyupgrade linting (TODO: we should fix these) ] lint.isort.known-first-party = [ "openfe" ] [tool.mypy] files = "src/openfe" # TODO: add src/openfecli ignore_missing_imports = true warn_unused_ignores = true [tool.coverage] run.omit = [ "src/*/tests/dev/*py", "src/*/tests/protocols/test_openmm_rfe_slow.py", "src/openfe/due.py", ] report.exclude_lines = [ "-no-cov", 'if __name__ == "__main__"', "pragma: no cover", "pragma: no-cover", "raise NotImplementedError", ] ================================================ FILE: rever.xsh ================================================ $PROJECT = $GITHUB_REPO = 'openfe' $GITHUB_ORG = 'OpenFreeEnergy' $ACTIVITIES = ['changelog'] $CHANGELOG_FILENAME = 'docs/CHANGELOG.rst' $CHANGELOG_TEMPLATE = 'TEMPLATE.rst' ================================================ FILE: src/openfe/__init__.py ================================================ # Before we do anything else, we want to disable JAX # acceleration by default but if a user has set # PYMBAR_DISABLE_JAX to some value, we want to keep # it import logging import os logger = logging.getLogger(__name__) if "PYMBAR_DISABLE_JAX" in os.environ: logger.info( f"PYMBAR_DISABLE_JAX set to {os.environ.get('PYMBAR_DISABLE_JAX')}. See https://docs.openfree.energy/en/latest/guide/troubleshooting.html#pymbar-disable-jax for more details" ) # setdefault will only set PYMBAR_DISABLE_JAX if it is unset os.environ.setdefault("PYMBAR_DISABLE_JAX", "TRUE") # We need to do this first so that we can set up our # log control since some modules have warnings on import from openfe.utils import logging_control logging_control._silence_message( msg=[ "****** PyMBAR will use 64-bit JAX! *******", ], logger_names=[ "pymbar.mbar_solvers", ], ) logging_control._silence_message( msg=[ "Warning on use of the timeseries module:", ], logger_names=[ "pymbar.timeseries", ], ) logging_control._append_logger( suffix="\n \n[OPENFE]: The simulation is still using the compute platform specified in the settings \n See this URL for more information: https://docs.openfree.energy/en/latest/guide/troubleshooting.html#jax-warnings \n\n", logger_names="jax._src.xla_bridge", ) from importlib.metadata import version from gufe import ( AlchemicalNetwork, ChemicalSystem, Component, LigandAtomMapping, NonTransformation, ProteinComponent, ProteinMembraneComponent, SmallMoleculeComponent, SolvatedPDBComponent, SolventComponent, Transformation, ) from gufe.protocols import ( Protocol, ProtocolDAG, ProtocolDAGResult, ProtocolResult, ProtocolUnit, ProtocolUnitFailure, ProtocolUnitResult, execute_DAG, ) from . import analysis, orchestration, setup, utils from .setup import ( KartografAtomMapper, LigandAtomMapper, LigandNetwork, LomapAtomMapper, PersesAtomMapper, ligand_network_planning, lomap_scorers, perses_scorers, ) __version__ = version("openfe") ================================================ FILE: src/openfe/analysis/__init__.py ================================================ # This code is part of OpenFE and is licensed under the MIT license. # For details, see https://github.com/OpenFreeEnergy/openfe from . import plotting ================================================ FILE: src/openfe/analysis/plotting.py ================================================ # This code is part of OpenFE and is licensed under the MIT license. # For details, see https://github.com/OpenFreeEnergy/openfe import warnings from typing import Optional, Union import matplotlib.pyplot as plt import numpy as np import numpy.typing as npt from matplotlib.axes import Axes from openff.units import Quantity def plot_lambda_transition_matrix(matrix: npt.NDArray) -> Axes: """ Plot out a transition matrix. Parameters ---------- matrix : npt.NDArray A nstates by nstates matrix of transition estimates. Returns ------- ax : matplotlib.axes.Axes An Axes object to plot. Raises ------ UserWarning If any row or column exceeds a sum value of 1.01. This indicates an incorrect overlap/probability matrix. Notes ----- Borrowed from `alchemlyb `_ which itself borrows from `alchemical-analysis `_. """ num_states = len(matrix) # Check if any row or column isn't close to 1.0 # Throw a warning if it's the case if not np.allclose(matrix.sum(axis=0), 1.0) or not np.allclose(matrix.sum(axis=1), 1.0): wmsg = ( "Overlap/probability matrix exceeds a sum of 1.0 in one or " "more columns or rows of the matrix. This indicates an " "incorrect overlap/probability matrix." ) warnings.warn(wmsg) fig, ax = plt.subplots(figsize=(num_states / 2, num_states / 2)) ax.axis("off") for i in range(num_states): if i != 0: ax.axvline(x=i, ls="-", lw=0.5, color="k", alpha=0.25) ax.axhline(y=i, ls="-", lw=0.5, color="k", alpha=0.25) for j in range(num_states): val = matrix[i, j] # Catch if 0.05 from 0 or 1 # https://github.com/OpenFreeEnergy/openfe/issues/806 if matrix[j, i] < 0.005: # This replicates the same behaviour as alchemical-analysis & alchemlyb # i.e. near-zero values will just not be annotated val_str = "" elif matrix[j, i] > 0.995: val_str = "{:.2f}".format(matrix[j, i])[:4] else: val_str = "{:.2f}".format(matrix[j, i])[1:] rel_prob = val / matrix.max() # shade box ax.fill_between( [i, i + 1], [num_states - j, num_states - j], [num_states - (j + 1), num_states - (j + 1)], color="k", alpha=rel_prob, ) # annotate box ax.annotate( val_str, xy=(i, j), xytext=(i + 0.5, num_states - (j + 0.5)), size=8, va="center", ha="center", color=("k" if rel_prob < 0.5 else "w"), ) # annotate axes base_settings: dict[str, Union[str, int]] = { "size": 10, "va": "center", "ha": "center", "color": "k", "family": "sans-serif", } for i in range(num_states): ax.annotate( text=f"{i}", xy=(i + 0.5, 1), xytext=(i + 0.5, num_states + 0.5), xycoords="data", textcoords=None, arrowprops=None, annotation_clip=None, **base_settings, ) ax.annotate( text=f"{i}", xy=(-0.5, num_states - (num_states - 0.5)), xytext=(-0.5, num_states - (i + 0.5)), xycoords="data", textcoords=None, arrowprops=None, annotation_clip=None, **base_settings, ) ax.annotate( r"$\lambda$", xy=(-0.5, num_states - (num_states - 0.5)), xytext=(-0.5, num_states + 0.5), xycoords="data", textcoords=None, arrowprops=None, annotation_clip=None, **base_settings, ) # add border ax.plot([0, num_states], [0, 0], "k-", lw=2.0) ax.plot([num_states, num_states], [0, num_states], "k-", lw=2.0) ax.plot([0, num_states], [num_states, num_states], "k-", lw=2.0) ax.plot([0, 0], [0, num_states], "k-", lw=2.0) return ax def plot_convergence( forward_and_reverse: dict[str, Union[npt.NDArray, Quantity]], units: Quantity ) -> Axes: """ Plot a Reverse and Forward convergence analysis of the free energies. Parameters ---------- forward_and_reverse : dict[str, npt.NDArray] A dictionary containing the reverse and forward values of the free energies sampled along a given fraction of the sample size. units : openff.units.Quantity The units the free energies are provided in. Returns ------- ax : matplotlib.axes.Axes An Axes object to plot. Notes ----- Modified from `alchemical analysis <>`_ """ known_units = { "kilojoule_per_mole": "kJ/mol", "kilojoules_per_mole": "kJ/mol", "kilocalorie_per_mole": "kcal/mol", "kilocalories_per_mole": "kcal/mol", } try: plt_units = known_units[str(units)] except KeyError: errmsg = ( f"Unknown plotting units {units} passed, acceptable " "values are kilojoule(s)_per_mole and " "kilocalorie(s)_per_mole" ) raise ValueError(errmsg) fig, ax = plt.subplots(figsize=(8, 6)) # Old style alchemical analysis formatting plt.setp(ax.spines["bottom"], color="#D2B9D3", lw=3, zorder=-2) plt.setp(ax.spines["left"], color="#D2B9D3", lw=3, zorder=-2) for dire in ["top", "right"]: ax.spines[dire].set_color("none") ax.xaxis.set_ticks_position("bottom") ax.yaxis.set_ticks_position("left") # Set the overall error bar to the final error for the reverse results overall_error = forward_and_reverse["reverse_dDGs"][-1].m # type: ignore final_value = forward_and_reverse["reverse_DGs"][-1].m # type: ignore ax.fill_between( [0, 1], final_value - overall_error, final_value + overall_error, color="#D2B9D3", zorder=1 ) ax.errorbar( forward_and_reverse["fractions"], # type: ignore [val.m for val in forward_and_reverse["forward_DGs"]], # type: ignore yerr=[err.m for err in forward_and_reverse["forward_dDGs"]], # type: ignore color="#736AFF", lw=3, zorder=2, marker="o", mfc="w", mew=2.5, mec="#736AFF", ms=8, label="Forward", ) ax.errorbar( forward_and_reverse["fractions"], # type: ignore [val.m for val in forward_and_reverse["reverse_DGs"]], # type: ignore yerr=[err.m for err in forward_and_reverse["reverse_dDGs"]], # type: ignore color="#C11B17", lw=3, zorder=2, marker="o", mfc="w", mew=2.5, mec="#C11B17", ms=8, label="Reverse", ) ax.legend(frameon=False) ax.set_ylabel(r"$\Delta G$" + f" ({plt_units})") ax.set_xlabel("Fraction of uncorrelated samples") return ax def plot_replica_timeseries( state_timeseries: npt.NDArray, equilibration_iterations: Optional[int] = None, ) -> Axes: """ Plot a the state timeseries of a set of replicas. Parameters ---------- state_timeseries : npt.NDArray A 2D n_iterattions by n_states array of the replica timeseries. equilibration_iterations : Optional[int] The number of iterations used up as equilibration time. Returns ------- ax : matplotlib.axes.Axes An Axes object to plot. """ num_states = len(state_timeseries.T) fig, ax = plt.subplots(figsize=(num_states, 4)) iterations = [i for i in range(len(state_timeseries))] for i in range(num_states): ax.scatter(iterations, state_timeseries.T[i], label=f"replica {i}", s=8) ax.set_xlabel("Number of simulation iterations") ax.set_ylabel("Lambda state") ax.set_title("Change in replica lambda state over time") if equilibration_iterations is not None: ax.axvline( x=equilibration_iterations, color="grey", linestyle="--", label="equilibration limit" ) ax.legend(loc="center left", bbox_to_anchor=(1, 0.5)) return ax def plot_2D_rmsd(data: list[list[float]], vmax=5.0) -> plt.Figure: """Plots 2D RMSD for many states Parameters ---------- data : list[list[float]] for each state, the 2D RMSD vmax : float, optional the value to consider "high" in the colourmap to flag bad values, defaults to 5.0 (A) Returns ------- matplotlib Figure """ twod_rmsd_arrs = [] for state in data: # unpack 2D RMSD data # we store N(N-1)//2 values, so find N then make symmetric array N = int((1 + np.sqrt(8 * len(state) + 1)) / 2) arr = np.zeros((N, N)) arr[np.triu_indices_from(arr, k=1)] = state arr += arr.T twod_rmsd_arrs.append(arr) nplots = len(data) + 1 # + colorbar # plot on 4 x n grid nrows = nplots // 4 + (1 if nplots % 4 else 0) fig, axes = plt.subplots(nrows, 4) for i, (arr, ax) in enumerate(zip(twod_rmsd_arrs, axes.flatten())): ax.imshow(arr, vmin=0, vmax=vmax, cmap=plt.get_cmap("cividis")) ax.axis("off") # turn off ticks/labels ax.set_title(f"State {i}") # if we have any leftover plots then we turn them off # except the last one! overage = len(axes.flatten()) - len(twod_rmsd_arrs) for i in range(overage, len(axes.flatten()) - 1): axes.flatten()[i].set_axis_off() plt.colorbar( axes.flatten()[0].images[0], cax=axes.flatten()[-1], label="RMSD scale (A)", orientation="horizontal", ) fig.suptitle("Protein 2D RMSD") fig.tight_layout() return fig def plot_ligand_COM_drift(time: list[float], data: list[list[float]]): fig, ax = plt.subplots() for i, s in enumerate(data): ax.plot(time, s, label=f"State {i}") ax.legend(loc="upper left") ax.set_xlabel("Time (ps)") ax.set_ylabel("Distance (A)") ax.set_title("Ligand COM drift") return fig def plot_ligand_RMSD(time: list[float], data: list[list[float]]): fig, ax = plt.subplots() for i, s in enumerate(data): ax.plot(time, s, label=f"State {i}") ax.legend(loc="upper left") ax.set_xlabel("Time (ps)") ax.set_ylabel("RMSD (A)") ax.set_title("Ligand RMSD") return fig ================================================ FILE: src/openfe/data/__init__.py ================================================ ================================================ FILE: src/openfe/data/_downloader.py ================================================ import pooch from ._registry import zenodo_data_registry def retrieve_registry_data(zenodo_registry: list[dict], path: str) -> None: """Helper function for pulling all test data up-front. Parameters ---------- path : str path to store the data - usually a pooch.os_cache instance. """ downloader = pooch.DOIDownloader(progressbar=True) def _infer_processor(fname: str): if fname.endswith("tar.gz"): return pooch.Untar() elif fname.endswith("zip"): return pooch.Unzip() else: return None for d in zenodo_registry: pooch.retrieve( url=d["base_url"] + d["fname"], known_hash=d["known_hash"], fname=d["fname"], processor=_infer_processor(d["fname"]), downloader=downloader, path=path, ) ================================================ FILE: src/openfe/data/_registry.py ================================================ import pooch POOCH_CACHE = pooch.os_cache("openfe") zenodo_rfe_simulation_nc = dict( base_url="doi:10.5281/zenodo.15375081/", fname="simulation.nc", known_hash="md5:bc4e842b47de17704d804ae345b91599", ) zenodo_t4_lysozyme_traj = dict( base_url="doi:10.5281/zenodo.15212342", fname="t4_lysozyme_trajectory.zip", known_hash="sha256:e985d055db25b5468491e169948f641833a5fbb67a23dbb0a00b57fb7c0e59c8", ) zenodo_industry_benchmark_systems = dict( base_url="doi:10.5281/zenodo.15212342", fname="industry_benchmark_systems.zip", known_hash="sha256:2bb5eee36e29b718b96bf6e9350e0b9957a592f6c289f77330cbb6f4311a07bd", ) zenodo_resume_data = dict( base_url="doi:10.5281/zenodo.19694844", fname="multistate_checkpoints.zip", known_hash="md5:a6bdceff0c4a2f200538edb17c21d443", ) zenodo_md_resume_data = dict( base_url="doi:10.5281/zenodo.19694944", fname="checkpoint.xml", known_hash="md5:0f3957c263b5def8de727c5c419b31b5", ) zenodo_data_registry = [ zenodo_rfe_simulation_nc, zenodo_t4_lysozyme_traj, zenodo_industry_benchmark_systems, zenodo_resume_data, zenodo_md_resume_data, ] ================================================ FILE: src/openfe/due.py ================================================ # emacs: at the end of the file # ex: set sts=4 ts=4 sw=4 et: # ## ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### # """ Stub file for a guaranteed safe import of duecredit constructs: if duecredit is not available. To use it, place it into your project codebase to be imported, e.g. copy as cp stub.py /path/tomodule/module/due.py Note that it might be better to avoid naming it duecredit.py to avoid shadowing installed duecredit. Then use in your code as from .due import due, Doi, BibTeX, Text See https://github.com/duecredit/duecredit/blob/master/README.md for examples. Origin: Originally a part of the duecredit Copyright: 2015-2021 DueCredit developers License: BSD-2 """ __version__ = "0.0.9" class InactiveDueCreditCollector(object): """Just a stub at the Collector which would not do anything""" def _donothing(self, *args, **kwargs): """Perform no good and no bad""" pass def dcite(self, *args, **kwargs): """If I could cite I would""" def nondecorating_decorator(func): return func return nondecorating_decorator active = False activate = add = cite = dump = load = _donothing def __repr__(self): return self.__class__.__name__ + "()" def _donothing_func(*args, **kwargs): """Perform no good and no bad""" pass try: from duecredit import BibTeX, Doi, Text, Url, due # lgtm [py/unused-import] if "due" in locals() and not hasattr(due, "cite"): raise RuntimeError("Imported due lacks .cite. DueCredit is now disabled") except Exception as e: if not isinstance(e, ImportError): import logging logging.getLogger("duecredit").error("Failed to import duecredit due to %s" % str(e)) # Initiate due stub due = InactiveDueCreditCollector() BibTeX = Doi = Url = Text = _donothing_func # Emacs mode definitions # Local Variables: # mode: python # py-indent-offset: 4 # tab-width: 4 # indent-tabs-mode: nil # End: ================================================ FILE: src/openfe/orchestration/__init__.py ================================================ ================================================ FILE: src/openfe/protocols/__init__.py ================================================ # This code is part of OpenFE and is licensed under the MIT license. # For details, see https://github.com/OpenFreeEnergy/openfe ================================================ FILE: src/openfe/protocols/openmm_afe/__init__.py ================================================ # This code is part of OpenFE and is licensed under the MIT license. # For details, see https://github.com/OpenFreeEnergy/openfe """ Run absolute free energy calculations using OpenMM and OpenMMTools. """ from .abfe_units import ( ABFEComplexAnalysisUnit, ABFEComplexSetupUnit, ABFEComplexSimUnit, ABFESolventAnalysisUnit, ABFESolventSetupUnit, ABFESolventSimUnit, ) from .afe_protocol_results import ( AbsoluteBindingProtocolResult, AbsoluteSolvationProtocolResult, ) from .ahfe_units import ( AHFESolventAnalysisUnit, AHFESolventSetupUnit, AHFESolventSimUnit, AHFEVacuumAnalysisUnit, AHFEVacuumSetupUnit, AHFEVacuumSimUnit, ) from .equil_binding_afe_method import ( AbsoluteBindingProtocol, AbsoluteBindingSettings, ) from .equil_solvation_afe_method import ( AbsoluteSolvationProtocol, AbsoluteSolvationSettings, ) __all__ = [ "AbsoluteSolvationProtocol", "AbsoluteSolvationSettings", "AbsoluteSolvationProtocolResult", "AHFESolventSetupUnit", "AHFESolventSimUnit", "AHFESolventAnalysisUnit", "AHFEVacuumSetupUnit", "AHFEVacuumSimUnit", "AHFEVacuumAnalysisUnit", "AbsoluteBindingProtocol", "AbsoluteBindingSettings", "AbsoluteBindingProtocolResult", "ABFEComplexSetupUnit", "ABFEComplexSimUnit", "ABFEComplexAnalysisUnit", "ABFESolventSetupUnit", "ABFESolventSimUnit", "ABFESolventAnalysisUnit", ] ================================================ FILE: src/openfe/protocols/openmm_afe/abfe_units.py ================================================ # This code is part of OpenFE and is licensed under the MIT license. # For details, see https://github.com/OpenFreeEnergy/openfe """ABFE Protocol Units --- :mod:`openfe.protocols.openmm_afe.abfe_units` ======================================================================== This module defines the ProtocolUnits for the :class:`AbsoluteBindingProtocol`. """ import logging import pathlib from collections.abc import Iterable import MDAnalysis as mda import numpy as np import numpy.typing as npt from gufe import ( SolventComponent, ) from gufe.components import Component, SolvatedPDBComponent from openff.units import Quantity from openff.units.openmm import to_openmm from openmm import System from openmm import unit as ommunit from openmm.app import Topology as omm_topology from openmmtools.states import ThermodynamicState from rdkit import Chem from openfe.protocols.openmm_afe.equil_afe_settings import ( BoreschRestraintSettings, SettingsBaseModel, ) from openfe.protocols.openmm_utils import system_validation from openfe.protocols.restraint_utils import geometry from openfe.protocols.restraint_utils.geometry.boresch import BoreschRestraintGeometry from openfe.protocols.restraint_utils.openmm import omm_restraints from openfe.protocols.restraint_utils.openmm.omm_restraints import BoreschRestraint from .base_afe_units import ( BaseAbsoluteMultiStateAnalysisUnit, BaseAbsoluteMultiStateSimulationUnit, BaseAbsoluteSetupUnit, ) logger = logging.getLogger(__name__) class ComplexComponentsMixin: def _get_components(self): """ Get the relevant components for a complex transformation. Returns ------- alchem_comps : dict[str, Component] A dict of alchemical components solv_comp : SolventComponent The SolventComponent of the system prot_comp : ProteinComponent | None The protein component of the system, if it exists. small_mols : dict[SmallMoleculeComponent: OFFMolecule] SmallMoleculeComponents to add to the system. """ stateA = self._inputs["stateA"] alchem_comps = self._inputs["alchemical_components"] solv_comp, prot_comp, small_mols = system_validation.get_components(stateA) off_comps = {m: m.to_openff() for m in small_mols} # We don't need to check that solv_comp is not None, otherwise # an error will have been raised when calling `validate_solvent` # in the Protocol's `_create`. # Similarly we don't need to check prot_comp # If there is an SolvatedPDBComponent, we set the solv_comp # in the complex to the SolvatedPDBComponent, as the SolventComponent # is only used in the solvent leg if isinstance(prot_comp, SolvatedPDBComponent): solv_comp = prot_comp return alchem_comps, solv_comp, prot_comp, off_comps class ComplexSettingsMixin: def _get_settings(self) -> dict[str, SettingsBaseModel]: """ Extract the relevant settings for a complex transformation. Returns ------- settings : dict[str, SettingsBaseModel] A dictionary with the following entries: * forcefield_settings : OpenMMSystemGeneratorFFSettings * thermo_settings : ThermoSettings * charge_settings : OpenFFPartialChargeSettings * solvation_settings : OpenMMSolvationSettings * alchemical_settings : AlchemicalSettings * lambda_settings : LambdaSettings * engine_settings : OpenMMEngineSettings * integrator_settings : IntegratorSettings * equil_simulation_settings : MDSimulationSettings * equil_output_settings : ABFEPreEquilOutputSettings * simulation_settings : SimulationSettings * output_settings: MultiStateOutputSettings * restraint_settings: BaseRestraintSettings """ prot_settings = self._inputs["protocol"].settings # type: ignore[attr-defined] settings = {} settings["forcefield_settings"] = prot_settings.forcefield_settings settings["thermo_settings"] = prot_settings.thermo_settings settings["charge_settings"] = prot_settings.partial_charge_settings settings["solvation_settings"] = prot_settings.complex_solvation_settings settings["alchemical_settings"] = prot_settings.alchemical_settings settings["lambda_settings"] = prot_settings.complex_lambda_settings settings["engine_settings"] = prot_settings.engine_settings settings["integrator_settings"] = prot_settings.complex_integrator_settings settings["equil_simulation_settings"] = prot_settings.complex_equil_simulation_settings settings["equil_output_settings"] = prot_settings.complex_equil_output_settings settings["simulation_settings"] = prot_settings.complex_simulation_settings settings["output_settings"] = prot_settings.complex_output_settings settings["restraint_settings"] = prot_settings.restraint_settings return settings class ABFEComplexSetupUnit(ComplexComponentsMixin, ComplexSettingsMixin, BaseAbsoluteSetupUnit): """ Setup unit for the complex phase of absolute binding free energy transformations. """ simtype = "complex" @staticmethod def _get_mda_universe( topology: omm_topology, positions: ommunit.Quantity | None, trajectory: pathlib.Path | None, ) -> mda.Universe: """ Helper method to get a Universe from an openmm Topology, and either an input trajectory or a set of positions. Parameters ---------- topology : openmm.app.Topology An OpenMM Topology that defines the System. positions: openmm.unit.Quantity | None The System's current positions. Used if a trajectory file is None or is not a file. trajectory: pathlib.Path | None A Path to a trajectory file to read positions from. Returns ------- mda.Universe An MDAnalysis Universe of the System. """ from MDAnalysis.coordinates.memory import MemoryReader # If the trajectory file doesn't exist, then we use positions if trajectory is not None and trajectory.is_file(): return mda.Universe( topology, trajectory, topology_format="OPENMMTOPOLOGY", ) else: if positions is None: raise ValueError("No positions to create the Universe with") # Positions is an openmm Quantity in nm we need # to convert to angstroms return mda.Universe( topology, np.array(positions._value) * 10, topology_format="OPENMMTOPOLOGY", trajectory_format=MemoryReader, ) @staticmethod def _get_idxs_from_residxs( topology: omm_topology, residxs: Iterable[int], ) -> list[int]: """ Helper method to get the a list of atom indices which belong to a list of residues. Parameters ---------- topology : openmm.app.Topology An OpenMM Topology that defines the System. residxs : Iterable[int] A list of residue numbers who's atoms we should get atom indices. Returns ------- atom_ids : list[int] A list of atom indices. TODO ---- * Check how this works when we deal with virtual sites. """ atom_ids = [] for r in topology.residues(): if r.index in residxs: atom_ids.extend([at.index for at in r.atoms()]) return atom_ids @staticmethod def _get_boresch_restraint( universe: mda.Universe, guest_rdmol: Chem.Mol, guest_atom_ids: list[int], host_atom_ids: list[int], temperature: Quantity, settings: BoreschRestraintSettings, ) -> tuple[BoreschRestraintGeometry, BoreschRestraint]: """ Get a Boresch-like restraint Geometry and OpenMM restraint force supplier. Parameters ---------- universe : mda.Universe An MDAnalysis Universe defining the system to get the restraint for. guest_rdmol : Chem.Mol An RDKit Molecule defining the guest molecule in the system. guest_atom_ids: list[int] A list of atom indices defining the guest molecule in the universe. host_atom_ids : list[int] A list of atom indices defining the host molecules in the universe. temperature : openff.units.Quantity The temperature of the simulation where the restraint will be added. settings : BoreschRestraintSettings Settings on how the Boresch-like restraint should be defined. Returns ------- geom : BoreschRestraintGeometry A class defining the Boresch-like restraint. restraint : BoreschRestraint A factory class for generating Boresch restraints in OpenMM. """ # Take the minimum of the two possible force constants to check against frc_const = min(settings.K_thetaA, settings.K_thetaB) geom = geometry.boresch.find_boresch_restraint( universe=universe, guest_rdmol=guest_rdmol, guest_idxs=guest_atom_ids, host_idxs=host_atom_ids, host_selection=settings.host_selection, anchor_finding_strategy=settings.anchor_finding_strategy, dssp_filter=settings.dssp_filter, rmsf_cutoff=settings.rmsf_cutoff, host_min_distance=settings.host_min_distance, host_max_distance=settings.host_max_distance, angle_force_constant=frc_const, temperature=temperature, ) restraint = omm_restraints.BoreschRestraint(settings) return geom, restraint def _add_restraints( self, system: System, topology: omm_topology, positions: ommunit.Quantity, alchem_comps: dict[str, list[Component]], comp_resids: dict[Component, npt.NDArray], settings: dict[str, SettingsBaseModel], ) -> tuple[ Quantity, System, geometry.HostGuestRestraintGeometry, ]: """ Find and add restraints to the OpenMM System. Notes ----- Currently, only Boresch-like restraints are supported. Parameters ---------- system : openmm.System The System to add the restraint to. topology : openmm.app.Topology An OpenMM Topology that defines the System. positions: openmm.unit.Quantity The System's current positions. Used if a trajectory file isn't found. alchem_comps: dict[str, list[Component]] A dictionary with a list of alchemical components in both state A and B. comp_resids: dict[Component, npt.NDArray] A dictionary keyed by each Component in the System which contains arrays with the residue indices that is contained by that Component. settings : dict[str, SettingsBaseModel] A dictionary of settings that defines how to find and set the restraint. Returns ------- correction : openff.units.Quantity The standard state correction for the restraint. system : openmm.System A copy of the System with the restraint added. rest_geom : geometry.HostGuestRestraintGeometry The restraint Geometry object. """ if self.verbose: self.logger.info("Generating restraints") # Get the guest rdmol guest_rdmol = alchem_comps["stateA"][0].to_rdkit() # sanitize the rdmol if possible - warn if you can't err = Chem.SanitizeMol(guest_rdmol, catchErrors=True) if err: msg = "restraint generation: could not sanitize ligand rdmol" logger.warning(msg) # Get the guest idxs # concatenate a list of residue indexes for all alchemical components residxs = np.concatenate([comp_resids[key] for key in alchem_comps["stateA"]]) # get the alchemicical atom ids guest_atom_ids = self._get_idxs_from_residxs(topology, residxs) # Now get the host idxs # We assume this is everything but the alchemical component # and the solvent. solv_comps = [c for c in comp_resids if isinstance(c, SolventComponent)] exclude_comps = [alchem_comps["stateA"]] + solv_comps residxs = np.concatenate([v for i, v in comp_resids.items() if i not in exclude_comps]) host_atom_ids = self._get_idxs_from_residxs(topology, residxs) # Finally create an MDAnalysis Universe # We try to pass the equilibration production file path through # In some cases (debugging / dry runs) this won't be available # so we'll default to using input positions. univ = self._get_mda_universe( topology, positions, self.shared_basepath / settings["equil_output_settings"].production_trajectory_filename, ) if isinstance(settings["restraint_settings"], BoreschRestraintSettings): rest_geom, restraint = self._get_boresch_restraint( univ, guest_rdmol, guest_atom_ids, host_atom_ids, settings["thermo_settings"].temperature, settings["restraint_settings"], ) else: # TODO turn this into a direction for different restraint types supported? raise NotImplementedError("Other restraint types are not yet available") if self.verbose: self.logger.info(f"restraint geometry is: {rest_geom}") # We need a temporary thermodynamic state to add the restraint # & get the correction thermodynamic_state = ThermodynamicState( system, temperature=to_openmm(settings["thermo_settings"].temperature), pressure=to_openmm(settings["thermo_settings"].pressure), ) # Add the force to the thermodynamic state restraint.add_force( thermodynamic_state, rest_geom, controlling_parameter_name="lambda_restraints", ) # Get the standard state correction as a unit.Quantity correction = restraint.get_standard_state_correction( thermodynamic_state, rest_geom, ) return ( correction, # Remove the thermostat, otherwise you'll get an # Andersen thermostat by default! thermodynamic_state.get_system(remove_thermostat=True), rest_geom, ) class ABFEComplexSimUnit( ComplexComponentsMixin, ComplexSettingsMixin, BaseAbsoluteMultiStateSimulationUnit ): """ Multi-state simulation (e.g. multi replica methods like Hamiltonian replica exchange) unit for the complex phase of absolute binding free energy transformations. """ simtype = "complex" class ABFEComplexAnalysisUnit(ComplexSettingsMixin, BaseAbsoluteMultiStateAnalysisUnit): """ Analysis unit for multi-state simulations with the complex phase of absolute binding free energy transformations. """ simtype = "complex" class SolventComponentsMixin: def _get_components(self): """ Get the relevant components for a solvent transformation. Returns ------- alchem_comps : dict[str, Component] A list of alchemical components solv_comp : SolventComponent The SolventComponent of the system prot_comp : ProteinComponent | None The protein component of the system, if it exists. small_mols : dict[SmallMoleculeComponent: OFFMolecule] SmallMoleculeComponents to add to the system. """ stateA = self._inputs["stateA"] alchem_comps = self._inputs["alchemical_components"] solv_comp, prot_comp, small_mols = system_validation.get_components(stateA) off_comps = {m: m.to_openff() for m in alchem_comps["stateA"]} # We don't need to check that solv_comp is not None, otherwise # an error will have been raised when calling `validate_solvent` # in the Protocol's `_create`. # Similarly we don't need to check prot_comp just return None return alchem_comps, solv_comp, None, off_comps class SolventSettingsMixin: def _get_settings(self) -> dict[str, SettingsBaseModel]: """ Extract the relevant settings for a solvent transformation. Returns ------- settings : dict[str, SettingsBaseModel] A dictionary with the following entries: * forcefield_settings : OpenMMSystemGeneratorFFSettings * thermo_settings : ThermoSettings * charge_settings : OpenFFPartialChargeSettings * solvation_settings : OpenMMSolvationSettings * alchemical_settings : AlchemicalSettings * lambda_settings : LambdaSettings * engine_settings : OpenMMEngineSettings * integrator_settings : IntegratorSettings * equil_simulation_settings : MDSimulationSettings * equil_output_settings : ABFEPreEquilOutputSettings * simulation_settings : MultiStateSimulationSettings * output_settings: MultiStateOutputSettings """ prot_settings = self._inputs["protocol"].settings # type: ignore[attr-defined] settings = {} settings["forcefield_settings"] = prot_settings.forcefield_settings settings["thermo_settings"] = prot_settings.thermo_settings settings["charge_settings"] = prot_settings.partial_charge_settings settings["solvation_settings"] = prot_settings.solvent_solvation_settings settings["alchemical_settings"] = prot_settings.alchemical_settings settings["lambda_settings"] = prot_settings.solvent_lambda_settings settings["engine_settings"] = prot_settings.engine_settings settings["integrator_settings"] = prot_settings.solvent_integrator_settings settings["equil_simulation_settings"] = prot_settings.solvent_equil_simulation_settings settings["equil_output_settings"] = prot_settings.solvent_equil_output_settings settings["simulation_settings"] = prot_settings.solvent_simulation_settings settings["output_settings"] = prot_settings.solvent_output_settings return settings class ABFESolventSetupUnit(SolventComponentsMixin, SolventSettingsMixin, BaseAbsoluteSetupUnit): """ Setup unit for the solvent phase of absolute binding free energy transformations. """ simtype = "solvent" class ABFESolventSimUnit( SolventComponentsMixin, SolventSettingsMixin, BaseAbsoluteMultiStateSimulationUnit ): """ Multi-state simulation (e.g. multi replica methods like Hamiltonian replica exchange) unit for the solvent phase of absolute binding free energy transformations. """ simtype = "solvent" class ABFESolventAnalysisUnit(SolventSettingsMixin, BaseAbsoluteMultiStateAnalysisUnit): """ Analysis unit for multi-state simulations with the solvent phase of absolute binding free energy transformations. """ simtype = "solvent" ================================================ FILE: src/openfe/protocols/openmm_afe/afe_protocol_results.py ================================================ # This code is part of OpenFE and is licensed under the MIT license. # For details, see https://github.com/OpenFreeEnergy/openfe """ Result classes for the Absolute Free Energy Protocols ===================================================== This module implements :class:`gufe.ProtocolResult` classes for the absolute free energy Protocols. Specifically it implements: * AbsoluteBindingProtocolResult * AbsoluteSolvationProtocolResult """ import itertools import logging import pathlib import warnings from typing import Optional, Union import gufe import numpy as np import numpy.typing as npt from openff.units import Quantity from openff.units import unit as offunit from openmmtools import multistate from openfe.protocols.restraint_utils.geometry.boresch import BoreschRestraintGeometry logger = logging.getLogger(__name__) class AbsoluteProtocolResultMixin: bound_state = "solvent" unbound_state = "vacuum" def __init__(self, **data): super().__init__(**data) # TODO: Detect when we have extensions and stitch these together? if any( len(pur_list) > 2 for pur_list in itertools.chain( self.data[self.bound_state].values(), self.data[self.unbound_state].values() ) ): raise NotImplementedError("Can't stitch together results yet") def get_forward_and_reverse_energy_analysis( self, ) -> dict[str, list[Optional[dict[str, Union[npt.NDArray, Quantity]]]]]: """ Get the reverse and forward analysis of the free energies. Returns ------- forward_reverse : dict[str, list[Optional[dict[str, Union[npt.NDArray, openff.units.Quantity]]]]] A dictionary, keyed for each leg of the thermodynamic cycle, either ``solvent`` and ``vacuum` for a solvation free energy or ``solvent`` and ``complex`` for a binding free energy, with each containing a list of dictionaries containing the forward and reverse analysis of each repeat of that simulation type. The forward and reverse analysis dictionaries contain: - `fractions`: npt.NDArray The fractions of data used for the estimates - `forward_DGs`, `reverse_DGs`: openff.units.Quantity The forward and reverse estimates for each fraction of data - `forward_dDGs`, `reverse_dDGs`: openff.units.Quantity The forward and reverse estimate uncertainty for each fraction of data. If one of the cycle leg list entries is ``None``, this indicates that the analysis could not be carried out for that repeat. This is most likely caused by MBAR convergence issues when attempting to calculate free energies from too few samples. Raises ------ UserWarning * If any of the forward and reverse dictionaries are ``None`` in a given thermodynamic cycle leg. """ forward_reverse: dict[str, list[Optional[dict[str, Union[npt.NDArray, Quantity]]]]] = {} for key in [self.bound_state, self.unbound_state]: forward_reverse[key] = [ pus[0].outputs["forward_and_reverse_energies"] for pus in self.data[key].values() # type: ignore[attr-defined] ] if None in forward_reverse[key]: wmsg = ( "One or more ``None`` entries were found in the forward " f"and reverse dictionaries of the repeats of the {key} " "calculations. This is likely caused by an MBAR convergence " "failure caused by too few independent samples when " "calculating the free energies of the 10% timeseries slice." ) warnings.warn(wmsg) return forward_reverse def get_overlap_matrices(self) -> dict[str, list[dict[str, npt.NDArray]]]: """ Get a the MBAR overlap estimates for all legs of the simulation. Returns ------- overlap_stats : dict[str, list[dict[str, npt.NDArray]]] A dictionary keyed for each leg of the thermodynamic cycle, either ``solvent`` and ``vacuum` for a solvation free energy or ``solvent`` and ``complex`` for a binding free energy, with each containing a list of dictionaries with the MBAR overlap estimates of each repeat of that simulation type. The underlying MBAR dictionaries contain the following keys: * ``scalar``: One minus the largest nontrivial eigenvalue * ``eigenvalues``: The sorted (descending) eigenvalues of the overlap matrix * ``matrix``: Estimated overlap matrix of observing a sample from state i in state j """ # Loop through and get the repeats and get the matrices overlap_stats: dict[str, list[dict[str, npt.NDArray]]] = {} for key in [self.bound_state, self.unbound_state]: overlap_stats[key] = [ pus[0].outputs["unit_mbar_overlap"] for pus in self.data[key].values() # type: ignore[attr-defined] ] return overlap_stats def get_replica_transition_statistics(self) -> dict[str, list[dict[str, npt.NDArray]]]: """ Get the replica exchange transition statistics for all legs of the simulation. Note ---- This is currently only available in cases where a replica exchange simulation was run. Returns ------- repex_stats : dict[str, list[dict[str, npt.NDArray]]] A dictionary with keys for each leg of the thermodynamic cycle, either ``solvent`` and ``vacuum` for a solvation free energy or ``solvent`` and ``complex`` for a binding free energy, with each containing a list of dictionaries containing the replica transition statistics for each repeat of that simulation type. The replica transition statistics dictionaries contain the following: * ``eigenvalues``: The sorted (descending) eigenvalues of the lambda state transition matrix * ``matrix``: The transition matrix estimate of a replica switching from state i to state j. """ repex_stats: dict[str, list[dict[str, npt.NDArray]]] = {} try: for key in [self.bound_state, self.unbound_state]: repex_stats[key] = [ pus[0].outputs["replica_exchange_statistics"] for pus in self.data[key].values() # type: ignore[attr-defined] ] except KeyError: errmsg = "Replica exchange statistics were not found, did you run a repex calculation?" raise ValueError(errmsg) return repex_stats def get_replica_states(self) -> dict[str, list[npt.NDArray]]: """ Get the timeseries of replica states for all simulation legs. Returns ------- replica_states : dict[str, list[npt.NDArray]] Dictionary keyed for each leg of the thermodynamic cycle, either `solvent` and `vacuum` for solvation free energies, or `complex` and `solvent` for binding free energies, with lists of replica states timeseries for each repeat of that simulation type. """ replica_states: dict[str, list[npt.NDArray]] = { self.bound_state: [], self.unbound_state: [], } def is_file(filename: str): p = pathlib.Path(filename) if not p.exists(): errmsg = f"File could not be found {p}" raise ValueError(errmsg) return p def get_replica_state(nc, chk): nc = is_file(nc) dir_path = nc.parents[0] chk = is_file(dir_path / chk).name reporter = multistate.MultiStateReporter( storage=nc, checkpoint_storage=chk, open_mode="r" ) retval = np.asarray(reporter.read_replica_thermodynamic_states()) reporter.close() return retval for key in [self.bound_state, self.unbound_state]: for pus in self.data[key].values(): # type: ignore[attr-defined] states = get_replica_state( pus[0].outputs["trajectory"], pus[0].outputs["checkpoint"], ) replica_states[key].append(states) return replica_states def equilibration_iterations(self) -> dict[str, list[float]]: """ Get the number of equilibration iterations for each simulation. Returns ------- equilibration_lengths : dict[str, list[float]] Dictionary keyed for each leg of the thermodynamic cycle, either `solvent` and `vacuum` for solvation free energies, or `complex` and `solvent` for binding free energies, with lists containing the number of equilibration iterations for each repeat of that simulation type. """ equilibration_lengths: dict[str, list[float]] = {} for key in [self.bound_state, self.unbound_state]: equilibration_lengths[key] = [ pus[0].outputs["equilibration_iterations"] for pus in self.data[key].values() # type: ignore[attr-defined] ] return equilibration_lengths def production_iterations(self) -> dict[str, list[float]]: """ Get the number of production iterations for each simulation. Returns the number of uncorrelated production samples for each repeat of the calculation. Returns ------- production_lengths : dict[str, list[float]] Dictionary keyed for each leg of the thermodynamic cycle, either `solvent` and `vacuum` for solvation free energies, or `complex` and `solvent` for binding free energies, with lists containing the number of equilibration iterations for each repeat of that simulation type. """ production_lengths: dict[str, list[float]] = {} for key in [self.bound_state, self.unbound_state]: production_lengths[key] = [ pus[0].outputs["production_iterations"] for pus in self.data[key].values() # type: ignore[attr-defined] ] return production_lengths def selection_indices(self) -> dict[str, list[Optional[npt.NDArray]]]: """ Get the system selection indices used to write PDB and trajectory files. Returns ------- indices : dict[str, list[npt.NDArray]] A dictionary keyed for each state, either `solvent` and `vacuum` for solvation free energies, or `complex` and `solvent` for binding free energies, each containing a list of NDArrays containing the corresponding full system atom indices for each atom written in the production trajectory files for each replica. """ indices: dict[str, list[Optional[npt.NDArray]]] = {} for key in [self.bound_state, self.unbound_state]: indices[key] = [] for pus in self.data[key].values(): # type: ignore[attr-defined] indices[key].append(pus[0].outputs["selection_indices"]) return indices class AbsoluteSolvationProtocolResult(gufe.ProtocolResult, AbsoluteProtocolResultMixin): """ Protocol results with the output of a AbsoluteSolvationProtocol """ bound_state = "solvent" unbound_state = "vacuum" def get_individual_estimates(self) -> dict[str, list[tuple[Quantity, Quantity]]]: """ Get the individual estimate of the free energies. Returns ------- dGs : dict[str, list[tuple[openff.units.Quantity, openff.units.Quantity]]] A dictionary, keyed `solvent` and `vacuum` for each leg of the thermodynamic cycle, with lists of tuples containing the individual free energy estimates and associated MBAR uncertainties for each repeat of that simulation type. """ dGs = {} for state in [self.bound_state, self.unbound_state]: state_dGs = [ (pus[0].outputs["unit_estimate"], pus[0].outputs["unit_estimate_error"]) for pus in self.data[state].values() ] dGs[state] = state_dGs return dGs def get_estimate(self): """Get the solvation free energy estimate for this calculation. Returns ------- dG : openff.units.Quantity The solvation free energy. This is a Quantity defined with units. """ def _get_average(estimates): # Get the unit value of the first value in the estimates u = estimates[0][0].u # Loop through estimates and get the free energy values # in the unit of the first estimate dGs = [i[0].to(u).m for i in estimates] return np.average(dGs) * u individual_estimates = self.get_individual_estimates() vac_dG = _get_average(individual_estimates["vacuum"]) solv_dG = _get_average(individual_estimates["solvent"]) return vac_dG - solv_dG def get_uncertainty(self): """Get the solvation free energy error for this calculation. Returns ------- err : openff.units.Quantity The standard deviation between estimates of the solvation free energy. This is a Quantity defined with units. """ def _get_stdev(estimates): # Get the unit value of the first value in the estimates u = estimates[0][0].u # Loop through estimates and get the free energy values # in the unit of the first estimate dGs = [i[0].to(u).m for i in estimates] return np.std(dGs) * u individual_estimates = self.get_individual_estimates() vac_err = _get_stdev(individual_estimates["vacuum"]) solv_err = _get_stdev(individual_estimates["solvent"]) # return the combined error return np.sqrt(vac_err**2 + solv_err**2) class AbsoluteBindingProtocolResult(gufe.ProtocolResult, AbsoluteProtocolResultMixin): """ Protocol results with the output of a AbsoluteBindingProtocol. """ bound_state = "complex" unbound_state = "solvent" def get_individual_estimates( self, ) -> dict[str, list[tuple[Quantity, Quantity]]]: """ Get the individual estimate of the free energies. Returns ------- dGs : dict[str, list[tuple[openff.units.Quantity, openff.units.Quantity]]] A dictionary, keyed `solvent`, `complex`, and 'standard_state' representing each portion of the thermodynamic cycle, with lists of tuples containing the individual free energy estimates and, for 'solvent' and 'complex', the associated MBAR uncertainties for each repeat of that simulation type. Notes ----- * Standard state correction has no error and so will return a value of 0. """ complex_dGs = [] correction_dGs = [] solv_dGs = [] for pus in self.data["complex"].values(): complex_dGs.append( (pus[0].outputs["unit_estimate"], pus[0].outputs["unit_estimate_error"]) ) correction_dGs.append( ( pus[0].outputs["standard_state_correction"], 0 * offunit.kilocalorie_per_mole, # correction has no error ) ) for pus in self.data["solvent"].values(): solv_dGs.append( (pus[0].outputs["unit_estimate"], pus[0].outputs["unit_estimate_error"]) ) return { "solvent": solv_dGs, "complex": complex_dGs, "standard_state_correction": correction_dGs, } @staticmethod def _add_complex_standard_state_corr( complex_dG: list[tuple[Quantity, Quantity]], standard_state_dG: list[tuple[Quantity, Quantity]], ) -> list[tuple[Quantity, Quantity]]: """ Helper method to combine the complex & standard state corrections legs. Parameters ---------- complex_dG : list[tuple[openff.units.Quantity, openff.units.Quantity]] The individual estimates of the complex leg, where the first entry of each tuple is the dG estimate and the second entry is the MBAR error. standard_state_dG : list[tuple[Quantity, Quantity]] The individual standard state corrections for each corresponding complex leg. The first entry is the correction, the second is an empty error value of 0. Returns ------- combined_dG : list[tuple[openff.units.Quantity,openff.units. Quantity]] A list of dG estimates & MBAR errors for the combined complex & standard state correction of each repeat. Notes ----- We assume that both list of items are in the right order. """ combined_dG: list[tuple[Quantity, Quantity]] = [] for comp, corr in zip(complex_dG, standard_state_dG): # No need to convert unit types, since pint takes care of that # except that mypy hates it because pint isn't typed properly... # No need to add errors since there's just the one combined_dG.append((comp[0] + corr[0], comp[1])) # type: ignore[operator] return combined_dG def get_estimate(self) -> Quantity: """Get the binding free energy estimate for this calculation. Returns ------- dG : openff.units.Quantity The binding free energy. This is a Quantity defined with units. """ def _get_average(estimates): # Get the unit value of the first value in the estimates u = estimates[0][0].u # Loop through estimates and get the free energy values # in the unit of the first estimate dGs = [i[0].to(u).m for i in estimates] return np.average(dGs) * u individual_estimates = self.get_individual_estimates() complex_dG = _get_average( self._add_complex_standard_state_corr( individual_estimates["complex"], individual_estimates["standard_state_correction"], ) ) solv_dG = _get_average(individual_estimates["solvent"]) return -complex_dG + solv_dG def get_uncertainty(self) -> Quantity: """Get the binding free energy error for this calculation. Returns ------- err : openff.units.Quantity The standard deviation between estimates of the binding free energy. This is a Quantity defined with units. """ def _get_stdev(estimates): # Get the unit value of the first value in the estimates u = estimates[0][0].u # Loop through estimates and get the free energy values # in the unit of the first estimate dGs = [i[0].to(u).m for i in estimates] return np.std(dGs) * u individual_estimates = self.get_individual_estimates() complex_err = _get_stdev( self._add_complex_standard_state_corr( individual_estimates["complex"], individual_estimates["standard_state_correction"], ) ) solv_err = _get_stdev(individual_estimates["solvent"]) # return the combined error return np.sqrt(complex_err**2 + solv_err**2) def restraint_geometries(self) -> list[BoreschRestraintGeometry]: """ Get a list of the restraint geometries for the complex simulations. These define the atoms that have been restrained in the system. Returns ------- geometries : list[dict[str, Any]] A list of dictionaries containing the details of the atoms in the system that are involved in the restraint. """ geometries = [ BoreschRestraintGeometry.model_validate(pus[0].outputs["restraint_geometry"]) for pus in self.data["complex"].values() ] return geometries ================================================ FILE: src/openfe/protocols/openmm_afe/ahfe_units.py ================================================ # This code is part of OpenFE and is licensed under the MIT license. # For details, see https://github.com/OpenFreeEnergy/openfe """ AHFE Protocol Units --- :mod:`openfe.protocols.openmm_afe.ahfe_units` ===================================================================== This module defines the ProtocolUnits for the :class:`AbsoluteSolvationProtocol`. """ import logging from openfe.protocols.openmm_afe.equil_afe_settings import ( SettingsBaseModel, ) from ..openmm_utils import system_validation from .base_afe_units import ( BaseAbsoluteMultiStateAnalysisUnit, BaseAbsoluteMultiStateSimulationUnit, BaseAbsoluteSetupUnit, ) logger = logging.getLogger(__name__) class VacuumComponentsMixin: def _get_components(self): """ Get the relevant components for a vacuum transformation. Returns ------- alchem_comps : dict[str, list[Component]] A list of alchemical components solv_comp : None For the gas phase transformation, None will always be returned for the solvent component of the chemical system. prot_comp : Optional[ProteinComponent] The protein component of the system, if it exists. small_mols : dict[Component, OpenFF Molecule] The openff Molecules to add to the system. This is equivalent to the alchemical components in stateA (since we only allow for disappearing ligands). """ stateA = self._inputs["stateA"] alchem_comps = self._inputs["alchemical_components"] off_comps = {m: m.to_openff() for m in alchem_comps["stateA"]} _, prot_comp, _ = system_validation.get_components(stateA) # Notes: # 1. Our input state will contain a solvent, we ``None`` that out # since this is the gas phase unit. # 2. Our small molecules will always just be the alchemical components # (of stateA since we enforce only one disappearing ligand) return alchem_comps, None, prot_comp, off_comps class VacuumSettingsMixin: def _get_settings(self) -> dict[str, SettingsBaseModel]: """ Extract the relevant settings for a vacuum transformation. Returns ------- settings : dict[str, SettingsBaseModel] A dictionary with the following entries: * forcefield_settings : OpenMMSystemGeneratorFFSettings * thermo_settings : ThermoSettings * charge_settings : OpenFFPartialChargeSettings * solvation_settings : OpenMMSolvationSettings * alchemical_settings : AlchemicalSettings * lambda_settings : LambdaSettings * engine_settings : OpenMMEngineSettings * integrator_settings : IntegratorSettings * equil_simulation_settings : MDSimulationSettings * equil_output_settings : MDOutputSettings * simulation_settings : SimulationSettings * output_settings: MultiStateOutputSettings """ prot_settings = self._inputs["protocol"].settings # type: ignore[attr-defined] settings = {} settings["forcefield_settings"] = prot_settings.vacuum_forcefield_settings settings["thermo_settings"] = prot_settings.thermo_settings settings["charge_settings"] = prot_settings.partial_charge_settings settings["solvation_settings"] = prot_settings.solvation_settings settings["alchemical_settings"] = prot_settings.alchemical_settings settings["lambda_settings"] = prot_settings.lambda_settings settings["engine_settings"] = prot_settings.vacuum_engine_settings settings["integrator_settings"] = prot_settings.integrator_settings settings["equil_simulation_settings"] = prot_settings.vacuum_equil_simulation_settings settings["equil_output_settings"] = prot_settings.vacuum_equil_output_settings settings["simulation_settings"] = prot_settings.vacuum_simulation_settings settings["output_settings"] = prot_settings.vacuum_output_settings return settings class AHFEVacuumSetupUnit(VacuumComponentsMixin, VacuumSettingsMixin, BaseAbsoluteSetupUnit): """ Setup unit for the vacuum phase of absolute hydration free energy transformations. """ simtype = "vacuum" class AHFEVacuumSimUnit( VacuumComponentsMixin, VacuumSettingsMixin, BaseAbsoluteMultiStateSimulationUnit ): """ Multi-state simulation (e.g. multi replica methods like Hamiltonian replica exchange) unit for the vacuum phase of absolute hydration free energy transformations. """ simtype = "vacuum" class AHFEVacuumAnalysisUnit(VacuumSettingsMixin, BaseAbsoluteMultiStateAnalysisUnit): """ Analysis unit for multi-state simulations with the vacuum phase of absolute hydration free energy transformations. """ simtype = "vacuum" class SolventComponentsMixin: def _get_components(self): """ Get the relevant components for a solvent transformation. Returns ------- alchem_comps : dict[str, Component] A list of alchemical components solv_comp : SolventComponent The SolventComponent of the system prot_comp : Optional[ProteinComponent] The protein component of the system, if it exists. small_mols : dict[SmallMoleculeComponent: OFFMolecule] SmallMoleculeComponents to add to the system. """ stateA = self._inputs["stateA"] alchem_comps = self._inputs["alchemical_components"] solv_comp, prot_comp, small_mols = system_validation.get_components(stateA) off_comps = {m: m.to_openff() for m in small_mols} # We don't need to check that solv_comp is not None, otherwise # an error will have been raised when calling `validate_solvent` # in the Protocol's `_create`. # Similarly we don't need to check prot_comp since that's also # disallowed on create return alchem_comps, solv_comp, prot_comp, off_comps class SolventSettingsMixin: def _get_settings(self) -> dict[str, SettingsBaseModel]: """ Extract the relevant settings for a solvent transformation. Returns ------- settings : dict[str, SettingsBaseModel] A dictionary with the following entries: * forcefield_settings : OpenMMSystemGeneratorFFSettings * thermo_settings : ThermoSettings * charge_settings : OpenFFPartialChargeSettings * solvation_settings : OpenMMSolvationSettings * alchemical_settings : AlchemicalSettings * lambda_settings : LambdaSettings * engine_settings : OpenMMEngineSettings * integrator_settings : IntegratorSettings * equil_simulation_settings : MDSimulationSettings * equil_output_settings : MDOutputSettings * simulation_settings : MultiStateSimulationSettings * output_settings: MultiStateOutputSettings """ prot_settings = self._inputs["protocol"].settings # type: ignore[attr-defined] settings = {} settings["forcefield_settings"] = prot_settings.solvent_forcefield_settings settings["thermo_settings"] = prot_settings.thermo_settings settings["charge_settings"] = prot_settings.partial_charge_settings settings["solvation_settings"] = prot_settings.solvation_settings settings["alchemical_settings"] = prot_settings.alchemical_settings settings["lambda_settings"] = prot_settings.lambda_settings settings["engine_settings"] = prot_settings.solvent_engine_settings settings["integrator_settings"] = prot_settings.integrator_settings settings["equil_simulation_settings"] = prot_settings.solvent_equil_simulation_settings settings["equil_output_settings"] = prot_settings.solvent_equil_output_settings settings["simulation_settings"] = prot_settings.solvent_simulation_settings settings["output_settings"] = prot_settings.solvent_output_settings return settings class AHFESolventSetupUnit(SolventComponentsMixin, SolventSettingsMixin, BaseAbsoluteSetupUnit): """ Setup unit for the solvent phase of absolute hydration free energy transformations. """ simtype = "solvent" class AHFESolventSimUnit( SolventComponentsMixin, SolventSettingsMixin, BaseAbsoluteMultiStateSimulationUnit ): """ Multi-state simulation (e.g. multi replica methods like Hamiltonian replica exchange) unit for the solvent phase of absolute hydration free energy transformations. """ simtype = "solvent" class AHFESolventAnalysisUnit(SolventSettingsMixin, BaseAbsoluteMultiStateAnalysisUnit): """ Analysis unit for multi-state simulations with the solvent phase of absolute hydration free energy transformations. """ simtype = "solvent" ================================================ FILE: src/openfe/protocols/openmm_afe/base_afe_units.py ================================================ # This code is part of OpenFE and is licensed under the MIT license. # For details, see https://github.com/OpenFreeEnergy/openfe """OpenMM AFE Protocol base classes =================================== Base classes for the OpenMM absolute free energy ProtocolUnits. This mostly implements BaseAbsoluteUnit whose methods can be overridden to define different types of alchemical transformations. TODO ---- * Add in all the AlchemicalFactory and AlchemicalRegion kwargs as settings. * Allow for a more flexible setting of Lambda regions. """ import abc import copy import logging import os import pathlib from typing import Any import gufe import numpy as np import numpy.typing as npt import openmm import openmmtools from gufe import ( BaseSolventComponent, ProteinComponent, SmallMoleculeComponent, SolventComponent, ) from gufe.components import Component from gufe.protocols.errors import ProtocolUnitExecutionError from openff.toolkit.topology import Molecule as OFFMolecule from openff.units import Quantity from openff.units import unit as offunit from openff.units.openmm import ensure_quantity, from_openmm, to_openmm from openmm import app from openmm import unit as ommunit from openmmforcefields.generators import SystemGenerator from openmmtools import multistate from openmmtools.alchemy import ( AbsoluteAlchemicalFactory, AlchemicalRegion, AlchemicalState, ) from openmmtools.states import ( GlobalParameterState, SamplerState, ThermodynamicState, create_thermodynamic_state_protocol, ) import openfe from openfe.protocols.openmm_afe.equil_afe_settings import ( AlchemicalSettings, BaseSolvationSettings, IntegratorSettings, MultiStateOutputSettings, MultiStateSimulationSettings, OpenFFPartialChargeSettings, ThermoSettings, ) from openfe.protocols.openmm_md.plain_md_methods import PlainMDSimulationUnit from openfe.protocols.openmm_utils import ( charge_generation, multistate_analysis, omm_compute, settings_validation, system_creation, system_validation, ) from openfe.protocols.openmm_utils.mdtraj_utils import ( mdtraj_from_openmm, ) from openfe.protocols.openmm_utils.omm_settings import ( SettingsBaseModel, ) from openfe.protocols.openmm_utils.serialization import ( deserialize, make_vec3_box, serialize, ) from openfe.protocols.restraint_utils import geometry from openfe.protocols.restraint_utils.openmm import omm_restraints from openfe.utils import log_system_probe, without_oechem_backend logger = logging.getLogger(__name__) class AbsoluteUnitMixin: def _prepare( self, verbose: bool, scratch_basepath: pathlib.Path | None, shared_basepath: pathlib.Path | None, ): """ Set basepaths and do some initial logging. Parameters ---------- verbose : bool Verbose output of the simulation progress. Output is provided via INFO level logging. scratch_basepath : pathlib.Path | None Optional base path to write scratch files to. shared_basepath : pathlib.Path | None Optional base path to write shared files to. """ self.verbose = verbose # set basepaths def _set_optional_path(basepath): if basepath is None: return pathlib.Path(".") return basepath self.scratch_basepath = _set_optional_path(scratch_basepath) self.shared_basepath = _set_optional_path(shared_basepath) @abc.abstractmethod def _get_settings(self) -> dict[str, SettingsBaseModel]: """ Get a dictionary with the following entries: * forcefield_settings : OpenMMSystemGeneratorFFSettings * thermo_settings : ThermoSettings * solvation_settings : BaseSolvationSettings * alchemical_settings : AlchemicalSettings * lambda_settings : LambdaSettings * engine_settings : OpenMMEngineSettings * integrator_settings : IntegratorSettings * equil_simulation_settings : MDSimulationSettings * equil_output_settings : MDOutputSettings * simulation_settings : MultiStateSimulationSettings * output_settings : MultiStateOutputSettings Settings may change depending on what type of simulation you are running. Cherry pick them and return them to be available later on. This method should also add various validation checks as necessary. Note ---- Must be implemented in the child class. """ ... @staticmethod def _verify_execution_environment( setup_outputs: dict[str, Any], ) -> None: """ Check that the Python environment hasn't changed based on the relevant Python library versions stored in the setup outputs. """ try: if ( (gufe.__version__ != setup_outputs["gufe_version"]) or (openfe.__version__ != setup_outputs["openfe_version"]) or (openmm.__version__ != setup_outputs["openmm_version"]) ): errmsg = "Python environment has changed, cannot continue Protocol execution." raise ProtocolUnitExecutionError(errmsg) except KeyError: errmsg = "Missing environment information from setup outputs." raise ProtocolUnitExecutionError(errmsg) class BaseAbsoluteSetupUnit(gufe.ProtocolUnit, AbsoluteUnitMixin): """ Base class for setting up an absolute free energy transformations. """ @abc.abstractmethod def _get_components( self, ) -> tuple[ dict[str, list[Component]], gufe.SolventComponent | None, gufe.ProteinComponent | None, dict[SmallMoleculeComponent, OFFMolecule], ]: """ Get the relevant components to create the alchemical system with. Note ---- Must be implemented in the child class. """ ... @staticmethod def _get_alchemical_indices( omm_top: openmm.app.Topology, comp_resids: dict[Component, npt.NDArray], alchem_comps: dict[str, list[Component]], ) -> list[int]: """ Get a list of atom indices for all the alchemical species Parameters ---------- omm_top : openmm.Topology Topology of OpenMM System. comp_resids : dict[Component, npt.NDArray] A dictionary of residues for each component in the System. alchem_comps : dict[str, list[Component]] A dictionary of alchemical components for each end state. Return ------ atom_ids : list[int] A list of atom indices for the alchemical species """ # concatenate a list of residue indexes for all alchemical components residxs = np.concatenate([comp_resids[key] for key in alchem_comps["stateA"]]) # get the alchemicical atom ids atom_ids = [] for r in omm_top.residues(): if r.index in residxs: atom_ids.extend([at.index for at in r.atoms()]) return atom_ids def _pre_equilibrate( self, system: openmm.System, topology: openmm.app.Topology, positions: ommunit.Quantity, settings: dict[str, SettingsBaseModel], dry: bool, ) -> tuple[ommunit.Quantity, ommunit.Quantity]: """ Run a non-alchemical equilibration to get a stable system. Parameters ---------- system : openmm.System The OpenMM System to equilibrate. topology : openmm.app.Topology OpenMM Topology of the System. positions : openmm.unit.Quantity Initial positions for the system. settings : dict[str, SettingsBaseModel] A dictionary of settings objects. Expects the following entries: * `forcefield_settings` * `engine_settings` * `thermo_settings` * `integrator_settings` * `equil_simulation_settings` * `equil_output_settings` dry: bool Whether or not this is a dry run. Returns ------- equilibrated_positions : npt.NDArray Equilibrated system positions box : openmm.unit.Quantity Box vectors of the equilibrated system. """ # Prep the simulation object # Restrict CPU count if running vacuum simulation restrict_cpu = settings["forcefield_settings"].nonbonded_method.lower() == "nocutoff" platform = omm_compute.get_openmm_platform( platform_name=settings["engine_settings"].compute_platform, gpu_device_index=settings["engine_settings"].gpu_device_index, restrict_cpu_count=restrict_cpu, ) integrator = openmm.LangevinMiddleIntegrator( to_openmm(settings["thermo_settings"].temperature), to_openmm(settings["integrator_settings"].langevin_collision_rate), to_openmm(settings["integrator_settings"].timestep), ) simulation = openmm.app.Simulation( topology=topology, system=system, integrator=integrator, platform=platform, ) # Get the necessary number of steps if settings["equil_simulation_settings"].equilibration_length_nvt is not None: equil_steps_nvt = settings_validation.get_simsteps( sim_length=settings["equil_simulation_settings"].equilibration_length_nvt, timestep=settings["integrator_settings"].timestep, mc_steps=1, ) else: equil_steps_nvt = None equil_steps_npt = settings_validation.get_simsteps( sim_length=settings["equil_simulation_settings"].equilibration_length, timestep=settings["integrator_settings"].timestep, mc_steps=1, ) prod_steps_npt = settings_validation.get_simsteps( sim_length=settings["equil_simulation_settings"].production_length, timestep=settings["integrator_settings"].timestep, mc_steps=1, ) if self.verbose: self.logger.info("running non-alchemical equilibration MD") # Don't do anything if we're doing a dry run if dry: box = system.getDefaultPeriodicBoxVectors() return positions, to_openmm(from_openmm(box)) # Use the _run_MD method from the PlainMDSimulationUnit # Should in-place modify the simulation PlainMDSimulationUnit._run_MD( simulation=simulation, positions=positions, simulation_settings=settings["equil_simulation_settings"], output_settings=settings["equil_output_settings"], temperature=settings["thermo_settings"].temperature, barostat_frequency=settings["integrator_settings"].barostat_frequency, timestep=settings["integrator_settings"].timestep, equil_steps_nvt=equil_steps_nvt, equil_steps_npt=equil_steps_npt, prod_steps=prod_steps_npt, verbose=self.verbose, shared_basepath=self.shared_basepath, ) # TODO: if we still see crashes, see if using enforcePeriodicBox is necessary # on newer tests, these were not necessary. state = simulation.context.getState(getPositions=True) equilibrated_positions = state.getPositions(asNumpy=True) box = state.getPeriodicBoxVectors() # cautiously delete out contexts & integrator del simulation.context, integrator return equilibrated_positions, to_openmm(from_openmm(box)) @staticmethod def _assign_partial_charges( partial_charge_settings: OpenFFPartialChargeSettings, small_mols: dict[SmallMoleculeComponent, OFFMolecule], ) -> None: """ Assign partial charges to the OpenFF Molecules associated with all the SmallMoleculeComponents in the transformation. Parameters ---------- charge_settings : OpenFFPartialChargeSettings Settings for controlling how the partial charges are assigned. small_mols : dict[SmallMoleculeComponent, openff.toolkit.Molecule] Dictionary of OpenFF Molecules to add, keyed by their associated SmallMoleculeComponent. """ for mol in small_mols.values(): charge_generation.assign_offmol_partial_charges( offmol=mol, overwrite=False, method=partial_charge_settings.partial_charge_method, toolkit_backend=partial_charge_settings.off_toolkit_backend, generate_n_conformers=partial_charge_settings.number_of_conformers, nagl_model=partial_charge_settings.nagl_model, ) @staticmethod def _get_system_generator( settings: dict[str, SettingsBaseModel], solvent_component: BaseSolventComponent | None, openff_molecules: list[OFFMolecule], ffcache: pathlib.Path | None, ) -> SystemGenerator: """ Get a system generator through the system creation utilities Parameters ---------- settings : dict[str, SettingsBaseModel] A dictionary of settings object for the unit. solvent_comp : BaseSolventComponent | None The solvent component of this system, if there is one. openff_molecules : list[openff.toolkit.Molecule] | None A list of OpenFF Molecules to generate templates for, if any. ffcache : pathlib.Path | None Path to the force field parameter cache. Returns ------- system_generator : openmmforcefields.generator.SystemGenerator System Generator to parameterise this unit. """ system_generator = system_creation.get_system_generator( forcefield_settings=settings["forcefield_settings"], integrator_settings=settings["integrator_settings"], thermo_settings=settings["thermo_settings"], cache=ffcache, has_solvent=solvent_component is not None, ) # Handle openff Molecule templates # TODO: revisit this once the SystemGenerator update happens if openff_molecules is None: return system_generator # Register all the templates, pass unique molecules to avoid clashes system_generator.add_molecules(list(set(openff_molecules))) return system_generator @staticmethod def _get_modeller( protein_component: ProteinComponent | None, solvent_component: BaseSolventComponent | None, small_mols: dict[SmallMoleculeComponent, OFFMolecule], system_generator: SystemGenerator, solvation_settings: BaseSolvationSettings, ) -> tuple[app.Modeller, dict[Component, npt.NDArray]]: """ Get an OpenMM Modeller object and a list of residue indices for each component in the system. Parameters ---------- protein_component : ProteinComponent | None Protein Component, if it exists. solvent_component : BaseSolventComponent | None The solvent component, if it exists. small_mols : dict[SmallMoleculeComponent, openff.toolkit.Molecule] Dictionary of OpenFF Molecules to add, keyed by SmallMoleculeComponent. system_generator : openmmforcefields.generator.SystemGenerator System Generator to parameterise this unit. solvation_settings : BaseSolvationSettings Settings detailing how to solvate the system. Returns ------- system_modeller : app.Modeller OpenMM Modeller object generated from ProteinComponent and OpenFF Molecules. comp_resids : dict[Component, npt.NDArray] Dictionary of residue indices for each component in system. """ # get OpenMM modeller + dictionary of resids for each component system_modeller, comp_resids = system_creation.get_omm_modeller( protein_comp=protein_component, solvent_comp=solvent_component, small_mols=small_mols, omm_forcefield=system_generator.forcefield, solvent_settings=solvation_settings, ) return system_modeller, comp_resids def _get_omm_objects( self, settings: dict[str, SettingsBaseModel], protein_component: ProteinComponent | None, solvent_component: BaseSolventComponent | None, small_mols: dict[SmallMoleculeComponent, OFFMolecule], ) -> tuple[ app.Topology, openmm.System, openmm.unit.Quantity, dict[Component, npt.NDArray], ]: """ Get the OpenMM Topology, Positions and System of the parameterised system. Parameters ---------- settings : dict[str, SettingsBaseModel] Protocol settings protein_component : ProteinComponent | None Protein component for the system. solvent_component : BaseSolventComponent | None Solvent component for the system, if it exists. small_mols : dict[str, openff.toolkit.Molecule] Dictionary of SmallMoleculeComponents and OpenFF Molecules defining the ligands to be added to the system Returns ------- topology : app.Topology OpenMM Topology object describing the parameterized system. system : openmm.System A non-alchemical OpenMM System of the simulated system. positions : openmm.unit.Quantity Positions of the system. comp_resids : dict[Component, npt.NDArray] A dictionary of the residues for each component in the System. """ if self.verbose: self.logger.info("Parameterizing system") with without_oechem_backend(): system_generator = self._get_system_generator( settings=settings, solvent_component=solvent_component, openff_molecules=list(small_mols.values()), ffcache=self.shared_basepath / settings["output_settings"].forcefield_cache, ) modeller, comp_resids = self._get_modeller( protein_component=protein_component, solvent_component=solvent_component, small_mols=small_mols, system_generator=system_generator, solvation_settings=settings["solvation_settings"], ) system = system_generator.create_system( topology=modeller.topology, molecules=list(small_mols.values()), ) topology = modeller.getTopology() # roundtrip positions to remove vec3 issues positions = to_openmm(from_openmm(modeller.getPositions())) return topology, system, positions, comp_resids def _add_restraints( self, system: openmm.System, topology: GlobalParameterState, positions: openmm.unit.Quantity, alchem_comps: dict[str, list[Component]], comp_resids: dict[Component, npt.NDArray], settings: dict[str, SettingsBaseModel], ) -> tuple[ Quantity | None, openmm.System | None, geometry.BaseRestraintGeometry | None, ]: """ Placeholder method to add restraints if necessary """ return None, system, None def _get_alchemical_system( self, topology: app.Topology, system: openmm.System, comp_resids: dict[Component, npt.NDArray], alchem_comps: dict[str, list[Component]], alchemical_settings: AlchemicalSettings, ) -> tuple[AbsoluteAlchemicalFactory, openmm.System, list[int]]: """ Get an alchemically modified system and its associated factory Parameters ---------- topology : openmm.Topology Topology of OpenMM System. system : openmm.System System to alchemically modify. comp_resids : dict[str, npt.NDArray] A dictionary of residues for each component in the System. alchem_comps : dict[str, list[Component]] A dictionary of alchemical components for each end state. alchemical_settings : AlchemicalSettings Settings controlling how the alchemical system is built. Returns ------- alchemical_factory : AbsoluteAlchemicalFactory Factory for creating an alchemically modified system. alchemical_system : openmm.System Alchemically modified system alchemical_indices : list[int] A list of atom indices for the alchemically modified species in the system. TODO ---- * Add support for all alchemical factory options """ alchemical_indices = self._get_alchemical_indices(topology, comp_resids, alchem_comps) alchemical_region = AlchemicalRegion( alchemical_atoms=alchemical_indices, softcore_alpha=alchemical_settings.softcore_alpha, annihilate_electrostatics=True, annihilate_sterics=alchemical_settings.annihilate_sterics, softcore_a=alchemical_settings.softcore_a, softcore_b=alchemical_settings.softcore_b, softcore_c=alchemical_settings.softcore_c, softcore_beta=0.0, softcore_d=1.0, softcore_e=1.0, softcore_f=2.0, ) alchemical_factory = AbsoluteAlchemicalFactory( consistent_exceptions=False, switch_width=1.0 * ommunit.angstroms, alchemical_pme_treatment="exact", alchemical_rf_treatment="switched", disable_alchemical_dispersion_correction=alchemical_settings.disable_alchemical_dispersion_correction, split_alchemical_forces=True, ) alchemical_system = alchemical_factory.create_alchemical_system(system, alchemical_region) return alchemical_factory, alchemical_system, alchemical_indices @staticmethod def _subsample_topology( topology: openmm.app.Topology, positions: openmm.unit.Quantity, output_selection: str, output_file: pathlib.Path, ) -> npt.NDArray: """ Subsample the system based on user-selected output selection and write the subsampled topology to a PDB file. Parameters ---------- topology : openmm.app.Topology The system topology to subsample. positions : openmm.unit.Quantity The system positions. output_selection : str An MDTraj selection string to subsample the topology with. output_file : pathlib.Path Path to the file to write the PDB to. Returns ------- selection_indices : npt.NDArray The indices of the subselected system. """ traj = mdtraj_from_openmm(topology, positions) selection_indices = traj.topology.select(output_selection) # Write out the subselected structure to PDB if not empty if len(selection_indices) > 0: sub_traj = traj.atom_slice(selection_indices) sub_traj.save_pdb(output_file) return selection_indices def run( self, dry: bool = False, verbose: bool = True, scratch_basepath: pathlib.Path | None = None, shared_basepath: pathlib.Path | None = None, ) -> dict[str, Any]: """Run the setup phase of an absolute free energy calculation. Parameters ---------- dry : bool Do a dry run of the calculation, creating all necessary alchemical system components (topology, system, etc...) but without running the simulation, default False verbose : bool Verbose output of the simulation progress. Output is provided via INFO level logging, default True scratch_basepath : pathlib.Path | None Path to the scratch (temporary) directory space. Defaults to the current working directory if ``None``. shared_basepath : pathlib.Path | None Path to the shared (persistent) directory space. Defaults to the current working directory if ``None``. Returns ------- dict Outputs created in the basepath directory or the debug objects (i.e. sampler) if ``dry==True``. """ # General preparation tasks self._prepare(verbose, scratch_basepath, shared_basepath) if self.verbose: self.logger.info("Starting system setup unit") # Get components alchem_comps, solv_comp, prot_comp, small_mols = self._get_components() # Get settings settings = self._get_settings() # Assign partial charges now to avoid any discrepancies later self._assign_partial_charges(settings["charge_settings"], small_mols) # Get OpenMM topology, positions, system, and comp_resids omm_topology, omm_system, positions, comp_resids = self._get_omm_objects( settings=settings, protein_component=prot_comp, solvent_component=solv_comp, small_mols=small_mols, ) # Pre-equilbrate System (Test + Avoid NaNs + get stable system) positions, box_vectors = self._pre_equilibrate( omm_system, omm_topology, positions, settings, dry ) # Add restraints # Note: when no restraint is applied, restrained_omm_system == omm_system ( standard_state_corr, restrained_omm_system, restraint_geometry, ) = self._add_restraints( omm_system, omm_topology, positions, alchem_comps, comp_resids, settings, ) # Get alchemical system alchem_factory, alchem_system, alchem_indices = self._get_alchemical_system( topology=omm_topology, system=restrained_omm_system, comp_resids=comp_resids, alchem_comps=alchem_comps, alchemical_settings=settings["alchemical_settings"], ) # Subselect system based on user inputs & write initial PDB selection_indices = self._subsample_topology( topology=omm_topology, positions=positions, output_selection=settings["output_settings"].output_indices, output_file=self.shared_basepath / settings["output_settings"].output_structure, ) # Serialize relevant outputs system_outfile = self.shared_basepath / "alchemical_system.xml.bz2" serialize(alchem_system, system_outfile) positions_outfile = self.shared_basepath / "system_positions.npy" npy_positions = from_openmm(positions).to("nanometer").m np.save(positions_outfile, npy_positions) # Set the PDB file name if len(selection_indices) > 0: pdb_structure = self.shared_basepath / settings["output_settings"].output_structure else: pdb_structure = None unit_results_dict = { "system": system_outfile, "positions": positions_outfile, "pdb_structure": pdb_structure, "selection_indices": selection_indices, "box_vectors": from_openmm(box_vectors), } if standard_state_corr is not None: unit_results_dict["standard_state_correction"] = standard_state_corr.to( "kilocalorie_per_mole" ) else: unit_results_dict["standard_state_correction"] = 0 * offunit.kilocalorie_per_mole if restraint_geometry is not None: unit_results_dict["restraint_geometry"] = restraint_geometry.model_dump() else: unit_results_dict["restraint_geometry"] = None if dry: unit_results_dict |= { "standard_system": omm_system, "restrained_system": restrained_omm_system, "alchem_system": alchem_system, "alchem_indices": alchem_indices, "alchem_factory": alchem_factory, "debug_positions": positions, } return unit_results_dict def _execute( self, ctx: gufe.Context, **inputs, ) -> dict[str, Any]: log_system_probe(logging.INFO, paths=[ctx.scratch]) outputs = self.run(scratch_basepath=ctx.scratch, shared_basepath=ctx.shared) return { "repeat_id": self._inputs["repeat_id"], "generation": self._inputs["generation"], "simtype": self.simtype, "openmm_version": openmm.__version__, "openfe_version": openfe.__version__, "gufe_version": gufe.__version__, **outputs, } class BaseAbsoluteMultiStateSimulationUnit(gufe.ProtocolUnit, AbsoluteUnitMixin): @staticmethod def _check_restart(output_settings: SettingsBaseModel, shared_path: pathlib.Path): """ Check if we are doing a restart. Parameters ---------- output_settings : SettingsBaseModel The simulation output settings shared_path : pathlib.Path The shared directory where we should be looking for existing files. Raises ------ IOError If one of the trajectory or checkpoint files are present without the other. Notes ----- For now this just checks if the netcdf files are present in the shared directory but in the future this may expand depending on how warehouse works. """ trajectory = shared_path / output_settings.output_filename checkpoint = shared_path / output_settings.checkpoint_storage_filename if trajectory.is_file() and checkpoint.is_file(): return True elif trajectory.is_file() ^ checkpoint.is_file(): if trajectory.is_file(): errmsg = "the trajectory file is present but not the checkpoint file. " else: errmsg = "the checkpoint file is present but not the trajectory file. " errmsg = ( "Attempting to restart but " + errmsg + "This should not happen under normal circumstances." ) raise IOError(errmsg) else: return False @abc.abstractmethod def _get_components( self, ) -> tuple[ dict[str, list[Component]], gufe.SolventComponent | None, gufe.ProteinComponent | None, dict[SmallMoleculeComponent, OFFMolecule], ]: """ Get the relevant components to create the alchemical system with. Note ---- Must be implemented in the child class. """ ... def _get_lambda_schedule( self, settings: dict[str, SettingsBaseModel] ) -> dict[str, list[float]]: """ Create the lambda schedule Parameters ---------- settings : dict[str, SettingsBaseModel] Settings for the unit. Returns ------- lambdas : dict[str, list[float]] TODO ---- * Augment this by using something akin to the RFE protocol's LambdaProtocol """ lambdas = dict() lambda_elec = settings["lambda_settings"].lambda_elec lambda_vdw = settings["lambda_settings"].lambda_vdw lambda_rest = settings["lambda_settings"].lambda_restraints # Reverse lambda schedule for vdw, end elec, # since in AbsoluteAlchemicalFactory 1 means fully # interacting (which would be non-interacting for us) lambdas["lambda_electrostatics"] = [1 - x for x in lambda_elec] lambdas["lambda_sterics"] = [1 - x for x in lambda_vdw] lambdas["lambda_restraints"] = [x for x in lambda_rest] return lambdas def _get_states( self, alchemical_system: openmm.System, positions: openmm.unit.Quantity, box_vectors: openmm.unit.Quantity, thermodynamic_settings: ThermoSettings, lambdas: dict[str, list[float]], solvent_component: BaseSolventComponent | None, alchemically_restrained: bool, ) -> tuple[list[SamplerState], list[ThermodynamicState]]: """ Get a list of sampler and thermodynmic states from an input alchemical system. Parameters ---------- alchemical_system : openmm.System Alchemical system to get states for. positions : openmm.unit.Quantity Positions of the alchemical system. box_vectors : openmm.unit.Quantity Box vectors of the alchemical system. thermodynamic_settings : ThermoSettings Settings controlling the thermodynamic parameters. lambdas : dict[str, list[float]] A dictionary of lambda scales. solvent_component : BaseSolventComponent | None The solvent component of the system, if there is one. alchemically_restrained : bool Whether or not the system requires a control parameter for any alchemical restraints. Returns ------- sampler_states : list[SamplerState] A list of SamplerStates for each replica in the system. cmp_states : list[ThermodynamicState] A list of ThermodynamicState for each replica in the system. """ # Fetch an alchemical state alchemical_state = AlchemicalState.from_system(alchemical_system) # Set up the system constants temperature = thermodynamic_settings.temperature pressure = thermodynamic_settings.pressure constants = dict() constants["temperature"] = ensure_quantity(temperature, "openmm") if solvent_component is not None: constants["pressure"] = ensure_quantity(pressure, "openmm") # Get the thermodynamic parameter protocol param_protocol = copy.deepcopy(lambdas) # Get the composable states if alchemically_restrained: restraint_state = omm_restraints.RestraintParameterState(lambda_restraints=1.0) composable_states = [alchemical_state, restraint_state] else: composable_states = [alchemical_state] # In this case we also don't have a restraint being controlled # so we drop it from the protocol param_protocol.pop("lambda_restraints", None) cmp_states = create_thermodynamic_state_protocol( alchemical_system, protocol=param_protocol, constants=constants, composable_states=composable_states, ) sampler_state = SamplerState(positions=positions) if alchemical_system.usesPeriodicBoundaryConditions(): sampler_state.box_vectors = box_vectors sampler_states = [sampler_state for _ in cmp_states] return sampler_states, cmp_states @staticmethod def _get_integrator( integrator_settings: IntegratorSettings, simulation_settings: MultiStateSimulationSettings, system: openmm.System, ) -> openmmtools.mcmc.LangevinDynamicsMove: """ Return a LangevinDynamicsMove integrator Parameters ---------- integrator_settings : IntegratorSettings Settings controlling the Langevin integrator simulation_settings : MultiStateSimulationSettings Settings controlling the simulation. system : openmm.System The OpenMM System. Returns ------- integrator : openmmtools.mcmc.LangevinDynamicsMove A configured integrator object. Raises ------ ValueError If there are virtual sites in the system, but velocities are not being reassigned after every MCMC move. """ steps_per_iteration = settings_validation.convert_steps_per_iteration( simulation_settings, integrator_settings ) integrator = openmmtools.mcmc.LangevinDynamicsMove( timestep=to_openmm(integrator_settings.timestep), collision_rate=to_openmm(integrator_settings.langevin_collision_rate), n_steps=steps_per_iteration, reassign_velocities=integrator_settings.reassign_velocities, n_restart_attempts=integrator_settings.n_restart_attempts, constraint_tolerance=integrator_settings.constraint_tolerance, ) # Validate for known issue when dealing with virtual sites # and mutltistate simulations if not integrator_settings.reassign_velocities: for particle_idx in range(system.getNumParticles()): if system.isVirtualSite(particle_idx): errmsg = ( "Simulations with virtual sites without velocity " "reassignments are unstable with MCMC integrators. " "You can set `reassign_velocities` to ``True`` in the " "`integrator_settings` to avoid this issue." ) raise ValueError(errmsg) return integrator @staticmethod def _get_reporter( storage_path: pathlib.Path, selection_indices: npt.NDArray, simulation_settings: MultiStateSimulationSettings, output_settings: MultiStateOutputSettings, ) -> multistate.MultiStateReporter: """ Get a MultistateReporter for the simulation you are running. Parameters ---------- storage_path : pathlib.Path Path to the directory where files should be written. selection_indices : npt.NDArray Array of system particle indices to subsample the system by. simulation_settings : MultiStateSimulationSettings Multistate simulation control settings, specifically containing the amount of time per state sampling iteration. output_settings: MultiStateOutputSettings Output settings for the simulations Returns ------- reporter : multistate.MultiStateReporter The reporter for the simulation. Notes ----- All this does is create the reporter, it works for both new reporters and if we are doing a restart. """ # Define the trajectory & checkpoint files nc = storage_path / output_settings.output_filename # The checkpoint file in openmmtools is taken as a file relative # to the location of the nc file, so you only want the filename chk = output_settings.checkpoint_storage_filename if output_settings.positions_write_frequency is not None: pos_interval = settings_validation.divmod_time_and_check( numerator=output_settings.positions_write_frequency, denominator=simulation_settings.time_per_iteration, numerator_name="output settings' position_write_frequency", denominator_name="simulation settings' time_per_iteration", ) else: pos_interval = 0 if output_settings.velocities_write_frequency is not None: vel_interval = settings_validation.divmod_time_and_check( numerator=output_settings.velocities_write_frequency, denominator=simulation_settings.time_per_iteration, numerator_name="output settings' velocity_write_frequency", denominator_name="simulation settings' time_per_iteration", ) else: vel_interval = 0 chk_intervals = settings_validation.convert_checkpoint_interval_to_iterations( checkpoint_interval=output_settings.checkpoint_interval, time_per_iteration=simulation_settings.time_per_iteration, ) return multistate.MultiStateReporter( storage=nc, analysis_particle_indices=selection_indices, checkpoint_interval=chk_intervals, checkpoint_storage=chk, position_interval=pos_interval, velocity_interval=vel_interval, ) @staticmethod def _get_sampler( integrator: openmmtools.mcmc.LangevinDynamicsMove, reporter: openmmtools.multistate.MultiStateReporter, simulation_settings: MultiStateSimulationSettings, thermodynamic_settings: ThermoSettings, compound_states: list[ThermodynamicState], sampler_states: list[SamplerState], platform: openmm.Platform, restart: bool, ) -> multistate.MultiStateSampler: """ Get a sampler based on the equilibrium sampling method requested. Parameters ---------- integrator : openmmtools.mcmc.LangevinDynamicsMove The simulation integrator. reporter : openmmtools.multistate.MultiStateReporter The reporter to hook up to the sampler. simulation_settings : MultiStateSimulationSettings Settings for the alchemical sampler. thermodynamic_settings : ThermoSettings Thermodynamic settings compound_states : list[ThermodynamicState] A list of thermodynamic states to sample. sampler_states : list[SamplerState] A list of sampler states. platform : openmm.Platform The compute platform to use. restart : bool ``True`` if we are doing a simulation restart. Returns ------- sampler : multistate.MultistateSampler A sampler configured for the chosen sampling method. """ _SAMPLERS = { "repex": multistate.ReplicaExchangeSampler, "sams": multistate.SAMSSampler, "independent": multistate.MultiStateSampler, } sampler_method = simulation_settings.sampler_method.lower() try: sampler_class = _SAMPLERS[sampler_method] except KeyError: errmsg = f"Unknown sampler {sampler_method}" raise AttributeError(errmsg) # Get the real time analysis values to use rta_its, rta_min_its = settings_validation.convert_real_time_analysis_iterations( simulation_settings=simulation_settings, ) # Get the number of production iterations to run for steps_per_iteration = integrator.n_steps timestep = from_openmm(integrator.timestep) number_of_iterations = int( settings_validation.get_simsteps( sim_length=simulation_settings.production_length, timestep=timestep, mc_steps=steps_per_iteration, ) / steps_per_iteration ) # convert early_termination_target_error from kcal/mol to kT early_termination_target_error = ( settings_validation.convert_target_error_from_kcal_per_mole_to_kT( thermodynamic_settings.temperature, simulation_settings.early_termination_target_error, ) ) sampler_kwargs = { "mcmc_moves": integrator, "online_analysis_interval": rta_its, "online_analysis_target_error": early_termination_target_error, "online_analysis_minimum_iterations": rta_min_its, "number_of_iterations": number_of_iterations, } if sampler_method == "sams": sampler_kwargs |= { "flatness_criteria": simulation_settings.sams_flatness_criteria, "gamma0": simulation_settings.sams_gamma0, } if sampler_method == "repex": sampler_kwargs |= { "replica_mixing_scheme": "swap-all", } # Restarting so we just rebuild from storage. if restart: sampler = sampler_class.from_storage(reporter) # We do some checks to make sure we are running the same system # including ensuring that we have the same thermodynamic parameters and # that the lambda schedule is the same. for index, thermostate in enumerate(sampler._thermodynamic_states): system_validation.assert_multistate_system_equality( ref_system=compound_states[index].get_system(remove_thermostat=True), stored_system=thermostate.get_system(remove_thermostat=True), ) # Loop over each composable state (e.g. GlobalParameterState object) # get the parameters and check that the values are the same. for composable_state in compound_states[index]._composable_states: for param in composable_state._parameters: expected = getattr(compound_states[index], param) stored = getattr(thermostate, param) if expected != stored: errmsg = ( f"System parameter {param} in checkpoint does " "not match protocol system, cannot resume" ) raise ValueError(errmsg) if ( (simulation_settings.n_replicas != sampler.n_states) or (simulation_settings.n_replicas != sampler.n_replicas) or (sampler.mcmc_moves[0].n_steps != steps_per_iteration) or (sampler.mcmc_moves[0].timestep != integrator.timestep) ): errmsg = "System in checkpoint does not match protocol system, cannot resume" raise ValueError(errmsg) else: sampler = sampler_class(**sampler_kwargs) sampler.create( thermodynamic_states=compound_states, sampler_states=sampler_states, storage=reporter, ) # Get and set the context caches sampler.energy_context_cache = openmmtools.cache.ContextCache( capacity=None, time_to_live=None, platform=platform, ) sampler.sampler_context_cache = openmmtools.cache.ContextCache( capacity=None, time_to_live=None, platform=platform, ) return sampler def _run_simulation( self, sampler: multistate.MultiStateSampler, reporter: multistate.MultiStateReporter, settings: dict[str, SettingsBaseModel], dry: bool, ): """ Run the simulation. Parameters ---------- sampler : multistate.MultiStateSampler The sampler associated with the simulation to run. reporter : multistate.MultiStateReporter The reporter associated with the sampler. settings : dict[str, SettingsBaseModel] The dictionary of settings for the protocol. dry : bool Whether or not to dry run the simulation """ # Get the relevant simulation steps mc_steps = settings_validation.convert_steps_per_iteration( simulation_settings=settings["simulation_settings"], integrator_settings=settings["integrator_settings"], ) equil_steps = settings_validation.get_simsteps( sim_length=settings["simulation_settings"].equilibration_length, timestep=settings["integrator_settings"].timestep, mc_steps=mc_steps, ) prod_steps = settings_validation.get_simsteps( sim_length=settings["simulation_settings"].production_length, timestep=settings["integrator_settings"].timestep, mc_steps=mc_steps, ) if not dry: # pragma: no-cover # No production steps have been taken, so start from scratch if sampler._iteration == 0: # minimize if self.verbose: self.logger.info("minimizing systems") sampler.minimize(max_iterations=settings["simulation_settings"].minimization_steps) # equilibrate if self.verbose: self.logger.info("equilibrating systems") sampler.equilibrate(int(equil_steps / mc_steps)) # At this point we are ready for production if self.verbose: self.logger.info("running production phase") # We use `run` so that we're limited by the number of iterations # we passed when we built the sampler. sampler.run(n_iterations=int(prod_steps / mc_steps) - sampler._iteration) if self.verbose: self.logger.info("production phase complete") else: # close reporter when you're done, prevent file handle clashes reporter.close() # clean up the reporter file fns = [ self.shared_basepath / settings["output_settings"].output_filename, self.shared_basepath / settings["output_settings"].checkpoint_storage_filename, ] for fn in fns: fn.unlink() def run( self, *, system: openmm.System, positions: openmm.unit.Quantity, box_vectors: Quantity, selection_indices: npt.NDArray, alchemical_restraints: bool, dry: bool = False, verbose: bool = True, scratch_basepath: pathlib.Path | None = None, shared_basepath: pathlib.Path | None = None, ) -> dict[str, Any]: """ Run the free energy calculation using a multistate sampler. Parameters ---------- system : openmm.System The System to simulate. positions : openmm.unit.Quantity The positions of the System. box_vectors : openff.units.Quantity The box vectors of the System. selection_indices : npt.NDArray Indices of the System particles to write to file. alchemical_restraints: bool, Whether or not the system has alchemical restraints. dry: bool Do a dry run of the calculation, creating all the necessary components, but without running the simulation. verbose : bool Verbose output of the simulation progress. Output is provided at the INFO logging level. scratch_basepath : pathlib.Path | None Where to store temporary files, defaults to the current working directory if ``None``. shared_basepath : pathlib.Path | None Where to store calculation outputs, defaults to the current working directory if ``None``. Returns ------- dict Outputs created by the unit, including the debug objects (i.e. sampler) if ``dry==True`` """ # Prepare paths & verbosity self._prepare(verbose, scratch_basepath, shared_basepath) if self.verbose: self.logger.info("Starting simulation unit") # Get the settings settings = self._get_settings() # Check for a restart self.restart = self._check_restart( output_settings=settings["output_settings"], shared_path=self.shared_basepath, ) # Get the components alchem_comps, solv_comp, prot_comp, small_mols = self._get_components() # Get the lambda schedule lambdas = self._get_lambda_schedule(settings) # Get the compute platform restrict_cpu = settings["forcefield_settings"].nonbonded_method.lower() == "nocutoff" platform = omm_compute.get_openmm_platform( platform_name=settings["engine_settings"].compute_platform, gpu_device_index=settings["engine_settings"].gpu_device_index, restrict_cpu_count=restrict_cpu, ) # Get compound and sampler states sampler_states, cmp_states = self._get_states( alchemical_system=system, positions=positions, # convert the box vectors to vec3 from openff box_vectors=make_vec3_box(box_vectors), thermodynamic_settings=settings["thermo_settings"], lambdas=lambdas, solvent_component=solv_comp, alchemically_restrained=alchemical_restraints, ) # Get the integrator integrator = self._get_integrator( integrator_settings=settings["integrator_settings"], simulation_settings=settings["simulation_settings"], system=system, ) try: # Create or get the multistate reporter reporter = self._get_reporter( storage_path=self.shared_basepath, selection_indices=selection_indices, simulation_settings=settings["simulation_settings"], output_settings=settings["output_settings"], ) # Get the sampler sampler = self._get_sampler( integrator=integrator, reporter=reporter, simulation_settings=settings["simulation_settings"], thermodynamic_settings=settings["thermo_settings"], compound_states=cmp_states, sampler_states=sampler_states, platform=platform, restart=self.restart, ) # Run the simulation self._run_simulation( sampler=sampler, reporter=reporter, settings=settings, dry=dry, ) finally: # Have to wrap this in a try/except, because we might # be in a situation where the reporter or sampler weren't created try: # Order is reporter, contexts, sampler, integrator reporter.close() # close to prevent file handle clashes # clear GPU context # Note: use cache.empty() when openmmtools #690 is resolved for context in list(sampler.energy_context_cache._lru._data.keys()): del sampler.energy_context_cache._lru._data[context] for context in list(sampler.sampler_context_cache._lru._data.keys()): del sampler.sampler_context_cache._lru._data[context] # cautiously clear out the global context cache too for context in list(openmmtools.cache.global_context_cache._lru._data.keys()): del openmmtools.cache.global_context_cache._lru._data[context] del sampler.sampler_context_cache, sampler.energy_context_cache # Keep these around in a dry run so we can inspect things if not dry: # At this point we know the sampler exists, so we del the integrator # first since it's associated with the sampler del integrator, sampler except UnboundLocalError: pass if not dry: nc = self.shared_basepath / settings["output_settings"].output_filename chk = self.shared_basepath / settings["output_settings"].checkpoint_storage_filename return { "trajectory": nc, "checkpoint": chk, } else: return { "sampler": sampler, "integrator": integrator, } def _execute( self, ctx: gufe.Context, *, setup_results, **inputs, ) -> dict[str, Any]: log_system_probe(logging.INFO, paths=[ctx.scratch]) # Ensure the environment hasn't changed self._verify_execution_environment(setup_results.outputs) # Get the relevant inputs for running the unit system = deserialize(setup_results.outputs["system"]) positions = to_openmm(np.load(setup_results.outputs["positions"]) * offunit.nanometer) selection_indices = setup_results.outputs["selection_indices"] box_vectors = setup_results.outputs["box_vectors"] if setup_results.outputs["restraint_geometry"] is not None: alchemical_restraints = True else: alchemical_restraints = False outputs = self.run( system=system, positions=positions, box_vectors=box_vectors, selection_indices=selection_indices, alchemical_restraints=alchemical_restraints, scratch_basepath=ctx.scratch, shared_basepath=ctx.shared, ) return { "repeat_id": self._inputs["repeat_id"], "generation": self._inputs["generation"], "simtype": self.simtype, **outputs, } class BaseAbsoluteMultiStateAnalysisUnit(gufe.ProtocolUnit, AbsoluteUnitMixin): @staticmethod def _analyze_multistate_energies( trajectory: pathlib.Path, checkpoint: pathlib.Path, sampler_method: str, output_directory: pathlib.Path, dry: bool, ): """ Analyze multistate energies and generate plots. Parameters ---------- trajectory : pathlib.Path Path to the NetCDF trajectory file. checkpoint : pathlib.Path The name of the checkpoint file. Note this is relative in path to the trajectory file. sampler_method : str The multistate sampler method used. output_directory : pathlib.Path The path to where plots will be written. dry : bool Whether or not we are running a dry run. """ reporter = multistate.MultiStateReporter( storage=trajectory, # Note: openmmtools only wants the name of the checkpoint # file, it assumes it to be in the same place as the trajectory checkpoint_storage=checkpoint.name, open_mode="r", ) analyzer = multistate_analysis.MultistateEquilFEAnalysis( reporter=reporter, sampling_method=sampler_method, result_units=offunit.kilocalorie_per_mole, ) # Only create plots when not doing a dry run if not dry: analyzer.plot(filepath=output_directory, filename_prefix="") analyzer.close() reporter.close() return analyzer.unit_results_dict def run( self, *, trajectory: pathlib.Path, checkpoint: pathlib.Path, dry: bool = False, verbose: bool = True, scratch_basepath: pathlib.Path | None = None, shared_basepath: pathlib.Path | None = None, ) -> dict[str, Any]: """Analyze the multistate simulation. Parameters ---------- trajectory : pathlib.Path Path to the MultiStateReporter generated NetCDF file. checkpoint : pathlib.Path Path to the checkpoint file generated by MultiStateReporter. dry : bool Do a dry run of the calculation, creating all necessary hybrid system components (topology, system, sampler, etc...) but without running the simulation. verbose : bool Verbose output of the simulation progress. Output is provided via INFO level logging. scratch_basepath: pathlib.Path | None Where to store temporary files, defaults to current working directory shared_basepath : pathlib.Path | None Where to run the calculation, defaults to current working directory Returns ------- dict Outputs created in the basepath directory or the debug objects (i.e. sampler) if ``dry==True``. """ # Prepare paths & verbosity self._prepare(verbose, scratch_basepath, shared_basepath) if self.verbose: self.logger.info("Starting simulation analysis unit") # Get the settings settings = self._get_settings() # Energies analysis if verbose: self.logger.info("Analyzing energies") energy_analysis = self._analyze_multistate_energies( trajectory=trajectory, checkpoint=checkpoint, sampler_method=settings["simulation_settings"].sampler_method.lower(), output_directory=self.shared_basepath, dry=dry, ) return energy_analysis def _execute( self, ctx: gufe.Context, *, setup_results, simulation_results, **inputs, ) -> dict[str, Any]: log_system_probe(logging.INFO, paths=[ctx.scratch]) # Ensure the environment hasn't changed self._verify_execution_environment(setup_results.outputs) # Get the relevant inputs for running the unit pdb_file = setup_results.outputs["pdb_structure"] selection_indices = setup_results.outputs["selection_indices"] restraint_geometry = setup_results.outputs["restraint_geometry"] standard_state_corr = setup_results.outputs["standard_state_correction"] trajectory = simulation_results.outputs["trajectory"] checkpoint = simulation_results.outputs["checkpoint"] outputs = self.run( trajectory=trajectory, checkpoint=checkpoint, scratch_basepath=ctx.scratch, shared_basepath=ctx.shared, ) return { "repeat_id": self._inputs["repeat_id"], "generation": self._inputs["generation"], "simtype": self.simtype, # We re-include things here also to make # life easier when gathering results. "pdb_structure": pdb_file, "trajectory": trajectory, "checkpoint": checkpoint, "selection_indices": selection_indices, "restraint_geometry": restraint_geometry, "standard_state_correction": standard_state_corr, **outputs, } ================================================ FILE: src/openfe/protocols/openmm_afe/equil_afe_settings.py ================================================ # This code is part of OpenFE and is licensed under the MIT license. # For details, see https://github.com/OpenFreeEnergy/openfe """Settings class for equilibrium AFE Protocols using OpenMM + OpenMMTools This module implements the necessary settings necessary to run absolute free energies using OpenMM. See Also -------- openfe.protocols.openmm_afe.AbsoluteSolvationProtocol TODO ---- * Add support for restraints """ import numpy as np from gufe.settings import ( OpenMMSystemGeneratorFFSettings, SettingsBaseModel, ThermoSettings, ) from pydantic import field_validator from openfe.protocols.openmm_utils.omm_settings import ( BaseSolvationSettings, IntegratorSettings, MDOutputSettings, MDSimulationSettings, MultiStateOutputSettings, MultiStateSimulationSettings, OpenFFPartialChargeSettings, OpenMMEngineSettings, OpenMMSolvationSettings, ) from openfe.protocols.restraint_utils.settings import ( BaseRestraintSettings, BoreschRestraintSettings, ) class AlchemicalSettings(SettingsBaseModel): """ Alchemical settings for Protocols which use the AbsoluteAlchemicalFactory. """ disable_alchemical_dispersion_correction: bool = False """ If True, the long-range dispersion correction will not be included for the alchemical region, avoiding the need to recompute the correction. This can improve performance, at the cost of accuracy. Default is False. """ annihilate_sterics: bool = False """ If True, sterics (Lennard-Jones) will be annihilated instead of decoupled. Default is False. """ softcore_alpha: float = 0.5 """ Alchemical softcore parameter for the Lennard-Jones interactions (default is 0.5). The generalized softcore potential formalism introduced by Pham and Shirts, J. Chem. Phys. 135, 034114 (2011), equation 13, is used here. The ``softcore_a``, ``softcore_b``, and ``softcore_c`` parameters are used alongside ``softcore_alpha`` to control how the potential is scaled. """ softcore_a: float = 1.0 """ Scaling constant ``a`` in Eq. 13 from Pham and Shirts, J. Chem. Phys. 135, 034114 (2011). """ softcore_b: float = 1.0 """ Scaling constant ``b`` in Eq. 13 from Pham and Shirts, J. Chem. Phys. 135, 034114 (2011). """ softcore_c: float = 6.0 """ Scaling constant ``c`` in Eq. 13 from Pham and Shirts, J. Chem. Phys. 135, 034114 (2011). """ class LambdaSettings(SettingsBaseModel): """Lambda schedule settings. Defines lists of floats to control various aspects of the alchemical transformation. Notes ----- * In all cases a lambda value of 0 defines the system in state A, whilst a value of 1 defines the system in state B. In an absolute transformation, state A means a fully interacting ligand without any restraints applied, and state B means a fully non-interacting ligand, with optional restraints applied. * ``lambda_elec``, ``lambda_vdw``, and ``lambda_restraints`` must all be of the same length, defining all the windows of the transformation. """ # fmt: off lambda_elec: list[float] = [ 0.0, 0.25, 0.5, 0.75, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, ] # fmt: on """ List of floats of lambda values for the electrostatics. Zero means fully interacting (state A), and one means annihilated (state B). Length of this list needs to match length of lambda_vdw and lambda_restraints. """ # fmt: off lambda_vdw: list[float] = [ 0.0, 0.0, 0.0, 0.0, 0.0, 0.05, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.65, 0.7, 0.75, 0.8, 0.85, 0.9, 0.95, 1.0, ] # fmt: on """ List of floats of lambda values for the van der Waals. Zero means full interacting (state A) and one means decoupled (state B). Length of this list needs to match length of lambda_elec and lambda_restraints. """ # fmt: off lambda_restraints: list[float] = [ 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, ] # fmt: on """ List of floats of lambda values for the restraints. Zero means no restraints are applied (state A), and one means restraints are fully applied (state B). Note: The length of this list needs to match length of lambda_vdw and lambda_elec. """ @field_validator("lambda_elec", "lambda_vdw", "lambda_restraints") def must_be_between_0_and_1(cls, v): for window in v: if not 0 <= window <= 1: errmsg = ( f"Lambda windows must be between 0 and 1, got a window with value {window}." ) raise ValueError(errmsg) return v @field_validator("lambda_elec", "lambda_vdw", "lambda_restraints") def must_be_monotonic(cls, v): difference = np.diff(v) monotonic = np.all(difference >= 0) if not monotonic: errmsg = ( "The lambda schedule is not monotonically increasing, " f"got the following schedule: {v}." ) raise ValueError(errmsg) return v class ABFEPreEquilOutputSettings(MDOutputSettings): output_indices: str = "all" """ Selection string for which part of the system to write coordinates for. For now, must be "all". """ equil_nvt_structure: str | None = "equil_nvt_structure.pdb" """ Name of the PDB file containing the system after NVT pre-equilibration. Only the atom subset specified by output_indices is saved. Default 'equil_nvt_structure.pdb'. """ equil_npt_structure: str | None = "equil_npt_structure.pdb" """ Name of the PDB file containing the system after NPT pre-equilibration. Only the atom subset specified by output_indices is saved. Default 'equil_npt_structure.pdb'. """ production_trajectory_filename: str | None = "production_equil.xtc" """ Name pre-equilibration "production" (i.e. extended NPT) trajectory file. Only the atom subset specified by output_indices is saved. Default `production_equil.xtc`. """ log_output: str | None = "production_equil_simulation.log" """ Filename for writing the pre-equilibration extended NPT MD simulation log file. This includes ns/day, timesteps, energies, density, etc. Default 'production_equil_simulation.log' """ @field_validator("output_indices") def must_be_all(cls, v): # Would be better if this was just changed to a Literal # but changing types in child classes in pydantic is messy if v != "all": msg = "output_indices must be all for ABFE pre-equilibration simulations" raise ValueError(msg) return v # This subclasses from SettingsBaseModel as it has vacuum_forcefield and # solvent_forcefield fields, not just a single forcefield_settings field class AbsoluteSolvationSettings(SettingsBaseModel): """ Configuration object for ``AbsoluteSolvationProtocol``. See Also -------- openfe.protocols.openmm_afe.AbsoluteSolvationProtocol """ protocol_repeats: int """ The number of completely independent repeats of the entire sampling process. The mean of the repeats defines the final estimate of FE difference, while the variance between repeats is used as the uncertainty. """ @field_validator("protocol_repeats") def must_be_positive(cls, v): if v <= 0: errmsg = f"protocol_repeats must be a positive value, got {v}." raise ValueError(errmsg) return v # Inherited things solvent_forcefield_settings: OpenMMSystemGeneratorFFSettings vacuum_forcefield_settings: OpenMMSystemGeneratorFFSettings """Parameters to set up the force field with OpenMM Force Fields""" thermo_settings: ThermoSettings """Settings for thermodynamic parameters""" solvation_settings: OpenMMSolvationSettings """Settings for solvating the system.""" # Alchemical settings alchemical_settings: AlchemicalSettings """ Alchemical protocol settings. """ lambda_settings: LambdaSettings """ Settings for controlling the lambda schedule for the different components (vdw, elec, restraints). """ # MD Engine things vacuum_engine_settings: OpenMMEngineSettings """ Settings specific to the OpenMM engine, such as the compute platform for the vacuum transformation. """ solvent_engine_settings: OpenMMEngineSettings """ Settings specific to the OpenMM engine, such as the compute platform for the solvent transformation. """ # Sampling State defining things integrator_settings: IntegratorSettings """ Settings for controlling the integrator, such as the timestep and barostat settings. """ # Simulation run settings vacuum_equil_simulation_settings: MDSimulationSettings """ Pre-alchemical vacuum simulation control settings. Notes ----- The `NVT` equilibration should be set to 0 * unit.nanosecond as it will not be run. """ vacuum_simulation_settings: MultiStateSimulationSettings """ Simulation control settings, including simulation lengths for the vacuum transformation. """ solvent_equil_simulation_settings: MDSimulationSettings """ Pre-alchemical solvent simulation control settings. """ solvent_simulation_settings: MultiStateSimulationSettings """ Simulation control settings, including simulation lengths for the solvent transformation. """ vacuum_equil_output_settings: MDOutputSettings """ Simulation output settings for the vacuum non-alchemical equilibration. """ vacuum_output_settings: MultiStateOutputSettings """ Simulation output settings for the vacuum transformation. """ solvent_equil_output_settings: MDOutputSettings """ Simulation output settings for the solvent non-alchemical equilibration. """ solvent_output_settings: MultiStateOutputSettings """ Simulation output settings for the solvent transformation. """ partial_charge_settings: OpenFFPartialChargeSettings """ Settings for controlling how to assign partial charges, including the partial charge assignment method, and the number of conformers used to generate the partial charges. """ class AbsoluteBindingSettings(SettingsBaseModel): """ Configuration object for ``AbsoluteBindingPProtocol`` See Also -------- openfe.protocols.openmm_afe.AbsoluteBindingProtocol """ protocol_repeats: int """ The number of completely independent repeats of the entire sampling process. The mean of the repeats defines the final estimate of FE difference, while the variance between repeats is used as the uncertainty. """ @field_validator("protocol_repeats") def must_be_positive(cls, v): if v <= 0: errmsg = f"protocol_repeats must be a positive value, got {v}." raise ValueError(errmsg) return v forcefield_settings: OpenMMSystemGeneratorFFSettings """Parameters to set up the force field with OpenMM Force Fields""" thermo_settings: ThermoSettings """Settings for thermodynamic parameters""" solvent_solvation_settings: OpenMMSolvationSettings """Settings for solvating the system in the solvent.""" complex_solvation_settings: OpenMMSolvationSettings """Settings for solvating the system in the complex.""" # Alchemical settings alchemical_settings: AlchemicalSettings """ Alchemical protocol settings. """ complex_lambda_settings: LambdaSettings """ Settings for controlling the complex transformation leg lambda schedule for the different components (vdw, elec, restraints). """ solvent_lambda_settings: LambdaSettings """ Settings for controlling the solvent transformation leg lambda schedule for the different components (vdw, elec, restraints). Notes ----- * The `restraints` entry of the lambda settings will be ignored in the solvent leg. """ # MD Engine things engine_settings: OpenMMEngineSettings """ Settings specific to the OpenMM engine, such as the compute platform. """ # Sampling State defining things solvent_integrator_settings: IntegratorSettings """ Settings for controlling the integrator, such as the timestep and barostat settings in the solvent. """ complex_integrator_settings: IntegratorSettings """ Settings for controlling the integrator, such as the timestep and barostat settings in the complex. """ # Simulation run settings complex_equil_simulation_settings: MDSimulationSettings """ Pre-alchemical complex simulation control settings. """ complex_simulation_settings: MultiStateSimulationSettings """ Simulation control settings, including simulation lengths for the complex transformation. """ solvent_equil_simulation_settings: MDSimulationSettings """ Pre-alchemical solvent simulation control settings. """ solvent_simulation_settings: MultiStateSimulationSettings """ Simulation control settings, including simulation lengths for the solvent transformation. """ # Simulation output settings complex_equil_output_settings: ABFEPreEquilOutputSettings """ Simulation output settings for the complex non-alchemical equilibration. """ complex_output_settings: MultiStateOutputSettings """ Simulation output settings for the complex transformation. """ solvent_equil_output_settings: ABFEPreEquilOutputSettings """ Simulation output settings for the solvent non-alchemical equilibration. """ solvent_output_settings: MultiStateOutputSettings """ Simulation output settings for the solvent transformation. """ partial_charge_settings: OpenFFPartialChargeSettings """ Settings for controlling how to assign partial charges, including the partial charge assignment method, and the number of conformers used to generate the partial charges. """ restraint_settings: BaseRestraintSettings """ Settings controlling how restraints are added to the system in the complex simulation. """ ================================================ FILE: src/openfe/protocols/openmm_afe/equil_binding_afe_method.py ================================================ # This code is part of OpenFE and is licensed under the MIT license. # For details, see https://github.com/OpenFreeEnergy/openfe """OpenMM Equilibrium Binding AFE Protocol --- :mod:`openfe.protocols.openmm_afe.equil_binding_afe_method` ========================================================================================================== This module implements the necessary methodology tooling to calculate an absolute binding free energy using OpenMM tools and one of the following alchemical sampling methods: * Hamiltonian Replica Exchange * Self-adjusted mixture sampling * Independent window sampling Current limitations ------------------- * Alchemical species with a net charge are not currently supported. * Disappearing molecules are only allowed in state A. * Only small molecules are allowed to act as alchemical molecules. Acknowledgements ---------------- * This Protocol re-implements components from `Yank `_. """ import logging import uuid import warnings from collections import defaultdict from typing import Any, Iterable import gufe from gufe import ( ChemicalSystem, ProteinComponent, ProteinMembraneComponent, SmallMoleculeComponent, SolventComponent, settings, ) from openff.units import unit as offunit from openfe.due import Doi, due from openfe.protocols.openmm_afe.equil_afe_settings import ( ABFEPreEquilOutputSettings, AbsoluteBindingSettings, AlchemicalSettings, BoreschRestraintSettings, IntegratorSettings, LambdaSettings, MDSimulationSettings, MultiStateOutputSettings, MultiStateSimulationSettings, OpenFFPartialChargeSettings, OpenMMEngineSettings, OpenMMSolvationSettings, ) from openfe.protocols.openmm_utils import ( settings_validation, system_validation, ) from .abfe_units import ( ABFEComplexAnalysisUnit, ABFEComplexSetupUnit, ABFEComplexSimUnit, ABFESolventAnalysisUnit, ABFESolventSetupUnit, ABFESolventSimUnit, ) from .afe_protocol_results import AbsoluteBindingProtocolResult due.cite( Doi("10.5281/zenodo.596504"), description="Yank", path="openfe.protocols.openmm_afe.equil_binding_afe_method", cite_module=True, ) due.cite( Doi("10.5281/zenodo.596622"), description="OpenMMTools", path="openfe.protocols.openmm_afe.equil_binding_afe_method", cite_module=True, ) due.cite( Doi("10.1371/journal.pcbi.1005659"), description="OpenMM", path="openfe.protocols.openmm_afe.equil_binding_afe_method", cite_module=True, ) logger = logging.getLogger(__name__) class AbsoluteBindingProtocol(gufe.Protocol): """ Absolute binding free energy calculations using OpenMM and OpenMMTools. See Also -------- :mod:`openfe.protocols` :class:`openfe.protocols.openmm_afe.AbsoluteBindingSettings` :class:`openfe.protocols.openmm_afe.AbsoluteBindingProtocolResult` :class:`openfe.protocols.openmm_afe.AbsoluteBindingSolventUnit` :class:`openfe.protocols.openmm_afe.AbsoluteBindingComplexUnit` """ result_cls = AbsoluteBindingProtocolResult _settings_cls = AbsoluteBindingSettings _settings: AbsoluteBindingSettings @classmethod def _default_settings(cls): """A dictionary of initial settings for this creating this Protocol These settings are intended as a suitable starting point for creating an instance of this protocol. It is recommended, however that care is taken to inspect and customize these before performing a Protocol. Returns ------- Settings a set of default settings """ # fmt: off return AbsoluteBindingSettings( protocol_repeats=3, forcefield_settings=settings.OpenMMSystemGeneratorFFSettings(), thermo_settings=settings.ThermoSettings( temperature=298.15 * offunit.kelvin, pressure=1 * offunit.bar, ), alchemical_settings=AlchemicalSettings(), solvent_lambda_settings=LambdaSettings( lambda_elec=[ 0.0, 0.25, 0.5, 0.75, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, ], lambda_vdw=[ 0.0, 0.0, 0.0, 0.0, 0.0, 0.12, 0.24, 0.36, 0.48, 0.6, 0.7, 0.77, 0.85, 1.0 ], lambda_restraints=[ 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 ], ), complex_lambda_settings=LambdaSettings( lambda_elec=[ 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.00, 1.0, 1.00, 1.0, 1.00, 1.0, 1.00, 1.0 ], lambda_vdw=[ 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.65, 0.7, 0.75, 0.8, 0.85, 0.9, 0.95, 1.0 ], lambda_restraints=[ 0.0, 0.2, 0.4, 0.6, 0.8, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.00, 1.0, 1.00, 1.0, 1.00, 1.0, 1.00, 1.0 ], ), partial_charge_settings=OpenFFPartialChargeSettings(), complex_solvation_settings=OpenMMSolvationSettings( solvent_padding=1.0 * offunit.nanometer, ), solvent_solvation_settings=OpenMMSolvationSettings(), engine_settings=OpenMMEngineSettings(), solvent_integrator_settings=IntegratorSettings(), complex_integrator_settings=IntegratorSettings(), restraint_settings=BoreschRestraintSettings(), solvent_equil_simulation_settings=MDSimulationSettings( equilibration_length_nvt=0.1 * offunit.nanosecond, equilibration_length=0.2 * offunit.nanosecond, production_length=0.5 * offunit.nanosecond, ), solvent_equil_output_settings=ABFEPreEquilOutputSettings(), solvent_simulation_settings=MultiStateSimulationSettings( n_replicas=14, equilibration_length=1.0 * offunit.nanosecond, production_length=10.0 * offunit.nanosecond, ), solvent_output_settings=MultiStateOutputSettings( output_structure="alchemical_system.pdb", output_filename="solvent.nc", checkpoint_storage_filename="solvent_checkpoint.nc", ), complex_equil_simulation_settings=MDSimulationSettings( equilibration_length_nvt=0.25 * offunit.nanosecond, equilibration_length=0.5 * offunit.nanosecond, production_length=5.0 * offunit.nanosecond, ), complex_equil_output_settings=ABFEPreEquilOutputSettings(), complex_simulation_settings=MultiStateSimulationSettings( n_replicas=30, equilibration_length=1 * offunit.nanosecond, production_length=10.0 * offunit.nanosecond, ), complex_output_settings=MultiStateOutputSettings( output_structure="alchemical_system.pdb", output_filename="complex.nc", checkpoint_storage_filename="complex_checkpoint.nc", ), ) # fmt: on @classmethod def _adaptive_settings( cls, stateA: ChemicalSystem, stateB: ChemicalSystem, initial_settings: None | AbsoluteBindingSettings = None, ) -> AbsoluteBindingSettings: """ Get the recommended OpenFE settings for this Protocol based on the input states involved in the transformation. These are intended as a suitable starting point, which can be further customized before creating a Protocol. Parameters ---------- stateA : ChemicalSystem The initial state of the transformation. stateB : ChemicalSystem The final state of the transformation. initial_settings : None | AbsoluteBindingSettings, optional Initial settings to adapt. If None, default settings are used. Returns ------- AbsoluteBindingSettings The recommended settings for this protocol based on the input states. """ # use initial settings or default settings if initial_settings is not None: protocol_settings = initial_settings.model_copy(deep=True) else: protocol_settings = cls.default_settings() # adapt the barostat based on the ProteinComponent if stateA.contains(ProteinMembraneComponent): protocol_settings.complex_integrator_settings.barostat = "MonteCarloMembraneBarostat" return protocol_settings @staticmethod def _validate_endstates( stateA: ChemicalSystem, stateB: ChemicalSystem, ) -> None: """ A binding transformation is defined (in terms of gufe components) as starting from one or more ligands with one protein and solvent, that then ends up in a state with one less ligand. Parameters ---------- stateA : ChemicalSystem The chemical system of end state A stateB : ChemicalSystem The chemical system of end state B Raises ------ ValueError If stateA & stateB do not contain a ProteinComponent. If stateA & stateB do not contain a SolventComponent. If stateA has more than one unique Component. If the stateA unique Component is not a SmallMoleculeComponent. If stateB contains any unique Components. If the alchemical species is charged. """ if not (stateA.contains(ProteinComponent) and stateB.contains(ProteinComponent)): errmsg = "No ProteinComponent found" raise ValueError(errmsg) if not (stateA.contains(SolventComponent) and stateB.contains(SolventComponent)): errmsg = "No SolventComponent found" raise ValueError(errmsg) # Needs gufe 1.3 diff = stateA.component_diff(stateB) if len(diff[0]) != 1: errmsg = ( "Only one alchemical species is supported. " f"Number of unique components found in stateA: {len(diff[0])}." ) raise ValueError(errmsg) if not isinstance(diff[0][0], SmallMoleculeComponent): errmsg = ( "Only disappearing small molecule components " "are supported by this protocol. " f"Found a {type(diff[0][0])}" ) raise ValueError(errmsg) # Check that the state A unique isn't charged if diff[0][0].total_charge != 0: errmsg = ( "Charged alchemical molecules are not currently " "supported for solvation free energies. " f"Molecule total charge: {diff[0][0].total_charge}." ) raise ValueError(errmsg) # If there are any alchemical Components in state B if len(diff[1]) > 0: errmsg = "Components appearing in state B are not currently supported" raise ValueError(errmsg) @staticmethod def _validate_lambda_schedule( lambda_settings: LambdaSettings, simulation_settings: MultiStateSimulationSettings, ) -> None: """ Checks that the lambda schedule is set up correctly. Parameters ---------- lambda_settings : LambdaSettings the lambda schedule Settings simulation_settings : MultiStateSimulationSettings the settings for either the complex or solvent phase Raises ------ ValueError If the number of lambda windows differs for electrostatics, sterics, and restraints. If the number of replicas does not match the number of lambda windows. If there are states with naked charges. """ lambda_elec = lambda_settings.lambda_elec lambda_vdw = lambda_settings.lambda_vdw lambda_restraints = lambda_settings.lambda_restraints n_replicas = simulation_settings.n_replicas # Ensure that all lambda components have equal amount of windows lambda_components = [lambda_vdw, lambda_elec, lambda_restraints] it = iter(lambda_components) the_len = len(next(it)) if not all(len(lambda_comp) == the_len for lambda_comp in it): errmsg = ( "Components elec, vdw, and restraints must have equal amount" f" of lambda windows. Got {len(lambda_elec)} elec lambda" f" windows, {len(lambda_vdw)} vdw lambda windows, and" f"{len(lambda_restraints)} restraints lambda windows." ) raise ValueError(errmsg) # Ensure that number of overall lambda windows matches number of lambda # windows for individual components if n_replicas != len(lambda_vdw): errmsg = ( f"Number of replicas {n_replicas} does not equal the" f" number of lambda windows {len(lambda_vdw)}" ) raise ValueError(errmsg) # Check if there are no lambda windows with naked charges for inx, lam in enumerate(lambda_elec): if lam < 1 and lambda_vdw[inx] == 1: errmsg = ( "There are states along this lambda schedule " "where there are atoms with charges but no LJ " f"interactions: lambda {inx}: " f"elec {lam} vdW {lambda_vdw[inx]}" ) raise ValueError(errmsg) def _validate( self, *, stateA: ChemicalSystem, stateB: ChemicalSystem, mapping: gufe.ComponentMapping | list[gufe.ComponentMapping] | None = None, extends: gufe.ProtocolDAGResult | None = None, ): # Check we're not extending if extends is not None: # This technically should be NotImplementedError # but gufe.Protocol.validate calls `_validate` wrapped around an # except for NotImplementedError, so we can't raise it here raise ValueError("Can't extend simulations yet") # Check we're not using a mapping, since we're not doing anything with it if mapping is not None: wmsg = "A mapping was passed but is not used by this Protocol." warnings.warn(wmsg) # Validate the end states & alchemical components system_validation.validate_chemical_system(stateA) system_validation.validate_chemical_system(stateB) self._validate_endstates(stateA, stateB) # Validate the complex lambda schedule self._validate_lambda_schedule( self.settings.complex_lambda_settings, self.settings.complex_simulation_settings, ) # If the complex restraints schedule is all zero, it might be bad # but we don't disallow it. if all([i == 0.0 for i in self.settings.complex_lambda_settings.lambda_restraints]): wmsg = ( "No restraints are being applied in the complex phase, " "this will likely lead to problematic results." ) warnings.warn(wmsg) # Validate the solvent lambda schedule self._validate_lambda_schedule( self.settings.solvent_lambda_settings, self.settings.solvent_simulation_settings, ) # If the solvent restraints schedule is not all one, it was likely # copied from the complex schedule. In this case we just ignore # the values and let the user know. # P.S. we don't need to change the settings at this point # the list gets popped out later in the SolventUnit, because we # don't have a restraint parameter state. if any([i != 0.0 for i in self.settings.solvent_lambda_settings.lambda_restraints]): wmsg = ( "There is an attempt to add restraints in the solvent " "phase. This protocol does not apply restraints in the " "solvent phase. These restraint lambda values will be ignored." ) warnings.warn(wmsg) # Check nonbond & solvent compatibility nonbonded_method = self.settings.forcefield_settings.nonbonded_method # Use the more complete system validation solvent checks system_validation.validate_solvent(stateA, nonbonded_method) # Validate the barostat used in combination with the protein component system_validation.validate_barostat( stateA, self.settings.complex_integrator_settings.barostat ) # Validate solvation settings settings_validation.validate_openmm_solvation_settings( self.settings.solvent_solvation_settings ) settings_validation.validate_openmm_solvation_settings( self.settings.complex_solvation_settings ) # Validate integrator things # We validate the timstep for both the complex & solvent settings settings_validation.validate_timestep( self.settings.forcefield_settings.hydrogen_mass, self.settings.complex_integrator_settings.timestep, ) settings_validation.validate_timestep( self.settings.forcefield_settings.hydrogen_mass, self.settings.solvent_integrator_settings.timestep, ) def _create( self, stateA: ChemicalSystem, stateB: ChemicalSystem, mapping: gufe.ComponentMapping | list[gufe.ComponentMapping] | None = None, extends: gufe.ProtocolDAGResult | None = None, ) -> list[gufe.ProtocolUnit]: # Validate inputs self.validate(stateA=stateA, stateB=stateB, mapping=mapping, extends=extends) # Get the alchemical components alchem_comps = system_validation.get_alchemical_components( stateA, stateB, ) # Get the name of the alchemical species alchname = alchem_comps["stateA"][0].name unit_classes: dict[str, dict[str, type[gufe.ProtocolUnit]]] = { "solvent": { "setup": ABFESolventSetupUnit, "simulation": ABFESolventSimUnit, "analysis": ABFESolventAnalysisUnit, }, "complex": { "setup": ABFEComplexSetupUnit, "simulation": ABFEComplexSimUnit, "analysis": ABFEComplexAnalysisUnit, }, } protocol_units: dict[str, list[gufe.ProtocolUnit]] = {"solvent": [], "complex": []} for phase in ["solvent", "complex"]: for i in range(self.settings.protocol_repeats): repeat_id = int(uuid.uuid4()) setup = unit_classes[phase]["setup"]( protocol=self, stateA=stateA, stateB=stateB, alchemical_components=alchem_comps, generation=0, repeat_id=repeat_id, name=f"ABFE Setup: {alchname} {phase} leg: repeat {i} generation 0", ) simulation = unit_classes[phase]["simulation"]( protocol=self, # only need state A & alchem comps stateA=stateA, alchemical_components=alchem_comps, setup_results=setup, generation=0, repeat_id=repeat_id, name=f"ABFE Simulation: {alchname} {phase} leg: repeat {i} generation 0", ) analysis = unit_classes[phase]["analysis"]( protocol=self, setup_results=setup, simulation_results=simulation, generation=0, repeat_id=repeat_id, name=f"ABFE Analysis: {alchname} {phase} leg, repeat {i} generation 0", ) protocol_units[phase] += [setup, simulation, analysis] return protocol_units["solvent"] + protocol_units["complex"] def _gather( self, protocol_dag_results: Iterable[gufe.ProtocolDAGResult] ) -> dict[str, dict[str, Any]]: # result units will have a repeat_id and generation # first group according to repeat_id unsorted_solvent_repeats = defaultdict(list) unsorted_complex_repeats = defaultdict(list) for d in protocol_dag_results: pu: gufe.ProtocolUnitResult for pu in d.protocol_unit_results: if ("Analysis" not in pu.name) or (not pu.ok()): continue if pu.outputs["simtype"] == "solvent": unsorted_solvent_repeats[pu.outputs["repeat_id"]].append(pu) else: unsorted_complex_repeats[pu.outputs["repeat_id"]].append(pu) repeats: dict[str, dict[str, list[gufe.ProtocolUnitResult]]] = { "solvent": {}, "complex": {}, } for k, v in unsorted_solvent_repeats.items(): repeats["solvent"][str(k)] = sorted(v, key=lambda x: x.outputs["generation"]) for k, v in unsorted_complex_repeats.items(): repeats["complex"][str(k)] = sorted(v, key=lambda x: x.outputs["generation"]) return repeats ================================================ FILE: src/openfe/protocols/openmm_afe/equil_solvation_afe_method.py ================================================ # This code is part of OpenFE and is licensed under the MIT license. # For details, see https://github.com/OpenFreeEnergy/openfe """OpenMM Equilibrium Solvation AFE Protocol --- :mod:`openfe.protocols.openmm_afe.equil_solvation_afe_method` =============================================================================================================== This module implements the necessary methodology tooling to run calculate an absolute solvation free energy using OpenMM tools and one of the following alchemical sampling methods: * Hamiltonian Replica Exchange * Self-adjusted mixture sampling * Independent window sampling Current limitations ------------------- * Alchemical species with a net charge are not currently supported. * Disappearing molecules are only allowed in state A. Support for appearing molecules will be added in due course. * Only small molecules are allowed to act as alchemical molecules. Alchemically changing protein or solvent components would induce perturbations which are too large to be handled by this Protocol. Acknowledgements ---------------- * Originally based on hydration.py in `espaloma_charge `_ """ import logging import uuid import warnings from collections import defaultdict from typing import Any, Iterable, Optional, Union import gufe import numpy as np from gufe import ( ChemicalSystem, ProteinComponent, SmallMoleculeComponent, SolventComponent, settings, ) from openff.units import unit as offunit from openfe.due import Doi, due from openfe.protocols.openmm_afe.equil_afe_settings import ( AbsoluteSolvationSettings, AlchemicalSettings, IntegratorSettings, LambdaSettings, MDOutputSettings, MDSimulationSettings, MultiStateOutputSettings, MultiStateSimulationSettings, OpenFFPartialChargeSettings, OpenMMEngineSettings, OpenMMSolvationSettings, ) from ..openmm_utils import settings_validation, system_validation from .afe_protocol_results import AbsoluteSolvationProtocolResult from .ahfe_units import ( AHFESolventAnalysisUnit, AHFESolventSetupUnit, AHFESolventSimUnit, AHFEVacuumAnalysisUnit, AHFEVacuumSetupUnit, AHFEVacuumSimUnit, ) due.cite( Doi("10.5281/zenodo.596504"), description="Yank", path="openfe.protocols.openmm_afe.equil_solvation_afe_method", cite_module=True, ) due.cite( Doi("10.48550/ARXIV.2302.06758"), description="EspalomaCharge", path="openfe.protocols.openmm_afe.equil_solvation_afe_method", cite_module=True, ) due.cite( Doi("10.5281/zenodo.596622"), description="OpenMMTools", path="openfe.protocols.openmm_afe.equil_solvation_afe_method", cite_module=True, ) due.cite( Doi("10.1371/journal.pcbi.1005659"), description="OpenMM", path="openfe.protocols.openmm_afe.equil_solvation_afe_method", cite_module=True, ) logger = logging.getLogger(__name__) class AbsoluteSolvationProtocol(gufe.Protocol): """ Absolute solvation free energy calculations using OpenMM and OpenMMTools. See Also -------- :mod:`openfe.protocols` :class:`openfe.protocols.openmm_afe.AbsoluteSolvationSettings` :class:`openfe.protocols.openmm_afe.AbsoluteSolvationProtocolResult` :class:`openfe.protocols.openmm_afe.AbsoluteSolvationVacuumUnit` :class:`openfe.protocols.openmm_afe.AbsoluteSolvationSolventUnit` """ result_cls = AbsoluteSolvationProtocolResult _settings_cls = AbsoluteSolvationSettings _settings: AbsoluteSolvationSettings @classmethod def _default_settings(cls): """A dictionary of initial settings for this creating this Protocol These settings are intended as a suitable starting point for creating an instance of this protocol. It is recommended, however that care is taken to inspect and customize these before performing a Protocol. Returns ------- Settings a set of default settings """ return AbsoluteSolvationSettings( protocol_repeats=3, solvent_forcefield_settings=settings.OpenMMSystemGeneratorFFSettings(), vacuum_forcefield_settings=settings.OpenMMSystemGeneratorFFSettings( nonbonded_method="nocutoff", ), thermo_settings=settings.ThermoSettings( temperature=298.15 * offunit.kelvin, pressure=1 * offunit.bar, ), alchemical_settings=AlchemicalSettings(), lambda_settings=LambdaSettings( lambda_elec=[ 0.0, 0.25, 0.5, 0.75, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0], lambda_vdw=[ 0.0, 0.0, 0.0, 0.0, 0.0, 0.12, 0.24, 0.36, 0.48, 0.6, 0.7, 0.77, 0.85, 1.0], lambda_restraints=[ 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], ), partial_charge_settings=OpenFFPartialChargeSettings(), solvation_settings=OpenMMSolvationSettings(), vacuum_engine_settings=OpenMMEngineSettings(), solvent_engine_settings=OpenMMEngineSettings(), integrator_settings=IntegratorSettings(), solvent_equil_simulation_settings=MDSimulationSettings( equilibration_length_nvt=0.1 * offunit.nanosecond, equilibration_length=0.2 * offunit.nanosecond, production_length=0.5 * offunit.nanosecond, ), solvent_equil_output_settings=MDOutputSettings( equil_nvt_structure="equil_nvt_structure.pdb", equil_npt_structure="equil_npt_structure.pdb", production_trajectory_filename="production_equil.xtc", log_output="equil_simulation.log", ), solvent_simulation_settings=MultiStateSimulationSettings( n_replicas=14, equilibration_length=1.0 * offunit.nanosecond, production_length=10.0 * offunit.nanosecond, ), solvent_output_settings=MultiStateOutputSettings( output_filename="solvent.nc", checkpoint_storage_filename="solvent_checkpoint.nc", ), vacuum_equil_simulation_settings=MDSimulationSettings( equilibration_length_nvt=None, equilibration_length=0.2 * offunit.nanosecond, production_length=0.5 * offunit.nanosecond, ), vacuum_equil_output_settings=MDOutputSettings( equil_nvt_structure=None, equil_npt_structure="equil_structure.pdb", production_trajectory_filename="production_equil.xtc", log_output="equil_simulation.log", ), vacuum_simulation_settings=MultiStateSimulationSettings( n_replicas=14, equilibration_length=0.5 * offunit.nanosecond, production_length=2.0 * offunit.nanosecond, ), vacuum_output_settings=MultiStateOutputSettings( output_filename="vacuum.nc", checkpoint_storage_filename="vacuum_checkpoint.nc", ), ) # fmt: skip @staticmethod def _validate_endstates( stateA: ChemicalSystem, stateB: ChemicalSystem, ) -> None: """ A solvent transformation is defined (in terms of gufe components) as starting from one or more ligands in solvent and ending up in a state with one less ligand. No protein components are allowed. Parameters ---------- stateA : ChemicalSystem The chemical system of end state A stateB : ChemicalSystem The chemical system of end state B Raises ------ ValueError If stateA or stateB contains a ProteinComponent. If there is no SolventComponent in either stateA or stateB. If there are alchemical components in state B. If there are non SmallMoleculeComponent alchemical species. If there are more than one alchemical species. If the alchemical species is charged. Notes ----- * Currently doesn't support alchemical components in state B. * Currently doesn't support alchemical components which are not SmallMoleculeComponents. * Currently doesn't support more than one alchemical component being desolvated. * Currently doesn't support charged alchemical components. * Solvent must always be present in both end states. """ # Check that there are no protein components if stateA.contains(ProteinComponent) or stateB.contains(ProteinComponent): errmsg = "Protein components are not allowed for absolute solvation free energies." raise ValueError(errmsg) # Check that there is a solvent component in both end states if not (stateA.contains(SolventComponent) and stateB.contains(SolventComponent)): errmsg = "No SolventComponent found in stateA and/or stateB" raise ValueError(errmsg) # Now we check the alchemical Components diff = stateA.component_diff(stateB) # Check that there's only one state A unique Component if len(diff[0]) != 1: errmsg = ( "Only one alchemical species is supported " "for absolute solvation free energies. " f"Number of unique components found in stateA: {len(diff[0])}." ) raise ValueError(errmsg) # Make sure that the state A unique is an SMC if not isinstance(diff[0][0], SmallMoleculeComponent): errmsg = ( "Only disappearing SmallMoleculeComponents " "are supported by this protocol. " f"Found a {type(diff[0][0])}" ) raise ValueError(errmsg) # Check that the state A unique isn't charged if diff[0][0].total_charge != 0: errmsg = ( "Charged alchemical molecules are not currently " "supported for solvation free energies. " f"Molecule total charge: {diff[0][0].total_charge}." ) raise ValueError(errmsg) # If there are any alchemical Components in state B if len(diff[1]) > 0: errmsg = "Components appearing in state B are not currently supported" raise ValueError(errmsg) @staticmethod def _validate_lambda_schedule( lambda_settings: LambdaSettings, simulation_settings: MultiStateSimulationSettings, ) -> None: """ Checks that the lambda schedule is set up correctly. Parameters ---------- lambda_settings : LambdaSettings the lambda schedule Settings simulation_settings : MultiStateSimulationSettings the settings for either the vacuum or solvent phase Raises ------ ValueError If the number of lambda windows differs for electrostatics and sterics. If the number of replicas does not match the number of lambda windows. If there are states with naked charges. Warnings If there are non-zero values for restraints (lambda_restraints). """ lambda_elec = lambda_settings.lambda_elec lambda_vdw = lambda_settings.lambda_vdw lambda_restraints = lambda_settings.lambda_restraints n_replicas = simulation_settings.n_replicas # Ensure that all lambda components have equal amount of windows lambda_components = [lambda_vdw, lambda_elec, lambda_restraints] it = iter(lambda_components) the_len = len(next(it)) if not all(len(lambda_comp) == the_len for lambda_comp in it): errmsg = ( "Components elec, vdw, and restraints must have equal amount" f" of lambda windows. Got {len(lambda_elec)} elec lambda" f" windows, {len(lambda_vdw)} vdw lambda windows, and" f"{len(lambda_restraints)} restraints lambda windows." ) raise ValueError(errmsg) # Ensure that number of overall lambda windows matches number of lambda # windows for individual components if n_replicas != len(lambda_vdw): errmsg = ( f"Number of replicas {n_replicas} does not equal the" f" number of lambda windows {len(lambda_vdw)}" ) raise ValueError(errmsg) # Check if there are lambda windows with naked charges for inx, lam in enumerate(lambda_elec): if lam < 1 and lambda_vdw[inx] == 1: errmsg = ( "There are states along this lambda schedule " "where there are atoms with charges but no LJ " f"interactions: lambda {inx}: " f"elec {lam} vdW {lambda_vdw[inx]}" ) raise ValueError(errmsg) # Check if there are lambda windows with non-zero restraints if len([r for r in lambda_restraints if r != 0]) > 0: wmsg = ( "Non-zero restraint lambdas applied. The absolute " "solvation protocol doesn't apply restraints, " "therefore restraints won't be applied. " f"Given lambda_restraints: {lambda_restraints}" ) logger.warning(wmsg) warnings.warn(wmsg) def _validate( self, *, stateA: ChemicalSystem, stateB: ChemicalSystem, mapping: Optional[Union[gufe.ComponentMapping, list[gufe.ComponentMapping]]] = None, extends: Optional[gufe.ProtocolDAGResult] = None, ): # Check we're not extending if extends is not None: # This should be a NotImplementedError, but the underlying # `validate` method wraps a call to `_validate` around a # NotImplementedError exception guard raise ValueError("Can't extend simulations yet") # Check we're not using a mapping, since we're not doing anything with it if mapping is not None: wmsg = "A mapping was passed but is not used by this Protocol." warnings.warn(wmsg) # Validate the endstates & alchemical components system_validation.validate_chemical_system(stateA) system_validation.validate_chemical_system(stateB) self._validate_endstates(stateA, stateB) # Validate the lambda schedule for solv_sets in ( self.settings.solvent_simulation_settings, self.settings.vacuum_simulation_settings, ): self._validate_lambda_schedule( self.settings.lambda_settings, solv_sets, ) # Check nonbond & solvent compatibility solv_nonbonded_method = self.settings.solvent_forcefield_settings.nonbonded_method vac_nonbonded_method = self.settings.vacuum_forcefield_settings.nonbonded_method # Use the more complete system validation solvent checks system_validation.validate_solvent(stateA, solv_nonbonded_method) # Gas phase is always gas phase if vac_nonbonded_method.lower() != "nocutoff": errmsg = ( "Only the nocutoff nonbonded_method is supported for " f"vacuum calculations, {vac_nonbonded_method} was " "passed" ) raise ValueError(errmsg) # Validate solvation settings settings_validation.validate_openmm_solvation_settings(self.settings.solvation_settings) # Check vacuum equilibration MD settings is 0 ns nvt_time = self.settings.vacuum_equil_simulation_settings.equilibration_length_nvt if nvt_time is not None: if not np.allclose(nvt_time, 0 * offunit.nanosecond): errmsg = "NVT equilibration cannot be run in vacuum simulation" raise ValueError(errmsg) # Validate integrator things settings_validation.validate_timestep( self.settings.vacuum_forcefield_settings.hydrogen_mass, self.settings.integrator_settings.timestep, ) settings_validation.validate_timestep( self.settings.solvent_forcefield_settings.hydrogen_mass, self.settings.integrator_settings.timestep, ) def _create( self, stateA: ChemicalSystem, stateB: ChemicalSystem, mapping: Optional[Union[gufe.ComponentMapping, list[gufe.ComponentMapping]]] = None, extends: Optional[gufe.ProtocolDAGResult] = None, ) -> list[gufe.ProtocolUnit]: # Validate inputs self.validate(stateA=stateA, stateB=stateB, mapping=mapping, extends=extends) # Get the alchemical components alchem_comps = system_validation.get_alchemical_components( stateA, stateB, ) # Get the name of the alchemical species alchname = alchem_comps["stateA"][0].name unit_classes: dict[str, dict[str, type[gufe.ProtocolUnit]]] = { "solvent": { "setup": AHFESolventSetupUnit, "simulation": AHFESolventSimUnit, "analysis": AHFESolventAnalysisUnit, }, "vacuum": { "setup": AHFEVacuumSetupUnit, "simulation": AHFEVacuumSimUnit, "analysis": AHFEVacuumAnalysisUnit, }, } protocol_units: dict[str, list[gufe.ProtocolUnit]] = {"solvent": [], "vacuum": []} for phase in ["solvent", "vacuum"]: for i in range(self.settings.protocol_repeats): repeat_id = int(uuid.uuid4()) setup = unit_classes[phase]["setup"]( protocol=self, stateA=stateA, stateB=stateB, alchemical_components=alchem_comps, generation=0, repeat_id=repeat_id, name=f"AHFE Setup: {alchname} {phase} leg: repeat {i} generation 0", ) simulation = unit_classes[phase]["simulation"]( protocol=self, # only need state A & alchem comps stateA=stateA, alchemical_components=alchem_comps, setup_results=setup, generation=0, repeat_id=repeat_id, name=f"AHFE Simulation: {alchname} {phase} leg: repeat {i} generation 0", ) analysis = unit_classes[phase]["analysis"]( protocol=self, setup_results=setup, simulation_results=simulation, generation=0, repeat_id=repeat_id, name=f"AHFE Analysis: {alchname} {phase} leg, repeat {i} generation 0", ) protocol_units[phase] += [setup, simulation, analysis] return protocol_units["solvent"] + protocol_units["vacuum"] def _gather( self, protocol_dag_results: Iterable[gufe.ProtocolDAGResult] ) -> dict[str, dict[str, Any]]: # result units will have a repeat_id and generation # first group according to repeat_id unsorted_solvent_repeats = defaultdict(list) unsorted_vacuum_repeats = defaultdict(list) for d in protocol_dag_results: pu: gufe.ProtocolUnitResult for pu in d.protocol_unit_results: if ("Analysis" not in pu.name) or (not pu.ok()): continue if pu.outputs["simtype"] == "solvent": unsorted_solvent_repeats[pu.outputs["repeat_id"]].append(pu) else: unsorted_vacuum_repeats[pu.outputs["repeat_id"]].append(pu) repeats: dict[str, dict[str, list[gufe.ProtocolUnitResult]]] = { "solvent": {}, "vacuum": {}, } for k, v in unsorted_solvent_repeats.items(): repeats["solvent"][str(k)] = sorted(v, key=lambda x: x.outputs["generation"]) for k, v in unsorted_vacuum_repeats.items(): repeats["vacuum"][str(k)] = sorted(v, key=lambda x: x.outputs["generation"]) return repeats ================================================ FILE: src/openfe/protocols/openmm_md/__init__.py ================================================ # This code is part of OpenFE and is licensed under the MIT license. # For details, see https://github.com/OpenFreeEnergy/openfe """ Run MD simulation using OpenMM and OpenMMTools. """ from .plain_md_methods import ( PlainMDProtocol, PlainMDProtocolResult, PlainMDProtocolSettings, PlainMDSetupUnit, PlainMDSimulationUnit, ) __all__ = [ "PlainMDProtocol", "PlainMDProtocolSettings", "PlainMDProtocolResult", "PlainMDSetupUnit", "PlainMDSimulationUnit", ] ================================================ FILE: src/openfe/protocols/openmm_md/plain_md_methods.py ================================================ # This code is part of OpenFE and is licensed under the MIT license. # For details, see https://github.com/OpenFreeEnergy/openfe """OpenMM MD Protocol --- :mod:`openfe.protocols.openmm_md.plain_md_methods` =========================================================================================== This module implements the necessary methodology tools to run an MD simulation using OpenMM tools. """ from __future__ import annotations import logging import pathlib import time import uuid import warnings from collections import defaultdict from typing import Any, Iterable, Optional import gufe import mdtraj import numpy as np import openmm import openmm.unit as omm_unit from gufe import ( BaseSolventComponent, ChemicalSystem, SmallMoleculeComponent, SolvatedPDBComponent, settings, ) from gufe.protocols.errors import ProtocolUnitExecutionError from gufe.settings.typing import KelvinQuantity from mdtraj.reporters import XTCReporter from openff.toolkit.topology import Molecule as OFFMolecule from openff.units import Quantity, unit from openff.units.openmm import from_openmm, to_openmm from openmm import MonteCarloBarostat, MonteCarloMembraneBarostat import openfe from openfe.protocols.openmm_md.plain_md_settings import ( IntegratorSettings, MDOutputSettings, MDSimulationSettings, OpenFFPartialChargeSettings, OpenMMEngineSettings, OpenMMSolvationSettings, PlainMDProtocolSettings, ) from openfe.protocols.openmm_utils import ( charge_generation, omm_compute, serialization, settings_validation, system_creation, system_validation, ) from openfe.protocols.openmm_utils.omm_settings import ( BasePartialChargeSettings, FemtosecondQuantity, ) from openfe.utils import log_system_probe, without_oechem_backend logger = logging.getLogger(__name__) class PlainMDProtocolResult(gufe.ProtocolResult): """ Dict-like container for the output of a PlainMDProtocol. Provides access to simulation outputs including the pre-minimized system PDB and production trajectory files. """ def __init__(self, **data): super().__init__(**data) # data is mapping of str(repeat_id): list[protocolunitresults] if any(len(pur_list) > 2 for pur_list in self.data.values()): raise NotImplementedError("Can't stitch together results yet") def get_estimate(self): """Since no results as output --> returns None Returns ------- None """ return None def get_uncertainty(self): """Since no results as output --> returns None""" return None def get_traj_filename(self) -> list[pathlib.Path]: """ Get a list of trajectory paths Returns ------- traj : list[pathlib.Path] list of paths (pathlib.Path) to the simulation trajectory """ traj = [pus[0].outputs["nc"] for pus in self.data.values()] return traj def get_pdb_filename(self) -> list[pathlib.Path]: """ Get a list of paths to the pdb files of the pre-minimized system. Returns ------- pdbs : list[pathlib.Path] list of paths (pathlib.Path) to the pdb files """ pdbs = [pus[0].outputs["system_pdb"] for pus in self.data.values()] return pdbs class PlainMDProtocol(gufe.Protocol): """ Protocol for running Molecular Dynamics simulations using OpenMM. See Also -------- :mod:`openfe.protocols` :class:`openfe.protocols.openmm_md.PlainMDProtocolSettings` :class:`openfe.protocols.openmm_md.PlainMDProtocolUnit` :class:`openfe.protocols.openmm_md.PlainMDProtocolResult` """ result_cls = PlainMDProtocolResult _settings_cls = PlainMDProtocolSettings _settings: PlainMDProtocolSettings @classmethod def _default_settings(cls): """A dictionary of initial settings for this creating this Protocol These settings are intended as a suitable starting point for creating an instance of this protocol. It is recommended, however that care is taken to inspect and customize these before performing a Protocol. Returns ------- Settings a set of default settings """ return PlainMDProtocolSettings( forcefield_settings=settings.OpenMMSystemGeneratorFFSettings(), thermo_settings=settings.ThermoSettings( temperature=298.15 * unit.kelvin, pressure=1 * unit.bar, ), partial_charge_settings=OpenFFPartialChargeSettings(), solvation_settings=OpenMMSolvationSettings(), engine_settings=OpenMMEngineSettings(), integrator_settings=IntegratorSettings(), simulation_settings=MDSimulationSettings( equilibration_length_nvt=0.1 * unit.nanosecond, equilibration_length=1.0 * unit.nanosecond, production_length=5.0 * unit.nanosecond, ), output_settings=MDOutputSettings(checkpoint_storage_filename="checkpoint.xml"), protocol_repeats=1, ) def _validate( self, stateA: ChemicalSystem, stateB: ChemicalSystem, mapping: Optional[dict[str, gufe.ComponentMapping]] = None, extends: Optional[gufe.ProtocolDAGResult] = None, ): # Check we're not extending if extends is not None: # This technically should be NotImplementedError # but gufe.Protocol.validate calls `_validate` wrapped around an # except for NotImplementedError, so we can't raise it here raise ValueError("Can't extend simulations yet") # Check we're not using a mapping, since we're not doing anything with it if mapping is not None: wmsg = "A mapping was passed but is not used by this Protocol." warnings.warn(wmsg) # check that stateA and stateB are the same if stateA is not stateB: errmsg = "The two end states do not match." raise ValueError(errmsg) # Validate the ChemicalSystem system_validation.validate_chemical_system(stateA) # Validate solvent component if present nonbond = self.settings.forcefield_settings.nonbonded_method system_validation.validate_solvent(stateA, nonbond) # Validate the BaseSolventComponents base_solvent = stateA.get_components_of_type(BaseSolventComponent) if len(base_solvent) > 1: errmsg = "Multiple BaseSolventComponents found, only one is supported." raise ValueError(errmsg) # Validate protein component if present system_validation.validate_protein(stateA) # Validate the barostat used in combination with the protein component system_validation.validate_barostat(stateA, self.settings.integrator_settings.barostat) # Validate solvation settings settings_validation.validate_openmm_solvation_settings(self.settings.solvation_settings) # is the timestep good for the mass? settings_validation.validate_timestep( self.settings.forcefield_settings.hydrogen_mass, self.settings.integrator_settings.timestep, ) def _create( self, stateA: ChemicalSystem, stateB: ChemicalSystem, mapping: Optional[dict[str, gufe.ComponentMapping]] = None, extends: Optional[gufe.ProtocolDAGResult] = None, ) -> list[gufe.ProtocolUnit]: # validate the inputs self.validate(stateA=stateA, stateB=stateB, mapping=mapping, extends=extends) # actually create and return Units # TODO: Deal with multiple ProteinComponents solvent_comp, protein_comp, small_mols = system_validation.get_components(stateA) system_name = "Solvent MD" if stateA.contains(BaseSolventComponent) else "Vacuum MD" for comp in [protein_comp] + small_mols: if comp is not None: comp_type = comp.__class__.__name__ if len(comp.name) == 0: comp_name = "NoName" else: comp_name = comp.name system_name += f" {comp_type}:{comp_name}" # make the DAG from the setup and simulation units n_repeats = self.settings.protocol_repeats units = [] for i in range(n_repeats): repeat_id = int(uuid.uuid4()) setup = PlainMDSetupUnit( protocol=self, stateA=stateA, generation=0, repeat_id=repeat_id, name=f"MD Setup: {system_name} repeat {i} generation 0", ) sim = PlainMDSimulationUnit( protocol=self, stateA=stateA, generation=0, repeat_id=repeat_id, setup_results=setup, name=f"MD Simulation: {system_name} repeat {i} generation 0", ) units.extend([setup, sim]) return units def _gather(self, protocol_dag_results: Iterable[gufe.ProtocolDAGResult]) -> dict[str, Any]: # result units will have a repeat_id and generations within this # repeat_id # first group according to repeat_id unsorted_repeats = defaultdict(list) for d in protocol_dag_results: pu: gufe.ProtocolUnitResult for pu in d.protocol_unit_results: # Only keep the simulation units which are ok if ("Simulation" not in pu.name) or (not pu.ok()): continue unsorted_repeats[pu.outputs["repeat_id"]].append(pu) # then sort by generation within each repeat_id list repeats: dict[str, list[gufe.ProtocolUnitResult]] = {} for k, v in unsorted_repeats.items(): repeats[str(k)] = sorted(v, key=lambda x: x.outputs["generation"]) # returns a dict of repeat_id: sorted list of ProtocolUnitResult return repeats class PlainMDUnitMixin: def _prepare( self, verbose: bool, scratch_basepath: pathlib.Path | None, shared_basepath: pathlib.Path | None, ): """ Set basepaths and do some initial logging. Parameters ---------- verbose : bool Verbose output of the simulation progress. Output is provided via INFO level logging. scratch_basepath : pathlib.Path | None Optional base path to write scratch files to. shared_basepath : pathlib.Path | None Optional base path to write shared files to. """ self.verbose = verbose # set basepaths def _set_optional_path(basepath): if basepath is None: return pathlib.Path(".") return basepath self.scratch_basepath = _set_optional_path(scratch_basepath) self.shared_basepath = _set_optional_path(shared_basepath) class PlainMDSetupUnit(PlainMDUnitMixin, gufe.ProtocolUnit): """ Protocol setup unit for plain MD simulations which handles charging, system building and solvation. """ @staticmethod def _assign_partial_charges( charge_settings: OpenFFPartialChargeSettings, smc_components: dict[SmallMoleculeComponent, OFFMolecule], ) -> None: """ Assign partial charges to SMCs. Parameters ---------- charge_settings : OpenFFPartialChargeSettings Settings for controlling how the partial charges are assigned. smc_components : dict[SmallMoleculeComponent, openff.toolkit.Molecule] Dictionary of OpenFF Molecules to add, keyed by SmallMoleculeComponent. """ for mol in smc_components.values(): charge_generation.assign_offmol_partial_charges( offmol=mol, overwrite=False, method=charge_settings.partial_charge_method, toolkit_backend=charge_settings.off_toolkit_backend, generate_n_conformers=charge_settings.number_of_conformers, nagl_model=charge_settings.nagl_model, ) def run( self, *, dry: bool = False, verbose: bool = True, scratch_basepath: pathlib.Path | None = None, shared_basepath: pathlib.Path | None = None, ) -> dict[str, Any]: """Setup a plain MD system. Parameters ---------- dry : bool Do a dry run of the calculation, creating all necessary hybrid system components (topology, system, sampler, etc...) but without running the simulation. verbose : bool Verbose output of the simulation progress. Output is provided via INFO level logging. scratch_basepath: pathlib.Path | None Where to store temporary files, defaults to current working directory shared_basepath : pathlib.Path | None Where to run the calculation, defaults to current working directory Returns ------- dict Outputs created by the setup unit or the debug objects (e.g. HybridTopologyFactory) if ``dry==True``. Raises ------ error Exception if anything failed """ # Prepare paths and set verbosity self._prepare(verbose, scratch_basepath, shared_basepath) if verbose: self.logger.info("Creating system") # 0. General setup and settings dependency resolution step # Extract relevant settings protocol_settings: PlainMDProtocolSettings = self._inputs["protocol"].settings stateA = self._inputs["stateA"] forcefield_settings: settings.OpenMMSystemGeneratorFFSettings = ( protocol_settings.forcefield_settings ) thermo_settings: settings.ThermoSettings = protocol_settings.thermo_settings solvation_settings: OpenMMSolvationSettings = protocol_settings.solvation_settings charge_settings: BasePartialChargeSettings = protocol_settings.partial_charge_settings sim_settings: MDSimulationSettings = protocol_settings.simulation_settings output_settings: MDOutputSettings = protocol_settings.output_settings integrator_settings: IntegratorSettings = protocol_settings.integrator_settings timestep = integrator_settings.timestep # is the timestep good for the mass? settings_validation.validate_timestep(forcefield_settings.hydrogen_mass, timestep) # do step validation early and pass through the units if sim_settings.equilibration_length_nvt is not None: equil_steps_nvt = settings_validation.get_simsteps( sim_length=sim_settings.equilibration_length_nvt, timestep=timestep, mc_steps=1, ) else: equil_steps_nvt = None equil_steps_npt = settings_validation.get_simsteps( sim_length=sim_settings.equilibration_length, timestep=timestep, mc_steps=1, ) prod_steps = settings_validation.get_simsteps( sim_length=sim_settings.production_length, timestep=timestep, mc_steps=1, ) solvent_comp, protein_comp, small_mols = system_validation.get_components(stateA) if isinstance(protein_comp, SolvatedPDBComponent): solvent_comp = protein_comp # 1. Create stateA system # Create a dictionary of OFFMol for each SMC for bookkeeping smc_components: dict[SmallMoleculeComponent, OFFMolecule] = { i: i.to_openff() for i in small_mols } # a. assign partial charges to smcs self._assign_partial_charges(charge_settings, smc_components) # b. get a system generator if output_settings.forcefield_cache is not None: ffcache = self.shared_basepath / output_settings.forcefield_cache else: ffcache = None # Note: we block out the oechem backend for all systemgenerator # linked operations to avoid any smiles operations that can # go wrong when doing rdkit->OEchem roundtripping with without_oechem_backend(): system_generator = system_creation.get_system_generator( forcefield_settings=forcefield_settings, integrator_settings=integrator_settings, thermo_settings=thermo_settings, cache=ffcache, has_solvent=solvent_comp is not None, ) # Force creation of smc templates so we can solvate later for mol in smc_components.values(): system_generator.create_system(mol.to_topology().to_openmm(), molecules=[mol]) # c. get OpenMM Modeller + a resids dictionary for each component stateA_modeller, comp_resids = system_creation.get_omm_modeller( protein_comp=protein_comp, solvent_comp=solvent_comp, small_mols=smc_components, omm_forcefield=system_generator.forcefield, solvent_settings=solvation_settings, ) # d. get topology & positions # Note: roundtrip positions to remove vec3 issues stateA_topology = stateA_modeller.getTopology() stateA_positions = to_openmm(from_openmm(stateA_modeller.getPositions())) # e. create the stateA System stateA_system = system_generator.create_system( stateA_topology, molecules=[s.to_openff() for s in small_mols], ) # f. Save pdb of entire system topology to file, this is always needed for restarts with open(self.shared_basepath / output_settings.preminimized_structure, "w") as f: openmm.app.PDBFile.writeFile(stateA_topology, stateA_positions, file=f, keepIds=True) # g. Save the system and positions to file system_outfile = self.shared_basepath / "system.xml.bz2" serialization.serialize(stateA_system, system_outfile) positions_outfile = self.shared_basepath / "input_positions.npy" np.save(positions_outfile, stateA_positions.value_in_unit(omm_unit.nanometers)) unit_results_dict = { "system": system_outfile, # save the positions to higher precision "positions": positions_outfile, "system_pdb": self.shared_basepath / output_settings.preminimized_structure, "equil_steps_nvt": equil_steps_nvt, "equil_steps_npt": equil_steps_npt, "prod_steps": prod_steps, } if dry: # add non serialised stuff for testing debug_info = { "system": stateA_system, "positions": stateA_positions, "topology": stateA_topology, } unit_results_dict["debug"] = debug_info return unit_results_dict def _execute( self, ctx: gufe.Context, **kwargs, ) -> dict[str, Any]: log_system_probe(logging.INFO, paths=[ctx.scratch]) outputs = self.run(scratch_basepath=ctx.scratch, shared_basepath=ctx.shared) return { "repeat_id": self._inputs["repeat_id"], "generation": self._inputs["generation"], # track some version restart info to check compatibility "openmm_version": openmm.__version__, "openfe_version": openfe.__version__, "gufe_version": gufe.__version__, **outputs, } class PlainMDSimulationUnit(PlainMDUnitMixin, gufe.ProtocolUnit): """ Protocol unit for plain MD simulation equilibration and production runs (NonTransformation). """ @staticmethod def _check_restart(output_settings: MDOutputSettings, shared_path: pathlib.Path): """ Check if we are doing a restart. Parameters ---------- output_settings : MDOutputSettings The simulation output settings shared_path : pathlib.Path The shared directory where we should be looking for existing files. Notes ----- For now this just checks if the checkpoint state file is present in the shared directory but in the future this may expand depending on how warehouse works. """ checkpoint = shared_path / output_settings.checkpoint_storage_filename return checkpoint.is_file() @staticmethod def _verify_execution_environment( setup_outputs: dict[str, Any], ) -> None: """ Check that the Python environment hasn't changed based on the relevant Python library versions stored in the setup outputs. """ try: if ( (gufe.__version__ != setup_outputs["gufe_version"]) or (openfe.__version__ != setup_outputs["openfe_version"]) or (openmm.__version__ != setup_outputs["openmm_version"]) ): errmsg = "Python environment has changed, cannot continue Protocol execution." raise ProtocolUnitExecutionError(errmsg) except KeyError: errmsg = "Missing environment information from setup outputs." raise ProtocolUnitExecutionError(errmsg) @staticmethod def _save_pdb_subset( simulation: openmm.app.Simulation, output_settings: MDOutputSettings, file_name: pathlib.Path, ): # get the positions positions = to_openmm( from_openmm( simulation.context.getState( getPositions=True, enforcePeriodicBox=False ).getPositions() ) ) # get the subset from the output settings mdtraj_top = mdtraj.Topology.from_openmm(simulation.topology) selection_indices = mdtraj_top.select(output_settings.output_indices) traj = mdtraj.Trajectory( positions[selection_indices, :], mdtraj_top.subset(selection_indices), ) traj.save_pdb(file_name) @staticmethod def _run_dynamics( simulation: openmm.app.Simulation, steps: int, temperature: KelvinQuantity, barostat_frequency: Quantity, output_settings: MDOutputSettings, verbose: bool = True, output_path: None | pathlib.Path = None, reinitialize_velocities: bool = True, ): """ Worker method to set the temperature, barostat and run dynamics and save final structure output. """ # only set the velocities to temperature if we are not restarting this section if reinitialize_velocities: # set the velocities to temperature simulation.context.setVelocitiesToTemperature(to_openmm(temperature)) # Setup the barostat for x in simulation.context.getSystem().getForces(): if isinstance(x, (MonteCarloBarostat, MonteCarloMembraneBarostat)): x.setFrequency(barostat_frequency.m) # run the simulation t0 = time.time() simulation.step(steps) t1 = time.time() if verbose: logger.info(f"Completed dynamics in {t1 - t0} seconds") # save the final frame if a file path is passed if output_path is not None: PlainMDSimulationUnit._save_pdb_subset( simulation, output_settings, output_path, ) @staticmethod def _get_remaining_steps( current_step_count: int, equil_steps_nvt: int, equil_steps_npt: int, prod_steps: int, ) -> tuple[int, int, int, bool]: """ Work out the remaining steps for each phase of the simulation based on the current step count, and determine if production has already started. Returns ------- equil_steps_nvt : int The number of nvt steps left to run equil_steps_npt : int The number of npt steps left to run prod_steps : int The number of production steps left to run production_started : bool Whether the production phase has already started or not """ nvt_end = equil_steps_nvt npt_end = equil_steps_nvt + equil_steps_npt prod_end = equil_steps_nvt + equil_steps_npt + prod_steps if npt_end < current_step_count <= prod_end: # In the production phase return 0, 0, prod_end - current_step_count, True elif nvt_end < current_step_count <= npt_end: # In the NPT equilibration phase return 0, npt_end - current_step_count, prod_steps, False else: # In the NVT equilibration phase return nvt_end - current_step_count, equil_steps_npt, prod_steps, False @staticmethod def _run_MD( simulation: openmm.app.Simulation, positions: omm_unit.Quantity, simulation_settings: MDSimulationSettings, output_settings: MDOutputSettings, temperature: KelvinQuantity, barostat_frequency: Quantity, timestep: FemtosecondQuantity, equil_steps_nvt: int | None, equil_steps_npt: int, prod_steps: int, verbose: bool = True, shared_basepath: pathlib.Path | None = None, restart: bool = False, ) -> None: """ Energy minimization, Equilibration and Production MD to be reused in multiple protocols Parameters ---------- simulation : openmm.app.Simulation An OpenMM simulation to simulate. positions : openmm.unit.Quantity Initial positions for the system. simulation_settings : SimulationSettingsMD Settings for MD simulation output_settings: OutputSettingsMD Settings for output of MD simulation temperature: KelvinQuantity temperature setting barostat_frequency: openff.units.Quantity Frequency for the barostat timestep: FemtosecondQuantity Simulation integration timestep equil_steps_nvt: Optional[int] number of steps for NVT equilibration if None, no NVT equilibration will be performed equil_steps_npt: int number of steps for NPT equilibration prod_steps: int number of steps for the production run verbose: bool Verbose output of the simulation progress. Output is provided via INFO level logging. shared_basepath : Pathlike, optional Where to run the calculation, defaults to current working directory restart: bool, optional, default=False Whether we are restarting from a previous simulation or not, the checkpoint file should be present in the shared directories. """ if shared_basepath is None: shared_basepath = pathlib.Path(".") # get the checkpointing interval for states and positions checkpoint_interval = settings_validation.get_simsteps( sim_length=output_settings.checkpoint_interval, timestep=timestep, mc_steps=1, ) # as nvt steps can be None set to 0 in this case equil_steps_nvt = equil_steps_nvt or 0 # track if production has already been started production_started = False # track if we need to reinitialize velocities for a phase # on a fresh run, reinitialize velocities for the first phase. # on a restart, preserve the checkpoint velocities for the phase being restarted. reinitialize_velocities = not restart # if restarting skip setup and minimization as they should be completed by the time the checkpoint reporter is used if restart: if verbose: logger.info("Restarting simulation from checkpoint state") simulation.loadState(str(shared_basepath / output_settings.checkpoint_storage_filename)) # workout the number of steps to run in each phase based on the current simulation step count current_step_count = simulation.context.getStepCount() equil_steps_nvt, equil_steps_npt, prod_steps, production_started = ( PlainMDSimulationUnit._get_remaining_steps( current_step_count=current_step_count, equil_steps_nvt=equil_steps_nvt, equil_steps_npt=equil_steps_npt, prod_steps=prod_steps, ) ) else: # this is the non restart case and requires minimization before moving on simulation.context.setPositions(positions) # minimize if verbose: logger.info("Minimizing systems") simulation.minimizeEnergy(maxIterations=simulation_settings.minimization_steps) if output_settings.minimized_structure: PlainMDSimulationUnit._save_pdb_subset( simulation, output_settings, shared_basepath / output_settings.minimized_structure, ) # add the checkpoint reporter so we can recover during the equilibration / production phases if output_settings.checkpoint_storage_filename: simulation.reporters.append( openmm.app.CheckpointReporter( file=str(shared_basepath / output_settings.checkpoint_storage_filename), reportInterval=checkpoint_interval, writeState=True, # writes portable XML via simulation.saveState() ) ) # equilibrate # NVT equilibration if equil_steps_nvt > 0: if verbose: logger.info(f"Running NVT equilibration for {equil_steps_nvt} steps") # setup the output path if we have one for the nvt equilibration if output_settings.equil_nvt_structure is not None: output_path = shared_basepath / output_settings.equil_nvt_structure else: output_path = None PlainMDSimulationUnit._run_dynamics( simulation=simulation, steps=equil_steps_nvt, temperature=temperature, barostat_frequency=0 * unit.timestep, # turn off the barostat for this stage output_settings=output_settings, verbose=verbose, output_path=output_path, reinitialize_velocities=reinitialize_velocities, ) # if we have run this stage we then need to reinitialize velocities in the next stages reinitialize_velocities = True # NPT equilibration if equil_steps_npt > 0: if verbose: logger.info(f"Running NPT equilibration for {equil_steps_npt} steps") # setup the output path if we have one for the npt equilibration if output_settings.equil_npt_structure is not None: output_path = shared_basepath / output_settings.equil_npt_structure else: output_path = None PlainMDSimulationUnit._run_dynamics( simulation=simulation, steps=equil_steps_npt, temperature=temperature, barostat_frequency=barostat_frequency, output_settings=output_settings, verbose=verbose, output_path=output_path, reinitialize_velocities=reinitialize_velocities, ) # the production stage can use these same velocities reinitialize_velocities = False # production if verbose: logger.info(f"Running production phase for {prod_steps} steps") # Setup the reporters write_interval = settings_validation.divmod_time_and_check( output_settings.trajectory_write_interval, timestep, "trajectory_write_interval", "timestep", ) if output_settings.production_trajectory_filename: # Get the sub selection of the system to save coords for selection_indices = mdtraj.Topology.from_openmm(simulation.topology).select( output_settings.output_indices ) xtc_reporter = XTCReporter( file=str(shared_basepath / output_settings.production_trajectory_filename), reportInterval=write_interval, atomSubset=selection_indices, # append to the trajectory if restarting and we have run the production stage before append=production_started, ) simulation.reporters.append(xtc_reporter) if output_settings.log_output: simulation.reporters.append( openmm.app.StateDataReporter( str(shared_basepath / output_settings.log_output), checkpoint_interval, step=True, time=True, potentialEnergy=True, kineticEnergy=True, totalEnergy=True, temperature=True, volume=True, density=True, speed=True, append=production_started, ) ) PlainMDSimulationUnit._run_dynamics( simulation=simulation, steps=prod_steps, temperature=temperature, barostat_frequency=barostat_frequency, output_settings=output_settings, verbose=verbose, output_path=None, # the trajectory is saved for the production run so don't save again reinitialize_velocities=reinitialize_velocities, ) def run( self, *, system: openmm.System, positions: openmm.unit.Quantity, topology: openmm.app.Topology, equil_steps_nvt: int | None, equil_steps_npt: int, prod_steps: int, dry: bool = False, verbose: bool = True, scratch_basepath: pathlib.Path | None = None, shared_basepath: pathlib.Path | None = None, ) -> dict[str, Any]: """Run the MD simulation. Parameters ---------- system : openmm.System The System to simulate. positions : openmm.unit.Quantity The positions of the System. topology: openmm.app.Topology The topology of the System. equil_steps_nvt : int The number of nvt equilibration steps. equil_steps_npt : int The number of npt equilibration steps. prod_steps : int The number of production steps. dry : bool Do a dry run of the calculation, creating all necessary hybrid system components (topology, system, sampler, etc...) but without running the simulation. verbose : bool Verbose output of the simulation progress. Output is provided via INFO level logging. scratch_basepath: Pathlike, optional Where to store temporary files, defaults to current working directory shared_basepath : Pathlike, optional Where to run the calculation, defaults to current working directory Returns ------- dict Outputs created in the basepath directory or the debug objects (i.e. sampler) if ``dry==True``. Raises ------ error Exception if anything failed """ # Prepare paths and set verbosity self._prepare(verbose, scratch_basepath, shared_basepath) # Extract relevant settings protocol_settings: PlainMDProtocolSettings = self._inputs["protocol"].settings forcefield_settings: settings.OpenMMSystemGeneratorFFSettings = ( protocol_settings.forcefield_settings ) thermo_settings: settings.ThermoSettings = protocol_settings.thermo_settings sim_settings: MDSimulationSettings = protocol_settings.simulation_settings output_settings: MDOutputSettings = protocol_settings.output_settings timestep = protocol_settings.integrator_settings.timestep integrator_settings = protocol_settings.integrator_settings # Get platform restrict_cpu = forcefield_settings.nonbonded_method.lower() == "nocutoff" platform = omm_compute.get_openmm_platform( platform_name=protocol_settings.engine_settings.compute_platform, gpu_device_index=protocol_settings.engine_settings.gpu_device_index, restrict_cpu_count=restrict_cpu, ) # Set the integrator integrator = openmm.LangevinMiddleIntegrator( to_openmm(thermo_settings.temperature), to_openmm(integrator_settings.langevin_collision_rate), to_openmm(timestep), ) # Build the simulation simulation = openmm.app.Simulation( topology, system, integrator, platform, ) try: if not dry: # pragma: no-cover # check for a restart restart = self._check_restart(output_settings, self.shared_basepath) # start the simulation self._run_MD( simulation, positions, sim_settings, output_settings, thermo_settings.temperature, integrator_settings.barostat_frequency, timestep, equil_steps_nvt, equil_steps_npt, prod_steps, shared_basepath=self.shared_basepath, restart=restart, verbose=self.verbose, ) finally: if not dry: del integrator, simulation if not dry: # pragma: no-cover output = { "system_pdb": self.shared_basepath / output_settings.preminimized_structure, "minimized_pdb": self.shared_basepath / output_settings.minimized_structure, "nc": self.shared_basepath / output_settings.production_trajectory_filename, "last_checkpoint": self.shared_basepath / output_settings.checkpoint_storage_filename, } # The checkpoint file can not exist if frequency > sim length if not output["last_checkpoint"].exists(): output["last_checkpoint"] = None # The NVT PDB can be omitted if we don't run the simulation # Note: we could also just check the file exist if ( output_settings.equil_nvt_structure and sim_settings.equilibration_length_nvt is not None ): output["nvt_equil_pdb"] = self.shared_basepath / output_settings.equil_nvt_structure else: output["nvt_equil_pdb"] = None if output_settings.equil_npt_structure: output["npt_equil_pdb"] = self.shared_basepath / output_settings.equil_npt_structure else: output["npt_equil_pdb"] = None return output else: return {"debug": {"system": system}} def _execute( self, ctx: gufe.Context, setup_results, **kwargs, ) -> dict[str, Any]: log_system_probe(logging.INFO, paths=[ctx.scratch]) # Ensure that the environment hasn't changed self._verify_execution_environment(setup_results.outputs) # Get the relevant inputs for running the unit system = serialization.deserialize(setup_results.outputs["system"]) positions = ( np.load(setup_results.outputs["positions"]) * omm_unit.nanometers ) # convert to openmm units topology = openmm.app.PDBFile(str(setup_results.outputs["system_pdb"])).getTopology() equil_steps_nvt = setup_results.outputs["equil_steps_nvt"] equil_steps_npt = setup_results.outputs["equil_steps_npt"] prod_steps = setup_results.outputs["prod_steps"] outputs = self.run( system=system, positions=positions, topology=topology, equil_steps_nvt=equil_steps_nvt, equil_steps_npt=equil_steps_npt, prod_steps=prod_steps, scratch_basepath=ctx.scratch, shared_basepath=ctx.shared, ) return { "repeat_id": self._inputs["repeat_id"], "generation": self._inputs["generation"], **outputs, } ================================================ FILE: src/openfe/protocols/openmm_md/plain_md_settings.py ================================================ # This code is part of OpenFE and is licensed under the MIT license. # For details, see https://github.com/OpenFreeEnergy/openfe """Settings class for plain MD Protocols using OpenMM + OpenMMTools This module implements the settings necessary to run MD simulations using :class:`openfe.protocols.openmm_md.plain_md_methods.py` """ from gufe.settings import OpenMMSystemGeneratorFFSettings, SettingsBaseModel from pydantic import ConfigDict, field_validator from openfe.protocols.openmm_utils.omm_settings import ( IntegratorSettings, MDOutputSettings, MDSimulationSettings, OpenFFPartialChargeSettings, OpenMMEngineSettings, OpenMMSolvationSettings, Settings, ) class PlainMDProtocolSettings(Settings): model_config = ConfigDict(arbitrary_types_allowed=True) protocol_repeats: int """ Number of independent MD runs to perform. """ @field_validator("protocol_repeats") def must_be_positive(cls, v): if v <= 0: errmsg = f"protocol_repeats must be a positive value, got {v}." raise ValueError(errmsg) return v # Things for creating the systems forcefield_settings: OpenMMSystemGeneratorFFSettings partial_charge_settings: OpenFFPartialChargeSettings solvation_settings: OpenMMSolvationSettings # MD Engine things engine_settings: OpenMMEngineSettings # Sampling State defining things integrator_settings: IntegratorSettings # Simulation run settings simulation_settings: MDSimulationSettings # Simulations output settings output_settings: MDOutputSettings ================================================ FILE: src/openfe/protocols/openmm_rfe/__init__.py ================================================ # This code is part of OpenFE and is licensed under the MIT license. # For details, see https://github.com/OpenFreeEnergy/openfe from . import _rfe_utils from .equil_rfe_settings import RelativeHybridTopologyProtocolSettings from .hybridtop_protocol_results import RelativeHybridTopologyProtocolResult from .hybridtop_protocols import RelativeHybridTopologyProtocol from .hybridtop_units import ( HybridTopologyMultiStateAnalysisUnit, HybridTopologyMultiStateSimulationUnit, HybridTopologySetupUnit, ) ================================================ FILE: src/openfe/protocols/openmm_rfe/_rfe_utils/__init__.py ================================================ from . import ( lambdaprotocol, multistate, relative, topologyhelpers, ) ================================================ FILE: src/openfe/protocols/openmm_rfe/_rfe_utils/lambdaprotocol.py ================================================ # Very slightly adapted from perses https://github.com/choderalab/perses # License: MIT # OpenFE note: eventually we aim to move this to openmmtools where possible # turn off formatting since this is mostly vendored code # fmt: off import copy import warnings import numpy as np from openmmtools.alchemy import AlchemicalState class LambdaProtocol(object): """Protocols for perturbing each of the component energy terms in alchemical free energy simulations. TODO ---- * Class needs cleaning up and made more consistent """ default_functions = {'lambda_sterics_core': lambda x: x, 'lambda_electrostatics_core': lambda x: x, 'lambda_sterics_insert': lambda x: 2.0 * x if x < 0.5 else 1.0, 'lambda_sterics_delete': lambda x: 0.0 if x < 0.5 else 2.0 * (x - 0.5), 'lambda_electrostatics_insert': lambda x: 0.0 if x < 0.5 else 2.0 * (x - 0.5), 'lambda_electrostatics_delete': lambda x: 2.0 * x if x < 0.5 else 1.0, 'lambda_bonds': lambda x: x, 'lambda_angles': lambda x: x, 'lambda_torsions': lambda x: x } # lambda components for each component, # all run from 0 -> 1 following master lambda def __init__(self, functions='default', windows=10, lambda_schedule=None): """Instantiates lambda protocol to be used in a free energy calculation. Can either be user defined, by passing in a dict, or using one of the pregenerated sets by passing in a string 'default', 'namd' or 'quarters' All protocols must begin and end at 0 and 1 respectively. Any energy term not defined in `functions` dict will be set to the function in `default_functions` Pre-coded options: default : ele and LJ terms of the old system are turned off between 0.0 -> 0.5 ele and LJ terms of the new system are turned on between 0.5 -> 1.0 core terms treated linearly quarters : 0.25 of the protocol is used in turn to individually change the (a) off old ele, (b) off old sterics, (c) on new sterics (d) on new ele core terms treated linearly namd : follows the protocol outlined here: https://pubs.acs.org/doi/full/10.1021/acs.jcim.9b00362# Jiang, Wei, Christophe Chipot, and Benoît Roux. "Computing Relative Binding Affinity of Ligands to Receptor: An Effective Hybrid Single-Dual-Topology Free-Energy Perturbation Approach in NAMD." Journal of chemical information and modeling 59.9 (2019): 3794-3802. ele-scaled : all terms are treated as in default, except for the old and new ele these are scaled with lambda^0.5, so as to be linear in energy, rather than lambda Parameters ---------- functions : str or dict One of the predefined lambda protocols ['default','namd','quarters'] or a dictionary. Default "default". windows : int Number of windows which this lambda schedule is intended to be used with. This value is used to validate the lambda function. lambda_schedule : list of floats Schedule of lambda windows to be sampled. If ``None`` will default to a linear spacing of windows as defined by ``np.linspace(0. ,1. ,windows)``. Default ``None``. Attributes ---------- functions : dict Lambda protocol to be used. lambda_schedule : list Schedule of windows to be sampled. """ self.functions = copy.deepcopy(functions) # set the lambda schedule self.lambda_schedule = self._validate_schedule(lambda_schedule, windows) if lambda_schedule: self.lambda_schedule = lambda_schedule else: self.lambda_schedule = np.linspace(0., 1., windows) if isinstance(self.functions, dict): self.type = 'user-defined' elif isinstance(self.functions, str): self.functions = None # will be set later self.type = functions if self.functions is None: if self.type == 'default': self.functions = copy.deepcopy( LambdaProtocol.default_functions) elif self.type == 'namd': self.functions = { 'lambda_sterics_core': lambda x: x, 'lambda_electrostatics_core': lambda x: x, 'lambda_sterics_insert': lambda x: (3. / 2.) * x if x < (2. / 3.) else 1.0, 'lambda_sterics_delete': lambda x: 0.0 if x < (1. / 3.) else (x - (1. / 3.)) * (3. / 2.), 'lambda_electrostatics_insert': lambda x: 0.0 if x < 0.5 else 2.0 * (x - 0.5), 'lambda_electrostatics_delete': lambda x: 2.0 * x if x < 0.5 else 1.0, 'lambda_bonds': lambda x: x, 'lambda_angles': lambda x: x, 'lambda_torsions': lambda x: x } elif self.type == 'quarters': self.functions = { 'lambda_sterics_core': lambda x: x, 'lambda_electrostatics_core': lambda x: x, 'lambda_sterics_insert': lambda x: 0. if x < 0.5 else 1 if x > 0.75 else 4 * (x - 0.5), 'lambda_sterics_delete': lambda x: 0. if x < 0.25 else 1 if x > 0.5 else 4 * (x - 0.25), 'lambda_electrostatics_insert': lambda x: 0. if x < 0.75 else 4 * (x - 0.75), 'lambda_electrostatics_delete': lambda x: 4.0 * x if x < 0.25 else 1.0, 'lambda_bonds': lambda x: x, 'lambda_angles': lambda x: x, 'lambda_torsions': lambda x: x } elif self.type == 'ele-scaled': self.functions = { 'lambda_electrostatics_insert': lambda x: 0.0 if x < 0.5 else ((2*(x-0.5))**0.5), 'lambda_electrostatics_delete': lambda x: (2*x)**2 if x < 0.5 else 1.0 } elif self.type == 'user-defined': self.functions = functions else: errmsg = f"LambdaProtocol type : {self.type} not recognised " raise ValueError(errmsg) self._validate_functions(n=windows) self._check_for_naked_charges() @staticmethod def _validate_schedule(schedule, windows): """ Checks that the input lambda schedule is valid. Rules are: - Must begin at 0 and end at 1 - Must be monotonically increasing Parameters ---------- schedule : list of floats The lambda schedule. If ``None`` the method returns ``np.linspace(0. ,1. ,windows)``. windows : int Number of windows to be sampled. Returns ------- schedule : list of floats A valid lambda schedule. """ if schedule is None: return np.linspace(0., 1., windows) # Check end states if schedule[0] != 0 or schedule[-1] != 1: errmsg = ("end and start lambda windows must be lambda 0 and 1 " "respectively") raise ValueError(errmsg) # Check monotonically increasing difference = np.diff(schedule) if not all(i >= 0. for i in difference): errmsg = "The lambda schedule is not monotonic" raise ValueError(errmsg) return schedule def _validate_functions(self, n=10): """Ensures that all the lambda functions adhere to the rules: - must begin at 0. - must finish at 1. - must be monotonically increasing Parameters ---------- n : int, default 10 number of grid points used to check monotonicity """ # the individual lambda functions that must be defined for required_functions = list(LambdaProtocol.default_functions.keys()) for function in required_functions: if function not in self.functions: # IA switched from warn to error here errmsg = (f"function {function} is missing from " "self.lambda_functions.") raise ValueError(errmsg) # Check that the function starts and ends at 0 and 1 respectively if self.functions[function](0) != 0: raise ValueError("lambda functions must start at 0") if self.functions[function](1) != 1: raise ValueError("lambda functions must end at 1") # now validatate that it's monotonic global_lambda = np.linspace(0., 1., n) sub_lambda = [self.functions[function](lam) for lam in global_lambda] difference = np.diff(sub_lambda) if not all(i >= 0. for i in difference): wmsg = (f"The function {function} is not monotonic as " "typically expected.") warnings.warn(wmsg) def _check_for_naked_charges(self): """ Checks that there are no cases where atoms have charge but no sterics. This avoids issues with singularities and/or excessive forces near the end states (even when using softcore electrostatics). """ global_lambda = self.lambda_schedule def check_overlap(ele, sterics, global_lambda, functions, endstate): for lam in global_lambda: ele_val = functions[ele](lam) ster_val = functions[sterics](lam) # if charge > 0 and sterics == 0 raise error if ele_val != endstate and ster_val == endstate: errmsg = ("There are states along this lambda schedule " "where there are atoms with charges but no LJ " f"interactions: {lam} {ele_val} {ster_val}") raise ValueError(errmsg) # checking unique new terms first ele = 'lambda_electrostatics_insert' sterics = 'lambda_sterics_insert' check_overlap(ele, sterics, global_lambda, self.functions, endstate=0) # checking unique old terms now ele = 'lambda_electrostatics_delete' sterics = 'lambda_sterics_delete' check_overlap(ele, sterics, global_lambda, self.functions, endstate=1) def get_functions(self): return self.functions def plot_functions(self, lambda_schedule=None): """ Plot the function for ease of visualisation. Parameters ---------- schedule : np.ndarray The lambda schedule to plot the function along. If ``None`` plot the one stored within this class. Default ``None``. """ import matplotlib.pyplot as plt fig = plt.figure(figsize=(10, 5)) global_lambda = lambda_schedule if lambda_schedule else self.lambda_schedule for f in self.functions: plt.plot(global_lambda, [self.functions[f](lam) for lam in global_lambda], alpha=0.5, label=f) plt.xlabel('global lambda') plt.ylabel('sub-lambda') plt.legend() plt.show() class RelativeAlchemicalState(AlchemicalState): """ Relative AlchemicalState to handle all lambda parameters required for relative perturbations lambda = 1 refers to ON, i.e. fully interacting while lambda = 0 refers to OFF, i.e. non-interacting with the system all lambda functions will follow from 0 -> 1 following the master lambda lambda*core parameters perturb linearly lambda_sterics_insert and lambda_electrostatics_delete perturb in the first half of the protocol 0 -> 0.5 lambda_sterics_delete and lambda_electrostatics_insert perturb in the second half of the protocol 0.5 -> 1 Attributes ---------- lambda_sterics_core lambda_electrostatics_core lambda_sterics_insert lambda_sterics_delete lambda_electrostatics_insert lambda_electrostatics_delete """ class _LambdaParameter(AlchemicalState._LambdaParameter): pass lambda_sterics_core = _LambdaParameter('lambda_sterics_core') lambda_electrostatics_core = _LambdaParameter('lambda_electrostatics_core') lambda_sterics_insert = _LambdaParameter('lambda_sterics_insert') lambda_sterics_delete = _LambdaParameter('lambda_sterics_delete') lambda_electrostatics_insert = _LambdaParameter( 'lambda_electrostatics_insert') lambda_electrostatics_delete = _LambdaParameter( 'lambda_electrostatics_delete') def set_alchemical_parameters(self, global_lambda, lambda_protocol=LambdaProtocol()): """Set each lambda value according to the lambda_functions protocol. The undefined parameters (i.e. those being set to None) remain undefined. Parameters ---------- lambda_value : float The new value for all defined parameters. """ self.global_lambda = global_lambda for parameter_name in lambda_protocol.functions: lambda_value = lambda_protocol.functions[parameter_name](global_lambda) setattr(self, parameter_name, lambda_value) ================================================ FILE: src/openfe/protocols/openmm_rfe/_rfe_utils/multistate.py ================================================ ############################################################################# # HYBRID SYSTEM SAMPLERS ############################################################################# """ This is adapted from Perses: https://github.com/choderalab/perses/ See here for the license: https://github.com/choderalab/perses/blob/main/LICENSE """ # turn off formatting since this is mostly vendored code # fmt: off import copy import logging import warnings import numpy as np import openmm import openmmtools.states as states from openmm import unit from openmmtools import cache from openmmtools.integrators import FIREMinimizationIntegrator from openmmtools.multistate import multistatesampler, replicaexchange, sams from openmmtools.states import CompoundThermodynamicState, SamplerState, ThermodynamicState from .lambdaprotocol import RelativeAlchemicalState logger = logging.getLogger(__name__) class HybridCompatibilityMixin: """ Mixin that allows the MultistateSampler to accommodate the situation where unsampled endpoints have a different number of degrees of freedom. """ def __init__( self, *args, hybrid_system: openmm.System | None = None, hybrid_positions: unit.Quantity | None = None, **kwargs ): self._hybrid_system = hybrid_system self._hybrid_positions = hybrid_positions super(HybridCompatibilityMixin, self).__init__(*args, **kwargs) def setup(self, reporter, lambda_protocol, temperature=298.15 * unit.kelvin, n_replicas=None, endstates=True, minimization_steps=100, minimization_platform="CPU"): """ Setup MultistateSampler based on the input lambda protocol and number of replicas. Parameters ---------- reporter : OpenMM reporter Simulation reporter to attach to each simulation replica. lambda_protocol : LambdaProtocol The lambda protocol to be used for simulation. Default to a default class creation of LambdaProtocol. temperature : openmm.Quantity Simulation temperature, default to 298.15 K n_replicas : int Number of replicas to simulate. Sets to the number of lambda states (as defined by lambda_protocol) if ``None``. Default ``None``. endstates : bool Whether or not to generate unsampled endstates (i.e. dispersion correction). minimization_steps : Optional[int] Number of steps to pre-minimize states. minimization_platform : str Platform to do the initial pre-minimization with. Attributes ---------- n_states : int Number of states / windows which are to be sampled. Obtained from lambda_protocol. """ n_states = len(lambda_protocol.lambda_schedule) lambda_zero_state = RelativeAlchemicalState.from_system(self._hybrid_system) thermostate = ThermodynamicState( self._hybrid_system, temperature=temperature ) compound_thermostate = CompoundThermodynamicState( thermostate, composable_states=[lambda_zero_state] ) # create lists for storing thermostates and sampler states thermodynamic_state_list = [] sampler_state_list = [] if n_replicas is None: msg = (f"setting number of replicas to number of states: {n_states}") warnings.warn(msg) n_replicas = n_states elif n_replicas > n_states: wmsg = (f"More sampler states: {n_replicas} requested than the " f"number of available states: {n_states}. Setting " "the number of replicas to the number of states") warnings.warn(wmsg) n_replicas = n_states lambda_schedule = lambda_protocol.lambda_schedule if len(lambda_schedule) != n_states: errmsg = ("length of lambda_schedule must match the number of " "states, n_states") raise ValueError(errmsg) # starting with the hybrid factory positions box = self._hybrid_system.getDefaultPeriodicBoxVectors() sampler_state = SamplerState( self._hybrid_positions, box_vectors=box ) # Loop over the lambdas and create & store a compound thermostate at # that lambda value for lambda_val in lambda_schedule: compound_thermostate_copy = copy.deepcopy(compound_thermostate) compound_thermostate_copy.set_alchemical_parameters( lambda_val, lambda_protocol ) thermodynamic_state_list.append(compound_thermostate_copy) # now generating a sampler_state for each thermodyanmic state, # with relaxed positions # Note: remove once choderalab/openmmtools#672 is completed minimize(compound_thermostate_copy, sampler_state, max_iterations=minimization_steps, platform_name=minimization_platform) sampler_state_list.append(copy.deepcopy(sampler_state)) del compound_thermostate, sampler_state # making sure number of sampler states equals n_replicas if len(sampler_state_list) != n_replicas: # picking roughly evenly spaced sampler states # if n_replicas == 1, then it will pick the first in the list samples = np.linspace(0, len(sampler_state_list) - 1, n_replicas) idx = np.round(samples).astype(int) sampler_state_list = [state for i, state in enumerate(sampler_state_list) if i in idx] assert len(sampler_state_list) == n_replicas if endstates: # generating unsampled endstates unsampled_dispersion_endstates = create_endstates( copy.deepcopy(thermodynamic_state_list[0]), copy.deepcopy(thermodynamic_state_list[-1]) ) self.create(thermodynamic_states=thermodynamic_state_list, sampler_states=sampler_state_list, storage=reporter, unsampled_thermodynamic_states=unsampled_dispersion_endstates) else: self.create(thermodynamic_states=thermodynamic_state_list, sampler_states=sampler_state_list, storage=reporter) class HybridRepexSampler(HybridCompatibilityMixin, replicaexchange.ReplicaExchangeSampler): """ ReplicaExchangeSampler that supports unsampled end states with a different number of positions """ def __init__( self, *args, hybrid_system: openmm.System | None = None, hybrid_positions: unit.Quantity | None = None, **kwargs ): super(HybridRepexSampler, self).__init__( *args, hybrid_system=hybrid_system, hybrid_positions=hybrid_positions, **kwargs ) class HybridSAMSSampler(HybridCompatibilityMixin, sams.SAMSSampler): """ SAMSSampler that supports unsampled end states with a different number of positions """ def __init__( self, *args, hybrid_system: openmm.System | None = None, hybrid_positions: unit.Quantity | None = None, **kwargs ): super(HybridSAMSSampler, self).__init__( *args, hybrid_system=hybrid_system, hybrid_positions=hybrid_positions, **kwargs ) class HybridMultiStateSampler(HybridCompatibilityMixin, multistatesampler.MultiStateSampler): """ MultiStateSampler that supports unsample end states with a different number of positions """ def __init__( self, *args, hybrid_system: openmm.System | None = None, hybrid_positions: unit.Quantity | None = None, **kwargs ): super(HybridMultiStateSampler, self).__init__( *args, hybrid_system=hybrid_system, hybrid_positions=hybrid_positions, **kwargs ) def create_endstates(first_thermostate, last_thermostate): """ Utility function to generate unsampled endstates 1. Move all alchemical atom LJ parameters from CustomNonbondedForce to NonbondedForce. 2. Delete the CustomNonbondedForce. 3. Set PME tolerance to 1e-5. 4. Enable LJPME to handle long range dispersion corrections in a physically reasonable manner. Parameters ---------- first_thermostate : openmmtools.states.CompoundThermodynamicState The first thermodynamic state for which an unsampled endstate will be created. last_thermostate : openmmtools.states.CompoundThermodynamicState The last thermodynamic state for which an unsampled endstate will be created. Returns ------- unsampled_endstates : list of openmmtools.states.CompoundThermodynamicState The corrected unsampled endstates. """ unsampled_endstates = [] for master_lambda, endstate in zip([0., 1.], [first_thermostate, last_thermostate]): dispersion_system = endstate.get_system() energy_unit = unit.kilocalories_per_mole # Find the NonbondedForce (there must be only one) forces = {force.__class__.__name__: force for force in dispersion_system.getForces()} # Set NonbondedForce to use LJPME ljpme = openmm.NonbondedForce.LJPME forces['NonbondedForce'].setNonbondedMethod(ljpme) # Set tight PME tolerance TIGHT_PME_TOLERANCE = 1.0e-5 forces['NonbondedForce'].setEwaldErrorTolerance(TIGHT_PME_TOLERANCE) # Move alchemical LJ sites from CustomNonbondedForce back to # NonbondedForce for particle_index in range(forces['NonbondedForce'].getNumParticles()): charge, sigma, epsilon = forces['NonbondedForce'].getParticleParameters(particle_index) sigmaA, epsilonA, sigmaB, epsilonB, unique_old, unique_new = forces['CustomNonbondedForce'].getParticleParameters(particle_index) if (epsilon/energy_unit == 0.0) and ((epsilonA > 0.0) or (epsilonB > 0.0)): sigma = (1-master_lambda)*sigmaA + master_lambda*sigmaB epsilon = (1-master_lambda)*epsilonA + master_lambda*epsilonB forces['NonbondedForce'].setParticleParameters( particle_index, charge, sigma, epsilon) # Delete the CustomNonbondedForce since we have moved all alchemical # particles out of it for force_index, force in enumerate(list(dispersion_system.getForces())): if force.__class__.__name__ == 'CustomNonbondedForce': custom_nonbonded_force_index = force_index break dispersion_system.removeForce(custom_nonbonded_force_index) # Set all parameters to master lambda for force_index, force in enumerate(list(dispersion_system.getForces())): if hasattr(force, 'getNumGlobalParameters'): for parameter_index in range(force.getNumGlobalParameters()): if force.getGlobalParameterName(parameter_index)[0:7] == 'lambda_': force.setGlobalParameterDefaultValue(parameter_index, master_lambda) # Store the unsampled endstate unsampled_endstates.append(ThermodynamicState( dispersion_system, temperature=endstate.temperature)) return unsampled_endstates def minimize(thermodynamic_state: states.ThermodynamicState, sampler_state: states.SamplerState, max_iterations: int=100, platform_name: str="CPU") -> states.SamplerState: """ Adapted from perses.dispersed.feptasks.minimize Minimize the given system and state, up to a maximum number of steps. This does not return a copy of the samplerstate; it is an update-in-place. Parameters ---------- thermodynamic_state : openmmtools.states.ThermodynamicState The state at which the system could be minimized sampler_state : openmmtools.states.SamplerState The starting state at which to minimize the system. max_iterations : Optional[int] The maximum number of minimization steps. Default is 100. platform_name : str The OpenMM platform name to carry out the minimization with. Returns ------- sampler_state : openmmtools.states.SamplerState The positions and accompanying state following minimization """ # Only run a minimization if max_iterations is not None if max_iterations is not None: # we won't take any steps, so use a simple integrator integrator = openmm.VerletIntegrator(1.0) platform = openmm.Platform.getPlatformByName(platform_name) dummy_cache = cache.DummyContextCache(platform=platform) context, integrator = dummy_cache.get_context( thermodynamic_state, integrator ) try: sampler_state.apply_to_context( context, ignore_velocities=True ) openmm.LocalEnergyMinimizer.minimize( context, maxIterations=max_iterations ) sampler_state.update_from_context(context) finally: del context, integrator, dummy_cache ================================================ FILE: src/openfe/protocols/openmm_rfe/_rfe_utils/relative.py ================================================ # This code is a slightly modified version of the HybridTopologyFactory code # from https://github.com/choderalab/perses # The eventual goal is to move a version of this towards openmmtools # LICENSE: MIT # turn off formatting since this is mostly vendored code # fmt: off import copy import itertools import logging import mdtraj as mdt import numpy as np import openmm from openmm import app, unit # OpenMM constant for Coulomb interactions (implicitly in md_unit_system units) from openmmtools.constants import ONE_4PI_EPS0 logger = logging.getLogger(__name__) class HybridTopologyFactory: """ This class generates a hybrid topology based on two input systems and an atom mapping. For convenience the states are called "old" and "new" respectively, defining the starting and end states along the alchemical transformation. The input systems are assumed to have: 1. The total number of molecules 2. The same coordinates for equivalent atoms Atoms in the resulting hybrid system are treated as being from one of four possible types: unique_old_atom : These atoms are not mapped and only present in the old system. Their interactions will be on for lambda=0, off for lambda=1 unique_new_atom : These atoms are not mapped and only present in the new system. Their interactions will be off for lambda=0, on for lambda=1 core_atom : These atoms are mapped between the two end states, and are part of a residue that is changing alchemically. Their interactions will be those corresponding to the old system at lambda=0, and those corresponding to the new system at lambda=1 environment_atom : These atoms are mapped between the two end states, and are not part of a residue undergoing an alchemical change. Their interactions are always on and are alchemically unmodified. Properties ---------- hybrid_system : openmm.System The hybrid system for simulation new_to_hybrid_atom_map : dict of int : int The mapping of new system atoms to hybrid atoms old_to_hybrid_atom_map : dict of int : int The mapping of old system atoms to hybrid atoms hybrid_positions : [n, 3] np.ndarray The positions of the hybrid system hybrid_topology : mdtraj.Topology The topology of the hybrid system omm_hybrid_topology : openmm.app.Topology The OpenMM topology object corresponding to the hybrid system .. warning :: This API is experimental and subject to change. Notes ----- * Logging has been removed and will be revamped at a later date. * The ability to define custom functions has been removed for now. * Neglected angle terms have been removed for now. * RMSD restraint option has been removed for now. * Endstate support has been removed for now. * Bond softening has been removed for now. * Unused InteractionGroup code paths have been removed. TODO ---- * Document how positions for hybrid system are constructed. * Allow support for annealing in omitted terms. * Implement omitted terms (this was not available in the original class). """ def __init__(self, old_system, old_positions, old_topology, new_system, new_positions, new_topology, old_to_new_atom_map, old_to_new_core_atom_map, use_dispersion_correction=False, softcore_alpha=0.5, softcore_LJ_v2=True, softcore_LJ_v2_alpha=0.85, interpolate_old_and_new_14s=False): """ Initialize the Hybrid topology factory. Parameters ---------- old_system : openmm.System OpenMM system defining the "old" (i.e. starting) state. old_positions : [n,3] np.ndarray of float The positions of the "old system". old_topology : openmm.Topology OpenMM topology defining the "old" state. new_system: opemm.System OpenMM system defining the "new" (i.e. end) state. new_positions : [m,3] np.ndarray of float The positions of the "new system" new_topology : openmm.Topology OpenMM topology defining the "new" state. old_to_new_atom_map : dict of int : int Dictionary of corresponding atoms between the old and new systems. Unique atoms are not included in this atom map. old_to_new_core_atom_map : dict of int : int Dictionary of corresponding atoms between the alchemical "core atoms" (i.e. residues which are changing) between the old and new systems. use_dispersion_correction : bool, default False Whether to use the long range correction in the custom sterics force. This can be very expensive for NCMC. softcore_alpha: float, default None "alpha" parameter of softcore sterics, default 0.5. softcore_LJ_v2 : bool, default True Implement the softcore LJ as defined by Gapsys et al. JCTC 2012. softcore_LJ_v2_alpha : float, default 0.85 Softcore alpha parameter for LJ v2 interpolate_old_and_new_14s : bool, default False Whether to turn off interactions for new exceptions (not just 1,4s) at lambda = 0 and old exceptions at lambda = 1; if False, they are present in the nonbonded force. """ # Assign system positions and force # IA - Are deep copies really needed here? self._old_system = copy.deepcopy(old_system) self._old_positions = old_positions self._old_topology = old_topology self._new_system = copy.deepcopy(new_system) self._new_positions = new_positions self._new_topology = new_topology self._hybrid_system_forces = dict() # Set mappings (full, core, and env maps) self._set_mappings(old_to_new_atom_map, old_to_new_core_atom_map) # Other options self._use_dispersion_correction = use_dispersion_correction self._interpolate_14s = interpolate_old_and_new_14s # Sofcore options self._softcore_alpha = softcore_alpha self._check_bounds(softcore_alpha, "softcore_alpha") # [0,1] check self._softcore_LJ_v2 = softcore_LJ_v2 if self._softcore_LJ_v2: self._check_bounds(softcore_LJ_v2_alpha, "softcore_LJ_v2_alpha") self._softcore_LJ_v2_alpha = softcore_LJ_v2_alpha # TODO: end __init__ here and move everything else to # create_hybrid_system() or equivalent self._check_and_store_system_forces() logger.info("Creating hybrid system") # Create empty system that will become the hybrid system self._hybrid_system = openmm.System() # Add particles to system self._add_particles() # Add box + barostat self._handle_box() # Assign atoms to one of the classes described in the class docstring # Renamed from original _determine_atom_classes self._set_atom_classes() # Construct dictionary of exceptions in old and new systems self._old_system_exceptions = self._generate_dict_from_exceptions( self._old_system_forces['NonbondedForce']) self._new_system_exceptions = self._generate_dict_from_exceptions( self._new_system_forces['NonbondedForce']) # check for exceptions clashes between unique and env atoms self._validate_disjoint_sets() logger.info("Setting force field terms") # Copy constraints, checking to make sure they are not changing self._handle_constraints() # Copy over relevant virtual sites - pick up refactor from here self._handle_virtual_sites() # TODO - move to a single method call? Would be good to group these # Call each of the force methods to add the corresponding force terms # and prepare the forces: self._add_bond_force_terms() self._add_angle_force_terms() self._add_torsion_force_terms() has_nonbonded_force = ('NonbondedForce' in self._old_system_forces or 'NonbondedForce' in self._new_system_forces) if has_nonbonded_force: self._add_nonbonded_force_terms() # Call each force preparation method to generate the actual # interactions that we need: logger.info("Adding forces") self._handle_harmonic_bonds() self._handle_harmonic_angles() self._handle_periodic_torsion_force() # add cmap terms if possible self._handle_cmap_torsion_force() if has_nonbonded_force: self._handle_nonbonded() if not (len(self._old_system_exceptions.keys()) == 0 and len(self._new_system_exceptions.keys()) == 0): self._handle_old_new_exceptions() # Get positions for the hybrid self._hybrid_positions = self._compute_hybrid_positions() # Get an MDTraj topology for writing self._hybrid_topology = self._create_mdtraj_topology() self._omm_hybrid_topology = self._create_hybrid_topology() logger.info("Hybrid system created") @staticmethod def _verify_cmap_compatibility( cmap_old: openmm.CMAPTorsionForce, cmap_new: openmm.CMAPTorsionForce, ) -> tuple[ int, int, int, int, ]: """ Verify CMAPTorsionForce compatibility between two systems. Parameters ---------- cmap_old : openmm.CMAPTorsionForce CMAPTorsionForce from the old system cmap_new : openmm.CMAPTorsionForce CMAPTorsionForce from the new system Returns ------- tuple (old_num_maps, new_num_maps, old_num_torsions, new_num_torsions) four integers describing the number of maps and torsions in each force. Raises ------ RuntimeError If only one of the forces is present, or if the number of maps or the number of torsions differs between the two forces. """ logger.info("CMAPTorsionForce found checking compatibility") # some quick checks on compatibility like the number of maps and total number of terms old_num_maps = cmap_old.getNumMaps() new_num_maps = cmap_new.getNumMaps() if old_num_maps != new_num_maps: raise RuntimeError( f"Incompatible CMAPTorsionForce between end states expected to have same number of maps, " f"found old: {old_num_maps} and new: {new_num_maps}") old_num_torsions = cmap_old.getNumTorsions() new_num_torsions = cmap_new.getNumTorsions() if old_num_torsions != new_num_torsions: raise RuntimeError( f"Incompatible CMAPTorsionForce between end states expected to have same number of torsions, " f"found old: {old_num_torsions} and new: {new_num_torsions}") return old_num_maps, new_num_maps, old_num_torsions, new_num_torsions def _handle_cmap_torsion_force(self): """ This method does the following in order: - Some basic checks that the CMAPTorsionForce exists in both old/new systems. - Adds the CMAPTorsionForce from the old system - Checks that the new system CMAPTorsionForce terms are equal to the old system's (we do not allow for alchemically changing CMAP terms). """ cmap_old = self._old_system_forces.get("CMAPTorsionForce", None) cmap_new = self._new_system_forces.get("CMAPTorsionForce", None) # if only one has cmap raise an error if (cmap_new is None) ^ (cmap_old is None): raise RuntimeError(f"Inconsistent CMAPTorsionForce between end states expected to be present in both" f"but found in old: {bool(cmap_old)} and new: {bool(cmap_new)}") if cmap_new == cmap_old is None: logger.info("No CMAPTorsionForce found. Skipping adding force.") return # verify compatibility and extract numbers of maps and torsions ( old_num_maps, new_num_maps, old_num_torsions, new_num_torsions ) = self._verify_cmap_compatibility( cmap_old, cmap_new ) logger.info("Adding CMAPTorsionForce to hybrid system") # start looping through the old system terms and add them to the hybrid system # track the terms we add so we can cross compare with the new system and also make sure we don't hit # an index in the alchemical region hybrid_cmap_force = openmm.CMAPTorsionForce() self._hybrid_system.addForce(hybrid_cmap_force) self._hybrid_system_forces["cmap_torsion_force"] = hybrid_cmap_force old_system_maps = {} old_system_terms = {} logger.info("Adding CMAP forces") # add all the old maps for i in range(old_num_maps): size, energy = cmap_old.getMapParameters(i) old_system_maps[i] = (size, energy) # also add the map to the hybrid system hybrid_cmap_force.addMap(size, energy) logger.info("Adding CMAP force terms") # now add the terms we need to map from the old to the new index old_to_hybrid_index = self._old_to_hybrid_map new_to_hybrid_index = self._new_to_hybrid_map for i in range(old_num_torsions): # get the parameters for the torsion using the same notation as OpenMM map_index, a1, a2, a3, a4, b1, b2, b3, b4 = cmap_old.getTorsionParameters(i) atom_ids = [a1, a2, a3, a4, b1, b2, b3, b4] # map to hybrid indices hybrid_atom_ids = [old_to_hybrid_index[a_id] for a_id in atom_ids] # add to the hybrid system using the hybrid index hybrid_cmap_force.addTorsion(map_index, *hybrid_atom_ids) # track the atoms we add in the hybrid system to cross compare with new system old_system_terms[tuple(hybrid_atom_ids)] = map_index # gather all alchemical atoms, use a copy so we don't change the groups alchemical_atoms = self._atom_classes["core_atoms"].copy() alchemical_atoms.update(self._atom_classes["unique_old_atoms"], self._atom_classes["unique_new_atoms"]) # check if any of the atoms added are in the alchemical region old_added_atoms = {atom_id for atoms in old_system_terms.keys() for atom_id in atoms} if overlap_atoms := alchemical_atoms.intersection(old_added_atoms): raise RuntimeError( f"Incompatible CMAPTorsionForce term found in alchemical region for old system atoms {overlap_atoms}") # now loop over the new system force and check the terms are compatible # we expect to add no new terms for i in range(new_num_maps): size, energy = cmap_new.getMapParameters(i) if (size, energy) != old_system_maps[i]: raise RuntimeError(f"Incompatible CMAPTorsionForce map parameters found between end states for map {i} " f"expected {old_system_maps[i]} found {(size, energy)}") for i in range(new_num_torsions): map_index, a1, a2, a3, a4, b1, b2, b3, b4 = cmap_new.getTorsionParameters(i) atom_ids = [a1, a2, a3, a4, b1, b2, b3, b4] # map to hybrid indices hybrid_atom_ids = [new_to_hybrid_index[a_id] for a_id in atom_ids] # check its in the old system terms if tuple(hybrid_atom_ids) not in old_system_terms.keys(): raise RuntimeError( f"Incompatible CMAPTorsionForce term found between end states for atoms {hybrid_atom_ids} " f"not found in old system terms.") # check the map index is the same if map_index != old_system_terms[tuple(hybrid_atom_ids)]: raise RuntimeError( f"Incompatible CMAPTorsionForce map index found between end states for atoms {hybrid_atom_ids} " f"expected {old_system_terms[tuple(hybrid_atom_ids)]} found {map_index}") logger.info("CMAPTorsionForce added to the hybrid system") @staticmethod def _check_bounds(value, varname, minmax=(0, 1)): """ Convenience method to check the bounds of a value. Parameters ---------- value : float Value to evaluate. varname : str Name of value to raise in error message minmax : tuple Two element tuple with the lower and upper bounds to check. Raises ------ AssertionError If value is lower or greater than bounds. """ if value < minmax[0] or value > minmax[1]: raise AssertionError(f"{varname} is not in {minmax}") @staticmethod def _invert_dict(dictionary): """ Convenience method to invert a dictionary (since we do it so often). Parameters: ---------- dictionary : dict Dictionary you want to invert """ return {v: k for k, v in dictionary.items()} def _set_mappings(self, old_to_new_map, core_old_to_new_map): """ Parameters ---------- old_to_new_map : dict of int : int Dictionary mapping atoms between the old and new systems. Notes ----- * For now this directly sets the system, core and env old_to_new_map, new_to_old_map, an empty new_to_hybrid_map and an empty old_to_hybrid_map. In the future this will be moved to the one dictionary to make things a lot less confusing. """ self._old_to_new_map = old_to_new_map self._core_old_to_new_map = core_old_to_new_map self._new_to_old_map = self._invert_dict(old_to_new_map) self._core_new_to_old_map = self._invert_dict(core_old_to_new_map) self._old_to_hybrid_map = {} self._new_to_hybrid_map = {} # Get unique atoms # old system first self._unique_old_atoms = [] for particle_idx in range(self._old_system.getNumParticles()): if particle_idx not in self._old_to_new_map.keys(): self._unique_old_atoms.append(particle_idx) self._unique_new_atoms = [] for particle_idx in range(self._new_system.getNumParticles()): if particle_idx not in self._new_to_old_map.keys(): self._unique_new_atoms.append(particle_idx) # Get env atoms (i.e. atoms mapped not in core) self._env_old_to_new_map = {} for key, value in old_to_new_map.items(): if key not in self._core_old_to_new_map.keys(): self._env_old_to_new_map[key] = value self._env_new_to_old_map = self._invert_dict(self._env_old_to_new_map) # IA - Internal check for now (move to test later) num_env = len(self._env_old_to_new_map.keys()) num_core = len(self._core_old_to_new_map.keys()) num_total = len(self._old_to_new_map.keys()) assert num_env + num_core == num_total def _check_and_store_system_forces(self): """ Conveniently stores the system forces and checks that no unknown forces exist. """ def _check_unknown_forces(forces, system_name): # TODO: double check that CMMotionRemover is ok being here known_forces = { 'HarmonicBondForce', 'HarmonicAngleForce', 'PeriodicTorsionForce', 'NonbondedForce', 'MonteCarloBarostat', 'CMMotionRemover', 'CMAPTorsionForce', 'MonteCarloMembraneBarostat', } force_names = forces.keys() unknown_forces = set(force_names) - set(known_forces) if unknown_forces: errmsg = (f"Unknown forces {unknown_forces} encountered in " f"{system_name} system") raise ValueError(errmsg) # Prepare dicts of forces, which will be useful later # TODO: Store this as self._system_forces[name], name in ('old', # 'new', 'hybrid') for compactness self._old_system_forces = {type(force).__name__: force for force in self._old_system.getForces()} _check_unknown_forces(self._old_system_forces, 'old') self._new_system_forces = {type(force).__name__: force for force in self._new_system.getForces()} _check_unknown_forces(self._new_system_forces, 'new') # TODO: check if this is actually used much, otherwise ditch it # Get and store the nonbonded method from the system: self._nonbonded_method = self._old_system_forces['NonbondedForce'].getNonbondedMethod() def _add_particles(self): """ Adds particles to the hybrid system. This does not copy over interactions, but does copy over the masses. Note ---- * If there is a difference in masses between the old and new systems the average mass of the two is used. TODO ---- * Review influence of lack of mass scaling. """ # Begin by copying all particles in the old system for particle_idx in range(self._old_system.getNumParticles()): mass_old = self._old_system.getParticleMass(particle_idx) if particle_idx in self._old_to_new_map.keys(): particle_idx_new_system = self._old_to_new_map[particle_idx] mass_new = self._new_system.getParticleMass( particle_idx_new_system) # Take the average of the masses if the atom is mapped particle_mass = (mass_old + mass_new) / 2 else: particle_mass = mass_old hybrid_idx = self._hybrid_system.addParticle(particle_mass) self._old_to_hybrid_map[particle_idx] = hybrid_idx # If the particle index in question is mapped, make sure to add it # to the new to hybrid map as well. if particle_idx in self._old_to_new_map.keys(): self._new_to_hybrid_map[particle_idx_new_system] = hybrid_idx # Next, add the remaining unique atoms from the new system to the # hybrid system and map accordingly. for particle_idx in self._unique_new_atoms: particle_mass = self._new_system.getParticleMass(particle_idx) hybrid_idx = self._hybrid_system.addParticle(particle_mass) self._new_to_hybrid_map[particle_idx] = hybrid_idx # Create the opposite atom maps for later use (nonbonded processing) self._hybrid_to_old_map = self._invert_dict(self._old_to_hybrid_map) self._hybrid_to_new_map = self._invert_dict(self._new_to_hybrid_map) def _handle_box(self): """ Copies over the barostat and box vectors as necessary. """ # Check that if there is a barostat in the old system, # it is added to the hybrid system present_barostat = [ i for i in self._old_system_forces.keys() if i in ["MonteCarloBarostat", "MonteCarloMembraneBarostat"] ] if len(present_barostat) == 1: barostat = copy.deepcopy( self._old_system_forces[present_barostat[0]]) self._hybrid_system.addForce(barostat) elif len(present_barostat) > 1: errmsg = "More than 1 barostat are present which is not supported" raise ValueError(errmsg) # Copy over the box vectors from the old system box_vectors = self._old_system.getDefaultPeriodicBoxVectors() self._hybrid_system.setDefaultPeriodicBoxVectors(*box_vectors) def _set_atom_classes(self): """ This method determines whether each atom belongs to unique old, unique new, core, or environment, as defined in the class docstring. All indices are indices in the hybrid system. """ self._atom_classes = {'unique_old_atoms': set(), 'unique_new_atoms': set(), 'core_atoms': set(), 'environment_atoms': set()} # First, find the unique old atoms for atom_idx in self._unique_old_atoms: hybrid_idx = self._old_to_hybrid_map[atom_idx] self._atom_classes['unique_old_atoms'].add(hybrid_idx) # Then the unique new atoms for atom_idx in self._unique_new_atoms: hybrid_idx = self._new_to_hybrid_map[atom_idx] self._atom_classes['unique_new_atoms'].add(hybrid_idx) # The core atoms: for new_idx, old_idx in self._core_new_to_old_map.items(): new_to_hybrid_idx = self._new_to_hybrid_map[new_idx] old_to_hybrid_idx = self._old_to_hybrid_map[old_idx] if new_to_hybrid_idx != old_to_hybrid_idx: errmsg = (f"there is an index collision in hybrid indices of " f"the core atom map: {self._core_new_to_old_map}") raise AssertionError(errmsg) self._atom_classes['core_atoms'].add(new_to_hybrid_idx) # The environment atoms: for new_idx, old_idx in self._env_new_to_old_map.items(): new_to_hybrid_idx = self._new_to_hybrid_map[new_idx] old_to_hybrid_idx = self._old_to_hybrid_map[old_idx] if new_to_hybrid_idx != old_to_hybrid_idx: errmsg = (f"there is an index collion in hybrid indices of " f"the environment atom map: " f"{self._env_new_to_old_map}") raise AssertionError(errmsg) self._atom_classes['environment_atoms'].add(new_to_hybrid_idx) @staticmethod def _generate_dict_from_exceptions(force): """ This is a utility function to generate a dictionary of the form (particle1_idx, particle2_idx) : [exception parameters]. This will facilitate access and search of exceptions. Parameters ---------- force : openmm.NonbondedForce object a force containing exceptions Returns ------- exceptions_dict : dict Dictionary of exceptions """ exceptions_dict = {} for exception_index in range(force.getNumExceptions()): [index1, index2, chargeProd, sigma, epsilon] = force.getExceptionParameters(exception_index) exceptions_dict[(index1, index2)] = [chargeProd, sigma, epsilon] return exceptions_dict def _validate_disjoint_sets(self): """ Conduct a sanity check to make sure that the hybrid maps of the old and new system exception dict keys do not contain both environment and unique_old/new atoms. TODO: repeated code - condense """ for old_indices in self._old_system_exceptions.keys(): hybrid_indices = (self._old_to_hybrid_map[old_indices[0]], self._old_to_hybrid_map[old_indices[1]]) old_env_intersection = set(old_indices).intersection( self._atom_classes['environment_atoms']) if old_env_intersection: if set(old_indices).intersection( self._atom_classes['unique_old_atoms'] ): errmsg = (f"old index exceptions {old_indices} include " "unique old and environment atoms, which is " "disallowed") raise AssertionError(errmsg) for new_indices in self._new_system_exceptions.keys(): hybrid_indices = (self._new_to_hybrid_map[new_indices[0]], self._new_to_hybrid_map[new_indices[1]]) new_env_intersection = set(hybrid_indices).intersection( self._atom_classes['environment_atoms']) if new_env_intersection: if set(hybrid_indices).intersection( self._atom_classes['unique_new_atoms'] ): errmsg = (f"new index exceptions {new_indices} include " "unique new and environment atoms, which is " "disallowed") raise AssertionError def _handle_constraints(self): """ This method adds relevant constraints from the old and new systems. First, all constraints from the old systenm are added. Then, constraints to atoms unique to the new system are added. TODO: condense duplicated code """ # lengths of constraints already added constraint_lengths = dict() # old system hybrid_map = self._old_to_hybrid_map for const_idx in range(self._old_system.getNumConstraints()): at1, at2, length = self._old_system.getConstraintParameters( const_idx) hybrid_atoms = tuple(sorted([hybrid_map[at1], hybrid_map[at2]])) if hybrid_atoms not in constraint_lengths.keys(): self._hybrid_system.addConstraint(hybrid_atoms[0], hybrid_atoms[1], length) constraint_lengths[hybrid_atoms] = length else: if constraint_lengths[hybrid_atoms] != length: raise AssertionError('constraint length is changing') # new system hybrid_map = self._new_to_hybrid_map for const_idx in range(self._new_system.getNumConstraints()): at1, at2, length = self._new_system.getConstraintParameters( const_idx) hybrid_atoms = tuple(sorted([hybrid_map[at1], hybrid_map[at2]])) if hybrid_atoms not in constraint_lengths.keys(): self._hybrid_system.addConstraint(hybrid_atoms[0], hybrid_atoms[1], length) constraint_lengths[hybrid_atoms] = length else: if constraint_lengths[hybrid_atoms] != length: raise AssertionError('constraint length is changing') @staticmethod def _copy_threeparticleavg(atm_map, env_atoms, vs): """ Helper method to copy a ThreeParticleAverageSite virtual site from two mapped Systems. Parameters ---------- atm_map : dict[int, int] The atom map correspondence between the two Systems. env_atoms: set[int] A list of environment atoms for the target System. This checks that no alchemical atoms are being tied to. vs : openmm.ThreeParticleAverageSite Returns ------- openmm.ThreeParticleAverageSite """ particles = {} weights = {} for i in range(vs.getNumParticles()): particles[i] = atm_map[vs.getParticle(i)] weights[i] = vs.getWeight(i) if not all(i in env_atoms for i in particles.values()): errmsg = ("Virtual sites bound to non-environment atoms " "are not supported") raise ValueError(errmsg) return openmm.ThreeParticleAverageSite( particles[0], particles[1], particles[2], weights[0], weights[1], weights[2], ) def _handle_virtual_sites(self): """ Ensure that all virtual sites in old and new system are copied over to the hybrid system. Note that we do not support virtual sites in the changing region. TODO - remerge into a single loop TODO - check that it's fine to double count here (even so, there's an optimisation that could be done here...) """ # old system # Loop through virtual sites for particle_idx in range(self._old_system.getNumParticles()): if self._old_system.isVirtualSite(particle_idx): # If it's a virtual site, make sure it is not in the unique or # core atoms, since this is currently unsupported hybrid_idx = self._old_to_hybrid_map[particle_idx] if hybrid_idx not in self._atom_classes['environment_atoms']: errmsg = ("Virtual sites in changing residue are " "unsupported.") raise ValueError(errmsg) else: virtual_site = self._old_system.getVirtualSite( particle_idx) if isinstance( virtual_site, openmm.ThreeParticleAverageSite): vs_copy = self._copy_threeparticleavg( self._old_to_hybrid_map, self._atom_classes['environment_atoms'], virtual_site, ) else: errmsg = ("Unsupported VirtualSite " f"class: {virtual_site}") raise ValueError(errmsg) self._hybrid_system.setVirtualSite(hybrid_idx, vs_copy) # new system - there should be nothing left to add # Loop through virtual sites for particle_idx in range(self._new_system.getNumParticles()): if self._new_system.isVirtualSite(particle_idx): # If it's a virtual site, make sure it is not in the unique or # core atoms, since this is currently unsupported hybrid_idx = self._new_to_hybrid_map[particle_idx] if hybrid_idx not in self._atom_classes['environment_atoms']: errmsg = ("Virtual sites in changing residue are " "unsupported.") raise ValueError(errmsg) else: if not self._hybrid_system.isVirtualSite(hybrid_idx): errmsg = ("Environment virtual site in new system " "found not copied from old system") raise ValueError(errmsg) def _add_bond_force_terms(self): """ This function adds the appropriate bond forces to the system (according to groups defined in the main class docstring). Note that it does _not_ add the particles to the force. It only adds the force to facilitate another method adding the particles to the force. Notes ----- * User defined functions have been removed for now. """ core_energy_expression = '(K/2)*(r-length)^2;' # linearly interpolate spring constant core_energy_expression += 'K = (1-lambda_bonds)*K1 + lambda_bonds*K2;' # linearly interpolate bond length core_energy_expression += 'length = (1-lambda_bonds)*length1 + lambda_bonds*length2;' # Create the force and add the relevant parameters custom_core_force = openmm.CustomBondForce(core_energy_expression) custom_core_force.addPerBondParameter('length1') # old bond length custom_core_force.addPerBondParameter('K1') # old spring constant custom_core_force.addPerBondParameter('length2') # new bond length custom_core_force.addPerBondParameter('K2') # new spring constant custom_core_force.addGlobalParameter('lambda_bonds', 0.0) self._hybrid_system.addForce(custom_core_force) self._hybrid_system_forces['core_bond_force'] = custom_core_force # Add a bond force for environment and unique atoms (bonds are never # scaled for these): standard_bond_force = openmm.HarmonicBondForce() self._hybrid_system.addForce(standard_bond_force) self._hybrid_system_forces['standard_bond_force'] = standard_bond_force def _add_angle_force_terms(self): """ This function adds the appropriate angle force terms to the hybrid system. It does not add particles or parameters to the force; this is done elsewhere. Notes ----- * User defined functions have been removed for now. * Neglected angle terms have been removed for now. """ energy_expression = '(K/2)*(theta-theta0)^2;' # linearly interpolate spring constant energy_expression += 'K = (1.0-lambda_angles)*K_1 + lambda_angles*K_2;' # linearly interpolate equilibrium angle energy_expression += 'theta0 = (1.0-lambda_angles)*theta0_1 + lambda_angles*theta0_2;' # Create the force and add relevant parameters custom_core_force = openmm.CustomAngleForce(energy_expression) # molecule1 equilibrium angle custom_core_force.addPerAngleParameter('theta0_1') # molecule1 spring constant custom_core_force.addPerAngleParameter('K_1') # molecule2 equilibrium angle custom_core_force.addPerAngleParameter('theta0_2') # molecule2 spring constant custom_core_force.addPerAngleParameter('K_2') custom_core_force.addGlobalParameter('lambda_angles', 0.0) # Add the force to the system and the force dict. self._hybrid_system.addForce(custom_core_force) self._hybrid_system_forces['core_angle_force'] = custom_core_force # Add an angle term for environment/unique interactions -- these are # never scaled standard_angle_force = openmm.HarmonicAngleForce() self._hybrid_system.addForce(standard_angle_force) self._hybrid_system_forces['standard_angle_force'] = standard_angle_force def _add_torsion_force_terms(self): """ This function adds the appropriate PeriodicTorsionForce terms to the system. Core torsions are interpolated, while environment and unique torsions are always on. Notes ----- * User defined functions have been removed for now. * Options for add_custom_core_force (default True) and add_unique_atom_torsion_force (default True) have been removed for now. """ energy_expression = '(1-lambda_torsions)*U1 + lambda_torsions*U2;' energy_expression += 'U1 = K1*(1+cos(periodicity1*theta-phase1));' energy_expression += 'U2 = K2*(1+cos(periodicity2*theta-phase2));' # Create the force and add the relevant parameters custom_core_force = openmm.CustomTorsionForce(energy_expression) # molecule1 periodicity custom_core_force.addPerTorsionParameter('periodicity1') # molecule1 phase custom_core_force.addPerTorsionParameter('phase1') # molecule1 spring constant custom_core_force.addPerTorsionParameter('K1') # molecule2 periodicity custom_core_force.addPerTorsionParameter('periodicity2') # molecule2 phase custom_core_force.addPerTorsionParameter('phase2') # molecule2 spring constant custom_core_force.addPerTorsionParameter('K2') custom_core_force.addGlobalParameter('lambda_torsions', 0.0) # Add the force to the system self._hybrid_system.addForce(custom_core_force) self._hybrid_system_forces['custom_torsion_force'] = custom_core_force # Create and add the torsion term for unique/environment atoms unique_atom_torsion_force = openmm.PeriodicTorsionForce() self._hybrid_system.addForce(unique_atom_torsion_force) self._hybrid_system_forces['unique_atom_torsion_force'] = unique_atom_torsion_force @staticmethod def _nonbonded_custom(v2): """ Get a part of the nonbonded energy expression when there is no cutoff. Parameters ---------- v2 : bool Whether to use the softcore methods as defined by Gapsys et al. JCTC 2012. Returns ------- sterics_energy_expression : str The energy expression for U_sterics electrostatics_energy_expression : str The energy expression for electrostatics TODO ---- * Move to a dictionary or equivalent. """ # Soft-core Lennard-Jones if v2: sterics_energy_expression = "U_sterics = select(step(r - r_LJ), 4*epsilon*x*(x-1.0), U_sterics_quad);" sterics_energy_expression += "U_sterics_quad = Force*(((r - r_LJ)^2)/2 - (r - r_LJ)) + U_sterics_cut;" sterics_energy_expression += "U_sterics_cut = 4*epsilon*((sigma/r_LJ)^6)*(((sigma/r_LJ)^6) - 1.0);" sterics_energy_expression += "Force = -4*epsilon*((-12*sigma^12)/(r_LJ^13) + (6*sigma^6)/(r_LJ^7));" sterics_energy_expression += "x = (sigma/r)^6;" sterics_energy_expression += "r_LJ = softcore_alpha*((26/7)*(sigma^6)*lambda_sterics_deprecated)^(1/6);" sterics_energy_expression += "lambda_sterics_deprecated = new_interaction*(1.0 - lambda_sterics_insert) + old_interaction*lambda_sterics_delete;" else: sterics_energy_expression = "U_sterics = 4*epsilon*x*(x-1.0); x = (sigma/reff_sterics)^6;" return sterics_energy_expression @staticmethod def _nonbonded_custom_sterics_common(): """ Get a custom sterics expression using amber softcore expression Returns ------- sterics_addition : str The common softcore sterics energy expression TODO ---- * Move to a dictionary or equivalent. """ # interpolation sterics_addition = "epsilon = (1-lambda_sterics)*epsilonA + lambda_sterics*epsilonB;" # effective softcore distance for sterics sterics_addition += "reff_sterics = sigma*((softcore_alpha*lambda_alpha + (r/sigma)^6))^(1/6);" sterics_addition += "sigma = (1-lambda_sterics)*sigmaA + lambda_sterics*sigmaB;" sterics_addition += "lambda_alpha = new_interaction*(1-lambda_sterics_insert) + old_interaction*lambda_sterics_delete;" sterics_addition += "lambda_sterics = core_interaction*lambda_sterics_core + new_interaction*lambda_sterics_insert + old_interaction*lambda_sterics_delete;" sterics_addition += "core_interaction = delta(unique_old1+unique_old2+unique_new1+unique_new2);new_interaction = max(unique_new1, unique_new2);old_interaction = max(unique_old1, unique_old2);" return sterics_addition @staticmethod def _nonbonded_custom_mixing_rules(): """ Mixing rules for the custom nonbonded force. Returns ------- sterics_mixing_rules : str The mixing expression for sterics electrostatics_mixing_rules : str The mixiing rules for electrostatics TODO ---- * Move to a dictionary or equivalent. """ # Define mixing rules. # mixing rule for epsilon sterics_mixing_rules = "epsilonA = sqrt(epsilonA1*epsilonA2);" # mixing rule for epsilon sterics_mixing_rules += "epsilonB = sqrt(epsilonB1*epsilonB2);" # mixing rule for sigma sterics_mixing_rules += "sigmaA = 0.5*(sigmaA1 + sigmaA2);" # mixing rule for sigma sterics_mixing_rules += "sigmaB = 0.5*(sigmaB1 + sigmaB2);" return sterics_mixing_rules @staticmethod def _translate_nonbonded_method_to_custom(standard_nonbonded_method): """ Utility function to translate the nonbonded method enum from the standard nonbonded force to the custom version `CutoffPeriodic`, `PME`, and `Ewald` all become `CutoffPeriodic`; `NoCutoff` becomes `NoCutoff`; `CutoffNonPeriodic` becomes `CutoffNonPeriodic` Parameters ---------- standard_nonbonded_method : openmm.NonbondedForce.NonbondedMethod the nonbonded method of the standard force Returns ------- custom_nonbonded_method : openmm.CustomNonbondedForce.NonbondedMethod the nonbonded method for the equivalent customnonbonded force """ if standard_nonbonded_method in [openmm.NonbondedForce.CutoffPeriodic, openmm.NonbondedForce.PME, openmm.NonbondedForce.Ewald]: return openmm.CustomNonbondedForce.CutoffPeriodic elif standard_nonbonded_method == openmm.NonbondedForce.NoCutoff: return openmm.CustomNonbondedForce.NoCutoff elif standard_nonbonded_method == openmm.NonbondedForce.CutoffNonPeriodic: return openmm.CustomNonbondedForce.CutoffNonPeriodic else: errmsg = "This nonbonded method is not supported." raise NotImplementedError(errmsg) def _add_nonbonded_force_terms(self): """ Add the nonbonded force terms to the hybrid system. Note that as with the other forces, this method does not add any interactions. It only sets up the forces. Notes ----- * User defined functions have been removed for now. * Argument `add_custom_sterics_force` (default True) has been removed for now. TODO ---- * Move nonbonded_method defn here to avoid just setting it globally and polluting `self`. """ # Add a regular nonbonded force for all interactions that are not # changing. standard_nonbonded_force = openmm.NonbondedForce() self._hybrid_system.addForce(standard_nonbonded_force) self._hybrid_system_forces['standard_nonbonded_force'] = standard_nonbonded_force # Create a CustomNonbondedForce to handle alchemically interpolated # nonbonded parameters. # Select functional form based on nonbonded method. # TODO: check _nonbonded_custom_ewald and _nonbonded_custom_cutoff # since they take arguments that are never used... r_cutoff = self._old_system_forces['NonbondedForce'].getCutoffDistance() sterics_energy_expression = self._nonbonded_custom(self._softcore_LJ_v2) if self._nonbonded_method in [openmm.NonbondedForce.NoCutoff]: sterics_energy_expression = self._nonbonded_custom( self._softcore_LJ_v2) elif self._nonbonded_method in [openmm.NonbondedForce.CutoffPeriodic, openmm.NonbondedForce.CutoffNonPeriodic]: epsilon_solvent = self._old_system_forces['NonbondedForce'].getReactionFieldDielectric() standard_nonbonded_force.setReactionFieldDielectric( epsilon_solvent) standard_nonbonded_force.setCutoffDistance(r_cutoff) elif self._nonbonded_method in [openmm.NonbondedForce.PME, openmm.NonbondedForce.Ewald]: [alpha_ewald, nx, ny, nz] = self._old_system_forces['NonbondedForce'].getPMEParameters() delta = self._old_system_forces['NonbondedForce'].getEwaldErrorTolerance() standard_nonbonded_force.setPMEParameters(alpha_ewald, nx, ny, nz) standard_nonbonded_force.setEwaldErrorTolerance(delta) standard_nonbonded_force.setCutoffDistance(r_cutoff) else: errmsg = f"Nonbonded method {self._nonbonded_method} not supported" raise ValueError(errmsg) standard_nonbonded_force.setNonbondedMethod(self._nonbonded_method) sterics_energy_expression += self._nonbonded_custom_sterics_common() sterics_mixing_rules = self._nonbonded_custom_mixing_rules() custom_nonbonded_method = self._translate_nonbonded_method_to_custom( self._nonbonded_method) total_sterics_energy = "U_sterics;" + sterics_energy_expression + sterics_mixing_rules sterics_custom_nonbonded_force = openmm.CustomNonbondedForce( total_sterics_energy) # Match cutoff from non-custom NB forces sterics_custom_nonbonded_force.setCutoffDistance(r_cutoff) if self._softcore_LJ_v2: sterics_custom_nonbonded_force.addGlobalParameter( "softcore_alpha", self._softcore_LJ_v2_alpha) else: sterics_custom_nonbonded_force.addGlobalParameter( "softcore_alpha", self._softcore_alpha) # Lennard-Jones sigma initial sterics_custom_nonbonded_force.addPerParticleParameter("sigmaA") # Lennard-Jones epsilon initial sterics_custom_nonbonded_force.addPerParticleParameter("epsilonA") # Lennard-Jones sigma final sterics_custom_nonbonded_force.addPerParticleParameter("sigmaB") # Lennard-Jones epsilon final sterics_custom_nonbonded_force.addPerParticleParameter("epsilonB") # 1 = hybrid old atom, 0 otherwise sterics_custom_nonbonded_force.addPerParticleParameter("unique_old") # 1 = hybrid new atom, 0 otherwise sterics_custom_nonbonded_force.addPerParticleParameter("unique_new") sterics_custom_nonbonded_force.addGlobalParameter( "lambda_sterics_core", 0.0) sterics_custom_nonbonded_force.addGlobalParameter( "lambda_electrostatics_core", 0.0) sterics_custom_nonbonded_force.addGlobalParameter( "lambda_sterics_insert", 0.0) sterics_custom_nonbonded_force.addGlobalParameter( "lambda_sterics_delete", 0.0) sterics_custom_nonbonded_force.setNonbondedMethod( custom_nonbonded_method) self._hybrid_system.addForce(sterics_custom_nonbonded_force) self._hybrid_system_forces['core_sterics_force'] = sterics_custom_nonbonded_force # Set the use of dispersion correction to be the same between the new # nonbonded force and the old one: if self._old_system_forces['NonbondedForce'].getUseDispersionCorrection(): self._hybrid_system_forces['standard_nonbonded_force'].setUseDispersionCorrection(True) if self._use_dispersion_correction: sterics_custom_nonbonded_force.setUseLongRangeCorrection(True) else: self._hybrid_system_forces['standard_nonbonded_force'].setUseDispersionCorrection(False) if self._old_system_forces['NonbondedForce'].getUseSwitchingFunction(): switching_distance = self._old_system_forces['NonbondedForce'].getSwitchingDistance() standard_nonbonded_force.setUseSwitchingFunction(True) standard_nonbonded_force.setSwitchingDistance(switching_distance) sterics_custom_nonbonded_force.setUseSwitchingFunction(True) sterics_custom_nonbonded_force.setSwitchingDistance(switching_distance) else: standard_nonbonded_force.setUseSwitchingFunction(False) sterics_custom_nonbonded_force.setUseSwitchingFunction(False) @staticmethod def _find_bond_parameters(bond_force, index1, index2): """ This is a convenience function to find bond parameters in another system given the two indices. Parameters ---------- bond_force : openmm.HarmonicBondForce The bond force where the parameters should be found index1 : int Index1 (order does not matter) of the bond atoms index2 : int Index2 (order does not matter) of the bond atoms Returns ------- bond_parameters : list List of relevant bond parameters """ index_set = {index1, index2} # Loop through all the bonds: for bond_index in range(bond_force.getNumBonds()): parms = bond_force.getBondParameters(bond_index) if index_set == {parms[0], parms[1]}: return parms return [] def _handle_harmonic_bonds(self): """ This method adds the appropriate interaction for all bonds in the hybrid system. The scheme used is: 1) If the two atoms are both in the core, then we add to the CustomBondForce and interpolate between the two parameters 2) If one of the atoms is in core and the other is environment, we have to assert that the bond parameters do not change between the old and the new system; then, the parameters are added to the regular bond force 3) Otherwise, we add the bond to a regular bond force. Notes ----- * Bond softening logic has been removed for now. """ old_system_bond_force = self._old_system_forces['HarmonicBondForce'] new_system_bond_force = self._new_system_forces['HarmonicBondForce'] # First, loop through the old system bond forces and add relevant terms for bond_index in range(old_system_bond_force.getNumBonds()): # Get each set of bond parameters [index1_old, index2_old, r0_old, k_old] = old_system_bond_force.getBondParameters(bond_index) # Map the indices to the hybrid system, for which our atom classes # are defined. index1_hybrid = self._old_to_hybrid_map[index1_old] index2_hybrid = self._old_to_hybrid_map[index2_old] index_set = {index1_hybrid, index2_hybrid} # Now check if it is a subset of the core atoms (that is, both # atoms are in the core) # If it is, we need to find the parameters in the old system so # that we can interpolate if index_set.issubset(self._atom_classes['core_atoms']): index1_new = self._old_to_new_map[index1_old] index2_new = self._old_to_new_map[index2_old] new_bond_parameters = self._find_bond_parameters( new_system_bond_force, index1_new, index2_new) if not new_bond_parameters: r0_new = r0_old k_new = 0.0*unit.kilojoule_per_mole/unit.angstrom**2 else: # TODO - why is this being recalculated? [index1, index2, r0_new, k_new] = self._find_bond_parameters( new_system_bond_force, index1_new, index2_new) self._hybrid_system_forces['core_bond_force'].addBond( index1_hybrid, index2_hybrid, [r0_old, k_old, r0_new, k_new]) # Check if the index set is a subset of anything besides # environment (in the case of environment, we just add the bond to # the regular bond force) # that would mean that this bond is core-unique_old or # unique_old-unique_old # NOTE - These are currently all the same because we don't soften # TODO - work these out somewhere else, this is terribly difficult # to understand logic. elif (index_set.issubset(self._atom_classes['unique_old_atoms']) or (len(index_set.intersection(self._atom_classes['unique_old_atoms'])) == 1 and len(index_set.intersection(self._atom_classes['core_atoms'])) == 1)): # We can just add it to the regular bond force. self._hybrid_system_forces['standard_bond_force'].addBond( index1_hybrid, index2_hybrid, r0_old, k_old) elif (len(index_set.intersection(self._atom_classes['environment_atoms'])) == 1 and len(index_set.intersection(self._atom_classes['core_atoms'])) == 1): self._hybrid_system_forces['standard_bond_force'].addBond( index1_hybrid, index2_hybrid, r0_old, k_old) # Otherwise, we just add the same parameters as those in the old # system (these are environment atoms, and the parameters are the # same) elif index_set.issubset(self._atom_classes['environment_atoms']): self._hybrid_system_forces['standard_bond_force'].addBond( index1_hybrid, index2_hybrid, r0_old, k_old) else: errmsg = (f"hybrid index set {index_set} does not fit into a " "canonical atom type") raise ValueError(errmsg) # Now loop through the new system to get the interactions that are # unique to it. for bond_index in range(new_system_bond_force.getNumBonds()): # Get each set of bond parameters [index1_new, index2_new, r0_new, k_new] = new_system_bond_force.getBondParameters(bond_index) # Convert indices to hybrid, since that is how we represent atom classes: index1_hybrid = self._new_to_hybrid_map[index1_new] index2_hybrid = self._new_to_hybrid_map[index2_new] index_set = {index1_hybrid, index2_hybrid} # If the intersection of this set and unique new atoms contains # anything, the bond is unique to the new system and must be added # all other bonds in the new system have been accounted for already # NOTE - These are mostly all the same because we don't soften if (len(index_set.intersection(self._atom_classes['unique_new_atoms'])) == 2 or (len(index_set.intersection(self._atom_classes['unique_new_atoms'])) == 1 and len(index_set.intersection(self._atom_classes['core_atoms'])) == 1)): # If we aren't softening bonds, then just add it to the standard bond force self._hybrid_system_forces['standard_bond_force'].addBond( index1_hybrid, index2_hybrid, r0_new, k_new) # If the bond is in the core, it has probably already been added # in the above loop. However, there are some circumstances # where it was not (closing a ring). In that case, the bond has # not been added and should be added here. # This has some peculiarities to be discussed... # TODO - Work out what the above peculiarities are... elif index_set.issubset(self._atom_classes['core_atoms']): if not self._find_bond_parameters( self._hybrid_system_forces['core_bond_force'], index1_hybrid, index2_hybrid): r0_old = r0_new k_old = 0.0*unit.kilojoule_per_mole/unit.angstrom**2 self._hybrid_system_forces['core_bond_force'].addBond( index1_hybrid, index2_hybrid, [r0_old, k_old, r0_new, k_new]) elif index_set.issubset(self._atom_classes['environment_atoms']): # Already been added pass elif (len(index_set.intersection(self._atom_classes['environment_atoms'])) == 1 and len(index_set.intersection(self._atom_classes['core_atoms'])) == 1): pass else: errmsg = (f"hybrid index set {index_set} does not fit into a " "canonical atom type") raise ValueError(errmsg) @staticmethod def _find_angle_parameters(angle_force, indices): """ Convenience function to find the angle parameters corresponding to a particular set of indices Parameters ---------- angle_force : openmm.HarmonicAngleForce The force where the angle of interest may be found. indices : list of int The indices (any order) of the angle atoms Returns ------- angle_params : list list of angle parameters """ indices_reversed = indices[::-1] # Now loop through and try to find the angle: for angle_index in range(angle_force.getNumAngles()): angle_params = angle_force.getAngleParameters(angle_index) # Get a set representing the angle indices angle_param_indices = angle_params[:3] if (indices == angle_param_indices or indices_reversed == angle_param_indices): return angle_params return [] # Return empty if no matching angle found def _handle_harmonic_angles(self): """ This method adds the appropriate interaction for all angles in the hybrid system. The scheme used, as with bonds, is: 1) If the three atoms are all in the core, then we add to the CustomAngleForce and interpolate between the two parameters 2) If the three atoms contain at least one unique new, check if the angle is in the neglected new list, and if so, interpolate from K_1 = 0; else, if the three atoms contain at least one unique old, check if the angle is in the neglected old list, and if so, interpolate from K_2 = 0. 3) If the angle contains at least one environment and at least one core atom, assert there are no unique new atoms and that the angle terms are preserved between the new and the old system. Then add to the standard angle force. 4) Otherwise, we add the angle to a regular angle force since it is environment. Notes ----- * Removed softening and neglected angle functionality """ old_system_angle_force = self._old_system_forces['HarmonicAngleForce'] new_system_angle_force = self._new_system_forces['HarmonicAngleForce'] # First, loop through all the angles in the old system to determine # what to do with them. We will only use the # custom angle force if all atoms are part of "core." Otherwise, they # are either unique to one system or never change. for angle_index in range(old_system_angle_force.getNumAngles()): old_angle_parameters = old_system_angle_force.getAngleParameters( angle_index) # Get the indices in the hybrid system hybrid_index_list = [ self._old_to_hybrid_map[old_atomid] for old_atomid in old_angle_parameters[:3] ] hybrid_index_set = set(hybrid_index_list) # If all atoms are in the core, we'll need to find the # corresponding parameters in the old system and interpolate if hybrid_index_set.issubset(self._atom_classes['core_atoms']): # Get the new indices so we can get the new angle parameters new_indices = [ self._old_to_new_map[old_atomid] for old_atomid in old_angle_parameters[:3] ] new_angle_parameters = self._find_angle_parameters( new_system_angle_force, new_indices ) if not new_angle_parameters: new_angle_parameters = [ 0, 0, 0, old_angle_parameters[3], 0.0*unit.kilojoule_per_mole/unit.radian**2 ] # Add to the hybrid force: # the parameters at indices 3 and 4 represent theta0 and k, # respectively. hybrid_force_parameters = [ old_angle_parameters[3], old_angle_parameters[4], new_angle_parameters[3], new_angle_parameters[4] ] self._hybrid_system_forces['core_angle_force'].addAngle( hybrid_index_list[0], hybrid_index_list[1], hybrid_index_list[2], hybrid_force_parameters ) # Check if the atoms are neither all core nor all environment, # which would mean they involve unique old interactions elif not hybrid_index_set.issubset( self._atom_classes['environment_atoms']): # if there is an environment atom if hybrid_index_set.intersection( self._atom_classes['environment_atoms']): if hybrid_index_set.intersection( self._atom_classes['unique_old_atoms']): errmsg = "we disallow unique-environment terms" raise ValueError(errmsg) self._hybrid_system_forces['standard_angle_force'].addAngle( hybrid_index_list[0], hybrid_index_list[1], hybrid_index_list[2], old_angle_parameters[3], old_angle_parameters[4] ) else: # There are no env atoms, so we can treat this term # appropriately # We don't soften so just add this to the standard angle # force self._hybrid_system_forces['standard_angle_force'].addAngle( hybrid_index_list[0], hybrid_index_list[1], hybrid_index_list[2], old_angle_parameters[3], old_angle_parameters[4] ) # Otherwise, only environment atoms are in this interaction, so # add it to the standard angle force elif hybrid_index_set.issubset( self._atom_classes['environment_atoms']): self._hybrid_system_forces['standard_angle_force'].addAngle( hybrid_index_list[0], hybrid_index_list[1], hybrid_index_list[2], old_angle_parameters[3], old_angle_parameters[4] ) else: errmsg = (f"handle_harmonic_angles: angle_index {angle_index} " "does not fit a canonical form.") raise ValueError(errmsg) # Finally, loop through the new system force to add any unique new # angles for angle_index in range(new_system_angle_force.getNumAngles()): new_angle_parameters = new_system_angle_force.getAngleParameters( angle_index) # Get the indices in the hybrid system hybrid_index_list = [ self._new_to_hybrid_map[new_atomid] for new_atomid in new_angle_parameters[:3] ] hybrid_index_set = set(hybrid_index_list) # If the intersection of this hybrid set with the unique new atoms # is nonempty, it must be added: # TODO - there's a ton of len > 0 on sets, empty sets == False, # so we can simplify this logic. if len(hybrid_index_set.intersection( self._atom_classes['unique_new_atoms'])) > 0: if hybrid_index_set.intersection( self._atom_classes['environment_atoms']): errmsg = ("we disallow angle terms with unique new and " "environment atoms") raise ValueError(errmsg) # Not softening just add to the nonalchemical force self._hybrid_system_forces['standard_angle_force'].addAngle( hybrid_index_list[0], hybrid_index_list[1], hybrid_index_list[2], new_angle_parameters[3], new_angle_parameters[4] ) elif hybrid_index_set.issubset(self._atom_classes['core_atoms']): if not self._find_angle_parameters(self._hybrid_system_forces['core_angle_force'], hybrid_index_list): hybrid_force_parameters = [ new_angle_parameters[3], 0.0*unit.kilojoule_per_mole/unit.radian**2, new_angle_parameters[3], new_angle_parameters[4] ] self._hybrid_system_forces['core_angle_force'].addAngle( hybrid_index_list[0], hybrid_index_list[1], hybrid_index_list[2], hybrid_force_parameters ) elif hybrid_index_set.issubset(self._atom_classes['environment_atoms']): # We have already added the appropriate environmental atom # terms pass elif hybrid_index_set.intersection(self._atom_classes['environment_atoms']): if hybrid_index_set.intersection(self._atom_classes['unique_new_atoms']): errmsg = ("we disallow angle terms with unique new and " "environment atoms") raise ValueError(errmsg) else: errmsg = (f"hybrid index list {hybrid_index_list} does not " "fit into a canonical atom set") raise ValueError(errmsg) @staticmethod def _find_torsion_parameters(torsion_force, indices): """ Convenience function to find the torsion parameters corresponding to a particular set of indices. Parameters ---------- torsion_force : openmm.PeriodicTorsionForce torsion force where the torsion of interest may be found indices : list of int The indices of the atoms of the torsion Returns ------- torsion_parameters : list torsion parameters """ indices_reversed = indices[::-1] torsion_params_list = list() # Now loop through and try to find the torsion: for torsion_idx in range(torsion_force.getNumTorsions()): torsion_params = torsion_force.getTorsionParameters(torsion_idx) # Get a set representing the torsion indices: torsion_param_indices = torsion_params[:4] if (indices == torsion_param_indices or indices_reversed == torsion_param_indices): torsion_params_list.append(torsion_params) return torsion_params_list def _handle_periodic_torsion_force(self): """ Handle the torsions defined in the new and old systems as such: 1. old system torsions will enter the ``custom_torsion_force`` if they do not contain ``unique_old_atoms`` and will interpolate from ``on`` to ``off`` from ``lambda_torsions`` = 0 to 1, respectively. 2. new system torsions will enter the ``custom_torsion_force`` if they do not contain ``unique_new_atoms`` and will interpolate from ``off`` to ``on`` from ``lambda_torsions`` = 0 to 1, respectively. 3. old *and* new system torsions will enter the ``unique_atom_torsion_force`` (``standard_torsion_force``) and will *not* be interpolated. Notes ----- * Torsion flattening logic has been removed for now. """ old_system_torsion_force = self._old_system_forces['PeriodicTorsionForce'] new_system_torsion_force = self._new_system_forces['PeriodicTorsionForce'] auxiliary_custom_torsion_force = [] old_custom_torsions_to_standard = [] # We need to keep track of what torsions we added so that we do not # double count # added_torsions = [] # TODO: Commented out since this actually isn't being done anywhere? # Is it necessary? Should we add this logic back in? for torsion_index in range(old_system_torsion_force.getNumTorsions()): torsion_parameters = old_system_torsion_force.getTorsionParameters( torsion_index) # Get the indices in the hybrid system hybrid_index_list = [ self._old_to_hybrid_map[old_index] for old_index in torsion_parameters[:4] ] hybrid_index_set = set(hybrid_index_list) # If all atoms are in the core, we'll need to find the # corresponding parameters in the old system and interpolate if hybrid_index_set.intersection(self._atom_classes['unique_old_atoms']): # Then it goes to a standard force... self._hybrid_system_forces['unique_atom_torsion_force'].addTorsion( hybrid_index_list[0], hybrid_index_list[1], hybrid_index_list[2], hybrid_index_list[3], torsion_parameters[4], torsion_parameters[5], torsion_parameters[6] ) else: # It is a core-only term, an environment-only term, or a # core/env term; in any case, it goes to the core torsion_force # TODO - why are we even adding the 0.0, 0.0, 0.0 section? hybrid_force_parameters = [ torsion_parameters[4], torsion_parameters[5], torsion_parameters[6], 0.0, 0.0, 0.0 ] auxiliary_custom_torsion_force.append( [hybrid_index_list[0], hybrid_index_list[1], hybrid_index_list[2], hybrid_index_list[3], hybrid_force_parameters[:3]] ) for torsion_index in range(new_system_torsion_force.getNumTorsions()): torsion_parameters = new_system_torsion_force.getTorsionParameters(torsion_index) # Get the indices in the hybrid system: hybrid_index_list = [ self._new_to_hybrid_map[new_index] for new_index in torsion_parameters[:4]] hybrid_index_set = set(hybrid_index_list) if hybrid_index_set.intersection(self._atom_classes['unique_new_atoms']): # Then it goes to the custom torsion force (scaled to zero) self._hybrid_system_forces['unique_atom_torsion_force'].addTorsion( hybrid_index_list[0], hybrid_index_list[1], hybrid_index_list[2], hybrid_index_list[3], torsion_parameters[4], torsion_parameters[5], torsion_parameters[6] ) else: hybrid_force_parameters = [ 0.0, 0.0, 0.0, torsion_parameters[4], torsion_parameters[5], torsion_parameters[6]] # Check to see if this term is in the olds... term = [hybrid_index_list[0], hybrid_index_list[1], hybrid_index_list[2], hybrid_index_list[3], hybrid_force_parameters[3:]] if term in auxiliary_custom_torsion_force: # Then this terms has to go to standard and be deleted... old_index = auxiliary_custom_torsion_force.index(term) old_custom_torsions_to_standard.append(old_index) self._hybrid_system_forces['unique_atom_torsion_force'].addTorsion( hybrid_index_list[0], hybrid_index_list[1], hybrid_index_list[2], hybrid_index_list[3], torsion_parameters[4], torsion_parameters[5], torsion_parameters[6] ) else: # Then this term has to go to the core force... self._hybrid_system_forces['custom_torsion_force'].addTorsion( hybrid_index_list[0], hybrid_index_list[1], hybrid_index_list[2], hybrid_index_list[3], hybrid_force_parameters ) # Now we have to loop through the aux custom torsion force for index in [q for q in range(len(auxiliary_custom_torsion_force)) if q not in old_custom_torsions_to_standard]: terms = auxiliary_custom_torsion_force[index] hybrid_index_list = terms[:4] hybrid_force_parameters = terms[4] + [0., 0., 0.] self._hybrid_system_forces['custom_torsion_force'].addTorsion( hybrid_index_list[0], hybrid_index_list[1], hybrid_index_list[2], hybrid_index_list[3], hybrid_force_parameters ) def _handle_nonbonded(self): """ Handle the nonbonded interactions defined in the new and old systems. TODO ---- * Expand this docstring to explain the logic. * A lot of this logic is duplicated, probably turn it into a couple of functions. """ def _check_indices(idx1, idx2): if idx1 != idx2: errmsg = ("Attempting to add incorrect particle to hybrid " "system") raise ValueError(errmsg) old_system_nonbonded_force = self._old_system_forces['NonbondedForce'] new_system_nonbonded_force = self._new_system_forces['NonbondedForce'] hybrid_to_old_map = self._hybrid_to_old_map hybrid_to_new_map = self._hybrid_to_new_map # Define new global parameters for NonbondedForce self._hybrid_system_forces['standard_nonbonded_force'].addGlobalParameter('lambda_electrostatics_core', 0.0) self._hybrid_system_forces['standard_nonbonded_force'].addGlobalParameter('lambda_sterics_core', 0.0) self._hybrid_system_forces['standard_nonbonded_force'].addGlobalParameter("lambda_electrostatics_delete", 0.0) self._hybrid_system_forces['standard_nonbonded_force'].addGlobalParameter("lambda_electrostatics_insert", 0.0) # We have to loop through the particles in the system, because # nonbonded force does not accept index for particle_index in range(self._hybrid_system.getNumParticles()): if particle_index in self._atom_classes['unique_old_atoms']: # Get the parameters in the old system old_index = hybrid_to_old_map[particle_index] [charge, sigma, epsilon] = old_system_nonbonded_force.getParticleParameters(old_index) # Add the particle to the hybrid custom sterics and # electrostatics. # turning off sterics in forward direction check_index = self._hybrid_system_forces['core_sterics_force'].addParticle( [sigma, epsilon, sigma, 0.0*epsilon, 1, 0] ) _check_indices(particle_index, check_index) # Add particle to the regular nonbonded force, but # Lennard-Jones will be handled by CustomNonbondedForce check_index = self._hybrid_system_forces['standard_nonbonded_force'].addParticle( charge, sigma, 0.0*epsilon ) _check_indices(particle_index, check_index) # Charge will be turned off at # lambda_electrostatics_delete = 0, on at # lambda_electrostatics_delete = 1; kill charge with # lambda_electrostatics_delete = 0 --> 1 self._hybrid_system_forces['standard_nonbonded_force'].addParticleParameterOffset( 'lambda_electrostatics_delete', particle_index, -charge, 0*sigma, 0*epsilon ) elif particle_index in self._atom_classes['unique_new_atoms']: # Get the parameters in the new system new_index = hybrid_to_new_map[particle_index] [charge, sigma, epsilon] = new_system_nonbonded_force.getParticleParameters(new_index) # Add the particle to the hybrid custom sterics and electrostatics # turning on sterics in forward direction check_index = self._hybrid_system_forces['core_sterics_force'].addParticle( [sigma, 0.0*epsilon, sigma, epsilon, 0, 1] ) _check_indices(particle_index, check_index) # Add particle to the regular nonbonded force, but # Lennard-Jones will be handled by CustomNonbondedForce check_index = self._hybrid_system_forces['standard_nonbonded_force'].addParticle( 0.0, sigma, 0.0 ) # charge starts at zero _check_indices(particle_index, check_index) # Charge will be turned off at lambda_electrostatics_insert = 0 # on at lambda_electrostatics_insert = 1; # add charge with lambda_electrostatics_insert = 0 --> 1 self._hybrid_system_forces['standard_nonbonded_force'].addParticleParameterOffset( 'lambda_electrostatics_insert', particle_index, +charge, 0, 0 ) elif particle_index in self._atom_classes['core_atoms']: # Get the parameters in the new and old systems: old_index = hybrid_to_old_map[particle_index] [charge_old, sigma_old, epsilon_old] = old_system_nonbonded_force.getParticleParameters(old_index) new_index = hybrid_to_new_map[particle_index] [charge_new, sigma_new, epsilon_new] = new_system_nonbonded_force.getParticleParameters(new_index) # Add the particle to the custom forces, interpolating between # the two parameters; add steric params and zero electrostatics # to core_sterics per usual check_index = self._hybrid_system_forces['core_sterics_force'].addParticle( [sigma_old, epsilon_old, sigma_new, epsilon_new, 0, 0]) _check_indices(particle_index, check_index) # Still add the particle to the regular nonbonded force, but # with zeroed out parameters; add old charge to # standard_nonbonded and zero sterics check_index = self._hybrid_system_forces['standard_nonbonded_force'].addParticle( # this term is off due to epsilon = 0, but just set sigma to the initial value to not confuse things charge_old, sigma_old, 0.0) _check_indices(particle_index, check_index) # Charge is charge_old at lambda_electrostatics = 0, # charge_new at lambda_electrostatics = 1 # TODO: We could also interpolate the Lennard-Jones here # instead of core_sterics force so that core_sterics_force # could just be softcore. # Interpolate between old and new charge with # lambda_electrostatics core make sure to keep sterics off self._hybrid_system_forces['standard_nonbonded_force'].addParticleParameterOffset( 'lambda_electrostatics_core', particle_index, (charge_new - charge_old), 0, 0 ) # Otherwise, the particle is in the environment else: # The parameters will be the same in new and old system, so # just take the old parameters old_index = hybrid_to_old_map[particle_index] [charge, sigma, epsilon] = old_system_nonbonded_force.getParticleParameters(old_index) # Add the particle to the hybrid custom sterics, but they dont # change; electrostatics are ignored self._hybrid_system_forces['core_sterics_force'].addParticle( [sigma, epsilon, sigma, epsilon, 0, 0] ) # Add the environment atoms to the regular nonbonded force as # well: should we be adding steric terms here, too? self._hybrid_system_forces['standard_nonbonded_force'].addParticle( charge, sigma, epsilon ) # Now loop pairwise through (unique_old, unique_new) and add exceptions # so that they never interact electrostatically # (place into Nonbonded Force) unique_old_atoms = self._atom_classes['unique_old_atoms'] unique_new_atoms = self._atom_classes['unique_new_atoms'] for old in unique_old_atoms: for new in unique_new_atoms: self._hybrid_system_forces['standard_nonbonded_force'].addException( old, new, 0.0*unit.elementary_charge**2, 1.0*unit.nanometers, 0.0*unit.kilojoules_per_mole) # This is only necessary to avoid the 'All forces must have # identical exclusions' rule self._hybrid_system_forces['core_sterics_force'].addExclusion(old, new) self._handle_interaction_groups() self._handle_hybrid_exceptions() self._handle_original_exceptions() def _handle_interaction_groups(self): """ Create the appropriate interaction groups for the custom nonbonded forces. The groups are: 1) Unique-old - core 2) Unique-old - environment 3) Unique-new - core 4) Unique-new - environment 5) Core - environment 6) Core - core Unique-old and Unique new are prevented from interacting this way, and intra-unique interactions occur in an unmodified nonbonded force. Must be called after particles are added to the Nonbonded forces TODO: we should also be adding the following interaction groups... 7) Unique-new - Unique-new 8) Unique-old - Unique-old """ # Get the force objects for convenience: sterics_custom_force = self._hybrid_system_forces['core_sterics_force'] # Also prepare the atom classes core_atoms = self._atom_classes['core_atoms'] unique_old_atoms = self._atom_classes['unique_old_atoms'] unique_new_atoms = self._atom_classes['unique_new_atoms'] environment_atoms = self._atom_classes['environment_atoms'] sterics_custom_force.addInteractionGroup(unique_old_atoms, core_atoms) sterics_custom_force.addInteractionGroup(unique_old_atoms, environment_atoms) sterics_custom_force.addInteractionGroup(unique_new_atoms, core_atoms) sterics_custom_force.addInteractionGroup(unique_new_atoms, environment_atoms) sterics_custom_force.addInteractionGroup(core_atoms, environment_atoms) sterics_custom_force.addInteractionGroup(core_atoms, core_atoms) sterics_custom_force.addInteractionGroup(unique_new_atoms, unique_new_atoms) sterics_custom_force.addInteractionGroup(unique_old_atoms, unique_old_atoms) def _handle_hybrid_exceptions(self): """ Instead of excluding interactions that shouldn't occur, we provide exceptions for interactions that were zeroed out but should occur. """ # TODO - are these actually used anywhere? Flake8 says no old_system_nonbonded_force = self._old_system_forces['NonbondedForce'] new_system_nonbonded_force = self._new_system_forces['NonbondedForce'] # Prepare the atom classes unique_old_atoms = self._atom_classes['unique_old_atoms'] unique_new_atoms = self._atom_classes['unique_new_atoms'] # Get the list of interaction pairs for which we need to set exceptions unique_old_pairs = list(itertools.combinations(unique_old_atoms, 2)) unique_new_pairs = list(itertools.combinations(unique_new_atoms, 2)) # Add back the interactions of the old unique atoms, unless there are # exceptions for atom_pair in unique_old_pairs: # Since the pairs are indexed in the dictionary by the old system # indices, we need to convert old_index_atom_pair = (self._hybrid_to_old_map[atom_pair[0]], self._hybrid_to_old_map[atom_pair[1]]) # Now we check if the pair is in the exception dictionary if old_index_atom_pair in self._old_system_exceptions: [chargeProd, sigma, epsilon] = self._old_system_exceptions[old_index_atom_pair] # if we are interpolating 1,4 exceptions then we have to if self._interpolate_14s: self._hybrid_system_forces['standard_nonbonded_force'].addException( atom_pair[0], atom_pair[1], chargeProd*0.0, sigma, epsilon*0.0 ) else: self._hybrid_system_forces['standard_nonbonded_force'].addException( atom_pair[0], atom_pair[1], chargeProd, sigma, epsilon ) # Add exclusion to ensure exceptions are consistent self._hybrid_system_forces['core_sterics_force'].addExclusion( atom_pair[0], atom_pair[1] ) # Check if the pair is in the reverse order and use that if so elif old_index_atom_pair[::-1] in self._old_system_exceptions: [chargeProd, sigma, epsilon] = self._old_system_exceptions[old_index_atom_pair[::-1]] # If we are interpolating 1,4 exceptions then we have to if self._interpolate_14s: self._hybrid_system_forces['standard_nonbonded_force'].addException( atom_pair[0], atom_pair[1], chargeProd*0.0, sigma, epsilon*0.0 ) else: self._hybrid_system_forces['standard_nonbonded_force'].addException( atom_pair[0], atom_pair[1], chargeProd, sigma, epsilon) # Add exclusion to ensure exceptions are consistent self._hybrid_system_forces['core_sterics_force'].addExclusion( atom_pair[0], atom_pair[1]) # TODO: work out why there's a bunch of commented out code here # Excerpt: # If it's not handled by an exception in the original system, we # just add the regular parameters as an exception # TODO: this implies that the old-old nonbonded interactions (those # which are not exceptions) are always self-interacting throughout # lambda protocol... # Add back the interactions of the new unique atoms, unless there are # exceptions for atom_pair in unique_new_pairs: # Since the pairs are indexed in the dictionary by the new system # indices, we need to convert new_index_atom_pair = (self._hybrid_to_new_map[atom_pair[0]], self._hybrid_to_new_map[atom_pair[1]]) # Now we check if the pair is in the exception dictionary if new_index_atom_pair in self._new_system_exceptions: [chargeProd, sigma, epsilon] = self._new_system_exceptions[new_index_atom_pair] if self._interpolate_14s: self._hybrid_system_forces['standard_nonbonded_force'].addException( atom_pair[0], atom_pair[1], chargeProd*0.0, sigma, epsilon*0.0 ) else: self._hybrid_system_forces['standard_nonbonded_force'].addException( atom_pair[0], atom_pair[1], chargeProd, sigma, epsilon ) self._hybrid_system_forces['core_sterics_force'].addExclusion( atom_pair[0], atom_pair[1] ) # Check if the pair is present in the reverse order and use that if so elif new_index_atom_pair[::-1] in self._new_system_exceptions: [chargeProd, sigma, epsilon] = self._new_system_exceptions[new_index_atom_pair[::-1]] if self._interpolate_14s: self._hybrid_system_forces['standard_nonbonded_force'].addException( atom_pair[0], atom_pair[1], chargeProd*0.0, sigma, epsilon*0.0 ) else: self._hybrid_system_forces['standard_nonbonded_force'].addException( atom_pair[0], atom_pair[1], chargeProd, sigma, epsilon ) self._hybrid_system_forces['core_sterics_force'].addExclusion( atom_pair[0], atom_pair[1] ) # TODO: work out why there's a bunch of commented out code here # If it's not handled by an exception in the original system, we # just add the regular parameters as an exception @staticmethod def _find_exception(force, index1, index2): """ Find the exception that corresponds to the given indices in the given system Parameters ---------- force : openmm.NonbondedForce object System containing the exceptions index1 : int The index of the first atom (order is unimportant) index2 : int The index of the second atom (order is unimportant) Returns ------- exception_parameters : list List of exception parameters """ index_set = {index1, index2} # Loop through the exceptions and try to find one matching the criteria for exception_idx in range(force.getNumExceptions()): exception_parameters = force.getExceptionParameters(exception_idx) if index_set==set(exception_parameters[:2]): return exception_parameters return [] def _handle_original_exceptions(self): """ This method ensures that exceptions present in the original systems are present in the hybrid appropriately. """ # Get what we need to find the exceptions from the new and old systems: old_system_nonbonded_force = self._old_system_forces['NonbondedForce'] new_system_nonbonded_force = self._new_system_forces['NonbondedForce'] hybrid_to_old_map = self._hybrid_to_old_map hybrid_to_new_map = self._hybrid_to_new_map # First, loop through the old system's exceptions and add them to the # hybrid appropriately: for exception_pair, exception_parameters in self._old_system_exceptions.items(): [index1_old, index2_old] = exception_pair [chargeProd_old, sigma_old, epsilon_old] = exception_parameters # Get hybrid indices: index1_hybrid = self._old_to_hybrid_map[index1_old] index2_hybrid = self._old_to_hybrid_map[index2_old] index_set = {index1_hybrid, index2_hybrid} # In this case, the interaction is only covered by the regular # nonbonded force, and as such will be copied to that force # In the unique-old case, it is handled elsewhere due to internal # peculiarities regarding exceptions if index_set.issubset(self._atom_classes['environment_atoms']): self._hybrid_system_forces['standard_nonbonded_force'].addException( index1_hybrid, index2_hybrid, chargeProd_old, sigma_old, epsilon_old ) self._hybrid_system_forces['core_sterics_force'].addExclusion( index1_hybrid, index2_hybrid ) # We have already handled unique old - unique old exceptions elif len(index_set.intersection(self._atom_classes['unique_old_atoms'])) == 2: continue # Otherwise, check if one of the atoms in the set is in the # unique_old_group and the other is not: elif len(index_set.intersection(self._atom_classes['unique_old_atoms'])) == 1: if self._interpolate_14s: self._hybrid_system_forces['standard_nonbonded_force'].addException( index1_hybrid, index2_hybrid, chargeProd_old*0.0, sigma_old, epsilon_old*0.0 ) else: self._hybrid_system_forces['standard_nonbonded_force'].addException( index1_hybrid, index2_hybrid, chargeProd_old, sigma_old, epsilon_old ) self._hybrid_system_forces['core_sterics_force'].addExclusion( index1_hybrid, index2_hybrid ) # If the exception particles are neither solely old unique, solely # environment, nor contain any unique old atoms, they are either # core/environment or core/core # In this case, we need to get the parameters from the exception in # the other (new) system, and interpolate between the two else: # First get the new indices. index1_new = hybrid_to_new_map[index1_hybrid] index2_new = hybrid_to_new_map[index2_hybrid] # Get the exception parameters: new_exception_parms= self._find_exception( new_system_nonbonded_force, index1_new, index2_new) # If there's no new exception, then we should just set the # exception parameters to be the nonbonded parameters if not new_exception_parms: [charge1_new, sigma1_new, epsilon1_new] = new_system_nonbonded_force.getParticleParameters(index1_new) [charge2_new, sigma2_new, epsilon2_new] = new_system_nonbonded_force.getParticleParameters(index2_new) chargeProd_new = charge1_new * charge2_new sigma_new = 0.5 * (sigma1_new + sigma2_new) epsilon_new = unit.sqrt(epsilon1_new*epsilon2_new) else: [index1_new, index2_new, chargeProd_new, sigma_new, epsilon_new] = new_exception_parms # Interpolate between old and new exception_index = self._hybrid_system_forces['standard_nonbonded_force'].addException( index1_hybrid, index2_hybrid, chargeProd_old, sigma_old, epsilon_old ) self._hybrid_system_forces['standard_nonbonded_force'].addExceptionParameterOffset( 'lambda_electrostatics_core', exception_index, (chargeProd_new - chargeProd_old), 0, 0 ) self._hybrid_system_forces['standard_nonbonded_force'].addExceptionParameterOffset( 'lambda_sterics_core', exception_index, 0, (sigma_new - sigma_old), (epsilon_new - epsilon_old) ) self._hybrid_system_forces['core_sterics_force'].addExclusion( index1_hybrid, index2_hybrid ) # Now, loop through the new system to collect remaining interactions. # The only that remain here are uniquenew-uniquenew, uniquenew-core, # and uniquenew-environment. There might also be core-core, since not # all core-core exceptions exist in both for exception_pair, exception_parameters in self._new_system_exceptions.items(): [index1_new, index2_new] = exception_pair [chargeProd_new, sigma_new, epsilon_new] = exception_parameters # Get hybrid indices: index1_hybrid = self._new_to_hybrid_map[index1_new] index2_hybrid = self._new_to_hybrid_map[index2_new] index_set = {index1_hybrid, index2_hybrid} # If it's a subset of unique_new_atoms, then this is an # intra-unique interaction and should have its exceptions # specified in the regular nonbonded force. However, this is # handled elsewhere as above due to peculiarities with exception # handling if index_set.issubset(self._atom_classes['unique_new_atoms']): continue # Look for the final class- interactions between uniquenew-core and # uniquenew-environment. They are treated similarly: they are # simply on and constant the entire time (as a valence term) elif len(index_set.intersection(self._atom_classes['unique_new_atoms'])) > 0: if self._interpolate_14s: self._hybrid_system_forces['standard_nonbonded_force'].addException( index1_hybrid, index2_hybrid, chargeProd_new*0.0, sigma_new, epsilon_new*0.0 ) else: self._hybrid_system_forces['standard_nonbonded_force'].addException( index1_hybrid, index2_hybrid, chargeProd_new, sigma_new, epsilon_new ) self._hybrid_system_forces['core_sterics_force'].addExclusion( index1_hybrid, index2_hybrid ) # However, there may be a core exception that exists in one system # but not the other (ring closure) elif index_set.issubset(self._atom_classes['core_atoms']): # Get the old indices try: index1_old = self._new_to_old_map[index1_new] index2_old = self._new_to_old_map[index2_new] except KeyError: continue # See if it's also in the old nonbonded force. if it is, then we don't need to add it. # But if it's not, we need to interpolate if not self._find_exception(old_system_nonbonded_force, index1_old, index2_old): [charge1_old, sigma1_old, epsilon1_old] = old_system_nonbonded_force.getParticleParameters(index1_old) [charge2_old, sigma2_old, epsilon2_old] = old_system_nonbonded_force.getParticleParameters(index2_old) chargeProd_old = charge1_old*charge2_old sigma_old = 0.5 * (sigma1_old + sigma2_old) epsilon_old = unit.sqrt(epsilon1_old*epsilon2_old) exception_index = self._hybrid_system_forces['standard_nonbonded_force'].addException( index1_hybrid, index2_hybrid, chargeProd_old, sigma_old, epsilon_old) self._hybrid_system_forces['standard_nonbonded_force'].addExceptionParameterOffset( 'lambda_electrostatics_core', exception_index, (chargeProd_new - chargeProd_old), 0, 0 ) self._hybrid_system_forces['standard_nonbonded_force'].addExceptionParameterOffset( 'lambda_sterics_core', exception_index, 0, (sigma_new - sigma_old), (epsilon_new - epsilon_old) ) self._hybrid_system_forces['core_sterics_force'].addExclusion( index1_hybrid, index2_hybrid ) def _handle_old_new_exceptions(self): """ Find the exceptions associated with old-old and old-core interactions, as well as new-new and new-core interactions. These exceptions will be placed in CustomBondedForce that will interpolate electrostatics and a softcore potential. TODO ---- * Move old_new_bond_exceptions to a dictionary or similar. """ old_new_nonbonded_exceptions = "U_electrostatics + U_sterics;" if self._softcore_LJ_v2: old_new_nonbonded_exceptions += "U_sterics = select(step(r - r_LJ), 4*epsilon*x*(x-1.0), U_sterics_quad);" old_new_nonbonded_exceptions += "U_sterics_quad = Force*(((r - r_LJ)^2)/2 - (r - r_LJ)) + U_sterics_cut;" old_new_nonbonded_exceptions += "U_sterics_cut = 4*epsilon*((sigma/r_LJ)^6)*(((sigma/r_LJ)^6) - 1.0);" old_new_nonbonded_exceptions += "Force = -4*epsilon*((-12*sigma^12)/(r_LJ^13) + (6*sigma^6)/(r_LJ^7));" old_new_nonbonded_exceptions += "x = (sigma/r)^6;" old_new_nonbonded_exceptions += "r_LJ = softcore_alpha*((26/7)*(sigma^6)*lambda_sterics_deprecated)^(1/6);" old_new_nonbonded_exceptions += "lambda_sterics_deprecated = new_interaction*(1.0 - lambda_sterics_insert) + old_interaction*lambda_sterics_delete;" else: old_new_nonbonded_exceptions += "U_sterics = 4*epsilon*x*(x-1.0); x = (sigma/reff_sterics)^6;" old_new_nonbonded_exceptions += "reff_sterics = sigma*((softcore_alpha*lambda_alpha + (r/sigma)^6))^(1/6);" old_new_nonbonded_exceptions += "reff_sterics = sigma*((softcore_alpha*lambda_alpha + (r/sigma)^6))^(1/6);" # effective softcore distance for sterics old_new_nonbonded_exceptions += "lambda_alpha = new_interaction*(1-lambda_sterics_insert) + old_interaction*lambda_sterics_delete;" old_new_nonbonded_exceptions += "U_electrostatics = (lambda_electrostatics_insert * unique_new + unique_old * (1 - lambda_electrostatics_delete)) * ONE_4PI_EPS0*chargeProd/r;" old_new_nonbonded_exceptions += "ONE_4PI_EPS0 = %f;" % ONE_4PI_EPS0 old_new_nonbonded_exceptions += "epsilon = (1-lambda_sterics)*epsilonA + lambda_sterics*epsilonB;" # interpolation old_new_nonbonded_exceptions += "sigma = (1-lambda_sterics)*sigmaA + lambda_sterics*sigmaB;" old_new_nonbonded_exceptions += "lambda_sterics = new_interaction*lambda_sterics_insert + old_interaction*lambda_sterics_delete;" old_new_nonbonded_exceptions += "new_interaction = delta(1-unique_new); old_interaction = delta(1-unique_old);" nonbonded_exceptions_force = openmm.CustomBondForce( old_new_nonbonded_exceptions) name = f"{nonbonded_exceptions_force.__class__.__name__}_exceptions" nonbonded_exceptions_force.setName(name) self._hybrid_system.addForce(nonbonded_exceptions_force) # For reference, set name in force dict self._hybrid_system_forces['old_new_exceptions_force'] = nonbonded_exceptions_force if self._softcore_LJ_v2: nonbonded_exceptions_force.addGlobalParameter( "softcore_alpha", self._softcore_LJ_v2_alpha ) else: nonbonded_exceptions_force.addGlobalParameter( "softcore_alpha", self._softcore_alpha ) # electrostatics insert nonbonded_exceptions_force.addGlobalParameter( "lambda_electrostatics_insert", 0.0 ) # electrostatics delete nonbonded_exceptions_force.addGlobalParameter( "lambda_electrostatics_delete", 0.0 ) # sterics insert nonbonded_exceptions_force.addGlobalParameter( "lambda_sterics_insert", 0.0 ) # steric delete nonbonded_exceptions_force.addGlobalParameter( "lambda_sterics_delete", 0.0 ) for parameter in ['chargeProd','sigmaA', 'epsilonA', 'sigmaB', 'epsilonB', 'unique_old', 'unique_new']: nonbonded_exceptions_force.addPerBondParameter(parameter) # Prepare for exceptions loop by grabbing nonbonded forces, # hybrid_to_old/new maps old_system_nonbonded_force = self._old_system_forces['NonbondedForce'] new_system_nonbonded_force = self._new_system_forces['NonbondedForce'] hybrid_to_old_map = self._hybrid_to_old_map hybrid_to_new_map = self._hybrid_to_new_map # First, loop through the old system's exceptions and add them to the # hybrid appropriately: for exception_pair, exception_parameters in self._old_system_exceptions.items(): [index1_old, index2_old] = exception_pair [chargeProd_old, sigma_old, epsilon_old] = exception_parameters # Get hybrid indices: index1_hybrid = self._old_to_hybrid_map[index1_old] index2_hybrid = self._old_to_hybrid_map[index2_old] index_set = {index1_hybrid, index2_hybrid} # Otherwise, check if one of the atoms in the set is in the # unique_old_group and the other is not: if (len(index_set.intersection(self._atom_classes['unique_old_atoms'])) > 0 and (chargeProd_old.value_in_unit_system(unit.md_unit_system) != 0.0 or epsilon_old.value_in_unit_system(unit.md_unit_system) != 0.0)): if self._interpolate_14s: # If we are interpolating 1,4s, then we anneal this term # off; otherwise, the exception force is constant and # already handled in the standard nonbonded force nonbonded_exceptions_force.addBond( index1_hybrid, index2_hybrid, [chargeProd_old, sigma_old, epsilon_old, sigma_old, epsilon_old*0.0, 1, 0] ) # Next, loop through the new system's exceptions and add them to the # hybrid appropriately for exception_pair, exception_parameters in self._new_system_exceptions.items(): [index1_new, index2_new] = exception_pair [chargeProd_new, sigma_new, epsilon_new] = exception_parameters # Get hybrid indices: index1_hybrid = self._new_to_hybrid_map[index1_new] index2_hybrid = self._new_to_hybrid_map[index2_new] index_set = {index1_hybrid, index2_hybrid} # Look for the final class- interactions between uniquenew-core and # uniquenew-environment. They are treated # similarly: they are simply on and constant the entire time # (as a valence term) if (len(index_set.intersection(self._atom_classes['unique_new_atoms'])) > 0 and (chargeProd_new.value_in_unit_system(unit.md_unit_system) != 0.0 or epsilon_new.value_in_unit_system(unit.md_unit_system) != 0.0)): if self._interpolate_14s: # If we are interpolating 1,4s, then we anneal this term # on; otherwise, the exception force is constant and # already handled in the standard nonbonded force nonbonded_exceptions_force.addBond( index1_hybrid, index2_hybrid, [chargeProd_new, sigma_new, epsilon_new*0.0, sigma_new, epsilon_new, 0, 1] ) def _compute_hybrid_positions(self): """ The positions of the hybrid system. Dimensionality is (n_environment + n_core + n_old_unique + n_new_unique), The positions are assigned by first copying all the mapped positions from the old system in, then copying the mapped positions from the new system. This means that there is an assumption that the positions common to old and new are the same (which is the case for perses as-is). Returns ------- hybrid_positions : np.ndarray [n, 3] Positions of the hybrid system, in nm """ # Get unitless positions old_pos_without_units = np.array( self._old_positions.value_in_unit(unit.nanometer)) new_pos_without_units = np.array( self._new_positions.value_in_unit(unit.nanometer)) # Determine the number of particles in the system n_atoms_hybrid = self._hybrid_system.getNumParticles() # Initialize an array for hybrid positions hybrid_pos_array = np.zeros([n_atoms_hybrid, 3]) # Loop through the old system indices, and assign positions. for old_idx, hybrid_idx in self._old_to_hybrid_map.items(): hybrid_pos_array[hybrid_idx, :] = old_pos_without_units[old_idx, :] # Do the same for new indices. Note that this overwrites some # coordinates, but as stated above, the assumption is that these are # the same. for new_idx, hybrid_idx in self._new_to_hybrid_map.items(): hybrid_pos_array[hybrid_idx, :] = new_pos_without_units[new_idx, :] return unit.Quantity(hybrid_pos_array, unit=unit.nanometers) def _create_mdtraj_topology(self): """ Create an MDTraj trajectory of the hybrid system. Note ---- This is purely for writing out trajectories and is not expected to be parametrized. TODO ---- * A lot of this can be simplified / reworked. """ old_top = mdt.Topology.from_openmm(self._old_topology) new_top = mdt.Topology.from_openmm(self._new_topology) hybrid_topology = copy.deepcopy(old_top) added_atoms = dict() # Get the core atoms in the new index system (as opposed to the hybrid # index system). We will need this later core_atoms_new_indices = set(self._core_old_to_new_map.values()) # Now, add each unique new atom to the topology (this is the same order # as the system) for particle_idx in self._unique_new_atoms: new_particle_hybrid_idx = self._new_to_hybrid_map[particle_idx] new_system_atom = new_top.atom(particle_idx) # First, we get the residue in the new system associated with this # atom new_system_res = new_system_atom.residue # Next, we have to enumerate the other atoms in that residue to # find mapped atoms new_system_atom_set = {atom.index for atom in new_system_res.atoms} # Now, we find the subset of atoms that are mapped. These must be # in the "core" category, since they are mapped and part of a # changing residue mapped_new_atom_indices = core_atoms_new_indices.intersection( new_system_atom_set) # Now get the old indices of the above atoms so that we can find # the appropriate residue in the old system for this we can use the # new to old atom map mapped_old_atom_indices = [self._new_to_old_map[atom_idx] for atom_idx in mapped_new_atom_indices] # We can just take the first one--they all have the same residue first_mapped_old_atom_index = mapped_old_atom_indices[0] # Get the atom object corresponding to this index from the hybrid # (which is a deepcopy of the old) mapped_hybrid_system_atom = hybrid_topology.atom( first_mapped_old_atom_index) # Get the residue that is relevant to this atom mapped_residue = mapped_hybrid_system_atom.residue # Add the atom using the mapped residue added_atoms[new_particle_hybrid_idx] = hybrid_topology.add_atom( new_system_atom.name, new_system_atom.element, mapped_residue) # Now loop through the bonds in the new system, and if the bond # contains a unique new atom, then add it to the hybrid topology for (atom1, atom2) in new_top.bonds: at1_hybrid_idx = self._new_to_hybrid_map[atom1.index] at2_hybrid_idx = self._new_to_hybrid_map[atom2.index] # If at least one atom is in the unique new class, we need to add # it to the hybrid system at1_uniq = at1_hybrid_idx in self._atom_classes['unique_new_atoms'] at2_uniq = at2_hybrid_idx in self._atom_classes['unique_new_atoms'] if at1_uniq or at2_uniq: if at1_uniq: atom1_to_bond = added_atoms[at1_hybrid_idx] else: old_idx = self._hybrid_to_old_map[at1_hybrid_idx] atom1_to_bond = hybrid_topology.atom(old_idx) if at2_uniq: atom2_to_bond = added_atoms[at2_hybrid_idx] else: old_idx = self._hybrid_to_old_map[at2_hybrid_idx] atom2_to_bond = hybrid_topology.atom(old_idx) hybrid_topology.add_bond(atom1_to_bond, atom2_to_bond) return hybrid_topology def _create_hybrid_topology(self): """ Create a hybrid openmm.app.Topology from the input old and new Topologies. Note ---- * This is not intended for parameterisation purposes, but instead for system visualisation. * Unlike the MDTraj Topology object, the residues of the alchemical species are not squashed. """ hybrid_top = app.Topology() # In the first instance, create a list of necessary atoms from # both old & new Topologies atom_list = [] # iterate once over the topologies for speed old_topology_atoms = list(self._old_topology.atoms()) new_topology_atoms = list(self._new_topology.atoms()) for pidx in range(self.hybrid_system.getNumParticles()): if pidx in self._hybrid_to_old_map: idx = self._hybrid_to_old_map[pidx] atom_list.append(old_topology_atoms[idx]) else: idx = self._hybrid_to_new_map[pidx] atom_list.append(new_topology_atoms[idx]) # Now we loop over the atoms and add them in alongside chains & resids # Non ideal variables to track the previous set of residues & chains # without having to constantly search backwards prev_res = None prev_chain = None for at in atom_list: if at.residue.chain != prev_chain: hybrid_chain = hybrid_top.addChain() prev_chain = at.residue.chain if at.residue != prev_res: hybrid_residue = hybrid_top.addResidue( at.residue.name, hybrid_chain, at.residue.id ) prev_res = at.residue hybrid_atom = hybrid_top.addAtom( at.name, at.element, hybrid_residue, at.id ) # Next we deal with bonds # loop over the topology atoms once to avoid repeated calls hybrid_top_atom_list = list(hybrid_top.atoms()) # First we add in all the old topology bonds for bond in self._old_topology.bonds(): at1 = self.old_to_hybrid_atom_map[bond.atom1.index] at2 = self.old_to_hybrid_atom_map[bond.atom2.index] hybrid_top.addBond( hybrid_top_atom_list[at1], hybrid_top_atom_list[at2], bond.type, bond.order, ) # Finally we add in all the bonds from the unique atoms in the # new Topology for bond in self._new_topology.bonds(): at1 = self.new_to_hybrid_atom_map[bond.atom1.index] at2 = self.new_to_hybrid_atom_map[bond.atom2.index] if ((at1 in self._atom_classes['unique_new_atoms']) or (at2 in self._atom_classes['unique_new_atoms'])): hybrid_top.addBond( hybrid_top_atom_list[at1], hybrid_top_atom_list[at2], bond.type, bond.order, ) return hybrid_top def old_positions(self, hybrid_positions): """ From input hybrid positions, get the positions which would correspond to the old system Parameters ---------- hybrid_positions : [n, 3] np.ndarray or simtk.unit.Quantity The positions of the hybrid system Returns ------- old_positions : [m, 3] np.ndarray with unit The positions of the old system """ n_atoms_old = self._old_system.getNumParticles() # making sure hybrid positions are simtk.unit.Quantity objects if not isinstance(hybrid_positions, unit.Quantity): hybrid_positions = unit.Quantity(hybrid_positions, unit=unit.nanometer) old_positions = unit.Quantity(np.zeros([n_atoms_old, 3]), unit=unit.nanometer) for idx in range(n_atoms_old): hyb_idx = self._old_to_hybrid_map[idx] old_positions[idx, :] = hybrid_positions[hyb_idx, :] return old_positions def new_positions(self, hybrid_positions): """ From input hybrid positions, get the positions which could correspond to the new system. Parameters ---------- hybrid_positions : [n, 3] np.ndarray or simtk.unit.Quantity The positions of the hybrid system Returns ------- new_positions : [m, 3] np.ndarray with unit The positions of the new system """ n_atoms_new = self._new_system.getNumParticles() # making sure hybrid positions are simtk.unit.Quantity objects if not isinstance(hybrid_positions, unit.Quantity): hybrid_positions = unit.Quantity(hybrid_positions, unit=unit.nanometer) new_positions = unit.Quantity(np.zeros([n_atoms_new, 3]), unit=unit.nanometer) for idx in range(n_atoms_new): hyb_idx = self._new_to_hybrid_map[idx] new_positions[idx, :] = hybrid_positions[hyb_idx, :] return new_positions @property def hybrid_system(self): """ The hybrid system. Returns ------- hybrid_system : openmm.System The system representing a hybrid between old and new topologies """ return self._hybrid_system @property def new_to_hybrid_atom_map(self): """ Give a dictionary that maps new system atoms to the hybrid system. Returns ------- new_to_hybrid_atom_map : dict of {int, int} The mapping of atoms from the new system to the hybrid """ return self._new_to_hybrid_map @property def old_to_hybrid_atom_map(self): """ Give a dictionary that maps old system atoms to the hybrid system. Returns ------- old_to_hybrid_atom_map : dict of {int, int} The mapping of atoms from the old system to the hybrid """ return self._old_to_hybrid_map @property def hybrid_positions(self): """ The positions of the hybrid system. Dimensionality is (n_environment + n_core + n_old_unique + n_new_unique). The positions are assigned by first copying all the mapped positions from the old system in, then copying the mapped positions from the new system. Returns ------- hybrid_positions : [n, 3] Quantity nanometers """ return self._hybrid_positions @property def hybrid_topology(self): """ An MDTraj hybrid topology for the purpose of writing out trajectories. Note that we do not expect this to be able to be parameterized by the openmm forcefield class. Returns ------- hybrid_topology : mdtraj.Topology """ return self._hybrid_topology @property def omm_hybrid_topology(self): """ An OpenMM format of the hybrid topology. Also cannot be used to parameterize system, only to write out trajectories. Returns ------- hybrid_topology : simtk.openmm.app.Topology .. versionchanged:: OpenFE 0.11 Now returns a Topology directly constructed from the input old / new Topologies, instead of trying to roundtrip an mdtraj topology. """ return self._omm_hybrid_topology @property def has_virtual_sites(self): """ Checks the hybrid system and tells us if we have any virtual sites. Returns ------- bool ``True`` if there are virtual sites, otherwise ``False``. """ for ix in range(self._hybrid_system.getNumParticles()): if self._hybrid_system.isVirtualSite(ix): return True return False ================================================ FILE: src/openfe/protocols/openmm_rfe/_rfe_utils/topologyhelpers.py ================================================ # This code is in parts based on TopologyProposal in perses # (https://github.com/choderalab/perses) # The eventual goal is to move this to the OpenFE alchemical topology # building toolsets. # LICENSE: MIT # turn off formatting since this is mostly vendored code # fmt: off import itertools import logging import warnings from copy import deepcopy from typing import Optional, Union import mdtraj as mdt import numpy as np import numpy.typing as npt from mdtraj.core.residue_names import _SOLVENT_TYPES from openff.units import Quantity, unit from openmm import NonbondedForce, System, app from openmm import unit as omm_unit from openfe import SolventComponent logger = logging.getLogger(__name__) def _get_ion_and_water_parameters( topology: app.Topology, system: System, ion_resname: str, water_resname: str = 'HOH', ): """ Get ion, and water (oxygen and hydrogen) atoms parameters. Parameters ---------- topology : app.Topology The topology to search for the ion and water system : app.System The system associated with the input topology object. ion_resname : str The residue name of the ion to get parameters for water_resname : str The residue name of the water to get parameters for. Default 'HOH'. Returns ------- ion_charge : float The partial charge of the ion atom ion_sigma : float The NonbondedForce sigma parameter of the ion atom ion_epsilon : float The NonbondedForce epsilon parameter of the ion atom o_charge : float The partial charge of the water oxygen. h_charge : float The partial charge of the water hydrogen. Raises ------ ValueError If there are no ``ion_resname`` or ``water_resname`` named residues in the input ``topology``. Attribution ----------- Based on `perses.utils.charge_changing.get_ion_and_water_parameters`. """ def _find_atom(topology, resname, elementname): for atom in topology.atoms(): if atom.residue.name == resname: if (elementname is None or atom.element.symbol == elementname): return atom.index errmsg = ("Error encountered when attempting to explicitly handle " "charge changes using an alchemical water. No residue " f"named: {resname} found, with element {elementname}") raise ValueError(errmsg) ion_index = _find_atom(topology, ion_resname, None) oxygen_index = _find_atom(topology, water_resname, 'O') hydrogen_index = _find_atom(topology, water_resname, 'H') nbf = [i for i in system.getForces() if isinstance(i, NonbondedForce)][0] ion_charge, ion_sigma, ion_epsilon = nbf.getParticleParameters(ion_index) o_charge, _, _ = nbf.getParticleParameters(oxygen_index) h_charge, _, _ = nbf.getParticleParameters(hydrogen_index) return ion_charge, ion_sigma, ion_epsilon, o_charge, h_charge def _fix_alchemical_water_atom_mapping( system_mapping: dict[str, Union[dict[int, int], list[int]]], b_idx: int, ) -> None: """ In-place fix atom mapping to account for alchemical water. Parameters ---------- system_mapping : dict Dictionary of system mappings. b_idx : int The index of the state B particle. """ a_idx = system_mapping['new_to_old_atom_map'][b_idx] # Note, because these are already shared positions, we don't # append alchemical molecule indices in the new & old molecule # i.e. the `old_mol_indices` and `new_mol_indices` lists # remove atom from the environment atom map system_mapping['old_to_new_env_atom_map'].pop(a_idx) system_mapping['new_to_old_env_atom_map'].pop(b_idx) # add atom to the new_to_old_core atom maps system_mapping['old_to_new_core_atom_map'][a_idx] = b_idx system_mapping['new_to_old_core_atom_map'][b_idx] = a_idx def handle_alchemical_waters( water_resids: list[int], topology: app.Topology, system: System, system_mapping: dict, charge_difference: int, solvent_component: SolventComponent, ): """ Add alchemical waters from a pre-defined list. Parameters ---------- water_resids : list[int] A list of alchemical water residues. topology : app.Topology The topology to search for the ion and water system : app.System The system associated with the input topology object. system_mapping : dictionary A dictionary of system mappings between the stateA and stateB systems charge_difference : int The charge difference between state A and state B. positive_ion_resname : str The name of a positive ion to replace the water with if the absolute charge difference is positive. negative_ion_resname : str The name of a negative ion to replace the water with if the absolute charge difference is negative. water_resname : str The residue name of the water to get parameters for. Default 'HOH'. Raises ------ ValueError If the absolute charge difference is not equalent to the number of alchemical water resids. If the chosen alchemical water has virtual sites (i.e. is not a 3 site water molecule). Attribution ----------- Based on `perses.utils.charge_changing.transform_waters_into_ions`. """ if abs(charge_difference) != len(water_resids): errmsg = ("There should be as many alchemical water residues: " f"{len(water_resids)} as the absolute charge " f"difference: {abs(charge_difference)}") raise ValueError(errmsg) if charge_difference > 0: ion_resname = solvent_component.positive_ion.strip('-+').upper() elif charge_difference < 0: ion_resname = solvent_component.negative_ion.strip('-+').upper() # if there's no charge difference then just skip altogether else: return None ion_charge, ion_sigma, ion_epsilon, o_charge, h_charge = _get_ion_and_water_parameters( topology, system, ion_resname, 'HOH', # Modeller always adds HOH waters ) # get the nonbonded forces nbfrcs = [i for i in system.getForces() if isinstance(i, NonbondedForce)] if len(nbfrcs) > 1: raise ValueError("Too many NonbondedForce forces found") # for convenience just grab the first & only entry nbf = nbfrcs[0] # Loop through residues, check if they match the residue index # mutate the atom as necessary for res in topology.residues(): if res.index in water_resids: # if the number of atoms > 3, then we have virtual sites which are # not supported currently if len([at for at in res.atoms()]) > 3: errmsg = ("Non 3-site waters (i.e. waters with virtual sites) " "are not currently supported as alchemical waters") raise ValueError(errmsg) for at in res.atoms(): idx = at.index charge, sigma, epsilon = nbf.getParticleParameters(idx) _fix_alchemical_water_atom_mapping(system_mapping, idx) if charge == o_charge: nbf.setParticleParameters( idx, ion_charge, ion_sigma, ion_epsilon ) else: if charge != h_charge: errmsg = ("modifying an atom that doesn't match known " "water parameters") raise ValueError(errmsg) nbf.setParticleParameters(idx, 0.0, sigma, epsilon) def get_alchemical_waters( topology: app.Topology, positions: npt.NDArray, charge_difference: int, distance_cutoff: Quantity = 0.8 * unit.nanometer, ) -> list[int]: """ Pick a list of waters to be used for alchemical charge correction. Parameters ---------- topology : openmm.app.Topology The topology to search for an alchemical water. positions : npt.NDArray The coordinates of the atoms associated with the ``topology``. charge_difference : int The charge difference between the two end states calculated as stateA_formal_charge - stateB_formal_charge. distance_cutoff : openff.units.Quantity The minimum distance away from the solutes from which an alchemical water can be chosen. Returns ------- chosen_residues : list[int] A list of residue indices for each chosen alchemical water. Notes ----- Based off perses.utils.charge_changing.get_water_indices. """ # if the charge difference is 0 then no waters are needed # return early with an empty list if charge_difference == 0: return [] # construct a new mdt trajectory traj = mdt.Trajectory( positions[np.newaxis, ...], mdt.Topology.from_openmm(topology) ) water_atoms = traj.topology.select("water") solvent_residue_names = list(_SOLVENT_TYPES) solute_atoms = [atom.index for atom in traj.topology.atoms if atom.residue.name not in solvent_residue_names] excluded_waters = mdt.compute_neighbors( traj, distance_cutoff.to(unit.nanometer).m, solute_atoms, haystack_indices=water_atoms, periodic=True, )[0] solvent_indices = set([ atom.residue.index for atom in traj.topology.atoms if (atom.index in water_atoms) and (atom.index not in excluded_waters) ]) if len(solvent_indices) < 1: errmsg = ("There are no waters outside of a " f"{distance_cutoff.to(unit.nanometer)} nanometer distance " "of the system solutes to be used as alchemical waters") raise ValueError(errmsg) # unlike the original perses approach, we stick to the first water index # in order to make sure we somewhat reproducibily pick the same water chosen_residues = list(solvent_indices)[:abs(charge_difference)] return chosen_residues def combined_topology(topology1: app.Topology, topology2: app.Topology, exclude_resids: Optional[npt.NDArray] = None,): """ Create a new topology combining these two topologies. The box information from the *first* topology will be copied over Parameters ---------- topology1 : openmm.app.Topology Topology of the template system to graft topology2 into. topology2 : openmm.app.Topology Topology to combine (not in place) with topology1. exclude_resids : npt.NDArray Residue indices in topology 1 to exclude from the combined topology. Returns ------- new : openmm.app.Topology appended_resids : npt.NDArray Residue indices of the residues appended from topology2 in the new topology. """ if exclude_resids is None: exclude_resids = np.array([]) top = app.Topology() # create list of excluded residues from topology excluded_res = [ r for r in topology1.residues() if r.index in exclude_resids ] # get a list of all excluded atoms excluded_atoms = set(itertools.chain.from_iterable( r.atoms() for r in excluded_res) ) # add new copies of selected chains, residues, and atoms; keep mapping # of old atoms to new for adding bonds later old_to_new_atom_map = {} appended_resids = [] for chain_id, chain in enumerate( itertools.chain(topology1.chains(), topology2.chains())): # TODO: is chain ID int or str? I recall it being int in MDTraj.... # are there any issues if we just add a blank chain? new_chain = top.addChain(chain_id) for residue in chain.residues(): if residue in excluded_res: continue new_res = top.addResidue(residue.name, new_chain, residue.id) # append the new resindex if it's part of topology2 if residue in list(topology2.residues()): appended_resids.append(new_res.index) for atom in residue.atoms(): new_atom = top.addAtom(atom.name, atom.element, new_res, atom.id) old_to_new_atom_map[atom] = new_atom # figure out which bonds to keep: drop any that involve removed atoms def atoms_for_bond(bond): return {bond.atom1, bond.atom2} keep_bonds = (bond for bond in itertools.chain(topology1.bonds(), topology2.bonds()) if not (atoms_for_bond(bond) & excluded_atoms)) # add bonds to topology for bond in keep_bonds: top.addBond(old_to_new_atom_map[bond.atom1], old_to_new_atom_map[bond.atom2], bond.type, bond.order) # Copy over the box vectors top.setPeriodicBoxVectors(topology1.getPeriodicBoxVectors()) return top, np.array(appended_resids) def _get_indices(topology, resids): """ Get the atoms indices from an array of residue indices in an OpenMM Topology Parameters ---------- topology : openmm.app.Topology Topology to search from. resids : npt.NDArrayLike An array of residue indices which match the residues we want to get atom indices for. """ # create list of openmm residues top_res = [r for r in topology.residues() if r.index in resids] # get a list of all atoms in residues top_atoms = list(itertools.chain.from_iterable(r.atoms() for r in top_res)) return [at.index for at in top_atoms] def _remove_constraints(old_to_new_atom_map, old_system, old_topology, new_system, new_topology): """ Adapted from Perses' Topology Proposal. Adjusts atom mapping to account for any bonds that are constrained but change in length. Parameters ---------- old_to_new_atom_map : dict of int : int Atom mapping between the old and new systems. old_system : openmm.app.System System of the "old" alchemical state. old_topology : openmm.app.Topology Topology of the "old" alchemical state. new_system : openmm.app.System System of the "new" alchemical state. new_topology : openmm.app.Topology Topology of the "new" alchemical state. Returns ------- no_const_old_to_new_atom_map : dict of int : int Adjusted version of the input mapping but with atoms involving changes in lengths of constrained bonds removed. TODO ---- * Very slow, needs refactoring * Can we drop having topologies as inputs here? """ from collections import Counter no_const_old_to_new_atom_map = deepcopy(old_to_new_atom_map) h_elem = app.Element.getByAtomicNumber(1) old_H_atoms = {i for i, atom in enumerate(old_topology.atoms()) if atom.element == h_elem and i in old_to_new_atom_map} new_H_atoms = {i for i, atom in enumerate(new_topology.atoms()) if atom.element == h_elem and i in old_to_new_atom_map.values()} def pick_H(i, j, x, y) -> int: """Identify which atom to remove to resolve constraint violation i maps to x, j maps to y Returns either i or j (whichever is H) to remove from mapping """ if i in old_H_atoms or x in new_H_atoms: return i elif j in old_H_atoms or y in new_H_atoms: return j else: raise ValueError(f"Couldn't resolve constraint demapping for atoms" f" A: {i}-{j} B: {x}-{y}") old_constraints: dict[[int, int], float] = dict() for idx in range(old_system.getNumConstraints()): atom1, atom2, length = old_system.getConstraintParameters(idx) if atom1 in old_to_new_atom_map and atom2 in old_to_new_atom_map: old_constraints[atom1, atom2] = length new_constraints = dict() for idx in range(new_system.getNumConstraints()): atom1, atom2, length = new_system.getConstraintParameters(idx) if (atom1 in old_to_new_atom_map.values() and atom2 in old_to_new_atom_map.values()): new_constraints[atom1, atom2] = length # there are two reasons constraints would invalidate a mapping entry # 1) length of constraint changed (but both constrained) # 2) constraint removed to harmonic bond (only one constrained) to_del = [] for (i, j), l_old in old_constraints.items(): x, y = old_to_new_atom_map[i], old_to_new_atom_map[j] try: l_new = new_constraints.pop((x, y)) except KeyError: try: l_new = new_constraints.pop((y, x)) except KeyError: # type 2) constraint doesn't exist in new system to_del.append(pick_H(i, j, x, y)) continue # type 1) constraint length changed if l_old != l_new: to_del.append(pick_H(i, j, x, y)) # iterate over new_constraints (we were .popping items out) # (if any left these are type 2)) if new_constraints: new_to_old = {v: k for k, v in old_to_new_atom_map.items()} for x, y in new_constraints: i, j = new_to_old[x], new_to_old[y] to_del.append(pick_H(i, j, x, y)) # count the number of times each atom appears to_del_counts = Counter(to_del) # if a H-atom appears more than once, it means it was involved in # multiple different constraints at the end states but that the atom is in the core region # this should not happen for idx, count in to_del_counts.items(): if count > 1: # this is raised before we hit the KeyError below raise ValueError(f"Atom {idx} was involved in {count} unique constraints " f" that changed between the two end-states. This should not happen for core " f"atoms, please check your atom mapping. Please raise an issue on the openfe github with " f"the steps to reproduce this error for more help.") for idx in to_del: del no_const_old_to_new_atom_map[idx] return no_const_old_to_new_atom_map def get_system_mappings(old_to_new_atom_map, old_system, old_topology, old_resids, new_system, new_topology, new_resids, fix_constraints=True): """ From a starting alchemical map between two molecules, get the mappings between two alchemical end state systems. Optionally, also fixes the mapping to account for a) element changes, and b) changes in bond lengths for constraints. Parameters ---------- old_to_new_atom_map : dict of int : int Atom mapping between the old and new systems. old_system : openmm.app.System System of the "old" alchemical state. old_topology : openmm.app.Topology Topology of the "old" alchemical state. old_resids : npt.NDArray Residue ids of the alchemical residues in the "old" topology. new_system : openmm.app.System System of the "new" alchemical state. new_topology : openmm.app.Topology Topology of the "new" alchemical state. new_resids : npt.NDArray Residue ids of the alchemical residues in the "new" topology. fix_constraints : bool, default True Whether to fix the atom mapping by removing any atoms which are involved in constrained bonds that change length across the alchemical change. Returns ------- mappings : dictionary A dictionary with all the necessary mappings for the two systems. These include: 1. old_to_new_atom_map This includes all the atoms mapped between the two systems (including non-core atoms, i.e. environment). 2. new_to_old_atom_map The inverted dictionary of old_to_new_atom_map 3. old_to_new_core_atom_map The atom mapping of the "core" atoms (i.e. atoms in alchemical residues) between the old and new systems 4. new_to_old_core_atom_map The inverted dictionary of old_to_new_core_atom_map 5. old_to_new_env_atom_map The atom mapping of solely the "environment" atoms between the old and new systems. 6. new_to_old_env_atom_map The inverted dictionaryu of old_to_new_env_atom_map. 7. old_mol_indices Indices of the alchemical molecule in the old system. Note: This will not contain the indices of any alchemical waters! 8. new_mol_indices Indices of the alchemical molecule in the new system. Note: This will not contain the indices of any alchemical waters! """ # Get the indices of the atoms in the alchemical residue of interest for # both the old and new systems old_at_indices = _get_indices(old_topology, old_resids) new_at_indices = _get_indices(new_topology, new_resids) # We assume that the atom indices are linear in the residue so we shift # by the index of the first atom in each residue adjusted_old_to_new_map = {} for (key, value) in old_to_new_atom_map.items(): shift_old = old_at_indices[0] + key shift_new = new_at_indices[0] + value adjusted_old_to_new_map[shift_old] = shift_new # TODO: the original intent here was to apply over the full mapping of all # the atoms in the two systems. For now we are only doing the alchemical # residues. We might want to change this as necessary in the future. if not fix_constraints: wmsg = ("Not attempting to fix atom mapping to account for " "constraints. Please note that core atoms which have " "constrained bonds and changing bond lengths are not allowed.") warnings.warn(wmsg) else: adjusted_old_to_new_map = _remove_constraints( adjusted_old_to_new_map, old_system, old_topology, new_system, new_topology) # We return a dictionary with all the necessary mappings (as they are # needed downstream). These include: # 1. old_to_new_atom_map # This includes all the atoms mapped between the two systems # (including non-core atoms, i.e. environment). # 2. new_to_old_atom_map # The inverted dictionary of old_to_new_atom_map # 3. old_to_new_core_atom_map # The atom mapping of the "core" atoms (i.e. atoms in alchemical # residues) between the old and new systems # 4. new_to_old_core_atom_map # The inverted dictionary of old_to_new_core_atom_map # 5. old_to_new_env_atom_map # The atom mapping of solely the "environment" atoms between the old # and new systems. # 6. new_to_old_env_atom_map # The inverted dictionaryu of old_to_new_env_atom_map. # Because of how we append the topologies, we can assume that the last # residue in the "new" topology is the ligand, just to be sure we check # this here - temp fix for now for at in new_topology.atoms(): if at.index > new_at_indices[-1]: raise ValueError("residues are appended after the new ligand") # We assume that all the atoms up until the first ligand atom match # except from the indices of the ligand in the old topology. new_to_old_all_map = {} old_mol_offset = len(old_at_indices) for i in range(new_at_indices[0]): if i >= old_at_indices[0]: old_idx = i + old_mol_offset else: old_idx = i new_to_old_all_map[i] = old_idx # At this point we only have environment atoms so make a copy new_to_old_env_map = deepcopy(new_to_old_all_map) # Next we append the contents of the "core" map we already have for key, value in adjusted_old_to_new_map.items(): # reverse order because we are going new->old instead of old->new new_to_old_all_map[value] = key # Now let's create our output dictionary mappings = {} mappings['new_to_old_atom_map'] = new_to_old_all_map mappings['old_to_new_atom_map'] = {v: k for k, v in new_to_old_all_map.items()} mappings['new_to_old_core_atom_map'] = {v: k for k, v in adjusted_old_to_new_map.items()} mappings['old_to_new_core_atom_map'] = adjusted_old_to_new_map mappings['new_to_old_env_atom_map'] = new_to_old_env_map mappings['old_to_new_env_atom_map'] = {v: k for k, v in new_to_old_env_map.items()} mappings['old_mol_indices'] = old_at_indices mappings['new_mol_indices'] = new_at_indices return mappings def set_and_check_new_positions(mapping, old_topology, new_topology, old_positions, insert_positions, tolerance=1.0): """ Utility to create new positions given a mapping, the old positions and the positions of the molecule being inserted, defined by `insert_positions. This will also softly check that the RMS distance between the core atoms of the old and new atoms do not differ by more than the amount specified by `tolerance`. Parameters ---------- mapping : dict of int : int Dictionary of atom mappings between the old and new systems. old_topology : openmm.app.Topology Topology of the "old" alchemical state. new_topology : openmm.app.Topology Topology of the "new" alchemical state. old_positions : simtk.unit.Quantity Position of the "old" alchemical state. insert_positions : simtk.unit.Quantity Positions of the alchemically changing molecule in the "new" alchemical state. tolerance : float Warning threshold for deviations along any dimension (x,y,z) in mapped atoms between the "old" and "new" positions. Default 1.0. """ # Get the positions in Angstrom as raw numpy arrays old_pos_array = old_positions.value_in_unit(omm_unit.angstrom) add_pos_array = insert_positions.value_in_unit(omm_unit.angstrom) # Create empty ndarray of size atoms to hold the positions new_pos_array = np.zeros((new_topology.getNumAtoms(), 3)) # get your mappings new_idxs = list(mapping['old_to_new_atom_map'].values()) old_idxs = list(mapping['old_to_new_atom_map'].keys()) new_mol_idxs = mapping['new_mol_indices'] # copy over the old positions for mapped atoms new_pos_array[new_idxs, :] = old_pos_array[old_idxs, :] # copy over the new alchemical molecule positions new_pos_array[new_mol_idxs, :] = add_pos_array # loop through all mapped atoms and make sure we don't deviate by more than # tolerance - not super necessary, but it's a nice sanity check for key, val in mapping['old_to_new_atom_map'].items(): if np.any( np.abs(new_pos_array[val] - old_pos_array[key]) > tolerance): wmsg = f"mapping {key} : {val} deviates by more than {tolerance}" warnings.warn(wmsg) logging.warning(wmsg) return new_pos_array * omm_unit.angstrom ================================================ FILE: src/openfe/protocols/openmm_rfe/equil_rfe_methods.py ================================================ # This code is part of OpenFE and is licensed under the MIT license. # For details, see https://github.com/OpenFreeEnergy/openfe """Equilibrium Relative Free Energy Protocol using OpenMM and OpenMMTools in a Perses-like manner. This module implements the necessary tooling to calculate the relative free energy of a ligand transformation using OpenMM tools and one of the following methods: - Hamiltonian Replica Exchange - Self-adjusted mixture sampling - Independent window sampling Acknowledgements ---------------- This Protocol is based on, and leverages components originating from the Perses toolkit (https://github.com/choderalab/perses). """ from .equil_rfe_settings import RelativeHybridTopologyProtocolSettings from .hybridtop_protocol_results import RelativeHybridTopologyProtocolResult from .hybridtop_protocols import RelativeHybridTopologyProtocol from .hybridtop_units import ( HybridTopologyMultiStateAnalysisUnit, HybridTopologyMultiStateSimulationUnit, HybridTopologySetupUnit, ) ================================================ FILE: src/openfe/protocols/openmm_rfe/equil_rfe_settings.py ================================================ # This code is part of OpenFE and is licensed under the MIT license. # For details, see https://github.com/OpenFreeEnergy/openfe """Equilibrium Relative Free Energy Protocol input settings. This module implements the necessary settings necessary to run relative free energies using :class:`openfe.protocols.openmm_rfe.equil_rfe_methods.py` """ from __future__ import annotations from typing import Literal from gufe.settings import ( OpenMMSystemGeneratorFFSettings, Settings, SettingsBaseModel, ThermoSettings, ) from gufe.settings.typing import NanometerQuantity from openff.units import unit from pydantic import ConfigDict, field_validator from openfe.protocols.openmm_utils.omm_settings import ( IntegratorSettings, MultiStateOutputSettings, MultiStateSimulationSettings, OpenFFPartialChargeSettings, OpenMMEngineSettings, OpenMMSolvationSettings, ) class LambdaSettings(SettingsBaseModel): model_config = ConfigDict(extra="ignore", arbitrary_types_allowed=True) """Lambda schedule settings. Settings controlling the lambda schedule, these include the switching function type, and the number of windows. """ lambda_functions: str = "default" """ Key of which switching functions to use for alchemical mutation. Default 'default'. """ lambda_windows: int = 11 """Number of lambda windows to calculate. Default 11.""" class AlchemicalSettings(SettingsBaseModel): model_config = ConfigDict(extra="ignore", arbitrary_types_allowed=True) """Settings for the alchemical protocol This describes the creation of the hybrid system. """ endstate_dispersion_correction: bool = False """ Whether to have extra unsampled endstate windows for long range correction. Default False. """ # alchemical settings use_dispersion_correction: bool = False """ Whether to use dispersion correction in the hybrid topology state. Default False. """ softcore_LJ: Literal["gapsys", "beutler"] """ Whether to use the LJ softcore function as defined by Gapsys et al. JCTC 2012, or the one by Beutler et al. Chem. Phys. Lett. 1994. Default 'gapsys'. """ softcore_alpha: float = 0.85 """Softcore alpha parameter. Default 0.85""" turn_off_core_unique_exceptions: bool = True """ Whether to turn off interactions for new exceptions (not just 1,4s) at lambda 0 and old exceptions at lambda 1 between unique atoms and core atoms. If False they are present in the nonbonded force. Default True. """ explicit_charge_correction: bool = False """ Whether to explicitly account for a charge difference during the alchemical transformation by transforming a water to a counterion of the opposite charge of the formal charge difference. Please note that this feature is currently in beta and poorly tested. Absolute charge changes greater than 1 are currently not supported. Default False. """ explicit_charge_correction_cutoff: NanometerQuantity = 0.8 * unit.nanometer """ The minimum distance from the system solutes from which an alchemical water can be chosen. Default 0.8 * unit.nanometer. """ class RelativeHybridTopologyProtocolSettings(Settings): protocol_repeats: int """ The number of completely independent repeats of the entire sampling process. The mean of the repeats defines the final estimate of FE difference, while the variance between repeats is used as the uncertainty. """ @field_validator("protocol_repeats") def must_be_positive(cls, v): if v <= 0: errmsg = f"protocol_repeats must be a positive value, got {v}." raise ValueError(errmsg) return v # Inherited things forcefield_settings: OpenMMSystemGeneratorFFSettings """Parameters to set up the force field with OpenMM Force Fields.""" thermo_settings: ThermoSettings """Settings for thermodynamic parameters.""" # Things for creating the systems solvation_settings: OpenMMSolvationSettings """Settings for solvating the system.""" partial_charge_settings: OpenFFPartialChargeSettings """Settings for assigning partial charges to small molecules.""" # Alchemical settings lambda_settings: LambdaSettings """ Lambda protocol settings including lambda windows and lambda functions. """ alchemical_settings: AlchemicalSettings """ Alchemical protocol settings including soft core scaling. """ simulation_settings: MultiStateSimulationSettings """ Settings for alchemical sampler. """ # MD Engine things engine_settings: OpenMMEngineSettings """Settings specific to the OpenMM engine such as the compute platform.""" # Sampling State defining things integrator_settings: IntegratorSettings """Settings for the integrator such as timestep and barostat settings.""" output_settings: MultiStateOutputSettings """ Simulation output control settings. """ ================================================ FILE: src/openfe/protocols/openmm_rfe/hybridtop_protocol_results.py ================================================ # This code is part of OpenFE and is licensed under the MIT license. # For details, see https://github.com/OpenFreeEnergy/openfe """ ProtocolUnitResults for Hybrid Topology methods using OpenMM and OpenMMTools in a Perses-like manner. """ import logging import pathlib import warnings from typing import Optional, Union import gufe import numpy as np import numpy.typing as npt from openff.units import Quantity from openmmtools import multistate logger = logging.getLogger(__name__) class RelativeHybridTopologyProtocolResult(gufe.ProtocolResult): """ Protocol results with the output of a RelativeHybridTopologyProtocol. """ def __init__(self, **data): super().__init__(**data) # data is mapping of str(repeat_id): list[protocolunitresults] # TODO: Detect when we have extensions and stitch these together? if any(len(pur_list) > 2 for pur_list in self.data.values()): raise NotImplementedError("Can't stitch together results yet") @staticmethod def compute_mean_estimate(dGs: list[Quantity]) -> Quantity: u = dGs[0].u # convert all values to units of the first value, then take average of magnitude # this would avoid an edge case where each value was in different units vals = np.asarray([dG.to(u).m for dG in dGs]) return np.average(vals) * u def get_estimate(self) -> Quantity: """Average free energy difference of this transformation Returns ------- dG : openff.units.Quantity The free energy difference between the first and last states. This is a Quantity defined with units. """ # TODO: Check this holds up completely for SAMS. dGs = [pus[0].outputs["unit_estimate"] for pus in self.data.values()] return self.compute_mean_estimate(dGs) @staticmethod def compute_uncertainty(dGs: list[Quantity]) -> Quantity: u = dGs[0].u # convert all values to units of the first value, then take average of magnitude # this would avoid a screwy case where each value was in different units vals = np.asarray([dG.to(u).m for dG in dGs]) return np.std(vals) * u def get_uncertainty(self) -> Quantity: """The uncertainty/error in the dG value: The std of the estimates of each independent repeat """ dGs = [pus[0].outputs["unit_estimate"] for pus in self.data.values()] return self.compute_uncertainty(dGs) def get_individual_estimates(self) -> list[tuple[Quantity, Quantity]]: """Return a list of tuples containing the individual free energy estimates and associated MBAR errors for each repeat. Returns ------- dGs : list[tuple[openff.units.Quantity]] n_replicate simulation list of tuples containing the free energy estimates (first entry) and associated MBAR estimate errors (second entry). """ dGs = [ (pus[0].outputs["unit_estimate"], pus[0].outputs["unit_estimate_error"]) for pus in self.data.values() ] return dGs def get_forward_and_reverse_energy_analysis( self, ) -> list[Optional[dict[str, Union[npt.NDArray, Quantity]]]]: """ Get a list of forward and reverse analysis of the free energies for each repeat using uncorrelated production samples. The returned dicts have keys: 'fractions' - the fraction of data used for this estimate 'forward_DGs', 'reverse_DGs' - for each fraction of data, the estimate 'forward_dDGs', 'reverse_dDGs' - for each estimate, the uncertainty The 'fractions' values are a numpy array, while the other arrays are Quantity arrays, with units attached. If the list entry is ``None`` instead of a dictionary, this indicates that the analysis could not be carried out for that repeat. This is most likely caused by MBAR convergence issues when attempting to calculate free energies from too few samples. Returns ------- forward_reverse : list[Optional[dict[str, Union[npt.NDArray, openff.units.Quantity]]]] Raises ------ UserWarning If any of the forward and reverse entries are ``None``. """ forward_reverse = [ pus[0].outputs["forward_and_reverse_energies"] for pus in self.data.values() ] if None in forward_reverse: wmsg = ( "One or more ``None`` entries were found in the list of " "forward and reverse analyses. This is likely caused by " "an MBAR convergence failure caused by too few independent " "samples when calculating the free energies of the 10% " "timeseries slice." ) warnings.warn(wmsg) return forward_reverse def get_overlap_matrices(self) -> list[dict[str, npt.NDArray]]: """ Return a list of dictionary containing the MBAR overlap estimates calculated for each repeat. Returns ------- overlap_stats : list[dict[str, npt.NDArray]] A list of dictionaries containing the following keys: * ``scalar``: One minus the largest nontrivial eigenvalue * ``eigenvalues``: The sorted (descending) eigenvalues of the overlap matrix * ``matrix``: Estimated overlap matrix of observing a sample from state i in state j """ # Loop through and get the repeats and get the matrices overlap_stats = [pus[0].outputs["unit_mbar_overlap"] for pus in self.data.values()] return overlap_stats def get_replica_transition_statistics(self) -> list[dict[str, npt.NDArray]]: """The replica lambda state transition statistics for each repeat. Note ---- This is currently only available in cases where a replica exchange simulation was run. Returns ------- repex_stats : list[dict[str, npt.NDArray]] A list of dictionaries containing the following: * ``eigenvalues``: The sorted (descending) eigenvalues of the lambda state transition matrix * ``matrix``: The transition matrix estimate of a replica switching from state i to state j. """ try: repex_stats = [ pus[0].outputs["replica_exchange_statistics"] for pus in self.data.values() ] except KeyError: errmsg = "Replica exchange statistics were not found, did you run a repex calculation?" raise ValueError(errmsg) return repex_stats def get_replica_states(self) -> list[npt.NDArray]: """ Returns the timeseries of replica states for each repeat. Returns ------- replica_states : List[npt.NDArray] List of replica states for each repeat """ def is_file(filename: str): p = pathlib.Path(filename) if not p.exists(): errmsg = f"File could not be found {p}" raise ValueError(errmsg) return p replica_states = [] for pus in self.data.values(): nc = is_file(pus[0].outputs["trajectory"]) dir_path = nc.parents[0] chk = is_file(pus[0].outputs["checkpoint"]).name reporter = multistate.MultiStateReporter( storage=nc, checkpoint_storage=chk, open_mode="r" ) replica_states.append(np.asarray(reporter.read_replica_thermodynamic_states())) reporter.close() return replica_states def equilibration_iterations(self) -> list[float]: """ Returns the number of equilibration iterations for each repeat of the calculation. Returns ------- equilibration_lengths : list[float] """ equilibration_lengths = [ pus[0].outputs["equilibration_iterations"] for pus in self.data.values() ] return equilibration_lengths def production_iterations(self) -> list[float]: """ Returns the number of uncorrelated production samples for each repeat of the calculation. Returns ------- production_lengths : list[float] """ production_lengths = [pus[0].outputs["production_iterations"] for pus in self.data.values()] return production_lengths ================================================ FILE: src/openfe/protocols/openmm_rfe/hybridtop_protocols.py ================================================ # This code is part of OpenFE and is licensed under the MIT license. # For details, see https://github.com/OpenFreeEnergy/openfe """ Hybrid Topology Protocols using OpenMM and OpenMMTools in a Perses-like manner. Acknowledgements ---------------- These Protocols are based on, and leverages components originating from the Perses toolkit (https://github.com/choderalab/perses). """ from __future__ import annotations import logging import uuid import warnings from collections import defaultdict from typing import Any, Iterable, Optional, Union import gufe import numpy as np from gufe import ( BaseSolventComponent, ChemicalSystem, Component, ComponentMapping, LigandAtomMapping, ProteinComponent, ProteinMembraneComponent, SmallMoleculeComponent, SolventComponent, settings, ) from openff.units import unit as offunit from openfe.due import Doi, due from ..openmm_utils import ( settings_validation, system_validation, ) from .equil_rfe_settings import ( AlchemicalSettings, IntegratorSettings, LambdaSettings, MultiStateOutputSettings, MultiStateSimulationSettings, OpenFFPartialChargeSettings, OpenMMEngineSettings, OpenMMSolvationSettings, RelativeHybridTopologyProtocolSettings, ) from .hybridtop_protocol_results import RelativeHybridTopologyProtocolResult from .hybridtop_units import ( HybridTopologyMultiStateAnalysisUnit, HybridTopologyMultiStateSimulationUnit, HybridTopologySetupUnit, ) logger = logging.getLogger(__name__) due.cite( Doi("10.5281/zenodo.1297683"), description="Perses", path="openfe.protocols.openmm_rfe.hybridtop_protocols", cite_module=True, ) due.cite( Doi("10.5281/zenodo.596622"), description="OpenMMTools", path="openfe.protocols.openmm_rfe.hybridtop_protocols", cite_module=True, ) due.cite( Doi("10.1371/journal.pcbi.1005659"), description="OpenMM", path="openfe.protocols.openmm_rfe.hybridtop_protocols", cite_module=True, ) class RelativeHybridTopologyProtocol(gufe.Protocol): """ Relative Free Energy calculations using a Hybrid Topology scheme using OpenMM and OpenMMTools. Based on `Perses `_ See Also -------- :mod:`openfe.protocols` :class:`openfe.protocols.openmm_rfe.RelativeHybridTopologySettings` :class:`openfe.protocols.openmm_rfe.RelativeHybridTopologyResult` :class:`openfe.protocols.openmm_rfe.RelativeHybridTopologyProtocolUnit` """ result_cls = RelativeHybridTopologyProtocolResult _settings_cls = RelativeHybridTopologyProtocolSettings _settings: RelativeHybridTopologyProtocolSettings @classmethod def _default_settings(cls): """A dictionary of initial settings for this creating this Protocol These settings are intended as a suitable starting point for creating an instance of this protocol. It is recommended, however that care is taken to inspect and customize these before performing a Protocol. Returns ------- Settings a set of default settings """ return RelativeHybridTopologyProtocolSettings( protocol_repeats=3, forcefield_settings=settings.OpenMMSystemGeneratorFFSettings(), thermo_settings=settings.ThermoSettings( temperature=298.15 * offunit.kelvin, pressure=1 * offunit.bar, ), partial_charge_settings=OpenFFPartialChargeSettings(), solvation_settings=OpenMMSolvationSettings(), alchemical_settings=AlchemicalSettings(softcore_LJ="gapsys"), lambda_settings=LambdaSettings(), simulation_settings=MultiStateSimulationSettings( equilibration_length=1.0 * offunit.nanosecond, production_length=5.0 * offunit.nanosecond, ), engine_settings=OpenMMEngineSettings(), integrator_settings=IntegratorSettings(), output_settings=MultiStateOutputSettings(), ) @classmethod def _adaptive_settings( cls, stateA: ChemicalSystem, stateB: ChemicalSystem, mapping: gufe.LigandAtomMapping | list[gufe.LigandAtomMapping], initial_settings: None | RelativeHybridTopologyProtocolSettings = None, ) -> RelativeHybridTopologyProtocolSettings: """ Get the recommended OpenFE settings for this protocol based on the input states involved in the transformation. These are intended as a suitable starting point for creating an instance of this protocol, which can be further customized before performing a Protocol. Parameters ---------- stateA : ChemicalSystem The initial state of the transformation. stateB : ChemicalSystem The final state of the transformation. mapping : LigandAtomMapping | list[LigandAtomMapping] The mapping(s) between transforming components in stateA and stateB. initial_settings : None | RelativeHybridTopologyProtocolSettings, optional Initial settings to base the adaptive settings on. If None, default settings are used. Returns ------- RelativeHybridTopologyProtocolSettings The recommended settings for this protocol based on the input states. Notes ----- - If the transformation involves a change in net charge, the settings are adapted to use a more expensive protocol with 22 lambda windows and 20 ns production length per window. - If both states contain a ProteinComponent, the solvation padding is set to 1 nm. - If initial_settings is provided, the adaptive settings are based on a copy of these settings. """ # use initial settings or default settings # this is needed for the CLI so we don't override user settings if initial_settings is not None: protocol_settings = initial_settings.model_copy(deep=True) else: protocol_settings = cls.default_settings() if isinstance(mapping, list): mapping = mapping[0] if mapping.get_alchemical_charge_difference() != 0: # apply the recommended charge change settings taken from the industry benchmarking as fast settings not validated # info = ( "Charge changing transformation between ligands " f"{mapping.componentA.name} and {mapping.componentB.name}. " "A more expensive protocol with 22 lambda windows, sampled " "for 20 ns each, will be used here." ) logger.info(info) protocol_settings.alchemical_settings.explicit_charge_correction = True protocol_settings.simulation_settings.production_length = 20 * offunit.nanosecond protocol_settings.simulation_settings.n_replicas = 22 protocol_settings.lambda_settings.lambda_windows = 22 # adapt the solvation padding based on the system components if stateA.contains(ProteinComponent): protocol_settings.solvation_settings.solvent_padding = 1 * offunit.nanometer # adapt the barostat based on the system components if stateA.contains(ProteinMembraneComponent): protocol_settings.integrator_settings.barostat = "MonteCarloMembraneBarostat" return protocol_settings @staticmethod def _validate_endstates( stateA: ChemicalSystem, stateB: ChemicalSystem, ) -> None: """ Validates the end states for the RFE protocol. Parameters ---------- stateA : ChemicalSystem The chemical system of end state A. stateB : ChemicalSystem The chemical system of end state B. Raises ------ ValueError * If either state contains more than one unique Component. * If unique components are not SmallMoleculeComponents. """ # Get the difference in Components between each state diff = stateA.component_diff(stateB) for i, entry in enumerate(diff): state_label = "A" if i == 0 else "B" # Check that there is only one unique Component in each state if len(entry) != 1: errmsg = ( "Only one alchemical component is allowed per end state. " f"Found {len(entry)} in state {state_label}." ) raise ValueError(errmsg) # Check that the unique Component is a SmallMoleculeComponent if not isinstance(entry[0], SmallMoleculeComponent): errmsg = ( f"Alchemical component in state {state_label} is of type " f"{type(entry[0])}, but only SmallMoleculeComponents " "transformations are currently supported." ) raise ValueError(errmsg) @staticmethod def _validate_mapping( mapping: Optional[Union[ComponentMapping, list[ComponentMapping]]], alchemical_components: dict[str, list[Component]], ) -> None: """ Validates that the provided mapping(s) are suitable for the RFE protocol. Parameters ---------- mapping : Optional[Union[ComponentMapping, list[ComponentMapping]]] all mappings between transforming components. alchemical_components : dict[str, list[Component]] Dictionary containing the alchemical components for states A and B. Raises ------ ValueError * If there are more than one mapping or mapping is None * If the mapping components are not in the alchemical components. UserWarning * Mappings which involve element changes in core atoms """ # if a single mapping is provided, convert to list if isinstance(mapping, ComponentMapping): mapping = [mapping] # For now we only support a single mapping if mapping is None or len(mapping) > 1: errmsg = "A single LigandAtomMapping is expected for this Protocol" raise ValueError(errmsg) # check that the mapping components are in the alchemical components for m in mapping: for state in ["A", "B"]: comp = getattr(m, f"component{state}") if comp not in alchemical_components[f"state{state}"]: raise ValueError( f"Mapping component{state} {comp} not " f"in alchemical components of state{state}" ) # TODO: remove - this is now the default behaviour? # Check for element changes in mappings for m in mapping: molA = m.componentA.to_rdkit() molB = m.componentB.to_rdkit() for i, j in m.componentA_to_componentB.items(): atomA = molA.GetAtomWithIdx(i) atomB = molB.GetAtomWithIdx(j) if atomA.GetAtomicNum() != atomB.GetAtomicNum(): wmsg = ( f"Element change in mapping between atoms " f"Ligand A: {i} (element {atomA.GetAtomicNum()}) and " f"Ligand B: {j} (element {atomB.GetAtomicNum()})\n" "No mass scaling is attempted in the hybrid topology, " "the average mass of the two atoms will be used in the " "simulation" ) logger.warning(wmsg) warnings.warn(wmsg) @staticmethod def _validate_smcs( stateA: ChemicalSystem, stateB: ChemicalSystem, ) -> None: """ Validates the SmallMoleculeComponents. Parameters ---------- stateA : ChemicalSystem The chemical system of end state A. stateB : ChemicalSystem The chemical system of end state B. Raises ------ ValueError * If there are isomorphic SmallMoleculeComponents with different charges within a given ChemicalSystem. """ smcs_A = stateA.get_components_of_type(SmallMoleculeComponent) smcs_B = stateB.get_components_of_type(SmallMoleculeComponent) smcs_all = list(set(smcs_A).union(set(smcs_B))) def _equal_charges(moli, molj): # Base case, both molecules don't have charges if (moli.partial_charges is None) & (molj.partial_charges is None): return True # If either is None but not the other if (moli.partial_charges is None) ^ (molj.partial_charges is None): return False # Check if the charges are close to each other return np.allclose(moli.partial_charges, molj.partial_charges) clashes = [] for smcs in [smcs_A, smcs_B]: offmols = [m.to_openff() for m in smcs] for i, moli in enumerate(offmols): for molj in offmols: if moli.is_isomorphic_with(molj): if not _equal_charges(moli, molj): clashes.append(smcs[i]) if len(clashes) > 0: errmsg = ( "Found SmallMoleculeComponents that are isomorphic " "but with different charges, this is not currently allowed. " f"Affected components: {clashes}" ) raise ValueError(errmsg) @staticmethod def _validate_charge_difference( mapping: LigandAtomMapping, nonbonded_method: str, explicit_charge_correction: bool, solvent_component: SolventComponent | None, ): """ Validates the net charge difference between the two states. Parameters ---------- mapping : dict[str, ComponentMapping] Dictionary of mappings between transforming components. nonbonded_method : str The OpenMM nonbonded method used for the simulation. explicit_charge_correction : bool Whether or not to use an explicit charge correction. solvent_component : openfe.SolventComponent | None The SolventComponent of the simulation. Raises ------ ValueError * If an explicit charge correction is attempted and the nonbonded method is not PME. * If the absolute charge difference is greater than one and an explicit charge correction is attempted. * If an explicit charge correction is attempted and there is no solvent present. UserWarning * If there is any charge difference. """ difference = mapping.get_alchemical_charge_difference() if abs(difference) == 0: return if not explicit_charge_correction: wmsg = ( f"A charge difference of {difference} is observed " "between the end states. No charge correction has " "been requested, please account for this in your " "final results." ) logger.warning(wmsg) warnings.warn(wmsg) return if solvent_component is None: errmsg = "Cannot use explicit charge correction without solvent" raise ValueError(errmsg) # We implicitly check earlier that we have to have pme for a solvated # system, so we only need to check the nonbonded method here if nonbonded_method.lower() != "pme": errmsg = "Explicit charge correction when not using PME is not currently supported." raise ValueError(errmsg) if abs(difference) > 1: errmsg = ( f"A charge difference of {difference} is observed " "between the end states and an explicit charge " "correction has been requested. Unfortunately " "only absolute differences of 1 are supported." ) raise ValueError(errmsg) ion = {-1: solvent_component.positive_ion, 1: solvent_component.negative_ion}[difference] wmsg = ( f"A charge difference of {difference} is observed " "between the end states. This will be addressed by " f"transforming a water into a {ion} ion" ) logger.info(wmsg) @staticmethod def _validate_simulation_settings( simulation_settings: MultiStateSimulationSettings, integrator_settings: IntegratorSettings, output_settings: MultiStateOutputSettings, ): """ Validate various simulation settings, including but not limited to timestep conversions, and output file write frequencies. Parameters ---------- simulation_settings : MultiStateSimulationSettings The sampler simulation settings. integrator_settings : IntegratorSettings Settings defining the behaviour of the integrator. output_settings : MultiStateOutputSettings Settings defining the simulation file writing behaviour. Raises ------ ValueError * If the """ steps_per_iteration = settings_validation.convert_steps_per_iteration( simulation_settings=simulation_settings, integrator_settings=integrator_settings, ) _ = settings_validation.get_simsteps( sim_length=simulation_settings.equilibration_length, timestep=integrator_settings.timestep, mc_steps=steps_per_iteration, ) _ = settings_validation.get_simsteps( sim_length=simulation_settings.production_length, timestep=integrator_settings.timestep, mc_steps=steps_per_iteration, ) _ = settings_validation.convert_checkpoint_interval_to_iterations( checkpoint_interval=output_settings.checkpoint_interval, time_per_iteration=simulation_settings.time_per_iteration, ) if output_settings.positions_write_frequency is not None: _ = settings_validation.divmod_time_and_check( numerator=output_settings.positions_write_frequency, denominator=simulation_settings.time_per_iteration, numerator_name="output settings' positions_write_frequency", denominator_name="sampler settings' time_per_iteration", ) if output_settings.velocities_write_frequency is not None: _ = settings_validation.divmod_time_and_check( numerator=output_settings.velocities_write_frequency, denominator=simulation_settings.time_per_iteration, numerator_name="output settings' velocities_write_frequency", denominator_name="sampler settings' time_per_iteration", ) _, _ = settings_validation.convert_real_time_analysis_iterations( simulation_settings=simulation_settings, ) def _validate( self, stateA: ChemicalSystem, stateB: ChemicalSystem, mapping: gufe.ComponentMapping | list[gufe.ComponentMapping] | None, extends: gufe.ProtocolDAGResult | None = None, ) -> None: # Check we're not trying to extend if extends: # This technically should be NotImplementedError # but gufe.Protocol.validate calls `_validate` wrapped around an # except for NotImplementedError, so we can't raise it here raise ValueError("Can't extend simulations yet") # Validate the end states system_validation.validate_chemical_system(stateA) system_validation.validate_chemical_system(stateB) self._validate_endstates(stateA, stateB) # Validate the mapping alchem_comps = system_validation.get_alchemical_components(stateA, stateB) self._validate_mapping(mapping, alchem_comps) # Validate the small molecule components self._validate_smcs(stateA, stateB) # Validate solvent component nonbond = self.settings.forcefield_settings.nonbonded_method system_validation.validate_solvent(stateA, nonbond) # Validate the BaseSolventComponents base_solvent = stateA.get_components_of_type(BaseSolventComponent) if len(base_solvent) > 1: errmsg = "Multiple BaseSolventComponents found, only one is supported." raise ValueError(errmsg) # Validate solvation settings settings_validation.validate_openmm_solvation_settings(self.settings.solvation_settings) # Validate protein component system_validation.validate_protein(stateA) # Validate the barostat used in combination with the protein component system_validation.validate_barostat(stateA, self.settings.integrator_settings.barostat) # Validate charge difference # Note: validation depends on the mapping & solvent component checks if stateA.contains(SolventComponent): solv_comp = stateA.get_components_of_type(SolventComponent)[0] else: solv_comp = None self._validate_charge_difference( mapping=mapping[0] if isinstance(mapping, list) else mapping, nonbonded_method=self.settings.forcefield_settings.nonbonded_method, explicit_charge_correction=self.settings.alchemical_settings.explicit_charge_correction, solvent_component=solv_comp, ) # Validate integrator things settings_validation.validate_timestep( self.settings.forcefield_settings.hydrogen_mass, self.settings.integrator_settings.timestep, ) # Validate simulation & output settings self._validate_simulation_settings( self.settings.simulation_settings, self.settings.integrator_settings, self.settings.output_settings, ) # Validate alchemical settings # PR #125 temporarily pin lambda schedule spacing to n_replicas if ( self.settings.simulation_settings.n_replicas != self.settings.lambda_settings.lambda_windows ): errmsg = ( "Number of replicas in ``simulation_settings``: " f"{self.settings.simulation_settings.n_replicas} must equal " "the number of lambda windows in lambda_settings: " f"{self.settings.lambda_settings.lambda_windows}." ) raise ValueError(errmsg) def _create( self, stateA: ChemicalSystem, stateB: ChemicalSystem, mapping: Optional[Union[gufe.ComponentMapping, list[gufe.ComponentMapping]]], extends: Optional[gufe.ProtocolDAGResult] = None, ) -> list[gufe.ProtocolUnit]: # validate inputs self.validate(stateA=stateA, stateB=stateB, mapping=mapping, extends=extends) # get alchemical components and mapping alchem_comps = system_validation.get_alchemical_components(stateA, stateB) ligandmapping = mapping[0] if isinstance(mapping, list) else mapping # actually create and return Units Anames = ",".join(c.name for c in alchem_comps["stateA"]) Bnames = ",".join(c.name for c in alchem_comps["stateB"]) # DAG dependency is setup -> simulation -> analysis # |---------------------> setup_units = [] simulation_units = [] analysis_units = [] for i in range(self.settings.protocol_repeats): repeat_id = int(uuid.uuid4()) setup = HybridTopologySetupUnit( protocol=self, stateA=stateA, stateB=stateB, ligandmapping=ligandmapping, alchemical_components=alchem_comps, generation=0, repeat_id=repeat_id, name=(f"HybridTopology Setup: {Anames} to {Bnames} repeat {i} generation 0"), ) simulation = HybridTopologyMultiStateSimulationUnit( protocol=self, setup_results=setup, generation=0, repeat_id=repeat_id, name=(f"HybridTopology Simulation: {Anames} to {Bnames} repeat {i} generation 0"), ) analysis = HybridTopologyMultiStateAnalysisUnit( protocol=self, setup_results=setup, simulation_results=simulation, generation=0, repeat_id=repeat_id, name=(f"HybridTopology Analysis: {Anames} to {Bnames} repeat {i} generation 0"), ) setup_units.append(setup) simulation_units.append(simulation) analysis_units.append(analysis) return [*setup_units, *simulation_units, *analysis_units] def _gather(self, protocol_dag_results: Iterable[gufe.ProtocolDAGResult]) -> dict[str, Any]: # result units will have a repeat_id and generations within this repeat_id # first group according to repeat_id unsorted_repeats = defaultdict(list) for d in protocol_dag_results: pu: gufe.ProtocolUnitResult for pu in d.protocol_unit_results: # We only need the analysis units that are ok if ("Analysis" not in pu.name) or (not pu.ok()): continue unsorted_repeats[pu.outputs["repeat_id"]].append(pu) # then sort by generation within each repeat_id list repeats: dict[str, list[gufe.ProtocolUnitResult]] = {} for k, v in unsorted_repeats.items(): repeats[str(k)] = sorted(v, key=lambda x: x.outputs["generation"]) # returns a dict of repeat_id: sorted list of ProtocolUnitResult return repeats ================================================ FILE: src/openfe/protocols/openmm_rfe/hybridtop_units.py ================================================ # This code is part of OpenFE and is licensed under the MIT license. # For details, see https://github.com/OpenFreeEnergy/openfe """ ProtocolUnits for Hybrid Topology methods using OpenMM and OpenMMTools in a Perses-like manner. Acknowledgements ---------------- These ProtocolUnits are based on, and leverage components originating from the Perses toolkit (https://github.com/choderalab/perses). """ import logging import os import pathlib import subprocess from itertools import chain from typing import Any import gufe import matplotlib.pyplot as plt import mdtraj as mdt import numpy as np import numpy.typing as npt import openmm import openmmtools from gufe import ( ChemicalSystem, Component, LigandAtomMapping, ProteinComponent, SmallMoleculeComponent, SolvatedPDBComponent, SolventComponent, ) from gufe.protocols.errors import ProtocolUnitExecutionError from gufe.settings import ( SettingsBaseModel, ThermoSettings, ) from openff.toolkit.topology import Molecule as OFFMolecule from openff.units import Quantity from openff.units import unit as offunit from openff.units.openmm import ensure_quantity, from_openmm, to_openmm from openmmforcefields.generators import SystemGenerator from openmmtools import multistate import openfe from openfe.protocols.openmm_utils.omm_settings import ( BasePartialChargeSettings, ) from ...analysis import plotting from ...utils import log_system_probe, without_oechem_backend from ..openmm_utils import ( charge_generation, multistate_analysis, omm_compute, settings_validation, system_creation, system_validation, ) from ..openmm_utils.serialization import ( deserialize, serialize, ) from . import _rfe_utils from ._rfe_utils.relative import HybridTopologyFactory from .equil_rfe_settings import ( AlchemicalSettings, IntegratorSettings, LambdaSettings, MultiStateOutputSettings, MultiStateSimulationSettings, OpenFFPartialChargeSettings, OpenMMEngineSettings, OpenMMSolvationSettings, RelativeHybridTopologyProtocolSettings, ) logger = logging.getLogger(__name__) class HybridTopologyUnitMixin: def _prepare( self, verbose: bool, scratch_basepath: pathlib.Path | None, shared_basepath: pathlib.Path | None, ): """ Set basepaths and do some initial logging. Parameters ---------- verbose : bool Verbose output of the simulation progress. Output is provided at the INFO level logging. scratch_basepath : pathlib.Path | None Optional scratch base path to write scratch files to. shared_basepath : pathlib.Path | None Optional shared base path to write shared files to. """ self.verbose = verbose # set basepaths def _set_optional_path(basepath): if basepath is None: return pathlib.Path(".") return basepath self.scratch_basepath = _set_optional_path(scratch_basepath) self.shared_basepath = _set_optional_path(shared_basepath) @staticmethod def _get_settings( settings: RelativeHybridTopologyProtocolSettings, ) -> dict[str, SettingsBaseModel]: """ Get a dictionary of Protocol settings. Returns ------- protocol_settings : dict[str, SettingsBaseModel] Notes ----- We return a dict so that we can duck type behaviour between phases. For example subclasses may contain both `solvent` and `complex` settings, using this approach we can extract the relevant entry to the same key and pass it to other methods in a seamless manner. """ protocol_settings: dict[str, SettingsBaseModel] = {} protocol_settings["forcefield_settings"] = settings.forcefield_settings protocol_settings["thermo_settings"] = settings.thermo_settings protocol_settings["alchemical_settings"] = settings.alchemical_settings protocol_settings["lambda_settings"] = settings.lambda_settings protocol_settings["charge_settings"] = settings.partial_charge_settings protocol_settings["solvation_settings"] = settings.solvation_settings protocol_settings["simulation_settings"] = settings.simulation_settings protocol_settings["output_settings"] = settings.output_settings protocol_settings["integrator_settings"] = settings.integrator_settings protocol_settings["engine_settings"] = settings.engine_settings return protocol_settings @staticmethod def _verify_execution_environment( setup_outputs: dict[str, Any], ) -> None: """ Check that the Python environment hasn't changed based on the relevant Python library versions stored in the setup outputs. """ try: if ( (gufe.__version__ != setup_outputs["gufe_version"]) or (openfe.__version__ != setup_outputs["openfe_version"]) or (openmm.__version__ != setup_outputs["openmm_version"]) ): errmsg = "Python environment has changed, cannot continue Protocol execution." raise ProtocolUnitExecutionError(errmsg) except KeyError: errmsg = "Missing environment information from setup outputs." raise ProtocolUnitExecutionError(errmsg) class HybridTopologySetupUnit(gufe.ProtocolUnit, HybridTopologyUnitMixin): """ Setup unit for Hybrid Topology Protocol transformations. """ @staticmethod def _get_components( stateA: ChemicalSystem, stateB: ChemicalSystem ) -> tuple[SolventComponent, ProteinComponent, dict[SmallMoleculeComponent, OFFMolecule]]: """ Get the components from the ChemicalSystem inputs. Parameters ---------- stateA : ChemicalSystem ChemicalSystem defining the state A components. stateB : CHemicalSystem ChemicalSystem defining the state B components. Returns ------- solv_comp : SolventComponent The solvent component. protein_comp : ProteinComponent The protein component. small_mols : dict[SmallMoleculeComponent, openff.toolkit.Molecule] Dictionary of small molecule components paired with their OpenFF Molecule. """ solvent_comp, protein_comp, smcs_A = system_validation.get_components(stateA) _, _, smcs_B = system_validation.get_components(stateB) small_mols = {m: m.to_openff() for m in set(smcs_A).union(set(smcs_B))} # If there is a SolvatedPDBComponent, we set the solvent_comp if isinstance(protein_comp, SolvatedPDBComponent): solvent_comp = protein_comp return solvent_comp, protein_comp, small_mols @staticmethod def _assign_partial_charges( charge_settings: OpenFFPartialChargeSettings, small_mols: dict[SmallMoleculeComponent, OFFMolecule], ) -> None: """ Assign partial charges to the OpenFF Molecules associated with all the SmallMoleculeComponents in the transformation. Parameters ---------- charge_settings : OpenFFPartialChargeSettings Settings for controlling how the partial charges are assigned. small_mols : dict[SmallMoleculeComponent, openff.toolkit.Molecule] Dictionary of OpenFF Molecules to add, keyed by their associated SmallMoleculeComponent. """ for smc, mol in small_mols.items(): charge_generation.assign_offmol_partial_charges( offmol=mol, overwrite=False, method=charge_settings.partial_charge_method, toolkit_backend=charge_settings.off_toolkit_backend, generate_n_conformers=charge_settings.number_of_conformers, nagl_model=charge_settings.nagl_model, ) @staticmethod def _get_system_generator( settings: dict[str, SettingsBaseModel], solvent_component: SolventComponent | None, openff_molecules: list[OFFMolecule] | None, ffcache: pathlib.Path | None, ) -> SystemGenerator: """ Get an OpenMM SystemGenerator. Parameters ---------- settings : dict[str, SettingsBaseModel] A dictionary of protocol settings. solvent_component : SolventComponent | None The solvent component of the system, if any. openff_molecules : list[openff.toolkit.Molecule] | None A list of openff molecules to generate templates for, if any. ffcache : pathlib.Path | None Path to the force field parameter cache. Returns ------- system_generator : openmmtools.SystemGenerator The SystemGenerator for the protocol. """ system_generator = system_creation.get_system_generator( forcefield_settings=settings["forcefield_settings"], integrator_settings=settings["integrator_settings"], thermo_settings=settings["thermo_settings"], cache=ffcache, has_solvent=solvent_component is not None, ) # Handle openff Molecule templates # TODO: revisit this once the SystemGenerator update happens # and we start loading the whole protein into OpenFF Topologies if openff_molecules is None: return system_generator # Register all the templates, pass unique molecules to avoid clashes system_generator.add_molecules(list(set(openff_molecules))) return system_generator @staticmethod def _create_stateA_system( small_mols: dict[SmallMoleculeComponent, OFFMolecule], protein_component: ProteinComponent | None, solvent_component: SolventComponent | None, system_generator: SystemGenerator, solvation_settings: OpenMMSolvationSettings, ) -> tuple[ openmm.System, openmm.app.Topology, openmm.unit.Quantity, dict[Component, npt.NDArray] ]: """ Create an OpenMM System for state A. Parameters ---------- small_mols : dict[SmallMoleculeComponent, openff.toolkit.Molecule] A list of small molecules to include in the System. protein_component : ProteinComponent | None Optionally, the protein component to include in the System. solvent_component : SolventComponent | None Optionally, the solvent component to include in the System. system_generator : SystemGenerator The SystemGenerator object ot use to construct the System. solvation_settings : OpenMMSolvationSettings Settings defining how to build the System. Returns ------- system : openmm.System The System that defines state A. topology : openmm.app.Topology The Topology defining the returned System. positions : openmm.unit.Quantity The positions of the particles in the System. comp_residues : dict[Component, npt.NDArray] A dictionary defining which residues in the System belong to which ChemicalSystem Component. """ modeller, comp_resids = system_creation.get_omm_modeller( protein_comp=protein_component, solvent_comp=solvent_component, small_mols=small_mols, omm_forcefield=system_generator.forcefield, solvent_settings=solvation_settings, ) topology = modeller.getTopology() # Note: roundtrip positions to remove vec3 issues positions = to_openmm(from_openmm(modeller.getPositions())) system = system_generator.create_system( modeller.topology, molecules=list(small_mols.values()), ) return system, topology, positions, comp_resids @staticmethod def _create_stateB_system( small_mols: dict[SmallMoleculeComponent, OFFMolecule], mapping: LigandAtomMapping, stateA_topology: openmm.app.Topology, exclude_resids: npt.NDArray, system_generator: SystemGenerator, ) -> tuple[openmm.System, openmm.app.Topology, npt.NDArray]: """ Create the state B System from the state A Topology. Parameters ---------- small_mols : dict[SmallMoleculeComponent, openff.toolkit.Molecule] Dictionary of OpenFF Molecules keyed by SmallMoleculeComponent to be present in system B. mapping : LigandAtomMapping LigandAtomMapping defining the correspondence between state A and B's alchemical ligand. stateA_topology : openmm.app.Topology The OpenMM topology for state A. exclude_resids : npt.NDArray A list of residues to exclude from state A when building state B. system_generator : SystemGenerator The SystemGenerator to use to build System B. Returns ------- system : openmm.System The state B System. topology : openmm.app.Topology The OpenMM Topology associated with the state B System. alchem_resids : npt.NDArray The residue indices of the state B alchemical species. """ topology, alchem_resids = _rfe_utils.topologyhelpers.combined_topology( topology1=stateA_topology, topology2=small_mols[mapping.componentB].to_topology().to_openmm(), exclude_resids=exclude_resids, ) system = system_generator.create_system( topology, molecules=list(small_mols.values()), ) return system, topology, alchem_resids @staticmethod def _handle_net_charge( stateA_topology: openmm.app.Topology, stateA_positions: openmm.unit.Quantity, stateB_topology: openmm.app.Topology, stateB_system: openmm.System, charge_difference: int, system_mappings: dict[str, dict[int, int]], distance_cutoff: Quantity, solvent_component: SolventComponent | None, ) -> None: """ Handle system net charge by adding an alchemical water. Parameters ---------- stateA_topology : openmm.app.Topology stateA_positions : openmm.unit.Quantity stateB_topology : openmm.app.Topology stateB_system : openmm.System charge_difference : int system_mappings : dict[str, dict[int, int]] distance_cutoff : Quantity solvent_component : SolventComponent | None """ # Base case, return if no net charge if charge_difference == 0: return # Get the residue ids for waters to turn alchemical alchem_water_resids = _rfe_utils.topologyhelpers.get_alchemical_waters( topology=stateA_topology, positions=stateA_positions, charge_difference=charge_difference, distance_cutoff=distance_cutoff, ) # In-place modify state B alchemical waters to ions _rfe_utils.topologyhelpers.handle_alchemical_waters( water_resids=alchem_water_resids, topology=stateB_topology, system=stateB_system, system_mapping=system_mappings, charge_difference=charge_difference, solvent_component=solvent_component, ) def _get_omm_objects( self, stateA: ChemicalSystem, stateB: ChemicalSystem, mapping: LigandAtomMapping, settings: dict[str, SettingsBaseModel], protein_component: ProteinComponent | None, solvent_component: SolventComponent | None, small_mols: dict[SmallMoleculeComponent, OFFMolecule], ) -> tuple[ openmm.System, openmm.app.Topology, openmm.unit.Quantity, openmm.System, openmm.app.Topology, openmm.unit.Quantity, dict[str, dict[int, int]], ]: """ Get OpenMM objects for both end states A and B. Parameters ---------- stateA : ChemicalSystem ChemicalSystem defining end state A. stateB : ChemicalSystem ChemicalSystem defining end state B. mapping : LigandAtomMapping The mapping for alchemical components between state A and B. settings : dict[str, SettingsBaseModel] Settings for the transformation. protein_component : ProteinComponent | None The common ProteinComponent between the end states, if there is is one. solvent_component : SolventComponent | None The common SolventComponent between the end states, if there is one. small_mols : dict[SmallMoleculeComponent, openff.toolkit.Molecule] The small molecules for both end states. Returns ------- stateA_system : openmm.System OpenMM System for state A. stateA_topology : openmm.app.Topology OpenMM Topology for the state A System. stateA_positions : openmm.unit.Quantity Positions of partials for state A System. stateB_system : openmm.System OpenMM System for state B. stateB_topology : openmm.app.Topology OpenMM Topology for the state B System. stateB_positions : openmm.unit.Quantity Positions of partials for state B System. system_mapping : dict[str, dict[int, int]] Dictionary of mappings defining the correspondence between the two state Systems. """ if self.verbose: self.logger.info("Parameterizing systems") def _filter_small_mols(smols, state): return {smc: offmol for smc, offmol in smols.items() if state.contains(smc)} states_inputs = { "A": {"state": stateA, "mols": _filter_small_mols(small_mols, stateA)}, "B": {"state": stateB, "mols": _filter_small_mols(small_mols, stateB)}, } # Everything involving systemgenerator handling has a risk of # oechem <-> rdkit smiles conversion clashes, cautiously ban it. with without_oechem_backend(): # Get the system generators with all the templates registered for state in ["A", "B"]: ffcache = settings["output_settings"].forcefield_cache if ffcache is not None: ffcache = self.shared_basepath / (f"{state}_" + ffcache) states_inputs[state]["generator"] = self._get_system_generator( settings=settings, solvent_component=solvent_component, openff_molecules=list(states_inputs[state]["mols"].values()), ffcache=ffcache, ) (stateA_system, stateA_topology, stateA_positions, comp_resids) = ( self._create_stateA_system( small_mols=states_inputs["A"]["mols"], protein_component=protein_component, solvent_component=solvent_component, system_generator=states_inputs["A"]["generator"], solvation_settings=settings["solvation_settings"], ) ) (stateB_system, stateB_topology, stateB_alchem_resids) = self._create_stateB_system( small_mols=states_inputs["B"]["mols"], mapping=mapping, stateA_topology=stateA_topology, exclude_resids=comp_resids[mapping.componentA], system_generator=states_inputs["B"]["generator"], ) # Get the mapping between the two systems system_mappings = _rfe_utils.topologyhelpers.get_system_mappings( old_to_new_atom_map=mapping.componentA_to_componentB, old_system=stateA_system, old_topology=stateA_topology, old_resids=comp_resids[mapping.componentA], new_system=stateB_system, new_topology=stateB_topology, new_resids=stateB_alchem_resids, # These are non-optional settings for this method fix_constraints=True, ) # Net charge: add alchemical water if needed # Must be done here as we in-place modify the particles of state B. if settings["alchemical_settings"].explicit_charge_correction: self._handle_net_charge( stateA_topology=stateA_topology, stateA_positions=stateA_positions, stateB_topology=stateB_topology, stateB_system=stateB_system, charge_difference=mapping.get_alchemical_charge_difference(), system_mappings=system_mappings, distance_cutoff=settings["alchemical_settings"].explicit_charge_correction_cutoff, solvent_component=solvent_component, ) # Finally get the state B positions stateB_positions = _rfe_utils.topologyhelpers.set_and_check_new_positions( system_mappings, stateA_topology, stateB_topology, old_positions=ensure_quantity(stateA_positions, "openmm"), insert_positions=ensure_quantity( small_mols[mapping.componentB].conformers[0], "openmm" ), ) return ( stateA_system, stateA_topology, stateA_positions, stateB_system, stateB_topology, stateB_positions, system_mappings, ) @staticmethod def _get_alchemical_system( stateA_system: openmm.System, stateA_positions: openmm.unit.Quantity, stateA_topology: openmm.app.Topology, stateB_system: openmm.System, stateB_positions: openmm.unit.Quantity, stateB_topology: openmm.app.Topology, system_mappings: dict[str, dict[int, int]], alchemical_settings: AlchemicalSettings, ): """ Get the hybrid topology alchemical system. Parameters ---------- stateA_system : openmm.System State A OpenMM System stateA_positions : openmm.unit.Quantity Positions of state A System stateA_topology : openmm.app.Topology Topology of state A System stateB_system : openmm.System State B OpenMM System stateB_positions : openmm.unit.Quantity Positions of state B System stateB_topology : openmm.app.Topology Topology of state B System system_mappings : dict[str, dict[int, int]] Mapping of corresponding atoms between the two Systems. alchemical_settings : AlchemicalSettings The alchemical settings defining how the alchemical system will be built. Returns ------- hybrid_factory : HybridTopologyFactory The factory creating the hybrid system. hybrid_system : openmm.System The hybrid System. """ if alchemical_settings.softcore_LJ.lower() == "gapsys": softcore_LJ_v2 = True elif alchemical_settings.softcore_LJ.lower() == "beutler": softcore_LJ_v2 = False hybrid_factory = _rfe_utils.relative.HybridTopologyFactory( stateA_system, stateA_positions, stateA_topology, stateB_system, stateB_positions, stateB_topology, old_to_new_atom_map=system_mappings["old_to_new_atom_map"], old_to_new_core_atom_map=system_mappings["old_to_new_core_atom_map"], use_dispersion_correction=alchemical_settings.use_dispersion_correction, softcore_alpha=alchemical_settings.softcore_alpha, softcore_LJ_v2=softcore_LJ_v2, softcore_LJ_v2_alpha=alchemical_settings.softcore_alpha, interpolate_old_and_new_14s=alchemical_settings.turn_off_core_unique_exceptions, ) return hybrid_factory, hybrid_factory.hybrid_system def _subsample_topology( self, hybrid_topology: mdt.Topology, hybrid_positions: openmm.unit.Quantity, output_selection: str, output_filename: str, atom_classes: dict[str, set[int]], ) -> npt.NDArray: """ Subsample the hybrid topology based on user-selected output selection and write the subsampled topology to a PDB file. Parameters ---------- hybrid_topology : mdtraj.Topology The hybrid system topology to subsample. hybrid_positions : openmm.unit.Quantity The hybrid system positions. output_selection : str An MDTraj selection string to subsample the topology with. output_filename : str The name of the file to write the PDB to. atom_classes : dict[str, set[int]] A dictionary defining what atoms belong to the different components of the hybrid system. Returns ------- selection_indices : npt.NDArray The indices of the subselected system. TODO ---- * Modify this to also store the full system. * Use the mdtraj_from_openmm utility. """ selection_indices = hybrid_topology.select(output_selection) # Write out a PDB containing the subsampled hybrid state # We use bfactors as a hack to label different states # bfactor of 0 is environment atoms # bfactor of 0.25 is unique old atoms # bfactor of 0.5 is core atoms # bfactor of 0.75 is unique new atoms bfactors = np.zeros_like(selection_indices, dtype=float) bfactors[np.isin(selection_indices, list(atom_classes["unique_old_atoms"]))] = 0.25 bfactors[np.isin(selection_indices, list(atom_classes["core_atoms"]))] = 0.50 bfactors[np.isin(selection_indices, list(atom_classes["unique_new_atoms"]))] = 0.75 if len(selection_indices) > 0: traj = mdt.Trajectory( hybrid_positions[selection_indices, :], hybrid_topology.subset(selection_indices), ).save_pdb( self.shared_basepath / output_filename, bfactors=bfactors, ) return selection_indices def run( self, *, dry: bool = False, verbose: bool = True, scratch_basepath: pathlib.Path | None = None, shared_basepath: pathlib.Path | None = None, ) -> dict[str, Any]: """Setup a hybrid topology system. Parameters ---------- dry : bool Do a dry run of the calculation, creating all necessary hybrid system components (topology, system, sampler, etc...) but without running the simulation. verbose : bool Verbose output of the simulation progress. Output is provided via INFO level logging. scratch_basepath: pathlib.Path | None Where to store temporary files, defaults to current working directory shared_basepath : pathlib.Path | None Where to run the calculation, defaults to current working directory Returns ------- dict Outputs created by the setup unit or the debug objects (e.g. HybridTopologyFactory) if ``dry==True``. Raises ------ error Exception if anything failed """ # Prepare paths & verbosity self._prepare(verbose, scratch_basepath, shared_basepath) if self.verbose: self.logger.info("Starting system setup unit") # Get settings settings = self._get_settings(self._inputs["protocol"].settings) # Get components stateA = self._inputs["stateA"] stateB = self._inputs["stateB"] mapping = self._inputs["ligandmapping"] alchem_comps = self._inputs["alchemical_components"] solvent_comp, protein_comp, small_mols = self._get_components(stateA, stateB) # Assign partial charges now to avoid any discrepancies later self._assign_partial_charges(settings["charge_settings"], small_mols) ( stateA_system, stateA_topology, stateA_positions, stateB_system, stateB_topology, stateB_positions, system_mappings, ) = self._get_omm_objects( stateA=stateA, stateB=stateB, mapping=mapping, settings=settings, protein_component=protein_comp, solvent_component=solvent_comp, small_mols=small_mols, ) # Get the hybrid factory & system hybrid_factory, hybrid_system = self._get_alchemical_system( stateA_system=stateA_system, stateA_positions=stateA_positions, stateA_topology=stateA_topology, stateB_system=stateB_system, stateB_positions=stateB_positions, stateB_topology=stateB_topology, system_mappings=system_mappings, alchemical_settings=settings["alchemical_settings"], ) # Subselect system based on user inputs & write initial PDB selection_indices = self._subsample_topology( hybrid_topology=hybrid_factory.hybrid_topology, hybrid_positions=hybrid_factory.hybrid_positions, output_selection=settings["output_settings"].output_indices, output_filename=settings["output_settings"].output_structure, atom_classes=hybrid_factory._atom_classes, ) # Serialize things # OpenMM System system_outfile = self.shared_basepath / "hybrid_system.xml.bz2" serialize(hybrid_system, system_outfile) # Positions positions_outfile = self.shared_basepath / "hybrid_positions.npy" npy_positions = from_openmm(hybrid_factory.hybrid_positions).to("nanometer").m np.save(positions_outfile, npy_positions) unit_results_dict = { "system": system_outfile, "positions": positions_outfile, "pdb_structure": self.shared_basepath / settings["output_settings"].output_structure, "selection_indices": selection_indices, } if dry: unit_results_dict |= { # Adding unserialized objects so we can directly use them # to chain units in tests "hybrid_factory": hybrid_factory, "hybrid_system": hybrid_system, "hybrid_positions": hybrid_factory.hybrid_positions, } return unit_results_dict def _execute( self, ctx: gufe.Context, **inputs, ) -> dict[str, Any]: log_system_probe(logging.INFO, paths=[ctx.scratch]) outputs = self.run(scratch_basepath=ctx.scratch, shared_basepath=ctx.shared) return { "repeat_id": self._inputs["repeat_id"], "generation": self._inputs["generation"], "openmm_version": openmm.__version__, "openfe_version": openfe.__version__, "gufe_version": gufe.__version__, **outputs, } class HybridTopologyMultiStateSimulationUnit(gufe.ProtocolUnit, HybridTopologyUnitMixin): """ Multi-state simulation (e.g. multi replica methods like hamiltonian replica exchange) unit for Hybrid Topology Protocol transformations. """ @staticmethod def _check_restart(output_settings: SettingsBaseModel, shared_path: pathlib.Path): """ Check if we are doing a restart. Parameters ---------- output_settings : SettingsBaseModel The simulation output settings shared_path : pathlib.Path The shared directory where we should be looking for existing files. Notes ----- For now this just checks if the netcdf files are present in the shared directory but in the future this may expand depending on how warehouse works. Raises ------ IOError If either the checkpoint or trajectory files don't exist. """ trajectory = shared_path / output_settings.output_filename checkpoint = shared_path / output_settings.checkpoint_storage_filename if trajectory.is_file() and checkpoint.is_file(): return True elif trajectory.is_file() ^ checkpoint.is_file(): if trajectory.is_file(): errmsg = "the trajectory file is present but not the checkpoint file. " else: errmsg = "the checkpoint file is present but not the trajectory file. " errmsg = ( "Attempting to restart but " + errmsg + "This should not happen under normal circumstances." ) raise IOError(errmsg) else: return False @staticmethod def _get_integrator( integrator_settings: IntegratorSettings, simulation_settings: MultiStateSimulationSettings, system: openmm.System, ) -> openmmtools.mcmc.LangevinDynamicsMove: """ Get and validate the integrator Parameters ---------- integrator_settings : IntegratorSettings Settings controlling the Langevin integrator. simulation_settings : MultiStateSimulationSettings Settings controlling the simulation. system : openmm.System The OpenMM System. Returns ------- integrator : openmmtools.mcmc.LangevinDynamicsMove The LangevinDynamicsMove integrator. Raises ------ ValueError If there are virtual sites in the system, but velocities are not being reassigned after every MCMC move. """ steps_per_iteration = settings_validation.convert_steps_per_iteration( simulation_settings, integrator_settings ) integrator = openmmtools.mcmc.LangevinDynamicsMove( timestep=to_openmm(integrator_settings.timestep), collision_rate=to_openmm(integrator_settings.langevin_collision_rate), n_steps=steps_per_iteration, reassign_velocities=integrator_settings.reassign_velocities, n_restart_attempts=integrator_settings.n_restart_attempts, constraint_tolerance=integrator_settings.constraint_tolerance, ) # Validate for known issue when dealing with virtual sites # and multistate simulations if not integrator_settings.reassign_velocities: for particle_idx in range(system.getNumParticles()): if system.isVirtualSite(particle_idx): errmsg = ( "Simulations with virtual sites without velocity " "reassignments are unstable with MCMC integrators." ) raise ValueError(errmsg) return integrator @staticmethod def _get_reporter( storage_path: pathlib.Path, selection_indices: npt.NDArray, output_settings: MultiStateOutputSettings, simulation_settings: MultiStateSimulationSettings, ) -> multistate.MultiStateReporter: """ Get the multistate reporter. Parameters ---------- storage_path : pathlib.Path Path to the directory where files should be written. selection_indices : npt.NDArray The set of system indices to report positions & velocities for. output_settings : MultiStateOutputSettings Settings defining how outputs should be written. simulation_settings : MultiStateSimulationSettings Settings defining out the simulation should be run. Notes ----- All this does is create the reporter, it works for both new reporters and if we are doing a restart. """ # Define the trajectory & checkpoint files nc = storage_path / output_settings.output_filename # The checkpoint file in openmmtools is taken as a file relative # to the location of the nc file, so you only want the filename chk = output_settings.checkpoint_storage_filename if output_settings.positions_write_frequency is not None: pos_interval = settings_validation.divmod_time_and_check( numerator=output_settings.positions_write_frequency, denominator=simulation_settings.time_per_iteration, numerator_name="output settings' position_write_frequency", denominator_name="simulation settings' time_per_iteration", ) else: pos_interval = 0 if output_settings.velocities_write_frequency is not None: vel_interval = settings_validation.divmod_time_and_check( numerator=output_settings.velocities_write_frequency, denominator=simulation_settings.time_per_iteration, numerator_name="output settings' velocity_write_frequency", denominator_name="sampler settings' time_per_iteration", ) else: vel_interval = 0 chk_intervals = settings_validation.convert_checkpoint_interval_to_iterations( checkpoint_interval=output_settings.checkpoint_interval, time_per_iteration=simulation_settings.time_per_iteration, ) return multistate.MultiStateReporter( storage=nc, analysis_particle_indices=selection_indices, checkpoint_interval=chk_intervals, checkpoint_storage=chk, position_interval=pos_interval, velocity_interval=vel_interval, ) @staticmethod def _get_sampler( system: openmm.System, positions: openmm.unit.Quantity, lambdas: _rfe_utils.lambdaprotocol.LambdaProtocol, integrator: openmmtools.mcmc.MCMCMove, reporter: multistate.MultiStateReporter, simulation_settings: MultiStateSimulationSettings, thermo_settings: ThermoSettings, alchem_settings: AlchemicalSettings, platform: openmm.Platform, restart: bool, dry: bool, ) -> multistate.MultiStateSampler: """ Get the MultiStateSampler. Parameters ---------- system : openmm.System The OpenMM System to simulate. positions : openmm.unit.Quantity The positions of the OpenMM System. lambdas : LambdaProtocol The lambda protocol to sample along. integrator : openmmtools.mcmc.MCMCMove The integrator to use. reporter : multistate.MultiStateReporter The reporter to attach to the sampler. simulation_settings : MultiStateSimulationSettings The simulation control settings. thermo_settings : ThermoSettings The thermodynamic control settings. alchem_settings : AlchemicalSettings The alchemical transformation settings. platform : openmm.Platform The compute platform to use. restart : bool ``True`` if we are doing a simulation restart. dry : bool Whether or not this is a dry run. Returns ------- sampler : multistate.MultiStateSampler The requested sampler. """ _SAMPLERS = { "repex": _rfe_utils.multistate.HybridRepexSampler, "sams": _rfe_utils.multistate.HybridSAMSSampler, "independent": _rfe_utils.multistate.HybridMultiStateSampler, } # note we if/else around sampler method because in the future # we will try to reuse this method and just have _SAMPLERs be # defined elsewhere sampler_method = simulation_settings.sampler_method.lower() try: sampler_class = _SAMPLERS[sampler_method] except KeyError: errmsg = f"Unknown sampler {sampler_method}" raise AttributeError(errmsg) # Get the real time analysis values to use rta_its, rta_min_its = settings_validation.convert_real_time_analysis_iterations( simulation_settings=simulation_settings, ) # Get the number of production iterations to run for steps_per_iteration = integrator.n_steps timestep = from_openmm(integrator.timestep) number_of_iterations = int( settings_validation.get_simsteps( sim_length=simulation_settings.production_length, timestep=timestep, mc_steps=steps_per_iteration, ) / steps_per_iteration ) # convert early_termination_target_error from kcal/mol to kT early_termination_target_error = ( settings_validation.convert_target_error_from_kcal_per_mole_to_kT( thermo_settings.temperature, simulation_settings.early_termination_target_error, ) ) sampler_kwargs = { "mcmc_moves": integrator, "hybrid_system": system, "hybrid_positions": positions, "online_analysis_interval": rta_its, "online_analysis_target_error": early_termination_target_error, "online_analysis_minimum_iterations": rta_min_its, "number_of_iterations": number_of_iterations, } if sampler_method == "sams": sampler_kwargs |= { "flatness_criteria": simulation_settings.sams_flatness_criteria, "gamma0": simulation_settings.sams_gamma0, } if sampler_method == "repex": sampler_kwargs |= {"replica_mixing_scheme": "swap-all"} # Restarting doesn't need any setup, we just rebuild from storage. if restart: sampler = sampler_class.from_storage(reporter) # type: ignore[attr-defined] # We do some checks to make sure we are running the same system system_validation.assert_multistate_system_equality( ref_system=system, stored_system=sampler._thermodynamic_states[0].get_system(remove_thermostat=True), ) # We do check to make sure we have the same thermodynamic # parameters and that the lambda schedule is the same. for index, thermostate in enumerate(sampler._thermodynamic_states): assert thermostate.temperature == to_openmm(thermo_settings.temperature) assert thermostate.pressure == to_openmm(thermo_settings.pressure) for key in lambdas.functions: lambda_value = lambdas.lambda_schedule[index] expected = lambdas.functions[key](lambda_value) stored = getattr(thermostate, key) assert expected == stored # Finally we check that some of the sampler parameters haven't changed if ( (simulation_settings.n_replicas != sampler.n_states) or (simulation_settings.n_replicas != sampler.n_replicas) or (sampler.mcmc_moves[0].n_steps != steps_per_iteration) or (sampler.mcmc_moves[0].timestep != integrator.timestep) ): errmsg = "Sampler in checkpoint does not match Protocol settings, cannot resume." raise ValueError(errmsg) else: sampler = sampler_class(**sampler_kwargs) sampler.setup( n_replicas=simulation_settings.n_replicas, reporter=reporter, lambda_protocol=lambdas, temperature=to_openmm(thermo_settings.temperature), endstates=alchem_settings.endstate_dispersion_correction, minimization_platform=platform.getName(), # Set minimization steps to None when running in dry mode # otherwise do a very small one to avoid NaNs minimization_steps=100 if not dry else None, ) # Get and set the context caches sampler.energy_context_cache = openmmtools.cache.ContextCache( capacity=None, time_to_live=None, platform=platform, ) sampler.sampler_context_cache = openmmtools.cache.ContextCache( capacity=None, time_to_live=None, platform=platform, ) return sampler def _run_simulation( self, sampler: multistate.MultiStateSampler, reporter: multistate.MultiStateReporter, simulation_settings: MultiStateSimulationSettings, integrator_settings: IntegratorSettings, output_settings: MultiStateOutputSettings, dry: bool, ): """ Run the simulation. Parameters ---------- sampler : multistate.MultiStateSampler. The sampler associated with the simulation to run. reporter : multistate.MultiStateReporter The reporter associated with the sampler. simulation_settings : MultiStateSimulationSettings Simulation control settings. integrator_settings : IntegratorSettings Integrator control settings. output_settings : MultiStateOutputSettings Simulation output control settings. dry : bool Whether or not to dry run the simulation. """ # Get the relevant simulation steps mc_steps = settings_validation.convert_steps_per_iteration( simulation_settings=simulation_settings, integrator_settings=integrator_settings, ) equil_steps = settings_validation.get_simsteps( sim_length=simulation_settings.equilibration_length, timestep=integrator_settings.timestep, mc_steps=mc_steps, ) prod_steps = settings_validation.get_simsteps( sim_length=simulation_settings.production_length, timestep=integrator_settings.timestep, mc_steps=mc_steps, ) if not dry: # pragma: no-cover # No productions steps have been taken, so start from scratch if sampler._iteration == 0: # minimize if self.verbose: self.logger.info("minimizing systems") sampler.minimize(max_iterations=simulation_settings.minimization_steps) # equilibrate if self.verbose: self.logger.info("equilibrating systems") sampler.equilibrate(int(equil_steps / mc_steps)) # At this point we are ready for production if self.verbose: self.logger.info("running production phase") # We use `run` so that we're limited by the number of iterations # we passed when we built the sampler. # TODO: I'm being extra prudent by passing in n_iterations here - remove? sampler.run(n_iterations=int(prod_steps / mc_steps) - sampler._iteration) if self.verbose: self.logger.info("production phase complete") else: # We ran a dry simulation # close reporter when you're done, prevent file handle clashes reporter.close() # TODO: review this is likely no longer necessary # clean up the reporter file fns = [ self.shared_basepath / output_settings.output_filename, self.shared_basepath / output_settings.checkpoint_storage_filename, ] for fn in fns: os.remove(fn) def run( self, *, system: openmm.System, positions: openmm.unit.Quantity, selection_indices: npt.NDArray, dry: bool = False, verbose: bool = True, scratch_basepath: pathlib.Path | None = None, shared_basepath: pathlib.Path | None = None, ) -> dict[str, Any]: """Run the free energy calculation using a multistate sampler. Parameters ---------- system : openmm.System The System to simulate. positions : openmm.unit.Quantity The positions of the System. selection_indices : npt.NDArray Indices of the System particles to write to file. dry : bool Do a dry run of the calculation, creating all necessary hybrid system components (topology, system, sampler, etc...) but without running the simulation. verbose : bool Verbose output of the simulation progress. Output is provided via INFO level logging. scratch_basepath: pathlib.Path | None Where to store temporary files, defaults to current working directory shared_basepath : pathlib.Path | None Where to run the calculation, defaults to current working directory Returns ------- dict Outputs created in the basepath directory or the debug objects (i.e. sampler) if ``dry==True``. Raises ------ error Exception if anything failed """ # Prepare paths & verbosity self._prepare(verbose, scratch_basepath, shared_basepath) if self.verbose: self.logger.info("Starting simulation unit") # Get the settings settings = self._get_settings(self._inputs["protocol"].settings) # Check for a restart self.restart = self._check_restart( output_settings=settings["output_settings"], shared_path=self.shared_basepath ) # Get the lambda schedule # TODO - this should be better exposed to users lambdas = _rfe_utils.lambdaprotocol.LambdaProtocol( functions=settings["lambda_settings"].lambda_functions, windows=settings["lambda_settings"].lambda_windows, ) # Get the compute platform restrict_cpu = settings["forcefield_settings"].nonbonded_method.lower() == "nocutoff" platform = omm_compute.get_openmm_platform( platform_name=settings["engine_settings"].compute_platform, gpu_device_index=settings["engine_settings"].gpu_device_index, restrict_cpu_count=restrict_cpu, ) # Get the integrator integrator = self._get_integrator( integrator_settings=settings["integrator_settings"], simulation_settings=settings["simulation_settings"], system=system, ) try: # Get the reporter reporter = self._get_reporter( storage_path=self.shared_basepath, selection_indices=selection_indices, output_settings=settings["output_settings"], simulation_settings=settings["simulation_settings"], ) # Get the sampler sampler = self._get_sampler( system=system, positions=positions, lambdas=lambdas, integrator=integrator, reporter=reporter, simulation_settings=settings["simulation_settings"], thermo_settings=settings["thermo_settings"], alchem_settings=settings["alchemical_settings"], platform=platform, restart=self.restart, dry=dry, ) # Run the simulation self._run_simulation( sampler=sampler, reporter=reporter, simulation_settings=settings["simulation_settings"], integrator_settings=settings["integrator_settings"], output_settings=settings["output_settings"], dry=dry, ) finally: # Have to wrap this in a try/except, because we might # be in a situation where the reporter or sampler wasn't created try: # Order is reporter, contexts, sampler, integrator reporter.close() # close to prevent file handle clashes # clear GPU context # Note: use cache.empty() when openmmtools #690 is resolved for context in list(sampler.energy_context_cache._lru._data.keys()): del sampler.energy_context_cache._lru._data[context] for context in list(sampler.sampler_context_cache._lru._data.keys()): del sampler.sampler_context_cache._lru._data[context] # cautiously clear out the global context cache too for context in list(openmmtools.cache.global_context_cache._lru._data.keys()): del openmmtools.cache.global_context_cache._lru._data[context] del sampler.sampler_context_cache, sampler.energy_context_cache # Keep these around in a dry run so we can inspect things if not dry: # At this point we know the sampler exists, so we del the integrator # first since it's associated with the sampler del integrator, sampler except UnboundLocalError: pass if not dry: # pragma: no-cover return { "nc": self.shared_basepath / settings["output_settings"].output_filename, "checkpoint": self.shared_basepath / settings["output_settings"].checkpoint_storage_filename, } else: return { "sampler": sampler, "integrator": integrator, } def _execute( self, ctx: gufe.Context, *, setup_results, **inputs, ) -> dict[str, Any]: log_system_probe(logging.INFO, paths=[ctx.scratch]) # Ensure that the environment hasn't changed self._verify_execution_environment(setup_results.outputs) # Get the relevant inputs for running the unit system = deserialize(setup_results.outputs["system"]) positions = to_openmm(np.load(setup_results.outputs["positions"]) * offunit.nm) selection_indices = setup_results.outputs["selection_indices"] # Run the unit outputs = self.run( system=system, positions=positions, selection_indices=selection_indices, scratch_basepath=ctx.scratch, shared_basepath=ctx.shared, ) return { "repeat_id": self._inputs["repeat_id"], "generation": self._inputs["generation"], **outputs, } class HybridTopologyMultiStateAnalysisUnit(gufe.ProtocolUnit, HybridTopologyUnitMixin): """ Analysis unit for multi-state Hybrid Topology Protocol transformations. """ @staticmethod def _analyze_multistate_energies( trajectory: pathlib.Path, checkpoint: pathlib.Path, sampler_method: str, output_directory: pathlib.Path, dry: bool, ): """ Analyze multistate energies and generate plots. Parameters ---------- trajectory : pathlib.Path Path to the NetCDF trajectory file. checkpoint : pathlib.Path The name of the checkpoint file. Note this is relative in path to the trajectory file. sampler_method : str The multistate sampler method used. output_directory : pathlib.Path The path to where plots will be written. dry : bool Whether or not we are running a dry run. """ reporter = multistate.MultiStateReporter( storage=trajectory, # Note: openmmtools only wants the name of the checkpoint # file, it assumes it to be in the same place as the trajectory checkpoint_storage=checkpoint.name, open_mode="r", ) analyzer = multistate_analysis.MultistateEquilFEAnalysis( reporter=reporter, sampling_method=sampler_method, result_units=offunit.kilocalorie_per_mole, ) # Only create plots when not doing a dry run if not dry: analyzer.plot(filepath=output_directory, filename_prefix="") analyzer.close() reporter.close() return analyzer.unit_results_dict @staticmethod def _structural_analysis( pdb_file: pathlib.Path, trj_file: pathlib.Path, output_directory: pathlib.Path, dry: bool, ) -> dict[str, str | pathlib.Path]: """ Run structural analysis using ``openfe-analysis``. Parameters ---------- pdb_file : pathlib.Path Path to the PDB file. trj_file : pathlib.Path Path to the trajectory file. output_directory : pathlib.Path The output directory where plots and the data NPZ file will be stored. dry : bool Whether or not we are running a dry run. Returns ------- dict[str, str | pathlib.Path] Dictionary containing either the path to the NPZ file with the structural data, or the analysis error. Notes ----- Don't put energy analysis here as it uses the MultiStateReporter, the structural analysis requires the file handle to be closed. """ from openfe_analysis import rmsd try: data = rmsd.gather_rms_data(pdb_file, trj_file) # TODO: eventually change this to more specific exception types except Exception as e: return {"structural_analysis_error": str(e)} # Generate relevant plots if not a dry run if not dry: if d := data["protein_2D_RMSD"]: fig = plotting.plot_2D_rmsd(d) fig.savefig(output_directory / "protein_2D_RMSD.png") plt.close(fig) f2 = plotting.plot_ligand_COM_drift(data["time(ps)"], data["ligand_wander"]) f2.savefig(output_directory / "ligand_COM_drift.png") plt.close(f2) f3 = plotting.plot_ligand_RMSD(data["time(ps)"], data["ligand_RMSD"]) f3.savefig(output_directory / "ligand_RMSD.png") plt.close(f3) # Write out an NPZ with all the relevant analysis data npz_file = output_directory / "structural_analysis.npz" np.savez_compressed( npz_file, protein_RMSD=np.asarray(data["protein_RMSD"], dtype=np.float32), ligand_RMSD=np.asarray(data["ligand_RMSD"], dtype=np.float32), ligand_COM_drift=np.asarray(data["ligand_wander"], dtype=np.float32), protein_2D_RMSD=np.asarray(data["protein_2D_RMSD"], dtype=np.float32), time_ps=np.asarray(data["time(ps)"], dtype=np.float32), ) return {"structural_analysis": npz_file} def run( self, *, pdb_file: pathlib.Path, trajectory: pathlib.Path, checkpoint: pathlib.Path, dry: bool = False, verbose: bool = True, scratch_basepath: pathlib.Path | None = None, shared_basepath: pathlib.Path | None = None, ) -> dict[str, Any]: """Analyze the multistate simulation. Parameters ---------- pdb_file : pathlib.Path Path to the PDB file representing the subsampled structure. trajectory : pathlib.Path Path to the MultiStateReporter generated NetCDF file. checkpoint : pathlib.Path Path to the checkpoint file generated by MultiStateReporter. dry : bool Do a dry run of the calculation, creating all necessary hybrid system components (topology, system, sampler, etc...) but without running the simulation. verbose : bool Verbose output of the simulation progress. Output is provided via INFO level logging. scratch_basepath: pathlib.Path | None Where to store temporary files, defaults to current working directory shared_basepath : pathlib.Path | None Where to run the calculation, defaults to current working directory Returns ------- dict Outputs created in the basepath directory or the debug objects (i.e. sampler) if ``dry==True``. Raises ------ error Exception if anything failed """ # Prepare paths & verbosity self._prepare(verbose, scratch_basepath, shared_basepath) if self.verbose: self.logger.info("Starting simulation analysis unit") # Get the settings settings = self._get_settings(self._inputs["protocol"].settings) # Energies analysis if verbose: self.logger.info("Analyzing energies") energy_analysis = self._analyze_multistate_energies( trajectory=trajectory, checkpoint=checkpoint, sampler_method=settings["simulation_settings"].sampler_method.lower(), output_directory=self.shared_basepath, dry=dry, ) # Structural analysis if verbose: self.logger.info("Analyzing structural outputs") structural_analysis = self._structural_analysis( pdb_file=pdb_file, trj_file=trajectory, output_directory=self.shared_basepath, dry=dry, ) # Return relevant things outputs = energy_analysis | structural_analysis return outputs def _execute( self, ctx: gufe.Context, *, setup_results, simulation_results, **inputs, ) -> dict[str, Any]: log_system_probe(logging.INFO, paths=[ctx.scratch]) # Ensure that we the environment hasn't changed self._verify_execution_environment(setup_results.outputs) pdb_file = setup_results.outputs["pdb_structure"] selection_indices = setup_results.outputs["selection_indices"] trajectory = simulation_results.outputs["nc"] checkpoint = simulation_results.outputs["checkpoint"] outputs = self.run( pdb_file=pdb_file, trajectory=trajectory, checkpoint=checkpoint, scratch_basepath=ctx.scratch, shared_basepath=ctx.shared, ) return { "repeat_id": self._inputs["repeat_id"], "generation": self._inputs["generation"], # We include various other outputs here to make # things easier when gathering. "pdb_structure": pdb_file, "trajectory": trajectory, "checkpoint": checkpoint, "selection_indices": selection_indices, **outputs, } ================================================ FILE: src/openfe/protocols/openmm_septop/__init__.py ================================================ # This code is part of OpenFE and is licensed under the MIT license. # For details, see https://github.com/OpenFreeEnergy/openfe """ Run SepTop free energy calculations using OpenMM and OpenMMTools. """ from .equil_septop_method import ( SepTopComplexAnalysisUnit, SepTopComplexRunUnit, SepTopComplexSetupUnit, SepTopProtocol, SepTopProtocolResult, SepTopSolventAnalysisUnit, SepTopSolventRunUnit, SepTopSolventSetupUnit, ) from .equil_septop_settings import ( SepTopSettings, ) __all__ = [ "SepTopProtocol", "SepTopSettings", "SepTopProtocolResult", "SepTopComplexSetupUnit", "SepTopSolventSetupUnit", "SepTopSolventRunUnit", "SepTopComplexRunUnit", "SepTopSolventAnalysisUnit", "SeptopComplexAnalysisUnit", ] ================================================ FILE: src/openfe/protocols/openmm_septop/base_units.py ================================================ # This code is part of OpenFE and is licensed under the MIT license. # For details, see https://github.com/OpenFreeEnergy/openfe """OpenMM Equilibrium SepTop Protocol base classes ================================================== Base classes for the equilibrium OpenMM SepTop free energy ProtocolUnits. This mostly implements BaseSepTopUnit whose methods can be overridden to define different types of alchemical transformations. TODO ---- * Add in all the AlchemicalFactory and AlchemicalRegion kwargs as settings. """ import abc import logging import pathlib from typing import Any, Literal, Optional import gufe import numpy.typing as npt import openmm import openmmtools from gufe import ( ChemicalSystem, ProteinComponent, SmallMoleculeComponent, SolventComponent, ) from gufe.components import Component from gufe.protocols.errors import ProtocolUnitExecutionError from openff.toolkit.topology import Molecule as OFFMolecule from openff.units import unit as offunit from openff.units.openmm import ensure_quantity, from_openmm, to_openmm from openmm import unit as omm_unit from openmmforcefields.generators import SystemGenerator from openmmtools import multistate from openmmtools.alchemy import AbsoluteAlchemicalFactory, AlchemicalRegion from openmmtools.states import ( SamplerState, ThermodynamicState, create_thermodynamic_state_protocol, ) import openfe from openfe.protocols.openmm_afe.equil_afe_settings import ( AlchemicalSettings, BaseSolvationSettings, IntegratorSettings, MultiStateOutputSettings, MultiStateSimulationSettings, OpenFFPartialChargeSettings, OpenMMEngineSettings, OpenMMSystemGeneratorFFSettings, ThermoSettings, ) from openfe.protocols.openmm_md.plain_md_methods import PlainMDSimulationUnit from openfe.protocols.openmm_utils import omm_compute from openfe.protocols.openmm_utils.omm_settings import SettingsBaseModel from openfe.protocols.openmm_utils.serialization import deserialize from openfe.utils import log_system_probe, without_oechem_backend from ..openmm_utils import ( charge_generation, multistate_analysis, settings_validation, system_creation, system_validation, ) from ..openmm_utils.mdtraj_utils import mdtraj_from_openmm from .utils import SepTopParameterState logger = logging.getLogger(__name__) def _pre_equilibrate( system: openmm.System, topology: openmm.app.Topology, positions: omm_unit.Quantity, settings: dict[str, SettingsBaseModel], endstate: Literal["A", "B", "AB"], dry: bool, shared_basepath: pathlib.Path, platform: openmm.Platform, verbose: bool, logger, ) -> tuple[omm_unit.Quantity, omm_unit.Quantity]: """ Run a non-alchemical equilibration to get a stable system. Parameters ---------- system : openmm.System An OpenMM System to equilibrate. topology : openmm.app.Topology OpenMM Topology of the System. positions : openmm.unit.Quantity Initial positions for the system. settings : dict[str, SettingsBaseModel] A dictionary of settings objects. Expects the following entries: * `engine_settings` * `thermo_settings` * `integrator_settings` * `equil_simulation_settings` * `equil_output_settings` endstate: Literal['A', 'B', 'AB'] The endstate that is pre-equilibrated,can be 'A', 'B' or 'AB'. dry: bool Whether or not this is a dry run. shared_basepath: pathlib.Path The Path to the shared storage. verbose: bool Whether to print extra information logger: logging.getLogger Name of the logger Returns ------- equilibrated_positions : npt.NDArray Equilibrated system positions box : openmm.unit.Quantity Box vectors of the equilibrated system. """ # Prep the simulation object integrator = openmm.LangevinMiddleIntegrator( to_openmm(settings["thermo_settings"].temperature), to_openmm(settings["integrator_settings"].langevin_collision_rate), to_openmm(settings["integrator_settings"].timestep), ) simulation = openmm.app.Simulation( topology=topology, system=system, integrator=integrator, platform=platform, ) # Get the necessary number of steps if settings["equil_simulation_settings"].equilibration_length_nvt is not None: equil_steps_nvt = settings_validation.get_simsteps( sim_length=settings["equil_simulation_settings"].equilibration_length_nvt, timestep=settings["integrator_settings"].timestep, mc_steps=1, ) else: equil_steps_nvt = None equil_steps_npt = settings_validation.get_simsteps( sim_length=settings["equil_simulation_settings"].equilibration_length, timestep=settings["integrator_settings"].timestep, mc_steps=1, ) prod_steps_npt = settings_validation.get_simsteps( sim_length=settings["equil_simulation_settings"].production_length, timestep=settings["integrator_settings"].timestep, mc_steps=1, ) if verbose: logger.info("running non-alchemical equilibration MD") # Don't do anything if we're doing a dry run if dry: box = system.getDefaultPeriodicBoxVectors() return positions, to_openmm(from_openmm(box)) # TODO: Refactor this part to live outside the method call # We have to modify the output settings to have different output # names for the files from the two end states unfrozen_outsettings = settings["equil_output_settings"].unfrozen_copy() if endstate == "A" or endstate == "B" or endstate == "AB": if unfrozen_outsettings.production_trajectory_filename: unfrozen_outsettings.production_trajectory_filename = ( unfrozen_outsettings.production_trajectory_filename + f"_state{endstate}.xtc" ) if unfrozen_outsettings.preminimized_structure: unfrozen_outsettings.preminimized_structure = ( unfrozen_outsettings.preminimized_structure + f"_state{endstate}.pdb" ) if unfrozen_outsettings.minimized_structure: unfrozen_outsettings.minimized_structure = ( unfrozen_outsettings.minimized_structure + f"_state{endstate}.pdb" ) if unfrozen_outsettings.equil_nvt_structure: unfrozen_outsettings.equil_nvt_structure = ( unfrozen_outsettings.equil_nvt_structure + f"_state{endstate}.pdb" ) if unfrozen_outsettings.equil_npt_structure: unfrozen_outsettings.equil_npt_structure = ( unfrozen_outsettings.equil_npt_structure + f"_state{endstate}.pdb" ) if unfrozen_outsettings.log_output: unfrozen_outsettings.log_output = ( unfrozen_outsettings.log_output + f"_state{endstate}.log" ) else: errmsg = f"Only 'A', 'B', and 'AB' are accepted as endstates. Got {endstate}" raise ValueError(errmsg) # Use the _run_MD method from the PlainMDSimulationUnit # Should in-place modify the simulation PlainMDSimulationUnit._run_MD( simulation=simulation, positions=positions, simulation_settings=settings["equil_simulation_settings"], output_settings=unfrozen_outsettings, temperature=settings["thermo_settings"].temperature, barostat_frequency=settings["integrator_settings"].barostat_frequency, timestep=settings["integrator_settings"].timestep, equil_steps_nvt=equil_steps_nvt, equil_steps_npt=equil_steps_npt, prod_steps=prod_steps_npt, verbose=verbose, shared_basepath=shared_basepath, ) state = simulation.context.getState( getPositions=True, ) equilibrated_positions = state.getPositions(asNumpy=True) box = state.getPeriodicBoxVectors() # cautiously delete out contexts & integrator del simulation.context, integrator return equilibrated_positions, to_openmm(from_openmm(box)) class SepTopUnitMixin: """ Mixin for SepTop ProtocolUnits, defining some of the common methods. """ def _prepare( self, verbose: bool, scratch_basepath: pathlib.Path | None, shared_basepath: pathlib.Path | None, ): """ Set basepaths and do some initial logging. Parameters ---------- verbose : bool Verbose output of the simulation progress. Output is provided via INFO level logging. scratch_basepath : pathlib.Path | None Optional base path to write scratch files to. shared_basepath : pathlib.Path | None Optional base path to write shared files to. """ self.verbose = verbose # set basepaths def _set_optional_path(basepath): if basepath is None: return pathlib.Path(".") return basepath self.scratch_basepath = _set_optional_path(scratch_basepath) self.shared_basepath = _set_optional_path(shared_basepath) @abc.abstractmethod def _get_settings(self) -> dict[str, SettingsBaseModel]: """ Get a dictionary with the following entries: * forcefield_settings : OpenMMSystemGeneratorFFSettings * thermo_settings : ThermoSettings * solvation_settings : BaseSolvationSettings * alchemical_settings : AlchemicalSettings * lambda_settings : LambdaSettings * engine_settings : OpenMMEngineSettings * integrator_settings : IntegratorSettings * equil_simulation_settings : MDSimulationSettings * equil_output_settings : MDOutputSettings * simulation_settings : MultiStateSimulationSettings * output_settings : MultiStateOutputSettings Settings may change depending on what type of simulation you are running. Cherry pick them and return them to be available later on. This method should also add various validation checks as necessary. Note ---- Must be implemented in the child class. """ ... @staticmethod def _verify_execution_environment( setup_outputs: dict[str, Any], ) -> None: """ Check that the Python environment hasn't changed based on the relevant Python library versions stored in the setup outputs. """ try: if ( (gufe.__version__ != setup_outputs["gufe_version"]) or (openfe.__version__ != setup_outputs["openfe_version"]) or (openmm.__version__ != setup_outputs["openmm_version"]) ): errmsg = "Python environment has changed, cannot continue Protocol execution." raise ProtocolUnitExecutionError(errmsg) except KeyError as e: errmsg = "Missing environment information from setup outputs." raise ProtocolUnitExecutionError(errmsg) from e class BaseSepTopSetupUnit(gufe.ProtocolUnit, SepTopUnitMixin): """ Base class for the setup of ligand SepTop RBFE free energy transformations. """ def _get_alchemical_system( self, system: openmm.System, alchem_indices_A: list[int], alchem_indices_B: list[int], alchemical_settings: AlchemicalSettings, ) -> tuple[AbsoluteAlchemicalFactory, openmm.System]: """ Get an alchemically modified system and its associated factory Parameters ---------- system : openmm.System System to alchemically modify. alchem_indices_A : list[int] A list of atom indices for the alchemically modified ligand A in the system. alchem_indices_B : list[int] A list of atom indices for the alchemically modified ligand B in the system. alchemical_settings : AlchemicalSettings Settings controlling how the alchemical system will be built. Returns ------- alchemical_factory : AbsoluteAlchemicalFactory Factory for creating an alchemically modified system. alchemical_system : openmm.System Alchemically modified system """ alchemical_factory = AbsoluteAlchemicalFactory( consistent_exceptions=False, switch_width=1.0 * offunit.angstroms, alchemical_pme_treatment="exact", alchemical_rf_treatment="switched", disable_alchemical_dispersion_correction=alchemical_settings.disable_alchemical_dispersion_correction, split_alchemical_forces=True, ) # Alchemical Region for ligand A alchemical_region_A = AlchemicalRegion( alchemical_atoms=alchem_indices_A, name="A", softcore_alpha=alchemical_settings.softcore_alpha, annihilate_electrostatics=True, annihilate_sterics=alchemical_settings.annihilate_sterics, softcore_a=alchemical_settings.softcore_a, softcore_b=alchemical_settings.softcore_b, softcore_c=alchemical_settings.softcore_c, softcore_beta=0.0, softcore_d=1.0, softcore_e=1.0, softcore_f=2.0, ) # Alchemical Region for ligand B alchemical_region_B = AlchemicalRegion( alchemical_atoms=alchem_indices_B, name="B", softcore_alpha=alchemical_settings.softcore_alpha, annihilate_electrostatics=True, annihilate_sterics=alchemical_settings.annihilate_sterics, softcore_a=alchemical_settings.softcore_a, softcore_b=alchemical_settings.softcore_b, softcore_c=alchemical_settings.softcore_c, softcore_beta=0.0, softcore_d=1.0, softcore_e=1.0, softcore_f=2.0, ) alchemical_system = alchemical_factory.create_alchemical_system( system, [alchemical_region_A, alchemical_region_B] ) return alchemical_factory, alchemical_system @abc.abstractmethod def _get_components( self, ) -> tuple[ dict[str, list[Component]], Optional[gufe.SolventComponent], Optional[gufe.ProteinComponent], dict[SmallMoleculeComponent, OFFMolecule], ]: """ Get the relevant components to create the alchemical system with. Note ---- Must be implemented in the child class. """ ... def _get_system_generator( self, settings: dict[str, SettingsBaseModel], solvent_comp: Optional[SolventComponent], ) -> SystemGenerator: """ Get a system generator through the system creation utilities Parameters ---------- settings : dict[str, SettingsBaseModel] A dictionary of settings object for the unit. solvent_comp : Optional[SolventComponent] The solvent component of this system, if there is one. Returns ------- system_generator : openmmforcefields.generator.SystemGenerator System Generator to parameterise this unit. """ ffcache = settings["output_settings"].forcefield_cache if ffcache is not None: ffcache = self.shared_basepath / ffcache # Block out oechem backend to avoid any issues with # smiles roundtripping between rdkit and oechem with without_oechem_backend(): system_generator = system_creation.get_system_generator( forcefield_settings=settings["forcefield_settings"], integrator_settings=settings["integrator_settings"], thermo_settings=settings["thermo_settings"], cache=ffcache, has_solvent=solvent_comp is not None, ) return system_generator @staticmethod def _assign_partial_charges( partial_charge_settings: OpenFFPartialChargeSettings, smc_components: dict[SmallMoleculeComponent, OFFMolecule], ) -> None: """ Assign partial charges to OFFMolecules inplace. Parameters ---------- charge_settings : OpenFFPartialChargeSettings Settings for controlling how the partial charges are assigned. smc_components : dict[SmallMoleculeComponent, openff.toolkit.Molecule] Dictionary of OpenFF Molecules to add, keyed by SmallMoleculeComponent. """ for mol in smc_components.values(): charge_generation.assign_offmol_partial_charges( offmol=mol, overwrite=False, method=partial_charge_settings.partial_charge_method, toolkit_backend=partial_charge_settings.off_toolkit_backend, generate_n_conformers=partial_charge_settings.number_of_conformers, nagl_model=partial_charge_settings.nagl_model, ) def _get_modeller( self, protein_component: Optional[ProteinComponent], solvent_component: SolventComponent, smc_components: dict[SmallMoleculeComponent, OFFMolecule], system_generator: SystemGenerator, solvation_settings: BaseSolvationSettings, ) -> tuple[openmm.app.Modeller, dict[Component, npt.NDArray]]: """ Get an OpenMM Modeller object and a list of residue indices for each component in the system. Parameters ---------- protein_component : Optional[ProteinComponent] Protein Component, if it exists. solvent_component : SolventComponent Solvent Component. smc_components : dict[SmallMoleculeComponent, openff.toolkit.Molecule] Dictionary of OpenFF Molecules to add, keyed by SmallMoleculeComponent. system_generator : openmmforcefields.generator.SystemGenerator System Generator to parameterise this unit. partial_charge_settings : BasePartialChargeSettings Settings detailing how to assign partial charges to the SMCs of the system. solvation_settings : BaseSolvationSettings Settings detailing how to solvate the system. Returns ------- system_modeller : openmm.app.Modeller OpenMM Modeller object generated from ProteinComponent and OpenFF Molecules. comp_resids : dict[Component, npt.NDArray] Dictionary of residue indices for each component in system. """ if self.verbose: self.logger.info("Parameterizing molecules") # TODO: guard the following from non-RDKit backends # force the creation of parameters for the small molecules # this is necessary because we need to have the FF generated ahead # of solvating the system. # Block out oechem backend to avoid any issues with # smiles roundtripping between rdkit and oechem with without_oechem_backend(): for mol in smc_components.values(): system_generator.create_system(mol.to_topology().to_openmm(), molecules=[mol]) # get OpenMM modeller + dictionary of resids for each component system_modeller, comp_resids = system_creation.get_omm_modeller( protein_comp=protein_component, solvent_comp=solvent_component, small_mols=smc_components, omm_forcefield=system_generator.forcefield, solvent_settings=solvation_settings, ) return system_modeller, comp_resids def _get_omm_objects( self, system_modeller: openmm.app.Modeller, system_generator: SystemGenerator, smc_components: list[OFFMolecule], ) -> tuple[openmm.app.Topology, openmm.unit.Quantity, openmm.System]: """ Get the OpenMM Topology, Positions and System of the parameterised system. Parameters ---------- system_modeller : openmm.app.Modeller OpenMM Modeller object representing the system to be parametrized. system_generator : SystemGenerator The SystemGenerator object to create a System with. smc_components : list[openff.toolkit.Molecule] A list of openff Molecules to add to the system. Returns ------- topology : openmm.app.Topology Topology object describing the parameterized system system : openmm.System An OpenMM System of the alchemical system. positions : openmm.unit.Quantity Positions of the system. """ topology = system_modeller.getTopology() # roundtrip positions to remove vec3 issues positions = to_openmm(from_openmm(system_modeller.getPositions())) # Block out oechem backend to avoid any issues with # smiles roundtripping between rdkit and oechem with without_oechem_backend(): system = system_generator.create_system( system_modeller.topology, molecules=smc_components, ) return topology, system, positions @staticmethod def _get_atom_indices( omm_topology: openmm.app.Topology, comp_resids: dict[Component, npt.NDArray], ) -> dict[Component, list]: """ Get all the atom indices for each component in the system, based on the dictionary of residue indices for each component. Parameters ---------- omm_topology: openmm.app.Topology OpenMM Topology object with the full system. comp_resids: dict[Component, npt.NDArray] Dictionary of the components in the topology with their residue indices. Returns ------- comp_atomids: dict[Component, list] A dictionary of atom indices for each component in the System. """ comp_atomids = {} for key, values in comp_resids.items(): atom_indices = [] for residue in omm_topology.residues(): if residue.index in values: atom_indices.extend([atom.index for atom in residue.atoms()]) comp_atomids[key] = atom_indices return comp_atomids @staticmethod def get_smc_comps( alchem_comps: dict[str, list[Component]], smc_comps: dict[SmallMoleculeComponent, OFFMolecule], ) -> tuple[ dict[SmallMoleculeComponent, OFFMolecule], dict[SmallMoleculeComponent, OFFMolecule], dict[SmallMoleculeComponent, OFFMolecule], ]: # Get smcs for the different states and the common smcs smc_off_A = {m: m.to_openff() for m in alchem_comps["stateA"]} smc_off_B = {m: m.to_openff() for m in alchem_comps["stateB"]} # Common smcs could e.g. be cofactors smc_off_both = { m: m.to_openff() for m in smc_comps if (m not in alchem_comps["stateA"] and m not in alchem_comps["stateB"]) } smc_comps_A = smc_off_A | smc_off_both smc_comps_B = smc_off_B | smc_off_both smc_comps_AB = smc_off_A | smc_off_B | smc_off_both return smc_comps_A, smc_comps_B, smc_comps_AB def get_system( self, solv_comp: SolventComponent, prot_comp: ProteinComponent, smc_comp: dict[SmallMoleculeComponent, OFFMolecule], settings: dict[str, SettingsBaseModel], ): """ Creates an OpenMM system, topology, positions, modeller and also residue IDs of the different components Parameters ---------- solv_comp: SolventComponent prot_comp: Optional[ProteinComponent] smc_comp: dict[SmallMoleculeComponent,OFFMolecule] settings: dict[str, SettingsBaseModel] A dictionary of settings object for the unit. Returns ------- omm_system: openmm.app.System omm_topology: openmm.app.Topology positions: openmm.unit.Quantity system_modeller: openmm.app.Modeller comp_resids: dict[Component, npt.NDArray] A dictionary of residues for each component in the System. """ # Get system generator system_generator = self._get_system_generator(settings, solv_comp) # Get modeller system_modeller, comp_resids = self._get_modeller( prot_comp, solv_comp, smc_comp, system_generator, settings["solvation_settings"], ) # Get OpenMM topology, positions and system omm_topology, omm_system, positions = self._get_omm_objects( system_modeller, system_generator, list(smc_comp.values()) ) return omm_system, omm_topology, positions, system_modeller, comp_resids @staticmethod def _subsample_topology( topology: openmm.app.Topology, positions: openmm.unit.Quantity, output_selection: str, output_file: pathlib.Path, ) -> npt.NDArray: """ Subsample the system based on user-selected output selection and write the subsampled topology to a PDB file. Parameters ---------- topology : openmm.app.Topology The system topology to subsample. positions : openmm.unit.Quantity The system positions. output_selection : str An MDTraj selection string to subsample the topology with. output_file : pathlib.Path Path to the file to write the PDB to. Returns ------- selection_indices : npt.NDArray The indices of the subselected system. """ traj = mdtraj_from_openmm(topology, positions) selection_indices = traj.topology.select(output_selection) # Write out the subselected structure to PDB if not empty if len(selection_indices) > 0: sub_traj = traj.atom_slice(selection_indices) sub_traj.save_pdb(output_file) return selection_indices def _execute( self, ctx: gufe.Context, **kwargs, ) -> dict[str, Any]: log_system_probe(logging.INFO, paths=[ctx.scratch]) outputs = self.run(scratch_basepath=ctx.scratch, shared_basepath=ctx.shared) return { "repeat_id": self._inputs["repeat_id"], "generation": self._inputs["generation"], "simtype": self.simtype, "openmm_version": openmm.__version__, "openfe_version": openfe.__version__, "gufe_version": gufe.__version__, **outputs, } class BaseSepTopRunUnit(gufe.ProtocolUnit, SepTopUnitMixin): """ Base class for running ligand SepTop RBFE free energy transformations. """ @staticmethod def _check_restart(output_settings: SettingsBaseModel, shared_path: pathlib.Path): """ Check if we are doing a restart. Parameters ---------- output_settings : SettingsBaseModel The simulation output settings shared_path : pathlib.Path The shared directory where we should be looking for existing files. Raises ------ IOError If one of the trajectory or checkpoint files are present without the other. Notes ----- For now this just checks if the netcdf files are present in the shared directory but in the future this may expand depending on how warehouse works. """ trajectory = shared_path / output_settings.output_filename checkpoint = shared_path / output_settings.checkpoint_storage_filename if trajectory.is_file() and checkpoint.is_file(): return True elif trajectory.is_file() ^ checkpoint.is_file(): if trajectory.is_file(): errmsg = "the trajectory file is present but not the checkpoint file. " else: errmsg = "the checkpoint file is present but not the trajectory file. " errmsg = ( "Attempting to restart but " + errmsg + "This should not happen under normal circumstances." ) raise IOError(errmsg) else: return False @abc.abstractmethod def _get_components( self, ) -> tuple[ dict[str, list[Component]], Optional[gufe.SolventComponent], Optional[gufe.ProteinComponent], dict[SmallMoleculeComponent, OFFMolecule], ]: """ Get the relevant components to create the alchemical system with. Note ---- Must be implemented in the child class. """ ... @abc.abstractmethod def _get_lambda_schedule( self, settings: dict[str, SettingsBaseModel] ) -> dict[str, list[float]]: """ Create the lambda schedule Parameters ---------- settings : dict[str, SettingsBaseModel] Settings for the unit. Returns ------- lambdas : dict[str, list[float]] Note ---- Must be implemented in the child class. """ ... def _get_states( self, alchemical_system: openmm.System, positions: openmm.unit.Quantity, box_vectors: Optional[openmm.unit.Quantity], settings: dict[str, SettingsBaseModel], lambdas: dict[str, list[float]], solvent_comp: Optional[SolventComponent], ) -> tuple[list[SamplerState], list[ThermodynamicState]]: """ Get a list of sampler and thermodynmic states from an input alchemical system. Parameters ---------- alchemical_system : openmm.System Alchemical system to get states for. positions : openmm.unit.Quantity Positions of the alchemical system. box_vectors : Optional[openmm.unit.Quantity] Box vectors of the alchemical system. settings : dict[str, SettingsBaseModel] A dictionary of settings for the protocol unit. lambdas : dict[str, list[float]] A dictionary of lambda scales. solvent_comp : Optional[SolventComponent] The solvent component of the system, if there is one. Returns ------- sampler_states : list[SamplerState] A list of SamplerStates for each replica in the system. cmp_states : list[ThermodynamicState] A list of ThermodynamicState for each replica in the system. """ alchemical_state = SepTopParameterState.from_system(alchemical_system) # Set up the system constants temperature = settings["thermo_settings"].temperature pressure = settings["thermo_settings"].pressure constants = dict() constants["temperature"] = ensure_quantity(temperature, "openmm") if solvent_comp is not None: constants["pressure"] = ensure_quantity(pressure, "openmm") cmp_states = create_thermodynamic_state_protocol( alchemical_system, protocol=lambdas, constants=constants, composable_states=[alchemical_state], ) sampler_state = SamplerState(positions=positions) if alchemical_system.usesPeriodicBoundaryConditions(): sampler_state.box_vectors = box_vectors sampler_states = [sampler_state for _ in cmp_states] return sampler_states, cmp_states @staticmethod def _get_integrator( integrator_settings: IntegratorSettings, simulation_settings: MultiStateSimulationSettings, system: openmm.System, ) -> openmmtools.mcmc.LangevinDynamicsMove: """ Return a LangevinDynamicsMove integrator Parameters ---------- integrator_settings : IntegratorSettings Settings controlling the Langevin integrator. simulation_settings : MultiStateSimulationSettings Settings controlling the simulation. system: openmm.System The OpenMM System being simulated. Returns ------- integrator : openmmtools.mcmc.LangevinDynamicsMove A configured integrator object. """ steps_per_iteration = settings_validation.convert_steps_per_iteration( simulation_settings, integrator_settings ) integrator = openmmtools.mcmc.LangevinDynamicsMove( timestep=to_openmm(integrator_settings.timestep), collision_rate=to_openmm(integrator_settings.langevin_collision_rate), n_steps=steps_per_iteration, reassign_velocities=integrator_settings.reassign_velocities, n_restart_attempts=integrator_settings.n_restart_attempts, constraint_tolerance=integrator_settings.constraint_tolerance, ) # Validate for known issue when dealing with virtual sites # and mutltistate simulations if not integrator_settings.reassign_velocities: for particle_idx in range(system.getNumParticles()): if system.isVirtualSite(particle_idx): errmsg = ( "Simulations with virtual sites without velocity " "reassignments are unstable with MCMC integrators. " "You can set `reassign_velocities` to ``True`` in the " "`integrator_settings` to avoid this issue." ) raise ValueError(errmsg) return integrator @staticmethod def _get_reporter( storage_path: pathlib.Path, selection_indices: npt.NDArray, simulation_settings: MultiStateSimulationSettings, output_settings: MultiStateOutputSettings, ) -> multistate.MultiStateReporter: """ Get a MultistateReporter for the simulation you are running. Parameters ---------- storage_path : pathlib.Path Path to the directory where files should be written. selection_indices : npt.NDArray Array of system particle indices to subsample the system by. simulation_settings : MultiStateSimulationSettings Multistate simulation control settings, specifically containing the amount of time per state sampling iteration. output_settings: MultiStateOutputSettings Output settings for the simulations Returns ------- reporter : multistate.MultiStateReporter The reporter for the simulation. Notes ----- All this does is create the reporter, it works for both new reporters and if we are doing a restart. """ # Define the trajectory & checkpoint files nc = storage_path / output_settings.output_filename # The checkpoint file in openmmtools is taken as the file relative # to the location of the nc file, so you only want the filename chk = output_settings.checkpoint_storage_filename if output_settings.positions_write_frequency is not None: pos_interval = settings_validation.divmod_time_and_check( numerator=output_settings.positions_write_frequency, denominator=simulation_settings.time_per_iteration, numerator_name="output settings' position_write_frequency", denominator_name="simulation settings' time_per_iteration", ) else: pos_interval = 0 if output_settings.velocities_write_frequency is not None: vel_interval = settings_validation.divmod_time_and_check( numerator=output_settings.velocities_write_frequency, denominator=simulation_settings.time_per_iteration, numerator_name="output settings' velocity_write_frequency", denominator_name="simulation settings' time_per_iteration", ) else: vel_interval = 0 chk_intervals = settings_validation.convert_checkpoint_interval_to_iterations( checkpoint_interval=output_settings.checkpoint_interval, time_per_iteration=simulation_settings.time_per_iteration, ) return multistate.MultiStateReporter( storage=nc, analysis_particle_indices=selection_indices, checkpoint_interval=chk_intervals, checkpoint_storage=chk, position_interval=pos_interval, velocity_interval=vel_interval, ) @staticmethod def _get_sampler( integrator: openmmtools.mcmc.LangevinDynamicsMove, reporter: openmmtools.multistate.MultiStateReporter, simulation_settings: MultiStateSimulationSettings, thermodynamic_settings: ThermoSettings, compound_states: list[ThermodynamicState], sampler_states: list[SamplerState], platform: openmm.Platform, restart: bool, ) -> multistate.MultiStateSampler: """ Get a sampler based on the equilibrium sampling method requested. Parameters ---------- integrator : openmmtools.mcmc.LangevinDynamicsMove The simulation integrator. reporter : openmmtools.multistate.MultiStateReporter The reporter to hook up to the sampler. simulation_settings : MultiStateSimulationSettings Settings for the alchemical sampler. thermodynamic_settings : ThermoSettings Thermodynamic settings compound_states : list[ThermodynamicState] A list of thermodynamic states to sample. sampler_states : list[SamplerState] A list of sampler states. platform : openmm.Platform The compute platform to use. restart : bool If we are restarting the simulation. Returns ------- sampler : multistate.MultistateSampler A sampler configured for the chosen sampling method. """ _SAMPLERS = { "repex": multistate.ReplicaExchangeSampler, "sams": multistate.SAMSSampler, "independent": multistate.MultiStateSampler, } sampler_method = simulation_settings.sampler_method.lower() try: sampler_class = _SAMPLERS[sampler_method] except KeyError: errmsg = f"Unknown sampler {sampler_method}" raise AttributeError(errmsg) # Get the real time analysis values to use rta_its, rta_min_its = settings_validation.convert_real_time_analysis_iterations( simulation_settings=simulation_settings, ) # Get the number of production iterations to run for steps_per_iteration = integrator.n_steps timestep = from_openmm(integrator.timestep) number_of_iterations = int( settings_validation.get_simsteps( sim_length=simulation_settings.production_length, timestep=timestep, mc_steps=steps_per_iteration, ) / steps_per_iteration ) # convert early_termination_target_error from kcal/mol to kT early_termination_target_error = ( settings_validation.convert_target_error_from_kcal_per_mole_to_kT( thermodynamic_settings.temperature, simulation_settings.early_termination_target_error, ) ) sampler_kwargs = { "mcmc_moves": integrator, "online_analysis_interval": rta_its, "online_analysis_target_error": early_termination_target_error, "online_analysis_minimum_iterations": rta_min_its, "number_of_iterations": number_of_iterations, } if sampler_method == "sams": sampler_kwargs |= { "flatness_criteria": simulation_settings.sams_flatness_criteria, "gamma0": simulation_settings.sams_gamma0, } if sampler_method == "repex": sampler_kwargs |= { "replica_mixing_scheme": "swap-all", } if restart: sampler = sampler_class.from_storage(reporter) # We do some checks to make sure we are running the same system # including ensuring that we have the same thermodynamic parameters and # that the lambda schedule is the same. for index, thermostate in enumerate(sampler._thermodynamic_states): system_validation.assert_multistate_system_equality( ref_system=compound_states[index].get_system(remove_thermostat=True), stored_system=thermostate.get_system(remove_thermostat=True), ) # Loop over each composable state (e.g. GlobalParameterState object) # get the parameters and check that the values are the same. for composable_state in compound_states[index]._composable_states: for param in composable_state._parameters: expected = getattr(compound_states[index], param) stored = getattr(thermostate, param) if expected != stored: errmsg = ( f"System parameter {param} in checkpoint does " "not match protocol system, cannot resume" ) raise ValueError(errmsg) if ( (simulation_settings.n_replicas != sampler.n_states) or (simulation_settings.n_replicas != sampler.n_replicas) or (sampler.mcmc_moves[0].n_steps != steps_per_iteration) or (sampler.mcmc_moves[0].timestep != integrator.timestep) ): errmsg = "System in checkpoint does not match protocol system, cannot resume" raise ValueError(errmsg) else: sampler = sampler_class(**sampler_kwargs) sampler.create( thermodynamic_states=compound_states, sampler_states=sampler_states, storage=reporter, ) # Get and set the context caches sampler.energy_context_cache = openmmtools.cache.ContextCache( capacity=None, time_to_live=None, platform=platform, ) sampler.sampler_context_cache = openmmtools.cache.ContextCache( capacity=None, time_to_live=None, platform=platform, ) return sampler def _run_simulation( self, sampler: multistate.MultiStateSampler, reporter: multistate.MultiStateReporter, settings: dict[str, SettingsBaseModel], dry: bool, ): """ Run the simulation. Parameters ---------- sampler : multistate.MultiStateSampler The sampler associated with the simulation to run. reporter : multistate.MultiStateReporter The reporter associated with the sampler. settings : dict[str, SettingsBaseModel] The dictionary of settings for the protocol. dry : bool Whether or not to dry run the simulation Returns ------- unit_results_dict : Optional[dict] A dictionary containing all the free energy results, if not a dry run. """ # Get the relevant simulation steps mc_steps = settings_validation.convert_steps_per_iteration( simulation_settings=settings["simulation_settings"], integrator_settings=settings["integrator_settings"], ) equil_steps = settings_validation.get_simsteps( sim_length=settings["simulation_settings"].equilibration_length, timestep=settings["integrator_settings"].timestep, mc_steps=mc_steps, ) prod_steps = settings_validation.get_simsteps( sim_length=settings["simulation_settings"].production_length, timestep=settings["integrator_settings"].timestep, mc_steps=mc_steps, ) if not dry: # pragma: no-cover if sampler._iteration == 0: # minimize if self.verbose: self.logger.info("minimizing systems") sampler.minimize(max_iterations=settings["simulation_settings"].minimization_steps) # equilibrate if self.verbose: self.logger.info("equilibrating systems") sampler.equilibrate(int(equil_steps / mc_steps)) # At this point we are ready for production if self.verbose: self.logger.info("running production phase") # We use `run` so that we're limited by the number of iterations # we passed when we built the sampler. sampler.run(n_iterations=int(prod_steps / mc_steps) - sampler._iteration) if self.verbose: self.logger.info("production phase complete") else: # close reporter when you're done, prevent file handle clashes reporter.close() # clean up the reporter file fns = [ self.shared_basepath / settings["output_settings"].output_filename, self.shared_basepath / settings["output_settings"].checkpoint_storage_filename, ] for fn in fns: fn.unlink() def run( self, system: openmm.System, pdb_file: openmm.app.pdbfile.PDBFile, selection_indices: npt.NDArray, dry: bool = False, verbose: bool = True, scratch_basepath: pathlib.Path | None = None, shared_basepath: pathlib.Path | None = None, ) -> dict[str, Any]: """ Run the simulation part of the SepTop protocol. Parameters ---------- system: openmm.System System used for the SepTop calculation. pdb_file: openmm.app.pdbfile.PDBFile OpenMM PDBFile object representing the SepTop System. selection_indices: npt.NDArray The indices of the particles to output in the trajectory. dry: bool Do a dry run of the calculation, creating all necessary alchemical system components (topology, system, sampler, etc...) but without running the simulation, default False verbose: bool Verbose output of the simulation progress. Output is provided via INFO level logging, default True scratch_basepath : pathlib.Path | None Path to the scratch (temporary) directory space. shared_basepath : pathlib.Path | None Path to the shared (persistent) directory space. Returns ------- dict: dict[str, Any] Dictionary of the outputs created in the basepath directory (e.g. path to the simulation .nc file, checkpoint file) or the sampler if ``dry==True``. """ # 0. General preparation tasks self._prepare(verbose, scratch_basepath, shared_basepath) if self.verbose: self.logger.info("Running the SepTop simulation.") # Get settings, components, and positions settings = self._get_settings() alchem_comps, solv_comp, prot_comp, smc_comps = self._get_components() positions = pdb_file.getPositions(asNumpy=True) # Check for a restart self.restart = self._check_restart( output_settings=settings["output_settings"], shared_path=self.shared_basepath, ) # Get the compute platform platform = omm_compute.get_openmm_platform( platform_name=settings["engine_settings"].compute_platform, gpu_device_index=settings["engine_settings"].gpu_device_index, restrict_cpu_count=False, ) # Check that the restraints are correctly applied by running a short equilibration if not self.restart: equil_positions, box_AB = _pre_equilibrate( system=system, topology=pdb_file.topology, positions=positions, settings=settings, endstate="AB", dry=dry, shared_basepath=self.shared_basepath, platform=platform, verbose=self.verbose, logger=self.logger, ) else: # If we are doing a restart, we will be using the positions # in the existing checkpoint file and equil_positions is purely # used to create the sampler & compound states (only used for # checking the sampler being created in restarts). # For the sake of simplicity, we assign equil_positions to # the PDB positions and box_AB to the system vectors equil_positions = positions box_AB = system.getDefaultPeriodicBoxVectors() # Get the lambda schedule lambdas = self._get_lambda_schedule(settings) # Get compound and sampler states sampler_states, cmp_states = self._get_states( alchemical_system=system, positions=equil_positions, box_vectors=box_AB, settings=settings, lambdas=lambdas, solvent_comp=solv_comp, ) # Get the integrator integrator = self._get_integrator( integrator_settings=settings["integrator_settings"], simulation_settings=settings["simulation_settings"], system=system, ) # Wrap in try/finally to avoid memory leak issues try: # Get the reporter reporter = self._get_reporter( storage_path=self.shared_basepath, selection_indices=selection_indices, simulation_settings=settings["simulation_settings"], output_settings=settings["output_settings"], ) # Get the sampler sampler = self._get_sampler( integrator=integrator, reporter=reporter, simulation_settings=settings["simulation_settings"], thermodynamic_settings=settings["thermo_settings"], compound_states=cmp_states, sampler_states=sampler_states, platform=platform, restart=self.restart, ) # 8. Run simulation self._run_simulation( sampler, reporter, settings, dry, ) finally: # Have to wrap this in a try/except, because we might # be in a situatino where the reporter and sampler weren't created try: # Order is reporter, contexts, sampler, integrator reporter.close() # clear GPU context # Note: use cache.empty() when openmmtools #690 is resolved for context in list(sampler.energy_context_cache._lru._data.keys()): del sampler.energy_context_cache._lru._data[context] for context in list(sampler.sampler_context_cache._lru._data.keys()): del sampler.sampler_context_cache._lru._data[context] # cautiously clear out the global context cache too for context in list(openmmtools.cache.global_context_cache._lru._data.keys()): del openmmtools.cache.global_context_cache._lru._data[context] del sampler.sampler_context_cache, sampler.energy_context_cache # Keep these around in a dry run so we can inspect things if not dry: # At this point we know the sampler exists, so we del the integrator # first since it's associated with the sampler del integrator, sampler except UnboundLocalError: pass if not dry: nc = self.shared_basepath / settings["output_settings"].output_filename chk = self.shared_basepath / settings["output_settings"].checkpoint_storage_filename return { "trajectory": nc, "checkpoint": chk, } else: return { "sampler": sampler, "integrator": integrator, "equil_positions": equil_positions, } def _execute( self, ctx: gufe.Context, *, setup, **kwargs, ) -> dict[str, Any]: log_system_probe(logging.INFO, paths=[ctx.scratch]) # Ensure the environment hasn't changed self._verify_execution_environment(setup.outputs) # Get the relevant inputs for running the unit system = deserialize(setup.outputs["system"]) pdb_file = openmm.app.pdbfile.PDBFile(str(setup.outputs["topology"])) selection_indices = setup.outputs["selection_indices"] outputs = self.run( system=system, pdb_file=pdb_file, selection_indices=selection_indices, scratch_basepath=ctx.scratch, shared_basepath=ctx.shared, ) return { "repeat_id": self._inputs["repeat_id"], "generation": self._inputs["generation"], "simtype": self.simtype, **outputs, } class BaseSepTopAnalysisUnit(gufe.ProtocolUnit, SepTopUnitMixin): @staticmethod def _analyze_multistate_energies( trajectory: pathlib.Path, checkpoint: pathlib.Path, sampler_method: str, output_directory: pathlib.Path, dry: bool, ): """ Analyze multistate energies and generate plots. Parameters ---------- trajectory : pathlib.Path Path to the NetCDF trajectory file. checkpoint : pathlib.Path The name of the checkpoint file. Note this is relative in path to the trajectory file. sampler_method : str The multistate sampler method used. output_directory : pathlib.Path The path to where plots will be written. dry : bool Whether or not we are running a dry run. """ reporter = multistate.MultiStateReporter( storage=trajectory, # Note: openmmtools only wants the name of the checkpoint # file, it assumes it to be in the same place as the trajectory checkpoint_storage=checkpoint.name, open_mode="r", ) analyzer = multistate_analysis.MultistateEquilFEAnalysis( reporter=reporter, sampling_method=sampler_method, result_units=offunit.kilocalorie_per_mole, ) # Only create plots when not doing a dry run if not dry: analyzer.plot(filepath=output_directory, filename_prefix="") analyzer.close() reporter.close() return analyzer.unit_results_dict def run( self, *, trajectory: pathlib.Path, checkpoint: pathlib.Path, dry: bool = False, verbose: bool = True, scratch_basepath: pathlib.Path | None = None, shared_basepath: pathlib.Path | None = None, ) -> dict[str, Any]: """Analyze the multistate simulation. Parameters ---------- trajectory : pathlib.Path Path to the MultiStateReporter generated NetCDF file. checkpoint : pathlib.Path Path to the checkpoint file generated by MultiStateReporter. dry : bool Do a dry run of the calculation, creating all necessary hybrid system components (topology, system, sampler, etc...) but without running the simulation. verbose : bool Verbose output of the simulation progress. Output is provided via INFO level logging. scratch_basepath: pathlib.Path | None Where to store temporary files, defaults to current working directory shared_basepath : pathlib.Path | None Where to run the calculation, defaults to current working directory Returns ------- dict Outputs created in the basepath directory or the debug objects (i.e. sampler) if ``dry==True``. """ # Prepare paths & verbosity self._prepare(verbose, scratch_basepath, shared_basepath) if self.verbose: self.logger.info("Starting simulation analysis unit") # Get the settings settings = self._get_settings() # Energies analysis if verbose: self.logger.info("Analyzing energies") energy_analysis = self._analyze_multistate_energies( trajectory=trajectory, checkpoint=checkpoint, sampler_method=settings["simulation_settings"].sampler_method.lower(), output_directory=self.shared_basepath, dry=dry, ) return energy_analysis def _execute( self, ctx: gufe.Context, *, setup, simulation, **inputs, ) -> dict[str, Any]: log_system_probe(logging.INFO, paths=[ctx.scratch]) # Ensure the environment hasn't changed self._verify_execution_environment(setup.outputs) # Get the relevant inputs for running the unit trajectory = simulation.outputs["trajectory"] checkpoint = simulation.outputs["checkpoint"] outputs = self.run( trajectory=trajectory, checkpoint=checkpoint, scratch_basepath=ctx.scratch, shared_basepath=ctx.shared, ) # We re-include things here to make life easier when gathering results if self.simtype == "complex": previous_outputs = { "standard_state_correction_A": setup.outputs["standard_state_correction_A"], "standard_state_correction_B": setup.outputs["standard_state_correction_B"], "restraint_geometry_A": setup.outputs["restraint_geometry_A"], "restraint_geometry_B": setup.outputs["restraint_geometry_B"], } else: previous_outputs = { "standard_state_correction": setup.outputs["standard_state_correction"] } previous_outputs["subsampled_pdb_structure"] = setup.outputs["subsampled_pdb_structure"] previous_outputs["selection_indices"] = setup.outputs["selection_indices"] previous_outputs["trajectory"] = trajectory previous_outputs["checkpoint"] = checkpoint return { "repeat_id": self._inputs["repeat_id"], "generation": self._inputs["generation"], "simtype": self.simtype, **outputs, **previous_outputs, } ================================================ FILE: src/openfe/protocols/openmm_septop/equil_septop_method.py ================================================ # This code is part of OpenFE and is licensed under the MIT license. # For details, see https://github.com/OpenFreeEnergy/openfe """OpenMM Equilibrium SepTop RBFE Protocol --- :mod:`openfe.protocols.openmm_septop.equil_septop_method` ======================================================================================================== This module implements the necessary methodology tooling to run a Separated Topologies RBFE calculation using OpenMM tools and one of the following alchemical sampling methods: * Hamiltonian Replica Exchange * Self-adjusted mixture sampling * Independent window sampling Current limitations ------------------- * Transformations that involve net charge changes are currently not supported. The ligands must have the same net charge. * Only small molecules are allowed to act as alchemical molecules. Alchemically changing protein or solvent components would induce perturbations which are too large to be handled by this Protocol. Acknowledgements ---------------- This Protocol is based on and inspired by the SepTop implementation from the Mobleylab (https://github.com/MobleyLab/SeparatedTopologies) as well as femto (https://github.com/Psivant/femto). """ from __future__ import annotations import logging import uuid import warnings from collections import defaultdict from typing import Any, Iterable, Optional, Union import gufe from gufe import ( ChemicalSystem, ProteinComponent, ProteinMembraneComponent, SmallMoleculeComponent, SolvatedPDBComponent, SolventComponent, settings, ) from gufe.components import Component from openff.units import unit as offunit from rdkit import Chem from openfe.due import Doi, due from openfe.protocols.openmm_septop.equil_septop_settings import ( AlchemicalSettings, IntegratorSettings, LambdaSettings, MDSimulationSettings, MultiStateOutputSettings, MultiStateSimulationSettings, OpenFFPartialChargeSettings, OpenMMEngineSettings, OpenMMSolvationSettings, SepTopEquilOutputSettings, SepTopSettings, SettingsBaseModel, ) from ..openmm_utils import settings_validation, system_validation from ..restraint_utils.settings import ( BoreschRestraintSettings, DistanceRestraintSettings, ) from .septop_protocol_results import SepTopProtocolResult from .septop_units import ( SepTopComplexAnalysisUnit, SepTopComplexRunUnit, SepTopComplexSetupUnit, SepTopSolventAnalysisUnit, SepTopSolventRunUnit, SepTopSolventSetupUnit, ) due.cite( Doi("10.1021/acs.jctc.3c00282"), description="Separated Topologies method", path="openfe.protocols.openmm_septop.equil_septop_method", cite_module=True, ) due.cite( Doi("10.5281/zenodo.596622"), description="OpenMMTools", path="openfe.protocols.openmm_septop.equil_septop_method", cite_module=True, ) due.cite( Doi("10.1371/journal.pcbi.1005659"), description="OpenMM", path="openfe.protocols.openmm_septop.equil_septop_method", cite_module=True, ) logger = logging.getLogger(__name__) def _check_alchemical_charge_difference( ligandA: SmallMoleculeComponent, ligandB: SmallMoleculeComponent, ): """ Checks and returns the difference in formal charge between state A and B. Raises ------ ValueError * If a change in net charge is detected. Parameters ---------- ligandA: SmallMoleculeComponent ligandB: SmallMoleculeComponent """ chg_A = Chem.rdmolops.GetFormalCharge(ligandA.to_rdkit()) chg_B = Chem.rdmolops.GetFormalCharge(ligandB.to_rdkit()) difference = chg_A - chg_B if abs(difference) != 0: errmsg = ( f"A charge difference of {difference} is observed " "between the end states. Unfortunately this protocol " "currently does not support net charge changes." ) raise ValueError(errmsg) class SepTopProtocol(gufe.Protocol): """ SepTop RBFE calculations using OpenMM and OpenMMTools. See Also -------- :mod:`openfe.protocols` :class:`openfe.protocols.openmm_septop.SepTopSettings` :class:`openfe.protocols.openmm_septop.SepTopProtocolResult` :class:`openfe.protocols.openmm_septop.SepTopComplexSetupUnit` :class:`openfe.protocols.openmm_septop.SepTopComplexRunUnit` :class:`openfe.protocols.openmm_septop.SepTopSolventSetupUnit` :class:`openfe.protocols.openmm_septop.SepTopSolventRunUnit` """ result_cls = SepTopProtocolResult _settings_cls = SepTopSettings _settings: SepTopSettings @classmethod def _default_settings(cls): """A dictionary of initial settings for this creating this Protocol These settings are intended as a suitable starting point for creating an instance of this protocol. It is recommended, however that care is taken to inspect and customize these before performing a Protocol. Returns ------- Settings a set of default settings """ return SepTopSettings( protocol_repeats=3, forcefield_settings=settings.OpenMMSystemGeneratorFFSettings(), thermo_settings=settings.ThermoSettings( temperature=298.15 * offunit.kelvin, pressure=1 * offunit.bar, ), alchemical_settings=AlchemicalSettings(), solvent_lambda_settings=LambdaSettings( lambda_elec_A=[ 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.125, 0.25, 0.375, 0.5, 0.625, 0.75, 0.875, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, ], lambda_elec_B=[ 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 0.875, 0.75, 0.625, 0.5, 0.375, 0.25, 0.125, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, ], lambda_vdw_A=[ 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.15, 0.23, 0.3, 0.4, 0.52, 0.64, 0.76, 0.88, 1.0, ], lambda_vdw_B=[ 1.0, 0.85, 0.77, 0.7, 0.6, 0.48, 0.36, 0.24, 0.12, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, ], lambda_restraints_A=[ 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, ], lambda_restraints_B=[ 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, ], ), complex_lambda_settings=LambdaSettings(), partial_charge_settings=OpenFFPartialChargeSettings(), solvent_solvation_settings=OpenMMSolvationSettings(), complex_solvation_settings=OpenMMSolvationSettings( solvent_padding=1.0 * offunit.nanometer, ), engine_settings=OpenMMEngineSettings(), solvent_integrator_settings=IntegratorSettings(), complex_integrator_settings=IntegratorSettings(), solvent_equil_simulation_settings=MDSimulationSettings( equilibration_length_nvt=0.1 * offunit.nanosecond, equilibration_length=0.1 * offunit.nanosecond, production_length=2.0 * offunit.nanosecond, ), solvent_equil_output_settings=SepTopEquilOutputSettings( equil_nvt_structure=None, equil_npt_structure="equil_npt", production_trajectory_filename="equil_npt", log_output="equil_simulation", ), solvent_simulation_settings=MultiStateSimulationSettings( n_replicas=27, minimization_steps=5000, equilibration_length=1.0 * offunit.nanosecond, production_length=10.0 * offunit.nanosecond, ), solvent_output_settings=MultiStateOutputSettings( output_structure="alchemical_system.pdb", output_filename="solvent.nc", checkpoint_storage_filename="solvent_checkpoint.nc", ), complex_equil_simulation_settings=MDSimulationSettings( equilibration_length_nvt=0.1 * offunit.nanosecond, equilibration_length=0.1 * offunit.nanosecond, production_length=2.0 * offunit.nanosecond, ), complex_equil_output_settings=SepTopEquilOutputSettings( equil_nvt_structure=None, equil_npt_structure="equil_npt", production_trajectory_filename="equil_production", log_output="equil_simulation", ), complex_simulation_settings=MultiStateSimulationSettings( n_replicas=19, equilibration_length=1.0 * offunit.nanosecond, production_length=10.0 * offunit.nanosecond, ), complex_output_settings=MultiStateOutputSettings( output_structure="alchemical_system.pdb", output_filename="complex.nc", checkpoint_storage_filename="complex_checkpoint.nc", ), solvent_restraint_settings=DistanceRestraintSettings( spring_constant=1000.0 * offunit.kilojoule_per_mole / offunit.nanometer**2, ), complex_restraint_settings=BoreschRestraintSettings(), ) # fmt: skip @classmethod def _adaptive_settings( cls, stateA: ChemicalSystem, stateB: ChemicalSystem, initial_settings: None | SepTopSettings = None, ) -> SepTopSettings: """ Get the recommended OpenFE settings for this Protocol based on the input states involved in the transformation. These are intended as a suitable starting point, which can be further customized before creating a Protocol. Parameters ---------- stateA : ChemicalSystem The initial state of the transformation. stateB : ChemicalSystem The final state of the transformation. initial_settings : None | SepTopSettings, optional Initial settings to adapt. If None, default settings are used. Returns ------- SepTopSettings The recommended settings for this protocol based on the input states. """ # use initial settings or default settings if initial_settings is not None: protocol_settings = initial_settings.model_copy(deep=True) else: protocol_settings = cls.default_settings() # adapt the barostat based on the ProteinComponent if stateA.contains(ProteinMembraneComponent): protocol_settings.complex_integrator_settings.barostat = "MonteCarloMembraneBarostat" return protocol_settings @staticmethod def _validate_endstates( stateA: ChemicalSystem, stateB: ChemicalSystem, ) -> None: """ A complex relative transformation is defined (in terms of gufe components) as starting from one or more ligands and a protein in solvent and ending up in a state with one ligand that is different. Parameters ---------- stateA : ChemicalSystem The chemical system of end state A stateB : ChemicalSystem The chemical system of end state B Raises ------ ValueError If there is no SolventComponent and no ProteinComponent in either stateA or stateB. If there are no or more than one alchemical components in state A. If there are no or more than one alchemical components in state B. If there are any alchemical components that are not SmallMoleculeComponents. If a change in net charge between the alchemical components is detected. """ # check that there is a protein component if not stateA.contains(ProteinComponent): errmsg = "No ProteinComponent found in stateA" raise ValueError(errmsg) if not stateB.contains(ProteinComponent): errmsg = "No ProteinComponent found in stateB" raise ValueError(errmsg) # check that there is only one protein component system_validation.validate_protein(stateA) system_validation.validate_protein(stateB) # check that there is a SolventComponent if not stateA.contains(SolventComponent): errmsg = "No SolventComponent found in stateA" raise ValueError(errmsg) if not stateB.contains(SolventComponent): errmsg = "No SolventComponent found in stateB" raise ValueError(errmsg) # Check the difference between the endstates diff = stateA.component_diff(stateB) for i, state in enumerate(["stateA", "stateB"]): # Error if there isn't exactly one alchemical component if len(diff[i]) != 1: errmsg = ( "Only one alchemical species is supported. " f"Number of unique components found in {state}: {len(diff[i])}." ) raise ValueError(errmsg) # Error if the component isn't an SMC if not isinstance(diff[i][0], SmallMoleculeComponent): errmsg = ( "Only transforming SmallMoleculeComponents are supported " f"by this Protocol. Found a {type(diff[i][0])}." ) raise ValueError(errmsg) # Raise an error if there is a change in net charge _check_alchemical_charge_difference(diff[0][0], diff[1][0]) @staticmethod def _validate_lambda_schedule( lambda_settings: LambdaSettings, simulation_settings: MultiStateSimulationSettings, ) -> None: """ Checks that the lambda schedule is set up correctly. Parameters ---------- lambda_settings : LambdaSettings the lambda schedule Settings simulation_settings : MultiStateSimulationSettings the settings for either the complex or solvent phase Raises ------ ValueError If the number of lambda windows differs for electrostatics and sterics. If the number of replicas does not match the number of lambda windows. TODO ---- Add a warning if all the lambda restraints are zero? Issue #1945. """ lambda_elec_A = lambda_settings.lambda_elec_A lambda_elec_B = lambda_settings.lambda_elec_B lambda_vdw_A = lambda_settings.lambda_vdw_A lambda_vdw_B = lambda_settings.lambda_vdw_B lambda_restraints_A = lambda_settings.lambda_restraints_A lambda_restraints_B = lambda_settings.lambda_restraints_B n_replicas = simulation_settings.n_replicas # Ensure that all lambda components have equal amount of windows lambda_components = [ lambda_vdw_A, lambda_vdw_B, lambda_elec_A, lambda_elec_B, lambda_restraints_A, lambda_restraints_B, ] lengths = {len(lam) for lam in lambda_components} if len(lengths) != 1: errmsg = ( "Components elec, vdw, and restraints must have equal amount" f" of lambda windows. Got {len(lambda_elec_A)} and " f"{len(lambda_elec_B)} elec lambda windows, " f"{len(lambda_vdw_A)} and {len(lambda_vdw_B)} vdw " f"lambda windows, and {len(lambda_restraints_A)} and " f"{len(lambda_restraints_B)} restraints lambda windows." ) raise ValueError(errmsg) # Ensure that number of overall lambda windows matches number of lambda # windows for individual components if n_replicas != len(lambda_vdw_B): errmsg = ( f"Number of replicas {n_replicas} does not equal the" f" number of lambda windows {len(lambda_vdw_B)}" ) raise ValueError(errmsg) # Check if there are lambda windows with naked charges for state, elec, vdw in ( ("A", lambda_elec_A, lambda_vdw_A), ("B", lambda_elec_B, lambda_vdw_B), ): for idx, (e, v) in enumerate(zip(elec, vdw)): if e < 1 and v == 1: raise ValueError( "There are states along this lambda schedule where " "there are atoms with charges but no LJ interactions: " f"State {state}: lambda {idx}: elec {e} vdW {v}" ) def _validate( self, stateA: ChemicalSystem, stateB: ChemicalSystem, mapping: gufe.ComponentMapping | list[gufe.ComponentMapping] | None, extends: gufe.ProtocolDAGResult | None = None, ) -> None: # Check we're not trying to extend if extends: # This technically should be NotImplementedError # but gufe.Protocol.validate calls `_validate` wrapped # around a try/except for that error type raise ValueError("Can't extend simulations yet") # Check the mappping if mapping is not None: wmsg = "A mapping was passed but is not used by this Protocol" warnings.warn(wmsg) # Validate end states system_validation.validate_chemical_system(stateA) system_validation.validate_chemical_system(stateB) self._validate_endstates(stateA, stateB) # Validate the lambda schedule self._validate_lambda_schedule( self.settings.solvent_lambda_settings, self.settings.solvent_simulation_settings, ) self._validate_lambda_schedule( self.settings.complex_lambda_settings, self.settings.complex_simulation_settings, ) # Check nonbonded and solvent compatibility nonbonded_method = self.settings.forcefield_settings.nonbonded_method # Validate solvent component system_validation.validate_solvent(stateA, nonbonded_method) # Validate solvation settings settings_validation.validate_openmm_solvation_settings( self.settings.solvent_solvation_settings ) settings_validation.validate_openmm_solvation_settings( self.settings.complex_solvation_settings ) # Validate the barostat used in combination with the protein component system_validation.validate_barostat( stateA, self.settings.complex_integrator_settings.barostat ) def _create( self, stateA: ChemicalSystem, stateB: ChemicalSystem, mapping: gufe.ComponentMapping | list[gufe.ComponentMapping] | None = None, extends: gufe.ProtocolDAGResult | None = None, ) -> list[gufe.ProtocolUnit]: self.validate(stateA=stateA, stateB=stateB, mapping=mapping, extends=extends) # Get the alchemical components alchem_comps = system_validation.get_alchemical_components( stateA, stateB, ) # Create list units for complex and solvent transforms alchname_A = alchem_comps["stateA"][0].name alchname_B = alchem_comps["stateB"][0].name unit_classes: dict[str, dict[str, type[gufe.ProtocolUnit]]] = { "solvent": { "setup": SepTopSolventSetupUnit, "simulation": SepTopSolventRunUnit, "analysis": SepTopSolventAnalysisUnit, }, "complex": { "setup": SepTopComplexSetupUnit, "simulation": SepTopComplexRunUnit, "analysis": SepTopComplexAnalysisUnit, }, } protocol_units: dict[str, list[gufe.ProtocolUnit]] = {"solvent": [], "complex": []} for i in range(self.settings.protocol_repeats): repeat_id = int(uuid.uuid4()) for phase in ["solvent", "complex"]: setup = unit_classes[phase]["setup"]( protocol=self, stateA=stateA, stateB=stateB, alchemical_components=alchem_comps, generation=0, repeat_id=repeat_id, name=( f"SepTop RBFE Setup, transformation {alchname_A} to " f"{alchname_B}, {phase} leg: repeat {i} generation 0" ), ) simulation = unit_classes[phase]["simulation"]( protocol=self, stateA=stateA, stateB=stateB, alchemical_components=alchem_comps, setup=setup, generation=0, repeat_id=repeat_id, name=( f"SepTop RBFE Run, transformation {alchname_A} to " f"{alchname_B}, {phase} leg: repeat {i} generation 0" ), ) analysis = unit_classes[phase]["analysis"]( protocol=self, setup=setup, simulation=simulation, generation=0, repeat_id=repeat_id, name=( f"SepTop RBFE Analysis, transformation {alchname_A} to " f"{alchname_B}, {phase} leg: repeat {i} generation 0" ), ) protocol_units[phase] += [setup, simulation, analysis] return protocol_units["solvent"] + protocol_units["complex"] def _gather( self, protocol_dag_results: Iterable[gufe.ProtocolDAGResult] ) -> dict[str, dict[str, Any]]: # result units will have a repeat_id and generation # first group according to repeat_id unsorted_solvent_repeats = defaultdict(list) unsorted_complex_repeats = defaultdict(list) for d in protocol_dag_results: pu: gufe.ProtocolUnitResult for pu in d.protocol_unit_results: if ("Analysis" not in pu.name) or (not pu.ok()): continue if pu.outputs["simtype"] == "solvent": unsorted_solvent_repeats[pu.outputs["repeat_id"]].append(pu) else: unsorted_complex_repeats[pu.outputs["repeat_id"]].append(pu) repeats: dict[str, dict[str, list[gufe.ProtocolUnitResult]]] = { "solvent": {}, "complex": {}, } for k, v in unsorted_solvent_repeats.items(): repeats["solvent"][str(k)] = sorted(v, key=lambda x: x.outputs["generation"]) for k, v in unsorted_complex_repeats.items(): repeats["complex"][str(k)] = sorted(v, key=lambda x: x.outputs["generation"]) return repeats ================================================ FILE: src/openfe/protocols/openmm_septop/equil_septop_settings.py ================================================ # This code is part of OpenFE and is licensed under the MIT license. # For details, see https://github.com/OpenFreeEnergy/openfe """Settings class for equilibrium SepTop Protocols using OpenMM + OpenMMTools This module implements the necessary settings necessary to run SepTop RBFE calculations using OpenMM. See Also -------- openfe.protocols.openmm_septop.SepTopProtocol """ from typing import Optional import numpy as np from gufe.settings import ( OpenMMSystemGeneratorFFSettings, SettingsBaseModel, ThermoSettings, ) from gufe.settings.typing import PicosecondQuantity from openff.units import unit as offunit from pydantic import field_validator from openfe.protocols.openmm_afe.equil_afe_settings import AlchemicalSettings from openfe.protocols.openmm_utils.omm_settings import ( IntegratorSettings, MDOutputSettings, MDSimulationSettings, MultiStateOutputSettings, MultiStateSimulationSettings, OpenFFPartialChargeSettings, OpenMMEngineSettings, OpenMMSolvationSettings, ) from openfe.protocols.restraint_utils.settings import BaseRestraintSettings class LambdaSettings(SettingsBaseModel): """Lambda schedule settings. Defines lists of floats to control various aspects of the alchemical transformation. Notes ----- * In all cases a lambda value of 0 defines a fully interacting state A and a non-interacting state B, whilst a value of 1 defines a fully interacting state B and a non-interacting state A. * ``lambda_elec``, `lambda_vdw``, and ``lambda_restraints`` must all be of the same length, defining all the windows of the transformation. """ # fmt: off lambda_elec_A: list[float] = [ 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.25, 0.5, 0.75, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, ] # fmt: on """ List of floats of the lambda values for the electrostatics of ligand A. Zero means fully interacting and 1 means fully decoupled. Length of this list needs to match length of lambda_vdw and lambda_restraints. """ # fmt: off lambda_elec_B: list[float] = [ 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 0.75, 0.5, 0.25, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, ] # fmt: on """ List of floats of the lambda values for the electrostatics of ligand B. Zero means fully interacting and 1 means fully decoupled. Length of this list needs to match length of lambda_vdw and lambda_restraints. """ # fmt: off lambda_vdw_A: list[float] = [ 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.14285714285714285, 0.2857142857142857, 0.42857142857142855, 0.5714285714285714, 0.7142857142857142, 0.8571428571428571, 1.0, ] # fmt: on """ List of floats of lambda values for the van der Waals of ligand A. Zero means fully interacting and 1 means fully decoupled. Length of this list needs to match length of lambda_elec and lambda_restraints. """ # fmt: off lambda_vdw_B: list[float] = [ 1.0, 0.8571428571428572, 0.7142857142857143, 0.5714285714285714, 0.4285714285714286, 0.2857142857142858, 0.1428571428571429, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, ] # fmt: on """ List of floats of lambda values for the van der Waals of ligand B. Zero means fully interacting and 1 means fully decoupled. Length of this list needs to match length of lambda_elec and lambda_restraints. """ # fmt: off lambda_restraints_A: list[float] = [ 0.0, 0.05, 0.1, 0.3, 0.5, 0.75, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, ] # fmt: on """ List of floats of lambda values for the restraints of ligand A. Zero means no restraints are applied and 1 means restraints are fully applied. Length of this list needs to match length of lambda_vdw and lambda_elec. """ # fmt: off lambda_restraints_B: list[float] = [ 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 0.75, 0.5, 0.3, 0.1, 0.05, 0.0, ] # fmt: on """ List of floats of lambda values for the restraints of ligand B. Zero means no restraints are applied and 1 means restraints are fully applied. Length of this list needs to match length of lambda_vdw and lambda_elec. """ @field_validator( "lambda_elec_A", "lambda_elec_B", "lambda_vdw_A", "lambda_vdw_B", "lambda_restraints_A", "lambda_restraints_B", ) def must_be_between_0_and_1(cls, v): for window in v: if not 0 <= window <= 1: errmsg = ( f"Lambda windows must be between 0 and 1, got a window with value {window}." ) raise ValueError(errmsg) return v @field_validator( "lambda_elec_A", "lambda_vdw_A", "lambda_restraints_A", ) def must_be_monotonically_increasing_A(cls, v): difference = np.diff(v) monotonic = np.all(difference >= 0) if not monotonic: errmsg = ( "The lambda schedule for ligand A is not monotonically" f" increasing, got schedule {v}." ) raise ValueError(errmsg) return v @field_validator( "lambda_elec_B", "lambda_vdw_B", "lambda_restraints_B", ) def must_be_monotonically_decreasing_B(cls, v): difference = np.diff(v) monotonic = np.all(difference <= 0) if not monotonic: errmsg = ( "The lambda schedule for ligand B is not monotonically" f" decreasing, got schedule {v}." ) raise ValueError(errmsg) return v class SepTopEquilOutputSettings(MDOutputSettings): # reporter settings output_indices: str = "all" """ Selection string for which part of the system to write coordinates for. The SepTop protocol enforces "all" since the full system output is required in the complex leg. Default "all". """ production_trajectory_filename: Optional[str] = "simulation" """ Basename for the path to the storage file for analysis. The protocol will append a '_stateA.xtc' and a '_stateB.xtc' for the output files of the respective endstates. Default 'simulation'. """ trajectory_write_interval: PicosecondQuantity = 20.0 * offunit.picosecond """ Frequency to write the xtc file. Default 20 * offunit.picosecond. """ preminimized_structure: Optional[str] = "system" """ Basename for the path to the pdb file of the full pre-minimized systems. The protocol will append a '_stateA.pdb' and a '_stateB.pdb' for the output files of the respective endstates. Default 'system'. """ minimized_structure: Optional[str] = "minimized" """ Basename for the path to the pdb file of the systems after minimization. The protocol will append a '_stateA.pdb' and a '_stateB.pdb' for the output files of the respective endstates. Default 'minimized'. """ equil_nvt_structure: Optional[str] = "equil_nvt" """ Basename for the path to the pdb file of the systems after NVT equilibration. The protocol will append a '_stateA' and a '_stateB' for the output files of the respective endstates. Default 'equil_nvt.pdb'. """ equil_npt_structure: Optional[str] = "equil_npt" """ Basename for the path to the pdb file of the systems after NPT equilibration. The protocol will append a '_stateA.pdb' and a '_stateB.pdb' for the output files of the respective endstates. Default 'equil_npt'. """ log_output: Optional[str] = "simulation" """ Basename for the filename for writing the log of the MD simulation, including timesteps, energies, density, etc. The protocol will append a '_stateA.pdb' and a '_stateB.pdb' for the output files of the respective endstates. Default 'simulation'. """ @field_validator("output_indices") def must_be_all(cls, v): if v != "all": errmsg = f"Equilibration simulations need to output the full system, got {v}." raise ValueError(errmsg) return v class SepTopSettings(SettingsBaseModel): """ Configuration object for ``SepTopProtocol``. See Also -------- openfe.protocols.openmm_septop.SepTopProtocol """ protocol_repeats: int """ The number of completely independent repeats of the entire sampling process. The mean of the repeats defines the final estimate of FE difference, while the variance between repeats is used as the uncertainty. """ @field_validator("protocol_repeats") def must_be_positive(cls, v): if v <= 0: errmsg = f"protocol_repeats must be a positive value, got {v}." raise ValueError(errmsg) return v # Inherited things forcefield_settings: OpenMMSystemGeneratorFFSettings """Parameters to set up the force field with OpenMM Force Fields""" thermo_settings: ThermoSettings """Settings for thermodynamic parameters""" solvent_solvation_settings: OpenMMSolvationSettings """Settings for solvating the solvent system.""" complex_solvation_settings: OpenMMSolvationSettings """Settings for solvating the complex system.""" # Alchemical settings alchemical_settings: AlchemicalSettings """ Alchemical protocol settings. """ solvent_lambda_settings: LambdaSettings """ Settings for controlling the lambda schedule for the different components (vdw, elec, restraints) in the solvent. """ complex_lambda_settings: LambdaSettings """ Settings for controlling the lambda schedule for the different components (vdw, elec, restraints) in the complex. """ # MD Engine things engine_settings: OpenMMEngineSettings """ Settings specific to the OpenMM engine, such as the compute platform. """ # Sampling State defining things solvent_integrator_settings: IntegratorSettings """ Settings for controlling the integrator, such as the timestep and barostat settings in the solvent. """ complex_integrator_settings: IntegratorSettings """ Settings for controlling the integrator, such as the timestep and barostat settings in the complex. """ # Simulation run settings complex_equil_simulation_settings: MDSimulationSettings """ Pre-alchemical complex simulation control settings. """ complex_simulation_settings: MultiStateSimulationSettings """ Simulation control settings, including simulation lengths for the complex transformation. """ solvent_equil_simulation_settings: MDSimulationSettings """ Pre-alchemical solvent simulation control settings. """ solvent_simulation_settings: MultiStateSimulationSettings """ Simulation control settings, including simulation lengths for the solvent transformation. """ complex_equil_output_settings: SepTopEquilOutputSettings """ Simulation output settings for the complex non-alchemical equilibration. """ complex_output_settings: MultiStateOutputSettings """ Simulation output settings for the complex transformation. """ solvent_equil_output_settings: SepTopEquilOutputSettings """ Simulation output settings for the solvent non-alchemical equilibration. """ solvent_output_settings: MultiStateOutputSettings """ Simulation output settings for the solvent transformation. """ partial_charge_settings: OpenFFPartialChargeSettings """ Settings for controlling how to assign partial charges, including the partial charge assignment method, and the number of conformers used to generate the partial charges. """ solvent_restraint_settings: BaseRestraintSettings """ Settings for the harmonic restraint in the solvent """ complex_restraint_settings: BaseRestraintSettings """ Settings for the Boresch restraints in the complex """ ================================================ FILE: src/openfe/protocols/openmm_septop/septop_protocol_results.py ================================================ # This code is part of OpenFE and is licensed under the MIT license. # For details, see https://github.com/OpenFreeEnergy/openfe """Result class for the SepTop Protocol :class:`openfe.protocols.openmm_septop.SepTopProtocolResult` ==================================================================================================== This module implement a :class:`gufe.ProtocolResult` class to contain the results of a :class:`openfe.protocols.openmm_septop.SepTopProtocol` free energy simulation. """ from __future__ import annotations import itertools import logging import pathlib import warnings from typing import Any, Optional, Union import gufe import numpy as np import numpy.typing as npt from openff.units import Quantity from openff.units import unit as offunit from openmmtools import multistate from openfe.protocols.restraint_utils.geometry.boresch import BoreschRestraintGeometry logger = logging.getLogger(__name__) class SepTopProtocolResult(gufe.ProtocolResult): """Dict-like container for the output of a SepTopProtocol""" def __init__(self, **data): super().__init__(**data) # TODO: Detect when we have extensions and stitch these together? if any( len(pur_list) > 2 for pur_list in itertools.chain( self.data["solvent"].values(), self.data["complex"].values() ) ): raise NotImplementedError("Can't stitch together results yet") def get_individual_estimates( self, ) -> dict[str, list[tuple[Quantity, Quantity]]]: """ Get the individual estimate of the free energies. Returns ------- dGs : dict[str, list[tuple[unit.Quantity, unit.Quantity]]] A dictionary, keyed ``solvent`` and ``complex`` for each leg of the thermodynamic cycle, with lists of tuples containing the individual free energy estimates and associated MBAR uncertainties for each repeat of that simulation type. """ complex_dGs = [] complex_correction_dGs_A = [] complex_correction_dGs_B = [] solv_dGs = [] solv_correction_dGs: list[tuple[Any, Any]] = [] for pus in self.data["complex"].values(): complex_dGs.append( (pus[0].outputs["unit_estimate"], pus[0].outputs["unit_estimate_error"]) ) complex_correction_dGs_A.append( ( pus[0].outputs["standard_state_correction_A"], 0 * offunit.kilocalorie_per_mole, # correction has no error ) ) complex_correction_dGs_B.append( ( pus[0].outputs["standard_state_correction_B"], 0 * offunit.kilocalorie_per_mole, # correction has no error ) ) for pus in self.data["solvent"].values(): solv_dGs.append( (pus[0].outputs["unit_estimate"], pus[0].outputs["unit_estimate_error"]) ) solv_correction_dGs.append( ( pus[0].outputs["standard_state_correction"], 0 * offunit.kilocalorie_per_mole, # correction has no error ) ) return { "solvent": solv_dGs, "complex": complex_dGs, "standard_state_correction_complex_A": complex_correction_dGs_A, "standard_state_correction_complex_B": complex_correction_dGs_B, "standard_state_correction_solvent": solv_correction_dGs, } @staticmethod def _add_complex_standard_state_corr( complex_dG: list[tuple[Quantity, Quantity]], standard_state_corrA_dG: list[tuple[Quantity, Quantity]], standard_state_corrB_dG: list[tuple[Quantity, Quantity]], ) -> list[tuple[Quantity, Quantity]]: """ Helper method to combine the complex & standard state corrections legs. Parameters ---------- complex_dG : list[tuple[openff.units.Quantity, openff.units.Quantity]] The individual estimates of the complex leg, where the first entry of each tuple is the dG estimate and the second entry is the MBAR error. standard_state_corrA_dG : list[tuple[Quantity, Quantity]] The individual standard state corrections of state A for each corresponding complex leg. The first entry is the correction, the second is an empty error value of 0. standard_state_corrB_dG : list[tuple[Quantity, Quantity]] The individual standard state corrections of state B for each corresponding complex leg. The first entry is the correction, the second is an empty error value of 0. Returns ------- combined_dG : list[tuple[openff.units.Quantity,openff.units. Quantity]] A list of dG estimates & MBAR errors for the combined complex & standard state correction of each repeat. Notes ----- We assume that both list of items are in the right order. """ combined_dG: list[tuple[Quantity, Quantity]] = [] for comp, corrA, corrB in zip(complex_dG, standard_state_corrA_dG, standard_state_corrB_dG): # No need to convert unit types, since pint takes care of that # except that mypy hates it because pint isn't typed properly... # No need to add errors since there's just the one combined_dG.append((comp[0] + corrA[0] + corrB[0], comp[1])) # type: ignore[operator] return combined_dG @staticmethod def _add_solvent_standard_state_corr( solvent_dG: list[tuple[Quantity, Quantity]], standard_state_corr_dG: list[tuple[Quantity, Quantity]], ) -> list[tuple[Quantity, Quantity]]: """ Helper method to combine the solvent & standard state corrections legs. Parameters ---------- solvent_dG : list[tuple[openff.units.Quantity, openff.units.Quantity]] The individual estimates of the solvent leg, where the first entry of each tuple is the dG estimate and the second entry is the MBAR error. standard_state_corrA_dG : list[tuple[Quantity, Quantity]] The individual solvent standard state corrections. The first entry is the correction, the second is an empty error value of 0. Returns ------- combined_dG : list[tuple[openff.units.Quantity,openff.units. Quantity]] A list of dG estimates & MBAR errors for the combined solvent & standard state correction of each repeat. Notes ----- We assume that both list of items are in the right order. """ combined_dG: list[tuple[Quantity, Quantity]] = [] for comp, corr in zip(solvent_dG, standard_state_corr_dG): # No need to convert unit types, since pint takes care of that # except that mypy hates it because pint isn't typed properly... # No need to add errors since there's just the one combined_dG.append((comp[0] + corr[0], comp[1])) # type: ignore[operator] return combined_dG def get_estimate(self) -> Quantity: """Get the difference in binding free energy estimate for this calculation. Returns ------- ddG : openff.units.Quantity The difference in binding free energy. This is a Quantity defined with units. """ def _get_average(estimates): # Get the unit value of the first value in the estimates u = estimates[0][0].u # Loop through estimates and get the free energy values # in the unit of the first estimate ddGs = [i[0].to(u).m for i in estimates] return np.average(ddGs) * u individual_estimates = self.get_individual_estimates() solv_ddG = _get_average( self._add_solvent_standard_state_corr( individual_estimates["solvent"], individual_estimates["standard_state_correction_solvent"], ) ) complex_ddG = _get_average( self._add_complex_standard_state_corr( individual_estimates["complex"], individual_estimates["standard_state_correction_complex_A"], individual_estimates["standard_state_correction_complex_B"], ) ) return complex_ddG - solv_ddG def get_uncertainty(self) -> Quantity: """Get the relative free energy error for this calculation. Returns ------- err : unit.Quantity The standard deviation between estimates of the relative binding free energy. This is a Quantity defined with units. """ def _get_stdev(estimates): # Get the unit value of the first value in the estimates u = estimates[0][0].u # Loop through estimates and get the free energy values # in the unit of the first estimate ddGs = [i[0].to(u).m for i in estimates] return np.std(ddGs) * u individual_estimates = self.get_individual_estimates() solv_err = _get_stdev( self._add_solvent_standard_state_corr( individual_estimates["solvent"], individual_estimates["standard_state_correction_solvent"], ) ) complex_err = _get_stdev( self._add_complex_standard_state_corr( individual_estimates["complex"], individual_estimates["standard_state_correction_complex_A"], individual_estimates["standard_state_correction_complex_B"], ) ) # return the combined error return np.sqrt(solv_err**2 + complex_err**2) def get_forward_and_reverse_energy_analysis( self, ) -> dict[str, list[Optional[dict[str, Union[npt.NDArray, Quantity]]]]]: """ Get the reverse and forward analysis of the free energies. Returns ------- forward_reverse : dict[str, list[Optional[dict[str, Union[npt.NDArray, unit.Quantity]]]]] A dictionary, keyed `complex` and `solvent` for each leg of the thermodynamic cycle which each contain a list of dictionaries containing the forward and reverse analysis of each repeat of that simulation type. The forward and reverse analysis dictionaries contain: - `fractions`: npt.NDArray The fractions of data used for the estimates - `forward_DDGs`, `reverse_DDGs`: unit.Quantity The forward and reverse estimates for each fraction of data - `forward_dDDGs`, `reverse_dDDGs`: unit.Quantity The forward and reverse estimate uncertainty for each fraction of data. If one of the cycle leg list entries is ``None``, this indicates that the analysis could not be carried out for that repeat. This is most likely caused by MBAR convergence issues when attempting to calculate free energies from too few samples. Raises ------ UserWarning * If any of the forward and reverse dictionaries are ``None`` in a given thermodynamic cycle leg. """ forward_reverse: dict[str, list[Optional[dict[str, Union[npt.NDArray, Quantity]]]]] = {} for key in ["complex", "solvent"]: forward_reverse[key] = [ pus[0].outputs["forward_and_reverse_energies"] for pus in self.data[key].values() ] if None in forward_reverse[key]: wmsg = ( "One or more ``None`` entries were found in the forward " f"and reverse dictionaries of the repeats of the {key} " "calculations. This is likely caused by an MBAR convergence " "failure caused by too few independent samples when " "calculating the free energies of the 10% timeseries slice." ) warnings.warn(wmsg) return forward_reverse def get_overlap_matrices(self) -> dict[str, list[dict[str, npt.NDArray]]]: """ Get a the MBAR overlap estimates for all legs of the simulation. Returns ------- overlap_stats : dict[str, list[dict[str, npt.NDArray]]] A dictionary with keys `complex` and `solvent` for each leg of the thermodynamic cycle, which each containing a list of dictionaries with the MBAR overlap estimates of each repeat of that simulation type. The underlying MBAR dictionaries contain the following keys: * ``scalar``: One minus the largest nontrivial eigenvalue * ``eigenvalues``: The sorted (descending) eigenvalues of the overlap matrix * ``matrix``: Estimated overlap matrix of observing a sample from state i in state j """ # Loop through and get the repeats and get the matrices overlap_stats: dict[str, list[dict[str, npt.NDArray]]] = {} for key in ["complex", "solvent"]: overlap_stats[key] = [ pus[0].outputs["unit_mbar_overlap"] for pus in self.data[key].values() ] return overlap_stats def get_replica_transition_statistics( self, ) -> dict[str, list[dict[str, npt.NDArray]]]: """ Get the replica exchange transition statistics for all legs of the simulation. Note ---- This is currently only available in cases where a replica exchange simulation was run. Returns ------- repex_stats : dict[str, list[dict[str, npt.NDArray]]] A dictionary with keys `complex` and `solvent` for each leg of the thermodynamic cycle, which each containing a list of dictionaries containing the replica transition statistics for each repeat of that simulation type. The replica transition statistics dictionaries contain the following: * ``eigenvalues``: The sorted (descending) eigenvalues of the lambda state transition matrix * ``matrix``: The transition matrix estimate of a replica switching from state i to state j. """ repex_stats: dict[str, list[dict[str, npt.NDArray]]] = {} try: for key in ["complex", "solvent"]: repex_stats[key] = [ pus[0].outputs["replica_exchange_statistics"] for pus in self.data[key].values() ] except KeyError: errmsg = "Replica exchange statistics were not found, did you run a repex calculation?" raise ValueError(errmsg) return repex_stats def get_replica_states(self) -> dict[str, list[npt.NDArray]]: """ Get the timeseries of replica states for all simulation legs. Returns ------- replica_states : dict[str, list[npt.NDArray]] Dictionary keyed `complex` and `solvent` for each leg of the thermodynamic cycle, with lists of replica states timeseries for each repeat of that simulation type. """ replica_states: dict[str, list[npt.NDArray]] = {"complex": [], "solvent": []} def is_file(filename: str): p = pathlib.Path(filename) if not p.exists(): errmsg = f"File could not be found {p}" raise ValueError(errmsg) return p def get_replica_state(nc, chk): nc = is_file(nc) dir_path = nc.parents[0] chk = is_file(dir_path / chk).name reporter = multistate.MultiStateReporter( storage=nc, checkpoint_storage=chk, open_mode="r" ) retval = np.asarray(reporter.read_replica_thermodynamic_states()) reporter.close() return retval for key in ["complex", "solvent"]: for pus in self.data[key].values(): states = get_replica_state( pus[0].outputs["trajectory"], pus[0].outputs["checkpoint"], ) replica_states[key].append(states) return replica_states def equilibration_iterations(self) -> dict[str, list[float]]: """ Get the number of equilibration iterations for each simulation. Returns ------- equilibration_lengths : dict[str, list[float]] Dictionary keyed `complex` and `solvent` for each leg of the thermodynamic cycle, with lists containing the number of equilibration iterations for each repeat of that simulation type. """ equilibration_lengths: dict[str, list[float]] = {} for key in ["complex", "solvent"]: equilibration_lengths[key] = [ pus[0].outputs["equilibration_iterations"] for pus in self.data[key].values() ] return equilibration_lengths def production_iterations(self) -> dict[str, list[float]]: """ Get the number of production iterations for each simulation. Returns the number of uncorrelated production samples for each repeat of the calculation. Returns ------- production_lengths : dict[str, list[float]] Dictionary keyed `complex` and `solvent` for each leg of the thermodynamic cycle, with lists with the number of production iterations for each repeat of that simulation type. """ production_lengths: dict[str, list[float]] = {} for key in ["complex", "solvent"]: production_lengths[key] = [ pus[0].outputs["production_iterations"] for pus in self.data[key].values() ] return production_lengths def restraint_geometries( self, ) -> tuple[list[BoreschRestraintGeometry], list[BoreschRestraintGeometry]]: """ Get a list of the restraint geometries for the complex simulations. These define the atoms that have been restrained in the system. Returns ------- geometry_A : list[dict[str, Any]] A list of dictionaries containing the details of the atoms in the system that are involved in the restraint of ligand A. geometry_B : list[dict[str, Any]] A list of dictionaries containing the details of the atoms in the system that are involved in the restraint of ligand B. """ geometry_A = [ BoreschRestraintGeometry.model_validate(pus[0].outputs["restraint_geometry_A"]) for pus in self.data["complex"].values() ] geometry_B = [ BoreschRestraintGeometry.model_validate(pus[0].outputs["restraint_geometry_B"]) for pus in self.data["complex"].values() ] return geometry_A, geometry_B def selection_indices(self) -> dict[str, list[Optional[npt.NDArray]]]: """ Get the system selection indices used to write PDB and trajectory files. Returns ------- indices : dict[str, list[npt.NDArray]] A dictionary keyed as `complex` and `solvent` for each state, each containing a list of NDArrays containing the corresponding full system atom indices for each atom written in the production trajectory files for each replica. """ indices: dict[str, list[Optional[npt.NDArray]]] = {} for key in ["complex", "solvent"]: indices[key] = [] for pus in self.data[key].values(): indices[key].append(pus[0].outputs["selection_indices"]) return indices ================================================ FILE: src/openfe/protocols/openmm_septop/septop_units.py ================================================ # This code is part of OpenFE and is licensed under the MIT license. # For details, see https://github.com/OpenFreeEnergy/openfe r"""OpenMM Equilibrium SepTop RBFE Protocol Units ================================================ This module implements the :class:`gufe.ProtocolUnit`\s for the Separated Topologies RBFE protocol. """ from __future__ import annotations import copy import itertools import logging import pathlib from typing import Any import MDAnalysis as mda import mdtraj as md import numpy as np import openmm import openmm.unit import openmm.unit as omm_units from gufe import ( SmallMoleculeComponent, SolvatedPDBComponent, SolventComponent, ) from gufe.settings import SettingsBaseModel from MDAnalysis.coordinates.memory import MemoryReader from openff.toolkit.topology import Molecule as OFFMolecule from openff.units import Quantity from openff.units.openmm import from_openmm, to_openmm from openmmtools.states import ThermodynamicState from rdkit import Chem from openfe.protocols.openmm_utils import omm_compute from openfe.protocols.openmm_utils.serialization import serialize from openfe.protocols.restraint_utils import geometry from openfe.protocols.restraint_utils.geometry.boresch import BoreschRestraintGeometry from openfe.protocols.restraint_utils.openmm import omm_restraints from openfe.protocols.restraint_utils.openmm.omm_restraints import ( BoreschRestraint, add_force_in_separate_group, ) from ..openmm_utils import ( settings_validation, system_validation, ) from ..openmm_utils.mdtraj_utils import mdtraj_from_openmm from ..restraint_utils.settings import ( BoreschRestraintSettings, DistanceRestraintSettings, ) from .base_units import ( BaseSepTopAnalysisUnit, BaseSepTopRunUnit, BaseSepTopSetupUnit, _pre_equilibrate, ) logger = logging.getLogger(__name__) class SepTopComplexMixin: """ A mixin to get the components and the settings for the Complex Units. """ def _get_components(self): """ Get the relevant components for a complex transformation. Returns ------- alchem_comps : dict[str, Component] A list of alchemical components solv_comp : SolventComponent The SolventComponent of the system prot_comp : ProteinComponent | None The protein component of the system, if it exists. small_mols : dict[SmallMoleculeComponent: OFFMolecule] SmallMoleculeComponents to add to the system. """ stateA = self._inputs["stateA"] alchem_comps = self._inputs["alchemical_components"] solv_comp, prot_comp, small_mols = system_validation.get_components(stateA) small_mols = {m: m.to_openff() for m in small_mols} # Also get alchemical smc from state B small_mols_B = {m: m.to_openff() for m in alchem_comps["stateB"]} small_mols = small_mols | small_mols_B # If there is a SolvatedPDBComponent, we set the solv_comp in the # complex to that, as the SolventComponent is only used in the solvent leg if isinstance(prot_comp, SolvatedPDBComponent): solv_comp = prot_comp return alchem_comps, solv_comp, prot_comp, small_mols def _get_settings(self) -> dict[str, SettingsBaseModel]: """ Extract the relevant settings for a complex transformation. Returns ------- settings : dict[str, SettingsBaseModel] A dictionary with the following entries: * forcefield_settings : OpenMMSystemGeneratorFFSettings * thermo_settings : ThermoSettings * charge_settings : OpenFFPartialChargeSettings * solvation_settings : OpenMMSolvationSettings * alchemical_settings : AlchemicalSettings * lambda_settings : LambdaSettings * engine_settings : OpenMMEngineSettings * integrator_settings : IntegratorSettings * equil_simulation_settings : MDSimulationSettings * equil_output_settings : SepTopEquilOutputSettings * simulation_settings : SimulationSettings * output_settings: MultiStateOutputSettings * restraint_settings: BoreschRestraintSettings """ prot_settings = self._inputs["protocol"].settings # type: ignore settings = { "forcefield_settings": prot_settings.forcefield_settings, "thermo_settings": prot_settings.thermo_settings, "charge_settings": prot_settings.partial_charge_settings, "solvation_settings": prot_settings.complex_solvation_settings, "alchemical_settings": prot_settings.alchemical_settings, "lambda_settings": prot_settings.complex_lambda_settings, "engine_settings": prot_settings.engine_settings, "integrator_settings": prot_settings.complex_integrator_settings, "equil_simulation_settings": prot_settings.complex_equil_simulation_settings, "equil_output_settings": prot_settings.complex_equil_output_settings, "simulation_settings": prot_settings.complex_simulation_settings, "output_settings": prot_settings.complex_output_settings, "restraint_settings": prot_settings.complex_restraint_settings, } settings_validation.validate_timestep( settings["forcefield_settings"].hydrogen_mass, settings["integrator_settings"].timestep, ) return settings class SepTopSolventMixin: """ A mixin to get the components and the settings for the Solvent Units. """ def _get_components(self): """ Get the relevant components for a solvent transformation. Note ----- The solvent portion of the transformation is the transformation of one ligand into the other in the solvent. The only thing that should be present is the alchemical species in state A and state B and the SolventComponent. Returns ------- alchem_comps : dict[str, Component] A list of alchemical components solv_comp : SolventComponent The SolventComponent of the system prot_comp : ProteinComponent | None The protein component of the system, if it exists. small_mols : dict[SmallMoleculeComponent: OFFMolecule] SmallMoleculeComponents to add to the system. """ stateA = self._inputs["stateA"] alchem_comps = self._inputs["alchemical_components"] small_mols_A = {m: m.to_openff() for m in alchem_comps["stateA"]} small_mols_B = {m: m.to_openff() for m in alchem_comps["stateB"]} small_mols = small_mols_A | small_mols_B solv_comp, _, _ = system_validation.get_components(stateA) return alchem_comps, solv_comp, None, small_mols def _get_settings(self) -> dict[str, SettingsBaseModel]: """ Extract the relevant settings for a solvent transformation. Returns ------- settings : dict[str, SettingsBaseModel] A dictionary with the following entries: * forcefield_settings : OpenMMSystemGeneratorFFSettings * thermo_settings : ThermoSettings * charge_settings : OpenFFPartialChargeSettings * solvation_settings : OpenMMSolvationSettings * alchemical_settings : AlchemicalSettings * lambda_settings : LambdaSettings * engine_settings : OpenMMEngineSettings * integrator_settings : IntegratorSettings * equil_simulation_settings : MDSimulationSettings * equil_output_settings : SepTopEquilOutputSettings * simulation_settings : MultiStateSimulationSettings * output_settings: MultiStateOutputSettings * restraint_settings: BaseRestraintsSettings """ prot_settings = self._inputs["protocol"].settings # type: ignore settings = { "forcefield_settings": prot_settings.forcefield_settings, "thermo_settings": prot_settings.thermo_settings, "charge_settings": prot_settings.partial_charge_settings, "solvation_settings": prot_settings.solvent_solvation_settings, "alchemical_settings": prot_settings.alchemical_settings, "lambda_settings": prot_settings.solvent_lambda_settings, "engine_settings": prot_settings.engine_settings, "integrator_settings": prot_settings.solvent_integrator_settings, "equil_simulation_settings": prot_settings.solvent_equil_simulation_settings, "equil_output_settings": prot_settings.solvent_equil_output_settings, "simulation_settings": prot_settings.solvent_simulation_settings, "output_settings": prot_settings.solvent_output_settings, "restraint_settings": prot_settings.solvent_restraint_settings, } settings_validation.validate_timestep( settings["forcefield_settings"].hydrogen_mass, settings["integrator_settings"].timestep, ) return settings class SepTopComplexSetupUnit(SepTopComplexMixin, BaseSepTopSetupUnit): """ Protocol Unit for the complex phase of a SepTop free energy calculation """ simtype = "complex" def get_system_AB( self, solv_comp: SolventComponent, system_modeller_A: openmm.app.Modeller, smc_comps_AB: dict[SmallMoleculeComponent, OFFMolecule], smc_off_B: dict[SmallMoleculeComponent, OFFMolecule], settings: dict[str, SettingsBaseModel], ): """ Creates an OpenMM system, topology, positions, and modeller for a complex system that contains a protein and two ligands. This takes the modeller of complex A (solvated protein-ligand A complex) and inserts ligand B into that complex. Parameters ---------- solv_comp: SolventComponent The SolventComponent system_modeller_A: openmm.app.Modeller smc_comps_AB: dict[SmallMoleculeComponent,OFFMolecule] The dictionary of all SmallMoleculeComponents in the system. smc_off_B: dict[SmallMoleculeComponent,OFFMolecule] The dictionary of the SmallMoleculeComponent and OFF Molecule of ligand B settings: dict[str, SettingsBaseModel] A dictionary of settings objects for the unit. Returns ------- omm_system_AB: openmm.System omm_topology_AB: openmm.app.Topology positions_AB: openmm.unit.Quantity system_modeller_AB: openmm.app.Modeller """ # Get system generator system_generator = self._get_system_generator(settings, solv_comp) # Get modeller B only ligand B modeller_ligandB, comp_resids_ligB = self._get_modeller( None, None, smc_off_B, system_generator, settings["solvation_settings"], ) # Take the modeller from system A --> every water/ion should be in # the same location system_modeller_AB = copy.copy(system_modeller_A) system_modeller_AB.add(modeller_ligandB.topology, modeller_ligandB.positions) omm_topology_AB, omm_system_AB, positions_AB = self._get_omm_objects( system_modeller_AB, system_generator, list(smc_comps_AB.values()) ) return omm_system_AB, omm_topology_AB, positions_AB, system_modeller_AB @staticmethod def _get_selection_atom_indices( traj: md.Trajectory, selection: str = "backbone", ): """ Get the atom indices of a MDTraj object, given a selection string. Parameters ---------- traj: md.Trajectory The Mdtraj trajectory for which to get the atom indices. selection: str The selection string. Default: 'backbone' Returns ------- indices: list The list of atom indices that satisfy the selection string. Raises ------ ValueError If less than three atom indices are found for the selection string. """ indices = traj.topology.select(selection) if len(indices) < 3: errmsg = ( f"Less than 3 ({len(indices)} backbone atoms were found For " "complex A. No alignment of structures is possible." "Currently only proteins are supported as hosts." ) raise ValueError(errmsg) return indices @staticmethod def _update_positions( omm_topology_A: openmm.app.Topology, omm_topology_B: openmm.app.Topology, positions_A: openmm.unit.Quantity, positions_B: openmm.unit.Quantity, ) -> openmm.unit.Quantity: """ Aligns the protein from complex B onto the protein from complex A and updates the positions of complex B. Parameters ---------- omm_topology_A: openmm.app.Topology OpenMM topology from complex A omm_topology_B: openmm.app.Topology OpenMM topology from complex B positions_A: openmm.unit.Quantity Positions of the system in state A positions_B: openmm.unit.Quantity Positions of the system in state B Returns ------- updated_positions_B: openmm.unit.Quantity Updated positions of the complex B """ mdtraj_complex_A = mdtraj_from_openmm(omm_topology_A, positions_A) mdtraj_complex_B = mdtraj_from_openmm(omm_topology_B, positions_B) alignment_indices = SepTopComplexSetupUnit._get_selection_atom_indices(mdtraj_complex_A) imaged_complex_B = mdtraj_complex_B.image_molecules() imaged_complex_B.superpose( mdtraj_complex_A, atom_indices=alignment_indices, ) # Extract updated system positions. updated_positions_B = imaged_complex_B.openmm_positions(-1) return updated_positions_B @staticmethod def _get_mda_universe( topology: openmm.app.Topology, positions: openmm.unit.Quantity, trajectory: pathlib.Path | None, settings: dict[str, SettingsBaseModel], ) -> mda.Universe: """ Helper method to get a Universe from an openmm Topology, and either an input trajectory or a set of positions. Parameters ---------- topology : openmm.app.Topology An OpenMM Topology that defines the System. positions: openmm.unit.Quantity The System's current positions. Used if a trajectory file is None or is not a file. trajectory: pathlib.Path A Path to a trajectory file to read positions from. settings: dict The settings dictionary Returns ------- mda.Universe An MDAnalysis Universe of the System. """ # If the trajectory file doesn't exist, then we use positions write_int = settings["equil_output_settings"].trajectory_write_interval prod_length = settings["equil_simulation_settings"].production_length if trajectory is not None and trajectory.is_file() and write_int <= prod_length: return mda.Universe( topology, trajectory, topology_format="OPENMMTOPOLOGY", ) else: # Positions is an openmm Quantity in nm we need # to convert to angstroms return mda.Universe( topology, np.array(positions._value) * 10, topology_format="OPENMMTOPOLOGY", trajectory_format=MemoryReader, ) @staticmethod def _get_boresch_restraint( universe: mda.Universe, guest_rdmol: Chem.Mol, guest_atom_ids: list[int], host_atom_ids: list[int], temperature: Quantity, settings: BoreschRestraintSettings, ) -> tuple[BoreschRestraintGeometry, BoreschRestraint]: """ Get a Boresch-like restraint Geometry and OpenMM restraint force supplier. Parameters ---------- universe : mda.Universe An MDAnalysis Universe defining the system to get the restraint for. guest_rdmol : Chem.Mol An RDKit Molecule defining the guest molecule in the system. guest_atom_ids: list[int] A list of atom indices defining the guest molecule in the universe. host_atom_ids : list[int] A list of atom indices defining the host molecules in the universe. temperature : unit.Quantity The temperature of the simulation where the restraint will be added. settings : BoreschRestraintSettings Settings on how the Boresch-like restraint should be defined. Returns ------- geom : BoreschRestraintGeometry A class defining the Boresch-like restraint. restraint : BoreschRestraint A factory class for generating Boresch restraints in OpenMM. """ frc_const = min(settings.K_thetaA, settings.K_thetaB) geom = geometry.boresch.find_boresch_restraint( universe=universe, guest_rdmol=guest_rdmol, guest_idxs=guest_atom_ids, host_idxs=host_atom_ids, host_selection=settings.host_selection, anchor_finding_strategy=settings.anchor_finding_strategy, dssp_filter=settings.dssp_filter, rmsf_cutoff=settings.rmsf_cutoff, host_min_distance=settings.host_min_distance, host_max_distance=settings.host_max_distance, angle_force_constant=frc_const, temperature=temperature, ) restraint = omm_restraints.BoreschRestraint(settings) return geom, restraint def _add_restraints( self, system: openmm.System, topology_A: openmm.app.Topology, topology_B: openmm.app.Topology, positions_A: openmm.unit.Quantity, positions_B: openmm.unit.Quantity, mol_A: SmallMoleculeComponent, mol_B: SmallMoleculeComponent, ligand_A_inxs: list[int], ligand_B_inxs: list[int], ligand_B_inxs_B: list[int], protein_inxs: list[int], settings: dict[str, SettingsBaseModel], ) -> tuple[ Quantity, Quantity, openmm.System, geometry.HostGuestRestraintGeometry, geometry.HostGuestRestraintGeometry, ]: """ Adds Boresch restraints to the system. Parameters ---------- system: openmm.System The OpenMM system where the restraints will be applied to. topology_A: openmm.app.Topology The OpenMM topology that defines the system A topology_B: openmm.app.Topology The OpenMM topology that defines the system B positions_A: openmm.unit.Quantity Positions of the system A. This could be a single set of positions, or a full trajectory. positions_B: openmm.unit.Quantity Positions of the system B. This could be a single set of positions, or a full trajectory. mol_A: SmallMoleculeComponent The SmallMoleculeComponent of ligand A mol_B: SmallMoleculeComponent The SmallMoleculeComponent of ligand B ligand_A_inxs: list[int] Atom indices of ligand A in the complex A ligand_B_inxs: list[int] Atom indices of ligand B in the complex B ligand_B_inxs_B: list[int] Atom indices of ligand B in the full system (AB) protein_inxs: list[int] Atom indices from the protein atoms settings: dict[str, SettingsBaseModel] The settings dict Returns ------- correction_A: unit.Quantity The standard state correction for the restraint for ligand A. correction_B: unit.Quantity The standard state correction for the restraint for ligand B. restrained_system: openmm.System The OpenMM system with the added restraints forces rest_geom_A: geometry.HostGuestRestraintGeometry The restraint Geometry object for ligand A. rest_geom_B: geometry.HostGuestRestraintGeometry The restraint Geometry object for ligand B. """ # Get the MDA Universe for the restraints selection # We try to pass the equilibration production file path through # In some cases (debugging / dry runs) this won't be available # so we'll default to using input positions. out_traj = ( self.shared_basepath / settings["equil_output_settings"].production_trajectory_filename ) u_A = self._get_mda_universe( topology_A, positions_A, pathlib.Path(f"{out_traj}_stateA.xtc"), settings, ) u_B = self._get_mda_universe( topology_B, positions_B, pathlib.Path(f"{out_traj}_stateB.xtc"), settings, ) rdmol_A = mol_A.to_rdkit() rdmol_B = mol_B.to_rdkit() Chem.SanitizeMol(rdmol_A) Chem.SanitizeMol(rdmol_B) rest_geom_A, restraint_A = self._get_boresch_restraint( u_A, rdmol_A, ligand_A_inxs, protein_inxs, settings["thermo_settings"].temperature, settings["restraint_settings"], ) rest_geom_B, restraint_B = self._get_boresch_restraint( u_B, rdmol_B, ligand_B_inxs_B, protein_inxs, settings["thermo_settings"].temperature, settings["restraint_settings"], ) # We have to update the indices for ligand B to match the AB complex new_boresch_B_indices = [ligand_B_inxs_B.index(i) for i in rest_geom_B.guest_atoms] rest_geom_B.guest_atoms = [ligand_B_inxs[i] for i in new_boresch_B_indices] if self.verbose: self.logger.info( f"restraint geometry is: ligand A: {rest_geom_A}and ligand B: {rest_geom_B}." ) # We need a temporary thermodynamic state to add the restraint # & get the correction thermodynamic_state = ThermodynamicState( system, temperature=to_openmm(settings["thermo_settings"].temperature), pressure=to_openmm(settings["thermo_settings"].pressure), ) # Add the force to the thermodynamic state restraint_A.add_force( thermodynamic_state, rest_geom_A, controlling_parameter_name="lambda_restraints_A", ) restraint_B.add_force( thermodynamic_state, rest_geom_B, controlling_parameter_name="lambda_restraints_B", ) # Get the standard state correction as a unit.Quantity correction_A = restraint_A.get_standard_state_correction( thermodynamic_state, rest_geom_A, ) correction_B = restraint_B.get_standard_state_correction( thermodynamic_state, rest_geom_B, ) # Multiply the correction for ligand B by -1 as for this ligands, # Boresch restraint has to be turned on in the analytical corr. correction_B = -correction_B # type: ignore[operator] # Get the system # Note: you have to remove the thermostat, otherwise you end up # with an Andersen thermostat by default! restrained_system = thermodynamic_state.get_system(remove_thermostat=True) return ( correction_A, correction_B, restrained_system, rest_geom_A, rest_geom_B, ) def run( self, dry=False, verbose=True, scratch_basepath=None, shared_basepath=None, ) -> dict[str, Any]: """ Run the SepTop free energy calculation. Parameters ---------- dry : bool Do a dry run of the calculation, creating all necessary alchemical system components (topology, system, sampler, etc...) but without running the simulation, default False verbose : bool Verbose output of the simulation progress. Output is provided via INFO level logging, default True scratch_basepath : pathlib.Path Path to the scratch (temporary) directory space. shared_basepath : pathlib.Path Path to the shared (persistent) directory space. Returns ------- dict Outputs created in the basepath directory or the debug objects (i.e. sampler) if ``dry==True``. """ # 0. General preparation tasks self._prepare(verbose, scratch_basepath, shared_basepath) self.logger.info("Setting up SepTop complex system.") # 1. Get components self.logger.info("Creating and setting up the OpenMM systems") alchem_comps, solv_comp, prot_comp, smc_comps = self._get_components() smc_comps_A, smc_comps_B, smc_comps_AB = self.get_smc_comps(alchem_comps, smc_comps) # 3. Get settings settings = self._get_settings() # 4. Assign partial charges self._assign_partial_charges(settings["charge_settings"], smc_comps_AB) # 5. Get the OpenMM systems omm_system_A, omm_topology_A, positions_A, modeller_A, comp_resids_A = ( self.get_system( solv_comp, prot_comp, smc_comps_A, settings, ) ) # fmt: skip omm_system_B, omm_topology_B, positions_B, modeller_B, comp_resids_B = ( self.get_system( solv_comp, prot_comp, smc_comps_B, settings, ) ) # fmt: skip smc_B_unique_keys = smc_comps_B.keys() - smc_comps_A.keys() smc_comp_B_unique = {key: smc_comps_B[key] for key in smc_B_unique_keys} omm_system_AB, omm_topology_AB, positions_AB, modeller_AB = self.get_system_AB( solv_comp, modeller_A, smc_comps_AB, smc_comp_B_unique, settings, ) # Get the comp_resids of the AB system resids_A = list(itertools.chain(*comp_resids_A.values())) resids_AB = [r.index for r in modeller_AB.topology.residues()] diff_resids = list(set(resids_AB) - set(resids_A)) comp_resids_AB = comp_resids_A | {alchem_comps["stateB"][0]: np.array(diff_resids)} # 6. Pre-equilbrate System (for restraint selection) platform = omm_compute.get_openmm_platform( platform_name=settings["engine_settings"].compute_platform, gpu_device_index=settings["engine_settings"].gpu_device_index, restrict_cpu_count=False, ) self.logger.info("Pre-equilibrating the systems") equil_positions_A, box_A = _pre_equilibrate( system=omm_system_A, topology=omm_topology_A, positions=positions_A, settings=settings, endstate="A", dry=dry, shared_basepath=self.shared_basepath, platform=platform, verbose=self.verbose, logger=self.logger, ) equil_positions_B, box_B = _pre_equilibrate( system=omm_system_B, topology=omm_topology_B, positions=positions_B, settings=settings, endstate="B", dry=dry, shared_basepath=self.shared_basepath, platform=platform, verbose=self.verbose, logger=self.logger, ) # 7. Get all the right atom indices for alignments comp_atomids_A = self._get_atom_indices(omm_topology_A, comp_resids_A) all_atom_ids_A = list(itertools.chain(*comp_atomids_A.values())) comp_atomids_B = self._get_atom_indices(omm_topology_B, comp_resids_B) # Get the atom indices of ligand B in system B atom_indices_B = comp_atomids_B[alchem_comps["stateB"][0]] # 8. Update the positions of system B: Align protein updated_positions_B = self._update_positions( omm_topology_A, omm_topology_B, equil_positions_A, equil_positions_B, ) # Get atom indices for ligand A and ligand B and the solvent in the # system AB comp_atomids_AB = self._get_atom_indices(omm_topology_AB, comp_resids_AB) atom_indices_AB_B = comp_atomids_AB[alchem_comps["stateB"][0]] atom_indices_AB_A = comp_atomids_AB[alchem_comps["stateA"][0]] # Update positions from AB system positions_AB[all_atom_ids_A[0] : all_atom_ids_A[-1] + 1, :] = equil_positions_A positions_AB[atom_indices_AB_B[0] : atom_indices_AB_B[-1] + 1, :] = updated_positions_B[ atom_indices_B[0] : atom_indices_B[-1] + 1 ] # 9. Create the alchemical system self.logger.info("Creating the alchemical system and applying restraints") alchemical_factory, alchemical_system = self._get_alchemical_system( omm_system_AB, atom_indices_AB_A, atom_indices_AB_B, settings["alchemical_settings"], ) # 10. Apply Restraints corr_A, corr_B, system, restraint_geom_A, restraint_geom_B = self._add_restraints( alchemical_system, omm_topology_A, omm_topology_B, equil_positions_A, equil_positions_B, alchem_comps["stateA"][0], alchem_comps["stateB"][0], atom_indices_AB_A, atom_indices_AB_B, atom_indices_B, comp_atomids_AB[prot_comp], settings, ) equil_positions_AB, box_AB = _pre_equilibrate( system=system, topology=omm_topology_AB, positions=positions_AB, settings=settings, endstate="AB", dry=dry, platform=platform, shared_basepath=self.shared_basepath, verbose=self.verbose, logger=self.logger, ) # Update box vectors omm_topology_AB.setPeriodicBoxVectors(box_AB) # Subselect system based on user inputs & write initial subsampled PDB sub_pdb_structure = self.shared_basepath / settings["output_settings"].output_structure selection_indices = self._subsample_topology( topology=omm_topology_AB, positions=positions_AB, output_selection=settings["output_settings"].output_indices, output_file=self.shared_basepath / settings["output_settings"].output_structure, ) # The subsampled PDB may not have been written if selection_indices == 0 # Issue #1942 - maybe move this to the method? if len(selection_indices) == 0: sub_pdb_structure = None # Serialize the system and PDB topology system_outfile = self.shared_basepath / "system.xml.bz2" serialize(system, system_outfile) topology_file = self.shared_basepath / "topology.pdb" openmm.app.pdbfile.PDBFile.writeFile( omm_topology_AB, equil_positions_AB, open(topology_file, "w"), ) if not dry: return { "system": system_outfile, "topology": topology_file, "standard_state_correction_A": corr_A.to("kilocalorie_per_mole"), "standard_state_correction_B": corr_B.to("kilocalorie_per_mole"), "restraint_geometry_A": restraint_geom_A.model_dump(), "restraint_geometry_B": restraint_geom_B.model_dump(), "selection_indices": selection_indices, "subsampled_pdb_structure": sub_pdb_structure, } else: return { # Add in various objects we can use to test the system "system": system_outfile, "topology": topology_file, "system_A": omm_system_A, "system_B": omm_system_B, "system_AB": omm_system_AB, "alchem_restrained_system": system, "alchem_system": alchemical_system, "alchem_factory": alchemical_factory, "positions": equil_positions_AB, "selection_indices": selection_indices, "subsampled_pdb_structure": sub_pdb_structure, } class SepTopSolventSetupUnit(SepTopSolventMixin, BaseSepTopSetupUnit): """ Protocol Unit for the solvent phase of a relative SepTop free energy """ simtype = "solvent" @staticmethod def _update_positions( mol_A: SmallMoleculeComponent, mol_B: SmallMoleculeComponent, ) -> SmallMoleculeComponent: """ Computes the amount to offset the second ligand by in the solution phase during RBFE calculations and applies the offset to the ligand, returning the SmallMoleculeComponent with the updated positions. Parameters ---------- mol_A: SmallMoleculeComponent The SmallMoleculeComponent of ligand A mol_B: SmallMoleculeComponent The SmallMoleculeComponent of ligand B Returns ------- updated_mol_B: SmallMoleculeComponent The SmallMoleculeComponent of ligand B after updating its positions to be a certain distance away from ligand A """ # Convert SmallMolecule to Rdkit Molecule rdmol_A = mol_A.to_rdkit() rdmol_B = mol_B.to_rdkit() # Offset ligand B from ligand A in the solvent pos_ligandA = rdmol_A.GetConformers()[0].GetPositions() pos_ligandB = rdmol_B.GetConformers()[0].GetPositions() ligand_1_radius = np.linalg.norm(pos_ligandA - pos_ligandA.mean(axis=0), axis=1).max() ligand_2_radius = np.linalg.norm(pos_ligandB - pos_ligandB.mean(axis=0), axis=1).max() ligand_distance = (ligand_1_radius + ligand_2_radius) * 1.5 ligand_offset = pos_ligandA.mean(0) - pos_ligandB.mean(0) ligand_offset[0] += ligand_distance # Offset the ligandB. pos_ligandB += ligand_offset # Extract updated system positions. rdmol_B.GetConformers()[0].SetPositions(pos_ligandB) updated_mol_B = SmallMoleculeComponent(rdmol_B) return updated_mol_B def _add_restraints( self, system: openmm.System, ligand_1: Chem.rdchem.Mol, ligand_2: Chem.rdchem.Mol, ligand_1_inxs: list[int], ligand_2_inxs: list[int], settings: dict[str, SettingsBaseModel], positions_AB: openmm.unit.Quantity, ) -> tuple[ Quantity, openmm.System, ]: """ Apply the distance restraint between the ligands. Parameters ---------- system: openmm.System The OpenMM system where the restraints will be applied to. ligand_1: Chem.rdchem.Mol The RDKit Molecule of ligand A ligand_2: Chem.rdchem.Mol The RDKit Molecule of ligand B ligand_1_idxs: list[int] Atom indices from the ligand A in the system. ligand_2_idxs: list[int] Atom indices from the ligand B in the system. settings: dict[str, SettingsBaseModel] The settings dict positions_AB: openmm.unit.Quantity The positions of the OpenMM system Returns ------- correction: unit.Quantity Standard state correction for the harmonic distance restraint. system: openmm.System The OpenMM system with the added restraints forces """ if isinstance(settings["restraint_settings"], DistanceRestraintSettings): rest_geom = geometry.harmonic.get_molecule_centers_restraint( molA_rdmol=ligand_1, molB_rdmol=ligand_2, molA_idxs=ligand_1_inxs, molB_idxs=ligand_2_inxs, ) else: # TODO turn this into a direction for different restraint types supported? raise NotImplementedError("Other restraint types are not yet available") if self.verbose: self.logger.info(f"restraint geometry is: {rest_geom}") distance = np.linalg.norm( positions_AB[rest_geom.guest_atoms[0]] - positions_AB[rest_geom.host_atoms[0]] ) k_distance = to_openmm(settings["restraint_settings"].spring_constant) force = openmm.HarmonicBondForce() force.addBond( rest_geom.guest_atoms[0], rest_geom.host_atoms[0], distance * openmm.unit.nanometers, k_distance, ) force.setName("alignment_restraint") # Add force to a separate force group add_force_in_separate_group(system, force) # No correction necessary as only a single harmonic bond is applied between the ligands correction = ( from_openmm( openmm.unit.MOLAR_GAS_CONSTANT_R * to_openmm(settings["thermo_settings"].temperature) ) * 0.0 ) return correction, system def run( self, dry=False, verbose=True, scratch_basepath=None, shared_basepath=None ) -> dict[str, Any]: """ Run the SepTop free energy calculation. Parameters ---------- dry : bool Do a dry run of the calculation, creating all necessary alchemical system components (topology, system, sampler, etc...) but without running the simulation, default False verbose : bool Verbose output of the simulation progress. Output is provided via INFO level logging, default True scratch_basepath : pathlib.Path Path to the scratch (temporary) directory space. shared_basepath : pathlib.Path Path to the shared (persistent) directory space. Returns ------- dict Outputs created in the basepath directory or the debug objects (i.e. sampler) if ``dry==True``. """ # 0. General preparation tasks self._prepare(verbose, scratch_basepath, shared_basepath) self.logger.info("Setting up SepTop solvent system.") # 1. Get components self.logger.info("Creating and setting up the OpenMM systems") alchem_comps, solv_comp, prot_comp, smc_comps = self._get_components() smc_comps_A, smc_comps_B, smc_comps_AB = self.get_smc_comps(alchem_comps, smc_comps) # 2. Get settings settings = self._get_settings() # 3. Assign partial charges self._assign_partial_charges(settings["charge_settings"], smc_comps_AB) # 4. Update the positions of ligand B: # - solvent: Offset ligand B with respect to ligand A smc_B = self._update_positions( alchem_comps["stateA"][0], alchem_comps["stateB"][0], ) smc_off_B = {smc_B: smc_B.to_openff()} # 5. Get the OpenMM systems omm_system_AB, omm_topology_AB, positions_AB, modeller_AB, comp_resids_AB = ( self.get_system( solv_comp, prot_comp, smc_comps_A | smc_off_B, settings, ) ) # fmt: skip # 6. Get atom indices for ligand A and ligand B and the solvent in the # system AB comp_atomids_AB = self._get_atom_indices(omm_topology_AB, comp_resids_AB) atom_indices_AB_A = comp_atomids_AB[alchem_comps["stateA"][0]] atom_indices_AB_B = comp_atomids_AB[smc_B] # 7. Create the alchemical system self.logger.info("Creating the alchemical system and applying restraints") alchemical_factory, alchemical_system = self._get_alchemical_system( omm_system_AB, atom_indices_AB_A, atom_indices_AB_B, settings["alchemical_settings"], ) # 8. Apply Restraints rdmol_A = alchem_comps["stateA"][0].to_rdkit() rdmol_B = smc_B.to_rdkit() Chem.SanitizeMol(rdmol_A) Chem.SanitizeMol(rdmol_B) corr, system = self._add_restraints( alchemical_system, rdmol_A, rdmol_B, atom_indices_AB_A, atom_indices_AB_B, settings, positions_AB, ) # Write the full system PDB topology_file = self.shared_basepath / "topology.pdb" openmm.app.pdbfile.PDBFile.writeFile( omm_topology_AB, positions_AB, open(topology_file, "w") ) # Subselect system based on user inputs & write initial subsampled PDB sub_pdb_structure = self.shared_basepath / settings["output_settings"].output_structure selection_indices = self._subsample_topology( topology=omm_topology_AB, positions=positions_AB, output_selection=settings["output_settings"].output_indices, output_file=self.shared_basepath / settings["output_settings"].output_structure, ) # The subsampled PDB may not have been written if selection_indices == 0 # Issue #1942 - maybe move this to the method? if len(selection_indices) == 0: sub_pdb_structure = None # Serialize the system system_outfile = self.shared_basepath / "system.xml.bz2" serialize(system, system_outfile) if not dry: return { "system": system_outfile, "topology": topology_file, "standard_state_correction": corr.to("kilocalorie_per_mole"), "selection_indices": selection_indices, "subsampled_pdb_structure": sub_pdb_structure, } else: return { # Add in various objects we can used to test the system "system": system_outfile, "topology": topology_file, "system_AB": omm_system_AB, "alchem_restrained_system": system, "alchem_system": alchemical_system, "alchem_factory": alchemical_factory, "positions": positions_AB, "selection_indices": selection_indices, "subsampled_pdb_structure": sub_pdb_structure, } class SepTopSolventRunUnit(SepTopSolventMixin, BaseSepTopRunUnit): """ Protocol Unit for the solvent phase of a relative SepTop free energy """ simtype = "solvent" def _get_lambda_schedule( self, settings: dict[str, SettingsBaseModel] ) -> dict[str, list[float]]: lambdas = dict() lambda_elec_A = settings["lambda_settings"].lambda_elec_A lambda_vdw_A = settings["lambda_settings"].lambda_vdw_A lambda_elec_B = settings["lambda_settings"].lambda_elec_B lambda_vdw_B = settings["lambda_settings"].lambda_vdw_B # Reverse lambda schedule since in AbsoluteAlchemicalFactory 1 # means fully interacting, not stateB lambda_elec_A = [1 - x for x in lambda_elec_A] lambda_vdw_A = [1 - x for x in lambda_vdw_A] lambda_elec_B = [1 - x for x in lambda_elec_B] lambda_vdw_B = [1 - x for x in lambda_vdw_B] # # Set lambda restraint for the solvent to 1 # lambda_restraints = len(lambda_elec_A) * [1] lambdas["lambda_electrostatics_A"] = lambda_elec_A lambdas["lambda_sterics_A"] = lambda_vdw_A lambdas["lambda_electrostatics_B"] = lambda_elec_B lambdas["lambda_sterics_B"] = lambda_vdw_B # lambdas['lambda_restraints'] = lambda_restraints return lambdas class SepTopComplexRunUnit(SepTopComplexMixin, BaseSepTopRunUnit): """ Protocol Unit for the complex phase of a relative SepTop free energy """ simtype = "complex" def _get_lambda_schedule( self, settings: dict[str, SettingsBaseModel] ) -> dict[str, list[float]]: lambdas = dict() lambda_elec_A = settings["lambda_settings"].lambda_elec_A lambda_vdw_A = settings["lambda_settings"].lambda_vdw_A lambda_elec_B = settings["lambda_settings"].lambda_elec_B lambda_vdw_B = settings["lambda_settings"].lambda_vdw_B lambda_restraints_A = settings["lambda_settings"].lambda_restraints_A lambda_restraints_B = settings["lambda_settings"].lambda_restraints_B # Reverse lambda schedule since in AbsoluteAlchemicalFactory 1 # means fully interacting, not stateB lambda_elec_A = [1 - x for x in lambda_elec_A] lambda_vdw_A = [1 - x for x in lambda_vdw_A] lambda_elec_B = [1 - x for x in lambda_elec_B] lambda_vdw_B = [1 - x for x in lambda_vdw_B] lambdas["lambda_electrostatics_A"] = lambda_elec_A lambdas["lambda_sterics_A"] = lambda_vdw_A lambdas["lambda_electrostatics_B"] = lambda_elec_B lambdas["lambda_sterics_B"] = lambda_vdw_B lambdas["lambda_restraints_A"] = lambda_restraints_A lambdas["lambda_restraints_B"] = lambda_restraints_B return lambdas class SepTopSolventAnalysisUnit(SepTopSolventMixin, BaseSepTopAnalysisUnit): """ Protocol Unit for the analysis of the solvent phase of a relative SepTop free energy """ simtype = "solvent" class SepTopComplexAnalysisUnit(SepTopComplexMixin, BaseSepTopAnalysisUnit): """ Protocol Unit for the analysis of the complex phase of a relative SepTop free energy """ simtype = "complex" ================================================ FILE: src/openfe/protocols/openmm_septop/utils.py ================================================ from openmmtools import states from openmmtools.states import GlobalParameterState class SepTopParameterState(GlobalParameterState): """ Composable state to control lambda parameters for two ligands. See :class:`openmmtools.states.GlobalParameterState` for more details. Parameters ---------- parameters_name_suffix : Optional[str] If specified, the state will control a modified version of the parameter ``lambda_restraints_{parameters_name_suffix}` instead of just ``lambda_restraints``. lambda_sterics_A : Optional[float] The value for the vdW interactions for ligand A. If defined, must be between 0 and 1. lambda_electrosterics_A : Optional[float] The value for the electrostatics interactions for ligand A. If defined, must be between 0 and 1. lambda_restraints_A : Optional[float] The strength of the restraint for ligand A. If defined, must be between 0 and 1. lambda_bonds_A : Optional[float] The value for modifying bonds for ligand A. If defined, must be between 0 and 1. lambda_angles_A : Optional[float] The value for modifying angles for ligand A. If defined, must be between 0 and 1. lambda_dihedrals_A : Optional[float] The value for modifying dihedrals for ligand A. If defined, must be between 0 and 1. lambda_sterics_B : Optional[float] The value for the vdW interactions for ligand B. If defined, must be between 0 and 1. lambda_electrosterics_B : Optional[float] The value for the electrostatics interactions for ligand B. If defined, must be between 0 and 1. lambda_restraints_B : Optional[float] The strength of the restraint for ligand B. If defined, must be between 0 and 1. lambda_bonds_B : Optional[float] The value for modifying bonds for ligand B. If defined, must be between 0 and 1. lambda_angles_B : Optional[float] The value for modifying angles for ligand B. If defined, must be between 0 and 1. lambda_dihedrals_B : Optional[float] The value for modifying dihedrals for ligand B. If defined, must be between 0 and 1. """ class _LambdaParameter(states.GlobalParameterState.GlobalParameter): """A global parameter in the interval [0, 1] with standard value 1.""" def __init__(self, parameter_name): super().__init__(parameter_name, standard_value=1.0, validator=self.lambda_validator) @staticmethod def lambda_validator(self, instance, parameter_value): if parameter_value is None: return parameter_value if not (0.0 <= parameter_value <= 1.0): raise ValueError("{} must be between 0 and 1.".format(self.parameter_name)) return float(parameter_value) # Lambda parameters for ligand A lambda_sterics_A = _LambdaParameter("lambda_sterics_A") lambda_electrostatics_A = _LambdaParameter("lambda_electrostatics_A") lambda_restraints_A = _LambdaParameter("lambda_restraints_A") lambda_bonds_A = _LambdaParameter("lambda_bonds_A") lambda_angles_A = _LambdaParameter("lambda_angles_A") lambda_torsions_A = _LambdaParameter("lambda_torsions_A") # Lambda parameters for ligand B lambda_sterics_B = _LambdaParameter("lambda_sterics_B") lambda_electrostatics_B = _LambdaParameter("lambda_electrostatics_B") lambda_restraints_B = _LambdaParameter("lambda_restraints_B") lambda_bonds_B = _LambdaParameter("lambda_bonds_B") lambda_angles_B = _LambdaParameter("lambda_angles_B") lambda_torsions_B = _LambdaParameter("lambda_torsions_B") # # Restraints solvent # lambda_restraints = _LambdaParameter('lambda_restraints') ================================================ FILE: src/openfe/protocols/openmm_utils/__init__.py ================================================ ================================================ FILE: src/openfe/protocols/openmm_utils/charge_generation.py ================================================ # This code is part of OpenFE and is licensed under the MIT license. # For details, see https://github.com/OpenFreeEnergy/openfe """ Reusable utilities for assigning partial charges to ChemicalComponents. """ import copy import sys import warnings from typing import Callable, Literal import numpy as np from gufe import SmallMoleculeComponent from openff.toolkit import Molecule as OFFMol from openff.toolkit.utils.base_wrapper import ToolkitWrapper from openff.toolkit.utils.toolkit_registry import ToolkitRegistry from openff.toolkit.utils.toolkits import ( AmberToolsToolkitWrapper, OpenEyeToolkitWrapper, RDKitToolkitWrapper, ) from openff.units import unit from threadpoolctl import threadpool_limits try: import openeye except ImportError: HAS_OPENEYE = False else: HAS_OPENEYE = True try: from openff.toolkit.utils.toolkit_registry import ( toolkit_registry_manager, ) except ImportError: # toolkit_registry_manager was made non private in 0.14.4 from openff.toolkit.utils.toolkit_registry import ( _toolkit_registry_manager as toolkit_registry_manager, ) try: from openff.nagl_models import ( get_models_by_type, validate_nagl_model_path, ) from openff.toolkit.utils.nagl_wrapper import NAGLToolkitWrapper except ImportError: HAS_NAGL = False else: HAS_NAGL = True try: from espaloma_charge.openff_wrapper import EspalomaChargeToolkitWrapper except ImportError: HAS_ESPALOMA_CHARGE = False else: HAS_ESPALOMA_CHARGE = True # Dictionary of lists for the various backend options we allow. # Note: can't create the classes ahead of time in case we end # up with a case where the tool is not available, e.g. if OpenEye tk # is not installed. BACKEND_OPTIONS: dict[str, list[ToolkitWrapper]] = { "ambertools": [RDKitToolkitWrapper, AmberToolsToolkitWrapper], "openeye": [OpenEyeToolkitWrapper], "rdkit": [RDKitToolkitWrapper], } def assign_offmol_espaloma_charges(offmol: OFFMol, toolkit_registry: ToolkitRegistry) -> None: """ Assign Espaloma charges using the OpenFF toolkit. Parameters ---------- offmol : openff.toolkit.Molecule OpenFF molecule to assign NAGL partial charges for. toolkit_registry : ToolkitRegistry Toolkit registry to use for assigning partial charges. This strictly limits available toolkit wrappers by overwriting the global registry during the partial charge assignment stage. """ if not HAS_ESPALOMA_CHARGE: errmsg = "The Espaloma ToolkiWrapper is not available, please install espaloma_charge" raise ImportError(errmsg) warnings.warn("Using espaloma to assign charges is not well tested", category=RuntimeWarning) # make a copy to remove conformers as espaloma enforces # a 0 conformer check offmol_copy = copy.deepcopy(offmol) offmol_copy._conformers = None # We are being overly cautious by applying the manager here # this is to avoid issues like: # https://github.com/openforcefield/openff-nagl/issues/69 with toolkit_registry_manager(toolkit_registry): offmol_copy.assign_partial_charges( partial_charge_method="espaloma-am1bcc", toolkit_registry=EspalomaChargeToolkitWrapper(), ) # Copy back charges into the original offmol object offmol.partial_charges = offmol_copy.partial_charges def assign_offmol_nagl_charges( offmol: OFFMol, toolkit_registry: ToolkitRegistry, nagl_model: str | None = None, ) -> None: """ Assign NAGL charges using the OpenFF toolkit. Parameters ---------- offmol : openff.toolkit.Molecule OpenFF molecule to assign NAGL partial charges for. toolkit_registry : ToolkitRegistry Toolkit registry to use for assigning partial charges. This strictly limits available toolkit wrappers by overwriting the global registry during the partial charge assignment stage. nagl_model : str | None The NAGL model to use when assigning partial charges. If ``None``, will fetch the latest production "am1bcc" model. """ if not HAS_NAGL: errmsg = ( "The NAGL toolkit is not available, you may " "be using an older version of the OpenFF " "toolkit - you need v0.14.4 or above" ) raise ImportError(errmsg) if nagl_model is None: prod_models = get_models_by_type(model_type="am1bcc", production_only=True) try: nagl_model = prod_models[-1] except IndexError: errmsg = ( "No production am1bcc NAGL models were found, " "please manually select a candidate release model." ) raise ValueError(errmsg) model_path = validate_nagl_model_path(nagl_model) # We are being overly cautious by applying the manager here # this is to avoid issues like: # https://github.com/openforcefield/openff-nagl/issues/69 with toolkit_registry_manager(toolkit_registry): offmol.assign_partial_charges( partial_charge_method=model_path, toolkit_registry=NAGLToolkitWrapper(), ) def assign_offmol_am1bcc_charges( offmol: OFFMol, partial_charge_method: Literal["am1bcc", "am1bccelf10"], toolkit_registry: ToolkitRegistry, ) -> None: """ Assign AM1BCC charges using the OpenFF toolkit. Parameters ---------- offmol : openff.toolkit.Molecule OpenFF Molecule to assign AM1BCC charges for. Must already have a conformer. partial_charge_method : Literal['am1bcc', 'am1bccelf10'] The partial charge method to employ. Options include `am1bcc`, `am1bccelf10`. toolkit_registry : ToolkitRegistry Toolkit registry to use for assigning partial charges. This strictly limits available toolkit wrappers by overwriting the global registry during the partial charge assignment stage. Raises ------ ValueError If the ``offmol`` does not have any conformers. """ if offmol.n_conformers == 0: errmsg = "method expects at least one conformer" raise ValueError(errmsg) # We are being overly cautious by both passing the # registry and applying the manager here - this is # to avoid issues like: # https://github.com/openforcefield/openff-nagl/issues/69 with toolkit_registry_manager(toolkit_registry): offmol.assign_partial_charges( partial_charge_method=partial_charge_method, use_conformers=offmol.conformers, toolkit_registry=toolkit_registry, ) def _generate_offmol_conformers( offmol: OFFMol, max_conf: int, toolkit_registry: ToolkitRegistry, generate_n_conformers: int | None, ) -> None: """ Helper method for OFF Molecule conformer generation in charge assignment. Parameters ---------- offmol : openff.toolkit.Molecule OpenFF Molecule to generate conformers for max_conf : int The maximum number of conformers supported by requested charge method. toolkit_registry : ToolkitRegistry Toolkit registry to use for generating conformers. This strictly limits available toolkit wrappers by overwriting the global registry during the conformer generation step. generate_n_conformers : int | None The number of conformers to generate. If ``None``, the existing conformers are retained & used. Raises ------ ValueError If the ``generate_n_conformers`` is ``None`` and there are either no conformers or more than ``max_conf`` conformers associated with the input ``offmol``. If ``generate_n_conformers`` is greater than the value of ``max_conf``. """ # Check number of conformers if generate_n_conformers is None and return if generate_n_conformers is None: if offmol.n_conformers == 0: errmsg = ( "No conformers are associated with input OpenFF " "Molecule. Need at least one for partial charge " "assignment" ) raise ValueError(errmsg) if offmol.n_conformers > max_conf: errmsg = ( "OpenFF Molecule has too many conformers: " f"{offmol.n_conformers}, selected partial charge " f"method can only support a maximum of {max_conf} " "conformers." ) raise ValueError(errmsg) return # Check that generate_n_conformers < max_conf if generate_n_conformers > max_conf: errmsg = ( f"{generate_n_conformers} conformers were requested " "for partial charge generation, but the selected " "method only supports up to {max_conf} conformers." ) raise ValueError(errmsg) # Generate conformers # OpenEye tk needs cis carboxylic acids make_carbox_cis = any( [isinstance(i, OpenEyeToolkitWrapper) for i in toolkit_registry.registered_toolkits] ) # We are being overly cautious by both passing the # registry and applying the manager here - this is # to avoid issues like: # https://github.com/openforcefield/openff-nagl/issues/69 with toolkit_registry_manager(toolkit_registry): offmol.generate_conformers( n_conformers=generate_n_conformers, rms_cutoff=0.25 * unit.angstrom, make_carboxylic_acids_cis=make_carbox_cis, toolkit_registry=toolkit_registry, ) def assign_offmol_partial_charges( offmol: OFFMol, overwrite: bool, method: Literal["am1bcc", "am1bccelf10", "nagl", "espaloma"], toolkit_backend: Literal["ambertools", "openeye", "rdkit"], generate_n_conformers: int | None, nagl_model: str | None, ) -> OFFMol: """ Assign partial charges to an OpenFF Molecule based on a selected method. Parameters ---------- offmol : openff.toolkit.Molecule The Molecule to assign partial charges to. overwrite : bool Whether or not to overwrite any existing non-zero partial charges. Note that zeroed charges will always be overwritten. method : Literal['am1bcc', 'am1bccelf10', 'nagl', 'espaloma'] Partial charge assignment method. Supported methods include; am1bcc, am1bccelf10, nagl, and espaloma. toolkit_backend : Literal['ambertools', 'openeye', 'rdkit'] OpenFF toolkit backend employed for charge generation. Supported options: * ``ambertools``: selects both the AmberTools and RDKit Toolkit Wrapper * ``openeye``: selects the OpenEye toolkit Wrapper * ``rdkit``: selects the RDKit toolkit Wrapper Note that the ``rdkit`` backend cannot be used for `am1bcc` or ``am1bccelf10`` partial charge methods. generate_n_conformers : int | None Number of conformers to generate for partial charge generation. If ``None``, the input conformer will be used. Values greater than 1 can only be used alongside ``am1bccelf10``. nagl_model : str | None The NAGL model to use for charge assignment if method is ``nagl``. If ``None``, the latest am1bcc NAGL charge model is used. Raises ------ ValueError If the ``toolkit_backend`` is not supported by the selected ``method``. If ``generate_n_conformers`` is ``None``, but the input ``offmol`` has no associated conformers. If the number of conformers passed or generated exceeds the number of conformers selected by the partial charge ``method``. Returns ------- The Molecule with partial charges assigned. """ # If you have non-zero charges and not overwriting, just return if offmol.partial_charges is not None and np.any(offmol.partial_charges): if not overwrite: return offmol # Dictionary for each available charge method # The idea of this pattern is to allow for maximum flexibility by # allowing for swapping out method calls as necessary. # # Must include: # 1. `confgen_func`: the conformer generation method # 2. `charge_func`: the partial charge assignment method # 2. `backends`: the allowed backends for the method # 3. `max_conf`: maximum number of allowed conformations for the method # 4. `charge_extra_kwargs`: any additional kwargs to be passed to the # partial charge assignment method beyond the input offmol and # the toolkitregistry CHARGE_METHODS = { "am1bcc": { "confgen_func": _generate_offmol_conformers, "charge_func": assign_offmol_am1bcc_charges, "backends": ["ambertools", "openeye"], "max_conf": 1, "charge_extra_kwargs": {"partial_charge_method": "am1bcc"}, }, "am1bccelf10": { "confgen_func": _generate_offmol_conformers, "charge_func": assign_offmol_am1bcc_charges, "backends": ["openeye"], "max_conf": sys.maxsize, "charge_extra_kwargs": {"partial_charge_method": "am1bccelf10"}, }, "nagl": { "confgen_func": _generate_offmol_conformers, "charge_func": assign_offmol_nagl_charges, "backends": ["openeye", "rdkit", "ambertools"], "max_conf": 1, "charge_extra_kwargs": {"nagl_model": nagl_model}, }, "espaloma": { "confgen_func": _generate_offmol_conformers, "charge_func": assign_offmol_espaloma_charges, "backends": ["rdkit", "ambertools"], "max_conf": 1, "charge_extra_kwargs": {}, }, } # Grab the backends and also check our method try: backends = CHARGE_METHODS[method.lower()]["backends"] except KeyError: errmsg = f"Unknown partial charge method {method}" raise ValueError(errmsg) # Check our method actually supports the toolkit backend selected if toolkit_backend.lower() not in backends: # type: ignore errmsg = ( f"Selected toolkit_backend ({toolkit_backend}) cannot " f"be used with the selected method ({method}). " f"Available backends are: {backends}" ) raise ValueError(errmsg) # OpenEye is the only optional dependency in the toolkit backends if toolkit_backend.lower() == "openeye" and not HAS_OPENEYE: errmsg = "OpenEye is not available and cannot be selected as a backend" raise ImportError(errmsg) # Issue 1760 if HAS_OPENEYE and method.lower() == "nagl": if toolkit_backend.lower() != "openeye": errmsg = "OpenEye toolkit is installed but not used in the OpenFF toolkit registry backend. This is not possible with NAGL charges." raise ValueError(errmsg) toolkits = ToolkitRegistry([i() for i in BACKEND_OPTIONS[toolkit_backend.lower()]]) # We make a copy of the molecule since we're going to modify conformers offmol_copy = copy.deepcopy(offmol) # Generate conformers - note this method may differ based on the partial # charge method employed CHARGE_METHODS[method.lower()]["confgen_func"]( offmol=offmol_copy, max_conf=CHARGE_METHODS[method.lower()]["max_conf"], toolkit_registry=toolkits, generate_n_conformers=generate_n_conformers, ) # type: ignore # limit the number of threads used by SQM # with threadpool_limits(limits=1): # Call selected method to assign partial charges CHARGE_METHODS[method.lower()]["charge_func"]( offmol=offmol_copy, toolkit_registry=toolkits, **CHARGE_METHODS[method.lower()]["charge_extra_kwargs"], ) # type: ignore # Copy partial charges back offmol.partial_charges = offmol_copy.partial_charges return offmol def bulk_assign_partial_charges( molecules: list[SmallMoleculeComponent], overwrite: bool, method: Literal["am1bcc", "am1bccelf10", "nagl", "espaloma"], toolkit_backend: Literal["ambertools", "openeye", "rdkit"], generate_n_conformers: int | None, nagl_model: str | None, processors: int = 1, ) -> list[SmallMoleculeComponent]: """ Assign partial charges to a list of SmallMoleculeComponents using multiprocessing. Parameters ---------- molecules : list[gufe.SmallMoleculeComponent] The list of molecules who should have partial charges assigned. overwrite : bool Whether or not to overwrite any existing non-zero partial charges. Note that zeroed charges will always be overwritten. method : Literal['am1bcc', 'am1bccelf10', 'nagl', 'espaloma'] Partial charge assignment method. Supported methods include; am1bcc, am1bccelf10, nagl, and espaloma. toolkit_backend : Literal['ambertools', 'openeye', 'rdkit'] OpenFF toolkit backend employed for charge generation. Supported options: * ``ambertools``: selects both the AmberTools and RDKit Toolkit Wrapper * ``openeye``: selects the OpenEye toolkit Wrapper * ``rdkit``: selects the RDKit toolkit Wrapper Note that the ``rdkit`` backend cannot be used for `am1bcc` or ``am1bccelf10`` partial charge methods. generate_n_conformers : int | None Number of conformers to generate for partial charge generation. If ``None``, the input conformer will be used. Values greater than 1 can only be used alongside ``am1bccelf10``. nagl_model : str | None The NAGL model to use for charge assignment if method is ``nagl``. If ``None``, the latest am1bcc NAGL charge model is used. processors: int, default 1 The number of processors which should be used to generate the charges. Raises ------ ValueError If the ``toolkit_backend`` is not supported by the selected ``method``. If ``generate_n_conformers`` is ``None``, but the input ``offmol`` has no associated conformers. If the number of conformers passed or generated exceeds the number of conformers selected by the partial charge ``method``. Returns ------- A list of SmallMoleculeComponents with the charges assigned. """ import tqdm charge_keywords = { "overwrite": overwrite, "method": method, "toolkit_backend": toolkit_backend, "generate_n_conformers": generate_n_conformers, "nagl_model": nagl_model, } charged_ligands = [] if processors > 1: from concurrent.futures import ProcessPoolExecutor, as_completed with ProcessPoolExecutor(max_workers=processors) as pool: work_list = [ pool.submit( assign_offmol_partial_charges, m.to_openff(), **charge_keywords, # type: ignore ) for m in molecules ] for work in tqdm.tqdm( as_completed(work_list), desc="Generating charges", ncols=80, total=len(molecules) ): charged_ligands.append(SmallMoleculeComponent.from_openff(work.result())) else: for m in tqdm.tqdm(molecules, desc="Generating charges", ncols=80, total=len(molecules)): mol_with_charge = assign_offmol_partial_charges(m.to_openff(), **charge_keywords) # type: ignore charged_ligands.append(SmallMoleculeComponent.from_openff(mol_with_charge)) return charged_ligands ================================================ FILE: src/openfe/protocols/openmm_utils/mdtraj_utils.py ================================================ # This code is part of OpenFE and is licensed under the MIT license. # For details, see https://github.com/OpenFreeEnergy/openfe import mdtraj as mdt import numpy as np import openmm from openmm import unit as omm_unit def mdtraj_from_openmm( omm_topology: openmm.app.Topology, omm_positions: openmm.unit.Quantity, ): """ Get an mdtraj object from an OpenMM topology and positions. Parameters ---------- omm_topology : openmm.app.Topology The OpenMM topology omm_positions : openmm.unit.Quantity The OpenMM positions Returns ------- mdtraj_trajectory : md.Trajectory """ mdtraj_topology = mdt.Topology.from_openmm(omm_topology) positions_in_mdtraj_format = omm_positions.value_in_unit(omm_unit.nanometers) box = omm_topology.getPeriodicBoxVectors() if box is not None: x, y, z = [np.array(b._value) for b in box] lx = np.linalg.norm(x) ly = np.linalg.norm(y) lz = np.linalg.norm(z) # angle between y and z alpha = np.arccos(np.dot(y, z) / (ly * lz)) # angle between x and z beta = np.arccos(np.dot(x, z) / (lx * lz)) # angle between x and y gamma = np.arccos(np.dot(x, y) / (lx * ly)) unitcell_lengths = np.array([lx, ly, lz]) unitcell_angles = np.array([np.rad2deg(alpha), np.rad2deg(beta), np.rad2deg(gamma)]) else: unitcell_lengths = None unitcell_angles = None mdtraj_trajectory = mdt.Trajectory( positions_in_mdtraj_format, mdtraj_topology, unitcell_lengths=unitcell_lengths, unitcell_angles=unitcell_angles, ) return mdtraj_trajectory ================================================ FILE: src/openfe/protocols/openmm_utils/multistate_analysis.py ================================================ # This code is part of OpenFE and is licensed under the MIT license. # For details, see https://github.com/OpenFreeEnergy/openfe """ Reusable utility methods to analyze results from multistate calculations. """ import warnings from pathlib import Path from typing import Optional, Union import matplotlib.pyplot as plt import numpy as np import numpy.typing as npt from openff.units import Quantity, unit from openff.units.openmm import from_openmm from openmmtools import multistate from openfe.analysis import plotting from openfe.due import Doi, due due.cite( Doi("10.5281/zenodo.596622"), description="OpenMMTools", path="openfe.protocols.openmm_utils.multistate_analysis", cite_module=True, ) due.cite( Doi("10.1063/1.2978177"), description="MBAR paper", path="openfe.protocols.openmm_utils.multistate_analysis", cite_module=True, ) due.cite( Doi("10.1021/ct0502864"), description="MBAR timeseries algorithms", path="openfe.protocols.openmm_utils.multistate_analysis", cite_module=True, ) due.cite( Doi("10.1021/acs.jctc.5b00784"), description="Automatic equilibration detection method", path="openfe.protocols.openmm_utils.multistate_analysis", cite_module=True, ) due.cite( Doi("10.5281/zenodo.596220"), description="pyMBAR zenodo", path="openfe.protocols.openmm_utils.multistate_analysis", cite_module=True, ) class MultistateEquilFEAnalysis: """ A class to generate and plot all necessary analyses for a free energy calculation using a :class:`openmmtools.MultiStateSampler`. Currently implemented analyses are: - Decorrelated MBAR analysis of free energies (and associated errors) - Number of equilibration & sampling steps - MBAR overlap matrices - Replica lambda traversal (exchange matrix and timeseries) - Forward and reverse analysis of free energies Parameters ---------- reporter : openmmtools.MultiStateReporter Reporter for the MultiStateSampler sampling_method : str The sampling method. Expected values are `repex`, `sams`, and `independent`. result_units : openff.units.Quantity Units to report results in. forward_reverse_samples : int The number of samples to use in the forward and reverse analysis of the free energies. Default 10. """ def __init__( self, reporter: multistate.MultiStateReporter, sampling_method: str, result_units: Quantity, forward_reverse_samples: int = 10, ): self.analyzer = multistate.MultiStateSamplerAnalyzer(reporter) self.units = result_units if sampling_method.lower() not in ["repex", "sams", "independent"]: wmsg = f"Unknown sampling method {sampling_method}" warnings.warn(wmsg) self.sampling_method = sampling_method.lower() # Do a first pass at the analysis self._analyze(forward_reverse_samples) def plot(self, filepath: Path, filename_prefix: str): """ Plot out results from the free energy analyses. Specifically the following plots are generated: * The free energy overlap matrix * The replica exchange overlap matrix (if sampler_method is repex) * The timeseries of replica states over time * The forward and reverse estimate of the free energies Parameters ---------- filepath : pathlib.Path The path to where files should be written. filename_prefix : str A prefix for the written filenames. """ # MBAR overlap matrix ax = plotting.plot_lambda_transition_matrix(self.free_energy_overlaps["matrix"]) ax.set_title("MBAR overlap matrix") ax.figure.savefig( # type: ignore filepath / (filename_prefix + "mbar_overlap_matrix.png") ) plt.close(ax.figure) # type: ignore # Reverse and forward analysis if self.forward_and_reverse_free_energies is not None: ax = plotting.plot_convergence(self.forward_and_reverse_free_energies, self.units) ax.set_title("Forward and Reverse free energy convergence") ax.figure.savefig( # type: ignore filepath / (filename_prefix + "forward_reverse_convergence.png") ) plt.close(ax.figure) # type: ignore # Replica state timeseries plot ax = plotting.plot_replica_timeseries(self.replica_states, self.equilibration_iterations) ax.set_title("Change in replica state over time") ax.figure.savefig( # type: ignore filepath / (filename_prefix + "replica_state_timeseries.png") ) plt.close(ax.figure) # type: ignore # Replica exchange transition matrix if self.sampling_method == "repex": ax = plotting.plot_lambda_transition_matrix(self.replica_exchange_statistics["matrix"]) ax.set_title("Replica exchange transition matrix") ax.figure.savefig( # type: ignore filepath / (filename_prefix + "replica_exchange_matrix.png") ) plt.close(ax.figure) # type: ignore def _analyze(self, forward_reverse_samples: int): """ Run the following analyses: * MBAR free energy difference between end states using post-equilibration decorrelated samples of the energies. * Forward and reverse fractional analysis of free energies over the equilibrated & decorrelated data points. * MBAR estimate of the overlap matrix across states. * Replica exchange transition matrix (if sampler_method is ``repex``) Parameters ---------- forward_reverse_samples : int Number of samples to take in the forward and reverse analysis of the free energies. """ # Do things that get badly cached later self._replica_states = self.analyzer.reporter.read_replica_thermodynamic_states() # convert full masked array to simple array # downcast to int32, we don't have more than 4 billion states thankfully self._replica_states = np.asarray(self._replica_states, dtype=np.int32) # float conversions to avoid having to deal with numpy dtype serialization self._equil_iters = float(self.analyzer.n_equilibration_iterations) self._prod_iters = float(self.analyzer._equilibration_data[2]) # Gather estimate of free energy self._free_energy, self._free_energy_err = self.get_equil_free_energy() # forward and reverse analysis self._forward_reverse = self.get_forward_and_reverse_analysis(forward_reverse_samples) # Gather overlap matrix self._overlap_matrix = self.get_overlap_matrix() # Gather exchange transition matrix # Note we only generate these for replica exchange calculations # TODO: consider if this would also work for SAMS if self.sampling_method == "repex": self._exchange_matrix = self.get_exchanges() @staticmethod def _get_free_energy( analyzer: multistate.MultiStateSamplerAnalyzer, u_ln: npt.NDArray, N_l: npt.NDArray, bootstraps: int = 1000, return_units: Quantity = unit.kilocalorie_per_mole, ) -> tuple[Quantity, Quantity]: """ Helper method to create an MBAR object and extract free energies between end states. Parameters ---------- analyzer : multistate.MultiStateSamplerAnalyzer MultiStateSamplerAnalyzer to extract free energies from. u_ln : npt.NDArray A n_states x (n_sampled_states * n_iterations) array of energies (in kT). N_l : npt.NDArray An array containing the total number of samples drawn from each state. bootstraps : int How many bootstrap samples will be computed. If 0, no bootstraps will be computed and analytical errors will be returned. return_units : openff.units.Quantity The return units the results will be provided in. Returns ------- DG : openff.units.Quantity The free energy difference between the end states. dDG : openff.units.Quantity The MBAR bootstrap (1000 iterations) error estimate for the free energy difference. TODO ---- * Allow folks to pass in extra options for bootstrapping etc.. * Add standard test against analyzer.get_free_energy() """ # pymbar has some side effects when imported so we only import it right when we # need it from pymbar import MBAR mbar = MBAR( u_ln, N_l, solver_protocol="robust", n_bootstraps=bootstraps, bootstrap_solver_protocol="robust", ) if bootstraps > 0: uncertainty_method = "bootstrap" else: uncertainty_method = None r = mbar.compute_free_energy_differences( compute_uncertainty=True, uncertainty_method=uncertainty_method, ) DF_ij = r["Delta_f"] dDF_ij = r["dDelta_f"] DG = DF_ij[0, -1] * analyzer.kT dDG = dDF_ij[0, -1] * analyzer.kT return (from_openmm(DG).to(return_units), from_openmm(dDG).to(return_units)) def get_equil_free_energy(self) -> tuple[Quantity, Quantity]: """ Extract unbiased and uncorrelated estimates of the free energy and the associated error from a MultiStateSamplerAnalyzer object. Returns ------- DG : openff.units.Quantity The free energy difference between the end states. dDG : openff.units.Quantity The MBAR error for the free energy difference estimate. """ u_ln_decorr = self.analyzer._unbiased_decorrelated_u_ln N_l_decorr = self.analyzer._unbiased_decorrelated_N_l DG, dDG = self._get_free_energy(self.analyzer, u_ln_decorr, N_l_decorr, 1000, self.units) return DG, dDG def get_forward_and_reverse_analysis( self, num_samples: int = 10 ) -> Optional[dict[str, Union[npt.NDArray, Quantity]]]: """ Calculate free energies with a progressively larger fraction of the decorrelated timeseries data in both the forward and reverse direction. Parameters ---------- num_samples : int The number data points to sample. Returns ------- forward_reverse : Optional[dict[str, Union[npt.NDArray, openff.units.Quantity]]] If this analysis fails, returns None; otherwise returns a dictionary containing; * ``fractions``: fractions of sample used to calculate free energies * ``forward_DGs`` and `forward_dDGs`: the free energy estimates and errors along each sample fraction in the forward direction * ``reverse_DGs`` and `reverse_dDGs`: the free energy estimates and errors along each sample fraction in the reverse direction Notes ----- * This method does not currently use bootstrap uncertainties due to issues with the solver when using low amounts of data points. All uncertainties are MBAR analytical errors. """ # pymbar has some side effects from being imported, so we only want to import # it right when we need it from pymbar.utils import ParameterError try: u_ln = self.analyzer._unbiased_decorrelated_u_ln N_l = self.analyzer._unbiased_decorrelated_N_l n_states = len(N_l) # Check that the N_l is the same across all states if not np.all(N_l == N_l[0]): errmsg = f"The number of samples is not equivalent across all states {N_l}" raise ValueError(errmsg) # Get the chunks of N_l going from 10% to ~ 100% # Note: you always lose out a few data points but it's fine chunks = [max(int(N_l[0] / num_samples * i), 1) for i in range(1, num_samples + 1)] forward_DGs = [] forward_dDGs = [] reverse_DGs = [] reverse_dDGs = [] fractions = [] for chunk in chunks: new_N_l = np.array([chunk for _ in range(n_states)]) samples = chunk * n_states # Forward DG, dDG = self._get_free_energy( self.analyzer, u_ln[:, :samples], new_N_l, 0, self.units, ) forward_DGs.append(DG) forward_dDGs.append(dDG) # Reverse DG, dDG = self._get_free_energy( self.analyzer, u_ln[:, -samples:], new_N_l, 0, self.units, ) reverse_DGs.append(DG) reverse_dDGs.append(dDG) fractions.append(chunk / N_l[0]) except ParameterError: return None forward_reverse = { "fractions": np.array(fractions), "forward_DGs": Quantity.from_list(forward_DGs), # type: ignore "forward_dDGs": Quantity.from_list(forward_dDGs), # type: ignore "reverse_DGs": Quantity.from_list(reverse_DGs), # type: ignore "reverse_dDGs": Quantity.from_list(reverse_dDGs), # type: ignore } return forward_reverse def get_overlap_matrix(self) -> dict[str, npt.NDArray]: """ Generate an overlap matrix across lambda states. Return ------ overlap_matrix : dict[str, npt.NDArray] A dictionary containing the following keys: * ``scalar``: One minus the largest nontrivial eigenvalue * ``eigenvalues``: The sorted (descending) eigenvalues of the overlap matrix * ``matrix``: Estimated overlap matrix of observing a sample from state i in state j """ return self.analyzer.mbar.compute_overlap() def get_exchanges(self) -> dict[str, npt.NDArray]: """ Gather both the transition matrix (and relevant eigenvalues) between replicas. Return ------ transition_matrix : dict[str, npt.NDArray] A dictionary containing the following: * ``eigenvalues``: The sorted (descending) eigenvalues of the lambda state transition matrix * ``matrix``: The transition matrix estimate of a replica switching from state i to state j. """ # Get replica mixing statistics mixing_stats = self.analyzer.generate_mixing_statistics() transition_matrix = { "eigenvalues": mixing_stats.eigenvalues, "matrix": mixing_stats.transition_matrix, } return transition_matrix @property def replica_states(self): """ Timeseries of states for each replica. """ return self._replica_states @property def equilibration_iterations(self): """ Number of iterations discarded as equilibration. """ return self._equil_iters @property def production_iterations(self): """ Number of production iterations from which energies are sampled. """ return self._prod_iters @property def free_energy(self): """ The free energy estimate from decorrelated unbiased samples """ return self._free_energy @property def free_energy_error(self): """ The MBAR estimate of the free energy estimate """ return self._free_energy_err @property def forward_and_reverse_free_energies(self): """ The dictionary forward and reverse analysis of the free energies using the number of samples defined at class initialization """ return self._forward_reverse @property def free_energy_overlaps(self): """ A dictionary containing the estimated overlap matrix and corresponding eigenvalues and scalars of the free energies. """ return self._overlap_matrix @property def replica_exchange_statistics(self): """ A dictionary containing the estimated replica exchange matrix and corresponding eigenvalues. """ if hasattr(self, "_exchange_matrix"): return self._exchange_matrix else: errmsg = ( "Exchange matrix was not generated, this is likely " f"{self.sampling_method} is not repex." ) raise ValueError(errmsg) @property def unit_results_dict(self): results_dict = { "unit_estimate": self.free_energy, "unit_estimate_error": self.free_energy_error, "unit_mbar_overlap": self.free_energy_overlaps, "forward_and_reverse_energies": self.forward_and_reverse_free_energies, "production_iterations": self.production_iterations, "equilibration_iterations": self.equilibration_iterations, } if hasattr(self, "_exchange_matrix"): results_dict["replica_exchange_statistics"] = self.replica_exchange_statistics return results_dict def close(self): self.analyzer.clear() ================================================ FILE: src/openfe/protocols/openmm_utils/omm_compute.py ================================================ # This code is part of OpenFE and is licensed under the MIT license. # For details, see https://github.com/OpenFreeEnergy/openfe # Adapted Perses' perses.app.setup_relative_calculation.get_openmm_platform import logging import os import warnings from typing import Optional logger = logging.getLogger(__name__) def get_openmm_platform( platform_name: Optional[str] = None, gpu_device_index: Optional[list[int]] = None, restrict_cpu_count: bool = False, ): """ Return OpenMM's platform object based on given name. Setting to mixed precision if using CUDA or OpenCL. Parameters ---------- platform_name : Optional[str] String with the platform name. If None, it will use the fastest platform supporting mixed precision. Default ``None``. gpu_device_index : Optional[list[str]] GPU device index selection. If ``None`` the default OpenMM GPU selection will be used. See the `OpenMM platform properties documentation `_ for more details. Default ``None``. restrict_cpu_count : bool Optional hint to restrict the CPU count to 1 when ``platform_name`` is CPU. This allows Protocols to ensure that no large performance in cases like vacuum simulations. Returns ------- platform : openmm.Platform OpenMM platform object. """ if platform_name is None: # No platform is specified, so retrieve fastest platform that supports # 'mixed' precision from openmmtools.utils import get_fastest_platform platform = get_fastest_platform(minimum_precision="mixed") else: try: platform_name = { "cpu": "CPU", "opencl": "OpenCL", "cuda": "CUDA", }[str(platform_name).lower()] except KeyError: pass from openmm import Platform platform = Platform.getPlatformByName(platform_name) # Set precision and properties name = platform.getName() if name in ["CUDA", "OpenCL"]: platform.setPropertyDefaultValue("Precision", "mixed") if gpu_device_index is not None: index_list = ",".join(str(i) for i in gpu_device_index) platform.setPropertyDefaultValue("DeviceIndex", index_list) if name == "CUDA": platform.setPropertyDefaultValue("DeterministicForces", "true") if name != "CUDA": wmsg = ( f"Non-CUDA platform selected: {name}, this may significantly " "impact simulation performance" ) warnings.warn(wmsg) logging.warning(wmsg) if name == "CPU" and restrict_cpu_count: threads = os.getenv("OPENMM_CPU_THREADS", "1") platform.setPropertyDefaultValue("Threads", threads) return platform ================================================ FILE: src/openfe/protocols/openmm_utils/omm_settings.py ================================================ # This code is part of OpenFE and is licensed under the MIT license. # For details, see https://github.com/OpenFreeEnergy/openfe """Equilibrium Free Energy Protocols input settings. This module implements base settings necessary to run free energy calculations using OpenMM +/- Tools, such as :mod:`openfe.protocols.openmm_rfe.equil_rfe_methods.py` and :mod`openfe.protocols.openmm_afe.equil_afe_methods.py` """ from typing import Annotated, Literal, Optional, TypeAlias from gufe.settings import ( OpenMMSystemGeneratorFFSettings as OpenMMSystemGeneratorFFSettings, ) from gufe.settings import ( Settings as Settings, ) from gufe.settings import ( SettingsBaseModel, ) from gufe.settings import ( ThermoSettings as ThermoSettings, ) from gufe.settings.typing import ( BoxQuantity, GufeQuantity, KCalPerMolQuantity, NanometerArrayQuantity, NanometerQuantity, NanosecondQuantity, PicosecondQuantity, specify_quantity_units, ) from openff.interchange.components._packmol import _box_vectors_are_in_reduced_form from openff.units import unit from pydantic import ConfigDict, field_validator, model_validator FemtosecondQuantity: TypeAlias = Annotated[GufeQuantity, specify_quantity_units("femtosecond")] InversePicosecondQuantity: TypeAlias = Annotated[ GufeQuantity, specify_quantity_units("1/picosecond") ] TimestepQuantity: TypeAlias = Annotated[GufeQuantity, specify_quantity_units("timestep")] SurfaceTensionQuantity: TypeAlias = Annotated[GufeQuantity, specify_quantity_units("bar*nanometer")] class BaseSolvationSettings(SettingsBaseModel): """ Base class for SolvationSettings objects. """ model_config = ConfigDict(arbitrary_types_allowed=True) class OpenMMSolvationSettings(BaseSolvationSettings): """Settings for controlling how a system is solvated using OpenMM tooling. Defining the number of waters ----------------------------- The number of waters is controlled by either: a) defining a solvent padding (``solvent_padding``) in combination with a box shape b) defining the number of solvent molecules (``number_of_solvent_molecules``) alongside the box shape (``box_shape``) c) defining the box directly either through the box vectors (``box_vectors``) or rectangular box lengths (``box_size``) When using ``solvent_padding``, ``box_vectors``, or ``box_size``, the exact number of waters added is determined automatically by OpenMM through :meth:`openmm.app.Modeller.addSolvent` internal heuristics. Briefly, the necessary volume required by a single water is estimated and then the defined target cell is packed with waters avoiding clashes with existing solutes and box edges. Defining the periodic cell size ------------------------------- The periodic cell size is defined by one, and only one, of the following: * ``solvent_padding`` in combination with ``box_shape``, * ``number_of_solvent_molecules`` in combination with ``box_shape``, * ``box_vectors``, * ``box_size`` When using ``number_of_solvent_molecules``, the size of the cell is defined by :meth:`openmm.app.Modeller.addSolvent` internal heuristics, automatically selecting a padding value that is large enough to contain the number of waters based on a geometric estimate of the volume required by each water molecule. Defining the periodic cell shape --------------------------------- The periodic cell shape is defined by one, and only one, of the following: * ``box_shape``, * ``box_vectors``, * ``box_size`` Default settings will create a cubic box, although more space efficient shapes (e.g. ``dodecahedrons``) are recommended to improve simulation performance. Notes ----- * The number of water molecules added will be affected by the number of ions defined in SolventComponent. For example, the value of ``number_of_solvent_molecules`` is the sum of the number of counterions added and the number of water molecules added. * Solvent addition does not account for any pre-existing waters explicitly defined in the :class:`openfe.ChemicalSystem`. Any waters will be added in addition to those pre-existing waters. * No solvation will happen if a SolventComponent is not passed. See Also -------- :mod:`openmm.app.Modeller` Base class for SolvationSettings objects """ solvent_model: Literal["tip3p", "spce", "tip4pew", "tip5p"] = "tip3p" """ Force field water model to use when solvating and defining the model properties (e.g. adding virtual site particles). Allowed values are: ``tip3p``, ``spce``, ``tip4pew``, and ``tip5p``. """ solvent_padding: NanometerQuantity | None = 1.5 * unit.nanometer """ Minimum distance from any solute bounding sphere to the edge of the box. Note ---- * Cannot be defined alongside ``number_of_solvent_molecules``, ``box_size``, or ``box_vectors``. """ box_shape: Optional[Literal["cube", "dodecahedron", "octahedron"]] = "dodecahedron" """ The shape of the periodic box to create. Notes ----- * Must be one of `cube`, `dodecahedron`, or `octahedron`. * Cannot be defined alongside ``box_vectors`` or ``box_size``. """ number_of_solvent_molecules: Optional[int] = None """ The number of solvent molecules (water + ions) to add. Note ---- * Cannot be defined alongside ``solvent_padding``, ``box_size``, or ``box_vectors``. """ box_vectors: BoxQuantity | None = None """ `OpenMM reduced form box vectors `. Notes ----- * Cannot be defined alongside ``solvent_padding``, ``number_of_solvent_molecules``, or ``box_size``. See Also -------- :mod:`openff.interchange.components.interchange` :mod:`openff.interchange.components._packmol` """ box_size: NanometerArrayQuantity | None = None # TODO: make this a better check! """ X, Y, and Z lengths of the unit cell for a rectangular box. Notes ----- * Cannot be defined alongside ``solvent_padding``, ``number_of_solvent_molecules``, or ``box_vectors``. """ @field_validator("box_vectors") def supported_vectors(cls, v): if v is not None: if not _box_vectors_are_in_reduced_form(v): errmsg = f"box_vectors: {v} are not in OpenMM reduced form" raise ValueError(errmsg) return v @field_validator("solvent_padding") def is_positive_distance(cls, v): # these are time units, not simulation steps if v is None: return v if not v.is_compatible_with(unit.nanometer): raise ValueError("solvent_padding must be in distance units (i.e. nanometers)") if v < 0: errmsg = "solvent_padding must be a positive value" raise ValueError(errmsg) return v @field_validator("number_of_solvent_molecules") def positive_solvent_number(cls, v): if v is None: return v if v <= 0: errmsg = f"number_of_solvent molecules: {v} must be positive" raise ValueError(errmsg) return v @field_validator("box_size") def box_size_properties(cls, v): if v is None: return v if v.shape != (3,): errmsg = f"box_size must be a 1-D array of length 3 got {v} with shape {v.shape}" raise ValueError(errmsg) return v class BasePartialChargeSettings(SettingsBaseModel): """ Base class for partial charge assignment. """ model_config = ConfigDict(arbitrary_types_allowed=True) class OpenFFPartialChargeSettings(BasePartialChargeSettings): """ Settings for controlling partial charge assignment using the OpenFF tooling """ partial_charge_method: Literal["am1bcc", "am1bccelf10", "nagl", "espaloma"] = "am1bcc" """ Selection of method for partial charge generation. Description of options ---------------------- ``am1bcc``: Generate partial charges using the AM1-BCC approach, as detailed by Araz Jalkalian et al. J. Comp. Chem. 2000. AM1-BCC charges are either assigned using AmberTools (via SQM) if ``off_toolkit_backend`` is set to ``ambertools`, or using the OpenEye Toolkit (via Quacpac) if ``off_toolkit_backend`` is set to ``openeye``. A maximum of one conformer is allowed. ``am1bccelf10``: Assign AM1-BCC partialk charges using the `ELF10 method `_ This is only currently possible via the OpenEye toolkit if setting ``off_toolkit_backend`` to ``openeye``. We recommend setting ``number_of_conformers`` to at least `500`. ``nagl``: Assign partial charges using the `OpenFF NAGL ML method `_ All ``off_toolkit_backend`` options are supported. A maximum of one conformer is allowed. ``espaloma``: Assign partial charges using the `Espaloma Charge method `_ Only ``ambertools`` and ``rdkit`` `off_toolkit_backend`` options are supported. A maximum of one conformer is allowed. """ off_toolkit_backend: Literal["ambertools", "openeye", "rdkit"] = "ambertools" """ The OpenFF toolkit registry backend to use for partial charge generation. OpenFF backend selection options -------------------------------- ``ambertools``: This limits partial charge generation to using a mixture of AmberTools and RDKit. ``openeye``: This limits partial charge generation to using the OpenEye toolkit. This cannot be used with ``espaloma`` as the ``partial_charge_method`` ``rdkit``: This limits partial charge generation to using the RDKit toolkit. Note that this alone cannot be used for conventional am1bcc partial charge generation, but is usually used in combination with the ``nagl`` or ``espaloma`` ``partial_charge_method`` selections. """ number_of_conformers: Optional[int] = None """ Number of conformers to generate as part of the partial charge assignment. If ``None`` (default), the existing conformer of the input SmallMoleculeComponent will be used. Values greater than 1 or ``None`` are only allowed when calculating partial charges through ``am1bccelf10``. See ``partial_charge_method``'s ``Description of options`` documentation. """ nagl_model: Optional[str] = None """ The `NAGL `_ model to use for partial charge assignment. If ``None`` (default) and ``partial_charge_method`` is set to ``nagl``, the latest available production am1bcc charge model will be used. """ class OpenMMEngineSettings(SettingsBaseModel): """OpenMM MD engine settings""" """ TODO ---- * In the future make precision and deterministic forces user defined too. """ compute_platform: Optional[str] = "cuda" """ OpenMM compute platform to perform MD integration with. If ``None``, will choose fastest available platform. Allowed platforms are; ``cuda``, ``opencl``, ``cpu``. Default ``cuda``. """ gpu_device_index: Optional[list[int]] = None """ List of integer indices for the GPU device to select when ``compute_platform`` is either set to ``CUDA`` or ``OpenCL``. If ``None``, the default OpenMM GPU selection behaviour is used. See the `OpenMM platform properties documentation `_ for more details. Default ``None``. """ @field_validator("compute_platform") def supported_sampler(cls, v): supported = ["cpu", "opencl", "cuda"] if v is not None and v.lower() not in supported: errmsg = f"Only the following OpenMM compute backends are supported: {supported}" raise ValueError(errmsg) return v class IntegratorSettings(SettingsBaseModel): """Settings for the `LangevinDynamicsMove integrator `_. Note ---- For some Protocols, an MC "move" (e.g. replica exchange swap) is applied at a given frequency. In most Protocols the move frequency is defined in ``MultiStateSimulationSettings.time_per_iteration``. """ model_config = ConfigDict(arbitrary_types_allowed=True) timestep: FemtosecondQuantity = 4.0 * unit.femtosecond """Size of the simulation timestep in femtoseconds. Default 4.0 * unit.femtosecond.""" langevin_collision_rate: InversePicosecondQuantity = 1.0 / unit.picosecond """Collision frequency in picoseconds. Default 1.0 / unit.picosecond.""" reassign_velocities: bool = False """ If ``True``, velocities are reassigned from the Maxwell-Boltzmann distribution at the beginning of each MC move. Default ``False``. """ n_restart_attempts: int = 20 """ Number of attempts to restart from Context if there are NaNs in the energies after integration. Default 20. """ constraint_tolerance: float = 1e-06 """Tolerance for the constraint solver. Default 1e-6.""" barostat: Literal["MonteCarloBarostat", "MonteCarloMembraneBarostat"] = "MonteCarloBarostat" """ The barostat to be used in the simulations. Default MonteCarloBarostat. Notes ----- If the system contains a membrane, use the `MonteCarloMembraneBarostat`. """ barostat_frequency: TimestepQuantity = 25.0 * unit.timestep """ Frequency at which volume scaling changes should be attempted. Note: The barostat frequency is ignored for gas-phase simulations. Default 25 * unit.timestep. """ surface_tension: Optional[SurfaceTensionQuantity] = 0 * unit.bar * unit.nanometer """ The surface tension in bar*nm to define the `MonteCarloMembraneBarostat`. Default 0 * unit.bar * unit.nanometer. Notes ----- The `surface_tension` is ignored when the `MonteCarloMembraneBarostat` is not used. """ remove_com: bool = False """ Whether or not to remove the center of mass motion. Default ``False``. """ @field_validator("langevin_collision_rate", "n_restart_attempts") def must_be_positive_or_zero(cls, v): if v < 0: errmsg = ( "langevin_collision_rate, and n_restart_attempts must be" f" zero or positive values, got {v}." ) raise ValueError(errmsg) return v @field_validator("timestep", "constraint_tolerance") def must_be_positive(cls, v): if v <= 0: errmsg = f"timestep, and constraint_tolerance must be positive values, got {v}." raise ValueError(errmsg) return v @field_validator("timestep") def is_time(cls, v): # these are time units, not simulation steps if not v.is_compatible_with(unit.picosecond): raise ValueError("timestep must be in time units (i.e. picoseconds)") return v @field_validator("langevin_collision_rate") def must_be_inverse_time(cls, v): if not v.is_compatible_with(1 / unit.picosecond): raise ValueError("langevin collision_rate must be in inverse time (i.e. 1/picoseconds)") return v @model_validator(mode="after") def validate_surface_tension(self): if self.barostat == "MonteCarloMembraneBarostat" and self.surface_tension is None: raise ValueError( "surface_tension must be set (may be zero) when using MonteCarloMembraneBarostat" ) if self.barostat == "MonteCarloBarostat" and self.surface_tension: raise ValueError( "Got a nonzero surface_tension which is not allowed when using " f"the MonteCarloBarostat. Got surface_tension {self.surface_tension}" ) return self class OutputSettings(SettingsBaseModel): """ Settings for simulation output settings, writing to disk, etc... """ model_config = ConfigDict(arbitrary_types_allowed=True) # reporter settings output_indices: str = "not water" """ Selection string for which part of the system to write coordinates for. Default 'not water'. """ checkpoint_interval: NanosecondQuantity = 1.0 * unit.nanosecond """ Frequency to write the checkpoint file. Default 1 * unit.nanosecond. """ checkpoint_storage_filename: str = "checkpoint.chk" """ Separate filename for the checkpoint file. Note, this should not be a full path, just a filename. Default 'checkpoint.chk'. """ forcefield_cache: Optional[str] = "db.json" """ Filename for caching small molecule residue templates so they can be later reused. """ @field_validator("checkpoint_interval") def must_be_positive(cls, v): if v <= 0: errmsg = f"Checkpoint intervals must be positive, got {v}." raise ValueError(errmsg) return v class MultiStateOutputSettings(OutputSettings): """ Settings for MultiState simulation output settings, writing to disk, etc... """ model_config = ConfigDict(arbitrary_types_allowed=True) # reporter settings output_filename: str = "simulation.nc" """Path to the trajectory storage file. Default 'simulation.nc'.""" output_structure: str = "hybrid_system.pdb" """ Path of the output hybrid topology structure file. This is used to visualise and further manipulate the system. Default 'hybrid_system.pdb'. """ positions_write_frequency: PicosecondQuantity | None = 100.0 * unit.picosecond """ Frequency at which positions are written to the simulation trajectory storage file (defined by ``output_filename``). If ``None``, no positions will be written to the trajectory. Unless set to ``None``, must be divisible by ``MultiStateSimulationSettings.time_per_iteration``. """ velocities_write_frequency: PicosecondQuantity | None = None """ Frequency at which velocities are written to the simulation trajectory storage file (defined by ``output_filename``). If ``None`` (default), no velocities will be written to the trajectory. Unless set to ``None``, must be divisible by ``MultiStateSimulationSettings.time_per_iteration``. """ @field_validator("positions_write_frequency", "velocities_write_frequency") def must_be_positive(cls, v): if v is not None and v < 0: errmsg = ( "Position_write_frequency and velocities_write_frequency" f" must be positive (or None), got {v}." ) raise ValueError(errmsg) return v class SimulationSettings(SettingsBaseModel): """ Settings for simulation control, including lengths, etc... """ model_config = ConfigDict(arbitrary_types_allowed=True) minimization_steps: int = 5000 """Number of minimization steps to perform. Default 5000.""" equilibration_length: NanosecondQuantity """ Length of the equilibration phase in units of time. Must be divisible by the :class:`IntegratorSettings.timestep`. """ production_length: NanosecondQuantity """ Length of the production phase in units of time. Must be divisible by the :class:`IntegratorSettings.timestep`. """ @field_validator("equilibration_length", "production_length") def is_time(cls, v): # these are time units, not simulation steps if not v.is_compatible_with(unit.picosecond): raise ValueError("Durations must be in time units") return v @field_validator("minimization_steps", "equilibration_length", "production_length") def must_be_positive(cls, v): if v <= 0: errmsg = f"Minimization steps, and MD lengths must be positive, got {v}" raise ValueError(errmsg) return v class MultiStateSimulationSettings(SimulationSettings): """ Settings for simulation control for multistate simulations, including simulation length and details of the alchemical sampler. """ """ TODO ---- * It'd be great if we could pass in the sampler object rather than using strings to define which one we want. * Make n_replicas optional such that: If ``None`` or greater than the number of lambda windows set in :class:`LambdaSettings`, this will default to the number of lambda windows. If less than the number of lambda windows, the replica lambda states will be picked at equidistant intervals along the lambda schedule. """ model_config = ConfigDict(arbitrary_types_allowed=True) sampler_method: str = "repex" """ Alchemical sampling method, must be one of; `repex` (Hamiltonian Replica Exchange), `sams` (Self-Adjusted Mixture Sampling), or `independent` (independently sampled lambda windows). Default `repex`. """ time_per_iteration: PicosecondQuantity = 2.5 * unit.picosecond # todo: Add validators in the protocol """ Simulation time between each MCMC move attempt. Default 2.5 * unit.picosecond. """ real_time_analysis_interval: PicosecondQuantity | None = 250.0 * unit.picosecond # todo: Add validators in the protocol """ Time interval at which to perform an analysis of the free energies. At each interval, real time analysis data (e.g. current free energy estimate and timing data) will be written to a yaml file named ``_real_time_analysis.yaml``. The current error in the estimate will also be assessed and if it drops below ``MultiStateSimulationSettings.early_termination_target_error`` the simulation will be terminated. If ``None``, no real time analysis will be performed and the yaml file will not be written. Default `250`. """ early_termination_target_error: KCalPerMolQuantity | None = 0.0 * unit.kilocalorie_per_mole # todo: have default ``None`` or ``0.0 * unit.kilocalorie_per_mole`` # (later would give an example of unit). """ Target error for the real time analysis measured in kcal/mol. Once the MBAR error of the free energy is at or below this value, the simulation will be considered complete. A suggested value of 0.12 * `unit.kilocalorie_per_mole` has shown to be effective in both hydration and binding free energy benchmarks. Default ``None``, i.e. no early termination will occur. """ real_time_analysis_minimum_time: PicosecondQuantity = 500.0 * unit.picosecond # todo: Add validators in the protocol """ Simulation time which must pass before real time analysis is carried out. Default 500 * unit.picosecond. """ sams_flatness_criteria: str = "logZ-flatness" """ SAMS only. Method for assessing when to switch to asymptomatically optimal scheme. One of ['logZ-flatness', 'minimum-visits', 'histogram-flatness']. Default 'logZ-flatness'. """ sams_gamma0: float = 1.0 """SAMS only. Initial weight adaptation rate. Default 1.0.""" n_replicas: int = 11 """Number of replicas to use. Default 11.""" @field_validator("sams_flatness_criteria") def supported_flatness(cls, v): supported = ["logz-flatness", "minimum-visits", "histogram-flatness"] if v.lower() not in supported: errmsg = f"Only the following sams_flatness_criteria are supported: {supported}" raise ValueError(errmsg) return v @field_validator("sampler_method") def supported_sampler(cls, v): supported = ["repex", "sams", "independent"] if v.lower() not in supported: errmsg = f"Only the following sampler_method values are supported: {supported}" raise ValueError(errmsg) return v @field_validator("n_replicas", "time_per_iteration") def must_be_positive(cls, v): if v <= 0: errmsg = f"n_replicas and steps_per_iteration must be positive values, got {v}." raise ValueError(errmsg) return v @field_validator( "early_termination_target_error", "real_time_analysis_minimum_time", "sams_gamma0", "n_replicas", ) def must_be_zero_or_positive(cls, v): if v < 0: errmsg = ( "Early termination target error, minimum iteration and" f" SAMS gamma0 must be 0 or positive values, got {v}." ) raise ValueError(errmsg) return v class MDSimulationSettings(SimulationSettings): """ Settings for simulation control for plain MD simulations """ model_config = ConfigDict(arbitrary_types_allowed=True) equilibration_length_nvt: NanosecondQuantity | None """ Length of the equilibration phase in the NVT ensemble in units of time. The total number of steps from this equilibration length (i.e. ``equilibration_length_nvt`` / :class:`IntegratorSettings.timestep`). If None, no NVT equilibration will be performed. """ class MDOutputSettings(OutputSettings): """Settings for simulation output settings for plain MD simulations.""" model_config = ConfigDict(arbitrary_types_allowed=True) # reporter settings production_trajectory_filename: Optional[str] = "simulation.xtc" """Path to the storage file for analysis. Default 'simulation.xtc'.""" trajectory_write_interval: PicosecondQuantity = 20.0 * unit.picosecond """ Frequency to write the xtc file. Default 5000 * unit.timestep. """ preminimized_structure: Optional[str] = "system.pdb" """Path to the pdb file of the full pre-minimized system. Default 'system.pdb'.""" minimized_structure: Optional[str] = "minimized.pdb" """Path to the pdb file of the system after minimization. Only the specified atom subset is saved. Default 'minimized.pdb'.""" equil_nvt_structure: Optional[str] = "equil_nvt.pdb" """Path to the pdb file of the system after NVT equilibration. Only the specified atom subset is saved. Default 'equil_nvt.pdb'.""" equil_npt_structure: Optional[str] = "equil_npt.pdb" """Path to the pdb file of the system after NPT equilibration. Only the specified atom subset is saved. Default 'equil_npt.pdb'.""" log_output: Optional[str] = "simulation.log" """ Filename for writing the log of the MD simulation, including timesteps, energies, density, etc. """ ================================================ FILE: src/openfe/protocols/openmm_utils/serialization.py ================================================ # This code is part of OpenFE and is licensed under the MIT license. # For details, see https://github.com/OpenFreeEnergy/openfe import os import pathlib from gufe.settings.typing import NanometerArrayQuantity from openff.units import Quantity from openmm import Vec3 from openmm import unit as ommunit def serialize(item, filename: pathlib.Path): """ Serialize an OpenMM System, State, or Integrator. Parameters ---------- item : System, State, or Integrator The thing to be serialized filename : str The filename to serialize to """ from openmm import XmlSerializer # Create parent directory if it doesn't exist filename_basedir = filename.parent if not filename_basedir.exists(): os.makedirs(filename_basedir) if filename.suffix == ".bz2": import bz2 with bz2.open(filename, mode="wb") as outfile: serialized_thing = XmlSerializer.serialize(item) outfile.write(serialized_thing.encode()) else: with open(filename, mode="w") as outfile: serialized_thing = XmlSerializer.serialize(item) outfile.write(serialized_thing) def deserialize(filename: pathlib.Path): """ Deserialize an OpenMM System, State, or Integrator. Parameters ---------- item : System, State, or Integrator The thing to be serialized filename : str The filename to serialize to """ from openmm import XmlSerializer # Create parent directory if it doesn't exist filename_basedir = filename.parent if not filename_basedir.exists(): os.makedirs(filename_basedir) if filename.suffix == ".bz2": import bz2 with bz2.open(filename, mode="rb") as infile: serialized_thing = infile.read().decode() item = XmlSerializer.deserialize(serialized_thing) else: with open(filename) as infile: serialized_thing = infile.read() item = XmlSerializer.deserialize(serialized_thing) return item def make_vec3_box(dimensions: NanometerArrayQuantity) -> Vec3: """ Convert an OpenFF box dimensions Quantity back into Vec3 format. Parameters ---------- dimensions : gufe.settings.typing.NanometerArrayQuantity United array to turn to Vec3 format. Returns ------- openmm.Vec3 The input array in Vec3 format. """ return [ Vec3(float(row[0]), float(row[1]), float(row[2])) * ommunit.nanometer for row in dimensions.m_as("nanometer") ] ================================================ FILE: src/openfe/protocols/openmm_utils/settings_validation.py ================================================ # This code is part of OpenFE and is licensed under the MIT license. # For details, see https://github.com/OpenFreeEnergy/openfe """ Reusable utility methods to validate input settings to OpenMM-based alchemical Protocols. """ from typing import Optional from openff.units import Quantity, unit from openfe.protocols.openmm_utils.omm_settings import OpenMMSolvationSettings from .omm_settings import ( IntegratorSettings, MultiStateSimulationSettings, ) def validate_openmm_solvation_settings(settings: OpenMMSolvationSettings) -> None: """ Checks that the OpenMMSolvation settings are correct. Raises ------ ValueError If more than one of ``solvent_padding``, ``number_of_solvent_molecules``, ``box_vectors``, or ``box_size`` are defined. If ``box_shape`` is defined alongside either ``box_vectors``, or ``box_size``. """ unique_attributes = ( settings.solvent_padding, settings.number_of_solvent_molecules, settings.box_vectors, settings.box_size, ) if len([x for x in unique_attributes if x is not None]) > 1: errmsg = ( "Only one of solvent_padding, number_of_solvent_molecules, " "box_vectors, and box_size can be defined in the solvation " "settings." ) raise ValueError(errmsg) if settings.box_shape is not None: if settings.box_size is not None or settings.box_vectors is not None: errmsg = ( "box_shape cannot be defined alongside either box_size " "or box_vectors in the solvation settings." ) raise ValueError(errmsg) def validate_timestep(hmass: float, timestep: Quantity): """ Check that the input timestep is suitable for the given hydrogen mass. Parameters ---------- hmass : float The target hydrogen mass (assumed units of amu). timestep : openff.units.Quantity The integration time step. Raises ------ ValueError If the hydrogen mass is less than 3 amu and the timestep is greater than 2 fs. """ if hmass < 3.0: if timestep > 2.0 * unit.femtoseconds: errmsg = f"timestep {timestep} too large for hydrogen mass {hmass}" raise ValueError(errmsg) def get_simsteps(sim_length: Quantity, timestep: Quantity, mc_steps: int) -> int: """ Gets and validates the number of simulation steps. Parameters ---------- sim_length : openff.units.Quantity Simulation length. timestep : openff.units.Quantity Integration timestep. mc_steps : int Number of integration timesteps between MCMC moves. Returns ------- sim_steps : int The number of simulation timesteps. """ sim_time = round(sim_length.to("attosecond").m) # type: ignore ts = round(timestep.to("attosecond").m) # type: ignore sim_steps, mod = divmod(sim_time, ts) if mod != 0: raise ValueError("Simulation time not divisible by timestep") if (sim_steps % mc_steps) != 0: errmsg = ( f"Simulation time {sim_time / 1000000} ps should contain a " "number of steps divisible by the number of integrator " f"timesteps between MC moves {mc_steps}" ) raise ValueError(errmsg) return sim_steps def divmod_time( time: Quantity, time_per_iteration: Quantity, ) -> tuple[int, int]: """ Convert a set amount of time to a number of iterations. Parameters --------- time: openff.units.Quantity The time to convert. time_per_iteration : openff.units.Quantity The amount of time which each iteration takes. Returns ------- iterations : int The number of iterations covered by the input time. remainder : int The remainder of the input time and time_per_iteration division. """ time_ats = round(time.to(unit.attosecond).m) # type: ignore tpi_ats = round(time_per_iteration.to(unit.attosecond).m) # type: ignore iterations, remainder = divmod(time_ats, tpi_ats) return iterations, remainder def divmod_time_and_check( numerator: Quantity, denominator: Quantity, numerator_name: str, denominator_name: str ) -> int: """Perform a division of time, failing if there is a remainder For example numerator 20.0 ps and denominator 4.0 fs gives 5000 Parameters ---------- numerator, denominator : openff.units.Quantity the division to perform numerator_name, denominator_name : str used for the error generated if there is any remainder Returns ------- iterations : int the result of the division Raises ------ ValueError if the division results in any remainder, will include a formatted error message """ its, rem = divmod_time(numerator, denominator) if rem: errmsg = ( f"The {numerator_name} ({numerator}) " "does not evenly divide by the " f"{denominator_name} ({denominator})" ) raise ValueError(errmsg) return its def convert_checkpoint_interval_to_iterations( checkpoint_interval: Quantity, time_per_iteration: Quantity, ) -> int: """ Get the number of iterations per checkpoint interval. This is necessary as our input settings define checkpoints intervals in units of time, but OpenMMTools' MultiStateReporter requires them defined in the number of MC intervals. Parameters ---------- checkpoint_interval : openff.units.Quantity The amount of time per checkpoints written. time_per_iteration : openff.units.Quantity The amount of time each MC iteration takes. Returns ------- iterations : int The number of iterations per checkpoint. """ iterations, rem = divmod_time(checkpoint_interval, time_per_iteration) if rem: errmsg = ( f"The amount of time per checkpoint {checkpoint_interval} " "does not evenly divide by the amount of time per " f"state MCMC move attempt {time_per_iteration}" ) raise ValueError(errmsg) return iterations def convert_steps_per_iteration( simulation_settings: MultiStateSimulationSettings, integrator_settings: IntegratorSettings, ) -> int: """Convert time per iteration to steps Parameters ---------- simulation_settings: MultiStateSimulationSettings integrator_settings: IntegratorSettings Returns ------- steps_per_iteration : int suitable for input to Integrator """ return divmod_time_and_check( simulation_settings.time_per_iteration, integrator_settings.timestep, "time_per_iteration", "timestep", ) def convert_real_time_analysis_iterations( simulation_settings: MultiStateSimulationSettings, ) -> tuple[Optional[int], Optional[int]]: """Convert time units in Settings to various other units Internally openmmtools uses various quantities with units of time, steps, and iterations. Our Settings objects instead have things defined in time (fs or ps). This function generates suitable inputs for the openmmtools objects Parameters ---------- simulation_settings: MultiStateSimulationSettings Returns ------- real_time_analysis_iterations : Optional[int] suitable for input to online_analysis_interval real_time_analysis_minimum_iterations : Optional[int] suitable for input to real_time_analysis_minimum_iterations """ if simulation_settings.real_time_analysis_interval is None: # option to turn off real time analysis return None, None rta_its = divmod_time_and_check( simulation_settings.real_time_analysis_interval, simulation_settings.time_per_iteration, "real_time_analysis_interval", "time_per_iteration", ) rta_min_its = divmod_time_and_check( simulation_settings.real_time_analysis_minimum_time, simulation_settings.time_per_iteration, "real_time_analysis_minimum_time", "time_per_iteration", ) return rta_its, rta_min_its def convert_target_error_from_kcal_per_mole_to_kT( temperature, target_error, ) -> float: """Convert kcal/mol target error to kT units If target_error is 0.0, returns 0.0 Parameters ---------- temperature : openff.units.Quantity temperature in K target_error : openff.units.Quantity error in kcal/mol Returns ------- early_termination_target_error : float in units of kT, suitable for input as "online_analysis_target_error" in a Sampler """ if target_error: kB = 0.001987204 * unit.kilocalorie_per_mole / unit.kelvin kT = temperature * kB early_termination_target_error = target_error / kT else: return 0.0 return early_termination_target_error.m ================================================ FILE: src/openfe/protocols/openmm_utils/system_creation.py ================================================ # This code is part of OpenFE and is licensed under the MIT license. # For details, see https://github.com/OpenFreeEnergy/openfe """ Reusable utility methods to create Systems for OpenMM-based alchemical Protocols. """ from pathlib import Path from typing import Optional import numpy as np import numpy.typing as npt from gufe import ( BaseSolventComponent, Component, ProteinComponent, ProteinMembraneComponent, SmallMoleculeComponent, SolvatedPDBComponent, SolventComponent, ) from gufe.settings import OpenMMSystemGeneratorFFSettings, ThermoSettings from openff.toolkit import Molecule as OFFMol from openff.units.openmm import ensure_quantity, to_openmm from openmm import MonteCarloBarostat, MonteCarloMembraneBarostat, app from openmm import unit as omm_unit from openmmforcefields.generators import SystemGenerator from openfe.protocols.openmm_utils.omm_settings import ( IntegratorSettings, OpenMMSolvationSettings, ) def get_system_generator( forcefield_settings: OpenMMSystemGeneratorFFSettings, thermo_settings: ThermoSettings, integrator_settings: IntegratorSettings, cache: Optional[Path], has_solvent: bool, ) -> SystemGenerator: """ Create a SystemGenerator based on Protocol settings. Parameters --------- forcefield_settings : OpenMMSystemGeneratorFFSettings Force field settings, including necessary information for constraints, hydrogen mass, rigid waters, non-ligand FF xmls, and the ligand FF name. thermo_settings : ThermoSettings Thermodynamic settings, including necessary settings for defining the ensemble conditions. integrator_settings : IntegratorSettings Integrator settings, including barostat control variables and COM removal. cache : Optional[pathlib.Path] Path to openff force field cache. has_solvent : bool Whether or not the target system has solvent (and by extension might require a barostat). Returns ------- system_generator : openmmforcefields.generator.SystemGenerator System Generator to use for this Protocol. TODO ---- * Investigate how RF can be passed to non-periodic kwargs. """ # get the right constraint constraints = { "hbonds": app.HBonds, "none": None, "allbonds": app.AllBonds, "hangles": app.HAngles, # vvv can be None so string it }[str(forcefield_settings.constraints).lower()] # create forcefield_kwargs entry forcefield_kwargs = { "constraints": constraints, "rigidWater": forcefield_settings.rigid_water, "removeCMMotion": integrator_settings.remove_com, "hydrogenMass": forcefield_settings.hydrogen_mass * omm_unit.amu, } # get the right nonbonded method nonbonded_method = { "pme": app.PME, "nocutoff": app.NoCutoff, "cutoffnonperiodic": app.CutoffNonPeriodic, "cutoffperiodic": app.CutoffPeriodic, "ewald": app.Ewald, }[forcefield_settings.nonbonded_method.lower()] nonbonded_cutoff = to_openmm( forcefield_settings.nonbonded_cutoff, ) # create the periodic_kwarg entry periodic_kwargs = { "nonbondedMethod": nonbonded_method, "nonbondedCutoff": nonbonded_cutoff, } # Currently the else is a dead branch, we will want to investigate the # possibility of using CutoffNonPeriodic at some point though (for RF) if nonbonded_method is not app.CutoffNonPeriodic: nonperiodic_kwargs = { "nonbondedMethod": app.NoCutoff, } else: # pragma: no-cover nonperiodic_kwargs = periodic_kwargs # Add barostat if necessary # For membrane systems, add a MonteCarloMembraneBarostat. if has_solvent: if integrator_settings.barostat == "MonteCarloMembraneBarostat": barostat = MonteCarloMembraneBarostat( ensure_quantity(thermo_settings.pressure, "openmm"), to_openmm(integrator_settings.surface_tension), ensure_quantity(thermo_settings.temperature, "openmm"), MonteCarloMembraneBarostat.XYIsotropic, MonteCarloMembraneBarostat.ZFree, integrator_settings.barostat_frequency.m, ) else: barostat = MonteCarloBarostat( ensure_quantity(thermo_settings.pressure, "openmm"), ensure_quantity(thermo_settings.temperature, "openmm"), integrator_settings.barostat_frequency.m, ) else: barostat = None system_generator = SystemGenerator( forcefields=forcefield_settings.forcefields, small_molecule_forcefield=forcefield_settings.small_molecule_forcefield, forcefield_kwargs=forcefield_kwargs, nonperiodic_forcefield_kwargs=nonperiodic_kwargs, periodic_forcefield_kwargs=periodic_kwargs, cache=str(cache) if cache is not None else None, barostat=barostat, ) return system_generator ModellerReturn = tuple[app.Modeller, dict[Component, npt.NDArray]] def get_omm_modeller( protein_comp: Optional[ProteinComponent], solvent_comp: Optional[BaseSolventComponent], small_mols: dict[SmallMoleculeComponent, OFFMol], omm_forcefield: app.ForceField, solvent_settings: OpenMMSolvationSettings, ) -> ModellerReturn: """ Generate an OpenMM Modeller class based on a potential input ProteinComponent, SolventComponent, and a set of small molecules. Parameters ---------- protein_comp : Optional[ProteinComponent] Protein Component, if it exists. solvent_comp : Optional[BaseSolventComponent] Base Solvent Component, if it exists. small_mols : dict Small molecules to add. omm_forcefield : app.ForceField ForceField object for system. solvent_settings : SolvationSettings Solvation settings. Returns ------- system_modeller : app.Modeller OpenMM Modeller object generated from ProteinComponent and OpenFF Molecules. component_resids : dict[Component, npt.NDArray] Dictionary of residue indices for each component in system. """ component_resids = {} def _add_small_mol( comp, mol, system_modeller: app.Modeller, comp_resids: dict[Component, npt.NDArray] ): """ Helper method to add OFFMol to an existing Modeller object and update a dictionary tracking residue indices for each component. """ omm_top = mol.to_topology().to_openmm() system_modeller.add(omm_top, ensure_quantity(mol.conformers[0], "openmm")) nres = omm_top.getNumResidues() resids = [res.index for res in system_modeller.topology.residues()] comp_resids[comp] = np.array(resids[-nres:]) # Create empty modeller system_modeller = app.Modeller(app.Topology(), []) # If there's a protein in the system, we add it first to the Modeller if protein_comp is not None: system_modeller.add(protein_comp.to_openmm_topology(), protein_comp.to_openmm_positions()) # add missing virtual particles (from crystal waters) system_modeller.addExtraParticles(omm_forcefield) component_resids[protein_comp] = np.array( [r.index for r in system_modeller.topology.residues()] ) # if we solvate temporarily rename water molecules to 'WAT' # see openmm issue #4103 if isinstance(solvent_comp, SolventComponent): for r in system_modeller.topology.residues(): if r.name == "HOH": r.name = "WAT" # Now loop through small mols for comp, mol in small_mols.items(): _add_small_mol(comp, mol, system_modeller, component_resids) # Add solvent if needed if isinstance(solvent_comp, SolventComponent): # Do unit conversions if necessary solvent_padding = None box_size = None box_vectors = None if solvent_settings.solvent_padding is not None: solvent_padding = to_openmm(solvent_settings.solvent_padding) if solvent_settings.box_size is not None: box_size = to_openmm(solvent_settings.box_size) if solvent_settings.box_vectors is not None: box_vectors = to_openmm(solvent_settings.box_vectors) system_modeller.addSolvent( omm_forcefield, model=solvent_settings.solvent_model, padding=solvent_padding, positiveIon=solvent_comp.positive_ion, negativeIon=solvent_comp.negative_ion, ionicStrength=to_openmm(solvent_comp.ion_concentration), neutralize=solvent_comp.neutralize, boxSize=box_size, boxVectors=box_vectors, boxShape=solvent_settings.box_shape, numAdded=solvent_settings.number_of_solvent_molecules, ) all_resids = np.array([r.index for r in system_modeller.topology.residues()]) existing_resids = np.concatenate([resids for resids in component_resids.values()]) component_resids[solvent_comp] = np.setdiff1d(all_resids, existing_resids) # undo rename of pre-existing waters for r in system_modeller.topology.residues(): if r.name == "WAT": r.name = "HOH" # If we are working with a presolvated system (with solvent # already added) and we have predefined box vectors, then skip solvation # with Modeller and set box vectors. elif isinstance(solvent_comp, SolvatedPDBComponent): # Set the periodic box vectors system_modeller.topology.setPeriodicBoxVectors(to_openmm(solvent_comp.box_vectors)) return system_modeller, component_resids ================================================ FILE: src/openfe/protocols/openmm_utils/system_validation.py ================================================ # This code is part of OpenFE and is licensed under the MIT license. # For details, see https://github.com/OpenFreeEnergy/openfe """ Reusable utility methods to validate input systems to OpenMM-based alchemical Protocols. """ import logging import warnings from typing import Optional, Tuple import numpy as np import openmm from gufe import ( BaseSolventComponent, ChemicalSystem, Component, ProteinComponent, ProteinMembraneComponent, SmallMoleculeComponent, SolvatedPDBComponent, SolventComponent, ) from gufe.components.errors import ComponentValidationError from openff.toolkit import Molecule as OFFMol logger = logging.getLogger(__name__) def get_alchemical_components( stateA: ChemicalSystem, stateB: ChemicalSystem, ) -> dict[str, list[Component]]: """ Checks the equality between Components of two end state ChemicalSystems and identify which components do not match. Parameters ---------- stateA : ChemicalSystem The chemical system of end state A. stateB : ChemicalSystem The chemical system of end state B. Returns ------- alchemical_components : dict[str, list[Component]] Dictionary containing a list of alchemical components for each state. Raises ------ ValueError If there are any duplicate components in states A or B. """ matched_components: dict[Component, Component] = {} alchemical_components: dict[str, list[Component]] = { "stateA": [], "stateB": [], } for keyA, valA in stateA.components.items(): for keyB, valB in stateB.components.items(): if valA == valB: if valA not in matched_components.keys(): matched_components[valA] = valB else: # Could be that either we have a duplicate component # in stateA or in stateB errmsg = ( f"state A components {keyA}: {valA} matches " "multiple components in stateA or stateB" ) raise ValueError(errmsg) # populate stateA alchemical components for valA in stateA.components.values(): if valA not in matched_components.keys(): alchemical_components["stateA"].append(valA) # populate stateB alchemical components for valB in stateB.components.values(): if valB not in matched_components.values(): alchemical_components["stateB"].append(valB) return alchemical_components def validate_solvent(state: ChemicalSystem, nonbonded_method: str): """ Checks that the ChemicalSystem component has the right solvent composition for an input nonbonded_methtod. Supported configurations are: * Vacuum (no BaseSolventComponent) * One BaseSolventComponent * One SolventComponent paired with one SolvatedPDBComponent Parameters ---------- state : ChemicalSystem The chemical system to inspect. nonbonded_method : str The nonbonded method to be applied for the simulation. Raises ------ ValueError * If there are more than two BaseSolventComponents in the ChemicalSystem. * If there are multiple SolventComponents or SolvatedPDBComponents in the ChemicalSystem. * If `nocutoff` is requested with any BaseSolventComponent present. * If there is no BaseSolventComponent and the `nonbonded_method` is `pme`. * If the SolventComponent solvent is not water. """ nb_method = nonbonded_method.lower() base_solv_comps = state.get_components_of_type(BaseSolventComponent) solvation_comps = state.get_components_of_type(SolventComponent) solvated_comps = state.get_components_of_type(SolvatedPDBComponent) if len(solvated_comps) > 1: raise ValueError("Multiple SolvatedPDBComponent found, only one is supported") if len(solvation_comps) > 1: raise ValueError("Multiple SolventComponent found, only one is supported") # Any BaseSolventComponent present → nocutoff is invalid if base_solv_comps and nb_method == "nocutoff": raise ValueError("nocutoff cannot be used for solvent transformations") # Vacuum transform if not base_solv_comps: if nb_method == "pme": raise ValueError("PME cannot be used for vacuum transform") return # Solvent-specific checks if solvation_comps: solvent = solvation_comps[0] if solvent.smiles != "O": raise ValueError("Non water solvent is not currently supported") def validate_protein(state: ChemicalSystem): """ Checks that the ChemicalSystem's ProteinComponent are suitable for the alchemical protocol. Parameters ---------- state : ChemicalSystem The chemical system to inspect. Raises ------ ValueError If there are multiple ProteinComponent in the ChemicalSystem. """ prot_comps = state.get_components_of_type(ProteinComponent) if len(prot_comps) > 1: errmsg = "Multiple ProteinComponent found, only one is supported" raise ValueError(errmsg) def validate_barostat(state: ChemicalSystem, barostat: str): """ Warn if there is a mismatch between the protein component type and barostat. A ProteinMembraneComponent should generally be simulated with a MonteCarloMembraneBarostat, while non-membrane protein systems should use a MonteCarloBarostat. Parameters ---------- state : ChemicalSystem The chemical system to inspect. barostat: str The barostat to be applied to the simulation """ prot_comps = state.get_components_of_type(ProteinComponent) protein_membrane = state.get_components_of_type(ProteinMembraneComponent) if not prot_comps: return if protein_membrane: if barostat != "MonteCarloMembraneBarostat": wmsg = ( "A ProteinMembraneComponent is present, but a membrane-specific " "barostat (MonteCarloMembraneBarostat) is not specified. If you " "are simulating a system with a membrane, consider using " "integrator_settings.barostat='MonteCarloMembraneBarostat'." ) warnings.warn(wmsg) logger.warning(wmsg) elif barostat == "MonteCarloMembraneBarostat": wmsg = ( "A MonteCarloMembraneBarostat is specified, but no " "ProteinMembraneComponent is present. If you are not simulating a " "membrane system, consider using " "integrator_settings.barostat='MonteCarloBarostat'." ) warnings.warn(wmsg) logger.warning(wmsg) ParseCompRet = Tuple[ Optional[SolventComponent], Optional[ProteinComponent], list[SmallMoleculeComponent], ] def get_components(state: ChemicalSystem) -> ParseCompRet: """ Establish all necessary Components for the transformation. Parameters ---------- state : ChemicalSystem ChemicalSystem to get all necessary components from. Returns ------- solvent_comp : Optional[SolventComponent] If it exists, the SolventComponent for the state, otherwise None. protein_comp : Optional[ProteinComponent] If it exists, the ProteinComponent for the state, otherwise None. small_mols : list[SmallMoleculeComponent] """ def _get_single_comps(state, comptype): comps = state.get_components_of_type(comptype) if len(comps) > 0: return comps[0] else: return None solvent_comp: Optional[SolventComponent] = _get_single_comps(state, SolventComponent) protein_comp: Optional[ProteinComponent] = _get_single_comps(state, ProteinComponent) small_mols = state.get_components_of_type(SmallMoleculeComponent) return solvent_comp, protein_comp, small_mols def assert_multistate_system_equality( ref_system: openmm.System, stored_system: openmm.System, ): """ Verify the equality of a MultiStateReporter stored system, with that of a pre-exisiting standard system. Raises ------ ValueError * If the particles in the two System don't match. * If the constraints in the two System don't match. * If the forces in the two systems don't match. """ # Assert particle equality def _get_masses(system): return np.array( [ system.getParticleMass(i).value_in_unit(openmm.unit.dalton) for i in range(system.getNumParticles()) ] ) ref_masses = _get_masses(ref_system) stored_masses = _get_masses(stored_system) if not ((ref_masses.shape == stored_masses.shape) and (np.allclose(ref_masses, stored_masses))): errmsg = "Stored checkpoint System particles do not match those of the simulated System" raise ValueError(errmsg) # Assert constraint equality def _get_constraints(system): constraints = [] for index in range(system.getNumConstraints()): i, j, d = system.getConstraintParameters(index) constraints.append([i, j, d.value_in_unit(openmm.unit.nanometer)]) return np.array(constraints) ref_constraints = _get_constraints(ref_system) stored_constraints = _get_constraints(stored_system) if not ( (ref_constraints.shape == stored_constraints.shape) and (np.allclose(ref_constraints, stored_constraints)) ): errmsg = "Stored checkpoint System constraints do not match those of the simulation System" raise ValueError(errmsg) # Assert force equality # Notes: # * Store forces are in different order # * The barostat doesn't exactly match because seeds have changed # Create dictionaries of forces keyed by their hash # Note: we can't rely on names because they may clash ref_force_dict = {hash(openmm.XmlSerializer.serialize(f)): f for f in ref_system.getForces()} stored_force_dict = { hash(openmm.XmlSerializer.serialize(f)): f for f in stored_system.getForces() } # Assert the number of forces is equal if len(ref_force_dict) != len(stored_force_dict): errmsg = "Number of forces stored in checkpoint System does not match simulation System" raise ValueError(errmsg) # Loop through forces and check for equality for sfhash, sforce in stored_force_dict.items(): # Barostat case - seed changed so we need to check manually if isinstance(sforce, (openmm.MonteCarloBarostat, openmm.MonteCarloMembraneBarostat)): # Find the equivalent force in the reference rforce = [ f for f in ref_force_dict.values() if isinstance(f, (openmm.MonteCarloBarostat, openmm.MonteCarloMembraneBarostat)) ][0] if ( (sforce.getFrequency() != rforce.getFrequency()) or (sforce.getForceGroup() != rforce.getForceGroup()) or (sforce.getDefaultPressure() != rforce.getDefaultPressure()) or (sforce.getDefaultTemperature() != rforce.getDefaultTemperature()) ): errmsg = ( f"Barostat Force {sforce.getName()} in the stored checkpoint " "System does not match the same force in the simulated System." ) raise ValueError(errmsg) else: if sfhash not in ref_force_dict: msg = ( f"Force {sforce.getName()} in the stored checkpoint System " "does not exactly match one of the forces in the simulated System " "this may be due to machine precision issues." ) logger.info(msg) def validate_chemical_system(system: ChemicalSystem): """ Validate that the input ChemicalSystem is suitable for use in an OpenMM-based alchemical protocol. Parameters ---------- state : ChemicalSystem The chemical system to validate. Raises ------ ComponentValidationError If any component in the ChemicalSystem fails validation. """ for entry in system.components: try: system.components[entry].validate() except ComponentValidationError as e: errmsg = f"Component {entry} from ChemicalSystem {system.name} failed validation: {e}" raise ComponentValidationError(errmsg) ================================================ FILE: src/openfe/protocols/restraint_utils/__init__.py ================================================ ================================================ FILE: src/openfe/protocols/restraint_utils/geometry/__init__.py ================================================ from .base import BaseRestraintGeometry, HostGuestRestraintGeometry from .boresch import BoreschRestraintGeometry from .flatbottom import FlatBottomDistanceGeometry from .harmonic import DistanceRestraintGeometry ================================================ FILE: src/openfe/protocols/restraint_utils/geometry/base.py ================================================ # This code is part of OpenFE and is licensed under the MIT license. # For details, see https://github.com/OpenFreeEnergy/openfe """ Restraint Geometry classes TODO ---- * Add relevant duecredit entries. """ import abc from pydantic import BaseModel, ConfigDict, field_validator class BaseRestraintGeometry(BaseModel, abc.ABC): """ A base class for a restraint geometry. """ model_config = ConfigDict(arbitrary_types_allowed=True) class HostGuestRestraintGeometry(BaseRestraintGeometry): """ An ordered list of guest atoms to restrain. Note ---- The order matters! It will be used to define the underlying force. """ guest_atoms: list[int] """ An ordered list of host atoms to restrain. Note ---- The order matters! It will be used to define the underlying force. """ host_atoms: list[int] @field_validator("guest_atoms", "host_atoms") def positive_idxs(cls, v): if v is not None and any([i < 0 for i in v]): # TODO: when would None be valid here? errmsg = "negative indices passed" raise ValueError(errmsg) return v ================================================ FILE: src/openfe/protocols/restraint_utils/geometry/boresch/__init__.py ================================================ from .geometry import ( BoreschRestraintGeometry, find_boresch_restraint, find_guest_atom_candidates, ) ================================================ FILE: src/openfe/protocols/restraint_utils/geometry/boresch/geometry.py ================================================ # This code is part of OpenFE and is licensed under the MIT license. # For details, see https://github.com/OpenFreeEnergy/openfe """ Restraint Geometry classes TODO ---- * Add relevant duecredit entries. """ from typing import Annotated, Literal, Optional, TypeAlias import MDAnalysis as mda from gufe.settings.typing import GufeQuantity, NanometerQuantity, specify_quantity_units from MDAnalysis.lib.distances import calc_angles, calc_bonds, calc_dihedrals from openff.units import Quantity, unit from rdkit import Chem from openfe.protocols.restraint_utils.geometry.base import HostGuestRestraintGeometry from .guest import find_guest_atom_candidates from .host import ( find_host_anchor_bonded, find_host_anchor_multi, find_host_atom_candidates, ) RadiansQuantity: TypeAlias = Annotated[GufeQuantity, specify_quantity_units("radians")] class BoreschRestraintGeometry(HostGuestRestraintGeometry): """ A class that defines the restraint geometry for a Boresch restraint. The restraint is defined by the following: H2 G2 - - - - H1 - - H0 -- G0 - - G1 Where HX represents the X index of ``host_atoms`` and GX the X index of ``guest_atoms``. """ r_aA0: NanometerQuantity """ The equilibrium distance between H0 and G0. """ theta_A0: RadiansQuantity """ The equilibrium angle value between H1, H0, and G0. """ theta_B0: RadiansQuantity """ The equilibrium angle value between H0, G0, and G1. """ phi_A0: RadiansQuantity """ The equilibrium dihedral value between H2, H1, H0, and G0. """ phi_B0: RadiansQuantity """ The equilibrium dihedral value between H1, H0, G0, and G1. """ phi_C0: RadiansQuantity """ The equilibrium dihedral value between H0, G0, G1, and G2. """ def _get_restraint_distances( atomgroup: mda.AtomGroup, ) -> tuple[Quantity, Quantity, Quantity, Quantity, Quantity, Quantity]: """ Get the bond, angle, and dihedral distances for an input atomgroup defining the six atoms for a Boresch-like restraint. The atoms must be in the order of H0, H1, H2, G0, G1, G2. Parameters ---------- atomgroup : mda.AtomGroup An AtomGroup defining the restrained atoms in order. Returns ------- bond : openff.units.Quantity The H0-G0 bond value. angle1 : openff.units.Quantity The H1-H0-G0 angle value. angle2 : openff.units.Quantity The H0-G0-G1 angle value. dihed1 : openff.units.Quantity The H2-H1-H0-G0 dihedral value. dihed2 : openff.units.Quantity The H1-H0-G0-G1 dihedral value. dihed3 : openff.units.Quantity The H0-G0-G1-G2 dihedral value. """ bond = ( calc_bonds( atomgroup.atoms[0].position, atomgroup.atoms[3].position, box=atomgroup.dimensions, ) * unit.angstroms ) angles = [] for idx_set in [[1, 0, 3], [0, 3, 4]]: angle = calc_angles( atomgroup.atoms[idx_set[0]].position, atomgroup.atoms[idx_set[1]].position, atomgroup.atoms[idx_set[2]].position, box=atomgroup.dimensions, ) angles.append(angle * unit.radians) dihedrals = [] for idx_set in [[2, 1, 0, 3], [1, 0, 3, 4], [0, 3, 4, 5]]: dihed = calc_dihedrals( atomgroup.atoms[idx_set[0]].position, atomgroup.atoms[idx_set[1]].position, atomgroup.atoms[idx_set[2]].position, atomgroup.atoms[idx_set[3]].position, box=atomgroup.dimensions, ) dihedrals.append(dihed * unit.radians) return bond, angles[0], angles[1], dihedrals[0], dihedrals[1], dihedrals[2] def find_boresch_restraint( universe: mda.Universe, guest_rdmol: Chem.Mol, guest_idxs: list[int], host_idxs: list[int], guest_restraint_atoms_idxs: Optional[list[int]] = None, host_restraint_atoms_idxs: Optional[list[int]] = None, host_selection: str = "all", anchor_finding_strategy: Literal["multi-residue", "bonded"] = "multi-residue", dssp_filter: bool = False, rmsf_cutoff: Quantity = 0.1 * unit.nanometer, host_min_distance: Quantity = 1 * unit.nanometer, host_max_distance: Quantity = 3 * unit.nanometer, angle_force_constant: Quantity = (83.68 * unit.kilojoule_per_mole / unit.radians**2), temperature: Quantity = 298.15 * unit.kelvin, ) -> BoreschRestraintGeometry: """ Find suitable Boresch-style restraints between a host and guest entity based on the approach of Baumann et al. [1] with some modifications. Parameters ---------- universe : mda.Universe An MDAnalysis Universe defining the system and its coordinates. guest_rdmol : Chem.Mol An RDKit Mol for the guest molecule. guest_idxs : list[int] Indices in the topology for the guest molecule. host_idxs : list[int] Indices in the topology for the host molecule. guest_restraint_atoms_idxs : Optional[list[int]] User selected indices of the guest molecule itself (i.e. indexed starting a 0 for the guest molecule). This overrides the restraint search and a restraint using these indices will be returned. Must be defined alongside ``host_restraint_atoms_idxs``. host_restraint_atoms_idxs : Optional[list[int]] User selected indices of the host molecule itself (i.e. indexed starting a 0 for the hosts molecule). This overrides the restraint search and a restraint using these indices will be returned. Must be defined alongside ``guest_restraint_atoms_idxs``. host_selection : str An MDAnalysis selection string to sub-select the host atoms. anchor_finding_strategy: Literal['multi-residue', 'bonded'] How host anchor atoms are found. Default `multi-residue`, attempts to find host anchors across multiple residues. dssp_filter : bool Whether or not to filter the host atoms by their secondary structure. rmsf_cutoff : openff.units.Quantity The cutoff value for atom root mean square fluctuation. Atoms with RMSF values above this cutoff will be disregarded. Must be in units compatible with nanometer. host_min_distance : openff.units.Quantity The minimum distance between any host atom and the guest G0 atom. Must be in units compatible with nanometer. host_max_distance : openff.units.Quantity The maximum distance between any host atom and the guest G0 atom. Must be in units compatible with nanometer. angle_force_constant : openff.units.Quantity The force constant for the G1-G0-H0 and G0-H0-H1 angles. Must be in units compatible with kilojoule / mole / radians ** 2. temperature : openff.units.Quantity The system temperature in units compatible with Kelvin. Returns ------- BoreschRestraintGeometry An object defining the parameters of the Boresch-like restraint. References ---------- [1] Baumann, Hannah M., et al. "Broadening the scope of binding free energy calculations using a Separated Topologies approach." (2023). """ if (guest_restraint_atoms_idxs is not None) and (host_restraint_atoms_idxs is not None): # fmt: skip # In this case assume the picked atoms were intentional / # representative of the input and go with it guest_ag = universe.atoms[guest_idxs] guest_atoms = [at.ix for at in guest_ag.atoms[guest_restraint_atoms_idxs]] host_ag = universe.atoms[host_idxs] host_atoms = [at.ix for at in host_ag.atoms[host_restraint_atoms_idxs]] # Set the equilibrium values as those of the final frame universe.trajectory[-1] atomgroup = universe.atoms[host_atoms + guest_atoms] bond, ang1, ang2, dih1, dih2, dih3 = _get_restraint_distances(atomgroup) # TODO: add checks to warn if this is a badly picked # set of atoms. return BoreschRestraintGeometry( host_atoms=host_atoms, guest_atoms=guest_atoms, r_aA0=bond, theta_A0=ang1, theta_B0=ang2, phi_A0=dih1, phi_B0=dih2, phi_C0=dih3, ) if (guest_restraint_atoms_idxs is not None) ^ (host_restraint_atoms_idxs is not None): # fmt: skip # This is not an intended outcome, crash out here errmsg = ( "both ``guest_restraints_atoms_idxs`` and " "``host_restraint_atoms_idxs`` " "must be set or both must be None. " f"Got {guest_restraint_atoms_idxs} and {host_restraint_atoms_idxs}" ) raise ValueError(errmsg) # 1. Fetch the guest anchors guest_anchors = find_guest_atom_candidates( universe=universe, rdmol=guest_rdmol, guest_idxs=guest_idxs, rmsf_cutoff=rmsf_cutoff, ) if len(guest_anchors) == 0: errmsg = "No suitable ligand atoms found for the restraint." raise ValueError(errmsg) # 2. We then loop through the guest anchors to find suitable host atoms for guest_anchor in guest_anchors: # We next fetch the host atom pool # Note: return is a set, so need to convert it later on host_pool = find_host_atom_candidates( universe=universe, host_idxs=host_idxs, guest_anchor_idx=guest_anchor[0], host_selection=host_selection, dssp_filter=dssp_filter, rmsf_cutoff=rmsf_cutoff, min_search_distance=host_min_distance, max_search_distance=host_max_distance, ) if anchor_finding_strategy == "multi-residue": host_anchor = find_host_anchor_multi( guest_atoms=universe.atoms[list(guest_anchor)], host_atom_pool=universe.atoms[list(host_pool)], host_minimum_distance=0.5 * unit.nanometer, # TODO: work out a rename for this, it's confusing guest_minimum_distance=host_min_distance, angle_force_constant=angle_force_constant, temperature=temperature, ) elif anchor_finding_strategy == "bonded": host_anchor = find_host_anchor_bonded( guest_atoms=universe.atoms[list(guest_anchor)], host_atom_pool=universe.atoms[list(host_pool)], guest_minimum_distance=host_min_distance, angle_force_constant=angle_force_constant, temperature=temperature, ) else: # We're doing something we shouldn't be errmsg = f"Unknown anchor finding strategy: {anchor_finding_strategy}" raise NotImplementedError(errmsg) # continue if it's empty, otherwise stop if host_anchor is not None: break if host_anchor is None: errmsg = "No suitable host atoms could be found" raise ValueError(errmsg) # Set the equilibrium values as those of the final frame universe.trajectory[-1] atomgroup = universe.atoms[list(host_anchor) + list(guest_anchor)] bond, ang1, ang2, dih1, dih2, dih3 = _get_restraint_distances(atomgroup) return BoreschRestraintGeometry( host_atoms=list(host_anchor), guest_atoms=list(guest_anchor), r_aA0=bond, theta_A0=ang1, theta_B0=ang2, phi_A0=dih1, phi_B0=dih2, phi_C0=dih3, ) ================================================ FILE: src/openfe/protocols/restraint_utils/geometry/boresch/guest.py ================================================ # This code is part of OpenFE and is licensed under the MIT license. # For details, see https://github.com/OpenFreeEnergy/openfe """ Restraint Geometry classes TODO ---- * Add relevant duecredit entries. """ from typing import Iterable, Optional import MDAnalysis as mda from openff.units import Quantity, unit from rdkit import Chem from openfe.protocols.restraint_utils.geometry.utils import ( get_aromatic_rings, get_central_atom_idx, get_heavy_atom_idxs, get_local_rmsf, is_collinear, ) def _sort_by_distance_from_atom( rdmol: Chem.Mol, target_idx: int, atom_idxs: Iterable[int] ) -> list[int]: """ Sort a list of RDMol atoms by their distance from a target atom. Parameters ---------- rdmol : Chem.Mol RDKit Molecule the atoms belong to. target_idx : int The idx of the atom to measure from. atom_idxs : list[int] The idx values of the atoms to sort. Returns ------- list[int] The input atom idxs sorted by their distance from the target atom. """ distances = [] conformer = rdmol.GetConformer() # Get the target atom position target_pos = conformer.GetAtomPosition(target_idx) for idx in atom_idxs: pos = conformer.GetAtomPosition(idx) distances.append(((target_pos - pos).Length(), idx)) return [i[1] for i in sorted(distances)] def _bonded_angles_from_pool( rdmol: Chem.Mol, atom_idx: int, atom_pool: list[int], aromatic_only: bool, ) -> list[tuple[int, int, int]]: """ Get all bonded angles starting from ``atom_idx`` from a pool of atoms. Parameters ---------- rdmol : Chem.Mol The RDKit Molecule atom_idx : int The index of the atom to search angles from. atom_pool : list[int] The list of indices to pick possible angle partners from. aromatic_only : bool Prune any angles that include non-aromatic bonds. Returns ------- list[tuple[int, int, int]] A list of tuples containing all the angles. Notes ----- * In the original SepTop code at3 is picked as directly bonded to at1. By comparison here we instead follow the case that at3 is bonded to at2 but not bonded to at1. """ angles = [] # Get the base atom and its neighbors at1 = rdmol.GetAtomWithIdx(atom_idx) at1_neighbors = [at.GetIdx() for at in at1.GetNeighbors()] # We loop at2 and at3 through the sorted atom_pool in order to get # a list of angles in the branch that are sorted by how close the atoms # are from the central atom for at2 in atom_pool: if at2 in at1_neighbors: at2_neighbors = [at.GetIdx() for at in rdmol.GetAtomWithIdx(at2).GetNeighbors()] for at3 in atom_pool: if at3 != atom_idx and at3 in at2_neighbors: angles.append((atom_idx, at2, at3)) if aromatic_only: # TODO: move this to its own method? aromatic_rings = get_aromatic_rings(rdmol) def _belongs_to_ring(angle, aromatic_rings): for ring in aromatic_rings: if all(a in ring for a in angle): return True return False # build a list of angles to remove angles_to_remove = [ angle for angle in angles if not _belongs_to_ring(angle, aromatic_rings) ] for angle in angles_to_remove: angles.remove(angle) return angles def _get_guest_atom_pool( rdmol: Chem.Mol, rmsf, #: ArrayQuantity, TODO: new pydantic v2-compatible quantity needed here. rmsf_cutoff: Quantity, ) -> tuple[Optional[set[int]], bool]: """ Filter atoms based on rmsf & rings, defaulting to heavy atoms if there are not enough. Parameters ---------- rdmol : Chem.Mol The RDKit Molecule to search through rmsf : Quantity A 1-D Quantity array of RMSF values for each atom. rmsf_cutoff : openff.units.Quantity The rmsf cutoff value for selecting atoms in units compatible with nanometer. Returns ------- atom_pool : Optional[set[int]] A pool of candidate atoms. ring_atoms_only : bool True if only ring atoms were selected. """ # Get a list of all the aromatic rings # Note: no need to keep track of rings because we'll filter by # bonded terms after, so if we only keep rings then all the bonded # atoms should be within the same ring system. atom_pool: set[int] = set() ring_atoms_only: bool = True for ring in get_aromatic_rings(rdmol): max_rmsf = rmsf[list(ring)].max() if max_rmsf < rmsf_cutoff: atom_pool.update(ring) # if we don't have enough atoms just get all the heavy atoms if len(atom_pool) < 3: ring_atoms_only = False heavy_atoms = get_heavy_atom_idxs(rdmol) atom_pool = set(idx for idx in heavy_atoms if rmsf[idx] < rmsf_cutoff) if len(atom_pool) < 3: return None, False return atom_pool, ring_atoms_only def find_guest_atom_candidates( universe: mda.Universe, rdmol: Chem.Mol, guest_idxs: list[int], rmsf_cutoff: Quantity = 1 * unit.nanometer, ) -> list[tuple[int, int, int]]: """ Get a list of potential ligand atom choices for a Boresch restraint being applied to a given small molecule. Parameters ---------- universe : mda.Universe An MDAnalysis Universe defining the system and its coordinates. rdmol : Chem.Mol An RDKit Molecule representing the small molecule ordered in the same way as it is listed in the topology. guest_idxs : list[int] The ligand indices in the topology. rmsf_cutoff : openff.units.Quantity The RMSF filter cut-off. Returns ------- angle_list : list[tuple[int]] A list of tuples for each valid G0, G1, G2 angle. If ``None``, no angles could be found. Raises ------ ValueError If no suitable ligand atoms could be found. TODO ---- Should the RDMol have a specific frame position? """ ligand_ag = universe.atoms[guest_idxs] # 0. Get the ligand RMSF rmsf = get_local_rmsf(ligand_ag) universe.trajectory[-1] # forward to the last frame # 1. Get the pool of atoms to work with atom_pool, rings_only = _get_guest_atom_pool(rdmol, rmsf, rmsf_cutoff) if atom_pool is None: # We don't have enough atoms so we raise an error errmsg = "No suitable ligand atoms were found for the restraint" raise ValueError(errmsg) # 2. Get the central atom center = get_central_atom_idx(rdmol) # 3. Sort the atom pool based on their distance from the center sorted_atom_pool = _sort_by_distance_from_atom(rdmol, center, atom_pool) # 4. Get a list of probable angles angles_list = [] for atom in sorted_atom_pool: angles = _bonded_angles_from_pool( rdmol=rdmol, atom_idx=atom, atom_pool=sorted_atom_pool, aromatic_only=rings_only, ) for angle in angles: # Check that the angle is at least not collinear angle_ag = ligand_ag.atoms[list(angle)] if not is_collinear(ligand_ag.positions, angle, universe.dimensions): angles_list.append( (angle_ag.atoms[0].ix, angle_ag.atoms[1].ix, angle_ag.atoms[2].ix) ) return angles_list ================================================ FILE: src/openfe/protocols/restraint_utils/geometry/boresch/host.py ================================================ # This code is part of OpenFE and is licensed under the MIT license. # For details, see https://github.com/OpenFreeEnergy/openfe """ Restraint Geometry classes TODO ---- * Add relevant duecredit entries. """ import warnings from typing import Optional import MDAnalysis as mda import numpy as np import numpy.typing as npt from MDAnalysis.analysis.base import AnalysisBase from MDAnalysis.lib.distances import calc_angles, calc_bonds, calc_dihedrals from openff.units import Quantity, unit from scipy.stats import circvar from openfe.protocols.restraint_utils.geometry.utils import ( CentroidDistanceSort, FindHostAtoms, check_angle_not_flat, check_angular_variance, check_dihedral_bounds, get_local_rmsf, is_collinear, protein_chain_selection, stable_secondary_structure_selection, ) def _host_atoms_search( atomgroup: mda.AtomGroup, guest_anchor_idx: int, rmsf_cutoff: Quantity, min_search_distance: Quantity, max_search_distance: Quantity, ) -> npt.NDArray: """ Helper method to get a set of host atoms with minimal RMSF within a given distance of a guest anchor. Parameters ---------- atomgroup : mda.AtomGroup An AtomGroup to find host atoms in. guest_anchor_idx : int The index of the proposed guest anchor binding atom. rmsf_cutoff : Quantity The maximum allowed RMSF value for any candidate host atom. min_search_distance : Quantity The minimum host atom search distance around the guest anchor. max_search_distance : Quantity The maximum host atom search distance around the guest anchor. Return ------ NDArray Array of host atom indexes """ # 0 Deal with the empty case if len(atomgroup) == 0: return np.array([], dtype=int) # 1 Get the RMSF & filter to create a new AtomGroup rmsf = get_local_rmsf(atomgroup) filtered_atomgroup = atomgroup.atoms[rmsf < rmsf_cutoff] # 2. Search for atoms within the min/max cutoff of the guest anchor atom_finder = FindHostAtoms( host_atoms=filtered_atomgroup, guest_atoms=atomgroup.universe.atoms[guest_anchor_idx], min_search_distance=min_search_distance, max_search_distance=max_search_distance, ) atom_finder.run() return atom_finder.results.host_idxs def find_host_atom_candidates( universe: mda.Universe, host_idxs: list[int], guest_anchor_idx: int, host_selection: str, dssp_filter: bool = False, rmsf_cutoff: Quantity = 0.1 * unit.nanometer, min_search_distance: Quantity = 0.5 * unit.nanometer, max_search_distance: Quantity = 1.5 * unit.nanometer, ) -> npt.NDArray: """ Get a list of suitable host atoms. Parameters ---------- universe : mda.Universe An MDAnalysis Universe defining the system and its coordinates. host_idxs : list[int] A list of the host indices in the system topology. guest_anchor_idx : int The index of the proposed l1 binding atom. host_selection : str An MDAnalysis selection string to filter the host by. dssp_filter : bool Whether or not to apply a DSSP filter on the host selection. rmsf_cutoff : openff.units.Quantity The maximum RMSF value allowed for any candidate host atom. min_search_distance : openff.units.Quantity The minimum search distance around l1 for suitable candidate atoms. max_search_distance : openff.units.Quantity The maximum search distance around l1 for suitable candidate atoms. Return ------ NDArray Array of host atom indexes sorted by distance from `guest_anchor_idx` """ # Get an AtomGroup for the host based on the input host indices host_ag = universe.atoms[host_idxs] # Filter the host AtomGroup based on ``host_selection` selected_host_ag = host_ag.select_atoms(host_selection) # If the host_selection does not work, raise an error if len(selected_host_ag) < 3: errmsg = ( "Boresch-like restraint generation: " f"too few atoms selected by ``host_selection``: {host_selection}" ) raise ValueError(errmsg) # None filtered_host_ixs for condition checking later filtered_host_idxs = None # If requested, filter the host atoms based on if their residues exist # within stable secondary structures. if dssp_filter: # TODO: allow more user-supplied kwargs here filtered_host_idxs = _host_atoms_search( atomgroup=stable_secondary_structure_selection(selected_host_ag), guest_anchor_idx=guest_anchor_idx, rmsf_cutoff=rmsf_cutoff, min_search_distance=min_search_distance, max_search_distance=max_search_distance, ) if len(filtered_host_idxs) < 20: wmsg = ( "Restraint generation: DSSP filter found too few host atoms " f"({len(filtered_host_idxs)} found). Will attempt to use all protein chains." ) warnings.warn(wmsg) filtered_host_idxs = _host_atoms_search( atomgroup=protein_chain_selection(selected_host_ag), guest_anchor_idx=guest_anchor_idx, rmsf_cutoff=rmsf_cutoff, min_search_distance=min_search_distance, max_search_distance=max_search_distance, ) if len(filtered_host_idxs) < 20: wmsg = ( "Restraint generation: protein chain filter found too few " f"host atoms ({len(filtered_host_idxs)} found). Will attempt to use all host atoms in " f"selection: {host_selection}." ) warnings.warn(wmsg) filtered_host_idxs = None if filtered_host_idxs is None: filtered_host_idxs = _host_atoms_search( atomgroup=selected_host_ag, guest_anchor_idx=guest_anchor_idx, rmsf_cutoff=rmsf_cutoff, min_search_distance=min_search_distance, max_search_distance=max_search_distance, ) # Crash out if no atoms were found if len(filtered_host_idxs) == 0: errmsg = ( f"No host atoms found within the search distance " f"{min_search_distance}-{max_search_distance}. Consider widening the search window." ) raise ValueError(errmsg) # Now we sort them by their distance from the guest anchor atom_sorter = CentroidDistanceSort( sortable_atoms=universe.atoms[filtered_host_idxs], reference_atoms=universe.atoms[guest_anchor_idx], ) atom_sorter.run() return atom_sorter.results.sorted_atomgroup.ix class EvaluateBoreschAtoms(AnalysisBase): """ Class to evaluate the geometric suitability of Boresch restraints. Parameters ---------- restraints : list[MDAnalysis.AtomGroup] A list of AtomGroup defining the H2-H1-H0-G0-G1-G2 atoms, in that order. angle_force_constant : openff.units.Quantity The force constant for the angle. temperature : openff.units.Quantity The system temperature in units compatible with Kelvin. """ def __init__( self, restraints: list[mda.AtomGroup], angle_force_constant: Quantity, temperature: Quantity, **kwargs, ): if len(restraints) < 1: errmsg = "Need to have at least one restraint" raise ValueError(errmsg) super().__init__(restraints[0].universe.trajectory, **kwargs) if not all(len(rest) == 6 for rest in restraints): errmsg = "Incorrect number of restraint atoms passed" raise ValueError(errmsg) self.restraints = restraints self.angle_force_constant = angle_force_constant self.temperature = temperature def _prepare(self): nrests = len(self.restraints) # Whether or not the restraint is valid self.results.valid = np.ones((nrests), dtype=bool) # Containers self.results.collinear = np.empty((nrests, self.n_frames), dtype=bool) self.results.bonds = np.zeros((nrests, self.n_frames)) self.results.angles = np.zeros((nrests, 2, self.n_frames)) self.results.dihedrals = np.zeros((nrests, 3, self.n_frames)) def _single_frame(self): # Loop through all the restraints and gather bond / angle info. for ridx, restraint in enumerate(self.restraints): self.results.collinear[ridx, self._frame_index] = is_collinear( positions=restraint.positions, atoms=[0, 1, 2, 3, 4, 5], dimensions=restraint.dimensions, ) # bonds self.results.bonds[ridx, self._frame_index] = calc_bonds( restraint.atoms[2].position, restraint.atoms[3].position, box=restraint.dimensions, ) # angles for i in range(1, 3): self.results.angles[ridx, i - 1, self._frame_index] = calc_angles( restraint.atoms[i].position, restraint.atoms[i + 1].position, restraint.atoms[i + 2].position, box=restraint.dimensions, ) # dihedrals for i in range(3): self.results.dihedrals[ridx, i, self._frame_index] = calc_dihedrals( restraint.atoms[i].position, restraint.atoms[i + 1].position, restraint.atoms[i + 2].position, restraint.atoms[i + 3].position, box=restraint.dimensions, ) def _conclude(self): for ridx in range(len(self.restraints)): # Check angles angle_bounds = True angle_variance = True for i in range(2): bounds = all( check_angle_not_flat( angle=angle * unit.radians, force_constant=self.angle_force_constant, temperature=self.temperature, ) for angle in self.results.angles[ridx, i] ) variance = check_angular_variance( self.results.angles[ridx, i] * unit.radians, upper_bound=np.pi * unit.radians, lower_bound=0 * unit.radians, width=1.745 * unit.radians, ) angle_bounds &= bounds angle_variance &= variance # Check dihedrals dihed_bounds = True dihed_variance = True for i in range(3): bounds = all( check_dihedral_bounds(dihed * unit.radians) for dihed in self.results.dihedrals[ridx, i] ) variance = check_angular_variance( self.results.dihedrals[ridx, i] * unit.radians, upper_bound=np.pi * unit.radians, lower_bound=-np.pi * unit.radians, width=5.23 * unit.radians, ) dihed_bounds &= bounds dihed_variance &= variance not_collinear = not all(self.results.collinear[ridx]) self.results.valid[ridx] = all( [ angle_bounds, angle_variance, dihed_bounds, dihed_variance, not_collinear, ] ) class EvaluateHostAtoms1(AnalysisBase): """ Class to evaluate the suitability of a set of host atoms as either H0 or H1 atoms (i.e. the first and second host atoms). Parameters ---------- reference : MDAnalysis.AtomGroup The reference preceding three atoms. host_atom_pool : MDAnalysis.AtomGroup The pool of atoms to pick an atom from. minimum_distance : openff.units.Quantity The minimum distance from the bound reference atom. angle_force_constant : openff.units.Quantity The force constant for the angle. temperature : openff.units.Quantity The system temperature in units compatible with Kelvin """ def __init__( self, reference: mda.AtomGroup, host_atom_pool: mda.AtomGroup, minimum_distance: Quantity, angle_force_constant: Quantity, temperature: Quantity, **kwargs, ): super().__init__(reference.universe.trajectory, **kwargs) if len(reference) != 3: errmsg = "Incorrect number of reference atoms passed" raise ValueError(errmsg) self.reference = reference self.host_atom_pool = host_atom_pool self.minimum_distance = minimum_distance.to("angstrom").m self.angle_force_constant = angle_force_constant self.temperature = temperature def _prepare(self): self.results.distances = np.zeros((len(self.host_atom_pool), self.n_frames)) self.results.angles = np.zeros((len(self.host_atom_pool), self.n_frames)) self.results.dihedrals = np.zeros((len(self.host_atom_pool), self.n_frames)) self.results.collinear = np.empty( (len(self.host_atom_pool), self.n_frames), dtype=bool, ) self.results.valid = np.empty( len(self.host_atom_pool), dtype=bool, ) # Set everything to False to begin with self.results.valid[:] = False def _single_frame(self): for i, at in enumerate(self.host_atom_pool): distance = calc_bonds( at.position, self.reference.atoms[0].position, box=self.reference.dimensions, ) angle = calc_angles( at.position, self.reference.atoms[0].position, self.reference.atoms[1].position, box=self.reference.dimensions, ) dihedral = calc_dihedrals( at.position, self.reference.atoms[0].position, self.reference.atoms[1].position, self.reference.atoms[2].position, box=self.reference.dimensions, ) collinear = is_collinear( positions=np.vstack((at.position, self.reference.positions)), atoms=[0, 1, 2, 3], dimensions=self.reference.dimensions, ) self.results.distances[i][self._frame_index] = distance self.results.angles[i][self._frame_index] = angle self.results.dihedrals[i][self._frame_index] = dihedral self.results.collinear[i][self._frame_index] = collinear def _conclude(self): for i, at in enumerate(self.host_atom_pool): # Check distances distance_bounds = all(self.results.distances[i] > self.minimum_distance) # Check angles angle_bounds = all( check_angle_not_flat( angle=angle * unit.radians, force_constant=self.angle_force_constant, temperature=self.temperature, ) for angle in self.results.angles[i] ) angle_variance = check_angular_variance( self.results.angles[i] * unit.radians, upper_bound=np.pi * unit.radians, lower_bound=0 * unit.radians, width=1.745 * unit.radians, ) # Check dihedrals dihed_bounds = all( check_dihedral_bounds(dihed * unit.radians) for dihed in self.results.dihedrals[i] ) # fmt: skip dihed_variance = check_angular_variance( self.results.dihedrals[i] * unit.radians, upper_bound=np.pi * unit.radians, lower_bound=-np.pi * unit.radians, width=5.23 * unit.radians, ) not_collinear = not all(self.results.collinear[i]) if all( [ distance_bounds, angle_bounds, angle_variance, dihed_bounds, dihed_variance, not_collinear, ] ): self.results.valid[i] = True class EvaluateHostAtoms2(EvaluateHostAtoms1): """ Class to evaluate the suitability of a set of host atoms as H2 atoms (i.e. the third host atoms). Parameters ---------- reference : MDAnalysis.AtomGroup The reference preceding three atoms. host_atom_pool : MDAnalysis.AtomGroup The pool of atoms to pick an atom from. minimum_distance : unit.Quantity The minimum distance from the bound reference atom. angle_force_constant : unit.Quantity The force constant for the angle. temperature : unit.Quantity The system temperature in Kelvin """ def _prepare(self): self.results.distances1 = np.zeros((len(self.host_atom_pool), self.n_frames)) self.results.distances2 = np.zeros((len(self.host_atom_pool), self.n_frames)) self.results.dihedrals = np.zeros((len(self.host_atom_pool), self.n_frames)) self.results.collinear = np.empty( (len(self.host_atom_pool), self.n_frames), dtype=bool, ) self.results.valid = np.empty( len(self.host_atom_pool), dtype=bool, ) # Default to valid == False self.results.valid[:] = False def _single_frame(self): for i, at in enumerate(self.host_atom_pool): distance1 = calc_bonds( at.position, self.reference.atoms[0].position, box=self.reference.dimensions, ) distance2 = calc_bonds( at.position, self.reference.atoms[1].position, box=self.reference.dimensions, ) dihedral = calc_dihedrals( at.position, self.reference.atoms[0].position, self.reference.atoms[1].position, self.reference.atoms[2].position, box=self.reference.dimensions, ) collinear = is_collinear( positions=np.vstack((at.position, self.reference.positions)), atoms=[0, 1, 2, 3], dimensions=self.reference.dimensions, ) self.results.distances1[i][self._frame_index] = distance1 self.results.distances2[i][self._frame_index] = distance2 self.results.dihedrals[i][self._frame_index] = dihedral self.results.collinear[i][self._frame_index] = collinear def _conclude(self): for i, at in enumerate(self.host_atom_pool): distance1_bounds = all(self.results.distances1[i] > self.minimum_distance) distance2_bounds = all(self.results.distances2[i] > self.minimum_distance) dihed_bounds = all( check_dihedral_bounds(dihed * unit.radians) for dihed in self.results.dihedrals[i] ) # fmt: skip dihed_variance = check_angular_variance( self.results.dihedrals[i] * unit.radians, upper_bound=np.pi * unit.radians, lower_bound=-np.pi * unit.radians, width=5.23 * unit.radians, ) not_collinear = not all(self.results.collinear[i]) if all( [ distance1_bounds, distance2_bounds, dihed_bounds, dihed_variance, not_collinear, ] ): self.results.valid[i] = True def _get_lowest_variance_restraint_hostanchor( proposed_restraints: list[mda.AtomGroup], angle_force_constant: Quantity, temperature: Quantity ) -> list[int] | None: # fmt: skip """ Evaluate a list of proposed restraints and return the lowest variance valid restraint. Parameters ---------- proposed_restraints : list[MDAnalysis.AtomGroup] A proposed list of AtomGroup defining the H2-H1-H0-G0-G1-G2 restraint atoms, in that order. angle_force_constant : openff.units.Quantity The force constant for the angle. temperature : openff.units.Quantity The system temperature in units compatible with Kelvin. Returns ------- list[int] | None The H0, H1, H2 host atom indices for the picked restraint, or None if no suitable restraints are found. """ # Evaluate all the restraints restraints_eval = EvaluateBoreschAtoms( restraints=proposed_restraints, angle_force_constant=angle_force_constant, temperature=temperature, ).run() # If there are no valid restraints, we have nothing if not any(restraints_eval.results.valid): return None valid_indices = [] valid_variances = [] for ridx in range(len(proposed_restraints)): if restraints_eval.results.valid[ridx]: valid_indices.append(ridx) dih_variance = sum( [ circvar(diheds, high=np.pi, low=-np.pi) for diheds in restraints_eval.results.dihedrals[ridx] ] ) ang_variance = sum( [ circvar(angles, high=np.pi, low=0) for angles in restraints_eval.results.angles[ridx] ] ) bond_variance = np.var(restraints_eval.results.bonds[ridx]) valid_variances.append(dih_variance + ang_variance + bond_variance) # get the restraint with the lowest summed variance restraint_index = valid_indices[np.argmin(valid_variances)] restraint = restraints_eval.restraints[restraint_index] # we reverse the indices to get H0, H1, H2 host_indices = [i for i in restraint.atoms.ix[:3][::-1]] return host_indices def find_host_anchor_bonded( guest_atoms: mda.AtomGroup, host_atom_pool: mda.AtomGroup, guest_minimum_distance: Quantity, angle_force_constant: Quantity, temperature: Quantity, ) -> list[int] | None: """ Find suitable atoms for the H0-H1-H2 portion of the restraint where all host atoms are bonded to each other. Parameters ---------- guest_atoms : mda.AtomGroup The guest anchor atoms for G0-G1-G2 host_atom_pool : mda.AtomGroup The host atoms to search from. guest_minimum_distance: openff.units.Quantity The minimum distance between host atoms and the guest anchor. angle_force_constant : openff.units.Quantity The force constant for the G1-G0-H0 and G0-H0-H1 angles. temperature : openff.units.Quantity The target system temperature. Returns ------- Optional[list[int]] A list of indices for a selected combination of H0, H1, and H2. """ if not hasattr(guest_atoms, "angles"): warnings.warn("no angles found - will attempt to guess") guest_atoms.universe.guess_TopologyAttrs(context="default", to_guess=["angles"]) # Evaluate the host_atom_pool for suitability as H0 atoms h0_eval = EvaluateHostAtoms1( reference=guest_atoms, host_atom_pool=host_atom_pool, minimum_distance=guest_minimum_distance, angle_force_constant=angle_force_constant, temperature=temperature, ).run() # Get a list of proposed restraints proposed_restraints = [] for i, valid_h0 in enumerate(h0_eval.results.valid): # If valid H0 atom, get all the angles it's involved in. if valid_h0: # note: i indexes host_atom_pool but not the universe! # from here on, we will switch to using atom.ix instead of i atom = host_atom_pool.atoms[i] angles = atom.angles.atomgroup_intersection(host_atom_pool, strict=True) for indices in angles.indices: if atom.ix == indices[0] or atom.ix == indices[-1]: if atom.ix == indices[0]: indices = indices[::-1] else: continue proposed_restraints.append(host_atom_pool.universe.atoms[indices] + guest_atoms) # If there are no proposed restraints, return with nothing if len(proposed_restraints) == 0: return None # Otherwise, evaluate the restraints, and return the anchor # atoms from the lowest variance restraint, if any valid restraints # are found return _get_lowest_variance_restraint_hostanchor( proposed_restraints=proposed_restraints, angle_force_constant=angle_force_constant, temperature=temperature, ) def find_host_anchor_multi( guest_atoms: mda.AtomGroup, host_atom_pool: mda.AtomGroup, host_minimum_distance: Quantity, guest_minimum_distance: Quantity, angle_force_constant: Quantity, temperature: Quantity, ) -> Optional[list[int]]: """ Find suitable atoms for the H0-H1-H2 portion of the restraint. Parameters ---------- guest_atoms : mda.AtomGroup The guest anchor atoms for G0-G1-G2 host_atom_pool : mda.AtomGroup The host atoms to search from. host_minimum_distance : openff.units.Quantity The minimum distance to pick host atoms from each other. guest_minimum_distance: openff.units.Quantity The minimum distance between host atoms and the guest anchor. angle_force_constant : openff.units.Quantity The force constant for the G1-G0-H0 and G0-H0-H1 angles. temperature : openff.units.Quantity The target system temperature. Returns ------- Optional[list[int]] A list of indices for a selected combination of H0, H1, and H2. """ # Evaluate the host_atom_pool for suitability as H0 atoms h0_eval = EvaluateHostAtoms1( reference=guest_atoms, host_atom_pool=host_atom_pool, minimum_distance=guest_minimum_distance, angle_force_constant=angle_force_constant, temperature=temperature, ) h0_eval.run() for i, valid_h0 in enumerate(h0_eval.results.valid): # If valid H0 atom, evaluate rest of host_atom_pool for suitability # as H1 atoms. if valid_h0: h0g0g1_atoms = host_atom_pool.atoms[i] + guest_atoms.atoms[:2] h1_eval = EvaluateHostAtoms1( reference=h0g0g1_atoms, host_atom_pool=host_atom_pool, minimum_distance=host_minimum_distance, angle_force_constant=angle_force_constant, temperature=temperature, ) h1_eval.run() for j, valid_h1 in enumerate(h1_eval.results.valid): # If valid H1 atom, evaluate rest of host_atom_pool for # suitability as H2 atoms if valid_h1: h1h0g0_atoms = host_atom_pool.atoms[j] + h0g0g1_atoms.atoms[:2] h2_eval = EvaluateHostAtoms2( reference=h1h0g0_atoms, host_atom_pool=host_atom_pool, minimum_distance=host_minimum_distance, angle_force_constant=angle_force_constant, temperature=temperature, ) h2_eval.run() if any(h2_eval.results.valid): # Get the sum of the average distances (dsum_avgs) # for all the host_atom_pool atoms distance1_avgs = np.array([d.mean() for d in h2_eval.results.distances1]) distance2_avgs = np.array([d.mean() for d in h2_eval.results.distances2]) dsum_avgs = distance1_avgs + distance2_avgs # Now filter by validity as H2 atom h2_dsum_avgs = [ (idx, val) for idx, val in enumerate(dsum_avgs) if h2_eval.results.valid[idx] ] # Get the index of the H2 atom with the lowest # average distance k = sorted(h2_dsum_avgs, key=lambda x: x[1])[0][0] return list(host_atom_pool.atoms[[i, j, k]].ix) return None ================================================ FILE: src/openfe/protocols/restraint_utils/geometry/flatbottom.py ================================================ # This code is part of OpenFE and is licensed under the MIT license. # For details, see https://github.com/OpenFreeEnergy/openfe """ Restraint Geometry classes TODO ---- * Add relevant duecredit entries. """ from typing import Optional import MDAnalysis as mda import numpy as np from gufe.settings.typing import NanometerQuantity from MDAnalysis.analysis.base import AnalysisBase from MDAnalysis.lib.distances import calc_bonds from openff.units import Quantity, unit from .harmonic import DistanceRestraintGeometry from .utils import _get_mda_selection class FlatBottomDistanceGeometry(DistanceRestraintGeometry): """ A geometry class for a flat bottom distance restraint between two groups of atoms. """ well_radius: NanometerQuantity class COMDistanceAnalysis(AnalysisBase): """ Get a timeseries of COM distances between two AtomGroups Parameters ---------- group1 : MDAnalysis.AtomGroup Atoms defining the first centroid. group2 : MDAnalysis.AtomGroup Atoms defining the second centroid. """ _analysis_algorithm_is_parallelizable = False def __init__(self, group1, group2, **kwargs): super().__init__(group1.universe.trajectory, **kwargs) self.ag1 = group1 self.ag2 = group2 def _prepare(self): self.results.distances = np.zeros(self.n_frames) def _single_frame(self): com_dist = calc_bonds( self.ag1.center_of_mass(), self.ag2.center_of_mass(), box=self.ag1.universe.dimensions, ) self.results.distances[self._frame_index] = com_dist def _conclude(self): pass def get_flatbottom_distance_restraint( universe: mda.Universe, host_atoms: Optional[list[int]] = None, guest_atoms: Optional[list[int]] = None, host_selection: Optional[str] = None, guest_selection: Optional[str] = None, padding: Quantity = 0.5 * unit.nanometer, ) -> FlatBottomDistanceGeometry: """ Get a FlatBottomDistanceGeometry by analyzing the COM distance change between two sets of atoms. The ``well_radius`` is defined as the maximum COM distance plus ``padding``. Parameters ---------- universe : mda.Universe An MDAnalysis Universe defining the system and its coordinates. host_atoms : Optional[list[int]] A list of host atoms indices. Either ``host_atoms`` or ``host_selection`` must be defined. guest_atoms : Optional[list[int]] A list of guest atoms indices. Either ``guest_atoms`` or ``guest_selection`` must be defined. host_selection : Optional[str] An MDAnalysis selection string to define the host atoms. Either ``host_atoms`` or ``host_selection`` must be defined. guest_selection : Optional[str] An MDAnalysis selection string to define the guest atoms. Either ``guest_atoms`` or ``guest_selection`` must be defined. padding : openff.units.Quantity A padding value to add to the ``well_radius`` definition. Must be in units compatible with nanometers. Returns ------- FlatBottomDistanceGeometry An object defining a flat bottom restraint geometry. """ guest_ag = _get_mda_selection(universe, guest_atoms, guest_selection) host_ag = _get_mda_selection(universe, host_atoms, host_selection) guest_idxs = [a.ix for a in guest_ag] host_idxs = [a.ix for a in host_ag] if len(host_idxs) == 0 or len(guest_idxs) == 0: errmsg = ( "no atoms found in either the host or guest atom groups" f"host_atoms: {host_idxs}" f"guest_atoms: {guest_idxs}" ) raise ValueError(errmsg) com_dists = COMDistanceAnalysis(guest_ag, host_ag) com_dists.run() well_radius = com_dists.results.distances.max() * unit.angstrom + padding return FlatBottomDistanceGeometry( guest_atoms=guest_idxs, host_atoms=host_idxs, well_radius=well_radius ) ================================================ FILE: src/openfe/protocols/restraint_utils/geometry/harmonic.py ================================================ # This code is part of OpenFE and is licensed under the MIT license. # For details, see https://github.com/OpenFreeEnergy/openfe """ Restraint Geometry classes TODO ---- * Add relevant duecredit entries. """ from typing import Optional import MDAnalysis as mda from rdkit import Chem from .base import HostGuestRestraintGeometry from .utils import _get_mda_selection, get_central_atom_idx class DistanceRestraintGeometry(HostGuestRestraintGeometry): """ A geometry class for a distance restraint between two groups of atoms. """ def get_distance_restraint( universe: mda.Universe, host_atoms: Optional[list[int]] = None, guest_atoms: Optional[list[int]] = None, host_selection: Optional[str] = None, guest_selection: Optional[str] = None, ) -> DistanceRestraintGeometry: """ Get a DistanceRestraintGeometry between two groups of atoms. You can either select the groups by passing through a set of indices or an MDAnalysis selection. Parameters ---------- universe : mda.Universe An MDAnalysis Universe defining the system and its coordinates. host_atoms : Optional[list[int]] A list of host atoms indices. Either ``host_atoms`` or ``host_selection`` must be defined. guest_atoms : Optional[list[int]] A list of guest atoms indices. Either ``guest_atoms`` or ``guest_selection`` must be defined. host_selection : Optional[str] An MDAnalysis selection string to define the host atoms. Either ``host_atoms`` or ``host_selection`` must be defined. guest_selection : Optional[str] An MDAnalysis selection string to define the guest atoms. Either ``guest_atoms`` or ``guest_selection`` must be defined. Returns ------- DistanceRestraintGeometry An object that defines a distance restraint geometry. """ guest_ag = _get_mda_selection(universe, guest_atoms, guest_selection) guest_atoms = [a.ix for a in guest_ag] host_ag = _get_mda_selection(universe, host_atoms, host_selection) host_atoms = [a.ix for a in host_ag] return DistanceRestraintGeometry(guest_atoms=guest_atoms, host_atoms=host_atoms) def get_molecule_centers_restraint( molA_rdmol: Chem.Mol, molB_rdmol: Chem.Mol, molA_idxs: list[int], molB_idxs: list[int], ): """ Get a DistanceRestraintGeometry between the central atoms of two molecules. Parameters ---------- molA_rdmol : Chem.Mol An RDKit Molecule for the first molecule. molB_rdmol : Chem.Mol An RDKit Molecule for the second molecule. molA_idxs : list[int] The indices of the first molecule in the system. Note we assume these to be sorted in the same order as the input rdmol. molB_idxs : list[int] The indices of the second molecule in the system. Note we assume these to be sorted in the same order as the input rdmol. Returns ------- DistanceRestraintGeometry An object that defines a distance restraint geometry. """ # We assume that the mol idxs are ordered centerA = molA_idxs[get_central_atom_idx(molA_rdmol)] centerB = molB_idxs[get_central_atom_idx(molB_rdmol)] return DistanceRestraintGeometry(guest_atoms=[centerA], host_atoms=[centerB]) ================================================ FILE: src/openfe/protocols/restraint_utils/geometry/utils.py ================================================ # This code is part of OpenFE and is licensed under the MIT license. # For details, see https://github.com/OpenFreeEnergy/openfe """ Search methods for generating Geometry objects TODO ---- * Add relevant duecredit entries. """ import warnings from itertools import combinations, groupby from typing import Optional, Union import MDAnalysis as mda import networkx as nx import numpy as np import numpy.typing as npt # from gufe.vendor.openff.models.types import ArrayQuantity TODO: write a custom quantity to replace this in pydantic v2 from MDAnalysis.analysis.base import AnalysisBase from MDAnalysis.analysis.dssp import DSSP from MDAnalysis.analysis.rms import RMSF from MDAnalysis.lib.distances import capped_distance, distance_array, minimize_vectors from MDAnalysis.transformations.nojump import NoJump from openfe_analysis.transformations import Aligner from openff.toolkit import Molecule as OFFMol from openff.units import Quantity, unit from rdkit import Chem from scipy.stats import circvar DEFAULT_ANGLE_FRC_CONSTANT = 83.68 * unit.kilojoule_per_mole / unit.radians**2 def _get_mda_selection( universe: Union[mda.Universe, mda.AtomGroup], atom_list: Optional[list[int]] = None, selection: Optional[str] = None, ) -> mda.AtomGroup: """ Return an AtomGroup based on either a list of atom indices or an mdanalysis string selection. Parameters ---------- universe : Union[mda.Universe, mda.AtomGroup] The MDAnalysis Universe or AtomGroup to get the AtomGroup from. atom_list : Optional[list[int]] A list of atom indices. selection : Optional[str] An MDAnalysis selection string. Returns ------- ag : mda.AtomGroup An atom group selected from the inputs. Raises ------ ValueError If both ``atom_list`` and ``selection`` are ``None`` or are defined. """ if atom_list is None: if selection is None: raise ValueError("one of either the atom lists or selections must be defined") ag = universe.select_atoms(selection) else: if selection is not None: raise ValueError("both atom_list and selection cannot be defined together") ag = universe.atoms[atom_list] return ag def get_aromatic_rings(rdmol: Chem.Mol) -> list[set[int]]: """ Get a list of tuples with the indices for each ring in an rdkit Molecule. Parameters ---------- rdmol : Chem.Mol RDKit Molecule Returns ------- list[set[[int]] List of tuples for each ring. """ ringinfo = rdmol.GetRingInfo() arom_idxs = get_aromatic_atom_idxs(rdmol) aromatic_rings = [] # Add to the aromatic_rings list if all the atoms in a ring are aromatic for ring in ringinfo.AtomRings(): if all(a in arom_idxs for a in ring): aromatic_rings.append(set(ring)) # Reduce the ring list by merging any rings that have colliding atoms for x, y in combinations(aromatic_rings, 2): if not x.isdisjoint(y): x.update(y) aromatic_rings.remove(y) return aromatic_rings def get_aromatic_atom_idxs(rdmol: Chem.Mol) -> list[int]: """ Helper method to get aromatic atoms idxs in a RDKit Molecule Parameters ---------- rdmol : Chem.Mol RDKit Molecule Returns ------- list[int] A list of the aromatic atom idxs """ idxs = [at.GetIdx() for at in rdmol.GetAtoms() if at.GetIsAromatic()] return idxs def get_heavy_atom_idxs(rdmol: Chem.Mol) -> list[int]: """ Get idxs of heavy atoms in an RDKit Molecule Parameters ---------- rmdol : Chem.Mol Returns ------- list[int] A list of heavy atom idxs """ idxs = [at.GetIdx() for at in rdmol.GetAtoms() if at.GetAtomicNum() > 1] return idxs def get_central_atom_idx(rdmol: Chem.Mol) -> int: """ Get the central atom in an rdkit Molecule. Parameters ---------- rdmol : Chem.Mol RDKit Molecule to query Returns ------- int Index of central atom in Molecule Note ---- If there are equal likelihood centers, will return the first entry. """ # TODO: switch to a manual conversion to avoid an OpenFF dependency offmol = OFFMol(rdmol, allow_undefined_stereo=True) nx_mol = offmol.to_networkx() if not nx.is_weakly_connected(nx_mol.to_directed()): errmsg = "A disconnected molecule was passed, cannot find the center" raise ValueError(errmsg) # Get a list of all shortest paths # Note: we call dict on shortest_path to support py3.10 which doesn't # support networkx 3.5 shortest_paths = [ path for node_paths in dict(nx.shortest_path(nx_mol)).values() for path in node_paths.values() ] # Get the longest of these paths (returns first instance) longest_path = max(shortest_paths, key=len) # Return the index of the central atom return longest_path[len(longest_path) // 2] def is_collinear( positions: npt.NDArray, atoms: Union[list[int], tuple[int, ...]], dimensions=None, threshold=0.9, ): """ Check whether any sequential vectors in a sequence of atoms are collinear. Approach: for each sequential set of 3 atoms (defined as A, B, and C), calculates the normalized inner product (i.e. cos^-1(angle)) between vectors AB and BC. If the absolute value of this inner product is close to 1 (i.e. an angle of 0 radians), then the three atoms are considered as collinear. You can use ``threshold`` to define how close to 1 is considered "flat". Parameters ---------- positions : npt.NDArray System positions. atoms : list[int] The indices of the atoms to test. dimensions : Optional[npt.NDArray] The dimensions of the system to minimize vectors. threshold : float Atoms are not collinear if their sequential vector separation dot products are less than ``threshold``. Default 0.9. Returns ------- result : bool Returns True if any sequential pair of vectors is collinear; False otherwise. Notes ----- Originally from Yank. """ if len(atoms) < 3: raise ValueError("Too few atoms passed for co-linearity test") if len(positions) < len(atoms) or len(positions) < max(atoms) + 1: errmsg = "atoms indices do not match the positions array passed" raise ValueError(errmsg) if not all(isinstance(x, int) for x in atoms): errmsg = "atoms is not a list of index integers" raise ValueError(errmsg) result = False for i in range(len(atoms) - 2): v1 = positions[atoms[i + 1], :] - positions[atoms[i], :] v2 = positions[atoms[i + 2], :] - positions[atoms[i + 1], :] if dimensions is not None: v1 = minimize_vectors(v1, box=dimensions) v2 = minimize_vectors(v2, box=dimensions) normalized_inner_product = np.dot(v1, v2) / np.sqrt(np.dot(v1, v1) * np.dot(v2, v2)) result = result or (np.abs(normalized_inner_product) > threshold) return result def _wrap_angle(angle: Quantity) -> Quantity: """ Wrap an angle to -pi to pi radians. Parameters ---------- angle : openff.units.Quantity An angle in radians compatible units. Returns ------- openff.units.Quantity The angle in units of radians wrapped. Notes ----- Pint automatically converts the angle to radians as it passes it through arctan2. """ return np.arctan2(np.sin(angle), np.cos(angle)) # type: ignore def check_angle_not_flat( angle: Quantity, force_constant: Quantity = DEFAULT_ANGLE_FRC_CONSTANT, temperature: Quantity = 298.15 * unit.kelvin, ) -> bool: """ Check whether the chosen angle is less than 10 kT from 0 or pi radians Parameters ---------- angle : openff.units.Quantity The angle to check in units compatible with radians. force_constant : openff.units.Quantity Force constant of the angle in units compatible with kilojoule_per_mole / radians ** 2. temperature : openff.units.Quantity The system temperature in units compatible with Kelvin. Returns ------- bool False if the angle is less than 10 kT from 0 or pi radians Note ---- We assume the temperature to be 298.15 Kelvin. Acknowledgements ---------------- This code was initially contributed by Vytautas Gapsys. """ # Convert things angle_rads = _wrap_angle(angle) frc_const = force_constant.to("unit.kilojoule_per_mole / unit.radians**2") temp_kelvin = temperature.to("kelvin") RT = 8.31445985 * 0.001 * temp_kelvin # type: ignore[operator] # check if angle is <10kT from 0 or 180 check1 = 0.5 * frc_const * np.power((angle_rads - 0.0), 2) # type: ignore[operator] check2 = 0.5 * frc_const * np.power((angle_rads - np.pi), 2) # type: ignore[operator] ang_check_1 = check1 / RT ang_check_2 = check2 / RT if ang_check_1.m < 10.0 or ang_check_2.m < 10.0: return False return True def check_dihedral_bounds( dihedral: Quantity, lower_cutoff: Quantity = -2.618 * unit.radians, upper_cutoff: Quantity = 2.618 * unit.radians, ) -> bool: """ Check that a dihedral does not exceed the bounds set by lower_cutoff and upper_cutoff on a -pi to pi range. All angles and cutoffs are wrapped to -pi to pi before applying the check. Parameters ---------- dihedral : openff.units.Quantity Dihedral in units compatible with radians. lower_cutoff : openff.units.Quantity Dihedral lower cutoff in units compatible with radians. upper_cutoff : openff.units.Quantity Dihedral upper cutoff in units compatible with radians. Returns ------- bool ``True`` if the dihedral is within the upper and lower cutoff bounds. """ dihed = _wrap_angle(dihedral) lower = _wrap_angle(lower_cutoff) upper = _wrap_angle(upper_cutoff) if (dihed < lower) or (dihed > upper): # type: ignore[operator] return False return True def check_angular_variance( angles: Quantity, upper_bound: Quantity, lower_bound: Quantity, width: Quantity, ) -> bool: """ Check that the variance of a list of ``angles`` does not exceed a given ``width`` Parameters ---------- angles : ArrayLike openff.units.Quantity An array of angles in units compatible with radians. upper_bound: openff.units.Quantity The upper bound in the angle range in radians compatible units. lower_bound: openff.units.Quantity The lower bound in the angle range in radians compatible units. width : openff.units.Quantity The width to check the variance against, in units compatible with radians. Returns ------- bool ``True`` if the variance of the angles is less than the width. """ # scipy circ methods already recasts internally so we shouldn't # need to wrap the angles variance = circvar( angles.to("radians").m, high=upper_bound.to("radians").m, low=lower_bound.to("radians").m, ) return not (variance * unit.radians > width) class CentroidDistanceSort(AnalysisBase): """ Sort (from shortest to longest) an input AtomGroup based on their distance from the center of geometry of another AtomGroup. Parameters ---------- sortable_atoms : MDAnalysis.AtomGroup AtomGroup to sort based on distance to center of geometry of ``reference_atoms``. reference_atoms : MDAnalysis.AtomGroup AtomGroup who's center of geometry will be used to distance sort ``sortable_atoms`` with. Attributes ---------- results.distances : np.array A numpy array of the distances from the centroid of ``reference_atoms`` for each frame. results.sorted_atomgroup : MDAnalysis.AtomGroup A copy of ``sortable_atoms`` where the atoms are sorted by their distance from the centroid of ``reference_atoms``. """ _analysis_algorithm_is_parallelizable = False def __init__( self, sortable_atoms, reference_atoms, **kwargs, ): super().__init__(sortable_atoms.universe.trajectory, **kwargs) def get_atomgroup(ag): """ We need this in case someone passes an Atom not an AG """ if ag._is_group: return ag return mda.AtomGroup([ag]) self.sortable_ag = get_atomgroup(sortable_atoms) self.reference_ag = get_atomgroup(reference_atoms) def _prepare(self): self.results.distances = np.zeros((self.n_frames, len(self.sortable_ag))) def _single_frame(self): self.results.distances[self._frame_index] = distance_array( self.reference_ag.center_of_geometry(), self.sortable_ag.atoms.positions, box=self.reference_ag.dimensions, ) def _conclude(self): idxs = np.argsort(np.mean(self.results.distances, axis=0)) self.results.sorted_atomgroup = self.sortable_ag.atoms[idxs] class FindHostAtoms(AnalysisBase): """ Class filter host atoms based on their distance from a set of guest atoms. Parameters ---------- host_atoms : MDAnalysis.AtomGroup Initial selection of host atoms to filter from. guest_atoms : MDAnalysis.AtomGroup Selection of guest atoms to search around. min_search_distance: openff.units.Quantity Minimum distance to filter atoms within. max_search_distance: openff.units.Quantity Maximum distance to filter atoms within. Attributes ---------- results.host_idxs : np.ndarray A NumPy array of host indices in the Universe. """ _analysis_algorithm_is_parallelizable = False def __init__( self, host_atoms, guest_atoms, min_search_distance, max_search_distance, **kwargs, ): super().__init__(host_atoms.universe.trajectory, **kwargs) def get_atomgroup(ag): if ag._is_group: return ag return mda.AtomGroup([ag]) self.host_ag = get_atomgroup(host_atoms) self.guest_ag = get_atomgroup(guest_atoms) self.min_cutoff = min_search_distance.to("angstrom").m self.max_cutoff = max_search_distance.to("angstrom").m def _prepare(self): self.results.host_idxs = set(self.host_ag.atoms.ix) def _single_frame(self): pairs = capped_distance( reference=self.guest_ag.positions, configuration=self.host_ag.positions, max_cutoff=self.max_cutoff, min_cutoff=self.min_cutoff, box=self.guest_ag.universe.dimensions, return_distances=False, ) host_idxs = set(self.host_ag.atoms[p].ix for p in pairs[:, 1]) # We do an intersection as we go along to prune atoms that don't pass # the distance selection criteria self.results.host_idxs = self.results.host_idxs.intersection(host_idxs) def _conclude(self): self.results.host_idxs = np.array(list(self.results.host_idxs)) # TODO: needs custom type https://github.com/OpenFreeEnergy/openfe/issues/1569 def get_local_rmsf(atomgroup: mda.AtomGroup): # -> ArrayQuantity: """ Get the RMSF of an AtomGroup when aligned upon itself. Parameters ---------- atomgroup : MDAnalysis.AtomGroup Return ------ rmsf : openff.units.Quantity ArrayQuantity of RMSF values. """ # The no trajectory case if len(atomgroup.universe.trajectory) < 2: return np.zeros(atomgroup.n_atoms) * unit.angstrom # First let's copy our Universe copy_u = atomgroup.universe.copy() ag = copy_u.atoms[atomgroup.atoms.ix] # Reset the trajectory index, otherwise we'll get in trouble with nojump copy_u.trajectory[0] nojump = NoJump() align = Aligner(ag) copy_u.trajectory.add_transformations(nojump, align) rmsf = RMSF(ag) rmsf.run() return rmsf.results.rmsf * unit.angstrom def _atomgroup_has_bonds(atomgroup: Union[mda.AtomGroup, mda.Universe]) -> bool: """ Check if all residues in an AtomGroup or Universe have bonds. Parameters ---------- atomgroup : Union[mda.Atomgroup, mda.Universe] Either an MDAnalysis AtomGroup or Universe to check for bonds. Returns ------- bool True if all residues contain at least one bond, False otherwise. """ if not hasattr(atomgroup, "bonds"): return False # Assume that any residue with more than one atom should have a bond if not all(len(r.atoms.bonds) > 0 for r in atomgroup.residues if len(r.atoms) > 1): return False return True def stable_secondary_structure_selection( atomgroup: mda.AtomGroup, trim_chain_start: int = 10, trim_chain_end: int = 10, min_structure_size: int = 6, trim_structure_ends: int = 2, ) -> mda.AtomGroup: """ Select all atoms in a given AtomGroup which belong to residues with a stable secondary structure as defined by Baumann et al.[1] The selection algorithm works in the following manner: 1. Protein residues are selected from the ``atomgroup``. 2. If there are fewer than 30 protein residues, raise an error. 3. Split the protein residues by fragment, guessing bonds if necessary. 4. Discard the first ``trim_chain_start`` and the last ``trim_chain_end`` residues per fragment. 5. Run DSSP using the last trajectory frame on the remaining fragment residues. 6. Extract all contiguous structure units that are longer than ``min_structure_size``, removing ``trim_structure_ends`` residues from each end of the structure. 7. For all extract structures, if there are more beta-sheet residues than there are alpha-helix residues, then allow residues to be selected from either structure type. If not, then only allow alpha-helix residues. 8. Select all atoms in the ``atomgroup`` that belong to residues from extracted structure units of the selected structure type. Parameters ---------- atomgroup : mda.AtomgGroup The AtomGroup to select atoms from. trim_chain_start: int The number of residues to trim from the start of each protein chain. Default 10. trim_chain_end : int The number of residues to trim from the end of each protein chain. Default 10. min_structure_size : int The minimum number of residues needed in a given secondary structure unit to be considered stable. Default 8. trim_structure_ends : int The number of residues to trim from the end of each secondary structure units. Default 3. Returns ------- AtomGroup : mda.AtomGroup An AtomGroup containing all the atoms from the input AtomGroup which belong to stable secondary structure residues. Raises ------ UserWarning If there are no bonds for the protein atoms in the input host residue. In this case, the bonds will be guessed using a simple distance metric. Notes ----- * This selection algorithm assumes contiguous & ordered residues. * We recommend always trimming at least one residue at the ends of each chain using ``trim_chain_start`` and ``trim_chain_end`` to avoid issues with capping residues. * DSSP assignment is done on the final frame of the trajectory. References ---------- [1] Baumann, Hannah M., et al. "Broadening the scope of binding free energy calculations using a Separated Topologies approach." (2023). """ # First let's copy our Universe so we don't overwrite its current state copy_u = atomgroup.universe.copy() # Create an AtomGroup that contains all the protein residues in the # input Universe - we will filter by what matches in the atomgroup later copy_protein_ag = copy_u.select_atoms("protein").atoms # We need to split by fragments to account for multiple chains # To do this, we need bonds! if not _atomgroup_has_bonds(copy_protein_ag): wmsg = "No bonds found in input Universe, will attempt to guess them." warnings.warn(wmsg) copy_protein_ag.guess_bonds() structures = [] # container for all contiguous secondary structure units # Counter for each residue type found structure_residue_counts = {"H": 0, "E": 0, "-": 0} # THe minimum length any chain must have min_chain_length = trim_chain_start + trim_chain_end + min_structure_size # Loop over each continually bonded section (i.e. chain) of the protein for frag in copy_protein_ag.fragments: # If this fragment is too small, skip processing it if len(frag.residues) < min_chain_length: continue # Trim the chain ends chain = frag.residues[trim_chain_start:-trim_chain_end].atoms try: # Run on the last frame # TODO: maybe filter out any residue that changes secondary # structure during the trajectory dssp = DSSP(chain).run(start=-1) except ValueError: # DSSP may fail if it doesn't recognise the system's atom names # or non-canonical residues are included, in this case just skip continue # Tag each residue structure by its resindex dssp_results = [ (structure, resid) for structure, resid in zip(dssp.results.dssp[0], chain.residues.resindices) ] # Group by contiguous secondary structure for _, group_iter in groupby(dssp_results, lambda x: x[0]): group = list(group_iter) if len(group) >= min_structure_size: structures.append(group[trim_structure_ends:-trim_structure_ends]) num_residues = len(group) - (2 * trim_structure_ends) structure_residue_counts[group[0][0]] += num_residues # Pick atoms in both helices and beta sheets allowed_structures = ["H", "E"] allowed_residxs = [] for structure in structures: if structure[0][0] in allowed_structures: allowed_residxs.extend([residue[1] for residue in structure]) # Resindexes are keyed at the Universe scale not AtomGroup allowed_atoms = atomgroup.universe.residues[allowed_residxs].atoms # Pick up all the atoms that intersect the initial selection and # those allowed. return atomgroup.intersection(allowed_atoms) def protein_chain_selection( atomgroup: mda.AtomGroup, min_chain_length: int = 30, trim_chain_start: int = 10, trim_chain_end: int = 10, ) -> mda.AtomGroup: """ Return a sub-selection of the input AtomGroup which belongs to protein chains trimmed by ``trim_chain_start`` and ``trim_chain_end``. Protein chains are defined as any continuously bonded part of system with at least ``min_chain_length`` (default: 30) residues which match the ``protein`` selection of MDAnalysis. Parameters ---------- atomgroup : mda.AtomgGroup The AtomGroup to select atoms from. min_chain_length : int The minimum number of residues to be considered a protein chain. Default 30. trim_chain_start : int The number of residues to trim from the start of each protein chain. Default 10. trim_chain_end : int The number of residues to trim from the end of each protein chain. Default 10. Returns ------- atomgroup : mda.AtomGroup An AtomGroup containing all the atoms from the input AtomGroup which belong to the trimmed protein chains. """ # First let's copy our Universe so we don't overwrite its current state copy_u = atomgroup.universe.copy() # Create an AtomGroup that contains all the protein residues in the # input Universe - we will filter by what matches in the atomgroup later copy_protein_ag = copy_u.select_atoms("protein").atoms # We need to split by fragments to account for multiple chains # To do this, we need bonds! if not _atomgroup_has_bonds(copy_protein_ag): wmsg = "No bonds found in input Universe, will attempt to guess them." warnings.warn(wmsg) copy_protein_ag.guess_bonds() copy_chains_ags_list = [] # Loop over each continually bonded section (i.e. chain) of the protein for frag in copy_protein_ag.fragments: # If this chain is less than min_chain_length residues, it's probably a peptide if len(frag.residues) < min_chain_length: continue chain = frag.residues[trim_chain_start:-trim_chain_end].atoms copy_chains_ags_list.append(chain) # If the list is empty, return an empty atomgroup if not copy_chains_ags_list: return atomgroup.atoms[[]] # Create a single atomgroup from all chains copy_chains_ag = sum(copy_chains_ags_list) # Now get a list of all the chain atoms in the original Universe # Resindexes are keyed at the Universe scale not AtomGroup chain_atoms = atomgroup.universe.atoms[copy_chains_ag.atoms.ix] # Return all atoms at the intersection of the input atomgroup and # the chains atomgroup return atomgroup.intersection(chain_atoms) ================================================ FILE: src/openfe/protocols/restraint_utils/openmm/__init__.py ================================================ ================================================ FILE: src/openfe/protocols/restraint_utils/openmm/omm_forces.py ================================================ # This code is part of OpenFE and is licensed under the MIT license. # For details, see https://github.com/OpenFreeEnergy/openfe """ Custom OpenMM Forces TODO ---- * Add relevant duecredit entries. """ import numpy as np import openmm def get_boresch_energy_function( control_parameter: str, ) -> str: """ Return a Boresch-style energy function for a CustomCompoundForce. Parameters ---------- control_parameter : str A string for the lambda scaling control parameter Returns ------- str The energy function string. """ energy_function = ( f"{control_parameter} * E; " "E = (K_r/2)*(distance(p3,p4) - r_aA0)^2 " "+ (K_thetaA/2)*(angle(p2,p3,p4)-theta_A0)^2 + (K_thetaB/2)*(angle(p3,p4,p5)-theta_B0)^2 " "+ (K_phiA/2)*dphi_A^2 + (K_phiB/2)*dphi_B^2 + (K_phiC/2)*dphi_C^2; " "dphi_A = dA - floor(dA/(2.0*pi)+0.5)*(2.0*pi); dA = dihedral(p1,p2,p3,p4) - phi_A0; " "dphi_B = dB - floor(dB/(2.0*pi)+0.5)*(2.0*pi); dB = dihedral(p2,p3,p4,p5) - phi_B0; " "dphi_C = dC - floor(dC/(2.0*pi)+0.5)*(2.0*pi); dC = dihedral(p3,p4,p5,p6) - phi_C0; " f"pi = {np.pi}; " ) return energy_function def get_periodic_boresch_energy_function( control_parameter: str, ) -> str: """ Return a Boresch-style energy function with a periodic torsion for a CustomCompoundForce. Parameters ---------- control_parameter : str A string for the lambda scaling control parameter Returns ------- str The energy function string. """ energy_function = ( f"{control_parameter} * E; " "E = (K_r/2)*(distance(p3,p4) - r_aA0)^2 " "+ (K_thetaA/2)*(angle(p2,p3,p4)-theta_A0)^2 + (K_thetaB/2)*(angle(p3,p4,p5)-theta_B0)^2 " "+ (K_phiA/2)*uphi_A + (K_phiB/2)*uphi_B + (K_phiC/2)*uphi_C; " "uphi_A = (1-cos(dA)); dA = dihedral(p1,p2,p3,p4) - phi_A0; " "uphi_B = (1-cos(dB)); dB = dihedral(p2,p3,p4,p5) - phi_B0; " "uphi_C = (1-cos(dC)); dC = dihedral(p3,p4,p5,p6) - phi_C0; " f"pi = {np.pi}; " ) return energy_function def get_custom_compound_bond_force( energy_function: str, n_particles: int = 6, ): """ Return an OpenMM CustomCompoundForce TODO ---- Change this to a direct subclass like openmmtools.force. Acknowledgements ---------------- Boresch-like energy functions are reproduced from `Yank `_ """ return openmm.CustomCompoundBondForce(n_particles, energy_function) def add_force_in_separate_group( system: openmm.System, force: openmm.Force, ): """ Add force to a System in a separate force group. Parameters ---------- system : openmm.System System to add the Force to. force : openmm.Force The Force to add to the System. Raises ------ ValueError If all 32 force groups are occupied. TODO ---- Unlike the original Yank implementation, we assume that all 32 force groups will not be filled. Should this be an issue we can consider just separating it from NonbondedForce. Acknowledgements ---------------- Mostly reproduced from `Yank `_. """ available_force_groups = set(range(32)) for existing_force in system.getForces(): available_force_groups.discard(existing_force.getForceGroup()) if len(available_force_groups) == 0: errmsg = "No available force groups could be found" raise ValueError(errmsg) force.setForceGroup(min(available_force_groups)) system.addForce(force) ================================================ FILE: src/openfe/protocols/restraint_utils/openmm/omm_restraints.py ================================================ # This code is part of OpenFE and is licensed under the MIT license. # For details, see https://github.com/OpenFreeEnergy/openfe """ Classes for applying restraints to OpenMM Systems. Acknowledgements ---------------- Many of the classes here are at least in part inspired from `Yank `_ and `OpenMMTools `_. TODO ---- * Add relevant duecredit entries. * Add Periodic Torsion Boresch class """ import abc import numpy as np import openmm from gufe.settings.models import SettingsBaseModel from openff.units import Quantity, unit from openff.units.openmm import from_openmm, to_openmm from openmm import unit as omm_unit from openmmtools.forces import ( FlatBottomRestraintBondForce, FlatBottomRestraintForce, HarmonicRestraintBondForce, HarmonicRestraintForce, ) from openmmtools.states import GlobalParameterState, ThermodynamicState from openfe.protocols.restraint_utils.geometry import ( BaseRestraintGeometry, BoreschRestraintGeometry, DistanceRestraintGeometry, FlatBottomDistanceGeometry, HostGuestRestraintGeometry, ) from openfe.protocols.restraint_utils.settings import ( BoreschRestraintSettings, DistanceRestraintSettings, FlatBottomRestraintSettings, ) from .omm_forces import ( add_force_in_separate_group, get_boresch_energy_function, get_custom_compound_bond_force, ) class RestraintParameterState(GlobalParameterState): """ Composable state to control `lambda_restraints` OpenMM Force parameters. See :class:`openmmtools.states.GlobalParameterState` for more details. Parameters ---------- parameters_name_suffix : Optional[str] If specified, the state will control a modified version of the parameter ``lambda_restraints_{parameters_name_suffix}` instead of just ``lambda_restraints``. lambda_restraints : Optional[float] The scaling parameter for the restraint. If defined, must be between 0 and 1. In most cases, a value of 1 indicates that the restraint is fully turned on, whilst a value of 0 indicates that it is inactive. Acknowledgement --------------- Partially reproduced from Yank. """ # We set the standard system to a fully interacting restraint lambda_restraints = GlobalParameterState.GlobalParameter( "lambda_restraints", standard_value=1.0 ) @lambda_restraints.validator # type: ignore def lambda_restraints(self, instance, new_value): if new_value is not None and not (0.0 <= new_value <= 1.0): errmsg = f"lambda_restraints must be between 0.0 and 1.0 and got {new_value}" raise ValueError(errmsg) # Not crashing out on None to match upstream behaviour return new_value class BaseHostGuestRestraints(abc.ABC): """ An abstract base class for defining objects that apply a restraint between two entities (referred to as a Host and a Guest). The following class variables must be set to the intended class to allow for type validation during the instantiation of the restraints. TODO ---- Add some developer examples here. """ _settings_cls: type[SettingsBaseModel] _geometry_cls: type[BaseRestraintGeometry] def __init__( self, restraint_settings: SettingsBaseModel, ): self.settings = restraint_settings self._verify_inputs() def _verify_inputs(self): """ Method for validating that the inputs to the class are correct. """ if not isinstance(self.settings, self._settings_cls): errmsg = f"Incorrect settings type {self.settings.__class__.__qualname__} passed through expected a `{self._settings_cls.__qualname__}` instance" raise ValueError(errmsg) def _verify_geometry(self, geometry): """ Method for validating that the geometry object passed is correct. """ if not isinstance(geometry, self._geometry_cls): errmsg = f"Incorrect geometry class type {geometry.__class__.__qualname__} passed through expected a `{self._geometry_cls.__qualname__}` instance" raise ValueError(errmsg) @abc.abstractmethod def add_force( self, thermodynamic_state: ThermodynamicState, geometry, controlling_parameter_name: str, ): """ Method for in-place adding the Force to the System of a ThermodynamicState. Parameters ---------- thermodynamic_state : ThermodynamicState The ThermodynamicState with a System to inplace modify with the new force. geometry : BaseRestraintGeometry A geometry object defining the restraint parameters. controlling_parameter_name : str The name of the controlling parameter for the Force. """ pass @abc.abstractmethod def get_standard_state_correction( self, thermodynamic_state: ThermodynamicState, geometry, ) -> Quantity: """ Get the standard state correction for the Force when applied to the input ThermodynamicState. Parameters ---------- thermodynamic_state : ThermodynamicState The ThermodynamicState with a System to inplace modify with the new force. geometry : BaseRestraintGeometry A geometry object defining the restraint parameters. Returns ------- correction : openff.units.Quantity The standard state correction free energy in units compatible with kilojoule per mole. """ pass @abc.abstractmethod def _get_force( self, geometry, controlling_parameter_name: str, ): """ Helper method to get the relevant OpenMM Force for this class, given an input geometry. """ pass class SingleBondMixin: """ A mixin to extend geometry checks for Forces that can only hold a single atom. """ def _verify_geometry(self, geometry: HostGuestRestraintGeometry): if len(geometry.host_atoms) != 1 or len(geometry.guest_atoms) != 1: errmsg = ( "host_atoms and guest_atoms must only include a single index " f"each, got {len(geometry.host_atoms)} and " f"{len(geometry.guest_atoms)} respectively." ) raise ValueError(errmsg) super(SingleBondMixin, self)._verify_geometry(geometry) # type: ignore[misc] class BaseRadiallySymmetricRestraintForce(BaseHostGuestRestraints): """ A base class for all radially symmetric Forces acting between two sets of atoms. Must be subclassed. """ _settings_cls = DistanceRestraintSettings _geometry_cls = DistanceRestraintGeometry def add_force( self, thermodynamic_state: ThermodynamicState, geometry: DistanceRestraintGeometry, controlling_parameter_name: str = "lambda_restraints", ) -> None: """ Method for in-place adding the Force to the System of the given ThermodynamicState. Parameters ---------- thermodynamic_state : ThermodynamicState The ThermodynamicState with a System to inplace modify with the new force. geometry : BaseRestraintGeometry A geometry object defining the restraint parameters. controlling_parameter_name : str The name of the controlling parameter for the Force. """ self._verify_geometry(geometry) force = self._get_force(geometry, controlling_parameter_name) force.setUsesPeriodicBoundaryConditions(thermodynamic_state.is_periodic) # Note .system is a call to get_system() so it's returning a copy system = thermodynamic_state.system add_force_in_separate_group(system, force) thermodynamic_state.system = system def get_standard_state_correction( self, thermodynamic_state: ThermodynamicState, geometry: DistanceRestraintGeometry, ) -> Quantity: """ Get the standard state correction for the Force when applied to the input ThermodynamicState. Parameters ---------- thermodynamic_state : ThermodynamicState The ThermodynamicState with a System to inplace modify with the new force. geometry : BaseRestraintGeometry A geometry object defining the restraint parameters. Returns ------- correction : openff.units.Quantity The standard state correction free energy in units compatible with kilojoule per mole. """ self._verify_geometry(geometry) # Note: this is a throw-away force, so we hard code the # controlling parameter name force = self._get_force(geometry, "lambda_restraints") corr = force.compute_standard_state_correction(thermodynamic_state, max_volume="system") dg = corr * thermodynamic_state.kT return from_openmm(dg).to("kilojoule_per_mole") def _get_force(self, geometry, controlling_parameter_name: str): raise NotImplementedError("only implemented in child classes") class HarmonicBondRestraint(SingleBondMixin, BaseRadiallySymmetricRestraintForce): """ A class to add a harmonic restraint between two atoms in an OpenMM system. The restraint is defined as a :class:`openmmtools.forces.HarmonicRestraintBondForce`. Notes ----- * Settings must contain a ``spring_constant`` for the Force in units compatible with kilojoule/mole/nm**2. """ def _get_force( self, geometry: DistanceRestraintGeometry, controlling_parameter_name: str, ) -> openmm.Force: """ Get the HarmonicRestraintBondForce given an input geometry. Parameters ---------- geometry : DistanceRestraintGeometry A geometry class that defines how the Force is applied. controlling_parameter_name : str The name of the controlling parameter for the Force. Returns ------- HarmonicRestraintBondForce An OpenMM Force that applies a harmonic restraint between two atoms. """ spring_constant = to_openmm(self.settings.spring_constant).value_in_unit_system( omm_unit.md_unit_system ) return HarmonicRestraintBondForce( spring_constant=spring_constant, restrained_atom_index1=geometry.host_atoms[0], restrained_atom_index2=geometry.guest_atoms[0], controlling_parameter_name=controlling_parameter_name, ) class FlatBottomBondRestraint(SingleBondMixin, BaseRadiallySymmetricRestraintForce): """ A class to add a flat bottom restraint between two atoms in an OpenMM system. The restraint is defined as a :class:`openmmtools.forces.FlatBottomRestraintBondForce`. Notes ----- * Settings must contain a ``spring_constant`` for the Force in units compatible with kilojoule/mole/nm**2. """ _settings_cls = FlatBottomRestraintSettings _geometry_cls: type[FlatBottomDistanceGeometry] = FlatBottomDistanceGeometry def _get_force( self, geometry: FlatBottomDistanceGeometry, controlling_parameter_name: str, ) -> openmm.Force: """ Get the FlatBottomRestraintBondForce given an input geometry. Parameters ---------- geometry : DistanceRestraintGeometry A geometry class that defines how the Force is applied. controlling_parameter_name : str The name of the controlling parameter for the Force. Returns ------- FlatBottomRestraintBondForce An OpenMM Force that applies a flat bottom restraint between two atoms. """ spring_constant = to_openmm(self.settings.spring_constant).value_in_unit_system( omm_unit.md_unit_system ) well_radius = to_openmm(geometry.well_radius).value_in_unit_system(omm_unit.md_unit_system) return FlatBottomRestraintBondForce( spring_constant=spring_constant, well_radius=well_radius, restrained_atom_index1=geometry.host_atoms[0], restrained_atom_index2=geometry.guest_atoms[0], controlling_parameter_name=controlling_parameter_name, ) class CentroidHarmonicRestraint(BaseRadiallySymmetricRestraintForce): """ A class to add a harmonic restraint between the centroid of two sets of atoms in an OpenMM system. The restraint is defined as a :class:`openmmtools.forces.HarmonicRestraintForce`. Notes ----- * Settings must contain a ``spring_constant`` for the Force in units compatible with kilojoule/mole/nm**2. """ def _get_force( self, geometry: DistanceRestraintGeometry, controlling_parameter_name: str, ) -> openmm.Force: """ Get the HarmonicRestraintForce given an input geometry. Parameters ---------- geometry : DistanceRestraintGeometry A geometry class that defines how the Force is applied. controlling_parameter_name : str The name of the controlling parameter for the Force. Returns ------- HarmonicRestraintForce An OpenMM Force that applies a harmonic restraint between the centroid of two sets of atoms. """ spring_constant = to_openmm(self.settings.spring_constant).value_in_unit_system( omm_unit.md_unit_system ) return HarmonicRestraintForce( spring_constant=spring_constant, restrained_atom_indices1=geometry.host_atoms, restrained_atom_indices2=geometry.guest_atoms, controlling_parameter_name=controlling_parameter_name, ) class CentroidFlatBottomRestraint(BaseRadiallySymmetricRestraintForce): """ A class to add a flat bottom restraint between the centroid of two sets of atoms in an OpenMM system. The restraint is defined as a :class:`openmmtools.forces.FlatBottomRestraintForce`. Notes ----- * Settings must contain a ``spring_constant`` for the Force in units compatible with kilojoule/mole/nm**2. """ def _get_force( self, geometry: FlatBottomDistanceGeometry, controlling_parameter_name: str, ) -> openmm.Force: """ Get the FlatBottomRestraintForce given an input geometry. Parameters ---------- geometry : DistanceRestraintGeometry A geometry class that defines how the Force is applied. controlling_parameter_name : str The name of the controlling parameter for the Force. Returns ------- FlatBottomRestraintForce An OpenMM Force that applies a flat bottom restraint between the centroid of two sets of atoms. """ spring_constant = to_openmm(self.settings.spring_constant).value_in_unit_system( omm_unit.md_unit_system ) # the geometry will take precedence over the settings well_radius = self.settings.well_radius or geometry.well_radius well_radius = to_openmm(well_radius).value_in_unit_system(omm_unit.md_unit_system) return FlatBottomRestraintForce( spring_constant=spring_constant, well_radius=well_radius, restrained_atom_indices1=geometry.host_atoms, restrained_atom_indices2=geometry.guest_atoms, controlling_parameter_name=controlling_parameter_name, ) class BoreschRestraint(BaseHostGuestRestraints): """ A class to add a Boresch-like restraint between six atoms, The restraint is defined as a :class:`openmmtools.forces.CustomCompoundForce` with the following energy function: lambda_control_parameter * E; E = (K_r/2)*(distance(p3,p4) - r_aA0)^2 + (K_thetaA/2)*(angle(p2,p3,p4)-theta_A0)^2 + (K_thetaB/2)*(angle(p3,p4,p5)-theta_B0)^2 + (K_phiA/2)*dphi_A^2 + (K_phiB/2)*dphi_B^2 + (K_phiC/2)*dphi_C^2; dphi_A = dA - floor(dA/(2.0*pi)+0.5)*(2.0*pi); dA = dihedral(p1,p2,p3,p4) - phi_A0; dphi_B = dB - floor(dB/(2.0*pi)+0.5)*(2.0*pi); dB = dihedral(p2,p3,p4,p5) - phi_B0; dphi_C = dC - floor(dC/(2.0*pi)+0.5)*(2.0*pi); dC = dihedral(p3,p4,p5,p6) - phi_C0; Where p1, p2, p3, p4, p5, p6 represent host atoms 2, 1, 0, and guest atoms 0, 1, 2 respectively. ``lambda_control_parameter`` is a control parameter for scaling the Force. ``K_r`` is defined as the bond spring constant between p3 and p4 and must be provided in the settings in units compatible with kilojoule / mole. ``r_aA0`` is the equilibrium distance of the bond between p3 and p4. This must be provided by the Geometry class in units compatiblle with nanometer. ``K_thetaA`` and ``K_thetaB`` are the spring constants for the angles formed by (p2, p3, p4) and (p3, p4, p5). They must be provided in the settings in units compatible with kilojoule / mole / radians**2. ``theta_A0`` and ``theta_B0`` are the equilibrium values for angles (p2, p3, p4) and (p3, p4, p5). They must be provided by the Geometry class in units compatible with radians. ``K_phiA``, ``K_phiB``, and ``K_phiC`` are the equilibrium force constants for the dihedrals formed by (p1, p2, p3, p4), (p2, p3, p4, p5), and (p3, p4, p5, p6). They must be provided in the settings in units compatible with kilojoule / mole / radians ** 2. ``phi_A0``, ``phi_B0``, and ``phi_C0`` are the equilibrium values for the dihedrals formed by (p1, p2, p3, p4), (p2, p3, p4, p5), and (p3, p4, p5, p6). They must be provided in the Geometry class in units compatible with radians. Notes ----- * Settings must define the ``K_r`` (d) """ _settings_cls = BoreschRestraintSettings _geometry_cls = BoreschRestraintGeometry def add_force( self, thermodynamic_state: ThermodynamicState, geometry: BoreschRestraintGeometry, controlling_parameter_name: str, ) -> None: """ Method for in-place adding the Boresch CustomCompoundForce to the System of the given ThermodynamicState. Parameters ---------- thermodynamic_state : ThermodynamicState The ThermodynamicState with a System to inplace modify with the new force. geometry : BaseRestraintGeometry A geometry object defining the restraint parameters. controlling_parameter_name : str The name of the controlling parameter for the Force. """ self._verify_geometry(geometry) force = self._get_force( geometry, controlling_parameter_name, ) force.setUsesPeriodicBoundaryConditions(thermodynamic_state.is_periodic) # Note .system is a call to get_system() so it's returning a copy system = thermodynamic_state.system add_force_in_separate_group(system, force) thermodynamic_state.system = system def _get_force( self, geometry: BoreschRestraintGeometry, controlling_parameter_name: str ) -> openmm.CustomCompoundBondForce: """ Get the CustomCompoundForce with a Boresch-like energy function given an input geometry. Parameters ---------- geometry : DistanceRestraintGeometry A geometry class that defines how the Force is applied. controlling_parameter_name : str The name of the controlling parameter for the Force. Returns ------- CustomCompoundForce An OpenMM CustomCompoundForce that applies a Boresch-like restraint between 6 atoms. """ efunc = get_boresch_energy_function(controlling_parameter_name) force = get_custom_compound_bond_force( energy_function=efunc, n_particles=6, ) param_values = [] parameter_dict = { "K_r": self.settings.K_r, "r_aA0": geometry.r_aA0, "K_thetaA": self.settings.K_thetaA, "theta_A0": geometry.theta_A0, "K_thetaB": self.settings.K_thetaB, "theta_B0": geometry.theta_B0, "K_phiA": self.settings.K_phiA, "phi_A0": geometry.phi_A0, "K_phiB": self.settings.K_phiB, "phi_B0": geometry.phi_B0, "K_phiC": self.settings.K_phiC, "phi_C0": geometry.phi_C0, } for key, val in parameter_dict.items(): param_values.append(to_openmm(val).value_in_unit_system(omm_unit.md_unit_system)) force.addPerBondParameter(key) force.addGlobalParameter(controlling_parameter_name, 1.0) atoms = [ geometry.host_atoms[2], geometry.host_atoms[1], geometry.host_atoms[0], geometry.guest_atoms[0], geometry.guest_atoms[1], geometry.guest_atoms[2], ] force.addBond(atoms, param_values) force.setName("Boresch-like") return force def get_standard_state_correction( self, thermodynamic_state: ThermodynamicState, geometry: BoreschRestraintGeometry, ) -> Quantity: """ Get the standard state correction for the Boresch-like restraint when applied to the input ThermodynamicState. The correction is calculated using the analytical method as defined by Boresch et al. [1] Parameters ---------- thermodynamic_state : ThermodynamicState The ThermodynamicState with a System to inplace modify with the new force. geometry : BaseRestraintGeometry A geometry object defining the restraint parameters. Returns ------- correction : openff.units.Quantity The standard state correction free energy in units compatible with kilojoule per mole. References ---------- [1] Boresch S, Tettinger F, Leitgeb M, Karplus M. J Phys Chem B. 107:9535, 2003. http://dx.doi.org/10.1021/jp0217839 """ self._verify_geometry(geometry) StandardV = 1.66053928 * unit.nanometer**3 kt = from_openmm(thermodynamic_state.kT) # distances r_aA0 = geometry.r_aA0.to("nm") sin_thetaA0 = np.sin(geometry.theta_A0.to("radians")) sin_thetaB0 = np.sin(geometry.theta_B0.to("radians")) # restraint energies K_r = self.settings.K_r.to("kilojoule_per_mole / nm ** 2") K_thetaA = self.settings.K_thetaA.to("kilojoule_per_mole / radians ** 2") K_thetaB = self.settings.K_thetaB.to("kilojoule_per_mole / radians ** 2") K_phiA = self.settings.K_phiA.to("kilojoule_per_mole / radians ** 2") K_phiB = self.settings.K_phiB.to("kilojoule_per_mole / radians ** 2") K_phiC = self.settings.K_phiC.to("kilojoule_per_mole / radians ** 2") numerator1 = 8.0 * (np.pi**2) * StandardV denum1 = (r_aA0**2) * sin_thetaA0 * sin_thetaB0 numerator2 = np.sqrt(K_r * K_thetaA * K_thetaB * K_phiA * K_phiB * K_phiC) denum2 = (2.0 * np.pi * kt) ** 3 dG = -kt * np.log((numerator1 / denum1) * (numerator2 / denum2)) return dG ================================================ FILE: src/openfe/protocols/restraint_utils/settings.py ================================================ # This code is part of OpenFE and is licensed under the MIT license. # For details, see https://github.com/OpenFreeEnergy/openfe """ Settings for adding restraints. TODO ---- * Rename from host/guest to molA/molB? * Add all the restraint settings entries. """ from typing import Annotated, Literal, Optional, TypeAlias from gufe.settings import SettingsBaseModel from gufe.settings.typing import GufeQuantity, NanometerQuantity, specify_quantity_units from openff.units import unit from pydantic import ConfigDict, field_validator SpringConstantLinearQuantity: TypeAlias = Annotated[ GufeQuantity, specify_quantity_units("kilojoule_per_mole / nm ** 2") ] SpringConstantAngularQuantity: TypeAlias = Annotated[ GufeQuantity, specify_quantity_units("kilojoule_per_mole / radians ** 2") ] class BaseRestraintSettings(SettingsBaseModel): """ Base class for RestraintSettings objects. """ model_config = ConfigDict(arbitrary_types_allowed=True) class DistanceRestraintSettings(BaseRestraintSettings): """ Settings defining a distance restraint between two groups of atoms defined as ``host`` and ``guest``. """ spring_constant: SpringConstantLinearQuantity """ The distance restraint potential spring constant. """ host_atoms: Optional[list[int]] = None """ The indices of the host component atoms to restrain. If defined, these will override any automatic selection. """ guest_atoms: Optional[list[int]] = None """ The indices of the guest component atoms to restraint. If defined, these will override any automatic selection. """ central_atoms_only: bool = False """ Whether to apply the restraint solely to the central atoms of each group. Note: this can only be applied if ``host`` and ``guest`` represent small molecules. """ @field_validator("guest_atoms", "host_atoms") def positive_idxs(cls, v): if v is not None and any([i < 0 for i in v]): errmsg = "negative indices passed" raise ValueError(errmsg) return v class FlatBottomRestraintSettings(DistanceRestraintSettings): """ Settings to define a flat bottom restraint between two groups of atoms named ``host`` and ``guest``. """ well_radius: NanometerQuantity | None = None """ The distance at which the harmonic restraint is imposed in units of distance. """ @field_validator("well_radius") def positive_value(cls, v): if v is not None and v.m < 0: errmsg = f"well radius cannot be negative {v}" raise ValueError(errmsg) return v class BoreschRestraintSettings(BaseRestraintSettings): """ Settings to define a Boresch-style restraint between two groups of atoms named ``host`` and ``guest``. The restraint is defined in the following manner: H2 G2 - - - - H1 - - H0 -- G0 - - G1 Where HX represents the X index of ``host_atoms`` and GX the X indexx of ``guest_atoms``. By default, the Boresch-like restraint will be obtained using a modified version of the search algorithm implemented by Baumann et al. [1]. If ``guest_atoms`` and ``host_atoms`` are defined, these indices will be used instead. References ---------- [1] Baumann, Hannah M., et al. "Broadening the scope of binding free energy calculations using a Separated Topologies approach." (2023). [2] Wu, Zhiyi, et al. "Optimizing Absolute Binding Free Energy Calculations for Production Usage." (2025; DOI 10.26434/chemrxiv-2025-q08ld-v2) """ K_r: SpringConstantLinearQuantity = 4184.0 * unit.kilojoule_per_mole / unit.nm**2 """ The bond spring constant between H0 and G0. Default 10 kcal/mol/Ų """ K_thetaA: SpringConstantAngularQuantity = 334.72 * unit.kilojoule_per_mole / unit.radians**2 """ The spring constant for the angle formed by H1-H0-G0. Default 80 kcal/mol/rad² """ K_thetaB: SpringConstantAngularQuantity = 334.72 * unit.kilojoule_per_mole / unit.radians**2 """ The spring constant for the angle formed by H0-G0-G1. Default 80 kcal/mol/rad² """ K_phiA: SpringConstantAngularQuantity = 334.72 * unit.kilojoule_per_mole / unit.radians**2 """ The equilibrium force constant for the dihedral formed by H2-H1-H0-G0. Default 80 kcal/mol/rad² """ K_phiB: SpringConstantAngularQuantity = 334.72 * unit.kilojoule_per_mole / unit.radians**2 """ The equilibrium force constant for the dihedral formed by H1-H0-G0-G1. Default 80 kcal/mol/rad² """ K_phiC: SpringConstantAngularQuantity = 334.72 * unit.kilojoule_per_mole / unit.radians**2 """ The equilibrium force constant for the dihedral formed by H0-G0-G1-G2. Default 80 kcal/mol/rad² """ host_selection: str = "backbone" """ Boresch-like restraint search parameter. An MDAnalysis selection string to sub-select the host atoms which will be involved in the restraint. """ dssp_filter: bool = True """ Boresch-like restraint search parameter. Whether or not to try to do a DSSP filter on the host atoms. """ rmsf_cutoff: NanometerQuantity = 0.1 * unit.nanometer """ Boresch-like restraint search parameter. The cutoff value for filtering atoms by their root mean square fluctuation. Atoms with values above this cutoff will be disregarded. """ host_min_distance: NanometerQuantity = 0.5 * unit.nanometer """ Boresch-like restraint search parameter. The minimum distance between any host atom and the guest G0 atom. Must be in units compatible with nanometer. """ host_max_distance: NanometerQuantity = 1.5 * unit.nanometer """ Boresch-like restraint search parameter. The maximum distance between any host atom and the guest G0 atom. Must be in units compatible with nanometer. """ # TODO: re-enable this (Issue #1555) # host_atoms: Optional[list[int]] = None # """ # The indices of the host component atoms to restrain. # If defined, these will override any automatic selection. # """ # guest_atoms: Optional[list[int]] = None # """ # The indices of the guest component atoms to restraint. # If defined, these will override any automatic selection. # """ anchor_finding_strategy: Literal["multi-residue", "bonded"] = "bonded" """ The Boresch atom picking strategy to use. Current options: * `bonded`: pick host atoms that are bonded to each other. * `multi-residue`: pick host atoms which can span multiple residues. """ # @field_validator("guest_atoms", "host_atoms") # def positive_idxs_list(cls, v): # if v is not None and any([i < 0 for i in v]): # errmsg = "negative indices passed" # raise ValueError(errmsg) # return v ================================================ FILE: src/openfe/setup/__init__.py ================================================ # This code is part of OpenFE and is licensed under the MIT license. # For details, see https://github.com/OpenFreeEnergy/openfe from .atom_mapping import ( KartografAtomMapper, LigandAtomMapper, LigandAtomMapping, LomapAtomMapper, PersesAtomMapper, lomap_scorers, perses_scorers, ) # TODO: circular import risk with LigandNetwork # isort: off from gufe import LigandNetwork from . import ligand_network_planning from .alchemical_network_planner import RHFEAlchemicalNetworkPlanner, RBFEAlchemicalNetworkPlanner ================================================ FILE: src/openfe/setup/alchemical_network_planner/__init__.py ================================================ # This code is part of OpenFE and is licensed under the MIT license. # For details, see https://github.com/OpenFreeEnergy/openfe from .relative_alchemical_network_planner import ( RBFEAlchemicalNetworkPlanner, RHFEAlchemicalNetworkPlanner, ) ================================================ FILE: src/openfe/setup/alchemical_network_planner/abstract_alchemical_network_planner.py ================================================ # This code is part of OpenFE and is licensed under the MIT license. # For details, see https://github.com/OpenFreeEnergy/openfe import abc from typing import Iterable from gufe import AlchemicalNetwork class AbstractAlchemicalNetworkPlanner(abc.ABC): """ this abstract class defines the interface for the alchemical Network Planners. """ @abc.abstractmethod def __call__(self, *args, **kwargs) -> AlchemicalNetwork: raise NotImplementedError() ================================================ FILE: src/openfe/setup/alchemical_network_planner/relative_alchemical_network_planner.py ================================================ # This code is part of OpenFE and is licensed under the MIT license. # For details, see https://github.com/OpenFreeEnergy/openfe import abc import warnings from typing import Callable, Iterable, Optional, Type from gufe import ( AlchemicalNetwork, ChemicalSystem, LigandAtomMapping, LigandNetwork, ProteinComponent, Protocol, SmallMoleculeComponent, SolventComponent, Transformation, ) from ...protocols.openmm_rfe.equil_rfe_methods import RelativeHybridTopologyProtocol from .. import LomapAtomMapper from ..atom_mapping.ligandatommapper import LigandAtomMapper from ..atom_mapping.lomap_scorers import default_lomap_score from ..chemicalsystem_generator import ( EasyChemicalSystemGenerator, RFEComponentLabels, ) from ..chemicalsystem_generator.abstract_chemicalsystem_generator import ( AbstractChemicalSystemGenerator, ) from ..ligand_network_planning import generate_minimal_spanning_network from .abstract_alchemical_network_planner import ( AbstractAlchemicalNetworkPlanner, ) # TODO: move/or find better structure for protocol_generator combinations! PROTOCOL_GENERATOR = { RelativeHybridTopologyProtocol: EasyChemicalSystemGenerator, } class RelativeAlchemicalNetworkPlanner(AbstractAlchemicalNetworkPlanner, abc.ABC): _chemical_system_generator: AbstractChemicalSystemGenerator def __init__( self, name: str = "easy_rfe_calculation", # TODO: remove 'easy' mappers: Optional[Iterable[LigandAtomMapper]] = None, mapping_scorer: Callable[[LigandAtomMapping], float] = default_lomap_score, ligand_network_planner: Callable = generate_minimal_spanning_network, protocol: Optional[Protocol] = None, ): """A simple strategy for executing a given protocol with mapper, mapping_scorers and networks for relative FE approaches. Parameters ---------- name : str, optional name of the approach/project the rfe, by default "easy_rfe_calculation" mappers : Iterable[LigandAtomMapper], optional mappers used to connect the ligands, by default the LomapAtomMapper with sensible default settings mapping_scorer : Callable, optional scorer evaluating the quality of the atom mappings, by default default_lomap_score ligand_network_planner : Callable, optional network using mapper and mapping_scorer to build up an optimal network, by default generate_minimal_spanning_network protocol : Protocol, optional FE-protocol for each transformation (edge of ligand network) that is required in order to calculate the FE graph, by default RelativeHybridTopologyProtocol( RelativeHybridTopologyProtocol._default_settings() ) """ if protocol is None: protocol = RelativeHybridTopologyProtocol( RelativeHybridTopologyProtocol.default_settings() ) if mappers is None: mappers = [ LomapAtomMapper( time=20, threed=True, max3d=1.0, element_change=True, shift=False, ) ] self.name = name self._mappers = mappers self._mapping_scorer = mapping_scorer self._ligand_network_planner = ligand_network_planner self._protocol = protocol self._chemical_system_generator_type = PROTOCOL_GENERATOR[protocol.__class__] @abc.abstractmethod def __call__(self, *args, **kwargs) -> AlchemicalNetwork: ... # -no-cov- @property def mappers(self) -> Iterable[LigandAtomMapper]: return self._mappers @property def mapping_scorer(self) -> Callable: return self._mapping_scorer @property def ligand_network_planner(self) -> Callable: return self._ligand_network_planner @property def transformation_protocol(self) -> Protocol: return self._protocol @property def chemical_system_generator_type( self, ) -> Type[AbstractChemicalSystemGenerator]: return self._chemical_system_generator_type def _construct_ligand_network(self, ligands: Iterable[SmallMoleculeComponent]) -> LigandNetwork: ligand_network = self._ligand_network_planner( ligands=ligands, mappers=self.mappers, scorer=self.mapping_scorer ) return ligand_network def _build_transformations( self, ligand_network_edges: Iterable[LigandAtomMapping], protocol: Protocol, chemical_system_generator: AbstractChemicalSystemGenerator, ) -> AlchemicalNetwork: """Construct alchemical network by building transformations from ligand network and adding the given protocol to each transformation. Parameters ---------- ligand_network_edges : Iterable[LigandAtomMapping] result from the ligand network planner connecting all Ligands, planning the transformations. protocol : Protocol simulation protocol for each transformation. chemical_system_generator : AbstractChemicalSystemGenerator generator, constructing all required chemical systems for each transformation. Returns ------- AlchemicalNetwork knows all transformations and their states that need to be simulated. """ transformation_edges = [] end_state_nodes = [] for ligand_mapping_edge in ligand_network_edges: for stateA_env, stateB_env in zip( chemical_system_generator(ligand_mapping_edge.componentA), chemical_system_generator(ligand_mapping_edge.componentB), ): transformation_edge = self._build_transformation( ligand_mapping_edge=ligand_mapping_edge, stateA=stateA_env, stateB=stateB_env, transformation_protocol=protocol, ) transformation_edges.append(transformation_edge) end_state_nodes.extend([stateA_env, stateB_env]) # Todo: make the code here more stable in future: Name doubling check all_transformation_labels = list(map(lambda x: x.name, transformation_edges)) if len(all_transformation_labels) != len(set(all_transformation_labels)): raise ValueError( "There were multiple transformations with the same edge label! This might lead to overwriting your files. \n labels: " + str(len(all_transformation_labels)) + "\nunique: " + str(len(set(all_transformation_labels))) + "\ngot: \n\t" + "\n\t".join(all_transformation_labels) ) alchemical_network = AlchemicalNetwork( nodes=end_state_nodes, edges=transformation_edges, name=self.name ) return alchemical_network def _build_transformation( self, ligand_mapping_edge: LigandAtomMapping, stateA: ChemicalSystem, stateB: ChemicalSystem, transformation_protocol: Protocol, ) -> Transformation: """ This function is the core of building transformations. it builds a transformation with the given protocol. Parameters ---------- ligand_mapping_edge: LigandAtomMapping stateA: ChemicalSystem stateB: ChemicalSystem Returns ------- Transformation """ transformation_name = self.name + "_" + stateA.name + "_" + stateB.name # Todo: Another dirty hack! - START protocol_settings = transformation_protocol.settings.unfrozen_copy() if "vacuum" in transformation_name: protocol_settings.forcefield_settings.nonbonded_method = "nocutoff" transformation_protocol = transformation_protocol.__class__(settings=protocol_settings) return Transformation( stateA=stateA, stateB=stateB, mapping=ligand_mapping_edge, name=transformation_name, protocol=transformation_protocol, ) class RHFEAlchemicalNetworkPlanner(RelativeAlchemicalNetworkPlanner): """ Plan alchemical networks for Relative Hydration Free Energy calculations. Create an instance of the class with a simulation protocol and ligand network planning scheme, then call it on a collection of ligands and solvent to create the network. """ def __init__( self, name: str = "rhfe", mappers: Optional[Iterable[LigandAtomMapper]] = None, mapping_scorer: Callable[[LigandAtomMapping], float] = default_lomap_score, ligand_network_planner: Callable = generate_minimal_spanning_network, protocol: Optional[Protocol] = None, ): super().__init__( name=name, mappers=mappers, mapping_scorer=mapping_scorer, ligand_network_planner=ligand_network_planner, protocol=protocol, ) def __call__( self, ligands: Iterable[SmallMoleculeComponent], solvent: SolventComponent, ) -> AlchemicalNetwork: """plan the alchemical network for the given ligands and solvent. Parameters ---------- ligands : Iterable[SmallMoleculeComponent] ligands that shall be used for the alchemical network. solvent : SolventComponent solvent for solvated simulations Returns ------- AlchemicalNetwork RHFE network for the given ligands and solvent. """ # components might be given differently! # throw into ligand_network_planning self._ligand_network = self._construct_ligand_network(ligands) # Prepare system generation self._chemical_system_generator = self._chemical_system_generator_type( solvent=solvent, do_vacuum=True, ) # Build transformations self._alchemical_network = self._build_transformations( ligand_network_edges=self._ligand_network.edges, protocol=self.transformation_protocol, chemical_system_generator=self._chemical_system_generator, ) return self._alchemical_network class RBFEAlchemicalNetworkPlanner(RelativeAlchemicalNetworkPlanner): """ Plan alchemical networks for Relative Binding Free Energy calculations. Create an instance of the class with a simulation protocol and ligand network planning scheme, then call it on a collection of ligands, protein, solvent, and co-factors to create the network. """ def __init__( self, name: str = "rbfe", mappers: Optional[Iterable[LigandAtomMapper]] = None, mapping_scorer: Callable[[LigandAtomMapping], float] = default_lomap_score, ligand_network_planner: Callable = generate_minimal_spanning_network, protocol: Optional[Protocol] = None, ): super().__init__( name=name, mappers=mappers, mapping_scorer=mapping_scorer, ligand_network_planner=ligand_network_planner, protocol=protocol, ) def _build_transformation( self, ligand_mapping_edge: LigandAtomMapping, stateA: ChemicalSystem, stateB: ChemicalSystem, transformation_protocol: Protocol, ) -> Transformation: """ Overwrite the default method to handle net charge change transformations with our default protocol. """ transformation_name = self.name + "_" + stateA.name + "_" + stateB.name protocol_settings = transformation_protocol.settings.unfrozen_copy() if isinstance(transformation_protocol, RelativeHybridTopologyProtocol): # adaptive transformation settings are only supported for RelativeHybridTopologyProtocol currently protocol_settings = transformation_protocol._adaptive_settings( stateA=stateA, stateB=stateB, mapping=ligand_mapping_edge, initial_settings=protocol_settings, ) if "vacuum" in transformation_name: protocol_settings.nonbonded_method = "nocutoff" transformation_protocol = transformation_protocol.__class__(settings=protocol_settings) transformation_protocol.validate(stateA=stateA, stateB=stateB, mapping=ligand_mapping_edge) return Transformation( stateA=stateA, stateB=stateB, mapping=ligand_mapping_edge, name=transformation_name, protocol=transformation_protocol, ) def __call__( self, ligands: Iterable[SmallMoleculeComponent], solvent: SolventComponent, protein: ProteinComponent, cofactors: Optional[Iterable[SmallMoleculeComponent]] = None, ) -> AlchemicalNetwork: """plan the alchemical network for RBFE calculations with the given ligands, protein and solvent. Parameters ---------- ligands : Iterable[SmallMoleculeComponent] ligands that shall be used for the alchemical network. solvent : SolventComponent solvent for solvated and complex simulations protein : ProteinComponent protein for complex simulations cofactors : Iterable[SmallMoleculeComponent] any cofactors in the system, can be empty list Returns ------- AlchemicalNetwork RBFE network for the given ligands, protein and solvent. """ # components might be given differently! # throw into ligand_network_planning self._ligand_network = self._construct_ligand_network(ligands) # Prepare system generation self._chemical_system_generator = self._chemical_system_generator_type( solvent=solvent, protein=protein, cofactors=cofactors, ) # Build transformations self._alchemical_network = self._build_transformations( ligand_network_edges=self._ligand_network.edges, protocol=self._protocol, chemical_system_generator=self._chemical_system_generator, ) return self._alchemical_network ================================================ FILE: src/openfe/setup/atom_mapping/__init__.py ================================================ from gufe import LigandAtomMapping from kartograf import KartografAtomMapper from . import lomap_scorers, perses_scorers from .ligandatommapper import LigandAtomMapper from .lomap_mapper import LomapAtomMapper from .perses_mapper import PersesAtomMapper ================================================ FILE: src/openfe/setup/atom_mapping/ligandatommapper.py ================================================ # This code is part of OpenFE and is licensed under the MIT license. # For details, see https://github.com/OpenFreeEnergy/openfe import abc from typing import Iterable import gufe from gufe import SmallMoleculeComponent from . import LigandAtomMapping class LigandAtomMapper(gufe.AtomMapper): """ Suggest atom mappings between two :class:`SmallMoleculeComponent` instances. Subclasses will typically implement the ``_mappings_generator`` method, which returns an iterable of :class:`.LigandAtomMapping` suggestions. """ @abc.abstractmethod def _mappings_generator( self, componentA: SmallMoleculeComponent, componentB: SmallMoleculeComponent, ) -> Iterable[dict[int, int]]: """ Suggest mapping options for the input molecules. Parameters ---------- componentA, componentB : rdkit.Mol the two molecules to create a mapping for Returns ------- Iterable[dict[int, int]] : an iterable over proposed mappings from componentA to componentB """ ... def suggest_mappings( self, componentA: SmallMoleculeComponent, componentB: SmallMoleculeComponent, ) -> Iterable[LigandAtomMapping]: """ Suggest :class:`.LigandAtomMapping` options for the input molecules. Parameters --------- componentA, componentB : :class:`.SmallMoleculeComponent` the two molecules to create a mapping for Returns ------- Iterable[LigandAtomMapping] : an iterable over proposed mappings """ # For this base class, implementation is redundant with # _mappings_generator. However, we keep it separate so that abstract # subclasses of this can customize suggest_mappings while always # maintaining the consistency that concrete implementations must # implement _mappings_generator. for map_dct in self._mappings_generator(componentA, componentB): yield LigandAtomMapping(componentA, componentB, map_dct) ================================================ FILE: src/openfe/setup/atom_mapping/lomap_mapper.py ================================================ # This code is part of OpenFE and is licensed under the MIT license. # For details, see https://github.com/OpenFreeEnergy/openfe """ The MCS class from Lomap shamelessly wrapped and used here to match our API. """ from lomap import LomapAtomMapper ================================================ FILE: src/openfe/setup/atom_mapping/lomap_scorers.py ================================================ # This code is part of OpenFE and is licensed under the MIT license. # For details, see https://github.com/OpenFreeEnergy/openfe from lomap.gufe_bindings.scorers import ( atomic_number_score, default_lomap_score, ecr_score, heterocycles_score, hybridization_score, mcsr_score, mncar_score, sulfonamides_score, tmcsr_score, transmuting_methyl_into_ring_score, transmuting_ring_sizes_score, ) # looks like we gotta make it detailed for mypy and RTD ================================================ FILE: src/openfe/setup/atom_mapping/perses_mapper.py ================================================ # This code is part of OpenFE and is licensed under the MIT license. # For details, see https://github.com/OpenFreeEnergy/openfe """ The MCS class from Perses shamelessly wrapped and used here to match our API. """ import warnings from gufe.settings.typing import AngstromQuantity from openff.units import Quantity, unit from openff.units.openmm import to_openmm from openfe.utils import requires_package from ...utils.silence_root_logging import silence_root_logging try: with silence_root_logging(): from perses.rjmc.atom_mapping import AtomMapper, InvalidMappingException except ImportError: pass # Don't throw error, will happen later from .ligandatommapper import LigandAtomMapper class PersesAtomMapper(LigandAtomMapper): allow_ring_breaking: bool preserve_chirality: bool use_positions: bool coordinate_tolerance: AngstromQuantity def _to_dict(self) -> dict: # strip units but record values return { "allow_ring_breaking": self.allow_ring_breaking, "preserve_chirality": self.preserve_chirality, "use_positions": self.use_positions, "coordinate_tolerance": self.coordinate_tolerance.m_as(unit.angstrom), "_tolerance_unit": "angstrom", } @classmethod def _from_dict(cls, dct: dict): # attach units again tolerence_unit = dct.pop("_tolerance_unit") dct["coordinate_tolerance"] *= getattr(unit, tolerence_unit) return cls(**dct) @classmethod def _defaults(cls): return {} @requires_package("perses") def __init__( self, allow_ring_breaking: bool = True, preserve_chirality: bool = True, use_positions: bool = True, coordinate_tolerance: Quantity = 0.25 * unit.angstrom, ): """ Suggest atom mappings with the Perses atom mapper. Parameters ---------- allow_ring_breaking: bool, optional this option checks if on only full cycles of the molecules shall be mapped, default: False preserve_chirality: bool, optional if mappings must strictly preserve chirality, default: True use_positions: bool, optional this option defines, if the coordinate_tolerance: openff.units.unit.Quantity, optional tolerance on how close coordinates need to be, such they can be mapped, default: 0.25*unit.angstrom """ warnings.warn( "PersesAtomMapper is deprecated and is planned to be removed in openfe v2.0. If you have questions related to this, please open an issue at https://github.com/OpenFreeEnergy/openfe/issues.", DeprecationWarning, ) self.allow_ring_breaking = allow_ring_breaking self.preserve_chirality = preserve_chirality self.use_positions = use_positions self.coordinate_tolerance = coordinate_tolerance def _mappings_generator(self, componentA, componentB): # Construct Perses Mapper _atom_mapper = AtomMapper( use_positions=self.use_positions, coordinate_tolerance=to_openmm(self.coordinate_tolerance), allow_ring_breaking=self.allow_ring_breaking, ) # Try generating a mapping try: _atom_mappings = _atom_mapper.get_all_mappings( old_mol=componentA.to_openff(), new_mol=componentB.to_openff() ) except InvalidMappingException: return # Catch empty mappings here if _atom_mappings is None: return # Post processing if self.preserve_chirality: for x in _atom_mappings: x.preserve_chirality() # Translate mapping objects mapping_dict = (x.old_to_new_atom_map for x in _atom_mappings) yield from mapping_dict ================================================ FILE: src/openfe/setup/atom_mapping/perses_scorers.py ================================================ # This code is part of OpenFE and is licensed under the MIT license. # For details, see https://github.com/OpenFreeEnergy/openfe import warnings from typing import Callable from openfe.utils import requires_package from ...utils.silence_root_logging import silence_root_logging try: with silence_root_logging(): from perses.rjmc.atom_mapping import AtomMapper, AtomMapping except ImportError: pass # Don't throw error, will happen later from . import LigandAtomMapping # Helper Function / reducing code amount def _get_all_mapped_atoms_with( oeyMolA, oeyMolB, numMaxPossibleMappingAtoms: int, criterium: Callable, ) -> int: molA_allAtomsWith = len(list(filter(criterium, oeyMolA.GetAtoms()))) molB_allAtomsWith = len(list(filter(criterium, oeyMolB.GetAtoms()))) if molA_allAtomsWith > molB_allAtomsWith and molA_allAtomsWith <= numMaxPossibleMappingAtoms: numMaxPossibleMappings = molA_allAtomsWith else: numMaxPossibleMappings = molB_allAtomsWith return numMaxPossibleMappings @requires_package("perses") def default_perses_scorer( mapping: LigandAtomMapping, use_positions: bool = False, normalize: bool = True, ) -> float: """ Score an atom mapping with the default Perses score function. Parameters ---------- mapping: LigandAtomMapping is an OpenFE Ligand Mapping, that should be mapped use_positions: bool, optional if the positions are used, perses takes the inverse eucledian distance of mapped atoms into account. else the number of mapped atoms is used for the score. default True normalize: bool, optional if true, the scores get normalized, such that different molecule pairs can be compared for one scorer metric, default = True *Warning* does not work for use_positions right now! Raises ------ NotImplementedError Normalization of the score using positions is not implemented right now. Returns ------- float """ warnings.warn( "default_perses_scorer is deprecated and is planned to be removed in openfe v2.0. If you have questions related to this, please open an issue at https://github.com/OpenFreeEnergy/openfe/issues", DeprecationWarning, ) score = AtomMapper(use_positions=use_positions).score_mapping( AtomMapping( old_mol=mapping.componentA.to_openff(), new_mol=mapping.componentB.to_openff(), old_to_new_atom_map=mapping.componentA_to_componentB, ) ) # normalize if normalize: oeyMolA = mapping.componentA.to_openff().to_openeye() oeyMolB = mapping.componentB.to_openff().to_openeye() if use_positions: raise NotImplementedError("normalizing using positions is not currently implemented") else: smallerMolecule = oeyMolA if (oeyMolA.NumAtoms() < oeyMolB.NumAtoms()) else oeyMolB numMaxPossibleMappingAtoms = smallerMolecule.NumAtoms() # Max possible Aromatic mappings numMaxPossibleAromaticMappings = _get_all_mapped_atoms_with( oeyMolA=oeyMolA, oeyMolB=oeyMolB, numMaxPossibleMappingAtoms=numMaxPossibleMappingAtoms, criterium=lambda x: x.IsAromatic(), ) # Max possible heavy mappings numMaxPossibleHeavyAtomMappings = _get_all_mapped_atoms_with( oeyMolA=oeyMolA, oeyMolB=oeyMolB, numMaxPossibleMappingAtoms=numMaxPossibleMappingAtoms, criterium=lambda x: x.GetAtomicNum() > 1, ) # Max possible ring mappings numMaxPossibleRingMappings = _get_all_mapped_atoms_with( oeyMolA=oeyMolA, oeyMolB=oeyMolB, numMaxPossibleMappingAtoms=numMaxPossibleMappingAtoms, criterium=lambda x: x.IsInRing(), ) # These weights are totally arbitrary normalize_score = ( 1.0 * numMaxPossibleMappingAtoms + 0.8 * numMaxPossibleAromaticMappings + 0.5 * numMaxPossibleHeavyAtomMappings + 0.4 * numMaxPossibleRingMappings ) score /= normalize_score # final normalize score return score ================================================ FILE: src/openfe/setup/chemicalsystem_generator/__init__.py ================================================ # This code is part of OpenFE and is licensed under the MIT license. # For details, see https://github.com/OpenFreeEnergy/openfe from .abstract_chemicalsystem_generator import RFEComponentLabels from .easy_chemicalsystem_generator import EasyChemicalSystemGenerator ================================================ FILE: src/openfe/setup/chemicalsystem_generator/abstract_chemicalsystem_generator.py ================================================ # This code is part of OpenFE and is licensed under the MIT license. # For details, see https://github.com/OpenFreeEnergy/openfe import abc from enum import Enum from typing import Iterable from gufe import ChemicalSystem # Todo: connect to protocols - use this for labels? class RFEComponentLabels(str, Enum): PROTEIN = "protein" LIGAND = "ligand" SOLVENT = "solvent" COFACTOR = "cofactor" class AbstractChemicalSystemGenerator(abc.ABC): """ this abstract class defines the interface for the chemical system generators. """ @abc.abstractmethod def __call__(self, *args, **kwargs) -> Iterable[ChemicalSystem]: raise NotImplementedError() ================================================ FILE: src/openfe/setup/chemicalsystem_generator/easy_chemicalsystem_generator.py ================================================ # This code is part of OpenFE and is licensed under the MIT license. # For details, see https://github.com/OpenFreeEnergy/openfe from typing import Iterable, Optional from gufe import ( ChemicalSystem, Component, ProteinComponent, ProteinMembraneComponent, SmallMoleculeComponent, SolventComponent, ) from .abstract_chemicalsystem_generator import ( AbstractChemicalSystemGenerator, RFEComponentLabels, ) class EasyChemicalSystemGenerator(AbstractChemicalSystemGenerator): def __init__( self, solvent: SolventComponent | None = None, protein: ProteinComponent | None = None, cofactors: Iterable[SmallMoleculeComponent] | None = None, do_vacuum: bool = False, ): """ Generate consistent chemical systems given a :class:`SmallMoleculeComponent`. This class aids preparation of :class:`ChemicalSystem` instances for free energy simulations. Construct an instance of the class with all the components except the :class:`SmallMoleculeComponent` that will be mutated, and then call the instance on each mutation target to prepare systems in vacuum, solvent, and with protein. This class is a easy generator class, for generating chemical systems with a focus on a given SmallMoleculeComponent. Depending on which parameters are given, the following systems will be generated in order: vacuum -> solvent -> protein Parameters ---------- solvent : SolventComponent, optional if a SolventComponent is given, solvated chemical systems will be generated, by default None protein : ProteinComponent, optional if a ProteinComponent is given, complex chemical systems will be generated, by default None cofactors : Iterable[SmallMoleculeComponent], optional any cofactors in the system. will be put in any systems containing the protein do_vacuum : bool, optional if true a chemical system in vacuum is returned, by default False Raises ------ ValueError If neither a solvent nor protein is provided and ``do_vacuum`` is false. """ self.solvent = solvent self.protein = protein self.cofactors = cofactors or [] self.do_vacuum = do_vacuum if solvent is None and protein is None and not do_vacuum: raise ValueError( "Chemical system generator is unable to generate any chemical systems with neither protein nor solvent nor do_vacuum" ) def __call__(self, component: SmallMoleculeComponent) -> Iterable[ChemicalSystem]: """Generate systems around the given :class:`SmallMoleculeComponent`. Parameters ---------- component : SmallMoleculeComponent The molecule for the system generation. Returns ------- Iterable[ChemicalSystem] Generator for systems with the given environments. Returns a vacuum system first in ``self.do_vacuum`` is true, then a solvated system without protein, then finally a solvated system with protein if the protein component is set. """ if self.do_vacuum: chem_sys = ChemicalSystem( components={RFEComponentLabels.LIGAND.value: component}, name=component.name + "_vacuum", ) yield chem_sys if self.solvent is not None: chem_sys = ChemicalSystem( components={ RFEComponentLabels.LIGAND.value: component, RFEComponentLabels.SOLVENT.value: self.solvent, }, name=component.name + "_solvent", ) yield chem_sys components: dict[str, Component] if self.protein is not None: components = { RFEComponentLabels.LIGAND.value: component, RFEComponentLabels.PROTEIN.value: self.protein, } for i, c in enumerate(self.cofactors): components.update({f"{RFEComponentLabels.COFACTOR.value}{i + 1}": c}) # ProteinMembraneComponent has its own solvent. if self.solvent is not None and not isinstance(self.protein, ProteinMembraneComponent): components.update({RFEComponentLabels.SOLVENT.value: self.solvent}) chem_sys = ChemicalSystem(components=components, name=component.name + "_complex") yield chem_sys return ================================================ FILE: src/openfe/setup/ligand_network_planning.py ================================================ # This code is part of OpenFE and is licensed under the MIT license. # For details, see https://github.com/OpenFreeEnergy/openfe from pathlib import Path from typing import Callable, Iterable, Optional, Union import networkx as nx from gufe import AtomMapper, SmallMoleculeComponent from konnektor import network_analysis, network_planners, network_tools from konnektor.network_planners import ( ExplicitNetworkGenerator, MaximalNetworkGenerator, MinimalSpanningTreeNetworkGenerator, RedundantMinimalSpanningTreeNetworkGenerator, StarNetworkGenerator, ) from lomap import LomapAtomMapper # import to expose generate_lomap_network in openfe from lomap import generate_lomap_network as generate_lomap_network from lomap.dbmol import _find_common_core from openfe.setup import LigandNetwork from openfe.setup.atom_mapping import LigandAtomMapping def _hasten_lomap(mapper, ligands): """take a mapper and some ligands, put a common core arg into the mapper""" if mapper.seed: return mapper try: core = _find_common_core( [m.to_rdkit() for m in ligands], element_change=mapper.element_change ) except RuntimeError: # in case MCS throws a hissy fit core = "" return LomapAtomMapper( time=mapper.time, threed=mapper.threed, max3d=mapper.max3d, element_change=mapper.element_change, seed=core, shift=mapper.shift, ) def generate_radial_network( ligands: Iterable[SmallMoleculeComponent], central_ligand: Union[SmallMoleculeComponent, str, int], mappers: Union[AtomMapper, Iterable[AtomMapper]], scorer: Optional[Callable[[LigandAtomMapping], float]] = None, progress: bool = False, n_processes: int = 1, ) -> LigandNetwork: """ Plan a radial network with all ligands connected to a central node. Also known as hub and spoke or star-map, this plans a LigandNetwork where all ligands are connected via a central ligand. Parameters ---------- ligands : iterable of SmallMoleculeComponents the ligands to arrange around the central ligand. If the central ligand is present it will be ignored (i.e. avoiding a self edge) central_ligand : SmallMoleculeComponent or str or int the ligand to use as the hub/central ligand. If this is a string, this should match to one and only one ligand name. If this is an integer, this refers to the index from within ligands mappers : AtomMapper or iterable of AtomMappers mapper(s) to use, at least 1 required scorer : scoring function, optional a callable which returns a float for any LigandAtomMapping. Used to assign scores to potential mappings; higher scores indicate better mappings. progress : bool If True, show a tqdm progress bar. (default=True) n_processes: int number of cpu processes to use if parallelizing network generation. Raises ------ ValueError if no mapping between the central ligand and any other ligand can be found Returns ------- network : LigandNetwork will have an edge between each ligand and the central ligand, with the mapping being the best possible mapping found using the supplied atom mappers. If no scorer is supplied, the first mapping provided by the iterable of mappers will be used. """ if isinstance(mappers, AtomMapper): mappers = [mappers] mappers = [ _hasten_lomap(m, ligands) if isinstance(m, LomapAtomMapper) else m for m in mappers ] # fmt: skip ligands = list(ligands) # handle central_ligand arg possibilities # after this, central_ligand is resolved to a SmallMoleculeComponent if isinstance(central_ligand, int): try: central_ligand = ligands[central_ligand] ligands.remove(central_ligand) except IndexError: raise ValueError( f"index '{central_ligand}' out of bounds, there are {len(ligands)} ligands" ) elif isinstance(central_ligand, str): possibles = [lig for lig in ligands if lig.name == central_ligand] if not possibles: raise ValueError( f"No ligand called '{central_ligand}' " f"available: {', '.join(lig.name for lig in ligands)}" ) if len(possibles) > 1: raise ValueError(f"Multiple ligands called '{central_ligand}'") central_ligand = possibles[0] ligands.remove(central_ligand) # Construct network network_planner = StarNetworkGenerator( mappers=mappers, scorer=scorer, progress=progress, n_processes=n_processes, ) network = network_planner.generate_ligand_network( components=ligands, central_component=central_ligand ) if network.is_connected(): connected_nodes = network.nodes else: connected_nodes = max(nx.weakly_connected_components(network.graph), key=len) # check for disconnected nodes missing_nodes = set(ligands + [central_ligand]) - set(connected_nodes) missing_node_names = [node.name for node in missing_nodes] if missing_nodes: raise RuntimeError( f"ERROR: No mapping found between the central ligand ('{central_ligand.name}') and the following node(s): {missing_node_names}" ) return network def generate_maximal_network( ligands: Iterable[SmallMoleculeComponent], mappers: Union[AtomMapper, Iterable[AtomMapper]], scorer: Optional[Callable[[LigandAtomMapping], float]] = None, progress: bool = True, n_processes: int = 1, ) -> LigandNetwork: """ Plan a network with all possible proposed mappings. This will attempt to create (and optionally score) all possible mappings (up to :math:`N(N-1)/2` for each mapper given). There may be fewer actual mappings that this because, when a mapper cannot return a mapping for a given pair, there is simply no suggested mapping for that pair. This network is typically used as the starting point for other network generators (which then optimize based on the scores) or to debug atom mappers (to see which mappings the mapper fails to generate). Parameters ---------- ligands : Iterable[SmallMoleculeComponent] the ligands to include in the LigandNetwork mappers : AtomMapper or Iterable[AtomMapper] the AtomMapper(s) to use to propose mappings. At least 1 required, but many can be given. scorer : Scoring function any callable which takes a LigandAtomMapping and returns a float progress : bool If True, show a tqdm progress bar. (default=True) n_processes: int number of cpu processes to use if parallelizing network generation. """ if isinstance(mappers, AtomMapper): mappers = [mappers] mappers = [_hasten_lomap(m, ligands) if isinstance(m, LomapAtomMapper) else m for m in mappers] nodes = list(ligands) # Construct network network_planner = MaximalNetworkGenerator( mappers=mappers, scorer=scorer, progress=progress, n_processes=n_processes, ) network = network_planner.generate_ligand_network(nodes) return network def generate_minimal_spanning_network( ligands: Iterable[SmallMoleculeComponent], mappers: Union[AtomMapper, Iterable[AtomMapper]], # TODO: scorer is currently required, but not actually necessary. scorer: Callable[[LigandAtomMapping], float], progress: bool = True, n_processes: int = 1, ) -> LigandNetwork: """ Plan a network with as few edges as possible with maximum total score Parameters ---------- ligands : Iterable[SmallMoleculeComponent] the ligands to include in the LigandNetwork mappers : AtomMapper or Iterable[AtomMapper] the AtomMapper(s) to use to propose mappings. At least 1 required, but many can be given, in which case all will be tried to find the highest score edges scorer : Scoring function any callable which takes a LigandAtomMapping and returns a float progress : bool If True, show a tqdm progress bar. (default=True) n_processes: int number of cpu processes to use if parallelizing network generation. """ if isinstance(mappers, AtomMapper): mappers = [mappers] mappers = [_hasten_lomap(m, ligands) if isinstance(m, LomapAtomMapper) else m for m in mappers] nodes = list(ligands) # Construct network network_planner = MinimalSpanningTreeNetworkGenerator( mappers=mappers, scorer=scorer, progress=progress, n_processes=n_processes, ) network = network_planner.generate_ligand_network(nodes) return network def generate_minimal_redundant_network( ligands: Iterable[SmallMoleculeComponent], mappers: Union[AtomMapper, Iterable[AtomMapper]], scorer: Callable[[LigandAtomMapping], float], progress: bool = True, mst_num: int = 2, n_processes: int = 1, ) -> LigandNetwork: """ Plan a network with a specified amount of redundancy for each node Creates a network with as few edges as possible with maximum total score, ensuring that every node is connected to two edges to introduce statistical redundancy. Parameters ---------- ligands : Iterable[SmallMoleculeComponent] the ligands to include in the LigandNetwork mappers : AtomMapper or Iterable[AtomMapper] the AtomMapper(s) to use to propose mappings. At least 1 required, but many can be given, in which case all will be tried to find the highest score edges scorer : Scoring function any callable which takes a LigandAtomMapping and returns a float progress : bool If True, show a tqdm progress bar. (default=True) mst_num : int Minimum Spanning Tree number: the number of minimum spanning trees to generate. If two, the second-best edges are included in the returned network. If three, the third-best edges are also included, etc. n_processes: int number of threads to use if parallelizing network generation """ if isinstance(mappers, AtomMapper): mappers = [mappers] mappers = [_hasten_lomap(m, ligands) if isinstance(m, LomapAtomMapper) else m for m in mappers] nodes = list(ligands) # Construct network network_planner = RedundantMinimalSpanningTreeNetworkGenerator( mappers=mappers, scorer=scorer, progress=progress, n_redundancy=mst_num, n_processes=n_processes, ) network = network_planner.generate_ligand_network(nodes) return network def generate_network_from_names( ligands: list[SmallMoleculeComponent], mapper: AtomMapper, names: list[tuple[str, str]], ) -> LigandNetwork: """ Generate a :class:`.LigandNetwork` by specifying edges as tuples of names. Parameters ---------- ligands : list of SmallMoleculeComponent the small molecules to place into the network mapper: AtomMapper the atom mapper to use to construct edges names : list of tuples of names the edges to form where the values refer to names of the small molecules, eg `[('benzene', 'toluene'), ...]` will create an edge between the molecule with names 'benzene' and 'toluene' Returns ------- LigandNetwork Raises ------ KeyError if an invalid name is requested ValueError if multiple molecules have the same name (this would otherwise be problematic) """ nodes = list(ligands) network_planner = ExplicitNetworkGenerator(mappers=mapper, scorer=None) network = network_planner.generate_network_from_names(components=nodes, names=names) return network def generate_network_from_indices( ligands: list[SmallMoleculeComponent], mapper: AtomMapper, indices: list[tuple[int, int]], ) -> LigandNetwork: """ Generate a :class:`.LigandNetwork` by specifying edges as tuples of indices. Parameters ---------- ligands : list of SmallMoleculeComponent the small molecules to place into the network mapper: AtomMapper the atom mapper to use to construct edges indices : list of tuples of indices the edges to form where the values refer to names of the small molecules, eg `[(3, 4), ...]` will create an edge between the 3rd and 4th molecules remembering that Python uses 0-based indexing Returns ------- LigandNetwork Raises ------ IndexError if an invalid ligand index is requested """ nodes = list(ligands) network_planner = ExplicitNetworkGenerator(mappers=mapper, scorer=None) network = network_planner.generate_network_from_indices(components=nodes, indices=indices) return network def load_orion_network( ligands: list[SmallMoleculeComponent], mapper: AtomMapper, network_file: Union[str, Path], ) -> LigandNetwork: """Load a :class:`.LigandNetwork` from an Orion NES network file. Parameters ---------- ligands : list of SmallMoleculeComponent the small molecules to place into the network mapper: AtomMapper the atom mapper to use to construct edges network_file : str path to NES network file. Returns ------- LigandNetwork Raises ------ KeyError If an unexpected line format is encountered. """ with open(network_file, "r") as f: network_lines = [ line.strip().split(" ") for line in f if not line.startswith("#") ] # fmt: skip names = [] for entry in network_lines: if len(entry) != 3 or entry[1] != ">>": errmsg = f"line does not match expected name >> name format: {entry}" raise KeyError(errmsg) names.append((entry[0], entry[2])) network_planner = ExplicitNetworkGenerator(mappers=mapper, scorer=None) network = network_planner.generate_network_from_names(components=ligands, names=names) return network def load_fepplus_network( ligands: list[SmallMoleculeComponent], mapper: AtomMapper, network_file: Union[str, Path], ) -> LigandNetwork: """Load a :class:`.LigandNetwork` from an FEP+ edges network file. Parameters ---------- ligands : list of SmallMoleculeComponent the small molecules to place into the network mapper: AtomMapper the atom mapper to use to construct edges network_file : str path to edges network file. Returns ------- LigandNetwork Raises ------ KeyError If an unexpected line format is encountered. """ with open(network_file, "r") as f: network_lines = [line.split() for line in f.readlines()] names = [] for entry in network_lines: if len(entry) != 5 or entry[1] != "#" or entry[3] != "->": errmsg = ( "line does not match expected format " "hash:hash # name -> name\n" f"line format: {entry}" ) raise KeyError(errmsg) names.append((entry[2], entry[4])) network_planner = ExplicitNetworkGenerator(mappers=mapper, scorer=None) network = network_planner.generate_network_from_names(components=ligands, names=names) return network ================================================ FILE: src/openfe/storage/__init__.py ================================================ ================================================ FILE: src/openfe/storage/metadatastore.py ================================================ # This code is part of OpenFE and is licensed under the MIT license. # For details, see https://github.com/OpenFreeEnergy/gufe import abc import collections import json from typing import Dict, Tuple from gufe.storage.errors import ChangedExternalResourceError, MissingExternalResourceError from gufe.storage.externalresource.base import Metadata class MetadataStore(collections.abc.Mapping): def __init__(self, external_store): self.external_store = external_store self._metadata_cache = self.load_all_metadata() @abc.abstractmethod def store_metadata(self, location: str, metadata: Metadata): raise NotImplementedError() @abc.abstractmethod def load_all_metadata(self) -> Dict[str, Metadata]: raise NotImplementedError() @abc.abstractmethod def __delitem__(self, location): raise NotImplementedError() def __getitem__(self, location): return self._metadata_cache[location] def __iter__(self): return iter(self._metadata_cache) def __len__(self): return len(self._metadata_cache) class JSONMetadataStore(MetadataStore): # Using JSON for now because it is easy to write this class and doesn't # require any external dependencies. It is NOT the right way to go in # the long term. API will probably stay the same, though. def _dump_file(self): metadata_dict = {key: val.to_dict() for key, val in self._metadata_cache.items()} metadata_bytes = json.dumps(metadata_dict).encode("utf-8") self.external_store.store_bytes("metadata.json", metadata_bytes) def store_metadata(self, location: str, metadata: Metadata): self._metadata_cache[location] = metadata self._dump_file() def load_all_metadata(self): if not self.external_store.exists("metadata.json"): return {} with self.external_store.load_stream("metadata.json") as json_f: all_metadata_dict = json.loads(json_f.read().decode("utf-8")) all_metadata = {key: Metadata(**val) for key, val in all_metadata_dict.items()} return all_metadata def __delitem__(self, location): del self._metadata_cache[location] self._dump_file() class PerFileJSONMetadataStore(MetadataStore): _metadata_prefix = "metadata/" def _metadata_path(self, location): return self._metadata_prefix + location + ".json" def store_metadata(self, location: str, metadata: Metadata): self._metadata_cache[location] = metadata path = self._metadata_path(location) dct = { "path": location, "metadata": metadata.to_dict(), } metadata_bytes = json.dumps(dct).encode("utf-8") self.external_store.store_bytes(path, metadata_bytes) def load_all_metadata(self): metadata_cache = {} prefix = self._metadata_prefix for location in self.external_store.iter_contents(prefix=prefix): if location.endswith(".json"): with self.external_store.load_stream(location) as f: dct = json.loads(f.read().decode("utf-8")) if set(dct) != {"path", "metadata"}: raise ChangedExternalResourceError(f"Bad metadata file: '{location}'") metadata_cache[dct["path"]] = Metadata(**dct["metadata"]) return metadata_cache def __delitem__(self, location): del self._metadata_cache[location] self.external_store.delete(self._metadata_path(location)) ================================================ FILE: src/openfe/storage/resultclient.py ================================================ # This code is part of OpenFE and is licensed under the MIT license. # For details, see https://github.com/OpenFreeEnergy/gufe import abc import json import re from typing import Any from gufe.tokenization import ( JSON_HANDLER, from_dict, get_all_gufe_objs, key_decode_dependencies, ) from .metadatastore import JSONMetadataStore from .resultserver import ResultServer GUFEKEY_JSON_REGEX = re.compile('":gufe-key:": "(?P[A-Za-z0-9_]+-[0-9a-f]+)"') class _ResultContainer(abc.ABC): """ Abstract class, represents all data under some level of the hierarchy. """ def __init__(self, parent, path_component): self.parent = parent self._path_component = self._to_path_component(path_component) self._cache = {} def __eq__(self, other): return isinstance(other, self.__class__) and self.path == other.path @staticmethod def _to_path_component(item: Any) -> str: """Convert input (object or string) to path string""" if isinstance(item, str): return item # TODO: instead of str(hash(...)), this should return the digest # that is being introduced in another PR; Python hash is not stable # across sessions return str(hash(item)) def __getitem__(self, item): # code for the case this is a file if item in self.result_server: return self.result_server.load_stream(item) # code for the case this is a "directory" hash_item = self._to_path_component(item) if hash_item not in self._cache: self._cache[hash_item] = self._load_next_level(item) return self._cache[hash_item] def __truediv__(self, item): return self[item] @abc.abstractmethod def _load_next_level(self, item): raise NotImplementedError() def __iter__(self): for loc in self.result_server: if loc.startswith(self.path): yield loc def load_stream(self, location, *, allow_changed=False): return self.result_server.load_stream(location, allow_changed) def load_bytes(self, location, *, allow_changed=False): with self.load_stream(location, allow_changed=allow_changed) as f: byte_data = f.read() return byte_data @property def path(self): return self.parent.path + "/" + self._path_component @property def result_server(self): return self.parent.result_server def __repr__(self): # probably should include repr of external store, too return f"{self.__class__.__name__}({self.path})" class ResultClient(_ResultContainer): def __init__(self, external_store): # default client is using JSONMetadataStore with the given external # result store; users could easily write a subblass that behaves # differently metadata_store = JSONMetadataStore(external_store) self._result_server = ResultServer(external_store, metadata_store) super().__init__(parent=self, path_component=None) def delete(self, location): self._result_server.delete(location) @staticmethod def _gufe_key_to_storage_key(prefix: str, key: str): """Create the storage key from the gufe key. Parameters ---------- prefix : str the prefix defining which section of storage should be used for this (e.g., ``setup``, ...) key : str the GufeKey for a GufeTokenizable (technically, is likely to be passed as a :class:`.GufeKey`, which is a subclass of ``str``) Returns ------- str : storage key (string identifier used by storage to locate this object) """ pref = prefix.split("/") # remove this if we switch to tuples cls, token = key.split("-") tup = tuple(list(pref) + [cls, f"{token}.json"]) # right now we're using strings, but we've talked about switching # that to tuples return "/".join(tup) def _store_gufe_tokenizable(self, prefix, obj): """generic function for deduplicating/storing a GufeTokenizable""" for o in get_all_gufe_objs(obj): key = self._gufe_key_to_storage_key(prefix, o.key) # we trust that if we get the same key, it's the same object, so # we only store on keys that we don't already know if key not in self.result_server: data = json.dumps( o.to_keyed_dict(), cls=JSON_HANDLER.encoder, sort_keys=True ).encode("utf-8") self.result_server.store_bytes(key, data) def store_transformation(self, transformation): """Store a :class:`.Transformation`. Parameters --------- transformation: :class:`.Transformation` the transformation to store """ self._store_gufe_tokenizable("setup", transformation) def store_network(self, network): """Store a :class:`.AlchemicalNetwork`. Parameters --------- network: :class:`.AlchemicalNetwork` the network to store """ self._store_gufe_tokenizable("setup", network) def _load_gufe_tokenizable(self, prefix, gufe_key): """generic function to load deduplicated object from a key""" registry = {} def recursive_build_object_cache(gufe_key): """DFS to rebuild object hierarchy""" # This implementation is a bit fragile, because ensuring that we # don't duplicate objects in memory depends on the fact that # `key_decode_dependencies` gets keyencoded objects from a cache # (they are cached on creation). storage_key = self._gufe_key_to_storage_key(prefix, gufe_key) with self.load_stream(storage_key) as f: keyencoded_json = f.read().decode("utf-8") dct = json.loads(keyencoded_json, cls=JSON_HANDLER.decoder) # this implementation may seem strange, but it will be a # faster than traversing the dict key_encoded = set(GUFEKEY_JSON_REGEX.findall(keyencoded_json)) # this approach takes the dct instead of the json str # found = [] # modify_dependencies(dct, found.append, is_gufe_key_dict) # key_encoded = {d[":gufe-key:"] for d in found} for key in key_encoded: # we're actually only doing this for the side effect of # generating the objects and adding them to the registry recursive_build_object_cache(key) if len(key_encoded) == 0: # fast path for objects that don't contain other gufe # objects (these tend to be larger dicts; avoid walking # them) obj = from_dict(dct) else: # objects that contain other gufe objects need be walked to # replace everything obj = key_decode_dependencies(dct, registry) registry[obj.key] = obj return obj return recursive_build_object_cache(gufe_key) def load_transformation(self, key: str): """Load a :class:`.Transformation` from its GufeKey Parameters ---------- key: str the gufe key for this object Returns ------- :class:`.Transformation` the desired transformation """ return self._load_gufe_tokenizable("setup", key) def load_network(self, key: str): """Load a :class:`.AlchemicalNetwork` from its GufeKey Parameters ---------- key: str the gufe key for this object Returns ------- :class:`.AlchemicalNetwork` the desired network """ return self._load_gufe_tokenizable("setup", key) def _load_next_level(self, transformation): return TransformationResult(self, transformation) # override these two inherited properties since this is always the end of # the recursive chain @property def path(self): return "transformations" @property def result_server(self): return self._result_server class TransformationResult(_ResultContainer): def __init__(self, parent, transformation): super().__init__(parent, transformation) self.transformation = transformation def _load_next_level(self, clone): return CloneResult(self, clone) class CloneResult(_ResultContainer): def __init__(self, parent, clone): super().__init__(parent, clone) self.clone = clone @staticmethod def _to_path_component(item): return str(item) def _load_next_level(self, extension): return ExtensionResult(self, extension) class ExtensionResult(_ResultContainer): def __init__(self, parent, extension): super().__init__(parent, str(extension)) self.extension = extension @staticmethod def _to_path_component(item): return str(item) def __getitem__(self, filename): # different here -- we don't cache the actual file objects return self._load_next_level(filename) def _load_next_level(self, filename): return self.result_server.load_stream(self.path + "/" + filename) ================================================ FILE: src/openfe/storage/resultserver.py ================================================ # This code is part of OpenFE and is licensed under the MIT license. # For details, see https://github.com/OpenFreeEnergy/gufe import warnings from typing import ClassVar from gufe.storage.errors import ChangedExternalResourceError, MissingExternalResourceError class ResultServer: """Class to manage communication between metadata and data storage. At this level, we provide an abstraction where client code no longer needs to be aware of the nature of the metadata, or even that it exists. """ def __init__(self, external_store, metadata_store): self.external_store = external_store self.metadata_store = metadata_store def _store_metadata(self, location): metadata = self.external_store.get_metadata(location) self.metadata_store.store_metadata(location, metadata) def store_bytes(self, location, byte_data): self.external_store.store_bytes(location, byte_data) self._store_metadata(location) def store_path(self, location, path): self.external_store.store_path(location, path) self._store_metadata(location) def delete(self, location): del self.metadata_store[location] self.external_store.delete(location) def validate(self, location, allow_changed=False): try: metadata = self.metadata_store[location] except KeyError: raise MissingExternalResourceError(f"Metadata for '{location}' not found") if not self.external_store.get_metadata(location) == metadata: msg = f"Metadata mismatch for {location}: this object may have changed." if not allow_changed: raise ChangedExternalResourceError( msg + " To allow this, set ExternalStorage.allow_changed = True" ) else: warnings.warn(msg) def __iter__(self): return iter(self.metadata_store) def find_missing_files(self): """Identify files listed in metadata but unavailable in storage""" return [f for f in self if not self.external_store.exists(f)] def load_stream(self, location, allow_changed=False): self.validate(location, allow_changed) return self.external_store.load_stream(location) ================================================ FILE: src/openfe/tests/__init__.py ================================================ ================================================ FILE: src/openfe/tests/analysis/__init__.py ================================================ ================================================ FILE: src/openfe/tests/analysis/test_plotting.py ================================================ import matplotlib import matplotlib.pyplot as plt import numpy as np import pytest from openfe.analysis.plotting import ( plot_2D_rmsd, plot_lambda_transition_matrix, ) MBAR_HIGH_FLOAT_PREC = np.array([ [4.04963280e-01, 2.64851626e-01, 1.55960834e-01, 8.70071466e-02, 4.65819362e-02, 2.21166590e-02, 5.28613476e-19, 1.21332039e-39, 9.53847574e-47, 1.08409130e-49, 1.00129930e-50], [2.64851626e-01, 2.38999336e-01, 1.90795611e-01, 1.39227718e-01, 9.35391162e-02, 5.40680743e-02, 4.14462223e-18, 9.51310340e-39, 7.47869291e-46, 8.49987577e-49, 7.85074074e-50], [1.55960834e-01, 1.90795611e-01, 1.99215052e-01, 1.82450137e-01, 1.49240018e-01, 1.03819831e-01, 2.12518612e-17, 4.87791510e-38, 3.83475587e-45, 4.35837503e-48, 4.02552618e-49], [8.70071466e-02, 1.39227718e-01, 1.82450137e-01, 2.03476122e-01, 2.00318604e-01, 1.69001754e-01, 7.63228831e-17, 1.75183030e-37, 1.37719525e-44, 1.56524525e-47, 1.44570756e-48], [4.65819362e-02, 9.35391162e-02, 1.49240018e-01, 2.00318604e-01, 2.39174175e-01, 2.52627633e-01, 2.01399730e-16, 4.62270467e-37, 3.63412308e-44, 4.13034672e-47, 3.81491237e-48], [2.21166590e-02, 5.40680743e-02, 1.03819831e-01, 1.69001754e-01, 2.52627633e-01, 3.79847531e-01, 3.76232213e-16, 8.63561442e-37, 6.78885803e-44, 7.71584694e-47, 7.12658815e-48], [5.28613476e-19, 4.14462223e-18, 2.12518612e-17, 7.63228831e-17, 2.01399730e-16, 3.76232213e-16, 1.01326575e+00, 8.95334208e-03, 5.08819552e-07, 9.41453345e-09, 2.77171908e-09], [1.21332039e-39, 9.51310340e-39, 4.87791510e-38, 1.75183030e-37, 4.62270467e-37, 8.63561442e-37, 8.95334208e-03, 8.92862646e-01, 1.07782005e-01, 9.27776485e-03, 3.34696054e-03], [9.53847574e-47, 7.47869291e-46, 3.83475587e-45, 1.37719525e-44, 3.63412308e-44, 6.78885803e-44, 5.08819552e-07, 1.07782005e-01, 5.54361284e-01, 2.25806184e-01, 1.34272920e-01], [1.08409130e-49, 8.49987577e-49, 4.35837503e-48, 1.56524525e-47, 4.13034672e-47, 7.71584694e-47, 9.41453345e-09, 9.27776485e-03, 2.25806184e-01, 3.94054662e-01, 3.93084315e-01], [1.00129930e-50, 7.85074074e-50, 4.02552618e-49, 1.44570756e-48, 3.81491237e-48, 7.12658815e-48, 2.77171908e-09, 3.34696054e-03, 1.34272920e-01, 3.93084315e-01, 4.91518742e-01], ]) # fmt: skip MBAR_HIGH_FLOAT_ABNORMAL = np.array([ [2.34151792e-001, 1.39888121e-001, 7.84874621e-002, 4.18336072e-002, 2.05969028e-002, 7.26433700e-003, 8.59588359e-069, 9.82810344e-154, 2.86854631e-174, 3.61851838e-179, 2.03347234e-180], [1.39888121e-001, 1.33087532e-001, 1.06283463e-001, 7.48596022e-002, 4.71944621e-002, 2.09090412e-002, 2.61632960e-069, 9.87687147e-154, 3.04564890e-174, 1.01323581e-178, 5.71180108e-180], [7.84874621e-002, 1.06283463e-001, 1.12085643e-001, 1.01164236e-001, 8.02528014e-002, 4.39486161e-002, 4.65970677e-070, 5.76131562e-154, 2.05138486e-174, 1.68711540e-178, 9.52136287e-180], [4.18336072e-002, 7.48596022e-002, 1.01164236e-001, 1.15030824e-001, 1.12925630e-001, 7.64083221e-002, 5.56609447e-071, 2.25203208e-154, 1.10970982e-174, 1.88729763e-178, 1.06553350e-179], [2.05969028e-002, 4.71944621e-002, 8.02528014e-002, 1.12925630e-001, 1.37008472e-001, 1.24243953e-001, 4.63825760e-072, 6.26556483e-155, 5.47382223e-175, 1.47688013e-178, 8.33933879e-180], [7.26433700e-003, 2.09090412e-002, 4.39486161e-002, 7.64083221e-002, 1.24243953e-001, 2.49447953e-001, 2.15384511e-073, 9.78751994e-156, 1.89651311e-175, 6.46075564e-179, 3.64830252e-180], [8.59588359e-069, 2.61632960e-069, 4.65970677e-070, 5.56609447e-071, 4.63825760e-072, 2.15384511e-073, 1.54873255e+000, 2.33585672e-002, 2.78272533e-006, 4.61271012e-008, 9.81085527e-009], [9.82810344e-154, 9.87687147e-154, 5.76131562e-154, 2.25203208e-154, 6.26556483e-155, 9.78751994e-156, 2.33585672e-002, 1.36721112e+000, 1.64391352e-001, 1.39600025e-002, 4.59238353e-003], [2.86854631e-174, 3.04564890e-174, 2.05138486e-174, 1.10970982e-174, 5.47382223e-175, 1.89651311e-175, 2.78272533e-006, 1.64391352e-001, 8.87029135e-001, 3.45990080e-001, 1.76251997e-001], [3.61851838e-179, 1.01323581e-178, 1.68711540e-178, 1.88729763e-178, 1.47688013e-178, 6.46075564e-179, 4.61271012e-008, 1.39600025e-002, 3.45990080e-001, 6.27268856e-001, 5.86475486e-001], [2.03347234e-180, 5.71180108e-180, 9.52136287e-180, 1.06553350e-179, 8.33933879e-180, 3.64830252e-180, 9.81085527e-009, 4.59238353e-003, 1.76251997e-001, 5.86475486e-001, 8.06379597e-001], ]) # fmt: skip @pytest.mark.parametrize( "matrix", [MBAR_HIGH_FLOAT_PREC, MBAR_HIGH_FLOAT_ABNORMAL], ) def test_mbar_overlap_plot_high_warn(matrix): wmsg = "Overlap/probability matrix exceeds" with pytest.warns(match=wmsg): ax = plot_lambda_transition_matrix(matrix) assert isinstance(ax, matplotlib.axes.Axes) MBAR_OVERLAP_NORMAL = np.array([ [5.40693861e-01, 3.01639682e-01, 1.21556611e-01, 3.23719204e-02, 3.58389041e-03, 1.48665588e-04, 5.24585724e-06, 1.21058499e-07, 1.77358642e-09, 1.47315799e-11, 5.95535941e-14], [3.01639682e-01, 3.31228861e-01, 2.43846627e-01, 1.08013742e-01, 1.43267020e-02, 8.83652857e-04, 5.81705578e-05, 2.49870089e-06, 6.30913374e-08, 8.22822509e-10, 5.45494512e-12], [1.21556611e-01, 2.43846627e-01, 3.25955156e-01, 2.56738695e-01, 4.67483791e-02, 4.53599666e-03, 5.71365908e-04, 4.52123401e-05, 1.91542154e-06, 4.11083861e-08, 4.89327222e-10], [3.23719204e-02, 1.08013742e-01, 2.56738695e-01, 4.09261028e-01, 1.58278950e-01, 2.79859170e-02, 6.41857330e-03, 8.67983163e-04, 6.08822529e-05, 2.26213546e-06, 4.64070520e-08], [3.58389041e-03, 1.43267020e-02, 4.67483791e-02, 1.58278950e-01, 4.25994251e-01, 2.44226615e-01, 8.69755675e-02, 1.78548481e-02, 1.90728937e-03, 1.00948754e-04, 2.55919445e-06], [1.48665588e-04, 8.83652857e-04, 4.53599666e-03, 2.79859170e-02, 2.44226615e-01, 3.71598157e-01, 2.43792854e-01, 8.89756349e-02, 1.63090400e-02, 1.47914160e-03, 6.43253565e-05], [5.24585724e-06, 5.81705578e-05, 5.71365908e-04, 6.41857330e-03, 8.69755675e-02, 2.43792854e-01, 3.28134403e-01, 2.34652614e-01, 8.31489505e-02, 1.49645600e-02, 1.27769523e-03], [1.21058499e-07, 2.49870089e-06, 4.52123401e-05, 8.67983163e-04, 1.78548481e-02, 8.89756349e-02, 2.34652614e-01, 3.26504455e-01, 2.32499832e-01, 8.43901256e-02, 1.42066757e-02], [1.77358642e-09, 6.30913374e-08, 1.91542154e-06, 6.08822529e-05, 1.90728937e-03, 1.63090400e-02, 8.31489505e-02, 2.32499832e-01, 3.36922669e-01, 2.44443192e-01, 8.47061646e-02], [1.47315799e-11, 8.22822509e-10, 4.11083861e-08, 2.26213546e-06, 1.00948754e-04, 1.47914160e-03, 1.49645600e-02, 8.43901256e-02, 2.44443192e-01, 3.65791191e-01, 2.88828537e-01], [5.95535941e-14, 5.45494512e-12, 4.89327222e-10, 4.64070520e-08, 2.55919445e-06, 6.43253565e-05, 1.27769523e-03, 1.42066757e-02, 8.47061646e-02, 2.88828537e-01, 6.10913996e-01] ]) # fmt: skip def test_mbar_overlap_plot(): ax = plot_lambda_transition_matrix(MBAR_OVERLAP_NORMAL) assert isinstance(ax, matplotlib.axes.Axes) @pytest.mark.parametrize("num", [i for i in range(1, 30)]) def test_plot_2D_rmsd(num): """ Smoke test: Loop through and test plotting fictitious 2D data """ points = num * (num - 1) // 2 data = [[0.5 for x in range(points)] for i in range(num)] fig = plot_2D_rmsd(data) plt.close(fig) ================================================ FILE: src/openfe/tests/conftest.py ================================================ # This code is part of OpenFE and is licensed under the MIT license. # For details, see https://github.com/OpenFreeEnergy/openfe import gzip import os import pathlib import urllib.error import urllib.request from importlib import resources import gufe import mdtraj import numpy as np import openmm import pandas as pd import pytest from gufe import AtomMapper, LigandAtomMapping, ProteinComponent, SmallMoleculeComponent from openff.toolkit import ForceField from openff.units import unit as offunit from openmm import unit as ommunit from rdkit import Chem from rdkit.Chem import AllChem import openfe from openfe.data._registry import POOCH_CACHE from openfe.protocols.openmm_rfe import RelativeHybridTopologyProtocol from openfe.protocols.openmm_rfe._rfe_utils.relative import HybridTopologyFactory from openfe.protocols.openmm_utils.serialization import deserialize from openfe.tests.protocols.openmm_rfe.helpers import make_htf class SlowTests: """Plugin for handling fixtures that skips slow tests Fixtures -------- Currently two fixture types are handled: * `integration`: Extremely slow tests that are meant to be run to truly put the code through a real run. * `slow`: Unit tests that just take too long to be running regularly. How to use the fixtures ----------------------- To add these fixtures simply add `@pytest.mark.integration` or `@pytest.mark.slow` decorator to the relevant function or class. How to run tests marked by these fixtures ----------------------------------------- To run the `integration` tests, either use the `--integration` flag when invoking pytest, or set the environment variable `OFE_INTEGRATION_TESTS` to `true`. Note: triggering `integration` will automatically also trigger tests marked as `slow`. To run the `slow` tests, either use the `--runslow` flag when invoking pytest, or set the environment variable `OFE_SLOW_TESTS` to `true` """ def __init__(self, config): self.config = config @staticmethod def _modify_slow(items, config): msg = ( "need --runslow pytest cli option or the environment variable " "`OFE_SLOW_TESTS` set to `True` to run" ) skip_slow = pytest.mark.skip(reason=msg) for item in items: if "slow" in item.keywords: item.add_marker(skip_slow) @staticmethod def _modify_integration(items, config): msg = ( "need --integration pytest cli option or the environment " "variable `OFE_INTEGRATION_TESTS` set to `True` to run" ) skip_int = pytest.mark.skip(reason=msg) for item in items: if "integration" in item.keywords: item.add_marker(skip_int) def pytest_collection_modifyitems(self, items, config): if ( config.getoption("--integration") or os.getenv("OFE_INTEGRATION_TESTS", default="false").lower() == "true" ): return elif ( config.getoption("--runslow") or os.getenv("OFE_SLOW_TESTS", default="false").lower() == "true" ): self._modify_integration(items, config) else: self._modify_integration(items, config) self._modify_slow(items, config) # allow for optional slow tests # See: https://docs.pytest.org/en/latest/example/simple.html def pytest_addoption(parser): parser.addoption("--runslow", action="store_true", default=False, help="run slow tests") parser.addoption("--integration", action="store_true", default=False, help="run long integration tests") # fmt: skip def pytest_configure(config): config.pluginmanager.register(SlowTests(config), "slow") config.addinivalue_line("markers", "slow: mark test as slow") config.addinivalue_line("markers", "integration: mark test as long integration test") def mol_from_smiles(smiles: str) -> Chem.Mol: m = Chem.MolFromSmiles(smiles) AllChem.Compute2DCoords(m) # type: ignore[attr-defined] return m @pytest.fixture(scope="session") def simple_mapping(): """Disappearing oxygen on end C C O C C """ molA = SmallMoleculeComponent(mol_from_smiles("CCO")) molB = SmallMoleculeComponent(mol_from_smiles("CC")) m = LigandAtomMapping(molA, molB, componentA_to_componentB={0: 0, 1: 1}) return m @pytest.fixture(scope="session") def other_mapping(): """Disappearing middle carbon C C O C C """ molA = SmallMoleculeComponent(mol_from_smiles("CCO")) molB = SmallMoleculeComponent(mol_from_smiles("CC")) m = LigandAtomMapping(molA, molB, componentA_to_componentB={0: 0, 2: 1}) return m @pytest.fixture() def lomap_basic_test_files_dir(tmp_path_factory): # for lomap, which wants the files in a directory lomap_files = tmp_path_factory.mktemp("lomap_files") lomap_basic = "openfe.tests.data.lomap_basic" for f in resources.contents(lomap_basic): if not f.endswith("mol2"): continue stuff = resources.read_binary(lomap_basic, f) with open(lomap_files / f, "wb") as fout: fout.write(stuff) yield str(lomap_files) @pytest.fixture(scope="session") def atom_mapping_basic_test_files(): # a dict of {filenames.strip(mol2): SmallMoleculeComponent} for a simple # set of ligands files = {} for f in [ "1,3,7-trimethylnaphthalene", "1-butyl-4-methylbenzene", "2,6-dimethylnaphthalene", "2-methyl-6-propylnaphthalene", "2-methylnaphthalene", "2-naftanol", "methylcyclohexane", "toluene", ]: with resources.as_file(resources.files("openfe.tests.data.lomap_basic")) as d: fn = str(d / (f + ".mol2")) mol = Chem.MolFromMol2File(fn, removeHs=False) files[f] = SmallMoleculeComponent(mol, name=f) return files @pytest.fixture() def lomap_old_mapper() -> AtomMapper: """ LomapAtomMapper with the old default settings. This is necessary as atom_mapping_basic_test_files are not all fully aligned and need both shift and a large max3d value. """ return openfe.setup.atom_mapping.LomapAtomMapper( time=20, threed=True, max3d=1000.0, element_change=True, seed="", shift=True, ) @pytest.fixture def benzene_toluene_topology(): """Load the mdtraj hybrid topology reference for benzene to toluene.""" with resources.as_file(resources.files("openfe.tests.data.openmm_rfe")) as d: atoms = pd.read_csv(d / "benzene_toluene_hybrid_top" / "hybrid_topology_atoms.csv") bonds = np.loadtxt(d / "benzene_toluene_hybrid_top" / "hybrid_topology_bonds.txt") return mdtraj.Topology.from_dataframe(atoms=atoms, bonds=bonds) @pytest.fixture(scope="session") def benzene_modifications(): files = {} with resources.as_file(resources.files("openfe.tests.data")) as d: fn = str(d / "benzene_modifications.sdf") supp = Chem.SDMolSupplier(str(fn), removeHs=False) for rdmol in supp: files[rdmol.GetProp("_Name")] = SmallMoleculeComponent(rdmol) return files @pytest.fixture(scope="session") def charged_benzene_modifications(): files = {} with resources.as_file(resources.files("openfe.tests.data.openmm_rfe")) as d: fn = str(d / "charged_benzenes.sdf") supp = Chem.SDMolSupplier(str(fn), removeHs=False) for rdmol in supp: files[rdmol.GetProp("_Name")] = SmallMoleculeComponent(rdmol) return files @pytest.fixture(scope="session") def T4L_septop_reference_xml(): with resources.as_file(resources.files("openfe.tests.data.openmm_septop")) as d: f = str(d / "system.xml.bz2") return deserialize(pathlib.Path(f)) @pytest.fixture def serialization_template(): def inner(filename): loc = "openfe.tests.data.serialization" tmpl = resources.read_text(loc, filename) return tmpl.replace("{OFE_VERSION}", openfe.__version__) return inner @pytest.fixture(scope="session") def benzene_transforms(): # a dict of Molecules for benzene transformations mols = {} with resources.as_file(resources.files("openfe.tests.data")) as d: fn = str(d / "benzene_modifications.sdf") supplier = Chem.SDMolSupplier(fn, removeHs=False) for mol in supplier: mols[mol.GetProp("_Name")] = SmallMoleculeComponent(mol) return mols @pytest.fixture(scope="session") def T4_protein_component_pdb() -> str: with resources.as_file(resources.files("openfe.tests.data")) as d: return str(d / "181l_only.pdb") @pytest.fixture(scope="session") def T4_protein_component(T4_protein_component_pdb) -> gufe.ProteinComponent: return gufe.ProteinComponent.from_pdb_file(T4_protein_component_pdb, name="T4_protein") @pytest.fixture(scope="session") def a2a_protein_membrane_pdb(): with resources.as_file(resources.files("openfe.tests.data.a2a")) as d: yield str(d / "protein.pdb.gz") @pytest.fixture(scope="session") def a2a_protein_membrane_component(a2a_protein_membrane_pdb) -> openfe.ProteinMembraneComponent: yield openfe.ProteinMembraneComponent.from_pdb_file(a2a_protein_membrane_pdb, name="a2a") @pytest.fixture(scope="session") def eg5_protein_pdb(): with resources.as_file(resources.files("openfe.tests.data.eg5")) as d: yield str(d / "eg5_protein.pdb") @pytest.fixture() def eg5_ligands_sdf(): with resources.as_file(resources.files("openfe.tests.data.eg5")) as d: yield str(d / "eg5_ligands.sdf") @pytest.fixture() def eg5_cofactor_sdf(): with resources.as_file(resources.files("openfe.tests.data.eg5")) as d: yield str(d / "eg5_cofactor.sdf") @pytest.fixture() def eg5_protein(eg5_protein_pdb) -> openfe.ProteinComponent: return openfe.ProteinComponent.from_pdb_file(eg5_protein_pdb) @pytest.fixture() def eg5_ligands(eg5_ligands_sdf) -> list[SmallMoleculeComponent]: return [SmallMoleculeComponent(m) for m in Chem.SDMolSupplier(eg5_ligands_sdf, removeHs=False)] @pytest.fixture() def eg5_cofactor(eg5_cofactor_sdf) -> SmallMoleculeComponent: return SmallMoleculeComponent.from_sdf_file(eg5_cofactor_sdf) @pytest.fixture(scope="session") def a2a_ligands_sdf(): with resources.as_file(resources.files("openfe.tests.data.a2a")) as d: yield str(d / "ligands.sdf.gz") @pytest.fixture(scope="session") def a2a_ligands(a2a_ligands_sdf): with gzip.open(a2a_ligands_sdf, "rb") as gzf: suppl = Chem.ForwardSDMolSupplier(gzf, removeHs=False) yield [SmallMoleculeComponent(m) for m in suppl] @pytest.fixture() def orion_network(): with resources.as_file(resources.files("openfe.tests.data.external_formats")) as d: yield str(d / "somebenzenes_nes.dat") @pytest.fixture() def fepplus_network(): with resources.as_file(resources.files("openfe.tests.data.external_formats")) as d: yield str(d / "somebenzenes_edges.edge") @pytest.fixture() def CN_molecule() -> list[SmallMoleculeComponent]: """ A basic CH3NH2 molecule for quick testing. """ with resources.as_file(resources.files("openfe.tests.data")) as d: fn = str(d / "CN.sdf") supp = Chem.SDMolSupplier(str(fn), removeHs=False) smc = [SmallMoleculeComponent(i) for i in supp][0] return smc @pytest.fixture(scope="function") def am1bcc_ref_charges(): ref_chgs = { "ambertools":[ 0.146957, -0.918943, 0.025557, 0.025557, 0.025557, 0.347657, 0.347657 ] * offunit.elementary_charge, "openeye": [ 0.14713, -0.92016, 0.02595, 0.02595, 0.02595, 0.34759, 0.34759 ] * offunit.elementary_charge, "nagl": [ 0.170413, -0.930417, 0.021593, 0.021593, 0.021593, 0.347612, 0.347612 ] * offunit.elementary_charge, "espaloma": [ 0.017702, -0.966793, 0.063076, 0.063076, 0.063076, 0.379931, 0.379931 ] * offunit.elementary_charge, } # fmt: skip return ref_chgs try: urllib.request.urlopen("https://www.google.com") except urllib.error.URLError: # -no-cov- HAS_INTERNET = False else: HAS_INTERNET = True try: import espaloma HAS_ESPALOMA = True except ModuleNotFoundError: HAS_ESPALOMA = False @pytest.fixture(scope="module") def chlorobenzene(): """Load chlorobenzene with partial charges from sdf file.""" with resources.as_file(resources.files("openfe.tests.data.htf")) as f: yield SmallMoleculeComponent.from_sdf_file(f / "t4_lysozyme_data" / "chlorobenzene.sdf") @pytest.fixture(scope="module") def fluorobenzene(): """Load fluorobenzene with partial charges from sdf file.""" with resources.as_file(resources.files("openfe.tests.data.htf")) as f: yield SmallMoleculeComponent.from_sdf_file(f / "t4_lysozyme_data" / "fluorobenzene.sdf") @pytest.fixture(scope="module") def ethane(): """Load ethane with partial charges from sdf file.""" with resources.as_file(resources.files("openfe.tests.data.htf")) as f: yield SmallMoleculeComponent.from_sdf_file(f / "ethane.sdf") @pytest.fixture(scope="module") def chloroethane(): """Load chloroethane with partial charges from sdf file.""" with resources.as_file(resources.files("openfe.tests.data.htf")) as f: yield SmallMoleculeComponent.from_sdf_file(f / "chloroethane.sdf") @pytest.fixture(scope="module") def fluoroethane(): """Load fluoroethane with partial charges from sdf file.""" with resources.as_file(resources.files("openfe.tests.data.htf")) as f: yield SmallMoleculeComponent.from_sdf_file(f / "fluoroethane.sdf") @pytest.fixture(scope="module") def benzene(): """Load fluoroethane with partial charges from sdf file.""" with resources.as_file(resources.files("openfe.tests.data.htf")) as f: yield SmallMoleculeComponent.from_sdf_file(f / "t4_lysozyme_data" / "benzene.sdf") @pytest.fixture(scope="module") def chlorobenzene_to_fluorobenzene_mapping(chlorobenzene, fluorobenzene): """Return a mapping from chlorobenzene to fluorobenzene.""" return LigandAtomMapping( componentA=chlorobenzene, componentB=fluorobenzene, componentA_to_componentB={ # perfect one-to-one mapping 0: 0, 1: 1, 2: 2, 3: 3, 4: 4, 5: 5, 6: 6, 7: 7, 8: 8, 9: 9, 10: 10, 11: 11, }, ) @pytest.fixture(scope="module") def chloroethane_to_ethane_mapping(chloroethane, ethane): """Return a mapping from chloroethane to ethane.""" return LigandAtomMapping( componentA=chloroethane, componentB=ethane, componentA_to_componentB={ # Cl-H not mapped, all others one-to-one 1: 1, 2: 2, 3: 3, 4: 4, 5: 5, 6: 6, 7: 7, }, ) @pytest.fixture(scope="module") def chloroethane_to_fluoroethane_mapping(chloroethane, fluoroethane): """Return a mapping from chloroethane to fluoroethane.""" return LigandAtomMapping( componentA=chloroethane, componentB=fluoroethane, componentA_to_componentB={ # perfect one-to-one mapping 0: 0, 1: 1, 2: 2, 3: 3, 4: 4, 5: 5, 6: 6, 7: 7, }, ) @pytest.fixture(scope="module") def chlorobenzene_to_benzene_mapping(chlorobenzene, benzene): """Return a mapping from chlorobenzene to benzene.""" return LigandAtomMapping( componentA=chlorobenzene, componentB=benzene, componentA_to_componentB={ # Cl-H not mapped, all others one-to-one 1: 1, 2: 2, 3: 3, 4: 4, 5: 5, 6: 6, 7: 7, 8: 8, 9: 9, 10: 10, 11: 11, }, ) @pytest.fixture(scope="module") def t4_lysozyme_solvated(): """Load the T4 lysozyme L99A structure and solvent from the pdb file.""" with resources.as_file(resources.files("openfe.tests.data.htf")) as f: with gzip.open(f / "t4_lysozyme_data" / "t4_lysozyme_solvated.pdb.gz", "rb") as gzf: yield ProteinComponent.from_pdb_file(gzf) def apply_box_vectors_and_fix_nb_force( hybrid_topology_factory: HybridTopologyFactory, force_field: ForceField ): """ Edit the systems in the hybrid topology factory to have the correct box vectors and nonbonded force settings for the T4 lysozyme system. """ hybrid_system = hybrid_topology_factory.hybrid_system # as we use a pre-solvated system, we need to correct the nonbonded methods and cutoffs and set the box vectors box_vectors = [ openmm.vec3.Vec3(x=6.90789161545809, y=0.0, z=0.0) * ommunit.nanometer, openmm.vec3.Vec3(x=0.0, y=6.90789161545809, z=0.0) * ommunit.nanometer, openmm.vec3.Vec3(x=3.453945807729045, y=3.453945807729045, z=4.88461700499211) * ommunit.nanometer, ] hybrid_system.setDefaultPeriodicBoxVectors(*box_vectors) for force in hybrid_system.getForces(): if isinstance(force, openmm.NonbondedForce): force.setNonbondedMethod(openmm.NonbondedForce.PME) force.setCutoffDistance( force_field.get_parameter_handler("Electrostatics").cutoff.m_as(offunit.nanometer) * ommunit.nanometer ) force.setUseDispersionCorrection(False) force.setUseSwitchingFunction(False) elif isinstance(force, openmm.CustomNonbondedForce): force.setCutoffDistance( force_field.get_parameter_handler("Electrostatics").cutoff.m_as(offunit.nanometer) * ommunit.nanometer ) force.setNonbondedMethod(force.CutoffPeriodic) force.setUseLongRangeCorrection(False) force.setUseSwitchingFunction(False) # make sure both end state systems have the same cutoff method and distance for end_state in [hybrid_topology_factory._old_system, hybrid_topology_factory._new_system]: end_state.setDefaultPeriodicBoxVectors(*box_vectors) for force in end_state.getForces(): if isinstance(force, openmm.NonbondedForce): force.setNonbondedMethod(openmm.NonbondedForce.PME) force.setCutoffDistance( force_field.get_parameter_handler("Electrostatics").cutoff.m_as( offunit.nanometer ) * ommunit.nanometer ) force.setUseDispersionCorrection(False) force.setUseSwitchingFunction(False) @pytest.fixture(scope="module") def htf_cmap_chlorobenzene_to_fluorobenzene( chlorobenzene_to_fluorobenzene_mapping, t4_lysozyme_solvated ): """Generate the htf for chlorobenzene to fluorobenzene with a CMAP term.""" settings = RelativeHybridTopologyProtocol.default_settings() small_ff = settings.forcefield_settings.small_molecule_forcefield if ".offxml" not in small_ff: small_ff += ".offxml" ff = ForceField(small_ff) # update the default force fields to include a force field with CMAP terms settings.forcefield_settings.forcefields = [ "amber/protein.ff19SB.xml", # cmap amber ff "amber/tip3p_standard.xml", # TIP3P and recommended monovalent ion parameters "amber/tip3p_HFE_multivalent.xml", # for divalent ions "amber/phosaa19SB.xml", # Handles THE TPO ] htf = make_htf( mapping=chlorobenzene_to_fluorobenzene_mapping, protein=t4_lysozyme_solvated, settings=settings, ) # apply box vectors and fix nonbonded force settings so we can use PME apply_box_vectors_and_fix_nb_force(hybrid_topology_factory=htf, force_field=ff) hybrid_system = htf.hybrid_system forces = {force.getName(): force for force in hybrid_system.getForces()} return { "htf": htf, "hybrid_system": hybrid_system, "forces": forces, "mapping": chlorobenzene_to_fluorobenzene_mapping, "chlorobenzene": chlorobenzene_to_fluorobenzene_mapping.componentA, "fluorobenzene": chlorobenzene_to_fluorobenzene_mapping.componentB, "electrostatic_scale": ff.get_parameter_handler("Electrostatics").scale14, "vdW_scale": ff.get_parameter_handler("vdW").scale14, "force_field": ff, } @pytest.fixture(scope="module") def htf_chloro_fluoroethane(chloroethane, fluoroethane, chloroethane_to_fluoroethane_mapping): """Generate the htf for chloroethane to fluoroethane in vacuum.""" settings = RelativeHybridTopologyProtocol.default_settings() small_ff = settings.forcefield_settings.small_molecule_forcefield if ".offxml" not in small_ff: small_ff += ".offxml" ff = ForceField(small_ff) chloro_openff = chloroethane.to_openff() chloro_charges = chloro_openff.partial_charges.m_as(offunit.elementary_charge) chloro_labels = ff.label_molecules(chloro_openff.to_topology())[0] fluoro_openff = fluoroethane.to_openff() fluoro_charges = fluoro_openff.partial_charges.m_as(offunit.elementary_charge) fluoro_labels = ff.label_molecules(fluoro_openff.to_topology())[0] htf = make_htf(mapping=chloroethane_to_fluoroethane_mapping, settings=settings) hybrid_system = htf.hybrid_system forces = {force.getName(): force for force in hybrid_system.getForces()} return { "htf": htf, "hybrid_system": hybrid_system, "forces": forces, "chloro_labels": chloro_labels, "fluoro_labels": fluoro_labels, "mapping": chloroethane_to_fluoroethane_mapping, "chloroethane": chloroethane, "fluoroethane": fluoroethane, "chloro_charges": chloro_charges, "fluoro_charges": fluoro_charges, "electrostatic_scale": ff.get_parameter_handler("Electrostatics").scale14, "vdW_scale": ff.get_parameter_handler("vdW").scale14, "force_field": ff, } @pytest.fixture(scope="module") def htf_chloro_ethane(chloroethane, ethane, chloroethane_to_ethane_mapping): """Generate the htf for chloroethane to ethane in vacuum.""" settings = RelativeHybridTopologyProtocol.default_settings() small_ff = settings.forcefield_settings.small_molecule_forcefield if ".offxml" not in small_ff: small_ff += ".offxml" ff = ForceField(small_ff) chloro_openff = chloroethane.to_openff() chloro_charges = chloro_openff.partial_charges.m_as(offunit.elementary_charge) chloro_labels = ff.label_molecules(chloro_openff.to_topology())[0] ethane_openff = ethane.to_openff() ethane_charges = ethane_openff.partial_charges.m_as(offunit.elementary_charge) ethane_labels = ff.label_molecules(ethane_openff.to_topology())[0] htf = make_htf(mapping=chloroethane_to_ethane_mapping, settings=settings) hybrid_system = htf.hybrid_system forces = {force.getName(): force for force in hybrid_system.getForces()} return { "htf": htf, "hybrid_system": hybrid_system, "forces": forces, "chloro_labels": chloro_labels, "ethane_labels": ethane_labels, "mapping": chloroethane_to_ethane_mapping, "chloroethane": chloroethane, "ethane": ethane, "chloro_charges": chloro_charges, "ethane_charges": ethane_charges, "electrostatic_scale": ff.get_parameter_handler("Electrostatics").scale14, "vdW_scale": ff.get_parameter_handler("vdW").scale14, "force_field": ff, } @pytest.fixture(scope="module") def htf_chlorobenzene_fluorobenzene( chlorobenzene, fluorobenzene, chlorobenzene_to_fluorobenzene_mapping, t4_lysozyme_solvated ): """Generate the htf for chlorobenzene to fluorobenzene in complex with t4-lysozyme solvated.""" settings = RelativeHybridTopologyProtocol.default_settings() small_ff = settings.forcefield_settings.small_molecule_forcefield if ".offxml" not in small_ff: small_ff += ".offxml" ff = ForceField(small_ff) chloro_openff = chlorobenzene.to_openff() chloro_charges = chloro_openff.partial_charges.m_as(offunit.elementary_charge) chloro_labels = ff.label_molecules(chloro_openff.to_topology())[0] fluoro_openff = fluorobenzene.to_openff() fluoro_charges = fluoro_openff.partial_charges.m_as(offunit.elementary_charge) fluoro_labels = ff.label_molecules(fluoro_openff.to_topology())[0] htf = make_htf( mapping=chlorobenzene_to_fluorobenzene_mapping, settings=settings, protein=t4_lysozyme_solvated, ) hybrid_system = htf.hybrid_system apply_box_vectors_and_fix_nb_force(hybrid_topology_factory=htf, force_field=ff) forces = {force.getName(): force for force in hybrid_system.getForces()} return { "htf": htf, "hybrid_system": hybrid_system, "forces": forces, "chloro_labels": chloro_labels, "fluoro_labels": fluoro_labels, "mapping": chlorobenzene_to_fluorobenzene_mapping, "chlorobenzene": chlorobenzene, "fluorobenzene": fluorobenzene, "chloro_charges": chloro_charges, "fluoro_charges": fluoro_charges, "electrostatic_scale": ff.get_parameter_handler("Electrostatics").scale14, "vdW_scale": ff.get_parameter_handler("vdW").scale14, "force_field": ff, } @pytest.fixture(scope="module") def htf_chlorobenzene_benzene( chlorobenzene, benzene, chlorobenzene_to_benzene_mapping, t4_lysozyme_solvated ): """Generate the htf for chlorobenzene to benzene with interpolate 1-4s on in complex with t4-lysozyme solvated.""" settings = RelativeHybridTopologyProtocol.default_settings() small_ff = settings.forcefield_settings.small_molecule_forcefield if ".offxml" not in small_ff: small_ff += ".offxml" ff = ForceField(small_ff) chloro_openff = chlorobenzene.to_openff() chloro_charges = chloro_openff.partial_charges.m_as(offunit.elementary_charge) chloro_labels = ff.label_molecules(chloro_openff.to_topology())[0] benzene_openff = benzene.to_openff() benzene_charges = benzene_openff.partial_charges.m_as(offunit.elementary_charge) benzene_labels = ff.label_molecules(benzene_openff.to_topology())[0] htf = make_htf( mapping=chlorobenzene_to_benzene_mapping, settings=settings, protein=t4_lysozyme_solvated ) hybrid_system = htf.hybrid_system apply_box_vectors_and_fix_nb_force(hybrid_topology_factory=htf, force_field=ff) forces = {force.getName(): force for force in hybrid_system.getForces()} return { "htf": htf, "hybrid_system": hybrid_system, "forces": forces, "chloro_labels": chloro_labels, "benzene_labels": benzene_labels, "mapping": chlorobenzene_to_benzene_mapping, "chlorobenzene": chlorobenzene, "benzene": benzene, "chloro_charges": chloro_charges, "benzene_charges": benzene_charges, "electrostatic_scale": ff.get_parameter_handler("Electrostatics").scale14, "vdW_scale": ff.get_parameter_handler("vdW").scale14, "force_field": ff, } ================================================ FILE: src/openfe/tests/data/181l_only.pdb ================================================ ATOM 1 C ACE A 0 44.004 -3.922 10.269 1.00 0.00 C ATOM 2 O ACE A 0 43.553 -3.405 11.300 1.00 0.00 O ATOM 3 CH3 ACE A 0 44.579 -5.322 10.286 1.00 0.00 C ATOM 4 1HH3 ACE A 0 43.825 -6.028 10.604 1.00 0.00 H ATOM 5 2HH3 ACE A 0 44.917 -5.595 9.297 1.00 0.00 H ATOM 6 3HH3 ACE A 0 45.415 -5.370 10.968 1.00 0.00 H ATOM 7 N MET A 1 43.982 -3.258 9.163 1.00 0.00 N ATOM 8 CA MET A 1 43.434 -1.917 9.134 1.00 0.00 C ATOM 9 C MET A 1 42.006 -1.966 9.640 1.00 0.00 C ATOM 10 O MET A 1 41.334 -2.969 9.468 1.00 0.00 O ATOM 11 CB MET A 1 43.582 -1.397 7.675 1.00 0.00 C ATOM 12 CG MET A 1 42.903 -0.084 7.444 1.00 0.00 C ATOM 13 SD MET A 1 44.006 1.250 7.952 1.00 0.00 S ATOM 14 CE MET A 1 45.481 0.757 7.112 1.00 0.00 C ATOM 15 H MET A 1 44.347 -3.673 8.318 1.00 0.00 H ATOM 16 HA MET A 1 43.973 -1.334 9.742 1.00 0.00 H ATOM 17 HB2 MET A 1 43.185 -2.073 7.055 1.00 0.00 H ATOM 18 HB3 MET A 1 44.556 -1.291 7.473 1.00 0.00 H ATOM 19 HG2 MET A 1 42.060 -0.044 7.981 1.00 0.00 H ATOM 20 HG3 MET A 1 42.685 0.014 6.473 1.00 0.00 H ATOM 21 HE1 MET A 1 46.208 1.417 7.300 1.00 0.00 H ATOM 22 HE2 MET A 1 45.761 -0.148 7.433 1.00 0.00 H ATOM 23 HE3 MET A 1 45.308 0.723 6.128 1.00 0.00 H ATOM 24 N ASN A 2 41.577 -0.917 10.331 1.00 0.00 N ATOM 25 CA ASN A 2 40.227 -0.852 10.835 1.00 0.00 C ATOM 26 C ASN A 2 39.857 0.627 10.904 1.00 0.00 C ATOM 27 O ASN A 2 40.756 1.443 10.662 1.00 0.00 O ATOM 28 CB ASN A 2 40.133 -1.529 12.224 1.00 0.00 C ATOM 29 CG ASN A 2 41.084 -0.909 13.215 1.00 0.00 C ATOM 30 ND2 ASN A 2 42.001 -1.711 13.752 1.00 0.00 N ATOM 31 OD1 ASN A 2 41.041 0.309 13.479 1.00 0.00 O ATOM 32 H ASN A 2 42.202 -0.156 10.506 1.00 0.00 H ATOM 33 HA ASN A 2 39.613 -1.317 10.198 1.00 0.00 H ATOM 34 HB2 ASN A 2 40.354 -2.499 12.127 1.00 0.00 H ATOM 35 HB3 ASN A 2 39.199 -1.433 12.568 1.00 0.00 H ATOM 36 HD21 ASN A 2 42.011 -2.684 13.522 1.00 0.00 H ATOM 37 HD22 ASN A 2 42.680 -1.340 14.386 1.00 0.00 H ATOM 38 N ILE A 3 38.598 0.950 11.230 1.00 0.00 N ATOM 39 CA ILE A 3 38.095 2.316 11.285 1.00 0.00 C ATOM 40 C ILE A 3 38.983 3.288 12.114 1.00 0.00 C ATOM 41 O ILE A 3 39.269 4.440 11.729 1.00 0.00 O ATOM 42 CB ILE A 3 36.596 2.331 11.634 1.00 0.00 C ATOM 43 CG1 ILE A 3 36.015 3.749 11.576 1.00 0.00 C ATOM 44 CG2 ILE A 3 36.352 1.659 12.987 1.00 0.00 C ATOM 45 CD1 ILE A 3 36.262 4.484 10.218 1.00 0.00 C ATOM 46 H ILE A 3 37.965 0.208 11.449 1.00 0.00 H ATOM 47 HA ILE A 3 38.148 2.652 10.345 1.00 0.00 H ATOM 48 HB ILE A 3 36.123 1.787 10.941 1.00 0.00 H ATOM 49 HG12 ILE A 3 36.432 4.290 12.306 1.00 0.00 H ATOM 50 HG13 ILE A 3 35.028 3.691 11.727 1.00 0.00 H ATOM 51 HG21 ILE A 3 35.375 1.678 13.197 1.00 0.00 H ATOM 52 HG22 ILE A 3 36.667 0.711 12.950 1.00 0.00 H ATOM 53 HG23 ILE A 3 36.855 2.149 13.698 1.00 0.00 H ATOM 54 HD11 ILE A 3 35.857 5.398 10.255 1.00 0.00 H ATOM 55 HD12 ILE A 3 37.246 4.562 10.055 1.00 0.00 H ATOM 56 HD13 ILE A 3 35.841 3.963 9.475 1.00 0.00 H ATOM 57 N PHE A 4 39.471 2.813 13.251 1.00 0.00 N ATOM 58 CA PHE A 4 40.288 3.621 14.120 1.00 0.00 C ATOM 59 C PHE A 4 41.595 4.009 13.514 1.00 0.00 C ATOM 60 O PHE A 4 42.017 5.171 13.544 1.00 0.00 O ATOM 61 CB PHE A 4 40.534 2.948 15.448 1.00 0.00 C ATOM 62 CG PHE A 4 39.261 2.896 16.253 1.00 0.00 C ATOM 63 CD1 PHE A 4 38.915 3.949 17.091 1.00 0.00 C ATOM 64 CD2 PHE A 4 38.438 1.771 16.220 1.00 0.00 C ATOM 65 CE1 PHE A 4 37.756 3.891 17.868 1.00 0.00 C ATOM 66 CE2 PHE A 4 37.266 1.706 16.970 1.00 0.00 C ATOM 67 CZ PHE A 4 36.931 2.766 17.809 1.00 0.00 C ATOM 68 H PHE A 4 39.267 1.870 13.512 1.00 0.00 H ATOM 69 HA PHE A 4 39.783 4.465 14.303 1.00 0.00 H ATOM 70 HB2 PHE A 4 41.224 3.463 15.956 1.00 0.00 H ATOM 71 HB3 PHE A 4 40.862 2.017 15.290 1.00 0.00 H ATOM 72 HD1 PHE A 4 39.502 4.757 17.138 1.00 0.00 H ATOM 73 HD2 PHE A 4 38.695 0.994 15.645 1.00 0.00 H ATOM 74 HE1 PHE A 4 37.517 4.655 18.467 1.00 0.00 H ATOM 75 HE2 PHE A 4 36.670 0.905 16.907 1.00 0.00 H ATOM 76 HZ PHE A 4 36.102 2.722 18.367 1.00 0.00 H ATOM 77 N GLU A 5 42.284 3.029 12.984 1.00 0.00 N ATOM 78 CA GLU A 5 43.538 3.324 12.350 1.00 0.00 C ATOM 79 C GLU A 5 43.301 4.168 11.123 1.00 0.00 C ATOM 80 O GLU A 5 44.143 4.951 10.782 1.00 0.00 O ATOM 81 CB GLU A 5 44.301 2.059 11.905 1.00 0.00 C ATOM 82 CG GLU A 5 44.570 1.071 13.057 1.00 0.00 C ATOM 83 CD GLU A 5 45.307 -0.199 12.662 1.00 0.00 C ATOM 84 OE1 GLU A 5 45.539 -0.541 11.509 1.00 0.00 O ATOM 85 OE2 GLU A 5 45.835 -0.819 13.703 1.00 0.00 O1- ATOM 86 H GLU A 5 41.942 2.090 13.020 1.00 0.00 H ATOM 87 HA GLU A 5 44.110 3.838 12.989 1.00 0.00 H ATOM 88 HB2 GLU A 5 45.179 2.338 11.515 1.00 0.00 H ATOM 89 HB3 GLU A 5 43.760 1.592 11.206 1.00 0.00 H ATOM 90 HG2 GLU A 5 43.689 0.808 13.451 1.00 0.00 H ATOM 91 HG3 GLU A 5 45.116 1.543 13.748 1.00 0.00 H ATOM 92 N MET A 6 42.196 3.948 10.448 1.00 0.00 N ATOM 93 CA MET A 6 41.906 4.713 9.248 1.00 0.00 C ATOM 94 C MET A 6 41.733 6.191 9.577 1.00 0.00 C ATOM 95 O MET A 6 42.305 7.096 8.943 1.00 0.00 O ATOM 96 CB MET A 6 40.583 4.198 8.656 1.00 0.00 C ATOM 97 CG MET A 6 40.268 4.791 7.289 1.00 0.00 C ATOM 98 SD MET A 6 38.516 4.549 6.882 1.00 0.00 S ATOM 99 CE MET A 6 38.491 4.603 5.061 1.00 0.00 C ATOM 100 H MET A 6 41.552 3.251 10.762 1.00 0.00 H ATOM 101 HA MET A 6 42.644 4.596 8.584 1.00 0.00 H ATOM 102 HB2 MET A 6 39.841 4.433 9.283 1.00 0.00 H ATOM 103 HB3 MET A 6 40.641 3.204 8.566 1.00 0.00 H ATOM 104 HG2 MET A 6 40.832 4.341 6.597 1.00 0.00 H ATOM 105 HG3 MET A 6 40.471 5.770 7.300 1.00 0.00 H ATOM 106 HE1 MET A 6 37.554 4.477 4.737 1.00 0.00 H ATOM 107 HE2 MET A 6 38.835 5.488 4.749 1.00 0.00 H ATOM 108 HE3 MET A 6 39.070 3.873 4.698 1.00 0.00 H ATOM 109 N LEU A 7 40.898 6.458 10.569 1.00 0.00 N ATOM 110 CA LEU A 7 40.633 7.840 10.929 1.00 0.00 C ATOM 111 C LEU A 7 41.868 8.518 11.566 1.00 0.00 C ATOM 112 O LEU A 7 42.104 9.741 11.449 1.00 0.00 O ATOM 113 CB LEU A 7 39.392 7.942 11.817 1.00 0.00 C ATOM 114 CG LEU A 7 38.095 7.927 11.038 1.00 0.00 C ATOM 115 CD1 LEU A 7 36.964 7.641 12.005 1.00 0.00 C ATOM 116 CD2 LEU A 7 37.911 9.284 10.346 1.00 0.00 C ATOM 117 H LEU A 7 40.453 5.714 11.067 1.00 0.00 H ATOM 118 HA LEU A 7 40.431 8.332 10.082 1.00 0.00 H ATOM 119 HB2 LEU A 7 39.441 8.796 12.334 1.00 0.00 H ATOM 120 HB3 LEU A 7 39.391 7.168 12.450 1.00 0.00 H ATOM 121 HG LEU A 7 38.131 7.205 10.347 1.00 0.00 H ATOM 122 HD11 LEU A 7 36.096 7.627 11.508 1.00 0.00 H ATOM 123 HD12 LEU A 7 37.114 6.753 12.440 1.00 0.00 H ATOM 124 HD13 LEU A 7 36.936 8.354 12.705 1.00 0.00 H ATOM 125 HD21 LEU A 7 37.055 9.281 9.829 1.00 0.00 H ATOM 126 HD22 LEU A 7 37.882 10.008 11.035 1.00 0.00 H ATOM 127 HD23 LEU A 7 38.676 9.447 9.723 1.00 0.00 H ATOM 128 N ARG A 8 42.674 7.714 12.256 1.00 0.00 N ATOM 129 CA ARG A 8 43.879 8.232 12.881 1.00 0.00 C ATOM 130 C ARG A 8 44.822 8.756 11.814 1.00 0.00 C ATOM 131 O ARG A 8 45.490 9.750 12.027 1.00 0.00 O ATOM 132 CB ARG A 8 44.530 7.358 13.934 1.00 0.00 C ATOM 133 CG ARG A 8 45.959 7.753 14.297 1.00 0.00 C ATOM 134 CD ARG A 8 46.112 8.681 15.527 1.00 0.00 C ATOM 135 NE ARG A 8 47.474 9.235 15.686 1.00 0.00 N ATOM 136 CZ ARG A 8 48.157 9.911 14.739 1.00 0.00 C ATOM 137 NH1 ARG A 8 47.674 10.152 13.525 1.00 0.00 N1+ ATOM 138 NH2 ARG A 8 49.384 10.348 15.035 1.00 0.00 N ATOM 139 H ARG A 8 42.448 6.744 12.345 1.00 0.00 H ATOM 140 HA ARG A 8 43.578 9.047 13.377 1.00 0.00 H ATOM 141 HB2 ARG A 8 44.544 6.418 13.593 1.00 0.00 H ATOM 142 HB3 ARG A 8 43.974 7.404 14.764 1.00 0.00 H ATOM 143 HG2 ARG A 8 46.357 8.221 13.508 1.00 0.00 H ATOM 144 HG3 ARG A 8 46.472 6.914 14.480 1.00 0.00 H ATOM 145 HD2 ARG A 8 45.886 8.157 16.348 1.00 0.00 H ATOM 146 HD3 ARG A 8 45.471 9.442 15.430 1.00 0.00 H ATOM 147 HE ARG A 8 47.926 9.097 16.568 1.00 0.00 H ATOM 148 HH11 ARG A 8 48.223 10.659 12.860 1.00 0.00 H ATOM 149 HH12 ARG A 8 46.762 9.827 13.276 1.00 0.00 H ATOM 150 HH21 ARG A 8 49.913 10.852 14.353 1.00 0.00 H ATOM 151 HH22 ARG A 8 49.773 10.171 15.939 1.00 0.00 H ATOM 152 N ILE A 9 44.811 8.131 10.651 1.00 0.00 N ATOM 153 CA ILE A 9 45.596 8.555 9.524 1.00 0.00 C ATOM 154 C ILE A 9 44.969 9.770 8.851 1.00 0.00 C ATOM 155 O ILE A 9 45.647 10.700 8.457 1.00 0.00 O ATOM 156 CB ILE A 9 45.769 7.426 8.495 1.00 0.00 C ATOM 157 CG1 ILE A 9 46.849 6.457 8.921 1.00 0.00 C ATOM 158 CG2 ILE A 9 46.155 7.969 7.105 1.00 0.00 C ATOM 159 CD1 ILE A 9 46.552 5.045 8.403 1.00 0.00 C ATOM 160 H ILE A 9 44.229 7.324 10.549 1.00 0.00 H ATOM 161 HA ILE A 9 46.503 8.816 9.856 1.00 0.00 H ATOM 162 HB ILE A 9 44.905 6.929 8.416 1.00 0.00 H ATOM 163 HG12 ILE A 9 46.895 6.436 9.920 1.00 0.00 H ATOM 164 HG13 ILE A 9 47.727 6.763 8.553 1.00 0.00 H ATOM 165 HG21 ILE A 9 46.258 7.207 6.466 1.00 0.00 H ATOM 166 HG22 ILE A 9 45.438 8.585 6.777 1.00 0.00 H ATOM 167 HG23 ILE A 9 47.019 8.468 7.170 1.00 0.00 H ATOM 168 HD11 ILE A 9 47.278 4.423 8.696 1.00 0.00 H ATOM 169 HD12 ILE A 9 45.676 4.732 8.771 1.00 0.00 H ATOM 170 HD13 ILE A 9 46.508 5.059 7.404 1.00 0.00 H ATOM 171 N ASP A 10 43.683 9.808 8.711 1.00 0.00 N ATOM 172 CA ASP A 10 43.099 10.964 8.067 1.00 0.00 C ATOM 173 C ASP A 10 43.051 12.245 8.910 1.00 0.00 C ATOM 174 O ASP A 10 43.086 13.347 8.392 1.00 0.00 O ATOM 175 CB ASP A 10 41.680 10.604 7.626 1.00 0.00 C ATOM 176 CG ASP A 10 41.719 9.818 6.391 1.00 0.00 C ATOM 177 OD1 ASP A 10 42.628 9.900 5.589 1.00 0.00 O ATOM 178 OD2 ASP A 10 40.724 9.014 6.273 1.00 0.00 O1- ATOM 179 H ASP A 10 43.108 9.058 9.039 1.00 0.00 H ATOM 180 HA ASP A 10 43.634 11.159 7.245 1.00 0.00 H ATOM 181 HB2 ASP A 10 41.160 11.443 7.467 1.00 0.00 H ATOM 182 HB3 ASP A 10 41.237 10.068 8.345 1.00 0.00 H ATOM 183 N GLU A 11 42.927 12.117 10.224 1.00 0.00 N ATOM 184 CA GLU A 11 42.763 13.267 11.074 1.00 0.00 C ATOM 185 C GLU A 11 44.017 13.713 11.821 1.00 0.00 C ATOM 186 O GLU A 11 44.090 14.848 12.255 1.00 0.00 O ATOM 187 CB GLU A 11 41.669 12.995 12.129 1.00 0.00 C ATOM 188 CG GLU A 11 40.343 12.685 11.476 1.00 0.00 C ATOM 189 CD GLU A 11 39.674 13.930 10.943 1.00 0.00 C ATOM 190 OE1 GLU A 11 40.305 15.027 11.265 1.00 0.00 O ATOM 191 OE2 GLU A 11 38.674 13.918 10.294 1.00 0.00 O1- ATOM 192 H GLU A 11 42.948 11.204 10.632 1.00 0.00 H ATOM 193 HA GLU A 11 42.457 14.030 10.504 1.00 0.00 H ATOM 194 HB2 GLU A 11 41.566 13.804 12.708 1.00 0.00 H ATOM 195 HB3 GLU A 11 41.945 12.216 12.692 1.00 0.00 H ATOM 196 HG2 GLU A 11 39.742 12.259 12.152 1.00 0.00 H ATOM 197 HG3 GLU A 11 40.496 12.050 10.718 1.00 0.00 H ATOM 198 N GLY A 12 44.990 12.816 12.013 1.00 0.00 N ATOM 199 CA GLY A 12 46.160 13.121 12.812 1.00 0.00 C ATOM 200 C GLY A 12 45.801 13.144 14.307 1.00 0.00 C ATOM 201 O GLY A 12 44.708 12.830 14.714 1.00 0.00 O ATOM 202 H GLY A 12 44.908 11.911 11.594 1.00 0.00 H ATOM 203 HA2 GLY A 12 46.516 14.017 12.545 1.00 0.00 H ATOM 204 HA3 GLY A 12 46.859 12.423 12.652 1.00 0.00 H ATOM 205 N LEU A 13 46.748 13.506 15.150 1.00 0.00 N ATOM 206 CA LEU A 13 46.517 13.633 16.582 1.00 0.00 C ATOM 207 C LEU A 13 47.177 14.923 17.047 1.00 0.00 C ATOM 208 O LEU A 13 48.351 15.138 16.799 1.00 0.00 O ATOM 209 CB LEU A 13 47.090 12.436 17.363 1.00 0.00 C ATOM 210 CG LEU A 13 47.425 12.766 18.822 1.00 0.00 C ATOM 211 CD1 LEU A 13 46.161 12.825 19.675 1.00 0.00 C ATOM 212 CD2 LEU A 13 48.364 11.714 19.390 1.00 0.00 C ATOM 213 H LEU A 13 47.661 13.701 14.792 1.00 0.00 H ATOM 214 HA LEU A 13 45.533 13.691 16.750 1.00 0.00 H ATOM 215 HB2 LEU A 13 47.926 12.131 16.907 1.00 0.00 H ATOM 216 HB3 LEU A 13 46.415 11.698 17.352 1.00 0.00 H ATOM 217 HG LEU A 13 47.879 13.656 18.856 1.00 0.00 H ATOM 218 HD11 LEU A 13 46.406 13.041 20.620 1.00 0.00 H ATOM 219 HD12 LEU A 13 45.551 13.533 19.319 1.00 0.00 H ATOM 220 HD13 LEU A 13 45.697 11.940 19.645 1.00 0.00 H ATOM 221 HD21 LEU A 13 48.577 11.936 20.341 1.00 0.00 H ATOM 222 HD22 LEU A 13 47.924 10.817 19.348 1.00 0.00 H ATOM 223 HD23 LEU A 13 49.208 11.697 18.854 1.00 0.00 H ATOM 224 N ARG A 14 46.440 15.813 17.680 1.00 0.00 N ATOM 225 CA ARG A 14 46.999 17.069 18.151 1.00 0.00 C ATOM 226 C ARG A 14 46.550 17.274 19.536 1.00 0.00 C ATOM 227 O ARG A 14 45.379 17.130 19.832 1.00 0.00 O ATOM 228 CB ARG A 14 46.695 18.247 17.258 1.00 0.00 C ATOM 229 CG ARG A 14 47.547 18.072 16.002 1.00 0.00 C ATOM 230 CD ARG A 14 47.386 19.150 14.974 1.00 0.00 C ATOM 231 NE ARG A 14 48.088 20.362 15.360 1.00 0.00 N ATOM 232 CZ ARG A 14 47.987 21.518 14.710 1.00 0.00 C ATOM 233 NH1 ARG A 14 47.226 21.645 13.621 1.00 0.00 N1+ ATOM 234 NH2 ARG A 14 48.682 22.561 15.145 1.00 0.00 N ATOM 235 H ARG A 14 45.472 15.619 17.840 1.00 0.00 H ATOM 236 HA ARG A 14 47.993 16.962 18.174 1.00 0.00 H ATOM 237 HB2 ARG A 14 46.933 19.101 17.720 1.00 0.00 H ATOM 238 HB3 ARG A 14 45.724 18.257 17.018 1.00 0.00 H ATOM 239 HG2 ARG A 14 47.301 17.200 15.579 1.00 0.00 H ATOM 240 HG3 ARG A 14 48.508 18.048 16.279 1.00 0.00 H ATOM 241 HD2 ARG A 14 46.413 19.357 14.870 1.00 0.00 H ATOM 242 HD3 ARG A 14 47.753 18.825 14.102 1.00 0.00 H ATOM 243 HE ARG A 14 48.683 20.325 16.163 1.00 0.00 H ATOM 244 HH11 ARG A 14 47.168 22.526 13.151 1.00 0.00 H ATOM 245 HH12 ARG A 14 46.714 20.859 13.275 1.00 0.00 H ATOM 246 HH21 ARG A 14 48.618 23.438 14.669 1.00 0.00 H ATOM 247 HH22 ARG A 14 49.269 22.470 15.949 1.00 0.00 H ATOM 248 N LEU A 15 47.514 17.523 20.390 1.00 0.00 N ATOM 249 CA LEU A 15 47.218 17.658 21.785 1.00 0.00 C ATOM 250 C LEU A 15 46.959 19.076 22.264 1.00 0.00 C ATOM 251 O LEU A 15 46.706 19.257 23.444 1.00 0.00 O ATOM 252 CB LEU A 15 48.249 16.968 22.683 1.00 0.00 C ATOM 253 CG LEU A 15 48.403 15.456 22.445 1.00 0.00 C ATOM 254 CD1 LEU A 15 49.492 14.938 23.379 1.00 0.00 C ATOM 255 CD2 LEU A 15 47.109 14.692 22.732 1.00 0.00 C ATOM 256 H LEU A 15 48.456 17.619 20.067 1.00 0.00 H ATOM 257 HA LEU A 15 46.361 17.164 21.928 1.00 0.00 H ATOM 258 HB2 LEU A 15 47.975 17.107 23.635 1.00 0.00 H ATOM 259 HB3 LEU A 15 49.137 17.400 22.525 1.00 0.00 H ATOM 260 HG LEU A 15 48.678 15.297 21.497 1.00 0.00 H ATOM 261 HD11 LEU A 15 49.609 13.955 23.241 1.00 0.00 H ATOM 262 HD12 LEU A 15 50.352 15.407 23.181 1.00 0.00 H ATOM 263 HD13 LEU A 15 49.228 15.112 24.328 1.00 0.00 H ATOM 264 HD21 LEU A 15 47.254 13.717 22.565 1.00 0.00 H ATOM 265 HD22 LEU A 15 46.844 14.831 23.686 1.00 0.00 H ATOM 266 HD23 LEU A 15 46.383 15.029 22.132 1.00 0.00 H ATOM 267 N LYS A 16 47.015 20.051 21.389 1.00 0.00 N ATOM 268 CA LYS A 16 46.708 21.436 21.780 1.00 0.00 C ATOM 269 C LYS A 16 45.647 21.964 20.836 1.00 0.00 C ATOM 270 O LYS A 16 45.673 21.516 19.697 1.00 0.00 O ATOM 271 CB LYS A 16 48.009 22.241 21.801 1.00 0.00 C ATOM 272 CG LYS A 16 47.832 23.733 21.621 1.00 0.00 C ATOM 273 CD LYS A 16 48.147 24.536 22.878 1.00 0.00 C ATOM 274 CE LYS A 16 46.887 25.089 23.559 1.00 0.00 C ATOM 275 NZ LYS A 16 47.181 26.099 24.609 1.00 0.00 N1+ ATOM 276 H LYS A 16 47.270 19.851 20.443 1.00 0.00 H ATOM 277 HA LYS A 16 46.329 21.425 22.705 1.00 0.00 H ATOM 278 HB2 LYS A 16 48.595 21.906 21.063 1.00 0.00 H ATOM 279 HB3 LYS A 16 48.458 22.084 22.681 1.00 0.00 H ATOM 280 HG2 LYS A 16 46.883 23.911 21.361 1.00 0.00 H ATOM 281 HG3 LYS A 16 48.441 24.038 20.889 1.00 0.00 H ATOM 282 HD2 LYS A 16 48.738 25.303 22.628 1.00 0.00 H ATOM 283 HD3 LYS A 16 48.626 23.943 23.525 1.00 0.00 H ATOM 284 HE2 LYS A 16 46.394 24.328 23.980 1.00 0.00 H ATOM 285 HE3 LYS A 16 46.310 25.515 22.862 1.00 0.00 H ATOM 286 HZ1 LYS A 16 46.744 26.966 24.369 1.00 0.00 H ATOM 287 HZ2 LYS A 16 46.827 25.779 25.488 1.00 0.00 H ATOM 288 HZ3 LYS A 16 48.170 26.232 24.676 1.00 0.00 H ATOM 289 N ILE A 17 44.685 22.822 21.285 1.00 0.00 N ATOM 290 CA ILE A 17 43.607 23.297 20.400 1.00 0.00 C ATOM 291 C ILE A 17 44.163 23.749 19.075 1.00 0.00 C ATOM 292 O ILE A 17 45.220 24.375 19.087 1.00 0.00 O ATOM 293 CB ILE A 17 42.789 24.435 21.027 1.00 0.00 C ATOM 294 CG1 ILE A 17 42.046 23.902 22.247 1.00 0.00 C ATOM 295 CG2 ILE A 17 41.792 25.056 20.026 1.00 0.00 C ATOM 296 CD1 ILE A 17 41.103 24.937 22.842 1.00 0.00 C ATOM 297 H ILE A 17 44.712 23.135 22.234 1.00 0.00 H ATOM 298 HA ILE A 17 42.988 22.530 20.229 1.00 0.00 H ATOM 299 HB ILE A 17 43.421 25.149 21.329 1.00 0.00 H ATOM 300 HG12 ILE A 17 42.715 23.638 22.942 1.00 0.00 H ATOM 301 HG13 ILE A 17 41.514 23.100 21.975 1.00 0.00 H ATOM 302 HG21 ILE A 17 41.283 25.790 20.475 1.00 0.00 H ATOM 303 HG22 ILE A 17 42.293 25.427 19.244 1.00 0.00 H ATOM 304 HG23 ILE A 17 41.155 24.353 19.710 1.00 0.00 H ATOM 305 HD11 ILE A 17 40.638 24.547 23.637 1.00 0.00 H ATOM 306 HD12 ILE A 17 41.626 25.742 23.123 1.00 0.00 H ATOM 307 HD13 ILE A 17 40.425 25.203 22.157 1.00 0.00 H ATOM 308 N TYR A 18 43.535 23.422 17.955 1.00 0.00 N ATOM 309 CA TYR A 18 44.045 23.872 16.666 1.00 0.00 C ATOM 310 C TYR A 18 42.889 24.158 15.776 1.00 0.00 C ATOM 311 O TYR A 18 41.730 23.848 16.121 1.00 0.00 O ATOM 312 CB TYR A 18 45.041 22.891 15.991 1.00 0.00 C ATOM 313 CG TYR A 18 44.361 21.618 15.572 1.00 0.00 C ATOM 314 CD1 TYR A 18 44.131 20.630 16.525 1.00 0.00 C ATOM 315 CD2 TYR A 18 43.928 21.420 14.259 1.00 0.00 C ATOM 316 CE1 TYR A 18 43.477 19.449 16.165 1.00 0.00 C ATOM 317 CE2 TYR A 18 43.295 20.241 13.873 1.00 0.00 C ATOM 318 CZ TYR A 18 43.064 19.266 14.846 1.00 0.00 C ATOM 319 OH TYR A 18 42.481 18.075 14.502 1.00 0.00 O ATOM 320 H TYR A 18 42.707 22.863 17.994 1.00 0.00 H ATOM 321 HA TYR A 18 44.528 24.734 16.818 1.00 0.00 H ATOM 322 HB2 TYR A 18 45.771 22.672 16.639 1.00 0.00 H ATOM 323 HB3 TYR A 18 45.433 23.331 15.183 1.00 0.00 H ATOM 324 HD1 TYR A 18 44.434 20.766 17.468 1.00 0.00 H ATOM 325 HD2 TYR A 18 44.076 22.140 13.581 1.00 0.00 H ATOM 326 HE1 TYR A 18 43.306 18.740 16.849 1.00 0.00 H ATOM 327 HE2 TYR A 18 43.013 20.096 12.924 1.00 0.00 H ATOM 328 HH TYR A 18 42.177 17.920 13.562 1.00 0.00 H ATOM 329 N LYS A 19 43.181 24.761 14.644 1.00 0.00 N ATOM 330 CA LYS A 19 42.100 25.017 13.730 1.00 0.00 C ATOM 331 C LYS A 19 42.106 23.969 12.668 1.00 0.00 C ATOM 332 O LYS A 19 43.183 23.620 12.162 1.00 0.00 O ATOM 333 CB LYS A 19 42.189 26.386 13.078 1.00 0.00 C ATOM 334 CG LYS A 19 41.893 27.487 14.044 1.00 0.00 C ATOM 335 CD LYS A 19 41.374 28.731 13.368 1.00 0.00 C ATOM 336 CE LYS A 19 41.737 29.991 14.136 1.00 0.00 C ATOM 337 NZ LYS A 19 41.380 31.273 13.461 1.00 0.00 N1+ ATOM 338 H LYS A 19 44.119 25.031 14.427 1.00 0.00 H ATOM 339 HA LYS A 19 41.237 24.958 14.232 1.00 0.00 H ATOM 340 HB2 LYS A 19 41.530 26.429 12.327 1.00 0.00 H ATOM 341 HB3 LYS A 19 43.113 26.512 12.718 1.00 0.00 H ATOM 342 HG2 LYS A 19 42.734 27.717 14.535 1.00 0.00 H ATOM 343 HG3 LYS A 19 41.205 27.166 14.694 1.00 0.00 H ATOM 344 HD2 LYS A 19 40.378 28.670 13.300 1.00 0.00 H ATOM 345 HD3 LYS A 19 41.768 28.788 12.450 1.00 0.00 H ATOM 346 HE2 LYS A 19 42.725 29.986 14.288 1.00 0.00 H ATOM 347 HE3 LYS A 19 41.264 29.963 15.017 1.00 0.00 H ATOM 348 HZ1 LYS A 19 40.747 31.789 14.039 1.00 0.00 H ATOM 349 HZ2 LYS A 19 42.209 31.812 13.310 1.00 0.00 H ATOM 350 HZ3 LYS A 19 40.945 31.077 12.582 1.00 0.00 H ATOM 351 N ASP A 20 40.913 23.515 12.339 1.00 0.00 N ATOM 352 CA ASP A 20 40.772 22.504 11.330 1.00 0.00 C ATOM 353 C ASP A 20 40.852 23.066 9.911 1.00 0.00 C ATOM 354 O ASP A 20 41.129 24.248 9.713 1.00 0.00 O ATOM 355 CB ASP A 20 39.586 21.575 11.611 1.00 0.00 C ATOM 356 CG ASP A 20 38.238 22.054 11.192 1.00 0.00 C ATOM 357 OD1 ASP A 20 38.244 23.261 10.763 1.00 0.00 O ATOM 358 OD2 ASP A 20 37.238 21.365 11.231 1.00 0.00 O1- ATOM 359 H ASP A 20 40.101 23.878 12.796 1.00 0.00 H ATOM 360 HA ASP A 20 41.583 21.926 11.426 1.00 0.00 H ATOM 361 HB2 ASP A 20 39.556 21.414 12.597 1.00 0.00 H ATOM 362 HB3 ASP A 20 39.760 20.712 11.137 1.00 0.00 H ATOM 363 N THR A 21 40.591 22.249 8.909 1.00 0.00 N ATOM 364 CA THR A 21 40.721 22.757 7.555 1.00 0.00 C ATOM 365 C THR A 21 39.731 23.806 7.224 1.00 0.00 C ATOM 366 O THR A 21 39.948 24.545 6.255 1.00 0.00 O ATOM 367 CB THR A 21 40.641 21.676 6.486 1.00 0.00 C ATOM 368 CG2 THR A 21 41.479 20.479 6.931 1.00 0.00 C ATOM 369 OG1 THR A 21 39.297 21.284 6.382 1.00 0.00 O ATOM 370 H THR A 21 40.311 21.304 9.077 1.00 0.00 H ATOM 371 HA THR A 21 41.627 23.175 7.483 1.00 0.00 H ATOM 372 HB THR A 21 40.971 22.027 5.610 1.00 0.00 H ATOM 373 HG1 THR A 21 38.706 22.057 6.611 1.00 0.00 H ATOM 374 HG21 THR A 21 41.433 19.763 6.235 1.00 0.00 H ATOM 375 HG22 THR A 21 42.430 20.765 7.053 1.00 0.00 H ATOM 376 HG23 THR A 21 41.123 20.126 7.796 1.00 0.00 H ATOM 377 N GLU A 22 38.658 23.848 8.002 1.00 0.00 N ATOM 378 CA GLU A 22 37.607 24.826 7.752 1.00 0.00 C ATOM 379 C GLU A 22 37.802 26.042 8.608 1.00 0.00 C ATOM 380 O GLU A 22 37.086 27.000 8.472 1.00 0.00 O ATOM 381 CB GLU A 22 36.229 24.245 8.029 1.00 0.00 C ATOM 382 CG GLU A 22 35.803 23.119 7.062 1.00 0.00 C ATOM 383 CD GLU A 22 35.537 23.554 5.641 1.00 0.00 C ATOM 384 OE1 GLU A 22 34.990 24.737 5.534 1.00 0.00 O ATOM 385 OE2 GLU A 22 35.788 22.854 4.684 1.00 0.00 O1- ATOM 386 H GLU A 22 38.570 23.206 8.763 1.00 0.00 H ATOM 387 HA GLU A 22 37.650 25.102 6.792 1.00 0.00 H ATOM 388 HB2 GLU A 22 35.559 24.984 7.962 1.00 0.00 H ATOM 389 HB3 GLU A 22 36.227 23.876 8.958 1.00 0.00 H ATOM 390 HG2 GLU A 22 34.966 22.705 7.420 1.00 0.00 H ATOM 391 HG3 GLU A 22 36.532 22.435 7.044 1.00 0.00 H ATOM 392 N GLY A 23 38.802 25.975 9.498 1.00 0.00 N ATOM 393 CA GLY A 23 39.125 27.029 10.418 1.00 0.00 C ATOM 394 C GLY A 23 38.453 26.867 11.772 1.00 0.00 C ATOM 395 O GLY A 23 38.416 27.826 12.506 1.00 0.00 O ATOM 396 H GLY A 23 39.355 25.142 9.523 1.00 0.00 H ATOM 397 HA2 GLY A 23 38.833 27.899 10.020 1.00 0.00 H ATOM 398 HA3 GLY A 23 40.116 27.040 10.554 1.00 0.00 H ATOM 399 N TYR A 24 37.953 25.681 12.130 1.00 0.00 N ATOM 400 CA TYR A 24 37.311 25.534 13.435 1.00 0.00 C ATOM 401 C TYR A 24 38.194 24.930 14.469 1.00 0.00 C ATOM 402 O TYR A 24 39.019 24.051 14.196 1.00 0.00 O ATOM 403 CB TYR A 24 36.048 24.689 13.435 1.00 0.00 C ATOM 404 CG TYR A 24 35.055 25.172 12.447 1.00 0.00 C ATOM 405 CD1 TYR A 24 34.659 26.507 12.443 1.00 0.00 C ATOM 406 CD2 TYR A 24 34.486 24.293 11.532 1.00 0.00 C ATOM 407 CE1 TYR A 24 33.697 26.962 11.544 1.00 0.00 C ATOM 408 CE2 TYR A 24 33.549 24.738 10.605 1.00 0.00 C ATOM 409 CZ TYR A 24 33.155 26.077 10.613 1.00 0.00 C ATOM 410 OH TYR A 24 32.235 26.533 9.711 1.00 0.00 O ATOM 411 H TYR A 24 38.017 24.899 11.510 1.00 0.00 H ATOM 412 HA TYR A 24 37.060 26.449 13.751 1.00 0.00 H ATOM 413 HB2 TYR A 24 35.638 24.722 14.347 1.00 0.00 H ATOM 414 HB3 TYR A 24 36.292 23.745 13.212 1.00 0.00 H ATOM 415 HD1 TYR A 24 35.070 27.146 13.093 1.00 0.00 H ATOM 416 HD2 TYR A 24 34.754 23.329 11.540 1.00 0.00 H ATOM 417 HE1 TYR A 24 33.398 27.916 11.566 1.00 0.00 H ATOM 418 HE2 TYR A 24 33.160 24.103 9.937 1.00 0.00 H ATOM 419 HH TYR A 24 31.840 25.906 9.039 1.00 0.00 H ATOM 420 N TYR A 25 37.986 25.431 15.671 1.00 0.00 N ATOM 421 CA TYR A 25 38.655 24.959 16.849 1.00 0.00 C ATOM 422 C TYR A 25 38.376 23.476 17.054 1.00 0.00 C ATOM 423 O TYR A 25 37.220 23.074 17.179 1.00 0.00 O ATOM 424 CB TYR A 25 38.266 25.826 18.083 1.00 0.00 C ATOM 425 CG TYR A 25 38.866 27.223 17.996 1.00 0.00 C ATOM 426 CD1 TYR A 25 40.242 27.370 17.843 1.00 0.00 C ATOM 427 CD2 TYR A 25 38.084 28.379 18.072 1.00 0.00 C ATOM 428 CE1 TYR A 25 40.823 28.632 17.735 1.00 0.00 C ATOM 429 CE2 TYR A 25 38.646 29.655 17.965 1.00 0.00 C ATOM 430 CZ TYR A 25 40.021 29.774 17.828 1.00 0.00 C ATOM 431 OH TYR A 25 40.604 31.010 17.739 1.00 0.00 O ATOM 432 H TYR A 25 37.328 26.178 15.766 1.00 0.00 H ATOM 433 HA TYR A 25 39.638 25.065 16.702 1.00 0.00 H ATOM 434 HB2 TYR A 25 38.602 25.379 18.912 1.00 0.00 H ATOM 435 HB3 TYR A 25 37.270 25.902 18.125 1.00 0.00 H ATOM 436 HD1 TYR A 25 40.823 26.557 17.810 1.00 0.00 H ATOM 437 HD2 TYR A 25 37.097 28.291 18.206 1.00 0.00 H ATOM 438 HE1 TYR A 25 41.809 28.721 17.592 1.00 0.00 H ATOM 439 HE2 TYR A 25 38.066 30.469 17.987 1.00 0.00 H ATOM 440 HH TYR A 25 41.592 31.088 17.609 1.00 0.00 H ATOM 441 N THR A 26 39.483 22.696 17.027 1.00 0.00 N ATOM 442 CA THR A 26 39.472 21.238 17.137 1.00 0.00 C ATOM 443 C THR A 26 40.582 20.830 18.109 1.00 0.00 C ATOM 444 O THR A 26 41.452 21.633 18.378 1.00 0.00 O ATOM 445 CB THR A 26 39.771 20.705 15.687 1.00 0.00 C ATOM 446 CG2 THR A 26 39.882 19.191 15.535 1.00 0.00 C ATOM 447 OG1 THR A 26 38.818 21.190 14.795 1.00 0.00 O ATOM 448 H THR A 26 40.369 23.148 16.925 1.00 0.00 H ATOM 449 HA THR A 26 38.582 20.913 17.458 1.00 0.00 H ATOM 450 HB THR A 26 40.651 21.091 15.411 1.00 0.00 H ATOM 451 HG1 THR A 26 38.164 21.766 15.286 1.00 0.00 H ATOM 452 HG21 THR A 26 40.072 18.965 14.580 1.00 0.00 H ATOM 453 HG22 THR A 26 40.625 18.852 16.112 1.00 0.00 H ATOM 454 HG23 THR A 26 39.022 18.764 15.814 1.00 0.00 H ATOM 455 N ILE A 27 40.590 19.602 18.636 1.00 0.00 N ATOM 456 CA ILE A 27 41.647 19.066 19.488 1.00 0.00 C ATOM 457 C ILE A 27 41.678 17.543 19.260 1.00 0.00 C ATOM 458 O ILE A 27 40.697 16.964 18.751 1.00 0.00 O ATOM 459 CB ILE A 27 41.436 19.422 20.971 1.00 0.00 C ATOM 460 CG1 ILE A 27 42.691 19.176 21.819 1.00 0.00 C ATOM 461 CG2 ILE A 27 40.252 18.616 21.503 1.00 0.00 C ATOM 462 CD1 ILE A 27 43.034 20.298 22.758 1.00 0.00 C ATOM 463 H ILE A 27 39.814 19.006 18.431 1.00 0.00 H ATOM 464 HA ILE A 27 42.521 19.450 19.190 1.00 0.00 H ATOM 465 HB ILE A 27 41.205 20.393 21.030 1.00 0.00 H ATOM 466 HG12 ILE A 27 43.465 19.038 21.200 1.00 0.00 H ATOM 467 HG13 ILE A 27 42.545 18.348 22.361 1.00 0.00 H ATOM 468 HG21 ILE A 27 40.104 18.838 22.467 1.00 0.00 H ATOM 469 HG22 ILE A 27 39.431 18.843 20.979 1.00 0.00 H ATOM 470 HG23 ILE A 27 40.446 17.639 21.412 1.00 0.00 H ATOM 471 HD11 ILE A 27 43.859 20.062 23.272 1.00 0.00 H ATOM 472 HD12 ILE A 27 43.195 21.134 22.234 1.00 0.00 H ATOM 473 HD13 ILE A 27 42.276 20.444 23.394 1.00 0.00 H ATOM 474 N GLY A 28 42.767 16.884 19.618 1.00 0.00 N ATOM 475 CA GLY A 28 42.837 15.417 19.536 1.00 0.00 C ATOM 476 C GLY A 28 42.808 14.845 18.133 1.00 0.00 C ATOM 477 O GLY A 28 43.586 15.262 17.289 1.00 0.00 O ATOM 478 H GLY A 28 43.560 17.394 19.952 1.00 0.00 H ATOM 479 HA2 GLY A 28 42.058 15.042 20.039 1.00 0.00 H ATOM 480 HA3 GLY A 28 43.688 15.123 19.972 1.00 0.00 H ATOM 481 N ILE A 29 41.957 13.840 17.922 1.00 0.00 N ATOM 482 CA ILE A 29 41.831 13.198 16.635 1.00 0.00 C ATOM 483 C ILE A 29 40.600 13.652 15.897 1.00 0.00 C ATOM 484 O ILE A 29 39.627 12.922 15.734 1.00 0.00 O ATOM 485 CB ILE A 29 41.887 11.675 16.745 1.00 0.00 C ATOM 486 CG1 ILE A 29 43.189 11.241 17.409 1.00 0.00 C ATOM 487 CG2 ILE A 29 41.884 11.099 15.340 1.00 0.00 C ATOM 488 CD1 ILE A 29 43.079 9.984 18.253 1.00 0.00 C ATOM 489 H ILE A 29 41.388 13.521 18.680 1.00 0.00 H ATOM 490 HA ILE A 29 42.620 13.481 16.089 1.00 0.00 H ATOM 491 HB ILE A 29 41.102 11.334 17.262 1.00 0.00 H ATOM 492 HG12 ILE A 29 43.502 11.986 17.998 1.00 0.00 H ATOM 493 HG13 ILE A 29 43.866 11.077 16.691 1.00 0.00 H ATOM 494 HG21 ILE A 29 41.920 10.101 15.389 1.00 0.00 H ATOM 495 HG22 ILE A 29 41.049 11.379 14.867 1.00 0.00 H ATOM 496 HG23 ILE A 29 42.681 11.437 14.839 1.00 0.00 H ATOM 497 HD11 ILE A 29 43.971 9.770 18.650 1.00 0.00 H ATOM 498 HD12 ILE A 29 42.415 10.132 18.986 1.00 0.00 H ATOM 499 HD13 ILE A 29 42.778 9.222 17.679 1.00 0.00 H ATOM 500 N GLY A 30 40.643 14.898 15.455 1.00 0.00 N ATOM 501 CA GLY A 30 39.510 15.413 14.721 1.00 0.00 C ATOM 502 C GLY A 30 38.278 15.720 15.570 1.00 0.00 C ATOM 503 O GLY A 30 37.159 15.738 15.072 1.00 0.00 O ATOM 504 H GLY A 30 41.444 15.472 15.625 1.00 0.00 H ATOM 505 HA2 GLY A 30 39.252 14.735 14.033 1.00 0.00 H ATOM 506 HA3 GLY A 30 39.792 16.258 14.267 1.00 0.00 H ATOM 507 N HIS A 31 38.456 16.020 16.845 1.00 0.00 N ATOM 508 CA HIS A 31 37.278 16.327 17.647 1.00 0.00 C ATOM 509 C HIS A 31 36.906 17.797 17.524 1.00 0.00 C ATOM 510 O HIS A 31 37.581 18.662 18.150 1.00 0.00 O ATOM 511 CB HIS A 31 37.519 15.962 19.138 1.00 0.00 C ATOM 512 CG HIS A 31 36.299 16.200 19.977 1.00 0.00 C ATOM 513 CD2 HIS A 31 35.982 17.242 20.831 1.00 0.00 C ATOM 514 ND1 HIS A 31 35.223 15.326 19.973 1.00 0.00 N ATOM 515 CE1 HIS A 31 34.288 15.829 20.776 1.00 0.00 C ATOM 516 NE2 HIS A 31 34.720 16.984 21.307 1.00 0.00 N ATOM 517 H HIS A 31 39.371 16.036 17.247 1.00 0.00 H ATOM 518 HA HIS A 31 36.514 15.779 17.308 1.00 0.00 H ATOM 519 HB2 HIS A 31 38.268 16.522 19.491 1.00 0.00 H ATOM 520 HB3 HIS A 31 37.769 14.996 19.198 1.00 0.00 H ATOM 521 HD1 HIS A 31 35.160 14.471 19.459 1.00 0.00 H ATOM 522 HD2 HIS A 31 36.558 18.028 21.057 1.00 0.00 H ATOM 523 HE1 HIS A 31 33.398 15.410 20.956 1.00 0.00 H ATOM 524 HE2 HIS A 31 34.208 17.561 21.943 1.00 0.00 H ATOM 525 N LEU A 32 35.868 18.122 16.745 1.00 0.00 N ATOM 526 CA LEU A 32 35.424 19.499 16.602 1.00 0.00 C ATOM 527 C LEU A 32 34.976 20.045 17.964 1.00 0.00 C ATOM 528 O LEU A 32 34.216 19.449 18.719 1.00 0.00 O ATOM 529 CB LEU A 32 34.287 19.581 15.577 1.00 0.00 C ATOM 530 CG LEU A 32 33.682 20.976 15.459 1.00 0.00 C ATOM 531 CD1 LEU A 32 34.747 21.958 15.002 1.00 0.00 C ATOM 532 CD2 LEU A 32 32.569 20.989 14.439 1.00 0.00 C ATOM 533 H LEU A 32 35.386 17.400 16.249 1.00 0.00 H ATOM 534 HA LEU A 32 36.191 20.050 16.273 1.00 0.00 H ATOM 535 HB2 LEU A 32 33.566 18.944 15.851 1.00 0.00 H ATOM 536 HB3 LEU A 32 34.646 19.314 14.683 1.00 0.00 H ATOM 537 HG LEU A 32 33.324 21.261 16.348 1.00 0.00 H ATOM 538 HD11 LEU A 32 34.347 22.871 14.926 1.00 0.00 H ATOM 539 HD12 LEU A 32 35.493 21.975 15.668 1.00 0.00 H ATOM 540 HD13 LEU A 32 35.102 21.674 14.111 1.00 0.00 H ATOM 541 HD21 LEU A 32 32.185 21.910 14.376 1.00 0.00 H ATOM 542 HD22 LEU A 32 32.931 20.717 13.547 1.00 0.00 H ATOM 543 HD23 LEU A 32 31.854 20.349 14.718 1.00 0.00 H ATOM 544 N LEU A 33 35.461 21.180 18.344 1.00 0.00 N ATOM 545 CA LEU A 33 35.025 21.681 19.619 1.00 0.00 C ATOM 546 C LEU A 33 33.848 22.660 19.482 1.00 0.00 C ATOM 547 O LEU A 33 32.879 22.609 20.244 1.00 0.00 O ATOM 548 CB LEU A 33 36.199 22.393 20.317 1.00 0.00 C ATOM 549 CG LEU A 33 37.242 21.463 20.913 1.00 0.00 C ATOM 550 CD1 LEU A 33 38.384 22.324 21.390 1.00 0.00 C ATOM 551 CD2 LEU A 33 36.667 20.723 22.113 1.00 0.00 C ATOM 552 H LEU A 33 36.110 21.687 17.777 1.00 0.00 H ATOM 553 HA LEU A 33 34.736 20.909 20.185 1.00 0.00 H ATOM 554 HB2 LEU A 33 35.827 22.957 21.054 1.00 0.00 H ATOM 555 HB3 LEU A 33 36.652 22.979 19.645 1.00 0.00 H ATOM 556 HG LEU A 33 37.562 20.812 20.224 1.00 0.00 H ATOM 557 HD11 LEU A 33 39.094 21.744 21.791 1.00 0.00 H ATOM 558 HD12 LEU A 33 38.765 22.831 20.617 1.00 0.00 H ATOM 559 HD13 LEU A 33 38.051 22.968 22.079 1.00 0.00 H ATOM 560 HD21 LEU A 33 37.363 20.115 22.495 1.00 0.00 H ATOM 561 HD22 LEU A 33 36.384 21.384 22.808 1.00 0.00 H ATOM 562 HD23 LEU A 33 35.876 20.184 21.824 1.00 0.00 H ATOM 563 N THR A 34 33.987 23.592 18.521 1.00 0.00 N ATOM 564 CA THR A 34 32.986 24.642 18.256 1.00 0.00 C ATOM 565 C THR A 34 33.221 25.336 16.932 1.00 0.00 C ATOM 566 O THR A 34 34.380 25.468 16.510 1.00 0.00 O ATOM 567 CB THR A 34 33.033 25.769 19.344 1.00 0.00 C ATOM 568 CG2 THR A 34 34.398 26.431 19.470 1.00 0.00 C ATOM 569 OG1 THR A 34 32.100 26.789 19.087 1.00 0.00 O ATOM 570 H THR A 34 34.813 23.571 17.957 1.00 0.00 H ATOM 571 HA THR A 34 32.075 24.230 18.252 1.00 0.00 H ATOM 572 HB THR A 34 32.806 25.357 20.226 1.00 0.00 H ATOM 573 HG1 THR A 34 31.801 27.193 19.952 1.00 0.00 H ATOM 574 HG21 THR A 34 34.362 27.137 20.177 1.00 0.00 H ATOM 575 HG22 THR A 34 35.080 25.744 19.720 1.00 0.00 H ATOM 576 HG23 THR A 34 34.649 26.847 18.596 1.00 0.00 H ATOM 577 N LYS A 35 32.148 25.842 16.314 1.00 0.00 N ATOM 578 CA LYS A 35 32.293 26.619 15.096 1.00 0.00 C ATOM 579 C LYS A 35 32.444 28.121 15.358 1.00 0.00 C ATOM 580 O LYS A 35 32.611 28.885 14.434 1.00 0.00 O ATOM 581 CB LYS A 35 31.229 26.378 14.104 1.00 0.00 C ATOM 582 CG LYS A 35 31.191 24.899 13.772 1.00 0.00 C ATOM 583 CD LYS A 35 30.131 24.557 12.782 1.00 0.00 C ATOM 584 CE LYS A 35 30.071 23.077 12.513 1.00 0.00 C ATOM 585 NZ LYS A 35 29.787 22.724 11.102 1.00 0.00 N1+ ATOM 586 H LYS A 35 31.237 25.684 16.695 1.00 0.00 H ATOM 587 HA LYS A 35 33.147 26.320 14.671 1.00 0.00 H ATOM 588 HB2 LYS A 35 31.419 26.903 13.274 1.00 0.00 H ATOM 589 HB3 LYS A 35 30.347 26.660 14.483 1.00 0.00 H ATOM 590 HG2 LYS A 35 31.020 24.387 14.614 1.00 0.00 H ATOM 591 HG3 LYS A 35 32.078 24.633 13.395 1.00 0.00 H ATOM 592 HD2 LYS A 35 30.323 25.034 11.924 1.00 0.00 H ATOM 593 HD3 LYS A 35 29.246 24.857 13.139 1.00 0.00 H ATOM 594 HE2 LYS A 35 29.351 22.684 13.085 1.00 0.00 H ATOM 595 HE3 LYS A 35 30.952 22.677 12.764 1.00 0.00 H ATOM 596 HZ1 LYS A 35 29.764 21.729 11.006 1.00 0.00 H ATOM 597 HZ2 LYS A 35 28.902 23.106 10.834 1.00 0.00 H ATOM 598 HZ3 LYS A 35 30.503 23.099 10.514 1.00 0.00 H ATOM 599 N SER A 36 32.383 28.507 16.622 1.00 0.00 N ATOM 600 CA SER A 36 32.532 29.893 17.028 1.00 0.00 C ATOM 601 C SER A 36 33.987 30.315 16.900 1.00 0.00 C ATOM 602 O SER A 36 34.918 29.529 17.107 1.00 0.00 O ATOM 603 CB SER A 36 32.048 30.129 18.454 1.00 0.00 C ATOM 604 OG SER A 36 33.007 30.894 19.157 1.00 0.00 O ATOM 605 H SER A 36 32.228 27.815 17.327 1.00 0.00 H ATOM 606 HA SER A 36 31.985 30.461 16.413 1.00 0.00 H ATOM 607 HB2 SER A 36 31.922 29.250 18.913 1.00 0.00 H ATOM 608 HB3 SER A 36 31.178 30.622 18.433 1.00 0.00 H ATOM 609 HG SER A 36 32.589 31.748 19.468 1.00 0.00 H ATOM 610 N PRO A 37 34.200 31.589 16.582 1.00 0.00 N ATOM 611 CA PRO A 37 35.528 32.147 16.378 1.00 0.00 C ATOM 612 C PRO A 37 36.327 32.364 17.654 1.00 0.00 C ATOM 613 O PRO A 37 37.517 32.682 17.626 1.00 0.00 O ATOM 614 CB PRO A 37 35.285 33.473 15.664 1.00 0.00 C ATOM 615 CG PRO A 37 33.907 33.383 15.040 1.00 0.00 C ATOM 616 CD PRO A 37 33.162 32.324 15.811 1.00 0.00 C ATOM 617 HA PRO A 37 36.044 31.542 15.771 1.00 0.00 H ATOM 618 HB2 PRO A 37 35.319 34.228 16.318 1.00 0.00 H ATOM 619 HB3 PRO A 37 35.976 33.615 14.955 1.00 0.00 H ATOM 620 HG2 PRO A 37 33.435 34.262 15.114 1.00 0.00 H ATOM 621 HG3 PRO A 37 33.979 33.124 14.077 1.00 0.00 H ATOM 622 HD2 PRO A 37 32.499 32.744 16.430 1.00 0.00 H ATOM 623 HD3 PRO A 37 32.688 31.705 15.185 1.00 0.00 H ATOM 624 N SER A 38 35.658 32.152 18.774 1.00 0.00 N ATOM 625 CA SER A 38 36.266 32.383 20.065 1.00 0.00 C ATOM 626 C SER A 38 37.049 31.257 20.656 1.00 0.00 C ATOM 627 O SER A 38 36.532 30.169 20.948 1.00 0.00 O ATOM 628 CB SER A 38 35.236 32.920 21.057 1.00 0.00 C ATOM 629 OG SER A 38 35.898 33.065 22.327 1.00 0.00 O ATOM 630 H SER A 38 34.714 31.826 18.727 1.00 0.00 H ATOM 631 HA SER A 38 36.922 33.125 19.927 1.00 0.00 H ATOM 632 HB2 SER A 38 34.474 32.278 21.140 1.00 0.00 H ATOM 633 HB3 SER A 38 34.893 33.807 20.747 1.00 0.00 H ATOM 634 HG SER A 38 35.860 34.022 22.615 1.00 0.00 H ATOM 635 N LEU A 39 38.306 31.581 20.913 1.00 0.00 N ATOM 636 CA LEU A 39 39.160 30.610 21.507 1.00 0.00 C ATOM 637 C LEU A 39 38.685 30.309 22.910 1.00 0.00 C ATOM 638 O LEU A 39 38.960 29.279 23.522 1.00 0.00 O ATOM 639 CB LEU A 39 40.647 30.982 21.418 1.00 0.00 C ATOM 640 CG LEU A 39 41.487 29.947 22.142 1.00 0.00 C ATOM 641 CD1 LEU A 39 41.447 28.628 21.386 1.00 0.00 C ATOM 642 CD2 LEU A 39 42.907 30.451 22.271 1.00 0.00 C ATOM 643 H LEU A 39 38.650 32.494 20.693 1.00 0.00 H ATOM 644 HA LEU A 39 39.045 29.768 20.980 1.00 0.00 H ATOM 645 HB2 LEU A 39 40.790 31.878 21.839 1.00 0.00 H ATOM 646 HB3 LEU A 39 40.922 31.018 20.457 1.00 0.00 H ATOM 647 HG LEU A 39 41.109 29.807 23.057 1.00 0.00 H ATOM 648 HD11 LEU A 39 42.002 27.950 21.868 1.00 0.00 H ATOM 649 HD12 LEU A 39 40.502 28.305 21.329 1.00 0.00 H ATOM 650 HD13 LEU A 39 41.810 28.761 20.464 1.00 0.00 H ATOM 651 HD21 LEU A 39 43.461 29.769 22.748 1.00 0.00 H ATOM 652 HD22 LEU A 39 43.288 30.612 21.360 1.00 0.00 H ATOM 653 HD23 LEU A 39 42.911 31.306 22.790 1.00 0.00 H ATOM 654 N ASN A 40 37.941 31.227 23.459 1.00 0.00 N ATOM 655 CA ASN A 40 37.459 30.952 24.792 1.00 0.00 C ATOM 656 C ASN A 40 36.267 30.047 24.772 1.00 0.00 C ATOM 657 O ASN A 40 36.145 29.189 25.623 1.00 0.00 O ATOM 658 CB ASN A 40 37.213 32.214 25.617 1.00 0.00 C ATOM 659 CG ASN A 40 38.424 33.116 25.635 1.00 0.00 C ATOM 660 ND2 ASN A 40 38.397 34.140 24.783 1.00 0.00 N ATOM 661 OD1 ASN A 40 39.371 32.893 26.415 1.00 0.00 O ATOM 662 H ASN A 40 37.716 32.077 22.982 1.00 0.00 H ATOM 663 HA ASN A 40 38.187 30.449 25.257 1.00 0.00 H ATOM 664 HB2 ASN A 40 36.992 31.949 26.556 1.00 0.00 H ATOM 665 HB3 ASN A 40 36.442 32.714 25.222 1.00 0.00 H ATOM 666 HD21 ASN A 40 37.609 34.269 24.181 1.00 0.00 H ATOM 667 HD22 ASN A 40 39.164 34.780 24.746 1.00 0.00 H ATOM 668 N ALA A 41 35.381 30.254 23.789 1.00 0.00 N ATOM 669 CA ALA A 41 34.251 29.364 23.692 1.00 0.00 C ATOM 670 C ALA A 41 34.809 27.944 23.486 1.00 0.00 C ATOM 671 O ALA A 41 34.354 26.993 24.106 1.00 0.00 O ATOM 672 CB ALA A 41 33.267 29.799 22.625 1.00 0.00 C ATOM 673 H ALA A 41 35.500 31.005 23.140 1.00 0.00 H ATOM 674 HA ALA A 41 33.774 29.380 24.571 1.00 0.00 H ATOM 675 HB1 ALA A 41 32.503 29.155 22.594 1.00 0.00 H ATOM 676 HB2 ALA A 41 32.924 30.713 22.841 1.00 0.00 H ATOM 677 HB3 ALA A 41 33.725 29.816 21.736 1.00 0.00 H ATOM 678 N ALA A 42 35.885 27.843 22.679 1.00 0.00 N ATOM 679 CA ALA A 42 36.550 26.572 22.425 1.00 0.00 C ATOM 680 C ALA A 42 37.162 26.051 23.687 1.00 0.00 C ATOM 681 O ALA A 42 37.089 24.846 23.988 1.00 0.00 O ATOM 682 CB ALA A 42 37.676 26.701 21.398 1.00 0.00 C ATOM 683 H ALA A 42 36.238 28.669 22.240 1.00 0.00 H ATOM 684 HA ALA A 42 35.877 25.912 22.091 1.00 0.00 H ATOM 685 HB1 ALA A 42 38.102 25.807 21.256 1.00 0.00 H ATOM 686 HB2 ALA A 42 37.301 27.033 20.532 1.00 0.00 H ATOM 687 HB3 ALA A 42 38.361 27.347 21.734 1.00 0.00 H ATOM 688 N LYS A 43 37.782 26.924 24.440 1.00 0.00 N ATOM 689 CA LYS A 43 38.361 26.453 25.685 1.00 0.00 C ATOM 690 C LYS A 43 37.291 25.931 26.656 1.00 0.00 C ATOM 691 O LYS A 43 37.471 24.939 27.350 1.00 0.00 O ATOM 692 CB LYS A 43 39.283 27.458 26.348 1.00 0.00 C ATOM 693 CG LYS A 43 40.757 27.326 25.966 1.00 0.00 C ATOM 694 CD LYS A 43 41.630 28.498 26.431 1.00 0.00 C ATOM 695 CE LYS A 43 43.094 28.399 26.031 1.00 0.00 C ATOM 696 NZ LYS A 43 44.026 28.825 27.093 1.00 0.00 N1+ ATOM 697 H LYS A 43 37.854 27.883 24.167 1.00 0.00 H ATOM 698 HA LYS A 43 38.930 25.666 25.448 1.00 0.00 H ATOM 699 HB2 LYS A 43 39.207 27.343 27.339 1.00 0.00 H ATOM 700 HB3 LYS A 43 38.977 28.376 26.094 1.00 0.00 H ATOM 701 HG2 LYS A 43 40.819 27.264 24.970 1.00 0.00 H ATOM 702 HG3 LYS A 43 41.114 26.486 26.376 1.00 0.00 H ATOM 703 HD2 LYS A 43 41.582 28.545 27.429 1.00 0.00 H ATOM 704 HD3 LYS A 43 41.256 29.339 26.039 1.00 0.00 H ATOM 705 HE2 LYS A 43 43.243 28.978 25.229 1.00 0.00 H ATOM 706 HE3 LYS A 43 43.294 27.448 25.797 1.00 0.00 H ATOM 707 HZ1 LYS A 43 44.967 28.736 26.766 1.00 0.00 H ATOM 708 HZ2 LYS A 43 43.845 29.779 27.332 1.00 0.00 H ATOM 709 HZ3 LYS A 43 43.897 28.249 27.900 1.00 0.00 H ATOM 710 N SER A 44 36.163 26.603 26.693 1.00 0.00 N ATOM 711 CA SER A 44 35.063 26.203 27.552 1.00 0.00 C ATOM 712 C SER A 44 34.475 24.822 27.226 1.00 0.00 C ATOM 713 O SER A 44 34.172 24.035 28.100 1.00 0.00 O ATOM 714 CB SER A 44 33.998 27.276 27.444 1.00 0.00 C ATOM 715 OG SER A 44 33.557 27.589 28.714 1.00 0.00 O ATOM 716 H SER A 44 36.059 27.412 26.114 1.00 0.00 H ATOM 717 HA SER A 44 35.394 26.186 28.495 1.00 0.00 H ATOM 718 HB2 SER A 44 33.233 26.937 26.896 1.00 0.00 H ATOM 719 HB3 SER A 44 34.384 28.091 27.011 1.00 0.00 H ATOM 720 HG SER A 44 33.265 28.545 28.739 1.00 0.00 H ATOM 721 N GLU A 45 34.278 24.584 25.943 1.00 0.00 N ATOM 722 CA GLU A 45 33.755 23.327 25.434 1.00 0.00 C ATOM 723 C GLU A 45 34.737 22.223 25.746 1.00 0.00 C ATOM 724 O GLU A 45 34.355 21.116 26.142 1.00 0.00 O ATOM 725 CB GLU A 45 33.604 23.393 23.907 1.00 0.00 C ATOM 726 CG GLU A 45 32.424 24.272 23.476 1.00 0.00 C ATOM 727 CD GLU A 45 31.092 23.657 23.840 1.00 0.00 C ATOM 728 OE1 GLU A 45 30.867 22.464 23.729 1.00 0.00 O ATOM 729 OE2 GLU A 45 30.224 24.520 24.274 1.00 0.00 O1- ATOM 730 H GLU A 45 34.500 25.306 25.287 1.00 0.00 H ATOM 731 HA GLU A 45 32.871 23.128 25.857 1.00 0.00 H ATOM 732 HB2 GLU A 45 33.460 22.467 23.558 1.00 0.00 H ATOM 733 HB3 GLU A 45 34.444 23.769 23.517 1.00 0.00 H ATOM 734 HG2 GLU A 45 32.461 24.397 22.485 1.00 0.00 H ATOM 735 HG3 GLU A 45 32.503 25.161 23.927 1.00 0.00 H ATOM 736 N LEU A 46 36.018 22.529 25.574 1.00 0.00 N ATOM 737 CA LEU A 46 37.036 21.550 25.864 1.00 0.00 C ATOM 738 C LEU A 46 36.981 21.055 27.318 1.00 0.00 C ATOM 739 O LEU A 46 37.055 19.863 27.615 1.00 0.00 O ATOM 740 CB LEU A 46 38.451 22.068 25.538 1.00 0.00 C ATOM 741 CG LEU A 46 39.517 20.991 25.786 1.00 0.00 C ATOM 742 CD1 LEU A 46 39.161 19.712 25.014 1.00 0.00 C ATOM 743 CD2 LEU A 46 40.906 21.484 25.371 1.00 0.00 C ATOM 744 H LEU A 46 36.276 23.437 25.244 1.00 0.00 H ATOM 745 HA LEU A 46 36.865 20.760 25.275 1.00 0.00 H ATOM 746 HB2 LEU A 46 38.648 22.859 26.116 1.00 0.00 H ATOM 747 HB3 LEU A 46 38.483 22.341 24.577 1.00 0.00 H ATOM 748 HG LEU A 46 39.534 20.779 26.763 1.00 0.00 H ATOM 749 HD11 LEU A 46 39.860 19.016 25.181 1.00 0.00 H ATOM 750 HD12 LEU A 46 38.272 19.373 25.323 1.00 0.00 H ATOM 751 HD13 LEU A 46 39.119 19.914 24.036 1.00 0.00 H ATOM 752 HD21 LEU A 46 41.580 20.765 25.543 1.00 0.00 H ATOM 753 HD22 LEU A 46 40.902 21.711 24.397 1.00 0.00 H ATOM 754 HD23 LEU A 46 41.144 22.297 25.902 1.00 0.00 H ATOM 755 N ASP A 47 36.861 21.973 28.258 1.00 0.00 N ATOM 756 CA ASP A 47 36.819 21.608 29.667 1.00 0.00 C ATOM 757 C ASP A 47 35.600 20.821 30.014 1.00 0.00 C ATOM 758 O ASP A 47 35.657 19.924 30.858 1.00 0.00 O ATOM 759 CB ASP A 47 36.926 22.822 30.591 1.00 0.00 C ATOM 760 CG ASP A 47 38.251 23.546 30.538 1.00 0.00 C ATOM 761 OD1 ASP A 47 39.359 23.052 30.230 1.00 0.00 O ATOM 762 OD2 ASP A 47 38.097 24.782 30.905 1.00 0.00 O1- ATOM 763 H ASP A 47 36.798 22.937 27.998 1.00 0.00 H ATOM 764 HA ASP A 47 37.611 21.025 29.848 1.00 0.00 H ATOM 765 HB2 ASP A 47 36.779 22.512 31.530 1.00 0.00 H ATOM 766 HB3 ASP A 47 36.208 23.470 30.338 1.00 0.00 H ATOM 767 N LYS A 48 34.517 21.222 29.376 1.00 0.00 N ATOM 768 CA LYS A 48 33.249 20.552 29.520 1.00 0.00 C ATOM 769 C LYS A 48 33.356 19.110 28.969 1.00 0.00 C ATOM 770 O LYS A 48 32.906 18.166 29.573 1.00 0.00 O ATOM 771 CB LYS A 48 32.220 21.367 28.758 1.00 0.00 C ATOM 772 CG LYS A 48 30.913 20.647 28.555 1.00 0.00 C ATOM 773 CD LYS A 48 29.749 21.599 28.365 1.00 0.00 C ATOM 774 CE LYS A 48 29.717 22.317 27.017 1.00 0.00 C ATOM 775 NZ LYS A 48 29.282 21.456 25.920 1.00 0.00 N1+ ATOM 776 H LYS A 48 34.578 22.017 28.773 1.00 0.00 H ATOM 777 HA LYS A 48 32.998 20.520 30.487 1.00 0.00 H ATOM 778 HB2 LYS A 48 32.598 21.595 27.861 1.00 0.00 H ATOM 779 HB3 LYS A 48 32.042 22.208 29.268 1.00 0.00 H ATOM 780 HG2 LYS A 48 30.733 20.077 29.357 1.00 0.00 H ATOM 781 HG3 LYS A 48 30.989 20.067 27.744 1.00 0.00 H ATOM 782 HD2 LYS A 48 29.794 22.292 29.085 1.00 0.00 H ATOM 783 HD3 LYS A 48 28.902 21.076 28.458 1.00 0.00 H ATOM 784 HE2 LYS A 48 30.637 22.652 26.813 1.00 0.00 H ATOM 785 HE3 LYS A 48 29.087 23.091 27.083 1.00 0.00 H ATOM 786 HZ1 LYS A 48 28.288 21.513 25.826 1.00 0.00 H ATOM 787 HZ2 LYS A 48 29.715 21.755 25.070 1.00 0.00 H ATOM 788 HZ3 LYS A 48 29.545 20.511 26.114 1.00 0.00 H ATOM 789 N ALA A 49 34.021 18.934 27.842 1.00 0.00 N ATOM 790 CA ALA A 49 34.185 17.611 27.280 1.00 0.00 C ATOM 791 C ALA A 49 35.084 16.672 28.119 1.00 0.00 C ATOM 792 O ALA A 49 34.792 15.495 28.269 1.00 0.00 O ATOM 793 CB ALA A 49 34.617 17.695 25.816 1.00 0.00 C ATOM 794 H ALA A 49 34.415 19.724 27.372 1.00 0.00 H ATOM 795 HA ALA A 49 33.275 17.196 27.278 1.00 0.00 H ATOM 796 HB1 ALA A 49 34.725 16.772 25.447 1.00 0.00 H ATOM 797 HB2 ALA A 49 33.921 18.185 25.291 1.00 0.00 H ATOM 798 HB3 ALA A 49 35.488 18.183 25.753 1.00 0.00 H ATOM 799 N ILE A 50 36.187 17.188 28.678 1.00 0.00 N ATOM 800 CA ILE A 50 37.166 16.428 29.480 1.00 0.00 C ATOM 801 C ILE A 50 36.823 16.297 30.961 1.00 0.00 C ATOM 802 O ILE A 50 37.251 15.383 31.677 1.00 0.00 O ATOM 803 CB ILE A 50 38.524 17.125 29.371 1.00 0.00 C ATOM 804 CG1 ILE A 50 38.894 17.231 27.907 1.00 0.00 C ATOM 805 CG2 ILE A 50 39.657 16.415 30.144 1.00 0.00 C ATOM 806 CD1 ILE A 50 38.734 15.901 27.193 1.00 0.00 C ATOM 807 H ILE A 50 36.360 18.163 28.541 1.00 0.00 H ATOM 808 HA ILE A 50 37.249 15.510 29.092 1.00 0.00 H ATOM 809 HB ILE A 50 38.430 18.051 29.737 1.00 0.00 H ATOM 810 HG12 ILE A 50 39.847 17.526 27.833 1.00 0.00 H ATOM 811 HG13 ILE A 50 38.301 17.907 27.470 1.00 0.00 H ATOM 812 HG21 ILE A 50 40.510 16.924 30.028 1.00 0.00 H ATOM 813 HG22 ILE A 50 39.423 16.374 31.115 1.00 0.00 H ATOM 814 HG23 ILE A 50 39.772 15.487 29.789 1.00 0.00 H ATOM 815 HD11 ILE A 50 38.986 16.007 26.231 1.00 0.00 H ATOM 816 HD12 ILE A 50 39.328 15.220 27.620 1.00 0.00 H ATOM 817 HD13 ILE A 50 37.782 15.601 27.257 1.00 0.00 H ATOM 818 N GLY A 51 36.112 17.276 31.452 1.00 0.00 N ATOM 819 CA GLY A 51 35.726 17.183 32.843 1.00 0.00 C ATOM 820 C GLY A 51 36.804 17.762 33.737 1.00 0.00 C ATOM 821 O GLY A 51 36.950 17.412 34.897 1.00 0.00 O ATOM 822 H GLY A 51 35.845 18.058 30.889 1.00 0.00 H ATOM 823 HA2 GLY A 51 35.583 16.222 33.081 1.00 0.00 H ATOM 824 HA3 GLY A 51 34.876 17.691 32.983 1.00 0.00 H ATOM 825 N ARG A 52 37.572 18.696 33.205 1.00 0.00 N ATOM 826 CA ARG A 52 38.575 19.327 34.025 1.00 0.00 C ATOM 827 C ARG A 52 39.012 20.601 33.366 1.00 0.00 C ATOM 828 O ARG A 52 38.645 20.860 32.224 1.00 0.00 O ATOM 829 CB ARG A 52 39.757 18.413 34.330 1.00 0.00 C ATOM 830 CG ARG A 52 40.768 18.362 33.222 1.00 0.00 C ATOM 831 CD ARG A 52 41.697 17.184 33.392 1.00 0.00 C ATOM 832 NE ARG A 52 42.597 17.029 32.286 1.00 0.00 N ATOM 833 CZ ARG A 52 43.419 17.972 31.899 1.00 0.00 C ATOM 834 NH1 ARG A 52 43.470 19.140 32.518 1.00 0.00 N1+ ATOM 835 NH2 ARG A 52 44.233 17.726 30.875 1.00 0.00 N ATOM 836 H ARG A 52 37.459 18.961 32.247 1.00 0.00 H ATOM 837 HA ARG A 52 38.146 19.568 34.896 1.00 0.00 H ATOM 838 HB2 ARG A 52 39.411 17.488 34.487 1.00 0.00 H ATOM 839 HB3 ARG A 52 40.210 18.745 35.158 1.00 0.00 H ATOM 840 HG2 ARG A 52 41.305 19.206 33.230 1.00 0.00 H ATOM 841 HG3 ARG A 52 40.291 18.279 32.347 1.00 0.00 H ATOM 842 HD2 ARG A 52 41.148 16.353 33.477 1.00 0.00 H ATOM 843 HD3 ARG A 52 42.233 17.316 34.226 1.00 0.00 H ATOM 844 HE ARG A 52 42.597 16.162 31.788 1.00 0.00 H ATOM 845 HH11 ARG A 52 44.106 19.845 32.204 1.00 0.00 H ATOM 846 HH12 ARG A 52 42.872 19.318 33.300 1.00 0.00 H ATOM 847 HH21 ARG A 52 44.869 18.431 30.562 1.00 0.00 H ATOM 848 HH22 ARG A 52 44.208 16.836 30.419 1.00 0.00 H ATOM 849 N ASN A 53 39.775 21.390 34.113 1.00 0.00 N ATOM 850 CA ASN A 53 40.307 22.645 33.635 1.00 0.00 C ATOM 851 C ASN A 53 41.545 22.324 32.816 1.00 0.00 C ATOM 852 O ASN A 53 42.573 21.935 33.353 1.00 0.00 O ATOM 853 CB ASN A 53 40.599 23.577 34.821 1.00 0.00 C ATOM 854 CG ASN A 53 39.794 24.842 34.684 1.00 0.00 C ATOM 855 ND2 ASN A 53 40.385 25.824 33.982 1.00 0.00 N ATOM 856 OD1 ASN A 53 38.635 24.910 35.129 1.00 0.00 O ATOM 857 H ASN A 53 39.991 21.103 35.046 1.00 0.00 H ATOM 858 HA ASN A 53 39.629 23.079 33.041 1.00 0.00 H ATOM 859 HB2 ASN A 53 41.573 23.803 34.834 1.00 0.00 H ATOM 860 HB3 ASN A 53 40.352 23.117 35.674 1.00 0.00 H ATOM 861 HD21 ASN A 53 41.321 25.708 33.651 1.00 0.00 H ATOM 862 HD22 ASN A 53 39.888 26.671 33.791 1.00 0.00 H ATOM 863 N THR A 54 41.458 22.410 31.496 1.00 0.00 N ATOM 864 CA THR A 54 42.603 21.947 30.723 1.00 0.00 C ATOM 865 C THR A 54 43.513 23.006 30.188 1.00 0.00 C ATOM 866 O THR A 54 44.547 22.670 29.631 1.00 0.00 O ATOM 867 CB THR A 54 42.138 21.173 29.497 1.00 0.00 C ATOM 868 CG2 THR A 54 41.219 20.020 29.908 1.00 0.00 C ATOM 869 OG1 THR A 54 41.480 22.098 28.677 1.00 0.00 O ATOM 870 H THR A 54 40.642 22.777 31.050 1.00 0.00 H ATOM 871 HA THR A 54 43.142 21.331 31.298 1.00 0.00 H ATOM 872 HB THR A 54 42.933 20.808 29.014 1.00 0.00 H ATOM 873 HG1 THR A 54 40.509 22.122 28.914 1.00 0.00 H ATOM 874 HG21 THR A 54 40.923 19.523 29.092 1.00 0.00 H ATOM 875 HG22 THR A 54 41.714 19.399 30.516 1.00 0.00 H ATOM 876 HG23 THR A 54 40.419 20.385 30.385 1.00 0.00 H ATOM 877 N ASN A 55 43.121 24.268 30.259 1.00 0.00 N ATOM 878 CA ASN A 55 43.967 25.280 29.665 1.00 0.00 C ATOM 879 C ASN A 55 44.281 25.044 28.171 1.00 0.00 C ATOM 880 O ASN A 55 45.285 25.528 27.671 1.00 0.00 O ATOM 881 CB ASN A 55 45.231 25.605 30.501 1.00 0.00 C ATOM 882 CG ASN A 55 45.745 27.027 30.277 1.00 0.00 C ATOM 883 ND2 ASN A 55 47.051 27.208 30.471 1.00 0.00 N ATOM 884 OD1 ASN A 55 44.994 27.949 29.910 1.00 0.00 O ATOM 885 H ASN A 55 42.264 24.515 30.711 1.00 0.00 H ATOM 886 HA ASN A 55 43.421 26.118 29.685 1.00 0.00 H ATOM 887 HB2 ASN A 55 45.954 24.961 30.249 1.00 0.00 H ATOM 888 HB3 ASN A 55 45.009 25.495 31.470 1.00 0.00 H ATOM 889 HD21 ASN A 55 47.623 26.443 30.766 1.00 0.00 H ATOM 890 HD22 ASN A 55 47.459 28.109 30.321 1.00 0.00 H ATOM 891 N GLY A 56 43.422 24.320 27.445 1.00 0.00 N ATOM 892 CA GLY A 56 43.640 24.118 26.006 1.00 0.00 C ATOM 893 C GLY A 56 44.567 22.973 25.623 1.00 0.00 C ATOM 894 O GLY A 56 44.943 22.790 24.462 1.00 0.00 O ATOM 895 H GLY A 56 42.623 23.912 27.886 1.00 0.00 H ATOM 896 HA2 GLY A 56 44.027 24.962 25.634 1.00 0.00 H ATOM 897 HA3 GLY A 56 42.750 23.945 25.584 1.00 0.00 H ATOM 898 N VAL A 57 44.913 22.179 26.604 1.00 0.00 N ATOM 899 CA VAL A 57 45.782 21.053 26.337 1.00 0.00 C ATOM 900 C VAL A 57 45.317 19.754 27.016 1.00 0.00 C ATOM 901 O VAL A 57 44.950 19.795 28.179 1.00 0.00 O ATOM 902 CB VAL A 57 47.107 21.435 26.889 1.00 0.00 C ATOM 903 CG1 VAL A 57 48.133 20.335 26.617 1.00 0.00 C ATOM 904 CG2 VAL A 57 47.516 22.756 26.247 1.00 0.00 C ATOM 905 H VAL A 57 44.579 22.349 27.531 1.00 0.00 H ATOM 906 HA VAL A 57 45.856 20.910 25.350 1.00 0.00 H ATOM 907 HB VAL A 57 47.023 21.565 27.877 1.00 0.00 H ATOM 908 HG11 VAL A 57 49.019 20.605 26.994 1.00 0.00 H ATOM 909 HG12 VAL A 57 47.833 19.485 27.049 1.00 0.00 H ATOM 910 HG13 VAL A 57 48.219 20.196 25.630 1.00 0.00 H ATOM 911 HG21 VAL A 57 48.408 23.037 26.602 1.00 0.00 H ATOM 912 HG22 VAL A 57 47.573 22.641 25.255 1.00 0.00 H ATOM 913 HG23 VAL A 57 46.835 23.456 26.463 1.00 0.00 H ATOM 914 N ILE A 58 45.378 18.623 26.314 1.00 0.00 N ATOM 915 CA ILE A 58 44.929 17.345 26.879 1.00 0.00 C ATOM 916 C ILE A 58 46.022 16.310 26.697 1.00 0.00 C ATOM 917 O ILE A 58 47.003 16.531 25.975 1.00 0.00 O ATOM 918 CB ILE A 58 43.665 16.858 26.159 1.00 0.00 C ATOM 919 CG1 ILE A 58 43.971 16.657 24.676 1.00 0.00 C ATOM 920 CG2 ILE A 58 42.521 17.874 26.309 1.00 0.00 C ATOM 921 CD1 ILE A 58 42.859 15.900 23.936 1.00 0.00 C ATOM 922 H ILE A 58 45.738 18.646 25.381 1.00 0.00 H ATOM 923 HA ILE A 58 44.736 17.460 27.853 1.00 0.00 H ATOM 924 HB ILE A 58 43.380 15.985 26.555 1.00 0.00 H ATOM 925 HG12 ILE A 58 44.821 16.137 24.593 1.00 0.00 H ATOM 926 HG13 ILE A 58 44.086 17.554 24.249 1.00 0.00 H ATOM 927 HG21 ILE A 58 41.710 17.535 25.832 1.00 0.00 H ATOM 928 HG22 ILE A 58 42.310 17.998 27.279 1.00 0.00 H ATOM 929 HG23 ILE A 58 42.799 18.749 25.913 1.00 0.00 H ATOM 930 HD11 ILE A 58 43.110 15.797 22.973 1.00 0.00 H ATOM 931 HD12 ILE A 58 42.739 14.997 24.348 1.00 0.00 H ATOM 932 HD13 ILE A 58 42.004 16.414 24.004 1.00 0.00 H ATOM 933 N THR A 59 45.879 15.176 27.340 1.00 0.00 N ATOM 934 CA THR A 59 46.854 14.133 27.174 1.00 0.00 C ATOM 935 C THR A 59 46.371 13.210 26.062 1.00 0.00 C ATOM 936 O THR A 59 45.215 13.244 25.690 1.00 0.00 O ATOM 937 CB THR A 59 46.889 13.283 28.452 1.00 0.00 C ATOM 938 CG2 THR A 59 47.054 14.138 29.685 1.00 0.00 C ATOM 939 OG1 THR A 59 45.657 12.617 28.518 1.00 0.00 O ATOM 940 H THR A 59 45.094 15.037 27.944 1.00 0.00 H ATOM 941 HA THR A 59 47.756 14.510 26.965 1.00 0.00 H ATOM 942 HB THR A 59 47.633 12.617 28.398 1.00 0.00 H ATOM 943 HG1 THR A 59 45.001 13.179 29.022 1.00 0.00 H ATOM 944 HG21 THR A 59 47.073 13.553 30.496 1.00 0.00 H ATOM 945 HG22 THR A 59 47.911 14.650 29.623 1.00 0.00 H ATOM 946 HG23 THR A 59 46.288 14.777 29.752 1.00 0.00 H ATOM 947 N LYS A 60 47.268 12.336 25.616 1.00 0.00 N ATOM 948 CA LYS A 60 46.997 11.329 24.613 1.00 0.00 C ATOM 949 C LYS A 60 45.808 10.442 24.982 1.00 0.00 C ATOM 950 O LYS A 60 44.963 10.148 24.146 1.00 0.00 O ATOM 951 CB LYS A 60 48.250 10.465 24.416 1.00 0.00 C ATOM 952 CG LYS A 60 48.158 9.440 23.270 1.00 0.00 C ATOM 953 CD LYS A 60 49.323 9.516 22.301 1.00 0.00 C ATOM 954 CE LYS A 60 49.466 8.302 21.372 1.00 0.00 C ATOM 955 NZ LYS A 60 50.318 8.537 20.191 1.00 0.00 N1+ ATOM 956 H LYS A 60 48.191 12.377 25.999 1.00 0.00 H ATOM 957 HA LYS A 60 46.792 11.790 23.750 1.00 0.00 H ATOM 958 HB2 LYS A 60 48.420 9.966 25.266 1.00 0.00 H ATOM 959 HB3 LYS A 60 49.020 11.074 24.227 1.00 0.00 H ATOM 960 HG2 LYS A 60 47.312 9.606 22.763 1.00 0.00 H ATOM 961 HG3 LYS A 60 48.134 8.522 23.666 1.00 0.00 H ATOM 962 HD2 LYS A 60 50.165 9.602 22.833 1.00 0.00 H ATOM 963 HD3 LYS A 60 49.203 10.330 21.733 1.00 0.00 H ATOM 964 HE2 LYS A 60 48.554 8.042 21.054 1.00 0.00 H ATOM 965 HE3 LYS A 60 49.862 7.550 21.899 1.00 0.00 H ATOM 966 HZ1 LYS A 60 50.360 7.704 19.640 1.00 0.00 H ATOM 967 HZ2 LYS A 60 49.932 9.280 19.644 1.00 0.00 H ATOM 968 HZ3 LYS A 60 51.239 8.787 20.489 1.00 0.00 H ATOM 969 N ASP A 61 45.757 9.997 26.252 1.00 0.00 N ATOM 970 CA ASP A 61 44.645 9.157 26.706 1.00 0.00 C ATOM 971 C ASP A 61 43.295 9.857 26.540 1.00 0.00 C ATOM 972 O ASP A 61 42.304 9.250 26.128 1.00 0.00 O ATOM 973 CB ASP A 61 44.812 8.758 28.186 1.00 0.00 C ATOM 974 CG ASP A 61 45.950 7.832 28.509 1.00 0.00 C ATOM 975 OD1 ASP A 61 46.514 7.293 27.457 1.00 0.00 O ATOM 976 OD2 ASP A 61 46.322 7.621 29.650 1.00 0.00 O1- ATOM 977 H ASP A 61 46.485 10.242 26.892 1.00 0.00 H ATOM 978 HA ASP A 61 44.636 8.323 26.155 1.00 0.00 H ATOM 979 HB2 ASP A 61 43.966 8.312 28.477 1.00 0.00 H ATOM 980 HB3 ASP A 61 44.945 9.597 28.713 1.00 0.00 H ATOM 981 N GLU A 62 43.290 11.151 26.933 1.00 0.00 N ATOM 982 CA GLU A 62 42.108 12.003 26.835 1.00 0.00 C ATOM 983 C GLU A 62 41.696 12.122 25.392 1.00 0.00 C ATOM 984 O GLU A 62 40.546 12.045 25.046 1.00 0.00 O ATOM 985 CB GLU A 62 42.424 13.367 27.387 1.00 0.00 C ATOM 986 CG GLU A 62 42.394 13.311 28.914 1.00 0.00 C ATOM 987 CD GLU A 62 42.842 14.606 29.568 1.00 0.00 C ATOM 988 OE1 GLU A 62 43.549 15.434 29.026 1.00 0.00 O ATOM 989 OE2 GLU A 62 42.429 14.715 30.798 1.00 0.00 O1- ATOM 990 H GLU A 62 44.132 11.541 27.307 1.00 0.00 H ATOM 991 HA GLU A 62 41.361 11.597 27.361 1.00 0.00 H ATOM 992 HB2 GLU A 62 41.744 14.025 27.063 1.00 0.00 H ATOM 993 HB3 GLU A 62 43.333 13.649 27.081 1.00 0.00 H ATOM 994 HG2 GLU A 62 43.000 12.575 29.217 1.00 0.00 H ATOM 995 HG3 GLU A 62 41.458 13.114 29.207 1.00 0.00 H ATOM 996 N ALA A 63 42.722 12.253 24.535 1.00 0.00 N ATOM 997 CA ALA A 63 42.472 12.330 23.116 1.00 0.00 C ATOM 998 C ALA A 63 41.800 11.058 22.596 1.00 0.00 C ATOM 999 O ALA A 63 40.819 11.101 21.825 1.00 0.00 O ATOM 1000 CB ALA A 63 43.777 12.593 22.398 1.00 0.00 C ATOM 1001 H ALA A 63 43.659 12.297 24.881 1.00 0.00 H ATOM 1002 HA ALA A 63 41.859 13.101 22.946 1.00 0.00 H ATOM 1003 HB1 ALA A 63 43.611 12.648 21.413 1.00 0.00 H ATOM 1004 HB2 ALA A 63 44.166 13.457 22.719 1.00 0.00 H ATOM 1005 HB3 ALA A 63 44.417 11.849 22.587 1.00 0.00 H ATOM 1006 N GLU A 64 42.357 9.916 23.032 1.00 0.00 N ATOM 1007 CA GLU A 64 41.816 8.649 22.623 1.00 0.00 C ATOM 1008 C GLU A 64 40.449 8.412 23.123 1.00 0.00 C ATOM 1009 O GLU A 64 39.634 7.772 22.449 1.00 0.00 O ATOM 1010 CB GLU A 64 42.756 7.515 22.965 1.00 0.00 C ATOM 1011 CG GLU A 64 43.843 7.541 21.887 1.00 0.00 C ATOM 1012 CD GLU A 64 45.125 6.857 22.263 1.00 0.00 C ATOM 1013 OE1 GLU A 64 45.287 6.316 23.332 1.00 0.00 O ATOM 1014 OE2 GLU A 64 46.009 6.905 21.307 1.00 0.00 O1- ATOM 1015 H GLU A 64 43.149 9.948 23.642 1.00 0.00 H ATOM 1016 HA GLU A 64 41.753 8.675 21.625 1.00 0.00 H ATOM 1017 HB2 GLU A 64 42.269 6.642 22.949 1.00 0.00 H ATOM 1018 HB3 GLU A 64 43.158 7.656 23.870 1.00 0.00 H ATOM 1019 HG2 GLU A 64 44.051 8.497 21.679 1.00 0.00 H ATOM 1020 HG3 GLU A 64 43.480 7.093 21.070 1.00 0.00 H ATOM 1021 N LYS A 65 40.230 8.925 24.310 1.00 0.00 N ATOM 1022 CA LYS A 65 38.906 8.767 24.863 1.00 0.00 C ATOM 1023 C LYS A 65 37.874 9.503 24.035 1.00 0.00 C ATOM 1024 O LYS A 65 36.835 8.941 23.666 1.00 0.00 O ATOM 1025 CB LYS A 65 38.840 9.153 26.296 1.00 0.00 C ATOM 1026 CG LYS A 65 37.478 8.774 26.841 1.00 0.00 C ATOM 1027 CD LYS A 65 37.386 8.862 28.327 1.00 0.00 C ATOM 1028 CE LYS A 65 35.950 8.577 28.767 1.00 0.00 C ATOM 1029 NZ LYS A 65 35.883 8.324 30.208 1.00 0.00 N1+ ATOM 1030 H LYS A 65 40.950 9.405 24.811 1.00 0.00 H ATOM 1031 HA LYS A 65 38.682 7.794 24.812 1.00 0.00 H ATOM 1032 HB2 LYS A 65 38.975 10.140 26.385 1.00 0.00 H ATOM 1033 HB3 LYS A 65 39.552 8.672 26.807 1.00 0.00 H ATOM 1034 HG2 LYS A 65 37.278 7.833 26.567 1.00 0.00 H ATOM 1035 HG3 LYS A 65 36.796 9.389 26.445 1.00 0.00 H ATOM 1036 HD2 LYS A 65 37.649 9.780 28.623 1.00 0.00 H ATOM 1037 HD3 LYS A 65 38.001 8.189 28.739 1.00 0.00 H ATOM 1038 HE2 LYS A 65 35.612 7.773 28.278 1.00 0.00 H ATOM 1039 HE3 LYS A 65 35.378 9.367 28.547 1.00 0.00 H ATOM 1040 HZ1 LYS A 65 34.936 8.141 30.471 1.00 0.00 H ATOM 1041 HZ2 LYS A 65 36.451 7.532 30.434 1.00 0.00 H ATOM 1042 HZ3 LYS A 65 36.217 9.126 30.703 1.00 0.00 H ATOM 1043 N LEU A 66 38.183 10.776 23.687 1.00 0.00 N ATOM 1044 CA LEU A 66 37.285 11.549 22.842 1.00 0.00 C ATOM 1045 C LEU A 66 37.046 10.806 21.525 1.00 0.00 C ATOM 1046 O LEU A 66 35.921 10.670 21.057 1.00 0.00 O ATOM 1047 CB LEU A 66 37.779 12.999 22.499 1.00 0.00 C ATOM 1048 CG LEU A 66 37.863 13.950 23.689 1.00 0.00 C ATOM 1049 CD1 LEU A 66 38.517 15.274 23.269 1.00 0.00 C ATOM 1050 CD2 LEU A 66 36.479 14.213 24.266 1.00 0.00 C ATOM 1051 H LEU A 66 39.034 11.187 24.013 1.00 0.00 H ATOM 1052 HA LEU A 66 36.408 11.627 23.315 1.00 0.00 H ATOM 1053 HB2 LEU A 66 37.147 13.392 21.832 1.00 0.00 H ATOM 1054 HB3 LEU A 66 38.690 12.928 22.093 1.00 0.00 H ATOM 1055 HG LEU A 66 38.428 13.526 24.397 1.00 0.00 H ATOM 1056 HD11 LEU A 66 38.565 15.887 24.058 1.00 0.00 H ATOM 1057 HD12 LEU A 66 39.440 15.096 22.928 1.00 0.00 H ATOM 1058 HD13 LEU A 66 37.972 15.701 22.548 1.00 0.00 H ATOM 1059 HD21 LEU A 66 36.555 14.837 25.043 1.00 0.00 H ATOM 1060 HD22 LEU A 66 35.898 14.624 23.564 1.00 0.00 H ATOM 1061 HD23 LEU A 66 36.075 13.350 24.570 1.00 0.00 H ATOM 1062 N PHE A 67 38.148 10.304 20.974 1.00 0.00 N ATOM 1063 CA PHE A 67 38.106 9.567 19.732 1.00 0.00 C ATOM 1064 C PHE A 67 37.169 8.373 19.809 1.00 0.00 C ATOM 1065 O PHE A 67 36.345 8.205 18.924 1.00 0.00 O ATOM 1066 CB PHE A 67 39.516 9.144 19.348 1.00 0.00 C ATOM 1067 CG PHE A 67 39.687 8.521 17.982 1.00 0.00 C ATOM 1068 CD1 PHE A 67 38.952 8.989 16.899 1.00 0.00 C ATOM 1069 CD2 PHE A 67 40.637 7.512 17.788 1.00 0.00 C ATOM 1070 CE1 PHE A 67 39.120 8.467 15.620 1.00 0.00 C ATOM 1071 CE2 PHE A 67 40.846 6.999 16.512 1.00 0.00 C ATOM 1072 CZ PHE A 67 40.066 7.462 15.444 1.00 0.00 C ATOM 1073 H PHE A 67 39.027 10.440 21.431 1.00 0.00 H ATOM 1074 HA PHE A 67 37.764 10.181 19.021 1.00 0.00 H ATOM 1075 HB2 PHE A 67 39.828 8.479 20.026 1.00 0.00 H ATOM 1076 HB3 PHE A 67 40.097 9.957 19.386 1.00 0.00 H ATOM 1077 HD1 PHE A 67 38.285 9.720 17.043 1.00 0.00 H ATOM 1078 HD2 PHE A 67 41.163 7.161 18.563 1.00 0.00 H ATOM 1079 HE1 PHE A 67 38.577 8.804 14.851 1.00 0.00 H ATOM 1080 HE2 PHE A 67 41.548 6.304 16.358 1.00 0.00 H ATOM 1081 HZ PHE A 67 40.192 7.062 14.536 1.00 0.00 H ATOM 1082 N ASN A 68 37.296 7.555 20.876 1.00 0.00 N ATOM 1083 CA ASN A 68 36.410 6.396 21.037 1.00 0.00 C ATOM 1084 C ASN A 68 34.940 6.809 21.075 1.00 0.00 C ATOM 1085 O ASN A 68 34.054 6.196 20.495 1.00 0.00 O ATOM 1086 CB ASN A 68 36.756 5.640 22.329 1.00 0.00 C ATOM 1087 CG ASN A 68 37.952 4.726 22.174 1.00 0.00 C ATOM 1088 ND2 ASN A 68 38.848 4.727 23.160 1.00 0.00 N ATOM 1089 OD1 ASN A 68 38.097 4.038 21.176 1.00 0.00 O ATOM 1090 H ASN A 68 38.000 7.740 21.562 1.00 0.00 H ATOM 1091 HA ASN A 68 36.548 5.780 20.261 1.00 0.00 H ATOM 1092 HB2 ASN A 68 35.966 5.089 22.598 1.00 0.00 H ATOM 1093 HB3 ASN A 68 36.956 6.308 23.046 1.00 0.00 H ATOM 1094 HD21 ASN A 68 38.704 5.301 23.966 1.00 0.00 H ATOM 1095 HD22 ASN A 68 39.665 4.154 23.094 1.00 0.00 H ATOM 1096 N GLN A 69 34.691 7.876 21.798 1.00 0.00 N ATOM 1097 CA GLN A 69 33.329 8.359 21.869 1.00 0.00 C ATOM 1098 C GLN A 69 32.817 8.820 20.517 1.00 0.00 C ATOM 1099 O GLN A 69 31.678 8.576 20.163 1.00 0.00 O ATOM 1100 CB GLN A 69 33.245 9.544 22.832 1.00 0.00 C ATOM 1101 CG GLN A 69 33.502 9.100 24.269 1.00 0.00 C ATOM 1102 CD GLN A 69 33.592 10.287 25.226 1.00 0.00 C ATOM 1103 NE2 GLN A 69 33.476 11.520 24.721 1.00 0.00 N ATOM 1104 OE1 GLN A 69 33.800 10.099 26.422 1.00 0.00 O ATOM 1105 H GLN A 69 35.426 8.344 22.289 1.00 0.00 H ATOM 1106 HA GLN A 69 32.741 7.624 22.206 1.00 0.00 H ATOM 1107 HB2 GLN A 69 32.333 9.949 22.773 1.00 0.00 H ATOM 1108 HB3 GLN A 69 33.930 10.225 22.573 1.00 0.00 H ATOM 1109 HG2 GLN A 69 34.363 8.593 24.301 1.00 0.00 H ATOM 1110 HG3 GLN A 69 32.754 8.505 24.562 1.00 0.00 H ATOM 1111 HE21 GLN A 69 33.307 11.646 23.744 1.00 0.00 H ATOM 1112 HE22 GLN A 69 33.559 12.316 25.321 1.00 0.00 H ATOM 1113 N ASP A 70 33.657 9.538 19.764 1.00 0.00 N ATOM 1114 CA ASP A 70 33.229 10.056 18.473 1.00 0.00 C ATOM 1115 C ASP A 70 32.962 9.001 17.424 1.00 0.00 C ATOM 1116 O ASP A 70 32.086 9.172 16.590 1.00 0.00 O ATOM 1117 CB ASP A 70 34.173 11.126 17.918 1.00 0.00 C ATOM 1118 CG ASP A 70 34.193 12.370 18.775 1.00 0.00 C ATOM 1119 OD1 ASP A 70 33.326 12.709 19.561 1.00 0.00 O ATOM 1120 OD2 ASP A 70 35.280 13.049 18.595 1.00 0.00 O1- ATOM 1121 H ASP A 70 34.585 9.720 20.090 1.00 0.00 H ATOM 1122 HA ASP A 70 32.355 10.514 18.634 1.00 0.00 H ATOM 1123 HB2 ASP A 70 33.872 11.374 16.997 1.00 0.00 H ATOM 1124 HB3 ASP A 70 35.098 10.749 17.876 1.00 0.00 H ATOM 1125 N VAL A 71 33.736 7.915 17.452 1.00 0.00 N ATOM 1126 CA VAL A 71 33.519 6.851 16.474 1.00 0.00 C ATOM 1127 C VAL A 71 32.201 6.191 16.787 1.00 0.00 C ATOM 1128 O VAL A 71 31.346 6.023 15.931 1.00 0.00 O ATOM 1129 CB VAL A 71 34.656 5.835 16.407 1.00 0.00 C ATOM 1130 CG1 VAL A 71 34.233 4.621 15.555 1.00 0.00 C ATOM 1131 CG2 VAL A 71 35.915 6.446 15.808 1.00 0.00 C ATOM 1132 H VAL A 71 34.459 7.830 18.137 1.00 0.00 H ATOM 1133 HA VAL A 71 33.439 7.278 15.573 1.00 0.00 H ATOM 1134 HB VAL A 71 34.861 5.521 17.334 1.00 0.00 H ATOM 1135 HG11 VAL A 71 34.984 3.962 15.518 1.00 0.00 H ATOM 1136 HG12 VAL A 71 33.431 4.189 15.966 1.00 0.00 H ATOM 1137 HG13 VAL A 71 34.010 4.925 14.629 1.00 0.00 H ATOM 1138 HG21 VAL A 71 36.639 5.756 15.778 1.00 0.00 H ATOM 1139 HG22 VAL A 71 35.721 6.766 14.881 1.00 0.00 H ATOM 1140 HG23 VAL A 71 36.212 7.217 16.372 1.00 0.00 H ATOM 1141 N ASP A 72 32.023 5.893 18.066 1.00 0.00 N ATOM 1142 CA ASP A 72 30.773 5.310 18.553 1.00 0.00 C ATOM 1143 C ASP A 72 29.529 6.126 18.147 1.00 0.00 C ATOM 1144 O ASP A 72 28.552 5.653 17.567 1.00 0.00 O ATOM 1145 CB ASP A 72 30.887 5.194 20.076 1.00 0.00 C ATOM 1146 CG ASP A 72 29.903 4.193 20.586 1.00 0.00 C ATOM 1147 OD1 ASP A 72 29.802 3.163 19.802 1.00 0.00 O ATOM 1148 OD2 ASP A 72 29.271 4.333 21.579 1.00 0.00 O1- ATOM 1149 H ASP A 72 32.763 6.071 18.715 1.00 0.00 H ATOM 1150 HA ASP A 72 30.685 4.390 18.172 1.00 0.00 H ATOM 1151 HB2 ASP A 72 30.699 6.084 20.491 1.00 0.00 H ATOM 1152 HB3 ASP A 72 31.812 4.902 20.318 1.00 0.00 H ATOM 1153 N ALA A 73 29.595 7.405 18.438 1.00 0.00 N ATOM 1154 CA ALA A 73 28.513 8.306 18.102 1.00 0.00 C ATOM 1155 C ALA A 73 28.276 8.293 16.615 1.00 0.00 C ATOM 1156 O ALA A 73 27.140 8.356 16.147 1.00 0.00 O ATOM 1157 CB ALA A 73 28.856 9.722 18.535 1.00 0.00 C ATOM 1158 H ALA A 73 30.407 7.763 18.900 1.00 0.00 H ATOM 1159 HA ALA A 73 27.681 8.011 18.571 1.00 0.00 H ATOM 1160 HB1 ALA A 73 28.102 10.335 18.298 1.00 0.00 H ATOM 1161 HB2 ALA A 73 29.003 9.742 19.524 1.00 0.00 H ATOM 1162 HB3 ALA A 73 29.688 10.021 18.068 1.00 0.00 H ATOM 1163 N ALA A 74 29.350 8.251 15.844 1.00 0.00 N ATOM 1164 CA ALA A 74 29.180 8.225 14.389 1.00 0.00 C ATOM 1165 C ALA A 74 28.394 7.004 13.916 1.00 0.00 C ATOM 1166 O ALA A 74 27.474 7.094 13.132 1.00 0.00 O ATOM 1167 CB ALA A 74 30.509 8.324 13.658 1.00 0.00 C ATOM 1168 H ALA A 74 30.265 8.237 16.248 1.00 0.00 H ATOM 1169 HA ALA A 74 28.646 9.033 14.140 1.00 0.00 H ATOM 1170 HB1 ALA A 74 30.349 8.303 12.671 1.00 0.00 H ATOM 1171 HB2 ALA A 74 30.962 9.181 13.904 1.00 0.00 H ATOM 1172 HB3 ALA A 74 31.091 7.553 13.918 1.00 0.00 H ATOM 1173 N VAL A 75 28.790 5.855 14.401 1.00 0.00 N ATOM 1174 CA VAL A 75 28.100 4.652 14.015 1.00 0.00 C ATOM 1175 C VAL A 75 26.611 4.734 14.383 1.00 0.00 C ATOM 1176 O VAL A 75 25.715 4.486 13.565 1.00 0.00 O ATOM 1177 CB VAL A 75 28.790 3.443 14.638 1.00 0.00 C ATOM 1178 CG1 VAL A 75 27.998 2.160 14.260 1.00 0.00 C ATOM 1179 CG2 VAL A 75 30.207 3.361 14.098 1.00 0.00 C ATOM 1180 H VAL A 75 29.564 5.813 15.033 1.00 0.00 H ATOM 1181 HA VAL A 75 28.166 4.565 13.021 1.00 0.00 H ATOM 1182 HB VAL A 75 28.814 3.544 15.633 1.00 0.00 H ATOM 1183 HG11 VAL A 75 28.444 1.362 14.665 1.00 0.00 H ATOM 1184 HG12 VAL A 75 27.063 2.231 14.607 1.00 0.00 H ATOM 1185 HG13 VAL A 75 27.978 2.062 13.265 1.00 0.00 H ATOM 1186 HG21 VAL A 75 30.671 2.571 14.499 1.00 0.00 H ATOM 1187 HG22 VAL A 75 30.179 3.262 13.103 1.00 0.00 H ATOM 1188 HG23 VAL A 75 30.703 4.196 14.336 1.00 0.00 H ATOM 1189 N ARG A 76 26.372 5.115 15.626 1.00 0.00 N ATOM 1190 CA ARG A 76 25.018 5.225 16.120 1.00 0.00 C ATOM 1191 C ARG A 76 24.201 6.235 15.310 1.00 0.00 C ATOM 1192 O ARG A 76 23.037 6.031 14.956 1.00 0.00 O ATOM 1193 CB ARG A 76 25.004 5.366 17.653 1.00 0.00 C ATOM 1194 CG ARG A 76 25.300 4.049 18.373 1.00 0.00 C ATOM 1195 CD ARG A 76 25.378 4.121 19.911 1.00 0.00 C ATOM 1196 NE ARG A 76 26.567 4.844 20.334 1.00 0.00 N ATOM 1197 CZ ARG A 76 26.544 6.092 20.811 1.00 0.00 C ATOM 1198 NH1 ARG A 76 25.407 6.768 20.917 1.00 0.00 N1+ ATOM 1199 NH2 ARG A 76 27.699 6.674 21.144 1.00 0.00 N ATOM 1200 H ARG A 76 27.138 5.330 16.232 1.00 0.00 H ATOM 1201 HA ARG A 76 24.597 4.337 15.934 1.00 0.00 H ATOM 1202 HB2 ARG A 76 24.101 5.689 17.936 1.00 0.00 H ATOM 1203 HB3 ARG A 76 25.696 6.038 17.918 1.00 0.00 H ATOM 1204 HG2 ARG A 76 26.178 3.708 18.038 1.00 0.00 H ATOM 1205 HG3 ARG A 76 24.577 3.401 18.134 1.00 0.00 H ATOM 1206 HD2 ARG A 76 25.409 3.193 20.282 1.00 0.00 H ATOM 1207 HD3 ARG A 76 24.567 4.591 20.259 1.00 0.00 H ATOM 1208 HE ARG A 76 27.451 4.381 20.264 1.00 0.00 H ATOM 1209 HH11 ARG A 76 25.412 7.701 21.277 1.00 0.00 H ATOM 1210 HH12 ARG A 76 24.545 6.344 20.637 1.00 0.00 H ATOM 1211 HH21 ARG A 76 27.703 7.607 21.503 1.00 0.00 H ATOM 1212 HH22 ARG A 76 28.559 6.176 21.035 1.00 0.00 H ATOM 1213 N GLY A 77 24.834 7.332 14.912 1.00 0.00 N ATOM 1214 CA GLY A 77 24.148 8.292 14.079 1.00 0.00 C ATOM 1215 C GLY A 77 23.733 7.639 12.756 1.00 0.00 C ATOM 1216 O GLY A 77 22.661 7.830 12.260 1.00 0.00 O ATOM 1217 H GLY A 77 25.782 7.493 15.188 1.00 0.00 H ATOM 1218 HA2 GLY A 77 24.758 9.062 13.891 1.00 0.00 H ATOM 1219 HA3 GLY A 77 23.333 8.621 14.556 1.00 0.00 H ATOM 1220 N ILE A 78 24.619 6.871 12.173 1.00 0.00 N ATOM 1221 CA ILE A 78 24.243 6.205 10.963 1.00 0.00 C ATOM 1222 C ILE A 78 23.086 5.251 11.260 1.00 0.00 C ATOM 1223 O ILE A 78 22.086 5.170 10.559 1.00 0.00 O ATOM 1224 CB ILE A 78 25.422 5.396 10.409 1.00 0.00 C ATOM 1225 CG1 ILE A 78 26.403 6.295 9.670 1.00 0.00 C ATOM 1226 CG2 ILE A 78 24.911 4.330 9.448 1.00 0.00 C ATOM 1227 CD1 ILE A 78 27.766 5.597 9.537 1.00 0.00 C ATOM 1228 H ILE A 78 25.533 6.753 12.562 1.00 0.00 H ATOM 1229 HA ILE A 78 23.953 6.881 10.285 1.00 0.00 H ATOM 1230 HB ILE A 78 25.897 4.950 11.168 1.00 0.00 H ATOM 1231 HG12 ILE A 78 26.517 7.148 10.179 1.00 0.00 H ATOM 1232 HG13 ILE A 78 26.045 6.496 8.758 1.00 0.00 H ATOM 1233 HG21 ILE A 78 25.684 3.806 9.090 1.00 0.00 H ATOM 1234 HG22 ILE A 78 24.287 3.716 9.932 1.00 0.00 H ATOM 1235 HG23 ILE A 78 24.426 4.768 8.691 1.00 0.00 H ATOM 1236 HD11 ILE A 78 28.401 6.197 9.050 1.00 0.00 H ATOM 1237 HD12 ILE A 78 28.128 5.396 10.447 1.00 0.00 H ATOM 1238 HD13 ILE A 78 27.655 4.744 9.027 1.00 0.00 H ATOM 1239 N LEU A 79 23.222 4.474 12.316 1.00 0.00 N ATOM 1240 CA LEU A 79 22.158 3.516 12.548 1.00 0.00 C ATOM 1241 C LEU A 79 20.793 4.077 12.862 1.00 0.00 C ATOM 1242 O LEU A 79 19.804 3.384 12.701 1.00 0.00 O ATOM 1243 CB LEU A 79 22.526 2.412 13.523 1.00 0.00 C ATOM 1244 CG LEU A 79 23.747 1.648 13.072 1.00 0.00 C ATOM 1245 CD1 LEU A 79 24.160 0.762 14.221 1.00 0.00 C ATOM 1246 CD2 LEU A 79 23.459 0.816 11.844 1.00 0.00 C ATOM 1247 H LEU A 79 24.014 4.541 12.923 1.00 0.00 H ATOM 1248 HA LEU A 79 22.043 3.050 11.671 1.00 0.00 H ATOM 1249 HB2 LEU A 79 21.757 1.777 13.598 1.00 0.00 H ATOM 1250 HB3 LEU A 79 22.711 2.819 14.417 1.00 0.00 H ATOM 1251 HG LEU A 79 24.484 2.292 12.870 1.00 0.00 H ATOM 1252 HD11 LEU A 79 24.970 0.236 13.962 1.00 0.00 H ATOM 1253 HD12 LEU A 79 24.371 1.327 15.019 1.00 0.00 H ATOM 1254 HD13 LEU A 79 23.413 0.136 14.444 1.00 0.00 H ATOM 1255 HD21 LEU A 79 24.287 0.324 11.573 1.00 0.00 H ATOM 1256 HD22 LEU A 79 22.733 0.159 12.049 1.00 0.00 H ATOM 1257 HD23 LEU A 79 23.167 1.414 11.097 1.00 0.00 H ATOM 1258 N ARG A 80 20.745 5.317 13.330 1.00 0.00 N ATOM 1259 CA ARG A 80 19.497 5.981 13.675 1.00 0.00 C ATOM 1260 C ARG A 80 18.899 6.743 12.524 1.00 0.00 C ATOM 1261 O ARG A 80 17.784 7.251 12.628 1.00 0.00 O ATOM 1262 CB ARG A 80 19.766 7.079 14.676 1.00 0.00 C ATOM 1263 CG ARG A 80 20.030 6.596 16.069 1.00 0.00 C ATOM 1264 CD ARG A 80 19.764 7.710 17.071 1.00 0.00 C ATOM 1265 NE ARG A 80 20.990 8.148 17.721 1.00 0.00 N ATOM 1266 CZ ARG A 80 21.697 9.227 17.382 1.00 0.00 C ATOM 1267 NH1 ARG A 80 21.356 10.062 16.387 1.00 0.00 N1+ ATOM 1268 NH2 ARG A 80 22.803 9.467 18.073 1.00 0.00 N ATOM 1269 H ARG A 80 21.603 5.817 13.451 1.00 0.00 H ATOM 1270 HA ARG A 80 18.839 5.324 14.042 1.00 0.00 H ATOM 1271 HB2 ARG A 80 18.969 7.682 14.700 1.00 0.00 H ATOM 1272 HB3 ARG A 80 20.565 7.595 14.367 1.00 0.00 H ATOM 1273 HG2 ARG A 80 20.984 6.306 16.143 1.00 0.00 H ATOM 1274 HG3 ARG A 80 19.430 5.821 16.269 1.00 0.00 H ATOM 1275 HD2 ARG A 80 19.129 7.376 17.767 1.00 0.00 H ATOM 1276 HD3 ARG A 80 19.355 8.487 16.592 1.00 0.00 H ATOM 1277 HE ARG A 80 21.330 7.596 18.483 1.00 0.00 H ATOM 1278 HH11 ARG A 80 21.929 10.855 16.182 1.00 0.00 H ATOM 1279 HH12 ARG A 80 20.529 9.890 15.852 1.00 0.00 H ATOM 1280 HH21 ARG A 80 23.366 10.264 17.855 1.00 0.00 H ATOM 1281 HH22 ARG A 80 23.074 8.851 18.812 1.00 0.00 H ATOM 1282 N ASN A 81 19.698 6.931 11.476 1.00 0.00 N ATOM 1283 CA ASN A 81 19.260 7.702 10.333 1.00 0.00 C ATOM 1284 C ASN A 81 18.530 6.886 9.268 1.00 0.00 C ATOM 1285 O ASN A 81 19.080 5.955 8.676 1.00 0.00 O ATOM 1286 CB ASN A 81 20.422 8.512 9.781 1.00 0.00 C ATOM 1287 CG ASN A 81 19.957 9.514 8.759 1.00 0.00 C ATOM 1288 ND2 ASN A 81 20.267 10.784 8.999 1.00 0.00 N ATOM 1289 OD1 ASN A 81 19.309 9.151 7.780 1.00 0.00 O ATOM 1290 H ASN A 81 20.615 6.533 11.479 1.00 0.00 H ATOM 1291 HA ASN A 81 18.597 8.365 10.680 1.00 0.00 H ATOM 1292 HB2 ASN A 81 21.077 7.890 9.352 1.00 0.00 H ATOM 1293 HB3 ASN A 81 20.867 8.998 10.534 1.00 0.00 H ATOM 1294 HD21 ASN A 81 20.797 11.024 9.812 1.00 0.00 H ATOM 1295 HD22 ASN A 81 19.970 11.499 8.367 1.00 0.00 H ATOM 1296 N ALA A 82 17.274 7.233 9.025 1.00 0.00 N ATOM 1297 CA ALA A 82 16.458 6.498 8.070 1.00 0.00 C ATOM 1298 C ALA A 82 17.021 6.456 6.670 1.00 0.00 C ATOM 1299 O ALA A 82 16.827 5.518 5.938 1.00 0.00 O ATOM 1300 CB ALA A 82 15.011 6.921 8.079 1.00 0.00 C ATOM 1301 H ALA A 82 16.879 8.015 9.507 1.00 0.00 H ATOM 1302 HA ALA A 82 16.462 5.550 8.389 1.00 0.00 H ATOM 1303 HB1 ALA A 82 14.503 6.384 7.406 1.00 0.00 H ATOM 1304 HB2 ALA A 82 14.625 6.768 8.988 1.00 0.00 H ATOM 1305 HB3 ALA A 82 14.946 7.892 7.849 1.00 0.00 H ATOM 1306 N LYS A 83 17.738 7.489 6.290 1.00 0.00 N ATOM 1307 CA LYS A 83 18.320 7.493 4.965 1.00 0.00 C ATOM 1308 C LYS A 83 19.654 6.777 4.919 1.00 0.00 C ATOM 1309 O LYS A 83 20.050 6.300 3.871 1.00 0.00 O ATOM 1310 CB LYS A 83 18.564 8.897 4.458 1.00 0.00 C ATOM 1311 CG LYS A 83 17.391 9.470 3.729 1.00 0.00 C ATOM 1312 CD LYS A 83 16.458 10.210 4.666 1.00 0.00 C ATOM 1313 CE LYS A 83 15.426 11.045 3.916 1.00 0.00 C ATOM 1314 NZ LYS A 83 15.470 10.816 2.459 1.00 0.00 N1+ ATOM 1315 H LYS A 83 17.880 8.262 6.908 1.00 0.00 H ATOM 1316 HA LYS A 83 17.690 7.033 4.339 1.00 0.00 H ATOM 1317 HB2 LYS A 83 19.347 8.879 3.836 1.00 0.00 H ATOM 1318 HB3 LYS A 83 18.772 9.486 5.239 1.00 0.00 H ATOM 1319 HG2 LYS A 83 16.887 8.726 3.290 1.00 0.00 H ATOM 1320 HG3 LYS A 83 17.722 10.106 3.032 1.00 0.00 H ATOM 1321 HD2 LYS A 83 17.001 10.816 5.248 1.00 0.00 H ATOM 1322 HD3 LYS A 83 15.979 9.542 5.236 1.00 0.00 H ATOM 1323 HE2 LYS A 83 15.604 12.013 4.095 1.00 0.00 H ATOM 1324 HE3 LYS A 83 14.515 10.807 4.251 1.00 0.00 H ATOM 1325 HZ1 LYS A 83 14.558 10.952 2.073 1.00 0.00 H ATOM 1326 HZ2 LYS A 83 16.109 11.461 2.039 1.00 0.00 H ATOM 1327 HZ3 LYS A 83 15.773 9.880 2.278 1.00 0.00 H ATOM 1328 N LEU A 84 20.374 6.760 6.031 1.00 0.00 N ATOM 1329 CA LEU A 84 21.698 6.156 6.019 1.00 0.00 C ATOM 1330 C LEU A 84 21.747 4.662 6.317 1.00 0.00 C ATOM 1331 O LEU A 84 22.497 3.905 5.714 1.00 0.00 O ATOM 1332 CB LEU A 84 22.683 6.918 6.954 1.00 0.00 C ATOM 1333 CG LEU A 84 22.894 8.379 6.605 1.00 0.00 C ATOM 1334 CD1 LEU A 84 23.843 8.996 7.637 1.00 0.00 C ATOM 1335 CD2 LEU A 84 23.525 8.524 5.219 1.00 0.00 C ATOM 1336 H LEU A 84 20.010 7.159 6.873 1.00 0.00 H ATOM 1337 HA LEU A 84 22.049 6.269 5.090 1.00 0.00 H ATOM 1338 HB2 LEU A 84 23.570 6.458 6.912 1.00 0.00 H ATOM 1339 HB3 LEU A 84 22.326 6.870 7.887 1.00 0.00 H ATOM 1340 HG LEU A 84 22.017 8.859 6.626 1.00 0.00 H ATOM 1341 HD11 LEU A 84 23.991 9.961 7.419 1.00 0.00 H ATOM 1342 HD12 LEU A 84 23.440 8.919 8.549 1.00 0.00 H ATOM 1343 HD13 LEU A 84 24.718 8.512 7.617 1.00 0.00 H ATOM 1344 HD21 LEU A 84 23.654 9.494 5.011 1.00 0.00 H ATOM 1345 HD22 LEU A 84 24.410 8.059 5.206 1.00 0.00 H ATOM 1346 HD23 LEU A 84 22.923 8.114 4.534 1.00 0.00 H ATOM 1347 N LYS A 85 20.976 4.264 7.293 1.00 0.00 N ATOM 1348 CA LYS A 85 20.954 2.909 7.729 1.00 0.00 C ATOM 1349 C LYS A 85 20.865 1.834 6.661 1.00 0.00 C ATOM 1350 O LYS A 85 21.599 0.838 6.663 1.00 0.00 O ATOM 1351 CB LYS A 85 19.905 2.733 8.781 1.00 0.00 C ATOM 1352 CG LYS A 85 19.974 1.318 9.304 1.00 0.00 C ATOM 1353 CD LYS A 85 19.238 1.131 10.595 1.00 0.00 C ATOM 1354 CE LYS A 85 19.144 -0.344 10.958 1.00 0.00 C ATOM 1355 NZ LYS A 85 18.287 -1.083 10.047 1.00 0.00 N1+ ATOM 1356 H LYS A 85 20.384 4.930 7.747 1.00 0.00 H ATOM 1357 HA LYS A 85 21.828 2.759 8.191 1.00 0.00 H ATOM 1358 HB2 LYS A 85 19.002 2.902 8.387 1.00 0.00 H ATOM 1359 HB3 LYS A 85 20.068 3.376 9.529 1.00 0.00 H ATOM 1360 HG2 LYS A 85 20.934 1.079 9.448 1.00 0.00 H ATOM 1361 HG3 LYS A 85 19.577 0.706 8.620 1.00 0.00 H ATOM 1362 HD2 LYS A 85 18.315 1.505 10.503 1.00 0.00 H ATOM 1363 HD3 LYS A 85 19.723 1.617 11.322 1.00 0.00 H ATOM 1364 HE2 LYS A 85 18.774 -0.424 11.884 1.00 0.00 H ATOM 1365 HE3 LYS A 85 20.061 -0.741 10.930 1.00 0.00 H ATOM 1366 HZ1 LYS A 85 18.833 -1.435 9.287 1.00 0.00 H ATOM 1367 HZ2 LYS A 85 17.862 -1.846 10.534 1.00 0.00 H ATOM 1368 HZ3 LYS A 85 17.576 -0.476 9.693 1.00 0.00 H ATOM 1369 N PRO A 86 19.923 1.989 5.784 1.00 0.00 N ATOM 1370 CA PRO A 86 19.718 1.012 4.751 1.00 0.00 C ATOM 1371 C PRO A 86 20.931 0.894 3.863 1.00 0.00 C ATOM 1372 O PRO A 86 21.327 -0.193 3.490 1.00 0.00 O ATOM 1373 CB PRO A 86 18.506 1.471 3.952 1.00 0.00 C ATOM 1374 CG PRO A 86 17.901 2.641 4.721 1.00 0.00 C ATOM 1375 CD PRO A 86 18.921 3.062 5.769 1.00 0.00 C ATOM 1376 HA PRO A 86 19.524 0.124 5.168 1.00 0.00 H ATOM 1377 HB2 PRO A 86 18.786 1.765 3.038 1.00 0.00 H ATOM 1378 HB3 PRO A 86 17.841 0.728 3.874 1.00 0.00 H ATOM 1379 HG2 PRO A 86 17.715 3.401 4.099 1.00 0.00 H ATOM 1380 HG3 PRO A 86 17.051 2.357 5.164 1.00 0.00 H ATOM 1381 HD2 PRO A 86 19.343 3.933 5.517 1.00 0.00 H ATOM 1382 HD3 PRO A 86 18.487 3.149 6.666 1.00 0.00 H ATOM 1383 N VAL A 87 21.556 2.019 3.540 1.00 0.00 N ATOM 1384 CA VAL A 87 22.743 1.963 2.703 1.00 0.00 C ATOM 1385 C VAL A 87 23.885 1.251 3.432 1.00 0.00 C ATOM 1386 O VAL A 87 24.555 0.336 2.950 1.00 0.00 O ATOM 1387 CB VAL A 87 23.208 3.358 2.277 1.00 0.00 C ATOM 1388 CG1 VAL A 87 24.315 3.235 1.225 1.00 0.00 C ATOM 1389 CG2 VAL A 87 22.026 4.173 1.750 1.00 0.00 C ATOM 1390 H VAL A 87 21.213 2.899 3.870 1.00 0.00 H ATOM 1391 HA VAL A 87 22.522 1.441 1.879 1.00 0.00 H ATOM 1392 HB VAL A 87 23.583 3.825 3.078 1.00 0.00 H ATOM 1393 HG11 VAL A 87 24.616 4.148 0.949 1.00 0.00 H ATOM 1394 HG12 VAL A 87 25.088 2.732 1.612 1.00 0.00 H ATOM 1395 HG13 VAL A 87 23.964 2.745 0.427 1.00 0.00 H ATOM 1396 HG21 VAL A 87 22.343 5.081 1.476 1.00 0.00 H ATOM 1397 HG22 VAL A 87 21.625 3.707 0.961 1.00 0.00 H ATOM 1398 HG23 VAL A 87 21.337 4.264 2.469 1.00 0.00 H ATOM 1399 N TYR A 88 24.101 1.688 4.642 1.00 0.00 N ATOM 1400 CA TYR A 88 25.107 1.129 5.505 1.00 0.00 C ATOM 1401 C TYR A 88 24.960 -0.392 5.686 1.00 0.00 C ATOM 1402 O TYR A 88 25.964 -1.131 5.691 1.00 0.00 O ATOM 1403 CB TYR A 88 25.006 1.855 6.871 1.00 0.00 C ATOM 1404 CG TYR A 88 26.080 1.445 7.826 1.00 0.00 C ATOM 1405 CD1 TYR A 88 27.346 2.030 7.761 1.00 0.00 C ATOM 1406 CD2 TYR A 88 25.851 0.462 8.788 1.00 0.00 C ATOM 1407 CE1 TYR A 88 28.359 1.661 8.638 1.00 0.00 C ATOM 1408 CE2 TYR A 88 26.851 0.090 9.683 1.00 0.00 C ATOM 1409 CZ TYR A 88 28.101 0.707 9.623 1.00 0.00 C ATOM 1410 OH TYR A 88 29.091 0.303 10.491 1.00 0.00 O ATOM 1411 H TYR A 88 23.543 2.444 4.984 1.00 0.00 H ATOM 1412 HA TYR A 88 26.006 1.317 5.110 1.00 0.00 H ATOM 1413 HB2 TYR A 88 24.118 1.645 7.280 1.00 0.00 H ATOM 1414 HB3 TYR A 88 25.076 2.840 6.715 1.00 0.00 H ATOM 1415 HD1 TYR A 88 27.528 2.729 7.069 1.00 0.00 H ATOM 1416 HD2 TYR A 88 24.956 0.018 8.836 1.00 0.00 H ATOM 1417 HE1 TYR A 88 29.266 2.076 8.564 1.00 0.00 H ATOM 1418 HE2 TYR A 88 26.674 -0.618 10.367 1.00 0.00 H ATOM 1419 HH TYR A 88 28.892 -0.382 11.192 1.00 0.00 H ATOM 1420 N ASP A 89 23.709 -0.854 5.846 1.00 0.00 N ATOM 1421 CA ASP A 89 23.437 -2.279 6.057 1.00 0.00 C ATOM 1422 C ASP A 89 23.760 -3.036 4.832 1.00 0.00 C ATOM 1423 O ASP A 89 24.152 -4.193 4.899 1.00 0.00 O ATOM 1424 CB ASP A 89 21.977 -2.531 6.393 1.00 0.00 C ATOM 1425 CG ASP A 89 21.731 -2.288 7.841 1.00 0.00 C ATOM 1426 OD1 ASP A 89 22.848 -2.091 8.515 1.00 0.00 O ATOM 1427 OD2 ASP A 89 20.642 -2.285 8.325 1.00 0.00 O1- ATOM 1428 H ASP A 89 22.944 -0.210 5.821 1.00 0.00 H ATOM 1429 HA ASP A 89 24.007 -2.613 6.807 1.00 0.00 H ATOM 1430 HB2 ASP A 89 21.747 -3.479 6.174 1.00 0.00 H ATOM 1431 HB3 ASP A 89 21.403 -1.915 5.853 1.00 0.00 H ATOM 1432 N SER A 90 23.593 -2.401 3.704 1.00 0.00 N ATOM 1433 CA SER A 90 23.868 -3.125 2.490 1.00 0.00 C ATOM 1434 C SER A 90 25.341 -3.313 2.229 1.00 0.00 C ATOM 1435 O SER A 90 25.735 -4.064 1.316 1.00 0.00 O ATOM 1436 CB SER A 90 23.269 -2.434 1.271 1.00 0.00 C ATOM 1437 OG SER A 90 24.054 -1.304 0.884 1.00 0.00 O ATOM 1438 H SER A 90 23.286 -1.449 3.684 1.00 0.00 H ATOM 1439 HA SER A 90 23.450 -4.030 2.569 1.00 0.00 H ATOM 1440 HB2 SER A 90 22.343 -2.128 1.491 1.00 0.00 H ATOM 1441 HB3 SER A 90 23.234 -3.083 0.511 1.00 0.00 H ATOM 1442 HG SER A 90 24.089 -0.649 1.638 1.00 0.00 H ATOM 1443 N LEU A 91 26.200 -2.568 2.905 1.00 0.00 N ATOM 1444 CA LEU A 91 27.633 -2.616 2.575 1.00 0.00 C ATOM 1445 C LEU A 91 28.443 -3.694 3.251 1.00 0.00 C ATOM 1446 O LEU A 91 28.092 -4.179 4.339 1.00 0.00 O ATOM 1447 CB LEU A 91 28.328 -1.299 2.979 1.00 0.00 C ATOM 1448 CG LEU A 91 27.746 -0.042 2.334 1.00 0.00 C ATOM 1449 CD1 LEU A 91 28.312 1.192 3.010 1.00 0.00 C ATOM 1450 CD2 LEU A 91 28.207 -0.025 0.874 1.00 0.00 C ATOM 1451 H LEU A 91 25.876 -1.973 3.640 1.00 0.00 H ATOM 1452 HA LEU A 91 27.724 -2.729 1.586 1.00 0.00 H ATOM 1453 HB2 LEU A 91 29.292 -1.364 2.720 1.00 0.00 H ATOM 1454 HB3 LEU A 91 28.256 -1.201 3.972 1.00 0.00 H ATOM 1455 HG LEU A 91 26.748 -0.047 2.389 1.00 0.00 H ATOM 1456 HD11 LEU A 91 27.928 2.011 2.584 1.00 0.00 H ATOM 1457 HD12 LEU A 91 28.074 1.179 3.981 1.00 0.00 H ATOM 1458 HD13 LEU A 91 29.307 1.200 2.910 1.00 0.00 H ATOM 1459 HD21 LEU A 91 27.843 0.788 0.419 1.00 0.00 H ATOM 1460 HD22 LEU A 91 29.206 -0.007 0.840 1.00 0.00 H ATOM 1461 HD23 LEU A 91 27.873 -0.845 0.409 1.00 0.00 H ATOM 1462 N ASP A 92 29.609 -3.991 2.651 1.00 0.00 N ATOM 1463 CA ASP A 92 30.556 -4.919 3.274 1.00 0.00 C ATOM 1464 C ASP A 92 31.351 -4.198 4.373 1.00 0.00 C ATOM 1465 O ASP A 92 31.275 -2.970 4.520 1.00 0.00 O ATOM 1466 CB ASP A 92 31.557 -5.480 2.295 1.00 0.00 C ATOM 1467 CG ASP A 92 32.327 -4.396 1.620 1.00 0.00 C ATOM 1468 OD1 ASP A 92 31.679 -3.885 0.599 1.00 0.00 O ATOM 1469 OD2 ASP A 92 33.439 -4.033 1.978 1.00 0.00 O1- ATOM 1470 H ASP A 92 29.832 -3.574 1.770 1.00 0.00 H ATOM 1471 HA ASP A 92 30.046 -5.675 3.685 1.00 0.00 H ATOM 1472 HB2 ASP A 92 31.071 -6.013 1.603 1.00 0.00 H ATOM 1473 HB3 ASP A 92 32.194 -6.074 2.786 1.00 0.00 H ATOM 1474 N ALA A 93 32.146 -4.938 5.143 1.00 0.00 N ATOM 1475 CA ALA A 93 32.892 -4.363 6.239 1.00 0.00 C ATOM 1476 C ALA A 93 33.897 -3.256 5.913 1.00 0.00 C ATOM 1477 O ALA A 93 34.018 -2.306 6.663 1.00 0.00 O ATOM 1478 CB ALA A 93 33.335 -5.369 7.301 1.00 0.00 C ATOM 1479 H ALA A 93 32.229 -5.917 4.958 1.00 0.00 H ATOM 1480 HA ALA A 93 32.181 -3.855 6.725 1.00 0.00 H ATOM 1481 HB1 ALA A 93 33.842 -4.893 8.020 1.00 0.00 H ATOM 1482 HB2 ALA A 93 32.530 -5.811 7.697 1.00 0.00 H ATOM 1483 HB3 ALA A 93 33.922 -6.061 6.881 1.00 0.00 H ATOM 1484 N VAL A 94 34.634 -3.342 4.810 1.00 0.00 N ATOM 1485 CA VAL A 94 35.558 -2.281 4.462 1.00 0.00 C ATOM 1486 C VAL A 94 34.796 -1.000 4.093 1.00 0.00 C ATOM 1487 O VAL A 94 35.042 0.080 4.646 1.00 0.00 O ATOM 1488 CB VAL A 94 36.480 -2.760 3.345 1.00 0.00 C ATOM 1489 CG1 VAL A 94 37.476 -1.685 2.896 1.00 0.00 C ATOM 1490 CG2 VAL A 94 37.314 -3.892 3.922 1.00 0.00 C ATOM 1491 H VAL A 94 34.550 -4.143 4.217 1.00 0.00 H ATOM 1492 HA VAL A 94 36.121 -2.085 5.265 1.00 0.00 H ATOM 1493 HB VAL A 94 35.944 -3.085 2.566 1.00 0.00 H ATOM 1494 HG11 VAL A 94 38.053 -2.050 2.166 1.00 0.00 H ATOM 1495 HG12 VAL A 94 36.976 -0.887 2.559 1.00 0.00 H ATOM 1496 HG13 VAL A 94 38.048 -1.416 3.671 1.00 0.00 H ATOM 1497 HG21 VAL A 94 37.937 -4.239 3.220 1.00 0.00 H ATOM 1498 HG22 VAL A 94 37.844 -3.553 4.700 1.00 0.00 H ATOM 1499 HG23 VAL A 94 36.711 -4.629 4.226 1.00 0.00 H ATOM 1500 N ARG A 95 33.870 -1.134 3.167 1.00 0.00 N ATOM 1501 CA ARG A 95 33.057 -0.019 2.743 1.00 0.00 C ATOM 1502 C ARG A 95 32.334 0.614 3.908 1.00 0.00 C ATOM 1503 O ARG A 95 32.121 1.828 3.947 1.00 0.00 O ATOM 1504 CB ARG A 95 32.101 -0.382 1.624 1.00 0.00 C ATOM 1505 CG ARG A 95 32.874 -0.733 0.361 1.00 0.00 C ATOM 1506 CD ARG A 95 31.890 -1.043 -0.753 1.00 0.00 C ATOM 1507 NE ARG A 95 32.574 -1.154 -2.019 1.00 0.00 N ATOM 1508 CZ ARG A 95 33.052 -2.302 -2.503 1.00 0.00 C ATOM 1509 NH1 ARG A 95 32.971 -3.466 -1.840 1.00 0.00 N1+ ATOM 1510 NH2 ARG A 95 33.661 -2.292 -3.685 1.00 0.00 N ATOM 1511 H ARG A 95 33.726 -2.030 2.747 1.00 0.00 H ATOM 1512 HA ARG A 95 33.681 0.673 2.379 1.00 0.00 H ATOM 1513 HB2 ARG A 95 31.501 0.396 1.438 1.00 0.00 H ATOM 1514 HB3 ARG A 95 31.550 -1.169 1.903 1.00 0.00 H ATOM 1515 HG2 ARG A 95 33.449 -1.533 0.532 1.00 0.00 H ATOM 1516 HG3 ARG A 95 33.449 0.040 0.094 1.00 0.00 H ATOM 1517 HD2 ARG A 95 31.214 -0.308 -0.808 1.00 0.00 H ATOM 1518 HD3 ARG A 95 31.428 -1.907 -0.552 1.00 0.00 H ATOM 1519 HE ARG A 95 32.697 -0.324 -2.564 1.00 0.00 H ATOM 1520 HH11 ARG A 95 33.345 -4.300 -2.246 1.00 0.00 H ATOM 1521 HH12 ARG A 95 32.537 -3.500 -0.940 1.00 0.00 H ATOM 1522 HH21 ARG A 95 34.027 -3.141 -4.066 1.00 0.00 H ATOM 1523 HH22 ARG A 95 33.753 -1.435 -4.193 1.00 0.00 H ATOM 1524 N ARG A 96 31.944 -0.189 4.883 1.00 0.00 N ATOM 1525 CA ARG A 96 31.280 0.424 6.031 1.00 0.00 C ATOM 1526 C ARG A 96 32.229 1.411 6.754 1.00 0.00 C ATOM 1527 O ARG A 96 31.819 2.429 7.300 1.00 0.00 O ATOM 1528 CB ARG A 96 30.768 -0.580 7.054 1.00 0.00 C ATOM 1529 CG ARG A 96 29.588 -1.374 6.556 1.00 0.00 C ATOM 1530 CD ARG A 96 29.031 -2.355 7.625 1.00 0.00 C ATOM 1531 NE ARG A 96 27.903 -3.105 7.057 1.00 0.00 N ATOM 1532 CZ ARG A 96 27.227 -4.079 7.656 1.00 0.00 C ATOM 1533 NH1 ARG A 96 27.505 -4.424 8.876 1.00 0.00 N1+ ATOM 1534 NH2 ARG A 96 26.228 -4.672 6.973 1.00 0.00 N ATOM 1535 H ARG A 96 32.097 -1.176 4.837 1.00 0.00 H ATOM 1536 HA ARG A 96 30.496 0.944 5.691 1.00 0.00 H ATOM 1537 HB2 ARG A 96 30.494 -0.084 7.878 1.00 0.00 H ATOM 1538 HB3 ARG A 96 31.508 -1.214 7.277 1.00 0.00 H ATOM 1539 HG2 ARG A 96 29.872 -1.901 5.755 1.00 0.00 H ATOM 1540 HG3 ARG A 96 28.861 -0.738 6.296 1.00 0.00 H ATOM 1541 HD2 ARG A 96 28.720 -1.838 8.423 1.00 0.00 H ATOM 1542 HD3 ARG A 96 29.751 -2.992 7.900 1.00 0.00 H ATOM 1543 HE ARG A 96 27.617 -2.859 6.131 1.00 0.00 H ATOM 1544 HH11 ARG A 96 26.990 -5.159 9.318 1.00 0.00 H ATOM 1545 HH12 ARG A 96 28.234 -3.955 9.374 1.00 0.00 H ATOM 1546 HH21 ARG A 96 25.701 -5.408 7.397 1.00 0.00 H ATOM 1547 HH22 ARG A 96 26.014 -4.376 6.042 1.00 0.00 H ATOM 1548 N ALA A 97 33.511 1.070 6.773 1.00 0.00 N ATOM 1549 CA ALA A 97 34.462 1.942 7.411 1.00 0.00 C ATOM 1550 C ALA A 97 34.522 3.252 6.622 1.00 0.00 C ATOM 1551 O ALA A 97 34.629 4.324 7.202 1.00 0.00 O ATOM 1552 CB ALA A 97 35.849 1.293 7.483 1.00 0.00 C ATOM 1553 H ALA A 97 33.813 0.216 6.349 1.00 0.00 H ATOM 1554 HA ALA A 97 34.148 2.138 8.340 1.00 0.00 H ATOM 1555 HB1 ALA A 97 36.487 1.920 7.930 1.00 0.00 H ATOM 1556 HB2 ALA A 97 35.793 0.444 8.008 1.00 0.00 H ATOM 1557 HB3 ALA A 97 36.171 1.092 6.558 1.00 0.00 H ATOM 1558 N ALA A 98 34.439 3.173 5.283 1.00 0.00 N ATOM 1559 CA ALA A 98 34.443 4.405 4.506 1.00 0.00 C ATOM 1560 C ALA A 98 33.222 5.261 4.844 1.00 0.00 C ATOM 1561 O ALA A 98 33.282 6.486 4.843 1.00 0.00 O ATOM 1562 CB ALA A 98 34.534 4.178 2.999 1.00 0.00 C ATOM 1563 H ALA A 98 34.376 2.285 4.828 1.00 0.00 H ATOM 1564 HA ALA A 98 35.253 4.924 4.777 1.00 0.00 H ATOM 1565 HB1 ALA A 98 34.532 5.060 2.528 1.00 0.00 H ATOM 1566 HB2 ALA A 98 35.380 3.688 2.786 1.00 0.00 H ATOM 1567 HB3 ALA A 98 33.750 3.637 2.696 1.00 0.00 H ATOM 1568 N ALA A 99 32.101 4.608 5.100 1.00 0.00 N ATOM 1569 CA ALA A 99 30.898 5.353 5.415 1.00 0.00 C ATOM 1570 C ALA A 99 31.052 6.053 6.740 1.00 0.00 C ATOM 1571 O ALA A 99 30.592 7.176 6.901 1.00 0.00 O ATOM 1572 CB ALA A 99 29.640 4.458 5.457 1.00 0.00 C ATOM 1573 H ALA A 99 32.083 3.608 5.076 1.00 0.00 H ATOM 1574 HA ALA A 99 30.765 6.047 4.708 1.00 0.00 H ATOM 1575 HB1 ALA A 99 28.841 5.017 5.677 1.00 0.00 H ATOM 1576 HB2 ALA A 99 29.509 4.025 4.565 1.00 0.00 H ATOM 1577 HB3 ALA A 99 29.756 3.752 6.156 1.00 0.00 H ATOM 1578 N ILE A 100 31.672 5.376 7.707 1.00 0.00 N ATOM 1579 CA ILE A 100 31.840 5.934 9.034 1.00 0.00 C ATOM 1580 C ILE A 100 32.738 7.167 8.951 1.00 0.00 C ATOM 1581 O ILE A 100 32.552 8.234 9.585 1.00 0.00 O ATOM 1582 CB ILE A 100 32.367 4.895 10.034 1.00 0.00 C ATOM 1583 CG1 ILE A 100 31.313 3.805 10.296 1.00 0.00 C ATOM 1584 CG2 ILE A 100 32.741 5.583 11.328 1.00 0.00 C ATOM 1585 CD1 ILE A 100 31.874 2.553 11.013 1.00 0.00 C ATOM 1586 H ILE A 100 32.029 4.463 7.512 1.00 0.00 H ATOM 1587 HA ILE A 100 30.941 6.234 9.353 1.00 0.00 H ATOM 1588 HB ILE A 100 33.185 4.466 9.650 1.00 0.00 H ATOM 1589 HG12 ILE A 100 30.929 3.520 9.418 1.00 0.00 H ATOM 1590 HG13 ILE A 100 30.589 4.196 10.865 1.00 0.00 H ATOM 1591 HG21 ILE A 100 33.084 4.906 11.979 1.00 0.00 H ATOM 1592 HG22 ILE A 100 33.451 6.264 11.150 1.00 0.00 H ATOM 1593 HG23 ILE A 100 31.935 6.034 11.711 1.00 0.00 H ATOM 1594 HD11 ILE A 100 31.138 1.890 11.150 1.00 0.00 H ATOM 1595 HD12 ILE A 100 32.593 2.142 10.452 1.00 0.00 H ATOM 1596 HD13 ILE A 100 32.253 2.818 11.899 1.00 0.00 H ATOM 1597 N ASN A 101 33.743 7.045 8.112 1.00 0.00 N ATOM 1598 CA ASN A 101 34.706 8.119 7.921 1.00 0.00 C ATOM 1599 C ASN A 101 34.010 9.384 7.430 1.00 0.00 C ATOM 1600 O ASN A 101 34.209 10.460 7.965 1.00 0.00 O ATOM 1601 CB ASN A 101 35.764 7.638 6.932 1.00 0.00 C ATOM 1602 CG ASN A 101 36.971 8.530 6.884 1.00 0.00 C ATOM 1603 ND2 ASN A 101 38.165 7.941 6.872 1.00 0.00 N ATOM 1604 OD1 ASN A 101 36.847 9.751 6.798 1.00 0.00 O ATOM 1605 H ASN A 101 33.848 6.196 7.594 1.00 0.00 H ATOM 1606 HA ASN A 101 35.149 8.314 8.796 1.00 0.00 H ATOM 1607 HB2 ASN A 101 35.356 7.605 6.020 1.00 0.00 H ATOM 1608 HB3 ASN A 101 36.057 6.720 7.200 1.00 0.00 H ATOM 1609 HD21 ASN A 101 38.232 6.946 6.944 1.00 0.00 H ATOM 1610 HD22 ASN A 101 38.994 8.494 6.791 1.00 0.00 H ATOM 1611 N MET A 102 33.190 9.257 6.420 1.00 0.00 N ATOM 1612 CA MET A 102 32.474 10.415 5.916 1.00 0.00 C ATOM 1613 C MET A 102 31.633 11.070 7.011 1.00 0.00 C ATOM 1614 O MET A 102 31.610 12.293 7.155 1.00 0.00 O ATOM 1615 CB MET A 102 31.501 10.039 4.768 1.00 0.00 C ATOM 1616 CG MET A 102 32.183 9.785 3.444 1.00 0.00 C ATOM 1617 SD MET A 102 30.998 9.529 2.120 1.00 0.00 S ATOM 1618 CE MET A 102 30.629 11.259 1.758 1.00 0.00 C ATOM 1619 H MET A 102 33.056 8.362 5.994 1.00 0.00 H ATOM 1620 HA MET A 102 33.136 11.082 5.574 1.00 0.00 H ATOM 1621 HB2 MET A 102 30.851 10.789 4.648 1.00 0.00 H ATOM 1622 HB3 MET A 102 31.008 9.210 5.032 1.00 0.00 H ATOM 1623 HG2 MET A 102 32.757 8.970 3.527 1.00 0.00 H ATOM 1624 HG3 MET A 102 32.755 10.574 3.218 1.00 0.00 H ATOM 1625 HE1 MET A 102 29.960 11.309 1.016 1.00 0.00 H ATOM 1626 HE2 MET A 102 30.254 11.698 2.575 1.00 0.00 H ATOM 1627 HE3 MET A 102 31.468 11.728 1.483 1.00 0.00 H ATOM 1628 N VAL A 103 30.900 10.255 7.762 1.00 0.00 N ATOM 1629 CA VAL A 103 30.038 10.804 8.794 1.00 0.00 C ATOM 1630 C VAL A 103 30.869 11.459 9.874 1.00 0.00 C ATOM 1631 O VAL A 103 30.513 12.510 10.349 1.00 0.00 O ATOM 1632 CB VAL A 103 29.055 9.794 9.385 1.00 0.00 C ATOM 1633 CG1 VAL A 103 28.318 10.422 10.550 1.00 0.00 C ATOM 1634 CG2 VAL A 103 28.030 9.391 8.338 1.00 0.00 C ATOM 1635 H VAL A 103 30.942 9.266 7.617 1.00 0.00 H ATOM 1636 HA VAL A 103 29.494 11.526 8.366 1.00 0.00 H ATOM 1637 HB VAL A 103 29.552 8.985 9.698 1.00 0.00 H ATOM 1638 HG11 VAL A 103 27.676 9.759 10.935 1.00 0.00 H ATOM 1639 HG12 VAL A 103 28.976 10.695 11.252 1.00 0.00 H ATOM 1640 HG13 VAL A 103 27.816 11.227 10.232 1.00 0.00 H ATOM 1641 HG21 VAL A 103 27.392 8.731 8.733 1.00 0.00 H ATOM 1642 HG22 VAL A 103 27.527 10.200 8.035 1.00 0.00 H ATOM 1643 HG23 VAL A 103 28.497 8.977 7.557 1.00 0.00 H ATOM 1644 N PHE A 104 31.986 10.848 10.262 1.00 0.00 N ATOM 1645 CA PHE A 104 32.827 11.414 11.298 1.00 0.00 C ATOM 1646 C PHE A 104 33.308 12.812 10.903 1.00 0.00 C ATOM 1647 O PHE A 104 33.453 13.709 11.707 1.00 0.00 O ATOM 1648 CB PHE A 104 34.059 10.524 11.469 1.00 0.00 C ATOM 1649 CG PHE A 104 34.990 10.953 12.576 1.00 0.00 C ATOM 1650 CD1 PHE A 104 35.940 11.947 12.361 1.00 0.00 C ATOM 1651 CD2 PHE A 104 34.971 10.306 13.811 1.00 0.00 C ATOM 1652 CE1 PHE A 104 36.815 12.302 13.390 1.00 0.00 C ATOM 1653 CE2 PHE A 104 35.857 10.623 14.838 1.00 0.00 C ATOM 1654 CZ PHE A 104 36.786 11.639 14.619 1.00 0.00 C ATOM 1655 H PHE A 104 32.249 9.985 9.832 1.00 0.00 H ATOM 1656 HA PHE A 104 32.320 11.460 12.159 1.00 0.00 H ATOM 1657 HB2 PHE A 104 34.571 10.530 10.610 1.00 0.00 H ATOM 1658 HB3 PHE A 104 33.748 9.594 11.665 1.00 0.00 H ATOM 1659 HD1 PHE A 104 35.996 12.405 11.474 1.00 0.00 H ATOM 1660 HD2 PHE A 104 34.295 9.586 13.966 1.00 0.00 H ATOM 1661 HE1 PHE A 104 37.472 13.042 13.245 1.00 0.00 H ATOM 1662 HE2 PHE A 104 35.827 10.134 15.710 1.00 0.00 H ATOM 1663 HZ PHE A 104 37.430 11.893 15.340 1.00 0.00 H ATOM 1664 N GLN A 105 33.591 12.977 9.619 1.00 0.00 N ATOM 1665 CA GLN A 105 34.097 14.217 9.046 1.00 0.00 C ATOM 1666 C GLN A 105 33.034 15.250 8.790 1.00 0.00 C ATOM 1667 O GLN A 105 33.246 16.420 9.049 1.00 0.00 O ATOM 1668 CB GLN A 105 34.902 14.018 7.685 1.00 0.00 C ATOM 1669 CG GLN A 105 35.545 15.311 7.084 1.00 0.00 C ATOM 1670 CD GLN A 105 36.150 15.199 5.669 1.00 0.00 C ATOM 1671 NE2 GLN A 105 36.785 16.268 5.142 1.00 0.00 N ATOM 1672 OE1 GLN A 105 36.100 14.154 5.055 1.00 0.00 O ATOM 1673 H GLN A 105 33.448 12.201 9.004 1.00 0.00 H ATOM 1674 HA GLN A 105 34.734 14.609 9.710 1.00 0.00 H ATOM 1675 HB2 GLN A 105 34.270 13.644 7.006 1.00 0.00 H ATOM 1676 HB3 GLN A 105 35.636 13.360 7.855 1.00 0.00 H ATOM 1677 HG2 GLN A 105 36.276 15.600 7.703 1.00 0.00 H ATOM 1678 HG3 GLN A 105 34.835 16.015 7.054 1.00 0.00 H ATOM 1679 HE21 GLN A 105 36.824 17.128 5.651 1.00 0.00 H ATOM 1680 HE22 GLN A 105 37.216 16.200 4.242 1.00 0.00 H ATOM 1681 N MET A 106 31.938 14.835 8.201 1.00 0.00 N ATOM 1682 CA MET A 106 30.974 15.806 7.799 1.00 0.00 C ATOM 1683 C MET A 106 29.629 15.797 8.444 1.00 0.00 C ATOM 1684 O MET A 106 28.803 16.625 8.138 1.00 0.00 O ATOM 1685 CB MET A 106 30.965 15.956 6.253 1.00 0.00 C ATOM 1686 CG MET A 106 30.249 14.948 5.414 1.00 0.00 C ATOM 1687 SD MET A 106 30.720 15.242 3.680 1.00 0.00 S ATOM 1688 CE MET A 106 32.208 14.282 3.569 1.00 0.00 C ATOM 1689 H MET A 106 31.782 13.861 8.038 1.00 0.00 H ATOM 1690 HA MET A 106 31.373 16.668 8.111 1.00 0.00 H ATOM 1691 HB2 MET A 106 31.920 15.954 5.956 1.00 0.00 H ATOM 1692 HB3 MET A 106 30.555 16.845 6.051 1.00 0.00 H ATOM 1693 HG2 MET A 106 29.261 15.055 5.522 1.00 0.00 H ATOM 1694 HG3 MET A 106 30.516 14.024 5.688 1.00 0.00 H ATOM 1695 HE1 MET A 106 32.584 14.355 2.645 1.00 0.00 H ATOM 1696 HE2 MET A 106 32.876 14.626 4.229 1.00 0.00 H ATOM 1697 HE3 MET A 106 32.003 13.324 3.771 1.00 0.00 H ATOM 1698 N GLY A 107 29.426 14.898 9.360 1.00 0.00 N ATOM 1699 CA GLY A 107 28.171 14.908 10.002 1.00 0.00 C ATOM 1700 C GLY A 107 27.167 14.191 9.173 1.00 0.00 C ATOM 1701 O GLY A 107 27.213 14.077 7.947 1.00 0.00 O ATOM 1702 H GLY A 107 30.129 14.228 9.599 1.00 0.00 H ATOM 1703 HA2 GLY A 107 27.875 15.854 10.135 1.00 0.00 H ATOM 1704 HA3 GLY A 107 28.250 14.455 10.890 1.00 0.00 H ATOM 1705 N GLU A 108 26.229 13.752 9.922 1.00 0.00 N ATOM 1706 CA GLU A 108 25.194 12.972 9.395 1.00 0.00 C ATOM 1707 C GLU A 108 24.294 13.728 8.464 1.00 0.00 C ATOM 1708 O GLU A 108 23.773 13.176 7.517 1.00 0.00 O ATOM 1709 CB GLU A 108 24.504 12.291 10.559 1.00 0.00 C ATOM 1710 CG GLU A 108 23.014 12.550 10.613 1.00 0.00 C ATOM 1711 CD GLU A 108 22.389 11.387 11.297 1.00 0.00 C ATOM 1712 OE1 GLU A 108 23.273 10.455 11.551 1.00 0.00 O ATOM 1713 OE2 GLU A 108 21.211 11.320 11.559 1.00 0.00 O1- ATOM 1714 H GLU A 108 26.235 13.969 10.898 1.00 0.00 H ATOM 1715 HA GLU A 108 25.625 12.250 8.854 1.00 0.00 H ATOM 1716 HB2 GLU A 108 24.914 12.623 11.408 1.00 0.00 H ATOM 1717 HB3 GLU A 108 24.651 11.305 10.481 1.00 0.00 H ATOM 1718 HG2 GLU A 108 22.648 12.640 9.687 1.00 0.00 H ATOM 1719 HG3 GLU A 108 22.831 13.388 11.126 1.00 0.00 H ATOM 1720 N THR A 109 24.136 15.006 8.712 1.00 0.00 N ATOM 1721 CA THR A 109 23.311 15.770 7.809 1.00 0.00 C ATOM 1722 C THR A 109 24.041 15.885 6.502 1.00 0.00 C ATOM 1723 O THR A 109 23.473 15.600 5.441 1.00 0.00 O ATOM 1724 CB THR A 109 22.983 17.158 8.357 1.00 0.00 C ATOM 1725 CG2 THR A 109 22.191 17.949 7.329 1.00 0.00 C ATOM 1726 OG1 THR A 109 22.213 17.003 9.511 1.00 0.00 O ATOM 1727 H THR A 109 24.573 15.437 9.501 1.00 0.00 H ATOM 1728 HA THR A 109 22.456 15.274 7.657 1.00 0.00 H ATOM 1729 HB THR A 109 23.829 17.643 8.578 1.00 0.00 H ATOM 1730 HG1 THR A 109 21.988 17.903 9.885 1.00 0.00 H ATOM 1731 HG21 THR A 109 21.981 18.855 7.696 1.00 0.00 H ATOM 1732 HG22 THR A 109 22.732 18.045 6.493 1.00 0.00 H ATOM 1733 HG23 THR A 109 21.339 17.467 7.122 1.00 0.00 H ATOM 1734 N GLY A 110 25.303 16.316 6.628 1.00 0.00 N ATOM 1735 CA GLY A 110 26.186 16.471 5.507 1.00 0.00 C ATOM 1736 C GLY A 110 26.097 15.287 4.577 1.00 0.00 C ATOM 1737 O GLY A 110 25.734 15.440 3.423 1.00 0.00 O ATOM 1738 H GLY A 110 25.644 16.539 7.541 1.00 0.00 H ATOM 1739 HA2 GLY A 110 27.125 16.555 5.840 1.00 0.00 H ATOM 1740 HA3 GLY A 110 25.935 17.299 5.006 1.00 0.00 H ATOM 1741 N VAL A 111 26.357 14.096 5.097 1.00 0.00 N ATOM 1742 CA VAL A 111 26.308 12.899 4.265 1.00 0.00 C ATOM 1743 C VAL A 111 24.964 12.621 3.636 1.00 0.00 C ATOM 1744 O VAL A 111 24.859 12.272 2.446 1.00 0.00 O ATOM 1745 CB VAL A 111 26.728 11.717 5.092 1.00 0.00 C ATOM 1746 CG1 VAL A 111 26.831 10.501 4.171 1.00 0.00 C ATOM 1747 CG2 VAL A 111 28.094 12.024 5.661 1.00 0.00 C ATOM 1748 H VAL A 111 26.588 14.017 6.067 1.00 0.00 H ATOM 1749 HA VAL A 111 26.975 13.010 3.528 1.00 0.00 H ATOM 1750 HB VAL A 111 26.070 11.549 5.826 1.00 0.00 H ATOM 1751 HG11 VAL A 111 27.110 9.702 4.704 1.00 0.00 H ATOM 1752 HG12 VAL A 111 25.941 10.326 3.749 1.00 0.00 H ATOM 1753 HG13 VAL A 111 27.509 10.679 3.458 1.00 0.00 H ATOM 1754 HG21 VAL A 111 28.403 11.254 6.219 1.00 0.00 H ATOM 1755 HG22 VAL A 111 28.740 12.175 4.913 1.00 0.00 H ATOM 1756 HG23 VAL A 111 28.042 12.846 6.228 1.00 0.00 H ATOM 1757 N ALA A 112 23.963 12.764 4.509 1.00 0.00 N ATOM 1758 CA ALA A 112 22.585 12.549 4.177 1.00 0.00 C ATOM 1759 C ALA A 112 22.174 13.272 2.886 1.00 0.00 C ATOM 1760 O ALA A 112 21.330 12.788 2.133 1.00 0.00 O ATOM 1761 CB ALA A 112 21.684 12.704 5.383 1.00 0.00 C ATOM 1762 H ALA A 112 24.187 13.036 5.445 1.00 0.00 H ATOM 1763 HA ALA A 112 22.531 11.577 3.948 1.00 0.00 H ATOM 1764 HB1 ALA A 112 20.734 12.547 5.112 1.00 0.00 H ATOM 1765 HB2 ALA A 112 21.945 12.039 6.082 1.00 0.00 H ATOM 1766 HB3 ALA A 112 21.777 13.629 5.752 1.00 0.00 H ATOM 1767 N GLY A 113 22.817 14.414 2.584 1.00 0.00 N ATOM 1768 CA GLY A 113 22.562 15.168 1.337 1.00 0.00 C ATOM 1769 C GLY A 113 23.180 14.581 0.055 1.00 0.00 C ATOM 1770 O GLY A 113 23.081 15.143 -1.047 1.00 0.00 O ATOM 1771 H GLY A 113 23.495 14.768 3.228 1.00 0.00 H ATOM 1772 HA2 GLY A 113 22.927 16.091 1.458 1.00 0.00 H ATOM 1773 HA3 GLY A 113 21.572 15.216 1.205 1.00 0.00 H ATOM 1774 N PHE A 114 23.995 13.532 0.164 1.00 0.00 N ATOM 1775 CA PHE A 114 24.597 12.897 -0.987 1.00 0.00 C ATOM 1776 C PHE A 114 23.680 11.810 -1.523 1.00 0.00 C ATOM 1777 O PHE A 114 24.096 10.705 -1.810 1.00 0.00 O ATOM 1778 CB PHE A 114 25.859 12.201 -0.532 1.00 0.00 C ATOM 1779 CG PHE A 114 27.048 13.118 -0.410 1.00 0.00 C ATOM 1780 CD1 PHE A 114 27.038 14.220 0.450 1.00 0.00 C ATOM 1781 CD2 PHE A 114 28.190 12.875 -1.169 1.00 0.00 C ATOM 1782 CE1 PHE A 114 28.143 15.066 0.554 1.00 0.00 C ATOM 1783 CE2 PHE A 114 29.297 13.718 -1.090 1.00 0.00 C ATOM 1784 CZ PHE A 114 29.279 14.807 -0.210 1.00 0.00 C ATOM 1785 H PHE A 114 24.197 13.171 1.074 1.00 0.00 H ATOM 1786 HA PHE A 114 24.801 13.571 -1.697 1.00 0.00 H ATOM 1787 HB2 PHE A 114 26.080 11.484 -1.193 1.00 0.00 H ATOM 1788 HB3 PHE A 114 25.686 11.788 0.362 1.00 0.00 H ATOM 1789 HD1 PHE A 114 26.224 14.406 1.001 1.00 0.00 H ATOM 1790 HD2 PHE A 114 28.216 12.084 -1.780 1.00 0.00 H ATOM 1791 HE1 PHE A 114 28.120 15.852 1.172 1.00 0.00 H ATOM 1792 HE2 PHE A 114 30.101 13.546 -1.659 1.00 0.00 H ATOM 1793 HZ PHE A 114 30.081 15.399 -0.130 1.00 0.00 H ATOM 1794 N THR A 115 22.425 12.135 -1.608 1.00 0.00 N ATOM 1795 CA THR A 115 21.377 11.253 -2.029 1.00 0.00 C ATOM 1796 C THR A 115 21.708 10.398 -3.199 1.00 0.00 C ATOM 1797 O THR A 115 21.553 9.198 -3.138 1.00 0.00 O ATOM 1798 CB THR A 115 20.161 12.081 -2.431 1.00 0.00 C ATOM 1799 CG2 THR A 115 19.008 11.149 -2.788 1.00 0.00 C ATOM 1800 OG1 THR A 115 19.804 12.910 -1.382 1.00 0.00 O ATOM 1801 H THR A 115 22.171 13.070 -1.361 1.00 0.00 H ATOM 1802 HA THR A 115 21.125 10.664 -1.261 1.00 0.00 H ATOM 1803 HB THR A 115 20.392 12.639 -3.228 1.00 0.00 H ATOM 1804 HG1 THR A 115 19.581 12.356 -0.580 1.00 0.00 H ATOM 1805 HG21 THR A 115 18.210 11.691 -3.052 1.00 0.00 H ATOM 1806 HG22 THR A 115 19.278 10.561 -3.551 1.00 0.00 H ATOM 1807 HG23 THR A 115 18.779 10.583 -1.996 1.00 0.00 H ATOM 1808 N ASN A 116 22.097 11.033 -4.290 1.00 0.00 N ATOM 1809 CA ASN A 116 22.437 10.262 -5.487 1.00 0.00 C ATOM 1810 C ASN A 116 23.567 9.243 -5.317 1.00 0.00 C ATOM 1811 O ASN A 116 23.509 8.116 -5.796 1.00 0.00 O ATOM 1812 CB ASN A 116 22.662 11.135 -6.745 1.00 0.00 C ATOM 1813 CG ASN A 116 21.484 12.062 -6.992 1.00 0.00 C ATOM 1814 ND2 ASN A 116 21.771 13.310 -7.345 1.00 0.00 N ATOM 1815 OD1 ASN A 116 20.321 11.676 -6.853 1.00 0.00 O ATOM 1816 H ASN A 116 22.159 12.031 -4.298 1.00 0.00 H ATOM 1817 HA ASN A 116 21.622 9.718 -5.688 1.00 0.00 H ATOM 1818 HB2 ASN A 116 22.779 10.538 -7.539 1.00 0.00 H ATOM 1819 HB3 ASN A 116 23.488 11.685 -6.617 1.00 0.00 H ATOM 1820 HD21 ASN A 116 22.724 13.593 -7.450 1.00 0.00 H ATOM 1821 HD22 ASN A 116 21.034 13.966 -7.506 1.00 0.00 H ATOM 1822 N SER A 117 24.651 9.648 -4.641 1.00 0.00 N ATOM 1823 CA SER A 117 25.762 8.725 -4.415 1.00 0.00 C ATOM 1824 C SER A 117 25.289 7.572 -3.536 1.00 0.00 C ATOM 1825 O SER A 117 25.709 6.442 -3.723 1.00 0.00 O ATOM 1826 CB SER A 117 26.918 9.386 -3.675 1.00 0.00 C ATOM 1827 OG SER A 117 27.319 10.605 -4.289 1.00 0.00 O ATOM 1828 H SER A 117 24.700 10.583 -4.291 1.00 0.00 H ATOM 1829 HA SER A 117 26.085 8.368 -5.291 1.00 0.00 H ATOM 1830 HB2 SER A 117 27.696 8.758 -3.666 1.00 0.00 H ATOM 1831 HB3 SER A 117 26.633 9.577 -2.736 1.00 0.00 H ATOM 1832 HG SER A 117 26.749 10.777 -5.092 1.00 0.00 H ATOM 1833 N LEU A 118 24.455 7.904 -2.537 1.00 0.00 N ATOM 1834 CA LEU A 118 23.915 6.932 -1.603 1.00 0.00 C ATOM 1835 C LEU A 118 23.157 5.816 -2.353 1.00 0.00 C ATOM 1836 O LEU A 118 23.346 4.623 -2.123 1.00 0.00 O ATOM 1837 CB LEU A 118 23.055 7.570 -0.462 1.00 0.00 C ATOM 1838 CG LEU A 118 23.805 8.477 0.545 1.00 0.00 C ATOM 1839 CD1 LEU A 118 22.820 9.096 1.552 1.00 0.00 C ATOM 1840 CD2 LEU A 118 24.871 7.716 1.305 1.00 0.00 C ATOM 1841 H LEU A 118 24.194 8.864 -2.432 1.00 0.00 H ATOM 1842 HA LEU A 118 24.699 6.496 -1.160 1.00 0.00 H ATOM 1843 HB2 LEU A 118 22.635 6.824 0.055 1.00 0.00 H ATOM 1844 HB3 LEU A 118 22.340 8.121 -0.892 1.00 0.00 H ATOM 1845 HG LEU A 118 24.246 9.217 0.037 1.00 0.00 H ATOM 1846 HD11 LEU A 118 23.320 9.677 2.193 1.00 0.00 H ATOM 1847 HD12 LEU A 118 22.144 9.646 1.062 1.00 0.00 H ATOM 1848 HD13 LEU A 118 22.356 8.367 2.055 1.00 0.00 H ATOM 1849 HD21 LEU A 118 25.331 8.334 1.943 1.00 0.00 H ATOM 1850 HD22 LEU A 118 24.447 6.967 1.814 1.00 0.00 H ATOM 1851 HD23 LEU A 118 25.539 7.345 0.660 1.00 0.00 H ATOM 1852 N ARG A 119 22.328 6.218 -3.268 1.00 0.00 N ATOM 1853 CA ARG A 119 21.559 5.277 -4.064 1.00 0.00 C ATOM 1854 C ARG A 119 22.499 4.404 -4.862 1.00 0.00 C ATOM 1855 O ARG A 119 22.321 3.185 -4.994 1.00 0.00 O ATOM 1856 CB ARG A 119 20.652 6.054 -5.001 1.00 0.00 C ATOM 1857 CG ARG A 119 19.692 5.215 -5.805 1.00 0.00 C ATOM 1858 CD ARG A 119 18.812 6.103 -6.691 1.00 0.00 C ATOM 1859 NE ARG A 119 19.436 6.395 -7.989 1.00 0.00 N ATOM 1860 CZ ARG A 119 20.063 7.534 -8.323 1.00 0.00 C ATOM 1861 NH1 ARG A 119 20.176 8.571 -7.491 1.00 0.00 N1+ ATOM 1862 NH2 ARG A 119 20.590 7.621 -9.552 1.00 0.00 N ATOM 1863 H ARG A 119 22.216 7.199 -3.429 1.00 0.00 H ATOM 1864 HA ARG A 119 21.004 4.705 -3.460 1.00 0.00 H ATOM 1865 HB2 ARG A 119 21.229 6.562 -5.640 1.00 0.00 H ATOM 1866 HB3 ARG A 119 20.117 6.696 -4.452 1.00 0.00 H ATOM 1867 HG2 ARG A 119 19.110 4.693 -5.182 1.00 0.00 H ATOM 1868 HG3 ARG A 119 20.211 4.585 -6.383 1.00 0.00 H ATOM 1869 HD2 ARG A 119 18.644 6.966 -6.214 1.00 0.00 H ATOM 1870 HD3 ARG A 119 17.942 5.636 -6.851 1.00 0.00 H ATOM 1871 HE ARG A 119 19.389 5.680 -8.687 1.00 0.00 H ATOM 1872 HH11 ARG A 119 20.653 9.399 -7.786 1.00 0.00 H ATOM 1873 HH12 ARG A 119 19.784 8.520 -6.573 1.00 0.00 H ATOM 1874 HH21 ARG A 119 21.064 8.455 -9.835 1.00 0.00 H ATOM 1875 HH22 ARG A 119 20.509 6.852 -10.186 1.00 0.00 H ATOM 1876 N MET A 120 23.540 5.042 -5.402 1.00 0.00 N ATOM 1877 CA MET A 120 24.487 4.278 -6.166 1.00 0.00 C ATOM 1878 C MET A 120 25.257 3.292 -5.298 1.00 0.00 C ATOM 1879 O MET A 120 25.527 2.163 -5.684 1.00 0.00 O ATOM 1880 CB MET A 120 25.459 5.106 -7.024 1.00 0.00 C ATOM 1881 CG MET A 120 24.814 5.829 -8.186 1.00 0.00 C ATOM 1882 SD MET A 120 25.972 7.091 -8.810 1.00 0.00 S ATOM 1883 CE MET A 120 24.874 8.392 -9.376 1.00 0.00 C ATOM 1884 H MET A 120 23.658 6.027 -5.278 1.00 0.00 H ATOM 1885 HA MET A 120 23.950 3.727 -6.805 1.00 0.00 H ATOM 1886 HB2 MET A 120 26.156 4.489 -7.389 1.00 0.00 H ATOM 1887 HB3 MET A 120 25.893 5.788 -6.434 1.00 0.00 H ATOM 1888 HG2 MET A 120 23.970 6.269 -7.881 1.00 0.00 H ATOM 1889 HG3 MET A 120 24.605 5.176 -8.914 1.00 0.00 H ATOM 1890 HE1 MET A 120 25.415 9.148 -9.745 1.00 0.00 H ATOM 1891 HE2 MET A 120 24.272 8.033 -10.090 1.00 0.00 H ATOM 1892 HE3 MET A 120 24.322 8.720 -8.609 1.00 0.00 H ATOM 1893 N LEU A 121 25.609 3.678 -4.115 1.00 0.00 N ATOM 1894 CA LEU A 121 26.303 2.724 -3.301 1.00 0.00 C ATOM 1895 C LEU A 121 25.384 1.542 -2.982 1.00 0.00 C ATOM 1896 O LEU A 121 25.783 0.380 -3.045 1.00 0.00 O ATOM 1897 CB LEU A 121 26.813 3.389 -2.014 1.00 0.00 C ATOM 1898 CG LEU A 121 27.977 4.377 -2.250 1.00 0.00 C ATOM 1899 CD1 LEU A 121 28.199 5.235 -0.997 1.00 0.00 C ATOM 1900 CD2 LEU A 121 29.275 3.619 -2.520 1.00 0.00 C ATOM 1901 H LEU A 121 25.406 4.599 -3.783 1.00 0.00 H ATOM 1902 HA LEU A 121 27.090 2.383 -3.815 1.00 0.00 H ATOM 1903 HB2 LEU A 121 27.127 2.673 -1.391 1.00 0.00 H ATOM 1904 HB3 LEU A 121 26.055 3.888 -1.594 1.00 0.00 H ATOM 1905 HG LEU A 121 27.764 4.967 -3.029 1.00 0.00 H ATOM 1906 HD11 LEU A 121 28.953 5.871 -1.158 1.00 0.00 H ATOM 1907 HD12 LEU A 121 27.366 5.750 -0.794 1.00 0.00 H ATOM 1908 HD13 LEU A 121 28.422 4.643 -0.223 1.00 0.00 H ATOM 1909 HD21 LEU A 121 30.017 4.272 -2.670 1.00 0.00 H ATOM 1910 HD22 LEU A 121 29.493 3.041 -1.733 1.00 0.00 H ATOM 1911 HD23 LEU A 121 29.164 3.047 -3.333 1.00 0.00 H ATOM 1912 N GLN A 122 24.141 1.872 -2.662 1.00 0.00 N ATOM 1913 CA GLN A 122 23.218 0.843 -2.309 1.00 0.00 C ATOM 1914 C GLN A 122 23.031 -0.161 -3.436 1.00 0.00 C ATOM 1915 O GLN A 122 22.839 -1.359 -3.222 1.00 0.00 O ATOM 1916 CB GLN A 122 21.906 1.412 -1.823 1.00 0.00 C ATOM 1917 CG GLN A 122 20.878 0.291 -1.655 1.00 0.00 C ATOM 1918 CD GLN A 122 19.752 0.635 -0.715 1.00 0.00 C ATOM 1919 NE2 GLN A 122 19.106 -0.400 -0.165 1.00 0.00 N ATOM 1920 OE1 GLN A 122 19.462 1.817 -0.494 1.00 0.00 O ATOM 1921 H GLN A 122 23.854 2.830 -2.668 1.00 0.00 H ATOM 1922 HA GLN A 122 23.620 0.345 -1.541 1.00 0.00 H ATOM 1923 HB2 GLN A 122 21.566 2.076 -2.489 1.00 0.00 H ATOM 1924 HB3 GLN A 122 22.048 1.866 -0.943 1.00 0.00 H ATOM 1925 HG2 GLN A 122 21.348 -0.518 -1.301 1.00 0.00 H ATOM 1926 HG3 GLN A 122 20.488 0.084 -2.552 1.00 0.00 H ATOM 1927 HE21 GLN A 122 19.385 -1.336 -0.381 1.00 0.00 H ATOM 1928 HE22 GLN A 122 18.344 -0.238 0.462 1.00 0.00 H ATOM 1929 N GLN A 123 23.122 0.323 -4.655 1.00 0.00 N ATOM 1930 CA GLN A 123 22.950 -0.563 -5.767 1.00 0.00 C ATOM 1931 C GLN A 123 24.230 -1.222 -6.136 1.00 0.00 C ATOM 1932 O GLN A 123 24.231 -1.960 -7.102 1.00 0.00 O ATOM 1933 CB GLN A 123 22.496 0.186 -7.011 1.00 0.00 C ATOM 1934 CG GLN A 123 21.113 0.864 -6.802 1.00 0.00 C ATOM 1935 CD GLN A 123 20.695 1.603 -8.065 1.00 0.00 C ATOM 1936 NE2 GLN A 123 20.435 0.846 -9.129 1.00 0.00 N ATOM 1937 OE1 GLN A 123 20.631 2.827 -8.105 1.00 0.00 O ATOM 1938 H GLN A 123 23.308 1.294 -4.803 1.00 0.00 H ATOM 1939 HA GLN A 123 22.273 -1.261 -5.534 1.00 0.00 H ATOM 1940 HB2 GLN A 123 22.429 -0.460 -7.771 1.00 0.00 H ATOM 1941 HB3 GLN A 123 23.172 0.890 -7.230 1.00 0.00 H ATOM 1942 HG2 GLN A 123 21.174 1.513 -6.044 1.00 0.00 H ATOM 1943 HG3 GLN A 123 20.431 0.165 -6.587 1.00 0.00 H ATOM 1944 HE21 GLN A 123 20.497 -0.150 -9.062 1.00 0.00 H ATOM 1945 HE22 GLN A 123 20.179 1.273 -9.996 1.00 0.00 H ATOM 1946 N LYS A 124 25.333 -0.904 -5.432 1.00 0.00 N ATOM 1947 CA LYS A 124 26.642 -1.497 -5.741 1.00 0.00 C ATOM 1948 C LYS A 124 27.236 -1.136 -7.086 1.00 0.00 C ATOM 1949 O LYS A 124 28.038 -1.891 -7.662 1.00 0.00 O ATOM 1950 CB LYS A 124 26.785 -3.007 -5.499 1.00 0.00 C ATOM 1951 CG LYS A 124 26.150 -3.432 -4.194 1.00 0.00 C ATOM 1952 CD LYS A 124 26.628 -4.764 -3.630 1.00 0.00 C ATOM 1953 CE LYS A 124 26.056 -5.005 -2.249 1.00 0.00 C ATOM 1954 NZ LYS A 124 26.723 -4.240 -1.184 1.00 0.00 N1+ ATOM 1955 H LYS A 124 25.260 -0.248 -4.681 1.00 0.00 H ATOM 1956 HA LYS A 124 27.264 -1.081 -5.077 1.00 0.00 H ATOM 1957 HB2 LYS A 124 27.757 -3.240 -5.476 1.00 0.00 H ATOM 1958 HB3 LYS A 124 26.342 -3.498 -6.249 1.00 0.00 H ATOM 1959 HG2 LYS A 124 25.163 -3.496 -4.339 1.00 0.00 H ATOM 1960 HG3 LYS A 124 26.341 -2.724 -3.514 1.00 0.00 H ATOM 1961 HD2 LYS A 124 27.626 -4.756 -3.574 1.00 0.00 H ATOM 1962 HD3 LYS A 124 26.335 -5.501 -4.239 1.00 0.00 H ATOM 1963 HE2 LYS A 124 26.142 -5.979 -2.038 1.00 0.00 H ATOM 1964 HE3 LYS A 124 25.089 -4.751 -2.260 1.00 0.00 H ATOM 1965 HZ1 LYS A 124 26.294 -4.449 -0.305 1.00 0.00 H ATOM 1966 HZ2 LYS A 124 27.691 -4.489 -1.150 1.00 0.00 H ATOM 1967 HZ3 LYS A 124 26.637 -3.262 -1.373 1.00 0.00 H ATOM 1968 N ARG A 125 26.931 0.051 -7.551 1.00 0.00 N ATOM 1969 CA ARG A 125 27.493 0.559 -8.783 1.00 0.00 C ATOM 1970 C ARG A 125 28.727 1.370 -8.364 1.00 0.00 C ATOM 1971 O ARG A 125 28.698 2.603 -8.244 1.00 0.00 O ATOM 1972 CB ARG A 125 26.447 1.436 -9.447 1.00 0.00 C ATOM 1973 CG ARG A 125 25.331 0.591 -10.060 1.00 0.00 C ATOM 1974 CD ARG A 125 24.077 1.407 -10.257 1.00 0.00 C ATOM 1975 NE ARG A 125 23.389 1.151 -11.525 1.00 0.00 N ATOM 1976 CZ ARG A 125 22.437 0.236 -11.710 1.00 0.00 C ATOM 1977 NH1 ARG A 125 22.050 -0.621 -10.737 1.00 0.00 N1+ ATOM 1978 NH2 ARG A 125 21.903 0.089 -12.914 1.00 0.00 N ATOM 1979 H ARG A 125 26.290 0.623 -7.038 1.00 0.00 H ATOM 1980 HA ARG A 125 27.755 -0.194 -9.387 1.00 0.00 H ATOM 1981 HB2 ARG A 125 26.882 1.975 -10.168 1.00 0.00 H ATOM 1982 HB3 ARG A 125 26.054 2.050 -8.763 1.00 0.00 H ATOM 1983 HG2 ARG A 125 25.129 -0.176 -9.450 1.00 0.00 H ATOM 1984 HG3 ARG A 125 25.635 0.241 -10.946 1.00 0.00 H ATOM 1985 HD2 ARG A 125 24.324 2.375 -10.224 1.00 0.00 H ATOM 1986 HD3 ARG A 125 23.446 1.198 -9.510 1.00 0.00 H ATOM 1987 HE ARG A 125 23.654 1.706 -12.313 1.00 0.00 H ATOM 1988 HH11 ARG A 125 21.331 -1.292 -10.919 1.00 0.00 H ATOM 1989 HH12 ARG A 125 22.483 -0.583 -9.836 1.00 0.00 H ATOM 1990 HH21 ARG A 125 21.188 -0.594 -13.064 1.00 0.00 H ATOM 1991 HH22 ARG A 125 22.215 0.661 -13.672 1.00 0.00 H ATOM 1992 N TRP A 126 29.811 0.656 -8.115 1.00 0.00 N ATOM 1993 CA TRP A 126 31.006 1.287 -7.578 1.00 0.00 C ATOM 1994 C TRP A 126 31.698 2.391 -8.338 1.00 0.00 C ATOM 1995 O TRP A 126 31.997 3.452 -7.791 1.00 0.00 O ATOM 1996 CB TRP A 126 31.972 0.365 -6.884 1.00 0.00 C ATOM 1997 CG TRP A 126 31.312 -0.804 -6.170 1.00 0.00 C ATOM 1998 CD1 TRP A 126 31.459 -2.091 -6.537 1.00 0.00 C ATOM 1999 CD2 TRP A 126 30.547 -0.799 -4.953 1.00 0.00 C ATOM 2000 CE2 TRP A 126 30.272 -2.151 -4.640 1.00 0.00 C ATOM 2001 CE3 TRP A 126 30.093 0.186 -4.059 1.00 0.00 C ATOM 2002 NE1 TRP A 126 30.849 -2.899 -5.641 1.00 0.00 N ATOM 2003 CZ2 TRP A 126 29.592 -2.521 -3.488 1.00 0.00 C ATOM 2004 CZ3 TRP A 126 29.371 -0.185 -2.949 1.00 0.00 C ATOM 2005 CH2 TRP A 126 29.121 -1.538 -2.661 1.00 0.00 C ATOM 2006 H TRP A 126 29.809 -0.327 -8.298 1.00 0.00 H ATOM 2007 HA TRP A 126 30.628 1.792 -6.802 1.00 0.00 H ATOM 2008 HB2 TRP A 126 32.484 0.897 -6.209 1.00 0.00 H ATOM 2009 HB3 TRP A 126 32.603 -0.001 -7.568 1.00 0.00 H ATOM 2010 HD1 TRP A 126 31.947 -2.403 -7.352 1.00 0.00 H ATOM 2011 HE1 TRP A 126 30.821 -3.897 -5.697 1.00 0.00 H ATOM 2012 HE3 TRP A 126 30.294 1.151 -4.229 1.00 0.00 H ATOM 2013 HZ2 TRP A 126 29.449 -3.486 -3.267 1.00 0.00 H ATOM 2014 HZ3 TRP A 126 29.017 0.521 -2.335 1.00 0.00 H ATOM 2015 HH2 TRP A 126 28.596 -1.784 -1.846 1.00 0.00 H ATOM 2016 N ASP A 127 32.033 2.125 -9.566 1.00 0.00 N ATOM 2017 CA ASP A 127 32.673 3.158 -10.326 1.00 0.00 C ATOM 2018 C ASP A 127 31.775 4.365 -10.441 1.00 0.00 C ATOM 2019 O ASP A 127 32.223 5.481 -10.293 1.00 0.00 O ATOM 2020 CB ASP A 127 33.022 2.647 -11.709 1.00 0.00 C ATOM 2021 CG ASP A 127 34.252 1.767 -11.655 1.00 0.00 C ATOM 2022 OD1 ASP A 127 34.591 1.122 -10.684 1.00 0.00 O ATOM 2023 OD2 ASP A 127 34.975 1.827 -12.747 1.00 0.00 O1- ATOM 2024 H ASP A 127 31.850 1.228 -9.968 1.00 0.00 H ATOM 2025 HA ASP A 127 33.516 3.426 -9.859 1.00 0.00 H ATOM 2026 HB2 ASP A 127 33.200 3.425 -12.312 1.00 0.00 H ATOM 2027 HB3 ASP A 127 32.254 2.117 -12.067 1.00 0.00 H ATOM 2028 N GLU A 128 30.485 4.147 -10.667 1.00 0.00 N ATOM 2029 CA GLU A 128 29.597 5.285 -10.773 1.00 0.00 C ATOM 2030 C GLU A 128 29.506 6.124 -9.527 1.00 0.00 C ATOM 2031 O GLU A 128 29.475 7.348 -9.579 1.00 0.00 O ATOM 2032 CB GLU A 128 28.218 4.853 -11.254 1.00 0.00 C ATOM 2033 CG GLU A 128 28.393 4.177 -12.624 1.00 0.00 C ATOM 2034 CD GLU A 128 27.200 3.402 -13.093 1.00 0.00 C ATOM 2035 OE1 GLU A 128 26.112 4.134 -13.170 1.00 0.00 O ATOM 2036 OE2 GLU A 128 27.257 2.230 -13.425 1.00 0.00 O1- ATOM 2037 H GLU A 128 30.134 3.215 -10.762 1.00 0.00 H ATOM 2038 HA GLU A 128 29.975 5.875 -11.486 1.00 0.00 H ATOM 2039 HB2 GLU A 128 27.622 5.651 -11.341 1.00 0.00 H ATOM 2040 HB3 GLU A 128 27.817 4.207 -10.604 1.00 0.00 H ATOM 2041 HG2 GLU A 128 29.169 3.550 -12.565 1.00 0.00 H ATOM 2042 HG3 GLU A 128 28.589 4.888 -13.300 1.00 0.00 H ATOM 2043 N ALA A 129 29.447 5.458 -8.406 1.00 0.00 N ATOM 2044 CA ALA A 129 29.333 6.189 -7.175 1.00 0.00 C ATOM 2045 C ALA A 129 30.585 7.018 -6.962 1.00 0.00 C ATOM 2046 O ALA A 129 30.532 8.158 -6.530 1.00 0.00 O ATOM 2047 CB ALA A 129 29.154 5.214 -6.016 1.00 0.00 C ATOM 2048 H ALA A 129 29.481 4.459 -8.404 1.00 0.00 H ATOM 2049 HA ALA A 129 28.539 6.795 -7.223 1.00 0.00 H ATOM 2050 HB1 ALA A 129 29.075 5.725 -5.160 1.00 0.00 H ATOM 2051 HB2 ALA A 129 28.325 4.674 -6.160 1.00 0.00 H ATOM 2052 HB3 ALA A 129 29.945 4.604 -5.968 1.00 0.00 H ATOM 2053 N ALA A 130 31.719 6.422 -7.307 1.00 0.00 N ATOM 2054 CA ALA A 130 33.001 7.077 -7.118 1.00 0.00 C ATOM 2055 C ALA A 130 33.049 8.379 -7.884 1.00 0.00 C ATOM 2056 O ALA A 130 33.534 9.400 -7.396 1.00 0.00 O ATOM 2057 CB ALA A 130 34.177 6.172 -7.526 1.00 0.00 C ATOM 2058 H ALA A 130 31.690 5.505 -7.704 1.00 0.00 H ATOM 2059 HA ALA A 130 33.098 7.288 -6.145 1.00 0.00 H ATOM 2060 HB1 ALA A 130 35.038 6.659 -7.381 1.00 0.00 H ATOM 2061 HB2 ALA A 130 34.166 5.341 -6.970 1.00 0.00 H ATOM 2062 HB3 ALA A 130 34.091 5.928 -8.492 1.00 0.00 H ATOM 2063 N VAL A 131 32.547 8.324 -9.108 1.00 0.00 N ATOM 2064 CA VAL A 131 32.512 9.491 -9.950 1.00 0.00 C ATOM 2065 C VAL A 131 31.571 10.535 -9.338 1.00 0.00 C ATOM 2066 O VAL A 131 31.939 11.694 -9.199 1.00 0.00 O ATOM 2067 CB VAL A 131 32.140 9.126 -11.415 1.00 0.00 C ATOM 2068 CG1 VAL A 131 31.731 10.329 -12.214 1.00 0.00 C ATOM 2069 CG2 VAL A 131 33.328 8.465 -12.117 1.00 0.00 C ATOM 2070 H VAL A 131 32.186 7.458 -9.453 1.00 0.00 H ATOM 2071 HA VAL A 131 33.432 9.883 -9.961 1.00 0.00 H ATOM 2072 HB VAL A 131 31.378 8.479 -11.399 1.00 0.00 H ATOM 2073 HG11 VAL A 131 31.502 10.048 -13.146 1.00 0.00 H ATOM 2074 HG12 VAL A 131 30.933 10.756 -11.789 1.00 0.00 H ATOM 2075 HG13 VAL A 131 32.486 10.984 -12.240 1.00 0.00 H ATOM 2076 HG21 VAL A 131 33.075 8.236 -13.057 1.00 0.00 H ATOM 2077 HG22 VAL A 131 34.104 9.096 -12.125 1.00 0.00 H ATOM 2078 HG23 VAL A 131 33.582 7.631 -11.628 1.00 0.00 H ATOM 2079 N ASN A 132 30.381 10.120 -8.922 1.00 0.00 N ATOM 2080 CA ASN A 132 29.429 11.043 -8.347 1.00 0.00 C ATOM 2081 C ASN A 132 29.941 11.631 -7.031 1.00 0.00 C ATOM 2082 O ASN A 132 29.747 12.793 -6.695 1.00 0.00 O ATOM 2083 CB ASN A 132 28.077 10.372 -8.139 1.00 0.00 C ATOM 2084 CG ASN A 132 26.999 11.333 -7.676 1.00 0.00 C ATOM 2085 ND2 ASN A 132 26.390 11.964 -8.650 1.00 0.00 N ATOM 2086 OD1 ASN A 132 26.783 11.565 -6.470 1.00 0.00 O ATOM 2087 H ASN A 132 30.139 9.153 -9.008 1.00 0.00 H ATOM 2088 HA ASN A 132 29.303 11.796 -8.992 1.00 0.00 H ATOM 2089 HB2 ASN A 132 28.181 9.655 -7.450 1.00 0.00 H ATOM 2090 HB3 ASN A 132 27.788 9.963 -9.005 1.00 0.00 H ATOM 2091 HD21 ASN A 132 26.601 11.738 -9.601 1.00 0.00 H ATOM 2092 HD22 ASN A 132 25.714 12.671 -8.442 1.00 0.00 H ATOM 2093 N LEU A 133 30.619 10.839 -6.241 1.00 0.00 N ATOM 2094 CA LEU A 133 31.072 11.360 -4.966 1.00 0.00 C ATOM 2095 C LEU A 133 32.052 12.534 -5.152 1.00 0.00 C ATOM 2096 O LEU A 133 32.141 13.426 -4.319 1.00 0.00 O ATOM 2097 CB LEU A 133 31.765 10.268 -4.071 1.00 0.00 C ATOM 2098 CG LEU A 133 30.822 9.280 -3.348 1.00 0.00 C ATOM 2099 CD1 LEU A 133 31.637 8.091 -2.819 1.00 0.00 C ATOM 2100 CD2 LEU A 133 30.133 9.963 -2.183 1.00 0.00 C ATOM 2101 H LEU A 133 30.820 9.897 -6.510 1.00 0.00 H ATOM 2102 HA LEU A 133 30.273 11.702 -4.471 1.00 0.00 H ATOM 2103 HB2 LEU A 133 32.303 10.741 -3.374 1.00 0.00 H ATOM 2104 HB3 LEU A 133 32.374 9.734 -4.658 1.00 0.00 H ATOM 2105 HG LEU A 133 30.133 8.949 -3.992 1.00 0.00 H ATOM 2106 HD11 LEU A 133 31.028 7.451 -2.351 1.00 0.00 H ATOM 2107 HD12 LEU A 133 32.084 7.627 -3.584 1.00 0.00 H ATOM 2108 HD13 LEU A 133 32.330 8.421 -2.178 1.00 0.00 H ATOM 2109 HD21 LEU A 133 29.527 9.312 -1.726 1.00 0.00 H ATOM 2110 HD22 LEU A 133 30.820 10.291 -1.535 1.00 0.00 H ATOM 2111 HD23 LEU A 133 29.597 10.737 -2.520 1.00 0.00 H ATOM 2112 N ALA A 134 32.835 12.481 -6.229 1.00 0.00 N ATOM 2113 CA ALA A 134 33.864 13.477 -6.512 1.00 0.00 C ATOM 2114 C ALA A 134 33.310 14.861 -6.863 1.00 0.00 C ATOM 2115 O ALA A 134 33.984 15.895 -6.728 1.00 0.00 O ATOM 2116 CB ALA A 134 34.896 12.944 -7.534 1.00 0.00 C ATOM 2117 H ALA A 134 32.712 11.725 -6.872 1.00 0.00 H ATOM 2118 HA ALA A 134 34.368 13.596 -5.656 1.00 0.00 H ATOM 2119 HB1 ALA A 134 35.586 13.646 -7.708 1.00 0.00 H ATOM 2120 HB2 ALA A 134 35.338 12.126 -7.166 1.00 0.00 H ATOM 2121 HB3 ALA A 134 34.431 12.715 -8.389 1.00 0.00 H ATOM 2122 N LYS A 135 32.059 14.900 -7.291 1.00 0.00 N ATOM 2123 CA LYS A 135 31.394 16.158 -7.631 1.00 0.00 C ATOM 2124 C LYS A 135 30.821 16.786 -6.414 1.00 0.00 C ATOM 2125 O LYS A 135 29.636 16.840 -6.241 1.00 0.00 O ATOM 2126 CB LYS A 135 30.232 15.925 -8.550 1.00 0.00 C ATOM 2127 CG LYS A 135 30.729 15.180 -9.767 1.00 0.00 C ATOM 2128 CD LYS A 135 29.707 15.250 -10.878 1.00 0.00 C ATOM 2129 CE LYS A 135 30.268 14.629 -12.133 1.00 0.00 C ATOM 2130 NZ LYS A 135 29.221 13.906 -12.876 1.00 0.00 N1+ ATOM 2131 H LYS A 135 31.552 14.043 -7.385 1.00 0.00 H ATOM 2132 HA LYS A 135 32.047 16.782 -8.060 1.00 0.00 H ATOM 2133 HB2 LYS A 135 29.840 16.802 -8.828 1.00 0.00 H ATOM 2134 HB3 LYS A 135 29.535 15.381 -8.082 1.00 0.00 H ATOM 2135 HG2 LYS A 135 30.889 14.223 -9.525 1.00 0.00 H ATOM 2136 HG3 LYS A 135 31.585 15.592 -10.079 1.00 0.00 H ATOM 2137 HD2 LYS A 135 29.476 16.207 -11.056 1.00 0.00 H ATOM 2138 HD3 LYS A 135 28.883 14.754 -10.602 1.00 0.00 H ATOM 2139 HE2 LYS A 135 30.995 13.988 -11.885 1.00 0.00 H ATOM 2140 HE3 LYS A 135 30.644 15.350 -12.715 1.00 0.00 H ATOM 2141 HZ1 LYS A 135 29.616 13.504 -13.702 1.00 0.00 H ATOM 2142 HZ2 LYS A 135 28.844 13.181 -12.300 1.00 0.00 H ATOM 2143 HZ3 LYS A 135 28.493 14.543 -13.130 1.00 0.00 H ATOM 2144 N SER A 136 31.706 17.232 -5.565 1.00 0.00 N ATOM 2145 CA SER A 136 31.249 17.745 -4.320 1.00 0.00 C ATOM 2146 C SER A 136 32.250 18.739 -3.748 1.00 0.00 C ATOM 2147 O SER A 136 33.467 18.734 -4.007 1.00 0.00 O ATOM 2148 CB SER A 136 31.089 16.565 -3.359 1.00 0.00 C ATOM 2149 OG SER A 136 32.387 15.944 -3.189 1.00 0.00 O ATOM 2150 H SER A 136 32.681 17.213 -5.785 1.00 0.00 H ATOM 2151 HA SER A 136 30.365 18.195 -4.447 1.00 0.00 H ATOM 2152 HB2 SER A 136 30.444 15.903 -3.740 1.00 0.00 H ATOM 2153 HB3 SER A 136 30.751 16.890 -2.476 1.00 0.00 H ATOM 2154 HG SER A 136 32.342 14.991 -3.488 1.00 0.00 H ATOM 2155 N ARG A 137 31.716 19.611 -2.929 1.00 0.00 N ATOM 2156 CA ARG A 137 32.553 20.556 -2.228 1.00 0.00 C ATOM 2157 C ARG A 137 33.602 19.794 -1.424 1.00 0.00 C ATOM 2158 O ARG A 137 34.759 20.185 -1.380 1.00 0.00 O ATOM 2159 CB ARG A 137 31.707 21.412 -1.270 1.00 0.00 C ATOM 2160 CG ARG A 137 32.595 22.160 -0.276 1.00 0.00 C ATOM 2161 CD ARG A 137 31.900 23.308 0.450 1.00 0.00 C ATOM 2162 NE ARG A 137 32.838 24.218 1.141 1.00 0.00 N ATOM 2163 CZ ARG A 137 33.555 23.938 2.247 1.00 0.00 C ATOM 2164 NH1 ARG A 137 33.510 22.756 2.860 1.00 0.00 N1+ ATOM 2165 NH2 ARG A 137 34.361 24.872 2.747 1.00 0.00 N ATOM 2166 H ARG A 137 30.726 19.622 -2.789 1.00 0.00 H ATOM 2167 HA ARG A 137 33.009 21.151 -2.890 1.00 0.00 H ATOM 2168 HB2 ARG A 137 31.081 20.817 -0.766 1.00 0.00 H ATOM 2169 HB3 ARG A 137 31.181 22.075 -1.802 1.00 0.00 H ATOM 2170 HG2 ARG A 137 33.377 22.533 -0.775 1.00 0.00 H ATOM 2171 HG3 ARG A 137 32.917 21.506 0.409 1.00 0.00 H ATOM 2172 HD2 ARG A 137 31.275 22.922 1.128 1.00 0.00 H ATOM 2173 HD3 ARG A 137 31.379 23.838 -0.220 1.00 0.00 H ATOM 2174 HE ARG A 137 32.952 25.131 0.749 1.00 0.00 H ATOM 2175 HH11 ARG A 137 34.061 22.596 3.679 1.00 0.00 H ATOM 2176 HH12 ARG A 137 32.925 22.029 2.501 1.00 0.00 H ATOM 2177 HH21 ARG A 137 34.900 24.680 3.567 1.00 0.00 H ATOM 2178 HH22 ARG A 137 34.427 25.765 2.302 1.00 0.00 H ATOM 2179 N TRP A 138 33.156 18.686 -0.754 1.00 0.00 N ATOM 2180 CA TRP A 138 33.983 17.803 0.061 1.00 0.00 C ATOM 2181 C TRP A 138 35.270 17.410 -0.666 1.00 0.00 C ATOM 2182 O TRP A 138 36.380 17.568 -0.169 1.00 0.00 O ATOM 2183 CB TRP A 138 33.179 16.513 0.353 1.00 0.00 C ATOM 2184 CG TRP A 138 33.953 15.389 0.968 1.00 0.00 C ATOM 2185 CD1 TRP A 138 34.652 15.431 2.133 1.00 0.00 C ATOM 2186 CD2 TRP A 138 33.952 14.006 0.530 1.00 0.00 C ATOM 2187 CE2 TRP A 138 34.739 13.288 1.457 1.00 0.00 C ATOM 2188 CE3 TRP A 138 33.421 13.362 -0.556 1.00 0.00 C ATOM 2189 NE1 TRP A 138 35.172 14.178 2.412 1.00 0.00 N ATOM 2190 CZ2 TRP A 138 34.936 11.905 1.333 1.00 0.00 C ATOM 2191 CZ3 TRP A 138 33.622 11.998 -0.696 1.00 0.00 C ATOM 2192 CH2 TRP A 138 34.375 11.286 0.238 1.00 0.00 C ATOM 2193 H TRP A 138 32.184 18.464 -0.830 1.00 0.00 H ATOM 2194 HA TRP A 138 34.210 18.258 0.922 1.00 0.00 H ATOM 2195 HB2 TRP A 138 32.798 16.186 -0.512 1.00 0.00 H ATOM 2196 HB3 TRP A 138 32.434 16.750 0.977 1.00 0.00 H ATOM 2197 HD1 TRP A 138 34.773 16.244 2.703 1.00 0.00 H ATOM 2198 HE1 TRP A 138 35.767 13.956 3.184 1.00 0.00 H ATOM 2199 HE3 TRP A 138 32.895 13.869 -1.239 1.00 0.00 H ATOM 2200 HZ2 TRP A 138 35.461 11.390 2.011 1.00 0.00 H ATOM 2201 HZ3 TRP A 138 33.222 11.518 -1.477 1.00 0.00 H ATOM 2202 HH2 TRP A 138 34.511 10.304 0.109 1.00 0.00 H ATOM 2203 N TYR A 139 35.099 16.946 -1.898 1.00 0.00 N ATOM 2204 CA TYR A 139 36.191 16.538 -2.715 1.00 0.00 C ATOM 2205 C TYR A 139 37.040 17.700 -3.080 1.00 0.00 C ATOM 2206 O TYR A 139 38.249 17.600 -3.104 1.00 0.00 O ATOM 2207 CB TYR A 139 35.680 15.974 -4.024 1.00 0.00 C ATOM 2208 CG TYR A 139 36.783 15.454 -4.903 1.00 0.00 C ATOM 2209 CD1 TYR A 139 37.310 14.184 -4.675 1.00 0.00 C ATOM 2210 CD2 TYR A 139 37.220 16.182 -6.006 1.00 0.00 C ATOM 2211 CE1 TYR A 139 38.266 13.637 -5.521 1.00 0.00 C ATOM 2212 CE2 TYR A 139 38.183 15.655 -6.868 1.00 0.00 C ATOM 2213 CZ TYR A 139 38.692 14.382 -6.619 1.00 0.00 C ATOM 2214 OH TYR A 139 39.652 13.867 -7.440 1.00 0.00 O ATOM 2215 H TYR A 139 34.171 16.881 -2.265 1.00 0.00 H ATOM 2216 HA TYR A 139 36.738 15.851 -2.237 1.00 0.00 H ATOM 2217 HB2 TYR A 139 35.193 16.697 -4.515 1.00 0.00 H ATOM 2218 HB3 TYR A 139 35.050 15.224 -3.824 1.00 0.00 H ATOM 2219 HD1 TYR A 139 36.994 13.656 -3.887 1.00 0.00 H ATOM 2220 HD2 TYR A 139 36.841 17.090 -6.182 1.00 0.00 H ATOM 2221 HE1 TYR A 139 38.641 12.727 -5.346 1.00 0.00 H ATOM 2222 HE2 TYR A 139 38.503 16.184 -7.654 1.00 0.00 H ATOM 2223 HH TYR A 139 39.967 14.391 -8.231 1.00 0.00 H ATOM 2224 N ASN A 140 36.417 18.806 -3.437 1.00 0.00 N ATOM 2225 CA ASN A 140 37.201 19.967 -3.824 1.00 0.00 C ATOM 2226 C ASN A 140 38.025 20.578 -2.692 1.00 0.00 C ATOM 2227 O ASN A 140 39.125 21.021 -2.934 1.00 0.00 O ATOM 2228 CB ASN A 140 36.354 21.017 -4.559 1.00 0.00 C ATOM 2229 CG ASN A 140 36.042 20.485 -5.925 1.00 0.00 C ATOM 2230 ND2 ASN A 140 34.839 19.934 -6.036 1.00 0.00 N ATOM 2231 OD1 ASN A 140 36.885 20.446 -6.835 1.00 0.00 O ATOM 2232 H ASN A 140 35.418 18.845 -3.441 1.00 0.00 H ATOM 2233 HA ASN A 140 37.865 19.635 -4.495 1.00 0.00 H ATOM 2234 HB2 ASN A 140 36.866 21.873 -4.637 1.00 0.00 H ATOM 2235 HB3 ASN A 140 35.505 21.181 -4.056 1.00 0.00 H ATOM 2236 HD21 ASN A 140 34.192 19.990 -5.276 1.00 0.00 H ATOM 2237 HD22 ASN A 140 34.581 19.463 -6.879 1.00 0.00 H ATOM 2238 N GLN A 141 37.516 20.570 -1.452 1.00 0.00 N ATOM 2239 CA GLN A 141 38.203 21.102 -0.286 1.00 0.00 C ATOM 2240 C GLN A 141 39.253 20.216 0.305 1.00 0.00 C ATOM 2241 O GLN A 141 40.294 20.718 0.733 1.00 0.00 O ATOM 2242 CB GLN A 141 37.273 21.534 0.843 1.00 0.00 C ATOM 2243 CG GLN A 141 36.270 22.605 0.363 1.00 0.00 C ATOM 2244 CD GLN A 141 36.919 23.835 -0.246 1.00 0.00 C ATOM 2245 NE2 GLN A 141 36.422 24.233 -1.416 1.00 0.00 N ATOM 2246 OE1 GLN A 141 37.821 24.493 0.328 1.00 0.00 O ATOM 2247 H GLN A 141 36.607 20.174 -1.321 1.00 0.00 H ATOM 2248 HA GLN A 141 38.675 21.929 -0.592 1.00 0.00 H ATOM 2249 HB2 GLN A 141 37.820 21.912 1.590 1.00 0.00 H ATOM 2250 HB3 GLN A 141 36.766 20.737 1.171 1.00 0.00 H ATOM 2251 HG2 GLN A 141 35.722 22.895 1.147 1.00 0.00 H ATOM 2252 HG3 GLN A 141 35.674 22.191 -0.325 1.00 0.00 H ATOM 2253 HE21 GLN A 141 35.703 23.699 -1.861 1.00 0.00 H ATOM 2254 HE22 GLN A 141 36.767 25.066 -1.849 1.00 0.00 H ATOM 2255 N THR A 142 38.962 18.920 0.414 1.00 0.00 N ATOM 2256 CA THR A 142 39.915 17.982 0.970 1.00 0.00 C ATOM 2257 C THR A 142 40.082 16.866 -0.006 1.00 0.00 C ATOM 2258 O THR A 142 39.735 15.731 0.268 1.00 0.00 O ATOM 2259 CB THR A 142 39.450 17.417 2.314 1.00 0.00 C ATOM 2260 CG2 THR A 142 39.581 18.539 3.361 1.00 0.00 C ATOM 2261 OG1 THR A 142 38.108 16.952 2.212 1.00 0.00 O ATOM 2262 H THR A 142 38.070 18.589 0.106 1.00 0.00 H ATOM 2263 HA THR A 142 40.794 18.443 1.095 1.00 0.00 H ATOM 2264 HB THR A 142 40.043 16.655 2.573 1.00 0.00 H ATOM 2265 HG1 THR A 142 38.056 16.233 1.519 1.00 0.00 H ATOM 2266 HG21 THR A 142 39.283 18.199 4.253 1.00 0.00 H ATOM 2267 HG22 THR A 142 40.535 18.832 3.418 1.00 0.00 H ATOM 2268 HG23 THR A 142 39.009 19.314 3.092 1.00 0.00 H ATOM 2269 N PRO A 143 40.673 17.176 -1.132 1.00 0.00 N ATOM 2270 CA PRO A 143 40.849 16.180 -2.176 1.00 0.00 C ATOM 2271 C PRO A 143 41.654 14.900 -1.835 1.00 0.00 C ATOM 2272 O PRO A 143 41.303 13.811 -2.251 1.00 0.00 O ATOM 2273 CB PRO A 143 41.511 16.906 -3.343 1.00 0.00 C ATOM 2274 CG PRO A 143 42.209 18.111 -2.727 1.00 0.00 C ATOM 2275 CD PRO A 143 41.437 18.425 -1.462 1.00 0.00 C ATOM 2276 HA PRO A 143 39.939 15.893 -2.476 1.00 0.00 H ATOM 2277 HB2 PRO A 143 42.175 16.310 -3.794 1.00 0.00 H ATOM 2278 HB3 PRO A 143 40.824 17.201 -4.006 1.00 0.00 H ATOM 2279 HG2 PRO A 143 43.160 17.891 -2.510 1.00 0.00 H ATOM 2280 HG3 PRO A 143 42.182 18.889 -3.355 1.00 0.00 H ATOM 2281 HD2 PRO A 143 42.065 18.656 -0.719 1.00 0.00 H ATOM 2282 HD3 PRO A 143 40.809 19.187 -1.617 1.00 0.00 H ATOM 2283 N ASN A 144 42.799 15.005 -1.150 1.00 0.00 N ATOM 2284 CA ASN A 144 43.556 13.795 -0.855 1.00 0.00 C ATOM 2285 C ASN A 144 42.808 12.837 0.071 1.00 0.00 C ATOM 2286 O ASN A 144 42.831 11.641 -0.107 1.00 0.00 O ATOM 2287 CB ASN A 144 44.967 14.078 -0.267 1.00 0.00 C ATOM 2288 CG ASN A 144 45.926 14.771 -1.247 1.00 0.00 C ATOM 2289 ND2 ASN A 144 46.778 15.613 -0.724 1.00 0.00 N ATOM 2290 OD1 ASN A 144 45.945 14.546 -2.466 1.00 0.00 O ATOM 2291 H ASN A 144 43.129 15.898 -0.846 1.00 0.00 H ATOM 2292 HA ASN A 144 43.692 13.316 -1.723 1.00 0.00 H ATOM 2293 HB2 ASN A 144 45.374 13.207 0.007 1.00 0.00 H ATOM 2294 HB3 ASN A 144 44.861 14.664 0.536 1.00 0.00 H ATOM 2295 HD21 ASN A 144 46.762 15.794 0.259 1.00 0.00 H ATOM 2296 HD22 ASN A 144 47.445 16.076 -1.307 1.00 0.00 H ATOM 2297 N ARG A 145 42.186 13.392 1.093 1.00 0.00 N ATOM 2298 CA ARG A 145 41.428 12.546 1.974 1.00 0.00 C ATOM 2299 C ARG A 145 40.192 11.985 1.244 1.00 0.00 C ATOM 2300 O ARG A 145 39.849 10.821 1.353 1.00 0.00 O ATOM 2301 CB ARG A 145 40.979 13.333 3.175 1.00 0.00 C ATOM 2302 CG ARG A 145 39.990 12.467 3.950 1.00 0.00 C ATOM 2303 CD ARG A 145 39.503 13.164 5.172 1.00 0.00 C ATOM 2304 NE ARG A 145 38.826 12.261 6.058 1.00 0.00 N ATOM 2305 CZ ARG A 145 38.629 12.673 7.282 1.00 0.00 C ATOM 2306 NH1 ARG A 145 39.095 13.860 7.620 1.00 0.00 N1+ ATOM 2307 NH2 ARG A 145 38.012 11.926 8.174 1.00 0.00 N ATOM 2308 H ARG A 145 42.240 14.378 1.251 1.00 0.00 H ATOM 2309 HA ARG A 145 42.004 11.786 2.276 1.00 0.00 H ATOM 2310 HB2 ARG A 145 40.534 14.179 2.881 1.00 0.00 H ATOM 2311 HB3 ARG A 145 41.765 13.553 3.752 1.00 0.00 H ATOM 2312 HG2 ARG A 145 40.442 11.617 4.218 1.00 0.00 H ATOM 2313 HG3 ARG A 145 39.209 12.258 3.361 1.00 0.00 H ATOM 2314 HD2 ARG A 145 38.870 13.890 4.902 1.00 0.00 H ATOM 2315 HD3 ARG A 145 40.284 13.564 5.651 1.00 0.00 H ATOM 2316 HE ARG A 145 38.520 11.359 5.753 1.00 0.00 H ATOM 2317 HH11 ARG A 145 38.960 14.204 8.549 1.00 0.00 H ATOM 2318 HH12 ARG A 145 39.583 14.416 6.947 1.00 0.00 H ATOM 2319 HH21 ARG A 145 37.875 12.268 9.104 1.00 0.00 H ATOM 2320 HH22 ARG A 145 37.680 11.017 7.922 1.00 0.00 H ATOM 2321 N ALA A 146 39.499 12.858 0.516 1.00 0.00 N ATOM 2322 CA ALA A 146 38.337 12.409 -0.243 1.00 0.00 C ATOM 2323 C ALA A 146 38.711 11.249 -1.164 1.00 0.00 C ATOM 2324 O ALA A 146 38.004 10.253 -1.233 1.00 0.00 O ATOM 2325 CB ALA A 146 37.757 13.567 -1.063 1.00 0.00 C ATOM 2326 H ALA A 146 39.774 13.819 0.490 1.00 0.00 H ATOM 2327 HA ALA A 146 37.639 12.093 0.400 1.00 0.00 H ATOM 2328 HB1 ALA A 146 36.962 13.246 -1.578 1.00 0.00 H ATOM 2329 HB2 ALA A 146 37.480 14.305 -0.448 1.00 0.00 H ATOM 2330 HB3 ALA A 146 38.451 13.906 -1.698 1.00 0.00 H ATOM 2331 N LYS A 147 39.833 11.397 -1.895 1.00 0.00 N ATOM 2332 CA LYS A 147 40.311 10.381 -2.802 1.00 0.00 C ATOM 2333 C LYS A 147 40.505 9.058 -2.106 1.00 0.00 C ATOM 2334 O LYS A 147 40.250 7.993 -2.676 1.00 0.00 O ATOM 2335 CB LYS A 147 41.649 10.731 -3.384 1.00 0.00 C ATOM 2336 CG LYS A 147 41.498 11.406 -4.714 1.00 0.00 C ATOM 2337 CD LYS A 147 42.645 12.334 -5.052 1.00 0.00 C ATOM 2338 CE LYS A 147 42.130 13.565 -5.758 1.00 0.00 C ATOM 2339 NZ LYS A 147 43.173 14.548 -6.053 1.00 0.00 N1+ ATOM 2340 H LYS A 147 40.356 12.245 -1.806 1.00 0.00 H ATOM 2341 HA LYS A 147 39.650 10.267 -3.544 1.00 0.00 H ATOM 2342 HB2 LYS A 147 42.183 9.894 -3.501 1.00 0.00 H ATOM 2343 HB3 LYS A 147 42.127 11.347 -2.757 1.00 0.00 H ATOM 2344 HG2 LYS A 147 40.652 11.939 -4.705 1.00 0.00 H ATOM 2345 HG3 LYS A 147 41.441 10.702 -5.422 1.00 0.00 H ATOM 2346 HD2 LYS A 147 43.291 11.857 -5.648 1.00 0.00 H ATOM 2347 HD3 LYS A 147 43.109 12.607 -4.209 1.00 0.00 H ATOM 2348 HE2 LYS A 147 41.442 13.999 -5.177 1.00 0.00 H ATOM 2349 HE3 LYS A 147 41.708 13.283 -6.620 1.00 0.00 H ATOM 2350 HZ1 LYS A 147 42.768 15.335 -6.518 1.00 0.00 H ATOM 2351 HZ2 LYS A 147 43.599 14.849 -5.200 1.00 0.00 H ATOM 2352 HZ3 LYS A 147 43.865 14.132 -6.643 1.00 0.00 H ATOM 2353 N ARG A 148 41.020 9.142 -0.888 1.00 0.00 N ATOM 2354 CA ARG A 148 41.256 7.910 -0.098 1.00 0.00 C ATOM 2355 C ARG A 148 39.972 7.156 0.231 1.00 0.00 C ATOM 2356 O ARG A 148 39.879 5.947 0.022 1.00 0.00 O ATOM 2357 CB ARG A 148 42.067 8.179 1.172 1.00 0.00 C ATOM 2358 CG ARG A 148 43.579 8.274 0.901 1.00 0.00 C ATOM 2359 CD ARG A 148 44.356 8.219 2.187 1.00 0.00 C ATOM 2360 NE ARG A 148 43.993 9.279 3.111 1.00 0.00 N ATOM 2361 CZ ARG A 148 44.576 10.492 3.105 1.00 0.00 C ATOM 2362 NH1 ARG A 148 45.526 10.790 2.217 1.00 0.00 N1+ ATOM 2363 NH2 ARG A 148 44.267 11.453 3.956 1.00 0.00 N ATOM 2364 H ARG A 148 41.249 10.036 -0.502 1.00 0.00 H ATOM 2365 HA ARG A 148 41.808 7.303 -0.669 1.00 0.00 H ATOM 2366 HB2 ARG A 148 41.904 7.435 1.820 1.00 0.00 H ATOM 2367 HB3 ARG A 148 41.759 9.042 1.572 1.00 0.00 H ATOM 2368 HG2 ARG A 148 43.775 9.137 0.436 1.00 0.00 H ATOM 2369 HG3 ARG A 148 43.856 7.511 0.318 1.00 0.00 H ATOM 2370 HD2 ARG A 148 45.330 8.300 1.975 1.00 0.00 H ATOM 2371 HD3 ARG A 148 44.182 7.338 2.627 1.00 0.00 H ATOM 2372 HE ARG A 148 43.276 9.099 3.784 1.00 0.00 H ATOM 2373 HH11 ARG A 148 45.951 11.695 2.224 1.00 0.00 H ATOM 2374 HH12 ARG A 148 45.813 10.108 1.544 1.00 0.00 H ATOM 2375 HH21 ARG A 148 44.734 12.336 3.904 1.00 0.00 H ATOM 2376 HH22 ARG A 148 43.566 11.298 4.652 1.00 0.00 H ATOM 2377 N VAL A 149 39.006 7.916 0.726 1.00 0.00 N ATOM 2378 CA VAL A 149 37.687 7.382 1.085 1.00 0.00 C ATOM 2379 C VAL A 149 36.948 6.824 -0.118 1.00 0.00 C ATOM 2380 O VAL A 149 36.341 5.749 -0.033 1.00 0.00 O ATOM 2381 CB VAL A 149 36.847 8.463 1.753 1.00 0.00 C ATOM 2382 CG1 VAL A 149 35.424 7.960 1.980 1.00 0.00 C ATOM 2383 CG2 VAL A 149 37.504 8.786 3.098 1.00 0.00 C ATOM 2384 H VAL A 149 39.183 8.891 0.860 1.00 0.00 H ATOM 2385 HA VAL A 149 37.819 6.640 1.742 1.00 0.00 H ATOM 2386 HB VAL A 149 36.830 9.282 1.179 1.00 0.00 H ATOM 2387 HG11 VAL A 149 34.883 8.678 2.419 1.00 0.00 H ATOM 2388 HG12 VAL A 149 35.011 7.721 1.101 1.00 0.00 H ATOM 2389 HG13 VAL A 149 35.446 7.152 2.569 1.00 0.00 H ATOM 2390 HG21 VAL A 149 36.976 9.495 3.565 1.00 0.00 H ATOM 2391 HG22 VAL A 149 37.528 7.962 3.664 1.00 0.00 H ATOM 2392 HG23 VAL A 149 38.437 9.112 2.944 1.00 0.00 H ATOM 2393 N ILE A 150 36.998 7.593 -1.217 1.00 0.00 N ATOM 2394 CA ILE A 150 36.363 7.232 -2.481 1.00 0.00 C ATOM 2395 C ILE A 150 36.956 5.957 -3.081 1.00 0.00 C ATOM 2396 O ILE A 150 36.265 5.136 -3.657 1.00 0.00 O ATOM 2397 CB ILE A 150 36.376 8.373 -3.523 1.00 0.00 C ATOM 2398 CG1 ILE A 150 35.440 9.507 -3.098 1.00 0.00 C ATOM 2399 CG2 ILE A 150 35.955 7.838 -4.912 1.00 0.00 C ATOM 2400 CD1 ILE A 150 35.583 10.748 -3.955 1.00 0.00 C ATOM 2401 H ILE A 150 37.496 8.459 -1.167 1.00 0.00 H ATOM 2402 HA ILE A 150 35.404 7.037 -2.277 1.00 0.00 H ATOM 2403 HB ILE A 150 37.306 8.735 -3.589 1.00 0.00 H ATOM 2404 HG12 ILE A 150 35.644 9.750 -2.150 1.00 0.00 H ATOM 2405 HG13 ILE A 150 34.496 9.182 -3.163 1.00 0.00 H ATOM 2406 HG21 ILE A 150 35.968 8.586 -5.575 1.00 0.00 H ATOM 2407 HG22 ILE A 150 36.593 7.125 -5.202 1.00 0.00 H ATOM 2408 HG23 ILE A 150 35.032 7.457 -4.857 1.00 0.00 H ATOM 2409 HD11 ILE A 150 34.950 11.451 -3.632 1.00 0.00 H ATOM 2410 HD12 ILE A 150 36.521 11.090 -3.893 1.00 0.00 H ATOM 2411 HD13 ILE A 150 35.373 10.522 -4.906 1.00 0.00 H ATOM 2412 N THR A 151 38.285 5.807 -2.947 1.00 0.00 N ATOM 2413 CA THR A 151 38.929 4.612 -3.475 1.00 0.00 C ATOM 2414 C THR A 151 38.485 3.410 -2.696 1.00 0.00 C ATOM 2415 O THR A 151 38.340 2.316 -3.234 1.00 0.00 O ATOM 2416 CB THR A 151 40.462 4.709 -3.403 1.00 0.00 C ATOM 2417 CG2 THR A 151 41.101 3.322 -3.569 1.00 0.00 C ATOM 2418 OG1 THR A 151 40.912 5.546 -4.438 1.00 0.00 O ATOM 2419 H THR A 151 38.828 6.511 -2.488 1.00 0.00 H ATOM 2420 HA THR A 151 38.658 4.495 -4.430 1.00 0.00 H ATOM 2421 HB THR A 151 40.730 5.096 -2.521 1.00 0.00 H ATOM 2422 HG1 THR A 151 41.909 5.616 -4.400 1.00 0.00 H ATOM 2423 HG21 THR A 151 42.096 3.405 -3.519 1.00 0.00 H ATOM 2424 HG22 THR A 151 40.780 2.718 -2.839 1.00 0.00 H ATOM 2425 HG23 THR A 151 40.842 2.940 -4.456 1.00 0.00 H ATOM 2426 N THR A 152 38.288 3.651 -1.405 1.00 0.00 N ATOM 2427 CA THR A 152 37.808 2.598 -0.543 1.00 0.00 C ATOM 2428 C THR A 152 36.403 2.148 -0.958 1.00 0.00 C ATOM 2429 O THR A 152 36.084 0.971 -0.905 1.00 0.00 O ATOM 2430 CB THR A 152 37.837 3.101 0.909 1.00 0.00 C ATOM 2431 CG2 THR A 152 37.421 1.998 1.833 1.00 0.00 C ATOM 2432 OG1 THR A 152 39.170 3.468 1.218 1.00 0.00 O ATOM 2433 H THR A 152 38.472 4.560 -1.031 1.00 0.00 H ATOM 2434 HA THR A 152 38.427 1.817 -0.621 1.00 0.00 H ATOM 2435 HB THR A 152 37.229 3.888 1.014 1.00 0.00 H ATOM 2436 HG1 THR A 152 39.312 4.431 0.990 1.00 0.00 H ATOM 2437 HG21 THR A 152 37.441 2.328 2.777 1.00 0.00 H ATOM 2438 HG22 THR A 152 36.494 1.702 1.603 1.00 0.00 H ATOM 2439 HG23 THR A 152 38.050 1.227 1.736 1.00 0.00 H ATOM 2440 N PHE A 153 35.561 3.099 -1.354 1.00 0.00 N ATOM 2441 CA PHE A 153 34.211 2.735 -1.737 1.00 0.00 C ATOM 2442 C PHE A 153 34.265 2.021 -3.080 1.00 0.00 C ATOM 2443 O PHE A 153 33.509 1.088 -3.357 1.00 0.00 O ATOM 2444 CB PHE A 153 33.301 3.984 -1.834 1.00 0.00 C ATOM 2445 CG PHE A 153 32.587 4.438 -0.575 1.00 0.00 C ATOM 2446 CD1 PHE A 153 31.723 3.604 0.135 1.00 0.00 C ATOM 2447 CD2 PHE A 153 32.726 5.755 -0.118 1.00 0.00 C ATOM 2448 CE1 PHE A 153 31.067 4.048 1.289 1.00 0.00 C ATOM 2449 CE2 PHE A 153 32.056 6.221 1.014 1.00 0.00 C ATOM 2450 CZ PHE A 153 31.230 5.357 1.739 1.00 0.00 C ATOM 2451 H PHE A 153 35.856 4.054 -1.387 1.00 0.00 H ATOM 2452 HA PHE A 153 33.835 2.111 -1.052 1.00 0.00 H ATOM 2453 HB2 PHE A 153 32.600 3.790 -2.521 1.00 0.00 H ATOM 2454 HB3 PHE A 153 33.871 4.745 -2.145 1.00 0.00 H ATOM 2455 HD1 PHE A 153 31.569 2.670 -0.187 1.00 0.00 H ATOM 2456 HD2 PHE A 153 33.324 6.381 -0.619 1.00 0.00 H ATOM 2457 HE1 PHE A 153 30.476 3.420 1.795 1.00 0.00 H ATOM 2458 HE2 PHE A 153 32.167 7.171 1.306 1.00 0.00 H ATOM 2459 HZ PHE A 153 30.764 5.673 2.566 1.00 0.00 H ATOM 2460 N ARG A 154 35.175 2.493 -3.923 1.00 0.00 N ATOM 2461 CA ARG A 154 35.316 1.938 -5.264 1.00 0.00 C ATOM 2462 C ARG A 154 35.841 0.525 -5.288 1.00 0.00 C ATOM 2463 O ARG A 154 35.346 -0.291 -6.046 1.00 0.00 O ATOM 2464 CB ARG A 154 36.171 2.777 -6.208 1.00 0.00 C ATOM 2465 CG ARG A 154 35.875 2.497 -7.685 1.00 0.00 C ATOM 2466 CD ARG A 154 36.773 3.294 -8.644 1.00 0.00 C ATOM 2467 NE ARG A 154 38.150 3.369 -8.173 1.00 0.00 N ATOM 2468 CZ ARG A 154 39.087 2.432 -8.340 1.00 0.00 C ATOM 2469 NH1 ARG A 154 38.849 1.282 -8.972 1.00 0.00 N1+ ATOM 2470 NH2 ARG A 154 40.308 2.659 -7.859 1.00 0.00 N ATOM 2471 H ARG A 154 35.773 3.241 -3.634 1.00 0.00 H ATOM 2472 HA ARG A 154 34.398 1.909 -5.659 1.00 0.00 H ATOM 2473 HB2 ARG A 154 37.134 2.575 -6.031 1.00 0.00 H ATOM 2474 HB3 ARG A 154 35.994 3.744 -6.025 1.00 0.00 H ATOM 2475 HG2 ARG A 154 34.922 2.737 -7.869 1.00 0.00 H ATOM 2476 HG3 ARG A 154 36.013 1.522 -7.857 1.00 0.00 H ATOM 2477 HD2 ARG A 154 36.410 4.222 -8.728 1.00 0.00 H ATOM 2478 HD3 ARG A 154 36.763 2.849 -9.540 1.00 0.00 H ATOM 2479 HE ARG A 154 38.418 4.197 -7.680 1.00 0.00 H ATOM 2480 HH11 ARG A 154 39.580 0.607 -9.075 1.00 0.00 H ATOM 2481 HH12 ARG A 154 37.940 1.094 -9.343 1.00 0.00 H ATOM 2482 HH21 ARG A 154 41.026 1.972 -7.972 1.00 0.00 H ATOM 2483 HH22 ARG A 154 40.507 3.517 -7.385 1.00 0.00 H ATOM 2484 N THR A 155 36.868 0.249 -4.474 1.00 0.00 N ATOM 2485 CA THR A 155 37.514 -1.057 -4.507 1.00 0.00 C ATOM 2486 C THR A 155 37.109 -1.998 -3.451 1.00 0.00 C ATOM 2487 O THR A 155 37.295 -3.180 -3.598 1.00 0.00 O ATOM 2488 CB THR A 155 39.032 -0.961 -4.347 1.00 0.00 C ATOM 2489 CG2 THR A 155 39.573 -0.071 -5.439 1.00 0.00 C ATOM 2490 OG1 THR A 155 39.358 -0.446 -3.069 1.00 0.00 O ATOM 2491 H THR A 155 37.195 0.947 -3.837 1.00 0.00 H ATOM 2492 HA THR A 155 37.320 -1.479 -5.392 1.00 0.00 H ATOM 2493 HB THR A 155 39.429 -1.874 -4.443 1.00 0.00 H ATOM 2494 HG1 THR A 155 38.960 0.465 -2.965 1.00 0.00 H ATOM 2495 HG21 THR A 155 40.566 0.002 -5.348 1.00 0.00 H ATOM 2496 HG22 THR A 155 39.348 -0.463 -6.331 1.00 0.00 H ATOM 2497 HG23 THR A 155 39.163 0.838 -5.362 1.00 0.00 H ATOM 2498 N GLY A 156 36.709 -1.480 -2.340 1.00 0.00 N ATOM 2499 CA GLY A 156 36.367 -2.395 -1.287 1.00 0.00 C ATOM 2500 C GLY A 156 37.593 -2.959 -0.568 1.00 0.00 C ATOM 2501 O GLY A 156 37.469 -3.915 0.180 1.00 0.00 O ATOM 2502 H GLY A 156 36.640 -0.490 -2.218 1.00 0.00 H ATOM 2503 HA2 GLY A 156 35.850 -3.155 -1.680 1.00 0.00 H ATOM 2504 HA3 GLY A 156 35.798 -1.915 -0.619 1.00 0.00 H ATOM 2505 N THR A 157 38.775 -2.357 -0.740 1.00 0.00 N ATOM 2506 CA THR A 157 40.024 -2.765 -0.073 1.00 0.00 C ATOM 2507 C THR A 157 40.621 -1.575 0.664 1.00 0.00 C ATOM 2508 O THR A 157 40.224 -0.442 0.457 1.00 0.00 O ATOM 2509 CB THR A 157 41.070 -3.045 -1.157 1.00 0.00 C ATOM 2510 CG2 THR A 157 40.476 -3.995 -2.198 1.00 0.00 C ATOM 2511 OG1 THR A 157 41.373 -1.781 -1.765 1.00 0.00 O ATOM 2512 H THR A 157 38.814 -1.577 -1.364 1.00 0.00 H ATOM 2513 HA THR A 157 39.888 -3.551 0.530 1.00 0.00 H ATOM 2514 HB THR A 157 41.893 -3.443 -0.752 1.00 0.00 H ATOM 2515 HG1 THR A 157 40.541 -1.394 -2.162 1.00 0.00 H ATOM 2516 HG21 THR A 157 41.156 -4.180 -2.907 1.00 0.00 H ATOM 2517 HG22 THR A 157 40.214 -4.853 -1.756 1.00 0.00 H ATOM 2518 HG23 THR A 157 39.669 -3.574 -2.612 1.00 0.00 H ATOM 2519 N TRP A 158 41.661 -1.801 1.418 1.00 0.00 N ATOM 2520 CA TRP A 158 42.283 -0.731 2.135 1.00 0.00 C ATOM 2521 C TRP A 158 43.479 -0.236 1.389 1.00 0.00 C ATOM 2522 O TRP A 158 44.382 0.363 1.962 1.00 0.00 O ATOM 2523 CB TRP A 158 42.833 -1.262 3.462 1.00 0.00 C ATOM 2524 CG TRP A 158 41.789 -1.694 4.431 1.00 0.00 C ATOM 2525 CD1 TRP A 158 41.561 -2.966 4.825 1.00 0.00 C ATOM 2526 CD2 TRP A 158 40.905 -0.874 5.208 1.00 0.00 C ATOM 2527 CE2 TRP A 158 40.166 -1.732 6.038 1.00 0.00 C ATOM 2528 CE3 TRP A 158 40.703 0.493 5.285 1.00 0.00 C ATOM 2529 NE1 TRP A 158 40.584 -3.000 5.776 1.00 0.00 N ATOM 2530 CZ2 TRP A 158 39.195 -1.264 6.923 1.00 0.00 C ATOM 2531 CZ3 TRP A 158 39.771 0.948 6.186 1.00 0.00 C ATOM 2532 CH2 TRP A 158 38.999 0.082 6.984 1.00 0.00 C ATOM 2533 H TRP A 158 42.026 -2.729 1.495 1.00 0.00 H ATOM 2534 HA TRP A 158 41.633 0.012 2.294 1.00 0.00 H ATOM 2535 HB2 TRP A 158 43.375 -0.538 3.888 1.00 0.00 H ATOM 2536 HB3 TRP A 158 43.421 -2.047 3.265 1.00 0.00 H ATOM 2537 HD1 TRP A 158 42.040 -3.769 4.470 1.00 0.00 H ATOM 2538 HE1 TRP A 158 40.230 -3.827 6.212 1.00 0.00 H ATOM 2539 HE3 TRP A 158 41.217 1.126 4.706 1.00 0.00 H ATOM 2540 HZ2 TRP A 158 38.663 -1.893 7.491 1.00 0.00 H ATOM 2541 HZ3 TRP A 158 39.635 1.934 6.279 1.00 0.00 H ATOM 2542 HH2 TRP A 158 38.304 0.457 7.598 1.00 0.00 H ATOM 2543 N ASP A 159 43.506 -0.457 0.122 1.00 0.00 N ATOM 2544 CA ASP A 159 44.676 -0.042 -0.592 1.00 0.00 C ATOM 2545 C ASP A 159 45.090 1.421 -0.490 1.00 0.00 C ATOM 2546 O ASP A 159 46.279 1.716 -0.581 1.00 0.00 O ATOM 2547 CB ASP A 159 44.603 -0.446 -2.041 1.00 0.00 C ATOM 2548 CG ASP A 159 44.547 -1.928 -2.276 1.00 0.00 C ATOM 2549 OD1 ASP A 159 45.074 -2.648 -1.312 1.00 0.00 O ATOM 2550 OD2 ASP A 159 44.111 -2.414 -3.292 1.00 0.00 O1- ATOM 2551 H ASP A 159 42.741 -0.901 -0.345 1.00 0.00 H ATOM 2552 HA ASP A 159 45.433 -0.566 -0.202 1.00 0.00 H ATOM 2553 HB2 ASP A 159 45.412 -0.087 -2.506 1.00 0.00 H ATOM 2554 HB3 ASP A 159 43.782 -0.036 -2.438 1.00 0.00 H ATOM 2555 N ALA A 160 44.156 2.338 -0.362 1.00 0.00 N ATOM 2556 CA ALA A 160 44.485 3.754 -0.334 1.00 0.00 C ATOM 2557 C ALA A 160 45.196 4.114 0.933 1.00 0.00 C ATOM 2558 O ALA A 160 45.815 5.163 1.079 1.00 0.00 O ATOM 2559 CB ALA A 160 43.212 4.602 -0.431 1.00 0.00 C ATOM 2560 H ALA A 160 43.200 2.056 -0.282 1.00 0.00 H ATOM 2561 HA ALA A 160 45.077 3.966 -1.111 1.00 0.00 H ATOM 2562 HB1 ALA A 160 43.455 5.572 -0.410 1.00 0.00 H ATOM 2563 HB2 ALA A 160 42.738 4.395 -1.287 1.00 0.00 H ATOM 2564 HB3 ALA A 160 42.612 4.392 0.341 1.00 0.00 H ATOM 2565 N TYR A 161 45.061 3.229 1.885 1.00 0.00 N ATOM 2566 CA TYR A 161 45.621 3.490 3.172 1.00 0.00 C ATOM 2567 C TYR A 161 46.856 2.700 3.386 1.00 0.00 C ATOM 2568 O TYR A 161 47.417 2.722 4.476 1.00 0.00 O ATOM 2569 CB TYR A 161 44.647 3.185 4.314 1.00 0.00 C ATOM 2570 CG TYR A 161 43.587 4.231 4.362 1.00 0.00 C ATOM 2571 CD1 TYR A 161 42.506 4.142 3.488 1.00 0.00 C ATOM 2572 CD2 TYR A 161 43.718 5.329 5.208 1.00 0.00 C ATOM 2573 CE1 TYR A 161 41.511 5.113 3.486 1.00 0.00 C ATOM 2574 CE2 TYR A 161 42.733 6.318 5.208 1.00 0.00 C ATOM 2575 CZ TYR A 161 41.642 6.198 4.343 1.00 0.00 C ATOM 2576 OH TYR A 161 40.686 7.175 4.344 1.00 0.00 O ATOM 2577 H TYR A 161 44.569 2.375 1.713 1.00 0.00 H ATOM 2578 HA TYR A 161 45.860 4.460 3.217 1.00 0.00 H ATOM 2579 HB2 TYR A 161 45.144 3.175 5.182 1.00 0.00 H ATOM 2580 HB3 TYR A 161 44.225 2.291 4.162 1.00 0.00 H ATOM 2581 HD1 TYR A 161 42.445 3.371 2.855 1.00 0.00 H ATOM 2582 HD2 TYR A 161 44.512 5.408 5.811 1.00 0.00 H ATOM 2583 HE1 TYR A 161 40.719 5.032 2.881 1.00 0.00 H ATOM 2584 HE2 TYR A 161 42.807 7.105 5.821 1.00 0.00 H ATOM 2585 HH TYR A 161 40.773 7.959 4.958 1.00 0.00 H ATOM 2586 N LYS A 162 47.298 1.997 2.362 1.00 0.00 N ATOM 2587 CA LYS A 162 48.508 1.230 2.531 1.00 0.00 C ATOM 2588 C LYS A 162 49.647 1.863 1.769 1.00 0.00 C ATOM 2589 O LYS A 162 50.757 2.016 2.340 1.00 0.00 O ATOM 2590 CB LYS A 162 48.368 -0.254 2.273 1.00 0.00 C ATOM 2591 CG LYS A 162 47.496 -0.917 3.341 1.00 0.00 C ATOM 2592 CD LYS A 162 46.720 -2.138 2.861 1.00 0.00 C ATOM 2593 CE LYS A 162 46.717 -2.350 1.344 1.00 0.00 C ATOM 2594 NZ LYS A 162 45.641 -3.237 0.865 1.00 0.00 N1+ ATOM 2595 H LYS A 162 46.807 1.996 1.491 1.00 0.00 H ATOM 2596 HA LYS A 162 48.749 1.315 3.498 1.00 0.00 H ATOM 2597 HB2 LYS A 162 49.275 -0.675 2.284 1.00 0.00 H ATOM 2598 HB3 LYS A 162 47.948 -0.392 1.376 1.00 0.00 H ATOM 2599 HG2 LYS A 162 46.838 -0.240 3.671 1.00 0.00 H ATOM 2600 HG3 LYS A 162 48.089 -1.201 4.095 1.00 0.00 H ATOM 2601 HD2 LYS A 162 45.771 -2.040 3.162 1.00 0.00 H ATOM 2602 HD3 LYS A 162 47.123 -2.948 3.286 1.00 0.00 H ATOM 2603 HE2 LYS A 162 47.595 -2.750 1.081 1.00 0.00 H ATOM 2604 HE3 LYS A 162 46.610 -1.459 0.902 1.00 0.00 H ATOM 2605 HZ1 LYS A 162 45.377 -2.970 -0.062 1.00 0.00 H ATOM 2606 HZ2 LYS A 162 45.966 -4.183 0.860 1.00 0.00 H ATOM 2607 HZ3 LYS A 162 44.850 -3.160 1.472 1.00 0.00 H ATOM 2608 N NME A 163 49.484 2.242 0.547 1.00 0.00 N ATOM 2609 CH3 NME A 163 50.586 2.850 -0.178 1.00 0.00 C ATOM 2610 H NME A 163 48.590 2.116 0.094 1.00 0.00 H ATOM 2611 1HH3 NME A 163 50.650 3.901 0.060 1.00 0.00 H ATOM 2612 2HH3 NME A 163 51.517 2.373 0.095 1.00 0.00 H ATOM 2613 3HH3 NME A 163 50.434 2.740 -1.242 1.00 0.00 H END ================================================ FILE: src/openfe/tests/data/CN.sdf ================================================ RDKit 3D 7 6 0 0 0 0 0 0 0 0999 V2000 -0.5449 0.0217 -0.1813 C 0 0 0 0 0 0 0 0 0 0 0 0 0.8594 -0.2905 0.0155 N 0 0 0 0 0 0 0 0 0 0 0 0 -0.7263 0.3463 -1.2100 H 0 0 0 0 0 0 0 0 0 0 0 0 -1.1601 -0.8593 0.0223 H 0 0 0 0 0 0 0 0 0 0 0 0 -0.8528 0.8211 0.4984 H 0 0 0 0 0 0 0 0 0 0 0 0 0.9508 -1.2559 0.3287 H 0 0 0 0 0 0 0 0 0 0 0 0 1.2332 0.2879 0.7669 H 0 0 0 0 0 0 0 0 0 0 0 0 1 2 1 0 1 3 1 0 1 4 1 0 1 5 1 0 2 6 1 0 2 7 1 0 M END $$$$ ================================================ FILE: src/openfe/tests/data/__init__.py ================================================ ================================================ FILE: src/openfe/tests/data/a2a/__init__.py ================================================ ================================================ FILE: src/openfe/tests/data/benzene_modifications.sdf ================================================ benzene PyMOL2.5 3D 0 12 12 0 0 0 0 0 0 0 0999 V2000 25.9780 5.3270 4.7790 C 0 0 0 0 0 0 0 0 0 0 0 0 26.3950 5.0740 3.4990 C 0 0 0 0 0 0 0 0 0 0 0 0 27.3400 5.8600 2.9020 C 0 0 0 0 0 0 0 0 0 0 0 0 27.8370 6.9210 3.5690 C 0 0 0 0 0 0 0 0 0 0 0 0 27.4200 7.1960 4.8560 C 0 0 0 0 0 0 0 0 0 0 0 0 26.4980 6.3790 5.4690 C 0 0 0 0 0 0 0 0 0 0 0 0 25.2298 4.6859 5.2451 H 0 0 0 0 0 0 0 0 0 0 0 0 25.9676 4.2351 2.9497 H 0 0 0 0 0 0 0 0 0 0 0 0 27.6890 5.6311 1.8951 H 0 0 0 0 0 0 0 0 0 0 0 0 28.5730 7.5660 3.0889 H 0 0 0 0 0 0 0 0 0 0 0 0 27.8209 8.0598 5.3863 H 0 0 0 0 0 0 0 0 0 0 0 0 26.1874 6.5720 6.4958 H 0 0 0 0 0 0 0 0 0 0 0 0 1 2 4 0 0 0 0 1 6 4 0 0 0 0 1 7 1 0 0 0 0 2 3 4 0 0 0 0 2 8 1 0 0 0 0 3 4 4 0 0 0 0 3 9 1 0 0 0 0 4 5 4 0 0 0 0 4 10 1 0 0 0 0 5 6 4 0 0 0 0 5 11 1 0 0 0 0 6 12 1 0 0 0 0 M END $$$$ toluene PyMOL2.5 3D 0 15 15 0 0 0 0 0 0 0 0999 V2000 28.9072 8.7434 5.1220 H 0 0 0 0 0 0 0 0 0 0 0 0 28.1966 8.1433 6.6393 H 0 0 0 0 0 0 0 0 0 0 0 0 27.9864 8.4164 5.6052 C 0 0 0 0 0 0 0 0 0 0 0 0 27.2579 9.2269 5.5838 H 0 0 0 0 0 0 0 0 0 0 0 0 25.9780 5.3270 4.7790 C 0 0 0 0 0 0 0 0 0 0 0 0 26.3950 5.0740 3.4990 C 0 0 0 0 0 0 0 0 0 0 0 0 27.3400 5.8600 2.9020 C 0 0 0 0 0 0 0 0 0 0 0 0 27.8370 6.9210 3.5690 C 0 0 0 0 0 0 0 0 0 0 0 0 27.4200 7.1960 4.8560 C 0 0 0 0 0 0 0 0 0 0 0 0 26.4980 6.3790 5.4690 C 0 0 0 0 0 0 0 0 0 0 0 0 25.2298 4.6859 5.2451 H 0 0 0 0 0 0 0 0 0 0 0 0 25.9676 4.2351 2.9497 H 0 0 0 0 0 0 0 0 0 0 0 0 27.6890 5.6311 1.8951 H 0 0 0 0 0 0 0 0 0 0 0 0 28.5730 7.5660 3.0889 H 0 0 0 0 0 0 0 0 0 0 0 0 26.1874 6.5720 6.4958 H 0 0 0 0 0 0 0 0 0 0 0 0 1 3 1 0 0 0 0 2 3 1 0 0 0 0 3 4 1 0 0 0 0 5 6 4 0 0 0 0 5 10 4 0 0 0 0 5 11 1 0 0 0 0 6 7 4 0 0 0 0 6 12 1 0 0 0 0 7 8 4 0 0 0 0 7 13 1 0 0 0 0 8 9 4 0 0 0 0 8 14 1 0 0 0 0 3 9 1 0 0 0 0 9 10 4 0 0 0 0 10 15 1 0 0 0 0 M END $$$$ phenol PyMOL2.5 3D 0 13 13 0 0 0 0 0 0 0 0999 V2000 25.9780 5.3270 4.7790 C 0 0 0 0 0 0 0 0 0 0 0 0 26.3950 5.0740 3.4990 C 0 0 0 0 0 0 0 0 0 0 0 0 27.3400 5.8600 2.9020 C 0 0 0 0 0 0 0 0 0 0 0 0 27.8370 6.9210 3.5690 C 0 0 0 0 0 0 0 0 0 0 0 0 27.4200 7.1960 4.8560 C 0 0 0 0 0 0 0 0 0 0 0 0 26.4980 6.3790 5.4690 C 0 0 0 0 0 0 0 0 0 0 0 0 25.2298 4.6859 5.2451 H 0 0 0 0 0 0 0 0 0 0 0 0 25.9676 4.2351 2.9497 H 0 0 0 0 0 0 0 0 0 0 0 0 27.6890 5.6311 1.8951 H 0 0 0 0 0 0 0 0 0 0 0 0 28.5730 7.5660 3.0889 H 0 0 0 0 0 0 0 0 0 0 0 0 28.1311 8.0887 6.4624 H 0 0 0 0 0 0 0 0 0 0 0 0 26.1874 6.5720 6.4958 H 0 0 0 0 0 0 0 0 0 0 0 0 27.9460 8.3293 5.5517 O 0 0 0 0 0 0 0 0 0 0 0 0 1 2 4 0 0 0 0 1 6 4 0 0 0 0 1 7 1 0 0 0 0 2 3 4 0 0 0 0 2 8 1 0 0 0 0 3 4 4 0 0 0 0 3 9 1 0 0 0 0 4 5 4 0 0 0 0 4 10 1 0 0 0 0 5 6 4 0 0 0 0 5 13 1 0 0 0 0 6 12 1 0 0 0 0 11 13 1 0 0 0 0 M END $$$$ benzonitrile PyMOL2.5 3D 0 13 13 0 0 0 0 0 0 0 0999 V2000 28.5559 9.5700 6.2831 N 0 0 0 0 0 0 0 0 0 0 0 0 27.9981 8.4043 5.5824 C 0 0 0 0 0 0 0 0 0 0 0 0 25.9780 5.3270 4.7790 C 0 0 0 0 0 0 0 0 0 0 0 0 26.3950 5.0740 3.4990 C 0 0 0 0 0 0 0 0 0 0 0 0 27.3400 5.8600 2.9020 C 0 0 0 0 0 0 0 0 0 0 0 0 27.8370 6.9210 3.5690 C 0 0 0 0 0 0 0 0 0 0 0 0 27.4200 7.1960 4.8560 C 0 0 0 0 0 0 0 0 0 0 0 0 26.4980 6.3790 5.4690 C 0 0 0 0 0 0 0 0 0 0 0 0 25.2298 4.6859 5.2451 H 0 0 0 0 0 0 0 0 0 0 0 0 25.9676 4.2351 2.9497 H 0 0 0 0 0 0 0 0 0 0 0 0 27.6890 5.6311 1.8951 H 0 0 0 0 0 0 0 0 0 0 0 0 28.5730 7.5660 3.0889 H 0 0 0 0 0 0 0 0 0 0 0 0 26.1874 6.5720 6.4958 H 0 0 0 0 0 0 0 0 0 0 0 0 1 2 3 0 0 0 0 3 4 4 0 0 0 0 3 8 4 0 0 0 0 3 9 1 0 0 0 0 4 5 4 0 0 0 0 4 10 1 0 0 0 0 5 6 4 0 0 0 0 5 11 1 0 0 0 0 6 7 4 0 0 0 0 6 12 1 0 0 0 0 2 7 1 0 0 0 0 7 8 4 0 0 0 0 8 13 1 0 0 0 0 M END $$$$ anisole PyMOL2.5 3D 0 16 16 0 0 0 0 0 0 0 0999 V2000 29.2873 8.8784 4.9226 C 0 0 0 0 0 0 0 0 0 0 0 0 29.5502 9.7990 5.4437 H 0 0 0 0 0 0 0 0 0 0 0 0 28.0548 8.3459 5.4720 O 0 0 0 0 0 0 0 0 0 0 0 0 30.0866 8.1484 5.0502 H 0 0 0 0 0 0 0 0 0 0 0 0 29.1525 9.0868 3.8612 H 0 0 0 0 0 0 0 0 0 0 0 0 25.9780 5.3270 4.7790 C 0 0 0 0 0 0 0 0 0 0 0 0 26.3950 5.0740 3.4990 C 0 0 0 0 0 0 0 0 0 0 0 0 27.3400 5.8600 2.9020 C 0 0 0 0 0 0 0 0 0 0 0 0 27.8370 6.9210 3.5690 C 0 0 0 0 0 0 0 0 0 0 0 0 27.4200 7.1960 4.8560 C 0 0 0 0 0 0 0 0 0 0 0 0 26.4980 6.3790 5.4690 C 0 0 0 0 0 0 0 0 0 0 0 0 25.2298 4.6859 5.2451 H 0 0 0 0 0 0 0 0 0 0 0 0 25.9676 4.2351 2.9497 H 0 0 0 0 0 0 0 0 0 0 0 0 27.6890 5.6311 1.8951 H 0 0 0 0 0 0 0 0 0 0 0 0 28.5730 7.5660 3.0889 H 0 0 0 0 0 0 0 0 0 0 0 0 26.1874 6.5720 6.4958 H 0 0 0 0 0 0 0 0 0 0 0 0 1 2 1 0 0 0 0 1 4 1 0 0 0 0 1 5 1 0 0 0 0 1 3 1 0 0 0 0 6 7 4 0 0 0 0 6 11 4 0 0 0 0 6 12 1 0 0 0 0 7 8 4 0 0 0 0 7 13 1 0 0 0 0 8 9 4 0 0 0 0 8 14 1 0 0 0 0 9 10 4 0 0 0 0 9 15 1 0 0 0 0 3 10 1 0 0 0 0 10 11 4 0 0 0 0 11 16 1 0 0 0 0 M END $$$$ benzaldehyde PyMOL2.5 3D 0 14 14 0 0 0 0 0 0 0 0999 V2000 29.2079 8.8492 4.9632 O 0 0 0 0 0 0 0 0 0 0 0 0 27.5482 8.8691 6.4597 H 0 0 0 0 0 0 0 0 0 0 0 0 27.9981 8.4043 5.5824 C 0 0 0 0 0 0 0 0 0 0 0 0 25.9780 5.3270 4.7790 C 0 0 0 0 0 0 0 0 0 0 0 0 26.3950 5.0740 3.4990 C 0 0 0 0 0 0 0 0 0 0 0 0 27.3400 5.8600 2.9020 C 0 0 0 0 0 0 0 0 0 0 0 0 27.8370 6.9210 3.5690 C 0 0 0 0 0 0 0 0 0 0 0 0 27.4200 7.1960 4.8560 C 0 0 0 0 0 0 0 0 0 0 0 0 26.4980 6.3790 5.4690 C 0 0 0 0 0 0 0 0 0 0 0 0 25.2298 4.6859 5.2451 H 0 0 0 0 0 0 0 0 0 0 0 0 25.9676 4.2351 2.9497 H 0 0 0 0 0 0 0 0 0 0 0 0 27.6890 5.6311 1.8951 H 0 0 0 0 0 0 0 0 0 0 0 0 28.5730 7.5660 3.0889 H 0 0 0 0 0 0 0 0 0 0 0 0 26.1874 6.5720 6.4958 H 0 0 0 0 0 0 0 0 0 0 0 0 1 3 2 0 0 0 0 2 3 1 0 0 0 0 4 5 4 0 0 0 0 4 9 4 0 0 0 0 4 10 1 0 0 0 0 5 6 4 0 0 0 0 5 11 1 0 0 0 0 6 7 4 0 0 0 0 6 12 1 0 0 0 0 7 8 4 0 0 0 0 7 13 1 0 0 0 0 3 8 1 0 0 0 0 8 9 4 0 0 0 0 9 14 1 0 0 0 0 M END $$$$ styrene PyMOL2.5 3D 0 16 16 0 0 0 0 0 0 0 0999 V2000 29.2873 8.8784 4.9226 C 0 0 0 0 0 0 0 0 0 0 0 0 29.6609 8.3486 4.0463 H 0 0 0 0 0 0 0 0 0 0 0 0 29.8344 9.7353 5.3157 H 0 0 0 0 0 0 0 0 0 0 0 0 27.5365 8.8812 6.4825 H 0 0 0 0 0 0 0 0 0 0 0 0 27.9864 8.4164 5.6052 C 0 0 0 0 0 0 0 0 0 0 0 0 25.9780 5.3270 4.7790 C 0 0 0 0 0 0 0 0 0 0 0 0 26.3950 5.0740 3.4990 C 0 0 0 0 0 0 0 0 0 0 0 0 27.3400 5.8600 2.9020 C 0 0 0 0 0 0 0 0 0 0 0 0 27.8370 6.9210 3.5690 C 0 0 0 0 0 0 0 0 0 0 0 0 27.4200 7.1960 4.8560 C 0 0 0 0 0 0 0 0 0 0 0 0 26.4980 6.3790 5.4690 C 0 0 0 0 0 0 0 0 0 0 0 0 25.2298 4.6859 5.2451 H 0 0 0 0 0 0 0 0 0 0 0 0 25.9676 4.2351 2.9497 H 0 0 0 0 0 0 0 0 0 0 0 0 27.6890 5.6311 1.8951 H 0 0 0 0 0 0 0 0 0 0 0 0 28.5730 7.5660 3.0889 H 0 0 0 0 0 0 0 0 0 0 0 0 26.1874 6.5720 6.4958 H 0 0 0 0 0 0 0 0 0 0 0 0 1 2 1 0 0 0 0 1 3 1 0 0 0 0 1 5 2 0 0 0 0 4 5 1 0 0 0 0 6 7 4 0 0 0 0 6 11 4 0 0 0 0 6 12 1 0 0 0 0 7 8 4 0 0 0 0 7 13 1 0 0 0 0 8 9 4 0 0 0 0 8 14 1 0 0 0 0 9 10 4 0 0 0 0 9 15 1 0 0 0 0 5 10 1 0 0 0 0 10 11 4 0 0 0 0 11 16 1 0 0 0 0 M END $$$$ ================================================ FILE: src/openfe/tests/data/cdk8/__init__.py ================================================ ================================================ FILE: src/openfe/tests/data/cdk8/cdk8_ligands.sdf ================================================ lig_40 RDKit 3D 55 59 0 0 0 0 0 0 0 0999 V2000 -2.1629 14.4632 -7.7736 H 0 0 0 0 0 0 0 0 0 0 0 0 -1.6358 13.6804 -7.2468 C 0 0 0 0 0 0 0 0 0 0 0 0 -0.4242 13.9183 -6.7602 N 0 0 0 0 0 0 0 0 0 0 0 0 -0.0745 12.7682 -6.1303 N 0 0 0 0 0 0 0 0 0 0 0 0 1.1739 12.6893 -5.4058 C 0 0 0 0 0 0 0 0 0 0 0 0 1.3405 11.6624 -5.0598 H 0 0 0 0 0 0 0 0 0 0 0 0 2.0071 12.9749 -6.0470 H 0 0 0 0 0 0 0 0 0 0 0 0 1.1432 13.3640 -4.5458 H 0 0 0 0 0 0 0 0 0 0 0 0 -1.0394 11.7936 -6.2530 C 0 0 0 0 0 0 0 0 0 0 0 0 -0.9271 10.8145 -5.8143 H 0 0 0 0 0 0 0 0 0 0 0 0 -2.0646 12.3553 -6.9521 C 0 0 0 0 0 0 0 0 0 0 0 0 -3.3612 11.7367 -7.2677 C 0 0 0 0 0 0 0 0 0 0 0 0 -3.4353 10.4402 -7.8240 C 0 0 0 0 0 0 0 0 0 0 0 0 -2.5291 9.8930 -8.0497 H 0 0 0 0 0 0 0 0 0 0 0 0 -4.6843 9.8342 -8.0582 C 0 0 0 0 0 0 0 0 0 0 0 0 -4.7212 8.8327 -8.4668 H 0 0 0 0 0 0 0 0 0 0 0 0 -5.8788 10.5137 -7.7409 C 0 0 0 0 0 0 0 0 0 0 0 0 -7.2257 9.8514 -7.9841 C 0 0 0 0 0 0 0 0 0 0 0 0 -8.0088 10.4290 -7.4862 H 0 0 0 0 0 0 0 0 0 0 0 0 -7.2161 8.8796 -7.4854 H 0 0 0 0 0 0 0 0 0 0 0 0 -7.5621 9.6839 -9.4431 C 0 0 0 0 0 0 0 0 0 0 0 0 -8.2465 8.6457 -9.8601 N 0 0 0 0 0 0 0 0 0 0 0 0 -8.4159 8.8045 -11.1975 N 0 0 0 0 0 0 0 0 0 0 0 0 -8.9502 8.1258 -11.7289 H 0 0 0 0 0 0 0 0 0 0 0 0 -7.8273 9.9474 -11.6947 C 0 0 0 0 0 0 0 0 0 0 0 0 -7.2413 10.5449 -10.5484 C 0 0 0 0 0 0 0 0 0 0 0 0 -6.5294 11.7467 -10.7406 C 0 0 0 0 0 0 0 0 0 0 0 0 -6.0852 12.2336 -9.8863 H 0 0 0 0 0 0 0 0 0 0 0 0 -6.3563 12.3077 -12.0259 C 0 0 0 0 0 0 0 0 0 0 0 0 -5.5362 13.5572 -12.1825 C 0 0 0 0 0 0 0 0 0 0 0 0 -5.9634 14.4904 -12.8591 O 0 0 0 0 0 0 0 0 0 0 0 0 -4.3771 13.6269 -11.4873 N 0 0 0 0 0 0 0 0 0 0 0 0 -3.5313 12.4788 -11.1187 C 0 0 0 0 0 0 0 0 0 0 0 0 -3.9497 11.5214 -11.4400 H 0 0 0 0 0 0 0 0 0 0 0 0 -3.4548 12.4356 -10.0313 H 0 0 0 0 0 0 0 0 0 0 0 0 -2.1266 12.6153 -11.7432 C 0 0 0 0 0 0 0 0 0 0 0 0 -1.4575 11.8547 -11.3364 H 0 0 0 0 0 0 0 0 0 0 0 0 -2.1916 12.4202 -12.8140 H 0 0 0 0 0 0 0 0 0 0 0 0 -1.5271 13.9516 -11.4995 N 0 0 0 0 0 4 0 0 0 0 0 0 -1.2173 13.9804 -10.5399 H 0 0 0 0 0 0 0 0 0 0 0 0 -2.4434 15.0961 -11.7287 C 0 0 0 0 0 0 0 0 0 0 0 0 -1.9564 16.0116 -11.3987 H 0 0 0 0 0 0 0 0 0 0 0 0 -2.6466 15.2159 -12.7917 H 0 0 0 0 0 0 0 0 0 0 0 0 -3.7957 14.8958 -11.0443 C 0 0 0 0 0 0 0 0 0 0 0 0 -3.6689 14.8810 -9.9610 H 0 0 0 0 0 0 0 0 0 0 0 0 -4.4493 15.7424 -11.2583 H 0 0 0 0 0 0 0 0 0 0 0 0 -7.0022 11.7149 -13.1320 C 0 0 0 0 0 0 0 0 0 0 0 0 -6.9139 12.1537 -14.1143 H 0 0 0 0 0 0 0 0 0 0 0 0 -7.7332 10.5264 -12.9709 C 0 0 0 0 0 0 0 0 0 0 0 0 -8.2191 10.0653 -13.8172 H 0 0 0 0 0 0 0 0 0 0 0 0 -5.8120 11.8110 -7.1954 C 0 0 0 0 0 0 0 0 0 0 0 0 -6.7168 12.3529 -6.9524 H 0 0 0 0 0 0 0 0 0 0 0 0 -4.5610 12.4178 -6.9739 C 0 0 0 0 0 0 0 0 0 0 0 0 -4.5187 13.4065 -6.5450 H 0 0 0 0 0 0 0 0 0 0 0 0 -0.7052 14.0647 -12.0846 H 0 0 0 0 0 0 0 0 0 0 0 0 1 2 1 0 2 11 1 0 2 3 2 0 3 4 1 0 4 5 1 0 4 9 1 0 5 6 1 0 5 7 1 0 5 8 1 0 9 10 1 0 9 11 2 0 11 12 1 0 12 53 1 0 12 13 2 0 13 14 1 0 13 15 1 0 15 16 1 0 15 17 2 0 17 18 1 0 17 51 1 0 18 19 1 0 18 20 1 0 18 21 1 0 21 26 1 0 21 22 2 0 22 23 1 0 23 24 1 0 23 25 1 0 25 49 1 0 25 26 2 0 26 27 1 0 27 28 1 0 27 29 2 0 29 30 1 0 29 47 1 0 30 31 2 0 30 32 1 0 32 44 1 0 32 33 1 0 33 34 1 0 33 35 1 0 33 36 1 0 36 37 1 0 36 38 1 0 36 39 1 0 39 40 1 0 39 41 1 0 39 55 1 0 41 42 1 0 41 43 1 0 41 44 1 0 44 45 1 0 44 46 1 0 47 48 1 0 47 49 2 0 49 50 1 0 51 52 1 0 51 53 2 0 53 54 1 0 M CHG 1 39 1 M END > ligprep_cdk8.smi > 28 > 53161 > 0 > W0NIM11uMW5bY0hdYyhbY0hdMSktYzJbY0hdW2NIXWMoW2NIXVtjSF0yKVtDSDJdYyhuW25IXTMpYyhjMzQpW2NIXWMoW2NIXVtjSF00KUMoPU8pTjVbQ0gyXVtDSDJdW05IXVtDSDJdW0NIMl01 > J2VwaWtfcHl0aG9uJywgJy1waHQnLCAnMC4wJywgJy1waCcsICc3LjQnLCAnLXRuJywgJzgnLCAnLW1hJywgJzUwMCcsICctaW1hZScsICc8aW5maWxlLm1hZT4nLCAnLW9tYWUnLCAnPG91dGZpbGUubWFlPic= > 0.98039200000000004 > 0.1225 > 0.1225 > 0.0001 > 0.1120 > 0.234459 > 1 > 1 > S-OPLS > 47.434600000000003 > 1 > lig_40-1 > glide-grid_CDK8-5HNB > 28 > 5 > -10.680521562383699 > -0.35601738541278899 > -1.1062287913851501 > -2.42673087257679 > -10.792521562383699 > -4.2718306350450801 > -0.59065016807439996 > 0 > -2.2052956385914499 > -48.461879730224602 > -11.060666084289601 > 0.42590076043445002 > -0.068451981952531202 > -99.420097957526707 > -59.522545814514203 > 4.2033767700195304 > 28 > 19 > 0.112 > 0.097333152874369194 > snapped_core_restrain > lig_40 > 0.036118163636363637 0.23521816363636364 -0.5287818363636364 0.10041816363636363 0.028618163636363637 0.072385163636363631 0.072385163636363631 0.072385163636363631 -0.12028183636363637 0.19601816363636365 -0.20128183636363636 -0.025981836363636362 -0.12848183636363636 0.13651816363636365 -0.11948183636363637 0.14851816363636364 -0.070281836363636371 -0.051381836363636364 0.083218163636363626 0.083218163636363626 0.35791816363636364 -0.48808183636363633 -0.0060818363636363643 0.34071816363636365 -0.020181836363636362 -0.22488183636363634 -0.021981836363636362 0.15101816363636364 -0.20058183636363636 0.69771816363636363 -0.55508183636363639 -0.50978183636363639 0.073018163636363626 0.099718163636363627 0.099718163636363627 0.078818163636363625 0.11046816363636364 0.11046816363636364 -0.76198183636363637 0.45881816363636363 0.078818163636363625 0.11046816363636364 0.11046816363636364 0.073018163636363626 0.099718163636363627 0.099718163636363627 -0.053981836363636362 0.15801816363636365 -0.13898183636363637 0.15801816363636365 -0.11948183636363637 0.14851816363636364 -0.12848183636363636 0.13651816363636365 0.45881816363636363 $$$$ lig_41 RDKit 3D 55 59 0 0 0 0 0 0 0 0999 V2000 -2.0940 14.3956 -7.8003 H 0 0 0 0 0 0 0 0 0 0 0 0 -1.6017 13.6239 -7.2266 C 0 0 0 0 0 0 0 0 0 0 0 0 -0.3906 13.8491 -6.7320 N 0 0 0 0 0 0 0 0 0 0 0 0 -0.0688 12.7144 -6.0644 N 0 0 0 0 0 0 0 0 0 0 0 0 1.1957 12.6229 -5.3651 C 0 0 0 0 0 0 0 0 0 0 0 0 1.3268 11.6198 -4.9582 H 0 0 0 0 0 0 0 0 0 0 0 0 2.0199 12.8371 -6.0449 H 0 0 0 0 0 0 0 0 0 0 0 0 1.2148 13.3414 -4.5452 H 0 0 0 0 0 0 0 0 0 0 0 0 -1.0674 11.7696 -6.1429 C 0 0 0 0 0 0 0 0 0 0 0 0 -0.9864 10.8164 -5.6488 H 0 0 0 0 0 0 0 0 0 0 0 0 -2.0672 12.3248 -6.8862 C 0 0 0 0 0 0 0 0 0 0 0 0 -3.3663 11.7213 -7.2183 C 0 0 0 0 0 0 0 0 0 0 0 0 -3.4422 10.4235 -7.7718 C 0 0 0 0 0 0 0 0 0 0 0 0 -2.5346 9.8737 -7.9804 H 0 0 0 0 0 0 0 0 0 0 0 0 -4.6900 9.8316 -8.0456 C 0 0 0 0 0 0 0 0 0 0 0 0 -4.7266 8.8351 -8.4599 H 0 0 0 0 0 0 0 0 0 0 0 0 -5.8851 10.5169 -7.7457 C 0 0 0 0 0 0 0 0 0 0 0 0 -7.2334 9.8517 -7.9879 C 0 0 0 0 0 0 0 0 0 0 0 0 -8.0159 10.4377 -7.5059 H 0 0 0 0 0 0 0 0 0 0 0 0 -7.2295 8.8924 -7.4690 H 0 0 0 0 0 0 0 0 0 0 0 0 -7.5740 9.6595 -9.4434 C 0 0 0 0 0 0 0 0 0 0 0 0 -8.2466 8.6100 -9.8517 N 0 0 0 0 0 0 0 0 0 0 0 0 -8.4161 8.7528 -11.1901 N 0 0 0 0 0 0 0 0 0 0 0 0 -8.9325 8.0540 -11.7148 H 0 0 0 0 0 0 0 0 0 0 0 0 -7.8492 9.9034 -11.6988 C 0 0 0 0 0 0 0 0 0 0 0 0 -7.2733 10.5152 -10.5542 C 0 0 0 0 0 0 0 0 0 0 0 0 -6.5852 11.7254 -10.7494 C 0 0 0 0 0 0 0 0 0 0 0 0 -6.1416 12.2127 -9.8955 H 0 0 0 0 0 0 0 0 0 0 0 0 -6.4115 12.2761 -12.0371 C 0 0 0 0 0 0 0 0 0 0 0 0 -5.5980 13.5247 -12.1904 C 0 0 0 0 0 0 0 0 0 0 0 0 -6.0453 14.4651 -12.8445 O 0 0 0 0 0 0 0 0 0 0 0 0 -4.4365 13.5849 -11.4988 N 0 0 0 0 0 0 0 0 0 0 0 0 -3.9078 14.8617 -11.0123 C 0 0 0 0 0 0 0 0 0 0 0 0 -3.8358 14.8270 -9.9235 H 0 0 0 0 0 0 0 0 0 0 0 0 -4.5618 15.7015 -11.2462 H 0 0 0 0 0 0 0 0 0 0 0 0 -2.5318 15.0946 -11.6256 C 0 0 0 0 0 0 0 0 0 0 0 0 -2.0928 16.0158 -11.2571 H 0 0 0 0 0 0 0 0 0 0 0 0 -2.6508 15.2154 -12.6977 H 0 0 0 0 0 0 0 0 0 0 0 0 -1.5867 13.9366 -11.2919 C 0 0 0 0 0 0 0 0 0 0 0 0 -0.6468 14.1050 -11.8040 H 0 0 0 0 0 0 0 0 0 0 0 0 -1.3643 13.9425 -10.2248 H 0 0 0 0 0 0 0 0 0 0 0 0 -2.1867 12.5771 -11.6800 C 0 0 0 0 0 0 0 0 0 0 0 0 -2.2113 12.4743 -12.7658 H 0 0 0 0 0 0 0 0 0 0 0 0 -1.5503 11.7721 -11.3123 H 0 0 0 0 0 0 0 0 0 0 0 0 -3.6081 12.4272 -11.1131 C 0 0 0 0 0 0 0 0 0 0 0 0 -3.5739 12.3558 -10.0267 H 0 0 0 0 0 0 0 0 0 0 0 0 -4.0136 11.4827 -11.4745 H 0 0 0 0 0 0 0 0 0 0 0 0 -7.0394 11.6742 -13.1502 C 0 0 0 0 0 0 0 0 0 0 0 0 -6.9504 12.1148 -14.1328 H 0 0 0 0 0 0 0 0 0 0 0 0 -7.7689 10.4812 -12.9779 C 0 0 0 0 0 0 0 0 0 0 0 0 -8.2463 10.0157 -13.8273 H 0 0 0 0 0 0 0 0 0 0 0 0 -5.8146 11.8190 -7.2061 C 0 0 0 0 0 0 0 0 0 0 0 0 -6.7182 12.3646 -6.9754 H 0 0 0 0 0 0 0 0 0 0 0 0 -4.5653 12.4185 -6.9578 C 0 0 0 0 0 0 0 0 0 0 0 0 -4.5306 13.4109 -6.5337 H 0 0 0 0 0 0 0 0 0 0 0 0 1 2 1 0 2 11 1 0 2 3 2 0 3 4 1 0 4 5 1 0 4 9 1 0 5 6 1 0 5 7 1 0 5 8 1 0 9 10 1 0 9 11 2 0 11 12 1 0 12 54 1 0 12 13 2 0 13 14 1 0 13 15 1 0 15 16 1 0 15 17 2 0 17 18 1 0 17 52 1 0 18 19 1 0 18 20 1 0 18 21 1 0 21 26 1 0 21 22 2 0 22 23 1 0 23 24 1 0 23 25 1 0 25 50 1 0 25 26 2 0 26 27 1 0 27 28 1 0 27 29 2 0 29 30 1 0 29 48 1 0 30 31 2 0 30 32 1 0 32 45 1 0 32 33 1 0 33 34 1 0 33 35 1 0 33 36 1 0 36 37 1 0 36 38 1 0 36 39 1 0 39 40 1 0 39 41 1 0 39 42 1 0 42 43 1 0 42 44 1 0 42 45 1 0 45 46 1 0 45 47 1 0 48 49 1 0 48 50 2 0 50 51 1 0 52 53 1 0 52 54 2 0 54 55 1 0 M END > ligprep_cdk8.smi > 29 > 53161 > 0 > W0NIM11uMW5bY0hdYyhbY0hdMSktYzJbY0hdW2NIXWMoW2NIXVtjSF0yKVtDSDJdYyhuW25IXTMpYyhjMzQpW2NIXWMoW2NIXVtjSF00KUMoPU8pTjVbQ0gyXVtDSDJdW0NIMl1bQ0gyXVtDSDJdNQ== > J2VwaWtfcHl0aG9uJywgJy1waHQnLCAnMC4wJywgJy1waCcsICc3LjQnLCAnLXRuJywgJzgnLCAnLW1hJywgJzUwMCcsICctaW1hZScsICc8aW5maWxlLm1hZT4nLCAnLW9tYWUnLCAnPG91dGZpbGUubWFlPic= > 1 > 0.0001 > 0.0000 > lig_41 > 0.04415452727272727 0.31125452727272723 -0.50974547272727277 0.086454527272727275 0.040654527272727267 0.058421527272727272 0.058421527272727272 0.058421527272727272 -0.12924547272727271 0.17605452727272727 -0.2122454727272727 0.01605452727272727 -0.12894547272727272 0.13005452727272729 -0.11594547272727274 0.13555452727272729 -0.087245472727272733 -0.04234547272727273 0.066254527272727265 0.066254527272727265 0.36395452727272726 -0.51304547272727274 -0.01604547272727273 0.32075452727272724 -0.037145472727272727 -0.21884547272727273 -0.025945472727272729 0.14905452727272728 -0.16554547272727271 0.66475452727272721 -0.59604547272727271 -0.45074547272727272 0.076554527272727269 0.060504527272727267 0.060504527272727267 -0.10334547272727274 0.050254527272727272 0.050254527272727272 -0.078345472727272727 0.042254527272727271 0.042254527272727271 -0.10334547272727274 0.050254527272727272 0.050254527272727272 0.076554527272727269 0.060504527272727267 0.060504527272727267 -0.059945472727272728 0.15105452727272728 -0.14894547272727271 0.14405452727272727 -0.11594547272727274 0.13555452727272729 -0.12894547272727272 0.13005452727272729 $$$$ lig_30 RDKit 3D 53 57 0 0 0 0 0 0 0 0999 V2000 -0.7872 12.8089 -12.2992 H 0 0 0 0 0 0 0 0 0 0 0 0 -1.6810 12.4903 -12.2318 O 0 0 0 0 0 0 0 0 0 0 0 0 -2.2207 12.9887 -11.0250 C 0 0 2 0 0 0 0 0 0 0 0 0 -1.6495 12.5822 -10.1897 H 0 0 0 0 0 0 0 0 0 0 0 0 -3.6815 12.5709 -10.9758 C 0 0 0 0 0 0 0 0 0 0 0 0 -3.8462 11.6095 -11.4691 H 0 0 0 0 0 0 0 0 0 0 0 0 -3.9905 12.4692 -9.9390 H 0 0 0 0 0 0 0 0 0 0 0 0 -4.4241 13.6755 -11.5866 N 0 0 0 0 0 0 0 0 0 0 0 0 -5.6265 13.5854 -12.1973 C 0 0 0 0 0 0 0 0 0 0 0 0 -6.0768 14.4908 -12.8958 O 0 0 0 0 0 0 0 0 0 0 0 0 -6.4289 12.3272 -12.0050 C 0 0 0 0 0 0 0 0 0 0 0 0 -6.6168 11.7969 -10.7099 C 0 0 0 0 0 0 0 0 0 0 0 0 -6.2085 12.3107 -9.8540 H 0 0 0 0 0 0 0 0 0 0 0 0 -7.2892 10.5758 -10.5034 C 0 0 0 0 0 0 0 0 0 0 0 0 -7.8466 9.9372 -11.6429 C 0 0 0 0 0 0 0 0 0 0 0 0 -7.7616 10.4948 -12.9294 C 0 0 0 0 0 0 0 0 0 0 0 0 -8.2338 10.0090 -13.7712 H 0 0 0 0 0 0 0 0 0 0 0 0 -7.0367 11.6895 -13.1113 C 0 0 0 0 0 0 0 0 0 0 0 0 -6.9384 12.1042 -14.1037 H 0 0 0 0 0 0 0 0 0 0 0 0 -8.4087 8.7895 -11.1253 N 0 0 0 0 0 0 0 0 0 0 0 0 -8.9146 8.0807 -11.6463 H 0 0 0 0 0 0 0 0 0 0 0 0 -8.2463 8.6650 -9.7838 N 0 0 0 0 0 0 0 0 0 0 0 0 -7.5899 9.7283 -9.3851 C 0 0 0 0 0 0 0 0 0 0 0 0 -7.2591 9.9313 -7.9327 C 0 0 0 0 0 0 0 0 0 0 0 0 -8.0228 10.5596 -7.4737 H 0 0 0 0 0 0 0 0 0 0 0 0 -7.3026 8.9850 -7.3918 H 0 0 0 0 0 0 0 0 0 0 0 0 -5.8857 10.5450 -7.6982 C 0 0 0 0 0 0 0 0 0 0 0 0 -4.7155 9.8390 -8.0465 C 0 0 0 0 0 0 0 0 0 0 0 0 -4.7899 8.8534 -8.4813 H 0 0 0 0 0 0 0 0 0 0 0 0 -3.4457 10.3996 -7.7905 C 0 0 0 0 0 0 0 0 0 0 0 0 -2.5579 9.8333 -8.0362 H 0 0 0 0 0 0 0 0 0 0 0 0 -3.3257 11.6858 -7.2212 C 0 0 0 0 0 0 0 0 0 0 0 0 -2.0109 12.2862 -6.9485 C 0 0 0 0 0 0 0 0 0 0 0 0 -0.9802 11.7445 -6.2408 C 0 0 0 0 0 0 0 0 0 0 0 0 -0.8730 10.8064 -5.7341 H 0 0 0 0 0 0 0 0 0 0 0 0 0.0037 12.7029 -6.1759 N 0 0 0 0 0 0 0 0 0 0 0 0 1.2605 12.6437 -5.4522 C 0 0 0 0 0 0 0 0 0 0 0 0 1.2787 11.7660 -4.8062 H 0 0 0 0 0 0 0 0 0 0 0 0 2.1045 12.5820 -6.1327 H 0 0 0 0 0 0 0 0 0 0 0 0 1.3738 13.5350 -4.8370 H 0 0 0 0 0 0 0 0 0 0 0 0 -0.3416 13.8252 -6.8501 N 0 0 0 0 0 0 0 0 0 0 0 0 -1.5621 13.5856 -7.3107 C 0 0 0 0 0 0 0 0 0 0 0 0 -2.0765 14.3558 -7.8632 H 0 0 0 0 0 0 0 0 0 0 0 0 -4.5022 12.3907 -6.8902 C 0 0 0 0 0 0 0 0 0 0 0 0 -4.4324 13.3680 -6.4362 H 0 0 0 0 0 0 0 0 0 0 0 0 -5.7707 11.8235 -7.1167 C 0 0 0 0 0 0 0 0 0 0 0 0 -6.6533 12.3780 -6.8411 H 0 0 0 0 0 0 0 0 0 0 0 0 -3.5752 14.8613 -11.7075 C 0 0 0 0 0 0 0 0 0 0 0 0 -4.0336 15.7303 -11.2344 H 0 0 0 0 0 0 0 0 0 0 0 0 -3.4217 15.0942 -12.7628 H 0 0 0 0 0 0 0 0 0 0 0 0 -2.2458 14.5110 -11.0388 C 0 0 0 0 0 0 0 0 0 0 0 0 -2.2410 14.8972 -10.0218 H 0 0 0 0 0 0 0 0 0 0 0 0 -1.3883 14.9475 -11.5541 H 0 0 0 0 0 0 0 0 0 0 0 0 1 2 1 0 2 3 1 0 3 51 1 0 3 4 1 1 3 5 1 0 5 6 1 0 5 7 1 0 5 8 1 0 8 9 1 0 8 48 1 0 9 10 2 0 9 11 1 0 11 18 1 0 11 12 2 0 12 13 1 0 12 14 1 0 14 23 1 0 14 15 2 0 15 16 1 0 15 20 1 0 16 17 1 0 16 18 2 0 18 19 1 0 20 21 1 0 20 22 1 0 22 23 2 0 23 24 1 0 24 25 1 0 24 26 1 0 24 27 1 0 27 46 1 0 27 28 2 0 28 29 1 0 28 30 1 0 30 31 1 0 30 32 2 0 32 33 1 0 32 44 1 0 33 42 1 0 33 34 2 0 34 35 1 0 34 36 1 0 36 37 1 0 36 41 1 0 37 38 1 0 37 39 1 0 37 40 1 0 41 42 2 0 42 43 1 0 44 45 1 0 44 46 2 0 46 47 1 0 48 49 1 0 48 50 1 0 48 51 1 0 51 52 1 0 51 53 1 0 M END > ligprep_cdk8.smi > 18 > 53161 > 0 > W09IXVtDQEBIXTFbQ0gyXU4oW0NIMl1bQ0gyXTEpQyg9TyljKFtjSF0yKVtjSF1bY0hdYyhjMjMpW25IXW5jM1tDSDJdYzRbY0hdW2NIXWMoW2NIXVtjSF00KS1jNVtjSF1uKFtDSDNdKW5bY0hdNQ== > J2VwaWtfcHl0aG9uJywgJy1waHQnLCAnMC4wJywgJy1waCcsICc3LjQnLCAnLXRuJywgJzgnLCAnLW1hJywgJzUwMCcsICctaW1hZScsICc8aW5maWxlLm1hZT4nLCAnLW9tYWUnLCAnPG91dGZpbGUubWFlPic= > 1 > 0.0001 > 0.0000 > 0.0001 > -0.0000 > 0 > 0 > 0 > S-OPLS > 35.030500000000004 > 1 > lig_30-1 > glide-grid_CDK8-5HNB > 18 > 6 > -10.579279438061199 > -0.35264264793537298 > -1.0957426974081499 > -2.40372755880942 > -10.579279438061199 > -4.1426126450426102 > -0.84002522740766805 > 0 > -2.4153608052563298 > -49.6699028015137 > -8.0594644546508807 > 0.51113404791874395 > 0 > -93.737816678333004 > -57.729367256164601 > 3.3176975250244101 > 2 > 10 > 0 > 0.057393311469585498 > snapped_core_restrain > lig_30 > 0.40396224528301888 -0.59383775471698108 0.12506224528301885 0.047662245283018864 0.07596224528301887 0.067162245283018868 0.067162245283018868 -0.44783775471698112 0.66666224528301887 -0.59313775471698105 -0.16863775471698114 -0.022037754716981134 0.14796224528301885 -0.22093775471698116 -0.032237754716981135 -0.15103775471698114 0.14396224528301885 -0.055037754716981135 0.15396224528301886 -0.018137754716981137 0.32366224528301885 -0.51213775471698109 0.36286224528301886 -0.041437754716981134 0.065162245283018866 0.065162245283018866 -0.08633775471698113 -0.11603775471698113 0.13496224528301887 -0.12853775471698115 0.12946224528301886 0.015962245283018865 -0.21133775471698113 -0.12933775471698114 0.17696224528301885 0.086362245283018876 0.040562245283018862 0.058329245283018867 0.058329245283018867 0.058329245283018867 -0.50983775471698112 0.31116224528301883 0.044062245283018865 -0.12853775471698115 0.12946224528301886 -0.11603775471698113 0.13496224528301887 0.074962245283018869 0.064162245283018865 0.064162245283018865 -0.13343775471698113 0.058662245283018867 0.058662245283018867 $$$$ ================================================ FILE: src/openfe/tests/data/cdk8/cdk8_protein.pdb ================================================ HEADER TRANSFERASE 18-JAN-16 5HNB TITLE CDK8-CYCC IN COMPLEX WITH TITLE 2 [6-HYDROXY-3-(3-METHYL-BENZYL)-1H-INDAZOL-5- TITLE 3 YL]-((S)-3-HYDROXY-PYRROLIDIN-1-YL)-METHANONE EXPDTA X-RAY DIFFRACTION REMARK 2 RESOLUTION. 2.35 ANGSTROMS REMARK 3 R VALUE : 0.217000 REMARK 3 FREE R VALUE : 0.252000 REMARK 4 5HNB COMPLIES WITH FORMAT V. 3.30, REMARK 200 TEMPERATURE (KELVIN) : 100.00 REMARK 200 PH : 6.90 REMARK 350 BIOMOLECULE: 1 REMARK 350 APPLY THE FOLLOWING TO CHAINS: A, B REMARK 350 BIOMT1 1 1.000000 0.000000 0.000000 0.000000 REMARK 350 BIOMT2 1 0.000000 1.000000 0.000000 0.000000 REMARK 350 BIOMT3 1 0.000000 0.000000 1.000000 0.000000 REMARK 888 REMARK 888 WRITTEN BY MAESTRO (A PRODUCT OF SCHRODINGER, LLC) SEQRES 1 A 364 ACE ASP ASP LYS MET ASP TYR ASP PHE LYS VAL LYS LEU SEQRES 2 A 364 SER SER GLU ARG GLU ARG VAL GLU ASP LEU PHE GLU TYR SEQRES 3 A 364 GLU GLY CYS LYS VAL GLY ARG GLY THR TYR GLY HIS VAL SEQRES 4 A 364 TYR LYS ALA LYS ARG LYS ASP GLY LYS ASP ASP LYS ASP SEQRES 5 A 364 TYR ALA LEU LYS GLN ILE GLU GLY THR GLY ILE SER MET SEQRES 6 A 364 SER ALA CYS ARG GLU ILE ALA LEU LEU ARG GLU LEU LYS SEQRES 7 A 364 HIS PRO ASN VAL ILE SER LEU GLN LYS VAL PHE LEU SER SEQRES 8 A 364 HIS ALA ASP ARG LYS VAL TRP LEU LEU PHE ASP TYR ALA SEQRES 9 A 364 GLU HIS ASP LEU TRP HIS ILE ILE LYS PHE HIS ARG ALA SEQRES 10 A 364 SER LYS ALA ASN LYS LYS PRO VAL GLN LEU PRO ARG GLY SEQRES 11 A 364 MET VAL LYS SER LEU LEU TYR GLN ILE LEU ASP GLY ILE SEQRES 12 A 364 HIS TYR LEU HIS ALA ASN TRP VAL LEU HIS ARG ASP LEU SEQRES 13 A 364 LYS PRO ALA ASN ILE LEU VAL MET GLY GLU GLY PRO GLU SEQRES 14 A 364 ARG GLY ARG VAL LYS ILE ALA ASP MET GLY PHE ALA ARG SEQRES 15 A 364 LEU PHE ASN SER PRO LEU LYS PRO LEU ALA ASP LEU ASP SEQRES 16 A 364 PRO VAL VAL VAL THR PHE TRP TYR ARG ALA PRO GLU LEU SEQRES 17 A 364 LEU LEU GLY ALA ARG HIS TYR THR LYS ALA ILE ASP ILE SEQRES 18 A 364 TRP ALA ILE GLY CYS ILE PHE ALA GLU LEU LEU THR SER SEQRES 19 A 364 GLU PRO ILE PHE HIS CYS ARG GLN GLU ASP ILE LYS THR SEQRES 20 A 364 SER ASN PRO TYR HIS HIS ASP GLN LEU ASP ARG ILE PHE SEQRES 21 A 364 ASN VAL MET GLY PHE PRO ALA ASP LYS ASP TRP GLU ASP SEQRES 22 A 364 ILE LYS LYS MET PRO GLU HIS SER THR LEU MET LYS ASP SEQRES 23 A 364 PHE ARG ARG ASN THR TYR THR ASN CYS SER LEU ILE LYS SEQRES 24 A 364 TYR MET GLU LYS HIS LYS VAL LYS PRO ASP SER LYS ALA SEQRES 25 A 364 PHE HIS LEU LEU GLN LYS LEU LEU THR MET ASP PRO ILE SEQRES 26 A 364 LYS ARG ILE THR SER GLU GLN ALA MET GLN ASP PRO TYR SEQRES 27 A 364 PHE LEU GLU ASP PRO LEU PRO THR SER ASP VAL PHE ALA SEQRES 28 A 364 GLY CYS GLN ILE PRO TYR PRO LYS ARG GLU PHE LEU NME SEQRES 1 B 268 ACE LYS ALA MET ALA GLY ASN PHE TRP GLN SER SER HIS SEQRES 2 B 268 TYR LEU GLN TRP ILE LEU ASP LYS GLN ASP LEU LEU LYS SEQRES 3 B 268 GLU ARG GLN LYS ASP LEU LYS PHE LEU SER GLU GLU GLU SEQRES 4 B 268 TYR TRP LYS LEU GLN ILE PHE PHE THR ASN VAL ILE GLN SEQRES 5 B 268 ALA LEU GLY GLU HIS LEU LYS LEU ARG GLN GLN VAL ILE SEQRES 6 B 268 ALA THR ALA THR VAL TYR PHE LYS ARG PHE TYR ALA ARG SEQRES 7 B 268 TYR SER LEU LYS SER ILE ASP PRO VAL LEU MET ALA PRO SEQRES 8 B 268 THR CYS VAL PHE LEU ALA SER LYS VAL GLU GLU PHE GLY SEQRES 9 B 268 VAL VAL SER ASN THR ARG LEU ILE ALA ALA ALA THR SER SEQRES 10 B 268 VAL LEU LYS THR ARG PHE SER TYR ALA PHE PRO LYS GLU SEQRES 11 B 268 PHE PRO TYR ARG MET ASN HIS ILE LEU GLU CYS GLU PHE SEQRES 12 B 268 TYR LEU LEU GLU LEU MET ASP CYS CYS LEU ILE VAL TYR SEQRES 13 B 268 HIS PRO TYR ARG PRO LEU LEU GLN TYR VAL GLN ASP MET SEQRES 14 B 268 GLY GLN GLU ASP MET LEU LEU PRO LEU ALA TRP ARG ILE SEQRES 15 B 268 VAL ASN ASP THR TYR ARG THR ASP LEU CYS LEU LEU TYR SEQRES 16 B 268 PRO PRO PHE MET ILE ALA LEU ALA CYS LEU HIS VAL ALA SEQRES 17 B 268 CYS VAL VAL GLN GLN LYS ASP ALA ARG GLN TRP PHE ALA SEQRES 18 B 268 GLU LEU SER VAL ASP MET GLU LYS ILE LEU GLU ILE ILE SEQRES 19 B 268 ARG VAL ILE LEU LYS LEU TYR GLU GLN TRP LYS ASN PHE SEQRES 20 B 268 ASP GLU ARG LYS GLU MET ALA THR ILE LEU SER LYS MET SEQRES 21 B 268 PRO LYS PRO LYS PRO PRO PRO NME HELIX 1 1 TYR A 3 TYR A 3 1 HELIX 2 2 ASP A 4 ASP A 4 1 HELIX 3 3 PHE A 5 PHE A 5 1 HELIX 4 4 LYS A 6 LYS A 6 1 HELIX 5 5 VAL A 7 VAL A 7 1 HELIX 6 6 LYS A 8 LYS A 8 1 HELIX 7 7 LEU A 9 LEU A 9 1 HELIX 8 8 SER A 10 SER A 10 1 HELIX 9 9 SER A 11 SER A 11 1 HELIX 10 10 GLU A 12 GLU A 12 1 HELIX 11 11 VAL A 16 VAL A 16 1 HELIX 12 12 GLU A 17 GLU A 17 1 HELIX 13 13 ASP A 18 ASP A 18 1 HELIX 14 14 LEU A 19 LEU A 19 1 HELIX 15 15 MET A 61 MET A 61 1 HELIX 16 16 SER A 62 SER A 62 1 HELIX 17 17 ALA A 63 ALA A 63 1 HELIX 18 18 CYS A 64 CYS A 64 1 HELIX 19 19 ARG A 65 ARG A 65 1 HELIX 20 20 GLU A 66 GLU A 66 1 HELIX 21 21 ILE A 67 ILE A 67 1 HELIX 22 22 ALA A 68 ALA A 68 1 HELIX 23 23 LEU A 69 LEU A 69 1 HELIX 24 24 LEU A 70 LEU A 70 1 HELIX 25 25 ARG A 71 ARG A 71 1 HELIX 26 26 GLU A 72 GLU A 72 1 HELIX 27 27 LEU A 104 LEU A 104 1 HELIX 28 28 TRP A 105 TRP A 105 1 HELIX 29 29 HIS A 106 HIS A 106 1 HELIX 30 30 ILE A 107 ILE A 107 1 HELIX 31 31 ILE A 108 ILE A 108 1 HELIX 32 32 LYS A 109 LYS A 109 1 HELIX 33 33 PHE A 110 PHE A 110 1 HELIX 34 34 HIS A 111 HIS A 111 1 HELIX 35 35 ARG A 112 ARG A 112 1 HELIX 36 36 ALA A 113 ALA A 113 1 HELIX 37 37 GLY A 126 GLY A 126 1 HELIX 38 38 MET A 127 MET A 127 1 HELIX 39 39 VAL A 128 VAL A 128 1 HELIX 40 40 LYS A 129 LYS A 129 1 HELIX 41 41 SER A 130 SER A 130 1 HELIX 42 42 LEU A 131 LEU A 131 1 HELIX 43 43 LEU A 132 LEU A 132 1 HELIX 44 44 TYR A 133 TYR A 133 1 HELIX 45 45 GLN A 134 GLN A 134 1 HELIX 46 46 ILE A 135 ILE A 135 1 HELIX 47 47 LEU A 136 LEU A 136 1 HELIX 48 48 ASP A 137 ASP A 137 1 HELIX 49 49 GLY A 138 GLY A 138 1 HELIX 50 50 ILE A 139 ILE A 139 1 HELIX 51 51 HIS A 140 HIS A 140 1 HELIX 52 52 TYR A 141 TYR A 141 1 HELIX 53 53 LEU A 142 LEU A 142 1 HELIX 54 54 HIS A 143 HIS A 143 1 HELIX 55 55 ALA A 144 ALA A 144 1 HELIX 56 56 LYS A 213 LYS A 213 1 HELIX 57 57 ALA A 214 ALA A 214 1 HELIX 58 58 ILE A 215 ILE A 215 1 HELIX 59 59 ASP A 216 ASP A 216 1 HELIX 60 60 ILE A 217 ILE A 217 1 HELIX 61 61 TRP A 218 TRP A 218 1 HELIX 62 62 ALA A 219 ALA A 219 1 HELIX 63 63 ILE A 220 ILE A 220 1 HELIX 64 64 GLY A 221 GLY A 221 1 HELIX 65 65 CYS A 222 CYS A 222 1 HELIX 66 66 ILE A 223 ILE A 223 1 HELIX 67 67 PHE A 224 PHE A 224 1 HELIX 68 68 ALA A 225 ALA A 225 1 HELIX 69 69 GLU A 226 GLU A 226 1 HELIX 70 70 LEU A 227 LEU A 227 1 HELIX 71 71 LEU A 228 LEU A 228 1 HELIX 72 72 THR A 229 THR A 229 1 HELIX 73 73 HIS A 249 HIS A 249 1 HELIX 74 74 ASP A 250 ASP A 250 1 HELIX 75 75 GLN A 251 GLN A 251 1 HELIX 76 76 LEU A 252 LEU A 252 1 HELIX 77 77 ASP A 253 ASP A 253 1 HELIX 78 78 ARG A 254 ARG A 254 1 HELIX 79 79 ILE A 255 ILE A 255 1 HELIX 80 80 PHE A 256 PHE A 256 1 HELIX 81 81 ASN A 257 ASN A 257 1 HELIX 82 82 VAL A 258 VAL A 258 1 HELIX 83 83 MET A 259 MET A 259 1 HELIX 84 84 HIS A 276 HIS A 276 1 HELIX 85 85 SER A 277 SER A 277 1 HELIX 86 86 THR A 278 THR A 278 1 HELIX 87 87 LEU A 279 LEU A 279 1 HELIX 88 88 MET A 280 MET A 280 1 HELIX 89 89 LYS A 281 LYS A 281 1 HELIX 90 90 ASP A 282 ASP A 282 1 HELIX 91 91 LEU A 293 LEU A 293 1 HELIX 92 92 ILE A 294 ILE A 294 1 HELIX 93 93 LYS A 295 LYS A 295 1 HELIX 94 94 TYR A 296 TYR A 296 1 HELIX 95 95 MET A 297 MET A 297 1 HELIX 96 96 GLU A 298 GLU A 298 1 HELIX 97 97 LYS A 299 LYS A 299 1 HELIX 98 98 LYS A 307 LYS A 307 1 HELIX 99 99 ALA A 308 ALA A 308 1 HELIX 100 100 PHE A 309 PHE A 309 1 HELIX 101 101 HIS A 310 HIS A 310 1 HELIX 102 102 LEU A 311 LEU A 311 1 HELIX 103 103 LEU A 312 LEU A 312 1 HELIX 104 104 GLN A 313 GLN A 313 1 HELIX 105 105 LYS A 314 LYS A 314 1 HELIX 106 106 LEU A 315 LEU A 315 1 HELIX 107 107 SER A 326 SER A 326 1 HELIX 108 108 GLU A 327 GLU A 327 1 HELIX 109 109 GLN A 328 GLN A 328 1 HELIX 110 110 ALA A 329 ALA A 329 1 HELIX 111 111 MET A 330 MET A 330 1 HELIX 112 112 SER B 9 SER B 9 1 HELIX 113 113 HIS B 10 HIS B 10 1 HELIX 114 114 TYR B 11 TYR B 11 1 HELIX 115 115 LEU B 12 LEU B 12 1 HELIX 116 116 GLN B 13 GLN B 13 1 HELIX 117 117 TRP B 14 TRP B 14 1 HELIX 118 118 LYS B 18 LYS B 18 1 HELIX 119 119 GLN B 19 GLN B 19 1 HELIX 120 120 ASP B 20 ASP B 20 1 HELIX 121 121 LEU B 21 LEU B 21 1 HELIX 122 122 LEU B 22 LEU B 22 1 HELIX 123 123 LYS B 23 LYS B 23 1 HELIX 124 124 GLU B 24 GLU B 24 1 HELIX 125 125 ARG B 25 ARG B 25 1 HELIX 126 126 GLN B 26 GLN B 26 1 HELIX 127 127 LYS B 27 LYS B 27 1 HELIX 128 128 ASP B 28 ASP B 28 1 HELIX 129 129 LEU B 29 LEU B 29 1 HELIX 130 130 GLU B 34 GLU B 34 1 HELIX 131 131 GLU B 35 GLU B 35 1 HELIX 132 132 GLU B 36 GLU B 36 1 HELIX 133 133 TYR B 37 TYR B 37 1 HELIX 134 134 TRP B 38 TRP B 38 1 HELIX 135 135 LYS B 39 LYS B 39 1 HELIX 136 136 LEU B 40 LEU B 40 1 HELIX 137 137 GLN B 41 GLN B 41 1 HELIX 138 138 ILE B 42 ILE B 42 1 HELIX 139 139 PHE B 43 PHE B 43 1 HELIX 140 140 PHE B 44 PHE B 44 1 HELIX 141 141 THR B 45 THR B 45 1 HELIX 142 142 ASN B 46 ASN B 46 1 HELIX 143 143 VAL B 47 VAL B 47 1 HELIX 144 144 ILE B 48 ILE B 48 1 HELIX 145 145 GLN B 49 GLN B 49 1 HELIX 146 146 ALA B 50 ALA B 50 1 HELIX 147 147 LEU B 51 LEU B 51 1 HELIX 148 148 GLY B 52 GLY B 52 1 HELIX 149 149 GLU B 53 GLU B 53 1 HELIX 150 150 HIS B 54 HIS B 54 1 HELIX 151 151 GLN B 59 GLN B 59 1 HELIX 152 152 GLN B 60 GLN B 60 1 HELIX 153 153 VAL B 61 VAL B 61 1 HELIX 154 154 ILE B 62 ILE B 62 1 HELIX 155 155 ALA B 63 ALA B 63 1 HELIX 156 156 THR B 64 THR B 64 1 HELIX 157 157 ALA B 65 ALA B 65 1 HELIX 158 158 THR B 66 THR B 66 1 HELIX 159 159 VAL B 67 VAL B 67 1 HELIX 160 160 TYR B 68 TYR B 68 1 HELIX 161 161 PHE B 69 PHE B 69 1 HELIX 162 162 LYS B 70 LYS B 70 1 HELIX 163 163 ARG B 71 ARG B 71 1 HELIX 164 164 PHE B 72 PHE B 72 1 HELIX 165 165 TYR B 73 TYR B 73 1 HELIX 166 166 ALA B 74 ALA B 74 1 HELIX 167 167 ARG B 75 ARG B 75 1 HELIX 168 168 ALA B 87 ALA B 87 1 HELIX 169 169 PRO B 88 PRO B 88 1 HELIX 170 170 THR B 89 THR B 89 1 HELIX 171 171 CYS B 90 CYS B 90 1 HELIX 172 172 VAL B 91 VAL B 91 1 HELIX 173 173 PHE B 92 PHE B 92 1 HELIX 174 174 LEU B 93 LEU B 93 1 HELIX 175 175 ALA B 94 ALA B 94 1 HELIX 176 176 SER B 95 SER B 95 1 HELIX 177 177 LYS B 96 LYS B 96 1 HELIX 178 178 VAL B 97 VAL B 97 1 HELIX 179 179 ASN B 105 ASN B 105 1 HELIX 180 180 THR B 106 THR B 106 1 HELIX 181 181 ARG B 107 ARG B 107 1 HELIX 182 182 LEU B 108 LEU B 108 1 HELIX 183 183 ILE B 109 ILE B 109 1 HELIX 184 184 ALA B 110 ALA B 110 1 HELIX 185 185 ALA B 111 ALA B 111 1 HELIX 186 186 ALA B 112 ALA B 112 1 HELIX 187 187 THR B 113 THR B 113 1 HELIX 188 188 SER B 114 SER B 114 1 HELIX 189 189 VAL B 115 VAL B 115 1 HELIX 190 190 LEU B 116 LEU B 116 1 HELIX 191 191 LYS B 117 LYS B 117 1 HELIX 192 192 THR B 118 THR B 118 1 HELIX 193 193 ARG B 119 ARG B 119 1 HELIX 194 194 MET B 132 MET B 132 1 HELIX 195 195 ASN B 133 ASN B 133 1 HELIX 196 196 HIS B 134 HIS B 134 1 HELIX 197 197 ILE B 135 ILE B 135 1 HELIX 198 198 LEU B 136 LEU B 136 1 HELIX 199 199 GLU B 137 GLU B 137 1 HELIX 200 200 CYS B 138 CYS B 138 1 HELIX 201 201 GLU B 139 GLU B 139 1 HELIX 202 202 PHE B 140 PHE B 140 1 HELIX 203 203 TYR B 141 TYR B 141 1 HELIX 204 204 LEU B 142 LEU B 142 1 HELIX 205 205 LEU B 143 LEU B 143 1 HELIX 206 206 GLU B 144 GLU B 144 1 HELIX 207 207 LEU B 145 LEU B 145 1 HELIX 208 208 ARG B 157 ARG B 157 1 HELIX 209 209 PRO B 158 PRO B 158 1 HELIX 210 210 LEU B 159 LEU B 159 1 HELIX 211 211 LEU B 160 LEU B 160 1 HELIX 212 212 GLN B 161 GLN B 161 1 HELIX 213 213 TYR B 162 TYR B 162 1 HELIX 214 214 VAL B 163 VAL B 163 1 HELIX 215 215 GLN B 164 GLN B 164 1 HELIX 216 216 ASP B 165 ASP B 165 1 HELIX 217 217 MET B 166 MET B 166 1 HELIX 218 218 GLU B 169 GLU B 169 1 HELIX 219 219 ASP B 170 ASP B 170 1 HELIX 220 220 MET B 171 MET B 171 1 HELIX 221 221 LEU B 172 LEU B 172 1 HELIX 222 222 LEU B 173 LEU B 173 1 HELIX 223 223 PRO B 174 PRO B 174 1 HELIX 224 224 LEU B 175 LEU B 175 1 HELIX 225 225 ALA B 176 ALA B 176 1 HELIX 226 226 TRP B 177 TRP B 177 1 HELIX 227 227 ARG B 178 ARG B 178 1 HELIX 228 228 ILE B 179 ILE B 179 1 HELIX 229 229 VAL B 180 VAL B 180 1 HELIX 230 230 ASN B 181 ASN B 181 1 HELIX 231 231 ASP B 182 ASP B 182 1 HELIX 232 232 THR B 183 THR B 183 1 HELIX 233 233 MET B 196 MET B 196 1 HELIX 234 234 ILE B 197 ILE B 197 1 HELIX 235 235 ALA B 198 ALA B 198 1 HELIX 236 236 LEU B 199 LEU B 199 1 HELIX 237 237 ALA B 200 ALA B 200 1 HELIX 238 238 CYS B 201 CYS B 201 1 HELIX 239 239 LEU B 202 LEU B 202 1 HELIX 240 240 HIS B 203 HIS B 203 1 HELIX 241 241 VAL B 204 VAL B 204 1 HELIX 242 242 ALA B 205 ALA B 205 1 HELIX 243 243 CYS B 206 CYS B 206 1 HELIX 244 244 VAL B 207 VAL B 207 1 HELIX 245 245 VAL B 208 VAL B 208 1 HELIX 246 246 ARG B 214 ARG B 214 1 HELIX 247 247 GLN B 215 GLN B 215 1 HELIX 248 248 TRP B 216 TRP B 216 1 HELIX 249 249 PHE B 217 PHE B 217 1 HELIX 250 250 ALA B 218 ALA B 218 1 HELIX 251 251 GLU B 219 GLU B 219 1 HELIX 252 252 MET B 224 MET B 224 1 HELIX 253 253 GLU B 225 GLU B 225 1 HELIX 254 254 LYS B 226 LYS B 226 1 HELIX 255 255 ILE B 227 ILE B 227 1 HELIX 256 256 LEU B 228 LEU B 228 1 HELIX 257 257 GLU B 229 GLU B 229 1 HELIX 258 258 ILE B 230 ILE B 230 1 HELIX 259 259 ILE B 231 ILE B 231 1 HELIX 260 260 ARG B 232 ARG B 232 1 HELIX 261 261 VAL B 233 VAL B 233 1 HELIX 262 262 ILE B 234 ILE B 234 1 HELIX 263 263 LEU B 235 LEU B 235 1 HELIX 264 264 LYS B 236 LYS B 236 1 HELIX 265 265 LEU B 237 LEU B 237 1 HELIX 266 266 TYR B 238 TYR B 238 1 HELIX 267 267 GLU B 239 GLU B 239 1 HELIX 268 268 GLN B 240 GLN B 240 1 HELIX 269 269 TRP B 241 TRP B 241 1 HELIX 270 270 LYS B 242 LYS B 242 1 HELIX 271 271 ASN B 243 ASN B 243 1 HELIX 272 272 GLU B 246 GLU B 246 1 HELIX 273 273 ARG B 247 ARG B 247 1 HELIX 274 274 LYS B 248 LYS B 248 1 HELIX 275 275 GLU B 249 GLU B 249 1 HELIX 276 276 MET B 250 MET B 250 1 HELIX 277 277 ALA B 251 ALA B 251 1 HELIX 278 278 THR B 252 THR B 252 1 HELIX 279 279 ILE B 253 ILE B 253 1 HELIX 280 280 LEU B 254 LEU B 254 1 HELIX 281 281 SER B 255 SER B 255 1 HELIX 282 282 LYS B 256 LYS B 256 1 TURN 1 1 ASP A -2 ASP A -2 TURN 2 2 ASP A -1 ASP A -1 TURN 3 3 LYS A 0 LYS A 0 TURN 4 4 MET A 1 MET A 1 TURN 5 5 ASP A 2 ASP A 2 TURN 6 6 ARG A 13 ARG A 13 TURN 7 7 GLU A 14 GLU A 14 TURN 8 8 ARG A 15 ARG A 15 TURN 9 9 TYR A 22 TYR A 22 TURN 10 10 GLU A 23 GLU A 23 TURN 11 11 GLY A 24 GLY A 24 TURN 12 12 CYS A 25 CYS A 25 TURN 13 13 GLY A 30 GLY A 30 TURN 14 14 THR A 31 THR A 31 TURN 15 15 TYR A 32 TYR A 32 TURN 16 16 LYS A 41 LYS A 41 TURN 17 17 ASP A 42 ASP A 42 TURN 18 18 GLY A 43 GLY A 43 TURN 19 19 LYS A 44 LYS A 44 TURN 20 20 ASP A 45 ASP A 45 TURN 21 21 ASP A 46 ASP A 46 TURN 22 22 LYS A 47 LYS A 47 TURN 23 23 GLU A 55 GLU A 55 TURN 24 24 GLY A 56 GLY A 56 TURN 25 25 THR A 57 THR A 57 TURN 26 26 GLY A 58 GLY A 58 TURN 27 27 ILE A 59 ILE A 59 TURN 28 28 SER A 60 SER A 60 TURN 29 29 LEU A 73 LEU A 73 TURN 30 30 LYS A 74 LYS A 74 TURN 31 31 HIS A 75 HIS A 75 TURN 32 32 PRO A 76 PRO A 76 TURN 33 33 ASN A 77 ASN A 77 TURN 34 34 VAL A 78 VAL A 78 TURN 35 35 ILE A 79 ILE A 79 TURN 36 36 SER A 80 SER A 80 TURN 37 37 HIS A 88 HIS A 88 TURN 38 38 ALA A 89 ALA A 89 TURN 39 39 ASP A 90 ASP A 90 TURN 40 40 ARG A 91 ARG A 91 TURN 41 41 TYR A 99 TYR A 99 TURN 42 42 ALA A 100 ALA A 100 TURN 43 43 GLU A 101 GLU A 101 TURN 44 44 HIS A 102 HIS A 102 TURN 45 45 ASP A 103 ASP A 103 TURN 46 46 SER A 114 SER A 114 TURN 47 47 LYS A 115 LYS A 115 TURN 48 48 ALA A 116 ALA A 116 TURN 49 49 ASN A 117 ASN A 117 TURN 50 50 LYS A 118 LYS A 118 TURN 51 51 LYS A 119 LYS A 119 TURN 52 52 PRO A 120 PRO A 120 TURN 53 53 VAL A 121 VAL A 121 TURN 54 54 GLN A 122 GLN A 122 TURN 55 55 LEU A 123 LEU A 123 TURN 56 56 PRO A 124 PRO A 124 TURN 57 57 ARG A 125 ARG A 125 TURN 58 58 ASN A 145 ASN A 145 TURN 59 59 TRP A 146 TRP A 146 TURN 60 60 VAL A 147 VAL A 147 TURN 61 61 LEU A 148 LEU A 148 TURN 62 62 HIS A 149 HIS A 149 TURN 63 63 ARG A 150 ARG A 150 TURN 64 64 ASP A 151 ASP A 151 TURN 65 65 LEU A 152 LEU A 152 TURN 66 66 LYS A 153 LYS A 153 TURN 67 67 PRO A 154 PRO A 154 TURN 68 68 ALA A 155 ALA A 155 TURN 69 69 ASN A 156 ASN A 156 TURN 70 70 MET A 160 MET A 160 TURN 71 71 GLY A 161 GLY A 161 TURN 72 72 GLU A 162 GLU A 162 TURN 73 73 GLY A 163 GLY A 163 TURN 74 74 PRO A 164 PRO A 164 TURN 75 75 GLU A 165 GLU A 165 TURN 76 76 ARG A 166 ARG A 166 TURN 77 77 GLY A 167 GLY A 167 TURN 78 78 ARG A 168 ARG A 168 TURN 79 79 ALA A 172 ALA A 172 TURN 80 80 ASP A 173 ASP A 173 TURN 81 81 MET A 174 MET A 174 TURN 82 82 GLY A 175 GLY A 175 TURN 83 83 PHE A 176 PHE A 176 TURN 84 84 ALA A 177 ALA A 177 TURN 85 85 ARG A 178 ARG A 178 TURN 86 86 LEU A 179 LEU A 179 TURN 87 87 PHE A 180 PHE A 180 TURN 88 88 ASN A 181 ASN A 181 TURN 89 89 SER A 182 SER A 182 TURN 90 90 PRO A 183 PRO A 183 TURN 91 91 LEU A 184 LEU A 184 TURN 92 92 LYS A 185 LYS A 185 TURN 93 93 LYS A 185 PRO A 186 TURN 94 94 LEU A 187 LEU A 187 TURN 95 95 ALA A 188 ALA A 188 TURN 96 96 ASP A 189 ASP A 189 TURN 97 97 LEU A 190 LEU A 190 TURN 98 98 ASP A 191 ASP A 191 TURN 99 99 PRO A 192 PRO A 192 TURN 100 100 VAL A 193 VAL A 193 TURN 101 101 VAL A 194 VAL A 194 TURN 102 102 VAL A 195 VAL A 195 TURN 103 103 THR A 196 THR A 196 TURN 104 104 THR A 196 THR A 196 TURN 105 105 PHE A 197 PHE A 197 TURN 106 106 TRP A 198 TRP A 198 TURN 107 107 TYR A 199 TYR A 199 TURN 108 108 ARG A 200 ARG A 200 TURN 109 109 ALA A 201 ALA A 201 TURN 110 110 PRO A 202 PRO A 202 TURN 111 111 GLU A 203 GLU A 203 TURN 112 112 LEU A 204 LEU A 204 TURN 113 113 LEU A 205 LEU A 205 TURN 114 114 LEU A 206 LEU A 206 TURN 115 115 GLY A 207 GLY A 207 TURN 116 116 ALA A 208 ALA A 208 TURN 117 117 ARG A 209 ARG A 209 TURN 118 118 HIS A 210 HIS A 210 TURN 119 119 TYR A 211 TYR A 211 TURN 120 120 THR A 212 THR A 212 TURN 121 121 SER A 230 SER A 230 TURN 122 122 GLU A 231 GLU A 231 TURN 123 123 PRO A 232 PRO A 232 TURN 124 124 ILE A 233 ILE A 233 TURN 125 125 PHE A 234 PHE A 234 TURN 126 126 HIS A 235 HIS A 235 TURN 127 127 CYS A 236 CYS A 236 TURN 128 128 ARG A 237 ARG A 237 TURN 129 129 GLN A 238 GLN A 238 TURN 130 130 GLU A 239 GLU A 239 TURN 131 131 GLU A 239 ASP A 240 TURN 132 132 ILE A 241 ILE A 241 TURN 133 133 LYS A 242 LYS A 242 TURN 134 134 THR A 243 THR A 243 TURN 135 135 SER A 244 SER A 244 TURN 136 136 SER A 244 SER A 244 TURN 137 137 ASN A 245 ASN A 245 TURN 138 138 PRO A 246 PRO A 246 TURN 139 139 TYR A 247 TYR A 247 TURN 140 140 HIS A 248 HIS A 248 TURN 141 141 GLY A 260 GLY A 260 TURN 142 142 PHE A 261 PHE A 261 TURN 143 143 PRO A 262 PRO A 262 TURN 144 144 ALA A 263 ALA A 263 TURN 145 145 ASP A 264 ASP A 264 TURN 146 146 LYS A 265 LYS A 265 TURN 147 147 ASP A 266 ASP A 266 TURN 148 148 TRP A 267 TRP A 267 TURN 149 149 GLU A 268 GLU A 268 TURN 150 150 ASP A 269 ASP A 269 TURN 151 151 ILE A 270 ILE A 270 TURN 152 152 LYS A 271 LYS A 271 TURN 153 153 LYS A 272 LYS A 272 TURN 154 154 MET A 273 MET A 273 TURN 155 155 PRO A 274 PRO A 274 TURN 156 156 GLU A 275 GLU A 275 TURN 157 157 PHE A 283 PHE A 283 TURN 158 158 ARG A 284 ARG A 284 TURN 159 159 ARG A 285 ARG A 285 TURN 160 160 ASN A 286 ASN A 286 TURN 161 161 THR A 287 THR A 287 TURN 162 162 TYR A 288 TYR A 288 TURN 163 163 THR A 289 THR A 289 TURN 164 164 ASN A 290 ASN A 290 TURN 165 165 CYS A 291 CYS A 291 TURN 166 166 SER A 292 SER A 292 TURN 167 167 HIS A 300 HIS A 300 TURN 168 168 LYS A 301 LYS A 301 TURN 169 169 VAL A 302 VAL A 302 TURN 170 170 LYS A 303 LYS A 303 TURN 171 171 PRO A 304 PRO A 304 TURN 172 172 ASP A 305 ASP A 305 TURN 173 173 SER A 306 SER A 306 TURN 174 174 LEU A 316 LEU A 316 TURN 175 175 THR A 317 THR A 317 TURN 176 176 MET A 318 MET A 318 TURN 177 177 ASP A 319 ASP A 319 TURN 178 178 PRO A 320 PRO A 320 TURN 179 179 ILE A 321 ILE A 321 TURN 180 180 LYS A 322 LYS A 322 TURN 181 181 ARG A 323 ARG A 323 TURN 182 182 ILE A 324 ILE A 324 TURN 183 183 THR A 325 THR A 325 TURN 184 184 GLN A 331 GLN A 331 TURN 185 185 ASP A 332 ASP A 332 TURN 186 186 PRO A 333 PRO A 333 TURN 187 187 TYR A 334 TYR A 334 TURN 188 188 PHE A 335 PHE A 335 TURN 189 189 LEU A 336 LEU A 336 TURN 190 190 GLU A 337 GLU A 337 TURN 191 191 ASP A 338 ASP A 338 TURN 192 192 PRO A 339 PRO A 339 TURN 193 193 LEU A 340 LEU A 340 TURN 194 194 PRO A 341 PRO A 341 TURN 195 195 THR A 342 THR A 342 TURN 196 196 SER A 343 SER A 343 TURN 197 197 ASP A 344 ASP A 344 TURN 198 198 VAL A 345 VAL A 345 TURN 199 199 PHE A 346 PHE A 346 TURN 200 200 ALA A 347 ALA A 347 TURN 201 201 GLY A 348 GLY A 348 TURN 202 202 CYS A 349 CYS A 349 TURN 203 203 GLN A 350 GLN A 350 TURN 204 204 ILE A 351 ILE A 351 TURN 205 205 PRO A 352 PRO A 352 TURN 206 206 TYR A 353 TYR A 353 TURN 207 207 PRO A 354 PRO A 354 TURN 208 208 LYS A 355 LYS A 355 TURN 209 209 ARG A 356 ARG A 356 TURN 210 210 GLU A 357 GLU A 357 TURN 211 211 PHE A 358 PHE A 358 TURN 212 212 LEU A 359 LEU A 359 TURN 213 213 LYS B -1 LYS B -1 TURN 214 214 ALA B 0 ALA B 0 TURN 215 215 MET B 1 MET B 1 TURN 216 216 ALA B 2 ALA B 2 TURN 217 217 GLY B 3 GLY B 3 TURN 218 218 ASN B 4 ASN B 4 TURN 219 219 PHE B 5 PHE B 5 TURN 220 220 TRP B 6 TRP B 6 TURN 221 221 GLN B 7 GLN B 7 TURN 222 222 SER B 8 SER B 8 TURN 223 223 ILE B 15 ILE B 15 TURN 224 224 LEU B 16 LEU B 16 TURN 225 225 ASP B 17 ASP B 17 TURN 226 226 LYS B 30 LYS B 30 TURN 227 227 PHE B 31 PHE B 31 TURN 228 228 LEU B 32 LEU B 32 TURN 229 229 SER B 33 SER B 33 TURN 230 230 LEU B 55 LEU B 55 TURN 231 231 LYS B 56 LYS B 56 TURN 232 232 LEU B 57 LEU B 57 TURN 233 233 ARG B 58 ARG B 58 TURN 234 234 TYR B 76 TYR B 76 TURN 235 235 SER B 77 SER B 77 TURN 236 236 LEU B 78 LEU B 78 TURN 237 237 LYS B 79 LYS B 79 TURN 238 238 SER B 80 SER B 80 TURN 239 239 ILE B 81 ILE B 81 TURN 240 240 ASP B 82 ASP B 82 TURN 241 241 PRO B 83 PRO B 83 TURN 242 242 VAL B 84 VAL B 84 TURN 243 243 LEU B 85 LEU B 85 TURN 244 244 MET B 86 MET B 86 TURN 245 245 GLU B 98 GLU B 98 TURN 246 246 GLU B 99 GLU B 99 TURN 247 247 PHE B 100 PHE B 100 TURN 248 248 GLY B 101 GLY B 101 TURN 249 249 VAL B 102 VAL B 102 TURN 250 250 VAL B 103 VAL B 103 TURN 251 251 SER B 104 SER B 104 TURN 252 252 PHE B 120 PHE B 120 TURN 253 253 SER B 121 SER B 121 TURN 254 254 TYR B 122 TYR B 122 TURN 255 255 ALA B 123 ALA B 123 TURN 256 256 PHE B 124 PHE B 124 TURN 257 257 PRO B 125 PRO B 125 TURN 258 258 LYS B 126 LYS B 126 TURN 259 259 GLU B 127 GLU B 127 TURN 260 260 PHE B 128 PHE B 128 TURN 261 261 PRO B 129 PRO B 129 TURN 262 262 TYR B 130 TYR B 130 TURN 263 263 ARG B 131 ARG B 131 TURN 264 264 MET B 146 MET B 146 TURN 265 265 ASP B 147 ASP B 147 TURN 266 266 CYS B 148 CYS B 148 TURN 267 267 CYS B 149 CYS B 149 TURN 268 268 LEU B 150 LEU B 150 TURN 269 269 ILE B 151 ILE B 151 TURN 270 270 VAL B 152 VAL B 152 TURN 271 271 TYR B 153 TYR B 153 TURN 272 272 HIS B 154 HIS B 154 TURN 273 273 PRO B 155 PRO B 155 TURN 274 274 TYR B 156 TYR B 156 TURN 275 275 GLY B 167 GLY B 167 TURN 276 276 GLN B 168 GLN B 168 TURN 277 277 TYR B 184 TYR B 184 TURN 278 278 ARG B 185 ARG B 185 TURN 279 279 THR B 186 THR B 186 TURN 280 280 ASP B 187 ASP B 187 TURN 281 281 LEU B 188 LEU B 188 TURN 282 282 CYS B 189 CYS B 189 TURN 283 283 LEU B 190 LEU B 190 TURN 284 284 LEU B 191 LEU B 191 TURN 285 285 TYR B 192 TYR B 192 TURN 286 286 PRO B 193 PRO B 193 TURN 287 287 PRO B 194 PRO B 194 TURN 288 288 PHE B 195 PHE B 195 TURN 289 289 GLN B 209 GLN B 209 TURN 290 290 GLN B 210 GLN B 210 TURN 291 291 LYS B 211 LYS B 211 TURN 292 292 ASP B 212 ASP B 212 TURN 293 293 ALA B 213 ALA B 213 TURN 294 294 LEU B 220 LEU B 220 TURN 295 295 SER B 221 SER B 221 TURN 296 296 VAL B 222 VAL B 222 TURN 297 297 ASP B 223 ASP B 223 TURN 298 298 PHE B 244 PHE B 244 TURN 299 299 ASP B 245 ASP B 245 TURN 300 300 MET B 257 MET B 257 TURN 301 301 PRO B 258 PRO B 258 TURN 302 302 LYS B 259 LYS B 259 TURN 303 303 PRO B 260 PRO B 260 TURN 304 304 LYS B 261 LYS B 261 TURN 305 305 PRO B 262 PRO B 262 TURN 306 306 PRO B 263 PRO B 263 TURN 307 307 PRO B 264 PRO B 264 SHEET 1 1 1 PHE A 20 PHE A 20 0 SHEET 1 2 1 GLU A 21 GLU A 21 0 SHEET 1 3 1 LYS A 26 LYS A 26 0 SHEET 1 4 1 VAL A 27 VAL A 27 0 SHEET 1 5 1 GLY A 28 GLY A 28 0 SHEET 1 6 1 ARG A 29 ARG A 29 0 SHEET 1 7 1 GLY A 33 GLY A 33 0 SHEET 1 8 1 HIS A 34 HIS A 34 0 SHEET 1 9 1 VAL A 35 VAL A 35 0 SHEET 1 10 1 TYR A 36 TYR A 36 0 SHEET 1 11 1 LYS A 37 LYS A 37 0 SHEET 1 12 1 ALA A 38 ALA A 38 0 SHEET 1 13 1 LYS A 39 LYS A 39 0 SHEET 1 14 1 ARG A 40 ARG A 40 0 SHEET 1 15 1 ASP A 48 ASP A 48 0 SHEET 1 16 1 TYR A 49 TYR A 49 0 SHEET 1 17 1 ALA A 50 ALA A 50 0 SHEET 1 18 1 LEU A 51 LEU A 51 0 SHEET 1 19 1 LYS A 52 LYS A 52 0 SHEET 1 20 1 GLN A 53 GLN A 53 0 SHEET 1 21 1 ILE A 54 ILE A 54 0 SHEET 1 22 1 LEU A 81 LEU A 81 0 SHEET 1 23 1 GLN A 82 GLN A 82 0 SHEET 1 24 1 LYS A 83 LYS A 83 0 SHEET 1 25 1 VAL A 84 VAL A 84 0 SHEET 1 26 1 PHE A 85 PHE A 85 0 SHEET 1 27 1 LEU A 86 LEU A 86 0 SHEET 1 28 1 SER A 87 SER A 87 0 SHEET 1 29 1 LYS A 92 LYS A 92 0 SHEET 1 30 1 VAL A 93 VAL A 93 0 SHEET 1 31 1 TRP A 94 TRP A 94 0 SHEET 1 32 1 LEU A 95 LEU A 95 0 SHEET 1 33 1 LEU A 96 LEU A 96 0 SHEET 1 34 1 PHE A 97 PHE A 97 0 SHEET 1 35 1 ASP A 98 ASP A 98 0 SHEET 1 36 1 ILE A 157 ILE A 157 0 SHEET 1 37 1 LEU A 158 LEU A 158 0 SHEET 1 38 1 VAL A 159 VAL A 159 0 SHEET 1 39 1 VAL A 169 VAL A 169 0 SHEET 1 40 1 LYS A 170 LYS A 170 0 SHEET 1 41 1 ILE A 171 ILE A 171 0 CRYST1 71.232 71.439 171.000 90.00 90.00 90.00 P 21 21 21 4 HETATM 1 CH3 ACE A -3 -27.867 31.795 -24.072 1.00 0.00 C HETATM 2 C ACE A -3 -28.241 32.500 -25.369 1.00 0.00 C HETATM 3 O ACE A -3 -28.700 31.841 -26.297 1.00 0.00 O HETATM 4 H1 ACE A -3 -28.476 30.903 -23.930 1.00 0.00 H HETATM 5 H2 ACE A -3 -26.825 31.481 -24.113 1.00 0.00 H HETATM 6 H3 ACE A -3 -27.995 32.448 -23.208 1.00 0.00 H ATOM 7 N ASP A -2 -28.027 33.829 -25.409 1.00 99.89 N ATOM 8 CA ASP A -2 -28.144 34.736 -26.563 1.00 99.82 C ATOM 9 C ASP A -2 -29.605 34.995 -27.004 1.00 98.93 C ATOM 10 O ASP A -2 -30.429 34.080 -27.035 1.00 99.12 O ATOM 11 CB ASP A -2 -27.239 34.282 -27.748 1.00 99.99 C ATOM 12 CG ASP A -2 -27.014 35.262 -28.917 1.00102.11 C ATOM 13 OD1 ASP A -2 -27.119 36.491 -28.705 1.00104.87 O ATOM 14 OD2 ASP A -2 -26.612 34.772 -29.996 1.00102.65 O1- ATOM 15 H ASP A -2 -27.658 34.267 -24.578 1.00 99.89 H ATOM 16 HA ASP A -2 -27.752 35.683 -26.189 1.00 99.82 H ATOM 17 HB3 ASP A -2 -27.640 33.353 -28.146 1.00 99.99 H ATOM 18 HB2 ASP A -2 -26.257 34.013 -27.357 1.00 99.99 H ATOM 19 N ASP A -1 -29.878 36.256 -27.377 1.00 97.25 N ATOM 20 CA ASP A -1 -31.137 36.723 -27.972 1.00 95.10 C ATOM 21 C ASP A -1 -31.308 36.258 -29.431 1.00 93.24 C ATOM 22 O ASP A -1 -32.442 36.038 -29.856 1.00 93.78 O ATOM 23 CB ASP A -1 -31.281 38.269 -27.923 0.00 94.86 C ATOM 24 CG ASP A -1 -31.102 38.935 -26.546 0.00 94.83 C ATOM 25 OD1 ASP A -1 -31.397 38.281 -25.520 0.00 94.84 O ATOM 26 OD2 ASP A -1 -30.818 40.153 -26.552 0.00 94.81 O1- ATOM 27 H ASP A -1 -29.139 36.944 -27.333 1.00 97.25 H ATOM 28 HA ASP A -1 -31.959 36.287 -27.400 1.00 95.10 H ATOM 29 HB3 ASP A -1 -32.268 38.554 -28.290 1.00 94.86 H ATOM 30 HB2 ASP A -1 -30.550 38.715 -28.601 1.00 94.86 H ATOM 31 N LYS A 0 -30.187 36.129 -30.165 1.00 90.20 N ATOM 32 CA LYS A 0 -30.148 35.757 -31.582 1.00 87.63 C ATOM 33 C LYS A 0 -30.109 34.225 -31.794 1.00 84.61 C ATOM 34 O LYS A 0 -30.193 33.781 -32.937 1.00 85.29 O ATOM 35 CB LYS A 0 -28.955 36.483 -32.256 1.00 87.75 C ATOM 36 CG LYS A 0 -29.274 37.150 -33.612 1.00 87.49 C ATOM 37 CD LYS A 0 -29.652 36.172 -34.734 1.00 85.50 C ATOM 38 CE LYS A 0 -29.725 36.824 -36.122 1.00 83.19 C ATOM 39 NZ LYS A 0 -30.039 35.830 -37.165 1.00 76.42 N1+ ATOM 40 H LYS A 0 -29.292 36.323 -29.734 1.00 90.20 H ATOM 41 HA LYS A 0 -31.069 36.107 -32.051 1.00 87.63 H ATOM 42 HB3 LYS A 0 -28.094 35.820 -32.346 1.00 87.75 H ATOM 43 HB2 LYS A 0 -28.612 37.288 -31.603 1.00 87.75 H ATOM 44 HG3 LYS A 0 -28.408 37.735 -33.921 1.00 87.49 H ATOM 45 HG2 LYS A 0 -30.080 37.873 -33.476 1.00 87.49 H ATOM 46 HD3 LYS A 0 -30.629 35.754 -34.505 1.00 85.50 H ATOM 47 HD2 LYS A 0 -28.946 35.341 -34.743 1.00 85.50 H ATOM 48 HE3 LYS A 0 -28.775 37.298 -36.368 1.00 83.19 H ATOM 49 HE2 LYS A 0 -30.488 37.602 -36.133 1.00 83.19 H ATOM 50 HZ1 LYS A 0 -29.300 35.139 -37.196 1.00 76.42 H ATOM 51 HZ2 LYS A 0 -30.915 35.374 -36.954 1.00 76.42 H ATOM 52 HZ3 LYS A 0 -30.097 36.286 -38.063 1.00 76.42 H ATOM 53 N MET A 1 -30.018 33.429 -30.715 1.00 79.72 N ATOM 54 CA MET A 1 -30.297 31.991 -30.752 1.00 76.49 C ATOM 55 C MET A 1 -31.801 31.754 -30.546 1.00 72.23 C ATOM 56 O MET A 1 -32.468 32.544 -29.874 1.00 73.31 O ATOM 57 CB MET A 1 -29.479 31.257 -29.673 1.00 76.38 C ATOM 58 CG MET A 1 -27.972 31.232 -29.965 1.00 77.28 C ATOM 59 SD MET A 1 -26.999 30.325 -28.731 1.00 79.10 S ATOM 60 CE MET A 1 -25.332 30.902 -29.141 1.00 72.83 C ATOM 61 H MET A 1 -29.944 33.844 -29.797 1.00 79.72 H ATOM 62 HA MET A 1 -30.018 31.578 -31.725 1.00 76.49 H ATOM 63 HB3 MET A 1 -29.826 30.225 -29.586 1.00 76.38 H ATOM 64 HB2 MET A 1 -29.660 31.717 -28.702 1.00 76.38 H ATOM 65 HG3 MET A 1 -27.589 32.246 -30.038 1.00 77.28 H ATOM 66 HG2 MET A 1 -27.795 30.789 -30.943 1.00 77.28 H ATOM 67 HE1 MET A 1 -24.604 30.462 -28.459 1.00 72.83 H ATOM 68 HE2 MET A 1 -25.067 30.618 -30.158 1.00 72.83 H ATOM 69 HE3 MET A 1 -25.272 31.987 -29.054 1.00 72.83 H ATOM 70 N ASP A 2 -32.296 30.650 -31.125 1.00 67.65 N ATOM 71 CA ASP A 2 -33.675 30.179 -31.001 1.00 64.97 C ATOM 72 C ASP A 2 -33.990 29.789 -29.543 1.00 62.71 C ATOM 73 O ASP A 2 -33.237 29.015 -28.949 1.00 60.30 O ATOM 74 CB ASP A 2 -33.905 29.000 -31.971 1.00 65.65 C ATOM 75 CG ASP A 2 -35.297 28.358 -31.952 1.00 64.38 C ATOM 76 OD1 ASP A 2 -36.288 29.105 -32.095 1.00 62.65 O ATOM 77 OD2 ASP A 2 -35.349 27.112 -31.878 1.00 62.24 O1- ATOM 78 H ASP A 2 -31.672 30.050 -31.648 1.00 67.65 H ATOM 79 HA ASP A 2 -34.330 31.002 -31.294 1.00 64.97 H ATOM 80 HB3 ASP A 2 -33.145 28.246 -31.780 1.00 65.65 H ATOM 81 HB2 ASP A 2 -33.719 29.338 -32.989 1.00 65.65 H ATOM 82 N TYR A 3 -35.095 30.332 -29.006 1.00 60.24 N ATOM 83 CA TYR A 3 -35.533 30.112 -27.628 1.00 58.15 C ATOM 84 C TYR A 3 -35.921 28.652 -27.322 1.00 55.62 C ATOM 85 O TYR A 3 -35.580 28.172 -26.242 1.00 56.13 O ATOM 86 CB TYR A 3 -36.661 31.104 -27.271 1.00 58.58 C ATOM 87 CG TYR A 3 -37.216 30.943 -25.865 1.00 62.63 C ATOM 88 CD1 TYR A 3 -36.448 31.351 -24.755 1.00 63.37 C ATOM 89 CD2 TYR A 3 -38.477 30.342 -25.662 1.00 63.35 C ATOM 90 CE1 TYR A 3 -36.936 31.159 -23.448 1.00 66.20 C ATOM 91 CE2 TYR A 3 -38.962 30.146 -24.355 1.00 67.24 C ATOM 92 CZ TYR A 3 -38.195 30.557 -23.248 1.00 66.55 C ATOM 93 OH TYR A 3 -38.674 30.376 -21.983 1.00 66.99 O ATOM 94 H TYR A 3 -35.654 30.972 -29.556 1.00 60.24 H ATOM 95 HA TYR A 3 -34.681 30.355 -26.991 1.00 58.15 H ATOM 96 HB3 TYR A 3 -37.480 31.005 -27.985 1.00 58.58 H ATOM 97 HB2 TYR A 3 -36.296 32.127 -27.376 1.00 58.58 H ATOM 98 HD1 TYR A 3 -35.478 31.803 -24.904 1.00 63.37 H ATOM 99 HD2 TYR A 3 -39.066 30.014 -26.506 1.00 63.35 H ATOM 100 HE1 TYR A 3 -36.341 31.473 -22.603 1.00 66.20 H ATOM 101 HE2 TYR A 3 -39.925 29.681 -24.204 1.00 67.24 H ATOM 102 HH TYR A 3 -38.073 30.686 -21.302 1.00 66.99 H ATOM 103 N ASP A 4 -36.595 27.976 -28.270 1.00 54.29 N ATOM 104 CA ASP A 4 -37.021 26.573 -28.152 1.00 53.80 C ATOM 105 C ASP A 4 -35.828 25.607 -28.044 1.00 53.46 C ATOM 106 O ASP A 4 -35.845 24.727 -27.185 1.00 55.20 O ATOM 107 CB ASP A 4 -37.966 26.111 -29.289 1.00 54.35 C ATOM 108 CG ASP A 4 -39.219 26.970 -29.535 1.00 54.65 C ATOM 109 OD1 ASP A 4 -39.695 27.636 -28.588 1.00 56.05 O ATOM 110 OD2 ASP A 4 -39.773 26.839 -30.649 1.00 57.31 O1- ATOM 111 H ASP A 4 -36.838 28.441 -29.134 1.00 54.29 H ATOM 112 HA ASP A 4 -37.577 26.492 -27.216 1.00 53.80 H ATOM 113 HB3 ASP A 4 -38.312 25.098 -29.080 1.00 54.35 H ATOM 114 HB2 ASP A 4 -37.408 26.067 -30.225 1.00 54.35 H ATOM 115 N PHE A 5 -34.806 25.830 -28.887 1.00 52.64 N ATOM 116 CA PHE A 5 -33.505 25.159 -28.869 1.00 51.91 C ATOM 117 C PHE A 5 -32.741 25.322 -27.543 1.00 52.55 C ATOM 118 O PHE A 5 -32.234 24.335 -27.011 1.00 52.94 O ATOM 119 CB PHE A 5 -32.703 25.638 -30.100 1.00 52.34 C ATOM 120 CG PHE A 5 -31.204 25.393 -30.127 1.00 51.68 C ATOM 121 CD1 PHE A 5 -30.698 24.124 -30.475 1.00 51.84 C ATOM 122 CD2 PHE A 5 -30.307 26.401 -29.711 1.00 54.36 C ATOM 123 CE1 PHE A 5 -29.326 23.912 -30.509 1.00 53.61 C ATOM 124 CE2 PHE A 5 -28.940 26.160 -29.725 1.00 54.99 C ATOM 125 CZ PHE A 5 -28.451 24.927 -30.139 1.00 53.22 C ATOM 126 H PHE A 5 -34.906 26.562 -29.577 1.00 52.64 H ATOM 127 HA PHE A 5 -33.688 24.090 -28.990 1.00 51.91 H ATOM 128 HB3 PHE A 5 -32.850 26.709 -30.222 1.00 52.34 H ATOM 129 HB2 PHE A 5 -33.129 25.182 -30.995 1.00 52.34 H ATOM 130 HD1 PHE A 5 -31.377 23.332 -30.749 1.00 51.84 H ATOM 131 HD2 PHE A 5 -30.677 27.366 -29.397 1.00 54.36 H ATOM 132 HE1 PHE A 5 -28.936 22.951 -30.810 1.00 53.61 H ATOM 133 HE2 PHE A 5 -28.254 26.937 -29.420 1.00 54.99 H ATOM 134 HZ PHE A 5 -27.386 24.749 -30.154 1.00 53.22 H ATOM 135 N LYS A 6 -32.702 26.567 -27.039 1.00 53.54 N ATOM 136 CA LYS A 6 -32.055 26.965 -25.791 1.00 54.38 C ATOM 137 C LYS A 6 -32.636 26.253 -24.556 1.00 53.27 C ATOM 138 O LYS A 6 -31.869 25.637 -23.816 1.00 52.13 O ATOM 139 CB LYS A 6 -32.092 28.507 -25.690 1.00 55.42 C ATOM 140 CG LYS A 6 -31.620 29.116 -24.357 1.00 58.50 C ATOM 141 CD LYS A 6 -31.690 30.649 -24.380 1.00 59.76 C ATOM 142 CE LYS A 6 -31.361 31.279 -23.017 0.00 59.59 C ATOM 143 NZ LYS A 6 -31.340 32.751 -23.094 0.00 59.67 N1+ ATOM 144 H LYS A 6 -33.146 27.315 -27.556 1.00 53.54 H ATOM 145 HA LYS A 6 -31.006 26.669 -25.873 1.00 54.38 H ATOM 146 HB3 LYS A 6 -33.111 28.848 -25.864 1.00 55.42 H ATOM 147 HB2 LYS A 6 -31.500 28.926 -26.506 1.00 55.42 H ATOM 148 HG3 LYS A 6 -30.601 28.794 -24.145 1.00 58.50 H ATOM 149 HG2 LYS A 6 -32.239 28.754 -23.535 1.00 58.50 H ATOM 150 HD3 LYS A 6 -32.688 30.959 -24.693 1.00 59.76 H ATOM 151 HD2 LYS A 6 -31.005 31.022 -25.142 1.00 59.76 H ATOM 152 HE3 LYS A 6 -30.392 30.933 -22.658 1.00 59.59 H ATOM 153 HE2 LYS A 6 -32.099 30.976 -22.274 1.00 59.59 H ATOM 154 HZ1 LYS A 6 -30.647 33.044 -23.768 1.00 59.67 H ATOM 155 HZ2 LYS A 6 -32.246 33.088 -23.384 1.00 59.67 H ATOM 156 HZ3 LYS A 6 -31.112 33.136 -22.188 1.00 59.67 H ATOM 157 N VAL A 7 -33.964 26.338 -24.359 1.00 52.10 N ATOM 158 CA VAL A 7 -34.642 25.750 -23.198 1.00 52.12 C ATOM 159 C VAL A 7 -34.741 24.213 -23.245 1.00 50.95 C ATOM 160 O VAL A 7 -34.753 23.600 -22.178 1.00 50.48 O ATOM 161 CB VAL A 7 -36.062 26.330 -22.962 1.00 52.99 C ATOM 162 CG1 VAL A 7 -36.008 27.839 -22.687 1.00 52.15 C ATOM 163 CG2 VAL A 7 -37.106 25.987 -24.044 1.00 48.96 C ATOM 164 H VAL A 7 -34.543 26.854 -25.011 1.00 52.10 H ATOM 165 HA VAL A 7 -34.046 26.000 -22.319 1.00 52.12 H ATOM 166 HB VAL A 7 -36.435 25.887 -22.037 1.00 52.99 H ATOM 167 HG11 VAL A 7 -36.988 28.205 -22.386 1.00 52.15 H ATOM 168 HG12 VAL A 7 -35.314 28.070 -21.879 1.00 52.15 H ATOM 169 HG13 VAL A 7 -35.695 28.401 -23.566 1.00 52.15 H ATOM 170 HG21 VAL A 7 -38.047 26.505 -23.860 1.00 48.96 H ATOM 171 HG22 VAL A 7 -36.762 26.275 -25.034 1.00 48.96 H ATOM 172 HG23 VAL A 7 -37.330 24.921 -24.073 1.00 48.96 H ATOM 173 N LYS A 8 -34.764 23.620 -24.453 1.00 50.75 N ATOM 174 CA LYS A 8 -34.715 22.170 -24.657 1.00 52.34 C ATOM 175 C LYS A 8 -33.376 21.578 -24.193 1.00 52.73 C ATOM 176 O LYS A 8 -33.388 20.624 -23.417 1.00 52.43 O ATOM 177 CB LYS A 8 -35.043 21.831 -26.130 1.00 54.10 C ATOM 178 CG LYS A 8 -34.922 20.346 -26.535 1.00 59.46 C ATOM 179 CD LYS A 8 -35.822 19.392 -25.729 1.00 64.15 C ATOM 180 CE LYS A 8 -35.756 17.950 -26.258 1.00 66.64 C ATOM 181 NZ LYS A 8 -36.623 17.039 -25.489 1.00 63.69 N1+ ATOM 182 H LYS A 8 -34.773 24.188 -25.290 1.00 50.75 H ATOM 183 HA LYS A 8 -35.502 21.738 -24.035 1.00 52.34 H ATOM 184 HB3 LYS A 8 -34.384 22.407 -26.781 1.00 54.10 H ATOM 185 HB2 LYS A 8 -36.055 22.172 -26.352 1.00 54.10 H ATOM 186 HG3 LYS A 8 -33.884 20.020 -26.462 1.00 59.46 H ATOM 187 HG2 LYS A 8 -35.178 20.263 -27.592 1.00 59.46 H ATOM 188 HD3 LYS A 8 -36.850 19.757 -25.759 1.00 64.15 H ATOM 189 HD2 LYS A 8 -35.523 19.405 -24.680 1.00 64.15 H ATOM 190 HE3 LYS A 8 -34.733 17.576 -26.215 1.00 66.64 H ATOM 191 HE2 LYS A 8 -36.066 17.921 -27.303 1.00 66.64 H ATOM 192 HZ1 LYS A 8 -36.305 16.994 -24.527 1.00 63.69 H ATOM 193 HZ2 LYS A 8 -37.577 17.368 -25.513 1.00 63.69 H ATOM 194 HZ3 LYS A 8 -36.576 16.112 -25.887 1.00 63.69 H ATOM 195 N LEU A 9 -32.257 22.179 -24.632 1.00 51.57 N ATOM 196 CA LEU A 9 -30.912 21.778 -24.218 1.00 51.43 C ATOM 197 C LEU A 9 -30.633 22.053 -22.733 1.00 52.14 C ATOM 198 O LEU A 9 -29.954 21.240 -22.117 1.00 53.27 O ATOM 199 CB LEU A 9 -29.847 22.459 -25.099 1.00 49.75 C ATOM 200 CG LEU A 9 -29.815 21.972 -26.562 1.00 50.30 C ATOM 201 CD1 LEU A 9 -28.841 22.841 -27.367 1.00 48.12 C ATOM 202 CD2 LEU A 9 -29.457 20.477 -26.686 1.00 47.78 C ATOM 203 H LEU A 9 -32.319 22.960 -25.272 1.00 51.57 H ATOM 204 HA LEU A 9 -30.839 20.697 -24.351 1.00 51.43 H ATOM 205 HB3 LEU A 9 -28.858 22.298 -24.666 1.00 49.75 H ATOM 206 HB2 LEU A 9 -30.007 23.539 -25.079 1.00 49.75 H ATOM 207 HG LEU A 9 -30.803 22.107 -27.003 1.00 50.30 H ATOM 208 HD11 LEU A 9 -28.530 22.362 -28.295 1.00 48.12 H ATOM 209 HD12 LEU A 9 -29.302 23.795 -27.622 1.00 48.12 H ATOM 210 HD13 LEU A 9 -27.942 23.051 -26.790 1.00 48.12 H ATOM 211 HD21 LEU A 9 -28.685 20.291 -27.433 1.00 47.78 H ATOM 212 HD22 LEU A 9 -29.081 20.069 -25.749 1.00 47.78 H ATOM 213 HD23 LEU A 9 -30.331 19.891 -26.971 1.00 47.78 H ATOM 214 N SER A 10 -31.179 23.148 -22.173 1.00 51.36 N ATOM 215 CA SER A 10 -31.047 23.494 -20.754 1.00 53.69 C ATOM 216 C SER A 10 -31.792 22.518 -19.820 1.00 53.97 C ATOM 217 O SER A 10 -31.301 22.253 -18.723 1.00 53.82 O ATOM 218 CB SER A 10 -31.503 24.953 -20.541 1.00 53.61 C ATOM 219 OG SER A 10 -31.273 25.394 -19.218 1.00 55.89 O ATOM 220 H SER A 10 -31.723 23.781 -22.743 1.00 51.36 H ATOM 221 HA SER A 10 -29.987 23.434 -20.503 1.00 53.69 H ATOM 222 HB3 SER A 10 -32.564 25.059 -20.766 1.00 53.61 H ATOM 223 HB2 SER A 10 -30.967 25.623 -21.213 1.00 53.61 H ATOM 224 HG SER A 10 -31.850 24.904 -18.627 1.00 55.89 H ATOM 225 N SER A 11 -32.942 21.996 -20.280 1.00 56.06 N ATOM 226 CA SER A 11 -33.747 20.997 -19.577 1.00 57.18 C ATOM 227 C SER A 11 -33.105 19.596 -19.608 1.00 57.73 C ATOM 228 O SER A 11 -33.184 18.883 -18.609 1.00 57.72 O ATOM 229 CB SER A 11 -35.169 20.993 -20.181 1.00 58.61 C ATOM 230 OG SER A 11 -36.036 20.097 -19.513 1.00 58.27 O ATOM 231 H SER A 11 -33.289 22.281 -21.187 1.00 56.06 H ATOM 232 HA SER A 11 -33.827 21.303 -18.532 1.00 57.18 H ATOM 233 HB3 SER A 11 -35.140 20.727 -21.239 1.00 58.61 H ATOM 234 HB2 SER A 11 -35.606 21.990 -20.118 1.00 58.61 H ATOM 235 HG SER A 11 -35.737 19.199 -19.675 1.00 58.27 H ATOM 236 N GLU A 12 -32.490 19.234 -20.747 1.00 57.88 N ATOM 237 CA GLU A 12 -31.898 17.917 -20.991 1.00 58.93 C ATOM 238 C GLU A 12 -30.444 17.779 -20.509 1.00 59.09 C ATOM 239 O GLU A 12 -30.025 16.650 -20.254 1.00 59.58 O ATOM 240 CB GLU A 12 -32.001 17.589 -22.498 1.00 59.09 C ATOM 241 CG GLU A 12 -33.448 17.397 -23.013 1.00 64.18 C ATOM 242 CD GLU A 12 -34.177 16.127 -22.540 1.00 67.27 C ATOM 243 OE1 GLU A 12 -33.512 15.177 -22.070 1.00 67.20 O ATOM 244 OE2 GLU A 12 -35.421 16.124 -22.679 1.00 71.01 O1- ATOM 245 H GLU A 12 -32.481 19.873 -21.530 1.00 57.88 H ATOM 246 HA GLU A 12 -32.472 17.172 -20.438 1.00 58.93 H ATOM 247 HB3 GLU A 12 -31.398 16.713 -22.744 1.00 59.09 H ATOM 248 HB2 GLU A 12 -31.549 18.405 -23.064 1.00 59.09 H ATOM 249 HG3 GLU A 12 -33.426 17.374 -24.102 1.00 64.18 H ATOM 250 HG2 GLU A 12 -34.056 18.260 -22.743 1.00 64.18 H ATOM 251 N ARG A 13 -29.701 18.897 -20.395 1.00 59.87 N ATOM 252 CA ARG A 13 -28.285 18.904 -20.023 1.00 60.88 C ATOM 253 C ARG A 13 -28.074 18.451 -18.574 1.00 60.76 C ATOM 254 O ARG A 13 -28.563 19.096 -17.645 1.00 60.82 O ATOM 255 CB ARG A 13 -27.645 20.280 -20.312 1.00 60.86 C ATOM 256 CG ARG A 13 -26.174 20.426 -19.859 1.00 59.97 C ATOM 257 CD ARG A 13 -25.435 21.651 -20.431 1.00 61.09 C ATOM 258 NE ARG A 13 -26.130 22.924 -20.169 1.00 62.81 N ATOM 259 CZ ARG A 13 -26.837 23.665 -21.044 1.00 60.04 C ATOM 260 NH1 ARG A 13 -26.990 23.323 -22.332 1.00 56.89 N ATOM 261 NH2 ARG A 13 -27.415 24.793 -20.615 1.00 60.13 N1+ ATOM 262 H ARG A 13 -30.109 19.794 -20.619 1.00 59.87 H ATOM 263 HA ARG A 13 -27.784 18.188 -20.677 1.00 60.88 H ATOM 264 HB3 ARG A 13 -28.242 21.058 -19.834 1.00 60.86 H ATOM 265 HB2 ARG A 13 -27.688 20.469 -21.384 1.00 60.86 H ATOM 266 HG3 ARG A 13 -25.666 19.552 -20.269 1.00 59.97 H ATOM 267 HG2 ARG A 13 -26.040 20.359 -18.778 1.00 59.97 H ATOM 268 HD3 ARG A 13 -25.107 21.509 -21.460 1.00 61.09 H ATOM 269 HD2 ARG A 13 -24.516 21.757 -19.856 1.00 61.09 H ATOM 270 HE ARG A 13 -26.086 23.243 -19.212 1.00 62.81 H ATOM 271 HH12 ARG A 13 -27.520 23.915 -22.956 1.00 56.89 H ATOM 272 HH11 ARG A 13 -26.527 22.503 -22.708 1.00 56.89 H ATOM 273 HH22 ARG A 13 -27.953 25.355 -21.263 1.00 60.13 H ATOM 274 HH21 ARG A 13 -27.330 25.088 -19.654 1.00 60.13 H ATOM 275 N GLU A 14 -27.309 17.360 -18.439 1.00 61.29 N ATOM 276 CA GLU A 14 -26.853 16.798 -17.177 1.00 62.84 C ATOM 277 C GLU A 14 -25.811 17.720 -16.533 1.00 62.60 C ATOM 278 O GLU A 14 -24.840 18.096 -17.191 1.00 62.58 O ATOM 279 CB GLU A 14 -26.255 15.407 -17.442 1.00 63.52 C ATOM 280 CG GLU A 14 -27.282 14.377 -17.958 1.00 67.40 C ATOM 281 CD GLU A 14 -26.601 13.143 -18.554 1.00 72.60 C ATOM 282 OE1 GLU A 14 -26.283 13.199 -19.763 1.00 76.30 O ATOM 283 OE2 GLU A 14 -26.393 12.168 -17.799 1.00 71.94 O1- ATOM 284 H GLU A 14 -26.953 16.905 -19.270 1.00 61.29 H ATOM 285 HA GLU A 14 -27.711 16.693 -16.509 1.00 62.84 H ATOM 286 HB3 GLU A 14 -25.816 15.038 -16.518 1.00 63.52 H ATOM 287 HB2 GLU A 14 -25.427 15.496 -18.149 1.00 63.52 H ATOM 288 HG3 GLU A 14 -27.925 14.817 -18.722 1.00 67.40 H ATOM 289 HG2 GLU A 14 -27.947 14.081 -17.146 1.00 67.40 H ATOM 290 N ARG A 15 -26.044 18.054 -15.258 1.00 63.56 N ATOM 291 CA ARG A 15 -25.146 18.871 -14.450 1.00 63.82 C ATOM 292 C ARG A 15 -24.335 17.957 -13.524 1.00 63.39 C ATOM 293 O ARG A 15 -24.859 16.946 -13.049 1.00 61.87 O ATOM 294 CB ARG A 15 -25.957 19.899 -13.641 1.00 64.93 C ATOM 295 CG ARG A 15 -26.977 20.707 -14.463 1.00 69.61 C ATOM 296 CD ARG A 15 -27.690 21.771 -13.615 1.00 73.57 C ATOM 297 NE ARG A 15 -28.835 22.366 -14.328 1.00 78.55 N ATOM 298 CZ ARG A 15 -29.770 23.185 -13.810 1.00 80.27 C ATOM 299 NH1 ARG A 15 -29.750 23.568 -12.524 1.00 79.10 N ATOM 300 NH2 ARG A 15 -30.753 23.627 -14.606 1.00 78.39 N1+ ATOM 301 H ARG A 15 -26.864 17.700 -14.787 1.00 63.56 H ATOM 302 HA ARG A 15 -24.459 19.422 -15.096 1.00 63.82 H ATOM 303 HB3 ARG A 15 -25.262 20.586 -13.163 1.00 64.93 H ATOM 304 HB2 ARG A 15 -26.483 19.392 -12.834 1.00 64.93 H ATOM 305 HG3 ARG A 15 -27.697 20.076 -14.987 1.00 69.61 H ATOM 306 HG2 ARG A 15 -26.400 21.218 -15.235 1.00 69.61 H ATOM 307 HD3 ARG A 15 -27.001 22.606 -13.480 1.00 73.57 H ATOM 308 HD2 ARG A 15 -27.936 21.406 -12.618 1.00 73.57 H ATOM 309 HE ARG A 15 -28.924 22.094 -15.296 1.00 78.55 H ATOM 310 HH12 ARG A 15 -30.463 24.175 -12.148 1.00 79.10 H ATOM 311 HH11 ARG A 15 -29.018 23.224 -11.916 1.00 79.10 H ATOM 312 HH22 ARG A 15 -31.472 24.235 -14.242 1.00 78.39 H ATOM 313 HH21 ARG A 15 -30.796 23.334 -15.572 1.00 78.39 H ATOM 314 N VAL A 16 -23.073 18.337 -13.277 1.00 62.64 N ATOM 315 CA VAL A 16 -22.134 17.577 -12.450 1.00 63.26 C ATOM 316 C VAL A 16 -22.564 17.466 -10.968 1.00 63.85 C ATOM 317 O VAL A 16 -22.371 16.406 -10.375 1.00 63.25 O ATOM 318 CB VAL A 16 -20.695 18.157 -12.563 1.00 63.21 C ATOM 319 CG1 VAL A 16 -20.545 19.592 -12.024 1.00 61.96 C ATOM 320 CG2 VAL A 16 -19.630 17.241 -11.935 1.00 62.01 C ATOM 321 H VAL A 16 -22.718 19.192 -13.681 1.00 62.64 H ATOM 322 HA VAL A 16 -22.114 16.563 -12.854 1.00 63.26 H ATOM 323 HB VAL A 16 -20.464 18.201 -13.629 1.00 63.21 H ATOM 324 HG11 VAL A 16 -19.543 19.969 -12.212 1.00 61.96 H ATOM 325 HG12 VAL A 16 -21.240 20.277 -12.509 1.00 61.96 H ATOM 326 HG13 VAL A 16 -20.711 19.649 -10.950 1.00 61.96 H ATOM 327 HG21 VAL A 16 -18.624 17.587 -12.174 1.00 62.01 H ATOM 328 HG22 VAL A 16 -19.712 17.203 -10.849 1.00 62.01 H ATOM 329 HG23 VAL A 16 -19.723 16.224 -12.314 1.00 62.01 H ATOM 330 N GLU A 17 -23.182 18.528 -10.420 1.00 65.16 N ATOM 331 CA GLU A 17 -23.707 18.577 -9.055 1.00 65.78 C ATOM 332 C GLU A 17 -25.001 17.763 -8.863 1.00 66.79 C ATOM 333 O GLU A 17 -25.263 17.346 -7.736 1.00 67.36 O ATOM 334 CB GLU A 17 -23.850 20.047 -8.582 1.00 66.16 C ATOM 335 CG GLU A 17 -24.963 20.923 -9.226 1.00 67.62 C ATOM 336 CD GLU A 17 -24.640 21.633 -10.554 1.00 67.41 C ATOM 337 OE1 GLU A 17 -23.537 21.431 -11.110 1.00 68.61 O ATOM 338 OE2 GLU A 17 -25.529 22.388 -11.005 1.00 68.07 O1- ATOM 339 H GLU A 17 -23.302 19.376 -10.962 1.00 65.16 H ATOM 340 HA GLU A 17 -22.962 18.114 -8.406 1.00 65.78 H ATOM 341 HB3 GLU A 17 -22.884 20.548 -8.664 1.00 66.16 H ATOM 342 HB2 GLU A 17 -24.041 20.024 -7.509 1.00 66.16 H ATOM 343 HG3 GLU A 17 -25.214 21.708 -8.511 1.00 67.62 H ATOM 344 HG2 GLU A 17 -25.881 20.350 -9.351 1.00 67.62 H ATOM 345 N ASP A 18 -25.772 17.532 -9.942 1.00 67.45 N ATOM 346 CA ASP A 18 -26.998 16.726 -9.919 1.00 66.73 C ATOM 347 C ASP A 18 -26.702 15.217 -9.940 1.00 66.29 C ATOM 348 O ASP A 18 -27.382 14.477 -9.229 1.00 66.96 O ATOM 349 CB ASP A 18 -28.003 17.082 -11.046 1.00 67.64 C ATOM 350 CG ASP A 18 -28.532 18.529 -11.081 1.00 69.26 C ATOM 351 OD1 ASP A 18 -28.402 19.255 -10.069 1.00 69.30 O ATOM 352 OD2 ASP A 18 -29.158 18.863 -12.111 1.00 71.50 O1- ATOM 353 H ASP A 18 -25.499 17.908 -10.839 1.00 67.45 H ATOM 354 HA ASP A 18 -27.504 16.920 -8.970 1.00 66.73 H ATOM 355 HB3 ASP A 18 -28.871 16.424 -10.980 1.00 67.64 H ATOM 356 HB2 ASP A 18 -27.534 16.885 -12.012 1.00 67.64 H ATOM 357 N LEU A 19 -25.707 14.786 -10.738 1.00 65.51 N ATOM 358 CA LEU A 19 -25.339 13.372 -10.861 1.00 64.24 C ATOM 359 C LEU A 19 -24.384 12.883 -9.762 1.00 62.53 C ATOM 360 O LEU A 19 -24.440 11.695 -9.448 1.00 64.30 O ATOM 361 CB LEU A 19 -24.694 13.085 -12.236 1.00 64.01 C ATOM 362 CG LEU A 19 -25.601 13.214 -13.477 1.00 66.18 C ATOM 363 CD1 LEU A 19 -24.856 12.665 -14.712 1.00 65.27 C ATOM 364 CD2 LEU A 19 -26.973 12.532 -13.314 1.00 66.78 C ATOM 365 H LEU A 19 -25.193 15.444 -11.307 1.00 65.51 H ATOM 366 HA LEU A 19 -26.241 12.766 -10.765 1.00 64.24 H ATOM 367 HB3 LEU A 19 -24.312 12.062 -12.221 1.00 64.01 H ATOM 368 HB2 LEU A 19 -23.821 13.726 -12.369 1.00 64.01 H ATOM 369 HG LEU A 19 -25.783 14.277 -13.646 1.00 66.18 H ATOM 370 HD11 LEU A 19 -24.877 13.370 -15.536 1.00 65.27 H ATOM 371 HD12 LEU A 19 -23.807 12.457 -14.503 1.00 65.27 H ATOM 372 HD13 LEU A 19 -25.291 11.734 -15.076 1.00 65.27 H ATOM 373 HD21 LEU A 19 -27.377 12.193 -14.269 1.00 66.78 H ATOM 374 HD22 LEU A 19 -26.921 11.661 -12.659 1.00 66.78 H ATOM 375 HD23 LEU A 19 -27.701 13.225 -12.890 1.00 66.78 H ATOM 376 N PHE A 20 -23.512 13.761 -9.236 1.00 61.62 N ATOM 377 CA PHE A 20 -22.426 13.372 -8.334 1.00 60.39 C ATOM 378 C PHE A 20 -22.406 14.192 -7.043 1.00 59.92 C ATOM 379 O PHE A 20 -22.637 15.402 -7.066 1.00 59.43 O ATOM 380 CB PHE A 20 -21.063 13.469 -9.053 1.00 60.22 C ATOM 381 CG PHE A 20 -20.831 12.396 -10.099 1.00 57.29 C ATOM 382 CD1 PHE A 20 -20.420 11.108 -9.699 1.00 56.65 C ATOM 383 CD2 PHE A 20 -21.192 12.615 -11.445 1.00 54.22 C ATOM 384 CE1 PHE A 20 -20.346 10.082 -10.629 1.00 57.16 C ATOM 385 CE2 PHE A 20 -21.108 11.575 -12.361 1.00 56.74 C ATOM 386 CZ PHE A 20 -20.691 10.314 -11.954 1.00 58.67 C ATOM 387 H PHE A 20 -23.520 14.727 -9.533 1.00 61.62 H ATOM 388 HA PHE A 20 -22.558 12.332 -8.031 1.00 60.39 H ATOM 389 HB3 PHE A 20 -20.261 13.388 -8.318 1.00 60.22 H ATOM 390 HB2 PHE A 20 -20.940 14.448 -9.515 1.00 60.22 H ATOM 391 HD1 PHE A 20 -20.171 10.913 -8.667 1.00 56.65 H ATOM 392 HD2 PHE A 20 -21.543 13.587 -11.761 1.00 54.22 H ATOM 393 HE1 PHE A 20 -20.036 9.097 -10.318 1.00 57.16 H ATOM 394 HE2 PHE A 20 -21.385 11.739 -13.391 1.00 56.74 H ATOM 395 HZ PHE A 20 -20.639 9.506 -12.668 1.00 58.67 H ATOM 396 N GLU A 21 -22.062 13.488 -5.956 1.00 60.93 N ATOM 397 CA GLU A 21 -21.753 14.016 -4.635 1.00 61.67 C ATOM 398 C GLU A 21 -20.227 14.048 -4.487 1.00 61.09 C ATOM 399 O GLU A 21 -19.594 13.005 -4.652 1.00 60.45 O ATOM 400 CB GLU A 21 -22.428 13.101 -3.583 1.00 62.72 C ATOM 401 CG GLU A 21 -22.093 13.397 -2.102 1.00 65.04 C ATOM 402 CD GLU A 21 -22.474 14.797 -1.591 1.00 68.18 C ATOM 403 OE1 GLU A 21 -23.393 15.424 -2.166 1.00 71.74 O ATOM 404 OE2 GLU A 21 -21.831 15.216 -0.605 1.00 71.03 O1- ATOM 405 H GLU A 21 -21.892 12.495 -6.062 1.00 60.93 H ATOM 406 HA GLU A 21 -22.138 15.032 -4.543 1.00 61.67 H ATOM 407 HB3 GLU A 21 -22.158 12.063 -3.787 1.00 62.72 H ATOM 408 HB2 GLU A 21 -23.510 13.136 -3.716 1.00 62.72 H ATOM 409 HG3 GLU A 21 -21.030 13.224 -1.924 1.00 65.04 H ATOM 410 HG2 GLU A 21 -22.614 12.672 -1.476 1.00 65.04 H ATOM 411 N TYR A 22 -19.671 15.236 -4.201 1.00 61.31 N ATOM 412 CA TYR A 22 -18.223 15.466 -4.187 1.00 61.20 C ATOM 413 C TYR A 22 -17.782 16.621 -3.267 1.00 62.22 C ATOM 414 O TYR A 22 -16.576 16.863 -3.196 1.00 62.55 O ATOM 415 CB TYR A 22 -17.712 15.655 -5.640 1.00 59.97 C ATOM 416 CG TYR A 22 -18.268 16.861 -6.384 1.00 57.24 C ATOM 417 CD1 TYR A 22 -19.362 16.704 -7.261 1.00 57.46 C ATOM 418 CD2 TYR A 22 -17.709 18.143 -6.193 1.00 56.82 C ATOM 419 CE1 TYR A 22 -19.902 17.820 -7.927 1.00 58.11 C ATOM 420 CE2 TYR A 22 -18.267 19.262 -6.839 1.00 58.71 C ATOM 421 CZ TYR A 22 -19.361 19.102 -7.711 1.00 59.93 C ATOM 422 OH TYR A 22 -19.892 20.189 -8.342 1.00 66.63 O ATOM 423 H TYR A 22 -20.259 16.048 -4.084 1.00 61.31 H ATOM 424 HA TYR A 22 -17.742 14.577 -3.776 1.00 61.20 H ATOM 425 HB3 TYR A 22 -17.929 14.759 -6.222 1.00 59.97 H ATOM 426 HB2 TYR A 22 -16.626 15.733 -5.641 1.00 59.97 H ATOM 427 HD1 TYR A 22 -19.794 15.728 -7.421 1.00 57.46 H ATOM 428 HD2 TYR A 22 -16.864 18.278 -5.534 1.00 56.82 H ATOM 429 HE1 TYR A 22 -20.736 17.686 -8.598 1.00 58.11 H ATOM 430 HE2 TYR A 22 -17.851 20.244 -6.668 1.00 58.71 H ATOM 431 HH TYR A 22 -20.638 19.976 -8.907 1.00 66.63 H ATOM 432 N GLU A 23 -18.715 17.330 -2.600 1.00 65.59 N ATOM 433 CA GLU A 23 -18.384 18.480 -1.750 1.00 67.84 C ATOM 434 C GLU A 23 -17.624 18.047 -0.481 1.00 67.48 C ATOM 435 O GLU A 23 -18.028 17.095 0.188 1.00 66.26 O ATOM 436 CB GLU A 23 -19.640 19.332 -1.456 1.00 69.78 C ATOM 437 CG GLU A 23 -20.752 18.664 -0.612 1.00 73.46 C ATOM 438 CD GLU A 23 -21.922 19.592 -0.233 1.00 79.06 C ATOM 439 OE1 GLU A 23 -22.118 20.628 -0.908 1.00 85.31 O ATOM 440 OE2 GLU A 23 -22.615 19.245 0.749 1.00 81.81 O1- ATOM 441 H GLU A 23 -19.691 17.079 -2.653 1.00 65.59 H ATOM 442 HA GLU A 23 -17.717 19.118 -2.335 1.00 67.84 H ATOM 443 HB3 GLU A 23 -20.058 19.660 -2.409 1.00 69.78 H ATOM 444 HB2 GLU A 23 -19.318 20.245 -0.953 1.00 69.78 H ATOM 445 HG3 GLU A 23 -20.336 18.258 0.310 1.00 73.46 H ATOM 446 HG2 GLU A 23 -21.164 17.820 -1.164 1.00 73.46 H ATOM 447 N GLY A 24 -16.498 18.731 -0.217 1.00 68.51 N ATOM 448 CA GLY A 24 -15.558 18.417 0.863 1.00 68.88 C ATOM 449 C GLY A 24 -14.715 17.152 0.598 1.00 69.41 C ATOM 450 O GLY A 24 -13.874 16.817 1.432 1.00 69.89 O ATOM 451 H GLY A 24 -16.243 19.497 -0.824 1.00 68.51 H ATOM 452 HA3 GLY A 24 -16.100 18.296 1.803 1.00 68.88 H ATOM 453 HA2 GLY A 24 -14.885 19.264 0.994 1.00 68.88 H ATOM 454 N CYS A 25 -14.923 16.461 -0.539 1.00 69.41 N ATOM 455 CA CYS A 25 -14.283 15.192 -0.892 1.00 68.23 C ATOM 456 C CYS A 25 -13.113 15.403 -1.875 1.00 66.95 C ATOM 457 O CYS A 25 -12.804 14.500 -2.654 1.00 66.16 O ATOM 458 CB CYS A 25 -15.304 14.174 -1.446 1.00 68.53 C ATOM 459 SG CYS A 25 -16.594 13.811 -0.224 1.00 69.60 S ATOM 460 H CYS A 25 -15.619 16.794 -1.192 1.00 69.41 H ATOM 461 HA CYS A 25 -13.852 14.750 0.005 1.00 68.23 H ATOM 462 HB3 CYS A 25 -14.818 13.229 -1.690 1.00 68.53 H ATOM 463 HB2 CYS A 25 -15.769 14.540 -2.359 1.00 68.53 H ATOM 464 HG CYS A 25 -17.146 15.029 -0.226 1.00 69.60 H ATOM 465 N LYS A 26 -12.460 16.579 -1.813 1.00 66.52 N ATOM 466 CA LYS A 26 -11.255 16.911 -2.575 1.00 66.95 C ATOM 467 C LYS A 26 -10.088 16.009 -2.149 1.00 67.78 C ATOM 468 O LYS A 26 -9.892 15.822 -0.953 1.00 68.65 O ATOM 469 CB LYS A 26 -10.932 18.404 -2.370 1.00 66.52 C ATOM 470 CG LYS A 26 -9.781 18.932 -3.253 1.00 66.75 C ATOM 471 CD LYS A 26 -9.475 20.423 -3.036 1.00 68.22 C ATOM 472 CE LYS A 26 -10.596 21.364 -3.514 1.00 70.26 C ATOM 473 NZ LYS A 26 -10.292 22.773 -3.212 1.00 71.37 N1+ ATOM 474 H LYS A 26 -12.758 17.264 -1.133 1.00 66.52 H ATOM 475 HA LYS A 26 -11.465 16.757 -3.631 1.00 66.95 H ATOM 476 HB3 LYS A 26 -10.705 18.593 -1.320 1.00 66.52 H ATOM 477 HB2 LYS A 26 -11.834 18.973 -2.586 1.00 66.52 H ATOM 478 HG3 LYS A 26 -10.014 18.757 -4.305 1.00 66.75 H ATOM 479 HG2 LYS A 26 -8.870 18.368 -3.050 1.00 66.75 H ATOM 480 HD3 LYS A 26 -8.549 20.664 -3.558 1.00 68.22 H ATOM 481 HD2 LYS A 26 -9.274 20.587 -1.976 1.00 68.22 H ATOM 482 HE3 LYS A 26 -11.543 21.125 -3.031 1.00 70.26 H ATOM 483 HE2 LYS A 26 -10.746 21.254 -4.588 1.00 70.26 H ATOM 484 HZ1 LYS A 26 -9.430 23.041 -3.662 1.00 71.37 H ATOM 485 HZ2 LYS A 26 -11.047 23.356 -3.544 1.00 71.37 H ATOM 486 HZ3 LYS A 26 -10.199 22.888 -2.213 1.00 71.37 H ATOM 487 N VAL A 27 -9.348 15.472 -3.127 1.00 67.04 N ATOM 488 CA VAL A 27 -8.188 14.607 -2.898 1.00 66.90 C ATOM 489 C VAL A 27 -6.918 15.132 -3.598 1.00 68.56 C ATOM 490 O VAL A 27 -5.833 14.644 -3.280 1.00 69.13 O ATOM 491 CB VAL A 27 -8.457 13.148 -3.362 1.00 66.04 C ATOM 492 CG1 VAL A 27 -9.505 12.452 -2.475 1.00 64.16 C ATOM 493 CG2 VAL A 27 -8.817 13.015 -4.853 1.00 63.03 C ATOM 494 H VAL A 27 -9.581 15.662 -4.093 1.00 67.04 H ATOM 495 HA VAL A 27 -7.946 14.569 -1.836 1.00 66.90 H ATOM 496 HB VAL A 27 -7.534 12.587 -3.214 1.00 66.04 H ATOM 497 HG11 VAL A 27 -9.607 11.399 -2.741 1.00 64.16 H ATOM 498 HG12 VAL A 27 -9.222 12.495 -1.423 1.00 64.16 H ATOM 499 HG13 VAL A 27 -10.487 12.915 -2.574 1.00 64.16 H ATOM 500 HG21 VAL A 27 -8.945 11.970 -5.136 1.00 63.03 H ATOM 501 HG22 VAL A 27 -9.748 13.532 -5.084 1.00 63.03 H ATOM 502 HG23 VAL A 27 -8.040 13.431 -5.491 1.00 63.03 H ATOM 503 N GLY A 28 -7.057 16.109 -4.513 1.00 70.38 N ATOM 504 CA GLY A 28 -5.943 16.693 -5.249 1.00 71.32 C ATOM 505 C GLY A 28 -6.189 18.185 -5.479 1.00 72.67 C ATOM 506 O GLY A 28 -7.328 18.635 -5.610 1.00 72.73 O ATOM 507 H GLY A 28 -7.976 16.472 -4.723 1.00 70.38 H ATOM 508 HA3 GLY A 28 -5.863 16.204 -6.219 1.00 71.32 H ATOM 509 HA2 GLY A 28 -4.993 16.552 -4.729 1.00 71.32 H ATOM 510 N ARG A 29 -5.079 18.927 -5.594 1.00 75.67 N ATOM 511 CA ARG A 29 -5.027 20.343 -5.935 1.00 78.01 C ATOM 512 C ARG A 29 -3.645 20.630 -6.537 1.00 78.78 C ATOM 513 O ARG A 29 -2.637 20.325 -5.898 1.00 79.24 O ATOM 514 CB ARG A 29 -5.311 21.199 -4.677 1.00 78.92 C ATOM 515 CG ARG A 29 -5.276 22.723 -4.903 1.00 81.70 C ATOM 516 CD ARG A 29 -6.498 23.252 -5.671 1.00 85.36 C ATOM 517 NE ARG A 29 -6.350 24.667 -6.059 1.00 90.22 N ATOM 518 CZ ARG A 29 -6.223 25.167 -7.305 1.00 92.66 C ATOM 519 NH1 ARG A 29 -6.187 24.384 -8.391 1.00 92.72 N ATOM 520 NH2 ARG A 29 -6.132 26.491 -7.477 1.00 94.07 N1+ ATOM 521 H ARG A 29 -4.175 18.488 -5.481 1.00 75.67 H ATOM 522 HA ARG A 29 -5.786 20.541 -6.692 1.00 78.01 H ATOM 523 HB3 ARG A 29 -4.583 20.948 -3.904 1.00 78.92 H ATOM 524 HB2 ARG A 29 -6.282 20.928 -4.262 1.00 78.92 H ATOM 525 HG3 ARG A 29 -4.333 23.078 -5.323 1.00 81.70 H ATOM 526 HG2 ARG A 29 -5.320 23.151 -3.900 1.00 81.70 H ATOM 527 HD3 ARG A 29 -7.327 23.281 -4.964 1.00 85.36 H ATOM 528 HD2 ARG A 29 -6.828 22.587 -6.469 1.00 85.36 H ATOM 529 HE ARG A 29 -6.322 25.323 -5.292 1.00 90.22 H ATOM 530 HH12 ARG A 29 -6.138 24.795 -9.317 1.00 92.72 H ATOM 531 HH11 ARG A 29 -6.220 23.378 -8.304 1.00 92.72 H ATOM 532 HH22 ARG A 29 -6.041 26.873 -8.411 1.00 94.07 H ATOM 533 HH21 ARG A 29 -6.135 27.121 -6.688 1.00 94.07 H ATOM 534 N GLY A 30 -3.620 21.216 -7.741 1.00 80.07 N ATOM 535 CA GLY A 30 -2.377 21.554 -8.425 1.00 81.48 C ATOM 536 C GLY A 30 -2.687 22.413 -9.653 1.00 82.10 C ATOM 537 O GLY A 30 -3.798 22.917 -9.819 1.00 82.17 O ATOM 538 H GLY A 30 -4.481 21.424 -8.229 1.00 80.07 H ATOM 539 HA3 GLY A 30 -1.862 20.642 -8.728 1.00 81.48 H ATOM 540 HA2 GLY A 30 -1.714 22.111 -7.760 1.00 81.48 H ATOM 541 N THR A 31 -1.678 22.577 -10.521 1.00 83.19 N ATOM 542 CA THR A 31 -1.750 23.347 -11.771 1.00 84.23 C ATOM 543 C THR A 31 -2.658 22.704 -12.847 1.00 84.16 C ATOM 544 O THR A 31 -3.118 23.412 -13.743 1.00 84.86 O ATOM 545 CB THR A 31 -0.330 23.576 -12.355 1.00 84.75 C ATOM 546 OG1 THR A 31 0.237 22.408 -12.924 1.00 85.92 O ATOM 547 CG2 THR A 31 0.648 24.165 -11.323 1.00 85.67 C ATOM 548 H THR A 31 -0.785 22.141 -10.337 1.00 83.19 H ATOM 549 HA THR A 31 -2.178 24.323 -11.532 1.00 84.23 H ATOM 550 HB THR A 31 -0.413 24.299 -13.169 1.00 84.75 H ATOM 551 HG1 THR A 31 1.105 22.636 -13.275 1.00 85.92 H ATOM 552 HG21 THR A 31 1.609 24.405 -11.771 1.00 85.67 H ATOM 553 HG22 THR A 31 0.252 25.085 -10.894 1.00 85.67 H ATOM 554 HG23 THR A 31 0.844 23.472 -10.505 1.00 85.67 H ATOM 555 N TYR A 32 -2.953 21.401 -12.693 1.00 83.26 N ATOM 556 CA TYR A 32 -3.955 20.647 -13.446 1.00 82.19 C ATOM 557 C TYR A 32 -5.414 21.029 -13.102 1.00 81.02 C ATOM 558 O TYR A 32 -6.302 20.739 -13.903 1.00 81.39 O ATOM 559 CB TYR A 32 -3.689 19.140 -13.225 1.00 82.47 C ATOM 560 CG TYR A 32 -3.687 18.652 -11.780 1.00 82.34 C ATOM 561 CD1 TYR A 32 -4.896 18.453 -11.075 1.00 82.15 C ATOM 562 CD2 TYR A 32 -2.460 18.386 -11.136 1.00 82.32 C ATOM 563 CE1 TYR A 32 -4.874 18.014 -9.737 1.00 80.97 C ATOM 564 CE2 TYR A 32 -2.440 17.924 -9.806 1.00 82.15 C ATOM 565 CZ TYR A 32 -3.647 17.733 -9.109 1.00 82.28 C ATOM 566 OH TYR A 32 -3.626 17.264 -7.829 1.00 82.09 O ATOM 567 H TYR A 32 -2.513 20.897 -11.938 1.00 83.26 H ATOM 568 HA TYR A 32 -3.807 20.862 -14.506 1.00 82.19 H ATOM 569 HB3 TYR A 32 -2.723 18.890 -13.667 1.00 82.47 H ATOM 570 HB2 TYR A 32 -4.407 18.549 -13.785 1.00 82.47 H ATOM 571 HD1 TYR A 32 -5.845 18.647 -11.552 1.00 82.15 H ATOM 572 HD2 TYR A 32 -1.528 18.523 -11.665 1.00 82.32 H ATOM 573 HE1 TYR A 32 -5.798 17.885 -9.195 1.00 80.97 H ATOM 574 HE2 TYR A 32 -1.496 17.710 -9.327 1.00 82.15 H ATOM 575 HH TYR A 32 -4.506 17.139 -7.471 1.00 82.09 H ATOM 576 N GLY A 33 -5.632 21.655 -11.931 1.00 78.94 N ATOM 577 CA GLY A 33 -6.948 22.018 -11.415 1.00 77.16 C ATOM 578 C GLY A 33 -7.197 21.289 -10.091 1.00 75.93 C ATOM 579 O GLY A 33 -6.281 21.109 -9.286 1.00 76.12 O ATOM 580 H GLY A 33 -4.844 21.869 -11.335 1.00 78.94 H ATOM 581 HA3 GLY A 33 -7.739 21.809 -12.133 1.00 77.16 H ATOM 582 HA2 GLY A 33 -6.971 23.090 -11.225 1.00 77.16 H ATOM 583 N HIS A 34 -8.470 20.947 -9.846 1.00 73.24 N ATOM 584 CA HIS A 34 -8.981 20.366 -8.604 1.00 70.97 C ATOM 585 C HIS A 34 -9.527 18.967 -8.916 1.00 67.64 C ATOM 586 O HIS A 34 -10.403 18.856 -9.772 1.00 67.60 O ATOM 587 CB HIS A 34 -10.117 21.253 -8.030 1.00 71.68 C ATOM 588 CG HIS A 34 -9.926 22.751 -8.083 1.00 74.93 C ATOM 589 ND1 HIS A 34 -10.042 23.486 -9.270 1.00 78.88 N ATOM 590 CD2 HIS A 34 -9.674 23.626 -7.048 1.00 77.21 C ATOM 591 CE1 HIS A 34 -9.827 24.746 -8.918 1.00 78.73 C ATOM 592 NE2 HIS A 34 -9.612 24.888 -7.610 1.00 78.39 N ATOM 593 H HIS A 34 -9.165 21.118 -10.561 1.00 73.24 H ATOM 594 HA HIS A 34 -8.183 20.297 -7.861 1.00 70.97 H ATOM 595 HB3 HIS A 34 -10.306 20.967 -6.995 1.00 71.68 H ATOM 596 HB2 HIS A 34 -11.050 21.062 -8.558 1.00 71.68 H ATOM 597 HD2 HIS A 34 -9.538 23.457 -5.992 1.00 77.21 H ATOM 598 HE1 HIS A 34 -9.829 25.569 -9.617 1.00 78.73 H ATOM 599 HE2 HIS A 34 -9.432 25.758 -7.128 1.00 78.39 H ATOM 600 N VAL A 35 -9.036 17.938 -8.207 1.00 63.64 N ATOM 601 CA VAL A 35 -9.527 16.563 -8.334 1.00 60.60 C ATOM 602 C VAL A 35 -10.259 16.171 -7.041 1.00 60.62 C ATOM 603 O VAL A 35 -9.733 16.383 -5.948 1.00 60.14 O ATOM 604 CB VAL A 35 -8.379 15.551 -8.620 1.00 59.76 C ATOM 605 CG1 VAL A 35 -8.795 14.065 -8.545 1.00 55.29 C ATOM 606 CG2 VAL A 35 -7.765 15.808 -10.008 1.00 59.83 C ATOM 607 H VAL A 35 -8.342 18.102 -7.490 1.00 63.64 H ATOM 608 HA VAL A 35 -10.233 16.485 -9.160 1.00 60.60 H ATOM 609 HB VAL A 35 -7.594 15.714 -7.880 1.00 59.76 H ATOM 610 HG11 VAL A 35 -7.961 13.414 -8.804 1.00 55.29 H ATOM 611 HG12 VAL A 35 -9.123 13.767 -7.552 1.00 55.29 H ATOM 612 HG13 VAL A 35 -9.609 13.847 -9.239 1.00 55.29 H ATOM 613 HG21 VAL A 35 -6.852 15.228 -10.142 1.00 59.83 H ATOM 614 HG22 VAL A 35 -8.455 15.527 -10.804 1.00 59.83 H ATOM 615 HG23 VAL A 35 -7.513 16.855 -10.162 1.00 59.83 H ATOM 616 N TYR A 36 -11.460 15.601 -7.212 1.00 60.15 N ATOM 617 CA TYR A 36 -12.343 15.151 -6.142 1.00 60.44 C ATOM 618 C TYR A 36 -12.631 13.659 -6.306 1.00 61.31 C ATOM 619 O TYR A 36 -12.871 13.206 -7.424 1.00 61.39 O ATOM 620 CB TYR A 36 -13.683 15.919 -6.204 1.00 60.94 C ATOM 621 CG TYR A 36 -13.598 17.429 -6.072 1.00 59.07 C ATOM 622 CD1 TYR A 36 -13.352 18.229 -7.207 1.00 56.26 C ATOM 623 CD2 TYR A 36 -13.796 18.044 -4.819 1.00 59.81 C ATOM 624 CE1 TYR A 36 -13.290 19.630 -7.090 1.00 59.00 C ATOM 625 CE2 TYR A 36 -13.725 19.445 -4.698 1.00 59.97 C ATOM 626 CZ TYR A 36 -13.466 20.239 -5.832 1.00 60.17 C ATOM 627 OH TYR A 36 -13.391 21.596 -5.714 1.00 63.33 O ATOM 628 H TYR A 36 -11.819 15.477 -8.151 1.00 60.15 H ATOM 629 HA TYR A 36 -11.880 15.301 -5.168 1.00 60.44 H ATOM 630 HB3 TYR A 36 -14.336 15.551 -5.411 1.00 60.94 H ATOM 631 HB2 TYR A 36 -14.200 15.698 -7.139 1.00 60.94 H ATOM 632 HD1 TYR A 36 -13.213 17.773 -8.176 1.00 56.26 H ATOM 633 HD2 TYR A 36 -14.006 17.443 -3.947 1.00 59.81 H ATOM 634 HE1 TYR A 36 -13.110 20.230 -7.969 1.00 59.00 H ATOM 635 HE2 TYR A 36 -13.875 19.908 -3.734 1.00 59.97 H ATOM 636 HH TYR A 36 -13.311 22.039 -6.562 1.00 63.33 H ATOM 637 N LYS A 37 -12.696 12.950 -5.170 1.00 61.26 N ATOM 638 CA LYS A 37 -13.341 11.645 -5.066 1.00 62.97 C ATOM 639 C LYS A 37 -14.862 11.867 -5.019 1.00 64.22 C ATOM 640 O LYS A 37 -15.319 12.750 -4.291 1.00 64.72 O ATOM 641 CB LYS A 37 -12.819 10.934 -3.806 1.00 63.74 C ATOM 642 CG LYS A 37 -13.340 9.497 -3.627 1.00 67.56 C ATOM 643 CD LYS A 37 -12.718 8.796 -2.410 1.00 68.71 C ATOM 644 CE LYS A 37 -12.983 7.285 -2.418 1.00 68.68 C ATOM 645 NZ LYS A 37 -12.258 6.576 -1.348 1.00 69.07 N1+ ATOM 646 H LYS A 37 -12.507 13.412 -4.290 1.00 61.26 H ATOM 647 HA LYS A 37 -13.080 11.043 -5.939 1.00 62.97 H ATOM 648 HB3 LYS A 37 -13.065 11.529 -2.928 1.00 63.74 H ATOM 649 HB2 LYS A 37 -11.731 10.901 -3.854 1.00 63.74 H ATOM 650 HG3 LYS A 37 -13.121 8.927 -4.532 1.00 67.56 H ATOM 651 HG2 LYS A 37 -14.425 9.494 -3.523 1.00 67.56 H ATOM 652 HD3 LYS A 37 -13.138 9.229 -1.503 1.00 68.71 H ATOM 653 HD2 LYS A 37 -11.648 9.001 -2.374 1.00 68.71 H ATOM 654 HE3 LYS A 37 -12.665 6.864 -3.370 1.00 68.68 H ATOM 655 HE2 LYS A 37 -14.051 7.089 -2.316 1.00 68.68 H ATOM 656 HZ1 LYS A 37 -11.263 6.715 -1.461 1.00 69.07 H ATOM 657 HZ2 LYS A 37 -12.550 6.921 -0.446 1.00 69.07 H ATOM 658 HZ3 LYS A 37 -12.459 5.588 -1.418 1.00 69.07 H ATOM 659 N ALA A 38 -15.607 11.087 -5.811 1.00 64.94 N ATOM 660 CA ALA A 38 -17.036 11.283 -6.015 1.00 65.98 C ATOM 661 C ALA A 38 -17.788 9.952 -6.041 1.00 67.60 C ATOM 662 O ALA A 38 -17.251 8.944 -6.499 1.00 66.77 O ATOM 663 CB ALA A 38 -17.244 12.052 -7.329 1.00 66.59 C ATOM 664 H ALA A 38 -15.166 10.389 -6.397 1.00 64.94 H ATOM 665 HA ALA A 38 -17.441 11.873 -5.195 1.00 65.98 H ATOM 666 HB1 ALA A 38 -18.299 12.279 -7.483 1.00 66.59 H ATOM 667 HB2 ALA A 38 -16.703 12.998 -7.322 1.00 66.59 H ATOM 668 HB3 ALA A 38 -16.894 11.481 -8.190 1.00 66.59 H ATOM 669 N LYS A 39 -19.044 10.010 -5.577 1.00 69.44 N ATOM 670 CA LYS A 39 -20.024 8.932 -5.667 1.00 71.48 C ATOM 671 C LYS A 39 -21.240 9.443 -6.444 1.00 73.06 C ATOM 672 O LYS A 39 -21.609 10.611 -6.320 1.00 72.05 O ATOM 673 CB LYS A 39 -20.453 8.488 -4.256 1.00 71.64 C ATOM 674 CG LYS A 39 -19.329 7.812 -3.452 0.00 71.03 C ATOM 675 CD LYS A 39 -19.821 7.146 -2.155 0.00 71.06 C ATOM 676 CE LYS A 39 -20.441 8.127 -1.143 0.00 71.06 C ATOM 677 NZ LYS A 39 -20.877 7.436 0.083 0.00 71.02 N1+ ATOM 678 H LYS A 39 -19.398 10.890 -5.226 1.00 69.44 H ATOM 679 HA LYS A 39 -19.607 8.075 -6.200 1.00 71.48 H ATOM 680 HB3 LYS A 39 -21.274 7.775 -4.352 1.00 71.64 H ATOM 681 HB2 LYS A 39 -20.852 9.342 -3.707 1.00 71.64 H ATOM 682 HG3 LYS A 39 -18.554 8.541 -3.214 1.00 71.03 H ATOM 683 HG2 LYS A 39 -18.848 7.054 -4.072 1.00 71.03 H ATOM 684 HD3 LYS A 39 -18.979 6.626 -1.696 1.00 71.06 H ATOM 685 HD2 LYS A 39 -20.545 6.370 -2.411 1.00 71.06 H ATOM 686 HE3 LYS A 39 -21.309 8.629 -1.570 1.00 71.06 H ATOM 687 HE2 LYS A 39 -19.720 8.900 -0.875 1.00 71.06 H ATOM 688 HZ1 LYS A 39 -20.083 6.989 0.519 1.00 71.02 H ATOM 689 HZ2 LYS A 39 -21.283 8.104 0.722 1.00 71.02 H ATOM 690 HZ3 LYS A 39 -21.565 6.736 -0.155 1.00 71.02 H ATOM 691 N ARG A 40 -21.848 8.534 -7.215 1.00 76.97 N ATOM 692 CA ARG A 40 -23.063 8.753 -7.991 1.00 80.49 C ATOM 693 C ARG A 40 -24.281 8.860 -7.057 1.00 83.00 C ATOM 694 O ARG A 40 -24.455 7.995 -6.197 1.00 83.54 O ATOM 695 CB ARG A 40 -23.168 7.587 -8.990 1.00 81.56 C ATOM 696 CG ARG A 40 -24.260 7.724 -10.057 1.00 85.86 C ATOM 697 CD ARG A 40 -24.206 6.535 -11.027 1.00 88.88 C ATOM 698 NE ARG A 40 -25.054 6.730 -12.210 1.00 94.07 N ATOM 699 CZ ARG A 40 -25.070 5.974 -13.323 1.00 97.27 C ATOM 700 NH1 ARG A 40 -24.273 4.903 -13.470 1.00 97.37 N ATOM 701 NH2 ARG A 40 -25.910 6.305 -14.311 1.00 98.75 N1+ ATOM 702 H ARG A 40 -21.504 7.581 -7.213 1.00 76.97 H ATOM 703 HA ARG A 40 -22.944 9.683 -8.550 1.00 80.49 H ATOM 704 HB3 ARG A 40 -23.313 6.649 -8.452 1.00 81.56 H ATOM 705 HB2 ARG A 40 -22.210 7.491 -9.504 1.00 81.56 H ATOM 706 HG3 ARG A 40 -24.225 8.684 -10.576 1.00 85.86 H ATOM 707 HG2 ARG A 40 -25.214 7.691 -9.530 1.00 85.86 H ATOM 708 HD3 ARG A 40 -24.654 5.679 -10.521 1.00 88.88 H ATOM 709 HD2 ARG A 40 -23.181 6.256 -11.275 1.00 88.88 H ATOM 710 HE ARG A 40 -25.757 7.452 -12.112 1.00 94.07 H ATOM 711 HH12 ARG A 40 -24.278 4.359 -14.320 1.00 97.37 H ATOM 712 HH11 ARG A 40 -23.665 4.625 -12.708 1.00 97.37 H ATOM 713 HH22 ARG A 40 -25.938 5.772 -15.167 1.00 98.75 H ATOM 714 HH21 ARG A 40 -26.530 7.096 -14.199 1.00 98.75 H ATOM 715 N LYS A 41 -25.079 9.929 -7.223 1.00 85.33 N ATOM 716 CA LYS A 41 -26.220 10.251 -6.360 1.00 87.15 C ATOM 717 C LYS A 41 -27.400 9.269 -6.454 1.00 90.90 C ATOM 718 O LYS A 41 -28.054 9.046 -5.435 1.00 92.23 O ATOM 719 CB LYS A 41 -26.657 11.716 -6.575 1.00 85.71 C ATOM 720 CG LYS A 41 -25.743 12.704 -5.832 1.00 81.53 C ATOM 721 CD LYS A 41 -26.204 14.167 -5.925 1.00 75.37 C ATOM 722 CE LYS A 41 -25.514 15.051 -4.873 1.00 71.89 C ATOM 723 NZ LYS A 41 -25.974 16.447 -4.919 1.00 68.86 N1+ ATOM 724 H LYS A 41 -24.872 10.594 -7.958 1.00 85.33 H ATOM 725 HA LYS A 41 -25.855 10.166 -5.334 1.00 87.15 H ATOM 726 HB3 LYS A 41 -27.665 11.851 -6.179 1.00 85.71 H ATOM 727 HB2 LYS A 41 -26.716 11.954 -7.638 1.00 85.71 H ATOM 728 HG3 LYS A 41 -24.728 12.614 -6.214 1.00 81.53 H ATOM 729 HG2 LYS A 41 -25.697 12.415 -4.781 1.00 81.53 H ATOM 730 HD3 LYS A 41 -27.288 14.224 -5.816 1.00 75.37 H ATOM 731 HD2 LYS A 41 -25.972 14.544 -6.922 1.00 75.37 H ATOM 732 HE3 LYS A 41 -24.437 15.044 -5.022 1.00 71.89 H ATOM 733 HE2 LYS A 41 -25.701 14.663 -3.871 1.00 71.89 H ATOM 734 HZ1 LYS A 41 -25.768 16.836 -5.832 1.00 68.86 H ATOM 735 HZ2 LYS A 41 -26.968 16.488 -4.750 1.00 68.86 H ATOM 736 HZ3 LYS A 41 -25.487 16.980 -4.211 1.00 68.86 H ATOM 737 N ASP A 42 -27.624 8.669 -7.636 1.00 93.71 N ATOM 738 CA ASP A 42 -28.547 7.544 -7.810 1.00 95.91 C ATOM 739 C ASP A 42 -27.822 6.229 -7.454 1.00 97.60 C ATOM 740 O ASP A 42 -26.616 6.103 -7.674 1.00 98.72 O ATOM 741 CB ASP A 42 -29.204 7.498 -9.214 1.00 96.49 C ATOM 742 CG ASP A 42 -28.251 7.435 -10.417 1.00 98.46 C ATOM 743 OD1 ASP A 42 -28.031 6.304 -10.902 1.00 99.43 O ATOM 744 OD2 ASP A 42 -27.667 8.487 -10.764 1.00101.14 O1- ATOM 745 H ASP A 42 -27.057 8.904 -8.439 1.00 93.71 H ATOM 746 HA ASP A 42 -29.368 7.665 -7.100 1.00 95.91 H ATOM 747 HB3 ASP A 42 -29.809 8.399 -9.334 1.00 96.49 H ATOM 748 HB2 ASP A 42 -29.918 6.674 -9.263 1.00 96.49 H ATOM 749 N GLY A 43 -28.586 5.277 -6.896 1.00 98.98 N ATOM 750 CA GLY A 43 -28.083 4.035 -6.303 1.00 99.78 C ATOM 751 C GLY A 43 -27.805 2.916 -7.322 1.00100.29 C ATOM 752 O GLY A 43 -27.829 1.750 -6.928 1.00101.59 O ATOM 753 H GLY A 43 -29.573 5.456 -6.780 1.00 98.98 H ATOM 754 HA3 GLY A 43 -28.820 3.680 -5.583 1.00 99.78 H ATOM 755 HA2 GLY A 43 -27.169 4.232 -5.740 1.00 99.78 H ATOM 756 N LYS A 44 -27.566 3.239 -8.607 1.00 99.97 N ATOM 757 CA LYS A 44 -27.300 2.270 -9.677 1.00 99.84 C ATOM 758 C LYS A 44 -25.971 1.502 -9.513 1.00 99.39 C ATOM 759 O LYS A 44 -25.916 0.327 -9.876 1.00 99.72 O ATOM 760 CB LYS A 44 -27.403 2.988 -11.037 1.00100.08 C ATOM 761 CG LYS A 44 -27.295 2.059 -12.258 0.00 99.81 C ATOM 762 CD LYS A 44 -27.681 2.768 -13.567 0.00 99.87 C ATOM 763 CE LYS A 44 -27.588 1.876 -14.818 0.00 99.88 C ATOM 764 NZ LYS A 44 -28.599 0.802 -14.824 0.00 99.88 N1+ ATOM 765 H LYS A 44 -27.553 4.213 -8.876 1.00 99.97 H ATOM 766 HA LYS A 44 -28.101 1.530 -9.637 1.00 99.84 H ATOM 767 HB3 LYS A 44 -26.649 3.775 -11.107 1.00100.08 H ATOM 768 HB2 LYS A 44 -28.371 3.489 -11.079 1.00100.08 H ATOM 769 HG3 LYS A 44 -27.933 1.189 -12.099 1.00 99.81 H ATOM 770 HG2 LYS A 44 -26.275 1.682 -12.346 1.00 99.81 H ATOM 771 HD3 LYS A 44 -27.028 3.628 -13.703 1.00 99.87 H ATOM 772 HD2 LYS A 44 -28.688 3.179 -13.479 1.00 99.87 H ATOM 773 HE3 LYS A 44 -26.593 1.435 -14.897 1.00 99.88 H ATOM 774 HE2 LYS A 44 -27.737 2.483 -15.711 1.00 99.88 H ATOM 775 HZ1 LYS A 44 -29.524 1.208 -14.786 1.00 99.88 H ATOM 776 HZ2 LYS A 44 -28.507 0.253 -15.667 1.00 99.88 H ATOM 777 HZ3 LYS A 44 -28.462 0.206 -14.019 1.00 99.88 H ATOM 778 N ASP A 45 -24.951 2.160 -8.940 1.00 98.19 N ATOM 779 CA ASP A 45 -23.674 1.555 -8.559 1.00 96.77 C ATOM 780 C ASP A 45 -23.020 2.405 -7.458 1.00 94.79 C ATOM 781 O ASP A 45 -23.235 3.617 -7.407 1.00 95.24 O ATOM 782 CB ASP A 45 -22.696 1.269 -9.739 1.00 97.09 C ATOM 783 CG ASP A 45 -22.200 2.435 -10.621 1.00 98.36 C ATOM 784 OD1 ASP A 45 -22.817 3.523 -10.636 1.00102.21 O ATOM 785 OD2 ASP A 45 -21.238 2.175 -11.376 1.00 98.50 O1- ATOM 786 H ASP A 45 -25.066 3.129 -8.675 1.00 98.19 H ATOM 787 HA ASP A 45 -23.911 0.594 -8.097 1.00 96.77 H ATOM 788 HB3 ASP A 45 -23.194 0.578 -10.419 1.00 97.09 H ATOM 789 HB2 ASP A 45 -21.834 0.716 -9.360 1.00 97.09 H ATOM 790 N ASP A 46 -22.222 1.740 -6.605 1.00 92.15 N ATOM 791 CA ASP A 46 -21.519 2.341 -5.465 1.00 89.96 C ATOM 792 C ASP A 46 -20.001 2.453 -5.754 1.00 87.43 C ATOM 793 O ASP A 46 -19.198 2.451 -4.821 1.00 87.03 O ATOM 794 CB ASP A 46 -21.829 1.550 -4.161 1.00 90.43 C ATOM 795 CG ASP A 46 -21.569 2.264 -2.817 1.00 91.04 C ATOM 796 OD1 ASP A 46 -21.591 3.515 -2.777 1.00 93.68 O ATOM 797 OD2 ASP A 46 -21.500 1.528 -1.808 1.00 88.75 O1- ATOM 798 H ASP A 46 -22.096 0.745 -6.719 1.00 92.15 H ATOM 799 HA ASP A 46 -21.872 3.365 -5.340 1.00 89.96 H ATOM 800 HB3 ASP A 46 -21.287 0.603 -4.178 1.00 90.43 H ATOM 801 HB2 ASP A 46 -22.882 1.265 -4.169 1.00 90.43 H ATOM 802 N LYS A 47 -19.623 2.557 -7.042 1.00 84.60 N ATOM 803 CA LYS A 47 -18.241 2.758 -7.481 1.00 82.36 C ATOM 804 C LYS A 47 -17.736 4.173 -7.162 1.00 78.80 C ATOM 805 O LYS A 47 -18.493 5.136 -7.281 1.00 77.80 O ATOM 806 CB LYS A 47 -18.129 2.504 -8.997 1.00 83.02 C ATOM 807 CG LYS A 47 -18.307 1.033 -9.400 0.00 82.35 C ATOM 808 CD LYS A 47 -17.930 0.799 -10.870 0.00 82.43 C ATOM 809 CE LYS A 47 -18.156 -0.651 -11.322 0.00 82.44 C ATOM 810 NZ LYS A 47 -17.765 -0.843 -12.730 0.00 82.42 N1+ ATOM 811 H LYS A 47 -20.326 2.552 -7.767 1.00 84.60 H ATOM 812 HA LYS A 47 -17.609 2.037 -6.957 1.00 82.36 H ATOM 813 HB3 LYS A 47 -17.137 2.818 -9.329 1.00 83.02 H ATOM 814 HB2 LYS A 47 -18.838 3.129 -9.542 1.00 83.02 H ATOM 815 HG3 LYS A 47 -19.342 0.731 -9.232 1.00 82.35 H ATOM 816 HG2 LYS A 47 -17.692 0.397 -8.762 1.00 82.35 H ATOM 817 HD3 LYS A 47 -16.881 1.067 -11.011 1.00 82.43 H ATOM 818 HD2 LYS A 47 -18.502 1.481 -11.502 1.00 82.43 H ATOM 819 HE3 LYS A 47 -19.207 -0.921 -11.209 1.00 82.44 H ATOM 820 HE2 LYS A 47 -17.576 -1.335 -10.702 1.00 82.44 H ATOM 821 HZ1 LYS A 47 -16.785 -0.622 -12.843 1.00 82.42 H ATOM 822 HZ2 LYS A 47 -17.927 -1.803 -13.000 1.00 82.42 H ATOM 823 HZ3 LYS A 47 -18.315 -0.231 -13.317 1.00 82.42 H ATOM 824 N ASP A 48 -16.442 4.264 -6.827 1.00 74.59 N ATOM 825 CA ASP A 48 -15.713 5.525 -6.694 1.00 71.55 C ATOM 826 C ASP A 48 -15.334 6.060 -8.086 1.00 68.21 C ATOM 827 O ASP A 48 -14.876 5.295 -8.936 1.00 68.36 O ATOM 828 CB ASP A 48 -14.450 5.383 -5.807 1.00 71.02 C ATOM 829 CG ASP A 48 -14.693 4.878 -4.373 1.00 72.78 C ATOM 830 OD1 ASP A 48 -15.759 5.198 -3.800 1.00 77.74 O ATOM 831 OD2 ASP A 48 -13.723 4.330 -3.803 1.00 67.24 O1- ATOM 832 H ASP A 48 -15.887 3.425 -6.746 1.00 74.59 H ATOM 833 HA ASP A 48 -16.375 6.256 -6.223 1.00 71.55 H ATOM 834 HB3 ASP A 48 -13.939 6.345 -5.734 1.00 71.02 H ATOM 835 HB2 ASP A 48 -13.757 4.689 -6.287 1.00 71.02 H ATOM 836 N TYR A 49 -15.514 7.374 -8.266 1.00 65.06 N ATOM 837 CA TYR A 49 -15.182 8.125 -9.475 1.00 62.46 C ATOM 838 C TYR A 49 -14.264 9.301 -9.116 1.00 60.48 C ATOM 839 O TYR A 49 -14.287 9.773 -7.980 1.00 58.86 O ATOM 840 CB TYR A 49 -16.483 8.635 -10.123 1.00 62.72 C ATOM 841 CG TYR A 49 -17.339 7.552 -10.755 1.00 67.33 C ATOM 842 CD1 TYR A 49 -18.376 6.939 -10.019 1.00 67.25 C ATOM 843 CD2 TYR A 49 -17.095 7.150 -12.084 1.00 69.29 C ATOM 844 CE1 TYR A 49 -19.164 5.931 -10.608 1.00 68.70 C ATOM 845 CE2 TYR A 49 -17.883 6.145 -12.674 1.00 71.71 C ATOM 846 CZ TYR A 49 -18.917 5.533 -11.938 1.00 71.69 C ATOM 847 OH TYR A 49 -19.671 4.555 -12.519 1.00 72.95 O ATOM 848 H TYR A 49 -15.912 7.923 -7.514 1.00 65.06 H ATOM 849 HA TYR A 49 -14.651 7.489 -10.188 1.00 62.46 H ATOM 850 HB3 TYR A 49 -16.232 9.343 -10.912 1.00 62.72 H ATOM 851 HB2 TYR A 49 -17.080 9.195 -9.401 1.00 62.72 H ATOM 852 HD1 TYR A 49 -18.568 7.240 -8.999 1.00 67.25 H ATOM 853 HD2 TYR A 49 -16.300 7.608 -12.655 1.00 69.29 H ATOM 854 HE1 TYR A 49 -19.955 5.465 -10.037 1.00 68.70 H ATOM 855 HE2 TYR A 49 -17.687 5.839 -13.692 1.00 71.71 H ATOM 856 HH TYR A 49 -20.280 4.110 -11.919 1.00 72.95 H ATOM 857 N ALA A 50 -13.473 9.748 -10.100 1.00 57.89 N ATOM 858 CA ALA A 50 -12.576 10.891 -9.986 1.00 57.22 C ATOM 859 C ALA A 50 -13.065 12.011 -10.910 1.00 57.62 C ATOM 860 O ALA A 50 -13.017 11.857 -12.129 1.00 59.75 O ATOM 861 CB ALA A 50 -11.149 10.450 -10.332 1.00 56.31 C ATOM 862 H ALA A 50 -13.517 9.311 -11.013 1.00 57.89 H ATOM 863 HA ALA A 50 -12.552 11.263 -8.963 1.00 57.22 H ATOM 864 HB1 ALA A 50 -10.475 11.303 -10.422 1.00 56.31 H ATOM 865 HB2 ALA A 50 -10.752 9.803 -9.552 1.00 56.31 H ATOM 866 HB3 ALA A 50 -11.115 9.890 -11.265 1.00 56.31 H ATOM 867 N LEU A 51 -13.527 13.112 -10.301 1.00 56.70 N ATOM 868 CA LEU A 51 -14.004 14.313 -10.981 1.00 56.58 C ATOM 869 C LEU A 51 -12.902 15.376 -10.959 1.00 57.30 C ATOM 870 O LEU A 51 -12.632 15.946 -9.903 1.00 56.16 O ATOM 871 CB LEU A 51 -15.283 14.820 -10.275 1.00 57.05 C ATOM 872 CG LEU A 51 -16.572 14.188 -10.836 1.00 60.95 C ATOM 873 CD1 LEU A 51 -17.771 14.461 -9.909 1.00 60.03 C ATOM 874 CD2 LEU A 51 -16.849 14.648 -12.285 1.00 60.08 C ATOM 875 H LEU A 51 -13.510 13.157 -9.290 1.00 56.70 H ATOM 876 HA LEU A 51 -14.236 14.089 -12.023 1.00 56.58 H ATOM 877 HB3 LEU A 51 -15.372 15.904 -10.361 1.00 57.05 H ATOM 878 HB2 LEU A 51 -15.201 14.625 -9.204 1.00 57.05 H ATOM 879 HG LEU A 51 -16.430 13.107 -10.852 1.00 60.95 H ATOM 880 HD11 LEU A 51 -18.224 13.521 -9.600 1.00 60.03 H ATOM 881 HD12 LEU A 51 -17.484 14.995 -9.002 1.00 60.03 H ATOM 882 HD13 LEU A 51 -18.551 15.051 -10.388 1.00 60.03 H ATOM 883 HD21 LEU A 51 -17.914 14.702 -12.508 1.00 60.08 H ATOM 884 HD22 LEU A 51 -16.420 15.629 -12.490 1.00 60.08 H ATOM 885 HD23 LEU A 51 -16.415 13.954 -13.003 1.00 60.08 H ATOM 886 N LYS A 52 -12.307 15.624 -12.134 1.00 57.59 N ATOM 887 CA LYS A 52 -11.305 16.658 -12.359 1.00 58.34 C ATOM 888 C LYS A 52 -11.985 17.911 -12.925 1.00 58.71 C ATOM 889 O LYS A 52 -12.323 17.927 -14.107 1.00 56.90 O ATOM 890 CB LYS A 52 -10.229 16.113 -13.323 1.00 59.12 C ATOM 891 CG LYS A 52 -9.110 17.117 -13.661 1.00 60.47 C ATOM 892 CD LYS A 52 -8.101 16.562 -14.674 1.00 62.30 C ATOM 893 CE LYS A 52 -6.903 17.507 -14.855 1.00 65.70 C ATOM 894 NZ LYS A 52 -5.830 16.900 -15.660 1.00 65.73 N1+ ATOM 895 H LYS A 52 -12.599 15.108 -12.955 1.00 57.59 H ATOM 896 HA LYS A 52 -10.808 16.908 -11.422 1.00 58.34 H ATOM 897 HB3 LYS A 52 -10.709 15.796 -14.247 1.00 59.12 H ATOM 898 HB2 LYS A 52 -9.784 15.214 -12.894 1.00 59.12 H ATOM 899 HG3 LYS A 52 -8.594 17.393 -12.739 1.00 60.47 H ATOM 900 HG2 LYS A 52 -9.522 18.042 -14.065 1.00 60.47 H ATOM 901 HD3 LYS A 52 -8.599 16.419 -15.634 1.00 62.30 H ATOM 902 HD2 LYS A 52 -7.774 15.573 -14.356 1.00 62.30 H ATOM 903 HE3 LYS A 52 -6.494 17.762 -13.878 1.00 65.70 H ATOM 904 HE2 LYS A 52 -7.221 18.439 -15.325 1.00 65.70 H ATOM 905 HZ1 LYS A 52 -6.186 16.684 -16.585 1.00 65.73 H ATOM 906 HZ2 LYS A 52 -5.055 17.542 -15.749 1.00 65.73 H ATOM 907 HZ3 LYS A 52 -5.506 16.052 -15.217 1.00 65.73 H ATOM 908 N GLN A 53 -12.110 18.956 -12.094 1.00 58.77 N ATOM 909 CA GLN A 53 -12.391 20.317 -12.544 1.00 60.35 C ATOM 910 C GLN A 53 -11.093 20.917 -13.108 1.00 61.07 C ATOM 911 O GLN A 53 -10.129 21.052 -12.356 1.00 60.36 O ATOM 912 CB GLN A 53 -12.935 21.142 -11.359 1.00 60.87 C ATOM 913 CG GLN A 53 -13.272 22.602 -11.721 1.00 64.55 C ATOM 914 CD GLN A 53 -13.921 23.362 -10.564 1.00 67.97 C ATOM 915 OE1 GLN A 53 -15.058 23.810 -10.676 1.00 71.42 O ATOM 916 NE2 GLN A 53 -13.192 23.548 -9.463 1.00 68.26 N ATOM 917 H GLN A 53 -11.786 18.866 -11.140 1.00 58.77 H ATOM 918 HA GLN A 53 -13.156 20.293 -13.321 1.00 60.35 H ATOM 919 HB3 GLN A 53 -12.214 21.125 -10.542 1.00 60.87 H ATOM 920 HB2 GLN A 53 -13.830 20.656 -10.975 1.00 60.87 H ATOM 921 HG3 GLN A 53 -13.949 22.620 -12.576 1.00 64.55 H ATOM 922 HG2 GLN A 53 -12.375 23.145 -12.021 1.00 64.55 H ATOM 923 HE22 GLN A 53 -13.582 24.061 -8.685 1.00 68.26 H ATOM 924 HE21 GLN A 53 -12.240 23.210 -9.414 1.00 68.26 H ATOM 925 N ILE A 54 -11.092 21.256 -14.407 1.00 63.18 N ATOM 926 CA ILE A 54 -9.946 21.850 -15.103 1.00 65.00 C ATOM 927 C ILE A 54 -9.695 23.297 -14.619 1.00 67.34 C ATOM 928 O ILE A 54 -10.655 24.022 -14.346 1.00 66.89 O ATOM 929 CB ILE A 54 -10.156 21.831 -16.652 1.00 65.02 C ATOM 930 CG1 ILE A 54 -10.270 20.379 -17.180 1.00 64.91 C ATOM 931 CG2 ILE A 54 -9.065 22.589 -17.445 1.00 68.02 C ATOM 932 CD1 ILE A 54 -10.625 20.277 -18.674 1.00 61.37 C ATOM 933 H ILE A 54 -11.930 21.124 -14.958 1.00 63.18 H ATOM 934 HA ILE A 54 -9.064 21.250 -14.868 1.00 65.00 H ATOM 935 HB ILE A 54 -11.108 22.320 -16.864 1.00 65.02 H ATOM 936 HG13 ILE A 54 -11.022 19.827 -16.615 1.00 64.91 H ATOM 937 HG12 ILE A 54 -9.327 19.858 -17.004 1.00 64.91 H ATOM 938 HG21 ILE A 54 -9.190 22.480 -18.520 1.00 68.02 H ATOM 939 HG22 ILE A 54 -9.092 23.660 -17.255 1.00 68.02 H ATOM 940 HG23 ILE A 54 -8.068 22.223 -17.195 1.00 68.02 H ATOM 941 HD11 ILE A 54 -11.292 19.438 -18.864 1.00 61.37 H ATOM 942 HD12 ILE A 54 -11.124 21.174 -19.038 1.00 61.37 H ATOM 943 HD13 ILE A 54 -9.730 20.124 -19.280 1.00 61.37 H ATOM 944 N GLU A 55 -8.410 23.681 -14.515 1.00 70.15 N ATOM 945 CA GLU A 55 -7.963 25.011 -14.092 1.00 71.83 C ATOM 946 C GLU A 55 -8.351 26.111 -15.104 1.00 71.47 C ATOM 947 O GLU A 55 -8.218 25.904 -16.310 1.00 70.79 O ATOM 948 CB GLU A 55 -6.435 24.962 -13.841 1.00 73.16 C ATOM 949 CG GLU A 55 -5.786 26.255 -13.286 1.00 76.56 C ATOM 950 CD GLU A 55 -6.241 26.704 -11.883 1.00 79.12 C ATOM 951 OE1 GLU A 55 -6.843 25.893 -11.143 1.00 81.59 O ATOM 952 OE2 GLU A 55 -5.967 27.879 -11.555 1.00 81.76 O1- ATOM 953 H GLU A 55 -7.677 23.027 -14.753 1.00 70.15 H ATOM 954 HA GLU A 55 -8.473 25.222 -13.151 1.00 71.83 H ATOM 955 HB3 GLU A 55 -5.935 24.710 -14.777 1.00 73.16 H ATOM 956 HB2 GLU A 55 -6.198 24.134 -13.175 1.00 73.16 H ATOM 957 HG3 GLU A 55 -5.931 27.076 -13.990 1.00 76.56 H ATOM 958 HG2 GLU A 55 -4.707 26.101 -13.237 1.00 76.56 H ATOM 959 N GLY A 56 -8.813 27.262 -14.586 1.00 72.71 N ATOM 960 CA GLY A 56 -9.273 28.401 -15.387 1.00 73.44 C ATOM 961 C GLY A 56 -10.720 28.204 -15.875 1.00 73.84 C ATOM 962 O GLY A 56 -11.352 27.184 -15.600 1.00 74.36 O ATOM 963 H GLY A 56 -8.853 27.365 -13.583 1.00 72.71 H ATOM 964 HA3 GLY A 56 -8.613 28.562 -16.241 1.00 73.44 H ATOM 965 HA2 GLY A 56 -9.224 29.300 -14.772 1.00 73.44 H ATOM 966 N THR A 57 -11.245 29.211 -16.590 1.00 74.35 N ATOM 967 CA THR A 57 -12.614 29.245 -17.119 1.00 74.06 C ATOM 968 C THR A 57 -12.607 29.195 -18.660 1.00 73.22 C ATOM 969 O THR A 57 -11.610 29.543 -19.296 1.00 72.49 O ATOM 970 CB THR A 57 -13.342 30.548 -16.685 1.00 74.45 C ATOM 971 OG1 THR A 57 -12.751 31.714 -17.234 1.00 76.35 O ATOM 972 CG2 THR A 57 -13.439 30.710 -15.161 1.00 75.14 C ATOM 973 H THR A 57 -10.684 30.025 -16.796 1.00 74.35 H ATOM 974 HA THR A 57 -13.191 28.391 -16.757 1.00 74.06 H ATOM 975 HB THR A 57 -14.365 30.512 -17.064 1.00 74.45 H ATOM 976 HG1 THR A 57 -12.791 31.661 -18.192 1.00 76.35 H ATOM 977 HG21 THR A 57 -14.009 31.602 -14.898 1.00 75.14 H ATOM 978 HG22 THR A 57 -13.947 29.856 -14.712 1.00 75.14 H ATOM 979 HG23 THR A 57 -12.457 30.797 -14.697 1.00 75.14 H ATOM 980 N GLY A 58 -13.748 28.763 -19.219 1.00 71.96 N ATOM 981 CA GLY A 58 -13.952 28.524 -20.644 1.00 71.53 C ATOM 982 C GLY A 58 -13.241 27.233 -21.064 1.00 71.34 C ATOM 983 O GLY A 58 -13.040 26.328 -20.252 1.00 72.15 O ATOM 984 H GLY A 58 -14.501 28.460 -18.613 1.00 71.96 H ATOM 985 HA3 GLY A 58 -13.597 29.374 -21.229 1.00 71.53 H ATOM 986 HA2 GLY A 58 -15.019 28.411 -20.833 1.00 71.53 H ATOM 987 N ILE A 59 -12.869 27.164 -22.349 1.00 70.55 N ATOM 988 CA ILE A 59 -12.007 26.119 -22.891 1.00 70.70 C ATOM 989 C ILE A 59 -10.695 26.825 -23.278 1.00 69.49 C ATOM 990 O ILE A 59 -10.708 27.683 -24.157 1.00 68.49 O ATOM 991 CB ILE A 59 -12.596 25.443 -24.172 1.00 71.23 C ATOM 992 CG1 ILE A 59 -14.102 25.120 -24.045 1.00 73.27 C ATOM 993 CG2 ILE A 59 -11.801 24.169 -24.530 1.00 74.23 C ATOM 994 CD1 ILE A 59 -14.711 24.494 -25.305 1.00 77.18 C ATOM 995 H ILE A 59 -13.074 27.929 -22.975 1.00 70.55 H ATOM 996 HA ILE A 59 -11.794 25.346 -22.149 1.00 70.70 H ATOM 997 HB ILE A 59 -12.503 26.127 -25.018 1.00 71.23 H ATOM 998 HG13 ILE A 59 -14.653 26.038 -23.851 1.00 73.27 H ATOM 999 HG12 ILE A 59 -14.273 24.465 -23.190 1.00 73.27 H ATOM 1000 HG21 ILE A 59 -12.103 23.756 -25.492 1.00 74.23 H ATOM 1001 HG22 ILE A 59 -10.736 24.368 -24.598 1.00 74.23 H ATOM 1002 HG23 ILE A 59 -11.938 23.392 -23.777 1.00 74.23 H ATOM 1003 HD11 ILE A 59 -15.798 24.589 -25.306 1.00 77.18 H ATOM 1004 HD12 ILE A 59 -14.330 24.970 -26.208 1.00 77.18 H ATOM 1005 HD13 ILE A 59 -14.469 23.435 -25.372 1.00 77.18 H ATOM 1006 N SER A 60 -9.588 26.473 -22.610 1.00 68.87 N ATOM 1007 CA SER A 60 -8.235 26.904 -22.979 1.00 67.43 C ATOM 1008 C SER A 60 -7.661 26.010 -24.099 1.00 68.18 C ATOM 1009 O SER A 60 -8.281 25.012 -24.462 1.00 68.28 O ATOM 1010 CB SER A 60 -7.367 26.912 -21.703 1.00 66.40 C ATOM 1011 OG SER A 60 -7.133 25.606 -21.218 1.00 64.01 O ATOM 1012 H SER A 60 -9.640 25.785 -21.873 1.00 68.87 H ATOM 1013 HA SER A 60 -8.276 27.927 -23.357 1.00 67.43 H ATOM 1014 HB3 SER A 60 -7.842 27.502 -20.918 1.00 66.40 H ATOM 1015 HB2 SER A 60 -6.402 27.379 -21.902 1.00 66.40 H ATOM 1016 HG SER A 60 -6.502 25.648 -20.494 1.00 64.01 H ATOM 1017 N MET A 61 -6.472 26.361 -24.619 1.00 67.44 N ATOM 1018 CA MET A 61 -5.741 25.531 -25.588 1.00 68.17 C ATOM 1019 C MET A 61 -5.304 24.174 -24.989 1.00 66.44 C ATOM 1020 O MET A 61 -5.338 23.167 -25.697 1.00 67.20 O ATOM 1021 CB MET A 61 -4.572 26.356 -26.177 1.00 68.84 C ATOM 1022 CG MET A 61 -3.884 25.742 -27.413 1.00 71.36 C ATOM 1023 SD MET A 61 -2.557 24.544 -27.107 1.00 78.92 S ATOM 1024 CE MET A 61 -1.195 25.666 -26.701 1.00 67.97 C ATOM 1025 H MET A 61 -6.004 27.196 -24.298 1.00 67.44 H ATOM 1026 HA MET A 61 -6.432 25.315 -26.406 1.00 68.17 H ATOM 1027 HB3 MET A 61 -3.829 26.538 -25.399 1.00 68.84 H ATOM 1028 HB2 MET A 61 -4.943 27.342 -26.460 1.00 68.84 H ATOM 1029 HG3 MET A 61 -3.462 26.541 -28.023 1.00 71.36 H ATOM 1030 HG2 MET A 61 -4.629 25.263 -28.045 1.00 71.36 H ATOM 1031 HE1 MET A 61 -0.281 25.098 -26.523 1.00 67.97 H ATOM 1032 HE2 MET A 61 -1.014 26.356 -27.525 1.00 67.97 H ATOM 1033 HE3 MET A 61 -1.424 26.242 -25.805 1.00 67.97 H ATOM 1034 N SER A 62 -4.966 24.169 -23.686 1.00 64.87 N ATOM 1035 CA SER A 62 -4.649 22.975 -22.900 1.00 64.65 C ATOM 1036 C SER A 62 -5.873 22.105 -22.569 1.00 62.96 C ATOM 1037 O SER A 62 -5.749 20.883 -22.624 1.00 63.59 O ATOM 1038 CB SER A 62 -3.820 23.374 -21.659 1.00 65.72 C ATOM 1039 OG SER A 62 -4.573 24.076 -20.690 1.00 70.00 O ATOM 1040 H SER A 62 -4.984 25.035 -23.166 1.00 64.87 H ATOM 1041 HA SER A 62 -4.016 22.347 -23.522 1.00 64.65 H ATOM 1042 HB3 SER A 62 -2.968 23.989 -21.949 1.00 65.72 H ATOM 1043 HB2 SER A 62 -3.412 22.480 -21.186 1.00 65.72 H ATOM 1044 HG SER A 62 -3.997 24.283 -19.949 1.00 70.00 H ATOM 1045 N ALA A 63 -7.029 22.732 -22.283 1.00 61.15 N ATOM 1046 CA ALA A 63 -8.304 22.046 -22.065 1.00 59.25 C ATOM 1047 C ALA A 63 -8.856 21.418 -23.354 1.00 57.20 C ATOM 1048 O ALA A 63 -9.366 20.302 -23.299 1.00 55.09 O ATOM 1049 CB ALA A 63 -9.328 23.025 -21.473 1.00 58.63 C ATOM 1050 H ALA A 63 -7.047 23.742 -22.224 1.00 61.15 H ATOM 1051 HA ALA A 63 -8.138 21.249 -21.337 1.00 59.25 H ATOM 1052 HB1 ALA A 63 -10.241 22.508 -21.177 1.00 58.63 H ATOM 1053 HB2 ALA A 63 -8.932 23.525 -20.589 1.00 58.63 H ATOM 1054 HB3 ALA A 63 -9.604 23.794 -22.192 1.00 58.63 H ATOM 1055 N CYS A 64 -8.712 22.133 -24.485 0.50 56.46 N ATOM 1056 CA CYS A 64 -9.133 21.708 -25.819 0.50 55.68 C ATOM 1057 C CYS A 64 -8.373 20.453 -26.286 0.50 55.63 C ATOM 1058 O CYS A 64 -9.021 19.481 -26.666 0.50 55.82 O ATOM 1059 CB CYS A 64 -9.039 22.861 -26.842 0.50 55.01 C ATOM 1060 SG CYS A 64 -9.742 22.406 -28.453 0.50 52.99 S ATOM 1061 H CYS A 64 -8.289 23.051 -24.431 0.50 56.46 H ATOM 1062 HA CYS A 64 -10.188 21.436 -25.737 0.50 55.68 H ATOM 1063 HB3 CYS A 64 -8.004 23.176 -26.975 0.50 55.01 H ATOM 1064 HB2 CYS A 64 -9.585 23.734 -26.487 0.50 55.01 H ATOM 1065 HG CYS A 64 -9.493 23.571 -29.058 0.50 52.99 H ATOM 1066 N ARG A 65 -7.030 20.480 -26.200 1.00 56.08 N ATOM 1067 CA ARG A 65 -6.163 19.346 -26.533 1.00 57.07 C ATOM 1068 C ARG A 65 -6.274 18.164 -25.555 1.00 55.68 C ATOM 1069 O ARG A 65 -6.112 17.030 -26.007 1.00 53.46 O ATOM 1070 CB ARG A 65 -4.700 19.809 -26.657 1.00 57.66 C ATOM 1071 CG ARG A 65 -4.429 20.530 -27.990 1.00 60.28 C ATOM 1072 CD ARG A 65 -2.964 20.943 -28.214 1.00 61.86 C ATOM 1073 NE ARG A 65 -2.051 19.788 -28.306 1.00 64.64 N ATOM 1074 CZ ARG A 65 -1.596 19.126 -29.385 1.00 68.11 C ATOM 1075 NH1 ARG A 65 -1.931 19.467 -30.636 1.00 69.99 N ATOM 1076 NH2 ARG A 65 -0.781 18.081 -29.197 1.00 69.14 N1+ ATOM 1077 H ARG A 65 -6.565 21.318 -25.877 1.00 56.08 H ATOM 1078 HA ARG A 65 -6.477 18.962 -27.506 1.00 57.07 H ATOM 1079 HB3 ARG A 65 -4.049 18.935 -26.611 1.00 57.66 H ATOM 1080 HB2 ARG A 65 -4.421 20.434 -25.808 1.00 57.66 H ATOM 1081 HG3 ARG A 65 -5.092 21.381 -28.147 1.00 60.28 H ATOM 1082 HG2 ARG A 65 -4.691 19.811 -28.767 1.00 60.28 H ATOM 1083 HD3 ARG A 65 -2.627 21.471 -27.322 1.00 61.86 H ATOM 1084 HD2 ARG A 65 -2.860 21.654 -29.033 1.00 61.86 H ATOM 1085 HE ARG A 65 -1.753 19.441 -27.402 1.00 64.64 H ATOM 1086 HH12 ARG A 65 -1.563 18.961 -31.428 1.00 69.99 H ATOM 1087 HH11 ARG A 65 -2.622 20.191 -30.788 1.00 69.99 H ATOM 1088 HH22 ARG A 65 -0.406 17.573 -29.985 1.00 69.14 H ATOM 1089 HH21 ARG A 65 -0.508 17.813 -28.262 1.00 69.14 H ATOM 1090 N GLU A 66 -6.568 18.423 -24.267 1.00 56.21 N ATOM 1091 CA GLU A 66 -6.831 17.374 -23.280 1.00 55.67 C ATOM 1092 C GLU A 66 -8.106 16.583 -23.598 1.00 54.39 C ATOM 1093 O GLU A 66 -8.042 15.359 -23.690 1.00 54.06 O ATOM 1094 CB GLU A 66 -6.800 17.934 -21.839 1.00 56.14 C ATOM 1095 CG GLU A 66 -7.223 16.899 -20.768 1.00 60.24 C ATOM 1096 CD GLU A 66 -6.937 17.261 -19.306 1.00 65.32 C ATOM 1097 OE1 GLU A 66 -6.610 18.432 -19.011 1.00 69.39 O ATOM 1098 OE2 GLU A 66 -7.059 16.328 -18.481 1.00 65.01 O1- ATOM 1099 H GLU A 66 -6.667 19.377 -23.949 1.00 56.21 H ATOM 1100 HA GLU A 66 -6.013 16.659 -23.358 1.00 55.67 H ATOM 1101 HB3 GLU A 66 -7.439 18.815 -21.769 1.00 56.14 H ATOM 1102 HB2 GLU A 66 -5.786 18.277 -21.630 1.00 56.14 H ATOM 1103 HG3 GLU A 66 -6.731 15.952 -20.982 1.00 60.24 H ATOM 1104 HG2 GLU A 66 -8.294 16.712 -20.845 1.00 60.24 H ATOM 1105 N ILE A 67 -9.217 17.311 -23.797 1.00 53.50 N ATOM 1106 CA ILE A 67 -10.517 16.768 -24.187 1.00 53.29 C ATOM 1107 C ILE A 67 -10.463 16.042 -25.547 1.00 52.39 C ATOM 1108 O ILE A 67 -11.041 14.964 -25.657 1.00 51.69 O ATOM 1109 CB ILE A 67 -11.607 17.884 -24.220 1.00 53.74 C ATOM 1110 CG1 ILE A 67 -11.891 18.426 -22.799 1.00 53.27 C ATOM 1111 CG2 ILE A 67 -12.946 17.470 -24.866 1.00 53.91 C ATOM 1112 CD1 ILE A 67 -12.586 19.799 -22.791 1.00 47.24 C ATOM 1113 H ILE A 67 -9.173 18.318 -23.698 1.00 53.50 H ATOM 1114 HA ILE A 67 -10.802 16.032 -23.433 1.00 53.29 H ATOM 1115 HB ILE A 67 -11.205 18.706 -24.814 1.00 53.74 H ATOM 1116 HG13 ILE A 67 -10.969 18.508 -22.225 1.00 53.27 H ATOM 1117 HG12 ILE A 67 -12.502 17.707 -22.253 1.00 53.27 H ATOM 1118 HG21 ILE A 67 -13.684 18.271 -24.814 1.00 53.91 H ATOM 1119 HG22 ILE A 67 -12.849 17.213 -25.920 1.00 53.91 H ATOM 1120 HG23 ILE A 67 -13.360 16.608 -24.344 1.00 53.91 H ATOM 1121 HD11 ILE A 67 -12.080 20.482 -22.107 1.00 47.24 H ATOM 1122 HD12 ILE A 67 -12.583 20.271 -23.773 1.00 47.24 H ATOM 1123 HD13 ILE A 67 -13.624 19.710 -22.470 1.00 47.24 H ATOM 1124 N ALA A 68 -9.734 16.614 -26.524 1.00 51.35 N ATOM 1125 CA ALA A 68 -9.535 16.054 -27.861 1.00 50.62 C ATOM 1126 C ALA A 68 -8.848 14.681 -27.852 1.00 50.08 C ATOM 1127 O ALA A 68 -9.385 13.748 -28.442 1.00 48.53 O ATOM 1128 CB ALA A 68 -8.740 17.037 -28.735 1.00 50.29 C ATOM 1129 H ALA A 68 -9.294 17.509 -26.352 1.00 51.35 H ATOM 1130 HA ALA A 68 -10.525 15.934 -28.303 1.00 50.62 H ATOM 1131 HB1 ALA A 68 -8.635 16.665 -29.753 1.00 50.29 H ATOM 1132 HB2 ALA A 68 -9.234 18.003 -28.803 1.00 50.29 H ATOM 1133 HB3 ALA A 68 -7.738 17.205 -28.342 1.00 50.29 H ATOM 1134 N LEU A 69 -7.685 14.579 -27.188 1.00 49.60 N ATOM 1135 CA LEU A 69 -6.869 13.364 -27.184 1.00 51.20 C ATOM 1136 C LEU A 69 -7.416 12.264 -26.260 1.00 51.55 C ATOM 1137 O LEU A 69 -7.372 11.101 -26.660 1.00 50.96 O ATOM 1138 CB LEU A 69 -5.402 13.722 -26.871 1.00 51.65 C ATOM 1139 CG LEU A 69 -4.687 14.444 -28.035 1.00 54.33 C ATOM 1140 CD1 LEU A 69 -3.355 15.063 -27.581 1.00 52.59 C ATOM 1141 CD2 LEU A 69 -4.478 13.508 -29.244 1.00 54.25 C ATOM 1142 H LEU A 69 -7.301 15.384 -26.711 1.00 49.60 H ATOM 1143 HA LEU A 69 -6.907 12.944 -28.191 1.00 51.20 H ATOM 1144 HB3 LEU A 69 -4.836 12.823 -26.624 1.00 51.65 H ATOM 1145 HB2 LEU A 69 -5.376 14.345 -25.976 1.00 51.65 H ATOM 1146 HG LEU A 69 -5.317 15.271 -28.365 1.00 54.33 H ATOM 1147 HD11 LEU A 69 -2.692 15.268 -28.422 1.00 52.59 H ATOM 1148 HD12 LEU A 69 -3.524 16.011 -27.069 1.00 52.59 H ATOM 1149 HD13 LEU A 69 -2.823 14.399 -26.900 1.00 52.59 H ATOM 1150 HD21 LEU A 69 -3.425 13.396 -29.493 1.00 54.25 H ATOM 1151 HD22 LEU A 69 -4.853 12.500 -29.062 1.00 54.25 H ATOM 1152 HD23 LEU A 69 -4.988 13.889 -30.129 1.00 54.25 H ATOM 1153 N LEU A 70 -7.975 12.624 -25.089 1.00 53.45 N ATOM 1154 CA LEU A 70 -8.640 11.676 -24.182 1.00 53.84 C ATOM 1155 C LEU A 70 -9.914 11.043 -24.772 1.00 54.62 C ATOM 1156 O LEU A 70 -10.269 9.942 -24.358 1.00 54.54 O ATOM 1157 CB LEU A 70 -8.990 12.361 -22.845 1.00 53.36 C ATOM 1158 CG LEU A 70 -7.805 12.578 -21.886 1.00 55.09 C ATOM 1159 CD1 LEU A 70 -8.243 13.455 -20.704 1.00 51.81 C ATOM 1160 CD2 LEU A 70 -7.196 11.250 -21.387 1.00 54.34 C ATOM 1161 H LEU A 70 -7.989 13.597 -24.811 1.00 53.45 H ATOM 1162 HA LEU A 70 -7.945 10.856 -23.993 1.00 53.84 H ATOM 1163 HB3 LEU A 70 -9.721 11.758 -22.311 1.00 53.36 H ATOM 1164 HB2 LEU A 70 -9.497 13.305 -23.051 1.00 53.36 H ATOM 1165 HG LEU A 70 -7.034 13.128 -22.425 1.00 55.09 H ATOM 1166 HD11 LEU A 70 -7.385 13.801 -20.129 1.00 51.81 H ATOM 1167 HD12 LEU A 70 -8.794 14.334 -21.039 1.00 51.81 H ATOM 1168 HD13 LEU A 70 -8.897 12.903 -20.030 1.00 51.81 H ATOM 1169 HD21 LEU A 70 -7.053 11.245 -20.306 1.00 54.34 H ATOM 1170 HD22 LEU A 70 -7.826 10.393 -21.626 1.00 54.34 H ATOM 1171 HD23 LEU A 70 -6.222 11.070 -21.841 1.00 54.34 H ATOM 1172 N ARG A 71 -10.568 11.724 -25.728 1.00 54.95 N ATOM 1173 CA ARG A 71 -11.746 11.219 -26.432 1.00 53.79 C ATOM 1174 C ARG A 71 -11.428 10.091 -27.438 1.00 52.54 C ATOM 1175 O ARG A 71 -12.347 9.363 -27.815 1.00 54.07 O ATOM 1176 CB ARG A 71 -12.461 12.419 -27.093 1.00 54.33 C ATOM 1177 CG ARG A 71 -13.856 12.155 -27.677 1.00 55.95 C ATOM 1178 CD ARG A 71 -14.890 11.840 -26.583 1.00 57.44 C ATOM 1179 NE ARG A 71 -16.195 11.451 -27.124 1.00 54.94 N ATOM 1180 CZ ARG A 71 -16.550 10.264 -27.641 1.00 57.54 C ATOM 1181 NH1 ARG A 71 -15.686 9.249 -27.796 1.00 61.21 N ATOM 1182 NH2 ARG A 71 -17.821 10.099 -28.012 1.00 59.42 N1+ ATOM 1183 H ARG A 71 -10.233 12.635 -26.011 1.00 54.95 H ATOM 1184 HA ARG A 71 -12.401 10.791 -25.673 1.00 53.79 H ATOM 1185 HB3 ARG A 71 -11.821 12.838 -27.868 1.00 54.33 H ATOM 1186 HB2 ARG A 71 -12.586 13.201 -26.347 1.00 54.33 H ATOM 1187 HG3 ARG A 71 -13.858 11.433 -28.494 1.00 55.95 H ATOM 1188 HG2 ARG A 71 -14.150 13.098 -28.138 1.00 55.95 H ATOM 1189 HD3 ARG A 71 -15.108 12.774 -26.064 1.00 57.44 H ATOM 1190 HD2 ARG A 71 -14.538 11.153 -25.815 1.00 57.44 H ATOM 1191 HE ARG A 71 -16.891 12.189 -27.126 1.00 54.94 H ATOM 1192 HH12 ARG A 71 -15.994 8.368 -28.179 1.00 61.21 H ATOM 1193 HH11 ARG A 71 -14.713 9.367 -27.542 1.00 61.21 H ATOM 1194 HH22 ARG A 71 -18.128 9.239 -28.450 1.00 59.42 H ATOM 1195 HH21 ARG A 71 -18.504 10.830 -27.856 1.00 59.42 H ATOM 1196 N GLU A 72 -10.148 9.961 -27.835 1.00 51.56 N ATOM 1197 CA GLU A 72 -9.667 9.001 -28.829 1.00 50.86 C ATOM 1198 C GLU A 72 -8.844 7.854 -28.223 1.00 50.64 C ATOM 1199 O GLU A 72 -8.932 6.737 -28.732 1.00 49.56 O ATOM 1200 CB GLU A 72 -8.804 9.743 -29.872 1.00 49.03 C ATOM 1201 CG GLU A 72 -9.481 10.931 -30.585 1.00 51.13 C ATOM 1202 CD GLU A 72 -10.824 10.624 -31.257 1.00 51.32 C ATOM 1203 OE1 GLU A 72 -10.965 9.534 -31.851 1.00 51.13 O ATOM 1204 OE2 GLU A 72 -11.700 11.511 -31.204 1.00 54.43 O1- ATOM 1205 H GLU A 72 -9.454 10.595 -27.464 1.00 51.56 H ATOM 1206 HA GLU A 72 -10.515 8.537 -29.337 1.00 50.86 H ATOM 1207 HB3 GLU A 72 -8.465 9.031 -30.619 1.00 49.03 H ATOM 1208 HB2 GLU A 72 -7.895 10.111 -29.394 1.00 49.03 H ATOM 1209 HG3 GLU A 72 -8.808 11.308 -31.353 1.00 51.13 H ATOM 1210 HG2 GLU A 72 -9.612 11.743 -29.874 1.00 51.13 H ATOM 1211 N LEU A 73 -8.046 8.143 -27.179 1.00 49.58 N ATOM 1212 CA LEU A 73 -7.163 7.175 -26.524 1.00 50.99 C ATOM 1213 C LEU A 73 -7.970 6.137 -25.725 1.00 50.99 C ATOM 1214 O LEU A 73 -8.836 6.515 -24.935 1.00 50.29 O ATOM 1215 CB LEU A 73 -6.165 7.917 -25.605 1.00 48.65 C ATOM 1216 CG LEU A 73 -5.099 8.776 -26.331 1.00 49.93 C ATOM 1217 CD1 LEU A 73 -4.430 9.766 -25.358 1.00 46.84 C ATOM 1218 CD2 LEU A 73 -4.040 7.929 -27.059 1.00 45.64 C ATOM 1219 H LEU A 73 -8.013 9.089 -26.822 1.00 49.58 H ATOM 1220 HA LEU A 73 -6.609 6.648 -27.302 1.00 50.99 H ATOM 1221 HB3 LEU A 73 -5.650 7.205 -24.958 1.00 48.65 H ATOM 1222 HB2 LEU A 73 -6.739 8.558 -24.933 1.00 48.65 H ATOM 1223 HG LEU A 73 -5.595 9.364 -27.102 1.00 49.93 H ATOM 1224 HD11 LEU A 73 -3.348 9.795 -25.483 1.00 46.84 H ATOM 1225 HD12 LEU A 73 -4.794 10.779 -25.521 1.00 46.84 H ATOM 1226 HD13 LEU A 73 -4.628 9.516 -24.315 1.00 46.84 H ATOM 1227 HD21 LEU A 73 -3.386 8.556 -27.664 1.00 45.64 H ATOM 1228 HD22 LEU A 73 -3.413 7.385 -26.355 1.00 45.64 H ATOM 1229 HD23 LEU A 73 -4.489 7.199 -27.729 1.00 45.64 H ATOM 1230 N LYS A 74 -7.654 4.851 -25.941 1.00 52.18 N ATOM 1231 CA LYS A 74 -8.288 3.715 -25.279 1.00 53.28 C ATOM 1232 C LYS A 74 -7.272 2.570 -25.180 1.00 52.15 C ATOM 1233 O LYS A 74 -6.980 1.925 -26.188 1.00 53.17 O ATOM 1234 CB LYS A 74 -9.586 3.323 -26.023 1.00 53.76 C ATOM 1235 CG LYS A 74 -10.345 2.148 -25.377 0.00 53.29 C ATOM 1236 CD LYS A 74 -11.669 1.835 -26.088 0.00 53.33 C ATOM 1237 CE LYS A 74 -12.413 0.659 -25.435 0.00 53.36 C ATOM 1238 NZ LYS A 74 -13.677 0.357 -26.130 0.00 53.36 N1+ ATOM 1239 H LYS A 74 -6.940 4.620 -26.621 1.00 52.18 H ATOM 1240 HA LYS A 74 -8.563 4.008 -24.264 1.00 53.28 H ATOM 1241 HB3 LYS A 74 -9.357 3.080 -27.062 1.00 53.76 H ATOM 1242 HB2 LYS A 74 -10.249 4.189 -26.056 1.00 53.76 H ATOM 1243 HG3 LYS A 74 -10.541 2.379 -24.329 1.00 53.29 H ATOM 1244 HG2 LYS A 74 -9.723 1.253 -25.383 1.00 53.29 H ATOM 1245 HD3 LYS A 74 -11.466 1.612 -27.137 1.00 53.33 H ATOM 1246 HD2 LYS A 74 -12.300 2.725 -26.079 1.00 53.33 H ATOM 1247 HE3 LYS A 74 -12.634 0.884 -24.391 1.00 53.36 H ATOM 1248 HE2 LYS A 74 -11.789 -0.236 -25.445 1.00 53.36 H ATOM 1249 HZ1 LYS A 74 -13.484 0.117 -27.092 1.00 53.36 H ATOM 1250 HZ2 LYS A 74 -14.136 -0.419 -25.676 1.00 53.36 H ATOM 1251 HZ3 LYS A 74 -14.280 1.167 -26.101 1.00 53.36 H ATOM 1252 N HIS A 75 -6.763 2.343 -23.960 1.00 50.74 N ATOM 1253 CA HIS A 75 -5.792 1.299 -23.631 1.00 49.66 C ATOM 1254 C HIS A 75 -5.870 1.026 -22.115 1.00 50.96 C ATOM 1255 O HIS A 75 -5.995 1.996 -21.367 1.00 50.45 O ATOM 1256 CB HIS A 75 -4.387 1.780 -24.047 1.00 49.60 C ATOM 1257 CG HIS A 75 -3.275 0.783 -23.841 1.00 50.03 C ATOM 1258 ND1 HIS A 75 -2.534 0.717 -22.656 1.00 44.97 N ATOM 1259 CD2 HIS A 75 -2.817 -0.189 -24.707 1.00 48.58 C ATOM 1260 CE1 HIS A 75 -1.681 -0.280 -22.844 1.00 47.72 C ATOM 1261 NE2 HIS A 75 -1.799 -0.849 -24.043 1.00 45.39 N ATOM 1262 H HIS A 75 -7.046 2.932 -23.188 1.00 50.74 H ATOM 1263 HA HIS A 75 -6.048 0.420 -24.218 1.00 49.66 H ATOM 1264 HB3 HIS A 75 -4.128 2.706 -23.531 1.00 49.60 H ATOM 1265 HB2 HIS A 75 -4.405 2.014 -25.109 1.00 49.60 H ATOM 1266 HD2 HIS A 75 -3.122 -0.453 -25.708 1.00 48.58 H ATOM 1267 HE1 HIS A 75 -0.959 -0.596 -22.107 1.00 47.72 H ATOM 1268 HE2 HIS A 75 -1.237 -1.615 -24.392 1.00 45.39 H ATOM 1269 N PRO A 76 -5.774 -0.256 -21.673 1.00 52.16 N ATOM 1270 CA PRO A 76 -5.793 -0.627 -20.239 1.00 52.31 C ATOM 1271 C PRO A 76 -4.823 0.099 -19.286 1.00 50.81 C ATOM 1272 O PRO A 76 -5.149 0.201 -18.105 1.00 51.24 O ATOM 1273 CB PRO A 76 -5.507 -2.137 -20.238 1.00 52.41 C ATOM 1274 CG PRO A 76 -6.030 -2.618 -21.575 1.00 54.45 C ATOM 1275 CD PRO A 76 -5.706 -1.460 -22.509 1.00 54.15 C ATOM 1276 HA PRO A 76 -6.813 -0.457 -19.888 1.00 52.31 H ATOM 1277 HB3 PRO A 76 -5.975 -2.656 -19.401 1.00 52.41 H ATOM 1278 HB2 PRO A 76 -4.433 -2.326 -20.185 1.00 52.41 H ATOM 1279 HG3 PRO A 76 -7.112 -2.745 -21.514 1.00 54.45 H ATOM 1280 HG2 PRO A 76 -5.598 -3.567 -21.895 1.00 54.45 H ATOM 1281 HD2 PRO A 76 -4.696 -1.562 -22.905 1.00 54.15 H ATOM 1282 HD3 PRO A 76 -6.411 -1.463 -23.340 1.00 54.15 H ATOM 1283 N ASN A 77 -3.673 0.579 -19.791 1.00 50.01 N ATOM 1284 CA ASN A 77 -2.641 1.249 -18.989 1.00 49.63 C ATOM 1285 C ASN A 77 -2.542 2.758 -19.261 1.00 48.16 C ATOM 1286 O ASN A 77 -1.540 3.367 -18.889 1.00 49.79 O ATOM 1287 CB ASN A 77 -1.279 0.527 -19.103 1.00 47.52 C ATOM 1288 CG ASN A 77 -1.329 -0.957 -18.723 1.00 49.37 C ATOM 1289 OD1 ASN A 77 -0.892 -1.814 -19.487 1.00 54.26 O ATOM 1290 ND2 ASN A 77 -1.849 -1.267 -17.532 1.00 45.70 N ATOM 1291 H ASN A 77 -3.465 0.469 -20.775 1.00 50.01 H ATOM 1292 HA ASN A 77 -2.924 1.229 -17.944 1.00 49.63 H ATOM 1293 HB3 ASN A 77 -0.555 0.998 -18.437 1.00 47.52 H ATOM 1294 HB2 ASN A 77 -0.879 0.627 -20.112 1.00 47.52 H ATOM 1295 HD22 ASN A 77 -1.876 -2.227 -17.223 1.00 45.70 H ATOM 1296 HD21 ASN A 77 -2.203 -0.541 -16.923 1.00 45.70 H ATOM 1297 N VAL A 78 -3.607 3.350 -19.819 1.00 47.32 N ATOM 1298 CA VAL A 78 -3.831 4.793 -19.876 1.00 47.64 C ATOM 1299 C VAL A 78 -5.220 5.053 -19.262 1.00 48.18 C ATOM 1300 O VAL A 78 -6.144 4.278 -19.513 1.00 48.75 O ATOM 1301 CB VAL A 78 -3.795 5.319 -21.342 1.00 47.71 C ATOM 1302 CG1 VAL A 78 -4.160 6.813 -21.487 1.00 45.11 C ATOM 1303 CG2 VAL A 78 -2.418 5.070 -21.990 1.00 45.55 C ATOM 1304 H VAL A 78 -4.393 2.782 -20.104 1.00 47.32 H ATOM 1305 HA VAL A 78 -3.085 5.326 -19.283 1.00 47.64 H ATOM 1306 HB VAL A 78 -4.524 4.755 -21.926 1.00 47.71 H ATOM 1307 HG11 VAL A 78 -4.032 7.150 -22.516 1.00 45.11 H ATOM 1308 HG12 VAL A 78 -5.199 7.011 -21.223 1.00 45.11 H ATOM 1309 HG13 VAL A 78 -3.528 7.438 -20.855 1.00 45.11 H ATOM 1310 HG21 VAL A 78 -2.384 5.459 -23.008 1.00 45.55 H ATOM 1311 HG22 VAL A 78 -1.620 5.552 -21.425 1.00 45.55 H ATOM 1312 HG23 VAL A 78 -2.187 4.006 -22.051 1.00 45.55 H ATOM 1313 N ILE A 79 -5.348 6.120 -18.453 1.00 48.52 N ATOM 1314 CA ILE A 79 -6.588 6.475 -17.754 1.00 49.37 C ATOM 1315 C ILE A 79 -7.727 6.850 -18.735 1.00 50.31 C ATOM 1316 O ILE A 79 -7.484 7.571 -19.705 1.00 51.56 O ATOM 1317 CB ILE A 79 -6.340 7.623 -16.731 1.00 49.17 C ATOM 1318 CG1 ILE A 79 -7.477 7.792 -15.700 1.00 54.38 C ATOM 1319 CG2 ILE A 79 -6.038 8.992 -17.380 1.00 48.64 C ATOM 1320 CD1 ILE A 79 -7.726 6.583 -14.787 1.00 56.54 C ATOM 1321 H ILE A 79 -4.552 6.724 -18.289 1.00 48.52 H ATOM 1322 HA ILE A 79 -6.892 5.581 -17.208 1.00 49.37 H ATOM 1323 HB ILE A 79 -5.447 7.349 -16.167 1.00 49.17 H ATOM 1324 HG13 ILE A 79 -8.406 8.068 -16.197 1.00 54.38 H ATOM 1325 HG12 ILE A 79 -7.219 8.631 -15.059 1.00 54.38 H ATOM 1326 HG21 ILE A 79 -5.722 9.718 -16.631 1.00 48.64 H ATOM 1327 HG22 ILE A 79 -5.240 8.916 -18.119 1.00 48.64 H ATOM 1328 HG23 ILE A 79 -6.912 9.416 -17.875 1.00 48.64 H ATOM 1329 HD11 ILE A 79 -8.418 6.850 -13.989 1.00 56.54 H ATOM 1330 HD12 ILE A 79 -8.165 5.745 -15.327 1.00 56.54 H ATOM 1331 HD13 ILE A 79 -6.805 6.246 -14.313 1.00 56.54 H ATOM 1332 N SER A 80 -8.930 6.307 -18.485 1.00 52.47 N ATOM 1333 CA SER A 80 -10.078 6.398 -19.388 1.00 53.87 C ATOM 1334 C SER A 80 -11.025 7.534 -18.979 1.00 53.97 C ATOM 1335 O SER A 80 -11.570 7.499 -17.874 1.00 56.65 O ATOM 1336 CB SER A 80 -10.795 5.033 -19.422 1.00 54.32 C ATOM 1337 OG SER A 80 -11.904 5.033 -20.300 1.00 61.62 O ATOM 1338 H SER A 80 -9.062 5.739 -17.661 1.00 52.47 H ATOM 1339 HA SER A 80 -9.722 6.585 -20.401 1.00 53.87 H ATOM 1340 HB3 SER A 80 -11.138 4.747 -18.426 1.00 54.32 H ATOM 1341 HB2 SER A 80 -10.106 4.260 -19.756 1.00 54.32 H ATOM 1342 HG SER A 80 -12.665 5.389 -19.829 1.00 61.62 H ATOM 1343 N LEU A 81 -11.233 8.489 -19.902 1.00 53.54 N ATOM 1344 CA LEU A 81 -12.242 9.545 -19.802 1.00 53.18 C ATOM 1345 C LEU A 81 -13.642 8.947 -20.023 1.00 54.31 C ATOM 1346 O LEU A 81 -13.923 8.445 -21.112 1.00 55.19 O ATOM 1347 CB LEU A 81 -11.907 10.661 -20.821 1.00 52.21 C ATOM 1348 CG LEU A 81 -12.896 11.854 -20.875 1.00 50.68 C ATOM 1349 CD1 LEU A 81 -12.958 12.623 -19.541 1.00 45.57 C ATOM 1350 CD2 LEU A 81 -12.592 12.788 -22.065 1.00 49.06 C ATOM 1351 H LEU A 81 -10.738 8.432 -20.783 1.00 53.54 H ATOM 1352 HA LEU A 81 -12.189 9.968 -18.798 1.00 53.18 H ATOM 1353 HB3 LEU A 81 -11.835 10.214 -21.814 1.00 52.21 H ATOM 1354 HB2 LEU A 81 -10.913 11.042 -20.590 1.00 52.21 H ATOM 1355 HG LEU A 81 -13.894 11.458 -21.067 1.00 50.68 H ATOM 1356 HD11 LEU A 81 -12.951 13.703 -19.685 1.00 45.57 H ATOM 1357 HD12 LEU A 81 -13.873 12.381 -19.004 1.00 45.57 H ATOM 1358 HD13 LEU A 81 -12.124 12.377 -18.884 1.00 45.57 H ATOM 1359 HD21 LEU A 81 -13.513 13.107 -22.552 1.00 49.06 H ATOM 1360 HD22 LEU A 81 -12.054 13.687 -21.761 1.00 49.06 H ATOM 1361 HD23 LEU A 81 -11.989 12.298 -22.828 1.00 49.06 H ATOM 1362 N GLN A 82 -14.477 9.009 -18.977 1.00 55.12 N ATOM 1363 CA GLN A 82 -15.826 8.447 -18.959 1.00 55.85 C ATOM 1364 C GLN A 82 -16.883 9.420 -19.505 1.00 55.64 C ATOM 1365 O GLN A 82 -17.801 8.968 -20.189 1.00 56.53 O ATOM 1366 CB GLN A 82 -16.183 8.025 -17.514 1.00 57.01 C ATOM 1367 CG GLN A 82 -15.287 6.934 -16.890 1.00 59.93 C ATOM 1368 CD GLN A 82 -15.192 5.660 -17.732 1.00 67.99 C ATOM 1369 OE1 GLN A 82 -14.196 5.437 -18.417 1.00 76.71 O ATOM 1370 NE2 GLN A 82 -16.234 4.829 -17.697 1.00 73.45 N ATOM 1371 H GLN A 82 -14.168 9.454 -18.122 1.00 55.12 H ATOM 1372 HA GLN A 82 -15.852 7.565 -19.600 1.00 55.85 H ATOM 1373 HB3 GLN A 82 -17.218 7.678 -17.488 1.00 57.01 H ATOM 1374 HB2 GLN A 82 -16.154 8.900 -16.865 1.00 57.01 H ATOM 1375 HG3 GLN A 82 -15.655 6.682 -15.895 1.00 59.93 H ATOM 1376 HG2 GLN A 82 -14.279 7.321 -16.745 1.00 59.93 H ATOM 1377 HE22 GLN A 82 -16.213 3.972 -18.231 1.00 73.45 H ATOM 1378 HE21 GLN A 82 -17.033 5.032 -17.114 1.00 73.45 H ATOM 1379 N LYS A 83 -16.751 10.721 -19.190 1.00 55.61 N ATOM 1380 CA LYS A 83 -17.731 11.755 -19.528 1.00 54.43 C ATOM 1381 C LYS A 83 -17.122 13.149 -19.319 1.00 53.52 C ATOM 1382 O LYS A 83 -16.254 13.311 -18.463 1.00 52.42 O ATOM 1383 CB LYS A 83 -19.008 11.564 -18.667 1.00 56.11 C ATOM 1384 CG LYS A 83 -20.190 12.472 -19.044 1.00 58.01 C ATOM 1385 CD LYS A 83 -21.484 12.061 -18.323 0.00 57.39 C ATOM 1386 CE LYS A 83 -22.714 12.894 -18.719 0.00 57.51 C ATOM 1387 NZ LYS A 83 -23.158 12.617 -20.098 0.00 57.47 N1+ ATOM 1388 H LYS A 83 -15.958 11.027 -18.643 1.00 55.61 H ATOM 1389 HA LYS A 83 -17.985 11.652 -20.585 1.00 54.43 H ATOM 1390 HB3 LYS A 83 -18.770 11.707 -17.613 1.00 56.11 H ATOM 1391 HB2 LYS A 83 -19.351 10.533 -18.758 1.00 56.11 H ATOM 1392 HG3 LYS A 83 -20.331 12.444 -20.124 1.00 58.01 H ATOM 1393 HG2 LYS A 83 -19.963 13.507 -18.786 1.00 58.01 H ATOM 1394 HD3 LYS A 83 -21.331 12.153 -17.247 1.00 57.39 H ATOM 1395 HD2 LYS A 83 -21.684 11.002 -18.496 1.00 57.39 H ATOM 1396 HE3 LYS A 83 -22.513 13.960 -18.612 1.00 57.51 H ATOM 1397 HE2 LYS A 83 -23.539 12.659 -18.047 1.00 57.51 H ATOM 1398 HZ1 LYS A 83 -24.015 13.126 -20.277 1.00 57.47 H ATOM 1399 HZ2 LYS A 83 -22.447 12.902 -20.757 1.00 57.47 H ATOM 1400 HZ3 LYS A 83 -23.343 11.630 -20.200 1.00 57.47 H ATOM 1401 N VAL A 84 -17.627 14.135 -20.075 1.00 52.25 N ATOM 1402 CA VAL A 84 -17.304 15.551 -19.905 1.00 52.06 C ATOM 1403 C VAL A 84 -18.609 16.311 -19.596 1.00 53.83 C ATOM 1404 O VAL A 84 -19.617 16.074 -20.266 1.00 55.20 O ATOM 1405 CB VAL A 84 -16.688 16.159 -21.200 1.00 52.77 C ATOM 1406 CG1 VAL A 84 -16.287 17.644 -21.050 1.00 46.20 C ATOM 1407 CG2 VAL A 84 -15.488 15.339 -21.715 1.00 54.27 C ATOM 1408 H VAL A 84 -18.346 13.931 -20.753 1.00 52.25 H ATOM 1409 HA VAL A 84 -16.604 15.693 -19.082 1.00 52.06 H ATOM 1410 HB VAL A 84 -17.442 16.118 -21.988 1.00 52.77 H ATOM 1411 HG11 VAL A 84 -15.774 18.009 -21.940 1.00 46.20 H ATOM 1412 HG12 VAL A 84 -17.151 18.291 -20.901 1.00 46.20 H ATOM 1413 HG13 VAL A 84 -15.615 17.788 -20.204 1.00 46.20 H ATOM 1414 HG21 VAL A 84 -14.998 15.831 -22.556 1.00 54.27 H ATOM 1415 HG22 VAL A 84 -14.741 15.184 -20.940 1.00 54.27 H ATOM 1416 HG23 VAL A 84 -15.801 14.355 -22.064 1.00 54.27 H ATOM 1417 N PHE A 85 -18.556 17.224 -18.613 1.00 55.25 N ATOM 1418 CA PHE A 85 -19.634 18.167 -18.305 1.00 55.43 C ATOM 1419 C PHE A 85 -19.157 19.582 -18.661 1.00 55.18 C ATOM 1420 O PHE A 85 -18.027 19.947 -18.328 1.00 54.69 O ATOM 1421 CB PHE A 85 -19.997 18.126 -16.806 1.00 56.33 C ATOM 1422 CG PHE A 85 -20.454 16.789 -16.254 1.00 57.01 C ATOM 1423 CD1 PHE A 85 -21.796 16.386 -16.408 1.00 61.77 C ATOM 1424 CD2 PHE A 85 -19.525 15.888 -15.692 1.00 58.81 C ATOM 1425 CE1 PHE A 85 -22.206 15.149 -15.934 1.00 62.44 C ATOM 1426 CE2 PHE A 85 -19.954 14.651 -15.228 1.00 61.02 C ATOM 1427 CZ PHE A 85 -21.291 14.290 -15.340 1.00 60.11 C ATOM 1428 H PHE A 85 -17.687 17.365 -18.112 1.00 55.25 H ATOM 1429 HA PHE A 85 -20.531 17.936 -18.882 1.00 55.43 H ATOM 1430 HB3 PHE A 85 -20.801 18.840 -16.621 1.00 56.33 H ATOM 1431 HB2 PHE A 85 -19.164 18.482 -16.208 1.00 56.33 H ATOM 1432 HD1 PHE A 85 -22.510 17.045 -16.879 1.00 61.77 H ATOM 1433 HD2 PHE A 85 -18.482 16.160 -15.608 1.00 58.81 H ATOM 1434 HE1 PHE A 85 -23.240 14.857 -16.036 1.00 62.44 H ATOM 1435 HE2 PHE A 85 -19.247 13.968 -14.780 1.00 61.02 H ATOM 1436 HZ PHE A 85 -21.619 13.328 -14.980 1.00 60.11 H ATOM 1437 N LEU A 86 -20.055 20.357 -19.286 1.00 55.79 N ATOM 1438 CA LEU A 86 -19.860 21.766 -19.614 1.00 56.25 C ATOM 1439 C LEU A 86 -20.880 22.571 -18.801 1.00 57.42 C ATOM 1440 O LEU A 86 -22.038 22.675 -19.207 1.00 56.78 O ATOM 1441 CB LEU A 86 -20.055 21.973 -21.137 1.00 56.23 C ATOM 1442 CG LEU A 86 -18.961 21.340 -22.025 1.00 56.77 C ATOM 1443 CD1 LEU A 86 -19.304 21.515 -23.519 1.00 57.90 C ATOM 1444 CD2 LEU A 86 -17.553 21.874 -21.694 1.00 53.18 C ATOM 1445 H LEU A 86 -20.962 19.978 -19.516 1.00 55.79 H ATOM 1446 HA LEU A 86 -18.864 22.107 -19.327 1.00 56.25 H ATOM 1447 HB3 LEU A 86 -20.095 23.041 -21.352 1.00 56.23 H ATOM 1448 HB2 LEU A 86 -21.029 21.576 -21.432 1.00 56.23 H ATOM 1449 HG LEU A 86 -18.958 20.267 -21.831 1.00 56.77 H ATOM 1450 HD11 LEU A 86 -19.176 20.579 -24.065 1.00 57.90 H ATOM 1451 HD12 LEU A 86 -20.336 21.834 -23.665 1.00 57.90 H ATOM 1452 HD13 LEU A 86 -18.678 22.267 -23.998 1.00 57.90 H ATOM 1453 HD21 LEU A 86 -16.946 22.043 -22.582 1.00 53.18 H ATOM 1454 HD22 LEU A 86 -17.598 22.822 -21.157 1.00 53.18 H ATOM 1455 HD23 LEU A 86 -17.011 21.164 -21.068 1.00 53.18 H ATOM 1456 N SER A 87 -20.437 23.106 -17.652 1.00 58.97 N ATOM 1457 CA SER A 87 -21.254 23.936 -16.769 1.00 59.88 C ATOM 1458 C SER A 87 -21.276 25.378 -17.306 1.00 60.74 C ATOM 1459 O SER A 87 -20.294 26.100 -17.143 1.00 59.19 O ATOM 1460 CB SER A 87 -20.715 23.814 -15.329 1.00 60.17 C ATOM 1461 OG SER A 87 -21.502 24.554 -14.420 1.00 60.24 O ATOM 1462 H SER A 87 -19.470 22.988 -17.379 1.00 58.97 H ATOM 1463 HA SER A 87 -22.276 23.549 -16.763 1.00 59.88 H ATOM 1464 HB3 SER A 87 -19.686 24.166 -15.262 1.00 60.17 H ATOM 1465 HB2 SER A 87 -20.713 22.771 -15.011 1.00 60.17 H ATOM 1466 HG SER A 87 -20.997 25.334 -14.159 1.00 60.24 H ATOM 1467 N HIS A 88 -22.377 25.737 -17.987 1.00 62.75 N ATOM 1468 CA HIS A 88 -22.552 26.998 -18.719 1.00 64.90 C ATOM 1469 C HIS A 88 -22.596 28.262 -17.836 1.00 66.86 C ATOM 1470 O HIS A 88 -22.253 29.335 -18.332 1.00 67.75 O ATOM 1471 CB HIS A 88 -23.833 26.918 -19.584 1.00 65.18 C ATOM 1472 CG HIS A 88 -23.773 26.057 -20.828 1.00 67.11 C ATOM 1473 ND1 HIS A 88 -23.292 24.757 -20.855 1.00 66.40 N ATOM 1474 CD2 HIS A 88 -24.154 26.326 -22.126 1.00 66.66 C ATOM 1475 CE1 HIS A 88 -23.400 24.316 -22.112 1.00 67.15 C ATOM 1476 NE2 HIS A 88 -23.919 25.215 -22.937 1.00 66.41 N ATOM 1477 H HIS A 88 -23.136 25.076 -18.067 1.00 62.75 H ATOM 1478 HA HIS A 88 -21.698 27.120 -19.388 1.00 64.90 H ATOM 1479 HB3 HIS A 88 -24.111 27.918 -19.924 1.00 65.18 H ATOM 1480 HB2 HIS A 88 -24.672 26.572 -18.978 1.00 65.18 H ATOM 1481 HD1 HIS A 88 -22.915 24.225 -20.080 1.00 66.40 H ATOM 1482 HD2 HIS A 88 -24.586 27.226 -22.536 1.00 66.66 H ATOM 1483 HE1 HIS A 88 -23.099 23.327 -22.426 1.00 67.15 H ATOM 1484 N ALA A 89 -23.029 28.128 -16.569 1.00 68.30 N ATOM 1485 CA ALA A 89 -23.243 29.240 -15.636 1.00 70.12 C ATOM 1486 C ALA A 89 -21.955 29.953 -15.186 1.00 70.01 C ATOM 1487 O ALA A 89 -21.963 31.178 -15.065 1.00 70.49 O ATOM 1488 CB ALA A 89 -24.023 28.723 -14.418 1.00 69.50 C ATOM 1489 H ALA A 89 -23.278 27.211 -16.228 1.00 68.30 H ATOM 1490 HA ALA A 89 -23.866 29.979 -16.142 1.00 70.12 H ATOM 1491 HB1 ALA A 89 -24.222 29.524 -13.705 1.00 69.50 H ATOM 1492 HB2 ALA A 89 -24.986 28.308 -14.717 1.00 69.50 H ATOM 1493 HB3 ALA A 89 -23.473 27.940 -13.893 1.00 69.50 H ATOM 1494 N ASP A 90 -20.887 29.174 -14.957 1.00 69.77 N ATOM 1495 CA ASP A 90 -19.571 29.629 -14.488 1.00 69.09 C ATOM 1496 C ASP A 90 -18.468 29.401 -15.544 1.00 68.82 C ATOM 1497 O ASP A 90 -17.351 29.882 -15.354 1.00 70.98 O ATOM 1498 CB ASP A 90 -19.174 28.987 -13.125 1.00 69.43 C ATOM 1499 CG ASP A 90 -19.340 27.461 -12.948 1.00 69.09 C ATOM 1500 OD1 ASP A 90 -19.523 26.738 -13.953 1.00 64.68 O ATOM 1501 OD2 ASP A 90 -19.179 27.019 -11.790 1.00 70.90 O1- ATOM 1502 H ASP A 90 -20.978 28.172 -15.061 1.00 69.77 H ATOM 1503 HA ASP A 90 -19.602 30.708 -14.331 1.00 69.09 H ATOM 1504 HB3 ASP A 90 -19.772 29.467 -12.348 1.00 69.43 H ATOM 1505 HB2 ASP A 90 -18.140 29.240 -12.884 1.00 69.43 H ATOM 1506 N ARG A 91 -18.798 28.668 -16.623 1.00 68.01 N ATOM 1507 CA ARG A 91 -17.912 28.239 -17.708 1.00 66.61 C ATOM 1508 C ARG A 91 -16.800 27.267 -17.261 1.00 63.84 C ATOM 1509 O ARG A 91 -15.729 27.259 -17.866 1.00 62.48 O ATOM 1510 CB ARG A 91 -17.377 29.436 -18.528 1.00 67.29 C ATOM 1511 CG ARG A 91 -18.488 30.326 -19.122 1.00 70.07 C ATOM 1512 CD ARG A 91 -17.991 31.442 -20.067 1.00 75.80 C ATOM 1513 NE ARG A 91 -17.120 30.946 -21.154 1.00 77.23 N ATOM 1514 CZ ARG A 91 -17.446 30.124 -22.170 1.00 80.86 C ATOM 1515 NH1 ARG A 91 -18.698 29.689 -22.376 1.00 80.80 N ATOM 1516 NH2 ARG A 91 -16.482 29.718 -23.006 1.00 82.08 N1+ ATOM 1517 H ARG A 91 -19.740 28.309 -16.681 1.00 68.01 H ATOM 1518 HA ARG A 91 -18.543 27.658 -18.379 1.00 66.61 H ATOM 1519 HB3 ARG A 91 -16.786 29.030 -19.347 1.00 67.29 H ATOM 1520 HB2 ARG A 91 -16.693 30.042 -17.933 1.00 67.29 H ATOM 1521 HG3 ARG A 91 -18.958 30.828 -18.276 1.00 70.07 H ATOM 1522 HG2 ARG A 91 -19.286 29.742 -19.579 1.00 70.07 H ATOM 1523 HD3 ARG A 91 -17.534 32.264 -19.515 1.00 75.80 H ATOM 1524 HD2 ARG A 91 -18.858 31.869 -20.571 1.00 75.80 H ATOM 1525 HE ARG A 91 -16.153 31.224 -21.073 1.00 77.23 H ATOM 1526 HH12 ARG A 91 -18.908 29.090 -23.161 1.00 80.80 H ATOM 1527 HH11 ARG A 91 -19.454 29.971 -21.763 1.00 80.80 H ATOM 1528 HH22 ARG A 91 -16.711 29.123 -23.791 1.00 82.08 H ATOM 1529 HH21 ARG A 91 -15.532 30.039 -22.894 1.00 82.08 H ATOM 1530 N LYS A 92 -17.066 26.445 -16.234 1.00 61.84 N ATOM 1531 CA LYS A 92 -16.129 25.430 -15.750 1.00 60.31 C ATOM 1532 C LYS A 92 -16.365 24.094 -16.470 1.00 57.74 C ATOM 1533 O LYS A 92 -17.512 23.681 -16.649 1.00 57.63 O ATOM 1534 CB LYS A 92 -16.265 25.285 -14.221 1.00 61.04 C ATOM 1535 CG LYS A 92 -15.916 26.568 -13.432 1.00 64.60 C ATOM 1536 CD LYS A 92 -14.446 27.027 -13.491 1.00 66.68 C ATOM 1537 CE LYS A 92 -13.489 26.061 -12.775 0.00 66.00 C ATOM 1538 NZ LYS A 92 -12.108 26.566 -12.726 0.00 66.02 N1+ ATOM 1539 H LYS A 92 -17.965 26.487 -15.770 1.00 61.84 H ATOM 1540 HA LYS A 92 -15.108 25.747 -15.965 1.00 60.31 H ATOM 1541 HB3 LYS A 92 -15.639 24.464 -13.869 1.00 61.04 H ATOM 1542 HB2 LYS A 92 -17.287 24.992 -13.978 1.00 61.04 H ATOM 1543 HG3 LYS A 92 -16.200 26.423 -12.388 1.00 64.60 H ATOM 1544 HG2 LYS A 92 -16.540 27.389 -13.785 1.00 64.60 H ATOM 1545 HD3 LYS A 92 -14.380 28.014 -13.031 1.00 66.68 H ATOM 1546 HD2 LYS A 92 -14.136 27.166 -14.527 1.00 66.68 H ATOM 1547 HE3 LYS A 92 -13.485 25.089 -13.266 1.00 66.00 H ATOM 1548 HE2 LYS A 92 -13.823 25.919 -11.749 1.00 66.00 H ATOM 1549 HZ1 LYS A 92 -11.770 26.695 -13.672 1.00 66.02 H ATOM 1550 HZ2 LYS A 92 -12.084 27.448 -12.235 1.00 66.02 H ATOM 1551 HZ3 LYS A 92 -11.521 25.894 -12.253 1.00 66.02 H ATOM 1552 N VAL A 93 -15.257 23.446 -16.854 1.00 56.27 N ATOM 1553 CA VAL A 93 -15.233 22.139 -17.503 1.00 54.34 C ATOM 1554 C VAL A 93 -14.814 21.089 -16.460 1.00 53.11 C ATOM 1555 O VAL A 93 -13.810 21.282 -15.771 1.00 51.93 O ATOM 1556 CB VAL A 93 -14.199 22.099 -18.666 1.00 54.22 C ATOM 1557 CG1 VAL A 93 -14.108 20.721 -19.355 1.00 50.82 C ATOM 1558 CG2 VAL A 93 -14.485 23.185 -19.720 1.00 53.39 C ATOM 1559 H VAL A 93 -14.349 23.858 -16.672 1.00 56.27 H ATOM 1560 HA VAL A 93 -16.218 21.891 -17.902 1.00 54.34 H ATOM 1561 HB VAL A 93 -13.211 22.319 -18.258 1.00 54.22 H ATOM 1562 HG11 VAL A 93 -13.421 20.755 -20.199 1.00 50.82 H ATOM 1563 HG12 VAL A 93 -13.738 19.945 -18.685 1.00 50.82 H ATOM 1564 HG13 VAL A 93 -15.079 20.399 -19.731 1.00 50.82 H ATOM 1565 HG21 VAL A 93 -13.768 23.141 -20.541 1.00 53.39 H ATOM 1566 HG22 VAL A 93 -15.482 23.075 -20.142 1.00 53.39 H ATOM 1567 HG23 VAL A 93 -14.419 24.185 -19.292 1.00 53.39 H ATOM 1568 N TRP A 94 -15.585 19.994 -16.390 1.00 51.85 N ATOM 1569 CA TRP A 94 -15.324 18.848 -15.522 1.00 51.87 C ATOM 1570 C TRP A 94 -15.141 17.591 -16.379 1.00 51.82 C ATOM 1571 O TRP A 94 -15.856 17.419 -17.365 1.00 53.38 O ATOM 1572 CB TRP A 94 -16.488 18.648 -14.534 1.00 51.58 C ATOM 1573 CG TRP A 94 -16.758 19.753 -13.557 1.00 51.06 C ATOM 1574 CD1 TRP A 94 -17.290 20.965 -13.844 1.00 50.00 C ATOM 1575 CD2 TRP A 94 -16.511 19.755 -12.120 1.00 49.72 C ATOM 1576 NE1 TRP A 94 -17.391 21.711 -12.688 1.00 49.59 N ATOM 1577 CE2 TRP A 94 -16.937 21.010 -11.589 1.00 51.61 C ATOM 1578 CE3 TRP A 94 -15.981 18.815 -11.205 1.00 51.03 C ATOM 1579 CZ2 TRP A 94 -16.847 21.313 -10.220 1.00 51.66 C ATOM 1580 CZ3 TRP A 94 -15.878 19.111 -9.831 1.00 53.63 C ATOM 1581 CH2 TRP A 94 -16.299 20.362 -9.341 1.00 52.18 C ATOM 1582 H TRP A 94 -16.384 19.907 -17.006 1.00 51.85 H ATOM 1583 HA TRP A 94 -14.417 19.011 -14.943 1.00 51.87 H ATOM 1584 HB3 TRP A 94 -16.306 17.744 -13.951 1.00 51.58 H ATOM 1585 HB2 TRP A 94 -17.406 18.456 -15.077 1.00 51.58 H ATOM 1586 HD1 TRP A 94 -17.589 21.286 -14.832 1.00 50.00 H ATOM 1587 HE1 TRP A 94 -17.768 22.649 -12.671 1.00 49.59 H ATOM 1588 HE3 TRP A 94 -15.648 17.856 -11.569 1.00 51.03 H ATOM 1589 HZ2 TRP A 94 -17.182 22.270 -9.848 1.00 51.66 H ATOM 1590 HZ3 TRP A 94 -15.471 18.375 -9.153 1.00 53.63 H ATOM 1591 HH2 TRP A 94 -16.205 20.589 -8.290 1.00 52.18 H ATOM 1592 N LEU A 95 -14.201 16.731 -15.960 1.00 51.47 N ATOM 1593 CA LEU A 95 -13.858 15.472 -16.613 1.00 51.39 C ATOM 1594 C LEU A 95 -14.028 14.332 -15.600 1.00 51.96 C ATOM 1595 O LEU A 95 -13.388 14.354 -14.548 1.00 51.96 O ATOM 1596 CB LEU A 95 -12.394 15.522 -17.113 1.00 51.01 C ATOM 1597 CG LEU A 95 -12.003 16.682 -18.059 1.00 50.86 C ATOM 1598 CD1 LEU A 95 -10.493 16.649 -18.368 1.00 44.82 C ATOM 1599 CD2 LEU A 95 -12.844 16.742 -19.349 1.00 48.92 C ATOM 1600 H LEU A 95 -13.648 16.964 -15.145 1.00 51.47 H ATOM 1601 HA LEU A 95 -14.527 15.274 -17.451 1.00 51.39 H ATOM 1602 HB3 LEU A 95 -12.153 14.575 -17.595 1.00 51.01 H ATOM 1603 HB2 LEU A 95 -11.735 15.583 -16.248 1.00 51.01 H ATOM 1604 HG LEU A 95 -12.192 17.610 -17.518 1.00 50.86 H ATOM 1605 HD11 LEU A 95 -10.282 16.754 -19.432 1.00 44.82 H ATOM 1606 HD12 LEU A 95 -9.974 17.462 -17.860 1.00 44.82 H ATOM 1607 HD13 LEU A 95 -10.025 15.721 -18.039 1.00 44.82 H ATOM 1608 HD21 LEU A 95 -13.031 17.775 -19.641 1.00 48.92 H ATOM 1609 HD22 LEU A 95 -12.349 16.249 -20.186 1.00 48.92 H ATOM 1610 HD23 LEU A 95 -13.815 16.271 -19.232 1.00 48.92 H ATOM 1611 N LEU A 96 -14.873 13.351 -15.950 1.00 51.79 N ATOM 1612 CA LEU A 96 -15.100 12.133 -15.177 1.00 52.69 C ATOM 1613 C LEU A 96 -14.095 11.053 -15.608 1.00 53.42 C ATOM 1614 O LEU A 96 -13.919 10.824 -16.803 1.00 53.73 O ATOM 1615 CB LEU A 96 -16.556 11.662 -15.404 1.00 53.36 C ATOM 1616 CG LEU A 96 -17.025 10.519 -14.471 1.00 54.54 C ATOM 1617 CD1 LEU A 96 -17.176 10.989 -13.016 1.00 55.76 C ATOM 1618 CD2 LEU A 96 -18.325 9.868 -14.978 1.00 54.29 C ATOM 1619 H LEU A 96 -15.354 13.402 -16.840 1.00 51.79 H ATOM 1620 HA LEU A 96 -14.963 12.355 -14.117 1.00 52.69 H ATOM 1621 HB3 LEU A 96 -16.652 11.344 -16.442 1.00 53.36 H ATOM 1622 HB2 LEU A 96 -17.238 12.506 -15.296 1.00 53.36 H ATOM 1623 HG LEU A 96 -16.274 9.729 -14.484 1.00 54.54 H ATOM 1624 HD11 LEU A 96 -17.795 10.302 -12.439 1.00 55.76 H ATOM 1625 HD12 LEU A 96 -16.207 11.051 -12.520 1.00 55.76 H ATOM 1626 HD13 LEU A 96 -17.648 11.969 -12.958 1.00 55.76 H ATOM 1627 HD21 LEU A 96 -18.304 8.790 -14.818 1.00 54.29 H ATOM 1628 HD22 LEU A 96 -19.202 10.261 -14.463 1.00 54.29 H ATOM 1629 HD23 LEU A 96 -18.481 10.028 -16.044 1.00 54.29 H ATOM 1630 N PHE A 97 -13.495 10.391 -14.613 1.00 53.90 N ATOM 1631 CA PHE A 97 -12.618 9.231 -14.760 1.00 53.21 C ATOM 1632 C PHE A 97 -13.041 8.176 -13.725 1.00 55.01 C ATOM 1633 O PHE A 97 -13.694 8.516 -12.736 1.00 57.54 O ATOM 1634 CB PHE A 97 -11.153 9.649 -14.493 1.00 52.68 C ATOM 1635 CG PHE A 97 -10.569 10.725 -15.392 1.00 47.78 C ATOM 1636 CD1 PHE A 97 -10.095 10.399 -16.679 1.00 43.93 C ATOM 1637 CD2 PHE A 97 -10.594 12.079 -14.995 1.00 46.72 C ATOM 1638 CE1 PHE A 97 -9.598 11.390 -17.512 1.00 45.72 C ATOM 1639 CE2 PHE A 97 -10.083 13.055 -15.839 1.00 45.47 C ATOM 1640 CZ PHE A 97 -9.583 12.713 -17.089 1.00 46.69 C ATOM 1641 H PHE A 97 -13.676 10.669 -13.657 1.00 53.90 H ATOM 1642 HA PHE A 97 -12.706 8.802 -15.759 1.00 53.21 H ATOM 1643 HB3 PHE A 97 -10.509 8.772 -14.584 1.00 52.68 H ATOM 1644 HB2 PHE A 97 -11.044 9.985 -13.464 1.00 52.68 H ATOM 1645 HD1 PHE A 97 -10.098 9.376 -17.014 1.00 43.93 H ATOM 1646 HD2 PHE A 97 -10.990 12.358 -14.030 1.00 46.72 H ATOM 1647 HE1 PHE A 97 -9.219 11.128 -18.489 1.00 45.72 H ATOM 1648 HE2 PHE A 97 -10.070 14.086 -15.526 1.00 45.47 H ATOM 1649 HZ PHE A 97 -9.188 13.482 -17.735 1.00 46.69 H ATOM 1650 N ASP A 98 -12.595 6.924 -13.925 1.00 54.45 N ATOM 1651 CA ASP A 98 -12.591 5.902 -12.869 1.00 54.41 C ATOM 1652 C ASP A 98 -11.486 6.210 -11.844 1.00 53.15 C ATOM 1653 O ASP A 98 -10.397 6.648 -12.221 1.00 53.04 O ATOM 1654 CB ASP A 98 -12.441 4.454 -13.403 1.00 55.47 C ATOM 1655 CG ASP A 98 -13.574 3.941 -14.311 1.00 60.32 C ATOM 1656 OD1 ASP A 98 -14.686 4.517 -14.288 1.00 66.03 O ATOM 1657 OD2 ASP A 98 -13.346 2.879 -14.931 1.00 62.12 O1- ATOM 1658 H ASP A 98 -12.081 6.698 -14.764 1.00 54.45 H ATOM 1659 HA ASP A 98 -13.545 5.961 -12.340 1.00 54.41 H ATOM 1660 HB3 ASP A 98 -12.356 3.761 -12.564 1.00 55.47 H ATOM 1661 HB2 ASP A 98 -11.508 4.378 -13.965 1.00 55.47 H ATOM 1662 N TYR A 99 -11.810 5.997 -10.562 1.00 51.82 N ATOM 1663 CA TYR A 99 -10.953 6.339 -9.432 1.00 51.53 C ATOM 1664 C TYR A 99 -9.855 5.288 -9.200 1.00 49.66 C ATOM 1665 O TYR A 99 -10.167 4.102 -9.095 1.00 49.47 O ATOM 1666 CB TYR A 99 -11.853 6.500 -8.200 1.00 51.24 C ATOM 1667 CG TYR A 99 -11.165 6.928 -6.922 1.00 51.57 C ATOM 1668 CD1 TYR A 99 -10.895 8.291 -6.679 1.00 53.85 C ATOM 1669 CD2 TYR A 99 -10.818 5.957 -5.964 1.00 54.64 C ATOM 1670 CE1 TYR A 99 -10.281 8.681 -5.474 1.00 51.68 C ATOM 1671 CE2 TYR A 99 -10.211 6.349 -4.762 1.00 56.06 C ATOM 1672 CZ TYR A 99 -9.948 7.707 -4.513 1.00 56.35 C ATOM 1673 OH TYR A 99 -9.386 8.073 -3.329 1.00 60.78 O ATOM 1674 H TYR A 99 -12.718 5.616 -10.333 1.00 51.82 H ATOM 1675 HA TYR A 99 -10.493 7.306 -9.633 1.00 51.53 H ATOM 1676 HB3 TYR A 99 -12.377 5.563 -8.011 1.00 51.24 H ATOM 1677 HB2 TYR A 99 -12.621 7.237 -8.412 1.00 51.24 H ATOM 1678 HD1 TYR A 99 -11.168 9.040 -7.407 1.00 53.85 H ATOM 1679 HD2 TYR A 99 -11.026 4.912 -6.141 1.00 54.64 H ATOM 1680 HE1 TYR A 99 -10.081 9.725 -5.282 1.00 51.68 H ATOM 1681 HE2 TYR A 99 -9.968 5.597 -4.031 1.00 56.06 H ATOM 1682 HH TYR A 99 -9.082 7.320 -2.808 1.00 60.78 H ATOM 1683 N ALA A 100 -8.607 5.764 -9.070 1.00 50.38 N ATOM 1684 CA ALA A 100 -7.438 4.981 -8.681 1.00 50.49 C ATOM 1685 C ALA A 100 -7.057 5.358 -7.244 1.00 51.17 C ATOM 1686 O ALA A 100 -6.744 6.520 -6.983 1.00 50.13 O ATOM 1687 CB ALA A 100 -6.287 5.286 -9.651 1.00 48.46 C ATOM 1688 H ALA A 100 -8.449 6.758 -9.164 1.00 50.38 H ATOM 1689 HA ALA A 100 -7.655 3.914 -8.730 1.00 50.49 H ATOM 1690 HB1 ALA A 100 -5.391 4.725 -9.385 1.00 48.46 H ATOM 1691 HB2 ALA A 100 -6.551 5.015 -10.673 1.00 48.46 H ATOM 1692 HB3 ALA A 100 -6.031 6.346 -9.647 1.00 48.46 H ATOM 1693 N GLU A 101 -7.106 4.370 -6.337 1.00 53.48 N ATOM 1694 CA GLU A 101 -6.871 4.553 -4.901 1.00 53.48 C ATOM 1695 C GLU A 101 -5.391 4.795 -4.534 1.00 54.29 C ATOM 1696 O GLU A 101 -5.132 5.387 -3.486 1.00 54.41 O ATOM 1697 CB GLU A 101 -7.474 3.335 -4.159 1.00 54.73 C ATOM 1698 CG GLU A 101 -7.487 3.390 -2.612 1.00 56.18 C ATOM 1699 CD GLU A 101 -8.483 4.418 -2.056 1.00 55.60 C ATOM 1700 OE1 GLU A 101 -9.638 4.017 -1.793 1.00 58.73 O ATOM 1701 OE2 GLU A 101 -8.084 5.593 -1.895 1.00 55.67 O1- ATOM 1702 H GLU A 101 -7.390 3.444 -6.624 1.00 53.48 H ATOM 1703 HA GLU A 101 -7.421 5.444 -4.599 1.00 53.48 H ATOM 1704 HB3 GLU A 101 -6.930 2.441 -4.463 1.00 54.73 H ATOM 1705 HB2 GLU A 101 -8.496 3.176 -4.506 1.00 54.73 H ATOM 1706 HG3 GLU A 101 -6.492 3.581 -2.211 1.00 56.18 H ATOM 1707 HG2 GLU A 101 -7.757 2.403 -2.233 1.00 56.18 H ATOM 1708 N HIS A 102 -4.453 4.359 -5.396 1.00 54.22 N ATOM 1709 CA HIS A 102 -3.004 4.417 -5.168 1.00 53.29 C ATOM 1710 C HIS A 102 -2.264 5.027 -6.372 1.00 52.79 C ATOM 1711 O HIS A 102 -2.871 5.304 -7.408 1.00 49.37 O ATOM 1712 CB HIS A 102 -2.477 2.999 -4.836 1.00 54.11 C ATOM 1713 CG HIS A 102 -3.280 2.256 -3.797 1.00 55.21 C ATOM 1714 ND1 HIS A 102 -4.236 1.291 -4.136 1.00 55.20 N ATOM 1715 CD2 HIS A 102 -3.269 2.413 -2.427 1.00 51.98 C ATOM 1716 CE1 HIS A 102 -4.770 0.927 -2.980 1.00 57.79 C ATOM 1717 NE2 HIS A 102 -4.232 1.554 -1.932 1.00 59.58 N ATOM 1718 H HIS A 102 -4.738 3.901 -6.252 1.00 54.22 H ATOM 1719 HA HIS A 102 -2.797 5.064 -4.314 1.00 53.29 H ATOM 1720 HB3 HIS A 102 -1.446 3.054 -4.485 1.00 54.11 H ATOM 1721 HB2 HIS A 102 -2.461 2.384 -5.736 1.00 54.11 H ATOM 1722 HD2 HIS A 102 -2.690 3.062 -1.785 1.00 51.98 H ATOM 1723 HE1 HIS A 102 -5.562 0.197 -2.897 1.00 57.79 H ATOM 1724 HE2 HIS A 102 -4.478 1.427 -0.959 1.00 59.58 H ATOM 1725 N ASP A 103 -0.952 5.232 -6.191 1.00 53.66 N ATOM 1726 CA ASP A 103 -0.008 5.712 -7.204 1.00 53.55 C ATOM 1727 C ASP A 103 1.418 5.381 -6.736 1.00 53.17 C ATOM 1728 O ASP A 103 1.624 5.111 -5.551 1.00 54.49 O ATOM 1729 CB ASP A 103 -0.166 7.219 -7.563 1.00 54.64 C ATOM 1730 CG ASP A 103 -0.081 8.206 -6.391 1.00 54.94 C ATOM 1731 OD1 ASP A 103 -1.146 8.539 -5.834 1.00 61.11 O ATOM 1732 OD2 ASP A 103 1.054 8.497 -5.963 1.00 54.55 O1- ATOM 1733 H ASP A 103 -0.531 4.990 -5.305 1.00 53.66 H ATOM 1734 HA ASP A 103 -0.178 5.121 -8.104 1.00 53.55 H ATOM 1735 HB3 ASP A 103 -1.139 7.366 -8.030 1.00 54.64 H ATOM 1736 HB2 ASP A 103 0.560 7.509 -8.324 1.00 54.64 H ATOM 1737 N LEU A 104 2.384 5.425 -7.671 1.00 52.35 N ATOM 1738 CA LEU A 104 3.787 5.106 -7.398 1.00 52.18 C ATOM 1739 C LEU A 104 4.500 6.056 -6.421 1.00 52.65 C ATOM 1740 O LEU A 104 5.422 5.589 -5.757 1.00 53.08 O ATOM 1741 CB LEU A 104 4.597 4.950 -8.706 1.00 50.66 C ATOM 1742 CG LEU A 104 4.390 3.618 -9.450 1.00 53.51 C ATOM 1743 CD1 LEU A 104 5.310 3.551 -10.680 1.00 46.19 C ATOM 1744 CD2 LEU A 104 4.622 2.386 -8.558 1.00 57.11 C ATOM 1745 H LEU A 104 2.151 5.671 -8.625 1.00 52.35 H ATOM 1746 HA LEU A 104 3.777 4.146 -6.890 1.00 52.18 H ATOM 1747 HB3 LEU A 104 5.661 5.024 -8.484 1.00 50.66 H ATOM 1748 HB2 LEU A 104 4.384 5.779 -9.376 1.00 50.66 H ATOM 1749 HG LEU A 104 3.358 3.591 -9.806 1.00 53.51 H ATOM 1750 HD11 LEU A 104 4.921 2.840 -11.406 1.00 46.19 H ATOM 1751 HD12 LEU A 104 5.409 4.519 -11.171 1.00 46.19 H ATOM 1752 HD13 LEU A 104 6.313 3.220 -10.410 1.00 46.19 H ATOM 1753 HD21 LEU A 104 5.094 1.581 -9.118 1.00 57.11 H ATOM 1754 HD22 LEU A 104 5.267 2.608 -7.708 1.00 57.11 H ATOM 1755 HD23 LEU A 104 3.679 2.004 -8.169 1.00 57.11 H ATOM 1756 N TRP A 105 4.078 7.331 -6.309 1.00 53.42 N ATOM 1757 CA TRP A 105 4.657 8.270 -5.340 1.00 55.35 C ATOM 1758 C TRP A 105 4.341 7.856 -3.892 1.00 54.65 C ATOM 1759 O TRP A 105 5.267 7.790 -3.089 1.00 55.02 O ATOM 1760 CB TRP A 105 4.245 9.725 -5.650 1.00 56.39 C ATOM 1761 CG TRP A 105 4.895 10.801 -4.829 1.00 61.99 C ATOM 1762 CD1 TRP A 105 6.037 11.446 -5.159 1.00 64.35 C ATOM 1763 CD2 TRP A 105 4.506 11.322 -3.520 1.00 65.21 C ATOM 1764 NE1 TRP A 105 6.366 12.345 -4.165 1.00 65.75 N ATOM 1765 CE2 TRP A 105 5.461 12.309 -3.125 1.00 67.33 C ATOM 1766 CE3 TRP A 105 3.445 11.063 -2.621 1.00 67.32 C ATOM 1767 CZ2 TRP A 105 5.365 13.002 -1.905 1.00 70.14 C ATOM 1768 CZ3 TRP A 105 3.340 11.747 -1.393 1.00 69.35 C ATOM 1769 CH2 TRP A 105 4.296 12.717 -1.034 1.00 69.78 C ATOM 1770 H TRP A 105 3.296 7.661 -6.860 1.00 53.42 H ATOM 1771 HA TRP A 105 5.741 8.221 -5.462 1.00 55.35 H ATOM 1772 HB3 TRP A 105 3.172 9.855 -5.542 1.00 56.39 H ATOM 1773 HB2 TRP A 105 4.466 9.945 -6.692 1.00 56.39 H ATOM 1774 HD1 TRP A 105 6.595 11.273 -6.068 1.00 64.35 H ATOM 1775 HE1 TRP A 105 7.185 12.934 -4.215 1.00 65.75 H ATOM 1776 HE3 TRP A 105 2.705 10.323 -2.880 1.00 67.32 H ATOM 1777 HZ2 TRP A 105 6.104 13.742 -1.637 1.00 70.14 H ATOM 1778 HZ3 TRP A 105 2.519 11.527 -0.726 1.00 69.35 H ATOM 1779 HH2 TRP A 105 4.209 13.240 -0.094 1.00 69.78 H ATOM 1780 N HIS A 106 3.068 7.527 -3.605 1.00 54.77 N ATOM 1781 CA HIS A 106 2.618 7.030 -2.300 1.00 55.69 C ATOM 1782 C HIS A 106 3.126 5.615 -1.963 1.00 55.10 C ATOM 1783 O HIS A 106 3.450 5.367 -0.802 1.00 56.41 O ATOM 1784 CB HIS A 106 1.081 7.099 -2.195 1.00 54.40 C ATOM 1785 CG HIS A 106 0.532 8.495 -2.023 1.00 58.57 C ATOM 1786 ND1 HIS A 106 0.160 9.298 -3.086 1.00 60.54 N ATOM 1787 CD2 HIS A 106 0.263 9.236 -0.893 1.00 58.96 C ATOM 1788 CE1 HIS A 106 -0.290 10.448 -2.579 1.00 59.62 C ATOM 1789 NE2 HIS A 106 -0.254 10.483 -1.252 1.00 61.10 N ATOM 1790 H HIS A 106 2.362 7.604 -4.327 1.00 54.77 H ATOM 1791 HA HIS A 106 3.028 7.691 -1.534 1.00 55.69 H ATOM 1792 HB3 HIS A 106 0.734 6.515 -1.342 1.00 54.40 H ATOM 1793 HB2 HIS A 106 0.621 6.646 -3.075 1.00 54.40 H ATOM 1794 HD1 HIS A 106 0.212 9.058 -4.072 1.00 60.54 H ATOM 1795 HD2 HIS A 106 0.401 8.970 0.145 1.00 58.96 H ATOM 1796 HE1 HIS A 106 -0.645 11.267 -3.187 1.00 59.62 H ATOM 1797 N ILE A 107 3.207 4.727 -2.971 1.00 55.39 N ATOM 1798 CA ILE A 107 3.716 3.356 -2.841 1.00 53.97 C ATOM 1799 C ILE A 107 5.220 3.307 -2.499 1.00 55.14 C ATOM 1800 O ILE A 107 5.599 2.558 -1.599 1.00 55.18 O ATOM 1801 CB ILE A 107 3.410 2.510 -4.119 1.00 52.78 C ATOM 1802 CG1 ILE A 107 1.907 2.142 -4.176 1.00 52.36 C ATOM 1803 CG2 ILE A 107 4.274 1.244 -4.333 1.00 48.93 C ATOM 1804 CD1 ILE A 107 1.421 1.682 -5.561 1.00 49.09 C ATOM 1805 H ILE A 107 2.907 5.002 -3.897 1.00 55.39 H ATOM 1806 HA ILE A 107 3.188 2.896 -2.003 1.00 53.97 H ATOM 1807 HB ILE A 107 3.612 3.158 -4.968 1.00 52.78 H ATOM 1808 HG13 ILE A 107 1.299 2.992 -3.867 1.00 52.36 H ATOM 1809 HG12 ILE A 107 1.701 1.357 -3.448 1.00 52.36 H ATOM 1810 HG21 ILE A 107 3.969 0.709 -5.231 1.00 48.93 H ATOM 1811 HG22 ILE A 107 5.329 1.480 -4.473 1.00 48.93 H ATOM 1812 HG23 ILE A 107 4.190 0.556 -3.493 1.00 48.93 H ATOM 1813 HD11 ILE A 107 0.358 1.886 -5.688 1.00 49.09 H ATOM 1814 HD12 ILE A 107 1.948 2.195 -6.365 1.00 49.09 H ATOM 1815 HD13 ILE A 107 1.566 0.610 -5.694 1.00 49.09 H ATOM 1816 N ILE A 108 6.037 4.121 -3.191 1.00 56.25 N ATOM 1817 CA ILE A 108 7.475 4.248 -2.934 1.00 57.08 C ATOM 1818 C ILE A 108 7.771 4.963 -1.601 1.00 59.72 C ATOM 1819 O ILE A 108 8.699 4.552 -0.907 1.00 60.07 O ATOM 1820 CB ILE A 108 8.221 4.969 -4.099 1.00 56.08 C ATOM 1821 CG1 ILE A 108 8.236 4.079 -5.365 1.00 54.61 C ATOM 1822 CG2 ILE A 108 9.662 5.419 -3.762 1.00 50.39 C ATOM 1823 CD1 ILE A 108 8.475 4.843 -6.679 1.00 43.55 C ATOM 1824 H ILE A 108 5.662 4.707 -3.927 1.00 56.25 H ATOM 1825 HA ILE A 108 7.885 3.238 -2.853 1.00 57.08 H ATOM 1826 HB ILE A 108 7.656 5.872 -4.337 1.00 56.08 H ATOM 1827 HG13 ILE A 108 7.286 3.551 -5.461 1.00 54.61 H ATOM 1828 HG12 ILE A 108 8.988 3.297 -5.255 1.00 54.61 H ATOM 1829 HG21 ILE A 108 10.170 5.812 -4.635 1.00 50.39 H ATOM 1830 HG22 ILE A 108 9.691 6.213 -3.016 1.00 50.39 H ATOM 1831 HG23 ILE A 108 10.255 4.585 -3.389 1.00 50.39 H ATOM 1832 HD11 ILE A 108 9.306 4.410 -7.235 1.00 43.55 H ATOM 1833 HD12 ILE A 108 7.600 4.787 -7.324 1.00 43.55 H ATOM 1834 HD13 ILE A 108 8.688 5.899 -6.517 1.00 43.55 H ATOM 1835 N LYS A 109 6.964 5.983 -1.252 1.00 62.16 N ATOM 1836 CA LYS A 109 7.068 6.730 0.005 1.00 65.22 C ATOM 1837 C LYS A 109 6.781 5.859 1.245 1.00 66.00 C ATOM 1838 O LYS A 109 7.384 6.101 2.288 1.00 65.57 O ATOM 1839 CB LYS A 109 6.145 7.968 -0.064 1.00 65.72 C ATOM 1840 CG LYS A 109 6.300 9.005 1.063 1.00 68.81 C ATOM 1841 CD LYS A 109 7.650 9.741 1.022 1.00 71.81 C ATOM 1842 CE LYS A 109 7.691 10.938 1.984 0.00 71.58 C ATOM 1843 NZ LYS A 109 8.955 11.687 1.870 0.00 71.74 N1+ ATOM 1844 H LYS A 109 6.228 6.273 -1.882 1.00 62.16 H ATOM 1845 HA LYS A 109 8.098 7.079 0.075 1.00 65.22 H ATOM 1846 HB3 LYS A 109 5.106 7.642 -0.115 1.00 65.72 H ATOM 1847 HB2 LYS A 109 6.341 8.499 -0.994 1.00 65.72 H ATOM 1848 HG3 LYS A 109 6.156 8.540 2.039 1.00 68.81 H ATOM 1849 HG2 LYS A 109 5.495 9.734 0.962 1.00 68.81 H ATOM 1850 HD3 LYS A 109 7.849 10.075 0.002 1.00 71.81 H ATOM 1851 HD2 LYS A 109 8.449 9.043 1.279 1.00 71.81 H ATOM 1852 HE3 LYS A 109 7.569 10.600 3.014 1.00 71.58 H ATOM 1853 HE2 LYS A 109 6.869 11.622 1.769 1.00 71.58 H ATOM 1854 HZ1 LYS A 109 9.062 12.025 0.925 1.00 71.74 H ATOM 1855 HZ2 LYS A 109 8.940 12.471 2.507 1.00 71.74 H ATOM 1856 HZ3 LYS A 109 9.728 11.080 2.103 1.00 71.74 H ATOM 1857 N PHE A 110 5.911 4.843 1.093 1.00 66.84 N ATOM 1858 CA PHE A 110 5.591 3.837 2.107 1.00 67.92 C ATOM 1859 C PHE A 110 6.776 2.898 2.415 1.00 70.50 C ATOM 1860 O PHE A 110 7.033 2.628 3.588 1.00 71.23 O ATOM 1861 CB PHE A 110 4.312 3.085 1.668 1.00 67.15 C ATOM 1862 CG PHE A 110 3.787 2.005 2.598 1.00 67.39 C ATOM 1863 CD1 PHE A 110 2.964 2.353 3.690 1.00 68.50 C ATOM 1864 CD2 PHE A 110 4.213 0.666 2.460 1.00 70.58 C ATOM 1865 CE1 PHE A 110 2.522 1.370 4.567 1.00 69.89 C ATOM 1866 CE2 PHE A 110 3.758 -0.301 3.346 1.00 70.67 C ATOM 1867 CZ PHE A 110 2.910 0.048 4.390 1.00 69.07 C ATOM 1868 H PHE A 110 5.451 4.728 0.200 1.00 66.84 H ATOM 1869 HA PHE A 110 5.356 4.370 3.030 1.00 67.92 H ATOM 1870 HB3 PHE A 110 4.462 2.639 0.685 1.00 67.15 H ATOM 1871 HB2 PHE A 110 3.509 3.812 1.537 1.00 67.15 H ATOM 1872 HD1 PHE A 110 2.661 3.379 3.839 1.00 68.50 H ATOM 1873 HD2 PHE A 110 4.882 0.387 1.659 1.00 70.58 H ATOM 1874 HE1 PHE A 110 1.873 1.635 5.388 1.00 69.89 H ATOM 1875 HE2 PHE A 110 4.068 -1.329 3.225 1.00 70.67 H ATOM 1876 HZ PHE A 110 2.558 -0.710 5.073 1.00 69.07 H ATOM 1877 N HIS A 111 7.496 2.454 1.366 1.00 73.02 N ATOM 1878 CA HIS A 111 8.714 1.641 1.482 1.00 74.91 C ATOM 1879 C HIS A 111 9.927 2.439 1.989 1.00 77.07 C ATOM 1880 O HIS A 111 10.713 1.901 2.768 1.00 76.67 O ATOM 1881 CB HIS A 111 9.041 0.973 0.133 1.00 75.20 C ATOM 1882 CG HIS A 111 8.041 -0.058 -0.321 1.00 75.01 C ATOM 1883 ND1 HIS A 111 7.712 -1.176 0.455 1.00 73.93 N ATOM 1884 CD2 HIS A 111 7.325 -0.105 -1.498 1.00 74.68 C ATOM 1885 CE1 HIS A 111 6.819 -1.839 -0.267 1.00 74.70 C ATOM 1886 NE2 HIS A 111 6.555 -1.251 -1.433 1.00 76.22 N ATOM 1887 H HIS A 111 7.226 2.722 0.430 1.00 73.02 H ATOM 1888 HA HIS A 111 8.528 0.853 2.215 1.00 74.91 H ATOM 1889 HB3 HIS A 111 10.010 0.475 0.189 1.00 75.20 H ATOM 1890 HB2 HIS A 111 9.135 1.731 -0.646 1.00 75.20 H ATOM 1891 HD2 HIS A 111 7.299 0.564 -2.346 1.00 74.68 H ATOM 1892 HE1 HIS A 111 6.351 -2.757 0.058 1.00 74.70 H ATOM 1893 HE2 HIS A 111 5.883 -1.569 -2.119 1.00 76.22 H ATOM 1894 N ARG A 112 10.039 3.709 1.564 1.00 79.68 N ATOM 1895 CA ARG A 112 11.060 4.664 2.000 1.00 82.70 C ATOM 1896 C ARG A 112 10.917 5.054 3.487 1.00 84.60 C ATOM 1897 O ARG A 112 11.932 5.266 4.150 1.00 84.13 O ATOM 1898 CB ARG A 112 11.017 5.883 1.051 1.00 83.17 C ATOM 1899 CG ARG A 112 12.015 7.014 1.358 1.00 86.08 C ATOM 1900 CD ARG A 112 12.042 8.083 0.249 1.00 90.98 C ATOM 1901 NE ARG A 112 12.791 9.294 0.639 1.00 94.74 N ATOM 1902 CZ ARG A 112 14.126 9.465 0.724 1.00 98.39 C ATOM 1903 NH1 ARG A 112 15.000 8.482 0.463 1.00 98.39 N ATOM 1904 NH2 ARG A 112 14.601 10.665 1.083 1.00100.49 N1+ ATOM 1905 H ARG A 112 9.370 4.058 0.890 1.00 79.68 H ATOM 1906 HA ARG A 112 12.033 4.183 1.884 1.00 82.70 H ATOM 1907 HB3 ARG A 112 10.014 6.307 1.072 1.00 83.17 H ATOM 1908 HB2 ARG A 112 11.172 5.537 0.028 1.00 83.17 H ATOM 1909 HG3 ARG A 112 12.996 6.538 1.394 1.00 86.08 H ATOM 1910 HG2 ARG A 112 11.859 7.463 2.340 1.00 86.08 H ATOM 1911 HD3 ARG A 112 11.042 8.318 -0.117 1.00 90.98 H ATOM 1912 HD2 ARG A 112 12.581 7.683 -0.609 1.00 90.98 H ATOM 1913 HE ARG A 112 12.213 10.084 0.882 1.00 94.74 H ATOM 1914 HH12 ARG A 112 15.997 8.633 0.535 1.00 98.39 H ATOM 1915 HH11 ARG A 112 14.664 7.569 0.190 1.00 98.39 H ATOM 1916 HH22 ARG A 112 15.598 10.818 1.146 1.00100.49 H ATOM 1917 HH21 ARG A 112 13.975 11.433 1.273 1.00100.49 H ATOM 1918 N ALA A 113 9.668 5.105 3.984 1.00 87.53 N ATOM 1919 CA ALA A 113 9.328 5.358 5.385 1.00 89.82 C ATOM 1920 C ALA A 113 9.533 4.140 6.306 1.00 92.41 C ATOM 1921 O ALA A 113 9.644 4.335 7.516 1.00 92.74 O ATOM 1922 CB ALA A 113 7.874 5.848 5.462 1.00 89.32 C ATOM 1923 H ALA A 113 8.885 4.940 3.365 1.00 87.53 H ATOM 1924 HA ALA A 113 9.972 6.158 5.755 1.00 89.82 H ATOM 1925 HB1 ALA A 113 7.573 6.042 6.493 1.00 89.32 H ATOM 1926 HB2 ALA A 113 7.746 6.778 4.909 1.00 89.32 H ATOM 1927 HB3 ALA A 113 7.181 5.115 5.046 1.00 89.32 H ATOM 1928 N SER A 114 9.592 2.921 5.736 1.00 94.99 N ATOM 1929 CA SER A 114 9.810 1.660 6.450 1.00 97.12 C ATOM 1930 C SER A 114 11.313 1.433 6.729 1.00 98.86 C ATOM 1931 O SER A 114 11.925 0.530 6.157 1.00 98.78 O ATOM 1932 CB SER A 114 9.134 0.522 5.652 1.00 97.19 C ATOM 1933 OG SER A 114 9.255 -0.726 6.308 1.00 98.48 O ATOM 1934 H SER A 114 9.500 2.845 4.733 1.00 94.99 H ATOM 1935 HA SER A 114 9.308 1.717 7.418 1.00 97.12 H ATOM 1936 HB3 SER A 114 9.565 0.431 4.656 1.00 97.19 H ATOM 1937 HB2 SER A 114 8.072 0.734 5.516 1.00 97.19 H ATOM 1938 HG SER A 114 10.168 -1.014 6.225 1.00 98.48 H ATOM 1939 N LYS A 115 11.872 2.283 7.603 1.00100.93 N ATOM 1940 CA LYS A 115 13.286 2.318 7.982 1.00102.13 C ATOM 1941 C LYS A 115 13.597 1.462 9.230 1.00103.12 C ATOM 1942 O LYS A 115 14.764 1.142 9.453 1.00103.52 O ATOM 1943 CB LYS A 115 13.654 3.808 8.187 1.00102.09 C ATOM 1944 CG LYS A 115 15.127 4.103 8.528 0.00101.72 C ATOM 1945 CD LYS A 115 15.423 5.608 8.605 0.00101.73 C ATOM 1946 CE LYS A 115 16.893 5.895 8.952 0.00101.72 C ATOM 1947 NZ LYS A 115 17.159 7.341 9.053 0.00101.71 N1+ ATOM 1948 H LYS A 115 11.295 3.013 7.999 1.00100.93 H ATOM 1949 HA LYS A 115 13.889 1.930 7.158 1.00102.13 H ATOM 1950 HB3 LYS A 115 13.020 4.233 8.967 1.00102.09 H ATOM 1951 HB2 LYS A 115 13.404 4.350 7.272 1.00102.09 H ATOM 1952 HG3 LYS A 115 15.774 3.638 7.783 1.00101.72 H ATOM 1953 HG2 LYS A 115 15.387 3.656 9.487 1.00101.72 H ATOM 1954 HD3 LYS A 115 14.769 6.062 9.352 1.00101.73 H ATOM 1955 HD2 LYS A 115 15.168 6.074 7.651 1.00101.73 H ATOM 1956 HE3 LYS A 115 17.550 5.470 8.192 1.00101.72 H ATOM 1957 HE2 LYS A 115 17.154 5.428 9.902 1.00101.72 H ATOM 1958 HZ1 LYS A 115 16.582 7.741 9.779 1.00101.71 H ATOM 1959 HZ2 LYS A 115 18.133 7.490 9.279 1.00101.71 H ATOM 1960 HZ3 LYS A 115 16.948 7.786 8.171 1.00101.71 H ATOM 1961 N ALA A 116 12.565 1.135 10.030 1.00103.48 N ATOM 1962 CA ALA A 116 12.671 0.577 11.380 1.00103.97 C ATOM 1963 C ALA A 116 12.998 -0.930 11.446 1.00103.83 C ATOM 1964 O ALA A 116 12.156 -1.715 11.882 1.00103.44 O ATOM 1965 CB ALA A 116 11.382 0.931 12.143 1.00104.24 C ATOM 1966 H ALA A 116 11.635 1.405 9.746 1.00103.48 H ATOM 1967 HA ALA A 116 13.489 1.093 11.888 1.00103.97 H ATOM 1968 HB1 ALA A 116 11.417 0.571 13.172 1.00104.24 H ATOM 1969 HB2 ALA A 116 11.238 2.011 12.186 1.00104.24 H ATOM 1970 HB3 ALA A 116 10.501 0.498 11.667 1.00104.24 H ATOM 1971 N ASN A 117 14.247 -1.275 11.078 1.00 48.99 N ATOM 1972 CA ASN A 117 14.990 -2.506 11.410 1.00 53.05 C ATOM 1973 C ASN A 117 14.217 -3.812 11.123 1.00 55.96 C ATOM 1974 O ASN A 117 14.046 -4.631 12.028 1.00 57.20 O ATOM 1975 CB ASN A 117 15.474 -2.447 12.890 1.00 0.00 C ATOM 1976 CG ASN A 117 16.408 -1.283 13.247 1.00 0.00 C ATOM 1977 OD1 ASN A 117 16.741 -0.439 12.418 1.00 0.00 O ATOM 1978 ND2 ASN A 117 16.843 -1.240 14.508 1.00 0.00 N ATOM 1979 HB2 ASN A 117 14.615 -2.414 13.562 1.00 0.00 H ATOM 1980 HB3 ASN A 117 16.018 -3.362 13.131 1.00 0.00 H ATOM 1981 HD22 ASN A 117 17.464 -0.500 14.802 1.00 0.00 H ATOM 1982 HD21 ASN A 117 16.559 -1.945 15.173 1.00 0.00 H ATOM 1983 H ASN A 117 14.827 -0.541 10.692 1.00 48.99 H ATOM 1984 HA ASN A 117 15.867 -2.508 10.762 1.00 53.05 H ATOM 1985 N LYS A 118 13.738 -3.977 9.879 1.00 58.97 N ATOM 1986 CA LYS A 118 12.866 -5.094 9.507 1.00 61.75 C ATOM 1987 C LYS A 118 12.899 -5.368 7.998 1.00 62.91 C ATOM 1988 O LYS A 118 13.216 -4.481 7.205 1.00 63.12 O ATOM 1989 CB LYS A 118 11.428 -4.818 10.012 1.00 0.00 C ATOM 1990 CG LYS A 118 10.724 -3.618 9.348 1.00 0.00 C ATOM 1991 CD LYS A 118 9.435 -3.221 10.078 1.00 0.00 C ATOM 1992 CE LYS A 118 8.750 -2.012 9.425 1.00 0.00 C ATOM 1993 NZ LYS A 118 7.552 -1.593 10.173 1.00 0.00 N1+ ATOM 1994 HB2 LYS A 118 10.813 -5.707 9.859 1.00 0.00 H ATOM 1995 HB3 LYS A 118 11.453 -4.670 11.092 1.00 0.00 H ATOM 1996 HG2 LYS A 118 11.395 -2.759 9.320 1.00 0.00 H ATOM 1997 HG3 LYS A 118 10.490 -3.855 8.309 1.00 0.00 H ATOM 1998 HD2 LYS A 118 8.754 -4.074 10.092 1.00 0.00 H ATOM 1999 HD3 LYS A 118 9.671 -2.998 11.120 1.00 0.00 H ATOM 2000 HE2 LYS A 118 9.439 -1.168 9.374 1.00 0.00 H ATOM 2001 HE3 LYS A 118 8.457 -2.256 8.404 1.00 0.00 H ATOM 2002 HZ1 LYS A 118 7.813 -1.338 11.115 1.00 0.00 H ATOM 2003 HZ2 LYS A 118 7.130 -0.799 9.713 1.00 0.00 H ATOM 2004 HZ3 LYS A 118 6.889 -2.355 10.202 1.00 0.00 H ATOM 2005 H LYS A 118 13.908 -3.283 9.166 1.00 58.97 H ATOM 2006 HA LYS A 118 13.238 -5.997 9.996 1.00 61.75 H ATOM 2007 N LYS A 119 12.508 -6.603 7.651 1.00 63.82 N ATOM 2008 CA LYS A 119 12.257 -7.055 6.286 1.00 64.00 C ATOM 2009 C LYS A 119 10.771 -6.807 5.947 1.00 62.95 C ATOM 2010 O LYS A 119 9.918 -7.226 6.733 1.00 63.27 O ATOM 2011 CB LYS A 119 12.515 -8.577 6.221 1.00 0.00 C ATOM 2012 CG LYS A 119 13.970 -9.003 6.474 1.00 0.00 C ATOM 2013 CD LYS A 119 14.128 -10.530 6.389 1.00 0.00 C ATOM 2014 CE LYS A 119 15.555 -11.004 6.706 1.00 0.00 C ATOM 2015 NZ LYS A 119 15.664 -12.473 6.643 1.00 0.00 N1+ ATOM 2016 HB2 LYS A 119 11.865 -9.094 6.930 1.00 0.00 H ATOM 2017 HB3 LYS A 119 12.225 -8.938 5.233 1.00 0.00 H ATOM 2018 HG2 LYS A 119 14.625 -8.522 5.747 1.00 0.00 H ATOM 2019 HG3 LYS A 119 14.293 -8.660 7.458 1.00 0.00 H ATOM 2020 HD2 LYS A 119 13.422 -11.000 7.076 1.00 0.00 H ATOM 2021 HD3 LYS A 119 13.845 -10.860 5.389 1.00 0.00 H ATOM 2022 HE2 LYS A 119 16.264 -10.567 6.003 1.00 0.00 H ATOM 2023 HE3 LYS A 119 15.848 -10.677 7.705 1.00 0.00 H ATOM 2024 HZ1 LYS A 119 15.425 -12.790 5.714 1.00 0.00 H ATOM 2025 HZ2 LYS A 119 16.611 -12.752 6.858 1.00 0.00 H ATOM 2026 HZ3 LYS A 119 15.032 -12.889 7.312 1.00 0.00 H ATOM 2027 H LYS A 119 12.255 -7.259 8.376 1.00 63.82 H ATOM 2028 HA LYS A 119 12.945 -6.548 5.612 1.00 64.00 H ATOM 2029 N PRO A 120 10.465 -6.195 4.780 1.00 60.74 N ATOM 2030 CA PRO A 120 9.103 -6.257 4.217 1.00 57.38 C ATOM 2031 C PRO A 120 8.792 -7.647 3.615 1.00 56.09 C ATOM 2032 O PRO A 120 9.677 -8.503 3.539 1.00 56.07 O ATOM 2033 CD PRO A 120 11.391 -5.518 3.867 1.00 0.00 C ATOM 2034 CB PRO A 120 9.138 -5.155 3.145 1.00 0.00 C ATOM 2035 CG PRO A 120 10.567 -5.178 2.626 1.00 0.00 C ATOM 2036 HD3 PRO A 120 11.757 -4.610 4.349 1.00 0.00 H ATOM 2037 HD2 PRO A 120 12.246 -6.135 3.589 1.00 0.00 H ATOM 2038 HB2 PRO A 120 8.406 -5.287 2.347 1.00 0.00 H ATOM 2039 HB3 PRO A 120 8.935 -4.190 3.614 1.00 0.00 H ATOM 2040 HG3 PRO A 120 10.870 -4.247 2.146 1.00 0.00 H ATOM 2041 HG2 PRO A 120 10.667 -5.980 1.892 1.00 0.00 H ATOM 2042 HA PRO A 120 8.348 -6.021 4.969 1.00 57.38 H ATOM 2043 N VAL A 121 7.544 -7.827 3.150 1.00 53.78 N ATOM 2044 CA VAL A 121 7.123 -8.961 2.315 1.00 51.38 C ATOM 2045 C VAL A 121 7.932 -9.027 0.995 1.00 48.13 C ATOM 2046 O VAL A 121 8.367 -7.984 0.509 1.00 47.73 O ATOM 2047 CB VAL A 121 5.597 -8.863 2.007 1.00 0.00 C ATOM 2048 CG1 VAL A 121 5.191 -7.606 1.209 1.00 0.00 C ATOM 2049 CG2 VAL A 121 5.024 -10.123 1.330 1.00 0.00 C ATOM 2050 HB VAL A 121 5.097 -8.791 2.974 1.00 0.00 H ATOM 2051 HG11 VAL A 121 4.109 -7.560 1.080 1.00 0.00 H ATOM 2052 HG12 VAL A 121 5.493 -6.692 1.719 1.00 0.00 H ATOM 2053 HG13 VAL A 121 5.634 -7.591 0.215 1.00 0.00 H ATOM 2054 HG21 VAL A 121 3.935 -10.076 1.282 1.00 0.00 H ATOM 2055 HG22 VAL A 121 5.382 -10.242 0.308 1.00 0.00 H ATOM 2056 HG23 VAL A 121 5.286 -11.024 1.885 1.00 0.00 H ATOM 2057 H VAL A 121 6.867 -7.086 3.254 1.00 53.78 H ATOM 2058 HA VAL A 121 7.312 -9.875 2.882 1.00 51.38 H ATOM 2059 N GLN A 122 8.141 -10.243 0.458 1.00 44.81 N ATOM 2060 CA GLN A 122 8.956 -10.498 -0.740 1.00 42.04 C ATOM 2061 C GLN A 122 8.236 -10.278 -2.092 1.00 39.32 C ATOM 2062 O GLN A 122 8.815 -10.587 -3.134 1.00 36.79 O ATOM 2063 CB GLN A 122 9.623 -11.888 -0.629 1.00 0.00 C ATOM 2064 CG GLN A 122 10.710 -11.933 0.468 1.00 0.00 C ATOM 2065 CD GLN A 122 11.475 -13.258 0.585 1.00 0.00 C ATOM 2066 OE1 GLN A 122 12.207 -13.453 1.552 1.00 0.00 O ATOM 2067 NE2 GLN A 122 11.336 -14.172 -0.379 1.00 0.00 N ATOM 2068 HB2 GLN A 122 8.863 -12.647 -0.434 1.00 0.00 H ATOM 2069 HB3 GLN A 122 10.080 -12.150 -1.584 1.00 0.00 H ATOM 2070 HG2 GLN A 122 11.445 -11.148 0.287 1.00 0.00 H ATOM 2071 HG3 GLN A 122 10.265 -11.717 1.440 1.00 0.00 H ATOM 2072 HE22 GLN A 122 11.833 -15.049 -0.318 1.00 0.00 H ATOM 2073 HE21 GLN A 122 10.737 -13.995 -1.172 1.00 0.00 H ATOM 2074 H GLN A 122 7.758 -11.058 0.915 1.00 44.81 H ATOM 2075 HA GLN A 122 9.767 -9.767 -0.747 1.00 42.04 H ATOM 2076 N LEU A 123 7.025 -9.695 -2.064 1.00 88.08 N ATOM 2077 CA LEU A 123 6.254 -9.252 -3.231 1.00 87.90 C ATOM 2078 C LEU A 123 6.937 -8.227 -4.183 1.00 87.49 C ATOM 2079 O LEU A 123 6.728 -8.380 -5.387 1.00 87.89 O ATOM 2080 CB LEU A 123 4.860 -8.768 -2.745 1.00 88.28 C ATOM 2081 CG LEU A 123 3.907 -8.152 -3.802 1.00 87.95 C ATOM 2082 CD1 LEU A 123 3.557 -9.146 -4.932 1.00 89.97 C ATOM 2083 CD2 LEU A 123 2.659 -7.541 -3.128 1.00 87.51 C ATOM 2084 HA LEU A 123 6.093 -10.152 -3.828 1.00 87.90 H ATOM 2085 HB3 LEU A 123 5.012 -8.020 -1.968 1.00 88.28 H ATOM 2086 HB2 LEU A 123 4.350 -9.598 -2.253 1.00 88.28 H ATOM 2087 HG LEU A 123 4.415 -7.306 -4.264 1.00 87.95 H ATOM 2088 HD11 LEU A 123 2.486 -9.250 -5.086 1.00 89.97 H ATOM 2089 HD12 LEU A 123 3.979 -8.818 -5.882 1.00 89.97 H ATOM 2090 HD13 LEU A 123 3.941 -10.146 -4.735 1.00 89.97 H ATOM 2091 HD21 LEU A 123 2.570 -6.481 -3.368 1.00 87.51 H ATOM 2092 HD22 LEU A 123 1.734 -8.015 -3.442 1.00 87.51 H ATOM 2093 HD23 LEU A 123 2.696 -7.621 -2.041 1.00 87.51 H ATOM 2094 H LEU A 123 6.626 -9.462 -1.166 1.00 88.08 H ATOM 2095 N PRO A 124 7.720 -7.229 -3.688 1.00 86.20 N ATOM 2096 CA PRO A 124 8.282 -6.144 -4.519 1.00 84.78 C ATOM 2097 C PRO A 124 9.047 -6.506 -5.801 1.00 82.20 C ATOM 2098 O PRO A 124 8.938 -5.746 -6.753 1.00 81.39 O ATOM 2099 CB PRO A 124 9.145 -5.322 -3.554 1.00 84.32 C ATOM 2100 CG PRO A 124 8.406 -5.454 -2.240 1.00 86.25 C ATOM 2101 CD PRO A 124 7.948 -6.904 -2.280 1.00 86.44 C ATOM 2102 HA PRO A 124 7.439 -5.514 -4.798 1.00 84.78 H ATOM 2103 HB3 PRO A 124 9.255 -4.282 -3.865 1.00 84.32 H ATOM 2104 HB2 PRO A 124 10.143 -5.753 -3.464 1.00 84.32 H ATOM 2105 HG3 PRO A 124 7.539 -4.792 -2.235 1.00 86.25 H ATOM 2106 HG2 PRO A 124 9.018 -5.218 -1.368 1.00 86.25 H ATOM 2107 HD2 PRO A 124 8.760 -7.535 -1.924 1.00 86.44 H ATOM 2108 HD3 PRO A 124 7.072 -7.046 -1.648 1.00 86.44 H ATOM 2109 N ARG A 125 9.778 -7.632 -5.851 1.00 79.64 N ATOM 2110 CA ARG A 125 10.539 -8.019 -7.049 1.00 77.52 C ATOM 2111 C ARG A 125 9.675 -8.545 -8.211 1.00 73.96 C ATOM 2112 O ARG A 125 10.087 -8.385 -9.361 1.00 73.42 O ATOM 2113 CB ARG A 125 11.666 -8.997 -6.664 1.00 78.43 C ATOM 2114 CG ARG A 125 12.755 -8.317 -5.814 1.00 81.81 C ATOM 2115 CD ARG A 125 13.671 -7.398 -6.650 1.00 85.36 C ATOM 2116 NE ARG A 125 14.476 -6.490 -5.819 1.00 87.58 N ATOM 2117 CZ ARG A 125 14.162 -5.229 -5.459 1.00 86.50 C ATOM 2118 NH1 ARG A 125 13.009 -4.639 -5.819 1.00 88.64 N ATOM 2119 NH2 ARG A 125 15.036 -4.540 -4.717 1.00 85.39 N1+ ATOM 2120 H ARG A 125 9.828 -8.248 -5.052 1.00 79.64 H ATOM 2121 HA ARG A 125 11.003 -7.116 -7.446 1.00 77.52 H ATOM 2122 HB3 ARG A 125 12.133 -9.404 -7.562 1.00 78.43 H ATOM 2123 HB2 ARG A 125 11.247 -9.851 -6.129 1.00 78.43 H ATOM 2124 HG3 ARG A 125 13.373 -9.132 -5.434 1.00 81.81 H ATOM 2125 HG2 ARG A 125 12.354 -7.818 -4.931 1.00 81.81 H ATOM 2126 HD3 ARG A 125 13.177 -6.901 -7.484 1.00 85.36 H ATOM 2127 HD2 ARG A 125 14.426 -8.036 -7.112 1.00 85.36 H ATOM 2128 HE ARG A 125 15.345 -6.876 -5.477 1.00 87.58 H ATOM 2129 HH12 ARG A 125 12.805 -3.692 -5.535 1.00 88.64 H ATOM 2130 HH11 ARG A 125 12.337 -5.144 -6.379 1.00 88.64 H ATOM 2131 HH22 ARG A 125 14.861 -3.571 -4.482 1.00 85.39 H ATOM 2132 HH21 ARG A 125 15.909 -4.958 -4.429 1.00 85.39 H ATOM 2133 N GLY A 126 8.485 -9.094 -7.915 1.00 68.96 N ATOM 2134 CA GLY A 126 7.486 -9.423 -8.932 1.00 64.52 C ATOM 2135 C GLY A 126 6.666 -8.174 -9.282 1.00 60.87 C ATOM 2136 O GLY A 126 6.365 -7.951 -10.455 1.00 59.23 O ATOM 2137 H GLY A 126 8.205 -9.184 -6.948 1.00 68.96 H ATOM 2138 HA3 GLY A 126 6.818 -10.191 -8.542 1.00 64.52 H ATOM 2139 HA2 GLY A 126 7.950 -9.826 -9.832 1.00 64.52 H ATOM 2140 N MET A 127 6.327 -7.359 -8.267 1.00 55.35 N ATOM 2141 CA MET A 127 5.510 -6.152 -8.372 1.00 52.74 C ATOM 2142 C MET A 127 6.165 -5.017 -9.186 1.00 50.36 C ATOM 2143 O MET A 127 5.475 -4.407 -9.998 1.00 50.22 O ATOM 2144 CB MET A 127 5.061 -5.737 -6.950 1.00 52.06 C ATOM 2145 CG MET A 127 4.494 -4.318 -6.817 1.00 52.58 C ATOM 2146 SD MET A 127 3.661 -3.938 -5.258 1.00 57.02 S ATOM 2147 CE MET A 127 3.291 -2.196 -5.596 1.00 52.47 C ATOM 2148 H MET A 127 6.607 -7.613 -7.329 1.00 55.35 H ATOM 2149 HA MET A 127 4.607 -6.426 -8.921 1.00 52.74 H ATOM 2150 HB3 MET A 127 5.915 -5.810 -6.284 1.00 52.06 H ATOM 2151 HB2 MET A 127 4.341 -6.459 -6.569 1.00 52.06 H ATOM 2152 HG3 MET A 127 3.792 -4.119 -7.627 1.00 52.58 H ATOM 2153 HG2 MET A 127 5.316 -3.609 -6.906 1.00 52.58 H ATOM 2154 HE1 MET A 127 2.789 -1.734 -4.749 1.00 52.47 H ATOM 2155 HE2 MET A 127 4.213 -1.646 -5.788 1.00 52.47 H ATOM 2156 HE3 MET A 127 2.646 -2.104 -6.470 1.00 52.47 H ATOM 2157 N VAL A 128 7.469 -4.767 -8.976 1.00 48.87 N ATOM 2158 CA VAL A 128 8.261 -3.751 -9.683 1.00 49.35 C ATOM 2159 C VAL A 128 8.423 -4.050 -11.187 1.00 48.69 C ATOM 2160 O VAL A 128 8.391 -3.115 -11.987 1.00 46.69 O ATOM 2161 CB VAL A 128 9.657 -3.561 -9.013 1.00 49.83 C ATOM 2162 CG1 VAL A 128 10.754 -2.896 -9.876 1.00 51.17 C ATOM 2163 CG2 VAL A 128 9.503 -2.804 -7.679 1.00 50.76 C ATOM 2164 H VAL A 128 7.966 -5.297 -8.270 1.00 48.87 H ATOM 2165 HA VAL A 128 7.716 -2.808 -9.605 1.00 49.35 H ATOM 2166 HB VAL A 128 10.045 -4.550 -8.767 1.00 49.83 H ATOM 2167 HG11 VAL A 128 11.627 -2.635 -9.278 1.00 51.17 H ATOM 2168 HG12 VAL A 128 11.102 -3.562 -10.667 1.00 51.17 H ATOM 2169 HG13 VAL A 128 10.396 -1.981 -10.349 1.00 51.17 H ATOM 2170 HG21 VAL A 128 10.460 -2.700 -7.169 1.00 50.76 H ATOM 2171 HG22 VAL A 128 9.085 -1.811 -7.830 1.00 50.76 H ATOM 2172 HG23 VAL A 128 8.823 -3.304 -6.994 1.00 50.76 H ATOM 2173 N LYS A 129 8.542 -5.341 -11.541 1.00 48.34 N ATOM 2174 CA LYS A 129 8.550 -5.817 -12.923 1.00 48.30 C ATOM 2175 C LYS A 129 7.172 -5.654 -13.590 1.00 48.23 C ATOM 2176 O LYS A 129 7.107 -5.203 -14.731 1.00 45.86 O ATOM 2177 CB LYS A 129 9.037 -7.278 -12.941 1.00 48.73 C ATOM 2178 CG LYS A 129 9.207 -7.869 -14.353 1.00 51.59 C ATOM 2179 CD LYS A 129 9.624 -9.344 -14.367 1.00 53.41 C ATOM 2180 CE LYS A 129 10.930 -9.624 -13.603 1.00 55.96 C ATOM 2181 NZ LYS A 129 11.434 -10.985 -13.831 1.00 59.17 N1+ ATOM 2182 H LYS A 129 8.555 -6.053 -10.825 1.00 48.34 H ATOM 2183 HA LYS A 129 9.269 -5.214 -13.483 1.00 48.30 H ATOM 2184 HB3 LYS A 129 8.353 -7.904 -12.366 1.00 48.73 H ATOM 2185 HB2 LYS A 129 9.994 -7.321 -12.421 1.00 48.73 H ATOM 2186 HG3 LYS A 129 9.940 -7.284 -14.905 1.00 51.59 H ATOM 2187 HG2 LYS A 129 8.274 -7.785 -14.908 1.00 51.59 H ATOM 2188 HD3 LYS A 129 9.718 -9.670 -15.403 1.00 53.41 H ATOM 2189 HD2 LYS A 129 8.803 -9.919 -13.945 1.00 53.41 H ATOM 2190 HE3 LYS A 129 10.790 -9.484 -12.531 1.00 55.96 H ATOM 2191 HE2 LYS A 129 11.700 -8.933 -13.929 1.00 55.96 H ATOM 2192 HZ1 LYS A 129 12.264 -11.143 -13.274 1.00 59.17 H ATOM 2193 HZ2 LYS A 129 10.720 -11.655 -13.575 1.00 59.17 H ATOM 2194 HZ3 LYS A 129 11.657 -11.099 -14.811 1.00 59.17 H ATOM 2195 N SER A 130 6.098 -5.990 -12.854 1.00 47.46 N ATOM 2196 CA SER A 130 4.710 -5.864 -13.303 1.00 46.31 C ATOM 2197 C SER A 130 4.299 -4.398 -13.549 1.00 47.15 C ATOM 2198 O SER A 130 3.624 -4.127 -14.541 1.00 47.13 O ATOM 2199 CB SER A 130 3.776 -6.533 -12.279 1.00 46.14 C ATOM 2200 OG SER A 130 4.014 -7.921 -12.207 1.00 47.47 O ATOM 2201 H SER A 130 6.233 -6.357 -11.921 1.00 47.46 H ATOM 2202 HA SER A 130 4.614 -6.394 -14.253 1.00 46.31 H ATOM 2203 HB3 SER A 130 2.737 -6.402 -12.577 1.00 46.14 H ATOM 2204 HB2 SER A 130 3.884 -6.095 -11.287 1.00 46.14 H ATOM 2205 HG SER A 130 4.786 -8.070 -11.650 1.00 47.47 H ATOM 2206 N LEU A 131 4.759 -3.486 -12.673 1.00 45.69 N ATOM 2207 CA LEU A 131 4.622 -2.033 -12.795 1.00 46.04 C ATOM 2208 C LEU A 131 5.350 -1.488 -14.031 1.00 46.59 C ATOM 2209 O LEU A 131 4.723 -0.770 -14.807 1.00 47.75 O ATOM 2210 CB LEU A 131 5.154 -1.347 -11.516 1.00 45.55 C ATOM 2211 CG LEU A 131 4.169 -1.380 -10.329 1.00 44.29 C ATOM 2212 CD1 LEU A 131 4.916 -1.210 -8.993 1.00 39.87 C ATOM 2213 CD2 LEU A 131 3.034 -0.346 -10.502 1.00 35.61 C ATOM 2214 H LEU A 131 5.284 -3.806 -11.869 1.00 45.69 H ATOM 2215 HA LEU A 131 3.560 -1.804 -12.909 1.00 46.04 H ATOM 2216 HB3 LEU A 131 5.422 -0.307 -11.713 1.00 45.55 H ATOM 2217 HB2 LEU A 131 6.088 -1.832 -11.235 1.00 45.55 H ATOM 2218 HG LEU A 131 3.708 -2.367 -10.299 1.00 44.29 H ATOM 2219 HD11 LEU A 131 4.417 -0.536 -8.298 1.00 39.87 H ATOM 2220 HD12 LEU A 131 4.998 -2.167 -8.491 1.00 39.87 H ATOM 2221 HD13 LEU A 131 5.932 -0.847 -9.138 1.00 39.87 H ATOM 2222 HD21 LEU A 131 2.956 0.345 -9.665 1.00 35.61 H ATOM 2223 HD22 LEU A 131 3.170 0.263 -11.397 1.00 35.61 H ATOM 2224 HD23 LEU A 131 2.065 -0.831 -10.588 1.00 35.61 H ATOM 2225 N LEU A 132 6.636 -1.852 -14.201 1.00 46.97 N ATOM 2226 CA LEU A 132 7.478 -1.422 -15.322 1.00 48.43 C ATOM 2227 C LEU A 132 6.930 -1.856 -16.693 1.00 47.96 C ATOM 2228 O LEU A 132 6.948 -1.041 -17.613 1.00 49.40 O ATOM 2229 CB LEU A 132 8.935 -1.898 -15.108 1.00 49.60 C ATOM 2230 CG LEU A 132 9.934 -1.487 -16.221 1.00 51.40 C ATOM 2231 CD1 LEU A 132 10.083 0.044 -16.340 1.00 51.34 C ATOM 2232 CD2 LEU A 132 11.284 -2.207 -16.054 1.00 47.15 C ATOM 2233 H LEU A 132 7.081 -2.445 -13.514 1.00 46.97 H ATOM 2234 HA LEU A 132 7.475 -0.331 -15.307 1.00 48.43 H ATOM 2235 HB3 LEU A 132 8.932 -2.987 -15.025 1.00 49.60 H ATOM 2236 HB2 LEU A 132 9.300 -1.529 -14.149 1.00 49.60 H ATOM 2237 HG LEU A 132 9.551 -1.828 -17.181 1.00 51.40 H ATOM 2238 HD11 LEU A 132 11.113 0.362 -16.498 1.00 51.34 H ATOM 2239 HD12 LEU A 132 9.509 0.416 -17.189 1.00 51.34 H ATOM 2240 HD13 LEU A 132 9.717 0.561 -15.453 1.00 51.34 H ATOM 2241 HD21 LEU A 132 12.126 -1.520 -16.061 1.00 47.15 H ATOM 2242 HD22 LEU A 132 11.332 -2.772 -15.124 1.00 47.15 H ATOM 2243 HD23 LEU A 132 11.457 -2.912 -16.865 1.00 47.15 H ATOM 2244 N TYR A 133 6.441 -3.106 -16.799 1.00 48.25 N ATOM 2245 CA TYR A 133 5.857 -3.646 -18.028 1.00 48.33 C ATOM 2246 C TYR A 133 4.589 -2.890 -18.463 1.00 48.21 C ATOM 2247 O TYR A 133 4.450 -2.588 -19.646 1.00 47.90 O ATOM 2248 CB TYR A 133 5.573 -5.155 -17.878 1.00 48.12 C ATOM 2249 CG TYR A 133 5.155 -5.813 -19.181 1.00 50.39 C ATOM 2250 CD1 TYR A 133 6.129 -6.099 -20.162 1.00 51.12 C ATOM 2251 CD2 TYR A 133 3.795 -6.077 -19.448 1.00 52.98 C ATOM 2252 CE1 TYR A 133 5.746 -6.631 -21.407 1.00 55.60 C ATOM 2253 CE2 TYR A 133 3.412 -6.603 -20.697 1.00 54.12 C ATOM 2254 CZ TYR A 133 4.386 -6.877 -21.678 1.00 57.97 C ATOM 2255 OH TYR A 133 4.011 -7.375 -22.891 1.00 60.96 O ATOM 2256 H TYR A 133 6.470 -3.727 -16.001 1.00 48.25 H ATOM 2257 HA TYR A 133 6.602 -3.521 -18.817 1.00 48.33 H ATOM 2258 HB3 TYR A 133 4.809 -5.326 -17.117 1.00 48.12 H ATOM 2259 HB2 TYR A 133 6.461 -5.670 -17.518 1.00 48.12 H ATOM 2260 HD1 TYR A 133 7.170 -5.888 -19.969 1.00 51.12 H ATOM 2261 HD2 TYR A 133 3.040 -5.849 -18.710 1.00 52.98 H ATOM 2262 HE1 TYR A 133 6.499 -6.836 -22.154 1.00 55.60 H ATOM 2263 HE2 TYR A 133 2.367 -6.787 -20.904 1.00 54.12 H ATOM 2264 HH TYR A 133 4.752 -7.538 -23.478 1.00 60.96 H ATOM 2265 N GLN A 134 3.711 -2.587 -17.494 1.00 46.87 N ATOM 2266 CA GLN A 134 2.471 -1.845 -17.707 1.00 46.59 C ATOM 2267 C GLN A 134 2.690 -0.353 -18.018 1.00 45.45 C ATOM 2268 O GLN A 134 1.943 0.196 -18.827 1.00 48.97 O ATOM 2269 CB GLN A 134 1.544 -2.048 -16.498 1.00 45.39 C ATOM 2270 CG GLN A 134 0.964 -3.472 -16.413 1.00 45.89 C ATOM 2271 CD GLN A 134 0.035 -3.664 -15.214 1.00 48.73 C ATOM 2272 OE1 GLN A 134 -0.856 -2.854 -14.973 1.00 46.45 O ATOM 2273 NE2 GLN A 134 0.208 -4.765 -14.482 1.00 46.33 N ATOM 2274 H GLN A 134 3.900 -2.872 -16.542 1.00 46.87 H ATOM 2275 HA GLN A 134 1.974 -2.275 -18.580 1.00 46.59 H ATOM 2276 HB3 GLN A 134 0.722 -1.343 -16.577 1.00 45.39 H ATOM 2277 HB2 GLN A 134 2.076 -1.805 -15.576 1.00 45.39 H ATOM 2278 HG3 GLN A 134 1.764 -4.212 -16.387 1.00 45.89 H ATOM 2279 HG2 GLN A 134 0.384 -3.679 -17.309 1.00 45.89 H ATOM 2280 HE22 GLN A 134 -0.413 -4.957 -13.708 1.00 46.33 H ATOM 2281 HE21 GLN A 134 0.939 -5.426 -14.704 1.00 46.33 H ATOM 2282 N ILE A 135 3.733 0.260 -17.427 1.00 44.30 N ATOM 2283 CA ILE A 135 4.197 1.612 -17.755 1.00 44.52 C ATOM 2284 C ILE A 135 4.720 1.699 -19.203 1.00 45.40 C ATOM 2285 O ILE A 135 4.323 2.610 -19.926 1.00 43.80 O ATOM 2286 CB ILE A 135 5.294 2.112 -16.763 1.00 44.44 C ATOM 2287 CG1 ILE A 135 4.694 2.397 -15.369 1.00 45.08 C ATOM 2288 CG2 ILE A 135 6.102 3.347 -17.227 1.00 42.22 C ATOM 2289 CD1 ILE A 135 5.736 2.394 -14.237 1.00 43.54 C ATOM 2290 H ILE A 135 4.288 -0.249 -16.751 1.00 44.30 H ATOM 2291 HA ILE A 135 3.339 2.281 -17.670 1.00 44.52 H ATOM 2292 HB ILE A 135 6.008 1.295 -16.646 1.00 44.44 H ATOM 2293 HG13 ILE A 135 3.927 1.662 -15.128 1.00 45.08 H ATOM 2294 HG12 ILE A 135 4.174 3.355 -15.387 1.00 45.08 H ATOM 2295 HG21 ILE A 135 6.794 3.684 -16.456 1.00 42.22 H ATOM 2296 HG22 ILE A 135 6.709 3.132 -18.107 1.00 42.22 H ATOM 2297 HG23 ILE A 135 5.444 4.184 -17.466 1.00 42.22 H ATOM 2298 HD11 ILE A 135 5.417 1.747 -13.421 1.00 43.54 H ATOM 2299 HD12 ILE A 135 6.711 2.034 -14.569 1.00 43.54 H ATOM 2300 HD13 ILE A 135 5.877 3.396 -13.833 1.00 43.54 H ATOM 2301 N LEU A 136 5.559 0.728 -19.606 1.00 45.39 N ATOM 2302 CA LEU A 136 6.096 0.597 -20.962 1.00 47.80 C ATOM 2303 C LEU A 136 5.011 0.344 -22.022 1.00 47.10 C ATOM 2304 O LEU A 136 5.125 0.897 -23.112 1.00 43.62 O ATOM 2305 CB LEU A 136 7.151 -0.529 -20.997 1.00 48.24 C ATOM 2306 CG LEU A 136 8.516 -0.138 -20.394 1.00 46.29 C ATOM 2307 CD1 LEU A 136 9.366 -1.392 -20.128 1.00 45.06 C ATOM 2308 CD2 LEU A 136 9.268 0.869 -21.285 1.00 45.18 C ATOM 2309 H LEU A 136 5.843 0.014 -18.948 1.00 45.39 H ATOM 2310 HA LEU A 136 6.576 1.542 -21.221 1.00 47.80 H ATOM 2311 HB3 LEU A 136 7.321 -0.843 -22.026 1.00 48.24 H ATOM 2312 HB2 LEU A 136 6.751 -1.406 -20.488 1.00 48.24 H ATOM 2313 HG LEU A 136 8.342 0.335 -19.427 1.00 46.29 H ATOM 2314 HD11 LEU A 136 10.246 -1.152 -19.530 1.00 45.06 H ATOM 2315 HD12 LEU A 136 8.800 -2.150 -19.586 1.00 45.06 H ATOM 2316 HD13 LEU A 136 9.705 -1.846 -21.059 1.00 45.06 H ATOM 2317 HD21 LEU A 136 10.326 0.625 -21.380 1.00 45.18 H ATOM 2318 HD22 LEU A 136 8.849 0.906 -22.289 1.00 45.18 H ATOM 2319 HD23 LEU A 136 9.205 1.877 -20.881 1.00 45.18 H ATOM 2320 N ASP A 137 3.982 -0.454 -21.686 1.00 48.40 N ATOM 2321 CA ASP A 137 2.852 -0.784 -22.559 1.00 48.99 C ATOM 2322 C ASP A 137 1.917 0.428 -22.769 1.00 50.85 C ATOM 2323 O ASP A 137 1.474 0.659 -23.895 1.00 52.32 O ATOM 2324 CB ASP A 137 2.096 -2.032 -22.027 1.00 50.08 C ATOM 2325 CG ASP A 137 1.053 -2.691 -22.951 1.00 51.33 C ATOM 2326 OD1 ASP A 137 1.067 -2.440 -24.176 1.00 50.04 O ATOM 2327 OD2 ASP A 137 0.299 -3.537 -22.424 1.00 49.97 O1- ATOM 2328 H ASP A 137 3.979 -0.896 -20.776 1.00 48.40 H ATOM 2329 HA ASP A 137 3.273 -1.034 -23.533 1.00 48.99 H ATOM 2330 HB3 ASP A 137 1.625 -1.787 -21.074 1.00 50.08 H ATOM 2331 HB2 ASP A 137 2.830 -2.800 -21.783 1.00 50.08 H ATOM 2332 N GLY A 138 1.667 1.202 -21.697 1.00 51.07 N ATOM 2333 CA GLY A 138 0.834 2.404 -21.734 1.00 49.89 C ATOM 2334 C GLY A 138 1.515 3.541 -22.510 1.00 49.02 C ATOM 2335 O GLY A 138 0.847 4.205 -23.300 1.00 47.55 O ATOM 2336 H GLY A 138 2.062 0.946 -20.802 1.00 51.07 H ATOM 2337 HA3 GLY A 138 0.631 2.729 -20.715 1.00 49.89 H ATOM 2338 HA2 GLY A 138 -0.132 2.175 -22.186 1.00 49.89 H ATOM 2339 N ILE A 139 2.836 3.736 -22.328 1.00 49.08 N ATOM 2340 CA ILE A 139 3.634 4.712 -23.080 1.00 49.75 C ATOM 2341 C ILE A 139 3.870 4.294 -24.546 1.00 49.21 C ATOM 2342 O ILE A 139 3.904 5.175 -25.403 1.00 48.82 O ATOM 2343 CB ILE A 139 4.995 5.035 -22.380 1.00 50.72 C ATOM 2344 CG1 ILE A 139 4.792 5.760 -21.028 1.00 55.85 C ATOM 2345 CG2 ILE A 139 6.010 5.824 -23.236 1.00 49.32 C ATOM 2346 CD1 ILE A 139 3.984 7.067 -21.082 1.00 59.87 C ATOM 2347 H ILE A 139 3.338 3.169 -21.656 1.00 49.08 H ATOM 2348 HA ILE A 139 3.054 5.635 -23.130 1.00 49.75 H ATOM 2349 HB ILE A 139 5.471 4.081 -22.144 1.00 50.72 H ATOM 2350 HG13 ILE A 139 5.757 5.954 -20.562 1.00 55.85 H ATOM 2351 HG12 ILE A 139 4.288 5.084 -20.347 1.00 55.85 H ATOM 2352 HG21 ILE A 139 6.886 6.113 -22.659 1.00 49.32 H ATOM 2353 HG22 ILE A 139 6.378 5.237 -24.078 1.00 49.32 H ATOM 2354 HG23 ILE A 139 5.564 6.737 -23.629 1.00 49.32 H ATOM 2355 HD11 ILE A 139 4.150 7.664 -20.187 1.00 59.87 H ATOM 2356 HD12 ILE A 139 4.250 7.682 -21.942 1.00 59.87 H ATOM 2357 HD13 ILE A 139 2.916 6.861 -21.131 1.00 59.87 H ATOM 2358 N HIS A 140 3.968 2.980 -24.825 1.00 50.17 N ATOM 2359 CA HIS A 140 4.035 2.433 -26.184 1.00 51.07 C ATOM 2360 C HIS A 140 2.762 2.719 -26.997 1.00 48.66 C ATOM 2361 O HIS A 140 2.883 3.063 -28.171 1.00 46.44 O ATOM 2362 CB HIS A 140 4.358 0.922 -26.155 1.00 51.01 C ATOM 2363 CG HIS A 140 4.385 0.250 -27.509 1.00 56.82 C ATOM 2364 ND1 HIS A 140 3.780 -0.971 -27.751 1.00 60.29 N ATOM 2365 CD2 HIS A 140 4.911 0.646 -28.720 1.00 61.32 C ATOM 2366 CE1 HIS A 140 3.934 -1.238 -29.050 1.00 65.42 C ATOM 2367 NE2 HIS A 140 4.607 -0.299 -29.703 1.00 64.08 N ATOM 2368 H HIS A 140 3.964 2.304 -24.072 1.00 50.17 H ATOM 2369 HA HIS A 140 4.851 2.941 -26.698 1.00 51.07 H ATOM 2370 HB3 HIS A 140 3.639 0.399 -25.524 1.00 51.01 H ATOM 2371 HB2 HIS A 140 5.335 0.760 -25.701 1.00 51.01 H ATOM 2372 HD1 HIS A 140 3.271 -1.531 -27.082 1.00 60.29 H ATOM 2373 HD2 HIS A 140 5.457 1.546 -28.964 1.00 61.32 H ATOM 2374 HE1 HIS A 140 3.543 -2.126 -29.525 1.00 65.42 H ATOM 2375 N TYR A 141 1.582 2.616 -26.359 1.00 46.92 N ATOM 2376 CA TYR A 141 0.302 2.966 -26.976 1.00 47.51 C ATOM 2377 C TYR A 141 0.214 4.456 -27.352 1.00 48.69 C ATOM 2378 O TYR A 141 -0.227 4.766 -28.458 1.00 48.29 O ATOM 2379 CB TYR A 141 -0.869 2.532 -26.072 1.00 47.25 C ATOM 2380 CG TYR A 141 -2.232 2.933 -26.610 1.00 45.22 C ATOM 2381 CD1 TYR A 141 -2.803 2.211 -27.678 1.00 47.44 C ATOM 2382 CD2 TYR A 141 -2.902 4.059 -26.087 1.00 44.33 C ATOM 2383 CE1 TYR A 141 -4.027 2.626 -28.237 1.00 45.28 C ATOM 2384 CE2 TYR A 141 -4.132 4.464 -26.637 1.00 45.69 C ATOM 2385 CZ TYR A 141 -4.685 3.761 -27.725 1.00 44.76 C ATOM 2386 OH TYR A 141 -5.854 4.183 -28.287 1.00 44.71 O ATOM 2387 H TYR A 141 1.556 2.332 -25.389 1.00 46.92 H ATOM 2388 HA TYR A 141 0.229 2.393 -27.903 1.00 47.51 H ATOM 2389 HB3 TYR A 141 -0.751 2.955 -25.073 1.00 47.25 H ATOM 2390 HB2 TYR A 141 -0.850 1.451 -25.939 1.00 47.25 H ATOM 2391 HD1 TYR A 141 -2.292 1.351 -28.086 1.00 47.44 H ATOM 2392 HD2 TYR A 141 -2.470 4.621 -25.271 1.00 44.33 H ATOM 2393 HE1 TYR A 141 -4.450 2.078 -29.066 1.00 45.28 H ATOM 2394 HE2 TYR A 141 -4.645 5.319 -26.228 1.00 45.69 H ATOM 2395 HH TYR A 141 -6.143 3.629 -29.016 1.00 44.71 H ATOM 2396 N LEU A 142 0.663 5.337 -26.441 1.00 48.21 N ATOM 2397 CA LEU A 142 0.733 6.781 -26.661 1.00 49.39 C ATOM 2398 C LEU A 142 1.693 7.130 -27.815 1.00 48.97 C ATOM 2399 O LEU A 142 1.280 7.843 -28.726 1.00 48.48 O ATOM 2400 CB LEU A 142 1.124 7.502 -25.347 1.00 48.79 C ATOM 2401 CG LEU A 142 0.082 7.415 -24.205 1.00 48.84 C ATOM 2402 CD1 LEU A 142 0.695 7.831 -22.849 1.00 52.40 C ATOM 2403 CD2 LEU A 142 -1.214 8.190 -24.523 1.00 45.02 C ATOM 2404 H LEU A 142 1.009 5.003 -25.552 1.00 48.21 H ATOM 2405 HA LEU A 142 -0.262 7.114 -26.962 1.00 49.39 H ATOM 2406 HB3 LEU A 142 1.314 8.557 -25.544 1.00 48.79 H ATOM 2407 HB2 LEU A 142 2.073 7.093 -25.000 1.00 48.79 H ATOM 2408 HG LEU A 142 -0.205 6.370 -24.105 1.00 48.84 H ATOM 2409 HD11 LEU A 142 0.693 6.990 -22.155 1.00 52.40 H ATOM 2410 HD12 LEU A 142 1.729 8.162 -22.952 1.00 52.40 H ATOM 2411 HD13 LEU A 142 0.155 8.643 -22.363 1.00 52.40 H ATOM 2412 HD21 LEU A 142 -1.403 9.009 -23.830 1.00 45.02 H ATOM 2413 HD22 LEU A 142 -1.198 8.627 -25.520 1.00 45.02 H ATOM 2414 HD23 LEU A 142 -2.077 7.526 -24.471 1.00 45.02 H ATOM 2415 N HIS A 143 2.922 6.581 -27.786 1.00 48.79 N ATOM 2416 CA HIS A 143 3.965 6.777 -28.801 1.00 48.85 C ATOM 2417 C HIS A 143 3.594 6.260 -30.202 1.00 48.04 C ATOM 2418 O HIS A 143 3.924 6.929 -31.180 1.00 48.29 O ATOM 2419 CB HIS A 143 5.289 6.136 -28.337 1.00 47.82 C ATOM 2420 CG HIS A 143 6.020 6.854 -27.229 1.00 46.89 C ATOM 2421 ND1 HIS A 143 7.260 6.408 -26.760 1.00 43.40 N ATOM 2422 CD2 HIS A 143 5.670 7.996 -26.537 1.00 43.88 C ATOM 2423 CE1 HIS A 143 7.603 7.277 -25.821 1.00 43.96 C ATOM 2424 NE2 HIS A 143 6.702 8.244 -25.653 1.00 37.69 N ATOM 2425 H HIS A 143 3.177 5.992 -27.003 1.00 48.79 H ATOM 2426 HA HIS A 143 4.122 7.853 -28.909 1.00 48.85 H ATOM 2427 HB3 HIS A 143 5.984 6.065 -29.174 1.00 47.82 H ATOM 2428 HB2 HIS A 143 5.110 5.109 -28.014 1.00 47.82 H ATOM 2429 HD2 HIS A 143 4.803 8.634 -26.599 1.00 43.88 H ATOM 2430 HE1 HIS A 143 8.514 7.202 -25.245 1.00 43.96 H ATOM 2431 HE2 HIS A 143 6.750 9.009 -24.988 1.00 37.69 H ATOM 2432 N ALA A 144 2.895 5.115 -30.282 1.00 46.74 N ATOM 2433 CA ALA A 144 2.382 4.539 -31.531 1.00 47.66 C ATOM 2434 C ALA A 144 1.350 5.437 -32.243 1.00 48.93 C ATOM 2435 O ALA A 144 1.275 5.406 -33.471 1.00 48.44 O ATOM 2436 CB ALA A 144 1.789 3.152 -31.241 1.00 42.79 C ATOM 2437 H ALA A 144 2.684 4.599 -29.437 1.00 46.74 H ATOM 2438 HA ALA A 144 3.227 4.410 -32.209 1.00 47.66 H ATOM 2439 HB1 ALA A 144 1.384 2.696 -32.145 1.00 42.79 H ATOM 2440 HB2 ALA A 144 2.550 2.475 -30.851 1.00 42.79 H ATOM 2441 HB3 ALA A 144 0.985 3.206 -30.506 1.00 42.79 H ATOM 2442 N ASN A 145 0.617 6.241 -31.456 1.00 50.22 N ATOM 2443 CA ASN A 145 -0.338 7.254 -31.908 1.00 50.60 C ATOM 2444 C ASN A 145 0.279 8.669 -31.955 1.00 51.73 C ATOM 2445 O ASN A 145 -0.465 9.612 -32.211 1.00 52.80 O ATOM 2446 CB ASN A 145 -1.564 7.201 -30.965 1.00 51.28 C ATOM 2447 CG ASN A 145 -2.440 5.969 -31.207 1.00 46.89 C ATOM 2448 OD1 ASN A 145 -3.004 5.818 -32.286 1.00 49.17 O ATOM 2449 ND2 ASN A 145 -2.577 5.096 -30.209 1.00 48.77 N ATOM 2450 H ASN A 145 0.753 6.191 -30.456 1.00 50.22 H ATOM 2451 HA ASN A 145 -0.656 6.990 -32.919 1.00 50.60 H ATOM 2452 HB3 ASN A 145 -2.209 8.059 -31.144 1.00 51.28 H ATOM 2453 HB2 ASN A 145 -1.260 7.267 -29.919 1.00 51.28 H ATOM 2454 HD22 ASN A 145 -3.159 4.280 -30.330 1.00 48.77 H ATOM 2455 HD21 ASN A 145 -2.068 5.218 -29.343 1.00 48.77 H ATOM 2456 N TRP A 146 1.597 8.815 -31.719 1.00 53.29 N ATOM 2457 CA TRP A 146 2.343 10.085 -31.706 1.00 53.19 C ATOM 2458 C TRP A 146 1.854 11.115 -30.663 1.00 52.03 C ATOM 2459 O TRP A 146 1.926 12.322 -30.898 1.00 52.58 O ATOM 2460 CB TRP A 146 2.487 10.668 -33.130 1.00 55.91 C ATOM 2461 CG TRP A 146 3.494 9.987 -34.001 1.00 59.21 C ATOM 2462 CD1 TRP A 146 3.268 8.946 -34.833 1.00 63.22 C ATOM 2463 CD2 TRP A 146 4.925 10.259 -34.073 1.00 66.54 C ATOM 2464 NE1 TRP A 146 4.455 8.575 -35.435 1.00 67.93 N ATOM 2465 CE2 TRP A 146 5.513 9.351 -35.004 1.00 68.26 C ATOM 2466 CE3 TRP A 146 5.788 11.187 -33.444 1.00 70.24 C ATOM 2467 CZ2 TRP A 146 6.888 9.367 -35.299 1.00 70.79 C ATOM 2468 CZ3 TRP A 146 7.168 11.213 -33.731 1.00 72.99 C ATOM 2469 CH2 TRP A 146 7.718 10.304 -34.657 1.00 73.10 C ATOM 2470 H TRP A 146 2.148 7.990 -31.524 1.00 53.29 H ATOM 2471 HA TRP A 146 3.348 9.842 -31.358 1.00 53.19 H ATOM 2472 HB3 TRP A 146 2.820 11.704 -33.091 1.00 55.91 H ATOM 2473 HB2 TRP A 146 1.527 10.689 -33.639 1.00 55.91 H ATOM 2474 HD1 TRP A 146 2.302 8.487 -34.989 1.00 63.22 H ATOM 2475 HE1 TRP A 146 4.509 7.817 -36.101 1.00 67.93 H ATOM 2476 HE3 TRP A 146 5.380 11.891 -32.733 1.00 70.24 H ATOM 2477 HZ2 TRP A 146 7.303 8.666 -36.008 1.00 70.79 H ATOM 2478 HZ3 TRP A 146 7.806 11.932 -33.239 1.00 72.99 H ATOM 2479 HH2 TRP A 146 8.776 10.328 -34.873 1.00 73.10 H ATOM 2480 N VAL A 147 1.411 10.610 -29.504 1.00 51.17 N ATOM 2481 CA VAL A 147 1.131 11.389 -28.304 1.00 49.42 C ATOM 2482 C VAL A 147 2.317 11.190 -27.345 1.00 49.43 C ATOM 2483 O VAL A 147 2.700 10.051 -27.079 1.00 49.50 O ATOM 2484 CB VAL A 147 -0.176 10.903 -27.609 1.00 50.28 C ATOM 2485 CG1 VAL A 147 -0.459 11.583 -26.252 1.00 46.10 C ATOM 2486 CG2 VAL A 147 -1.394 11.073 -28.537 1.00 46.30 C ATOM 2487 H VAL A 147 1.379 9.605 -29.383 1.00 51.17 H ATOM 2488 HA VAL A 147 1.029 12.450 -28.542 1.00 49.42 H ATOM 2489 HB VAL A 147 -0.085 9.834 -27.411 1.00 50.28 H ATOM 2490 HG11 VAL A 147 -1.427 11.280 -25.854 1.00 46.10 H ATOM 2491 HG12 VAL A 147 0.283 11.322 -25.496 1.00 46.10 H ATOM 2492 HG13 VAL A 147 -0.470 12.669 -26.348 1.00 46.10 H ATOM 2493 HG21 VAL A 147 -2.317 10.771 -28.043 1.00 46.30 H ATOM 2494 HG22 VAL A 147 -1.508 12.111 -28.848 1.00 46.30 H ATOM 2495 HG23 VAL A 147 -1.300 10.466 -29.438 1.00 46.30 H ATOM 2496 N LEU A 148 2.877 12.299 -26.844 1.00 48.99 N ATOM 2497 CA LEU A 148 3.936 12.290 -25.834 1.00 47.89 C ATOM 2498 C LEU A 148 3.324 12.684 -24.484 1.00 47.68 C ATOM 2499 O LEU A 148 2.445 13.549 -24.445 1.00 47.55 O ATOM 2500 CB LEU A 148 5.050 13.283 -26.235 1.00 48.34 C ATOM 2501 CG LEU A 148 5.724 13.006 -27.596 1.00 46.82 C ATOM 2502 CD1 LEU A 148 6.758 14.103 -27.910 1.00 47.75 C ATOM 2503 CD2 LEU A 148 6.346 11.597 -27.672 1.00 41.93 C ATOM 2504 H LEU A 148 2.513 13.206 -27.097 1.00 48.99 H ATOM 2505 HA LEU A 148 4.372 11.295 -25.732 1.00 47.89 H ATOM 2506 HB3 LEU A 148 5.816 13.284 -25.457 1.00 48.34 H ATOM 2507 HB2 LEU A 148 4.638 14.293 -26.257 1.00 48.34 H ATOM 2508 HG LEU A 148 4.966 13.062 -28.379 1.00 46.82 H ATOM 2509 HD11 LEU A 148 7.490 13.783 -28.651 1.00 47.75 H ATOM 2510 HD12 LEU A 148 6.270 14.994 -28.306 1.00 47.75 H ATOM 2511 HD13 LEU A 148 7.305 14.401 -27.015 1.00 47.75 H ATOM 2512 HD21 LEU A 148 7.296 11.593 -28.203 1.00 41.93 H ATOM 2513 HD22 LEU A 148 6.534 11.179 -26.682 1.00 41.93 H ATOM 2514 HD23 LEU A 148 5.684 10.909 -28.198 1.00 41.93 H ATOM 2515 N HIS A 149 3.821 12.065 -23.401 1.00 47.67 N ATOM 2516 CA HIS A 149 3.416 12.385 -22.032 1.00 48.82 C ATOM 2517 C HIS A 149 4.008 13.726 -21.573 1.00 48.79 C ATOM 2518 O HIS A 149 3.258 14.580 -21.110 1.00 49.25 O ATOM 2519 CB HIS A 149 3.799 11.235 -21.083 1.00 48.84 C ATOM 2520 CG HIS A 149 3.074 11.285 -19.761 1.00 50.60 C ATOM 2521 ND1 HIS A 149 3.362 12.225 -18.767 1.00 49.94 N ATOM 2522 CD2 HIS A 149 2.039 10.490 -19.324 1.00 48.91 C ATOM 2523 CE1 HIS A 149 2.495 11.976 -17.796 1.00 49.67 C ATOM 2524 NE2 HIS A 149 1.681 10.959 -18.073 1.00 49.87 N ATOM 2525 H HIS A 149 4.568 11.389 -23.504 1.00 47.67 H ATOM 2526 HA HIS A 149 2.328 12.473 -22.029 1.00 48.82 H ATOM 2527 HB3 HIS A 149 4.875 11.220 -20.904 1.00 48.84 H ATOM 2528 HB2 HIS A 149 3.560 10.279 -21.550 1.00 48.84 H ATOM 2529 HD2 HIS A 149 1.530 9.675 -19.814 1.00 48.91 H ATOM 2530 HE1 HIS A 149 2.443 12.546 -16.883 1.00 49.67 H ATOM 2531 HE2 HIS A 149 0.932 10.618 -17.484 1.00 49.87 H ATOM 2532 N ARG A 150 5.332 13.886 -21.742 1.00 50.74 N ATOM 2533 CA ARG A 150 6.102 15.114 -21.506 1.00 51.82 C ATOM 2534 C ARG A 150 6.258 15.527 -20.024 1.00 52.77 C ATOM 2535 O ARG A 150 6.892 16.551 -19.775 1.00 52.32 O ATOM 2536 CB ARG A 150 5.595 16.276 -22.408 1.00 51.87 C ATOM 2537 CG ARG A 150 5.568 15.894 -23.903 1.00 54.15 C ATOM 2538 CD ARG A 150 5.222 17.023 -24.886 1.00 54.58 C ATOM 2539 NE ARG A 150 3.791 17.361 -24.928 1.00 56.89 N ATOM 2540 CZ ARG A 150 3.173 18.087 -25.878 1.00 61.38 C ATOM 2541 NH1 ARG A 150 3.816 18.603 -26.931 1.00 63.49 N ATOM 2542 NH2 ARG A 150 1.863 18.312 -25.782 1.00 60.00 N1+ ATOM 2543 H ARG A 150 5.869 13.108 -22.105 1.00 50.74 H ATOM 2544 HA ARG A 150 7.114 14.874 -21.833 1.00 51.82 H ATOM 2545 HB3 ARG A 150 6.251 17.138 -22.286 1.00 51.87 H ATOM 2546 HB2 ARG A 150 4.608 16.612 -22.090 1.00 51.87 H ATOM 2547 HG3 ARG A 150 4.796 15.134 -24.005 1.00 54.15 H ATOM 2548 HG2 ARG A 150 6.491 15.410 -24.212 1.00 54.15 H ATOM 2549 HD3 ARG A 150 5.649 16.832 -25.870 1.00 54.58 H ATOM 2550 HD2 ARG A 150 5.675 17.940 -24.517 1.00 54.58 H ATOM 2551 HE ARG A 150 3.232 17.021 -24.155 1.00 56.89 H ATOM 2552 HH12 ARG A 150 3.310 19.136 -27.631 1.00 63.49 H ATOM 2553 HH11 ARG A 150 4.804 18.430 -27.072 1.00 63.49 H ATOM 2554 HH22 ARG A 150 1.400 18.903 -26.464 1.00 60.00 H ATOM 2555 HH21 ARG A 150 1.346 17.956 -24.988 1.00 60.00 H ATOM 2556 N ASP A 151 5.732 14.735 -19.070 1.00 52.99 N ATOM 2557 CA ASP A 151 5.790 15.020 -17.633 1.00 54.08 C ATOM 2558 C ASP A 151 5.644 13.709 -16.827 1.00 53.44 C ATOM 2559 O ASP A 151 4.814 13.632 -15.920 1.00 51.89 O ATOM 2560 CB ASP A 151 4.774 16.136 -17.234 1.00 54.42 C ATOM 2561 CG ASP A 151 4.874 16.727 -15.813 1.00 61.37 C ATOM 2562 OD1 ASP A 151 5.930 16.575 -15.159 1.00 65.15 O ATOM 2563 OD2 ASP A 151 3.913 17.432 -15.437 1.00 69.39 O1- ATOM 2564 H ASP A 151 5.227 13.900 -19.336 1.00 52.99 H ATOM 2565 HA ASP A 151 6.798 15.380 -17.419 1.00 54.08 H ATOM 2566 HB3 ASP A 151 3.760 15.765 -17.396 1.00 54.42 H ATOM 2567 HB2 ASP A 151 4.871 16.971 -17.929 1.00 54.42 H ATOM 2568 N LEU A 152 6.437 12.680 -17.180 1.00 52.73 N ATOM 2569 CA LEU A 152 6.454 11.393 -16.475 1.00 52.36 C ATOM 2570 C LEU A 152 7.199 11.491 -15.134 1.00 50.92 C ATOM 2571 O LEU A 152 8.299 12.040 -15.073 1.00 49.63 O ATOM 2572 CB LEU A 152 7.072 10.299 -17.373 1.00 53.22 C ATOM 2573 CG LEU A 152 6.045 9.594 -18.281 1.00 57.16 C ATOM 2574 CD1 LEU A 152 6.737 8.770 -19.380 1.00 55.28 C ATOM 2575 CD2 LEU A 152 5.027 8.756 -17.476 1.00 56.87 C ATOM 2576 H LEU A 152 7.101 12.790 -17.936 1.00 52.73 H ATOM 2577 HA LEU A 152 5.419 11.122 -16.259 1.00 52.36 H ATOM 2578 HB3 LEU A 152 7.567 9.533 -16.772 1.00 53.22 H ATOM 2579 HB2 LEU A 152 7.858 10.750 -17.978 1.00 53.22 H ATOM 2580 HG LEU A 152 5.498 10.384 -18.790 1.00 57.16 H ATOM 2581 HD11 LEU A 152 6.263 8.953 -20.344 1.00 55.28 H ATOM 2582 HD12 LEU A 152 7.788 9.034 -19.482 1.00 55.28 H ATOM 2583 HD13 LEU A 152 6.698 7.698 -19.191 1.00 55.28 H ATOM 2584 HD21 LEU A 152 4.951 7.728 -17.830 1.00 56.87 H ATOM 2585 HD22 LEU A 152 5.286 8.710 -16.418 1.00 56.87 H ATOM 2586 HD23 LEU A 152 4.030 9.190 -17.544 1.00 56.87 H ATOM 2587 N LYS A 153 6.559 10.930 -14.098 1.00 50.01 N ATOM 2588 CA LYS A 153 6.977 10.929 -12.695 1.00 50.11 C ATOM 2589 C LYS A 153 6.032 9.986 -11.910 1.00 48.70 C ATOM 2590 O LYS A 153 4.913 9.762 -12.378 1.00 49.43 O ATOM 2591 CB LYS A 153 6.981 12.379 -12.136 1.00 49.08 C ATOM 2592 CG LYS A 153 5.621 13.106 -12.197 1.00 51.78 C ATOM 2593 CD LYS A 153 5.741 14.616 -11.943 1.00 57.35 C ATOM 2594 CE LYS A 153 4.403 15.341 -12.155 1.00 60.44 C ATOM 2595 NZ LYS A 153 4.535 16.805 -12.055 1.00 62.82 N1+ ATOM 2596 H LYS A 153 5.665 10.487 -14.263 1.00 50.01 H ATOM 2597 HA LYS A 153 7.992 10.534 -12.688 1.00 50.11 H ATOM 2598 HB3 LYS A 153 7.719 12.963 -12.686 1.00 49.08 H ATOM 2599 HB2 LYS A 153 7.337 12.382 -11.106 1.00 49.08 H ATOM 2600 HG3 LYS A 153 4.934 12.668 -11.472 1.00 51.78 H ATOM 2601 HG2 LYS A 153 5.162 12.957 -13.174 1.00 51.78 H ATOM 2602 HD3 LYS A 153 6.500 15.033 -12.607 1.00 57.35 H ATOM 2603 HD2 LYS A 153 6.097 14.780 -10.924 1.00 57.35 H ATOM 2604 HE3 LYS A 153 3.660 14.994 -11.436 1.00 60.44 H ATOM 2605 HE2 LYS A 153 4.021 15.121 -13.150 1.00 60.44 H ATOM 2606 HZ1 LYS A 153 5.160 17.124 -12.784 1.00 62.82 H ATOM 2607 HZ2 LYS A 153 3.630 17.230 -12.201 1.00 62.82 H ATOM 2608 HZ3 LYS A 153 4.894 17.065 -11.149 1.00 62.82 H ATOM 2609 N PRO A 154 6.465 9.458 -10.736 1.00 47.39 N ATOM 2610 CA PRO A 154 5.668 8.515 -9.915 1.00 47.77 C ATOM 2611 C PRO A 154 4.240 8.947 -9.525 1.00 48.22 C ATOM 2612 O PRO A 154 3.367 8.087 -9.427 1.00 49.05 O ATOM 2613 CB PRO A 154 6.535 8.288 -8.665 1.00 47.71 C ATOM 2614 CG PRO A 154 7.954 8.531 -9.129 1.00 45.56 C ATOM 2615 CD PRO A 154 7.792 9.649 -10.151 1.00 46.45 C ATOM 2616 HA PRO A 154 5.610 7.585 -10.482 1.00 47.77 H ATOM 2617 HB3 PRO A 154 6.417 7.293 -8.239 1.00 47.71 H ATOM 2618 HB2 PRO A 154 6.292 9.011 -7.886 1.00 47.71 H ATOM 2619 HG3 PRO A 154 8.333 7.632 -9.615 1.00 45.56 H ATOM 2620 HG2 PRO A 154 8.636 8.783 -8.316 1.00 45.56 H ATOM 2621 HD2 PRO A 154 7.828 10.621 -9.658 1.00 46.45 H ATOM 2622 HD3 PRO A 154 8.597 9.594 -10.879 1.00 46.45 H ATOM 2623 N ALA A 155 4.018 10.258 -9.329 1.00 49.07 N ATOM 2624 CA ALA A 155 2.710 10.833 -8.993 1.00 50.04 C ATOM 2625 C ALA A 155 1.673 10.735 -10.128 1.00 50.73 C ATOM 2626 O ALA A 155 0.477 10.706 -9.842 1.00 51.58 O ATOM 2627 CB ALA A 155 2.910 12.295 -8.569 1.00 48.64 C ATOM 2628 H ALA A 155 4.782 10.912 -9.419 1.00 49.07 H ATOM 2629 HA ALA A 155 2.311 10.283 -8.138 1.00 50.04 H ATOM 2630 HB1 ALA A 155 1.963 12.756 -8.284 1.00 48.64 H ATOM 2631 HB2 ALA A 155 3.577 12.364 -7.709 1.00 48.64 H ATOM 2632 HB3 ALA A 155 3.340 12.891 -9.375 1.00 48.64 H ATOM 2633 N ASN A 156 2.157 10.670 -11.381 1.00 51.16 N ATOM 2634 CA ASN A 156 1.363 10.555 -12.607 1.00 52.02 C ATOM 2635 C ASN A 156 1.195 9.095 -13.071 1.00 51.35 C ATOM 2636 O ASN A 156 0.417 8.868 -13.998 1.00 51.38 O ATOM 2637 CB ASN A 156 2.017 11.451 -13.691 1.00 53.90 C ATOM 2638 CG ASN A 156 1.765 12.955 -13.493 1.00 55.57 C ATOM 2639 OD1 ASN A 156 1.222 13.391 -12.479 1.00 60.84 O ATOM 2640 ND2 ASN A 156 2.146 13.767 -14.478 1.00 58.02 N ATOM 2641 H ASN A 156 3.159 10.673 -11.515 1.00 51.16 H ATOM 2642 HA ASN A 156 0.368 10.941 -12.385 1.00 52.02 H ATOM 2643 HB3 ASN A 156 1.619 11.197 -14.672 1.00 53.90 H ATOM 2644 HB2 ASN A 156 3.090 11.265 -13.755 1.00 53.90 H ATOM 2645 HD22 ASN A 156 1.951 14.757 -14.421 1.00 58.02 H ATOM 2646 HD21 ASN A 156 2.621 13.410 -15.295 1.00 58.02 H ATOM 2647 N ILE A 157 1.859 8.131 -12.407 1.00 51.38 N ATOM 2648 CA ILE A 157 1.630 6.702 -12.611 1.00 51.11 C ATOM 2649 C ILE A 157 0.691 6.217 -11.489 1.00 49.75 C ATOM 2650 O ILE A 157 1.156 5.865 -10.403 1.00 49.94 O ATOM 2651 CB ILE A 157 2.947 5.864 -12.567 1.00 50.95 C ATOM 2652 CG1 ILE A 157 4.063 6.411 -13.486 1.00 55.14 C ATOM 2653 CG2 ILE A 157 2.680 4.372 -12.869 1.00 50.61 C ATOM 2654 CD1 ILE A 157 3.690 6.547 -14.966 1.00 53.55 C ATOM 2655 H ILE A 157 2.471 8.380 -11.642 1.00 51.38 H ATOM 2656 HA ILE A 157 1.144 6.518 -13.572 1.00 51.11 H ATOM 2657 HB ILE A 157 3.365 5.917 -11.561 1.00 50.95 H ATOM 2658 HG13 ILE A 157 4.950 5.783 -13.396 1.00 55.14 H ATOM 2659 HG12 ILE A 157 4.375 7.387 -13.121 1.00 55.14 H ATOM 2660 HG21 ILE A 157 3.608 3.812 -12.942 1.00 50.61 H ATOM 2661 HG22 ILE A 157 2.078 3.892 -12.098 1.00 50.61 H ATOM 2662 HG23 ILE A 157 2.159 4.248 -13.816 1.00 50.61 H ATOM 2663 HD11 ILE A 157 4.579 6.487 -15.593 1.00 53.55 H ATOM 2664 HD12 ILE A 157 3.021 5.753 -15.284 1.00 53.55 H ATOM 2665 HD13 ILE A 157 3.200 7.501 -15.166 1.00 53.55 H ATOM 2666 N LEU A 158 -0.624 6.229 -11.765 1.00 48.83 N ATOM 2667 CA LEU A 158 -1.647 5.747 -10.835 1.00 48.42 C ATOM 2668 C LEU A 158 -1.703 4.209 -10.834 1.00 49.02 C ATOM 2669 O LEU A 158 -1.287 3.583 -11.809 1.00 46.67 O ATOM 2670 CB LEU A 158 -3.044 6.335 -11.156 1.00 48.20 C ATOM 2671 CG LEU A 158 -3.126 7.797 -11.656 1.00 50.84 C ATOM 2672 CD1 LEU A 158 -4.601 8.237 -11.770 1.00 46.64 C ATOM 2673 CD2 LEU A 158 -2.283 8.794 -10.837 1.00 45.73 C ATOM 2674 H LEU A 158 -0.950 6.520 -12.677 1.00 48.83 H ATOM 2675 HA LEU A 158 -1.377 6.073 -9.834 1.00 48.42 H ATOM 2676 HB3 LEU A 158 -3.643 6.247 -10.250 1.00 48.20 H ATOM 2677 HB2 LEU A 158 -3.541 5.707 -11.892 1.00 48.20 H ATOM 2678 HG LEU A 158 -2.721 7.805 -12.668 1.00 50.84 H ATOM 2679 HD11 LEU A 158 -4.795 8.754 -12.708 1.00 46.64 H ATOM 2680 HD12 LEU A 158 -5.287 7.391 -11.733 1.00 46.64 H ATOM 2681 HD13 LEU A 158 -4.893 8.915 -10.969 1.00 46.64 H ATOM 2682 HD21 LEU A 158 -2.830 9.703 -10.598 1.00 45.73 H ATOM 2683 HD22 LEU A 158 -1.938 8.366 -9.899 1.00 45.73 H ATOM 2684 HD23 LEU A 158 -1.400 9.102 -11.397 1.00 45.73 H ATOM 2685 N VAL A 159 -2.238 3.635 -9.747 1.00 49.95 N ATOM 2686 CA VAL A 159 -2.484 2.201 -9.605 1.00 50.60 C ATOM 2687 C VAL A 159 -3.868 2.021 -8.959 1.00 51.58 C ATOM 2688 O VAL A 159 -4.139 2.606 -7.910 1.00 52.35 O ATOM 2689 CB VAL A 159 -1.405 1.495 -8.727 1.00 50.63 C ATOM 2690 CG1 VAL A 159 -1.684 -0.007 -8.500 1.00 50.60 C ATOM 2691 CG2 VAL A 159 0.015 1.660 -9.303 1.00 48.69 C ATOM 2692 H VAL A 159 -2.557 4.212 -8.979 1.00 49.95 H ATOM 2693 HA VAL A 159 -2.503 1.726 -10.588 1.00 50.60 H ATOM 2694 HB VAL A 159 -1.394 1.972 -7.747 1.00 50.63 H ATOM 2695 HG11 VAL A 159 -0.864 -0.482 -7.961 1.00 50.60 H ATOM 2696 HG12 VAL A 159 -2.584 -0.174 -7.910 1.00 50.60 H ATOM 2697 HG13 VAL A 159 -1.801 -0.533 -9.448 1.00 50.60 H ATOM 2698 HG21 VAL A 159 0.750 1.131 -8.697 1.00 48.69 H ATOM 2699 HG22 VAL A 159 0.076 1.268 -10.318 1.00 48.69 H ATOM 2700 HG23 VAL A 159 0.322 2.705 -9.328 1.00 48.69 H ATOM 2701 N MET A 160 -4.722 1.214 -9.605 1.00 52.73 N ATOM 2702 CA MET A 160 -6.071 0.885 -9.146 1.00 52.71 C ATOM 2703 C MET A 160 -6.046 0.008 -7.881 1.00 53.51 C ATOM 2704 O MET A 160 -5.240 -0.919 -7.795 1.00 49.86 O ATOM 2705 CB MET A 160 -6.813 0.152 -10.279 1.00 53.40 C ATOM 2706 CG MET A 160 -7.057 0.975 -11.557 1.00 49.52 C ATOM 2707 SD MET A 160 -8.166 2.404 -11.416 1.00 53.85 S ATOM 2708 CE MET A 160 -9.754 1.569 -11.170 1.00 49.55 C ATOM 2709 H MET A 160 -4.428 0.768 -10.465 1.00 52.73 H ATOM 2710 HA MET A 160 -6.597 1.813 -8.916 1.00 52.71 H ATOM 2711 HB3 MET A 160 -7.765 -0.238 -9.918 1.00 53.40 H ATOM 2712 HB2 MET A 160 -6.216 -0.716 -10.551 1.00 53.40 H ATOM 2713 HG3 MET A 160 -7.453 0.321 -12.334 1.00 49.52 H ATOM 2714 HG2 MET A 160 -6.108 1.346 -11.937 1.00 49.52 H ATOM 2715 HE1 MET A 160 -10.566 2.296 -11.185 1.00 49.55 H ATOM 2716 HE2 MET A 160 -9.932 0.841 -11.961 1.00 49.55 H ATOM 2717 HE3 MET A 160 -9.771 1.056 -10.210 1.00 49.55 H ATOM 2718 N GLY A 161 -6.969 0.295 -6.951 1.00 55.30 N ATOM 2719 CA GLY A 161 -7.195 -0.487 -5.736 1.00 56.11 C ATOM 2720 C GLY A 161 -8.213 -1.603 -6.014 1.00 56.83 C ATOM 2721 O GLY A 161 -8.392 -2.028 -7.157 1.00 55.73 O ATOM 2722 H GLY A 161 -7.621 1.051 -7.120 1.00 55.30 H ATOM 2723 HA3 GLY A 161 -7.580 0.176 -4.961 1.00 56.11 H ATOM 2724 HA2 GLY A 161 -6.265 -0.917 -5.360 1.00 56.11 H ATOM 2725 N GLU A 162 -8.874 -2.077 -4.944 1.00 58.68 N ATOM 2726 CA GLU A 162 -9.911 -3.118 -4.951 1.00 58.64 C ATOM 2727 C GLU A 162 -11.058 -2.825 -5.941 1.00 58.37 C ATOM 2728 O GLU A 162 -11.523 -1.686 -6.009 1.00 57.26 O ATOM 2729 CB GLU A 162 -10.479 -3.272 -3.519 1.00 60.15 C ATOM 2730 CG GLU A 162 -9.449 -3.647 -2.422 1.00 60.39 C ATOM 2731 CD GLU A 162 -8.889 -5.079 -2.463 1.00 64.75 C ATOM 2732 OE1 GLU A 162 -9.440 -5.932 -3.195 1.00 63.47 O ATOM 2733 OE2 GLU A 162 -7.899 -5.312 -1.736 1.00 67.53 O1- ATOM 2734 H GLU A 162 -8.674 -1.683 -4.037 1.00 58.68 H ATOM 2735 HA GLU A 162 -9.428 -4.050 -5.253 1.00 58.64 H ATOM 2736 HB3 GLU A 162 -11.297 -3.995 -3.519 1.00 60.15 H ATOM 2737 HB2 GLU A 162 -10.943 -2.329 -3.227 1.00 60.15 H ATOM 2738 HG3 GLU A 162 -9.929 -3.525 -1.450 1.00 60.39 H ATOM 2739 HG2 GLU A 162 -8.619 -2.940 -2.429 1.00 60.39 H ATOM 2740 N GLY A 163 -11.488 -3.864 -6.674 1.00 59.50 N ATOM 2741 CA GLY A 163 -12.515 -3.769 -7.709 1.00 59.67 C ATOM 2742 C GLY A 163 -12.108 -4.610 -8.935 1.00 60.23 C ATOM 2743 O GLY A 163 -11.194 -5.432 -8.839 1.00 60.88 O ATOM 2744 H GLY A 163 -11.068 -4.776 -6.542 1.00 59.50 H ATOM 2745 HA3 GLY A 163 -12.668 -2.732 -8.015 1.00 59.67 H ATOM 2746 HA2 GLY A 163 -13.457 -4.141 -7.308 1.00 59.67 H ATOM 2747 N PRO A 164 -12.799 -4.436 -10.087 1.00 60.62 N ATOM 2748 CA PRO A 164 -12.577 -5.230 -11.317 1.00 60.66 C ATOM 2749 C PRO A 164 -11.181 -5.143 -11.963 1.00 61.03 C ATOM 2750 O PRO A 164 -10.795 -6.084 -12.656 1.00 61.00 O ATOM 2751 CB PRO A 164 -13.656 -4.720 -12.290 1.00 60.92 C ATOM 2752 CG PRO A 164 -14.737 -4.128 -11.404 1.00 61.20 C ATOM 2753 CD PRO A 164 -13.943 -3.536 -10.249 1.00 61.23 C ATOM 2754 HA PRO A 164 -12.785 -6.272 -11.066 1.00 60.66 H ATOM 2755 HB3 PRO A 164 -14.040 -5.507 -12.940 1.00 60.92 H ATOM 2756 HB2 PRO A 164 -13.256 -3.932 -12.933 1.00 60.92 H ATOM 2757 HG3 PRO A 164 -15.377 -4.929 -11.031 1.00 61.20 H ATOM 2758 HG2 PRO A 164 -15.368 -3.401 -11.914 1.00 61.20 H ATOM 2759 HD2 PRO A 164 -13.571 -2.542 -10.504 1.00 61.23 H ATOM 2760 HD3 PRO A 164 -14.570 -3.450 -9.361 1.00 61.23 H ATOM 2761 N GLU A 165 -10.467 -4.028 -11.741 1.00 60.38 N ATOM 2762 CA GLU A 165 -9.161 -3.736 -12.331 1.00 59.00 C ATOM 2763 C GLU A 165 -8.070 -3.685 -11.251 1.00 57.92 C ATOM 2764 O GLU A 165 -7.219 -2.800 -11.301 1.00 56.84 O ATOM 2765 CB GLU A 165 -9.247 -2.417 -13.131 1.00 57.81 C ATOM 2766 CG GLU A 165 -10.260 -2.458 -14.291 1.00 57.79 C ATOM 2767 CD GLU A 165 -10.151 -1.227 -15.195 1.00 58.53 C ATOM 2768 OE1 GLU A 165 -9.875 -1.422 -16.400 1.00 55.07 O ATOM 2769 OE2 GLU A 165 -10.317 -0.102 -14.674 1.00 60.38 O1- ATOM 2770 H GLU A 165 -10.841 -3.307 -11.139 1.00 60.38 H ATOM 2771 HA GLU A 165 -8.863 -4.526 -13.024 1.00 59.00 H ATOM 2772 HB3 GLU A 165 -8.266 -2.170 -13.536 1.00 57.81 H ATOM 2773 HB2 GLU A 165 -9.504 -1.601 -12.452 1.00 57.81 H ATOM 2774 HG3 GLU A 165 -11.278 -2.513 -13.903 1.00 57.79 H ATOM 2775 HG2 GLU A 165 -10.107 -3.366 -14.877 1.00 57.79 H ATOM 2776 N ARG A 166 -8.111 -4.624 -10.290 1.00 57.10 N ATOM 2777 CA ARG A 166 -7.209 -4.696 -9.138 1.00 55.45 C ATOM 2778 C ARG A 166 -5.720 -4.698 -9.528 1.00 54.24 C ATOM 2779 O ARG A 166 -5.304 -5.555 -10.304 1.00 56.13 O ATOM 2780 CB ARG A 166 -7.588 -5.927 -8.293 1.00 56.05 C ATOM 2781 CG ARG A 166 -6.920 -5.981 -6.910 1.00 57.75 C ATOM 2782 CD ARG A 166 -7.302 -7.259 -6.151 1.00 60.60 C ATOM 2783 NE ARG A 166 -6.913 -7.195 -4.735 1.00 61.72 N ATOM 2784 CZ ARG A 166 -5.724 -7.463 -4.169 1.00 63.12 C ATOM 2785 NH1 ARG A 166 -4.652 -7.857 -4.870 1.00 62.01 N ATOM 2786 NH2 ARG A 166 -5.608 -7.324 -2.846 1.00 64.03 N1+ ATOM 2787 H ARG A 166 -8.844 -5.318 -10.318 1.00 57.10 H ATOM 2788 HA ARG A 166 -7.403 -3.807 -8.543 1.00 55.45 H ATOM 2789 HB3 ARG A 166 -7.362 -6.840 -8.846 1.00 56.05 H ATOM 2790 HB2 ARG A 166 -8.668 -5.929 -8.139 1.00 56.05 H ATOM 2791 HG3 ARG A 166 -7.120 -5.082 -6.324 1.00 57.75 H ATOM 2792 HG2 ARG A 166 -5.841 -6.003 -7.070 1.00 57.75 H ATOM 2793 HD3 ARG A 166 -6.759 -8.099 -6.583 1.00 60.60 H ATOM 2794 HD2 ARG A 166 -8.357 -7.504 -6.269 1.00 60.60 H ATOM 2795 HE ARG A 166 -7.647 -6.855 -4.121 1.00 61.72 H ATOM 2796 HH12 ARG A 166 -3.779 -8.044 -4.397 1.00 62.01 H ATOM 2797 HH11 ARG A 166 -4.707 -7.967 -5.877 1.00 62.01 H ATOM 2798 HH22 ARG A 166 -4.728 -7.531 -2.393 1.00 64.03 H ATOM 2799 HH21 ARG A 166 -6.385 -6.964 -2.304 1.00 64.03 H ATOM 2800 N GLY A 167 -4.970 -3.719 -8.992 1.00 51.78 N ATOM 2801 CA GLY A 167 -3.533 -3.537 -9.199 1.00 51.04 C ATOM 2802 C GLY A 167 -3.134 -3.144 -10.628 1.00 51.38 C ATOM 2803 O GLY A 167 -1.946 -3.193 -10.936 1.00 51.98 O ATOM 2804 H GLY A 167 -5.416 -3.039 -8.391 1.00 51.78 H ATOM 2805 HA3 GLY A 167 -2.990 -4.434 -8.911 1.00 51.04 H ATOM 2806 HA2 GLY A 167 -3.193 -2.743 -8.536 1.00 51.04 H ATOM 2807 N ARG A 168 -4.080 -2.760 -11.500 1.00 50.97 N ATOM 2808 CA ARG A 168 -3.790 -2.292 -12.854 1.00 50.91 C ATOM 2809 C ARG A 168 -3.262 -0.850 -12.818 1.00 47.73 C ATOM 2810 O ARG A 168 -3.905 0.013 -12.222 1.00 46.35 O ATOM 2811 CB ARG A 168 -5.063 -2.437 -13.712 1.00 50.65 C ATOM 2812 CG ARG A 168 -4.915 -2.008 -15.187 1.00 53.92 C ATOM 2813 CD ARG A 168 -6.098 -2.447 -16.070 1.00 57.64 C ATOM 2814 NE ARG A 168 -6.091 -3.896 -16.340 1.00 58.41 N ATOM 2815 CZ ARG A 168 -7.053 -4.621 -16.941 1.00 59.92 C ATOM 2816 NH1 ARG A 168 -8.207 -4.080 -17.361 1.00 60.17 N ATOM 2817 NH2 ARG A 168 -6.850 -5.931 -17.125 1.00 63.84 N1+ ATOM 2818 H ARG A 168 -5.050 -2.746 -11.216 1.00 50.97 H ATOM 2819 HA ARG A 168 -3.026 -2.941 -13.287 1.00 50.91 H ATOM 2820 HB3 ARG A 168 -5.862 -1.840 -13.273 1.00 50.65 H ATOM 2821 HB2 ARG A 168 -5.396 -3.474 -13.658 1.00 50.65 H ATOM 2822 HG3 ARG A 168 -4.007 -2.486 -15.560 1.00 53.92 H ATOM 2823 HG2 ARG A 168 -4.746 -0.937 -15.295 1.00 53.92 H ATOM 2824 HD3 ARG A 168 -6.182 -1.853 -16.978 1.00 57.64 H ATOM 2825 HD2 ARG A 168 -7.014 -2.271 -15.508 1.00 57.64 H ATOM 2826 HE ARG A 168 -5.257 -4.380 -16.040 1.00 58.41 H ATOM 2827 HH12 ARG A 168 -8.911 -4.648 -17.810 1.00 60.17 H ATOM 2828 HH11 ARG A 168 -8.411 -3.104 -17.181 1.00 60.17 H ATOM 2829 HH22 ARG A 168 -7.557 -6.501 -17.567 1.00 63.84 H ATOM 2830 HH21 ARG A 168 -5.990 -6.362 -16.820 1.00 63.84 H ATOM 2831 N VAL A 169 -2.117 -0.616 -13.478 1.00 47.38 N ATOM 2832 CA VAL A 169 -1.542 0.715 -13.685 1.00 46.92 C ATOM 2833 C VAL A 169 -2.437 1.546 -14.624 1.00 47.80 C ATOM 2834 O VAL A 169 -2.970 0.993 -15.584 1.00 49.00 O ATOM 2835 CB VAL A 169 -0.121 0.613 -14.312 1.00 47.94 C ATOM 2836 CG1 VAL A 169 0.484 1.942 -14.814 1.00 45.01 C ATOM 2837 CG2 VAL A 169 0.866 -0.063 -13.345 1.00 45.44 C ATOM 2838 H VAL A 169 -1.641 -1.382 -13.938 1.00 47.38 H ATOM 2839 HA VAL A 169 -1.472 1.206 -12.715 1.00 46.92 H ATOM 2840 HB VAL A 169 -0.205 -0.031 -15.183 1.00 47.94 H ATOM 2841 HG11 VAL A 169 1.524 1.815 -15.116 1.00 45.01 H ATOM 2842 HG12 VAL A 169 -0.042 2.333 -15.685 1.00 45.01 H ATOM 2843 HG13 VAL A 169 0.453 2.702 -14.033 1.00 45.01 H ATOM 2844 HG21 VAL A 169 1.859 -0.149 -13.785 1.00 45.44 H ATOM 2845 HG22 VAL A 169 0.961 0.514 -12.426 1.00 45.44 H ATOM 2846 HG23 VAL A 169 0.545 -1.070 -13.075 1.00 45.44 H ATOM 2847 N LYS A 170 -2.565 2.848 -14.334 1.00 49.01 N ATOM 2848 CA LYS A 170 -3.249 3.828 -15.171 1.00 48.15 C ATOM 2849 C LYS A 170 -2.341 5.055 -15.274 1.00 48.50 C ATOM 2850 O LYS A 170 -2.164 5.762 -14.283 1.00 47.27 O ATOM 2851 CB LYS A 170 -4.608 4.226 -14.551 1.00 48.65 C ATOM 2852 CG LYS A 170 -5.635 3.098 -14.391 1.00 48.06 C ATOM 2853 CD LYS A 170 -6.182 2.560 -15.716 1.00 47.65 C ATOM 2854 CE LYS A 170 -7.273 1.507 -15.486 1.00 44.49 C ATOM 2855 NZ LYS A 170 -7.820 1.012 -16.758 1.00 45.56 N1+ ATOM 2856 H LYS A 170 -2.101 3.220 -13.514 1.00 49.01 H ATOM 2857 HA LYS A 170 -3.412 3.437 -16.178 1.00 48.15 H ATOM 2858 HB3 LYS A 170 -5.052 5.017 -15.156 1.00 48.65 H ATOM 2859 HB2 LYS A 170 -4.448 4.659 -13.566 1.00 48.65 H ATOM 2860 HG3 LYS A 170 -6.465 3.474 -13.792 1.00 48.06 H ATOM 2861 HG2 LYS A 170 -5.200 2.281 -13.817 1.00 48.06 H ATOM 2862 HD3 LYS A 170 -5.368 2.131 -16.299 1.00 47.65 H ATOM 2863 HD2 LYS A 170 -6.579 3.387 -16.307 1.00 47.65 H ATOM 2864 HE3 LYS A 170 -8.090 1.928 -14.899 1.00 44.49 H ATOM 2865 HE2 LYS A 170 -6.876 0.661 -14.924 1.00 44.49 H ATOM 2866 HZ1 LYS A 170 -7.081 0.579 -17.295 1.00 45.56 H ATOM 2867 HZ2 LYS A 170 -8.549 0.333 -16.570 1.00 45.56 H ATOM 2868 HZ3 LYS A 170 -8.212 1.775 -17.293 1.00 45.56 H ATOM 2869 N ILE A 171 -1.784 5.296 -16.468 1.00 45.94 N ATOM 2870 CA ILE A 171 -0.975 6.481 -16.747 1.00 44.87 C ATOM 2871 C ILE A 171 -1.907 7.685 -16.987 1.00 45.90 C ATOM 2872 O ILE A 171 -2.787 7.609 -17.845 1.00 45.78 O ATOM 2873 CB ILE A 171 -0.047 6.257 -17.973 1.00 46.09 C ATOM 2874 CG1 ILE A 171 0.930 5.093 -17.689 1.00 45.88 C ATOM 2875 CG2 ILE A 171 0.737 7.523 -18.375 1.00 37.44 C ATOM 2876 CD1 ILE A 171 1.796 4.683 -18.883 1.00 50.99 C ATOM 2877 H ILE A 171 -1.940 4.667 -17.245 1.00 45.94 H ATOM 2878 HA ILE A 171 -0.340 6.689 -15.882 1.00 44.87 H ATOM 2879 HB ILE A 171 -0.667 5.972 -18.825 1.00 46.09 H ATOM 2880 HG13 ILE A 171 0.396 4.209 -17.343 1.00 45.88 H ATOM 2881 HG12 ILE A 171 1.579 5.374 -16.864 1.00 45.88 H ATOM 2882 HG21 ILE A 171 1.402 7.337 -19.217 1.00 37.44 H ATOM 2883 HG22 ILE A 171 0.072 8.328 -18.684 1.00 37.44 H ATOM 2884 HG23 ILE A 171 1.346 7.889 -17.548 1.00 37.44 H ATOM 2885 HD11 ILE A 171 1.881 3.599 -18.947 1.00 50.99 H ATOM 2886 HD12 ILE A 171 1.392 5.038 -19.830 1.00 50.99 H ATOM 2887 HD13 ILE A 171 2.800 5.087 -18.764 1.00 50.99 H ATOM 2888 N ALA A 172 -1.705 8.747 -16.194 1.00 46.66 N ATOM 2889 CA ALA A 172 -2.579 9.916 -16.136 1.00 47.96 C ATOM 2890 C ALA A 172 -1.778 11.220 -16.136 1.00 48.52 C ATOM 2891 O ALA A 172 -0.570 11.210 -15.903 1.00 48.10 O ATOM 2892 CB ALA A 172 -3.434 9.813 -14.865 1.00 48.16 C ATOM 2893 H ALA A 172 -0.945 8.739 -15.524 1.00 46.66 H ATOM 2894 HA ALA A 172 -3.235 9.940 -17.008 1.00 47.96 H ATOM 2895 HB1 ALA A 172 -4.162 10.623 -14.801 1.00 48.16 H ATOM 2896 HB2 ALA A 172 -3.987 8.875 -14.851 1.00 48.16 H ATOM 2897 HB3 ALA A 172 -2.817 9.853 -13.966 1.00 48.16 H ATOM 2898 N ASP A 173 -2.502 12.320 -16.401 1.00 50.86 N ATOM 2899 CA ASP A 173 -2.030 13.707 -16.424 1.00 53.92 C ATOM 2900 C ASP A 173 -0.868 13.902 -17.420 1.00 55.30 C ATOM 2901 O ASP A 173 0.207 14.378 -17.052 1.00 55.90 O ATOM 2902 CB ASP A 173 -1.729 14.250 -15.001 1.00 55.29 C ATOM 2903 CG ASP A 173 -1.587 15.779 -14.852 1.00 60.75 C ATOM 2904 OD1 ASP A 173 -2.260 16.517 -15.608 1.00 71.98 O ATOM 2905 OD2 ASP A 173 -0.941 16.184 -13.861 1.00 67.50 O1- ATOM 2906 H ASP A 173 -3.490 12.208 -16.578 1.00 50.86 H ATOM 2907 HA ASP A 173 -2.871 14.268 -16.833 1.00 53.92 H ATOM 2908 HB3 ASP A 173 -0.840 13.758 -14.606 1.00 55.29 H ATOM 2909 HB2 ASP A 173 -2.540 13.936 -14.346 1.00 55.29 H ATOM 2910 N MET A 174 -1.128 13.519 -18.681 1.00 55.71 N ATOM 2911 CA MET A 174 -0.297 13.850 -19.836 1.00 57.26 C ATOM 2912 C MET A 174 -0.285 15.378 -20.016 1.00 58.77 C ATOM 2913 O MET A 174 -1.342 16.006 -19.918 1.00 59.05 O ATOM 2914 CB MET A 174 -0.867 13.178 -21.108 1.00 57.61 C ATOM 2915 CG MET A 174 -0.689 11.651 -21.235 1.00 57.30 C ATOM 2916 SD MET A 174 -1.486 10.571 -20.007 1.00 60.56 S ATOM 2917 CE MET A 174 -3.234 10.793 -20.425 1.00 57.19 C ATOM 2918 H MET A 174 -2.021 13.098 -18.891 1.00 55.71 H ATOM 2919 HA MET A 174 0.722 13.499 -19.663 1.00 57.26 H ATOM 2920 HB3 MET A 174 -0.402 13.629 -21.987 1.00 57.61 H ATOM 2921 HB2 MET A 174 -1.923 13.416 -21.190 1.00 57.61 H ATOM 2922 HG3 MET A 174 0.374 11.422 -21.238 1.00 57.30 H ATOM 2923 HG2 MET A 174 -1.050 11.340 -22.216 1.00 57.30 H ATOM 2924 HE1 MET A 174 -3.850 10.141 -19.807 1.00 57.19 H ATOM 2925 HE2 MET A 174 -3.542 11.823 -20.250 1.00 57.19 H ATOM 2926 HE3 MET A 174 -3.411 10.543 -21.472 1.00 57.19 H ATOM 2927 N GLY A 175 0.901 15.944 -20.286 1.00 60.83 N ATOM 2928 CA GLY A 175 1.085 17.361 -20.581 1.00 61.58 C ATOM 2929 C GLY A 175 0.599 17.596 -22.010 1.00 62.35 C ATOM 2930 O GLY A 175 1.387 17.490 -22.945 1.00 62.54 O ATOM 2931 H GLY A 175 1.723 15.358 -20.361 1.00 60.83 H ATOM 2932 HA3 GLY A 175 2.146 17.602 -20.509 1.00 61.58 H ATOM 2933 HA2 GLY A 175 0.550 17.992 -19.869 1.00 61.58 H ATOM 2934 N PHE A 176 -0.711 17.851 -22.162 1.00 63.42 N ATOM 2935 CA PHE A 176 -1.426 17.855 -23.437 1.00 64.95 C ATOM 2936 C PHE A 176 -1.189 19.072 -24.340 1.00 65.43 C ATOM 2937 O PHE A 176 -1.467 18.958 -25.531 1.00 67.66 O ATOM 2938 CB PHE A 176 -2.932 17.619 -23.195 1.00 64.87 C ATOM 2939 CG PHE A 176 -3.325 16.169 -22.968 1.00 66.11 C ATOM 2940 CD1 PHE A 176 -3.100 15.213 -23.980 1.00 65.81 C ATOM 2941 CD2 PHE A 176 -3.961 15.766 -21.775 1.00 66.14 C ATOM 2942 CE1 PHE A 176 -3.527 13.903 -23.811 1.00 68.02 C ATOM 2943 CE2 PHE A 176 -4.397 14.455 -21.632 1.00 66.97 C ATOM 2944 CZ PHE A 176 -4.188 13.531 -22.650 1.00 66.46 C ATOM 2945 H PHE A 176 -1.294 17.882 -21.336 1.00 63.42 H ATOM 2946 HA PHE A 176 -1.043 17.013 -24.015 1.00 64.95 H ATOM 2947 HB3 PHE A 176 -3.520 17.968 -24.045 1.00 64.87 H ATOM 2948 HB2 PHE A 176 -3.267 18.220 -22.347 1.00 64.87 H ATOM 2949 HD1 PHE A 176 -2.607 15.503 -24.894 1.00 65.81 H ATOM 2950 HD2 PHE A 176 -4.139 16.477 -20.982 1.00 66.14 H ATOM 2951 HE1 PHE A 176 -3.357 13.175 -24.591 1.00 68.02 H ATOM 2952 HE2 PHE A 176 -4.901 14.153 -20.726 1.00 66.97 H ATOM 2953 HZ PHE A 176 -4.528 12.514 -22.533 1.00 66.46 H ATOM 2954 N ALA A 177 -0.656 20.178 -23.798 1.00 65.43 N ATOM 2955 CA ALA A 177 -0.338 21.380 -24.564 1.00 66.24 C ATOM 2956 C ALA A 177 0.979 21.987 -24.088 1.00 66.19 C ATOM 2957 O ALA A 177 1.084 22.395 -22.932 1.00 66.90 O ATOM 2958 CB ALA A 177 -1.474 22.395 -24.431 1.00 65.29 C ATOM 2959 H ALA A 177 -0.434 20.202 -22.813 1.00 65.43 H ATOM 2960 HA ALA A 177 -0.234 21.139 -25.623 1.00 66.24 H ATOM 2961 HB1 ALA A 177 -1.190 23.363 -24.844 1.00 65.29 H ATOM 2962 HB2 ALA A 177 -2.359 22.055 -24.967 1.00 65.29 H ATOM 2963 HB3 ALA A 177 -1.733 22.552 -23.386 1.00 65.29 H ATOM 2964 N ARG A 178 1.939 22.067 -25.016 1.00 66.17 N ATOM 2965 CA ARG A 178 3.201 22.780 -24.864 1.00 66.46 C ATOM 2966 C ARG A 178 3.387 23.588 -26.152 1.00 66.92 C ATOM 2967 O ARG A 178 3.355 22.995 -27.230 1.00 66.75 O ATOM 2968 CB ARG A 178 4.355 21.771 -24.653 1.00 66.09 C ATOM 2969 CG ARG A 178 4.252 20.890 -23.388 1.00 66.20 C ATOM 2970 CD ARG A 178 4.449 21.662 -22.069 1.00 66.31 C ATOM 2971 NE ARG A 178 4.323 20.800 -20.879 1.00 67.71 N ATOM 2972 CZ ARG A 178 3.244 20.586 -20.099 1.00 69.20 C ATOM 2973 NH1 ARG A 178 2.048 21.135 -20.352 1.00 66.70 N ATOM 2974 NH2 ARG A 178 3.373 19.802 -19.021 1.00 65.42 N1+ ATOM 2975 H ARG A 178 1.761 21.705 -25.945 1.00 66.17 H ATOM 2976 HA ARG A 178 3.155 23.475 -24.024 1.00 66.46 H ATOM 2977 HB3 ARG A 178 5.302 22.313 -24.627 1.00 66.09 H ATOM 2978 HB2 ARG A 178 4.421 21.113 -25.520 1.00 66.09 H ATOM 2979 HG3 ARG A 178 5.064 20.169 -23.469 1.00 66.20 H ATOM 2980 HG2 ARG A 178 3.346 20.283 -23.368 1.00 66.20 H ATOM 2981 HD3 ARG A 178 3.844 22.566 -22.010 1.00 66.31 H ATOM 2982 HD2 ARG A 178 5.485 22.000 -22.037 1.00 66.31 H ATOM 2983 HE ARG A 178 5.177 20.327 -20.609 1.00 67.71 H ATOM 2984 HH12 ARG A 178 1.271 20.990 -19.724 1.00 66.70 H ATOM 2985 HH11 ARG A 178 1.922 21.725 -21.165 1.00 66.70 H ATOM 2986 HH22 ARG A 178 2.594 19.639 -18.399 1.00 65.42 H ATOM 2987 HH21 ARG A 178 4.273 19.404 -18.793 1.00 65.42 H ATOM 2988 N LEU A 179 3.556 24.918 -26.026 1.00 67.10 N ATOM 2989 CA LEU A 179 3.674 25.862 -27.146 1.00 67.55 C ATOM 2990 C LEU A 179 4.802 25.470 -28.111 1.00 66.64 C ATOM 2991 O LEU A 179 5.960 25.445 -27.698 1.00 65.02 O ATOM 2992 CB LEU A 179 3.947 27.285 -26.613 1.00 68.92 C ATOM 2993 CG LEU A 179 2.791 27.959 -25.852 1.00 71.31 C ATOM 2994 CD1 LEU A 179 3.308 29.220 -25.130 1.00 72.57 C ATOM 2995 CD2 LEU A 179 1.580 28.255 -26.767 1.00 73.82 C ATOM 2996 H LEU A 179 3.577 25.328 -25.104 1.00 67.10 H ATOM 2997 HA LEU A 179 2.728 25.849 -27.688 1.00 67.55 H ATOM 2998 HB3 LEU A 179 4.233 27.941 -27.437 1.00 68.92 H ATOM 2999 HB2 LEU A 179 4.818 27.236 -25.960 1.00 68.92 H ATOM 3000 HG LEU A 179 2.451 27.270 -25.078 1.00 71.31 H ATOM 3001 HD11 LEU A 179 2.690 30.099 -25.311 1.00 72.57 H ATOM 3002 HD12 LEU A 179 3.333 29.058 -24.053 1.00 72.57 H ATOM 3003 HD13 LEU A 179 4.321 29.486 -25.433 1.00 72.57 H ATOM 3004 HD21 LEU A 179 0.695 27.733 -26.407 1.00 73.82 H ATOM 3005 HD22 LEU A 179 1.326 29.314 -26.811 1.00 73.82 H ATOM 3006 HD23 LEU A 179 1.748 27.936 -27.796 1.00 73.82 H ATOM 3007 N PHE A 180 4.430 25.160 -29.364 1.00 66.60 N ATOM 3008 CA PHE A 180 5.318 24.735 -30.455 1.00 66.57 C ATOM 3009 C PHE A 180 6.076 23.418 -30.158 1.00 66.48 C ATOM 3010 O PHE A 180 7.158 23.217 -30.709 1.00 65.55 O ATOM 3011 CB PHE A 180 6.300 25.874 -30.848 1.00 66.54 C ATOM 3012 CG PHE A 180 5.664 27.219 -31.157 1.00 65.90 C ATOM 3013 CD1 PHE A 180 5.057 27.451 -32.407 1.00 64.53 C ATOM 3014 CD2 PHE A 180 5.545 28.198 -30.146 1.00 66.09 C ATOM 3015 CE1 PHE A 180 4.400 28.651 -32.649 1.00 65.67 C ATOM 3016 CE2 PHE A 180 4.877 29.387 -30.404 1.00 66.52 C ATOM 3017 CZ PHE A 180 4.311 29.614 -31.652 1.00 65.97 C ATOM 3018 H PHE A 180 3.449 25.214 -29.605 1.00 66.60 H ATOM 3019 HA PHE A 180 4.669 24.534 -31.307 1.00 66.57 H ATOM 3020 HB3 PHE A 180 6.866 25.575 -31.732 1.00 66.54 H ATOM 3021 HB2 PHE A 180 7.044 26.021 -30.063 1.00 66.54 H ATOM 3022 HD1 PHE A 180 5.102 26.701 -33.181 1.00 64.53 H ATOM 3023 HD2 PHE A 180 5.972 28.025 -29.169 1.00 66.09 H ATOM 3024 HE1 PHE A 180 3.943 28.829 -33.612 1.00 65.67 H ATOM 3025 HE2 PHE A 180 4.791 30.135 -29.629 1.00 66.52 H ATOM 3026 HZ PHE A 180 3.790 30.540 -31.846 1.00 65.97 H ATOM 3027 N ASN A 181 5.524 22.559 -29.275 1.00 66.62 N ATOM 3028 CA ASN A 181 6.143 21.331 -28.747 1.00 67.29 C ATOM 3029 C ASN A 181 7.439 21.618 -27.942 1.00 67.84 C ATOM 3030 O ASN A 181 8.310 20.754 -27.890 1.00 66.56 O ATOM 3031 CB ASN A 181 6.340 20.299 -29.904 1.00 67.23 C ATOM 3032 CG ASN A 181 6.682 18.856 -29.494 1.00 68.07 C ATOM 3033 OD1 ASN A 181 6.408 18.425 -28.377 1.00 70.81 O ATOM 3034 ND2 ASN A 181 7.303 18.102 -30.402 1.00 65.22 N ATOM 3035 H ASN A 181 4.628 22.794 -28.867 1.00 66.62 H ATOM 3036 HA ASN A 181 5.446 20.913 -28.021 1.00 67.29 H ATOM 3037 HB3 ASN A 181 7.102 20.648 -30.601 1.00 67.23 H ATOM 3038 HB2 ASN A 181 5.414 20.235 -30.476 1.00 67.23 H ATOM 3039 HD22 ASN A 181 7.572 17.156 -30.173 1.00 65.22 H ATOM 3040 HD21 ASN A 181 7.522 18.472 -31.316 1.00 65.22 H ATOM 3041 N SER A 182 7.578 22.822 -27.355 1.00 69.54 N ATOM 3042 CA SER A 182 8.846 23.311 -26.808 1.00 71.29 C ATOM 3043 C SER A 182 8.855 23.283 -25.262 1.00 72.37 C ATOM 3044 O SER A 182 7.976 23.902 -24.659 1.00 73.45 O ATOM 3045 CB SER A 182 9.064 24.745 -27.328 1.00 71.95 C ATOM 3046 OG SER A 182 10.365 25.199 -27.016 1.00 72.00 O ATOM 3047 H SER A 182 6.827 23.498 -27.411 1.00 69.54 H ATOM 3048 HA SER A 182 9.654 22.723 -27.230 1.00 71.29 H ATOM 3049 HB3 SER A 182 8.345 25.438 -26.894 1.00 71.95 H ATOM 3050 HB2 SER A 182 8.938 24.785 -28.411 1.00 71.95 H ATOM 3051 HG SER A 182 10.990 24.709 -27.559 1.00 72.00 H ATOM 3052 N PRO A 183 9.871 22.628 -24.642 1.00 73.79 N ATOM 3053 CA PRO A 183 10.170 22.776 -23.200 1.00 74.17 C ATOM 3054 C PRO A 183 10.591 24.191 -22.753 1.00 74.92 C ATOM 3055 O PRO A 183 10.493 24.489 -21.563 1.00 73.52 O ATOM 3056 CB PRO A 183 11.316 21.777 -22.939 1.00 73.83 C ATOM 3057 CG PRO A 183 11.359 20.856 -24.145 1.00 74.30 C ATOM 3058 CD PRO A 183 10.824 21.718 -25.272 1.00 74.07 C ATOM 3059 HA PRO A 183 9.284 22.480 -22.640 1.00 74.17 H ATOM 3060 HB3 PRO A 183 11.185 21.223 -22.009 1.00 73.83 H ATOM 3061 HB2 PRO A 183 12.272 22.298 -22.869 1.00 73.83 H ATOM 3062 HG3 PRO A 183 10.692 20.012 -23.982 1.00 74.30 H ATOM 3063 HG2 PRO A 183 12.351 20.457 -24.355 1.00 74.30 H ATOM 3064 HD2 PRO A 183 11.625 22.303 -25.724 1.00 74.07 H ATOM 3065 HD3 PRO A 183 10.369 21.081 -26.027 1.00 74.07 H ATOM 3066 N LEU A 184 11.060 25.021 -23.701 1.00 76.31 N ATOM 3067 CA LEU A 184 11.576 26.375 -23.477 1.00 77.55 C ATOM 3068 C LEU A 184 10.480 27.426 -23.199 1.00 78.68 C ATOM 3069 O LEU A 184 10.827 28.582 -22.957 1.00 78.54 O ATOM 3070 CB LEU A 184 12.415 26.818 -24.704 1.00 77.00 C ATOM 3071 CG LEU A 184 13.475 25.813 -25.211 1.00 77.09 C ATOM 3072 CD1 LEU A 184 14.211 26.376 -26.446 1.00 79.15 C ATOM 3073 CD2 LEU A 184 14.452 25.388 -24.099 1.00 76.62 C ATOM 3074 H LEU A 184 11.097 24.700 -24.658 1.00 76.31 H ATOM 3075 HA LEU A 184 12.224 26.349 -22.599 1.00 77.55 H ATOM 3076 HB3 LEU A 184 12.913 27.759 -24.465 1.00 77.00 H ATOM 3077 HB2 LEU A 184 11.740 27.046 -25.531 1.00 77.00 H ATOM 3078 HG LEU A 184 12.965 24.909 -25.546 1.00 77.09 H ATOM 3079 HD11 LEU A 184 15.295 26.295 -26.367 1.00 79.15 H ATOM 3080 HD12 LEU A 184 13.911 25.847 -27.349 1.00 79.15 H ATOM 3081 HD13 LEU A 184 13.984 27.430 -26.610 1.00 79.15 H ATOM 3082 HD21 LEU A 184 15.443 25.140 -24.479 1.00 76.62 H ATOM 3083 HD22 LEU A 184 14.571 26.168 -23.348 1.00 76.62 H ATOM 3084 HD23 LEU A 184 14.076 24.501 -23.591 1.00 76.62 H ATOM 3085 N LYS A 185 9.197 27.030 -23.270 1.00 80.41 N ATOM 3086 CA LYS A 185 8.036 27.914 -23.204 1.00 81.09 C ATOM 3087 C LYS A 185 7.184 27.636 -21.948 1.00 82.06 C ATOM 3088 O LYS A 185 6.225 26.868 -22.033 1.00 82.62 O ATOM 3089 CB LYS A 185 7.195 27.718 -24.488 1.00 80.83 C ATOM 3090 CG LYS A 185 7.877 28.134 -25.804 1.00 79.87 C ATOM 3091 CD LYS A 185 8.161 29.640 -25.919 0.00 79.84 C ATOM 3092 CE LYS A 185 8.681 30.017 -27.315 0.00 79.77 C ATOM 3093 NZ LYS A 185 8.961 31.459 -27.424 0.00 79.79 N1+ ATOM 3094 H LYS A 185 8.996 26.057 -23.455 1.00 80.41 H ATOM 3095 HA LYS A 185 8.340 28.959 -23.179 1.00 81.09 H ATOM 3096 HB3 LYS A 185 6.268 28.286 -24.397 1.00 80.83 H ATOM 3097 HB2 LYS A 185 6.898 26.671 -24.575 1.00 80.83 H ATOM 3098 HG3 LYS A 185 7.238 27.828 -26.633 1.00 79.87 H ATOM 3099 HG2 LYS A 185 8.808 27.580 -25.929 1.00 79.87 H ATOM 3100 HD3 LYS A 185 8.899 29.928 -25.169 1.00 79.84 H ATOM 3101 HD2 LYS A 185 7.252 30.198 -25.691 1.00 79.84 H ATOM 3102 HE3 LYS A 185 7.948 29.746 -28.076 1.00 79.77 H ATOM 3103 HE2 LYS A 185 9.595 29.466 -27.538 1.00 79.77 H ATOM 3104 HZ1 LYS A 185 9.662 31.720 -26.745 1.00 79.79 H ATOM 3105 HZ2 LYS A 185 9.300 31.667 -28.353 1.00 79.79 H ATOM 3106 HZ3 LYS A 185 8.114 31.983 -27.252 1.00 79.79 H ATOM 3107 N PRO A 186 7.473 28.335 -20.825 1.00 11.82 N ATOM 3108 CA PRO A 186 6.468 28.571 -19.771 1.00 12.72 C ATOM 3109 C PRO A 186 5.500 29.738 -20.097 1.00 14.25 C ATOM 3110 O PRO A 186 4.704 30.105 -19.236 1.00 13.87 O ATOM 3111 CD PRO A 186 8.753 28.970 -20.489 1.00 0.00 C ATOM 3112 CB PRO A 186 7.349 28.888 -18.552 1.00 0.00 C ATOM 3113 CG PRO A 186 8.531 29.649 -19.139 1.00 0.00 C ATOM 3114 HD3 PRO A 186 9.512 28.191 -20.397 1.00 0.00 H ATOM 3115 HD2 PRO A 186 9.091 29.693 -21.230 1.00 0.00 H ATOM 3116 HB2 PRO A 186 6.839 29.449 -17.767 1.00 0.00 H ATOM 3117 HB3 PRO A 186 7.695 27.955 -18.105 1.00 0.00 H ATOM 3118 HG3 PRO A 186 9.414 29.638 -18.500 1.00 0.00 H ATOM 3119 HG2 PRO A 186 8.246 30.690 -19.298 1.00 0.00 H ATOM 3120 HA PRO A 186 5.873 27.679 -19.570 1.00 12.72 H ATOM 3121 N LEU A 187 5.613 30.320 -21.307 1.00 15.64 N ATOM 3122 CA LEU A 187 5.024 31.591 -21.739 1.00 17.67 C ATOM 3123 C LEU A 187 3.557 31.465 -22.206 1.00 17.39 C ATOM 3124 O LEU A 187 3.217 31.904 -23.305 1.00 18.55 O ATOM 3125 CB LEU A 187 5.942 32.202 -22.830 1.00 0.00 C ATOM 3126 CG LEU A 187 7.396 32.486 -22.382 1.00 0.00 C ATOM 3127 CD1 LEU A 187 8.281 32.879 -23.585 1.00 0.00 C ATOM 3128 CD2 LEU A 187 7.469 33.517 -21.234 1.00 0.00 C ATOM 3129 HB2 LEU A 187 5.959 31.523 -23.684 1.00 0.00 H ATOM 3130 HB3 LEU A 187 5.510 33.135 -23.197 1.00 0.00 H ATOM 3131 HG LEU A 187 7.816 31.556 -22.001 1.00 0.00 H ATOM 3132 HD11 LEU A 187 8.651 33.902 -23.521 1.00 0.00 H ATOM 3133 HD12 LEU A 187 9.149 32.223 -23.654 1.00 0.00 H ATOM 3134 HD13 LEU A 187 7.743 32.800 -24.530 1.00 0.00 H ATOM 3135 HD21 LEU A 187 8.240 34.271 -21.390 1.00 0.00 H ATOM 3136 HD22 LEU A 187 6.527 34.049 -21.101 1.00 0.00 H ATOM 3137 HD23 LEU A 187 7.698 33.022 -20.289 1.00 0.00 H ATOM 3138 H LEU A 187 6.269 29.921 -21.961 1.00 15.64 H ATOM 3139 HA LEU A 187 5.009 32.266 -20.882 1.00 17.67 H ATOM 3140 N ALA A 188 2.711 30.896 -21.338 1.00 16.48 N ATOM 3141 CA ALA A 188 1.259 30.803 -21.486 1.00 16.65 C ATOM 3142 C ALA A 188 0.635 30.552 -20.112 1.00 17.19 C ATOM 3143 O ALA A 188 -0.278 31.277 -19.718 1.00 16.97 O ATOM 3144 CB ALA A 188 0.862 29.710 -22.495 1.00 0.00 C ATOM 3145 HB1 ALA A 188 1.114 30.006 -23.512 1.00 0.00 H ATOM 3146 HB2 ALA A 188 1.363 28.765 -22.283 1.00 0.00 H ATOM 3147 HB3 ALA A 188 -0.213 29.526 -22.476 1.00 0.00 H ATOM 3148 H ALA A 188 3.077 30.580 -20.449 1.00 16.48 H ATOM 3149 HA ALA A 188 0.882 31.763 -21.845 1.00 16.65 H ATOM 3150 N ASP A 189 1.187 29.556 -19.401 1.00 17.55 N ATOM 3151 CA ASP A 189 0.892 29.227 -18.005 1.00 19.53 C ATOM 3152 C ASP A 189 1.782 30.057 -17.053 1.00 18.26 C ATOM 3153 O ASP A 189 2.397 31.034 -17.485 1.00 18.30 O ATOM 3154 CB ASP A 189 0.966 27.700 -17.729 1.00 0.00 C ATOM 3155 CG ASP A 189 0.232 26.844 -18.778 1.00 0.00 C ATOM 3156 OD1 ASP A 189 -1.018 26.816 -18.724 1.00 0.00 O ATOM 3157 OD2 ASP A 189 0.916 26.355 -19.706 1.00 0.00 O1- ATOM 3158 HB2 ASP A 189 2.007 27.376 -17.681 1.00 0.00 H ATOM 3159 HB3 ASP A 189 0.522 27.472 -16.758 1.00 0.00 H ATOM 3160 H ASP A 189 1.914 28.997 -19.825 1.00 17.55 H ATOM 3161 HA ASP A 189 -0.135 29.534 -17.795 1.00 19.53 H ATOM 3162 N LEU A 190 1.798 29.690 -15.761 1.00 18.16 N ATOM 3163 CA LEU A 190 2.465 30.449 -14.695 1.00 16.86 C ATOM 3164 C LEU A 190 3.578 29.655 -13.984 1.00 17.11 C ATOM 3165 O LEU A 190 4.347 30.266 -13.242 1.00 18.09 O ATOM 3166 CB LEU A 190 1.388 30.918 -13.678 1.00 0.00 C ATOM 3167 CG LEU A 190 1.312 32.451 -13.510 1.00 0.00 C ATOM 3168 CD1 LEU A 190 0.886 33.159 -14.816 1.00 0.00 C ATOM 3169 CD2 LEU A 190 0.422 32.839 -12.309 1.00 0.00 C ATOM 3170 HB2 LEU A 190 0.400 30.549 -13.960 1.00 0.00 H ATOM 3171 HB3 LEU A 190 1.576 30.470 -12.700 1.00 0.00 H ATOM 3172 HG LEU A 190 2.320 32.793 -13.270 1.00 0.00 H ATOM 3173 HD11 LEU A 190 0.062 33.859 -14.674 1.00 0.00 H ATOM 3174 HD12 LEU A 190 1.717 33.728 -15.233 1.00 0.00 H ATOM 3175 HD13 LEU A 190 0.567 32.450 -15.580 1.00 0.00 H ATOM 3176 HD21 LEU A 190 -0.442 33.439 -12.594 1.00 0.00 H ATOM 3177 HD22 LEU A 190 0.034 31.964 -11.785 1.00 0.00 H ATOM 3178 HD23 LEU A 190 0.990 33.420 -11.582 1.00 0.00 H ATOM 3179 H LEU A 190 1.270 28.879 -15.471 1.00 18.16 H ATOM 3180 HA LEU A 190 2.965 31.324 -15.113 1.00 16.86 H ATOM 3181 N ASP A 191 3.631 28.328 -14.185 1.00 16.91 N ATOM 3182 CA ASP A 191 4.470 27.392 -13.430 1.00 15.94 C ATOM 3183 C ASP A 191 5.780 27.044 -14.177 1.00 17.65 C ATOM 3184 O ASP A 191 5.818 27.129 -15.406 1.00 18.83 O ATOM 3185 CB ASP A 191 3.713 26.074 -13.077 1.00 0.00 C ATOM 3186 CG ASP A 191 3.155 25.208 -14.233 1.00 0.00 C ATOM 3187 OD1 ASP A 191 3.027 23.986 -13.997 1.00 0.00 O ATOM 3188 OD2 ASP A 191 2.741 25.761 -15.275 1.00 0.00 O1- ATOM 3189 HB2 ASP A 191 4.328 25.453 -12.424 1.00 0.00 H ATOM 3190 HB3 ASP A 191 2.848 26.349 -12.471 1.00 0.00 H ATOM 3191 H ASP A 191 3.002 27.893 -14.847 1.00 16.91 H ATOM 3192 HA ASP A 191 4.723 27.878 -12.488 1.00 15.94 H ATOM 3193 N PRO A 192 6.792 26.526 -13.436 1.00 16.20 N ATOM 3194 CA PRO A 192 7.782 25.599 -14.009 1.00 17.24 C ATOM 3195 C PRO A 192 7.097 24.255 -14.336 1.00 16.91 C ATOM 3196 O PRO A 192 6.631 23.577 -13.423 1.00 18.66 O ATOM 3197 CD PRO A 192 6.992 26.700 -11.991 1.00 0.00 C ATOM 3198 CB PRO A 192 8.851 25.493 -12.907 1.00 0.00 C ATOM 3199 CG PRO A 192 8.098 25.722 -11.604 1.00 0.00 C ATOM 3200 HD3 PRO A 192 7.312 27.727 -11.812 1.00 0.00 H ATOM 3201 HD2 PRO A 192 6.102 26.515 -11.391 1.00 0.00 H ATOM 3202 HB2 PRO A 192 9.392 24.546 -12.913 1.00 0.00 H ATOM 3203 HB3 PRO A 192 9.585 26.288 -13.045 1.00 0.00 H ATOM 3204 HG3 PRO A 192 8.732 26.086 -10.795 1.00 0.00 H ATOM 3205 HG2 PRO A 192 7.651 24.783 -11.274 1.00 0.00 H ATOM 3206 HA PRO A 192 8.230 26.014 -14.914 1.00 17.24 H ATOM 3207 N VAL A 193 6.978 23.953 -15.639 1.00 15.49 N ATOM 3208 CA VAL A 193 6.059 22.963 -16.226 1.00 15.21 C ATOM 3209 C VAL A 193 6.347 21.460 -15.944 1.00 14.65 C ATOM 3210 O VAL A 193 5.732 20.601 -16.577 1.00 15.18 O ATOM 3211 CB VAL A 193 5.929 23.197 -17.761 1.00 0.00 C ATOM 3212 CG1 VAL A 193 5.349 24.589 -18.078 1.00 0.00 C ATOM 3213 CG2 VAL A 193 7.230 22.953 -18.552 1.00 0.00 C ATOM 3214 HB VAL A 193 5.191 22.493 -18.150 1.00 0.00 H ATOM 3215 HG11 VAL A 193 5.165 24.703 -19.147 1.00 0.00 H ATOM 3216 HG12 VAL A 193 4.398 24.745 -17.567 1.00 0.00 H ATOM 3217 HG13 VAL A 193 6.023 25.390 -17.775 1.00 0.00 H ATOM 3218 HG21 VAL A 193 7.077 23.130 -19.616 1.00 0.00 H ATOM 3219 HG22 VAL A 193 8.029 23.616 -18.221 1.00 0.00 H ATOM 3220 HG23 VAL A 193 7.584 21.928 -18.449 1.00 0.00 H ATOM 3221 H VAL A 193 7.396 24.580 -16.311 1.00 15.49 H ATOM 3222 HA VAL A 193 5.079 23.152 -15.786 1.00 15.21 H ATOM 3223 N VAL A 194 7.249 21.156 -14.997 1.00 13.85 N ATOM 3224 CA VAL A 194 7.564 19.816 -14.487 1.00 13.89 C ATOM 3225 C VAL A 194 7.839 19.932 -12.966 1.00 13.31 C ATOM 3226 O VAL A 194 7.980 21.044 -12.454 1.00 13.54 O ATOM 3227 CB VAL A 194 8.815 19.220 -15.226 1.00 0.00 C ATOM 3228 CG1 VAL A 194 9.354 17.875 -14.703 1.00 0.00 C ATOM 3229 CG2 VAL A 194 8.588 19.064 -16.739 1.00 0.00 C ATOM 3230 HB VAL A 194 9.628 19.931 -15.094 1.00 0.00 H ATOM 3231 HG11 VAL A 194 10.086 17.445 -15.388 1.00 0.00 H ATOM 3232 HG12 VAL A 194 9.870 17.999 -13.755 1.00 0.00 H ATOM 3233 HG13 VAL A 194 8.559 17.142 -14.575 1.00 0.00 H ATOM 3234 HG21 VAL A 194 9.452 18.626 -17.239 1.00 0.00 H ATOM 3235 HG22 VAL A 194 7.735 18.412 -16.930 1.00 0.00 H ATOM 3236 HG23 VAL A 194 8.408 20.021 -17.224 1.00 0.00 H ATOM 3237 H VAL A 194 7.663 21.915 -14.472 1.00 13.85 H ATOM 3238 HA VAL A 194 6.703 19.161 -14.617 1.00 13.89 H ATOM 3239 N VAL A 195 7.952 18.791 -12.264 1.00 11.96 N ATOM 3240 CA VAL A 195 8.503 18.675 -10.902 1.00 11.91 C ATOM 3241 C VAL A 195 10.020 19.052 -10.829 1.00 11.63 C ATOM 3242 O VAL A 195 10.543 19.662 -11.762 1.00 12.13 O ATOM 3243 CB VAL A 195 8.201 17.246 -10.344 1.00 0.00 C ATOM 3244 CG1 VAL A 195 9.049 16.125 -10.970 1.00 0.00 C ATOM 3245 CG2 VAL A 195 8.207 17.136 -8.805 1.00 0.00 C ATOM 3246 HB VAL A 195 7.171 17.035 -10.630 1.00 0.00 H ATOM 3247 HG11 VAL A 195 8.708 15.149 -10.625 1.00 0.00 H ATOM 3248 HG12 VAL A 195 8.967 16.127 -12.057 1.00 0.00 H ATOM 3249 HG13 VAL A 195 10.104 16.208 -10.710 1.00 0.00 H ATOM 3250 HG21 VAL A 195 7.735 16.205 -8.488 1.00 0.00 H ATOM 3251 HG22 VAL A 195 9.208 17.132 -8.379 1.00 0.00 H ATOM 3252 HG23 VAL A 195 7.647 17.951 -8.346 1.00 0.00 H ATOM 3253 H VAL A 195 7.806 17.916 -12.747 1.00 11.96 H ATOM 3254 HA VAL A 195 7.976 19.400 -10.280 1.00 11.91 H ATOM 3255 N THR A 196 10.694 18.733 -9.710 1.00 75.08 N ATOM 3256 CA THR A 196 12.041 19.162 -9.283 1.00 75.02 C ATOM 3257 C THR A 196 13.254 18.706 -10.149 1.00 72.81 C ATOM 3258 O THR A 196 14.376 18.616 -9.656 1.00 75.73 O ATOM 3259 CB THR A 196 12.267 18.790 -7.783 1.00 75.02 C ATOM 3260 OG1 THR A 196 11.089 19.051 -7.041 1.00 76.05 O ATOM 3261 CG2 THR A 196 13.411 19.531 -7.057 1.00 75.19 C ATOM 3262 HA THR A 196 12.038 20.252 -9.351 1.00 75.02 H ATOM 3263 HB THR A 196 12.442 17.717 -7.705 1.00 75.02 H ATOM 3264 HG1 THR A 196 11.285 18.938 -6.108 1.00 76.05 H ATOM 3265 HG21 THR A 196 13.307 19.462 -5.974 1.00 75.19 H ATOM 3266 HG22 THR A 196 14.394 19.125 -7.285 1.00 75.19 H ATOM 3267 HG23 THR A 196 13.426 20.585 -7.329 1.00 75.19 H ATOM 3268 H THR A 196 10.186 18.249 -8.983 1.00 75.08 H ATOM 3269 N PHE A 197 13.030 18.470 -11.453 1.00 68.56 N ATOM 3270 CA PHE A 197 14.013 18.207 -12.517 1.00 64.96 C ATOM 3271 C PHE A 197 14.659 16.804 -12.459 1.00 60.77 C ATOM 3272 O PHE A 197 15.440 16.484 -13.355 1.00 58.08 O ATOM 3273 CB PHE A 197 15.093 19.323 -12.586 1.00 65.54 C ATOM 3274 CG PHE A 197 14.582 20.753 -12.466 1.00 67.44 C ATOM 3275 CD1 PHE A 197 13.560 21.229 -13.313 1.00 68.07 C ATOM 3276 CD2 PHE A 197 15.131 21.623 -11.500 1.00 71.77 C ATOM 3277 CE1 PHE A 197 13.083 22.525 -13.168 1.00 70.69 C ATOM 3278 CE2 PHE A 197 14.637 22.914 -11.366 1.00 73.18 C ATOM 3279 CZ PHE A 197 13.615 23.361 -12.195 1.00 71.74 C ATOM 3280 H PHE A 197 12.086 18.619 -11.784 1.00 68.56 H ATOM 3281 HA PHE A 197 13.442 18.241 -13.444 1.00 64.96 H ATOM 3282 HB3 PHE A 197 15.638 19.245 -13.527 1.00 65.54 H ATOM 3283 HB2 PHE A 197 15.836 19.164 -11.805 1.00 65.54 H ATOM 3284 HD1 PHE A 197 13.127 20.580 -14.056 1.00 68.07 H ATOM 3285 HD2 PHE A 197 15.922 21.285 -10.846 1.00 71.77 H ATOM 3286 HE1 PHE A 197 12.291 22.883 -13.809 1.00 70.69 H ATOM 3287 HE2 PHE A 197 15.051 23.573 -10.618 1.00 73.18 H ATOM 3288 HZ PHE A 197 13.237 24.367 -12.085 1.00 71.74 H ATOM 3289 N TRP A 198 14.314 15.987 -11.445 1.00 56.85 N ATOM 3290 CA TRP A 198 14.856 14.646 -11.185 1.00 54.81 C ATOM 3291 C TRP A 198 14.609 13.629 -12.317 1.00 52.52 C ATOM 3292 O TRP A 198 15.407 12.707 -12.474 1.00 50.72 O ATOM 3293 CB TRP A 198 14.270 14.085 -9.868 1.00 54.00 C ATOM 3294 CG TRP A 198 14.362 14.899 -8.608 1.00 57.24 C ATOM 3295 CD1 TRP A 198 15.225 15.909 -8.359 1.00 60.19 C ATOM 3296 CD2 TRP A 198 13.594 14.724 -7.377 1.00 59.77 C ATOM 3297 NE1 TRP A 198 15.000 16.409 -7.094 1.00 62.18 N ATOM 3298 CE2 TRP A 198 14.014 15.711 -6.436 1.00 61.67 C ATOM 3299 CE3 TRP A 198 12.578 13.833 -6.958 1.00 61.41 C ATOM 3300 CZ2 TRP A 198 13.447 15.823 -5.155 1.00 64.63 C ATOM 3301 CZ3 TRP A 198 12.004 13.929 -5.674 1.00 65.63 C ATOM 3302 CH2 TRP A 198 12.434 14.925 -4.774 1.00 64.39 C ATOM 3303 H TRP A 198 13.670 16.336 -10.749 1.00 56.85 H ATOM 3304 HA TRP A 198 15.934 14.752 -11.063 1.00 54.81 H ATOM 3305 HB3 TRP A 198 14.739 13.129 -9.643 1.00 54.00 H ATOM 3306 HB2 TRP A 198 13.211 13.869 -10.013 1.00 54.00 H ATOM 3307 HD1 TRP A 198 15.957 16.280 -9.060 1.00 60.19 H ATOM 3308 HE1 TRP A 198 15.507 17.203 -6.718 1.00 62.18 H ATOM 3309 HE3 TRP A 198 12.235 13.064 -7.635 1.00 61.41 H ATOM 3310 HZ2 TRP A 198 13.791 16.584 -4.470 1.00 64.63 H ATOM 3311 HZ3 TRP A 198 11.232 13.234 -5.380 1.00 65.63 H ATOM 3312 HH2 TRP A 198 11.992 14.993 -3.791 1.00 64.39 H ATOM 3313 N TYR A 199 13.513 13.807 -13.070 1.00 51.61 N ATOM 3314 CA TYR A 199 13.062 12.901 -14.129 1.00 51.83 C ATOM 3315 C TYR A 199 13.328 13.468 -15.535 1.00 51.74 C ATOM 3316 O TYR A 199 13.073 12.747 -16.498 1.00 50.69 O ATOM 3317 CB TYR A 199 11.562 12.575 -13.926 1.00 51.66 C ATOM 3318 CG TYR A 199 11.213 12.125 -12.515 1.00 54.19 C ATOM 3319 CD1 TYR A 199 11.368 10.778 -12.133 1.00 55.31 C ATOM 3320 CD2 TYR A 199 10.784 13.071 -11.562 1.00 54.97 C ATOM 3321 CE1 TYR A 199 11.144 10.394 -10.797 1.00 58.25 C ATOM 3322 CE2 TYR A 199 10.554 12.689 -10.229 1.00 57.04 C ATOM 3323 CZ TYR A 199 10.750 11.352 -9.840 1.00 56.94 C ATOM 3324 OH TYR A 199 10.547 10.997 -8.539 1.00 51.49 O ATOM 3325 H TYR A 199 12.914 14.603 -12.891 1.00 51.61 H ATOM 3326 HA TYR A 199 13.607 11.959 -14.069 1.00 51.83 H ATOM 3327 HB3 TYR A 199 11.249 11.799 -14.627 1.00 51.66 H ATOM 3328 HB2 TYR A 199 10.952 13.447 -14.163 1.00 51.66 H ATOM 3329 HD1 TYR A 199 11.672 10.040 -12.858 1.00 55.31 H ATOM 3330 HD2 TYR A 199 10.661 14.103 -11.847 1.00 54.97 H ATOM 3331 HE1 TYR A 199 11.268 9.359 -10.515 1.00 58.25 H ATOM 3332 HE2 TYR A 199 10.245 13.425 -9.502 1.00 57.04 H ATOM 3333 HH TYR A 199 10.776 10.077 -8.349 1.00 51.49 H ATOM 3334 N ARG A 200 13.838 14.713 -15.646 1.00 50.18 N ATOM 3335 CA ARG A 200 14.233 15.338 -16.914 1.00 51.35 C ATOM 3336 C ARG A 200 15.525 14.722 -17.472 1.00 49.33 C ATOM 3337 O ARG A 200 16.511 14.601 -16.746 1.00 48.59 O ATOM 3338 CB ARG A 200 14.432 16.860 -16.751 1.00 52.16 C ATOM 3339 CG ARG A 200 13.134 17.663 -16.566 1.00 56.78 C ATOM 3340 CD ARG A 200 13.392 19.168 -16.747 1.00 62.40 C ATOM 3341 NE ARG A 200 12.181 19.986 -16.552 1.00 67.29 N ATOM 3342 CZ ARG A 200 12.082 21.322 -16.718 1.00 69.76 C ATOM 3343 NH1 ARG A 200 13.129 22.072 -17.096 1.00 69.42 N ATOM 3344 NH2 ARG A 200 10.909 21.930 -16.505 1.00 69.74 N1+ ATOM 3345 H ARG A 200 14.042 15.241 -14.809 1.00 50.18 H ATOM 3346 HA ARG A 200 13.435 15.183 -17.640 1.00 51.35 H ATOM 3347 HB3 ARG A 200 14.920 17.240 -17.651 1.00 52.16 H ATOM 3348 HB2 ARG A 200 15.125 17.070 -15.936 1.00 52.16 H ATOM 3349 HG3 ARG A 200 12.655 17.447 -15.610 1.00 56.78 H ATOM 3350 HG2 ARG A 200 12.434 17.339 -17.338 1.00 56.78 H ATOM 3351 HD3 ARG A 200 13.708 19.339 -17.777 1.00 62.40 H ATOM 3352 HD2 ARG A 200 14.208 19.506 -16.108 1.00 62.40 H ATOM 3353 HE ARG A 200 11.354 19.480 -16.268 1.00 67.29 H ATOM 3354 HH12 ARG A 200 13.031 23.070 -17.217 1.00 69.42 H ATOM 3355 HH11 ARG A 200 14.025 21.639 -17.263 1.00 69.42 H ATOM 3356 HH22 ARG A 200 10.822 22.929 -16.628 1.00 69.74 H ATOM 3357 HH21 ARG A 200 10.099 21.398 -16.220 1.00 69.74 H ATOM 3358 N ALA A 201 15.492 14.406 -18.775 1.00 46.83 N ATOM 3359 CA ALA A 201 16.617 13.910 -19.568 1.00 46.21 C ATOM 3360 C ALA A 201 17.749 14.953 -19.705 1.00 44.47 C ATOM 3361 O ALA A 201 17.461 16.150 -19.659 1.00 43.36 O ATOM 3362 CB ALA A 201 16.052 13.502 -20.935 1.00 44.83 C ATOM 3363 H ALA A 201 14.631 14.543 -19.285 1.00 46.83 H ATOM 3364 HA ALA A 201 17.006 13.030 -19.065 1.00 46.21 H ATOM 3365 HB1 ALA A 201 16.771 12.911 -21.497 1.00 44.83 H ATOM 3366 HB2 ALA A 201 15.156 12.889 -20.828 1.00 44.83 H ATOM 3367 HB3 ALA A 201 15.786 14.374 -21.534 1.00 44.83 H ATOM 3368 N PRO A 202 19.018 14.503 -19.860 1.00 43.80 N ATOM 3369 CA PRO A 202 20.181 15.411 -19.885 1.00 45.49 C ATOM 3370 C PRO A 202 20.224 16.404 -21.062 1.00 46.40 C ATOM 3371 O PRO A 202 20.834 17.459 -20.908 1.00 47.91 O ATOM 3372 CB PRO A 202 21.394 14.467 -19.865 1.00 44.71 C ATOM 3373 CG PRO A 202 20.881 13.173 -20.476 1.00 46.15 C ATOM 3374 CD PRO A 202 19.448 13.108 -19.960 1.00 44.26 C ATOM 3375 HA PRO A 202 20.188 16.004 -18.969 1.00 45.49 H ATOM 3376 HB3 PRO A 202 21.695 14.288 -18.832 1.00 44.71 H ATOM 3377 HB2 PRO A 202 22.266 14.860 -20.390 1.00 44.71 H ATOM 3378 HG3 PRO A 202 21.476 12.299 -20.211 1.00 46.15 H ATOM 3379 HG2 PRO A 202 20.876 13.260 -21.563 1.00 46.15 H ATOM 3380 HD2 PRO A 202 18.822 12.500 -20.612 1.00 44.26 H ATOM 3381 HD3 PRO A 202 19.429 12.676 -18.962 1.00 44.26 H ATOM 3382 N GLU A 203 19.556 16.086 -22.186 1.00 46.77 N ATOM 3383 CA GLU A 203 19.406 16.987 -23.328 1.00 46.56 C ATOM 3384 C GLU A 203 18.420 18.141 -23.058 1.00 48.23 C ATOM 3385 O GLU A 203 18.663 19.232 -23.565 1.00 47.21 O ATOM 3386 CB GLU A 203 19.088 16.212 -24.628 1.00 47.06 C ATOM 3387 CG GLU A 203 17.717 15.504 -24.728 1.00 47.04 C ATOM 3388 CD GLU A 203 17.619 14.096 -24.121 1.00 45.10 C ATOM 3389 OE1 GLU A 203 18.600 13.595 -23.529 1.00 39.52 O ATOM 3390 OE2 GLU A 203 16.528 13.512 -24.279 1.00 40.85 O1- ATOM 3391 H GLU A 203 19.111 15.181 -22.276 1.00 46.77 H ATOM 3392 HA GLU A 203 20.383 17.443 -23.493 1.00 46.56 H ATOM 3393 HB3 GLU A 203 19.892 15.504 -24.832 1.00 47.06 H ATOM 3394 HB2 GLU A 203 19.147 16.918 -25.456 1.00 47.06 H ATOM 3395 HG3 GLU A 203 17.479 15.406 -25.787 1.00 47.04 H ATOM 3396 HG2 GLU A 203 16.923 16.125 -24.313 1.00 47.04 H ATOM 3397 N LEU A 204 17.377 17.929 -22.228 1.00 48.44 N ATOM 3398 CA LEU A 204 16.496 19.001 -21.733 1.00 48.97 C ATOM 3399 C LEU A 204 17.266 20.001 -20.858 1.00 50.59 C ATOM 3400 O LEU A 204 17.050 21.206 -20.979 1.00 52.39 O ATOM 3401 CB LEU A 204 15.310 18.429 -20.924 1.00 49.55 C ATOM 3402 CG LEU A 204 14.320 17.566 -21.730 1.00 49.37 C ATOM 3403 CD1 LEU A 204 13.387 16.794 -20.774 1.00 45.06 C ATOM 3404 CD2 LEU A 204 13.542 18.416 -22.758 1.00 44.58 C ATOM 3405 H LEU A 204 17.240 17.014 -21.821 1.00 48.44 H ATOM 3406 HA LEU A 204 16.109 19.550 -22.591 1.00 48.97 H ATOM 3407 HB3 LEU A 204 14.754 19.247 -20.462 1.00 49.55 H ATOM 3408 HB2 LEU A 204 15.698 17.847 -20.089 1.00 49.55 H ATOM 3409 HG LEU A 204 14.887 16.817 -22.285 1.00 49.37 H ATOM 3410 HD11 LEU A 204 12.339 16.834 -21.071 1.00 45.06 H ATOM 3411 HD12 LEU A 204 13.673 15.743 -20.736 1.00 45.06 H ATOM 3412 HD13 LEU A 204 13.440 17.172 -19.754 1.00 45.06 H ATOM 3413 HD21 LEU A 204 12.466 18.244 -22.731 1.00 44.58 H ATOM 3414 HD22 LEU A 204 13.693 19.484 -22.598 1.00 44.58 H ATOM 3415 HD23 LEU A 204 13.875 18.198 -23.773 1.00 44.58 H ATOM 3416 N LEU A 205 18.187 19.469 -20.040 1.00 51.51 N ATOM 3417 CA LEU A 205 19.113 20.220 -19.198 1.00 51.88 C ATOM 3418 C LEU A 205 20.266 20.881 -19.985 1.00 52.85 C ATOM 3419 O LEU A 205 21.034 21.628 -19.382 1.00 54.12 O ATOM 3420 CB LEU A 205 19.644 19.288 -18.091 1.00 51.51 C ATOM 3421 CG LEU A 205 18.551 18.677 -17.182 1.00 51.16 C ATOM 3422 CD1 LEU A 205 19.150 17.602 -16.270 1.00 47.26 C ATOM 3423 CD2 LEU A 205 17.782 19.738 -16.372 1.00 54.08 C ATOM 3424 H LEU A 205 18.298 18.465 -20.020 1.00 51.51 H ATOM 3425 HA LEU A 205 18.556 21.023 -18.726 1.00 51.88 H ATOM 3426 HB3 LEU A 205 20.353 19.831 -17.465 1.00 51.51 H ATOM 3427 HB2 LEU A 205 20.213 18.483 -18.555 1.00 51.51 H ATOM 3428 HG LEU A 205 17.827 18.160 -17.812 1.00 51.16 H ATOM 3429 HD11 LEU A 205 18.366 17.062 -15.739 1.00 47.26 H ATOM 3430 HD12 LEU A 205 19.714 16.868 -16.844 1.00 47.26 H ATOM 3431 HD13 LEU A 205 19.829 18.040 -15.537 1.00 47.26 H ATOM 3432 HD21 LEU A 205 16.738 19.783 -16.682 1.00 54.08 H ATOM 3433 HD22 LEU A 205 17.793 19.525 -15.302 1.00 54.08 H ATOM 3434 HD23 LEU A 205 18.204 20.733 -16.503 1.00 54.08 H ATOM 3435 N LEU A 206 20.359 20.613 -21.301 1.00 52.79 N ATOM 3436 CA LEU A 206 21.333 21.194 -22.225 1.00 52.84 C ATOM 3437 C LEU A 206 20.667 21.996 -23.367 1.00 53.83 C ATOM 3438 O LEU A 206 21.366 22.373 -24.309 1.00 53.68 O ATOM 3439 CB LEU A 206 22.281 20.089 -22.750 1.00 51.98 C ATOM 3440 CG LEU A 206 23.284 19.561 -21.703 1.00 50.14 C ATOM 3441 CD1 LEU A 206 24.014 18.303 -22.222 1.00 43.85 C ATOM 3442 CD2 LEU A 206 24.271 20.658 -21.259 1.00 43.55 C ATOM 3443 H LEU A 206 19.697 19.971 -21.715 1.00 52.79 H ATOM 3444 HA LEU A 206 21.927 21.923 -21.681 1.00 52.84 H ATOM 3445 HB3 LEU A 206 22.866 20.454 -23.592 1.00 51.98 H ATOM 3446 HB2 LEU A 206 21.681 19.268 -23.138 1.00 51.98 H ATOM 3447 HG LEU A 206 22.727 19.255 -20.818 1.00 50.14 H ATOM 3448 HD11 LEU A 206 23.886 17.468 -21.532 1.00 43.85 H ATOM 3449 HD12 LEU A 206 23.631 17.978 -23.190 1.00 43.85 H ATOM 3450 HD13 LEU A 206 25.084 18.460 -22.350 1.00 43.85 H ATOM 3451 HD21 LEU A 206 25.252 20.251 -21.021 1.00 43.55 H ATOM 3452 HD22 LEU A 206 24.411 21.417 -22.028 1.00 43.55 H ATOM 3453 HD23 LEU A 206 23.911 21.167 -20.366 1.00 43.55 H ATOM 3454 N GLY A 207 19.363 22.306 -23.250 1.00 54.10 N ATOM 3455 CA GLY A 207 18.691 23.262 -24.131 1.00 54.41 C ATOM 3456 C GLY A 207 17.961 22.620 -25.318 1.00 54.99 C ATOM 3457 O GLY A 207 17.808 23.297 -26.334 1.00 55.02 O ATOM 3458 H GLY A 207 18.844 21.969 -22.451 1.00 54.10 H ATOM 3459 HA3 GLY A 207 19.388 24.019 -24.496 1.00 54.41 H ATOM 3460 HA2 GLY A 207 17.947 23.800 -23.549 1.00 54.41 H ATOM 3461 N ALA A 208 17.500 21.356 -25.214 1.00 55.00 N ATOM 3462 CA ALA A 208 16.669 20.686 -26.228 1.00 55.12 C ATOM 3463 C ALA A 208 15.376 21.464 -26.522 1.00 56.87 C ATOM 3464 O ALA A 208 14.585 21.703 -25.609 1.00 54.73 O ATOM 3465 CB ALA A 208 16.329 19.251 -25.795 1.00 54.12 C ATOM 3466 H ALA A 208 17.704 20.819 -24.381 1.00 55.00 H ATOM 3467 HA ALA A 208 17.261 20.627 -27.144 1.00 55.12 H ATOM 3468 HB1 ALA A 208 15.665 18.768 -26.513 1.00 54.12 H ATOM 3469 HB2 ALA A 208 17.221 18.631 -25.726 1.00 54.12 H ATOM 3470 HB3 ALA A 208 15.830 19.230 -24.828 1.00 54.12 H ATOM 3471 N ARG A 209 15.219 21.863 -27.793 1.00 58.98 N ATOM 3472 CA ARG A 209 14.157 22.755 -28.257 1.00 61.27 C ATOM 3473 C ARG A 209 12.779 22.091 -28.395 1.00 61.16 C ATOM 3474 O ARG A 209 11.800 22.830 -28.494 1.00 61.76 O ATOM 3475 CB ARG A 209 14.570 23.399 -29.595 1.00 62.64 C ATOM 3476 CG ARG A 209 15.882 24.198 -29.528 1.00 69.36 C ATOM 3477 CD ARG A 209 16.190 24.903 -30.857 1.00 77.96 C ATOM 3478 NE ARG A 209 17.512 25.552 -30.841 1.00 83.85 N ATOM 3479 CZ ARG A 209 18.138 26.142 -31.877 1.00 91.42 C ATOM 3480 NH1 ARG A 209 17.598 26.190 -33.106 1.00 94.42 N ATOM 3481 NH2 ARG A 209 19.337 26.701 -31.675 1.00 93.45 N1+ ATOM 3482 H ARG A 209 15.920 21.617 -28.477 1.00 58.98 H ATOM 3483 HA ARG A 209 14.047 23.548 -27.516 1.00 61.27 H ATOM 3484 HB3 ARG A 209 13.777 24.068 -29.934 1.00 62.64 H ATOM 3485 HB2 ARG A 209 14.657 22.625 -30.360 1.00 62.64 H ATOM 3486 HG3 ARG A 209 16.728 23.597 -29.191 1.00 69.36 H ATOM 3487 HG2 ARG A 209 15.734 24.962 -28.764 1.00 69.36 H ATOM 3488 HD3 ARG A 209 15.482 25.724 -30.976 1.00 77.96 H ATOM 3489 HD2 ARG A 209 16.048 24.240 -31.711 1.00 77.96 H ATOM 3490 HE ARG A 209 17.977 25.555 -29.944 1.00 83.85 H ATOM 3491 HH12 ARG A 209 18.086 26.638 -33.868 1.00 94.42 H ATOM 3492 HH11 ARG A 209 16.694 25.773 -33.274 1.00 94.42 H ATOM 3493 HH22 ARG A 209 19.829 27.149 -32.435 1.00 93.45 H ATOM 3494 HH21 ARG A 209 19.764 26.681 -30.759 1.00 93.45 H ATOM 3495 N HIS A 210 12.719 20.747 -28.404 1.00 60.81 N ATOM 3496 CA HIS A 210 11.483 19.979 -28.549 1.00 59.61 C ATOM 3497 C HIS A 210 11.472 18.743 -27.643 1.00 57.96 C ATOM 3498 O HIS A 210 12.525 18.158 -27.386 1.00 56.52 O ATOM 3499 CB HIS A 210 11.263 19.573 -30.022 1.00 60.55 C ATOM 3500 CG HIS A 210 11.070 20.725 -30.976 1.00 66.76 C ATOM 3501 ND1 HIS A 210 10.004 21.606 -30.888 1.00 67.70 N ATOM 3502 CD2 HIS A 210 11.827 21.164 -32.040 1.00 68.84 C ATOM 3503 CE1 HIS A 210 10.163 22.512 -31.856 1.00 72.15 C ATOM 3504 NE2 HIS A 210 11.247 22.307 -32.594 1.00 71.20 N ATOM 3505 H HIS A 210 13.564 20.205 -28.292 1.00 60.81 H ATOM 3506 HA HIS A 210 10.657 20.610 -28.239 1.00 59.61 H ATOM 3507 HB3 HIS A 210 10.382 18.934 -30.105 1.00 60.55 H ATOM 3508 HB2 HIS A 210 12.105 18.974 -30.372 1.00 60.55 H ATOM 3509 HD1 HIS A 210 9.258 21.587 -30.207 1.00 67.70 H ATOM 3510 HD2 HIS A 210 12.745 20.758 -32.438 1.00 68.84 H ATOM 3511 HE1 HIS A 210 9.481 23.333 -32.022 1.00 72.15 H ATOM 3512 N TYR A 211 10.256 18.341 -27.234 1.00 56.62 N ATOM 3513 CA TYR A 211 9.981 17.052 -26.597 1.00 56.51 C ATOM 3514 C TYR A 211 9.988 15.918 -27.638 1.00 55.45 C ATOM 3515 O TYR A 211 9.591 16.132 -28.785 1.00 53.07 O ATOM 3516 CB TYR A 211 8.620 17.099 -25.885 1.00 56.64 C ATOM 3517 CG TYR A 211 8.526 18.027 -24.688 1.00 58.41 C ATOM 3518 CD1 TYR A 211 8.963 17.598 -23.417 1.00 57.86 C ATOM 3519 CD2 TYR A 211 7.944 19.303 -24.830 1.00 59.85 C ATOM 3520 CE1 TYR A 211 8.803 18.434 -22.293 1.00 58.74 C ATOM 3521 CE2 TYR A 211 7.789 20.139 -23.711 1.00 59.90 C ATOM 3522 CZ TYR A 211 8.209 19.704 -22.441 1.00 63.33 C ATOM 3523 OH TYR A 211 8.032 20.517 -21.361 1.00 69.09 O ATOM 3524 H TYR A 211 9.444 18.890 -27.483 1.00 56.62 H ATOM 3525 HA TYR A 211 10.753 16.863 -25.851 1.00 56.51 H ATOM 3526 HB3 TYR A 211 8.363 16.102 -25.532 1.00 56.64 H ATOM 3527 HB2 TYR A 211 7.841 17.358 -26.599 1.00 56.64 H ATOM 3528 HD1 TYR A 211 9.399 16.618 -23.297 1.00 57.86 H ATOM 3529 HD2 TYR A 211 7.583 19.629 -25.791 1.00 59.85 H ATOM 3530 HE1 TYR A 211 9.124 18.091 -21.320 1.00 58.74 H ATOM 3531 HE2 TYR A 211 7.333 21.111 -23.825 1.00 59.90 H ATOM 3532 HH TYR A 211 8.184 20.074 -20.521 1.00 69.09 H ATOM 3533 N THR A 212 10.432 14.731 -27.200 1.00 54.81 N ATOM 3534 CA THR A 212 10.621 13.539 -28.029 1.00 53.31 C ATOM 3535 C THR A 212 10.116 12.285 -27.287 1.00 53.49 C ATOM 3536 O THR A 212 9.797 12.353 -26.099 1.00 53.04 O ATOM 3537 CB THR A 212 12.129 13.341 -28.374 1.00 54.65 C ATOM 3538 OG1 THR A 212 12.892 12.876 -27.273 1.00 54.66 O ATOM 3539 CG2 THR A 212 12.813 14.571 -28.992 1.00 47.76 C ATOM 3540 H THR A 212 10.715 14.631 -26.236 1.00 54.81 H ATOM 3541 HA THR A 212 10.047 13.625 -28.954 1.00 53.31 H ATOM 3542 HB THR A 212 12.190 12.553 -29.125 1.00 54.65 H ATOM 3543 HG1 THR A 212 13.815 13.123 -27.410 1.00 54.66 H ATOM 3544 HG21 THR A 212 13.819 14.330 -29.335 1.00 47.76 H ATOM 3545 HG22 THR A 212 12.253 14.937 -29.853 1.00 47.76 H ATOM 3546 HG23 THR A 212 12.899 15.390 -28.278 1.00 47.76 H ATOM 3547 N LYS A 213 10.077 11.146 -28.000 1.00 52.29 N ATOM 3548 CA LYS A 213 9.788 9.831 -27.420 1.00 48.92 C ATOM 3549 C LYS A 213 10.858 9.389 -26.408 1.00 47.29 C ATOM 3550 O LYS A 213 10.493 8.888 -25.347 1.00 45.98 O ATOM 3551 CB LYS A 213 9.644 8.775 -28.532 1.00 48.25 C ATOM 3552 CG LYS A 213 8.412 8.985 -29.423 1.00 51.20 C ATOM 3553 CD LYS A 213 8.256 7.866 -30.461 1.00 49.81 C ATOM 3554 CE LYS A 213 7.043 8.091 -31.373 1.00 54.53 C ATOM 3555 NZ LYS A 213 6.866 6.986 -32.332 1.00 54.50 N1+ ATOM 3556 H LYS A 213 10.333 11.156 -28.977 1.00 52.29 H ATOM 3557 HA LYS A 213 8.838 9.903 -26.887 1.00 48.92 H ATOM 3558 HB3 LYS A 213 9.564 7.787 -28.076 1.00 48.25 H ATOM 3559 HB2 LYS A 213 10.546 8.750 -29.146 1.00 48.25 H ATOM 3560 HG3 LYS A 213 8.481 9.946 -29.933 1.00 51.20 H ATOM 3561 HG2 LYS A 213 7.517 9.029 -28.802 1.00 51.20 H ATOM 3562 HD3 LYS A 213 8.164 6.910 -29.943 1.00 49.81 H ATOM 3563 HD2 LYS A 213 9.165 7.803 -31.062 1.00 49.81 H ATOM 3564 HE3 LYS A 213 7.158 9.021 -31.927 1.00 54.53 H ATOM 3565 HE2 LYS A 213 6.140 8.191 -30.771 1.00 54.53 H ATOM 3566 HZ1 LYS A 213 6.733 6.120 -31.829 1.00 54.50 H ATOM 3567 HZ2 LYS A 213 6.049 7.167 -32.899 1.00 54.50 H ATOM 3568 HZ3 LYS A 213 7.681 6.912 -32.924 1.00 54.50 H ATOM 3569 N ALA A 214 12.142 9.619 -26.742 1.00 45.00 N ATOM 3570 CA ALA A 214 13.308 9.288 -25.920 1.00 45.50 C ATOM 3571 C ALA A 214 13.303 9.960 -24.537 1.00 44.64 C ATOM 3572 O ALA A 214 13.713 9.318 -23.570 1.00 44.33 O ATOM 3573 CB ALA A 214 14.589 9.651 -26.689 1.00 41.66 C ATOM 3574 H ALA A 214 12.344 10.063 -27.626 1.00 45.00 H ATOM 3575 HA ALA A 214 13.300 8.207 -25.767 1.00 45.50 H ATOM 3576 HB1 ALA A 214 15.480 9.315 -26.157 1.00 41.66 H ATOM 3577 HB2 ALA A 214 14.604 9.180 -27.671 1.00 41.66 H ATOM 3578 HB3 ALA A 214 14.680 10.727 -26.839 1.00 41.66 H ATOM 3579 N ILE A 215 12.815 11.211 -24.461 1.00 45.01 N ATOM 3580 CA ILE A 215 12.642 11.981 -23.224 1.00 45.62 C ATOM 3581 C ILE A 215 11.721 11.285 -22.199 1.00 46.13 C ATOM 3582 O ILE A 215 12.058 11.259 -21.015 1.00 46.60 O ATOM 3583 CB ILE A 215 12.168 13.440 -23.536 1.00 44.20 C ATOM 3584 CG1 ILE A 215 13.371 14.255 -24.060 1.00 44.63 C ATOM 3585 CG2 ILE A 215 11.472 14.191 -22.378 1.00 46.06 C ATOM 3586 CD1 ILE A 215 13.037 15.547 -24.813 1.00 40.98 C ATOM 3587 H ILE A 215 12.513 11.670 -25.310 1.00 45.01 H ATOM 3588 HA ILE A 215 13.627 12.041 -22.757 1.00 45.62 H ATOM 3589 HB ILE A 215 11.444 13.383 -24.348 1.00 44.20 H ATOM 3590 HG13 ILE A 215 13.937 13.634 -24.751 1.00 44.63 H ATOM 3591 HG12 ILE A 215 14.047 14.484 -23.236 1.00 44.63 H ATOM 3592 HG21 ILE A 215 11.183 15.200 -22.665 1.00 46.06 H ATOM 3593 HG22 ILE A 215 10.556 13.700 -22.049 1.00 46.06 H ATOM 3594 HG23 ILE A 215 12.136 14.273 -21.523 1.00 46.06 H ATOM 3595 HD11 ILE A 215 13.944 16.123 -24.994 1.00 40.98 H ATOM 3596 HD12 ILE A 215 12.605 15.327 -25.786 1.00 40.98 H ATOM 3597 HD13 ILE A 215 12.346 16.185 -24.266 1.00 40.98 H ATOM 3598 N ASP A 216 10.623 10.677 -22.680 1.00 46.68 N ATOM 3599 CA ASP A 216 9.724 9.837 -21.882 1.00 46.86 C ATOM 3600 C ASP A 216 10.381 8.529 -21.405 1.00 46.12 C ATOM 3601 O ASP A 216 10.090 8.111 -20.287 1.00 45.25 O ATOM 3602 CB ASP A 216 8.383 9.538 -22.602 1.00 47.63 C ATOM 3603 CG ASP A 216 7.486 10.754 -22.901 1.00 47.35 C ATOM 3604 OD1 ASP A 216 7.630 11.797 -22.226 1.00 41.99 O ATOM 3605 OD2 ASP A 216 6.569 10.586 -23.734 1.00 42.26 O1- ATOM 3606 H ASP A 216 10.422 10.725 -23.669 1.00 46.68 H ATOM 3607 HA ASP A 216 9.496 10.394 -20.971 1.00 46.86 H ATOM 3608 HB3 ASP A 216 7.799 8.818 -22.031 1.00 47.63 H ATOM 3609 HB2 ASP A 216 8.601 9.053 -23.553 1.00 47.63 H ATOM 3610 N ILE A 217 11.269 7.921 -22.213 1.00 44.38 N ATOM 3611 CA ILE A 217 11.960 6.679 -21.844 1.00 43.53 C ATOM 3612 C ILE A 217 13.009 6.878 -20.727 1.00 43.93 C ATOM 3613 O ILE A 217 13.152 5.984 -19.892 1.00 45.89 O ATOM 3614 CB ILE A 217 12.655 5.971 -23.045 1.00 43.54 C ATOM 3615 CG1 ILE A 217 11.731 5.786 -24.269 1.00 45.78 C ATOM 3616 CG2 ILE A 217 13.260 4.614 -22.636 1.00 37.88 C ATOM 3617 CD1 ILE A 217 10.405 5.063 -24.003 1.00 41.92 C ATOM 3618 H ILE A 217 11.480 8.311 -23.122 1.00 44.38 H ATOM 3619 HA ILE A 217 11.207 5.996 -21.446 1.00 43.53 H ATOM 3620 HB ILE A 217 13.481 6.598 -23.385 1.00 43.54 H ATOM 3621 HG13 ILE A 217 12.269 5.261 -25.059 1.00 45.78 H ATOM 3622 HG12 ILE A 217 11.510 6.760 -24.692 1.00 45.78 H ATOM 3623 HG21 ILE A 217 13.579 4.030 -23.491 1.00 37.88 H ATOM 3624 HG22 ILE A 217 14.138 4.730 -22.001 1.00 37.88 H ATOM 3625 HG23 ILE A 217 12.528 4.012 -22.098 1.00 37.88 H ATOM 3626 HD11 ILE A 217 9.862 4.943 -24.939 1.00 41.92 H ATOM 3627 HD12 ILE A 217 10.563 4.072 -23.578 1.00 41.92 H ATOM 3628 HD13 ILE A 217 9.762 5.627 -23.328 1.00 41.92 H ATOM 3629 N TRP A 218 13.682 8.046 -20.689 1.00 42.79 N ATOM 3630 CA TRP A 218 14.576 8.427 -19.589 1.00 44.11 C ATOM 3631 C TRP A 218 13.831 8.538 -18.248 1.00 45.47 C ATOM 3632 O TRP A 218 14.343 8.047 -17.245 1.00 45.83 O ATOM 3633 CB TRP A 218 15.339 9.727 -19.923 1.00 43.37 C ATOM 3634 CG TRP A 218 16.256 10.258 -18.852 1.00 44.81 C ATOM 3635 CD1 TRP A 218 15.866 11.017 -17.802 1.00 46.12 C ATOM 3636 CD2 TRP A 218 17.686 10.021 -18.653 1.00 43.55 C ATOM 3637 NE1 TRP A 218 16.945 11.287 -16.989 1.00 47.40 N ATOM 3638 CE2 TRP A 218 18.095 10.698 -17.462 1.00 46.86 C ATOM 3639 CE3 TRP A 218 18.687 9.306 -19.352 1.00 45.96 C ATOM 3640 CZ2 TRP A 218 19.421 10.678 -16.998 1.00 43.08 C ATOM 3641 CZ3 TRP A 218 20.021 9.274 -18.893 1.00 42.10 C ATOM 3642 CH2 TRP A 218 20.388 9.957 -17.718 1.00 45.51 C ATOM 3643 H TRP A 218 13.521 8.739 -21.407 1.00 42.79 H ATOM 3644 HA TRP A 218 15.318 7.634 -19.477 1.00 44.11 H ATOM 3645 HB3 TRP A 218 14.631 10.516 -20.178 1.00 43.37 H ATOM 3646 HB2 TRP A 218 15.941 9.564 -20.814 1.00 43.37 H ATOM 3647 HD1 TRP A 218 14.853 11.352 -17.641 1.00 46.12 H ATOM 3648 HE1 TRP A 218 16.879 11.846 -16.147 1.00 47.40 H ATOM 3649 HE3 TRP A 218 18.424 8.768 -20.250 1.00 45.96 H ATOM 3650 HZ2 TRP A 218 19.693 11.209 -16.097 1.00 43.08 H ATOM 3651 HZ3 TRP A 218 20.767 8.720 -19.441 1.00 42.10 H ATOM 3652 HH2 TRP A 218 21.409 9.926 -17.368 1.00 45.51 H ATOM 3653 N ALA A 219 12.634 9.150 -18.265 1.00 47.64 N ATOM 3654 CA ALA A 219 11.765 9.288 -17.097 1.00 48.26 C ATOM 3655 C ALA A 219 11.232 7.944 -16.563 1.00 48.93 C ATOM 3656 O ALA A 219 11.066 7.819 -15.352 1.00 51.01 O ATOM 3657 CB ALA A 219 10.616 10.245 -17.431 1.00 48.07 C ATOM 3658 H ALA A 219 12.277 9.523 -19.133 1.00 47.64 H ATOM 3659 HA ALA A 219 12.356 9.746 -16.301 1.00 48.26 H ATOM 3660 HB1 ALA A 219 9.965 10.391 -16.569 1.00 48.07 H ATOM 3661 HB2 ALA A 219 10.992 11.226 -17.722 1.00 48.07 H ATOM 3662 HB3 ALA A 219 10.008 9.868 -18.253 1.00 48.07 H ATOM 3663 N ILE A 220 11.029 6.953 -17.452 1.00 48.21 N ATOM 3664 CA ILE A 220 10.688 5.572 -17.090 1.00 47.14 C ATOM 3665 C ILE A 220 11.887 4.821 -16.470 1.00 46.04 C ATOM 3666 O ILE A 220 11.678 4.016 -15.564 1.00 46.86 O ATOM 3667 CB ILE A 220 10.147 4.763 -18.308 1.00 45.48 C ATOM 3668 CG1 ILE A 220 8.830 5.373 -18.839 1.00 45.62 C ATOM 3669 CG2 ILE A 220 9.939 3.255 -18.034 1.00 44.63 C ATOM 3670 CD1 ILE A 220 8.485 4.947 -20.275 1.00 44.28 C ATOM 3671 H ILE A 220 11.169 7.134 -18.437 1.00 48.21 H ATOM 3672 HA ILE A 220 9.897 5.610 -16.338 1.00 47.14 H ATOM 3673 HB ILE A 220 10.885 4.846 -19.106 1.00 45.48 H ATOM 3674 HG13 ILE A 220 8.873 6.460 -18.812 1.00 45.62 H ATOM 3675 HG12 ILE A 220 8.012 5.118 -18.168 1.00 45.62 H ATOM 3676 HG21 ILE A 220 9.425 2.764 -18.856 1.00 44.63 H ATOM 3677 HG22 ILE A 220 10.882 2.724 -17.900 1.00 44.63 H ATOM 3678 HG23 ILE A 220 9.333 3.097 -17.141 1.00 44.63 H ATOM 3679 HD11 ILE A 220 8.281 5.822 -20.890 1.00 44.28 H ATOM 3680 HD12 ILE A 220 9.297 4.401 -20.755 1.00 44.28 H ATOM 3681 HD13 ILE A 220 7.601 4.308 -20.295 1.00 44.28 H ATOM 3682 N GLY A 221 13.114 5.124 -16.933 1.00 45.39 N ATOM 3683 CA GLY A 221 14.362 4.600 -16.375 1.00 45.79 C ATOM 3684 C GLY A 221 14.638 5.178 -14.980 1.00 45.88 C ATOM 3685 O GLY A 221 15.114 4.451 -14.110 1.00 45.82 O ATOM 3686 H GLY A 221 13.201 5.788 -17.691 1.00 45.39 H ATOM 3687 HA3 GLY A 221 15.185 4.862 -17.039 1.00 45.79 H ATOM 3688 HA2 GLY A 221 14.325 3.513 -16.318 1.00 45.79 H ATOM 3689 N CYS A 222 14.287 6.457 -14.753 1.00 44.93 N ATOM 3690 CA CYS A 222 14.337 7.124 -13.452 1.00 44.49 C ATOM 3691 C CYS A 222 13.362 6.480 -12.453 1.00 43.96 C ATOM 3692 O CYS A 222 13.770 6.169 -11.334 1.00 43.52 O ATOM 3693 CB CYS A 222 14.050 8.633 -13.554 1.00 44.14 C ATOM 3694 SG CYS A 222 15.373 9.485 -14.442 1.00 43.76 S ATOM 3695 H CYS A 222 13.937 7.013 -15.523 1.00 44.93 H ATOM 3696 HA CYS A 222 15.345 6.992 -13.060 1.00 44.49 H ATOM 3697 HB3 CYS A 222 13.969 9.086 -12.565 1.00 44.14 H ATOM 3698 HB2 CYS A 222 13.112 8.818 -14.073 1.00 44.14 H ATOM 3699 HG CYS A 222 14.869 10.714 -14.307 1.00 43.76 H ATOM 3700 N ILE A 223 12.110 6.264 -12.894 1.00 45.47 N ATOM 3701 CA ILE A 223 11.049 5.597 -12.138 1.00 45.97 C ATOM 3702 C ILE A 223 11.394 4.134 -11.780 1.00 47.17 C ATOM 3703 O ILE A 223 11.127 3.733 -10.650 1.00 46.83 O ATOM 3704 CB ILE A 223 9.682 5.686 -12.892 1.00 47.87 C ATOM 3705 CG1 ILE A 223 9.134 7.133 -12.858 1.00 47.72 C ATOM 3706 CG2 ILE A 223 8.582 4.708 -12.419 1.00 41.43 C ATOM 3707 CD1 ILE A 223 8.074 7.434 -13.932 1.00 46.34 C ATOM 3708 H ILE A 223 11.860 6.562 -13.828 1.00 45.47 H ATOM 3709 HA ILE A 223 10.946 6.138 -11.194 1.00 45.97 H ATOM 3710 HB ILE A 223 9.884 5.444 -13.936 1.00 47.87 H ATOM 3711 HG13 ILE A 223 9.944 7.853 -12.966 1.00 47.72 H ATOM 3712 HG12 ILE A 223 8.709 7.329 -11.875 1.00 47.72 H ATOM 3713 HG21 ILE A 223 7.637 4.896 -12.929 1.00 41.43 H ATOM 3714 HG22 ILE A 223 8.842 3.672 -12.634 1.00 41.43 H ATOM 3715 HG23 ILE A 223 8.400 4.801 -11.348 1.00 41.43 H ATOM 3716 HD11 ILE A 223 8.219 8.430 -14.349 1.00 46.34 H ATOM 3717 HD12 ILE A 223 8.115 6.727 -14.760 1.00 46.34 H ATOM 3718 HD13 ILE A 223 7.069 7.396 -13.511 1.00 46.34 H ATOM 3719 N PHE A 224 12.018 3.388 -12.711 1.00 48.38 N ATOM 3720 CA PHE A 224 12.469 2.008 -12.504 1.00 46.86 C ATOM 3721 C PHE A 224 13.617 1.881 -11.485 1.00 47.80 C ATOM 3722 O PHE A 224 13.577 0.971 -10.659 1.00 49.21 O ATOM 3723 CB PHE A 224 12.807 1.349 -13.860 1.00 46.94 C ATOM 3724 CG PHE A 224 13.341 -0.081 -13.833 1.00 43.57 C ATOM 3725 CD1 PHE A 224 12.778 -1.060 -12.982 1.00 45.37 C ATOM 3726 CD2 PHE A 224 14.293 -0.489 -14.792 1.00 44.16 C ATOM 3727 CE1 PHE A 224 13.225 -2.374 -13.036 1.00 44.50 C ATOM 3728 CE2 PHE A 224 14.709 -1.813 -14.847 1.00 41.62 C ATOM 3729 CZ PHE A 224 14.189 -2.749 -13.962 1.00 42.16 C ATOM 3730 H PHE A 224 12.191 3.781 -13.627 1.00 48.38 H ATOM 3731 HA PHE A 224 11.616 1.468 -12.088 1.00 46.86 H ATOM 3732 HB3 PHE A 224 13.529 1.978 -14.384 1.00 46.94 H ATOM 3733 HB2 PHE A 224 11.913 1.345 -14.482 1.00 46.94 H ATOM 3734 HD1 PHE A 224 12.005 -0.797 -12.275 1.00 45.37 H ATOM 3735 HD2 PHE A 224 14.694 0.221 -15.498 1.00 44.16 H ATOM 3736 HE1 PHE A 224 12.808 -3.112 -12.367 1.00 44.50 H ATOM 3737 HE2 PHE A 224 15.433 -2.118 -15.588 1.00 41.62 H ATOM 3738 HZ PHE A 224 14.520 -3.776 -14.010 1.00 42.16 H ATOM 3739 N ALA A 225 14.587 2.810 -11.523 1.00 48.17 N ATOM 3740 CA ALA A 225 15.678 2.888 -10.547 1.00 48.25 C ATOM 3741 C ALA A 225 15.183 3.207 -9.127 1.00 50.15 C ATOM 3742 O ALA A 225 15.704 2.641 -8.168 1.00 51.27 O ATOM 3743 CB ALA A 225 16.705 3.931 -11.003 1.00 46.48 C ATOM 3744 H ALA A 225 14.569 3.528 -12.235 1.00 48.17 H ATOM 3745 HA ALA A 225 16.172 1.915 -10.517 1.00 48.25 H ATOM 3746 HB1 ALA A 225 17.528 4.001 -10.291 1.00 46.48 H ATOM 3747 HB2 ALA A 225 17.136 3.672 -11.969 1.00 46.48 H ATOM 3748 HB3 ALA A 225 16.256 4.920 -11.098 1.00 46.48 H ATOM 3749 N GLU A 226 14.158 4.068 -9.027 1.00 51.12 N ATOM 3750 CA GLU A 226 13.488 4.423 -7.780 1.00 51.87 C ATOM 3751 C GLU A 226 12.567 3.319 -7.229 1.00 51.94 C ATOM 3752 O GLU A 226 12.400 3.243 -6.015 1.00 52.17 O ATOM 3753 CB GLU A 226 12.794 5.785 -7.971 1.00 51.19 C ATOM 3754 CG GLU A 226 11.967 6.283 -6.764 1.00 52.36 C ATOM 3755 CD GLU A 226 11.372 7.692 -6.900 1.00 50.62 C ATOM 3756 OE1 GLU A 226 11.483 8.294 -7.990 1.00 50.48 O ATOM 3757 OE2 GLU A 226 10.798 8.159 -5.893 1.00 57.17 O1- ATOM 3758 H GLU A 226 13.788 4.494 -9.866 1.00 51.12 H ATOM 3759 HA GLU A 226 14.261 4.554 -7.024 1.00 51.87 H ATOM 3760 HB3 GLU A 226 12.160 5.747 -8.859 1.00 51.19 H ATOM 3761 HB2 GLU A 226 13.573 6.515 -8.186 1.00 51.19 H ATOM 3762 HG3 GLU A 226 12.573 6.243 -5.859 1.00 52.36 H ATOM 3763 HG2 GLU A 226 11.139 5.600 -6.605 1.00 52.36 H ATOM 3764 N LEU A 227 12.024 2.458 -8.104 1.00 52.39 N ATOM 3765 CA LEU A 227 11.273 1.262 -7.716 1.00 51.11 C ATOM 3766 C LEU A 227 12.180 0.160 -7.131 1.00 51.05 C ATOM 3767 O LEU A 227 11.743 -0.552 -6.228 1.00 51.03 O ATOM 3768 CB LEU A 227 10.489 0.732 -8.937 1.00 51.06 C ATOM 3769 CG LEU A 227 9.152 1.445 -9.227 1.00 50.37 C ATOM 3770 CD1 LEU A 227 8.579 0.997 -10.591 1.00 45.57 C ATOM 3771 CD2 LEU A 227 8.138 1.267 -8.076 1.00 49.67 C ATOM 3772 H LEU A 227 12.168 2.596 -9.095 1.00 52.39 H ATOM 3773 HA LEU A 227 10.573 1.543 -6.928 1.00 51.11 H ATOM 3774 HB3 LEU A 227 10.277 -0.323 -8.802 1.00 51.06 H ATOM 3775 HB2 LEU A 227 11.126 0.777 -9.819 1.00 51.06 H ATOM 3776 HG LEU A 227 9.352 2.514 -9.300 1.00 50.37 H ATOM 3777 HD11 LEU A 227 7.536 0.687 -10.540 1.00 45.57 H ATOM 3778 HD12 LEU A 227 8.631 1.810 -11.313 1.00 45.57 H ATOM 3779 HD13 LEU A 227 9.136 0.160 -11.015 1.00 45.57 H ATOM 3780 HD21 LEU A 227 7.190 0.853 -8.404 1.00 49.67 H ATOM 3781 HD22 LEU A 227 8.508 0.603 -7.294 1.00 49.67 H ATOM 3782 HD23 LEU A 227 7.914 2.224 -7.609 1.00 49.67 H ATOM 3783 N LEU A 228 13.419 0.048 -7.640 1.00 49.44 N ATOM 3784 CA LEU A 228 14.416 -0.930 -7.199 1.00 50.60 C ATOM 3785 C LEU A 228 15.089 -0.570 -5.859 1.00 50.39 C ATOM 3786 O LEU A 228 15.512 -1.488 -5.159 1.00 51.19 O ATOM 3787 CB LEU A 228 15.488 -1.087 -8.302 1.00 50.20 C ATOM 3788 CG LEU A 228 15.016 -1.838 -9.568 1.00 51.02 C ATOM 3789 CD1 LEU A 228 16.002 -1.623 -10.738 1.00 48.93 C ATOM 3790 CD2 LEU A 228 14.778 -3.336 -9.296 1.00 51.45 C ATOM 3791 H LEU A 228 13.698 0.658 -8.396 1.00 49.44 H ATOM 3792 HA LEU A 228 13.918 -1.890 -7.056 1.00 50.60 H ATOM 3793 HB3 LEU A 228 16.359 -1.605 -7.903 1.00 50.20 H ATOM 3794 HB2 LEU A 228 15.843 -0.093 -8.579 1.00 50.20 H ATOM 3795 HG LEU A 228 14.060 -1.421 -9.883 1.00 51.02 H ATOM 3796 HD11 LEU A 228 16.368 -2.560 -11.156 1.00 48.93 H ATOM 3797 HD12 LEU A 228 15.526 -1.072 -11.550 1.00 48.93 H ATOM 3798 HD13 LEU A 228 16.879 -1.049 -10.438 1.00 48.93 H ATOM 3799 HD21 LEU A 228 14.820 -3.927 -10.211 1.00 51.45 H ATOM 3800 HD22 LEU A 228 15.517 -3.742 -8.605 1.00 51.45 H ATOM 3801 HD23 LEU A 228 13.794 -3.502 -8.859 1.00 51.45 H ATOM 3802 N THR A 229 15.206 0.731 -5.539 1.00 50.98 N ATOM 3803 CA THR A 229 16.041 1.233 -4.438 1.00 51.07 C ATOM 3804 C THR A 229 15.267 2.067 -3.390 1.00 52.96 C ATOM 3805 O THR A 229 15.828 2.328 -2.326 1.00 55.55 O ATOM 3806 CB THR A 229 17.179 2.131 -4.997 1.00 50.77 C ATOM 3807 OG1 THR A 229 16.673 3.347 -5.510 1.00 47.78 O ATOM 3808 CG2 THR A 229 18.032 1.446 -6.080 1.00 48.43 C ATOM 3809 H THR A 229 14.827 1.427 -6.166 1.00 50.98 H ATOM 3810 HA THR A 229 16.503 0.406 -3.895 1.00 51.07 H ATOM 3811 HB THR A 229 17.846 2.396 -4.176 1.00 50.77 H ATOM 3812 HG1 THR A 229 16.238 3.163 -6.350 1.00 47.78 H ATOM 3813 HG21 THR A 229 18.875 2.073 -6.373 1.00 48.43 H ATOM 3814 HG22 THR A 229 18.431 0.495 -5.726 1.00 48.43 H ATOM 3815 HG23 THR A 229 17.459 1.230 -6.979 1.00 48.43 H ATOM 3816 N SER A 230 14.024 2.477 -3.702 1.00 53.51 N ATOM 3817 CA SER A 230 13.136 3.340 -2.905 1.00 55.16 C ATOM 3818 C SER A 230 13.567 4.824 -2.802 1.00 55.47 C ATOM 3819 O SER A 230 12.921 5.568 -2.065 1.00 54.50 O ATOM 3820 CB SER A 230 12.803 2.711 -1.527 1.00 55.54 C ATOM 3821 OG SER A 230 11.994 1.566 -1.700 1.00 56.13 O ATOM 3822 H SER A 230 13.646 2.220 -4.603 1.00 53.51 H ATOM 3823 HA SER A 230 12.200 3.377 -3.461 1.00 55.16 H ATOM 3824 HB3 SER A 230 12.230 3.402 -0.908 1.00 55.54 H ATOM 3825 HB2 SER A 230 13.693 2.454 -0.953 1.00 55.54 H ATOM 3826 HG SER A 230 12.522 0.884 -2.122 1.00 56.13 H ATOM 3827 N GLU A 231 14.609 5.244 -3.545 1.00 56.61 N ATOM 3828 CA GLU A 231 15.128 6.618 -3.571 1.00 57.16 C ATOM 3829 C GLU A 231 15.149 7.139 -5.022 1.00 55.89 C ATOM 3830 O GLU A 231 15.536 6.369 -5.902 1.00 54.68 O ATOM 3831 CB GLU A 231 16.572 6.636 -3.024 1.00 58.59 C ATOM 3832 CG GLU A 231 16.732 6.000 -1.624 1.00 67.11 C ATOM 3833 CD GLU A 231 18.007 6.386 -0.853 1.00 76.39 C ATOM 3834 OE1 GLU A 231 18.874 7.096 -1.411 1.00 79.23 O ATOM 3835 OE2 GLU A 231 18.082 5.972 0.324 1.00 83.58 O1- ATOM 3836 H GLU A 231 15.091 4.584 -4.140 1.00 56.61 H ATOM 3837 HA GLU A 231 14.521 7.250 -2.927 1.00 57.16 H ATOM 3838 HB3 GLU A 231 16.890 7.680 -2.995 1.00 58.59 H ATOM 3839 HB2 GLU A 231 17.251 6.136 -3.718 1.00 58.59 H ATOM 3840 HG3 GLU A 231 16.715 4.913 -1.723 1.00 67.11 H ATOM 3841 HG2 GLU A 231 15.869 6.255 -1.011 1.00 67.11 H ATOM 3842 N PRO A 232 14.794 8.428 -5.270 1.00 54.06 N ATOM 3843 CA PRO A 232 15.004 9.057 -6.591 1.00 53.11 C ATOM 3844 C PRO A 232 16.486 9.050 -7.012 1.00 53.33 C ATOM 3845 O PRO A 232 17.324 9.584 -6.282 1.00 53.27 O ATOM 3846 CB PRO A 232 14.444 10.487 -6.448 1.00 52.82 C ATOM 3847 CG PRO A 232 13.614 10.478 -5.176 1.00 54.31 C ATOM 3848 CD PRO A 232 14.251 9.395 -4.316 1.00 54.73 C ATOM 3849 HA PRO A 232 14.401 8.506 -7.311 1.00 53.11 H ATOM 3850 HB3 PRO A 232 13.847 10.780 -7.313 1.00 52.82 H ATOM 3851 HB2 PRO A 232 15.239 11.226 -6.358 1.00 52.82 H ATOM 3852 HG3 PRO A 232 12.594 10.186 -5.425 1.00 54.31 H ATOM 3853 HG2 PRO A 232 13.564 11.449 -4.685 1.00 54.31 H ATOM 3854 HD2 PRO A 232 15.070 9.800 -3.720 1.00 54.73 H ATOM 3855 HD3 PRO A 232 13.502 8.976 -3.645 1.00 54.73 H ATOM 3856 N ILE A 233 16.778 8.403 -8.153 1.00 52.76 N ATOM 3857 CA ILE A 233 18.135 8.196 -8.671 1.00 51.32 C ATOM 3858 C ILE A 233 18.938 9.488 -8.929 1.00 51.49 C ATOM 3859 O ILE A 233 20.146 9.486 -8.700 1.00 51.33 O ATOM 3860 CB ILE A 233 18.158 7.274 -9.930 1.00 50.94 C ATOM 3861 CG1 ILE A 233 19.580 7.036 -10.492 1.00 50.15 C ATOM 3862 CG2 ILE A 233 17.204 7.741 -11.044 1.00 47.69 C ATOM 3863 CD1 ILE A 233 19.754 5.740 -11.293 1.00 44.89 C ATOM 3864 H ILE A 233 16.030 7.996 -8.697 1.00 52.76 H ATOM 3865 HA ILE A 233 18.674 7.674 -7.882 1.00 51.32 H ATOM 3866 HB ILE A 233 17.799 6.301 -9.599 1.00 50.94 H ATOM 3867 HG13 ILE A 233 20.287 6.996 -9.665 1.00 50.15 H ATOM 3868 HG12 ILE A 233 19.883 7.882 -11.107 1.00 50.15 H ATOM 3869 HG21 ILE A 233 17.293 7.117 -11.932 1.00 47.69 H ATOM 3870 HG22 ILE A 233 16.166 7.695 -10.721 1.00 47.69 H ATOM 3871 HG23 ILE A 233 17.408 8.764 -11.345 1.00 47.69 H ATOM 3872 HD11 ILE A 233 20.652 5.796 -11.907 1.00 44.89 H ATOM 3873 HD12 ILE A 233 19.858 4.879 -10.632 1.00 44.89 H ATOM 3874 HD13 ILE A 233 18.915 5.550 -11.960 1.00 44.89 H ATOM 3875 N PHE A 234 18.257 10.572 -9.330 1.00 51.77 N ATOM 3876 CA PHE A 234 18.863 11.878 -9.567 1.00 52.49 C ATOM 3877 C PHE A 234 18.223 12.940 -8.653 1.00 52.51 C ATOM 3878 O PHE A 234 17.870 14.019 -9.130 1.00 49.36 O ATOM 3879 CB PHE A 234 18.785 12.234 -11.069 1.00 52.36 C ATOM 3880 CG PHE A 234 19.340 11.191 -12.025 1.00 51.46 C ATOM 3881 CD1 PHE A 234 20.698 10.817 -11.975 1.00 49.42 C ATOM 3882 CD2 PHE A 234 18.490 10.557 -12.953 1.00 47.57 C ATOM 3883 CE1 PHE A 234 21.180 9.854 -12.853 1.00 51.46 C ATOM 3884 CE2 PHE A 234 18.989 9.585 -13.809 1.00 46.99 C ATOM 3885 CZ PHE A 234 20.332 9.240 -13.763 1.00 45.02 C ATOM 3886 H PHE A 234 17.259 10.508 -9.498 1.00 51.77 H ATOM 3887 HA PHE A 234 19.915 11.847 -9.297 1.00 52.49 H ATOM 3888 HB3 PHE A 234 19.355 13.146 -11.244 1.00 52.36 H ATOM 3889 HB2 PHE A 234 17.756 12.458 -11.348 1.00 52.36 H ATOM 3890 HD1 PHE A 234 21.366 11.277 -11.261 1.00 49.42 H ATOM 3891 HD2 PHE A 234 17.445 10.821 -12.993 1.00 47.57 H ATOM 3892 HE1 PHE A 234 22.219 9.577 -12.825 1.00 51.46 H ATOM 3893 HE2 PHE A 234 18.336 9.101 -14.519 1.00 46.99 H ATOM 3894 HZ PHE A 234 20.716 8.489 -14.438 1.00 45.02 H ATOM 3895 N HIS A 235 18.111 12.624 -7.347 1.00 55.61 N ATOM 3896 CA HIS A 235 17.644 13.533 -6.293 1.00 57.77 C ATOM 3897 C HIS A 235 18.562 14.761 -6.143 1.00 57.75 C ATOM 3898 O HIS A 235 19.773 14.595 -6.001 1.00 58.16 O ATOM 3899 CB HIS A 235 17.536 12.766 -4.957 1.00 58.39 C ATOM 3900 CG HIS A 235 16.974 13.579 -3.815 1.00 62.31 C ATOM 3901 ND1 HIS A 235 17.766 14.335 -2.967 1.00 65.52 N ATOM 3902 CD2 HIS A 235 15.682 13.761 -3.372 1.00 67.89 C ATOM 3903 CE1 HIS A 235 16.952 14.938 -2.097 1.00 69.21 C ATOM 3904 NE2 HIS A 235 15.672 14.636 -2.283 1.00 71.59 N ATOM 3905 H HIS A 235 18.391 11.704 -7.038 1.00 55.61 H ATOM 3906 HA HIS A 235 16.643 13.868 -6.574 1.00 57.77 H ATOM 3907 HB3 HIS A 235 18.514 12.382 -4.664 1.00 58.39 H ATOM 3908 HB2 HIS A 235 16.900 11.892 -5.073 1.00 58.39 H ATOM 3909 HD1 HIS A 235 18.771 14.430 -3.010 1.00 65.52 H ATOM 3910 HD2 HIS A 235 14.765 13.345 -3.760 1.00 67.89 H ATOM 3911 HE1 HIS A 235 17.297 15.605 -1.321 1.00 69.21 H ATOM 3912 N CYS A 236 17.957 15.957 -6.149 1.00 58.63 N ATOM 3913 CA CYS A 236 18.660 17.238 -6.159 1.00 60.81 C ATOM 3914 C CYS A 236 17.815 18.316 -5.450 1.00 61.73 C ATOM 3915 O CYS A 236 16.586 18.234 -5.448 1.00 59.65 O ATOM 3916 CB CYS A 236 19.018 17.626 -7.613 1.00 59.64 C ATOM 3917 SG CYS A 236 20.050 19.114 -7.719 1.00 64.11 S ATOM 3918 H CYS A 236 16.951 16.004 -6.234 1.00 58.63 H ATOM 3919 HA CYS A 236 19.585 17.132 -5.590 1.00 60.81 H ATOM 3920 HB3 CYS A 236 18.106 17.797 -8.185 1.00 59.64 H ATOM 3921 HB2 CYS A 236 19.554 16.815 -8.106 1.00 59.64 H ATOM 3922 HG CYS A 236 20.235 19.067 -9.041 1.00 64.11 H ATOM 3923 N ARG A 237 18.502 19.325 -4.888 1.00 65.47 N ATOM 3924 CA ARG A 237 17.926 20.534 -4.292 1.00 69.21 C ATOM 3925 C ARG A 237 17.269 21.457 -5.350 1.00 72.27 C ATOM 3926 O ARG A 237 17.545 21.333 -6.543 1.00 72.09 O ATOM 3927 CB ARG A 237 19.048 21.228 -3.478 1.00 69.67 C ATOM 3928 CG ARG A 237 18.618 22.451 -2.639 0.00 69.17 C ATOM 3929 CD ARG A 237 19.775 23.082 -1.848 0.00 69.14 C ATOM 3930 NE ARG A 237 19.355 24.297 -1.123 0.00 69.09 N ATOM 3931 CZ ARG A 237 19.244 25.554 -1.599 0.00 69.04 C ATOM 3932 NH1 ARG A 237 19.529 25.878 -2.868 0.00 69.01 N ATOM 3933 NH2 ARG A 237 18.830 26.523 -0.773 0.00 68.99 N1+ ATOM 3934 H ARG A 237 19.509 19.325 -4.965 1.00 65.47 H ATOM 3935 HA ARG A 237 17.146 20.217 -3.597 1.00 69.21 H ATOM 3936 HB3 ARG A 237 19.851 21.514 -4.156 1.00 69.67 H ATOM 3937 HB2 ARG A 237 19.491 20.497 -2.800 1.00 69.67 H ATOM 3938 HG3 ARG A 237 17.875 22.086 -1.929 1.00 69.17 H ATOM 3939 HG2 ARG A 237 18.121 23.220 -3.228 1.00 69.17 H ATOM 3940 HD3 ARG A 237 20.666 23.235 -2.458 1.00 69.14 H ATOM 3941 HD2 ARG A 237 20.066 22.384 -1.063 1.00 69.14 H ATOM 3942 HE ARG A 237 19.088 24.140 -0.163 1.00 69.09 H ATOM 3943 HH12 ARG A 237 19.425 26.825 -3.200 1.00 69.01 H ATOM 3944 HH11 ARG A 237 19.805 25.155 -3.528 1.00 69.01 H ATOM 3945 HH22 ARG A 237 18.732 27.471 -1.108 1.00 68.99 H ATOM 3946 HH21 ARG A 237 18.607 26.316 0.190 1.00 68.99 H ATOM 3947 N GLN A 238 16.386 22.350 -4.878 1.00 76.47 N ATOM 3948 CA GLN A 238 15.621 23.310 -5.676 1.00 79.58 C ATOM 3949 C GLN A 238 16.385 24.635 -5.903 1.00 81.52 C ATOM 3950 O GLN A 238 17.104 25.083 -5.011 1.00 82.48 O ATOM 3951 CB GLN A 238 14.304 23.597 -4.918 1.00 79.51 C ATOM 3952 CG GLN A 238 13.383 22.370 -4.751 0.00 79.33 C ATOM 3953 CD GLN A 238 12.188 22.631 -3.828 0.00 79.36 C ATOM 3954 OE1 GLN A 238 11.690 23.750 -3.736 0.00 79.35 O ATOM 3955 NE2 GLN A 238 11.703 21.585 -3.157 0.00 79.37 N ATOM 3956 H GLN A 238 16.223 22.394 -3.883 1.00 76.47 H ATOM 3957 HA GLN A 238 15.383 22.867 -6.645 1.00 79.58 H ATOM 3958 HB3 GLN A 238 13.745 24.372 -5.443 1.00 79.51 H ATOM 3959 HB2 GLN A 238 14.540 24.011 -3.936 1.00 79.51 H ATOM 3960 HG3 GLN A 238 13.942 21.520 -4.359 1.00 79.33 H ATOM 3961 HG2 GLN A 238 12.995 22.075 -5.724 1.00 79.33 H ATOM 3962 HE22 GLN A 238 10.910 21.707 -2.544 1.00 79.37 H ATOM 3963 HE21 GLN A 238 12.123 20.672 -3.251 1.00 79.37 H ATOM 3964 N GLU A 239 16.123 25.273 -7.061 1.00 83.62 N ATOM 3965 CA GLU A 239 16.404 26.679 -7.424 1.00 84.73 C ATOM 3966 C GLU A 239 17.869 27.131 -7.619 1.00 85.52 C ATOM 3967 O GLU A 239 18.057 28.256 -8.083 1.00 86.64 O ATOM 3968 CB GLU A 239 15.721 27.668 -6.450 1.00 85.11 C ATOM 3969 CG GLU A 239 14.188 27.543 -6.347 0.00 84.81 C ATOM 3970 CD GLU A 239 13.522 28.606 -5.454 0.00 84.90 C ATOM 3971 OE1 GLU A 239 14.152 29.650 -5.168 0.00 84.88 O ATOM 3972 OE2 GLU A 239 12.360 28.355 -5.068 0.00 84.90 O1- ATOM 3973 H GLU A 239 15.535 24.792 -7.725 1.00 83.62 H ATOM 3974 HA GLU A 239 15.936 26.811 -8.401 1.00 84.73 H ATOM 3975 HB3 GLU A 239 15.960 28.687 -6.760 1.00 85.11 H ATOM 3976 HB2 GLU A 239 16.154 27.559 -5.454 1.00 85.11 H ATOM 3977 HG3 GLU A 239 13.923 26.557 -5.969 1.00 84.81 H ATOM 3978 HG2 GLU A 239 13.751 27.620 -7.343 1.00 84.81 H ATOM 3979 N ASP A 240 18.863 26.294 -7.282 1.00 39.20 N ATOM 3980 CA ASP A 240 20.321 26.557 -7.232 1.00 38.03 C ATOM 3981 C ASP A 240 20.981 27.227 -8.463 1.00 38.61 C ATOM 3982 O ASP A 240 22.146 27.619 -8.383 1.00 38.19 O ATOM 3983 CB ASP A 240 21.162 25.283 -6.897 1.00 0.00 C ATOM 3984 CG ASP A 240 20.384 24.048 -6.424 1.00 0.00 C ATOM 3985 OD1 ASP A 240 19.827 23.348 -7.299 1.00 0.00 O ATOM 3986 OD2 ASP A 240 20.217 23.920 -5.194 1.00 0.00 O1- ATOM 3987 HB2 ASP A 240 21.751 24.962 -7.757 1.00 0.00 H ATOM 3988 HB3 ASP A 240 21.901 25.535 -6.134 1.00 0.00 H ATOM 3989 H ASP A 240 18.600 25.382 -6.932 1.00 39.20 H ATOM 3990 HA ASP A 240 20.447 27.254 -6.402 1.00 38.03 H ATOM 3991 N ILE A 241 20.264 27.253 -9.592 1.00 39.83 N ATOM 3992 CA ILE A 241 20.813 27.210 -10.939 1.00 39.77 C ATOM 3993 C ILE A 241 20.335 28.353 -11.867 1.00 40.23 C ATOM 3994 O ILE A 241 20.592 28.285 -13.069 1.00 39.92 O ATOM 3995 CB ILE A 241 20.399 25.853 -11.566 1.00 0.00 C ATOM 3996 CG1 ILE A 241 18.866 25.669 -11.753 1.00 0.00 C ATOM 3997 CG2 ILE A 241 21.060 24.650 -10.865 1.00 0.00 C ATOM 3998 CD1 ILE A 241 18.080 25.052 -10.581 1.00 0.00 C ATOM 3999 HB ILE A 241 20.830 25.847 -12.566 1.00 0.00 H ATOM 4000 HG12 ILE A 241 18.377 26.589 -12.066 1.00 0.00 H ATOM 4001 HG13 ILE A 241 18.739 25.008 -12.599 1.00 0.00 H ATOM 4002 HG21 ILE A 241 20.813 23.717 -11.369 1.00 0.00 H ATOM 4003 HG22 ILE A 241 22.143 24.753 -10.851 1.00 0.00 H ATOM 4004 HG23 ILE A 241 20.746 24.540 -9.830 1.00 0.00 H ATOM 4005 HD11 ILE A 241 17.131 25.567 -10.435 1.00 0.00 H ATOM 4006 HD12 ILE A 241 17.853 24.004 -10.777 1.00 0.00 H ATOM 4007 HD13 ILE A 241 18.616 25.089 -9.638 1.00 0.00 H ATOM 4008 H ILE A 241 19.294 26.979 -9.530 1.00 39.83 H ATOM 4009 HA ILE A 241 21.903 27.265 -10.910 1.00 39.77 H ATOM 4010 N LYS A 242 19.671 29.380 -11.305 1.00 40.52 N ATOM 4011 CA LYS A 242 19.146 30.571 -11.999 1.00 40.12 C ATOM 4012 C LYS A 242 17.971 30.227 -12.949 1.00 40.07 C ATOM 4013 O LYS A 242 17.932 30.727 -14.074 1.00 39.51 O ATOM 4014 CB LYS A 242 20.268 31.380 -12.720 1.00 0.00 C ATOM 4015 CG LYS A 242 21.562 31.613 -11.903 1.00 0.00 C ATOM 4016 CD LYS A 242 22.773 30.795 -12.408 1.00 0.00 C ATOM 4017 CE LYS A 242 23.590 30.149 -11.277 1.00 0.00 C ATOM 4018 NZ LYS A 242 24.652 29.270 -11.803 1.00 0.00 N1+ ATOM 4019 HB2 LYS A 242 20.523 30.908 -13.669 1.00 0.00 H ATOM 4020 HB3 LYS A 242 19.857 32.350 -13.001 1.00 0.00 H ATOM 4021 HG2 LYS A 242 21.819 32.673 -11.939 1.00 0.00 H ATOM 4022 HG3 LYS A 242 21.376 31.407 -10.848 1.00 0.00 H ATOM 4023 HD2 LYS A 242 22.462 30.030 -13.118 1.00 0.00 H ATOM 4024 HD3 LYS A 242 23.422 31.461 -12.978 1.00 0.00 H ATOM 4025 HE2 LYS A 242 24.039 30.916 -10.645 1.00 0.00 H ATOM 4026 HE3 LYS A 242 22.941 29.549 -10.639 1.00 0.00 H ATOM 4027 HZ1 LYS A 242 25.292 29.810 -12.367 1.00 0.00 H ATOM 4028 HZ2 LYS A 242 25.155 28.851 -11.034 1.00 0.00 H ATOM 4029 HZ3 LYS A 242 24.240 28.542 -12.369 1.00 0.00 H ATOM 4030 H LYS A 242 19.505 29.351 -10.309 1.00 40.52 H ATOM 4031 HA LYS A 242 18.728 31.212 -11.222 1.00 40.12 H ATOM 4032 N THR A 243 17.056 29.359 -12.476 1.00 39.24 N ATOM 4033 CA THR A 243 15.968 28.715 -13.226 1.00 39.28 C ATOM 4034 C THR A 243 14.996 29.675 -13.969 1.00 39.02 C ATOM 4035 O THR A 243 14.875 30.841 -13.593 1.00 37.21 O ATOM 4036 CB THR A 243 15.176 27.758 -12.286 1.00 0.00 C ATOM 4037 OG1 THR A 243 14.250 26.953 -12.994 1.00 0.00 O ATOM 4038 CG2 THR A 243 14.397 28.463 -11.160 1.00 0.00 C ATOM 4039 HB THR A 243 15.886 27.071 -11.825 1.00 0.00 H ATOM 4040 HG1 THR A 243 14.736 26.320 -13.531 1.00 0.00 H ATOM 4041 HG21 THR A 243 15.059 29.063 -10.535 1.00 0.00 H ATOM 4042 HG22 THR A 243 13.618 29.120 -11.547 1.00 0.00 H ATOM 4043 HG23 THR A 243 13.914 27.735 -10.507 1.00 0.00 H ATOM 4044 H THR A 243 17.166 29.031 -11.528 1.00 39.24 H ATOM 4045 HA THR A 243 16.455 28.100 -13.984 1.00 39.28 H ATOM 4046 N SER A 244 14.355 29.123 -15.016 1.00 86.11 N ATOM 4047 CA SER A 244 13.507 29.695 -16.079 1.00 86.07 C ATOM 4048 C SER A 244 14.135 29.397 -17.451 1.00 85.26 C ATOM 4049 O SER A 244 13.407 29.094 -18.397 1.00 85.69 O ATOM 4050 CB SER A 244 13.097 31.180 -15.900 1.00 86.52 C ATOM 4051 OG SER A 244 14.154 32.084 -16.161 1.00 86.47 O ATOM 4052 HA SER A 244 12.586 29.112 -16.031 1.00 86.07 H ATOM 4053 HB3 SER A 244 12.687 31.360 -14.905 1.00 86.52 H ATOM 4054 HB2 SER A 244 12.293 31.414 -16.599 1.00 86.52 H ATOM 4055 HG SER A 244 14.777 32.028 -15.429 1.00 86.47 H ATOM 4056 H SER A 244 14.543 28.142 -15.167 1.00 86.11 H ATOM 4057 N ASN A 245 15.479 29.404 -17.495 1.00 83.09 N ATOM 4058 CA ASN A 245 16.315 28.826 -18.549 1.00 80.73 C ATOM 4059 C ASN A 245 16.253 27.277 -18.522 1.00 77.41 C ATOM 4060 O ASN A 245 15.941 26.708 -17.472 1.00 76.67 O ATOM 4061 CB ASN A 245 17.769 29.363 -18.394 1.00 81.67 C ATOM 4062 CG ASN A 245 18.526 28.972 -17.111 1.00 83.09 C ATOM 4063 OD1 ASN A 245 17.940 28.554 -16.116 1.00 84.51 O ATOM 4064 ND2 ASN A 245 19.852 29.116 -17.128 1.00 83.47 N ATOM 4065 H ASN A 245 15.980 29.663 -16.656 1.00 83.09 H ATOM 4066 HA ASN A 245 15.915 29.182 -19.499 1.00 80.73 H ATOM 4067 HB3 ASN A 245 17.756 30.452 -18.453 1.00 81.67 H ATOM 4068 HB2 ASN A 245 18.376 29.032 -19.235 1.00 81.67 H ATOM 4069 HD22 ASN A 245 20.388 28.872 -16.307 1.00 83.47 H ATOM 4070 HD21 ASN A 245 20.326 29.467 -17.948 1.00 83.47 H ATOM 4071 N PRO A 246 16.585 26.608 -19.650 1.00 73.51 N ATOM 4072 CA PRO A 246 16.658 25.138 -19.683 1.00 70.45 C ATOM 4073 C PRO A 246 17.875 24.527 -18.960 1.00 67.03 C ATOM 4074 O PRO A 246 17.811 23.345 -18.631 1.00 66.23 O ATOM 4075 CB PRO A 246 16.680 24.816 -21.182 1.00 70.32 C ATOM 4076 CG PRO A 246 17.355 26.023 -21.814 1.00 72.63 C ATOM 4077 CD PRO A 246 16.830 27.183 -20.976 1.00 73.71 C ATOM 4078 HA PRO A 246 15.759 24.704 -19.241 1.00 70.45 H ATOM 4079 HB3 PRO A 246 15.656 24.730 -21.545 1.00 70.32 H ATOM 4080 HB2 PRO A 246 17.188 23.881 -21.417 1.00 70.32 H ATOM 4081 HG3 PRO A 246 17.150 26.134 -22.879 1.00 72.63 H ATOM 4082 HG2 PRO A 246 18.436 25.942 -21.690 1.00 72.63 H ATOM 4083 HD2 PRO A 246 17.536 28.011 -20.979 1.00 73.71 H ATOM 4084 HD3 PRO A 246 15.882 27.542 -21.378 1.00 73.71 H ATOM 4085 N TYR A 247 18.942 25.311 -18.724 1.00 62.92 N ATOM 4086 CA TYR A 247 20.161 24.847 -18.062 1.00 61.50 C ATOM 4087 C TYR A 247 19.989 24.797 -16.537 1.00 61.34 C ATOM 4088 O TYR A 247 19.649 25.816 -15.935 1.00 62.85 O ATOM 4089 CB TYR A 247 21.342 25.746 -18.471 1.00 61.66 C ATOM 4090 CG TYR A 247 22.705 25.253 -18.014 1.00 60.68 C ATOM 4091 CD1 TYR A 247 23.331 24.189 -18.696 1.00 58.55 C ATOM 4092 CD2 TYR A 247 23.353 25.856 -16.915 1.00 57.85 C ATOM 4093 CE1 TYR A 247 24.606 23.744 -18.301 1.00 56.07 C ATOM 4094 CE2 TYR A 247 24.627 25.409 -16.517 1.00 58.42 C ATOM 4095 CZ TYR A 247 25.259 24.360 -17.216 1.00 59.00 C ATOM 4096 OH TYR A 247 26.513 23.961 -16.864 1.00 58.13 O ATOM 4097 H TYR A 247 18.931 26.278 -19.014 1.00 62.92 H ATOM 4098 HA TYR A 247 20.377 23.842 -18.420 1.00 61.50 H ATOM 4099 HB3 TYR A 247 21.185 26.766 -18.118 1.00 61.66 H ATOM 4100 HB2 TYR A 247 21.375 25.817 -19.557 1.00 61.66 H ATOM 4101 HD1 TYR A 247 22.837 23.717 -19.534 1.00 58.55 H ATOM 4102 HD2 TYR A 247 22.879 26.667 -16.382 1.00 57.85 H ATOM 4103 HE1 TYR A 247 25.088 22.941 -18.839 1.00 56.07 H ATOM 4104 HE2 TYR A 247 25.127 25.886 -15.687 1.00 58.42 H ATOM 4105 HH TYR A 247 26.951 24.586 -16.274 1.00 58.13 H ATOM 4106 N HIS A 248 20.251 23.616 -15.950 1.00 60.78 N ATOM 4107 CA HIS A 248 20.195 23.389 -14.508 1.00 61.08 C ATOM 4108 C HIS A 248 21.473 22.654 -14.078 1.00 58.91 C ATOM 4109 O HIS A 248 21.551 21.435 -14.229 1.00 58.81 O ATOM 4110 CB HIS A 248 18.889 22.655 -14.094 1.00 63.68 C ATOM 4111 CG HIS A 248 17.586 23.313 -14.515 1.00 68.18 C ATOM 4112 ND1 HIS A 248 17.093 23.249 -15.806 1.00 72.43 N ATOM 4113 CD2 HIS A 248 16.647 24.047 -13.820 1.00 71.25 C ATOM 4114 CE1 HIS A 248 15.962 23.957 -15.844 1.00 75.22 C ATOM 4115 NE2 HIS A 248 15.630 24.477 -14.673 1.00 73.61 N ATOM 4116 H HIS A 248 20.542 22.829 -16.512 1.00 60.78 H ATOM 4117 HA HIS A 248 20.208 24.352 -14.010 1.00 61.08 H ATOM 4118 HB3 HIS A 248 18.868 22.545 -13.009 1.00 63.68 H ATOM 4119 HB2 HIS A 248 18.893 21.640 -14.487 1.00 63.68 H ATOM 4120 HD1 HIS A 248 17.539 22.812 -16.602 1.00 72.43 H ATOM 4121 HD2 HIS A 248 16.619 24.315 -12.777 1.00 71.25 H ATOM 4122 HE1 HIS A 248 15.388 24.106 -16.746 1.00 75.22 H ATOM 4123 N HIS A 249 22.456 23.429 -13.578 1.00 56.95 N ATOM 4124 CA HIS A 249 23.795 22.985 -13.175 1.00 56.40 C ATOM 4125 C HIS A 249 23.811 21.839 -12.148 1.00 55.36 C ATOM 4126 O HIS A 249 24.416 20.810 -12.431 1.00 54.76 O ATOM 4127 CB HIS A 249 24.639 24.193 -12.705 1.00 56.04 C ATOM 4128 CG HIS A 249 26.028 23.857 -12.207 1.00 55.49 C ATOM 4129 ND1 HIS A 249 26.307 23.573 -10.880 1.00 54.60 N ATOM 4130 CD2 HIS A 249 27.232 23.752 -12.865 1.00 59.89 C ATOM 4131 CE1 HIS A 249 27.610 23.294 -10.799 1.00 57.38 C ATOM 4132 NE2 HIS A 249 28.237 23.385 -11.965 1.00 62.10 N ATOM 4133 H HIS A 249 22.293 24.423 -13.505 1.00 56.95 H ATOM 4134 HA HIS A 249 24.271 22.598 -14.079 1.00 56.40 H ATOM 4135 HB3 HIS A 249 24.123 24.732 -11.912 1.00 56.04 H ATOM 4136 HB2 HIS A 249 24.745 24.902 -13.526 1.00 56.04 H ATOM 4137 HD1 HIS A 249 25.643 23.557 -10.110 1.00 54.60 H ATOM 4138 HD2 HIS A 249 27.445 23.888 -13.914 1.00 59.89 H ATOM 4139 HE1 HIS A 249 28.105 23.023 -9.877 1.00 57.38 H ATOM 4140 N ASP A 250 23.179 22.021 -10.976 1.00 54.49 N ATOM 4141 CA ASP A 250 23.240 21.037 -9.884 1.00 55.10 C ATOM 4142 C ASP A 250 22.517 19.715 -10.211 1.00 52.74 C ATOM 4143 O ASP A 250 22.892 18.680 -9.658 1.00 53.90 O ATOM 4144 CB ASP A 250 22.817 21.570 -8.491 1.00 57.58 C ATOM 4145 CG ASP A 250 23.663 22.714 -7.892 1.00 61.50 C ATOM 4146 OD1 ASP A 250 24.253 23.513 -8.653 1.00 65.61 O ATOM 4147 OD2 ASP A 250 23.614 22.844 -6.650 1.00 68.93 O1- ATOM 4148 H ASP A 250 22.711 22.893 -10.772 1.00 54.49 H ATOM 4149 HA ASP A 250 24.295 20.784 -9.779 1.00 55.10 H ATOM 4150 HB3 ASP A 250 22.796 20.747 -7.773 1.00 57.58 H ATOM 4151 HB2 ASP A 250 21.795 21.941 -8.561 1.00 57.58 H ATOM 4152 N GLN A 251 21.535 19.753 -11.130 1.00 50.89 N ATOM 4153 CA GLN A 251 20.871 18.563 -11.660 1.00 49.76 C ATOM 4154 C GLN A 251 21.788 17.764 -12.609 1.00 49.30 C ATOM 4155 O GLN A 251 21.787 16.536 -12.536 1.00 49.13 O ATOM 4156 CB GLN A 251 19.546 18.970 -12.343 1.00 50.04 C ATOM 4157 CG GLN A 251 18.656 17.784 -12.768 1.00 48.79 C ATOM 4158 CD GLN A 251 18.199 16.939 -11.581 1.00 49.99 C ATOM 4159 OE1 GLN A 251 17.557 17.447 -10.667 1.00 46.75 O ATOM 4160 NE2 GLN A 251 18.517 15.646 -11.594 1.00 45.81 N ATOM 4161 H GLN A 251 21.268 20.638 -11.537 1.00 50.89 H ATOM 4162 HA GLN A 251 20.642 17.922 -10.806 1.00 49.76 H ATOM 4163 HB3 GLN A 251 19.758 19.584 -13.218 1.00 50.04 H ATOM 4164 HB2 GLN A 251 18.974 19.610 -11.669 1.00 50.04 H ATOM 4165 HG3 GLN A 251 19.178 17.149 -13.482 1.00 48.79 H ATOM 4166 HG2 GLN A 251 17.771 18.156 -13.283 1.00 48.79 H ATOM 4167 HE22 GLN A 251 18.241 15.054 -10.822 1.00 45.81 H ATOM 4168 HE21 GLN A 251 19.041 15.254 -12.363 1.00 45.81 H ATOM 4169 N LEU A 252 22.572 18.470 -13.446 1.00 48.66 N ATOM 4170 CA LEU A 252 23.610 17.892 -14.308 1.00 48.52 C ATOM 4171 C LEU A 252 24.767 17.288 -13.496 1.00 47.49 C ATOM 4172 O LEU A 252 25.191 16.183 -13.823 1.00 47.64 O ATOM 4173 CB LEU A 252 24.133 18.953 -15.303 1.00 47.73 C ATOM 4174 CG LEU A 252 23.146 19.284 -16.441 1.00 48.27 C ATOM 4175 CD1 LEU A 252 23.535 20.600 -17.147 1.00 46.23 C ATOM 4176 CD2 LEU A 252 22.997 18.106 -17.430 1.00 44.68 C ATOM 4177 H LEU A 252 22.510 19.479 -13.449 1.00 48.66 H ATOM 4178 HA LEU A 252 23.157 17.076 -14.873 1.00 48.52 H ATOM 4179 HB3 LEU A 252 25.075 18.628 -15.746 1.00 47.73 H ATOM 4180 HB2 LEU A 252 24.374 19.862 -14.754 1.00 47.73 H ATOM 4181 HG LEU A 252 22.169 19.456 -15.990 1.00 48.27 H ATOM 4182 HD11 LEU A 252 22.704 21.306 -17.136 1.00 46.23 H ATOM 4183 HD12 LEU A 252 24.378 21.096 -16.664 1.00 46.23 H ATOM 4184 HD13 LEU A 252 23.819 20.449 -18.186 1.00 46.23 H ATOM 4185 HD21 LEU A 252 22.983 18.428 -18.472 1.00 44.68 H ATOM 4186 HD22 LEU A 252 23.806 17.382 -17.328 1.00 44.68 H ATOM 4187 HD23 LEU A 252 22.066 17.570 -17.252 1.00 44.68 H ATOM 4188 N ASP A 253 25.205 17.986 -12.429 1.00 48.94 N ATOM 4189 CA ASP A 253 26.183 17.529 -11.434 1.00 48.67 C ATOM 4190 C ASP A 253 25.795 16.167 -10.830 1.00 48.74 C ATOM 4191 O ASP A 253 26.611 15.247 -10.860 1.00 48.77 O ATOM 4192 CB ASP A 253 26.420 18.606 -10.341 1.00 49.82 C ATOM 4193 CG ASP A 253 27.276 18.185 -9.132 1.00 51.19 C ATOM 4194 OD1 ASP A 253 28.464 17.858 -9.345 1.00 47.92 O ATOM 4195 OD2 ASP A 253 26.711 18.132 -8.017 1.00 59.52 O1- ATOM 4196 H ASP A 253 24.806 18.900 -12.255 1.00 48.94 H ATOM 4197 HA ASP A 253 27.123 17.385 -11.970 1.00 48.67 H ATOM 4198 HB3 ASP A 253 25.455 18.951 -9.980 1.00 49.82 H ATOM 4199 HB2 ASP A 253 26.873 19.490 -10.790 1.00 49.82 H ATOM 4200 N ARG A 254 24.546 16.065 -10.344 1.00 49.84 N ATOM 4201 CA ARG A 254 23.966 14.849 -9.778 1.00 50.40 C ATOM 4202 C ARG A 254 23.890 13.677 -10.776 1.00 48.77 C ATOM 4203 O ARG A 254 24.154 12.544 -10.375 1.00 49.71 O ATOM 4204 CB ARG A 254 22.590 15.179 -9.159 1.00 50.67 C ATOM 4205 CG ARG A 254 21.816 13.964 -8.615 1.00 53.88 C ATOM 4206 CD ARG A 254 22.504 13.249 -7.434 1.00 53.19 C ATOM 4207 NE ARG A 254 21.847 11.975 -7.091 1.00 56.32 N ATOM 4208 CZ ARG A 254 22.124 11.170 -6.047 1.00 59.10 C ATOM 4209 NH1 ARG A 254 23.088 11.458 -5.158 1.00 63.74 N ATOM 4210 NH2 ARG A 254 21.417 10.045 -5.891 1.00 59.15 N1+ ATOM 4211 H ARG A 254 23.948 16.882 -10.352 1.00 49.84 H ATOM 4212 HA ARG A 254 24.634 14.540 -8.973 1.00 50.40 H ATOM 4213 HB3 ARG A 254 21.965 15.660 -9.913 1.00 50.67 H ATOM 4214 HB2 ARG A 254 22.715 15.918 -8.366 1.00 50.67 H ATOM 4215 HG3 ARG A 254 21.547 13.270 -9.410 1.00 53.88 H ATOM 4216 HG2 ARG A 254 20.870 14.373 -8.264 1.00 53.88 H ATOM 4217 HD3 ARG A 254 22.369 13.875 -6.552 1.00 53.19 H ATOM 4218 HD2 ARG A 254 23.578 13.133 -7.569 1.00 53.19 H ATOM 4219 HE ARG A 254 21.128 11.670 -7.733 1.00 56.32 H ATOM 4220 HH12 ARG A 254 23.276 10.840 -4.383 1.00 63.74 H ATOM 4221 HH11 ARG A 254 23.629 12.304 -5.262 1.00 63.74 H ATOM 4222 HH22 ARG A 254 21.583 9.430 -5.108 1.00 59.15 H ATOM 4223 HH21 ARG A 254 20.727 9.777 -6.582 1.00 59.15 H ATOM 4224 N ILE A 255 23.562 13.967 -12.048 1.00 47.57 N ATOM 4225 CA ILE A 255 23.559 12.983 -13.132 1.00 47.72 C ATOM 4226 C ILE A 255 24.969 12.435 -13.433 1.00 47.63 C ATOM 4227 O ILE A 255 25.096 11.231 -13.637 1.00 46.85 O ATOM 4228 CB ILE A 255 22.873 13.528 -14.425 1.00 47.44 C ATOM 4229 CG1 ILE A 255 21.348 13.676 -14.205 1.00 48.60 C ATOM 4230 CG2 ILE A 255 23.130 12.708 -15.711 1.00 47.13 C ATOM 4231 CD1 ILE A 255 20.658 14.606 -15.212 1.00 43.46 C ATOM 4232 H ILE A 255 23.347 14.921 -12.305 1.00 47.57 H ATOM 4233 HA ILE A 255 22.972 12.132 -12.788 1.00 47.72 H ATOM 4234 HB ILE A 255 23.273 14.527 -14.602 1.00 47.44 H ATOM 4235 HG13 ILE A 255 21.140 14.047 -13.202 1.00 48.60 H ATOM 4236 HG12 ILE A 255 20.879 12.692 -14.250 1.00 48.60 H ATOM 4237 HG21 ILE A 255 22.582 13.117 -16.560 1.00 47.13 H ATOM 4238 HG22 ILE A 255 24.181 12.708 -15.997 1.00 47.13 H ATOM 4239 HG23 ILE A 255 22.814 11.671 -15.588 1.00 47.13 H ATOM 4240 HD11 ILE A 255 19.752 15.033 -14.781 1.00 43.46 H ATOM 4241 HD12 ILE A 255 21.302 15.435 -15.506 1.00 43.46 H ATOM 4242 HD13 ILE A 255 20.367 14.069 -16.116 1.00 43.46 H ATOM 4243 N PHE A 256 26.000 13.297 -13.397 1.00 49.59 N ATOM 4244 CA PHE A 256 27.397 12.906 -13.605 1.00 49.58 C ATOM 4245 C PHE A 256 28.016 12.184 -12.391 1.00 50.62 C ATOM 4246 O PHE A 256 28.909 11.365 -12.593 1.00 51.58 O ATOM 4247 CB PHE A 256 28.239 14.136 -13.991 1.00 50.12 C ATOM 4248 CG PHE A 256 27.768 14.933 -15.197 1.00 49.75 C ATOM 4249 CD1 PHE A 256 27.306 14.296 -16.371 1.00 49.09 C ATOM 4250 CD2 PHE A 256 27.916 16.336 -15.195 1.00 45.31 C ATOM 4251 CE1 PHE A 256 26.920 15.058 -17.466 1.00 49.82 C ATOM 4252 CE2 PHE A 256 27.516 17.078 -16.296 1.00 49.11 C ATOM 4253 CZ PHE A 256 27.014 16.443 -17.424 1.00 51.09 C ATOM 4254 H PHE A 256 25.828 14.281 -13.233 1.00 49.59 H ATOM 4255 HA PHE A 256 27.429 12.197 -14.433 1.00 49.58 H ATOM 4256 HB3 PHE A 256 29.269 13.834 -14.183 1.00 50.12 H ATOM 4257 HB2 PHE A 256 28.270 14.815 -13.138 1.00 50.12 H ATOM 4258 HD1 PHE A 256 27.232 13.221 -16.426 1.00 49.09 H ATOM 4259 HD2 PHE A 256 28.311 16.842 -14.326 1.00 45.31 H ATOM 4260 HE1 PHE A 256 26.548 14.572 -18.356 1.00 49.82 H ATOM 4261 HE2 PHE A 256 27.600 18.153 -16.266 1.00 49.11 H ATOM 4262 HZ PHE A 256 26.707 17.025 -18.279 1.00 51.09 H ATOM 4263 N ASN A 257 27.528 12.457 -11.166 1.00 50.98 N ATOM 4264 CA ASN A 257 27.908 11.734 -9.942 1.00 54.02 C ATOM 4265 C ASN A 257 27.367 10.292 -9.907 1.00 53.02 C ATOM 4266 O ASN A 257 27.930 9.472 -9.181 1.00 53.25 O ATOM 4267 CB ASN A 257 27.425 12.514 -8.694 1.00 56.17 C ATOM 4268 CG ASN A 257 28.286 13.731 -8.339 1.00 61.96 C ATOM 4269 OD1 ASN A 257 29.512 13.657 -8.354 1.00 70.85 O ATOM 4270 ND2 ASN A 257 27.649 14.845 -7.977 1.00 68.35 N ATOM 4271 H ASN A 257 26.826 13.178 -11.061 1.00 50.98 H ATOM 4272 HA ASN A 257 28.998 11.707 -9.950 1.00 54.02 H ATOM 4273 HB3 ASN A 257 27.477 11.868 -7.816 1.00 56.17 H ATOM 4274 HB2 ASN A 257 26.376 12.794 -8.797 1.00 56.17 H ATOM 4275 HD22 ASN A 257 28.172 15.684 -7.762 1.00 68.35 H ATOM 4276 HD21 ASN A 257 26.642 14.890 -7.975 1.00 68.35 H ATOM 4277 N VAL A 258 26.306 10.008 -10.679 1.00 54.28 N ATOM 4278 CA VAL A 258 25.640 8.709 -10.725 1.00 53.18 C ATOM 4279 C VAL A 258 26.000 7.914 -11.995 1.00 53.88 C ATOM 4280 O VAL A 258 26.175 6.706 -11.882 1.00 51.09 O ATOM 4281 CB VAL A 258 24.100 8.894 -10.635 1.00 53.78 C ATOM 4282 CG1 VAL A 258 23.258 7.653 -10.998 1.00 52.05 C ATOM 4283 CG2 VAL A 258 23.694 9.392 -9.236 1.00 49.71 C ATOM 4284 H VAL A 258 25.893 10.741 -11.239 1.00 54.28 H ATOM 4285 HA VAL A 258 25.947 8.102 -9.871 1.00 53.18 H ATOM 4286 HB VAL A 258 23.828 9.688 -11.331 1.00 53.78 H ATOM 4287 HG11 VAL A 258 22.207 7.830 -10.783 1.00 52.05 H ATOM 4288 HG12 VAL A 258 23.319 7.404 -12.058 1.00 52.05 H ATOM 4289 HG13 VAL A 258 23.569 6.778 -10.428 1.00 52.05 H ATOM 4290 HG21 VAL A 258 22.634 9.635 -9.203 1.00 49.71 H ATOM 4291 HG22 VAL A 258 23.888 8.637 -8.475 1.00 49.71 H ATOM 4292 HG23 VAL A 258 24.235 10.292 -8.949 1.00 49.71 H ATOM 4293 N MET A 259 26.097 8.579 -13.160 1.00 55.02 N ATOM 4294 CA MET A 259 26.346 7.944 -14.461 1.00 55.07 C ATOM 4295 C MET A 259 27.811 8.036 -14.919 1.00 55.84 C ATOM 4296 O MET A 259 28.208 7.246 -15.775 1.00 56.48 O ATOM 4297 CB MET A 259 25.461 8.607 -15.544 1.00 55.08 C ATOM 4298 CG MET A 259 23.945 8.545 -15.295 1.00 54.61 C ATOM 4299 SD MET A 259 23.214 6.893 -15.121 1.00 56.14 S ATOM 4300 CE MET A 259 23.738 6.139 -16.681 1.00 46.39 C ATOM 4301 H MET A 259 25.915 9.574 -13.184 1.00 55.02 H ATOM 4302 HA MET A 259 26.092 6.883 -14.413 1.00 55.07 H ATOM 4303 HB3 MET A 259 25.672 8.164 -16.518 1.00 55.08 H ATOM 4304 HB2 MET A 259 25.747 9.655 -15.653 1.00 55.08 H ATOM 4305 HG3 MET A 259 23.429 9.048 -16.114 1.00 54.61 H ATOM 4306 HG2 MET A 259 23.699 9.110 -14.400 1.00 54.61 H ATOM 4307 HE1 MET A 259 23.218 5.194 -16.834 1.00 46.39 H ATOM 4308 HE2 MET A 259 23.515 6.803 -17.516 1.00 46.39 H ATOM 4309 HE3 MET A 259 24.810 5.941 -16.670 1.00 46.39 H ATOM 4310 N GLY A 260 28.569 9.013 -14.395 1.00 55.65 N ATOM 4311 CA GLY A 260 29.857 9.432 -14.948 1.00 53.37 C ATOM 4312 C GLY A 260 29.636 10.540 -15.991 1.00 52.10 C ATOM 4313 O GLY A 260 28.523 10.746 -16.481 1.00 52.15 O ATOM 4314 H GLY A 260 28.176 9.610 -13.681 1.00 55.65 H ATOM 4315 HA3 GLY A 260 30.391 8.598 -15.406 1.00 53.37 H ATOM 4316 HA2 GLY A 260 30.488 9.810 -14.146 1.00 53.37 H ATOM 4317 N PHE A 261 30.721 11.251 -16.340 1.00 52.55 N ATOM 4318 CA PHE A 261 30.716 12.292 -17.371 1.00 52.27 C ATOM 4319 C PHE A 261 30.874 11.604 -18.748 1.00 52.09 C ATOM 4320 O PHE A 261 31.824 10.834 -18.907 1.00 51.92 O ATOM 4321 CB PHE A 261 31.887 13.256 -17.085 1.00 50.98 C ATOM 4322 CG PHE A 261 31.762 14.599 -17.781 1.00 50.25 C ATOM 4323 CD1 PHE A 261 30.958 15.607 -17.208 1.00 52.65 C ATOM 4324 CD2 PHE A 261 32.286 14.797 -19.075 1.00 51.21 C ATOM 4325 CE1 PHE A 261 30.739 16.795 -17.890 1.00 50.25 C ATOM 4326 CE2 PHE A 261 32.060 15.995 -19.741 1.00 51.07 C ATOM 4327 CZ PHE A 261 31.293 16.991 -19.147 1.00 50.33 C ATOM 4328 H PHE A 261 31.615 11.036 -15.924 1.00 52.55 H ATOM 4329 HA PHE A 261 29.786 12.850 -17.271 1.00 52.27 H ATOM 4330 HB3 PHE A 261 32.846 12.803 -17.339 1.00 50.98 H ATOM 4331 HB2 PHE A 261 31.927 13.456 -16.017 1.00 50.98 H ATOM 4332 HD1 PHE A 261 30.505 15.455 -16.239 1.00 52.65 H ATOM 4333 HD2 PHE A 261 32.859 14.019 -19.554 1.00 51.21 H ATOM 4334 HE1 PHE A 261 30.125 17.564 -17.447 1.00 50.25 H ATOM 4335 HE2 PHE A 261 32.470 16.148 -20.728 1.00 51.07 H ATOM 4336 HZ PHE A 261 31.111 17.919 -19.667 1.00 50.33 H ATOM 4337 N PRO A 262 29.938 11.843 -19.698 1.00 50.93 N ATOM 4338 CA PRO A 262 29.904 11.117 -20.983 1.00 52.14 C ATOM 4339 C PRO A 262 31.094 11.457 -21.898 1.00 53.51 C ATOM 4340 O PRO A 262 31.434 12.632 -22.049 1.00 53.76 O ATOM 4341 CB PRO A 262 28.559 11.542 -21.600 1.00 50.24 C ATOM 4342 CG PRO A 262 28.285 12.921 -21.025 1.00 51.25 C ATOM 4343 CD PRO A 262 28.855 12.824 -19.614 1.00 51.81 C ATOM 4344 HA PRO A 262 29.892 10.041 -20.800 1.00 52.14 H ATOM 4345 HB3 PRO A 262 27.781 10.850 -21.275 1.00 50.24 H ATOM 4346 HB2 PRO A 262 28.556 11.539 -22.692 1.00 50.24 H ATOM 4347 HG3 PRO A 262 27.231 13.202 -21.048 1.00 51.25 H ATOM 4348 HG2 PRO A 262 28.842 13.668 -21.592 1.00 51.25 H ATOM 4349 HD2 PRO A 262 29.193 13.802 -19.266 1.00 51.81 H ATOM 4350 HD3 PRO A 262 28.104 12.450 -18.918 1.00 51.81 H ATOM 4351 N ALA A 263 31.707 10.414 -22.484 1.00 54.21 N ATOM 4352 CA ALA A 263 32.752 10.538 -23.503 1.00 54.41 C ATOM 4353 C ALA A 263 32.196 11.087 -24.825 1.00 54.10 C ATOM 4354 O ALA A 263 30.993 10.992 -25.076 1.00 53.77 O ATOM 4355 CB ALA A 263 33.425 9.174 -23.716 1.00 54.56 C ATOM 4356 H ALA A 263 31.366 9.475 -22.314 1.00 54.21 H ATOM 4357 HA ALA A 263 33.509 11.231 -23.145 1.00 54.41 H ATOM 4358 HB1 ALA A 263 34.328 9.274 -24.319 1.00 54.56 H ATOM 4359 HB2 ALA A 263 33.717 8.723 -22.767 1.00 54.56 H ATOM 4360 HB3 ALA A 263 32.770 8.473 -24.232 1.00 54.56 H ATOM 4361 N ASP A 264 33.100 11.625 -25.662 1.00 56.50 N ATOM 4362 CA ASP A 264 32.781 12.138 -27.001 1.00 57.94 C ATOM 4363 C ASP A 264 32.206 11.049 -27.925 1.00 57.82 C ATOM 4364 O ASP A 264 31.324 11.359 -28.720 1.00 58.57 O ATOM 4365 CB ASP A 264 33.966 12.847 -27.709 1.00 60.42 C ATOM 4366 CG ASP A 264 34.671 13.995 -26.958 1.00 65.51 C ATOM 4367 OD1 ASP A 264 34.172 14.445 -25.902 1.00 65.68 O ATOM 4368 OD2 ASP A 264 35.692 14.463 -27.509 1.00 73.31 O1- ATOM 4369 H ASP A 264 34.067 11.696 -25.381 1.00 56.50 H ATOM 4370 HA ASP A 264 31.990 12.880 -26.868 1.00 57.94 H ATOM 4371 HB3 ASP A 264 33.619 13.254 -28.660 1.00 60.42 H ATOM 4372 HB2 ASP A 264 34.731 12.105 -27.946 1.00 60.42 H ATOM 4373 N LYS A 265 32.676 9.798 -27.770 1.00 56.77 N ATOM 4374 CA LYS A 265 32.152 8.626 -28.471 1.00 57.09 C ATOM 4375 C LYS A 265 30.758 8.198 -27.972 1.00 56.58 C ATOM 4376 O LYS A 265 29.970 7.732 -28.790 1.00 56.88 O ATOM 4377 CB LYS A 265 33.183 7.480 -28.380 1.00 57.39 C ATOM 4378 CG LYS A 265 32.795 6.211 -29.163 0.00 57.21 C ATOM 4379 CD LYS A 265 33.912 5.159 -29.188 0.00 57.26 C ATOM 4380 CE LYS A 265 33.509 3.906 -29.982 0.00 57.25 C ATOM 4381 NZ LYS A 265 34.584 2.899 -30.000 0.00 57.25 N1+ ATOM 4382 H LYS A 265 33.403 9.626 -27.092 1.00 56.77 H ATOM 4383 HA LYS A 265 32.049 8.894 -29.525 1.00 57.09 H ATOM 4384 HB3 LYS A 265 33.358 7.221 -27.334 1.00 57.39 H ATOM 4385 HB2 LYS A 265 34.136 7.844 -28.766 1.00 57.39 H ATOM 4386 HG3 LYS A 265 32.531 6.485 -30.186 1.00 57.21 H ATOM 4387 HG2 LYS A 265 31.904 5.760 -28.726 1.00 57.21 H ATOM 4388 HD3 LYS A 265 34.167 4.886 -28.163 1.00 57.26 H ATOM 4389 HD2 LYS A 265 34.811 5.601 -29.622 1.00 57.26 H ATOM 4390 HE3 LYS A 265 33.266 4.174 -31.011 1.00 57.25 H ATOM 4391 HE2 LYS A 265 32.616 3.456 -29.548 1.00 57.25 H ATOM 4392 HZ1 LYS A 265 34.798 2.617 -29.054 1.00 57.25 H ATOM 4393 HZ2 LYS A 265 34.282 2.093 -30.530 1.00 57.25 H ATOM 4394 HZ3 LYS A 265 35.409 3.293 -30.429 1.00 57.25 H ATOM 4395 N ASP A 266 30.471 8.368 -26.666 1.00 56.78 N ATOM 4396 CA ASP A 266 29.185 8.022 -26.039 1.00 56.79 C ATOM 4397 C ASP A 266 28.021 8.897 -26.529 1.00 55.81 C ATOM 4398 O ASP A 266 26.917 8.375 -26.683 1.00 54.84 O ATOM 4399 CB ASP A 266 29.207 8.055 -24.486 1.00 56.80 C ATOM 4400 CG ASP A 266 30.281 7.209 -23.781 1.00 62.01 C ATOM 4401 OD1 ASP A 266 30.805 6.253 -24.397 1.00 62.15 O ATOM 4402 OD2 ASP A 266 30.483 7.470 -22.575 1.00 68.07 O1- ATOM 4403 H ASP A 266 31.166 8.770 -26.054 1.00 56.78 H ATOM 4404 HA ASP A 266 28.953 6.998 -26.341 1.00 56.79 H ATOM 4405 HB3 ASP A 266 28.243 7.714 -24.105 1.00 56.80 H ATOM 4406 HB2 ASP A 266 29.327 9.086 -24.149 1.00 56.80 H ATOM 4407 N TRP A 267 28.292 10.190 -26.763 1.00 54.11 N ATOM 4408 CA TRP A 267 27.313 11.179 -27.197 1.00 54.40 C ATOM 4409 C TRP A 267 28.044 12.192 -28.087 1.00 55.06 C ATOM 4410 O TRP A 267 28.550 13.193 -27.585 1.00 52.99 O ATOM 4411 CB TRP A 267 26.634 11.797 -25.948 1.00 53.95 C ATOM 4412 CG TRP A 267 25.477 12.741 -26.141 1.00 52.76 C ATOM 4413 CD1 TRP A 267 24.905 13.101 -27.314 1.00 52.86 C ATOM 4414 CD2 TRP A 267 24.726 13.447 -25.106 1.00 49.92 C ATOM 4415 NE1 TRP A 267 23.873 13.985 -27.080 1.00 51.60 N ATOM 4416 CE2 TRP A 267 23.719 14.242 -25.736 1.00 48.77 C ATOM 4417 CE3 TRP A 267 24.795 13.502 -23.695 1.00 47.30 C ATOM 4418 CZ2 TRP A 267 22.838 15.058 -25.006 1.00 47.55 C ATOM 4419 CZ3 TRP A 267 23.914 14.312 -22.951 1.00 45.53 C ATOM 4420 CH2 TRP A 267 22.938 15.091 -23.604 1.00 46.27 C ATOM 4421 H TRP A 267 29.231 10.534 -26.614 1.00 54.11 H ATOM 4422 HA TRP A 267 26.552 10.686 -27.804 1.00 54.40 H ATOM 4423 HB3 TRP A 267 27.379 12.314 -25.343 1.00 53.95 H ATOM 4424 HB2 TRP A 267 26.261 10.994 -25.310 1.00 53.95 H ATOM 4425 HD1 TRP A 267 25.208 12.744 -28.287 1.00 52.86 H ATOM 4426 HE1 TRP A 267 23.310 14.371 -27.825 1.00 51.60 H ATOM 4427 HE3 TRP A 267 25.540 12.915 -23.178 1.00 47.30 H ATOM 4428 HZ2 TRP A 267 22.099 15.656 -25.518 1.00 47.55 H ATOM 4429 HZ3 TRP A 267 23.993 14.339 -21.875 1.00 45.53 H ATOM 4430 HH2 TRP A 267 22.272 15.715 -23.029 1.00 46.27 H ATOM 4431 N GLU A 268 28.110 11.886 -29.394 1.00 57.53 N ATOM 4432 CA GLU A 268 28.791 12.694 -30.412 1.00 60.21 C ATOM 4433 C GLU A 268 28.090 14.034 -30.699 1.00 60.56 C ATOM 4434 O GLU A 268 28.774 15.042 -30.883 1.00 61.86 O ATOM 4435 CB GLU A 268 28.960 11.863 -31.703 1.00 61.39 C ATOM 4436 CG GLU A 268 29.848 10.608 -31.510 1.00 64.36 C ATOM 4437 CD GLU A 268 30.020 9.702 -32.740 1.00 67.25 C ATOM 4438 OE1 GLU A 268 29.532 10.058 -33.836 1.00 69.28 O ATOM 4439 OE2 GLU A 268 30.655 8.639 -32.555 1.00 69.24 O1- ATOM 4440 H GLU A 268 27.685 11.031 -29.723 1.00 57.53 H ATOM 4441 HA GLU A 268 29.786 12.940 -30.040 1.00 60.21 H ATOM 4442 HB3 GLU A 268 29.387 12.493 -32.485 1.00 61.39 H ATOM 4443 HB2 GLU A 268 27.976 11.559 -32.063 1.00 61.39 H ATOM 4444 HG3 GLU A 268 29.459 9.996 -30.695 1.00 64.36 H ATOM 4445 HG2 GLU A 268 30.845 10.927 -31.207 1.00 64.36 H ATOM 4446 N ASP A 269 26.746 14.024 -30.686 1.00 60.46 N ATOM 4447 CA ASP A 269 25.885 15.190 -30.918 1.00 61.20 C ATOM 4448 C ASP A 269 25.630 16.034 -29.651 1.00 59.71 C ATOM 4449 O ASP A 269 24.765 16.910 -29.691 1.00 59.22 O ATOM 4450 CB ASP A 269 24.559 14.816 -31.638 1.00 62.43 C ATOM 4451 CG ASP A 269 24.694 14.158 -33.026 1.00 64.68 C ATOM 4452 OD1 ASP A 269 25.759 14.301 -33.667 1.00 65.17 O ATOM 4453 OD2 ASP A 269 23.654 13.651 -33.501 1.00 72.35 O1- ATOM 4454 H ASP A 269 26.267 13.150 -30.522 1.00 60.46 H ATOM 4455 HA ASP A 269 26.421 15.871 -31.583 1.00 61.20 H ATOM 4456 HB3 ASP A 269 23.940 15.703 -31.772 1.00 62.43 H ATOM 4457 HB2 ASP A 269 23.993 14.134 -31.001 1.00 62.43 H ATOM 4458 N ILE A 270 26.411 15.824 -28.572 1.00 57.99 N ATOM 4459 CA ILE A 270 26.406 16.681 -27.379 1.00 57.85 C ATOM 4460 C ILE A 270 26.899 18.116 -27.684 1.00 58.50 C ATOM 4461 O ILE A 270 26.470 19.051 -27.013 1.00 57.20 O ATOM 4462 CB ILE A 270 27.266 16.077 -26.227 1.00 57.51 C ATOM 4463 CG1 ILE A 270 26.900 16.681 -24.849 1.00 57.84 C ATOM 4464 CG2 ILE A 270 28.791 16.135 -26.470 1.00 50.59 C ATOM 4465 CD1 ILE A 270 27.464 15.899 -23.654 1.00 57.06 C ATOM 4466 H ILE A 270 27.098 15.084 -28.589 1.00 57.99 H ATOM 4467 HA ILE A 270 25.372 16.742 -27.036 1.00 57.85 H ATOM 4468 HB ILE A 270 27.005 15.021 -26.183 1.00 57.51 H ATOM 4469 HG13 ILE A 270 25.815 16.727 -24.745 1.00 57.84 H ATOM 4470 HG12 ILE A 270 27.248 17.712 -24.787 1.00 57.84 H ATOM 4471 HG21 ILE A 270 29.328 15.516 -25.750 1.00 50.59 H ATOM 4472 HG22 ILE A 270 29.051 15.771 -27.464 1.00 50.59 H ATOM 4473 HG23 ILE A 270 29.182 17.147 -26.382 1.00 50.59 H ATOM 4474 HD11 ILE A 270 26.833 16.026 -22.774 1.00 57.06 H ATOM 4475 HD12 ILE A 270 27.525 14.830 -23.862 1.00 57.06 H ATOM 4476 HD13 ILE A 270 28.465 16.245 -23.394 1.00 57.06 H ATOM 4477 N LYS A 271 27.751 18.256 -28.717 1.00 60.72 N ATOM 4478 CA LYS A 271 28.285 19.516 -29.233 1.00 62.14 C ATOM 4479 C LYS A 271 27.233 20.404 -29.923 1.00 62.68 C ATOM 4480 O LYS A 271 27.409 21.622 -29.942 1.00 64.12 O ATOM 4481 CB LYS A 271 29.458 19.209 -30.187 1.00 63.27 C ATOM 4482 CG LYS A 271 30.657 18.555 -29.478 0.00 62.61 C ATOM 4483 CD LYS A 271 31.837 18.271 -30.419 0.00 62.71 C ATOM 4484 CE LYS A 271 33.025 17.641 -29.673 0.00 62.68 C ATOM 4485 NZ LYS A 271 34.156 17.355 -30.573 0.00 62.67 N1+ ATOM 4486 H LYS A 271 28.044 17.425 -29.212 1.00 60.72 H ATOM 4487 HA LYS A 271 28.673 20.079 -28.388 1.00 62.14 H ATOM 4488 HB3 LYS A 271 29.799 20.136 -30.651 1.00 63.27 H ATOM 4489 HB2 LYS A 271 29.115 18.568 -31.001 1.00 63.27 H ATOM 4490 HG3 LYS A 271 30.347 17.621 -29.008 1.00 62.61 H ATOM 4491 HG2 LYS A 271 30.993 19.206 -28.672 1.00 62.61 H ATOM 4492 HD3 LYS A 271 32.147 19.202 -30.898 1.00 62.71 H ATOM 4493 HD2 LYS A 271 31.503 17.608 -31.219 1.00 62.71 H ATOM 4494 HE3 LYS A 271 32.719 16.708 -29.196 1.00 62.68 H ATOM 4495 HE2 LYS A 271 33.370 18.307 -28.881 1.00 62.68 H ATOM 4496 HZ1 LYS A 271 34.479 18.212 -30.997 1.00 62.67 H ATOM 4497 HZ2 LYS A 271 34.908 16.937 -30.042 1.00 62.67 H ATOM 4498 HZ3 LYS A 271 33.860 16.712 -31.293 1.00 62.67 H ATOM 4499 N LYS A 272 26.166 19.789 -30.463 1.00 63.90 N ATOM 4500 CA LYS A 272 25.062 20.468 -31.148 1.00 63.81 C ATOM 4501 C LYS A 272 24.028 21.084 -30.183 1.00 63.68 C ATOM 4502 O LYS A 272 23.218 21.896 -30.629 1.00 64.55 O ATOM 4503 CB LYS A 272 24.379 19.479 -32.115 1.00 63.95 C ATOM 4504 CG LYS A 272 25.306 18.965 -33.230 1.00 65.86 C ATOM 4505 CD LYS A 272 24.593 17.998 -34.184 1.00 69.22 C ATOM 4506 CE LYS A 272 25.525 17.457 -35.280 0.00 68.38 C ATOM 4507 NZ LYS A 272 24.864 16.424 -36.096 0.00 68.55 N1+ ATOM 4508 H LYS A 272 26.084 18.785 -30.385 1.00 63.90 H ATOM 4509 HA LYS A 272 25.475 21.288 -31.739 1.00 63.81 H ATOM 4510 HB3 LYS A 272 23.521 19.965 -32.582 1.00 63.95 H ATOM 4511 HB2 LYS A 272 23.976 18.633 -31.556 1.00 63.95 H ATOM 4512 HG3 LYS A 272 26.166 18.457 -32.790 1.00 65.86 H ATOM 4513 HG2 LYS A 272 25.703 19.811 -33.793 1.00 65.86 H ATOM 4514 HD3 LYS A 272 23.743 18.507 -34.642 1.00 69.22 H ATOM 4515 HD2 LYS A 272 24.177 17.172 -33.607 1.00 69.22 H ATOM 4516 HE3 LYS A 272 26.417 17.016 -34.833 1.00 68.38 H ATOM 4517 HE2 LYS A 272 25.857 18.268 -35.929 1.00 68.38 H ATOM 4518 HZ1 LYS A 272 24.622 15.642 -35.499 1.00 68.55 H ATOM 4519 HZ2 LYS A 272 24.028 16.798 -36.520 1.00 68.55 H ATOM 4520 HZ3 LYS A 272 25.497 16.101 -36.814 1.00 68.55 H ATOM 4521 N MET A 273 24.071 20.700 -28.895 1.00 62.06 N ATOM 4522 CA MET A 273 23.207 21.223 -27.836 1.00 61.45 C ATOM 4523 C MET A 273 23.559 22.696 -27.518 1.00 59.91 C ATOM 4524 O MET A 273 24.746 22.970 -27.328 1.00 58.79 O ATOM 4525 CB MET A 273 23.389 20.354 -26.576 1.00 61.31 C ATOM 4526 CG MET A 273 23.077 18.856 -26.757 1.00 62.46 C ATOM 4527 SD MET A 273 21.451 18.432 -27.446 1.00 61.02 S ATOM 4528 CE MET A 273 20.368 19.376 -26.344 1.00 56.92 C ATOM 4529 H MET A 273 24.775 20.037 -28.603 1.00 62.06 H ATOM 4530 HA MET A 273 22.184 21.107 -28.180 1.00 61.45 H ATOM 4531 HB3 MET A 273 22.751 20.747 -25.789 1.00 61.31 H ATOM 4532 HB2 MET A 273 24.405 20.457 -26.194 1.00 61.31 H ATOM 4533 HG3 MET A 273 23.176 18.351 -25.795 1.00 62.46 H ATOM 4534 HG2 MET A 273 23.821 18.404 -27.410 1.00 62.46 H ATOM 4535 HE1 MET A 273 19.329 19.117 -26.535 1.00 56.92 H ATOM 4536 HE2 MET A 273 20.604 19.151 -25.306 1.00 56.92 H ATOM 4537 HE3 MET A 273 20.482 20.447 -26.502 1.00 56.92 H ATOM 4538 N PRO A 274 22.559 23.615 -27.473 1.00 59.61 N ATOM 4539 CA PRO A 274 22.781 25.054 -27.190 1.00 58.80 C ATOM 4540 C PRO A 274 23.630 25.430 -25.959 1.00 58.18 C ATOM 4541 O PRO A 274 24.353 26.423 -26.028 1.00 57.67 O ATOM 4542 CB PRO A 274 21.361 25.628 -27.068 1.00 58.27 C ATOM 4543 CG PRO A 274 20.530 24.751 -27.982 1.00 60.99 C ATOM 4544 CD PRO A 274 21.145 23.371 -27.784 1.00 59.86 C ATOM 4545 HA PRO A 274 23.258 25.472 -28.078 1.00 58.80 H ATOM 4546 HB3 PRO A 274 21.307 26.682 -27.344 1.00 58.27 H ATOM 4547 HB2 PRO A 274 20.992 25.534 -26.045 1.00 58.27 H ATOM 4548 HG3 PRO A 274 20.678 25.067 -29.015 1.00 60.99 H ATOM 4549 HG2 PRO A 274 19.462 24.789 -27.770 1.00 60.99 H ATOM 4550 HD2 PRO A 274 20.681 22.858 -26.941 1.00 59.86 H ATOM 4551 HD3 PRO A 274 20.990 22.779 -28.685 1.00 59.86 H ATOM 4552 N GLU A 275 23.540 24.638 -24.878 1.00 58.19 N ATOM 4553 CA GLU A 275 24.239 24.878 -23.612 1.00 58.24 C ATOM 4554 C GLU A 275 25.531 24.048 -23.470 1.00 57.53 C ATOM 4555 O GLU A 275 26.015 23.904 -22.348 1.00 58.18 O ATOM 4556 CB GLU A 275 23.274 24.601 -22.439 1.00 58.72 C ATOM 4557 CG GLU A 275 21.939 25.386 -22.465 1.00 61.62 C ATOM 4558 CD GLU A 275 22.035 26.893 -22.165 1.00 63.21 C ATOM 4559 OE1 GLU A 275 23.072 27.346 -21.629 1.00 62.90 O ATOM 4560 OE2 GLU A 275 21.029 27.577 -22.455 1.00 65.48 O1- ATOM 4561 H GLU A 275 22.917 23.842 -24.893 1.00 58.19 H ATOM 4562 HA GLU A 275 24.545 25.924 -23.553 1.00 58.24 H ATOM 4563 HB3 GLU A 275 23.776 24.782 -21.488 1.00 58.72 H ATOM 4564 HB2 GLU A 275 23.055 23.539 -22.438 1.00 58.72 H ATOM 4565 HG3 GLU A 275 21.270 24.948 -21.723 1.00 61.62 H ATOM 4566 HG2 GLU A 275 21.435 25.241 -23.421 1.00 61.62 H ATOM 4567 N HIS A 276 26.089 23.520 -24.578 1.00 57.14 N ATOM 4568 CA HIS A 276 27.347 22.764 -24.566 1.00 55.95 C ATOM 4569 C HIS A 276 28.560 23.604 -24.125 1.00 55.41 C ATOM 4570 O HIS A 276 29.385 23.095 -23.371 1.00 53.68 O ATOM 4571 CB HIS A 276 27.611 22.105 -25.932 1.00 54.51 C ATOM 4572 CG HIS A 276 28.864 21.260 -25.958 1.00 56.12 C ATOM 4573 ND1 HIS A 276 28.970 20.052 -25.289 1.00 51.38 N ATOM 4574 CD2 HIS A 276 30.097 21.471 -26.536 1.00 54.28 C ATOM 4575 CE1 HIS A 276 30.211 19.601 -25.483 1.00 56.68 C ATOM 4576 NE2 HIS A 276 30.953 20.411 -26.228 1.00 54.20 N ATOM 4577 H HIS A 276 25.644 23.650 -25.477 1.00 57.14 H ATOM 4578 HA HIS A 276 27.225 21.961 -23.836 1.00 55.95 H ATOM 4579 HB3 HIS A 276 27.687 22.864 -26.713 1.00 54.51 H ATOM 4580 HB2 HIS A 276 26.765 21.476 -26.205 1.00 54.51 H ATOM 4581 HD1 HIS A 276 28.241 19.596 -24.759 1.00 51.38 H ATOM 4582 HD2 HIS A 276 30.435 22.304 -27.134 1.00 54.28 H ATOM 4583 HE1 HIS A 276 30.579 18.674 -25.069 1.00 56.68 H ATOM 4584 N SER A 277 28.640 24.870 -24.566 1.00 55.37 N ATOM 4585 CA SER A 277 29.697 25.801 -24.158 1.00 56.55 C ATOM 4586 C SER A 277 29.645 26.150 -22.658 1.00 55.77 C ATOM 4587 O SER A 277 30.701 26.310 -22.046 1.00 54.58 O ATOM 4588 CB SER A 277 29.634 27.070 -25.028 1.00 57.06 C ATOM 4589 OG SER A 277 30.181 26.809 -26.304 1.00 60.09 O ATOM 4590 H SER A 277 27.937 25.232 -25.193 1.00 55.37 H ATOM 4591 HA SER A 277 30.661 25.316 -24.328 1.00 56.55 H ATOM 4592 HB3 SER A 277 30.217 27.876 -24.582 1.00 57.06 H ATOM 4593 HB2 SER A 277 28.610 27.435 -25.127 1.00 57.06 H ATOM 4594 HG SER A 277 30.132 27.612 -26.829 1.00 60.09 H ATOM 4595 N THR A 278 28.426 26.200 -22.092 1.00 55.93 N ATOM 4596 CA THR A 278 28.168 26.373 -20.662 1.00 56.22 C ATOM 4597 C THR A 278 28.552 25.124 -19.838 1.00 56.61 C ATOM 4598 O THR A 278 29.072 25.267 -18.733 1.00 56.70 O ATOM 4599 CB THR A 278 26.671 26.688 -20.385 1.00 57.58 C ATOM 4600 OG1 THR A 278 26.199 27.653 -21.307 1.00 60.32 O ATOM 4601 CG2 THR A 278 26.402 27.237 -18.974 1.00 57.11 C ATOM 4602 H THR A 278 27.605 26.070 -22.665 1.00 55.93 H ATOM 4603 HA THR A 278 28.772 27.212 -20.309 1.00 56.22 H ATOM 4604 HB THR A 278 26.066 25.792 -20.524 1.00 57.58 H ATOM 4605 HG1 THR A 278 25.242 27.729 -21.212 1.00 60.32 H ATOM 4606 HG21 THR A 278 25.338 27.425 -18.824 1.00 57.11 H ATOM 4607 HG22 THR A 278 26.722 26.543 -18.200 1.00 57.11 H ATOM 4608 HG23 THR A 278 26.932 28.175 -18.807 1.00 57.11 H ATOM 4609 N LEU A 279 28.337 23.927 -20.418 1.00 54.99 N ATOM 4610 CA LEU A 279 28.715 22.629 -19.857 1.00 53.47 C ATOM 4611 C LEU A 279 30.243 22.470 -19.750 1.00 53.29 C ATOM 4612 O LEU A 279 30.724 22.089 -18.688 1.00 52.31 O ATOM 4613 CB LEU A 279 28.072 21.501 -20.702 1.00 53.62 C ATOM 4614 CG LEU A 279 28.162 20.071 -20.117 1.00 54.14 C ATOM 4615 CD1 LEU A 279 27.241 19.897 -18.893 1.00 54.31 C ATOM 4616 CD2 LEU A 279 27.906 18.997 -21.199 1.00 51.83 C ATOM 4617 H LEU A 279 27.889 23.899 -21.324 1.00 54.99 H ATOM 4618 HA LEU A 279 28.299 22.593 -18.849 1.00 53.47 H ATOM 4619 HB3 LEU A 279 28.546 21.492 -21.681 1.00 53.62 H ATOM 4620 HB2 LEU A 279 27.026 21.741 -20.889 1.00 53.62 H ATOM 4621 HG LEU A 279 29.184 19.911 -19.772 1.00 54.14 H ATOM 4622 HD11 LEU A 279 27.799 19.469 -18.065 1.00 54.31 H ATOM 4623 HD12 LEU A 279 26.820 20.843 -18.549 1.00 54.31 H ATOM 4624 HD13 LEU A 279 26.395 19.238 -19.087 1.00 54.31 H ATOM 4625 HD21 LEU A 279 28.818 18.439 -21.411 1.00 51.83 H ATOM 4626 HD22 LEU A 279 27.156 18.265 -20.900 1.00 51.83 H ATOM 4627 HD23 LEU A 279 27.569 19.432 -22.140 1.00 51.83 H ATOM 4628 N MET A 280 30.978 22.798 -20.828 1.00 53.62 N ATOM 4629 CA MET A 280 32.446 22.765 -20.866 1.00 53.24 C ATOM 4630 C MET A 280 33.112 23.817 -19.959 1.00 54.37 C ATOM 4631 O MET A 280 34.216 23.567 -19.477 1.00 55.47 O ATOM 4632 CB MET A 280 32.946 22.919 -22.319 1.00 52.70 C ATOM 4633 CG MET A 280 32.529 21.804 -23.296 1.00 52.61 C ATOM 4634 SD MET A 280 33.112 20.127 -22.920 1.00 61.27 S ATOM 4635 CE MET A 280 31.669 19.453 -22.054 1.00 48.28 C ATOM 4636 H MET A 280 30.513 23.099 -21.675 1.00 53.62 H ATOM 4637 HA MET A 280 32.771 21.794 -20.490 1.00 53.24 H ATOM 4638 HB3 MET A 280 34.036 22.975 -22.322 1.00 52.70 H ATOM 4639 HB2 MET A 280 32.603 23.875 -22.717 1.00 52.70 H ATOM 4640 HG3 MET A 280 32.912 22.056 -24.285 1.00 52.61 H ATOM 4641 HG2 MET A 280 31.449 21.767 -23.407 1.00 52.61 H ATOM 4642 HE1 MET A 280 31.799 18.382 -21.903 1.00 48.28 H ATOM 4643 HE2 MET A 280 31.537 19.924 -21.081 1.00 48.28 H ATOM 4644 HE3 MET A 280 30.761 19.607 -22.637 1.00 48.28 H ATOM 4645 N LYS A 281 32.431 24.953 -19.731 1.00 56.25 N ATOM 4646 CA LYS A 281 32.872 26.022 -18.836 1.00 58.10 C ATOM 4647 C LYS A 281 32.796 25.617 -17.352 1.00 58.60 C ATOM 4648 O LYS A 281 33.743 25.889 -16.613 1.00 59.66 O ATOM 4649 CB LYS A 281 32.051 27.295 -19.143 1.00 59.46 C ATOM 4650 CG LYS A 281 32.378 28.522 -18.272 1.00 62.55 C ATOM 4651 CD LYS A 281 31.522 29.740 -18.645 1.00 64.71 C ATOM 4652 CE LYS A 281 31.827 30.960 -17.762 0.00 64.38 C ATOM 4653 NZ LYS A 281 30.984 32.115 -18.117 0.00 64.50 N1+ ATOM 4654 H LYS A 281 31.536 25.091 -20.178 1.00 56.25 H ATOM 4655 HA LYS A 281 33.917 26.239 -19.066 1.00 58.10 H ATOM 4656 HB3 LYS A 281 30.989 27.072 -19.040 1.00 59.46 H ATOM 4657 HB2 LYS A 281 32.202 27.564 -20.189 1.00 59.46 H ATOM 4658 HG3 LYS A 281 33.436 28.768 -18.373 1.00 62.55 H ATOM 4659 HG2 LYS A 281 32.213 28.294 -17.218 1.00 62.55 H ATOM 4660 HD3 LYS A 281 30.467 29.472 -18.555 1.00 64.71 H ATOM 4661 HD2 LYS A 281 31.688 29.987 -19.694 1.00 64.71 H ATOM 4662 HE3 LYS A 281 32.875 31.246 -17.862 1.00 64.38 H ATOM 4663 HE2 LYS A 281 31.658 30.716 -16.712 1.00 64.38 H ATOM 4664 HZ1 LYS A 281 30.011 31.870 -17.995 1.00 64.50 H ATOM 4665 HZ2 LYS A 281 31.212 32.896 -17.518 1.00 64.50 H ATOM 4666 HZ3 LYS A 281 31.148 32.370 -19.080 1.00 64.50 H ATOM 4667 N ASP A 282 31.672 25.000 -16.951 1.00 58.86 N ATOM 4668 CA ASP A 282 31.355 24.700 -15.550 1.00 58.90 C ATOM 4669 C ASP A 282 31.842 23.314 -15.088 1.00 59.21 C ATOM 4670 O ASP A 282 32.087 23.162 -13.891 1.00 58.76 O ATOM 4671 CB ASP A 282 29.845 24.850 -15.226 1.00 59.93 C ATOM 4672 CG ASP A 282 29.181 26.205 -15.547 1.00 60.39 C ATOM 4673 OD1 ASP A 282 29.896 27.219 -15.714 1.00 59.12 O ATOM 4674 OD2 ASP A 282 27.931 26.230 -15.494 1.00 64.74 O1- ATOM 4675 H ASP A 282 30.934 24.824 -17.620 1.00 58.86 H ATOM 4676 HA ASP A 282 31.880 25.423 -14.921 1.00 58.90 H ATOM 4677 HB3 ASP A 282 29.696 24.673 -14.161 1.00 59.93 H ATOM 4678 HB2 ASP A 282 29.289 24.076 -15.759 1.00 59.93 H ATOM 4679 N PHE A 283 31.963 22.336 -16.006 1.00 58.88 N ATOM 4680 CA PHE A 283 32.287 20.944 -15.675 1.00 58.24 C ATOM 4681 C PHE A 283 33.622 20.483 -16.267 1.00 57.75 C ATOM 4682 O PHE A 283 34.023 20.936 -17.340 1.00 58.31 O ATOM 4683 CB PHE A 283 31.167 20.002 -16.157 1.00 57.66 C ATOM 4684 CG PHE A 283 29.849 20.170 -15.433 1.00 55.13 C ATOM 4685 CD1 PHE A 283 29.711 19.662 -14.128 1.00 54.02 C ATOM 4686 CD2 PHE A 283 28.809 20.949 -15.980 1.00 54.98 C ATOM 4687 CE1 PHE A 283 28.530 19.856 -13.430 1.00 53.40 C ATOM 4688 CE2 PHE A 283 27.626 21.116 -15.274 1.00 50.39 C ATOM 4689 CZ PHE A 283 27.489 20.565 -14.008 1.00 53.32 C ATOM 4690 H PHE A 283 31.757 22.527 -16.978 1.00 58.88 H ATOM 4691 HA PHE A 283 32.364 20.828 -14.593 1.00 58.24 H ATOM 4692 HB3 PHE A 283 31.480 18.969 -16.000 1.00 57.66 H ATOM 4693 HB2 PHE A 283 31.006 20.092 -17.230 1.00 57.66 H ATOM 4694 HD1 PHE A 283 30.528 19.126 -13.673 1.00 54.02 H ATOM 4695 HD2 PHE A 283 28.918 21.399 -16.954 1.00 54.98 H ATOM 4696 HE1 PHE A 283 28.425 19.460 -12.432 1.00 53.40 H ATOM 4697 HE2 PHE A 283 26.813 21.681 -15.702 1.00 50.39 H ATOM 4698 HZ PHE A 283 26.578 20.712 -13.457 1.00 53.32 H ATOM 4699 N ARG A 284 34.244 19.535 -15.550 1.00 58.60 N ATOM 4700 CA ARG A 284 35.442 18.800 -15.941 1.00 59.79 C ATOM 4701 C ARG A 284 35.183 17.294 -15.783 1.00 59.75 C ATOM 4702 O ARG A 284 34.486 16.876 -14.857 1.00 58.94 O ATOM 4703 CB ARG A 284 36.629 19.226 -15.052 1.00 61.36 C ATOM 4704 CG ARG A 284 37.097 20.677 -15.288 1.00 65.00 C ATOM 4705 CD ARG A 284 38.211 21.164 -14.339 1.00 70.59 C ATOM 4706 NE ARG A 284 39.397 20.284 -14.316 1.00 76.65 N ATOM 4707 CZ ARG A 284 40.336 20.116 -15.268 1.00 78.07 C ATOM 4708 NH1 ARG A 284 40.320 20.792 -16.428 1.00 78.71 N ATOM 4709 NH2 ARG A 284 41.322 19.237 -15.049 1.00 81.82 N1+ ATOM 4710 H ARG A 284 33.835 19.245 -14.670 1.00 58.60 H ATOM 4711 HA ARG A 284 35.685 18.998 -16.988 1.00 59.79 H ATOM 4712 HB3 ARG A 284 37.466 18.555 -15.250 1.00 61.36 H ATOM 4713 HB2 ARG A 284 36.374 19.088 -13.999 1.00 61.36 H ATOM 4714 HG3 ARG A 284 36.236 21.315 -15.088 1.00 65.00 H ATOM 4715 HG2 ARG A 284 37.350 20.865 -16.332 1.00 65.00 H ATOM 4716 HD3 ARG A 284 37.825 21.355 -13.337 1.00 70.59 H ATOM 4717 HD2 ARG A 284 38.568 22.129 -14.701 1.00 70.59 H ATOM 4718 HE ARG A 284 39.478 19.721 -13.482 1.00 76.65 H ATOM 4719 HH12 ARG A 284 41.039 20.647 -17.122 1.00 78.71 H ATOM 4720 HH11 ARG A 284 39.586 21.462 -16.608 1.00 78.71 H ATOM 4721 HH22 ARG A 284 42.041 19.091 -15.743 1.00 81.82 H ATOM 4722 HH21 ARG A 284 41.369 18.723 -14.181 1.00 81.82 H ATOM 4723 N ARG A 285 35.800 16.510 -16.681 1.00 60.71 N ATOM 4724 CA ARG A 285 35.751 15.046 -16.727 1.00 62.35 C ATOM 4725 C ARG A 285 36.380 14.359 -15.498 1.00 63.59 C ATOM 4726 O ARG A 285 35.873 13.322 -15.068 1.00 63.38 O ATOM 4727 CB ARG A 285 36.418 14.606 -18.049 1.00 62.63 C ATOM 4728 CG ARG A 285 36.511 13.082 -18.282 1.00 64.18 C ATOM 4729 CD ARG A 285 37.114 12.679 -19.645 1.00 66.27 C ATOM 4730 NE ARG A 285 36.379 13.247 -20.792 1.00 68.41 N ATOM 4731 CZ ARG A 285 35.136 12.936 -21.205 1.00 67.82 C ATOM 4732 NH1 ARG A 285 34.417 11.960 -20.628 1.00 68.20 N ATOM 4733 NH2 ARG A 285 34.595 13.630 -22.215 1.00 67.35 N1+ ATOM 4734 H ARG A 285 36.351 16.946 -17.406 1.00 60.71 H ATOM 4735 HA ARG A 285 34.700 14.751 -16.761 1.00 62.35 H ATOM 4736 HB3 ARG A 285 37.428 15.017 -18.098 1.00 62.63 H ATOM 4737 HB2 ARG A 285 35.865 15.072 -18.865 1.00 62.63 H ATOM 4738 HG3 ARG A 285 35.553 12.591 -18.111 1.00 64.18 H ATOM 4739 HG2 ARG A 285 37.178 12.672 -17.523 1.00 64.18 H ATOM 4740 HD3 ARG A 285 37.061 11.594 -19.746 1.00 66.27 H ATOM 4741 HD2 ARG A 285 38.174 12.928 -19.694 1.00 66.27 H ATOM 4742 HE ARG A 285 36.854 13.998 -21.273 1.00 68.41 H ATOM 4743 HH12 ARG A 285 33.476 11.760 -20.939 1.00 68.20 H ATOM 4744 HH11 ARG A 285 34.809 11.421 -19.870 1.00 68.20 H ATOM 4745 HH22 ARG A 285 33.650 13.436 -22.519 1.00 67.35 H ATOM 4746 HH21 ARG A 285 35.119 14.351 -22.692 1.00 67.35 H ATOM 4747 N ASN A 286 37.460 14.959 -14.965 1.00 64.60 N ATOM 4748 CA ASN A 286 38.253 14.482 -13.827 1.00 65.46 C ATOM 4749 C ASN A 286 37.441 14.307 -12.527 1.00 64.39 C ATOM 4750 O ASN A 286 37.730 13.390 -11.761 1.00 65.66 O ATOM 4751 CB ASN A 286 39.428 15.469 -13.621 1.00 66.88 C ATOM 4752 CG ASN A 286 40.468 14.995 -12.599 1.00 71.63 C ATOM 4753 OD1 ASN A 286 41.096 13.956 -12.783 1.00 77.56 O ATOM 4754 ND2 ASN A 286 40.658 15.759 -11.520 1.00 73.05 N ATOM 4755 H ASN A 286 37.787 15.814 -15.390 1.00 64.60 H ATOM 4756 HA ASN A 286 38.655 13.501 -14.092 1.00 65.46 H ATOM 4757 HB3 ASN A 286 39.050 16.454 -13.342 1.00 66.88 H ATOM 4758 HB2 ASN A 286 39.957 15.605 -14.565 1.00 66.88 H ATOM 4759 HD22 ASN A 286 41.333 15.478 -10.823 1.00 73.05 H ATOM 4760 HD21 ASN A 286 40.122 16.602 -11.379 1.00 73.05 H ATOM 4761 N THR A 287 36.442 15.179 -12.313 1.00 62.28 N ATOM 4762 CA THR A 287 35.570 15.203 -11.136 1.00 60.97 C ATOM 4763 C THR A 287 34.687 13.943 -10.978 1.00 61.01 C ATOM 4764 O THR A 287 34.300 13.624 -9.854 1.00 60.63 O ATOM 4765 CB THR A 287 34.649 16.455 -11.199 1.00 60.73 C ATOM 4766 OG1 THR A 287 35.459 17.613 -11.288 1.00 61.77 O ATOM 4767 CG2 THR A 287 33.687 16.657 -10.013 1.00 60.86 C ATOM 4768 H THR A 287 36.261 15.900 -12.997 1.00 62.28 H ATOM 4769 HA THR A 287 36.205 15.274 -10.251 1.00 60.97 H ATOM 4770 HB THR A 287 34.059 16.416 -12.115 1.00 60.73 H ATOM 4771 HG1 THR A 287 35.904 17.737 -10.445 1.00 61.77 H ATOM 4772 HG21 THR A 287 33.163 17.610 -10.093 1.00 60.86 H ATOM 4773 HG22 THR A 287 32.921 15.884 -9.972 1.00 60.86 H ATOM 4774 HG23 THR A 287 34.221 16.649 -9.063 1.00 60.86 H ATOM 4775 N TYR A 288 34.409 13.247 -12.094 1.00 61.42 N ATOM 4776 CA TYR A 288 33.488 12.109 -12.172 1.00 61.54 C ATOM 4777 C TYR A 288 34.186 10.840 -12.696 1.00 63.50 C ATOM 4778 O TYR A 288 33.510 9.961 -13.232 1.00 65.43 O ATOM 4779 CB TYR A 288 32.292 12.505 -13.064 1.00 60.07 C ATOM 4780 CG TYR A 288 31.673 13.848 -12.723 1.00 53.76 C ATOM 4781 CD1 TYR A 288 30.878 13.987 -11.567 1.00 49.66 C ATOM 4782 CD2 TYR A 288 31.931 14.973 -13.535 1.00 51.14 C ATOM 4783 CE1 TYR A 288 30.344 15.243 -11.226 1.00 50.75 C ATOM 4784 CE2 TYR A 288 31.399 16.228 -13.193 1.00 46.10 C ATOM 4785 CZ TYR A 288 30.614 16.364 -12.032 1.00 49.56 C ATOM 4786 OH TYR A 288 30.132 17.586 -11.680 1.00 53.87 O ATOM 4787 H TYR A 288 34.796 13.558 -12.974 1.00 61.42 H ATOM 4788 HA TYR A 288 33.104 11.860 -11.182 1.00 61.54 H ATOM 4789 HB3 TYR A 288 31.515 11.743 -13.017 1.00 60.07 H ATOM 4790 HB2 TYR A 288 32.619 12.535 -14.103 1.00 60.07 H ATOM 4791 HD1 TYR A 288 30.686 13.133 -10.934 1.00 49.66 H ATOM 4792 HD2 TYR A 288 32.560 14.888 -14.408 1.00 51.14 H ATOM 4793 HE1 TYR A 288 29.738 15.352 -10.340 1.00 50.75 H ATOM 4794 HE2 TYR A 288 31.615 17.087 -13.811 1.00 46.10 H ATOM 4795 HH TYR A 288 29.612 17.580 -10.865 1.00 53.87 H ATOM 4796 N THR A 289 35.520 10.762 -12.545 1.00 66.18 N ATOM 4797 CA THR A 289 36.370 9.694 -13.083 1.00 68.06 C ATOM 4798 C THR A 289 36.145 8.293 -12.455 1.00 68.75 C ATOM 4799 O THR A 289 36.485 7.296 -13.093 1.00 69.69 O ATOM 4800 CB THR A 289 37.872 10.091 -12.975 1.00 68.50 C ATOM 4801 OG1 THR A 289 38.699 9.173 -13.666 1.00 70.74 O ATOM 4802 CG2 THR A 289 38.414 10.179 -11.536 1.00 69.90 C ATOM 4803 H THR A 289 36.006 11.524 -12.091 1.00 66.18 H ATOM 4804 HA THR A 289 36.127 9.606 -14.144 1.00 68.06 H ATOM 4805 HB THR A 289 38.004 11.062 -13.454 1.00 68.50 H ATOM 4806 HG1 THR A 289 38.605 8.308 -13.259 1.00 70.74 H ATOM 4807 HG21 THR A 289 39.423 10.591 -11.528 1.00 69.90 H ATOM 4808 HG22 THR A 289 37.795 10.825 -10.913 1.00 69.90 H ATOM 4809 HG23 THR A 289 38.459 9.203 -11.055 1.00 69.90 H ATOM 4810 N ASN A 290 35.562 8.238 -11.244 1.00 68.46 N ATOM 4811 CA ASN A 290 35.223 6.997 -10.532 1.00 68.77 C ATOM 4812 C ASN A 290 33.698 6.824 -10.364 1.00 67.13 C ATOM 4813 O ASN A 290 33.285 5.964 -9.587 1.00 66.77 O ATOM 4814 CB ASN A 290 35.943 6.946 -9.158 1.00 69.75 C ATOM 4815 CG ASN A 290 37.472 7.041 -9.231 1.00 74.52 C ATOM 4816 OD1 ASN A 290 38.072 7.882 -8.568 1.00 77.51 O ATOM 4817 ND2 ASN A 290 38.113 6.179 -10.024 1.00 76.76 N ATOM 4818 H ASN A 290 35.309 9.099 -10.780 1.00 68.46 H ATOM 4819 HA ASN A 290 35.534 6.125 -11.109 1.00 68.77 H ATOM 4820 HB3 ASN A 290 35.711 6.013 -8.642 1.00 69.75 H ATOM 4821 HB2 ASN A 290 35.574 7.747 -8.516 1.00 69.75 H ATOM 4822 HD22 ASN A 290 39.120 6.214 -10.088 1.00 76.76 H ATOM 4823 HD21 ASN A 290 37.606 5.505 -10.578 1.00 76.76 H ATOM 4824 N CYS A 291 32.892 7.614 -11.094 1.00 64.71 N ATOM 4825 CA CYS A 291 31.429 7.570 -11.064 1.00 61.63 C ATOM 4826 C CYS A 291 30.918 6.718 -12.237 1.00 60.56 C ATOM 4827 O CYS A 291 31.351 6.927 -13.370 1.00 61.12 O ATOM 4828 CB CYS A 291 30.835 8.988 -11.149 1.00 61.95 C ATOM 4829 SG CYS A 291 31.288 9.943 -9.674 1.00 53.50 S ATOM 4830 H CYS A 291 33.297 8.280 -11.738 1.00 64.71 H ATOM 4831 HA CYS A 291 31.086 7.119 -10.130 1.00 61.63 H ATOM 4832 HB3 CYS A 291 29.747 8.950 -11.223 1.00 61.95 H ATOM 4833 HB2 CYS A 291 31.196 9.516 -12.029 1.00 61.95 H ATOM 4834 HG CYS A 291 30.471 9.298 -8.835 1.00 53.50 H ATOM 4835 N SER A 292 29.994 5.790 -11.941 1.00 59.10 N ATOM 4836 CA SER A 292 29.340 4.912 -12.914 1.00 58.41 C ATOM 4837 C SER A 292 28.048 4.335 -12.319 1.00 57.05 C ATOM 4838 O SER A 292 27.932 4.223 -11.095 1.00 56.68 O ATOM 4839 CB SER A 292 30.312 3.811 -13.410 1.00 57.46 C ATOM 4840 OG SER A 292 30.541 2.798 -12.448 1.00 57.35 O ATOM 4841 H SER A 292 29.680 5.678 -10.987 1.00 59.10 H ATOM 4842 HA SER A 292 29.058 5.529 -13.769 1.00 58.41 H ATOM 4843 HB3 SER A 292 31.268 4.232 -13.720 1.00 57.46 H ATOM 4844 HB2 SER A 292 29.891 3.333 -14.295 1.00 57.46 H ATOM 4845 HG SER A 292 31.139 2.150 -12.828 1.00 57.35 H ATOM 4846 N LEU A 293 27.100 3.974 -13.203 1.00 55.59 N ATOM 4847 CA LEU A 293 25.794 3.409 -12.842 1.00 54.05 C ATOM 4848 C LEU A 293 25.909 2.049 -12.127 1.00 53.95 C ATOM 4849 O LEU A 293 25.116 1.789 -11.224 1.00 54.55 O ATOM 4850 CB LEU A 293 24.900 3.338 -14.104 1.00 52.73 C ATOM 4851 CG LEU A 293 23.417 2.958 -13.864 1.00 48.76 C ATOM 4852 CD1 LEU A 293 22.675 3.984 -12.980 1.00 46.61 C ATOM 4853 CD2 LEU A 293 22.683 2.693 -15.196 1.00 46.33 C ATOM 4854 H LEU A 293 27.264 4.103 -14.194 1.00 55.59 H ATOM 4855 HA LEU A 293 25.341 4.105 -12.135 1.00 54.05 H ATOM 4856 HB3 LEU A 293 25.345 2.623 -14.799 1.00 52.73 H ATOM 4857 HB2 LEU A 293 24.929 4.301 -14.614 1.00 52.73 H ATOM 4858 HG LEU A 293 23.399 2.010 -13.330 1.00 48.76 H ATOM 4859 HD11 LEU A 293 21.738 4.319 -13.424 1.00 46.61 H ATOM 4860 HD12 LEU A 293 22.429 3.555 -12.009 1.00 46.61 H ATOM 4861 HD13 LEU A 293 23.272 4.876 -12.793 1.00 46.61 H ATOM 4862 HD21 LEU A 293 22.186 1.722 -15.174 1.00 46.33 H ATOM 4863 HD22 LEU A 293 21.920 3.439 -15.419 1.00 46.33 H ATOM 4864 HD23 LEU A 293 23.367 2.682 -16.046 1.00 46.33 H ATOM 4865 N ILE A 294 26.927 1.247 -12.496 1.00 54.71 N ATOM 4866 CA ILE A 294 27.310 -0.006 -11.837 1.00 55.76 C ATOM 4867 C ILE A 294 27.604 0.196 -10.339 1.00 55.52 C ATOM 4868 O ILE A 294 26.988 -0.476 -9.515 1.00 55.36 O ATOM 4869 CB ILE A 294 28.541 -0.667 -12.539 1.00 55.42 C ATOM 4870 CG1 ILE A 294 28.142 -1.195 -13.937 1.00 58.15 C ATOM 4871 CG2 ILE A 294 29.249 -1.781 -11.726 1.00 54.88 C ATOM 4872 CD1 ILE A 294 29.328 -1.594 -14.828 1.00 55.47 C ATOM 4873 H ILE A 294 27.532 1.549 -13.245 1.00 54.71 H ATOM 4874 HA ILE A 294 26.463 -0.689 -11.912 1.00 55.76 H ATOM 4875 HB ILE A 294 29.281 0.120 -12.698 1.00 55.42 H ATOM 4876 HG13 ILE A 294 27.567 -0.441 -14.473 1.00 58.15 H ATOM 4877 HG12 ILE A 294 27.477 -2.053 -13.822 1.00 58.15 H ATOM 4878 HG21 ILE A 294 30.048 -2.252 -12.297 1.00 54.88 H ATOM 4879 HG22 ILE A 294 29.718 -1.399 -10.819 1.00 54.88 H ATOM 4880 HG23 ILE A 294 28.553 -2.564 -11.431 1.00 54.88 H ATOM 4881 HD11 ILE A 294 29.073 -1.485 -15.882 1.00 55.47 H ATOM 4882 HD12 ILE A 294 30.204 -0.976 -14.635 1.00 55.47 H ATOM 4883 HD13 ILE A 294 29.608 -2.635 -14.665 1.00 55.47 H ATOM 4884 N LYS A 295 28.491 1.157 -10.029 1.00 56.35 N ATOM 4885 CA LYS A 295 28.893 1.517 -8.669 1.00 56.38 C ATOM 4886 C LYS A 295 27.761 2.125 -7.825 1.00 56.12 C ATOM 4887 O LYS A 295 27.739 1.891 -6.618 1.00 55.82 O ATOM 4888 CB LYS A 295 30.101 2.470 -8.732 1.00 57.78 C ATOM 4889 CG LYS A 295 31.381 1.786 -9.236 0.00 56.56 C ATOM 4890 CD LYS A 295 32.538 2.777 -9.398 0.00 56.72 C ATOM 4891 CE LYS A 295 33.831 2.096 -9.867 0.00 56.69 C ATOM 4892 NZ LYS A 295 34.935 3.062 -10.000 0.00 56.73 N1+ ATOM 4893 H LYS A 295 28.928 1.685 -10.771 1.00 56.35 H ATOM 4894 HA LYS A 295 29.208 0.600 -8.168 1.00 56.38 H ATOM 4895 HB3 LYS A 295 30.304 2.871 -7.737 1.00 57.78 H ATOM 4896 HB2 LYS A 295 29.862 3.328 -9.362 1.00 57.78 H ATOM 4897 HG3 LYS A 295 31.193 1.292 -10.190 1.00 56.56 H ATOM 4898 HG2 LYS A 295 31.667 0.998 -8.538 1.00 56.56 H ATOM 4899 HD3 LYS A 295 32.707 3.292 -8.451 1.00 56.72 H ATOM 4900 HD2 LYS A 295 32.244 3.543 -10.118 1.00 56.72 H ATOM 4901 HE3 LYS A 295 33.673 1.609 -10.830 1.00 56.69 H ATOM 4902 HE2 LYS A 295 34.129 1.321 -9.159 1.00 56.69 H ATOM 4903 HZ1 LYS A 295 35.110 3.494 -9.104 1.00 56.73 H ATOM 4904 HZ2 LYS A 295 35.768 2.583 -10.315 1.00 56.73 H ATOM 4905 HZ3 LYS A 295 34.677 3.772 -10.670 1.00 56.73 H ATOM 4906 N TYR A 296 26.840 2.869 -8.463 1.00 55.86 N ATOM 4907 CA TYR A 296 25.666 3.442 -7.807 1.00 55.95 C ATOM 4908 C TYR A 296 24.648 2.369 -7.378 1.00 56.54 C ATOM 4909 O TYR A 296 24.216 2.382 -6.226 1.00 55.58 O ATOM 4910 CB TYR A 296 25.029 4.531 -8.699 1.00 55.85 C ATOM 4911 CG TYR A 296 23.778 5.148 -8.097 1.00 54.78 C ATOM 4912 CD1 TYR A 296 23.892 6.116 -7.078 1.00 51.21 C ATOM 4913 CD2 TYR A 296 22.502 4.701 -8.497 1.00 49.91 C ATOM 4914 CE1 TYR A 296 22.738 6.615 -6.448 1.00 50.43 C ATOM 4915 CE2 TYR A 296 21.350 5.185 -7.852 1.00 52.44 C ATOM 4916 CZ TYR A 296 21.467 6.141 -6.823 1.00 51.84 C ATOM 4917 OH TYR A 296 20.356 6.600 -6.179 1.00 57.47 O ATOM 4918 H TYR A 296 26.928 3.030 -9.458 1.00 55.86 H ATOM 4919 HA TYR A 296 26.015 3.937 -6.898 1.00 55.95 H ATOM 4920 HB3 TYR A 296 24.778 4.114 -9.676 1.00 55.85 H ATOM 4921 HB2 TYR A 296 25.752 5.325 -8.892 1.00 55.85 H ATOM 4922 HD1 TYR A 296 24.867 6.461 -6.764 1.00 51.21 H ATOM 4923 HD2 TYR A 296 22.408 3.958 -9.275 1.00 49.91 H ATOM 4924 HE1 TYR A 296 22.832 7.344 -5.657 1.00 50.43 H ATOM 4925 HE2 TYR A 296 20.380 4.814 -8.148 1.00 52.44 H ATOM 4926 HH TYR A 296 19.548 6.168 -6.478 1.00 57.47 H ATOM 4927 N MET A 297 24.284 1.469 -8.307 1.00 57.42 N ATOM 4928 CA MET A 297 23.298 0.412 -8.073 1.00 59.47 C ATOM 4929 C MET A 297 23.808 -0.706 -7.143 1.00 61.47 C ATOM 4930 O MET A 297 22.992 -1.258 -6.407 1.00 61.15 O ATOM 4931 CB MET A 297 22.780 -0.136 -9.418 1.00 59.09 C ATOM 4932 CG MET A 297 22.008 0.891 -10.274 1.00 60.09 C ATOM 4933 SD MET A 297 20.545 1.682 -9.541 1.00 60.20 S ATOM 4934 CE MET A 297 19.496 0.240 -9.239 1.00 52.16 C ATOM 4935 H MET A 297 24.680 1.515 -9.237 1.00 57.42 H ATOM 4936 HA MET A 297 22.452 0.864 -7.553 1.00 59.47 H ATOM 4937 HB3 MET A 297 22.138 -0.999 -9.252 1.00 59.09 H ATOM 4938 HB2 MET A 297 23.624 -0.516 -9.996 1.00 59.09 H ATOM 4939 HG3 MET A 297 21.688 0.415 -11.201 1.00 60.09 H ATOM 4940 HG2 MET A 297 22.678 1.695 -10.571 1.00 60.09 H ATOM 4941 HE1 MET A 297 18.475 0.555 -9.027 1.00 52.16 H ATOM 4942 HE2 MET A 297 19.480 -0.418 -10.107 1.00 52.16 H ATOM 4943 HE3 MET A 297 19.872 -0.313 -8.381 1.00 52.16 H ATOM 4944 N GLU A 298 25.130 -0.967 -7.125 1.00 65.13 N ATOM 4945 CA GLU A 298 25.804 -1.848 -6.160 1.00 67.74 C ATOM 4946 C GLU A 298 25.631 -1.407 -4.695 1.00 69.42 C ATOM 4947 O GLU A 298 25.390 -2.260 -3.841 1.00 70.36 O ATOM 4948 CB GLU A 298 27.306 -1.964 -6.499 1.00 68.58 C ATOM 4949 CG GLU A 298 27.620 -3.018 -7.582 1.00 71.32 C ATOM 4950 CD GLU A 298 29.107 -3.114 -7.974 1.00 72.83 C ATOM 4951 OE1 GLU A 298 29.851 -2.124 -7.792 1.00 71.21 O ATOM 4952 OE2 GLU A 298 29.486 -4.200 -8.464 1.00 73.73 O1- ATOM 4953 H GLU A 298 25.736 -0.494 -7.783 1.00 65.13 H ATOM 4954 HA GLU A 298 25.350 -2.838 -6.245 1.00 67.74 H ATOM 4955 HB3 GLU A 298 27.886 -2.201 -5.605 1.00 68.58 H ATOM 4956 HB2 GLU A 298 27.661 -0.985 -6.825 1.00 68.58 H ATOM 4957 HG3 GLU A 298 27.041 -2.819 -8.483 1.00 71.32 H ATOM 4958 HG2 GLU A 298 27.289 -3.994 -7.224 1.00 71.32 H ATOM 4959 N LYS A 299 25.722 -0.088 -4.441 1.00 70.40 N ATOM 4960 CA LYS A 299 25.502 0.529 -3.127 1.00 71.56 C ATOM 4961 C LYS A 299 24.046 0.427 -2.633 1.00 71.21 C ATOM 4962 O LYS A 299 23.831 0.466 -1.422 1.00 71.35 O ATOM 4963 CB LYS A 299 25.949 2.004 -3.167 1.00 72.29 C ATOM 4964 CG LYS A 299 27.470 2.186 -3.299 1.00 75.60 C ATOM 4965 CD LYS A 299 27.853 3.647 -3.577 1.00 78.97 C ATOM 4966 CE LYS A 299 29.367 3.834 -3.757 1.00 80.69 C ATOM 4967 NZ LYS A 299 29.715 5.244 -4.006 1.00 80.50 N1+ ATOM 4968 H LYS A 299 25.924 0.547 -5.201 1.00 70.40 H ATOM 4969 HA LYS A 299 26.127 0.000 -2.404 1.00 71.56 H ATOM 4970 HB3 LYS A 299 25.632 2.513 -2.256 1.00 72.29 H ATOM 4971 HB2 LYS A 299 25.441 2.517 -3.983 1.00 72.29 H ATOM 4972 HG3 LYS A 299 27.861 1.547 -4.089 1.00 75.60 H ATOM 4973 HG2 LYS A 299 27.951 1.851 -2.380 1.00 75.60 H ATOM 4974 HD3 LYS A 299 27.495 4.270 -2.756 1.00 78.97 H ATOM 4975 HD2 LYS A 299 27.330 3.987 -4.473 1.00 78.97 H ATOM 4976 HE3 LYS A 299 29.724 3.232 -4.594 1.00 80.69 H ATOM 4977 HE2 LYS A 299 29.898 3.495 -2.866 1.00 80.69 H ATOM 4978 HZ1 LYS A 299 29.414 5.809 -3.225 1.00 80.50 H ATOM 4979 HZ2 LYS A 299 30.715 5.331 -4.117 1.00 80.50 H ATOM 4980 HZ3 LYS A 299 29.255 5.562 -4.847 1.00 80.50 H ATOM 4981 N HIS A 300 23.092 0.277 -3.568 1.00 70.74 N ATOM 4982 CA HIS A 300 21.662 0.110 -3.298 1.00 70.09 C ATOM 4983 C HIS A 300 21.189 -1.345 -3.504 1.00 70.25 C ATOM 4984 O HIS A 300 19.990 -1.572 -3.670 1.00 70.51 O ATOM 4985 CB HIS A 300 20.855 1.130 -4.124 1.00 69.84 C ATOM 4986 CG HIS A 300 21.135 2.573 -3.779 1.00 69.97 C ATOM 4987 ND1 HIS A 300 22.229 3.270 -4.265 1.00 72.04 N ATOM 4988 CD2 HIS A 300 20.451 3.469 -2.986 1.00 70.91 C ATOM 4989 CE1 HIS A 300 22.180 4.497 -3.742 1.00 72.90 C ATOM 4990 NE2 HIS A 300 21.126 4.691 -2.959 1.00 72.34 N ATOM 4991 H HIS A 300 23.362 0.240 -4.541 1.00 70.74 H ATOM 4992 HA HIS A 300 21.459 0.327 -2.248 1.00 70.09 H ATOM 4993 HB3 HIS A 300 19.792 0.974 -3.949 1.00 69.84 H ATOM 4994 HB2 HIS A 300 21.026 0.980 -5.191 1.00 69.84 H ATOM 4995 HD1 HIS A 300 22.939 2.917 -4.897 1.00 72.04 H ATOM 4996 HD2 HIS A 300 19.539 3.329 -2.425 1.00 70.91 H ATOM 4997 HE1 HIS A 300 22.920 5.257 -3.940 1.00 72.90 H ATOM 4998 N LYS A 301 22.131 -2.305 -3.431 1.00 70.79 N ATOM 4999 CA LYS A 301 21.916 -3.755 -3.340 1.00 70.62 C ATOM 5000 C LYS A 301 21.310 -4.393 -4.614 1.00 69.50 C ATOM 5001 O LYS A 301 20.630 -5.415 -4.521 1.00 70.99 O ATOM 5002 CB LYS A 301 21.142 -4.076 -2.032 1.00 71.38 C ATOM 5003 CG LYS A 301 21.304 -5.509 -1.492 0.00 70.99 C ATOM 5004 CD LYS A 301 20.609 -5.688 -0.134 0.00 71.08 C ATOM 5005 CE LYS A 301 20.772 -7.108 0.431 0.00 71.06 C ATOM 5006 NZ LYS A 301 20.103 -7.254 1.736 0.00 71.05 N1+ ATOM 5007 H LYS A 301 23.094 -2.014 -3.322 1.00 70.79 H ATOM 5008 HA LYS A 301 22.914 -4.185 -3.248 1.00 70.62 H ATOM 5009 HB3 LYS A 301 20.085 -3.832 -2.147 1.00 71.38 H ATOM 5010 HB2 LYS A 301 21.514 -3.411 -1.251 1.00 71.38 H ATOM 5011 HG3 LYS A 301 22.365 -5.739 -1.391 1.00 70.99 H ATOM 5012 HG2 LYS A 301 20.898 -6.238 -2.192 1.00 70.99 H ATOM 5013 HD3 LYS A 301 19.550 -5.451 -0.243 1.00 71.08 H ATOM 5014 HD2 LYS A 301 21.014 -4.962 0.573 1.00 71.08 H ATOM 5015 HE3 LYS A 301 21.829 -7.347 0.552 1.00 71.06 H ATOM 5016 HE2 LYS A 301 20.353 -7.840 -0.260 1.00 71.06 H ATOM 5017 HZ1 LYS A 301 19.116 -7.064 1.633 1.00 71.05 H ATOM 5018 HZ2 LYS A 301 20.231 -8.195 2.079 1.00 71.05 H ATOM 5019 HZ3 LYS A 301 20.503 -6.600 2.395 1.00 71.05 H ATOM 5020 N VAL A 302 21.588 -3.799 -5.786 1.00 66.92 N ATOM 5021 CA VAL A 302 21.215 -4.326 -7.099 1.00 64.34 C ATOM 5022 C VAL A 302 22.500 -4.746 -7.832 1.00 64.59 C ATOM 5023 O VAL A 302 23.401 -3.927 -8.019 1.00 65.55 O ATOM 5024 CB VAL A 302 20.444 -3.269 -7.941 1.00 64.20 C ATOM 5025 CG1 VAL A 302 20.269 -3.624 -9.436 1.00 59.88 C ATOM 5026 CG2 VAL A 302 19.070 -2.972 -7.316 1.00 59.08 C ATOM 5027 H VAL A 302 22.147 -2.955 -5.797 1.00 66.92 H ATOM 5028 HA VAL A 302 20.573 -5.203 -6.995 1.00 64.34 H ATOM 5029 HB VAL A 302 21.006 -2.339 -7.897 1.00 64.20 H ATOM 5030 HG11 VAL A 302 19.630 -2.898 -9.940 1.00 59.88 H ATOM 5031 HG12 VAL A 302 21.218 -3.626 -9.973 1.00 59.88 H ATOM 5032 HG13 VAL A 302 19.810 -4.605 -9.559 1.00 59.88 H ATOM 5033 HG21 VAL A 302 18.530 -2.228 -7.898 1.00 59.08 H ATOM 5034 HG22 VAL A 302 18.451 -3.868 -7.270 1.00 59.08 H ATOM 5035 HG23 VAL A 302 19.166 -2.581 -6.302 1.00 59.08 H ATOM 5036 N LYS A 303 22.551 -6.030 -8.216 1.00 65.08 N ATOM 5037 CA LYS A 303 23.697 -6.663 -8.867 1.00 65.93 C ATOM 5038 C LYS A 303 23.832 -6.193 -10.333 1.00 66.57 C ATOM 5039 O LYS A 303 22.818 -6.153 -11.031 1.00 65.70 O ATOM 5040 CB LYS A 303 23.480 -8.186 -8.837 1.00 66.75 C ATOM 5041 CG LYS A 303 23.407 -8.798 -7.429 1.00 66.75 C ATOM 5042 CD LYS A 303 23.278 -10.327 -7.483 0.00 66.79 C ATOM 5043 CE LYS A 303 23.208 -10.966 -6.088 0.00 66.80 C ATOM 5044 NZ LYS A 303 23.092 -12.433 -6.168 0.00 66.81 N1+ ATOM 5045 H LYS A 303 21.762 -6.632 -8.033 1.00 65.08 H ATOM 5046 HA LYS A 303 24.579 -6.418 -8.275 1.00 65.93 H ATOM 5047 HB3 LYS A 303 24.317 -8.650 -9.354 1.00 66.75 H ATOM 5048 HB2 LYS A 303 22.583 -8.454 -9.397 1.00 66.75 H ATOM 5049 HG3 LYS A 303 22.559 -8.384 -6.882 1.00 66.75 H ATOM 5050 HG2 LYS A 303 24.301 -8.525 -6.867 1.00 66.75 H ATOM 5051 HD3 LYS A 303 24.127 -10.736 -8.035 1.00 66.79 H ATOM 5052 HD2 LYS A 303 22.387 -10.589 -8.056 1.00 66.79 H ATOM 5053 HE3 LYS A 303 22.352 -10.576 -5.536 1.00 66.80 H ATOM 5054 HE2 LYS A 303 24.101 -10.717 -5.513 1.00 66.80 H ATOM 5055 HZ1 LYS A 303 23.895 -12.807 -6.655 1.00 66.81 H ATOM 5056 HZ2 LYS A 303 23.052 -12.822 -5.237 1.00 66.81 H ATOM 5057 HZ3 LYS A 303 22.252 -12.678 -6.672 1.00 66.81 H ATOM 5058 N PRO A 304 25.060 -5.853 -10.789 1.00 67.20 N ATOM 5059 CA PRO A 304 25.275 -5.373 -12.165 1.00 67.36 C ATOM 5060 C PRO A 304 25.138 -6.446 -13.264 1.00 67.13 C ATOM 5061 O PRO A 304 24.882 -6.078 -14.408 1.00 65.88 O ATOM 5062 CB PRO A 304 26.684 -4.774 -12.118 1.00 68.01 C ATOM 5063 CG PRO A 304 27.404 -5.615 -11.078 1.00 69.61 C ATOM 5064 CD PRO A 304 26.317 -5.880 -10.039 1.00 67.27 C ATOM 5065 HA PRO A 304 24.566 -4.578 -12.384 1.00 67.36 H ATOM 5066 HB3 PRO A 304 26.615 -3.740 -11.776 1.00 68.01 H ATOM 5067 HB2 PRO A 304 27.197 -4.766 -13.081 1.00 68.01 H ATOM 5068 HG3 PRO A 304 28.291 -5.131 -10.674 1.00 69.61 H ATOM 5069 HG2 PRO A 304 27.717 -6.559 -11.528 1.00 69.61 H ATOM 5070 HD2 PRO A 304 26.487 -6.827 -9.526 1.00 67.27 H ATOM 5071 HD3 PRO A 304 26.298 -5.080 -9.298 1.00 67.27 H ATOM 5072 N ASP A 305 25.288 -7.737 -12.911 1.00 66.00 N ATOM 5073 CA ASP A 305 25.131 -8.873 -13.830 1.00 65.99 C ATOM 5074 C ASP A 305 23.656 -9.249 -14.098 1.00 62.54 C ATOM 5075 O ASP A 305 23.408 -10.033 -15.014 1.00 63.00 O ATOM 5076 CB ASP A 305 25.979 -10.116 -13.436 1.00 67.73 C ATOM 5077 CG ASP A 305 25.841 -10.703 -12.016 1.00 75.19 C ATOM 5078 OD1 ASP A 305 24.936 -10.287 -11.260 1.00 82.66 O ATOM 5079 OD2 ASP A 305 26.630 -11.628 -11.726 1.00 80.95 O1- ATOM 5080 H ASP A 305 25.492 -7.978 -11.951 1.00 66.00 H ATOM 5081 HA ASP A 305 25.531 -8.555 -14.792 1.00 65.99 H ATOM 5082 HB3 ASP A 305 27.029 -9.848 -13.562 1.00 67.73 H ATOM 5083 HB2 ASP A 305 25.806 -10.920 -14.154 1.00 67.73 H ATOM 5084 N SER A 306 22.710 -8.695 -13.316 1.00 58.93 N ATOM 5085 CA SER A 306 21.274 -8.957 -13.439 1.00 54.66 C ATOM 5086 C SER A 306 20.660 -8.367 -14.722 1.00 54.68 C ATOM 5087 O SER A 306 21.143 -7.354 -15.234 1.00 51.52 O ATOM 5088 CB SER A 306 20.548 -8.469 -12.164 1.00 53.28 C ATOM 5089 OG SER A 306 20.367 -7.066 -12.120 1.00 55.13 O ATOM 5090 H SER A 306 22.988 -8.054 -12.587 1.00 58.93 H ATOM 5091 HA SER A 306 21.167 -10.041 -13.481 1.00 54.66 H ATOM 5092 HB3 SER A 306 21.083 -8.790 -11.270 1.00 53.28 H ATOM 5093 HB2 SER A 306 19.561 -8.927 -12.109 1.00 53.28 H ATOM 5094 HG SER A 306 21.199 -6.662 -11.846 1.00 55.13 H ATOM 5095 N LYS A 307 19.570 -9.002 -15.185 1.00 53.23 N ATOM 5096 CA LYS A 307 18.763 -8.541 -16.318 1.00 52.28 C ATOM 5097 C LYS A 307 18.011 -7.227 -16.037 1.00 52.07 C ATOM 5098 O LYS A 307 17.781 -6.468 -16.979 1.00 49.42 O ATOM 5099 CB LYS A 307 17.784 -9.648 -16.753 1.00 52.90 C ATOM 5100 CG LYS A 307 18.480 -10.893 -17.322 1.00 52.19 C ATOM 5101 CD LYS A 307 17.482 -11.874 -17.950 1.00 53.91 C ATOM 5102 CE LYS A 307 18.118 -13.231 -18.284 1.00 52.81 C ATOM 5103 NZ LYS A 307 17.109 -14.209 -18.725 1.00 55.56 N1+ ATOM 5104 H LYS A 307 19.240 -9.834 -14.713 1.00 53.23 H ATOM 5105 HA LYS A 307 19.450 -8.348 -17.144 1.00 52.28 H ATOM 5106 HB3 LYS A 307 17.120 -9.256 -17.523 1.00 52.90 H ATOM 5107 HB2 LYS A 307 17.141 -9.931 -15.919 1.00 52.90 H ATOM 5108 HG3 LYS A 307 19.032 -11.393 -16.525 1.00 52.19 H ATOM 5109 HG2 LYS A 307 19.218 -10.599 -18.070 1.00 52.19 H ATOM 5110 HD3 LYS A 307 17.087 -11.429 -18.864 1.00 53.91 H ATOM 5111 HD2 LYS A 307 16.627 -12.000 -17.286 1.00 53.91 H ATOM 5112 HE3 LYS A 307 18.621 -13.639 -17.406 1.00 52.81 H ATOM 5113 HE2 LYS A 307 18.873 -13.116 -19.062 1.00 52.81 H ATOM 5114 HZ1 LYS A 307 16.442 -14.353 -17.979 1.00 55.56 H ATOM 5115 HZ2 LYS A 307 16.629 -13.859 -19.542 1.00 55.56 H ATOM 5116 HZ3 LYS A 307 17.559 -15.086 -18.944 1.00 55.56 H ATOM 5117 N ALA A 308 17.684 -6.971 -14.755 1.00 50.57 N ATOM 5118 CA ALA A 308 17.122 -5.715 -14.259 1.00 49.65 C ATOM 5119 C ALA A 308 18.063 -4.524 -14.481 1.00 48.84 C ATOM 5120 O ALA A 308 17.605 -3.484 -14.951 1.00 48.46 O ATOM 5121 CB ALA A 308 16.803 -5.849 -12.760 1.00 48.80 C ATOM 5122 H ALA A 308 17.883 -7.669 -14.052 1.00 50.57 H ATOM 5123 HA ALA A 308 16.192 -5.528 -14.799 1.00 49.65 H ATOM 5124 HB1 ALA A 308 16.274 -4.970 -12.391 1.00 48.80 H ATOM 5125 HB2 ALA A 308 16.176 -6.715 -12.558 1.00 48.80 H ATOM 5126 HB3 ALA A 308 17.708 -5.966 -12.164 1.00 48.80 H ATOM 5127 N PHE A 309 19.359 -4.711 -14.166 1.00 48.38 N ATOM 5128 CA PHE A 309 20.398 -3.700 -14.346 1.00 49.42 C ATOM 5129 C PHE A 309 20.689 -3.390 -15.824 1.00 49.49 C ATOM 5130 O PHE A 309 20.826 -2.217 -16.168 1.00 49.11 O ATOM 5131 CB PHE A 309 21.679 -4.096 -13.579 1.00 48.95 C ATOM 5132 CG PHE A 309 22.798 -3.075 -13.696 1.00 48.20 C ATOM 5133 CD1 PHE A 309 22.796 -1.945 -12.854 1.00 46.29 C ATOM 5134 CD2 PHE A 309 23.711 -3.125 -14.773 1.00 43.56 C ATOM 5135 CE1 PHE A 309 23.702 -0.919 -13.073 1.00 45.18 C ATOM 5136 CE2 PHE A 309 24.605 -2.085 -14.978 1.00 44.55 C ATOM 5137 CZ PHE A 309 24.593 -0.982 -14.136 1.00 45.82 C ATOM 5138 H PHE A 309 19.657 -5.600 -13.787 1.00 48.38 H ATOM 5139 HA PHE A 309 20.028 -2.779 -13.892 1.00 49.42 H ATOM 5140 HB3 PHE A 309 22.043 -5.068 -13.916 1.00 48.95 H ATOM 5141 HB2 PHE A 309 21.440 -4.213 -12.521 1.00 48.95 H ATOM 5142 HD1 PHE A 309 22.078 -1.866 -12.051 1.00 46.29 H ATOM 5143 HD2 PHE A 309 23.695 -3.957 -15.462 1.00 43.56 H ATOM 5144 HE1 PHE A 309 23.701 -0.058 -12.425 1.00 45.18 H ATOM 5145 HE2 PHE A 309 25.295 -2.121 -15.808 1.00 44.55 H ATOM 5146 HZ PHE A 309 25.272 -0.163 -14.315 1.00 45.82 H ATOM 5147 N HIS A 310 20.785 -4.437 -16.663 1.00 50.30 N ATOM 5148 CA HIS A 310 21.067 -4.300 -18.093 1.00 49.83 C ATOM 5149 C HIS A 310 19.955 -3.582 -18.874 1.00 50.15 C ATOM 5150 O HIS A 310 20.278 -2.817 -19.782 1.00 52.53 O ATOM 5151 CB HIS A 310 21.407 -5.666 -18.716 1.00 49.67 C ATOM 5152 CG HIS A 310 22.825 -6.110 -18.466 1.00 52.02 C ATOM 5153 ND1 HIS A 310 23.230 -6.764 -17.315 1.00 54.58 N ATOM 5154 CD2 HIS A 310 23.956 -6.000 -19.246 1.00 53.31 C ATOM 5155 CE1 HIS A 310 24.536 -7.010 -17.445 1.00 53.15 C ATOM 5156 NE2 HIS A 310 25.046 -6.570 -18.588 1.00 49.74 N ATOM 5157 H HIS A 310 20.674 -5.377 -16.308 1.00 50.30 H ATOM 5158 HA HIS A 310 21.952 -3.667 -18.191 1.00 49.83 H ATOM 5159 HB3 HIS A 310 21.284 -5.629 -19.798 1.00 49.67 H ATOM 5160 HB2 HIS A 310 20.720 -6.435 -18.359 1.00 49.67 H ATOM 5161 HD1 HIS A 310 22.648 -7.013 -16.524 1.00 54.58 H ATOM 5162 HD2 HIS A 310 24.068 -5.553 -20.223 1.00 53.31 H ATOM 5163 HE1 HIS A 310 25.125 -7.515 -16.696 1.00 53.15 H ATOM 5164 N LEU A 311 18.687 -3.792 -18.478 1.00 48.63 N ATOM 5165 CA LEU A 311 17.541 -3.046 -18.996 1.00 48.91 C ATOM 5166 C LEU A 311 17.535 -1.588 -18.504 1.00 48.90 C ATOM 5167 O LEU A 311 17.306 -0.696 -19.316 1.00 50.09 O ATOM 5168 CB LEU A 311 16.234 -3.799 -18.656 1.00 47.24 C ATOM 5169 CG LEU A 311 14.910 -3.114 -19.079 1.00 47.64 C ATOM 5170 CD1 LEU A 311 14.827 -2.784 -20.586 1.00 44.16 C ATOM 5171 CD2 LEU A 311 13.703 -3.951 -18.632 1.00 40.53 C ATOM 5172 H LEU A 311 18.495 -4.446 -17.731 1.00 48.63 H ATOM 5173 HA LEU A 311 17.644 -3.021 -20.082 1.00 48.91 H ATOM 5174 HB3 LEU A 311 16.200 -3.972 -17.578 1.00 47.24 H ATOM 5175 HB2 LEU A 311 16.284 -4.790 -19.105 1.00 47.24 H ATOM 5176 HG LEU A 311 14.830 -2.171 -18.540 1.00 47.64 H ATOM 5177 HD11 LEU A 311 14.766 -1.707 -20.745 1.00 44.16 H ATOM 5178 HD12 LEU A 311 15.690 -3.144 -21.144 1.00 44.16 H ATOM 5179 HD13 LEU A 311 13.949 -3.229 -21.055 1.00 44.16 H ATOM 5180 HD21 LEU A 311 12.774 -3.584 -19.068 1.00 40.53 H ATOM 5181 HD22 LEU A 311 13.816 -4.995 -18.922 1.00 40.53 H ATOM 5182 HD23 LEU A 311 13.592 -3.913 -17.548 1.00 40.53 H ATOM 5183 N LEU A 312 17.825 -1.367 -17.208 1.00 48.45 N ATOM 5184 CA LEU A 312 17.892 -0.047 -16.571 1.00 47.94 C ATOM 5185 C LEU A 312 18.945 0.887 -17.197 1.00 48.54 C ATOM 5186 O LEU A 312 18.665 2.072 -17.374 1.00 50.14 O ATOM 5187 CB LEU A 312 18.115 -0.241 -15.051 1.00 47.46 C ATOM 5188 CG LEU A 312 18.263 1.029 -14.182 1.00 45.70 C ATOM 5189 CD1 LEU A 312 17.020 1.936 -14.246 1.00 43.84 C ATOM 5190 CD2 LEU A 312 18.648 0.667 -12.733 1.00 41.54 C ATOM 5191 H LEU A 312 18.003 -2.156 -16.601 1.00 48.45 H ATOM 5192 HA LEU A 312 16.917 0.412 -16.734 1.00 47.94 H ATOM 5193 HB3 LEU A 312 19.013 -0.842 -14.912 1.00 47.46 H ATOM 5194 HB2 LEU A 312 17.300 -0.837 -14.644 1.00 47.46 H ATOM 5195 HG LEU A 312 19.099 1.608 -14.577 1.00 45.70 H ATOM 5196 HD11 LEU A 312 17.322 2.976 -14.343 1.00 43.84 H ATOM 5197 HD12 LEU A 312 16.372 1.724 -15.093 1.00 43.84 H ATOM 5198 HD13 LEU A 312 16.398 1.849 -13.358 1.00 43.84 H ATOM 5199 HD21 LEU A 312 17.956 1.071 -11.995 1.00 41.54 H ATOM 5200 HD22 LEU A 312 18.688 -0.411 -12.576 1.00 41.54 H ATOM 5201 HD23 LEU A 312 19.635 1.063 -12.493 1.00 41.54 H ATOM 5202 N GLN A 313 20.114 0.327 -17.544 1.00 49.36 N ATOM 5203 CA GLN A 313 21.218 1.014 -18.210 1.00 50.51 C ATOM 5204 C GLN A 313 20.905 1.408 -19.670 1.00 49.65 C ATOM 5205 O GLN A 313 21.414 2.430 -20.130 1.00 50.15 O ATOM 5206 CB GLN A 313 22.481 0.140 -18.055 1.00 50.76 C ATOM 5207 CG GLN A 313 23.756 0.691 -18.722 1.00 54.81 C ATOM 5208 CD GLN A 313 25.004 -0.058 -18.256 1.00 58.06 C ATOM 5209 OE1 GLN A 313 25.759 0.442 -17.425 1.00 58.09 O ATOM 5210 NE2 GLN A 313 25.220 -1.266 -18.781 1.00 57.02 N ATOM 5211 H GLN A 313 20.267 -0.651 -17.332 1.00 49.36 H ATOM 5212 HA GLN A 313 21.393 1.946 -17.670 1.00 50.51 H ATOM 5213 HB3 GLN A 313 22.281 -0.863 -18.437 1.00 50.76 H ATOM 5214 HB2 GLN A 313 22.672 0.014 -16.988 1.00 50.76 H ATOM 5215 HG3 GLN A 313 23.876 1.746 -18.472 1.00 54.81 H ATOM 5216 HG2 GLN A 313 23.684 0.633 -19.809 1.00 54.81 H ATOM 5217 HE22 GLN A 313 26.030 -1.801 -18.504 1.00 57.02 H ATOM 5218 HE21 GLN A 313 24.570 -1.663 -19.449 1.00 57.02 H ATOM 5219 N LYS A 314 20.043 0.630 -20.349 1.00 50.04 N ATOM 5220 CA LYS A 314 19.529 0.937 -21.687 1.00 49.87 C ATOM 5221 C LYS A 314 18.456 2.045 -21.678 1.00 50.35 C ATOM 5222 O LYS A 314 18.429 2.850 -22.611 1.00 52.49 O ATOM 5223 CB LYS A 314 19.005 -0.351 -22.352 1.00 48.70 C ATOM 5224 CG LYS A 314 20.123 -1.322 -22.765 1.00 45.45 C ATOM 5225 CD LYS A 314 19.573 -2.655 -23.292 1.00 46.12 C ATOM 5226 CE LYS A 314 20.685 -3.635 -23.697 1.00 44.48 C ATOM 5227 NZ LYS A 314 20.132 -4.895 -24.224 1.00 42.62 N1+ ATOM 5228 H LYS A 314 19.657 -0.190 -19.903 1.00 50.04 H ATOM 5229 HA LYS A 314 20.364 1.303 -22.286 1.00 49.87 H ATOM 5230 HB3 LYS A 314 18.452 -0.093 -23.253 1.00 48.70 H ATOM 5231 HB2 LYS A 314 18.293 -0.851 -21.698 1.00 48.70 H ATOM 5232 HG3 LYS A 314 20.789 -1.505 -21.924 1.00 45.45 H ATOM 5233 HG2 LYS A 314 20.736 -0.854 -23.536 1.00 45.45 H ATOM 5234 HD3 LYS A 314 18.930 -2.458 -24.150 1.00 46.12 H ATOM 5235 HD2 LYS A 314 18.938 -3.108 -22.528 1.00 46.12 H ATOM 5236 HE3 LYS A 314 21.320 -3.863 -22.840 1.00 44.48 H ATOM 5237 HE2 LYS A 314 21.320 -3.186 -24.462 1.00 44.48 H ATOM 5238 HZ1 LYS A 314 19.594 -5.345 -23.494 1.00 42.62 H ATOM 5239 HZ2 LYS A 314 19.533 -4.704 -25.015 1.00 42.62 H ATOM 5240 HZ3 LYS A 314 20.885 -5.506 -24.507 1.00 42.62 H ATOM 5241 N LEU A 315 17.623 2.096 -20.620 1.00 48.29 N ATOM 5242 CA LEU A 315 16.641 3.162 -20.385 1.00 47.39 C ATOM 5243 C LEU A 315 17.319 4.494 -19.997 1.00 46.64 C ATOM 5244 O LEU A 315 16.853 5.546 -20.434 1.00 44.68 O ATOM 5245 CB LEU A 315 15.625 2.734 -19.295 1.00 45.51 C ATOM 5246 CG LEU A 315 14.764 1.479 -19.596 1.00 49.20 C ATOM 5247 CD1 LEU A 315 14.103 0.921 -18.321 1.00 44.11 C ATOM 5248 CD2 LEU A 315 13.719 1.709 -20.696 1.00 42.67 C ATOM 5249 H LEU A 315 17.690 1.386 -19.903 1.00 48.29 H ATOM 5250 HA LEU A 315 16.104 3.342 -21.315 1.00 47.39 H ATOM 5251 HB3 LEU A 315 14.950 3.565 -19.086 1.00 45.51 H ATOM 5252 HB2 LEU A 315 16.176 2.561 -18.370 1.00 45.51 H ATOM 5253 HG LEU A 315 15.422 0.705 -19.979 1.00 49.20 H ATOM 5254 HD11 LEU A 315 13.057 0.654 -18.476 1.00 44.11 H ATOM 5255 HD12 LEU A 315 14.617 0.023 -17.983 1.00 44.11 H ATOM 5256 HD13 LEU A 315 14.132 1.632 -17.498 1.00 44.11 H ATOM 5257 HD21 LEU A 315 13.477 0.773 -21.201 1.00 42.67 H ATOM 5258 HD22 LEU A 315 12.790 2.121 -20.299 1.00 42.67 H ATOM 5259 HD23 LEU A 315 14.085 2.390 -21.456 1.00 42.67 H ATOM 5260 N LEU A 316 18.416 4.417 -19.221 1.00 46.35 N ATOM 5261 CA LEU A 316 19.231 5.551 -18.778 1.00 46.61 C ATOM 5262 C LEU A 316 20.531 5.661 -19.601 1.00 48.67 C ATOM 5263 O LEU A 316 21.610 5.797 -19.028 1.00 53.10 O ATOM 5264 CB LEU A 316 19.515 5.440 -17.256 1.00 46.32 C ATOM 5265 CG LEU A 316 18.278 5.577 -16.343 1.00 44.15 C ATOM 5266 CD1 LEU A 316 18.685 5.445 -14.866 1.00 45.10 C ATOM 5267 CD2 LEU A 316 17.513 6.892 -16.572 1.00 43.94 C ATOM 5268 H LEU A 316 18.721 3.510 -18.893 1.00 46.35 H ATOM 5269 HA LEU A 316 18.694 6.482 -18.960 1.00 46.61 H ATOM 5270 HB3 LEU A 316 20.216 6.223 -16.960 1.00 46.32 H ATOM 5271 HB2 LEU A 316 20.020 4.495 -17.051 1.00 46.32 H ATOM 5272 HG LEU A 316 17.604 4.748 -16.563 1.00 44.15 H ATOM 5273 HD11 LEU A 316 17.827 5.193 -14.244 1.00 45.10 H ATOM 5274 HD12 LEU A 316 19.439 4.670 -14.721 1.00 45.10 H ATOM 5275 HD13 LEU A 316 19.097 6.379 -14.484 1.00 45.10 H ATOM 5276 HD21 LEU A 316 17.058 7.261 -15.653 1.00 43.94 H ATOM 5277 HD22 LEU A 316 18.169 7.679 -16.942 1.00 43.94 H ATOM 5278 HD23 LEU A 316 16.714 6.756 -17.300 1.00 43.94 H ATOM 5279 N THR A 317 20.411 5.642 -20.939 1.00 47.73 N ATOM 5280 CA THR A 317 21.512 5.977 -21.850 1.00 47.25 C ATOM 5281 C THR A 317 21.575 7.508 -22.019 1.00 46.98 C ATOM 5282 O THR A 317 20.525 8.121 -22.202 1.00 45.81 O ATOM 5283 CB THR A 317 21.286 5.345 -23.246 1.00 48.27 C ATOM 5284 OG1 THR A 317 21.210 3.939 -23.111 1.00 50.27 O ATOM 5285 CG2 THR A 317 22.382 5.637 -24.284 1.00 46.88 C ATOM 5286 H THR A 317 19.499 5.522 -21.355 1.00 47.73 H ATOM 5287 HA THR A 317 22.459 5.612 -21.446 1.00 47.25 H ATOM 5288 HB THR A 317 20.332 5.690 -23.642 1.00 48.27 H ATOM 5289 HG1 THR A 317 20.497 3.732 -22.501 1.00 50.27 H ATOM 5290 HG21 THR A 317 22.207 5.077 -25.201 1.00 46.88 H ATOM 5291 HG22 THR A 317 22.421 6.691 -24.556 1.00 46.88 H ATOM 5292 HG23 THR A 317 23.365 5.352 -23.909 1.00 46.88 H ATOM 5293 N MET A 318 22.777 8.104 -21.932 1.00 47.85 N ATOM 5294 CA MET A 318 22.982 9.561 -21.966 1.00 48.95 C ATOM 5295 C MET A 318 22.601 10.224 -23.303 1.00 47.42 C ATOM 5296 O MET A 318 21.975 11.284 -23.283 1.00 46.76 O ATOM 5297 CB MET A 318 24.439 9.900 -21.581 1.00 51.20 C ATOM 5298 CG MET A 318 24.801 9.575 -20.119 1.00 56.41 C ATOM 5299 SD MET A 318 23.947 10.571 -18.861 1.00 63.20 S ATOM 5300 CE MET A 318 24.803 12.156 -19.060 1.00 56.26 C ATOM 5301 H MET A 318 23.605 7.542 -21.792 1.00 47.85 H ATOM 5302 HA MET A 318 22.323 9.996 -21.212 1.00 48.95 H ATOM 5303 HB3 MET A 318 24.628 10.958 -21.763 1.00 51.20 H ATOM 5304 HB2 MET A 318 25.126 9.370 -22.242 1.00 51.20 H ATOM 5305 HG3 MET A 318 25.874 9.703 -19.974 1.00 56.41 H ATOM 5306 HG2 MET A 318 24.594 8.526 -19.909 1.00 56.41 H ATOM 5307 HE1 MET A 318 24.368 12.906 -18.400 1.00 56.26 H ATOM 5308 HE2 MET A 318 25.856 12.045 -18.807 1.00 56.26 H ATOM 5309 HE3 MET A 318 24.724 12.521 -20.083 1.00 56.26 H ATOM 5310 N ASP A 319 22.957 9.580 -24.426 1.00 48.08 N ATOM 5311 CA ASP A 319 22.637 10.018 -25.785 1.00 48.37 C ATOM 5312 C ASP A 319 21.212 9.526 -26.141 1.00 46.80 C ATOM 5313 O ASP A 319 21.000 8.312 -26.127 1.00 47.05 O ATOM 5314 CB ASP A 319 23.695 9.441 -26.764 1.00 49.38 C ATOM 5315 CG ASP A 319 23.628 9.884 -28.237 1.00 48.19 C ATOM 5316 OD1 ASP A 319 22.883 10.836 -28.557 1.00 45.89 O ATOM 5317 OD2 ASP A 319 24.412 9.312 -29.024 1.00 47.50 O1- ATOM 5318 H ASP A 319 23.480 8.717 -24.354 1.00 48.08 H ATOM 5319 HA ASP A 319 22.726 11.102 -25.802 1.00 48.37 H ATOM 5320 HB3 ASP A 319 23.687 8.352 -26.718 1.00 49.38 H ATOM 5321 HB2 ASP A 319 24.678 9.721 -26.392 1.00 49.38 H ATOM 5322 N PRO A 320 20.258 10.442 -26.441 1.00 47.89 N ATOM 5323 CA PRO A 320 18.862 10.055 -26.728 1.00 48.04 C ATOM 5324 C PRO A 320 18.621 9.189 -27.979 1.00 48.64 C ATOM 5325 O PRO A 320 17.633 8.455 -27.980 1.00 48.94 O ATOM 5326 CB PRO A 320 18.109 11.390 -26.812 1.00 47.83 C ATOM 5327 CG PRO A 320 19.168 12.413 -27.179 1.00 47.06 C ATOM 5328 CD PRO A 320 20.402 11.902 -26.449 1.00 48.19 C ATOM 5329 HA PRO A 320 18.475 9.494 -25.875 1.00 48.04 H ATOM 5330 HB3 PRO A 320 17.700 11.622 -25.832 1.00 47.83 H ATOM 5331 HB2 PRO A 320 17.274 11.386 -27.515 1.00 47.83 H ATOM 5332 HG3 PRO A 320 18.900 13.435 -26.909 1.00 47.06 H ATOM 5333 HG2 PRO A 320 19.344 12.383 -28.255 1.00 47.06 H ATOM 5334 HD2 PRO A 320 21.302 12.263 -26.945 1.00 48.19 H ATOM 5335 HD3 PRO A 320 20.416 12.259 -25.418 1.00 48.19 H ATOM 5336 N ILE A 321 19.498 9.253 -29.000 1.00 49.64 N ATOM 5337 CA ILE A 321 19.373 8.414 -30.203 1.00 49.92 C ATOM 5338 C ILE A 321 19.879 6.967 -30.004 1.00 49.62 C ATOM 5339 O ILE A 321 19.450 6.086 -30.748 1.00 51.30 O ATOM 5340 CB ILE A 321 20.058 9.028 -31.458 1.00 51.44 C ATOM 5341 CG1 ILE A 321 21.593 9.196 -31.370 1.00 52.78 C ATOM 5342 CG2 ILE A 321 19.381 10.349 -31.867 1.00 51.99 C ATOM 5343 CD1 ILE A 321 22.287 9.329 -32.733 1.00 56.13 C ATOM 5344 H ILE A 321 20.295 9.874 -28.957 1.00 49.64 H ATOM 5345 HA ILE A 321 18.311 8.329 -30.441 1.00 49.92 H ATOM 5346 HB ILE A 321 19.870 8.332 -32.278 1.00 51.44 H ATOM 5347 HG13 ILE A 321 22.057 8.366 -30.840 1.00 52.78 H ATOM 5348 HG12 ILE A 321 21.813 10.085 -30.785 1.00 52.78 H ATOM 5349 HG21 ILE A 321 19.767 10.718 -32.818 1.00 51.99 H ATOM 5350 HG22 ILE A 321 18.305 10.220 -31.983 1.00 51.99 H ATOM 5351 HG23 ILE A 321 19.543 11.128 -31.121 1.00 51.99 H ATOM 5352 HD11 ILE A 321 23.355 9.128 -32.641 1.00 56.13 H ATOM 5353 HD12 ILE A 321 21.881 8.629 -33.464 1.00 56.13 H ATOM 5354 HD13 ILE A 321 22.178 10.337 -33.134 1.00 56.13 H ATOM 5355 N LYS A 322 20.738 6.741 -28.994 1.00 47.58 N ATOM 5356 CA LYS A 322 21.223 5.416 -28.592 1.00 47.09 C ATOM 5357 C LYS A 322 20.356 4.767 -27.501 1.00 45.74 C ATOM 5358 O LYS A 322 20.522 3.575 -27.246 1.00 45.16 O ATOM 5359 CB LYS A 322 22.686 5.531 -28.127 1.00 47.98 C ATOM 5360 CG LYS A 322 23.639 5.848 -29.284 1.00 49.12 C ATOM 5361 CD LYS A 322 25.102 5.929 -28.844 1.00 52.89 C ATOM 5362 CE LYS A 322 26.016 6.298 -30.020 1.00 53.21 C ATOM 5363 NZ LYS A 322 27.418 6.402 -29.599 1.00 57.96 N1+ ATOM 5364 H LYS A 322 21.045 7.517 -28.423 1.00 47.58 H ATOM 5365 HA LYS A 322 21.196 4.744 -29.452 1.00 47.09 H ATOM 5366 HB3 LYS A 322 23.006 4.589 -27.679 1.00 47.98 H ATOM 5367 HB2 LYS A 322 22.773 6.285 -27.344 1.00 47.98 H ATOM 5368 HG3 LYS A 322 23.354 6.792 -29.746 1.00 49.12 H ATOM 5369 HG2 LYS A 322 23.536 5.087 -30.059 1.00 49.12 H ATOM 5370 HD3 LYS A 322 25.405 4.971 -28.418 1.00 52.89 H ATOM 5371 HD2 LYS A 322 25.197 6.666 -28.045 1.00 52.89 H ATOM 5372 HE3 LYS A 322 25.714 7.252 -30.453 1.00 53.21 H ATOM 5373 HE2 LYS A 322 25.941 5.549 -30.809 1.00 53.21 H ATOM 5374 HZ1 LYS A 322 27.732 5.519 -29.225 1.00 57.96 H ATOM 5375 HZ2 LYS A 322 27.996 6.659 -30.387 1.00 57.96 H ATOM 5376 HZ3 LYS A 322 27.503 7.115 -28.887 1.00 57.96 H ATOM 5377 N ARG A 323 19.453 5.548 -26.885 1.00 46.29 N ATOM 5378 CA ARG A 323 18.494 5.103 -25.878 1.00 44.44 C ATOM 5379 C ARG A 323 17.449 4.160 -26.494 1.00 45.15 C ATOM 5380 O ARG A 323 16.982 4.414 -27.606 1.00 43.77 O ATOM 5381 CB ARG A 323 17.862 6.364 -25.256 1.00 45.36 C ATOM 5382 CG ARG A 323 17.117 6.157 -23.921 1.00 44.17 C ATOM 5383 CD ARG A 323 16.545 7.473 -23.350 1.00 47.80 C ATOM 5384 NE ARG A 323 17.611 8.438 -23.004 1.00 46.04 N ATOM 5385 CZ ARG A 323 17.601 9.782 -23.098 1.00 44.53 C ATOM 5386 NH1 ARG A 323 16.512 10.473 -23.449 1.00 41.82 N ATOM 5387 NH2 ARG A 323 18.721 10.464 -22.843 1.00 47.51 N1+ ATOM 5388 H ARG A 323 19.384 6.518 -27.158 1.00 46.29 H ATOM 5389 HA ARG A 323 19.048 4.562 -25.111 1.00 44.44 H ATOM 5390 HB3 ARG A 323 17.188 6.832 -25.974 1.00 45.36 H ATOM 5391 HB2 ARG A 323 18.663 7.086 -25.090 1.00 45.36 H ATOM 5392 HG3 ARG A 323 17.817 5.729 -23.201 1.00 44.17 H ATOM 5393 HG2 ARG A 323 16.316 5.425 -24.021 1.00 44.17 H ATOM 5394 HD3 ARG A 323 15.902 7.281 -22.492 1.00 47.80 H ATOM 5395 HD2 ARG A 323 15.913 7.916 -24.118 1.00 47.80 H ATOM 5396 HE ARG A 323 18.480 8.018 -22.700 1.00 46.04 H ATOM 5397 HH12 ARG A 323 16.555 11.480 -23.565 1.00 41.82 H ATOM 5398 HH11 ARG A 323 15.636 9.992 -23.604 1.00 41.82 H ATOM 5399 HH22 ARG A 323 18.746 11.472 -22.955 1.00 47.51 H ATOM 5400 HH21 ARG A 323 19.569 9.974 -22.587 1.00 47.51 H ATOM 5401 N ILE A 324 17.111 3.091 -25.757 1.00 45.91 N ATOM 5402 CA ILE A 324 16.128 2.074 -26.146 1.00 46.05 C ATOM 5403 C ILE A 324 14.714 2.677 -26.323 1.00 45.46 C ATOM 5404 O ILE A 324 14.409 3.699 -25.709 1.00 42.55 O ATOM 5405 CB ILE A 324 16.101 0.952 -25.062 1.00 47.35 C ATOM 5406 CG1 ILE A 324 15.479 -0.368 -25.563 1.00 51.84 C ATOM 5407 CG2 ILE A 324 15.458 1.380 -23.725 1.00 53.59 C ATOM 5408 CD1 ILE A 324 15.742 -1.571 -24.647 1.00 56.10 C ATOM 5409 H ILE A 324 17.547 2.955 -24.856 1.00 45.91 H ATOM 5410 HA ILE A 324 16.449 1.651 -27.100 1.00 46.05 H ATOM 5411 HB ILE A 324 17.147 0.735 -24.850 1.00 47.35 H ATOM 5412 HG13 ILE A 324 15.858 -0.599 -26.559 1.00 51.84 H ATOM 5413 HG12 ILE A 324 14.404 -0.251 -25.666 1.00 51.84 H ATOM 5414 HG21 ILE A 324 15.684 0.670 -22.929 1.00 53.59 H ATOM 5415 HG22 ILE A 324 15.829 2.353 -23.404 1.00 53.59 H ATOM 5416 HG23 ILE A 324 14.373 1.451 -23.801 1.00 53.59 H ATOM 5417 HD11 ILE A 324 15.553 -2.505 -25.176 1.00 56.10 H ATOM 5418 HD12 ILE A 324 16.772 -1.591 -24.295 1.00 56.10 H ATOM 5419 HD13 ILE A 324 15.092 -1.553 -23.773 1.00 56.10 H ATOM 5420 N THR A 325 13.882 2.046 -27.163 1.00 44.32 N ATOM 5421 CA THR A 325 12.473 2.412 -27.331 1.00 44.97 C ATOM 5422 C THR A 325 11.586 1.613 -26.350 1.00 45.37 C ATOM 5423 O THR A 325 12.034 0.613 -25.785 1.00 43.60 O ATOM 5424 CB THR A 325 12.002 2.131 -28.782 1.00 45.35 C ATOM 5425 OG1 THR A 325 11.887 0.753 -29.071 1.00 47.75 O ATOM 5426 CG2 THR A 325 12.865 2.805 -29.859 1.00 46.52 C ATOM 5427 H THR A 325 14.191 1.226 -27.668 1.00 44.32 H ATOM 5428 HA THR A 325 12.331 3.475 -27.129 1.00 44.97 H ATOM 5429 HB THR A 325 10.998 2.541 -28.889 1.00 45.35 H ATOM 5430 HG1 THR A 325 11.549 0.669 -29.968 1.00 47.75 H ATOM 5431 HG21 THR A 325 12.441 2.652 -30.852 1.00 46.52 H ATOM 5432 HG22 THR A 325 12.930 3.880 -29.690 1.00 46.52 H ATOM 5433 HG23 THR A 325 13.881 2.408 -29.871 1.00 46.52 H ATOM 5434 N SER A 326 10.334 2.066 -26.167 1.00 46.21 N ATOM 5435 CA SER A 326 9.341 1.408 -25.309 1.00 48.15 C ATOM 5436 C SER A 326 8.998 -0.032 -25.740 1.00 47.95 C ATOM 5437 O SER A 326 8.883 -0.894 -24.870 1.00 49.58 O ATOM 5438 CB SER A 326 8.087 2.296 -25.165 1.00 46.61 C ATOM 5439 OG SER A 326 7.376 2.418 -26.379 1.00 51.24 O ATOM 5440 H SER A 326 10.022 2.891 -26.664 1.00 46.21 H ATOM 5441 HA SER A 326 9.800 1.341 -24.322 1.00 48.15 H ATOM 5442 HB3 SER A 326 8.342 3.289 -24.802 1.00 46.61 H ATOM 5443 HB2 SER A 326 7.412 1.867 -24.423 1.00 46.61 H ATOM 5444 HG SER A 326 7.918 2.904 -27.008 1.00 51.24 H ATOM 5445 N GLU A 327 8.889 -0.273 -27.059 1.00 48.30 N ATOM 5446 CA GLU A 327 8.622 -1.586 -27.639 1.00 49.29 C ATOM 5447 C GLU A 327 9.814 -2.554 -27.518 1.00 47.25 C ATOM 5448 O GLU A 327 9.584 -3.717 -27.197 1.00 47.66 O ATOM 5449 CB GLU A 327 8.080 -1.466 -29.085 1.00 50.19 C ATOM 5450 CG GLU A 327 8.978 -0.808 -30.166 1.00 57.27 C ATOM 5451 CD GLU A 327 8.929 0.727 -30.309 1.00 63.43 C ATOM 5452 OE1 GLU A 327 8.286 1.415 -29.484 1.00 59.89 O ATOM 5453 OE2 GLU A 327 9.588 1.208 -31.257 1.00 67.48 O1- ATOM 5454 H GLU A 327 8.960 0.493 -27.718 1.00 48.30 H ATOM 5455 HA GLU A 327 7.812 -2.025 -27.051 1.00 49.29 H ATOM 5456 HB3 GLU A 327 7.112 -0.974 -29.055 1.00 50.19 H ATOM 5457 HB2 GLU A 327 7.849 -2.475 -29.430 1.00 50.19 H ATOM 5458 HG3 GLU A 327 8.673 -1.214 -31.131 1.00 57.27 H ATOM 5459 HG2 GLU A 327 10.015 -1.119 -30.043 1.00 57.27 H ATOM 5460 N GLN A 328 11.053 -2.064 -27.712 1.00 47.51 N ATOM 5461 CA GLN A 328 12.291 -2.831 -27.510 1.00 48.87 C ATOM 5462 C GLN A 328 12.513 -3.261 -26.050 1.00 49.46 C ATOM 5463 O GLN A 328 13.017 -4.360 -25.816 1.00 50.93 O ATOM 5464 CB GLN A 328 13.502 -2.018 -28.003 1.00 50.16 C ATOM 5465 CG GLN A 328 13.651 -1.969 -29.534 1.00 52.69 C ATOM 5466 CD GLN A 328 14.810 -1.066 -29.973 1.00 58.57 C ATOM 5467 OE1 GLN A 328 15.134 -0.079 -29.315 1.00 58.33 O ATOM 5468 NE2 GLN A 328 15.429 -1.391 -31.109 1.00 63.85 N ATOM 5469 H GLN A 328 11.169 -1.092 -27.966 1.00 47.51 H ATOM 5470 HA GLN A 328 12.219 -3.743 -28.106 1.00 48.87 H ATOM 5471 HB3 GLN A 328 14.423 -2.435 -27.590 1.00 50.16 H ATOM 5472 HB2 GLN A 328 13.425 -1.007 -27.604 1.00 50.16 H ATOM 5473 HG3 GLN A 328 12.735 -1.602 -29.997 1.00 52.69 H ATOM 5474 HG2 GLN A 328 13.809 -2.978 -29.917 1.00 52.69 H ATOM 5475 HE22 GLN A 328 16.191 -0.821 -31.447 1.00 63.85 H ATOM 5476 HE21 GLN A 328 15.140 -2.201 -31.639 1.00 63.85 H ATOM 5477 N ALA A 329 12.112 -2.394 -25.105 1.00 47.62 N ATOM 5478 CA ALA A 329 12.153 -2.654 -23.671 1.00 47.39 C ATOM 5479 C ALA A 329 11.151 -3.734 -23.227 1.00 47.39 C ATOM 5480 O ALA A 329 11.486 -4.500 -22.330 1.00 46.84 O ATOM 5481 CB ALA A 329 11.942 -1.337 -22.914 1.00 43.92 C ATOM 5482 H ALA A 329 11.731 -1.499 -25.385 1.00 47.62 H ATOM 5483 HA ALA A 329 13.153 -3.018 -23.430 1.00 47.39 H ATOM 5484 HB1 ALA A 329 12.018 -1.482 -21.836 1.00 43.92 H ATOM 5485 HB2 ALA A 329 12.694 -0.599 -23.196 1.00 43.92 H ATOM 5486 HB3 ALA A 329 10.963 -0.907 -23.129 1.00 43.92 H ATOM 5487 N MET A 330 9.978 -3.824 -23.882 1.00 46.45 N ATOM 5488 CA MET A 330 8.986 -4.884 -23.656 1.00 48.43 C ATOM 5489 C MET A 330 9.438 -6.268 -24.161 1.00 49.64 C ATOM 5490 O MET A 330 9.015 -7.266 -23.578 1.00 50.50 O ATOM 5491 CB MET A 330 7.639 -4.497 -24.298 1.00 48.63 C ATOM 5492 CG MET A 330 6.937 -3.330 -23.592 1.00 51.22 C ATOM 5493 SD MET A 330 5.570 -2.597 -24.529 1.00 55.41 S ATOM 5494 CE MET A 330 4.367 -3.950 -24.451 1.00 56.02 C ATOM 5495 H MET A 330 9.763 -3.157 -24.612 1.00 46.45 H ATOM 5496 HA MET A 330 8.830 -4.976 -22.579 1.00 48.43 H ATOM 5497 HB3 MET A 330 6.970 -5.358 -24.273 1.00 48.63 H ATOM 5498 HB2 MET A 330 7.778 -4.259 -25.352 1.00 48.63 H ATOM 5499 HG3 MET A 330 7.657 -2.541 -23.395 1.00 51.22 H ATOM 5500 HG2 MET A 330 6.564 -3.648 -22.617 1.00 51.22 H ATOM 5501 HE1 MET A 330 3.451 -3.662 -24.964 1.00 56.02 H ATOM 5502 HE2 MET A 330 4.757 -4.846 -24.934 1.00 56.02 H ATOM 5503 HE3 MET A 330 4.124 -4.189 -23.415 1.00 56.02 H ATOM 5504 N GLN A 331 10.290 -6.308 -25.202 1.00 49.38 N ATOM 5505 CA GLN A 331 10.880 -7.537 -25.753 1.00 48.68 C ATOM 5506 C GLN A 331 12.125 -8.027 -24.983 1.00 46.61 C ATOM 5507 O GLN A 331 12.644 -9.091 -25.320 1.00 44.51 O ATOM 5508 CB GLN A 331 11.225 -7.330 -27.250 1.00 49.53 C ATOM 5509 CG GLN A 331 10.043 -7.011 -28.192 1.00 53.82 C ATOM 5510 CD GLN A 331 8.836 -7.937 -28.034 1.00 57.74 C ATOM 5511 OE1 GLN A 331 8.959 -9.152 -28.162 1.00 63.98 O ATOM 5512 NE2 GLN A 331 7.660 -7.362 -27.770 1.00 65.89 N ATOM 5513 H GLN A 331 10.586 -5.443 -25.632 1.00 49.38 H ATOM 5514 HA GLN A 331 10.151 -8.344 -25.669 1.00 48.68 H ATOM 5515 HB3 GLN A 331 11.711 -8.229 -27.631 1.00 49.53 H ATOM 5516 HB2 GLN A 331 11.967 -6.536 -27.347 1.00 49.53 H ATOM 5517 HG3 GLN A 331 10.381 -7.059 -29.228 1.00 53.82 H ATOM 5518 HG2 GLN A 331 9.719 -5.987 -28.037 1.00 53.82 H ATOM 5519 HE22 GLN A 331 6.833 -7.932 -27.663 1.00 65.89 H ATOM 5520 HE21 GLN A 331 7.590 -6.359 -27.676 1.00 65.89 H ATOM 5521 N ASP A 332 12.582 -7.262 -23.975 1.00 45.92 N ATOM 5522 CA ASP A 332 13.758 -7.546 -23.149 1.00 45.71 C ATOM 5523 C ASP A 332 13.563 -8.858 -22.341 1.00 46.65 C ATOM 5524 O ASP A 332 12.483 -9.040 -21.773 1.00 46.85 O ATOM 5525 CB ASP A 332 14.010 -6.342 -22.207 1.00 45.86 C ATOM 5526 CG ASP A 332 15.413 -6.296 -21.596 1.00 45.05 C ATOM 5527 OD1 ASP A 332 16.298 -5.698 -22.247 1.00 43.71 O ATOM 5528 OD2 ASP A 332 15.628 -6.989 -20.580 1.00 46.92 O1- ATOM 5529 H ASP A 332 12.092 -6.407 -23.754 1.00 45.92 H ATOM 5530 HA ASP A 332 14.588 -7.628 -23.850 1.00 45.71 H ATOM 5531 HB3 ASP A 332 13.265 -6.321 -21.409 1.00 45.86 H ATOM 5532 HB2 ASP A 332 13.853 -5.414 -22.759 1.00 45.86 H ATOM 5533 N PRO A 333 14.589 -9.747 -22.295 1.00 45.62 N ATOM 5534 CA PRO A 333 14.503 -11.042 -21.581 1.00 46.71 C ATOM 5535 C PRO A 333 14.367 -10.981 -20.043 1.00 47.99 C ATOM 5536 O PRO A 333 14.182 -12.036 -19.436 1.00 49.03 O ATOM 5537 CB PRO A 333 15.773 -11.789 -22.020 1.00 47.14 C ATOM 5538 CG PRO A 333 16.768 -10.687 -22.332 1.00 46.47 C ATOM 5539 CD PRO A 333 15.889 -9.614 -22.960 1.00 46.04 C ATOM 5540 HA PRO A 333 13.632 -11.588 -21.947 1.00 46.71 H ATOM 5541 HB3 PRO A 333 15.561 -12.359 -22.926 1.00 47.14 H ATOM 5542 HB2 PRO A 333 16.156 -12.493 -21.280 1.00 47.14 H ATOM 5543 HG3 PRO A 333 17.587 -11.008 -22.977 1.00 46.47 H ATOM 5544 HG2 PRO A 333 17.198 -10.310 -21.403 1.00 46.47 H ATOM 5545 HD2 PRO A 333 16.350 -8.635 -22.843 1.00 46.04 H ATOM 5546 HD3 PRO A 333 15.756 -9.803 -24.026 1.00 46.04 H ATOM 5547 N TYR A 334 14.404 -9.776 -19.445 1.00 47.35 N ATOM 5548 CA TYR A 334 13.994 -9.498 -18.064 1.00 47.78 C ATOM 5549 C TYR A 334 12.524 -9.879 -17.792 1.00 48.93 C ATOM 5550 O TYR A 334 12.230 -10.396 -16.717 1.00 50.44 O ATOM 5551 CB TYR A 334 14.250 -8.002 -17.769 1.00 48.29 C ATOM 5552 CG TYR A 334 13.765 -7.468 -16.430 1.00 49.53 C ATOM 5553 CD1 TYR A 334 14.322 -7.951 -15.229 1.00 55.46 C ATOM 5554 CD2 TYR A 334 12.764 -6.474 -16.383 1.00 54.76 C ATOM 5555 CE1 TYR A 334 13.888 -7.437 -13.992 1.00 53.39 C ATOM 5556 CE2 TYR A 334 12.342 -5.948 -15.147 1.00 56.10 C ATOM 5557 CZ TYR A 334 12.904 -6.429 -13.950 1.00 56.50 C ATOM 5558 OH TYR A 334 12.484 -5.930 -12.752 1.00 53.45 O ATOM 5559 H TYR A 334 14.611 -8.958 -20.004 1.00 47.35 H ATOM 5560 HA TYR A 334 14.625 -10.097 -17.405 1.00 47.78 H ATOM 5561 HB3 TYR A 334 13.773 -7.409 -18.550 1.00 48.29 H ATOM 5562 HB2 TYR A 334 15.315 -7.787 -17.846 1.00 48.29 H ATOM 5563 HD1 TYR A 334 15.083 -8.718 -15.252 1.00 55.46 H ATOM 5564 HD2 TYR A 334 12.317 -6.106 -17.295 1.00 54.76 H ATOM 5565 HE1 TYR A 334 14.307 -7.829 -13.077 1.00 53.39 H ATOM 5566 HE2 TYR A 334 11.579 -5.185 -15.121 1.00 56.10 H ATOM 5567 HH TYR A 334 12.934 -6.324 -12.001 1.00 53.45 H ATOM 5568 N PHE A 335 11.643 -9.643 -18.779 1.00 48.67 N ATOM 5569 CA PHE A 335 10.218 -9.972 -18.710 1.00 48.60 C ATOM 5570 C PHE A 335 9.898 -11.445 -19.015 1.00 49.78 C ATOM 5571 O PHE A 335 8.808 -11.890 -18.662 1.00 50.13 O ATOM 5572 CB PHE A 335 9.424 -9.005 -19.609 1.00 49.20 C ATOM 5573 CG PHE A 335 9.496 -7.559 -19.150 1.00 47.56 C ATOM 5574 CD1 PHE A 335 9.015 -7.206 -17.872 1.00 45.51 C ATOM 5575 CD2 PHE A 335 10.077 -6.564 -19.966 1.00 48.18 C ATOM 5576 CE1 PHE A 335 9.125 -5.897 -17.428 1.00 46.52 C ATOM 5577 CE2 PHE A 335 10.144 -5.254 -19.507 1.00 48.95 C ATOM 5578 CZ PHE A 335 9.668 -4.924 -18.249 1.00 47.14 C ATOM 5579 H PHE A 335 11.960 -9.222 -19.642 1.00 48.67 H ATOM 5580 HA PHE A 335 9.884 -9.818 -17.684 1.00 48.60 H ATOM 5581 HB3 PHE A 335 8.373 -9.294 -19.639 1.00 49.20 H ATOM 5582 HB2 PHE A 335 9.785 -9.069 -20.636 1.00 49.20 H ATOM 5583 HD1 PHE A 335 8.572 -7.953 -17.232 1.00 45.51 H ATOM 5584 HD2 PHE A 335 10.462 -6.810 -20.945 1.00 48.18 H ATOM 5585 HE1 PHE A 335 8.779 -5.629 -16.445 1.00 46.52 H ATOM 5586 HE2 PHE A 335 10.570 -4.474 -20.116 1.00 48.95 H ATOM 5587 HZ PHE A 335 9.722 -3.905 -17.907 1.00 47.14 H ATOM 5588 N LEU A 336 10.849 -12.180 -19.617 1.00 50.12 N ATOM 5589 CA LEU A 336 10.766 -13.627 -19.840 1.00 52.19 C ATOM 5590 C LEU A 336 11.305 -14.431 -18.641 1.00 53.17 C ATOM 5591 O LEU A 336 10.947 -15.599 -18.499 1.00 54.12 O ATOM 5592 CB LEU A 336 11.549 -13.998 -21.119 1.00 51.38 C ATOM 5593 CG LEU A 336 11.021 -13.338 -22.412 1.00 53.03 C ATOM 5594 CD1 LEU A 336 11.946 -13.637 -23.610 1.00 51.66 C ATOM 5595 CD2 LEU A 336 9.548 -13.698 -22.705 1.00 48.01 C ATOM 5596 H LEU A 336 11.720 -11.740 -19.880 1.00 50.12 H ATOM 5597 HA LEU A 336 9.721 -13.914 -19.967 1.00 52.19 H ATOM 5598 HB3 LEU A 336 11.536 -15.082 -21.253 1.00 51.38 H ATOM 5599 HB2 LEU A 336 12.597 -13.729 -20.982 1.00 51.38 H ATOM 5600 HG LEU A 336 11.066 -12.259 -22.265 1.00 53.03 H ATOM 5601 HD11 LEU A 336 12.243 -12.713 -24.107 1.00 51.66 H ATOM 5602 HD12 LEU A 336 12.862 -14.144 -23.303 1.00 51.66 H ATOM 5603 HD13 LEU A 336 11.472 -14.272 -24.359 1.00 51.66 H ATOM 5604 HD21 LEU A 336 9.366 -13.894 -23.761 1.00 48.01 H ATOM 5605 HD22 LEU A 336 9.226 -14.582 -22.155 1.00 48.01 H ATOM 5606 HD23 LEU A 336 8.891 -12.877 -22.418 1.00 48.01 H ATOM 5607 N GLU A 337 12.144 -13.796 -17.805 1.00 52.87 N ATOM 5608 CA GLU A 337 12.712 -14.360 -16.584 1.00 53.06 C ATOM 5609 C GLU A 337 11.656 -14.452 -15.464 1.00 53.51 C ATOM 5610 O GLU A 337 10.759 -13.611 -15.399 1.00 52.97 O ATOM 5611 CB GLU A 337 13.927 -13.490 -16.193 1.00 53.27 C ATOM 5612 CG GLU A 337 14.718 -13.967 -14.958 1.00 52.66 C ATOM 5613 CD GLU A 337 15.955 -13.102 -14.700 1.00 57.38 C ATOM 5614 OE1 GLU A 337 15.770 -11.914 -14.356 1.00 54.69 O ATOM 5615 OE2 GLU A 337 17.075 -13.636 -14.855 1.00 56.94 O1- ATOM 5616 H GLU A 337 12.385 -12.834 -17.996 1.00 52.87 H ATOM 5617 HA GLU A 337 13.069 -15.367 -16.809 1.00 53.06 H ATOM 5618 HB3 GLU A 337 13.592 -12.468 -16.024 1.00 53.27 H ATOM 5619 HB2 GLU A 337 14.606 -13.438 -17.045 1.00 53.27 H ATOM 5620 HG3 GLU A 337 15.007 -15.012 -15.084 1.00 52.66 H ATOM 5621 HG2 GLU A 337 14.094 -13.928 -14.066 1.00 52.66 H ATOM 5622 N ASP A 338 11.803 -15.468 -14.600 1.00 54.61 N ATOM 5623 CA ASP A 338 10.971 -15.717 -13.419 1.00 56.90 C ATOM 5624 C ASP A 338 11.267 -14.661 -12.320 1.00 55.92 C ATOM 5625 O ASP A 338 12.447 -14.427 -12.048 1.00 54.87 O ATOM 5626 CB ASP A 338 11.252 -17.156 -12.912 1.00 58.48 C ATOM 5627 CG ASP A 338 10.430 -17.592 -11.688 1.00 61.77 C ATOM 5628 OD1 ASP A 338 9.232 -17.892 -11.884 1.00 64.05 O ATOM 5629 OD2 ASP A 338 10.967 -17.487 -10.563 1.00 69.82 O1- ATOM 5630 H ASP A 338 12.572 -16.110 -14.727 1.00 54.61 H ATOM 5631 HA ASP A 338 9.936 -15.668 -13.754 1.00 56.90 H ATOM 5632 HB3 ASP A 338 12.316 -17.275 -12.700 1.00 58.48 H ATOM 5633 HB2 ASP A 338 11.054 -17.860 -13.722 1.00 58.48 H ATOM 5634 N PRO A 339 10.236 -14.061 -11.677 1.00 55.96 N ATOM 5635 CA PRO A 339 8.788 -14.225 -11.927 1.00 56.43 C ATOM 5636 C PRO A 339 8.304 -13.407 -13.136 1.00 57.44 C ATOM 5637 O PRO A 339 8.778 -12.292 -13.332 1.00 58.57 O ATOM 5638 CB PRO A 339 8.161 -13.702 -10.624 1.00 56.47 C ATOM 5639 CG PRO A 339 9.116 -12.620 -10.145 1.00 55.76 C ATOM 5640 CD PRO A 339 10.479 -13.175 -10.534 1.00 55.64 C ATOM 5641 HA PRO A 339 8.512 -15.270 -12.059 1.00 56.43 H ATOM 5642 HB3 PRO A 339 8.127 -14.511 -9.892 1.00 56.47 H ATOM 5643 HB2 PRO A 339 7.142 -13.332 -10.744 1.00 56.47 H ATOM 5644 HG3 PRO A 339 9.025 -12.393 -9.082 1.00 55.76 H ATOM 5645 HG2 PRO A 339 8.932 -11.700 -10.700 1.00 55.76 H ATOM 5646 HD2 PRO A 339 11.185 -12.375 -10.763 1.00 55.64 H ATOM 5647 HD3 PRO A 339 10.892 -13.769 -9.716 1.00 55.64 H ATOM 5648 N LEU A 340 7.357 -13.957 -13.911 1.00 57.54 N ATOM 5649 CA LEU A 340 6.715 -13.271 -15.041 1.00 58.24 C ATOM 5650 C LEU A 340 5.823 -12.094 -14.568 1.00 57.55 C ATOM 5651 O LEU A 340 5.222 -12.205 -13.498 1.00 57.48 O ATOM 5652 CB LEU A 340 5.853 -14.300 -15.810 1.00 58.67 C ATOM 5653 CG LEU A 340 6.654 -15.425 -16.504 1.00 63.50 C ATOM 5654 CD1 LEU A 340 5.709 -16.493 -17.095 1.00 62.94 C ATOM 5655 CD2 LEU A 340 7.631 -14.876 -17.562 1.00 64.69 C ATOM 5656 H LEU A 340 7.005 -14.878 -13.692 1.00 57.54 H ATOM 5657 HA LEU A 340 7.517 -12.904 -15.681 1.00 58.24 H ATOM 5658 HB3 LEU A 340 5.256 -13.785 -16.565 1.00 58.67 H ATOM 5659 HB2 LEU A 340 5.133 -14.742 -15.118 1.00 58.67 H ATOM 5660 HG LEU A 340 7.252 -15.931 -15.745 1.00 63.50 H ATOM 5661 HD11 LEU A 340 5.971 -17.486 -16.729 1.00 62.94 H ATOM 5662 HD12 LEU A 340 4.668 -16.315 -16.823 1.00 62.94 H ATOM 5663 HD13 LEU A 340 5.748 -16.527 -18.184 1.00 62.94 H ATOM 5664 HD21 LEU A 340 7.766 -15.558 -18.402 1.00 64.69 H ATOM 5665 HD22 LEU A 340 7.287 -13.926 -17.969 1.00 64.69 H ATOM 5666 HD23 LEU A 340 8.616 -14.711 -17.125 1.00 64.69 H ATOM 5667 N PRO A 341 5.733 -10.997 -15.363 1.00 56.24 N ATOM 5668 CA PRO A 341 4.854 -9.853 -15.046 1.00 55.12 C ATOM 5669 C PRO A 341 3.354 -10.213 -15.117 1.00 55.14 C ATOM 5670 O PRO A 341 2.925 -10.859 -16.073 1.00 55.58 O ATOM 5671 CB PRO A 341 5.251 -8.789 -16.083 1.00 55.15 C ATOM 5672 CG PRO A 341 5.761 -9.580 -17.275 1.00 55.95 C ATOM 5673 CD PRO A 341 6.441 -10.783 -16.628 1.00 55.97 C ATOM 5674 HA PRO A 341 5.090 -9.486 -14.047 1.00 55.12 H ATOM 5675 HB3 PRO A 341 6.057 -8.175 -15.679 1.00 55.15 H ATOM 5676 HB2 PRO A 341 4.439 -8.112 -16.353 1.00 55.15 H ATOM 5677 HG3 PRO A 341 6.420 -9.008 -17.928 1.00 55.95 H ATOM 5678 HG2 PRO A 341 4.914 -9.919 -17.873 1.00 55.95 H ATOM 5679 HD2 PRO A 341 6.403 -11.648 -17.291 1.00 55.97 H ATOM 5680 HD3 PRO A 341 7.487 -10.558 -16.412 1.00 55.97 H ATOM 5681 N THR A 342 2.606 -9.802 -14.083 1.00 53.18 N ATOM 5682 CA THR A 342 1.188 -10.108 -13.880 1.00 53.37 C ATOM 5683 C THR A 342 0.331 -8.827 -13.987 1.00 53.75 C ATOM 5684 O THR A 342 0.801 -7.739 -13.653 1.00 53.55 O ATOM 5685 CB THR A 342 0.981 -10.724 -12.466 1.00 53.50 C ATOM 5686 OG1 THR A 342 1.416 -9.859 -11.433 1.00 50.04 O ATOM 5687 CG2 THR A 342 1.705 -12.065 -12.281 1.00 53.86 C ATOM 5688 H THR A 342 3.037 -9.259 -13.345 1.00 53.18 H ATOM 5689 HA THR A 342 0.839 -10.823 -14.629 1.00 53.37 H ATOM 5690 HB THR A 342 -0.085 -10.897 -12.309 1.00 53.50 H ATOM 5691 HG1 THR A 342 0.796 -9.126 -11.360 1.00 50.04 H ATOM 5692 HG21 THR A 342 1.478 -12.500 -11.307 1.00 53.86 H ATOM 5693 HG22 THR A 342 1.401 -12.784 -13.042 1.00 53.86 H ATOM 5694 HG23 THR A 342 2.787 -11.951 -12.344 1.00 53.86 H ATOM 5695 N SER A 343 -0.922 -8.997 -14.452 1.00 53.63 N ATOM 5696 CA SER A 343 -1.912 -7.932 -14.684 1.00 54.96 C ATOM 5697 C SER A 343 -2.300 -7.145 -13.416 1.00 53.85 C ATOM 5698 O SER A 343 -2.466 -5.927 -13.483 1.00 53.85 O ATOM 5699 CB SER A 343 -3.171 -8.548 -15.326 1.00 53.80 C ATOM 5700 OG SER A 343 -2.914 -8.915 -16.666 1.00 60.51 O ATOM 5701 H SER A 343 -1.219 -9.922 -14.724 1.00 53.63 H ATOM 5702 HA SER A 343 -1.476 -7.215 -15.383 1.00 54.96 H ATOM 5703 HB3 SER A 343 -3.992 -7.829 -15.335 1.00 53.80 H ATOM 5704 HB2 SER A 343 -3.517 -9.419 -14.767 1.00 53.80 H ATOM 5705 HG SER A 343 -3.696 -9.340 -17.027 1.00 60.51 H ATOM 5706 N ASP A 344 -2.394 -7.865 -12.288 1.00 54.11 N ATOM 5707 CA ASP A 344 -2.515 -7.331 -10.937 1.00 53.72 C ATOM 5708 C ASP A 344 -1.088 -7.268 -10.380 1.00 53.55 C ATOM 5709 O ASP A 344 -0.514 -8.324 -10.122 1.00 52.96 O ATOM 5710 CB ASP A 344 -3.462 -8.245 -10.105 1.00 53.82 C ATOM 5711 CG ASP A 344 -3.674 -7.947 -8.607 1.00 53.52 C ATOM 5712 OD1 ASP A 344 -3.215 -6.900 -8.105 1.00 53.87 O ATOM 5713 OD2 ASP A 344 -4.363 -8.776 -7.975 1.00 59.82 O1- ATOM 5714 H ASP A 344 -2.247 -8.863 -12.340 1.00 54.11 H ATOM 5715 HA ASP A 344 -2.929 -6.322 -10.968 1.00 53.72 H ATOM 5716 HB3 ASP A 344 -3.132 -9.281 -10.199 1.00 53.82 H ATOM 5717 HB2 ASP A 344 -4.445 -8.227 -10.578 1.00 53.82 H ATOM 5718 N VAL A 345 -0.534 -6.053 -10.214 1.00 53.09 N ATOM 5719 CA VAL A 345 0.832 -5.849 -9.709 1.00 53.87 C ATOM 5720 C VAL A 345 1.023 -6.307 -8.245 1.00 55.86 C ATOM 5721 O VAL A 345 2.138 -6.678 -7.887 1.00 55.43 O ATOM 5722 CB VAL A 345 1.301 -4.370 -9.832 1.00 54.02 C ATOM 5723 CG1 VAL A 345 1.249 -3.875 -11.289 1.00 50.95 C ATOM 5724 CG2 VAL A 345 0.630 -3.380 -8.855 1.00 51.31 C ATOM 5725 H VAL A 345 -1.055 -5.220 -10.455 1.00 53.09 H ATOM 5726 HA VAL A 345 1.495 -6.462 -10.322 1.00 53.87 H ATOM 5727 HB VAL A 345 2.362 -4.354 -9.577 1.00 54.02 H ATOM 5728 HG11 VAL A 345 1.563 -2.838 -11.380 1.00 50.95 H ATOM 5729 HG12 VAL A 345 1.907 -4.458 -11.924 1.00 50.95 H ATOM 5730 HG13 VAL A 345 0.254 -3.950 -11.720 1.00 50.95 H ATOM 5731 HG21 VAL A 345 0.880 -2.348 -9.100 1.00 51.31 H ATOM 5732 HG22 VAL A 345 -0.455 -3.469 -8.867 1.00 51.31 H ATOM 5733 HG23 VAL A 345 0.956 -3.545 -7.829 1.00 51.31 H ATOM 5734 N PHE A 346 -0.066 -6.335 -7.455 1.00 58.67 N ATOM 5735 CA PHE A 346 -0.093 -6.861 -6.088 1.00 60.61 C ATOM 5736 C PHE A 346 -0.221 -8.403 -6.054 1.00 63.75 C ATOM 5737 O PHE A 346 -0.080 -8.976 -4.977 1.00 64.82 O ATOM 5738 CB PHE A 346 -1.259 -6.212 -5.309 1.00 60.39 C ATOM 5739 CG PHE A 346 -1.369 -4.696 -5.393 1.00 59.24 C ATOM 5740 CD1 PHE A 346 -0.282 -3.866 -5.044 1.00 59.29 C ATOM 5741 CD2 PHE A 346 -2.592 -4.098 -5.770 1.00 59.65 C ATOM 5742 CE1 PHE A 346 -0.419 -2.484 -5.098 1.00 56.31 C ATOM 5743 CE2 PHE A 346 -2.710 -2.715 -5.801 1.00 57.82 C ATOM 5744 CZ PHE A 346 -1.629 -1.912 -5.467 1.00 55.73 C ATOM 5745 H PHE A 346 -0.959 -6.041 -7.829 1.00 58.67 H ATOM 5746 HA PHE A 346 0.843 -6.596 -5.592 1.00 60.61 H ATOM 5747 HB3 PHE A 346 -1.189 -6.480 -4.254 1.00 60.39 H ATOM 5748 HB2 PHE A 346 -2.198 -6.639 -5.653 1.00 60.39 H ATOM 5749 HD1 PHE A 346 0.659 -4.301 -4.740 1.00 59.29 H ATOM 5750 HD2 PHE A 346 -3.444 -4.710 -6.029 1.00 59.65 H ATOM 5751 HE1 PHE A 346 0.413 -1.846 -4.846 1.00 56.31 H ATOM 5752 HE2 PHE A 346 -3.650 -2.262 -6.082 1.00 57.82 H ATOM 5753 HZ PHE A 346 -1.731 -0.836 -5.493 1.00 55.73 H ATOM 5754 N ALA A 347 -0.476 -9.047 -7.210 1.00 67.14 N ATOM 5755 CA ALA A 347 -0.483 -10.497 -7.452 1.00 69.64 C ATOM 5756 C ALA A 347 -1.408 -11.313 -6.525 1.00 71.99 C ATOM 5757 O ALA A 347 -1.027 -12.394 -6.074 1.00 73.10 O ATOM 5758 CB ALA A 347 0.963 -11.030 -7.454 1.00 69.85 C ATOM 5759 H ALA A 347 -0.599 -8.487 -8.044 1.00 67.14 H ATOM 5760 HA ALA A 347 -0.881 -10.627 -8.459 1.00 69.64 H ATOM 5761 HB1 ALA A 347 1.002 -12.076 -7.759 1.00 69.85 H ATOM 5762 HB2 ALA A 347 1.577 -10.471 -8.157 1.00 69.85 H ATOM 5763 HB3 ALA A 347 1.426 -10.952 -6.470 1.00 69.85 H ATOM 5764 N GLY A 348 -2.605 -10.773 -6.244 1.00 74.39 N ATOM 5765 CA GLY A 348 -3.617 -11.390 -5.384 1.00 75.29 C ATOM 5766 C GLY A 348 -3.330 -11.229 -3.878 1.00 76.25 C ATOM 5767 O GLY A 348 -4.192 -11.584 -3.076 1.00 76.54 O ATOM 5768 H GLY A 348 -2.859 -9.894 -6.678 1.00 74.39 H ATOM 5769 HA3 GLY A 348 -3.714 -12.451 -5.619 1.00 75.29 H ATOM 5770 HA2 GLY A 348 -4.581 -10.932 -5.608 1.00 75.29 H ATOM 5771 N CYS A 349 -2.161 -10.689 -3.486 1.00 77.34 N ATOM 5772 CA CYS A 349 -1.788 -10.413 -2.095 1.00 78.52 C ATOM 5773 C CYS A 349 -2.486 -9.131 -1.616 1.00 79.39 C ATOM 5774 O CYS A 349 -2.650 -8.203 -2.410 1.00 80.21 O ATOM 5775 CB CYS A 349 -0.265 -10.244 -1.925 1.00 78.11 C ATOM 5776 SG CYS A 349 0.622 -11.737 -2.451 1.00 78.54 S ATOM 5777 H CYS A 349 -1.492 -10.399 -4.186 1.00 77.34 H ATOM 5778 HA CYS A 349 -2.114 -11.249 -1.472 1.00 78.52 H ATOM 5779 HB3 CYS A 349 -0.017 -10.055 -0.880 1.00 78.11 H ATOM 5780 HB2 CYS A 349 0.106 -9.389 -2.488 1.00 78.11 H ATOM 5781 HG CYS A 349 0.315 -11.637 -3.747 1.00 78.54 H ATOM 5782 N GLN A 350 -2.857 -9.096 -0.323 1.00 79.36 N ATOM 5783 CA GLN A 350 -3.506 -7.956 0.333 1.00 78.81 C ATOM 5784 C GLN A 350 -2.664 -6.670 0.246 1.00 78.03 C ATOM 5785 O GLN A 350 -1.452 -6.726 0.449 1.00 78.09 O ATOM 5786 CB GLN A 350 -3.842 -8.329 1.793 1.00 79.05 C ATOM 5787 CG GLN A 350 -4.593 -7.224 2.570 0.00 78.83 C ATOM 5788 CD GLN A 350 -5.057 -7.677 3.955 0.00 78.88 C ATOM 5789 OE1 GLN A 350 -4.374 -8.443 4.632 0.00 78.85 O ATOM 5790 NE2 GLN A 350 -6.210 -7.175 4.401 0.00 78.86 N ATOM 5791 H GLN A 350 -2.676 -9.897 0.265 1.00 79.36 H ATOM 5792 HA GLN A 350 -4.449 -7.786 -0.188 1.00 78.81 H ATOM 5793 HB3 GLN A 350 -2.925 -8.592 2.323 1.00 79.05 H ATOM 5794 HB2 GLN A 350 -4.456 -9.231 1.786 1.00 79.05 H ATOM 5795 HG3 GLN A 350 -5.460 -6.898 1.992 1.00 78.83 H ATOM 5796 HG2 GLN A 350 -3.959 -6.347 2.706 1.00 78.83 H ATOM 5797 HE22 GLN A 350 -6.551 -7.435 5.315 1.00 78.86 H ATOM 5798 HE21 GLN A 350 -6.748 -6.538 3.832 1.00 78.86 H ATOM 5799 N ILE A 351 -3.340 -5.554 -0.063 1.00 77.08 N ATOM 5800 CA ILE A 351 -2.765 -4.222 -0.248 1.00 76.17 C ATOM 5801 C ILE A 351 -2.433 -3.581 1.125 1.00 75.90 C ATOM 5802 O ILE A 351 -3.368 -3.302 1.878 1.00 75.52 O ATOM 5803 CB ILE A 351 -3.804 -3.336 -1.007 1.00 75.65 C ATOM 5804 CG1 ILE A 351 -3.964 -3.824 -2.467 1.00 75.09 C ATOM 5805 CG2 ILE A 351 -3.510 -1.820 -1.000 1.00 75.18 C ATOM 5806 CD1 ILE A 351 -5.191 -3.258 -3.201 1.00 72.34 C ATOM 5807 H ILE A 351 -4.340 -5.609 -0.193 1.00 77.08 H ATOM 5808 HA ILE A 351 -1.883 -4.318 -0.879 1.00 76.17 H ATOM 5809 HB ILE A 351 -4.769 -3.469 -0.514 1.00 75.65 H ATOM 5810 HG13 ILE A 351 -4.024 -4.911 -2.505 1.00 75.09 H ATOM 5811 HG12 ILE A 351 -3.063 -3.568 -3.023 1.00 75.09 H ATOM 5812 HG21 ILE A 351 -4.287 -1.284 -1.538 1.00 75.18 H ATOM 5813 HG22 ILE A 351 -3.490 -1.387 -0.001 1.00 75.18 H ATOM 5814 HG23 ILE A 351 -2.563 -1.598 -1.483 1.00 75.18 H ATOM 5815 HD11 ILE A 351 -5.550 -3.958 -3.956 1.00 72.34 H ATOM 5816 HD12 ILE A 351 -6.018 -3.063 -2.517 1.00 72.34 H ATOM 5817 HD13 ILE A 351 -4.949 -2.324 -3.708 1.00 72.34 H ATOM 5818 N PRO A 352 -1.132 -3.364 1.445 1.00 75.36 N ATOM 5819 CA PRO A 352 -0.738 -2.698 2.702 1.00 75.16 C ATOM 5820 C PRO A 352 -0.820 -1.157 2.655 1.00 74.65 C ATOM 5821 O PRO A 352 -0.827 -0.530 3.714 1.00 73.77 O ATOM 5822 CB PRO A 352 0.715 -3.163 2.885 1.00 75.54 C ATOM 5823 CG PRO A 352 1.255 -3.250 1.465 1.00 75.89 C ATOM 5824 CD PRO A 352 0.052 -3.748 0.666 1.00 75.20 C ATOM 5825 HA PRO A 352 -1.341 -3.049 3.542 1.00 75.16 H ATOM 5826 HB3 PRO A 352 0.723 -4.153 3.343 1.00 75.54 H ATOM 5827 HB2 PRO A 352 1.312 -2.506 3.517 1.00 75.54 H ATOM 5828 HG3 PRO A 352 2.131 -3.892 1.371 1.00 75.89 H ATOM 5829 HG2 PRO A 352 1.538 -2.254 1.121 1.00 75.89 H ATOM 5830 HD2 PRO A 352 0.048 -3.330 -0.340 1.00 75.20 H ATOM 5831 HD3 PRO A 352 0.104 -4.830 0.585 1.00 75.20 H ATOM 5832 N TYR A 353 -0.839 -0.588 1.437 1.00 74.47 N ATOM 5833 CA TYR A 353 -0.744 0.842 1.146 1.00 73.26 C ATOM 5834 C TYR A 353 -2.030 1.583 1.575 1.00 73.64 C ATOM 5835 O TYR A 353 -3.097 1.226 1.071 1.00 73.38 O ATOM 5836 CB TYR A 353 -0.507 1.003 -0.373 1.00 71.92 C ATOM 5837 CG TYR A 353 0.674 0.206 -0.901 1.00 67.75 C ATOM 5838 CD1 TYR A 353 1.990 0.525 -0.501 1.00 63.15 C ATOM 5839 CD2 TYR A 353 0.455 -0.892 -1.759 1.00 63.04 C ATOM 5840 CE1 TYR A 353 3.072 -0.267 -0.934 1.00 59.49 C ATOM 5841 CE2 TYR A 353 1.533 -1.691 -2.176 1.00 63.24 C ATOM 5842 CZ TYR A 353 2.840 -1.383 -1.762 1.00 59.29 C ATOM 5843 OH TYR A 353 3.875 -2.171 -2.172 1.00 60.84 O ATOM 5844 H TYR A 353 -0.830 -1.190 0.627 1.00 74.47 H ATOM 5845 HA TYR A 353 0.147 1.215 1.647 1.00 73.26 H ATOM 5846 HB3 TYR A 353 -0.350 2.055 -0.615 1.00 71.92 H ATOM 5847 HB2 TYR A 353 -1.397 0.697 -0.925 1.00 71.92 H ATOM 5848 HD1 TYR A 353 2.170 1.367 0.150 1.00 63.15 H ATOM 5849 HD2 TYR A 353 -0.540 -1.144 -2.088 1.00 63.04 H ATOM 5850 HE1 TYR A 353 4.076 -0.020 -0.620 1.00 59.49 H ATOM 5851 HE2 TYR A 353 1.353 -2.548 -2.807 1.00 63.24 H ATOM 5852 HH TYR A 353 3.593 -2.898 -2.733 1.00 60.84 H ATOM 5853 N PRO A 354 -1.922 2.584 2.485 1.00 75.17 N ATOM 5854 CA PRO A 354 -3.056 3.441 2.893 1.00 75.97 C ATOM 5855 C PRO A 354 -3.828 4.109 1.742 1.00 76.89 C ATOM 5856 O PRO A 354 -3.224 4.542 0.759 1.00 77.79 O ATOM 5857 CB PRO A 354 -2.407 4.506 3.794 1.00 76.37 C ATOM 5858 CG PRO A 354 -1.184 3.824 4.372 1.00 76.88 C ATOM 5859 CD PRO A 354 -0.707 2.955 3.218 1.00 76.15 C ATOM 5860 HA PRO A 354 -3.729 2.819 3.487 1.00 75.97 H ATOM 5861 HB3 PRO A 354 -3.083 4.867 4.570 1.00 76.37 H ATOM 5862 HB2 PRO A 354 -2.089 5.372 3.209 1.00 76.37 H ATOM 5863 HG3 PRO A 354 -1.485 3.188 5.205 1.00 76.88 H ATOM 5864 HG2 PRO A 354 -0.426 4.519 4.734 1.00 76.88 H ATOM 5865 HD2 PRO A 354 -0.051 3.519 2.553 1.00 76.15 H ATOM 5866 HD3 PRO A 354 -0.159 2.098 3.607 1.00 76.15 H ATOM 5867 N LYS A 355 -5.155 4.194 1.921 1.00 77.26 N ATOM 5868 CA LYS A 355 -6.072 4.971 1.086 1.00 78.20 C ATOM 5869 C LYS A 355 -5.792 6.477 1.240 1.00 78.69 C ATOM 5870 O LYS A 355 -5.499 6.918 2.354 1.00 78.80 O ATOM 5871 CB LYS A 355 -7.519 4.648 1.516 1.00 78.63 C ATOM 5872 CG LYS A 355 -7.896 3.166 1.341 1.00 80.41 C ATOM 5873 CD LYS A 355 -9.367 2.886 1.680 1.00 83.09 C ATOM 5874 CE LYS A 355 -9.739 1.410 1.466 1.00 84.24 C ATOM 5875 NZ LYS A 355 -11.149 1.148 1.802 1.00 85.81 N1+ ATOM 5876 H LYS A 355 -5.559 3.808 2.762 1.00 77.26 H ATOM 5877 HA LYS A 355 -5.928 4.683 0.043 1.00 78.20 H ATOM 5878 HB3 LYS A 355 -8.210 5.259 0.933 1.00 78.63 H ATOM 5879 HB2 LYS A 355 -7.670 4.937 2.557 1.00 78.63 H ATOM 5880 HG3 LYS A 355 -7.264 2.545 1.977 1.00 80.41 H ATOM 5881 HG2 LYS A 355 -7.690 2.854 0.318 1.00 80.41 H ATOM 5882 HD3 LYS A 355 -10.004 3.523 1.065 1.00 83.09 H ATOM 5883 HD2 LYS A 355 -9.554 3.171 2.716 1.00 83.09 H ATOM 5884 HE3 LYS A 355 -9.108 0.768 2.083 1.00 84.24 H ATOM 5885 HE2 LYS A 355 -9.569 1.126 0.427 1.00 84.24 H ATOM 5886 HZ1 LYS A 355 -11.744 1.709 1.209 1.00 85.81 H ATOM 5887 HZ2 LYS A 355 -11.355 0.170 1.654 1.00 85.81 H ATOM 5888 HZ3 LYS A 355 -11.317 1.385 2.769 1.00 85.81 H ATOM 5889 N ARG A 356 -5.887 7.237 0.135 1.00 79.46 N ATOM 5890 CA ARG A 356 -5.625 8.682 0.132 1.00 79.85 C ATOM 5891 C ARG A 356 -6.674 9.460 0.948 1.00 80.84 C ATOM 5892 O ARG A 356 -7.870 9.179 0.843 1.00 80.93 O ATOM 5893 CB ARG A 356 -5.479 9.204 -1.317 1.00 79.49 C ATOM 5894 CG ARG A 356 -6.781 9.266 -2.140 1.00 75.25 C ATOM 5895 CD ARG A 356 -6.630 9.807 -3.573 1.00 73.06 C ATOM 5896 NE ARG A 356 -5.933 8.866 -4.467 1.00 66.63 N ATOM 5897 CZ ARG A 356 -4.623 8.816 -4.769 1.00 61.33 C ATOM 5898 NH1 ARG A 356 -3.719 9.677 -4.278 1.00 59.08 N ATOM 5899 NH2 ARG A 356 -4.201 7.862 -5.599 1.00 58.22 N1+ ATOM 5900 H ARG A 356 -6.160 6.820 -0.745 1.00 79.46 H ATOM 5901 HA ARG A 356 -4.653 8.818 0.612 1.00 79.85 H ATOM 5902 HB3 ARG A 356 -4.743 8.585 -1.832 1.00 79.49 H ATOM 5903 HB2 ARG A 356 -5.051 10.206 -1.279 1.00 79.49 H ATOM 5904 HG3 ARG A 356 -7.572 9.827 -1.644 1.00 75.25 H ATOM 5905 HG2 ARG A 356 -7.136 8.238 -2.191 1.00 75.25 H ATOM 5906 HD3 ARG A 356 -6.041 10.723 -3.541 1.00 73.06 H ATOM 5907 HD2 ARG A 356 -7.594 10.104 -3.986 1.00 73.06 H ATOM 5908 HE ARG A 356 -6.523 8.148 -4.865 1.00 66.63 H ATOM 5909 HH12 ARG A 356 -2.747 9.590 -4.552 1.00 59.08 H ATOM 5910 HH11 ARG A 356 -4.000 10.412 -3.646 1.00 59.08 H ATOM 5911 HH22 ARG A 356 -3.220 7.814 -5.849 1.00 58.22 H ATOM 5912 HH21 ARG A 356 -4.854 7.206 -6.008 1.00 58.22 H ATOM 5913 N GLU A 357 -6.187 10.418 1.748 1.00 82.63 N ATOM 5914 CA GLU A 357 -7.003 11.262 2.618 1.00 84.35 C ATOM 5915 C GLU A 357 -7.596 12.469 1.879 1.00 84.23 C ATOM 5916 O GLU A 357 -7.083 12.885 0.838 1.00 83.84 O ATOM 5917 CB GLU A 357 -6.152 11.720 3.825 1.00 85.36 C ATOM 5918 CG GLU A 357 -5.809 10.594 4.830 1.00 88.43 C ATOM 5919 CD GLU A 357 -6.966 10.098 5.722 1.00 92.13 C ATOM 5920 OE1 GLU A 357 -8.093 10.638 5.629 1.00 92.58 O ATOM 5921 OE2 GLU A 357 -6.691 9.169 6.512 1.00 94.76 O1- ATOM 5922 H GLU A 357 -5.192 10.585 1.779 1.00 82.63 H ATOM 5923 HA GLU A 357 -7.844 10.668 2.978 1.00 84.35 H ATOM 5924 HB3 GLU A 357 -6.634 12.547 4.350 1.00 85.36 H ATOM 5925 HB2 GLU A 357 -5.214 12.136 3.454 1.00 85.36 H ATOM 5926 HG3 GLU A 357 -5.021 10.954 5.493 1.00 88.43 H ATOM 5927 HG2 GLU A 357 -5.386 9.740 4.300 1.00 88.43 H ATOM 5928 N PHE A 358 -8.675 13.008 2.466 1.00 84.88 N ATOM 5929 CA PHE A 358 -9.390 14.178 1.967 1.00 85.38 C ATOM 5930 C PHE A 358 -8.719 15.490 2.408 1.00 86.26 C ATOM 5931 O PHE A 358 -8.087 15.545 3.464 1.00 86.46 O ATOM 5932 CB PHE A 358 -10.849 14.135 2.457 1.00 85.52 C ATOM 5933 CG PHE A 358 -11.630 12.912 2.011 1.00 85.14 C ATOM 5934 CD1 PHE A 358 -12.024 12.776 0.665 1.00 81.18 C ATOM 5935 CD2 PHE A 358 -11.861 11.846 2.906 1.00 85.13 C ATOM 5936 CE1 PHE A 358 -12.708 11.640 0.257 1.00 81.94 C ATOM 5937 CE2 PHE A 358 -12.537 10.712 2.474 1.00 85.75 C ATOM 5938 CZ PHE A 358 -12.969 10.615 1.157 1.00 84.23 C ATOM 5939 H PHE A 358 -9.020 12.608 3.327 1.00 84.88 H ATOM 5940 HA PHE A 358 -9.391 14.134 0.877 1.00 85.38 H ATOM 5941 HB3 PHE A 358 -11.380 15.014 2.084 1.00 85.52 H ATOM 5942 HB2 PHE A 358 -10.886 14.204 3.546 1.00 85.52 H ATOM 5943 HD1 PHE A 358 -11.802 13.557 -0.046 1.00 81.18 H ATOM 5944 HD2 PHE A 358 -11.523 11.909 3.930 1.00 85.13 H ATOM 5945 HE1 PHE A 358 -13.037 11.552 -0.765 1.00 81.94 H ATOM 5946 HE2 PHE A 358 -12.727 9.904 3.165 1.00 85.75 H ATOM 5947 HZ PHE A 358 -13.501 9.734 0.833 1.00 84.23 H ATOM 5948 N LEU A 359 -8.909 16.524 1.579 1.00 86.95 N ATOM 5949 CA LEU A 359 -8.442 17.893 1.773 1.00 87.03 C ATOM 5950 C LEU A 359 -9.655 18.763 2.138 1.00 87.73 C ATOM 5951 O LEU A 359 -10.701 18.651 1.495 1.00 87.80 O ATOM 5952 CB LEU A 359 -7.794 18.407 0.461 1.00 86.85 C ATOM 5953 CG LEU A 359 -6.341 17.943 0.197 1.00 86.01 C ATOM 5954 CD1 LEU A 359 -6.186 16.415 0.048 1.00 84.28 C ATOM 5955 CD2 LEU A 359 -5.746 18.687 -1.019 1.00 84.51 C ATOM 5956 H LEU A 359 -9.439 16.370 0.730 1.00 86.95 H ATOM 5957 HA LEU A 359 -7.708 17.942 2.580 1.00 87.03 H ATOM 5958 HB3 LEU A 359 -7.777 19.498 0.500 1.00 86.85 H ATOM 5959 HB2 LEU A 359 -8.424 18.159 -0.395 1.00 86.85 H ATOM 5960 HG LEU A 359 -5.749 18.240 1.065 1.00 86.01 H ATOM 5961 HD11 LEU A 359 -5.429 16.139 -0.687 1.00 84.28 H ATOM 5962 HD12 LEU A 359 -5.889 15.961 0.993 1.00 84.28 H ATOM 5963 HD13 LEU A 359 -7.116 15.944 -0.264 1.00 84.28 H ATOM 5964 HD21 LEU A 359 -4.797 19.157 -0.760 1.00 84.51 H ATOM 5965 HD22 LEU A 359 -5.561 18.025 -1.866 1.00 84.51 H ATOM 5966 HD23 LEU A 359 -6.405 19.476 -1.384 1.00 84.51 H HETATM 5967 N NME A 360 -9.469 19.632 3.144 1.00 0.00 N HETATM 5968 C NME A 360 -10.490 20.548 3.639 1.00 0.00 C HETATM 5969 H NME A 360 -8.573 19.659 3.609 1.00 0.00 H HETATM 5970 H1 NME A 360 -11.453 20.433 3.138 1.00 0.00 H HETATM 5971 H2 NME A 360 -10.647 20.380 4.705 1.00 0.00 H HETATM 5972 H3 NME A 360 -10.160 21.578 3.505 1.00 0.00 H TER 5973 NME A 360 HETATM 5974 CH3 ACE B -2 2.190 16.434 -34.527 1.00 0.00 C HETATM 5975 C ACE B -2 1.940 14.947 -34.755 1.00 0.00 C HETATM 5976 O ACE B -2 2.432 14.119 -33.992 1.00 0.00 O HETATM 5977 H1 ACE B -2 2.919 16.585 -33.730 1.00 0.00 H HETATM 5978 H2 ACE B -2 2.574 16.902 -35.433 1.00 0.00 H HETATM 5979 H3 ACE B -2 1.264 16.935 -34.243 1.00 0.00 H ATOM 5980 N LYS B -1 1.165 14.632 -35.809 1.00 63.18 N ATOM 5981 CA LYS B -1 0.772 13.282 -36.254 1.00 62.35 C ATOM 5982 C LYS B -1 -0.143 12.525 -35.263 1.00 59.65 C ATOM 5983 O LYS B -1 -0.249 11.302 -35.357 1.00 57.65 O ATOM 5984 CB LYS B -1 2.006 12.439 -36.670 1.00 63.51 C ATOM 5985 CG LYS B -1 2.849 13.071 -37.790 1.00 67.85 C ATOM 5986 CD LYS B -1 4.042 12.189 -38.187 0.00 67.10 C ATOM 5987 CE LYS B -1 4.921 12.847 -39.263 0.00 67.32 C ATOM 5988 NZ LYS B -1 6.060 11.990 -39.638 0.00 67.29 N1+ ATOM 5989 H LYS B -1 0.805 15.387 -36.372 1.00 63.18 H ATOM 5990 HA LYS B -1 0.165 13.433 -37.147 1.00 62.35 H ATOM 5991 HB3 LYS B -1 1.680 11.456 -37.013 1.00 63.51 H ATOM 5992 HB2 LYS B -1 2.642 12.251 -35.805 1.00 63.51 H ATOM 5993 HG3 LYS B -1 3.220 14.045 -37.469 1.00 67.85 H ATOM 5994 HG2 LYS B -1 2.221 13.252 -38.662 1.00 67.85 H ATOM 5995 HD3 LYS B -1 3.671 11.228 -38.546 1.00 67.10 H ATOM 5996 HD2 LYS B -1 4.639 11.974 -37.299 1.00 67.10 H ATOM 5997 HE3 LYS B -1 5.307 13.801 -38.903 1.00 67.32 H ATOM 5998 HE2 LYS B -1 4.332 13.055 -40.157 1.00 67.32 H ATOM 5999 HZ1 LYS B -1 5.719 11.113 -40.006 1.00 67.29 H ATOM 6000 HZ2 LYS B -1 6.616 12.455 -40.341 1.00 67.29 H ATOM 6001 HZ3 LYS B -1 6.631 11.812 -38.824 1.00 67.29 H ATOM 6002 N ALA B 0 -0.790 13.259 -34.339 1.00 59.92 N ATOM 6003 CA ALA B 0 -1.637 12.739 -33.267 1.00 58.54 C ATOM 6004 C ALA B 0 -2.833 11.915 -33.776 1.00 58.46 C ATOM 6005 O ALA B 0 -3.662 12.437 -34.521 1.00 59.56 O ATOM 6006 CB ALA B 0 -2.107 13.914 -32.400 1.00 57.77 C ATOM 6007 H ALA B 0 -0.650 14.258 -34.335 1.00 59.92 H ATOM 6008 HA ALA B 0 -1.008 12.104 -32.641 1.00 58.54 H ATOM 6009 HB1 ALA B 0 -2.797 13.576 -31.630 1.00 57.77 H ATOM 6010 HB2 ALA B 0 -1.265 14.394 -31.900 1.00 57.77 H ATOM 6011 HB3 ALA B 0 -2.621 14.672 -32.993 1.00 57.77 H ATOM 6012 N MET B 1 -2.877 10.640 -33.351 1.00 56.81 N ATOM 6013 CA MET B 1 -3.885 9.619 -33.663 1.00 54.96 C ATOM 6014 C MET B 1 -3.930 9.179 -35.145 1.00 56.12 C ATOM 6015 O MET B 1 -4.917 8.563 -35.541 1.00 55.49 O ATOM 6016 CB MET B 1 -5.292 10.023 -33.140 1.00 54.14 C ATOM 6017 CG MET B 1 -5.364 10.544 -31.691 1.00 51.89 C ATOM 6018 SD MET B 1 -4.582 9.532 -30.400 1.00 52.67 S ATOM 6019 CE MET B 1 -5.412 7.939 -30.645 1.00 49.92 C ATOM 6020 H MET B 1 -2.120 10.315 -32.761 1.00 56.81 H ATOM 6021 HA MET B 1 -3.570 8.732 -33.113 1.00 54.96 H ATOM 6022 HB3 MET B 1 -5.972 9.177 -33.232 1.00 54.14 H ATOM 6023 HB2 MET B 1 -5.710 10.791 -33.793 1.00 54.14 H ATOM 6024 HG3 MET B 1 -6.411 10.675 -31.418 1.00 51.89 H ATOM 6025 HG2 MET B 1 -4.923 11.539 -31.638 1.00 51.89 H ATOM 6026 HE1 MET B 1 -5.026 7.198 -29.947 1.00 49.92 H ATOM 6027 HE2 MET B 1 -6.483 8.029 -30.482 1.00 49.92 H ATOM 6028 HE3 MET B 1 -5.242 7.566 -31.653 1.00 49.92 H ATOM 6029 N ALA B 2 -2.887 9.482 -35.941 1.00 57.98 N ATOM 6030 CA ALA B 2 -2.853 9.322 -37.403 1.00 59.63 C ATOM 6031 C ALA B 2 -3.144 7.915 -37.965 1.00 59.68 C ATOM 6032 O ALA B 2 -3.626 7.829 -39.094 1.00 63.45 O ATOM 6033 CB ALA B 2 -1.501 9.826 -37.931 1.00 60.03 C ATOM 6034 H ALA B 2 -2.097 9.969 -35.538 1.00 57.98 H ATOM 6035 HA ALA B 2 -3.628 9.979 -37.801 1.00 59.63 H ATOM 6036 HB1 ALA B 2 -1.427 9.719 -39.014 1.00 60.03 H ATOM 6037 HB2 ALA B 2 -1.364 10.882 -37.703 1.00 60.03 H ATOM 6038 HB3 ALA B 2 -0.669 9.278 -37.485 1.00 60.03 H ATOM 6039 N GLY B 3 -2.858 6.856 -37.188 1.00 59.20 N ATOM 6040 CA GLY B 3 -3.056 5.459 -37.586 1.00 57.92 C ATOM 6041 C GLY B 3 -4.315 4.832 -36.960 1.00 57.15 C ATOM 6042 O GLY B 3 -4.507 3.626 -37.114 1.00 57.45 O ATOM 6043 H GLY B 3 -2.470 7.016 -36.269 1.00 59.20 H ATOM 6044 HA3 GLY B 3 -2.187 4.890 -37.254 1.00 57.92 H ATOM 6045 HA2 GLY B 3 -3.100 5.349 -38.670 1.00 57.92 H ATOM 6046 N ASN B 4 -5.145 5.609 -36.242 1.00 54.66 N ATOM 6047 CA ASN B 4 -6.218 5.111 -35.375 1.00 52.23 C ATOM 6048 C ASN B 4 -7.638 5.304 -35.952 1.00 51.44 C ATOM 6049 O ASN B 4 -8.587 5.207 -35.175 1.00 51.23 O ATOM 6050 CB ASN B 4 -6.084 5.801 -33.991 1.00 51.77 C ATOM 6051 CG ASN B 4 -6.596 4.966 -32.808 1.00 48.15 C ATOM 6052 OD1 ASN B 4 -6.146 3.844 -32.586 1.00 53.79 O ATOM 6053 ND2 ASN B 4 -7.533 5.520 -32.036 1.00 41.01 N ATOM 6054 H ASN B 4 -4.948 6.599 -36.169 1.00 54.66 H ATOM 6055 HA ASN B 4 -6.154 4.030 -35.236 1.00 52.23 H ATOM 6056 HB3 ASN B 4 -6.524 6.797 -34.001 1.00 51.77 H ATOM 6057 HB2 ASN B 4 -5.028 5.961 -33.783 1.00 51.77 H ATOM 6058 HD22 ASN B 4 -7.907 5.021 -31.242 1.00 41.01 H ATOM 6059 HD21 ASN B 4 -7.895 6.442 -32.256 1.00 41.01 H ATOM 6060 N PHE B 5 -7.791 5.562 -37.267 1.00 51.87 N ATOM 6061 CA PHE B 5 -9.085 5.864 -37.906 1.00 52.35 C ATOM 6062 C PHE B 5 -10.218 4.843 -37.666 1.00 52.81 C ATOM 6063 O PHE B 5 -11.350 5.262 -37.438 1.00 53.97 O ATOM 6064 CB PHE B 5 -8.906 6.186 -39.409 1.00 52.48 C ATOM 6065 CG PHE B 5 -10.193 6.452 -40.183 1.00 51.39 C ATOM 6066 CD1 PHE B 5 -10.843 7.697 -40.053 1.00 51.01 C ATOM 6067 CD2 PHE B 5 -10.851 5.408 -40.871 1.00 51.13 C ATOM 6068 CE1 PHE B 5 -12.082 7.900 -40.642 1.00 52.53 C ATOM 6069 CE2 PHE B 5 -12.097 5.629 -41.444 1.00 51.23 C ATOM 6070 CZ PHE B 5 -12.708 6.872 -41.335 1.00 52.64 C ATOM 6071 H PHE B 5 -6.977 5.608 -37.865 1.00 51.87 H ATOM 6072 HA PHE B 5 -9.423 6.792 -37.442 1.00 52.35 H ATOM 6073 HB3 PHE B 5 -8.361 5.379 -39.901 1.00 52.48 H ATOM 6074 HB2 PHE B 5 -8.285 7.077 -39.503 1.00 52.48 H ATOM 6075 HD1 PHE B 5 -10.384 8.489 -39.485 1.00 51.01 H ATOM 6076 HD2 PHE B 5 -10.398 4.430 -40.937 1.00 51.13 H ATOM 6077 HE1 PHE B 5 -12.562 8.861 -40.552 1.00 52.53 H ATOM 6078 HE2 PHE B 5 -12.597 4.827 -41.967 1.00 51.23 H ATOM 6079 HZ PHE B 5 -13.680 7.035 -41.777 1.00 52.64 H ATOM 6080 N TRP B 6 -9.906 3.538 -37.700 1.00 55.06 N ATOM 6081 CA TRP B 6 -10.893 2.462 -37.545 1.00 55.69 C ATOM 6082 C TRP B 6 -11.400 2.251 -36.103 1.00 55.27 C ATOM 6083 O TRP B 6 -12.368 1.512 -35.923 1.00 56.25 O ATOM 6084 CB TRP B 6 -10.340 1.166 -38.164 1.00 56.30 C ATOM 6085 CG TRP B 6 -9.959 1.283 -39.611 1.00 57.27 C ATOM 6086 CD1 TRP B 6 -8.699 1.299 -40.103 1.00 57.36 C ATOM 6087 CD2 TRP B 6 -10.838 1.473 -40.762 1.00 55.08 C ATOM 6088 NE1 TRP B 6 -8.737 1.466 -41.472 1.00 59.38 N ATOM 6089 CE2 TRP B 6 -10.031 1.578 -41.936 1.00 55.75 C ATOM 6090 CE3 TRP B 6 -12.238 1.575 -40.934 1.00 57.15 C ATOM 6091 CZ2 TRP B 6 -10.587 1.759 -43.215 1.00 55.99 C ATOM 6092 CZ3 TRP B 6 -12.807 1.755 -42.211 1.00 57.16 C ATOM 6093 CH2 TRP B 6 -11.985 1.841 -43.350 1.00 58.90 C ATOM 6094 H TRP B 6 -8.949 3.251 -37.857 1.00 55.06 H ATOM 6095 HA TRP B 6 -11.773 2.742 -38.128 1.00 55.69 H ATOM 6096 HB3 TRP B 6 -11.083 0.370 -38.085 1.00 56.30 H ATOM 6097 HB2 TRP B 6 -9.471 0.824 -37.600 1.00 56.30 H ATOM 6098 HD1 TRP B 6 -7.806 1.196 -39.504 1.00 57.36 H ATOM 6099 HE1 TRP B 6 -7.903 1.500 -42.040 1.00 59.38 H ATOM 6100 HE3 TRP B 6 -12.882 1.506 -40.070 1.00 57.15 H ATOM 6101 HZ2 TRP B 6 -9.949 1.829 -44.084 1.00 55.99 H ATOM 6102 HZ3 TRP B 6 -13.879 1.821 -42.318 1.00 57.16 H ATOM 6103 HH2 TRP B 6 -12.431 1.967 -44.326 1.00 58.90 H ATOM 6104 N GLN B 7 -10.773 2.921 -35.122 0.50 55.03 N ATOM 6105 CA GLN B 7 -11.189 2.968 -33.718 0.50 54.60 C ATOM 6106 C GLN B 7 -11.455 4.409 -33.239 0.50 53.87 C ATOM 6107 O GLN B 7 -11.626 4.615 -32.037 0.50 53.47 O ATOM 6108 CB GLN B 7 -10.125 2.252 -32.849 0.50 55.31 C ATOM 6109 CG GLN B 7 -10.006 0.730 -33.086 0.50 56.50 C ATOM 6110 CD GLN B 7 -11.296 -0.049 -32.796 0.50 57.92 C ATOM 6111 OE1 GLN B 7 -12.041 0.281 -31.876 0.50 61.67 O ATOM 6112 NE2 GLN B 7 -11.551 -1.106 -33.568 0.50 56.64 N ATOM 6113 H GLN B 7 -9.980 3.502 -35.358 0.50 55.03 H ATOM 6114 HA GLN B 7 -12.149 2.463 -33.598 0.50 54.60 H ATOM 6115 HB3 GLN B 7 -10.333 2.414 -31.790 0.50 55.31 H ATOM 6116 HB2 GLN B 7 -9.151 2.712 -33.025 0.50 55.31 H ATOM 6117 HG3 GLN B 7 -9.220 0.327 -32.447 0.50 56.50 H ATOM 6118 HG2 GLN B 7 -9.690 0.543 -34.113 0.50 56.50 H ATOM 6119 HE22 GLN B 7 -12.387 -1.652 -33.413 0.50 56.64 H ATOM 6120 HE21 GLN B 7 -10.925 -1.358 -34.319 0.50 56.64 H ATOM 6121 N SER B 8 -11.502 5.378 -34.171 1.00 52.30 N ATOM 6122 CA SER B 8 -11.746 6.790 -33.886 1.00 50.63 C ATOM 6123 C SER B 8 -13.242 7.114 -33.764 1.00 49.39 C ATOM 6124 O SER B 8 -14.071 6.425 -34.359 1.00 50.71 O ATOM 6125 CB SER B 8 -11.073 7.649 -34.977 1.00 50.19 C ATOM 6126 OG SER B 8 -11.805 7.720 -36.187 1.00 46.11 O ATOM 6127 H SER B 8 -11.370 5.137 -35.143 1.00 52.30 H ATOM 6128 HA SER B 8 -11.263 7.023 -32.935 1.00 50.63 H ATOM 6129 HB3 SER B 8 -10.064 7.301 -35.187 1.00 50.19 H ATOM 6130 HB2 SER B 8 -10.965 8.661 -34.598 1.00 50.19 H ATOM 6131 HG SER B 8 -11.712 6.878 -36.647 1.00 46.11 H ATOM 6132 N SER B 9 -13.546 8.214 -33.055 1.00 49.81 N ATOM 6133 CA SER B 9 -14.891 8.786 -32.965 1.00 49.52 C ATOM 6134 C SER B 9 -15.407 9.376 -34.297 1.00 50.41 C ATOM 6135 O SER B 9 -16.623 9.444 -34.472 1.00 51.71 O ATOM 6136 CB SER B 9 -14.952 9.798 -31.804 1.00 49.54 C ATOM 6137 OG SER B 9 -14.398 11.054 -32.143 1.00 50.02 O ATOM 6138 H SER B 9 -12.805 8.732 -32.598 1.00 49.81 H ATOM 6139 HA SER B 9 -15.561 7.965 -32.703 1.00 49.52 H ATOM 6140 HB3 SER B 9 -14.445 9.409 -30.920 1.00 49.54 H ATOM 6141 HB2 SER B 9 -15.992 9.956 -31.518 1.00 49.54 H ATOM 6142 HG SER B 9 -13.466 11.061 -31.888 1.00 50.02 H ATOM 6143 N HIS B 10 -14.496 9.748 -35.220 1.00 51.57 N ATOM 6144 CA HIS B 10 -14.815 10.159 -36.590 1.00 52.91 C ATOM 6145 C HIS B 10 -15.530 9.034 -37.350 1.00 52.07 C ATOM 6146 O HIS B 10 -16.599 9.279 -37.900 1.00 51.68 O ATOM 6147 CB HIS B 10 -13.536 10.619 -37.327 1.00 52.48 C ATOM 6148 CG HIS B 10 -13.730 11.253 -38.689 1.00 53.67 C ATOM 6149 ND1 HIS B 10 -13.278 12.546 -38.978 1.00 59.35 N ATOM 6150 CD2 HIS B 10 -14.299 10.724 -39.832 1.00 57.72 C ATOM 6151 CE1 HIS B 10 -13.580 12.738 -40.256 1.00 59.33 C ATOM 6152 NE2 HIS B 10 -14.182 11.690 -40.813 1.00 56.40 N ATOM 6153 H HIS B 10 -13.511 9.687 -34.996 1.00 51.57 H ATOM 6154 HA HIS B 10 -15.487 11.015 -36.519 1.00 52.91 H ATOM 6155 HB3 HIS B 10 -12.843 9.787 -37.448 1.00 52.48 H ATOM 6156 HB2 HIS B 10 -13.016 11.351 -36.711 1.00 52.48 H ATOM 6157 HD2 HIS B 10 -14.749 9.763 -40.029 1.00 57.72 H ATOM 6158 HE1 HIS B 10 -13.354 13.645 -40.796 1.00 59.33 H ATOM 6159 HE2 HIS B 10 -14.470 11.610 -41.781 1.00 56.40 H ATOM 6160 N TYR B 11 -14.940 7.828 -37.339 1.00 53.08 N ATOM 6161 CA TYR B 11 -15.498 6.636 -37.972 1.00 55.10 C ATOM 6162 C TYR B 11 -16.748 6.101 -37.250 1.00 55.79 C ATOM 6163 O TYR B 11 -17.747 5.822 -37.912 1.00 56.34 O ATOM 6164 CB TYR B 11 -14.397 5.565 -38.101 1.00 55.29 C ATOM 6165 CG TYR B 11 -14.849 4.237 -38.685 1.00 58.95 C ATOM 6166 CD1 TYR B 11 -15.340 4.176 -40.006 1.00 60.86 C ATOM 6167 CD2 TYR B 11 -14.811 3.066 -37.899 1.00 63.64 C ATOM 6168 CE1 TYR B 11 -15.813 2.957 -40.529 1.00 62.10 C ATOM 6169 CE2 TYR B 11 -15.276 1.846 -38.424 1.00 65.76 C ATOM 6170 CZ TYR B 11 -15.782 1.792 -39.738 1.00 65.10 C ATOM 6171 OH TYR B 11 -16.236 0.609 -40.243 1.00 69.41 O ATOM 6172 H TYR B 11 -14.062 7.710 -36.851 1.00 53.08 H ATOM 6173 HA TYR B 11 -15.795 6.912 -38.983 1.00 55.10 H ATOM 6174 HB3 TYR B 11 -13.964 5.380 -37.117 1.00 55.29 H ATOM 6175 HB2 TYR B 11 -13.588 5.948 -38.721 1.00 55.29 H ATOM 6176 HD1 TYR B 11 -15.372 5.067 -40.615 1.00 60.86 H ATOM 6177 HD2 TYR B 11 -14.436 3.102 -36.887 1.00 63.64 H ATOM 6178 HE1 TYR B 11 -16.197 2.923 -41.538 1.00 62.10 H ATOM 6179 HE2 TYR B 11 -15.247 0.954 -37.815 1.00 65.76 H ATOM 6180 HH TYR B 11 -16.579 0.684 -41.137 1.00 69.41 H ATOM 6181 N LEU B 12 -16.655 5.953 -35.918 1.00 56.46 N ATOM 6182 CA LEU B 12 -17.655 5.273 -35.093 1.00 57.70 C ATOM 6183 C LEU B 12 -18.943 6.081 -34.838 1.00 57.77 C ATOM 6184 O LEU B 12 -19.944 5.454 -34.488 1.00 58.26 O ATOM 6185 CB LEU B 12 -17.008 4.843 -33.755 1.00 57.38 C ATOM 6186 CG LEU B 12 -15.914 3.754 -33.882 1.00 59.12 C ATOM 6187 CD1 LEU B 12 -15.138 3.612 -32.560 1.00 57.86 C ATOM 6188 CD2 LEU B 12 -16.486 2.399 -34.351 1.00 55.39 C ATOM 6189 H LEU B 12 -15.799 6.217 -35.447 1.00 56.46 H ATOM 6190 HA LEU B 12 -17.967 4.376 -35.630 1.00 57.70 H ATOM 6191 HB3 LEU B 12 -17.775 4.479 -33.069 1.00 57.38 H ATOM 6192 HB2 LEU B 12 -16.584 5.726 -33.276 1.00 57.38 H ATOM 6193 HG LEU B 12 -15.191 4.069 -34.634 1.00 59.12 H ATOM 6194 HD11 LEU B 12 -14.641 2.645 -32.473 1.00 57.86 H ATOM 6195 HD12 LEU B 12 -14.364 4.375 -32.486 1.00 57.86 H ATOM 6196 HD13 LEU B 12 -15.791 3.729 -31.696 1.00 57.86 H ATOM 6197 HD21 LEU B 12 -16.239 1.584 -33.671 1.00 55.39 H ATOM 6198 HD22 LEU B 12 -17.573 2.417 -34.433 1.00 55.39 H ATOM 6199 HD23 LEU B 12 -16.092 2.130 -35.331 1.00 55.39 H ATOM 6200 N GLN B 13 -18.915 7.419 -34.991 1.00 59.08 N ATOM 6201 CA GLN B 13 -20.058 8.293 -34.686 1.00 59.55 C ATOM 6202 C GLN B 13 -20.370 9.347 -35.759 1.00 59.45 C ATOM 6203 O GLN B 13 -21.526 9.764 -35.827 1.00 61.52 O ATOM 6204 CB GLN B 13 -19.869 8.969 -33.309 1.00 60.15 C ATOM 6205 CG GLN B 13 -20.007 7.992 -32.125 1.00 63.89 C ATOM 6206 CD GLN B 13 -19.800 8.653 -30.762 1.00 65.64 C ATOM 6207 OE1 GLN B 13 -19.045 8.136 -29.942 1.00 69.17 O ATOM 6208 NE2 GLN B 13 -20.476 9.775 -30.502 1.00 61.68 N ATOM 6209 H GLN B 13 -18.054 7.875 -35.258 1.00 59.08 H ATOM 6210 HA GLN B 13 -20.968 7.691 -34.631 1.00 59.55 H ATOM 6211 HB3 GLN B 13 -20.609 9.763 -33.197 1.00 60.15 H ATOM 6212 HB2 GLN B 13 -18.899 9.463 -33.265 1.00 60.15 H ATOM 6213 HG3 GLN B 13 -19.280 7.186 -32.217 1.00 63.89 H ATOM 6214 HG2 GLN B 13 -20.992 7.524 -32.137 1.00 63.89 H ATOM 6215 HE22 GLN B 13 -20.408 10.222 -29.595 1.00 61.68 H ATOM 6216 HE21 GLN B 13 -21.092 10.173 -31.196 1.00 61.68 H ATOM 6217 N TRP B 14 -19.371 9.783 -36.548 1.00 58.82 N ATOM 6218 CA TRP B 14 -19.507 10.921 -37.470 1.00 57.73 C ATOM 6219 C TRP B 14 -19.339 10.571 -38.959 1.00 56.80 C ATOM 6220 O TRP B 14 -19.312 11.487 -39.783 1.00 56.58 O ATOM 6221 CB TRP B 14 -18.626 12.092 -36.992 1.00 56.99 C ATOM 6222 CG TRP B 14 -19.048 12.665 -35.671 1.00 57.09 C ATOM 6223 CD1 TRP B 14 -18.424 12.493 -34.483 1.00 56.21 C ATOM 6224 CD2 TRP B 14 -20.251 13.441 -35.383 1.00 55.07 C ATOM 6225 NE1 TRP B 14 -19.161 13.096 -33.484 1.00 58.38 N ATOM 6226 CE2 TRP B 14 -20.306 13.687 -33.979 1.00 55.97 C ATOM 6227 CE3 TRP B 14 -21.317 13.946 -36.166 1.00 56.94 C ATOM 6228 CZ2 TRP B 14 -21.373 14.382 -33.382 1.00 57.05 C ATOM 6229 CZ3 TRP B 14 -22.373 14.677 -35.583 1.00 58.83 C ATOM 6230 CH2 TRP B 14 -22.403 14.894 -34.192 1.00 57.28 C ATOM 6231 H TRP B 14 -18.442 9.399 -36.452 1.00 58.82 H ATOM 6232 HA TRP B 14 -20.531 11.297 -37.440 1.00 57.73 H ATOM 6233 HB3 TRP B 14 -18.663 12.908 -37.712 1.00 56.99 H ATOM 6234 HB2 TRP B 14 -17.584 11.781 -36.933 1.00 56.99 H ATOM 6235 HD1 TRP B 14 -17.500 11.951 -34.349 1.00 56.21 H ATOM 6236 HE1 TRP B 14 -18.880 13.085 -32.512 1.00 58.38 H ATOM 6237 HE3 TRP B 14 -21.319 13.773 -37.232 1.00 56.94 H ATOM 6238 HZ2 TRP B 14 -21.403 14.520 -32.312 1.00 57.05 H ATOM 6239 HZ3 TRP B 14 -23.167 15.063 -36.205 1.00 58.83 H ATOM 6240 HH2 TRP B 14 -23.219 15.443 -33.746 1.00 57.28 H ATOM 6241 N ILE B 15 -19.330 9.268 -39.288 1.00 55.79 N ATOM 6242 CA ILE B 15 -19.670 8.765 -40.618 1.00 55.76 C ATOM 6243 C ILE B 15 -21.154 8.359 -40.547 1.00 54.97 C ATOM 6244 O ILE B 15 -21.491 7.284 -40.051 1.00 54.47 O ATOM 6245 CB ILE B 15 -18.765 7.580 -41.068 1.00 55.34 C ATOM 6246 CG1 ILE B 15 -17.291 8.024 -41.240 1.00 55.61 C ATOM 6247 CG2 ILE B 15 -19.255 6.858 -42.344 1.00 55.29 C ATOM 6248 CD1 ILE B 15 -17.040 9.138 -42.273 1.00 56.11 C ATOM 6249 H ILE B 15 -19.334 8.577 -38.551 1.00 55.79 H ATOM 6250 HA ILE B 15 -19.572 9.556 -41.363 1.00 55.76 H ATOM 6251 HB ILE B 15 -18.768 6.836 -40.270 1.00 55.34 H ATOM 6252 HG13 ILE B 15 -16.671 7.160 -41.484 1.00 55.61 H ATOM 6253 HG12 ILE B 15 -16.921 8.381 -40.283 1.00 55.61 H ATOM 6254 HG21 ILE B 15 -18.530 6.116 -42.680 1.00 55.29 H ATOM 6255 HG22 ILE B 15 -20.192 6.326 -42.183 1.00 55.29 H ATOM 6256 HG23 ILE B 15 -19.416 7.558 -43.163 1.00 55.29 H ATOM 6257 HD11 ILE B 15 -16.002 9.127 -42.605 1.00 56.11 H ATOM 6258 HD12 ILE B 15 -17.667 9.035 -43.158 1.00 56.11 H ATOM 6259 HD13 ILE B 15 -17.233 10.121 -41.843 1.00 56.11 H ATOM 6260 N LEU B 16 -22.001 9.303 -40.976 1.00 54.47 N ATOM 6261 CA LEU B 16 -23.457 9.279 -40.895 1.00 54.36 C ATOM 6262 C LEU B 16 -24.066 8.485 -42.060 1.00 55.25 C ATOM 6263 O LEU B 16 -23.470 8.417 -43.137 1.00 50.95 O ATOM 6264 CB LEU B 16 -23.969 10.742 -40.953 1.00 54.12 C ATOM 6265 CG LEU B 16 -23.398 11.695 -39.875 1.00 54.54 C ATOM 6266 CD1 LEU B 16 -23.863 13.149 -40.114 1.00 55.14 C ATOM 6267 CD2 LEU B 16 -23.701 11.212 -38.442 1.00 55.25 C ATOM 6268 H LEU B 16 -21.616 10.135 -41.404 1.00 54.47 H ATOM 6269 HA LEU B 16 -23.756 8.816 -39.953 1.00 54.36 H ATOM 6270 HB3 LEU B 16 -25.059 10.746 -40.883 1.00 54.12 H ATOM 6271 HB2 LEU B 16 -23.737 11.156 -41.936 1.00 54.12 H ATOM 6272 HG LEU B 16 -22.312 11.713 -39.983 1.00 54.54 H ATOM 6273 HD11 LEU B 16 -23.009 13.824 -40.176 1.00 55.14 H ATOM 6274 HD12 LEU B 16 -24.419 13.252 -41.047 1.00 55.14 H ATOM 6275 HD13 LEU B 16 -24.512 13.518 -39.320 1.00 55.14 H ATOM 6276 HD21 LEU B 16 -23.927 12.033 -37.761 1.00 55.25 H ATOM 6277 HD22 LEU B 16 -24.548 10.525 -38.415 1.00 55.25 H ATOM 6278 HD23 LEU B 16 -22.842 10.685 -38.029 1.00 55.25 H ATOM 6279 N ASP B 17 -25.282 7.961 -41.835 1.00 57.02 N ATOM 6280 CA ASP B 17 -26.159 7.439 -42.883 1.00 59.12 C ATOM 6281 C ASP B 17 -26.776 8.634 -43.637 1.00 59.36 C ATOM 6282 O ASP B 17 -27.261 9.574 -43.003 1.00 58.54 O ATOM 6283 CB ASP B 17 -27.234 6.494 -42.280 1.00 61.54 C ATOM 6284 CG ASP B 17 -28.178 5.738 -43.241 1.00 63.02 C ATOM 6285 OD1 ASP B 17 -27.981 5.785 -44.477 1.00 65.39 O ATOM 6286 OD2 ASP B 17 -29.079 5.058 -42.705 1.00 72.29 O1- ATOM 6287 H ASP B 17 -25.703 8.058 -40.922 1.00 57.02 H ATOM 6288 HA ASP B 17 -25.548 6.857 -43.577 1.00 59.12 H ATOM 6289 HB3 ASP B 17 -27.842 7.059 -41.573 1.00 61.54 H ATOM 6290 HB2 ASP B 17 -26.727 5.747 -41.669 1.00 61.54 H ATOM 6291 N LYS B 18 -26.747 8.561 -44.977 1.00 61.00 N ATOM 6292 CA LYS B 18 -27.295 9.565 -45.889 1.00 63.03 C ATOM 6293 C LYS B 18 -28.814 9.765 -45.751 1.00 65.17 C ATOM 6294 O LYS B 18 -29.277 10.887 -45.940 1.00 66.24 O ATOM 6295 CB LYS B 18 -26.883 9.200 -47.331 1.00 63.24 C ATOM 6296 CG LYS B 18 -27.274 10.243 -48.393 1.00 65.55 C ATOM 6297 CD LYS B 18 -26.736 9.891 -49.785 1.00 67.36 C ATOM 6298 CE LYS B 18 -27.091 10.959 -50.831 1.00 70.08 C ATOM 6299 NZ LYS B 18 -26.565 10.611 -52.162 1.00 73.94 N1+ ATOM 6300 H LYS B 18 -26.356 7.736 -45.410 1.00 61.00 H ATOM 6301 HA LYS B 18 -26.833 10.518 -45.632 1.00 63.03 H ATOM 6302 HB3 LYS B 18 -27.306 8.230 -47.600 1.00 63.24 H ATOM 6303 HB2 LYS B 18 -25.799 9.073 -47.360 1.00 63.24 H ATOM 6304 HG3 LYS B 18 -26.903 11.223 -48.092 1.00 65.55 H ATOM 6305 HG2 LYS B 18 -28.360 10.329 -48.453 1.00 65.55 H ATOM 6306 HD3 LYS B 18 -27.143 8.925 -50.088 1.00 67.36 H ATOM 6307 HD2 LYS B 18 -25.653 9.765 -49.733 1.00 67.36 H ATOM 6308 HE3 LYS B 18 -26.683 11.926 -50.536 1.00 70.08 H ATOM 6309 HE2 LYS B 18 -28.174 11.073 -50.900 1.00 70.08 H ATOM 6310 HZ1 LYS B 18 -26.961 9.731 -52.461 1.00 73.94 H ATOM 6311 HZ2 LYS B 18 -26.814 11.333 -52.823 1.00 73.94 H ATOM 6312 HZ3 LYS B 18 -25.559 10.528 -52.116 1.00 73.94 H ATOM 6313 N GLN B 19 -29.554 8.701 -45.399 1.00 66.09 N ATOM 6314 CA GLN B 19 -31.002 8.756 -45.201 1.00 65.89 C ATOM 6315 C GLN B 19 -31.402 9.462 -43.894 1.00 64.50 C ATOM 6316 O GLN B 19 -32.410 10.165 -43.899 1.00 66.15 O ATOM 6317 CB GLN B 19 -31.598 7.335 -45.289 1.00 67.30 C ATOM 6318 CG GLN B 19 -31.352 6.593 -46.625 1.00 70.77 C ATOM 6319 CD GLN B 19 -31.646 7.424 -47.879 1.00 75.13 C ATOM 6320 OE1 GLN B 19 -30.742 7.731 -48.653 1.00 78.47 O ATOM 6321 NE2 GLN B 19 -32.910 7.804 -48.077 1.00 75.34 N ATOM 6322 H GLN B 19 -29.109 7.805 -45.244 1.00 66.09 H ATOM 6323 HA GLN B 19 -31.428 9.361 -46.003 1.00 65.89 H ATOM 6324 HB3 GLN B 19 -32.674 7.393 -45.117 1.00 67.30 H ATOM 6325 HB2 GLN B 19 -31.205 6.723 -44.476 1.00 67.30 H ATOM 6326 HG3 GLN B 19 -31.943 5.677 -46.655 1.00 70.77 H ATOM 6327 HG2 GLN B 19 -30.309 6.276 -46.668 1.00 70.77 H ATOM 6328 HE22 GLN B 19 -33.149 8.356 -48.888 1.00 75.34 H ATOM 6329 HE21 GLN B 19 -33.632 7.543 -47.422 1.00 75.34 H ATOM 6330 N ASP B 20 -30.589 9.316 -42.832 1.00 63.47 N ATOM 6331 CA ASP B 20 -30.745 10.039 -41.563 1.00 64.14 C ATOM 6332 C ASP B 20 -30.371 11.526 -41.692 1.00 62.60 C ATOM 6333 O ASP B 20 -31.058 12.366 -41.112 1.00 63.07 O ATOM 6334 CB ASP B 20 -29.962 9.399 -40.389 1.00 65.48 C ATOM 6335 CG ASP B 20 -30.306 7.937 -40.048 1.00 69.92 C ATOM 6336 OD1 ASP B 20 -31.413 7.475 -40.408 1.00 73.82 O ATOM 6337 OD2 ASP B 20 -29.502 7.345 -39.295 1.00 73.24 O1- ATOM 6338 H ASP B 20 -29.784 8.710 -42.902 1.00 63.47 H ATOM 6339 HA ASP B 20 -31.805 10.011 -41.301 1.00 64.14 H ATOM 6340 HB3 ASP B 20 -30.120 9.987 -39.483 1.00 65.48 H ATOM 6341 HB2 ASP B 20 -28.893 9.441 -40.610 1.00 65.48 H ATOM 6342 N LEU B 21 -29.322 11.823 -42.480 1.00 62.43 N ATOM 6343 CA LEU B 21 -28.880 13.176 -42.828 1.00 61.80 C ATOM 6344 C LEU B 21 -29.955 13.957 -43.609 1.00 62.07 C ATOM 6345 O LEU B 21 -30.207 15.118 -43.288 1.00 60.71 O ATOM 6346 CB LEU B 21 -27.538 13.070 -43.596 1.00 61.72 C ATOM 6347 CG LEU B 21 -26.910 14.394 -44.094 1.00 60.37 C ATOM 6348 CD1 LEU B 21 -26.587 15.358 -42.932 1.00 59.56 C ATOM 6349 CD2 LEU B 21 -25.684 14.114 -44.992 1.00 61.00 C ATOM 6350 H LEU B 21 -28.798 11.066 -42.900 1.00 62.43 H ATOM 6351 HA LEU B 21 -28.705 13.706 -41.890 1.00 61.80 H ATOM 6352 HB3 LEU B 21 -27.693 12.426 -44.461 1.00 61.72 H ATOM 6353 HB2 LEU B 21 -26.812 12.548 -42.970 1.00 61.72 H ATOM 6354 HG LEU B 21 -27.636 14.894 -44.735 1.00 60.37 H ATOM 6355 HD11 LEU B 21 -25.578 15.768 -42.985 1.00 59.56 H ATOM 6356 HD12 LEU B 21 -27.273 16.205 -42.934 1.00 59.56 H ATOM 6357 HD13 LEU B 21 -26.679 14.871 -41.962 1.00 59.56 H ATOM 6358 HD21 LEU B 21 -24.769 14.582 -44.631 1.00 61.00 H ATOM 6359 HD22 LEU B 21 -25.476 13.048 -45.078 1.00 61.00 H ATOM 6360 HD23 LEU B 21 -25.856 14.486 -46.003 1.00 61.00 H ATOM 6361 N LEU B 22 -30.585 13.289 -44.591 1.00 64.26 N ATOM 6362 CA LEU B 22 -31.667 13.823 -45.420 1.00 66.06 C ATOM 6363 C LEU B 22 -32.988 13.970 -44.642 1.00 65.90 C ATOM 6364 O LEU B 22 -33.728 14.907 -44.930 1.00 65.26 O ATOM 6365 CB LEU B 22 -31.854 12.920 -46.665 1.00 66.50 C ATOM 6366 CG LEU B 22 -31.072 13.348 -47.934 1.00 70.24 C ATOM 6367 CD1 LEU B 22 -29.567 13.635 -47.725 1.00 72.76 C ATOM 6368 CD2 LEU B 22 -31.316 12.342 -49.080 1.00 69.52 C ATOM 6369 H LEU B 22 -30.301 12.341 -44.797 1.00 64.26 H ATOM 6370 HA LEU B 22 -31.382 14.823 -45.753 1.00 66.06 H ATOM 6371 HB3 LEU B 22 -32.909 12.904 -46.945 1.00 66.50 H ATOM 6372 HB2 LEU B 22 -31.624 11.885 -46.409 1.00 66.50 H ATOM 6373 HG LEU B 22 -31.519 14.291 -48.252 1.00 70.24 H ATOM 6374 HD11 LEU B 22 -29.366 14.703 -47.817 1.00 72.76 H ATOM 6375 HD12 LEU B 22 -29.200 13.330 -46.749 1.00 72.76 H ATOM 6376 HD13 LEU B 22 -28.937 13.134 -48.461 1.00 72.76 H ATOM 6377 HD21 LEU B 22 -31.624 12.858 -49.990 1.00 69.52 H ATOM 6378 HD22 LEU B 22 -30.429 11.755 -49.320 1.00 69.52 H ATOM 6379 HD23 LEU B 22 -32.103 11.627 -48.836 1.00 69.52 H ATOM 6380 N LYS B 23 -33.255 13.070 -43.677 1.00 66.56 N ATOM 6381 CA LYS B 23 -34.443 13.088 -42.818 1.00 67.05 C ATOM 6382 C LYS B 23 -34.448 14.272 -41.835 1.00 67.17 C ATOM 6383 O LYS B 23 -35.489 14.913 -41.683 1.00 66.79 O ATOM 6384 CB LYS B 23 -34.584 11.725 -42.108 1.00 68.18 C ATOM 6385 CG LYS B 23 -35.783 11.603 -41.149 1.00 68.22 C ATOM 6386 CD LYS B 23 -35.931 10.183 -40.585 0.00 68.09 C ATOM 6387 CE LYS B 23 -37.114 10.061 -39.611 0.00 68.09 C ATOM 6388 NZ LYS B 23 -37.241 8.693 -39.078 0.00 68.07 N1+ ATOM 6389 H LYS B 23 -32.606 12.311 -43.516 1.00 66.56 H ATOM 6390 HA LYS B 23 -35.310 13.204 -43.470 1.00 67.05 H ATOM 6391 HB3 LYS B 23 -33.670 11.503 -41.557 1.00 68.18 H ATOM 6392 HB2 LYS B 23 -34.678 10.950 -42.870 1.00 68.18 H ATOM 6393 HG3 LYS B 23 -36.697 11.889 -41.670 1.00 68.22 H ATOM 6394 HG2 LYS B 23 -35.669 12.299 -40.317 1.00 68.22 H ATOM 6395 HD3 LYS B 23 -35.004 9.900 -40.083 1.00 68.09 H ATOM 6396 HD2 LYS B 23 -36.057 9.482 -41.412 1.00 68.09 H ATOM 6397 HE3 LYS B 23 -38.045 10.329 -40.112 1.00 68.09 H ATOM 6398 HE2 LYS B 23 -36.987 10.751 -38.776 1.00 68.09 H ATOM 6399 HZ1 LYS B 23 -36.394 8.444 -38.587 1.00 68.07 H ATOM 6400 HZ2 LYS B 23 -38.023 8.650 -38.441 1.00 68.07 H ATOM 6401 HZ3 LYS B 23 -37.390 8.046 -39.839 1.00 68.07 H ATOM 6402 N GLU B 24 -33.286 14.566 -41.224 1.00 66.82 N ATOM 6403 CA GLU B 24 -33.078 15.743 -40.375 1.00 67.34 C ATOM 6404 C GLU B 24 -33.160 17.068 -41.154 1.00 66.09 C ATOM 6405 O GLU B 24 -33.592 18.066 -40.584 1.00 64.69 O ATOM 6406 CB GLU B 24 -31.723 15.637 -39.637 1.00 67.89 C ATOM 6407 CG GLU B 24 -31.631 14.531 -38.559 1.00 72.28 C ATOM 6408 CD GLU B 24 -32.315 14.820 -37.208 1.00 76.11 C ATOM 6409 OE1 GLU B 24 -32.063 14.022 -36.279 1.00 81.42 O ATOM 6410 OE2 GLU B 24 -33.070 15.812 -37.098 1.00 72.23 O1- ATOM 6411 H GLU B 24 -32.478 13.975 -41.374 1.00 66.82 H ATOM 6412 HA GLU B 24 -33.885 15.762 -39.642 1.00 67.34 H ATOM 6413 HB3 GLU B 24 -31.449 16.598 -39.196 1.00 67.89 H ATOM 6414 HB2 GLU B 24 -30.945 15.440 -40.375 1.00 67.89 H ATOM 6415 HG3 GLU B 24 -30.574 14.344 -38.358 1.00 72.28 H ATOM 6416 HG2 GLU B 24 -32.030 13.594 -38.948 1.00 72.28 H ATOM 6417 N ARG B 25 -32.771 17.055 -42.440 1.00 65.55 N ATOM 6418 CA ARG B 25 -32.750 18.231 -43.311 1.00 65.54 C ATOM 6419 C ARG B 25 -34.144 18.783 -43.657 1.00 65.37 C ATOM 6420 O ARG B 25 -34.247 19.978 -43.933 1.00 64.13 O ATOM 6421 CB ARG B 25 -31.938 17.880 -44.571 1.00 65.18 C ATOM 6422 CG ARG B 25 -31.544 19.081 -45.453 1.00 67.09 C ATOM 6423 CD ARG B 25 -30.500 18.715 -46.522 1.00 67.22 C ATOM 6424 NE ARG B 25 -29.192 18.409 -45.915 1.00 69.83 N ATOM 6425 CZ ARG B 25 -28.063 18.028 -46.534 1.00 70.36 C ATOM 6426 NH1 ARG B 25 -27.992 17.871 -47.863 1.00 72.35 N ATOM 6427 NH2 ARG B 25 -26.975 17.795 -45.791 1.00 68.54 N1+ ATOM 6428 H ARG B 25 -32.439 16.191 -42.846 1.00 65.55 H ATOM 6429 HA ARG B 25 -32.211 19.012 -42.771 1.00 65.54 H ATOM 6430 HB3 ARG B 25 -32.485 17.161 -45.180 1.00 65.18 H ATOM 6431 HB2 ARG B 25 -31.033 17.367 -44.252 1.00 65.18 H ATOM 6432 HG3 ARG B 25 -31.108 19.829 -44.789 1.00 67.09 H ATOM 6433 HG2 ARG B 25 -32.400 19.571 -45.915 1.00 67.09 H ATOM 6434 HD3 ARG B 25 -30.443 19.469 -47.307 1.00 67.22 H ATOM 6435 HD2 ARG B 25 -30.813 17.787 -47.003 1.00 67.22 H ATOM 6436 HE ARG B 25 -29.157 18.520 -44.911 1.00 69.83 H ATOM 6437 HH12 ARG B 25 -27.129 17.548 -48.287 1.00 72.35 H ATOM 6438 HH11 ARG B 25 -28.797 18.054 -48.443 1.00 72.35 H ATOM 6439 HH22 ARG B 25 -26.116 17.497 -46.239 1.00 68.54 H ATOM 6440 HH21 ARG B 25 -27.000 17.906 -44.788 1.00 68.54 H ATOM 6441 N GLN B 26 -35.180 17.922 -43.609 1.00 65.60 N ATOM 6442 CA GLN B 26 -36.569 18.218 -43.976 1.00 65.80 C ATOM 6443 C GLN B 26 -37.217 19.410 -43.248 1.00 65.15 C ATOM 6444 O GLN B 26 -38.115 20.022 -43.825 1.00 63.97 O ATOM 6445 CB GLN B 26 -37.448 16.957 -43.794 1.00 67.24 C ATOM 6446 CG GLN B 26 -37.078 15.742 -44.669 1.00 67.93 C ATOM 6447 CD GLN B 26 -37.040 16.036 -46.171 1.00 71.75 C ATOM 6448 OE1 GLN B 26 -37.960 16.642 -46.714 1.00 71.67 O ATOM 6449 NE2 GLN B 26 -35.983 15.591 -46.853 1.00 76.03 N ATOM 6450 H GLN B 26 -34.997 16.964 -43.343 1.00 65.60 H ATOM 6451 HA GLN B 26 -36.551 18.483 -45.032 1.00 65.80 H ATOM 6452 HB3 GLN B 26 -38.491 17.212 -43.993 1.00 67.24 H ATOM 6453 HB2 GLN B 26 -37.420 16.649 -42.747 1.00 67.24 H ATOM 6454 HG3 GLN B 26 -37.796 14.940 -44.498 1.00 67.93 H ATOM 6455 HG2 GLN B 26 -36.116 15.352 -44.347 1.00 67.93 H ATOM 6456 HE22 GLN B 26 -35.919 15.751 -47.849 1.00 76.03 H ATOM 6457 HE21 GLN B 26 -35.231 15.114 -46.374 1.00 76.03 H ATOM 6458 N LYS B 27 -36.753 19.733 -42.026 1.00 64.86 N ATOM 6459 CA LYS B 27 -37.244 20.864 -41.234 1.00 65.69 C ATOM 6460 C LYS B 27 -36.907 22.239 -41.852 1.00 65.61 C ATOM 6461 O LYS B 27 -37.724 23.152 -41.731 1.00 66.24 O ATOM 6462 CB LYS B 27 -36.782 20.720 -39.762 1.00 66.44 C ATOM 6463 CG LYS B 27 -35.289 20.993 -39.471 1.00 68.61 C ATOM 6464 CD LYS B 27 -34.921 20.859 -37.978 0.00 67.53 C ATOM 6465 CE LYS B 27 -34.763 19.418 -37.455 0.00 67.61 C ATOM 6466 NZ LYS B 27 -33.415 18.880 -37.711 0.00 67.57 N1+ ATOM 6467 H LYS B 27 -36.005 19.188 -41.620 1.00 64.86 H ATOM 6468 HA LYS B 27 -38.333 20.790 -41.228 1.00 65.69 H ATOM 6469 HB3 LYS B 27 -37.061 19.731 -39.397 1.00 66.44 H ATOM 6470 HB2 LYS B 27 -37.363 21.424 -39.165 1.00 66.44 H ATOM 6471 HG3 LYS B 27 -35.050 22.011 -39.770 1.00 68.61 H ATOM 6472 HG2 LYS B 27 -34.657 20.351 -40.081 1.00 68.61 H ATOM 6473 HD3 LYS B 27 -35.685 21.361 -37.383 1.00 67.53 H ATOM 6474 HD2 LYS B 27 -34.003 21.416 -37.792 1.00 67.53 H ATOM 6475 HE3 LYS B 27 -35.514 18.754 -37.882 1.00 67.61 H ATOM 6476 HE2 LYS B 27 -34.909 19.407 -36.375 1.00 67.61 H ATOM 6477 HZ1 LYS B 27 -33.347 17.937 -37.345 1.00 67.57 H ATOM 6478 HZ2 LYS B 27 -33.244 18.850 -38.708 1.00 67.57 H ATOM 6479 HZ3 LYS B 27 -32.713 19.454 -37.269 1.00 67.57 H ATOM 6480 N ASP B 28 -35.752 22.345 -42.536 1.00 64.96 N ATOM 6481 CA ASP B 28 -35.319 23.542 -43.272 1.00 64.65 C ATOM 6482 C ASP B 28 -35.760 23.525 -44.740 1.00 64.56 C ATOM 6483 O ASP B 28 -35.805 24.596 -45.344 1.00 63.06 O ATOM 6484 CB ASP B 28 -33.793 23.792 -43.204 1.00 64.47 C ATOM 6485 CG ASP B 28 -33.217 24.059 -41.807 1.00 63.67 C ATOM 6486 OD1 ASP B 28 -33.993 24.265 -40.849 1.00 57.33 O ATOM 6487 OD2 ASP B 28 -31.976 24.149 -41.731 1.00 62.91 O1- ATOM 6488 H ASP B 28 -35.139 21.544 -42.601 1.00 64.96 H ATOM 6489 HA ASP B 28 -35.806 24.415 -42.834 1.00 64.65 H ATOM 6490 HB3 ASP B 28 -33.525 24.644 -43.832 1.00 64.47 H ATOM 6491 HB2 ASP B 28 -33.271 22.925 -43.613 1.00 64.47 H ATOM 6492 N LEU B 29 -36.117 22.347 -45.284 1.00 65.01 N ATOM 6493 CA LEU B 29 -36.673 22.212 -46.635 1.00 65.90 C ATOM 6494 C LEU B 29 -38.141 22.685 -46.746 1.00 67.65 C ATOM 6495 O LEU B 29 -38.668 22.737 -47.856 1.00 67.83 O ATOM 6496 CB LEU B 29 -36.482 20.775 -47.164 1.00 65.17 C ATOM 6497 CG LEU B 29 -35.003 20.347 -47.308 1.00 63.31 C ATOM 6498 CD1 LEU B 29 -34.889 18.842 -47.628 1.00 60.73 C ATOM 6499 CD2 LEU B 29 -34.227 21.224 -48.313 1.00 60.45 C ATOM 6500 H LEU B 29 -36.050 21.501 -44.736 1.00 65.01 H ATOM 6501 HA LEU B 29 -36.092 22.871 -47.274 1.00 65.90 H ATOM 6502 HB3 LEU B 29 -36.964 20.672 -48.137 1.00 65.17 H ATOM 6503 HB2 LEU B 29 -37.008 20.088 -46.503 1.00 65.17 H ATOM 6504 HG LEU B 29 -34.519 20.492 -46.346 1.00 63.31 H ATOM 6505 HD11 LEU B 29 -34.283 18.635 -48.509 1.00 60.73 H ATOM 6506 HD12 LEU B 29 -34.439 18.301 -46.796 1.00 60.73 H ATOM 6507 HD13 LEU B 29 -35.866 18.395 -47.810 1.00 60.73 H ATOM 6508 HD21 LEU B 29 -33.503 20.654 -48.892 1.00 60.45 H ATOM 6509 HD22 LEU B 29 -34.894 21.718 -49.022 1.00 60.45 H ATOM 6510 HD23 LEU B 29 -33.669 22.004 -47.795 1.00 60.45 H ATOM 6511 N LYS B 30 -38.754 23.073 -45.614 1.00 69.52 N ATOM 6512 CA LYS B 30 -40.013 23.819 -45.549 1.00 70.23 C ATOM 6513 C LYS B 30 -39.841 25.312 -45.901 1.00 70.18 C ATOM 6514 O LYS B 30 -40.827 25.950 -46.268 1.00 70.75 O ATOM 6515 CB LYS B 30 -40.603 23.679 -44.130 1.00 70.39 C ATOM 6516 CG LYS B 30 -41.006 22.240 -43.770 0.00 70.14 C ATOM 6517 CD LYS B 30 -41.572 22.122 -42.349 0.00 70.19 C ATOM 6518 CE LYS B 30 -41.930 20.672 -41.988 0.00 70.22 C ATOM 6519 NZ LYS B 30 -42.508 20.573 -40.636 0.00 70.26 N1+ ATOM 6520 H LYS B 30 -38.265 22.965 -44.737 1.00 69.52 H ATOM 6521 HA LYS B 30 -40.716 23.387 -46.264 1.00 70.23 H ATOM 6522 HB3 LYS B 30 -41.487 24.313 -44.040 1.00 70.39 H ATOM 6523 HB2 LYS B 30 -39.887 24.052 -43.396 1.00 70.39 H ATOM 6524 HG3 LYS B 30 -40.144 21.583 -43.863 1.00 70.14 H ATOM 6525 HG2 LYS B 30 -41.743 21.881 -44.490 1.00 70.14 H ATOM 6526 HD3 LYS B 30 -42.455 22.758 -42.263 1.00 70.19 H ATOM 6527 HD2 LYS B 30 -40.840 22.512 -41.640 1.00 70.19 H ATOM 6528 HE3 LYS B 30 -41.041 20.042 -42.037 1.00 70.22 H ATOM 6529 HE2 LYS B 30 -42.649 20.271 -42.703 1.00 70.22 H ATOM 6530 HZ1 LYS B 30 -43.351 21.126 -40.588 1.00 70.26 H ATOM 6531 HZ2 LYS B 30 -42.728 19.608 -40.433 1.00 70.26 H ATOM 6532 HZ3 LYS B 30 -41.843 20.915 -39.958 1.00 70.26 H ATOM 6533 N PHE B 31 -38.610 25.838 -45.765 1.00 69.51 N ATOM 6534 CA PHE B 31 -38.254 27.248 -45.947 1.00 68.56 C ATOM 6535 C PHE B 31 -37.407 27.481 -47.211 1.00 66.43 C ATOM 6536 O PHE B 31 -37.479 28.565 -47.789 1.00 66.02 O ATOM 6537 CB PHE B 31 -37.460 27.718 -44.710 1.00 69.85 C ATOM 6538 CG PHE B 31 -38.239 27.729 -43.408 1.00 72.09 C ATOM 6539 CD1 PHE B 31 -38.350 26.553 -42.635 1.00 73.48 C ATOM 6540 CD2 PHE B 31 -38.987 28.866 -43.038 1.00 74.44 C ATOM 6541 CE1 PHE B 31 -39.136 26.545 -41.491 1.00 74.70 C ATOM 6542 CE2 PHE B 31 -39.764 28.840 -41.887 1.00 76.68 C ATOM 6543 CZ PHE B 31 -39.834 27.686 -41.115 1.00 75.04 C ATOM 6544 H PHE B 31 -37.854 25.235 -45.470 1.00 69.51 H ATOM 6545 HA PHE B 31 -39.152 27.862 -46.036 1.00 68.56 H ATOM 6546 HB3 PHE B 31 -37.080 28.725 -44.873 1.00 69.85 H ATOM 6547 HB2 PHE B 31 -36.578 27.091 -44.573 1.00 69.85 H ATOM 6548 HD1 PHE B 31 -37.823 25.658 -42.930 1.00 73.48 H ATOM 6549 HD2 PHE B 31 -38.951 29.761 -43.642 1.00 74.44 H ATOM 6550 HE1 PHE B 31 -39.208 25.645 -40.897 1.00 74.70 H ATOM 6551 HE2 PHE B 31 -40.323 29.717 -41.596 1.00 76.68 H ATOM 6552 HZ PHE B 31 -40.444 27.672 -40.225 1.00 75.04 H ATOM 6553 N LEU B 32 -36.611 26.470 -47.592 1.00 64.79 N ATOM 6554 CA LEU B 32 -35.643 26.495 -48.687 1.00 61.90 C ATOM 6555 C LEU B 32 -35.922 25.312 -49.626 1.00 61.77 C ATOM 6556 O LEU B 32 -36.475 24.305 -49.190 1.00 62.38 O ATOM 6557 CB LEU B 32 -34.223 26.336 -48.083 1.00 60.66 C ATOM 6558 CG LEU B 32 -33.764 27.486 -47.156 1.00 57.94 C ATOM 6559 CD1 LEU B 32 -32.619 27.034 -46.235 1.00 50.16 C ATOM 6560 CD2 LEU B 32 -33.396 28.753 -47.952 1.00 52.59 C ATOM 6561 H LEU B 32 -36.627 25.611 -47.060 1.00 64.79 H ATOM 6562 HA LEU B 32 -35.713 27.423 -49.256 1.00 61.90 H ATOM 6563 HB3 LEU B 32 -33.485 26.211 -48.878 1.00 60.66 H ATOM 6564 HB2 LEU B 32 -34.198 25.402 -47.518 1.00 60.66 H ATOM 6565 HG LEU B 32 -34.587 27.754 -46.493 1.00 57.94 H ATOM 6566 HD11 LEU B 32 -32.001 27.871 -45.915 1.00 50.16 H ATOM 6567 HD12 LEU B 32 -33.014 26.572 -45.329 1.00 50.16 H ATOM 6568 HD13 LEU B 32 -31.971 26.305 -46.722 1.00 50.16 H ATOM 6569 HD21 LEU B 32 -33.926 29.615 -47.555 1.00 52.59 H ATOM 6570 HD22 LEU B 32 -32.332 28.983 -47.903 1.00 52.59 H ATOM 6571 HD23 LEU B 32 -33.654 28.671 -49.008 1.00 52.59 H ATOM 6572 N SER B 33 -35.465 25.411 -50.882 1.00 61.17 N ATOM 6573 CA SER B 33 -35.331 24.249 -51.768 1.00 61.23 C ATOM 6574 C SER B 33 -34.035 23.468 -51.454 1.00 60.93 C ATOM 6575 O SER B 33 -33.161 23.984 -50.754 1.00 61.06 O ATOM 6576 CB SER B 33 -35.421 24.716 -53.237 1.00 61.22 C ATOM 6577 OG SER B 33 -34.256 25.381 -53.678 1.00 61.39 O ATOM 6578 H SER B 33 -35.041 26.275 -51.196 1.00 61.17 H ATOM 6579 HA SER B 33 -36.173 23.576 -51.596 1.00 61.23 H ATOM 6580 HB3 SER B 33 -36.281 25.371 -53.380 1.00 61.22 H ATOM 6581 HB2 SER B 33 -35.577 23.856 -53.890 1.00 61.22 H ATOM 6582 HG SER B 33 -34.287 26.288 -53.358 1.00 61.39 H ATOM 6583 N GLU B 34 -33.920 22.243 -51.998 1.00 60.74 N ATOM 6584 CA GLU B 34 -32.706 21.418 -51.917 1.00 61.98 C ATOM 6585 C GLU B 34 -31.480 22.074 -52.577 1.00 61.74 C ATOM 6586 O GLU B 34 -30.372 21.946 -52.054 1.00 61.77 O ATOM 6587 CB GLU B 34 -32.959 20.032 -52.543 1.00 62.37 C ATOM 6588 CG GLU B 34 -34.013 19.191 -51.790 1.00 69.00 C ATOM 6589 CD GLU B 34 -34.235 17.769 -52.337 1.00 76.85 C ATOM 6590 OE1 GLU B 34 -33.667 17.425 -53.399 1.00 78.91 O ATOM 6591 OE2 GLU B 34 -34.986 17.031 -51.663 1.00 80.14 O1- ATOM 6592 H GLU B 34 -34.680 21.863 -52.543 1.00 60.74 H ATOM 6593 HA GLU B 34 -32.463 21.281 -50.863 1.00 61.98 H ATOM 6594 HB3 GLU B 34 -32.018 19.479 -52.581 1.00 62.37 H ATOM 6595 HB2 GLU B 34 -33.276 20.161 -53.580 1.00 62.37 H ATOM 6596 HG3 GLU B 34 -34.973 19.708 -51.792 1.00 69.00 H ATOM 6597 HG2 GLU B 34 -33.711 19.105 -50.747 1.00 69.00 H ATOM 6598 N GLU B 35 -31.719 22.792 -53.687 1.00 61.01 N ATOM 6599 CA GLU B 35 -30.721 23.569 -54.413 1.00 61.23 C ATOM 6600 C GLU B 35 -30.229 24.785 -53.605 1.00 59.42 C ATOM 6601 O GLU B 35 -29.020 24.986 -53.519 1.00 58.49 O ATOM 6602 CB GLU B 35 -31.296 23.941 -55.796 1.00 63.70 C ATOM 6603 CG GLU B 35 -30.327 24.747 -56.685 1.00 69.43 C ATOM 6604 CD GLU B 35 -30.806 24.992 -58.125 1.00 75.50 C ATOM 6605 OE1 GLU B 35 -32.035 24.998 -58.360 1.00 77.70 O ATOM 6606 OE2 GLU B 35 -29.914 25.210 -58.976 1.00 80.55 O1- ATOM 6607 H GLU B 35 -32.664 22.851 -54.040 1.00 61.01 H ATOM 6608 HA GLU B 35 -29.859 22.919 -54.579 1.00 61.23 H ATOM 6609 HB3 GLU B 35 -32.224 24.500 -55.661 1.00 63.70 H ATOM 6610 HB2 GLU B 35 -31.571 23.023 -56.317 1.00 63.70 H ATOM 6611 HG3 GLU B 35 -29.361 24.240 -56.711 1.00 69.43 H ATOM 6612 HG2 GLU B 35 -30.157 25.721 -56.230 1.00 69.43 H ATOM 6613 N GLU B 36 -31.165 25.529 -52.988 1.00 56.76 N ATOM 6614 CA GLU B 36 -30.887 26.664 -52.100 1.00 56.07 C ATOM 6615 C GLU B 36 -30.138 26.287 -50.812 1.00 55.18 C ATOM 6616 O GLU B 36 -29.319 27.082 -50.353 1.00 54.34 O ATOM 6617 CB GLU B 36 -32.197 27.403 -51.769 1.00 55.79 C ATOM 6618 CG GLU B 36 -32.735 28.226 -52.959 1.00 55.62 C ATOM 6619 CD GLU B 36 -34.086 28.917 -52.718 1.00 56.77 C ATOM 6620 OE1 GLU B 36 -34.843 28.481 -51.822 1.00 60.03 O ATOM 6621 OE2 GLU B 36 -34.358 29.881 -53.467 1.00 55.79 O1- ATOM 6622 H GLU B 36 -32.140 25.290 -53.108 1.00 56.76 H ATOM 6623 HA GLU B 36 -30.243 27.355 -52.645 1.00 56.07 H ATOM 6624 HB3 GLU B 36 -32.055 28.064 -50.912 1.00 55.79 H ATOM 6625 HB2 GLU B 36 -32.938 26.668 -51.454 1.00 55.79 H ATOM 6626 HG3 GLU B 36 -32.833 27.594 -53.842 1.00 55.62 H ATOM 6627 HG2 GLU B 36 -31.994 28.980 -53.225 1.00 55.62 H ATOM 6628 N TYR B 37 -30.401 25.083 -50.272 1.00 54.69 N ATOM 6629 CA TYR B 37 -29.695 24.544 -49.111 1.00 54.61 C ATOM 6630 C TYR B 37 -28.232 24.183 -49.439 1.00 53.70 C ATOM 6631 O TYR B 37 -27.359 24.459 -48.620 1.00 52.62 O ATOM 6632 CB TYR B 37 -30.477 23.354 -48.510 1.00 55.00 C ATOM 6633 CG TYR B 37 -29.946 22.871 -47.168 1.00 55.30 C ATOM 6634 CD1 TYR B 37 -28.854 21.979 -47.112 1.00 52.52 C ATOM 6635 CD2 TYR B 37 -30.518 23.344 -45.967 1.00 56.34 C ATOM 6636 CE1 TYR B 37 -28.318 21.593 -45.870 1.00 53.21 C ATOM 6637 CE2 TYR B 37 -29.993 22.939 -44.723 1.00 57.38 C ATOM 6638 CZ TYR B 37 -28.888 22.066 -44.674 1.00 54.67 C ATOM 6639 OH TYR B 37 -28.366 21.669 -43.478 1.00 56.97 O ATOM 6640 H TYR B 37 -31.109 24.491 -50.687 1.00 54.69 H ATOM 6641 HA TYR B 37 -29.672 25.329 -48.352 1.00 54.61 H ATOM 6642 HB3 TYR B 37 -30.498 22.518 -49.211 1.00 55.00 H ATOM 6643 HB2 TYR B 37 -31.520 23.646 -48.370 1.00 55.00 H ATOM 6644 HD1 TYR B 37 -28.405 21.607 -48.021 1.00 52.52 H ATOM 6645 HD2 TYR B 37 -31.354 24.027 -45.993 1.00 56.34 H ATOM 6646 HE1 TYR B 37 -27.472 20.923 -45.836 1.00 53.21 H ATOM 6647 HE2 TYR B 37 -30.435 23.308 -43.811 1.00 57.38 H ATOM 6648 HH TYR B 37 -28.800 22.064 -42.711 1.00 56.97 H ATOM 6649 N TRP B 38 -27.975 23.612 -50.632 1.00 53.30 N ATOM 6650 CA TRP B 38 -26.618 23.314 -51.103 1.00 54.16 C ATOM 6651 C TRP B 38 -25.823 24.589 -51.460 1.00 53.10 C ATOM 6652 O TRP B 38 -24.610 24.613 -51.266 1.00 53.08 O ATOM 6653 CB TRP B 38 -26.672 22.293 -52.263 1.00 54.36 C ATOM 6654 CG TRP B 38 -25.365 21.740 -52.774 1.00 61.32 C ATOM 6655 CD1 TRP B 38 -24.212 21.636 -52.069 1.00 62.16 C ATOM 6656 CD2 TRP B 38 -25.086 21.111 -54.065 1.00 65.21 C ATOM 6657 NE1 TRP B 38 -23.231 21.068 -52.850 1.00 66.48 N ATOM 6658 CE2 TRP B 38 -23.713 20.713 -54.091 1.00 65.69 C ATOM 6659 CE3 TRP B 38 -25.852 20.834 -55.223 1.00 66.04 C ATOM 6660 CZ2 TRP B 38 -23.127 20.095 -55.210 1.00 64.44 C ATOM 6661 CZ3 TRP B 38 -25.279 20.202 -56.346 1.00 64.35 C ATOM 6662 CH2 TRP B 38 -23.918 19.839 -56.343 1.00 63.68 C ATOM 6663 H TRP B 38 -28.734 23.400 -51.266 1.00 53.30 H ATOM 6664 HA TRP B 38 -26.100 22.833 -50.273 1.00 54.16 H ATOM 6665 HB3 TRP B 38 -27.210 22.727 -53.107 1.00 54.36 H ATOM 6666 HB2 TRP B 38 -27.262 21.434 -51.943 1.00 54.36 H ATOM 6667 HD1 TRP B 38 -24.077 21.970 -51.052 1.00 62.16 H ATOM 6668 HE1 TRP B 38 -22.288 20.934 -52.512 1.00 66.48 H ATOM 6669 HE3 TRP B 38 -26.893 21.120 -55.250 1.00 66.04 H ATOM 6670 HZ2 TRP B 38 -22.085 19.812 -55.197 1.00 64.44 H ATOM 6671 HZ3 TRP B 38 -25.884 20.010 -57.220 1.00 64.35 H ATOM 6672 HH2 TRP B 38 -23.479 19.368 -57.209 1.00 63.68 H ATOM 6673 N LYS B 39 -26.520 25.645 -51.911 1.00 52.27 N ATOM 6674 CA LYS B 39 -25.957 26.975 -52.152 1.00 52.65 C ATOM 6675 C LYS B 39 -25.530 27.709 -50.865 1.00 52.30 C ATOM 6676 O LYS B 39 -24.546 28.447 -50.913 1.00 51.45 O ATOM 6677 CB LYS B 39 -26.938 27.785 -53.021 1.00 52.88 C ATOM 6678 CG LYS B 39 -26.949 27.295 -54.482 1.00 52.60 C ATOM 6679 CD LYS B 39 -28.040 27.946 -55.341 1.00 55.82 C ATOM 6680 CE LYS B 39 -27.951 27.496 -56.809 1.00 56.58 C ATOM 6681 NZ LYS B 39 -29.014 28.089 -57.637 1.00 50.61 N1+ ATOM 6682 H LYS B 39 -27.514 25.548 -52.070 1.00 52.27 H ATOM 6683 HA LYS B 39 -25.046 26.842 -52.734 1.00 52.65 H ATOM 6684 HB3 LYS B 39 -26.663 28.840 -53.015 1.00 52.88 H ATOM 6685 HB2 LYS B 39 -27.938 27.738 -52.592 1.00 52.88 H ATOM 6686 HG3 LYS B 39 -27.062 26.213 -54.520 1.00 52.60 H ATOM 6687 HG2 LYS B 39 -25.975 27.489 -54.928 1.00 52.60 H ATOM 6688 HD3 LYS B 39 -27.958 29.032 -55.273 1.00 55.82 H ATOM 6689 HD2 LYS B 39 -29.018 27.688 -54.930 1.00 55.82 H ATOM 6690 HE3 LYS B 39 -28.016 26.411 -56.875 1.00 56.58 H ATOM 6691 HE2 LYS B 39 -26.990 27.775 -57.237 1.00 56.58 H ATOM 6692 HZ1 LYS B 39 -28.933 29.101 -57.617 1.00 50.61 H ATOM 6693 HZ2 LYS B 39 -28.929 27.761 -58.589 1.00 50.61 H ATOM 6694 HZ3 LYS B 39 -29.918 27.819 -57.276 1.00 50.61 H ATOM 6695 N LEU B 40 -26.209 27.436 -49.735 1.00 52.49 N ATOM 6696 CA LEU B 40 -25.792 27.862 -48.393 1.00 53.91 C ATOM 6697 C LEU B 40 -24.548 27.105 -47.902 1.00 53.75 C ATOM 6698 O LEU B 40 -23.663 27.739 -47.330 1.00 53.70 O ATOM 6699 CB LEU B 40 -26.951 27.682 -47.387 1.00 55.07 C ATOM 6700 CG LEU B 40 -28.063 28.738 -47.512 1.00 57.46 C ATOM 6701 CD1 LEU B 40 -29.414 28.217 -46.990 1.00 61.08 C ATOM 6702 CD2 LEU B 40 -27.659 30.062 -46.833 1.00 55.15 C ATOM 6703 H LEU B 40 -27.017 26.832 -49.777 1.00 52.49 H ATOM 6704 HA LEU B 40 -25.526 28.919 -48.437 1.00 53.91 H ATOM 6705 HB3 LEU B 40 -26.580 27.693 -46.361 1.00 55.07 H ATOM 6706 HB2 LEU B 40 -27.375 26.690 -47.525 1.00 55.07 H ATOM 6707 HG LEU B 40 -28.193 28.934 -48.575 1.00 57.46 H ATOM 6708 HD11 LEU B 40 -29.883 28.918 -46.302 1.00 61.08 H ATOM 6709 HD12 LEU B 40 -30.109 28.066 -47.816 1.00 61.08 H ATOM 6710 HD13 LEU B 40 -29.321 27.264 -46.470 1.00 61.08 H ATOM 6711 HD21 LEU B 40 -28.078 30.922 -47.355 1.00 55.15 H ATOM 6712 HD22 LEU B 40 -28.008 30.107 -45.804 1.00 55.15 H ATOM 6713 HD23 LEU B 40 -26.578 30.195 -46.802 1.00 55.15 H ATOM 6714 N GLN B 41 -24.486 25.783 -48.152 1.00 54.49 N ATOM 6715 CA GLN B 41 -23.338 24.933 -47.817 1.00 55.20 C ATOM 6716 C GLN B 41 -22.048 25.330 -48.550 1.00 53.99 C ATOM 6717 O GLN B 41 -20.993 25.352 -47.920 1.00 53.98 O ATOM 6718 CB GLN B 41 -23.670 23.451 -48.066 1.00 57.22 C ATOM 6719 CG GLN B 41 -24.663 22.866 -47.049 1.00 58.29 C ATOM 6720 CD GLN B 41 -24.928 21.389 -47.335 1.00 64.66 C ATOM 6721 OE1 GLN B 41 -25.432 21.034 -48.397 1.00 67.66 O ATOM 6722 NE2 GLN B 41 -24.586 20.524 -46.381 1.00 65.28 N ATOM 6723 H GLN B 41 -25.261 25.328 -48.614 1.00 54.49 H ATOM 6724 HA GLN B 41 -23.145 25.059 -46.749 1.00 55.20 H ATOM 6725 HB3 GLN B 41 -22.751 22.863 -48.028 1.00 57.22 H ATOM 6726 HB2 GLN B 41 -24.057 23.327 -49.076 1.00 57.22 H ATOM 6727 HG3 GLN B 41 -25.611 23.400 -47.078 1.00 58.29 H ATOM 6728 HG2 GLN B 41 -24.273 22.986 -46.037 1.00 58.29 H ATOM 6729 HE22 GLN B 41 -24.671 19.529 -46.554 1.00 65.28 H ATOM 6730 HE21 GLN B 41 -24.205 20.844 -45.504 1.00 65.28 H ATOM 6731 N ILE B 42 -22.167 25.682 -49.843 1.00 51.83 N ATOM 6732 CA ILE B 42 -21.093 26.255 -50.655 1.00 51.42 C ATOM 6733 C ILE B 42 -20.613 27.609 -50.093 1.00 50.43 C ATOM 6734 O ILE B 42 -19.410 27.786 -49.909 1.00 50.82 O ATOM 6735 CB ILE B 42 -21.534 26.440 -52.142 1.00 51.27 C ATOM 6736 CG1 ILE B 42 -21.718 25.075 -52.847 1.00 49.08 C ATOM 6737 CG2 ILE B 42 -20.597 27.336 -52.984 1.00 52.00 C ATOM 6738 CD1 ILE B 42 -22.652 25.114 -54.066 1.00 44.79 C ATOM 6739 H ILE B 42 -23.069 25.603 -50.293 1.00 51.83 H ATOM 6740 HA ILE B 42 -20.249 25.562 -50.627 1.00 51.42 H ATOM 6741 HB ILE B 42 -22.511 26.925 -52.127 1.00 51.27 H ATOM 6742 HG13 ILE B 42 -22.096 24.326 -52.151 1.00 49.08 H ATOM 6743 HG12 ILE B 42 -20.746 24.711 -53.171 1.00 49.08 H ATOM 6744 HG21 ILE B 42 -20.888 27.340 -54.033 1.00 52.00 H ATOM 6745 HG22 ILE B 42 -20.612 28.379 -52.664 1.00 52.00 H ATOM 6746 HG23 ILE B 42 -19.568 26.984 -52.925 1.00 52.00 H ATOM 6747 HD11 ILE B 42 -23.008 24.113 -54.311 1.00 44.79 H ATOM 6748 HD12 ILE B 42 -23.528 25.733 -53.890 1.00 44.79 H ATOM 6749 HD13 ILE B 42 -22.143 25.510 -54.944 1.00 44.79 H ATOM 6750 N PHE B 43 -21.567 28.516 -49.820 1.00 49.87 N ATOM 6751 CA PHE B 43 -21.325 29.872 -49.330 1.00 50.10 C ATOM 6752 C PHE B 43 -20.604 29.938 -47.972 1.00 48.73 C ATOM 6753 O PHE B 43 -19.609 30.652 -47.867 1.00 49.68 O ATOM 6754 CB PHE B 43 -22.643 30.673 -49.373 1.00 50.38 C ATOM 6755 CG PHE B 43 -22.616 32.058 -48.748 1.00 51.11 C ATOM 6756 CD1 PHE B 43 -22.040 33.139 -49.446 1.00 48.85 C ATOM 6757 CD2 PHE B 43 -23.040 32.246 -47.415 1.00 50.79 C ATOM 6758 CE1 PHE B 43 -21.969 34.389 -48.848 1.00 51.72 C ATOM 6759 CE2 PHE B 43 -22.949 33.501 -46.831 1.00 51.85 C ATOM 6760 CZ PHE B 43 -22.423 34.568 -47.548 1.00 50.39 C ATOM 6761 H PHE B 43 -22.534 28.282 -49.998 1.00 49.87 H ATOM 6762 HA PHE B 43 -20.652 30.343 -50.050 1.00 50.10 H ATOM 6763 HB3 PHE B 43 -23.442 30.099 -48.904 1.00 50.38 H ATOM 6764 HB2 PHE B 43 -22.939 30.794 -50.416 1.00 50.38 H ATOM 6765 HD1 PHE B 43 -21.670 33.003 -50.452 1.00 48.85 H ATOM 6766 HD2 PHE B 43 -23.441 31.419 -46.849 1.00 50.79 H ATOM 6767 HE1 PHE B 43 -21.560 35.225 -49.392 1.00 51.72 H ATOM 6768 HE2 PHE B 43 -23.290 33.645 -45.817 1.00 51.85 H ATOM 6769 HZ PHE B 43 -22.361 35.544 -47.095 1.00 50.39 H ATOM 6770 N PHE B 44 -21.091 29.180 -46.972 1.00 47.55 N ATOM 6771 CA PHE B 44 -20.489 29.131 -45.637 1.00 46.58 C ATOM 6772 C PHE B 44 -19.153 28.369 -45.553 1.00 45.00 C ATOM 6773 O PHE B 44 -18.365 28.672 -44.658 1.00 44.03 O ATOM 6774 CB PHE B 44 -21.505 28.669 -44.573 1.00 48.77 C ATOM 6775 CG PHE B 44 -22.499 29.744 -44.161 1.00 46.53 C ATOM 6776 CD1 PHE B 44 -22.051 30.882 -43.454 1.00 51.25 C ATOM 6777 CD2 PHE B 44 -23.854 29.671 -44.550 1.00 49.91 C ATOM 6778 CE1 PHE B 44 -22.939 31.904 -43.143 1.00 52.45 C ATOM 6779 CE2 PHE B 44 -24.727 30.699 -44.221 1.00 48.40 C ATOM 6780 CZ PHE B 44 -24.270 31.813 -43.528 1.00 51.36 C ATOM 6781 H PHE B 44 -21.919 28.617 -47.120 1.00 47.55 H ATOM 6782 HA PHE B 44 -20.229 30.158 -45.383 1.00 46.58 H ATOM 6783 HB3 PHE B 44 -20.973 28.366 -43.670 1.00 48.77 H ATOM 6784 HB2 PHE B 44 -22.041 27.783 -44.916 1.00 48.77 H ATOM 6785 HD1 PHE B 44 -21.015 30.966 -43.157 1.00 51.25 H ATOM 6786 HD2 PHE B 44 -24.222 28.816 -45.096 1.00 49.91 H ATOM 6787 HE1 PHE B 44 -22.593 32.771 -42.600 1.00 52.45 H ATOM 6788 HE2 PHE B 44 -25.766 30.634 -44.507 1.00 48.40 H ATOM 6789 HZ PHE B 44 -24.955 32.610 -43.278 1.00 51.36 H ATOM 6790 N THR B 45 -18.883 27.454 -46.503 1.00 45.06 N ATOM 6791 CA THR B 45 -17.562 26.840 -46.689 1.00 44.49 C ATOM 6792 C THR B 45 -16.531 27.863 -47.213 1.00 45.16 C ATOM 6793 O THR B 45 -15.389 27.832 -46.755 1.00 43.34 O ATOM 6794 CB THR B 45 -17.630 25.632 -47.667 1.00 46.45 C ATOM 6795 OG1 THR B 45 -18.287 24.575 -46.999 1.00 49.08 O ATOM 6796 CG2 THR B 45 -16.298 25.082 -48.217 1.00 45.05 C ATOM 6797 H THR B 45 -19.579 27.231 -47.200 1.00 45.06 H ATOM 6798 HA THR B 45 -17.212 26.482 -45.718 1.00 44.49 H ATOM 6799 HB THR B 45 -18.252 25.898 -48.521 1.00 46.45 H ATOM 6800 HG1 THR B 45 -18.108 23.755 -47.471 1.00 49.08 H ATOM 6801 HG21 THR B 45 -16.470 24.223 -48.863 1.00 45.05 H ATOM 6802 HG22 THR B 45 -15.765 25.815 -48.824 1.00 45.05 H ATOM 6803 HG23 THR B 45 -15.637 24.763 -47.412 1.00 45.05 H ATOM 6804 N ASN B 46 -16.955 28.767 -48.116 1.00 45.99 N ATOM 6805 CA ASN B 46 -16.129 29.856 -48.653 1.00 46.05 C ATOM 6806 C ASN B 46 -15.855 30.957 -47.609 1.00 46.51 C ATOM 6807 O ASN B 46 -14.767 31.531 -47.634 1.00 49.89 O ATOM 6808 CB ASN B 46 -16.777 30.458 -49.924 1.00 46.08 C ATOM 6809 CG ASN B 46 -16.931 29.475 -51.093 1.00 48.15 C ATOM 6810 OD1 ASN B 46 -16.237 28.463 -51.179 1.00 53.21 O ATOM 6811 ND2 ASN B 46 -17.846 29.778 -52.014 1.00 46.07 N ATOM 6812 H ASN B 46 -17.908 28.725 -48.453 1.00 45.99 H ATOM 6813 HA ASN B 46 -15.167 29.423 -48.934 1.00 46.05 H ATOM 6814 HB3 ASN B 46 -16.166 31.286 -50.286 1.00 46.08 H ATOM 6815 HB2 ASN B 46 -17.752 30.883 -49.686 1.00 46.08 H ATOM 6816 HD22 ASN B 46 -17.991 29.170 -52.805 1.00 46.07 H ATOM 6817 HD21 ASN B 46 -18.396 30.627 -51.949 1.00 46.07 H ATOM 6818 N VAL B 47 -16.812 31.206 -46.695 1.00 46.49 N ATOM 6819 CA VAL B 47 -16.661 32.116 -45.555 1.00 46.50 C ATOM 6820 C VAL B 47 -15.642 31.588 -44.522 1.00 45.79 C ATOM 6821 O VAL B 47 -14.791 32.361 -44.088 1.00 45.09 O ATOM 6822 CB VAL B 47 -18.032 32.416 -44.873 1.00 46.62 C ATOM 6823 CG1 VAL B 47 -17.966 33.040 -43.463 1.00 46.01 C ATOM 6824 CG2 VAL B 47 -18.915 33.304 -45.769 1.00 45.80 C ATOM 6825 H VAL B 47 -17.695 30.717 -46.761 1.00 46.49 H ATOM 6826 HA VAL B 47 -16.265 33.059 -45.938 1.00 46.50 H ATOM 6827 HB VAL B 47 -18.551 31.466 -44.759 1.00 46.62 H ATOM 6828 HG11 VAL B 47 -18.957 33.337 -43.118 1.00 46.01 H ATOM 6829 HG12 VAL B 47 -17.583 32.334 -42.728 1.00 46.01 H ATOM 6830 HG13 VAL B 47 -17.332 33.928 -43.448 1.00 46.01 H ATOM 6831 HG21 VAL B 47 -19.922 33.400 -45.362 1.00 45.80 H ATOM 6832 HG22 VAL B 47 -18.498 34.308 -45.858 1.00 45.80 H ATOM 6833 HG23 VAL B 47 -19.011 32.903 -46.776 1.00 45.80 H ATOM 6834 N ILE B 48 -15.710 30.284 -44.193 1.00 45.61 N ATOM 6835 CA ILE B 48 -14.760 29.597 -43.306 1.00 45.30 C ATOM 6836 C ILE B 48 -13.339 29.498 -43.905 1.00 45.56 C ATOM 6837 O ILE B 48 -12.370 29.627 -43.155 1.00 45.36 O ATOM 6838 CB ILE B 48 -15.283 28.184 -42.893 1.00 44.67 C ATOM 6839 CG1 ILE B 48 -16.487 28.324 -41.933 1.00 46.20 C ATOM 6840 CG2 ILE B 48 -14.233 27.234 -42.267 1.00 40.45 C ATOM 6841 CD1 ILE B 48 -17.316 27.041 -41.773 1.00 41.37 C ATOM 6842 H ILE B 48 -16.445 29.710 -44.584 1.00 45.61 H ATOM 6843 HA ILE B 48 -14.678 30.198 -42.398 1.00 45.30 H ATOM 6844 HB ILE B 48 -15.647 27.699 -43.801 1.00 44.67 H ATOM 6845 HG13 ILE B 48 -17.155 29.114 -42.276 1.00 46.20 H ATOM 6846 HG12 ILE B 48 -16.133 28.649 -40.953 1.00 46.20 H ATOM 6847 HG21 ILE B 48 -14.689 26.308 -41.920 1.00 40.45 H ATOM 6848 HG22 ILE B 48 -13.458 26.946 -42.978 1.00 40.45 H ATOM 6849 HG23 ILE B 48 -13.747 27.694 -41.409 1.00 40.45 H ATOM 6850 HD11 ILE B 48 -18.369 27.282 -41.637 1.00 41.37 H ATOM 6851 HD12 ILE B 48 -17.240 26.393 -42.646 1.00 41.37 H ATOM 6852 HD13 ILE B 48 -16.991 26.469 -40.902 1.00 41.37 H ATOM 6853 N GLN B 49 -13.243 29.326 -45.237 1.00 45.65 N ATOM 6854 CA GLN B 49 -11.989 29.351 -45.995 1.00 46.89 C ATOM 6855 C GLN B 49 -11.301 30.725 -45.920 1.00 46.50 C ATOM 6856 O GLN B 49 -10.107 30.780 -45.635 1.00 49.11 O ATOM 6857 CB GLN B 49 -12.253 28.908 -47.456 1.00 47.23 C ATOM 6858 CG GLN B 49 -11.011 28.798 -48.372 1.00 47.81 C ATOM 6859 CD GLN B 49 -10.036 27.688 -47.965 1.00 53.71 C ATOM 6860 OE1 GLN B 49 -10.449 26.594 -47.588 1.00 56.18 O ATOM 6861 NE2 GLN B 49 -8.732 27.947 -48.078 1.00 50.19 N ATOM 6862 H GLN B 49 -14.086 29.207 -45.782 1.00 45.65 H ATOM 6863 HA GLN B 49 -11.322 28.628 -45.533 1.00 46.89 H ATOM 6864 HB3 GLN B 49 -12.953 29.602 -47.917 1.00 47.23 H ATOM 6865 HB2 GLN B 49 -12.767 27.947 -47.452 1.00 47.23 H ATOM 6866 HG3 GLN B 49 -10.490 29.755 -48.426 1.00 47.81 H ATOM 6867 HG2 GLN B 49 -11.341 28.581 -49.388 1.00 47.81 H ATOM 6868 HE22 GLN B 49 -8.049 27.238 -47.847 1.00 50.19 H ATOM 6869 HE21 GLN B 49 -8.414 28.845 -48.428 1.00 50.19 H ATOM 6870 N ALA B 50 -12.082 31.797 -46.132 1.00 46.34 N ATOM 6871 CA ALA B 50 -11.632 33.186 -46.083 1.00 46.23 C ATOM 6872 C ALA B 50 -11.208 33.665 -44.683 1.00 46.98 C ATOM 6873 O ALA B 50 -10.254 34.437 -44.594 1.00 48.71 O ATOM 6874 CB ALA B 50 -12.737 34.080 -46.655 1.00 45.40 C ATOM 6875 H ALA B 50 -13.057 31.657 -46.362 1.00 46.34 H ATOM 6876 HA ALA B 50 -10.761 33.268 -46.736 1.00 46.23 H ATOM 6877 HB1 ALA B 50 -12.438 35.127 -46.647 1.00 45.40 H ATOM 6878 HB2 ALA B 50 -12.964 33.814 -47.688 1.00 45.40 H ATOM 6879 HB3 ALA B 50 -13.656 33.985 -46.077 1.00 45.40 H ATOM 6880 N LEU B 51 -11.885 33.178 -43.626 1.00 49.57 N ATOM 6881 CA LEU B 51 -11.526 33.401 -42.218 1.00 49.76 C ATOM 6882 C LEU B 51 -10.183 32.756 -41.846 1.00 50.29 C ATOM 6883 O LEU B 51 -9.396 33.377 -41.131 1.00 51.88 O ATOM 6884 CB LEU B 51 -12.637 32.848 -41.295 1.00 50.15 C ATOM 6885 CG LEU B 51 -13.895 33.733 -41.188 1.00 50.96 C ATOM 6886 CD1 LEU B 51 -15.068 32.945 -40.565 1.00 52.23 C ATOM 6887 CD2 LEU B 51 -13.604 35.049 -40.436 1.00 50.82 C ATOM 6888 H LEU B 51 -12.679 32.572 -43.788 1.00 49.57 H ATOM 6889 HA LEU B 51 -11.420 34.474 -42.057 1.00 49.76 H ATOM 6890 HB3 LEU B 51 -12.251 32.695 -40.285 1.00 50.15 H ATOM 6891 HB2 LEU B 51 -12.919 31.856 -41.650 1.00 50.15 H ATOM 6892 HG LEU B 51 -14.199 34.011 -42.198 1.00 50.96 H ATOM 6893 HD11 LEU B 51 -15.618 33.517 -39.819 1.00 52.23 H ATOM 6894 HD12 LEU B 51 -15.785 32.660 -41.332 1.00 52.23 H ATOM 6895 HD13 LEU B 51 -14.735 32.025 -40.083 1.00 52.23 H ATOM 6896 HD21 LEU B 51 -13.807 35.909 -41.074 1.00 50.82 H ATOM 6897 HD22 LEU B 51 -14.207 35.162 -39.535 1.00 50.82 H ATOM 6898 HD23 LEU B 51 -12.563 35.126 -40.119 1.00 50.82 H ATOM 6899 N GLY B 52 -9.946 31.534 -42.350 1.00 50.76 N ATOM 6900 CA GLY B 52 -8.729 30.768 -42.106 1.00 50.32 C ATOM 6901 C GLY B 52 -7.526 31.349 -42.858 1.00 51.91 C ATOM 6902 O GLY B 52 -6.426 31.355 -42.312 1.00 49.81 O ATOM 6903 H GLY B 52 -10.652 31.095 -42.925 1.00 50.76 H ATOM 6904 HA3 GLY B 52 -8.908 29.760 -42.464 1.00 50.32 H ATOM 6905 HA2 GLY B 52 -8.522 30.708 -41.037 1.00 50.32 H ATOM 6906 N GLU B 53 -7.740 31.871 -44.079 1.00 53.83 N ATOM 6907 CA GLU B 53 -6.741 32.583 -44.881 1.00 55.35 C ATOM 6908 C GLU B 53 -6.317 33.931 -44.267 1.00 55.80 C ATOM 6909 O GLU B 53 -5.138 34.273 -44.352 1.00 55.87 O ATOM 6910 CB GLU B 53 -7.270 32.770 -46.318 1.00 56.13 C ATOM 6911 CG GLU B 53 -7.246 31.467 -47.151 1.00 59.16 C ATOM 6912 CD GLU B 53 -7.903 31.552 -48.541 1.00 64.15 C ATOM 6913 OE1 GLU B 53 -8.573 32.565 -48.845 1.00 67.74 O ATOM 6914 OE2 GLU B 53 -7.731 30.571 -49.296 1.00 65.30 O1- ATOM 6915 H GLU B 53 -8.663 31.801 -44.488 1.00 53.83 H ATOM 6916 HA GLU B 53 -5.844 31.962 -44.926 1.00 55.35 H ATOM 6917 HB3 GLU B 53 -6.691 33.537 -46.838 1.00 56.13 H ATOM 6918 HB2 GLU B 53 -8.290 33.153 -46.262 1.00 56.13 H ATOM 6919 HG3 GLU B 53 -7.730 30.660 -46.601 1.00 59.16 H ATOM 6920 HG2 GLU B 53 -6.209 31.154 -47.281 1.00 59.16 H ATOM 6921 N HIS B 54 -7.266 34.645 -43.634 1.00 56.68 N ATOM 6922 CA HIS B 54 -7.028 35.902 -42.916 1.00 56.82 C ATOM 6923 C HIS B 54 -6.173 35.701 -41.652 1.00 56.76 C ATOM 6924 O HIS B 54 -5.247 36.477 -41.419 1.00 55.72 O ATOM 6925 CB HIS B 54 -8.384 36.553 -42.571 1.00 57.83 C ATOM 6926 CG HIS B 54 -8.322 38.035 -42.298 1.00 61.53 C ATOM 6927 ND1 HIS B 54 -7.942 38.562 -41.060 1.00 67.20 N ATOM 6928 CD2 HIS B 54 -8.624 39.078 -43.150 1.00 63.06 C ATOM 6929 CE1 HIS B 54 -8.030 39.877 -41.207 1.00 68.67 C ATOM 6930 NE2 HIS B 54 -8.435 40.240 -42.424 1.00 66.65 N ATOM 6931 H HIS B 54 -8.214 34.294 -43.610 1.00 56.68 H ATOM 6932 HA HIS B 54 -6.492 36.562 -43.601 1.00 56.82 H ATOM 6933 HB3 HIS B 54 -8.850 36.059 -41.717 1.00 57.83 H ATOM 6934 HB2 HIS B 54 -9.078 36.419 -43.397 1.00 57.83 H ATOM 6935 HD2 HIS B 54 -8.961 39.086 -44.176 1.00 63.06 H ATOM 6936 HE1 HIS B 54 -7.812 40.581 -40.417 1.00 68.67 H ATOM 6937 HE2 HIS B 54 -8.598 41.185 -42.747 1.00 66.65 H ATOM 6938 N LEU B 55 -6.491 34.645 -40.885 1.00 56.18 N ATOM 6939 CA LEU B 55 -5.797 34.247 -39.658 1.00 54.72 C ATOM 6940 C LEU B 55 -4.487 33.469 -39.912 1.00 56.69 C ATOM 6941 O LEU B 55 -3.768 33.207 -38.947 1.00 56.42 O ATOM 6942 CB LEU B 55 -6.783 33.438 -38.782 1.00 52.33 C ATOM 6943 CG LEU B 55 -7.929 34.291 -38.184 1.00 50.51 C ATOM 6944 CD1 LEU B 55 -9.062 33.400 -37.634 1.00 46.19 C ATOM 6945 CD2 LEU B 55 -7.419 35.297 -37.130 1.00 46.49 C ATOM 6946 H LEU B 55 -7.279 34.068 -41.150 1.00 56.18 H ATOM 6947 HA LEU B 55 -5.513 35.150 -39.117 1.00 54.72 H ATOM 6948 HB3 LEU B 55 -6.256 32.941 -37.965 1.00 52.33 H ATOM 6949 HB2 LEU B 55 -7.201 32.636 -39.393 1.00 52.33 H ATOM 6950 HG LEU B 55 -8.373 34.872 -38.993 1.00 50.51 H ATOM 6951 HD11 LEU B 55 -10.014 33.650 -38.104 1.00 46.19 H ATOM 6952 HD12 LEU B 55 -8.878 32.344 -37.826 1.00 46.19 H ATOM 6953 HD13 LEU B 55 -9.195 33.502 -36.558 1.00 46.19 H ATOM 6954 HD21 LEU B 55 -8.083 35.380 -36.269 1.00 46.49 H ATOM 6955 HD22 LEU B 55 -6.436 35.023 -36.749 1.00 46.49 H ATOM 6956 HD23 LEU B 55 -7.336 36.296 -37.559 1.00 46.49 H ATOM 6957 N LYS B 56 -4.190 33.145 -41.186 1.00 58.84 N ATOM 6958 CA LYS B 56 -2.986 32.461 -41.681 1.00 58.97 C ATOM 6959 C LYS B 56 -2.848 31.014 -41.161 1.00 58.80 C ATOM 6960 O LYS B 56 -1.742 30.569 -40.851 1.00 60.94 O ATOM 6961 CB LYS B 56 -1.716 33.318 -41.446 1.00 59.62 C ATOM 6962 CG LYS B 56 -1.770 34.700 -42.121 0.00 58.99 C ATOM 6963 CD LYS B 56 -0.471 35.494 -41.925 0.00 59.02 C ATOM 6964 CE LYS B 56 -0.528 36.882 -42.582 0.00 58.98 C ATOM 6965 NZ LYS B 56 0.731 37.626 -42.394 0.00 58.97 N1+ ATOM 6966 H LYS B 56 -4.851 33.406 -41.904 1.00 58.84 H ATOM 6967 HA LYS B 56 -3.125 32.369 -42.759 1.00 58.97 H ATOM 6968 HB3 LYS B 56 -0.847 32.787 -41.835 1.00 59.62 H ATOM 6969 HB2 LYS B 56 -1.536 33.443 -40.378 1.00 59.62 H ATOM 6970 HG3 LYS B 56 -2.605 35.276 -41.719 1.00 58.99 H ATOM 6971 HG2 LYS B 56 -1.969 34.577 -43.186 1.00 58.99 H ATOM 6972 HD3 LYS B 56 0.362 34.922 -42.336 1.00 59.02 H ATOM 6973 HD2 LYS B 56 -0.275 35.598 -40.856 1.00 59.02 H ATOM 6974 HE3 LYS B 56 -1.347 37.466 -42.161 1.00 58.98 H ATOM 6975 HE2 LYS B 56 -0.719 36.785 -43.652 1.00 58.98 H ATOM 6976 HZ1 LYS B 56 1.494 37.110 -42.807 1.00 58.97 H ATOM 6977 HZ2 LYS B 56 0.658 38.531 -42.838 1.00 58.97 H ATOM 6978 HZ3 LYS B 56 0.906 37.751 -41.407 1.00 58.97 H ATOM 6979 N LEU B 57 -3.986 30.308 -41.083 1.00 58.64 N ATOM 6980 CA LEU B 57 -4.088 28.915 -40.653 1.00 57.12 C ATOM 6981 C LEU B 57 -3.784 27.966 -41.822 1.00 55.76 C ATOM 6982 O LEU B 57 -4.125 28.275 -42.965 1.00 56.49 O ATOM 6983 CB LEU B 57 -5.518 28.658 -40.125 1.00 57.00 C ATOM 6984 CG LEU B 57 -5.934 29.536 -38.922 1.00 56.02 C ATOM 6985 CD1 LEU B 57 -7.422 29.328 -38.580 1.00 56.16 C ATOM 6986 CD2 LEU B 57 -5.021 29.342 -37.694 1.00 50.52 C ATOM 6987 H LEU B 57 -4.851 30.738 -41.384 1.00 58.64 H ATOM 6988 HA LEU B 57 -3.366 28.730 -39.856 1.00 57.12 H ATOM 6989 HB3 LEU B 57 -5.620 27.608 -39.845 1.00 57.00 H ATOM 6990 HB2 LEU B 57 -6.227 28.817 -40.940 1.00 57.00 H ATOM 6991 HG LEU B 57 -5.841 30.579 -39.227 1.00 56.02 H ATOM 6992 HD11 LEU B 57 -7.942 30.285 -38.551 1.00 56.16 H ATOM 6993 HD12 LEU B 57 -7.931 28.710 -39.320 1.00 56.16 H ATOM 6994 HD13 LEU B 57 -7.572 28.847 -37.614 1.00 56.16 H ATOM 6995 HD21 LEU B 57 -5.578 29.325 -36.757 1.00 50.52 H ATOM 6996 HD22 LEU B 57 -4.455 28.412 -37.748 1.00 50.52 H ATOM 6997 HD23 LEU B 57 -4.304 30.160 -37.618 1.00 50.52 H ATOM 6998 N ARG B 58 -3.193 26.802 -41.500 1.00 54.86 N ATOM 6999 CA ARG B 58 -2.967 25.703 -42.446 1.00 54.87 C ATOM 7000 C ARG B 58 -4.297 25.042 -42.858 1.00 53.75 C ATOM 7001 O ARG B 58 -5.253 25.065 -42.084 1.00 53.65 O ATOM 7002 CB ARG B 58 -1.955 24.708 -41.833 1.00 55.85 C ATOM 7003 CG ARG B 58 -2.482 23.819 -40.689 1.00 61.49 C ATOM 7004 CD ARG B 58 -1.347 23.081 -39.958 1.00 66.31 C ATOM 7005 NE ARG B 58 -1.850 22.038 -39.045 1.00 68.64 N ATOM 7006 CZ ARG B 58 -1.870 20.708 -39.258 1.00 72.07 C ATOM 7007 NH1 ARG B 58 -1.385 20.152 -40.378 1.00 75.05 N ATOM 7008 NH2 ARG B 58 -2.393 19.909 -38.320 1.00 73.73 N1+ ATOM 7009 H ARG B 58 -2.947 26.620 -40.539 1.00 54.86 H ATOM 7010 HA ARG B 58 -2.509 26.135 -43.338 1.00 54.87 H ATOM 7011 HB3 ARG B 58 -1.077 25.259 -41.495 1.00 55.85 H ATOM 7012 HB2 ARG B 58 -1.597 24.049 -42.626 1.00 55.85 H ATOM 7013 HG3 ARG B 58 -3.271 23.136 -41.008 1.00 61.49 H ATOM 7014 HG2 ARG B 58 -2.941 24.499 -39.971 1.00 61.49 H ATOM 7015 HD3 ARG B 58 -0.879 23.795 -39.279 1.00 66.31 H ATOM 7016 HD2 ARG B 58 -0.550 22.754 -40.628 1.00 66.31 H ATOM 7017 HE ARG B 58 -2.230 22.373 -38.170 1.00 68.64 H ATOM 7018 HH12 ARG B 58 -1.407 19.152 -40.511 1.00 75.05 H ATOM 7019 HH11 ARG B 58 -1.009 20.742 -41.107 1.00 75.05 H ATOM 7020 HH22 ARG B 58 -2.430 18.910 -38.449 1.00 73.73 H ATOM 7021 HH21 ARG B 58 -2.758 20.304 -37.459 1.00 73.73 H ATOM 7022 N GLN B 59 -4.330 24.475 -44.075 1.00 52.21 N ATOM 7023 CA GLN B 59 -5.542 23.971 -44.734 1.00 51.93 C ATOM 7024 C GLN B 59 -6.284 22.851 -43.971 1.00 51.78 C ATOM 7025 O GLN B 59 -7.500 22.737 -44.117 1.00 52.05 O ATOM 7026 CB GLN B 59 -5.170 23.541 -46.173 1.00 50.44 C ATOM 7027 CG GLN B 59 -6.359 23.227 -47.107 1.00 51.82 C ATOM 7028 CD GLN B 59 -7.288 24.428 -47.324 1.00 53.86 C ATOM 7029 OE1 GLN B 59 -6.828 25.528 -47.622 1.00 56.00 O ATOM 7030 NE2 GLN B 59 -8.599 24.225 -47.192 1.00 55.07 N ATOM 7031 H GLN B 59 -3.495 24.481 -44.643 1.00 52.21 H ATOM 7032 HA GLN B 59 -6.224 24.821 -44.787 1.00 51.93 H ATOM 7033 HB3 GLN B 59 -4.514 22.670 -46.131 1.00 50.44 H ATOM 7034 HB2 GLN B 59 -4.575 24.329 -46.637 1.00 50.44 H ATOM 7035 HG3 GLN B 59 -6.927 22.380 -46.725 1.00 51.82 H ATOM 7036 HG2 GLN B 59 -5.976 22.919 -48.079 1.00 51.82 H ATOM 7037 HE22 GLN B 59 -9.245 24.992 -47.334 1.00 55.07 H ATOM 7038 HE21 GLN B 59 -8.967 23.317 -46.943 1.00 55.07 H ATOM 7039 N GLN B 60 -5.556 22.076 -43.150 1.00 51.28 N ATOM 7040 CA GLN B 60 -6.094 21.030 -42.280 1.00 52.53 C ATOM 7041 C GLN B 60 -6.936 21.582 -41.114 1.00 51.36 C ATOM 7042 O GLN B 60 -7.935 20.958 -40.768 1.00 51.03 O ATOM 7043 CB GLN B 60 -4.952 20.136 -41.747 1.00 54.71 C ATOM 7044 CG GLN B 60 -4.228 19.290 -42.820 1.00 61.20 C ATOM 7045 CD GLN B 60 -3.072 19.991 -43.548 1.00 67.85 C ATOM 7046 OE1 GLN B 60 -2.782 21.166 -43.328 1.00 65.90 O ATOM 7047 NE2 GLN B 60 -2.387 19.250 -44.419 1.00 72.04 N ATOM 7048 H GLN B 60 -4.555 22.216 -43.103 1.00 51.28 H ATOM 7049 HA GLN B 60 -6.754 20.406 -42.886 1.00 52.53 H ATOM 7050 HB3 GLN B 60 -5.382 19.439 -41.025 1.00 54.71 H ATOM 7051 HB2 GLN B 60 -4.239 20.730 -41.174 1.00 54.71 H ATOM 7052 HG3 GLN B 60 -4.943 18.912 -43.551 1.00 61.20 H ATOM 7053 HG2 GLN B 60 -3.803 18.412 -42.332 1.00 61.20 H ATOM 7054 HE22 GLN B 60 -1.610 19.654 -44.920 1.00 72.04 H ATOM 7055 HE21 GLN B 60 -2.640 18.287 -44.586 1.00 72.04 H ATOM 7056 N VAL B 61 -6.543 22.741 -40.553 1.00 49.58 N ATOM 7057 CA VAL B 61 -7.281 23.459 -39.503 1.00 48.52 C ATOM 7058 C VAL B 61 -8.574 24.098 -40.046 1.00 47.87 C ATOM 7059 O VAL B 61 -9.591 24.089 -39.352 1.00 46.71 O ATOM 7060 CB VAL B 61 -6.400 24.567 -38.851 1.00 49.52 C ATOM 7061 CG1 VAL B 61 -7.139 25.548 -37.913 1.00 48.85 C ATOM 7062 CG2 VAL B 61 -5.223 23.939 -38.092 1.00 49.32 C ATOM 7063 H VAL B 61 -5.722 23.209 -40.909 1.00 49.58 H ATOM 7064 HA VAL B 61 -7.562 22.739 -38.731 1.00 48.52 H ATOM 7065 HB VAL B 61 -5.969 25.172 -39.648 1.00 49.52 H ATOM 7066 HG11 VAL B 61 -6.438 26.213 -37.406 1.00 48.85 H ATOM 7067 HG12 VAL B 61 -7.838 26.189 -38.451 1.00 48.85 H ATOM 7068 HG13 VAL B 61 -7.697 25.011 -37.147 1.00 48.85 H ATOM 7069 HG21 VAL B 61 -4.545 24.706 -37.719 1.00 49.32 H ATOM 7070 HG22 VAL B 61 -5.583 23.362 -37.241 1.00 49.32 H ATOM 7071 HG23 VAL B 61 -4.642 23.268 -38.723 1.00 49.32 H ATOM 7072 N ILE B 62 -8.512 24.602 -41.289 1.00 46.22 N ATOM 7073 CA ILE B 62 -9.646 25.158 -42.027 1.00 46.48 C ATOM 7074 C ILE B 62 -10.680 24.068 -42.382 1.00 45.11 C ATOM 7075 O ILE B 62 -11.881 24.313 -42.267 1.00 44.55 O ATOM 7076 CB ILE B 62 -9.176 25.862 -43.334 1.00 47.43 C ATOM 7077 CG1 ILE B 62 -8.147 26.972 -43.013 1.00 48.74 C ATOM 7078 CG2 ILE B 62 -10.344 26.430 -44.168 1.00 45.19 C ATOM 7079 CD1 ILE B 62 -7.599 27.725 -44.237 1.00 53.58 C ATOM 7080 H ILE B 62 -7.632 24.575 -41.786 1.00 46.22 H ATOM 7081 HA ILE B 62 -10.138 25.895 -41.388 1.00 46.48 H ATOM 7082 HB ILE B 62 -8.668 25.126 -43.958 1.00 47.43 H ATOM 7083 HG13 ILE B 62 -7.297 26.559 -42.475 1.00 48.74 H ATOM 7084 HG12 ILE B 62 -8.603 27.672 -42.318 1.00 48.74 H ATOM 7085 HG21 ILE B 62 -9.972 26.921 -45.062 1.00 45.19 H ATOM 7086 HG22 ILE B 62 -11.027 25.658 -44.520 1.00 45.19 H ATOM 7087 HG23 ILE B 62 -10.920 27.159 -43.598 1.00 45.19 H ATOM 7088 HD11 ILE B 62 -6.644 28.195 -44.006 1.00 53.58 H ATOM 7089 HD12 ILE B 62 -7.441 27.054 -45.081 1.00 53.58 H ATOM 7090 HD13 ILE B 62 -8.280 28.514 -44.557 1.00 53.58 H ATOM 7091 N ALA B 63 -10.186 22.877 -42.760 1.00 44.34 N ATOM 7092 CA ALA B 63 -10.984 21.686 -43.030 1.00 44.73 C ATOM 7093 C ALA B 63 -11.670 21.121 -41.776 1.00 44.98 C ATOM 7094 O ALA B 63 -12.825 20.713 -41.875 1.00 46.64 O ATOM 7095 CB ALA B 63 -10.092 20.633 -43.697 1.00 43.65 C ATOM 7096 H ALA B 63 -9.185 22.768 -42.856 1.00 44.34 H ATOM 7097 HA ALA B 63 -11.766 21.962 -43.741 1.00 44.73 H ATOM 7098 HB1 ALA B 63 -10.652 19.725 -43.910 1.00 43.65 H ATOM 7099 HB2 ALA B 63 -9.695 21.003 -44.642 1.00 43.65 H ATOM 7100 HB3 ALA B 63 -9.247 20.358 -43.067 1.00 43.65 H ATOM 7101 N THR B 64 -10.972 21.137 -40.623 1.00 43.39 N ATOM 7102 CA THR B 64 -11.502 20.736 -39.312 1.00 43.67 C ATOM 7103 C THR B 64 -12.656 21.652 -38.855 1.00 43.95 C ATOM 7104 O THR B 64 -13.658 21.143 -38.357 1.00 43.88 O ATOM 7105 CB THR B 64 -10.389 20.744 -38.223 1.00 43.65 C ATOM 7106 OG1 THR B 64 -9.448 19.729 -38.502 1.00 43.44 O ATOM 7107 CG2 THR B 64 -10.841 20.532 -36.770 1.00 39.80 C ATOM 7108 H THR B 64 -10.012 21.455 -40.629 1.00 43.39 H ATOM 7109 HA THR B 64 -11.896 19.721 -39.403 1.00 43.67 H ATOM 7110 HB THR B 64 -9.848 21.688 -38.273 1.00 43.65 H ATOM 7111 HG1 THR B 64 -8.798 19.715 -37.794 1.00 43.44 H ATOM 7112 HG21 THR B 64 -9.987 20.452 -36.096 1.00 39.80 H ATOM 7113 HG22 THR B 64 -11.440 21.368 -36.414 1.00 39.80 H ATOM 7114 HG23 THR B 64 -11.432 19.622 -36.668 1.00 39.80 H ATOM 7115 N ALA B 65 -12.516 22.969 -39.091 1.00 42.97 N ATOM 7116 CA ALA B 65 -13.545 23.978 -38.846 1.00 43.89 C ATOM 7117 C ALA B 65 -14.785 23.816 -39.743 1.00 42.84 C ATOM 7118 O ALA B 65 -15.904 24.003 -39.268 1.00 42.84 O ATOM 7119 CB ALA B 65 -12.928 25.368 -39.041 1.00 43.27 C ATOM 7120 H ALA B 65 -11.654 23.308 -39.497 1.00 42.97 H ATOM 7121 HA ALA B 65 -13.861 23.885 -37.805 1.00 43.89 H ATOM 7122 HB1 ALA B 65 -13.642 26.155 -38.800 1.00 43.27 H ATOM 7123 HB2 ALA B 65 -12.057 25.492 -38.399 1.00 43.27 H ATOM 7124 HB3 ALA B 65 -12.600 25.530 -40.067 1.00 43.27 H ATOM 7125 N THR B 66 -14.576 23.438 -41.015 1.00 44.04 N ATOM 7126 CA THR B 66 -15.661 23.183 -41.964 1.00 42.98 C ATOM 7127 C THR B 66 -16.450 21.898 -41.632 1.00 43.71 C ATOM 7128 O THR B 66 -17.664 21.876 -41.832 1.00 45.23 O ATOM 7129 CB THR B 66 -15.153 23.100 -43.425 1.00 43.23 C ATOM 7130 OG1 THR B 66 -14.417 24.266 -43.733 1.00 40.93 O ATOM 7131 CG2 THR B 66 -16.271 22.979 -44.475 1.00 37.39 C ATOM 7132 H THR B 66 -13.633 23.296 -41.349 1.00 44.04 H ATOM 7133 HA THR B 66 -16.360 24.021 -41.900 1.00 42.98 H ATOM 7134 HB THR B 66 -14.470 22.256 -43.537 1.00 43.23 H ATOM 7135 HG1 THR B 66 -13.641 24.301 -43.163 1.00 40.93 H ATOM 7136 HG21 THR B 66 -15.901 23.202 -45.473 1.00 37.39 H ATOM 7137 HG22 THR B 66 -16.692 21.974 -44.495 1.00 37.39 H ATOM 7138 HG23 THR B 66 -17.081 23.681 -44.275 1.00 37.39 H ATOM 7139 N VAL B 67 -15.765 20.884 -41.074 1.00 44.80 N ATOM 7140 CA VAL B 67 -16.377 19.659 -40.560 1.00 44.29 C ATOM 7141 C VAL B 67 -17.213 19.902 -39.285 1.00 45.44 C ATOM 7142 O VAL B 67 -18.305 19.346 -39.201 1.00 46.38 O ATOM 7143 CB VAL B 67 -15.322 18.536 -40.328 1.00 45.49 C ATOM 7144 CG1 VAL B 67 -15.797 17.355 -39.455 1.00 44.52 C ATOM 7145 CG2 VAL B 67 -14.819 17.989 -41.676 1.00 40.81 C ATOM 7146 H VAL B 67 -14.765 20.968 -40.949 1.00 44.80 H ATOM 7147 HA VAL B 67 -17.069 19.302 -41.326 1.00 44.29 H ATOM 7148 HB VAL B 67 -14.460 18.979 -39.827 1.00 45.49 H ATOM 7149 HG11 VAL B 67 -15.088 16.530 -39.474 1.00 44.52 H ATOM 7150 HG12 VAL B 67 -15.907 17.647 -38.411 1.00 44.52 H ATOM 7151 HG13 VAL B 67 -16.752 16.963 -39.806 1.00 44.52 H ATOM 7152 HG21 VAL B 67 -13.989 17.296 -41.549 1.00 40.81 H ATOM 7153 HG22 VAL B 67 -15.612 17.452 -42.193 1.00 40.81 H ATOM 7154 HG23 VAL B 67 -14.481 18.785 -42.337 1.00 40.81 H ATOM 7155 N TYR B 68 -16.739 20.753 -38.352 1.00 44.37 N ATOM 7156 CA TYR B 68 -17.484 21.152 -37.145 1.00 44.42 C ATOM 7157 C TYR B 68 -18.820 21.845 -37.466 1.00 45.45 C ATOM 7158 O TYR B 68 -19.824 21.556 -36.814 1.00 44.68 O ATOM 7159 CB TYR B 68 -16.648 22.110 -36.270 1.00 44.86 C ATOM 7160 CG TYR B 68 -15.382 21.611 -35.597 1.00 46.15 C ATOM 7161 CD1 TYR B 68 -14.991 20.252 -35.602 1.00 45.09 C ATOM 7162 CD2 TYR B 68 -14.594 22.558 -34.912 1.00 44.88 C ATOM 7163 CE1 TYR B 68 -13.825 19.851 -34.921 1.00 46.97 C ATOM 7164 CE2 TYR B 68 -13.431 22.158 -34.236 1.00 45.26 C ATOM 7165 CZ TYR B 68 -13.043 20.808 -34.245 1.00 47.75 C ATOM 7166 OH TYR B 68 -11.893 20.442 -33.614 1.00 42.37 O ATOM 7167 H TYR B 68 -15.824 21.168 -38.471 1.00 44.37 H ATOM 7168 HA TYR B 68 -17.713 20.249 -36.577 1.00 44.42 H ATOM 7169 HB3 TYR B 68 -17.275 22.481 -35.458 1.00 44.86 H ATOM 7170 HB2 TYR B 68 -16.377 22.986 -36.858 1.00 44.86 H ATOM 7171 HD1 TYR B 68 -15.577 19.504 -36.114 1.00 45.09 H ATOM 7172 HD2 TYR B 68 -14.886 23.597 -34.896 1.00 44.88 H ATOM 7173 HE1 TYR B 68 -13.533 18.812 -34.923 1.00 46.97 H ATOM 7174 HE2 TYR B 68 -12.834 22.889 -33.715 1.00 45.26 H ATOM 7175 HH TYR B 68 -11.673 19.511 -33.724 1.00 42.37 H ATOM 7176 N PHE B 69 -18.792 22.725 -38.481 1.00 44.39 N ATOM 7177 CA PHE B 69 -19.944 23.449 -39.015 1.00 42.67 C ATOM 7178 C PHE B 69 -20.982 22.489 -39.628 1.00 43.34 C ATOM 7179 O PHE B 69 -22.168 22.612 -39.327 1.00 45.20 O ATOM 7180 CB PHE B 69 -19.419 24.498 -40.023 1.00 44.14 C ATOM 7181 CG PHE B 69 -20.442 25.450 -40.618 1.00 42.48 C ATOM 7182 CD1 PHE B 69 -21.235 25.059 -41.718 1.00 39.81 C ATOM 7183 CD2 PHE B 69 -20.694 26.691 -39.996 1.00 43.31 C ATOM 7184 CE1 PHE B 69 -22.217 25.912 -42.203 1.00 39.50 C ATOM 7185 CE2 PHE B 69 -21.670 27.536 -40.506 1.00 39.73 C ATOM 7186 CZ PHE B 69 -22.431 27.145 -41.600 1.00 42.22 C ATOM 7187 H PHE B 69 -17.911 22.907 -38.942 1.00 44.39 H ATOM 7188 HA PHE B 69 -20.418 23.978 -38.185 1.00 42.67 H ATOM 7189 HB3 PHE B 69 -18.910 23.996 -40.846 1.00 44.14 H ATOM 7190 HB2 PHE B 69 -18.652 25.102 -39.537 1.00 44.14 H ATOM 7191 HD1 PHE B 69 -21.083 24.096 -42.184 1.00 39.81 H ATOM 7192 HD2 PHE B 69 -20.118 26.997 -39.135 1.00 43.31 H ATOM 7193 HE1 PHE B 69 -22.822 25.615 -43.047 1.00 39.50 H ATOM 7194 HE2 PHE B 69 -21.849 28.493 -40.039 1.00 39.73 H ATOM 7195 HZ PHE B 69 -23.198 27.800 -41.985 1.00 42.22 H ATOM 7196 N LYS B 70 -20.504 21.526 -40.437 1.00 44.32 N ATOM 7197 CA LYS B 70 -21.319 20.492 -41.078 1.00 44.07 C ATOM 7198 C LYS B 70 -21.982 19.507 -40.108 1.00 46.22 C ATOM 7199 O LYS B 70 -23.131 19.150 -40.350 1.00 44.55 O ATOM 7200 CB LYS B 70 -20.484 19.739 -42.125 1.00 43.60 C ATOM 7201 CG LYS B 70 -20.308 20.536 -43.420 1.00 43.38 C ATOM 7202 CD LYS B 70 -19.502 19.751 -44.463 1.00 45.20 C ATOM 7203 CE LYS B 70 -19.248 20.532 -45.756 1.00 46.40 C ATOM 7204 NZ LYS B 70 -20.482 20.831 -46.507 1.00 46.32 N1+ ATOM 7205 H LYS B 70 -19.513 21.489 -40.630 1.00 44.32 H ATOM 7206 HA LYS B 70 -22.129 21.011 -41.597 1.00 44.07 H ATOM 7207 HB3 LYS B 70 -20.986 18.809 -42.389 1.00 43.60 H ATOM 7208 HB2 LYS B 70 -19.519 19.449 -41.710 1.00 43.60 H ATOM 7209 HG3 LYS B 70 -19.818 21.487 -43.213 1.00 43.38 H ATOM 7210 HG2 LYS B 70 -21.292 20.784 -43.819 1.00 43.38 H ATOM 7211 HD3 LYS B 70 -20.003 18.808 -44.689 1.00 45.20 H ATOM 7212 HD2 LYS B 70 -18.539 19.480 -44.028 1.00 45.20 H ATOM 7213 HE3 LYS B 70 -18.584 19.951 -46.397 1.00 46.40 H ATOM 7214 HE2 LYS B 70 -18.742 21.470 -45.530 1.00 46.40 H ATOM 7215 HZ1 LYS B 70 -20.240 21.319 -47.358 1.00 46.32 H ATOM 7216 HZ2 LYS B 70 -20.958 19.969 -46.738 1.00 46.32 H ATOM 7217 HZ3 LYS B 70 -21.082 21.418 -45.946 1.00 46.32 H ATOM 7218 N ARG B 71 -21.281 19.110 -39.030 1.00 48.54 N ATOM 7219 CA ARG B 71 -21.827 18.270 -37.957 1.00 49.35 C ATOM 7220 C ARG B 71 -22.964 18.965 -37.189 1.00 49.77 C ATOM 7221 O ARG B 71 -23.918 18.286 -36.808 1.00 48.71 O ATOM 7222 CB ARG B 71 -20.713 17.871 -36.970 1.00 50.46 C ATOM 7223 CG ARG B 71 -19.697 16.871 -37.540 1.00 52.96 C ATOM 7224 CD ARG B 71 -18.522 16.658 -36.577 1.00 53.27 C ATOM 7225 NE ARG B 71 -17.583 15.645 -37.082 1.00 57.28 N ATOM 7226 CZ ARG B 71 -16.509 15.147 -36.444 1.00 57.40 C ATOM 7227 NH1 ARG B 71 -16.164 15.537 -35.207 1.00 56.51 N ATOM 7228 NH2 ARG B 71 -15.761 14.231 -37.069 1.00 51.02 N1+ ATOM 7229 H ARG B 71 -20.328 19.427 -38.912 1.00 48.54 H ATOM 7230 HA ARG B 71 -22.239 17.363 -38.403 1.00 49.35 H ATOM 7231 HB3 ARG B 71 -21.157 17.413 -36.084 1.00 50.46 H ATOM 7232 HB2 ARG B 71 -20.198 18.765 -36.615 1.00 50.46 H ATOM 7233 HG3 ARG B 71 -19.320 17.244 -38.489 1.00 52.96 H ATOM 7234 HG2 ARG B 71 -20.180 15.925 -37.784 1.00 52.96 H ATOM 7235 HD3 ARG B 71 -18.880 16.400 -35.579 1.00 53.27 H ATOM 7236 HD2 ARG B 71 -17.962 17.590 -36.485 1.00 53.27 H ATOM 7237 HE ARG B 71 -17.774 15.301 -38.013 1.00 57.28 H ATOM 7238 HH12 ARG B 71 -15.374 15.107 -34.743 1.00 56.51 H ATOM 7239 HH11 ARG B 71 -16.709 16.233 -34.718 1.00 56.51 H ATOM 7240 HH22 ARG B 71 -14.980 13.802 -36.589 1.00 51.02 H ATOM 7241 HH21 ARG B 71 -15.991 13.932 -38.008 1.00 51.02 H ATOM 7242 N PHE B 72 -22.847 20.291 -36.990 1.00 48.90 N ATOM 7243 CA PHE B 72 -23.828 21.098 -36.270 1.00 48.69 C ATOM 7244 C PHE B 72 -25.172 21.194 -37.012 1.00 48.44 C ATOM 7245 O PHE B 72 -26.211 20.898 -36.420 1.00 49.44 O ATOM 7246 CB PHE B 72 -23.221 22.469 -35.890 1.00 48.73 C ATOM 7247 CG PHE B 72 -24.079 23.303 -34.953 1.00 51.46 C ATOM 7248 CD1 PHE B 72 -25.135 24.086 -35.463 1.00 51.34 C ATOM 7249 CD2 PHE B 72 -23.952 23.158 -33.554 1.00 52.77 C ATOM 7250 CE1 PHE B 72 -26.014 24.722 -34.599 1.00 50.49 C ATOM 7251 CE2 PHE B 72 -24.847 23.795 -32.703 1.00 52.32 C ATOM 7252 CZ PHE B 72 -25.877 24.568 -33.226 1.00 50.04 C ATOM 7253 H PHE B 72 -22.030 20.778 -37.333 1.00 48.90 H ATOM 7254 HA PHE B 72 -24.037 20.576 -35.345 1.00 48.69 H ATOM 7255 HB3 PHE B 72 -23.009 23.050 -36.789 1.00 48.73 H ATOM 7256 HB2 PHE B 72 -22.257 22.313 -35.403 1.00 48.73 H ATOM 7257 HD1 PHE B 72 -25.270 24.174 -36.529 1.00 51.34 H ATOM 7258 HD2 PHE B 72 -23.176 22.533 -33.138 1.00 52.77 H ATOM 7259 HE1 PHE B 72 -26.814 25.325 -34.999 1.00 50.49 H ATOM 7260 HE2 PHE B 72 -24.750 23.677 -31.634 1.00 52.32 H ATOM 7261 HZ PHE B 72 -26.578 25.049 -32.561 1.00 50.04 H ATOM 7262 N TYR B 73 -25.114 21.570 -38.300 1.00 48.33 N ATOM 7263 CA TYR B 73 -26.287 21.731 -39.162 1.00 47.44 C ATOM 7264 C TYR B 73 -26.770 20.422 -39.821 1.00 48.04 C ATOM 7265 O TYR B 73 -27.841 20.431 -40.424 1.00 50.10 O ATOM 7266 CB TYR B 73 -26.026 22.874 -40.167 1.00 47.02 C ATOM 7267 CG TYR B 73 -25.845 24.222 -39.484 1.00 47.23 C ATOM 7268 CD1 TYR B 73 -26.923 24.817 -38.792 1.00 45.60 C ATOM 7269 CD2 TYR B 73 -24.587 24.858 -39.486 1.00 48.64 C ATOM 7270 CE1 TYR B 73 -26.731 26.014 -38.073 1.00 47.70 C ATOM 7271 CE2 TYR B 73 -24.395 26.048 -38.761 1.00 46.47 C ATOM 7272 CZ TYR B 73 -25.461 26.620 -38.045 1.00 47.22 C ATOM 7273 OH TYR B 73 -25.253 27.750 -37.314 1.00 52.24 O ATOM 7274 H TYR B 73 -24.219 21.792 -38.716 1.00 48.33 H ATOM 7275 HA TYR B 73 -27.116 22.051 -38.530 1.00 47.44 H ATOM 7276 HB3 TYR B 73 -26.856 22.968 -40.866 1.00 47.02 H ATOM 7277 HB2 TYR B 73 -25.149 22.644 -40.773 1.00 47.02 H ATOM 7278 HD1 TYR B 73 -27.893 24.342 -38.788 1.00 45.60 H ATOM 7279 HD2 TYR B 73 -23.758 24.427 -40.024 1.00 48.64 H ATOM 7280 HE1 TYR B 73 -27.553 26.449 -37.523 1.00 47.70 H ATOM 7281 HE2 TYR B 73 -23.423 26.514 -38.739 1.00 46.47 H ATOM 7282 HH TYR B 73 -26.059 28.103 -36.920 1.00 52.24 H ATOM 7283 N ALA B 74 -26.041 19.307 -39.634 1.00 49.24 N ATOM 7284 CA ALA B 74 -26.512 17.956 -39.959 1.00 49.92 C ATOM 7285 C ALA B 74 -27.589 17.437 -38.986 1.00 52.31 C ATOM 7286 O ALA B 74 -28.342 16.542 -39.370 1.00 54.24 O ATOM 7287 CB ALA B 74 -25.324 16.980 -39.997 1.00 48.88 C ATOM 7288 H ALA B 74 -25.153 19.365 -39.156 1.00 49.24 H ATOM 7289 HA ALA B 74 -26.954 17.976 -40.957 1.00 49.92 H ATOM 7290 HB1 ALA B 74 -25.654 15.943 -40.071 1.00 48.88 H ATOM 7291 HB2 ALA B 74 -24.692 17.170 -40.863 1.00 48.88 H ATOM 7292 HB3 ALA B 74 -24.707 17.060 -39.103 1.00 48.88 H ATOM 7293 N ARG B 75 -27.636 18.000 -37.766 1.00 52.90 N ATOM 7294 CA ARG B 75 -28.506 17.563 -36.675 1.00 55.00 C ATOM 7295 C ARG B 75 -29.581 18.609 -36.316 1.00 55.33 C ATOM 7296 O ARG B 75 -30.675 18.205 -35.922 1.00 56.45 O ATOM 7297 CB ARG B 75 -27.599 17.203 -35.477 1.00 56.22 C ATOM 7298 CG ARG B 75 -28.322 16.613 -34.253 0.00 55.32 C ATOM 7299 CD ARG B 75 -27.337 16.204 -33.145 0.00 55.47 C ATOM 7300 NE ARG B 75 -28.020 15.537 -32.023 0.00 55.42 N ATOM 7301 CZ ARG B 75 -27.465 15.103 -30.875 0.00 55.43 C ATOM 7302 NH1 ARG B 75 -26.155 15.246 -30.612 0.00 55.43 N ATOM 7303 NH2 ARG B 75 -28.246 14.509 -29.964 0.00 55.38 N1+ ATOM 7304 H ARG B 75 -26.981 18.735 -37.541 1.00 52.90 H ATOM 7305 HA ARG B 75 -29.038 16.655 -36.966 1.00 55.00 H ATOM 7306 HB3 ARG B 75 -27.036 18.085 -35.170 1.00 56.22 H ATOM 7307 HB2 ARG B 75 -26.854 16.480 -35.814 1.00 56.22 H ATOM 7308 HG3 ARG B 75 -28.969 15.781 -34.534 1.00 55.32 H ATOM 7309 HG2 ARG B 75 -28.980 17.384 -33.853 1.00 55.32 H ATOM 7310 HD3 ARG B 75 -26.888 17.106 -32.730 1.00 55.47 H ATOM 7311 HD2 ARG B 75 -26.518 15.600 -33.538 1.00 55.47 H ATOM 7312 HE ARG B 75 -29.012 15.395 -32.150 1.00 55.42 H ATOM 7313 HH12 ARG B 75 -25.763 14.915 -29.742 1.00 55.43 H ATOM 7314 HH11 ARG B 75 -25.547 15.692 -31.284 1.00 55.43 H ATOM 7315 HH22 ARG B 75 -27.854 14.177 -29.094 1.00 55.38 H ATOM 7316 HH21 ARG B 75 -29.233 14.389 -30.136 1.00 55.38 H ATOM 7317 N TYR B 76 -29.274 19.913 -36.456 1.00 55.88 N ATOM 7318 CA TYR B 76 -30.174 21.021 -36.107 1.00 56.45 C ATOM 7319 C TYR B 76 -30.411 21.963 -37.293 1.00 57.31 C ATOM 7320 O TYR B 76 -29.675 21.943 -38.279 1.00 58.05 O ATOM 7321 CB TYR B 76 -29.600 21.813 -34.911 1.00 57.60 C ATOM 7322 CG TYR B 76 -29.698 21.100 -33.577 1.00 62.26 C ATOM 7323 CD1 TYR B 76 -30.794 21.320 -32.717 1.00 68.40 C ATOM 7324 CD2 TYR B 76 -28.683 20.210 -33.193 1.00 62.47 C ATOM 7325 CE1 TYR B 76 -30.857 20.660 -31.472 1.00 70.82 C ATOM 7326 CE2 TYR B 76 -28.738 19.557 -31.947 1.00 67.28 C ATOM 7327 CZ TYR B 76 -29.825 19.784 -31.084 1.00 70.92 C ATOM 7328 OH TYR B 76 -29.874 19.152 -29.876 1.00 78.75 O ATOM 7329 H TYR B 76 -28.359 20.179 -36.794 1.00 55.88 H ATOM 7330 HA TYR B 76 -31.152 20.634 -35.818 1.00 56.45 H ATOM 7331 HB3 TYR B 76 -30.137 22.755 -34.791 1.00 57.60 H ATOM 7332 HB2 TYR B 76 -28.562 22.096 -35.101 1.00 57.60 H ATOM 7333 HD1 TYR B 76 -31.583 21.999 -33.004 1.00 68.40 H ATOM 7334 HD2 TYR B 76 -27.870 20.036 -33.877 1.00 62.47 H ATOM 7335 HE1 TYR B 76 -31.697 20.837 -30.816 1.00 70.82 H ATOM 7336 HE2 TYR B 76 -27.949 18.882 -31.653 1.00 67.28 H ATOM 7337 HH TYR B 76 -30.645 19.389 -29.357 1.00 78.75 H ATOM 7338 N SER B 77 -31.455 22.792 -37.134 1.00 56.31 N ATOM 7339 CA SER B 77 -31.867 23.869 -38.031 1.00 56.74 C ATOM 7340 C SER B 77 -30.823 25.001 -38.132 1.00 55.38 C ATOM 7341 O SER B 77 -30.071 25.229 -37.185 1.00 52.67 O ATOM 7342 CB SER B 77 -33.213 24.406 -37.491 1.00 56.94 C ATOM 7343 OG SER B 77 -33.733 25.476 -38.252 1.00 57.92 O ATOM 7344 H SER B 77 -31.992 22.722 -36.282 1.00 56.31 H ATOM 7345 HA SER B 77 -32.016 23.437 -39.020 1.00 56.74 H ATOM 7346 HB3 SER B 77 -33.098 24.742 -36.459 1.00 56.94 H ATOM 7347 HB2 SER B 77 -33.966 23.621 -37.477 1.00 56.94 H ATOM 7348 HG SER B 77 -33.948 25.141 -39.133 1.00 57.92 H ATOM 7349 N LEU B 78 -30.867 25.746 -39.250 1.00 55.15 N ATOM 7350 CA LEU B 78 -30.175 27.027 -39.438 1.00 55.65 C ATOM 7351 C LEU B 78 -30.664 28.142 -38.484 1.00 55.05 C ATOM 7352 O LEU B 78 -29.919 29.098 -38.273 1.00 54.34 O ATOM 7353 CB LEU B 78 -30.316 27.477 -40.912 1.00 56.37 C ATOM 7354 CG LEU B 78 -29.462 26.669 -41.919 1.00 54.85 C ATOM 7355 CD1 LEU B 78 -29.924 26.917 -43.372 1.00 51.65 C ATOM 7356 CD2 LEU B 78 -27.946 26.910 -41.728 1.00 53.19 C ATOM 7357 H LEU B 78 -31.491 25.470 -39.999 1.00 55.15 H ATOM 7358 HA LEU B 78 -29.121 26.872 -39.215 1.00 55.65 H ATOM 7359 HB3 LEU B 78 -30.051 28.531 -41.015 1.00 56.37 H ATOM 7360 HB2 LEU B 78 -31.370 27.413 -41.188 1.00 56.37 H ATOM 7361 HG LEU B 78 -29.638 25.613 -41.718 1.00 54.85 H ATOM 7362 HD11 LEU B 78 -29.139 27.330 -44.004 1.00 51.65 H ATOM 7363 HD12 LEU B 78 -30.253 25.987 -43.836 1.00 51.65 H ATOM 7364 HD13 LEU B 78 -30.763 27.611 -43.423 1.00 51.65 H ATOM 7365 HD21 LEU B 78 -27.437 25.976 -41.489 1.00 53.19 H ATOM 7366 HD22 LEU B 78 -27.463 27.316 -42.616 1.00 53.19 H ATOM 7367 HD23 LEU B 78 -27.737 27.606 -40.916 1.00 53.19 H ATOM 7368 N LYS B 79 -31.877 27.999 -37.915 1.00 54.58 N ATOM 7369 CA LYS B 79 -32.463 28.939 -36.956 1.00 54.95 C ATOM 7370 C LYS B 79 -31.892 28.790 -35.536 1.00 53.20 C ATOM 7371 O LYS B 79 -31.932 29.767 -34.792 1.00 52.89 O ATOM 7372 CB LYS B 79 -34.005 28.796 -36.972 1.00 56.05 C ATOM 7373 CG LYS B 79 -34.653 27.727 -36.068 1.00 60.83 C ATOM 7374 CD LYS B 79 -36.071 27.367 -36.549 1.00 67.05 C ATOM 7375 CE LYS B 79 -36.773 26.270 -35.729 1.00 70.16 C ATOM 7376 NZ LYS B 79 -37.290 26.761 -34.439 1.00 71.76 N1+ ATOM 7377 H LYS B 79 -32.438 27.188 -38.141 1.00 54.58 H ATOM 7378 HA LYS B 79 -32.227 29.952 -37.291 1.00 54.95 H ATOM 7379 HB3 LYS B 79 -34.320 28.640 -38.001 1.00 56.05 H ATOM 7380 HB2 LYS B 79 -34.436 29.751 -36.680 1.00 56.05 H ATOM 7381 HG3 LYS B 79 -34.694 28.095 -35.042 1.00 60.83 H ATOM 7382 HG2 LYS B 79 -34.037 26.830 -36.040 1.00 60.83 H ATOM 7383 HD3 LYS B 79 -36.010 27.019 -37.580 1.00 67.05 H ATOM 7384 HD2 LYS B 79 -36.685 28.269 -36.581 1.00 67.05 H ATOM 7385 HE3 LYS B 79 -36.104 25.425 -35.563 1.00 70.16 H ATOM 7386 HE2 LYS B 79 -37.625 25.892 -36.295 1.00 70.16 H ATOM 7387 HZ1 LYS B 79 -36.526 27.073 -33.852 1.00 71.76 H ATOM 7388 HZ2 LYS B 79 -37.921 27.535 -34.592 1.00 71.76 H ATOM 7389 HZ3 LYS B 79 -37.780 26.020 -33.961 1.00 71.76 H ATOM 7390 N SER B 80 -31.402 27.584 -35.186 1.00 53.35 N ATOM 7391 CA SER B 80 -30.955 27.201 -33.842 1.00 53.00 C ATOM 7392 C SER B 80 -29.859 28.118 -33.268 1.00 51.51 C ATOM 7393 O SER B 80 -30.033 28.670 -32.181 1.00 50.58 O ATOM 7394 CB SER B 80 -30.594 25.700 -33.822 1.00 52.63 C ATOM 7395 OG SER B 80 -29.379 25.394 -34.472 1.00 61.43 O ATOM 7396 H SER B 80 -31.379 26.852 -35.881 1.00 53.35 H ATOM 7397 HA SER B 80 -31.829 27.306 -33.203 1.00 53.00 H ATOM 7398 HB3 SER B 80 -31.395 25.104 -34.261 1.00 52.63 H ATOM 7399 HB2 SER B 80 -30.493 25.370 -32.794 1.00 52.63 H ATOM 7400 HG SER B 80 -29.525 25.407 -35.425 1.00 61.43 H ATOM 7401 N ILE B 81 -28.796 28.306 -34.060 1.00 49.49 N ATOM 7402 CA ILE B 81 -27.749 29.305 -33.889 1.00 48.52 C ATOM 7403 C ILE B 81 -27.453 29.838 -35.302 1.00 48.70 C ATOM 7404 O ILE B 81 -27.480 29.061 -36.259 1.00 48.99 O ATOM 7405 CB ILE B 81 -26.440 28.708 -33.275 1.00 48.80 C ATOM 7406 CG1 ILE B 81 -26.721 28.005 -31.922 1.00 47.83 C ATOM 7407 CG2 ILE B 81 -25.334 29.778 -33.118 1.00 42.80 C ATOM 7408 CD1 ILE B 81 -25.495 27.422 -31.204 1.00 45.51 C ATOM 7409 H ILE B 81 -28.755 27.802 -34.935 1.00 49.49 H ATOM 7410 HA ILE B 81 -28.115 30.127 -33.271 1.00 48.52 H ATOM 7411 HB ILE B 81 -26.056 27.946 -33.957 1.00 48.80 H ATOM 7412 HG13 ILE B 81 -27.428 27.191 -32.073 1.00 47.83 H ATOM 7413 HG12 ILE B 81 -27.218 28.694 -31.246 1.00 47.83 H ATOM 7414 HG21 ILE B 81 -24.441 29.369 -32.653 1.00 42.80 H ATOM 7415 HG22 ILE B 81 -25.009 30.186 -34.074 1.00 42.80 H ATOM 7416 HG23 ILE B 81 -25.674 30.608 -32.499 1.00 42.80 H ATOM 7417 HD11 ILE B 81 -25.798 26.647 -30.501 1.00 45.51 H ATOM 7418 HD12 ILE B 81 -24.796 26.974 -31.906 1.00 45.51 H ATOM 7419 HD13 ILE B 81 -24.963 28.185 -30.635 1.00 45.51 H ATOM 7420 N ASP B 82 -27.190 31.151 -35.413 1.00 48.90 N ATOM 7421 CA ASP B 82 -26.909 31.846 -36.673 1.00 48.88 C ATOM 7422 C ASP B 82 -25.584 31.322 -37.283 1.00 48.09 C ATOM 7423 O ASP B 82 -24.571 31.374 -36.584 1.00 48.02 O ATOM 7424 CB ASP B 82 -26.840 33.374 -36.404 1.00 48.52 C ATOM 7425 CG ASP B 82 -26.733 34.322 -37.618 1.00 47.78 C ATOM 7426 OD1 ASP B 82 -26.874 33.874 -38.775 1.00 47.65 O ATOM 7427 OD2 ASP B 82 -26.587 35.536 -37.361 1.00 44.77 O1- ATOM 7428 H ASP B 82 -27.175 31.726 -34.581 1.00 48.90 H ATOM 7429 HA ASP B 82 -27.769 31.650 -37.311 1.00 48.88 H ATOM 7430 HB3 ASP B 82 -26.014 33.584 -35.720 1.00 48.52 H ATOM 7431 HB2 ASP B 82 -27.733 33.660 -35.848 1.00 48.52 H ATOM 7432 N PRO B 83 -25.586 30.827 -38.547 1.00 48.52 N ATOM 7433 CA PRO B 83 -24.347 30.380 -39.219 1.00 48.99 C ATOM 7434 C PRO B 83 -23.248 31.449 -39.419 1.00 49.56 C ATOM 7435 O PRO B 83 -22.092 31.071 -39.607 1.00 50.32 O ATOM 7436 CB PRO B 83 -24.834 29.765 -40.539 1.00 49.14 C ATOM 7437 CG PRO B 83 -26.170 30.434 -40.806 1.00 48.94 C ATOM 7438 CD PRO B 83 -26.750 30.592 -39.409 1.00 49.05 C ATOM 7439 HA PRO B 83 -23.898 29.587 -38.626 1.00 48.99 H ATOM 7440 HB3 PRO B 83 -24.988 28.694 -40.402 1.00 49.14 H ATOM 7441 HB2 PRO B 83 -24.135 29.886 -41.365 1.00 49.14 H ATOM 7442 HG3 PRO B 83 -26.813 29.873 -41.484 1.00 48.94 H ATOM 7443 HG2 PRO B 83 -26.005 31.421 -41.239 1.00 48.94 H ATOM 7444 HD2 PRO B 83 -27.494 31.386 -39.408 1.00 49.05 H ATOM 7445 HD3 PRO B 83 -27.238 29.670 -39.089 1.00 49.05 H ATOM 7446 N VAL B 84 -23.601 32.744 -39.317 1.00 49.87 N ATOM 7447 CA VAL B 84 -22.656 33.867 -39.280 1.00 49.46 C ATOM 7448 C VAL B 84 -21.816 33.891 -37.983 1.00 49.27 C ATOM 7449 O VAL B 84 -20.641 34.247 -38.050 1.00 50.58 O ATOM 7450 CB VAL B 84 -23.396 35.229 -39.431 1.00 50.11 C ATOM 7451 CG1 VAL B 84 -22.522 36.488 -39.236 1.00 47.68 C ATOM 7452 CG2 VAL B 84 -24.115 35.310 -40.788 1.00 47.76 C ATOM 7453 H VAL B 84 -24.574 32.985 -39.182 1.00 49.87 H ATOM 7454 HA VAL B 84 -21.967 33.753 -40.119 1.00 49.46 H ATOM 7455 HB VAL B 84 -24.167 35.276 -38.663 1.00 50.11 H ATOM 7456 HG11 VAL B 84 -23.076 37.395 -39.480 1.00 47.68 H ATOM 7457 HG12 VAL B 84 -22.187 36.601 -38.204 1.00 47.68 H ATOM 7458 HG13 VAL B 84 -21.640 36.458 -39.876 1.00 47.68 H ATOM 7459 HG21 VAL B 84 -24.640 36.258 -40.902 1.00 47.76 H ATOM 7460 HG22 VAL B 84 -23.403 35.217 -41.607 1.00 47.76 H ATOM 7461 HG23 VAL B 84 -24.856 34.518 -40.902 1.00 47.76 H ATOM 7462 N LEU B 85 -22.417 33.487 -36.849 1.00 48.51 N ATOM 7463 CA LEU B 85 -21.753 33.333 -35.552 1.00 47.85 C ATOM 7464 C LEU B 85 -20.983 32.003 -35.449 1.00 47.47 C ATOM 7465 O LEU B 85 -19.894 31.992 -34.874 1.00 47.86 O ATOM 7466 CB LEU B 85 -22.812 33.482 -34.429 1.00 47.05 C ATOM 7467 CG LEU B 85 -22.332 33.289 -32.969 1.00 48.68 C ATOM 7468 CD1 LEU B 85 -21.233 34.296 -32.566 1.00 45.57 C ATOM 7469 CD2 LEU B 85 -23.530 33.308 -31.996 1.00 47.57 C ATOM 7470 H LEU B 85 -23.384 33.196 -36.882 1.00 48.51 H ATOM 7471 HA LEU B 85 -21.026 34.140 -35.453 1.00 47.85 H ATOM 7472 HB3 LEU B 85 -23.614 32.766 -34.608 1.00 47.05 H ATOM 7473 HB2 LEU B 85 -23.276 34.462 -34.515 1.00 47.05 H ATOM 7474 HG LEU B 85 -21.895 32.295 -32.881 1.00 48.68 H ATOM 7475 HD11 LEU B 85 -20.332 33.770 -32.254 1.00 45.57 H ATOM 7476 HD12 LEU B 85 -20.955 34.965 -33.379 1.00 45.57 H ATOM 7477 HD13 LEU B 85 -21.533 34.935 -31.739 1.00 45.57 H ATOM 7478 HD21 LEU B 85 -23.319 33.838 -31.068 1.00 47.57 H ATOM 7479 HD22 LEU B 85 -24.408 33.777 -32.440 1.00 47.57 H ATOM 7480 HD23 LEU B 85 -23.814 32.293 -31.718 1.00 47.57 H ATOM 7481 N MET B 86 -21.552 30.917 -36.004 1.00 49.58 N ATOM 7482 CA MET B 86 -20.991 29.565 -35.940 1.00 49.46 C ATOM 7483 C MET B 86 -19.696 29.388 -36.755 1.00 48.27 C ATOM 7484 O MET B 86 -18.816 28.660 -36.301 1.00 49.33 O ATOM 7485 CB MET B 86 -22.076 28.539 -36.341 1.00 48.66 C ATOM 7486 CG MET B 86 -21.680 27.054 -36.211 1.00 51.68 C ATOM 7487 SD MET B 86 -21.135 26.510 -34.569 1.00 53.67 S ATOM 7488 CE MET B 86 -22.708 26.585 -33.685 1.00 51.02 C ATOM 7489 H MET B 86 -22.456 31.007 -36.448 1.00 49.58 H ATOM 7490 HA MET B 86 -20.739 29.386 -34.894 1.00 49.46 H ATOM 7491 HB3 MET B 86 -22.350 28.714 -37.379 1.00 48.66 H ATOM 7492 HB2 MET B 86 -22.982 28.721 -35.762 1.00 48.66 H ATOM 7493 HG3 MET B 86 -20.889 26.814 -36.919 1.00 51.68 H ATOM 7494 HG2 MET B 86 -22.527 26.430 -36.497 1.00 51.68 H ATOM 7495 HE1 MET B 86 -22.581 26.239 -32.659 1.00 51.02 H ATOM 7496 HE2 MET B 86 -23.094 27.602 -33.669 1.00 51.02 H ATOM 7497 HE3 MET B 86 -23.444 25.959 -34.180 1.00 51.02 H ATOM 7498 N ALA B 87 -19.591 30.054 -37.919 1.00 46.49 N ATOM 7499 CA ALA B 87 -18.426 30.010 -38.810 1.00 46.22 C ATOM 7500 C ALA B 87 -17.081 30.420 -38.156 1.00 44.95 C ATOM 7501 O ALA B 87 -16.175 29.584 -38.161 1.00 46.05 O ATOM 7502 CB ALA B 87 -18.732 30.797 -40.097 1.00 44.03 C ATOM 7503 H ALA B 87 -20.364 30.627 -38.231 1.00 46.49 H ATOM 7504 HA ALA B 87 -18.311 28.966 -39.109 1.00 46.22 H ATOM 7505 HB1 ALA B 87 -17.834 30.948 -40.696 1.00 44.03 H ATOM 7506 HB2 ALA B 87 -19.447 30.253 -40.717 1.00 44.03 H ATOM 7507 HB3 ALA B 87 -19.168 31.775 -39.892 1.00 44.03 H ATOM 7508 N PRO B 88 -16.959 31.633 -37.557 1.00 44.25 N ATOM 7509 CA PRO B 88 -15.746 32.017 -36.807 1.00 43.75 C ATOM 7510 C PRO B 88 -15.530 31.252 -35.486 1.00 44.35 C ATOM 7511 O PRO B 88 -14.377 31.112 -35.082 1.00 43.33 O ATOM 7512 CB PRO B 88 -15.905 33.530 -36.578 1.00 44.33 C ATOM 7513 CG PRO B 88 -17.406 33.756 -36.581 1.00 44.57 C ATOM 7514 CD PRO B 88 -17.900 32.751 -37.616 1.00 43.23 C ATOM 7515 HA PRO B 88 -14.866 31.851 -37.430 1.00 43.75 H ATOM 7516 HB3 PRO B 88 -15.451 34.071 -37.409 1.00 44.33 H ATOM 7517 HB2 PRO B 88 -15.434 33.892 -35.663 1.00 44.33 H ATOM 7518 HG3 PRO B 88 -17.691 34.783 -36.809 1.00 44.57 H ATOM 7519 HG2 PRO B 88 -17.811 33.505 -35.601 1.00 44.57 H ATOM 7520 HD2 PRO B 88 -18.927 32.463 -37.413 1.00 43.23 H ATOM 7521 HD3 PRO B 88 -17.858 33.194 -38.611 1.00 43.23 H ATOM 7522 N THR B 89 -16.605 30.741 -34.856 1.00 46.04 N ATOM 7523 CA THR B 89 -16.514 29.907 -33.650 1.00 45.97 C ATOM 7524 C THR B 89 -15.882 28.527 -33.927 1.00 45.36 C ATOM 7525 O THR B 89 -15.092 28.056 -33.109 1.00 46.09 O ATOM 7526 CB THR B 89 -17.896 29.679 -32.983 1.00 46.62 C ATOM 7527 OG1 THR B 89 -18.462 30.923 -32.624 1.00 45.09 O ATOM 7528 CG2 THR B 89 -17.866 28.819 -31.710 1.00 43.16 C ATOM 7529 H THR B 89 -17.530 30.889 -35.234 1.00 46.04 H ATOM 7530 HA THR B 89 -15.872 30.425 -32.935 1.00 45.97 H ATOM 7531 HB THR B 89 -18.578 29.214 -33.695 1.00 46.62 H ATOM 7532 HG1 THR B 89 -18.758 31.372 -33.422 1.00 45.09 H ATOM 7533 HG21 THR B 89 -18.840 28.809 -31.232 1.00 43.16 H ATOM 7534 HG22 THR B 89 -17.607 27.781 -31.914 1.00 43.16 H ATOM 7535 HG23 THR B 89 -17.146 29.213 -30.993 1.00 43.16 H ATOM 7536 N CYS B 90 -16.204 27.930 -35.089 1.00 46.30 N ATOM 7537 CA CYS B 90 -15.624 26.676 -35.570 1.00 46.54 C ATOM 7538 C CYS B 90 -14.127 26.818 -35.893 1.00 45.75 C ATOM 7539 O CYS B 90 -13.361 25.916 -35.558 1.00 47.73 O ATOM 7540 CB CYS B 90 -16.345 26.138 -36.816 1.00 47.29 C ATOM 7541 SG CYS B 90 -18.022 25.576 -36.431 1.00 44.40 S ATOM 7542 H CYS B 90 -16.879 28.371 -35.701 1.00 46.30 H ATOM 7543 HA CYS B 90 -15.716 25.938 -34.772 1.00 46.54 H ATOM 7544 HB3 CYS B 90 -15.798 25.281 -37.196 1.00 47.29 H ATOM 7545 HB2 CYS B 90 -16.385 26.880 -37.614 1.00 47.29 H ATOM 7546 HG CYS B 90 -18.523 26.795 -36.194 1.00 44.40 H ATOM 7547 N VAL B 91 -13.745 27.946 -36.520 1.00 45.85 N ATOM 7548 CA VAL B 91 -12.362 28.307 -36.849 1.00 45.08 C ATOM 7549 C VAL B 91 -11.496 28.529 -35.592 1.00 45.41 C ATOM 7550 O VAL B 91 -10.342 28.100 -35.573 1.00 48.20 O ATOM 7551 CB VAL B 91 -12.322 29.563 -37.772 1.00 45.33 C ATOM 7552 CG1 VAL B 91 -10.942 30.230 -37.935 1.00 42.78 C ATOM 7553 CG2 VAL B 91 -12.876 29.229 -39.169 1.00 47.66 C ATOM 7554 H VAL B 91 -14.448 28.628 -36.771 1.00 45.85 H ATOM 7555 HA VAL B 91 -11.916 27.474 -37.391 1.00 45.08 H ATOM 7556 HB VAL B 91 -12.984 30.315 -37.342 1.00 45.33 H ATOM 7557 HG11 VAL B 91 -10.976 31.031 -38.674 1.00 42.78 H ATOM 7558 HG12 VAL B 91 -10.585 30.676 -37.006 1.00 42.78 H ATOM 7559 HG13 VAL B 91 -10.203 29.503 -38.271 1.00 42.78 H ATOM 7560 HG21 VAL B 91 -12.938 30.118 -39.796 1.00 47.66 H ATOM 7561 HG22 VAL B 91 -12.237 28.508 -39.680 1.00 47.66 H ATOM 7562 HG23 VAL B 91 -13.876 28.800 -39.119 1.00 47.66 H ATOM 7563 N PHE B 92 -12.088 29.152 -34.560 1.00 44.00 N ATOM 7564 CA PHE B 92 -11.472 29.397 -33.258 1.00 44.13 C ATOM 7565 C PHE B 92 -11.204 28.101 -32.475 1.00 45.03 C ATOM 7566 O PHE B 92 -10.074 27.902 -32.034 1.00 46.36 O ATOM 7567 CB PHE B 92 -12.354 30.392 -32.481 1.00 44.69 C ATOM 7568 CG PHE B 92 -11.859 30.841 -31.118 1.00 44.62 C ATOM 7569 CD1 PHE B 92 -10.612 31.489 -30.986 1.00 50.74 C ATOM 7570 CD2 PHE B 92 -12.673 30.673 -29.979 1.00 48.90 C ATOM 7571 CE1 PHE B 92 -10.203 31.955 -29.743 1.00 51.02 C ATOM 7572 CE2 PHE B 92 -12.241 31.140 -28.746 1.00 52.77 C ATOM 7573 CZ PHE B 92 -11.013 31.778 -28.628 1.00 52.58 C ATOM 7574 H PHE B 92 -13.038 29.483 -34.666 1.00 44.00 H ATOM 7575 HA PHE B 92 -10.509 29.876 -33.444 1.00 44.13 H ATOM 7576 HB3 PHE B 92 -13.361 29.986 -32.378 1.00 44.69 H ATOM 7577 HB2 PHE B 92 -12.463 31.291 -33.080 1.00 44.69 H ATOM 7578 HD1 PHE B 92 -9.980 31.643 -31.849 1.00 50.74 H ATOM 7579 HD2 PHE B 92 -13.636 30.189 -30.059 1.00 48.90 H ATOM 7580 HE1 PHE B 92 -9.254 32.459 -29.644 1.00 51.02 H ATOM 7581 HE2 PHE B 92 -12.869 31.007 -27.878 1.00 52.77 H ATOM 7582 HZ PHE B 92 -10.688 32.144 -27.666 1.00 52.58 H ATOM 7583 N LEU B 93 -12.223 27.229 -32.372 1.00 45.16 N ATOM 7584 CA LEU B 93 -12.148 25.920 -31.714 1.00 46.28 C ATOM 7585 C LEU B 93 -11.147 24.961 -32.391 1.00 47.61 C ATOM 7586 O LEU B 93 -10.422 24.264 -31.682 1.00 47.26 O ATOM 7587 CB LEU B 93 -13.577 25.325 -31.623 1.00 44.44 C ATOM 7588 CG LEU B 93 -13.726 23.982 -30.864 1.00 44.31 C ATOM 7589 CD1 LEU B 93 -13.314 24.067 -29.381 1.00 39.14 C ATOM 7590 CD2 LEU B 93 -15.155 23.431 -31.005 1.00 44.30 C ATOM 7591 H LEU B 93 -13.123 27.472 -32.765 1.00 45.16 H ATOM 7592 HA LEU B 93 -11.785 26.104 -30.701 1.00 46.28 H ATOM 7593 HB3 LEU B 93 -13.961 25.201 -32.638 1.00 44.44 H ATOM 7594 HB2 LEU B 93 -14.234 26.058 -31.152 1.00 44.44 H ATOM 7595 HG LEU B 93 -13.075 23.249 -31.341 1.00 44.31 H ATOM 7596 HD11 LEU B 93 -14.114 23.747 -28.712 1.00 39.14 H ATOM 7597 HD12 LEU B 93 -12.456 23.426 -29.184 1.00 39.14 H ATOM 7598 HD13 LEU B 93 -13.038 25.077 -29.082 1.00 39.14 H ATOM 7599 HD21 LEU B 93 -15.206 22.386 -30.701 1.00 44.30 H ATOM 7600 HD22 LEU B 93 -15.863 23.989 -30.390 1.00 44.30 H ATOM 7601 HD23 LEU B 93 -15.499 23.481 -32.038 1.00 44.30 H ATOM 7602 N ALA B 94 -11.102 24.973 -33.737 1.00 48.50 N ATOM 7603 CA ALA B 94 -10.198 24.158 -34.554 1.00 50.01 C ATOM 7604 C ALA B 94 -8.719 24.564 -34.436 1.00 49.45 C ATOM 7605 O ALA B 94 -7.860 23.684 -34.474 1.00 49.77 O ATOM 7606 CB ALA B 94 -10.648 24.215 -36.021 1.00 49.34 C ATOM 7607 H ALA B 94 -11.740 25.569 -34.247 1.00 48.50 H ATOM 7608 HA ALA B 94 -10.285 23.123 -34.216 1.00 50.01 H ATOM 7609 HB1 ALA B 94 -10.002 23.607 -36.655 1.00 49.34 H ATOM 7610 HB2 ALA B 94 -11.664 23.836 -36.137 1.00 49.34 H ATOM 7611 HB3 ALA B 94 -10.626 25.235 -36.407 1.00 49.34 H ATOM 7612 N SER B 95 -8.445 25.872 -34.276 1.00 50.59 N ATOM 7613 CA SER B 95 -7.097 26.409 -34.060 1.00 52.31 C ATOM 7614 C SER B 95 -6.538 26.113 -32.652 1.00 52.65 C ATOM 7615 O SER B 95 -5.320 26.115 -32.484 1.00 52.64 O ATOM 7616 CB SER B 95 -7.080 27.915 -34.407 1.00 52.62 C ATOM 7617 OG SER B 95 -7.623 28.738 -33.392 1.00 55.81 O ATOM 7618 H SER B 95 -9.202 26.542 -34.277 1.00 50.59 H ATOM 7619 HA SER B 95 -6.437 25.912 -34.774 1.00 52.31 H ATOM 7620 HB3 SER B 95 -7.604 28.103 -35.344 1.00 52.62 H ATOM 7621 HB2 SER B 95 -6.050 28.237 -34.564 1.00 52.62 H ATOM 7622 HG SER B 95 -8.541 28.490 -33.245 1.00 55.81 H ATOM 7623 N LYS B 96 -7.431 25.847 -31.683 1.00 55.91 N ATOM 7624 CA LYS B 96 -7.104 25.508 -30.297 1.00 57.86 C ATOM 7625 C LYS B 96 -6.867 24.003 -30.080 1.00 59.50 C ATOM 7626 O LYS B 96 -6.348 23.637 -29.025 1.00 61.21 O ATOM 7627 CB LYS B 96 -8.212 26.064 -29.384 1.00 58.41 C ATOM 7628 CG LYS B 96 -8.180 27.603 -29.318 1.00 57.42 C ATOM 7629 CD LYS B 96 -9.479 28.234 -28.804 1.00 60.43 C ATOM 7630 CE LYS B 96 -9.809 27.887 -27.350 1.00 59.21 C ATOM 7631 NZ LYS B 96 -11.024 28.589 -26.915 1.00 59.28 N1+ ATOM 7632 H LYS B 96 -8.416 25.873 -31.906 1.00 55.91 H ATOM 7633 HA LYS B 96 -6.170 26.007 -30.027 1.00 57.86 H ATOM 7634 HB3 LYS B 96 -8.104 25.672 -28.371 1.00 58.41 H ATOM 7635 HB2 LYS B 96 -9.184 25.719 -29.740 1.00 58.41 H ATOM 7636 HG3 LYS B 96 -7.972 28.021 -30.303 1.00 57.42 H ATOM 7637 HG2 LYS B 96 -7.348 27.918 -28.687 1.00 57.42 H ATOM 7638 HD3 LYS B 96 -10.308 27.926 -29.443 1.00 60.43 H ATOM 7639 HD2 LYS B 96 -9.398 29.315 -28.920 1.00 60.43 H ATOM 7640 HE3 LYS B 96 -8.986 28.173 -26.694 1.00 59.21 H ATOM 7641 HE2 LYS B 96 -9.964 26.814 -27.227 1.00 59.21 H ATOM 7642 HZ1 LYS B 96 -11.204 28.369 -25.943 1.00 59.28 H ATOM 7643 HZ2 LYS B 96 -10.902 29.586 -27.018 1.00 59.28 H ATOM 7644 HZ3 LYS B 96 -11.817 28.291 -27.473 1.00 59.28 H ATOM 7645 N VAL B 97 -7.186 23.163 -31.083 1.00 62.13 N ATOM 7646 CA VAL B 97 -6.736 21.769 -31.157 1.00 63.26 C ATOM 7647 C VAL B 97 -5.235 21.678 -31.523 1.00 66.12 C ATOM 7648 O VAL B 97 -4.606 20.675 -31.196 1.00 66.66 O ATOM 7649 CB VAL B 97 -7.587 20.945 -32.173 1.00 63.64 C ATOM 7650 CG1 VAL B 97 -7.075 19.520 -32.484 1.00 64.19 C ATOM 7651 CG2 VAL B 97 -9.046 20.845 -31.702 1.00 58.06 C ATOM 7652 H VAL B 97 -7.638 23.528 -31.910 1.00 62.13 H ATOM 7653 HA VAL B 97 -6.858 21.316 -30.170 1.00 63.26 H ATOM 7654 HB VAL B 97 -7.595 21.481 -33.121 1.00 63.64 H ATOM 7655 HG11 VAL B 97 -7.788 18.972 -33.101 1.00 64.19 H ATOM 7656 HG12 VAL B 97 -6.137 19.533 -33.040 1.00 64.19 H ATOM 7657 HG13 VAL B 97 -6.923 18.945 -31.570 1.00 64.19 H ATOM 7658 HG21 VAL B 97 -9.637 20.254 -32.399 1.00 58.06 H ATOM 7659 HG22 VAL B 97 -9.115 20.366 -30.725 1.00 58.06 H ATOM 7660 HG23 VAL B 97 -9.517 21.824 -31.630 1.00 58.06 H ATOM 7661 N GLU B 98 -4.674 22.738 -32.133 1.00 68.72 N ATOM 7662 CA GLU B 98 -3.243 22.901 -32.394 1.00 70.85 C ATOM 7663 C GLU B 98 -2.550 23.610 -31.217 1.00 72.15 C ATOM 7664 O GLU B 98 -3.201 24.347 -30.475 1.00 72.45 O ATOM 7665 CB GLU B 98 -3.049 23.730 -33.685 1.00 71.68 C ATOM 7666 CG GLU B 98 -3.824 23.222 -34.920 1.00 75.56 C ATOM 7667 CD GLU B 98 -3.478 21.798 -35.386 1.00 78.94 C ATOM 7668 OE1 GLU B 98 -2.298 21.399 -35.263 1.00 82.55 O ATOM 7669 OE2 GLU B 98 -4.396 21.133 -35.913 1.00 80.55 O1- ATOM 7670 H GLU B 98 -5.249 23.539 -32.351 1.00 68.72 H ATOM 7671 HA GLU B 98 -2.782 21.921 -32.528 1.00 70.85 H ATOM 7672 HB3 GLU B 98 -1.986 23.778 -33.927 1.00 71.68 H ATOM 7673 HB2 GLU B 98 -3.337 24.766 -33.503 1.00 71.68 H ATOM 7674 HG3 GLU B 98 -3.608 23.894 -35.749 1.00 75.56 H ATOM 7675 HG2 GLU B 98 -4.898 23.305 -34.744 1.00 75.56 H ATOM 7676 N GLU B 99 -1.230 23.389 -31.101 1.00 72.69 N ATOM 7677 CA GLU B 99 -0.349 24.035 -30.120 1.00 74.09 C ATOM 7678 C GLU B 99 0.740 24.900 -30.784 1.00 75.11 C ATOM 7679 O GLU B 99 1.446 25.613 -30.070 1.00 75.00 O ATOM 7680 CB GLU B 99 0.259 22.953 -29.201 1.00 73.60 C ATOM 7681 CG GLU B 99 1.216 21.957 -29.906 1.00 71.39 C ATOM 7682 CD GLU B 99 1.719 20.796 -29.036 1.00 71.59 C ATOM 7683 OE1 GLU B 99 1.288 20.672 -27.866 1.00 69.42 O ATOM 7684 OE2 GLU B 99 2.547 20.024 -29.564 1.00 66.59 O1- ATOM 7685 H GLU B 99 -0.781 22.751 -31.741 1.00 72.69 H ATOM 7686 HA GLU B 99 -0.926 24.718 -29.499 1.00 74.09 H ATOM 7687 HB3 GLU B 99 -0.559 22.413 -28.727 1.00 73.60 H ATOM 7688 HB2 GLU B 99 0.791 23.443 -28.384 1.00 73.60 H ATOM 7689 HG3 GLU B 99 2.091 22.492 -30.278 1.00 71.39 H ATOM 7690 HG2 GLU B 99 0.723 21.525 -30.777 1.00 71.39 H ATOM 7691 N PHE B 100 0.855 24.834 -32.121 1.00 76.73 N ATOM 7692 CA PHE B 100 1.767 25.633 -32.935 1.00 79.17 C ATOM 7693 C PHE B 100 1.107 26.974 -33.297 1.00 80.29 C ATOM 7694 O PHE B 100 0.571 27.123 -34.395 1.00 81.82 O ATOM 7695 CB PHE B 100 2.202 24.813 -34.172 1.00 79.51 C ATOM 7696 CG PHE B 100 3.261 23.759 -33.888 1.00 81.50 C ATOM 7697 CD1 PHE B 100 2.924 22.563 -33.218 1.00 82.72 C ATOM 7698 CD2 PHE B 100 4.619 24.023 -34.172 1.00 81.25 C ATOM 7699 CE1 PHE B 100 3.915 21.648 -32.886 1.00 82.98 C ATOM 7700 CE2 PHE B 100 5.594 23.091 -33.840 1.00 83.02 C ATOM 7701 CZ PHE B 100 5.242 21.907 -33.205 1.00 83.50 C ATOM 7702 H PHE B 100 0.225 24.236 -32.634 1.00 76.73 H ATOM 7703 HA PHE B 100 2.666 25.862 -32.361 1.00 79.17 H ATOM 7704 HB3 PHE B 100 2.588 25.473 -34.950 1.00 79.51 H ATOM 7705 HB2 PHE B 100 1.334 24.317 -34.610 1.00 79.51 H ATOM 7706 HD1 PHE B 100 1.898 22.354 -32.957 1.00 82.72 H ATOM 7707 HD2 PHE B 100 4.905 24.945 -34.655 1.00 81.25 H ATOM 7708 HE1 PHE B 100 3.652 20.734 -32.374 1.00 82.98 H ATOM 7709 HE2 PHE B 100 6.630 23.293 -34.066 1.00 83.02 H ATOM 7710 HZ PHE B 100 6.007 21.192 -32.942 1.00 83.50 H ATOM 7711 N GLY B 101 1.140 27.911 -32.335 1.00 80.69 N ATOM 7712 CA GLY B 101 0.515 29.228 -32.433 1.00 80.90 C ATOM 7713 C GLY B 101 -0.889 29.207 -31.811 1.00 79.80 C ATOM 7714 O GLY B 101 -1.480 28.148 -31.590 1.00 80.28 O ATOM 7715 H GLY B 101 1.579 27.684 -31.454 1.00 80.69 H ATOM 7716 HA3 GLY B 101 0.455 29.567 -33.469 1.00 80.90 H ATOM 7717 HA2 GLY B 101 1.139 29.944 -31.898 1.00 80.90 H ATOM 7718 N VAL B 102 -1.409 30.412 -31.527 1.00 78.27 N ATOM 7719 CA VAL B 102 -2.715 30.650 -30.908 1.00 77.16 C ATOM 7720 C VAL B 102 -3.372 31.865 -31.590 1.00 74.86 C ATOM 7721 O VAL B 102 -2.700 32.875 -31.811 1.00 75.68 O ATOM 7722 CB VAL B 102 -2.572 30.941 -29.378 1.00 78.02 C ATOM 7723 CG1 VAL B 102 -3.860 31.443 -28.688 1.00 78.73 C ATOM 7724 CG2 VAL B 102 -2.035 29.718 -28.608 1.00 78.66 C ATOM 7725 H VAL B 102 -0.879 31.243 -31.743 1.00 78.27 H ATOM 7726 HA VAL B 102 -3.363 29.783 -31.053 1.00 77.16 H ATOM 7727 HB VAL B 102 -1.829 31.731 -29.255 1.00 78.02 H ATOM 7728 HG11 VAL B 102 -3.726 31.517 -27.608 1.00 78.73 H ATOM 7729 HG12 VAL B 102 -4.151 32.437 -29.028 1.00 78.73 H ATOM 7730 HG13 VAL B 102 -4.696 30.766 -28.869 1.00 78.73 H ATOM 7731 HG21 VAL B 102 -1.969 29.918 -27.538 1.00 78.66 H ATOM 7732 HG22 VAL B 102 -2.682 28.851 -28.743 1.00 78.66 H ATOM 7733 HG23 VAL B 102 -1.034 29.441 -28.936 1.00 78.66 H ATOM 7734 N VAL B 103 -4.682 31.757 -31.870 1.00 71.36 N ATOM 7735 CA VAL B 103 -5.524 32.863 -32.331 1.00 68.15 C ATOM 7736 C VAL B 103 -6.098 33.592 -31.102 1.00 67.61 C ATOM 7737 O VAL B 103 -6.797 32.967 -30.304 1.00 66.65 O ATOM 7738 CB VAL B 103 -6.695 32.353 -33.225 1.00 67.18 C ATOM 7739 CG1 VAL B 103 -7.768 33.414 -33.555 1.00 63.32 C ATOM 7740 CG2 VAL B 103 -6.167 31.741 -34.537 1.00 64.12 C ATOM 7741 H VAL B 103 -5.167 30.897 -31.659 1.00 71.36 H ATOM 7742 HA VAL B 103 -4.930 33.567 -32.914 1.00 68.15 H ATOM 7743 HB VAL B 103 -7.204 31.548 -32.690 1.00 67.18 H ATOM 7744 HG11 VAL B 103 -8.499 33.025 -34.265 1.00 63.32 H ATOM 7745 HG12 VAL B 103 -8.330 33.717 -32.673 1.00 63.32 H ATOM 7746 HG13 VAL B 103 -7.323 34.308 -33.995 1.00 63.32 H ATOM 7747 HG21 VAL B 103 -6.981 31.343 -35.143 1.00 64.12 H ATOM 7748 HG22 VAL B 103 -5.642 32.484 -35.138 1.00 64.12 H ATOM 7749 HG23 VAL B 103 -5.477 30.918 -34.348 1.00 64.12 H ATOM 7750 N SER B 104 -5.791 34.894 -30.975 1.00 67.57 N ATOM 7751 CA SER B 104 -6.315 35.753 -29.913 1.00 66.89 C ATOM 7752 C SER B 104 -7.770 36.179 -30.179 1.00 67.73 C ATOM 7753 O SER B 104 -8.252 36.101 -31.311 1.00 68.42 O ATOM 7754 CB SER B 104 -5.371 36.959 -29.704 1.00 67.01 C ATOM 7755 OG SER B 104 -5.512 37.959 -30.695 1.00 67.14 O ATOM 7756 H SER B 104 -5.196 35.345 -31.655 1.00 67.57 H ATOM 7757 HA SER B 104 -6.303 35.174 -28.987 1.00 66.89 H ATOM 7758 HB3 SER B 104 -4.331 36.635 -29.658 1.00 67.01 H ATOM 7759 HB2 SER B 104 -5.584 37.424 -28.741 1.00 67.01 H ATOM 7760 HG SER B 104 -4.889 38.664 -30.503 1.00 67.14 H ATOM 7761 N ASN B 105 -8.427 36.645 -29.107 1.00 66.90 N ATOM 7762 CA ASN B 105 -9.807 37.137 -29.098 1.00 66.19 C ATOM 7763 C ASN B 105 -10.000 38.359 -30.014 1.00 64.91 C ATOM 7764 O ASN B 105 -10.997 38.414 -30.734 1.00 65.36 O ATOM 7765 CB ASN B 105 -10.205 37.484 -27.642 1.00 66.73 C ATOM 7766 CG ASN B 105 -10.358 36.304 -26.666 1.00 67.15 C ATOM 7767 OD1 ASN B 105 -10.819 36.505 -25.546 1.00 67.48 O ATOM 7768 ND2 ASN B 105 -9.989 35.079 -27.051 1.00 63.86 N ATOM 7769 H ASN B 105 -7.949 36.678 -28.218 1.00 66.90 H ATOM 7770 HA ASN B 105 -10.429 36.316 -29.463 1.00 66.19 H ATOM 7771 HB3 ASN B 105 -11.159 38.012 -27.652 1.00 66.73 H ATOM 7772 HB2 ASN B 105 -9.488 38.187 -27.216 1.00 66.73 H ATOM 7773 HD22 ASN B 105 -10.081 34.304 -26.411 1.00 63.86 H ATOM 7774 HD21 ASN B 105 -9.618 34.920 -27.977 1.00 63.86 H ATOM 7775 N THR B 106 -9.029 39.289 -29.994 1.00 65.13 N ATOM 7776 CA THR B 106 -9.026 40.495 -30.820 1.00 64.12 C ATOM 7777 C THR B 106 -8.777 40.200 -32.313 1.00 61.32 C ATOM 7778 O THR B 106 -9.453 40.814 -33.137 1.00 62.16 O ATOM 7779 CB THR B 106 -7.976 41.527 -30.329 1.00 64.82 C ATOM 7780 OG1 THR B 106 -8.238 41.837 -28.974 1.00 67.50 O ATOM 7781 CG2 THR B 106 -7.929 42.853 -31.113 1.00 68.37 C ATOM 7782 H THR B 106 -8.244 39.180 -29.369 1.00 65.13 H ATOM 7783 HA THR B 106 -10.014 40.954 -30.736 1.00 64.12 H ATOM 7784 HB THR B 106 -6.985 41.071 -30.364 1.00 64.82 H ATOM 7785 HG1 THR B 106 -7.684 42.578 -28.716 1.00 67.50 H ATOM 7786 HG21 THR B 106 -7.241 43.560 -30.647 1.00 68.37 H ATOM 7787 HG22 THR B 106 -7.588 42.711 -32.138 1.00 68.37 H ATOM 7788 HG23 THR B 106 -8.912 43.324 -31.151 1.00 68.37 H ATOM 7789 N ARG B 107 -7.876 39.247 -32.642 1.00 59.65 N ATOM 7790 CA ARG B 107 -7.649 38.807 -34.026 1.00 58.42 C ATOM 7791 C ARG B 107 -8.857 38.084 -34.638 1.00 56.69 C ATOM 7792 O ARG B 107 -9.071 38.246 -35.837 1.00 56.91 O ATOM 7793 CB ARG B 107 -6.400 37.905 -34.172 1.00 59.79 C ATOM 7794 CG ARG B 107 -5.053 38.647 -34.085 1.00 63.23 C ATOM 7795 CD ARG B 107 -3.915 38.020 -34.920 1.00 68.84 C ATOM 7796 NE ARG B 107 -3.657 36.595 -34.627 1.00 70.66 N ATOM 7797 CZ ARG B 107 -3.468 35.584 -35.501 1.00 72.09 C ATOM 7798 NH1 ARG B 107 -3.554 35.747 -36.830 1.00 70.34 N ATOM 7799 NH2 ARG B 107 -3.172 34.366 -35.029 1.00 75.05 N1+ ATOM 7800 H ARG B 107 -7.362 38.761 -31.920 1.00 59.65 H ATOM 7801 HA ARG B 107 -7.495 39.700 -34.635 1.00 58.42 H ATOM 7802 HB3 ARG B 107 -6.435 37.425 -35.152 1.00 59.79 H ATOM 7803 HB2 ARG B 107 -6.433 37.089 -33.447 1.00 59.79 H ATOM 7804 HG3 ARG B 107 -4.744 38.883 -33.067 1.00 63.23 H ATOM 7805 HG2 ARG B 107 -5.234 39.616 -34.551 1.00 63.23 H ATOM 7806 HD3 ARG B 107 -2.990 38.495 -34.590 1.00 68.84 H ATOM 7807 HD2 ARG B 107 -4.002 38.269 -35.979 1.00 68.84 H ATOM 7808 HE ARG B 107 -3.545 36.381 -33.643 1.00 70.66 H ATOM 7809 HH12 ARG B 107 -3.410 34.965 -37.456 1.00 70.34 H ATOM 7810 HH11 ARG B 107 -3.776 36.653 -37.216 1.00 70.34 H ATOM 7811 HH22 ARG B 107 -3.022 33.595 -35.664 1.00 75.05 H ATOM 7812 HH21 ARG B 107 -3.071 34.212 -34.035 1.00 75.05 H ATOM 7813 N LEU B 108 -9.619 37.321 -33.836 1.00 54.69 N ATOM 7814 CA LEU B 108 -10.807 36.611 -34.307 1.00 53.68 C ATOM 7815 C LEU B 108 -11.944 37.565 -34.706 1.00 52.36 C ATOM 7816 O LEU B 108 -12.487 37.414 -35.798 1.00 51.33 O ATOM 7817 CB LEU B 108 -11.271 35.587 -33.251 1.00 54.43 C ATOM 7818 CG LEU B 108 -12.500 34.753 -33.682 1.00 55.78 C ATOM 7819 CD1 LEU B 108 -12.182 33.829 -34.877 1.00 59.58 C ATOM 7820 CD2 LEU B 108 -13.081 34.001 -32.484 1.00 59.45 C ATOM 7821 H LEU B 108 -9.378 37.210 -32.860 1.00 54.69 H ATOM 7822 HA LEU B 108 -10.513 36.062 -35.203 1.00 53.68 H ATOM 7823 HB3 LEU B 108 -11.508 36.117 -32.327 1.00 54.43 H ATOM 7824 HB2 LEU B 108 -10.448 34.916 -33.001 1.00 54.43 H ATOM 7825 HG LEU B 108 -13.304 35.414 -34.002 1.00 55.78 H ATOM 7826 HD11 LEU B 108 -12.464 32.796 -34.696 1.00 59.58 H ATOM 7827 HD12 LEU B 108 -12.717 34.154 -35.770 1.00 59.58 H ATOM 7828 HD13 LEU B 108 -11.120 33.820 -35.119 1.00 59.58 H ATOM 7829 HD21 LEU B 108 -13.709 33.166 -32.793 1.00 59.45 H ATOM 7830 HD22 LEU B 108 -12.301 33.625 -31.823 1.00 59.45 H ATOM 7831 HD23 LEU B 108 -13.705 34.676 -31.899 1.00 59.45 H ATOM 7832 N ILE B 109 -12.279 38.516 -33.817 1.00 51.92 N ATOM 7833 CA ILE B 109 -13.341 39.499 -34.038 1.00 53.22 C ATOM 7834 C ILE B 109 -12.976 40.517 -35.139 1.00 53.11 C ATOM 7835 O ILE B 109 -13.856 40.886 -35.917 1.00 55.15 O ATOM 7836 CB ILE B 109 -13.727 40.233 -32.716 1.00 53.32 C ATOM 7837 CG1 ILE B 109 -14.269 39.251 -31.645 1.00 53.96 C ATOM 7838 CG2 ILE B 109 -14.695 41.426 -32.886 1.00 52.98 C ATOM 7839 CD1 ILE B 109 -15.595 38.556 -31.995 1.00 48.72 C ATOM 7840 H ILE B 109 -11.792 38.570 -32.932 1.00 51.92 H ATOM 7841 HA ILE B 109 -14.218 38.962 -34.400 1.00 53.22 H ATOM 7842 HB ILE B 109 -12.804 40.644 -32.300 1.00 53.32 H ATOM 7843 HG13 ILE B 109 -14.391 39.781 -30.700 1.00 53.96 H ATOM 7844 HG12 ILE B 109 -13.529 38.478 -31.441 1.00 53.96 H ATOM 7845 HG21 ILE B 109 -14.991 41.830 -31.917 1.00 52.98 H ATOM 7846 HG22 ILE B 109 -14.241 42.249 -33.439 1.00 52.98 H ATOM 7847 HG23 ILE B 109 -15.603 41.134 -33.413 1.00 52.98 H ATOM 7848 HD11 ILE B 109 -15.919 37.923 -31.171 1.00 48.72 H ATOM 7849 HD12 ILE B 109 -16.394 39.272 -32.184 1.00 48.72 H ATOM 7850 HD13 ILE B 109 -15.499 37.910 -32.867 1.00 48.72 H ATOM 7851 N ALA B 110 -11.685 40.887 -35.234 1.00 53.28 N ATOM 7852 CA ALA B 110 -11.138 41.705 -36.318 1.00 53.78 C ATOM 7853 C ALA B 110 -11.173 40.997 -37.681 1.00 51.09 C ATOM 7854 O ALA B 110 -11.529 41.643 -38.663 1.00 49.76 O ATOM 7855 CB ALA B 110 -9.708 42.145 -35.976 1.00 53.53 C ATOM 7856 H ALA B 110 -11.017 40.551 -34.553 1.00 53.28 H ATOM 7857 HA ALA B 110 -11.753 42.604 -36.395 1.00 53.78 H ATOM 7858 HB1 ALA B 110 -9.286 42.766 -36.767 1.00 53.53 H ATOM 7859 HB2 ALA B 110 -9.688 42.734 -35.058 1.00 53.53 H ATOM 7860 HB3 ALA B 110 -9.046 41.289 -35.840 1.00 53.53 H ATOM 7861 N ALA B 111 -10.851 39.690 -37.715 1.00 51.56 N ATOM 7862 CA ALA B 111 -10.924 38.851 -38.914 1.00 52.95 C ATOM 7863 C ALA B 111 -12.363 38.621 -39.393 1.00 53.86 C ATOM 7864 O ALA B 111 -12.603 38.712 -40.593 1.00 55.35 O ATOM 7865 CB ALA B 111 -10.207 37.512 -38.678 1.00 52.44 C ATOM 7866 H ALA B 111 -10.549 39.226 -36.868 1.00 51.56 H ATOM 7867 HA ALA B 111 -10.396 39.373 -39.713 1.00 52.95 H ATOM 7868 HB1 ALA B 111 -10.272 36.867 -39.556 1.00 52.44 H ATOM 7869 HB2 ALA B 111 -9.148 37.670 -38.475 1.00 52.44 H ATOM 7870 HB3 ALA B 111 -10.632 36.966 -37.835 1.00 52.44 H ATOM 7871 N ALA B 112 -13.294 38.372 -38.456 1.00 55.08 N ATOM 7872 CA ALA B 112 -14.722 38.204 -38.726 1.00 54.50 C ATOM 7873 C ALA B 112 -15.403 39.478 -39.255 1.00 55.42 C ATOM 7874 O ALA B 112 -16.269 39.370 -40.120 1.00 54.06 O ATOM 7875 CB ALA B 112 -15.420 37.686 -37.462 1.00 54.43 C ATOM 7876 H ALA B 112 -13.011 38.289 -37.488 1.00 55.08 H ATOM 7877 HA ALA B 112 -14.829 37.444 -39.500 1.00 54.50 H ATOM 7878 HB1 ALA B 112 -16.481 37.511 -37.644 1.00 54.43 H ATOM 7879 HB2 ALA B 112 -14.988 36.741 -37.132 1.00 54.43 H ATOM 7880 HB3 ALA B 112 -15.334 38.396 -36.637 1.00 54.43 H ATOM 7881 N THR B 113 -14.976 40.655 -38.768 1.00 55.39 N ATOM 7882 CA THR B 113 -15.443 41.952 -39.259 1.00 54.09 C ATOM 7883 C THR B 113 -14.840 42.299 -40.635 1.00 54.05 C ATOM 7884 O THR B 113 -15.590 42.711 -41.520 1.00 55.32 O ATOM 7885 CB THR B 113 -15.113 43.098 -38.264 1.00 55.24 C ATOM 7886 OG1 THR B 113 -15.738 42.827 -37.025 1.00 54.41 O ATOM 7887 CG2 THR B 113 -15.558 44.506 -38.707 1.00 52.80 C ATOM 7888 H THR B 113 -14.270 40.671 -38.045 1.00 55.39 H ATOM 7889 HA THR B 113 -16.527 41.907 -39.378 1.00 54.09 H ATOM 7890 HB THR B 113 -14.038 43.117 -38.077 1.00 55.24 H ATOM 7891 HG1 THR B 113 -15.307 42.064 -36.626 1.00 54.41 H ATOM 7892 HG21 THR B 113 -15.387 45.236 -37.915 1.00 52.80 H ATOM 7893 HG22 THR B 113 -15.007 44.854 -39.581 1.00 52.80 H ATOM 7894 HG23 THR B 113 -16.621 44.527 -38.951 1.00 52.80 H ATOM 7895 N SER B 114 -13.516 42.108 -40.787 1.00 55.10 N ATOM 7896 CA SER B 114 -12.747 42.431 -41.990 1.00 56.32 C ATOM 7897 C SER B 114 -13.129 41.569 -43.205 1.00 56.46 C ATOM 7898 O SER B 114 -13.389 42.132 -44.265 1.00 55.68 O ATOM 7899 CB SER B 114 -11.237 42.359 -41.678 1.00 55.29 C ATOM 7900 OG SER B 114 -10.436 42.703 -42.794 1.00 62.25 O ATOM 7901 H SER B 114 -12.976 41.758 -40.006 1.00 55.10 H ATOM 7902 HA SER B 114 -12.976 43.469 -42.242 1.00 56.32 H ATOM 7903 HB3 SER B 114 -10.961 41.356 -41.349 1.00 55.29 H ATOM 7904 HB2 SER B 114 -10.988 43.041 -40.865 1.00 55.29 H ATOM 7905 HG SER B 114 -10.535 43.642 -42.965 1.00 62.25 H ATOM 7906 N VAL B 115 -13.179 40.237 -43.036 1.00 55.93 N ATOM 7907 CA VAL B 115 -13.512 39.286 -44.101 1.00 55.81 C ATOM 7908 C VAL B 115 -14.933 39.485 -44.661 1.00 56.50 C ATOM 7909 O VAL B 115 -15.092 39.476 -45.879 1.00 58.52 O ATOM 7910 CB VAL B 115 -13.322 37.811 -43.634 1.00 56.62 C ATOM 7911 CG1 VAL B 115 -13.970 36.727 -44.519 1.00 53.91 C ATOM 7912 CG2 VAL B 115 -11.827 37.493 -43.469 1.00 52.12 C ATOM 7913 H VAL B 115 -12.964 39.834 -42.132 1.00 55.93 H ATOM 7914 HA VAL B 115 -12.816 39.470 -44.923 1.00 55.81 H ATOM 7915 HB VAL B 115 -13.786 37.714 -42.652 1.00 56.62 H ATOM 7916 HG11 VAL B 115 -13.679 35.728 -44.193 1.00 53.91 H ATOM 7917 HG12 VAL B 115 -15.059 36.759 -44.480 1.00 53.91 H ATOM 7918 HG13 VAL B 115 -13.664 36.841 -45.559 1.00 53.91 H ATOM 7919 HG21 VAL B 115 -11.679 36.501 -43.046 1.00 52.12 H ATOM 7920 HG22 VAL B 115 -11.309 37.526 -44.428 1.00 52.12 H ATOM 7921 HG23 VAL B 115 -11.333 38.202 -42.806 1.00 52.12 H ATOM 7922 N LEU B 116 -15.924 39.698 -43.778 1.00 57.85 N ATOM 7923 CA LEU B 116 -17.322 39.853 -44.178 1.00 59.09 C ATOM 7924 C LEU B 116 -17.638 41.186 -44.884 1.00 60.50 C ATOM 7925 O LEU B 116 -18.574 41.200 -45.681 1.00 61.05 O ATOM 7926 CB LEU B 116 -18.260 39.607 -42.976 1.00 59.02 C ATOM 7927 CG LEU B 116 -18.222 38.165 -42.412 1.00 62.53 C ATOM 7928 CD1 LEU B 116 -19.104 38.049 -41.151 1.00 62.03 C ATOM 7929 CD2 LEU B 116 -18.573 37.087 -43.460 1.00 60.80 C ATOM 7930 H LEU B 116 -15.729 39.716 -42.787 1.00 57.85 H ATOM 7931 HA LEU B 116 -17.519 39.080 -44.917 1.00 59.09 H ATOM 7932 HB3 LEU B 116 -19.288 39.833 -43.266 1.00 59.02 H ATOM 7933 HB2 LEU B 116 -18.011 40.317 -42.185 1.00 59.02 H ATOM 7934 HG LEU B 116 -17.199 37.963 -42.094 1.00 62.53 H ATOM 7935 HD11 LEU B 116 -18.544 37.606 -40.327 1.00 62.03 H ATOM 7936 HD12 LEU B 116 -19.460 39.021 -40.811 1.00 62.03 H ATOM 7937 HD13 LEU B 116 -19.988 37.433 -41.315 1.00 62.03 H ATOM 7938 HD21 LEU B 116 -19.216 36.302 -43.060 1.00 60.80 H ATOM 7939 HD22 LEU B 116 -19.085 37.508 -44.323 1.00 60.80 H ATOM 7940 HD23 LEU B 116 -17.670 36.597 -43.826 1.00 60.80 H ATOM 7941 N LYS B 117 -16.862 42.257 -44.626 1.00 61.11 N ATOM 7942 CA LYS B 117 -17.059 43.562 -45.272 1.00 63.25 C ATOM 7943 C LYS B 117 -16.211 43.748 -46.547 1.00 62.98 C ATOM 7944 O LYS B 117 -16.595 44.573 -47.374 1.00 63.87 O ATOM 7945 CB LYS B 117 -16.847 44.703 -44.248 1.00 64.27 C ATOM 7946 CG LYS B 117 -15.386 45.027 -43.877 1.00 68.99 C ATOM 7947 CD LYS B 117 -15.249 46.092 -42.775 1.00 71.89 C ATOM 7948 CE LYS B 117 -15.631 47.507 -43.249 0.00 70.96 C ATOM 7949 NZ LYS B 117 -15.447 48.513 -42.189 0.00 71.10 N1+ ATOM 7950 H LYS B 117 -16.111 42.189 -43.953 1.00 61.11 H ATOM 7951 HA LYS B 117 -18.101 43.642 -45.591 1.00 63.25 H ATOM 7952 HB3 LYS B 117 -17.422 44.487 -43.347 1.00 64.27 H ATOM 7953 HB2 LYS B 117 -17.292 45.606 -44.668 1.00 64.27 H ATOM 7954 HG3 LYS B 117 -14.839 45.366 -44.756 1.00 68.99 H ATOM 7955 HG2 LYS B 117 -14.890 44.117 -43.552 1.00 68.99 H ATOM 7956 HD3 LYS B 117 -14.221 46.085 -42.410 1.00 71.89 H ATOM 7957 HD2 LYS B 117 -15.871 45.806 -41.924 1.00 71.89 H ATOM 7958 HE3 LYS B 117 -16.671 47.542 -43.572 1.00 70.96 H ATOM 7959 HE2 LYS B 117 -15.018 47.791 -44.105 1.00 70.96 H ATOM 7960 HZ1 LYS B 117 -16.081 48.320 -41.423 1.00 71.10 H ATOM 7961 HZ2 LYS B 117 -14.494 48.497 -41.855 1.00 71.10 H ATOM 7962 HZ3 LYS B 117 -15.661 49.430 -42.556 1.00 71.10 H ATOM 7963 N THR B 118 -15.093 43.013 -46.695 1.00 64.34 N ATOM 7964 CA THR B 118 -14.193 43.133 -47.850 1.00 65.13 C ATOM 7965 C THR B 118 -14.413 42.028 -48.906 1.00 64.93 C ATOM 7966 O THR B 118 -14.085 42.278 -50.066 1.00 66.98 O ATOM 7967 CB THR B 118 -12.693 43.107 -47.440 1.00 65.08 C ATOM 7968 OG1 THR B 118 -12.304 41.872 -46.866 1.00 68.36 O ATOM 7969 CG2 THR B 118 -12.299 44.255 -46.498 1.00 63.01 C ATOM 7970 H THR B 118 -14.815 42.367 -45.969 1.00 64.34 H ATOM 7971 HA THR B 118 -14.365 44.086 -48.354 1.00 65.13 H ATOM 7972 HB THR B 118 -12.089 43.219 -48.342 1.00 65.08 H ATOM 7973 HG1 THR B 118 -12.613 41.854 -45.953 1.00 68.36 H ATOM 7974 HG21 THR B 118 -11.242 44.202 -46.235 1.00 63.01 H ATOM 7975 HG22 THR B 118 -12.469 45.221 -46.975 1.00 63.01 H ATOM 7976 HG23 THR B 118 -12.869 44.248 -45.571 1.00 63.01 H ATOM 7977 N ARG B 119 -14.965 40.861 -48.525 1.00 62.66 N ATOM 7978 CA ARG B 119 -15.148 39.714 -49.427 1.00 60.70 C ATOM 7979 C ARG B 119 -16.605 39.240 -49.549 1.00 58.18 C ATOM 7980 O ARG B 119 -16.883 38.541 -50.522 1.00 57.05 O ATOM 7981 CB ARG B 119 -14.245 38.537 -48.990 1.00 61.51 C ATOM 7982 CG ARG B 119 -12.736 38.848 -49.033 1.00 64.77 C ATOM 7983 CD ARG B 119 -11.839 37.679 -48.587 1.00 68.11 C ATOM 7984 NE ARG B 119 -11.877 36.541 -49.527 1.00 72.07 N ATOM 7985 CZ ARG B 119 -11.047 35.481 -49.559 1.00 74.20 C ATOM 7986 NH1 ARG B 119 -10.014 35.356 -48.715 1.00 75.72 N ATOM 7987 NH2 ARG B 119 -11.255 34.510 -50.456 1.00 77.44 N1+ ATOM 7988 H ARG B 119 -15.193 40.705 -47.553 1.00 62.66 H ATOM 7989 HA ARG B 119 -14.851 39.983 -50.442 1.00 60.70 H ATOM 7990 HB3 ARG B 119 -14.443 37.683 -49.639 1.00 61.51 H ATOM 7991 HB2 ARG B 119 -14.518 38.208 -47.989 1.00 61.51 H ATOM 7992 HG3 ARG B 119 -12.477 39.738 -48.462 1.00 64.77 H ATOM 7993 HG2 ARG B 119 -12.499 39.092 -50.070 1.00 64.77 H ATOM 7994 HD3 ARG B 119 -12.232 37.286 -47.650 1.00 68.11 H ATOM 7995 HD2 ARG B 119 -10.827 38.024 -48.372 1.00 68.11 H ATOM 7996 HE ARG B 119 -12.631 36.565 -50.198 1.00 72.07 H ATOM 7997 HH12 ARG B 119 -9.423 34.531 -48.752 1.00 75.72 H ATOM 7998 HH11 ARG B 119 -9.828 36.065 -48.017 1.00 75.72 H ATOM 7999 HH22 ARG B 119 -10.642 33.706 -50.476 1.00 77.44 H ATOM 8000 HH21 ARG B 119 -12.024 34.561 -51.108 1.00 77.44 H ATOM 8001 N PHE B 120 -17.498 39.593 -48.604 1.00 55.81 N ATOM 8002 CA PHE B 120 -18.881 39.090 -48.568 1.00 55.43 C ATOM 8003 C PHE B 120 -19.921 40.210 -48.388 1.00 55.10 C ATOM 8004 O PHE B 120 -21.005 39.942 -47.869 1.00 52.53 O ATOM 8005 CB PHE B 120 -19.028 37.973 -47.506 1.00 55.05 C ATOM 8006 CG PHE B 120 -18.148 36.756 -47.724 1.00 51.61 C ATOM 8007 CD1 PHE B 120 -18.502 35.796 -48.693 1.00 47.64 C ATOM 8008 CD2 PHE B 120 -16.890 36.659 -47.096 1.00 50.31 C ATOM 8009 CE1 PHE B 120 -17.641 34.748 -48.987 1.00 50.84 C ATOM 8010 CE2 PHE B 120 -16.039 35.610 -47.409 1.00 51.41 C ATOM 8011 CZ PHE B 120 -16.412 34.658 -48.348 1.00 51.42 C ATOM 8012 H PHE B 120 -17.213 40.175 -47.829 1.00 55.81 H ATOM 8013 HA PHE B 120 -19.139 38.647 -49.530 1.00 55.43 H ATOM 8014 HB3 PHE B 120 -20.059 37.616 -47.481 1.00 55.05 H ATOM 8015 HB2 PHE B 120 -18.832 38.378 -46.516 1.00 55.05 H ATOM 8016 HD1 PHE B 120 -19.441 35.884 -49.216 1.00 47.64 H ATOM 8017 HD2 PHE B 120 -16.581 37.406 -46.381 1.00 50.31 H ATOM 8018 HE1 PHE B 120 -17.922 34.011 -49.725 1.00 50.84 H ATOM 8019 HE2 PHE B 120 -15.076 35.544 -46.929 1.00 51.41 H ATOM 8020 HZ PHE B 120 -15.738 33.849 -48.590 1.00 51.42 H ATOM 8021 N SER B 121 -19.602 41.439 -48.836 1.00 56.28 N ATOM 8022 CA SER B 121 -20.500 42.601 -48.763 1.00 58.60 C ATOM 8023 C SER B 121 -21.783 42.480 -49.615 1.00 59.09 C ATOM 8024 O SER B 121 -22.769 43.145 -49.298 1.00 60.92 O ATOM 8025 CB SER B 121 -19.711 43.889 -49.072 1.00 59.90 C ATOM 8026 OG SER B 121 -19.371 44.006 -50.440 1.00 64.94 O ATOM 8027 H SER B 121 -18.698 41.596 -49.258 1.00 56.28 H ATOM 8028 HA SER B 121 -20.819 42.672 -47.723 1.00 58.60 H ATOM 8029 HB3 SER B 121 -18.804 43.929 -48.472 1.00 59.90 H ATOM 8030 HB2 SER B 121 -20.303 44.762 -48.795 1.00 59.90 H ATOM 8031 HG SER B 121 -18.631 43.419 -50.623 1.00 64.94 H ATOM 8032 N TYR B 122 -21.760 41.607 -50.640 1.00 59.21 N ATOM 8033 CA TYR B 122 -22.910 41.233 -51.469 1.00 60.83 C ATOM 8034 C TYR B 122 -24.016 40.486 -50.699 1.00 62.87 C ATOM 8035 O TYR B 122 -25.170 40.543 -51.119 1.00 64.66 O ATOM 8036 CB TYR B 122 -22.420 40.395 -52.671 1.00 59.48 C ATOM 8037 CG TYR B 122 -21.726 39.073 -52.356 1.00 60.74 C ATOM 8038 CD1 TYR B 122 -22.475 37.901 -52.105 1.00 59.27 C ATOM 8039 CD2 TYR B 122 -20.318 39.004 -52.358 1.00 53.96 C ATOM 8040 CE1 TYR B 122 -21.825 36.668 -51.898 1.00 61.47 C ATOM 8041 CE2 TYR B 122 -19.669 37.771 -52.155 1.00 57.19 C ATOM 8042 CZ TYR B 122 -20.419 36.601 -51.938 1.00 59.07 C ATOM 8043 OH TYR B 122 -19.773 35.410 -51.783 1.00 60.78 O ATOM 8044 H TYR B 122 -20.904 41.107 -50.830 1.00 59.21 H ATOM 8045 HA TYR B 122 -23.349 42.155 -51.855 1.00 60.83 H ATOM 8046 HB3 TYR B 122 -21.746 41.002 -53.276 1.00 59.48 H ATOM 8047 HB2 TYR B 122 -23.266 40.176 -53.325 1.00 59.48 H ATOM 8048 HD1 TYR B 122 -23.555 37.934 -52.105 1.00 59.27 H ATOM 8049 HD2 TYR B 122 -19.730 39.891 -52.540 1.00 53.96 H ATOM 8050 HE1 TYR B 122 -22.409 35.774 -51.734 1.00 61.47 H ATOM 8051 HE2 TYR B 122 -18.592 37.716 -52.192 1.00 57.19 H ATOM 8052 HH TYR B 122 -20.349 34.641 -51.743 1.00 60.78 H ATOM 8053 N ALA B 123 -23.632 39.792 -49.615 1.00 64.38 N ATOM 8054 CA ALA B 123 -24.508 39.001 -48.758 1.00 64.25 C ATOM 8055 C ALA B 123 -24.810 39.707 -47.428 1.00 65.76 C ATOM 8056 O ALA B 123 -25.880 39.472 -46.868 1.00 66.78 O ATOM 8057 CB ALA B 123 -23.821 37.653 -48.496 1.00 63.26 C ATOM 8058 H ALA B 123 -22.657 39.801 -49.351 1.00 64.38 H ATOM 8059 HA ALA B 123 -25.459 38.805 -49.256 1.00 64.25 H ATOM 8060 HB1 ALA B 123 -24.353 37.073 -47.744 1.00 63.26 H ATOM 8061 HB2 ALA B 123 -23.776 37.051 -49.404 1.00 63.26 H ATOM 8062 HB3 ALA B 123 -22.799 37.787 -48.136 1.00 63.26 H ATOM 8063 N PHE B 124 -23.867 40.536 -46.945 1.00 66.46 N ATOM 8064 CA PHE B 124 -23.907 41.173 -45.630 1.00 67.47 C ATOM 8065 C PHE B 124 -23.691 42.691 -45.793 1.00 68.87 C ATOM 8066 O PHE B 124 -22.539 43.128 -45.790 1.00 68.63 O ATOM 8067 CB PHE B 124 -22.823 40.539 -44.725 1.00 67.38 C ATOM 8068 CG PHE B 124 -22.950 39.038 -44.525 1.00 67.31 C ATOM 8069 CD1 PHE B 124 -24.127 38.477 -43.985 1.00 63.58 C ATOM 8070 CD2 PHE B 124 -21.888 38.185 -44.892 1.00 64.31 C ATOM 8071 CE1 PHE B 124 -24.236 37.100 -43.843 1.00 62.57 C ATOM 8072 CE2 PHE B 124 -22.010 36.813 -44.723 1.00 61.56 C ATOM 8073 CZ PHE B 124 -23.182 36.273 -44.209 1.00 59.77 C ATOM 8074 H PHE B 124 -23.014 40.672 -47.468 1.00 66.46 H ATOM 8075 HA PHE B 124 -24.860 40.990 -45.138 1.00 67.47 H ATOM 8076 HB3 PHE B 124 -22.854 41.007 -43.739 1.00 67.38 H ATOM 8077 HB2 PHE B 124 -21.829 40.750 -45.123 1.00 67.38 H ATOM 8078 HD1 PHE B 124 -24.952 39.111 -43.695 1.00 63.58 H ATOM 8079 HD2 PHE B 124 -20.980 38.596 -45.306 1.00 64.31 H ATOM 8080 HE1 PHE B 124 -25.142 36.670 -43.442 1.00 62.57 H ATOM 8081 HE2 PHE B 124 -21.194 36.162 -45.002 1.00 61.56 H ATOM 8082 HZ PHE B 124 -23.272 35.204 -44.087 1.00 59.77 H ATOM 8083 N PRO B 125 -24.783 43.483 -45.932 1.00 70.08 N ATOM 8084 CA PRO B 125 -24.672 44.953 -46.024 1.00 70.97 C ATOM 8085 C PRO B 125 -24.290 45.650 -44.700 1.00 71.48 C ATOM 8086 O PRO B 125 -23.786 46.771 -44.746 1.00 72.38 O ATOM 8087 CB PRO B 125 -26.056 45.384 -46.530 1.00 71.38 C ATOM 8088 CG PRO B 125 -27.005 44.330 -45.983 1.00 70.84 C ATOM 8089 CD PRO B 125 -26.180 43.048 -46.043 1.00 70.45 C ATOM 8090 HA PRO B 125 -23.921 45.224 -46.769 1.00 70.97 H ATOM 8091 HB3 PRO B 125 -26.066 45.354 -47.620 1.00 71.38 H ATOM 8092 HB2 PRO B 125 -26.340 46.395 -46.232 1.00 71.38 H ATOM 8093 HG3 PRO B 125 -27.946 44.265 -46.531 1.00 70.84 H ATOM 8094 HG2 PRO B 125 -27.240 44.563 -44.943 1.00 70.84 H ATOM 8095 HD2 PRO B 125 -26.493 42.368 -45.252 1.00 70.45 H ATOM 8096 HD3 PRO B 125 -26.314 42.548 -47.003 1.00 70.45 H ATOM 8097 N LYS B 126 -24.516 44.972 -43.561 1.00 70.62 N ATOM 8098 CA LYS B 126 -24.118 45.407 -42.224 1.00 69.33 C ATOM 8099 C LYS B 126 -22.823 44.697 -41.798 1.00 66.97 C ATOM 8100 O LYS B 126 -22.552 43.583 -42.252 1.00 66.25 O ATOM 8101 CB LYS B 126 -25.252 45.072 -41.230 1.00 69.86 C ATOM 8102 CG LYS B 126 -26.558 45.841 -41.496 1.00 70.23 C ATOM 8103 CD LYS B 126 -27.642 45.538 -40.450 0.00 70.50 C ATOM 8104 CE LYS B 126 -28.954 46.290 -40.728 0.00 70.53 C ATOM 8105 NZ LYS B 126 -29.980 45.997 -39.711 0.00 70.48 N1+ ATOM 8106 H LYS B 126 -24.922 44.049 -43.615 1.00 70.62 H ATOM 8107 HA LYS B 126 -23.945 46.485 -42.211 1.00 69.33 H ATOM 8108 HB3 LYS B 126 -24.919 45.308 -40.217 1.00 69.86 H ATOM 8109 HB2 LYS B 126 -25.449 43.999 -41.239 1.00 69.86 H ATOM 8110 HG3 LYS B 126 -26.938 45.592 -42.487 1.00 70.23 H ATOM 8111 HG2 LYS B 126 -26.353 46.912 -41.507 1.00 70.23 H ATOM 8112 HD3 LYS B 126 -27.266 45.803 -39.460 1.00 70.50 H ATOM 8113 HD2 LYS B 126 -27.828 44.463 -40.430 1.00 70.50 H ATOM 8114 HE3 LYS B 126 -29.346 46.016 -41.708 1.00 70.53 H ATOM 8115 HE2 LYS B 126 -28.776 47.366 -40.742 1.00 70.53 H ATOM 8116 HZ1 LYS B 126 -29.643 46.277 -38.801 1.00 70.48 H ATOM 8117 HZ2 LYS B 126 -30.825 46.507 -39.927 1.00 70.48 H ATOM 8118 HZ3 LYS B 126 -30.178 45.007 -39.705 1.00 70.48 H ATOM 8119 N GLU B 127 -22.074 45.343 -40.888 1.00 65.01 N ATOM 8120 CA GLU B 127 -20.904 44.775 -40.210 1.00 63.98 C ATOM 8121 C GLU B 127 -21.283 43.632 -39.250 1.00 62.09 C ATOM 8122 O GLU B 127 -22.425 43.575 -38.790 1.00 62.03 O ATOM 8123 CB GLU B 127 -20.166 45.891 -39.440 1.00 64.65 C ATOM 8124 CG GLU B 127 -19.563 46.980 -40.356 0.00 64.02 C ATOM 8125 CD GLU B 127 -18.752 48.071 -39.634 0.00 64.07 C ATOM 8126 OE1 GLU B 127 -18.796 48.144 -38.385 0.00 63.99 O ATOM 8127 OE2 GLU B 127 -18.079 48.831 -40.364 0.00 63.99 O1- ATOM 8128 H GLU B 127 -22.366 46.253 -40.563 1.00 65.01 H ATOM 8129 HA GLU B 127 -20.233 44.369 -40.969 1.00 63.98 H ATOM 8130 HB3 GLU B 127 -19.369 45.451 -38.838 1.00 64.65 H ATOM 8131 HB2 GLU B 127 -20.857 46.352 -38.732 1.00 64.65 H ATOM 8132 HG3 GLU B 127 -20.357 47.473 -40.918 1.00 64.02 H ATOM 8133 HG2 GLU B 127 -18.916 46.503 -41.094 1.00 64.02 H ATOM 8134 N PHE B 128 -20.296 42.764 -38.961 1.00 60.31 N ATOM 8135 CA PHE B 128 -20.379 41.611 -38.057 1.00 58.03 C ATOM 8136 C PHE B 128 -20.841 42.023 -36.635 1.00 58.92 C ATOM 8137 O PHE B 128 -20.068 42.687 -35.942 1.00 58.01 O ATOM 8138 CB PHE B 128 -18.991 40.934 -38.047 1.00 57.72 C ATOM 8139 CG PHE B 128 -18.860 39.693 -37.181 1.00 52.55 C ATOM 8140 CD1 PHE B 128 -19.528 38.504 -37.542 1.00 48.08 C ATOM 8141 CD2 PHE B 128 -18.139 39.735 -35.968 1.00 49.95 C ATOM 8142 CE1 PHE B 128 -19.424 37.379 -36.737 1.00 48.07 C ATOM 8143 CE2 PHE B 128 -18.045 38.596 -35.180 1.00 51.74 C ATOM 8144 CZ PHE B 128 -18.675 37.420 -35.569 1.00 46.44 C ATOM 8145 H PHE B 128 -19.391 42.911 -39.383 1.00 60.31 H ATOM 8146 HA PHE B 128 -21.069 40.904 -38.513 1.00 58.03 H ATOM 8147 HB3 PHE B 128 -18.228 41.653 -37.748 1.00 57.72 H ATOM 8148 HB2 PHE B 128 -18.736 40.638 -39.065 1.00 57.72 H ATOM 8149 HD1 PHE B 128 -20.117 38.463 -38.446 1.00 48.08 H ATOM 8150 HD2 PHE B 128 -17.650 40.646 -35.653 1.00 49.95 H ATOM 8151 HE1 PHE B 128 -19.927 36.467 -37.018 1.00 48.07 H ATOM 8152 HE2 PHE B 128 -17.484 38.625 -34.259 1.00 51.74 H ATOM 8153 HZ PHE B 128 -18.601 36.539 -34.951 1.00 46.44 H ATOM 8154 N PRO B 129 -22.102 41.703 -36.254 1.00 59.67 N ATOM 8155 CA PRO B 129 -22.732 42.300 -35.062 1.00 60.56 C ATOM 8156 C PRO B 129 -22.311 41.676 -33.718 1.00 61.23 C ATOM 8157 O PRO B 129 -22.576 42.279 -32.678 1.00 60.67 O ATOM 8158 CB PRO B 129 -24.231 42.098 -35.331 1.00 61.07 C ATOM 8159 CG PRO B 129 -24.296 40.788 -36.101 1.00 62.20 C ATOM 8160 CD PRO B 129 -23.046 40.841 -36.974 1.00 60.27 C ATOM 8161 HA PRO B 129 -22.518 43.370 -35.012 1.00 60.56 H ATOM 8162 HB3 PRO B 129 -24.599 42.911 -35.959 1.00 61.07 H ATOM 8163 HB2 PRO B 129 -24.845 42.080 -34.429 1.00 61.07 H ATOM 8164 HG3 PRO B 129 -25.217 40.661 -36.671 1.00 62.20 H ATOM 8165 HG2 PRO B 129 -24.220 39.955 -35.401 1.00 62.20 H ATOM 8166 HD2 PRO B 129 -22.644 39.842 -37.151 1.00 60.27 H ATOM 8167 HD3 PRO B 129 -23.292 41.287 -37.938 1.00 60.27 H ATOM 8168 N TYR B 130 -21.692 40.486 -33.759 1.00 61.66 N ATOM 8169 CA TYR B 130 -21.309 39.714 -32.581 1.00 61.54 C ATOM 8170 C TYR B 130 -19.964 40.170 -32.006 1.00 61.81 C ATOM 8171 O TYR B 130 -19.078 40.606 -32.742 1.00 63.65 O ATOM 8172 CB TYR B 130 -21.261 38.222 -32.950 1.00 60.97 C ATOM 8173 CG TYR B 130 -22.599 37.665 -33.392 1.00 57.84 C ATOM 8174 CD1 TYR B 130 -23.595 37.397 -32.431 1.00 55.55 C ATOM 8175 CD2 TYR B 130 -22.862 37.438 -34.759 1.00 53.59 C ATOM 8176 CE1 TYR B 130 -24.849 36.902 -32.831 1.00 56.08 C ATOM 8177 CE2 TYR B 130 -24.119 36.950 -35.161 1.00 55.44 C ATOM 8178 CZ TYR B 130 -25.108 36.677 -34.195 1.00 58.10 C ATOM 8179 OH TYR B 130 -26.318 36.185 -34.574 1.00 56.36 O ATOM 8180 H TYR B 130 -21.496 40.058 -34.652 1.00 61.66 H ATOM 8181 HA TYR B 130 -22.074 39.849 -31.813 1.00 61.54 H ATOM 8182 HB3 TYR B 130 -20.921 37.634 -32.096 1.00 60.97 H ATOM 8183 HB2 TYR B 130 -20.528 38.053 -33.736 1.00 60.97 H ATOM 8184 HD1 TYR B 130 -23.404 37.577 -31.385 1.00 55.55 H ATOM 8185 HD2 TYR B 130 -22.107 37.646 -35.503 1.00 53.59 H ATOM 8186 HE1 TYR B 130 -25.607 36.693 -32.089 1.00 56.08 H ATOM 8187 HE2 TYR B 130 -24.316 36.778 -36.209 1.00 55.44 H ATOM 8188 HH TYR B 130 -26.375 36.024 -35.524 1.00 56.36 H ATOM 8189 N ARG B 131 -19.852 40.007 -30.683 1.00 61.96 N ATOM 8190 CA ARG B 131 -18.654 40.248 -29.887 1.00 62.18 C ATOM 8191 C ARG B 131 -18.192 38.909 -29.279 1.00 61.96 C ATOM 8192 O ARG B 131 -18.857 37.887 -29.463 1.00 63.63 O ATOM 8193 CB ARG B 131 -19.012 41.337 -28.851 1.00 62.30 C ATOM 8194 CG ARG B 131 -17.812 42.050 -28.204 0.00 62.03 C ATOM 8195 CD ARG B 131 -18.255 43.218 -27.307 0.00 62.05 C ATOM 8196 NE ARG B 131 -17.126 44.086 -26.926 0.00 62.03 N ATOM 8197 CZ ARG B 131 -17.172 45.174 -26.133 0.00 62.01 C ATOM 8198 NH1 ARG B 131 -18.306 45.580 -25.541 0.00 61.95 N ATOM 8199 NH2 ARG B 131 -16.050 45.876 -25.931 0.00 61.94 N1+ ATOM 8200 H ARG B 131 -20.634 39.618 -30.171 1.00 61.96 H ATOM 8201 HA ARG B 131 -17.853 40.620 -30.529 1.00 62.18 H ATOM 8202 HB3 ARG B 131 -19.681 40.935 -28.091 1.00 62.30 H ATOM 8203 HB2 ARG B 131 -19.590 42.108 -29.365 1.00 62.30 H ATOM 8204 HG3 ARG B 131 -17.071 42.361 -28.942 1.00 62.03 H ATOM 8205 HG2 ARG B 131 -17.321 41.319 -27.563 1.00 62.03 H ATOM 8206 HD3 ARG B 131 -18.603 42.794 -26.365 1.00 62.05 H ATOM 8207 HD2 ARG B 131 -19.094 43.774 -27.728 1.00 62.05 H ATOM 8208 HE ARG B 131 -16.236 43.836 -27.333 1.00 62.03 H ATOM 8209 HH12 ARG B 131 -18.317 46.399 -24.951 1.00 61.95 H ATOM 8210 HH11 ARG B 131 -19.160 45.061 -25.683 1.00 61.95 H ATOM 8211 HH22 ARG B 131 -16.059 46.696 -25.341 1.00 61.94 H ATOM 8212 HH21 ARG B 131 -15.184 45.596 -26.368 1.00 61.94 H ATOM 8213 N MET B 132 -17.027 38.913 -28.612 1.00 62.07 N ATOM 8214 CA MET B 132 -16.346 37.706 -28.133 1.00 62.36 C ATOM 8215 C MET B 132 -17.137 36.847 -27.124 1.00 62.88 C ATOM 8216 O MET B 132 -16.957 35.632 -27.124 1.00 64.22 O ATOM 8217 CB MET B 132 -14.951 38.087 -27.599 1.00 61.77 C ATOM 8218 CG MET B 132 -14.000 36.891 -27.448 1.00 63.83 C ATOM 8219 SD MET B 132 -13.499 36.153 -29.029 1.00 62.17 S ATOM 8220 CE MET B 132 -13.320 34.426 -28.526 1.00 62.75 C ATOM 8221 H MET B 132 -16.520 39.779 -28.503 1.00 62.07 H ATOM 8222 HA MET B 132 -16.209 37.081 -29.016 1.00 62.36 H ATOM 8223 HB3 MET B 132 -15.045 38.603 -26.642 1.00 61.77 H ATOM 8224 HB2 MET B 132 -14.485 38.804 -28.277 1.00 61.77 H ATOM 8225 HG3 MET B 132 -14.442 36.120 -26.820 1.00 63.83 H ATOM 8226 HG2 MET B 132 -13.109 37.211 -26.915 1.00 63.83 H ATOM 8227 HE1 MET B 132 -12.946 33.840 -29.363 1.00 62.75 H ATOM 8228 HE2 MET B 132 -12.625 34.334 -27.693 1.00 62.75 H ATOM 8229 HE3 MET B 132 -14.283 34.016 -28.220 1.00 62.75 H ATOM 8230 N ASN B 133 -18.024 37.461 -26.323 1.00 63.01 N ATOM 8231 CA ASN B 133 -18.921 36.755 -25.397 1.00 62.10 C ATOM 8232 C ASN B 133 -19.923 35.815 -26.103 1.00 59.83 C ATOM 8233 O ASN B 133 -20.258 34.774 -25.538 1.00 57.80 O ATOM 8234 CB ASN B 133 -19.631 37.759 -24.454 1.00 62.92 C ATOM 8235 CG ASN B 133 -20.533 38.784 -25.155 1.00 65.91 C ATOM 8236 OD1 ASN B 133 -20.047 39.657 -25.870 1.00 69.62 O ATOM 8237 ND2 ASN B 133 -21.848 38.686 -24.946 1.00 71.02 N ATOM 8238 H ASN B 133 -18.148 38.462 -26.385 1.00 63.01 H ATOM 8239 HA ASN B 133 -18.283 36.128 -24.771 1.00 62.10 H ATOM 8240 HB3 ASN B 133 -18.881 38.313 -23.888 1.00 62.92 H ATOM 8241 HB2 ASN B 133 -20.214 37.212 -23.711 1.00 62.92 H ATOM 8242 HD22 ASN B 133 -22.479 39.338 -25.389 1.00 71.02 H ATOM 8243 HD21 ASN B 133 -22.222 37.957 -24.356 1.00 71.02 H ATOM 8244 N HIS B 134 -20.349 36.181 -27.325 1.00 59.03 N ATOM 8245 CA HIS B 134 -21.230 35.379 -28.174 1.00 58.12 C ATOM 8246 C HIS B 134 -20.500 34.197 -28.835 1.00 56.47 C ATOM 8247 O HIS B 134 -21.116 33.144 -28.986 1.00 56.87 O ATOM 8248 CB HIS B 134 -21.902 36.265 -29.238 1.00 58.68 C ATOM 8249 CG HIS B 134 -22.617 37.483 -28.712 1.00 61.43 C ATOM 8250 ND1 HIS B 134 -22.121 38.780 -28.883 1.00 64.15 N ATOM 8251 CD2 HIS B 134 -23.817 37.550 -28.038 1.00 64.17 C ATOM 8252 CE1 HIS B 134 -23.032 39.567 -28.326 1.00 63.80 C ATOM 8253 NE2 HIS B 134 -24.060 38.892 -27.810 1.00 63.82 N ATOM 8254 H HIS B 134 -20.012 37.044 -27.731 1.00 59.03 H ATOM 8255 HA HIS B 134 -22.020 34.969 -27.541 1.00 58.12 H ATOM 8256 HB3 HIS B 134 -22.637 35.679 -29.790 1.00 58.68 H ATOM 8257 HB2 HIS B 134 -21.165 36.596 -29.970 1.00 58.68 H ATOM 8258 HD2 HIS B 134 -24.504 36.775 -27.730 1.00 64.17 H ATOM 8259 HE1 HIS B 134 -22.948 40.644 -28.295 1.00 63.80 H ATOM 8260 HE2 HIS B 134 -24.873 39.286 -27.358 1.00 63.82 H ATOM 8261 N ILE B 135 -19.209 34.374 -29.179 1.00 55.35 N ATOM 8262 CA ILE B 135 -18.327 33.310 -29.678 1.00 54.83 C ATOM 8263 C ILE B 135 -18.085 32.233 -28.602 1.00 54.63 C ATOM 8264 O ILE B 135 -18.181 31.046 -28.909 1.00 52.29 O ATOM 8265 CB ILE B 135 -16.931 33.848 -30.131 1.00 54.23 C ATOM 8266 CG1 ILE B 135 -17.017 34.904 -31.259 1.00 53.17 C ATOM 8267 CG2 ILE B 135 -15.899 32.749 -30.482 1.00 52.78 C ATOM 8268 CD1 ILE B 135 -17.298 34.346 -32.662 1.00 54.97 C ATOM 8269 H ILE B 135 -18.778 35.275 -29.030 1.00 55.35 H ATOM 8270 HA ILE B 135 -18.819 32.833 -30.527 1.00 54.83 H ATOM 8271 HB ILE B 135 -16.507 34.381 -29.282 1.00 54.23 H ATOM 8272 HG13 ILE B 135 -16.069 35.442 -31.296 1.00 53.17 H ATOM 8273 HG12 ILE B 135 -17.762 35.663 -31.017 1.00 53.17 H ATOM 8274 HG21 ILE B 135 -14.960 33.191 -30.795 1.00 52.78 H ATOM 8275 HG22 ILE B 135 -15.649 32.109 -29.636 1.00 52.78 H ATOM 8276 HG23 ILE B 135 -16.253 32.108 -31.289 1.00 52.78 H ATOM 8277 HD11 ILE B 135 -17.670 35.129 -33.320 1.00 54.97 H ATOM 8278 HD12 ILE B 135 -16.394 33.939 -33.114 1.00 54.97 H ATOM 8279 HD13 ILE B 135 -18.044 33.555 -32.643 1.00 54.97 H ATOM 8280 N LEU B 136 -17.784 32.679 -27.370 1.00 55.47 N ATOM 8281 CA LEU B 136 -17.518 31.835 -26.205 1.00 56.56 C ATOM 8282 C LEU B 136 -18.737 30.993 -25.788 1.00 56.50 C ATOM 8283 O LEU B 136 -18.567 29.809 -25.498 1.00 57.79 O ATOM 8284 CB LEU B 136 -17.029 32.726 -25.039 1.00 56.65 C ATOM 8285 CG LEU B 136 -15.592 33.276 -25.201 1.00 56.80 C ATOM 8286 CD1 LEU B 136 -15.293 34.359 -24.141 1.00 55.50 C ATOM 8287 CD2 LEU B 136 -14.519 32.166 -25.235 1.00 52.70 C ATOM 8288 H LEU B 136 -17.715 33.676 -27.215 1.00 55.47 H ATOM 8289 HA LEU B 136 -16.731 31.133 -26.483 1.00 56.56 H ATOM 8290 HB3 LEU B 136 -17.085 32.183 -24.097 1.00 56.65 H ATOM 8291 HB2 LEU B 136 -17.726 33.558 -24.928 1.00 56.65 H ATOM 8292 HG LEU B 136 -15.544 33.772 -26.168 1.00 56.80 H ATOM 8293 HD11 LEU B 136 -15.012 35.298 -24.618 1.00 55.50 H ATOM 8294 HD12 LEU B 136 -16.161 34.570 -23.515 1.00 55.50 H ATOM 8295 HD13 LEU B 136 -14.482 34.084 -23.467 1.00 55.50 H ATOM 8296 HD21 LEU B 136 -13.719 32.322 -24.511 1.00 52.70 H ATOM 8297 HD22 LEU B 136 -14.935 31.179 -25.038 1.00 52.70 H ATOM 8298 HD23 LEU B 136 -14.051 32.124 -26.217 1.00 52.70 H ATOM 8299 N GLU B 137 -19.939 31.598 -25.803 0.50 56.18 N ATOM 8300 CA GLU B 137 -21.208 30.914 -25.543 0.50 55.82 C ATOM 8301 C GLU B 137 -21.527 29.856 -26.617 0.50 55.23 C ATOM 8302 O GLU B 137 -21.834 28.715 -26.273 0.50 55.30 O ATOM 8303 CB GLU B 137 -22.331 31.968 -25.385 0.50 56.27 C ATOM 8304 CG GLU B 137 -23.755 31.425 -25.116 0.50 58.34 C ATOM 8305 CD GLU B 137 -23.896 30.753 -23.742 0.50 60.55 C ATOM 8306 OE1 GLU B 137 -24.296 31.461 -22.793 0.50 60.58 O ATOM 8307 OE2 GLU B 137 -23.605 29.540 -23.651 0.50 61.77 O1- ATOM 8308 H GLU B 137 -20.001 32.579 -26.039 0.50 56.18 H ATOM 8309 HA GLU B 137 -21.097 30.392 -24.591 0.50 55.82 H ATOM 8310 HB3 GLU B 137 -22.364 32.590 -26.281 0.50 56.27 H ATOM 8311 HB2 GLU B 137 -22.062 32.650 -24.577 0.50 56.27 H ATOM 8312 HG3 GLU B 137 -24.058 30.731 -25.900 0.50 58.34 H ATOM 8313 HG2 GLU B 137 -24.465 32.250 -25.179 0.50 58.34 H ATOM 8314 N CYS B 138 -21.385 30.251 -27.894 1.00 54.20 N ATOM 8315 CA CYS B 138 -21.547 29.417 -29.087 1.00 53.19 C ATOM 8316 C CYS B 138 -20.605 28.191 -29.114 1.00 52.72 C ATOM 8317 O CYS B 138 -21.007 27.139 -29.609 1.00 51.92 O ATOM 8318 CB CYS B 138 -21.421 30.296 -30.353 1.00 52.63 C ATOM 8319 SG CYS B 138 -21.657 29.402 -31.912 1.00 51.28 S ATOM 8320 H CYS B 138 -21.126 31.212 -28.075 1.00 54.20 H ATOM 8321 HA CYS B 138 -22.567 29.027 -29.061 1.00 53.19 H ATOM 8322 HB3 CYS B 138 -20.447 30.784 -30.387 1.00 52.63 H ATOM 8323 HB2 CYS B 138 -22.167 31.090 -30.322 1.00 52.63 H ATOM 8324 HG CYS B 138 -20.552 28.657 -31.816 1.00 51.28 H ATOM 8325 N GLU B 139 -19.388 28.342 -28.560 1.00 52.20 N ATOM 8326 CA GLU B 139 -18.364 27.300 -28.459 1.00 52.90 C ATOM 8327 C GLU B 139 -18.753 26.152 -27.507 1.00 53.14 C ATOM 8328 O GLU B 139 -18.437 25.001 -27.805 1.00 51.92 O ATOM 8329 CB GLU B 139 -17.020 27.956 -28.073 1.00 52.01 C ATOM 8330 CG GLU B 139 -15.820 26.992 -27.998 1.00 55.20 C ATOM 8331 CD GLU B 139 -14.513 27.716 -27.657 1.00 54.63 C ATOM 8332 OE1 GLU B 139 -14.421 28.259 -26.532 1.00 56.66 O ATOM 8333 OE2 GLU B 139 -13.611 27.707 -28.523 1.00 59.93 O1- ATOM 8334 H GLU B 139 -19.127 29.248 -28.195 1.00 52.20 H ATOM 8335 HA GLU B 139 -18.244 26.868 -29.454 1.00 52.90 H ATOM 8336 HB3 GLU B 139 -17.132 28.459 -27.114 1.00 52.01 H ATOM 8337 HB2 GLU B 139 -16.786 28.744 -28.788 1.00 52.01 H ATOM 8338 HG3 GLU B 139 -15.719 26.457 -28.944 1.00 55.20 H ATOM 8339 HG2 GLU B 139 -15.992 26.233 -27.237 1.00 55.20 H ATOM 8340 N PHE B 140 -19.453 26.478 -26.404 1.00 53.68 N ATOM 8341 CA PHE B 140 -20.013 25.502 -25.463 1.00 53.29 C ATOM 8342 C PHE B 140 -21.149 24.653 -26.064 1.00 52.33 C ATOM 8343 O PHE B 140 -21.173 23.450 -25.812 1.00 52.57 O ATOM 8344 CB PHE B 140 -20.424 26.192 -24.139 1.00 53.34 C ATOM 8345 CG PHE B 140 -19.417 26.097 -23.000 1.00 55.54 C ATOM 8346 CD1 PHE B 140 -18.039 26.331 -23.207 1.00 57.90 C ATOM 8347 CD2 PHE B 140 -19.877 25.897 -21.680 1.00 57.33 C ATOM 8348 CE1 PHE B 140 -17.160 26.291 -22.131 1.00 60.15 C ATOM 8349 CE2 PHE B 140 -18.980 25.846 -20.623 1.00 59.42 C ATOM 8350 CZ PHE B 140 -17.625 26.037 -20.849 1.00 63.02 C ATOM 8351 H PHE B 140 -19.683 27.447 -26.232 1.00 53.68 H ATOM 8352 HA PHE B 140 -19.219 24.788 -25.230 1.00 53.29 H ATOM 8353 HB3 PHE B 140 -21.350 25.745 -23.777 1.00 53.34 H ATOM 8354 HB2 PHE B 140 -20.663 27.244 -24.303 1.00 53.34 H ATOM 8355 HD1 PHE B 140 -17.660 26.536 -24.198 1.00 57.90 H ATOM 8356 HD2 PHE B 140 -20.929 25.766 -21.487 1.00 57.33 H ATOM 8357 HE1 PHE B 140 -16.107 26.463 -22.283 1.00 60.15 H ATOM 8358 HE2 PHE B 140 -19.338 25.662 -19.621 1.00 59.42 H ATOM 8359 HZ PHE B 140 -16.929 25.999 -20.023 1.00 63.02 H ATOM 8360 N TYR B 141 -22.023 25.269 -26.884 1.00 51.27 N ATOM 8361 CA TYR B 141 -23.056 24.570 -27.660 1.00 51.52 C ATOM 8362 C TYR B 141 -22.475 23.668 -28.764 1.00 51.76 C ATOM 8363 O TYR B 141 -23.009 22.581 -28.987 1.00 53.94 O ATOM 8364 CB TYR B 141 -24.037 25.587 -28.282 1.00 49.89 C ATOM 8365 CG TYR B 141 -25.031 26.205 -27.317 1.00 54.27 C ATOM 8366 CD1 TYR B 141 -26.107 25.433 -26.837 1.00 56.52 C ATOM 8367 CD2 TYR B 141 -24.912 27.553 -26.924 1.00 57.24 C ATOM 8368 CE1 TYR B 141 -27.065 26.004 -25.977 1.00 56.71 C ATOM 8369 CE2 TYR B 141 -25.862 28.123 -26.055 1.00 58.07 C ATOM 8370 CZ TYR B 141 -26.943 27.352 -25.586 1.00 60.27 C ATOM 8371 OH TYR B 141 -27.872 27.918 -24.762 1.00 58.80 O ATOM 8372 H TYR B 141 -21.949 26.266 -27.032 1.00 51.27 H ATOM 8373 HA TYR B 141 -23.611 23.930 -26.971 1.00 51.52 H ATOM 8374 HB3 TYR B 141 -24.639 25.088 -29.044 1.00 49.89 H ATOM 8375 HB2 TYR B 141 -23.494 26.372 -28.810 1.00 49.89 H ATOM 8376 HD1 TYR B 141 -26.200 24.401 -27.139 1.00 56.52 H ATOM 8377 HD2 TYR B 141 -24.102 28.160 -27.298 1.00 57.24 H ATOM 8378 HE1 TYR B 141 -27.893 25.405 -25.628 1.00 56.71 H ATOM 8379 HE2 TYR B 141 -25.769 29.158 -25.763 1.00 58.07 H ATOM 8380 HH TYR B 141 -27.689 28.847 -24.597 1.00 58.80 H ATOM 8381 N LEU B 142 -21.398 24.129 -29.424 1.00 51.75 N ATOM 8382 CA LEU B 142 -20.693 23.410 -30.486 1.00 51.38 C ATOM 8383 C LEU B 142 -19.988 22.143 -29.967 1.00 51.58 C ATOM 8384 O LEU B 142 -20.138 21.089 -30.583 1.00 48.47 O ATOM 8385 CB LEU B 142 -19.735 24.391 -31.205 1.00 51.10 C ATOM 8386 CG LEU B 142 -18.891 23.809 -32.363 1.00 49.32 C ATOM 8387 CD1 LEU B 142 -19.747 23.221 -33.505 1.00 47.82 C ATOM 8388 CD2 LEU B 142 -17.903 24.862 -32.889 1.00 48.75 C ATOM 8389 H LEU B 142 -21.037 25.046 -29.197 1.00 51.75 H ATOM 8390 HA LEU B 142 -21.449 23.088 -31.204 1.00 51.38 H ATOM 8391 HB3 LEU B 142 -19.056 24.814 -30.465 1.00 51.10 H ATOM 8392 HB2 LEU B 142 -20.314 25.233 -31.586 1.00 51.10 H ATOM 8393 HG LEU B 142 -18.276 23.005 -31.963 1.00 49.32 H ATOM 8394 HD11 LEU B 142 -19.430 23.585 -34.483 1.00 47.82 H ATOM 8395 HD12 LEU B 142 -19.671 22.133 -33.527 1.00 47.82 H ATOM 8396 HD13 LEU B 142 -20.801 23.474 -33.402 1.00 47.82 H ATOM 8397 HD21 LEU B 142 -17.171 24.407 -33.556 1.00 48.75 H ATOM 8398 HD22 LEU B 142 -18.415 25.650 -33.440 1.00 48.75 H ATOM 8399 HD23 LEU B 142 -17.353 25.336 -32.076 1.00 48.75 H ATOM 8400 N LEU B 143 -19.267 22.257 -28.835 1.00 52.79 N ATOM 8401 CA LEU B 143 -18.573 21.140 -28.187 1.00 54.35 C ATOM 8402 C LEU B 143 -19.546 20.089 -27.613 1.00 54.70 C ATOM 8403 O LEU B 143 -19.278 18.895 -27.754 1.00 56.02 O ATOM 8404 CB LEU B 143 -17.612 21.680 -27.102 1.00 54.08 C ATOM 8405 CG LEU B 143 -16.625 20.625 -26.543 1.00 59.65 C ATOM 8406 CD1 LEU B 143 -15.554 20.252 -27.583 1.00 58.51 C ATOM 8407 CD2 LEU B 143 -15.986 21.071 -25.213 1.00 60.09 C ATOM 8408 H LEU B 143 -19.182 23.159 -28.385 1.00 52.79 H ATOM 8409 HA LEU B 143 -17.977 20.651 -28.960 1.00 54.35 H ATOM 8410 HB3 LEU B 143 -18.214 22.092 -26.291 1.00 54.08 H ATOM 8411 HB2 LEU B 143 -17.043 22.524 -27.495 1.00 54.08 H ATOM 8412 HG LEU B 143 -17.176 19.716 -26.307 1.00 59.65 H ATOM 8413 HD11 LEU B 143 -14.685 19.785 -27.121 1.00 58.51 H ATOM 8414 HD12 LEU B 143 -15.947 19.545 -28.313 1.00 58.51 H ATOM 8415 HD13 LEU B 143 -15.209 21.129 -28.131 1.00 58.51 H ATOM 8416 HD21 LEU B 143 -16.235 20.374 -24.412 1.00 60.09 H ATOM 8417 HD22 LEU B 143 -14.899 21.118 -25.268 1.00 60.09 H ATOM 8418 HD23 LEU B 143 -16.338 22.054 -24.904 1.00 60.09 H ATOM 8419 N GLU B 144 -20.659 20.554 -27.010 1.00 54.61 N ATOM 8420 CA GLU B 144 -21.746 19.727 -26.474 1.00 54.67 C ATOM 8421 C GLU B 144 -22.402 18.841 -27.547 1.00 54.65 C ATOM 8422 O GLU B 144 -22.562 17.642 -27.319 1.00 55.11 O ATOM 8423 CB GLU B 144 -22.778 20.631 -25.759 1.00 55.50 C ATOM 8424 CG GLU B 144 -24.029 19.905 -25.198 1.00 58.28 C ATOM 8425 CD GLU B 144 -25.066 20.810 -24.510 1.00 63.56 C ATOM 8426 OE1 GLU B 144 -24.992 22.050 -24.661 1.00 64.83 O ATOM 8427 OE2 GLU B 144 -25.948 20.236 -23.832 1.00 64.92 O1- ATOM 8428 H GLU B 144 -20.792 21.553 -26.928 1.00 54.61 H ATOM 8429 HA GLU B 144 -21.307 19.065 -25.726 1.00 54.67 H ATOM 8430 HB3 GLU B 144 -23.089 21.419 -26.447 1.00 55.50 H ATOM 8431 HB2 GLU B 144 -22.279 21.137 -24.932 1.00 55.50 H ATOM 8432 HG3 GLU B 144 -23.708 19.136 -24.494 1.00 58.28 H ATOM 8433 HG2 GLU B 144 -24.558 19.388 -25.999 1.00 58.28 H ATOM 8434 N LEU B 145 -22.739 19.454 -28.696 1.00 52.81 N ATOM 8435 CA LEU B 145 -23.330 18.793 -29.859 1.00 53.70 C ATOM 8436 C LEU B 145 -22.440 17.689 -30.442 1.00 51.72 C ATOM 8437 O LEU B 145 -22.940 16.594 -30.709 1.00 53.17 O ATOM 8438 CB LEU B 145 -23.698 19.850 -30.923 1.00 54.14 C ATOM 8439 CG LEU B 145 -24.168 19.264 -32.279 1.00 58.14 C ATOM 8440 CD1 LEU B 145 -25.385 19.995 -32.842 1.00 60.92 C ATOM 8441 CD2 LEU B 145 -23.044 19.169 -33.327 1.00 60.76 C ATOM 8442 H LEU B 145 -22.582 20.448 -28.787 1.00 52.81 H ATOM 8443 HA LEU B 145 -24.256 18.320 -29.525 1.00 53.70 H ATOM 8444 HB3 LEU B 145 -22.859 20.526 -31.096 1.00 54.14 H ATOM 8445 HB2 LEU B 145 -24.478 20.479 -30.491 1.00 54.14 H ATOM 8446 HG LEU B 145 -24.533 18.252 -32.098 1.00 58.14 H ATOM 8447 HD11 LEU B 145 -25.972 19.287 -33.421 1.00 60.92 H ATOM 8448 HD12 LEU B 145 -26.021 20.410 -32.062 1.00 60.92 H ATOM 8449 HD13 LEU B 145 -25.119 20.811 -33.505 1.00 60.92 H ATOM 8450 HD21 LEU B 145 -23.427 18.741 -34.250 1.00 60.76 H ATOM 8451 HD22 LEU B 145 -22.613 20.145 -33.548 1.00 60.76 H ATOM 8452 HD23 LEU B 145 -22.231 18.518 -33.020 1.00 60.76 H ATOM 8453 N MET B 146 -21.150 18.007 -30.643 1.00 49.21 N ATOM 8454 CA MET B 146 -20.171 17.090 -31.226 1.00 47.74 C ATOM 8455 C MET B 146 -19.795 15.918 -30.305 1.00 46.40 C ATOM 8456 O MET B 146 -19.106 15.015 -30.770 1.00 44.43 O ATOM 8457 CB MET B 146 -18.926 17.864 -31.693 1.00 45.39 C ATOM 8458 CG MET B 146 -19.208 18.782 -32.894 1.00 43.49 C ATOM 8459 SD MET B 146 -17.738 19.456 -33.704 1.00 50.27 S ATOM 8460 CE MET B 146 -16.876 20.208 -32.299 1.00 46.10 C ATOM 8461 H MET B 146 -20.817 18.931 -30.402 1.00 49.21 H ATOM 8462 HA MET B 146 -20.624 16.651 -32.113 1.00 47.74 H ATOM 8463 HB3 MET B 146 -18.131 17.171 -31.972 1.00 45.39 H ATOM 8464 HB2 MET B 146 -18.536 18.451 -30.860 1.00 45.39 H ATOM 8465 HG3 MET B 146 -19.852 19.610 -32.605 1.00 43.49 H ATOM 8466 HG2 MET B 146 -19.758 18.228 -33.657 1.00 43.49 H ATOM 8467 HE1 MET B 146 -16.033 20.804 -32.648 1.00 46.10 H ATOM 8468 HE2 MET B 146 -17.548 20.849 -31.732 1.00 46.10 H ATOM 8469 HE3 MET B 146 -16.493 19.435 -31.634 1.00 46.10 H ATOM 8470 N ASP B 147 -20.262 15.938 -29.042 1.00 49.52 N ATOM 8471 CA ASP B 147 -20.008 14.937 -28.003 1.00 51.41 C ATOM 8472 C ASP B 147 -18.514 14.941 -27.610 1.00 51.39 C ATOM 8473 O ASP B 147 -17.933 13.886 -27.366 1.00 52.39 O ATOM 8474 CB ASP B 147 -20.567 13.537 -28.401 1.00 52.20 C ATOM 8475 CG ASP B 147 -20.700 12.478 -27.291 1.00 57.92 C ATOM 8476 OD1 ASP B 147 -20.740 12.845 -26.095 1.00 61.74 O ATOM 8477 OD2 ASP B 147 -20.862 11.299 -27.677 1.00 59.76 O1- ATOM 8478 H ASP B 147 -20.843 16.714 -28.755 1.00 49.52 H ATOM 8479 HA ASP B 147 -20.555 15.297 -27.131 1.00 51.41 H ATOM 8480 HB3 ASP B 147 -19.962 13.118 -29.207 1.00 52.20 H ATOM 8481 HB2 ASP B 147 -21.557 13.671 -28.838 1.00 52.20 H ATOM 8482 N CYS B 148 -17.910 16.146 -27.598 1.00 51.62 N ATOM 8483 CA CYS B 148 -16.499 16.419 -27.312 1.00 51.66 C ATOM 8484 C CYS B 148 -15.511 15.868 -28.370 1.00 50.65 C ATOM 8485 O CYS B 148 -14.311 15.805 -28.098 1.00 51.99 O ATOM 8486 CB CYS B 148 -16.113 16.029 -25.869 1.00 52.61 C ATOM 8487 SG CYS B 148 -16.953 17.148 -24.714 1.00 56.00 S ATOM 8488 H CYS B 148 -18.470 16.963 -27.807 1.00 51.62 H ATOM 8489 HA CYS B 148 -16.396 17.500 -27.392 1.00 51.66 H ATOM 8490 HB3 CYS B 148 -15.044 16.113 -25.706 1.00 52.61 H ATOM 8491 HB2 CYS B 148 -16.377 14.999 -25.632 1.00 52.61 H ATOM 8492 HG CYS B 148 -18.188 16.707 -24.969 1.00 56.00 H ATOM 8493 N CYS B 149 -16.019 15.506 -29.562 1.00 49.06 N ATOM 8494 CA CYS B 149 -15.249 14.971 -30.684 1.00 48.60 C ATOM 8495 C CYS B 149 -14.605 16.133 -31.463 1.00 48.46 C ATOM 8496 O CYS B 149 -15.315 16.861 -32.159 1.00 48.30 O ATOM 8497 CB CYS B 149 -16.136 14.119 -31.611 1.00 49.02 C ATOM 8498 SG CYS B 149 -16.834 12.706 -30.707 1.00 50.85 S ATOM 8499 H CYS B 149 -17.016 15.579 -29.712 1.00 49.06 H ATOM 8500 HA CYS B 149 -14.458 14.325 -30.296 1.00 48.60 H ATOM 8501 HB3 CYS B 149 -15.550 13.730 -32.440 1.00 49.02 H ATOM 8502 HB2 CYS B 149 -16.942 14.708 -32.048 1.00 49.02 H ATOM 8503 HG CYS B 149 -15.696 12.005 -30.657 1.00 50.85 H ATOM 8504 N LEU B 150 -13.282 16.291 -31.302 1.00 47.91 N ATOM 8505 CA LEU B 150 -12.490 17.405 -31.831 1.00 47.81 C ATOM 8506 C LEU B 150 -11.430 16.954 -32.852 1.00 48.07 C ATOM 8507 O LEU B 150 -11.100 17.747 -33.733 1.00 47.49 O ATOM 8508 CB LEU B 150 -11.794 18.133 -30.658 1.00 47.48 C ATOM 8509 CG LEU B 150 -12.735 18.851 -29.665 1.00 48.91 C ATOM 8510 CD1 LEU B 150 -11.956 19.314 -28.419 1.00 49.54 C ATOM 8511 CD2 LEU B 150 -13.496 20.019 -30.326 1.00 42.98 C ATOM 8512 H LEU B 150 -12.778 15.635 -30.716 1.00 47.91 H ATOM 8513 HA LEU B 150 -13.140 18.111 -32.350 1.00 47.81 H ATOM 8514 HB3 LEU B 150 -11.084 18.863 -31.046 1.00 47.48 H ATOM 8515 HB2 LEU B 150 -11.198 17.403 -30.111 1.00 47.48 H ATOM 8516 HG LEU B 150 -13.481 18.137 -29.316 1.00 48.91 H ATOM 8517 HD11 LEU B 150 -12.384 20.205 -27.959 1.00 49.54 H ATOM 8518 HD12 LEU B 150 -11.946 18.535 -27.658 1.00 49.54 H ATOM 8519 HD13 LEU B 150 -10.921 19.548 -28.662 1.00 49.54 H ATOM 8520 HD21 LEU B 150 -13.349 20.964 -29.803 1.00 42.98 H ATOM 8521 HD22 LEU B 150 -13.186 20.189 -31.354 1.00 42.98 H ATOM 8522 HD23 LEU B 150 -14.566 19.820 -30.342 1.00 42.98 H ATOM 8523 N ILE B 151 -10.909 15.719 -32.737 1.00 47.64 N ATOM 8524 CA ILE B 151 -9.943 15.147 -33.682 1.00 47.15 C ATOM 8525 C ILE B 151 -10.675 14.704 -34.963 1.00 46.47 C ATOM 8526 O ILE B 151 -11.621 13.924 -34.872 1.00 48.40 O ATOM 8527 CB ILE B 151 -9.182 13.933 -33.063 1.00 48.21 C ATOM 8528 CG1 ILE B 151 -8.357 14.338 -31.816 1.00 48.60 C ATOM 8529 CG2 ILE B 151 -8.302 13.139 -34.058 1.00 44.78 C ATOM 8530 CD1 ILE B 151 -7.271 15.400 -32.054 1.00 47.97 C ATOM 8531 H ILE B 151 -11.210 15.116 -31.982 1.00 47.64 H ATOM 8532 HA ILE B 151 -9.216 15.916 -33.951 1.00 47.15 H ATOM 8533 HB ILE B 151 -9.936 13.232 -32.704 1.00 48.21 H ATOM 8534 HG13 ILE B 151 -7.893 13.456 -31.375 1.00 48.60 H ATOM 8535 HG12 ILE B 151 -9.034 14.711 -31.049 1.00 48.60 H ATOM 8536 HG21 ILE B 151 -7.743 12.356 -33.544 1.00 44.78 H ATOM 8537 HG22 ILE B 151 -8.894 12.641 -34.826 1.00 44.78 H ATOM 8538 HG23 ILE B 151 -7.582 13.783 -34.562 1.00 44.78 H ATOM 8539 HD11 ILE B 151 -6.621 15.482 -31.182 1.00 47.97 H ATOM 8540 HD12 ILE B 151 -6.642 15.158 -32.909 1.00 47.97 H ATOM 8541 HD13 ILE B 151 -7.708 16.385 -32.222 1.00 47.97 H ATOM 8542 N VAL B 152 -10.237 15.230 -36.119 1.00 45.97 N ATOM 8543 CA VAL B 152 -10.871 15.004 -37.418 1.00 45.32 C ATOM 8544 C VAL B 152 -9.796 14.604 -38.446 1.00 45.19 C ATOM 8545 O VAL B 152 -8.736 15.230 -38.500 1.00 44.76 O ATOM 8546 CB VAL B 152 -11.591 16.289 -37.930 1.00 45.33 C ATOM 8547 CG1 VAL B 152 -12.284 16.106 -39.290 1.00 46.26 C ATOM 8548 CG2 VAL B 152 -12.639 16.810 -36.931 1.00 42.41 C ATOM 8549 H VAL B 152 -9.443 15.855 -36.119 1.00 45.97 H ATOM 8550 HA VAL B 152 -11.600 14.194 -37.353 1.00 45.32 H ATOM 8551 HB VAL B 152 -10.845 17.077 -38.053 1.00 45.33 H ATOM 8552 HG11 VAL B 152 -12.741 17.041 -39.607 1.00 46.26 H ATOM 8553 HG12 VAL B 152 -11.603 15.799 -40.081 1.00 46.26 H ATOM 8554 HG13 VAL B 152 -13.073 15.359 -39.223 1.00 46.26 H ATOM 8555 HG21 VAL B 152 -13.169 17.679 -37.325 1.00 42.41 H ATOM 8556 HG22 VAL B 152 -13.380 16.046 -36.699 1.00 42.41 H ATOM 8557 HG23 VAL B 152 -12.178 17.121 -35.996 1.00 42.41 H ATOM 8558 N TYR B 153 -10.113 13.579 -39.252 1.00 44.96 N ATOM 8559 CA TYR B 153 -9.267 13.047 -40.322 1.00 45.05 C ATOM 8560 C TYR B 153 -9.705 13.639 -41.669 1.00 44.68 C ATOM 8561 O TYR B 153 -10.904 13.808 -41.892 1.00 46.37 O ATOM 8562 CB TYR B 153 -9.389 11.511 -40.349 1.00 45.50 C ATOM 8563 CG TYR B 153 -8.905 10.808 -39.095 1.00 46.61 C ATOM 8564 CD1 TYR B 153 -9.740 10.751 -37.961 1.00 49.30 C ATOM 8565 CD2 TYR B 153 -7.632 10.200 -39.059 1.00 45.22 C ATOM 8566 CE1 TYR B 153 -9.301 10.104 -36.796 1.00 50.76 C ATOM 8567 CE2 TYR B 153 -7.199 9.538 -37.893 1.00 49.27 C ATOM 8568 CZ TYR B 153 -8.037 9.492 -36.762 1.00 49.86 C ATOM 8569 OH TYR B 153 -7.634 8.859 -35.628 1.00 45.96 O ATOM 8570 H TYR B 153 -11.020 13.142 -39.156 1.00 44.96 H ATOM 8571 HA TYR B 153 -8.223 13.310 -40.139 1.00 45.05 H ATOM 8572 HB3 TYR B 153 -8.824 11.114 -41.194 1.00 45.50 H ATOM 8573 HB2 TYR B 153 -10.429 11.221 -40.514 1.00 45.50 H ATOM 8574 HD1 TYR B 153 -10.718 11.209 -37.976 1.00 49.30 H ATOM 8575 HD2 TYR B 153 -6.986 10.233 -39.924 1.00 45.22 H ATOM 8576 HE1 TYR B 153 -9.938 10.082 -35.928 1.00 50.76 H ATOM 8577 HE2 TYR B 153 -6.227 9.067 -37.874 1.00 49.27 H ATOM 8578 HH TYR B 153 -6.706 8.597 -35.661 1.00 45.96 H ATOM 8579 N HIS B 154 -8.722 13.933 -42.538 1.00 45.16 N ATOM 8580 CA HIS B 154 -8.929 14.599 -43.829 1.00 43.57 C ATOM 8581 C HIS B 154 -8.206 13.857 -44.970 1.00 43.96 C ATOM 8582 O HIS B 154 -7.236 13.151 -44.688 1.00 43.35 O ATOM 8583 CB HIS B 154 -8.423 16.050 -43.738 1.00 44.14 C ATOM 8584 CG HIS B 154 -9.094 16.880 -42.677 1.00 43.00 C ATOM 8585 ND1 HIS B 154 -10.472 17.116 -42.676 1.00 43.54 N ATOM 8586 CD2 HIS B 154 -8.529 17.502 -41.584 1.00 43.41 C ATOM 8587 CE1 HIS B 154 -10.683 17.859 -41.603 1.00 45.24 C ATOM 8588 NE2 HIS B 154 -9.571 18.115 -40.916 1.00 46.09 N ATOM 8589 H HIS B 154 -7.763 13.727 -42.299 1.00 45.16 H ATOM 8590 HA HIS B 154 -9.997 14.607 -44.029 1.00 43.57 H ATOM 8591 HB3 HIS B 154 -8.572 16.558 -44.690 1.00 44.14 H ATOM 8592 HB2 HIS B 154 -7.349 16.057 -43.546 1.00 44.14 H ATOM 8593 HD2 HIS B 154 -7.508 17.555 -41.236 1.00 43.41 H ATOM 8594 HE1 HIS B 154 -11.659 18.221 -41.316 1.00 45.24 H ATOM 8595 HE2 HIS B 154 -9.501 18.670 -40.069 1.00 46.09 H ATOM 8596 N PRO B 155 -8.665 14.029 -46.238 1.00 43.55 N ATOM 8597 CA PRO B 155 -8.076 13.331 -47.398 1.00 43.38 C ATOM 8598 C PRO B 155 -6.642 13.740 -47.782 1.00 44.66 C ATOM 8599 O PRO B 155 -6.035 13.020 -48.568 1.00 45.11 O ATOM 8600 CB PRO B 155 -9.052 13.611 -48.559 1.00 42.44 C ATOM 8601 CG PRO B 155 -10.332 14.084 -47.901 1.00 43.02 C ATOM 8602 CD PRO B 155 -9.827 14.811 -46.669 1.00 41.70 C ATOM 8603 HA PRO B 155 -8.088 12.263 -47.176 1.00 43.38 H ATOM 8604 HB3 PRO B 155 -9.223 12.740 -49.189 1.00 42.44 H ATOM 8605 HB2 PRO B 155 -8.669 14.398 -49.207 1.00 42.44 H ATOM 8606 HG3 PRO B 155 -10.923 13.222 -47.590 1.00 43.02 H ATOM 8607 HG2 PRO B 155 -10.952 14.705 -48.548 1.00 43.02 H ATOM 8608 HD2 PRO B 155 -9.491 15.816 -46.929 1.00 41.70 H ATOM 8609 HD3 PRO B 155 -10.642 14.895 -45.954 1.00 41.70 H ATOM 8610 N TYR B 156 -6.123 14.858 -47.243 1.00 45.15 N ATOM 8611 CA TYR B 156 -4.801 15.415 -47.556 1.00 47.19 C ATOM 8612 C TYR B 156 -3.625 14.459 -47.283 1.00 51.05 C ATOM 8613 O TYR B 156 -2.716 14.386 -48.109 1.00 51.03 O ATOM 8614 CB TYR B 156 -4.594 16.730 -46.775 1.00 45.96 C ATOM 8615 CG TYR B 156 -5.661 17.783 -47.010 1.00 44.99 C ATOM 8616 CD1 TYR B 156 -5.774 18.410 -48.267 1.00 43.26 C ATOM 8617 CD2 TYR B 156 -6.556 18.126 -45.977 1.00 43.30 C ATOM 8618 CE1 TYR B 156 -6.787 19.359 -48.493 1.00 45.46 C ATOM 8619 CE2 TYR B 156 -7.581 19.062 -46.207 1.00 41.11 C ATOM 8620 CZ TYR B 156 -7.704 19.675 -47.469 1.00 40.20 C ATOM 8621 OH TYR B 156 -8.717 20.562 -47.699 1.00 44.84 O ATOM 8622 H TYR B 156 -6.688 15.404 -46.610 1.00 45.15 H ATOM 8623 HA TYR B 156 -4.794 15.644 -48.623 1.00 47.19 H ATOM 8624 HB3 TYR B 156 -3.629 17.166 -47.033 1.00 45.96 H ATOM 8625 HB2 TYR B 156 -4.545 16.519 -45.706 1.00 45.96 H ATOM 8626 HD1 TYR B 156 -5.095 18.153 -49.066 1.00 43.26 H ATOM 8627 HD2 TYR B 156 -6.470 17.662 -45.008 1.00 43.30 H ATOM 8628 HE1 TYR B 156 -6.874 19.812 -49.469 1.00 45.46 H ATOM 8629 HE2 TYR B 156 -8.275 19.295 -45.415 1.00 41.11 H ATOM 8630 HH TYR B 156 -9.304 20.675 -46.946 1.00 44.84 H ATOM 8631 N ARG B 157 -3.669 13.749 -46.142 1.00 52.25 N ATOM 8632 CA ARG B 157 -2.636 12.806 -45.710 1.00 53.72 C ATOM 8633 C ARG B 157 -2.573 11.502 -46.542 1.00 51.27 C ATOM 8634 O ARG B 157 -1.479 11.195 -47.015 1.00 51.73 O ATOM 8635 CB ARG B 157 -2.743 12.589 -44.185 1.00 54.92 C ATOM 8636 CG ARG B 157 -1.711 11.602 -43.594 1.00 62.30 C ATOM 8637 CD ARG B 157 -1.588 11.680 -42.059 1.00 70.67 C ATOM 8638 NE ARG B 157 -0.881 12.901 -41.615 1.00 79.37 N ATOM 8639 CZ ARG B 157 -1.008 13.562 -40.448 1.00 84.70 C ATOM 8640 NH1 ARG B 157 -1.854 13.168 -39.484 1.00 87.27 N ATOM 8641 NH2 ARG B 157 -0.263 14.656 -40.244 1.00 84.51 N1+ ATOM 8642 H ARG B 157 -4.465 13.850 -45.530 1.00 52.25 H ATOM 8643 HA ARG B 157 -1.679 13.307 -45.872 1.00 53.72 H ATOM 8644 HB3 ARG B 157 -3.741 12.234 -43.928 1.00 54.92 H ATOM 8645 HB2 ARG B 157 -2.648 13.560 -43.698 1.00 54.92 H ATOM 8646 HG3 ARG B 157 -0.745 11.870 -44.027 1.00 62.30 H ATOM 8647 HG2 ARG B 157 -1.890 10.573 -43.908 1.00 62.30 H ATOM 8648 HD3 ARG B 157 -1.163 10.770 -41.635 1.00 70.67 H ATOM 8649 HD2 ARG B 157 -2.601 11.757 -41.665 1.00 70.67 H ATOM 8650 HE ARG B 157 -0.214 13.261 -42.282 1.00 79.37 H ATOM 8651 HH12 ARG B 157 -1.944 13.689 -38.624 1.00 87.27 H ATOM 8652 HH11 ARG B 157 -2.423 12.345 -39.622 1.00 87.27 H ATOM 8653 HH22 ARG B 157 -0.342 15.175 -39.382 1.00 84.51 H ATOM 8654 HH21 ARG B 157 0.381 14.975 -40.954 1.00 84.51 H ATOM 8655 N PRO B 158 -3.702 10.782 -46.769 1.00 49.68 N ATOM 8656 CA PRO B 158 -3.701 9.633 -47.693 1.00 50.20 C ATOM 8657 C PRO B 158 -3.450 10.003 -49.169 1.00 51.86 C ATOM 8658 O PRO B 158 -2.787 9.222 -49.846 1.00 50.79 O ATOM 8659 CB PRO B 158 -5.055 8.941 -47.461 1.00 49.68 C ATOM 8660 CG PRO B 158 -5.951 10.021 -46.882 1.00 49.40 C ATOM 8661 CD PRO B 158 -4.986 10.880 -46.071 1.00 49.00 C ATOM 8662 HA PRO B 158 -2.910 8.940 -47.397 1.00 50.20 H ATOM 8663 HB3 PRO B 158 -4.928 8.143 -46.729 1.00 49.68 H ATOM 8664 HB2 PRO B 158 -5.481 8.490 -48.358 1.00 49.68 H ATOM 8665 HG3 PRO B 158 -6.782 9.629 -46.295 1.00 49.40 H ATOM 8666 HG2 PRO B 158 -6.371 10.603 -47.700 1.00 49.40 H ATOM 8667 HD2 PRO B 158 -5.367 11.891 -45.972 1.00 49.00 H ATOM 8668 HD3 PRO B 158 -4.868 10.464 -45.070 1.00 49.00 H ATOM 8669 N LEU B 159 -3.904 11.188 -49.625 1.00 52.22 N ATOM 8670 CA LEU B 159 -3.633 11.720 -50.969 1.00 52.32 C ATOM 8671 C LEU B 159 -2.134 11.929 -51.237 1.00 53.33 C ATOM 8672 O LEU B 159 -1.671 11.563 -52.317 1.00 53.23 O ATOM 8673 CB LEU B 159 -4.429 13.029 -51.194 1.00 51.27 C ATOM 8674 CG LEU B 159 -4.285 13.698 -52.582 1.00 50.29 C ATOM 8675 CD1 LEU B 159 -4.838 12.810 -53.717 1.00 50.72 C ATOM 8676 CD2 LEU B 159 -4.902 15.111 -52.581 1.00 46.17 C ATOM 8677 H LEU B 159 -4.454 11.781 -49.018 1.00 52.22 H ATOM 8678 HA LEU B 159 -3.985 10.969 -51.675 1.00 52.32 H ATOM 8679 HB3 LEU B 159 -4.125 13.744 -50.428 1.00 51.27 H ATOM 8680 HB2 LEU B 159 -5.489 12.842 -51.027 1.00 51.27 H ATOM 8681 HG LEU B 159 -3.224 13.848 -52.779 1.00 50.29 H ATOM 8682 HD11 LEU B 159 -4.079 12.643 -54.482 1.00 50.72 H ATOM 8683 HD12 LEU B 159 -5.156 11.831 -53.361 1.00 50.72 H ATOM 8684 HD13 LEU B 159 -5.708 13.244 -54.208 1.00 50.72 H ATOM 8685 HD21 LEU B 159 -4.198 15.839 -52.984 1.00 46.17 H ATOM 8686 HD22 LEU B 159 -5.808 15.171 -53.181 1.00 46.17 H ATOM 8687 HD23 LEU B 159 -5.165 15.447 -51.578 1.00 46.17 H ATOM 8688 N LEU B 160 -1.416 12.481 -50.242 1.00 54.67 N ATOM 8689 CA LEU B 160 0.033 12.686 -50.258 1.00 56.19 C ATOM 8690 C LEU B 160 0.807 11.363 -50.420 1.00 55.72 C ATOM 8691 O LEU B 160 1.758 11.317 -51.195 1.00 55.81 O ATOM 8692 CB LEU B 160 0.448 13.446 -48.977 1.00 57.20 C ATOM 8693 CG LEU B 160 1.917 13.924 -48.936 1.00 64.39 C ATOM 8694 CD1 LEU B 160 2.207 14.963 -50.037 1.00 68.85 C ATOM 8695 CD2 LEU B 160 2.294 14.443 -47.533 1.00 68.31 C ATOM 8696 H LEU B 160 -1.889 12.767 -49.396 1.00 54.67 H ATOM 8697 HA LEU B 160 0.253 13.315 -51.122 1.00 56.19 H ATOM 8698 HB3 LEU B 160 0.259 12.805 -48.116 1.00 57.20 H ATOM 8699 HB2 LEU B 160 -0.196 14.316 -48.847 1.00 57.20 H ATOM 8700 HG LEU B 160 2.563 13.066 -49.119 1.00 64.39 H ATOM 8701 HD11 LEU B 160 2.682 14.484 -50.893 1.00 68.85 H ATOM 8702 HD12 LEU B 160 1.294 15.440 -50.395 1.00 68.85 H ATOM 8703 HD13 LEU B 160 2.876 15.757 -49.705 1.00 68.85 H ATOM 8704 HD21 LEU B 160 2.504 15.512 -47.523 1.00 68.31 H ATOM 8705 HD22 LEU B 160 1.500 14.271 -46.805 1.00 68.31 H ATOM 8706 HD23 LEU B 160 3.185 13.934 -47.161 1.00 68.31 H ATOM 8707 N GLN B 161 0.348 10.309 -49.725 1.00 55.30 N ATOM 8708 CA GLN B 161 0.893 8.955 -49.813 1.00 56.27 C ATOM 8709 C GLN B 161 0.637 8.282 -51.174 1.00 56.76 C ATOM 8710 O GLN B 161 1.526 7.584 -51.657 1.00 58.25 O ATOM 8711 CB GLN B 161 0.339 8.102 -48.653 1.00 56.16 C ATOM 8712 CG GLN B 161 0.838 8.562 -47.267 1.00 59.20 C ATOM 8713 CD GLN B 161 0.141 7.859 -46.098 1.00 66.93 C ATOM 8714 OE1 GLN B 161 -0.630 6.919 -46.279 1.00 72.21 O ATOM 8715 NE2 GLN B 161 0.419 8.317 -44.877 1.00 65.97 N ATOM 8716 H GLN B 161 -0.449 10.428 -49.115 1.00 55.30 H ATOM 8717 HA GLN B 161 1.976 9.027 -49.690 1.00 56.27 H ATOM 8718 HB3 GLN B 161 0.619 7.057 -48.798 1.00 56.16 H ATOM 8719 HB2 GLN B 161 -0.750 8.126 -48.678 1.00 56.16 H ATOM 8720 HG3 GLN B 161 0.683 9.634 -47.149 1.00 59.20 H ATOM 8721 HG2 GLN B 161 1.913 8.395 -47.189 1.00 59.20 H ATOM 8722 HE22 GLN B 161 -0.005 7.884 -44.069 1.00 65.97 H ATOM 8723 HE21 GLN B 161 1.063 9.085 -44.753 1.00 65.97 H ATOM 8724 N TYR B 162 -0.546 8.513 -51.775 1.00 57.57 N ATOM 8725 CA TYR B 162 -0.945 7.933 -53.061 1.00 57.37 C ATOM 8726 C TYR B 162 -0.201 8.524 -54.271 1.00 58.20 C ATOM 8727 O TYR B 162 0.188 7.749 -55.143 1.00 56.81 O ATOM 8728 CB TYR B 162 -2.474 8.042 -53.258 1.00 57.04 C ATOM 8729 CG TYR B 162 -3.358 7.242 -52.309 1.00 57.39 C ATOM 8730 CD1 TYR B 162 -3.024 5.921 -51.937 1.00 57.46 C ATOM 8731 CD2 TYR B 162 -4.555 7.812 -51.821 1.00 56.94 C ATOM 8732 CE1 TYR B 162 -3.863 5.188 -51.076 1.00 57.85 C ATOM 8733 CE2 TYR B 162 -5.383 7.088 -50.943 1.00 56.41 C ATOM 8734 CZ TYR B 162 -5.042 5.772 -50.576 1.00 58.37 C ATOM 8735 OH TYR B 162 -5.857 5.060 -49.747 1.00 59.27 O ATOM 8736 H TYR B 162 -1.237 9.086 -51.309 1.00 57.57 H ATOM 8737 HA TYR B 162 -0.673 6.877 -53.036 1.00 57.37 H ATOM 8738 HB3 TYR B 162 -2.723 7.700 -54.261 1.00 57.04 H ATOM 8739 HB2 TYR B 162 -2.769 9.091 -53.221 1.00 57.04 H ATOM 8740 HD1 TYR B 162 -2.132 5.446 -52.315 1.00 57.46 H ATOM 8741 HD2 TYR B 162 -4.838 8.814 -52.109 1.00 56.94 H ATOM 8742 HE1 TYR B 162 -3.598 4.177 -50.805 1.00 57.85 H ATOM 8743 HE2 TYR B 162 -6.290 7.536 -50.566 1.00 56.41 H ATOM 8744 HH TYR B 162 -5.526 4.178 -49.565 1.00 59.27 H ATOM 8745 N VAL B 163 0.010 9.853 -54.309 1.00 60.05 N ATOM 8746 CA VAL B 163 0.771 10.512 -55.381 1.00 61.51 C ATOM 8747 C VAL B 163 2.286 10.223 -55.314 1.00 63.23 C ATOM 8748 O VAL B 163 2.930 10.188 -56.361 1.00 63.20 O ATOM 8749 CB VAL B 163 0.574 12.053 -55.408 1.00 60.93 C ATOM 8750 CG1 VAL B 163 -0.878 12.442 -55.731 1.00 60.34 C ATOM 8751 CG2 VAL B 163 1.092 12.791 -54.158 1.00 61.50 C ATOM 8752 H VAL B 163 -0.344 10.446 -53.569 1.00 60.05 H ATOM 8753 HA VAL B 163 0.410 10.117 -56.334 1.00 61.51 H ATOM 8754 HB VAL B 163 1.155 12.429 -56.250 1.00 60.93 H ATOM 8755 HG11 VAL B 163 -0.987 13.522 -55.819 1.00 60.34 H ATOM 8756 HG12 VAL B 163 -1.186 12.014 -56.683 1.00 60.34 H ATOM 8757 HG13 VAL B 163 -1.573 12.096 -54.966 1.00 60.34 H ATOM 8758 HG21 VAL B 163 0.890 13.856 -54.214 1.00 61.50 H ATOM 8759 HG22 VAL B 163 0.606 12.421 -53.260 1.00 61.50 H ATOM 8760 HG23 VAL B 163 2.168 12.687 -54.028 1.00 61.50 H ATOM 8761 N GLN B 164 2.810 9.979 -54.099 1.00 64.60 N ATOM 8762 CA GLN B 164 4.180 9.524 -53.856 1.00 65.62 C ATOM 8763 C GLN B 164 4.398 8.053 -54.252 1.00 65.74 C ATOM 8764 O GLN B 164 5.484 7.723 -54.726 1.00 66.85 O ATOM 8765 CB GLN B 164 4.551 9.780 -52.382 1.00 66.50 C ATOM 8766 CG GLN B 164 4.818 11.272 -52.095 1.00 68.50 C ATOM 8767 CD GLN B 164 4.981 11.609 -50.609 1.00 71.72 C ATOM 8768 OE1 GLN B 164 4.772 10.775 -49.730 1.00 72.36 O ATOM 8769 NE2 GLN B 164 5.341 12.862 -50.326 1.00 66.76 N ATOM 8770 H GLN B 164 2.219 10.053 -53.282 1.00 64.60 H ATOM 8771 HA GLN B 164 4.849 10.120 -54.480 1.00 65.62 H ATOM 8772 HB3 GLN B 164 5.443 9.211 -52.114 1.00 66.50 H ATOM 8773 HB2 GLN B 164 3.751 9.404 -51.742 1.00 66.50 H ATOM 8774 HG3 GLN B 164 4.006 11.885 -52.486 1.00 68.50 H ATOM 8775 HG2 GLN B 164 5.718 11.582 -52.625 1.00 68.50 H ATOM 8776 HE22 GLN B 164 5.460 13.154 -49.367 1.00 66.76 H ATOM 8777 HE21 GLN B 164 5.483 13.535 -51.071 1.00 66.76 H ATOM 8778 N ASP B 165 3.355 7.216 -54.093 1.00 67.16 N ATOM 8779 CA ASP B 165 3.333 5.807 -54.495 1.00 68.89 C ATOM 8780 C ASP B 165 3.289 5.655 -56.033 1.00 69.33 C ATOM 8781 O ASP B 165 3.981 4.788 -56.566 1.00 69.61 O ATOM 8782 CB ASP B 165 2.183 5.047 -53.788 1.00 68.99 C ATOM 8783 CG ASP B 165 2.244 3.519 -53.916 1.00 71.53 C ATOM 8784 OD1 ASP B 165 3.063 2.920 -53.185 1.00 78.98 O ATOM 8785 OD2 ASP B 165 1.585 2.991 -54.837 1.00 75.86 O1- ATOM 8786 H ASP B 165 2.505 7.564 -53.672 1.00 67.16 H ATOM 8787 HA ASP B 165 4.274 5.367 -54.158 1.00 68.89 H ATOM 8788 HB3 ASP B 165 1.218 5.413 -54.143 1.00 68.99 H ATOM 8789 HB2 ASP B 165 2.194 5.293 -52.726 1.00 68.99 H ATOM 8790 N MET B 166 2.535 6.539 -56.715 1.00 69.97 N ATOM 8791 CA MET B 166 2.539 6.687 -58.175 1.00 70.28 C ATOM 8792 C MET B 166 3.880 7.199 -58.737 1.00 71.13 C ATOM 8793 O MET B 166 4.208 6.864 -59.875 1.00 71.03 O ATOM 8794 CB MET B 166 1.431 7.669 -58.611 1.00 69.50 C ATOM 8795 CG MET B 166 0.000 7.128 -58.541 1.00 70.60 C ATOM 8796 SD MET B 166 -1.194 8.347 -59.152 1.00 72.24 S ATOM 8797 CE MET B 166 -2.682 7.331 -59.251 1.00 65.96 C ATOM 8798 H MET B 166 1.968 7.200 -56.201 1.00 69.97 H ATOM 8799 HA MET B 166 2.344 5.711 -58.622 1.00 70.28 H ATOM 8800 HB3 MET B 166 1.601 7.973 -59.645 1.00 69.50 H ATOM 8801 HB2 MET B 166 1.498 8.586 -58.025 1.00 69.50 H ATOM 8802 HG3 MET B 166 -0.266 6.847 -57.524 1.00 70.60 H ATOM 8803 HG2 MET B 166 -0.082 6.228 -59.150 1.00 70.60 H ATOM 8804 HE1 MET B 166 -3.507 7.902 -59.676 1.00 65.96 H ATOM 8805 HE2 MET B 166 -2.506 6.451 -59.869 1.00 65.96 H ATOM 8806 HE3 MET B 166 -2.962 7.007 -58.253 1.00 65.96 H ATOM 8807 N GLY B 167 4.601 8.027 -57.959 1.00 71.44 N ATOM 8808 CA GLY B 167 5.787 8.756 -58.414 1.00 72.27 C ATOM 8809 C GLY B 167 5.398 9.957 -59.296 1.00 72.47 C ATOM 8810 O GLY B 167 6.168 10.333 -60.179 1.00 73.38 O ATOM 8811 H GLY B 167 4.270 8.234 -57.027 1.00 71.44 H ATOM 8812 HA3 GLY B 167 6.461 8.091 -58.957 1.00 72.27 H ATOM 8813 HA2 GLY B 167 6.329 9.120 -57.541 1.00 72.27 H ATOM 8814 N GLN B 168 4.196 10.521 -59.084 1.00 72.99 N ATOM 8815 CA GLN B 168 3.576 11.566 -59.900 1.00 73.68 C ATOM 8816 C GLN B 168 3.176 12.784 -59.047 1.00 73.61 C ATOM 8817 O GLN B 168 2.166 13.423 -59.340 1.00 73.28 O ATOM 8818 CB GLN B 168 2.361 10.957 -60.643 1.00 74.07 C ATOM 8819 CG GLN B 168 2.694 9.861 -61.676 1.00 76.42 C ATOM 8820 CD GLN B 168 3.518 10.321 -62.885 1.00 80.60 C ATOM 8821 OE1 GLN B 168 4.218 9.514 -63.490 1.00 83.46 O ATOM 8822 NE2 GLN B 168 3.424 11.595 -63.275 1.00 81.38 N ATOM 8823 H GLN B 168 3.630 10.174 -58.320 1.00 72.99 H ATOM 8824 HA GLN B 168 4.288 11.949 -60.631 1.00 73.68 H ATOM 8825 HB3 GLN B 168 1.793 11.738 -61.149 1.00 74.07 H ATOM 8826 HB2 GLN B 168 1.677 10.535 -59.905 1.00 74.07 H ATOM 8827 HG3 GLN B 168 1.762 9.434 -62.044 1.00 76.42 H ATOM 8828 HG2 GLN B 168 3.223 9.040 -61.193 1.00 76.42 H ATOM 8829 HE22 GLN B 168 3.962 11.922 -64.065 1.00 81.38 H ATOM 8830 HE21 GLN B 168 2.835 12.242 -62.774 1.00 81.38 H ATOM 8831 N GLU B 169 3.971 13.087 -58.005 1.00 73.60 N ATOM 8832 CA GLU B 169 3.712 14.161 -57.046 1.00 73.42 C ATOM 8833 C GLU B 169 3.686 15.563 -57.685 1.00 73.42 C ATOM 8834 O GLU B 169 2.701 16.274 -57.503 1.00 73.82 O ATOM 8835 CB GLU B 169 4.692 14.040 -55.861 1.00 73.10 C ATOM 8836 CG GLU B 169 4.420 15.041 -54.714 0.00 72.92 C ATOM 8837 CD GLU B 169 5.288 14.855 -53.458 0.00 72.84 C ATOM 8838 OE1 GLU B 169 6.329 14.164 -53.532 0.00 72.84 O ATOM 8839 OE2 GLU B 169 4.886 15.414 -52.415 0.00 72.85 O1- ATOM 8840 H GLU B 169 4.785 12.517 -57.823 1.00 73.60 H ATOM 8841 HA GLU B 169 2.713 13.987 -56.647 1.00 73.42 H ATOM 8842 HB3 GLU B 169 5.714 14.164 -56.224 1.00 73.10 H ATOM 8843 HB2 GLU B 169 4.632 13.025 -55.465 1.00 73.10 H ATOM 8844 HG3 GLU B 169 3.372 14.957 -54.424 1.00 72.92 H ATOM 8845 HG2 GLU B 169 4.564 16.064 -55.064 1.00 72.92 H ATOM 8846 N ASP B 170 4.723 15.913 -58.465 1.00 72.69 N ATOM 8847 CA ASP B 170 4.835 17.210 -59.155 1.00 72.04 C ATOM 8848 C ASP B 170 3.731 17.446 -60.206 1.00 71.43 C ATOM 8849 O ASP B 170 3.343 18.595 -60.417 1.00 72.20 O ATOM 8850 CB ASP B 170 6.220 17.449 -59.817 1.00 72.65 C ATOM 8851 CG ASP B 170 7.477 17.298 -58.937 0.00 72.05 C ATOM 8852 OD1 ASP B 170 7.355 17.177 -57.698 0.00 72.07 O ATOM 8853 OD2 ASP B 170 8.574 17.375 -59.533 0.00 72.14 O1- ATOM 8854 H ASP B 170 5.510 15.289 -58.560 1.00 72.69 H ATOM 8855 HA ASP B 170 4.704 17.980 -58.391 1.00 72.04 H ATOM 8856 HB3 ASP B 170 6.246 18.458 -60.232 1.00 72.65 H ATOM 8857 HB2 ASP B 170 6.335 16.761 -60.656 1.00 72.65 H ATOM 8858 N MET B 171 3.253 16.360 -60.835 0.50 70.63 N ATOM 8859 CA MET B 171 2.234 16.383 -61.879 0.50 70.18 C ATOM 8860 C MET B 171 0.811 16.512 -61.305 0.50 68.41 C ATOM 8861 O MET B 171 0.107 17.460 -61.651 0.50 68.45 O ATOM 8862 CB MET B 171 2.410 15.125 -62.763 0.50 70.98 C ATOM 8863 CG MET B 171 1.475 15.030 -63.984 0.50 72.88 C ATOM 8864 SD MET B 171 1.588 16.389 -65.185 0.50 78.03 S ATOM 8865 CE MET B 171 3.291 16.179 -65.775 0.50 76.51 C ATOM 8866 H MET B 171 3.615 15.452 -60.584 0.50 70.63 H ATOM 8867 HA MET B 171 2.418 17.258 -62.506 0.50 70.18 H ATOM 8868 HB3 MET B 171 2.266 14.232 -62.152 0.50 70.98 H ATOM 8869 HB2 MET B 171 3.443 15.067 -63.105 0.50 70.98 H ATOM 8870 HG3 MET B 171 0.439 14.961 -63.654 0.50 72.88 H ATOM 8871 HG2 MET B 171 1.676 14.100 -64.516 0.50 72.88 H ATOM 8872 HE1 MET B 171 3.489 16.871 -66.594 0.50 76.51 H ATOM 8873 HE2 MET B 171 4.004 16.384 -64.977 0.50 76.51 H ATOM 8874 HE3 MET B 171 3.448 15.163 -66.135 0.50 76.51 H ATOM 8875 N LEU B 172 0.414 15.538 -60.468 1.00 66.25 N ATOM 8876 CA LEU B 172 -0.974 15.324 -60.055 1.00 63.92 C ATOM 8877 C LEU B 172 -1.369 16.066 -58.770 1.00 61.00 C ATOM 8878 O LEU B 172 -2.533 16.453 -58.674 1.00 60.48 O ATOM 8879 CB LEU B 172 -1.226 13.810 -59.860 1.00 63.63 C ATOM 8880 CG LEU B 172 -1.101 12.943 -61.134 1.00 64.63 C ATOM 8881 CD1 LEU B 172 -1.081 11.450 -60.769 1.00 67.31 C ATOM 8882 CD2 LEU B 172 -2.183 13.246 -62.190 1.00 63.56 C ATOM 8883 H LEU B 172 1.071 14.818 -60.194 1.00 66.25 H ATOM 8884 HA LEU B 172 -1.636 15.683 -60.844 1.00 63.92 H ATOM 8885 HB3 LEU B 172 -2.222 13.651 -59.440 1.00 63.63 H ATOM 8886 HB2 LEU B 172 -0.531 13.445 -59.102 1.00 63.63 H ATOM 8887 HG LEU B 172 -0.133 13.162 -61.585 1.00 64.63 H ATOM 8888 HD11 LEU B 172 -0.496 10.877 -61.489 1.00 67.31 H ATOM 8889 HD12 LEU B 172 -0.645 11.280 -59.785 1.00 67.31 H ATOM 8890 HD13 LEU B 172 -2.082 11.024 -60.745 1.00 67.31 H ATOM 8891 HD21 LEU B 172 -2.758 12.360 -62.459 1.00 63.56 H ATOM 8892 HD22 LEU B 172 -2.898 13.996 -61.853 1.00 63.56 H ATOM 8893 HD23 LEU B 172 -1.729 13.608 -63.112 1.00 63.56 H ATOM 8894 N LEU B 173 -0.445 16.225 -57.801 1.00 58.77 N ATOM 8895 CA LEU B 173 -0.762 16.735 -56.457 1.00 57.03 C ATOM 8896 C LEU B 173 -1.356 18.158 -56.376 1.00 57.39 C ATOM 8897 O LEU B 173 -2.281 18.317 -55.584 1.00 57.79 O ATOM 8898 CB LEU B 173 0.433 16.568 -55.487 1.00 56.15 C ATOM 8899 CG LEU B 173 0.148 16.820 -53.983 1.00 55.04 C ATOM 8900 CD1 LEU B 173 -0.934 15.894 -53.389 1.00 47.81 C ATOM 8901 CD2 LEU B 173 1.452 16.769 -53.167 1.00 48.95 C ATOM 8902 H LEU B 173 0.506 15.914 -57.951 1.00 58.77 H ATOM 8903 HA LEU B 173 -1.546 16.067 -56.100 1.00 57.03 H ATOM 8904 HB3 LEU B 173 1.218 17.260 -55.786 1.00 56.15 H ATOM 8905 HB2 LEU B 173 0.853 15.571 -55.610 1.00 56.15 H ATOM 8906 HG LEU B 173 -0.214 17.843 -53.881 1.00 55.04 H ATOM 8907 HD11 LEU B 173 -0.619 15.437 -52.451 1.00 47.81 H ATOM 8908 HD12 LEU B 173 -1.845 16.454 -53.180 1.00 47.81 H ATOM 8909 HD13 LEU B 173 -1.203 15.081 -54.062 1.00 47.81 H ATOM 8910 HD21 LEU B 173 1.412 17.459 -52.323 1.00 48.95 H ATOM 8911 HD22 LEU B 173 1.643 15.771 -52.773 1.00 48.95 H ATOM 8912 HD23 LEU B 173 2.320 17.046 -53.765 1.00 48.95 H ATOM 8913 N PRO B 174 -0.900 19.147 -57.187 1.00 56.80 N ATOM 8914 CA PRO B 174 -1.504 20.497 -57.181 1.00 56.56 C ATOM 8915 C PRO B 174 -2.997 20.531 -57.553 1.00 55.76 C ATOM 8916 O PRO B 174 -3.760 21.252 -56.911 1.00 56.00 O ATOM 8917 CB PRO B 174 -0.642 21.302 -58.170 1.00 57.05 C ATOM 8918 CG PRO B 174 0.691 20.573 -58.198 1.00 57.05 C ATOM 8919 CD PRO B 174 0.281 19.116 -58.054 1.00 55.82 C ATOM 8920 HA PRO B 174 -1.374 20.907 -56.177 1.00 56.56 H ATOM 8921 HB3 PRO B 174 -0.533 22.347 -57.877 1.00 57.05 H ATOM 8922 HB2 PRO B 174 -1.077 21.286 -59.170 1.00 57.05 H ATOM 8923 HG3 PRO B 174 1.287 20.870 -57.334 1.00 57.05 H ATOM 8924 HG2 PRO B 174 1.277 20.769 -59.096 1.00 57.05 H ATOM 8925 HD2 PRO B 174 -0.004 18.710 -59.025 1.00 55.82 H ATOM 8926 HD3 PRO B 174 1.104 18.520 -57.662 1.00 55.82 H ATOM 8927 N LEU B 175 -3.381 19.719 -58.554 1.00 53.54 N ATOM 8928 CA LEU B 175 -4.759 19.560 -59.007 1.00 53.09 C ATOM 8929 C LEU B 175 -5.592 18.691 -58.050 1.00 51.07 C ATOM 8930 O LEU B 175 -6.722 19.066 -57.751 1.00 51.48 O ATOM 8931 CB LEU B 175 -4.756 19.007 -60.449 1.00 53.42 C ATOM 8932 CG LEU B 175 -6.149 18.809 -61.090 1.00 52.40 C ATOM 8933 CD1 LEU B 175 -6.987 20.103 -61.150 1.00 53.56 C ATOM 8934 CD2 LEU B 175 -6.014 18.167 -62.474 1.00 52.68 C ATOM 8935 H LEU B 175 -2.691 19.147 -59.021 1.00 53.54 H ATOM 8936 HA LEU B 175 -5.212 20.553 -59.025 1.00 53.09 H ATOM 8937 HB3 LEU B 175 -4.225 18.053 -60.457 1.00 53.42 H ATOM 8938 HB2 LEU B 175 -4.170 19.675 -61.083 1.00 53.42 H ATOM 8939 HG LEU B 175 -6.697 18.087 -60.486 1.00 52.40 H ATOM 8940 HD11 LEU B 175 -7.458 20.238 -62.125 1.00 53.56 H ATOM 8941 HD12 LEU B 175 -7.786 20.079 -60.408 1.00 53.56 H ATOM 8942 HD13 LEU B 175 -6.388 20.993 -60.960 1.00 53.56 H ATOM 8943 HD21 LEU B 175 -6.951 17.700 -62.769 1.00 52.68 H ATOM 8944 HD22 LEU B 175 -5.753 18.902 -63.235 1.00 52.68 H ATOM 8945 HD23 LEU B 175 -5.248 17.391 -62.478 1.00 52.68 H ATOM 8946 N ALA B 176 -5.029 17.563 -57.585 1.00 49.77 N ATOM 8947 CA ALA B 176 -5.691 16.622 -56.679 1.00 49.78 C ATOM 8948 C ALA B 176 -6.004 17.229 -55.300 1.00 48.29 C ATOM 8949 O ALA B 176 -7.097 16.996 -54.789 1.00 48.24 O ATOM 8950 CB ALA B 176 -4.843 15.349 -56.552 1.00 48.67 C ATOM 8951 H ALA B 176 -4.096 17.310 -57.885 1.00 49.77 H ATOM 8952 HA ALA B 176 -6.641 16.340 -57.136 1.00 49.78 H ATOM 8953 HB1 ALA B 176 -5.383 14.580 -56.003 1.00 48.67 H ATOM 8954 HB2 ALA B 176 -4.607 14.933 -57.531 1.00 48.67 H ATOM 8955 HB3 ALA B 176 -3.903 15.538 -56.033 1.00 48.67 H ATOM 8956 N TRP B 177 -5.072 18.036 -54.762 1.00 48.09 N ATOM 8957 CA TRP B 177 -5.228 18.815 -53.529 1.00 48.99 C ATOM 8958 C TRP B 177 -6.326 19.883 -53.658 1.00 49.94 C ATOM 8959 O TRP B 177 -7.114 20.042 -52.728 1.00 50.64 O ATOM 8960 CB TRP B 177 -3.871 19.450 -53.164 1.00 49.24 C ATOM 8961 CG TRP B 177 -3.759 20.153 -51.841 1.00 48.17 C ATOM 8962 CD1 TRP B 177 -4.250 21.378 -51.539 1.00 46.93 C ATOM 8963 CD2 TRP B 177 -3.118 19.670 -50.622 1.00 47.69 C ATOM 8964 NE1 TRP B 177 -3.954 21.687 -50.228 1.00 46.14 N ATOM 8965 CE2 TRP B 177 -3.249 20.673 -49.613 1.00 49.96 C ATOM 8966 CE3 TRP B 177 -2.426 18.487 -50.268 1.00 48.13 C ATOM 8967 CZ2 TRP B 177 -2.714 20.514 -48.322 1.00 49.22 C ATOM 8968 CZ3 TRP B 177 -1.878 18.319 -48.980 1.00 49.73 C ATOM 8969 CH2 TRP B 177 -2.017 19.332 -48.011 1.00 50.16 C ATOM 8970 H TRP B 177 -4.195 18.166 -55.250 1.00 48.09 H ATOM 8971 HA TRP B 177 -5.512 18.123 -52.734 1.00 48.99 H ATOM 8972 HB3 TRP B 177 -3.560 20.148 -53.943 1.00 49.24 H ATOM 8973 HB2 TRP B 177 -3.114 18.666 -53.151 1.00 49.24 H ATOM 8974 HD1 TRP B 177 -4.790 22.009 -52.231 1.00 46.93 H ATOM 8975 HE1 TRP B 177 -4.216 22.566 -49.805 1.00 46.14 H ATOM 8976 HE3 TRP B 177 -2.306 17.702 -51.000 1.00 48.13 H ATOM 8977 HZ2 TRP B 177 -2.829 21.292 -47.582 1.00 49.22 H ATOM 8978 HZ3 TRP B 177 -1.349 17.409 -48.738 1.00 49.73 H ATOM 8979 HH2 TRP B 177 -1.588 19.197 -47.031 1.00 50.16 H ATOM 8980 N ARG B 178 -6.368 20.561 -54.820 1.00 49.21 N ATOM 8981 CA ARG B 178 -7.397 21.532 -55.188 1.00 48.43 C ATOM 8982 C ARG B 178 -8.804 20.908 -55.258 1.00 48.56 C ATOM 8983 O ARG B 178 -9.743 21.524 -54.758 1.00 47.98 O ATOM 8984 CB ARG B 178 -6.970 22.282 -56.475 1.00 48.57 C ATOM 8985 CG ARG B 178 -8.055 23.187 -57.093 1.00 49.77 C ATOM 8986 CD ARG B 178 -8.846 22.504 -58.226 1.00 48.06 C ATOM 8987 NE ARG B 178 -10.110 23.204 -58.504 1.00 48.04 N ATOM 8988 CZ ARG B 178 -10.390 24.178 -59.389 1.00 50.91 C ATOM 8989 NH1 ARG B 178 -9.474 24.674 -60.235 1.00 48.48 N ATOM 8990 NH2 ARG B 178 -11.636 24.666 -59.414 1.00 50.79 N1+ ATOM 8991 H ARG B 178 -5.671 20.370 -55.527 1.00 49.21 H ATOM 8992 HA ARG B 178 -7.436 22.277 -54.394 1.00 48.43 H ATOM 8993 HB3 ARG B 178 -6.637 21.575 -57.233 1.00 48.57 H ATOM 8994 HB2 ARG B 178 -6.091 22.884 -56.241 1.00 48.57 H ATOM 8995 HG3 ARG B 178 -7.511 24.015 -57.552 1.00 49.77 H ATOM 8996 HG2 ARG B 178 -8.695 23.652 -56.340 1.00 49.77 H ATOM 8997 HD3 ARG B 178 -9.006 21.442 -58.049 1.00 48.06 H ATOM 8998 HD2 ARG B 178 -8.252 22.553 -59.138 1.00 48.06 H ATOM 8999 HE ARG B 178 -10.864 22.931 -57.880 1.00 48.04 H ATOM 9000 HH12 ARG B 178 -9.716 25.406 -60.887 1.00 48.48 H ATOM 9001 HH11 ARG B 178 -8.532 24.313 -60.221 1.00 48.48 H ATOM 9002 HH22 ARG B 178 -11.894 25.396 -60.061 1.00 50.79 H ATOM 9003 HH21 ARG B 178 -12.329 24.310 -58.768 1.00 50.79 H ATOM 9004 N ILE B 179 -8.924 19.696 -55.832 1.00 47.30 N ATOM 9005 CA ILE B 179 -10.188 18.956 -55.909 1.00 46.98 C ATOM 9006 C ILE B 179 -10.665 18.489 -54.514 1.00 45.14 C ATOM 9007 O ILE B 179 -11.867 18.561 -54.266 1.00 45.01 O ATOM 9008 CB ILE B 179 -10.127 17.746 -56.897 1.00 46.82 C ATOM 9009 CG1 ILE B 179 -9.832 18.202 -58.348 1.00 47.30 C ATOM 9010 CG2 ILE B 179 -11.404 16.872 -56.919 1.00 40.61 C ATOM 9011 CD1 ILE B 179 -9.154 17.126 -59.207 1.00 48.41 C ATOM 9012 H ILE B 179 -8.111 19.248 -56.235 1.00 47.30 H ATOM 9013 HA ILE B 179 -10.941 19.649 -56.290 1.00 46.98 H ATOM 9014 HB ILE B 179 -9.298 17.112 -56.579 1.00 46.82 H ATOM 9015 HG13 ILE B 179 -9.193 19.081 -58.355 1.00 47.30 H ATOM 9016 HG12 ILE B 179 -10.752 18.524 -58.836 1.00 47.30 H ATOM 9017 HG21 ILE B 179 -11.315 16.044 -57.620 1.00 40.61 H ATOM 9018 HG22 ILE B 179 -11.633 16.431 -55.954 1.00 40.61 H ATOM 9019 HG23 ILE B 179 -12.273 17.459 -57.216 1.00 40.61 H ATOM 9020 HD11 ILE B 179 -9.130 17.423 -60.256 1.00 48.41 H ATOM 9021 HD12 ILE B 179 -8.127 16.971 -58.884 1.00 48.41 H ATOM 9022 HD13 ILE B 179 -9.664 16.166 -59.149 1.00 48.41 H ATOM 9023 N VAL B 180 -9.731 18.106 -53.615 1.00 45.03 N ATOM 9024 CA VAL B 180 -10.016 17.787 -52.208 1.00 46.08 C ATOM 9025 C VAL B 180 -10.591 18.984 -51.421 1.00 46.38 C ATOM 9026 O VAL B 180 -11.530 18.764 -50.658 1.00 46.52 O ATOM 9027 CB VAL B 180 -8.790 17.186 -51.444 1.00 46.53 C ATOM 9028 CG1 VAL B 180 -8.919 17.148 -49.904 1.00 49.61 C ATOM 9029 CG2 VAL B 180 -8.482 15.757 -51.919 1.00 43.18 C ATOM 9030 H VAL B 180 -8.760 18.071 -53.894 1.00 45.03 H ATOM 9031 HA VAL B 180 -10.792 17.021 -52.217 1.00 46.08 H ATOM 9032 HB VAL B 180 -7.916 17.795 -51.675 1.00 46.53 H ATOM 9033 HG11 VAL B 180 -8.049 16.677 -49.446 1.00 49.61 H ATOM 9034 HG12 VAL B 180 -8.997 18.142 -49.469 1.00 49.61 H ATOM 9035 HG13 VAL B 180 -9.802 16.587 -49.597 1.00 49.61 H ATOM 9036 HG21 VAL B 180 -7.590 15.363 -51.434 1.00 43.18 H ATOM 9037 HG22 VAL B 180 -9.302 15.079 -51.683 1.00 43.18 H ATOM 9038 HG23 VAL B 180 -8.317 15.716 -52.992 1.00 43.18 H ATOM 9039 N ASN B 181 -10.078 20.213 -51.648 1.00 46.94 N ATOM 9040 CA ASN B 181 -10.615 21.456 -51.061 1.00 46.91 C ATOM 9041 C ASN B 181 -12.089 21.700 -51.442 1.00 45.98 C ATOM 9042 O ASN B 181 -12.855 22.198 -50.617 1.00 47.46 O ATOM 9043 CB ASN B 181 -9.806 22.712 -51.485 1.00 47.16 C ATOM 9044 CG ASN B 181 -8.300 22.698 -51.204 1.00 48.56 C ATOM 9045 OD1 ASN B 181 -7.517 23.199 -52.007 1.00 47.11 O ATOM 9046 ND2 ASN B 181 -7.874 22.162 -50.063 1.00 47.84 N ATOM 9047 H ASN B 181 -9.301 20.318 -52.287 1.00 46.94 H ATOM 9048 HA ASN B 181 -10.581 21.366 -49.973 1.00 46.91 H ATOM 9049 HB3 ASN B 181 -10.211 23.590 -50.980 1.00 47.16 H ATOM 9050 HB2 ASN B 181 -9.941 22.898 -52.551 1.00 47.16 H ATOM 9051 HD22 ASN B 181 -6.885 22.141 -49.864 1.00 47.84 H ATOM 9052 HD21 ASN B 181 -8.519 21.751 -49.401 1.00 47.84 H ATOM 9053 N ASP B 182 -12.446 21.331 -52.682 1.00 45.59 N ATOM 9054 CA ASP B 182 -13.772 21.513 -53.270 1.00 45.23 C ATOM 9055 C ASP B 182 -14.809 20.490 -52.782 1.00 45.11 C ATOM 9056 O ASP B 182 -15.994 20.818 -52.819 1.00 43.91 O ATOM 9057 CB ASP B 182 -13.731 21.547 -54.816 1.00 44.73 C ATOM 9058 CG ASP B 182 -12.748 22.558 -55.433 1.00 48.41 C ATOM 9059 OD1 ASP B 182 -12.472 23.604 -54.802 1.00 52.82 O ATOM 9060 OD2 ASP B 182 -12.400 22.345 -56.612 1.00 45.67 O1- ATOM 9061 H ASP B 182 -11.746 20.936 -53.295 1.00 45.59 H ATOM 9062 HA ASP B 182 -14.140 22.486 -52.936 1.00 45.23 H ATOM 9063 HB3 ASP B 182 -14.722 21.786 -55.202 1.00 44.73 H ATOM 9064 HB2 ASP B 182 -13.477 20.554 -55.192 1.00 44.73 H ATOM 9065 N THR B 183 -14.388 19.304 -52.297 1.00 44.23 N ATOM 9066 CA THR B 183 -15.303 18.314 -51.706 1.00 44.83 C ATOM 9067 C THR B 183 -15.994 18.812 -50.418 1.00 45.81 C ATOM 9068 O THR B 183 -17.102 18.359 -50.141 1.00 46.76 O ATOM 9069 CB THR B 183 -14.633 16.947 -51.395 1.00 46.19 C ATOM 9070 OG1 THR B 183 -13.766 16.975 -50.275 1.00 46.29 O ATOM 9071 CG2 THR B 183 -13.917 16.327 -52.596 1.00 44.74 C ATOM 9072 H THR B 183 -13.403 19.077 -52.299 1.00 44.23 H ATOM 9073 HA THR B 183 -16.091 18.130 -52.440 1.00 44.83 H ATOM 9074 HB THR B 183 -15.431 16.254 -51.122 1.00 46.19 H ATOM 9075 HG1 THR B 183 -13.007 17.531 -50.478 1.00 46.29 H ATOM 9076 HG21 THR B 183 -13.602 15.307 -52.382 1.00 44.74 H ATOM 9077 HG22 THR B 183 -14.572 16.291 -53.466 1.00 44.74 H ATOM 9078 HG23 THR B 183 -13.030 16.891 -52.865 1.00 44.74 H ATOM 9079 N TYR B 184 -15.380 19.773 -49.704 1.00 46.23 N ATOM 9080 CA TYR B 184 -15.944 20.449 -48.530 1.00 45.67 C ATOM 9081 C TYR B 184 -17.109 21.412 -48.842 1.00 47.05 C ATOM 9082 O TYR B 184 -17.711 21.926 -47.905 1.00 46.94 O ATOM 9083 CB TYR B 184 -14.819 21.158 -47.754 1.00 45.16 C ATOM 9084 CG TYR B 184 -13.802 20.213 -47.143 1.00 45.03 C ATOM 9085 CD1 TYR B 184 -14.012 19.668 -45.858 1.00 46.80 C ATOM 9086 CD2 TYR B 184 -12.649 19.862 -47.870 1.00 45.60 C ATOM 9087 CE1 TYR B 184 -13.072 18.773 -45.311 1.00 48.77 C ATOM 9088 CE2 TYR B 184 -11.715 18.961 -47.330 1.00 46.55 C ATOM 9089 CZ TYR B 184 -11.925 18.420 -46.050 1.00 48.08 C ATOM 9090 OH TYR B 184 -11.006 17.563 -45.528 1.00 46.85 O ATOM 9091 H TYR B 184 -14.472 20.099 -50.003 1.00 46.23 H ATOM 9092 HA TYR B 184 -16.356 19.680 -47.877 1.00 45.67 H ATOM 9093 HB3 TYR B 184 -15.242 21.738 -46.937 1.00 45.16 H ATOM 9094 HB2 TYR B 184 -14.311 21.881 -48.393 1.00 45.16 H ATOM 9095 HD1 TYR B 184 -14.893 19.931 -45.291 1.00 46.80 H ATOM 9096 HD2 TYR B 184 -12.484 20.278 -48.851 1.00 45.60 H ATOM 9097 HE1 TYR B 184 -13.231 18.358 -44.326 1.00 48.77 H ATOM 9098 HE2 TYR B 184 -10.837 18.690 -47.898 1.00 46.55 H ATOM 9099 HH TYR B 184 -11.175 17.325 -44.611 1.00 46.85 H ATOM 9100 N ARG B 185 -17.450 21.617 -50.125 1.00 47.89 N ATOM 9101 CA ARG B 185 -18.698 22.254 -50.560 1.00 49.97 C ATOM 9102 C ARG B 185 -19.893 21.269 -50.541 1.00 49.78 C ATOM 9103 O ARG B 185 -21.030 21.718 -50.684 1.00 51.04 O ATOM 9104 CB ARG B 185 -18.492 22.806 -51.982 1.00 51.15 C ATOM 9105 CG ARG B 185 -17.435 23.926 -52.100 1.00 54.14 C ATOM 9106 CD ARG B 185 -16.926 24.157 -53.539 1.00 57.47 C ATOM 9107 NE ARG B 185 -17.964 24.672 -54.451 1.00 60.76 N ATOM 9108 CZ ARG B 185 -18.085 25.906 -54.975 1.00 59.44 C ATOM 9109 NH1 ARG B 185 -17.247 26.909 -54.674 1.00 63.52 N ATOM 9110 NH2 ARG B 185 -19.086 26.134 -55.833 1.00 55.27 N1+ ATOM 9111 H ARG B 185 -16.891 21.200 -50.857 1.00 47.89 H ATOM 9112 HA ARG B 185 -18.942 23.087 -49.897 1.00 49.97 H ATOM 9113 HB3 ARG B 185 -19.439 23.177 -52.367 1.00 51.15 H ATOM 9114 HB2 ARG B 185 -18.227 21.977 -52.630 1.00 51.15 H ATOM 9115 HG3 ARG B 185 -16.583 23.781 -51.436 1.00 54.14 H ATOM 9116 HG2 ARG B 185 -17.920 24.839 -51.750 1.00 54.14 H ATOM 9117 HD3 ARG B 185 -16.670 23.187 -53.966 1.00 57.47 H ATOM 9118 HD2 ARG B 185 -15.994 24.723 -53.556 1.00 57.47 H ATOM 9119 HE ARG B 185 -18.666 23.995 -54.716 1.00 60.76 H ATOM 9120 HH12 ARG B 185 -17.361 27.816 -55.105 1.00 63.52 H ATOM 9121 HH11 ARG B 185 -16.489 26.759 -54.023 1.00 63.52 H ATOM 9122 HH22 ARG B 185 -19.222 27.059 -56.226 1.00 55.27 H ATOM 9123 HH21 ARG B 185 -19.728 25.390 -56.079 1.00 55.27 H ATOM 9124 N THR B 186 -19.619 19.961 -50.379 1.00 49.13 N ATOM 9125 CA THR B 186 -20.575 18.850 -50.412 1.00 46.63 C ATOM 9126 C THR B 186 -20.491 18.009 -49.111 1.00 47.70 C ATOM 9127 O THR B 186 -19.679 18.306 -48.235 1.00 46.16 O ATOM 9128 CB THR B 186 -20.306 17.932 -51.646 1.00 46.08 C ATOM 9129 OG1 THR B 186 -19.249 17.016 -51.449 1.00 44.77 O ATOM 9130 CG2 THR B 186 -20.070 18.679 -52.969 1.00 43.81 C ATOM 9131 H THR B 186 -18.655 19.684 -50.245 1.00 49.13 H ATOM 9132 HA THR B 186 -21.594 19.236 -50.477 1.00 46.63 H ATOM 9133 HB THR B 186 -21.198 17.322 -51.795 1.00 46.08 H ATOM 9134 HG1 THR B 186 -18.442 17.510 -51.268 1.00 44.77 H ATOM 9135 HG21 THR B 186 -20.024 17.983 -53.807 1.00 43.81 H ATOM 9136 HG22 THR B 186 -20.875 19.385 -53.169 1.00 43.81 H ATOM 9137 HG23 THR B 186 -19.132 19.236 -52.958 1.00 43.81 H ATOM 9138 N ASP B 187 -21.353 16.984 -49.008 1.00 47.98 N ATOM 9139 CA ASP B 187 -21.537 16.117 -47.833 1.00 49.25 C ATOM 9140 C ASP B 187 -20.546 14.938 -47.713 1.00 48.87 C ATOM 9141 O ASP B 187 -20.703 14.158 -46.774 1.00 50.76 O ATOM 9142 CB ASP B 187 -22.986 15.560 -47.776 1.00 49.87 C ATOM 9143 CG ASP B 187 -24.109 16.605 -47.771 1.00 50.65 C ATOM 9144 OD1 ASP B 187 -23.914 17.684 -47.170 1.00 48.11 O ATOM 9145 OD2 ASP B 187 -25.213 16.252 -48.240 1.00 52.50 O1- ATOM 9146 H ASP B 187 -21.989 16.807 -49.772 1.00 47.98 H ATOM 9147 HA ASP B 187 -21.374 16.723 -46.940 1.00 49.25 H ATOM 9148 HB3 ASP B 187 -23.130 14.949 -46.883 1.00 49.87 H ATOM 9149 HB2 ASP B 187 -23.140 14.909 -48.638 1.00 49.87 H ATOM 9150 N LEU B 188 -19.570 14.792 -48.630 1.00 46.67 N ATOM 9151 CA LEU B 188 -18.669 13.627 -48.728 1.00 46.58 C ATOM 9152 C LEU B 188 -17.898 13.262 -47.439 1.00 46.28 C ATOM 9153 O LEU B 188 -17.738 12.072 -47.167 1.00 46.29 O ATOM 9154 CB LEU B 188 -17.691 13.814 -49.912 1.00 46.62 C ATOM 9155 CG LEU B 188 -18.359 13.792 -51.306 1.00 47.71 C ATOM 9156 CD1 LEU B 188 -17.373 14.256 -52.401 1.00 45.49 C ATOM 9157 CD2 LEU B 188 -18.984 12.420 -51.631 1.00 45.57 C ATOM 9158 H LEU B 188 -19.484 15.478 -49.367 1.00 46.67 H ATOM 9159 HA LEU B 188 -19.308 12.769 -48.942 1.00 46.58 H ATOM 9160 HB3 LEU B 188 -16.922 13.039 -49.888 1.00 46.62 H ATOM 9161 HB2 LEU B 188 -17.161 14.759 -49.780 1.00 46.62 H ATOM 9162 HG LEU B 188 -19.183 14.502 -51.302 1.00 47.71 H ATOM 9163 HD11 LEU B 188 -17.476 13.700 -53.333 1.00 45.49 H ATOM 9164 HD12 LEU B 188 -17.532 15.305 -52.650 1.00 45.49 H ATOM 9165 HD13 LEU B 188 -16.336 14.156 -52.080 1.00 45.49 H ATOM 9166 HD21 LEU B 188 -18.840 12.125 -52.668 1.00 45.57 H ATOM 9167 HD22 LEU B 188 -18.558 11.632 -51.013 1.00 45.57 H ATOM 9168 HD23 LEU B 188 -20.060 12.432 -51.454 1.00 45.57 H ATOM 9169 N CYS B 189 -17.474 14.270 -46.655 1.00 46.65 N ATOM 9170 CA CYS B 189 -16.776 14.120 -45.370 1.00 45.11 C ATOM 9171 C CYS B 189 -17.643 13.536 -44.232 1.00 45.75 C ATOM 9172 O CYS B 189 -17.078 13.045 -43.255 1.00 45.57 O ATOM 9173 CB CYS B 189 -16.098 15.441 -44.935 1.00 44.40 C ATOM 9174 SG CYS B 189 -17.290 16.704 -44.376 1.00 46.22 S ATOM 9175 H CYS B 189 -17.620 15.223 -46.965 1.00 46.65 H ATOM 9176 HA CYS B 189 -15.974 13.401 -45.545 1.00 45.11 H ATOM 9177 HB3 CYS B 189 -15.486 15.846 -45.741 1.00 44.40 H ATOM 9178 HB2 CYS B 189 -15.416 15.249 -44.106 1.00 44.40 H ATOM 9179 HG CYS B 189 -17.666 16.061 -43.266 1.00 46.22 H ATOM 9180 N LEU B 190 -18.978 13.603 -44.369 1.00 47.27 N ATOM 9181 CA LEU B 190 -19.940 13.052 -43.415 1.00 47.43 C ATOM 9182 C LEU B 190 -20.400 11.636 -43.805 1.00 48.57 C ATOM 9183 O LEU B 190 -21.108 11.032 -43.006 1.00 49.20 O ATOM 9184 CB LEU B 190 -21.176 13.983 -43.322 1.00 46.50 C ATOM 9185 CG LEU B 190 -20.898 15.438 -42.879 1.00 46.96 C ATOM 9186 CD1 LEU B 190 -22.183 16.289 -42.988 1.00 44.48 C ATOM 9187 CD2 LEU B 190 -20.255 15.521 -41.476 1.00 46.18 C ATOM 9188 H LEU B 190 -19.373 14.018 -45.203 1.00 47.27 H ATOM 9189 HA LEU B 190 -19.484 12.975 -42.426 1.00 47.43 H ATOM 9190 HB3 LEU B 190 -21.902 13.552 -42.631 1.00 46.50 H ATOM 9191 HB2 LEU B 190 -21.674 14.001 -44.293 1.00 46.50 H ATOM 9192 HG LEU B 190 -20.188 15.871 -43.584 1.00 46.96 H ATOM 9193 HD11 LEU B 190 -22.471 16.751 -42.044 1.00 44.48 H ATOM 9194 HD12 LEU B 190 -22.054 17.091 -43.716 1.00 44.48 H ATOM 9195 HD13 LEU B 190 -23.037 15.699 -43.319 1.00 44.48 H ATOM 9196 HD21 LEU B 190 -20.700 16.292 -40.848 1.00 46.18 H ATOM 9197 HD22 LEU B 190 -20.340 14.580 -40.931 1.00 46.18 H ATOM 9198 HD23 LEU B 190 -19.192 15.755 -41.554 1.00 46.18 H ATOM 9199 N LEU B 191 -20.048 11.145 -45.008 1.00 49.37 N ATOM 9200 CA LEU B 191 -20.625 9.928 -45.592 1.00 49.76 C ATOM 9201 C LEU B 191 -19.587 8.840 -45.913 1.00 49.79 C ATOM 9202 O LEU B 191 -19.964 7.668 -45.918 1.00 48.64 O ATOM 9203 CB LEU B 191 -21.395 10.307 -46.879 1.00 51.09 C ATOM 9204 CG LEU B 191 -22.622 11.221 -46.664 1.00 51.97 C ATOM 9205 CD1 LEU B 191 -23.255 11.612 -48.015 1.00 52.66 C ATOM 9206 CD2 LEU B 191 -23.660 10.611 -45.706 1.00 51.05 C ATOM 9207 H LEU B 191 -19.455 11.695 -45.614 1.00 49.37 H ATOM 9208 HA LEU B 191 -21.324 9.465 -44.895 1.00 49.76 H ATOM 9209 HB3 LEU B 191 -21.729 9.399 -47.386 1.00 51.09 H ATOM 9210 HB2 LEU B 191 -20.706 10.799 -47.568 1.00 51.09 H ATOM 9211 HG LEU B 191 -22.275 12.147 -46.208 1.00 51.97 H ATOM 9212 HD11 LEU B 191 -23.458 12.681 -48.050 1.00 52.66 H ATOM 9213 HD12 LEU B 191 -22.603 11.379 -48.857 1.00 52.66 H ATOM 9214 HD13 LEU B 191 -24.199 11.098 -48.192 1.00 52.66 H ATOM 9215 HD21 LEU B 191 -24.673 10.887 -45.988 1.00 51.05 H ATOM 9216 HD22 LEU B 191 -23.610 9.522 -45.687 1.00 51.05 H ATOM 9217 HD23 LEU B 191 -23.508 10.969 -44.687 1.00 51.05 H ATOM 9218 N TYR B 192 -18.329 9.220 -46.194 1.00 50.18 N ATOM 9219 CA TYR B 192 -17.271 8.308 -46.641 1.00 49.68 C ATOM 9220 C TYR B 192 -15.992 8.550 -45.821 1.00 50.58 C ATOM 9221 O TYR B 192 -15.699 9.710 -45.527 1.00 49.63 O ATOM 9222 CB TYR B 192 -16.969 8.575 -48.132 1.00 49.66 C ATOM 9223 CG TYR B 192 -18.123 8.286 -49.074 1.00 49.84 C ATOM 9224 CD1 TYR B 192 -18.330 6.984 -49.577 1.00 53.19 C ATOM 9225 CD2 TYR B 192 -18.998 9.326 -49.447 1.00 51.20 C ATOM 9226 CE1 TYR B 192 -19.404 6.728 -50.453 1.00 53.89 C ATOM 9227 CE2 TYR B 192 -20.076 9.069 -50.313 1.00 53.44 C ATOM 9228 CZ TYR B 192 -20.280 7.770 -50.817 1.00 53.62 C ATOM 9229 OH TYR B 192 -21.330 7.530 -51.652 1.00 50.95 O ATOM 9230 H TYR B 192 -18.083 10.201 -46.174 1.00 50.18 H ATOM 9231 HA TYR B 192 -17.612 7.279 -46.547 1.00 49.68 H ATOM 9232 HB3 TYR B 192 -16.125 7.960 -48.451 1.00 49.66 H ATOM 9233 HB2 TYR B 192 -16.648 9.608 -48.276 1.00 49.66 H ATOM 9234 HD1 TYR B 192 -17.663 6.181 -49.299 1.00 53.19 H ATOM 9235 HD2 TYR B 192 -18.847 10.323 -49.060 1.00 51.20 H ATOM 9236 HE1 TYR B 192 -19.554 5.730 -50.841 1.00 53.89 H ATOM 9237 HE2 TYR B 192 -20.746 9.870 -50.590 1.00 53.44 H ATOM 9238 HH TYR B 192 -21.383 6.614 -51.952 1.00 50.95 H ATOM 9239 N PRO B 193 -15.215 7.479 -45.517 1.00 53.26 N ATOM 9240 CA PRO B 193 -13.825 7.604 -45.024 1.00 52.88 C ATOM 9241 C PRO B 193 -12.920 8.501 -45.908 1.00 53.26 C ATOM 9242 O PRO B 193 -13.071 8.456 -47.131 1.00 53.94 O ATOM 9243 CB PRO B 193 -13.317 6.153 -45.045 1.00 53.21 C ATOM 9244 CG PRO B 193 -14.557 5.308 -44.832 1.00 55.13 C ATOM 9245 CD PRO B 193 -15.613 6.073 -45.615 1.00 53.83 C ATOM 9246 HA PRO B 193 -13.920 7.943 -43.997 1.00 52.88 H ATOM 9247 HB3 PRO B 193 -12.551 5.965 -44.294 1.00 53.21 H ATOM 9248 HB2 PRO B 193 -12.890 5.910 -46.019 1.00 53.21 H ATOM 9249 HG3 PRO B 193 -14.815 5.305 -43.772 1.00 55.13 H ATOM 9250 HG2 PRO B 193 -14.440 4.273 -45.155 1.00 55.13 H ATOM 9251 HD2 PRO B 193 -15.610 5.779 -46.665 1.00 53.83 H ATOM 9252 HD3 PRO B 193 -16.603 5.879 -45.200 1.00 53.83 H ATOM 9253 N PRO B 194 -11.997 9.287 -45.299 1.00 52.31 N ATOM 9254 CA PRO B 194 -11.146 10.238 -46.047 1.00 51.86 C ATOM 9255 C PRO B 194 -10.232 9.664 -47.145 1.00 51.85 C ATOM 9256 O PRO B 194 -9.928 10.392 -48.087 1.00 50.57 O ATOM 9257 CB PRO B 194 -10.314 10.938 -44.965 1.00 51.73 C ATOM 9258 CG PRO B 194 -11.098 10.763 -43.684 1.00 52.69 C ATOM 9259 CD PRO B 194 -11.773 9.414 -43.857 1.00 52.84 C ATOM 9260 HA PRO B 194 -11.818 10.968 -46.502 1.00 51.86 H ATOM 9261 HB3 PRO B 194 -10.170 11.989 -45.196 1.00 51.73 H ATOM 9262 HB2 PRO B 194 -9.331 10.476 -44.857 1.00 51.73 H ATOM 9263 HG3 PRO B 194 -11.853 11.547 -43.616 1.00 52.69 H ATOM 9264 HG2 PRO B 194 -10.478 10.818 -42.794 1.00 52.69 H ATOM 9265 HD2 PRO B 194 -11.119 8.604 -43.530 1.00 52.84 H ATOM 9266 HD3 PRO B 194 -12.674 9.403 -43.247 1.00 52.84 H ATOM 9267 N PHE B 195 -9.813 8.391 -47.021 1.00 50.88 N ATOM 9268 CA PHE B 195 -8.960 7.724 -48.010 1.00 50.16 C ATOM 9269 C PHE B 195 -9.726 7.390 -49.307 1.00 50.19 C ATOM 9270 O PHE B 195 -9.112 7.424 -50.370 1.00 51.69 O ATOM 9271 CB PHE B 195 -8.284 6.489 -47.370 1.00 48.34 C ATOM 9272 CG PHE B 195 -9.114 5.218 -47.270 1.00 49.26 C ATOM 9273 CD1 PHE B 195 -10.022 5.046 -46.205 1.00 50.81 C ATOM 9274 CD2 PHE B 195 -9.108 4.277 -48.323 1.00 52.30 C ATOM 9275 CE1 PHE B 195 -10.848 3.931 -46.174 1.00 53.86 C ATOM 9276 CE2 PHE B 195 -9.945 3.171 -48.274 1.00 53.96 C ATOM 9277 CZ PHE B 195 -10.805 2.995 -47.199 1.00 52.08 C ATOM 9278 H PHE B 195 -10.091 7.843 -46.221 1.00 50.88 H ATOM 9279 HA PHE B 195 -8.163 8.422 -48.269 1.00 50.16 H ATOM 9280 HB3 PHE B 195 -7.919 6.748 -46.375 1.00 48.34 H ATOM 9281 HB2 PHE B 195 -7.389 6.252 -47.944 1.00 48.34 H ATOM 9282 HD1 PHE B 195 -10.078 5.776 -45.411 1.00 50.81 H ATOM 9283 HD2 PHE B 195 -8.456 4.417 -49.172 1.00 52.30 H ATOM 9284 HE1 PHE B 195 -11.536 3.802 -45.354 1.00 53.86 H ATOM 9285 HE2 PHE B 195 -9.933 2.451 -49.078 1.00 53.96 H ATOM 9286 HZ PHE B 195 -11.455 2.133 -47.167 1.00 52.08 H ATOM 9287 N MET B 196 -11.043 7.119 -49.216 1.00 50.08 N ATOM 9288 CA MET B 196 -11.923 6.939 -50.377 1.00 50.72 C ATOM 9289 C MET B 196 -12.136 8.249 -51.151 1.00 49.82 C ATOM 9290 O MET B 196 -12.199 8.217 -52.380 1.00 50.29 O ATOM 9291 CB MET B 196 -13.287 6.359 -49.953 1.00 49.87 C ATOM 9292 CG MET B 196 -13.214 4.977 -49.295 1.00 56.44 C ATOM 9293 SD MET B 196 -14.847 4.220 -49.078 1.00 64.17 S ATOM 9294 CE MET B 196 -14.363 2.675 -48.267 1.00 64.37 C ATOM 9295 H MET B 196 -11.492 7.119 -48.311 1.00 50.08 H ATOM 9296 HA MET B 196 -11.443 6.229 -51.053 1.00 50.72 H ATOM 9297 HB3 MET B 196 -13.936 6.290 -50.825 1.00 49.87 H ATOM 9298 HB2 MET B 196 -13.788 7.049 -49.272 1.00 49.87 H ATOM 9299 HG3 MET B 196 -12.731 5.050 -48.321 1.00 56.44 H ATOM 9300 HG2 MET B 196 -12.606 4.307 -49.903 1.00 56.44 H ATOM 9301 HE1 MET B 196 -15.241 2.056 -48.085 1.00 64.37 H ATOM 9302 HE2 MET B 196 -13.668 2.116 -48.895 1.00 64.37 H ATOM 9303 HE3 MET B 196 -13.882 2.884 -47.312 1.00 64.37 H ATOM 9304 N ILE B 197 -12.211 9.373 -50.418 1.00 48.12 N ATOM 9305 CA ILE B 197 -12.318 10.718 -50.979 1.00 46.97 C ATOM 9306 C ILE B 197 -11.015 11.134 -51.693 1.00 46.32 C ATOM 9307 O ILE B 197 -11.095 11.697 -52.782 1.00 47.15 O ATOM 9308 CB ILE B 197 -12.706 11.776 -49.902 1.00 46.60 C ATOM 9309 CG1 ILE B 197 -14.052 11.419 -49.224 1.00 44.19 C ATOM 9310 CG2 ILE B 197 -12.763 13.222 -50.449 1.00 43.65 C ATOM 9311 CD1 ILE B 197 -14.358 12.253 -47.970 1.00 38.83 C ATOM 9312 H ILE B 197 -12.154 9.312 -49.411 1.00 48.12 H ATOM 9313 HA ILE B 197 -13.104 10.698 -51.730 1.00 46.97 H ATOM 9314 HB ILE B 197 -11.940 11.750 -49.128 1.00 46.60 H ATOM 9315 HG13 ILE B 197 -14.072 10.370 -48.932 1.00 44.19 H ATOM 9316 HG12 ILE B 197 -14.864 11.537 -49.943 1.00 44.19 H ATOM 9317 HG21 ILE B 197 -13.083 13.931 -49.686 1.00 43.65 H ATOM 9318 HG22 ILE B 197 -11.795 13.575 -50.803 1.00 43.65 H ATOM 9319 HG23 ILE B 197 -13.469 13.290 -51.276 1.00 43.65 H ATOM 9320 HD11 ILE B 197 -14.964 11.684 -47.265 1.00 38.83 H ATOM 9321 HD12 ILE B 197 -13.450 12.554 -47.448 1.00 38.83 H ATOM 9322 HD13 ILE B 197 -14.911 13.157 -48.224 1.00 38.83 H ATOM 9323 N ALA B 198 -9.853 10.791 -51.107 1.00 45.89 N ATOM 9324 CA ALA B 198 -8.521 11.005 -51.679 1.00 46.38 C ATOM 9325 C ALA B 198 -8.297 10.271 -53.013 1.00 49.21 C ATOM 9326 O ALA B 198 -7.736 10.868 -53.930 1.00 49.00 O ATOM 9327 CB ALA B 198 -7.457 10.586 -50.655 1.00 44.73 C ATOM 9328 H ALA B 198 -9.876 10.335 -50.205 1.00 45.89 H ATOM 9329 HA ALA B 198 -8.410 12.076 -51.865 1.00 46.38 H ATOM 9330 HB1 ALA B 198 -6.451 10.709 -51.054 1.00 44.73 H ATOM 9331 HB2 ALA B 198 -7.529 11.183 -49.748 1.00 44.73 H ATOM 9332 HB3 ALA B 198 -7.564 9.542 -50.366 1.00 44.73 H ATOM 9333 N LEU B 199 -8.769 9.015 -53.104 1.00 49.06 N ATOM 9334 CA LEU B 199 -8.713 8.183 -54.310 1.00 49.46 C ATOM 9335 C LEU B 199 -9.630 8.685 -55.435 1.00 48.33 C ATOM 9336 O LEU B 199 -9.229 8.614 -56.595 1.00 48.17 O ATOM 9337 CB LEU B 199 -9.055 6.721 -53.946 1.00 49.61 C ATOM 9338 CG LEU B 199 -7.954 5.995 -53.149 1.00 46.21 C ATOM 9339 CD1 LEU B 199 -8.444 4.633 -52.621 1.00 46.25 C ATOM 9340 CD2 LEU B 199 -6.649 5.850 -53.947 1.00 42.21 C ATOM 9341 H LEU B 199 -9.207 8.593 -52.296 1.00 49.06 H ATOM 9342 HA LEU B 199 -7.698 8.231 -54.703 1.00 49.46 H ATOM 9343 HB3 LEU B 199 -9.267 6.144 -54.847 1.00 49.61 H ATOM 9344 HB2 LEU B 199 -9.981 6.715 -53.370 1.00 49.61 H ATOM 9345 HG LEU B 199 -7.720 6.603 -52.280 1.00 46.21 H ATOM 9346 HD11 LEU B 199 -7.843 3.805 -52.997 1.00 46.25 H ATOM 9347 HD12 LEU B 199 -8.394 4.602 -51.533 1.00 46.25 H ATOM 9348 HD13 LEU B 199 -9.477 4.430 -52.903 1.00 46.25 H ATOM 9349 HD21 LEU B 199 -5.963 5.163 -53.452 1.00 42.21 H ATOM 9350 HD22 LEU B 199 -6.837 5.480 -54.954 1.00 42.21 H ATOM 9351 HD23 LEU B 199 -6.120 6.798 -54.031 1.00 42.21 H ATOM 9352 N ALA B 200 -10.818 9.203 -55.080 1.00 48.87 N ATOM 9353 CA ALA B 200 -11.769 9.798 -56.018 1.00 49.32 C ATOM 9354 C ALA B 200 -11.280 11.136 -56.603 1.00 50.00 C ATOM 9355 O ALA B 200 -11.467 11.367 -57.796 1.00 51.98 O ATOM 9356 CB ALA B 200 -13.117 9.968 -55.312 1.00 48.18 C ATOM 9357 H ALA B 200 -11.086 9.212 -54.105 1.00 48.87 H ATOM 9358 HA ALA B 200 -11.909 9.103 -56.848 1.00 49.32 H ATOM 9359 HB1 ALA B 200 -13.852 10.443 -55.962 1.00 48.18 H ATOM 9360 HB2 ALA B 200 -13.523 9.002 -55.009 1.00 48.18 H ATOM 9361 HB3 ALA B 200 -13.020 10.583 -54.418 1.00 48.18 H ATOM 9362 N CYS B 201 -10.633 11.967 -55.766 1.00 49.92 N ATOM 9363 CA CYS B 201 -10.029 13.247 -56.151 1.00 50.20 C ATOM 9364 C CYS B 201 -8.793 13.059 -57.047 1.00 50.84 C ATOM 9365 O CYS B 201 -8.611 13.831 -57.987 1.00 50.16 O ATOM 9366 CB CYS B 201 -9.642 14.091 -54.923 1.00 49.08 C ATOM 9367 SG CYS B 201 -11.124 14.556 -53.988 1.00 47.75 S ATOM 9368 H CYS B 201 -10.538 11.708 -54.793 1.00 49.92 H ATOM 9369 HA CYS B 201 -10.769 13.804 -56.730 1.00 50.20 H ATOM 9370 HB3 CYS B 201 -9.131 15.005 -55.226 1.00 49.08 H ATOM 9371 HB2 CYS B 201 -8.965 13.543 -54.266 1.00 49.08 H ATOM 9372 HG CYS B 201 -11.362 13.334 -53.496 1.00 47.75 H ATOM 9373 N LEU B 202 -7.989 12.022 -56.752 1.00 49.72 N ATOM 9374 CA LEU B 202 -6.827 11.602 -57.535 1.00 51.67 C ATOM 9375 C LEU B 202 -7.218 11.004 -58.898 1.00 53.15 C ATOM 9376 O LEU B 202 -6.515 11.258 -59.874 1.00 55.24 O ATOM 9377 CB LEU B 202 -5.986 10.631 -56.675 1.00 50.57 C ATOM 9378 CG LEU B 202 -4.735 10.006 -57.334 1.00 47.49 C ATOM 9379 CD1 LEU B 202 -3.767 11.067 -57.901 1.00 45.75 C ATOM 9380 CD2 LEU B 202 -4.038 9.061 -56.333 1.00 42.85 C ATOM 9381 H LEU B 202 -8.199 11.453 -55.943 1.00 49.72 H ATOM 9382 HA LEU B 202 -6.227 12.493 -57.728 1.00 51.67 H ATOM 9383 HB3 LEU B 202 -6.630 9.818 -56.337 1.00 50.57 H ATOM 9384 HB2 LEU B 202 -5.678 11.157 -55.773 1.00 50.57 H ATOM 9385 HG LEU B 202 -5.055 9.385 -58.171 1.00 47.49 H ATOM 9386 HD11 LEU B 202 -2.724 10.768 -57.811 1.00 45.75 H ATOM 9387 HD12 LEU B 202 -3.948 11.228 -58.963 1.00 45.75 H ATOM 9388 HD13 LEU B 202 -3.876 12.030 -57.400 1.00 45.75 H ATOM 9389 HD21 LEU B 202 -2.964 9.234 -56.257 1.00 42.85 H ATOM 9390 HD22 LEU B 202 -4.446 9.161 -55.327 1.00 42.85 H ATOM 9391 HD23 LEU B 202 -4.179 8.021 -56.623 1.00 42.85 H ATOM 9392 N HIS B 203 -8.338 10.261 -58.955 1.00 54.01 N ATOM 9393 CA HIS B 203 -8.891 9.705 -60.193 1.00 55.79 C ATOM 9394 C HIS B 203 -9.390 10.803 -61.149 1.00 54.01 C ATOM 9395 O HIS B 203 -9.104 10.723 -62.342 1.00 54.91 O ATOM 9396 CB HIS B 203 -9.993 8.678 -59.863 1.00 56.38 C ATOM 9397 CG HIS B 203 -10.464 7.848 -61.035 1.00 61.46 C ATOM 9398 ND1 HIS B 203 -11.304 8.335 -62.023 1.00 68.32 N ATOM 9399 CD2 HIS B 203 -10.215 6.537 -61.378 1.00 64.86 C ATOM 9400 CE1 HIS B 203 -11.509 7.344 -62.894 1.00 67.80 C ATOM 9401 NE2 HIS B 203 -10.879 6.223 -62.566 1.00 66.09 N ATOM 9402 H HIS B 203 -8.858 10.073 -58.108 1.00 54.01 H ATOM 9403 HA HIS B 203 -8.080 9.170 -60.691 1.00 55.79 H ATOM 9404 HB3 HIS B 203 -10.855 9.176 -59.418 1.00 56.38 H ATOM 9405 HB2 HIS B 203 -9.629 7.980 -59.110 1.00 56.38 H ATOM 9406 HD1 HIS B 203 -11.680 9.271 -62.085 1.00 68.32 H ATOM 9407 HD2 HIS B 203 -9.609 5.803 -60.867 1.00 64.86 H ATOM 9408 HE1 HIS B 203 -12.123 7.444 -63.776 1.00 67.80 H ATOM 9409 N VAL B 204 -10.087 11.820 -60.612 1.00 51.97 N ATOM 9410 CA VAL B 204 -10.540 12.990 -61.369 1.00 50.53 C ATOM 9411 C VAL B 204 -9.364 13.873 -61.847 1.00 50.83 C ATOM 9412 O VAL B 204 -9.429 14.378 -62.966 1.00 51.35 O ATOM 9413 CB VAL B 204 -11.579 13.827 -60.562 1.00 51.04 C ATOM 9414 CG1 VAL B 204 -11.907 15.221 -61.143 1.00 47.81 C ATOM 9415 CG2 VAL B 204 -12.892 13.036 -60.404 1.00 49.54 C ATOM 9416 H VAL B 204 -10.299 11.817 -59.623 1.00 51.97 H ATOM 9417 HA VAL B 204 -11.041 12.620 -62.266 1.00 50.53 H ATOM 9418 HB VAL B 204 -11.175 13.985 -59.560 1.00 51.04 H ATOM 9419 HG11 VAL B 204 -12.689 15.712 -60.564 1.00 47.81 H ATOM 9420 HG12 VAL B 204 -11.048 15.891 -61.131 1.00 47.81 H ATOM 9421 HG13 VAL B 204 -12.257 15.146 -62.173 1.00 47.81 H ATOM 9422 HG21 VAL B 204 -13.600 13.557 -59.761 1.00 49.54 H ATOM 9423 HG22 VAL B 204 -13.377 12.880 -61.368 1.00 49.54 H ATOM 9424 HG23 VAL B 204 -12.723 12.055 -59.965 1.00 49.54 H ATOM 9425 N ALA B 205 -8.290 13.981 -61.040 1.00 50.40 N ATOM 9426 CA ALA B 205 -7.039 14.648 -61.416 1.00 50.19 C ATOM 9427 C ALA B 205 -6.296 13.942 -62.566 1.00 52.18 C ATOM 9428 O ALA B 205 -5.766 14.630 -63.438 1.00 52.47 O ATOM 9429 CB ALA B 205 -6.124 14.788 -60.189 1.00 47.88 C ATOM 9430 H ALA B 205 -8.309 13.550 -60.125 1.00 50.40 H ATOM 9431 HA ALA B 205 -7.302 15.651 -61.752 1.00 50.19 H ATOM 9432 HB1 ALA B 205 -5.236 15.375 -60.426 1.00 47.88 H ATOM 9433 HB2 ALA B 205 -6.635 15.292 -59.371 1.00 47.88 H ATOM 9434 HB3 ALA B 205 -5.789 13.820 -59.819 1.00 47.88 H ATOM 9435 N CYS B 206 -6.309 12.594 -62.564 1.00 54.40 N ATOM 9436 CA CYS B 206 -5.755 11.744 -63.622 1.00 55.92 C ATOM 9437 C CYS B 206 -6.518 11.900 -64.947 1.00 55.92 C ATOM 9438 O CYS B 206 -5.872 12.010 -65.985 1.00 55.85 O ATOM 9439 CB CYS B 206 -5.716 10.250 -63.233 1.00 55.02 C ATOM 9440 SG CYS B 206 -4.472 9.932 -61.957 1.00 55.06 S ATOM 9441 H CYS B 206 -6.750 12.110 -61.794 1.00 54.40 H ATOM 9442 HA CYS B 206 -4.731 12.076 -63.803 1.00 55.92 H ATOM 9443 HB3 CYS B 206 -5.460 9.632 -64.094 1.00 55.02 H ATOM 9444 HB2 CYS B 206 -6.686 9.905 -62.877 1.00 55.02 H ATOM 9445 HG CYS B 206 -5.123 10.564 -60.973 1.00 55.06 H ATOM 9446 N VAL B 207 -7.861 11.927 -64.891 1.00 55.93 N ATOM 9447 CA VAL B 207 -8.742 12.082 -66.053 1.00 57.94 C ATOM 9448 C VAL B 207 -8.603 13.460 -66.737 1.00 60.08 C ATOM 9449 O VAL B 207 -8.538 13.509 -67.966 1.00 60.13 O ATOM 9450 CB VAL B 207 -10.228 11.808 -65.665 1.00 57.77 C ATOM 9451 CG1 VAL B 207 -11.296 12.315 -66.660 1.00 60.07 C ATOM 9452 CG2 VAL B 207 -10.452 10.305 -65.414 1.00 57.04 C ATOM 9453 H VAL B 207 -8.321 11.820 -63.997 1.00 55.93 H ATOM 9454 HA VAL B 207 -8.439 11.332 -66.787 1.00 57.94 H ATOM 9455 HB VAL B 207 -10.420 12.316 -64.718 1.00 57.77 H ATOM 9456 HG11 VAL B 207 -12.293 11.988 -66.363 1.00 60.07 H ATOM 9457 HG12 VAL B 207 -11.330 13.403 -66.709 1.00 60.07 H ATOM 9458 HG13 VAL B 207 -11.111 11.935 -67.666 1.00 60.07 H ATOM 9459 HG21 VAL B 207 -11.451 10.114 -65.023 1.00 57.04 H ATOM 9460 HG22 VAL B 207 -10.341 9.732 -66.335 1.00 57.04 H ATOM 9461 HG23 VAL B 207 -9.741 9.900 -64.695 1.00 57.04 H ATOM 9462 N VAL B 208 -8.527 14.536 -65.934 1.00 61.48 N ATOM 9463 CA VAL B 208 -8.360 15.917 -66.398 1.00 61.01 C ATOM 9464 C VAL B 208 -6.995 16.170 -67.075 1.00 61.09 C ATOM 9465 O VAL B 208 -6.961 16.849 -68.102 1.00 58.93 O ATOM 9466 CB VAL B 208 -8.585 16.921 -65.226 1.00 60.75 C ATOM 9467 CG1 VAL B 208 -8.051 18.355 -65.440 1.00 58.66 C ATOM 9468 CG2 VAL B 208 -10.079 16.995 -64.857 1.00 58.58 C ATOM 9469 H VAL B 208 -8.595 14.411 -64.933 1.00 61.48 H ATOM 9470 HA VAL B 208 -9.129 16.099 -67.152 1.00 61.01 H ATOM 9471 HB VAL B 208 -8.069 16.517 -64.355 1.00 60.75 H ATOM 9472 HG11 VAL B 208 -8.337 19.006 -64.613 1.00 58.66 H ATOM 9473 HG12 VAL B 208 -6.962 18.386 -65.494 1.00 58.66 H ATOM 9474 HG13 VAL B 208 -8.448 18.793 -66.356 1.00 58.66 H ATOM 9475 HG21 VAL B 208 -10.234 17.588 -63.956 1.00 58.58 H ATOM 9476 HG22 VAL B 208 -10.659 17.452 -65.659 1.00 58.58 H ATOM 9477 HG23 VAL B 208 -10.503 16.009 -64.674 1.00 58.58 H ATOM 9478 N GLN B 209 -5.914 15.599 -66.515 1.00 62.64 N ATOM 9479 CA GLN B 209 -4.554 15.687 -67.062 1.00 64.60 C ATOM 9480 C GLN B 209 -4.219 14.602 -68.105 1.00 65.67 C ATOM 9481 O GLN B 209 -3.108 14.617 -68.633 1.00 65.34 O ATOM 9482 CB GLN B 209 -3.535 15.717 -65.904 1.00 65.15 C ATOM 9483 CG GLN B 209 -3.578 17.049 -65.128 1.00 69.41 C ATOM 9484 CD GLN B 209 -2.533 17.142 -64.014 1.00 71.87 C ATOM 9485 OE1 GLN B 209 -2.011 16.135 -63.547 1.00 75.89 O ATOM 9486 NE2 GLN B 209 -2.230 18.361 -63.565 1.00 74.36 N ATOM 9487 H GLN B 209 -6.018 15.058 -65.667 1.00 62.64 H ATOM 9488 HA GLN B 209 -4.457 16.633 -67.599 1.00 64.60 H ATOM 9489 HB3 GLN B 209 -2.523 15.578 -66.290 1.00 65.15 H ATOM 9490 HB2 GLN B 209 -3.717 14.878 -65.231 1.00 65.15 H ATOM 9491 HG3 GLN B 209 -4.566 17.189 -64.693 1.00 69.41 H ATOM 9492 HG2 GLN B 209 -3.422 17.879 -65.819 1.00 69.41 H ATOM 9493 HE22 GLN B 209 -1.535 18.459 -62.837 1.00 74.36 H ATOM 9494 HE21 GLN B 209 -2.668 19.182 -63.955 1.00 74.36 H ATOM 9495 N GLN B 210 -5.177 13.701 -68.399 1.00 67.79 N ATOM 9496 CA GLN B 210 -5.101 12.618 -69.390 1.00 70.87 C ATOM 9497 C GLN B 210 -4.021 11.555 -69.081 1.00 72.24 C ATOM 9498 O GLN B 210 -3.493 10.925 -69.999 1.00 72.91 O ATOM 9499 CB GLN B 210 -5.002 13.190 -70.827 1.00 71.56 C ATOM 9500 CG GLN B 210 -6.198 14.088 -71.208 1.00 73.53 C ATOM 9501 CD GLN B 210 -6.102 14.669 -72.622 1.00 76.89 C ATOM 9502 OE1 GLN B 210 -5.209 14.333 -73.398 1.00 80.30 O ATOM 9503 NE2 GLN B 210 -7.040 15.553 -72.967 1.00 78.37 N ATOM 9504 H GLN B 210 -6.059 13.769 -67.911 1.00 67.79 H ATOM 9505 HA GLN B 210 -6.051 12.088 -69.314 1.00 70.87 H ATOM 9506 HB3 GLN B 210 -4.946 12.368 -71.543 1.00 71.56 H ATOM 9507 HB2 GLN B 210 -4.072 13.749 -70.942 1.00 71.56 H ATOM 9508 HG3 GLN B 210 -6.280 14.921 -70.509 1.00 73.53 H ATOM 9509 HG2 GLN B 210 -7.125 13.520 -71.128 1.00 73.53 H ATOM 9510 HE22 GLN B 210 -7.028 15.966 -73.888 1.00 78.37 H ATOM 9511 HE21 GLN B 210 -7.762 15.815 -72.312 1.00 78.37 H ATOM 9512 N LYS B 211 -3.722 11.371 -67.785 1.00 73.56 N ATOM 9513 CA LYS B 211 -2.780 10.390 -67.261 1.00 73.62 C ATOM 9514 C LYS B 211 -3.461 9.019 -67.119 1.00 73.68 C ATOM 9515 O LYS B 211 -4.502 8.925 -66.468 1.00 73.08 O ATOM 9516 CB LYS B 211 -2.235 10.913 -65.910 1.00 73.74 C ATOM 9517 CG LYS B 211 -1.264 9.976 -65.164 1.00 74.44 C ATOM 9518 CD LYS B 211 0.007 9.641 -65.962 0.00 73.83 C ATOM 9519 CE LYS B 211 0.952 8.712 -65.188 0.00 73.84 C ATOM 9520 NZ LYS B 211 2.189 8.434 -65.939 0.00 73.83 N1+ ATOM 9521 H LYS B 211 -4.237 11.899 -67.092 1.00 73.56 H ATOM 9522 HA LYS B 211 -1.949 10.311 -67.963 1.00 73.62 H ATOM 9523 HB3 LYS B 211 -3.073 11.125 -65.244 1.00 73.74 H ATOM 9524 HB2 LYS B 211 -1.741 11.872 -66.074 1.00 73.74 H ATOM 9525 HG3 LYS B 211 -1.775 9.055 -64.878 1.00 74.44 H ATOM 9526 HG2 LYS B 211 -0.979 10.452 -64.225 1.00 74.44 H ATOM 9527 HD3 LYS B 211 0.521 10.569 -66.219 1.00 73.83 H ATOM 9528 HD2 LYS B 211 -0.262 9.165 -66.905 1.00 73.83 H ATOM 9529 HE3 LYS B 211 0.458 7.767 -64.962 1.00 73.84 H ATOM 9530 HE2 LYS B 211 1.217 9.167 -64.237 1.00 73.84 H ATOM 9531 HZ1 LYS B 211 2.672 9.301 -66.129 1.00 73.83 H ATOM 9532 HZ2 LYS B 211 2.789 7.835 -65.389 1.00 73.83 H ATOM 9533 HZ3 LYS B 211 1.962 7.975 -66.810 1.00 73.83 H ATOM 9534 N ASP B 212 -2.829 7.982 -67.693 1.00 74.12 N ATOM 9535 CA ASP B 212 -3.220 6.584 -67.521 1.00 74.97 C ATOM 9536 C ASP B 212 -2.734 6.097 -66.142 1.00 74.51 C ATOM 9537 O ASP B 212 -1.535 6.147 -65.865 1.00 75.13 O ATOM 9538 CB ASP B 212 -2.699 5.706 -68.692 1.00 75.54 C ATOM 9539 CG ASP B 212 -3.135 4.225 -68.733 1.00 76.85 C ATOM 9540 OD1 ASP B 212 -3.998 3.809 -67.927 1.00 76.31 O ATOM 9541 OD2 ASP B 212 -2.645 3.526 -69.646 1.00 78.66 O1- ATOM 9542 H ASP B 212 -1.984 8.143 -68.222 1.00 74.12 H ATOM 9543 HA ASP B 212 -4.312 6.542 -67.545 1.00 74.97 H ATOM 9544 HB3 ASP B 212 -1.609 5.751 -68.720 1.00 75.54 H ATOM 9545 HB2 ASP B 212 -3.019 6.165 -69.628 1.00 75.54 H ATOM 9546 N ALA B 213 -3.690 5.641 -65.320 1.00 74.10 N ATOM 9547 CA ALA B 213 -3.466 5.121 -63.973 1.00 74.72 C ATOM 9548 C ALA B 213 -4.354 3.901 -63.664 1.00 74.92 C ATOM 9549 O ALA B 213 -4.446 3.524 -62.497 1.00 74.63 O ATOM 9550 CB ALA B 213 -3.666 6.261 -62.957 1.00 74.67 C ATOM 9551 H ALA B 213 -4.650 5.652 -65.634 1.00 74.10 H ATOM 9552 HA ALA B 213 -2.437 4.765 -63.888 1.00 74.72 H ATOM 9553 HB1 ALA B 213 -3.488 5.922 -61.936 1.00 74.67 H ATOM 9554 HB2 ALA B 213 -2.976 7.084 -63.147 1.00 74.67 H ATOM 9555 HB3 ALA B 213 -4.679 6.663 -63.000 1.00 74.67 H ATOM 9556 N ARG B 214 -4.980 3.293 -64.692 1.00 75.12 N ATOM 9557 CA ARG B 214 -5.905 2.155 -64.571 1.00 75.31 C ATOM 9558 C ARG B 214 -5.292 0.920 -63.887 1.00 73.67 C ATOM 9559 O ARG B 214 -5.984 0.278 -63.097 1.00 73.46 O ATOM 9560 CB ARG B 214 -6.448 1.760 -65.960 1.00 76.48 C ATOM 9561 CG ARG B 214 -7.256 2.862 -66.676 1.00 81.10 C ATOM 9562 CD ARG B 214 -7.708 2.465 -68.096 1.00 86.03 C ATOM 9563 NE ARG B 214 -6.576 2.405 -69.038 1.00 88.73 N ATOM 9564 CZ ARG B 214 -6.541 1.889 -70.279 1.00 90.27 C ATOM 9565 NH1 ARG B 214 -7.619 1.336 -70.855 1.00 90.55 N ATOM 9566 NH2 ARG B 214 -5.386 1.933 -70.955 1.00 90.16 N1+ ATOM 9567 H ARG B 214 -4.815 3.627 -65.632 1.00 75.12 H ATOM 9568 HA ARG B 214 -6.744 2.485 -63.955 1.00 75.31 H ATOM 9569 HB3 ARG B 214 -7.096 0.888 -65.854 1.00 76.48 H ATOM 9570 HB2 ARG B 214 -5.616 1.438 -66.588 1.00 76.48 H ATOM 9571 HG3 ARG B 214 -6.611 3.738 -66.760 1.00 81.10 H ATOM 9572 HG2 ARG B 214 -8.109 3.193 -66.083 1.00 81.10 H ATOM 9573 HD3 ARG B 214 -8.521 3.097 -68.455 1.00 86.03 H ATOM 9574 HD2 ARG B 214 -8.102 1.449 -68.051 1.00 86.03 H ATOM 9575 HE ARG B 214 -5.716 2.819 -68.688 1.00 88.73 H ATOM 9576 HH12 ARG B 214 -7.566 0.954 -71.788 1.00 90.55 H ATOM 9577 HH11 ARG B 214 -8.493 1.300 -70.352 1.00 90.55 H ATOM 9578 HH22 ARG B 214 -5.317 1.555 -71.888 1.00 90.16 H ATOM 9579 HH21 ARG B 214 -4.565 2.353 -70.532 1.00 90.16 H ATOM 9580 N GLN B 215 -4.009 0.636 -64.176 1.00 72.87 N ATOM 9581 CA GLN B 215 -3.239 -0.442 -63.555 1.00 73.08 C ATOM 9582 C GLN B 215 -2.976 -0.193 -62.058 1.00 71.43 C ATOM 9583 O GLN B 215 -3.083 -1.135 -61.277 1.00 71.48 O ATOM 9584 CB GLN B 215 -1.931 -0.660 -64.353 1.00 73.43 C ATOM 9585 CG GLN B 215 -0.987 -1.771 -63.834 1.00 76.29 C ATOM 9586 CD GLN B 215 -1.636 -3.159 -63.773 1.00 78.56 C ATOM 9587 OE1 GLN B 215 -2.402 -3.535 -64.658 1.00 81.97 O ATOM 9588 NE2 GLN B 215 -1.310 -3.939 -62.742 1.00 78.61 N ATOM 9589 H GLN B 215 -3.513 1.215 -64.838 1.00 72.87 H ATOM 9590 HA GLN B 215 -3.843 -1.347 -63.633 1.00 73.08 H ATOM 9591 HB3 GLN B 215 -1.372 0.276 -64.389 1.00 73.43 H ATOM 9592 HB2 GLN B 215 -2.188 -0.882 -65.390 1.00 73.43 H ATOM 9593 HG3 GLN B 215 -0.600 -1.504 -62.850 1.00 76.29 H ATOM 9594 HG2 GLN B 215 -0.117 -1.839 -64.488 1.00 76.29 H ATOM 9595 HE22 GLN B 215 -1.705 -4.864 -62.659 1.00 78.61 H ATOM 9596 HE21 GLN B 215 -0.672 -3.605 -62.026 1.00 78.61 H ATOM 9597 N TRP B 216 -2.675 1.064 -61.685 1.00 69.58 N ATOM 9598 CA TRP B 216 -2.444 1.475 -60.299 1.00 68.69 C ATOM 9599 C TRP B 216 -3.712 1.363 -59.431 1.00 68.50 C ATOM 9600 O TRP B 216 -3.619 0.854 -58.316 1.00 68.31 O ATOM 9601 CB TRP B 216 -1.833 2.892 -60.265 1.00 68.12 C ATOM 9602 CG TRP B 216 -1.447 3.399 -58.907 1.00 63.36 C ATOM 9603 CD1 TRP B 216 -0.227 3.259 -58.341 1.00 60.38 C ATOM 9604 CD2 TRP B 216 -2.287 4.031 -57.891 1.00 60.16 C ATOM 9605 NE1 TRP B 216 -0.251 3.770 -57.062 1.00 58.06 N ATOM 9606 CE2 TRP B 216 -1.495 4.258 -56.726 1.00 61.74 C ATOM 9607 CE3 TRP B 216 -3.645 4.422 -57.827 1.00 60.13 C ATOM 9608 CZ2 TRP B 216 -2.018 4.842 -55.560 1.00 58.12 C ATOM 9609 CZ3 TRP B 216 -4.181 5.014 -56.667 1.00 61.68 C ATOM 9610 CH2 TRP B 216 -3.373 5.217 -55.534 1.00 56.94 C ATOM 9611 H TRP B 216 -2.631 1.794 -62.381 1.00 69.58 H ATOM 9612 HA TRP B 216 -1.703 0.790 -59.881 1.00 68.69 H ATOM 9613 HB3 TRP B 216 -2.525 3.612 -60.702 1.00 68.12 H ATOM 9614 HB2 TRP B 216 -0.941 2.916 -60.893 1.00 68.12 H ATOM 9615 HD1 TRP B 216 0.621 2.790 -58.820 1.00 60.38 H ATOM 9616 HE1 TRP B 216 0.545 3.707 -56.433 1.00 58.06 H ATOM 9617 HE3 TRP B 216 -4.282 4.271 -58.685 1.00 60.13 H ATOM 9618 HZ2 TRP B 216 -1.389 4.993 -54.695 1.00 58.12 H ATOM 9619 HZ3 TRP B 216 -5.218 5.309 -56.648 1.00 61.68 H ATOM 9620 HH2 TRP B 216 -3.799 5.658 -54.647 1.00 56.94 H ATOM 9621 N PHE B 217 -4.868 1.802 -59.964 1.00 69.27 N ATOM 9622 CA PHE B 217 -6.178 1.654 -59.319 1.00 70.48 C ATOM 9623 C PHE B 217 -6.659 0.194 -59.192 1.00 73.59 C ATOM 9624 O PHE B 217 -7.390 -0.106 -58.248 1.00 75.09 O ATOM 9625 CB PHE B 217 -7.237 2.554 -59.999 1.00 69.25 C ATOM 9626 CG PHE B 217 -7.245 4.005 -59.537 1.00 66.54 C ATOM 9627 CD1 PHE B 217 -7.837 4.346 -58.301 1.00 62.13 C ATOM 9628 CD2 PHE B 217 -6.558 5.005 -60.259 1.00 59.77 C ATOM 9629 CE1 PHE B 217 -7.784 5.656 -57.842 1.00 57.94 C ATOM 9630 CE2 PHE B 217 -6.506 6.307 -59.778 1.00 60.22 C ATOM 9631 CZ PHE B 217 -7.119 6.631 -58.575 1.00 58.42 C ATOM 9632 H PHE B 217 -4.864 2.224 -60.884 1.00 69.27 H ATOM 9633 HA PHE B 217 -6.068 2.004 -58.293 1.00 70.48 H ATOM 9634 HB3 PHE B 217 -8.237 2.161 -59.805 1.00 69.25 H ATOM 9635 HB2 PHE B 217 -7.117 2.523 -61.083 1.00 69.25 H ATOM 9636 HD1 PHE B 217 -8.339 3.592 -57.712 1.00 62.13 H ATOM 9637 HD2 PHE B 217 -6.080 4.770 -61.194 1.00 59.77 H ATOM 9638 HE1 PHE B 217 -8.252 5.918 -56.906 1.00 57.94 H ATOM 9639 HE2 PHE B 217 -5.987 7.069 -60.341 1.00 60.22 H ATOM 9640 HZ PHE B 217 -7.076 7.645 -58.205 1.00 58.42 H ATOM 9641 N ALA B 218 -6.221 -0.686 -60.112 1.00 76.09 N ATOM 9642 CA ALA B 218 -6.495 -2.125 -60.085 1.00 77.26 C ATOM 9643 C ALA B 218 -5.655 -2.894 -59.046 1.00 78.05 C ATOM 9644 O ALA B 218 -6.127 -3.914 -58.547 1.00 79.96 O ATOM 9645 CB ALA B 218 -6.283 -2.707 -61.491 1.00 77.37 C ATOM 9646 H ALA B 218 -5.634 -0.362 -60.868 1.00 76.09 H ATOM 9647 HA ALA B 218 -7.546 -2.265 -59.823 1.00 77.26 H ATOM 9648 HB1 ALA B 218 -6.510 -3.774 -61.515 1.00 77.37 H ATOM 9649 HB2 ALA B 218 -6.934 -2.221 -62.218 1.00 77.37 H ATOM 9650 HB3 ALA B 218 -5.255 -2.581 -61.830 1.00 77.37 H ATOM 9651 N GLU B 219 -4.450 -2.388 -58.724 1.00 78.74 N ATOM 9652 CA GLU B 219 -3.563 -2.926 -57.685 1.00 79.35 C ATOM 9653 C GLU B 219 -4.049 -2.663 -56.245 1.00 79.57 C ATOM 9654 O GLU B 219 -3.584 -3.351 -55.336 1.00 78.70 O ATOM 9655 CB GLU B 219 -2.134 -2.382 -57.899 1.00 80.08 C ATOM 9656 CG GLU B 219 -1.410 -3.030 -59.103 1.00 82.75 C ATOM 9657 CD GLU B 219 -0.077 -2.379 -59.515 1.00 86.14 C ATOM 9658 OE1 GLU B 219 0.335 -1.372 -58.895 1.00 89.33 O ATOM 9659 OE2 GLU B 219 0.521 -2.911 -60.476 1.00 86.39 O1- ATOM 9660 H GLU B 219 -4.120 -1.558 -59.196 1.00 78.74 H ATOM 9661 HA GLU B 219 -3.528 -4.012 -57.800 1.00 79.35 H ATOM 9662 HB3 GLU B 219 -1.531 -2.527 -57.001 1.00 80.08 H ATOM 9663 HB2 GLU B 219 -2.191 -1.303 -58.044 1.00 80.08 H ATOM 9664 HG3 GLU B 219 -2.066 -3.037 -59.971 1.00 82.75 H ATOM 9665 HG2 GLU B 219 -1.218 -4.078 -58.871 1.00 82.75 H ATOM 9666 N LEU B 220 -4.971 -1.702 -56.058 1.00 79.93 N ATOM 9667 CA LEU B 220 -5.584 -1.387 -54.766 1.00 79.72 C ATOM 9668 C LEU B 220 -6.648 -2.425 -54.374 1.00 79.13 C ATOM 9669 O LEU B 220 -7.371 -2.924 -55.238 1.00 78.91 O ATOM 9670 CB LEU B 220 -6.242 0.008 -54.819 1.00 79.76 C ATOM 9671 CG LEU B 220 -5.300 1.181 -55.155 1.00 81.49 C ATOM 9672 CD1 LEU B 220 -6.102 2.493 -55.242 1.00 81.17 C ATOM 9673 CD2 LEU B 220 -4.100 1.292 -54.189 1.00 81.07 C ATOM 9674 H LEU B 220 -5.317 -1.186 -56.854 1.00 79.93 H ATOM 9675 HA LEU B 220 -4.803 -1.390 -54.003 1.00 79.72 H ATOM 9676 HB3 LEU B 220 -6.716 0.214 -53.858 1.00 79.76 H ATOM 9677 HB2 LEU B 220 -7.051 -0.010 -55.551 1.00 79.76 H ATOM 9678 HG LEU B 220 -4.896 1.003 -56.149 1.00 81.49 H ATOM 9679 HD11 LEU B 220 -5.779 3.215 -54.498 1.00 81.17 H ATOM 9680 HD12 LEU B 220 -5.986 2.957 -56.219 1.00 81.17 H ATOM 9681 HD13 LEU B 220 -7.171 2.338 -55.089 1.00 81.17 H ATOM 9682 HD21 LEU B 220 -3.846 2.325 -53.949 1.00 81.07 H ATOM 9683 HD22 LEU B 220 -4.286 0.780 -53.245 1.00 81.07 H ATOM 9684 HD23 LEU B 220 -3.210 0.847 -54.635 1.00 81.07 H ATOM 9685 N SER B 221 -6.754 -2.670 -53.060 1.00 79.13 N ATOM 9686 CA SER B 221 -7.764 -3.523 -52.435 1.00 79.74 C ATOM 9687 C SER B 221 -8.857 -2.651 -51.784 1.00 79.23 C ATOM 9688 O SER B 221 -9.011 -2.657 -50.562 1.00 80.81 O ATOM 9689 CB SER B 221 -7.048 -4.499 -51.471 1.00 79.58 C ATOM 9690 OG SER B 221 -6.414 -3.840 -50.390 0.00 79.36 O ATOM 9691 H SER B 221 -6.116 -2.221 -52.419 1.00 79.13 H ATOM 9692 HA SER B 221 -8.258 -4.132 -53.194 1.00 79.74 H ATOM 9693 HB3 SER B 221 -6.301 -5.083 -52.011 1.00 79.58 H ATOM 9694 HB2 SER B 221 -7.764 -5.214 -51.065 1.00 79.58 H ATOM 9695 HG SER B 221 -7.097 -3.431 -49.851 1.00 79.36 H ATOM 9696 N VAL B 222 -9.587 -1.903 -52.629 1.00 77.90 N ATOM 9697 CA VAL B 222 -10.667 -0.998 -52.226 1.00 75.92 C ATOM 9698 C VAL B 222 -11.939 -1.283 -53.044 1.00 74.65 C ATOM 9699 O VAL B 222 -11.852 -1.776 -54.171 1.00 73.70 O ATOM 9700 CB VAL B 222 -10.270 0.496 -52.431 1.00 76.31 C ATOM 9701 CG1 VAL B 222 -9.073 0.885 -51.548 1.00 76.94 C ATOM 9702 CG2 VAL B 222 -10.036 0.923 -53.896 1.00 74.98 C ATOM 9703 H VAL B 222 -9.413 -1.962 -53.622 1.00 77.90 H ATOM 9704 HA VAL B 222 -10.917 -1.152 -51.175 1.00 75.92 H ATOM 9705 HB VAL B 222 -11.103 1.100 -52.069 1.00 76.31 H ATOM 9706 HG11 VAL B 222 -8.889 1.958 -51.582 1.00 76.94 H ATOM 9707 HG12 VAL B 222 -9.250 0.616 -50.507 1.00 76.94 H ATOM 9708 HG13 VAL B 222 -8.159 0.384 -51.867 1.00 76.94 H ATOM 9709 HG21 VAL B 222 -9.687 1.955 -53.952 1.00 74.98 H ATOM 9710 HG22 VAL B 222 -9.288 0.298 -54.383 1.00 74.98 H ATOM 9711 HG23 VAL B 222 -10.951 0.870 -54.486 1.00 74.98 H ATOM 9712 N ASP B 223 -13.098 -0.943 -52.454 1.00 74.29 N ATOM 9713 CA ASP B 223 -14.416 -1.039 -53.081 1.00 73.95 C ATOM 9714 C ASP B 223 -14.589 0.127 -54.072 1.00 73.50 C ATOM 9715 O ASP B 223 -14.968 1.225 -53.663 1.00 72.58 O ATOM 9716 CB ASP B 223 -15.538 -1.095 -52.009 1.00 73.87 C ATOM 9717 CG ASP B 223 -16.985 -1.288 -52.507 1.00 77.18 C ATOM 9718 OD1 ASP B 223 -17.181 -1.672 -53.682 1.00 80.34 O ATOM 9719 OD2 ASP B 223 -17.886 -1.131 -51.655 1.00 79.81 O1- ATOM 9720 H ASP B 223 -13.084 -0.542 -51.528 1.00 74.29 H ATOM 9721 HA ASP B 223 -14.450 -1.977 -53.641 1.00 73.95 H ATOM 9722 HB3 ASP B 223 -15.492 -0.199 -51.387 1.00 73.87 H ATOM 9723 HB2 ASP B 223 -15.318 -1.917 -51.327 1.00 73.87 H ATOM 9724 N MET B 224 -14.294 -0.147 -55.354 1.00 72.43 N ATOM 9725 CA MET B 224 -14.353 0.815 -56.456 1.00 71.74 C ATOM 9726 C MET B 224 -15.762 1.331 -56.793 1.00 70.69 C ATOM 9727 O MET B 224 -15.847 2.379 -57.430 1.00 69.93 O ATOM 9728 CB MET B 224 -13.663 0.230 -57.707 1.00 72.62 C ATOM 9729 CG MET B 224 -12.127 0.151 -57.606 1.00 75.06 C ATOM 9730 SD MET B 224 -11.242 1.732 -57.418 1.00 78.60 S ATOM 9731 CE MET B 224 -11.705 2.587 -58.948 1.00 81.95 C ATOM 9732 H MET B 224 -13.977 -1.076 -55.595 1.00 72.43 H ATOM 9733 HA MET B 224 -13.791 1.693 -56.139 1.00 71.74 H ATOM 9734 HB3 MET B 224 -13.919 0.817 -58.589 1.00 72.62 H ATOM 9735 HB2 MET B 224 -14.058 -0.767 -57.906 1.00 72.62 H ATOM 9736 HG3 MET B 224 -11.736 -0.340 -58.498 1.00 75.06 H ATOM 9737 HG2 MET B 224 -11.847 -0.485 -56.767 1.00 75.06 H ATOM 9738 HE1 MET B 224 -11.149 3.521 -59.034 1.00 81.95 H ATOM 9739 HE2 MET B 224 -11.477 1.968 -59.817 1.00 81.95 H ATOM 9740 HE3 MET B 224 -12.769 2.823 -58.951 1.00 81.95 H ATOM 9741 N GLU B 225 -16.833 0.647 -56.345 1.00 69.76 N ATOM 9742 CA GLU B 225 -18.210 1.132 -56.480 1.00 68.67 C ATOM 9743 C GLU B 225 -18.453 2.405 -55.649 1.00 66.94 C ATOM 9744 O GLU B 225 -19.040 3.349 -56.173 1.00 68.13 O ATOM 9745 CB GLU B 225 -19.210 0.005 -56.147 1.00 68.47 C ATOM 9746 CG GLU B 225 -20.691 0.385 -56.390 0.00 68.39 C ATOM 9747 CD GLU B 225 -21.701 -0.763 -56.214 0.00 68.36 C ATOM 9748 OE1 GLU B 225 -21.374 -1.762 -55.534 0.00 68.33 O ATOM 9749 OE2 GLU B 225 -22.811 -0.617 -56.773 0.00 68.35 O1- ATOM 9750 H GLU B 225 -16.706 -0.203 -55.812 1.00 69.76 H ATOM 9751 HA GLU B 225 -18.356 1.394 -57.530 1.00 68.67 H ATOM 9752 HB3 GLU B 225 -19.082 -0.290 -55.105 1.00 68.47 H ATOM 9753 HB2 GLU B 225 -18.961 -0.876 -56.743 1.00 68.47 H ATOM 9754 HG3 GLU B 225 -20.792 0.788 -57.399 1.00 68.39 H ATOM 9755 HG2 GLU B 225 -20.989 1.184 -55.710 1.00 68.39 H ATOM 9756 N LYS B 226 -17.934 2.433 -54.408 1.00 65.13 N ATOM 9757 CA LYS B 226 -17.974 3.601 -53.525 1.00 63.77 C ATOM 9758 C LYS B 226 -17.036 4.738 -53.957 1.00 62.57 C ATOM 9759 O LYS B 226 -17.356 5.893 -53.684 1.00 60.92 O ATOM 9760 CB LYS B 226 -17.705 3.173 -52.071 1.00 63.73 C ATOM 9761 CG LYS B 226 -18.857 2.338 -51.495 1.00 67.19 C ATOM 9762 CD LYS B 226 -18.668 1.999 -50.007 1.00 69.12 C ATOM 9763 CE LYS B 226 -19.763 1.077 -49.438 0.00 68.47 C ATOM 9764 NZ LYS B 226 -21.103 1.693 -49.476 0.00 68.58 N1+ ATOM 9765 H LYS B 226 -17.451 1.620 -54.053 1.00 65.13 H ATOM 9766 HA LYS B 226 -18.986 4.005 -53.569 1.00 63.77 H ATOM 9767 HB3 LYS B 226 -17.589 4.062 -51.448 1.00 63.73 H ATOM 9768 HB2 LYS B 226 -16.764 2.626 -52.000 1.00 63.73 H ATOM 9769 HG3 LYS B 226 -18.962 1.416 -52.068 1.00 67.19 H ATOM 9770 HG2 LYS B 226 -19.789 2.886 -51.633 1.00 67.19 H ATOM 9771 HD3 LYS B 226 -18.618 2.920 -49.425 1.00 69.12 H ATOM 9772 HD2 LYS B 226 -17.699 1.514 -49.875 1.00 69.12 H ATOM 9773 HE3 LYS B 226 -19.529 0.824 -48.403 1.00 68.47 H ATOM 9774 HE2 LYS B 226 -19.794 0.139 -49.993 1.00 68.47 H ATOM 9775 HZ1 LYS B 226 -21.345 1.906 -50.434 1.00 68.58 H ATOM 9776 HZ2 LYS B 226 -21.782 1.051 -49.094 1.00 68.58 H ATOM 9777 HZ3 LYS B 226 -21.101 2.546 -48.935 1.00 68.58 H ATOM 9778 N ILE B 227 -15.934 4.416 -54.658 1.00 60.77 N ATOM 9779 CA ILE B 227 -15.056 5.409 -55.286 1.00 59.99 C ATOM 9780 C ILE B 227 -15.760 6.101 -56.476 1.00 60.41 C ATOM 9781 O ILE B 227 -15.647 7.318 -56.604 1.00 58.89 O ATOM 9782 CB ILE B 227 -13.706 4.789 -55.767 1.00 59.68 C ATOM 9783 CG1 ILE B 227 -12.945 4.066 -54.630 1.00 58.82 C ATOM 9784 CG2 ILE B 227 -12.766 5.787 -56.477 1.00 59.30 C ATOM 9785 CD1 ILE B 227 -12.621 4.932 -53.407 1.00 56.17 C ATOM 9786 H ILE B 227 -15.722 3.445 -54.840 1.00 60.77 H ATOM 9787 HA ILE B 227 -14.836 6.183 -54.548 1.00 59.99 H ATOM 9788 HB ILE B 227 -13.941 4.023 -56.506 1.00 59.68 H ATOM 9789 HG13 ILE B 227 -12.023 3.633 -55.019 1.00 58.82 H ATOM 9790 HG12 ILE B 227 -13.531 3.216 -54.289 1.00 58.82 H ATOM 9791 HG21 ILE B 227 -11.806 5.327 -56.712 1.00 59.30 H ATOM 9792 HG22 ILE B 227 -13.183 6.128 -57.422 1.00 59.30 H ATOM 9793 HG23 ILE B 227 -12.571 6.666 -55.863 1.00 59.30 H ATOM 9794 HD11 ILE B 227 -11.916 4.422 -52.751 1.00 56.17 H ATOM 9795 HD12 ILE B 227 -12.179 5.884 -53.693 1.00 56.17 H ATOM 9796 HD13 ILE B 227 -13.518 5.136 -52.824 1.00 56.17 H ATOM 9797 N LEU B 228 -16.517 5.327 -57.277 1.00 60.42 N ATOM 9798 CA LEU B 228 -17.335 5.810 -58.393 1.00 60.49 C ATOM 9799 C LEU B 228 -18.537 6.668 -57.955 1.00 58.68 C ATOM 9800 O LEU B 228 -18.878 7.601 -58.680 1.00 59.98 O ATOM 9801 CB LEU B 228 -17.794 4.618 -59.261 1.00 60.68 C ATOM 9802 CG LEU B 228 -16.684 4.013 -60.149 1.00 63.91 C ATOM 9803 CD1 LEU B 228 -17.096 2.623 -60.680 1.00 68.89 C ATOM 9804 CD2 LEU B 228 -16.250 4.980 -61.275 1.00 67.68 C ATOM 9805 H LEU B 228 -16.553 4.330 -57.106 1.00 60.42 H ATOM 9806 HA LEU B 228 -16.703 6.454 -59.002 1.00 60.49 H ATOM 9807 HB3 LEU B 228 -18.618 4.918 -59.908 1.00 60.68 H ATOM 9808 HB2 LEU B 228 -18.203 3.848 -58.607 1.00 60.68 H ATOM 9809 HG LEU B 228 -15.806 3.858 -59.523 1.00 63.91 H ATOM 9810 HD11 LEU B 228 -17.021 2.538 -61.764 1.00 68.89 H ATOM 9811 HD12 LEU B 228 -16.458 1.847 -60.255 1.00 68.89 H ATOM 9812 HD13 LEU B 228 -18.123 2.370 -60.415 1.00 68.89 H ATOM 9813 HD21 LEU B 228 -16.341 4.544 -62.269 1.00 67.68 H ATOM 9814 HD22 LEU B 228 -16.842 5.896 -61.281 1.00 67.68 H ATOM 9815 HD23 LEU B 228 -15.208 5.272 -61.148 1.00 67.68 H ATOM 9816 N GLU B 229 -19.129 6.379 -56.781 1.00 57.02 N ATOM 9817 CA GLU B 229 -20.163 7.210 -56.153 1.00 57.15 C ATOM 9818 C GLU B 229 -19.648 8.616 -55.800 1.00 55.57 C ATOM 9819 O GLU B 229 -20.330 9.594 -56.102 1.00 54.39 O ATOM 9820 CB GLU B 229 -20.729 6.519 -54.895 1.00 57.80 C ATOM 9821 CG GLU B 229 -21.611 5.284 -55.185 1.00 61.08 C ATOM 9822 CD GLU B 229 -21.985 4.431 -53.957 1.00 65.04 C ATOM 9823 OE1 GLU B 229 -21.638 4.809 -52.814 1.00 66.93 O ATOM 9824 OE2 GLU B 229 -22.634 3.388 -54.187 1.00 64.49 O1- ATOM 9825 H GLU B 229 -18.818 5.575 -56.251 1.00 57.02 H ATOM 9826 HA GLU B 229 -20.976 7.333 -56.872 1.00 57.15 H ATOM 9827 HB3 GLU B 229 -21.316 7.237 -54.321 1.00 57.80 H ATOM 9828 HB2 GLU B 229 -19.896 6.233 -54.253 1.00 57.80 H ATOM 9829 HG3 GLU B 229 -21.130 4.640 -55.918 1.00 61.08 H ATOM 9830 HG2 GLU B 229 -22.537 5.615 -55.653 1.00 61.08 H ATOM 9831 N ILE B 230 -18.442 8.684 -55.206 1.00 54.63 N ATOM 9832 CA ILE B 230 -17.775 9.930 -54.825 1.00 53.48 C ATOM 9833 C ILE B 230 -17.295 10.737 -56.054 1.00 53.82 C ATOM 9834 O ILE B 230 -17.397 11.963 -56.027 1.00 53.04 O ATOM 9835 CB ILE B 230 -16.568 9.673 -53.874 1.00 52.51 C ATOM 9836 CG1 ILE B 230 -16.994 8.959 -52.569 1.00 51.84 C ATOM 9837 CG2 ILE B 230 -15.777 10.942 -53.492 1.00 48.91 C ATOM 9838 CD1 ILE B 230 -15.830 8.265 -51.843 1.00 46.96 C ATOM 9839 H ILE B 230 -17.946 7.830 -54.992 1.00 54.63 H ATOM 9840 HA ILE B 230 -18.505 10.542 -54.293 1.00 53.48 H ATOM 9841 HB ILE B 230 -15.887 9.006 -54.404 1.00 52.51 H ATOM 9842 HG13 ILE B 230 -17.770 8.220 -52.757 1.00 51.84 H ATOM 9843 HG12 ILE B 230 -17.456 9.682 -51.897 1.00 51.84 H ATOM 9844 HG21 ILE B 230 -14.951 10.697 -52.831 1.00 48.91 H ATOM 9845 HG22 ILE B 230 -15.347 11.454 -54.349 1.00 48.91 H ATOM 9846 HG23 ILE B 230 -16.409 11.652 -52.963 1.00 48.91 H ATOM 9847 HD11 ILE B 230 -16.160 7.336 -51.379 1.00 46.96 H ATOM 9848 HD12 ILE B 230 -15.017 8.010 -52.524 1.00 46.96 H ATOM 9849 HD13 ILE B 230 -15.420 8.900 -51.058 1.00 46.96 H ATOM 9850 N ILE B 231 -16.832 10.047 -57.115 1.00 54.74 N ATOM 9851 CA ILE B 231 -16.455 10.645 -58.403 1.00 55.32 C ATOM 9852 C ILE B 231 -17.631 11.368 -59.094 1.00 56.45 C ATOM 9853 O ILE B 231 -17.427 12.474 -59.589 1.00 57.89 O ATOM 9854 CB ILE B 231 -15.809 9.601 -59.373 1.00 56.42 C ATOM 9855 CG1 ILE B 231 -14.371 9.259 -58.919 1.00 55.11 C ATOM 9856 CG2 ILE B 231 -15.806 9.983 -60.875 1.00 54.70 C ATOM 9857 CD1 ILE B 231 -13.814 7.952 -59.501 1.00 54.98 C ATOM 9858 H ILE B 231 -16.756 9.041 -57.054 1.00 54.74 H ATOM 9859 HA ILE B 231 -15.702 11.405 -58.186 1.00 55.32 H ATOM 9860 HB ILE B 231 -16.397 8.688 -59.290 1.00 56.42 H ATOM 9861 HG13 ILE B 231 -14.336 9.176 -57.835 1.00 55.11 H ATOM 9862 HG12 ILE B 231 -13.699 10.080 -59.167 1.00 55.11 H ATOM 9863 HG21 ILE B 231 -15.301 9.236 -61.484 1.00 54.70 H ATOM 9864 HG22 ILE B 231 -16.815 10.055 -61.280 1.00 54.70 H ATOM 9865 HG23 ILE B 231 -15.303 10.937 -61.041 1.00 54.70 H ATOM 9866 HD11 ILE B 231 -12.840 7.728 -59.068 1.00 54.98 H ATOM 9867 HD12 ILE B 231 -14.471 7.109 -59.291 1.00 54.98 H ATOM 9868 HD13 ILE B 231 -13.679 8.008 -60.580 1.00 54.98 H ATOM 9869 N ARG B 232 -18.834 10.765 -59.081 1.00 57.97 N ATOM 9870 CA ARG B 232 -20.051 11.373 -59.633 1.00 58.74 C ATOM 9871 C ARG B 232 -20.558 12.582 -58.825 1.00 57.33 C ATOM 9872 O ARG B 232 -21.144 13.478 -59.434 1.00 56.48 O ATOM 9873 CB ARG B 232 -21.155 10.310 -59.808 1.00 60.80 C ATOM 9874 CG ARG B 232 -20.868 9.334 -60.966 1.00 66.95 C ATOM 9875 CD ARG B 232 -22.006 8.332 -61.243 1.00 72.76 C ATOM 9876 NE ARG B 232 -22.109 7.270 -60.226 1.00 77.35 N ATOM 9877 CZ ARG B 232 -21.634 6.012 -60.305 1.00 81.94 C ATOM 9878 NH1 ARG B 232 -20.978 5.559 -61.385 1.00 82.40 N ATOM 9879 NH2 ARG B 232 -21.828 5.185 -59.270 1.00 82.17 N1+ ATOM 9880 H ARG B 232 -18.934 9.852 -58.660 1.00 57.97 H ATOM 9881 HA ARG B 232 -19.806 11.759 -60.625 1.00 58.74 H ATOM 9882 HB3 ARG B 232 -22.098 10.812 -60.031 1.00 60.80 H ATOM 9883 HB2 ARG B 232 -21.313 9.771 -58.873 1.00 60.80 H ATOM 9884 HG3 ARG B 232 -19.973 8.776 -60.691 1.00 66.95 H ATOM 9885 HG2 ARG B 232 -20.604 9.858 -61.885 1.00 66.95 H ATOM 9886 HD3 ARG B 232 -21.993 7.967 -62.271 1.00 72.76 H ATOM 9887 HD2 ARG B 232 -22.951 8.865 -61.143 1.00 72.76 H ATOM 9888 HE ARG B 232 -22.582 7.533 -59.370 1.00 77.35 H ATOM 9889 HH12 ARG B 232 -20.638 4.609 -61.421 1.00 82.40 H ATOM 9890 HH11 ARG B 232 -20.821 6.172 -62.171 1.00 82.40 H ATOM 9891 HH22 ARG B 232 -21.483 4.237 -59.291 1.00 82.17 H ATOM 9892 HH21 ARG B 232 -22.327 5.509 -58.452 1.00 82.17 H ATOM 9893 N VAL B 233 -20.292 12.630 -57.506 1.00 55.61 N ATOM 9894 CA VAL B 233 -20.553 13.810 -56.672 1.00 53.83 C ATOM 9895 C VAL B 233 -19.575 14.963 -56.988 1.00 52.98 C ATOM 9896 O VAL B 233 -20.014 16.112 -57.014 1.00 51.27 O ATOM 9897 CB VAL B 233 -20.519 13.480 -55.148 1.00 54.84 C ATOM 9898 CG1 VAL B 233 -20.534 14.709 -54.211 1.00 52.97 C ATOM 9899 CG2 VAL B 233 -21.685 12.551 -54.764 1.00 50.04 C ATOM 9900 H VAL B 233 -19.815 11.858 -57.060 1.00 55.61 H ATOM 9901 HA VAL B 233 -21.558 14.167 -56.909 1.00 53.83 H ATOM 9902 HB VAL B 233 -19.600 12.933 -54.941 1.00 54.84 H ATOM 9903 HG11 VAL B 233 -20.662 14.410 -53.172 1.00 52.97 H ATOM 9904 HG12 VAL B 233 -19.604 15.276 -54.260 1.00 52.97 H ATOM 9905 HG13 VAL B 233 -21.353 15.386 -54.456 1.00 52.97 H ATOM 9906 HG21 VAL B 233 -21.613 12.239 -53.721 1.00 50.04 H ATOM 9907 HG22 VAL B 233 -22.646 13.049 -54.897 1.00 50.04 H ATOM 9908 HG23 VAL B 233 -21.700 11.647 -55.370 1.00 50.04 H ATOM 9909 N ILE B 234 -18.298 14.638 -57.267 1.00 52.08 N ATOM 9910 CA ILE B 234 -17.263 15.591 -57.687 1.00 52.23 C ATOM 9911 C ILE B 234 -17.511 16.174 -59.098 1.00 53.33 C ATOM 9912 O ILE B 234 -17.195 17.342 -59.319 1.00 53.19 O ATOM 9913 CB ILE B 234 -15.830 14.973 -57.591 1.00 51.08 C ATOM 9914 CG1 ILE B 234 -15.438 14.740 -56.113 1.00 52.23 C ATOM 9915 CG2 ILE B 234 -14.714 15.780 -58.296 1.00 49.69 C ATOM 9916 CD1 ILE B 234 -14.265 13.767 -55.917 1.00 52.49 C ATOM 9917 H ILE B 234 -18.011 13.670 -57.210 1.00 52.08 H ATOM 9918 HA ILE B 234 -17.303 16.429 -56.989 1.00 52.23 H ATOM 9919 HB ILE B 234 -15.866 13.995 -58.071 1.00 51.08 H ATOM 9920 HG13 ILE B 234 -16.287 14.356 -55.548 1.00 52.23 H ATOM 9921 HG12 ILE B 234 -15.194 15.698 -55.653 1.00 52.23 H ATOM 9922 HG21 ILE B 234 -13.734 15.331 -58.144 1.00 49.69 H ATOM 9923 HG22 ILE B 234 -14.855 15.827 -59.376 1.00 49.69 H ATOM 9924 HG23 ILE B 234 -14.667 16.801 -57.916 1.00 49.69 H ATOM 9925 HD11 ILE B 234 -14.182 13.470 -54.872 1.00 52.49 H ATOM 9926 HD12 ILE B 234 -14.392 12.861 -56.510 1.00 52.49 H ATOM 9927 HD13 ILE B 234 -13.314 14.221 -56.197 1.00 52.49 H ATOM 9928 N LEU B 235 -18.102 15.387 -60.013 1.00 52.27 N ATOM 9929 CA LEU B 235 -18.489 15.846 -61.350 1.00 53.61 C ATOM 9930 C LEU B 235 -19.738 16.748 -61.317 1.00 53.19 C ATOM 9931 O LEU B 235 -19.741 17.776 -61.994 1.00 54.75 O ATOM 9932 CB LEU B 235 -18.696 14.635 -62.286 1.00 53.05 C ATOM 9933 CG LEU B 235 -17.392 13.900 -62.676 1.00 57.26 C ATOM 9934 CD1 LEU B 235 -17.700 12.565 -63.385 1.00 55.03 C ATOM 9935 CD2 LEU B 235 -16.430 14.789 -63.493 1.00 54.00 C ATOM 9936 H LEU B 235 -18.311 14.425 -59.785 1.00 52.27 H ATOM 9937 HA LEU B 235 -17.676 16.456 -61.748 1.00 53.61 H ATOM 9938 HB3 LEU B 235 -19.194 14.956 -63.203 1.00 53.05 H ATOM 9939 HB2 LEU B 235 -19.384 13.939 -61.804 1.00 53.05 H ATOM 9940 HG LEU B 235 -16.868 13.645 -61.756 1.00 57.26 H ATOM 9941 HD11 LEU B 235 -17.145 11.748 -62.925 1.00 55.03 H ATOM 9942 HD12 LEU B 235 -18.757 12.304 -63.328 1.00 55.03 H ATOM 9943 HD13 LEU B 235 -17.437 12.580 -64.442 1.00 55.03 H ATOM 9944 HD21 LEU B 235 -16.008 14.272 -64.355 1.00 54.00 H ATOM 9945 HD22 LEU B 235 -16.921 15.686 -63.869 1.00 54.00 H ATOM 9946 HD23 LEU B 235 -15.590 15.112 -62.877 1.00 54.00 H ATOM 9947 N LYS B 236 -20.750 16.376 -60.511 1.00 52.54 N ATOM 9948 CA LYS B 236 -21.982 17.149 -60.303 1.00 53.69 C ATOM 9949 C LYS B 236 -21.739 18.494 -59.586 1.00 53.97 C ATOM 9950 O LYS B 236 -22.434 19.466 -59.878 1.00 55.43 O ATOM 9951 CB LYS B 236 -23.007 16.266 -59.557 1.00 53.19 C ATOM 9952 CG LYS B 236 -24.383 16.924 -59.337 1.00 53.81 C ATOM 9953 CD LYS B 236 -25.397 15.990 -58.665 0.00 53.44 C ATOM 9954 CE LYS B 236 -26.743 16.691 -58.415 0.00 53.43 C ATOM 9955 NZ LYS B 236 -27.720 15.796 -57.771 0.00 53.40 N1+ ATOM 9956 H LYS B 236 -20.677 15.511 -59.992 1.00 52.54 H ATOM 9957 HA LYS B 236 -22.392 17.377 -61.289 1.00 53.69 H ATOM 9958 HB3 LYS B 236 -22.595 15.960 -58.593 1.00 53.19 H ATOM 9959 HB2 LYS B 236 -23.154 15.347 -60.126 1.00 53.19 H ATOM 9960 HG3 LYS B 236 -24.778 17.263 -60.296 1.00 53.81 H ATOM 9961 HG2 LYS B 236 -24.279 17.815 -58.719 1.00 53.81 H ATOM 9962 HD3 LYS B 236 -24.982 15.630 -57.721 1.00 53.44 H ATOM 9963 HD2 LYS B 236 -25.545 15.110 -59.293 1.00 53.44 H ATOM 9964 HE3 LYS B 236 -27.164 17.048 -59.356 1.00 53.43 H ATOM 9965 HE2 LYS B 236 -26.600 17.564 -57.776 1.00 53.43 H ATOM 9966 HZ1 LYS B 236 -27.359 15.484 -56.881 1.00 53.40 H ATOM 9967 HZ2 LYS B 236 -28.587 16.294 -57.624 1.00 53.40 H ATOM 9968 HZ3 LYS B 236 -27.890 14.996 -58.365 1.00 53.40 H ATOM 9969 N LEU B 237 -20.734 18.521 -58.696 1.00 53.67 N ATOM 9970 CA LEU B 237 -20.206 19.686 -57.985 1.00 53.26 C ATOM 9971 C LEU B 237 -19.783 20.829 -58.928 1.00 50.74 C ATOM 9972 O LEU B 237 -20.160 21.972 -58.674 1.00 47.52 O ATOM 9973 CB LEU B 237 -19.072 19.177 -57.059 1.00 53.94 C ATOM 9974 CG LEU B 237 -18.003 20.169 -56.556 1.00 60.22 C ATOM 9975 CD1 LEU B 237 -18.585 21.126 -55.504 1.00 68.37 C ATOM 9976 CD2 LEU B 237 -16.768 19.407 -56.037 1.00 64.18 C ATOM 9977 H LEU B 237 -20.246 17.655 -58.507 1.00 53.67 H ATOM 9978 HA LEU B 237 -21.007 20.076 -57.356 1.00 53.26 H ATOM 9979 HB3 LEU B 237 -18.534 18.411 -57.605 1.00 53.94 H ATOM 9980 HB2 LEU B 237 -19.511 18.655 -56.208 1.00 53.94 H ATOM 9981 HG LEU B 237 -17.636 20.774 -57.385 1.00 60.22 H ATOM 9982 HD11 LEU B 237 -18.398 22.160 -55.787 1.00 68.37 H ATOM 9983 HD12 LEU B 237 -19.663 21.007 -55.386 1.00 68.37 H ATOM 9984 HD13 LEU B 237 -18.140 20.960 -54.528 1.00 68.37 H ATOM 9985 HD21 LEU B 237 -16.278 19.922 -55.216 1.00 64.18 H ATOM 9986 HD22 LEU B 237 -17.021 18.406 -55.687 1.00 64.18 H ATOM 9987 HD23 LEU B 237 -16.024 19.299 -56.828 1.00 64.18 H ATOM 9988 N TYR B 238 -19.038 20.502 -59.998 1.00 49.23 N ATOM 9989 CA TYR B 238 -18.566 21.474 -60.989 1.00 49.52 C ATOM 9990 C TYR B 238 -19.654 21.948 -61.968 1.00 51.86 C ATOM 9991 O TYR B 238 -19.530 23.059 -62.484 1.00 51.29 O ATOM 9992 CB TYR B 238 -17.334 20.917 -61.731 1.00 49.75 C ATOM 9993 CG TYR B 238 -16.127 20.674 -60.840 1.00 46.61 C ATOM 9994 CD1 TYR B 238 -15.624 21.716 -60.031 1.00 45.17 C ATOM 9995 CD2 TYR B 238 -15.504 19.409 -60.808 1.00 42.28 C ATOM 9996 CE1 TYR B 238 -14.540 21.482 -59.168 1.00 47.93 C ATOM 9997 CE2 TYR B 238 -14.413 19.177 -59.948 1.00 47.09 C ATOM 9998 CZ TYR B 238 -13.939 20.210 -59.118 1.00 49.74 C ATOM 9999 OH TYR B 238 -12.901 19.979 -58.266 1.00 47.65 O ATOM 10000 H TYR B 238 -18.761 19.541 -60.143 1.00 49.23 H ATOM 10001 HA TYR B 238 -18.254 22.366 -60.445 1.00 49.52 H ATOM 10002 HB3 TYR B 238 -17.022 21.616 -62.509 1.00 49.75 H ATOM 10003 HB2 TYR B 238 -17.602 19.993 -62.246 1.00 49.75 H ATOM 10004 HD1 TYR B 238 -16.074 22.697 -60.056 1.00 45.17 H ATOM 10005 HD2 TYR B 238 -15.873 18.604 -61.429 1.00 42.28 H ATOM 10006 HE1 TYR B 238 -14.181 22.287 -58.546 1.00 47.93 H ATOM 10007 HE2 TYR B 238 -13.950 18.202 -59.918 1.00 47.09 H ATOM 10008 HH TYR B 238 -12.691 20.744 -57.717 1.00 47.65 H ATOM 10009 N GLU B 239 -20.713 21.146 -62.172 1.00 53.07 N ATOM 10010 CA GLU B 239 -21.895 21.549 -62.940 1.00 53.68 C ATOM 10011 C GLU B 239 -22.830 22.477 -62.145 1.00 53.49 C ATOM 10012 O GLU B 239 -23.450 23.346 -62.755 1.00 53.42 O ATOM 10013 CB GLU B 239 -22.641 20.308 -63.475 1.00 54.19 C ATOM 10014 CG GLU B 239 -21.816 19.446 -64.460 1.00 57.12 C ATOM 10015 CD GLU B 239 -21.371 20.159 -65.750 1.00 57.15 C ATOM 10016 OE1 GLU B 239 -22.160 20.968 -66.290 1.00 59.30 O ATOM 10017 OE2 GLU B 239 -20.235 19.873 -66.189 1.00 58.01 O1- ATOM 10018 H GLU B 239 -20.751 20.238 -61.730 1.00 53.07 H ATOM 10019 HA GLU B 239 -21.557 22.135 -63.796 1.00 53.68 H ATOM 10020 HB3 GLU B 239 -23.578 20.610 -63.946 1.00 54.19 H ATOM 10021 HB2 GLU B 239 -22.932 19.678 -62.634 1.00 54.19 H ATOM 10022 HG3 GLU B 239 -22.408 18.578 -64.752 1.00 57.12 H ATOM 10023 HG2 GLU B 239 -20.943 19.047 -63.944 1.00 57.12 H ATOM 10024 N GLN B 240 -22.879 22.327 -60.808 1.00 52.54 N ATOM 10025 CA GLN B 240 -23.560 23.270 -59.919 1.00 53.85 C ATOM 10026 C GLN B 240 -22.801 24.604 -59.813 1.00 52.68 C ATOM 10027 O GLN B 240 -23.457 25.642 -59.797 1.00 52.39 O ATOM 10028 CB GLN B 240 -23.808 22.631 -58.533 1.00 55.00 C ATOM 10029 CG GLN B 240 -24.526 23.532 -57.496 1.00 60.71 C ATOM 10030 CD GLN B 240 -25.986 23.827 -57.860 1.00 67.88 C ATOM 10031 OE1 GLN B 240 -26.882 23.073 -57.490 1.00 70.89 O ATOM 10032 NE2 GLN B 240 -26.236 24.917 -58.588 1.00 67.99 N ATOM 10033 H GLN B 240 -22.372 21.571 -60.367 1.00 52.54 H ATOM 10034 HA GLN B 240 -24.534 23.483 -60.363 1.00 53.85 H ATOM 10035 HB3 GLN B 240 -22.856 22.309 -58.112 1.00 55.00 H ATOM 10036 HB2 GLN B 240 -24.388 21.718 -58.669 1.00 55.00 H ATOM 10037 HG3 GLN B 240 -23.989 24.467 -57.331 1.00 60.71 H ATOM 10038 HG2 GLN B 240 -24.521 23.031 -56.528 1.00 60.71 H ATOM 10039 HE22 GLN B 240 -27.186 25.131 -58.860 1.00 67.99 H ATOM 10040 HE21 GLN B 240 -25.479 25.510 -58.901 1.00 67.99 H ATOM 10041 N TRP B 241 -21.456 24.553 -59.772 1.00 52.26 N ATOM 10042 CA TRP B 241 -20.547 25.707 -59.732 1.00 52.05 C ATOM 10043 C TRP B 241 -20.746 26.628 -60.949 1.00 52.39 C ATOM 10044 O TRP B 241 -20.897 27.835 -60.770 1.00 50.40 O ATOM 10045 CB TRP B 241 -19.099 25.173 -59.638 1.00 51.50 C ATOM 10046 CG TRP B 241 -17.964 26.103 -59.303 1.00 49.18 C ATOM 10047 CD1 TRP B 241 -17.739 27.351 -59.781 1.00 48.01 C ATOM 10048 CD2 TRP B 241 -16.809 25.795 -58.465 1.00 48.57 C ATOM 10049 NE1 TRP B 241 -16.564 27.848 -59.256 1.00 45.22 N ATOM 10050 CE2 TRP B 241 -15.944 26.931 -58.437 1.00 51.07 C ATOM 10051 CE3 TRP B 241 -16.411 24.666 -57.715 1.00 45.39 C ATOM 10052 CZ2 TRP B 241 -14.752 26.951 -57.691 1.00 49.06 C ATOM 10053 CZ3 TRP B 241 -15.225 24.679 -56.957 1.00 47.49 C ATOM 10054 CH2 TRP B 241 -14.394 25.815 -56.943 1.00 48.77 C ATOM 10055 H TRP B 241 -21.008 23.647 -59.783 1.00 52.26 H ATOM 10056 HA TRP B 241 -20.775 26.266 -58.823 1.00 52.05 H ATOM 10057 HB3 TRP B 241 -18.830 24.666 -60.563 1.00 51.50 H ATOM 10058 HB2 TRP B 241 -19.078 24.403 -58.867 1.00 51.50 H ATOM 10059 HD1 TRP B 241 -18.374 27.884 -60.469 1.00 48.01 H ATOM 10060 HE1 TRP B 241 -16.219 28.771 -59.476 1.00 45.22 H ATOM 10061 HE3 TRP B 241 -17.034 23.784 -57.705 1.00 45.39 H ATOM 10062 HZ2 TRP B 241 -14.121 27.827 -57.690 1.00 49.06 H ATOM 10063 HZ3 TRP B 241 -14.967 23.809 -56.378 1.00 47.49 H ATOM 10064 HH2 TRP B 241 -13.486 25.814 -56.358 1.00 48.77 H ATOM 10065 N LYS B 242 -20.793 26.015 -62.144 1.00 52.74 N ATOM 10066 CA LYS B 242 -21.097 26.624 -63.440 1.00 53.70 C ATOM 10067 C LYS B 242 -22.422 27.411 -63.455 1.00 53.91 C ATOM 10068 O LYS B 242 -22.446 28.540 -63.943 1.00 54.65 O ATOM 10069 CB LYS B 242 -21.076 25.480 -64.482 1.00 53.68 C ATOM 10070 CG LYS B 242 -21.617 25.784 -65.893 1.00 56.38 C ATOM 10071 CD LYS B 242 -21.841 24.488 -66.683 1.00 58.99 C ATOM 10072 CE LYS B 242 -22.518 24.719 -68.041 1.00 62.73 C ATOM 10073 NZ LYS B 242 -22.786 23.441 -68.724 1.00 63.40 N1+ ATOM 10074 H LYS B 242 -20.644 25.016 -62.171 1.00 52.74 H ATOM 10075 HA LYS B 242 -20.289 27.320 -63.671 1.00 53.70 H ATOM 10076 HB3 LYS B 242 -21.680 24.667 -64.081 1.00 53.68 H ATOM 10077 HB2 LYS B 242 -20.066 25.075 -64.561 1.00 53.68 H ATOM 10078 HG3 LYS B 242 -20.923 26.435 -66.424 1.00 56.38 H ATOM 10079 HG2 LYS B 242 -22.567 26.316 -65.851 1.00 56.38 H ATOM 10080 HD3 LYS B 242 -22.458 23.814 -66.085 1.00 58.99 H ATOM 10081 HD2 LYS B 242 -20.884 23.982 -66.823 1.00 58.99 H ATOM 10082 HE3 LYS B 242 -21.892 25.344 -68.678 1.00 62.73 H ATOM 10083 HE2 LYS B 242 -23.466 25.241 -67.904 1.00 62.73 H ATOM 10084 HZ1 LYS B 242 -23.372 22.864 -68.138 1.00 63.40 H ATOM 10085 HZ2 LYS B 242 -23.248 23.613 -69.605 1.00 63.40 H ATOM 10086 HZ3 LYS B 242 -21.914 22.957 -68.886 1.00 63.40 H ATOM 10087 N ASN B 243 -23.490 26.784 -62.935 1.00 54.58 N ATOM 10088 CA ASN B 243 -24.864 27.296 -62.972 1.00 55.47 C ATOM 10089 C ASN B 243 -25.227 28.181 -61.760 1.00 54.76 C ATOM 10090 O ASN B 243 -26.341 28.704 -61.738 1.00 57.81 O ATOM 10091 CB ASN B 243 -25.836 26.096 -63.092 1.00 56.35 C ATOM 10092 CG ASN B 243 -25.698 25.291 -64.394 1.00 56.66 C ATOM 10093 OD1 ASN B 243 -25.283 25.810 -65.428 1.00 58.82 O ATOM 10094 ND2 ASN B 243 -26.073 24.011 -64.352 1.00 56.14 N ATOM 10095 H ASN B 243 -23.374 25.858 -62.547 1.00 54.58 H ATOM 10096 HA ASN B 243 -24.974 27.918 -63.863 1.00 55.47 H ATOM 10097 HB3 ASN B 243 -26.868 26.448 -63.057 1.00 56.35 H ATOM 10098 HB2 ASN B 243 -25.710 25.430 -62.236 1.00 56.35 H ATOM 10099 HD22 ASN B 243 -26.009 23.438 -65.180 1.00 56.14 H ATOM 10100 HD21 ASN B 243 -26.409 23.604 -63.492 1.00 56.14 H ATOM 10101 N PHE B 244 -24.310 28.344 -60.790 1.00 53.23 N ATOM 10102 CA PHE B 244 -24.501 29.142 -59.578 1.00 53.08 C ATOM 10103 C PHE B 244 -23.637 30.408 -59.633 1.00 52.85 C ATOM 10104 O PHE B 244 -22.458 30.328 -59.980 1.00 53.95 O ATOM 10105 CB PHE B 244 -24.145 28.272 -58.349 1.00 52.47 C ATOM 10106 CG PHE B 244 -24.191 28.918 -56.971 1.00 52.96 C ATOM 10107 CD1 PHE B 244 -25.225 29.813 -56.616 1.00 54.97 C ATOM 10108 CD2 PHE B 244 -23.303 28.476 -55.967 1.00 49.80 C ATOM 10109 CE1 PHE B 244 -25.316 30.301 -55.321 1.00 53.41 C ATOM 10110 CE2 PHE B 244 -23.418 28.969 -54.674 1.00 52.85 C ATOM 10111 CZ PHE B 244 -24.412 29.880 -54.356 1.00 54.86 C ATOM 10112 H PHE B 244 -23.405 27.904 -60.888 1.00 53.23 H ATOM 10113 HA PHE B 244 -25.548 29.441 -59.491 1.00 53.08 H ATOM 10114 HB3 PHE B 244 -23.137 27.877 -58.489 1.00 52.47 H ATOM 10115 HB2 PHE B 244 -24.807 27.408 -58.317 1.00 52.47 H ATOM 10116 HD1 PHE B 244 -25.958 30.121 -57.344 1.00 54.97 H ATOM 10117 HD2 PHE B 244 -22.534 27.753 -56.196 1.00 49.80 H ATOM 10118 HE1 PHE B 244 -26.102 30.993 -55.058 1.00 53.41 H ATOM 10119 HE2 PHE B 244 -22.740 28.645 -53.903 1.00 52.85 H ATOM 10120 HZ PHE B 244 -24.480 30.251 -53.347 1.00 54.86 H ATOM 10121 N ASP B 245 -24.233 31.538 -59.226 1.00 53.58 N ATOM 10122 CA ASP B 245 -23.547 32.808 -59.028 1.00 54.95 C ATOM 10123 C ASP B 245 -23.975 33.313 -57.644 1.00 54.01 C ATOM 10124 O ASP B 245 -25.028 33.937 -57.512 1.00 55.38 O ATOM 10125 CB ASP B 245 -23.834 33.791 -60.193 1.00 56.06 C ATOM 10126 CG ASP B 245 -22.970 35.066 -60.261 1.00 61.79 C ATOM 10127 OD1 ASP B 245 -22.441 35.520 -59.221 1.00 67.31 O ATOM 10128 OD2 ASP B 245 -22.937 35.644 -61.368 1.00 72.02 O1- ATOM 10129 H ASP B 245 -25.215 31.528 -58.979 1.00 53.58 H ATOM 10130 HA ASP B 245 -22.467 32.643 -58.994 1.00 54.95 H ATOM 10131 HB3 ASP B 245 -24.885 34.083 -60.179 1.00 56.06 H ATOM 10132 HB2 ASP B 245 -23.717 33.248 -61.134 1.00 56.06 H ATOM 10133 N GLU B 246 -23.140 33.012 -56.636 1.00 54.72 N ATOM 10134 CA GLU B 246 -23.371 33.344 -55.229 1.00 55.83 C ATOM 10135 C GLU B 246 -23.410 34.856 -54.936 1.00 54.49 C ATOM 10136 O GLU B 246 -24.072 35.256 -53.980 1.00 54.81 O ATOM 10137 CB GLU B 246 -22.328 32.605 -54.364 1.00 55.73 C ATOM 10138 CG GLU B 246 -20.877 33.116 -54.457 1.00 59.53 C ATOM 10139 CD GLU B 246 -19.921 32.175 -53.715 1.00 63.20 C ATOM 10140 OE1 GLU B 246 -19.318 31.320 -54.401 1.00 68.26 O ATOM 10141 OE2 GLU B 246 -19.819 32.308 -52.475 1.00 64.95 O1- ATOM 10142 H GLU B 246 -22.299 32.490 -56.832 1.00 54.72 H ATOM 10143 HA GLU B 246 -24.356 32.948 -54.982 1.00 55.83 H ATOM 10144 HB3 GLU B 246 -22.335 31.552 -54.644 1.00 55.73 H ATOM 10145 HB2 GLU B 246 -22.644 32.628 -53.322 1.00 55.73 H ATOM 10146 HG3 GLU B 246 -20.795 34.118 -54.036 1.00 59.53 H ATOM 10147 HG2 GLU B 246 -20.571 33.199 -55.501 1.00 59.53 H ATOM 10148 N ARG B 247 -22.743 35.670 -55.772 1.00 54.45 N ATOM 10149 CA ARG B 247 -22.736 37.128 -55.658 1.00 54.32 C ATOM 10150 C ARG B 247 -24.076 37.776 -56.043 1.00 53.38 C ATOM 10151 O ARG B 247 -24.406 38.822 -55.485 1.00 50.89 O ATOM 10152 CB ARG B 247 -21.548 37.723 -56.437 1.00 54.68 C ATOM 10153 CG ARG B 247 -20.193 37.195 -55.932 1.00 56.11 C ATOM 10154 CD ARG B 247 -18.983 37.843 -56.621 1.00 59.17 C ATOM 10155 NE ARG B 247 -17.731 37.524 -55.909 1.00 62.95 N ATOM 10156 CZ ARG B 247 -17.115 38.270 -54.971 1.00 64.29 C ATOM 10157 NH1 ARG B 247 -17.557 39.487 -54.616 1.00 63.79 N ATOM 10158 NH2 ARG B 247 -16.026 37.782 -54.365 1.00 66.25 N1+ ATOM 10159 H ARG B 247 -22.252 35.279 -56.564 1.00 54.45 H ATOM 10160 HA ARG B 247 -22.573 37.368 -54.612 1.00 54.32 H ATOM 10161 HB3 ARG B 247 -21.559 38.808 -56.321 1.00 54.68 H ATOM 10162 HB2 ARG B 247 -21.652 37.530 -57.504 1.00 54.68 H ATOM 10163 HG3 ARG B 247 -20.170 36.133 -56.180 1.00 56.11 H ATOM 10164 HG2 ARG B 247 -20.116 37.246 -54.847 1.00 56.11 H ATOM 10165 HD3 ARG B 247 -19.126 38.902 -56.834 1.00 59.17 H ATOM 10166 HD2 ARG B 247 -18.857 37.360 -57.590 1.00 59.17 H ATOM 10167 HE ARG B 247 -17.347 36.612 -56.112 1.00 62.95 H ATOM 10168 HH12 ARG B 247 -17.084 40.021 -53.901 1.00 63.79 H ATOM 10169 HH11 ARG B 247 -18.378 39.871 -55.062 1.00 63.79 H ATOM 10170 HH22 ARG B 247 -15.560 38.314 -53.644 1.00 66.25 H ATOM 10171 HH21 ARG B 247 -15.675 36.866 -54.606 1.00 66.25 H ATOM 10172 N LYS B 248 -24.835 37.129 -56.943 1.00 53.85 N ATOM 10173 CA LYS B 248 -26.166 37.565 -57.365 1.00 56.08 C ATOM 10174 C LYS B 248 -27.307 36.983 -56.511 1.00 55.48 C ATOM 10175 O LYS B 248 -28.383 37.582 -56.509 1.00 56.30 O ATOM 10176 CB LYS B 248 -26.371 37.191 -58.848 1.00 56.89 C ATOM 10177 CG LYS B 248 -25.530 38.044 -59.812 1.00 62.93 C ATOM 10178 CD LYS B 248 -25.820 37.712 -61.287 1.00 68.13 C ATOM 10179 CE LYS B 248 -25.126 38.639 -62.304 1.00 70.58 C ATOM 10180 NZ LYS B 248 -23.655 38.582 -62.225 1.00 72.77 N1+ ATOM 10181 H LYS B 248 -24.495 36.270 -57.355 1.00 53.85 H ATOM 10182 HA LYS B 248 -26.230 38.651 -57.281 1.00 56.08 H ATOM 10183 HB3 LYS B 248 -27.419 37.335 -59.113 1.00 56.89 H ATOM 10184 HB2 LYS B 248 -26.164 36.131 -59.003 1.00 56.89 H ATOM 10185 HG3 LYS B 248 -24.472 37.892 -59.596 1.00 62.93 H ATOM 10186 HG2 LYS B 248 -25.734 39.100 -59.632 1.00 62.93 H ATOM 10187 HD3 LYS B 248 -26.896 37.765 -61.456 1.00 68.13 H ATOM 10188 HD2 LYS B 248 -25.548 36.675 -61.487 1.00 68.13 H ATOM 10189 HE3 LYS B 248 -25.448 39.671 -62.158 1.00 70.58 H ATOM 10190 HE2 LYS B 248 -25.423 38.354 -63.313 1.00 70.58 H ATOM 10191 HZ1 LYS B 248 -23.353 37.620 -62.326 1.00 72.77 H ATOM 10192 HZ2 LYS B 248 -23.245 39.148 -62.953 1.00 72.77 H ATOM 10193 HZ3 LYS B 248 -23.353 38.918 -61.322 1.00 72.77 H ATOM 10194 N GLU B 249 -27.085 35.837 -55.842 1.00 55.31 N ATOM 10195 CA GLU B 249 -28.164 35.024 -55.269 1.00 54.66 C ATOM 10196 C GLU B 249 -28.213 34.977 -53.735 1.00 53.32 C ATOM 10197 O GLU B 249 -29.312 34.810 -53.206 1.00 53.69 O ATOM 10198 CB GLU B 249 -28.058 33.587 -55.812 1.00 54.81 C ATOM 10199 CG GLU B 249 -28.280 33.471 -57.337 1.00 56.52 C ATOM 10200 CD GLU B 249 -28.151 32.032 -57.854 1.00 59.58 C ATOM 10201 OE1 GLU B 249 -28.706 31.125 -57.195 1.00 60.16 O ATOM 10202 OE2 GLU B 249 -27.501 31.849 -58.907 1.00 66.71 O1- ATOM 10203 H GLU B 249 -26.174 35.403 -55.889 1.00 55.31 H ATOM 10204 HA GLU B 249 -29.135 35.410 -55.589 1.00 54.66 H ATOM 10205 HB3 GLU B 249 -28.781 32.958 -55.290 1.00 54.81 H ATOM 10206 HB2 GLU B 249 -27.075 33.181 -55.566 1.00 54.81 H ATOM 10207 HG3 GLU B 249 -27.589 34.120 -57.876 1.00 56.52 H ATOM 10208 HG2 GLU B 249 -29.280 33.829 -57.586 1.00 56.52 H ATOM 10209 N MET B 250 -27.063 35.057 -53.040 1.00 53.35 N ATOM 10210 CA MET B 250 -26.996 34.696 -51.618 1.00 54.38 C ATOM 10211 C MET B 250 -27.700 35.634 -50.631 1.00 55.46 C ATOM 10212 O MET B 250 -28.135 35.129 -49.601 1.00 54.70 O ATOM 10213 CB MET B 250 -25.557 34.376 -51.170 1.00 53.73 C ATOM 10214 CG MET B 250 -25.021 33.048 -51.731 1.00 54.26 C ATOM 10215 SD MET B 250 -26.002 31.546 -51.441 1.00 54.57 S ATOM 10216 CE MET B 250 -26.326 31.644 -49.668 1.00 47.87 C ATOM 10217 H MET B 250 -26.184 35.214 -53.514 1.00 53.35 H ATOM 10218 HA MET B 250 -27.568 33.774 -51.528 1.00 54.38 H ATOM 10219 HB3 MET B 250 -25.497 34.329 -50.081 1.00 53.73 H ATOM 10220 HB2 MET B 250 -24.893 35.192 -51.454 1.00 53.73 H ATOM 10221 HG3 MET B 250 -24.018 32.873 -51.348 1.00 54.26 H ATOM 10222 HG2 MET B 250 -24.925 33.131 -52.808 1.00 54.26 H ATOM 10223 HE1 MET B 250 -26.809 30.722 -49.356 1.00 47.87 H ATOM 10224 HE2 MET B 250 -25.404 31.766 -49.103 1.00 47.87 H ATOM 10225 HE3 MET B 250 -26.994 32.473 -49.443 1.00 47.87 H ATOM 10226 N ALA B 251 -27.870 36.931 -50.940 1.00 55.59 N ATOM 10227 CA ALA B 251 -28.673 37.835 -50.102 1.00 57.16 C ATOM 10228 C ALA B 251 -30.165 37.450 -50.052 1.00 58.06 C ATOM 10229 O ALA B 251 -30.779 37.578 -48.993 1.00 58.13 O ATOM 10230 CB ALA B 251 -28.495 39.288 -50.558 1.00 55.82 C ATOM 10231 H ALA B 251 -27.488 37.309 -51.797 1.00 55.59 H ATOM 10232 HA ALA B 251 -28.287 37.767 -49.082 1.00 57.16 H ATOM 10233 HB1 ALA B 251 -29.095 39.968 -49.951 1.00 55.82 H ATOM 10234 HB2 ALA B 251 -27.458 39.600 -50.456 1.00 55.82 H ATOM 10235 HB3 ALA B 251 -28.787 39.431 -51.597 1.00 55.82 H ATOM 10236 N THR B 252 -30.698 36.938 -51.176 1.00 58.19 N ATOM 10237 CA THR B 252 -32.061 36.418 -51.286 1.00 59.13 C ATOM 10238 C THR B 252 -32.223 35.048 -50.595 1.00 58.31 C ATOM 10239 O THR B 252 -33.235 34.839 -49.928 1.00 60.63 O ATOM 10240 CB THR B 252 -32.500 36.279 -52.771 1.00 59.46 C ATOM 10241 OG1 THR B 252 -32.437 37.550 -53.389 1.00 61.39 O ATOM 10242 CG2 THR B 252 -33.918 35.721 -52.996 1.00 60.91 C ATOM 10243 H THR B 252 -30.124 36.862 -52.004 1.00 58.19 H ATOM 10244 HA THR B 252 -32.735 37.124 -50.796 1.00 59.13 H ATOM 10245 HB THR B 252 -31.796 35.638 -53.301 1.00 59.46 H ATOM 10246 HG1 THR B 252 -31.517 37.834 -53.418 1.00 61.39 H ATOM 10247 HG21 THR B 252 -34.192 35.766 -54.051 1.00 60.91 H ATOM 10248 HG22 THR B 252 -33.998 34.676 -52.694 1.00 60.91 H ATOM 10249 HG23 THR B 252 -34.661 36.290 -52.436 1.00 60.91 H ATOM 10250 N ILE B 253 -31.226 34.155 -50.732 1.00 57.15 N ATOM 10251 CA ILE B 253 -31.237 32.817 -50.129 1.00 55.46 C ATOM 10252 C ILE B 253 -31.039 32.851 -48.594 1.00 54.97 C ATOM 10253 O ILE B 253 -31.676 32.061 -47.897 1.00 53.79 O ATOM 10254 CB ILE B 253 -30.195 31.874 -50.810 1.00 54.71 C ATOM 10255 CG1 ILE B 253 -30.577 31.636 -52.293 1.00 55.75 C ATOM 10256 CG2 ILE B 253 -29.997 30.518 -50.098 1.00 49.20 C ATOM 10257 CD1 ILE B 253 -29.499 30.937 -53.135 1.00 57.44 C ATOM 10258 H ILE B 253 -30.420 34.388 -51.296 1.00 57.15 H ATOM 10259 HA ILE B 253 -32.226 32.388 -50.307 1.00 55.46 H ATOM 10260 HB ILE B 253 -29.233 32.386 -50.797 1.00 54.71 H ATOM 10261 HG13 ILE B 253 -30.812 32.581 -52.781 1.00 55.75 H ATOM 10262 HG12 ILE B 253 -31.499 31.056 -52.335 1.00 55.75 H ATOM 10263 HG21 ILE B 253 -29.260 29.897 -50.607 1.00 49.20 H ATOM 10264 HG22 ILE B 253 -29.633 30.641 -49.081 1.00 49.20 H ATOM 10265 HG23 ILE B 253 -30.930 29.956 -50.050 1.00 49.20 H ATOM 10266 HD11 ILE B 253 -29.743 30.996 -54.196 1.00 57.44 H ATOM 10267 HD12 ILE B 253 -28.523 31.402 -52.999 1.00 57.44 H ATOM 10268 HD13 ILE B 253 -29.412 29.880 -52.886 1.00 57.44 H ATOM 10269 N LEU B 254 -30.222 33.796 -48.092 1.00 54.64 N ATOM 10270 CA LEU B 254 -30.038 34.066 -46.661 1.00 54.94 C ATOM 10271 C LEU B 254 -31.295 34.664 -45.999 1.00 56.13 C ATOM 10272 O LEU B 254 -31.527 34.381 -44.825 1.00 57.56 O ATOM 10273 CB LEU B 254 -28.818 34.988 -46.433 1.00 53.45 C ATOM 10274 CG LEU B 254 -27.435 34.327 -46.654 1.00 53.46 C ATOM 10275 CD1 LEU B 254 -26.325 35.375 -46.866 1.00 52.60 C ATOM 10276 CD2 LEU B 254 -27.049 33.344 -45.537 1.00 53.53 C ATOM 10277 H LEU B 254 -29.709 34.398 -48.724 1.00 54.64 H ATOM 10278 HA LEU B 254 -29.846 33.113 -46.173 1.00 54.94 H ATOM 10279 HB3 LEU B 254 -28.835 35.393 -45.419 1.00 53.45 H ATOM 10280 HB2 LEU B 254 -28.924 35.853 -47.091 1.00 53.45 H ATOM 10281 HG LEU B 254 -27.497 33.738 -47.568 1.00 53.46 H ATOM 10282 HD11 LEU B 254 -25.876 35.258 -47.851 1.00 52.60 H ATOM 10283 HD12 LEU B 254 -26.699 36.397 -46.799 1.00 52.60 H ATOM 10284 HD13 LEU B 254 -25.521 35.280 -46.135 1.00 52.60 H ATOM 10285 HD21 LEU B 254 -26.245 32.688 -45.872 1.00 53.53 H ATOM 10286 HD22 LEU B 254 -26.701 33.866 -44.645 1.00 53.53 H ATOM 10287 HD23 LEU B 254 -27.877 32.705 -45.243 1.00 53.53 H ATOM 10288 N SER B 255 -32.097 35.444 -46.752 0.50 55.94 N ATOM 10289 CA SER B 255 -33.379 35.986 -46.283 0.50 55.67 C ATOM 10290 C SER B 255 -34.488 34.917 -46.176 0.50 56.55 C ATOM 10291 O SER B 255 -35.391 35.084 -45.356 0.50 57.04 O ATOM 10292 CB SER B 255 -33.787 37.207 -47.141 0.50 55.50 C ATOM 10293 OG SER B 255 -34.458 36.871 -48.340 0.50 51.06 O ATOM 10294 H SER B 255 -31.842 35.649 -47.707 0.50 55.94 H ATOM 10295 HA SER B 255 -33.206 36.363 -45.273 0.50 55.67 H ATOM 10296 HB3 SER B 255 -32.923 37.831 -47.370 0.50 55.50 H ATOM 10297 HB2 SER B 255 -34.467 37.835 -46.565 0.50 55.50 H ATOM 10298 HG SER B 255 -33.884 36.316 -48.878 0.50 51.06 H ATOM 10299 N LYS B 256 -34.384 33.839 -46.977 1.00 57.63 N ATOM 10300 CA LYS B 256 -35.292 32.691 -46.961 1.00 58.28 C ATOM 10301 C LYS B 256 -35.024 31.686 -45.825 1.00 59.17 C ATOM 10302 O LYS B 256 -35.875 30.821 -45.620 1.00 58.69 O ATOM 10303 CB LYS B 256 -35.259 31.978 -48.329 1.00 59.05 C ATOM 10304 CG LYS B 256 -35.997 32.725 -49.447 1.00 61.64 C ATOM 10305 CD LYS B 256 -36.038 31.898 -50.739 1.00 65.49 C ATOM 10306 CE LYS B 256 -36.774 32.612 -51.881 1.00 67.29 C ATOM 10307 NZ LYS B 256 -36.917 31.738 -53.058 1.00 69.24 N1+ ATOM 10308 H LYS B 256 -33.612 33.780 -47.626 1.00 57.63 H ATOM 10309 HA LYS B 256 -36.305 33.066 -46.805 1.00 58.28 H ATOM 10310 HB3 LYS B 256 -35.744 31.005 -48.238 1.00 59.05 H ATOM 10311 HB2 LYS B 256 -34.231 31.771 -48.628 1.00 59.05 H ATOM 10312 HG3 LYS B 256 -35.524 33.687 -49.634 1.00 61.64 H ATOM 10313 HG2 LYS B 256 -37.016 32.943 -49.126 1.00 61.64 H ATOM 10314 HD3 LYS B 256 -36.513 30.937 -50.532 1.00 65.49 H ATOM 10315 HD2 LYS B 256 -35.016 31.669 -51.049 1.00 65.49 H ATOM 10316 HE3 LYS B 256 -36.234 33.515 -52.170 1.00 67.29 H ATOM 10317 HE2 LYS B 256 -37.770 32.920 -51.558 1.00 67.29 H ATOM 10318 HZ1 LYS B 256 -36.003 31.416 -53.352 1.00 69.24 H ATOM 10319 HZ2 LYS B 256 -37.475 30.933 -52.813 1.00 69.24 H ATOM 10320 HZ3 LYS B 256 -37.360 32.241 -53.813 1.00 69.24 H ATOM 10321 N MET B 257 -33.889 31.794 -45.104 1.00 60.31 N ATOM 10322 CA MET B 257 -33.583 30.942 -43.946 1.00 60.66 C ATOM 10323 C MET B 257 -34.615 31.112 -42.810 1.00 60.99 C ATOM 10324 O MET B 257 -35.092 32.231 -42.604 1.00 63.39 O ATOM 10325 CB MET B 257 -32.189 31.271 -43.373 1.00 60.82 C ATOM 10326 CG MET B 257 -31.016 30.838 -44.257 1.00 60.49 C ATOM 10327 SD MET B 257 -29.417 30.762 -43.394 1.00 60.55 S ATOM 10328 CE MET B 257 -29.288 32.438 -42.713 1.00 61.27 C ATOM 10329 H MET B 257 -33.226 32.526 -45.317 1.00 60.31 H ATOM 10330 HA MET B 257 -33.589 29.918 -44.319 1.00 60.66 H ATOM 10331 HB3 MET B 257 -32.066 30.790 -42.401 1.00 60.82 H ATOM 10332 HB2 MET B 257 -32.124 32.342 -43.177 1.00 60.82 H ATOM 10333 HG3 MET B 257 -30.934 31.494 -45.121 1.00 60.49 H ATOM 10334 HG2 MET B 257 -31.213 29.842 -44.649 1.00 60.49 H ATOM 10335 HE1 MET B 257 -28.306 32.583 -42.264 1.00 61.27 H ATOM 10336 HE2 MET B 257 -29.425 33.185 -43.494 1.00 61.27 H ATOM 10337 HE3 MET B 257 -30.041 32.599 -41.942 1.00 61.27 H ATOM 10338 N PRO B 258 -34.909 30.018 -42.067 1.00 60.93 N ATOM 10339 CA PRO B 258 -35.762 30.097 -40.870 1.00 62.63 C ATOM 10340 C PRO B 258 -35.113 30.946 -39.761 1.00 65.46 C ATOM 10341 O PRO B 258 -33.937 30.753 -39.449 1.00 64.82 O ATOM 10342 CB PRO B 258 -35.947 28.629 -40.464 1.00 61.98 C ATOM 10343 CG PRO B 258 -34.707 27.915 -40.976 1.00 60.80 C ATOM 10344 CD PRO B 258 -34.384 28.662 -42.263 1.00 60.23 C ATOM 10345 HA PRO B 258 -36.733 30.523 -41.133 1.00 62.63 H ATOM 10346 HB3 PRO B 258 -36.824 28.232 -40.969 1.00 61.98 H ATOM 10347 HB2 PRO B 258 -36.112 28.488 -39.397 1.00 61.98 H ATOM 10348 HG3 PRO B 258 -34.861 26.848 -41.128 1.00 60.80 H ATOM 10349 HG2 PRO B 258 -33.888 28.039 -40.267 1.00 60.80 H ATOM 10350 HD2 PRO B 258 -33.312 28.633 -42.459 1.00 60.23 H ATOM 10351 HD3 PRO B 258 -34.900 28.206 -43.109 1.00 60.23 H ATOM 10352 N LYS B 259 -35.888 31.904 -39.233 1.00 68.99 N ATOM 10353 CA LYS B 259 -35.450 32.848 -38.207 1.00 71.53 C ATOM 10354 C LYS B 259 -35.665 32.268 -36.792 1.00 72.27 C ATOM 10355 O LYS B 259 -36.624 31.517 -36.596 1.00 71.59 O ATOM 10356 CB LYS B 259 -36.238 34.161 -38.387 1.00 72.97 C ATOM 10357 CG LYS B 259 -35.869 34.905 -39.683 0.00 72.00 C ATOM 10358 CD LYS B 259 -36.604 36.244 -39.830 0.00 72.14 C ATOM 10359 CE LYS B 259 -36.221 36.975 -41.127 0.00 72.10 C ATOM 10360 NZ LYS B 259 -36.929 38.261 -41.259 0.00 72.05 N1+ ATOM 10361 H LYS B 259 -36.842 32.002 -39.547 1.00 68.99 H ATOM 10362 HA LYS B 259 -34.393 33.050 -38.383 1.00 71.53 H ATOM 10363 HB3 LYS B 259 -36.033 34.824 -37.545 1.00 72.97 H ATOM 10364 HB2 LYS B 259 -37.311 33.964 -38.359 1.00 72.97 H ATOM 10365 HG3 LYS B 259 -36.093 34.278 -40.546 1.00 72.00 H ATOM 10366 HG2 LYS B 259 -34.793 35.079 -39.705 1.00 72.00 H ATOM 10367 HD3 LYS B 259 -36.378 36.873 -38.967 1.00 72.14 H ATOM 10368 HD2 LYS B 259 -37.680 36.065 -39.807 1.00 72.14 H ATOM 10369 HE3 LYS B 259 -36.456 36.356 -41.994 1.00 72.10 H ATOM 10370 HE2 LYS B 259 -35.147 37.165 -41.150 1.00 72.10 H ATOM 10371 HZ1 LYS B 259 -36.696 38.858 -40.478 1.00 72.05 H ATOM 10372 HZ2 LYS B 259 -36.652 38.711 -42.120 1.00 72.05 H ATOM 10373 HZ3 LYS B 259 -37.926 38.098 -41.273 1.00 72.05 H ATOM 10374 N PRO B 260 -34.784 32.626 -35.828 1.00 74.67 N ATOM 10375 CA PRO B 260 -34.926 32.213 -34.418 1.00 76.77 C ATOM 10376 C PRO B 260 -36.155 32.848 -33.745 1.00 78.60 C ATOM 10377 O PRO B 260 -36.401 34.041 -33.934 1.00 79.73 O ATOM 10378 CB PRO B 260 -33.628 32.716 -33.763 1.00 76.17 C ATOM 10379 CG PRO B 260 -33.216 33.913 -34.599 1.00 76.76 C ATOM 10380 CD PRO B 260 -33.628 33.509 -36.006 1.00 75.85 C ATOM 10381 HA PRO B 260 -34.986 31.125 -34.342 1.00 76.77 H ATOM 10382 HB3 PRO B 260 -32.862 31.945 -33.825 1.00 76.17 H ATOM 10383 HB2 PRO B 260 -33.736 32.973 -32.708 1.00 76.17 H ATOM 10384 HG3 PRO B 260 -32.160 34.152 -34.522 1.00 76.76 H ATOM 10385 HG2 PRO B 260 -33.781 34.792 -34.286 1.00 76.76 H ATOM 10386 HD2 PRO B 260 -33.841 34.394 -36.607 1.00 75.85 H ATOM 10387 HD3 PRO B 260 -32.833 32.943 -36.492 1.00 75.85 H ATOM 10388 N LYS B 261 -36.890 32.045 -32.959 1.00 80.34 N ATOM 10389 CA LYS B 261 -37.982 32.532 -32.118 1.00 81.58 C ATOM 10390 C LYS B 261 -37.381 33.268 -30.897 1.00 82.01 C ATOM 10391 O LYS B 261 -36.554 32.668 -30.208 1.00 80.24 O ATOM 10392 CB LYS B 261 -38.842 31.330 -31.675 1.00 81.58 C ATOM 10393 CG LYS B 261 -40.126 31.743 -30.928 1.00 83.77 C ATOM 10394 CD LYS B 261 -40.979 30.559 -30.450 1.00 86.26 C ATOM 10395 CE LYS B 261 -41.631 29.754 -31.588 1.00 87.34 C ATOM 10396 NZ LYS B 261 -42.417 28.622 -31.067 1.00 88.20 N1+ ATOM 10397 H LYS B 261 -36.630 31.074 -32.834 1.00 80.34 H ATOM 10398 HA LYS B 261 -38.602 33.176 -32.739 1.00 81.58 H ATOM 10399 HB3 LYS B 261 -38.258 30.660 -31.042 1.00 81.58 H ATOM 10400 HB2 LYS B 261 -39.113 30.755 -32.560 1.00 81.58 H ATOM 10401 HG3 LYS B 261 -40.729 32.393 -31.564 1.00 83.77 H ATOM 10402 HG2 LYS B 261 -39.867 32.340 -30.053 1.00 83.77 H ATOM 10403 HD3 LYS B 261 -41.750 30.936 -29.777 1.00 86.26 H ATOM 10404 HD2 LYS B 261 -40.350 29.908 -29.845 1.00 86.26 H ATOM 10405 HE3 LYS B 261 -40.877 29.353 -32.264 1.00 87.34 H ATOM 10406 HE2 LYS B 261 -42.287 30.397 -32.176 1.00 87.34 H ATOM 10407 HZ1 LYS B 261 -43.124 28.956 -30.429 1.00 88.20 H ATOM 10408 HZ2 LYS B 261 -42.850 28.127 -31.832 1.00 88.20 H ATOM 10409 HZ3 LYS B 261 -41.788 27.994 -30.579 1.00 88.20 H ATOM 10410 N PRO B 262 -37.778 34.539 -30.652 1.00 83.94 N ATOM 10411 CA PRO B 262 -37.268 35.306 -29.499 1.00 84.95 C ATOM 10412 C PRO B 262 -37.815 34.789 -28.146 1.00 85.81 C ATOM 10413 O PRO B 262 -38.798 34.043 -28.139 1.00 85.26 O ATOM 10414 CB PRO B 262 -37.750 36.736 -29.805 1.00 85.26 C ATOM 10415 CG PRO B 262 -39.042 36.549 -30.580 1.00 84.83 C ATOM 10416 CD PRO B 262 -38.758 35.311 -31.421 1.00 84.67 C ATOM 10417 HA PRO B 262 -36.177 35.271 -29.492 1.00 84.95 H ATOM 10418 HB3 PRO B 262 -37.013 37.237 -30.434 1.00 85.26 H ATOM 10419 HB2 PRO B 262 -37.895 37.357 -28.919 1.00 85.26 H ATOM 10420 HG3 PRO B 262 -39.327 37.419 -31.172 1.00 84.83 H ATOM 10421 HG2 PRO B 262 -39.854 36.337 -29.883 1.00 84.83 H ATOM 10422 HD2 PRO B 262 -39.680 34.763 -31.614 1.00 84.67 H ATOM 10423 HD3 PRO B 262 -38.311 35.592 -32.376 1.00 84.67 H ATOM 10424 N PRO B 263 -37.197 35.213 -27.019 1.00 88.02 N ATOM 10425 CA PRO B 263 -37.687 34.841 -25.679 1.00 89.69 C ATOM 10426 C PRO B 263 -39.024 35.533 -25.302 1.00 90.91 C ATOM 10427 O PRO B 263 -39.376 36.529 -25.937 1.00 90.53 O ATOM 10428 CB PRO B 263 -36.530 35.261 -24.756 1.00 89.94 C ATOM 10429 CG PRO B 263 -35.858 36.417 -25.481 1.00 89.77 C ATOM 10430 CD PRO B 263 -35.975 36.017 -26.947 1.00 88.68 C ATOM 10431 HA PRO B 263 -37.801 33.760 -25.667 1.00 89.69 H ATOM 10432 HB3 PRO B 263 -35.827 34.432 -24.662 1.00 89.94 H ATOM 10433 HB2 PRO B 263 -36.845 35.534 -23.748 1.00 89.94 H ATOM 10434 HG3 PRO B 263 -34.830 36.595 -25.163 1.00 89.77 H ATOM 10435 HG2 PRO B 263 -36.426 37.332 -25.308 1.00 89.77 H ATOM 10436 HD2 PRO B 263 -35.989 36.895 -27.592 1.00 88.68 H ATOM 10437 HD3 PRO B 263 -35.129 35.393 -27.239 1.00 88.68 H ATOM 10438 N PRO B 264 -39.741 35.016 -24.272 1.00 92.52 N ATOM 10439 CA PRO B 264 -41.034 35.583 -23.837 1.00 93.06 C ATOM 10440 C PRO B 264 -40.940 37.006 -23.254 1.00 92.90 C ATOM 10441 O PRO B 264 -41.684 37.881 -23.693 1.00 92.66 O ATOM 10442 CB PRO B 264 -41.572 34.571 -22.803 1.00 93.09 C ATOM 10443 CG PRO B 264 -40.788 33.294 -23.048 0.00 92.68 C ATOM 10444 CD PRO B 264 -39.434 33.805 -23.514 0.00 92.40 C ATOM 10445 HA PRO B 264 -41.697 35.591 -24.704 1.00 93.06 H ATOM 10446 HB3 PRO B 264 -42.647 34.411 -22.900 1.00 93.09 H ATOM 10447 HB2 PRO B 264 -41.389 34.907 -21.782 1.00 93.09 H ATOM 10448 HG3 PRO B 264 -41.256 32.732 -23.858 1.00 92.68 H ATOM 10449 HG2 PRO B 264 -40.731 32.641 -22.177 1.00 92.68 H ATOM 10450 HD2 PRO B 264 -38.798 34.064 -22.666 1.00 92.40 H ATOM 10451 HD3 PRO B 264 -38.940 33.031 -24.091 1.00 92.40 H HETATM10452 N NME B 265 -40.026 37.206 -22.292 1.00 0.00 N HETATM10453 C NME B 265 -39.847 38.486 -21.624 1.00 0.00 C HETATM10454 H NME B 265 -39.447 36.438 -21.986 1.00 0.00 H HETATM10455 H1 NME B 265 -39.565 39.261 -22.337 1.00 0.00 H HETATM10456 H2 NME B 265 -40.766 38.792 -21.122 1.00 0.00 H HETATM10457 H3 NME B 265 -39.060 38.408 -20.875 1.00 0.00 H END ================================================ FILE: src/openfe/tests/data/eg5/__init__.py ================================================ ================================================ FILE: src/openfe/tests/data/eg5/eg5_cofactor.sdf ================================================ 3L9H 3D Schrodinger Suite 2021-1. 39 41 0 0 1 0 999 V2000 17.7103 1.3810 16.7258 P 0 0 0 0 0 0 16.2918 1.9380 16.9415 O 0 0 0 0 0 0 17.7048 -0.1381 16.4765 O 0 5 0 0 0 0 18.4945 2.1622 15.6604 O 0 5 0 0 0 0 20.1704 1.9553 18.6598 P 0 0 0 0 0 0 21.0614 1.4768 17.5414 O 0 0 0 0 0 0 20.2345 3.3559 19.2252 O 0 5 0 0 0 0 18.5522 1.6400 18.2257 O 0 0 0 0 0 0 20.3327 0.8377 19.9634 O 0 0 0 0 0 0 19.5869 1.0879 21.1452 C 0 0 0 0 0 0 20.4613 1.1653 22.4074 C 0 0 1 0 0 0 21.0911 -0.0950 22.5958 O 0 0 0 0 0 0 21.6078 2.1760 22.3912 C 0 0 1 0 0 0 21.7761 2.7834 23.6633 O 0 0 0 0 0 0 22.8150 1.3580 21.9342 C 0 0 1 0 0 0 24.0771 1.7580 22.4399 O 0 0 0 0 0 0 22.4830 -0.0283 22.4899 C 0 0 2 0 0 0 22.9954 -1.1724 21.6426 N 0 0 0 0 0 0 22.4947 -1.6440 20.4842 C 0 0 0 0 0 0 23.2096 -2.5994 19.9459 N 0 0 0 0 0 0 24.2457 -2.7439 20.7874 C 0 0 0 0 0 0 25.3696 -3.6002 20.7533 C 0 0 0 0 0 0 25.5873 -4.5319 19.7432 N 0 0 0 0 0 0 26.2748 -3.5190 21.7663 N 0 0 0 0 0 0 26.0465 -2.6305 22.7424 C 0 0 0 0 0 0 25.0272 -1.7702 22.8844 N 0 0 0 0 0 0 24.1457 -1.8743 21.8585 C 0 0 0 0 0 0 18.9006 0.2596 21.2825 H 0 0 0 0 0 0 18.9668 1.9826 21.0671 H 0 0 0 0 0 0 19.7967 1.3439 23.2547 H 0 0 0 0 0 0 21.4113 2.9719 21.6708 H 0 0 0 0 0 0 22.6054 3.2689 23.6516 H 0 0 0 0 0 0 22.8340 1.3030 20.8442 H 0 0 0 0 0 0 24.3615 2.5656 21.9940 H 0 0 0 0 0 0 22.8770 -0.1608 23.5002 H 0 0 0 0 0 0 21.5746 -1.2447 20.0891 H 0 0 0 0 0 0 26.3917 -5.1389 19.8129 H 0 0 0 0 0 0 24.9075 -4.6313 19.0027 H 0 0 0 0 0 0 26.7890 -2.6030 23.5264 H 0 0 0 0 0 0 1 2 2 0 0 0 1 3 1 0 0 0 1 4 1 0 0 0 1 8 1 0 0 0 5 6 2 0 0 0 5 7 1 0 0 0 5 8 1 0 0 0 5 9 1 0 0 0 9 10 1 0 0 0 10 11 1 0 0 0 10 28 1 0 0 0 10 29 1 0 0 0 11 12 1 0 0 0 11 13 1 0 0 0 11 30 1 0 0 0 12 17 1 0 0 0 13 14 1 0 0 0 13 15 1 0 0 0 13 31 1 0 0 0 14 32 1 0 0 0 15 16 1 0 0 0 15 17 1 0 0 0 15 33 1 0 0 0 16 34 1 0 0 0 17 18 1 0 0 0 17 35 1 0 0 0 18 19 1 0 0 0 18 27 1 0 0 0 19 20 2 0 0 0 19 36 1 0 0 0 20 21 1 0 0 0 21 22 1 0 0 0 21 27 2 0 0 0 22 23 1 0 0 0 22 24 2 0 0 0 23 37 1 0 0 0 23 38 1 0 0 0 24 25 1 0 0 0 25 26 2 0 0 0 25 39 1 0 0 0 26 27 1 0 0 0 M CHG 3 3 -1 4 -1 7 -1 M END $$$$ ================================================ FILE: src/openfe/tests/data/eg5/eg5_ligands.sdf ================================================ lig_CHEMBL1078691 3D Schrodinger Suite 2022-3. 52 55 0 0 1 0 999 V2000 35.1506 6.9961 16.0497 H 0 0 0 0 0 0 34.3743 7.0705 16.5998 O 0 0 0 0 0 0 33.2046 7.3830 15.9898 C 0 0 0 0 0 0 32.0447 6.9520 16.6533 C 0 0 0 0 0 0 32.1282 6.3166 17.5227 H 0 0 0 0 0 0 30.7825 7.3762 16.2356 C 0 0 0 0 0 0 29.9005 7.0576 16.7698 H 0 0 0 0 0 0 30.6855 8.2450 15.1420 C 0 0 0 0 0 0 29.3301 8.7627 14.7491 C 0 0 2 0 0 0 28.5854 8.3128 15.4086 H 0 0 0 0 0 0 29.0334 8.2926 13.4113 N 0 0 0 0 0 0 29.1849 7.3041 13.2524 H 0 0 0 0 0 0 28.0015 8.9176 12.7152 C 0 0 0 0 0 0 27.6064 8.3593 11.4896 C 0 0 0 0 0 0 28.0744 7.4593 11.1200 H 0 0 0 0 0 0 26.6215 8.9895 10.7190 C 0 0 0 0 0 0 26.3839 8.5619 9.7591 H 0 0 0 0 0 0 25.9919 10.1712 11.1752 C 0 0 0 0 0 0 24.9721 10.8852 10.2862 C 0 0 0 0 0 0 25.7685 11.7006 9.2629 C 0 0 0 0 0 0 25.1850 12.2615 8.5441 H 0 0 0 0 0 0 26.4154 11.0282 8.7187 H 0 0 0 0 0 0 26.3849 12.4375 9.7712 H 0 0 0 0 0 0 24.0760 11.8274 11.0884 C 0 0 0 0 0 0 24.6975 12.5884 11.5194 H 0 0 0 0 0 0 23.5851 11.3401 11.9242 H 0 0 0 0 0 0 23.3168 12.3089 10.4711 H 0 0 0 0 0 0 24.0346 9.8607 9.6499 C 0 0 0 0 0 0 23.1879 10.2624 9.1189 H 0 0 0 0 0 0 23.5850 9.3883 10.5023 H 0 0 0 0 0 0 24.5077 9.1197 9.0090 H 0 0 0 0 0 0 26.3813 10.7069 12.4232 C 0 0 0 0 0 0 25.9589 11.6155 12.8183 H 0 0 0 0 0 0 27.3886 10.1014 13.1842 C 0 0 0 0 0 0 27.8259 10.7731 14.4732 C 0 0 1 0 0 0 27.8533 11.8496 14.2952 H 0 0 0 0 0 0 26.8794 10.5164 15.5097 O 0 0 0 0 0 0 27.1625 11.1892 16.7294 C 0 0 0 0 0 0 27.1951 12.2677 16.5678 H 0 0 0 0 0 0 26.3524 10.9946 17.4323 H 0 0 0 0 0 0 28.4911 10.6767 17.2983 C 0 0 0 0 0 0 28.7333 11.1954 18.2261 H 0 0 0 0 0 0 28.4005 9.6180 17.5453 H 0 0 0 0 0 0 29.6124 10.8762 16.2710 C 0 0 0 0 0 0 29.8008 11.9464 16.1678 H 0 0 0 0 0 0 30.5418 10.4474 16.6445 H 0 0 0 0 0 0 29.2323 10.3026 14.8842 C 0 0 1 0 0 0 29.9366 10.7258 14.1662 H 0 0 0 0 0 0 31.8413 8.6247 14.4221 C 0 0 0 0 0 0 31.7566 9.2763 13.5652 H 0 0 0 0 0 0 33.1113 8.1894 14.8427 C 0 0 0 0 0 0 33.9873 8.5296 14.3176 H 0 0 0 0 0 0 1 2 1 0 0 0 2 3 1 0 0 0 3 51 1 0 0 0 3 4 2 0 0 0 4 5 1 0 0 0 4 6 1 0 0 0 6 7 1 0 0 0 6 8 2 0 0 0 8 9 1 0 0 0 8 49 1 0 0 0 9 47 1 0 0 0 9 10 1 0 0 0 9 11 1 0 0 0 11 12 1 0 0 0 11 13 1 0 0 0 13 34 1 0 0 0 13 14 2 0 0 0 14 15 1 0 0 0 14 16 1 0 0 0 16 17 1 0 0 0 16 18 2 0 0 0 18 19 1 0 0 0 18 32 1 0 0 0 19 20 1 0 0 0 19 24 1 0 0 0 19 28 1 0 0 0 20 21 1 0 0 0 20 22 1 0 0 0 20 23 1 0 0 0 24 25 1 0 0 0 24 26 1 0 0 0 24 27 1 0 0 0 28 29 1 0 0 0 28 30 1 0 0 0 28 31 1 0 0 0 32 33 1 0 0 0 32 34 2 0 0 0 34 35 1 0 0 0 35 47 1 0 0 0 35 36 1 0 0 0 35 37 1 0 0 0 37 38 1 0 0 0 38 39 1 0 0 0 38 40 1 0 0 0 38 41 1 0 0 0 41 42 1 0 0 0 41 43 1 0 0 0 41 44 1 0 0 0 44 45 1 0 0 0 44 46 1 0 0 0 44 47 1 0 0 0 47 48 1 0 0 0 49 50 1 0 0 0 49 51 2 0 0 0 51 52 1 0 0 0 M END > ligprep_eg5.smi > 3 > 53161 > 0 > W09IXWMxW2NIXVtjSF1jKFtjSF1bY0hdMSlbQ0BIXShbTkhdMilbQ0BIXShbQ0gyXVtDSDJdW0NIMl1PMylbQ0BIXTNjKGMyNClbY0hdYyhbY0hdW2NIXTQpQyhbQ0gzXSkoW0NIM10pW0NIM10= > J2VwaWtfcHl0aG9uJywgJy1waHQnLCAnMC4wJywgJy1waCcsICc3LjQnLCAnLXRuJywgJzgnLCAnLW1hJywgJzUwMCcsICctaW1hZScsICc8aW5maWxlLm1hZT4nLCAnLW9tYWUnLCAnPG91dGZpbGUubWFlPic= > 1 > 0.0010 > 0.0000 > 0.0010 > -0.0000 > 0 > 0 > 0 > S-OPLS > 34.1252 > 1 > lig_CHEMBL1078691-1 > glide-grid_EG5-3L9H > 3 > 3 > -8.97665928402366 > -0.359066371360946 > -1.04991643792862 > -2.12773725908467 > -8.97665928402366 > -5.06383813021649 > -0.431309273878793 > -0 > -1.28824924773551 > -34.2456703186035 > -6.52582502365112 > 0.49789463728498 > 0 > -51.6245432573516 > -40.7714953422546 > 1.23162662982941 > 2 > 1 > -0 > 0.0779755402671082 > snapped_core_restrain $$$$ lig_CHEMBL1078774 3D Schrodinger Suite 2022-3. 52 55 0 0 1 0 999 V2000 35.1317 7.1361 15.9189 H 0 0 0 0 0 0 34.3769 7.1037 16.4998 O 0 0 0 0 0 0 33.1652 7.3943 15.9602 C 0 0 0 0 0 0 32.0523 6.9447 16.6649 C 0 0 0 0 0 0 32.1848 6.2954 17.5273 H 0 0 0 0 0 0 30.7676 7.3612 16.2917 C 0 0 0 0 0 0 29.9132 7.0126 16.8534 H 0 0 0 0 0 0 30.6110 8.2402 15.2132 C 0 0 0 0 0 0 29.2527 8.7515 14.8401 C 0 0 2 0 0 0 28.5177 8.3167 15.5212 H 0 0 0 0 0 0 28.9515 8.2587 13.5087 N 0 0 0 0 0 0 29.1186 7.2738 13.3365 H 0 0 0 0 0 0 27.9696 8.9051 12.7651 C 0 0 0 0 0 0 27.6156 8.3613 11.5183 C 0 0 0 0 0 0 28.0902 7.4551 11.1617 H 0 0 0 0 0 0 26.6584 8.9961 10.7199 C 0 0 0 0 0 0 26.4477 8.5667 9.7540 H 0 0 0 0 0 0 26.0117 10.1756 11.1654 C 0 0 0 0 0 0 24.9931 10.8765 10.2682 C 0 0 0 0 0 0 25.7815 11.7127 9.2589 C 0 0 0 0 0 0 25.1851 12.2654 8.5382 H 0 0 0 0 0 0 26.4421 11.0483 8.7182 H 0 0 0 0 0 0 26.3857 12.4520 9.7704 H 0 0 0 0 0 0 24.0600 11.7945 11.0720 C 0 0 0 0 0 0 24.6348 12.5868 11.5261 H 0 0 0 0 0 0 23.5850 11.2763 11.8923 H 0 0 0 0 0 0 23.2851 12.2360 10.4513 H 0 0 0 0 0 0 24.0847 9.8280 9.6200 C 0 0 0 0 0 0 23.2374 10.1884 9.0655 H 0 0 0 0 0 0 23.5965 9.3881 10.4568 H 0 0 0 0 0 0 24.5681 9.0774 9.0037 H 0 0 0 0 0 0 26.3762 10.7143 12.4168 C 0 0 0 0 0 0 25.9463 11.6243 12.7961 H 0 0 0 0 0 0 27.3553 10.1016 13.2063 C 0 0 0 0 0 0 27.7772 10.7805 14.4987 C 0 0 1 0 0 0 27.8208 11.8547 14.3064 H 0 0 0 0 0 0 26.8226 10.5519 15.5345 O 0 0 0 0 0 0 27.1192 11.2365 16.7459 C 0 0 0 0 0 0 27.1635 12.3123 16.5691 H 0 0 0 0 0 0 26.3120 11.0645 17.4581 H 0 0 0 0 0 0 28.4479 10.7181 17.3127 C 0 0 0 0 0 0 28.6956 11.2441 18.2357 H 0 0 0 0 0 0 28.3556 9.6619 17.5676 H 0 0 0 0 0 0 29.5640 10.9118 16.2829 C 0 0 0 0 0 0 29.7348 11.9812 16.1491 H 0 0 0 0 0 0 30.5011 10.5045 16.6567 H 0 0 0 0 0 0 29.1753 10.2968 14.9230 C 0 0 1 0 0 0 29.8748 10.6986 14.1896 H 0 0 0 0 0 0 31.7232 8.6610 14.4697 C 0 0 0 0 0 0 31.6100 9.3232 13.6206 H 0 0 0 0 0 0 32.9883 8.2352 14.8420 C 0 0 0 0 0 0 33.9851 8.7065 14.1028 F 0 0 0 0 0 0 1 2 1 0 0 0 2 3 1 0 0 0 3 51 1 0 0 0 3 4 2 0 0 0 4 5 1 0 0 0 4 6 1 0 0 0 6 7 1 0 0 0 6 8 2 0 0 0 8 9 1 0 0 0 8 49 1 0 0 0 9 47 1 0 0 0 9 10 1 0 0 0 9 11 1 0 0 0 11 12 1 0 0 0 11 13 1 0 0 0 13 34 1 0 0 0 13 14 2 0 0 0 14 15 1 0 0 0 14 16 1 0 0 0 16 17 1 0 0 0 16 18 2 0 0 0 18 19 1 0 0 0 18 32 1 0 0 0 19 20 1 0 0 0 19 24 1 0 0 0 19 28 1 0 0 0 20 21 1 0 0 0 20 22 1 0 0 0 20 23 1 0 0 0 24 25 1 0 0 0 24 26 1 0 0 0 24 27 1 0 0 0 28 29 1 0 0 0 28 30 1 0 0 0 28 31 1 0 0 0 32 33 1 0 0 0 32 34 2 0 0 0 34 35 1 0 0 0 35 47 1 0 0 0 35 36 1 0 0 0 35 37 1 0 0 0 37 38 1 0 0 0 38 39 1 0 0 0 38 40 1 0 0 0 38 41 1 0 0 0 41 42 1 0 0 0 41 43 1 0 0 0 41 44 1 0 0 0 44 45 1 0 0 0 44 46 1 0 0 0 44 47 1 0 0 0 47 48 1 0 0 0 49 50 1 0 0 0 49 51 2 0 0 0 51 52 1 0 0 0 M END > ligprep_eg5.smi > 4 > 53161 > 0 > W09IXWMxW2NIXVtjSF1jKFtjSF1jMUYpW0NASF0oW05IXTIpW0NASF0oW0NIMl1bQ0gyXVtDSDJdTzMpW0NASF0zYyhjMjQpW2NIXWMoW2NIXVtjSF00KUMoW0NIM10pKFtDSDNdKVtDSDNd > J2VwaWtfcHl0aG9uJywgJy1waHQnLCAnMC4wJywgJy1waCcsICc3LjQnLCAnLXRuJywgJzgnLCAnLW1hJywgJzUwMCcsICctaW1hZScsICc8aW5maWxlLm1hZT4nLCAnLW9tYWUnLCAnPG91dGZpbGUubWFlPic= > 1 > 0.0129 > 0.0000 > 0.0129 > -0.0000 > 0 > 0 > 0 > S-OPLS > 40.6678 > 1 > lig_CHEMBL1078774-1 > glide-grid_EG5-3L9H > 4 > 3 > -8.97337207022735 > -0.345129695008744 > -1.02244536344363 > -2.10736698665757 > -8.97337207022735 > -5.06032647734131 > -0.454813574920432 > -0 > -1.37207791070462 > -31.0318450927734 > -6.59056234359741 > 0.454022498917303 > 0 > -53.833901517828 > -37.6224074363708 > 1.32856965065002 > 11 > 3 > -0 > 0.0977424974958633 > snapped_core_restrain ================================================ FILE: src/openfe/tests/data/eg5/eg5_protein.pdb ================================================ HEADER MOTOR PROTEIN 05-JAN-10 3L9H TITLE X-RAY STRUCTURE OF MITOTIC KINESIN-5 (KSP, KIF11, EG5)IN TITLE 2 COMPLEX WITH THE HEXAHYDRO-2H-PYRANO[3,2-C]QUINOLINE EMD TITLE 3 534085 EXPDTA X-RAY DIFFRACTION REMARK 2 RESOLUTION. 2.00 ANGSTROMS REMARK 3 R VALUE : 0.234000 REMARK 3 FREE R VALUE : 0.258000 REMARK 4 3L9H COMPLIES WITH FORMAT V. 3.20, 01-DEC-08 REMARK 200 TEMPERATURE (KELVIN) : 100.00 REMARK 200 PH : 7.00 REMARK 350 BIOMOLECULE: 1 REMARK 350 APPLY THE FOLLOWING TO CHAINS: A REMARK 350 BIOMT1 1 1.000000 0.000000 0.000000 0.000000 REMARK 350 BIOMT2 1 0.000000 1.000000 0.000000 0.000000 REMARK 350 BIOMT3 1 0.000000 0.000000 1.000000 0.000000 REMARK 350 BIOMOLECULE: 2 REMARK 350 APPLY THE FOLLOWING TO CHAINS: B REMARK 350 BIOMT1 1 1.000000 0.000000 0.000000 0.000000 REMARK 350 BIOMT2 1 0.000000 1.000000 0.000000 0.000000 REMARK 350 BIOMT3 1 0.000000 0.000000 1.000000 0.000000 REMARK 888 REMARK 888 WRITTEN BY MAESTRO (A PRODUCT OF SCHRODINGER, LLC) SEQRES 1 A 349 ACE GLY LYS ASN ILE GLN VAL VAL VAL ARG CYS ARG PRO SEQRES 2 A 349 PHE ASN LEU ALA GLU ARG LYS ALA SER ALA HIS SER ILE SEQRES 3 A 349 VAL GLU CYS ASP PRO VAL ARG LYS GLU VAL SER VAL ARG SEQRES 4 A 349 THR GLY GLY LEU ALA ASP LYS SER SER ARG LYS THR TYR SEQRES 5 A 349 THR PHE ASP MET VAL PHE GLY ALA SER THR LYS GLN ILE SEQRES 6 A 349 ASP VAL TYR ARG SER VAL VAL CYS PRO ILE LEU ASP GLU SEQRES 7 A 349 VAL ILE MET GLY TYR ASN CYS THR ILE PHE ALA TYR GLY SEQRES 8 A 349 GLN THR GLY THR GLY LYS THR PHE THR MET GLU GLY GLU SEQRES 9 A 349 ARG SER PRO ASN GLU GLU TYR THR TRP GLU GLU ASP PRO SEQRES 10 A 349 LEU ALA GLY ILE ILE PRO ARG THR LEU HIS GLN ILE PHE SEQRES 11 A 349 GLU LYS LEU THR ASP ASN GLY THR GLU PHE SER VAL LYS SEQRES 12 A 349 VAL SER LEU LEU GLU ILE TYR ASN GLU GLU LEU PHE ASP SEQRES 13 A 349 LEU LEU ASN PRO SER SER ASP VAL SER GLU ARG LEU GLN SEQRES 14 A 349 MET PHE ASP ASP PRO ARG ASN LYS ARG GLY VAL ILE ILE SEQRES 15 A 349 LYS GLY LEU GLU GLU ILE THR VAL HIS ASN LYS ASP GLU SEQRES 16 A 349 VAL TYR GLN ILE LEU GLU LYS GLY ALA ALA LYS ARG THR SEQRES 17 A 349 THR ALA ALA THR LEU MET ASN ALA TYR SER SER ARG SER SEQRES 18 A 349 HIS SER VAL PHE SER VAL THR ILE HIS MET LYS GLU THR SEQRES 19 A 349 THR ILE ASP GLY GLU GLU LEU VAL LYS ILE GLY LYS LEU SEQRES 20 A 349 ASN LEU VAL ASP LEU ALA GLY SER GLU ASN ILE GLY ARG SEQRES 21 A 349 SER GLY ALA VAL ASP LYS ARG ALA ARG GLU ALA GLY ASN SEQRES 22 A 349 ILE ASN GLN SER LEU LEU THR LEU GLY ARG VAL ILE THR SEQRES 23 A 349 ALA LEU VAL GLU ARG THR PRO HIS VAL PRO TYR ARG GLU SEQRES 24 A 349 SER LYS LEU THR ARG ILE LEU GLN ASP SER LEU GLY GLY SEQRES 25 A 349 ARG THR ARG THR SER ILE ILE ALA THR ILE SER PRO ALA SEQRES 26 A 349 SER LEU ASN LEU GLU GLU THR LEU SER THR LEU GLU TYR SEQRES 27 A 349 ALA HIS ARG ALA LYS ASN ILE LEU ASN LYS NME FORMUL 2 HOH *7(H2 0) HELIX 1 1 LEU A 30 LEU A 30 1 HELIX 2 2 ALA A 31 ALA A 31 1 HELIX 3 3 GLU A 32 GLU A 32 1 HELIX 4 4 ARG A 33 ARG A 33 1 HELIX 5 5 GLN A 78 GLN A 78 1 HELIX 6 6 ILE A 79 ILE A 79 1 HELIX 7 7 ASP A 80 ASP A 80 1 HELIX 8 8 VAL A 81 VAL A 81 1 HELIX 9 9 TYR A 82 TYR A 82 1 HELIX 10 10 ARG A 83 ARG A 83 1 HELIX 11 11 SER A 84 SER A 84 1 HELIX 12 12 CYS A 87 CYS A 87 1 HELIX 13 13 PRO A 88 PRO A 88 1 HELIX 14 14 ILE A 89 ILE A 89 1 HELIX 15 15 LEU A 90 LEU A 90 1 HELIX 16 16 ASP A 91 ASP A 91 1 HELIX 17 17 GLU A 92 GLU A 92 1 HELIX 18 18 VAL A 93 VAL A 93 1 HELIX 19 19 ILE A 94 ILE A 94 1 HELIX 20 20 LYS A 111 LYS A 111 1 HELIX 21 21 THR A 112 THR A 112 1 HELIX 22 22 PHE A 113 PHE A 113 1 HELIX 23 23 THR A 114 THR A 114 1 HELIX 24 24 MET A 115 MET A 115 1 HELIX 25 25 ILE A 136 ILE A 136 1 HELIX 26 26 PRO A 137 PRO A 137 1 HELIX 27 27 ARG A 138 ARG A 138 1 HELIX 28 28 THR A 139 THR A 139 1 HELIX 29 29 LEU A 140 LEU A 140 1 HELIX 30 30 HIS A 141 HIS A 141 1 HELIX 31 31 GLN A 142 GLN A 142 1 HELIX 32 32 ILE A 143 ILE A 143 1 HELIX 33 33 PHE A 144 PHE A 144 1 HELIX 34 34 GLU A 145 GLU A 145 1 HELIX 35 35 LYS A 146 LYS A 146 1 HELIX 36 36 VAL A 210 VAL A 210 1 HELIX 37 37 TYR A 211 TYR A 211 1 HELIX 38 38 GLN A 212 GLN A 212 1 HELIX 39 39 ILE A 213 ILE A 213 1 HELIX 40 40 LEU A 214 LEU A 214 1 HELIX 41 41 GLU A 215 GLU A 215 1 HELIX 42 42 LYS A 216 LYS A 216 1 HELIX 43 43 GLY A 217 GLY A 217 1 HELIX 44 44 ALA A 218 ALA A 218 1 HELIX 45 45 ALA A 219 ALA A 219 1 HELIX 46 46 LYS A 220 LYS A 220 1 HELIX 47 47 ARG A 221 ARG A 221 1 HELIX 48 48 THR A 222 THR A 222 1 HELIX 49 49 THR A 223 THR A 223 1 HELIX 50 50 ALA A 224 ALA A 224 1 HELIX 51 51 ALA A 225 ALA A 225 1 HELIX 52 52 THR A 226 THR A 226 1 HELIX 53 53 LEU A 227 LEU A 227 1 HELIX 54 54 TYR A 231 TYR A 231 1 HELIX 55 55 SER A 232 SER A 232 1 HELIX 56 56 SER A 233 SER A 233 1 HELIX 57 57 ARG A 234 ARG A 234 1 HELIX 58 58 GLN A 290 GLN A 290 1 HELIX 59 59 SER A 291 SER A 291 1 HELIX 60 60 LEU A 292 LEU A 292 1 HELIX 61 61 LEU A 293 LEU A 293 1 HELIX 62 62 THR A 294 THR A 294 1 HELIX 63 63 LEU A 295 LEU A 295 1 HELIX 64 64 GLY A 296 GLY A 296 1 HELIX 65 65 ARG A 297 ARG A 297 1 HELIX 66 66 VAL A 298 VAL A 298 1 HELIX 67 67 ILE A 299 ILE A 299 1 HELIX 68 68 THR A 300 THR A 300 1 HELIX 69 69 ALA A 301 ALA A 301 1 HELIX 70 70 LEU A 302 LEU A 302 1 HELIX 71 71 VAL A 303 VAL A 303 1 HELIX 72 72 LYS A 315 LYS A 315 1 HELIX 73 73 LEU A 316 LEU A 316 1 HELIX 74 74 THR A 317 THR A 317 1 HELIX 75 75 ARG A 318 ARG A 318 1 HELIX 76 76 ILE A 319 ILE A 319 1 HELIX 77 77 LEU A 343 LEU A 343 1 HELIX 78 78 GLU A 344 GLU A 344 1 HELIX 79 79 GLU A 345 GLU A 345 1 HELIX 80 80 THR A 346 THR A 346 1 HELIX 81 81 LEU A 347 LEU A 347 1 HELIX 82 82 SER A 348 SER A 348 1 HELIX 83 83 THR A 349 THR A 349 1 HELIX 84 84 LEU A 350 LEU A 350 1 HELIX 85 85 GLU A 351 GLU A 351 1 HELIX 86 86 TYR A 352 TYR A 352 1 HELIX 87 87 ALA A 353 ALA A 353 1 HELIX 88 88 HIS A 354 HIS A 354 1 HELIX 89 89 ARG A 355 ARG A 355 1 HELIX 90 90 ALA A 356 ALA A 356 1 TURN 1 1 GLY A 16 GLY A 16 TURN 2 2 LYS A 17 LYS A 17 TURN 3 3 ASN A 18 ASN A 18 TURN 4 4 ILE A 19 ILE A 19 TURN 5 5 GLN A 20 GLN A 20 TURN 6 6 VAL A 21 VAL A 21 TURN 7 7 CYS A 25 CYS A 25 TURN 8 8 ARG A 26 ARG A 26 TURN 9 9 PRO A 27 PRO A 27 TURN 10 10 PHE A 28 PHE A 28 TURN 11 11 ASN A 29 ASN A 29 TURN 12 12 LYS A 34 LYS A 34 TURN 13 13 ALA A 35 ALA A 35 TURN 14 14 SER A 36 SER A 36 TURN 15 15 ALA A 37 ALA A 37 TURN 16 16 HIS A 38 HIS A 38 TURN 17 17 SER A 39 SER A 39 TURN 18 18 ILE A 40 ILE A 40 TURN 19 19 PRO A 45 PRO A 45 TURN 20 20 VAL A 46 VAL A 46 TURN 21 21 ARG A 47 ARG A 47 TURN 22 22 LYS A 48 LYS A 48 TURN 23 23 LEU A 57 LEU A 57 TURN 24 24 ALA A 58 ALA A 58 TURN 25 25 ASP A 59 ASP A 59 TURN 26 26 LYS A 60 LYS A 60 TURN 27 27 PHE A 68 PHE A 68 TURN 28 28 ASP A 69 ASP A 69 TURN 29 29 GLY A 73 GLY A 73 TURN 30 30 ALA A 74 ALA A 74 TURN 31 31 SER A 75 SER A 75 TURN 32 32 THR A 76 THR A 76 TURN 33 33 LYS A 77 LYS A 77 TURN 34 34 VAL A 85 VAL A 85 TURN 35 35 VAL A 86 VAL A 86 TURN 36 36 MET A 95 MET A 95 TURN 37 37 GLY A 96 GLY A 96 TURN 38 38 TYR A 97 TYR A 97 TURN 39 39 TYR A 104 TYR A 104 TURN 40 40 GLY A 105 GLY A 105 TURN 41 41 GLN A 106 GLN A 106 TURN 42 42 THR A 107 THR A 107 TURN 43 43 GLY A 108 GLY A 108 TURN 44 44 THR A 109 THR A 109 TURN 45 45 GLY A 110 GLY A 110 TURN 46 46 GLU A 116 GLU A 116 TURN 47 47 GLY A 117 GLY A 117 TURN 48 48 GLU A 118 GLU A 118 TURN 49 49 ARG A 119 ARG A 119 TURN 50 50 SER A 120 SER A 120 TURN 51 51 PRO A 121 PRO A 121 TURN 52 52 ASN A 122 ASN A 122 TURN 53 53 GLU A 123 GLU A 123 TURN 54 54 GLU A 124 GLU A 124 TURN 55 55 TYR A 125 TYR A 125 TURN 56 56 THR A 126 THR A 126 TURN 57 57 TRP A 127 TRP A 127 TURN 58 58 GLU A 128 GLU A 128 TURN 59 59 GLU A 129 GLU A 129 TURN 60 60 ASP A 130 ASP A 130 TURN 61 61 PRO A 131 PRO A 131 TURN 62 62 LEU A 132 LEU A 132 TURN 63 63 ALA A 133 ALA A 133 TURN 64 64 GLY A 134 GLY A 134 TURN 65 65 ILE A 135 ILE A 135 TURN 66 66 LEU A 147 LEU A 147 TURN 67 67 THR A 148 THR A 148 TURN 68 68 ASP A 149 ASP A 149 TURN 69 69 ASN A 150 ASN A 150 TURN 70 70 GLY A 151 GLY A 151 TURN 71 71 THR A 152 THR A 152 TURN 72 72 ASN A 165 ASN A 165 TURN 73 73 GLU A 166 GLU A 166 TURN 74 74 LEU A 171 LEU A 171 TURN 75 75 LEU A 172 LEU A 172 TURN 76 76 ASN A 173 ASN A 173 TURN 77 77 PRO A 174 PRO A 174 TURN 78 78 SER A 175 SER A 175 TURN 79 79 SER A 176 SER A 176 TURN 80 80 ASP A 177 ASP A 177 TURN 81 81 VAL A 178 VAL A 178 TURN 82 82 SER A 179 SER A 179 TURN 83 83 GLU A 180 GLU A 180 TURN 84 84 ASP A 187 ASP A 187 TURN 85 85 PRO A 188 PRO A 188 TURN 86 86 ARG A 189 ARG A 189 TURN 87 87 ASN A 190 ASN A 190 TURN 88 88 LYS A 191 LYS A 191 TURN 89 89 ARG A 192 ARG A 192 TURN 90 90 GLY A 193 GLY A 193 TURN 91 91 GLY A 198 GLY A 198 TURN 92 92 LEU A 199 LEU A 199 TURN 93 93 GLU A 200 GLU A 200 TURN 94 94 GLU A 201 GLU A 201 TURN 95 95 VAL A 204 VAL A 204 TURN 96 96 HIS A 205 HIS A 205 TURN 97 97 ASN A 206 ASN A 206 TURN 98 98 LYS A 207 LYS A 207 TURN 99 99 ASP A 208 ASP A 208 TURN 100 100 GLU A 209 GLU A 209 TURN 101 101 MET A 228 MET A 228 TURN 102 102 ASN A 229 ASN A 229 TURN 103 103 ALA A 230 ALA A 230 TURN 104 104 SER A 235 SER A 235 TURN 105 105 THR A 249 THR A 249 TURN 106 106 ILE A 250 ILE A 250 TURN 107 107 ASP A 251 ASP A 251 TURN 108 108 GLY A 252 GLY A 252 TURN 109 109 GLU A 253 GLU A 253 TURN 110 110 LEU A 266 LEU A 266 TURN 111 111 ALA A 267 ALA A 267 TURN 112 112 GLY A 268 GLY A 268 TURN 113 113 SER A 269 SER A 269 TURN 114 114 GLU A 270 GLU A 270 TURN 115 115 ASN A 271 ASN A 271 TURN 116 116 ILE A 272 ILE A 272 TURN 117 117 GLY A 273 GLY A 273 TURN 118 118 ARG A 274 ARG A 274 TURN 119 119 SER A 275 SER A 275 TURN 120 120 GLY A 276 GLY A 276 TURN 121 121 ALA A 277 ALA A 277 TURN 122 122 VAL A 278 VAL A 278 TURN 123 123 ASP A 279 ASP A 279 TURN 124 124 LYS A 280 LYS A 280 TURN 125 125 ARG A 281 ARG A 281 TURN 126 126 ALA A 282 ALA A 282 TURN 127 127 ARG A 283 ARG A 283 TURN 128 128 GLU A 284 GLU A 284 TURN 129 129 ALA A 285 ALA A 285 TURN 130 130 GLY A 286 GLY A 286 TURN 131 131 ASN A 287 ASN A 287 TURN 132 132 ILE A 288 ILE A 288 TURN 133 133 ASN A 289 ASN A 289 TURN 134 134 GLU A 304 GLU A 304 TURN 135 135 ARG A 305 ARG A 305 TURN 136 136 THR A 306 THR A 306 TURN 137 137 PRO A 307 PRO A 307 TURN 138 138 HIS A 308 HIS A 308 TURN 139 139 VAL A 309 VAL A 309 TURN 140 140 PRO A 310 PRO A 310 TURN 141 141 TYR A 311 TYR A 311 TURN 142 142 ARG A 312 ARG A 312 TURN 143 143 GLU A 313 GLU A 313 TURN 144 144 SER A 314 SER A 314 TURN 145 145 LEU A 320 LEU A 320 TURN 146 146 GLN A 321 GLN A 321 TURN 147 147 ASP A 322 ASP A 322 TURN 148 148 SER A 323 SER A 323 TURN 149 149 LEU A 324 LEU A 324 TURN 150 150 GLY A 325 GLY A 325 TURN 151 151 GLY A 326 GLY A 326 TURN 152 152 ARG A 327 ARG A 327 TURN 153 153 THR A 328 THR A 328 TURN 154 154 ARG A 329 ARG A 329 TURN 155 155 THR A 330 THR A 330 TURN 156 156 SER A 331 SER A 331 TURN 157 157 ILE A 332 ILE A 332 TURN 158 158 ILE A 333 ILE A 333 TURN 159 159 ALA A 334 ALA A 334 TURN 160 160 THR A 335 THR A 335 TURN 161 161 ILE A 336 ILE A 336 TURN 162 162 SER A 337 SER A 337 TURN 163 163 PRO A 338 PRO A 338 TURN 164 164 ALA A 339 ALA A 339 TURN 165 165 SER A 340 SER A 340 TURN 166 166 LEU A 341 LEU A 341 TURN 167 167 ASN A 342 ASN A 342 TURN 168 168 LYS A 357 LYS A 357 TURN 169 169 ASN A 358 ASN A 358 TURN 170 170 ILE A 359 ILE A 359 TURN 171 171 LEU A 360 LEU A 360 TURN 172 172 ASN A 361 ASN A 361 TURN 173 173 LYS A 362 LYS A 362 SHEET 1 1 1 VAL A 22 VAL A 22 0 SHEET 1 2 1 VAL A 23 VAL A 23 0 SHEET 1 3 1 ARG A 24 ARG A 24 0 SHEET 1 4 1 VAL A 41 VAL A 41 0 SHEET 1 5 1 GLU A 42 GLU A 42 0 SHEET 1 6 1 CYS A 43 CYS A 43 0 SHEET 1 7 1 ASP A 44 ASP A 44 0 SHEET 1 8 1 GLU A 49 GLU A 49 0 SHEET 1 9 1 VAL A 50 VAL A 50 0 SHEET 1 10 1 SER A 51 SER A 51 0 SHEET 1 11 1 VAL A 52 VAL A 52 0 SHEET 1 12 1 ARG A 53 ARG A 53 0 SHEET 1 13 1 THR A 54 THR A 54 0 SHEET 1 14 1 GLY A 55 GLY A 55 0 SHEET 1 15 1 GLY A 56 GLY A 56 0 SHEET 1 16 1 SER A 61 SER A 61 0 SHEET 1 17 1 SER A 62 SER A 62 0 SHEET 1 18 1 ARG A 63 ARG A 63 0 SHEET 1 19 1 LYS A 64 LYS A 64 0 SHEET 1 20 1 THR A 65 THR A 65 0 SHEET 1 21 1 TYR A 66 TYR A 66 0 SHEET 1 22 1 THR A 67 THR A 67 0 SHEET 1 23 1 MET A 70 MET A 70 0 SHEET 1 24 1 VAL A 71 VAL A 71 0 SHEET 1 25 1 PHE A 72 PHE A 72 0 SHEET 1 26 1 ASN A 98 ASN A 98 0 SHEET 1 27 1 CYS A 99 CYS A 99 0 SHEET 1 28 1 THR A 100 THR A 100 0 SHEET 1 29 1 ILE A 101 ILE A 101 0 SHEET 1 30 1 PHE A 102 PHE A 102 0 SHEET 1 31 1 ALA A 103 ALA A 103 0 SHEET 1 32 1 GLU A 153 GLU A 153 0 SHEET 1 33 1 PHE A 154 PHE A 154 0 SHEET 1 34 1 SER A 155 SER A 155 0 SHEET 1 35 1 VAL A 156 VAL A 156 0 SHEET 1 36 1 LYS A 157 LYS A 157 0 SHEET 1 37 1 VAL A 158 VAL A 158 0 SHEET 1 38 1 SER A 159 SER A 159 0 SHEET 1 39 1 LEU A 160 LEU A 160 0 SHEET 1 40 1 LEU A 161 LEU A 161 0 SHEET 1 41 1 GLU A 162 GLU A 162 0 SHEET 1 42 1 ILE A 163 ILE A 163 0 SHEET 1 43 1 TYR A 164 TYR A 164 0 SHEET 1 44 1 GLU A 167 GLU A 167 0 SHEET 1 45 1 LEU A 168 LEU A 168 0 SHEET 1 46 1 PHE A 169 PHE A 169 0 SHEET 1 47 1 ASP A 170 ASP A 170 0 SHEET 1 48 1 ARG A 181 ARG A 181 0 SHEET 1 49 1 LEU A 182 LEU A 182 0 SHEET 1 50 1 GLN A 183 GLN A 183 0 SHEET 1 51 1 MET A 184 MET A 184 0 SHEET 1 52 1 PHE A 185 PHE A 185 0 SHEET 1 53 1 ASP A 186 ASP A 186 0 SHEET 1 54 1 VAL A 194 VAL A 194 0 SHEET 1 55 1 ILE A 195 ILE A 195 0 SHEET 1 56 1 ILE A 196 ILE A 196 0 SHEET 1 57 1 LYS A 197 LYS A 197 0 SHEET 1 58 1 ILE A 202 ILE A 202 0 SHEET 1 59 1 THR A 203 THR A 203 0 SHEET 1 60 1 HIS A 236 HIS A 236 0 SHEET 1 61 1 SER A 237 SER A 237 0 SHEET 1 62 1 VAL A 238 VAL A 238 0 SHEET 1 63 1 PHE A 239 PHE A 239 0 SHEET 1 64 1 SER A 240 SER A 240 0 SHEET 1 65 1 VAL A 241 VAL A 241 0 SHEET 1 66 1 THR A 242 THR A 242 0 SHEET 1 67 1 ILE A 243 ILE A 243 0 SHEET 1 68 1 HIS A 244 HIS A 244 0 SHEET 1 69 1 MET A 245 MET A 245 0 SHEET 1 70 1 LYS A 246 LYS A 246 0 SHEET 1 71 1 GLU A 247 GLU A 247 0 SHEET 1 72 1 THR A 248 THR A 248 0 SHEET 1 73 1 GLU A 254 GLU A 254 0 SHEET 1 74 1 LEU A 255 LEU A 255 0 SHEET 1 75 1 VAL A 256 VAL A 256 0 SHEET 1 76 1 LYS A 257 LYS A 257 0 SHEET 1 77 1 ILE A 258 ILE A 258 0 SHEET 1 78 1 GLY A 259 GLY A 259 0 SHEET 1 79 1 LYS A 260 LYS A 260 0 SHEET 1 80 1 LEU A 261 LEU A 261 0 SHEET 1 81 1 ASN A 262 ASN A 262 0 SHEET 1 82 1 LEU A 263 LEU A 263 0 SHEET 1 83 1 VAL A 264 VAL A 264 0 SHEET 1 84 1 ASP A 265 ASP A 265 0 CRYST1 160.950 79.718 69.513 90.00 96.88 90.00 C 1 2 1 8 HETATM 1 CH3 ACE A 15 24.431 -17.877 -11.476 1.00 0.00 C HETATM 2 C ACE A 15 24.674 -16.414 -11.124 1.00 0.00 C HETATM 3 O ACE A 15 25.798 -15.931 -11.253 1.00 0.00 O HETATM 4 H1 ACE A 15 25.311 -18.475 -11.239 1.00 0.00 H HETATM 5 H2 ACE A 15 23.585 -18.282 -10.919 1.00 0.00 H HETATM 6 H3 ACE A 15 24.223 -17.978 -12.542 1.00 0.00 H ATOM 7 N GLY A 16 23.614 -15.724 -10.670 1.00 56.82 N ATOM 8 CA GLY A 16 23.646 -14.323 -10.247 1.00 57.15 C ATOM 9 C GLY A 16 24.213 -14.203 -8.825 1.00 56.24 C ATOM 10 O GLY A 16 25.151 -14.910 -8.454 1.00 56.63 O ATOM 11 H GLY A 16 22.728 -16.199 -10.583 1.00 56.82 H ATOM 12 HA3 GLY A 16 22.635 -13.918 -10.293 1.00 57.15 H ATOM 13 HA2 GLY A 16 24.256 -13.729 -10.929 1.00 57.15 H ATOM 14 N LYS A 17 23.662 -13.267 -8.040 1.00 53.91 N ATOM 15 CA LYS A 17 24.105 -13.003 -6.677 1.00 51.35 C ATOM 16 C LYS A 17 22.888 -12.704 -5.798 1.00 48.72 C ATOM 17 O LYS A 17 22.318 -11.618 -5.893 1.00 48.83 O ATOM 18 CB LYS A 17 25.153 -11.868 -6.699 1.00 53.46 C ATOM 19 CG LYS A 17 25.712 -11.461 -5.324 1.00 54.84 C ATOM 20 CD LYS A 17 26.495 -12.582 -4.611 1.00 56.79 C ATOM 21 CE LYS A 17 27.010 -12.193 -3.216 1.00 57.01 C ATOM 22 NZ LYS A 17 28.016 -11.119 -3.266 1.00 59.10 N1+ ATOM 23 H LYS A 17 22.912 -12.683 -8.386 1.00 53.91 H ATOM 24 HA LYS A 17 24.578 -13.900 -6.274 1.00 51.35 H ATOM 25 HB3 LYS A 17 24.714 -10.985 -7.167 1.00 53.46 H ATOM 26 HB2 LYS A 17 25.987 -12.157 -7.341 1.00 53.46 H ATOM 27 HG3 LYS A 17 24.896 -11.125 -4.688 1.00 54.84 H ATOM 28 HG2 LYS A 17 26.353 -10.591 -5.464 1.00 54.84 H ATOM 29 HD3 LYS A 17 27.325 -12.908 -5.240 1.00 56.79 H ATOM 30 HD2 LYS A 17 25.855 -13.456 -4.490 1.00 56.79 H ATOM 31 HE3 LYS A 17 27.459 -13.061 -2.732 1.00 57.01 H ATOM 32 HE2 LYS A 17 26.180 -11.874 -2.586 1.00 57.01 H ATOM 33 HZ1 LYS A 17 28.326 -10.902 -2.329 1.00 59.10 H ATOM 34 HZ2 LYS A 17 28.805 -11.418 -3.822 1.00 59.10 H ATOM 35 HZ3 LYS A 17 27.606 -10.296 -3.682 1.00 59.10 H ATOM 36 N ASN A 18 22.534 -13.674 -4.941 1.00 45.87 N ATOM 37 CA ASN A 18 21.461 -13.558 -3.950 1.00 44.12 C ATOM 38 C ASN A 18 21.811 -12.503 -2.887 1.00 40.49 C ATOM 39 O ASN A 18 22.990 -12.349 -2.557 1.00 38.53 O ATOM 40 CB ASN A 18 21.221 -14.929 -3.273 1.00 45.88 C ATOM 41 CG ASN A 18 20.663 -16.028 -4.189 1.00 48.93 C ATOM 42 OD1 ASN A 18 20.711 -15.937 -5.414 1.00 50.57 O ATOM 43 ND2 ASN A 18 20.140 -17.097 -3.585 1.00 49.83 N ATOM 44 H ASN A 18 23.043 -14.546 -4.940 1.00 45.87 H ATOM 45 HA ASN A 18 20.571 -13.264 -4.502 1.00 44.12 H ATOM 46 HB3 ASN A 18 20.515 -14.801 -2.452 1.00 45.88 H ATOM 47 HB2 ASN A 18 22.147 -15.292 -2.823 1.00 45.88 H ATOM 48 HD22 ASN A 18 19.764 -17.854 -4.136 1.00 49.83 H ATOM 49 HD21 ASN A 18 20.101 -17.148 -2.577 1.00 49.83 H ATOM 50 N ILE A 19 20.785 -11.816 -2.354 1.00 37.01 N ATOM 51 CA ILE A 19 20.936 -10.859 -1.254 1.00 33.92 C ATOM 52 C ILE A 19 21.437 -11.568 0.018 1.00 32.91 C ATOM 53 O ILE A 19 20.806 -12.523 0.471 1.00 32.02 O ATOM 54 CB ILE A 19 19.627 -10.064 -0.954 1.00 34.31 C ATOM 55 CG1 ILE A 19 19.307 -9.139 -2.156 1.00 33.64 C ATOM 56 CG2 ILE A 19 19.667 -9.262 0.374 1.00 32.90 C ATOM 57 CD1 ILE A 19 18.136 -8.165 -1.954 1.00 33.56 C ATOM 58 H ILE A 19 19.841 -11.995 -2.674 1.00 37.01 H ATOM 59 HA ILE A 19 21.695 -10.142 -1.565 1.00 33.92 H ATOM 60 HB ILE A 19 18.810 -10.781 -0.877 1.00 34.31 H ATOM 61 HG13 ILE A 19 19.108 -9.745 -3.041 1.00 33.64 H ATOM 62 HG12 ILE A 19 20.194 -8.558 -2.400 1.00 33.64 H ATOM 63 HG21 ILE A 19 18.744 -8.711 0.540 1.00 32.90 H ATOM 64 HG22 ILE A 19 19.775 -9.903 1.249 1.00 32.90 H ATOM 65 HG23 ILE A 19 20.487 -8.546 0.385 1.00 32.90 H ATOM 66 HD11 ILE A 19 17.783 -7.782 -2.911 1.00 33.56 H ATOM 67 HD12 ILE A 19 17.298 -8.645 -1.453 1.00 33.56 H ATOM 68 HD13 ILE A 19 18.433 -7.305 -1.357 1.00 33.56 H ATOM 69 N GLN A 20 22.581 -11.093 0.535 1.00 31.83 N ATOM 70 CA GLN A 20 23.246 -11.666 1.700 1.00 31.76 C ATOM 71 C GLN A 20 22.649 -11.100 2.987 1.00 29.83 C ATOM 72 O GLN A 20 22.845 -9.923 3.283 1.00 30.30 O ATOM 73 CB GLN A 20 24.758 -11.400 1.625 1.00 32.28 C ATOM 74 CG GLN A 20 25.436 -12.188 0.492 1.00 35.88 C ATOM 75 CD GLN A 20 26.959 -12.095 0.565 1.00 37.61 C ATOM 76 OE1 GLN A 20 27.516 -11.013 0.728 1.00 40.61 O ATOM 77 NE2 GLN A 20 27.641 -13.231 0.418 1.00 39.78 N ATOM 78 H GLN A 20 23.027 -10.292 0.113 1.00 31.83 H ATOM 79 HA GLN A 20 23.099 -12.747 1.693 1.00 31.76 H ATOM 80 HB3 GLN A 20 25.214 -11.687 2.575 1.00 32.28 H ATOM 81 HB2 GLN A 20 24.946 -10.332 1.506 1.00 32.28 H ATOM 82 HG3 GLN A 20 25.101 -11.819 -0.477 1.00 35.88 H ATOM 83 HG2 GLN A 20 25.137 -13.236 0.546 1.00 35.88 H ATOM 84 HE22 GLN A 20 28.649 -13.230 0.470 1.00 39.78 H ATOM 85 HE21 GLN A 20 27.153 -14.107 0.292 1.00 39.78 H ATOM 86 N VAL A 21 21.934 -11.949 3.729 1.00 27.26 N ATOM 87 CA VAL A 21 21.259 -11.549 4.953 1.00 26.53 C ATOM 88 C VAL A 21 22.034 -12.104 6.151 1.00 27.22 C ATOM 89 O VAL A 21 22.328 -13.298 6.190 1.00 28.15 O ATOM 90 CB VAL A 21 19.814 -12.090 5.008 1.00 25.02 C ATOM 91 CG1 VAL A 21 19.068 -11.635 6.274 1.00 25.05 C ATOM 92 CG2 VAL A 21 19.017 -11.669 3.758 1.00 23.47 C ATOM 93 H VAL A 21 21.845 -12.920 3.455 1.00 27.26 H ATOM 94 HA VAL A 21 21.201 -10.464 5.023 1.00 26.53 H ATOM 95 HB VAL A 21 19.847 -13.180 5.024 1.00 25.02 H ATOM 96 HG11 VAL A 21 18.077 -12.072 6.286 1.00 25.05 H ATOM 97 HG12 VAL A 21 19.552 -11.950 7.198 1.00 25.05 H ATOM 98 HG13 VAL A 21 18.960 -10.550 6.308 1.00 25.05 H ATOM 99 HG21 VAL A 21 17.985 -12.007 3.810 1.00 23.47 H ATOM 100 HG22 VAL A 21 19.002 -10.586 3.641 1.00 23.47 H ATOM 101 HG23 VAL A 21 19.438 -12.094 2.848 1.00 23.47 H ATOM 102 N VAL A 22 22.328 -11.218 7.110 1.00 26.44 N ATOM 103 CA VAL A 22 23.018 -11.556 8.348 1.00 27.25 C ATOM 104 C VAL A 22 22.177 -11.059 9.531 1.00 25.59 C ATOM 105 O VAL A 22 21.467 -10.064 9.391 1.00 22.16 O ATOM 106 CB VAL A 22 24.448 -10.936 8.400 1.00 28.72 C ATOM 107 CG1 VAL A 22 25.230 -11.232 7.107 1.00 32.98 C ATOM 108 CG2 VAL A 22 24.532 -9.431 8.717 1.00 29.91 C ATOM 109 H VAL A 22 22.039 -10.253 7.012 1.00 26.44 H ATOM 110 HA VAL A 22 23.093 -12.636 8.430 1.00 27.25 H ATOM 111 HB VAL A 22 24.979 -11.448 9.204 1.00 28.72 H ATOM 112 HG11 VAL A 22 26.256 -10.888 7.188 1.00 32.98 H ATOM 113 HG12 VAL A 22 25.247 -12.299 6.884 1.00 32.98 H ATOM 114 HG13 VAL A 22 24.798 -10.723 6.246 1.00 32.98 H ATOM 115 HG21 VAL A 22 25.564 -9.082 8.681 1.00 29.91 H ATOM 116 HG22 VAL A 22 23.965 -8.856 7.986 1.00 29.91 H ATOM 117 HG23 VAL A 22 24.156 -9.193 9.712 1.00 29.91 H ATOM 118 N VAL A 23 22.269 -11.757 10.672 1.00 24.13 N ATOM 119 CA VAL A 23 21.580 -11.373 11.905 1.00 23.21 C ATOM 120 C VAL A 23 22.603 -10.887 12.939 1.00 24.05 C ATOM 121 O VAL A 23 23.682 -11.468 13.034 1.00 25.40 O ATOM 122 CB VAL A 23 20.755 -12.554 12.494 1.00 22.95 C ATOM 123 CG1 VAL A 23 20.241 -12.363 13.940 1.00 24.02 C ATOM 124 CG2 VAL A 23 19.558 -12.861 11.584 1.00 22.44 C ATOM 125 H VAL A 23 22.869 -12.569 10.723 1.00 24.13 H ATOM 126 HA VAL A 23 20.892 -10.560 11.698 1.00 23.21 H ATOM 127 HB VAL A 23 21.392 -13.440 12.499 1.00 22.95 H ATOM 128 HG11 VAL A 23 19.594 -13.190 14.235 1.00 24.02 H ATOM 129 HG12 VAL A 23 21.051 -12.334 14.669 1.00 24.02 H ATOM 130 HG13 VAL A 23 19.663 -11.444 14.038 1.00 24.02 H ATOM 131 HG21 VAL A 23 19.017 -13.731 11.946 1.00 22.44 H ATOM 132 HG22 VAL A 23 18.855 -12.029 11.559 1.00 22.44 H ATOM 133 HG23 VAL A 23 19.868 -13.067 10.560 1.00 22.44 H ATOM 134 N ARG A 24 22.228 -9.857 13.714 1.00 23.76 N ATOM 135 CA ARG A 24 23.009 -9.381 14.849 1.00 24.07 C ATOM 136 C ARG A 24 22.105 -9.252 16.077 1.00 23.91 C ATOM 137 O ARG A 24 21.280 -8.343 16.138 1.00 23.91 O ATOM 138 CB ARG A 24 23.730 -8.063 14.503 1.00 24.65 C ATOM 139 CG ARG A 24 24.711 -7.627 15.607 1.00 24.28 C ATOM 140 CD ARG A 24 25.349 -6.260 15.344 1.00 22.93 C ATOM 141 NE ARG A 24 26.436 -5.996 16.300 1.00 21.81 N ATOM 142 CZ ARG A 24 27.196 -4.891 16.374 1.00 24.11 C ATOM 143 NH1 ARG A 24 26.979 -3.833 15.585 1.00 24.49 N ATOM 144 NH2 ARG A 24 28.200 -4.844 17.256 1.00 25.73 N1+ ATOM 145 H ARG A 24 21.323 -9.426 13.575 1.00 23.76 H ATOM 146 HA ARG A 24 23.778 -10.111 15.093 1.00 24.07 H ATOM 147 HB3 ARG A 24 23.004 -7.272 14.310 1.00 24.65 H ATOM 148 HB2 ARG A 24 24.290 -8.193 13.576 1.00 24.65 H ATOM 149 HG3 ARG A 24 25.460 -8.393 15.812 1.00 24.28 H ATOM 150 HG2 ARG A 24 24.138 -7.528 16.530 1.00 24.28 H ATOM 151 HD3 ARG A 24 24.600 -5.494 15.551 1.00 22.93 H ATOM 152 HD2 ARG A 24 25.651 -6.135 14.304 1.00 22.93 H ATOM 153 HE ARG A 24 26.586 -6.718 16.995 1.00 21.81 H ATOM 154 HH12 ARG A 24 27.579 -3.019 15.648 1.00 24.49 H ATOM 155 HH11 ARG A 24 26.195 -3.825 14.944 1.00 24.49 H ATOM 156 HH22 ARG A 24 28.781 -4.020 17.314 1.00 25.73 H ATOM 157 HH21 ARG A 24 28.395 -5.632 17.860 1.00 25.73 H ATOM 158 N CYS A 25 22.320 -10.131 17.063 1.00 22.64 N ATOM 159 CA CYS A 25 21.715 -10.009 18.383 1.00 24.93 C ATOM 160 C CYS A 25 22.588 -9.082 19.242 1.00 26.45 C ATOM 161 O CYS A 25 23.783 -9.344 19.369 1.00 27.13 O ATOM 162 CB CYS A 25 21.520 -11.392 19.031 1.00 25.80 C ATOM 163 SG CYS A 25 20.550 -11.265 20.560 1.00 30.42 S ATOM 164 H CYS A 25 23.024 -10.851 16.953 1.00 22.64 H ATOM 165 HA CYS A 25 20.730 -9.558 18.277 1.00 24.93 H ATOM 166 HB3 CYS A 25 22.478 -11.867 19.248 1.00 25.80 H ATOM 167 HB2 CYS A 25 20.986 -12.055 18.350 1.00 25.80 H ATOM 168 HG CYS A 25 21.450 -10.556 21.249 1.00 30.42 H ATOM 169 N ARG A 26 21.984 -8.031 19.822 1.00 25.64 N ATOM 170 CA ARG A 26 22.656 -7.160 20.793 1.00 26.31 C ATOM 171 C ARG A 26 22.728 -7.840 22.184 1.00 28.11 C ATOM 172 O ARG A 26 21.927 -8.735 22.456 1.00 25.72 O ATOM 173 CB ARG A 26 21.952 -5.782 20.834 1.00 26.30 C ATOM 174 CG ARG A 26 20.507 -5.752 21.363 1.00 27.32 C ATOM 175 CD ARG A 26 20.138 -4.352 21.882 1.00 28.22 C ATOM 176 NE ARG A 26 18.758 -4.277 22.384 1.00 29.36 N ATOM 177 CZ ARG A 26 18.256 -4.736 23.544 1.00 28.29 C ATOM 178 NH1 ARG A 26 19.002 -5.395 24.439 1.00 33.40 N ATOM 179 NH2 ARG A 26 16.966 -4.516 23.822 1.00 32.13 N1+ ATOM 180 H ARG A 26 20.997 -7.868 19.671 1.00 25.64 H ATOM 181 HA ARG A 26 23.671 -6.993 20.430 1.00 26.31 H ATOM 182 HB3 ARG A 26 21.972 -5.339 19.838 1.00 26.30 H ATOM 183 HB2 ARG A 26 22.541 -5.102 21.444 1.00 26.30 H ATOM 184 HG3 ARG A 26 20.349 -6.488 22.150 1.00 27.32 H ATOM 185 HG2 ARG A 26 19.835 -6.033 20.552 1.00 27.32 H ATOM 186 HD3 ARG A 26 20.220 -3.632 21.067 1.00 28.22 H ATOM 187 HD2 ARG A 26 20.837 -4.017 22.650 1.00 28.22 H ATOM 188 HE ARG A 26 18.133 -3.743 21.793 1.00 29.36 H ATOM 189 HH12 ARG A 26 18.610 -5.668 25.334 1.00 33.40 H ATOM 190 HH11 ARG A 26 19.982 -5.572 24.262 1.00 33.40 H ATOM 191 HH22 ARG A 26 16.568 -4.859 24.687 1.00 32.13 H ATOM 192 HH21 ARG A 26 16.379 -4.009 23.175 1.00 32.13 H ATOM 193 N PRO A 27 23.652 -7.395 23.064 1.00 31.04 N ATOM 194 CA PRO A 27 23.677 -7.832 24.471 1.00 34.75 C ATOM 195 C PRO A 27 22.548 -7.213 25.306 1.00 38.49 C ATOM 196 O PRO A 27 21.915 -6.248 24.873 1.00 38.86 O ATOM 197 CB PRO A 27 25.056 -7.353 24.962 1.00 34.27 C ATOM 198 CG PRO A 27 25.342 -6.111 24.137 1.00 33.61 C ATOM 199 CD PRO A 27 24.740 -6.460 22.783 1.00 32.04 C ATOM 200 HA PRO A 27 23.596 -8.916 24.550 1.00 34.75 H ATOM 201 HB3 PRO A 27 25.810 -8.110 24.748 1.00 34.27 H ATOM 202 HB2 PRO A 27 25.101 -7.153 26.034 1.00 34.27 H ATOM 203 HG3 PRO A 27 26.400 -5.854 24.084 1.00 33.61 H ATOM 204 HG2 PRO A 27 24.810 -5.259 24.564 1.00 33.61 H ATOM 205 HD2 PRO A 27 24.418 -5.557 22.278 1.00 32.04 H ATOM 206 HD3 PRO A 27 25.468 -6.964 22.151 1.00 32.04 H ATOM 207 N PHE A 28 22.361 -7.759 26.519 1.00 42.80 N ATOM 208 CA PHE A 28 21.550 -7.130 27.558 1.00 45.58 C ATOM 209 C PHE A 28 22.172 -5.810 28.030 1.00 48.44 C ATOM 210 O PHE A 28 23.350 -5.792 28.395 1.00 50.16 O ATOM 211 CB PHE A 28 21.358 -8.084 28.755 1.00 46.72 C ATOM 212 CG PHE A 28 20.412 -9.250 28.530 1.00 46.51 C ATOM 213 CD1 PHE A 28 20.782 -10.554 28.922 1.00 48.45 C ATOM 214 CD2 PHE A 28 19.106 -9.029 28.045 1.00 45.93 C ATOM 215 CE1 PHE A 28 19.877 -11.597 28.786 1.00 49.91 C ATOM 216 CE2 PHE A 28 18.214 -10.080 27.926 1.00 45.72 C ATOM 217 CZ PHE A 28 18.601 -11.357 28.293 1.00 47.71 C ATOM 218 H PHE A 28 22.906 -8.560 26.800 1.00 42.80 H ATOM 219 HA PHE A 28 20.582 -6.909 27.113 1.00 45.58 H ATOM 220 HB3 PHE A 28 20.972 -7.535 29.615 1.00 46.72 H ATOM 221 HB2 PHE A 28 22.331 -8.471 29.061 1.00 46.72 H ATOM 222 HD1 PHE A 28 21.763 -10.747 29.330 1.00 48.45 H ATOM 223 HD2 PHE A 28 18.780 -8.044 27.770 1.00 45.93 H ATOM 224 HE1 PHE A 28 20.159 -12.596 29.085 1.00 49.91 H ATOM 225 HE2 PHE A 28 17.217 -9.903 27.555 1.00 45.72 H ATOM 226 HZ PHE A 28 17.891 -12.159 28.207 1.00 47.71 H ATOM 227 N ASN A 29 21.356 -4.744 28.045 1.00 50.46 N ATOM 228 CA ASN A 29 21.730 -3.436 28.584 1.00 53.78 C ATOM 229 C ASN A 29 21.845 -3.467 30.123 1.00 55.58 C ATOM 230 O ASN A 29 21.491 -4.460 30.761 1.00 55.96 O ATOM 231 CB ASN A 29 20.788 -2.331 28.027 1.00 53.62 C ATOM 232 CG ASN A 29 19.304 -2.428 28.409 1.00 54.79 C ATOM 233 OD1 ASN A 29 18.962 -2.562 29.578 1.00 53.72 O ATOM 234 ND2 ASN A 29 18.409 -2.325 27.424 1.00 53.06 N ATOM 235 H ASN A 29 20.391 -4.853 27.754 1.00 50.46 H ATOM 236 HA ASN A 29 22.729 -3.210 28.207 1.00 53.78 H ATOM 237 HB3 ASN A 29 20.871 -2.323 26.939 1.00 53.62 H ATOM 238 HB2 ASN A 29 21.142 -1.352 28.351 1.00 53.62 H ATOM 239 HD22 ASN A 29 17.423 -2.390 27.631 1.00 53.06 H ATOM 240 HD21 ASN A 29 18.707 -2.207 26.467 1.00 53.06 H ATOM 241 N LEU A 30 22.341 -2.359 30.693 1.00 57.56 N ATOM 242 CA LEU A 30 22.530 -2.164 32.133 1.00 59.64 C ATOM 243 C LEU A 30 21.217 -2.299 32.935 1.00 60.88 C ATOM 244 O LEU A 30 21.245 -2.847 34.034 1.00 62.21 O ATOM 245 CB LEU A 30 23.193 -0.788 32.386 1.00 60.12 C ATOM 246 CG LEU A 30 24.697 -0.689 32.028 1.00 60.89 C ATOM 247 CD1 LEU A 30 25.005 -0.909 30.531 1.00 60.86 C ATOM 248 CD2 LEU A 30 25.298 0.642 32.525 1.00 62.34 C ATOM 249 H LEU A 30 22.613 -1.583 30.107 1.00 57.56 H ATOM 250 HA LEU A 30 23.203 -2.946 32.490 1.00 59.64 H ATOM 251 HB3 LEU A 30 23.099 -0.560 33.450 1.00 60.12 H ATOM 252 HB2 LEU A 30 22.635 -0.005 31.869 1.00 60.12 H ATOM 253 HG LEU A 30 25.206 -1.469 32.590 1.00 60.89 H ATOM 254 HD11 LEU A 30 25.918 -0.401 30.221 1.00 60.86 H ATOM 255 HD12 LEU A 30 25.141 -1.966 30.307 1.00 60.86 H ATOM 256 HD13 LEU A 30 24.200 -0.535 29.898 1.00 60.86 H ATOM 257 HD21 LEU A 30 26.157 0.462 33.173 1.00 62.34 H ATOM 258 HD22 LEU A 30 25.636 1.279 31.708 1.00 62.34 H ATOM 259 HD23 LEU A 30 24.580 1.227 33.101 1.00 62.34 H ATOM 260 N ALA A 31 20.094 -1.847 32.350 1.00 61.49 N ATOM 261 CA ALA A 31 18.746 -1.937 32.915 1.00 61.47 C ATOM 262 C ALA A 31 18.064 -3.316 32.763 1.00 60.67 C ATOM 263 O ALA A 31 16.956 -3.472 33.275 1.00 59.44 O ATOM 264 CB ALA A 31 17.889 -0.813 32.311 1.00 63.13 C ATOM 265 H ALA A 31 20.149 -1.452 31.421 1.00 61.49 H ATOM 266 HA ALA A 31 18.815 -1.746 33.986 1.00 61.47 H ATOM 267 HB1 ALA A 31 16.896 -0.782 32.762 1.00 63.13 H ATOM 268 HB2 ALA A 31 18.348 0.162 32.477 1.00 63.13 H ATOM 269 HB3 ALA A 31 17.755 -0.936 31.236 1.00 63.13 H ATOM 270 N GLU A 32 18.716 -4.284 32.093 1.00 60.89 N ATOM 271 CA GLU A 32 18.238 -5.659 31.908 1.00 61.52 C ATOM 272 C GLU A 32 19.019 -6.665 32.769 1.00 61.89 C ATOM 273 O GLU A 32 18.408 -7.600 33.286 1.00 62.53 O ATOM 274 CB GLU A 32 18.311 -6.042 30.413 1.00 60.85 C ATOM 275 CG GLU A 32 17.153 -5.444 29.581 1.00 60.97 C ATOM 276 CD GLU A 32 17.285 -5.627 28.059 1.00 60.90 C ATOM 277 OE1 GLU A 32 18.420 -5.548 27.545 1.00 59.14 O ATOM 278 OE2 GLU A 32 16.237 -5.813 27.404 1.00 59.59 O1- ATOM 279 H GLU A 32 19.606 -4.068 31.665 1.00 60.89 H ATOM 280 HA GLU A 32 17.194 -5.739 32.219 1.00 61.52 H ATOM 281 HB3 GLU A 32 18.307 -7.127 30.297 1.00 60.85 H ATOM 282 HB2 GLU A 32 19.269 -5.707 30.016 1.00 60.85 H ATOM 283 HG3 GLU A 32 17.065 -4.377 29.778 1.00 60.97 H ATOM 284 HG2 GLU A 32 16.214 -5.886 29.918 1.00 60.97 H ATOM 285 N ARG A 33 20.340 -6.462 32.926 1.00 62.13 N ATOM 286 CA ARG A 33 21.209 -7.335 33.724 1.00 62.76 C ATOM 287 C ARG A 33 20.979 -7.224 35.241 1.00 63.12 C ATOM 288 O ARG A 33 21.171 -8.225 35.930 1.00 62.75 O ATOM 289 CB ARG A 33 22.684 -7.061 33.394 1.00 62.27 C ATOM 290 CG ARG A 33 23.081 -7.461 31.963 1.00 62.64 C ATOM 291 CD ARG A 33 24.594 -7.388 31.686 1.00 63.34 C ATOM 292 NE ARG A 33 25.108 -6.008 31.607 1.00 64.48 N ATOM 293 CZ ARG A 33 25.614 -5.231 32.585 1.00 65.42 C ATOM 294 NH1 ARG A 33 25.669 -5.606 33.872 1.00 65.97 N ATOM 295 NH2 ARG A 33 26.099 -4.031 32.252 1.00 64.71 N1+ ATOM 296 H ARG A 33 20.784 -5.681 32.463 1.00 62.13 H ATOM 297 HA ARG A 33 20.991 -8.369 33.450 1.00 62.76 H ATOM 298 HB3 ARG A 33 23.312 -7.627 34.084 1.00 62.27 H ATOM 299 HB2 ARG A 33 22.902 -6.006 33.567 1.00 62.27 H ATOM 300 HG3 ARG A 33 22.571 -6.784 31.279 1.00 62.64 H ATOM 301 HG2 ARG A 33 22.712 -8.456 31.710 1.00 62.64 H ATOM 302 HD3 ARG A 33 24.844 -7.946 30.784 1.00 63.34 H ATOM 303 HD2 ARG A 33 25.130 -7.890 32.492 1.00 63.34 H ATOM 304 HE ARG A 33 25.048 -5.606 30.681 1.00 64.48 H ATOM 305 HH12 ARG A 33 26.068 -4.999 34.573 1.00 65.97 H ATOM 306 HH11 ARG A 33 25.321 -6.515 34.144 1.00 65.97 H ATOM 307 HH22 ARG A 33 26.501 -3.428 32.955 1.00 64.71 H ATOM 308 HH21 ARG A 33 26.088 -3.724 31.290 1.00 64.71 H ATOM 309 N LYS A 34 20.542 -6.049 35.732 1.00 63.45 N ATOM 310 CA LYS A 34 20.125 -5.846 37.126 1.00 64.03 C ATOM 311 C LYS A 34 18.891 -6.680 37.512 1.00 64.60 C ATOM 312 O LYS A 34 18.813 -7.142 38.650 1.00 65.69 O ATOM 313 CB LYS A 34 19.824 -4.358 37.376 1.00 63.62 C ATOM 314 CG LYS A 34 21.065 -3.453 37.415 1.00 64.63 C ATOM 315 CD LYS A 34 20.789 -2.005 37.873 1.00 64.91 C ATOM 316 CE LYS A 34 19.717 -1.227 37.078 1.00 65.86 C ATOM 317 NZ LYS A 34 18.341 -1.488 37.545 1.00 65.56 N1+ ATOM 318 H LYS A 34 20.419 -5.265 35.107 1.00 63.45 H ATOM 319 HA LYS A 34 20.950 -6.153 37.772 1.00 64.03 H ATOM 320 HB3 LYS A 34 19.325 -4.259 38.343 1.00 63.62 H ATOM 321 HB2 LYS A 34 19.117 -4.007 36.623 1.00 63.62 H ATOM 322 HG3 LYS A 34 21.548 -3.445 36.441 1.00 64.63 H ATOM 323 HG2 LYS A 34 21.798 -3.890 38.094 1.00 64.63 H ATOM 324 HD3 LYS A 34 21.726 -1.452 37.797 1.00 64.91 H ATOM 325 HD2 LYS A 34 20.549 -2.003 38.937 1.00 64.91 H ATOM 326 HE3 LYS A 34 19.803 -1.439 36.014 1.00 65.86 H ATOM 327 HE2 LYS A 34 19.894 -0.158 37.197 1.00 65.86 H ATOM 328 HZ1 LYS A 34 18.263 -1.240 38.522 1.00 65.56 H ATOM 329 HZ2 LYS A 34 17.690 -0.934 37.006 1.00 65.56 H ATOM 330 HZ3 LYS A 34 18.123 -2.467 37.430 1.00 65.56 H ATOM 331 N ALA A 35 17.971 -6.869 36.550 1.00 64.26 N ATOM 332 CA ALA A 35 16.790 -7.719 36.680 1.00 64.31 C ATOM 333 C ALA A 35 17.092 -9.217 36.489 1.00 64.22 C ATOM 334 O ALA A 35 16.199 -10.028 36.731 1.00 63.88 O ATOM 335 CB ALA A 35 15.740 -7.245 35.661 1.00 63.53 C ATOM 336 H ALA A 35 18.120 -6.462 35.638 1.00 64.26 H ATOM 337 HA ALA A 35 16.372 -7.591 37.681 1.00 64.31 H ATOM 338 HB1 ALA A 35 14.813 -7.812 35.755 1.00 63.53 H ATOM 339 HB2 ALA A 35 15.494 -6.194 35.812 1.00 63.53 H ATOM 340 HB3 ALA A 35 16.093 -7.359 34.636 1.00 63.53 H ATOM 341 N SER A 36 18.322 -9.555 36.050 1.00 64.97 N ATOM 342 CA SER A 36 18.800 -10.899 35.709 1.00 64.87 C ATOM 343 C SER A 36 17.929 -11.548 34.618 1.00 64.00 C ATOM 344 O SER A 36 17.423 -12.656 34.806 1.00 64.70 O ATOM 345 CB SER A 36 18.947 -11.771 36.979 1.00 65.13 C ATOM 346 OG SER A 36 20.030 -11.309 37.760 1.00 65.33 O ATOM 347 H SER A 36 18.995 -8.816 35.901 1.00 64.97 H ATOM 348 HA SER A 36 19.789 -10.778 35.263 1.00 64.87 H ATOM 349 HB3 SER A 36 19.168 -12.806 36.714 1.00 65.13 H ATOM 350 HB2 SER A 36 18.037 -11.784 37.578 1.00 65.13 H ATOM 351 HG SER A 36 19.806 -10.439 38.101 1.00 65.33 H ATOM 352 N ALA A 37 17.737 -10.805 33.513 1.00 62.61 N ATOM 353 CA ALA A 37 16.912 -11.194 32.371 1.00 60.97 C ATOM 354 C ALA A 37 17.411 -12.488 31.710 1.00 59.83 C ATOM 355 O ALA A 37 18.604 -12.606 31.429 1.00 59.91 O ATOM 356 CB ALA A 37 16.888 -10.037 31.358 1.00 60.54 C ATOM 357 H ALA A 37 18.169 -9.893 33.451 1.00 62.61 H ATOM 358 HA ALA A 37 15.895 -11.351 32.736 1.00 60.97 H ATOM 359 HB1 ALA A 37 16.288 -10.288 30.483 1.00 60.54 H ATOM 360 HB2 ALA A 37 16.458 -9.138 31.800 1.00 60.54 H ATOM 361 HB3 ALA A 37 17.892 -9.787 31.012 1.00 60.54 H ATOM 362 N HIS A 38 16.481 -13.426 31.476 1.00 58.07 N ATOM 363 CA HIS A 38 16.738 -14.670 30.753 1.00 56.37 C ATOM 364 C HIS A 38 16.643 -14.400 29.245 1.00 53.14 C ATOM 365 O HIS A 38 15.660 -13.812 28.788 1.00 52.97 O ATOM 366 CB HIS A 38 15.751 -15.767 31.212 1.00 57.37 C ATOM 367 CG HIS A 38 14.291 -15.485 30.947 1.00 58.33 C ATOM 368 ND1 HIS A 38 13.585 -16.074 29.891 1.00 58.82 N ATOM 369 CD2 HIS A 38 13.450 -14.624 31.621 1.00 58.28 C ATOM 370 CE1 HIS A 38 12.377 -15.531 29.957 1.00 58.75 C ATOM 371 NE2 HIS A 38 12.241 -14.664 30.957 1.00 57.35 N ATOM 372 H HIS A 38 15.522 -13.252 31.738 1.00 58.07 H ATOM 373 HA HIS A 38 17.746 -15.016 30.992 1.00 56.37 H ATOM 374 HB3 HIS A 38 15.872 -15.941 32.282 1.00 57.37 H ATOM 375 HB2 HIS A 38 16.010 -16.711 30.730 1.00 57.37 H ATOM 376 HD2 HIS A 38 13.617 -13.990 32.479 1.00 58.28 H ATOM 377 HE1 HIS A 38 11.582 -15.745 29.259 1.00 58.75 H ATOM 378 HE2 HIS A 38 11.414 -14.125 31.176 1.00 57.35 H ATOM 379 N SER A 39 17.675 -14.828 28.504 1.00 49.89 N ATOM 380 CA SER A 39 17.704 -14.716 27.050 1.00 45.41 C ATOM 381 C SER A 39 16.875 -15.843 26.426 1.00 41.77 C ATOM 382 O SER A 39 17.040 -17.004 26.804 1.00 42.08 O ATOM 383 CB SER A 39 19.161 -14.739 26.551 1.00 45.19 C ATOM 384 OG SER A 39 19.209 -14.520 25.156 1.00 47.29 O ATOM 385 H SER A 39 18.452 -15.303 28.940 1.00 49.89 H ATOM 386 HA SER A 39 17.269 -13.757 26.762 1.00 45.41 H ATOM 387 HB3 SER A 39 19.642 -15.690 26.781 1.00 45.19 H ATOM 388 HB2 SER A 39 19.745 -13.958 27.038 1.00 45.19 H ATOM 389 HG SER A 39 20.064 -14.807 24.823 1.00 47.29 H ATOM 390 N ILE A 40 16.029 -15.469 25.458 1.00 37.57 N ATOM 391 CA ILE A 40 15.319 -16.412 24.602 1.00 34.91 C ATOM 392 C ILE A 40 16.072 -16.669 23.282 1.00 33.66 C ATOM 393 O ILE A 40 15.690 -17.599 22.583 1.00 33.63 O ATOM 394 CB ILE A 40 13.869 -15.941 24.296 1.00 35.48 C ATOM 395 CG1 ILE A 40 13.760 -14.583 23.564 1.00 33.76 C ATOM 396 CG2 ILE A 40 13.027 -15.957 25.585 1.00 34.54 C ATOM 397 CD1 ILE A 40 12.395 -14.342 22.904 1.00 35.52 C ATOM 398 H ILE A 40 15.953 -14.491 25.210 1.00 37.57 H ATOM 399 HA ILE A 40 15.246 -17.381 25.101 1.00 34.91 H ATOM 400 HB ILE A 40 13.424 -16.682 23.630 1.00 35.48 H ATOM 401 HG13 ILE A 40 14.516 -14.505 22.786 1.00 33.76 H ATOM 402 HG12 ILE A 40 13.969 -13.775 24.262 1.00 33.76 H ATOM 403 HG21 ILE A 40 11.981 -15.719 25.397 1.00 34.54 H ATOM 404 HG22 ILE A 40 13.053 -16.939 26.055 1.00 34.54 H ATOM 405 HG23 ILE A 40 13.409 -15.238 26.309 1.00 34.54 H ATOM 406 HD11 ILE A 40 12.030 -13.338 23.116 1.00 35.52 H ATOM 407 HD12 ILE A 40 12.463 -14.437 21.821 1.00 35.52 H ATOM 408 HD13 ILE A 40 11.639 -15.044 23.249 1.00 35.52 H ATOM 409 N VAL A 41 17.127 -15.892 22.973 1.00 32.34 N ATOM 410 CA VAL A 41 17.910 -16.023 21.744 1.00 33.13 C ATOM 411 C VAL A 41 19.268 -16.693 22.034 1.00 33.37 C ATOM 412 O VAL A 41 20.004 -16.236 22.908 1.00 33.03 O ATOM 413 CB VAL A 41 18.170 -14.635 21.087 1.00 31.02 C ATOM 414 CG1 VAL A 41 19.098 -14.683 19.855 1.00 30.01 C ATOM 415 CG2 VAL A 41 16.850 -13.950 20.688 1.00 32.15 C ATOM 416 H VAL A 41 17.427 -15.172 23.616 1.00 32.34 H ATOM 417 HA VAL A 41 17.365 -16.627 21.017 1.00 33.13 H ATOM 418 HB VAL A 41 18.658 -13.993 21.822 1.00 31.02 H ATOM 419 HG11 VAL A 41 19.158 -13.711 19.368 1.00 30.01 H ATOM 420 HG12 VAL A 41 20.120 -14.963 20.111 1.00 30.01 H ATOM 421 HG13 VAL A 41 18.727 -15.398 19.122 1.00 30.01 H ATOM 422 HG21 VAL A 41 17.034 -13.002 20.180 1.00 32.15 H ATOM 423 HG22 VAL A 41 16.264 -14.575 20.016 1.00 32.15 H ATOM 424 HG23 VAL A 41 16.235 -13.727 21.558 1.00 32.15 H ATOM 425 N GLU A 42 19.589 -17.725 21.239 1.00 34.68 N ATOM 426 CA GLU A 42 20.917 -18.330 21.142 1.00 37.62 C ATOM 427 C GLU A 42 21.416 -18.169 19.704 1.00 37.62 C ATOM 428 O GLU A 42 20.675 -18.465 18.768 1.00 37.32 O ATOM 429 CB GLU A 42 20.870 -19.823 21.518 1.00 39.30 C ATOM 430 CG GLU A 42 20.636 -20.073 23.023 1.00 44.83 C ATOM 431 CD GLU A 42 20.549 -21.556 23.429 1.00 48.30 C ATOM 432 OE1 GLU A 42 20.972 -22.431 22.640 1.00 49.42 O ATOM 433 OE2 GLU A 42 20.044 -21.792 24.548 1.00 47.07 O1- ATOM 434 H GLU A 42 18.920 -18.039 20.547 1.00 34.68 H ATOM 435 HA GLU A 42 21.621 -17.826 21.807 1.00 37.62 H ATOM 436 HB3 GLU A 42 21.808 -20.295 21.217 1.00 39.30 H ATOM 437 HB2 GLU A 42 20.085 -20.318 20.944 1.00 39.30 H ATOM 438 HG3 GLU A 42 19.726 -19.565 23.342 1.00 44.83 H ATOM 439 HG2 GLU A 42 21.448 -19.620 23.592 1.00 44.83 H ATOM 440 N CYS A 43 22.673 -17.727 19.570 1.00 37.12 N ATOM 441 CA CYS A 43 23.362 -17.537 18.297 1.00 38.66 C ATOM 442 C CYS A 43 24.501 -18.560 18.197 1.00 40.09 C ATOM 443 O CYS A 43 25.208 -18.786 19.180 1.00 40.18 O ATOM 444 CB CYS A 43 23.930 -16.109 18.189 1.00 37.97 C ATOM 445 SG CYS A 43 22.581 -14.923 17.915 1.00 39.98 S ATOM 446 H CYS A 43 23.223 -17.540 20.396 1.00 37.12 H ATOM 447 HA CYS A 43 22.683 -17.703 17.458 1.00 38.66 H ATOM 448 HB3 CYS A 43 24.633 -16.027 17.360 1.00 37.97 H ATOM 449 HB2 CYS A 43 24.478 -15.833 19.091 1.00 37.97 H ATOM 450 HG CYS A 43 22.271 -15.343 16.686 1.00 39.98 H ATOM 451 N ASP A 44 24.675 -19.122 16.992 1.00 39.18 N ATOM 452 CA ASP A 44 25.745 -20.054 16.646 1.00 39.68 C ATOM 453 C ASP A 44 26.288 -19.598 15.274 1.00 37.75 C ATOM 454 O ASP A 44 25.747 -20.029 14.256 1.00 34.98 O ATOM 455 CB ASP A 44 25.243 -21.526 16.689 1.00 42.51 C ATOM 456 CG ASP A 44 26.304 -22.640 16.552 1.00 45.22 C ATOM 457 OD1 ASP A 44 27.392 -22.396 15.984 1.00 46.28 O ATOM 458 OD2 ASP A 44 25.957 -23.782 16.927 1.00 48.98 O1- ATOM 459 H ASP A 44 24.035 -18.897 16.240 1.00 39.18 H ATOM 460 HA ASP A 44 26.544 -19.997 17.385 1.00 39.68 H ATOM 461 HB3 ASP A 44 24.480 -21.676 15.923 1.00 42.51 H ATOM 462 HB2 ASP A 44 24.713 -21.677 17.631 1.00 42.51 H ATOM 463 N PRO A 45 27.326 -18.725 15.265 1.00 37.21 N ATOM 464 CA PRO A 45 27.967 -18.229 14.028 1.00 38.23 C ATOM 465 C PRO A 45 28.553 -19.293 13.082 1.00 39.60 C ATOM 466 O PRO A 45 28.496 -19.092 11.869 1.00 38.37 O ATOM 467 CB PRO A 45 29.075 -17.287 14.534 1.00 37.82 C ATOM 468 CG PRO A 45 28.604 -16.837 15.904 1.00 36.47 C ATOM 469 CD PRO A 45 27.909 -18.077 16.443 1.00 37.30 C ATOM 470 HA PRO A 45 27.216 -17.646 13.490 1.00 38.23 H ATOM 471 HB3 PRO A 45 29.255 -16.449 13.862 1.00 37.82 H ATOM 472 HB2 PRO A 45 30.020 -17.823 14.645 1.00 37.82 H ATOM 473 HG3 PRO A 45 27.875 -16.033 15.797 1.00 36.47 H ATOM 474 HG2 PRO A 45 29.409 -16.478 16.545 1.00 36.47 H ATOM 475 HD2 PRO A 45 28.630 -18.758 16.898 1.00 37.30 H ATOM 476 HD3 PRO A 45 27.177 -17.794 17.199 1.00 37.30 H ATOM 477 N VAL A 46 29.099 -20.388 13.643 1.00 40.68 N ATOM 478 CA VAL A 46 29.722 -21.487 12.894 1.00 42.73 C ATOM 479 C VAL A 46 28.687 -22.267 12.062 1.00 44.14 C ATOM 480 O VAL A 46 28.940 -22.553 10.892 1.00 44.76 O ATOM 481 CB VAL A 46 30.458 -22.486 13.837 1.00 45.34 C ATOM 482 CG1 VAL A 46 31.100 -23.688 13.109 1.00 45.35 C ATOM 483 CG2 VAL A 46 31.527 -21.776 14.687 1.00 45.25 C ATOM 484 H VAL A 46 29.087 -20.492 14.648 1.00 40.68 H ATOM 485 HA VAL A 46 30.452 -21.054 12.208 1.00 42.73 H ATOM 486 HB VAL A 46 29.730 -22.898 14.537 1.00 45.34 H ATOM 487 HG11 VAL A 46 31.679 -24.301 13.799 1.00 45.35 H ATOM 488 HG12 VAL A 46 30.355 -24.347 12.661 1.00 45.35 H ATOM 489 HG13 VAL A 46 31.773 -23.357 12.318 1.00 45.35 H ATOM 490 HG21 VAL A 46 32.043 -22.479 15.342 1.00 45.25 H ATOM 491 HG22 VAL A 46 32.277 -21.296 14.058 1.00 45.25 H ATOM 492 HG23 VAL A 46 31.090 -21.009 15.327 1.00 45.25 H ATOM 493 N ARG A 47 27.526 -22.541 12.678 1.00 43.50 N ATOM 494 CA ARG A 47 26.360 -23.145 12.036 1.00 44.40 C ATOM 495 C ARG A 47 25.573 -22.138 11.171 1.00 43.29 C ATOM 496 O ARG A 47 24.765 -22.558 10.344 1.00 42.55 O ATOM 497 CB ARG A 47 25.470 -23.732 13.148 1.00 46.46 C ATOM 498 CG ARG A 47 24.634 -24.946 12.709 1.00 51.87 C ATOM 499 CD ARG A 47 25.373 -26.293 12.807 1.00 55.57 C ATOM 500 NE ARG A 47 25.573 -26.702 14.211 1.00 59.35 N ATOM 501 CZ ARG A 47 26.228 -27.780 14.675 1.00 61.63 C ATOM 502 NH1 ARG A 47 26.815 -28.666 13.855 1.00 62.28 N ATOM 503 NH2 ARG A 47 26.297 -27.967 15.999 1.00 61.37 N1+ ATOM 504 H ARG A 47 27.410 -22.283 13.650 1.00 43.50 H ATOM 505 HA ARG A 47 26.716 -23.954 11.395 1.00 44.40 H ATOM 506 HB3 ARG A 47 24.822 -22.955 13.557 1.00 46.46 H ATOM 507 HB2 ARG A 47 26.096 -24.040 13.985 1.00 46.46 H ATOM 508 HG3 ARG A 47 24.162 -24.818 11.735 1.00 51.87 H ATOM 509 HG2 ARG A 47 23.812 -24.987 13.422 1.00 51.87 H ATOM 510 HD3 ARG A 47 26.382 -26.156 12.417 1.00 55.57 H ATOM 511 HD2 ARG A 47 24.903 -27.063 12.194 1.00 55.57 H ATOM 512 HE ARG A 47 25.181 -26.066 14.893 1.00 59.35 H ATOM 513 HH12 ARG A 47 27.304 -29.468 14.225 1.00 62.28 H ATOM 514 HH11 ARG A 47 26.768 -28.530 12.856 1.00 62.28 H ATOM 515 HH22 ARG A 47 26.780 -28.765 16.383 1.00 61.37 H ATOM 516 HH21 ARG A 47 25.881 -27.292 16.627 1.00 61.37 H ATOM 517 N LYS A 48 25.816 -20.833 11.401 1.00 42.41 N ATOM 518 CA LYS A 48 25.125 -19.669 10.841 1.00 40.29 C ATOM 519 C LYS A 48 23.639 -19.630 11.243 1.00 39.93 C ATOM 520 O LYS A 48 22.806 -19.196 10.448 1.00 39.37 O ATOM 521 CB LYS A 48 25.321 -19.575 9.313 1.00 41.78 C ATOM 522 CG LYS A 48 26.783 -19.476 8.864 1.00 43.17 C ATOM 523 CD LYS A 48 26.912 -19.576 7.334 1.00 45.52 C ATOM 524 CE LYS A 48 28.298 -19.179 6.800 1.00 47.46 C ATOM 525 NZ LYS A 48 29.365 -20.080 7.271 1.00 50.93 N1+ ATOM 526 H LYS A 48 26.512 -20.608 12.099 1.00 42.41 H ATOM 527 HA LYS A 48 25.585 -18.790 11.295 1.00 40.29 H ATOM 528 HB3 LYS A 48 24.817 -18.679 8.955 1.00 41.78 H ATOM 529 HB2 LYS A 48 24.841 -20.420 8.818 1.00 41.78 H ATOM 530 HG3 LYS A 48 27.375 -20.263 9.331 1.00 43.17 H ATOM 531 HG2 LYS A 48 27.198 -18.530 9.212 1.00 43.17 H ATOM 532 HD3 LYS A 48 26.155 -18.950 6.864 1.00 45.52 H ATOM 533 HD2 LYS A 48 26.677 -20.594 7.020 1.00 45.52 H ATOM 534 HE3 LYS A 48 28.544 -18.162 7.107 1.00 47.46 H ATOM 535 HE2 LYS A 48 28.291 -19.189 5.709 1.00 47.46 H ATOM 536 HZ1 LYS A 48 30.254 -19.777 6.901 1.00 50.93 H ATOM 537 HZ2 LYS A 48 29.397 -20.063 8.281 1.00 50.93 H ATOM 538 HZ3 LYS A 48 29.173 -21.022 6.959 1.00 50.93 H ATOM 539 N GLU A 49 23.340 -20.092 12.468 1.00 38.53 N ATOM 540 CA GLU A 49 21.989 -20.229 12.994 1.00 39.11 C ATOM 541 C GLU A 49 21.716 -19.262 14.143 1.00 37.38 C ATOM 542 O GLU A 49 22.619 -18.913 14.903 1.00 35.68 O ATOM 543 CB GLU A 49 21.744 -21.672 13.470 1.00 41.64 C ATOM 544 CG GLU A 49 21.632 -22.677 12.306 1.00 47.78 C ATOM 545 CD GLU A 49 21.267 -24.114 12.711 1.00 51.12 C ATOM 546 OE1 GLU A 49 21.072 -24.382 13.918 1.00 50.60 O ATOM 547 OE2 GLU A 49 21.203 -24.946 11.779 1.00 52.69 O1- ATOM 548 H GLU A 49 24.088 -20.390 13.081 1.00 38.53 H ATOM 549 HA GLU A 49 21.275 -20.012 12.205 1.00 39.11 H ATOM 550 HB3 GLU A 49 20.830 -21.710 14.066 1.00 41.64 H ATOM 551 HB2 GLU A 49 22.553 -21.979 14.136 1.00 41.64 H ATOM 552 HG3 GLU A 49 22.569 -22.702 11.752 1.00 47.78 H ATOM 553 HG2 GLU A 49 20.871 -22.325 11.608 1.00 47.78 H ATOM 554 N VAL A 50 20.431 -18.915 14.258 1.00 35.62 N ATOM 555 CA VAL A 50 19.838 -18.205 15.377 1.00 35.40 C ATOM 556 C VAL A 50 18.571 -18.974 15.785 1.00 35.75 C ATOM 557 O VAL A 50 17.700 -19.221 14.950 1.00 34.76 O ATOM 558 CB VAL A 50 19.523 -16.727 15.021 1.00 35.70 C ATOM 559 CG1 VAL A 50 18.625 -16.548 13.786 1.00 37.29 C ATOM 560 CG2 VAL A 50 18.952 -15.935 16.210 1.00 33.58 C ATOM 561 H VAL A 50 19.773 -19.247 13.564 1.00 35.62 H ATOM 562 HA VAL A 50 20.536 -18.211 16.215 1.00 35.40 H ATOM 563 HB VAL A 50 20.481 -16.267 14.772 1.00 35.70 H ATOM 564 HG11 VAL A 50 18.651 -15.512 13.455 1.00 37.29 H ATOM 565 HG12 VAL A 50 18.971 -17.152 12.949 1.00 37.29 H ATOM 566 HG13 VAL A 50 17.586 -16.808 13.984 1.00 37.29 H ATOM 567 HG21 VAL A 50 18.835 -14.883 15.954 1.00 33.58 H ATOM 568 HG22 VAL A 50 17.976 -16.305 16.524 1.00 33.58 H ATOM 569 HG23 VAL A 50 19.625 -15.992 17.065 1.00 33.58 H ATOM 570 N SER A 51 18.531 -19.373 17.063 1.00 34.36 N ATOM 571 CA SER A 51 17.468 -20.172 17.656 1.00 34.46 C ATOM 572 C SER A 51 16.752 -19.323 18.711 1.00 35.79 C ATOM 573 O SER A 51 17.421 -18.742 19.564 1.00 35.89 O ATOM 574 CB SER A 51 18.094 -21.444 18.258 1.00 37.01 C ATOM 575 OG SER A 51 17.089 -22.332 18.698 1.00 39.31 O ATOM 576 H SER A 51 19.288 -19.117 17.685 1.00 34.36 H ATOM 577 HA SER A 51 16.753 -20.474 16.893 1.00 34.46 H ATOM 578 HB3 SER A 51 18.754 -21.205 19.092 1.00 37.01 H ATOM 579 HB2 SER A 51 18.702 -21.958 17.512 1.00 37.01 H ATOM 580 HG SER A 51 16.696 -22.752 17.929 1.00 39.31 H ATOM 581 N VAL A 52 15.415 -19.273 18.632 1.00 34.84 N ATOM 582 CA VAL A 52 14.570 -18.466 19.509 1.00 36.07 C ATOM 583 C VAL A 52 13.629 -19.387 20.295 1.00 36.69 C ATOM 584 O VAL A 52 12.938 -20.195 19.682 1.00 39.27 O ATOM 585 CB VAL A 52 13.694 -17.470 18.700 1.00 35.47 C ATOM 586 CG1 VAL A 52 12.754 -16.624 19.585 1.00 35.27 C ATOM 587 CG2 VAL A 52 14.562 -16.535 17.847 1.00 35.83 C ATOM 588 H VAL A 52 14.937 -19.779 17.897 1.00 34.84 H ATOM 589 HA VAL A 52 15.179 -17.887 20.200 1.00 36.07 H ATOM 590 HB VAL A 52 13.066 -18.031 18.006 1.00 35.47 H ATOM 591 HG11 VAL A 52 12.254 -15.847 19.008 1.00 35.27 H ATOM 592 HG12 VAL A 52 11.970 -17.226 20.044 1.00 35.27 H ATOM 593 HG13 VAL A 52 13.310 -16.132 20.384 1.00 35.27 H ATOM 594 HG21 VAL A 52 13.940 -15.795 17.347 1.00 35.83 H ATOM 595 HG22 VAL A 52 15.292 -16.000 18.453 1.00 35.83 H ATOM 596 HG23 VAL A 52 15.104 -17.079 17.073 1.00 35.83 H ATOM 597 N ARG A 53 13.596 -19.219 21.626 1.00 38.55 N ATOM 598 CA ARG A 53 12.708 -19.929 22.540 1.00 41.08 C ATOM 599 C ARG A 53 11.301 -19.320 22.495 1.00 42.23 C ATOM 600 O ARG A 53 11.147 -18.142 22.817 1.00 42.18 O ATOM 601 CB ARG A 53 13.308 -19.884 23.957 1.00 42.63 C ATOM 602 CG ARG A 53 12.695 -20.937 24.895 1.00 47.38 C ATOM 603 CD ARG A 53 13.301 -20.956 26.312 1.00 50.43 C ATOM 604 NE ARG A 53 12.954 -19.765 27.106 1.00 55.27 N ATOM 605 CZ ARG A 53 11.773 -19.503 27.694 1.00 56.95 C ATOM 606 NH1 ARG A 53 10.725 -20.334 27.608 1.00 59.72 N ATOM 607 NH2 ARG A 53 11.635 -18.378 28.398 1.00 58.53 N1+ ATOM 608 H ARG A 53 14.210 -18.533 22.048 1.00 38.55 H ATOM 609 HA ARG A 53 12.663 -20.969 22.216 1.00 41.08 H ATOM 610 HB3 ARG A 53 13.209 -18.887 24.384 1.00 42.63 H ATOM 611 HB2 ARG A 53 14.378 -20.065 23.894 1.00 42.63 H ATOM 612 HG3 ARG A 53 12.747 -21.932 24.454 1.00 47.38 H ATOM 613 HG2 ARG A 53 11.632 -20.710 24.970 1.00 47.38 H ATOM 614 HD3 ARG A 53 14.386 -20.910 26.218 1.00 50.43 H ATOM 615 HD2 ARG A 53 13.092 -21.887 26.839 1.00 50.43 H ATOM 616 HE ARG A 53 13.688 -19.077 27.192 1.00 55.27 H ATOM 617 HH12 ARG A 53 9.863 -20.138 28.096 1.00 59.72 H ATOM 618 HH11 ARG A 53 10.810 -21.196 27.087 1.00 59.72 H ATOM 619 HH22 ARG A 53 10.759 -18.164 28.851 1.00 58.53 H ATOM 620 HH21 ARG A 53 12.418 -17.748 28.518 1.00 58.53 H ATOM 621 N THR A 54 10.315 -20.130 22.084 1.00 44.25 N ATOM 622 CA THR A 54 8.952 -19.675 21.795 1.00 46.39 C ATOM 623 C THR A 54 7.912 -20.111 22.851 1.00 48.51 C ATOM 624 O THR A 54 6.730 -19.818 22.669 1.00 47.93 O ATOM 625 CB THR A 54 8.506 -20.154 20.387 1.00 46.41 C ATOM 626 OG1 THR A 54 8.198 -21.537 20.340 1.00 47.70 O ATOM 627 CG2 THR A 54 9.533 -19.812 19.297 1.00 45.46 C ATOM 628 H THR A 54 10.518 -21.093 21.852 1.00 44.25 H ATOM 629 HA THR A 54 8.923 -18.586 21.777 1.00 46.39 H ATOM 630 HB THR A 54 7.588 -19.621 20.132 1.00 46.41 H ATOM 631 HG1 THR A 54 7.416 -21.688 20.879 1.00 47.70 H ATOM 632 HG21 THR A 54 9.094 -19.880 18.307 1.00 45.46 H ATOM 633 HG22 THR A 54 9.909 -18.794 19.410 1.00 45.46 H ATOM 634 HG23 THR A 54 10.385 -20.489 19.326 1.00 45.46 H ATOM 635 N GLY A 55 8.352 -20.762 23.938 1.00 50.52 N ATOM 636 CA GLY A 55 7.480 -21.176 25.034 1.00 54.71 C ATOM 637 C GLY A 55 8.156 -22.294 25.833 1.00 58.31 C ATOM 638 O GLY A 55 9.194 -22.820 25.432 1.00 58.28 O ATOM 639 H GLY A 55 9.332 -20.992 24.022 1.00 50.52 H ATOM 640 HA3 GLY A 55 6.524 -21.542 24.657 1.00 54.71 H ATOM 641 HA2 GLY A 55 7.282 -20.322 25.684 1.00 54.71 H ATOM 642 N GLY A 56 7.548 -22.653 26.974 1.00 60.67 N ATOM 643 CA GLY A 56 8.051 -23.681 27.884 1.00 63.02 C ATOM 644 C GLY A 56 8.911 -23.040 28.982 1.00 64.97 C ATOM 645 O GLY A 56 8.605 -21.952 29.470 1.00 66.30 O ATOM 646 H GLY A 56 6.699 -22.182 27.251 1.00 60.67 H ATOM 647 HA3 GLY A 56 8.609 -24.451 27.350 1.00 63.02 H ATOM 648 HA2 GLY A 56 7.202 -24.178 28.355 1.00 63.02 H ATOM 649 N LEU A 57 9.960 -23.767 29.392 1.00 65.39 N ATOM 650 CA LEU A 57 10.880 -23.457 30.487 1.00 66.24 C ATOM 651 C LEU A 57 12.337 -23.533 29.994 1.00 66.92 C ATOM 652 O LEU A 57 12.604 -24.014 28.895 1.00 67.15 O ATOM 653 CB LEU A 57 10.671 -24.493 31.629 1.00 65.98 C ATOM 654 CG LEU A 57 9.336 -24.417 32.408 1.00 66.38 C ATOM 655 CD1 LEU A 57 9.050 -23.014 32.978 1.00 66.32 C ATOM 656 CD2 LEU A 57 8.135 -25.026 31.654 1.00 66.04 C ATOM 657 H LEU A 57 10.144 -24.652 28.934 1.00 65.39 H ATOM 658 HA LEU A 57 10.716 -22.442 30.850 1.00 66.24 H ATOM 659 HB3 LEU A 57 11.462 -24.359 32.369 1.00 65.98 H ATOM 660 HB2 LEU A 57 10.814 -25.505 31.246 1.00 65.98 H ATOM 661 HG LEU A 57 9.490 -25.064 33.273 1.00 66.38 H ATOM 662 HD11 LEU A 57 8.654 -23.084 33.991 1.00 66.32 H ATOM 663 HD12 LEU A 57 9.951 -22.404 33.034 1.00 66.32 H ATOM 664 HD13 LEU A 57 8.323 -22.467 32.379 1.00 66.32 H ATOM 665 HD21 LEU A 57 7.600 -25.731 32.291 1.00 66.04 H ATOM 666 HD22 LEU A 57 7.417 -24.270 31.337 1.00 66.04 H ATOM 667 HD23 LEU A 57 8.444 -25.576 30.766 1.00 66.04 H ATOM 668 N ALA A 58 13.282 -23.106 30.847 1.00 67.23 N ATOM 669 CA ALA A 58 14.722 -23.288 30.626 1.00 66.48 C ATOM 670 C ALA A 58 15.191 -24.760 30.712 1.00 65.87 C ATOM 671 O ALA A 58 16.263 -25.069 30.194 1.00 66.21 O ATOM 672 CB ALA A 58 15.487 -22.411 31.626 1.00 67.06 C ATOM 673 H ALA A 58 13.015 -22.712 31.737 1.00 67.23 H ATOM 674 HA ALA A 58 14.957 -22.932 29.621 1.00 66.48 H ATOM 675 HB1 ALA A 58 16.565 -22.487 31.477 1.00 67.06 H ATOM 676 HB2 ALA A 58 15.218 -21.360 31.512 1.00 67.06 H ATOM 677 HB3 ALA A 58 15.274 -22.698 32.657 1.00 67.06 H ATOM 678 N ASP A 59 14.380 -25.629 31.341 1.00 64.61 N ATOM 679 CA ASP A 59 14.613 -27.069 31.489 1.00 62.91 C ATOM 680 C ASP A 59 14.027 -27.872 30.301 1.00 61.47 C ATOM 681 O ASP A 59 14.523 -28.958 30.004 1.00 60.79 O ATOM 682 CB ASP A 59 14.013 -27.543 32.841 1.00 64.61 C ATOM 683 CG ASP A 59 14.357 -28.965 33.326 1.00 65.60 C ATOM 684 OD1 ASP A 59 13.610 -29.438 34.211 1.00 65.91 O ATOM 685 OD2 ASP A 59 15.424 -29.494 32.945 1.00 67.03 O1- ATOM 686 H ASP A 59 13.523 -25.285 31.747 1.00 64.61 H ATOM 687 HA ASP A 59 15.691 -27.240 31.504 1.00 62.91 H ATOM 688 HB3 ASP A 59 12.928 -27.426 32.808 1.00 64.61 H ATOM 689 HB2 ASP A 59 14.339 -26.855 33.623 1.00 64.61 H ATOM 690 N LYS A 60 12.988 -27.332 29.640 1.00 60.27 N ATOM 691 CA LYS A 60 12.234 -27.994 28.574 1.00 58.55 C ATOM 692 C LYS A 60 11.502 -26.919 27.763 1.00 57.58 C ATOM 693 O LYS A 60 10.641 -26.249 28.329 1.00 58.16 O ATOM 694 CB LYS A 60 11.246 -29.008 29.208 1.00 58.27 C ATOM 695 CG LYS A 60 10.230 -29.648 28.237 1.00 57.51 C ATOM 696 CD LYS A 60 9.083 -30.356 28.971 1.00 57.75 C ATOM 697 CE LYS A 60 7.980 -30.820 28.007 1.00 57.66 C ATOM 698 NZ LYS A 60 6.835 -31.403 28.728 1.00 59.13 N1+ ATOM 699 H LYS A 60 12.654 -26.418 29.908 1.00 60.27 H ATOM 700 HA LYS A 60 12.925 -28.524 27.916 1.00 58.55 H ATOM 701 HB3 LYS A 60 10.685 -28.487 29.985 1.00 58.27 H ATOM 702 HB2 LYS A 60 11.796 -29.797 29.723 1.00 58.27 H ATOM 703 HG3 LYS A 60 10.746 -30.354 27.585 1.00 57.51 H ATOM 704 HG2 LYS A 60 9.787 -28.901 27.578 1.00 57.51 H ATOM 705 HD3 LYS A 60 8.663 -29.680 29.719 1.00 57.75 H ATOM 706 HD2 LYS A 60 9.484 -31.210 29.519 1.00 57.75 H ATOM 707 HE3 LYS A 60 8.374 -31.558 27.308 1.00 57.66 H ATOM 708 HE2 LYS A 60 7.615 -29.979 27.416 1.00 57.66 H ATOM 709 HZ1 LYS A 60 6.441 -30.714 29.352 1.00 59.13 H ATOM 710 HZ2 LYS A 60 6.132 -31.697 28.064 1.00 59.13 H ATOM 711 HZ3 LYS A 60 7.144 -32.202 29.263 1.00 59.13 H ATOM 712 N SER A 61 11.804 -26.800 26.461 1.00 55.59 N ATOM 713 CA SER A 61 11.184 -25.804 25.584 1.00 52.94 C ATOM 714 C SER A 61 11.201 -26.196 24.105 1.00 51.62 C ATOM 715 O SER A 61 12.091 -26.917 23.654 1.00 50.85 O ATOM 716 CB SER A 61 11.836 -24.420 25.787 1.00 53.73 C ATOM 717 OG SER A 61 13.243 -24.448 25.640 1.00 53.69 O ATOM 718 H SER A 61 12.502 -27.395 26.037 1.00 55.59 H ATOM 719 HA SER A 61 10.130 -25.722 25.859 1.00 52.94 H ATOM 720 HB3 SER A 61 11.550 -23.993 26.742 1.00 53.73 H ATOM 721 HB2 SER A 61 11.464 -23.725 25.037 1.00 53.73 H ATOM 722 HG SER A 61 13.613 -24.916 26.393 1.00 53.69 H ATOM 723 N SER A 62 10.226 -25.619 23.385 1.00 49.47 N ATOM 724 CA SER A 62 10.166 -25.547 21.930 1.00 48.07 C ATOM 725 C SER A 62 10.924 -24.301 21.439 1.00 46.24 C ATOM 726 O SER A 62 10.928 -23.273 22.124 1.00 45.55 O ATOM 727 CB SER A 62 8.681 -25.529 21.509 1.00 47.76 C ATOM 728 OG SER A 62 8.012 -24.350 21.921 1.00 48.25 O ATOM 729 H SER A 62 9.546 -25.042 23.859 1.00 49.47 H ATOM 730 HA SER A 62 10.634 -26.439 21.509 1.00 48.07 H ATOM 731 HB3 SER A 62 8.157 -26.394 21.918 1.00 47.76 H ATOM 732 HB2 SER A 62 8.601 -25.603 20.423 1.00 47.76 H ATOM 733 HG SER A 62 8.378 -23.607 21.434 1.00 48.25 H ATOM 734 N ARG A 63 11.545 -24.421 20.255 1.00 44.90 N ATOM 735 CA ARG A 63 12.338 -23.359 19.639 1.00 44.08 C ATOM 736 C ARG A 63 12.109 -23.317 18.121 1.00 42.93 C ATOM 737 O ARG A 63 11.867 -24.360 17.511 1.00 42.40 O ATOM 738 CB ARG A 63 13.844 -23.546 19.956 1.00 45.10 C ATOM 739 CG ARG A 63 14.193 -23.757 21.448 1.00 45.50 C ATOM 740 CD ARG A 63 15.702 -23.796 21.744 1.00 47.24 C ATOM 741 NE ARG A 63 16.331 -22.470 21.625 1.00 48.56 N ATOM 742 CZ ARG A 63 16.618 -21.599 22.607 1.00 50.82 C ATOM 743 NH1 ARG A 63 17.148 -20.416 22.281 1.00 50.08 N ATOM 744 NH2 ARG A 63 16.394 -21.879 23.899 1.00 53.19 N1+ ATOM 745 H ARG A 63 11.485 -25.284 19.733 1.00 44.90 H ATOM 746 HA ARG A 63 11.999 -22.409 20.047 1.00 44.08 H ATOM 747 HB3 ARG A 63 14.386 -22.681 19.572 1.00 45.10 H ATOM 748 HB2 ARG A 63 14.222 -24.405 19.400 1.00 45.10 H ATOM 749 HG3 ARG A 63 13.721 -24.643 21.872 1.00 45.50 H ATOM 750 HG2 ARG A 63 13.765 -22.912 21.986 1.00 45.50 H ATOM 751 HD3 ARG A 63 16.183 -24.375 20.955 1.00 47.24 H ATOM 752 HD2 ARG A 63 15.931 -24.323 22.671 1.00 47.24 H ATOM 753 HE ARG A 63 16.567 -22.205 20.675 1.00 48.56 H ATOM 754 HH12 ARG A 63 17.389 -19.747 22.998 1.00 50.08 H ATOM 755 HH11 ARG A 63 17.317 -20.176 21.313 1.00 50.08 H ATOM 756 HH22 ARG A 63 16.697 -21.240 24.619 1.00 53.19 H ATOM 757 HH21 ARG A 63 16.017 -22.779 24.158 1.00 53.19 H ATOM 758 N LYS A 64 12.243 -22.113 17.542 1.00 42.57 N ATOM 759 CA LYS A 64 12.290 -21.874 16.099 1.00 41.26 C ATOM 760 C LYS A 64 13.727 -21.515 15.707 1.00 38.78 C ATOM 761 O LYS A 64 14.285 -20.579 16.277 1.00 38.88 O ATOM 762 CB LYS A 64 11.341 -20.719 15.719 1.00 43.63 C ATOM 763 CG LYS A 64 9.853 -21.103 15.742 1.00 47.59 C ATOM 764 CD LYS A 64 8.963 -19.947 15.245 1.00 49.93 C ATOM 765 CE LYS A 64 7.452 -20.233 15.277 1.00 51.92 C ATOM 766 NZ LYS A 64 6.896 -20.212 16.643 1.00 52.03 N1+ ATOM 767 H LYS A 64 12.452 -21.312 18.124 1.00 42.57 H ATOM 768 HA LYS A 64 11.987 -22.768 15.550 1.00 41.26 H ATOM 769 HB3 LYS A 64 11.573 -20.396 14.702 1.00 43.63 H ATOM 770 HB2 LYS A 64 11.521 -19.851 16.356 1.00 43.63 H ATOM 771 HG3 LYS A 64 9.567 -21.418 16.744 1.00 47.59 H ATOM 772 HG2 LYS A 64 9.698 -21.971 15.100 1.00 47.59 H ATOM 773 HD3 LYS A 64 9.240 -19.718 14.216 1.00 49.93 H ATOM 774 HD2 LYS A 64 9.182 -19.042 15.811 1.00 49.93 H ATOM 775 HE3 LYS A 64 7.235 -21.193 14.807 1.00 51.92 H ATOM 776 HE2 LYS A 64 6.929 -19.471 14.698 1.00 51.92 H ATOM 777 HZ1 LYS A 64 7.349 -20.921 17.203 1.00 52.03 H ATOM 778 HZ2 LYS A 64 7.054 -19.304 17.057 1.00 52.03 H ATOM 779 HZ3 LYS A 64 5.904 -20.396 16.605 1.00 52.03 H ATOM 780 N THR A 65 14.279 -22.251 14.731 1.00 38.63 N ATOM 781 CA THR A 65 15.624 -22.045 14.195 1.00 37.37 C ATOM 782 C THR A 65 15.543 -21.489 12.763 1.00 37.22 C ATOM 783 O THR A 65 14.638 -21.840 12.004 1.00 36.21 O ATOM 784 CB THR A 65 16.422 -23.376 14.149 1.00 38.99 C ATOM 785 OG1 THR A 65 15.835 -24.338 13.291 1.00 41.01 O ATOM 786 CG2 THR A 65 16.615 -24.005 15.536 1.00 37.71 C ATOM 787 H THR A 65 13.750 -22.996 14.299 1.00 38.63 H ATOM 788 HA THR A 65 16.176 -21.339 14.813 1.00 37.37 H ATOM 789 HB THR A 65 17.416 -23.169 13.748 1.00 38.99 H ATOM 790 HG1 THR A 65 15.820 -23.986 12.397 1.00 41.01 H ATOM 791 HG21 THR A 65 17.197 -24.926 15.470 1.00 37.71 H ATOM 792 HG22 THR A 65 17.158 -23.326 16.189 1.00 37.71 H ATOM 793 HG23 THR A 65 15.664 -24.247 16.012 1.00 37.71 H ATOM 794 N TYR A 66 16.520 -20.633 12.437 1.00 35.89 N ATOM 795 CA TYR A 66 16.673 -19.986 11.139 1.00 35.61 C ATOM 796 C TYR A 66 18.160 -19.982 10.792 1.00 34.68 C ATOM 797 O TYR A 66 18.961 -19.578 11.634 1.00 34.69 O ATOM 798 CB TYR A 66 16.185 -18.525 11.219 1.00 35.24 C ATOM 799 CG TYR A 66 14.757 -18.318 11.670 1.00 35.81 C ATOM 800 CD1 TYR A 66 14.474 -18.140 13.042 1.00 36.83 C ATOM 801 CD2 TYR A 66 13.711 -18.298 10.726 1.00 36.87 C ATOM 802 CE1 TYR A 66 13.147 -17.964 13.471 1.00 37.60 C ATOM 803 CE2 TYR A 66 12.385 -18.118 11.157 1.00 38.67 C ATOM 804 CZ TYR A 66 12.101 -17.957 12.529 1.00 38.55 C ATOM 805 OH TYR A 66 10.815 -17.800 12.953 1.00 40.55 O ATOM 806 H TYR A 66 17.215 -20.385 13.128 1.00 35.89 H ATOM 807 HA TYR A 66 16.119 -20.521 10.365 1.00 35.61 H ATOM 808 HB3 TYR A 66 16.315 -18.038 10.252 1.00 35.24 H ATOM 809 HB2 TYR A 66 16.813 -17.985 11.926 1.00 35.24 H ATOM 810 HD1 TYR A 66 15.272 -18.152 13.770 1.00 36.83 H ATOM 811 HD2 TYR A 66 13.922 -18.428 9.675 1.00 36.87 H ATOM 812 HE1 TYR A 66 12.933 -17.841 14.523 1.00 37.60 H ATOM 813 HE2 TYR A 66 11.590 -18.115 10.428 1.00 38.67 H ATOM 814 HH TYR A 66 10.173 -17.850 12.234 1.00 40.55 H ATOM 815 N THR A 67 18.492 -20.370 9.553 1.00 34.56 N ATOM 816 CA THR A 67 19.838 -20.225 9.001 1.00 35.90 C ATOM 817 C THR A 67 19.908 -18.928 8.175 1.00 34.33 C ATOM 818 O THR A 67 18.936 -18.573 7.507 1.00 36.54 O ATOM 819 CB THR A 67 20.212 -21.422 8.088 1.00 35.84 C ATOM 820 OG1 THR A 67 20.182 -22.608 8.859 1.00 40.38 O ATOM 821 CG2 THR A 67 21.604 -21.340 7.430 1.00 38.08 C ATOM 822 H THR A 67 17.781 -20.696 8.915 1.00 34.56 H ATOM 823 HA THR A 67 20.568 -20.176 9.809 1.00 35.90 H ATOM 824 HB THR A 67 19.461 -21.532 7.303 1.00 35.84 H ATOM 825 HG1 THR A 67 20.919 -22.602 9.475 1.00 40.38 H ATOM 826 HG21 THR A 67 21.846 -22.267 6.910 1.00 38.08 H ATOM 827 HG22 THR A 67 21.661 -20.541 6.690 1.00 38.08 H ATOM 828 HG23 THR A 67 22.384 -21.164 8.173 1.00 38.08 H ATOM 829 N PHE A 68 21.066 -18.259 8.238 1.00 33.30 N ATOM 830 CA PHE A 68 21.389 -17.033 7.511 1.00 34.46 C ATOM 831 C PHE A 68 22.759 -17.169 6.829 1.00 35.45 C ATOM 832 O PHE A 68 23.421 -18.194 6.989 1.00 35.78 O ATOM 833 CB PHE A 68 21.330 -15.843 8.491 1.00 32.88 C ATOM 834 CG PHE A 68 19.921 -15.483 8.914 1.00 32.39 C ATOM 835 CD1 PHE A 68 19.367 -16.013 10.098 1.00 30.02 C ATOM 836 CD2 PHE A 68 19.095 -14.754 8.036 1.00 32.12 C ATOM 837 CE1 PHE A 68 18.043 -15.746 10.414 1.00 32.75 C ATOM 838 CE2 PHE A 68 17.775 -14.503 8.376 1.00 32.46 C ATOM 839 CZ PHE A 68 17.250 -14.992 9.562 1.00 30.39 C ATOM 840 H PHE A 68 21.812 -18.624 8.818 1.00 33.30 H ATOM 841 HA PHE A 68 20.670 -16.864 6.708 1.00 34.46 H ATOM 842 HB3 PHE A 68 21.772 -14.953 8.047 1.00 32.88 H ATOM 843 HB2 PHE A 68 21.927 -16.056 9.378 1.00 32.88 H ATOM 844 HD1 PHE A 68 19.971 -16.617 10.760 1.00 30.02 H ATOM 845 HD2 PHE A 68 19.488 -14.390 7.099 1.00 32.12 H ATOM 846 HE1 PHE A 68 17.621 -16.109 11.333 1.00 32.75 H ATOM 847 HE2 PHE A 68 17.161 -13.925 7.710 1.00 32.46 H ATOM 848 HZ PHE A 68 16.224 -14.788 9.826 1.00 30.39 H ATOM 849 N ASP A 69 23.163 -16.140 6.066 1.00 35.34 N ATOM 850 CA ASP A 69 24.493 -16.049 5.450 1.00 36.28 C ATOM 851 C ASP A 69 25.610 -15.856 6.493 1.00 36.61 C ATOM 852 O ASP A 69 26.680 -16.434 6.315 1.00 37.28 O ATOM 853 CB ASP A 69 24.591 -14.990 4.326 1.00 36.93 C ATOM 854 CG ASP A 69 23.641 -15.265 3.149 1.00 38.87 C ATOM 855 OD1 ASP A 69 22.434 -14.959 3.276 1.00 40.13 O ATOM 856 OD2 ASP A 69 24.112 -15.913 2.188 1.00 42.22 O1- ATOM 857 H ASP A 69 22.567 -15.331 5.942 1.00 35.34 H ATOM 858 HA ASP A 69 24.684 -17.016 4.980 1.00 36.28 H ATOM 859 HB3 ASP A 69 25.615 -14.931 3.951 1.00 36.93 H ATOM 860 HB2 ASP A 69 24.363 -14.000 4.722 1.00 36.93 H ATOM 861 N MET A 70 25.328 -15.109 7.573 1.00 36.59 N ATOM 862 CA MET A 70 26.141 -15.024 8.791 1.00 35.56 C ATOM 863 C MET A 70 25.221 -14.753 9.990 1.00 34.74 C ATOM 864 O MET A 70 24.092 -14.298 9.811 1.00 31.88 O ATOM 865 CB MET A 70 27.245 -13.939 8.688 1.00 39.47 C ATOM 866 CG MET A 70 28.322 -14.212 7.626 1.00 45.06 C ATOM 867 SD MET A 70 29.760 -13.111 7.657 1.00 51.52 S ATOM 868 CE MET A 70 29.062 -11.670 6.820 1.00 51.68 C ATOM 869 H MET A 70 24.422 -14.665 7.634 1.00 36.59 H ATOM 870 HA MET A 70 26.610 -15.994 8.966 1.00 35.56 H ATOM 871 HB3 MET A 70 27.748 -13.844 9.652 1.00 39.47 H ATOM 872 HB2 MET A 70 26.797 -12.965 8.505 1.00 39.47 H ATOM 873 HG3 MET A 70 27.894 -14.157 6.626 1.00 45.06 H ATOM 874 HG2 MET A 70 28.697 -15.228 7.752 1.00 45.06 H ATOM 875 HE1 MET A 70 29.856 -10.977 6.548 1.00 51.68 H ATOM 876 HE2 MET A 70 28.535 -11.960 5.911 1.00 51.68 H ATOM 877 HE3 MET A 70 28.369 -11.165 7.488 1.00 51.68 H ATOM 878 N VAL A 71 25.721 -15.024 11.204 1.00 32.66 N ATOM 879 CA VAL A 71 25.039 -14.676 12.450 1.00 31.78 C ATOM 880 C VAL A 71 26.083 -14.187 13.464 1.00 32.81 C ATOM 881 O VAL A 71 27.161 -14.770 13.568 1.00 31.61 O ATOM 882 CB VAL A 71 24.218 -15.858 13.050 1.00 31.25 C ATOM 883 CG1 VAL A 71 23.634 -15.563 14.447 1.00 33.70 C ATOM 884 CG2 VAL A 71 23.070 -16.276 12.115 1.00 33.69 C ATOM 885 H VAL A 71 26.654 -15.397 11.301 1.00 32.66 H ATOM 886 HA VAL A 71 24.354 -13.848 12.264 1.00 31.78 H ATOM 887 HB VAL A 71 24.876 -16.723 13.154 1.00 31.25 H ATOM 888 HG11 VAL A 71 22.986 -16.367 14.791 1.00 33.70 H ATOM 889 HG12 VAL A 71 24.415 -15.453 15.197 1.00 33.70 H ATOM 890 HG13 VAL A 71 23.042 -14.647 14.442 1.00 33.70 H ATOM 891 HG21 VAL A 71 22.454 -17.056 12.556 1.00 33.69 H ATOM 892 HG22 VAL A 71 22.414 -15.436 11.887 1.00 33.69 H ATOM 893 HG23 VAL A 71 23.449 -16.666 11.172 1.00 33.69 H ATOM 894 N PHE A 72 25.719 -13.119 14.185 1.00 31.41 N ATOM 895 CA PHE A 72 26.526 -12.450 15.196 1.00 30.44 C ATOM 896 C PHE A 72 25.753 -12.437 16.520 1.00 33.41 C ATOM 897 O PHE A 72 24.587 -12.040 16.544 1.00 34.20 O ATOM 898 CB PHE A 72 26.847 -11.021 14.712 1.00 31.40 C ATOM 899 CG PHE A 72 27.760 -10.979 13.499 1.00 31.93 C ATOM 900 CD1 PHE A 72 29.136 -11.266 13.630 1.00 29.89 C ATOM 901 CD2 PHE A 72 27.205 -10.842 12.208 1.00 33.00 C ATOM 902 CE1 PHE A 72 29.929 -11.384 12.496 1.00 31.75 C ATOM 903 CE2 PHE A 72 28.014 -10.967 11.089 1.00 32.57 C ATOM 904 CZ PHE A 72 29.364 -11.249 11.234 1.00 33.90 C ATOM 905 H PHE A 72 24.816 -12.695 14.010 1.00 31.41 H ATOM 906 HA PHE A 72 27.465 -12.985 15.353 1.00 30.44 H ATOM 907 HB3 PHE A 72 27.306 -10.456 15.517 1.00 31.40 H ATOM 908 HB2 PHE A 72 25.931 -10.482 14.472 1.00 31.40 H ATOM 909 HD1 PHE A 72 29.570 -11.420 14.606 1.00 29.89 H ATOM 910 HD2 PHE A 72 26.147 -10.667 12.084 1.00 33.00 H ATOM 911 HE1 PHE A 72 30.981 -11.610 12.593 1.00 31.75 H ATOM 912 HE2 PHE A 72 27.585 -10.874 10.101 1.00 32.57 H ATOM 913 HZ PHE A 72 29.965 -11.388 10.350 1.00 33.90 H ATOM 914 N GLY A 73 26.425 -12.873 17.595 1.00 33.64 N ATOM 915 CA GLY A 73 25.866 -12.923 18.944 1.00 32.52 C ATOM 916 C GLY A 73 26.119 -11.609 19.694 1.00 32.30 C ATOM 917 O GLY A 73 26.727 -10.675 19.171 1.00 31.71 O ATOM 918 H GLY A 73 27.381 -13.180 17.486 1.00 33.64 H ATOM 919 HA3 GLY A 73 26.341 -13.742 19.485 1.00 32.52 H ATOM 920 HA2 GLY A 73 24.796 -13.133 18.922 1.00 32.52 H ATOM 921 N ALA A 74 25.654 -11.570 20.953 1.00 32.62 N ATOM 922 CA ALA A 74 25.782 -10.462 21.907 1.00 32.76 C ATOM 923 C ALA A 74 27.219 -9.977 22.186 1.00 33.54 C ATOM 924 O ALA A 74 27.400 -8.803 22.505 1.00 34.23 O ATOM 925 CB ALA A 74 25.111 -10.902 23.215 1.00 33.34 C ATOM 926 H ALA A 74 25.162 -12.377 21.306 1.00 32.62 H ATOM 927 HA ALA A 74 25.233 -9.608 21.511 1.00 32.76 H ATOM 928 HB1 ALA A 74 25.340 -10.228 24.037 1.00 33.34 H ATOM 929 HB2 ALA A 74 24.026 -10.938 23.104 1.00 33.34 H ATOM 930 HB3 ALA A 74 25.445 -11.895 23.519 1.00 33.34 H ATOM 931 N SER A 75 28.206 -10.877 22.054 1.00 34.01 N ATOM 932 CA SER A 75 29.630 -10.609 22.262 1.00 34.43 C ATOM 933 C SER A 75 30.325 -9.871 21.098 1.00 34.89 C ATOM 934 O SER A 75 31.456 -9.423 21.286 1.00 35.01 O ATOM 935 CB SER A 75 30.322 -11.951 22.582 1.00 34.37 C ATOM 936 OG SER A 75 30.361 -12.814 21.460 1.00 36.98 O ATOM 937 H SER A 75 27.980 -11.824 21.783 1.00 34.01 H ATOM 938 HA SER A 75 29.725 -9.972 23.144 1.00 34.43 H ATOM 939 HB3 SER A 75 29.817 -12.458 23.405 1.00 34.37 H ATOM 940 HB2 SER A 75 31.348 -11.775 22.912 1.00 34.37 H ATOM 941 HG SER A 75 31.027 -12.491 20.847 1.00 36.98 H ATOM 942 N THR A 76 29.667 -9.780 19.928 1.00 34.17 N ATOM 943 CA THR A 76 30.229 -9.228 18.694 1.00 32.21 C ATOM 944 C THR A 76 30.534 -7.723 18.814 1.00 32.29 C ATOM 945 O THR A 76 29.636 -6.940 19.122 1.00 33.66 O ATOM 946 CB THR A 76 29.264 -9.433 17.497 1.00 32.67 C ATOM 947 OG1 THR A 76 29.038 -10.820 17.342 1.00 34.27 O ATOM 948 CG2 THR A 76 29.752 -8.888 16.145 1.00 30.68 C ATOM 949 H THR A 76 28.727 -10.146 19.861 1.00 34.17 H ATOM 950 HA THR A 76 31.157 -9.765 18.486 1.00 32.21 H ATOM 951 HB THR A 76 28.303 -8.970 17.723 1.00 32.67 H ATOM 952 HG1 THR A 76 28.499 -11.118 18.079 1.00 34.27 H ATOM 953 HG21 THR A 76 28.994 -8.998 15.372 1.00 30.68 H ATOM 954 HG22 THR A 76 29.980 -7.827 16.190 1.00 30.68 H ATOM 955 HG23 THR A 76 30.641 -9.419 15.811 1.00 30.68 H ATOM 956 N LYS A 77 31.793 -7.357 18.541 1.00 29.27 N ATOM 957 CA LYS A 77 32.267 -5.976 18.504 1.00 30.93 C ATOM 958 C LYS A 77 32.053 -5.354 17.115 1.00 29.85 C ATOM 959 O LYS A 77 31.833 -6.067 16.137 1.00 28.59 O ATOM 960 CB LYS A 77 33.761 -5.957 18.893 1.00 30.84 C ATOM 961 CG LYS A 77 34.063 -6.449 20.324 1.00 33.75 C ATOM 962 CD LYS A 77 33.336 -5.696 21.455 1.00 39.24 C ATOM 963 CE LYS A 77 33.618 -4.182 21.480 1.00 41.33 C ATOM 964 NZ LYS A 77 32.957 -3.518 22.617 1.00 40.00 N1+ ATOM 965 H LYS A 77 32.469 -8.065 18.279 1.00 29.27 H ATOM 966 HA LYS A 77 31.702 -5.374 19.217 1.00 30.93 H ATOM 967 HB3 LYS A 77 34.155 -4.946 18.786 1.00 30.84 H ATOM 968 HB2 LYS A 77 34.328 -6.566 18.189 1.00 30.84 H ATOM 969 HG3 LYS A 77 35.138 -6.386 20.493 1.00 33.75 H ATOM 970 HG2 LYS A 77 33.822 -7.511 20.396 1.00 33.75 H ATOM 971 HD3 LYS A 77 33.645 -6.137 22.405 1.00 39.24 H ATOM 972 HD2 LYS A 77 32.263 -5.882 21.388 1.00 39.24 H ATOM 973 HE3 LYS A 77 33.267 -3.708 20.563 1.00 41.33 H ATOM 974 HE2 LYS A 77 34.692 -3.999 21.546 1.00 41.33 H ATOM 975 HZ1 LYS A 77 33.292 -3.915 23.483 1.00 40.00 H ATOM 976 HZ2 LYS A 77 33.164 -2.530 22.600 1.00 40.00 H ATOM 977 HZ3 LYS A 77 31.957 -3.651 22.553 1.00 40.00 H ATOM 978 N GLN A 78 32.143 -4.017 17.053 1.00 28.05 N ATOM 979 CA GLN A 78 32.015 -3.236 15.820 1.00 27.78 C ATOM 980 C GLN A 78 33.085 -3.566 14.763 1.00 28.95 C ATOM 981 O GLN A 78 32.777 -3.556 13.572 1.00 25.92 O ATOM 982 CB GLN A 78 32.124 -1.743 16.156 1.00 27.45 C ATOM 983 CG GLN A 78 31.092 -1.171 17.144 1.00 25.90 C ATOM 984 CD GLN A 78 29.726 -0.917 16.518 1.00 24.67 C ATOM 985 OE1 GLN A 78 29.121 -1.813 15.941 1.00 25.98 O ATOM 986 NE2 GLN A 78 29.217 0.305 16.656 1.00 22.88 N ATOM 987 H GLN A 78 32.325 -3.488 17.893 1.00 28.05 H ATOM 988 HA GLN A 78 31.040 -3.449 15.380 1.00 27.78 H ATOM 989 HB3 GLN A 78 32.078 -1.186 15.221 1.00 27.45 H ATOM 990 HB2 GLN A 78 33.113 -1.556 16.570 1.00 27.45 H ATOM 991 HG3 GLN A 78 31.474 -0.219 17.501 1.00 25.90 H ATOM 992 HG2 GLN A 78 30.980 -1.802 18.026 1.00 25.90 H ATOM 993 HE22 GLN A 78 28.300 0.518 16.278 1.00 22.88 H ATOM 994 HE21 GLN A 78 29.726 1.032 17.144 1.00 22.88 H ATOM 995 N ILE A 79 34.312 -3.860 15.227 1.00 27.36 N ATOM 996 CA ILE A 79 35.437 -4.293 14.400 1.00 29.06 C ATOM 997 C ILE A 79 35.202 -5.674 13.749 1.00 27.29 C ATOM 998 O ILE A 79 35.612 -5.864 12.606 1.00 27.78 O ATOM 999 CB ILE A 79 36.767 -4.300 15.218 1.00 30.11 C ATOM 1000 CG1 ILE A 79 38.034 -4.597 14.384 1.00 32.36 C ATOM 1001 CG2 ILE A 79 36.739 -5.239 16.442 1.00 27.95 C ATOM 1002 CD1 ILE A 79 38.249 -3.654 13.192 1.00 34.09 C ATOM 1003 H ILE A 79 34.481 -3.839 16.222 1.00 27.36 H ATOM 1004 HA ILE A 79 35.528 -3.560 13.597 1.00 29.06 H ATOM 1005 HB ILE A 79 36.887 -3.288 15.609 1.00 30.11 H ATOM 1006 HG13 ILE A 79 38.019 -5.628 14.037 1.00 32.36 H ATOM 1007 HG12 ILE A 79 38.909 -4.524 15.030 1.00 32.36 H ATOM 1008 HG21 ILE A 79 37.631 -5.104 17.055 1.00 27.95 H ATOM 1009 HG22 ILE A 79 35.881 -5.043 17.081 1.00 27.95 H ATOM 1010 HG23 ILE A 79 36.709 -6.287 16.149 1.00 27.95 H ATOM 1011 HD11 ILE A 79 39.256 -3.766 12.789 1.00 34.09 H ATOM 1012 HD12 ILE A 79 37.549 -3.863 12.383 1.00 34.09 H ATOM 1013 HD13 ILE A 79 38.125 -2.612 13.483 1.00 34.09 H ATOM 1014 N ASP A 80 34.496 -6.576 14.456 1.00 28.59 N ATOM 1015 CA ASP A 80 34.096 -7.901 13.971 1.00 27.29 C ATOM 1016 C ASP A 80 33.113 -7.801 12.795 1.00 29.89 C ATOM 1017 O ASP A 80 33.333 -8.469 11.786 1.00 27.87 O ATOM 1018 CB ASP A 80 33.499 -8.817 15.069 1.00 28.62 C ATOM 1019 CG ASP A 80 34.316 -9.001 16.360 1.00 31.56 C ATOM 1020 OD1 ASP A 80 33.704 -9.485 17.337 1.00 29.84 O ATOM 1021 OD2 ASP A 80 35.545 -8.768 16.344 1.00 31.94 O1- ATOM 1022 H ASP A 80 34.181 -6.339 15.385 1.00 28.59 H ATOM 1023 HA ASP A 80 34.999 -8.385 13.593 1.00 27.29 H ATOM 1024 HB3 ASP A 80 33.320 -9.811 14.655 1.00 28.62 H ATOM 1025 HB2 ASP A 80 32.531 -8.417 15.362 1.00 28.62 H ATOM 1026 N VAL A 81 32.088 -6.936 12.927 1.00 26.47 N ATOM 1027 CA VAL A 81 31.121 -6.618 11.870 1.00 27.06 C ATOM 1028 C VAL A 81 31.795 -5.975 10.643 1.00 27.68 C ATOM 1029 O VAL A 81 31.490 -6.368 9.518 1.00 27.78 O ATOM 1030 CB VAL A 81 29.992 -5.665 12.372 1.00 26.45 C ATOM 1031 CG1 VAL A 81 29.049 -5.125 11.271 1.00 26.19 C ATOM 1032 CG2 VAL A 81 29.156 -6.336 13.473 1.00 24.32 C ATOM 1033 H VAL A 81 31.979 -6.430 13.796 1.00 26.47 H ATOM 1034 HA VAL A 81 30.666 -7.557 11.547 1.00 27.06 H ATOM 1035 HB VAL A 81 30.461 -4.793 12.830 1.00 26.45 H ATOM 1036 HG11 VAL A 81 28.219 -4.569 11.705 1.00 26.19 H ATOM 1037 HG12 VAL A 81 29.553 -4.438 10.591 1.00 26.19 H ATOM 1038 HG13 VAL A 81 28.625 -5.937 10.679 1.00 26.19 H ATOM 1039 HG21 VAL A 81 28.342 -5.691 13.801 1.00 24.32 H ATOM 1040 HG22 VAL A 81 28.719 -7.274 13.129 1.00 24.32 H ATOM 1041 HG23 VAL A 81 29.766 -6.549 14.348 1.00 24.32 H ATOM 1042 N TYR A 82 32.711 -5.020 10.877 1.00 31.58 N ATOM 1043 CA TYR A 82 33.408 -4.314 9.808 1.00 34.08 C ATOM 1044 C TYR A 82 34.322 -5.230 8.971 1.00 34.35 C ATOM 1045 O TYR A 82 34.248 -5.177 7.746 1.00 35.44 O ATOM 1046 CB TYR A 82 34.152 -3.082 10.357 1.00 37.56 C ATOM 1047 CG TYR A 82 34.718 -2.221 9.244 1.00 40.86 C ATOM 1048 CD1 TYR A 82 36.027 -2.444 8.767 1.00 42.74 C ATOM 1049 CD2 TYR A 82 33.891 -1.271 8.611 1.00 41.86 C ATOM 1050 CE1 TYR A 82 36.479 -1.771 7.618 1.00 44.29 C ATOM 1051 CE2 TYR A 82 34.356 -0.578 7.479 1.00 43.80 C ATOM 1052 CZ TYR A 82 35.638 -0.849 6.968 1.00 45.95 C ATOM 1053 OH TYR A 82 36.059 -0.227 5.834 1.00 47.94 O ATOM 1054 H TYR A 82 32.915 -4.733 11.826 1.00 31.58 H ATOM 1055 HA TYR A 82 32.635 -3.937 9.137 1.00 34.08 H ATOM 1056 HB3 TYR A 82 34.951 -3.382 11.038 1.00 37.56 H ATOM 1057 HB2 TYR A 82 33.465 -2.472 10.945 1.00 37.56 H ATOM 1058 HD1 TYR A 82 36.662 -3.177 9.242 1.00 42.74 H ATOM 1059 HD2 TYR A 82 32.887 -1.096 8.969 1.00 41.86 H ATOM 1060 HE1 TYR A 82 37.464 -1.978 7.225 1.00 44.29 H ATOM 1061 HE2 TYR A 82 33.716 0.140 6.990 1.00 43.80 H ATOM 1062 HH TYR A 82 35.398 0.358 5.457 1.00 47.94 H ATOM 1063 N ARG A 83 35.144 -6.056 9.637 1.00 33.61 N ATOM 1064 CA ARG A 83 36.062 -7.003 8.998 1.00 33.79 C ATOM 1065 C ARG A 83 35.344 -8.068 8.154 1.00 32.60 C ATOM 1066 O ARG A 83 35.787 -8.337 7.039 1.00 31.20 O ATOM 1067 CB ARG A 83 36.916 -7.697 10.076 1.00 33.24 C ATOM 1068 CG ARG A 83 38.028 -6.810 10.662 1.00 34.93 C ATOM 1069 CD ARG A 83 38.706 -7.420 11.905 1.00 36.32 C ATOM 1070 NE ARG A 83 39.373 -8.706 11.627 1.00 35.56 N ATOM 1071 CZ ARG A 83 40.584 -8.918 11.080 1.00 37.72 C ATOM 1072 NH1 ARG A 83 41.398 -7.911 10.726 1.00 36.80 N ATOM 1073 NH2 ARG A 83 40.987 -10.179 10.880 1.00 38.76 N1+ ATOM 1074 H ARG A 83 35.147 -6.047 10.650 1.00 33.61 H ATOM 1075 HA ARG A 83 36.721 -6.447 8.327 1.00 33.79 H ATOM 1076 HB3 ARG A 83 37.394 -8.576 9.641 1.00 33.24 H ATOM 1077 HB2 ARG A 83 36.269 -8.073 10.871 1.00 33.24 H ATOM 1078 HG3 ARG A 83 37.666 -5.809 10.897 1.00 34.93 H ATOM 1079 HG2 ARG A 83 38.775 -6.665 9.880 1.00 34.93 H ATOM 1080 HD3 ARG A 83 37.937 -7.639 12.647 1.00 36.32 H ATOM 1081 HD2 ARG A 83 39.382 -6.707 12.377 1.00 36.32 H ATOM 1082 HE ARG A 83 38.815 -9.520 11.845 1.00 35.56 H ATOM 1083 HH12 ARG A 83 42.302 -8.097 10.317 1.00 36.80 H ATOM 1084 HH11 ARG A 83 41.108 -6.955 10.874 1.00 36.80 H ATOM 1085 HH22 ARG A 83 41.891 -10.369 10.471 1.00 38.76 H ATOM 1086 HH21 ARG A 83 40.394 -10.953 11.141 1.00 38.76 H ATOM 1087 N SER A 84 34.278 -8.663 8.710 1.00 29.89 N ATOM 1088 CA SER A 84 33.582 -9.798 8.109 1.00 33.65 C ATOM 1089 C SER A 84 32.568 -9.419 7.016 1.00 31.73 C ATOM 1090 O SER A 84 32.480 -10.167 6.042 1.00 32.56 O ATOM 1091 CB SER A 84 32.952 -10.655 9.221 1.00 33.28 C ATOM 1092 OG SER A 84 31.922 -9.959 9.888 1.00 42.99 O ATOM 1093 H SER A 84 33.966 -8.380 9.629 1.00 29.89 H ATOM 1094 HA SER A 84 34.335 -10.429 7.630 1.00 33.65 H ATOM 1095 HB3 SER A 84 33.706 -10.959 9.949 1.00 33.28 H ATOM 1096 HB2 SER A 84 32.531 -11.570 8.802 1.00 33.28 H ATOM 1097 HG SER A 84 32.322 -9.382 10.548 1.00 42.99 H ATOM 1098 N VAL A 85 31.824 -8.306 7.184 1.00 32.27 N ATOM 1099 CA VAL A 85 30.730 -7.941 6.274 1.00 30.87 C ATOM 1100 C VAL A 85 31.093 -6.724 5.402 1.00 30.01 C ATOM 1101 O VAL A 85 30.891 -6.804 4.192 1.00 32.23 O ATOM 1102 CB VAL A 85 29.327 -7.758 6.969 1.00 32.16 C ATOM 1103 CG1 VAL A 85 29.183 -8.501 8.313 1.00 32.40 C ATOM 1104 CG2 VAL A 85 28.748 -6.334 7.115 1.00 32.73 C ATOM 1105 H VAL A 85 31.936 -7.737 8.012 1.00 32.27 H ATOM 1106 HA VAL A 85 30.580 -8.754 5.561 1.00 30.87 H ATOM 1107 HB VAL A 85 28.630 -8.267 6.301 1.00 32.16 H ATOM 1108 HG11 VAL A 85 28.132 -8.636 8.573 1.00 32.40 H ATOM 1109 HG12 VAL A 85 29.644 -9.484 8.296 1.00 32.40 H ATOM 1110 HG13 VAL A 85 29.642 -7.955 9.132 1.00 32.40 H ATOM 1111 HG21 VAL A 85 27.754 -6.367 7.561 1.00 32.73 H ATOM 1112 HG22 VAL A 85 29.368 -5.726 7.770 1.00 32.73 H ATOM 1113 HG23 VAL A 85 28.641 -5.821 6.159 1.00 32.73 H ATOM 1114 N VAL A 86 31.615 -5.632 5.994 1.00 28.37 N ATOM 1115 CA VAL A 86 31.777 -4.360 5.277 1.00 30.45 C ATOM 1116 C VAL A 86 33.036 -4.309 4.402 1.00 32.51 C ATOM 1117 O VAL A 86 32.955 -3.773 3.301 1.00 30.96 O ATOM 1118 CB VAL A 86 31.848 -3.126 6.215 1.00 29.71 C ATOM 1119 CG1 VAL A 86 31.919 -1.776 5.462 1.00 30.36 C ATOM 1120 CG2 VAL A 86 30.674 -3.082 7.193 1.00 30.48 C ATOM 1121 H VAL A 86 31.796 -5.626 6.988 1.00 28.37 H ATOM 1122 HA VAL A 86 30.912 -4.223 4.625 1.00 30.45 H ATOM 1123 HB VAL A 86 32.753 -3.199 6.818 1.00 29.71 H ATOM 1124 HG11 VAL A 86 31.834 -0.938 6.151 1.00 30.36 H ATOM 1125 HG12 VAL A 86 32.862 -1.638 4.933 1.00 30.36 H ATOM 1126 HG13 VAL A 86 31.109 -1.683 4.738 1.00 30.36 H ATOM 1127 HG21 VAL A 86 30.776 -2.198 7.812 1.00 30.48 H ATOM 1128 HG22 VAL A 86 29.715 -3.038 6.676 1.00 30.48 H ATOM 1129 HG23 VAL A 86 30.669 -3.938 7.865 1.00 30.48 H ATOM 1130 N CYS A 87 34.171 -4.829 4.898 1.00 33.65 N ATOM 1131 CA CYS A 87 35.466 -4.747 4.221 1.00 34.56 C ATOM 1132 C CYS A 87 35.499 -5.428 2.826 1.00 33.22 C ATOM 1133 O CYS A 87 35.979 -4.778 1.898 1.00 32.37 O ATOM 1134 CB CYS A 87 36.637 -5.135 5.153 1.00 37.83 C ATOM 1135 SG CYS A 87 38.257 -4.723 4.441 1.00 49.64 S ATOM 1136 H CYS A 87 34.171 -5.234 5.826 1.00 33.65 H ATOM 1137 HA CYS A 87 35.602 -3.681 4.026 1.00 34.56 H ATOM 1138 HB3 CYS A 87 36.620 -6.192 5.414 1.00 37.83 H ATOM 1139 HB2 CYS A 87 36.552 -4.586 6.092 1.00 37.83 H ATOM 1140 HG CYS A 87 38.187 -5.585 3.422 1.00 49.64 H ATOM 1141 N PRO A 88 34.877 -6.623 2.651 1.00 32.21 N ATOM 1142 CA PRO A 88 34.634 -7.211 1.317 1.00 33.69 C ATOM 1143 C PRO A 88 33.717 -6.386 0.393 1.00 34.06 C ATOM 1144 O PRO A 88 34.009 -6.288 -0.798 1.00 33.78 O ATOM 1145 CB PRO A 88 34.022 -8.593 1.617 1.00 33.34 C ATOM 1146 CG PRO A 88 34.480 -8.924 3.025 1.00 30.72 C ATOM 1147 CD PRO A 88 34.482 -7.563 3.702 1.00 31.11 C ATOM 1148 HA PRO A 88 35.606 -7.343 0.836 1.00 33.69 H ATOM 1149 HB3 PRO A 88 34.328 -9.352 0.896 1.00 33.34 H ATOM 1150 HB2 PRO A 88 32.931 -8.550 1.603 1.00 33.34 H ATOM 1151 HG3 PRO A 88 35.497 -9.317 2.995 1.00 30.72 H ATOM 1152 HG2 PRO A 88 33.849 -9.657 3.529 1.00 30.72 H ATOM 1153 HD2 PRO A 88 33.478 -7.319 4.039 1.00 31.11 H ATOM 1154 HD3 PRO A 88 35.141 -7.565 4.566 1.00 31.11 H ATOM 1155 N ILE A 89 32.637 -5.810 0.955 1.00 33.67 N ATOM 1156 CA ILE A 89 31.678 -4.963 0.237 1.00 32.79 C ATOM 1157 C ILE A 89 32.318 -3.647 -0.250 1.00 33.05 C ATOM 1158 O ILE A 89 32.088 -3.270 -1.398 1.00 33.90 O ATOM 1159 CB ILE A 89 30.408 -4.655 1.095 1.00 34.37 C ATOM 1160 CG1 ILE A 89 29.592 -5.944 1.343 1.00 34.88 C ATOM 1161 CG2 ILE A 89 29.476 -3.569 0.514 1.00 31.66 C ATOM 1162 CD1 ILE A 89 28.557 -5.817 2.473 1.00 40.21 C ATOM 1163 H ILE A 89 32.465 -5.932 1.943 1.00 33.67 H ATOM 1164 HA ILE A 89 31.357 -5.514 -0.649 1.00 32.79 H ATOM 1165 HB ILE A 89 30.747 -4.296 2.066 1.00 34.37 H ATOM 1166 HG13 ILE A 89 30.254 -6.776 1.582 1.00 34.88 H ATOM 1167 HG12 ILE A 89 29.083 -6.232 0.423 1.00 34.88 H ATOM 1168 HG21 ILE A 89 28.588 -3.427 1.130 1.00 31.66 H ATOM 1169 HG22 ILE A 89 29.954 -2.592 0.442 1.00 31.66 H ATOM 1170 HG23 ILE A 89 29.140 -3.861 -0.479 1.00 31.66 H ATOM 1171 HD11 ILE A 89 28.344 -6.790 2.915 1.00 40.21 H ATOM 1172 HD12 ILE A 89 28.909 -5.164 3.271 1.00 40.21 H ATOM 1173 HD13 ILE A 89 27.615 -5.412 2.109 1.00 40.21 H ATOM 1174 N LEU A 90 33.136 -3.007 0.606 1.00 34.40 N ATOM 1175 CA LEU A 90 33.893 -1.797 0.292 1.00 36.12 C ATOM 1176 C LEU A 90 34.934 -2.024 -0.812 1.00 36.86 C ATOM 1177 O LEU A 90 35.085 -1.142 -1.647 1.00 35.34 O ATOM 1178 CB LEU A 90 34.528 -1.192 1.569 1.00 35.83 C ATOM 1179 CG LEU A 90 35.307 0.134 1.353 1.00 37.20 C ATOM 1180 CD1 LEU A 90 34.436 1.251 0.742 1.00 39.93 C ATOM 1181 CD2 LEU A 90 36.004 0.598 2.643 1.00 37.31 C ATOM 1182 H LEU A 90 33.258 -3.378 1.541 1.00 34.40 H ATOM 1183 HA LEU A 90 33.165 -1.083 -0.095 1.00 36.12 H ATOM 1184 HB3 LEU A 90 35.196 -1.934 2.010 1.00 35.83 H ATOM 1185 HB2 LEU A 90 33.744 -1.024 2.310 1.00 35.83 H ATOM 1186 HG LEU A 90 36.119 -0.063 0.652 1.00 37.20 H ATOM 1187 HD11 LEU A 90 34.560 2.196 1.266 1.00 39.93 H ATOM 1188 HD12 LEU A 90 34.701 1.426 -0.301 1.00 39.93 H ATOM 1189 HD13 LEU A 90 33.373 1.013 0.776 1.00 39.93 H ATOM 1190 HD21 LEU A 90 36.930 1.130 2.418 1.00 37.31 H ATOM 1191 HD22 LEU A 90 35.375 1.265 3.234 1.00 37.31 H ATOM 1192 HD23 LEU A 90 36.270 -0.252 3.270 1.00 37.31 H ATOM 1193 N ASP A 91 35.598 -3.193 -0.840 1.00 36.65 N ATOM 1194 CA ASP A 91 36.536 -3.564 -1.910 1.00 39.50 C ATOM 1195 C ASP A 91 35.874 -3.637 -3.290 1.00 39.38 C ATOM 1196 O ASP A 91 36.474 -3.162 -4.251 1.00 39.21 O ATOM 1197 CB ASP A 91 37.327 -4.862 -1.621 1.00 39.23 C ATOM 1198 CG ASP A 91 38.243 -4.809 -0.389 1.00 42.38 C ATOM 1199 OD1 ASP A 91 38.630 -3.692 0.019 1.00 41.38 O ATOM 1200 OD2 ASP A 91 38.656 -5.900 0.061 1.00 43.09 O1- ATOM 1201 H ASP A 91 35.449 -3.878 -0.112 1.00 36.65 H ATOM 1202 HA ASP A 91 37.255 -2.745 -1.986 1.00 39.50 H ATOM 1203 HB3 ASP A 91 37.948 -5.118 -2.481 1.00 39.23 H ATOM 1204 HB2 ASP A 91 36.626 -5.687 -1.482 1.00 39.23 H ATOM 1205 N GLU A 92 34.636 -4.153 -3.357 1.00 38.83 N ATOM 1206 CA GLU A 92 33.822 -4.130 -4.570 1.00 39.48 C ATOM 1207 C GLU A 92 33.406 -2.704 -4.992 1.00 38.74 C ATOM 1208 O GLU A 92 33.427 -2.412 -6.187 1.00 36.80 O ATOM 1209 CB GLU A 92 32.677 -5.155 -4.437 1.00 41.28 C ATOM 1210 CG GLU A 92 31.664 -5.155 -5.606 1.00 42.07 C ATOM 1211 CD GLU A 92 30.783 -6.408 -5.738 1.00 44.04 C ATOM 1212 OE1 GLU A 92 31.165 -7.481 -5.219 1.00 41.66 O ATOM 1213 OE2 GLU A 92 29.716 -6.276 -6.378 1.00 43.65 O1- ATOM 1214 H GLU A 92 34.199 -4.522 -2.524 1.00 38.83 H ATOM 1215 HA GLU A 92 34.456 -4.501 -5.378 1.00 39.48 H ATOM 1216 HB3 GLU A 92 32.142 -5.003 -3.499 1.00 41.28 H ATOM 1217 HB2 GLU A 92 33.151 -6.134 -4.349 1.00 41.28 H ATOM 1218 HG3 GLU A 92 32.197 -5.039 -6.550 1.00 42.07 H ATOM 1219 HG2 GLU A 92 31.013 -4.287 -5.499 1.00 42.07 H ATOM 1220 N VAL A 93 33.139 -1.814 -4.019 1.00 37.58 N ATOM 1221 CA VAL A 93 32.923 -0.380 -4.251 1.00 39.39 C ATOM 1222 C VAL A 93 34.175 0.314 -4.837 1.00 39.94 C ATOM 1223 O VAL A 93 34.025 1.084 -5.783 1.00 38.57 O ATOM 1224 CB VAL A 93 32.449 0.365 -2.966 1.00 39.78 C ATOM 1225 CG1 VAL A 93 32.354 1.898 -3.088 1.00 38.88 C ATOM 1226 CG2 VAL A 93 31.106 -0.188 -2.478 1.00 39.30 C ATOM 1227 H VAL A 93 33.145 -2.116 -3.054 1.00 37.58 H ATOM 1228 HA VAL A 93 32.130 -0.298 -4.994 1.00 39.39 H ATOM 1229 HB VAL A 93 33.162 0.174 -2.172 1.00 39.78 H ATOM 1230 HG11 VAL A 93 31.929 2.340 -2.186 1.00 38.88 H ATOM 1231 HG12 VAL A 93 33.328 2.363 -3.237 1.00 38.88 H ATOM 1232 HG13 VAL A 93 31.716 2.176 -3.922 1.00 38.88 H ATOM 1233 HG21 VAL A 93 30.928 0.081 -1.439 1.00 39.30 H ATOM 1234 HG22 VAL A 93 30.281 0.183 -3.087 1.00 39.30 H ATOM 1235 HG23 VAL A 93 31.073 -1.272 -2.519 1.00 39.30 H ATOM 1236 N ILE A 94 35.381 -0.018 -4.332 1.00 39.41 N ATOM 1237 CA ILE A 94 36.664 0.464 -4.868 1.00 41.12 C ATOM 1238 C ILE A 94 36.959 -0.065 -6.295 1.00 42.53 C ATOM 1239 O ILE A 94 37.577 0.656 -7.077 1.00 42.63 O ATOM 1240 CB ILE A 94 37.881 0.141 -3.934 1.00 41.77 C ATOM 1241 CG1 ILE A 94 37.738 0.693 -2.491 1.00 41.96 C ATOM 1242 CG2 ILE A 94 39.247 0.594 -4.501 1.00 41.60 C ATOM 1243 CD1 ILE A 94 37.118 2.090 -2.355 1.00 42.93 C ATOM 1244 H ILE A 94 35.433 -0.655 -3.548 1.00 39.41 H ATOM 1245 HA ILE A 94 36.581 1.547 -4.959 1.00 41.12 H ATOM 1246 HB ILE A 94 37.938 -0.944 -3.835 1.00 41.77 H ATOM 1247 HG13 ILE A 94 38.703 0.678 -1.982 1.00 41.96 H ATOM 1248 HG12 ILE A 94 37.141 0.003 -1.907 1.00 41.96 H ATOM 1249 HG21 ILE A 94 40.053 0.409 -3.791 1.00 41.60 H ATOM 1250 HG22 ILE A 94 39.524 0.059 -5.409 1.00 41.60 H ATOM 1251 HG23 ILE A 94 39.249 1.660 -4.727 1.00 41.60 H ATOM 1252 HD11 ILE A 94 37.408 2.554 -1.412 1.00 42.93 H ATOM 1253 HD12 ILE A 94 37.428 2.758 -3.160 1.00 42.93 H ATOM 1254 HD13 ILE A 94 36.031 2.027 -2.368 1.00 42.93 H ATOM 1255 N MET A 95 36.451 -1.262 -6.647 1.00 42.42 N ATOM 1256 CA MET A 95 36.461 -1.797 -8.018 1.00 44.90 C ATOM 1257 C MET A 95 35.496 -1.076 -8.985 1.00 45.13 C ATOM 1258 O MET A 95 35.525 -1.380 -10.177 1.00 44.37 O ATOM 1259 CB MET A 95 36.185 -3.314 -8.011 1.00 46.53 C ATOM 1260 CG MET A 95 37.313 -4.150 -7.394 1.00 50.85 C ATOM 1261 SD MET A 95 36.937 -5.920 -7.288 1.00 55.62 S ATOM 1262 CE MET A 95 37.130 -6.386 -9.029 1.00 55.21 C ATOM 1263 H MET A 95 35.964 -1.817 -5.956 1.00 42.42 H ATOM 1264 HA MET A 95 37.461 -1.646 -8.428 1.00 44.90 H ATOM 1265 HB3 MET A 95 36.038 -3.661 -9.034 1.00 46.53 H ATOM 1266 HB2 MET A 95 35.251 -3.531 -7.499 1.00 46.53 H ATOM 1267 HG3 MET A 95 37.548 -3.798 -6.393 1.00 50.85 H ATOM 1268 HG2 MET A 95 38.227 -4.026 -7.975 1.00 50.85 H ATOM 1269 HE1 MET A 95 36.999 -7.462 -9.143 1.00 55.21 H ATOM 1270 HE2 MET A 95 36.388 -5.885 -9.650 1.00 55.21 H ATOM 1271 HE3 MET A 95 38.124 -6.120 -9.389 1.00 55.21 H ATOM 1272 N GLY A 96 34.701 -0.117 -8.485 1.00 43.95 N ATOM 1273 CA GLY A 96 33.850 0.740 -9.300 1.00 42.59 C ATOM 1274 C GLY A 96 32.426 0.183 -9.428 1.00 42.57 C ATOM 1275 O GLY A 96 31.765 0.478 -10.423 1.00 41.48 O ATOM 1276 H GLY A 96 34.728 0.080 -7.494 1.00 43.95 H ATOM 1277 HA3 GLY A 96 34.283 0.899 -10.288 1.00 42.59 H ATOM 1278 HA2 GLY A 96 33.806 1.714 -8.817 1.00 42.59 H ATOM 1279 N TYR A 97 31.959 -0.616 -8.453 1.00 41.65 N ATOM 1280 CA TYR A 97 30.594 -1.150 -8.403 1.00 41.71 C ATOM 1281 C TYR A 97 29.727 -0.365 -7.413 1.00 38.76 C ATOM 1282 O TYR A 97 30.233 0.370 -6.562 1.00 37.69 O ATOM 1283 CB TYR A 97 30.624 -2.643 -8.016 1.00 45.44 C ATOM 1284 CG TYR A 97 31.041 -3.583 -9.133 1.00 52.18 C ATOM 1285 CD1 TYR A 97 32.369 -3.594 -9.610 1.00 54.66 C ATOM 1286 CD2 TYR A 97 30.085 -4.446 -9.708 1.00 53.53 C ATOM 1287 CE1 TYR A 97 32.728 -4.436 -10.680 1.00 57.85 C ATOM 1288 CE2 TYR A 97 30.447 -5.296 -10.769 1.00 57.11 C ATOM 1289 CZ TYR A 97 31.765 -5.284 -11.263 1.00 58.28 C ATOM 1290 OH TYR A 97 32.105 -6.094 -12.307 1.00 60.52 O ATOM 1291 H TYR A 97 32.551 -0.842 -7.666 1.00 41.65 H ATOM 1292 HA TYR A 97 30.123 -1.070 -9.385 1.00 41.71 H ATOM 1293 HB3 TYR A 97 29.632 -2.965 -7.695 1.00 45.44 H ATOM 1294 HB2 TYR A 97 31.253 -2.798 -7.149 1.00 45.44 H ATOM 1295 HD1 TYR A 97 33.115 -2.953 -9.166 1.00 54.66 H ATOM 1296 HD2 TYR A 97 29.068 -4.456 -9.345 1.00 53.53 H ATOM 1297 HE1 TYR A 97 33.744 -4.428 -11.046 1.00 57.85 H ATOM 1298 HE2 TYR A 97 29.708 -5.950 -11.210 1.00 57.11 H ATOM 1299 HH TYR A 97 33.026 -6.009 -12.564 1.00 60.52 H ATOM 1300 N ASN A 98 28.411 -0.575 -7.554 1.00 36.08 N ATOM 1301 CA ASN A 98 27.384 -0.057 -6.660 1.00 33.17 C ATOM 1302 C ASN A 98 27.034 -1.142 -5.638 1.00 29.96 C ATOM 1303 O ASN A 98 26.784 -2.287 -6.022 1.00 27.65 O ATOM 1304 CB ASN A 98 26.144 0.359 -7.479 1.00 34.52 C ATOM 1305 CG ASN A 98 26.423 1.507 -8.460 1.00 37.68 C ATOM 1306 OD1 ASN A 98 27.249 2.378 -8.202 1.00 37.20 O ATOM 1307 ND2 ASN A 98 25.727 1.517 -9.596 1.00 36.60 N ATOM 1308 H ASN A 98 28.085 -1.200 -8.278 1.00 36.08 H ATOM 1309 HA ASN A 98 27.764 0.825 -6.148 1.00 33.17 H ATOM 1310 HB3 ASN A 98 25.353 0.691 -6.805 1.00 34.52 H ATOM 1311 HB2 ASN A 98 25.747 -0.499 -8.024 1.00 34.52 H ATOM 1312 HD22 ASN A 98 25.873 2.254 -10.270 1.00 36.60 H ATOM 1313 HD21 ASN A 98 25.081 0.767 -9.813 1.00 36.60 H ATOM 1314 N CYS A 99 27.016 -0.749 -4.358 1.00 28.42 N ATOM 1315 CA CYS A 99 26.696 -1.611 -3.225 1.00 26.99 C ATOM 1316 C CYS A 99 25.673 -0.908 -2.318 1.00 24.43 C ATOM 1317 O CYS A 99 25.582 0.320 -2.325 1.00 23.39 O ATOM 1318 CB CYS A 99 27.955 -1.985 -2.425 1.00 26.76 C ATOM 1319 SG CYS A 99 29.011 -3.136 -3.354 1.00 30.41 S ATOM 1320 H CYS A 99 27.243 0.211 -4.130 1.00 28.42 H ATOM 1321 HA CYS A 99 26.241 -2.526 -3.591 1.00 26.99 H ATOM 1322 HB3 CYS A 99 27.680 -2.458 -1.483 1.00 26.76 H ATOM 1323 HB2 CYS A 99 28.525 -1.090 -2.189 1.00 26.76 H ATOM 1324 HG CYS A 99 30.010 -3.165 -2.466 1.00 30.41 H ATOM 1325 N THR A 100 24.921 -1.703 -1.543 1.00 23.88 N ATOM 1326 CA THR A 100 23.961 -1.219 -0.553 1.00 23.96 C ATOM 1327 C THR A 100 23.948 -2.173 0.649 1.00 24.20 C ATOM 1328 O THR A 100 24.034 -3.385 0.467 1.00 24.93 O ATOM 1329 CB THR A 100 22.521 -1.117 -1.133 1.00 21.66 C ATOM 1330 OG1 THR A 100 22.493 -0.090 -2.101 1.00 23.67 O ATOM 1331 CG2 THR A 100 21.398 -0.804 -0.122 1.00 20.28 C ATOM 1332 H THR A 100 25.014 -2.708 -1.619 1.00 23.88 H ATOM 1333 HA THR A 100 24.284 -0.238 -0.213 1.00 23.96 H ATOM 1334 HB THR A 100 22.274 -2.046 -1.648 1.00 21.66 H ATOM 1335 HG1 THR A 100 21.640 -0.127 -2.550 1.00 23.67 H ATOM 1336 HG21 THR A 100 20.452 -0.608 -0.628 1.00 20.28 H ATOM 1337 HG22 THR A 100 21.223 -1.636 0.560 1.00 20.28 H ATOM 1338 HG23 THR A 100 21.637 0.074 0.478 1.00 20.28 H ATOM 1339 N ILE A 101 23.827 -1.612 1.859 1.00 23.51 N ATOM 1340 CA ILE A 101 23.663 -2.377 3.089 1.00 21.26 C ATOM 1341 C ILE A 101 22.478 -1.766 3.854 1.00 20.88 C ATOM 1342 O ILE A 101 22.540 -0.599 4.238 1.00 21.37 O ATOM 1343 CB ILE A 101 24.924 -2.353 4.005 1.00 21.03 C ATOM 1344 CG1 ILE A 101 26.227 -2.696 3.242 1.00 21.50 C ATOM 1345 CG2 ILE A 101 24.751 -3.311 5.208 1.00 19.72 C ATOM 1346 CD1 ILE A 101 27.506 -2.553 4.084 1.00 22.58 C ATOM 1347 H ILE A 101 23.786 -0.604 1.949 1.00 23.51 H ATOM 1348 HA ILE A 101 23.433 -3.418 2.864 1.00 21.26 H ATOM 1349 HB ILE A 101 25.049 -1.341 4.391 1.00 21.03 H ATOM 1350 HG13 ILE A 101 26.338 -2.050 2.372 1.00 21.50 H ATOM 1351 HG12 ILE A 101 26.162 -3.711 2.852 1.00 21.50 H ATOM 1352 HG21 ILE A 101 25.608 -3.268 5.879 1.00 19.72 H ATOM 1353 HG22 ILE A 101 23.874 -3.074 5.811 1.00 19.72 H ATOM 1354 HG23 ILE A 101 24.646 -4.344 4.877 1.00 19.72 H ATOM 1355 HD11 ILE A 101 28.371 -2.365 3.448 1.00 22.58 H ATOM 1356 HD12 ILE A 101 27.433 -1.726 4.791 1.00 22.58 H ATOM 1357 HD13 ILE A 101 27.708 -3.461 4.651 1.00 22.58 H ATOM 1358 N PHE A 102 21.428 -2.574 4.056 1.00 20.90 N ATOM 1359 CA PHE A 102 20.280 -2.239 4.896 1.00 21.42 C ATOM 1360 C PHE A 102 20.543 -2.625 6.359 1.00 22.24 C ATOM 1361 O PHE A 102 21.201 -3.632 6.615 1.00 22.50 O ATOM 1362 CB PHE A 102 19.023 -2.974 4.390 1.00 21.24 C ATOM 1363 CG PHE A 102 18.434 -2.482 3.079 1.00 24.65 C ATOM 1364 CD1 PHE A 102 17.545 -1.388 3.071 1.00 24.59 C ATOM 1365 CD2 PHE A 102 18.848 -3.032 1.847 1.00 23.12 C ATOM 1366 CE1 PHE A 102 17.011 -0.931 1.874 1.00 27.89 C ATOM 1367 CE2 PHE A 102 18.315 -2.550 0.657 1.00 26.02 C ATOM 1368 CZ PHE A 102 17.391 -1.513 0.671 1.00 25.24 C ATOM 1369 H PHE A 102 21.449 -3.517 3.690 1.00 20.90 H ATOM 1370 HA PHE A 102 20.086 -1.169 4.849 1.00 21.42 H ATOM 1371 HB3 PHE A 102 18.231 -2.908 5.138 1.00 21.24 H ATOM 1372 HB2 PHE A 102 19.243 -4.035 4.295 1.00 21.24 H ATOM 1373 HD1 PHE A 102 17.263 -0.913 3.999 1.00 24.59 H ATOM 1374 HD2 PHE A 102 19.564 -3.840 1.828 1.00 23.12 H ATOM 1375 HE1 PHE A 102 16.305 -0.114 1.877 1.00 27.89 H ATOM 1376 HE2 PHE A 102 18.617 -2.981 -0.285 1.00 26.02 H ATOM 1377 HZ PHE A 102 16.978 -1.148 -0.258 1.00 25.24 H ATOM 1378 N ALA A 103 19.945 -1.860 7.281 1.00 19.47 N ATOM 1379 CA ALA A 103 19.755 -2.227 8.677 1.00 20.05 C ATOM 1380 C ALA A 103 18.246 -2.264 8.921 1.00 19.29 C ATOM 1381 O ALA A 103 17.575 -1.250 8.726 1.00 18.27 O ATOM 1382 CB ALA A 103 20.464 -1.237 9.610 1.00 18.35 C ATOM 1383 H ALA A 103 19.478 -1.012 6.990 1.00 19.47 H ATOM 1384 HA ALA A 103 20.173 -3.213 8.870 1.00 20.05 H ATOM 1385 HB1 ALA A 103 20.191 -1.415 10.649 1.00 18.35 H ATOM 1386 HB2 ALA A 103 21.543 -1.363 9.545 1.00 18.35 H ATOM 1387 HB3 ALA A 103 20.232 -0.200 9.375 1.00 18.35 H ATOM 1388 N TYR A 104 17.754 -3.448 9.308 1.00 17.95 N ATOM 1389 CA TYR A 104 16.345 -3.736 9.559 1.00 19.33 C ATOM 1390 C TYR A 104 16.200 -4.308 10.975 1.00 20.55 C ATOM 1391 O TYR A 104 17.114 -4.974 11.451 1.00 22.06 O ATOM 1392 CB TYR A 104 15.845 -4.732 8.486 1.00 18.75 C ATOM 1393 CG TYR A 104 14.369 -5.088 8.581 1.00 19.21 C ATOM 1394 CD1 TYR A 104 13.953 -6.183 9.364 1.00 21.30 C ATOM 1395 CD2 TYR A 104 13.402 -4.303 7.921 1.00 20.16 C ATOM 1396 CE1 TYR A 104 12.582 -6.462 9.515 1.00 21.55 C ATOM 1397 CE2 TYR A 104 12.031 -4.588 8.061 1.00 20.84 C ATOM 1398 CZ TYR A 104 11.621 -5.671 8.861 1.00 22.27 C ATOM 1399 OH TYR A 104 10.296 -5.965 8.993 1.00 22.91 O ATOM 1400 H TYR A 104 18.392 -4.217 9.471 1.00 17.95 H ATOM 1401 HA TYR A 104 15.759 -2.819 9.496 1.00 19.33 H ATOM 1402 HB3 TYR A 104 16.428 -5.655 8.536 1.00 18.75 H ATOM 1403 HB2 TYR A 104 16.032 -4.326 7.491 1.00 18.75 H ATOM 1404 HD1 TYR A 104 14.685 -6.793 9.871 1.00 21.30 H ATOM 1405 HD2 TYR A 104 13.708 -3.467 7.319 1.00 20.16 H ATOM 1406 HE1 TYR A 104 12.267 -7.288 10.129 1.00 21.55 H ATOM 1407 HE2 TYR A 104 11.300 -3.979 7.551 1.00 20.84 H ATOM 1408 HH TYR A 104 9.725 -5.398 8.471 1.00 22.91 H ATOM 1409 N GLY A 105 15.040 -4.081 11.605 1.00 19.26 N ATOM 1410 CA GLY A 105 14.725 -4.644 12.911 1.00 21.52 C ATOM 1411 C GLY A 105 13.948 -3.638 13.755 1.00 20.28 C ATOM 1412 O GLY A 105 13.716 -2.494 13.358 1.00 18.68 O ATOM 1413 H GLY A 105 14.335 -3.496 11.171 1.00 19.26 H ATOM 1414 HA3 GLY A 105 15.626 -4.913 13.463 1.00 21.52 H ATOM 1415 HA2 GLY A 105 14.135 -5.550 12.776 1.00 21.52 H ATOM 1416 N GLN A 106 13.532 -4.107 14.940 1.00 21.44 N ATOM 1417 CA GLN A 106 12.794 -3.351 15.948 1.00 20.84 C ATOM 1418 C GLN A 106 13.602 -2.165 16.513 1.00 21.07 C ATOM 1419 O GLN A 106 14.830 -2.189 16.500 1.00 21.08 O ATOM 1420 CB GLN A 106 12.285 -4.341 17.023 1.00 22.65 C ATOM 1421 CG GLN A 106 11.686 -3.716 18.302 1.00 25.55 C ATOM 1422 CD GLN A 106 11.212 -4.756 19.314 1.00 28.83 C ATOM 1423 OE1 GLN A 106 11.800 -5.827 19.446 1.00 30.01 O ATOM 1424 NE2 GLN A 106 10.160 -4.423 20.062 1.00 30.80 N ATOM 1425 H GLN A 106 13.737 -5.069 15.184 1.00 21.44 H ATOM 1426 HA GLN A 106 11.921 -2.955 15.433 1.00 20.84 H ATOM 1427 HB3 GLN A 106 13.097 -5.003 17.309 1.00 22.65 H ATOM 1428 HB2 GLN A 106 11.533 -4.986 16.564 1.00 22.65 H ATOM 1429 HG3 GLN A 106 10.860 -3.055 18.037 1.00 25.55 H ATOM 1430 HG2 GLN A 106 12.430 -3.114 18.820 1.00 25.55 H ATOM 1431 HE22 GLN A 106 9.782 -5.072 20.738 1.00 30.80 H ATOM 1432 HE21 GLN A 106 9.710 -3.527 19.937 1.00 30.80 H ATOM 1433 N THR A 107 12.892 -1.140 17.001 1.00 22.00 N ATOM 1434 CA THR A 107 13.447 0.056 17.620 1.00 22.73 C ATOM 1435 C THR A 107 14.171 -0.302 18.923 1.00 24.87 C ATOM 1436 O THR A 107 13.597 -0.965 19.788 1.00 22.44 O ATOM 1437 CB THR A 107 12.342 1.100 17.933 1.00 22.42 C ATOM 1438 OG1 THR A 107 11.751 1.514 16.718 1.00 21.89 O ATOM 1439 CG2 THR A 107 12.816 2.371 18.664 1.00 22.99 C ATOM 1440 H THR A 107 11.882 -1.188 16.966 1.00 22.00 H ATOM 1441 HA THR A 107 14.161 0.483 16.918 1.00 22.73 H ATOM 1442 HB THR A 107 11.556 0.631 18.527 1.00 22.42 H ATOM 1443 HG1 THR A 107 10.878 1.871 16.912 1.00 21.89 H ATOM 1444 HG21 THR A 107 12.005 3.093 18.758 1.00 22.99 H ATOM 1445 HG22 THR A 107 13.164 2.156 19.675 1.00 22.99 H ATOM 1446 HG23 THR A 107 13.633 2.857 18.128 1.00 22.99 H ATOM 1447 N GLY A 108 15.426 0.146 19.009 1.00 25.38 N ATOM 1448 CA GLY A 108 16.298 -0.095 20.144 1.00 25.41 C ATOM 1449 C GLY A 108 17.017 -1.451 20.065 1.00 23.92 C ATOM 1450 O GLY A 108 17.517 -1.888 21.099 1.00 21.87 O ATOM 1451 H GLY A 108 15.804 0.707 18.251 1.00 25.38 H ATOM 1452 HA3 GLY A 108 15.743 -0.023 21.081 1.00 25.41 H ATOM 1453 HA2 GLY A 108 17.032 0.707 20.154 1.00 25.41 H ATOM 1454 N THR A 109 17.076 -2.123 18.898 1.00 21.42 N ATOM 1455 CA THR A 109 17.781 -3.405 18.737 1.00 22.55 C ATOM 1456 C THR A 109 19.199 -3.267 18.150 1.00 24.86 C ATOM 1457 O THR A 109 19.950 -4.237 18.261 1.00 23.18 O ATOM 1458 CB THR A 109 16.997 -4.425 17.881 1.00 25.44 C ATOM 1459 OG1 THR A 109 16.842 -4.014 16.541 1.00 25.10 O ATOM 1460 CG2 THR A 109 15.633 -4.772 18.479 1.00 23.33 C ATOM 1461 H THR A 109 16.676 -1.715 18.062 1.00 21.42 H ATOM 1462 HA THR A 109 17.907 -3.876 19.711 1.00 22.55 H ATOM 1463 HB THR A 109 17.569 -5.351 17.845 1.00 25.44 H ATOM 1464 HG1 THR A 109 16.186 -3.307 16.514 1.00 25.10 H ATOM 1465 HG21 THR A 109 15.155 -5.552 17.892 1.00 23.33 H ATOM 1466 HG22 THR A 109 15.742 -5.149 19.493 1.00 23.33 H ATOM 1467 HG23 THR A 109 14.966 -3.911 18.523 1.00 23.33 H ATOM 1468 N GLY A 110 19.571 -2.092 17.614 1.00 22.69 N ATOM 1469 CA GLY A 110 20.961 -1.794 17.276 1.00 22.97 C ATOM 1470 C GLY A 110 21.173 -1.403 15.813 1.00 23.46 C ATOM 1471 O GLY A 110 22.295 -1.577 15.341 1.00 22.88 O ATOM 1472 H GLY A 110 18.894 -1.346 17.498 1.00 22.69 H ATOM 1473 HA3 GLY A 110 21.636 -2.620 17.506 1.00 22.97 H ATOM 1474 HA2 GLY A 110 21.290 -0.967 17.897 1.00 22.97 H ATOM 1475 N LYS A 111 20.159 -0.894 15.085 1.00 19.23 N ATOM 1476 CA LYS A 111 20.320 -0.437 13.696 1.00 20.76 C ATOM 1477 C LYS A 111 21.287 0.753 13.576 1.00 20.44 C ATOM 1478 O LYS A 111 22.252 0.649 12.821 1.00 21.60 O ATOM 1479 CB LYS A 111 18.975 -0.072 13.046 1.00 18.15 C ATOM 1480 CG LYS A 111 17.980 -1.229 12.902 1.00 21.24 C ATOM 1481 CD LYS A 111 16.680 -0.802 12.193 1.00 20.68 C ATOM 1482 CE LYS A 111 15.860 0.293 12.895 1.00 18.44 C ATOM 1483 NZ LYS A 111 15.512 -0.068 14.276 1.00 18.27 N1+ ATOM 1484 H LYS A 111 19.254 -0.729 15.516 1.00 19.23 H ATOM 1485 HA LYS A 111 20.746 -1.266 13.128 1.00 20.76 H ATOM 1486 HB3 LYS A 111 19.175 0.306 12.045 1.00 18.15 H ATOM 1487 HB2 LYS A 111 18.514 0.747 13.593 1.00 18.15 H ATOM 1488 HG3 LYS A 111 17.754 -1.645 13.883 1.00 21.24 H ATOM 1489 HG2 LYS A 111 18.443 -2.037 12.336 1.00 21.24 H ATOM 1490 HD3 LYS A 111 16.047 -1.674 12.051 1.00 20.68 H ATOM 1491 HD2 LYS A 111 16.922 -0.454 11.189 1.00 20.68 H ATOM 1492 HE3 LYS A 111 14.929 0.454 12.353 1.00 18.44 H ATOM 1493 HE2 LYS A 111 16.395 1.242 12.901 1.00 18.44 H ATOM 1494 HZ1 LYS A 111 16.356 -0.186 14.826 1.00 18.27 H ATOM 1495 HZ2 LYS A 111 14.963 0.677 14.684 1.00 18.27 H ATOM 1496 HZ3 LYS A 111 14.983 -0.929 14.281 1.00 18.27 H ATOM 1497 N THR A 112 21.037 1.827 14.348 1.00 20.23 N ATOM 1498 CA THR A 112 21.883 3.023 14.425 1.00 21.91 C ATOM 1499 C THR A 112 23.283 2.719 14.991 1.00 21.96 C ATOM 1500 O THR A 112 24.266 3.230 14.460 1.00 20.36 O ATOM 1501 CB THR A 112 21.250 4.137 15.307 1.00 23.15 C ATOM 1502 OG1 THR A 112 19.962 4.458 14.824 1.00 24.85 O ATOM 1503 CG2 THR A 112 22.054 5.448 15.386 1.00 22.97 C ATOM 1504 H THR A 112 20.204 1.838 14.930 1.00 20.23 H ATOM 1505 HA THR A 112 22.007 3.408 13.411 1.00 21.91 H ATOM 1506 HB THR A 112 21.113 3.767 16.322 1.00 23.15 H ATOM 1507 HG1 THR A 112 19.384 3.697 14.974 1.00 24.85 H ATOM 1508 HG21 THR A 112 21.507 6.208 15.946 1.00 22.97 H ATOM 1509 HG22 THR A 112 23.015 5.318 15.883 1.00 22.97 H ATOM 1510 HG23 THR A 112 22.242 5.845 14.389 1.00 22.97 H ATOM 1511 N PHE A 113 23.354 1.861 16.023 1.00 22.76 N ATOM 1512 CA PHE A 113 24.592 1.384 16.635 1.00 23.80 C ATOM 1513 C PHE A 113 25.478 0.622 15.637 1.00 21.95 C ATOM 1514 O PHE A 113 26.684 0.843 15.619 1.00 22.14 O ATOM 1515 CB PHE A 113 24.269 0.536 17.883 1.00 23.71 C ATOM 1516 CG PHE A 113 25.481 0.078 18.677 1.00 26.76 C ATOM 1517 CD1 PHE A 113 26.063 0.946 19.624 1.00 27.02 C ATOM 1518 CD2 PHE A 113 26.141 -1.129 18.359 1.00 26.47 C ATOM 1519 CE1 PHE A 113 27.228 0.578 20.283 1.00 27.82 C ATOM 1520 CE2 PHE A 113 27.308 -1.475 19.024 1.00 29.17 C ATOM 1521 CZ PHE A 113 27.843 -0.632 19.988 1.00 28.08 C ATOM 1522 H PHE A 113 22.490 1.526 16.442 1.00 22.76 H ATOM 1523 HA PHE A 113 25.145 2.267 16.963 1.00 23.80 H ATOM 1524 HB3 PHE A 113 23.679 -0.338 17.603 1.00 23.71 H ATOM 1525 HB2 PHE A 113 23.637 1.118 18.554 1.00 23.71 H ATOM 1526 HD1 PHE A 113 25.601 1.897 19.842 1.00 27.02 H ATOM 1527 HD2 PHE A 113 25.737 -1.787 17.604 1.00 26.47 H ATOM 1528 HE1 PHE A 113 27.658 1.237 21.023 1.00 27.82 H ATOM 1529 HE2 PHE A 113 27.800 -2.408 18.796 1.00 29.17 H ATOM 1530 HZ PHE A 113 28.744 -0.921 20.505 1.00 28.08 H ATOM 1531 N THR A 114 24.870 -0.227 14.795 1.00 21.64 N ATOM 1532 CA THR A 114 25.576 -0.934 13.733 1.00 22.49 C ATOM 1533 C THR A 114 26.054 0.029 12.631 1.00 24.03 C ATOM 1534 O THR A 114 27.251 0.055 12.356 1.00 20.85 O ATOM 1535 CB THR A 114 24.714 -2.051 13.092 1.00 24.26 C ATOM 1536 OG1 THR A 114 24.377 -3.012 14.073 1.00 21.97 O ATOM 1537 CG2 THR A 114 25.388 -2.795 11.930 1.00 22.94 C ATOM 1538 H THR A 114 23.869 -0.367 14.852 1.00 21.64 H ATOM 1539 HA THR A 114 26.462 -1.396 14.170 1.00 22.49 H ATOM 1540 HB THR A 114 23.774 -1.629 12.732 1.00 24.26 H ATOM 1541 HG1 THR A 114 23.727 -2.617 14.666 1.00 21.97 H ATOM 1542 HG21 THR A 114 24.766 -3.619 11.597 1.00 22.94 H ATOM 1543 HG22 THR A 114 25.531 -2.149 11.065 1.00 22.94 H ATOM 1544 HG23 THR A 114 26.358 -3.198 12.221 1.00 22.94 H ATOM 1545 N MET A 115 25.125 0.805 12.046 1.00 23.61 N ATOM 1546 CA MET A 115 25.385 1.675 10.898 1.00 25.56 C ATOM 1547 C MET A 115 26.330 2.850 11.186 1.00 25.01 C ATOM 1548 O MET A 115 27.101 3.210 10.302 1.00 22.73 O ATOM 1549 CB MET A 115 24.050 2.181 10.296 1.00 28.20 C ATOM 1550 CG MET A 115 23.882 1.813 8.819 1.00 36.97 C ATOM 1551 SD MET A 115 23.787 0.024 8.540 1.00 41.03 S ATOM 1552 CE MET A 115 24.716 -0.077 7.001 1.00 40.29 C ATOM 1553 H MET A 115 24.161 0.751 12.351 1.00 23.61 H ATOM 1554 HA MET A 115 25.889 1.049 10.161 1.00 25.56 H ATOM 1555 HB3 MET A 115 23.960 3.262 10.401 1.00 28.20 H ATOM 1556 HB2 MET A 115 23.194 1.784 10.837 1.00 28.20 H ATOM 1557 HG3 MET A 115 24.714 2.230 8.252 1.00 36.97 H ATOM 1558 HG2 MET A 115 22.978 2.270 8.415 1.00 36.97 H ATOM 1559 HE1 MET A 115 24.860 -1.119 6.736 1.00 40.29 H ATOM 1560 HE2 MET A 115 24.180 0.428 6.199 1.00 40.29 H ATOM 1561 HE3 MET A 115 25.697 0.381 7.124 1.00 40.29 H ATOM 1562 N GLU A 116 26.241 3.432 12.389 1.00 24.06 N ATOM 1563 CA GLU A 116 26.899 4.688 12.749 1.00 25.23 C ATOM 1564 C GLU A 116 27.826 4.525 13.943 1.00 25.96 C ATOM 1565 O GLU A 116 28.910 5.108 13.950 1.00 25.46 O ATOM 1566 CB GLU A 116 25.842 5.731 13.139 1.00 25.27 C ATOM 1567 CG GLU A 116 24.681 5.814 12.145 1.00 28.22 C ATOM 1568 CD GLU A 116 23.925 7.134 12.194 1.00 28.85 C ATOM 1569 OE1 GLU A 116 23.921 7.810 13.248 1.00 30.85 O ATOM 1570 OE2 GLU A 116 23.365 7.458 11.130 1.00 32.46 O1- ATOM 1571 H GLU A 116 25.565 3.083 13.058 1.00 24.06 H ATOM 1572 HA GLU A 116 27.482 5.077 11.912 1.00 25.23 H ATOM 1573 HB3 GLU A 116 26.339 6.696 13.227 1.00 25.27 H ATOM 1574 HB2 GLU A 116 25.435 5.536 14.133 1.00 25.27 H ATOM 1575 HG3 GLU A 116 23.969 5.011 12.337 1.00 28.22 H ATOM 1576 HG2 GLU A 116 25.051 5.652 11.135 1.00 28.22 H ATOM 1577 N GLY A 117 27.354 3.768 14.944 1.00 24.48 N ATOM 1578 CA GLY A 117 27.987 3.678 16.245 1.00 25.32 C ATOM 1579 C GLY A 117 27.735 4.949 17.053 1.00 27.26 C ATOM 1580 O GLY A 117 26.839 5.745 16.765 1.00 27.39 O ATOM 1581 H GLY A 117 26.444 3.337 14.849 1.00 24.48 H ATOM 1582 HA3 GLY A 117 29.054 3.530 16.112 1.00 25.32 H ATOM 1583 HA2 GLY A 117 27.601 2.831 16.808 1.00 25.32 H ATOM 1584 N GLU A 118 28.550 5.102 18.096 1.00 28.11 N ATOM 1585 CA GLU A 118 28.487 6.196 19.053 1.00 28.54 C ATOM 1586 C GLU A 118 29.873 6.386 19.675 1.00 29.30 C ATOM 1587 O GLU A 118 30.763 5.558 19.483 1.00 27.87 O ATOM 1588 CB GLU A 118 27.388 5.893 20.096 1.00 31.14 C ATOM 1589 CG GLU A 118 27.600 4.600 20.918 1.00 32.60 C ATOM 1590 CD GLU A 118 26.412 4.280 21.833 1.00 34.85 C ATOM 1591 OE1 GLU A 118 25.272 4.234 21.316 1.00 33.99 O ATOM 1592 OE2 GLU A 118 26.658 4.072 23.040 1.00 36.88 O1- ATOM 1593 H GLU A 118 29.272 4.415 18.270 1.00 28.11 H ATOM 1594 HA GLU A 118 28.238 7.120 18.528 1.00 28.54 H ATOM 1595 HB3 GLU A 118 26.429 5.861 19.577 1.00 31.14 H ATOM 1596 HB2 GLU A 118 27.307 6.731 20.788 1.00 31.14 H ATOM 1597 HG3 GLU A 118 28.514 4.679 21.509 1.00 32.60 H ATOM 1598 HG2 GLU A 118 27.741 3.746 20.254 1.00 32.60 H ATOM 1599 N ARG A 119 30.028 7.492 20.411 1.00 28.64 N ATOM 1600 CA ARG A 119 31.229 7.764 21.190 1.00 31.10 C ATOM 1601 C ARG A 119 31.181 7.022 22.530 1.00 30.49 C ATOM 1602 O ARG A 119 30.154 7.060 23.212 1.00 30.81 O ATOM 1603 CB ARG A 119 31.395 9.287 21.404 1.00 31.76 C ATOM 1604 CG ARG A 119 31.425 10.139 20.114 1.00 32.25 C ATOM 1605 CD ARG A 119 32.334 9.605 18.990 1.00 35.36 C ATOM 1606 NE ARG A 119 33.708 9.358 19.453 1.00 36.57 N ATOM 1607 CZ ARG A 119 34.644 10.249 19.821 1.00 34.93 C ATOM 1608 NH1 ARG A 119 34.510 11.570 19.649 1.00 36.05 N ATOM 1609 NH2 ARG A 119 35.750 9.786 20.404 1.00 36.63 N1+ ATOM 1610 H ARG A 119 29.262 8.140 20.519 1.00 28.64 H ATOM 1611 HA ARG A 119 32.092 7.396 20.634 1.00 31.10 H ATOM 1612 HB3 ARG A 119 32.321 9.460 21.955 1.00 31.76 H ATOM 1613 HB2 ARG A 119 30.610 9.670 22.054 1.00 31.76 H ATOM 1614 HG3 ARG A 119 31.628 11.190 20.323 1.00 32.25 H ATOM 1615 HG2 ARG A 119 30.407 10.127 19.723 1.00 32.25 H ATOM 1616 HD3 ARG A 119 32.416 10.358 18.212 1.00 35.36 H ATOM 1617 HD2 ARG A 119 31.894 8.735 18.510 1.00 35.36 H ATOM 1618 HE ARG A 119 33.910 8.387 19.662 1.00 36.57 H ATOM 1619 HH12 ARG A 119 35.227 12.208 19.963 1.00 36.05 H ATOM 1620 HH11 ARG A 119 33.688 11.937 19.185 1.00 36.05 H ATOM 1621 HH22 ARG A 119 36.471 10.409 20.742 1.00 36.63 H ATOM 1622 HH21 ARG A 119 35.849 8.793 20.574 1.00 36.63 H ATOM 1623 N SER A 120 32.322 6.419 22.899 1.00 32.22 N ATOM 1624 CA SER A 120 32.587 5.871 24.228 1.00 32.57 C ATOM 1625 C SER A 120 32.531 7.002 25.279 1.00 32.68 C ATOM 1626 O SER A 120 33.111 8.060 25.020 1.00 31.36 O ATOM 1627 CB SER A 120 33.986 5.226 24.243 1.00 32.71 C ATOM 1628 OG SER A 120 33.976 3.966 23.608 1.00 34.94 O ATOM 1629 H SER A 120 33.108 6.418 22.259 1.00 32.22 H ATOM 1630 HA SER A 120 31.849 5.097 24.407 1.00 32.57 H ATOM 1631 HB3 SER A 120 34.331 5.067 25.266 1.00 32.71 H ATOM 1632 HB2 SER A 120 34.717 5.867 23.761 1.00 32.71 H ATOM 1633 HG SER A 120 33.912 4.110 22.657 1.00 34.94 H ATOM 1634 N PRO A 121 31.827 6.786 26.416 1.00 34.84 N ATOM 1635 CA PRO A 121 31.739 7.769 27.517 1.00 37.38 C ATOM 1636 C PRO A 121 33.075 8.361 28.004 1.00 39.81 C ATOM 1637 O PRO A 121 34.088 7.662 28.018 1.00 39.38 O ATOM 1638 CB PRO A 121 31.059 6.978 28.647 1.00 38.04 C ATOM 1639 CG PRO A 121 30.200 5.954 27.933 1.00 38.85 C ATOM 1640 CD PRO A 121 31.046 5.584 26.725 1.00 35.74 C ATOM 1641 HA PRO A 121 31.078 8.569 27.179 1.00 37.38 H ATOM 1642 HB3 PRO A 121 30.475 7.613 29.313 1.00 38.04 H ATOM 1643 HB2 PRO A 121 31.801 6.457 29.255 1.00 38.04 H ATOM 1644 HG3 PRO A 121 29.278 6.431 27.598 1.00 38.85 H ATOM 1645 HG2 PRO A 121 29.932 5.099 28.554 1.00 38.85 H ATOM 1646 HD2 PRO A 121 31.729 4.767 26.962 1.00 35.74 H ATOM 1647 HD3 PRO A 121 30.387 5.270 25.915 1.00 35.74 H ATOM 1648 N ASN A 122 33.023 9.640 28.414 1.00 41.25 N ATOM 1649 CA ASN A 122 34.096 10.377 29.097 1.00 43.22 C ATOM 1650 C ASN A 122 35.334 10.693 28.223 1.00 44.35 C ATOM 1651 O ASN A 122 36.402 10.950 28.778 1.00 44.32 O ATOM 1652 CB ASN A 122 34.481 9.651 30.421 1.00 42.57 C ATOM 1653 CG ASN A 122 35.081 10.549 31.509 1.00 44.13 C ATOM 1654 OD1 ASN A 122 34.754 11.729 31.616 1.00 43.28 O ATOM 1655 ND2 ASN A 122 35.964 9.982 32.334 1.00 42.61 N ATOM 1656 H ASN A 122 32.146 10.134 28.344 1.00 41.25 H ATOM 1657 HA ASN A 122 33.708 11.369 29.330 1.00 43.22 H ATOM 1658 HB3 ASN A 122 35.141 8.804 30.221 1.00 42.57 H ATOM 1659 HB2 ASN A 122 33.580 9.230 30.870 1.00 42.57 H ATOM 1660 HD22 ASN A 122 36.390 10.528 33.068 1.00 42.61 H ATOM 1661 HD21 ASN A 122 36.221 9.012 32.222 1.00 42.61 H ATOM 1662 N GLU A 123 35.182 10.689 26.884 1.00 44.87 N ATOM 1663 CA GLU A 123 36.237 10.983 25.900 1.00 45.91 C ATOM 1664 C GLU A 123 37.492 10.091 26.054 1.00 45.85 C ATOM 1665 O GLU A 123 38.608 10.613 26.022 1.00 45.69 O ATOM 1666 CB GLU A 123 36.618 12.488 25.904 1.00 46.51 C ATOM 1667 CG GLU A 123 35.465 13.470 25.625 1.00 49.83 C ATOM 1668 CD GLU A 123 35.978 14.909 25.460 1.00 51.36 C ATOM 1669 OE1 GLU A 123 36.522 15.450 26.449 1.00 52.20 O ATOM 1670 OE2 GLU A 123 35.824 15.447 24.341 1.00 52.40 O1- ATOM 1671 H GLU A 123 34.277 10.463 26.499 1.00 44.87 H ATOM 1672 HA GLU A 123 35.817 10.750 24.921 1.00 45.91 H ATOM 1673 HB3 GLU A 123 37.388 12.660 25.149 1.00 46.51 H ATOM 1674 HB2 GLU A 123 37.082 12.744 26.858 1.00 46.51 H ATOM 1675 HG3 GLU A 123 34.742 13.446 26.442 1.00 49.83 H ATOM 1676 HG2 GLU A 123 34.926 13.158 24.729 1.00 49.83 H ATOM 1677 N GLU A 124 37.301 8.770 26.239 1.00 45.90 N ATOM 1678 CA GLU A 124 38.400 7.801 26.356 1.00 46.68 C ATOM 1679 C GLU A 124 39.345 7.778 25.144 1.00 46.72 C ATOM 1680 O GLU A 124 40.561 7.776 25.328 1.00 46.68 O ATOM 1681 CB GLU A 124 37.866 6.373 26.591 1.00 48.60 C ATOM 1682 CG GLU A 124 37.466 6.069 28.046 1.00 51.23 C ATOM 1683 CD GLU A 124 37.313 4.561 28.298 1.00 52.35 C ATOM 1684 OE1 GLU A 124 38.315 3.834 28.112 1.00 52.94 O ATOM 1685 OE2 GLU A 124 36.197 4.153 28.687 1.00 53.19 O1- ATOM 1686 H GLU A 124 36.364 8.397 26.284 1.00 45.90 H ATOM 1687 HA GLU A 124 39.004 8.092 27.218 1.00 46.68 H ATOM 1688 HB3 GLU A 124 38.611 5.649 26.254 1.00 48.60 H ATOM 1689 HB2 GLU A 124 36.994 6.206 25.958 1.00 48.60 H ATOM 1690 HG3 GLU A 124 36.548 6.602 28.299 1.00 51.23 H ATOM 1691 HG2 GLU A 124 38.231 6.442 28.728 1.00 51.23 H ATOM 1692 N TYR A 125 38.753 7.747 23.944 1.00 44.20 N ATOM 1693 CA TYR A 125 39.460 7.603 22.678 1.00 43.39 C ATOM 1694 C TYR A 125 39.227 8.852 21.824 1.00 43.25 C ATOM 1695 O TYR A 125 38.278 9.603 22.054 1.00 43.62 O ATOM 1696 CB TYR A 125 38.926 6.355 21.932 1.00 43.13 C ATOM 1697 CG TYR A 125 38.839 5.088 22.766 1.00 42.67 C ATOM 1698 CD1 TYR A 125 37.653 4.810 23.472 1.00 41.89 C ATOM 1699 CD2 TYR A 125 39.932 4.203 22.861 1.00 42.68 C ATOM 1700 CE1 TYR A 125 37.562 3.675 24.298 1.00 41.87 C ATOM 1701 CE2 TYR A 125 39.838 3.056 23.677 1.00 40.06 C ATOM 1702 CZ TYR A 125 38.658 2.799 24.404 1.00 41.85 C ATOM 1703 OH TYR A 125 38.576 1.706 25.216 1.00 42.69 O ATOM 1704 H TYR A 125 37.745 7.806 23.885 1.00 44.20 H ATOM 1705 HA TYR A 125 40.534 7.488 22.833 1.00 43.39 H ATOM 1706 HB3 TYR A 125 39.537 6.153 21.052 1.00 43.13 H ATOM 1707 HB2 TYR A 125 37.923 6.559 21.551 1.00 43.13 H ATOM 1708 HD1 TYR A 125 36.819 5.489 23.400 1.00 41.89 H ATOM 1709 HD2 TYR A 125 40.845 4.406 22.320 1.00 42.68 H ATOM 1710 HE1 TYR A 125 36.654 3.487 24.852 1.00 41.87 H ATOM 1711 HE2 TYR A 125 40.679 2.383 23.755 1.00 40.06 H ATOM 1712 HH TYR A 125 37.807 1.727 25.790 1.00 42.69 H ATOM 1713 N THR A 126 40.058 8.987 20.785 1.00 42.92 N ATOM 1714 CA THR A 126 39.752 9.778 19.596 1.00 43.57 C ATOM 1715 C THR A 126 38.758 8.984 18.710 1.00 42.84 C ATOM 1716 O THR A 126 38.630 7.772 18.894 1.00 42.17 O ATOM 1717 CB THR A 126 41.062 10.065 18.818 1.00 44.90 C ATOM 1718 OG1 THR A 126 41.562 8.932 18.130 1.00 44.67 O ATOM 1719 CG2 THR A 126 42.184 10.664 19.681 1.00 45.17 C ATOM 1720 H THR A 126 40.829 8.343 20.678 1.00 42.92 H ATOM 1721 HA THR A 126 39.292 10.725 19.888 1.00 43.57 H ATOM 1722 HB THR A 126 40.825 10.817 18.067 1.00 44.90 H ATOM 1723 HG1 THR A 126 41.244 8.977 17.222 1.00 44.67 H ATOM 1724 HG21 THR A 126 43.038 10.945 19.066 1.00 45.17 H ATOM 1725 HG22 THR A 126 41.843 11.560 20.200 1.00 45.17 H ATOM 1726 HG23 THR A 126 42.542 9.958 20.431 1.00 45.17 H ATOM 1727 N TRP A 127 38.039 9.657 17.792 1.00 42.95 N ATOM 1728 CA TRP A 127 36.971 9.026 16.996 1.00 43.84 C ATOM 1729 C TRP A 127 37.456 7.869 16.094 1.00 44.40 C ATOM 1730 O TRP A 127 36.702 6.923 15.878 1.00 42.80 O ATOM 1731 CB TRP A 127 36.197 10.097 16.200 1.00 42.89 C ATOM 1732 CG TRP A 127 36.894 10.708 15.021 1.00 42.66 C ATOM 1733 CD1 TRP A 127 37.614 11.851 15.050 1.00 44.16 C ATOM 1734 CD2 TRP A 127 37.031 10.178 13.662 1.00 43.10 C ATOM 1735 NE1 TRP A 127 38.178 12.071 13.812 1.00 43.55 N ATOM 1736 CE2 TRP A 127 37.867 11.064 12.923 1.00 43.27 C ATOM 1737 CE3 TRP A 127 36.565 9.027 12.981 1.00 45.46 C ATOM 1738 CZ2 TRP A 127 38.235 10.813 11.592 1.00 43.09 C ATOM 1739 CZ3 TRP A 127 36.904 8.778 11.635 1.00 44.80 C ATOM 1740 CH2 TRP A 127 37.743 9.669 10.939 1.00 45.11 C ATOM 1741 H TRP A 127 38.188 10.645 17.651 1.00 42.95 H ATOM 1742 HA TRP A 127 36.268 8.596 17.711 1.00 43.84 H ATOM 1743 HB3 TRP A 127 35.868 10.893 16.870 1.00 42.89 H ATOM 1744 HB2 TRP A 127 35.281 9.650 15.819 1.00 42.89 H ATOM 1745 HD1 TRP A 127 37.737 12.476 15.923 1.00 44.16 H ATOM 1746 HE1 TRP A 127 38.799 12.846 13.626 1.00 43.55 H ATOM 1747 HE3 TRP A 127 35.955 8.308 13.504 1.00 45.46 H ATOM 1748 HZ2 TRP A 127 38.917 11.486 11.102 1.00 43.09 H ATOM 1749 HZ3 TRP A 127 36.531 7.891 11.144 1.00 44.80 H ATOM 1750 HH2 TRP A 127 38.019 9.469 9.914 1.00 45.11 H ATOM 1751 N GLU A 128 38.710 7.954 15.617 1.00 45.51 N ATOM 1752 CA GLU A 128 39.398 6.942 14.814 1.00 46.17 C ATOM 1753 C GLU A 128 39.657 5.634 15.581 1.00 44.95 C ATOM 1754 O GLU A 128 39.607 4.565 14.975 1.00 45.02 O ATOM 1755 CB GLU A 128 40.754 7.490 14.311 1.00 48.66 C ATOM 1756 CG GLU A 128 40.691 8.813 13.515 1.00 52.56 C ATOM 1757 CD GLU A 128 40.914 10.115 14.309 1.00 55.33 C ATOM 1758 OE1 GLU A 128 41.225 11.131 13.651 1.00 56.74 O ATOM 1759 OE2 GLU A 128 40.761 10.106 15.547 1.00 55.59 O1- ATOM 1760 H GLU A 128 39.257 8.784 15.818 1.00 45.51 H ATOM 1761 HA GLU A 128 38.770 6.715 13.950 1.00 46.17 H ATOM 1762 HB3 GLU A 128 41.195 6.739 13.655 1.00 48.66 H ATOM 1763 HB2 GLU A 128 41.461 7.575 15.139 1.00 48.66 H ATOM 1764 HG3 GLU A 128 39.740 8.874 12.989 1.00 52.56 H ATOM 1765 HG2 GLU A 128 41.447 8.756 12.734 1.00 52.56 H ATOM 1766 N GLU A 129 39.943 5.757 16.887 1.00 42.89 N ATOM 1767 CA GLU A 129 40.312 4.658 17.778 1.00 42.13 C ATOM 1768 C GLU A 129 39.141 4.139 18.624 1.00 41.35 C ATOM 1769 O GLU A 129 39.318 3.133 19.310 1.00 39.97 O ATOM 1770 CB GLU A 129 41.457 5.134 18.691 1.00 46.76 C ATOM 1771 CG GLU A 129 42.753 5.444 17.913 1.00 51.38 C ATOM 1772 CD GLU A 129 43.966 5.784 18.793 1.00 54.75 C ATOM 1773 OE1 GLU A 129 43.773 6.200 19.958 1.00 56.39 O ATOM 1774 OE2 GLU A 129 45.091 5.619 18.272 1.00 57.50 O1- ATOM 1775 H GLU A 129 39.949 6.677 17.305 1.00 42.89 H ATOM 1776 HA GLU A 129 40.674 3.811 17.193 1.00 42.13 H ATOM 1777 HB3 GLU A 129 41.666 4.380 19.453 1.00 46.76 H ATOM 1778 HB2 GLU A 129 41.137 6.028 19.228 1.00 46.76 H ATOM 1779 HG3 GLU A 129 42.591 6.284 17.235 1.00 51.38 H ATOM 1780 HG2 GLU A 129 43.004 4.588 17.285 1.00 51.38 H ATOM 1781 N ASP A 130 37.984 4.823 18.578 1.00 38.84 N ATOM 1782 CA ASP A 130 36.802 4.514 19.376 1.00 36.35 C ATOM 1783 C ASP A 130 36.222 3.145 18.943 1.00 34.79 C ATOM 1784 O ASP A 130 35.811 3.019 17.788 1.00 33.59 O ATOM 1785 CB ASP A 130 35.758 5.649 19.243 1.00 37.00 C ATOM 1786 CG ASP A 130 34.789 5.722 20.430 1.00 37.96 C ATOM 1787 OD1 ASP A 130 34.764 6.790 21.075 1.00 37.28 O ATOM 1788 OD2 ASP A 130 34.098 4.718 20.702 1.00 37.20 O1- ATOM 1789 H ASP A 130 37.922 5.642 17.989 1.00 38.84 H ATOM 1790 HA ASP A 130 37.147 4.505 20.408 1.00 36.35 H ATOM 1791 HB3 ASP A 130 35.182 5.546 18.322 1.00 37.00 H ATOM 1792 HB2 ASP A 130 36.271 6.606 19.133 1.00 37.00 H ATOM 1793 N PRO A 131 36.208 2.142 19.855 1.00 34.64 N ATOM 1794 CA PRO A 131 35.711 0.793 19.533 1.00 33.09 C ATOM 1795 C PRO A 131 34.185 0.699 19.343 1.00 30.37 C ATOM 1796 O PRO A 131 33.726 -0.330 18.848 1.00 29.21 O ATOM 1797 CB PRO A 131 36.193 -0.058 20.716 1.00 34.60 C ATOM 1798 CG PRO A 131 36.187 0.905 21.890 1.00 35.14 C ATOM 1799 CD PRO A 131 36.628 2.219 21.257 1.00 34.51 C ATOM 1800 HA PRO A 131 36.185 0.431 18.620 1.00 33.09 H ATOM 1801 HB3 PRO A 131 37.212 -0.398 20.526 1.00 34.60 H ATOM 1802 HB2 PRO A 131 35.583 -0.944 20.902 1.00 34.60 H ATOM 1803 HG3 PRO A 131 36.825 0.591 22.717 1.00 35.14 H ATOM 1804 HG2 PRO A 131 35.170 1.008 22.272 1.00 35.14 H ATOM 1805 HD2 PRO A 131 36.175 3.059 21.783 1.00 34.51 H ATOM 1806 HD3 PRO A 131 37.712 2.319 21.304 1.00 34.51 H ATOM 1807 N LEU A 132 33.441 1.758 19.712 1.00 28.68 N ATOM 1808 CA LEU A 132 31.997 1.874 19.520 1.00 26.61 C ATOM 1809 C LEU A 132 31.618 2.564 18.198 1.00 26.87 C ATOM 1810 O LEU A 132 30.422 2.668 17.942 1.00 24.37 O ATOM 1811 CB LEU A 132 31.344 2.590 20.725 1.00 25.86 C ATOM 1812 CG LEU A 132 31.572 1.931 22.100 1.00 27.89 C ATOM 1813 CD1 LEU A 132 30.827 2.718 23.197 1.00 26.82 C ATOM 1814 CD2 LEU A 132 31.207 0.435 22.132 1.00 27.95 C ATOM 1815 H LEU A 132 33.891 2.572 20.114 1.00 28.68 H ATOM 1816 HA LEU A 132 31.566 0.875 19.463 1.00 26.61 H ATOM 1817 HB3 LEU A 132 30.268 2.660 20.559 1.00 25.86 H ATOM 1818 HB2 LEU A 132 31.700 3.616 20.775 1.00 25.86 H ATOM 1819 HG LEU A 132 32.636 2.006 22.323 1.00 27.89 H ATOM 1820 HD11 LEU A 132 31.444 2.814 24.090 1.00 26.82 H ATOM 1821 HD12 LEU A 132 30.565 3.725 22.871 1.00 26.82 H ATOM 1822 HD13 LEU A 132 29.898 2.232 23.493 1.00 26.82 H ATOM 1823 HD21 LEU A 132 30.730 0.145 23.068 1.00 27.95 H ATOM 1824 HD22 LEU A 132 30.523 0.168 21.329 1.00 27.95 H ATOM 1825 HD23 LEU A 132 32.101 -0.180 22.023 1.00 27.95 H ATOM 1826 N ALA A 133 32.596 2.973 17.363 1.00 25.36 N ATOM 1827 CA ALA A 133 32.378 3.463 15.994 1.00 25.95 C ATOM 1828 C ALA A 133 31.762 2.377 15.100 1.00 25.66 C ATOM 1829 O ALA A 133 32.189 1.231 15.192 1.00 23.39 O ATOM 1830 CB ALA A 133 33.726 3.923 15.414 1.00 22.78 C ATOM 1831 H ALA A 133 33.561 2.871 17.646 1.00 25.36 H ATOM 1832 HA ALA A 133 31.692 4.309 16.039 1.00 25.95 H ATOM 1833 HB1 ALA A 133 33.595 4.415 14.451 1.00 22.78 H ATOM 1834 HB2 ALA A 133 34.219 4.632 16.078 1.00 22.78 H ATOM 1835 HB3 ALA A 133 34.410 3.086 15.268 1.00 22.78 H ATOM 1836 N GLY A 134 30.772 2.739 14.272 1.00 26.37 N ATOM 1837 CA GLY A 134 30.015 1.791 13.452 1.00 24.19 C ATOM 1838 C GLY A 134 30.543 1.771 12.017 1.00 26.33 C ATOM 1839 O GLY A 134 31.680 2.159 11.749 1.00 25.05 O ATOM 1840 H GLY A 134 30.473 3.705 14.241 1.00 26.37 H ATOM 1841 HA3 GLY A 134 28.964 2.069 13.447 1.00 24.19 H ATOM 1842 HA2 GLY A 134 30.057 0.780 13.858 1.00 24.19 H ATOM 1843 N ILE A 135 29.699 1.273 11.101 1.00 26.17 N ATOM 1844 CA ILE A 135 30.011 1.047 9.689 1.00 26.40 C ATOM 1845 C ILE A 135 30.429 2.323 8.931 1.00 27.39 C ATOM 1846 O ILE A 135 31.471 2.289 8.285 1.00 28.26 O ATOM 1847 CB ILE A 135 28.844 0.323 8.946 1.00 27.45 C ATOM 1848 CG1 ILE A 135 28.660 -1.103 9.526 1.00 25.10 C ATOM 1849 CG2 ILE A 135 28.981 0.289 7.405 1.00 27.06 C ATOM 1850 CD1 ILE A 135 27.487 -1.903 8.948 1.00 23.56 C ATOM 1851 H ILE A 135 28.779 0.972 11.397 1.00 26.17 H ATOM 1852 HA ILE A 135 30.875 0.378 9.673 1.00 26.40 H ATOM 1853 HB ILE A 135 27.927 0.871 9.160 1.00 27.45 H ATOM 1854 HG13 ILE A 135 28.518 -1.050 10.599 1.00 25.10 H ATOM 1855 HG12 ILE A 135 29.574 -1.677 9.424 1.00 25.10 H ATOM 1856 HG21 ILE A 135 28.166 -0.257 6.934 1.00 27.06 H ATOM 1857 HG22 ILE A 135 28.956 1.286 6.967 1.00 27.06 H ATOM 1858 HG23 ILE A 135 29.913 -0.180 7.099 1.00 27.06 H ATOM 1859 HD11 ILE A 135 27.298 -2.788 9.554 1.00 23.56 H ATOM 1860 HD12 ILE A 135 26.573 -1.310 8.931 1.00 23.56 H ATOM 1861 HD13 ILE A 135 27.690 -2.249 7.934 1.00 23.56 H ATOM 1862 N ILE A 136 29.640 3.407 9.040 1.00 28.24 N ATOM 1863 CA ILE A 136 29.866 4.696 8.376 1.00 28.10 C ATOM 1864 C ILE A 136 31.250 5.328 8.672 1.00 28.82 C ATOM 1865 O ILE A 136 32.006 5.476 7.714 1.00 28.49 O ATOM 1866 CB ILE A 136 28.701 5.708 8.631 1.00 28.83 C ATOM 1867 CG1 ILE A 136 27.423 5.289 7.869 1.00 30.10 C ATOM 1868 CG2 ILE A 136 29.016 7.183 8.289 1.00 28.01 C ATOM 1869 CD1 ILE A 136 26.135 5.923 8.408 1.00 29.54 C ATOM 1870 H ILE A 136 28.792 3.343 9.593 1.00 28.24 H ATOM 1871 HA ILE A 136 29.860 4.476 7.306 1.00 28.10 H ATOM 1872 HB ILE A 136 28.461 5.661 9.692 1.00 28.83 H ATOM 1873 HG13 ILE A 136 27.302 4.206 7.888 1.00 30.10 H ATOM 1874 HG12 ILE A 136 27.528 5.562 6.821 1.00 30.10 H ATOM 1875 HG21 ILE A 136 28.143 7.818 8.431 1.00 28.01 H ATOM 1876 HG22 ILE A 136 29.802 7.596 8.919 1.00 28.01 H ATOM 1877 HG23 ILE A 136 29.321 7.288 7.248 1.00 28.01 H ATOM 1878 HD11 ILE A 136 25.308 5.213 8.387 1.00 29.54 H ATOM 1879 HD12 ILE A 136 26.259 6.255 9.435 1.00 29.54 H ATOM 1880 HD13 ILE A 136 25.844 6.792 7.820 1.00 29.54 H ATOM 1881 N PRO A 137 31.603 5.656 9.942 1.00 27.97 N ATOM 1882 CA PRO A 137 32.911 6.275 10.241 1.00 29.98 C ATOM 1883 C PRO A 137 34.133 5.409 9.883 1.00 31.46 C ATOM 1884 O PRO A 137 35.117 5.961 9.390 1.00 32.74 O ATOM 1885 CB PRO A 137 32.846 6.600 11.740 1.00 30.07 C ATOM 1886 CG PRO A 137 31.811 5.638 12.296 1.00 28.98 C ATOM 1887 CD PRO A 137 30.800 5.538 11.161 1.00 26.54 C ATOM 1888 HA PRO A 137 32.997 7.210 9.682 1.00 29.98 H ATOM 1889 HB3 PRO A 137 32.496 7.625 11.863 1.00 30.07 H ATOM 1890 HB2 PRO A 137 33.805 6.521 12.255 1.00 30.07 H ATOM 1891 HG3 PRO A 137 31.376 5.966 13.240 1.00 28.98 H ATOM 1892 HG2 PRO A 137 32.272 4.665 12.462 1.00 28.98 H ATOM 1893 HD2 PRO A 137 30.222 4.619 11.236 1.00 26.54 H ATOM 1894 HD3 PRO A 137 30.110 6.380 11.208 1.00 26.54 H ATOM 1895 N ARG A 138 34.026 4.081 10.075 1.00 32.19 N ATOM 1896 CA ARG A 138 35.033 3.106 9.651 1.00 31.81 C ATOM 1897 C ARG A 138 35.192 3.034 8.126 1.00 34.98 C ATOM 1898 O ARG A 138 36.327 2.939 7.670 1.00 35.97 O ATOM 1899 CB ARG A 138 34.697 1.708 10.196 1.00 31.32 C ATOM 1900 CG ARG A 138 34.800 1.593 11.720 1.00 28.44 C ATOM 1901 CD ARG A 138 34.463 0.174 12.202 1.00 28.17 C ATOM 1902 NE ARG A 138 34.462 0.097 13.668 1.00 28.21 N ATOM 1903 CZ ARG A 138 35.517 0.038 14.500 1.00 30.29 C ATOM 1904 NH1 ARG A 138 36.782 -0.044 14.061 1.00 28.82 N ATOM 1905 NH2 ARG A 138 35.296 0.079 15.817 1.00 28.61 N1+ ATOM 1906 H ARG A 138 33.182 3.702 10.484 1.00 32.19 H ATOM 1907 HA ARG A 138 35.996 3.413 10.065 1.00 31.81 H ATOM 1908 HB3 ARG A 138 35.386 0.980 9.766 1.00 31.32 H ATOM 1909 HB2 ARG A 138 33.698 1.414 9.869 1.00 31.32 H ATOM 1910 HG3 ARG A 138 34.194 2.342 12.232 1.00 28.44 H ATOM 1911 HG2 ARG A 138 35.832 1.823 11.987 1.00 28.44 H ATOM 1912 HD3 ARG A 138 35.213 -0.527 11.835 1.00 28.17 H ATOM 1913 HD2 ARG A 138 33.508 -0.163 11.797 1.00 28.17 H ATOM 1914 HE ARG A 138 33.552 0.234 14.093 1.00 28.21 H ATOM 1915 HH12 ARG A 138 37.554 -0.059 14.711 1.00 28.82 H ATOM 1916 HH11 ARG A 138 36.969 -0.061 13.069 1.00 28.82 H ATOM 1917 HH22 ARG A 138 36.067 0.069 16.468 1.00 28.61 H ATOM 1918 HH21 ARG A 138 34.354 0.176 16.172 1.00 28.61 H ATOM 1919 N THR A 139 34.079 3.101 7.371 1.00 35.78 N ATOM 1920 CA THR A 139 34.073 3.106 5.906 1.00 36.79 C ATOM 1921 C THR A 139 34.789 4.343 5.345 1.00 37.82 C ATOM 1922 O THR A 139 35.692 4.162 4.533 1.00 35.78 O ATOM 1923 CB THR A 139 32.640 3.040 5.305 1.00 37.62 C ATOM 1924 OG1 THR A 139 32.080 1.775 5.587 1.00 35.78 O ATOM 1925 CG2 THR A 139 32.523 3.258 3.785 1.00 37.13 C ATOM 1926 H THR A 139 33.175 3.173 7.821 1.00 35.78 H ATOM 1927 HA THR A 139 34.623 2.223 5.574 1.00 36.79 H ATOM 1928 HB THR A 139 32.004 3.777 5.795 1.00 37.62 H ATOM 1929 HG1 THR A 139 31.906 1.732 6.534 1.00 35.78 H ATOM 1930 HG21 THR A 139 31.495 3.118 3.457 1.00 37.13 H ATOM 1931 HG22 THR A 139 32.797 4.272 3.494 1.00 37.13 H ATOM 1932 HG23 THR A 139 33.152 2.561 3.232 1.00 37.13 H ATOM 1933 N LEU A 140 34.419 5.551 5.813 1.00 39.09 N ATOM 1934 CA LEU A 140 35.057 6.808 5.409 1.00 40.74 C ATOM 1935 C LEU A 140 36.559 6.833 5.729 1.00 42.29 C ATOM 1936 O LEU A 140 37.342 7.149 4.836 1.00 42.16 O ATOM 1937 CB LEU A 140 34.361 8.037 6.044 1.00 40.56 C ATOM 1938 CG LEU A 140 33.082 8.569 5.359 1.00 42.13 C ATOM 1939 CD1 LEU A 140 33.229 8.796 3.845 1.00 41.68 C ATOM 1940 CD2 LEU A 140 31.831 7.757 5.698 1.00 45.74 C ATOM 1941 H LEU A 140 33.673 5.622 6.493 1.00 39.09 H ATOM 1942 HA LEU A 140 34.978 6.865 4.325 1.00 40.74 H ATOM 1943 HB3 LEU A 140 35.068 8.864 6.014 1.00 40.56 H ATOM 1944 HB2 LEU A 140 34.175 7.859 7.104 1.00 40.56 H ATOM 1945 HG LEU A 140 32.912 9.556 5.794 1.00 42.13 H ATOM 1946 HD11 LEU A 140 32.799 9.753 3.551 1.00 41.68 H ATOM 1947 HD12 LEU A 140 34.270 8.814 3.524 1.00 41.68 H ATOM 1948 HD13 LEU A 140 32.718 8.017 3.282 1.00 41.68 H ATOM 1949 HD21 LEU A 140 30.960 8.173 5.198 1.00 45.74 H ATOM 1950 HD22 LEU A 140 31.923 6.716 5.390 1.00 45.74 H ATOM 1951 HD23 LEU A 140 31.633 7.798 6.767 1.00 45.74 H ATOM 1952 N HIS A 141 36.933 6.455 6.965 1.00 42.88 N ATOM 1953 CA HIS A 141 38.323 6.362 7.417 1.00 44.87 C ATOM 1954 C HIS A 141 39.172 5.410 6.556 1.00 44.22 C ATOM 1955 O HIS A 141 40.252 5.805 6.121 1.00 43.81 O ATOM 1956 CB HIS A 141 38.364 5.966 8.907 1.00 46.81 C ATOM 1957 CG HIS A 141 39.755 5.914 9.494 1.00 50.62 C ATOM 1958 ND1 HIS A 141 40.556 4.783 9.456 1.00 52.14 N ATOM 1959 CD2 HIS A 141 40.506 6.879 10.125 1.00 51.05 C ATOM 1960 CE1 HIS A 141 41.724 5.111 10.016 1.00 52.04 C ATOM 1961 NE2 HIS A 141 41.765 6.367 10.446 1.00 50.72 N ATOM 1962 H HIS A 141 36.226 6.201 7.644 1.00 42.88 H ATOM 1963 HA HIS A 141 38.755 7.360 7.325 1.00 44.87 H ATOM 1964 HB3 HIS A 141 37.884 4.998 9.058 1.00 46.81 H ATOM 1965 HB2 HIS A 141 37.789 6.684 9.490 1.00 46.81 H ATOM 1966 HD1 HIS A 141 40.324 3.889 9.047 1.00 52.14 H ATOM 1967 HD2 HIS A 141 40.244 7.900 10.357 1.00 51.05 H ATOM 1968 HE1 HIS A 141 42.555 4.426 10.104 1.00 52.04 H ATOM 1969 N GLN A 142 38.652 4.194 6.318 1.00 43.78 N ATOM 1970 CA GLN A 142 39.307 3.161 5.521 1.00 44.19 C ATOM 1971 C GLN A 142 39.404 3.486 4.024 1.00 44.75 C ATOM 1972 O GLN A 142 40.373 3.054 3.409 1.00 45.21 O ATOM 1973 CB GLN A 142 38.637 1.795 5.758 1.00 45.44 C ATOM 1974 CG GLN A 142 38.894 1.197 7.158 1.00 48.56 C ATOM 1975 CD GLN A 142 40.296 0.608 7.316 1.00 50.10 C ATOM 1976 OE1 GLN A 142 41.260 1.338 7.532 1.00 49.63 O ATOM 1977 NE2 GLN A 142 40.413 -0.718 7.226 1.00 51.81 N ATOM 1978 H GLN A 142 37.752 3.947 6.709 1.00 43.78 H ATOM 1979 HA GLN A 142 40.332 3.100 5.881 1.00 44.19 H ATOM 1980 HB3 GLN A 142 38.957 1.074 5.003 1.00 45.44 H ATOM 1981 HB2 GLN A 142 37.565 1.911 5.604 1.00 45.44 H ATOM 1982 HG3 GLN A 142 38.165 0.419 7.366 1.00 48.56 H ATOM 1983 HG2 GLN A 142 38.747 1.951 7.932 1.00 48.56 H ATOM 1984 HE22 GLN A 142 41.319 -1.150 7.330 1.00 51.81 H ATOM 1985 HE21 GLN A 142 39.604 -1.294 7.044 1.00 51.81 H ATOM 1986 N ILE A 143 38.466 4.278 3.470 1.00 43.60 N ATOM 1987 CA ILE A 143 38.564 4.817 2.108 1.00 43.61 C ATOM 1988 C ILE A 143 39.809 5.711 1.944 1.00 45.62 C ATOM 1989 O ILE A 143 40.591 5.468 1.028 1.00 44.70 O ATOM 1990 CB ILE A 143 37.278 5.581 1.658 1.00 42.40 C ATOM 1991 CG1 ILE A 143 36.127 4.588 1.384 1.00 40.31 C ATOM 1992 CG2 ILE A 143 37.458 6.515 0.436 1.00 40.71 C ATOM 1993 CD1 ILE A 143 34.728 5.228 1.419 1.00 38.90 C ATOM 1994 H ILE A 143 37.676 4.585 4.022 1.00 43.60 H ATOM 1995 HA ILE A 143 38.693 3.965 1.437 1.00 43.61 H ATOM 1996 HB ILE A 143 36.963 6.210 2.489 1.00 42.40 H ATOM 1997 HG13 ILE A 143 36.150 3.777 2.110 1.00 40.31 H ATOM 1998 HG12 ILE A 143 36.285 4.097 0.424 1.00 40.31 H ATOM 1999 HG21 ILE A 143 36.514 6.960 0.128 1.00 40.71 H ATOM 2000 HG22 ILE A 143 38.128 7.350 0.646 1.00 40.71 H ATOM 2001 HG23 ILE A 143 37.857 5.972 -0.421 1.00 40.71 H ATOM 2002 HD11 ILE A 143 33.951 4.471 1.317 1.00 38.90 H ATOM 2003 HD12 ILE A 143 34.555 5.750 2.359 1.00 38.90 H ATOM 2004 HD13 ILE A 143 34.584 5.944 0.612 1.00 38.90 H ATOM 2005 N PHE A 144 40.008 6.663 2.874 1.00 46.96 N ATOM 2006 CA PHE A 144 41.208 7.504 2.934 1.00 49.07 C ATOM 2007 C PHE A 144 42.489 6.763 3.345 1.00 50.61 C ATOM 2008 O PHE A 144 43.560 7.331 3.162 1.00 51.54 O ATOM 2009 CB PHE A 144 40.983 8.717 3.858 1.00 48.69 C ATOM 2010 CG PHE A 144 39.969 9.712 3.337 1.00 49.25 C ATOM 2011 CD1 PHE A 144 40.245 10.472 2.182 1.00 49.30 C ATOM 2012 CD2 PHE A 144 38.703 9.816 3.944 1.00 48.10 C ATOM 2013 CE1 PHE A 144 39.263 11.287 1.639 1.00 48.65 C ATOM 2014 CE2 PHE A 144 37.731 10.627 3.383 1.00 49.28 C ATOM 2015 CZ PHE A 144 38.011 11.351 2.233 1.00 49.42 C ATOM 2016 H PHE A 144 39.328 6.796 3.610 1.00 46.96 H ATOM 2017 HA PHE A 144 41.395 7.879 1.926 1.00 49.07 H ATOM 2018 HB3 PHE A 144 41.917 9.259 4.012 1.00 48.69 H ATOM 2019 HB2 PHE A 144 40.673 8.365 4.841 1.00 48.69 H ATOM 2020 HD1 PHE A 144 41.215 10.416 1.714 1.00 49.30 H ATOM 2021 HD2 PHE A 144 38.487 9.269 4.847 1.00 48.10 H ATOM 2022 HE1 PHE A 144 39.468 11.865 0.749 1.00 48.65 H ATOM 2023 HE2 PHE A 144 36.755 10.688 3.840 1.00 49.28 H ATOM 2024 HZ PHE A 144 37.248 11.968 1.796 1.00 49.42 H ATOM 2025 N GLU A 145 42.386 5.537 3.881 1.00 51.76 N ATOM 2026 CA GLU A 145 43.545 4.720 4.230 1.00 53.26 C ATOM 2027 C GLU A 145 44.002 3.875 3.030 1.00 53.56 C ATOM 2028 O GLU A 145 45.191 3.859 2.727 1.00 53.41 O ATOM 2029 CB GLU A 145 43.215 3.852 5.466 1.00 54.78 C ATOM 2030 CG GLU A 145 44.400 3.059 6.056 1.00 58.42 C ATOM 2031 CD GLU A 145 45.499 3.967 6.626 1.00 60.55 C ATOM 2032 OE1 GLU A 145 46.488 4.204 5.899 1.00 61.57 O ATOM 2033 OE2 GLU A 145 45.330 4.414 7.783 1.00 60.12 O1- ATOM 2034 H GLU A 145 41.475 5.128 4.038 1.00 51.76 H ATOM 2035 HA GLU A 145 44.368 5.384 4.500 1.00 53.26 H ATOM 2036 HB3 GLU A 145 42.444 3.132 5.197 1.00 54.78 H ATOM 2037 HB2 GLU A 145 42.774 4.476 6.246 1.00 54.78 H ATOM 2038 HG3 GLU A 145 44.823 2.387 5.308 1.00 58.42 H ATOM 2039 HG2 GLU A 145 44.033 2.412 6.854 1.00 58.42 H ATOM 2040 N LYS A 146 43.050 3.195 2.371 1.00 52.91 N ATOM 2041 CA LYS A 146 43.314 2.210 1.323 1.00 53.75 C ATOM 2042 C LYS A 146 43.578 2.834 -0.060 1.00 54.11 C ATOM 2043 O LYS A 146 44.247 2.187 -0.861 1.00 53.73 O ATOM 2044 CB LYS A 146 42.151 1.191 1.273 1.00 54.00 C ATOM 2045 CG LYS A 146 41.928 0.435 2.607 1.00 56.01 C ATOM 2046 CD LYS A 146 42.075 -1.090 2.530 1.00 56.78 C ATOM 2047 CE LYS A 146 40.922 -1.777 1.782 1.00 56.67 C ATOM 2048 NZ LYS A 146 41.048 -3.243 1.840 1.00 56.24 N1+ ATOM 2049 H LYS A 146 42.087 3.267 2.676 1.00 52.91 H ATOM 2050 HA LYS A 146 44.217 1.659 1.597 1.00 53.75 H ATOM 2051 HB3 LYS A 146 42.335 0.476 0.470 1.00 54.00 H ATOM 2052 HB2 LYS A 146 41.227 1.705 0.999 1.00 54.00 H ATOM 2053 HG3 LYS A 146 40.933 0.655 2.988 1.00 56.01 H ATOM 2054 HG2 LYS A 146 42.617 0.799 3.370 1.00 56.01 H ATOM 2055 HD3 LYS A 146 42.144 -1.481 3.547 1.00 56.78 H ATOM 2056 HD2 LYS A 146 43.025 -1.332 2.050 1.00 56.78 H ATOM 2057 HE3 LYS A 146 40.897 -1.466 0.737 1.00 56.67 H ATOM 2058 HE2 LYS A 146 39.963 -1.500 2.222 1.00 56.67 H ATOM 2059 HZ1 LYS A 146 40.276 -3.650 1.322 1.00 56.24 H ATOM 2060 HZ2 LYS A 146 41.918 -3.530 1.417 1.00 56.24 H ATOM 2061 HZ3 LYS A 146 41.011 -3.557 2.799 1.00 56.24 H ATOM 2062 N LEU A 147 43.076 4.056 -0.325 1.00 53.89 N ATOM 2063 CA LEU A 147 43.275 4.755 -1.603 1.00 54.30 C ATOM 2064 C LEU A 147 44.414 5.781 -1.547 1.00 56.38 C ATOM 2065 O LEU A 147 45.034 5.990 -2.588 1.00 57.15 O ATOM 2066 CB LEU A 147 41.971 5.437 -2.073 1.00 52.68 C ATOM 2067 CG LEU A 147 41.046 4.548 -2.925 1.00 51.66 C ATOM 2068 CD1 LEU A 147 40.693 3.211 -2.254 1.00 49.87 C ATOM 2069 CD2 LEU A 147 39.783 5.332 -3.314 1.00 48.79 C ATOM 2070 H LEU A 147 42.510 4.528 0.368 1.00 53.89 H ATOM 2071 HA LEU A 147 43.561 4.039 -2.376 1.00 54.30 H ATOM 2072 HB3 LEU A 147 42.221 6.286 -2.709 1.00 52.68 H ATOM 2073 HB2 LEU A 147 41.439 5.869 -1.230 1.00 52.68 H ATOM 2074 HG LEU A 147 41.570 4.305 -3.852 1.00 51.66 H ATOM 2075 HD11 LEU A 147 39.750 2.815 -2.616 1.00 49.87 H ATOM 2076 HD12 LEU A 147 41.453 2.456 -2.460 1.00 49.87 H ATOM 2077 HD13 LEU A 147 40.603 3.313 -1.172 1.00 49.87 H ATOM 2078 HD21 LEU A 147 38.968 4.674 -3.612 1.00 48.79 H ATOM 2079 HD22 LEU A 147 39.422 5.954 -2.494 1.00 48.79 H ATOM 2080 HD23 LEU A 147 39.994 5.992 -4.153 1.00 48.79 H ATOM 2081 N THR A 148 44.691 6.386 -0.376 1.00 57.67 N ATOM 2082 CA THR A 148 45.844 7.284 -0.198 1.00 58.54 C ATOM 2083 C THR A 148 47.175 6.508 -0.107 1.00 60.02 C ATOM 2084 O THR A 148 48.210 7.060 -0.480 1.00 59.77 O ATOM 2085 CB THR A 148 45.720 8.185 1.059 1.00 58.20 C ATOM 2086 OG1 THR A 148 44.516 8.922 0.985 1.00 58.85 O ATOM 2087 CG2 THR A 148 46.851 9.207 1.278 1.00 58.05 C ATOM 2088 H THR A 148 44.149 6.173 0.448 1.00 57.67 H ATOM 2089 HA THR A 148 45.907 7.938 -1.072 1.00 58.54 H ATOM 2090 HB THR A 148 45.682 7.548 1.941 1.00 58.20 H ATOM 2091 HG1 THR A 148 43.790 8.324 1.177 1.00 58.85 H ATOM 2092 HG21 THR A 148 46.613 9.880 2.103 1.00 58.05 H ATOM 2093 HG22 THR A 148 47.795 8.724 1.531 1.00 58.05 H ATOM 2094 HG23 THR A 148 47.012 9.816 0.388 1.00 58.05 H ATOM 2095 N ASP A 149 47.112 5.233 0.325 1.00 61.81 N ATOM 2096 CA ASP A 149 48.198 4.247 0.267 1.00 63.39 C ATOM 2097 C ASP A 149 48.673 4.050 -1.186 1.00 64.18 C ATOM 2098 O ASP A 149 49.865 4.188 -1.460 1.00 64.37 O ATOM 2099 CB ASP A 149 47.769 2.947 1.010 1.00 64.12 C ATOM 2100 CG ASP A 149 48.717 1.730 1.096 1.00 65.61 C ATOM 2101 OD1 ASP A 149 49.522 1.479 0.172 1.00 66.85 O ATOM 2102 OD2 ASP A 149 48.519 0.960 2.061 1.00 67.42 O1- ATOM 2103 H ASP A 149 46.223 4.871 0.640 1.00 61.81 H ATOM 2104 HA ASP A 149 49.037 4.671 0.822 1.00 63.39 H ATOM 2105 HB3 ASP A 149 46.823 2.598 0.592 1.00 64.12 H ATOM 2106 HB2 ASP A 149 47.534 3.237 2.034 1.00 64.12 H ATOM 2107 N ASN A 150 47.713 3.798 -2.088 1.00 64.99 N ATOM 2108 CA ASN A 150 47.926 3.705 -3.532 1.00 65.74 C ATOM 2109 C ASN A 150 48.150 5.098 -4.151 1.00 65.03 C ATOM 2110 O ASN A 150 47.802 6.117 -3.553 1.00 65.91 O ATOM 2111 CB ASN A 150 46.702 3.004 -4.171 1.00 67.17 C ATOM 2112 CG ASN A 150 46.561 1.530 -3.764 1.00 68.38 C ATOM 2113 OD1 ASN A 150 46.375 1.213 -2.592 1.00 69.69 O ATOM 2114 ND2 ASN A 150 46.630 0.615 -4.732 1.00 69.67 N ATOM 2115 H ASN A 150 46.759 3.697 -1.773 1.00 64.99 H ATOM 2116 HA ASN A 150 48.813 3.088 -3.689 1.00 65.74 H ATOM 2117 HB3 ASN A 150 46.770 3.053 -5.259 1.00 67.17 H ATOM 2118 HB2 ASN A 150 45.784 3.528 -3.899 1.00 67.17 H ATOM 2119 HD22 ASN A 150 46.538 -0.364 -4.502 1.00 69.67 H ATOM 2120 HD21 ASN A 150 46.765 0.888 -5.694 1.00 69.67 H ATOM 2121 N GLY A 151 48.679 5.108 -5.385 1.00 64.36 N ATOM 2122 CA GLY A 151 48.858 6.310 -6.205 1.00 63.41 C ATOM 2123 C GLY A 151 47.542 6.803 -6.838 1.00 62.81 C ATOM 2124 O GLY A 151 47.594 7.619 -7.756 1.00 63.61 O ATOM 2125 H GLY A 151 48.945 4.231 -5.810 1.00 64.36 H ATOM 2126 HA3 GLY A 151 49.567 6.082 -7.001 1.00 63.41 H ATOM 2127 HA2 GLY A 151 49.297 7.114 -5.611 1.00 63.41 H ATOM 2128 N THR A 152 46.379 6.304 -6.380 1.00 60.95 N ATOM 2129 CA THR A 152 45.049 6.654 -6.871 1.00 59.02 C ATOM 2130 C THR A 152 44.722 8.134 -6.610 1.00 58.13 C ATOM 2131 O THR A 152 44.837 8.591 -5.473 1.00 57.82 O ATOM 2132 CB THR A 152 43.938 5.798 -6.196 1.00 59.09 C ATOM 2133 OG1 THR A 152 44.261 4.424 -6.291 1.00 59.39 O ATOM 2134 CG2 THR A 152 42.539 5.969 -6.819 1.00 57.71 C ATOM 2135 H THR A 152 46.406 5.680 -5.588 1.00 60.95 H ATOM 2136 HA THR A 152 45.039 6.473 -7.946 1.00 59.02 H ATOM 2137 HB THR A 152 43.879 6.041 -5.134 1.00 59.09 H ATOM 2138 HG1 THR A 152 45.064 4.263 -5.791 1.00 59.39 H ATOM 2139 HG21 THR A 152 41.792 5.397 -6.269 1.00 57.71 H ATOM 2140 HG22 THR A 152 42.214 7.007 -6.821 1.00 57.71 H ATOM 2141 HG23 THR A 152 42.521 5.627 -7.854 1.00 57.71 H ATOM 2142 N GLU A 153 44.316 8.840 -7.674 1.00 56.97 N ATOM 2143 CA GLU A 153 43.813 10.207 -7.618 1.00 56.69 C ATOM 2144 C GLU A 153 42.294 10.144 -7.433 1.00 55.11 C ATOM 2145 O GLU A 153 41.599 9.811 -8.389 1.00 55.09 O ATOM 2146 CB GLU A 153 44.273 10.944 -8.896 1.00 57.96 C ATOM 2147 CG GLU A 153 43.615 12.319 -9.151 1.00 60.39 C ATOM 2148 CD GLU A 153 44.224 13.071 -10.343 1.00 61.93 C ATOM 2149 OE1 GLU A 153 45.468 13.196 -10.383 1.00 62.34 O ATOM 2150 OE2 GLU A 153 43.432 13.531 -11.195 1.00 61.46 O1- ATOM 2151 H GLU A 153 44.278 8.398 -8.583 1.00 56.97 H ATOM 2152 HA GLU A 153 44.244 10.734 -6.764 1.00 56.69 H ATOM 2153 HB3 GLU A 153 44.125 10.311 -9.770 1.00 57.96 H ATOM 2154 HB2 GLU A 153 45.354 11.070 -8.816 1.00 57.96 H ATOM 2155 HG3 GLU A 153 43.725 12.947 -8.266 1.00 60.39 H ATOM 2156 HG2 GLU A 153 42.542 12.200 -9.310 1.00 60.39 H ATOM 2157 N PHE A 154 41.811 10.402 -6.207 1.00 52.70 N ATOM 2158 CA PHE A 154 40.409 10.189 -5.850 1.00 49.80 C ATOM 2159 C PHE A 154 39.805 11.395 -5.124 1.00 49.14 C ATOM 2160 O PHE A 154 40.516 12.198 -4.520 1.00 48.93 O ATOM 2161 CB PHE A 154 40.270 8.882 -5.029 1.00 48.80 C ATOM 2162 CG PHE A 154 40.753 8.928 -3.589 1.00 49.66 C ATOM 2163 CD1 PHE A 154 39.834 9.060 -2.527 1.00 48.25 C ATOM 2164 CD2 PHE A 154 42.134 8.956 -3.307 1.00 48.95 C ATOM 2165 CE1 PHE A 154 40.296 9.160 -1.222 1.00 49.33 C ATOM 2166 CE2 PHE A 154 42.577 9.068 -1.999 1.00 50.09 C ATOM 2167 CZ PHE A 154 41.661 9.160 -0.961 1.00 50.47 C ATOM 2168 H PHE A 154 42.428 10.684 -5.459 1.00 52.70 H ATOM 2169 HA PHE A 154 39.842 10.079 -6.770 1.00 49.80 H ATOM 2170 HB3 PHE A 154 40.788 8.074 -5.539 1.00 48.80 H ATOM 2171 HB2 PHE A 154 39.223 8.577 -5.016 1.00 48.80 H ATOM 2172 HD1 PHE A 154 38.772 9.071 -2.725 1.00 48.25 H ATOM 2173 HD2 PHE A 154 42.849 8.884 -4.108 1.00 48.95 H ATOM 2174 HE1 PHE A 154 39.591 9.236 -0.407 1.00 49.33 H ATOM 2175 HE2 PHE A 154 43.637 9.076 -1.788 1.00 50.09 H ATOM 2176 HZ PHE A 154 42.016 9.234 0.053 1.00 50.47 H ATOM 2177 N SER A 155 38.469 11.445 -5.189 1.00 45.90 N ATOM 2178 CA SER A 155 37.605 12.383 -4.490 1.00 45.47 C ATOM 2179 C SER A 155 36.435 11.587 -3.901 1.00 43.55 C ATOM 2180 O SER A 155 35.952 10.651 -4.539 1.00 43.15 O ATOM 2181 CB SER A 155 37.138 13.465 -5.485 1.00 43.93 C ATOM 2182 OG SER A 155 36.300 14.422 -4.866 1.00 46.92 O ATOM 2183 H SER A 155 37.983 10.724 -5.708 1.00 45.90 H ATOM 2184 HA SER A 155 38.153 12.855 -3.672 1.00 45.47 H ATOM 2185 HB3 SER A 155 36.597 13.016 -6.319 1.00 43.93 H ATOM 2186 HB2 SER A 155 37.999 13.985 -5.908 1.00 43.93 H ATOM 2187 HG SER A 155 36.085 15.101 -5.511 1.00 46.92 H ATOM 2188 N VAL A 156 36.000 11.984 -2.698 1.00 42.99 N ATOM 2189 CA VAL A 156 34.894 11.360 -1.981 1.00 40.85 C ATOM 2190 C VAL A 156 33.810 12.424 -1.770 1.00 40.89 C ATOM 2191 O VAL A 156 34.131 13.524 -1.330 1.00 42.32 O ATOM 2192 CB VAL A 156 35.356 10.843 -0.588 1.00 40.60 C ATOM 2193 CG1 VAL A 156 34.222 10.235 0.260 1.00 41.68 C ATOM 2194 CG2 VAL A 156 36.494 9.818 -0.715 1.00 41.72 C ATOM 2195 H VAL A 156 36.427 12.779 -2.245 1.00 42.99 H ATOM 2196 HA VAL A 156 34.477 10.525 -2.544 1.00 40.85 H ATOM 2197 HB VAL A 156 35.761 11.686 -0.030 1.00 40.60 H ATOM 2198 HG11 VAL A 156 34.606 9.830 1.197 1.00 41.68 H ATOM 2199 HG12 VAL A 156 33.457 10.965 0.524 1.00 41.68 H ATOM 2200 HG13 VAL A 156 33.741 9.420 -0.281 1.00 41.68 H ATOM 2201 HG21 VAL A 156 36.798 9.446 0.263 1.00 41.72 H ATOM 2202 HG22 VAL A 156 36.191 8.963 -1.320 1.00 41.72 H ATOM 2203 HG23 VAL A 156 37.379 10.259 -1.174 1.00 41.72 H ATOM 2204 N LYS A 157 32.554 12.066 -2.066 1.00 39.19 N ATOM 2205 CA LYS A 157 31.364 12.855 -1.753 1.00 37.21 C ATOM 2206 C LYS A 157 30.448 12.020 -0.860 1.00 35.33 C ATOM 2207 O LYS A 157 30.394 10.804 -1.033 1.00 33.52 O ATOM 2208 CB LYS A 157 30.613 13.221 -3.044 1.00 38.54 C ATOM 2209 CG LYS A 157 31.374 14.195 -3.957 1.00 42.32 C ATOM 2210 CD LYS A 157 30.564 14.651 -5.183 1.00 44.23 C ATOM 2211 CE LYS A 157 30.042 13.484 -6.041 1.00 46.31 C ATOM 2212 NZ LYS A 157 29.441 13.952 -7.301 1.00 48.40 N1+ ATOM 2213 H LYS A 157 32.378 11.139 -2.432 1.00 39.19 H ATOM 2214 HA LYS A 157 31.636 13.767 -1.224 1.00 37.21 H ATOM 2215 HB3 LYS A 157 29.661 13.684 -2.780 1.00 38.54 H ATOM 2216 HB2 LYS A 157 30.368 12.305 -3.585 1.00 38.54 H ATOM 2217 HG3 LYS A 157 32.302 13.731 -4.294 1.00 42.32 H ATOM 2218 HG2 LYS A 157 31.669 15.073 -3.380 1.00 42.32 H ATOM 2219 HD3 LYS A 157 31.199 15.299 -5.788 1.00 44.23 H ATOM 2220 HD2 LYS A 157 29.731 15.273 -4.854 1.00 44.23 H ATOM 2221 HE3 LYS A 157 29.285 12.913 -5.502 1.00 46.31 H ATOM 2222 HE2 LYS A 157 30.858 12.801 -6.269 1.00 46.31 H ATOM 2223 HZ1 LYS A 157 28.645 14.539 -7.074 1.00 48.40 H ATOM 2224 HZ2 LYS A 157 30.113 14.485 -7.834 1.00 48.40 H ATOM 2225 HZ3 LYS A 157 29.111 13.167 -7.844 1.00 48.40 H ATOM 2226 N VAL A 158 29.719 12.691 0.042 1.00 34.70 N ATOM 2227 CA VAL A 158 28.712 12.071 0.897 1.00 32.77 C ATOM 2228 C VAL A 158 27.419 12.897 0.905 1.00 33.04 C ATOM 2229 O VAL A 158 27.466 14.124 0.841 1.00 33.91 O ATOM 2230 CB VAL A 158 29.195 11.895 2.364 1.00 32.67 C ATOM 2231 CG1 VAL A 158 30.320 10.856 2.474 1.00 31.61 C ATOM 2232 CG2 VAL A 158 29.590 13.197 3.086 1.00 33.84 C ATOM 2233 H VAL A 158 29.828 13.693 0.139 1.00 34.70 H ATOM 2234 HA VAL A 158 28.463 11.094 0.490 1.00 32.77 H ATOM 2235 HB VAL A 158 28.360 11.477 2.929 1.00 32.67 H ATOM 2236 HG11 VAL A 158 30.587 10.678 3.516 1.00 31.61 H ATOM 2237 HG12 VAL A 158 30.008 9.902 2.052 1.00 31.61 H ATOM 2238 HG13 VAL A 158 31.220 11.177 1.950 1.00 31.61 H ATOM 2239 HG21 VAL A 158 29.920 12.976 4.100 1.00 33.84 H ATOM 2240 HG22 VAL A 158 30.411 13.704 2.579 1.00 33.84 H ATOM 2241 HG23 VAL A 158 28.763 13.901 3.163 1.00 33.84 H ATOM 2242 N SER A 159 26.288 12.188 1.014 1.00 31.10 N ATOM 2243 CA SER A 159 24.956 12.763 1.155 1.00 29.81 C ATOM 2244 C SER A 159 24.130 11.910 2.125 1.00 27.90 C ATOM 2245 O SER A 159 24.349 10.703 2.221 1.00 26.67 O ATOM 2246 CB SER A 159 24.300 12.933 -0.234 1.00 29.49 C ATOM 2247 OG SER A 159 23.938 11.706 -0.832 1.00 33.07 O ATOM 2248 H SER A 159 26.335 11.178 1.066 1.00 31.10 H ATOM 2249 HA SER A 159 25.060 13.752 1.604 1.00 29.81 H ATOM 2250 HB3 SER A 159 24.963 13.476 -0.908 1.00 29.49 H ATOM 2251 HB2 SER A 159 23.394 13.532 -0.143 1.00 29.49 H ATOM 2252 HG SER A 159 23.162 11.357 -0.379 1.00 33.07 H ATOM 2253 N LEU A 160 23.191 12.566 2.816 1.00 28.07 N ATOM 2254 CA LEU A 160 22.306 11.969 3.803 1.00 24.85 C ATOM 2255 C LEU A 160 20.880 12.425 3.496 1.00 24.84 C ATOM 2256 O LEU A 160 20.458 13.495 3.937 1.00 25.97 O ATOM 2257 CB LEU A 160 22.785 12.377 5.208 1.00 25.10 C ATOM 2258 CG LEU A 160 22.040 11.742 6.395 1.00 24.01 C ATOM 2259 CD1 LEU A 160 22.077 10.203 6.383 1.00 23.66 C ATOM 2260 CD2 LEU A 160 22.594 12.318 7.710 1.00 27.15 C ATOM 2261 H LEU A 160 23.064 13.561 2.656 1.00 28.07 H ATOM 2262 HA LEU A 160 22.339 10.883 3.723 1.00 24.85 H ATOM 2263 HB3 LEU A 160 22.694 13.460 5.286 1.00 25.10 H ATOM 2264 HB2 LEU A 160 23.844 12.138 5.308 1.00 25.10 H ATOM 2265 HG LEU A 160 20.996 12.036 6.322 1.00 24.01 H ATOM 2266 HD11 LEU A 160 22.331 9.789 7.359 1.00 23.66 H ATOM 2267 HD12 LEU A 160 21.107 9.795 6.098 1.00 23.66 H ATOM 2268 HD13 LEU A 160 22.809 9.823 5.676 1.00 23.66 H ATOM 2269 HD21 LEU A 160 21.872 12.248 8.522 1.00 27.15 H ATOM 2270 HD22 LEU A 160 23.491 11.786 8.013 1.00 27.15 H ATOM 2271 HD23 LEU A 160 22.870 13.368 7.611 1.00 27.15 H ATOM 2272 N LEU A 161 20.178 11.585 2.725 1.00 23.65 N ATOM 2273 CA LEU A 161 18.763 11.735 2.419 1.00 23.59 C ATOM 2274 C LEU A 161 17.957 10.936 3.440 1.00 21.28 C ATOM 2275 O LEU A 161 18.292 9.777 3.681 1.00 20.76 O ATOM 2276 CB LEU A 161 18.505 11.202 0.998 1.00 25.98 C ATOM 2277 CG LEU A 161 17.033 11.282 0.536 1.00 27.94 C ATOM 2278 CD1 LEU A 161 16.530 12.740 0.453 1.00 26.95 C ATOM 2279 CD2 LEU A 161 16.840 10.505 -0.775 1.00 28.87 C ATOM 2280 H LEU A 161 20.608 10.725 2.416 1.00 23.65 H ATOM 2281 HA LEU A 161 18.486 12.789 2.464 1.00 23.59 H ATOM 2282 HB3 LEU A 161 18.833 10.162 0.949 1.00 25.98 H ATOM 2283 HB2 LEU A 161 19.133 11.741 0.294 1.00 25.98 H ATOM 2284 HG LEU A 161 16.399 10.772 1.262 1.00 27.94 H ATOM 2285 HD11 LEU A 161 16.005 12.957 -0.476 1.00 26.95 H ATOM 2286 HD12 LEU A 161 15.837 12.952 1.268 1.00 26.95 H ATOM 2287 HD13 LEU A 161 17.345 13.459 0.529 1.00 26.95 H ATOM 2288 HD21 LEU A 161 16.277 11.069 -1.518 1.00 28.87 H ATOM 2289 HD22 LEU A 161 17.790 10.223 -1.229 1.00 28.87 H ATOM 2290 HD23 LEU A 161 16.295 9.582 -0.586 1.00 28.87 H ATOM 2291 N GLU A 162 16.897 11.549 3.986 1.00 21.39 N ATOM 2292 CA GLU A 162 16.019 10.906 4.960 1.00 22.91 C ATOM 2293 C GLU A 162 14.555 11.099 4.593 1.00 21.99 C ATOM 2294 O GLU A 162 14.198 12.121 4.018 1.00 22.20 O ATOM 2295 CB GLU A 162 16.314 11.413 6.378 1.00 20.42 C ATOM 2296 CG GLU A 162 17.813 11.301 6.698 1.00 26.15 C ATOM 2297 CD GLU A 162 18.207 11.221 8.163 1.00 25.20 C ATOM 2298 OE1 GLU A 162 19.430 11.100 8.351 1.00 25.08 O ATOM 2299 OE2 GLU A 162 17.346 11.279 9.067 1.00 25.71 O1- ATOM 2300 H GLU A 162 16.682 12.509 3.746 1.00 21.39 H ATOM 2301 HA GLU A 162 16.202 9.834 4.931 1.00 22.91 H ATOM 2302 HB3 GLU A 162 15.718 10.829 7.081 1.00 20.42 H ATOM 2303 HB2 GLU A 162 15.992 12.449 6.483 1.00 20.42 H ATOM 2304 HG3 GLU A 162 18.343 12.141 6.245 1.00 26.15 H ATOM 2305 HG2 GLU A 162 18.219 10.404 6.234 1.00 26.15 H ATOM 2306 N ILE A 163 13.748 10.087 4.932 1.00 19.55 N ATOM 2307 CA ILE A 163 12.349 9.985 4.552 1.00 20.11 C ATOM 2308 C ILE A 163 11.533 9.827 5.840 1.00 19.59 C ATOM 2309 O ILE A 163 11.668 8.809 6.516 1.00 19.30 O ATOM 2310 CB ILE A 163 12.078 8.749 3.638 1.00 21.56 C ATOM 2311 CG1 ILE A 163 13.127 8.643 2.505 1.00 20.64 C ATOM 2312 CG2 ILE A 163 10.636 8.778 3.078 1.00 20.03 C ATOM 2313 CD1 ILE A 163 12.921 7.468 1.546 1.00 22.06 C ATOM 2314 H ILE A 163 14.131 9.298 5.439 1.00 19.55 H ATOM 2315 HA ILE A 163 12.029 10.877 4.019 1.00 20.11 H ATOM 2316 HB ILE A 163 12.171 7.837 4.228 1.00 21.56 H ATOM 2317 HG13 ILE A 163 14.128 8.540 2.925 1.00 20.64 H ATOM 2318 HG12 ILE A 163 13.142 9.570 1.940 1.00 20.64 H ATOM 2319 HG21 ILE A 163 10.416 7.893 2.482 1.00 20.03 H ATOM 2320 HG22 ILE A 163 9.887 8.806 3.870 1.00 20.03 H ATOM 2321 HG23 ILE A 163 10.476 9.651 2.444 1.00 20.03 H ATOM 2322 HD11 ILE A 163 13.870 7.141 1.119 1.00 22.06 H ATOM 2323 HD12 ILE A 163 12.479 6.616 2.060 1.00 22.06 H ATOM 2324 HD13 ILE A 163 12.267 7.746 0.721 1.00 22.06 H ATOM 2325 N TYR A 164 10.696 10.828 6.140 1.00 19.64 N ATOM 2326 CA TYR A 164 9.721 10.786 7.225 1.00 22.59 C ATOM 2327 C TYR A 164 8.374 11.223 6.644 1.00 21.43 C ATOM 2328 O TYR A 164 8.281 12.327 6.108 1.00 23.00 O ATOM 2329 CB TYR A 164 10.197 11.657 8.411 1.00 18.51 C ATOM 2330 CG TYR A 164 9.213 11.791 9.564 1.00 20.90 C ATOM 2331 CD1 TYR A 164 8.145 12.713 9.489 1.00 20.72 C ATOM 2332 CD2 TYR A 164 9.358 10.989 10.715 1.00 20.94 C ATOM 2333 CE1 TYR A 164 7.207 12.802 10.533 1.00 23.50 C ATOM 2334 CE2 TYR A 164 8.437 11.104 11.775 1.00 24.08 C ATOM 2335 CZ TYR A 164 7.352 11.996 11.676 1.00 23.90 C ATOM 2336 OH TYR A 164 6.450 12.096 12.694 1.00 25.55 O ATOM 2337 H TYR A 164 10.647 11.636 5.533 1.00 19.64 H ATOM 2338 HA TYR A 164 9.611 9.763 7.592 1.00 22.59 H ATOM 2339 HB3 TYR A 164 10.442 12.660 8.073 1.00 18.51 H ATOM 2340 HB2 TYR A 164 11.132 11.247 8.795 1.00 18.51 H ATOM 2341 HD1 TYR A 164 8.033 13.346 8.622 1.00 20.72 H ATOM 2342 HD2 TYR A 164 10.175 10.287 10.793 1.00 20.94 H ATOM 2343 HE1 TYR A 164 6.385 13.499 10.459 1.00 23.50 H ATOM 2344 HE2 TYR A 164 8.559 10.504 12.663 1.00 24.08 H ATOM 2345 HH TYR A 164 6.727 11.613 13.480 1.00 25.55 H ATOM 2346 N ASN A 165 7.362 10.345 6.766 1.00 22.76 N ATOM 2347 CA ASN A 165 5.983 10.536 6.297 1.00 27.93 C ATOM 2348 C ASN A 165 5.897 10.807 4.774 1.00 25.77 C ATOM 2349 O ASN A 165 5.116 11.654 4.343 1.00 25.97 O ATOM 2350 CB ASN A 165 5.284 11.629 7.154 1.00 30.06 C ATOM 2351 CG ASN A 165 3.753 11.598 7.077 1.00 37.45 C ATOM 2352 OD1 ASN A 165 3.134 10.551 7.252 1.00 40.14 O ATOM 2353 ND2 ASN A 165 3.138 12.753 6.813 1.00 39.66 N ATOM 2354 H ASN A 165 7.538 9.465 7.237 1.00 22.76 H ATOM 2355 HA ASN A 165 5.457 9.591 6.434 1.00 27.93 H ATOM 2356 HB3 ASN A 165 5.663 12.622 6.904 1.00 30.06 H ATOM 2357 HB2 ASN A 165 5.531 11.470 8.204 1.00 30.06 H ATOM 2358 HD22 ASN A 165 2.132 12.785 6.747 1.00 39.66 H ATOM 2359 HD21 ASN A 165 3.673 13.595 6.653 1.00 39.66 H ATOM 2360 N GLU A 166 6.738 10.110 3.987 1.00 25.78 N ATOM 2361 CA GLU A 166 6.918 10.284 2.536 1.00 27.67 C ATOM 2362 C GLU A 166 7.451 11.664 2.104 1.00 27.00 C ATOM 2363 O GLU A 166 7.320 12.014 0.930 1.00 28.61 O ATOM 2364 CB GLU A 166 5.646 9.878 1.740 1.00 29.56 C ATOM 2365 CG GLU A 166 5.176 8.430 1.952 1.00 29.68 C ATOM 2366 CD GLU A 166 6.246 7.410 1.559 1.00 30.08 C ATOM 2367 OE1 GLU A 166 6.974 6.970 2.473 1.00 27.75 O ATOM 2368 OE2 GLU A 166 6.325 7.090 0.354 1.00 28.15 O1- ATOM 2369 H GLU A 166 7.338 9.418 4.415 1.00 25.78 H ATOM 2370 HA GLU A 166 7.729 9.609 2.263 1.00 27.67 H ATOM 2371 HB3 GLU A 166 5.813 10.018 0.670 1.00 29.56 H ATOM 2372 HB2 GLU A 166 4.824 10.550 1.986 1.00 29.56 H ATOM 2373 HG3 GLU A 166 4.275 8.248 1.365 1.00 29.68 H ATOM 2374 HG2 GLU A 166 4.885 8.283 2.991 1.00 29.68 H ATOM 2375 N GLU A 167 8.070 12.407 3.035 1.00 26.94 N ATOM 2376 CA GLU A 167 8.728 13.677 2.757 1.00 27.18 C ATOM 2377 C GLU A 167 10.241 13.479 2.866 1.00 28.13 C ATOM 2378 O GLU A 167 10.716 12.938 3.864 1.00 24.51 O ATOM 2379 CB GLU A 167 8.249 14.772 3.724 1.00 31.62 C ATOM 2380 CG GLU A 167 6.712 14.884 3.845 1.00 40.49 C ATOM 2381 CD GLU A 167 6.180 16.204 4.427 1.00 46.73 C ATOM 2382 OE1 GLU A 167 6.986 17.113 4.729 1.00 51.21 O ATOM 2383 OE2 GLU A 167 4.938 16.298 4.528 1.00 50.72 O1- ATOM 2384 H GLU A 167 8.134 12.074 3.987 1.00 26.94 H ATOM 2385 HA GLU A 167 8.488 14.013 1.748 1.00 27.18 H ATOM 2386 HB3 GLU A 167 8.678 15.715 3.380 1.00 31.62 H ATOM 2387 HB2 GLU A 167 8.656 14.599 4.718 1.00 31.62 H ATOM 2388 HG3 GLU A 167 6.353 14.073 4.480 1.00 40.49 H ATOM 2389 HG2 GLU A 167 6.248 14.724 2.872 1.00 40.49 H ATOM 2390 N LEU A 168 10.955 13.934 1.830 1.00 25.62 N ATOM 2391 CA LEU A 168 12.407 13.871 1.716 1.00 26.26 C ATOM 2392 C LEU A 168 13.048 15.068 2.427 1.00 27.12 C ATOM 2393 O LEU A 168 12.573 16.189 2.263 1.00 27.76 O ATOM 2394 CB LEU A 168 12.789 13.886 0.225 1.00 26.24 C ATOM 2395 CG LEU A 168 12.244 12.705 -0.602 1.00 27.75 C ATOM 2396 CD1 LEU A 168 12.632 12.868 -2.083 1.00 26.99 C ATOM 2397 CD2 LEU A 168 12.667 11.338 -0.037 1.00 24.52 C ATOM 2398 H LEU A 168 10.475 14.361 1.048 1.00 25.62 H ATOM 2399 HA LEU A 168 12.758 12.946 2.169 1.00 26.26 H ATOM 2400 HB3 LEU A 168 13.875 13.911 0.133 1.00 26.24 H ATOM 2401 HB2 LEU A 168 12.424 14.812 -0.220 1.00 26.24 H ATOM 2402 HG LEU A 168 11.154 12.740 -0.564 1.00 27.75 H ATOM 2403 HD11 LEU A 168 11.737 12.916 -2.701 1.00 26.99 H ATOM 2404 HD12 LEU A 168 13.192 13.786 -2.264 1.00 26.99 H ATOM 2405 HD13 LEU A 168 13.246 12.046 -2.452 1.00 26.99 H ATOM 2406 HD21 LEU A 168 12.868 10.606 -0.817 1.00 24.52 H ATOM 2407 HD22 LEU A 168 13.567 11.414 0.574 1.00 24.52 H ATOM 2408 HD23 LEU A 168 11.870 10.926 0.583 1.00 24.52 H ATOM 2409 N PHE A 169 14.124 14.803 3.177 1.00 27.59 N ATOM 2410 CA PHE A 169 14.868 15.787 3.954 1.00 28.06 C ATOM 2411 C PHE A 169 16.367 15.569 3.752 1.00 27.91 C ATOM 2412 O PHE A 169 16.814 14.435 3.584 1.00 26.56 O ATOM 2413 CB PHE A 169 14.509 15.657 5.448 1.00 27.08 C ATOM 2414 CG PHE A 169 13.043 15.882 5.762 1.00 29.27 C ATOM 2415 CD1 PHE A 169 12.213 14.804 6.134 1.00 26.75 C ATOM 2416 CD2 PHE A 169 12.467 17.153 5.562 1.00 29.59 C ATOM 2417 CE1 PHE A 169 10.861 15.027 6.356 1.00 29.38 C ATOM 2418 CE2 PHE A 169 11.120 17.359 5.817 1.00 29.78 C ATOM 2419 CZ PHE A 169 10.322 16.299 6.219 1.00 29.34 C ATOM 2420 H PHE A 169 14.431 13.843 3.280 1.00 27.59 H ATOM 2421 HA PHE A 169 14.627 16.796 3.611 1.00 28.06 H ATOM 2422 HB3 PHE A 169 15.077 16.395 6.017 1.00 27.08 H ATOM 2423 HB2 PHE A 169 14.812 14.681 5.832 1.00 27.08 H ATOM 2424 HD1 PHE A 169 12.619 13.808 6.238 1.00 26.75 H ATOM 2425 HD2 PHE A 169 13.070 17.964 5.186 1.00 29.59 H ATOM 2426 HE1 PHE A 169 10.213 14.210 6.626 1.00 29.38 H ATOM 2427 HE2 PHE A 169 10.688 18.340 5.677 1.00 29.78 H ATOM 2428 HZ PHE A 169 9.269 16.457 6.400 1.00 29.34 H ATOM 2429 N ASP A 170 17.109 16.680 3.802 1.00 28.99 N ATOM 2430 CA ASP A 170 18.554 16.738 3.668 1.00 31.65 C ATOM 2431 C ASP A 170 19.115 17.011 5.069 1.00 31.23 C ATOM 2432 O ASP A 170 18.846 18.070 5.634 1.00 33.73 O ATOM 2433 CB ASP A 170 18.923 17.840 2.652 1.00 32.63 C ATOM 2434 CG ASP A 170 20.381 17.900 2.188 1.00 36.16 C ATOM 2435 OD1 ASP A 170 21.291 17.440 2.913 1.00 37.04 O ATOM 2436 OD2 ASP A 170 20.576 18.543 1.139 1.00 37.99 O1- ATOM 2437 H ASP A 170 16.659 17.570 3.984 1.00 28.99 H ATOM 2438 HA ASP A 170 18.941 15.785 3.299 1.00 31.65 H ATOM 2439 HB3 ASP A 170 18.651 18.819 3.054 1.00 32.63 H ATOM 2440 HB2 ASP A 170 18.289 17.729 1.774 1.00 32.63 H ATOM 2441 N LEU A 171 19.872 16.041 5.600 1.00 32.05 N ATOM 2442 CA LEU A 171 20.402 16.076 6.962 1.00 33.78 C ATOM 2443 C LEU A 171 21.898 16.424 7.024 1.00 36.20 C ATOM 2444 O LEU A 171 22.421 16.452 8.135 1.00 37.78 O ATOM 2445 CB LEU A 171 20.058 14.747 7.678 1.00 31.15 C ATOM 2446 CG LEU A 171 18.695 14.759 8.402 1.00 31.77 C ATOM 2447 CD1 LEU A 171 18.679 15.685 9.621 1.00 29.95 C ATOM 2448 CD2 LEU A 171 17.497 14.983 7.464 1.00 27.08 C ATOM 2449 H LEU A 171 20.055 15.200 5.068 1.00 32.05 H ATOM 2450 HA LEU A 171 19.925 16.881 7.523 1.00 33.78 H ATOM 2451 HB3 LEU A 171 20.814 14.496 8.422 1.00 31.15 H ATOM 2452 HB2 LEU A 171 20.079 13.929 6.960 1.00 31.15 H ATOM 2453 HG LEU A 171 18.586 13.765 8.822 1.00 31.77 H ATOM 2454 HD11 LEU A 171 18.104 15.244 10.434 1.00 29.95 H ATOM 2455 HD12 LEU A 171 19.685 15.874 9.993 1.00 29.95 H ATOM 2456 HD13 LEU A 171 18.226 16.642 9.385 1.00 29.95 H ATOM 2457 HD21 LEU A 171 16.625 14.435 7.814 1.00 27.08 H ATOM 2458 HD22 LEU A 171 17.217 16.034 7.401 1.00 27.08 H ATOM 2459 HD23 LEU A 171 17.703 14.632 6.453 1.00 27.08 H ATOM 2460 N LEU A 172 22.550 16.751 5.892 1.00 38.78 N ATOM 2461 CA LEU A 172 23.935 17.241 5.883 1.00 42.77 C ATOM 2462 C LEU A 172 24.066 18.716 5.474 1.00 44.63 C ATOM 2463 O LEU A 172 25.080 19.299 5.852 1.00 46.83 O ATOM 2464 CB LEU A 172 24.832 16.352 4.992 1.00 39.05 C ATOM 2465 CG LEU A 172 25.307 15.037 5.645 1.00 37.98 C ATOM 2466 CD1 LEU A 172 26.123 14.192 4.643 1.00 35.12 C ATOM 2467 CD2 LEU A 172 26.075 15.258 6.962 1.00 35.36 C ATOM 2468 H LEU A 172 22.069 16.724 5.002 1.00 38.78 H ATOM 2469 HA LEU A 172 24.344 17.220 6.893 1.00 42.77 H ATOM 2470 HB3 LEU A 172 25.727 16.901 4.703 1.00 39.05 H ATOM 2471 HB2 LEU A 172 24.313 16.142 4.059 1.00 39.05 H ATOM 2472 HG LEU A 172 24.424 14.469 5.913 1.00 37.98 H ATOM 2473 HD11 LEU A 172 25.708 13.191 4.535 1.00 35.12 H ATOM 2474 HD12 LEU A 172 26.142 14.639 3.649 1.00 35.12 H ATOM 2475 HD13 LEU A 172 27.162 14.073 4.950 1.00 35.12 H ATOM 2476 HD21 LEU A 172 26.871 14.529 7.105 1.00 35.36 H ATOM 2477 HD22 LEU A 172 26.525 16.250 7.011 1.00 35.36 H ATOM 2478 HD23 LEU A 172 25.406 15.157 7.815 1.00 35.36 H ATOM 2479 N ASN A 173 23.092 19.302 4.748 1.00 48.64 N ATOM 2480 CA ASN A 173 23.133 20.692 4.261 1.00 51.22 C ATOM 2481 C ASN A 173 23.265 21.701 5.426 1.00 53.10 C ATOM 2482 O ASN A 173 22.304 21.851 6.180 1.00 51.10 O ATOM 2483 CB ASN A 173 21.855 20.967 3.432 1.00 53.38 C ATOM 2484 CG ASN A 173 21.805 22.326 2.717 1.00 55.13 C ATOM 2485 OD1 ASN A 173 22.729 23.131 2.801 1.00 57.22 O ATOM 2486 ND2 ASN A 173 20.729 22.571 1.970 1.00 54.72 N ATOM 2487 H ASN A 173 22.302 18.749 4.439 1.00 48.64 H ATOM 2488 HA ASN A 173 23.978 20.739 3.576 1.00 51.22 H ATOM 2489 HB3 ASN A 173 20.953 20.828 4.030 1.00 53.38 H ATOM 2490 HB2 ASN A 173 21.824 20.230 2.638 1.00 53.38 H ATOM 2491 HD22 ASN A 173 20.662 23.429 1.441 1.00 54.72 H ATOM 2492 HD21 ASN A 173 20.003 21.875 1.876 1.00 54.72 H ATOM 2493 N PRO A 174 24.427 22.381 5.556 1.00 55.43 N ATOM 2494 CA PRO A 174 24.622 23.370 6.626 1.00 55.93 C ATOM 2495 C PRO A 174 23.961 24.738 6.347 1.00 56.43 C ATOM 2496 O PRO A 174 23.924 25.563 7.259 1.00 57.87 O ATOM 2497 CB PRO A 174 26.151 23.476 6.701 1.00 56.37 C ATOM 2498 CG PRO A 174 26.603 23.310 5.258 1.00 57.18 C ATOM 2499 CD PRO A 174 25.612 22.296 4.692 1.00 55.65 C ATOM 2500 HA PRO A 174 24.239 22.998 7.578 1.00 55.93 H ATOM 2501 HB3 PRO A 174 26.540 22.654 7.305 1.00 56.37 H ATOM 2502 HB2 PRO A 174 26.509 24.405 7.147 1.00 56.37 H ATOM 2503 HG3 PRO A 174 27.642 22.996 5.162 1.00 57.18 H ATOM 2504 HG2 PRO A 174 26.492 24.260 4.733 1.00 57.18 H ATOM 2505 HD2 PRO A 174 25.383 22.520 3.649 1.00 55.65 H ATOM 2506 HD3 PRO A 174 26.043 21.298 4.737 1.00 55.65 H ATOM 2507 N SER A 175 23.478 24.962 5.110 1.00 56.90 N ATOM 2508 CA SER A 175 22.917 26.234 4.655 1.00 57.82 C ATOM 2509 C SER A 175 21.427 26.351 5.007 1.00 58.21 C ATOM 2510 O SER A 175 21.030 27.361 5.587 1.00 59.23 O ATOM 2511 CB SER A 175 23.116 26.386 3.132 1.00 58.15 C ATOM 2512 OG SER A 175 24.487 26.344 2.795 1.00 58.20 O ATOM 2513 H SER A 175 23.525 24.227 4.417 1.00 56.90 H ATOM 2514 HA SER A 175 23.447 27.053 5.146 1.00 57.82 H ATOM 2515 HB3 SER A 175 22.720 27.346 2.798 1.00 58.15 H ATOM 2516 HB2 SER A 175 22.582 25.622 2.569 1.00 58.15 H ATOM 2517 HG SER A 175 24.795 25.438 2.878 1.00 58.20 H ATOM 2518 N SER A 176 20.641 25.321 4.652 1.00 58.11 N ATOM 2519 CA SER A 176 19.201 25.264 4.893 1.00 57.43 C ATOM 2520 C SER A 176 18.903 24.357 6.097 1.00 57.06 C ATOM 2521 O SER A 176 19.651 23.416 6.358 1.00 56.98 O ATOM 2522 CB SER A 176 18.519 24.749 3.613 1.00 58.25 C ATOM 2523 OG SER A 176 17.116 24.806 3.721 1.00 59.33 O ATOM 2524 H SER A 176 21.050 24.514 4.205 1.00 58.11 H ATOM 2525 HA SER A 176 18.816 26.263 5.106 1.00 57.43 H ATOM 2526 HB3 SER A 176 18.800 23.716 3.414 1.00 58.25 H ATOM 2527 HB2 SER A 176 18.821 25.342 2.748 1.00 58.25 H ATOM 2528 HG SER A 176 16.809 25.690 3.498 1.00 59.33 H ATOM 2529 N ASP A 177 17.790 24.649 6.786 1.00 56.57 N ATOM 2530 CA ASP A 177 17.235 23.873 7.901 1.00 57.04 C ATOM 2531 C ASP A 177 16.579 22.562 7.423 1.00 55.49 C ATOM 2532 O ASP A 177 16.300 22.407 6.233 1.00 54.80 O ATOM 2533 CB ASP A 177 16.266 24.712 8.788 1.00 59.67 C ATOM 2534 CG ASP A 177 15.378 25.748 8.070 1.00 62.71 C ATOM 2535 OD1 ASP A 177 14.852 25.430 6.979 1.00 63.65 O ATOM 2536 OD2 ASP A 177 15.145 26.810 8.686 1.00 64.94 O1- ATOM 2537 H ASP A 177 17.208 25.413 6.470 1.00 56.57 H ATOM 2538 HA ASP A 177 18.079 23.589 8.533 1.00 57.04 H ATOM 2539 HB3 ASP A 177 16.863 25.222 9.546 1.00 59.67 H ATOM 2540 HB2 ASP A 177 15.595 24.060 9.350 1.00 59.67 H ATOM 2541 N VAL A 178 16.343 21.634 8.367 1.00 53.79 N ATOM 2542 CA VAL A 178 15.723 20.332 8.095 1.00 52.83 C ATOM 2543 C VAL A 178 14.278 20.406 7.574 1.00 52.35 C ATOM 2544 O VAL A 178 13.897 19.522 6.816 1.00 53.10 O ATOM 2545 CB VAL A 178 15.698 19.406 9.336 1.00 52.72 C ATOM 2546 CG1 VAL A 178 17.108 19.092 9.820 1.00 52.31 C ATOM 2547 CG2 VAL A 178 14.819 19.901 10.498 1.00 53.46 C ATOM 2548 H VAL A 178 16.580 21.823 9.330 1.00 53.79 H ATOM 2549 HA VAL A 178 16.325 19.847 7.324 1.00 52.83 H ATOM 2550 HB VAL A 178 15.286 18.445 9.020 1.00 52.72 H ATOM 2551 HG11 VAL A 178 17.080 18.289 10.550 1.00 52.31 H ATOM 2552 HG12 VAL A 178 17.740 18.772 8.992 1.00 52.31 H ATOM 2553 HG13 VAL A 178 17.567 19.958 10.294 1.00 52.31 H ATOM 2554 HG21 VAL A 178 14.971 19.292 11.385 1.00 53.46 H ATOM 2555 HG22 VAL A 178 15.050 20.931 10.768 1.00 53.46 H ATOM 2556 HG23 VAL A 178 13.760 19.839 10.251 1.00 53.46 H ATOM 2557 N SER A 179 13.519 21.448 7.957 1.00 51.84 N ATOM 2558 CA SER A 179 12.134 21.677 7.532 1.00 50.53 C ATOM 2559 C SER A 179 11.957 21.927 6.020 1.00 49.55 C ATOM 2560 O SER A 179 10.836 21.802 5.527 1.00 48.64 O ATOM 2561 CB SER A 179 11.533 22.809 8.390 1.00 50.49 C ATOM 2562 OG SER A 179 12.186 24.046 8.186 1.00 49.66 O ATOM 2563 H SER A 179 13.912 22.160 8.556 1.00 51.84 H ATOM 2564 HA SER A 179 11.578 20.766 7.760 1.00 50.53 H ATOM 2565 HB3 SER A 179 11.590 22.553 9.447 1.00 50.49 H ATOM 2566 HB2 SER A 179 10.474 22.936 8.160 1.00 50.49 H ATOM 2567 HG SER A 179 12.054 24.334 7.279 1.00 49.66 H ATOM 2568 N GLU A 180 13.058 22.246 5.319 1.00 49.36 N ATOM 2569 CA GLU A 180 13.113 22.473 3.882 1.00 49.04 C ATOM 2570 C GLU A 180 13.111 21.123 3.140 1.00 48.31 C ATOM 2571 O GLU A 180 14.169 20.533 2.924 1.00 48.45 O ATOM 2572 CB GLU A 180 14.378 23.308 3.597 1.00 51.29 C ATOM 2573 CG GLU A 180 14.324 24.086 2.267 1.00 55.71 C ATOM 2574 CD GLU A 180 13.886 25.541 2.488 1.00 58.55 C ATOM 2575 OE1 GLU A 180 12.722 25.737 2.906 1.00 58.48 O ATOM 2576 OE2 GLU A 180 14.726 26.437 2.249 1.00 58.81 O1- ATOM 2577 H GLU A 180 13.940 22.333 5.806 1.00 49.36 H ATOM 2578 HA GLU A 180 12.232 23.049 3.590 1.00 49.04 H ATOM 2579 HB3 GLU A 180 15.264 22.673 3.589 1.00 51.29 H ATOM 2580 HB2 GLU A 180 14.559 23.996 4.426 1.00 51.29 H ATOM 2581 HG3 GLU A 180 13.648 23.606 1.558 1.00 55.71 H ATOM 2582 HG2 GLU A 180 15.307 24.066 1.794 1.00 55.71 H ATOM 2583 N ARG A 181 11.908 20.641 2.795 1.00 46.01 N ATOM 2584 CA ARG A 181 11.706 19.364 2.113 1.00 46.71 C ATOM 2585 C ARG A 181 12.213 19.394 0.656 1.00 45.19 C ATOM 2586 O ARG A 181 12.084 20.415 -0.022 1.00 45.10 O ATOM 2587 CB ARG A 181 10.220 18.964 2.224 1.00 48.88 C ATOM 2588 CG ARG A 181 9.244 19.850 1.418 1.00 53.95 C ATOM 2589 CD ARG A 181 7.754 19.627 1.735 1.00 58.90 C ATOM 2590 NE ARG A 181 7.311 18.229 1.586 1.00 62.40 N ATOM 2591 CZ ARG A 181 7.171 17.509 0.457 1.00 63.28 C ATOM 2592 NH1 ARG A 181 7.504 17.984 -0.753 1.00 64.77 N ATOM 2593 NH2 ARG A 181 6.678 16.268 0.547 1.00 63.18 N1+ ATOM 2594 H ARG A 181 11.077 21.165 3.030 1.00 46.01 H ATOM 2595 HA ARG A 181 12.289 18.630 2.669 1.00 46.71 H ATOM 2596 HB3 ARG A 181 9.929 18.968 3.275 1.00 48.88 H ATOM 2597 HB2 ARG A 181 10.117 17.929 1.894 1.00 48.88 H ATOM 2598 HG3 ARG A 181 9.426 19.814 0.344 1.00 53.95 H ATOM 2599 HG2 ARG A 181 9.457 20.880 1.705 1.00 53.95 H ATOM 2600 HD3 ARG A 181 7.165 20.192 1.013 1.00 58.90 H ATOM 2601 HD2 ARG A 181 7.489 20.033 2.712 1.00 58.90 H ATOM 2602 HE ARG A 181 7.090 17.776 2.466 1.00 62.40 H ATOM 2603 HH12 ARG A 181 7.380 17.423 -1.583 1.00 64.77 H ATOM 2604 HH11 ARG A 181 7.879 18.918 -0.836 1.00 64.77 H ATOM 2605 HH22 ARG A 181 6.537 15.704 -0.278 1.00 63.18 H ATOM 2606 HH21 ARG A 181 6.397 15.901 1.447 1.00 63.18 H ATOM 2607 N LEU A 182 12.770 18.259 0.209 1.00 41.92 N ATOM 2608 CA LEU A 182 13.299 18.066 -1.143 1.00 39.89 C ATOM 2609 C LEU A 182 12.213 17.500 -2.073 1.00 38.35 C ATOM 2610 O LEU A 182 11.207 16.974 -1.598 1.00 38.67 O ATOM 2611 CB LEU A 182 14.511 17.107 -1.092 1.00 40.08 C ATOM 2612 CG LEU A 182 15.627 17.483 -0.091 1.00 39.80 C ATOM 2613 CD1 LEU A 182 16.759 16.436 -0.147 1.00 39.86 C ATOM 2614 CD2 LEU A 182 16.149 18.923 -0.282 1.00 39.90 C ATOM 2615 H LEU A 182 12.827 17.461 0.829 1.00 41.92 H ATOM 2616 HA LEU A 182 13.623 19.025 -1.551 1.00 39.89 H ATOM 2617 HB3 LEU A 182 14.946 17.033 -2.090 1.00 40.08 H ATOM 2618 HB2 LEU A 182 14.167 16.103 -0.852 1.00 40.08 H ATOM 2619 HG LEU A 182 15.209 17.425 0.915 1.00 39.80 H ATOM 2620 HD11 LEU A 182 16.928 15.991 0.834 1.00 39.86 H ATOM 2621 HD12 LEU A 182 16.529 15.616 -0.827 1.00 39.86 H ATOM 2622 HD13 LEU A 182 17.704 16.860 -0.480 1.00 39.86 H ATOM 2623 HD21 LEU A 182 17.227 18.999 -0.141 1.00 39.90 H ATOM 2624 HD22 LEU A 182 15.931 19.308 -1.278 1.00 39.90 H ATOM 2625 HD23 LEU A 182 15.688 19.597 0.441 1.00 39.90 H ATOM 2626 N GLN A 183 12.449 17.604 -3.387 1.00 36.55 N ATOM 2627 CA GLN A 183 11.569 17.071 -4.429 1.00 36.23 C ATOM 2628 C GLN A 183 12.327 15.986 -5.198 1.00 33.70 C ATOM 2629 O GLN A 183 13.508 16.181 -5.482 1.00 32.46 O ATOM 2630 CB GLN A 183 11.155 18.217 -5.375 1.00 40.21 C ATOM 2631 CG GLN A 183 10.294 19.294 -4.686 1.00 46.32 C ATOM 2632 CD GLN A 183 10.070 20.524 -5.567 1.00 51.85 C ATOM 2633 OE1 GLN A 183 9.771 20.409 -6.753 1.00 53.00 O ATOM 2634 NE2 GLN A 183 10.189 21.717 -4.981 1.00 54.16 N ATOM 2635 H GLN A 183 13.312 18.021 -3.708 1.00 36.55 H ATOM 2636 HA GLN A 183 10.668 16.627 -4.002 1.00 36.23 H ATOM 2637 HB3 GLN A 183 10.599 17.807 -6.220 1.00 40.21 H ATOM 2638 HB2 GLN A 183 12.049 18.680 -5.798 1.00 40.21 H ATOM 2639 HG3 GLN A 183 10.767 19.618 -3.758 1.00 46.32 H ATOM 2640 HG2 GLN A 183 9.325 18.877 -4.409 1.00 46.32 H ATOM 2641 HE22 GLN A 183 10.020 22.560 -5.510 1.00 54.16 H ATOM 2642 HE21 GLN A 183 10.426 21.786 -4.002 1.00 54.16 H ATOM 2643 N MET A 184 11.634 14.890 -5.554 1.00 32.15 N ATOM 2644 CA MET A 184 12.185 13.854 -6.428 1.00 35.07 C ATOM 2645 C MET A 184 11.328 13.685 -7.684 1.00 35.72 C ATOM 2646 O MET A 184 10.109 13.860 -7.649 1.00 34.61 O ATOM 2647 CB MET A 184 12.407 12.522 -5.682 1.00 34.84 C ATOM 2648 CG MET A 184 11.141 11.723 -5.318 1.00 38.74 C ATOM 2649 SD MET A 184 11.469 10.099 -4.586 1.00 41.75 S ATOM 2650 CE MET A 184 12.019 9.209 -6.055 1.00 40.67 C ATOM 2651 H MET A 184 10.658 14.802 -5.315 1.00 32.15 H ATOM 2652 HA MET A 184 13.162 14.185 -6.768 1.00 35.07 H ATOM 2653 HB3 MET A 184 12.998 12.711 -4.787 1.00 34.84 H ATOM 2654 HB2 MET A 184 13.047 11.899 -6.306 1.00 34.84 H ATOM 2655 HG3 MET A 184 10.513 11.553 -6.192 1.00 38.74 H ATOM 2656 HG2 MET A 184 10.539 12.299 -4.616 1.00 38.74 H ATOM 2657 HE1 MET A 184 12.197 8.162 -5.816 1.00 40.67 H ATOM 2658 HE2 MET A 184 11.275 9.266 -6.846 1.00 40.67 H ATOM 2659 HE3 MET A 184 12.946 9.641 -6.425 1.00 40.67 H ATOM 2660 N PHE A 185 12.027 13.326 -8.765 1.00 38.29 N ATOM 2661 CA PHE A 185 11.511 13.112 -10.109 1.00 42.79 C ATOM 2662 C PHE A 185 12.190 11.854 -10.660 1.00 44.70 C ATOM 2663 O PHE A 185 13.246 11.458 -10.169 1.00 44.77 O ATOM 2664 CB PHE A 185 11.885 14.325 -10.993 1.00 43.13 C ATOM 2665 CG PHE A 185 11.475 15.680 -10.444 1.00 43.75 C ATOM 2666 CD1 PHE A 185 12.364 16.403 -9.619 1.00 43.96 C ATOM 2667 CD2 PHE A 185 10.152 16.142 -10.600 1.00 44.55 C ATOM 2668 CE1 PHE A 185 11.950 17.586 -9.023 1.00 44.32 C ATOM 2669 CE2 PHE A 185 9.760 17.332 -10.002 1.00 45.42 C ATOM 2670 CZ PHE A 185 10.658 18.052 -9.225 1.00 45.48 C ATOM 2671 H PHE A 185 13.027 13.195 -8.672 1.00 38.29 H ATOM 2672 HA PHE A 185 10.429 12.968 -10.092 1.00 42.79 H ATOM 2673 HB3 PHE A 185 11.422 14.208 -11.975 1.00 43.13 H ATOM 2674 HB2 PHE A 185 12.962 14.343 -11.174 1.00 43.13 H ATOM 2675 HD1 PHE A 185 13.365 16.035 -9.441 1.00 43.96 H ATOM 2676 HD2 PHE A 185 9.442 15.574 -11.185 1.00 44.55 H ATOM 2677 HE1 PHE A 185 12.632 18.143 -8.397 1.00 44.32 H ATOM 2678 HE2 PHE A 185 8.752 17.694 -10.134 1.00 45.42 H ATOM 2679 HZ PHE A 185 10.344 18.976 -8.766 1.00 45.48 H ATOM 2680 N ASP A 186 11.608 11.273 -11.714 1.00 49.80 N ATOM 2681 CA ASP A 186 12.247 10.204 -12.488 1.00 53.56 C ATOM 2682 C ASP A 186 13.375 10.786 -13.350 1.00 53.93 C ATOM 2683 O ASP A 186 13.199 11.856 -13.933 1.00 53.64 O ATOM 2684 CB ASP A 186 11.238 9.432 -13.367 1.00 56.42 C ATOM 2685 CG ASP A 186 10.033 8.857 -12.608 1.00 58.79 C ATOM 2686 OD1 ASP A 186 9.009 8.610 -13.280 1.00 61.00 O ATOM 2687 OD2 ASP A 186 10.179 8.532 -11.406 1.00 60.88 O1- ATOM 2688 H ASP A 186 10.743 11.638 -12.085 1.00 49.80 H ATOM 2689 HA ASP A 186 12.695 9.493 -11.790 1.00 53.56 H ATOM 2690 HB3 ASP A 186 11.742 8.602 -13.863 1.00 56.42 H ATOM 2691 HB2 ASP A 186 10.860 10.092 -14.151 1.00 56.42 H ATOM 2692 N ASP A 187 14.506 10.066 -13.412 1.00 55.24 N ATOM 2693 CA ASP A 187 15.660 10.426 -14.235 1.00 58.13 C ATOM 2694 C ASP A 187 15.295 10.136 -15.712 1.00 59.52 C ATOM 2695 O ASP A 187 14.926 8.996 -15.999 1.00 59.93 O ATOM 2696 CB ASP A 187 16.911 9.644 -13.752 1.00 58.39 C ATOM 2697 CG ASP A 187 18.283 10.085 -14.307 1.00 59.33 C ATOM 2698 OD1 ASP A 187 18.375 10.537 -15.470 1.00 60.74 O ATOM 2699 OD2 ASP A 187 19.271 9.846 -13.580 1.00 60.02 O1- ATOM 2700 H ASP A 187 14.570 9.185 -12.921 1.00 55.24 H ATOM 2701 HA ASP A 187 15.863 11.477 -14.052 1.00 58.13 H ATOM 2702 HB3 ASP A 187 16.784 8.582 -13.960 1.00 58.39 H ATOM 2703 HB2 ASP A 187 16.948 9.704 -12.663 1.00 58.39 H ATOM 2704 N PRO A 188 15.387 11.151 -16.613 1.00 60.65 N ATOM 2705 CA PRO A 188 15.169 10.977 -18.066 1.00 62.13 C ATOM 2706 C PRO A 188 15.918 9.815 -18.748 1.00 63.15 C ATOM 2707 O PRO A 188 15.374 9.233 -19.685 1.00 63.29 O ATOM 2708 CB PRO A 188 15.589 12.328 -18.669 1.00 62.23 C ATOM 2709 CG PRO A 188 15.324 13.330 -17.563 1.00 61.55 C ATOM 2710 CD PRO A 188 15.690 12.553 -16.309 1.00 60.85 C ATOM 2711 HA PRO A 188 14.096 10.835 -18.208 1.00 62.13 H ATOM 2712 HB3 PRO A 188 15.044 12.568 -19.582 1.00 62.23 H ATOM 2713 HB2 PRO A 188 16.654 12.331 -18.909 1.00 62.23 H ATOM 2714 HG3 PRO A 188 14.260 13.571 -17.542 1.00 61.55 H ATOM 2715 HG2 PRO A 188 15.879 14.262 -17.675 1.00 61.55 H ATOM 2716 HD2 PRO A 188 16.757 12.650 -16.110 1.00 60.85 H ATOM 2717 HD3 PRO A 188 15.132 12.945 -15.459 1.00 60.85 H ATOM 2718 N ARG A 189 17.128 9.495 -18.256 1.00 64.44 N ATOM 2719 CA ARG A 189 17.941 8.367 -18.704 1.00 65.37 C ATOM 2720 C ARG A 189 17.538 7.090 -17.948 1.00 66.47 C ATOM 2721 O ARG A 189 16.638 6.387 -18.409 1.00 66.61 O ATOM 2722 CB ARG A 189 19.440 8.703 -18.541 1.00 65.44 C ATOM 2723 CG ARG A 189 19.894 9.938 -19.326 1.00 66.51 C ATOM 2724 CD ARG A 189 21.406 10.165 -19.175 1.00 66.86 C ATOM 2725 NE ARG A 189 21.821 11.485 -19.674 1.00 66.26 N ATOM 2726 CZ ARG A 189 21.719 12.656 -19.015 1.00 66.65 C ATOM 2727 NH1 ARG A 189 21.194 12.743 -17.781 1.00 66.57 N ATOM 2728 NH2 ARG A 189 22.156 13.771 -19.612 1.00 65.04 N1+ ATOM 2729 H ARG A 189 17.492 10.010 -17.464 1.00 64.44 H ATOM 2730 HA ARG A 189 17.758 8.189 -19.766 1.00 65.37 H ATOM 2731 HB3 ARG A 189 20.039 7.845 -18.853 1.00 65.44 H ATOM 2732 HB2 ARG A 189 19.674 8.874 -17.489 1.00 65.44 H ATOM 2733 HG3 ARG A 189 19.318 10.832 -19.082 1.00 66.51 H ATOM 2734 HG2 ARG A 189 19.686 9.721 -20.375 1.00 66.51 H ATOM 2735 HD3 ARG A 189 21.914 9.469 -19.843 1.00 66.86 H ATOM 2736 HD2 ARG A 189 21.777 9.943 -18.174 1.00 66.86 H ATOM 2737 HE ARG A 189 22.187 11.498 -20.615 1.00 66.26 H ATOM 2738 HH12 ARG A 189 21.130 13.631 -17.306 1.00 66.57 H ATOM 2739 HH11 ARG A 189 20.850 11.912 -17.318 1.00 66.57 H ATOM 2740 HH22 ARG A 189 22.091 14.662 -19.141 1.00 65.04 H ATOM 2741 HH21 ARG A 189 22.555 13.734 -20.539 1.00 65.04 H ATOM 2742 N ASN A 190 18.237 6.806 -16.833 1.00 66.58 N ATOM 2743 CA ASN A 190 18.134 5.599 -16.007 1.00 66.84 C ATOM 2744 C ASN A 190 16.696 5.336 -15.546 1.00 66.83 C ATOM 2745 O ASN A 190 16.134 6.142 -14.806 1.00 66.79 O ATOM 2746 CB ASN A 190 19.070 5.736 -14.780 1.00 67.44 C ATOM 2747 CG ASN A 190 20.569 5.739 -15.104 1.00 68.51 C ATOM 2748 OD1 ASN A 190 20.992 5.373 -16.199 1.00 68.94 O ATOM 2749 ND2 ASN A 190 21.388 6.142 -14.130 1.00 68.38 N ATOM 2750 H ASN A 190 18.941 7.465 -16.533 1.00 66.58 H ATOM 2751 HA ASN A 190 18.479 4.775 -16.636 1.00 66.84 H ATOM 2752 HB3 ASN A 190 18.901 4.901 -14.098 1.00 67.44 H ATOM 2753 HB2 ASN A 190 18.825 6.643 -14.224 1.00 67.44 H ATOM 2754 HD22 ASN A 190 22.385 6.160 -14.286 1.00 68.38 H ATOM 2755 HD21 ASN A 190 21.018 6.451 -13.243 1.00 68.38 H ATOM 2756 N LYS A 191 16.145 4.198 -15.991 1.00 66.99 N ATOM 2757 CA LYS A 191 14.784 3.760 -15.671 1.00 67.22 C ATOM 2758 C LYS A 191 14.638 3.258 -14.222 1.00 66.45 C ATOM 2759 O LYS A 191 13.533 3.302 -13.683 1.00 65.12 O ATOM 2760 CB LYS A 191 14.349 2.676 -16.675 1.00 68.00 C ATOM 2761 CG LYS A 191 14.388 3.157 -18.140 1.00 69.16 C ATOM 2762 CD LYS A 191 13.687 2.212 -19.128 1.00 69.10 C ATOM 2763 CE LYS A 191 12.152 2.257 -19.017 1.00 69.33 C ATOM 2764 NZ LYS A 191 11.504 1.395 -20.020 1.00 70.64 N1+ ATOM 2765 H LYS A 191 16.671 3.600 -16.611 1.00 66.99 H ATOM 2766 HA LYS A 191 14.117 4.617 -15.785 1.00 67.22 H ATOM 2767 HB3 LYS A 191 13.336 2.365 -16.419 1.00 68.00 H ATOM 2768 HB2 LYS A 191 14.973 1.788 -16.570 1.00 68.00 H ATOM 2769 HG3 LYS A 191 15.427 3.272 -18.450 1.00 69.16 H ATOM 2770 HG2 LYS A 191 13.946 4.152 -18.216 1.00 69.16 H ATOM 2771 HD3 LYS A 191 14.042 1.193 -18.961 1.00 69.10 H ATOM 2772 HD2 LYS A 191 13.995 2.476 -20.140 1.00 69.10 H ATOM 2773 HE3 LYS A 191 11.795 3.278 -19.160 1.00 69.33 H ATOM 2774 HE2 LYS A 191 11.820 1.937 -18.030 1.00 69.33 H ATOM 2775 HZ1 LYS A 191 11.795 0.438 -19.884 1.00 70.64 H ATOM 2776 HZ2 LYS A 191 10.500 1.457 -19.921 1.00 70.64 H ATOM 2777 HZ3 LYS A 191 11.768 1.698 -20.947 1.00 70.64 H ATOM 2778 N ARG A 192 15.758 2.817 -13.624 1.00 66.07 N ATOM 2779 CA ARG A 192 15.870 2.398 -12.226 1.00 65.07 C ATOM 2780 C ARG A 192 16.387 3.527 -11.313 1.00 63.80 C ATOM 2781 O ARG A 192 16.500 3.310 -10.106 1.00 64.94 O ATOM 2782 CB ARG A 192 16.781 1.154 -12.141 1.00 65.08 C ATOM 2783 CG ARG A 192 16.354 0.029 -13.106 1.00 65.38 C ATOM 2784 CD ARG A 192 17.045 -1.325 -12.868 1.00 64.94 C ATOM 2785 NE ARG A 192 16.612 -1.982 -11.621 1.00 63.91 N ATOM 2786 CZ ARG A 192 15.437 -2.598 -11.387 1.00 65.68 C ATOM 2787 NH1 ARG A 192 14.472 -2.687 -12.315 1.00 64.31 N ATOM 2788 NH2 ARG A 192 15.218 -3.147 -10.188 1.00 65.10 N1+ ATOM 2789 H ARG A 192 16.619 2.820 -14.150 1.00 66.07 H ATOM 2790 HA ARG A 192 14.884 2.117 -11.857 1.00 65.07 H ATOM 2791 HB3 ARG A 192 16.782 0.784 -11.115 1.00 65.08 H ATOM 2792 HB2 ARG A 192 17.813 1.432 -12.363 1.00 65.08 H ATOM 2793 HG3 ARG A 192 16.453 0.313 -14.153 1.00 65.38 H ATOM 2794 HG2 ARG A 192 15.282 -0.096 -12.947 1.00 65.38 H ATOM 2795 HD3 ARG A 192 18.107 -1.133 -12.717 1.00 64.94 H ATOM 2796 HD2 ARG A 192 16.986 -1.979 -13.739 1.00 64.94 H ATOM 2797 HE ARG A 192 17.285 -1.929 -10.868 1.00 63.91 H ATOM 2798 HH12 ARG A 192 13.592 -3.134 -12.099 1.00 64.31 H ATOM 2799 HH11 ARG A 192 14.604 -2.267 -13.223 1.00 64.31 H ATOM 2800 HH22 ARG A 192 14.344 -3.614 -9.984 1.00 65.10 H ATOM 2801 HH21 ARG A 192 15.898 -3.059 -9.446 1.00 65.10 H ATOM 2802 N GLY A 193 16.702 4.693 -11.905 1.00 61.68 N ATOM 2803 CA GLY A 193 17.254 5.858 -11.229 1.00 57.85 C ATOM 2804 C GLY A 193 16.195 6.959 -11.119 1.00 54.40 C ATOM 2805 O GLY A 193 15.203 6.988 -11.851 1.00 54.74 O ATOM 2806 H GLY A 193 16.527 4.797 -12.895 1.00 61.68 H ATOM 2807 HA3 GLY A 193 18.090 6.238 -11.817 1.00 57.85 H ATOM 2808 HA2 GLY A 193 17.645 5.607 -10.242 1.00 57.85 H ATOM 2809 N VAL A 194 16.460 7.887 -10.193 1.00 51.20 N ATOM 2810 CA VAL A 194 15.654 9.067 -9.903 1.00 47.88 C ATOM 2811 C VAL A 194 16.595 10.258 -9.641 1.00 45.73 C ATOM 2812 O VAL A 194 17.732 10.067 -9.208 1.00 44.54 O ATOM 2813 CB VAL A 194 14.747 8.844 -8.654 1.00 48.42 C ATOM 2814 CG1 VAL A 194 13.683 7.760 -8.910 1.00 48.70 C ATOM 2815 CG2 VAL A 194 15.511 8.570 -7.342 1.00 48.70 C ATOM 2816 H VAL A 194 17.309 7.814 -9.651 1.00 51.20 H ATOM 2817 HA VAL A 194 15.032 9.315 -10.764 1.00 47.88 H ATOM 2818 HB VAL A 194 14.191 9.765 -8.486 1.00 48.42 H ATOM 2819 HG11 VAL A 194 12.988 7.675 -8.078 1.00 48.70 H ATOM 2820 HG12 VAL A 194 13.096 7.988 -9.801 1.00 48.70 H ATOM 2821 HG13 VAL A 194 14.133 6.777 -9.049 1.00 48.70 H ATOM 2822 HG21 VAL A 194 14.826 8.324 -6.533 1.00 48.70 H ATOM 2823 HG22 VAL A 194 16.195 7.727 -7.446 1.00 48.70 H ATOM 2824 HG23 VAL A 194 16.091 9.432 -7.015 1.00 48.70 H ATOM 2825 N ILE A 195 16.084 11.468 -9.901 1.00 44.00 N ATOM 2826 CA ILE A 195 16.733 12.741 -9.594 1.00 42.15 C ATOM 2827 C ILE A 195 16.114 13.287 -8.303 1.00 39.98 C ATOM 2828 O ILE A 195 14.891 13.378 -8.232 1.00 40.39 O ATOM 2829 CB ILE A 195 16.504 13.768 -10.746 1.00 42.60 C ATOM 2830 CG1 ILE A 195 17.329 13.348 -11.983 1.00 44.09 C ATOM 2831 CG2 ILE A 195 16.803 15.243 -10.378 1.00 43.47 C ATOM 2832 CD1 ILE A 195 16.950 14.086 -13.272 1.00 45.10 C ATOM 2833 H ILE A 195 15.130 11.535 -10.231 1.00 44.00 H ATOM 2834 HA ILE A 195 17.807 12.603 -9.450 1.00 42.15 H ATOM 2835 HB ILE A 195 15.450 13.718 -11.028 1.00 42.60 H ATOM 2836 HG13 ILE A 195 17.219 12.279 -12.164 1.00 44.09 H ATOM 2837 HG12 ILE A 195 18.390 13.501 -11.781 1.00 44.09 H ATOM 2838 HG21 ILE A 195 16.663 15.907 -11.231 1.00 43.47 H ATOM 2839 HG22 ILE A 195 16.142 15.624 -9.599 1.00 43.47 H ATOM 2840 HG23 ILE A 195 17.831 15.362 -10.034 1.00 43.47 H ATOM 2841 HD11 ILE A 195 17.393 13.586 -14.133 1.00 45.10 H ATOM 2842 HD12 ILE A 195 15.869 14.112 -13.415 1.00 45.10 H ATOM 2843 HD13 ILE A 195 17.320 15.111 -13.274 1.00 45.10 H ATOM 2844 N ILE A 196 16.960 13.663 -7.333 1.00 39.35 N ATOM 2845 CA ILE A 196 16.533 14.278 -6.076 1.00 38.26 C ATOM 2846 C ILE A 196 17.091 15.711 -6.063 1.00 39.38 C ATOM 2847 O ILE A 196 18.280 15.916 -5.810 1.00 41.32 O ATOM 2848 CB ILE A 196 17.032 13.494 -4.827 1.00 37.13 C ATOM 2849 CG1 ILE A 196 16.555 12.020 -4.838 1.00 37.59 C ATOM 2850 CG2 ILE A 196 16.604 14.156 -3.495 1.00 36.34 C ATOM 2851 CD1 ILE A 196 17.502 11.069 -4.096 1.00 38.64 C ATOM 2852 H ILE A 196 17.957 13.568 -7.465 1.00 39.35 H ATOM 2853 HA ILE A 196 15.445 14.330 -6.013 1.00 38.26 H ATOM 2854 HB ILE A 196 18.123 13.484 -4.855 1.00 37.13 H ATOM 2855 HG13 ILE A 196 16.473 11.644 -5.856 1.00 37.59 H ATOM 2856 HG12 ILE A 196 15.547 11.943 -4.428 1.00 37.59 H ATOM 2857 HG21 ILE A 196 17.029 13.633 -2.639 1.00 36.34 H ATOM 2858 HG22 ILE A 196 16.914 15.197 -3.420 1.00 36.34 H ATOM 2859 HG23 ILE A 196 15.519 14.141 -3.383 1.00 36.34 H ATOM 2860 HD11 ILE A 196 16.967 10.192 -3.730 1.00 38.64 H ATOM 2861 HD12 ILE A 196 18.293 10.717 -4.759 1.00 38.64 H ATOM 2862 HD13 ILE A 196 17.981 11.552 -3.245 1.00 38.64 H ATOM 2863 N LYS A 197 16.206 16.669 -6.375 1.00 38.14 N ATOM 2864 CA LYS A 197 16.483 18.101 -6.405 1.00 37.79 C ATOM 2865 C LYS A 197 16.796 18.642 -5.000 1.00 36.85 C ATOM 2866 O LYS A 197 15.981 18.483 -4.091 1.00 35.36 O ATOM 2867 CB LYS A 197 15.276 18.827 -7.042 1.00 37.13 C ATOM 2868 CG LYS A 197 15.433 20.356 -7.147 1.00 39.41 C ATOM 2869 CD LYS A 197 14.198 21.047 -7.739 1.00 41.69 C ATOM 2870 CE LYS A 197 14.383 22.571 -7.820 1.00 44.71 C ATOM 2871 NZ LYS A 197 13.187 23.240 -8.360 1.00 46.18 N1+ ATOM 2872 H LYS A 197 15.243 16.408 -6.536 1.00 38.14 H ATOM 2873 HA LYS A 197 17.350 18.254 -7.051 1.00 37.79 H ATOM 2874 HB3 LYS A 197 14.377 18.605 -6.466 1.00 37.13 H ATOM 2875 HB2 LYS A 197 15.103 18.421 -8.040 1.00 37.13 H ATOM 2876 HG3 LYS A 197 16.309 20.586 -7.755 1.00 39.41 H ATOM 2877 HG2 LYS A 197 15.622 20.788 -6.164 1.00 39.41 H ATOM 2878 HD3 LYS A 197 13.326 20.807 -7.128 1.00 41.69 H ATOM 2879 HD2 LYS A 197 13.999 20.639 -8.732 1.00 41.69 H ATOM 2880 HE3 LYS A 197 15.236 22.815 -8.455 1.00 44.71 H ATOM 2881 HE2 LYS A 197 14.591 22.979 -6.831 1.00 44.71 H ATOM 2882 HZ1 LYS A 197 12.394 23.046 -7.765 1.00 46.18 H ATOM 2883 HZ2 LYS A 197 13.344 24.237 -8.397 1.00 46.18 H ATOM 2884 HZ3 LYS A 197 12.998 22.895 -9.291 1.00 46.18 H ATOM 2885 N GLY A 198 17.950 19.316 -4.887 1.00 38.11 N ATOM 2886 CA GLY A 198 18.369 20.028 -3.683 1.00 39.85 C ATOM 2887 C GLY A 198 19.177 19.157 -2.710 1.00 40.71 C ATOM 2888 O GLY A 198 19.602 19.689 -1.687 1.00 41.56 O ATOM 2889 H GLY A 198 18.561 19.387 -5.688 1.00 38.11 H ATOM 2890 HA3 GLY A 198 17.508 20.447 -3.159 1.00 39.85 H ATOM 2891 HA2 GLY A 198 18.990 20.872 -3.984 1.00 39.85 H ATOM 2892 N LEU A 199 19.406 17.860 -3.002 1.00 40.46 N ATOM 2893 CA LEU A 199 20.236 16.974 -2.181 1.00 40.03 C ATOM 2894 C LEU A 199 21.720 17.357 -2.291 1.00 41.70 C ATOM 2895 O LEU A 199 22.331 17.127 -3.336 1.00 41.24 O ATOM 2896 CB LEU A 199 19.980 15.500 -2.569 1.00 37.82 C ATOM 2897 CG LEU A 199 20.751 14.454 -1.727 1.00 36.34 C ATOM 2898 CD1 LEU A 199 20.402 14.545 -0.229 1.00 35.93 C ATOM 2899 CD2 LEU A 199 20.538 13.032 -2.280 1.00 35.17 C ATOM 2900 H LEU A 199 19.042 17.467 -3.858 1.00 40.46 H ATOM 2901 HA LEU A 199 19.922 17.100 -1.144 1.00 40.03 H ATOM 2902 HB3 LEU A 199 20.215 15.363 -3.626 1.00 37.82 H ATOM 2903 HB2 LEU A 199 18.917 15.298 -2.467 1.00 37.82 H ATOM 2904 HG LEU A 199 21.819 14.653 -1.826 1.00 36.34 H ATOM 2905 HD11 LEU A 199 20.575 13.602 0.290 1.00 35.93 H ATOM 2906 HD12 LEU A 199 21.018 15.297 0.260 1.00 35.93 H ATOM 2907 HD13 LEU A 199 19.361 14.826 -0.071 1.00 35.93 H ATOM 2908 HD21 LEU A 199 21.481 12.487 -2.325 1.00 35.17 H ATOM 2909 HD22 LEU A 199 19.850 12.452 -1.670 1.00 35.17 H ATOM 2910 HD23 LEU A 199 20.127 13.046 -3.290 1.00 35.17 H ATOM 2911 N GLU A 200 22.260 17.926 -1.202 1.00 42.28 N ATOM 2912 CA GLU A 200 23.662 18.300 -1.065 1.00 45.64 C ATOM 2913 C GLU A 200 24.586 17.084 -1.041 1.00 45.00 C ATOM 2914 O GLU A 200 24.344 16.134 -0.298 1.00 43.55 O ATOM 2915 CB GLU A 200 23.881 19.147 0.208 1.00 49.57 C ATOM 2916 CG GLU A 200 23.403 20.605 0.081 1.00 57.01 C ATOM 2917 CD GLU A 200 24.177 21.431 -0.956 1.00 60.33 C ATOM 2918 OE1 GLU A 200 25.428 21.389 -0.918 1.00 62.11 O ATOM 2919 OE2 GLU A 200 23.506 22.099 -1.773 1.00 62.56 O1- ATOM 2920 H GLU A 200 21.673 18.114 -0.396 1.00 42.28 H ATOM 2921 HA GLU A 200 23.922 18.895 -1.943 1.00 45.64 H ATOM 2922 HB3 GLU A 200 24.932 19.133 0.505 1.00 49.57 H ATOM 2923 HB2 GLU A 200 23.357 18.684 1.045 1.00 49.57 H ATOM 2924 HG3 GLU A 200 23.558 21.094 1.039 1.00 57.01 H ATOM 2925 HG2 GLU A 200 22.331 20.635 -0.120 1.00 57.01 H ATOM 2926 N GLU A 201 25.655 17.189 -1.835 1.00 45.79 N ATOM 2927 CA GLU A 201 26.770 16.261 -1.858 1.00 46.72 C ATOM 2928 C GLU A 201 27.987 17.028 -1.341 1.00 46.76 C ATOM 2929 O GLU A 201 28.514 17.885 -2.050 1.00 47.10 O ATOM 2930 CB GLU A 201 26.981 15.751 -3.293 1.00 48.30 C ATOM 2931 CG GLU A 201 25.827 14.857 -3.797 1.00 53.27 C ATOM 2932 CD GLU A 201 26.003 14.333 -5.231 1.00 56.17 C ATOM 2933 OE1 GLU A 201 25.324 13.334 -5.553 1.00 57.27 O ATOM 2934 OE2 GLU A 201 26.803 14.919 -5.994 1.00 58.06 O1- ATOM 2935 H GLU A 201 25.767 18.019 -2.401 1.00 45.79 H ATOM 2936 HA GLU A 201 26.586 15.402 -1.213 1.00 46.72 H ATOM 2937 HB3 GLU A 201 27.913 15.188 -3.337 1.00 48.30 H ATOM 2938 HB2 GLU A 201 27.107 16.605 -3.962 1.00 48.30 H ATOM 2939 HG3 GLU A 201 24.884 15.404 -3.759 1.00 53.27 H ATOM 2940 HG2 GLU A 201 25.715 14.006 -3.124 1.00 53.27 H ATOM 2941 N ILE A 202 28.387 16.724 -0.098 1.00 46.40 N ATOM 2942 CA ILE A 202 29.537 17.339 0.553 1.00 46.13 C ATOM 2943 C ILE A 202 30.800 16.547 0.202 1.00 45.18 C ATOM 2944 O ILE A 202 30.892 15.369 0.548 1.00 45.33 O ATOM 2945 CB ILE A 202 29.374 17.399 2.100 1.00 45.98 C ATOM 2946 CG1 ILE A 202 28.192 18.330 2.456 1.00 47.32 C ATOM 2947 CG2 ILE A 202 30.658 17.856 2.835 1.00 45.32 C ATOM 2948 CD1 ILE A 202 27.916 18.466 3.957 1.00 48.95 C ATOM 2949 H ILE A 202 27.912 15.995 0.419 1.00 46.40 H ATOM 2950 HA ILE A 202 29.652 18.364 0.192 1.00 46.13 H ATOM 2951 HB ILE A 202 29.126 16.398 2.460 1.00 45.98 H ATOM 2952 HG13 ILE A 202 27.279 17.981 1.970 1.00 47.32 H ATOM 2953 HG12 ILE A 202 28.382 19.324 2.049 1.00 47.32 H ATOM 2954 HG21 ILE A 202 30.512 17.895 3.913 1.00 45.32 H ATOM 2955 HG22 ILE A 202 31.500 17.184 2.676 1.00 45.32 H ATOM 2956 HG23 ILE A 202 30.965 18.850 2.509 1.00 45.32 H ATOM 2957 HD11 ILE A 202 26.907 18.840 4.115 1.00 48.95 H ATOM 2958 HD12 ILE A 202 28.011 17.511 4.474 1.00 48.95 H ATOM 2959 HD13 ILE A 202 28.597 19.176 4.426 1.00 48.95 H ATOM 2960 N THR A 203 31.755 17.231 -0.447 1.00 44.53 N ATOM 2961 CA THR A 203 33.084 16.702 -0.726 1.00 44.04 C ATOM 2962 C THR A 203 33.895 16.557 0.574 1.00 43.54 C ATOM 2963 O THR A 203 34.031 17.525 1.323 1.00 43.23 O ATOM 2964 CB THR A 203 33.879 17.615 -1.695 1.00 44.86 C ATOM 2965 OG1 THR A 203 33.165 17.718 -2.911 1.00 43.73 O ATOM 2966 CG2 THR A 203 35.301 17.121 -2.028 1.00 44.45 C ATOM 2967 H THR A 203 31.594 18.191 -0.714 1.00 44.53 H ATOM 2968 HA THR A 203 32.958 15.728 -1.197 1.00 44.04 H ATOM 2969 HB THR A 203 33.948 18.621 -1.278 1.00 44.86 H ATOM 2970 HG1 THR A 203 33.191 16.868 -3.355 1.00 43.73 H ATOM 2971 HG21 THR A 203 35.766 17.749 -2.788 1.00 44.45 H ATOM 2972 HG22 THR A 203 35.957 17.141 -1.157 1.00 44.45 H ATOM 2973 HG23 THR A 203 35.287 16.098 -2.407 1.00 44.45 H ATOM 2974 N VAL A 204 34.418 15.345 0.788 1.00 44.30 N ATOM 2975 CA VAL A 204 35.281 14.998 1.904 1.00 45.77 C ATOM 2976 C VAL A 204 36.712 14.913 1.337 1.00 46.96 C ATOM 2977 O VAL A 204 36.987 14.072 0.480 1.00 47.51 O ATOM 2978 CB VAL A 204 34.901 13.628 2.533 1.00 44.79 C ATOM 2979 CG1 VAL A 204 35.601 13.429 3.888 1.00 45.00 C ATOM 2980 CG2 VAL A 204 33.382 13.431 2.688 1.00 44.50 C ATOM 2981 H VAL A 204 34.268 14.612 0.105 1.00 44.30 H ATOM 2982 HA VAL A 204 35.229 15.762 2.681 1.00 45.77 H ATOM 2983 HB VAL A 204 35.224 12.820 1.880 1.00 44.79 H ATOM 2984 HG11 VAL A 204 35.324 12.471 4.321 1.00 45.00 H ATOM 2985 HG12 VAL A 204 36.685 13.444 3.790 1.00 45.00 H ATOM 2986 HG13 VAL A 204 35.324 14.207 4.601 1.00 45.00 H ATOM 2987 HG21 VAL A 204 33.152 12.516 3.236 1.00 44.50 H ATOM 2988 HG22 VAL A 204 32.926 14.261 3.218 1.00 44.50 H ATOM 2989 HG23 VAL A 204 32.889 13.352 1.719 1.00 44.50 H ATOM 2990 N HIS A 205 37.575 15.836 1.781 1.00 48.27 N ATOM 2991 CA HIS A 205 38.931 16.026 1.262 1.00 50.42 C ATOM 2992 C HIS A 205 39.951 15.083 1.921 1.00 50.78 C ATOM 2993 O HIS A 205 40.913 14.695 1.260 1.00 50.81 O ATOM 2994 CB HIS A 205 39.346 17.499 1.461 1.00 50.66 C ATOM 2995 CG HIS A 205 38.441 18.496 0.772 1.00 50.85 C ATOM 2996 ND1 HIS A 205 37.443 19.173 1.453 1.00 51.12 N1+ ATOM 2997 CD2 HIS A 205 38.419 18.960 -0.530 1.00 50.79 C ATOM 2998 CE1 HIS A 205 36.831 19.966 0.580 1.00 50.20 C ATOM 2999 NE2 HIS A 205 37.383 19.876 -0.628 1.00 50.46 N ATOM 3000 H HIS A 205 37.269 16.496 2.488 1.00 48.27 H ATOM 3001 HA HIS A 205 38.931 15.817 0.190 1.00 50.42 H ATOM 3002 HB3 HIS A 205 40.355 17.653 1.078 1.00 50.66 H ATOM 3003 HB2 HIS A 205 39.386 17.740 2.524 1.00 50.66 H ATOM 3004 HD1 HIS A 205 37.198 19.056 2.434 1.00 51.12 H ATOM 3005 HD2 HIS A 205 39.029 18.715 -1.387 1.00 50.79 H ATOM 3006 HE1 HIS A 205 35.993 20.603 0.824 1.00 50.20 H ATOM 3007 HE2 HIS A 205 37.102 20.383 -1.456 1.00 50.46 H ATOM 3008 N ASN A 206 39.723 14.732 3.196 1.00 51.18 N ATOM 3009 CA ASN A 206 40.587 13.867 4.002 1.00 51.18 C ATOM 3010 C ASN A 206 39.800 13.298 5.192 1.00 51.21 C ATOM 3011 O ASN A 206 38.724 13.802 5.521 1.00 51.46 O ATOM 3012 CB ASN A 206 41.888 14.608 4.425 1.00 50.68 C ATOM 3013 CG ASN A 206 41.676 15.927 5.184 1.00 52.37 C ATOM 3014 OD1 ASN A 206 41.149 15.935 6.292 1.00 53.55 O ATOM 3015 ND2 ASN A 206 42.102 17.048 4.600 1.00 52.82 N ATOM 3016 H ASN A 206 38.896 15.074 3.667 1.00 51.18 H ATOM 3017 HA ASN A 206 40.870 13.027 3.366 1.00 51.18 H ATOM 3018 HB3 ASN A 206 42.489 14.809 3.538 1.00 50.68 H ATOM 3019 HB2 ASN A 206 42.503 13.956 5.047 1.00 50.68 H ATOM 3020 HD22 ASN A 206 41.990 17.933 5.072 1.00 52.82 H ATOM 3021 HD21 ASN A 206 42.546 17.020 3.693 1.00 52.82 H ATOM 3022 N LYS A 207 40.377 12.268 5.835 1.00 52.18 N ATOM 3023 CA LYS A 207 39.844 11.647 7.051 1.00 53.37 C ATOM 3024 C LYS A 207 39.692 12.620 8.237 1.00 53.82 C ATOM 3025 O LYS A 207 38.712 12.501 8.964 1.00 53.82 O ATOM 3026 CB LYS A 207 40.661 10.397 7.432 1.00 55.31 C ATOM 3027 CG LYS A 207 42.174 10.642 7.607 1.00 56.90 C ATOM 3028 CD LYS A 207 42.791 9.989 8.851 1.00 58.37 C ATOM 3029 CE LYS A 207 42.207 10.523 10.171 1.00 58.94 C ATOM 3030 NZ LYS A 207 43.150 10.352 11.287 1.00 60.33 N1+ ATOM 3031 H LYS A 207 41.258 11.904 5.502 1.00 52.18 H ATOM 3032 HA LYS A 207 38.849 11.290 6.798 1.00 53.37 H ATOM 3033 HB3 LYS A 207 40.517 9.625 6.679 1.00 55.31 H ATOM 3034 HB2 LYS A 207 40.234 9.970 8.340 1.00 55.31 H ATOM 3035 HG3 LYS A 207 42.401 11.707 7.630 1.00 56.90 H ATOM 3036 HG2 LYS A 207 42.690 10.265 6.723 1.00 56.90 H ATOM 3037 HD3 LYS A 207 43.870 10.153 8.813 1.00 58.37 H ATOM 3038 HD2 LYS A 207 42.651 8.907 8.799 1.00 58.37 H ATOM 3039 HE3 LYS A 207 41.268 10.025 10.414 1.00 58.94 H ATOM 3040 HE2 LYS A 207 41.982 11.584 10.088 1.00 58.94 H ATOM 3041 HZ1 LYS A 207 43.986 10.889 11.103 1.00 60.33 H ATOM 3042 HZ2 LYS A 207 42.716 10.697 12.135 1.00 60.33 H ATOM 3043 HZ3 LYS A 207 43.382 9.375 11.397 1.00 60.33 H ATOM 3044 N ASP A 208 40.598 13.605 8.367 1.00 53.64 N ATOM 3045 CA ASP A 208 40.578 14.669 9.385 1.00 54.33 C ATOM 3046 C ASP A 208 39.460 15.724 9.194 1.00 53.71 C ATOM 3047 O ASP A 208 39.445 16.713 9.926 1.00 54.95 O ATOM 3048 CB ASP A 208 41.962 15.346 9.585 1.00 56.35 C ATOM 3049 CG ASP A 208 43.135 14.361 9.717 1.00 58.62 C ATOM 3050 OD1 ASP A 208 43.298 13.818 10.832 1.00 59.21 O ATOM 3051 OD2 ASP A 208 43.750 14.043 8.674 1.00 60.63 O1- ATOM 3052 H ASP A 208 41.367 13.656 7.713 1.00 53.64 H ATOM 3053 HA ASP A 208 40.341 14.177 10.331 1.00 54.33 H ATOM 3054 HB3 ASP A 208 41.945 15.959 10.488 1.00 56.35 H ATOM 3055 HB2 ASP A 208 42.172 16.024 8.757 1.00 56.35 H ATOM 3056 N GLU A 209 38.540 15.490 8.244 1.00 52.25 N ATOM 3057 CA GLU A 209 37.350 16.296 7.978 1.00 50.66 C ATOM 3058 C GLU A 209 36.059 15.451 8.073 1.00 48.60 C ATOM 3059 O GLU A 209 34.976 16.033 8.133 1.00 47.52 O ATOM 3060 CB GLU A 209 37.525 16.928 6.584 1.00 52.62 C ATOM 3061 CG GLU A 209 36.485 18.011 6.222 1.00 55.80 C ATOM 3062 CD GLU A 209 36.679 18.541 4.802 1.00 58.39 C ATOM 3063 OE1 GLU A 209 36.692 17.701 3.880 1.00 60.18 O ATOM 3064 OE2 GLU A 209 36.806 19.774 4.639 1.00 60.45 O1- ATOM 3065 H GLU A 209 38.660 14.682 7.649 1.00 52.25 H ATOM 3066 HA GLU A 209 37.265 17.096 8.715 1.00 50.66 H ATOM 3067 HB3 GLU A 209 37.498 16.128 5.842 1.00 52.62 H ATOM 3068 HB2 GLU A 209 38.523 17.363 6.509 1.00 52.62 H ATOM 3069 HG3 GLU A 209 36.537 18.827 6.945 1.00 55.80 H ATOM 3070 HG2 GLU A 209 35.470 17.620 6.273 1.00 55.80 H ATOM 3071 N VAL A 210 36.179 14.107 8.111 1.00 46.40 N ATOM 3072 CA VAL A 210 35.064 13.157 8.216 1.00 44.14 C ATOM 3073 C VAL A 210 34.184 13.402 9.451 1.00 43.51 C ATOM 3074 O VAL A 210 32.966 13.475 9.303 1.00 42.39 O ATOM 3075 CB VAL A 210 35.563 11.677 8.236 1.00 44.48 C ATOM 3076 CG1 VAL A 210 34.548 10.607 8.703 1.00 42.85 C ATOM 3077 CG2 VAL A 210 36.103 11.282 6.855 1.00 42.99 C ATOM 3078 H VAL A 210 37.100 13.694 8.085 1.00 46.40 H ATOM 3079 HA VAL A 210 34.438 13.300 7.333 1.00 44.14 H ATOM 3080 HB VAL A 210 36.393 11.620 8.937 1.00 44.48 H ATOM 3081 HG11 VAL A 210 34.965 9.606 8.597 1.00 42.85 H ATOM 3082 HG12 VAL A 210 34.286 10.715 9.756 1.00 42.85 H ATOM 3083 HG13 VAL A 210 33.629 10.648 8.118 1.00 42.85 H ATOM 3084 HG21 VAL A 210 36.648 10.339 6.899 1.00 42.99 H ATOM 3085 HG22 VAL A 210 35.287 11.165 6.144 1.00 42.99 H ATOM 3086 HG23 VAL A 210 36.777 12.038 6.453 1.00 42.99 H ATOM 3087 N TYR A 211 34.816 13.545 10.629 1.00 42.45 N ATOM 3088 CA TYR A 211 34.116 13.676 11.904 1.00 41.99 C ATOM 3089 C TYR A 211 33.244 14.937 12.017 1.00 43.14 C ATOM 3090 O TYR A 211 32.134 14.827 12.533 1.00 42.53 O ATOM 3091 CB TYR A 211 35.115 13.564 13.065 1.00 40.52 C ATOM 3092 CG TYR A 211 34.451 13.378 14.414 1.00 39.40 C ATOM 3093 CD1 TYR A 211 33.783 12.168 14.683 1.00 39.03 C ATOM 3094 CD2 TYR A 211 34.452 14.409 15.376 1.00 39.70 C ATOM 3095 CE1 TYR A 211 33.083 12.003 15.887 1.00 37.82 C ATOM 3096 CE2 TYR A 211 33.743 14.243 16.582 1.00 39.48 C ATOM 3097 CZ TYR A 211 33.032 13.052 16.824 1.00 38.29 C ATOM 3098 OH TYR A 211 32.279 12.914 17.953 1.00 39.27 O ATOM 3099 H TYR A 211 35.824 13.494 10.668 1.00 42.45 H ATOM 3100 HA TYR A 211 33.441 12.820 11.965 1.00 41.99 H ATOM 3101 HB3 TYR A 211 35.794 14.418 13.086 1.00 40.52 H ATOM 3102 HB2 TYR A 211 35.730 12.685 12.894 1.00 40.52 H ATOM 3103 HD1 TYR A 211 33.791 11.368 13.957 1.00 39.03 H ATOM 3104 HD2 TYR A 211 34.960 15.341 15.179 1.00 39.70 H ATOM 3105 HE1 TYR A 211 32.574 11.072 16.069 1.00 37.82 H ATOM 3106 HE2 TYR A 211 33.720 15.047 17.304 1.00 39.48 H ATOM 3107 HH TYR A 211 32.066 13.751 18.382 1.00 39.27 H ATOM 3108 N GLN A 212 33.723 16.076 11.484 1.00 43.75 N ATOM 3109 CA GLN A 212 32.967 17.331 11.390 1.00 43.56 C ATOM 3110 C GLN A 212 31.652 17.219 10.604 1.00 41.95 C ATOM 3111 O GLN A 212 30.649 17.793 11.026 1.00 41.64 O ATOM 3112 CB GLN A 212 33.842 18.445 10.781 1.00 46.00 C ATOM 3113 CG GLN A 212 34.710 19.183 11.809 1.00 48.97 C ATOM 3114 CD GLN A 212 35.341 20.426 11.181 1.00 50.63 C ATOM 3115 OE1 GLN A 212 36.243 20.316 10.355 1.00 50.62 O ATOM 3116 NE2 GLN A 212 34.862 21.612 11.560 1.00 51.22 N ATOM 3117 H GLN A 212 34.640 16.078 11.061 1.00 43.75 H ATOM 3118 HA GLN A 212 32.696 17.617 12.407 1.00 43.56 H ATOM 3119 HB3 GLN A 212 33.199 19.188 10.303 1.00 46.00 H ATOM 3120 HB2 GLN A 212 34.464 18.044 9.979 1.00 46.00 H ATOM 3121 HG3 GLN A 212 35.495 18.526 12.185 1.00 48.97 H ATOM 3122 HG2 GLN A 212 34.109 19.478 12.671 1.00 48.97 H ATOM 3123 HE22 GLN A 212 35.249 22.458 11.168 1.00 51.22 H ATOM 3124 HE21 GLN A 212 34.119 21.673 12.241 1.00 51.22 H ATOM 3125 N ILE A 213 31.687 16.476 9.487 1.00 40.96 N ATOM 3126 CA ILE A 213 30.529 16.230 8.629 1.00 40.40 C ATOM 3127 C ILE A 213 29.480 15.340 9.326 1.00 38.82 C ATOM 3128 O ILE A 213 28.289 15.636 9.231 1.00 38.70 O ATOM 3129 CB ILE A 213 30.957 15.608 7.268 1.00 41.38 C ATOM 3130 CG1 ILE A 213 31.837 16.609 6.480 1.00 41.39 C ATOM 3131 CG2 ILE A 213 29.782 15.120 6.391 1.00 41.81 C ATOM 3132 CD1 ILE A 213 32.608 15.980 5.316 1.00 43.68 C ATOM 3133 H ILE A 213 32.552 16.034 9.207 1.00 40.96 H ATOM 3134 HA ILE A 213 30.056 17.193 8.425 1.00 40.40 H ATOM 3135 HB ILE A 213 31.577 14.737 7.480 1.00 41.38 H ATOM 3136 HG13 ILE A 213 32.570 17.079 7.135 1.00 41.39 H ATOM 3137 HG12 ILE A 213 31.216 17.426 6.109 1.00 41.39 H ATOM 3138 HG21 ILE A 213 30.126 14.797 5.412 1.00 41.81 H ATOM 3139 HG22 ILE A 213 29.266 14.267 6.831 1.00 41.81 H ATOM 3140 HG23 ILE A 213 29.053 15.914 6.230 1.00 41.81 H ATOM 3141 HD11 ILE A 213 33.407 16.639 4.973 1.00 43.68 H ATOM 3142 HD12 ILE A 213 33.065 15.033 5.605 1.00 43.68 H ATOM 3143 HD13 ILE A 213 31.949 15.797 4.470 1.00 43.68 H ATOM 3144 N LEU A 214 29.945 14.313 10.058 1.00 37.14 N ATOM 3145 CA LEU A 214 29.104 13.416 10.852 1.00 36.39 C ATOM 3146 C LEU A 214 28.479 14.105 12.081 1.00 36.96 C ATOM 3147 O LEU A 214 27.314 13.834 12.371 1.00 36.52 O ATOM 3148 CB LEU A 214 29.912 12.164 11.257 1.00 34.22 C ATOM 3149 CG LEU A 214 30.410 11.292 10.082 1.00 34.05 C ATOM 3150 CD1 LEU A 214 31.178 10.063 10.600 1.00 33.97 C ATOM 3151 CD2 LEU A 214 29.303 10.894 9.091 1.00 31.89 C ATOM 3152 H LEU A 214 30.941 14.140 10.094 1.00 37.14 H ATOM 3153 HA LEU A 214 28.269 13.107 10.222 1.00 36.39 H ATOM 3154 HB3 LEU A 214 29.294 11.542 11.899 1.00 34.22 H ATOM 3155 HB2 LEU A 214 30.763 12.466 11.870 1.00 34.22 H ATOM 3156 HG LEU A 214 31.126 11.880 9.516 1.00 34.05 H ATOM 3157 HD11 LEU A 214 31.949 9.759 9.893 1.00 33.97 H ATOM 3158 HD12 LEU A 214 31.673 10.271 11.547 1.00 33.97 H ATOM 3159 HD13 LEU A 214 30.517 9.209 10.755 1.00 33.97 H ATOM 3160 HD21 LEU A 214 29.456 9.893 8.693 1.00 31.89 H ATOM 3161 HD22 LEU A 214 28.316 10.916 9.549 1.00 31.89 H ATOM 3162 HD23 LEU A 214 29.286 11.573 8.238 1.00 31.89 H ATOM 3163 N GLU A 215 29.221 15.016 12.741 1.00 36.83 N ATOM 3164 CA GLU A 215 28.717 15.886 13.811 1.00 37.19 C ATOM 3165 C GLU A 215 27.581 16.810 13.352 1.00 35.62 C ATOM 3166 O GLU A 215 26.598 16.939 14.080 1.00 34.59 O ATOM 3167 CB GLU A 215 29.846 16.745 14.410 1.00 38.50 C ATOM 3168 CG GLU A 215 30.763 16.002 15.394 1.00 40.59 C ATOM 3169 CD GLU A 215 31.796 16.959 16.002 1.00 43.18 C ATOM 3170 OE1 GLU A 215 32.668 17.433 15.241 1.00 43.05 O ATOM 3171 OE2 GLU A 215 31.698 17.203 17.225 1.00 42.79 O1- ATOM 3172 H GLU A 215 30.184 15.164 12.467 1.00 36.83 H ATOM 3173 HA GLU A 215 28.313 15.245 14.597 1.00 37.19 H ATOM 3174 HB3 GLU A 215 29.426 17.616 14.918 1.00 38.50 H ATOM 3175 HB2 GLU A 215 30.451 17.147 13.597 1.00 38.50 H ATOM 3176 HG3 GLU A 215 31.280 15.179 14.902 1.00 40.59 H ATOM 3177 HG2 GLU A 215 30.163 15.548 16.184 1.00 40.59 H ATOM 3178 N LYS A 216 27.722 17.402 12.152 1.00 34.60 N ATOM 3179 CA LYS A 216 26.673 18.182 11.491 1.00 35.20 C ATOM 3180 C LYS A 216 25.416 17.356 11.182 1.00 33.65 C ATOM 3181 O LYS A 216 24.317 17.870 11.373 1.00 33.67 O ATOM 3182 CB LYS A 216 27.231 18.877 10.226 1.00 37.19 C ATOM 3183 CG LYS A 216 27.593 20.356 10.444 1.00 41.61 C ATOM 3184 CD LYS A 216 26.351 21.265 10.575 1.00 45.71 C ATOM 3185 CE LYS A 216 26.675 22.749 10.822 1.00 48.01 C ATOM 3186 NZ LYS A 216 27.247 22.987 12.161 1.00 49.53 N1+ ATOM 3187 H LYS A 216 28.573 17.260 11.625 1.00 34.60 H ATOM 3188 HA LYS A 216 26.375 18.944 12.212 1.00 35.20 H ATOM 3189 HB3 LYS A 216 26.504 18.839 9.412 1.00 37.19 H ATOM 3190 HB2 LYS A 216 28.097 18.331 9.849 1.00 37.19 H ATOM 3191 HG3 LYS A 216 28.196 20.697 9.602 1.00 41.61 H ATOM 3192 HG2 LYS A 216 28.229 20.439 11.325 1.00 41.61 H ATOM 3193 HD3 LYS A 216 25.684 20.900 11.358 1.00 45.71 H ATOM 3194 HD2 LYS A 216 25.772 21.194 9.652 1.00 45.71 H ATOM 3195 HE3 LYS A 216 25.762 23.341 10.737 1.00 48.01 H ATOM 3196 HE2 LYS A 216 27.363 23.120 10.062 1.00 48.01 H ATOM 3197 HZ1 LYS A 216 28.109 22.470 12.256 1.00 49.53 H ATOM 3198 HZ2 LYS A 216 27.434 23.973 12.278 1.00 49.53 H ATOM 3199 HZ3 LYS A 216 26.594 22.683 12.868 1.00 49.53 H ATOM 3200 N GLY A 217 25.605 16.088 10.778 1.00 33.75 N ATOM 3201 CA GLY A 217 24.547 15.106 10.549 1.00 32.24 C ATOM 3202 C GLY A 217 23.714 14.869 11.815 1.00 30.95 C ATOM 3203 O GLY A 217 22.497 15.046 11.788 1.00 30.94 O ATOM 3204 H GLY A 217 26.553 15.763 10.645 1.00 33.75 H ATOM 3205 HA3 GLY A 217 25.004 14.166 10.240 1.00 32.24 H ATOM 3206 HA2 GLY A 217 23.908 15.430 9.735 1.00 32.24 H ATOM 3207 N ALA A 218 24.390 14.516 12.921 1.00 31.76 N ATOM 3208 CA ALA A 218 23.798 14.267 14.237 1.00 30.06 C ATOM 3209 C ALA A 218 23.133 15.502 14.875 1.00 30.68 C ATOM 3210 O ALA A 218 22.100 15.352 15.529 1.00 28.25 O ATOM 3211 CB ALA A 218 24.881 13.694 15.163 1.00 30.77 C ATOM 3212 H ALA A 218 25.394 14.401 12.862 1.00 31.76 H ATOM 3213 HA ALA A 218 23.026 13.507 14.110 1.00 30.06 H ATOM 3214 HB1 ALA A 218 24.487 13.496 16.160 1.00 30.77 H ATOM 3215 HB2 ALA A 218 25.266 12.752 14.774 1.00 30.77 H ATOM 3216 HB3 ALA A 218 25.725 14.378 15.267 1.00 30.77 H ATOM 3217 N ALA A 219 23.713 16.694 14.654 1.00 30.08 N ATOM 3218 CA ALA A 219 23.179 17.977 15.111 1.00 31.41 C ATOM 3219 C ALA A 219 21.873 18.360 14.401 1.00 31.60 C ATOM 3220 O ALA A 219 20.940 18.801 15.070 1.00 31.54 O ATOM 3221 CB ALA A 219 24.238 19.073 14.927 1.00 34.27 C ATOM 3222 H ALA A 219 24.578 16.734 14.129 1.00 30.08 H ATOM 3223 HA ALA A 219 22.967 17.890 16.178 1.00 31.41 H ATOM 3224 HB1 ALA A 219 23.867 20.042 15.264 1.00 34.27 H ATOM 3225 HB2 ALA A 219 25.135 18.850 15.505 1.00 34.27 H ATOM 3226 HB3 ALA A 219 24.533 19.176 13.883 1.00 34.27 H ATOM 3227 N LYS A 220 21.809 18.143 13.075 1.00 32.32 N ATOM 3228 CA LYS A 220 20.595 18.345 12.285 1.00 32.64 C ATOM 3229 C LYS A 220 19.482 17.338 12.624 1.00 30.46 C ATOM 3230 O LYS A 220 18.320 17.736 12.611 1.00 31.31 O ATOM 3231 CB LYS A 220 20.920 18.360 10.780 1.00 35.19 C ATOM 3232 CG LYS A 220 21.672 19.626 10.319 1.00 41.44 C ATOM 3233 CD LYS A 220 21.510 19.893 8.816 1.00 45.82 C ATOM 3234 CE LYS A 220 20.213 20.659 8.510 1.00 46.78 C ATOM 3235 NZ LYS A 220 19.777 20.499 7.115 1.00 49.70 N1+ ATOM 3236 H LYS A 220 22.615 17.785 12.580 1.00 32.32 H ATOM 3237 HA LYS A 220 20.203 19.330 12.545 1.00 32.64 H ATOM 3238 HB3 LYS A 220 19.977 18.318 10.235 1.00 35.19 H ATOM 3239 HB2 LYS A 220 21.471 17.464 10.492 1.00 35.19 H ATOM 3240 HG3 LYS A 220 22.730 19.537 10.549 1.00 41.44 H ATOM 3241 HG2 LYS A 220 21.329 20.497 10.878 1.00 41.44 H ATOM 3242 HD3 LYS A 220 21.528 18.946 8.280 1.00 45.82 H ATOM 3243 HD2 LYS A 220 22.371 20.456 8.456 1.00 45.82 H ATOM 3244 HE3 LYS A 220 20.345 21.720 8.724 1.00 46.78 H ATOM 3245 HE2 LYS A 220 19.409 20.315 9.148 1.00 46.78 H ATOM 3246 HZ1 LYS A 220 20.506 20.849 6.506 1.00 49.70 H ATOM 3247 HZ2 LYS A 220 19.595 19.527 6.900 1.00 49.70 H ATOM 3248 HZ3 LYS A 220 18.939 21.039 6.955 1.00 49.70 H ATOM 3249 N ARG A 221 19.833 16.090 12.988 1.00 29.75 N ATOM 3250 CA ARG A 221 18.874 15.095 13.486 1.00 28.19 C ATOM 3251 C ARG A 221 18.180 15.489 14.797 1.00 27.11 C ATOM 3252 O ARG A 221 17.042 15.071 14.998 1.00 26.10 O ATOM 3253 CB ARG A 221 19.540 13.730 13.697 1.00 30.31 C ATOM 3254 CG ARG A 221 19.927 13.005 12.406 1.00 30.67 C ATOM 3255 CD ARG A 221 19.353 11.585 12.409 1.00 34.41 C ATOM 3256 NE ARG A 221 19.885 10.797 11.306 1.00 31.18 N ATOM 3257 CZ ARG A 221 21.010 10.074 11.293 1.00 30.15 C ATOM 3258 NH1 ARG A 221 21.803 9.984 12.368 1.00 26.01 N ATOM 3259 NH2 ARG A 221 21.325 9.427 10.169 1.00 29.12 N1+ ATOM 3260 H ARG A 221 20.805 15.811 12.963 1.00 29.75 H ATOM 3261 HA ARG A 221 18.085 14.982 12.742 1.00 28.19 H ATOM 3262 HB3 ARG A 221 18.846 13.096 14.253 1.00 30.31 H ATOM 3263 HB2 ARG A 221 20.414 13.819 14.341 1.00 30.31 H ATOM 3264 HG3 ARG A 221 21.000 13.015 12.220 1.00 30.67 H ATOM 3265 HG2 ARG A 221 19.474 13.541 11.571 1.00 30.67 H ATOM 3266 HD3 ARG A 221 18.287 11.652 12.185 1.00 34.41 H ATOM 3267 HD2 ARG A 221 19.428 11.083 13.374 1.00 34.41 H ATOM 3268 HE ARG A 221 19.373 10.871 10.431 1.00 31.18 H ATOM 3269 HH12 ARG A 221 22.601 9.356 12.361 1.00 26.01 H ATOM 3270 HH11 ARG A 221 21.562 10.468 13.219 1.00 26.01 H ATOM 3271 HH22 ARG A 221 22.124 8.802 10.158 1.00 29.12 H ATOM 3272 HH21 ARG A 221 20.746 9.532 9.345 1.00 29.12 H ATOM 3273 N THR A 222 18.853 16.278 15.650 1.00 25.90 N ATOM 3274 CA THR A 222 18.279 16.788 16.895 1.00 26.98 C ATOM 3275 C THR A 222 17.165 17.823 16.633 1.00 24.38 C ATOM 3276 O THR A 222 16.139 17.783 17.313 1.00 25.97 O ATOM 3277 CB THR A 222 19.360 17.426 17.804 1.00 27.34 C ATOM 3278 OG1 THR A 222 20.358 16.460 18.081 1.00 28.70 O ATOM 3279 CG2 THR A 222 18.845 17.969 19.149 1.00 29.13 C ATOM 3280 H THR A 222 19.787 16.585 15.420 1.00 25.90 H ATOM 3281 HA THR A 222 17.835 15.947 17.433 1.00 26.98 H ATOM 3282 HB THR A 222 19.845 18.247 17.278 1.00 27.34 H ATOM 3283 HG1 THR A 222 20.778 16.198 17.257 1.00 28.70 H ATOM 3284 HG21 THR A 222 19.672 18.309 19.774 1.00 29.13 H ATOM 3285 HG22 THR A 222 18.177 18.821 19.018 1.00 29.13 H ATOM 3286 HG23 THR A 222 18.304 17.202 19.703 1.00 29.13 H ATOM 3287 N THR A 223 17.357 18.681 15.615 1.00 26.05 N ATOM 3288 CA THR A 223 16.345 19.631 15.145 1.00 28.52 C ATOM 3289 C THR A 223 15.186 18.937 14.394 1.00 27.17 C ATOM 3290 O THR A 223 14.052 19.396 14.510 1.00 27.18 O ATOM 3291 CB THR A 223 16.954 20.753 14.254 1.00 30.32 C ATOM 3292 OG1 THR A 223 17.185 20.375 12.911 1.00 39.33 O ATOM 3293 CG2 THR A 223 18.227 21.389 14.832 1.00 30.64 C ATOM 3294 H THR A 223 18.222 18.652 15.094 1.00 26.05 H ATOM 3295 HA THR A 223 15.915 20.115 16.024 1.00 28.52 H ATOM 3296 HB THR A 223 16.208 21.548 14.198 1.00 30.32 H ATOM 3297 HG1 THR A 223 17.773 19.613 12.896 1.00 39.33 H ATOM 3298 HG21 THR A 223 18.547 22.240 14.229 1.00 30.64 H ATOM 3299 HG22 THR A 223 18.057 21.750 15.847 1.00 30.64 H ATOM 3300 HG23 THR A 223 19.055 20.682 14.863 1.00 30.64 H ATOM 3301 N ALA A 224 15.468 17.821 13.696 1.00 25.91 N ATOM 3302 CA ALA A 224 14.459 16.977 13.053 1.00 24.46 C ATOM 3303 C ALA A 224 13.585 16.233 14.076 1.00 23.90 C ATOM 3304 O ALA A 224 12.376 16.155 13.878 1.00 20.38 O ATOM 3305 CB ALA A 224 15.144 15.998 12.089 1.00 24.41 C ATOM 3306 H ALA A 224 16.426 17.505 13.626 1.00 25.91 H ATOM 3307 HA ALA A 224 13.802 17.620 12.466 1.00 24.46 H ATOM 3308 HB1 ALA A 224 14.407 15.437 11.516 1.00 24.41 H ATOM 3309 HB2 ALA A 224 15.777 16.522 11.374 1.00 24.41 H ATOM 3310 HB3 ALA A 224 15.764 15.276 12.618 1.00 24.41 H ATOM 3311 N ALA A 225 14.198 15.758 15.174 1.00 24.13 N ATOM 3312 CA ALA A 225 13.517 15.140 16.311 1.00 25.95 C ATOM 3313 C ALA A 225 12.609 16.104 17.090 1.00 25.57 C ATOM 3314 O ALA A 225 11.577 15.664 17.597 1.00 26.74 O ATOM 3315 CB ALA A 225 14.558 14.488 17.233 1.00 23.02 C ATOM 3316 H ALA A 225 15.204 15.839 15.252 1.00 24.13 H ATOM 3317 HA ALA A 225 12.867 14.358 15.926 1.00 25.95 H ATOM 3318 HB1 ALA A 225 14.085 14.009 18.091 1.00 23.02 H ATOM 3319 HB2 ALA A 225 15.121 13.720 16.701 1.00 23.02 H ATOM 3320 HB3 ALA A 225 15.273 15.218 17.614 1.00 23.02 H ATOM 3321 N THR A 226 12.980 17.394 17.136 1.00 25.99 N ATOM 3322 CA THR A 226 12.169 18.458 17.729 1.00 26.54 C ATOM 3323 C THR A 226 10.896 18.746 16.904 1.00 25.91 C ATOM 3324 O THR A 226 9.824 18.897 17.491 1.00 26.81 O ATOM 3325 CB THR A 226 12.980 19.776 17.866 1.00 27.83 C ATOM 3326 OG1 THR A 226 14.105 19.547 18.692 1.00 29.02 O ATOM 3327 CG2 THR A 226 12.208 20.975 18.450 1.00 30.31 C ATOM 3328 H THR A 226 13.843 17.678 16.696 1.00 25.99 H ATOM 3329 HA THR A 226 11.861 18.136 18.726 1.00 26.54 H ATOM 3330 HB THR A 226 13.365 20.071 16.891 1.00 27.83 H ATOM 3331 HG1 THR A 226 14.675 18.896 18.271 1.00 29.02 H ATOM 3332 HG21 THR A 226 12.874 21.822 18.620 1.00 30.31 H ATOM 3333 HG22 THR A 226 11.422 21.321 17.778 1.00 30.31 H ATOM 3334 HG23 THR A 226 11.747 20.720 19.404 1.00 30.31 H ATOM 3335 N LEU A 227 11.039 18.796 15.569 1.00 26.53 N ATOM 3336 CA LEU A 227 9.971 19.157 14.634 1.00 26.89 C ATOM 3337 C LEU A 227 8.993 18.011 14.324 1.00 26.84 C ATOM 3338 O LEU A 227 7.818 18.293 14.092 1.00 27.26 O ATOM 3339 CB LEU A 227 10.609 19.683 13.327 1.00 28.85 C ATOM 3340 CG LEU A 227 11.323 21.046 13.476 1.00 34.29 C ATOM 3341 CD1 LEU A 227 12.190 21.352 12.239 1.00 36.73 C ATOM 3342 CD2 LEU A 227 10.335 22.189 13.799 1.00 33.59 C ATOM 3343 H LEU A 227 11.951 18.646 15.160 1.00 26.53 H ATOM 3344 HA LEU A 227 9.381 19.956 15.084 1.00 26.89 H ATOM 3345 HB3 LEU A 227 9.850 19.773 12.547 1.00 28.85 H ATOM 3346 HB2 LEU A 227 11.318 18.937 12.962 1.00 28.85 H ATOM 3347 HG LEU A 227 12.007 20.981 14.322 1.00 34.29 H ATOM 3348 HD11 LEU A 227 12.043 22.359 11.849 1.00 36.73 H ATOM 3349 HD12 LEU A 227 13.248 21.261 12.485 1.00 36.73 H ATOM 3350 HD13 LEU A 227 11.980 20.664 11.421 1.00 36.73 H ATOM 3351 HD21 LEU A 227 10.441 23.048 13.137 1.00 33.59 H ATOM 3352 HD22 LEU A 227 9.296 21.866 13.724 1.00 33.59 H ATOM 3353 HD23 LEU A 227 10.488 22.551 14.816 1.00 33.59 H ATOM 3354 N MET A 228 9.485 16.762 14.295 1.00 25.26 N ATOM 3355 CA MET A 228 8.739 15.587 13.838 1.00 24.70 C ATOM 3356 C MET A 228 8.686 14.531 14.949 1.00 23.35 C ATOM 3357 O MET A 228 9.711 14.233 15.564 1.00 20.92 O ATOM 3358 CB MET A 228 9.408 15.055 12.555 1.00 24.08 C ATOM 3359 CG MET A 228 9.168 15.961 11.334 1.00 24.87 C ATOM 3360 SD MET A 228 10.164 15.579 9.869 1.00 24.76 S ATOM 3361 CE MET A 228 11.710 16.421 10.296 1.00 26.75 C ATOM 3362 H MET A 228 10.463 16.606 14.503 1.00 25.26 H ATOM 3363 HA MET A 228 7.710 15.854 13.592 1.00 24.70 H ATOM 3364 HB3 MET A 228 9.025 14.062 12.329 1.00 24.08 H ATOM 3365 HB2 MET A 228 10.476 14.923 12.717 1.00 24.08 H ATOM 3366 HG3 MET A 228 9.346 17.007 11.584 1.00 24.87 H ATOM 3367 HG2 MET A 228 8.119 15.895 11.046 1.00 24.87 H ATOM 3368 HE1 MET A 228 12.441 16.291 9.498 1.00 26.75 H ATOM 3369 HE2 MET A 228 11.541 17.488 10.443 1.00 26.75 H ATOM 3370 HE3 MET A 228 12.121 16.003 11.213 1.00 26.75 H ATOM 3371 N ASN A 229 7.472 14.008 15.196 1.00 23.78 N ATOM 3372 CA ASN A 229 7.145 13.104 16.305 1.00 26.25 C ATOM 3373 C ASN A 229 7.753 11.712 16.102 1.00 24.54 C ATOM 3374 O ASN A 229 7.451 11.061 15.101 1.00 24.23 O ATOM 3375 CB ASN A 229 5.610 12.979 16.458 1.00 28.76 C ATOM 3376 CG ASN A 229 4.848 14.258 16.830 1.00 36.20 C ATOM 3377 OD1 ASN A 229 3.625 14.278 16.730 1.00 39.05 O ATOM 3378 ND2 ASN A 229 5.529 15.321 17.270 1.00 36.12 N ATOM 3379 H ASN A 229 6.691 14.297 14.625 1.00 23.78 H ATOM 3380 HA ASN A 229 7.558 13.541 17.217 1.00 26.25 H ATOM 3381 HB3 ASN A 229 5.383 12.247 17.236 1.00 28.76 H ATOM 3382 HB2 ASN A 229 5.175 12.586 15.537 1.00 28.76 H ATOM 3383 HD22 ASN A 229 5.033 16.163 17.521 1.00 36.12 H ATOM 3384 HD21 ASN A 229 6.537 15.300 17.359 1.00 36.12 H ATOM 3385 N ALA A 230 8.584 11.290 17.072 1.00 23.31 N ATOM 3386 CA ALA A 230 9.316 10.019 17.096 1.00 22.45 C ATOM 3387 C ALA A 230 10.159 9.809 15.823 1.00 22.19 C ATOM 3388 O ALA A 230 10.096 8.743 15.212 1.00 21.45 O ATOM 3389 CB ALA A 230 8.342 8.859 17.379 1.00 23.18 C ATOM 3390 H ALA A 230 8.781 11.910 17.844 1.00 23.31 H ATOM 3391 HA ALA A 230 10.017 10.078 17.928 1.00 22.45 H ATOM 3392 HB1 ALA A 230 8.873 7.917 17.512 1.00 23.18 H ATOM 3393 HB2 ALA A 230 7.773 9.040 18.292 1.00 23.18 H ATOM 3394 HB3 ALA A 230 7.629 8.729 16.567 1.00 23.18 H ATOM 3395 N TYR A 231 10.893 10.865 15.427 1.00 20.58 N ATOM 3396 CA TYR A 231 11.648 10.941 14.177 1.00 23.09 C ATOM 3397 C TYR A 231 12.699 9.831 14.038 1.00 23.15 C ATOM 3398 O TYR A 231 12.776 9.221 12.977 1.00 21.50 O ATOM 3399 CB TYR A 231 12.298 12.330 14.036 1.00 21.56 C ATOM 3400 CG TYR A 231 13.026 12.550 12.723 1.00 22.51 C ATOM 3401 CD1 TYR A 231 14.422 12.360 12.636 1.00 22.41 C ATOM 3402 CD2 TYR A 231 12.293 12.898 11.571 1.00 22.80 C ATOM 3403 CE1 TYR A 231 15.072 12.484 11.394 1.00 26.33 C ATOM 3404 CE2 TYR A 231 12.946 13.045 10.336 1.00 22.49 C ATOM 3405 CZ TYR A 231 14.330 12.820 10.244 1.00 23.24 C ATOM 3406 OH TYR A 231 14.942 12.918 9.032 1.00 25.69 O ATOM 3407 H TYR A 231 10.889 11.702 15.996 1.00 20.58 H ATOM 3408 HA TYR A 231 10.930 10.820 13.365 1.00 23.09 H ATOM 3409 HB3 TYR A 231 13.004 12.479 14.852 1.00 21.56 H ATOM 3410 HB2 TYR A 231 11.542 13.108 14.131 1.00 21.56 H ATOM 3411 HD1 TYR A 231 14.993 12.090 13.512 1.00 22.41 H ATOM 3412 HD2 TYR A 231 11.225 13.034 11.626 1.00 22.80 H ATOM 3413 HE1 TYR A 231 16.136 12.318 11.326 1.00 26.33 H ATOM 3414 HE2 TYR A 231 12.381 13.310 9.454 1.00 22.49 H ATOM 3415 HH TYR A 231 15.826 12.530 9.037 1.00 25.69 H ATOM 3416 N SER A 232 13.458 9.578 15.115 1.00 22.12 N ATOM 3417 CA SER A 232 14.523 8.577 15.172 1.00 21.84 C ATOM 3418 C SER A 232 14.069 7.130 14.895 1.00 21.72 C ATOM 3419 O SER A 232 14.886 6.351 14.409 1.00 22.45 O ATOM 3420 CB SER A 232 15.255 8.712 16.523 1.00 21.64 C ATOM 3421 OG SER A 232 14.455 8.291 17.612 1.00 26.16 O ATOM 3422 H SER A 232 13.306 10.103 15.965 1.00 22.12 H ATOM 3423 HA SER A 232 15.235 8.841 14.386 1.00 21.84 H ATOM 3424 HB3 SER A 232 15.571 9.743 16.688 1.00 21.64 H ATOM 3425 HB2 SER A 232 16.164 8.108 16.515 1.00 21.64 H ATOM 3426 HG SER A 232 14.425 7.331 17.616 1.00 26.16 H ATOM 3427 N SER A 233 12.798 6.807 15.193 1.00 20.41 N ATOM 3428 CA SER A 233 12.223 5.475 15.018 1.00 20.63 C ATOM 3429 C SER A 233 11.335 5.334 13.770 1.00 19.00 C ATOM 3430 O SER A 233 11.184 4.210 13.297 1.00 19.49 O ATOM 3431 CB SER A 233 11.483 5.075 16.311 1.00 24.24 C ATOM 3432 OG SER A 233 10.309 5.832 16.529 1.00 29.04 O ATOM 3433 H SER A 233 12.181 7.506 15.583 1.00 20.41 H ATOM 3434 HA SER A 233 13.034 4.762 14.890 1.00 20.63 H ATOM 3435 HB3 SER A 233 12.140 5.172 17.176 1.00 24.24 H ATOM 3436 HB2 SER A 233 11.190 4.028 16.256 1.00 24.24 H ATOM 3437 HG SER A 233 9.885 5.511 17.328 1.00 29.04 H ATOM 3438 N ARG A 234 10.761 6.437 13.263 1.00 18.33 N ATOM 3439 CA ARG A 234 9.834 6.423 12.126 1.00 22.18 C ATOM 3440 C ARG A 234 10.484 6.846 10.803 1.00 22.21 C ATOM 3441 O ARG A 234 9.923 6.518 9.757 1.00 20.94 O ATOM 3442 CB ARG A 234 8.635 7.335 12.426 1.00 23.89 C ATOM 3443 CG ARG A 234 7.771 6.850 13.597 1.00 25.44 C ATOM 3444 CD ARG A 234 6.533 7.735 13.784 1.00 31.15 C ATOM 3445 NE ARG A 234 5.779 7.372 14.993 1.00 38.50 N ATOM 3446 CZ ARG A 234 4.777 8.070 15.560 1.00 41.33 C ATOM 3447 NH1 ARG A 234 4.323 9.221 15.039 1.00 40.07 N ATOM 3448 NH2 ARG A 234 4.217 7.600 16.681 1.00 42.46 N1+ ATOM 3449 H ARG A 234 10.909 7.329 13.714 1.00 18.33 H ATOM 3450 HA ARG A 234 9.444 5.415 11.969 1.00 22.18 H ATOM 3451 HB3 ARG A 234 8.000 7.413 11.542 1.00 23.89 H ATOM 3452 HB2 ARG A 234 8.997 8.342 12.632 1.00 23.89 H ATOM 3453 HG3 ARG A 234 8.335 6.741 14.524 1.00 25.44 H ATOM 3454 HG2 ARG A 234 7.434 5.847 13.328 1.00 25.44 H ATOM 3455 HD3 ARG A 234 5.845 7.536 12.961 1.00 31.15 H ATOM 3456 HD2 ARG A 234 6.785 8.794 13.732 1.00 31.15 H ATOM 3457 HE ARG A 234 6.063 6.507 15.431 1.00 38.50 H ATOM 3458 HH12 ARG A 234 3.570 9.728 15.479 1.00 40.07 H ATOM 3459 HH11 ARG A 234 4.741 9.588 14.196 1.00 40.07 H ATOM 3460 HH22 ARG A 234 3.464 8.103 17.128 1.00 42.46 H ATOM 3461 HH21 ARG A 234 4.542 6.736 17.091 1.00 42.46 H ATOM 3462 N SER A 235 11.627 7.550 10.843 1.00 19.99 N ATOM 3463 CA SER A 235 12.362 7.927 9.638 1.00 19.86 C ATOM 3464 C SER A 235 13.190 6.754 9.090 1.00 19.77 C ATOM 3465 O SER A 235 13.654 5.908 9.854 1.00 20.24 O ATOM 3466 CB SER A 235 13.218 9.191 9.887 1.00 21.58 C ATOM 3467 OG SER A 235 14.389 8.940 10.641 1.00 21.88 O ATOM 3468 H SER A 235 12.049 7.797 11.728 1.00 19.99 H ATOM 3469 HA SER A 235 11.616 8.202 8.894 1.00 19.86 H ATOM 3470 HB3 SER A 235 12.630 9.964 10.381 1.00 21.58 H ATOM 3471 HB2 SER A 235 13.532 9.613 8.932 1.00 21.58 H ATOM 3472 HG SER A 235 14.132 8.796 11.556 1.00 21.88 H ATOM 3473 N HIS A 236 13.385 6.775 7.767 1.00 18.17 N ATOM 3474 CA HIS A 236 14.415 6.021 7.061 1.00 19.29 C ATOM 3475 C HIS A 236 15.540 7.008 6.739 1.00 18.44 C ATOM 3476 O HIS A 236 15.240 8.154 6.412 1.00 20.59 O ATOM 3477 CB HIS A 236 13.838 5.446 5.751 1.00 18.44 C ATOM 3478 CG HIS A 236 12.567 4.658 5.915 1.00 20.86 C ATOM 3479 ND1 HIS A 236 12.567 3.288 6.186 1.00 20.53 N ATOM 3480 CD2 HIS A 236 11.262 5.099 5.848 1.00 19.38 C ATOM 3481 CE1 HIS A 236 11.289 2.955 6.262 1.00 18.42 C ATOM 3482 NE2 HIS A 236 10.470 3.991 6.085 1.00 19.60 N ATOM 3483 H HIS A 236 12.937 7.503 7.225 1.00 18.17 H ATOM 3484 HA HIS A 236 14.788 5.205 7.682 1.00 19.29 H ATOM 3485 HB3 HIS A 236 14.579 4.798 5.281 1.00 18.44 H ATOM 3486 HB2 HIS A 236 13.643 6.244 5.034 1.00 18.44 H ATOM 3487 HD2 HIS A 236 10.849 6.082 5.670 1.00 19.38 H ATOM 3488 HE1 HIS A 236 10.952 1.951 6.463 1.00 18.42 H ATOM 3489 HE2 HIS A 236 9.458 3.974 6.127 1.00 19.60 H ATOM 3490 N SER A 237 16.795 6.553 6.800 1.00 20.58 N ATOM 3491 CA SER A 237 17.963 7.337 6.407 1.00 21.26 C ATOM 3492 C SER A 237 18.805 6.538 5.412 1.00 21.57 C ATOM 3493 O SER A 237 18.957 5.331 5.575 1.00 20.33 O ATOM 3494 CB SER A 237 18.746 7.785 7.658 1.00 24.54 C ATOM 3495 OG SER A 237 19.438 6.740 8.306 1.00 26.90 O ATOM 3496 H SER A 237 16.979 5.608 7.117 1.00 20.58 H ATOM 3497 HA SER A 237 17.636 8.238 5.889 1.00 21.26 H ATOM 3498 HB3 SER A 237 18.080 8.263 8.376 1.00 24.54 H ATOM 3499 HB2 SER A 237 19.489 8.527 7.370 1.00 24.54 H ATOM 3500 HG SER A 237 20.153 6.437 7.740 1.00 26.90 H ATOM 3501 N VAL A 238 19.332 7.242 4.403 1.00 22.05 N ATOM 3502 CA VAL A 238 20.194 6.705 3.361 1.00 22.38 C ATOM 3503 C VAL A 238 21.449 7.588 3.345 1.00 23.09 C ATOM 3504 O VAL A 238 21.437 8.661 2.740 1.00 25.68 O ATOM 3505 CB VAL A 238 19.505 6.745 1.960 1.00 21.69 C ATOM 3506 CG1 VAL A 238 20.417 6.244 0.817 1.00 20.82 C ATOM 3507 CG2 VAL A 238 18.179 5.960 1.947 1.00 20.75 C ATOM 3508 H VAL A 238 19.125 8.231 4.327 1.00 22.05 H ATOM 3509 HA VAL A 238 20.492 5.678 3.581 1.00 22.38 H ATOM 3510 HB VAL A 238 19.240 7.777 1.727 1.00 21.69 H ATOM 3511 HG11 VAL A 238 19.878 6.212 -0.131 1.00 20.82 H ATOM 3512 HG12 VAL A 238 21.283 6.888 0.664 1.00 20.82 H ATOM 3513 HG13 VAL A 238 20.787 5.239 1.019 1.00 20.82 H ATOM 3514 HG21 VAL A 238 17.729 5.956 0.953 1.00 20.75 H ATOM 3515 HG22 VAL A 238 18.326 4.924 2.248 1.00 20.75 H ATOM 3516 HG23 VAL A 238 17.448 6.400 2.625 1.00 20.75 H ATOM 3517 N PHE A 239 22.506 7.123 4.030 1.00 25.74 N ATOM 3518 CA PHE A 239 23.827 7.740 3.977 1.00 25.50 C ATOM 3519 C PHE A 239 24.558 7.114 2.787 1.00 27.21 C ATOM 3520 O PHE A 239 24.990 5.967 2.888 1.00 25.60 O ATOM 3521 CB PHE A 239 24.578 7.511 5.311 1.00 24.56 C ATOM 3522 CG PHE A 239 25.854 8.329 5.462 1.00 23.56 C ATOM 3523 CD1 PHE A 239 27.025 7.986 4.751 1.00 24.94 C ATOM 3524 CD2 PHE A 239 25.838 9.529 6.207 1.00 23.03 C ATOM 3525 CE1 PHE A 239 28.138 8.812 4.803 1.00 25.28 C ATOM 3526 CE2 PHE A 239 26.973 10.326 6.270 1.00 24.84 C ATOM 3527 CZ PHE A 239 28.118 9.970 5.570 1.00 24.20 C ATOM 3528 H PHE A 239 22.445 6.239 4.520 1.00 25.74 H ATOM 3529 HA PHE A 239 23.731 8.815 3.829 1.00 25.50 H ATOM 3530 HB3 PHE A 239 24.830 6.458 5.432 1.00 24.56 H ATOM 3531 HB2 PHE A 239 23.920 7.740 6.149 1.00 24.56 H ATOM 3532 HD1 PHE A 239 27.060 7.091 4.149 1.00 24.94 H ATOM 3533 HD2 PHE A 239 24.948 9.833 6.737 1.00 23.03 H ATOM 3534 HE1 PHE A 239 29.017 8.553 4.233 1.00 25.28 H ATOM 3535 HE2 PHE A 239 26.959 11.237 6.851 1.00 24.84 H ATOM 3536 HZ PHE A 239 28.992 10.604 5.608 1.00 24.20 H ATOM 3537 N SER A 240 24.678 7.865 1.684 1.00 28.35 N ATOM 3538 CA SER A 240 25.437 7.427 0.520 1.00 31.42 C ATOM 3539 C SER A 240 26.833 8.061 0.527 1.00 32.07 C ATOM 3540 O SER A 240 26.976 9.215 0.929 1.00 32.25 O ATOM 3541 CB SER A 240 24.635 7.678 -0.772 1.00 34.03 C ATOM 3542 OG SER A 240 24.801 8.961 -1.338 1.00 40.12 O ATOM 3543 H SER A 240 24.334 8.817 1.676 1.00 28.35 H ATOM 3544 HA SER A 240 25.557 6.350 0.576 1.00 31.42 H ATOM 3545 HB3 SER A 240 23.573 7.482 -0.617 1.00 34.03 H ATOM 3546 HB2 SER A 240 24.974 6.957 -1.515 1.00 34.03 H ATOM 3547 HG SER A 240 24.336 9.607 -0.796 1.00 40.12 H ATOM 3548 N VAL A 241 27.817 7.288 0.052 1.00 33.55 N ATOM 3549 CA VAL A 241 29.173 7.736 -0.231 1.00 34.45 C ATOM 3550 C VAL A 241 29.516 7.325 -1.670 1.00 34.62 C ATOM 3551 O VAL A 241 29.385 6.151 -2.006 1.00 35.51 O ATOM 3552 CB VAL A 241 30.218 7.168 0.778 1.00 34.83 C ATOM 3553 CG1 VAL A 241 30.239 5.637 0.921 1.00 38.79 C ATOM 3554 CG2 VAL A 241 31.645 7.669 0.487 1.00 35.64 C ATOM 3555 H VAL A 241 27.608 6.336 -0.224 1.00 33.55 H ATOM 3556 HA VAL A 241 29.205 8.822 -0.168 1.00 34.45 H ATOM 3557 HB VAL A 241 29.942 7.557 1.759 1.00 34.83 H ATOM 3558 HG11 VAL A 241 30.890 5.333 1.741 1.00 38.79 H ATOM 3559 HG12 VAL A 241 29.247 5.242 1.140 1.00 38.79 H ATOM 3560 HG13 VAL A 241 30.619 5.155 0.020 1.00 38.79 H ATOM 3561 HG21 VAL A 241 32.356 7.285 1.217 1.00 35.64 H ATOM 3562 HG22 VAL A 241 32.007 7.357 -0.493 1.00 35.64 H ATOM 3563 HG23 VAL A 241 31.682 8.757 0.528 1.00 35.64 H ATOM 3564 N THR A 242 29.937 8.305 -2.483 1.00 35.79 N ATOM 3565 CA THR A 242 30.386 8.109 -3.859 1.00 37.70 C ATOM 3566 C THR A 242 31.881 8.444 -3.934 1.00 37.87 C ATOM 3567 O THR A 242 32.287 9.492 -3.432 1.00 37.49 O ATOM 3568 CB THR A 242 29.638 9.035 -4.853 1.00 37.97 C ATOM 3569 OG1 THR A 242 28.251 8.772 -4.771 1.00 39.56 O ATOM 3570 CG2 THR A 242 30.056 8.873 -6.329 1.00 37.97 C ATOM 3571 H THR A 242 30.018 9.247 -2.121 1.00 35.79 H ATOM 3572 HA THR A 242 30.233 7.075 -4.163 1.00 37.70 H ATOM 3573 HB THR A 242 29.780 10.077 -4.562 1.00 37.97 H ATOM 3574 HG1 THR A 242 27.942 9.076 -3.910 1.00 39.56 H ATOM 3575 HG21 THR A 242 29.443 9.500 -6.978 1.00 37.97 H ATOM 3576 HG22 THR A 242 31.093 9.162 -6.497 1.00 37.97 H ATOM 3577 HG23 THR A 242 29.940 7.842 -6.663 1.00 37.97 H ATOM 3578 N ILE A 243 32.662 7.550 -4.557 1.00 39.49 N ATOM 3579 CA ILE A 243 34.109 7.678 -4.676 1.00 41.33 C ATOM 3580 C ILE A 243 34.449 7.701 -6.177 1.00 42.69 C ATOM 3581 O ILE A 243 34.334 6.678 -6.850 1.00 41.59 O ATOM 3582 CB ILE A 243 34.876 6.490 -4.019 1.00 42.17 C ATOM 3583 CG1 ILE A 243 34.339 6.106 -2.620 1.00 40.50 C ATOM 3584 CG2 ILE A 243 36.390 6.787 -3.930 1.00 40.47 C ATOM 3585 CD1 ILE A 243 34.920 4.783 -2.110 1.00 41.65 C ATOM 3586 H ILE A 243 32.248 6.725 -4.976 1.00 39.49 H ATOM 3587 HA ILE A 243 34.458 8.602 -4.216 1.00 41.33 H ATOM 3588 HB ILE A 243 34.752 5.605 -4.645 1.00 42.17 H ATOM 3589 HG13 ILE A 243 33.255 5.995 -2.632 1.00 40.50 H ATOM 3590 HG12 ILE A 243 34.550 6.905 -1.908 1.00 40.50 H ATOM 3591 HG21 ILE A 243 36.951 5.895 -3.657 1.00 40.47 H ATOM 3592 HG22 ILE A 243 36.803 7.155 -4.866 1.00 40.47 H ATOM 3593 HG23 ILE A 243 36.598 7.551 -3.181 1.00 40.47 H ATOM 3594 HD11 ILE A 243 34.284 4.344 -1.342 1.00 41.65 H ATOM 3595 HD12 ILE A 243 35.006 4.057 -2.917 1.00 41.65 H ATOM 3596 HD13 ILE A 243 35.912 4.930 -1.687 1.00 41.65 H ATOM 3597 N HIS A 244 34.874 8.872 -6.667 1.00 44.46 N ATOM 3598 CA HIS A 244 35.465 9.037 -7.994 1.00 47.53 C ATOM 3599 C HIS A 244 36.957 8.733 -7.886 1.00 47.71 C ATOM 3600 O HIS A 244 37.603 9.276 -6.996 1.00 47.71 O ATOM 3601 CB HIS A 244 35.233 10.474 -8.489 1.00 49.46 C ATOM 3602 CG HIS A 244 33.777 10.794 -8.685 1.00 52.62 C ATOM 3603 ND1 HIS A 244 33.068 10.377 -9.815 1.00 53.91 N ATOM 3604 CD2 HIS A 244 32.917 11.459 -7.836 1.00 52.34 C ATOM 3605 CE1 HIS A 244 31.825 10.785 -9.607 1.00 52.76 C ATOM 3606 NE2 HIS A 244 31.678 11.428 -8.450 1.00 53.06 N ATOM 3607 H HIS A 244 34.966 9.663 -6.042 1.00 44.46 H ATOM 3608 HA HIS A 244 35.003 8.345 -8.703 1.00 47.53 H ATOM 3609 HB3 HIS A 244 35.744 10.631 -9.440 1.00 49.46 H ATOM 3610 HB2 HIS A 244 35.656 11.195 -7.789 1.00 49.46 H ATOM 3611 HD2 HIS A 244 33.081 11.910 -6.869 1.00 52.34 H ATOM 3612 HE1 HIS A 244 31.016 10.606 -10.300 1.00 52.76 H ATOM 3613 HE2 HIS A 244 30.815 11.798 -8.084 1.00 53.06 H ATOM 3614 N MET A 245 37.457 7.850 -8.758 1.00 48.94 N ATOM 3615 CA MET A 245 38.824 7.338 -8.731 1.00 49.37 C ATOM 3616 C MET A 245 39.421 7.438 -10.134 1.00 51.21 C ATOM 3617 O MET A 245 38.759 7.086 -11.108 1.00 50.79 O ATOM 3618 CB MET A 245 38.819 5.865 -8.272 1.00 47.53 C ATOM 3619 CG MET A 245 38.271 5.654 -6.855 1.00 47.54 C ATOM 3620 SD MET A 245 37.955 3.929 -6.414 1.00 44.84 S ATOM 3621 CE MET A 245 36.293 3.751 -7.119 1.00 45.83 C ATOM 3622 H MET A 245 36.852 7.437 -9.457 1.00 48.94 H ATOM 3623 HA MET A 245 39.444 7.918 -8.045 1.00 49.37 H ATOM 3624 HB3 MET A 245 39.834 5.467 -8.312 1.00 47.53 H ATOM 3625 HB2 MET A 245 38.237 5.267 -8.972 1.00 47.53 H ATOM 3626 HG3 MET A 245 37.325 6.176 -6.737 1.00 47.54 H ATOM 3627 HG2 MET A 245 38.961 6.087 -6.134 1.00 47.54 H ATOM 3628 HE1 MET A 245 35.952 2.719 -7.071 1.00 45.83 H ATOM 3629 HE2 MET A 245 35.584 4.362 -6.562 1.00 45.83 H ATOM 3630 HE3 MET A 245 36.276 4.068 -8.160 1.00 45.83 H ATOM 3631 N LYS A 246 40.684 7.866 -10.183 1.00 52.65 N ATOM 3632 CA LYS A 246 41.535 7.895 -11.359 1.00 54.10 C ATOM 3633 C LYS A 246 42.818 7.169 -10.943 1.00 54.52 C ATOM 3634 O LYS A 246 43.819 7.799 -10.602 1.00 54.51 O ATOM 3635 CB LYS A 246 41.739 9.358 -11.806 1.00 54.81 C ATOM 3636 CG LYS A 246 42.485 9.497 -13.141 1.00 57.30 C ATOM 3637 CD LYS A 246 42.701 10.970 -13.530 1.00 58.78 C ATOM 3638 CE LYS A 246 43.164 11.179 -14.981 1.00 60.80 C ATOM 3639 NZ LYS A 246 42.095 10.892 -15.956 1.00 61.59 N1+ ATOM 3640 H LYS A 246 41.126 8.187 -9.332 1.00 52.65 H ATOM 3641 HA LYS A 246 41.081 7.338 -12.181 1.00 54.10 H ATOM 3642 HB3 LYS A 246 42.254 9.926 -11.031 1.00 54.81 H ATOM 3643 HB2 LYS A 246 40.760 9.829 -11.914 1.00 54.81 H ATOM 3644 HG3 LYS A 246 41.921 8.974 -13.913 1.00 57.30 H ATOM 3645 HG2 LYS A 246 43.454 9.000 -13.088 1.00 57.30 H ATOM 3646 HD3 LYS A 246 43.469 11.377 -12.874 1.00 58.78 H ATOM 3647 HD2 LYS A 246 41.801 11.554 -13.329 1.00 58.78 H ATOM 3648 HE3 LYS A 246 44.032 10.555 -15.198 1.00 60.80 H ATOM 3649 HE2 LYS A 246 43.476 12.215 -15.118 1.00 60.80 H ATOM 3650 HZ1 LYS A 246 41.307 11.498 -15.780 1.00 61.59 H ATOM 3651 HZ2 LYS A 246 42.444 11.052 -16.890 1.00 61.59 H ATOM 3652 HZ3 LYS A 246 41.808 9.928 -15.866 1.00 61.59 H ATOM 3653 N GLU A 247 42.715 5.832 -10.913 1.00 55.12 N ATOM 3654 CA GLU A 247 43.784 4.911 -10.550 1.00 56.95 C ATOM 3655 C GLU A 247 44.915 4.946 -11.578 1.00 58.47 C ATOM 3656 O GLU A 247 44.640 4.787 -12.762 1.00 58.51 O ATOM 3657 CB GLU A 247 43.189 3.496 -10.407 1.00 56.93 C ATOM 3658 CG GLU A 247 44.225 2.401 -10.073 1.00 58.97 C ATOM 3659 CD GLU A 247 43.569 1.035 -9.857 1.00 60.88 C ATOM 3660 OE1 GLU A 247 42.999 0.506 -10.837 1.00 62.91 O ATOM 3661 OE2 GLU A 247 43.629 0.548 -8.706 1.00 61.38 O1- ATOM 3662 H GLU A 247 41.860 5.400 -11.234 1.00 55.12 H ATOM 3663 HA GLU A 247 44.178 5.209 -9.579 1.00 56.95 H ATOM 3664 HB3 GLU A 247 42.663 3.231 -11.326 1.00 56.93 H ATOM 3665 HB2 GLU A 247 42.429 3.516 -9.626 1.00 56.93 H ATOM 3666 HG3 GLU A 247 44.795 2.691 -9.188 1.00 58.97 H ATOM 3667 HG2 GLU A 247 44.950 2.292 -10.880 1.00 58.97 H ATOM 3668 N THR A 248 46.150 5.112 -11.092 1.00 59.07 N ATOM 3669 CA THR A 248 47.364 5.048 -11.894 1.00 60.38 C ATOM 3670 C THR A 248 48.174 3.841 -11.380 1.00 60.78 C ATOM 3671 O THR A 248 49.039 3.969 -10.512 1.00 60.10 O ATOM 3672 CB THR A 248 48.164 6.380 -11.808 1.00 61.01 C ATOM 3673 OG1 THR A 248 48.631 6.673 -10.505 1.00 63.16 O ATOM 3674 CG2 THR A 248 47.349 7.593 -12.286 1.00 61.02 C ATOM 3675 H THR A 248 46.288 5.253 -10.101 1.00 59.07 H ATOM 3676 HA THR A 248 47.135 4.874 -12.946 1.00 60.38 H ATOM 3677 HB THR A 248 49.041 6.290 -12.451 1.00 61.01 H ATOM 3678 HG1 THR A 248 49.173 5.935 -10.211 1.00 63.16 H ATOM 3679 HG21 THR A 248 46.540 7.829 -11.593 1.00 61.02 H ATOM 3680 HG22 THR A 248 47.976 8.481 -12.372 1.00 61.02 H ATOM 3681 HG23 THR A 248 46.897 7.411 -13.258 1.00 61.02 H ATOM 3682 N THR A 249 47.830 2.661 -11.924 1.00 61.35 N ATOM 3683 CA THR A 249 48.451 1.356 -11.655 1.00 61.85 C ATOM 3684 C THR A 249 49.974 1.367 -11.930 1.00 61.20 C ATOM 3685 O THR A 249 50.436 2.222 -12.687 1.00 61.63 O ATOM 3686 CB THR A 249 47.775 0.282 -12.555 1.00 62.62 C ATOM 3687 OG1 THR A 249 46.380 0.301 -12.329 1.00 63.50 O ATOM 3688 CG2 THR A 249 48.237 -1.174 -12.374 1.00 63.08 C ATOM 3689 H THR A 249 47.096 2.643 -12.619 1.00 61.35 H ATOM 3690 HA THR A 249 48.287 1.113 -10.603 1.00 61.85 H ATOM 3691 HB THR A 249 47.925 0.556 -13.600 1.00 62.62 H ATOM 3692 HG1 THR A 249 45.978 -0.434 -12.800 1.00 63.50 H ATOM 3693 HG21 THR A 249 49.255 -1.308 -12.728 1.00 63.08 H ATOM 3694 HG22 THR A 249 48.182 -1.491 -11.333 1.00 63.08 H ATOM 3695 HG23 THR A 249 47.620 -1.853 -12.965 1.00 63.08 H ATOM 3696 N ILE A 250 50.739 0.444 -11.314 1.00 60.81 N ATOM 3697 CA ILE A 250 52.208 0.371 -11.433 1.00 60.26 C ATOM 3698 C ILE A 250 52.738 0.202 -12.880 1.00 60.18 C ATOM 3699 O ILE A 250 53.884 0.564 -13.145 1.00 60.31 O ATOM 3700 CB ILE A 250 52.833 -0.742 -10.532 1.00 60.33 C ATOM 3701 CG1 ILE A 250 52.798 -2.204 -11.054 1.00 59.91 C ATOM 3702 CG2 ILE A 250 52.350 -0.643 -9.073 1.00 59.68 C ATOM 3703 CD1 ILE A 250 51.405 -2.813 -11.267 1.00 59.13 C ATOM 3704 H ILE A 250 50.309 -0.236 -10.705 1.00 60.81 H ATOM 3705 HA ILE A 250 52.589 1.331 -11.079 1.00 60.26 H ATOM 3706 HB ILE A 250 53.896 -0.500 -10.486 1.00 60.33 H ATOM 3707 HG13 ILE A 250 53.348 -2.837 -10.358 1.00 59.91 H ATOM 3708 HG12 ILE A 250 53.356 -2.284 -11.988 1.00 59.91 H ATOM 3709 HG21 ILE A 250 52.903 -1.328 -8.430 1.00 59.68 H ATOM 3710 HG22 ILE A 250 52.501 0.364 -8.681 1.00 59.68 H ATOM 3711 HG23 ILE A 250 51.292 -0.878 -8.971 1.00 59.68 H ATOM 3712 HD11 ILE A 250 51.460 -3.901 -11.245 1.00 59.13 H ATOM 3713 HD12 ILE A 250 50.690 -2.503 -10.506 1.00 59.13 H ATOM 3714 HD13 ILE A 250 51.009 -2.537 -12.240 1.00 59.13 H ATOM 3715 N ASP A 251 51.877 -0.296 -13.783 1.00 60.25 N ATOM 3716 CA ASP A 251 52.093 -0.443 -15.227 1.00 60.38 C ATOM 3717 C ASP A 251 51.906 0.869 -16.021 1.00 59.91 C ATOM 3718 O ASP A 251 52.124 0.866 -17.232 1.00 60.56 O ATOM 3719 CB ASP A 251 51.210 -1.577 -15.810 1.00 60.98 C ATOM 3720 CG ASP A 251 51.362 -2.949 -15.123 1.00 62.11 C ATOM 3721 OD1 ASP A 251 52.484 -3.264 -14.662 1.00 61.91 O ATOM 3722 OD2 ASP A 251 50.386 -3.726 -15.198 1.00 62.45 O1- ATOM 3723 H ASP A 251 50.959 -0.569 -13.462 1.00 60.25 H ATOM 3724 HA ASP A 251 53.135 -0.719 -15.386 1.00 60.38 H ATOM 3725 HB3 ASP A 251 51.435 -1.722 -16.868 1.00 60.98 H ATOM 3726 HB2 ASP A 251 50.162 -1.280 -15.744 1.00 60.98 H ATOM 3727 N GLY A 252 51.533 1.965 -15.340 1.00 59.46 N ATOM 3728 CA GLY A 252 51.425 3.314 -15.890 1.00 58.92 C ATOM 3729 C GLY A 252 50.054 3.604 -16.519 1.00 59.26 C ATOM 3730 O GLY A 252 49.792 4.764 -16.834 1.00 59.89 O ATOM 3731 H GLY A 252 51.351 1.878 -14.347 1.00 59.46 H ATOM 3732 HA3 GLY A 252 52.207 3.491 -16.631 1.00 58.92 H ATOM 3733 HA2 GLY A 252 51.593 4.024 -15.080 1.00 58.92 H ATOM 3734 N GLU A 253 49.181 2.592 -16.697 1.00 59.20 N ATOM 3735 CA GLU A 253 47.828 2.766 -17.232 1.00 59.24 C ATOM 3736 C GLU A 253 46.901 3.473 -16.229 1.00 59.28 C ATOM 3737 O GLU A 253 46.977 3.209 -15.027 1.00 59.03 O ATOM 3738 CB GLU A 253 47.239 1.422 -17.710 1.00 58.97 C ATOM 3739 CG GLU A 253 47.239 0.276 -16.668 1.00 60.46 C ATOM 3740 CD GLU A 253 46.358 -0.937 -17.017 1.00 61.44 C ATOM 3741 OE1 GLU A 253 46.334 -1.858 -16.171 1.00 62.15 O ATOM 3742 OE2 GLU A 253 45.713 -0.943 -18.091 1.00 61.94 O1- ATOM 3743 H GLU A 253 49.438 1.656 -16.422 1.00 59.20 H ATOM 3744 HA GLU A 253 47.908 3.405 -18.115 1.00 59.24 H ATOM 3745 HB3 GLU A 253 47.776 1.095 -18.601 1.00 58.97 H ATOM 3746 HB2 GLU A 253 46.218 1.616 -18.042 1.00 58.97 H ATOM 3747 HG3 GLU A 253 46.911 0.649 -15.699 1.00 60.46 H ATOM 3748 HG2 GLU A 253 48.261 -0.074 -16.521 1.00 60.46 H ATOM 3749 N GLU A 254 46.051 4.360 -16.766 1.00 59.88 N ATOM 3750 CA GLU A 254 45.186 5.249 -15.999 1.00 60.07 C ATOM 3751 C GLU A 254 43.718 4.831 -16.186 1.00 59.53 C ATOM 3752 O GLU A 254 43.112 5.189 -17.197 1.00 59.70 O ATOM 3753 CB GLU A 254 45.443 6.709 -16.427 1.00 61.29 C ATOM 3754 CG GLU A 254 46.924 7.132 -16.311 1.00 62.36 C ATOM 3755 CD GLU A 254 47.130 8.637 -16.518 1.00 63.74 C ATOM 3756 OE1 GLU A 254 46.738 9.130 -17.600 1.00 64.15 O ATOM 3757 OE2 GLU A 254 47.679 9.276 -15.594 1.00 63.61 O1- ATOM 3758 H GLU A 254 46.043 4.499 -17.766 1.00 59.88 H ATOM 3759 HA GLU A 254 45.447 5.191 -14.948 1.00 60.07 H ATOM 3760 HB3 GLU A 254 44.829 7.369 -15.813 1.00 61.29 H ATOM 3761 HB2 GLU A 254 45.111 6.858 -17.456 1.00 61.29 H ATOM 3762 HG3 GLU A 254 47.521 6.610 -17.060 1.00 62.36 H ATOM 3763 HG2 GLU A 254 47.330 6.821 -15.348 1.00 62.36 H ATOM 3764 N LEU A 255 43.180 4.067 -15.219 1.00 58.86 N ATOM 3765 CA LEU A 255 41.805 3.560 -15.232 1.00 58.29 C ATOM 3766 C LEU A 255 40.913 4.453 -14.360 1.00 57.75 C ATOM 3767 O LEU A 255 41.251 4.697 -13.202 1.00 57.53 O ATOM 3768 CB LEU A 255 41.739 2.102 -14.708 1.00 58.62 C ATOM 3769 CG LEU A 255 42.695 1.080 -15.367 1.00 59.01 C ATOM 3770 CD1 LEU A 255 42.701 1.131 -16.908 1.00 58.57 C ATOM 3771 CD2 LEU A 255 44.110 1.121 -14.761 1.00 59.86 C ATOM 3772 H LEU A 255 43.733 3.839 -14.403 1.00 58.86 H ATOM 3773 HA LEU A 255 41.415 3.576 -16.252 1.00 58.29 H ATOM 3774 HB3 LEU A 255 40.718 1.748 -14.855 1.00 58.62 H ATOM 3775 HB2 LEU A 255 41.892 2.077 -13.627 1.00 58.62 H ATOM 3776 HG LEU A 255 42.291 0.103 -15.096 1.00 59.01 H ATOM 3777 HD11 LEU A 255 42.773 0.126 -17.324 1.00 58.57 H ATOM 3778 HD12 LEU A 255 41.789 1.575 -17.307 1.00 58.57 H ATOM 3779 HD13 LEU A 255 43.542 1.705 -17.299 1.00 58.57 H ATOM 3780 HD21 LEU A 255 44.449 0.119 -14.496 1.00 59.86 H ATOM 3781 HD22 LEU A 255 44.831 1.533 -15.462 1.00 59.86 H ATOM 3782 HD23 LEU A 255 44.162 1.728 -13.856 1.00 59.86 H ATOM 3783 N VAL A 256 39.772 4.886 -14.918 1.00 57.07 N ATOM 3784 CA VAL A 256 38.769 5.674 -14.203 1.00 55.73 C ATOM 3785 C VAL A 256 37.654 4.739 -13.697 1.00 54.78 C ATOM 3786 O VAL A 256 37.149 3.923 -14.470 1.00 54.63 O ATOM 3787 CB VAL A 256 38.147 6.774 -15.109 1.00 56.83 C ATOM 3788 CG1 VAL A 256 37.027 7.586 -14.422 1.00 57.15 C ATOM 3789 CG2 VAL A 256 39.229 7.743 -15.624 1.00 57.77 C ATOM 3790 H VAL A 256 39.545 4.628 -15.868 1.00 57.07 H ATOM 3791 HA VAL A 256 39.237 6.171 -13.355 1.00 55.73 H ATOM 3792 HB VAL A 256 37.708 6.293 -15.984 1.00 56.83 H ATOM 3793 HG11 VAL A 256 36.685 8.401 -15.061 1.00 57.15 H ATOM 3794 HG12 VAL A 256 36.150 6.978 -14.200 1.00 57.15 H ATOM 3795 HG13 VAL A 256 37.374 8.025 -13.486 1.00 57.15 H ATOM 3796 HG21 VAL A 256 38.797 8.514 -16.263 1.00 57.77 H ATOM 3797 HG22 VAL A 256 39.733 8.243 -14.796 1.00 57.77 H ATOM 3798 HG23 VAL A 256 39.988 7.228 -16.213 1.00 57.77 H ATOM 3799 N LYS A 257 37.297 4.882 -12.411 1.00 51.70 N ATOM 3800 CA LYS A 257 36.267 4.096 -11.731 1.00 48.93 C ATOM 3801 C LYS A 257 35.394 5.013 -10.863 1.00 46.97 C ATOM 3802 O LYS A 257 35.898 5.988 -10.307 1.00 45.71 O ATOM 3803 CB LYS A 257 36.932 3.004 -10.863 1.00 50.03 C ATOM 3804 CG LYS A 257 37.610 1.885 -11.674 1.00 50.79 C ATOM 3805 CD LYS A 257 38.182 0.733 -10.824 1.00 50.90 C ATOM 3806 CE LYS A 257 39.599 0.953 -10.258 1.00 50.77 C ATOM 3807 NZ LYS A 257 39.631 1.866 -9.101 1.00 52.08 N1+ ATOM 3808 H LYS A 257 37.745 5.597 -11.851 1.00 51.70 H ATOM 3809 HA LYS A 257 35.617 3.621 -12.468 1.00 48.93 H ATOM 3810 HB3 LYS A 257 36.171 2.541 -10.233 1.00 50.03 H ATOM 3811 HB2 LYS A 257 37.646 3.464 -10.184 1.00 50.03 H ATOM 3812 HG3 LYS A 257 38.403 2.295 -12.300 1.00 50.79 H ATOM 3813 HG2 LYS A 257 36.874 1.470 -12.364 1.00 50.79 H ATOM 3814 HD3 LYS A 257 38.185 -0.176 -11.428 1.00 50.90 H ATOM 3815 HD2 LYS A 257 37.501 0.527 -10.001 1.00 50.90 H ATOM 3816 HE3 LYS A 257 40.268 1.325 -11.034 1.00 50.77 H ATOM 3817 HE2 LYS A 257 40.004 -0.002 -9.923 1.00 50.77 H ATOM 3818 HZ1 LYS A 257 39.030 1.505 -8.371 1.00 52.08 H ATOM 3819 HZ2 LYS A 257 40.576 1.935 -8.747 1.00 52.08 H ATOM 3820 HZ3 LYS A 257 39.307 2.780 -9.379 1.00 52.08 H ATOM 3821 N ILE A 258 34.106 4.658 -10.739 1.00 44.56 N ATOM 3822 CA ILE A 258 33.141 5.328 -9.869 1.00 42.44 C ATOM 3823 C ILE A 258 32.493 4.263 -8.973 1.00 40.52 C ATOM 3824 O ILE A 258 31.740 3.424 -9.467 1.00 38.13 O ATOM 3825 CB ILE A 258 32.027 6.079 -10.663 1.00 43.22 C ATOM 3826 CG1 ILE A 258 32.645 7.190 -11.544 1.00 43.77 C ATOM 3827 CG2 ILE A 258 30.926 6.672 -9.747 1.00 45.13 C ATOM 3828 CD1 ILE A 258 31.642 7.914 -12.454 1.00 43.79 C ATOM 3829 H ILE A 258 33.760 3.844 -11.234 1.00 44.56 H ATOM 3830 HA ILE A 258 33.644 6.058 -9.234 1.00 42.44 H ATOM 3831 HB ILE A 258 31.547 5.364 -11.335 1.00 43.22 H ATOM 3832 HG13 ILE A 258 33.426 6.775 -12.181 1.00 43.77 H ATOM 3833 HG12 ILE A 258 33.145 7.917 -10.906 1.00 43.77 H ATOM 3834 HG21 ILE A 258 30.165 7.201 -10.320 1.00 45.13 H ATOM 3835 HG22 ILE A 258 30.392 5.911 -9.178 1.00 45.13 H ATOM 3836 HG23 ILE A 258 31.351 7.380 -9.034 1.00 45.13 H ATOM 3837 HD11 ILE A 258 32.147 8.348 -13.316 1.00 43.79 H ATOM 3838 HD12 ILE A 258 30.876 7.234 -12.828 1.00 43.79 H ATOM 3839 HD13 ILE A 258 31.143 8.726 -11.925 1.00 43.79 H ATOM 3840 N GLY A 259 32.801 4.332 -7.672 1.00 37.82 N ATOM 3841 CA GLY A 259 32.202 3.496 -6.640 1.00 36.40 C ATOM 3842 C GLY A 259 31.053 4.262 -5.984 1.00 34.07 C ATOM 3843 O GLY A 259 31.104 5.487 -5.890 1.00 31.38 O ATOM 3844 H GLY A 259 33.422 5.067 -7.355 1.00 37.82 H ATOM 3845 HA3 GLY A 259 32.954 3.321 -5.874 1.00 36.40 H ATOM 3846 HA2 GLY A 259 31.876 2.528 -7.023 1.00 36.40 H ATOM 3847 N LYS A 260 30.053 3.529 -5.474 1.00 34.92 N ATOM 3848 CA LYS A 260 28.978 4.071 -4.644 1.00 35.62 C ATOM 3849 C LYS A 260 28.524 3.011 -3.631 1.00 34.43 C ATOM 3850 O LYS A 260 28.368 1.848 -3.994 1.00 33.78 O ATOM 3851 CB LYS A 260 27.843 4.620 -5.535 1.00 38.36 C ATOM 3852 CG LYS A 260 26.584 5.118 -4.799 1.00 43.96 C ATOM 3853 CD LYS A 260 25.539 5.668 -5.789 1.00 46.47 C ATOM 3854 CE LYS A 260 24.143 5.904 -5.188 1.00 47.84 C ATOM 3855 NZ LYS A 260 24.126 6.991 -4.194 1.00 49.34 N1+ ATOM 3856 H LYS A 260 30.055 2.524 -5.588 1.00 34.92 H ATOM 3857 HA LYS A 260 29.389 4.904 -4.081 1.00 35.62 H ATOM 3858 HB3 LYS A 260 27.538 3.834 -6.221 1.00 38.36 H ATOM 3859 HB2 LYS A 260 28.235 5.428 -6.153 1.00 38.36 H ATOM 3860 HG3 LYS A 260 26.861 5.884 -4.074 1.00 43.96 H ATOM 3861 HG2 LYS A 260 26.135 4.301 -4.233 1.00 43.96 H ATOM 3862 HD3 LYS A 260 25.439 4.972 -6.623 1.00 46.47 H ATOM 3863 HD2 LYS A 260 25.914 6.594 -6.227 1.00 46.47 H ATOM 3864 HE3 LYS A 260 23.769 4.990 -4.727 1.00 47.84 H ATOM 3865 HE2 LYS A 260 23.443 6.165 -5.982 1.00 47.84 H ATOM 3866 HZ1 LYS A 260 24.433 7.853 -4.623 1.00 49.34 H ATOM 3867 HZ2 LYS A 260 23.190 7.109 -3.834 1.00 49.34 H ATOM 3868 HZ3 LYS A 260 24.746 6.759 -3.432 1.00 49.34 H ATOM 3869 N LEU A 261 28.303 3.443 -2.382 1.00 33.81 N ATOM 3870 CA LEU A 261 27.833 2.610 -1.279 1.00 31.60 C ATOM 3871 C LEU A 261 26.693 3.348 -0.570 1.00 29.63 C ATOM 3872 O LEU A 261 26.902 4.487 -0.160 1.00 29.87 O ATOM 3873 CB LEU A 261 29.019 2.310 -0.339 1.00 29.94 C ATOM 3874 CG LEU A 261 28.707 1.493 0.936 1.00 31.43 C ATOM 3875 CD1 LEU A 261 28.100 0.114 0.637 1.00 27.52 C ATOM 3876 CD2 LEU A 261 29.960 1.351 1.820 1.00 29.62 C ATOM 3877 H LEU A 261 28.470 4.416 -2.158 1.00 33.81 H ATOM 3878 HA LEU A 261 27.465 1.662 -1.659 1.00 31.60 H ATOM 3879 HB3 LEU A 261 29.463 3.253 -0.035 1.00 29.94 H ATOM 3880 HB2 LEU A 261 29.794 1.809 -0.911 1.00 29.94 H ATOM 3881 HG LEU A 261 27.977 2.052 1.518 1.00 31.43 H ATOM 3882 HD11 LEU A 261 28.088 -0.516 1.527 1.00 27.52 H ATOM 3883 HD12 LEU A 261 27.070 0.195 0.288 1.00 27.52 H ATOM 3884 HD13 LEU A 261 28.681 -0.408 -0.118 1.00 27.52 H ATOM 3885 HD21 LEU A 261 30.315 0.320 1.865 1.00 29.62 H ATOM 3886 HD22 LEU A 261 30.791 1.955 1.455 1.00 29.62 H ATOM 3887 HD23 LEU A 261 29.750 1.662 2.843 1.00 29.62 H ATOM 3888 N ASN A 262 25.536 2.685 -0.416 1.00 30.06 N ATOM 3889 CA ASN A 262 24.382 3.200 0.329 1.00 27.76 C ATOM 3890 C ASN A 262 24.290 2.460 1.665 1.00 25.27 C ATOM 3891 O ASN A 262 24.167 1.239 1.685 1.00 25.48 O ATOM 3892 CB ASN A 262 23.073 3.000 -0.463 1.00 28.70 C ATOM 3893 CG ASN A 262 23.064 3.717 -1.813 1.00 33.27 C ATOM 3894 OD1 ASN A 262 23.089 4.945 -1.868 1.00 35.47 O ATOM 3895 ND2 ASN A 262 23.018 2.949 -2.903 1.00 30.78 N ATOM 3896 H ASN A 262 25.441 1.753 -0.799 1.00 30.06 H ATOM 3897 HA ASN A 262 24.491 4.266 0.533 1.00 27.76 H ATOM 3898 HB3 ASN A 262 22.231 3.384 0.114 1.00 28.70 H ATOM 3899 HB2 ASN A 262 22.878 1.940 -0.607 1.00 28.70 H ATOM 3900 HD22 ASN A 262 22.995 3.360 -3.824 1.00 30.78 H ATOM 3901 HD21 ASN A 262 23.005 1.940 -2.812 1.00 30.78 H ATOM 3902 N LEU A 263 24.334 3.219 2.762 1.00 25.22 N ATOM 3903 CA LEU A 263 24.276 2.707 4.124 1.00 25.09 C ATOM 3904 C LEU A 263 22.918 3.140 4.677 1.00 22.26 C ATOM 3905 O LEU A 263 22.766 4.266 5.153 1.00 22.01 O ATOM 3906 CB LEU A 263 25.496 3.239 4.911 1.00 27.62 C ATOM 3907 CG LEU A 263 26.846 2.806 4.287 1.00 30.92 C ATOM 3908 CD1 LEU A 263 28.031 3.570 4.886 1.00 34.54 C ATOM 3909 CD2 LEU A 263 27.074 1.283 4.334 1.00 30.34 C ATOM 3910 H LEU A 263 24.449 4.222 2.678 1.00 25.22 H ATOM 3911 HA LEU A 263 24.313 1.617 4.137 1.00 25.09 H ATOM 3912 HB3 LEU A 263 25.446 2.904 5.948 1.00 27.62 H ATOM 3913 HB2 LEU A 263 25.458 4.327 4.950 1.00 27.62 H ATOM 3914 HG LEU A 263 26.841 3.099 3.238 1.00 30.92 H ATOM 3915 HD11 LEU A 263 28.952 3.354 4.345 1.00 34.54 H ATOM 3916 HD12 LEU A 263 27.874 4.646 4.822 1.00 34.54 H ATOM 3917 HD13 LEU A 263 28.191 3.299 5.928 1.00 34.54 H ATOM 3918 HD21 LEU A 263 28.055 1.027 4.732 1.00 30.34 H ATOM 3919 HD22 LEU A 263 26.334 0.773 4.945 1.00 30.34 H ATOM 3920 HD23 LEU A 263 27.009 0.849 3.337 1.00 30.34 H ATOM 3921 N VAL A 264 21.940 2.242 4.499 1.00 21.33 N ATOM 3922 CA VAL A 264 20.529 2.499 4.732 1.00 21.12 C ATOM 3923 C VAL A 264 20.145 1.974 6.121 1.00 20.78 C ATOM 3924 O VAL A 264 20.395 0.811 6.423 1.00 22.61 O ATOM 3925 CB VAL A 264 19.640 1.807 3.661 1.00 22.88 C ATOM 3926 CG1 VAL A 264 18.133 2.074 3.863 1.00 19.18 C ATOM 3927 CG2 VAL A 264 20.061 2.208 2.236 1.00 19.56 C ATOM 3928 H VAL A 264 22.165 1.325 4.132 1.00 21.33 H ATOM 3929 HA VAL A 264 20.354 3.570 4.673 1.00 21.12 H ATOM 3930 HB VAL A 264 19.789 0.730 3.725 1.00 22.88 H ATOM 3931 HG11 VAL A 264 17.544 1.672 3.041 1.00 19.18 H ATOM 3932 HG12 VAL A 264 17.761 1.613 4.777 1.00 19.18 H ATOM 3933 HG13 VAL A 264 17.925 3.143 3.922 1.00 19.18 H ATOM 3934 HG21 VAL A 264 19.474 1.677 1.491 1.00 19.56 H ATOM 3935 HG22 VAL A 264 19.939 3.276 2.069 1.00 19.56 H ATOM 3936 HG23 VAL A 264 21.104 1.960 2.036 1.00 19.56 H ATOM 3937 N ASP A 265 19.531 2.845 6.926 1.00 21.91 N ATOM 3938 CA ASP A 265 19.002 2.547 8.249 1.00 22.53 C ATOM 3939 C ASP A 265 17.505 2.839 8.163 1.00 21.18 C ATOM 3940 O ASP A 265 17.105 3.999 8.094 1.00 19.87 O ATOM 3941 CB ASP A 265 19.778 3.337 9.328 1.00 23.03 C ATOM 3942 CG ASP A 265 19.279 3.361 10.784 1.00 26.46 C ATOM 3943 OD1 ASP A 265 18.330 2.628 11.137 1.00 25.06 O ATOM 3944 OD2 ASP A 265 19.921 4.108 11.553 1.00 29.68 O1- ATOM 3945 H ASP A 265 19.354 3.784 6.589 1.00 21.91 H ATOM 3946 HA ASP A 265 19.118 1.487 8.475 1.00 22.53 H ATOM 3947 HB3 ASP A 265 19.882 4.365 8.991 1.00 23.03 H ATOM 3948 HB2 ASP A 265 20.793 2.940 9.350 1.00 23.03 H ATOM 3949 N LEU A 266 16.721 1.757 8.122 1.00 19.19 N ATOM 3950 CA LEU A 266 15.273 1.789 7.967 1.00 20.84 C ATOM 3951 C LEU A 266 14.579 2.204 9.268 1.00 20.61 C ATOM 3952 O LEU A 266 15.143 2.039 10.350 1.00 20.90 O ATOM 3953 CB LEU A 266 14.803 0.386 7.531 1.00 17.59 C ATOM 3954 CG LEU A 266 15.381 -0.068 6.173 1.00 21.63 C ATOM 3955 CD1 LEU A 266 15.095 -1.554 5.947 1.00 18.98 C ATOM 3956 CD2 LEU A 266 14.833 0.777 5.013 1.00 19.35 C ATOM 3957 H LEU A 266 17.135 0.839 8.215 1.00 19.19 H ATOM 3958 HA LEU A 266 15.020 2.519 7.196 1.00 20.84 H ATOM 3959 HB3 LEU A 266 13.713 0.353 7.484 1.00 17.59 H ATOM 3960 HB2 LEU A 266 15.084 -0.335 8.301 1.00 17.59 H ATOM 3961 HG LEU A 266 16.466 0.035 6.182 1.00 21.63 H ATOM 3962 HD11 LEU A 266 15.381 -1.883 4.949 1.00 18.98 H ATOM 3963 HD12 LEU A 266 15.647 -2.165 6.661 1.00 18.98 H ATOM 3964 HD13 LEU A 266 14.032 -1.752 6.071 1.00 18.98 H ATOM 3965 HD21 LEU A 266 14.946 0.276 4.052 1.00 19.35 H ATOM 3966 HD22 LEU A 266 13.773 0.980 5.155 1.00 19.35 H ATOM 3967 HD23 LEU A 266 15.349 1.734 4.940 1.00 19.35 H ATOM 3968 N ALA A 267 13.331 2.675 9.129 1.00 21.47 N ATOM 3969 CA ALA A 267 12.390 2.869 10.230 1.00 19.08 C ATOM 3970 C ALA A 267 12.118 1.549 10.960 1.00 19.61 C ATOM 3971 O ALA A 267 12.099 0.499 10.316 1.00 18.68 O ATOM 3972 CB ALA A 267 11.079 3.422 9.666 1.00 18.56 C ATOM 3973 H ALA A 267 12.955 2.799 8.198 1.00 21.47 H ATOM 3974 HA ALA A 267 12.812 3.596 10.924 1.00 19.08 H ATOM 3975 HB1 ALA A 267 10.395 3.692 10.470 1.00 18.56 H ATOM 3976 HB2 ALA A 267 11.258 4.314 9.066 1.00 18.56 H ATOM 3977 HB3 ALA A 267 10.573 2.692 9.033 1.00 18.56 H ATOM 3978 N GLY A 268 11.906 1.640 12.281 1.00 20.90 N ATOM 3979 CA GLY A 268 11.627 0.527 13.183 1.00 21.41 C ATOM 3980 C GLY A 268 10.481 -0.354 12.668 1.00 22.97 C ATOM 3981 O GLY A 268 9.420 0.151 12.303 1.00 21.66 O ATOM 3982 H GLY A 268 11.923 2.560 12.704 1.00 20.90 H ATOM 3983 HA3 GLY A 268 11.344 0.954 14.142 1.00 21.41 H ATOM 3984 HA2 GLY A 268 12.535 -0.057 13.338 1.00 21.41 H ATOM 3985 N SER A 269 10.715 -1.674 12.655 1.00 23.42 N ATOM 3986 CA SER A 269 9.807 -2.677 12.104 1.00 24.42 C ATOM 3987 C SER A 269 8.610 -3.066 12.996 1.00 27.82 C ATOM 3988 O SER A 269 7.819 -3.892 12.540 1.00 27.45 O ATOM 3989 CB SER A 269 10.635 -3.908 11.686 1.00 22.75 C ATOM 3990 OG SER A 269 11.128 -4.632 12.793 1.00 25.27 O ATOM 3991 H SER A 269 11.603 -2.028 12.986 1.00 23.42 H ATOM 3992 HA SER A 269 9.382 -2.263 11.189 1.00 24.42 H ATOM 3993 HB3 SER A 269 11.466 -3.623 11.043 1.00 22.75 H ATOM 3994 HB2 SER A 269 10.007 -4.583 11.110 1.00 22.75 H ATOM 3995 HG SER A 269 11.645 -5.375 12.469 1.00 25.27 H ATOM 3996 N GLU A 270 8.484 -2.509 14.219 1.00 30.78 N ATOM 3997 CA GLU A 270 7.446 -2.890 15.187 1.00 34.86 C ATOM 3998 C GLU A 270 6.014 -2.668 14.677 1.00 37.87 C ATOM 3999 O GLU A 270 5.767 -1.746 13.900 1.00 37.82 O ATOM 4000 CB GLU A 270 7.677 -2.271 16.597 1.00 34.89 C ATOM 4001 CG GLU A 270 7.064 -0.883 16.938 1.00 37.74 C ATOM 4002 CD GLU A 270 7.750 0.331 16.298 1.00 43.02 C ATOM 4003 OE1 GLU A 270 8.632 0.912 16.971 1.00 35.23 O ATOM 4004 OE2 GLU A 270 7.397 0.674 15.149 1.00 47.66 O1- ATOM 4005 H GLU A 270 9.168 -1.834 14.538 1.00 30.78 H ATOM 4006 HA GLU A 270 7.586 -3.959 15.296 1.00 34.86 H ATOM 4007 HB3 GLU A 270 8.734 -2.288 16.849 1.00 34.89 H ATOM 4008 HB2 GLU A 270 7.248 -2.972 17.314 1.00 34.89 H ATOM 4009 HG3 GLU A 270 7.103 -0.757 18.022 1.00 37.74 H ATOM 4010 HG2 GLU A 270 6.000 -0.854 16.705 1.00 37.74 H ATOM 4011 N ASN A 271 5.093 -3.516 15.160 1.00 41.83 N ATOM 4012 CA ASN A 271 3.653 -3.420 14.910 1.00 44.48 C ATOM 4013 C ASN A 271 3.085 -2.097 15.443 1.00 45.67 C ATOM 4014 O ASN A 271 3.433 -1.684 16.551 1.00 46.37 O ATOM 4015 CB ASN A 271 2.931 -4.602 15.597 1.00 47.15 C ATOM 4016 CG ASN A 271 3.222 -5.969 14.971 1.00 50.68 C ATOM 4017 OD1 ASN A 271 3.251 -6.109 13.750 1.00 51.46 O ATOM 4018 ND2 ASN A 271 3.409 -6.993 15.806 1.00 52.35 N ATOM 4019 H ASN A 271 5.382 -4.244 15.803 1.00 41.83 H ATOM 4020 HA ASN A 271 3.521 -3.479 13.828 1.00 44.48 H ATOM 4021 HB3 ASN A 271 1.851 -4.459 15.531 1.00 47.15 H ATOM 4022 HB2 ASN A 271 3.170 -4.622 16.663 1.00 47.15 H ATOM 4023 HD22 ASN A 271 3.582 -7.920 15.447 1.00 52.35 H ATOM 4024 HD21 ASN A 271 3.401 -6.849 16.806 1.00 52.35 H ATOM 4025 N ILE A 272 2.195 -1.486 14.649 1.00 13.83 N ATOM 4026 CA ILE A 272 1.460 -0.288 15.034 1.00 15.42 C ATOM 4027 C ILE A 272 0.055 -0.677 15.526 1.00 16.71 C ATOM 4028 O ILE A 272 -0.660 -1.417 14.847 1.00 17.84 O ATOM 4029 CB ILE A 272 1.359 0.732 13.855 1.00 0.00 C ATOM 4030 CG1 ILE A 272 0.739 2.089 14.265 1.00 0.00 C ATOM 4031 CG2 ILE A 272 0.636 0.199 12.597 1.00 0.00 C ATOM 4032 CD1 ILE A 272 1.489 2.818 15.390 1.00 0.00 C ATOM 4033 HB ILE A 272 2.385 0.939 13.546 1.00 0.00 H ATOM 4034 HG12 ILE A 272 0.710 2.745 13.399 1.00 0.00 H ATOM 4035 HG13 ILE A 272 -0.305 1.958 14.546 1.00 0.00 H ATOM 4036 HG21 ILE A 272 0.745 0.894 11.765 1.00 0.00 H ATOM 4037 HG22 ILE A 272 1.045 -0.756 12.271 1.00 0.00 H ATOM 4038 HG23 ILE A 272 -0.434 0.071 12.759 1.00 0.00 H ATOM 4039 HD11 ILE A 272 1.318 3.893 15.335 1.00 0.00 H ATOM 4040 HD12 ILE A 272 1.152 2.483 16.371 1.00 0.00 H ATOM 4041 HD13 ILE A 272 2.565 2.652 15.328 1.00 0.00 H ATOM 4042 H ILE A 272 1.951 -1.893 13.758 1.00 13.83 H ATOM 4043 HA ILE A 272 1.988 0.206 15.852 1.00 15.42 H ATOM 4044 N GLY A 273 -0.321 -0.123 16.688 1.00 17.08 N ATOM 4045 CA GLY A 273 -1.707 -0.053 17.131 1.00 15.97 C ATOM 4046 C GLY A 273 -2.224 1.274 16.576 1.00 17.17 C ATOM 4047 O GLY A 273 -1.744 2.333 16.984 1.00 15.94 O ATOM 4048 HA3 GLY A 273 -1.743 -0.038 18.221 1.00 15.97 H ATOM 4049 H GLY A 273 0.342 0.445 17.196 1.00 17.08 H ATOM 4050 HA2 GLY A 273 -2.303 -0.901 16.788 1.00 15.97 H ATOM 4051 N ARG A 274 -3.170 1.206 15.626 1.00 14.58 N ATOM 4052 CA ARG A 274 -3.710 2.361 14.904 1.00 15.78 C ATOM 4053 C ARG A 274 -4.465 3.351 15.808 1.00 16.40 C ATOM 4054 O ARG A 274 -4.947 2.978 16.879 1.00 14.34 O ATOM 4055 CB ARG A 274 -4.683 1.882 13.807 1.00 0.00 C ATOM 4056 CG ARG A 274 -4.110 0.939 12.736 1.00 0.00 C ATOM 4057 CD ARG A 274 -5.173 0.730 11.646 1.00 0.00 C ATOM 4058 NE ARG A 274 -4.850 -0.312 10.660 1.00 0.00 N ATOM 4059 CZ ARG A 274 -5.648 -0.682 9.636 1.00 0.00 C ATOM 4060 NH1 ARG A 274 -6.825 -0.080 9.392 1.00 0.00 N ATOM 4061 NH2 ARG A 274 -5.258 -1.682 8.836 1.00 0.00 N1+ ATOM 4062 HB2 ARG A 274 -5.538 1.392 14.279 1.00 0.00 H ATOM 4063 HB3 ARG A 274 -5.095 2.753 13.294 1.00 0.00 H ATOM 4064 HG2 ARG A 274 -3.252 1.449 12.296 1.00 0.00 H ATOM 4065 HG3 ARG A 274 -3.741 -0.004 13.141 1.00 0.00 H ATOM 4066 HD2 ARG A 274 -6.158 0.577 12.082 1.00 0.00 H ATOM 4067 HD3 ARG A 274 -5.223 1.648 11.059 1.00 0.00 H ATOM 4068 HE ARG A 274 -3.971 -0.791 10.791 1.00 0.00 H ATOM 4069 HH12 ARG A 274 -7.416 -0.376 8.629 1.00 0.00 H ATOM 4070 HH11 ARG A 274 -7.136 0.672 9.995 1.00 0.00 H ATOM 4071 HH22 ARG A 274 -5.843 -1.982 8.070 1.00 0.00 H ATOM 4072 HH21 ARG A 274 -4.378 -2.151 8.997 1.00 0.00 H ATOM 4073 H ARG A 274 -3.523 0.303 15.343 1.00 14.58 H ATOM 4074 HA ARG A 274 -2.875 2.886 14.435 1.00 15.78 H ATOM 4075 N SER A 275 -4.634 4.577 15.287 1.00 14.55 N ATOM 4076 CA SER A 275 -5.642 5.542 15.722 1.00 16.42 C ATOM 4077 C SER A 275 -7.041 5.056 15.281 1.00 17.16 C ATOM 4078 O SER A 275 -7.532 5.453 14.228 1.00 16.93 O ATOM 4079 CB SER A 275 -5.237 6.937 15.190 1.00 0.00 C ATOM 4080 OG SER A 275 -5.114 6.983 13.779 1.00 0.00 O ATOM 4081 HB2 SER A 275 -5.971 7.682 15.497 1.00 0.00 H ATOM 4082 HB3 SER A 275 -4.285 7.241 15.628 1.00 0.00 H ATOM 4083 HG SER A 275 -4.912 7.884 13.516 1.00 0.00 H ATOM 4084 H SER A 275 -4.195 4.801 14.406 1.00 14.55 H ATOM 4085 HA SER A 275 -5.633 5.592 16.813 1.00 16.42 H ATOM 4086 N GLY A 276 -7.623 4.142 16.081 1.00 15.23 N ATOM 4087 CA GLY A 276 -8.789 3.319 15.736 1.00 16.84 C ATOM 4088 C GLY A 276 -10.083 4.105 15.468 1.00 16.88 C ATOM 4089 O GLY A 276 -10.978 3.576 14.811 1.00 16.65 O ATOM 4090 HA3 GLY A 276 -8.971 2.619 16.551 1.00 16.84 H ATOM 4091 H GLY A 276 -7.128 3.868 16.918 1.00 15.23 H ATOM 4092 HA2 GLY A 276 -8.544 2.721 14.859 1.00 16.84 H ATOM 4093 N ALA A 277 -10.172 5.363 15.934 0.50 17.32 N ATOM 4094 CA ALA A 277 -11.259 6.295 15.628 0.50 21.27 C ATOM 4095 C ALA A 277 -11.269 6.770 14.161 0.50 23.22 C ATOM 4096 O ALA A 277 -12.330 7.156 13.670 0.50 25.56 O ATOM 4097 CB ALA A 277 -11.154 7.497 16.578 1.00 0.00 C ATOM 4098 HB1 ALA A 277 -10.208 8.027 16.450 1.00 0.00 H ATOM 4099 HB2 ALA A 277 -11.960 8.211 16.405 1.00 0.00 H ATOM 4100 HB3 ALA A 277 -11.219 7.180 17.619 1.00 0.00 H ATOM 4101 H ALA A 277 -9.405 5.739 16.473 1.00 17.32 H ATOM 4102 HA ALA A 277 -12.207 5.789 15.820 1.00 21.27 H ATOM 4103 N VAL A 278 -10.101 6.733 13.496 1.00 20.27 N ATOM 4104 CA VAL A 278 -9.903 7.185 12.120 1.00 20.59 C ATOM 4105 C VAL A 278 -10.267 6.104 11.081 1.00 19.48 C ATOM 4106 O VAL A 278 -10.578 6.480 9.959 1.00 18.81 O ATOM 4107 CB VAL A 278 -8.430 7.644 11.878 1.00 0.00 C ATOM 4108 CG1 VAL A 278 -8.113 8.110 10.438 1.00 0.00 C ATOM 4109 CG2 VAL A 278 -8.026 8.757 12.863 1.00 0.00 C ATOM 4110 HB VAL A 278 -7.772 6.797 12.070 1.00 0.00 H ATOM 4111 HG11 VAL A 278 -7.115 8.546 10.376 1.00 0.00 H ATOM 4112 HG12 VAL A 278 -8.127 7.286 9.725 1.00 0.00 H ATOM 4113 HG13 VAL A 278 -8.823 8.865 10.099 1.00 0.00 H ATOM 4114 HG21 VAL A 278 -7.001 9.086 12.691 1.00 0.00 H ATOM 4115 HG22 VAL A 278 -8.675 9.628 12.764 1.00 0.00 H ATOM 4116 HG23 VAL A 278 -8.078 8.418 13.898 1.00 0.00 H ATOM 4117 H VAL A 278 -9.275 6.379 13.962 1.00 20.27 H ATOM 4118 HA VAL A 278 -10.555 8.042 11.939 1.00 20.59 H ATOM 4119 N ASP A 279 -10.264 4.806 11.440 1.00 16.88 N ATOM 4120 CA ASP A 279 -10.481 3.666 10.523 1.00 15.78 C ATOM 4121 C ASP A 279 -11.818 3.643 9.743 1.00 14.21 C ATOM 4122 O ASP A 279 -11.919 2.900 8.766 1.00 16.58 O ATOM 4123 CB ASP A 279 -10.245 2.299 11.216 1.00 0.00 C ATOM 4124 CG ASP A 279 -8.841 2.072 11.805 1.00 0.00 C ATOM 4125 OD1 ASP A 279 -7.871 2.700 11.324 1.00 0.00 O ATOM 4126 OD2 ASP A 279 -8.731 1.143 12.633 1.00 0.00 O1- ATOM 4127 HB2 ASP A 279 -10.970 2.182 12.023 1.00 0.00 H ATOM 4128 HB3 ASP A 279 -10.425 1.486 10.511 1.00 0.00 H ATOM 4129 H ASP A 279 -10.019 4.563 12.390 1.00 16.88 H ATOM 4130 HA ASP A 279 -9.725 3.773 9.743 1.00 15.78 H ATOM 4131 N LYS A 280 -12.794 4.471 10.148 1.00 16.18 N ATOM 4132 CA LYS A 280 -14.050 4.729 9.437 1.00 16.76 C ATOM 4133 C LYS A 280 -13.888 5.639 8.192 1.00 17.04 C ATOM 4134 O LYS A 280 -14.762 5.619 7.326 1.00 18.73 O ATOM 4135 CB LYS A 280 -15.038 5.302 10.477 1.00 0.00 C ATOM 4136 CG LYS A 280 -16.442 5.659 9.960 1.00 0.00 C ATOM 4137 CD LYS A 280 -17.382 6.064 11.102 1.00 0.00 C ATOM 4138 CE LYS A 280 -18.753 6.540 10.598 1.00 0.00 C ATOM 4139 NZ LYS A 280 -19.634 6.933 11.711 1.00 0.00 N1+ ATOM 4140 HB2 LYS A 280 -15.144 4.572 11.282 1.00 0.00 H ATOM 4141 HB3 LYS A 280 -14.601 6.190 10.937 1.00 0.00 H ATOM 4142 HG2 LYS A 280 -16.378 6.486 9.251 1.00 0.00 H ATOM 4143 HG3 LYS A 280 -16.862 4.813 9.415 1.00 0.00 H ATOM 4144 HD2 LYS A 280 -17.511 5.214 11.775 1.00 0.00 H ATOM 4145 HD3 LYS A 280 -16.910 6.852 11.692 1.00 0.00 H ATOM 4146 HE2 LYS A 280 -18.633 7.395 9.930 1.00 0.00 H ATOM 4147 HE3 LYS A 280 -19.240 5.750 10.025 1.00 0.00 H ATOM 4148 HZ1 LYS A 280 -19.206 7.684 12.233 1.00 0.00 H ATOM 4149 HZ2 LYS A 280 -20.523 7.243 11.345 1.00 0.00 H ATOM 4150 HZ3 LYS A 280 -19.781 6.141 12.321 1.00 0.00 H ATOM 4151 H LYS A 280 -12.628 5.043 10.963 1.00 16.18 H ATOM 4152 HA LYS A 280 -14.444 3.773 9.089 1.00 16.76 H ATOM 4153 N ARG A 281 -12.786 6.411 8.122 1.00 17.25 N ATOM 4154 CA ARG A 281 -12.413 7.331 7.043 1.00 16.47 C ATOM 4155 C ARG A 281 -12.039 6.565 5.763 1.00 18.22 C ATOM 4156 O ARG A 281 -10.873 6.214 5.576 1.00 17.69 O ATOM 4157 CB ARG A 281 -11.258 8.226 7.560 1.00 0.00 C ATOM 4158 CG ARG A 281 -10.642 9.271 6.615 1.00 0.00 C ATOM 4159 CD ARG A 281 -11.616 10.269 5.976 1.00 0.00 C ATOM 4160 NE ARG A 281 -10.845 11.345 5.330 1.00 0.00 N ATOM 4161 CZ ARG A 281 -11.113 12.659 5.250 1.00 0.00 C ATOM 4162 NH1 ARG A 281 -12.265 13.188 5.688 1.00 0.00 N ATOM 4163 NH2 ARG A 281 -10.180 13.461 4.721 1.00 0.00 N1+ ATOM 4164 HB2 ARG A 281 -11.576 8.729 8.474 1.00 0.00 H ATOM 4165 HB3 ARG A 281 -10.425 7.585 7.842 1.00 0.00 H ATOM 4166 HG2 ARG A 281 -9.812 9.780 7.108 1.00 0.00 H ATOM 4167 HG3 ARG A 281 -10.181 8.713 5.801 1.00 0.00 H ATOM 4168 HD2 ARG A 281 -12.137 9.774 5.156 1.00 0.00 H ATOM 4169 HD3 ARG A 281 -12.375 10.609 6.680 1.00 0.00 H ATOM 4170 HE ARG A 281 -9.934 11.057 4.992 1.00 0.00 H ATOM 4171 HH12 ARG A 281 -12.434 14.181 5.625 1.00 0.00 H ATOM 4172 HH11 ARG A 281 -12.968 12.589 6.094 1.00 0.00 H ATOM 4173 HH22 ARG A 281 -10.333 14.455 4.645 1.00 0.00 H ATOM 4174 HH21 ARG A 281 -9.286 13.073 4.448 1.00 0.00 H ATOM 4175 H ARG A 281 -12.107 6.343 8.871 1.00 17.25 H ATOM 4176 HA ARG A 281 -13.272 7.970 6.829 1.00 16.47 H ATOM 4177 N ALA A 282 -13.044 6.336 4.902 1.00 19.52 N ATOM 4178 CA ALA A 282 -12.904 5.703 3.592 1.00 19.44 C ATOM 4179 C ALA A 282 -12.391 6.711 2.545 1.00 21.06 C ATOM 4180 O ALA A 282 -13.111 7.061 1.610 1.00 20.72 O ATOM 4181 CB ALA A 282 -14.249 5.064 3.207 1.00 0.00 C ATOM 4182 HB1 ALA A 282 -14.186 4.560 2.241 1.00 0.00 H ATOM 4183 HB2 ALA A 282 -14.552 4.318 3.943 1.00 0.00 H ATOM 4184 HB3 ALA A 282 -15.045 5.807 3.144 1.00 0.00 H ATOM 4185 H ALA A 282 -13.979 6.626 5.152 1.00 19.52 H ATOM 4186 HA ALA A 282 -12.169 4.899 3.663 1.00 19.44 H ATOM 4187 N ARG A 283 -11.140 7.151 2.742 1.00 20.98 N ATOM 4188 CA ARG A 283 -10.361 7.987 1.834 1.00 20.56 C ATOM 4189 C ARG A 283 -8.867 7.890 2.193 1.00 19.71 C ATOM 4190 O ARG A 283 -8.040 7.843 1.282 1.00 21.33 O ATOM 4191 CB ARG A 283 -10.856 9.453 1.813 1.00 0.00 C ATOM 4192 CG ARG A 283 -10.199 10.274 0.683 1.00 0.00 C ATOM 4193 CD ARG A 283 -9.815 11.709 1.078 1.00 0.00 C ATOM 4194 NE ARG A 283 -8.888 12.297 0.094 1.00 0.00 N ATOM 4195 CZ ARG A 283 -7.556 12.092 0.021 1.00 0.00 C ATOM 4196 NH1 ARG A 283 -6.885 11.364 0.927 1.00 0.00 N ATOM 4197 NH2 ARG A 283 -6.874 12.631 -0.997 1.00 0.00 N1+ ATOM 4198 HB2 ARG A 283 -11.939 9.492 1.689 1.00 0.00 H ATOM 4199 HB3 ARG A 283 -10.655 9.907 2.783 1.00 0.00 H ATOM 4200 HG2 ARG A 283 -9.369 9.760 0.198 1.00 0.00 H ATOM 4201 HG3 ARG A 283 -10.960 10.342 -0.096 1.00 0.00 H ATOM 4202 HD2 ARG A 283 -10.709 12.329 0.998 1.00 0.00 H ATOM 4203 HD3 ARG A 283 -9.478 11.805 2.108 1.00 0.00 H ATOM 4204 HE ARG A 283 -9.324 12.843 -0.635 1.00 0.00 H ATOM 4205 HH12 ARG A 283 -5.892 11.211 0.838 1.00 0.00 H ATOM 4206 HH11 ARG A 283 -7.368 10.987 1.736 1.00 0.00 H ATOM 4207 HH22 ARG A 283 -5.877 12.491 -1.074 1.00 0.00 H ATOM 4208 HH21 ARG A 283 -7.348 13.184 -1.696 1.00 0.00 H ATOM 4209 H ARG A 283 -10.636 6.795 3.544 1.00 20.98 H ATOM 4210 HA ARG A 283 -10.484 7.566 0.833 1.00 20.56 H ATOM 4211 N GLU A 284 -8.548 7.823 3.499 1.00 21.43 N ATOM 4212 CA GLU A 284 -7.213 7.479 3.995 1.00 20.61 C ATOM 4213 C GLU A 284 -7.036 5.952 4.037 1.00 20.80 C ATOM 4214 O GLU A 284 -8.017 5.212 4.134 1.00 19.82 O ATOM 4215 CB GLU A 284 -6.952 8.120 5.382 1.00 0.00 C ATOM 4216 CG GLU A 284 -6.329 9.535 5.334 1.00 0.00 C ATOM 4217 CD GLU A 284 -7.333 10.675 5.127 1.00 0.00 C ATOM 4218 OE1 GLU A 284 -7.797 10.851 3.979 1.00 0.00 O ATOM 4219 OE2 GLU A 284 -7.623 11.375 6.120 1.00 0.00 O1- ATOM 4220 HB2 GLU A 284 -7.878 8.149 5.958 1.00 0.00 H ATOM 4221 HB3 GLU A 284 -6.286 7.484 5.967 1.00 0.00 H ATOM 4222 HG2 GLU A 284 -5.798 9.707 6.272 1.00 0.00 H ATOM 4223 HG3 GLU A 284 -5.561 9.586 4.560 1.00 0.00 H ATOM 4224 H GLU A 284 -9.273 7.884 4.198 1.00 21.43 H ATOM 4225 HA GLU A 284 -6.466 7.864 3.299 1.00 20.61 H ATOM 4226 N ALA A 285 -5.769 5.522 3.946 1.00 20.97 N ATOM 4227 CA ALA A 285 -5.365 4.119 3.890 1.00 20.77 C ATOM 4228 C ALA A 285 -5.089 3.530 5.282 1.00 20.48 C ATOM 4229 O ALA A 285 -4.831 4.271 6.233 1.00 20.59 O ATOM 4230 CB ALA A 285 -4.108 4.031 3.009 1.00 0.00 C ATOM 4231 HB1 ALA A 285 -4.330 4.338 1.986 1.00 0.00 H ATOM 4232 HB2 ALA A 285 -3.312 4.677 3.378 1.00 0.00 H ATOM 4233 HB3 ALA A 285 -3.717 3.014 2.964 1.00 0.00 H ATOM 4234 H ALA A 285 -5.020 6.196 3.896 1.00 20.97 H ATOM 4235 HA ALA A 285 -6.155 3.530 3.419 1.00 20.77 H ATOM 4236 N GLY A 286 -5.105 2.187 5.350 1.00 19.09 N ATOM 4237 CA GLY A 286 -4.703 1.409 6.521 1.00 17.64 C ATOM 4238 C GLY A 286 -3.176 1.280 6.506 1.00 16.69 C ATOM 4239 O GLY A 286 -2.641 0.267 6.055 1.00 15.61 O ATOM 4240 HA3 GLY A 286 -5.159 0.420 6.467 1.00 17.64 H ATOM 4241 H GLY A 286 -5.331 1.662 4.519 1.00 19.09 H ATOM 4242 HA2 GLY A 286 -5.044 1.874 7.447 1.00 17.64 H ATOM 4243 N ASN A 287 -2.496 2.330 6.985 1.00 18.01 N ATOM 4244 CA ASN A 287 -1.044 2.496 6.983 1.00 16.78 C ATOM 4245 C ASN A 287 -0.629 3.506 8.069 1.00 17.94 C ATOM 4246 O ASN A 287 -1.492 4.106 8.711 1.00 15.20 O ATOM 4247 CB ASN A 287 -0.543 2.912 5.561 1.00 0.00 C ATOM 4248 CG ASN A 287 -0.861 4.337 5.074 1.00 0.00 C ATOM 4249 OD1 ASN A 287 -1.742 5.020 5.591 1.00 0.00 O ATOM 4250 ND2 ASN A 287 -0.134 4.792 4.051 1.00 0.00 N ATOM 4251 HB2 ASN A 287 0.542 2.850 5.546 1.00 0.00 H ATOM 4252 HB3 ASN A 287 -0.894 2.201 4.813 1.00 0.00 H ATOM 4253 HD22 ASN A 287 -0.300 5.721 3.691 1.00 0.00 H ATOM 4254 HD21 ASN A 287 0.570 4.212 3.614 1.00 0.00 H ATOM 4255 H ASN A 287 -3.011 3.130 7.329 1.00 18.01 H ATOM 4256 HA ASN A 287 -0.566 1.556 7.265 1.00 16.78 H ATOM 4257 N ILE A 288 0.688 3.744 8.165 1.00 39.42 N ATOM 4258 CA ILE A 288 1.245 5.043 8.559 1.00 36.53 C ATOM 4259 C ILE A 288 2.668 5.256 8.016 1.00 31.50 C ATOM 4260 O ILE A 288 3.021 6.407 7.762 1.00 34.96 O ATOM 4261 CB ILE A 288 1.211 5.423 10.079 1.00 39.81 C ATOM 4262 CG1 ILE A 288 1.167 4.244 11.074 1.00 41.18 C ATOM 4263 CG2 ILE A 288 0.086 6.432 10.379 1.00 39.92 C ATOM 4264 CD1 ILE A 288 2.422 3.361 11.081 1.00 43.90 C ATOM 4265 HA ILE A 288 0.646 5.780 8.018 1.00 36.53 H ATOM 4266 HB ILE A 288 2.123 5.971 10.324 1.00 39.81 H ATOM 4267 HG13 ILE A 288 0.281 3.633 10.901 1.00 41.18 H ATOM 4268 HG12 ILE A 288 1.044 4.649 12.079 1.00 41.18 H ATOM 4269 HG21 ILE A 288 0.153 6.797 11.404 1.00 39.92 H ATOM 4270 HG22 ILE A 288 0.150 7.302 9.725 1.00 39.92 H ATOM 4271 HG23 ILE A 288 -0.903 5.995 10.257 1.00 39.92 H ATOM 4272 HD11 ILE A 288 2.221 2.410 10.593 1.00 43.90 H ATOM 4273 HD12 ILE A 288 3.265 3.831 10.576 1.00 43.90 H ATOM 4274 HD13 ILE A 288 2.741 3.143 12.100 1.00 43.90 H ATOM 4275 H ILE A 288 1.322 3.154 7.647 1.00 39.42 H ATOM 4276 N ASN A 289 3.438 4.173 7.812 1.00 28.46 N ATOM 4277 CA ASN A 289 4.759 4.223 7.193 1.00 23.85 C ATOM 4278 C ASN A 289 4.670 3.513 5.837 1.00 21.26 C ATOM 4279 O ASN A 289 4.866 2.300 5.758 1.00 18.44 O ATOM 4280 CB ASN A 289 5.815 3.594 8.132 1.00 23.77 C ATOM 4281 CG ASN A 289 7.244 4.043 7.803 1.00 25.10 C ATOM 4282 OD1 ASN A 289 7.622 4.158 6.638 1.00 25.42 O ATOM 4283 ND2 ASN A 289 8.049 4.290 8.836 1.00 14.33 N ATOM 4284 H ASN A 289 3.106 3.252 8.066 1.00 28.46 H ATOM 4285 HA ASN A 289 5.078 5.242 6.963 1.00 23.85 H ATOM 4286 HB3 ASN A 289 5.754 2.506 8.161 1.00 23.77 H ATOM 4287 HB2 ASN A 289 5.605 3.925 9.151 1.00 23.77 H ATOM 4288 HD22 ASN A 289 8.997 4.605 8.686 1.00 14.33 H ATOM 4289 HD21 ASN A 289 7.720 4.166 9.783 1.00 14.33 H ATOM 4290 N GLN A 290 4.359 4.298 4.794 1.00 21.33 N ATOM 4291 CA GLN A 290 4.189 3.826 3.424 1.00 21.12 C ATOM 4292 C GLN A 290 5.474 3.227 2.823 1.00 19.80 C ATOM 4293 O GLN A 290 5.379 2.219 2.126 1.00 17.84 O ATOM 4294 CB GLN A 290 3.600 4.974 2.574 1.00 22.69 C ATOM 4295 CG GLN A 290 3.310 4.652 1.092 1.00 21.91 C ATOM 4296 CD GLN A 290 2.296 3.518 0.906 1.00 24.64 C ATOM 4297 OE1 GLN A 290 1.446 3.284 1.764 1.00 22.56 O ATOM 4298 NE2 GLN A 290 2.362 2.823 -0.229 1.00 26.54 N ATOM 4299 H GLN A 290 4.231 5.292 4.940 1.00 21.33 H ATOM 4300 HA GLN A 290 3.454 3.020 3.471 1.00 21.12 H ATOM 4301 HB3 GLN A 290 4.270 5.828 2.626 1.00 22.69 H ATOM 4302 HB2 GLN A 290 2.676 5.318 3.041 1.00 22.69 H ATOM 4303 HG3 GLN A 290 4.236 4.407 0.570 1.00 21.91 H ATOM 4304 HG2 GLN A 290 2.916 5.541 0.600 1.00 21.91 H ATOM 4305 HE22 GLN A 290 1.714 2.070 -0.411 1.00 26.54 H ATOM 4306 HE21 GLN A 290 3.058 3.058 -0.927 1.00 26.54 H ATOM 4307 N SER A 291 6.640 3.814 3.142 1.00 19.05 N ATOM 4308 CA SER A 291 7.958 3.328 2.729 1.00 20.94 C ATOM 4309 C SER A 291 8.326 1.947 3.288 1.00 20.92 C ATOM 4310 O SER A 291 8.857 1.126 2.540 1.00 21.32 O ATOM 4311 CB SER A 291 9.036 4.383 3.048 1.00 20.43 C ATOM 4312 OG SER A 291 9.212 5.251 1.948 1.00 20.74 O ATOM 4313 H SER A 291 6.632 4.656 3.702 1.00 19.05 H ATOM 4314 HA SER A 291 7.932 3.178 1.655 1.00 20.94 H ATOM 4315 HB3 SER A 291 9.999 3.917 3.252 1.00 20.43 H ATOM 4316 HB2 SER A 291 8.778 4.964 3.934 1.00 20.43 H ATOM 4317 HG SER A 291 8.467 5.867 1.940 1.00 20.74 H ATOM 4318 N LEU A 292 8.008 1.704 4.571 1.00 19.79 N ATOM 4319 CA LEU A 292 8.260 0.428 5.240 1.00 20.51 C ATOM 4320 C LEU A 292 7.312 -0.687 4.760 1.00 21.92 C ATOM 4321 O LEU A 292 7.773 -1.810 4.557 1.00 19.80 O ATOM 4322 CB LEU A 292 8.196 0.637 6.767 1.00 21.65 C ATOM 4323 CG LEU A 292 8.647 -0.567 7.624 1.00 25.71 C ATOM 4324 CD1 LEU A 292 10.086 -1.034 7.309 1.00 23.44 C ATOM 4325 CD2 LEU A 292 8.463 -0.257 9.121 1.00 25.41 C ATOM 4326 H LEU A 292 7.554 2.420 5.121 1.00 19.79 H ATOM 4327 HA LEU A 292 9.276 0.128 4.976 1.00 20.51 H ATOM 4328 HB3 LEU A 292 7.175 0.907 7.039 1.00 21.65 H ATOM 4329 HB2 LEU A 292 8.807 1.498 7.038 1.00 21.65 H ATOM 4330 HG LEU A 292 7.981 -1.402 7.403 1.00 25.71 H ATOM 4331 HD11 LEU A 292 10.645 -1.305 8.205 1.00 23.44 H ATOM 4332 HD12 LEU A 292 10.069 -1.916 6.668 1.00 23.44 H ATOM 4333 HD13 LEU A 292 10.667 -0.271 6.793 1.00 23.44 H ATOM 4334 HD21 LEU A 292 7.907 -1.056 9.612 1.00 25.41 H ATOM 4335 HD22 LEU A 292 9.414 -0.151 9.641 1.00 25.41 H ATOM 4336 HD23 LEU A 292 7.912 0.669 9.286 1.00 25.41 H ATOM 4337 N LEU A 293 6.025 -0.350 4.553 1.00 20.92 N ATOM 4338 CA LEU A 293 5.007 -1.251 4.004 1.00 22.29 C ATOM 4339 C LEU A 293 5.330 -1.695 2.573 1.00 22.16 C ATOM 4340 O LEU A 293 5.236 -2.887 2.282 1.00 23.04 O ATOM 4341 CB LEU A 293 3.624 -0.569 4.031 1.00 21.25 C ATOM 4342 CG LEU A 293 3.002 -0.458 5.436 1.00 24.69 C ATOM 4343 CD1 LEU A 293 1.803 0.504 5.422 1.00 21.82 C ATOM 4344 CD2 LEU A 293 2.644 -1.833 6.037 1.00 24.44 C ATOM 4345 H LEU A 293 5.722 0.595 4.752 1.00 20.92 H ATOM 4346 HA LEU A 293 4.983 -2.148 4.625 1.00 22.29 H ATOM 4347 HB3 LEU A 293 2.923 -1.109 3.393 1.00 21.25 H ATOM 4348 HB2 LEU A 293 3.719 0.424 3.588 1.00 21.25 H ATOM 4349 HG LEU A 293 3.754 -0.014 6.087 1.00 24.69 H ATOM 4350 HD11 LEU A 293 1.941 1.272 6.182 1.00 21.82 H ATOM 4351 HD12 LEU A 293 1.690 1.012 4.464 1.00 21.82 H ATOM 4352 HD13 LEU A 293 0.854 0.008 5.627 1.00 21.82 H ATOM 4353 HD21 LEU A 293 1.641 -1.863 6.462 1.00 24.44 H ATOM 4354 HD22 LEU A 293 2.699 -2.629 5.294 1.00 24.44 H ATOM 4355 HD23 LEU A 293 3.335 -2.092 6.839 1.00 24.44 H ATOM 4356 N THR A 294 5.724 -0.734 1.721 1.00 22.88 N ATOM 4357 CA THR A 294 6.076 -0.982 0.326 1.00 21.29 C ATOM 4358 C THR A 294 7.383 -1.775 0.168 1.00 22.41 C ATOM 4359 O THR A 294 7.451 -2.590 -0.746 1.00 21.52 O ATOM 4360 CB THR A 294 6.203 0.323 -0.492 1.00 20.03 C ATOM 4361 OG1 THR A 294 5.003 1.058 -0.389 1.00 16.51 O ATOM 4362 CG2 THR A 294 6.453 0.118 -1.993 1.00 20.26 C ATOM 4363 H THR A 294 5.782 0.225 2.038 1.00 22.88 H ATOM 4364 HA THR A 294 5.275 -1.577 -0.114 1.00 21.29 H ATOM 4365 HB THR A 294 7.003 0.929 -0.067 1.00 20.03 H ATOM 4366 HG1 THR A 294 4.942 1.413 0.505 1.00 16.51 H ATOM 4367 HG21 THR A 294 6.440 1.066 -2.530 1.00 20.26 H ATOM 4368 HG22 THR A 294 7.416 -0.345 -2.197 1.00 20.26 H ATOM 4369 HG23 THR A 294 5.687 -0.524 -2.427 1.00 20.26 H ATOM 4370 N LEU A 295 8.366 -1.583 1.069 1.00 23.24 N ATOM 4371 CA LEU A 295 9.595 -2.382 1.122 1.00 22.73 C ATOM 4372 C LEU A 295 9.312 -3.875 1.365 1.00 22.80 C ATOM 4373 O LEU A 295 9.913 -4.710 0.692 1.00 22.35 O ATOM 4374 CB LEU A 295 10.562 -1.789 2.174 1.00 22.23 C ATOM 4375 CG LEU A 295 11.905 -2.541 2.346 1.00 25.11 C ATOM 4376 CD1 LEU A 295 12.750 -2.545 1.057 1.00 20.75 C ATOM 4377 CD2 LEU A 295 12.686 -2.005 3.558 1.00 21.13 C ATOM 4378 H LEU A 295 8.254 -0.885 1.793 1.00 23.24 H ATOM 4379 HA LEU A 295 10.072 -2.306 0.145 1.00 22.73 H ATOM 4380 HB3 LEU A 295 10.050 -1.767 3.137 1.00 22.23 H ATOM 4381 HB2 LEU A 295 10.769 -0.748 1.924 1.00 22.23 H ATOM 4382 HG LEU A 295 11.692 -3.582 2.579 1.00 25.11 H ATOM 4383 HD11 LEU A 295 13.813 -2.393 1.245 1.00 20.75 H ATOM 4384 HD12 LEU A 295 12.653 -3.502 0.543 1.00 20.75 H ATOM 4385 HD13 LEU A 295 12.433 -1.767 0.364 1.00 20.75 H ATOM 4386 HD21 LEU A 295 12.902 -2.811 4.260 1.00 21.13 H ATOM 4387 HD22 LEU A 295 13.636 -1.555 3.274 1.00 21.13 H ATOM 4388 HD23 LEU A 295 12.129 -1.243 4.105 1.00 21.13 H ATOM 4389 N GLY A 296 8.369 -4.172 2.276 1.00 23.61 N ATOM 4390 CA GLY A 296 7.920 -5.530 2.575 1.00 22.93 C ATOM 4391 C GLY A 296 7.180 -6.155 1.384 1.00 24.51 C ATOM 4392 O GLY A 296 7.392 -7.331 1.104 1.00 24.67 O ATOM 4393 H GLY A 296 7.924 -3.421 2.787 1.00 23.61 H ATOM 4394 HA3 GLY A 296 7.254 -5.502 3.437 1.00 22.93 H ATOM 4395 HA2 GLY A 296 8.774 -6.153 2.844 1.00 22.93 H ATOM 4396 N ARG A 297 6.356 -5.370 0.667 1.00 23.60 N ATOM 4397 CA ARG A 297 5.608 -5.798 -0.522 1.00 23.93 C ATOM 4398 C ARG A 297 6.494 -5.977 -1.768 1.00 23.58 C ATOM 4399 O ARG A 297 6.197 -6.857 -2.573 1.00 23.29 O ATOM 4400 CB ARG A 297 4.473 -4.797 -0.798 1.00 24.98 C ATOM 4401 CG ARG A 297 3.398 -4.782 0.303 1.00 23.29 C ATOM 4402 CD ARG A 297 2.517 -3.531 0.221 1.00 25.05 C ATOM 4403 NE ARG A 297 1.533 -3.471 1.316 1.00 23.01 N ATOM 4404 CZ ARG A 297 0.821 -2.392 1.694 1.00 22.41 C ATOM 4405 NH1 ARG A 297 0.936 -1.208 1.076 1.00 24.72 N ATOM 4406 NH2 ARG A 297 -0.030 -2.499 2.721 1.00 19.41 N1+ ATOM 4407 H ARG A 297 6.227 -4.408 0.949 1.00 23.60 H ATOM 4408 HA ARG A 297 5.152 -6.765 -0.306 1.00 23.93 H ATOM 4409 HB3 ARG A 297 3.985 -5.040 -1.743 1.00 24.98 H ATOM 4410 HB2 ARG A 297 4.898 -3.801 -0.929 1.00 24.98 H ATOM 4411 HG3 ARG A 297 3.835 -4.865 1.298 1.00 23.29 H ATOM 4412 HG2 ARG A 297 2.780 -5.672 0.179 1.00 23.29 H ATOM 4413 HD3 ARG A 297 1.963 -3.529 -0.718 1.00 25.05 H ATOM 4414 HD2 ARG A 297 3.150 -2.646 0.230 1.00 25.05 H ATOM 4415 HE ARG A 297 1.391 -4.336 1.817 1.00 23.01 H ATOM 4416 HH12 ARG A 297 0.377 -0.413 1.363 1.00 24.72 H ATOM 4417 HH11 ARG A 297 1.571 -1.105 0.292 1.00 24.72 H ATOM 4418 HH22 ARG A 297 -0.572 -1.699 3.017 1.00 19.41 H ATOM 4419 HH21 ARG A 297 -0.142 -3.378 3.206 1.00 19.41 H ATOM 4420 N VAL A 298 7.569 -5.179 -1.896 1.00 24.92 N ATOM 4421 CA VAL A 298 8.597 -5.324 -2.930 1.00 24.78 C ATOM 4422 C VAL A 298 9.428 -6.600 -2.718 1.00 27.12 C ATOM 4423 O VAL A 298 9.617 -7.341 -3.679 1.00 27.82 O ATOM 4424 CB VAL A 298 9.517 -4.068 -3.026 1.00 23.28 C ATOM 4425 CG1 VAL A 298 10.884 -4.277 -3.713 1.00 22.42 C ATOM 4426 CG2 VAL A 298 8.779 -2.922 -3.738 1.00 24.57 C ATOM 4427 H VAL A 298 7.723 -4.443 -1.219 1.00 24.92 H ATOM 4428 HA VAL A 298 8.085 -5.436 -3.886 1.00 24.78 H ATOM 4429 HB VAL A 298 9.728 -3.728 -2.011 1.00 23.28 H ATOM 4430 HG11 VAL A 298 11.404 -3.329 -3.847 1.00 22.42 H ATOM 4431 HG12 VAL A 298 11.547 -4.914 -3.126 1.00 22.42 H ATOM 4432 HG13 VAL A 298 10.769 -4.725 -4.700 1.00 22.42 H ATOM 4433 HG21 VAL A 298 9.370 -2.008 -3.739 1.00 24.57 H ATOM 4434 HG22 VAL A 298 8.568 -3.176 -4.777 1.00 24.57 H ATOM 4435 HG23 VAL A 298 7.827 -2.690 -3.264 1.00 24.57 H ATOM 4436 N ILE A 299 9.844 -6.865 -1.466 1.00 27.82 N ATOM 4437 CA ILE A 299 10.501 -8.110 -1.055 1.00 30.85 C ATOM 4438 C ILE A 299 9.614 -9.347 -1.296 1.00 32.84 C ATOM 4439 O ILE A 299 10.116 -10.335 -1.827 1.00 33.53 O ATOM 4440 CB ILE A 299 10.977 -8.048 0.432 1.00 28.95 C ATOM 4441 CG1 ILE A 299 12.201 -7.106 0.550 1.00 27.94 C ATOM 4442 CG2 ILE A 299 11.256 -9.415 1.115 1.00 27.72 C ATOM 4443 CD1 ILE A 299 12.596 -6.762 1.990 1.00 30.35 C ATOM 4444 H ILE A 299 9.659 -6.198 -0.728 1.00 27.82 H ATOM 4445 HA ILE A 299 11.384 -8.225 -1.688 1.00 30.85 H ATOM 4446 HB ILE A 299 10.172 -7.583 1.004 1.00 28.95 H ATOM 4447 HG13 ILE A 299 12.011 -6.176 0.014 1.00 27.94 H ATOM 4448 HG12 ILE A 299 13.063 -7.544 0.054 1.00 27.94 H ATOM 4449 HG21 ILE A 299 11.655 -9.289 2.122 1.00 27.72 H ATOM 4450 HG22 ILE A 299 10.348 -10.006 1.228 1.00 27.72 H ATOM 4451 HG23 ILE A 299 11.971 -10.018 0.559 1.00 27.72 H ATOM 4452 HD11 ILE A 299 12.945 -5.732 2.065 1.00 30.35 H ATOM 4453 HD12 ILE A 299 11.750 -6.876 2.664 1.00 30.35 H ATOM 4454 HD13 ILE A 299 13.397 -7.412 2.346 1.00 30.35 H ATOM 4455 N THR A 300 8.315 -9.246 -0.964 1.00 33.27 N ATOM 4456 CA THR A 300 7.307 -10.282 -1.203 1.00 34.38 C ATOM 4457 C THR A 300 7.119 -10.599 -2.697 1.00 34.53 C ATOM 4458 O THR A 300 7.111 -11.773 -3.058 1.00 38.06 O ATOM 4459 CB THR A 300 5.925 -9.904 -0.600 1.00 33.97 C ATOM 4460 OG1 THR A 300 6.051 -9.752 0.800 1.00 33.69 O ATOM 4461 CG2 THR A 300 4.781 -10.901 -0.854 1.00 35.88 C ATOM 4462 H THR A 300 7.983 -8.393 -0.533 1.00 33.27 H ATOM 4463 HA THR A 300 7.659 -11.189 -0.715 1.00 34.38 H ATOM 4464 HB THR A 300 5.617 -8.936 -0.994 1.00 33.97 H ATOM 4465 HG1 THR A 300 6.568 -8.957 0.975 1.00 33.69 H ATOM 4466 HG21 THR A 300 3.886 -10.623 -0.296 1.00 35.88 H ATOM 4467 HG22 THR A 300 4.496 -10.933 -1.905 1.00 35.88 H ATOM 4468 HG23 THR A 300 5.058 -11.909 -0.550 1.00 35.88 H ATOM 4469 N ALA A 301 7.025 -9.554 -3.536 1.00 34.90 N ATOM 4470 CA ALA A 301 6.903 -9.676 -4.986 1.00 35.29 C ATOM 4471 C ALA A 301 8.136 -10.310 -5.653 1.00 36.92 C ATOM 4472 O ALA A 301 7.967 -11.109 -6.572 1.00 36.87 O ATOM 4473 CB ALA A 301 6.605 -8.299 -5.592 1.00 33.23 C ATOM 4474 H ALA A 301 7.034 -8.612 -3.168 1.00 34.90 H ATOM 4475 HA ALA A 301 6.048 -10.326 -5.182 1.00 35.29 H ATOM 4476 HB1 ALA A 301 6.523 -8.362 -6.676 1.00 33.23 H ATOM 4477 HB2 ALA A 301 5.663 -7.898 -5.217 1.00 33.23 H ATOM 4478 HB3 ALA A 301 7.389 -7.578 -5.359 1.00 33.23 H ATOM 4479 N LEU A 302 9.341 -9.972 -5.165 1.00 35.19 N ATOM 4480 CA LEU A 302 10.617 -10.501 -5.649 1.00 36.10 C ATOM 4481 C LEU A 302 10.817 -11.994 -5.333 1.00 37.90 C ATOM 4482 O LEU A 302 11.231 -12.731 -6.229 1.00 38.70 O ATOM 4483 CB LEU A 302 11.775 -9.653 -5.082 1.00 33.95 C ATOM 4484 CG LEU A 302 11.927 -8.270 -5.752 1.00 33.02 C ATOM 4485 CD1 LEU A 302 12.863 -7.367 -4.932 1.00 30.87 C ATOM 4486 CD2 LEU A 302 12.384 -8.368 -7.219 1.00 32.24 C ATOM 4487 H LEU A 302 9.397 -9.297 -4.413 1.00 35.19 H ATOM 4488 HA LEU A 302 10.625 -10.408 -6.735 1.00 36.10 H ATOM 4489 HB3 LEU A 302 12.720 -10.188 -5.189 1.00 33.95 H ATOM 4490 HB2 LEU A 302 11.626 -9.535 -4.008 1.00 33.95 H ATOM 4491 HG LEU A 302 10.952 -7.786 -5.759 1.00 33.02 H ATOM 4492 HD11 LEU A 302 12.589 -6.320 -5.056 1.00 30.87 H ATOM 4493 HD12 LEU A 302 12.821 -7.589 -3.866 1.00 30.87 H ATOM 4494 HD13 LEU A 302 13.899 -7.481 -5.246 1.00 30.87 H ATOM 4495 HD21 LEU A 302 13.063 -7.560 -7.487 1.00 32.24 H ATOM 4496 HD22 LEU A 302 12.891 -9.310 -7.427 1.00 32.24 H ATOM 4497 HD23 LEU A 302 11.531 -8.303 -7.893 1.00 32.24 H ATOM 4498 N VAL A 303 10.523 -12.413 -4.089 1.00 38.90 N ATOM 4499 CA VAL A 303 10.735 -13.791 -3.625 1.00 41.75 C ATOM 4500 C VAL A 303 9.666 -14.775 -4.143 1.00 43.21 C ATOM 4501 O VAL A 303 10.007 -15.927 -4.411 1.00 42.07 O ATOM 4502 CB VAL A 303 10.807 -13.895 -2.074 1.00 41.73 C ATOM 4503 CG1 VAL A 303 11.944 -13.029 -1.510 1.00 42.94 C ATOM 4504 CG2 VAL A 303 9.489 -13.646 -1.318 1.00 45.02 C ATOM 4505 H VAL A 303 10.190 -11.752 -3.399 1.00 38.90 H ATOM 4506 HA VAL A 303 11.698 -14.128 -4.015 1.00 41.75 H ATOM 4507 HB VAL A 303 11.085 -14.922 -1.831 1.00 41.73 H ATOM 4508 HG11 VAL A 303 11.874 -12.941 -0.429 1.00 42.94 H ATOM 4509 HG12 VAL A 303 12.917 -13.453 -1.757 1.00 42.94 H ATOM 4510 HG13 VAL A 303 11.931 -12.017 -1.903 1.00 42.94 H ATOM 4511 HG21 VAL A 303 9.646 -13.631 -0.239 1.00 45.02 H ATOM 4512 HG22 VAL A 303 9.054 -12.694 -1.601 1.00 45.02 H ATOM 4513 HG23 VAL A 303 8.753 -14.425 -1.514 1.00 45.02 H ATOM 4514 N GLU A 304 8.419 -14.302 -4.321 1.00 45.70 N ATOM 4515 CA GLU A 304 7.319 -15.062 -4.926 1.00 49.45 C ATOM 4516 C GLU A 304 7.352 -15.055 -6.465 1.00 51.34 C ATOM 4517 O GLU A 304 6.543 -15.753 -7.076 1.00 52.06 O ATOM 4518 CB GLU A 304 5.968 -14.524 -4.409 1.00 49.94 C ATOM 4519 CG GLU A 304 5.766 -14.754 -2.895 1.00 53.37 C ATOM 4520 CD GLU A 304 4.437 -14.240 -2.318 1.00 56.10 C ATOM 4521 OE1 GLU A 304 3.721 -13.481 -3.009 1.00 59.28 O ATOM 4522 OE2 GLU A 304 4.166 -14.611 -1.154 1.00 56.03 O1- ATOM 4523 H GLU A 304 8.204 -13.349 -4.058 1.00 45.70 H ATOM 4524 HA GLU A 304 7.402 -16.106 -4.619 1.00 49.45 H ATOM 4525 HB3 GLU A 304 5.148 -15.001 -4.949 1.00 49.94 H ATOM 4526 HB2 GLU A 304 5.896 -13.460 -4.641 1.00 49.94 H ATOM 4527 HG3 GLU A 304 6.568 -14.277 -2.334 1.00 53.37 H ATOM 4528 HG2 GLU A 304 5.842 -15.822 -2.687 1.00 53.37 H ATOM 4529 N ARG A 305 8.267 -14.269 -7.063 1.00 52.96 N ATOM 4530 CA ARG A 305 8.451 -14.085 -8.506 1.00 55.80 C ATOM 4531 C ARG A 305 7.221 -13.496 -9.225 1.00 56.10 C ATOM 4532 O ARG A 305 7.021 -13.758 -10.411 1.00 58.37 O ATOM 4533 CB ARG A 305 8.973 -15.374 -9.180 1.00 56.75 C ATOM 4534 CG ARG A 305 10.239 -15.954 -8.517 1.00 57.95 C ATOM 4535 CD ARG A 305 11.136 -16.732 -9.495 1.00 60.70 C ATOM 4536 NE ARG A 305 11.780 -15.824 -10.464 1.00 64.39 N ATOM 4537 CZ ARG A 305 12.596 -16.142 -11.484 1.00 65.17 C ATOM 4538 NH1 ARG A 305 12.973 -17.406 -11.728 1.00 65.84 N ATOM 4539 NH2 ARG A 305 13.042 -15.161 -12.279 1.00 65.41 N1+ ATOM 4540 H ARG A 305 8.893 -13.734 -6.478 1.00 52.96 H ATOM 4541 HA ARG A 305 9.232 -13.330 -8.600 1.00 55.80 H ATOM 4542 HB3 ARG A 305 9.176 -15.150 -10.228 1.00 56.75 H ATOM 4543 HB2 ARG A 305 8.197 -16.141 -9.195 1.00 56.75 H ATOM 4544 HG3 ARG A 305 10.010 -16.547 -7.630 1.00 57.95 H ATOM 4545 HG2 ARG A 305 10.817 -15.106 -8.144 1.00 57.95 H ATOM 4546 HD3 ARG A 305 10.501 -17.385 -10.095 1.00 60.70 H ATOM 4547 HD2 ARG A 305 11.843 -17.377 -8.972 1.00 60.70 H ATOM 4548 HE ARG A 305 11.549 -14.849 -10.341 1.00 64.39 H ATOM 4549 HH12 ARG A 305 13.586 -17.624 -12.500 1.00 65.84 H ATOM 4550 HH11 ARG A 305 12.642 -18.151 -11.133 1.00 65.84 H ATOM 4551 HH22 ARG A 305 13.655 -15.370 -13.054 1.00 65.41 H ATOM 4552 HH21 ARG A 305 12.766 -14.204 -12.115 1.00 65.41 H ATOM 4553 N THR A 306 6.430 -12.696 -8.490 1.00 55.97 N ATOM 4554 CA THR A 306 5.245 -11.991 -8.971 1.00 55.57 C ATOM 4555 C THR A 306 5.644 -10.969 -10.065 1.00 54.94 C ATOM 4556 O THR A 306 6.546 -10.170 -9.800 1.00 56.07 O ATOM 4557 CB THR A 306 4.586 -11.200 -7.810 1.00 55.82 C ATOM 4558 OG1 THR A 306 4.186 -12.106 -6.799 1.00 55.58 O ATOM 4559 CG2 THR A 306 3.334 -10.393 -8.204 1.00 56.42 C ATOM 4560 H THR A 306 6.702 -12.498 -7.537 1.00 55.97 H ATOM 4561 HA THR A 306 4.537 -12.745 -9.307 1.00 55.57 H ATOM 4562 HB THR A 306 5.313 -10.515 -7.373 1.00 55.82 H ATOM 4563 HG1 THR A 306 4.963 -12.539 -6.437 1.00 55.58 H ATOM 4564 HG21 THR A 306 2.893 -9.910 -7.331 1.00 56.42 H ATOM 4565 HG22 THR A 306 3.556 -9.606 -8.922 1.00 56.42 H ATOM 4566 HG23 THR A 306 2.573 -11.038 -8.645 1.00 56.42 H ATOM 4567 N PRO A 307 5.012 -11.029 -11.265 1.00 54.81 N ATOM 4568 CA PRO A 307 5.316 -10.129 -12.400 1.00 54.33 C ATOM 4569 C PRO A 307 5.409 -8.623 -12.091 1.00 52.41 C ATOM 4570 O PRO A 307 6.333 -7.975 -12.581 1.00 53.53 O ATOM 4571 CB PRO A 307 4.195 -10.423 -13.411 1.00 54.49 C ATOM 4572 CG PRO A 307 3.832 -11.872 -13.152 1.00 55.69 C ATOM 4573 CD PRO A 307 3.988 -12.008 -11.644 1.00 55.25 C ATOM 4574 HA PRO A 307 6.269 -10.462 -12.816 1.00 54.33 H ATOM 4575 HB3 PRO A 307 4.505 -10.254 -14.442 1.00 54.49 H ATOM 4576 HB2 PRO A 307 3.323 -9.794 -13.221 1.00 54.49 H ATOM 4577 HG3 PRO A 307 4.559 -12.515 -13.650 1.00 55.69 H ATOM 4578 HG2 PRO A 307 2.840 -12.145 -13.513 1.00 55.69 H ATOM 4579 HD2 PRO A 307 3.055 -11.761 -11.136 1.00 55.25 H ATOM 4580 HD3 PRO A 307 4.261 -13.035 -11.403 1.00 55.25 H ATOM 4581 N HIS A 308 4.480 -8.115 -11.264 1.00 49.84 N ATOM 4582 CA HIS A 308 4.475 -6.737 -10.785 1.00 47.05 C ATOM 4583 C HIS A 308 5.226 -6.639 -9.449 1.00 44.45 C ATOM 4584 O HIS A 308 4.877 -7.347 -8.504 1.00 44.53 O ATOM 4585 CB HIS A 308 3.017 -6.256 -10.651 1.00 48.81 C ATOM 4586 CG HIS A 308 2.866 -4.820 -10.204 1.00 50.00 C ATOM 4587 ND1 HIS A 308 3.509 -3.758 -10.852 1.00 49.02 N ATOM 4588 CD2 HIS A 308 2.134 -4.318 -9.148 1.00 51.40 C ATOM 4589 CE1 HIS A 308 3.149 -2.677 -10.172 1.00 50.89 C ATOM 4590 NE2 HIS A 308 2.335 -2.949 -9.151 1.00 51.97 N ATOM 4591 H HIS A 308 3.760 -8.716 -10.891 1.00 49.84 H ATOM 4592 HA HIS A 308 4.970 -6.097 -11.520 1.00 47.05 H ATOM 4593 HB3 HIS A 308 2.471 -6.894 -9.955 1.00 48.81 H ATOM 4594 HB2 HIS A 308 2.511 -6.353 -11.612 1.00 48.81 H ATOM 4595 HD2 HIS A 308 1.513 -4.808 -8.413 1.00 51.40 H ATOM 4596 HE1 HIS A 308 3.485 -1.681 -10.418 1.00 50.89 H ATOM 4597 HE2 HIS A 308 1.946 -2.282 -8.497 1.00 51.97 H ATOM 4598 N VAL A 309 6.210 -5.730 -9.399 1.00 40.26 N ATOM 4599 CA VAL A 309 6.958 -5.388 -8.193 1.00 35.27 C ATOM 4600 C VAL A 309 6.672 -3.893 -7.912 1.00 31.25 C ATOM 4601 O VAL A 309 7.007 -3.063 -8.761 1.00 30.60 O ATOM 4602 CB VAL A 309 8.486 -5.578 -8.400 1.00 34.02 C ATOM 4603 CG1 VAL A 309 9.287 -5.234 -7.127 1.00 31.38 C ATOM 4604 CG2 VAL A 309 8.829 -7.015 -8.837 1.00 34.36 C ATOM 4605 H VAL A 309 6.421 -5.179 -10.219 1.00 40.26 H ATOM 4606 HA VAL A 309 6.664 -6.036 -7.372 1.00 35.27 H ATOM 4607 HB VAL A 309 8.828 -4.920 -9.200 1.00 34.02 H ATOM 4608 HG11 VAL A 309 10.335 -5.511 -7.234 1.00 31.38 H ATOM 4609 HG12 VAL A 309 9.256 -4.169 -6.900 1.00 31.38 H ATOM 4610 HG13 VAL A 309 8.902 -5.772 -6.261 1.00 31.38 H ATOM 4611 HG21 VAL A 309 9.898 -7.121 -9.014 1.00 34.36 H ATOM 4612 HG22 VAL A 309 8.543 -7.741 -8.076 1.00 34.36 H ATOM 4613 HG23 VAL A 309 8.328 -7.291 -9.764 1.00 34.36 H ATOM 4614 N PRO A 310 6.005 -3.573 -6.776 1.00 30.38 N ATOM 4615 CA PRO A 310 5.485 -2.217 -6.504 1.00 29.30 C ATOM 4616 C PRO A 310 6.547 -1.196 -6.030 1.00 28.73 C ATOM 4617 O PRO A 310 6.369 -0.589 -4.976 1.00 27.93 O ATOM 4618 CB PRO A 310 4.382 -2.493 -5.462 1.00 29.27 C ATOM 4619 CG PRO A 310 4.892 -3.683 -4.673 1.00 29.44 C ATOM 4620 CD PRO A 310 5.557 -4.524 -5.753 1.00 29.54 C ATOM 4621 HA PRO A 310 5.019 -1.802 -7.400 1.00 29.30 H ATOM 4622 HB3 PRO A 310 3.462 -2.770 -5.979 1.00 29.27 H ATOM 4623 HB2 PRO A 310 4.139 -1.651 -4.814 1.00 29.27 H ATOM 4624 HG3 PRO A 310 4.108 -4.216 -4.134 1.00 29.44 H ATOM 4625 HG2 PRO A 310 5.635 -3.352 -3.947 1.00 29.44 H ATOM 4626 HD2 PRO A 310 6.373 -5.115 -5.340 1.00 29.54 H ATOM 4627 HD3 PRO A 310 4.826 -5.203 -6.196 1.00 29.54 H ATOM 4628 N TYR A 311 7.620 -0.987 -6.819 1.00 28.68 N ATOM 4629 CA TYR A 311 8.672 0.003 -6.543 1.00 29.45 C ATOM 4630 C TYR A 311 8.145 1.442 -6.443 1.00 28.70 C ATOM 4631 O TYR A 311 8.620 2.187 -5.594 1.00 24.95 O ATOM 4632 CB TYR A 311 9.757 -0.010 -7.637 1.00 31.49 C ATOM 4633 CG TYR A 311 10.513 -1.304 -7.844 1.00 34.07 C ATOM 4634 CD1 TYR A 311 11.369 -1.804 -6.839 1.00 35.28 C ATOM 4635 CD2 TYR A 311 10.416 -1.974 -9.080 1.00 36.40 C ATOM 4636 CE1 TYR A 311 12.137 -2.959 -7.084 1.00 36.88 C ATOM 4637 CE2 TYR A 311 11.189 -3.121 -9.326 1.00 39.34 C ATOM 4638 CZ TYR A 311 12.055 -3.610 -8.332 1.00 38.02 C ATOM 4639 OH TYR A 311 12.803 -4.719 -8.591 1.00 38.99 O ATOM 4640 H TYR A 311 7.717 -1.523 -7.672 1.00 28.68 H ATOM 4641 HA TYR A 311 9.129 -0.259 -5.588 1.00 29.45 H ATOM 4642 HB3 TYR A 311 10.508 0.751 -7.414 1.00 31.49 H ATOM 4643 HB2 TYR A 311 9.318 0.290 -8.591 1.00 31.49 H ATOM 4644 HD1 TYR A 311 11.455 -1.293 -5.891 1.00 35.28 H ATOM 4645 HD2 TYR A 311 9.767 -1.597 -9.857 1.00 36.40 H ATOM 4646 HE1 TYR A 311 12.791 -3.336 -6.314 1.00 36.88 H ATOM 4647 HE2 TYR A 311 11.118 -3.623 -10.280 1.00 39.34 H ATOM 4648 HH TYR A 311 13.397 -4.944 -7.864 1.00 38.99 H ATOM 4649 N ARG A 312 7.188 1.807 -7.311 1.00 28.58 N ATOM 4650 CA ARG A 312 6.659 3.166 -7.431 1.00 28.46 C ATOM 4651 C ARG A 312 5.696 3.596 -6.313 1.00 24.21 C ATOM 4652 O ARG A 312 5.388 4.787 -6.238 1.00 25.31 O ATOM 4653 CB ARG A 312 6.044 3.356 -8.827 1.00 35.11 C ATOM 4654 CG ARG A 312 7.102 3.240 -9.934 1.00 41.09 C ATOM 4655 CD ARG A 312 6.584 3.695 -11.308 1.00 45.95 C ATOM 4656 NE ARG A 312 7.696 3.974 -12.232 1.00 49.55 N ATOM 4657 CZ ARG A 312 8.467 5.079 -12.213 1.00 51.02 C ATOM 4658 NH1 ARG A 312 8.266 6.062 -11.323 1.00 53.12 N ATOM 4659 NH2 ARG A 312 9.460 5.204 -13.102 1.00 51.89 N1+ ATOM 4660 H ARG A 312 6.829 1.128 -7.966 1.00 28.58 H ATOM 4661 HA ARG A 312 7.497 3.854 -7.366 1.00 28.46 H ATOM 4662 HB3 ARG A 312 5.599 4.351 -8.887 1.00 35.11 H ATOM 4663 HB2 ARG A 312 5.231 2.647 -8.994 1.00 35.11 H ATOM 4664 HG3 ARG A 312 7.356 2.182 -10.010 1.00 41.09 H ATOM 4665 HG2 ARG A 312 8.031 3.744 -9.660 1.00 41.09 H ATOM 4666 HD3 ARG A 312 5.854 4.503 -11.250 1.00 45.95 H ATOM 4667 HD2 ARG A 312 6.065 2.852 -11.766 1.00 45.95 H ATOM 4668 HE ARG A 312 7.905 3.251 -12.905 1.00 49.55 H ATOM 4669 HH12 ARG A 312 8.822 6.911 -11.373 1.00 53.12 H ATOM 4670 HH11 ARG A 312 7.512 5.999 -10.656 1.00 53.12 H ATOM 4671 HH22 ARG A 312 10.008 6.053 -13.123 1.00 51.89 H ATOM 4672 HH21 ARG A 312 9.644 4.480 -13.781 1.00 51.89 H ATOM 4673 N GLU A 313 5.258 2.660 -5.455 1.00 23.86 N ATOM 4674 CA GLU A 313 4.308 2.931 -4.375 1.00 23.27 C ATOM 4675 C GLU A 313 4.916 3.625 -3.136 1.00 22.41 C ATOM 4676 O GLU A 313 4.150 3.962 -2.235 1.00 20.21 O ATOM 4677 CB GLU A 313 3.521 1.649 -4.026 1.00 23.76 C ATOM 4678 CG GLU A 313 2.783 1.049 -5.251 1.00 28.94 C ATOM 4679 CD GLU A 313 1.772 -0.074 -4.958 1.00 31.02 C ATOM 4680 OE1 GLU A 313 1.386 -0.741 -5.943 1.00 28.97 O ATOM 4681 OE2 GLU A 313 1.392 -0.263 -3.781 1.00 31.90 O1- ATOM 4682 H GLU A 313 5.566 1.702 -5.551 1.00 23.86 H ATOM 4683 HA GLU A 313 3.572 3.640 -4.760 1.00 23.27 H ATOM 4684 HB3 GLU A 313 2.808 1.881 -3.234 1.00 23.76 H ATOM 4685 HB2 GLU A 313 4.197 0.900 -3.617 1.00 23.76 H ATOM 4686 HG3 GLU A 313 3.518 0.669 -5.963 1.00 28.94 H ATOM 4687 HG2 GLU A 313 2.241 1.842 -5.767 1.00 28.94 H ATOM 4688 N SER A 314 6.237 3.885 -3.112 1.00 21.60 N ATOM 4689 CA SER A 314 6.876 4.691 -2.067 1.00 21.14 C ATOM 4690 C SER A 314 8.168 5.363 -2.542 1.00 20.47 C ATOM 4691 O SER A 314 8.789 4.903 -3.498 1.00 20.55 O ATOM 4692 CB SER A 314 7.115 3.854 -0.795 1.00 20.33 C ATOM 4693 OG SER A 314 8.272 3.039 -0.874 1.00 17.31 O ATOM 4694 H SER A 314 6.828 3.597 -3.879 1.00 21.60 H ATOM 4695 HA SER A 314 6.182 5.497 -1.822 1.00 21.14 H ATOM 4696 HB3 SER A 314 6.244 3.259 -0.538 1.00 20.33 H ATOM 4697 HB2 SER A 314 7.258 4.536 0.041 1.00 20.33 H ATOM 4698 HG SER A 314 8.167 2.414 -1.599 1.00 17.31 H ATOM 4699 N LYS A 315 8.568 6.408 -1.800 1.00 21.93 N ATOM 4700 CA LYS A 315 9.823 7.142 -1.964 1.00 24.01 C ATOM 4701 C LYS A 315 11.064 6.248 -1.788 1.00 23.64 C ATOM 4702 O LYS A 315 11.952 6.307 -2.637 1.00 23.92 O ATOM 4703 CB LYS A 315 9.868 8.328 -0.972 1.00 25.23 C ATOM 4704 CG LYS A 315 8.738 9.365 -1.122 1.00 30.47 C ATOM 4705 CD LYS A 315 8.782 10.164 -2.430 1.00 34.06 C ATOM 4706 CE LYS A 315 7.603 11.137 -2.569 1.00 40.37 C ATOM 4707 NZ LYS A 315 7.659 11.880 -3.839 1.00 44.85 N1+ ATOM 4708 H LYS A 315 7.987 6.703 -1.024 1.00 21.93 H ATOM 4709 HA LYS A 315 9.848 7.526 -2.985 1.00 24.01 H ATOM 4710 HB3 LYS A 315 10.825 8.844 -1.059 1.00 25.23 H ATOM 4711 HB2 LYS A 315 9.831 7.938 0.046 1.00 25.23 H ATOM 4712 HG3 LYS A 315 8.799 10.059 -0.283 1.00 30.47 H ATOM 4713 HG2 LYS A 315 7.768 8.880 -1.031 1.00 30.47 H ATOM 4714 HD3 LYS A 315 8.796 9.486 -3.282 1.00 34.06 H ATOM 4715 HD2 LYS A 315 9.714 10.729 -2.450 1.00 34.06 H ATOM 4716 HE3 LYS A 315 7.605 11.853 -1.747 1.00 40.37 H ATOM 4717 HE2 LYS A 315 6.658 10.593 -2.522 1.00 40.37 H ATOM 4718 HZ1 LYS A 315 7.645 11.229 -4.610 1.00 44.85 H ATOM 4719 HZ2 LYS A 315 6.864 12.499 -3.902 1.00 44.85 H ATOM 4720 HZ3 LYS A 315 8.511 12.422 -3.871 1.00 44.85 H ATOM 4721 N LEU A 316 11.089 5.425 -0.722 1.00 22.60 N ATOM 4722 CA LEU A 316 12.199 4.528 -0.375 1.00 21.91 C ATOM 4723 C LEU A 316 12.537 3.524 -1.485 1.00 21.21 C ATOM 4724 O LEU A 316 13.696 3.436 -1.881 1.00 22.09 O ATOM 4725 CB LEU A 316 11.882 3.800 0.951 1.00 22.01 C ATOM 4726 CG LEU A 316 12.999 2.887 1.506 1.00 23.74 C ATOM 4727 CD1 LEU A 316 14.245 3.698 1.908 1.00 23.65 C ATOM 4728 CD2 LEU A 316 12.484 2.037 2.680 1.00 21.42 C ATOM 4729 H LEU A 316 10.308 5.422 -0.079 1.00 22.60 H ATOM 4730 HA LEU A 316 13.077 5.158 -0.226 1.00 21.91 H ATOM 4731 HB3 LEU A 316 10.970 3.215 0.817 1.00 22.01 H ATOM 4732 HB2 LEU A 316 11.655 4.540 1.715 1.00 22.01 H ATOM 4733 HG LEU A 316 13.297 2.177 0.734 1.00 23.74 H ATOM 4734 HD11 LEU A 316 14.887 3.140 2.591 1.00 23.65 H ATOM 4735 HD12 LEU A 316 14.841 3.954 1.033 1.00 23.65 H ATOM 4736 HD13 LEU A 316 13.975 4.631 2.402 1.00 23.65 H ATOM 4737 HD21 LEU A 316 12.783 0.994 2.569 1.00 21.42 H ATOM 4738 HD22 LEU A 316 12.876 2.398 3.628 1.00 21.42 H ATOM 4739 HD23 LEU A 316 11.399 2.052 2.762 1.00 21.42 H ATOM 4740 N THR A 317 11.516 2.793 -1.956 1.00 20.82 N ATOM 4741 CA THR A 317 11.660 1.732 -2.951 1.00 21.01 C ATOM 4742 C THR A 317 11.792 2.248 -4.401 1.00 22.51 C ATOM 4743 O THR A 317 12.246 1.472 -5.239 1.00 24.89 O ATOM 4744 CB THR A 317 10.476 0.741 -2.867 1.00 20.28 C ATOM 4745 OG1 THR A 317 9.239 1.389 -3.069 1.00 19.26 O ATOM 4746 CG2 THR A 317 10.406 0.013 -1.519 1.00 21.44 C ATOM 4747 H THR A 317 10.584 2.932 -1.588 1.00 20.82 H ATOM 4748 HA THR A 317 12.575 1.177 -2.728 1.00 21.01 H ATOM 4749 HB THR A 317 10.586 -0.012 -3.648 1.00 20.28 H ATOM 4750 HG1 THR A 317 9.195 1.713 -3.977 1.00 19.26 H ATOM 4751 HG21 THR A 317 9.618 -0.737 -1.530 1.00 21.44 H ATOM 4752 HG22 THR A 317 11.343 -0.503 -1.310 1.00 21.44 H ATOM 4753 HG23 THR A 317 10.207 0.695 -0.691 1.00 21.44 H ATOM 4754 N ARG A 318 11.474 3.530 -4.672 1.00 24.39 N ATOM 4755 CA ARG A 318 11.843 4.211 -5.922 1.00 24.64 C ATOM 4756 C ARG A 318 13.339 4.554 -5.939 1.00 24.75 C ATOM 4757 O ARG A 318 14.006 4.280 -6.936 1.00 22.73 O ATOM 4758 CB ARG A 318 11.035 5.513 -6.102 1.00 26.49 C ATOM 4759 CG ARG A 318 9.578 5.282 -6.509 1.00 30.67 C ATOM 4760 CD ARG A 318 8.700 6.540 -6.458 1.00 32.24 C ATOM 4761 NE ARG A 318 9.039 7.522 -7.503 1.00 37.00 N ATOM 4762 CZ ARG A 318 8.560 8.777 -7.606 1.00 39.39 C ATOM 4763 NH1 ARG A 318 7.674 9.276 -6.730 1.00 42.30 N ATOM 4764 NH2 ARG A 318 8.972 9.552 -8.616 1.00 40.43 N1+ ATOM 4765 H ARG A 318 11.077 4.109 -3.945 1.00 24.39 H ATOM 4766 HA ARG A 318 11.641 3.552 -6.769 1.00 24.64 H ATOM 4767 HB3 ARG A 318 11.498 6.121 -6.881 1.00 26.49 H ATOM 4768 HB2 ARG A 318 11.080 6.105 -5.188 1.00 26.49 H ATOM 4769 HG3 ARG A 318 9.116 4.507 -5.913 1.00 30.67 H ATOM 4770 HG2 ARG A 318 9.596 4.898 -7.530 1.00 30.67 H ATOM 4771 HD3 ARG A 318 8.892 7.041 -5.508 1.00 32.24 H ATOM 4772 HD2 ARG A 318 7.641 6.285 -6.461 1.00 32.24 H ATOM 4773 HE ARG A 318 9.701 7.210 -8.198 1.00 37.00 H ATOM 4774 HH12 ARG A 318 7.284 10.196 -6.868 1.00 42.30 H ATOM 4775 HH11 ARG A 318 7.321 8.689 -5.984 1.00 42.30 H ATOM 4776 HH22 ARG A 318 8.631 10.497 -8.713 1.00 40.43 H ATOM 4777 HH21 ARG A 318 9.590 9.185 -9.332 1.00 40.43 H ATOM 4778 N ILE A 319 13.825 5.147 -4.834 1.00 24.38 N ATOM 4779 CA ILE A 319 15.213 5.573 -4.641 1.00 25.59 C ATOM 4780 C ILE A 319 16.201 4.390 -4.594 1.00 25.42 C ATOM 4781 O ILE A 319 17.299 4.508 -5.137 1.00 25.60 O ATOM 4782 CB ILE A 319 15.347 6.455 -3.356 1.00 26.11 C ATOM 4783 CG1 ILE A 319 14.636 7.814 -3.564 1.00 27.58 C ATOM 4784 CG2 ILE A 319 16.790 6.700 -2.857 1.00 26.26 C ATOM 4785 CD1 ILE A 319 14.237 8.535 -2.268 1.00 29.91 C ATOM 4786 H ILE A 319 13.199 5.341 -4.064 1.00 24.38 H ATOM 4787 HA ILE A 319 15.488 6.184 -5.503 1.00 25.59 H ATOM 4788 HB ILE A 319 14.819 5.934 -2.555 1.00 26.11 H ATOM 4789 HG13 ILE A 319 13.730 7.674 -4.148 1.00 27.58 H ATOM 4790 HG12 ILE A 319 15.266 8.468 -4.166 1.00 27.58 H ATOM 4791 HG21 ILE A 319 16.806 7.378 -2.004 1.00 26.26 H ATOM 4792 HG22 ILE A 319 17.275 5.783 -2.526 1.00 26.26 H ATOM 4793 HG23 ILE A 319 17.406 7.145 -3.639 1.00 26.26 H ATOM 4794 HD11 ILE A 319 14.615 9.556 -2.268 1.00 29.91 H ATOM 4795 HD12 ILE A 319 13.153 8.602 -2.178 1.00 29.91 H ATOM 4796 HD13 ILE A 319 14.606 8.031 -1.374 1.00 29.91 H ATOM 4797 N LEU A 320 15.774 3.273 -3.983 1.00 23.39 N ATOM 4798 CA LEU A 320 16.553 2.046 -3.809 1.00 23.27 C ATOM 4799 C LEU A 320 16.024 0.900 -4.693 1.00 22.23 C ATOM 4800 O LEU A 320 16.201 -0.263 -4.328 1.00 18.72 O ATOM 4801 CB LEU A 320 16.543 1.650 -2.312 1.00 23.58 C ATOM 4802 CG LEU A 320 17.160 2.689 -1.352 1.00 25.87 C ATOM 4803 CD1 LEU A 320 16.935 2.246 0.099 1.00 25.90 C ATOM 4804 CD2 LEU A 320 18.655 2.952 -1.628 1.00 25.98 C ATOM 4805 H LEU A 320 14.859 3.273 -3.551 1.00 23.39 H ATOM 4806 HA LEU A 320 17.586 2.207 -4.119 1.00 23.27 H ATOM 4807 HB3 LEU A 320 17.081 0.713 -2.168 1.00 23.58 H ATOM 4808 HB2 LEU A 320 15.514 1.445 -2.012 1.00 23.58 H ATOM 4809 HG LEU A 320 16.623 3.630 -1.471 1.00 25.87 H ATOM 4810 HD11 LEU A 320 17.117 3.064 0.796 1.00 25.90 H ATOM 4811 HD12 LEU A 320 15.916 1.893 0.258 1.00 25.90 H ATOM 4812 HD13 LEU A 320 17.601 1.426 0.358 1.00 25.90 H ATOM 4813 HD21 LEU A 320 19.249 2.942 -0.714 1.00 25.98 H ATOM 4814 HD22 LEU A 320 19.087 2.205 -2.295 1.00 25.98 H ATOM 4815 HD23 LEU A 320 18.799 3.927 -2.093 1.00 25.98 H ATOM 4816 N GLN A 321 15.407 1.223 -5.846 1.00 21.93 N ATOM 4817 CA GLN A 321 14.906 0.249 -6.824 1.00 25.12 C ATOM 4818 C GLN A 321 15.974 -0.748 -7.309 1.00 23.77 C ATOM 4819 O GLN A 321 15.700 -1.947 -7.354 1.00 25.82 O ATOM 4820 CB GLN A 321 14.206 0.987 -7.991 1.00 25.91 C ATOM 4821 CG GLN A 321 13.803 0.080 -9.178 1.00 35.95 C ATOM 4822 CD GLN A 321 12.874 0.714 -10.217 1.00 39.40 C ATOM 4823 OE1 GLN A 321 12.394 0.014 -11.104 1.00 43.71 O ATOM 4824 NE2 GLN A 321 12.623 2.024 -10.141 1.00 41.83 N ATOM 4825 H GLN A 321 15.287 2.197 -6.086 1.00 21.93 H ATOM 4826 HA GLN A 321 14.142 -0.339 -6.310 1.00 25.12 H ATOM 4827 HB3 GLN A 321 14.853 1.786 -8.357 1.00 25.91 H ATOM 4828 HB2 GLN A 321 13.316 1.476 -7.595 1.00 25.91 H ATOM 4829 HG3 GLN A 321 13.309 -0.815 -8.802 1.00 35.95 H ATOM 4830 HG2 GLN A 321 14.693 -0.256 -9.712 1.00 35.95 H ATOM 4831 HE22 GLN A 321 12.032 2.464 -10.830 1.00 41.83 H ATOM 4832 HE21 GLN A 321 13.039 2.584 -9.411 1.00 41.83 H ATOM 4833 N ASP A 322 17.174 -0.234 -7.626 1.00 25.83 N ATOM 4834 CA ASP A 322 18.310 -1.015 -8.114 1.00 27.25 C ATOM 4835 C ASP A 322 18.931 -1.931 -7.032 1.00 28.86 C ATOM 4836 O ASP A 322 19.571 -2.922 -7.381 1.00 28.79 O ATOM 4837 CB ASP A 322 19.382 -0.093 -8.743 1.00 28.99 C ATOM 4838 CG ASP A 322 20.349 -0.795 -9.709 1.00 32.05 C ATOM 4839 OD1 ASP A 322 19.857 -1.492 -10.624 1.00 27.75 O ATOM 4840 OD2 ASP A 322 21.569 -0.580 -9.559 1.00 31.15 O1- ATOM 4841 H ASP A 322 17.328 0.763 -7.538 1.00 25.83 H ATOM 4842 HA ASP A 322 17.902 -1.664 -8.887 1.00 27.25 H ATOM 4843 HB3 ASP A 322 19.936 0.416 -7.951 1.00 28.99 H ATOM 4844 HB2 ASP A 322 18.893 0.709 -9.298 1.00 28.99 H ATOM 4845 N SER A 323 18.711 -1.613 -5.746 1.00 28.11 N ATOM 4846 CA SER A 323 19.153 -2.419 -4.602 1.00 26.92 C ATOM 4847 C SER A 323 18.236 -3.628 -4.332 1.00 28.99 C ATOM 4848 O SER A 323 18.616 -4.507 -3.563 1.00 30.38 O ATOM 4849 CB SER A 323 19.220 -1.520 -3.354 1.00 24.83 C ATOM 4850 OG SER A 323 20.107 -0.443 -3.569 1.00 25.15 O ATOM 4851 H SER A 323 18.146 -0.804 -5.528 1.00 28.11 H ATOM 4852 HA SER A 323 20.152 -2.810 -4.795 1.00 26.92 H ATOM 4853 HB3 SER A 323 19.580 -2.087 -2.495 1.00 24.83 H ATOM 4854 HB2 SER A 323 18.239 -1.134 -3.082 1.00 24.83 H ATOM 4855 HG SER A 323 19.763 0.099 -4.283 1.00 25.15 H ATOM 4856 N LEU A 324 17.047 -3.653 -4.948 1.00 28.47 N ATOM 4857 CA LEU A 324 16.007 -4.642 -4.701 1.00 29.95 C ATOM 4858 C LEU A 324 15.714 -5.360 -6.023 1.00 32.13 C ATOM 4859 O LEU A 324 14.773 -4.995 -6.721 1.00 30.55 O ATOM 4860 CB LEU A 324 14.776 -3.901 -4.127 1.00 26.21 C ATOM 4861 CG LEU A 324 14.992 -3.285 -2.725 1.00 28.34 C ATOM 4862 CD1 LEU A 324 13.824 -2.358 -2.345 1.00 24.74 C ATOM 4863 CD2 LEU A 324 15.268 -4.347 -1.641 1.00 26.31 C ATOM 4864 H LEU A 324 16.799 -2.905 -5.582 1.00 28.47 H ATOM 4865 HA LEU A 324 16.330 -5.402 -3.987 1.00 29.95 H ATOM 4866 HB3 LEU A 324 13.923 -4.579 -4.082 1.00 26.21 H ATOM 4867 HB2 LEU A 324 14.495 -3.107 -4.820 1.00 26.21 H ATOM 4868 HG LEU A 324 15.870 -2.640 -2.778 1.00 28.34 H ATOM 4869 HD11 LEU A 324 14.170 -1.530 -1.725 1.00 24.74 H ATOM 4870 HD12 LEU A 324 13.347 -1.919 -3.223 1.00 24.74 H ATOM 4871 HD13 LEU A 324 13.049 -2.890 -1.795 1.00 24.74 H ATOM 4872 HD21 LEU A 324 14.682 -4.177 -0.738 1.00 26.31 H ATOM 4873 HD22 LEU A 324 15.038 -5.356 -1.986 1.00 26.31 H ATOM 4874 HD23 LEU A 324 16.319 -4.334 -1.347 1.00 26.31 H ATOM 4875 N GLY A 325 16.541 -6.365 -6.353 1.00 33.04 N ATOM 4876 CA GLY A 325 16.398 -7.173 -7.566 1.00 35.57 C ATOM 4877 C GLY A 325 17.047 -6.528 -8.804 1.00 36.92 C ATOM 4878 O GLY A 325 16.805 -6.999 -9.916 1.00 37.76 O ATOM 4879 H GLY A 325 17.297 -6.616 -5.731 1.00 33.04 H ATOM 4880 HA3 GLY A 325 15.348 -7.383 -7.772 1.00 35.57 H ATOM 4881 HA2 GLY A 325 16.874 -8.131 -7.383 1.00 35.57 H ATOM 4882 N GLY A 326 17.848 -5.463 -8.629 1.00 36.99 N ATOM 4883 CA GLY A 326 18.547 -4.767 -9.708 1.00 35.83 C ATOM 4884 C GLY A 326 20.015 -5.204 -9.764 1.00 36.25 C ATOM 4885 O GLY A 326 20.351 -6.339 -9.431 1.00 36.30 O ATOM 4886 H GLY A 326 18.015 -5.127 -7.692 1.00 36.99 H ATOM 4887 HA3 GLY A 326 18.475 -3.698 -9.542 1.00 35.83 H ATOM 4888 HA2 GLY A 326 18.087 -4.949 -10.679 1.00 35.83 H ATOM 4889 N ARG A 327 20.876 -4.291 -10.238 1.00 34.63 N ATOM 4890 CA ARG A 327 22.294 -4.513 -10.534 1.00 36.55 C ATOM 4891 C ARG A 327 23.259 -4.020 -9.437 1.00 36.94 C ATOM 4892 O ARG A 327 24.462 -3.961 -9.692 1.00 38.93 O ATOM 4893 CB ARG A 327 22.628 -3.865 -11.892 1.00 38.14 C ATOM 4894 CG ARG A 327 21.859 -4.470 -13.075 1.00 42.41 C ATOM 4895 CD ARG A 327 22.327 -3.867 -14.405 1.00 46.96 C ATOM 4896 NE ARG A 327 21.543 -4.365 -15.547 1.00 51.13 N ATOM 4897 CZ ARG A 327 21.654 -3.970 -16.830 1.00 54.30 C ATOM 4898 NH1 ARG A 327 22.509 -3.008 -17.211 1.00 55.38 N ATOM 4899 NH2 ARG A 327 20.886 -4.556 -17.757 1.00 54.29 N1+ ATOM 4900 H ARG A 327 20.530 -3.364 -10.461 1.00 34.63 H ATOM 4901 HA ARG A 327 22.468 -5.583 -10.626 1.00 36.55 H ATOM 4902 HB3 ARG A 327 23.692 -3.980 -12.104 1.00 38.14 H ATOM 4903 HB2 ARG A 327 22.442 -2.791 -11.843 1.00 38.14 H ATOM 4904 HG3 ARG A 327 20.777 -4.393 -12.959 1.00 42.41 H ATOM 4905 HG2 ARG A 327 22.092 -5.536 -13.080 1.00 42.41 H ATOM 4906 HD3 ARG A 327 23.346 -4.210 -14.594 1.00 46.96 H ATOM 4907 HD2 ARG A 327 22.365 -2.778 -14.361 1.00 46.96 H ATOM 4908 HE ARG A 327 20.874 -5.088 -15.328 1.00 51.13 H ATOM 4909 HH12 ARG A 327 22.580 -2.730 -18.179 1.00 55.38 H ATOM 4910 HH11 ARG A 327 23.098 -2.558 -16.525 1.00 55.38 H ATOM 4911 HH22 ARG A 327 20.956 -4.279 -18.726 1.00 54.29 H ATOM 4912 HH21 ARG A 327 20.236 -5.284 -17.501 1.00 54.29 H ATOM 4913 N THR A 328 22.747 -3.688 -8.245 1.00 34.16 N ATOM 4914 CA THR A 328 23.559 -3.342 -7.077 1.00 31.72 C ATOM 4915 C THR A 328 23.710 -4.595 -6.192 1.00 30.02 C ATOM 4916 O THR A 328 22.729 -5.311 -5.995 1.00 30.34 O ATOM 4917 CB THR A 328 22.844 -2.225 -6.270 1.00 31.13 C ATOM 4918 OG1 THR A 328 22.993 -0.998 -6.956 1.00 32.46 O ATOM 4919 CG2 THR A 328 23.300 -1.990 -4.826 1.00 28.96 C ATOM 4920 H THR A 328 21.749 -3.742 -8.095 1.00 34.16 H ATOM 4921 HA THR A 328 24.548 -2.990 -7.375 1.00 31.72 H ATOM 4922 HB THR A 328 21.779 -2.434 -6.245 1.00 31.13 H ATOM 4923 HG1 THR A 328 22.532 -1.051 -7.801 1.00 32.46 H ATOM 4924 HG21 THR A 328 22.845 -1.086 -4.430 1.00 28.96 H ATOM 4925 HG22 THR A 328 23.018 -2.808 -4.165 1.00 28.96 H ATOM 4926 HG23 THR A 328 24.376 -1.865 -4.778 1.00 28.96 H ATOM 4927 N ARG A 329 24.920 -4.825 -5.647 1.00 29.31 N ATOM 4928 CA ARG A 329 25.159 -5.848 -4.622 1.00 29.30 C ATOM 4929 C ARG A 329 24.519 -5.399 -3.301 1.00 26.80 C ATOM 4930 O ARG A 329 24.894 -4.345 -2.795 1.00 29.25 O ATOM 4931 CB ARG A 329 26.676 -6.102 -4.459 1.00 30.11 C ATOM 4932 CG ARG A 329 27.028 -7.054 -3.295 1.00 31.58 C ATOM 4933 CD ARG A 329 28.530 -7.319 -3.128 1.00 32.48 C ATOM 4934 NE ARG A 329 28.805 -8.080 -1.897 1.00 36.20 N ATOM 4935 CZ ARG A 329 29.960 -8.660 -1.517 1.00 37.53 C ATOM 4936 NH1 ARG A 329 31.079 -8.578 -2.250 1.00 35.50 N ATOM 4937 NH2 ARG A 329 29.991 -9.349 -0.370 1.00 37.85 N1+ ATOM 4938 H ARG A 329 25.689 -4.196 -5.843 1.00 29.31 H ATOM 4939 HA ARG A 329 24.692 -6.783 -4.941 1.00 29.30 H ATOM 4940 HB3 ARG A 329 27.182 -5.151 -4.296 1.00 30.11 H ATOM 4941 HB2 ARG A 329 27.075 -6.500 -5.392 1.00 30.11 H ATOM 4942 HG3 ARG A 329 26.549 -8.003 -3.543 1.00 31.58 H ATOM 4943 HG2 ARG A 329 26.599 -6.744 -2.344 1.00 31.58 H ATOM 4944 HD3 ARG A 329 29.129 -6.411 -3.215 1.00 32.48 H ATOM 4945 HD2 ARG A 329 28.828 -7.985 -3.937 1.00 32.48 H ATOM 4946 HE ARG A 329 28.011 -8.160 -1.272 1.00 36.20 H ATOM 4947 HH12 ARG A 329 31.942 -8.995 -1.935 1.00 35.50 H ATOM 4948 HH11 ARG A 329 31.068 -8.087 -3.140 1.00 35.50 H ATOM 4949 HH22 ARG A 329 30.850 -9.774 -0.052 1.00 37.85 H ATOM 4950 HH21 ARG A 329 29.159 -9.437 0.200 1.00 37.85 H ATOM 4951 N THR A 330 23.585 -6.195 -2.764 1.00 27.34 N ATOM 4952 CA THR A 330 22.833 -5.805 -1.574 1.00 27.33 C ATOM 4953 C THR A 330 22.998 -6.817 -0.436 1.00 28.41 C ATOM 4954 O THR A 330 22.941 -8.026 -0.661 1.00 25.07 O ATOM 4955 CB THR A 330 21.336 -5.609 -1.892 1.00 28.09 C ATOM 4956 OG1 THR A 330 21.251 -4.518 -2.784 1.00 26.38 O ATOM 4957 CG2 THR A 330 20.423 -5.299 -0.692 1.00 25.58 C ATOM 4958 H THR A 330 23.317 -7.057 -3.217 1.00 27.34 H ATOM 4959 HA THR A 330 23.184 -4.846 -1.209 1.00 27.33 H ATOM 4960 HB THR A 330 20.953 -6.483 -2.414 1.00 28.09 H ATOM 4961 HG1 THR A 330 20.321 -4.374 -2.990 1.00 26.38 H ATOM 4962 HG21 THR A 330 19.409 -5.070 -1.018 1.00 25.58 H ATOM 4963 HG22 THR A 330 20.346 -6.139 -0.003 1.00 25.58 H ATOM 4964 HG23 THR A 330 20.795 -4.440 -0.132 1.00 25.58 H ATOM 4965 N SER A 331 23.172 -6.258 0.770 1.00 29.22 N ATOM 4966 CA SER A 331 23.208 -6.960 2.044 1.00 28.06 C ATOM 4967 C SER A 331 22.117 -6.397 2.968 1.00 27.09 C ATOM 4968 O SER A 331 21.711 -5.247 2.801 1.00 26.08 O ATOM 4969 CB SER A 331 24.594 -6.766 2.691 1.00 30.03 C ATOM 4970 OG SER A 331 25.566 -7.557 2.044 1.00 34.99 O ATOM 4971 H SER A 331 23.211 -5.249 0.838 1.00 29.22 H ATOM 4972 HA SER A 331 23.008 -8.013 1.876 1.00 28.06 H ATOM 4973 HB3 SER A 331 24.578 -7.064 3.740 1.00 30.03 H ATOM 4974 HB2 SER A 331 24.898 -5.719 2.665 1.00 30.03 H ATOM 4975 HG SER A 331 25.398 -8.478 2.258 1.00 34.99 H ATOM 4976 N ILE A 332 21.676 -7.210 3.940 1.00 26.63 N ATOM 4977 CA ILE A 332 20.734 -6.799 4.982 1.00 25.76 C ATOM 4978 C ILE A 332 21.270 -7.288 6.338 1.00 25.56 C ATOM 4979 O ILE A 332 21.546 -8.477 6.483 1.00 25.03 O ATOM 4980 CB ILE A 332 19.301 -7.385 4.767 1.00 25.98 C ATOM 4981 CG1 ILE A 332 18.706 -6.971 3.397 1.00 25.58 C ATOM 4982 CG2 ILE A 332 18.322 -7.013 5.910 1.00 24.93 C ATOM 4983 CD1 ILE A 332 17.372 -7.647 3.060 1.00 24.29 C ATOM 4984 H ILE A 332 22.042 -8.151 4.015 1.00 26.63 H ATOM 4985 HA ILE A 332 20.665 -5.712 5.022 1.00 25.76 H ATOM 4986 HB ILE A 332 19.387 -8.473 4.759 1.00 25.98 H ATOM 4987 HG13 ILE A 332 19.402 -7.207 2.594 1.00 25.58 H ATOM 4988 HG12 ILE A 332 18.567 -5.893 3.361 1.00 25.58 H ATOM 4989 HG21 ILE A 332 17.328 -7.427 5.742 1.00 24.93 H ATOM 4990 HG22 ILE A 332 18.640 -7.398 6.879 1.00 24.93 H ATOM 4991 HG23 ILE A 332 18.217 -5.931 6.002 1.00 24.93 H ATOM 4992 HD11 ILE A 332 17.191 -7.638 1.985 1.00 24.29 H ATOM 4993 HD12 ILE A 332 17.363 -8.684 3.392 1.00 24.29 H ATOM 4994 HD13 ILE A 332 16.534 -7.133 3.532 1.00 24.29 H ATOM 4995 N ILE A 333 21.373 -6.369 7.310 1.00 23.67 N ATOM 4996 CA ILE A 333 21.724 -6.674 8.694 1.00 22.02 C ATOM 4997 C ILE A 333 20.440 -6.573 9.539 1.00 22.07 C ATOM 4998 O ILE A 333 19.974 -5.473 9.831 1.00 19.54 O ATOM 4999 CB ILE A 333 22.815 -5.724 9.275 1.00 22.12 C ATOM 5000 CG1 ILE A 333 24.092 -5.708 8.397 1.00 19.60 C ATOM 5001 CG2 ILE A 333 23.164 -6.116 10.732 1.00 21.06 C ATOM 5002 CD1 ILE A 333 25.101 -4.611 8.762 1.00 20.16 C ATOM 5003 H ILE A 333 21.156 -5.400 7.112 1.00 23.67 H ATOM 5004 HA ILE A 333 22.112 -7.688 8.772 1.00 22.02 H ATOM 5005 HB ILE A 333 22.423 -4.704 9.285 1.00 22.12 H ATOM 5006 HG13 ILE A 333 23.830 -5.571 7.348 1.00 19.60 H ATOM 5007 HG12 ILE A 333 24.590 -6.673 8.455 1.00 19.60 H ATOM 5008 HG21 ILE A 333 24.005 -5.553 11.122 1.00 21.06 H ATOM 5009 HG22 ILE A 333 22.333 -5.948 11.417 1.00 21.06 H ATOM 5010 HG23 ILE A 333 23.435 -7.170 10.800 1.00 21.06 H ATOM 5011 HD11 ILE A 333 25.798 -4.441 7.943 1.00 20.16 H ATOM 5012 HD12 ILE A 333 24.605 -3.663 8.976 1.00 20.16 H ATOM 5013 HD13 ILE A 333 25.694 -4.891 9.633 1.00 20.16 H ATOM 5014 N ALA A 334 19.885 -7.739 9.893 1.00 19.22 N ATOM 5015 CA ALA A 334 18.684 -7.884 10.708 1.00 21.48 C ATOM 5016 C ALA A 334 19.051 -7.877 12.199 1.00 23.05 C ATOM 5017 O ALA A 334 19.550 -8.875 12.713 1.00 22.81 O ATOM 5018 CB ALA A 334 17.975 -9.180 10.297 1.00 20.70 C ATOM 5019 H ALA A 334 20.340 -8.603 9.622 1.00 19.22 H ATOM 5020 HA ALA A 334 17.999 -7.067 10.492 1.00 21.48 H ATOM 5021 HB1 ALA A 334 17.090 -9.364 10.906 1.00 20.70 H ATOM 5022 HB2 ALA A 334 17.653 -9.122 9.257 1.00 20.70 H ATOM 5023 HB3 ALA A 334 18.631 -10.046 10.386 1.00 20.70 H ATOM 5024 N THR A 335 18.818 -6.745 12.873 1.00 22.98 N ATOM 5025 CA THR A 335 19.144 -6.551 14.283 1.00 22.61 C ATOM 5026 C THR A 335 17.963 -6.989 15.178 1.00 23.15 C ATOM 5027 O THR A 335 16.813 -6.705 14.845 1.00 20.17 O ATOM 5028 CB THR A 335 19.513 -5.071 14.550 1.00 24.16 C ATOM 5029 OG1 THR A 335 18.447 -4.191 14.261 1.00 25.56 O ATOM 5030 CG2 THR A 335 20.736 -4.617 13.739 1.00 21.73 C ATOM 5031 H THR A 335 18.379 -5.959 12.407 1.00 22.98 H ATOM 5032 HA THR A 335 20.018 -7.151 14.513 1.00 22.61 H ATOM 5033 HB THR A 335 19.746 -4.953 15.609 1.00 24.16 H ATOM 5034 HG1 THR A 335 17.770 -4.296 14.940 1.00 25.56 H ATOM 5035 HG21 THR A 335 21.008 -3.591 13.976 1.00 21.73 H ATOM 5036 HG22 THR A 335 21.604 -5.240 13.954 1.00 21.73 H ATOM 5037 HG23 THR A 335 20.550 -4.660 12.666 1.00 21.73 H ATOM 5038 N ILE A 336 18.265 -7.699 16.280 1.00 21.79 N ATOM 5039 CA ILE A 336 17.268 -8.275 17.194 1.00 23.08 C ATOM 5040 C ILE A 336 17.679 -8.119 18.672 1.00 23.78 C ATOM 5041 O ILE A 336 18.863 -7.976 18.979 1.00 23.15 O ATOM 5042 CB ILE A 336 17.006 -9.791 16.908 1.00 23.04 C ATOM 5043 CG1 ILE A 336 18.258 -10.693 17.057 1.00 23.18 C ATOM 5044 CG2 ILE A 336 16.309 -9.996 15.549 1.00 22.42 C ATOM 5045 CD1 ILE A 336 17.981 -12.195 16.922 1.00 22.53 C ATOM 5046 H ILE A 336 19.233 -7.901 16.497 1.00 21.79 H ATOM 5047 HA ILE A 336 16.329 -7.733 17.086 1.00 23.08 H ATOM 5048 HB ILE A 336 16.289 -10.135 17.656 1.00 23.04 H ATOM 5049 HG13 ILE A 336 18.712 -10.544 18.034 1.00 23.18 H ATOM 5050 HG12 ILE A 336 19.011 -10.404 16.323 1.00 23.18 H ATOM 5051 HG21 ILE A 336 15.961 -11.021 15.422 1.00 22.42 H ATOM 5052 HG22 ILE A 336 15.432 -9.356 15.458 1.00 22.42 H ATOM 5053 HG23 ILE A 336 16.976 -9.770 14.716 1.00 22.42 H ATOM 5054 HD11 ILE A 336 18.867 -12.770 17.186 1.00 22.53 H ATOM 5055 HD12 ILE A 336 17.172 -12.513 17.580 1.00 22.53 H ATOM 5056 HD13 ILE A 336 17.714 -12.465 15.900 1.00 22.53 H ATOM 5057 N SER A 337 16.668 -8.167 19.555 1.00 25.88 N ATOM 5058 CA SER A 337 16.814 -8.197 21.010 1.00 27.99 C ATOM 5059 C SER A 337 16.876 -9.661 21.508 1.00 28.21 C ATOM 5060 O SER A 337 16.176 -10.506 20.948 1.00 24.65 O ATOM 5061 CB SER A 337 15.593 -7.484 21.625 1.00 29.04 C ATOM 5062 OG SER A 337 15.634 -7.507 23.039 1.00 32.61 O ATOM 5063 H SER A 337 15.721 -8.266 19.211 1.00 25.88 H ATOM 5064 HA SER A 337 17.712 -7.637 21.272 1.00 27.99 H ATOM 5065 HB3 SER A 337 14.664 -7.951 21.296 1.00 29.04 H ATOM 5066 HB2 SER A 337 15.554 -6.443 21.309 1.00 29.04 H ATOM 5067 HG SER A 337 14.790 -7.178 23.372 1.00 32.61 H ATOM 5068 N PRO A 338 17.658 -9.931 22.578 1.00 30.07 N ATOM 5069 CA PRO A 338 17.649 -11.235 23.264 1.00 31.62 C ATOM 5070 C PRO A 338 16.479 -11.459 24.246 1.00 32.46 C ATOM 5071 O PRO A 338 16.252 -12.608 24.622 1.00 33.11 O ATOM 5072 CB PRO A 338 18.993 -11.243 24.008 1.00 30.65 C ATOM 5073 CG PRO A 338 19.242 -9.783 24.348 1.00 32.34 C ATOM 5074 CD PRO A 338 18.653 -9.031 23.162 1.00 30.98 C ATOM 5075 HA PRO A 338 17.639 -12.047 22.539 1.00 31.62 H ATOM 5076 HB3 PRO A 338 19.779 -11.612 23.350 1.00 30.65 H ATOM 5077 HB2 PRO A 338 19.001 -11.869 24.901 1.00 30.65 H ATOM 5078 HG3 PRO A 338 20.290 -9.549 24.539 1.00 32.34 H ATOM 5079 HG2 PRO A 338 18.678 -9.521 25.242 1.00 32.34 H ATOM 5080 HD2 PRO A 338 18.230 -8.078 23.479 1.00 30.98 H ATOM 5081 HD3 PRO A 338 19.414 -8.834 22.409 1.00 30.98 H ATOM 5082 N ALA A 339 15.796 -10.384 24.679 1.00 30.89 N ATOM 5083 CA ALA A 339 14.817 -10.410 25.770 1.00 29.88 C ATOM 5084 C ALA A 339 13.478 -11.059 25.385 1.00 31.52 C ATOM 5085 O ALA A 339 12.995 -10.862 24.270 1.00 27.09 O ATOM 5086 CB ALA A 339 14.592 -8.976 26.268 1.00 31.10 C ATOM 5087 H ALA A 339 16.020 -9.470 24.309 1.00 30.89 H ATOM 5088 HA ALA A 339 15.253 -10.985 26.590 1.00 29.88 H ATOM 5089 HB1 ALA A 339 13.924 -8.954 27.129 1.00 31.10 H ATOM 5090 HB2 ALA A 339 15.531 -8.512 26.572 1.00 31.10 H ATOM 5091 HB3 ALA A 339 14.154 -8.349 25.494 1.00 31.10 H ATOM 5092 N SER A 340 12.893 -11.791 26.348 1.00 31.98 N ATOM 5093 CA SER A 340 11.622 -12.516 26.238 1.00 34.26 C ATOM 5094 C SER A 340 10.394 -11.650 25.894 1.00 34.39 C ATOM 5095 O SER A 340 9.469 -12.153 25.256 1.00 35.26 O ATOM 5096 CB SER A 340 11.413 -13.321 27.535 1.00 34.41 C ATOM 5097 OG SER A 340 11.082 -12.502 28.641 1.00 35.04 O ATOM 5098 H SER A 340 13.360 -11.883 27.239 1.00 31.98 H ATOM 5099 HA SER A 340 11.743 -13.233 25.427 1.00 34.26 H ATOM 5100 HB3 SER A 340 12.316 -13.879 27.777 1.00 34.41 H ATOM 5101 HB2 SER A 340 10.617 -14.054 27.398 1.00 34.41 H ATOM 5102 HG SER A 340 10.189 -12.168 28.521 1.00 35.04 H ATOM 5103 N LEU A 341 10.421 -10.371 26.305 1.00 35.73 N ATOM 5104 CA LEU A 341 9.390 -9.361 26.045 1.00 37.29 C ATOM 5105 C LEU A 341 9.254 -8.984 24.558 1.00 36.72 C ATOM 5106 O LEU A 341 8.204 -8.476 24.163 1.00 36.23 O ATOM 5107 CB LEU A 341 9.729 -8.094 26.862 1.00 41.08 C ATOM 5108 CG LEU A 341 9.662 -8.271 28.396 1.00 46.36 C ATOM 5109 CD1 LEU A 341 10.236 -7.035 29.119 1.00 46.09 C ATOM 5110 CD2 LEU A 341 8.241 -8.625 28.883 1.00 46.76 C ATOM 5111 H LEU A 341 11.225 -10.048 26.824 1.00 35.73 H ATOM 5112 HA LEU A 341 8.429 -9.764 26.365 1.00 37.29 H ATOM 5113 HB3 LEU A 341 9.056 -7.281 26.583 1.00 41.08 H ATOM 5114 HB2 LEU A 341 10.728 -7.758 26.579 1.00 41.08 H ATOM 5115 HG LEU A 341 10.314 -9.105 28.661 1.00 46.36 H ATOM 5116 HD11 LEU A 341 10.936 -7.335 29.901 1.00 46.09 H ATOM 5117 HD12 LEU A 341 10.780 -6.377 28.440 1.00 46.09 H ATOM 5118 HD13 LEU A 341 9.462 -6.429 29.590 1.00 46.09 H ATOM 5119 HD21 LEU A 341 7.937 -8.041 29.752 1.00 46.76 H ATOM 5120 HD22 LEU A 341 7.490 -8.459 28.110 1.00 46.76 H ATOM 5121 HD23 LEU A 341 8.185 -9.675 29.171 1.00 46.76 H ATOM 5122 N ASN A 342 10.316 -9.227 23.776 1.00 33.70 N ATOM 5123 CA ASN A 342 10.427 -8.851 22.369 1.00 33.45 C ATOM 5124 C ASN A 342 10.262 -10.054 21.427 1.00 33.28 C ATOM 5125 O ASN A 342 10.554 -9.897 20.245 1.00 31.23 O ATOM 5126 CB ASN A 342 11.779 -8.136 22.130 1.00 34.11 C ATOM 5127 CG ASN A 342 12.017 -6.929 23.046 1.00 35.86 C ATOM 5128 OD1 ASN A 342 12.997 -6.893 23.782 1.00 37.36 O ATOM 5129 ND2 ASN A 342 11.125 -5.939 23.021 1.00 39.01 N ATOM 5130 H ASN A 342 11.134 -9.666 24.178 1.00 33.70 H ATOM 5131 HA ASN A 342 9.627 -8.170 22.080 1.00 33.45 H ATOM 5132 HB3 ASN A 342 11.852 -7.793 21.099 1.00 34.11 H ATOM 5133 HB2 ASN A 342 12.598 -8.843 22.271 1.00 34.11 H ATOM 5134 HD22 ASN A 342 11.256 -5.129 23.609 1.00 39.01 H ATOM 5135 HD21 ASN A 342 10.298 -6.000 22.443 1.00 39.01 H ATOM 5136 N LEU A 343 9.791 -11.209 21.939 1.00 32.73 N ATOM 5137 CA LEU A 343 9.600 -12.474 21.216 1.00 31.59 C ATOM 5138 C LEU A 343 8.869 -12.338 19.870 1.00 31.46 C ATOM 5139 O LEU A 343 9.404 -12.795 18.863 1.00 31.83 O ATOM 5140 CB LEU A 343 8.906 -13.497 22.150 1.00 31.98 C ATOM 5141 CG LEU A 343 8.491 -14.860 21.533 1.00 32.11 C ATOM 5142 CD1 LEU A 343 9.664 -15.621 20.892 1.00 31.95 C ATOM 5143 CD2 LEU A 343 7.759 -15.739 22.565 1.00 37.07 C ATOM 5144 H LEU A 343 9.558 -11.238 22.922 1.00 32.73 H ATOM 5145 HA LEU A 343 10.604 -12.840 20.998 1.00 31.59 H ATOM 5146 HB3 LEU A 343 8.012 -13.029 22.565 1.00 31.98 H ATOM 5147 HB2 LEU A 343 9.557 -13.686 23.004 1.00 31.98 H ATOM 5148 HG LEU A 343 7.767 -14.660 20.743 1.00 32.11 H ATOM 5149 HD11 LEU A 343 9.305 -16.462 20.300 1.00 31.95 H ATOM 5150 HD12 LEU A 343 10.257 -14.991 20.231 1.00 31.95 H ATOM 5151 HD13 LEU A 343 10.335 -16.021 21.647 1.00 31.95 H ATOM 5152 HD21 LEU A 343 6.801 -16.084 22.174 1.00 37.07 H ATOM 5153 HD22 LEU A 343 8.337 -16.621 22.838 1.00 37.07 H ATOM 5154 HD23 LEU A 343 7.554 -15.199 23.490 1.00 37.07 H ATOM 5155 N GLU A 344 7.684 -11.703 19.875 1.00 32.34 N ATOM 5156 CA GLU A 344 6.853 -11.503 18.686 1.00 30.85 C ATOM 5157 C GLU A 344 7.560 -10.700 17.578 1.00 28.00 C ATOM 5158 O GLU A 344 7.491 -11.098 16.416 1.00 28.52 O ATOM 5159 CB GLU A 344 5.503 -10.883 19.105 1.00 33.98 C ATOM 5160 CG GLU A 344 4.516 -10.626 17.938 1.00 42.77 C ATOM 5161 CD GLU A 344 3.134 -10.090 18.346 1.00 47.25 C ATOM 5162 OE1 GLU A 344 2.268 -10.053 17.443 1.00 48.91 O ATOM 5163 OE2 GLU A 344 2.947 -9.717 19.527 1.00 49.27 O1- ATOM 5164 H GLU A 344 7.318 -11.337 20.745 1.00 32.34 H ATOM 5165 HA GLU A 344 6.644 -12.494 18.278 1.00 30.85 H ATOM 5166 HB3 GLU A 344 5.691 -9.947 19.635 1.00 33.98 H ATOM 5167 HB2 GLU A 344 5.029 -11.549 19.828 1.00 33.98 H ATOM 5168 HG3 GLU A 344 4.377 -11.553 17.380 1.00 42.77 H ATOM 5169 HG2 GLU A 344 4.942 -9.905 17.239 1.00 42.77 H ATOM 5170 N GLU A 345 8.252 -9.617 17.970 1.00 25.97 N ATOM 5171 CA GLU A 345 8.998 -8.749 17.059 1.00 27.03 C ATOM 5172 C GLU A 345 10.326 -9.344 16.580 1.00 26.23 C ATOM 5173 O GLU A 345 10.704 -9.108 15.435 1.00 23.96 O ATOM 5174 CB GLU A 345 9.219 -7.366 17.704 1.00 27.74 C ATOM 5175 CG GLU A 345 7.931 -6.605 18.094 1.00 31.24 C ATOM 5176 CD GLU A 345 6.999 -6.187 16.946 1.00 33.29 C ATOM 5177 OE1 GLU A 345 5.950 -5.599 17.283 1.00 35.69 O ATOM 5178 OE2 GLU A 345 7.323 -6.421 15.760 1.00 35.01 O1- ATOM 5179 H GLU A 345 8.278 -9.368 18.948 1.00 25.97 H ATOM 5180 HA GLU A 345 8.395 -8.643 16.161 1.00 27.03 H ATOM 5181 HB3 GLU A 345 9.821 -6.740 17.043 1.00 27.74 H ATOM 5182 HB2 GLU A 345 9.818 -7.495 18.606 1.00 27.74 H ATOM 5183 HG3 GLU A 345 8.213 -5.696 18.624 1.00 31.24 H ATOM 5184 HG2 GLU A 345 7.357 -7.196 18.809 1.00 31.24 H ATOM 5185 N THR A 346 10.992 -10.133 17.435 1.00 25.10 N ATOM 5186 CA THR A 346 12.191 -10.889 17.085 1.00 25.31 C ATOM 5187 C THR A 346 11.876 -11.987 16.053 1.00 26.27 C ATOM 5188 O THR A 346 12.596 -12.070 15.064 1.00 25.60 O ATOM 5189 CB THR A 346 12.841 -11.524 18.339 1.00 24.58 C ATOM 5190 OG1 THR A 346 13.329 -10.480 19.153 1.00 20.56 O ATOM 5191 CG2 THR A 346 14.004 -12.499 18.087 1.00 23.70 C ATOM 5192 H THR A 346 10.649 -10.254 18.380 1.00 25.10 H ATOM 5193 HA THR A 346 12.908 -10.197 16.635 1.00 25.31 H ATOM 5194 HB THR A 346 12.079 -12.047 18.920 1.00 24.58 H ATOM 5195 HG1 THR A 346 13.567 -10.859 20.008 1.00 20.56 H ATOM 5196 HG21 THR A 346 14.502 -12.770 19.018 1.00 23.70 H ATOM 5197 HG22 THR A 346 13.653 -13.426 17.636 1.00 23.70 H ATOM 5198 HG23 THR A 346 14.751 -12.062 17.424 1.00 23.70 H ATOM 5199 N LEU A 347 10.775 -12.739 16.246 1.00 25.55 N ATOM 5200 CA LEU A 347 10.278 -13.718 15.274 1.00 27.06 C ATOM 5201 C LEU A 347 9.847 -13.071 13.949 1.00 26.24 C ATOM 5202 O LEU A 347 10.187 -13.618 12.903 1.00 22.77 O ATOM 5203 CB LEU A 347 9.115 -14.548 15.862 1.00 29.01 C ATOM 5204 CG LEU A 347 9.513 -15.536 16.978 1.00 31.73 C ATOM 5205 CD1 LEU A 347 8.254 -16.211 17.562 1.00 34.42 C ATOM 5206 CD2 LEU A 347 10.555 -16.569 16.505 1.00 33.31 C ATOM 5207 H LEU A 347 10.216 -12.610 17.080 1.00 25.55 H ATOM 5208 HA LEU A 347 11.105 -14.390 15.037 1.00 27.06 H ATOM 5209 HB3 LEU A 347 8.641 -15.118 15.061 1.00 29.01 H ATOM 5210 HB2 LEU A 347 8.347 -13.869 16.237 1.00 29.01 H ATOM 5211 HG LEU A 347 9.984 -14.983 17.788 1.00 31.73 H ATOM 5212 HD11 LEU A 347 8.416 -17.258 17.818 1.00 34.42 H ATOM 5213 HD12 LEU A 347 7.937 -15.701 18.471 1.00 34.42 H ATOM 5214 HD13 LEU A 347 7.414 -16.175 16.868 1.00 34.42 H ATOM 5215 HD21 LEU A 347 10.474 -17.520 17.030 1.00 33.31 H ATOM 5216 HD22 LEU A 347 10.464 -16.771 15.438 1.00 33.31 H ATOM 5217 HD23 LEU A 347 11.566 -16.202 16.679 1.00 33.31 H ATOM 5218 N SER A 348 9.157 -11.916 14.006 1.00 25.08 N ATOM 5219 CA SER A 348 8.751 -11.138 12.831 1.00 25.81 C ATOM 5220 C SER A 348 9.954 -10.669 11.989 1.00 25.76 C ATOM 5221 O SER A 348 9.922 -10.822 10.769 1.00 26.65 O ATOM 5222 CB SER A 348 7.854 -9.959 13.265 1.00 27.51 C ATOM 5223 OG SER A 348 7.412 -9.202 12.155 1.00 31.87 O ATOM 5224 H SER A 348 8.897 -11.532 14.906 1.00 25.08 H ATOM 5225 HA SER A 348 8.151 -11.798 12.202 1.00 25.81 H ATOM 5226 HB3 SER A 348 8.387 -9.297 13.946 1.00 27.51 H ATOM 5227 HB2 SER A 348 6.977 -10.326 13.799 1.00 27.51 H ATOM 5228 HG SER A 348 6.989 -8.396 12.475 1.00 31.87 H ATOM 5229 N THR A 349 11.003 -10.163 12.660 1.00 24.55 N ATOM 5230 CA THR A 349 12.247 -9.724 12.031 1.00 23.43 C ATOM 5231 C THR A 349 13.052 -10.879 11.410 1.00 24.65 C ATOM 5232 O THR A 349 13.573 -10.697 10.312 1.00 23.30 O ATOM 5233 CB THR A 349 13.139 -8.939 13.030 1.00 24.23 C ATOM 5234 OG1 THR A 349 12.512 -7.695 13.268 1.00 21.82 O ATOM 5235 CG2 THR A 349 14.592 -8.659 12.595 1.00 22.09 C ATOM 5236 H THR A 349 10.949 -10.059 13.665 1.00 24.55 H ATOM 5237 HA THR A 349 11.964 -9.061 11.215 1.00 23.43 H ATOM 5238 HB THR A 349 13.169 -9.469 13.983 1.00 24.23 H ATOM 5239 HG1 THR A 349 11.669 -7.850 13.708 1.00 21.82 H ATOM 5240 HG21 THR A 349 15.081 -7.968 13.280 1.00 22.09 H ATOM 5241 HG22 THR A 349 15.195 -9.568 12.582 1.00 22.09 H ATOM 5242 HG23 THR A 349 14.630 -8.216 11.601 1.00 22.09 H ATOM 5243 N LEU A 350 13.109 -12.041 12.084 1.00 25.56 N ATOM 5244 CA LEU A 350 13.788 -13.237 11.584 1.00 27.20 C ATOM 5245 C LEU A 350 13.072 -13.869 10.381 1.00 27.84 C ATOM 5246 O LEU A 350 13.756 -14.253 9.437 1.00 27.94 O ATOM 5247 CB LEU A 350 13.974 -14.263 12.718 1.00 26.67 C ATOM 5248 CG LEU A 350 14.993 -13.826 13.793 1.00 28.29 C ATOM 5249 CD1 LEU A 350 14.977 -14.792 14.987 1.00 28.78 C ATOM 5250 CD2 LEU A 350 16.412 -13.625 13.243 1.00 27.19 C ATOM 5251 H LEU A 350 12.660 -12.122 12.987 1.00 25.56 H ATOM 5252 HA LEU A 350 14.774 -12.932 11.228 1.00 27.20 H ATOM 5253 HB3 LEU A 350 14.302 -15.218 12.304 1.00 26.67 H ATOM 5254 HB2 LEU A 350 13.004 -14.458 13.180 1.00 26.67 H ATOM 5255 HG LEU A 350 14.691 -12.855 14.175 1.00 28.29 H ATOM 5256 HD11 LEU A 350 15.048 -14.239 15.922 1.00 28.78 H ATOM 5257 HD12 LEU A 350 14.062 -15.384 15.020 1.00 28.78 H ATOM 5258 HD13 LEU A 350 15.810 -15.494 14.961 1.00 28.78 H ATOM 5259 HD21 LEU A 350 17.171 -13.922 13.964 1.00 27.19 H ATOM 5260 HD22 LEU A 350 16.574 -14.193 12.328 1.00 27.19 H ATOM 5261 HD23 LEU A 350 16.593 -12.574 13.014 1.00 27.19 H ATOM 5262 N GLU A 351 11.729 -13.918 10.405 1.00 29.78 N ATOM 5263 CA GLU A 351 10.897 -14.351 9.279 1.00 31.65 C ATOM 5264 C GLU A 351 11.052 -13.447 8.047 1.00 31.57 C ATOM 5265 O GLU A 351 11.253 -13.967 6.952 1.00 32.81 O ATOM 5266 CB GLU A 351 9.415 -14.442 9.706 1.00 34.82 C ATOM 5267 CG GLU A 351 9.089 -15.628 10.644 1.00 41.40 C ATOM 5268 CD GLU A 351 9.012 -17.019 9.990 1.00 44.64 C ATOM 5269 OE1 GLU A 351 8.808 -17.977 10.768 1.00 46.61 O ATOM 5270 OE2 GLU A 351 9.166 -17.130 8.752 1.00 43.42 O1- ATOM 5271 H GLU A 351 11.231 -13.603 11.229 1.00 29.78 H ATOM 5272 HA GLU A 351 11.241 -15.345 8.987 1.00 31.65 H ATOM 5273 HB3 GLU A 351 8.760 -14.465 8.833 1.00 34.82 H ATOM 5274 HB2 GLU A 351 9.146 -13.523 10.228 1.00 34.82 H ATOM 5275 HG3 GLU A 351 8.128 -15.437 11.124 1.00 41.40 H ATOM 5276 HG2 GLU A 351 9.823 -15.674 11.447 1.00 41.40 H ATOM 5277 N TYR A 352 11.003 -12.121 8.257 1.00 31.02 N ATOM 5278 CA TYR A 352 11.183 -11.096 7.226 1.00 29.54 C ATOM 5279 C TYR A 352 12.561 -11.175 6.549 1.00 30.19 C ATOM 5280 O TYR A 352 12.638 -11.172 5.320 1.00 29.15 O ATOM 5281 CB TYR A 352 10.941 -9.712 7.861 1.00 31.28 C ATOM 5282 CG TYR A 352 10.909 -8.538 6.899 1.00 31.74 C ATOM 5283 CD1 TYR A 352 12.105 -7.957 6.423 1.00 32.52 C ATOM 5284 CD2 TYR A 352 9.666 -7.997 6.508 1.00 34.47 C ATOM 5285 CE1 TYR A 352 12.057 -6.833 5.578 1.00 34.85 C ATOM 5286 CE2 TYR A 352 9.619 -6.861 5.679 1.00 34.55 C ATOM 5287 CZ TYR A 352 10.814 -6.273 5.225 1.00 34.94 C ATOM 5288 OH TYR A 352 10.764 -5.148 4.458 1.00 38.19 O ATOM 5289 H TYR A 352 10.828 -11.777 9.193 1.00 31.02 H ATOM 5290 HA TYR A 352 10.422 -11.259 6.461 1.00 29.54 H ATOM 5291 HB3 TYR A 352 11.686 -9.508 8.630 1.00 31.28 H ATOM 5292 HB2 TYR A 352 9.983 -9.726 8.383 1.00 31.28 H ATOM 5293 HD1 TYR A 352 13.063 -8.353 6.724 1.00 32.52 H ATOM 5294 HD2 TYR A 352 8.745 -8.431 6.867 1.00 34.47 H ATOM 5295 HE1 TYR A 352 12.977 -6.384 5.232 1.00 34.85 H ATOM 5296 HE2 TYR A 352 8.666 -6.434 5.408 1.00 34.55 H ATOM 5297 HH TYR A 352 11.632 -4.825 4.208 1.00 38.19 H ATOM 5298 N ALA A 353 13.613 -11.259 7.380 1.00 27.84 N ATOM 5299 CA ALA A 353 15.006 -11.392 6.971 1.00 29.40 C ATOM 5300 C ALA A 353 15.267 -12.694 6.196 1.00 30.72 C ATOM 5301 O ALA A 353 15.927 -12.648 5.161 1.00 30.09 O ATOM 5302 CB ALA A 353 15.882 -11.289 8.228 1.00 27.70 C ATOM 5303 H ALA A 353 13.452 -11.242 8.379 1.00 27.84 H ATOM 5304 HA ALA A 353 15.244 -10.552 6.315 1.00 29.40 H ATOM 5305 HB1 ALA A 353 16.944 -11.308 7.999 1.00 27.70 H ATOM 5306 HB2 ALA A 353 15.690 -10.351 8.749 1.00 27.70 H ATOM 5307 HB3 ALA A 353 15.681 -12.101 8.928 1.00 27.70 H ATOM 5308 N HIS A 354 14.709 -13.816 6.684 1.00 33.52 N ATOM 5309 CA HIS A 354 14.829 -15.146 6.081 1.00 36.23 C ATOM 5310 C HIS A 354 14.273 -15.219 4.648 1.00 36.11 C ATOM 5311 O HIS A 354 14.891 -15.860 3.800 1.00 35.43 O ATOM 5312 CB HIS A 354 14.171 -16.190 7.008 1.00 39.61 C ATOM 5313 CG HIS A 354 14.169 -17.595 6.464 1.00 43.40 C ATOM 5314 ND1 HIS A 354 13.043 -18.192 5.920 1.00 45.98 N ATOM 5315 CD2 HIS A 354 15.174 -18.530 6.362 1.00 45.87 C ATOM 5316 CE1 HIS A 354 13.408 -19.407 5.506 1.00 46.42 C ATOM 5317 NE2 HIS A 354 14.687 -19.680 5.739 1.00 47.89 N ATOM 5318 H HIS A 354 14.176 -13.770 7.543 1.00 33.52 H ATOM 5319 HA HIS A 354 15.893 -15.380 6.021 1.00 36.23 H ATOM 5320 HB3 HIS A 354 13.144 -15.904 7.235 1.00 39.61 H ATOM 5321 HB2 HIS A 354 14.701 -16.216 7.961 1.00 39.61 H ATOM 5322 HD1 HIS A 354 12.122 -17.784 5.848 1.00 45.98 H ATOM 5323 HD2 HIS A 354 16.207 -18.456 6.670 1.00 45.87 H ATOM 5324 HE1 HIS A 354 12.730 -20.102 5.032 1.00 46.42 H ATOM 5325 N ARG A 355 13.143 -14.537 4.402 1.00 36.76 N ATOM 5326 CA ARG A 355 12.517 -14.414 3.086 1.00 38.68 C ATOM 5327 C ARG A 355 13.401 -13.656 2.087 1.00 37.05 C ATOM 5328 O ARG A 355 13.551 -14.125 0.961 1.00 37.00 O ATOM 5329 CB ARG A 355 11.158 -13.712 3.231 1.00 42.28 C ATOM 5330 CG ARG A 355 10.110 -14.551 3.984 1.00 47.63 C ATOM 5331 CD ARG A 355 8.919 -13.729 4.514 1.00 52.45 C ATOM 5332 NE ARG A 355 8.232 -12.974 3.451 1.00 57.27 N ATOM 5333 CZ ARG A 355 7.507 -13.472 2.432 1.00 59.95 C ATOM 5334 NH1 ARG A 355 7.277 -14.783 2.267 1.00 61.16 N ATOM 5335 NH2 ARG A 355 6.986 -12.630 1.539 1.00 59.95 N1+ ATOM 5336 H ARG A 355 12.695 -14.036 5.158 1.00 36.76 H ATOM 5337 HA ARG A 355 12.352 -15.418 2.688 1.00 38.68 H ATOM 5338 HB3 ARG A 355 10.762 -13.487 2.239 1.00 42.28 H ATOM 5339 HB2 ARG A 355 11.291 -12.749 3.725 1.00 42.28 H ATOM 5340 HG3 ARG A 355 10.586 -15.024 4.839 1.00 47.63 H ATOM 5341 HG2 ARG A 355 9.776 -15.392 3.378 1.00 47.63 H ATOM 5342 HD3 ARG A 355 9.230 -13.064 5.319 1.00 52.45 H ATOM 5343 HD2 ARG A 355 8.187 -14.406 4.955 1.00 52.45 H ATOM 5344 HE ARG A 355 8.369 -11.974 3.483 1.00 57.27 H ATOM 5345 HH12 ARG A 355 6.718 -15.114 1.494 1.00 61.16 H ATOM 5346 HH11 ARG A 355 7.646 -15.447 2.932 1.00 61.16 H ATOM 5347 HH22 ARG A 355 6.427 -12.984 0.775 1.00 59.95 H ATOM 5348 HH21 ARG A 355 7.088 -11.629 1.640 1.00 59.95 H ATOM 5349 N ALA A 356 13.994 -12.531 2.528 1.00 35.18 N ATOM 5350 CA ALA A 356 14.840 -11.652 1.719 1.00 33.47 C ATOM 5351 C ALA A 356 16.122 -12.299 1.155 1.00 34.33 C ATOM 5352 O ALA A 356 16.671 -11.759 0.196 1.00 32.89 O ATOM 5353 CB ALA A 356 15.169 -10.392 2.530 1.00 31.30 C ATOM 5354 H ALA A 356 13.837 -12.235 3.482 1.00 35.18 H ATOM 5355 HA ALA A 356 14.239 -11.344 0.861 1.00 33.47 H ATOM 5356 HB1 ALA A 356 15.697 -9.665 1.913 1.00 31.30 H ATOM 5357 HB2 ALA A 356 14.260 -9.909 2.892 1.00 31.30 H ATOM 5358 HB3 ALA A 356 15.793 -10.619 3.394 1.00 31.30 H ATOM 5359 N LYS A 357 16.542 -13.454 1.707 1.00 34.54 N ATOM 5360 CA LYS A 357 17.620 -14.300 1.182 1.00 38.30 C ATOM 5361 C LYS A 357 17.369 -14.808 -0.252 1.00 40.22 C ATOM 5362 O LYS A 357 18.329 -14.975 -1.002 1.00 40.04 O ATOM 5363 CB LYS A 357 17.807 -15.533 2.085 1.00 38.47 C ATOM 5364 CG LYS A 357 18.277 -15.247 3.521 1.00 39.23 C ATOM 5365 CD LYS A 357 18.350 -16.526 4.374 1.00 41.33 C ATOM 5366 CE LYS A 357 19.476 -17.487 3.943 1.00 42.15 C ATOM 5367 NZ LYS A 357 19.315 -18.824 4.536 1.00 41.28 N1+ ATOM 5368 H LYS A 357 16.036 -13.828 2.497 1.00 34.54 H ATOM 5369 HA LYS A 357 18.540 -13.714 1.182 1.00 38.30 H ATOM 5370 HB3 LYS A 357 18.539 -16.183 1.606 1.00 38.47 H ATOM 5371 HB2 LYS A 357 16.878 -16.104 2.112 1.00 38.47 H ATOM 5372 HG3 LYS A 357 17.600 -14.541 4.001 1.00 39.23 H ATOM 5373 HG2 LYS A 357 19.256 -14.769 3.492 1.00 39.23 H ATOM 5374 HD3 LYS A 357 17.383 -17.032 4.329 1.00 41.33 H ATOM 5375 HD2 LYS A 357 18.487 -16.248 5.420 1.00 41.33 H ATOM 5376 HE3 LYS A 357 20.448 -17.078 4.222 1.00 42.15 H ATOM 5377 HE2 LYS A 357 19.495 -17.633 2.866 1.00 42.15 H ATOM 5378 HZ1 LYS A 357 18.442 -19.226 4.225 1.00 41.28 H ATOM 5379 HZ2 LYS A 357 20.081 -19.417 4.251 1.00 41.28 H ATOM 5380 HZ3 LYS A 357 19.302 -18.745 5.545 1.00 41.28 H ATOM 5381 N ASN A 358 16.092 -15.061 -0.589 1.00 41.32 N ATOM 5382 CA ASN A 358 15.650 -15.622 -1.871 1.00 42.57 C ATOM 5383 C ASN A 358 15.533 -14.572 -2.994 1.00 43.12 C ATOM 5384 O ASN A 358 15.154 -14.949 -4.103 1.00 44.49 O ATOM 5385 CB ASN A 358 14.309 -16.374 -1.669 1.00 45.39 C ATOM 5386 CG ASN A 358 14.402 -17.633 -0.795 1.00 48.23 C ATOM 5387 OD1 ASN A 358 15.486 -18.106 -0.459 1.00 51.21 O ATOM 5388 ND2 ASN A 358 13.247 -18.198 -0.441 1.00 48.45 N ATOM 5389 H ASN A 358 15.361 -14.884 0.088 1.00 41.32 H ATOM 5390 HA ASN A 358 16.405 -16.345 -2.187 1.00 42.57 H ATOM 5391 HB3 ASN A 358 13.921 -16.708 -2.632 1.00 45.39 H ATOM 5392 HB2 ASN A 358 13.557 -15.703 -1.253 1.00 45.39 H ATOM 5393 HD22 ASN A 358 13.249 -19.033 0.126 1.00 48.45 H ATOM 5394 HD21 ASN A 358 12.367 -17.799 -0.735 1.00 48.45 H ATOM 5395 N ILE A 359 15.870 -13.298 -2.724 1.00 41.07 N ATOM 5396 CA ILE A 359 15.922 -12.247 -3.742 1.00 40.73 C ATOM 5397 C ILE A 359 17.249 -12.346 -4.515 1.00 41.82 C ATOM 5398 O ILE A 359 18.304 -12.456 -3.893 1.00 42.57 O ATOM 5399 CB ILE A 359 15.808 -10.820 -3.132 1.00 40.12 C ATOM 5400 CG1 ILE A 359 14.491 -10.680 -2.342 1.00 40.44 C ATOM 5401 CG2 ILE A 359 15.912 -9.700 -4.197 1.00 39.64 C ATOM 5402 CD1 ILE A 359 14.395 -9.422 -1.478 1.00 41.20 C ATOM 5403 H ILE A 359 16.188 -13.046 -1.799 1.00 41.07 H ATOM 5404 HA ILE A 359 15.089 -12.384 -4.434 1.00 40.73 H ATOM 5405 HB ILE A 359 16.629 -10.691 -2.426 1.00 40.12 H ATOM 5406 HG13 ILE A 359 14.369 -11.526 -1.668 1.00 40.44 H ATOM 5407 HG12 ILE A 359 13.644 -10.718 -3.026 1.00 40.44 H ATOM 5408 HG21 ILE A 359 15.784 -8.708 -3.769 1.00 39.64 H ATOM 5409 HG22 ILE A 359 16.881 -9.688 -4.691 1.00 39.64 H ATOM 5410 HG23 ILE A 359 15.152 -9.819 -4.970 1.00 39.64 H ATOM 5411 HD11 ILE A 359 13.471 -9.461 -0.913 1.00 41.20 H ATOM 5412 HD12 ILE A 359 15.216 -9.362 -0.764 1.00 41.20 H ATOM 5413 HD13 ILE A 359 14.376 -8.506 -2.067 1.00 41.20 H ATOM 5414 N LEU A 360 17.148 -12.289 -5.851 1.00 42.09 N ATOM 5415 CA LEU A 360 18.259 -12.379 -6.793 1.00 44.36 C ATOM 5416 C LEU A 360 18.584 -10.983 -7.347 1.00 43.24 C ATOM 5417 O LEU A 360 17.731 -10.392 -8.009 1.00 43.73 O ATOM 5418 CB LEU A 360 17.838 -13.359 -7.916 1.00 47.52 C ATOM 5419 CG LEU A 360 18.827 -13.511 -9.095 1.00 50.60 C ATOM 5420 CD1 LEU A 360 20.160 -14.139 -8.649 1.00 52.74 C ATOM 5421 CD2 LEU A 360 18.178 -14.305 -10.241 1.00 52.55 C ATOM 5422 H LEU A 360 16.232 -12.178 -6.268 1.00 42.09 H ATOM 5423 HA LEU A 360 19.144 -12.779 -6.296 1.00 44.36 H ATOM 5424 HB3 LEU A 360 16.879 -13.029 -8.320 1.00 47.52 H ATOM 5425 HB2 LEU A 360 17.647 -14.341 -7.479 1.00 47.52 H ATOM 5426 HG LEU A 360 19.053 -12.529 -9.510 1.00 50.60 H ATOM 5427 HD11 LEU A 360 20.456 -14.983 -9.272 1.00 52.74 H ATOM 5428 HD12 LEU A 360 20.959 -13.402 -8.693 1.00 52.74 H ATOM 5429 HD13 LEU A 360 20.120 -14.502 -7.622 1.00 52.74 H ATOM 5430 HD21 LEU A 360 18.918 -14.645 -10.967 1.00 52.55 H ATOM 5431 HD22 LEU A 360 17.650 -15.184 -9.870 1.00 52.55 H ATOM 5432 HD23 LEU A 360 17.458 -13.689 -10.780 1.00 52.55 H ATOM 5433 N ASN A 361 19.826 -10.525 -7.120 1.00 42.13 N ATOM 5434 CA ASN A 361 20.409 -9.317 -7.721 1.00 44.33 C ATOM 5435 C ASN A 361 21.481 -9.727 -8.753 1.00 45.70 C ATOM 5436 O ASN A 361 21.829 -10.904 -8.863 1.00 46.71 O ATOM 5437 CB ASN A 361 21.000 -8.406 -6.611 1.00 42.58 C ATOM 5438 CG ASN A 361 19.954 -7.713 -5.722 1.00 42.14 C ATOM 5439 OD1 ASN A 361 18.849 -8.206 -5.519 1.00 39.55 O ATOM 5440 ND2 ASN A 361 20.302 -6.554 -5.167 1.00 40.89 N ATOM 5441 H ASN A 361 20.470 -11.086 -6.578 1.00 42.13 H ATOM 5442 HA ASN A 361 19.623 -8.764 -8.240 1.00 44.33 H ATOM 5443 HB3 ASN A 361 21.589 -7.613 -7.074 1.00 42.58 H ATOM 5444 HB2 ASN A 361 21.690 -8.964 -5.978 1.00 42.58 H ATOM 5445 HD22 ASN A 361 19.656 -6.060 -4.566 1.00 40.89 H ATOM 5446 HD21 ASN A 361 21.210 -6.144 -5.357 1.00 40.89 H ATOM 5447 N LYS A 362 21.952 -8.738 -9.527 1.00 46.44 N ATOM 5448 CA LYS A 362 22.835 -8.915 -10.684 1.00 48.00 C ATOM 5449 C LYS A 362 24.015 -7.925 -10.624 1.00 47.90 C ATOM 5450 O LYS A 362 24.285 -7.235 -11.609 1.00 48.26 O ATOM 5451 CB LYS A 362 21.999 -8.754 -11.976 1.00 48.16 C ATOM 5452 CG LYS A 362 20.896 -9.814 -12.162 1.00 50.94 C ATOM 5453 CD LYS A 362 20.050 -9.600 -13.427 1.00 53.33 C ATOM 5454 CE LYS A 362 19.194 -8.321 -13.372 1.00 55.16 C ATOM 5455 NZ LYS A 362 18.323 -8.195 -14.553 1.00 55.37 N1+ ATOM 5456 H LYS A 362 21.599 -7.799 -9.388 1.00 46.44 H ATOM 5457 HA LYS A 362 23.276 -9.914 -10.680 1.00 48.00 H ATOM 5458 HB3 LYS A 362 22.656 -8.802 -12.846 1.00 48.16 H ATOM 5459 HB2 LYS A 362 21.562 -7.756 -11.977 1.00 48.16 H ATOM 5460 HG3 LYS A 362 20.227 -9.826 -11.302 1.00 50.94 H ATOM 5461 HG2 LYS A 362 21.355 -10.803 -12.199 1.00 50.94 H ATOM 5462 HD3 LYS A 362 19.409 -10.471 -13.565 1.00 53.33 H ATOM 5463 HD2 LYS A 362 20.709 -9.569 -14.297 1.00 53.33 H ATOM 5464 HE3 LYS A 362 19.817 -7.429 -13.320 1.00 55.16 H ATOM 5465 HE2 LYS A 362 18.567 -8.327 -12.480 1.00 55.16 H ATOM 5466 HZ1 LYS A 362 17.768 -7.355 -14.460 1.00 55.37 H ATOM 5467 HZ2 LYS A 362 18.883 -8.146 -15.391 1.00 55.37 H ATOM 5468 HZ3 LYS A 362 17.708 -8.995 -14.604 1.00 55.37 H HETATM 5469 N NME A 363 24.687 -7.866 -9.462 1.00 0.00 N HETATM 5470 C NME A 363 25.822 -6.985 -9.210 1.00 0.00 C HETATM 5471 H NME A 363 24.395 -8.463 -8.702 1.00 0.00 H HETATM 5472 H1 NME A 363 26.066 -6.336 -10.052 1.00 0.00 H HETATM 5473 H2 NME A 363 25.607 -6.348 -8.351 1.00 0.00 H HETATM 5474 H3 NME A 363 26.705 -7.577 -8.974 1.00 0.00 H TER 5475 NME A 363 HETATM 5476 O HOH A 372 14.127 2.495 15.237 1.00 20.25 O HETATM 5477 H1 HOH A 372 13.297 2.286 15.760 1.00 20.25 H HETATM 5478 H2 HOH A 372 14.921 2.463 15.861 1.00 20.25 H HETATM 5479 O HOH A 377 22.168 -5.652 17.068 1.00 24.29 O HETATM 5480 H1 HOH A 377 21.799 -6.550 16.818 1.00 24.29 H HETATM 5481 H2 HOH A 377 21.449 -5.112 17.515 1.00 24.29 H HETATM 5482 O HOH A 395 14.808 3.792 12.670 1.00 27.35 O HETATM 5483 H1 HOH A 395 15.161 3.112 12.024 1.00 27.35 H HETATM 5484 H2 HOH A 395 14.745 3.389 13.587 1.00 27.35 H HETATM 5485 O HOH A 419 26.199 -7.665 18.971 1.00 30.83 O HETATM 5486 H1 HOH A 419 25.560 -8.426 19.111 1.00 30.83 H HETATM 5487 H2 HOH A 419 26.576 -7.383 19.855 1.00 30.83 H HETATM 5488 O HOH A 468 30.820 15.098 19.149 1.00 67.44 O HETATM 5489 H1 HOH A 468 29.991 15.360 19.644 1.00 67.44 H HETATM 5490 H2 HOH A 468 31.104 15.865 18.563 1.00 67.44 H HETATM 5491 O HOH A 484 27.842 -6.299 21.160 1.00 38.37 O HETATM 5492 H1 HOH A 484 28.606 -6.492 20.537 1.00 38.37 H HETATM 5493 H2 HOH A 484 27.781 -7.031 21.842 1.00 38.37 H HETATM 5494 O HOH A 499 22.332 5.193 9.602 1.00 41.21 O HETATM 5495 H1 HOH A 499 22.732 5.985 10.074 1.00 41.21 H HETATM 5496 H2 HOH A 499 21.557 4.857 10.143 1.00 41.21 H CONECT 5476 5477 5478 CONECT 5477 5476 CONECT 5478 5476 CONECT 5479 5480 5481 CONECT 5480 5479 CONECT 5481 5479 CONECT 5482 5483 5484 CONECT 5483 5482 CONECT 5484 5482 CONECT 5485 5486 5487 CONECT 5486 5485 CONECT 5487 5485 CONECT 5488 5489 5490 CONECT 5489 5488 CONECT 5490 5488 CONECT 5491 5492 5493 CONECT 5492 5491 CONECT 5493 5491 CONECT 5494 5495 5496 CONECT 5495 5494 CONECT 5496 5494 END ================================================ FILE: src/openfe/tests/data/external_formats/__init__.py ================================================ ================================================ FILE: src/openfe/tests/data/external_formats/somebenzenes_edges.edge ================================================ 1c91235:9c91235 # benzene -> toluene 1c91235:7876633 # benzene -> phenol 1c91235:2a51f95 # benzene -> benzonitrile 1c91235:efja0bc # benzene -> anisole 1c91235:7877722 # benzene -> styrene 1c91235:99930cd # benzene -> benzaldehyde ================================================ FILE: src/openfe/tests/data/htf/__init__.py ================================================ ================================================ FILE: src/openfe/tests/data/htf/chloroethane.sdf ================================================ chloroethane RDKit 3D 8 7 0 0 0 0 0 0 0 0999 V2000 -1.3775 1.4853 -0.3054 Cl 0 0 0 0 0 0 0 0 0 0 0 0 -0.7289 -0.1486 0.0141 C 0 0 0 0 0 0 0 0 0 0 0 0 0.7801 -0.0222 0.0530 C 0 0 0 0 0 0 0 0 0 0 0 0 -1.0446 -0.7625 -0.8423 H 0 0 0 0 0 0 0 0 0 0 0 0 -1.1589 -0.4787 0.9822 H 0 0 0 0 0 0 0 0 0 0 0 0 1.1368 0.9399 -0.3538 H 0 0 0 0 0 0 0 0 0 0 0 0 1.2037 -0.8083 -0.6046 H 0 0 0 0 0 0 0 0 0 0 0 0 1.1892 -0.2049 1.0569 H 0 0 0 0 0 0 0 0 0 0 0 0 1 2 1 0 2 3 1 0 2 4 1 0 2 5 1 0 3 6 1 0 3 7 1 0 3 8 1 0 M END > (1) -0.20252500000000001 0.038874999999999993 -0.107225 0.062575000000000006 0.062575000000000006 0.048574999999999993 0.048574999999999993 0.048574999999999993 $$$$ ================================================ FILE: src/openfe/tests/data/htf/ethane.sdf ================================================ ethane RDKit 3D 8 7 0 0 0 0 0 0 0 0999 V2000 -1.1246 0.8482 -0.1808 H 0 0 0 0 0 0 0 0 0 0 0 0 -0.7289 -0.1486 0.0141 C 0 0 0 0 0 0 0 0 0 0 0 0 0.7801 -0.0222 0.0530 C 0 0 0 0 0 0 0 0 0 0 0 0 -1.0446 -0.7625 -0.8423 H 0 0 0 0 0 0 0 0 0 0 0 0 -1.1589 -0.4787 0.9822 H 0 0 0 0 0 0 0 0 0 0 0 0 1.1368 0.9399 -0.3538 H 0 0 0 0 0 0 0 0 0 0 0 0 1.2037 -0.8083 -0.6046 H 0 0 0 0 0 0 0 0 0 0 0 0 1.1892 -0.2049 1.0569 H 0 0 0 0 0 0 0 0 0 0 0 0 1 2 1 0 2 3 1 0 2 4 1 0 2 5 1 0 3 6 1 0 3 7 1 0 3 8 1 0 M END > (1) 0.031449999999999999 -0.094350000000000003 -0.094350000000000003 0.031449999999999999 0.031449999999999999 0.031449999999999999 0.031449999999999999 0.031449999999999999 $$$$ ================================================ FILE: src/openfe/tests/data/htf/fluoroethane.sdf ================================================ fluoroethane RDKit 3D 8 7 0 0 0 0 0 0 0 0999 V2000 -1.2190 1.0859 -0.2273 F 0 0 0 0 0 0 0 0 0 0 0 0 -0.7289 -0.1486 0.0141 C 0 0 0 0 0 0 0 0 0 0 0 0 0.7801 -0.0222 0.0530 C 0 0 0 0 0 0 0 0 0 0 0 0 -1.0446 -0.7625 -0.8423 H 0 0 0 0 0 0 0 0 0 0 0 0 -1.1589 -0.4787 0.9822 H 0 0 0 0 0 0 0 0 0 0 0 0 1.1368 0.9399 -0.3538 H 0 0 0 0 0 0 0 0 0 0 0 0 1.2037 -0.8083 -0.6046 H 0 0 0 0 0 0 0 0 0 0 0 0 1.1892 -0.2049 1.0569 H 0 0 0 0 0 0 0 0 0 0 0 0 1 2 1 0 2 3 1 0 2 4 1 0 2 5 1 0 3 6 1 0 3 7 1 0 3 8 1 0 M END > (1) -0.24917500000000001 0.159025 -0.13097500000000001 0.038824999999999991 0.038824999999999991 0.047824999999999993 0.047824999999999993 0.047824999999999993 $$$$ ================================================ FILE: src/openfe/tests/data/htf/t4_lysozyme_data/benzene.sdf ================================================ benzene RDKit 3D 12 12 0 0 0 0 0 0 0 0999 V2000 -6.6806 7.0134 -0.0533 H 0 0 0 0 0 0 0 0 0 0 0 0 -7.2858 7.1609 -0.9477 C 0 0 0 0 0 0 0 0 0 0 0 0 -7.8665 6.0569 -1.5923 C 0 0 0 0 0 0 0 0 0 0 0 0 -8.6603 6.2343 -2.7247 C 0 0 0 0 0 0 0 0 0 0 0 0 -8.8944 7.5191 -3.2149 C 0 0 0 0 0 0 0 0 0 0 0 0 -8.3035 8.6211 -2.6006 C 0 0 0 0 0 0 0 0 0 0 0 0 -7.5003 8.4444 -1.4758 C 0 0 0 0 0 0 0 0 0 0 0 0 -7.7098 5.0628 -1.2014 H 0 0 0 0 0 0 0 0 0 0 0 0 -9.0935 5.3789 -3.2180 H 0 0 0 0 0 0 0 0 0 0 0 0 -9.5294 7.6705 -4.0709 H 0 0 0 0 0 0 0 0 0 0 0 0 -8.4705 9.6119 -2.9925 H 0 0 0 0 0 0 0 0 0 0 0 0 -7.0579 9.3041 -0.9946 H 0 0 0 0 0 0 0 0 0 0 0 0 1 2 1 0 2 3 2 0 2 7 1 0 3 4 1 0 3 8 1 0 4 5 2 0 4 9 1 0 5 6 1 0 5 10 1 0 6 7 2 0 6 11 1 0 7 12 1 0 M END > (1) 0.13 -0.13 -0.13 -0.13 -0.13 -0.13 -0.13 0.13 0.13 0.13 0.13 0.13 $$$$ ================================================ FILE: src/openfe/tests/data/htf/t4_lysozyme_data/chlorobenzene.sdf ================================================ chlorobenzene RDKit 3D 12 12 0 0 0 0 0 0 0 0999 V2000 -6.3030 6.9214 0.5047 Cl 0 0 0 0 0 0 0 0 0 0 0 0 -7.2858 7.1609 -0.9477 C 0 0 0 0 0 0 0 0 0 0 0 0 -7.8665 6.0569 -1.5923 C 0 0 0 0 0 0 0 0 0 0 0 0 -8.6603 6.2343 -2.7247 C 0 0 0 0 0 0 0 0 0 0 0 0 -8.8944 7.5191 -3.2149 C 0 0 0 0 0 0 0 0 0 0 0 0 -8.3035 8.6211 -2.6006 C 0 0 0 0 0 0 0 0 0 0 0 0 -7.5003 8.4444 -1.4758 C 0 0 0 0 0 0 0 0 0 0 0 0 -7.7098 5.0628 -1.2014 H 0 0 0 0 0 0 0 0 0 0 0 0 -9.0935 5.3789 -3.2180 H 0 0 0 0 0 0 0 0 0 0 0 0 -9.5294 7.6705 -4.0709 H 0 0 0 0 0 0 0 0 0 0 0 0 -8.4705 9.6119 -2.9925 H 0 0 0 0 0 0 0 0 0 0 0 0 -7.0579 9.3041 -0.9946 H 0 0 0 0 0 0 0 0 0 0 0 0 1 2 1 0 2 3 2 0 2 7 1 0 3 4 1 0 3 8 1 0 4 5 2 0 4 9 1 0 5 6 1 0 5 10 1 0 6 7 2 0 6 11 1 0 7 12 1 0 M END > (1) -0.097566666666666677 0.017233333333333326 -0.12416666666666668 -0.12216666666666667 -0.12916666666666668 -0.12216666666666667 -0.12416666666666668 0.14683333333333332 0.13683333333333333 0.13483333333333333 0.13683333333333333 0.14683333333333332 $$$$ ================================================ FILE: src/openfe/tests/data/htf/t4_lysozyme_data/fluorobenzene.sdf ================================================ fluorobenzene RDKit 3D 12 12 0 0 0 0 0 0 0 0999 V2000 -6.5362 6.9783 0.1601 F 0 0 0 0 0 0 0 0 0 0 0 0 -7.2858 7.1609 -0.9477 C 0 0 0 0 0 0 0 0 0 0 0 0 -7.8665 6.0569 -1.5923 C 0 0 0 0 0 0 0 0 0 0 0 0 -8.6603 6.2343 -2.7247 C 0 0 0 0 0 0 0 0 0 0 0 0 -8.8944 7.5191 -3.2149 C 0 0 0 0 0 0 0 0 0 0 0 0 -8.3035 8.6211 -2.6006 C 0 0 0 0 0 0 0 0 0 0 0 0 -7.5003 8.4444 -1.4758 C 0 0 0 0 0 0 0 0 0 0 0 0 -7.7098 5.0628 -1.2014 H 0 0 0 0 0 0 0 0 0 0 0 0 -9.0935 5.3789 -3.2180 H 0 0 0 0 0 0 0 0 0 0 0 0 -9.5294 7.6705 -4.0709 H 0 0 0 0 0 0 0 0 0 0 0 0 -8.4705 9.6119 -2.9925 H 0 0 0 0 0 0 0 0 0 0 0 0 -7.0579 9.3041 -0.9946 H 0 0 0 0 0 0 0 0 0 0 0 0 1 2 1 0 2 3 2 0 2 7 1 0 3 4 1 0 3 8 1 0 4 5 2 0 4 9 1 0 5 6 1 0 5 10 1 0 6 7 2 0 6 11 1 0 7 12 1 0 M END > (1) -0.14198333333333335 0.12381666666666666 -0.16608333333333336 -0.10508333333333333 -0.14508333333333334 -0.10508333333333333 -0.16608333333333336 0.14791666666666664 0.13691666666666666 0.13591666666666666 0.13691666666666666 0.14791666666666664 $$$$ ================================================ FILE: src/openfe/tests/data/lomap_basic/1,3,7-trimethylnaphthalene.mol2 ================================================ @MOLECULE ***** 27 28 0 0 0 SMALL GASTEIGER @ATOM 1 C 0.9251 0.1494 -0.0025 C.3 1 LIG1 -0.0397 2 C 2.4242 0.1552 0.0465 C.ar 1 LIG1 -0.0498 3 C 3.1297 -1.0574 0.0810 C.ar 1 LIG1 -0.0509 4 C 4.5422 -1.1042 0.1427 C.ar 1 LIG1 -0.0147 5 C 5.2861 -2.3145 0.1727 C.ar 1 LIG1 -0.0425 6 C 6.6903 -2.2735 0.2331 C.ar 1 LIG1 -0.0553 7 C 7.3760 -1.0578 0.2620 C.ar 1 LIG1 -0.0496 8 C 6.6436 0.1328 0.2358 C.ar 1 LIG1 -0.0511 9 C 5.2413 0.1261 0.1765 C.ar 1 LIG1 -0.0174 10 C 4.5298 1.3362 0.1522 C.ar 1 LIG1 -0.0538 11 C 3.1361 1.3519 0.0914 C.ar 1 LIG1 -0.0582 12 C 8.8737 -1.0147 0.3281 C.3 1 LIG1 -0.0397 13 C 4.6094 -3.6603 0.1443 C.3 1 LIG1 -0.0391 14 H 0.5282 1.1476 -0.2149 H 1 LIG1 0.0278 15 H 0.5194 -0.1845 0.9575 H 1 LIG1 0.0278 16 H 0.5728 -0.5198 -0.7944 H 1 LIG1 0.0278 17 H 2.5577 -1.9826 0.0575 H 1 LIG1 0.0626 18 H 7.2540 -3.2043 0.2569 H 1 LIG1 0.0623 19 H 7.1781 1.0810 0.2619 H 1 LIG1 0.0626 20 H 5.0603 2.2854 0.1820 H 1 LIG1 0.0624 21 H 2.6157 2.3065 0.0777 H 1 LIG1 0.0620 22 H 9.3069 -2.0200 0.3015 H 1 LIG1 0.0278 23 H 9.1960 -0.5332 1.2567 H 1 LIG1 0.0278 24 H 9.2731 -0.4567 -0.5249 H 1 LIG1 0.0278 25 H 5.3371 -4.4789 0.1591 H 1 LIG1 0.0278 26 H 4.0157 -3.7691 -0.7690 H 1 LIG1 0.0278 27 H 3.9645 -3.7798 1.0209 H 1 LIG1 0.0278 @BOND 1 6 7 ar 2 5 6 ar 3 7 8 ar 4 8 9 ar 5 9 10 ar 6 4 9 ar 7 10 11 ar 8 2 11 ar 9 2 3 ar 10 3 4 ar 11 4 5 ar 12 1 2 1 13 5 13 1 14 7 12 1 15 1 14 1 16 1 15 1 17 1 16 1 18 3 17 1 19 6 18 1 20 8 19 1 21 10 20 1 22 11 21 1 23 12 22 1 24 12 23 1 25 12 24 1 26 13 25 1 27 13 26 1 28 13 27 1 ================================================ FILE: src/openfe/tests/data/lomap_basic/1-butyl-4-methylbenzene.mol2 ================================================ @MOLECULE ***** 27 27 0 0 0 SMALL GASTEIGER @ATOM 1 C 1.9899 -1.5496 1.4095 C.3 1 LIG1 -0.0653 2 C 3.0612 -0.6401 0.8303 C.3 1 LIG1 -0.0556 3 C 3.5100 0.4139 1.8419 C.3 1 LIG1 -0.0493 4 C 4.5859 1.3256 1.2470 C.3 1 LIG1 -0.0277 5 C 5.0777 2.3433 2.2464 C.ar 1 LIG1 -0.0473 6 C 4.4793 3.6056 2.3316 C.ar 1 LIG1 -0.0583 7 C 4.9350 4.5439 3.2608 C.ar 1 LIG1 -0.0586 8 C 5.9858 4.2317 4.1299 C.ar 1 LIG1 -0.0504 9 C 6.5860 2.9711 4.0431 C.ar 1 LIG1 -0.0586 10 C 6.1309 2.0320 3.1146 C.ar 1 LIG1 -0.0583 11 C 6.4975 5.2565 5.0979 C.3 1 LIG1 -0.0397 12 H 1.6931 -2.3034 0.6726 H 1 LIG1 0.0230 13 H 1.0980 -0.9785 1.6885 H 1 LIG1 0.0230 14 H 2.3560 -2.0720 2.3000 H 1 LIG1 0.0230 15 H 2.6700 -0.1517 -0.0688 H 1 LIG1 0.0263 16 H 3.9190 -1.2484 0.5229 H 1 LIG1 0.0263 17 H 3.8957 -0.0824 2.7418 H 1 LIG1 0.0268 18 H 2.6473 1.0144 2.1583 H 1 LIG1 0.0268 19 H 4.1939 1.8426 0.3620 H 1 LIG1 0.0313 20 H 5.4358 0.7279 0.8940 H 1 LIG1 0.0313 21 H 3.6566 3.8691 1.6710 H 1 LIG1 0.0620 22 H 4.4634 5.5233 3.3010 H 1 LIG1 0.0620 23 H 7.4138 2.7097 4.6988 H 1 LIG1 0.0620 24 H 6.6080 1.0557 3.0700 H 1 LIG1 0.0620 25 H 7.0175 4.7827 5.9374 H 1 LIG1 0.0278 26 H 5.6710 5.8412 5.5155 H 1 LIG1 0.0278 27 H 7.1937 5.9336 4.5926 H 1 LIG1 0.0278 @BOND 1 5 6 ar 2 6 7 ar 3 5 10 ar 4 9 10 ar 5 8 9 ar 6 7 8 ar 7 1 2 1 8 2 3 1 9 3 4 1 10 4 5 1 11 8 11 1 12 1 12 1 13 1 13 1 14 1 14 1 15 2 15 1 16 2 16 1 17 3 17 1 18 3 18 1 19 4 19 1 20 4 20 1 21 6 21 1 22 7 22 1 23 9 23 1 24 10 24 1 25 11 25 1 26 11 26 1 27 11 27 1 ================================================ FILE: src/openfe/tests/data/lomap_basic/2,6-dimethylnaphthalene.mol2 ================================================ @MOLECULE ***** 24 25 0 0 0 SMALL GASTEIGER @ATOM 1 C 0.8817 -0.0759 0.0737 C.3 1 LIG1 -0.0397 2 C 2.3811 -0.0540 0.0354 C.ar 1 LIG1 -0.0499 3 C 3.0834 1.1532 0.0347 C.ar 1 LIG1 -0.0582 4 C 4.4799 1.1582 -0.0011 C.ar 1 LIG1 -0.0538 5 C 5.2032 -0.0442 -0.0356 C.ar 1 LIG1 -0.0176 6 C 6.6087 -0.0550 -0.0772 C.ar 1 LIG1 -0.0511 7 C 7.3242 -1.2594 -0.1176 C.ar 1 LIG1 -0.0499 8 C 8.8235 -1.2393 -0.1486 C.3 1 LIG1 -0.0397 9 C 6.6224 -2.4667 -0.0984 C.ar 1 LIG1 -0.0582 10 C 5.2258 -2.4717 -0.0573 C.ar 1 LIG1 -0.0538 11 C 4.5024 -1.2692 -0.0283 C.ar 1 LIG1 -0.0176 12 C 3.0971 -1.2586 0.0081 C.ar 1 LIG1 -0.0511 13 H 0.4638 0.9355 0.0362 H 1 LIG1 0.0278 14 H 0.5354 -0.5508 0.9973 H 1 LIG1 0.0278 15 H 0.4903 -0.6304 -0.7856 H 1 LIG1 0.0278 16 H 2.5515 2.1015 0.0601 H 1 LIG1 0.0620 17 H 5.0016 2.1125 -0.0033 H 1 LIG1 0.0624 18 H 7.1539 0.8869 -0.0807 H 1 LIG1 0.0626 19 H 9.2330 -2.2332 -0.3578 H 1 LIG1 0.0278 20 H 9.2150 -0.9034 0.8167 H 1 LIG1 0.0278 21 H 9.1785 -0.5651 -0.9354 H 1 LIG1 0.0278 22 H 7.1546 -3.4149 -0.1177 H 1 LIG1 0.0620 23 H 4.7045 -3.4261 -0.0479 H 1 LIG1 0.0624 24 H 2.5515 -2.2003 0.0134 H 1 LIG1 0.0626 @BOND 1 2 3 ar 2 3 4 ar 3 2 12 ar 4 11 12 ar 5 10 11 ar 6 5 11 ar 7 9 10 ar 8 7 9 ar 9 6 7 ar 10 5 6 ar 11 4 5 ar 12 1 2 1 13 7 8 1 14 1 13 1 15 1 14 1 16 1 15 1 17 3 16 1 18 4 17 1 19 6 18 1 20 8 19 1 21 8 20 1 22 8 21 1 23 9 22 1 24 10 23 1 25 12 24 1 ================================================ FILE: src/openfe/tests/data/lomap_basic/2-methyl-6-propylnaphthalene.mol2 ================================================ @MOLECULE ***** 30 31 0 0 0 SMALL GASTEIGER @ATOM 1 C 0.7969 1.3147 -1.5722 C.3 1 LIG1 -0.0650 2 C 2.3162 1.3551 -1.5843 C.3 1 LIG1 -0.0519 3 C 2.8874 1.3784 -0.1657 C.3 1 LIG1 -0.0279 4 C 4.3949 1.4239 -0.1763 C.ar 1 LIG1 -0.0468 5 C 5.1419 0.2376 -0.2084 C.ar 1 LIG1 -0.0508 6 C 6.5466 0.2630 -0.2482 C.ar 1 LIG1 -0.0176 7 C 7.2164 1.5056 -0.2598 C.ar 1 LIG1 -0.0176 8 C 6.4634 2.6893 -0.2285 C.ar 1 LIG1 -0.0538 9 C 5.0678 2.6494 -0.1901 C.ar 1 LIG1 -0.0580 10 C 8.6208 1.5306 -0.3057 C.ar 1 LIG1 -0.0511 11 C 9.3673 0.3447 -0.3470 C.ar 1 LIG1 -0.0499 12 C 8.6960 -0.8804 -0.3232 C.ar 1 LIG1 -0.0582 13 C 7.3000 -0.9207 -0.2780 C.ar 1 LIG1 -0.0538 14 C 10.8656 0.4019 -0.3796 C.3 1 LIG1 -0.0397 15 H 0.4106 1.2994 -2.5961 H 1 LIG1 0.0230 16 H 0.3854 2.1942 -1.0670 H 1 LIG1 0.0230 17 H 0.4325 0.4199 -1.0579 H 1 LIG1 0.0230 18 H 2.6477 2.2415 -2.1391 H 1 LIG1 0.0266 19 H 2.6945 0.4813 -2.1292 H 1 LIG1 0.0266 20 H 2.5534 0.4943 0.3922 H 1 LIG1 0.0313 21 H 2.5001 2.2454 0.3843 H 1 LIG1 0.0313 22 H 4.6215 -0.7184 -0.2065 H 1 LIG1 0.0626 23 H 6.9606 3.6568 -0.2384 H 1 LIG1 0.0624 24 H 4.5102 3.5829 -0.1747 H 1 LIG1 0.0620 25 H 9.1424 2.4858 -0.3125 H 1 LIG1 0.0626 26 H 9.2523 -1.8147 -0.3422 H 1 LIG1 0.0620 27 H 6.8033 -1.8881 -0.2657 H 1 LIG1 0.0624 28 H 11.2977 -0.5759 -0.6162 H 1 LIG1 0.0278 29 H 11.2498 0.7216 0.5938 H 1 LIG1 0.0278 30 H 11.2028 1.1048 -1.1483 H 1 LIG1 0.0278 @BOND 1 4 9 ar 2 8 9 ar 3 4 5 ar 4 5 6 ar 5 6 13 ar 6 6 7 ar 7 12 13 ar 8 11 12 ar 9 10 11 ar 10 7 10 ar 11 7 8 ar 12 1 2 1 13 2 3 1 14 3 4 1 15 11 14 1 16 1 15 1 17 1 16 1 18 1 17 1 19 2 18 1 20 2 19 1 21 3 20 1 22 3 21 1 23 5 22 1 24 8 23 1 25 9 24 1 26 10 25 1 27 12 26 1 28 13 27 1 29 14 28 1 30 14 29 1 31 14 30 1 ================================================ FILE: src/openfe/tests/data/lomap_basic/2-methylnaphthalene.mol2 ================================================ @MOLECULE ***** 21 22 0 0 0 SMALL GASTEIGER @ATOM 1 C 0.9750 -0.0348 0.0833 C.3 1 LIG1 -0.0397 2 C 2.4749 -0.0532 0.0754 C.ar 1 LIG1 -0.0499 3 C 3.2098 1.1400 0.0597 C.ar 1 LIG1 -0.0511 4 C 4.6141 1.1264 -0.0127 C.ar 1 LIG1 -0.0176 5 C 5.3554 2.3190 -0.0614 C.ar 1 LIG1 -0.0540 6 C 6.7465 2.2894 -0.1768 C.ar 1 LIG1 -0.0612 7 C 7.4142 1.0702 -0.2321 C.ar 1 LIG1 -0.0612 8 C 6.6939 -0.1236 -0.1628 C.ar 1 LIG1 -0.0540 9 C 5.2934 -0.1107 -0.0560 C.ar 1 LIG1 -0.0179 10 C 4.5528 -1.3018 -0.0057 C.ar 1 LIG1 -0.0538 11 C 3.1574 -1.2723 0.0551 C.ar 1 LIG1 -0.0582 12 H 0.5850 0.9882 0.1017 H 1 LIG1 0.0278 13 H 0.5915 -0.5586 0.9643 H 1 LIG1 0.0278 14 H 0.5924 -0.5209 -0.8204 H 1 LIG1 0.0278 15 H 2.6835 2.0917 0.0844 H 1 LIG1 0.0626 16 H 4.8512 3.2813 -0.0218 H 1 LIG1 0.0624 17 H 7.3059 3.2198 -0.2301 H 1 LIG1 0.0618 18 H 8.4962 1.0459 -0.3322 H 1 LIG1 0.0618 19 H 7.2331 -1.0669 -0.2063 H 1 LIG1 0.0624 20 H 5.0575 -2.2644 -0.0289 H 1 LIG1 0.0624 21 H 2.6062 -2.2099 0.0730 H 1 LIG1 0.0620 @BOND 1 1 2 1 2 2 3 ar 3 3 4 ar 4 4 5 ar 5 5 6 ar 6 6 7 ar 7 7 8 ar 8 8 9 ar 9 4 9 ar 10 9 10 ar 11 10 11 ar 12 2 11 ar 13 1 12 1 14 1 13 1 15 1 14 1 16 3 15 1 17 5 16 1 18 6 17 1 19 7 18 1 20 8 19 1 21 10 20 1 22 11 21 1 ================================================ FILE: src/openfe/tests/data/lomap_basic/2-naftanol.mol2 ================================================ @MOLECULE ***** 19 20 0 0 0 SMALL GASTEIGER @ATOM 1 O 9.9477 -4.1875 1.4569 O.3 1 LIG1 -0.5067 2 C 9.0676 -3.1850 1.1716 C.ar 1 LIG1 0.1175 3 C 7.7820 -3.1808 1.6974 C.ar 1 LIG1 -0.0196 4 C 6.9153 -2.1329 1.3798 C.ar 1 LIG1 -0.0506 5 C 7.3294 -1.0867 0.5375 C.ar 1 LIG1 -0.0177 6 C 6.4703 -0.0252 0.2106 C.ar 1 LIG1 -0.0540 7 C 6.8977 1.0066 -0.6271 C.ar 1 LIG1 -0.0612 8 C 8.1878 0.9906 -1.1489 C.ar 1 LIG1 -0.0612 9 C 9.0548 -0.0574 -0.8344 C.ar 1 LIG1 -0.0539 10 C 8.6411 -1.1023 0.0071 C.ar 1 LIG1 -0.0144 11 C 9.5008 -2.1625 0.3346 C.ar 1 LIG1 -0.0125 12 H 9.5144 -4.8197 2.0534 H 1 LIG1 0.2921 13 H 7.4363 -3.9757 2.3505 H 1 LIG1 0.0654 14 H 5.9102 -2.1360 1.7951 H 1 LIG1 0.0625 15 H 5.4583 0.0059 0.6080 H 1 LIG1 0.0624 16 H 6.2223 1.8225 -0.8713 H 1 LIG1 0.0618 17 H 8.5216 1.7931 -1.8011 H 1 LIG1 0.0618 18 H 10.0593 -0.0532 -1.2512 H 1 LIG1 0.0624 19 H 10.5134 -2.1967 -0.0603 H 1 LIG1 0.0660 @BOND 1 2 3 ar 2 2 11 ar 3 3 4 ar 4 4 5 ar 5 5 6 ar 6 5 10 ar 7 6 7 ar 8 7 8 ar 9 8 9 ar 10 9 10 ar 11 10 11 ar 12 1 2 1 13 1 12 1 14 3 13 1 15 4 14 1 16 6 15 1 17 7 16 1 18 8 17 1 19 9 18 1 20 11 19 1 ================================================ FILE: src/openfe/tests/data/lomap_basic/README.md ================================================ Testfiles from Lomap's basic tests ================================================ FILE: src/openfe/tests/data/lomap_basic/__init__.py ================================================ ================================================ FILE: src/openfe/tests/data/lomap_basic/methylcyclohexane.mol2 ================================================ @MOLECULE ***** 21 21 0 0 0 SMALL GASTEIGER @ATOM 1 C 0.9730 0.1554 0.1412 C.3 1 LIG1 -0.0624 2 C 2.4934 0.1043 -0.0303 C.3 1 LIG1 -0.0439 3 C 2.9737 -1.3048 -0.4072 C.3 1 LIG1 -0.0505 4 C 2.6388 -1.6853 -1.8487 C.3 1 LIG1 -0.0528 5 C 3.1458 -0.6424 -2.8397 C.3 1 LIG1 -0.0530 6 C 2.6503 0.7581 -2.4959 C.3 1 LIG1 -0.0528 7 C 2.9839 1.1382 -1.0536 C.3 1 LIG1 -0.0505 8 H 0.6557 1.1542 0.4607 H 1 LIG1 0.0232 9 H 0.6478 -0.5562 0.9081 H 1 LIG1 0.0232 10 H 0.4392 -0.0840 -0.7835 H 1 LIG1 0.0232 11 H 2.9316 0.3596 0.9431 H 1 LIG1 0.0298 12 H 2.5484 -2.0480 0.2778 H 1 LIG1 0.0268 13 H 4.0632 -1.3509 -0.2778 H 1 LIG1 0.0268 14 H 3.0861 -2.6588 -2.0822 H 1 LIG1 0.0265 15 H 1.5550 -1.8040 -1.9616 H 1 LIG1 0.0265 16 H 4.2430 -0.6482 -2.8423 H 1 LIG1 0.0265 17 H 2.8244 -0.9091 -3.8522 H 1 LIG1 0.0265 18 H 3.1052 1.4851 -3.1790 H 1 LIG1 0.0265 19 H 1.5667 0.8148 -2.6555 H 1 LIG1 0.0265 20 H 4.0736 1.2348 -0.9613 H 1 LIG1 0.0268 21 H 2.5648 2.1260 -0.8271 H 1 LIG1 0.0268 @BOND 1 2 7 1 2 2 3 1 3 6 7 1 4 5 6 1 5 4 5 1 6 3 4 1 7 1 2 1 8 1 8 1 9 1 9 1 10 1 10 1 11 2 11 1 12 3 12 1 13 3 13 1 14 4 14 1 15 4 15 1 16 5 16 1 17 5 17 1 18 6 18 1 19 6 19 1 20 7 20 1 21 7 21 1 ================================================ FILE: src/openfe/tests/data/lomap_basic/toluene.mol2 ================================================ @MOLECULE ***** 15 15 0 0 0 SMALL GASTEIGER @ATOM 1 C 0.9562 0.0874 0.1225 C.3 1 LIG1 -0.0397 2 C 2.4532 0.1169 0.0327 C.ar 1 LIG1 -0.0504 3 C 3.1480 1.3313 -0.0192 C.ar 1 LIG1 -0.0588 4 C 4.5410 1.3447 -0.1106 C.ar 1 LIG1 -0.0615 5 C 5.2502 0.1457 -0.1538 C.ar 1 LIG1 -0.0617 6 C 4.5672 -1.0681 -0.1065 C.ar 1 LIG1 -0.0615 7 C 3.1745 -1.0830 -0.0148 C.ar 1 LIG1 -0.0588 8 H 0.5405 1.0944 0.2295 H 1 LIG1 0.0278 9 H 0.6412 -0.4972 0.9928 H 1 LIG1 0.0278 10 H 0.5343 -0.3590 -0.7834 H 1 LIG1 0.0278 11 H 2.6097 2.2757 0.0116 H 1 LIG1 0.0620 12 H 5.0726 2.2915 -0.1488 H 1 LIG1 0.0618 13 H 6.3343 0.1573 -0.2252 H 1 LIG1 0.0618 14 H 5.1186 -2.0039 -0.1418 H 1 LIG1 0.0618 15 H 2.6530 -2.0368 0.0195 H 1 LIG1 0.0620 @BOND 1 2 3 ar 2 3 4 ar 3 2 7 ar 4 6 7 ar 5 5 6 ar 6 4 5 ar 7 1 2 1 8 1 8 1 9 1 9 1 10 1 10 1 11 3 11 1 12 4 12 1 13 5 13 1 14 6 14 1 15 7 15 1 ================================================ FILE: src/openfe/tests/data/multi_molecule.sdf ================================================ RDKit 2D 3 2 0 0 0 0 0 0 0 0999 V2000 0.0000 0.0000 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 1.2990 0.7500 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 2.5981 -0.0000 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 1 2 1 0 2 3 1 0 M END $$$$ RDKit 2D 3 2 0 0 0 0 0 0 0 0999 V2000 0.0000 0.0000 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 1.2990 0.7500 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 2.5981 -0.0000 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 1 2 1 0 2 3 1 0 M END $$$$ ================================================ FILE: src/openfe/tests/data/openmm_afe/__init__.py ================================================ ================================================ FILE: src/openfe/tests/data/openmm_md/__init__.py ================================================ ================================================ FILE: src/openfe/tests/data/openmm_rfe/__init__.py ================================================ ================================================ FILE: src/openfe/tests/data/openmm_rfe/benzene_toluene_hybrid_top/hybrid_topology_atoms.csv ================================================ ,serial,name,element,resSeq,resName,chainID,segmentID,formal_charge 0,,C1x,C,0,UNK,0,, 1,,C2x,C,0,UNK,0,, 2,,C3x,C,0,UNK,0,, 3,,C4x,C,0,UNK,0,, 4,,C5x,C,0,UNK,0,, 5,,C6x,C,0,UNK,0,, 6,,H1x,H,0,UNK,0,, 7,,H2x,H,0,UNK,0,, 8,,H3x,H,0,UNK,0,, 9,,H4x,H,0,UNK,0,, 10,,H5x,H,0,UNK,0,, 11,,H6x,H,0,UNK,0,, 12,,H1x,H,0,UNK,0,, 13,,H2x,H,0,UNK,0,, 14,,C1x,C,0,UNK,0,, 15,,H3x,H,0,UNK,0,, ================================================ FILE: src/openfe/tests/data/openmm_rfe/benzene_toluene_hybrid_top/hybrid_topology_bonds.txt ================================================ 0.000000000000000000e+00 1.000000000000000000e+00 1.500000000000000000e+00 2.000000000000000000e+00 0.000000000000000000e+00 5.000000000000000000e+00 1.500000000000000000e+00 1.000000000000000000e+00 0.000000000000000000e+00 6.000000000000000000e+00 1.000000000000000000e+00 1.000000000000000000e+00 1.000000000000000000e+00 2.000000000000000000e+00 1.500000000000000000e+00 1.000000000000000000e+00 1.000000000000000000e+00 7.000000000000000000e+00 1.000000000000000000e+00 1.000000000000000000e+00 2.000000000000000000e+00 3.000000000000000000e+00 1.500000000000000000e+00 2.000000000000000000e+00 2.000000000000000000e+00 8.000000000000000000e+00 1.000000000000000000e+00 1.000000000000000000e+00 3.000000000000000000e+00 4.000000000000000000e+00 1.500000000000000000e+00 1.000000000000000000e+00 3.000000000000000000e+00 9.000000000000000000e+00 1.000000000000000000e+00 1.000000000000000000e+00 4.000000000000000000e+00 5.000000000000000000e+00 1.500000000000000000e+00 2.000000000000000000e+00 4.000000000000000000e+00 1.000000000000000000e+01 1.000000000000000000e+00 1.000000000000000000e+00 5.000000000000000000e+00 1.100000000000000000e+01 1.000000000000000000e+00 1.000000000000000000e+00 1.200000000000000000e+01 1.400000000000000000e+01 0.000000000000000000e+00 0.000000000000000000e+00 1.300000000000000000e+01 1.400000000000000000e+01 0.000000000000000000e+00 0.000000000000000000e+00 1.400000000000000000e+01 1.500000000000000000e+01 0.000000000000000000e+00 0.000000000000000000e+00 4.000000000000000000e+00 1.400000000000000000e+01 0.000000000000000000e+00 0.000000000000000000e+00 ================================================ FILE: src/openfe/tests/data/openmm_rfe/charged_benzenes.sdf ================================================ benzene PyMOL2.5 3D 0 12 12 0 0 0 0 0 0 0 0999 V2000 1.4045 -0.0000 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 0.7022 1.2164 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 -0.7023 1.2164 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 -1.4045 -0.0000 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 -0.7023 -1.2164 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 0.7023 -1.2164 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 2.5079 -0.0000 0.0000 H 0 0 0 0 0 0 0 0 0 0 0 0 1.2540 2.1720 0.0000 H 0 0 0 0 0 0 0 0 0 0 0 0 -1.2540 2.1720 0.0000 H 0 0 0 0 0 0 0 0 0 0 0 0 -2.5079 -0.0000 0.0000 H 0 0 0 0 0 0 0 0 0 0 0 0 -1.2540 -2.1719 0.0000 H 0 0 0 0 0 0 0 0 0 0 0 0 1.2540 -2.1720 0.0000 H 0 0 0 0 0 0 0 0 0 0 0 0 1 2 2 0 0 0 0 1 6 1 0 0 0 0 1 7 1 0 0 0 0 2 3 1 0 0 0 0 2 8 1 0 0 0 0 3 4 2 0 0 0 0 3 9 1 0 0 0 0 4 5 1 0 0 0 0 4 10 1 0 0 0 0 5 6 2 0 0 0 0 5 11 1 0 0 0 0 6 12 1 0 0 0 0 M END $$$$ aniline PyMOL2.5 3D 0 15 15 0 0 0 0 0 0 0 0999 V2000 1.4045 -0.0000 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 0.7022 1.2164 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 -0.7023 1.2164 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 -1.4045 -0.0000 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 -0.7023 -1.2164 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 0.7023 -1.2164 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 3.2106 0.8251 0.4756 H 0 0 0 0 0 0 0 0 0 0 0 0 3.2117 -0.8238 0.4772 H 0 0 0 0 0 0 0 0 0 0 0 0 3.2117 -0.0000 -0.9520 H 0 0 0 0 0 0 0 0 0 0 0 0 2.8745 -0.0000 0.0000 N 0 3 0 0 0 0 0 0 0 0 0 0 1.2540 2.1720 0.0000 H 0 0 0 0 0 0 0 0 0 0 0 0 -1.2540 2.1720 0.0000 H 0 0 0 0 0 0 0 0 0 0 0 0 -2.5079 -0.0000 0.0000 H 0 0 0 0 0 0 0 0 0 0 0 0 -1.2540 -2.1719 0.0000 H 0 0 0 0 0 0 0 0 0 0 0 0 1.2540 -2.1720 0.0000 H 0 0 0 0 0 0 0 0 0 0 0 0 1 2 2 0 0 0 0 1 6 1 0 0 0 0 1 10 1 0 0 0 0 2 3 1 0 0 0 0 2 11 1 0 0 0 0 3 4 2 0 0 0 0 3 12 1 0 0 0 0 4 5 1 0 0 0 0 4 13 1 0 0 0 0 5 6 2 0 0 0 0 5 14 1 0 0 0 0 6 15 1 0 0 0 0 7 10 1 0 0 0 0 8 10 1 0 0 0 0 9 10 1 0 0 0 0 M END $$$$ benzoic_acid PyMOL2.5 3D 0 14 14 0 0 0 0 0 0 0 0999 V2000 1.4045 -0.0000 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 2.7445 -0.0000 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 3.2607 -1.0833 0.0000 O 0 5 0 0 0 0 0 0 0 0 0 0 0.7022 1.2164 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 -0.7023 1.2164 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 3.4265 1.0159 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 -1.4045 -0.0000 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 -0.7023 -1.2164 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 0.7023 -1.2164 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 1.2540 2.1720 0.0000 H 0 0 0 0 0 0 0 0 0 0 0 0 -1.2540 2.1720 0.0000 H 0 0 0 0 0 0 0 0 0 0 0 0 -2.5079 -0.0000 0.0000 H 0 0 0 0 0 0 0 0 0 0 0 0 -1.2540 -2.1719 0.0000 H 0 0 0 0 0 0 0 0 0 0 0 0 1.2540 -2.1720 0.0000 H 0 0 0 0 0 0 0 0 0 0 0 0 1 2 1 0 0 0 0 1 4 2 0 0 0 0 1 9 1 0 0 0 0 2 3 1 0 0 0 0 2 6 2 0 0 0 0 4 5 1 0 0 0 0 4 10 1 0 0 0 0 5 7 2 0 0 0 0 5 11 1 0 0 0 0 7 8 1 0 0 0 0 7 12 1 0 0 0 0 8 9 2 0 0 0 0 8 13 1 0 0 0 0 9 14 1 0 0 0 0 M END $$$$ ================================================ FILE: src/openfe/tests/data/openmm_rfe/dummy_charge_ligand_23.sdf ================================================ ligand_23 RDKit 3D 36 38 0 0 0 0 0 0 0 0999 V2000 -1.9600 21.5500 -27.3300 C 0 0 0 0 0 0 0 0 0 0 0 0 -1.2900 22.4100 -28.2000 C 0 0 0 0 0 0 0 0 0 0 0 0 -1.9600 22.9500 -29.2900 C 0 0 0 0 0 0 0 0 0 0 0 0 -3.3000 22.6200 -29.5400 C 0 0 0 0 0 0 0 0 0 0 0 0 -3.9700 21.7600 -28.6500 C 0 0 0 0 0 0 0 0 0 0 0 0 -3.2900 21.2300 -27.5600 C 0 0 0 0 0 0 0 0 0 0 0 0 -5.6400 21.3500 -28.9200 Cl 0 0 0 0 0 0 0 0 0 0 0 0 -4.0400 23.1500 -30.7100 C 0 0 0 0 0 0 0 0 0 0 0 0 -4.2300 22.4200 -31.6700 O 0 0 0 0 0 0 0 0 0 0 0 0 -4.5100 24.4100 -30.6500 N 0 0 0 0 0 0 0 0 0 0 0 0 -5.2900 25.1100 -31.5800 C 0 0 0 0 0 0 0 0 0 0 0 0 -5.9600 24.5500 -32.6800 C 0 0 0 0 0 0 0 0 0 0 0 0 -6.7800 25.3600 -33.4600 C 0 0 0 0 0 0 0 0 0 0 0 0 -6.9200 26.6500 -33.1800 N 0 0 0 0 0 0 0 0 0 0 0 0 -6.3000 27.2300 -32.1600 C 0 0 0 0 0 0 0 0 0 0 0 0 -5.5100 26.4600 -31.3100 C 0 0 0 0 0 0 0 0 0 0 0 0 -6.5400 28.5800 -31.8800 N 0 0 0 0 0 0 0 0 0 0 0 0 -5.7100 29.4500 -31.2300 C 0 0 0 0 0 0 0 0 0 0 0 0 -4.6200 29.1200 -30.8100 O 0 0 0 0 0 0 0 0 0 0 0 0 -6.2300 30.8500 -31.0300 C 0 0 1 0 0 0 0 0 0 0 0 0 -5.5800 31.7500 -29.9800 C 0 0 0 0 0 0 0 0 0 0 0 0 -5.3600 32.0200 -31.4700 C 0 0 1 0 0 0 0 0 0 0 0 0 -4.1100 31.7200 -32.0100 F 0 0 0 0 0 0 0 0 0 0 0 0 -1.1100 24.0500 -30.3300 Cl 0 0 0 0 0 0 0 0 0 0 0 0 -7.3100 30.9400 -31.1600 H 0 0 0 0 0 0 0 0 0 0 0 0 -5.8600 32.9000 -31.8800 H 0 0 0 0 0 0 0 0 0 0 0 0 -1.4400 21.1300 -26.4800 H 0 0 0 0 0 0 0 0 0 0 0 0 -0.2600 22.6600 -28.0200 H 0 0 0 0 0 0 0 0 0 0 0 0 -3.8100 20.5600 -26.8900 H 0 0 0 0 0 0 0 0 0 0 0 0 -4.3200 24.9800 -29.8400 H 0 0 0 0 0 0 0 0 0 0 0 0 -5.8400 23.5000 -32.9100 H 0 0 0 0 0 0 0 0 0 0 0 0 -7.3100 24.9400 -34.3000 H 0 0 0 0 0 0 0 0 0 0 0 0 -5.0600 26.9100 -30.4300 H 0 0 0 0 0 0 0 0 0 0 0 0 -7.4000 29.0100 -32.1800 H 0 0 0 0 0 0 0 0 0 0 0 0 -6.3500 32.2000 -29.3600 H 0 0 0 0 0 0 0 0 0 0 0 0 -4.9200 31.1500 -29.3500 H 0 0 0 0 0 0 0 0 0 0 0 0 13 32 1 0 13 14 1 0 12 13 2 0 14 15 2 0 12 31 1 0 11 12 1 0 17 34 1 0 15 17 1 0 15 16 1 0 22 23 1 0 17 18 1 0 22 26 1 6 8 9 2 0 11 16 2 0 10 11 1 0 20 22 1 0 21 22 1 0 16 33 1 0 18 20 1 0 18 19 2 0 20 25 1 6 20 21 1 0 8 10 1 0 4 8 1 0 10 30 1 0 3 24 1 0 21 35 1 0 21 36 1 0 3 4 2 0 4 5 1 0 2 3 1 0 5 7 1 0 5 6 2 0 2 28 1 0 1 2 2 0 1 6 1 0 6 29 1 0 1 27 1 0 M END > (1) -0.097000000000000003 -0.1295 0.050899999999999994 -0.1426 0.050899999999999994 -0.1295 -0.058400000000000007 0.68969999999999998 -0.53810000000000002 -0.46510000000000001 0.1236 -0.32829999999999998 0.44219999999999998 -0.72699999999999998 0.54220000000000002 -0.27029999999999998 -0.5464 0.69610000000000005 -0.56910000000000005 -0.23069999999999999 -0.13339999999999999 0.12759999999999999 -0.20530000000000001 -0.058400000000000007 0.1237 0.1027 0.14799999999999999 0.1565 0.1565 0.32550000000000001 0.14199999999999999 0.022099999999999995 0.20300000000000001 0.33750000000000002 0.094200000000000006 0.094200000000000006 $$$$ ================================================ FILE: src/openfe/tests/data/openmm_rfe/dummy_charge_ligand_55.sdf ================================================ ligand_55 RDKit 3D 33 34 0 0 0 0 0 0 0 0999 V2000 -1.9600 21.5500 -27.3300 C 0 0 0 0 0 0 0 0 0 0 0 0 -1.2900 22.4100 -28.2000 C 0 0 0 0 0 0 0 0 0 0 0 0 -1.9600 22.9500 -29.2900 C 0 0 0 0 0 0 0 0 0 0 0 0 -3.3000 22.6200 -29.5400 C 0 0 0 0 0 0 0 0 0 0 0 0 -3.9700 21.7600 -28.6500 C 0 0 0 0 0 0 0 0 0 0 0 0 -3.2900 21.2300 -27.5600 C 0 0 0 0 0 0 0 0 0 0 0 0 -5.6400 21.3500 -28.9200 Cl 0 0 0 0 0 0 0 0 0 0 0 0 -4.0400 23.1500 -30.7100 C 0 0 0 0 0 0 0 0 0 0 0 0 -4.2300 22.4200 -31.6700 O 0 0 0 0 0 0 0 0 0 0 0 0 -4.5100 24.4100 -30.6500 N 0 0 0 0 0 0 0 0 0 0 0 0 -5.2900 25.1100 -31.5800 C 0 0 0 0 0 0 0 0 0 0 0 0 -5.9600 24.5500 -32.6800 C 0 0 0 0 0 0 0 0 0 0 0 0 -6.7800 25.3600 -33.4600 C 0 0 0 0 0 0 0 0 0 0 0 0 -6.9200 26.6500 -33.1800 N 0 0 0 0 0 0 0 0 0 0 0 0 -6.3000 27.2300 -32.1600 C 0 0 0 0 0 0 0 0 0 0 0 0 -5.5100 26.4600 -31.3100 C 0 0 0 0 0 0 0 0 0 0 0 0 -6.5400 28.5800 -31.8800 N 0 0 0 0 0 0 0 0 0 0 0 0 -5.7100 29.4500 -31.2300 C 0 0 0 0 0 0 0 0 0 0 0 0 -4.6200 29.1200 -30.8100 O 0 0 0 0 0 0 0 0 0 0 0 0 -1.1100 24.0500 -30.3300 Cl 0 0 0 0 0 0 0 0 0 0 0 0 -1.4400 21.1300 -26.4800 H 0 0 0 0 0 0 0 0 0 0 0 0 -0.2600 22.6600 -28.0200 H 0 0 0 0 0 0 0 0 0 0 0 0 -3.8100 20.5600 -26.8900 H 0 0 0 0 0 0 0 0 0 0 0 0 -4.3200 24.9800 -29.8400 H 0 0 0 0 0 0 0 0 0 0 0 0 -5.8400 23.5000 -32.9100 H 0 0 0 0 0 0 0 0 0 0 0 0 -7.3100 24.9400 -34.3000 H 0 0 0 0 0 0 0 0 0 0 0 0 -5.0600 26.9100 -30.4300 H 0 0 0 0 0 0 0 0 0 0 0 0 -7.4000 29.0100 -32.1800 H 0 0 0 0 0 0 0 0 0 0 0 0 -5.1900 31.8500 -30.6800 C 0 0 0 0 0 0 0 0 0 0 0 0 -5.5900 32.8600 -30.8200 H 0 0 0 0 0 0 0 0 0 0 0 0 -4.9100 31.7200 -29.6300 H 0 0 0 0 0 0 0 0 0 0 0 0 -6.2500 30.8500 -31.0300 O 0 0 0 0 0 0 0 0 0 0 0 0 -4.3200 31.7100 -31.3200 H 0 0 0 0 0 0 0 0 0 0 0 0 13 26 1 0 13 14 1 0 12 13 2 0 14 15 2 0 12 25 1 0 11 12 1 0 17 28 1 0 15 17 1 0 15 16 1 0 17 18 1 0 8 9 2 0 11 16 2 0 10 11 1 0 29 33 1 0 16 27 1 0 18 32 1 0 18 19 2 0 29 32 1 0 29 30 1 0 8 10 1 0 4 8 1 0 29 31 1 0 10 24 1 0 3 20 1 0 3 4 2 0 4 5 1 0 2 3 1 0 5 7 1 0 5 6 2 0 2 22 1 0 1 2 2 0 1 6 1 0 6 23 1 0 1 21 1 0 M END > (1) -0.094999969696969694 -0.1279999696969697 0.052400030303030309 -0.1445999696969697 0.052400030303030309 -0.1279999696969697 -0.059899969696969695 0.69270003030303029 -0.54809996969696972 -0.4610999696969697 0.1306000303030303 -0.2992999696969697 0.44520003030303029 -0.72799996969696967 0.55120003030303033 -0.32229996969696967 -0.51939996969696967 0.74610003030303029 -0.57699996969696965 -0.059899969696969695 0.1480000303030303 0.15800003030303031 0.15800003030303031 0.33150003030303032 0.1840000303030303 0.028100030303030307 0.1790000303030303 0.35250003030303029 0.1387000303030303 0.055033030303030306 0.055033030303030306 -0.44289996969696971 0.055033030303030306 $$$$ ================================================ FILE: src/openfe/tests/data/openmm_rfe/ligand_23.sdf ================================================ ligand_23 RDKit 3D 36 38 0 0 0 0 0 0 0 0999 V2000 -1.9600 21.5500 -27.3300 C 0 0 0 0 0 0 0 0 0 0 0 0 -1.2900 22.4100 -28.2000 C 0 0 0 0 0 0 0 0 0 0 0 0 -1.9600 22.9500 -29.2900 C 0 0 0 0 0 0 0 0 0 0 0 0 -3.3000 22.6200 -29.5400 C 0 0 0 0 0 0 0 0 0 0 0 0 -3.9700 21.7600 -28.6500 C 0 0 0 0 0 0 0 0 0 0 0 0 -3.2900 21.2300 -27.5600 C 0 0 0 0 0 0 0 0 0 0 0 0 -5.6400 21.3500 -28.9200 Cl 0 0 0 0 0 0 0 0 0 0 0 0 -4.0400 23.1500 -30.7100 C 0 0 0 0 0 0 0 0 0 0 0 0 -4.2300 22.4200 -31.6700 O 0 0 0 0 0 0 0 0 0 0 0 0 -4.5100 24.4100 -30.6500 N 0 0 0 0 0 0 0 0 0 0 0 0 -5.2900 25.1100 -31.5800 C 0 0 0 0 0 0 0 0 0 0 0 0 -5.9600 24.5500 -32.6800 C 0 0 0 0 0 0 0 0 0 0 0 0 -6.7800 25.3600 -33.4600 C 0 0 0 0 0 0 0 0 0 0 0 0 -6.9200 26.6500 -33.1800 N 0 0 0 0 0 0 0 0 0 0 0 0 -6.3000 27.2300 -32.1600 C 0 0 0 0 0 0 0 0 0 0 0 0 -5.5100 26.4600 -31.3100 C 0 0 0 0 0 0 0 0 0 0 0 0 -6.5400 28.5800 -31.8800 N 0 0 0 0 0 0 0 0 0 0 0 0 -5.7100 29.4500 -31.2300 C 0 0 0 0 0 0 0 0 0 0 0 0 -4.6200 29.1200 -30.8100 O 0 0 0 0 0 0 0 0 0 0 0 0 -6.2300 30.8500 -31.0300 C 0 0 1 0 0 0 0 0 0 0 0 0 -5.5800 31.7500 -29.9800 C 0 0 0 0 0 0 0 0 0 0 0 0 -5.3600 32.0200 -31.4700 C 0 0 1 0 0 0 0 0 0 0 0 0 -4.1100 31.7200 -32.0100 F 0 0 0 0 0 0 0 0 0 0 0 0 -1.1100 24.0500 -30.3300 Cl 0 0 0 0 0 0 0 0 0 0 0 0 -7.3100 30.9400 -31.1600 H 0 0 0 0 0 0 0 0 0 0 0 0 -5.8600 32.9000 -31.8800 H 0 0 0 0 0 0 0 0 0 0 0 0 -1.4400 21.1300 -26.4800 H 0 0 0 0 0 0 0 0 0 0 0 0 -0.2600 22.6600 -28.0200 H 0 0 0 0 0 0 0 0 0 0 0 0 -3.8100 20.5600 -26.8900 H 0 0 0 0 0 0 0 0 0 0 0 0 -4.3200 24.9800 -29.8400 H 0 0 0 0 0 0 0 0 0 0 0 0 -5.8400 23.5000 -32.9100 H 0 0 0 0 0 0 0 0 0 0 0 0 -7.3100 24.9400 -34.3000 H 0 0 0 0 0 0 0 0 0 0 0 0 -5.0600 26.9100 -30.4300 H 0 0 0 0 0 0 0 0 0 0 0 0 -7.4000 29.0100 -32.1800 H 0 0 0 0 0 0 0 0 0 0 0 0 -6.3500 32.2000 -29.3600 H 0 0 0 0 0 0 0 0 0 0 0 0 -4.9200 31.1500 -29.3500 H 0 0 0 0 0 0 0 0 0 0 0 0 13 32 1 0 13 14 1 0 12 13 2 0 14 15 2 0 12 31 1 0 11 12 1 0 17 34 1 0 15 17 1 0 15 16 1 0 22 23 1 0 17 18 1 0 22 26 1 6 8 9 2 0 11 16 2 0 10 11 1 0 20 22 1 0 21 22 1 0 16 33 1 0 18 20 1 0 18 19 2 0 20 25 1 6 20 21 1 0 8 10 1 0 4 8 1 0 10 30 1 0 3 24 1 0 21 35 1 0 21 36 1 0 3 4 2 0 4 5 1 0 2 3 1 0 5 7 1 0 5 6 2 0 2 28 1 0 1 2 2 0 1 6 1 0 6 29 1 0 1 27 1 0 M END $$$$ ================================================ FILE: src/openfe/tests/data/openmm_rfe/ligand_55.sdf ================================================ ligand_55 RDKit 3D 33 34 0 0 0 0 0 0 0 0999 V2000 -1.9600 21.5500 -27.3300 C 0 0 0 0 0 0 0 0 0 0 0 0 -1.2900 22.4100 -28.2000 C 0 0 0 0 0 0 0 0 0 0 0 0 -1.9600 22.9500 -29.2900 C 0 0 0 0 0 0 0 0 0 0 0 0 -3.3000 22.6200 -29.5400 C 0 0 0 0 0 0 0 0 0 0 0 0 -3.9700 21.7600 -28.6500 C 0 0 0 0 0 0 0 0 0 0 0 0 -3.2900 21.2300 -27.5600 C 0 0 0 0 0 0 0 0 0 0 0 0 -5.6400 21.3500 -28.9200 Cl 0 0 0 0 0 0 0 0 0 0 0 0 -4.0400 23.1500 -30.7100 C 0 0 0 0 0 0 0 0 0 0 0 0 -4.2300 22.4200 -31.6700 O 0 0 0 0 0 0 0 0 0 0 0 0 -4.5100 24.4100 -30.6500 N 0 0 0 0 0 0 0 0 0 0 0 0 -5.2900 25.1100 -31.5800 C 0 0 0 0 0 0 0 0 0 0 0 0 -5.9600 24.5500 -32.6800 C 0 0 0 0 0 0 0 0 0 0 0 0 -6.7800 25.3600 -33.4600 C 0 0 0 0 0 0 0 0 0 0 0 0 -6.9200 26.6500 -33.1800 N 0 0 0 0 0 0 0 0 0 0 0 0 -6.3000 27.2300 -32.1600 C 0 0 0 0 0 0 0 0 0 0 0 0 -5.5100 26.4600 -31.3100 C 0 0 0 0 0 0 0 0 0 0 0 0 -6.5400 28.5800 -31.8800 N 0 0 0 0 0 0 0 0 0 0 0 0 -5.7100 29.4500 -31.2300 C 0 0 0 0 0 0 0 0 0 0 0 0 -4.6200 29.1200 -30.8100 O 0 0 0 0 0 0 0 0 0 0 0 0 -1.1100 24.0500 -30.3300 Cl 0 0 0 0 0 0 0 0 0 0 0 0 -1.4400 21.1300 -26.4800 H 0 0 0 0 0 0 0 0 0 0 0 0 -0.2600 22.6600 -28.0200 H 0 0 0 0 0 0 0 0 0 0 0 0 -3.8100 20.5600 -26.8900 H 0 0 0 0 0 0 0 0 0 0 0 0 -4.3200 24.9800 -29.8400 H 0 0 0 0 0 0 0 0 0 0 0 0 -5.8400 23.5000 -32.9100 H 0 0 0 0 0 0 0 0 0 0 0 0 -7.3100 24.9400 -34.3000 H 0 0 0 0 0 0 0 0 0 0 0 0 -5.0600 26.9100 -30.4300 H 0 0 0 0 0 0 0 0 0 0 0 0 -7.4000 29.0100 -32.1800 H 0 0 0 0 0 0 0 0 0 0 0 0 -5.1900 31.8500 -30.6800 C 0 0 0 0 0 0 0 0 0 0 0 0 -5.5900 32.8600 -30.8200 H 0 0 0 0 0 0 0 0 0 0 0 0 -4.9100 31.7200 -29.6300 H 0 0 0 0 0 0 0 0 0 0 0 0 -6.2500 30.8500 -31.0300 O 0 0 0 0 0 0 0 0 0 0 0 0 -4.3200 31.7100 -31.3200 H 0 0 0 0 0 0 0 0 0 0 0 0 13 26 1 0 13 14 1 0 12 13 2 0 14 15 2 0 12 25 1 0 11 12 1 0 17 28 1 0 15 17 1 0 15 16 1 0 17 18 1 0 8 9 2 0 11 16 2 0 10 11 1 0 29 33 1 0 16 27 1 0 18 32 1 0 18 19 2 0 29 32 1 0 29 30 1 0 8 10 1 0 4 8 1 0 29 31 1 0 10 24 1 0 3 20 1 0 3 4 2 0 4 5 1 0 2 3 1 0 5 7 1 0 5 6 2 0 2 22 1 0 1 2 2 0 1 6 1 0 6 23 1 0 1 21 1 0 M END $$$$ ================================================ FILE: src/openfe/tests/data/openmm_rfe/malt1_shapefit_1832577-09-9.sdf ================================================ 1832577-09-9 RDKit 3D 42 44 0 0 0 0 0 0 0 0999 V2000 -10.5334 -24.7004 10.8465 C 0 0 0 0 0 0 0 0 0 0 0 0 -12.2375 -23.4317 11.9659 C 0 0 0 0 0 0 0 0 0 0 0 0 -8.0781 -15.7676 14.8202 C 0 0 0 0 0 0 0 0 0 0 0 0 -11.4686 -25.7088 10.6839 C 0 0 0 0 0 0 0 0 0 0 0 0 -10.9226 -23.5382 11.5125 C 0 0 0 0 0 0 0 0 0 0 0 0 -13.1112 -24.4951 11.7511 C 0 0 0 0 0 0 0 0 0 0 0 0 -7.6176 -15.0858 13.6901 C 0 0 0 0 0 0 0 0 0 0 0 0 -8.3276 -17.0469 14.3752 C 0 0 0 0 0 0 0 0 0 0 0 0 -8.9990 -19.1925 14.2702 C 0 0 0 0 0 0 0 0 0 0 0 0 -8.7389 -19.3130 12.8049 C 0 0 0 0 0 0 0 0 0 0 0 0 -8.1967 -18.2212 12.2237 C 0 0 0 0 0 0 0 0 0 0 0 0 -10.0695 -21.3590 12.4332 C 0 0 0 0 0 0 0 0 0 0 0 0 -6.6229 -18.7823 10.3075 C 0 0 0 0 0 0 0 0 0 0 0 0 -9.4574 -17.7523 8.9592 C 0 0 0 0 0 0 0 0 0 0 0 0 -7.9112 -18.0842 10.7331 C 0 0 1 0 0 0 0 0 0 0 0 0 -14.5419 -24.4050 12.1861 C 0 0 0 0 0 0 0 0 0 0 0 0 -12.7444 -25.6344 11.1183 N 0 0 0 0 0 0 0 0 0 0 0 0 -7.5397 -15.8574 12.6119 N 0 0 0 0 0 0 0 0 0 0 0 0 -8.8095 -18.1459 15.0128 N 0 0 0 0 0 0 0 0 0 0 0 0 -8.0014 -17.0717 13.0171 N 0 0 0 0 0 0 0 0 0 0 0 0 -9.9582 -22.5164 11.6556 N 0 0 0 0 0 0 0 0 0 0 0 0 -9.0189 -20.4821 12.1403 N 0 0 0 0 0 0 0 0 0 0 0 0 -10.9683 -21.1116 13.2336 O 0 0 0 0 0 0 0 0 0 0 0 0 -9.0133 -18.6233 9.9903 O 0 0 0 0 0 0 0 0 0 0 0 0 -14.8129 -23.3365 12.9853 F 0 0 0 0 0 0 0 0 0 0 0 0 -15.3944 -24.3052 11.1299 F 0 0 0 0 0 0 0 0 0 0 0 0 -14.9390 -25.5006 12.8886 F 0 0 0 0 0 0 0 0 0 0 0 0 -7.1927 -13.4497 13.6054 Cl 0 0 0 0 0 0 0 0 0 0 0 0 -9.5246 -24.8290 10.4673 H 0 0 0 0 0 0 0 0 0 0 0 0 -12.6096 -22.5382 12.4512 H 0 0 0 0 0 0 0 0 0 0 0 0 -8.2318 -15.3930 15.8221 H 0 0 0 0 0 0 0 0 0 0 0 0 -11.2061 -26.6332 10.1807 H 0 0 0 0 0 0 0 0 0 0 0 0 -9.3567 -20.1035 14.7754 H 0 0 0 0 0 0 0 0 0 0 0 0 -6.6919 -19.8701 10.4066 H 0 0 0 0 0 0 0 0 0 0 0 0 -5.7650 -18.4293 10.8885 H 0 0 0 0 0 0 0 0 0 0 0 0 -6.4262 -18.5845 9.2476 H 0 0 0 0 0 0 0 0 0 0 0 0 -10.2928 -18.2284 8.4403 H 0 0 0 0 0 0 0 0 0 0 0 0 -8.6511 -17.5717 8.2429 H 0 0 0 0 0 0 0 0 0 0 0 0 -9.8072 -16.8053 9.3830 H 0 0 0 0 0 0 0 0 0 0 0 0 -7.8052 -17.0236 10.4761 H 0 0 0 0 0 0 0 0 0 0 0 0 -9.0700 -22.6660 11.1835 H 0 0 0 0 0 0 0 0 0 0 0 0 -8.5590 -20.6256 11.2464 H 0 0 0 0 0 0 0 0 0 0 0 0 1 4 2 0 1 5 1 0 2 5 2 0 2 6 1 0 3 7 1 0 3 8 2 0 4 17 1 0 5 21 1 0 6 16 1 0 6 17 2 0 7 18 2 0 7 28 1 0 8 19 1 0 8 20 1 0 9 10 1 0 9 19 2 0 10 11 2 0 10 22 1 0 11 15 1 0 11 20 1 0 12 21 1 0 12 22 1 0 12 23 2 0 13 15 1 0 14 24 1 0 15 24 1 0 16 25 1 0 16 26 1 0 16 27 1 0 18 20 1 0 1 29 1 0 2 30 1 0 3 31 1 0 4 32 1 0 9 33 1 0 13 34 1 0 13 35 1 0 13 36 1 0 14 37 1 0 14 38 1 0 14 39 1 0 15 40 1 6 21 41 1 0 22 42 1 0 M END > (1) -0.28232385714285713 -0.21832385714285713 -0.27862385714285715 0.42117614285714289 0.10657614285714286 0.34757614285714289 0.39957614285714288 0.34647614285714284 0.41317614285714288 -0.16672385714285712 0.064376142857142854 0.75507614285714286 -0.10212385714285714 0.10967614285714286 0.19037614285714288 0.59957614285714289 -0.63702385714285714 -0.51012385714285713 -0.61002385714285712 0.054176142857142853 -0.46912385714285715 -0.43812385714285712 -0.58612385714285709 -0.38862385714285713 -0.22632385714285713 -0.22632385714285713 -0.22632385714285713 -0.042323857142857142 0.14797614285714286 0.19997614285714288 0.19197614285714287 0.036076142857142855 0.032076142857142852 0.06534314285714285 0.06534314285714285 0.06534314285714285 0.036343142857142852 0.036343142857142852 0.036343142857142852 0.063676142857142862 0.31947614285714288 0.30447614285714286 $$$$ ================================================ FILE: src/openfe/tests/data/openmm_rfe/malt1_shapefit_Pfizer-01-01.sdf ================================================ Pfizer-01-01 RDKit 3D 41 43 0 0 0 0 0 0 0 0999 V2000 -10.4516 -24.7374 10.8592 C 0 0 0 0 0 0 0 0 0 0 0 0 -8.0415 -15.7554 14.6861 C 0 0 0 0 0 0 0 0 0 0 0 0 -12.1995 -23.5068 11.9598 C 0 0 0 0 0 0 0 0 0 0 0 0 -11.3650 -25.7538 10.6519 C 0 0 0 0 0 0 0 0 0 0 0 0 -7.6252 -15.0904 13.5309 C 0 0 0 0 0 0 0 0 0 0 0 0 -10.8751 -23.5938 11.5374 C 0 0 0 0 0 0 0 0 0 0 0 0 -13.0474 -24.5795 11.6985 C 0 0 0 0 0 0 0 0 0 0 0 0 -8.3405 -17.0307 14.2671 C 0 0 0 0 0 0 0 0 0 0 0 0 -9.0021 -19.1792 14.2556 C 0 0 0 0 0 0 0 0 0 0 0 0 -8.7289 -19.3573 12.8025 C 0 0 0 0 0 0 0 0 0 0 0 0 -8.2349 -18.2799 12.1537 C 0 0 0 0 0 0 0 0 0 0 0 0 -10.0585 -21.4037 12.4667 C 0 0 0 0 0 0 0 0 0 0 0 0 -9.1650 -17.7186 9.8701 C 0 0 0 0 0 0 0 0 0 0 0 0 -6.6506 -17.6895 10.1921 C 0 0 0 0 0 0 0 0 0 0 0 0 -7.9771 -18.2985 10.6433 C 0 0 0 0 0 0 0 0 0 0 0 0 -14.4786 -24.5193 12.1303 C 0 0 0 0 0 0 0 0 0 0 0 0 -12.6493 -25.7028 11.0565 N 0 0 0 0 0 0 0 0 0 0 0 0 -7.6436 -15.8678 12.4511 N 0 0 0 0 0 0 0 0 0 0 0 0 -8.8156 -18.1033 14.9523 N 0 0 0 0 0 0 0 0 0 0 0 0 -8.0598 -17.0872 12.8947 N 0 0 0 0 0 0 0 0 0 0 0 0 -9.9191 -22.5788 11.7247 N 0 0 0 0 0 0 0 0 0 0 0 0 -8.9690 -20.5680 12.2086 N 0 0 0 0 0 0 0 0 0 0 0 0 -11.0007 -21.1080 13.1964 O 0 0 0 0 0 0 0 0 0 0 0 0 -15.1528 -23.4749 11.5765 F 0 0 0 0 0 0 0 0 0 0 0 0 -15.1768 -25.6365 11.7900 F 0 0 0 0 0 0 0 0 0 0 0 0 -14.6164 -24.3881 13.4776 F 0 0 0 0 0 0 0 0 0 0 0 0 -9.4316 -24.8426 10.5033 H 0 0 0 0 0 0 0 0 0 0 0 0 -8.1283 -15.3694 15.6916 H 0 0 0 0 0 0 0 0 0 0 0 0 -12.5978 -22.6339 12.4625 H 0 0 0 0 0 0 0 0 0 0 0 0 -11.0765 -26.6639 10.1381 H 0 0 0 0 0 0 0 0 0 0 0 0 -7.3103 -14.0623 13.4264 H 0 0 0 0 0 0 0 0 0 0 0 0 -9.3639 -20.0703 14.7933 H 0 0 0 0 0 0 0 0 0 0 0 0 -9.3154 -16.6559 10.0803 H 0 0 0 0 0 0 0 0 0 0 0 0 -10.0909 -18.2494 10.1233 H 0 0 0 0 0 0 0 0 0 0 0 0 -9.0120 -17.8326 8.7910 H 0 0 0 0 0 0 0 0 0 0 0 0 -6.6454 -16.5986 10.2486 H 0 0 0 0 0 0 0 0 0 0 0 0 -6.4604 -17.9536 9.1452 H 0 0 0 0 0 0 0 0 0 0 0 0 -5.8198 -18.0816 10.7876 H 0 0 0 0 0 0 0 0 0 0 0 0 -7.9000 -19.3380 10.3085 H 0 0 0 0 0 0 0 0 0 0 0 0 -9.0114 -22.7367 11.2938 H 0 0 0 0 0 0 0 0 0 0 0 0 -8.4315 -20.8010 11.3813 H 0 0 0 0 0 0 0 0 0 0 0 0 1 4 2 0 1 6 1 0 2 5 1 0 2 8 2 0 3 6 2 0 3 7 1 0 4 17 1 0 5 18 2 0 6 21 1 0 7 16 1 0 7 17 2 0 8 19 1 0 8 20 1 0 9 10 1 0 9 19 2 0 10 11 2 0 10 22 1 0 11 15 1 0 11 20 1 0 12 21 1 0 12 22 1 0 12 23 2 0 13 15 1 0 14 15 1 0 16 24 1 0 16 25 1 0 16 26 1 0 18 20 1 0 1 27 1 0 2 28 1 0 3 29 1 0 4 30 1 0 5 31 1 0 9 32 1 0 13 33 1 0 13 34 1 0 13 35 1 0 14 36 1 0 14 37 1 0 14 38 1 0 15 39 1 0 21 40 1 0 22 41 1 0 M END > (1) -0.24122690243902437 -0.29752690243902435 -0.26022690243902435 0.41927309756097564 0.37157309756097562 0.10867309756097562 0.35167309756097564 0.3465730975609756 0.45327309756097561 -0.13062690243902439 0.019473097560975618 0.77017309756097563 -0.094026902439024382 -0.094026902439024382 -0.016326902439024384 0.59867309756097564 -0.63792690243902439 -0.56402690243902442 -0.61792690243902437 0.051273097560975624 -0.4700269024390244 -0.44502690243902437 -0.59702690243902434 -0.22855990243902438 -0.22855990243902438 -0.22855990243902438 0.19107309756097562 0.18307309756097562 0.16007309756097562 0.039173097560975624 0.055873097560975624 0.059173097560975621 0.048940097560975622 0.048940097560975622 0.048940097560975622 0.048940097560975622 0.048940097560975622 0.048940097560975622 0.045773097560975619 0.32057309756097563 0.31257309756097562 $$$$ ================================================ FILE: src/openfe/tests/data/openmm_rfe/reference.xml ================================================ ================================================ FILE: src/openfe/tests/data/openmm_septop/__init__.py ================================================ ================================================ FILE: src/openfe/tests/data/serialization/__init__.py ================================================ ================================================ FILE: src/openfe/tests/data/serialization/ethane_template.sdf ================================================ RDKit 2D 8 7 0 0 0 0 0 0 0 0999 V2000 0.0000 0.0000 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 1.5000 0.0000 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 -1.5000 0.0000 0.0000 H 0 0 0 0 0 0 0 0 0 0 0 0 0.0000 1.5000 0.0000 H 0 0 0 0 0 0 0 0 0 0 0 0 -0.0000 -1.5000 0.0000 H 0 0 0 0 0 0 0 0 0 0 0 0 3.0000 0.0000 0.0000 H 0 0 0 0 0 0 0 0 0 0 0 0 1.5000 -1.5000 0.0000 H 0 0 0 0 0 0 0 0 0 0 0 0 1.5000 1.5000 0.0000 H 0 0 0 0 0 0 0 0 0 0 0 0 1 2 1 0 1 3 1 0 1 4 1 0 1 5 1 0 2 6 1 0 2 7 1 0 2 8 1 0 M END > ethane > {GUFE_VERSION} $$$$ ================================================ FILE: src/openfe/tests/data/serialization/network_template.graphml ================================================ {"__module__": "gufe.components.smallmoleculecomponent", "__qualname__": "SmallMoleculeComponent", "atoms": [[6, 0, 0, false, 0, 0, {}], [6, 0, 0, false, 0, 0, {}]], "bonds": [[0, 1, 1, 0, {}]], "conformer": ["\u0093NUMPY\u0001\u0000v\u0000{'descr': '<f8', 'fortran_order': False, 'shape': (2, 3), } \n\u0000\u0000\u0000\u0000\u0000\u0000\u00e8\u00bf\u0000\u0000\u0000\u0000\u0000\u0000\u0090<\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u00e8?\u0000\u0000\u0000\u0000\u0000\u0000\u0090\u00bc\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000", {}], "molprops": {"ofe-name": ""}} {"__module__": "gufe.components.smallmoleculecomponent", "__qualname__": "SmallMoleculeComponent", "atoms": [[6, 0, 0, false, 0, 0, {}], [6, 0, 0, false, 0, 0, {}], [8, 0, 0, false, 0, 0, {}]], "bonds": [[0, 1, 1, 0, {}], [1, 2, 1, 0, {}]], "conformer": ["\u0093NUMPY\u0001\u0000v\u0000{'descr': '<f8', 'fortran_order': False, 'shape': (3, 3), } \n\u00809B.\u00dc\u00c8\u00f4\u00bf\u00f5\u00ff\u00ff\u00ff\u00ff\u00ff\u00cf\u00bf\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0001\u0000\u0000\u0000\u0000\u0000\u00e0?\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u00809B.\u00dc\u00c8\u00f4?\u0006\u0000\u0000\u0000\u0000\u0000\u00d0\u00bf\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000", {}], "molprops": {"ofe-name": ""}} {"__module__": "gufe.components.smallmoleculecomponent", "__qualname__": "SmallMoleculeComponent", "atoms": [[6, 0, 0, false, 0, 0, {}], [8, 0, 0, false, 0, 0, {}]], "bonds": [[0, 1, 1, 0, {}]], "conformer": ["\u0093NUMPY\u0001\u0000v\u0000{'descr': '<f8', 'fortran_order': False, 'shape': (2, 3), } \n\u0000\u0000\u0000\u0000\u0000\u0000\u00e8\u00bf\u0000\u0000\u0000\u0000\u0000\u0000\u0090<\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u00e8?\u0000\u0000\u0000\u0000\u0000\u0000\u0090\u00bc\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000", {}], "molprops": {"ofe-name": ""}} [[0, 0]] [[0, 0], [1, 1]] [[0, 0], [2, 1]] {OFE_VERSION} ================================================ FILE: src/openfe/tests/dev/__init__.py ================================================ ================================================ FILE: src/openfe/tests/dev/serialization_test_templates.py ================================================ #!/usr/bin/env python # This script creates several files used in testing setup serialization: # # * openfe/tests/data/multi_molecule.sdf # * openfe/tests/data/serialization/ethane_template.sdf # * openfe/tests/data/serialization/network_template.graphml # # The two serialization templates need manual editing to replace the current # version of gufe with: # {GUFE_VERSION} from rdkit import Chem from rdkit.Chem import AllChem from openfe import LigandAtomMapping, LigandNetwork, SmallMoleculeComponent # multi_molecule.sdf mol1 = Chem.MolFromSmiles("CCO") mol2 = Chem.MolFromSmiles("CCC") writer = Chem.SDWriter("multi_molecule.sdf") writer.write(mol1) writer.write(mol2) writer.close() def mol_from_smiles(smiles: str) -> Chem.Mol: m = Chem.MolFromSmiles(smiles) AllChem.Compute2DCoords(m) # type: ignore[attr-defined] return m # ethane_template.sdf m = SmallMoleculeComponent(mol_from_smiles("CC"), name="ethane") with open("ethane_template.sdf", mode="w") as tmpl: tmpl.write(m.to_sdf()) # ethane_with_H_template.sdf m2 = SmallMoleculeComponent(Chem.AddHs(m.to_rdkit())) with open("ethane_with_H_template.sdf", mode="w") as tmpl: tmpl.write(m2.to_sdf()) # network_template.graphml mol1 = SmallMoleculeComponent(mol_from_smiles("CCO")) mol2 = SmallMoleculeComponent(mol_from_smiles("CC")) mol3 = SmallMoleculeComponent(mol_from_smiles("CO")) edge12 = LigandAtomMapping(mol1, mol2, {0: 0, 1: 1}) edge23 = LigandAtomMapping(mol2, mol3, {0: 0}) edge13 = LigandAtomMapping(mol1, mol3, {0: 0, 2: 1}) network = LigandNetwork([edge12, edge23, edge13]) with open("network_template.graphml", "w") as fn: fn.write(network.to_graphml()) ================================================ FILE: src/openfe/tests/protocols/__init__.py ================================================ ================================================ FILE: src/openfe/tests/protocols/conftest.py ================================================ # This code is part of OpenFE and is licensed under the MIT license. # For details, see https://github.com/OpenFreeEnergy/openfe import gzip import pathlib from importlib import resources from typing import Optional import MDAnalysis as mda import openmm import pooch import pytest from gufe.tests.test_tokenization import GufeTokenizableTestsMixin from openff.units import Quantity, unit from openff.units.openmm import from_openmm from openmm import Platform from rdkit import Chem from rdkit.Geometry import Point3D import openfe from openfe.data._registry import ( POOCH_CACHE, zenodo_industry_benchmark_systems, zenodo_md_resume_data, zenodo_resume_data, zenodo_rfe_simulation_nc, zenodo_t4_lysozyme_traj, ) @pytest.fixture def benzene_vacuum_system(benzene_modifications): return openfe.ChemicalSystem( {"ligand": benzene_modifications["benzene"]}, ) @pytest.fixture(scope="session") def benzene_system(benzene_modifications): return openfe.ChemicalSystem( { "ligand": benzene_modifications["benzene"], "solvent": openfe.SolventComponent( positive_ion="Na", negative_ion="Cl", ion_concentration=0.15 * unit.molar, ), }, ) @pytest.fixture def benzene_complex_system(benzene_modifications, T4_protein_component): return openfe.ChemicalSystem( { "ligand": benzene_modifications["benzene"], "solvent": openfe.SolventComponent( positive_ion="Na", negative_ion="Cl", ion_concentration=0.15 * unit.molar, ), "protein": T4_protein_component, } ) @pytest.fixture def toluene_vacuum_system(benzene_modifications): return openfe.ChemicalSystem( {"ligand": benzene_modifications["toluene"]}, ) @pytest.fixture(scope="session") def toluene_system(benzene_modifications): return openfe.ChemicalSystem( { "ligand": benzene_modifications["toluene"], "solvent": openfe.SolventComponent( positive_ion="Na", negative_ion="Cl", ion_concentration=0.15 * unit.molar ), }, ) @pytest.fixture def toluene_complex_system(benzene_modifications, T4_protein_component): return openfe.ChemicalSystem( { "ligand": benzene_modifications["toluene"], "solvent": openfe.SolventComponent( positive_ion="Na", negative_ion="Cl", ion_concentration=0.15 * unit.molar ), "protein": T4_protein_component, } ) @pytest.fixture(scope="session") def benzene_to_toluene_mapping(benzene_modifications): mapper = openfe.setup.LomapAtomMapper(element_change=False) molA = benzene_modifications["benzene"] molB = benzene_modifications["toluene"] return next(mapper.suggest_mappings(molA, molB)) @pytest.fixture def benzene_charges(): files = {} with resources.as_file(resources.files("openfe.tests.data.openmm_rfe")) as d: fn = str(d / "charged_benzenes.sdf") supp = Chem.SDMolSupplier(str(fn), removeHs=False) for rdmol in supp: files[rdmol.GetProp("_Name")] = openfe.SmallMoleculeComponent(rdmol) return files @pytest.fixture def benzene_to_benzoic_mapping(benzene_charges): mapper = openfe.setup.LomapAtomMapper(element_change=False) molA = benzene_charges["benzene"] molB = benzene_charges["benzoic_acid"] return next(mapper.suggest_mappings(molA, molB)) @pytest.fixture def benzoic_to_benzene_mapping(benzene_charges): mapper = openfe.setup.LomapAtomMapper(element_change=False) molA = benzene_charges["benzoic_acid"] molB = benzene_charges["benzene"] return next(mapper.suggest_mappings(molA, molB)) @pytest.fixture def benzene_to_aniline_mapping(benzene_charges): mapper = openfe.setup.LomapAtomMapper(element_change=False) molA = benzene_charges["benzene"] molB = benzene_charges["aniline"] return next(mapper.suggest_mappings(molA, molB)) @pytest.fixture def aniline_to_benzene_mapping(benzene_charges): mapper = openfe.setup.LomapAtomMapper(element_change=False) molA = benzene_charges["aniline"] molB = benzene_charges["benzene"] return next(mapper.suggest_mappings(molA, molB)) @pytest.fixture def aniline_to_benzoic_mapping(benzene_charges): mapper = openfe.setup.LomapAtomMapper(element_change=False) molA = benzene_charges["aniline"] molB = benzene_charges["benzoic_acid"] return next(mapper.suggest_mappings(molA, molB)) @pytest.fixture def benzene_many_solv_system(benzene_modifications): rdmol_phenol = benzene_modifications["phenol"].to_rdkit() rdmol_benzo = benzene_modifications["benzonitrile"].to_rdkit() conf_phenol = rdmol_phenol.GetConformer() conf_benzo = rdmol_benzo.GetConformer() for atm in range(rdmol_phenol.GetNumAtoms()): x, y, z = conf_phenol.GetAtomPosition(atm) conf_phenol.SetAtomPosition(atm, Point3D(x + 30, y, z)) for atm in range(rdmol_benzo.GetNumAtoms()): x, y, z = conf_benzo.GetAtomPosition(atm) conf_benzo.SetAtomPosition(atm, Point3D(x, y + 30, z)) phenol = openfe.SmallMoleculeComponent.from_rdkit(rdmol_phenol, name="phenol") benzo = openfe.SmallMoleculeComponent.from_rdkit(rdmol_benzo, name="benzonitrile") return openfe.ChemicalSystem( { "whatligand": benzene_modifications["benzene"], "foo": phenol, "bar": benzo, "solvent": openfe.SolventComponent(), }, ) @pytest.fixture def toluene_many_solv_system(benzene_modifications): rdmol_phenol = benzene_modifications["phenol"].to_rdkit() rdmol_benzo = benzene_modifications["benzonitrile"].to_rdkit() conf_phenol = rdmol_phenol.GetConformer() conf_benzo = rdmol_benzo.GetConformer() for atm in range(rdmol_phenol.GetNumAtoms()): x, y, z = conf_phenol.GetAtomPosition(atm) conf_phenol.SetAtomPosition(atm, Point3D(x + 30, y, z)) for atm in range(rdmol_benzo.GetNumAtoms()): x, y, z = conf_benzo.GetAtomPosition(atm) conf_benzo.SetAtomPosition(atm, Point3D(x, y + 30, z)) phenol = openfe.SmallMoleculeComponent.from_rdkit(rdmol_phenol, name="phenol") benzo = openfe.SmallMoleculeComponent.from_rdkit(rdmol_benzo, name="benzonitrile") return openfe.ChemicalSystem( { "whatligand": benzene_modifications["toluene"], "foo": phenol, "bar": benzo, "solvent": openfe.SolventComponent(), }, ) @pytest.fixture def rfe_transformation_json() -> str: """string of a RFE results similar to quickrun generated with gen-serialized-results.py """ d = resources.files("openfe.tests.data.openmm_rfe") with gzip.open((d / "RHFEProtocol_json_results.gz").as_posix(), "r") as f: # type: ignore return f.read().decode() # type: ignore @pytest.fixture def afe_solv_transformation_json() -> str: """ string of a Absolute Solvation result (CN in water) generated by quickrun generated with gen-serialized-results.py """ d = resources.files("openfe.tests.data.openmm_afe") fname = "AHFEProtocol_json_results.gz" with gzip.open((d / fname).as_posix(), "r") as f: # type: ignore return f.read().decode() # type: ignore @pytest.fixture def abfe_transformation_json_path() -> str: """ Path to an Absolute Binding result (tyk2 complex) generated by quickrun generated with gen-serialized-results.py """ d = resources.files("openfe.tests.data.openmm_afe") fname = "ABFEProtocol_json_results.json.gz" return str(d / fname) @pytest.fixture def md_json() -> str: """ string of a MD result (TYK ligand lig_ejm_31 in water) generated by quickrun generated with gen-serialized-results.py """ d = resources.files("openfe.tests.data.openmm_md") fname = "MDProtocol_json_results.gz" with gzip.open((d / fname).as_posix(), "r") as f: # type: ignore return f.read().decode() # type: ignore @pytest.fixture def septop_json() -> str: """ Path to a SepTop result (hif2a) generated with gen-serialized-results.py """ d = resources.files("openfe.tests.data.openmm_septop") fname = "SepTopProtocol_json_results.gz" with gzip.open((d / fname).as_posix(), "r") as f: # type: ignore return f.read().decode() # type: ignore pooch_industry_benchmark_systems = pooch.create( path=POOCH_CACHE, base_url=zenodo_industry_benchmark_systems["base_url"], registry={ zenodo_industry_benchmark_systems["fname"]: zenodo_industry_benchmark_systems["known_hash"] }, ) @pytest.fixture def industry_benchmark_files(): pooch_industry_benchmark_systems.fetch( "industry_benchmark_systems.zip", processor=pooch.Unzip() ) cache_dir = pathlib.Path( POOCH_CACHE / "industry_benchmark_systems.zip.unzip/industry_benchmark_systems" ) return cache_dir pooch_t4_lysozyme = pooch.create( path=POOCH_CACHE, base_url=zenodo_t4_lysozyme_traj["base_url"], registry={zenodo_t4_lysozyme_traj["fname"]: zenodo_t4_lysozyme_traj["known_hash"]}, ) # session scope for downstream reuse @pytest.fixture(scope="session") def t4_lysozyme_trajectory_dir(): pooch_t4_lysozyme.fetch("t4_lysozyme_trajectory.zip", processor=pooch.Unzip()) cache_dir = pathlib.Path( POOCH_CACHE / "t4_lysozyme_trajectory.zip.unzip/t4_lysozyme_trajectory" ) return cache_dir @pytest.fixture def simulation_nc(): return pooch.retrieve( url=zenodo_rfe_simulation_nc["base_url"] + zenodo_rfe_simulation_nc["fname"], known_hash=zenodo_rfe_simulation_nc["known_hash"], path=POOCH_CACHE, ) pooch_resume_data = pooch.create( path=POOCH_CACHE, base_url=zenodo_resume_data["base_url"], registry={zenodo_resume_data["fname"]: zenodo_resume_data["known_hash"]}, ) @pytest.fixture(scope="session") def htop_trajectory_path(): pooch_resume_data.fetch("multistate_checkpoints.zip", processor=pooch.Unzip()) topdir = "multistate_checkpoints.zip.unzip/multistate_checkpoints" subdir = "hybrid_top" filename = "simulation.nc" return pathlib.Path(pooch.os_cache("openfe") / f"{topdir}/{subdir}/{filename}") @pytest.fixture(scope="session") def htop_checkpoint_path(): pooch_resume_data.fetch("multistate_checkpoints.zip", processor=pooch.Unzip()) topdir = "multistate_checkpoints.zip.unzip/multistate_checkpoints" subdir = "hybrid_top" filename = "checkpoint.chk" return pathlib.Path(pooch.os_cache("openfe") / f"{topdir}/{subdir}/{filename}") @pytest.fixture(scope="module") def ahfe_vac_trajectory_path(): pooch_resume_data.fetch("multistate_checkpoints.zip", processor=pooch.Unzip()) topdir = "multistate_checkpoints.zip.unzip/multistate_checkpoints" subdir = "ahfes" filename = "vacuum.nc" return pathlib.Path(pooch.os_cache("openfe") / f"{topdir}/{subdir}/{filename}") @pytest.fixture(scope="module") def vac_checkpoint_path(): pooch_resume_data.fetch("multistate_checkpoints.zip", processor=pooch.Unzip()) topdir = "multistate_checkpoints.zip.unzip/multistate_checkpoints" subdir = "ahfes" filename = "vacuum_checkpoint.nc" return pathlib.Path(pooch.os_cache("openfe") / f"{topdir}/{subdir}/{filename}") @pytest.fixture(scope="module") def ahfe_solv_trajectory_path(): pooch_resume_data.fetch("multistate_checkpoints.zip", processor=pooch.Unzip()) topdir = "multistate_checkpoints.zip.unzip/multistate_checkpoints" subdir = "ahfes" filename = "solvent.nc" return pathlib.Path(pooch.os_cache("openfe") / f"{topdir}/{subdir}/{filename}") @pytest.fixture(scope="module") def ahfe_solv_checkpoint_path(): pooch_resume_data.fetch("multistate_checkpoints.zip", processor=pooch.Unzip()) topdir = "multistate_checkpoints.zip.unzip/multistate_checkpoints" subdir = "ahfes" filename = "solvent_checkpoint.nc" return pathlib.Path(pooch.os_cache("openfe") / f"{topdir}/{subdir}/{filename}") @pytest.fixture(scope="module") def septop_solv_trajectory_path(): pooch_resume_data.fetch("multistate_checkpoints.zip", processor=pooch.Unzip()) topdir = "multistate_checkpoints.zip.unzip/multistate_checkpoints" subdir = "septop" filename = "solvent.nc" return pathlib.Path(pooch.os_cache("openfe") / f"{topdir}/{subdir}/{filename}") @pytest.fixture(scope="module") def septop_solv_checkpoint_path(): pooch_resume_data.fetch("multistate_checkpoints.zip", processor=pooch.Unzip()) topdir = "multistate_checkpoints.zip.unzip/multistate_checkpoints" subdir = "septop" filename = "solvent_checkpoint.nc" return pathlib.Path(pooch.os_cache("openfe") / f"{topdir}/{subdir}/{filename}") pooch_md_resume_data = pooch.create( path=POOCH_CACHE, base_url=zenodo_md_resume_data["base_url"], registry={zenodo_md_resume_data["fname"]: zenodo_md_resume_data["known_hash"]}, ) @pytest.fixture(scope="module") def plain_md_checkpoint_path(): pooch_md_resume_data.fetch("checkpoint.xml") return pathlib.Path(pooch.os_cache("openfe") / "checkpoint.xml") @pytest.fixture(scope="session") def available_platforms() -> set[str]: return { Platform.getPlatform(i).getName() for i in range(Platform.getNumPlatforms()) } # fmt: skip @pytest.fixture(scope="session") def get_available_openmm_platforms() -> set[str]: """ OpenMM Platforms that are available and functional on system """ import openmm from openmm import Platform # Get platforms that openmm was built with platforms = {Platform.getPlatform(i).getName() for i in range(Platform.getNumPlatforms())} # Now check if we can actually use the platforms working_platforms = set() for platform in platforms: system = openmm.System() system.addParticle(1.0) integrator = openmm.VerletIntegrator(0.001) try: context = openmm.Context(system, integrator, Platform.getPlatformByName(platform)) working_platforms.add(platform) del context except openmm.OpenMMException: continue finally: del system, integrator return working_platforms class ModGufeTokenizableTestsMixin(GufeTokenizableTestsMixin): """ A modified gufe tokenizable tests mixin which allows for repr to be lazily evaluated. """ def test_repr(self, instance): """ Overwrites the base `test_repr` call. """ assert isinstance(repr(instance), str) assert self.repr in repr(instance) def compute_energy( system: openmm.System, positions: openmm.unit.Quantity, box_vectors: Optional[openmm.unit.Quantity], context_params: Optional[dict[str, float]] = None, platform=None, ) -> Quantity: """ Computes the potential energy of a system at a given set of positions. Parameters ---------- system: openmm.System The system to compute the energy of. positions: openmm.unit.Quantity The positions to compute the energy at. box_vectors: Optional[openmm.unit.Quantity] The box vectors to use if any. context_params: Optional[dict[str, float]] Any global context parameters to set. platform: str The platform to use. Returns ------- potential : openff.units.Quantity The computed potential energy in openff unit. """ context_params = context_params if context_params is not None else {} integrator = openmm.VerletIntegrator(0.0001 * openmm.unit.femtoseconds) if platform is None: context = openmm.Context(system, integrator) if platform is not None: context = openmm.Context(system, integrator, platform) for key, value in context_params.items(): context.setParameter(key, value) if box_vectors is not None: context.setPeriodicBoxVectors(*box_vectors) context.setPositions(positions) state = context.getState(getEnergy=True) potential = state.getPotentialEnergy() del context, integrator, state return from_openmm(potential) ================================================ FILE: src/openfe/tests/protocols/openmm_abfe/__init__.py ================================================ ================================================ FILE: src/openfe/tests/protocols/openmm_abfe/conftest.py ================================================ # This code is part of OpenFE and is licensed under the MIT license. # For details, see https://github.com/OpenFreeEnergy/openfe import gufe import pytest from openfe.protocols import openmm_afe @pytest.fixture def benzene_complex_dag(benzene_modifications, T4_protein_component): s = openmm_afe.AbsoluteBindingProtocol.default_settings() s.complex_output_settings.output_indices = "not water" s.solvent_output_settings.output_indices = "not water" protocol = openmm_afe.AbsoluteBindingProtocol( settings=s, ) stateA = gufe.ChemicalSystem( { "protein": T4_protein_component, "benzene": benzene_modifications["benzene"], "solvent": gufe.SolventComponent(), } ) stateB = gufe.ChemicalSystem( { "protein": T4_protein_component, "solvent": gufe.SolventComponent(), } ) return protocol.create(stateA=stateA, stateB=stateB, mapping=None) ================================================ FILE: src/openfe/tests/protocols/openmm_abfe/test_abfe_energies.py ================================================ # This code is part of OpenFE and is licensed under the MIT license. # For details, see https://github.com/OpenFreeEnergy/openfe import collections import copy from importlib import resources import gufe import numpy as np import openmm import pytest from openmm import Platform from openmm import unit as ommunit from openmmtools.alchemy import ( AbsoluteAlchemicalFactory, AlchemicalRegion, AlchemicalState, ) from openfe.protocols import openmm_afe from openfe.protocols.openmm_afe.abfe_units import ( ABFEComplexSetupUnit, ) from openfe.protocols.openmm_utils.omm_settings import OpenMMSolvationSettings from openfe.protocols.openmm_utils.serialization import deserialize class AlchemStateRest(AlchemicalState): """ A modified AlchemicalState for testing. Note: we don't need this in the main protocol since we use composable thermodynamic states. """ lambda_restraints = AlchemicalState._LambdaParameter("lambda_restraints") def get_alchemical_energy_components(alchemical_system, alchemical_state, positions, platform): """Compute potential energy of the alchemical system by Force. This can be useful for debug and analysis. Parameters ---------- alchemical_system : openmm.AlchemicalSystem An alchemically modified system. alchemical_state : AlchemicalState The alchemical state to set the Context to. positions : openmm.unit.Quantity of dimension (natoms, 3) Coordinates to use for energy test (units of distance). platform : openmm.Platform, optional The OpenMM platform to use to compute the energy. If None, OpenMM tries to select the fastest available. Returns ------- energy_components : dict str: openmm.unit.Quantity A string label describing the role of the force associated to its contribution to the potential energy. """ # Find and label all forces. force_labels = AbsoluteAlchemicalFactory._find_force_components(alchemical_system) assert len(force_labels) <= 32, ( "The alchemical system has more than 32 force groups; " "can't compute individual force component energies." ) # Create deep copy of alchemical system. system = copy.deepcopy(alchemical_system) # Separate all forces into separate force groups. for force_index, force in enumerate(system.getForces()): force.setForceGroup(force_index) assert len(force_labels) == len(system.getForces()) # Create a Context in the given state. integrator = openmm.LangevinMiddleIntegrator( 300 * openmm.unit.kelvin, 1.0 / openmm.unit.picosecond, 1.0 * openmm.unit.femtoseconds, ) # integrator = openmm.VerletIntegrator(0.0 * ommunit.femtoseconds) context = openmm.Context(system, integrator, platform) context.setPeriodicBoxVectors(*system.getDefaultPeriodicBoxVectors()) context.setPositions(np.round(positions, 3)) context.setVelocitiesToTemperature(300, 42) alchemical_state.apply_to_context(context) # Get energy components energy_components = collections.OrderedDict() for force_label, force_index in force_labels.items(): energy_components[force_label] = context.getState( getEnergy=True, groups={force_index}, ).getPotentialEnergy() # Clean up del context, integrator return energy_components @pytest.mark.slow class TestT4EnergiesRegression: """ Test: * Regression of a system energies against a previously serialized one. * That the energies do what we think they should be doing. """ @pytest.fixture() def t4_reference_system(self): with resources.as_file(resources.files("openfe.tests.data.openmm_afe")) as d: f = d / "T4_abfe_system.xml.bz2" system = deserialize(f) return system @pytest.fixture() def t4_validation_data(self, benzene_modifications, T4_protein_component, tmp_path): s = openmm_afe.AbsoluteBindingProtocol.default_settings() s.protocol_repeats = 1 s.engine_settings.compute_platform = "cpu" s.forcefield_settings.small_molecule_forcefield = "openff-2.2.1" s.complex_solvation_settings = OpenMMSolvationSettings( solvent_padding=None, number_of_solvent_molecules=1000, box_shape="dodecahedron", ) protocol = openmm_afe.AbsoluteBindingProtocol(settings=s) stateA = gufe.ChemicalSystem( { "protein": T4_protein_component, "benzene": benzene_modifications["benzene"], "solvent": gufe.SolventComponent(), } ) stateB = gufe.ChemicalSystem( { "protein": T4_protein_component, "solvent": gufe.SolventComponent(), } ) dag = protocol.create(stateA=stateA, stateB=stateB, mapping=None) complex_units = [u for u in dag.protocol_units if isinstance(u, ABFEComplexSetupUnit)] results = complex_units[0].run( dry=True, scratch_basepath=tmp_path, shared_basepath=tmp_path ) return results @staticmethod def get_energy_components( system, indices, positions, lambda_sterics, lambda_electrostatics, lambda_restraints, ): platform = Platform.getPlatformByName("Reference") alchemical_region = AlchemicalRegion(alchemical_atoms=indices) alchemical_state = AlchemStateRest.from_system( system, parameters_name_suffix=alchemical_region.name ) alchemical_state.lambda_sterics = lambda_sterics alchemical_state.lambda_electrostatics = lambda_electrostatics alchemical_state.lambda_restraints = lambda_restraints return get_alchemical_energy_components( system, alchemical_state, positions, platform=platform ) @pytest.mark.parametrize("lambda_val", [0, 1]) def test_energies_regression(self, lambda_val, t4_reference_system, t4_validation_data): energies_ref = self.get_energy_components( t4_reference_system, t4_validation_data["alchem_indices"], t4_validation_data["debug_positions"], lambda_val, lambda_val, lambda_val, ) energies_val = self.get_energy_components( t4_validation_data["alchem_system"], t4_validation_data["alchem_indices"], t4_validation_data["debug_positions"], lambda_val, lambda_val, lambda_val, ) # Check the keys match assert [k for k in energies_ref.keys()] == [k for k in energies_val.keys()] for key in energies_ref.keys(): e_ref = energies_ref[key].value_in_unit(ommunit.kilojoule_per_mole) e_val = energies_val[key].value_in_unit(ommunit.kilojoule_per_mole) assert pytest.approx(e_ref, abs=1e-3) == e_val def test_lambda_scale(self, t4_validation_data): def assert_energies(actual, expected, nonbonded_lower: bool): assert [k for k in expected.keys()] == [k for k in actual.keys()] for key in expected.keys(): e_ref = expected[key].value_in_unit(ommunit.kilojoule_per_mole) e_val = actual[key].value_in_unit(ommunit.kilojoule_per_mole) # Knowing exactly by how much the NBF has reduced is hard, so we # just check it's lower if nonbonded_lower and key == "unmodified NonbondedForce": assert e_val < e_ref else: assert e_val == pytest.approx(e_ref, abs=0.1) # lambda 1 on all energies = self.get_energy_components( t4_validation_data["alchem_system"], t4_validation_data["alchem_indices"], t4_validation_data["debug_positions"], lambda_sterics=1.0, lambda_electrostatics=1.0, lambda_restraints=1.0, ) # turn off restraints expected = copy.deepcopy(energies) expected["unmodified CustomCompoundBondForce"] = 0 * ommunit.kilojoule_per_mole energies = self.get_energy_components( t4_validation_data["alchem_system"], t4_validation_data["alchem_indices"], t4_validation_data["debug_positions"], lambda_sterics=1.0, lambda_electrostatics=1.0, lambda_restraints=0.0, ) assert_energies(energies, expected, nonbonded_lower=False) # turn off electrostatics energies = self.get_energy_components( t4_validation_data["alchem_system"], t4_validation_data["alchem_indices"], t4_validation_data["debug_positions"], lambda_sterics=1.0, lambda_electrostatics=0.0, lambda_restraints=0.0, ) # assert all but the NonbondedForce, that should just be lower assert_energies(energies, expected, nonbonded_lower=True) # turn off sterics expected = copy.deepcopy(energies) expected["alchemically modified NonbondedForce for non-alchemical/alchemical sterics"] = ( 0 * ommunit.kilojoule_per_mole ) expected[ "alchemically modified BondForce for non-alchemical/alchemical sterics exceptions" ] = 0 * ommunit.kilojoule_per_mole energies = self.get_energy_components( t4_validation_data["alchem_system"], t4_validation_data["alchem_indices"], t4_validation_data["debug_positions"], lambda_sterics=0.0, lambda_electrostatics=0.0, lambda_restraints=0.0, ) # assert all but the NonbondedForce, that should just be lower assert_energies(energies, expected, nonbonded_lower=False) ================================================ FILE: src/openfe/tests/protocols/openmm_abfe/test_abfe_protocol.py ================================================ # This code is part of OpenFE and is licensed under the MIT license. # For details, see https://github.com/OpenFreeEnergy/openfe from math import sqrt from unittest import mock import gufe import mdtraj as mdt import numpy as np import openmm import pytest from numpy.testing import assert_allclose from openff.units import unit as offunit from openff.units.openmm import from_openmm, to_openmm from openmm import ( CustomBondForce, CustomCompoundBondForce, CustomNonbondedForce, HarmonicAngleForce, HarmonicBondForce, MonteCarloBarostat, MonteCarloMembraneBarostat, NonbondedForce, PeriodicTorsionForce, ) from openmm import unit as omm_unit from openmm import unit as ommunit from openmmtools.alchemy import ( AlchemicalRegion, ) from openmmtools.multistate.multistatesampler import MultiStateSampler from openmmtools.tests import test_alchemy from openmmtools.tests.test_alchemy import ( check_interacting_energy_components, check_noninteracting_energy_components, compare_system_energies, ) import openfe from openfe import ChemicalSystem, SmallMoleculeComponent, SolventComponent from openfe.protocols import openmm_afe from openfe.protocols.openmm_afe import ( AbsoluteBindingProtocol, ) from .utils import UNIT_TYPES, _get_units @pytest.fixture() def default_settings(): return AbsoluteBindingProtocol.default_settings() @pytest.fixture(scope="module") def benzene_wcharges(benzene_modifications): benz_off = benzene_modifications["benzene"].to_openff() benz_off.assign_partial_charges(partial_charge_method="gasteiger") return SmallMoleculeComponent.from_openff(benz_off) def test_create_default_protocol(default_settings): # this is roughly how it should be created protocol = AbsoluteBindingProtocol( settings=default_settings, ) assert protocol def test_serialize_protocol(default_settings): protocol = AbsoluteBindingProtocol( settings=default_settings, ) ser = protocol.to_dict() ret = AbsoluteBindingProtocol.from_dict(ser) assert protocol == ret def test_repeat_units(benzene_modifications, T4_protein_component): protocol = openmm_afe.AbsoluteBindingProtocol( settings=openmm_afe.AbsoluteBindingProtocol.default_settings() ) stateA = gufe.ChemicalSystem( { "protein": T4_protein_component, "benzene": benzene_modifications["benzene"], "solvent": gufe.SolventComponent(), } ) stateB = gufe.ChemicalSystem( { "protein": T4_protein_component, "solvent": gufe.SolventComponent(), } ) dag = protocol.create( stateA=stateA, stateB=stateB, mapping=None, ) # 6 protocol unit, 3 per repeat pus = list(dag.protocol_units) assert len(pus) == 18 # Check info for each repeat for phase in ["solvent", "complex"]: setup = _get_units(pus, UNIT_TYPES[phase]["setup"]) sim = _get_units(pus, UNIT_TYPES[phase]["sim"]) analysis = _get_units(pus, UNIT_TYPES[phase]["analysis"]) # Should be 3 of each set assert len(setup) == len(sim) == len(analysis) == 3 # Check that the dag chain is correct for analysis_pu in analysis: repeat_id = analysis_pu.inputs["repeat_id"] setup_pu = [s for s in setup if s.inputs["repeat_id"] == repeat_id][0] sim_pu = [s for s in sim if s.inputs["repeat_id"] == repeat_id][0] assert analysis_pu.inputs["setup_results"] == setup_pu assert analysis_pu.inputs["simulation_results"] == sim_pu assert sim_pu.inputs["setup_results"] == setup_pu def test_create_independent_repeat_ids(benzene_modifications, T4_protein_component): s = openmm_afe.AbsoluteBindingProtocol.default_settings() protocol = openmm_afe.AbsoluteBindingProtocol( settings=s, ) stateA = gufe.ChemicalSystem( { "protein": T4_protein_component, "benzene": benzene_modifications["benzene"], "solvent": gufe.SolventComponent(), } ) stateB = gufe.ChemicalSystem( { "protein": T4_protein_component, "solvent": gufe.SolventComponent(), } ) dags = [] for i in range(2): dags.append(protocol.create(stateA=stateA, stateB=stateB, mapping=None)) repeat_ids = set() for dag in dags: # 3 sets of 6 units assert len(list(dag.protocol_units)) == 18 for u in dag.protocol_units: repeat_ids.add(u.inputs["repeat_id"]) # squashed by repeat_id, that's 2 sets of 6 assert len(repeat_ids) == 12 def test_mda_universe_error(): """ Test that we get an error if we pass no positions or trajectory when calling the mda Universe getter. """ with pytest.raises(ValueError, match="No positions to create"): _ = openmm_afe.ABFEComplexSetupUnit._get_mda_universe( topology="foo", positions=None, trajectory=None ) class TestT4LysozymeDryRun: solvent = SolventComponent(ion_concentration=0 * offunit.molar) num_all_not_water = 2634 # 9 counterions to neutralize num_protein_component_atoms = 2614 # No ions num_ligand_atoms = 12 expected_complex_particles = 32607 expected_ligand_solvent_particles = 3012 barostat_by_phase = { "complex": MonteCarloBarostat, "solvent": MonteCarloBarostat, } @pytest.fixture(scope="class", autouse=True) def set_platform(self, get_available_openmm_platforms): """ Set the platform used by this test, overriding the openmmtools default. If a CUDA-enabled GPU is present, it will attempt to set the platform to CUDA + mixed precision. Otherwise the Reference platform will be used. We need this because system size discrepancies can occur see for more details. Note ---- - must keep autouse=True to ensure it is used without being called explicitly """ original_platform = test_alchemy.GLOBAL_ALCHEMY_PLATFORM # set the new platform # Try cuda if available, then CPU if "CUDA" in get_available_openmm_platforms: test_platform = openmm.Platform.getPlatformByName("CUDA") test_platform.setPropertyDefaultValue("Precision", "mixed") test_alchemy.GLOBAL_ALCHEMY_PLATFORM = test_platform else: test_alchemy.GLOBAL_ALCHEMY_PLATFORM = openmm.Platform.getPlatformByName("Reference") yield # restore the old value test_alchemy.GLOBAL_ALCHEMY_PLATFORM = original_platform @pytest.fixture(scope="class") def protocol(self, settings): return openmm_afe.AbsoluteBindingProtocol( settings=settings, ) @pytest.fixture(scope="class") def settings(self): s = openmm_afe.AbsoluteBindingProtocol.default_settings() s.protocol_repeats = 1 s.engine_settings.compute_platform = "cpu" s.complex_output_settings.output_indices = "not water" s.complex_solvation_settings.box_shape = "dodecahedron" s.complex_solvation_settings.solvent_padding = None s.complex_solvation_settings.number_of_solvent_molecules = 10000 s.solvent_solvation_settings.box_shape = "cube" s.solvent_solvation_settings.solvent_padding = None s.solvent_solvation_settings.number_of_solvent_molecules = 1000 return s @pytest.fixture(scope="class") def dag(self, protocol, benzene_wcharges, T4_protein_component): stateA = ChemicalSystem( { "benzene": benzene_wcharges, "protein": T4_protein_component, "solvent": self.solvent, } ) stateB = ChemicalSystem( { "protein": T4_protein_component, "solvent": self.solvent, } ) return protocol.create( stateA=stateA, stateB=stateB, mapping=None, ) @pytest.fixture(scope="class") def complex_setup_units(self, dag): return _get_units(dag.protocol_units, UNIT_TYPES["complex"]["setup"]) @pytest.fixture(scope="class") def complex_sim_units(self, dag): return _get_units(dag.protocol_units, UNIT_TYPES["complex"]["sim"]) @pytest.fixture(scope="class") def solvent_setup_units(self, dag): return _get_units(dag.protocol_units, UNIT_TYPES["solvent"]["setup"]) @pytest.fixture(scope="class") def solvent_sim_units(self, dag): return _get_units(dag.protocol_units, UNIT_TYPES["solvent"]["sim"]) def test_number_of_units( self, dag, complex_setup_units, complex_sim_units, solvent_setup_units, solvent_sim_units, ): assert len(list(dag.protocol_units)) == 6 assert len(complex_setup_units) == len(complex_sim_units) == 1 assert len(solvent_setup_units) == len(solvent_sim_units) == 1 def _assert_force_num(self, system, forcetype, number): forces = [f for f in system.getForces() if isinstance(f, forcetype)] assert len(forces) == number def _assert_expected_alchemical_forces(self, system, phase: str, settings): """ Assert the forces expected in the alchemical system. """ barostat_type = self.barostat_by_phase[phase] self._assert_force_num(system, NonbondedForce, 1) self._assert_force_num(system, CustomNonbondedForce, 2) self._assert_force_num(system, CustomBondForce, 2) self._assert_force_num(system, HarmonicBondForce, 1) self._assert_force_num(system, HarmonicAngleForce, 1) self._assert_force_num(system, PeriodicTorsionForce, 1) self._assert_force_num(system, barostat_type, 1) if phase == "complex": self._assert_force_num(system, CustomCompoundBondForce, 1) assert len(system.getForces()) == 10 else: assert len(system.getForces()) == 9 # Check the nonbonded force has the right contents nonbond = [f for f in system.getForces() if isinstance(f, NonbondedForce)] assert len(nonbond) == 1 assert nonbond[0].getNonbondedMethod() == NonbondedForce.PME assert ( from_openmm(nonbond[0].getCutoffDistance()) == settings.forcefield_settings.nonbonded_cutoff ) # Check the barostat made it all the way through barostat = [f for f in system.getForces() if isinstance(f, barostat_type)] assert len(barostat) == 1 expected_frequency = int( ( settings.complex_integrator_settings if phase == "complex" else settings.solvent_integrator_settings ).barostat_frequency.m ) assert barostat[0].getFrequency() == expected_frequency assert barostat[0].getDefaultPressure() == to_openmm(settings.thermo_settings.pressure) assert barostat[0].getDefaultTemperature() == to_openmm( settings.thermo_settings.temperature ) def _assert_expected_nonalchemical_forces(self, system, phase: str, settings): """ Assert the forces expected in the non-alchemical system. """ barostat_type = self.barostat_by_phase[phase] self._assert_force_num(system, NonbondedForce, 1) self._assert_force_num(system, HarmonicBondForce, 1) self._assert_force_num(system, HarmonicAngleForce, 1) self._assert_force_num(system, PeriodicTorsionForce, 1) self._assert_force_num(system, barostat_type, 1) assert len(system.getForces()) == 5 # Check that the nonbonded force has the right contents nonbond = [f for f in system.getForces() if isinstance(f, NonbondedForce)] assert len(nonbond) == 1 assert nonbond[0].getNonbondedMethod() == NonbondedForce.PME assert ( from_openmm(nonbond[0].getCutoffDistance()) == settings.forcefield_settings.nonbonded_cutoff ) # Check the barostat made it all the way through barostat = [f for f in system.getForces() if isinstance(f, barostat_type)] assert len(barostat) == 1 expected_frequency = int( ( settings.complex_integrator_settings if phase == "complex" else settings.solvent_integrator_settings ).barostat_frequency.m ) assert barostat[0].getFrequency() == expected_frequency assert barostat[0].getDefaultPressure() == to_openmm(settings.thermo_settings.pressure) assert barostat[0].getDefaultTemperature() == to_openmm( settings.thermo_settings.temperature ) def _verify_sampler(self, sampler, phase: str, settings): """ Utility to verify the contents of the sampler. """ assert sampler.is_periodic assert isinstance(sampler, MultiStateSampler) barostat_type = self.barostat_by_phase[phase] assert isinstance(sampler._thermodynamic_states[0].barostat, barostat_type) assert sampler._thermodynamic_states[1].pressure == to_openmm( settings.thermo_settings.pressure ) for state in sampler._thermodynamic_states: system = state.get_system(remove_thermostat=True) self._assert_expected_alchemical_forces(system, phase, settings) def _check_box_vectors(self, system): self._test_dodecahedron_vectors(system) @staticmethod def _test_dodecahedron_vectors(system): # dodecahedron has the following shape: # [width, 0, 0], [0, width, 0], [0.5, 0.5, 0.5 * sqrt(2)] * width vectors = system.getDefaultPeriodicBoxVectors() width = float(from_openmm(vectors)[0][0].to("nanometer").m) expected_vectors = [ [width, 0, 0], [0, width, 0], [0.5 * width, 0.5 * width, 0.5 * sqrt(2) * width], ] * offunit.nanometer assert_allclose( expected_vectors, from_openmm(vectors), ) @staticmethod def _test_cubic_vectors(system): # cube is an identity matrix vectors = system.getDefaultPeriodicBoxVectors() width = float(from_openmm(vectors)[0][0].to("nanometer").m) expected_vectors = [ [width, 0, 0], [0, width, 0], [0, 0, width], ] * offunit.nanometer assert_allclose( expected_vectors, from_openmm(vectors), ) @staticmethod def _test_energies(reference_system, alchemical_system, alchemical_regions, positions): compare_system_energies( reference_system=reference_system, alchemical_system=alchemical_system, alchemical_regions=alchemical_regions, positions=positions, ) check_noninteracting_energy_components( reference_system=reference_system, alchemical_system=alchemical_system, alchemical_regions=alchemical_regions, positions=positions, ) check_interacting_energy_components( reference_system=reference_system, alchemical_system=alchemical_system, alchemical_regions=alchemical_regions, positions=positions, ) def test_complex_dry_run(self, complex_setup_units, complex_sim_units, settings, tmp_path): setup_results = complex_setup_units[0].run( dry=True, verbose=True, scratch_basepath=tmp_path, shared_basepath=tmp_path, ) sim_results = complex_sim_units[0].run( system=setup_results["alchem_system"], positions=setup_results["debug_positions"], selection_indices=setup_results["selection_indices"], box_vectors=setup_results["box_vectors"], alchemical_restraints=True, dry=True, scratch_basepath=tmp_path, shared_basepath=tmp_path, ) # Check the sampler self._verify_sampler(sim_results["sampler"], phase="complex", settings=settings) # Check the alchemical system assert setup_results["alchem_system"].getNumParticles() == self.expected_complex_particles self._assert_expected_alchemical_forces( setup_results["alchem_system"], phase="complex", settings=settings ) self._check_box_vectors(setup_results["alchem_system"]) # Check the alchemical indices expected_indices = [ i + self.num_protein_component_atoms - 1 for i in range(self.num_ligand_atoms) ] assert expected_indices == setup_results["alchem_indices"] # Check the non-alchemical system assert setup_results["standard_system"].getNumParticles() == self.expected_complex_particles self._assert_expected_nonalchemical_forces( setup_results["standard_system"], "complex", settings=settings, ) self._check_box_vectors(setup_results["standard_system"]) # Check the box vectors haven't changed (they shouldn't have because we didn't do MD) assert_allclose( from_openmm(setup_results["alchem_system"].getDefaultPeriodicBoxVectors()), from_openmm(setup_results["standard_system"].getDefaultPeriodicBoxVectors()), ) # Check the PDB pdb = mdt.load_pdb(setup_results["pdb_structure"]) assert pdb.n_atoms == self.num_all_not_water # Check energies alchem_region = AlchemicalRegion(alchemical_atoms=setup_results["alchem_indices"]) self._test_energies( reference_system=setup_results["standard_system"], alchemical_system=setup_results["alchem_system"], alchemical_regions=alchem_region, positions=setup_results["debug_positions"], ) def test_solvent_dry_run(self, solvent_setup_units, solvent_sim_units, settings, tmp_path): setup_results = solvent_setup_units[0].run( dry=True, verbose=True, scratch_basepath=tmp_path, shared_basepath=tmp_path, ) sim_results = solvent_sim_units[0].run( system=setup_results["alchem_system"], positions=setup_results["debug_positions"], selection_indices=setup_results["selection_indices"], box_vectors=setup_results["box_vectors"], alchemical_restraints=False, dry=True, scratch_basepath=tmp_path, shared_basepath=tmp_path, ) # Check the sampler self._verify_sampler(sim_results["sampler"], phase="solvent", settings=settings) # Check the alchemical system assert ( setup_results["alchem_system"].getNumParticles() == self.expected_ligand_solvent_particles ) self._assert_expected_alchemical_forces( setup_results["alchem_system"], phase="solvent", settings=settings ) self._test_cubic_vectors(setup_results["alchem_system"]) # Check the alchemical indices expected_indices = [i for i in range(self.num_ligand_atoms)] assert expected_indices == setup_results["alchem_indices"] # Check the non-alchemical system assert ( setup_results["standard_system"].getNumParticles() == self.expected_ligand_solvent_particles ) self._assert_expected_nonalchemical_forces( setup_results["standard_system"], phase="solvent", settings=settings ) self._test_cubic_vectors(setup_results["standard_system"]) # Check the box vectors haven't changed (they shouldn't have because we didn't do MD) assert_allclose( from_openmm(setup_results["alchem_system"].getDefaultPeriodicBoxVectors()), from_openmm(setup_results["standard_system"].getDefaultPeriodicBoxVectors()), ) # Check the PDB pdb = mdt.load_pdb(setup_results["pdb_structure"]) assert pdb.n_atoms == self.num_ligand_atoms # Check energies alchem_region = AlchemicalRegion(alchemical_atoms=setup_results["alchem_indices"]) self._test_energies( reference_system=setup_results["standard_system"], alchemical_system=setup_results["alchem_system"], alchemical_regions=alchem_region, positions=setup_results["debug_positions"], ) @pytest.mark.slow class TestT4LysozymeTIP4PExtraSettingsDryRun(TestT4LysozymeDryRun): """ TIP4P and a few extra settings to test out the dry run. """ expected_complex_particles = 42598 expected_ligand_solvent_particles = 4012 @pytest.fixture(scope="class") def settings(self): s = openmm_afe.AbsoluteBindingProtocol.default_settings() s.protocol_repeats = 1 s.engine_settings.compute_platform = "cpu" s.complex_output_settings.output_indices = "not water" s.complex_solvation_settings.box_shape = "dodecahedron" s.complex_solvation_settings.solvent_padding = None s.complex_solvation_settings.number_of_solvent_molecules = 10000 s.complex_solvation_settings.solvent_model = "tip4pew" s.solvent_solvation_settings.box_shape = "cube" s.solvent_solvation_settings.solvent_padding = None s.solvent_solvation_settings.number_of_solvent_molecules = 1000 s.solvent_solvation_settings.solvent_model = "tip4pew" s.forcefield_settings.nonbonded_cutoff = 0.8 * offunit.nanometer s.forcefield_settings.forcefields = [ "amber/ff14SB.xml", # ff14SB protein force field "amber/tip4pew_standard.xml", # FF we are testing with the fun VS "amber/phosaa10.xml", # Handles THE TPO ] s.complex_integrator_settings.reassign_velocities = True s.solvent_integrator_settings.reassign_velocities = True s.complex_integrator_settings.barostat_frequency = 100.0 * offunit.timestep s.solvent_integrator_settings.barostat_frequency = 100.0 * offunit.timestep s.thermo_settings.pressure = 1.1 * offunit.bar return s def test_user_charges(benzene_modifications, T4_protein_component, tmp_path): s = openmm_afe.AbsoluteBindingProtocol.default_settings() s.protocol_repeats = 1 s.engine_settings.compute_platform = "cpu" s.complex_solvation_settings.box_shape = "dodecahedron" s.complex_solvation_settings.solvent_padding = 0.8 * offunit.nanometer s.forcefield_settings.nonbonded_cutoff = 0.7 * offunit.nanometer protocol = openmm_afe.AbsoluteBindingProtocol(settings=s) def assign_fictitious_charges(offmol): """ Get a random array of fake partial charges for your offmol. """ rand_arr = np.random.randint(1, 10, size=offmol.n_atoms) / 100 rand_arr[-1] = -sum(rand_arr[:-1]) return rand_arr * offunit.elementary_charge benzene_offmol = benzene_modifications["benzene"].to_openff() offmol_pchgs = assign_fictitious_charges(benzene_offmol) benzene_offmol.partial_charges = offmol_pchgs benzene_smc = openfe.SmallMoleculeComponent.from_openff(benzene_offmol) # check propchgs prop_chgs = benzene_smc.to_dict()["molprops"]["atom.dprop.PartialCharge"] prop_chgs = np.array(prop_chgs.split(), dtype=float) assert_allclose(prop_chgs, offmol_pchgs) stateA = gufe.ChemicalSystem( { "protein": T4_protein_component, "benzene": benzene_smc, "solvent": gufe.SolventComponent(), } ) stateB = gufe.ChemicalSystem( { "protein": T4_protein_component, "solvent": gufe.SolventComponent(), } ) dag = protocol.create(stateA=stateA, stateB=stateB, mapping=None) complex_setup_units = _get_units(dag.protocol_units, UNIT_TYPES["complex"]["setup"]) results = complex_setup_units[0].run( dry=True, scratch_basepath=tmp_path, shared_basepath=tmp_path, ) system_nbf = [ f for f in results["standard_system"].getForces() if isinstance(f, NonbondedForce) ][0] alchem_system_nbf = [ f for f in results["alchem_system"].getForces() if isinstance(f, NonbondedForce) ][0] # fmt: skip for i in range(12): # add 2613 to account for the protein index = i + 2613 c, s, e = system_nbf.getParticleParameters(index) assert pytest.approx(prop_chgs[i]) == c.value_in_unit(ommunit.elementary_charge) offsets = alchem_system_nbf.getParticleParameterOffset(i) assert pytest.approx(prop_chgs[i]) == offsets[2] @pytest.mark.slow class TestA2AMembraneDryRun(TestT4LysozymeDryRun): """ A test case for a membrane. TODO ---- * The energies coming from this system are very high. Maybe replace with a larger test case? """ solvent = SolventComponent(ion_concentration=0 * offunit.molar) num_all_not_water = 16080 num_protein_component_atoms = 39391 expected_complex_particles = 39426 expected_ligand_solvent_particles = 3036 # No ions num_ligand_atoms = 36 expected_ligand_solvent_particles = 3036 barostat_by_phase = { "complex": MonteCarloMembraneBarostat, "solvent": MonteCarloBarostat, } @pytest.fixture(scope="class") def settings(self): s = openmm_afe.AbsoluteBindingProtocol.default_settings() s.protocol_repeats = 1 s.engine_settings.compute_platform = "cpu" s.complex_output_settings.output_indices = "not water" s.solvent_solvation_settings.box_shape = "cube" s.solvent_solvation_settings.solvent_padding = None s.solvent_solvation_settings.number_of_solvent_molecules = 1000 return s @pytest.fixture(scope="class") def dag(self, settings, a2a_ligands, a2a_protein_membrane_component): stateA = ChemicalSystem( { "ligand": a2a_ligands[0], "protein": a2a_protein_membrane_component, "solvent": self.solvent, } ) stateB = ChemicalSystem( { "protein": a2a_protein_membrane_component, "solvent": self.solvent, } ) adaptive_settings = AbsoluteBindingProtocol._adaptive_settings( stateA=stateA, stateB=stateB, initial_settings=settings, ) protocol = AbsoluteBindingProtocol(settings=adaptive_settings) return protocol.create( stateA=stateA, stateB=stateB, mapping=None, ) def _check_box_vectors(self, system): self._test_orthogonal_vectors(system) @staticmethod def _test_orthogonal_vectors(system): """Test that the system has an orthorhombic (rectangular) periodic box.""" vectors = system.getDefaultPeriodicBoxVectors() vectors = from_openmm(vectors) # convert to a Quantity array # Extract box lengths in nanometers width_x, width_y, width_z = [v[i].to("nanometer").m for i, v in enumerate(vectors)] # Expected orthogonal box (axis-aligned) expected_vectors = ( np.array( [ [width_x, 0, 0], [0, width_y, 0], [0, 0, width_z], ] ) * offunit.nanometer ) assert_allclose( vectors, expected_vectors, atol=1e-5, err_msg=f"Box is not orthogonal:\n{vectors}" ) ================================================ FILE: src/openfe/tests/protocols/openmm_abfe/test_abfe_protocol_results.py ================================================ # This code is part of OpenFE and is licensed under the MIT license. # For details, see https://github.com/OpenFreeEnergy/openfe import gzip import itertools import json from pathlib import Path from unittest import mock import gufe import numpy as np import openmm import pytest from openff.units import unit as offunit import openfe from openfe.protocols import openmm_afe from openfe.protocols.restraint_utils.geometry.boresch import BoreschRestraintGeometry from .utils import UNIT_TYPES, _get_units @pytest.fixture() def patcher(): with ( mock.patch( "openfe.protocols.openmm_afe.abfe_units.ABFESolventSetupUnit.run", return_value={ "system": Path("system.xml.bz2"), "positions": Path("positions.npy"), "pdb_structure": Path("hybrid_system.pdb"), "selection_indices": np.zeros(100), "box_vectors": [np.zeros(3), np.zeros(3), np.zeros(3)] * offunit.nm, "standard_state_correction": 0 * offunit.kilocalorie_per_mole, "restraint_geometry": None, "gufe_version": gufe.__version__, "openfe_version": openfe.__version__, "openmm_version": openmm.__version__, }, ), mock.patch( "openfe.protocols.openmm_afe.abfe_units.ABFEComplexSetupUnit.run", return_value={ "system": Path("system.xml.bz2"), "positions": Path("positions.npy"), "pdb_structure": Path("hybrid_system.pdb"), "selection_indices": np.zeros(100), "box_vectors": [np.zeros(3), np.zeros(3), np.zeros(3)] * offunit.nm, "standard_state_correction": 0 * offunit.kilocalorie_per_mole, "restraint_geometry": True, }, ), mock.patch( "openfe.protocols.openmm_afe.base_afe_units.np.load", return_value=np.zeros(100), ), mock.patch( "openfe.protocols.openmm_afe.base_afe_units.deserialize", return_value="foo", ), mock.patch( "openfe.protocols.openmm_afe.abfe_units.ABFEComplexSimUnit.run", return_value={ "trajectory": Path("file.nc"), "checkpoint": Path("chk.chk"), }, ), mock.patch( "openfe.protocols.openmm_afe.abfe_units.ABFESolventSimUnit.run", return_value={ "trajectory": Path("file.nc"), "checkpoint": Path("chk.chk"), }, ), mock.patch( "openfe.protocols.openmm_afe.abfe_units.ABFEComplexAnalysisUnit.run", return_value={"foo": "bar"}, ), mock.patch( "openfe.protocols.openmm_afe.abfe_units.ABFESolventAnalysisUnit.run", return_value={"foo": "bar"}, ), ): yield def test_gather(benzene_complex_dag, patcher, tmp_path): # check that .gather behaves as expected dagres = gufe.protocols.execute_DAG( benzene_complex_dag, shared_basedir=tmp_path, scratch_basedir=tmp_path, keep_shared=True, ) protocol = openmm_afe.AbsoluteBindingProtocol( settings=openmm_afe.AbsoluteBindingProtocol.default_settings(), ) res = protocol.gather([dagres]) assert isinstance(res, openmm_afe.AbsoluteBindingProtocolResult) def test_unit_tagging(benzene_complex_dag, patcher, tmp_path): # test that executing the units includes correct gen and repeat info dag_units = benzene_complex_dag.protocol_units for phase in ["solvent", "complex"]: setup_results = {} sim_results = {} analysis_results = {} setup_units = _get_units(dag_units, UNIT_TYPES[phase]["setup"]) sim_units = _get_units(dag_units, UNIT_TYPES[phase]["sim"]) a_units = _get_units(dag_units, UNIT_TYPES[phase]["analysis"]) for u in setup_units: rid = u.inputs["repeat_id"] setup_results[rid] = u.execute(context=gufe.Context(tmp_path, tmp_path)) for u in sim_units: rid = u.inputs["repeat_id"] sim_results[rid] = u.execute( context=gufe.Context(tmp_path, tmp_path), setup_results=setup_results[rid], ) for u in a_units: rid = u.inputs["repeat_id"] analysis_results[rid] = u.execute( context=gufe.Context(tmp_path, tmp_path), setup_results=setup_results[rid], simulation_results=sim_results[rid], ) for results in [setup_results, sim_results, analysis_results]: for ret in results.values(): assert isinstance(ret, gufe.ProtocolUnitResult) assert ret.outputs["generation"] == 0 assert len(setup_results) == len(sim_results) == len(analysis_results) == 3 class TestProtocolResult: @pytest.fixture() def protocolresult(self, abfe_transformation_json_path): with gzip.open(abfe_transformation_json_path) as f: pr = openfe.ProtocolResult.from_json(f) return pr def test_reload_protocol_result(self, afe_solv_transformation_json): d = json.loads(afe_solv_transformation_json, cls=gufe.tokenization.JSON_HANDLER.decoder) pr = openmm_afe.AbsoluteBindingProtocolResult.from_dict(d["protocol_result"]) assert pr def test_get_estimate(self, protocolresult): est = protocolresult.get_estimate() assert est assert est.m == pytest.approx(-19.74, abs=0.01) assert isinstance(est, offunit.Quantity) assert est.is_compatible_with(offunit.kilojoule_per_mole) def test_get_uncertainty(self, protocolresult): est = protocolresult.get_uncertainty() assert est assert est.m == pytest.approx(0.85, abs=0.01) assert isinstance(est, offunit.Quantity) assert est.is_compatible_with(offunit.kilojoule_per_mole) def test_get_individual(self, protocolresult): inds = protocolresult.get_individual_estimates() assert isinstance(inds, dict) assert isinstance(inds["solvent"], list) assert isinstance(inds["complex"], list) assert len(inds["solvent"]) == len(inds["complex"]) == 3 for e, u in itertools.chain(inds["solvent"], inds["complex"]): assert e.is_compatible_with(offunit.kilojoule_per_mole) assert u.is_compatible_with(offunit.kilojoule_per_mole) @pytest.mark.parametrize("key", ["solvent", "complex"]) def test_get_forwards_etc(self, key, protocolresult): far = protocolresult.get_forward_and_reverse_energy_analysis() assert isinstance(far, dict) assert isinstance(far[key], list) for f in far[key]: if f is not None: assert isinstance(f, dict) for k in [ "fractions", "forward_DGs", "forward_dDGs", "reverse_DGs", "reverse_dDGs", ]: assert k in f if k == "fractions": assert isinstance(f[k], np.ndarray) @pytest.mark.parametrize("key", ["solvent", "complex"]) def test_get_frwd_reverse_none_return(self, key, protocolresult): # fetch the first result of type key data = [i for i in protocolresult.data[key].values()][0][0] # set the output to None data.outputs["forward_and_reverse_energies"] = None # now fetch the analysis results and expect a warning wmsg = f"were found in the forward and reverse dictionaries of the repeats of the {key}" with pytest.warns(UserWarning, match=wmsg): protocolresult.get_forward_and_reverse_energy_analysis() @pytest.mark.parametrize("key, n_rep", [("solvent", 14), ("complex", 30)]) def test_get_overlap_matrices(self, key, n_rep, protocolresult): ovp = protocolresult.get_overlap_matrices() assert isinstance(ovp, dict) assert isinstance(ovp[key], list) assert len(ovp[key]) == 3 ovp1 = ovp[key][0] assert isinstance(ovp1["matrix"], np.ndarray) assert ovp1["matrix"].shape == (n_rep, n_rep) @pytest.mark.parametrize("key, n_rep", [("solvent", 14), ("complex", 30)]) def test_get_replica_transition_statistics(self, n_rep, key, protocolresult): rpx = protocolresult.get_replica_transition_statistics() assert isinstance(rpx, dict) assert isinstance(rpx[key], list) assert len(rpx[key]) == 3 rpx1 = rpx[key][0] assert "eigenvalues" in rpx1 assert "matrix" in rpx1 assert rpx1["eigenvalues"].shape == (n_rep,) assert rpx1["matrix"].shape == (n_rep, n_rep) @pytest.mark.parametrize("key", ["solvent", "complex"]) def test_equilibration_iterations(self, key, protocolresult): eq = protocolresult.equilibration_iterations() assert isinstance(eq, dict) assert isinstance(eq[key], list) assert len(eq[key]) == 3 assert all(isinstance(v, float) for v in eq[key]) @pytest.mark.parametrize("key", ["solvent", "complex"]) def test_production_iterations(self, key, protocolresult): prod = protocolresult.production_iterations() assert isinstance(prod, dict) assert isinstance(prod[key], list) assert len(prod[key]) == 3 assert all(isinstance(v, float) for v in prod[key]) def test_filenotfound_replica_states(self, protocolresult): errmsg = "File could not be found" with pytest.raises(ValueError, match=errmsg): protocolresult.get_replica_states() def test_restraint_geometry(self, protocolresult): geom = protocolresult.restraint_geometries() assert isinstance(geom, list) assert len(geom) == 3 assert isinstance(geom[0], BoreschRestraintGeometry) assert geom[0].guest_atoms == [1779, 1778, 1777] assert geom[0].host_atoms == [852, 853, 854] assert pytest.approx(geom[0].r_aA0, rel=1e-2) == 1.041035 * offunit.nanometer assert pytest.approx(geom[0].theta_A0, rel=1e-2) == 1.063788 * offunit.radian assert pytest.approx(geom[0].theta_B0, rel=1e-2) == 1.230858 * offunit.radian assert pytest.approx(geom[0].phi_A0, rel=1e-2) == 1.155133 * offunit.radian assert pytest.approx(geom[0].phi_B0, rel=1e-2) == 1.141134 * offunit.radian assert pytest.approx(geom[0].phi_C0, rel=1e-2) == -0.621615 * offunit.radian @pytest.mark.parametrize( "key, expected_size", [ ["solvent", 41], ["complex", 1828], ], ) def test_selection_indices(self, key, protocolresult, expected_size): indices = protocolresult.selection_indices() assert isinstance(indices, dict) assert isinstance(indices[key], list) for inds in indices[key]: assert isinstance(inds, np.ndarray) assert len(inds) == expected_size ================================================ FILE: src/openfe/tests/protocols/openmm_abfe/test_abfe_settings.py ================================================ # This code is part of OpenFE and is licensed under the MIT license. # For details, see https://github.com/OpenFreeEnergy/openfe import pytest from openfe import ChemicalSystem, SolventComponent from openfe.protocols.openmm_afe import ( AbsoluteBindingProtocol, AbsoluteBindingSettings, ) @pytest.fixture() def default_settings(): return AbsoluteBindingProtocol.default_settings() def test_create_default_settings(): settings = AbsoluteBindingProtocol.default_settings() assert settings def test_negative_repeats_settings(default_settings): with pytest.raises(ValueError, match="protocol_repeats must be a positive"): default_settings.protocol_repeats = -1 @pytest.mark.parametrize( "val", [ {"elec": [0.0, -1], "vdw": [0.0, 1.0], "restraints": [0.0, 1.0]}, {"elec": [0.0, 1.5], "vdw": [0.0, 1.5], "restraints": [-0.1, 1.0]}, ], ) def test_incorrect_window_settings(val, default_settings): errmsg = "Lambda windows must be between 0 and 1." lambda_settings = default_settings.complex_lambda_settings with pytest.raises(ValueError, match=errmsg): lambda_settings.lambda_elec = val["elec"] lambda_settings.lambda_vdw = val["vdw"] lambda_settings.lambda_restraints = val["restraints"] @pytest.mark.parametrize( "val", [ { "elec": [0.0, 0.1, 0.0], "vdw": [0.0, 1.0, 1.0], "restraints": [0.0, 1.0, 1.0], }, { "elec": [0.0, 0.1, 0.2], "vdw": [0.0, 1.0, 0.2], "restraints": [0.0, 1.0, 1.0], }, { "elec": [0.0, 0.1, 0.2], "vdw": [0.0, 1.0, 1.0], "restraints": [0.0, 1.0, 0.0], }, ], ) def test_monotonic_lambda_windows(val, default_settings): errmsg = "The lambda schedule is not monotonic." lambda_settings = default_settings.complex_lambda_settings with pytest.raises(ValueError, match=errmsg): lambda_settings.lambda_elec = val["elec"] lambda_settings.lambda_vdw = val["vdw"] lambda_settings.lambda_restraints = val["restraints"] def test_equil_not_all_complex(default_settings): with pytest.raises(ValueError, match="output_indices must be all"): default_settings.complex_equil_output_settings.output_indices = "not water" def test_equil_not_all_solvent(default_settings): with pytest.raises(ValueError, match="output_indices must be all"): default_settings.solvent_equil_output_settings.output_indices = "not water" def test_adaptive_settings_no_protein_membrane(toluene_complex_system, default_settings): settings = AbsoluteBindingProtocol._adaptive_settings( toluene_complex_system, toluene_complex_system, default_settings, ) assert isinstance(settings, AbsoluteBindingSettings) # Should use default barostat since no ProteinMembraneComponent assert settings.complex_integrator_settings.barostat == "MonteCarloBarostat" def test_adaptive_settings_with_protein_membrane(a2a_protein_membrane_component, a2a_ligands): stateA = ChemicalSystem( { "ligandA": a2a_ligands[0], "protein": a2a_protein_membrane_component, "solvent": SolventComponent(), } ) settings = AbsoluteBindingProtocol._adaptive_settings(stateA, stateA) assert isinstance(settings, AbsoluteBindingSettings) # Barostat should have been updated assert settings.complex_integrator_settings.barostat == "MonteCarloMembraneBarostat" ================================================ FILE: src/openfe/tests/protocols/openmm_abfe/test_abfe_slow.py ================================================ # This code is part of OpenFE and is licensed under the MIT license. # For details, see https://github.com/OpenFreeEnergy/openfe import pathlib import pytest from openff.units import unit as offunit import openfe from openfe.protocols.openmm_afe import AbsoluteBindingProtocol from openfe.protocols.openmm_utils.charge_generation import HAS_NAGL, HAS_OPENEYE @pytest.mark.integration @pytest.mark.flaky(reruns=3) # pytest-rerunfailures; we can get bad minimisation @pytest.mark.skipif(not HAS_NAGL, reason="need NAGL") @pytest.mark.skipif( HAS_OPENEYE and HAS_NAGL, reason="NAGL/openeye incompatibility. See https://github.com/openforcefield/openff-nagl/issues/177", ) @pytest.mark.parametrize("platform", ["CUDA"]) def test_openmm_run_engine( platform, available_platforms, eg5_protein, eg5_ligands, eg5_cofactor, tmp_path, ): if platform not in available_platforms: pytest.skip(f"OpenMM Platform: {platform} not available") settings = AbsoluteBindingProtocol.default_settings() # Run a really short calculation to check everything is going well settings.protocol_repeats = 1 settings.engine_settings.compute_platform = "CUDA" # Solvent settings.solvent_equil_simulation_settings.equilibration_length_nvt = 10 * offunit.picosecond settings.solvent_equil_simulation_settings.equilibration_length = 10 * offunit.picosecond settings.solvent_equil_simulation_settings.production_length = 10 * offunit.picosecond settings.solvent_simulation_settings.equilibration_length = 50 * offunit.picosecond settings.solvent_simulation_settings.production_length = 125 * offunit.picosecond settings.solvent_simulation_settings.early_termination_target_error = 0.12 * offunit.kilocalorie_per_mole # fmt: skip settings.solvent_simulation_settings.time_per_iteration = 2.5 * offunit.ps settings.solvent_solvation_settings.box_shape = "dodecahedron" settings.solvent_solvation_settings.solvent_padding = 1.5 * offunit.nanometer # Complex settings.complex_equil_simulation_settings.equilibration_length_nvt = 10 * offunit.picosecond settings.complex_equil_simulation_settings.equilibration_length = 10 * offunit.picosecond settings.complex_equil_simulation_settings.production_length = 100 * offunit.picosecond settings.complex_simulation_settings.equilibration_length = 50 * offunit.picosecond settings.complex_simulation_settings.production_length = 125 * offunit.picosecond settings.complex_simulation_settings.early_termination_target_error = 0.12 * offunit.kilocalorie_per_mole # fmt: skip settings.complex_simulation_settings.time_per_iteration = 2.5 * offunit.ps settings.complex_solvation_settings.box_shape = "dodecahedron" settings.complex_solvation_settings.solvent_padding = 0.9 * offunit.nanometer # General FF things settings.forcefield_settings.nonbonded_cutoff = 0.8 * offunit.nanometer settings.partial_charge_settings.partial_charge_method = "nagl" settings.partial_charge_settings.nagl_model = "openff-gnn-am1bcc-0.1.0-rc.3.pt" protocol = AbsoluteBindingProtocol(settings=settings) # unpack ligands ligand, _ = eg5_ligands stateA = openfe.ChemicalSystem( { "protein": eg5_protein, "cofactor": eg5_cofactor, "ligand": ligand, "solvent": openfe.SolventComponent(), } ) stateB = openfe.ChemicalSystem( { "protein": eg5_protein, "cofactor": eg5_cofactor, "solvent": openfe.SolventComponent(), } ) # Create DAG from protocol, get the vacuum and solvent units # and eventually dry run the first solvent unit dag = protocol.create( stateA=stateA, stateB=stateB, mapping=None, ) cwd = pathlib.Path(tmp_path) r = openfe.execute_DAG(dag, shared_basedir=cwd, scratch_basedir=cwd, keep_shared=True) assert r.ok() # Check outputs of solvent & complex results for phase in ["solvent", "complex"]: purs = [pur for pur in r.protocol_unit_results if pur.outputs["simtype"] == phase] # get the path to the simulation unit shared dict for pur in purs: if "Simulation" in pur.name: sim_shared = tmp_path / f"shared_{pur.source_key}_attempt_0" assert sim_shared.exists() assert pathlib.Path(sim_shared).is_dir() # check the analysis outputs for pur in purs: if "Analysis" not in pur.name: continue unit_shared = tmp_path / f"shared_{pur.source_key}_attempt_0" assert unit_shared.exists() assert pathlib.Path(unit_shared).is_dir() # Does the checkpoint file exist? checkpoint = pur.outputs["checkpoint"] assert checkpoint == sim_shared / f"{pur.outputs['simtype']}_checkpoint.nc" assert checkpoint.exists() # Does the trajectory file exist? nc = pur.outputs["trajectory"] assert nc == sim_shared / f"{pur.outputs['simtype']}.nc" assert nc.exists() # Test results methods that need files present results = protocol.gather([r]) states = results.get_replica_states() assert len(states.items()) == 2 assert len(states["solvent"]) == 1 assert len(states["complex"]) == 1 assert states["solvent"][0].shape[1] == 14 assert states["complex"][0].shape[1] == 30 ================================================ FILE: src/openfe/tests/protocols/openmm_abfe/test_abfe_tokenization.py ================================================ # This code is part of OpenFE and is licensed under the MIT license. # For details, see https://github.com/OpenFreeEnergy/openfe import gzip import pytest import openfe from openfe.protocols.openmm_afe import ( ABFEComplexAnalysisUnit, ABFEComplexSetupUnit, ABFEComplexSimUnit, ABFESolventAnalysisUnit, ABFESolventSetupUnit, ABFESolventSimUnit, AbsoluteBindingProtocol, AbsoluteBindingProtocolResult, ) from ..conftest import ModGufeTokenizableTestsMixin @pytest.fixture def protocol(): return AbsoluteBindingProtocol(AbsoluteBindingProtocol.default_settings()) @pytest.fixture def protocol_units(protocol, benzene_complex_system, T4_protein_component): stateA = benzene_complex_system stateB = openfe.ChemicalSystem( {"protein": T4_protein_component, "solvent": openfe.SolventComponent()} ) pus = protocol.create( stateA=stateA, stateB=stateB, mapping=None, ) return list(pus.protocol_units) def _filter_units(pus, classtype): for pu in pus: if isinstance(pu, classtype): return pu @pytest.fixture def complex_protocol_setup_unit(protocol_units): return _filter_units(protocol_units, ABFEComplexSetupUnit) @pytest.fixture def complex_protocol_sim_unit(protocol_units): return _filter_units(protocol_units, ABFEComplexSimUnit) @pytest.fixture def complex_protocol_analysis_unit(protocol_units): return _filter_units(protocol_units, ABFEComplexAnalysisUnit) @pytest.fixture def solvent_protocol_setup_unit(protocol_units): return _filter_units(protocol_units, ABFESolventSetupUnit) @pytest.fixture def solvent_protocol_sim_unit(protocol_units): return _filter_units(protocol_units, ABFESolventSimUnit) @pytest.fixture def solvent_protocol_analysis_unit(protocol_units): return _filter_units(protocol_units, ABFESolventAnalysisUnit) @pytest.fixture def protocol_result(abfe_transformation_json_path): with gzip.open(abfe_transformation_json_path) as f: pr = AbsoluteBindingProtocolResult.from_json(f) return pr class TestAbsoluteBindingProtocol(ModGufeTokenizableTestsMixin): cls = AbsoluteBindingProtocol key = None repr = "AbsoluteBindingProtocol-" @pytest.fixture() def instance(self, protocol): return protocol class TestABFESolventSetupUnit(ModGufeTokenizableTestsMixin): cls = ABFESolventSetupUnit repr = "ABFESolventSetupUnit(ABFE Setup: benzene solvent leg" key = None @pytest.fixture() def instance(self, solvent_protocol_setup_unit): return solvent_protocol_setup_unit class TestABFESolventSimUnit(ModGufeTokenizableTestsMixin): cls = ABFESolventSimUnit repr = "ABFESolventSimUnit(ABFE Simulation: benzene solvent leg" key = None @pytest.fixture() def instance(self, solvent_protocol_sim_unit): return solvent_protocol_sim_unit class TestABFESolventAnalysisUnit(ModGufeTokenizableTestsMixin): cls = ABFESolventAnalysisUnit repr = "ABFESolventAnalysisUnit(ABFE Analysis: benzene solvent leg" key = None @pytest.fixture() def instance(self, solvent_protocol_analysis_unit): return solvent_protocol_analysis_unit class TestABFEComplexSetupUnit(ModGufeTokenizableTestsMixin): cls = ABFEComplexSetupUnit repr = "ABFEComplexSetupUnit(ABFE Setup: benzene complex leg" key = None @pytest.fixture() def instance(self, complex_protocol_setup_unit): return complex_protocol_setup_unit class TestABFEComplexSimUnit(ModGufeTokenizableTestsMixin): cls = ABFEComplexSimUnit repr = "ABFEComplexSimUnit(ABFE Simulation: benzene complex leg" key = None @pytest.fixture() def instance(self, complex_protocol_sim_unit): return complex_protocol_sim_unit class TestABFEComplexAnalysisUnit(ModGufeTokenizableTestsMixin): cls = ABFEComplexAnalysisUnit repr = "ABFEComplexAnalysisUnit(ABFE Analysis: benzene complex leg" key = None @pytest.fixture() def instance(self, complex_protocol_analysis_unit): return complex_protocol_analysis_unit class TestAbsoluteBindingProtocolResult(ModGufeTokenizableTestsMixin): cls = AbsoluteBindingProtocolResult key = None repr = "AbsoluteBindingProtocolResult-" @pytest.fixture() def instance(self, protocol_result): return protocol_result ================================================ FILE: src/openfe/tests/protocols/openmm_abfe/test_abfe_validation.py ================================================ # This code is part of OpenFE and is licensed under the MIT license. # For details, see https://github.com/OpenFreeEnergy/openfe import pytest from gufe import LigandAtomMapping, ProtocolDAGResult from openfe import ChemicalSystem, SolventComponent from openfe.protocols.openmm_afe import ( AbsoluteBindingProtocol, ) @pytest.fixture() def default_settings(): return AbsoluteBindingProtocol.default_settings() @pytest.mark.parametrize( "val", [ {"elec": [0.0, 1.0], "vdw": [1.0, 1.0], "restraints": [0.0, 0.0]}, ], ) def test_validate_complex_lambda_schedule_naked_charge(val, default_settings): errmsg = ( "There are states along this lambda schedule " "where there are atoms with charges but no LJ " f"interactions: lambda 0: " f"elec {val['elec'][0]} vdW {val['vdw'][0]}" ) default_settings.complex_lambda_settings.lambda_elec = val["elec"] default_settings.complex_lambda_settings.lambda_vdw = val["vdw"] default_settings.complex_lambda_settings.lambda_restraints = val["restraints"] default_settings.complex_simulation_settings.n_replicas = 2 with pytest.raises(ValueError, match=errmsg): AbsoluteBindingProtocol._validate_lambda_schedule( default_settings.complex_lambda_settings, default_settings.complex_simulation_settings, ) @pytest.mark.parametrize( "val", [ {"elec": [0.0, 1.0], "vdw": [1.0, 1.0], "restraints": [0.0, 0.0]}, ], ) def test_validate_solvent_lambda_schedule_naked_charge(val, default_settings): errmsg = ( "There are states along this lambda schedule " "where there are atoms with charges but no LJ " f"interactions: lambda 0: " f"elec {val['elec'][0]} vdW {val['vdw'][0]}" ) default_settings.solvent_lambda_settings.lambda_elec = val["elec"] default_settings.solvent_lambda_settings.lambda_vdw = val["vdw"] default_settings.solvent_lambda_settings.lambda_restraints = val["restraints"] default_settings.solvent_simulation_settings.n_replicas = 2 with pytest.raises(ValueError, match=errmsg): AbsoluteBindingProtocol._validate_lambda_schedule( default_settings.solvent_lambda_settings, default_settings.solvent_simulation_settings, ) @pytest.mark.parametrize( "val", [ {"elec": [1.0, 1.0], "vdw": [0.0, 1.0], "restraints": [0.0, 1.0]}, ], ) def test_validate_lambda_schedule_nreplicas(val, default_settings): # Only testing complex since it'll be the same for solvent default_settings.complex_lambda_settings.lambda_elec = val["elec"] default_settings.complex_lambda_settings.lambda_vdw = val["vdw"] default_settings.complex_lambda_settings.lambda_restraints = val["restraints"] n_replicas = 3 default_settings.complex_simulation_settings.n_replicas = n_replicas errmsg = ( f"Number of replicas {n_replicas} does not equal the" f" number of lambda windows {len(val['vdw'])}" ) with pytest.raises(ValueError, match=errmsg): AbsoluteBindingProtocol._validate_lambda_schedule( default_settings.complex_lambda_settings, default_settings.complex_simulation_settings, ) @pytest.mark.parametrize( "val", [ {"elec": [1.0, 1.0, 1.0], "vdw": [0.0, 1.0], "restraints": [1.0, 1.0]}, ], ) def test_validate_lambda_schedule_nwindows(val, default_settings): # Only testing complex since it'll be the same for solvent default_settings.complex_lambda_settings.lambda_elec = val["elec"] default_settings.complex_lambda_settings.lambda_vdw = val["vdw"] default_settings.complex_lambda_settings.lambda_restraints = val["restraints"] n_replicas = 3 default_settings.complex_simulation_settings.n_replicas = n_replicas errmsg = ( "Components elec, vdw, and restraints must have equal amount" f" of lambda windows. Got {len(val['elec'])} elec lambda" f" windows, {len(val['vdw'])} vdw lambda windows, and" f"{len(val['restraints'])} restraints lambda windows." ) with pytest.raises(ValueError, match=errmsg): AbsoluteBindingProtocol._validate_lambda_schedule( default_settings.complex_lambda_settings, default_settings.complex_simulation_settings, ) def test_validate_no_protcomp( benzene_modifications, ): stateA = ChemicalSystem( {"benzene": benzene_modifications["benzene"], "solvent": SolventComponent()} ) stateB = ChemicalSystem( { "benzene": benzene_modifications["benzene"], "solvent": SolventComponent(), } ) errmsg = "No ProteinComponent found" with pytest.raises(ValueError, match=errmsg): AbsoluteBindingProtocol._validate_endstates(stateA, stateB) def test_validate_endstates_nosolvcomp_stateA(benzene_modifications, T4_protein_component): stateA = ChemicalSystem( { "benzene": benzene_modifications["benzene"], "protein": T4_protein_component, } ) stateB = ChemicalSystem( { "benzene": benzene_modifications["benzene"], "protein": T4_protein_component, "solvent": SolventComponent(), } ) with pytest.raises(ValueError, match="No SolventComponent found"): AbsoluteBindingProtocol._validate_endstates(stateA, stateB) def test_validate_endstates_nosolvcomp_stateB(benzene_modifications, T4_protein_component): stateA = ChemicalSystem( { "benzene": benzene_modifications["benzene"], "protein": T4_protein_component, "solvent": SolventComponent(), } ) stateB = ChemicalSystem( { "benzene": benzene_modifications["benzene"], "protein": T4_protein_component, } ) with pytest.raises(ValueError, match="No SolventComponent found"): AbsoluteBindingProtocol._validate_endstates(stateA, stateB) def test_validate_endstates_multiple_uniqueA(benzene_modifications, T4_protein_component): stateA = ChemicalSystem( { "benzene": benzene_modifications["benzene"], "toluene": benzene_modifications["toluene"], "protein": T4_protein_component, "solvlent": SolventComponent(), } ) stateB = ChemicalSystem( { "protein": T4_protein_component, "solvent": SolventComponent(), } ) with pytest.raises(ValueError, match="Only one alchemical species"): AbsoluteBindingProtocol._validate_endstates(stateA, stateB) def test_validate_solvent_endstates_solvent_dissapearing( benzene_modifications, T4_protein_component ): stateA = ChemicalSystem( { "benzene": benzene_modifications["benzene"], "protein": T4_protein_component, "foo": SolventComponent(smiles="C"), "solvent": SolventComponent(), } ) stateB = ChemicalSystem( { "benzene": benzene_modifications["benzene"], "protein": T4_protein_component, "solvent": SolventComponent(), } ) errmsg = "Only disappearing small molecule components" with pytest.raises(ValueError, match=errmsg): AbsoluteBindingProtocol._validate_endstates(stateA, stateB) def test_validate_endstates_unique_stateB(benzene_modifications, T4_protein_component): stateA = ChemicalSystem( { "benzene": benzene_modifications["benzene"], "protein": T4_protein_component, "solvent": SolventComponent(), } ) stateB = ChemicalSystem( { "toluene": benzene_modifications["toluene"], "protein": T4_protein_component, "solvent": SolventComponent(), } ) with pytest.raises(ValueError, match="appearing in state B"): AbsoluteBindingProtocol._validate_endstates(stateA, stateB) def test_charged_endstate(charged_benzene_modifications, T4_protein_component): stateA = ChemicalSystem( { "benzene": charged_benzene_modifications["benzoic_acid"], "protein": T4_protein_component, "solvent": SolventComponent(), } ) stateB = ChemicalSystem( { "protein": T4_protein_component, "solvent": SolventComponent(), } ) errmsg = "Charged alchemical molecules are not currently supported" with pytest.raises(ValueError, match=errmsg): AbsoluteBindingProtocol._validate_endstates(stateA, stateB) def test_validate_fail_extends(benzene_modifications, T4_protein_component, default_settings): stateA = ChemicalSystem( { "benzene": benzene_modifications["benzene"], "protein": T4_protein_component, "solvent": SolventComponent(), } ) stateB = ChemicalSystem( { "protein": T4_protein_component, "solvent": SolventComponent(), } ) prot = AbsoluteBindingProtocol(settings=default_settings) fake_result = ProtocolDAGResult( protocol_units=[], protocol_unit_results=[], transformation_key="foo" ) with pytest.raises(ValueError, match="extend simulations"): prot.validate(stateA=stateA, stateB=stateB, mapping=None, extends=fake_result) def test_high_timestep(benzene_modifications, T4_protein_component): s = AbsoluteBindingProtocol.default_settings() s.forcefield_settings.hydrogen_mass = 1.0 stateA = ChemicalSystem( { "benzene": benzene_modifications["benzene"], "protein": T4_protein_component, "solvent": SolventComponent(), } ) stateB = ChemicalSystem( { "protein": T4_protein_component, "solvent": SolventComponent(), } ) protocol = AbsoluteBindingProtocol(settings=s) with pytest.raises(ValueError, match="too large for hydrogen"): protocol.validate(stateA=stateA, stateB=stateB, mapping=None) def test_validate_warnings(benzene_modifications, T4_protein_component, default_settings): stateA = ChemicalSystem( { "benzene": benzene_modifications["benzene"], "protein": T4_protein_component, "solvent": SolventComponent(), } ) stateB = ChemicalSystem( { "protein": T4_protein_component, "solvent": SolventComponent(), } ) mapping = LigandAtomMapping( componentA=benzene_modifications["benzene"], componentB=benzene_modifications["benzene"], componentA_to_componentB={}, ) # one the complex restraints default_settings.complex_lambda_settings.lambda_restraints = [ 0 for _ in default_settings.complex_lambda_settings.lambda_restraints ] # add a restraint in solvent default_settings.solvent_lambda_settings.lambda_restraints[-1] = 0.9 prot = AbsoluteBindingProtocol(settings=default_settings) with pytest.warns(UserWarning) as record: prot.validate(stateA=stateA, stateB=stateB, mapping=mapping, extends=None) assert len(record) == 3 assert "mapping was passed" in str(record[0].message) assert "being applied in the complex" in str(record[1].message) assert "add restraints in the solvent" in str(record[2].message) ================================================ FILE: src/openfe/tests/protocols/openmm_abfe/utils.py ================================================ # This code is part of OpenFE and is licensed under the MIT license. # For details, see https://github.com/OpenFreeEnergy/openfe from openfe.protocols.openmm_afe.abfe_units import ( ABFEComplexAnalysisUnit, ABFEComplexSetupUnit, ABFEComplexSimUnit, ABFESolventAnalysisUnit, ABFESolventSetupUnit, ABFESolventSimUnit, ) UNIT_TYPES = { "solvent": { "setup": ABFESolventSetupUnit, "sim": ABFESolventSimUnit, "analysis": ABFESolventAnalysisUnit, }, "complex": { "setup": ABFEComplexSetupUnit, "sim": ABFEComplexSimUnit, "analysis": ABFEComplexAnalysisUnit, }, } def _get_units(protocol_units, unit_type): """ Helper method to extract setup units. """ return [pu for pu in protocol_units if isinstance(pu, unit_type)] ================================================ FILE: src/openfe/tests/protocols/openmm_ahfe/__init__.py ================================================ ================================================ FILE: src/openfe/tests/protocols/openmm_ahfe/test_ahfe_protocol.py ================================================ # This code is part of OpenFE and is licensed under the MIT license. # For details, see https://github.com/OpenFreeEnergy/openfe import sys from math import sqrt from unittest import mock import gufe import mdtraj as mdt import numpy as np import pytest from numpy.testing import assert_allclose from openff.units import unit as offunit from openff.units.openmm import ensure_quantity, from_openmm from openmm import ( CustomBondForce, CustomNonbondedForce, HarmonicAngleForce, HarmonicBondForce, NonbondedForce, PeriodicTorsionForce, ) from openmmtools.multistate.multistatesampler import MultiStateSampler import openfe from openfe import ChemicalSystem, SolventComponent from openfe.protocols import openmm_afe from openfe.protocols.openmm_afe import ( AbsoluteSolvationProtocol, AHFESolventSimUnit, ) from openfe.protocols.openmm_utils.charge_generation import ( HAS_ESPALOMA_CHARGE, HAS_NAGL, HAS_OPENEYE, ) from .utils import UNIT_TYPES, _get_units @pytest.fixture() def protocol_dry_settings(): settings = AbsoluteSolvationProtocol.default_settings() settings.vacuum_engine_settings.compute_platform = None settings.solvent_engine_settings.compute_platform = None settings.protocol_repeats = 1 return settings @pytest.fixture() def default_settings(): return AbsoluteSolvationProtocol.default_settings() def test_create_default_protocol(default_settings): # this is roughly how it should be created protocol = AbsoluteSolvationProtocol(settings=default_settings) assert protocol def test_serialize_protocol(default_settings): protocol = AbsoluteSolvationProtocol(settings=default_settings) ser = protocol.to_dict() ret = AbsoluteSolvationProtocol.from_dict(ser) assert protocol == ret def test_bad_sampler(): class FakeSimSettings(gufe.settings.SettingsBaseModel): sampler_method: str = "foo bar" errmsg = "Unknown sampler foo bar" with pytest.raises(AttributeError, match=errmsg): AHFESolventSimUnit._get_sampler( integrator=None, reporter=None, simulation_settings=FakeSimSettings(), thermodynamic_settings=None, compound_states=None, sampler_states=None, platform=None, restart=False, ) def test_repeat_units(benzene_system): protocol = openmm_afe.AbsoluteSolvationProtocol( settings=openmm_afe.AbsoluteSolvationProtocol.default_settings() ) dag = protocol.create( stateA=benzene_system, stateB=ChemicalSystem({"solvent": SolventComponent()}), mapping=None, ) # 6 protocol unit, 3 per repeat pus = list(dag.protocol_units) assert len(pus) == 18 # Check info for each repeat for phase in ["solvent", "vacuum"]: setup = _get_units(pus, UNIT_TYPES[phase]["setup"]) sim = _get_units(pus, UNIT_TYPES[phase]["sim"]) analysis = _get_units(pus, UNIT_TYPES[phase]["analysis"]) # Should be 3 of each set assert len(setup) == len(sim) == len(analysis) == 3 # Check that the dag chain is correct for analysis_pu in analysis: repeat_id = analysis_pu.inputs["repeat_id"] setup_pu = [s for s in setup if s.inputs["repeat_id"] == repeat_id][0] sim_pu = [s for s in sim if s.inputs["repeat_id"] == repeat_id][0] assert analysis_pu.inputs["setup_results"] == setup_pu assert analysis_pu.inputs["simulation_results"] == sim_pu assert sim_pu.inputs["setup_results"] == setup_pu def test_create_independent_repeat_ids(benzene_system): protocol = openmm_afe.AbsoluteSolvationProtocol( settings=openmm_afe.AbsoluteSolvationProtocol.default_settings() ) stateB = ChemicalSystem({"solvent": SolventComponent()}) dags = [] for i in range(2): dags.append( protocol.create( stateA=benzene_system, stateB=stateB, mapping=None, ) ) repeat_ids = set() for dag in dags: # 3 sets of 6 units assert len(list(dag.protocol_units)) == 18 for u in dag.protocol_units: repeat_ids.add(u.inputs["repeat_id"]) # squashed by repeat_id, that's 2 sets of 6 assert len(repeat_ids) == 12 def _assert_num_forces(system, forcetype, number): """ Helper method to check the number of forces of a given type in a system. """ forces = [f for f in system.getForces() if isinstance(f, forcetype)] assert len(forces) == number def _verify_alchemical_sterics_force_parameters( force, long_range=True, alpha=0.5, beta=0, a=1.0, b=1.0, c=6.0, d=1.0, e=1.0, f=2.0, ): assert force.getUseLongRangeCorrection() is long_range if force.getNumGlobalParameters() == 8: shift = 0 else: shift = 1 # Check the softcore parameters for the sterics forces assert force.getGlobalParameterName(0 + shift) == "softcore_alpha" assert force.getGlobalParameterName(1 + shift) == "softcore_beta" assert force.getGlobalParameterName(2 + shift) == "softcore_a" assert force.getGlobalParameterName(3 + shift) == "softcore_b" assert force.getGlobalParameterName(4 + shift) == "softcore_c" assert force.getGlobalParameterName(5 + shift) == "softcore_d" assert force.getGlobalParameterName(6 + shift) == "softcore_e" assert force.getGlobalParameterName(7 + shift) == "softcore_f" assert force.getGlobalParameterDefaultValue(0 + shift) == alpha assert force.getGlobalParameterDefaultValue(1 + shift) == beta assert force.getGlobalParameterDefaultValue(2 + shift) == a assert force.getGlobalParameterDefaultValue(3 + shift) == b assert force.getGlobalParameterDefaultValue(4 + shift) == c assert force.getGlobalParameterDefaultValue(5 + shift) == d assert force.getGlobalParameterDefaultValue(6 + shift) == e assert force.getGlobalParameterDefaultValue(7 + shift) == f @pytest.mark.parametrize("method", ["repex", "sams", "independent", "InDePeNdENT"]) def test_setup_dry_sim_vac_benzene(benzene_system, method, protocol_dry_settings, tmp_path): protocol_dry_settings.vacuum_simulation_settings.sampler_method = method protocol = openmm_afe.AbsoluteSolvationProtocol(settings=protocol_dry_settings) stateA = benzene_system stateB = ChemicalSystem({"solvent": SolventComponent()}) # Create DAG from protocol, get the vacuum and solvent units # and eventually dry run the first vacuum unit dag = protocol.create( stateA=stateA, stateB=stateB, mapping=None, ) prot_units = list(dag.protocol_units) assert len(prot_units) == 6 vac_setup_unit = _get_units(prot_units, UNIT_TYPES["vacuum"]["setup"]) vac_sim_unit = _get_units(prot_units, UNIT_TYPES["vacuum"]["sim"]) assert len(vac_setup_unit) == 1 assert len(vac_sim_unit) == 1 setup_results = vac_setup_unit[0].run( dry=True, scratch_basepath=tmp_path, shared_basepath=tmp_path ) sim_results = vac_sim_unit[0].run( system=setup_results["alchem_system"], positions=setup_results["debug_positions"], selection_indices=setup_results["selection_indices"], box_vectors=setup_results["box_vectors"], alchemical_restraints=False, dry=True, ) sampler = sim_results["sampler"] assert isinstance(sampler, MultiStateSampler) assert not sampler.is_periodic assert sampler._thermodynamic_states[0].barostat is None # standard system system = setup_results["standard_system"] assert system.getNumParticles() == 12 assert len(system.getForces()) == 4 _assert_num_forces(system, NonbondedForce, 1) _assert_num_forces(system, HarmonicBondForce, 1) _assert_num_forces(system, HarmonicAngleForce, 1) _assert_num_forces(system, PeriodicTorsionForce, 1) # alchemical system alchem_system = setup_results["alchem_system"] assert alchem_system.getNumParticles() == 12 assert len(alchem_system.getForces()) == 12 _assert_num_forces(alchem_system, NonbondedForce, 1) _assert_num_forces(alchem_system, CustomNonbondedForce, 4) _assert_num_forces(alchem_system, CustomBondForce, 4) _assert_num_forces(alchem_system, HarmonicBondForce, 1) _assert_num_forces(alchem_system, HarmonicAngleForce, 1) _assert_num_forces(alchem_system, PeriodicTorsionForce, 1) # Check some force contents stericsf = [ f for f in alchem_system.getForces() if isinstance(f, CustomNonbondedForce) and "U_sterics" in f.getEnergyFunction() ] for force in stericsf: _verify_alchemical_sterics_force_parameters(force) @pytest.mark.parametrize( "alpha, a, b, c, correction", [ [0.2, 2, 2, 1, True], [0.35, 2.2, 1.5, 0, False], ], ) def test_alchemical_settings_setup_vacuum( alpha, a, b, c, correction, benzene_system, protocol_dry_settings, tmp_path ): """ Test non default alchemical settings """ protocol_dry_settings.alchemical_settings.softcore_alpha = alpha protocol_dry_settings.alchemical_settings.softcore_a = a protocol_dry_settings.alchemical_settings.softcore_b = b protocol_dry_settings.alchemical_settings.softcore_c = c protocol_dry_settings.alchemical_settings.disable_alchemical_dispersion_correction = correction protocol = openmm_afe.AbsoluteSolvationProtocol(settings=protocol_dry_settings) stateA = benzene_system stateB = ChemicalSystem({"solvent": SolventComponent()}) # Create DAG from protocol, get the vacuum and solvent units # and eventually dry run the first vacuum unit dag = protocol.create( stateA=stateA, stateB=stateB, mapping=None, ) prot_units = list(dag.protocol_units) assert len(prot_units) == 6 vac_setup_unit = _get_units(prot_units, UNIT_TYPES["vacuum"]["setup"]) vac_sim_unit = _get_units(prot_units, UNIT_TYPES["vacuum"]["sim"]) assert len(vac_setup_unit) == 1 assert len(vac_sim_unit) == 1 results = vac_setup_unit[0].run(dry=True, scratch_basepath=tmp_path, shared_basepath=tmp_path) alchem_system = results["alchem_system"] _assert_num_forces(alchem_system, NonbondedForce, 1) _assert_num_forces(alchem_system, CustomNonbondedForce, 4) _assert_num_forces(alchem_system, CustomBondForce, 4) _assert_num_forces(alchem_system, HarmonicBondForce, 1) _assert_num_forces(alchem_system, HarmonicAngleForce, 1) _assert_num_forces(alchem_system, PeriodicTorsionForce, 1) # Check some force contents stericsf = [ f for f in alchem_system.getForces() if isinstance(f, CustomNonbondedForce) and "U_sterics" in f.getEnergyFunction() ] for force in stericsf: _verify_alchemical_sterics_force_parameters( force, long_range=not correction, alpha=alpha, a=a, b=b, c=c, ) def test_confgen_fail_AFE(benzene_system, protocol_dry_settings, tmp_path): # check system parametrisation works even if confgen fails protocol = openmm_afe.AbsoluteSolvationProtocol(settings=protocol_dry_settings) stateA = benzene_system stateB = ChemicalSystem({"solvent": SolventComponent()}) # Create DAG from protocol, get the vacuum and solvent units # and eventually dry run the first vacuum unit dag = protocol.create( stateA=stateA, stateB=stateB, mapping=None, ) prot_units = list(dag.protocol_units) vac_setup_unit = _get_units(prot_units, UNIT_TYPES["vacuum"]["setup"]) with mock.patch("rdkit.Chem.AllChem.EmbedMultipleConfs", return_value=0): # If this worked, the system will have been built system = vac_setup_unit[0].run( dry=True, scratch_basepath=tmp_path, shared_basepath=tmp_path, )["alchem_system"] assert system def test_setup_solv_benzene(benzene_system, protocol_dry_settings, tmp_path): protocol_dry_settings.solvent_output_settings.output_indices = "resname UNK" protocol = openmm_afe.AbsoluteSolvationProtocol(settings=protocol_dry_settings) stateA = benzene_system stateB = ChemicalSystem({"solvent": SolventComponent()}) # Create DAG from protocol, get the vacuum and solvent units # and eventually dry run the first solvent unit dag = protocol.create( stateA=stateA, stateB=stateB, mapping=None, ) prot_units = list(dag.protocol_units) sol_setup_unit = _get_units(prot_units, UNIT_TYPES["solvent"]["setup"]) sol_sim_unit = _get_units(prot_units, UNIT_TYPES["solvent"]["sim"]) assert len(sol_setup_unit) == len(sol_sim_unit) == 1 setup_results = sol_setup_unit[0].run( dry=True, scratch_basepath=tmp_path, shared_basepath=tmp_path ) sim_results = sol_sim_unit[0].run( system=setup_results["alchem_system"], positions=setup_results["debug_positions"], selection_indices=setup_results["selection_indices"], box_vectors=setup_results["box_vectors"], alchemical_restraints=False, dry=True, scratch_basepath=tmp_path, shared_basepath=tmp_path, ) sol_sampler = sim_results["sampler"] assert sol_sampler.is_periodic pdb = mdt.load_pdb(setup_results["pdb_structure"]) assert pdb.n_atoms == 12 def test_dry_run_vsite_fail(benzene_system, tmp_path, protocol_dry_settings): protocol_dry_settings.vacuum_forcefield_settings.forcefields = [ "amber/ff14SB.xml", # ff14SB protein force field "amber/tip4pew_standard.xml", # FF we are testing with the fun VS "amber/phosaa10.xml", # Handles THE TPO ] protocol_dry_settings.solvent_forcefield_settings.forcefields = [ "amber/ff14SB.xml", # ff14SB protein force field "amber/tip4pew_standard.xml", # FF we are testing with the fun VS "amber/phosaa10.xml", # Handles THE TPO ] protocol_dry_settings.solvation_settings.solvent_model = "tip4pew" protocol_dry_settings.integrator_settings.reassign_velocities = False protocol = AbsoluteSolvationProtocol(settings=protocol_dry_settings) stateA = benzene_system stateB = ChemicalSystem({"solvent": SolventComponent()}) # Create DAG from protocol, get the vacuum and solvent units # and eventually dry run the first solvent unit dag = protocol.create( stateA=stateA, stateB=stateB, mapping=None, ) prot_units = list(dag.protocol_units) sol_setup_unit = _get_units(prot_units, UNIT_TYPES["solvent"]["setup"]) sol_sim_unit = _get_units(prot_units, UNIT_TYPES["solvent"]["sim"]) setup_results = sol_setup_unit[0].run( dry=True, scratch_basepath=tmp_path, shared_basepath=tmp_path ) with pytest.raises(ValueError, match="are unstable"): sim_results = sol_sim_unit[0].run( system=setup_results["alchem_system"], positions=setup_results["debug_positions"], selection_indices=setup_results["selection_indices"], box_vectors=setup_results["box_vectors"], alchemical_restraints=False, dry=True, scratch_basepath=tmp_path, shared_basepath=tmp_path, ) def test_setup_dry_sim_solv_benzene_tip4p(benzene_system, protocol_dry_settings, tmp_path): protocol_dry_settings.vacuum_forcefield_settings.forcefields = [ "amber/ff14SB.xml", # ff14SB protein force field "amber/tip4pew_standard.xml", # FF we are testing with the fun VS "amber/phosaa10.xml", # Handles THE TPO ] protocol_dry_settings.solvent_forcefield_settings.forcefields = [ "amber/ff14SB.xml", # ff14SB protein force field "amber/tip4pew_standard.xml", # FF we are testing with the fun VS "amber/phosaa10.xml", # Handles THE TPO ] protocol_dry_settings.solvation_settings.solvent_model = "tip4pew" protocol_dry_settings.integrator_settings.reassign_velocities = True protocol = AbsoluteSolvationProtocol(settings=protocol_dry_settings) stateA = benzene_system stateB = ChemicalSystem({"solvent": SolventComponent()}) # Create DAG from protocol, get the vacuum and solvent units # and eventually dry run the first solvent unit dag = protocol.create( stateA=stateA, stateB=stateB, mapping=None, ) prot_units = list(dag.protocol_units) sol_setup_units = _get_units(prot_units, UNIT_TYPES["solvent"]["setup"]) sol_sim_units = _get_units(prot_units, UNIT_TYPES["solvent"]["sim"]) setup_results = sol_setup_units[0].run( dry=True, scratch_basepath=tmp_path, shared_basepath=tmp_path ) sim_results = sol_sim_units[0].run( system=setup_results["alchem_system"], positions=setup_results["debug_positions"], selection_indices=setup_results["selection_indices"], box_vectors=setup_results["box_vectors"], alchemical_restraints=False, dry=True, scratch_basepath=tmp_path, shared_basepath=tmp_path, ) sol_sampler = sim_results["sampler"] assert sol_sampler.is_periodic def test_dry_run_solv_benzene_noncubic(benzene_system, protocol_dry_settings, tmp_path): protocol_dry_settings.solvation_settings.solvent_padding = 1.5 * offunit.nanometer protocol_dry_settings.solvation_settings.box_shape = "dodecahedron" protocol = AbsoluteSolvationProtocol(settings=protocol_dry_settings) stateA = benzene_system stateB = ChemicalSystem({"solvent": SolventComponent()}) # Create DAG from protocol, get the vacuum and solvent units # and eventually dry run the first solvent unit dag = protocol.create( stateA=stateA, stateB=stateB, mapping=None, ) prot_units = list(dag.protocol_units) sol_setup_units = _get_units(prot_units, UNIT_TYPES["solvent"]["setup"]) results = sol_setup_units[0].run(dry=True, scratch_basepath=tmp_path, shared_basepath=tmp_path) system = results["alchem_system"] vectors = system.getDefaultPeriodicBoxVectors() width = float(from_openmm(vectors)[0][0].to("nanometer").m) # dodecahedron has the following shape: # [width, 0, 0], [0, width, 0], [0.5, 0.5, 0.5 * sqrt(2)] * width expected_vectors = [ [width, 0, 0], [0, width, 0], [0.5 * width, 0.5 * width, 0.5 * sqrt(2) * width], ] * offunit.nanometer assert_allclose(expected_vectors, from_openmm(vectors)) def test_dry_run_solv_user_charges_benzene(benzene_modifications, protocol_dry_settings, tmp_path): """ Create a test system with fictitious user supplied charges and ensure that they are properly passed through to the constructed alchemical system. """ protocol = openmm_afe.AbsoluteSolvationProtocol(settings=protocol_dry_settings) def assign_fictitious_charges(offmol): """ Get a random array of fake partial charges for your offmol. """ rand_arr = np.random.randint(1, 10, size=offmol.n_atoms) / 100 rand_arr[-1] = -sum(rand_arr[:-1]) return rand_arr * offunit.elementary_charge benzene_offmol = benzene_modifications["benzene"].to_openff() offmol_pchgs = assign_fictitious_charges(benzene_offmol) benzene_offmol.partial_charges = offmol_pchgs benzene_smc = openfe.SmallMoleculeComponent.from_openff(benzene_offmol) # check propchgs prop_chgs = benzene_smc.to_dict()["molprops"]["atom.dprop.PartialCharge"] prop_chgs = np.array(prop_chgs.split(), dtype=float) np.testing.assert_allclose(prop_chgs, offmol_pchgs) # Create ChemicalSystems stateA = ChemicalSystem( { "benzene": benzene_smc, "solvent": SolventComponent(), } ) stateB = ChemicalSystem({"solvent": SolventComponent()}) # Create DAG from protocol, get the vacuum and solvent units # and eventually dry run the first solvent unit dag = protocol.create(stateA=stateA, stateB=stateB, mapping=None) prot_units = list(dag.protocol_units) vac_setup_units = _get_units(prot_units, UNIT_TYPES["vacuum"]["setup"]) sol_setup_units = _get_units(prot_units, UNIT_TYPES["solvent"]["setup"]) # check sol_unit charges results = sol_setup_units[0].run(dry=True, scratch_basepath=tmp_path, shared_basepath=tmp_path) system = results["alchem_system"] nonbond = [f for f in system.getForces() if isinstance(f, NonbondedForce)] assert len(nonbond) == 1 # loop through the 12 benzene atoms # partial charge is stored in the offset for i in range(12): offsets = nonbond[0].getParticleParameterOffset(i) c = ensure_quantity(offsets[2], "openff") assert pytest.approx(c) == prop_chgs[i] # check vac_unit charges results = vac_setup_units[0].run(dry=True, scratch_basepath=tmp_path, shared_basepath=tmp_path) system = results["alchem_system"] nonbond = [f for f in system.getForces() if isinstance(f, CustomNonbondedForce)] assert len(nonbond) == 4 custom_elec = [n for n in nonbond if n.getGlobalParameterName(0) == "lambda_electrostatics"][0] # loop through the 12 benzene atoms for i in range(12): c, s = custom_elec.getParticleParameters(i) c = ensure_quantity(c, "openff") assert pytest.approx(c) == prop_chgs[i] @pytest.mark.parametrize( "method, backend, ref_key", [ ("am1bcc", "ambertools", "ambertools"), pytest.param( "am1bcc", "openeye", "openeye", marks=pytest.mark.skipif(not HAS_OPENEYE, reason="needs oechem"), ), pytest.param( "nagl", "rdkit", "nagl", marks=pytest.mark.skipif( not HAS_NAGL or HAS_OPENEYE or sys.platform.startswith("darwin"), reason="needs NAGL (without oechem) and/or on macos", ), ), pytest.param( "espaloma", "rdkit", "espaloma", marks=pytest.mark.skipif(not HAS_ESPALOMA_CHARGE, reason="needs espaloma charge"), ), ], ) def test_dry_run_charge_backends( CN_molecule, tmp_path, method, backend, ref_key, protocol_dry_settings, am1bcc_ref_charges ): """ Check that partial charge generation with different backends works as expected. """ protocol_dry_settings.partial_charge_settings.partial_charge_method = method protocol_dry_settings.partial_charge_settings.off_toolkit_backend = backend protocol_dry_settings.partial_charge_settings.nagl_model = "openff-gnn-am1bcc-0.1.0-rc.1.pt" protocol = openmm_afe.AbsoluteSolvationProtocol(settings=protocol_dry_settings) # Create ChemicalSystems stateA = ChemicalSystem({"benzene": CN_molecule, "solvent": SolventComponent()}) stateB = ChemicalSystem({"solvent": SolventComponent()}) # Create DAG from protocol, get the vacuum and solvent units # and eventually dry run the first solvent unit dag = protocol.create(stateA=stateA, stateB=stateB, mapping=None) prot_units = list(dag.protocol_units) vac_setup_units = _get_units(prot_units, UNIT_TYPES["vacuum"]["setup"]) # check vac_unit charges results = vac_setup_units[0].run(dry=True, scratch_basepath=tmp_path, shared_basepath=tmp_path) system = results["alchem_system"] nonbond = [f for f in system.getForces() if isinstance(f, CustomNonbondedForce)] assert len(nonbond) == 4 custom_elec = [n for n in nonbond if n.getGlobalParameterName(0) == "lambda_electrostatics"][0] charges = [] for i in range(system.getNumParticles()): c, s = custom_elec.getParticleParameters(i) charges.append(c) assert_allclose( am1bcc_ref_charges[ref_key], charges * offunit.elementary_charge, rtol=1e-4, ) @pytest.fixture def benzene_solvation_dag(benzene_system, protocol_dry_settings): protocol_dry_settings.protocol_repeats = 3 protocol = openmm_afe.AbsoluteSolvationProtocol(settings=protocol_dry_settings) stateA = benzene_system stateB = ChemicalSystem({"solvent": SolventComponent()}) return protocol.create(stateA=stateA, stateB=stateB, mapping=None) @pytest.mark.parametrize( "positions_write_frequency,velocities_write_frequency", [ [100 * offunit.picosecond, None], [None, None], [None, 100 * offunit.picosecond], ], ) def test_dry_run_vacuum_write_frequency( benzene_system, positions_write_frequency, velocities_write_frequency, protocol_dry_settings, tmp_path, ): protocol_dry_settings.solvent_output_settings.output_indices = "resname UNK" protocol_dry_settings.solvent_output_settings.positions_write_frequency = positions_write_frequency # fmt: skip protocol_dry_settings.solvent_output_settings.velocities_write_frequency = velocities_write_frequency # fmt: skip protocol_dry_settings.vacuum_output_settings.positions_write_frequency = positions_write_frequency # fmt: skip protocol_dry_settings.vacuum_output_settings.velocities_write_frequency = velocities_write_frequency # fmt: skip # set the time per iteration to 1 ps to make the math easy protocol_dry_settings.solvent_simulation_settings.time_per_iteration = 1 * offunit.picosecond protocol_dry_settings.vacuum_simulation_settings.time_per_iteration = 1 * offunit.picosecond protocol = openmm_afe.AbsoluteSolvationProtocol(settings=protocol_dry_settings) stateA = benzene_system stateB = ChemicalSystem({"solvent": SolventComponent()}) # Create DAG from protocol, get the vacuum and solvent units dag = protocol.create( stateA=stateA, stateB=stateB, mapping=None, ) prot_units = list(dag.protocol_units) assert len(prot_units) == 6 for phase in ["solvent", "vacuum"]: setup_units = _get_units(prot_units, UNIT_TYPES[phase]["setup"]) sim_units = _get_units(prot_units, UNIT_TYPES[phase]["sim"]) setup_results = setup_units[0].run( dry=True, scratch_basepath=tmp_path, shared_basepath=tmp_path, ) sim_results = sim_units[0].run( system=setup_results["alchem_system"], positions=setup_results["debug_positions"], selection_indices=setup_results["selection_indices"], box_vectors=setup_results["box_vectors"], alchemical_restraints=False, dry=True, scratch_basepath=tmp_path, shared_basepath=tmp_path, ) sampler = sim_results["sampler"] reporter = sampler._reporter if positions_write_frequency: assert reporter.position_interval == positions_write_frequency.m else: assert reporter.position_interval == 0 if velocities_write_frequency: assert reporter.velocity_interval == velocities_write_frequency.m else: assert reporter.velocity_interval == 0 ================================================ FILE: src/openfe/tests/protocols/openmm_ahfe/test_ahfe_protocol_results.py ================================================ # This code is part of OpenFE and is licensed under the MIT license. # For details, see https://github.com/OpenFreeEnergy/openfe import itertools import json from pathlib import Path from unittest import mock import gufe import numpy as np import openmm import pytest from openff.units import unit as offunit import openfe from openfe import ChemicalSystem, SolventComponent from openfe.protocols import openmm_afe from .utils import UNIT_TYPES, _get_units @pytest.fixture() def protocol_dry_settings(): settings = openmm_afe.AbsoluteSolvationProtocol.default_settings() settings.vacuum_engine_settings.compute_platform = None settings.solvent_engine_settings.compute_platform = None settings.protocol_repeats = 1 return settings @pytest.fixture def benzene_solvation_dag(benzene_system, protocol_dry_settings): protocol_dry_settings.protocol_repeats = 3 protocol = openmm_afe.AbsoluteSolvationProtocol(settings=protocol_dry_settings) stateA = benzene_system stateB = ChemicalSystem({"solvent": SolventComponent()}) return protocol.create(stateA=stateA, stateB=stateB, mapping=None) @pytest.fixture def patcher(): with ( mock.patch( "openfe.protocols.openmm_afe.ahfe_units.AHFESolventSetupUnit.run", return_value={ "system": Path("system.xml.bz2"), "positions": Path("positions.npy"), "pdb_structure": Path("hybrid_system.pdb"), "selection_indices": np.zeros(100), "box_vectors": [np.zeros(3), np.zeros(3), np.zeros(3)] * offunit.nm, "standard_state_correction": 0 * offunit.kilocalorie_per_mole, "restraint_geometry": None, "gufe_version": gufe.__version__, "openfe_version": openfe.__version__, "openmm_version": openmm.__version__, }, ), mock.patch( "openfe.protocols.openmm_afe.ahfe_units.AHFEVacuumSetupUnit.run", return_value={ "system": Path("system.xml.bz2"), "positions": Path("positions.npy"), "pdb_structure": Path("hybrid_system.pdb"), "selection_indices": np.zeros(100), "box_vectors": [np.zeros(3), np.zeros(3), np.zeros(3)] * offunit.nm, "standard_state_correction": 0 * offunit.kilocalorie_per_mole, "restraint_geometry": None, }, ), mock.patch( "openfe.protocols.openmm_afe.base_afe_units.np.load", return_value=np.zeros(100), ), mock.patch( "openfe.protocols.openmm_afe.base_afe_units.deserialize", return_value="foo", ), mock.patch( "openfe.protocols.openmm_afe.ahfe_units.AHFESolventSimUnit.run", return_value={ "trajectory": Path("file.nc"), "checkpoint": Path("chk.chk"), }, ), mock.patch( "openfe.protocols.openmm_afe.ahfe_units.AHFEVacuumSimUnit.run", return_value={ "trajectory": Path("file.nc"), "checkpoint": Path("chk.chk"), }, ), mock.patch( "openfe.protocols.openmm_afe.ahfe_units.AHFESolventAnalysisUnit.run", return_value={"foo": "bar"}, ), mock.patch( "openfe.protocols.openmm_afe.ahfe_units.AHFEVacuumAnalysisUnit.run", return_value={"foo": "bar"}, ), ): yield def test_gather(benzene_solvation_dag, patcher, tmp_path): # check that .gather behaves as expected dagres = gufe.protocols.execute_DAG( benzene_solvation_dag, shared_basedir=tmp_path, scratch_basedir=tmp_path, keep_shared=True, ) protocol = openmm_afe.AbsoluteSolvationProtocol( settings=openmm_afe.AbsoluteSolvationProtocol.default_settings(), ) res = protocol.gather([dagres]) assert isinstance(res, openmm_afe.AbsoluteSolvationProtocolResult) def test_unit_tagging(benzene_solvation_dag, patcher, tmp_path): # test that executing the units includes correct gen and repeat info dag_units = benzene_solvation_dag.protocol_units for phase in ["solvent", "vacuum"]: setup_results = {} sim_results = {} analysis_results = {} setup_units = _get_units(dag_units, UNIT_TYPES[phase]["setup"]) sim_units = _get_units(dag_units, UNIT_TYPES[phase]["sim"]) a_units = _get_units(dag_units, UNIT_TYPES[phase]["analysis"]) for u in setup_units: rid = u.inputs["repeat_id"] setup_results[rid] = u.execute(context=gufe.Context(tmp_path, tmp_path)) for u in sim_units: rid = u.inputs["repeat_id"] sim_results[rid] = u.execute( context=gufe.Context(tmp_path, tmp_path), setup_results=setup_results[rid], ) for u in a_units: rid = u.inputs["repeat_id"] analysis_results[rid] = u.execute( context=gufe.Context(tmp_path, tmp_path), setup_results=setup_results[rid], simulation_results=sim_results[rid], ) for results in [setup_results, sim_results, analysis_results]: for ret in results.values(): assert isinstance(ret, gufe.ProtocolUnitResult) assert ret.outputs["generation"] == 0 assert len(setup_results) == len(sim_results) == len(analysis_results) == 3 class TestProtocolResult: @pytest.fixture() def protocolresult(self, afe_solv_transformation_json): d = json.loads(afe_solv_transformation_json, cls=gufe.tokenization.JSON_HANDLER.decoder) pr = openfe.ProtocolResult.from_dict(d["protocol_result"]) return pr def test_reload_protocol_result(self, afe_solv_transformation_json): d = json.loads(afe_solv_transformation_json, cls=gufe.tokenization.JSON_HANDLER.decoder) pr = openmm_afe.AbsoluteSolvationProtocolResult.from_dict(d["protocol_result"]) assert pr def test_get_estimate(self, protocolresult): est = protocolresult.get_estimate() assert est assert est.m == pytest.approx(-2.47, abs=0.5) assert isinstance(est, offunit.Quantity) assert est.is_compatible_with(offunit.kilojoule_per_mole) def test_get_uncertainty(self, protocolresult): est = protocolresult.get_uncertainty() assert est assert est.m == pytest.approx(0.2, abs=0.2) assert isinstance(est, offunit.Quantity) assert est.is_compatible_with(offunit.kilojoule_per_mole) def test_get_individual(self, protocolresult): inds = protocolresult.get_individual_estimates() assert isinstance(inds, dict) assert isinstance(inds["solvent"], list) assert isinstance(inds["vacuum"], list) assert len(inds["solvent"]) == len(inds["vacuum"]) == 3 for e, u in itertools.chain(inds["solvent"], inds["vacuum"]): assert e.is_compatible_with(offunit.kilojoule_per_mole) assert u.is_compatible_with(offunit.kilojoule_per_mole) @pytest.mark.parametrize("key", ["solvent", "vacuum"]) def test_get_forwards_etc(self, key, protocolresult): far = protocolresult.get_forward_and_reverse_energy_analysis() assert isinstance(far, dict) assert isinstance(far[key], list) far1 = far[key][0] assert isinstance(far1, dict) for k in ["fractions", "forward_DGs", "forward_dDGs", "reverse_DGs", "reverse_dDGs"]: assert k in far1 if k == "fractions": assert isinstance(far1[k], np.ndarray) @pytest.mark.parametrize("key", ["solvent", "vacuum"]) def test_get_frwd_reverse_none_return(self, key, protocolresult): # fetch the first result of type key data = [i for i in protocolresult.data[key].values()][0][0] # set the output to None data.outputs["forward_and_reverse_energies"] = None # now fetch the analysis results and expect a warning wmsg = f"were found in the forward and reverse dictionaries of the repeats of the {key}" with pytest.warns(UserWarning, match=wmsg): protocolresult.get_forward_and_reverse_energy_analysis() @pytest.mark.parametrize("key", ["solvent", "vacuum"]) def test_get_overlap_matrices(self, key, protocolresult): ovp = protocolresult.get_overlap_matrices() assert isinstance(ovp, dict) assert isinstance(ovp[key], list) assert len(ovp[key]) == 3 ovp1 = ovp[key][0] assert isinstance(ovp1["matrix"], np.ndarray) assert ovp1["matrix"].shape == (14, 14) @pytest.mark.parametrize("key", ["solvent", "vacuum"]) def test_get_replica_transition_statistics(self, key, protocolresult): rpx = protocolresult.get_replica_transition_statistics() assert isinstance(rpx, dict) assert isinstance(rpx[key], list) assert len(rpx[key]) == 3 rpx1 = rpx[key][0] assert "eigenvalues" in rpx1 assert "matrix" in rpx1 assert rpx1["eigenvalues"].shape == (14,) assert rpx1["matrix"].shape == (14, 14) @pytest.mark.parametrize("key", ["solvent", "vacuum"]) def test_equilibration_iterations(self, key, protocolresult): eq = protocolresult.equilibration_iterations() assert isinstance(eq, dict) assert isinstance(eq[key], list) assert len(eq[key]) == 3 assert all(isinstance(v, float) for v in eq[key]) @pytest.mark.parametrize("key", ["solvent", "vacuum"]) def test_production_iterations(self, key, protocolresult): prod = protocolresult.production_iterations() assert isinstance(prod, dict) assert isinstance(prod[key], list) assert len(prod[key]) == 3 assert all(isinstance(v, float) for v in prod[key]) def test_filenotfound_replica_states(self, protocolresult): errmsg = "File could not be found" with pytest.raises(ValueError, match=errmsg): protocolresult.get_replica_states() ================================================ FILE: src/openfe/tests/protocols/openmm_ahfe/test_ahfe_resume.py ================================================ # This code is part of OpenFE and is licensed under the MIT license. # For details, see https://github.com/OpenFreeEnergy/openfe import copy import logging import os import pathlib import shutil import gufe import openmm import pytest from gufe.protocols.errors import ProtocolUnitExecutionError from numpy.testing import assert_allclose from openfe_analysis.utils.multistate import _determine_position_indices from openff.units import unit as offunit from openff.units.openmm import from_openmm from openmmtools.multistate import MultiStateReporter, ReplicaExchangeSampler import openfe from openfe.data._registry import POOCH_CACHE from openfe.protocols import openmm_afe from ...conftest import HAS_INTERNET from .utils import _get_units @pytest.fixture() def protocol_settings(): settings = openmm_afe.AbsoluteSolvationProtocol.default_settings() settings.protocol_repeats = 1 settings.solvent_output_settings.output_indices = "resname UNK" settings.solvation_settings.solvent_padding = None settings.solvation_settings.number_of_solvent_molecules = 750 settings.solvation_settings.box_shape = "dodecahedron" settings.vacuum_simulation_settings.equilibration_length = 100 * offunit.picosecond settings.vacuum_simulation_settings.production_length = 200 * offunit.picosecond settings.solvent_simulation_settings.equilibration_length = 100 * offunit.picosecond settings.solvent_simulation_settings.production_length = 200 * offunit.picosecond settings.vacuum_engine_settings.compute_platform = "CUDA" settings.solvent_engine_settings.compute_platform = "CUDA" settings.vacuum_simulation_settings.time_per_iteration = 2.5 * offunit.picosecond settings.solvent_simulation_settings.time_per_iteration = 2.5 * offunit.picosecond settings.vacuum_output_settings.checkpoint_interval = 100 * offunit.picosecond settings.solvent_output_settings.checkpoint_interval = 100 * offunit.picosecond settings.vacuum_engine_settings.compute_platform = None settings.solvent_engine_settings.compute_platform = None return settings def test_verify_execution_environment(): # Verification should pass openmm_afe.AHFESolventSimUnit._verify_execution_environment( setup_outputs={ "gufe_version": gufe.__version__, "openfe_version": openfe.__version__, "openmm_version": openmm.__version__, }, ) def test_verify_execution_environment_fail(): # Passing a bad version should fail with pytest.raises(ProtocolUnitExecutionError, match="Python environment"): openmm_afe.AHFESolventSimUnit._verify_execution_environment( setup_outputs={ "gufe_version": 0.1, "openfe_version": openfe.__version__, "openmm_version": openmm.__version__, }, ) def test_verify_execution_env_missing_key(): errmsg = "Missing environment information from setup outputs." with pytest.raises(ProtocolUnitExecutionError, match=errmsg): openmm_afe.AHFESolventSimUnit._verify_execution_environment( setup_outputs={ "foo_version": 0.1, "openfe_version": openfe.__version__, "openmm_version": openmm.__version__, }, ) @pytest.mark.skipif( not os.path.exists(POOCH_CACHE) and not HAS_INTERNET, reason="Internet unavailable and test data is not cached locally", ) def test_solvent_check_restart(protocol_settings, ahfe_solv_trajectory_path): assert openmm_afe.AHFESolventSimUnit._check_restart( output_settings=protocol_settings.solvent_output_settings, shared_path=ahfe_solv_trajectory_path.parent, ) assert not openmm_afe.AHFESolventSimUnit._check_restart( output_settings=protocol_settings.solvent_output_settings, shared_path=pathlib.Path("."), ) @pytest.mark.skipif( not os.path.exists(POOCH_CACHE) and not HAS_INTERNET, reason="Internet unavailable and test data is not cached locally", ) def test_vacuum_check_restart(protocol_settings, ahfe_vac_trajectory_path): assert openmm_afe.AHFEVacuumSimUnit._check_restart( output_settings=protocol_settings.vacuum_output_settings, shared_path=ahfe_vac_trajectory_path.parent, ) assert not openmm_afe.AHFEVacuumSimUnit._check_restart( output_settings=protocol_settings.vacuum_output_settings, shared_path=pathlib.Path("."), ) @pytest.mark.skipif( not os.path.exists(POOCH_CACHE) and not HAS_INTERNET, reason="Internet unavailable and test data is not cached locally", ) def test_check_restart_one_file_missing(protocol_settings, ahfe_vac_trajectory_path): protocol_settings.vacuum_output_settings.checkpoint_storage_filename = "foo.nc" errmsg = "the trajectory file is present but not the checkpoint file." with pytest.raises(IOError, match=errmsg): openmm_afe.AHFEVacuumSimUnit._check_restart( output_settings=protocol_settings.vacuum_output_settings, shared_path=ahfe_vac_trajectory_path.parent, ) class TestCheckpointResuming: @pytest.fixture() def protocol_dag( self, protocol_settings, benzene_modifications, ): stateA = openfe.ChemicalSystem( { "benzene": benzene_modifications["benzene"], "solvent": openfe.SolventComponent(), } ) stateB = openfe.ChemicalSystem({"solvent": openfe.SolventComponent()}) protocol = openmm_afe.AbsoluteSolvationProtocol(settings=protocol_settings) # Create DAG from protocol, get the vacuum and solvent units # and eventually dry run the first solvent unit return protocol.create( stateA=stateA, stateB=stateB, mapping=None, ) @staticmethod def _check_sampler(sampler, num_iterations: int): # Helper method to do some checks on the sampler assert sampler._iteration == num_iterations assert sampler.number_of_iterations == 80 assert sampler.is_completed is (num_iterations == 80) assert sampler.n_states == sampler.n_replicas == 14 assert sampler.is_periodic assert sampler.mcmc_moves[0].n_steps == 625 assert from_openmm(sampler.mcmc_moves[0].timestep) == 4 * offunit.fs @staticmethod def _get_positions(dataset): frame_list = _determine_position_indices(dataset) positions = [] for frame in frame_list: positions.append(copy.deepcopy(dataset.variables["positions"][frame].data)) return positions @staticmethod def _copy_simfiles(cwd: pathlib.Path, filepath): shutil.copyfile(filepath, f"{cwd}/{filepath.name}") @pytest.mark.integration def test_resume( self, protocol_dag, ahfe_solv_trajectory_path, ahfe_solv_checkpoint_path, tmp_path ): """ Attempt to resume a simulation unit with pre-existing checkpoint & trajectory files. """ self._copy_simfiles(tmp_path, ahfe_solv_trajectory_path) self._copy_simfiles(tmp_path, ahfe_solv_checkpoint_path) # 1. Check that the trajectory / checkpoint contain what we expect reporter = MultiStateReporter( tmp_path / "solvent.nc", checkpoint_storage="solvent_checkpoint.nc", ) sampler = ReplicaExchangeSampler.from_storage(reporter) self._check_sampler(sampler, num_iterations=40) # Deep copy energies & positions for later comparison init_energies = copy.deepcopy(reporter.read_energies())[0] assert init_energies.shape == (41, 14, 14) init_positions = self._get_positions(reporter._storage[0]) assert len(init_positions) == 2 reporter.close() del sampler # 2. get & run the units pus = list(protocol_dag.protocol_units) setup_unit = _get_units(pus, openmm_afe.AHFESolventSetupUnit)[0] sim_unit = _get_units(pus, openmm_afe.AHFESolventSimUnit)[0] analysis_unit = _get_units(pus, openmm_afe.AHFESolventAnalysisUnit)[0] # Dry run the setup since it'll be easier to use the objects directly setup_results = setup_unit.run( dry=True, scratch_basepath=tmp_path, shared_basepath=tmp_path, ) # Now we run the simultion in resume mode sim_results = sim_unit.run( system=setup_results["alchem_system"], positions=setup_results["debug_positions"], selection_indices=setup_results["selection_indices"], box_vectors=setup_results["box_vectors"], alchemical_restraints=False, scratch_basepath=tmp_path, shared_basepath=tmp_path, ) # Finally we analyze the results _ = analysis_unit.run( trajectory=sim_results["trajectory"], checkpoint=sim_results["checkpoint"], scratch_basepath=tmp_path, shared_basepath=tmp_path, ) # Analyze the trajectory / checkpoint again reporter = MultiStateReporter( tmp_path / "solvent.nc", checkpoint_storage="solvent_checkpoint.nc", ) sampler = ReplicaExchangeSampler.from_storage(reporter) self._check_sampler(sampler, num_iterations=80) # Check the energies and positions energies = reporter.read_energies()[0] assert energies.shape == (81, 14, 14) assert_allclose(init_energies, energies[:41]) positions = self._get_positions(reporter._storage[0]) assert len(positions) == 3 for i in range(2): assert_allclose(positions[i], init_positions[i]) reporter.close() del sampler # Check the free energy plots are there mbar_overlap_file = tmp_path / "mbar_overlap_matrix.png" assert (mbar_overlap_file).exists() @pytest.mark.slow def test_resume_fail_particles( self, protocol_dag, ahfe_solv_trajectory_path, ahfe_solv_checkpoint_path, tmp_path ): """ Test that the run unit will fail with a system incompatible to the one present in the trajectory/checkpoint files. Here we check that we don't have the same particles / mass. """ # copy files self._copy_simfiles(tmp_path, ahfe_solv_trajectory_path) self._copy_simfiles(tmp_path, ahfe_solv_checkpoint_path) pus = list(protocol_dag.protocol_units) setup_unit = _get_units(pus, openmm_afe.AHFESolventSetupUnit)[0] sim_unit = _get_units(pus, openmm_afe.AHFESolventSimUnit)[0] # Dry run the setup since it'll be easier to use the objects directly setup_results = setup_unit.run( dry=True, scratch_basepath=tmp_path, shared_basepath=tmp_path ) # Create a fake system where we will add a particle fake_system = copy.deepcopy(setup_results["alchem_system"]) fake_system.addParticle(42) # Fake system should trigger a mismatch errmsg = "Stored checkpoint System particles do not" with pytest.raises(ValueError, match=errmsg): _ = sim_unit.run( system=fake_system, positions=setup_results["debug_positions"], selection_indices=setup_results["selection_indices"], box_vectors=setup_results["box_vectors"], alchemical_restraints=False, scratch_basepath=tmp_path, shared_basepath=tmp_path, ) @pytest.mark.slow def test_resume_fail_constraints( self, protocol_dag, ahfe_solv_trajectory_path, ahfe_solv_checkpoint_path, tmp_path ): """ Test that the run unit will fail with a system incompatible to the one present in the trajectory/checkpoint files. Here we check that we don't have the same constraints. """ # copy files self._copy_simfiles(tmp_path, ahfe_solv_trajectory_path) self._copy_simfiles(tmp_path, ahfe_solv_checkpoint_path) pus = list(protocol_dag.protocol_units) setup_unit = _get_units(pus, openmm_afe.AHFESolventSetupUnit)[0] sim_unit = _get_units(pus, openmm_afe.AHFESolventSimUnit)[0] # Dry run the setup since it'll be easier to use the objects directly setup_results = setup_unit.run( dry=True, scratch_basepath=tmp_path, shared_basepath=tmp_path ) # Create a fake system without constraints fake_system = copy.deepcopy(setup_results["alchem_system"]) for i in reversed(range(fake_system.getNumConstraints())): fake_system.removeConstraint(i) # Fake system should trigger a mismatch errmsg = "Stored checkpoint System constraints do not" with pytest.raises(ValueError, match=errmsg): _ = sim_unit.run( system=fake_system, positions=setup_results["debug_positions"], selection_indices=setup_results["selection_indices"], box_vectors=setup_results["box_vectors"], alchemical_restraints=False, scratch_basepath=tmp_path, shared_basepath=tmp_path, ) @pytest.mark.slow def test_resume_fail_forces( self, protocol_dag, ahfe_solv_trajectory_path, ahfe_solv_checkpoint_path, tmp_path ): """ Test that the run unit will fail with a system incompatible to the one present in the trajectory/checkpoint files. Here we check we don't have the same forces. """ # copy files self._copy_simfiles(tmp_path, ahfe_solv_trajectory_path) self._copy_simfiles(tmp_path, ahfe_solv_checkpoint_path) pus = list(protocol_dag.protocol_units) setup_unit = _get_units(pus, openmm_afe.AHFESolventSetupUnit)[0] sim_unit = _get_units(pus, openmm_afe.AHFESolventSimUnit)[0] # Dry run the setup since it'll be easier to use the objects directly setup_results = setup_unit.run( dry=True, scratch_basepath=tmp_path, shared_basepath=tmp_path ) # Create a fake system without the last force fake_system = copy.deepcopy(setup_results["alchem_system"]) fake_system.removeForce(fake_system.getNumForces() - 1) # Fake system should trigger a mismatch errmsg = "Number of forces stored in checkpoint System" with pytest.raises(ValueError, match=errmsg): _ = sim_unit.run( system=fake_system, positions=setup_results["debug_positions"], selection_indices=setup_results["selection_indices"], box_vectors=setup_results["box_vectors"], alchemical_restraints=False, scratch_basepath=tmp_path, shared_basepath=tmp_path, ) @pytest.mark.slow def test_resume_differ_barostat( self, protocol_dag, ahfe_solv_trajectory_path, ahfe_solv_checkpoint_path, tmp_path, ): """ Test that the run unit will fail with a system incompatible to the one present in the trajectory/checkpoint files. Here we check what happens if you have a different barostat """ # copy files self._copy_simfiles(tmp_path, ahfe_solv_trajectory_path) self._copy_simfiles(tmp_path, ahfe_solv_checkpoint_path) pus = list(protocol_dag.protocol_units) setup_unit = _get_units(pus, openmm_afe.AHFESolventSetupUnit)[0] sim_unit = _get_units(pus, openmm_afe.AHFESolventSimUnit)[0] # Dry run the setup since it'll be easier to use the objects directly setup_results = setup_unit.run( dry=True, scratch_basepath=tmp_path, shared_basepath=tmp_path ) # Create a fake system with the fake force type fake_system = copy.deepcopy(setup_results["alchem_system"]) # Loop through forces and remove the force matching force type for i, f in enumerate(fake_system.getForces()): if isinstance(f, openmm.MonteCarloBarostat): findex = i fake_system.removeForce(findex) # Now add the new barostat new_force = openmm.MonteCarloBarostat( 1 * openmm.unit.atmosphere, 300 * openmm.unit.kelvin, 100 ) fake_system.addForce(new_force) # Fake system should trigger a mismatch errmsg = "stored checkpoint System does not match the same force" with pytest.raises(ValueError, match=errmsg): _ = sim_unit.run( system=fake_system, positions=setup_results["debug_positions"], selection_indices=setup_results["selection_indices"], box_vectors=setup_results["box_vectors"], alchemical_restraints=False, scratch_basepath=tmp_path, shared_basepath=tmp_path, ) @pytest.mark.slow def test_resume_differ_forces( self, protocol_dag, ahfe_solv_trajectory_path, ahfe_solv_checkpoint_path, tmp_path, caplog, ): """ Test that the run unit will fail with a system incompatible to the one present in the trajectory/checkpoint files. Here we check we have a different force """ # copy files self._copy_simfiles(tmp_path, ahfe_solv_trajectory_path) self._copy_simfiles(tmp_path, ahfe_solv_checkpoint_path) pus = list(protocol_dag.protocol_units) setup_unit = _get_units(pus, openmm_afe.AHFESolventSetupUnit)[0] sim_unit = _get_units(pus, openmm_afe.AHFESolventSimUnit)[0] # Dry run the setup since it'll be easier to use the objects directly setup_results = setup_unit.run( dry=True, scratch_basepath=tmp_path, shared_basepath=tmp_path ) # Create a fake system with the fake force type fake_system = copy.deepcopy(setup_results["alchem_system"]) # Loop through forces and remove the force matching force type for i, f in enumerate(fake_system.getForces()): if isinstance(f, openmm.NonbondedForce): findex = i fake_system.removeForce(findex) # Now add a fake force new_force = openmm.NonbondedForce() new_force.setNonbondedMethod(openmm.NonbondedForce.PME) new_force.addGlobalParameter("lambda_electrostatics", 1.0) fake_system.addForce(new_force) # Mismatching force should trigger a warning wmsg = "does not exactly match one of the forces in the simulated System" caplog.set_level(logging.INFO) _ = sim_unit.run( system=fake_system, positions=setup_results["debug_positions"], selection_indices=setup_results["selection_indices"], box_vectors=setup_results["box_vectors"], alchemical_restraints=False, scratch_basepath=tmp_path, shared_basepath=tmp_path, dry=True, ) assert wmsg in caplog.text @pytest.mark.slow @pytest.mark.parametrize("bad_file", ["trajectory", "checkpoint"]) def test_resume_bad_files( self, protocol_dag, ahfe_solv_trajectory_path, ahfe_solv_checkpoint_path, bad_file, tmp_path ): """ Test what happens when you have a bad trajectory and/or checkpoint files. """ # copy files if bad_file == "trajectory": with open(tmp_path / "solvent.nc", "w") as f: f.write("foo") else: self._copy_simfiles(tmp_path, ahfe_solv_trajectory_path) if bad_file == "checkpoint": with open(tmp_path / "solvent_checkpoint.nc", "w") as f: f.write("bar") else: self._copy_simfiles(tmp_path, ahfe_solv_checkpoint_path) pus = list(protocol_dag.protocol_units) setup_unit = _get_units(pus, openmm_afe.AHFESolventSetupUnit)[0] sim_unit = _get_units(pus, openmm_afe.AHFESolventSimUnit)[0] # Dry run the setup since it'll be easier to use the objects directly setup_results = setup_unit.run( dry=True, scratch_basepath=tmp_path, shared_basepath=tmp_path ) with pytest.raises(OSError, match="Unknown file format"): _ = sim_unit.run( system=setup_results["alchem_system"], positions=setup_results["debug_positions"], selection_indices=setup_results["selection_indices"], box_vectors=setup_results["box_vectors"], alchemical_restraints=False, scratch_basepath=tmp_path, shared_basepath=tmp_path, ) ================================================ FILE: src/openfe/tests/protocols/openmm_ahfe/test_ahfe_settings.py ================================================ # This code is part of OpenFE and is licensed under the MIT license. # For details, see https://github.com/OpenFreeEnergy/openfe import pytest from openfe.protocols import openmm_afe from openfe.protocols.openmm_afe import ( AbsoluteSolvationProtocol, ) @pytest.fixture() def default_settings(): return AbsoluteSolvationProtocol.default_settings() def test_create_default_settings(): settings = AbsoluteSolvationProtocol.default_settings() assert settings def test_invalid_protocol_repeats(): settings = AbsoluteSolvationProtocol.default_settings() with pytest.raises(ValueError, match="must be a positive value"): settings.protocol_repeats = -1 @pytest.mark.parametrize( "val", [ {"elec": [0.0, -1], "vdw": [0.0, 1.0], "restraints": [0.0, 1.0]}, {"elec": [0.0, 1.5], "vdw": [0.0, 1.5], "restraints": [-0.1, 1.0]}, ], ) def test_incorrect_window_settings(val, default_settings): errmsg = "Lambda windows must be between 0 and 1." lambda_settings = default_settings.lambda_settings with pytest.raises(ValueError, match=errmsg): lambda_settings.lambda_elec = val["elec"] lambda_settings.lambda_vdw = val["vdw"] lambda_settings.lambda_restraints = val["restraints"] @pytest.mark.parametrize( "val", [ {"elec": [0.0, 0.1, 0.0], "vdw": [0.0, 1.0, 1.0], "restraints": [0.0, 1.0, 1.0]}, ], ) def test_monotonic_lambda_windows(val, default_settings): errmsg = "The lambda schedule is not monotonically increasing" lambda_settings = default_settings.lambda_settings with pytest.raises(ValueError, match=errmsg): lambda_settings.lambda_elec = val["elec"] lambda_settings.lambda_vdw = val["vdw"] lambda_settings.lambda_restraints = val["restraints"] ================================================ FILE: src/openfe/tests/protocols/openmm_ahfe/test_ahfe_slow.py ================================================ # This code is part of OpenFE and is licensed under the MIT license. # For details, see https://github.com/OpenFreeEnergy/openfe import pathlib import pytest from gufe.protocols import execute_DAG from openff.units import unit import openfe from openfe.protocols import openmm_afe @pytest.mark.integration # takes too long to be a slow test ~ 4 mins locally @pytest.mark.flaky(reruns=3) # pytest-rerunfailures; we can get bad minimisation @pytest.mark.parametrize( "platform", [pytest.param("CPU", marks=pytest.mark.xfail(reason="see openfe issue #1670")), "CUDA"], ) def test_openmm_run_engine( platform, get_available_openmm_platforms, benzene_modifications, tmp_path, ): if platform not in get_available_openmm_platforms: pytest.skip(f"OpenMM Platform: {platform} not available") # Run a really short calculation to check everything is going well s = openmm_afe.AbsoluteSolvationProtocol.default_settings() s.protocol_repeats = 1 s.solvent_output_settings.output_indices = "resname UNK" s.vacuum_equil_simulation_settings.equilibration_length = 0.1 * unit.picosecond s.vacuum_equil_simulation_settings.production_length = 0.1 * unit.picosecond s.vacuum_simulation_settings.equilibration_length = 0.1 * unit.picosecond s.vacuum_simulation_settings.production_length = 0.1 * unit.picosecond s.solvent_equil_simulation_settings.equilibration_length_nvt = 0.1 * unit.picosecond s.solvent_equil_simulation_settings.equilibration_length = 0.1 * unit.picosecond s.solvent_equil_simulation_settings.production_length = 0.1 * unit.picosecond s.solvent_simulation_settings.equilibration_length = 0.1 * unit.picosecond s.solvent_simulation_settings.production_length = 0.1 * unit.picosecond s.vacuum_engine_settings.compute_platform = platform s.solvent_engine_settings.compute_platform = platform s.vacuum_simulation_settings.time_per_iteration = 20 * unit.femtosecond s.solvent_simulation_settings.time_per_iteration = 20 * unit.femtosecond s.vacuum_output_settings.checkpoint_interval = 20 * unit.femtosecond s.solvent_output_settings.checkpoint_interval = 20 * unit.femtosecond s.vacuum_simulation_settings.n_replicas = 20 s.solvent_simulation_settings.n_replicas = 20 s.lambda_settings.lambda_elec = [ 0.0, 0.25, 0.5, 0.75, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0 ] # fmt: skip s.lambda_settings.lambda_vdw = [ 0.0, 0.0, 0.0, 0.0, 0.0, 0.05, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.65, 0.7, 0.75, 0.8, 0.85, 0.9, 0.95, 1.0 ] # fmt: skip s.lambda_settings.lambda_restraints = [1.0 for i in range(20)] protocol = openmm_afe.AbsoluteSolvationProtocol( settings=s, ) stateA = openfe.ChemicalSystem( { "benzene": benzene_modifications["benzene"], "solvent": openfe.SolventComponent(), } ) stateB = openfe.ChemicalSystem({"solvent": openfe.SolventComponent()}) # Create DAG from protocol, get the vacuum and solvent units # and eventually dry run the first solvent unit dag = protocol.create( stateA=stateA, stateB=stateB, mapping=None, ) r = execute_DAG(dag, shared_basedir=tmp_path, scratch_basedir=tmp_path, keep_shared=True) assert r.ok() # Check outputs of solvent & vacuum results for phase in ["solvent", "vacuum"]: purs = [pur for pur in r.protocol_unit_results if pur.outputs["simtype"] == phase] # get the path to the simulation unit shared dict for pur in purs: if "Simulation" in pur.name: sim_shared = tmp_path / f"shared_{pur.source_key}_attempt_0" assert sim_shared.exists() assert pathlib.Path(sim_shared).is_dir() # check the analysis outputs for pur in purs: if "Analysis" not in pur.name: continue unit_shared = tmp_path / f"shared_{pur.source_key}_attempt_0" assert unit_shared.exists() assert pathlib.Path(unit_shared).is_dir() # Does the checkpoint file exist? checkpoint = pur.outputs["checkpoint"] assert checkpoint == sim_shared / f"{pur.outputs['simtype']}_checkpoint.nc" assert checkpoint.exists() # Does the trajectory file exist? nc = pur.outputs["trajectory"] assert nc == sim_shared / f"{pur.outputs['simtype']}.nc" assert nc.exists() # Test results methods that need files present results = protocol.gather([r]) states = results.get_replica_states() assert len(states.items()) == 2 assert len(states["solvent"]) == 1 assert states["solvent"][0].shape[1] == 20 ================================================ FILE: src/openfe/tests/protocols/openmm_ahfe/test_ahfe_tokenization.py ================================================ # This code is part of OpenFE and is licensed under the MIT license. # For details, see https://github.com/OpenFreeEnergy/openfe import json import gufe import pytest import openfe from openfe.protocols import openmm_afe from openfe.protocols.openmm_afe import ( AHFESolventAnalysisUnit, AHFESolventSetupUnit, AHFESolventSimUnit, AHFEVacuumAnalysisUnit, AHFEVacuumSetupUnit, AHFEVacuumSimUnit, ) from ..conftest import ModGufeTokenizableTestsMixin @pytest.fixture def protocol(): return openmm_afe.AbsoluteSolvationProtocol( openmm_afe.AbsoluteSolvationProtocol.default_settings() ) @pytest.fixture def protocol_units(protocol, benzene_system): pus = protocol.create( stateA=benzene_system, stateB=openfe.ChemicalSystem({"solvent": openfe.SolventComponent()}), mapping=None, ) return list(pus.protocol_units) def _filter_units(pus, classtype): for pu in pus: if isinstance(pu, classtype): return pu @pytest.fixture def solvent_protocol_setup_unit(protocol_units): return _filter_units(protocol_units, AHFESolventSetupUnit) @pytest.fixture def solvent_protocol_sim_unit(protocol_units): return _filter_units(protocol_units, AHFESolventSimUnit) @pytest.fixture def solvent_protocol_analysis_unit(protocol_units): return _filter_units(protocol_units, AHFESolventAnalysisUnit) @pytest.fixture def vacuum_protocol_setup_unit(protocol_units): return _filter_units(protocol_units, AHFEVacuumSetupUnit) @pytest.fixture def vacuum_protocol_sim_unit(protocol_units): return _filter_units(protocol_units, AHFEVacuumSimUnit) @pytest.fixture def vacuum_protocol_analysis_unit(protocol_units): return _filter_units(protocol_units, AHFEVacuumAnalysisUnit) @pytest.fixture def protocol_result(afe_solv_transformation_json): d = json.loads(afe_solv_transformation_json, cls=gufe.tokenization.JSON_HANDLER.decoder) pr = openmm_afe.AbsoluteSolvationProtocolResult.from_dict(d["protocol_result"]) return pr class TestAbsoluteSolvationProtocol(ModGufeTokenizableTestsMixin): cls = openmm_afe.AbsoluteSolvationProtocol key = None repr = "AbsoluteSolvationProtocol-" @pytest.fixture() def instance(self, protocol): return protocol class TestAHFESolventSetupUnit(ModGufeTokenizableTestsMixin): cls = AHFESolventSetupUnit repr = "AHFESolventSetupUnit(AHFE Setup: benzene solvent leg" key = None @pytest.fixture() def instance(self, solvent_protocol_setup_unit): return solvent_protocol_setup_unit class TestAHFESolventSimUnit(ModGufeTokenizableTestsMixin): cls = AHFESolventSimUnit repr = "AHFESolventSimUnit(AHFE Simulation: benzene solvent leg" key = None @pytest.fixture() def instance(self, solvent_protocol_sim_unit): return solvent_protocol_sim_unit class TestAHFESolventAnalysisUnit(ModGufeTokenizableTestsMixin): cls = AHFESolventAnalysisUnit repr = "AHFESolventAnalysisUnit(AHFE Analysis: benzene solvent leg" key = None @pytest.fixture() def instance(self, solvent_protocol_analysis_unit): return solvent_protocol_analysis_unit class TestAHFEVacuumSetupUnit(ModGufeTokenizableTestsMixin): cls = AHFEVacuumSetupUnit repr = "AHFEVacuumSetupUnit(AHFE Setup: benzene vacuum leg" key = None @pytest.fixture() def instance(self, vacuum_protocol_setup_unit): return vacuum_protocol_setup_unit class TestAHFEVacuumSimUnit(ModGufeTokenizableTestsMixin): cls = AHFEVacuumSimUnit repr = "AHFEVacuumSimUnit(AHFE Simulation: benzene vacuum leg" key = None @pytest.fixture() def instance(self, vacuum_protocol_sim_unit): return vacuum_protocol_sim_unit class TestAHFEVacuumAnalysisUnit(ModGufeTokenizableTestsMixin): cls = AHFEVacuumAnalysisUnit repr = "AHFEVacuumAnalysisUnit(AHFE Analysis: benzene vacuum leg" key = None @pytest.fixture() def instance(self, vacuum_protocol_analysis_unit): return vacuum_protocol_analysis_unit class TestAbsoluteSolvationProtocolResult(ModGufeTokenizableTestsMixin): cls = openmm_afe.AbsoluteSolvationProtocolResult key = None repr = "AbsoluteSolvationProtocolResult-" @pytest.fixture() def instance(self, protocol_result): return protocol_result ================================================ FILE: src/openfe/tests/protocols/openmm_ahfe/test_ahfe_validation.py ================================================ # This code is part of OpenFE and is licensed under the MIT license. # For details, see https://github.com/OpenFreeEnergy/openfe import pytest from gufe import LigandAtomMapping, ProtocolDAGResult from openff.units import unit as offunit from openfe import ChemicalSystem, SolventComponent from openfe.protocols import openmm_afe from openfe.protocols.openmm_afe import ( AbsoluteSolvationProtocol, ) from openfe.protocols.openmm_utils import system_validation @pytest.fixture() def default_settings(): return AbsoluteSolvationProtocol.default_settings() @pytest.fixture() def stateA(benzene_modifications): return ChemicalSystem( {"benzene": benzene_modifications["benzene"], "solvent": SolventComponent()} ) @pytest.fixture() def stateB(): return ChemicalSystem({"solvent": SolventComponent()}) @pytest.mark.parametrize( "val", [ {"elec": [0.0, 1.0], "vdw": [1.0, 1.0], "restraints": [0.0, 0.0]}, ], ) def test_validate_lambda_schedule_naked_charge(val, default_settings): errmsg = ( "There are states along this lambda schedule " "where there are atoms with charges but no LJ " f"interactions: lambda 0: " f"elec {val['elec'][0]} vdW {val['vdw'][0]}" ) default_settings.lambda_settings.lambda_elec = val["elec"] default_settings.lambda_settings.lambda_vdw = val["vdw"] default_settings.lambda_settings.lambda_restraints = val["restraints"] default_settings.vacuum_simulation_settings.n_replicas = 2 default_settings.solvent_simulation_settings.n_replicas = 2 with pytest.raises(ValueError, match=errmsg): AbsoluteSolvationProtocol._validate_lambda_schedule( default_settings.lambda_settings, default_settings.vacuum_simulation_settings, ) with pytest.raises(ValueError, match=errmsg): AbsoluteSolvationProtocol._validate_lambda_schedule( default_settings.lambda_settings, default_settings.solvent_simulation_settings, ) @pytest.mark.parametrize( "val", [ {"elec": [1.0, 1.0], "vdw": [0.0, 1.0], "restraints": [0.0, 0.0]}, ], ) def test_validate_lambda_schedule_nreplicas(val, default_settings): default_settings.lambda_settings.lambda_elec = val["elec"] default_settings.lambda_settings.lambda_vdw = val["vdw"] default_settings.lambda_settings.lambda_restraints = val["restraints"] n_replicas = 3 default_settings.vacuum_simulation_settings.n_replicas = n_replicas errmsg = ( f"Number of replicas {n_replicas} does not equal the" f" number of lambda windows {len(val['vdw'])}" ) with pytest.raises(ValueError, match=errmsg): AbsoluteSolvationProtocol._validate_lambda_schedule( default_settings.lambda_settings, default_settings.vacuum_simulation_settings, ) @pytest.mark.parametrize( "val", [ {"elec": [1.0, 1.0, 1.0], "vdw": [0.0, 1.0], "restraints": [0.0, 0.0]}, ], ) def test_validate_lambda_schedule_nwindows(val, default_settings): default_settings.lambda_settings.lambda_elec = val["elec"] default_settings.lambda_settings.lambda_vdw = val["vdw"] default_settings.lambda_settings.lambda_restraints = val["restraints"] n_replicas = 3 default_settings.vacuum_simulation_settings.n_replicas = n_replicas errmsg = ( "Components elec, vdw, and restraints must have equal amount" f" of lambda windows. Got {len(val['elec'])} elec lambda" f" windows, {len(val['vdw'])} vdw lambda windows, and" f"{len(val['restraints'])} restraints lambda windows." ) with pytest.raises(ValueError, match=errmsg): AbsoluteSolvationProtocol._validate_lambda_schedule( default_settings.lambda_settings, default_settings.vacuum_simulation_settings, ) @pytest.mark.parametrize( "val", [ {"elec": [1.0, 1.0], "vdw": [1.0, 1.0], "restraints": [0.0, 1.0]}, ], ) def test_validate_lambda_schedule_nonzero_restraints(val, default_settings): wmsg = ( "Non-zero restraint lambdas applied. The absolute " "solvation protocol doesn't apply restraints, " "therefore restraints won't be applied." ) default_settings.lambda_settings.lambda_elec = val["elec"] default_settings.lambda_settings.lambda_vdw = val["vdw"] default_settings.lambda_settings.lambda_restraints = val["restraints"] default_settings.vacuum_simulation_settings.n_replicas = 2 with pytest.warns(UserWarning, match=wmsg): AbsoluteSolvationProtocol._validate_lambda_schedule( default_settings.lambda_settings, default_settings.vacuum_simulation_settings, ) def test_validate_endstates_protcomp(benzene_modifications, T4_protein_component): stateA = ChemicalSystem( { "benzene": benzene_modifications["benzene"], "protein": T4_protein_component, "solvent": SolventComponent(), } ) stateB = ChemicalSystem( { "benzene": benzene_modifications["benzene"], "phenol": benzene_modifications["phenol"], "solvent": SolventComponent(), } ) with pytest.raises(ValueError, match="Protein components are not allowed"): AbsoluteSolvationProtocol._validate_endstates(stateA, stateB) def test_validate_endstates_nosolvcomp_stateA(benzene_modifications, T4_protein_component): stateA = ChemicalSystem( { "benzene": benzene_modifications["benzene"], } ) stateB = ChemicalSystem( { "benzene": benzene_modifications["benzene"], "phenol": benzene_modifications["phenol"], "solvent": SolventComponent(), } ) with pytest.raises(ValueError, match="No SolventComponent found in stateA"): AbsoluteSolvationProtocol._validate_endstates(stateA, stateB) def test_validate_endstates_nosolvcomp_stateB(benzene_modifications, T4_protein_component): stateA = ChemicalSystem( { "benzene": benzene_modifications["benzene"], "solvent": SolventComponent(), } ) stateB = ChemicalSystem( { "benzene": benzene_modifications["benzene"], "phenol": benzene_modifications["phenol"], } ) with pytest.raises(ValueError, match="No SolventComponent found in stateA and/or stateB"): AbsoluteSolvationProtocol._validate_endstates(stateA, stateB) def test_validate_alchem_comps_appearingB(benzene_modifications): stateA = ChemicalSystem( { "solvent": SolventComponent(), "toluene": benzene_modifications["toluene"], } ) stateB = ChemicalSystem( {"benzene": benzene_modifications["benzene"], "solvent": SolventComponent()} ) with pytest.raises(ValueError, match="Components appearing in state B"): AbsoluteSolvationProtocol._validate_endstates(stateA, stateB) def test_validate_alchem_comps_multi(benzene_modifications): stateA = ChemicalSystem( { "benzene": benzene_modifications["benzene"], "toluene": benzene_modifications["toluene"], "solvent": SolventComponent(), } ) stateB = ChemicalSystem({"solvent": SolventComponent()}) alchem_comps = system_validation.get_alchemical_components(stateA, stateB) assert len(alchem_comps["stateA"]) == 2 with pytest.raises(ValueError, match="Only one alchemical species"): AbsoluteSolvationProtocol._validate_endstates(stateA, stateB) def test_validate_alchem_nonsmc(benzene_modifications): stateA = ChemicalSystem( { "solvent": SolventComponent(), "solvent2": SolventComponent(smiles="C"), } ) stateB = ChemicalSystem( { "solvent": SolventComponent(), } ) errmsg = "Only disappearing SmallMoleculeComponents" with pytest.raises(ValueError, match=errmsg): AbsoluteSolvationProtocol._validate_endstates(stateA, stateB) def test_charged_alchem_comp(charged_benzene_modifications): stateA = ChemicalSystem( { "solute": charged_benzene_modifications["benzoic_acid"], "solvent": SolventComponent(), } ) stateB = ChemicalSystem( { "solvent": SolventComponent(), } ) assert charged_benzene_modifications["benzoic_acid"].total_charge == -1 with pytest.raises(ValueError, match="Charged alchemical molecules"): AbsoluteSolvationProtocol._validate_endstates(stateA, stateB) def test_extends_error(default_settings, stateA, stateB): fake_results = ProtocolDAGResult( protocol_units=[], protocol_unit_results=[], transformation_key="foo" ) protocol = openmm_afe.AbsoluteSolvationProtocol(settings=default_settings) with pytest.raises(ValueError, match="Can't extend simulation"): protocol.validate(stateA=stateA, stateB=stateB, mapping=None, extends=fake_results) def test_vac_bad_nonbonded(stateA, stateB): settings = openmm_afe.AbsoluteSolvationProtocol.default_settings() settings.vacuum_forcefield_settings.nonbonded_method = "pme" protocol = openmm_afe.AbsoluteSolvationProtocol(settings=settings) with pytest.raises(ValueError, match="Only the nocutoff"): protocol.validate(stateA=stateA, stateB=stateB, mapping=None) def test_vac_nvt_error(stateA, stateB): settings = openmm_afe.AbsoluteSolvationProtocol.default_settings() settings.vacuum_equil_simulation_settings.equilibration_length_nvt = 1 * offunit.nanosecond protocol = openmm_afe.AbsoluteSolvationProtocol(settings=settings) with pytest.raises(ValueError, match="cannot be run in vacuum"): protocol.validate(stateA=stateA, stateB=stateB, mapping=None) def test_mapping_warning(benzene_modifications, default_settings, stateA, stateB): # Pass in a fake mapping and expect a warning it won't be used protocol = openmm_afe.AbsoluteSolvationProtocol(settings=default_settings) mapping = LigandAtomMapping( componentA=benzene_modifications["benzene"], componentB=benzene_modifications["benzene"], componentA_to_componentB={}, ) with pytest.warns(UserWarning, match="mapping was passed"): protocol.validate(stateA=stateA, stateB=stateB, mapping=mapping) @pytest.mark.parametrize("phase", ["solvent", "vacuum"]) def test_high_timestep(phase, stateA, stateB): s = AbsoluteSolvationProtocol.default_settings() if phase == "solvent": s.solvent_forcefield_settings.hydrogen_mass = 1.0 else: s.vacuum_forcefield_settings.hydrogen_mass = 1.0 protocol = openmm_afe.AbsoluteSolvationProtocol( settings=s, ) with pytest.raises(ValueError, match="too large for hydrogen"): protocol.validate(stateA=stateA, stateB=stateB, mapping=None) ================================================ FILE: src/openfe/tests/protocols/openmm_ahfe/utils.py ================================================ # This code is part of OpenFE and is licensed under the MIT license. # For details, see https://github.com/OpenFreeEnergy/openfe from openfe.protocols.openmm_afe import ( AbsoluteSolvationProtocol, AHFESolventAnalysisUnit, AHFESolventSetupUnit, AHFESolventSimUnit, AHFEVacuumAnalysisUnit, AHFEVacuumSetupUnit, AHFEVacuumSimUnit, ) UNIT_TYPES = { "solvent": { "setup": AHFESolventSetupUnit, "sim": AHFESolventSimUnit, "analysis": AHFESolventAnalysisUnit, }, "vacuum": { "setup": AHFEVacuumSetupUnit, "sim": AHFEVacuumSimUnit, "analysis": AHFEVacuumAnalysisUnit, }, } def _get_units(protocol_units, unit_type): """ Helper method to extract setup units. """ return [pu for pu in protocol_units if isinstance(pu, unit_type)] ================================================ FILE: src/openfe/tests/protocols/openmm_md/__init__.py ================================================ ================================================ FILE: src/openfe/tests/protocols/openmm_md/test_plain_md_protocol.py ================================================ # This code is part of OpenFE and is licensed under the MIT license. # For details, see https://github.com/OpenFreeEnergy/openfe import json import logging import pathlib import sys from unittest import mock import gufe import numpy as np import openmm import pytest from gufe import ChemicalSystem, LigandAtomMapping, SmallMoleculeComponent from numpy.testing import assert_allclose from openff.units import unit from openff.units.openmm import from_openmm, to_openmm from openmm import MonteCarloBarostat, NonbondedForce from openmm import unit as omm_unit from openmmtools.states import ThermodynamicState from pydantic import ValidationError import openfe from openfe.protocols import openmm_md from openfe.protocols.openmm_md.plain_md_methods import ( PlainMDProtocol, PlainMDProtocolResult, PlainMDSetupUnit, PlainMDSimulationUnit, ) from openfe.protocols.openmm_utils import serialization from openfe.protocols.openmm_utils.charge_generation import ( HAS_ESPALOMA_CHARGE, HAS_NAGL, HAS_OPENEYE, ) from openfe.tests.conftest import HAS_ESPALOMA @pytest.fixture() def vac_settings(): settings = PlainMDProtocol.default_settings() settings.forcefield_settings.nonbonded_method = "nocutoff" settings.engine_settings.compute_platform = None return settings @pytest.mark.parametrize( "inputs, expected", [ # inputs are current step count, nvt steps, npt steps and prod steps # outputs are steps to run for nvt, npt, prod and if the production phase has started pytest.param([50, 100, 100, 100], [50, 100, 100, False], id="nvt resuming"), pytest.param([101, 100, 100, 100], [0, 99, 100, False], id="npt resuming"), pytest.param([220, 100, 100, 100], [0, 0, 80, True], id="prod resuming"), pytest.param([200, 100, 100, 100], [0, 0, 100, False], id="prod resuming not started"), ], ) def test_get_remaining_steps(inputs, expected): nvt, npt, prod, is_prod = PlainMDSimulationUnit._get_remaining_steps(*inputs) assert nvt == expected[0] assert npt == expected[1] assert prod == expected[2] assert is_prod == expected[3] def test_create_default_settings(): settings = PlainMDProtocol.default_settings() assert settings def test_create_default_protocol(): # this is roughly how it should be created protocol = PlainMDProtocol( settings=PlainMDProtocol.default_settings(), ) assert protocol def test_invalid_protocol_repeats(): settings = PlainMDProtocol.default_settings() with pytest.raises(ValueError, match="must be a positive value"): settings.protocol_repeats = -1 def test_serialize_protocol(): protocol = PlainMDProtocol( settings=PlainMDProtocol.default_settings(), ) ser = protocol.to_dict() ret = PlainMDProtocol.from_dict(ser) assert protocol == ret def test_create_independent_repeat_ids(benzene_system): # if we create two dags each with 3 repeats, they should give 6 repeat_ids # this allows multiple DAGs in flight for one Transformation that don't clash on gather settings = PlainMDProtocol.default_settings() # Default protocol is 1 repeat, change to 3 repeats settings.protocol_repeats = 3 protocol = PlainMDProtocol(settings=settings) dag1 = protocol.create( stateA=benzene_system, stateB=benzene_system, mapping=None, ) dag2 = protocol.create( stateA=benzene_system, stateB=benzene_system, mapping=None, ) repeat_ids = set() u: PlainMDSetupUnit | PlainMDSimulationUnit for u in dag1.protocol_units: repeat_ids.add(u.inputs["repeat_id"]) for u in dag2.protocol_units: repeat_ids.add(u.inputs["repeat_id"]) assert len(repeat_ids) == 6 def test_dry_run_default_vacuum(benzene_vacuum_system, vac_settings, tmp_path): protocol = PlainMDProtocol(settings=vac_settings) # create DAG from protocol and take the setup unit dag = protocol.create( stateA=benzene_vacuum_system, stateB=benzene_vacuum_system, mapping=None, ) setup_unit = list(dag.protocol_units)[0] result = setup_unit.run( dry=True, verbose=True, scratch_basepath=tmp_path, shared_basepath=tmp_path ) system = result["debug"]["system"] assert not ThermodynamicState( system, temperature=to_openmm(protocol.settings.thermo_settings.temperature), ).is_periodic assert ( ThermodynamicState( system, temperature=to_openmm(protocol.settings.thermo_settings.temperature), ).barostat is None ) def test_dry_run_logger_output(benzene_vacuum_system, vac_settings, tmp_path, caplog): vac_settings.simulation_settings.equilibration_length_nvt = 1 * unit.picosecond vac_settings.simulation_settings.equilibration_length = 1 * unit.picosecond vac_settings.simulation_settings.production_length = 1 * unit.picosecond protocol = PlainMDProtocol( settings=vac_settings, ) # create DAG from protocol dag = protocol.create( stateA=benzene_vacuum_system, stateB=benzene_vacuum_system, mapping=None, ) setup_unit = list(dag.protocol_units)[0] caplog.set_level(logging.INFO) setup_results = setup_unit.run( dry=False, verbose=True, scratch_basepath=tmp_path, shared_basepath=tmp_path ) messages = [r.message for r in caplog.records] assert "Creating system" in messages # now run the production unit after extracting outputs from the setup unit system = serialization.deserialize(setup_results["system"]) positions = np.load(setup_results["positions"]) * omm_unit.nanometers topology = openmm.app.PDBFile(str(setup_results["system_pdb"])).getTopology() equil_steps_nvt = setup_results["equil_steps_nvt"] equil_steps_npt = setup_results["equil_steps_npt"] prod_steps = setup_results["prod_steps"] prod_unit = list(dag.protocol_units)[1] prod_unit.run( system=system, positions=positions, topology=topology, equil_steps_nvt=equil_steps_nvt, equil_steps_npt=equil_steps_npt, prod_steps=prod_steps, dry=False, verbose=True, scratch_basepath=tmp_path, shared_basepath=tmp_path, ) messages = [r.message for r in caplog.records] assert "Minimizing systems" in messages assert "Running NVT equilibration for 250 steps" in messages assert "Running NPT equilibration for 250 steps" in messages assert "Running production phase for 250 steps" in messages def test_dry_run_ffcache_none_vacuum(benzene_vacuum_system, vac_settings, tmp_path): vac_settings.output_settings.forcefield_cache = None protocol = PlainMDProtocol( settings=vac_settings, ) assert protocol.settings.output_settings.forcefield_cache is None # create DAG from protocol and take first (and only) work unit from within dag = protocol.create( stateA=benzene_vacuum_system, stateB=benzene_vacuum_system, mapping=None, ) dag_unit = list(dag.protocol_units)[0] dag_unit.run(dry=True, scratch_basepath=tmp_path, shared_basepath=tmp_path)["debug"]["system"] def test_dry_run_gaff_vacuum(benzene_vacuum_system, vac_settings, tmp_path): vac_settings.forcefield_settings.small_molecule_forcefield = "gaff-2.11" protocol = PlainMDProtocol( settings=vac_settings, ) # create DAG from protocol and take first (and only) work unit from within dag = protocol.create( stateA=benzene_vacuum_system, stateB=benzene_vacuum_system, mapping=None, ) dag_unit = list(dag.protocol_units)[0] dag_unit.run(dry=True, scratch_basepath=tmp_path, shared_basepath=tmp_path)["debug"]["system"] @pytest.mark.xfail(reason="Issue #1940") @pytest.mark.skipif(not HAS_ESPALOMA, reason="espaloma is not available") def test_dry_run_espaloma_vacuum_user_charges(benzene_modifications, vac_settings, tmp_path): vac_settings.forcefield_settings.small_molecule_forcefield = "espaloma-0.3.2" protocol = PlainMDProtocol( settings=vac_settings, ) # add some dummy charges to the benzene molecule benzene = benzene_modifications["benzene"] benzene_openff = benzene.to_openff() # assign some fake charges expected_charges = [-0.5, -0.5, -0.5, -0.5, -0.5, -0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5] benzene_openff.partial_charges = expected_charges * unit.elementary_charge benzene_system = ChemicalSystem({"ligand": SmallMoleculeComponent.from_openff(benzene_openff)}) # create DAG from protocol and take first (and only) work unit from within dag = protocol.create( stateA=benzene_system, stateB=benzene_system, mapping=None, ) dag_unit = list(dag.protocol_units)[0] result = dag_unit.run(dry=True, scratch_basepath=tmp_path, shared_basepath=tmp_path) system = result["debug"]["system"] assert system.getNumParticles() == 12 # check the charges assigned nb_force = [f for f in system.getForces() if isinstance(f, NonbondedForce)][0] charges = [] for i in range(nb_force.getNumParticles()): c, _, _ = nb_force.getParticleParameters(i) charges.append(c.value_in_unit(omm_unit.elementary_charge)) assert_allclose(charges, expected_charges, rtol=1e-6) @pytest.mark.parametrize( "method, backend, ref_key", [ ("am1bcc", "ambertools", "ambertools"), pytest.param( "am1bcc", "openeye", "openeye", marks=pytest.mark.skipif(not HAS_OPENEYE, reason="needs oechem"), ), pytest.param( "nagl", "rdkit", "nagl", marks=pytest.mark.skipif( not HAS_NAGL or HAS_OPENEYE or sys.platform.startswith("darwin"), reason="needs NAGL (without oechem) and/or on macos", ), ), pytest.param( "espaloma", "rdkit", "espaloma", marks=pytest.mark.skipif(not HAS_ESPALOMA_CHARGE, reason="needs espaloma charge"), ), ], ) def test_dry_run_charge_backends( CN_molecule, tmp_path, method, backend, ref_key, vac_settings, am1bcc_ref_charges ): vac_settings.partial_charge_settings.partial_charge_method = method vac_settings.partial_charge_settings.off_toolkit_backend = backend vac_settings.partial_charge_settings.nagl_model = "openff-gnn-am1bcc-0.1.0-rc.1.pt" protocol = PlainMDProtocol(settings=vac_settings) csystem = openfe.ChemicalSystem({"ligand": CN_molecule}) dag = protocol.create(stateA=csystem, stateB=csystem, mapping=None) md_unit = list(dag.protocol_units)[0] result = md_unit.run(dry=True, scratch_basepath=tmp_path, shared_basepath=tmp_path) system = result["debug"]["system"] nonbond = [f for f in system.getForces() if isinstance(f, NonbondedForce)][0] charges = [] for i in range(system.getNumParticles()): c, s, e = nonbond.getParticleParameters(i) charges.append(from_openmm(c)) charges = unit.Quantity.from_list(charges) assert_allclose(am1bcc_ref_charges[ref_key], charges, rtol=1e-4) def test_dry_many_molecules_solvent(benzene_many_solv_system, tmp_path): """ A basic test flushing "will it work if you pass multiple molecules" """ settings = PlainMDProtocol.default_settings() settings.engine_settings.compute_platform = None protocol = PlainMDProtocol(settings=settings) # create DAG from protocol and take first (and only) work unit from within dag = protocol.create( stateA=benzene_many_solv_system, stateB=benzene_many_solv_system, mapping=None, ) dag_unit = list(dag.protocol_units)[0] dag_unit.run(dry=True, scratch_basepath=tmp_path, shared_basepath=tmp_path)["debug"]["system"] BENZ = """\ benzene PyMOL2.5 3D 0 12 12 0 0 0 0 0 0 0 0999 V2000 1.4045 -0.0000 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 0.7022 1.2164 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 -0.7023 1.2164 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 -1.4045 -0.0000 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 -0.7023 -1.2164 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 0.7023 -1.2164 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 2.5079 -0.0000 0.0000 H 0 0 0 0 0 0 0 0 0 0 0 0 1.2540 2.1720 0.0000 H 0 0 0 0 0 0 0 0 0 0 0 0 -1.2540 2.1720 0.0000 H 0 0 0 0 0 0 0 0 0 0 0 0 -2.5079 -0.0000 0.0000 H 0 0 0 0 0 0 0 0 0 0 0 0 -1.2540 -2.1719 0.0000 H 0 0 0 0 0 0 0 0 0 0 0 0 1.2540 -2.1720 0.0000 H 0 0 0 0 0 0 0 0 0 0 0 0 1 2 2 0 0 0 0 1 6 1 0 0 0 0 1 7 1 0 0 0 0 2 3 1 0 0 0 0 2 8 1 0 0 0 0 3 4 2 0 0 0 0 3 9 1 0 0 0 0 4 5 1 0 0 0 0 4 10 1 0 0 0 0 5 6 2 0 0 0 0 5 11 1 0 0 0 0 6 12 1 0 0 0 0 M END $$$$ """ PYRIDINE = """\ pyridine PyMOL2.5 3D 0 11 11 0 0 0 0 0 0 0 0999 V2000 1.4045 -0.0000 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 -0.7023 1.2164 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 -1.4045 -0.0000 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 -0.7023 -1.2164 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 0.7023 -1.2164 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 2.4940 -0.0325 0.0000 H 0 0 0 0 0 0 0 0 0 0 0 0 1.2473 -2.1604 0.0000 H 0 0 0 0 0 0 0 0 0 0 0 0 -1.2473 -2.1604 0.0000 H 0 0 0 0 0 0 0 0 0 0 0 0 -2.4945 -0.0000 0.0000 H 0 0 0 0 0 0 0 0 0 0 0 0 -1.2753 2.1437 0.0000 H 0 0 0 0 0 0 0 0 0 0 0 0 0.7525 1.3034 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0 1 5 1 0 0 0 0 1 6 1 0 0 0 0 1 11 2 0 0 0 0 2 3 2 0 0 0 0 2 10 1 0 0 0 0 3 4 1 0 0 0 0 3 9 1 0 0 0 0 4 5 2 0 0 0 0 4 8 1 0 0 0 0 5 7 1 0 0 0 0 2 11 1 0 0 0 0 M END $$$$ """ def test_dry_run_ligand_tip4p(benzene_system, tmp_path): """ Test that we can create a system with virtual sites in the environment (waters) """ settings = PlainMDProtocol.default_settings() settings.engine_settings.compute_platform = None settings.forcefield_settings.forcefields = [ "amber/ff14SB.xml", # ff14SB protein force field "amber/tip4pew_standard.xml", # FF we are testing with the fun VS "amber/phosaa10.xml", # Handles THE TPO ] # we need a larger padding distance when using the dodecahedron box settings.solvation_settings.solvent_padding = 1.5 * unit.nanometer settings.forcefield_settings.nonbonded_cutoff = 0.9 * unit.nanometer settings.solvation_settings.solvent_model = "tip4pew" settings.integrator_settings.reassign_velocities = True protocol = PlainMDProtocol(settings=settings) dag = protocol.create( stateA=benzene_system, stateB=benzene_system, mapping=None, ) dag_unit = list(dag.protocol_units)[0] result = dag_unit.run(dry=True, scratch_basepath=tmp_path, shared_basepath=tmp_path) system = result["debug"]["system"] assert system @pytest.mark.slow def test_dry_run_complex(benzene_complex_system, tmp_path): # this will be very time consuming settings = PlainMDProtocol.default_settings() settings.engine_settings.compute_platform = None protocol = PlainMDProtocol(settings=settings) dag = protocol.create( stateA=benzene_complex_system, stateB=benzene_complex_system, mapping=None, ) dag_unit = list(dag.protocol_units)[0] result = dag_unit.run(dry=True, scratch_basepath=tmp_path, shared_basepath=tmp_path) sim = result["debug"]["system"] assert ThermodynamicState( sim, temperature=to_openmm(protocol.settings.thermo_settings.temperature), ).is_periodic assert isinstance( ThermodynamicState( sim, temperature=to_openmm(protocol.settings.thermo_settings.temperature), ).barostat, MonteCarloBarostat, ) assert ( ThermodynamicState( sim, temperature=to_openmm(protocol.settings.thermo_settings.temperature), ).pressure == 1 * omm_unit.bar ) def test_hightimestep(benzene_vacuum_system, tmp_path): settings = PlainMDProtocol.default_settings() settings.forcefield_settings.hydrogen_mass = 1.0 settings.forcefield_settings.nonbonded_method = "nocutoff" p = PlainMDProtocol(settings=settings) errmsg = "too large for hydrogen mass" # make sure this is triggered in validate with pytest.raises(ValueError, match=errmsg): _ = p.create( stateA=benzene_vacuum_system, stateB=benzene_vacuum_system, mapping=None, ) def test_vaccuum_PME_error(benzene_vacuum_system): p = PlainMDProtocol( settings=PlainMDProtocol.default_settings(), ) errmsg = "PME cannot be used for vacuum transform" # make sure this is triggered in validate with pytest.raises(ValueError, match=errmsg): _ = p.create( stateA=benzene_vacuum_system, stateB=benzene_vacuum_system, mapping=None, ) def test_multiple_basesolvents_error(a2a_protein_membrane_component): p = PlainMDProtocol( settings=PlainMDProtocol.default_settings(), ) system = ChemicalSystem( { "protein-membrane": a2a_protein_membrane_component, "solvent": openfe.SolventComponent(), } ) errmsg = "Multiple BaseSolventComponents found, only one is supported." with pytest.raises(ValueError, match=errmsg): _ = p.create( stateA=system, stateB=system, mapping=None, ) def test_states_not_matching_error(benzene_vacuum_system, toluene_vacuum_system): p = PlainMDProtocol(settings=PlainMDProtocol.default_settings()) errmsg = "The two end states do not match." with pytest.raises(ValueError, match=errmsg): _ = p.create( stateA=benzene_vacuum_system, stateB=toluene_vacuum_system, mapping=None, ) def test_mapping_warning(benzene_vacuum_system, tmp_path): settings = PlainMDProtocol.default_settings() settings.forcefield_settings.nonbonded_method = "nocutoff" p = PlainMDProtocol(settings=settings) warnmsg = "A mapping was passed but is not used by this Protocol." benzene = benzene_vacuum_system.components["ligand"] with pytest.warns(match=warnmsg): _ = p.create( stateA=benzene_vacuum_system, stateB=benzene_vacuum_system, mapping=LigandAtomMapping( componentA=benzene, componentB=benzene, componentA_to_componentB=dict((i, i) for i in range(12)), ), ) @pytest.fixture def solvent_protocol_dag(benzene_system): settings = PlainMDProtocol.default_settings() settings.protocol_repeats = 3 protocol = PlainMDProtocol(settings=settings) return protocol.create( stateA=benzene_system, stateB=benzene_system, mapping=None, ) def test_unit_tagging(benzene_system, tmp_path): # test that executing the Units includes correct generation and repeat info settings = PlainMDProtocol.default_settings() settings.protocol_repeats = 3 protocol = PlainMDProtocol(settings=settings) dag = protocol.create( stateA=benzene_system, stateB=benzene_system, mapping=None, ) dag_units = dag.protocol_units with mock.patch( "openfe.protocols.openmm_md.plain_md_methods.PlainMDSimulationUnit.run", return_value={ "nc": "simulation.xtc", "last_checkpoint": "checkpoint.chk", }, ): results = [] for u in dag_units: # just execute the setup unit so we don't have to pass the results though to the simulation unit if isinstance(u, PlainMDSetupUnit): ret = u.execute(context=gufe.Context(tmp_path, tmp_path)) results.append(ret) repeats = set() for ret in results: assert isinstance(ret, gufe.ProtocolUnitResult) assert ret.outputs["generation"] == 0 repeats.add(ret.outputs["repeat_id"]) # repeats are random ints, so check we got 3 individual numbers assert len(repeats) == 3 def test_gather(solvent_protocol_dag, tmp_path): # check .gather behaves as expected with mock.patch( "openfe.protocols.openmm_md.plain_md_methods.PlainMDSimulationUnit.run", return_value={ "nc": "simulation.xtc", "last_checkpoint": "checkpoint.chk", }, ): dagres = gufe.protocols.execute_DAG( solvent_protocol_dag, shared_basedir=tmp_path, scratch_basedir=tmp_path, keep_shared=True, ) settings = PlainMDProtocol.default_settings() settings.protocol_repeats = 3 prot = PlainMDProtocol(settings=settings) res = prot.gather([dagres]) assert isinstance(res, PlainMDProtocolResult) class TestProtocolResult: @pytest.fixture() def protocolresult(self, md_json): d = json.loads(md_json, cls=gufe.tokenization.JSON_HANDLER.decoder) pr = openfe.ProtocolResult.from_dict(d["protocol_result"]) return pr def test_reload_protocol_result(self, md_json): d = json.loads(md_json, cls=gufe.tokenization.JSON_HANDLER.decoder) pr = openmm_md.plain_md_methods.PlainMDProtocolResult.from_dict(d["protocol_result"]) assert pr def test_get_estimate(self, protocolresult): est = protocolresult.get_estimate() assert est is None def test_get_uncertainty(self, protocolresult): est = protocolresult.get_uncertainty() assert est is None def test_get_traj_filename(self, protocolresult): traj = protocolresult.get_traj_filename() assert isinstance(traj, list) assert isinstance(traj[0], pathlib.Path) def test_get_pdb_filename(self, protocolresult): pdb = protocolresult.get_pdb_filename() assert isinstance(pdb, list) assert isinstance(pdb[0], pathlib.Path) ================================================ FILE: src/openfe/tests/protocols/openmm_md/test_plain_md_resume.py ================================================ # This code is part of OpenFE and is licensed under the MIT license. # For details, see https://github.com/OpenFreeEnergy/openfe import os import pathlib import shutil import gufe import openmm import openmm.unit as openmm_unit import pytest from gufe import ChemicalSystem, SmallMoleculeComponent from gufe.protocols.errors import ProtocolUnitExecutionError from openff.units import unit import openfe from openfe.data._registry import POOCH_CACHE from openfe.protocols.openmm_md.plain_md_methods import ( PlainMDProtocol, PlainMDSetupUnit, PlainMDSimulationUnit, ) from ...conftest import HAS_INTERNET @pytest.fixture() def vacuum_protocol_settings(): # setup a cheap vacuum md protocol settings = PlainMDProtocol.default_settings() settings.protocol_repeats = 1 settings.forcefield_settings.nonbonded_method = "nocutoff" settings.engine_settings.compute_platform = None settings.simulation_settings.equilibration_length_nvt = 1 * unit.picoseconds settings.simulation_settings.equilibration_length = 1 * unit.picoseconds settings.simulation_settings.production_length = 1 * unit.picoseconds settings.output_settings.checkpoint_interval = 0.5 * unit.picoseconds settings.output_settings.trajectory_write_interval = 0.5 * unit.picoseconds return settings def test_verify_execution_environment(): # verify using the current versions of the software PlainMDSimulationUnit._verify_execution_environment( setup_outputs={ "gufe_version": gufe.__version__, "openfe_version": openfe.__version__, "openmm_version": openmm.__version__, } ) def test_verify_execution_environment_fail(): # pass in different versions to force failure with pytest.raises(ProtocolUnitExecutionError, match="Python environment"): PlainMDSimulationUnit._verify_execution_environment( setup_outputs={ "gufe_version": 0.1, "openfe_version": openmm.__version__, "openmm_version": openmm.__version__, } ) def test_verify_execution_env_missing_key(): errmsg = "Missing environment information from setup outputs." with pytest.raises(ProtocolUnitExecutionError, match=errmsg): PlainMDSimulationUnit._verify_execution_environment( setup_outputs={ "foo_version": 0.1, "openfe_version": openfe.__version__, "openmm_version": openmm.__version__, }, ) @pytest.mark.skipif( not os.path.exists(POOCH_CACHE) and not HAS_INTERNET, reason="Internet unavailable and test data is not cached locally", ) def test_check_restart(vacuum_protocol_settings, plain_md_checkpoint_path): # test we can correctly detect when we should be restarting assert PlainMDSimulationUnit._check_restart( output_settings=vacuum_protocol_settings.output_settings, shared_path=plain_md_checkpoint_path.parent, ) # make sure it does not try and restart if inputs are missing assert not PlainMDSimulationUnit._check_restart( output_settings=vacuum_protocol_settings.output_settings, shared_path=pathlib.Path("."), ) @pytest.mark.skipif( not os.path.exists(POOCH_CACHE) and not HAS_INTERNET, reason="Internet unavailable and test data is not cached locally", ) class TestPlainMDResume: @pytest.fixture def protocol_dag(self, vacuum_protocol_settings, benzene_vacuum_system): protocol = PlainMDProtocol( settings=vacuum_protocol_settings, ) return protocol.create( stateA=benzene_vacuum_system, stateB=benzene_vacuum_system, mapping=None ) def test_resume( self, protocol_dag, tmp_path, caplog, vacuum_protocol_settings, plain_md_checkpoint_path ): # test that we can resume a simulation from a checkpoint protocol_units = list(protocol_dag.protocol_units) setup_unit: PlainMDSetupUnit = protocol_units[0] simulation_unit: PlainMDSimulationUnit = protocol_units[1] # copy the files over shutil.copyfile(plain_md_checkpoint_path, tmp_path / "checkpoint.xml") # dry run the setup unit setup_results = setup_unit.run( dry=True, scratch_basepath=tmp_path, shared_basepath=tmp_path ) # make sure the protocol thinks it can restart assert PlainMDSimulationUnit._check_restart( output_settings=vacuum_protocol_settings.output_settings, shared_path=tmp_path, ) # now run the simulation unit in resume mode this should be 0.5 ps of equilibration and 1 ps of production sim_results = simulation_unit.run( system=setup_results["debug"]["system"], positions=setup_results["debug"]["positions"], topology=setup_results["debug"]["topology"], equil_steps_nvt=setup_results["equil_steps_nvt"], equil_steps_npt=setup_results["equil_steps_npt"], prod_steps=setup_results["prod_steps"], verbose=True, scratch_basepath=tmp_path, shared_basepath=tmp_path, ) # make sure it prints that its restarting assert "Restarting simulation from checkpoint state" in caplog.text # check the number of npt steps to run is correct, this should be 0.5 ps at 4fs timestep assert "Running NPT equilibration for 125 steps" in caplog.text # make sure the production phase steps are correct, this should be the full 1ps at 4fs timestep assert "Running production phase for 250 steps" in caplog.text # check the outputs of the simulation unit assert sim_results["system_pdb"].exists() assert sim_results["nc"].exists() assert sim_results["last_checkpoint"] # load the final checkpoint and check the simulation time is correct, this should be 3 ps # also check the total step count simulation = openmm.app.Simulation( setup_results["debug"]["topology"], setup_results["debug"]["system"], openmm.LangevinMiddleIntegrator( 298.15 * openmm_unit.kelvin, 1.0 / openmm_unit.picosecond, 4 * openmm_unit.femtoseconds, ), ) simulation.context.setPositions(setup_results["debug"]["positions"]) simulation.loadState(str(sim_results["last_checkpoint"])) total_sim_time = simulation.context.getTime() # check the time is 3 ps assert total_sim_time.value_in_unit(openmm_unit.picoseconds) == pytest.approx(3) # check the step count has been extended assert simulation.context.getStepCount() == 750 ================================================ FILE: src/openfe/tests/protocols/openmm_md/test_plain_md_slow.py ================================================ # This code is part of OpenFE and is licensed under the MIT license. # For details, see https://github.com/OpenFreeEnergy/openfe import pathlib import pytest from gufe.protocols import execute_DAG from openff.units import unit from openfe.protocols import openmm_md @pytest.mark.integration @pytest.mark.parametrize("platform", ["CPU", "CUDA"]) def test_vacuum_sim( benzene_vacuum_system, platform, available_platforms, tmp_path, ): if platform not in available_platforms: pytest.skip(f"OpenMM Platform: {platform} is not available") # Run a vacuum MD simulation and check what files we get. settings = openmm_md.PlainMDProtocol.default_settings() settings.simulation_settings.equilibration_length_nvt = None settings.simulation_settings.equilibration_length = 10 * unit.picosecond settings.simulation_settings.production_length = 20 * unit.picosecond settings.output_settings.checkpoint_interval = 5 * unit.picosecond settings.forcefield_settings.nonbonded_method = "nocutoff" settings.engine_settings.compute_platform = platform prot = openmm_md.PlainMDProtocol(settings) dag = prot.create( stateA=benzene_vacuum_system, stateB=benzene_vacuum_system, mapping=None, ) r = execute_DAG( dag, shared_basedir=tmp_path, scratch_basedir=tmp_path, keep_shared=True, ) assert r.ok() assert len(r.protocol_unit_results) == 2 pur = r.protocol_unit_results[1] unit_shared = tmp_path / f"shared_{pur.source_key}_attempt_0" assert unit_shared.exists() assert pathlib.Path(unit_shared).is_dir() # check the files files = [ "equil_npt.pdb", "minimized.pdb", "simulation.xtc", "simulation.log", "checkpoint.xml", ] for file in files: assert (unit_shared / file).exists() # NVT PDB should not exist assert not (unit_shared / "equil_nvt.pdb").exists() # check that the output file paths are correct assert pur.outputs["system_pdb"] == unit_shared / "system.pdb" assert pur.outputs["minimized_pdb"] == unit_shared / "minimized.pdb" assert pur.outputs["nc"] == unit_shared / "simulation.xtc" assert pur.outputs["last_checkpoint"] == unit_shared / "checkpoint.xml" assert pur.outputs["npt_equil_pdb"] == unit_shared / "equil_npt.pdb" assert pur.outputs["nvt_equil_pdb"] is None @pytest.mark.integration @pytest.mark.parametrize("platform", ["CUDA"]) def test_complex_solvent_sim_gpu( benzene_complex_system, platform, available_platforms, tmp_path, ): if platform not in available_platforms: pytest.skip(f"OpenMM Platform: {platform} is not available") # Run an MD simulation and check what files we get. settings = openmm_md.PlainMDProtocol.default_settings() settings.simulation_settings.equilibration_length_nvt = 50 * unit.picosecond settings.simulation_settings.equilibration_length = 50 * unit.picosecond settings.simulation_settings.production_length = 100 * unit.picosecond settings.output_settings.checkpoint_interval = 10 * unit.picosecond settings.engine_settings.compute_platform = platform prot = openmm_md.PlainMDProtocol(settings) dag = prot.create( stateA=benzene_complex_system, stateB=benzene_complex_system, mapping=None, ) r = execute_DAG( dag, shared_basedir=tmp_path, scratch_basedir=tmp_path, keep_shared=True, ) assert r.ok() assert len(r.protocol_unit_results) == 2 pur = r.protocol_unit_results[1] unit_shared = tmp_path / f"shared_{pur.source_key}_attempt_0" assert unit_shared.exists() assert pathlib.Path(unit_shared).is_dir() # check the files files = [ "checkpoint.xml", "equil_nvt.pdb", "equil_npt.pdb", "minimized.pdb", "simulation.xtc", "simulation.log", ] for file in files: assert (unit_shared / file).exists() # check that the output file paths are correct assert pur.outputs["system_pdb"] == unit_shared / "system.pdb" assert pur.outputs["minimized_pdb"] == unit_shared / "minimized.pdb" assert pur.outputs["nc"] == unit_shared / "simulation.xtc" assert pur.outputs["last_checkpoint"] == unit_shared / "checkpoint.xml" assert pur.outputs["nvt_equil_pdb"] == unit_shared / "equil_nvt.pdb" assert pur.outputs["npt_equil_pdb"] == unit_shared / "equil_npt.pdb" ================================================ FILE: src/openfe/tests/protocols/openmm_md/test_plain_md_tokenization.py ================================================ # This ccode is part of OpenFE and is licensed under the MIT license. # For details, see https://github.com/OpenFreeEnergy/openfe import json import gufe import pytest from gufe.tests.test_tokenization import GufeTokenizableTestsMixin from openfe.protocols import openmm_md @pytest.fixture def protocol(): return openmm_md.PlainMDProtocol(openmm_md.PlainMDProtocol.default_settings()) @pytest.fixture def protocol_units(protocol, benzene_system): pus = protocol.create( stateA=benzene_system, stateB=benzene_system, mapping=None, ) return list(pus.protocol_units) @pytest.fixture def protocol_setup_unit(protocol, protocol_units): for pu in protocol_units: if isinstance(pu, openmm_md.PlainMDSetupUnit): return pu @pytest.fixture def protocol_simulation_unit(protocol, protocol_units): for pu in protocol_units: if isinstance(pu, openmm_md.PlainMDSimulationUnit): return pu @pytest.fixture def protocol_result(md_json): d = json.loads(md_json, cls=gufe.tokenization.JSON_HANDLER.decoder) pr = gufe.ProtocolResult.from_dict(d["protocol_result"]) return pr class TestPlainMDProtocol(GufeTokenizableTestsMixin): cls = openmm_md.PlainMDProtocol key = None repr = "PlainMDProtocol-" @pytest.fixture() def instance(self, protocol): return protocol def test_repr(self, instance): """ Overwrites the base `test_repr` call to do a bit more. """ assert isinstance(repr(instance), str) assert self.repr in repr(instance) class TestPlainMDSetupUnit(GufeTokenizableTestsMixin): cls = openmm_md.PlainMDSetupUnit repr = "PlainMDSetupUnit(" key = None @pytest.fixture def instance(self, protocol_setup_unit): return protocol_setup_unit def test_repr(self, instance): """ Overwrites the base `test_repr` call to do a bit more. """ assert isinstance(repr(instance), str) assert self.repr in repr(instance) class TestPlainMDSimulationUnit(GufeTokenizableTestsMixin): cls = openmm_md.PlainMDSimulationUnit repr = "PlainMDSimulationUnit(" key = None @pytest.fixture() def instance(self, protocol_simulation_unit): return protocol_simulation_unit def test_repr(self, instance): assert isinstance(repr(instance), str) assert self.repr in repr(instance) class TestPlainMDProtocolResult(GufeTokenizableTestsMixin): cls = openmm_md.PlainMDProtocolResult key = None repr = "PlainMDProtocolResult-" @pytest.fixture() def instance(self, protocol_result): return protocol_result def test_repr(self, instance): """ Overwrites the base `test_repr` call to do a bit more. """ assert isinstance(repr(instance), str) assert self.repr in repr(instance) ================================================ FILE: src/openfe/tests/protocols/openmm_rfe/__init__.py ================================================ ================================================ FILE: src/openfe/tests/protocols/openmm_rfe/helpers.py ================================================ from itertools import chain import numpy as np import openmm from gufe import LigandAtomMapping, ProteinComponent, SolventComponent from openff.units.openmm import ensure_quantity, from_openmm, to_openmm from openmm import app, unit from openmmforcefields.generators import SystemGenerator from openfe.protocols.openmm_rfe import _rfe_utils from openfe.protocols.openmm_rfe._rfe_utils.relative import HybridTopologyFactory from openfe.protocols.openmm_utils import system_creation def make_htf( mapping: LigandAtomMapping, settings, protein: ProteinComponent = None, solvent: SolventComponent = None, ) -> HybridTopologyFactory: """Code copied from the RBFE protocol to make an HTF.""" system_generator = SystemGenerator( forcefields=settings.forcefield_settings.forcefields, small_molecule_forcefield=settings.forcefield_settings.small_molecule_forcefield, forcefield_kwargs={ "constraints": app.HBonds, "rigidWater": True, "hydrogenMass": settings.forcefield_settings.hydrogen_mass * unit.amu, "removeCMMotion": settings.integrator_settings.remove_com, }, periodic_forcefield_kwargs={ "nonbondedMethod": app.PME, "nonbondedCutoff": 0.9 * unit.nanometers, }, barostat=openmm.MonteCarloBarostat( ensure_quantity(settings.thermo_settings.pressure, "openmm"), ensure_quantity(settings.thermo_settings.temperature, "openmm"), settings.integrator_settings.barostat_frequency.m, ), cache=None, ) small_mols = [mapping.componentA, mapping.componentB] # copy a lot of code from the RHT protocol off_small_mols = { "stateA": [(mapping.componentA, mapping.componentA.to_openff())], "stateB": [(mapping.componentB, mapping.componentB.to_openff())], "both": [ (m, m.to_openff()) for m in small_mols if (m != mapping.componentA and m != mapping.componentB) ], } # c. force the creation of parameters # This is necessary because we need to have the FF templates # registered ahead of solvating the system. for smc, mol in chain( off_small_mols["stateA"], off_small_mols["stateB"], off_small_mols["both"] ): system_generator.create_system(mol.to_topology().to_openmm(), molecules=[mol]) # c. get OpenMM Modeller + a dictionary of resids for each component stateA_modeller, comp_resids = system_creation.get_omm_modeller( # add the protein if passed protein_comp=protein, # add the solvent if passed solvent_comp=solvent, small_mols=dict(chain(off_small_mols["stateA"], off_small_mols["both"])), omm_forcefield=system_generator.forcefield, solvent_settings=settings.solvation_settings, ) # d. get topology & positions # Note: roundtrip positions to remove vec3 issues stateA_topology = stateA_modeller.getTopology() stateA_positions = to_openmm(from_openmm(stateA_modeller.getPositions())) # e. create the stateA System stateA_system = system_generator.create_system( stateA_modeller.topology, molecules=[m for _, m in chain(off_small_mols["stateA"], off_small_mols["both"])], ) # 2. Get stateB system # a. get the topology stateB_topology, stateB_alchem_resids = _rfe_utils.topologyhelpers.combined_topology( stateA_topology, # zeroth item (there's only one) then get the OFF representation off_small_mols["stateB"][0][1].to_topology().to_openmm(), exclude_resids=comp_resids[mapping.componentA], ) # b. get a list of small molecules for stateB stateB_system = system_generator.create_system( stateB_topology, molecules=[m for _, m in chain(off_small_mols["stateB"], off_small_mols["both"])], ) # c. Define correspondence mappings between the two systems ligand_mappings = _rfe_utils.topologyhelpers.get_system_mappings( mapping.componentA_to_componentB, stateA_system, stateA_topology, comp_resids[mapping.componentA], stateB_system, stateB_topology, stateB_alchem_resids, # These are non-optional settings for this method fix_constraints=True, ) # e. Finally get the positions stateB_positions = _rfe_utils.topologyhelpers.set_and_check_new_positions( ligand_mappings, stateA_topology, stateB_topology, old_positions=ensure_quantity(stateA_positions, "openmm"), insert_positions=ensure_quantity(off_small_mols["stateB"][0][1].conformers[0], "openmm"), ) return HybridTopologyFactory( old_system=stateA_system, old_positions=stateA_positions, old_topology=stateA_topology, new_system=stateB_system, new_positions=stateB_positions, new_topology=stateB_topology, old_to_new_atom_map=ligand_mappings["old_to_new_atom_map"], old_to_new_core_atom_map=ligand_mappings["old_to_new_core_atom_map"], use_dispersion_correction=settings.alchemical_settings.use_dispersion_correction, softcore_alpha=settings.alchemical_settings.softcore_alpha, softcore_LJ_v2=True, softcore_LJ_v2_alpha=settings.alchemical_settings.softcore_alpha, interpolate_old_and_new_14s=settings.alchemical_settings.turn_off_core_unique_exceptions, ) def _make_system_with_cmap( map_sizes: list[int], mapped_torsions: list[tuple[int, int, int, int, int, int, int, int, int]] | None = None, num_atoms: int = 8, ) -> tuple[openmm.System, openmm.app.Topology, openmm.unit.Quantity]: """ Build an OpenMM System with a CMAP term based on the provided mapping data. Parameters ---------- map_sizes : list[int] A list of integers specifying the sizes of the CMAP grids to be added. mapped_torsions : list[tuple[int, int, int, int, int, int, int, int, int]], optional A list of tuples specifying the atom indices for each mapped torsion. Each tuple should contain 9 integers: the first is the map index, followed by the 8 atom indices defining the two dihedrals. If None, a default torsion will be added using the first 8 atoms. num_atoms : int, optional The total number of atoms in the system must be >= 8. Default is 8 the minimum required for a single CMAP. Returns ------- tuple[openmm.System, openmm.app.Topology, openmm.unit.Quantity] A tuple containing the OpenMM System, Topology, and Positions. """ assert num_atoms >= 8, "num_atoms must be at least 8 to accommodate mapped torsions" system = openmm.System() # add dummy forces to avoid errors for force in [ openmm.NonbondedForce, openmm.HarmonicBondForce, openmm.HarmonicAngleForce, openmm.PeriodicTorsionForce, ]: system.addForce(force()) for _ in range(num_atoms): system.addParticle(12.0) # Add carbon-like particles # create a CMAP force if we have map sizes to add if map_sizes: cmap_force = openmm.CMAPTorsionForce() for map_size in map_sizes: # Create a grid for the CMAP grid = [0.0] * (map_size * map_size) cmap_force.addMap(map_size, grid) if mapped_torsions is None: # add a single cmap term for all atoms using the first map mapped_torsions = [(0, 0, 1, 2, 3, 4, 5, 6, 7)] for torsion in mapped_torsions: cmap_force.addTorsion(torsion[0], *torsion[1:]) system.addForce(cmap_force) # build a basic topology for the number of atoms bonding each atom to the next topology = openmm.app.Topology() chain = topology.addChain() res = topology.addResidue("RES", chain) atoms = [] for i in range(num_atoms): atom = topology.addAtom(f"C{i + 1}", openmm.app.element.carbon, res) atoms.append(atom) if i > 0: topology.addBond(atoms[i - 1], atoms[i]) # build a fake set of positions positions = openmm.unit.Quantity(np.zeros((num_atoms, 3)), openmm.unit.nanometer) return system, topology, positions ================================================ FILE: src/openfe/tests/protocols/openmm_rfe/test_hybrid_factory.py ================================================ import copy import openmm import pytest from openff.units import unit as offunit from openmm import app, unit from openfe.protocols.openmm_rfe import RelativeHybridTopologyProtocol, _rfe_utils from openfe.protocols.openmm_rfe._rfe_utils.relative import HybridTopologyFactory from openfe.tests.protocols.openmm_rfe.helpers import _make_system_with_cmap, make_htf def test_cmap_system_no_dummy_pme_energy(htf_cmap_chlorobenzene_to_fluorobenzene): """ Test that we can make a hybrid topology for a system with conserved CMAP terms not in the alchemical region and that the hybrid energy matches the end state energy. """ htf = htf_cmap_chlorobenzene_to_fluorobenzene["htf"] # make sure the cmap force was added to the internal store assert "cmap_torsion_force" in htf._hybrid_system_forces hybrid_system = htf.hybrid_system # make sure we can find the force in the system forces = htf_cmap_chlorobenzene_to_fluorobenzene["forces"] assert isinstance(forces["CMAPTorsionForce"], openmm.CMAPTorsionForce) integrator = openmm.LangevinIntegrator( 300 * unit.kelvin, 1.0 / unit.picosecond, 0.002 * unit.picoseconds ) platform = openmm.Platform.getPlatformByName("Reference") default_lambda = _rfe_utils.lambdaprotocol.LambdaProtocol() hybrid_simulation = app.Simulation( topology=htf.omm_hybrid_topology, system=hybrid_system, integrator=integrator, platform=platform, ) for end_state, ref_system, ref_top, pos in [ (0, htf._old_system, htf._old_topology, htf._old_positions), (1, htf._new_system, htf._new_topology, htf._new_positions), ]: # set lambda # set all lambda values to the current end state for name, func in default_lambda.functions.items(): val = func(end_state) hybrid_simulation.context.setParameter(name, val) # set positions hybrid_simulation.context.setPositions(pos) # get the hybrid system energy hybrid_state = hybrid_simulation.context.getState(getEnergy=True) hybrid_energy = hybrid_state.getPotentialEnergy().value_in_unit(unit.kilojoule_per_mole) # now create a reference simulation ref_simulation = app.Simulation( topology=ref_top, system=ref_system, integrator=copy.deepcopy(integrator), platform=platform, ) ref_simulation.context.setPositions(pos) ref_state = ref_simulation.context.getState(getEnergy=True) ref_energy = ref_state.getPotentialEnergy().value_in_unit(unit.kilojoule_per_mole) # energies should be the same assert ref_energy == pytest.approx(hybrid_energy, rel=1e-5) # make sure the energy is non-zero to avoid false positives assert 0.0 != pytest.approx(hybrid_energy) def test_cmap_missing_cmap_error(): """Test that an error is raised if a CMAPTorsionForce is only present in one of the end states.""" with pytest.raises( RuntimeError, match="Inconsistent CMAPTorsionForce between end states expected to be present in both", ): old_system, old_topology, old_positions = _make_system_with_cmap([4]) new_system, new_topology, new_positions = _make_system_with_cmap([]) _ = HybridTopologyFactory( old_system=old_system, old_topology=old_topology, old_positions=old_positions, new_system=new_system, new_topology=new_topology, new_positions=new_positions, # map all atoms so that one of the cmap atoms is in the alchemical core region old_to_new_atom_map={0: 0, 1: 1, 2: 2, 3: 3, 4: 4, 5: 5, 6: 6, 7: 7}, old_to_new_core_atom_map={4: 4}, # atom 4 is part of the cmap torsion ) def test_verify_cmap_incompatible_maps_error(): """Test that an error is raised if the number of CMAP terms differ between the end states.""" old_cmap = openmm.CMAPTorsionForce() new_cmap = openmm.CMAPTorsionForce() old_cmap.addMap(2, [0.0] * 2 * 2) # add one map new_cmap.addMap(2, [0.0] * 2 * 2) # add one map new_cmap.addMap(2, [0.0] * 2 * 2) # add a second map to make them incompatible with pytest.raises( RuntimeError, match="Incompatible CMAPTorsionForce between end states expected to have same number of maps, found old: 1 and new: 2", ): _ = HybridTopologyFactory._verify_cmap_compatibility(old_cmap, new_cmap) def test_verify_cmap_incompatible_torsions_error(): """Test that an error is raised if the number of CMAP torsions differ between the end states.""" old_cmap = openmm.CMAPTorsionForce() new_cmap = openmm.CMAPTorsionForce() old_cmap.addMap(2, [0.0] * 2 * 2) # add one map new_cmap.addMap(2, [0.0] * 2 * 2) # add one map # add torsions old_cmap.addTorsion(0, 0, 1, 2, 3, 4, 5, 6, 7) new_cmap.addTorsion(0, 0, 1, 2, 3, 4, 5, 6, 7) new_cmap.addTorsion(0, 1, 2, 3, 4, 5, 6, 7, 8) # add a second torsion to make them incompatible with pytest.raises( RuntimeError, match="Incompatible CMAPTorsionForce between end states expected to have same number of torsions, found old: 1 and new: 2", ): _ = HybridTopologyFactory._verify_cmap_compatibility(old_cmap, new_cmap) def test_cmap_maps_incompatible_error(): """Test that an error is raised if the CMAP maps differ between the end states using a dummy system. In this case the map parameters differ for map index 0 between the old and new systems """ old_system, old_topology, old_positions = _make_system_with_cmap([4]) new_system, new_topology, new_positions = _make_system_with_cmap([3]) with pytest.raises( RuntimeError, match="Incompatible CMAPTorsionForce map parameters found between end states for map 0 expected", ): _ = HybridTopologyFactory( old_system=old_system, old_topology=old_topology, old_positions=old_positions, new_system=new_system, new_topology=new_topology, new_positions=new_positions, # map all atoms so they end up in the environment old_to_new_atom_map={0: 0, 1: 1, 2: 2, 3: 3, 4: 4, 5: 5, 6: 6, 7: 7}, old_to_new_core_atom_map={}, ) def test_cmap_torsions_incompatible_error(): """Test that an error is raised if the CMAP torsions differ between the end states using a dummy system. In this case there is an extra cmap torsion in the new system not present in the old system.""" old_system, old_topology, old_positions = _make_system_with_cmap([4], num_atoms=12) new_system, new_topology, new_positions = _make_system_with_cmap( [4], num_atoms=12, mapped_torsions=[ # change the mapped atoms from the default (0, 4, 5, 6, 7, 8, 9, 10, 11) ], ) with pytest.raises( RuntimeError, match="Incompatible CMAPTorsionForce term found between end states for atoms " ): _ = HybridTopologyFactory( old_system=old_system, old_topology=old_topology, old_positions=old_positions, new_system=new_system, new_topology=new_topology, new_positions=new_positions, # map all atoms so they end up in the environment old_to_new_atom_map={ 0: 0, 1: 1, 2: 2, 3: 3, 4: 4, 5: 5, 6: 6, 7: 7, 8: 8, 9: 9, 10: 10, 11: 11, }, old_to_new_core_atom_map={}, ) def test_cmap_map_index_incompatible_error(): """Test that an error is raised if the CMAP map indices differ between the end states using a dummy system. In this case the map index for the single cmap torsion differs between the old and new systems.""" old_system, old_topology, old_positions = _make_system_with_cmap([4, 5]) new_system, new_topology, new_positions = _make_system_with_cmap( [4, 5], mapped_torsions=[ # change the map index from the default (1, 0, 1, 2, 3, 4, 5, 6, 7) ], ) # modify one of the torsions in the new system to make them incompatible with pytest.raises( RuntimeError, match="Incompatible CMAPTorsionForce map index found between end states for atoms ", ): _ = HybridTopologyFactory( old_system=old_system, old_topology=old_topology, old_positions=old_positions, new_system=new_system, new_topology=new_topology, new_positions=new_positions, # map all atoms so they end up in the environment old_to_new_atom_map={0: 0, 1: 1, 2: 2, 3: 3, 4: 4, 5: 5, 6: 6, 7: 7}, old_to_new_core_atom_map={}, ) def test_cmap_in_alchemical_region_error(): """Test that an error is raised if a CMAP torsion is in the alchemical region.""" old_system, old_topology, old_positions = _make_system_with_cmap([4]) new_system, new_topology, new_positions = _make_system_with_cmap([4]) with pytest.raises( RuntimeError, match="Incompatible CMAPTorsionForce term found in alchemical region for old system atoms", ): _ = HybridTopologyFactory( old_system=old_system, old_topology=old_topology, old_positions=old_positions, new_system=new_system, new_topology=new_topology, new_positions=new_positions, # map all atoms so that one of the cmap atoms is in the alchemical core region old_to_new_atom_map={0: 0, 1: 1, 2: 2, 3: 3, 4: 4, 5: 5, 6: 6, 7: 7}, old_to_new_core_atom_map={4: 4}, # atom 4 is part of the cmap torsion ) @pytest.mark.parametrize("softcore_alpha", [pytest.param(0.5), pytest.param(0.75)]) def test_softcore_parameters(chloroethane_to_fluoroethane_mapping, softcore_alpha): """ Make sure the softcore parameters are correctly set by the HTF """ settings = RelativeHybridTopologyProtocol.default_settings() settings.alchemical_settings.softcore_alpha = softcore_alpha htf = make_htf(mapping=chloroethane_to_fluoroethane_mapping, settings=settings) forces = {force.getName(): force for force in htf.hybrid_system.getForces()} # only the custom nonbonded forces and the custom bond sterics force should have these parameters set for force in [forces["CustomNonbondedForce"], forces["CustomBondForce_exceptions"]]: num_params = force.getNumGlobalParameters() hybrid_soft_core = None for i in range(num_params): # get the name of the parameter param_name = force.getGlobalParameterName(i) if param_name == "softcore_alpha": hybrid_soft_core = force.getGlobalParameterDefaultValue(i) break assert hybrid_soft_core == softcore_alpha def test_particles_mass_no_dummy(htf_chloro_fluoroethane): """ Make sure the number of particles is correct and the masses are as expected when no dummy atoms are in the hybrid system """ hybrid_system = htf_chloro_fluoroethane["hybrid_system"] assert hybrid_system.getNumParticles() == 8 expected_mass = [ 27.225801625000003 * unit.dalton, # Average of Cl/F 8.026674 * unit.dalton, # Carbon with 2Hs and HMR 6.034621 * unit.dalton, # Carbon with 3Hs and HMR 3 * unit.dalton, # HMR Hydrogen 3 * unit.dalton, 3 * unit.dalton, 3 * unit.dalton, 3 * unit.dalton, ] for idx in range(hybrid_system.getNumParticles()): assert hybrid_system.getParticleMass(idx) == expected_mass[idx] def test_particle_mass_dummy(htf_chloro_ethane): """ Make sure the number of particles is correct and the masses are as expected when dummy atoms are in the hybrid system """ hybrid_system = htf_chloro_ethane["hybrid_system"] # as we have a single unique atom at each end state there should be 9 particles assert hybrid_system.getNumParticles() == 9 expected_mass = [ 35.4532 * unit.dalton, # CL mass 7.0306475 * unit.dalton, # Average mass of Carbon with 2Hs and 3Hs with HMR 6.034621 * unit.dalton, # Carbon with 3Hs and HMR 3 * unit.dalton, # HMR Hydrogen 3 * unit.dalton, 3 * unit.dalton, 3 * unit.dalton, 3 * unit.dalton, 3 * unit.dalton, ] for idx in range(hybrid_system.getNumParticles()): assert hybrid_system.getParticleMass(idx) == expected_mass[idx] def test_constraints_count_no_dummy(htf_chloro_fluoroethane): """The number of hydrogens does not change so 5 constraints in total.""" assert htf_chloro_fluoroethane["hybrid_system"].getNumConstraints() == 5 def test_constraints_count_dummy(htf_chloro_ethane): """The number of hydrogens changes so we have an additional constraint for the unique ethane hydrogen.""" assert htf_chloro_ethane["hybrid_system"].getNumConstraints() == 6 def test_hybrid_forces_no_dummy(htf_chloro_fluoroethane): """ Test that we only have the expected forces in the hybrid system. """ forces = htf_chloro_fluoroethane["forces"] expected_forces = { "CustomBondForce", "HarmonicBondForce", "CustomAngleForce", "HarmonicAngleForce", "CustomTorsionForce", "PeriodicTorsionForce", "NonbondedForce", "CustomNonbondedForce", "CustomBondForce_exceptions", } assert not set(forces.keys()) - expected_forces def test_hybrid_forces_dummy(htf_chloro_ethane): forces = htf_chloro_ethane["forces"] expected_forces = { "CustomBondForce", "HarmonicBondForce", "CustomAngleForce", "HarmonicAngleForce", "CustomTorsionForce", "PeriodicTorsionForce", "NonbondedForce", "CustomNonbondedForce", "CustomBondForce_exceptions", } assert not set(forces.keys()) - expected_forces def test_bond_force_no_dummy(htf_chloro_fluoroethane): """ Test the standard and interpolated custom forces are correctly setup when we have no dummy atoms. """ forces = htf_chloro_fluoroethane["forces"] mapping = htf_chloro_fluoroethane["mapping"] chloro_labels = htf_chloro_fluoroethane["chloro_labels"] fluoro_labels = htf_chloro_fluoroethane["fluoro_labels"] # there should be no standard bond force terms standard_bond_force = forces["HarmonicBondForce"] assert standard_bond_force.getNumBonds() == 0 # there should be two forces in the interpolated bond force custom_bond_force = forces["CustomBondForce"] # there should be a single global parameter for lambda assert custom_bond_force.getNumGlobalParameters() == 1 # make sure it has the correct name assert custom_bond_force.getGlobalParameterName(0) == "lambda_bonds" num_bonds = custom_bond_force.getNumBonds() assert num_bonds == 2 # now check the parameters are correctly interpolated for i in range(num_bonds): p1, p2, params = custom_bond_force.getBondParameters(i) # p1, p2 are the index in chloroethane get the expected parameters from the labels chloro_bond = chloro_labels["Bonds"][(p1, p2)] # make sure the initial parameters match chloroethane # this also implicitly checks the per bond parameters have been entered in the expected order assert params[0] == chloro_bond.length.m_as(offunit.nanometer) assert params[1] == chloro_bond.k.m_as(offunit.kilojoule_per_mole / offunit.nanometer**2) # then check the fluoro parameters # map the index first f1 = mapping.componentA_to_componentB[p1] f2 = mapping.componentA_to_componentB[p2] fluoro_bond = fluoro_labels["Bonds"][(f1, f2)] assert params[2] == fluoro_bond.length.m_as(offunit.nanometer) assert params[3] == fluoro_bond.k.m_as(offunit.kilojoule_per_mole / offunit.nanometer**2) def test_bond_force_dummy(htf_chloro_ethane): forces = htf_chloro_ethane["forces"] mapping = htf_chloro_ethane["mapping"] chloro_labels = htf_chloro_ethane["chloro_labels"] ethane_labels = htf_chloro_ethane["ethane_labels"] # there should be one standard bond force term (non-interpolated) # as terms with a dummy atom are held fixed # there would be 2 if the transformed atom was not H and involved in a constraint standard_bond_force = forces["HarmonicBondForce"] num_bonds = standard_bond_force.getNumBonds() assert num_bonds == 1 for i in range(num_bonds): p1, p2, length, k = standard_bond_force.getBondParameters(i) # make sure they correspond to the expected values in stateA chloroethane chloro_bond = chloro_labels["Bonds"][(p1, p2)] assert length == chloro_bond.length.m_as(offunit.nanometer) * unit.nanometer assert ( k == chloro_bond.k.m_as(offunit.kilojoule_per_mole / offunit.nanometer**2) * unit.kilojoule_per_mole / unit.nanometer**2 ) # there should then be one interpolated (fully mapped) bond force for the central carbons custom_bond_force = forces["CustomBondForce"] # there should be a single global parameter for lambda assert custom_bond_force.getNumGlobalParameters() == 1 # make sure it has the correct name assert custom_bond_force.getGlobalParameterName(0) == "lambda_bonds" num_bonds = custom_bond_force.getNumBonds() assert num_bonds == 1 for i in range(num_bonds): p1, p2, params = custom_bond_force.getBondParameters(i) # p1, p2 are the index in chloroethane get the expected parameters from the labels chloro_bond = chloro_labels["Bonds"][(p1, p2)] # make sure the initial parameters match chloroethane # this also implicitly checks the per bond parameters have been entered in the expected order assert params[0] == chloro_bond.length.m_as(offunit.nanometer) assert params[1] == chloro_bond.k.m_as(offunit.kilojoule_per_mole / offunit.nanometer**2) # then check the ethane parameters # map the index first e1 = mapping.componentA_to_componentB[p1] e2 = mapping.componentA_to_componentB[p2] ethane_bond = ethane_labels["Bonds"][(e1, e2)] assert params[2] == ethane_bond.length.m_as(offunit.nanometer) assert params[3] == ethane_bond.k.m_as(offunit.kilojoule_per_mole / offunit.nanometer**2) def test_angle_force_no_dummy(htf_chloro_fluoroethane): """ Test the standard and interpolated custom angle forces are correctly setup when we have no dummy atoms. """ forces = htf_chloro_fluoroethane["forces"] mapping = htf_chloro_fluoroethane["mapping"] chloro_labels = htf_chloro_fluoroethane["chloro_labels"] fluoro_labels = htf_chloro_fluoroethane["fluoro_labels"] # there should be no standard angle force terms standard_angle_force = forces["HarmonicAngleForce"] assert standard_angle_force.getNumAngles() == 0 # there should be 12 forces in the interpolated angle force even if the parameters are not interpolated custom_angle_force = forces["CustomAngleForce"] # there should be a single global parameter for lambda assert custom_angle_force.getNumGlobalParameters() == 1 # make sure it has the correct name assert custom_angle_force.getGlobalParameterName(0) == "lambda_angles" num_angles = custom_angle_force.getNumAngles() assert num_angles == 12 # now check the parameters are correctly interpolated for i in range(num_angles): p1, p2, p3, params = custom_angle_force.getAngleParameters(i) # p1, p2, p3 are the index in chloroethane get the expected parameters from the labels chloro_angle = chloro_labels["Angles"][(p1, p2, p3)] # make sure the initial parameters match chloroethane # this also implicitly checks the per angle parameters have been entered in the expected order assert params[0] == chloro_angle.angle.m_as(offunit.radian) assert params[1] == chloro_angle.k.m_as(offunit.kilojoule_per_mole / offunit.radian**2) # then check the fluoro parameters # map the index first f1 = mapping.componentA_to_componentB[p1] f2 = mapping.componentA_to_componentB[p2] f3 = mapping.componentA_to_componentB[p3] fluoro_angle = fluoro_labels["Angles"][(f1, f2, f3)] assert params[2] == fluoro_angle.angle.m_as(offunit.radian) assert params[3] == fluoro_angle.k.m_as(offunit.kilojoule_per_mole / offunit.radian**2) def test_angle_force_dummy(htf_chloro_ethane): forces = htf_chloro_ethane["forces"] mapping = htf_chloro_ethane["mapping"] chloro_labels = htf_chloro_ethane["chloro_labels"] ethane_labels = htf_chloro_ethane["ethane_labels"] # there should be 6 standard angle force terms (non-interpolated) # 3 for chloroethane involving the Cl atom # 3 for ethane involving the unique H atom standard_angle_force = forces["HarmonicAngleForce"] num_angles = standard_angle_force.getNumAngles() assert num_angles == 6 for i in range(num_angles): p1, p2, p3, angle, k = standard_angle_force.getAngleParameters(i) # if the starting atom index is 0 it is a chloroethane angle else ethane if p1 == 0 or p3 == 0: chloro_angle = chloro_labels["Angles"][(p1, p2, p3)] assert angle == chloro_angle.angle.m_as(offunit.radian) * unit.radian assert ( k == chloro_angle.k.m_as(offunit.kilojoule_per_mole / offunit.radian**2) * unit.kilojoule_per_mole / unit.radian**2 ) else: # manually map the Cl - H e1 = 0 e2 = mapping.componentA_to_componentB[p2] e3 = mapping.componentA_to_componentB[p3] ethane_angle = ethane_labels["Angles"][(e1, e2, e3)] assert angle == ethane_angle.angle.m_as(offunit.radian) * unit.radian assert ( k == ethane_angle.k.m_as(offunit.kilojoule_per_mole / offunit.radian**2) * unit.kilojoule_per_mole / unit.radian**2 ) # there should then be 9 interpolated (fully mapped) angle terms custom_angle_force = forces["CustomAngleForce"] # there should be a single global parameter for lambda assert custom_angle_force.getNumGlobalParameters() == 1 # make sure it has the correct name assert custom_angle_force.getGlobalParameterName(0) == "lambda_angles" num_angles = custom_angle_force.getNumAngles() assert num_angles == 9 for i in range(num_angles): p1, p2, p3, params = custom_angle_force.getAngleParameters(i) # p1, p2, p3 are the index in chloroethane get the expected parameters from the labels chloro_angle = chloro_labels["Angles"][(p1, p2, p3)] # make sure the initial parameters match chloroethane # this also implicitly checks the per angle parameters have been entered in the expected order assert params[0] == chloro_angle.angle.m_as(offunit.radian) assert params[1] == chloro_angle.k.m_as(offunit.kilojoule_per_mole / offunit.radian**2) # then check the ethane parameters # map the index first e1 = mapping.componentA_to_componentB[p1] e2 = mapping.componentA_to_componentB[p2] e3 = mapping.componentA_to_componentB[p3] ethane_angle = ethane_labels["Angles"][(e1, e2, e3)] assert params[2] == ethane_angle.angle.m_as(offunit.radian) assert params[3] == ethane_angle.k.m_as(offunit.kilojoule_per_mole / offunit.radian**2) def test_torsion_force_no_dummy(htf_chloro_fluoroethane): """ Test the standard and interpolated custom torsion forces are correctly setup when we have no dummy atoms. """ forces = htf_chloro_fluoroethane["forces"] mapping = htf_chloro_fluoroethane["mapping"] chloro_labels = htf_chloro_fluoroethane["chloro_labels"] fluoro_labels = htf_chloro_fluoroethane["fluoro_labels"] # there should be 6 standard torsion force terms (non-interpolated) standard_torsion_force = forces["PeriodicTorsionForce"] num_torsions = standard_torsion_force.getNumTorsions() assert num_torsions == 6 # now check the parameters are correctly assigned for i in range(num_torsions): p1, p2, p3, p4, periodicity, phase, k = standard_torsion_force.getTorsionParameters(i) # p1, p2, p3, p4 are the index in chloroethane get the expected parameters from the labels chloro_torsion = chloro_labels["ProperTorsions"][(p1, p2, p3, p4)] term_index = chloro_torsion.periodicity.index(periodicity) assert periodicity == chloro_torsion.periodicity[term_index] assert phase == chloro_torsion.phase[term_index].m_as(offunit.radian) * unit.radian assert ( k == chloro_torsion.k[term_index].m_as(offunit.kilojoule_per_mole) * unit.kilojoule_per_mole ) # map to fluoroethane f1 = mapping.componentA_to_componentB[p1] f2 = mapping.componentA_to_componentB[p2] f3 = mapping.componentA_to_componentB[p3] f4 = mapping.componentA_to_componentB[p4] fluoro_torsion = fluoro_labels["ProperTorsions"][(f1, f2, f3, f4)] term_index = fluoro_torsion.periodicity.index(periodicity) # make sure those parameters also match assert periodicity == fluoro_torsion.periodicity[term_index] assert phase == fluoro_torsion.phase[term_index].m_as(offunit.radian) * unit.radian assert ( k == fluoro_torsion.k[term_index].m_as(offunit.kilojoule_per_mole) * unit.kilojoule_per_mole ) # custom torsion forces custom_torsion_force = forces["CustomTorsionForce"] # there should be a single global parameter for lambda assert custom_torsion_force.getNumGlobalParameters() == 1 # make sure it has the correct name assert custom_torsion_force.getGlobalParameterName(0) == "lambda_torsions" num_torsions = custom_torsion_force.getNumTorsions() # we have 3 interpolated torsions with two k values each which is 6 terms # but the HTF interpolates each torsion from and to zero so 6 * 2 total parameters assert num_torsions == 12 for i in range(num_torsions): p1, p2, p3, p4, params = custom_torsion_force.getTorsionParameters(i) # check which end state the parameters correspond to # if the 3 starting parameters are zero its fluoroethane else chloroethane if params[0] == 0.0 and params[1] == 0.0 and params[2] == 0.0: # fluoroethane f1 = mapping.componentA_to_componentB[p1] f2 = mapping.componentA_to_componentB[p2] f3 = mapping.componentA_to_componentB[p3] f4 = mapping.componentA_to_componentB[p4] fluoro_torsion = fluoro_labels["ProperTorsions"][(f1, f2, f3, f4)] # now we need to check which interaction this is if we have multiple periodicity's periodicity = params[3] term_index = fluoro_torsion.periodicity.index(periodicity) assert periodicity == fluoro_torsion.periodicity[term_index] assert params[4] == fluoro_torsion.phase[term_index].m_as(offunit.radian) assert params[5] == fluoro_torsion.k[term_index].m_as(offunit.kilojoule_per_mole) else: # chloroethane chloro_torsion = chloro_labels["ProperTorsions"][(p1, p2, p3, p4)] periodicity = params[0] term_index = chloro_torsion.periodicity.index(periodicity) assert periodicity == chloro_torsion.periodicity[term_index] assert params[1] == chloro_torsion.phase[term_index].m_as(offunit.radian) assert params[2] == chloro_torsion.k[term_index].m_as(offunit.kilojoule_per_mole) def test_torsion_force_dummy(htf_chloro_ethane): forces = htf_chloro_ethane["forces"] mapping = htf_chloro_ethane["mapping"] chloro_labels = htf_chloro_ethane["chloro_labels"] ethane_labels = htf_chloro_ethane["ethane_labels"] # there should be no interpolated torsion force terms # as those involving a dummy atom are held fixed # and in this example the fully mapped torsions have the same parameters custom_torsion_force = forces["CustomTorsionForce"] assert custom_torsion_force.getNumTorsions() == 0 # there should be a single global parameter for lambda assert custom_torsion_force.getNumGlobalParameters() == 1 # make sure it has the correct name assert custom_torsion_force.getGlobalParameterName(0) == "lambda_torsions" # 15 torsion terms in total in the standard periodic torsion force # chloroethane has 3 unique torsions with 2 phases = 6 # chloroethane and ethane have 6 shared single phase torsions = 6 # ethane has 3 unique torsions with a single phase = 3 standard_torsion_force = forces["PeriodicTorsionForce"] num_torsions = standard_torsion_force.getNumTorsions() assert num_torsions == 15 # now check the parameters are correctly assigned for i in range(num_torsions): p1, p2, p3, p4, periodicity, phase, k = standard_torsion_force.getTorsionParameters(i) # determine if this is chloroethane or ethane if p1 == 0: # unique chloroethane torsion chloro_torsion = chloro_labels["ProperTorsions"][(p1, p2, p3, p4)] assert periodicity in chloro_torsion.periodicity term_index = chloro_torsion.periodicity.index(periodicity) assert phase == chloro_torsion.phase[term_index].m_as(offunit.radian) * unit.radian assert ( k == chloro_torsion.k[term_index].m_as(offunit.kilojoule_per_mole) * unit.kilojoule_per_mole ) elif p1 == 8: # unique ethane torsion e1 = 0 e2 = mapping.componentA_to_componentB[p2] e3 = mapping.componentA_to_componentB[p3] e4 = mapping.componentA_to_componentB[p4] ethane_torsion = ethane_labels["ProperTorsions"][(e1, e2, e3, e4)] assert periodicity in ethane_torsion.periodicity term_index = ethane_torsion.periodicity.index(periodicity) assert phase == ethane_torsion.phase[term_index].m_as(offunit.radian) * unit.radian assert ( k == ethane_torsion.k[term_index].m_as(offunit.kilojoule_per_mole) * unit.kilojoule_per_mole ) else: # we have a mapped torsion so check the parameters are the same in both molecules chloro_torsion = chloro_labels["ProperTorsions"][(p1, p2, p3, p4)] f1 = mapping.componentA_to_componentB[p1] f2 = mapping.componentA_to_componentB[p2] f3 = mapping.componentA_to_componentB[p3] f4 = mapping.componentA_to_componentB[p4] ethane_torsion = ethane_labels["ProperTorsions"][(f1, f2, f3, f4)] assert periodicity in chloro_torsion.periodicity term_index = chloro_torsion.periodicity.index(periodicity) assert phase == chloro_torsion.phase[term_index].m_as(offunit.radian) * unit.radian assert ( k == chloro_torsion.k[term_index].m_as(offunit.kilojoule_per_mole) * unit.kilojoule_per_mole ) # check ethane parameters match assert periodicity in ethane_torsion.periodicity term_index = ethane_torsion.periodicity.index(periodicity) assert phase == ethane_torsion.phase[term_index].m_as(offunit.radian) * unit.radian assert ( k == ethane_torsion.k[term_index].m_as(offunit.kilojoule_per_mole) * unit.kilojoule_per_mole ) def test_nonbonded_force_no_dummy(htf_chloro_fluoroethane): """ Test the nonbonded particle parameters are correctly set when we have no dummy atoms. """ forces = htf_chloro_fluoroethane["forces"] chloro_labels = htf_chloro_fluoroethane["chloro_labels"] nonbonded_force = forces["NonbondedForce"] # there should be 4 global parameters used to scale the particle offsets assert nonbonded_force.getNumGlobalParameters() == 4 expected_global_params = { "lambda_electrostatics_core", "lambda_electrostatics_insert", "lambda_electrostatics_delete", "lambda_sterics_core", } actual_global_params = { nonbonded_force.getGlobalParameterName(i) for i in range(nonbonded_force.getNumGlobalParameters()) } assert actual_global_params == expected_global_params # as the particles are fully mapped we should have just 8 particles num_atoms = nonbonded_force.getNumParticles() assert num_atoms == 8 # check the input parameters match the chloroethane parameters chloro_charges = htf_chloro_fluoroethane["chloro_charges"] for i in range(num_atoms): charge, sigma, epsilon = nonbonded_force.getParticleParameters(i) chloro_vdw = chloro_labels["vdW"][(i,)] assert charge == chloro_charges[i] * unit.elementary_charge assert sigma == chloro_vdw.sigma.m_as(offunit.nanometer) * unit.nanometer # this is always zero as we use the softcore potential for the vdw assert epsilon == 0.0 * unit.kilojoule_per_mole def test_nonbonded_force_dummy(htf_chloro_ethane): """Test the nonbonded particle parameters are correctly set when we have dummy atoms.""" forces = htf_chloro_ethane["forces"] chloro_labels = htf_chloro_ethane["chloro_labels"] ethane_labels = htf_chloro_ethane["ethane_labels"] nonbonded_force = forces["NonbondedForce"] # there should be 4 global parameters used to scale the particle offsets assert nonbonded_force.getNumGlobalParameters() == 4 expected_global_params = { "lambda_electrostatics_core", "lambda_electrostatics_insert", "lambda_electrostatics_delete", "lambda_sterics_core", } actual_global_params = { nonbonded_force.getGlobalParameterName(i) for i in range(nonbonded_force.getNumGlobalParameters()) } assert actual_global_params == expected_global_params # as we have a single unique atom at each end state there should be 9 particles num_atoms = nonbonded_force.getNumParticles() assert num_atoms == 9 # check the input parameters match the chloroethane parameters for the mapped atoms chloro_charges = htf_chloro_ethane["chloro_charges"] for i in range(num_atoms): charge, sigma, epsilon = nonbonded_force.getParticleParameters(i) if i == 0: # unique chloro atom chloro_vdw = chloro_labels["vdW"][(i,)] assert charge == chloro_charges[i] * unit.elementary_charge assert sigma == chloro_vdw.sigma.m_as(offunit.nanometer) * unit.nanometer # we use soft core for vdW so epsilon is zero assert epsilon == 0.0 * unit.kilojoule_per_mole elif i == 8: # unique ethane hydrogen atom e1 = 0 ethane_vdw = ethane_labels["vdW"][(e1,)] assert ( charge == 0.0 * unit.elementary_charge ) # this should be zero and be scaled to the ethane value via particle offsets assert sigma == ethane_vdw.sigma.m_as(offunit.nanometer) * unit.nanometer # we use soft core for vdW so epsilon is zero assert epsilon == 0.0 * unit.kilojoule_per_mole else: # mapped atoms should use the chloroethane parameters # they will be adjusted using particle offsets chloro_vdw = chloro_labels["vdW"][(i,)] assert charge == chloro_charges[i] * unit.elementary_charge assert sigma == chloro_vdw.sigma.m_as(offunit.nanometer) * unit.nanometer # we use soft core for vdW so epsilon is zero assert epsilon == 0.0 * unit.kilojoule_per_mole def test_nonbonded_offsets_no_dummy(htf_chloro_fluoroethane): """Test that the nonbonded particle parameter offsets are correctly set when we have no dummy atoms.""" forces = htf_chloro_fluoroethane["forces"] mapping = htf_chloro_fluoroethane["mapping"] nonbonded_force = forces["NonbondedForce"] # get the charges chloro_charges = htf_chloro_fluoroethane["chloro_charges"] fluoro_charges = htf_chloro_fluoroethane["fluoro_charges"] # We scale the nonbonded electrostatics with lambda so check the offsets # there should be 8 offsets one for each particle num_offsets = nonbonded_force.getNumParticleParameterOffsets() assert num_offsets == 8 for i in range(num_offsets): offset_params = nonbonded_force.getParticleParameterOffset(i) assert ( offset_params[0] == "lambda_electrostatics_core" ) # Make sure only the electrostatics core lambda is used particle_index = offset_params[1] # make sure the epsilon and sigma scales are zero assert offset_params[3] == offset_params[4] == 0.0 # calculate the scale for this particle index f1 = mapping.componentA_to_componentB[particle_index] charge_scale = fluoro_charges[f1] - chloro_charges[particle_index] # check the offset value matches assert offset_params[2] == charge_scale def test_nonbonded_offsets_dummy(htf_chloro_ethane): forces = htf_chloro_ethane["forces"] mapping = htf_chloro_ethane["mapping"] nonbonded_force = forces["NonbondedForce"] # there should be 9 offsets one for each particle num_offsets = nonbonded_force.getNumParticleParameterOffsets() assert num_offsets == 9 chloro_charges = htf_chloro_ethane["chloro_charges"] ethane_charges = htf_chloro_ethane["ethane_charges"] for i in range(num_offsets): offset_params = nonbonded_force.getParticleParameterOffset(i) particle_index = offset_params[1] # make sure the epsilon and sigma scales are zero assert offset_params[3] == offset_params[4] == 0.0 # calculate the scale for this particle index if particle_index == 0: # unique chloro atom # make sure this particle is removed at lambda = 1 assert offset_params[0] == "lambda_electrostatics_delete" charge_scale = 0.0 - chloro_charges[particle_index] elif particle_index == 8: # unique ethane hydrogen atom # make sure this particle is inserted at lambda = 1 assert offset_params[0] == "lambda_electrostatics_insert" e1 = 0 charge_scale = ethane_charges[e1] - 0.0 else: # mapped atoms # make sure the charge is scaled with the electrostatics core lambda assert offset_params[0] == "lambda_electrostatics_core" f1 = mapping.componentA_to_componentB[particle_index] charge_scale = ethane_charges[f1] - chloro_charges[particle_index] # check the offset value matches assert offset_params[2] == charge_scale def test_nonbonded_exceptions_no_dummy(htf_chloro_fluoroethane): """Test that the nonbonded exceptions are correctly set when we have no dummy atoms.""" forces = htf_chloro_fluoroethane["forces"] chloroethane = htf_chloro_fluoroethane["chloroethane"] chloro_openff = chloroethane.to_openff() chloro_labels = htf_chloro_fluoroethane["chloro_labels"] chloro_charges = htf_chloro_fluoroethane["chloro_charges"] electro_scale = htf_chloro_fluoroethane["electrostatic_scale"] vdw_scale = htf_chloro_fluoroethane["vdW_scale"] nonbonded_force = forces["NonbondedForce"] num_exceptions = nonbonded_force.getNumExceptions() # there should be 28 in total (8 * 7) / 2 assert num_exceptions == 28 # there should 9 non-zero exceptions corresponding to the 9 proper torsions exception_1_4s = [] # get all atoms with a minimal path of 3 bonds between them for pair_1_4 in chloro_openff.nth_degree_neighbors(3): a1 = chloro_openff.atoms.index(pair_1_4[0]) a2 = chloro_openff.atoms.index(pair_1_4[1]) exception_1_4s.append((a1, a2)) assert len(exception_1_4s) == 9 non_zero_exceptions = 0 # now check the parameters are correctly assigned for i in range(num_exceptions): p1, p2, charge_prod, sigma, epsilon = nonbonded_force.getExceptionParameters(i) # check if this is a 1-4 interaction, should use the chloroethane parameters if (p1, p2) in exception_1_4s or (p2, p1) in exception_1_4s: charge1 = chloro_charges[p1] charge2 = chloro_charges[p2] expected_charge_prod = ( charge1 * charge2 * electro_scale ) # get the scaled charge product chloro_vdw1 = chloro_labels["vdW"][(p1,)] chloro_vdw2 = chloro_labels["vdW"][(p2,)] # Lorentz-Berthelot combining rules expected_sigma = (chloro_vdw1.sigma + chloro_vdw2.sigma) / 2.0 expected_epsilon = ( (chloro_vdw1.epsilon * chloro_vdw2.epsilon) ** 0.5 ) * vdw_scale # scaled epsilon by the 1-4 scale for the ff assert expected_charge_prod == pytest.approx( charge_prod.value_in_unit(unit.elementary_charge**2), rel=1e-5 ) # charge product assert sigma == expected_sigma.m_as(offunit.nanometer) * unit.nanometer # sigma assert expected_epsilon.m_as(offunit.kilojoule_per_mole) == pytest.approx( epsilon.value_in_unit(unit.kilojoule_per_mole), rel=1e-5 ) # epsilon # track how many non-zero exceptions we have found non_zero_exceptions += 1 # not a 1-4 so this should be set to zero else: assert charge_prod == 0.0 * unit.elementary_charge**2 # charge product assert sigma == 1.0 * unit.nanometer # sigma, dummy value of 1 used assert epsilon == 0.0 * unit.kilojoule_per_mole # epsilon, should always be zero assert non_zero_exceptions == 9 def test_nonbonded_exceptions_dummy(htf_chloro_ethane): """Test that the nonbonded exceptions are correctly set when we have dummy atoms, any involving a dummy should be zeroed.""" forces = htf_chloro_ethane["forces"] chloroethane = htf_chloro_ethane["chloroethane"] chloro_labels = htf_chloro_ethane["chloro_labels"] chloro_charges = htf_chloro_ethane["chloro_charges"] chloro_openff = chloroethane.to_openff() electro_scale = htf_chloro_ethane["electrostatic_scale"] vdw_scale = htf_chloro_ethane["vdW_scale"] nonbonded_force = forces["NonbondedForce"] num_exceptions = nonbonded_force.getNumExceptions() # there should be 36 in total (9 * 8) / 2 assert num_exceptions == 36 # get the expected exception atoms exception_1_4s = [] # get all atoms with a minimal path of 3 bonds between them for pair_1_4 in chloro_openff.nth_degree_neighbors(3): a1 = chloro_openff.atoms.index(pair_1_4[0]) a2 = chloro_openff.atoms.index(pair_1_4[1]) exception_1_4s.append((a1, a2)) assert len(exception_1_4s) == 9 # manually add the 1-4s involving the unique ethane hydrogen atom (atom 8) for i in [5, 6, 7]: exception_1_4s.append((8, i)) # there should 6 non-zero exceptions corresponding to the 6 mapped proper torsions not involving a dummy atom non_zero_exceptions = 0 # there should be 6 zeroed exceptions corresponding to those involving a dummy atom zeroed_dummy_exceptions = 0 # now check the parameters are correctly assigned for i in range(num_exceptions): p1, p2, charge_prod, sigma, epsilon = nonbonded_force.getExceptionParameters(i) # check if this is a 1-4 interaction if (p1, p2) in exception_1_4s or (p2, p1) in exception_1_4s: if p1 == 0 or p2 == 0 or p1 == 8 or p2 == 8: # this is a dummy atom exception which should be interpolated in the custom steric bond force # make sure the parameters are set to zero assert ( charge_prod == 0.0 * unit.elementary_charge**2 ) # charge product should always be zero assert epsilon == 0.0 * unit.kilojoule_per_mole # epsilon, should always be zero # sigma will use a dummy value this is not important as epsilon is 0.0 zeroed_dummy_exceptions += 1 else: # this is a mapped exception so check the parameters match chloroethane charge1 = chloro_charges[p1] charge2 = chloro_charges[p2] expected_charge_prod = ( charge1 * charge2 * electro_scale ) # get the scaled charge product chloro_vdw1 = chloro_labels["vdW"][(p1,)] chloro_vdw2 = chloro_labels["vdW"][(p2,)] # Lorentz-Berthelot combining rules expected_sigma = (chloro_vdw1.sigma + chloro_vdw2.sigma) / 2.0 expected_epsilon = ( (chloro_vdw1.epsilon * chloro_vdw2.epsilon) ** 0.5 ) * vdw_scale # scaled epsilon by the 1-4 scale for the ff assert expected_charge_prod == pytest.approx( charge_prod.value_in_unit(unit.elementary_charge**2), rel=1e-5 ) # charge product assert sigma == expected_sigma.m_as(offunit.nanometer) * unit.nanometer # sigma assert expected_epsilon.m_as(offunit.kilojoule_per_mole) == pytest.approx( epsilon.value_in_unit(unit.kilojoule_per_mole), rel=1e-5 ) # epsilon # track how many non-zero exceptions we have found non_zero_exceptions += 1 # not a 1-4 so this should be set to zero else: assert ( charge_prod == 0.0 * unit.elementary_charge**2 ) # charge product should always be zero assert sigma == 1.0 * unit.nanometer # sigma, dummy value of 1 used assert epsilon == 0.0 * unit.kilojoule_per_mole # epsilon, should always be zero assert non_zero_exceptions == 6 assert zeroed_dummy_exceptions == 6 def test_nonbonded_exception_offsets_no_dummy(htf_chloro_fluoroethane): """Test that the nonbonded exception parameter offsets are correctly set when we have no dummy atoms and interpolate between the end state values.""" forces = htf_chloro_fluoroethane["forces"] mapping = htf_chloro_fluoroethane["mapping"] chloroethane = htf_chloro_fluoroethane["chloroethane"] chloro_openff = chloroethane.to_openff() chloro_labels = htf_chloro_fluoroethane["chloro_labels"] fluoro_labels = htf_chloro_fluoroethane["fluoro_labels"] chloro_charges = htf_chloro_fluoroethane["chloro_charges"] fluoro_charges = htf_chloro_fluoroethane["fluoro_charges"] electro_scale = htf_chloro_fluoroethane["electrostatic_scale"] vdw_scale = htf_chloro_fluoroethane["vdW_scale"] nonbonded_force = forces["NonbondedForce"] # there should be 56 exception offsets 2 for each of the 28 exceptions to allow for electrostatics and vdw scaling num_offsets = nonbonded_force.getNumExceptionParameterOffsets() assert num_offsets == 56 # get the expected exception atoms exception_1_4s = [] # get all atoms with a minimal path of 3 bonds between them for pair_1_4 in chloro_openff.nth_degree_neighbors(3): a1 = chloro_openff.atoms.index(pair_1_4[0]) a2 = chloro_openff.atoms.index(pair_1_4[1]) exception_1_4s.append((a1, a2)) # Only 12 of the offsets should be non-zero corresponding to the 1-4 interactions # 9 from electrostatics # 3 from sterics (3 torsions with Cl/F as all hydrogen vdW remain the same) non_zero_offsets = 0 for i in range(num_offsets): parameter, exception_index, charge_prod_scale, sigma_scale, epsilon_scale = ( nonbonded_force.getExceptionParameterOffset(i) ) # get the index of the particles in the exception p1, p2, _, _, _ = nonbonded_force.getExceptionParameters(exception_index) # if this is not an expected exception it should not be scaled if (p1, p2) not in exception_1_4s and (p2, p1) not in exception_1_4s: # should be zero assert charge_prod_scale == 0.0 assert sigma_scale == 0.0 assert epsilon_scale == 0.0 else: # now check the parameters are correct if parameter == "lambda_electrostatics_core": # track how many we have found if charge_prod_scale != 0.0: non_zero_offsets += 1 # electrostatics offset chloro_charge1 = chloro_charges[p1] chloro_charge2 = chloro_charges[p2] f1 = mapping.componentA_to_componentB[p1] f2 = mapping.componentA_to_componentB[p2] fluoro_charge1 = fluoro_charges[f1] fluoro_charge2 = fluoro_charges[f2] # must use the 1-4 scale factor defined in the force field expected_scale = ( (fluoro_charge1 * fluoro_charge2) - (chloro_charge1 * chloro_charge2) ) * electro_scale assert expected_scale == pytest.approx(charge_prod_scale, rel=1e-5) # sigma and epsilon should be zero assert sigma_scale == 0.0 assert epsilon_scale == 0.0 elif parameter == "lambda_sterics_core": if sigma_scale != 0.0 or epsilon_scale != 0.0: non_zero_offsets += 1 # sterics offset chloro_vdw1 = chloro_labels["vdW"][(p1,)] chloro_vdw2 = chloro_labels["vdW"][(p2,)] f1 = mapping.componentA_to_componentB[p1] f2 = mapping.componentA_to_componentB[p2] fluoro_vdw1 = fluoro_labels["vdW"][(f1,)] fluoro_vdw2 = fluoro_labels["vdW"][(f2,)] # calculate the LJ parameters using Lorentz-Berthelot mixing chloro_sigma = (chloro_vdw1.sigma + chloro_vdw2.sigma) / 2.0 chloro_epsilon = (chloro_vdw1.epsilon * chloro_vdw2.epsilon) ** 0.5 fluoro_sigma = (fluoro_vdw1.sigma + fluoro_vdw2.sigma) / 2.0 fluoro_epsilon = (fluoro_vdw1.epsilon * fluoro_vdw2.epsilon) ** 0.5 # now get the scales expected_sigma_scale = fluoro_sigma.m_as(offunit.nanometer) - chloro_sigma.m_as( offunit.nanometer ) # must use the 1-4 scale factor defined in the force field expected_epsilon_scale = ( fluoro_epsilon.m_as(offunit.kilojoule_per_mole) - chloro_epsilon.m_as(offunit.kilojoule_per_mole) ) * vdw_scale assert sigma_scale == expected_sigma_scale assert expected_epsilon_scale == pytest.approx(epsilon_scale, rel=1e-5) # make sure we found all non-zero offsets assert non_zero_offsets == 12 def test_nonbonded_exception_offsets_dummy(htf_chloro_ethane): """Test that the nonbonded exception parameter offsets are correctly set when we have dummy atoms. All values should be zero if involving a dummy atom.""" forces = htf_chloro_ethane["forces"] chloroethane = htf_chloro_ethane["chloroethane"] chloro_labels = htf_chloro_ethane["chloro_labels"] chloro_charges = htf_chloro_ethane["chloro_charges"] chloro_openff = chloroethane.to_openff() ethane_labels = htf_chloro_ethane["ethane_labels"] ethane_charges = htf_chloro_ethane["ethane_charges"] mapping = htf_chloro_ethane["mapping"] electro_scale = htf_chloro_ethane["electrostatic_scale"] vdw_scale = htf_chloro_ethane["vdW_scale"] nonbonded_force = forces["NonbondedForce"] # there are 36 exceptions so 72 offsets (2 lambda per exception) # but the htf removes all offsets involving dummy atoms from the nonbonded force # so we remove 2 * 7 offsets involving the unique chloro atom in chloroethane # and 2 * 7 offsets involving the unique hydrogen atom in ethane # and finally we remove 2 * 2 offsets involving the unique chloro and unique hydrogen atoms num_offsets = nonbonded_force.getNumExceptionParameterOffsets() assert num_offsets == 42 # get the expected exception atoms exception_1_4s = [] # get all atoms with a minimal path of 3 bonds between them # not involving the dummy atoms for pair_1_4 in chloro_openff.nth_degree_neighbors(3): a1 = chloro_openff.atoms.index(pair_1_4[0]) a2 = chloro_openff.atoms.index(pair_1_4[1]) if a1 != 0 and a2 != 0: exception_1_4s.append((a1, a2)) # we expect only 12 offsets to be non-zero corresponding to the 6 mapped 1-4 interactions # each with electrostatics and sterics offsets non_zero_offsets = 0 for i in range(num_offsets): parameter, exception_index, charge_prod_scale, sigma_scale, epsilon_scale = ( nonbonded_force.getExceptionParameterOffset(i) ) # get the index of the particles in the exception p1, p2, _, _, _ = nonbonded_force.getExceptionParameters(exception_index) # if this is not an expected exception it should not be scaled if (p1, p2) not in exception_1_4s and (p2, p1) not in exception_1_4s: # should be zero assert charge_prod_scale == 0.0 assert sigma_scale == 0.0 assert epsilon_scale == 0.0 else: # now check the parameters are correct if parameter == "lambda_electrostatics_core": # track how many we have found if charge_prod_scale != 0.0: non_zero_offsets += 1 # electrostatics offset chloro_charge1 = chloro_charges[p1] chloro_charge2 = chloro_charges[p2] e1 = mapping.componentA_to_componentB[p1] e2 = mapping.componentA_to_componentB[p2] ethane_charge1 = ethane_charges[e1] ethane_charge2 = ethane_charges[e2] # must use the 1-4 scale factor defined in the force field expected_scale = ( (ethane_charge1 * ethane_charge2) - (chloro_charge1 * chloro_charge2) ) * electro_scale # we see some rounding issues here so use approx assert expected_scale == pytest.approx(charge_prod_scale, rel=1e-5) # sigma and epsilon should be zero assert sigma_scale == 0.0 assert epsilon_scale == 0.0 elif parameter == "lambda_sterics_core": if sigma_scale != 0.0 or epsilon_scale != 0.0: non_zero_offsets += 1 # sterics offset chloro_vdw1 = chloro_labels["vdW"][(p1,)] chloro_vdw2 = chloro_labels["vdW"][(p2,)] e1 = mapping.componentA_to_componentB[p1] e2 = mapping.componentA_to_componentB[p2] ethane_vdw1 = ethane_labels["vdW"][(e1,)] ethane_vdw2 = ethane_labels["vdW"][(e2,)] # calculate the LJ parameters using Lorentz-Berthelot mixing chloro_sigma = (chloro_vdw1.sigma + chloro_vdw2.sigma) / 2.0 chloro_epsilon = (chloro_vdw1.epsilon * chloro_vdw2.epsilon) ** 0.5 ethane_sigma = (ethane_vdw1.sigma + ethane_vdw2.sigma) / 2.0 ethane_epsilon = (ethane_vdw1.epsilon * ethane_vdw2.epsilon) ** 0.5 # now get the scales expected_sigma_scale = ethane_sigma.m_as(offunit.nanometer) - chloro_sigma.m_as( offunit.nanometer ) # must use the 1-4 scale factor defined in the force field expected_epsilon_scale = ( ethane_epsilon.m_as(offunit.kilojoule_per_mole) - chloro_epsilon.m_as(offunit.kilojoule_per_mole) ) * vdw_scale assert sigma_scale == expected_sigma_scale assert epsilon_scale == expected_epsilon_scale # make sure we found all non-zero offsets assert non_zero_offsets == 12 def test_custom_nb_force_no_dummy(htf_chloro_fluoroethane): """ Test the custom nonbonded force is correctly setup when we have no dummy atoms. This test implicitly checks that the global parameters are in the correct order. """ forces = htf_chloro_fluoroethane["forces"] mapping = htf_chloro_fluoroethane["mapping"] chloro_labels = htf_chloro_fluoroethane["chloro_labels"] fluoro_labels = htf_chloro_fluoroethane["fluoro_labels"] custom_nb_force = forces["CustomNonbondedForce"] # there should be 5 global parameters used to scale the particle parameters assert custom_nb_force.getNumGlobalParameters() == 5 expected_global_params = { "lambda_sterics_core", "lambda_sterics_insert", "lambda_sterics_delete", "lambda_electrostatics_core", "softcore_alpha", } actual_global_params = { custom_nb_force.getGlobalParameterName(i) for i in range(custom_nb_force.getNumGlobalParameters()) } assert actual_global_params == expected_global_params # there should be 8 particles as all atoms are mapped num_particles = custom_nb_force.getNumParticles() assert num_particles == 8 # now check the parameters are correctly assigned for i in range(num_particles): params = custom_nb_force.getParticleParameters(i) # check the chloroethane parameters chloro_vdw = chloro_labels["vdW"][(i,)] assert params[0] == chloro_vdw.sigma.m_as(offunit.nanometer) assert params[1] == chloro_vdw.epsilon.m_as(offunit.kilojoule_per_mole) # map to fluoroethane f1 = mapping.componentA_to_componentB[i] fluoro_vdw = fluoro_labels["vdW"][(f1,)] assert params[2] == fluoro_vdw.sigma.m_as(offunit.nanometer) assert params[3] == fluoro_vdw.epsilon.m_as(offunit.kilojoule_per_mole) # as we have no unique parameters both unique_old and unque_new should be zero assert params[4] == 0.0 assert params[5] == 0.0 def test_custom_nb_force_dummy(htf_chloro_ethane): forces = htf_chloro_ethane["forces"] mapping = htf_chloro_ethane["mapping"] chloro_labels = htf_chloro_ethane["chloro_labels"] ethane_labels = htf_chloro_ethane["ethane_labels"] custom_nb_force = forces["CustomNonbondedForce"] # there should be 5 global parameters used to scale the particle parameters assert custom_nb_force.getNumGlobalParameters() == 5 expected_global_params = { "lambda_sterics_core", "lambda_sterics_insert", "lambda_sterics_delete", "lambda_electrostatics_core", "softcore_alpha", } actual_global_params = { custom_nb_force.getGlobalParameterName(i) for i in range(custom_nb_force.getNumGlobalParameters()) } assert actual_global_params == expected_global_params # there should be 9 particles as we have 1 unique atom in each end state num_particles = custom_nb_force.getNumParticles() assert num_particles == 9 # now check the parameters are correctly assigned for i in range(num_particles): params = custom_nb_force.getParticleParameters(i) if i == 0: # unique chloro atom chloro_vdw = chloro_labels["vdW"][(i,)] # lambda=0 parameters should be chloroethane values assert params[0] == chloro_vdw.sigma.m_as(offunit.nanometer) assert params[1] == chloro_vdw.epsilon.m_as(offunit.kilojoule_per_mole) # lambda=0 parameters should be zeroed dummy atom values assert params[2] == chloro_vdw.sigma.m_as(offunit.nanometer) assert params[3] == 0.0 # check we correctly assign the unique_old and unique_new parameters assert params[4] == 1 # unique_old should be true assert params[5] == 0 # unique_new should be false elif i == 8: # unique ethane hydrogen atom ethane_vdw = ethane_labels["vdW"][(0,)] # lambda=0 parameters should be zeroed dummy atom values assert params[0] == ethane_vdw.sigma.m_as(offunit.nanometer) assert params[1] == 0.0 # epsilon is zero for dummy atoms # lambda=1 parameters should be ethane values assert params[2] == ethane_vdw.sigma.m_as(offunit.nanometer) assert params[3] == ethane_vdw.epsilon.m_as(offunit.kilojoule_per_mole) # check we correctly assign the unique_old and unique_new parameters assert params[4] == 0 # unique_old should be false assert params[5] == 1 # unique_new should be true else: # mapped atoms should use the chloro at lambda=0 and ethane at lambda=1 chloro_vdw = chloro_labels["vdW"][(i,)] assert params[0] == chloro_vdw.sigma.m_as(offunit.nanometer) assert params[1] == chloro_vdw.epsilon.m_as(offunit.kilojoule_per_mole) e1 = mapping.componentA_to_componentB[i] ethane_vdw = ethane_labels["vdW"][(e1,)] assert params[2] == ethane_vdw.sigma.m_as(offunit.nanometer) assert params[3] == ethane_vdw.epsilon.m_as(offunit.kilojoule_per_mole) # as we have no unique parameters both unique_old and unique_new should be zero assert params[4] == 0 assert params[5] == 0 def test_custom_nb_exclusions_no_dummy(htf_chloro_fluoroethane): """ Test that the expected exclusions are correctly assigned when we have no dummy atoms. This should only be the standard exclusions. """ forces = htf_chloro_fluoroethane["forces"] custom_nb_force = forces["CustomNonbondedForce"] num_exclusions = custom_nb_force.getNumExclusions() # there should be 28 in total (8 * 7) / 2 assert num_exclusions == 28 # now check the exclusions are correctly assigned exclusion_set = set() for i in range(num_exclusions): p1, p2 = custom_nb_force.getExclusionParticles(i) exclusion_set.add((p1, p2)) # check we have all expected exclusions for a1 in range(8): for a2 in range(a1 + 1, 8): assert (a1, a2) in exclusion_set def test_custom_nb_exclusions_dummy(htf_chloro_ethane): """ Test that all exclusions are correctly assigned when we have dummy atoms, this should involve an exclusion between the two dummy atoms 0-8. """ forces = htf_chloro_ethane["forces"] custom_nb_force = forces["CustomNonbondedForce"] num_exclusions = custom_nb_force.getNumExclusions() # there should be 36 in total (9 * 8) / 2 assert num_exclusions == 36 # now check the exclusions are correctly assigned exclusion_set = set() for i in range(num_exclusions): p1, p2 = custom_nb_force.getExclusionParticles(i) exclusion_set.add((p1, p2)) # due to the way we add the exclusions for the unique_new atoms we need to add the reverse too exclusion_set.add((p2, p1)) # check we have all expected exclusions for a1 in range(9): for a2 in range(a1 + 1, 9): assert (a1, a2) in exclusion_set def test_custom_nb_interation_groups_no_dummy(htf_chloro_fluoroethane): """ Test the interaction groups are correctly assigned when we have no dummy atoms. """ forces = htf_chloro_fluoroethane["forces"] custom_nb_force = forces["CustomNonbondedForce"] num_groups = custom_nb_force.getNumInteractionGroups() # we should always have 8 groups assert num_groups == 8 # now check the groups are correctly assigned particle_set = set(range(8)) expected_groups = [ (set(), particle_set), # unique_old, core (set(), set()), # unique_old, env (set(), particle_set), # unique_new, core (set(), set()), # unique_new, env (particle_set, set()), # core, env (particle_set, particle_set), # core, core (set(), set()), # unique_new, unique_new (set(), set()), # unique_old, unique_old ] for i in range(num_groups): group1, group2 = custom_nb_force.getInteractionGroupParameters(i) expected_g1, expected_g2 = expected_groups[i] assert set(group1) == expected_g1 assert set(group2) == expected_g2 def test_custom_nb_interation_groups_dummy(htf_chloro_ethane): """ Make sure the interaction groups are correctly assigned when we have dummy atoms. The unique_old and unique_new atoms should be split to not interact. """ forces = htf_chloro_ethane["forces"] custom_nb_force = forces["CustomNonbondedForce"] num_groups = custom_nb_force.getNumInteractionGroups() # we should always have 8 groups assert num_groups == 8 # now check the groups are correctly assigned core_set = set(range(1, 8)) unique_old_set = {0} unique_new_set = {8} expected_groups = [ (unique_old_set, core_set), # unique_old, core (unique_old_set, set()), # unique_old, env (unique_new_set, core_set), # unique_new, core (unique_new_set, set()), # unique_new, env (core_set, set()), # core, env (core_set, core_set), # core, core (unique_new_set, unique_new_set), # unique_new, unique_new (unique_old_set, unique_old_set), # unique_old, unique_old ] for i in range(num_groups): group1, group2 = custom_nb_force.getInteractionGroupParameters(i) expected_g1, expected_g2 = expected_groups[i] assert set(group1) == expected_g1 assert set(group2) == expected_g2 def test_custom_sterics_force_no_dummy(htf_chloro_fluoroethane): """ Make sure there are no bonds in the custom sterics force when we have no dummy atoms. """ forces = htf_chloro_fluoroethane["forces"] custom_sterics_force = forces["CustomBondForce_exceptions"] # there should be 5 global parameters used to scale the particle parameters assert custom_sterics_force.getNumGlobalParameters() == 5 expected_global_params = { "lambda_sterics_insert", "lambda_sterics_delete", "lambda_electrostatics_insert", "lambda_electrostatics_delete", "softcore_alpha", } actual_global_params = { custom_sterics_force.getGlobalParameterName(i) for i in range(custom_sterics_force.getNumGlobalParameters()) } assert actual_global_params == expected_global_params # we should have no parameters in this force as there are no dummy atoms assert custom_sterics_force.getNumBonds() == 0 def test_custom_sterics_force_dummy(htf_chloro_ethane): """ The custom sterics force should contain only 1-4 interactions involving dummy atoms make sure they are correctly interpolated. """ forces = htf_chloro_ethane["forces"] mapping = htf_chloro_ethane["mapping"] chloroethane = htf_chloro_ethane["chloroethane"] chloro_charges = htf_chloro_ethane["chloro_charges"] chloro_labels = htf_chloro_ethane["chloro_labels"] ethane_charges = htf_chloro_ethane["ethane_charges"] ethane_labels = htf_chloro_ethane["ethane_labels"] chloro_openff = chloroethane.to_openff() electro_scale = htf_chloro_ethane["electrostatic_scale"] vdw_scale = htf_chloro_ethane["vdW_scale"] custom_sterics_force = forces["CustomBondForce_exceptions"] # there should be 5 global parameters used to scale the particle parameters assert custom_sterics_force.getNumGlobalParameters() == 5 expected_global_params = { "lambda_sterics_insert", "lambda_sterics_delete", "lambda_electrostatics_insert", "lambda_electrostatics_delete", "softcore_alpha", } actual_global_params = { custom_sterics_force.getGlobalParameterName(i) for i in range(custom_sterics_force.getNumGlobalParameters()) } assert actual_global_params == expected_global_params num_bonds = custom_sterics_force.getNumBonds() # there should be 6 bonds corresponding to the 1-4s involving a dummy atom # 3 involving the unique chloro atom to be interpolated out # 3 involving the unique ethane hydrogen atom to be interpolated in assert num_bonds == 6 # now check the bonds are correctly assigned expected_bonds = [] # get all atoms with a minimal path of 3 bonds between them for pair_1_4 in chloro_openff.nth_degree_neighbors(3): a1 = chloro_openff.atoms.index(pair_1_4[0]) a2 = chloro_openff.atoms.index(pair_1_4[1]) if a1 == 0 or a2 == 0: expected_bonds.append((a1, a2)) # manually add the 1-4s involving the unique ethane hydrogen atom (atom 8) for i in [5, 6, 7]: expected_bonds.append((8, i)) for i in range(num_bonds): p1, p2, params = custom_sterics_force.getBondParameters(i) # all parameters here should be 1-4 involving a dummy atom only assert (p1, p2) in expected_bonds or (p2, p1) in expected_bonds # now check the parameters are correct if p1 == 0 or p2 == 0: # unique chloro atom being removed charge1 = chloro_charges[p1] charge2 = chloro_charges[p2] # check the charge product at lambda=0 assert charge1 * charge2 * electro_scale == pytest.approx(params[0], rel=1e-5) # this is scaled by the unique flags make sure unique_old is 1 and unique_new is 0 assert params[5] == 1 # unique_old assert params[6] == 0 # unique_new # now check the vdw parameters at lambda=0 chloro_vdw1 = chloro_labels["vdW"][(p1,)] chloro_vdw2 = chloro_labels["vdW"][(p2,)] expected_sigma = (chloro_vdw1.sigma + chloro_vdw2.sigma) / 2.0 expected_epsilon = ((chloro_vdw1.epsilon * chloro_vdw2.epsilon) ** 0.5) * vdw_scale assert params[1] == expected_sigma.m_as(offunit.nanometer) assert expected_epsilon.m_as(offunit.kilojoule_per_mole) == pytest.approx( params[2], rel=1e-5 ) # check the vdw go to zero at lambda=1 assert params[4] == 0.0 # epsilon at lambda=1 # sigma doesn't matter if epsilon is zero elif p1 == 8 or p2 == 8: # unique ethane hydrogen atom being inserted e1 = 0 if p1 == 8 else mapping.componentA_to_componentB[p1] e2 = 0 if p2 == 8 else mapping.componentA_to_componentB[p2] ethane_charge1 = ethane_charges[e1] ethane_charge2 = ethane_charges[e2] # check the charge product at lambda=1 assert ethane_charge1 * ethane_charge2 * electro_scale == pytest.approx( params[0], rel=1e-5 ) # this is scaled by the unique flags make sure unique_old is 0 and unique_new is 1 assert params[5] == 0 # unique_old assert params[6] == 1 # unique_new # now check the vdw parameters at lambda=1 ethane_vdw1 = ethane_labels["vdW"][(e1,)] ethane_vdw2 = ethane_labels["vdW"][(e2,)] expected_sigma = (ethane_vdw1.sigma + ethane_vdw2.sigma) / 2.0 expected_epsilon = ((ethane_vdw1.epsilon * ethane_vdw2.epsilon) ** 0.5) * vdw_scale assert params[3] == expected_sigma.m_as(offunit.nanometer) assert expected_epsilon.m_as(offunit.kilojoule_per_mole) == pytest.approx( params[4], rel=1e-5 ) # check the vdw are zero at lambda=0 assert params[2] == 0.0 # epsilon at lambda=0 def test_vacuum_system_energy_no_dummy(htf_chloro_fluoroethane): """ Test that the hybrid system energy is the same at lambda=0 and lambda=1 as the pure systems. All individual force components should match as there are no dummy atoms. """ integrator = openmm.LangevinIntegrator( 300 * unit.kelvin, 1.0 / unit.picosecond, 0.002 * unit.picoseconds ) platform = openmm.Platform.getPlatformByName("CPU") default_lambda = _rfe_utils.lambdaprotocol.LambdaProtocol() htf = htf_chloro_fluoroethane["htf"] hybrid_system = htf.hybrid_system # set the nonbonded method to NoCutoff to avoid any cutoff issues for force in hybrid_system.getForces(): if isinstance(force, openmm.NonbondedForce): force.setNonbondedMethod(openmm.NonbondedForce.NoCutoff) if isinstance(force, openmm.CustomNonbondedForce): force.setNonbondedMethod(openmm.CustomNonbondedForce.NoCutoff) hybrid_simulation = app.Simulation( topology=htf.omm_hybrid_topology, system=hybrid_system, integrator=integrator, platform=platform, ) for end_state, ref_system, ref_top, pos in [ (0, htf._old_system, htf._old_topology, htf._old_positions), (1, htf._new_system, htf._new_topology, htf._new_positions), ]: for force in ref_system.getForces(): if isinstance(force, openmm.NonbondedForce): force.setNonbondedMethod(openmm.NonbondedForce.NoCutoff) # set lambda # set all lambda values to the current end state for name, func in default_lambda.functions.items(): val = func(end_state) hybrid_simulation.context.setParameter(name, val) # set positions hybrid_simulation.context.setPositions(pos) # get the hybrid system energy hybrid_state = hybrid_simulation.context.getState(getEnergy=True) hybrid_energy = hybrid_state.getPotentialEnergy().value_in_unit(unit.kilojoule_per_mole) # now create a reference simulation ref_simulation = app.Simulation( topology=ref_top, system=ref_system, integrator=copy.deepcopy(integrator), platform=platform, ) ref_simulation.context.setPositions(pos) ref_state = ref_simulation.context.getState(getEnergy=True) ref_energy = ref_state.getPotentialEnergy().value_in_unit(unit.kilojoule_per_mole) # energies should be the same assert ref_energy == pytest.approx(hybrid_energy, rel=1e-5) # check the energy is non-zero to avoid false positives assert 0.0 != pytest.approx(hybrid_energy) def test_vacuum_system_energy_dummy(htf_chloro_ethane): """ Test that the hybrid system nonbonded energy is the same at lambda=0 and lambda=1 as the pure systems. All individual force components will not match due to the presence of dummy atoms, only the total nonbonded energy should be the same. """ integrator = openmm.LangevinIntegrator( 300 * unit.kelvin, 1.0 / unit.picosecond, 0.002 * unit.picoseconds ) platform = openmm.Platform.getPlatformByName("CPU") default_lambda = _rfe_utils.lambdaprotocol.LambdaProtocol() htf = htf_chloro_ethane["htf"] hybrid_system = htf.hybrid_system # # set the nonbonded method to NoCutoff to avoid any cutoff issues for force in hybrid_system.getForces(): if isinstance(force, openmm.NonbondedForce): force.setNonbondedMethod(openmm.NonbondedForce.NoCutoff) if isinstance(force, openmm.CustomNonbondedForce): force.setNonbondedMethod(openmm.CustomNonbondedForce.NoCutoff) # set the nonbonded forces to group 1 to easily extract their energies and all others to 0 for force in hybrid_system.getForces(): if force.getName() in [ "NonbondedForce", "CustomNonbondedForce", "CustomBondForce_exceptions", ]: force.setForceGroup(1) else: force.setForceGroup(0) hybrid_simulation = app.Simulation( topology=htf.omm_hybrid_topology, system=hybrid_system, integrator=integrator, platform=platform, ) for end_state, ref_system, ref_top, pos in [ (0, htf._old_system, htf._old_topology, htf._old_positions), (1, htf._new_system, htf._new_topology, htf._new_positions), ]: # set lambda # set all lambda values to the current end state for name, func in default_lambda.functions.items(): val = func(end_state) hybrid_simulation.context.setParameter(name, val) # set positions as the hybrid positions, as all mapped atoms are in the same place in both end states hybrid_simulation.context.setPositions(htf.hybrid_positions) # get the hybrid system nonbonded energy hybrid_state = hybrid_simulation.context.getState(getEnergy=True, groups={1}) hybrid_energy = hybrid_state.getPotentialEnergy().value_in_unit(unit.kilojoule_per_mole) # set the force group for the reference system nonbonded forces for force in ref_system.getForces(): if force.getName() == "NonbondedForce": force.setForceGroup(1) force.setNonbondedMethod(openmm.NonbondedForce.NoCutoff) else: force.setForceGroup(0) # now create a reference simulation ref_simulation = app.Simulation( topology=ref_top, system=ref_system, integrator=copy.deepcopy(integrator), platform=platform, ) ref_simulation.context.setPositions(pos) ref_state = ref_simulation.context.getState(getEnergy=True, groups={1}) ref_energy = ref_state.getPotentialEnergy().value_in_unit(unit.kilojoule_per_mole) # energies should be the same # this is only true if we correctly interpolate the 1-4 interactions involving dummy atoms assert ref_energy == pytest.approx(hybrid_energy, rel=1e-5) # check the energy is non-zero to avoid false positives assert 0.0 != pytest.approx(hybrid_energy) def test_system_energy_pme_no_dummy(htf_chlorobenzene_fluorobenzene): """ Test that the hybrid system energy is the same at lambda=0 and lambda=1 as the pure systems using PME, for a fully mapped system. """ integrator = openmm.LangevinIntegrator( 300 * unit.kelvin, 1.0 / unit.picosecond, 0.002 * unit.picoseconds ) platform = openmm.Platform.getPlatformByName("CPU") default_lambda = _rfe_utils.lambdaprotocol.LambdaProtocol() htf = htf_chlorobenzene_fluorobenzene["htf"] hybrid_system = htf.hybrid_system hybrid_simulation = app.Simulation( topology=htf.omm_hybrid_topology, system=hybrid_system, integrator=integrator, platform=platform, ) for end_state, ref_system, ref_top, pos in [ (0, htf._old_system, htf._old_topology, htf._old_positions), (1, htf._new_system, htf._new_topology, htf._new_positions), ]: # set lambda # set all lambda values to the current end state for name, func in default_lambda.functions.items(): val = func(end_state) hybrid_simulation.context.setParameter(name, val) # set positions hybrid_simulation.context.setPositions(pos) # get the hybrid system energy hybrid_state = hybrid_simulation.context.getState(getEnergy=True) hybrid_energy = hybrid_state.getPotentialEnergy().value_in_unit(unit.kilojoule_per_mole) # now create a reference simulation ref_simulation = app.Simulation( topology=ref_top, system=ref_system, integrator=copy.deepcopy(integrator), platform=platform, ) ref_simulation.context.setPositions(pos) ref_state = ref_simulation.context.getState(getEnergy=True) ref_energy = ref_state.getPotentialEnergy().value_in_unit(unit.kilojoule_per_mole) # energies should be the same assert ref_energy == pytest.approx(hybrid_energy, rel=1e-5) # make sure the energy is non-zero to avoid false positives assert 0.0 != pytest.approx(hybrid_energy) def test_system_interaction_groups_no_dummy(htf_chlorobenzene_fluorobenzene): """Test the interaction groups are correctly assigned when we have environment atoms as well.""" forces = htf_chlorobenzene_fluorobenzene["forces"] htf = htf_chlorobenzene_fluorobenzene["htf"] custom_nb_force = forces["CustomNonbondedForce"] num_groups = custom_nb_force.getNumInteractionGroups() # we should always have 8 groups assert num_groups == 8 # now check the groups are correctly assigned # we assume the ligand topology is added to the end of the solvated protein topology which ends on index 21666 core_set = set(range(21667, 21679)) unique_old_set = set() unique_new_set = set() environment_set = set(range(0, 21667)) expected_groups = [ (unique_old_set, core_set), # unique_old, core (unique_old_set, environment_set), # unique_old, env (unique_new_set, core_set), # unique_new, core (unique_new_set, environment_set), # unique_new, env (core_set, environment_set), # core, env (core_set, core_set), # core, core (unique_new_set, unique_new_set), # unique_new, unique_new (unique_old_set, unique_old_set), # unique_old, unique_old ] for i in range(num_groups): group1, group2 = custom_nb_force.getInteractionGroupParameters(i) expected_g1, expected_g2 = expected_groups[i] assert set(group1) == expected_g1 assert set(group2) == expected_g2 def test_system_interaction_groups_dummy(htf_chlorobenzene_benzene): """Test the interaction groups are correctly assigned when we have environment atoms and dummy atoms.""" forces = htf_chlorobenzene_benzene["forces"] htf = htf_chlorobenzene_benzene["htf"] custom_nb_force = forces["CustomNonbondedForce"] num_groups = custom_nb_force.getNumInteractionGroups() # we should always have 8 groups assert num_groups == 8 # now check the groups are correctly assigned # we assume the ligand topology is added to the end of the solvated protein topology which ends on index 21666 core_set = set(range(21668, 21679)) unique_old_set = {21667} unique_new_set = {21679} environment_set = set(range(0, 21667)) expected_groups = [ (unique_old_set, core_set), # unique_old, core (unique_old_set, environment_set), # unique_old, env (unique_new_set, core_set), # unique_new, core (unique_new_set, environment_set), # unique_new, env (core_set, environment_set), # core, env (core_set, core_set), # core, core (unique_new_set, unique_new_set), # unique_new, unique_new (unique_old_set, unique_old_set), # unique_old, unique_old ] for i in range(num_groups): group1, group2 = custom_nb_force.getInteractionGroupParameters(i) expected_g1, expected_g2 = expected_groups[i] assert set(group1) == expected_g1 assert set(group2) == expected_g2 def test_system_energy_pme_dummy(htf_chlorobenzene_benzene): """ Test that the hybrid system nonbonded energy is the same at lambda=0 and lambda=1 as the pure systems using PME, for a system with dummy atoms. """ integrator = openmm.LangevinIntegrator( 300 * unit.kelvin, 1.0 / unit.picosecond, 0.002 * unit.picoseconds ) platform = openmm.Platform.getPlatformByName("CPU") default_lambda = _rfe_utils.lambdaprotocol.LambdaProtocol() htf = htf_chlorobenzene_benzene["htf"] hybrid_system = htf.hybrid_system # set the nonbonded forces to group 1 to easily extract their energies and all others to 0 for force in hybrid_system.getForces(): if force.getName() in [ "NonbondedForce", "CustomNonbondedForce", "CustomBondForce_exceptions", ]: force.setForceGroup(1) else: force.setForceGroup(0) hybrid_simulation = app.Simulation( topology=htf.omm_hybrid_topology, system=hybrid_system, integrator=integrator, platform=platform, ) for end_state, ref_system, ref_top, pos in [ (0, htf._old_system, htf._old_topology, htf._old_positions), (1, htf._new_system, htf._new_topology, htf._new_positions), ]: # set lambda # set all lambda values to the current end state for name, func in default_lambda.functions.items(): val = func(end_state) hybrid_simulation.context.setParameter(name, val) # set positions as the hybrid positions, as all mapped atoms are in the same place in both end states hybrid_simulation.context.setPositions(htf.hybrid_positions) # get the hybrid system nonbonded energy hybrid_state = hybrid_simulation.context.getState(getEnergy=True, groups={1}) hybrid_energy = hybrid_state.getPotentialEnergy().value_in_unit(unit.kilojoule_per_mole) # set the force group for the reference system nonbonded forces for force in ref_system.getForces(): if force.getName() == "NonbondedForce": force.setForceGroup(1) else: force.setForceGroup(0) # now create a reference simulation ref_simulation = app.Simulation( topology=ref_top, system=ref_system, integrator=copy.deepcopy(integrator), platform=platform, ) ref_simulation.context.setPositions(pos) ref_state = ref_simulation.context.getState(getEnergy=True, groups={1}) ref_energy = ref_state.getPotentialEnergy().value_in_unit(unit.kilojoule_per_mole) # energies should be the same # this is only true if we correctly interpolate the 1-4 interactions involving dummy atoms # make sure the energy is non-zero to avoid false positives assert 0.0 != pytest.approx(hybrid_energy) assert hybrid_energy == pytest.approx(ref_energy, rel=1e-5) ================================================ FILE: src/openfe/tests/protocols/openmm_rfe/test_hybrid_top_protocol.py ================================================ # This code is part of OpenFE and is licensed under the MIT license. # For details, see https://github.com/OpenFreeEnergy/openfe import copy import json import sys import xml.etree.ElementTree as ET from importlib import resources from math import sqrt from pathlib import Path from unittest import mock import gufe import mdtraj as mdt import numpy as np import openmm import pytest from kartograf import KartografAtomMapper from kartograf.atom_aligner import align_mol_shape from numpy.testing import assert_allclose from openff.toolkit import Molecule from openff.units import unit from openff.units.openmm import ensure_quantity, from_openmm, to_openmm from openmm import ( CustomNonbondedForce, MonteCarloBarostat, MonteCarloMembraneBarostat, NonbondedForce, XmlSerializer, app, ) from openmm import unit as omm_unit from openmmforcefields.generators import SMIRNOFFTemplateGenerator from openmmtools.multistate.multistatesampler import MultiStateSampler from rdkit import Chem from rdkit.Geometry import Point3D import openfe from openfe import setup from openfe.protocols import openmm_rfe from openfe.protocols.openmm_rfe._rfe_utils import topologyhelpers from openfe.protocols.openmm_rfe.hybridtop_units import ( HybridTopologyMultiStateAnalysisUnit, HybridTopologyMultiStateSimulationUnit, HybridTopologySetupUnit, ) from openfe.protocols.openmm_utils import omm_compute, system_creation from openfe.protocols.openmm_utils.charge_generation import ( HAS_ESPALOMA_CHARGE, HAS_NAGL, HAS_OPENEYE, ) def _get_units(protocol_units, unit_type): """ Helper method to extract setup units """ return [pu for pu in protocol_units if isinstance(pu, unit_type)] @pytest.fixture() def vac_settings(): settings = openmm_rfe.RelativeHybridTopologyProtocol.default_settings() settings.forcefield_settings.nonbonded_method = "nocutoff" settings.engine_settings.compute_platform = None settings.protocol_repeats = 1 return settings @pytest.fixture() def solv_settings(): settings = openmm_rfe.RelativeHybridTopologyProtocol.default_settings() settings.engine_settings.compute_platform = None settings.protocol_repeats = 1 return settings def test_compute_platform_warn(): with pytest.warns(UserWarning, match="Non-CUDA platform selected: CPU"): omm_compute.get_openmm_platform("CPU") def test_append_topology(benzene_complex_system, toluene_complex_system): mod = app.Modeller( benzene_complex_system["protein"].to_openmm_topology(), benzene_complex_system["protein"].to_openmm_positions(), ) lig1 = benzene_complex_system["ligand"].to_openff() mod.add( lig1.to_topology().to_openmm(), ensure_quantity(lig1.conformers[0], "openmm"), ) top1 = mod.topology assert len(list(top1.atoms())) == 2625 assert len(list(top1.bonds())) == 2645 lig2 = toluene_complex_system["ligand"].to_openff() top2, appended_resids = openmm_rfe._rfe_utils.topologyhelpers.combined_topology( top1, lig2.to_topology().to_openmm(), exclude_resids=np.asarray(list(top1.residues())[-1].index), ) assert len(list(top2.atoms())) == 2625 + 3 # added methyl assert len(list(top2.bonds())) == 2645 + 4 - 1 # add methyl bonds, minus hydrogen assert appended_resids[0] == len(list(top1.residues())) - 1 def test_append_topology_no_exclude(benzene_complex_system, toluene_complex_system): mod = app.Modeller( benzene_complex_system["protein"].to_openmm_topology(), benzene_complex_system["protein"].to_openmm_positions(), ) lig1 = benzene_complex_system["ligand"].to_openff() mod.add( lig1.to_topology().to_openmm(), ensure_quantity(lig1.conformers[0], "openmm"), ) top1 = mod.topology assert len(list(top1.atoms())) == 2625 assert len(list(top1.bonds())) == 2645 lig2 = toluene_complex_system["ligand"].to_openff() top2, appended_resids = openmm_rfe._rfe_utils.topologyhelpers.combined_topology( top1, lig2.to_topology().to_openmm(), exclude_resids=None, ) assert len(list(top2.atoms())) == 2625 + 15 # added toluene assert len(list(top2.bonds())) == 2645 + 15 # 15 bonds in toluene assert appended_resids[0] == len(list(top1.residues())) def test_create_default_settings(): settings = openmm_rfe.RelativeHybridTopologyProtocol.default_settings() assert settings def test_adaptive_settings_no_initial(benzene_system, toluene_system, benzene_to_toluene_mapping): settings = openmm_rfe.RelativeHybridTopologyProtocol._adaptive_settings( stateA=benzene_system, stateB=toluene_system, mapping=[benzene_to_toluene_mapping], ) # this is a solvent system make sure the padding is 1.5 nm assert settings.solvation_settings.solvent_padding == 1.5 * unit.nanometer # make sure the default parameter is not changed assert settings.protocol_repeats == 3 def test_create_default_protocol(): # this is roughly how it should be created protocol = openmm_rfe.RelativeHybridTopologyProtocol( settings=openmm_rfe.RelativeHybridTopologyProtocol.default_settings(), ) assert protocol def test_invalid_protocol_repeats(): settings = openmm_rfe.RelativeHybridTopologyProtocol.default_settings() with pytest.raises(ValueError, match="must be a positive value"): settings.protocol_repeats = -1 def test_serialize_protocol(): protocol = openmm_rfe.RelativeHybridTopologyProtocol( settings=openmm_rfe.RelativeHybridTopologyProtocol.default_settings(), ) ser = protocol.to_dict() ret = openmm_rfe.RelativeHybridTopologyProtocol.from_dict(ser) assert protocol == ret def test_repeat_units(benzene_system, toluene_system, benzene_to_toluene_mapping): settings = openmm_rfe.RelativeHybridTopologyProtocol.default_settings() protocol = openmm_rfe.RelativeHybridTopologyProtocol( settings=settings, ) dag = protocol.create( stateA=benzene_system, stateB=toluene_system, mapping=benzene_to_toluene_mapping, ) # 9 protocol units, 3 per repeat pus = list(dag.protocol_units) assert len(pus) == 9 # Aggregate some info for each repeat setup = _get_units(pus, HybridTopologySetupUnit) simulation = _get_units(pus, HybridTopologyMultiStateSimulationUnit) analysis = _get_units(pus, HybridTopologyMultiStateAnalysisUnit) # Should be 3 of everything assert len(setup) == len(simulation) == len(analysis) == 3 # Check that the dag chain is correct for analysis_pu in analysis: repeat_id = analysis_pu.inputs["repeat_id"] setup_pu = [s for s in setup if s.inputs["repeat_id"] == repeat_id][0] sim_pu = [s for s in simulation if s.inputs["repeat_id"] == repeat_id][0] assert analysis_pu.inputs["setup_results"] == setup_pu assert analysis_pu.inputs["simulation_results"] == sim_pu assert sim_pu.inputs["setup_results"] == setup_pu def test_create_independent_repeat_ids(benzene_system, toluene_system, benzene_to_toluene_mapping): # if we create two dags each with 3 repeats, they should give 6 repeat_ids # this allows multiple DAGs in flight for one Transformation that don't clash on gather settings = openmm_rfe.RelativeHybridTopologyProtocol.default_settings() protocol = openmm_rfe.RelativeHybridTopologyProtocol( settings=settings, ) dag1 = protocol.create( stateA=benzene_system, stateB=toluene_system, mapping=benzene_to_toluene_mapping, ) dag2 = protocol.create( stateA=benzene_system, stateB=toluene_system, mapping=benzene_to_toluene_mapping, ) repeat_ids = set() for u in dag1.protocol_units: repeat_ids.add(u.inputs["repeat_id"]) for u in dag2.protocol_units: repeat_ids.add(u.inputs["repeat_id"]) assert len(repeat_ids) == 6 def test_bad_sampler(): class FakeSimSettings(gufe.settings.SettingsBaseModel): sampler_method: str = "foo bar" errmsg = "Unknown sampler foo bar" with pytest.raises(AttributeError, match=errmsg): HybridTopologyMultiStateSimulationUnit._get_sampler( system=None, positions=None, lambdas=None, integrator=None, reporter=None, simulation_settings=FakeSimSettings(), thermo_settings=None, alchem_settings=None, platform=None, restart=False, dry=False, ) @pytest.mark.parametrize("method", ["repex", "sams", "independent", "InDePeNdENT"]) def test_setup_dry_sim_default_vacuum( benzene_vacuum_system, toluene_vacuum_system, benzene_to_toluene_mapping, method, vac_settings, tmp_path, benzene_toluene_topology, ): vac_settings.simulation_settings.sampler_method = method protocol = openmm_rfe.RelativeHybridTopologyProtocol( settings=vac_settings, ) # create DAG from protocol and take first (and only) work unit from within dag = protocol.create( stateA=benzene_vacuum_system, stateB=toluene_vacuum_system, mapping=benzene_to_toluene_mapping, ) dag_setup_unit = _get_units(dag.protocol_units, HybridTopologySetupUnit)[0] dag_sim_unit = _get_units(dag.protocol_units, HybridTopologyMultiStateSimulationUnit)[0] # Manually run the units setup_results = dag_setup_unit.run( dry=True, scratch_basepath=tmp_path, shared_basepath=tmp_path ) sim_results = dag_sim_unit.run( system=setup_results["hybrid_system"], positions=setup_results["hybrid_positions"], selection_indices=setup_results["selection_indices"], dry=True, scratch_basepath=tmp_path, shared_basepath=tmp_path, ) sampler = sim_results["sampler"] assert isinstance(sampler, MultiStateSampler) assert not sampler.is_periodic assert sampler._thermodynamic_states[0].barostat is None # Check hybrid OMM and MDTtraj Topologies htf = setup_results["hybrid_factory"] # 16 atoms: # 11 common atoms, 1 extra hydrogen in benzene, 4 extra in toluene # 12 bonds in benzene + 4 extra toluene bonds assert len(list(htf.hybrid_topology.atoms)) == 16 assert len(list(htf.omm_hybrid_topology.atoms())) == 16 assert len(list(htf.hybrid_topology.bonds)) == 16 assert len(list(htf.omm_hybrid_topology.bonds())) == 16 # smoke test - can convert back the mdtraj topology ret_top = mdt.Topology.to_openmm(htf.hybrid_topology) assert len(list(ret_top.atoms())) == 16 assert len(list(ret_top.bonds())) == 16 # check that our PDB has the right number of atoms pdb = mdt.load_pdb(tmp_path / "hybrid_system.pdb") assert pdb.n_atoms == 16 # regression test that we have the expected mdtraj topology assert benzene_toluene_topology == htf.hybrid_topology # check we can extract the correct positions for the end states old_positions = htf.old_positions(htf.hybrid_positions) # check the shape and positions match the input assert old_positions.shape == (12, 3) # compare with the input positions which are stored on the htf assert_allclose( old_positions.value_in_unit(omm_unit.angstrom), htf._old_positions.value_in_unit(omm_unit.angstrom), ) # same for toluene new_positions = htf.new_positions(htf.hybrid_positions) assert new_positions.shape == (15, 3) assert_allclose( new_positions.value_in_unit(omm_unit.angstrom), htf._new_positions.value_in_unit(omm_unit.angstrom), ) def test_setup_gaff_vacuum( benzene_vacuum_system, toluene_vacuum_system, benzene_to_toluene_mapping, vac_settings, tmp_path ): """ Simple dry run of the setup unit to make sure that parameterisation will work with gaff. """ vac_settings.forcefield_settings.small_molecule_forcefield = "gaff-2.11" protocol = openmm_rfe.RelativeHybridTopologyProtocol( settings=vac_settings, ) # create DAG from protocol and take first (and only) work unit from within dag = protocol.create( stateA=benzene_vacuum_system, stateB=toluene_vacuum_system, mapping=benzene_to_toluene_mapping, ) dag_setup_unit = _get_units(dag.protocol_units, HybridTopologySetupUnit)[0] _ = dag_setup_unit.run(dry=True, scratch_basepath=tmp_path, shared_basepath=tmp_path) @pytest.mark.slow def test_dry_many_molecules_solvent( benzene_many_solv_system, toluene_many_solv_system, benzene_to_toluene_mapping, solv_settings, tmp_path, ): """ A basic setup test flushing "will it work if you pass multiple molecules" """ protocol = openmm_rfe.RelativeHybridTopologyProtocol( settings=solv_settings, ) # create DAG from protocol and take first (and only) work unit from within dag = protocol.create( stateA=benzene_many_solv_system, stateB=toluene_many_solv_system, mapping=benzene_to_toluene_mapping, ) dag_setup_unit = _get_units(dag.protocol_units, HybridTopologySetupUnit)[0] _ = dag_setup_unit.run(dry=True, scratch_basepath=tmp_path, shared_basepath=tmp_path) BENZ = """\ benzene PyMOL2.5 3D 0 12 12 0 0 0 0 0 0 0 0999 V2000 1.4045 -0.0000 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 0.7022 1.2164 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 -0.7023 1.2164 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 -1.4045 -0.0000 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 -0.7023 -1.2164 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 0.7023 -1.2164 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 2.5079 -0.0000 0.0000 H 0 0 0 0 0 0 0 0 0 0 0 0 1.2540 2.1720 0.0000 H 0 0 0 0 0 0 0 0 0 0 0 0 -1.2540 2.1720 0.0000 H 0 0 0 0 0 0 0 0 0 0 0 0 -2.5079 -0.0000 0.0000 H 0 0 0 0 0 0 0 0 0 0 0 0 -1.2540 -2.1719 0.0000 H 0 0 0 0 0 0 0 0 0 0 0 0 1.2540 -2.1720 0.0000 H 0 0 0 0 0 0 0 0 0 0 0 0 1 2 2 0 0 0 0 1 6 1 0 0 0 0 1 7 1 0 0 0 0 2 3 1 0 0 0 0 2 8 1 0 0 0 0 3 4 2 0 0 0 0 3 9 1 0 0 0 0 4 5 1 0 0 0 0 4 10 1 0 0 0 0 5 6 2 0 0 0 0 5 11 1 0 0 0 0 6 12 1 0 0 0 0 M END $$$$ """ PYRIDINE = """\ pyridine PyMOL2.5 3D 0 11 11 0 0 0 0 0 0 0 0999 V2000 1.4045 -0.0000 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 -0.7023 1.2164 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 -1.4045 -0.0000 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 -0.7023 -1.2164 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 0.7023 -1.2164 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 2.4940 -0.0325 0.0000 H 0 0 0 0 0 0 0 0 0 0 0 0 1.2473 -2.1604 0.0000 H 0 0 0 0 0 0 0 0 0 0 0 0 -1.2473 -2.1604 0.0000 H 0 0 0 0 0 0 0 0 0 0 0 0 -2.4945 -0.0000 0.0000 H 0 0 0 0 0 0 0 0 0 0 0 0 -1.2753 2.1437 0.0000 H 0 0 0 0 0 0 0 0 0 0 0 0 0.7525 1.3034 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0 1 5 1 0 0 0 0 1 6 1 0 0 0 0 1 11 2 0 0 0 0 2 3 2 0 0 0 0 2 10 1 0 0 0 0 3 4 1 0 0 0 0 3 9 1 0 0 0 0 4 5 2 0 0 0 0 4 8 1 0 0 0 0 5 7 1 0 0 0 0 2 11 1 0 0 0 0 M END $$$$ """ def test_setup_core_element_change(vac_settings, tmp_path): benz = openfe.SmallMoleculeComponent(Chem.MolFromMolBlock(BENZ, removeHs=False)) pyr = openfe.SmallMoleculeComponent(Chem.MolFromMolBlock(PYRIDINE, removeHs=False)) mapping = openfe.LigandAtomMapping( benz, pyr, {0: 0, 1: 10, 2: 1, 3: 2, 4: 3, 5: 4, 6: 5, 8: 9, 9: 8, 10: 7, 11: 6} ) protocol = openmm_rfe.RelativeHybridTopologyProtocol(settings=vac_settings) dag = protocol.create( stateA=openfe.ChemicalSystem({"ligand": benz}), stateB=openfe.ChemicalSystem({"ligand": pyr}), mapping=mapping, ) dag_setup_unit = _get_units(dag.protocol_units, HybridTopologySetupUnit)[0] results = dag_setup_unit.run(dry=True, scratch_basepath=tmp_path, shared_basepath=tmp_path) system = results["hybrid_system"] assert system.getNumParticles() == 12 # Average mass between nitrogen and carbon assert system.getParticleMass(1) == 12.0127235 * omm_unit.amu # Get out the CustomNonbondedForce cnf = [f for f in system.getForces() if f.__class__.__name__ == "CustomNonbondedForce"][0] # there should be no new unique atoms assert cnf.getInteractionGroupParameters(6) == [(), ()] # there should be one old unique atom (spare hydrogen from the benzene) assert cnf.getInteractionGroupParameters(7) == [(7,), (7,)] @pytest.mark.parametrize("method", ["repex", "sams", "independent"]) def test_dry_run_ligand( benzene_system, toluene_system, benzene_to_toluene_mapping, method, solv_settings, tmp_path ): # this might be a bit time consuming solv_settings.simulation_settings.sampler_method = method solv_settings.output_settings.output_indices = "resname UNK" protocol = openmm_rfe.RelativeHybridTopologyProtocol( settings=solv_settings, ) dag = protocol.create( stateA=benzene_system, stateB=toluene_system, mapping=benzene_to_toluene_mapping, ) dag_setup_unit = _get_units(dag.protocol_units, HybridTopologySetupUnit)[0] dag_sim_unit = _get_units(dag.protocol_units, HybridTopologyMultiStateSimulationUnit)[0] # Manually run the units setup_results = dag_setup_unit.run( dry=True, scratch_basepath=tmp_path, shared_basepath=tmp_path ) sim_results = dag_sim_unit.run( system=setup_results["hybrid_system"], positions=setup_results["hybrid_positions"], selection_indices=setup_results["selection_indices"], dry=True, scratch_basepath=tmp_path, shared_basepath=tmp_path, ) sampler = sim_results["sampler"] assert isinstance(sampler, MultiStateSampler) assert sampler.is_periodic assert isinstance(sampler._thermodynamic_states[0].barostat, MonteCarloBarostat) assert sampler._thermodynamic_states[1].pressure == 1 * omm_unit.bar # Check we have the right number of atoms in the PDB pdb = mdt.load_pdb(tmp_path / "hybrid_system.pdb") assert pdb.n_atoms == 16 def test_confgen_mocked_fail( benzene_system, toluene_system, benzene_to_toluene_mapping, solv_settings, tmp_path ): """ Check that even if conformer generation fails, we can still perform a sim """ protocol = openmm_rfe.RelativeHybridTopologyProtocol(settings=solv_settings) dag = protocol.create( stateA=benzene_system, stateB=toluene_system, mapping=benzene_to_toluene_mapping ) dag_unit = list(dag.protocol_units)[0] with mock.patch("rdkit.Chem.AllChem.EmbedMultipleConfs", return_value=0): sampler = dag_unit.run(dry=True, scratch_basepath=tmp_path, shared_basepath=tmp_path) assert sampler @pytest.fixture(scope="session") def tip4p_hybrid_factory( benzene_system, toluene_system, benzene_to_toluene_mapping, tmp_path_factory, ): """ Hybrid system with virtual sites in the environment (waters) """ settings = openmm_rfe.RelativeHybridTopologyProtocol.default_settings() settings.engine_settings.compute_platform = None settings.forcefield_settings.forcefields = [ "amber/ff14SB.xml", # ff14SB protein force field "amber/tip4pew_standard.xml", # FF we are testing with the fun VS "amber/phosaa10.xml", # Handles THE TPO ] settings.solvation_settings.solvent_padding = 1.5 * unit.nanometer settings.forcefield_settings.nonbonded_cutoff = 0.9 * unit.nanometer settings.solvation_settings.solvent_model = "tip4pew" settings.integrator_settings.reassign_velocities = True protocol = openmm_rfe.RelativeHybridTopologyProtocol( settings=settings, ) dag = protocol.create( stateA=benzene_system, stateB=toluene_system, mapping=benzene_to_toluene_mapping, ) dag_setup_unit = [pu for pu in dag.protocol_units if isinstance(pu, HybridTopologySetupUnit)][0] shared_temp = tmp_path_factory.mktemp("tip4p_shared") scratch_temp = tmp_path_factory.mktemp("tip4p_scratch") dag_unit_setup_result = dag_setup_unit.run( dry=True, scratch_basepath=scratch_temp, shared_basepath=shared_temp, ) return dag_unit_setup_result["hybrid_factory"] def test_tip4p_particle_count(tip4p_hybrid_factory): """ Check that the total number of particles in the system are as expected. """ htf = tip4p_hybrid_factory old_particle_count = htf._old_system.getNumParticles() unique_new_count = len(htf._unique_new_atoms) hybrid_particle_count = htf.hybrid_system.getNumParticles() assert old_particle_count + unique_new_count == hybrid_particle_count def test_tip4p_num_waters(tip4p_hybrid_factory): """ Check that the number of virtual sites is equal the number of waters. """ htf = tip4p_hybrid_factory # Test 2 num_waters = len([r for r in htf._old_topology.residues() if r.name == "HOH"]) virtual_sites = [ ix for ix in range(htf.hybrid_system.getNumParticles()) if htf.hybrid_system.isVirtualSite(ix) ] assert num_waters == len(virtual_sites) def test_tip4p_check_vsite_parameters(tip4p_hybrid_factory): """ Check that the virtual site parameters are those expected as defined by the tip4p-ew parameters in openmmforcefields """ htf = tip4p_hybrid_factory virtual_sites = [ ix for ix in range(htf.hybrid_system.getNumParticles()) if htf.hybrid_system.isVirtualSite(ix) ] # get the standard and custom nonbonded forces - one of each nonbond = [f for f in htf.hybrid_system.getForces() if isinstance(f, NonbondedForce)][0] cust_nonbond = [ f for f in htf.hybrid_system.getForces() if isinstance(f, CustomNonbondedForce) ][0] # loop through every virtual site and check that they have the # expected tip4p parameters for entry in virtual_sites: vs = htf.hybrid_system.getVirtualSite(entry) vs_mass = htf.hybrid_system.getParticleMass(entry) assert ensure_quantity(vs_mass, "openff").m == pytest.approx(0) vs_weights = [vs.getWeight(ix) for ix in range(vs.getNumParticles())] np.testing.assert_allclose(vs_weights, [0.786646558, 0.106676721, 0.106676721]) c, s, e = nonbond.getParticleParameters(entry) assert ensure_quantity(c, "openff").m == pytest.approx(-1.04844) assert ensure_quantity(s, "openff").m == 1 assert ensure_quantity(e, "openff").m == 0 s1, e1, s2, e2, i, j = cust_nonbond.getParticleParameters(entry) assert i == j == 0 assert s1 == s2 == 1 assert e1 == e2 == 0 @pytest.mark.slow @pytest.mark.parametrize( "cutoff", [ 1.0 * unit.nanometer, 12.0 * unit.angstrom, 0.9 * unit.nanometer, ], ) def test_setup_ligand_system_cutoff( cutoff, benzene_system, toluene_system, benzene_to_toluene_mapping, solv_settings, tmp_path ): """ Test that the right nonbonded cutoff is propagated to the hybrid system. """ solv_settings.solvation_settings.solvent_padding = 1.5 * unit.nanometer solv_settings.forcefield_settings.nonbonded_cutoff = cutoff protocol = openmm_rfe.RelativeHybridTopologyProtocol( settings=solv_settings, ) dag = protocol.create( stateA=benzene_system, stateB=toluene_system, mapping=benzene_to_toluene_mapping, ) dag_setup_unit = [pu for pu in dag.protocol_units if isinstance(pu, HybridTopologySetupUnit)][0] hs = dag_setup_unit.run(dry=True, scratch_basepath=tmp_path, shared_basepath=tmp_path)[ "hybrid_system" ] nbfs = [ f for f in hs.getForces() if isinstance(f, CustomNonbondedForce) or isinstance(f, NonbondedForce) ] for f in nbfs: f_cutoff = from_openmm(f.getCutoffDistance()) assert f_cutoff == cutoff @pytest.mark.parametrize( "method, backend, ref_key", [ ("am1bcc", "ambertools", "ambertools"), pytest.param( "am1bcc", "openeye", "openeye", marks=pytest.mark.skipif(not HAS_OPENEYE, reason="needs oechem"), ), pytest.param( "nagl", "rdkit", "nagl", marks=pytest.mark.skipif( not HAS_NAGL or HAS_OPENEYE or sys.platform.startswith("darwin"), reason="needs NAGL (without oechem) and/or on macos", ), ), pytest.param( "espaloma", "rdkit", "espaloma", marks=pytest.mark.skipif(not HAS_ESPALOMA_CHARGE, reason="needs espaloma charge"), ), ], ) def test_setup_charge_backends( CN_molecule, tmp_path, method, backend, ref_key, vac_settings, am1bcc_ref_charges ): vac_settings.partial_charge_settings.partial_charge_method = method vac_settings.partial_charge_settings.off_toolkit_backend = backend vac_settings.partial_charge_settings.nagl_model = "openff-gnn-am1bcc-0.1.0-rc.1.pt" protocol = openmm_rfe.RelativeHybridTopologyProtocol( settings=vac_settings, ) # make stateB molecule offmolB = Molecule.from_smiles("CCN") offmolB.generate_conformers() molB = openfe.SmallMoleculeComponent.from_openff(offmolB) a_molB = align_mol_shape(molB, ref_mol=CN_molecule) mapper = KartografAtomMapper(atom_map_hydrogens=True) mapping = next(mapper.suggest_mappings(CN_molecule, a_molB)) systemA = openfe.ChemicalSystem({"l": CN_molecule}) systemB = openfe.ChemicalSystem({"l": a_molB}) dag = protocol.create(stateA=systemA, stateB=systemB, mapping=mapping) dag_setup_unit = [pu for pu in dag.protocol_units if isinstance(pu, HybridTopologySetupUnit)][0] results = dag_setup_unit.run(dry=True, scratch_basepath=tmp_path, shared_basepath=tmp_path) htf = results["hybrid_factory"] hybrid_system = results["hybrid_system"] # get the standard nonbonded force nonbond = [f for f in hybrid_system.getForces() if isinstance(f, NonbondedForce)] assert len(nonbond) == 1 # get the particle parameter offsets c_offsets = {} for i in range(nonbond[0].getNumParticleParameterOffsets()): offset = nonbond[0].getParticleParameterOffset(i) c_offsets[offset[1]] = ensure_quantity(offset[2], "openff") # See the user charges test below for an idea of what we're doing here # In this particular case we are solely checking that the old atoms # match the reference charges in am1bcc_ref_charges for i in range(hybrid_system.getNumParticles()): c, s, e = nonbond[0].getParticleParameters(i) # get the particle charge (c) c = ensure_quantity(c, "openff") # particle charge (c) is equal to molA particle charge # offset (c_offsets) is equal to -(molA particle charge) if i in htf._atom_classes["unique_old_atoms"]: idx = htf._hybrid_to_old_map[i] ref = am1bcc_ref_charges[ref_key][idx] np.testing.assert_allclose(c, ref, rtol=1e-4) np.testing.assert_allclose(c_offsets[i], -ref, rtol=1e-4) # particle charge (c) is equal to molA particle charge # offset (c_offsets) is equal to difference between molB and molA elif i in htf._atom_classes["core_atoms"]: old_i = htf._hybrid_to_old_map[i] ref = am1bcc_ref_charges[ref_key][i] np.testing.assert_allclose(c, ref, rtol=1e-4) def test_setup_same_mol_different_charges(benzene_modifications, vac_settings, tmp_path): """ Issue #1120 - make sure we can do an RFE of a system with different parameters but the same molecule. """ protocol = openmm_rfe.RelativeHybridTopologyProtocol(settings=vac_settings) benzene_offmol = benzene_modifications["benzene"].to_openff() # Give state A some gasteiger charges benzene_offmol.assign_partial_charges(partial_charge_method="gasteiger") stateA_charges = copy.deepcopy(benzene_offmol.partial_charges) stateA_mol = openfe.SmallMoleculeComponent.from_openff(benzene_offmol) # Give state B gasteiger charges scaled by 0.9 benzene_offmol.partial_charges *= 0.9 stateB_charges = copy.deepcopy(benzene_offmol.partial_charges) stateB_mol = openfe.SmallMoleculeComponent.from_openff(benzene_offmol) # Create new mapping mapping = gufe.LigandAtomMapping( componentA=stateA_mol, componentB=stateB_mol, componentA_to_componentB={i: i for i in range(12)}, ) # create DAG from protocol and take first (and only) work unit from within dag = protocol.create( stateA=openfe.ChemicalSystem({"l": stateA_mol}), stateB=openfe.ChemicalSystem({"l": stateB_mol}), mapping=mapping, ) dag_setup_unit = [pu for pu in dag.protocol_units if isinstance(pu, HybridTopologySetupUnit)][0] results = dag_setup_unit.run(dry=True, scratch_basepath=tmp_path, shared_basepath=tmp_path) htf = results["hybrid_factory"] hybrid_system = results["hybrid_system"] # get the standard nonbonded force nonbond = [f for f in hybrid_system.getForces() if isinstance(f, NonbondedForce)] # get the particle parameters & offsets for i in range(hybrid_system.getNumParticles()): # All particles should be core atoms assert i in htf._atom_classes["core_atoms"] # offsets offset = ensure_quantity(nonbond[0].getParticleParameterOffset(i)[2], "openff") # parameters c, s, e = nonbond[0].getParticleParameters(i) c = ensure_quantity(c, "openff") # check state A charge assert pytest.approx(c) == stateA_charges[i] # check state B charge c_diff = stateB_charges[i] - stateA_charges[i] assert pytest.approx(offset) == c_diff # check that the offset value is non-zero assert abs(offset) > 0 * offset.units @pytest.mark.flaky(reruns=3) # bad minimisation can happen def test_setup_user_charges(benzene_modifications, vac_settings, tmp_path): """ Create a hybrid system with a set of fictitious user supplied charges and ensure that they are properly passed through to the constructed hybrid topology. """ protocol = openmm_rfe.RelativeHybridTopologyProtocol( settings=vac_settings, ) def assign_fictitious_charges(offmol): """ Get a random array of fake partial charges (ints because why not) that sums up to 0. Note that OpenFF will complain if you try to create a molecule that has a total charge that is different from the expected formal charge, hence we enforce a zero charge here. """ rand_arr = np.random.randint(1, 10, size=offmol.n_atoms) / 100 rand_arr[-1] = -sum(rand_arr[:-1]) return rand_arr * unit.elementary_charge def check_propchgs(smc, charge_array): """ Check that the partial charges we assigned to our offmol from which the smc was constructed are present and the right ones. """ prop_chgs = smc.to_dict()["molprops"]["atom.dprop.PartialCharge"] prop_chgs = np.array(prop_chgs.split(), dtype=float) np.testing.assert_allclose(prop_chgs, charge_array.m) # Create new smc with overridden charges benzene_offmol = benzene_modifications["benzene"].to_openff() toluene_offmol = benzene_modifications["toluene"].to_openff() benzene_rand_chg = assign_fictitious_charges(benzene_offmol) toluene_rand_chg = assign_fictitious_charges(toluene_offmol) benzene_offmol.partial_charges = benzene_rand_chg toluene_offmol.partial_charges = toluene_rand_chg benzene_smc = openfe.SmallMoleculeComponent.from_openff(benzene_offmol) toluene_smc = openfe.SmallMoleculeComponent.from_openff(toluene_offmol) # Check that the new smcs have the new overridden charges check_propchgs(benzene_smc, benzene_rand_chg) check_propchgs(toluene_smc, toluene_rand_chg) # Create new mapping mapper = openfe.setup.LomapAtomMapper(element_change=False) mapping = next(mapper.suggest_mappings(benzene_smc, toluene_smc)) # create DAG from protocol and take first (and only) work unit from within dag = protocol.create( stateA=openfe.ChemicalSystem({"l": benzene_smc}), stateB=openfe.ChemicalSystem({"l": toluene_smc}), mapping=mapping, ) dag_setup_unit = [pu for pu in dag.protocol_units if isinstance(pu, HybridTopologySetupUnit)][0] results = dag_setup_unit.run(dry=True, scratch_basepath=tmp_path, shared_basepath=tmp_path) htf = results["hybrid_factory"] hybrid_system = results["hybrid_system"] # get the standard nonbonded force nonbond = [f for f in hybrid_system.getForces() if isinstance(f, NonbondedForce)] assert len(nonbond) == 1 # get the particle parameter offsets c_offsets = {} for i in range(nonbond[0].getNumParticleParameterOffsets()): offset = nonbond[0].getParticleParameterOffset(i) c_offsets[offset[1]] = ensure_quantity(offset[2], "openff") # Here is a bit of exposition on what we're doing # HTF creates two sets of nonbonded forces, a standard one (for the # PME) and a custom one (for sterics). # Here we specifically check charges, so we only concentrate on the # standard NonbondedForce. # The way the NonbondedForce is constructed is as follows: # - unique old atoms: # * The particle charge is set to the input molA particle charge # * The chargeScale offset is set to the negative value of the molA # particle charge (such that by scaling you effectively zero out # the charge. # - unique new atoms: # * The particle charge is set to zero (doesn't exist in the starting # end state). # * The chargeScale offset is set to the value of the molB particle # charge (such that by scaling you effectively go from 0 to molB # charge). # - core atoms: # * The particle charge is set to the input molA particle charge # (i.e. we start from a system that has molA charges). # * The particle charge offset is set to the difference between # the molB particle charge and the molA particle charge (i.e. # we scale by that difference to get to the value of the molB # particle charge). for i in range(hybrid_system.getNumParticles()): c, s, e = nonbond[0].getParticleParameters(i) # get the particle charge (c) c = ensure_quantity(c, "openff") # particle charge (c) is equal to molA particle charge # offset (c_offsets) is equal to -(molA particle charge) if i in htf._atom_classes["unique_old_atoms"]: idx = htf._hybrid_to_old_map[i] np.testing.assert_allclose(c, benzene_rand_chg[idx]) np.testing.assert_allclose(c_offsets[i], -benzene_rand_chg[idx]) # particle charge (c) is equal to 0 # offset (c_offsets) is equal to molB particle charge elif i in htf._atom_classes["unique_new_atoms"]: idx = htf._hybrid_to_new_map[i] np.testing.assert_allclose(c, 0 * unit.elementary_charge) np.testing.assert_allclose(c_offsets[i], toluene_rand_chg[idx]) # particle charge (c) is equal to molA particle charge # offset (c_offsets) is equal to difference between molB and molA elif i in htf._atom_classes["core_atoms"]: old_i = htf._hybrid_to_old_map[i] new_i = htf._hybrid_to_new_map[i] c_exp = toluene_rand_chg[new_i] - benzene_rand_chg[old_i] np.testing.assert_allclose(c, benzene_rand_chg[old_i]) np.testing.assert_allclose(c_offsets[i], c_exp) def test_virtual_sites_no_reassign( benzene_system, toluene_system, benzene_to_toluene_mapping, solv_settings, tmp_path ): """ Because of some as-of-yet not fully identified issue, not reassigning velocities will cause systems to NaN. See https://github.com/choderalab/openmmtools/issues/695 """ solv_settings.forcefield_settings.forcefields = [ "amber/ff14SB.xml", # ff14SB protein force field "amber/tip4pew_standard.xml", # FF we are testing with the fun VS "amber/phosaa10.xml", # Handles THE TPO ] solv_settings.solvation_settings.solvent_padding = 1.0 * unit.nanometer solv_settings.forcefield_settings.nonbonded_cutoff = 0.9 * unit.nanometer solv_settings.solvation_settings.solvent_model = "tip4pew" solv_settings.integrator_settings.reassign_velocities = False protocol = openmm_rfe.RelativeHybridTopologyProtocol( settings=solv_settings, ) dag = protocol.create( stateA=benzene_system, stateB=toluene_system, mapping=benzene_to_toluene_mapping, ) dag_setup_unit = _get_units(dag.protocol_units, HybridTopologySetupUnit)[0] dag_sim_unit = _get_units(dag.protocol_units, HybridTopologyMultiStateSimulationUnit)[0] # Manually run the units setup_results = dag_setup_unit.run( dry=True, scratch_basepath=tmp_path, shared_basepath=tmp_path ) errmsg = "Simulations with virtual sites without velocity" with pytest.raises(ValueError, match=errmsg): _ = dag_sim_unit.run( system=setup_results["hybrid_system"], positions=setup_results["hybrid_positions"], selection_indices=setup_results["selection_indices"], dry=True, scratch_basepath=tmp_path, shared_basepath=tmp_path, ) def test_setup_dodecahdron_ligand_box( benzene_system, toluene_system, benzene_to_toluene_mapping, solv_settings, tmp_path ): """ Test that a hybrid system with a dodechadron is built properly. """ solv_settings.solvation_settings.solvent_padding = 1.5 * unit.nanometer solv_settings.solvation_settings.box_shape = "dodecahedron" protocol = openmm_rfe.RelativeHybridTopologyProtocol(settings=solv_settings) dag = protocol.create( stateA=benzene_system, stateB=toluene_system, mapping=benzene_to_toluene_mapping, ) dag_setup_unit = _get_units(dag.protocol_units, HybridTopologySetupUnit)[0] hs = dag_setup_unit.run(dry=True, scratch_basepath=tmp_path, shared_basepath=tmp_path)[ "hybrid_system" ] vectors = hs.getDefaultPeriodicBoxVectors() width = float(from_openmm(vectors)[0][0].to("nanometer").m) # dodecahedron has the following shape: # [width, 0, 0], [0, width, 0], [0.5, 0.5, 0.5 * sqrt(2)] * width expected_vectors = [ [width, 0, 0], [0, width, 0], [0.5 * width, 0.5 * width, 0.5 * sqrt(2) * width], ] * unit.nanometer assert_allclose(expected_vectors, from_openmm(vectors)) @pytest.mark.slow @pytest.mark.parametrize("method", ["repex", "sams", "independent"]) def test_dry_run_complex( benzene_complex_system, toluene_complex_system, benzene_to_toluene_mapping, method, solv_settings, tmp_path, ): # this will be very time consuming solv_settings.simulation_settings.sampler_method = method solv_settings.output_settings.output_indices = "protein or resname UNK" protocol = openmm_rfe.RelativeHybridTopologyProtocol( settings=solv_settings, ) dag = protocol.create( stateA=benzene_complex_system, stateB=toluene_complex_system, mapping=benzene_to_toluene_mapping, ) dag_setup_unit = _get_units(dag.protocol_units, HybridTopologySetupUnit)[0] dag_sim_unit = _get_units(dag.protocol_units, HybridTopologyMultiStateSimulationUnit)[0] setup_results = dag_setup_unit.run( dry=True, scratch_basepath=tmp_path, shared_basepath=tmp_path ) sim_results = dag_sim_unit.run( system=setup_results["hybrid_system"], positions=setup_results["hybrid_positions"], selection_indices=setup_results["selection_indices"], dry=True, scratch_basepath=tmp_path, shared_basepath=tmp_path, ) sampler = sim_results["sampler"] assert isinstance(sampler, MultiStateSampler) assert sampler.is_periodic assert isinstance(sampler._thermodynamic_states[0].barostat, MonteCarloBarostat) assert sampler._thermodynamic_states[1].pressure == 1 * omm_unit.bar # Check we have the right number of atoms in the PDB pdb = mdt.load_pdb(tmp_path / "hybrid_system.pdb") assert pdb.n_atoms == 2629 @pytest.mark.slow def test_dry_run_membrane_complex( a2a_protein_membrane_component, a2a_ligands, tmpdir, ): # TODO check if we can remove the slow mark once the HTF speed up is merged ligA = next(c for c in a2a_ligands if c.name == "4g") ligB = next(c for c in a2a_ligands if c.name == "4h") mapping = openfe.LigandAtomMapping( componentA=ligA, componentB=ligB, componentA_to_componentB={i: i for i in range(36)}, ) settings = openmm_rfe.RelativeHybridTopologyProtocol.default_settings() settings.protocol_repeats = 1 settings.engine_settings.compute_platform = "cpu" settings.output_settings.output_indices = "all" systemA = openfe.ChemicalSystem( {"ligand": mapping.componentA, "protein": a2a_protein_membrane_component}, name=f"{mapping.componentA.name}_{a2a_protein_membrane_component.name}", ) systemB = openfe.ChemicalSystem( {"ligand": mapping.componentB, "protein": a2a_protein_membrane_component}, name=f"{mapping.componentB.name}_{a2a_protein_membrane_component.name}", ) adaptive_settings = openmm_rfe.RelativeHybridTopologyProtocol._adaptive_settings( stateA=systemA, stateB=systemB, mapping=mapping, initial_settings=settings ) protocol = openmm_rfe.RelativeHybridTopologyProtocol( settings=adaptive_settings, ) dag = protocol.create( stateA=systemA, stateB=systemB, mapping=mapping, ) dag_setup_unit = _get_units(dag.protocol_units, HybridTopologySetupUnit)[0] dag_sim_unit = _get_units(dag.protocol_units, HybridTopologyMultiStateSimulationUnit)[0] with tmpdir.as_cwd(): setup_results = dag_setup_unit.run(dry=True) input_box = a2a_protein_membrane_component.box_vectors system_box = from_openmm(setup_results["hybrid_system"].getDefaultPeriodicBoxVectors()) assert_allclose(system_box, input_box, atol=1e-5) sim_results = dag_sim_unit.run( system=setup_results["hybrid_system"], positions=setup_results["hybrid_positions"], selection_indices=setup_results["selection_indices"], dry=True, ) sampler = sim_results["sampler"] assert isinstance(sampler, MultiStateSampler) assert sampler.is_periodic assert isinstance(sampler._thermodynamic_states[0].barostat, MonteCarloMembraneBarostat) assert sampler._thermodynamic_states[1].pressure == 1 * omm_unit.bar # Check we have the right number of atoms in the PDB pdb = mdt.load_pdb("hybrid_system.pdb") # 39391 protein + membrane + water atoms # 36 ligand atoms assert pdb.n_atoms == 39427 box = sampler._thermodynamic_states[0].system.getDefaultPeriodicBoxVectors() vectors = from_openmm(box) # convert to a Quantity array # Extract box lengths in nanometers width_x, width_y, width_z = [v[i].to("nanometer").m for i, v in enumerate(vectors)] # Expected orthogonal box (axis-aligned) expected_vectors = ( np.array( [ [width_x, 0, 0], [0, width_y, 0], [0, 0, width_z], ] ) * unit.nanometer ) assert_allclose( vectors, expected_vectors, atol=1e-5, err_msg=f"Box is not orthogonal:\n{vectors}" ) def test_lambda_schedule_default(): lambdas = openmm_rfe._rfe_utils.lambdaprotocol.LambdaProtocol(functions="default") assert len(lambdas.lambda_schedule) == 10 @pytest.mark.parametrize("windows", [11, 6, 9000]) def test_lambda_schedule(windows): lambdas = openmm_rfe._rfe_utils.lambdaprotocol.LambdaProtocol( functions="default", windows=windows ) assert len(lambdas.lambda_schedule) == windows def test_setup_ligand_overlap_warning( benzene_vacuum_system, toluene_vacuum_system, benzene_to_toluene_mapping, vac_settings, tmp_path ): protocol = openmm_rfe.RelativeHybridTopologyProtocol( settings=vac_settings, ) # update atom positions sysA = benzene_vacuum_system rdmol = benzene_vacuum_system["ligand"].to_rdkit() conf = rdmol.GetConformer() for atm in range(rdmol.GetNumAtoms()): x, y, z = conf.GetAtomPosition(atm) conf.SetAtomPosition(atm, Point3D(x + 3, y, z)) new_ligand = openfe.SmallMoleculeComponent.from_rdkit( rdmol, name=benzene_vacuum_system["ligand"].name ) components = dict(benzene_vacuum_system.components) components["ligand"] = new_ligand sysA = openfe.ChemicalSystem(components) mapping = benzene_to_toluene_mapping.copy_with_replacements(componentA=new_ligand) # Specifically check that the first pair throws a warning with pytest.warns(UserWarning, match="0 : 4 deviates"): dag = protocol.create( stateA=sysA, stateB=toluene_vacuum_system, mapping=mapping, ) dag_setup_unit = [ pu for pu in dag.protocol_units if isinstance(pu, HybridTopologySetupUnit) ][0] dag_setup_unit.run(dry=True, scratch_basepath=tmp_path, shared_basepath=tmp_path) @pytest.fixture def solvent_protocol_dag(benzene_system, toluene_system, benzene_to_toluene_mapping): settings = openmm_rfe.RelativeHybridTopologyProtocol.default_settings() protocol = openmm_rfe.RelativeHybridTopologyProtocol( settings=settings, ) return protocol.create( stateA=benzene_system, stateB=toluene_system, mapping=benzene_to_toluene_mapping, ) @pytest.fixture() def unit_mock_patcher(): with ( mock.patch( "openfe.protocols.openmm_rfe.hybridtop_units.HybridTopologySetupUnit.run", return_value={ "system": Path("system.xml.bz2"), "positions": Path("positions.npy"), "pdb_structure": Path("hybrid_system.pdb"), "selection_indices": np.zeros(100), "gufe_version": gufe.__version__, "openfe_version": openfe.__version__, "openmm_version": openmm.__version__, }, ), mock.patch( "openfe.protocols.openmm_rfe.hybridtop_units.np.load", return_value=np.zeros(100), ), mock.patch( "openfe.protocols.openmm_rfe.hybridtop_units.deserialize", return_value={ "item": "foo", }, ), mock.patch( "openfe.protocols.openmm_rfe.hybridtop_units.HybridTopologyMultiStateSimulationUnit.run", return_value={ "nc": Path("file.nc"), "checkpoint": Path("chk.chk"), }, ), mock.patch( "openfe.protocols.openmm_rfe.hybridtop_units.HybridTopologyMultiStateAnalysisUnit.run", return_value={ "foo": "bar", }, ), ): yield def test_unit_tagging(solvent_protocol_dag, unit_mock_patcher, tmp_path): # test that executing the Units includes correct generation and repeat info dag_units = solvent_protocol_dag.protocol_units setup_results = {} sim_results = {} analysis_results = {} setup_units = _get_units(dag_units, HybridTopologySetupUnit) sim_units = _get_units(dag_units, HybridTopologyMultiStateSimulationUnit) analysis_units = _get_units(dag_units, HybridTopologyMultiStateAnalysisUnit) for u in setup_units: rid = u.inputs["repeat_id"] setup_results[rid] = u.execute(context=gufe.Context(tmp_path, tmp_path)) for u in sim_units: rid = u.inputs["repeat_id"] sim_results[rid] = u.execute( context=gufe.Context(tmp_path, tmp_path), setup_results=setup_results[rid] ) for u in analysis_units: rid = u.inputs["repeat_id"] analysis_results[rid] = u.execute( context=gufe.Context(tmp_path, tmp_path), setup_results=setup_results[rid], simulation_results=sim_results[rid], ) for results in [setup_results, sim_results, analysis_results]: for ret in results.values(): assert isinstance(ret, gufe.ProtocolUnitResult) assert ret.outputs["generation"] == 0 # repeats are random ints, so check we got 3 individual numbers assert len(setup_results) == len(sim_results) == len(analysis_results) == 3 def test_gather(solvent_protocol_dag, unit_mock_patcher, tmp_path): # check .gather behaves as expected dagres = gufe.protocols.execute_DAG( solvent_protocol_dag, shared_basedir=tmp_path, scratch_basedir=tmp_path, keep_shared=True, ) prot = openmm_rfe.RelativeHybridTopologyProtocol( settings=openmm_rfe.RelativeHybridTopologyProtocol.default_settings() ) res = prot.gather([dagres]) assert isinstance(res, openmm_rfe.RelativeHybridTopologyProtocolResult) class TestConstraintRemoval: @staticmethod def make_systems( ligA: openfe.SmallMoleculeComponent, ligB: openfe.SmallMoleculeComponent, constraints, ): """Make vacuum system for each, return Topology and System for each""" omm_forcefield_A = app.ForceField("tip3p.xml") smirnoff_A = SMIRNOFFTemplateGenerator( forcefield="openff-2.0.0.offxml", molecules=[ligA.to_openff()], ) omm_forcefield_A.registerTemplateGenerator(smirnoff_A.generator) omm_forcefield_B = app.ForceField("tip3p.xml") smirnoff_B = SMIRNOFFTemplateGenerator( forcefield="openff-2.0.0.offxml", molecules=[ligB.to_openff()], ) omm_forcefield_B.registerTemplateGenerator(smirnoff_B.generator) stateA_modeller = app.Modeller( ligA.to_openff().to_topology().to_openmm(), ensure_quantity(ligA.to_openff().conformers[0], "openmm"), ) stateA_topology = stateA_modeller.getTopology() stateA_system = omm_forcefield_A.createSystem( stateA_topology, nonbondedMethod=app.CutoffNonPeriodic, nonbondedCutoff=ensure_quantity(1.1 * unit.nm, "openmm"), constraints=constraints, rigidWater=True, hydrogenMass=None, removeCMMotion=True, ) stateB_topology, _ = openmm_rfe._rfe_utils.topologyhelpers.combined_topology( stateA_topology, ligB.to_openff().to_topology().to_openmm(), exclude_resids=np.array([r.index for r in list(stateA_topology.residues())]), ) # since we're doing a swap of the only molecule, this is equivalent: # stateB_topology = app.Modeller( # sysB['ligand'].to_openff().to_topology().to_openmm(), # ensure_quantity(sysB['ligand'].to_openff().conformers[0], 'openmm') # ) stateB_system = omm_forcefield_B.createSystem( stateB_topology, nonbondedMethod=app.CutoffNonPeriodic, nonbondedCutoff=ensure_quantity(1.1 * unit.nm, "openmm"), constraints=constraints, rigidWater=True, hydrogenMass=None, removeCMMotion=True, ) return stateA_topology, stateA_system, stateB_topology, stateB_system @pytest.mark.parametrize("reverse", [False, True]) def test_remove_constraints_lengthchange(self, benzene_modifications, reverse): # check that mappings are correctly corrected to avoid changes in # constraint length # use a phenol->toluene transform to test ligA = benzene_modifications["phenol"] ligB = benzene_modifications["toluene"] mapping = { 0: 4, 1: 5, 2: 6, 3: 7, 4: 8, 5: 9, 6: 10, 7: 11, 8: 12, 9: 13, 10: 1, 11: 14, 12: 2, } # fmt: skip expected = 10 # this should get removed from mapping if reverse: ligA, ligB = ligB, ligA expected = mapping[expected] mapping = {v: k for k, v in mapping.items()} mapping = setup.LigandAtomMapping( componentA=ligA, componentB=ligB, # this is default lomap # importantly the H in -OH maps to one of the -CH3 # this constraint will change length componentA_to_componentB=mapping, ) stateA_topology, stateA_system, stateB_topology, stateB_system = self.make_systems( ligA, ligB, constraints=app.HBonds ) # this normally requires global indices, however as ligandA/B is only thing # in system, this mapping is still correct ret = openmm_rfe._rfe_utils.topologyhelpers._remove_constraints( mapping.componentA_to_componentB, stateA_system, stateA_topology, stateB_system, stateB_topology, ) # all of this just to check that an entry was removed from the mapping # the removed constraint assert expected not in ret # but only one constraint should be removed assert len(ret) == len(mapping.componentA_to_componentB) - 1 @pytest.mark.parametrize("reverse", [False, True]) def test_constraint_to_harmonic(self, benzene_modifications, reverse): ligA = benzene_modifications["benzene"] ligB = benzene_modifications["toluene"] expected = 10 mapping = { 0: 4, 1: 5, 2: 6, 3: 7, 4: 8, 5: 9, 6: 10, 7: 11, 8: 12, 9: 13, 10: 2, 11: 14 } # fmt: skip if reverse: ligA, ligB = ligB, ligA expected = mapping[expected] mapping = {v: k for k, v in mapping.items()} # this maps a -H to a -C, so the constraint on -H turns into a C-C bond # H constraint is A(4, 10) and C-C is B(8, 2) mapping = setup.LigandAtomMapping( componentA=ligA, componentB=ligB, componentA_to_componentB=mapping ) stateA_topology, stateA_system, stateB_topology, stateB_system = self.make_systems( ligA, ligB, constraints=app.HBonds ) ret = openmm_rfe._rfe_utils.topologyhelpers._remove_constraints( mapping.componentA_to_componentB, stateA_system, stateA_topology, stateB_system, stateB_topology, ) assert expected not in ret assert len(ret) == len(mapping.componentA_to_componentB) - 1 @pytest.mark.parametrize("reverse", [False, True]) def test_constraint_to_harmonic_nitrile(self, benzene_modifications, reverse): # same as previous test, but ligands are swapped # this follows a slightly different code path ligA = benzene_modifications["toluene"] ligB = benzene_modifications["benzonitrile"] if reverse: ligA, ligB = ligB, ligA mapping = { 0: 0, 2: 1, 4: 2, 5: 3, 6: 4, 7: 5, 8: 6, 9: 7, 10: 8, 11: 9, 12: 10, 13: 11, 14: 12, } # fmt: skip if reverse: mapping = {v: k for k, v in mapping.items()} mapping = setup.LigandAtomMapping( componentA=ligA, componentB=ligB, componentA_to_componentB=mapping, ) stateA_topology, stateA_system, stateB_topology, stateB_system = self.make_systems( ligA, ligB, constraints=app.HBonds ) ret = openmm_rfe._rfe_utils.topologyhelpers._remove_constraints( mapping.componentA_to_componentB, stateA_system, stateA_topology, stateB_system, stateB_topology, ) assert 0 not in ret assert len(ret) == len(mapping.componentA_to_componentB) - 1 @pytest.mark.parametrize("reverse", [False, True]) def test_non_H_constraint_fail(self, benzene_modifications, reverse): # here we specify app.AllBonds constraints # in this transform, the C-C[#N] to C-C[=O] constraint changes length # indices A(8, 2) to B(6, 1) # there's no Hydrogen involved so we can't trivially figure out the # best atom to remove from mapping # (but it would be 2 [& 1] in this case..) ligA = benzene_modifications["toluene"] ligB = benzene_modifications["benzonitrile"] mapping = { 0: 0, 2: 1, 4: 2, 5: 3, 6: 4, 7: 5, 8: 6, 9: 7, 10: 8, 11: 9, 12: 10, 13: 11, 14: 12, } # fmt: skip if reverse: ligA, ligB = ligB, ligA mapping = {v: k for k, v in mapping.items()} mapping = setup.LigandAtomMapping( componentA=ligA, componentB=ligB, componentA_to_componentB=mapping, ) stateA_topology, stateA_system, stateB_topology, stateB_system = self.make_systems( ligA, ligB, constraints=app.AllBonds ) with pytest.raises(ValueError, match="resolve constraint") as e: _ = openmm_rfe._rfe_utils.topologyhelpers._remove_constraints( mapping.componentA_to_componentB, stateA_system, stateA_topology, stateB_system, stateB_topology, ) if not reverse: assert "A: 2-8 B: 1-6" in str(e) else: assert "A: 1-6 B: 2-8" in str(e) def test_double_constraint_fail(self): # make sure catch cases where a H is involved with two different unique constraints in the end states # see with resources.as_file(resources.files("openfe.tests.data.openmm_rfe")) as d: fn1 = str(d / "malt1_shapefit_Pfizer-01-01.sdf") fn2 = str(d / "malt1_shapefit_1832577-09-9.sdf") lig1 = openfe.SmallMoleculeComponent.from_sdf_file(fn1) lig2 = openfe.SmallMoleculeComponent.from_sdf_file(fn2) # mapping taken from issue mapping = setup.LigandAtomMapping( componentA=lig1, componentB=lig2, componentA_to_componentB={ 26: 28, 27: 30, 28: 29, 29: 31, 30: 27, 31: 32, 32: 38, 34: 13, 39: 40, 40: 41, 0: 0, 1: 2, 2: 1, 3: 3, 4: 6, 5: 4, 6: 5, 7: 7, 8: 8, 9: 9, 10: 10, 11: 11, 12: 23, 14: 14, 15: 15, 16: 16, 17: 17, 18: 18, 19: 19, 20: 20, 21: 21, 22: 22, } ) # fmt: skip stateA_topology, stateA_system, stateB_topology, stateB_system = self.make_systems( lig1, lig2, constraints=app.HBonds ) with pytest.raises(ValueError, match="Atom 34 was involved in 2 unique constraints"): _ = openmm_rfe._rfe_utils.topologyhelpers._remove_constraints( mapping.componentA_to_componentB, stateA_system, stateA_topology, stateB_system, stateB_topology, ) @pytest.fixture(scope="session") def tyk2_xml(tmp_path_factory): with resources.as_file(resources.files("openfe.tests.data.openmm_rfe")) as d: fn1 = str(d / "ligand_23.sdf") fn2 = str(d / "ligand_55.sdf") lig23 = openfe.SmallMoleculeComponent.from_sdf_file(fn1) lig55 = openfe.SmallMoleculeComponent.from_sdf_file(fn2) mapping = setup.LigandAtomMapping( componentA=lig23, componentB=lig55, # perses mapper output componentA_to_componentB={ 0: 0, 1: 1, 2: 2, 3: 3, 4: 4, 5: 5, 6: 6, 7: 7, 8: 8, 9: 9, 10: 10, 11: 11, 12: 12, 13: 13, 14: 14, 15: 15, 16: 16, 17: 17, 18: 18, 23: 19, 26: 20, 27: 21, 28: 22, 29: 23, 30: 24, 31: 25, 32: 26, 33: 27, } ) # fmt: skip vac_settings = openmm_rfe.RelativeHybridTopologyProtocol.default_settings() vac_settings.forcefield_settings.nonbonded_method = "nocutoff" vac_settings.engine_settings.compute_platform = None vac_settings.forcefield_settings.small_molecule_forcefield = "openff-2.0.0" vac_settings.forcefield_settings.hydrogen_mass = 3.0 vac_settings.protocol_repeats = 1 protocol = openmm_rfe.RelativeHybridTopologyProtocol(vac_settings) dag = protocol.create( stateA=openfe.ChemicalSystem({"ligand": lig23}), stateB=openfe.ChemicalSystem({"ligand": lig55}), mapping=mapping, ) dag_setup_unit = _get_units(dag.protocol_units, HybridTopologySetupUnit)[0] tmp = tmp_path_factory.mktemp("xml_reg") setup_results = dag_setup_unit.run(dry=True, shared_basepath=tmp) system = setup_results["hybrid_system"] return ET.fromstring(XmlSerializer.serialize(system)) @pytest.fixture(scope="session") def tyk2_reference_xml(): with resources.as_file(resources.files("openfe.tests.data.openmm_rfe")) as d: f = d / "reference.xml" with open(f, "r") as i: xmldata = i.read() return ET.fromstring(xmldata) @pytest.mark.slow class TestTyk2XmlRegression: """Generates Hybrid system XML and performs regression test""" @staticmethod def test_particles(tyk2_xml, tyk2_reference_xml): # < Particle mass = "10.018727" / > particles = tyk2_xml.find("Particles") assert particles ref_particles = tyk2_reference_xml.find("Particles") for a, b in zip(particles, ref_particles): assert float(a.get("mass")) == pytest.approx(float(b.get("mass"))) @staticmethod def test_constraints(tyk2_xml, tyk2_reference_xml): # constraints = tyk2_xml.find("Constraints") assert constraints ref_constraints = tyk2_reference_xml.find("Constraints") for a, b in zip(constraints, ref_constraints): assert a.get("p1") == b.get("p1") assert a.get("p2") == b.get("p2") assert float(a.get("d")) == pytest.approx(float(b.get("d"))) class TestProtocolResult: @pytest.fixture() def protocolresult(self, rfe_transformation_json): d = json.loads(rfe_transformation_json, cls=gufe.tokenization.JSON_HANDLER.decoder) pr = openfe.ProtocolResult.from_dict(d["protocol_result"]) return pr def test_reload_protocol_result(self, rfe_transformation_json): d = json.loads(rfe_transformation_json, cls=gufe.tokenization.JSON_HANDLER.decoder) pr = openmm_rfe.RelativeHybridTopologyProtocolResult.from_dict(d["protocol_result"]) assert pr def test_get_estimate(self, protocolresult): est = protocolresult.get_estimate() assert est assert est.m == pytest.approx(16.85, abs=0.3) assert isinstance(est, unit.Quantity) assert est.is_compatible_with(unit.kilojoule_per_mole) def test_get_uncertainty(self, protocolresult): est = protocolresult.get_uncertainty() assert est assert est.m == pytest.approx(0.1, abs=0.2) assert isinstance(est, unit.Quantity) assert est.is_compatible_with(unit.kilojoule_per_mole) def test_get_individual(self, protocolresult): inds = protocolresult.get_individual_estimates() assert isinstance(inds, list) assert len(inds) == 3 for e, u in inds: assert e.is_compatible_with(unit.kilojoule_per_mole) assert u.is_compatible_with(unit.kilojoule_per_mole) def test_get_forwards_etc(self, protocolresult): far = protocolresult.get_forward_and_reverse_energy_analysis() assert isinstance(far, list) far1 = far[0] assert isinstance(far1, dict) for k in ["fractions", "forward_DGs", "forward_dDGs", "reverse_DGs", "reverse_dDGs"]: assert k in far1 if k == "fractions": assert isinstance(far1[k], np.ndarray) else: assert isinstance(far1[k], unit.Quantity) assert far1[k].is_compatible_with(unit.kilojoule_per_mole) def test_none_foward_reverse_energies(self, protocolresult): # get the first entry's results data = [i for i in protocolresult.data.values()][0][0] # set the forward and reverse analysis to None data.outputs["forward_and_reverse_energies"] = None # now call the getter and expect a user warning wmsg = "One or more ``None`` entries were found in" with pytest.warns(UserWarning, match=wmsg): protocolresult.get_forward_and_reverse_energy_analysis() def test_get_overlap_matrices(self, protocolresult): ovp = protocolresult.get_overlap_matrices() assert isinstance(ovp, list) assert len(ovp) == 3 ovp1 = ovp[0] assert isinstance(ovp1["matrix"], np.ndarray) assert ovp1["matrix"].shape == (11, 11) def test_get_replica_transition_statistics(self, protocolresult): rpx = protocolresult.get_replica_transition_statistics() assert isinstance(rpx, list) assert len(rpx) == 3 rpx1 = rpx[0] assert "eigenvalues" in rpx1 assert "matrix" in rpx1 assert rpx1["eigenvalues"].shape == (11,) assert rpx1["matrix"].shape == (11, 11) def test_equilibration_iterations(self, protocolresult): eq = protocolresult.equilibration_iterations() assert isinstance(eq, list) assert len(eq) == 3 assert all(isinstance(v, float) for v in eq) def test_production_iterations(self, protocolresult): prod = protocolresult.production_iterations() assert isinstance(prod, list) assert len(prod) == 3 assert all(isinstance(v, float) for v in prod) def test_filenotfound_replica_states(self, protocolresult): errmsg = "File could not be found" with pytest.raises(ValueError, match=errmsg): protocolresult.get_replica_states() @pytest.fixture(scope="session") def benzene_solvent_openmm_system(benzene_modifications): smc = benzene_modifications["benzene"] offmol = smc.to_openff() settings = openmm_rfe.RelativeHybridTopologyProtocol.default_settings() system_generator = system_creation.get_system_generator( forcefield_settings=settings.forcefield_settings, integrator_settings=settings.integrator_settings, thermo_settings=settings.thermo_settings, cache=None, has_solvent=True, ) system_generator.create_system( offmol.to_topology().to_openmm(), molecules=[offmol], ) modeller, _ = system_creation.get_omm_modeller( protein_comp=None, solvent_comp=openfe.SolventComponent(), small_mols={smc: offmol}, omm_forcefield=system_generator.forcefield, solvent_settings=settings.solvation_settings, ) topology = modeller.getTopology() positions = to_openmm(from_openmm(modeller.getPositions())) system = system_generator.create_system(topology, molecules=[offmol]) return system, topology, positions @pytest.fixture(scope="session") def benzene_tip4p_solvent_openmm_system(benzene_modifications): smc = benzene_modifications["benzene"] offmol = smc.to_openff() settings = openmm_rfe.RelativeHybridTopologyProtocol.default_settings() settings.forcefield_settings.forcefields = [ "amber/ff14SB.xml", "amber/tip4pew_standard.xml", "amber/phosaa10.xml", ] settings.solvation_settings.solvent_model = "tip4pew" system_generator = system_creation.get_system_generator( forcefield_settings=settings.forcefield_settings, integrator_settings=settings.integrator_settings, thermo_settings=settings.thermo_settings, cache=None, has_solvent=True, ) system_generator.create_system( offmol.to_topology().to_openmm(), molecules=[offmol], ) modeller, _ = system_creation.get_omm_modeller( protein_comp=None, solvent_comp=openfe.SolventComponent(), small_mols={smc: offmol}, omm_forcefield=system_generator.forcefield, solvent_settings=settings.solvation_settings, ) topology = modeller.getTopology() positions = to_openmm(from_openmm(modeller.getPositions())) system = system_generator.create_system(topology, molecules=[offmol]) return system, topology, positions @pytest.fixture def benzene_self_system_mapping(benzene_solvent_openmm_system): """ A fictitious mapping of benzene to benzene where there is no alchemical transformation (this technically doesn't work in practice because the RFE protocol expects an alchemical component). """ system, topology, positions = benzene_solvent_openmm_system res = [r for r in topology.residues()] benzene_res = [r for r in res if r.name == "UNK"][0] benzene_ids = [a.index for a in benzene_res.atoms()] env_ids = [a.index for a in topology.atoms() if a.index not in benzene_ids] all_ids = [a.index for a in topology.atoms()] system_mapping = { "new_to_old_atom_map": {i: i for i in all_ids}, "old_to_new_atom_map": {i: i for i in all_ids}, "new_to_old_core_atom_map": {i: i for i in benzene_ids}, "old_to_new_core_atom_map": {i: i for i in benzene_ids}, "old_to_new_env_atom_map": {i: i for i in env_ids}, "new_to_old_env_atom_map": {i: i for i in env_ids}, "old_mol_indices": benzene_ids, "new_mol_indices": benzene_ids, } return system_mapping @pytest.mark.parametrize( "ion, water", [ ["NA", "SOL"], ["NX", "WAT"], ], ) def test_get_ion_water_parameters_unknownresname(ion, water, benzene_solvent_openmm_system): system, topology, positions = benzene_solvent_openmm_system errmsg = "Error encountered when attempting to explicitly handle" with pytest.raises(ValueError, match=errmsg): topologyhelpers._get_ion_and_water_parameters( topology, system, ion_resname=ion, water_resname=water ) def test_get_alchemical_waters_no_waters( benzene_solvent_openmm_system, ): system, topology, positions = benzene_solvent_openmm_system errmsg = "There are no waters" with pytest.raises(ValueError, match=errmsg): topologyhelpers.get_alchemical_waters( topology, positions, charge_difference=1, distance_cutoff=3.0 * unit.nanometer ) def test_handle_alchemwats_incorrect_count( benzene_solvent_openmm_system, ): """ Check that an error is thrown when charge_difference != len(water_resids) """ system, topology, positions = benzene_solvent_openmm_system errmsg = "There should be as many alchemical water residues:" with pytest.raises(ValueError, match=errmsg): topologyhelpers.handle_alchemical_waters( water_resids=[1, 2, 3], topology=topology, system=system, system_mapping={}, charge_difference=1, solvent_component=openfe.SolventComponent(), ) def test_handle_alchemwats_too_many_nbf( benzene_solvent_openmm_system, ): """ Check that an error is thrown when there are multiple NonbondedForces """ system, topology, positions = benzene_solvent_openmm_system new_system = copy.deepcopy(system) new_system.addForce(NonbondedForce()) errmsg = "Too many NonbondedForce forces" with pytest.raises(ValueError, match=errmsg): topologyhelpers.handle_alchemical_waters( water_resids=[1], topology=topology, system=new_system, system_mapping={}, charge_difference=1, solvent_component=openfe.SolventComponent(), ) def test_handle_alchemwats_vsite_water( benzene_tip4p_solvent_openmm_system, ): """ Check that an error is thrown when trying to use a 4 site water as an alchemical species """ system, topology, positions = benzene_tip4p_solvent_openmm_system errmsg = "Non 3-site waters" with pytest.raises(ValueError, match=errmsg): topologyhelpers.handle_alchemical_waters( water_resids=[1], topology=topology, system=system, system_mapping={}, charge_difference=1, solvent_component=openfe.SolventComponent(), ) def test_handle_alchemwats_incorrect_atom( benzene_solvent_openmm_system, benzene_self_system_mapping, ): """ Check that an error is thrown when charge_difference != len(water_resids) """ system, topology, positions = benzene_solvent_openmm_system # modify the charge of hydrogen atom 25 new_system = copy.deepcopy(system) # protect the session scoped object nbf = [i for i in new_system.getForces() if isinstance(i, NonbondedForce)][0] c, s, e = nbf.getParticleParameters(25) nbf.setParticleParameters(25, 1 * omm_unit.elementary_charge, s, e) errmsg = "modifying an atom that doesn't match" with pytest.raises(ValueError, match=errmsg): topologyhelpers.handle_alchemical_waters( water_resids=[5], topology=topology, system=new_system, system_mapping=benzene_self_system_mapping, charge_difference=1, solvent_component=openfe.SolventComponent(), ) def test_handle_alchemical_wats( benzene_solvent_openmm_system, benzene_self_system_mapping, ): system, topology, positions = benzene_solvent_openmm_system n_env = len(benzene_self_system_mapping["old_to_new_env_atom_map"]) n_core = len(benzene_self_system_mapping["old_to_new_core_atom_map"]) topologyhelpers.handle_alchemical_waters( water_resids=[5], topology=topology, system=system, system_mapping=benzene_self_system_mapping, charge_difference=1, solvent_component=openfe.SolventComponent(), ) # check the mappings old_new_env = benzene_self_system_mapping["old_to_new_env_atom_map"] old_new_core = benzene_self_system_mapping["old_to_new_core_atom_map"] assert len(old_new_env) == n_env - 3 assert old_new_env == benzene_self_system_mapping["new_to_old_env_atom_map"] assert len(old_new_core) == n_core + 3 assert old_new_core == benzene_self_system_mapping["new_to_old_core_atom_map"] expected_old_new_core = {i: i for i in range(12)} | {24: 24, 25: 25, 26: 26} assert old_new_core == expected_old_new_core # system parameters checks nbf = [i for i in system.getForces() if isinstance(i, NonbondedForce)][0] # check the oxygen parameters i_chg, i_sig, i_eps, o_chg, h_chg = topologyhelpers._get_ion_and_water_parameters( topology, system, "NA", "HOH" ) charge, sigma, epsilon = nbf.getParticleParameters(24) assert charge == 1.0 * omm_unit.elementary_charge == i_chg assert sigma == i_sig assert epsilon == i_eps # check the hydrogen parameters for i in [25, 26]: charge, _, _ = nbf.getParticleParameters(i) assert charge == 0.0 * omm_unit.elementary_charge def _assert_total_charge(system, atom_classes, chgA, chgB): nonbond = [f for f in system.getForces() if isinstance(f, NonbondedForce)] offsets = {} for i in range(nonbond[0].getNumParticleParameterOffsets()): offset = nonbond[0].getParticleParameterOffset(i) assert len(offset) == 5 offsets[offset[1]] = ensure_quantity(offset[2], "openff") stateA_charges = np.zeros(system.getNumParticles()) stateB_charges = np.zeros(system.getNumParticles()) for i in range(system.getNumParticles()): # get the particle charge (c) and the chargeScale offset (c_offset) c, s, e = nonbond[0].getParticleParameters(i) c = ensure_quantity(c, "openff") # particle charge (c) is equal to molA particle charge # offset (c_offset) is equal to -(molA particle charge) if i in atom_classes["unique_old_atoms"]: stateA_charges[i] = c.m # particle charge (c) is equal to 0 # offset (c_offset) is equal to molB particle charge elif i in atom_classes["unique_new_atoms"]: stateB_charges[i] = offsets[i].m # particle charge (c) is equal to molA particle charge # offset (c_offset) is equal to difference between molB and molA elif i in atom_classes["core_atoms"]: stateA_charges[i] = c.m stateB_charges[i] = c.m + offsets[i].m # an environment atom else: assert i in atom_classes["environment_atoms"] stateA_charges[i] = c.m stateB_charges[i] = c.m assert chgA == pytest.approx(np.sum(stateA_charges)) assert chgB == pytest.approx(np.sum(stateB_charges)) def test_dry_run_alchemwater_solvent(benzene_to_benzoic_mapping, solv_settings, tmp_path): stateA_system = openfe.ChemicalSystem( { "ligand": benzene_to_benzoic_mapping.componentA, "solvent": openfe.SolventComponent(), } ) stateB_system = openfe.ChemicalSystem( { "ligand": benzene_to_benzoic_mapping.componentB, "solvent": openfe.SolventComponent(), } ) solv_settings.alchemical_settings.explicit_charge_correction = True protocol = openmm_rfe.RelativeHybridTopologyProtocol( settings=solv_settings, ) # create DAG from protocol and take first (and only) work unit from within dag = protocol.create( stateA=stateA_system, stateB=stateB_system, mapping=benzene_to_benzoic_mapping, ) dag_setup_unit = _get_units(dag.protocol_units, HybridTopologySetupUnit)[0] results = dag_setup_unit.run(dry=True, scratch_basepath=tmp_path, shared_basepath=tmp_path) htf = results["hybrid_factory"] _assert_total_charge(htf.hybrid_system, htf._atom_classes, 0, 0) assert len(htf._atom_classes["core_atoms"]) == 14 assert len(htf._atom_classes["unique_new_atoms"]) == 3 assert len(htf._atom_classes["unique_old_atoms"]) == 1 @pytest.mark.slow @pytest.mark.parametrize( "mapping_name,chgA,chgB,correction,core_atoms,new_uniq,old_uniq", [ ["benzene_to_aniline_mapping", 0, 1, False, 11, 4, 1], ["aniline_to_benzene_mapping", 0, 0, True, 14, 1, 4], ["aniline_to_benzene_mapping", 0, -1, False, 11, 1, 4], ["benzene_to_benzoic_mapping", 0, 0, True, 14, 3, 1], ["benzene_to_benzoic_mapping", 0, -1, False, 11, 3, 1], ["benzoic_to_benzene_mapping", 0, 0, True, 14, 1, 3], ["benzoic_to_benzene_mapping", 0, 1, False, 11, 1, 3], ], ) def test_setup_complex_alchemwater_totcharge( mapping_name, chgA, chgB, correction, core_atoms, new_uniq, old_uniq, tmp_path, request, T4_protein_component, solv_settings, ): mapping = request.getfixturevalue(mapping_name) solvent = openfe.SolventComponent() stateA_system = openfe.ChemicalSystem( { "ligand": mapping.componentA, "solvent": solvent, "protein": T4_protein_component, } ) stateB_system = openfe.ChemicalSystem( { "ligand": mapping.componentB, "solvent": solvent, "protein": T4_protein_component, } ) solv_settings.solvation_settings.solvent_padding = "0.9 nm" solv_settings.solvation_settings.box_shape = "dodecahedron" solv_settings.alchemical_settings.explicit_charge_correction = correction protocol = openmm_rfe.RelativeHybridTopologyProtocol( settings=solv_settings, ) # create DAG from protocol and take first (and only) work unit from within dag = protocol.create( stateA=stateA_system, stateB=stateB_system, mapping=mapping, ) dag_setup_unit = _get_units(dag.protocol_units, HybridTopologySetupUnit)[0] setup_results = dag_setup_unit.run( dry=True, scratch_basepath=tmp_path, shared_basepath=tmp_path ) htf = setup_results["hybrid_factory"] _assert_total_charge(htf.hybrid_system, htf._atom_classes, chgA, chgB) assert len(htf._atom_classes["core_atoms"]) == core_atoms assert len(htf._atom_classes["unique_new_atoms"]) == new_uniq assert len(htf._atom_classes["unique_old_atoms"]) == old_uniq def test_structural_analysis_error(tmp_path): ret = openmm_rfe.hybridtop_units.HybridTopologyMultiStateAnalysisUnit._structural_analysis( Path(tmp_path), Path(tmp_path), Path(tmp_path), True, ) assert "structural_analysis_error" in ret assert "structural_analysis" not in ret @pytest.mark.parametrize( "positions_write_frequency,velocities_write_frequency", [ [100 * unit.picosecond, None], [None, None], [None, 100 * unit.picosecond], ], ) def test_dry_run_vacuum_write_frequency( benzene_vacuum_system, toluene_vacuum_system, benzene_to_toluene_mapping, positions_write_frequency, velocities_write_frequency, vac_settings, tmp_path, ): vac_settings.output_settings.positions_write_frequency = positions_write_frequency vac_settings.output_settings.velocities_write_frequency = velocities_write_frequency # set the time per iteration to 1 to get the expected outputs vac_settings.simulation_settings.time_per_iteration = 1 * unit.picosecond protocol = openmm_rfe.RelativeHybridTopologyProtocol( settings=vac_settings, ) # create DAG from protocol and take first (and only) work unit from within dag = protocol.create( stateA=benzene_vacuum_system, stateB=toluene_vacuum_system, mapping=benzene_to_toluene_mapping, ) dag_setup_unit = _get_units(dag.protocol_units, HybridTopologySetupUnit)[0] dag_sim_unit = _get_units(dag.protocol_units, HybridTopologyMultiStateSimulationUnit)[0] # Manually run the units setup_results = dag_setup_unit.run( dry=True, scratch_basepath=tmp_path, shared_basepath=tmp_path ) sim_results = dag_sim_unit.run( system=setup_results["hybrid_system"], positions=setup_results["hybrid_positions"], selection_indices=setup_results["selection_indices"], dry=True, scratch_basepath=tmp_path, shared_basepath=tmp_path, ) sampler = sim_results["sampler"] reporter = sampler._reporter if positions_write_frequency: assert reporter.position_interval == positions_write_frequency.m else: assert reporter.position_interval == 0 if velocities_write_frequency: assert reporter.velocity_interval == velocities_write_frequency.m else: assert reporter.velocity_interval == 0 ================================================ FILE: src/openfe/tests/protocols/openmm_rfe/test_hybrid_top_resume.py ================================================ # This code is part of OpenFE and is licensed under the MIT license. # For details, see https://github.com/OpenFreeEnergy/openfe import copy import logging import os import pathlib import shutil import gufe import numpy as np import openmm import pooch import pytest from gufe.protocols import execute_DAG from gufe.protocols.errors import ProtocolUnitExecutionError from numpy.testing import assert_allclose from openfe_analysis.utils.multistate import _determine_position_indices from openff.units import unit as offunit from openff.units.openmm import from_openmm from openmmtools.multistate import MultiStateReporter import openfe from openfe.data._registry import POOCH_CACHE from openfe.protocols import openmm_rfe from openfe.protocols.openmm_rfe._rfe_utils.multistate import HybridRepexSampler from openfe.protocols.openmm_rfe.hybridtop_units import ( HybridTopologyMultiStateAnalysisUnit, HybridTopologyMultiStateSimulationUnit, HybridTopologySetupUnit, ) from ...conftest import HAS_INTERNET from .test_hybrid_top_protocol import _get_units @pytest.fixture() def protocol_settings(): settings = openmm_rfe.RelativeHybridTopologyProtocol.default_settings() settings.solvation_settings.solvent_padding = None settings.solvation_settings.number_of_solvent_molecules = 750 settings.solvation_settings.box_shape = "dodecahedron" settings.protocol_repeats = 1 settings.simulation_settings.equilibration_length = 100 * offunit.picosecond settings.simulation_settings.production_length = 200 * offunit.picosecond settings.simulation_settings.time_per_iteration = 2.5 * offunit.picosecond settings.output_settings.checkpoint_interval = 100 * offunit.picosecond settings.engine_settings.compute_platform = None return settings def test_verify_execution_environment(): # Verification should pass openmm_rfe.HybridTopologyMultiStateSimulationUnit._verify_execution_environment( setup_outputs={ "gufe_version": gufe.__version__, "openfe_version": openfe.__version__, "openmm_version": openmm.__version__, }, ) def test_verify_execution_environment_fail(): # Passing a bad version should fail with pytest.raises(ProtocolUnitExecutionError, match="Python environment"): openmm_rfe.HybridTopologyMultiStateSimulationUnit._verify_execution_environment( setup_outputs={ "gufe_version": 0.1, "openfe_version": openfe.__version__, "openmm_version": openmm.__version__, }, ) def test_verify_execution_env_missing_key(): errmsg = "Missing environment information from setup outputs." with pytest.raises(ProtocolUnitExecutionError, match=errmsg): openmm_rfe.HybridTopologyMultiStateSimulationUnit._verify_execution_environment( setup_outputs={ "foo_version": 0.1, "openfe_version": openfe.__version__, "openmm_version": openmm.__version__, }, ) @pytest.mark.skipif( not os.path.exists(POOCH_CACHE) and not HAS_INTERNET, reason="Internet unavailable and test data is not cached locally", ) def test_check_restart(protocol_settings, htop_trajectory_path): assert openmm_rfe.HybridTopologyMultiStateSimulationUnit._check_restart( output_settings=protocol_settings.output_settings, shared_path=htop_trajectory_path.parent, ) assert not openmm_rfe.HybridTopologyMultiStateSimulationUnit._check_restart( output_settings=protocol_settings.output_settings, shared_path=pathlib.Path("."), ) @pytest.mark.skipif( not os.path.exists(POOCH_CACHE) and not HAS_INTERNET, reason="Internet unavailable and test data is not cached locally", ) class TestCheckpointResuming: @pytest.fixture() def protocol_dag( self, protocol_settings, benzene_system, toluene_system, benzene_to_toluene_mapping ): protocol = openmm_rfe.RelativeHybridTopologyProtocol(settings=protocol_settings) return protocol.create( stateA=benzene_system, stateB=toluene_system, mapping=benzene_to_toluene_mapping ) @staticmethod def _check_sampler(sampler, num_iterations: int): # Helper method to do some checks on the sampler assert sampler._iteration == num_iterations assert sampler.number_of_iterations == 80 assert sampler.is_completed is (num_iterations == 80) assert sampler.n_states == sampler.n_replicas == 11 assert sampler.is_periodic assert sampler.mcmc_moves[0].n_steps == 625 assert from_openmm(sampler.mcmc_moves[0].timestep) == 4 * offunit.fs @staticmethod def _get_positions(dataset): frame_list = _determine_position_indices(dataset) positions = [] for frame in frame_list: positions.append(copy.deepcopy(dataset.variables["positions"][frame].data)) return positions @staticmethod def _copy_simfiles(basedir: pathlib.Path, filepath): shutil.copyfile(filepath, f"{basedir}/{filepath.name}") @pytest.mark.integration def test_resume(self, protocol_dag, htop_trajectory_path, htop_checkpoint_path, tmp_path): """ Attempt to resume a simulation unit with pre-existing checkpoint & trajectory files. """ # copy files self._copy_simfiles(tmp_path, htop_trajectory_path) self._copy_simfiles(tmp_path, htop_checkpoint_path) # 1. Check that the trajectory / checkpoint contain what we expect reporter = MultiStateReporter( tmp_path / "simulation.nc", checkpoint_storage="checkpoint.chk", ) sampler = HybridRepexSampler.from_storage(reporter) self._check_sampler(sampler, num_iterations=40) # Deep copy energies & positions for later tests init_energies = copy.deepcopy(reporter.read_energies())[0] assert init_energies.shape == (41, 11, 11) init_positions = self._get_positions(reporter._storage[0]) assert len(init_positions) == 2 reporter.close() del sampler # 2. get & run the units pus = list(protocol_dag.protocol_units) setup_unit = _get_units(pus, HybridTopologySetupUnit)[0] simulation_unit = _get_units(pus, HybridTopologyMultiStateSimulationUnit)[0] analysis_unit = _get_units(pus, HybridTopologyMultiStateAnalysisUnit)[0] # Dry run the setup since it'll be easier to use the objects directly setup_results = setup_unit.run( dry=True, scratch_basepath=tmp_path, shared_basepath=tmp_path ) # Now we run the simulation in resume mode sim_results = simulation_unit.run( system=setup_results["hybrid_system"], positions=setup_results["hybrid_positions"], selection_indices=setup_results["selection_indices"], scratch_basepath=tmp_path, shared_basepath=tmp_path, ) # Finally we analyze the results _ = analysis_unit.run( pdb_file=setup_results["pdb_structure"], trajectory=sim_results["nc"], checkpoint=sim_results["checkpoint"], scratch_basepath=tmp_path, shared_basepath=tmp_path, ) # 3. Analyze the trajectory/checkpoint again reporter = MultiStateReporter( tmp_path / "simulation.nc", checkpoint_storage="checkpoint.chk", ) sampler = HybridRepexSampler.from_storage(reporter) self._check_sampler(sampler, num_iterations=80) # Check the energies and positions energies = reporter.read_energies()[0] assert energies.shape == (81, 11, 11) assert_allclose(init_energies, energies[:41]) positions = self._get_positions(reporter._storage[0]) assert len(positions) == 3 for i in range(2): assert_allclose(positions[i], init_positions[i]) reporter.close() del sampler # Check the openfe-analysis outputs are there structural_analysis_file = tmp_path / "structural_analysis.npz" assert (structural_analysis_file).exists() @pytest.mark.slow def test_resume_fail_particles( self, protocol_dag, htop_trajectory_path, htop_checkpoint_path, tmp_path ): """ Test that the run unit will fail with a system incompatible to the one present in the trajectory/checkpoint files. Here we check that we don't have the same particles / mass. """ # copy files self._copy_simfiles(tmp_path, htop_trajectory_path) self._copy_simfiles(tmp_path, htop_checkpoint_path) pus = list(protocol_dag.protocol_units) setup_unit = _get_units(pus, HybridTopologySetupUnit)[0] simulation_unit = _get_units(pus, HybridTopologyMultiStateSimulationUnit)[0] # Dry run the setup since it'll be easier to use the objects directly setup_results = setup_unit.run( dry=True, scratch_basepath=tmp_path, shared_basepath=tmp_path ) # Fake system should trigger a mismatch errmsg = "Stored checkpoint System particles do not" with pytest.raises(ValueError, match=errmsg): _ = simulation_unit.run( system=openmm.System(), positions=setup_results["hybrid_positions"], selection_indices=setup_results["selection_indices"], scratch_basepath=tmp_path, shared_basepath=tmp_path, ) @pytest.mark.slow def test_resume_fail_constraints( self, protocol_dag, htop_trajectory_path, htop_checkpoint_path, tmp_path ): """ Test that the run unit will fail with a system incompatible to the one present in the trajectory/checkpoint files. Here we check that we don't have the same constraints. """ # copy files self._copy_simfiles(tmp_path, htop_trajectory_path) self._copy_simfiles(tmp_path, htop_checkpoint_path) pus = list(protocol_dag.protocol_units) setup_unit = _get_units(pus, HybridTopologySetupUnit)[0] simulation_unit = _get_units(pus, HybridTopologyMultiStateSimulationUnit)[0] # Dry run the setup since it'll be easier to use the objects directly setup_results = setup_unit.run( dry=True, scratch_basepath=tmp_path, shared_basepath=tmp_path ) # Create a fake system without constraints fake_system = copy.deepcopy(setup_results["hybrid_system"]) for i in reversed(range(fake_system.getNumConstraints())): fake_system.removeConstraint(i) # Fake system should trigger a mismatch errmsg = "Stored checkpoint System constraints do not" with pytest.raises(ValueError, match=errmsg): _ = simulation_unit.run( system=fake_system, positions=setup_results["hybrid_positions"], selection_indices=setup_results["selection_indices"], scratch_basepath=tmp_path, shared_basepath=tmp_path, ) @pytest.mark.slow def test_resume_fail_forces( self, protocol_dag, htop_trajectory_path, htop_checkpoint_path, tmp_path ): """ Test that the run unit will fail with a system incompatible to the one present in the trajectory/checkpoint files. Here we check we don't have the same forces. """ # copy files self._copy_simfiles(tmp_path, htop_trajectory_path) self._copy_simfiles(tmp_path, htop_checkpoint_path) pus = list(protocol_dag.protocol_units) setup_unit = _get_units(pus, HybridTopologySetupUnit)[0] simulation_unit = _get_units(pus, HybridTopologyMultiStateSimulationUnit)[0] # Dry run the setup since it'll be easier to use the objects directly setup_results = setup_unit.run( dry=True, scratch_basepath=tmp_path, shared_basepath=tmp_path ) # Create a fake system without the last force fake_system = copy.deepcopy(setup_results["hybrid_system"]) fake_system.removeForce(fake_system.getNumForces() - 1) # Fake system should trigger a mismatch errmsg = "Number of forces stored in checkpoint System" with pytest.raises(ValueError, match=errmsg): _ = simulation_unit.run( system=fake_system, positions=setup_results["hybrid_positions"], selection_indices=setup_results["selection_indices"], scratch_basepath=tmp_path, shared_basepath=tmp_path, ) @pytest.mark.slow def test_resume_differ_barostat( self, protocol_dag, htop_trajectory_path, htop_checkpoint_path, tmp_path ): """ Test that the run unit will fail if the barostat differs. """ # copy files self._copy_simfiles(tmp_path, htop_trajectory_path) self._copy_simfiles(tmp_path, htop_checkpoint_path) pus = list(protocol_dag.protocol_units) setup_unit = _get_units(pus, HybridTopologySetupUnit)[0] simulation_unit = _get_units(pus, HybridTopologyMultiStateSimulationUnit)[0] # Dry run the setup since it'll be easier to use the objects directly setup_results = setup_unit.run( dry=True, scratch_basepath=tmp_path, shared_basepath=tmp_path ) # Create a fake system with the fake forcetype fake_system = copy.deepcopy(setup_results["hybrid_system"]) # Loop through forces and remove the force matching force type for i, f in enumerate(fake_system.getForces()): if isinstance(f, openmm.MonteCarloBarostat): findex = i fake_system.removeForce(findex) new_force = openmm.MonteCarloBarostat( 1 * openmm.unit.atmosphere, 300 * openmm.unit.kelvin, 100 ) fake_system.addForce(new_force) # Fake system should trigger a mismatch errmsg = "stored checkpoint System does not match the same force" with pytest.raises(ValueError, match=errmsg): _ = simulation_unit.run( system=fake_system, positions=setup_results["hybrid_positions"], selection_indices=setup_results["selection_indices"], scratch_basepath=tmp_path, shared_basepath=tmp_path, ) @pytest.mark.slow def test_resume_differ_forces( self, protocol_dag, htop_trajectory_path, htop_checkpoint_path, tmp_path, caplog ): """ Test that the run unit will warn if forces don't match to the one present in the trajectory/checkpoint files. """ # copy files self._copy_simfiles(tmp_path, htop_trajectory_path) self._copy_simfiles(tmp_path, htop_checkpoint_path) pus = list(protocol_dag.protocol_units) setup_unit = _get_units(pus, HybridTopologySetupUnit)[0] simulation_unit = _get_units(pus, HybridTopologyMultiStateSimulationUnit)[0] # Dry run the setup since it'll be easier to use the objects directly setup_results = setup_unit.run( dry=True, scratch_basepath=tmp_path, shared_basepath=tmp_path ) # Create a fake system with the fake forcetype fake_system = copy.deepcopy(setup_results["hybrid_system"]) # Loop through forces and remove the force matching force type for i, f in enumerate(fake_system.getForces()): if isinstance(f, openmm.NonbondedForce): findex = i fake_system.removeForce(findex) fake_system.addForce(openmm.NonbondedForce()) # Mismatching force should trigger a warning wmsg = "does not exactly match one of the forces in the simulated System" caplog.set_level(logging.INFO) _ = simulation_unit.run( system=fake_system, positions=setup_results["hybrid_positions"], selection_indices=setup_results["selection_indices"], scratch_basepath=tmp_path, shared_basepath=tmp_path, dry=True, ) assert wmsg in caplog.text @pytest.mark.slow @pytest.mark.parametrize("bad_file", ["trajectory", "checkpoint"]) def test_resume_bad_files( self, protocol_dag, htop_trajectory_path, htop_checkpoint_path, bad_file, tmp_path ): """ Test what happens when you have a bad trajectory and/or checkpoint files. """ # copy files if bad_file == "trajectory": with open(tmp_path / "simulation.nc", "w") as f: f.write("foo") else: self._copy_simfiles(tmp_path, htop_trajectory_path) if bad_file == "checkpoint": with open(tmp_path / "checkpoint.chk", "w") as f: f.write("bar") else: self._copy_simfiles(tmp_path, htop_checkpoint_path) pus = list(protocol_dag.protocol_units) setup_unit = _get_units(pus, HybridTopologySetupUnit)[0] simulation_unit = _get_units(pus, HybridTopologyMultiStateSimulationUnit)[0] # Dry run the setup since it'll be easier to use the objects directly setup_results = setup_unit.run( dry=True, scratch_basepath=tmp_path, shared_basepath=tmp_path ) with pytest.raises(OSError, match="Unknown file format"): _ = simulation_unit.run( system=setup_results["hybrid_system"], positions=setup_results["hybrid_positions"], selection_indices=setup_results["selection_indices"], scratch_basepath=tmp_path, shared_basepath=tmp_path, ) @pytest.mark.slow @pytest.mark.parametrize("missing_file", ["trajectory", "checkpoint"]) def test_missing_file( self, protocol_dag, htop_trajectory_path, htop_checkpoint_path, missing_file, tmp_path ): """ Test that an error is thrown if either file is missing but the other isn't. """ # copy files if missing_file == "trajectory": pass else: self._copy_simfiles(tmp_path, htop_trajectory_path) if missing_file == "checkpoint": pass else: self._copy_simfiles(tmp_path, htop_checkpoint_path) pus = list(protocol_dag.protocol_units) setup_unit = _get_units(pus, HybridTopologySetupUnit)[0] simulation_unit = _get_units(pus, HybridTopologyMultiStateSimulationUnit)[0] # Dry run the setup since it'll be easier to use the objects directly setup_results = setup_unit.run( dry=True, scratch_basepath=tmp_path, shared_basepath=tmp_path ) errmsg = f"file is present but not the {missing_file} file." with pytest.raises(IOError, match=errmsg): _ = simulation_unit.run( system=setup_results["hybrid_system"], positions=setup_results["hybrid_positions"], selection_indices=setup_results["selection_indices"], scratch_basepath=tmp_path, shared_basepath=tmp_path, ) ================================================ FILE: src/openfe/tests/protocols/openmm_rfe/test_hybrid_top_slow.py ================================================ # This code is part of OpenFE and is licensed under the MIT license. # For details, see https://github.com/OpenFreeEnergy/openfe import pathlib import numpy as np import pytest from gufe.protocols import execute_DAG from numpy.testing import assert_allclose from openff.units import unit as offunit import openfe from openfe.protocols import openmm_rfe from openfe.protocols.openmm_utils.charge_generation import HAS_NAGL, HAS_OPENEYE @pytest.mark.slow @pytest.mark.flaky(reruns=3) # pytest-rerunfailures; we can get bad minimization @pytest.mark.parametrize("platform", ["CPU", "CUDA"]) def test_openmm_run_engine( benzene_vacuum_system, platform, get_available_openmm_platforms, benzene_modifications, tmp_path, ): if platform not in get_available_openmm_platforms: pytest.skip(f"OpenMM Platform: {platform} not available") # this test actually runs MD # these settings are a small self to self sim, that has enough eq that # it doesn't occasionally crash s = openfe.protocols.openmm_rfe.RelativeHybridTopologyProtocol.default_settings() s.simulation_settings.equilibration_length = 0.1 * offunit.picosecond s.simulation_settings.production_length = 0.1 * offunit.picosecond s.simulation_settings.time_per_iteration = 20 * offunit.femtosecond s.forcefield_settings.nonbonded_method = "nocutoff" s.protocol_repeats = 1 s.engine_settings.compute_platform = platform s.output_settings.checkpoint_interval = 20 * offunit.femtosecond s.output_settings.positions_write_frequency = 20 * offunit.femtosecond p = openmm_rfe.RelativeHybridTopologyProtocol(s) b = benzene_vacuum_system["ligand"] # make a copy with a different name rdmol = benzene_modifications["benzene"].to_rdkit() b_alt = openfe.SmallMoleculeComponent.from_rdkit(rdmol, name="alt") benzene_vacuum_alt_system = openfe.ChemicalSystem({"ligand": b_alt}) m = openfe.LigandAtomMapping( componentA=b, componentB=b_alt, componentA_to_componentB={i: i for i in range(12)}, ) dag = p.create( stateA=benzene_vacuum_system, stateB=benzene_vacuum_alt_system, mapping=[m], ) r = execute_DAG(dag, shared_basedir=tmp_path, scratch_basedir=tmp_path, keep_shared=True) assert r.ok() # Get the path to the simulation unit shared for pur in r.protocol_unit_results: if "Simulation" in pur.name: sim_shared = tmp_path / f"shared_{pur.source_key}_attempt_0" assert sim_shared.exists() assert pathlib.Path(sim_shared).is_dir() for pur in r.protocol_unit_results: if "Analysis" not in pur.name: continue analysis_shared = tmp_path / f"shared_{pur.source_key}_attempt_0" assert analysis_shared.exists() assert pathlib.Path(analysis_shared).is_dir() # Check the checkpoint file exists checkpoint = pur.outputs["checkpoint"] assert checkpoint.name == "checkpoint.chk" assert checkpoint == sim_shared / "checkpoint.chk" assert checkpoint.exists() # Check the nc simulation file exists # TODO: assert the number of frames nc = pur.outputs["trajectory"] assert nc.name == "simulation.nc" assert nc == sim_shared / "simulation.nc" assert nc.exists() # Check structural analysis contents structural_analysis_file = analysis_shared / "structural_analysis.npz" assert (structural_analysis_file).exists() assert pur.outputs["structural_analysis"] == structural_analysis_file structural_data = np.load(pur.outputs["structural_analysis"]) structural_keys = [ "protein_RMSD", "ligand_RMSD", "ligand_COM_drift", "protein_2D_RMSD", "time_ps", ] for key in structural_keys: assert key in structural_data.keys() # 6 frames being written to file assert_allclose(structural_data["time_ps"], [0.0, 0.02, 0.04, 0.06, 0.08, 0.1]) assert structural_data["ligand_RMSD"].shape == (11, 6) assert structural_data["ligand_COM_drift"].shape == (11, 6) # No protein so should be empty assert structural_data["protein_RMSD"].size == 0 assert structural_data["protein_2D_RMSD"].size == 0 # Test results methods that need files present results = p.gather([r]) states = results.get_replica_states() assert len(states) == 1 assert states[0].shape[1] == 11 @pytest.mark.integration # takes ~7 minutes to run @pytest.mark.flaky(reruns=3) @pytest.mark.skipif(not HAS_NAGL, reason="need NAGL") @pytest.mark.skipif( HAS_OPENEYE and HAS_NAGL, reason="NAGL/openeye incompatibility. See https://github.com/openforcefield/openff-nagl/issues/177", ) def test_run_eg5_sim(eg5_protein, eg5_ligands, eg5_cofactor, tmp_path): # this runs a very short eg5 complex leg # different to previous test: # - has a cofactor # - has an alchemical swap present # - runs in solvated protein # if this passes 99.9% chance of a good time s = openfe.protocols.openmm_rfe.RelativeHybridTopologyProtocol.default_settings() s.simulation_settings.equilibration_length = 0.1 * offunit.picosecond s.simulation_settings.production_length = 0.1 * offunit.picosecond s.simulation_settings.time_per_iteration = 20 * offunit.femtosecond s.forcefield_settings.nonbonded_cutoff = 0.8 * offunit.nanometer s.partial_charge_settings.partial_charge_method = "nagl" s.partial_charge_settings.nagl_model = "openff-gnn-am1bcc-0.1.0-rc.3.pt" s.protocol_repeats = 1 s.output_settings.checkpoint_interval = 20 * offunit.femtosecond p = openmm_rfe.RelativeHybridTopologyProtocol(s) base_sys = { "protein": eg5_protein, "cofactor": eg5_cofactor, "solvent": openfe.SolventComponent(), } # this is just a simple (unmapped) *-H -> *-F switch l1, l2 = eg5_ligands[0], eg5_ligands[1] m = openfe.LigandAtomMapping( componentA=l1, componentB=l2, # a bit lucky, first 51 atoms map to each other, H->F swap is at 52 componentA_to_componentB={i: i for i in range(51)}, ) sys1 = openfe.ChemicalSystem(components={**base_sys, "ligand": l1}) sys2 = openfe.ChemicalSystem(components={**base_sys, "ligand": l2}) dag = p.create(stateA=sys1, stateB=sys2, mapping=[m]) r = execute_DAG(dag, shared_basedir=tmp_path, scratch_basedir=tmp_path, keep_shared=True) assert r.ok() @pytest.mark.integration @pytest.mark.flaky(reruns=3) def test_run_dodecahedron_sim(benzene_system, toluene_system, benzene_to_toluene_mapping, tmp_path): """ Test that we can run a ligand in solvent RFE with a non-cubic box """ settings = openmm_rfe.RelativeHybridTopologyProtocol.default_settings() settings.solvation_settings.solvent_padding = 1.5 * offunit.nanometer settings.solvation_settings.box_shape = "dodecahedron" settings.protocol_repeats = 1 settings.simulation_settings.equilibration_length = 0.1 * offunit.picosecond settings.simulation_settings.production_length = 0.1 * offunit.picosecond settings.simulation_settings.time_per_iteration = 20 * offunit.femtosecond settings.output_settings.checkpoint_interval = 20 * offunit.femtosecond protocol = openmm_rfe.RelativeHybridTopologyProtocol(settings=settings) dag = protocol.create( stateA=benzene_system, stateB=toluene_system, mapping=benzene_to_toluene_mapping, ) r = execute_DAG( dag, shared_basedir=tmp_path, scratch_basedir=tmp_path, keep_shared=True, ) assert r.ok() ================================================ FILE: src/openfe/tests/protocols/openmm_rfe/test_hybrid_top_tokenization.py ================================================ # This code is part of OpenFE and is licensed under the MIT license. # For details, see https://github.com/OpenFreeEnergy/openfe import pytest from gufe.tests.test_tokenization import GufeTokenizableTestsMixin from openff.units import unit from openfe.protocols import openmm_rfe from openfe.protocols.openmm_rfe.hybridtop_units import ( HybridTopologyMultiStateAnalysisUnit, HybridTopologyMultiStateSimulationUnit, HybridTopologySetupUnit, ) """ todo: - RelativeHybridTopologyProtocolResult - RelativeHybridTopologyProtocol - RelativeHybridTopologyProtocolUnit """ @pytest.fixture def rfe_protocol(): return openmm_rfe.RelativeHybridTopologyProtocol( openmm_rfe.RelativeHybridTopologyProtocol.default_settings() ) @pytest.fixture def rfe_protocol_other_input_units(): """Identical to rfe_protocol, but with `kcal / mol` as input unit instead of `kilocalorie_per_mole`.""" new_settings = openmm_rfe.RelativeHybridTopologyProtocol.default_settings() new_settings.simulation_settings.early_termination_target_error = 0.0 * unit.kilocalorie/unit.mol # fmt: skip return openmm_rfe.RelativeHybridTopologyProtocol(new_settings) @pytest.fixture def protocol_units(rfe_protocol, benzene_system, toluene_system, benzene_to_toluene_mapping): pus = rfe_protocol.create( stateA=benzene_system, stateB=toluene_system, mapping=[benzene_to_toluene_mapping], ) return list(pus.protocol_units) @pytest.fixture def protocol_setup_unit(protocol_units): for pu in protocol_units: if isinstance(pu, HybridTopologySetupUnit): return pu @pytest.fixture def protocol_simulation_unit(protocol_units): for pu in protocol_units: if isinstance(pu, HybridTopologyMultiStateSimulationUnit): return pu @pytest.fixture def protocol_analysis_unit(protocol_units): for pu in protocol_units: if isinstance(pu, HybridTopologyMultiStateAnalysisUnit): return pu @pytest.mark.skip class TestRelativeHybridTopologyProtocolResult(GufeTokenizableTestsMixin): cls = openmm_rfe.RelativeHybridTopologyProtocolResult repr = "" key = "" @pytest.fixture() def instance(self): pass class TestRelativeHybridTopologyProtocolOtherInputUnits(GufeTokenizableTestsMixin): cls = openmm_rfe.RelativeHybridTopologyProtocol key = None repr = " angstrom @pytest.fixture() def default_settings(): s = SepTopProtocol.default_settings() return s def test_create_default_protocol(default_settings): # this is roughly how it should be created protocol = SepTopProtocol( settings=default_settings, ) assert protocol assert protocol.settings == default_settings def test_serialize_protocol(default_settings): protocol = SepTopProtocol( settings=default_settings, ) ser = protocol.to_dict() ret = SepTopProtocol.from_dict(ser) assert protocol == ret def test_repeat_units(benzene_complex_system, toluene_complex_system, default_settings): default_settings.protocol_repeats = 3 protocol = SepTopProtocol( settings=default_settings, ) dag = protocol.create( stateA=benzene_complex_system, stateB=toluene_complex_system, mapping=None, ) # 6 protocol unit, 3 per repeat pus = list(dag.protocol_units) assert len(pus) == 18 # Check info for each repeat for phase in ["solvent", "complex"]: setup = _get_units(pus, UNIT_TYPES[phase]["setup"]) sim = _get_units(pus, UNIT_TYPES[phase]["sim"]) analysis = _get_units(pus, UNIT_TYPES[phase]["analysis"]) # Should be 3 of each set assert len(setup) == 3 assert len(sim) == 3 assert len(analysis) == 3 # check that the dag chain is correct for analysis_pu in analysis: repeat_id = analysis_pu.inputs["repeat_id"] setup_pu = [ s for s in setup if (s.inputs["repeat_id"] == repeat_id) and (s.simtype == phase) ][0] sim_pu = [ s for s in sim if (s.inputs["repeat_id"] == repeat_id) and (s.simtype == phase) ][0] assert analysis_pu.inputs["setup"] == setup_pu assert analysis_pu.inputs["simulation"] == sim_pu assert sim_pu.inputs["setup"] == setup_pu def test_create_independent_repeat_ids( benzene_complex_system, toluene_complex_system, default_settings ): # if we create two dags each with 3 repeats, they should give 6 repeat_ids # this allows multiple DAGs in flight for one Transformation that don't clash on gather # Default protocol is 1 repeat, change to 3 repeats default_settings.protocol_repeats = 3 protocol = SepTopProtocol( settings=default_settings, ) dags = [] for i in range(2): dags.append( protocol.create( stateA=benzene_complex_system, stateB=toluene_complex_system, mapping=None, ) ) repeat_ids = set() for dag in dags: # 3 repeats of 6 units assert len(list(dag.protocol_units)) == 18 for u in dag.protocol_units: repeat_ids.add(u.inputs["repeat_id"]) # one uuid per repeat, so should equal 6 assert len(repeat_ids) == 6 # Tests for the alchemical systems. This tests were modified from # femto (https://github.com/Psivant/femto/tree/main) def compute_interaction_energy( epsilon, sigma, charge, distance, lambda_vdw: float = 1.0, lambda_charges: float = 1.0, ): r_electrostatics = distance r_vdw = (0.5 * sigma**6 * (1.0 - lambda_vdw) + distance**6) ** (1.0 / 6.0) return ( # vdw 4.0 * lambda_vdw * epsilon * ((sigma / r_vdw) ** 12 - (sigma / r_vdw) ** 6) # electrostatics + ONE_4PI_EPS0 * lambda_charges * charge / r_electrostatics ) * openmm.unit.kilojoule_per_mole @pytest.fixture def three_particle_system(): force = openmm.NonbondedForce() force.setNonbondedMethod(openmm.NonbondedForce.NoCutoff) force.setUseDispersionCorrection(False) charges = 0.1, 0.2, -0.3 sigmas = 1.1, 1.2, 1.3 epsilons = 210, 220, 230 force.addParticle(charges[0], sigmas[0] * openmm.unit.angstrom, epsilons[0]) force.addParticle(charges[1], sigmas[1] * openmm.unit.angstrom, epsilons[1]) force.addParticle(charges[2], sigmas[2] * openmm.unit.angstrom, epsilons[2]) system = openmm.System() system.addParticle(1.0) system.addParticle(1.0) system.addParticle(1.0) system.addForce(force) distances = [[0.0, 4.0, 3.0], [4.0, 0.0, 5.0], [3.0, 5.0, 0.0]] def interaction_energy_fn(idx_a, idx_b, lambda_vdw: float = 1.0, lambda_charges: float = 1.0): epsilon = np.sqrt(epsilons[idx_a] * epsilons[idx_b]) sigma = 0.5 * (sigmas[idx_a] + sigmas[idx_b]) charge = charges[idx_a] * charges[idx_b] return compute_interaction_energy( epsilon, sigma, charge, distances[idx_a][idx_b], lambda_vdw, lambda_charges ) coords = ( np.array([[0.0, 0.0, 0.0], [distances[0][1], 0.0, 0.0], [0.0, distances[0][2], 0.0]]) * openmm.unit.angstrom ) return system, coords, interaction_energy_fn class TestNonbondedInteractions: def test_one_ligand(self, three_particle_system): """Test scaling the nonbonded interactions of single particles.""" system, coords, energy_fn = three_particle_system factory = AbsoluteAlchemicalFactory(consistent_exceptions=False) alchemical_region_A = AlchemicalRegion(alchemical_atoms=[0], name="A") alchemical_system = factory.create_alchemical_system(system, [alchemical_region_A]) energy_0 = compute_energy( alchemical_system, coords, None, { "lambda_sterics_A": 1.0, "lambda_electrostatics_A": 1.0, }, ) # expect lig_1 + solvent, lig_1 + lig_2 and lig_2 + solvent # interaction when # lambda=0 expected_energy_0 = energy_fn(0, 2) + energy_fn(0, 1) + energy_fn(1, 2) assert_allclose(energy_0, from_openmm(expected_energy_0), rtol=1e-05) # expect only lig_2 + solvent interaction when lambda=1 energy_1 = compute_energy( alchemical_system, coords, None, { "lambda_sterics_A": 0.0, "lambda_electrostatics_A": 0.0, }, ) expected_energy_1 = energy_fn(1, 2) assert_allclose(energy_1, from_openmm(expected_energy_1), rtol=1e-05) # expect all particles to interact but only lig - solvent interactions to be # scaled energy_05 = compute_energy( alchemical_system, coords, None, { "lambda_sterics_A": 0.5, "lambda_electrostatics_A": 0.5, }, ) expected_energy_05 = energy_fn(1, 2) + energy_fn(0, 2, 0.5, 0.5) + energy_fn(0, 1, 0.5, 0.5) assert_allclose(energy_05, from_openmm(expected_energy_05), rtol=1e-05) def test_two_ligands(self, three_particle_system): """Test scaling the nonbonded interactions of single particles.""" system, coords, energy_fn = three_particle_system # Do it the openmm way factory = AbsoluteAlchemicalFactory(consistent_exceptions=False) alchemical_region_A = AlchemicalRegion(alchemical_atoms=[0], name="A") alchemical_region_B = AlchemicalRegion(alchemical_atoms=[1], name="B") alchemical_system = factory.create_alchemical_system( system, [alchemical_region_A, alchemical_region_B] ) energy_0 = compute_energy( alchemical_system, coords, None, { "lambda_sterics_A": 1.0, "lambda_electrostatics_A": 1.0, "lambda_sterics_B": 0.0, "lambda_electrostatics_B": 0.0, }, ) # expect only lig_1 + solvent interaction when lambda=0 expected_energy_0 = energy_fn(0, 2) assert_allclose(energy_0, from_openmm(expected_energy_0), rtol=1e-05) # expect only lig_2 + solvent interaction when lambda=1 energy_1 = compute_energy( alchemical_system, coords, None, { "lambda_sterics_A": 0.0, "lambda_electrostatics_A": 0.0, "lambda_sterics_B": 1.0, "lambda_electrostatics_B": 1.0, }, ) expected_energy_1 = energy_fn(1, 2) assert_allclose(energy_1, from_openmm(expected_energy_1), rtol=1e-05) # expect lig_1 + solvent and lig_2 + solvent interaction when lambda=0.5 # but no lig_1 + lig_2 interaction by default energy_05 = compute_energy( alchemical_system, coords, None, { "lambda_sterics_A": 0.5, "lambda_electrostatics_A": 0.5, "lambda_sterics_B": 0.5, "lambda_electrostatics_B": 0.5, }, ) expected_energy_05 = energy_fn(0, 2, 0.5, 0.5) + energy_fn(1, 2, 0.5, 0.5) assert_allclose(energy_05, from_openmm(expected_energy_05), rtol=1e-05) def test_two_ligands_charges(self, three_particle_system): """Test scaling the nonbonded interactions of single particles.""" system, coords, energy_fn = three_particle_system # Do it the openmm way factory = AbsoluteAlchemicalFactory(consistent_exceptions=False) alchemical_region_A = AlchemicalRegion(alchemical_atoms=[0], name="A") alchemical_region_B = AlchemicalRegion(alchemical_atoms=[1], name="B") alchemical_system = factory.create_alchemical_system( system, [alchemical_region_A, alchemical_region_B] ) energy = compute_energy( alchemical_system, coords, None, { "lambda_sterics_A": 1.0, "lambda_electrostatics_A": 0.8, "lambda_sterics_B": 1.0, "lambda_electrostatics_B": 0.2, }, ) expected_energy = energy_fn(0, 2, 1.0, 0.8) + energy_fn(1, 2, 1.0, 0.2) assert_allclose(energy, from_openmm(expected_energy), rtol=1e-05) def test_dry_run_benzene_toluene(benzene_toluene_dag, tmp_path): prot_units = list(benzene_toluene_dag.protocol_units) assert len(prot_units) == 6 solv_setup_unit = [u for u in prot_units if isinstance(u, SepTopSolventSetupUnit)] sol_run_unit = [u for u in prot_units if isinstance(u, SepTopSolventRunUnit)] complex_setup_unit = [u for u in prot_units if isinstance(u, SepTopComplexSetupUnit)] complex_run_unit = [u for u in prot_units if isinstance(u, SepTopComplexRunUnit)] assert len(solv_setup_unit) == 1 assert len(sol_run_unit) == 1 assert len(complex_setup_unit) == 1 assert len(complex_run_unit) == 1 solv_setup_output = solv_setup_unit[0].run( dry=True, scratch_basepath=tmp_path, shared_basepath=tmp_path ) pdb = md.load_pdb(tmp_path / "topology.pdb") assert pdb.n_atoms == 1762 central_atoms = np.array([[2, 19]], dtype=np.int32) distance = md.compute_distances(pdb, central_atoms)[0][0] assert np.isclose(distance, 0.8661) pdb_file = openmm.app.pdbfile.PDBFile(str(solv_setup_output["topology"])) alchem_system = deserialize(solv_setup_output["system"]) solv_sampler = sol_run_unit[0].run( alchem_system, pdb_file, solv_setup_output["selection_indices"], dry=True, scratch_basepath=tmp_path, shared_basepath=tmp_path, )["sampler"] # fmt: skip assert solv_sampler.is_periodic assert isinstance(solv_sampler, MultiStateSampler) assert isinstance(solv_sampler._thermodynamic_states[0].barostat, MonteCarloBarostat) assert solv_sampler._thermodynamic_states[1].pressure == 1 * openmm.unit.bar # Check we have the right number of atoms in the PDB pdb = md.load_pdb(tmp_path / "alchemical_system.pdb") assert pdb.n_atoms == 31 # Test the solvent system assert len(alchem_system.getForces()) == 14 _assert_num_forces(alchem_system, NonbondedForce, 1) _assert_num_forces(alchem_system, CustomNonbondedForce, 4) _assert_num_forces(alchem_system, CustomBondForce, 4) _assert_num_forces(alchem_system, HarmonicBondForce, 2) _assert_num_forces(alchem_system, HarmonicAngleForce, 1) _assert_num_forces(alchem_system, PeriodicTorsionForce, 1) _assert_num_forces(alchem_system, MonteCarloBarostat, 1) # Check steric forces for f in alchem_system.getForces(): if isinstance(f, CustomNonbondedForce) and "U_sterics" in f.getEnergyFunction(): _verify_alchemical_sterics_force_parameters(f) complex_setup_output = complex_setup_unit[0].run( dry=True, scratch_basepath=tmp_path, shared_basepath=tmp_path ) pdb_file = openmm.app.pdbfile.PDBFile(str(complex_setup_output["topology"])) alchem_system = deserialize(complex_setup_output["system"]) complex_sampler = complex_run_unit[0].run( alchem_system, pdb_file, complex_setup_output["selection_indices"], dry=True, scratch_basepath=tmp_path, shared_basepath=tmp_path, )["sampler"] # fmt: skip assert complex_sampler.is_periodic assert isinstance(complex_sampler, MultiStateSampler) assert isinstance(complex_sampler._thermodynamic_states[0].barostat, MonteCarloBarostat) assert complex_sampler._thermodynamic_states[1].pressure == 1 * openmm.unit.bar # Check we have the right number of atoms in the PDB pdb = md.load_pdb(tmp_path / "alchemical_system.pdb") assert pdb.n_atoms == 2687 # Test the complex system assert len(alchem_system.getForces()) == 15 _assert_num_forces(alchem_system, NonbondedForce, 1) _assert_num_forces(alchem_system, CustomNonbondedForce, 4) _assert_num_forces(alchem_system, CustomBondForce, 4) _assert_num_forces(alchem_system, HarmonicBondForce, 1) _assert_num_forces(alchem_system, HarmonicAngleForce, 1) _assert_num_forces(alchem_system, PeriodicTorsionForce, 1) _assert_num_forces(alchem_system, CustomCompoundBondForce, 2) _assert_num_forces(alchem_system, MonteCarloBarostat, 1) # Check steric forces for f in alchem_system.getForces(): if isinstance(f, CustomNonbondedForce) and "U_sterics" in f.getEnergyFunction(): _verify_alchemical_sterics_force_parameters(f) @pytest.mark.parametrize("method", ["repex", "sams", "independent"]) def test_dry_run_methods( benzene_complex_system, toluene_complex_system, tmp_path, protocol_dry_settings, method, ): protocol_dry_settings.solvent_simulation_settings.sampler_method = method protocol_dry_settings.complex_simulation_settings.sampler_method = method protocol_dry_settings.complex_output_settings.output_indices = "resname UNK" protocol_dry_settings.solvent_output_settings.output_indices = "resname UNK" protocol = SepTopProtocol( settings=protocol_dry_settings, ) dag = protocol.create( stateA=benzene_complex_system, stateB=toluene_complex_system, mapping=None, ) dag_units = list(dag.protocol_units) # Only check the cutoff for the Solvent SetUp Unit solv_setup_unit = [u for u in dag_units if isinstance(u, SepTopSolventSetupUnit)] sol_run_unit = [u for u in dag_units if isinstance(u, SepTopSolventRunUnit)] solv_setup_output = solv_setup_unit[0].run( dry=True, scratch_basepath=tmp_path, shared_basepath=tmp_path ) pdb_file = openmm.app.pdbfile.PDBFile(str(solv_setup_output["topology"])) alchem_system = deserialize(solv_setup_output["system"]) solv_sampler = sol_run_unit[0].run( alchem_system, pdb_file, solv_setup_output["selection_indices"], dry=True, scratch_basepath=tmp_path, shared_basepath=tmp_path, )["sampler"] # fmt: skip assert isinstance(solv_sampler, MultiStateSampler) assert solv_sampler.is_periodic assert isinstance(solv_sampler._thermodynamic_states[0].barostat, MonteCarloBarostat) assert solv_sampler._thermodynamic_states[1].pressure == 1 * openmm.unit.bar # Check we have the right number of atoms in the PDB pdb = md.load_pdb(tmp_path / "alchemical_system.pdb") assert pdb.n_atoms == 27 @pytest.mark.parametrize( "pressure", [ 1.0, 0.9, 1.1, ], ) def test_dry_run_ligand_system_pressure( pressure, benzene_complex_system, toluene_complex_system, tmp_path, protocol_dry_settings, ): """ Test that the right nonbonded cutoff is propagated to the system. """ # openfe settings requires openff/pint units protocol_dry_settings.thermo_settings.pressure = pressure * offunit.bar protocol = SepTopProtocol( settings=protocol_dry_settings, ) dag = protocol.create( stateA=benzene_complex_system, stateB=toluene_complex_system, mapping=None, ) dag_units = list(dag.protocol_units) # Only check the cutoff for the Solvent SetUp Unit solv_setup_unit = [u for u in dag_units if isinstance(u, SepTopSolventSetupUnit)] sol_run_unit = [u for u in dag_units if isinstance(u, SepTopSolventRunUnit)] solv_setup_output = solv_setup_unit[0].run( dry=True, scratch_basepath=tmp_path, shared_basepath=tmp_path ) pdb_file = openmm.app.pdbfile.PDBFile(str(solv_setup_output["topology"])) alchem_system = deserialize(solv_setup_output["system"]) solv_sampler = sol_run_unit[0].run( alchem_system, pdb_file, solv_setup_output["selection_indices"], dry=True, scratch_basepath=tmp_path, shared_basepath=tmp_path, )["sampler"] # fmt: skip # at this point, the units will be in openmm units assert solv_sampler._thermodynamic_states[1].pressure == pressure * openmm.unit.bar def test_virtual_sites_no_reassign( benzene_complex_system, toluene_complex_system, tmp_path, protocol_dry_settings, ): """ Test that an error is raised when not reassigning velocities in a system with virtual site. """ protocol_dry_settings.forcefield_settings.forcefields = [ "amber/ff14SB.xml", "amber/tip4pew_standard.xml", # FF with VS ] protocol_dry_settings.solvent_solvation_settings.solvent_model = "tip4pew" protocol_dry_settings.solvent_integrator_settings.reassign_velocities = False protocol = SepTopProtocol( settings=protocol_dry_settings, ) dag = protocol.create( stateA=benzene_complex_system, stateB=toluene_complex_system, mapping=None, ) dag_units = list(dag.protocol_units) # Only check the Solvent Unit solv_setup_unit = [u for u in dag_units if isinstance(u, SepTopSolventSetupUnit)] solv_run_unit = [u for u in dag_units if isinstance(u, SepTopSolventRunUnit)] setup_results = solv_setup_unit[0].run( dry=True, scratch_basepath=tmp_path, shared_basepath=tmp_path, ) pdb_file = openmm.app.pdbfile.PDBFile(str(setup_results["topology"])) with pytest.raises(ValueError, match="are unstable"): _ = solv_run_unit[0].run( setup_results["alchem_system"], pdb_file, setup_results["selection_indices"], dry=True, scratch_basepath=tmp_path, shared_basepath=tmp_path, ) # fmt: skip @pytest.mark.parametrize( "cutoff", [1.0 * offunit.nanometer, 12.0 * offunit.angstrom, 0.9 * offunit.nanometer], ) def test_dry_run_ligand_system_cutoff( cutoff, benzene_complex_system, toluene_complex_system, tmp_path, protocol_dry_settings, ): """ Test that the right nonbonded cutoff is propagated to the system. """ protocol_dry_settings.solvent_solvation_settings.solvent_padding = 1.9 * offunit.nanometer protocol_dry_settings.forcefield_settings.nonbonded_cutoff = cutoff protocol = SepTopProtocol( settings=protocol_dry_settings, ) dag = protocol.create( stateA=benzene_complex_system, stateB=toluene_complex_system, mapping=None, ) dag_units = list(dag.protocol_units) # Only check the cutoff for the Solvent SetUp Unit solv_setup_unit = [u for u in dag_units if isinstance(u, SepTopSolventSetupUnit)] serialized_system = solv_setup_unit[0].run( dry=True, scratch_basepath=tmp_path, shared_basepath=tmp_path )["system"] system = deserialize(serialized_system) nbfs = [ f for f in system.getForces() if isinstance(f, CustomNonbondedForce) or isinstance(f, NonbondedForce) ] for f in nbfs: f_cutoff = from_openmm(f.getCutoffDistance()) assert f_cutoff == cutoff def test_dry_run_benzene_toluene_tip4p( benzene_complex_system, toluene_complex_system, tmp_path, protocol_dry_settings, ): protocol_dry_settings.forcefield_settings.forcefields = [ "amber/ff14SB.xml", # ff14SB protein force field "amber/tip4pew_standard.xml", # FF we are testing with the fun VS "amber/phosaa10.xml", # Handles THE TPO ] protocol_dry_settings.solvent_solvation_settings.solvent_model = "tip4pew" protocol_dry_settings.solvent_integrator_settings.reassign_velocities = True protocol = SepTopProtocol(settings=protocol_dry_settings) # Create DAG from protocol, get the solvent units # and eventually dry run the first solvent unit dag = protocol.create( stateA=benzene_complex_system, stateB=toluene_complex_system, mapping=None, ) prot_units = list(dag.protocol_units) assert len(prot_units) == 6 solv_setup_unit = [u for u in prot_units if isinstance(u, SepTopSolventSetupUnit)] sol_run_unit = [u for u in prot_units if isinstance(u, SepTopSolventRunUnit)] assert len(solv_setup_unit) == 1 assert len(sol_run_unit) == 1 solv_setup_output = solv_setup_unit[0].run( dry=True, scratch_basepath=tmp_path, shared_basepath=tmp_path ) pdb_file = openmm.app.pdbfile.PDBFile(str(solv_setup_output["topology"])) alchem_system = deserialize(solv_setup_output["system"]) solv_run = sol_run_unit[0].run( alchem_system, pdb_file, solv_setup_output["selection_indices"], dry=True, scratch_basepath=tmp_path, shared_basepath=tmp_path, )["sampler"] # fmt: skip assert solv_run.is_periodic def test_dry_run_benzene_toluene_noncubic( benzene_complex_system, toluene_complex_system, tmp_path, protocol_dry_settings, ): protocol_dry_settings.solvent_solvation_settings.solvent_padding = 1.5 * offunit.nanometer protocol_dry_settings.solvent_solvation_settings.box_shape = "dodecahedron" protocol = SepTopProtocol(settings=protocol_dry_settings) # Create DAG from protocol, get the vacuum and solvent units # and eventually dry run the first solvent unit dag = protocol.create( stateA=benzene_complex_system, stateB=toluene_complex_system, mapping=None, ) prot_units = list(dag.protocol_units) assert len(prot_units) == 6 solv_setup_unit = [u for u in prot_units if isinstance(u, SepTopSolventSetupUnit)] assert len(solv_setup_unit) == 1 solv_setup_output = solv_setup_unit[0].run( dry=True, scratch_basepath=tmp_path, shared_basepath=tmp_path ) serialized_system = solv_setup_output["system"] system = deserialize(serialized_system) vectors = system.getDefaultPeriodicBoxVectors() width = float(from_openmm(vectors)[0][0].to("nanometer").m) # dodecahedron has the following shape: # [width, 0, 0], [0, width, 0], [0.5, 0.5, 0.5 * sqrt(2)] * width expected_vectors = [ [width, 0, 0], [0, width, 0], [0.5 * width, 0.5 * width, 0.5 * math.sqrt(2) * width], ] * offunit.nanometer assert_allclose( expected_vectors, from_openmm(vectors), ) def test_dry_run_solv_user_charges_benzene_toluene( benzene_modifications, T4_protein_component, tmp_path, protocol_dry_settings, ): """ Create a test system with fictitious user supplied charges and ensure that they are properly passed through to the constructed alchemical system. """ protocol = SepTopProtocol(settings=protocol_dry_settings) def assign_fictitious_charges(offmol): """ Get a random array of fake partial charges for your offmol. """ rand_arr = np.random.randint(1, 10, size=offmol.n_atoms) / 100 rand_arr[-1] = -sum(rand_arr[:-1]) return rand_arr * offunit.elementary_charge def check_partial_charges(offmol): offmol_pchgs = assign_fictitious_charges(offmol) offmol.partial_charges = offmol_pchgs smc = openfe.SmallMoleculeComponent.from_openff(offmol) # check propchgs prop_chgs = smc.to_dict()["molprops"]["atom.dprop.PartialCharge"] prop_chgs = np.array(prop_chgs.split(), dtype=float) np.testing.assert_allclose(prop_chgs, offmol_pchgs) return smc, prop_chgs benzene_offmol = benzene_modifications["benzene"].to_openff() toluene_offmol = benzene_modifications["toluene"].to_openff() benzene_smc, benzene_charge = check_partial_charges(benzene_offmol) toluene_smc, toluene_charge = check_partial_charges(toluene_offmol) # Create ChemicalSystems stateA = ChemicalSystem( { "benzene": benzene_smc, "T4l": T4_protein_component, "solvent": SolventComponent(), } ) stateB = ChemicalSystem( { "toluene": toluene_smc, "T4l": T4_protein_component, "solvent": SolventComponent(), } ) # Create DAG from protocol, get the vacuum and solvent units # and eventually dry run the first solvent unit dag = protocol.create( stateA=stateA, stateB=stateB, mapping=None, ) prot_units = list(dag.protocol_units) solv_setup_unit = [u for u in prot_units if isinstance(u, SepTopSolventSetupUnit)] complex_setup_unit = [u for u in prot_units if isinstance(u, SepTopComplexSetupUnit)] # check sol_unit charges serialized_system = solv_setup_unit[0].run( dry=True, scratch_basepath=tmp_path, shared_basepath=tmp_path )["system"] system = deserialize(serialized_system) nonbond = [f for f in system.getForces() if isinstance(f, openmm.NonbondedForce)] assert len(nonbond) == 1 # loop through the 12 benzene atoms # partial charge is stored in the offset for i in range(12): offsets = nonbond[0].getParticleParameterOffset(i) c = ensure_quantity(offsets[2], "openff") assert pytest.approx(c) == benzene_charge[i] # loop through 15 toluene atoms for inx, i in enumerate(range(12, 27)): offsets = nonbond[0].getParticleParameterOffset(i) c = ensure_quantity(offsets[2], "openff") assert pytest.approx(c) == toluene_charge[inx] # check complex_unit charges serialized_system = complex_setup_unit[0].run( dry=True, scratch_basepath=tmp_path, shared_basepath=tmp_path )["system"] system = deserialize(serialized_system) nonbond = [f for f in system.getForces() if isinstance(f, openmm.NonbondedForce)] assert len(nonbond) == 1 # loop through the 12 benzene atoms # partial charge is stored in the offset for i in range(12): offsets = nonbond[0].getParticleParameterOffset(i) c = ensure_quantity(offsets[2], "openff") assert pytest.approx(c) == benzene_charge[i] # loop through 15 toluene atoms for inx, i in enumerate(range(12, 27)): offsets = nonbond[0].getParticleParameterOffset(i) c = ensure_quantity(offsets[2], "openff") assert pytest.approx(c) == toluene_charge[inx] def test_high_timestep( benzene_complex_system, toluene_complex_system, tmp_path, protocol_dry_settings, ): protocol_dry_settings.forcefield_settings.hydrogen_mass = 1.0 protocol_dry_settings.forcefield_settings.hydrogen_mass = 1.0 protocol = SepTopProtocol(settings=protocol_dry_settings) dag = protocol.create( stateA=benzene_complex_system, stateB=toluene_complex_system, mapping=None, ) prot_units = list(dag.protocol_units) errmsg = "too large for hydrogen mass" with pytest.raises(ValueError, match=errmsg): prot_units[0].run(dry=True, scratch_basepath=tmp_path, shared_basepath=tmp_path) def test_bad_sampler(): class FakeSimSettings(gufe.settings.SettingsBaseModel): sampler_method: str = "foo bar" errmsg = "Unknown sampler foo bar" with pytest.raises(AttributeError, match=errmsg): SepTopSolventRunUnit._get_sampler( integrator=None, reporter=None, simulation_settings=FakeSimSettings(), thermodynamic_settings=None, compound_states=None, sampler_states=None, platform=None, restart=False, ) @pytest.fixture def T4L_xml( benzene_complex_system, toluene_complex_system, tmp_path_factory, protocol_dry_settings, ): # Fixing the number of solvent molecules in the solvent settings # to test against reference xml protocol_dry_settings.solvent_solvation_settings.solvent_padding = None protocol_dry_settings.solvent_solvation_settings.number_of_solvent_molecules = 364 protocol_dry_settings.forcefield_settings.small_molecule_forcefield = "openff-2.1.1" protocol = SepTopProtocol(settings=protocol_dry_settings) dag = protocol.create( stateA=benzene_complex_system, stateB=toluene_complex_system, mapping=None, ) # Get the SepTopSolventSetupUnit prot_units = list(dag.protocol_units) solv_setup_unit = [u for u in prot_units if isinstance(u, SepTopSolventSetupUnit)] tmp = tmp_path_factory.mktemp("xml_reg") dryrun = solv_setup_unit[0].run(dry=True, shared_basepath=tmp) system = dryrun["system"] return deserialize(system) class TestT4LXmlRegression: """Generates SepTop system XML (solvent) and performs regression test""" @staticmethod def test_particles(T4L_xml, T4L_septop_reference_xml): nr_particles = T4L_xml.getNumParticles() nr_particles_ref = T4L_septop_reference_xml.getNumParticles() assert nr_particles == nr_particles_ref particle_masses = [T4L_xml.getParticleMass(i) for i in range(nr_particles)] particle_masses_ref = [ T4L_septop_reference_xml.getParticleMass(i) for i in range(nr_particles) ] assert particle_masses for a, b in zip(particle_masses, particle_masses_ref): assert a == b @staticmethod def test_constraints(T4L_xml, T4L_septop_reference_xml): nr_constraints = T4L_xml.getNumConstraints() nr_constraints_ref = T4L_septop_reference_xml.getNumConstraints() assert nr_constraints == nr_constraints_ref constraints = [T4L_xml.getConstraintParameters(i) for i in range(nr_constraints)] constraints_ref = [ T4L_septop_reference_xml.getConstraintParameters(i) for i in range(nr_constraints) ] assert constraints for a, b in zip(constraints, constraints_ref): # Particle 1 assert a[0] == b[0] # Particle 2 assert a[1] == b[1] # Constraint Quantity assert a[2] == b[2] @pytest.mark.slow class TestA2AMembraneDryRun: solvent = SolventComponent(ion_concentration=0 * offunit.molar) num_all_not_water = 16116 num_complex_atoms = 39462 num_ligand_atoms_A = 36 num_ligand_atoms_B = 36 @pytest.fixture(scope="class") def settings(self): s = SepTopProtocol.default_settings() s.protocol_repeats = 1 s.engine_settings.compute_platform = "cpu" s.complex_output_settings.output_indices = "not water" s.complex_solvation_settings.box_shape = "dodecahedron" s.complex_solvation_settings.solvent_padding = 0.9 * offunit.nanometer s.solvent_solvation_settings.box_shape = "cube" return s @pytest.fixture(scope="function") def dag(self, settings, a2a_ligands, a2a_protein_membrane_component): stateA = ChemicalSystem( { "ligandA": a2a_ligands[0], "protein": a2a_protein_membrane_component, "solvent": self.solvent, } ) stateB = ChemicalSystem( { "ligandB": a2a_ligands[1], "protein": a2a_protein_membrane_component, "solvent": self.solvent, } ) # adaptive settings protocol_settings = SepTopProtocol._adaptive_settings( stateA=stateA, stateB=stateB, initial_settings=settings, ) protocol = SepTopProtocol(settings=protocol_settings) return protocol.create( stateA=stateA, stateB=stateB, mapping=None, ) @pytest.fixture(scope="function") def complex_setup_units(self, dag): return [u for u in dag.protocol_units if isinstance(u, SepTopComplexSetupUnit)] @pytest.fixture(scope="function") def complex_run_units(self, dag): return [u for u in dag.protocol_units if isinstance(u, SepTopComplexRunUnit)] @pytest.fixture(scope="function") def complex_analysis_unit(self, dag): return [u for u in dag.protocol_units if isinstance(u, SepTopComplexAnalysisUnit)] @pytest.fixture(scope="function") def solvent_setup_units(self, dag): return [u for u in dag.protocol_units if isinstance(u, SepTopSolventSetupUnit)] @pytest.fixture(scope="function") def solvent_run_units(self, dag): return [u for u in dag.protocol_units if isinstance(u, SepTopSolventRunUnit)] @pytest.fixture(scope="function") def solvent_analysis_unit(self, dag): return [u for u in dag.protocol_units if isinstance(u, SepTopSolventAnalysisUnit)] def test_number_of_units( self, dag, complex_setup_units, complex_run_units, solvent_setup_units, solvent_run_units ): assert len(list(dag.protocol_units)) == 6 assert len(complex_setup_units) == 1 assert len(complex_run_units) == 1 assert len(solvent_setup_units) == 1 assert len(solvent_run_units) == 1 def _assert_force_num(self, system, forcetype, number): forces = [f for f in system.getForces() if isinstance(f, forcetype)] assert len(forces) == number def _assert_expected_alchemical_forces(self, system, complexed: bool, settings): """ Assert the forces expected in the alchemical system. """ if complexed: barostat_type = MonteCarloMembraneBarostat self._assert_force_num(system, HarmonicBondForce, 1) # Two custom bonds for the two Boresch restraints self._assert_force_num(system, CustomCompoundBondForce, 2) assert len(system.getForces()) == 15 else: # Extra bond in the solvent self._assert_force_num(system, HarmonicBondForce, 2) assert len(system.getForces()) == 14 barostat_type = MonteCarloBarostat self._assert_force_num(system, NonbondedForce, 1) self._assert_force_num(system, CustomNonbondedForce, 4) self._assert_force_num(system, CustomBondForce, 4) self._assert_force_num(system, HarmonicAngleForce, 1) self._assert_force_num(system, PeriodicTorsionForce, 1) self._assert_force_num(system, barostat_type, 1) # Check the nonbonded force has the right contents nonbond = [f for f in system.getForces() if isinstance(f, NonbondedForce)] assert len(nonbond) == 1 assert nonbond[0].getNonbondedMethod() == NonbondedForce.PME assert ( from_openmm(nonbond[0].getCutoffDistance()) == settings.forcefield_settings.nonbonded_cutoff ) # Check the barostat made it all the way through barostat = [f for f in system.getForces() if isinstance(f, barostat_type)] assert len(barostat) == 1 assert barostat[0].getFrequency() == int( settings.complex_integrator_settings.barostat_frequency.m ) assert barostat[0].getDefaultPressure() == to_openmm(settings.thermo_settings.pressure) assert barostat[0].getDefaultTemperature() == to_openmm( settings.thermo_settings.temperature ) def _assert_expected_nonalchemical_forces(self, system, complexed: bool, settings): """ Assert the forces expected in the non-alchemical system. """ if complexed: barostat_type = MonteCarloMembraneBarostat else: barostat_type = MonteCarloBarostat self._assert_force_num(system, NonbondedForce, 1) self._assert_force_num(system, HarmonicBondForce, 1) self._assert_force_num(system, HarmonicAngleForce, 1) self._assert_force_num(system, PeriodicTorsionForce, 1) self._assert_force_num(system, barostat_type, 1) assert len(system.getForces()) == 5 # Check that the nonbonded force has the right contents nonbond = [f for f in system.getForces() if isinstance(f, NonbondedForce)] assert len(nonbond) == 1 assert nonbond[0].getNonbondedMethod() == NonbondedForce.PME assert ( from_openmm(nonbond[0].getCutoffDistance()) == settings.forcefield_settings.nonbonded_cutoff ) # Check the barostat made it all the way through barostat = [f for f in system.getForces() if isinstance(f, barostat_type)] assert len(barostat) == 1 assert barostat[0].getFrequency() == int( settings.complex_integrator_settings.barostat_frequency.m ) assert barostat[0].getDefaultPressure() == to_openmm(settings.thermo_settings.pressure) assert barostat[0].getDefaultTemperature() == to_openmm( settings.thermo_settings.temperature ) def _verify_sampler(self, sampler, complexed: bool, settings): """ Utility to verify the contents of the sampler. """ assert sampler.is_periodic assert isinstance(sampler, MultiStateSampler) if complexed: barostat_type = MonteCarloMembraneBarostat else: barostat_type = MonteCarloBarostat assert isinstance(sampler._thermodynamic_states[0].barostat, barostat_type) assert sampler._thermodynamic_states[1].pressure == to_openmm( settings.thermo_settings.pressure ) for state in sampler._thermodynamic_states: system = state.get_system(remove_thermostat=True) self._assert_expected_alchemical_forces(system, complexed, settings) @staticmethod def _test_orthogonal_vectors(system): """Test that the system has an orthorhombic (rectangular) periodic box.""" vectors = system.getDefaultPeriodicBoxVectors() vectors = from_openmm(vectors) # convert to a Quantity array # Extract box lengths in nanometers width_x, width_y, width_z = [v[i].to("nanometer").m for i, v in enumerate(vectors)] # Expected orthogonal box (axis-aligned) expected_vectors = ( np.array( [ [width_x, 0, 0], [0, width_y, 0], [0, 0, width_z], ] ) * offunit.nanometer ) assert_allclose( vectors, expected_vectors, atol=1e-5, err_msg=f"Box is not orthogonal:\n{vectors}" ) @staticmethod def _test_cubic_vectors(system): # cube is an identity matrix vectors = system.getDefaultPeriodicBoxVectors() width = float(from_openmm(vectors)[0][0].to("nanometer").m) expected_vectors = [ [width, 0, 0], [0, width, 0], [0, 0, width], ] * offunit.nanometer assert_allclose( expected_vectors, from_openmm(vectors), ) def test_complex_dry_run(self, complex_setup_units, complex_run_units, tmpdir): with tmpdir.as_cwd(): # Get adaptive settings adaptive_settings = complex_setup_units[0]._inputs["protocol"].settings # Check that adaptive settings changed the barostat to membrane barostat assert ( adaptive_settings.complex_integrator_settings.barostat == "MonteCarloMembraneBarostat" ) complex_setup_output = complex_setup_units[0].run(dry=True) pdb_file = openmm.app.pdbfile.PDBFile(str(complex_setup_output["topology"])) system = deserialize(complex_setup_output["system"]) indices = complex_setup_output["selection_indices"] data = complex_run_units[0].run(system, pdb_file, indices, dry=True) # fmt: skip # Check the sampler self._verify_sampler(data["sampler"], complexed=True, settings=adaptive_settings) # Check the alchemical system self._assert_expected_alchemical_forces( complex_setup_output["alchem_restrained_system"], complexed=True, settings=adaptive_settings, ) self._test_orthogonal_vectors(complex_setup_output["alchem_restrained_system"]) # Check the non-alchemical system self._assert_expected_nonalchemical_forces( complex_setup_output["system_AB"], complexed=True, settings=adaptive_settings ) self._test_orthogonal_vectors(complex_setup_output["system_AB"]) # Check the box vectors haven't changed (they shouldn't have because we didn't do MD) assert_allclose( from_openmm( complex_setup_output["alchem_restrained_system"].getDefaultPeriodicBoxVectors() ), from_openmm(complex_setup_output["system_AB"].getDefaultPeriodicBoxVectors()), ) # Check the PDB pdb = md.load_pdb("alchemical_system.pdb") assert pdb.n_atoms == self.num_all_not_water full_pdb = md.load_pdb("topology.pdb") assert full_pdb.n_atoms == self.num_complex_atoms def test_solvent_dry_run(self, solvent_setup_units, solvent_run_units, settings, tmpdir): with tmpdir.as_cwd(): solv_setup_output = solvent_setup_units[0].run(dry=True) pdb_file = openmm.app.pdbfile.PDBFile(str(solv_setup_output["topology"])) system = deserialize(solv_setup_output["system"]) indices = solv_setup_output["selection_indices"] data = solvent_run_units[0].run(system, pdb_file, indices, dry=True) # fmt: skip # Check the sampler self._verify_sampler(data["sampler"], complexed=False, settings=settings) # Check the alchemical system self._assert_expected_alchemical_forces( solv_setup_output["alchem_restrained_system"], complexed=False, settings=settings ) self._test_cubic_vectors(solv_setup_output["alchem_restrained_system"]) # Check the alchemical indices expected_indices = [i for i in range(self.num_ligand_atoms_A + self.num_ligand_atoms_B)] assert expected_indices == solv_setup_output["selection_indices"].tolist() # Check the non-alchemical system self._assert_expected_nonalchemical_forces( solv_setup_output["system_AB"], complexed=False, settings=settings ) self._test_cubic_vectors(solv_setup_output["system_AB"]) # Check the PDB pdb = md.load_pdb("alchemical_system.pdb") assert pdb.n_atoms == (self.num_ligand_atoms_A + self.num_ligand_atoms_B) ================================================ FILE: src/openfe/tests/protocols/openmm_septop/test_septop_protocol_results.py ================================================ # This code is part of OpenFE and is licensed under the MIT license. # For details, see https://github.com/OpenFreeEnergy/openfe import itertools import json import math import pathlib from unittest import mock import gufe import mdtraj as md import numpy as np import openmm import openmm.app import openmm.unit import pytest from numpy.testing import assert_allclose from openff.units import unit as offunit from openff.units.openmm import ensure_quantity, from_openmm, to_openmm from openmm import ( CustomBondForce, CustomCompoundBondForce, CustomNonbondedForce, HarmonicAngleForce, HarmonicBondForce, MonteCarloBarostat, MonteCarloMembraneBarostat, NonbondedForce, PeriodicTorsionForce, ) from openmmtools.alchemy import AbsoluteAlchemicalFactory, AlchemicalRegion from openmmtools.multistate.multistatesampler import MultiStateSampler import openfe.protocols.openmm_septop from openfe import ChemicalSystem, SolventComponent from openfe.protocols.openmm_septop import ( SepTopComplexRunUnit, SepTopComplexSetupUnit, SepTopProtocol, SepTopProtocolResult, SepTopSolventRunUnit, SepTopSolventSetupUnit, ) from openfe.protocols.openmm_septop.base_units import ( BaseSepTopAnalysisUnit, BaseSepTopRunUnit, BaseSepTopSetupUnit, ) from openfe.protocols.openmm_utils.serialization import deserialize from openfe.protocols.restraint_utils.geometry.boresch import BoreschRestraintGeometry from openfe.tests.protocols.conftest import compute_energy from openfe.tests.protocols.openmm_ahfe.test_ahfe_protocol import ( _assert_num_forces, _verify_alchemical_sterics_force_parameters, ) from .utils import UNIT_TYPES, _get_units @pytest.fixture def patcher(): base_path = "openfe.protocols.openmm_septop.base_units" protocol_path = "openfe.protocols.openmm_septop.equil_septop_method" with ( mock.patch( f"{protocol_path}.SepTopComplexSetupUnit.run", return_value={ "system": pathlib.Path("system.xml.bz2"), "topology": "topology.pdb", "standard_state_correction_A": 0 * offunit.kilocalorie_per_mole, "standard_state_correction_B": 0 * offunit.kilocalorie_per_mole, "restraint_geometry_A": None, "restraint_geometry_B": None, "selection_indices": np.array( [ 0, ] ), "subsampled_pdb_structure": "subsampled.pdb", }, ), mock.patch( f"{protocol_path}.SepTopSolventSetupUnit.run", return_value={ "system": pathlib.Path("system.xml.bz2"), "topology": "topology.pdb", "standard_state_correction": 0 * offunit.kilocalorie_per_mole, "selection_indices": np.array( [ 0, ] ), "subsampled_pdb_structure": "subsampled.pdb", }, ), mock.patch( f"{protocol_path}.SepTopComplexRunUnit.run", return_value={ "trajectory": "foo.nc", "checkpoint": "bar.nc", }, ), mock.patch( f"{protocol_path}.SepTopSolventRunUnit.run", return_value={ "trajectory": "foo.nc", "checkpoint": "bar.nc", }, ), mock.patch( f"{protocol_path}.SepTopComplexAnalysisUnit.run", return_value={"foo": "bar"}, ), mock.patch( f"{protocol_path}.SepTopSolventAnalysisUnit.run", return_value={"foo": "bar"}, ), mock.patch( f"{base_path}.deserialize", return_value="foo", ), mock.patch( f"{base_path}.openmm.app.pdbfile.PDBFile", return_value="foo", ), ): yield def test_unit_tagging(benzene_toluene_dag, patcher, tmp_path): # test that executing the units includes correct gen and repeat info dag_units = benzene_toluene_dag.protocol_units for phase in ["solvent", "complex"]: setup_results = {} sim_results = {} analysis_results = {} setup_units = _get_units(dag_units, UNIT_TYPES[phase]["setup"]) sim_units = _get_units(dag_units, UNIT_TYPES[phase]["sim"]) a_units = _get_units(dag_units, UNIT_TYPES[phase]["analysis"]) for u in setup_units: rid = u.inputs["repeat_id"] setup_results[rid] = u.execute(context=gufe.Context(tmp_path, tmp_path)) for u in sim_units: rid = u.inputs["repeat_id"] sim_results[rid] = u.execute( context=gufe.Context(tmp_path, tmp_path), setup=setup_results[rid], ) for u in a_units: rid = u.inputs["repeat_id"] analysis_results[rid] = u.execute( context=gufe.Context(tmp_path, tmp_path), setup=setup_results[rid], simulation=sim_results[rid], ) for results in [setup_results, sim_results, analysis_results]: for ret in results.values(): assert isinstance(ret, gufe.ProtocolUnitResult) assert ret.outputs["generation"] == 0 assert len(setup_results) == 1 assert len(sim_results) == 1 assert len(analysis_results) == 1 def test_gather(benzene_toluene_dag, patcher, tmp_path): # check that .gather behaves as expected dagres = gufe.protocols.execute_DAG( benzene_toluene_dag, shared_basedir=tmp_path, scratch_basedir=tmp_path, keep_shared=True, ) protocol = SepTopProtocol( settings=SepTopProtocol.default_settings(), ) res = protocol.gather([dagres]) assert isinstance(res, openfe.protocols.openmm_septop.SepTopProtocolResult) class TestProtocolResult: @pytest.fixture() def protocolresult(self, septop_json): d = json.loads(septop_json, cls=gufe.tokenization.JSON_HANDLER.decoder) pr = openfe.ProtocolResult.from_dict(d["protocol_result"]) return pr def test_reload_protocol_result(self, septop_json): d = json.loads(septop_json, cls=gufe.tokenization.JSON_HANDLER.decoder) pr = SepTopProtocolResult.from_dict(d["protocol_result"]) assert pr def test_get_estimate(self, protocolresult): est = protocolresult.get_estimate() assert est assert est.m == pytest.approx(1.6, abs=0.1) assert isinstance(est, offunit.Quantity) assert est.is_compatible_with(offunit.kilojoule_per_mole) def test_get_uncertainty(self, protocolresult): est = protocolresult.get_uncertainty() assert est.m == pytest.approx(0.0, abs=0.1) assert isinstance(est, offunit.Quantity) assert est.is_compatible_with(offunit.kilojoule_per_mole) def test_get_individual(self, protocolresult): inds = protocolresult.get_individual_estimates() assert isinstance(inds, dict) assert isinstance(inds["solvent"], list) assert isinstance(inds["complex"], list) assert len(inds["solvent"]) == len(inds["complex"]) == 1 for e, u in itertools.chain(inds["solvent"], inds["complex"]): assert e.is_compatible_with(offunit.kilojoule_per_mole) assert u.is_compatible_with(offunit.kilojoule_per_mole) def test_get_forwards_etc(self, protocolresult): """ Due to the short simulation times, we expect the frwd/reverse analysis of the solvent to be None. """ wmsg = "were found in the forward and reverse dictionaries of the repeats of the solvent" with pytest.warns(UserWarning, match=wmsg): far = protocolresult.get_forward_and_reverse_energy_analysis() assert isinstance(far, dict) for key in ["solvent", "complex"]: assert isinstance(far[key], list) assert far["solvent"][0] is None complex_keys = list(far["complex"][0].keys()) for key in ["fractions", "forward_DGs", "forward_dDGs", "reverse_DGs", "reverse_dDGs"]: assert key in complex_keys assert len(far["complex"][0][key]) == 10 @pytest.mark.parametrize("key", ["solvent", "complex"]) def test_get_overlap_matrices(self, key, protocolresult): ovp = protocolresult.get_overlap_matrices() assert isinstance(ovp, dict) assert isinstance(ovp[key], list) assert len(ovp[key]) == 1 ovp1 = ovp[key][0] assert isinstance(ovp1["matrix"], np.ndarray) if key == "solvent": lambda_nr = 27 else: lambda_nr = 19 assert ovp1["matrix"].shape == (lambda_nr, lambda_nr) @pytest.mark.parametrize("key", ["solvent", "complex"]) def test_get_replica_transition_statistics(self, key, protocolresult): rpx = protocolresult.get_replica_transition_statistics() if key == "solvent": lambda_nr = 27 else: lambda_nr = 19 assert isinstance(rpx, dict) assert isinstance(rpx[key], list) assert len(rpx[key]) == 1 rpx1 = rpx[key][0] assert "eigenvalues" in rpx1 assert "matrix" in rpx1 assert rpx1["eigenvalues"].shape == (lambda_nr,) assert rpx1["matrix"].shape == (lambda_nr, lambda_nr) @pytest.mark.parametrize("key", ["solvent", "complex"]) def test_equilibration_iterations(self, key, protocolresult): eq = protocolresult.equilibration_iterations() assert isinstance(eq, dict) assert isinstance(eq[key], list) assert len(eq[key]) == 1 assert all(isinstance(v, float) for v in eq[key]) @pytest.mark.parametrize("key", ["solvent", "complex"]) def test_production_iterations(self, key, protocolresult): prod = protocolresult.production_iterations() assert isinstance(prod, dict) assert isinstance(prod[key], list) assert len(prod[key]) == 1 assert all(isinstance(v, float) for v in prod[key]) @pytest.mark.parametrize( "key, expected_size", [ ["solvent", 87], ["complex", 1868], ], ) def test_selection_indices(self, key, protocolresult, expected_size): indices = protocolresult.selection_indices() assert isinstance(indices, dict) assert isinstance(indices[key], list) for inds in indices[key]: assert isinstance(inds, np.ndarray) assert len(inds) == expected_size def test_filenotfound_replica_states(self, protocolresult): errmsg = "File could not be found" with pytest.raises(ValueError, match=errmsg): protocolresult.get_replica_states() def test_restraint_geometry(self, protocolresult): geom = protocolresult.restraint_geometries() assert isinstance(geom, tuple) assert len(geom) == 2 assert isinstance(geom[0], list) assert isinstance(geom[0][0], BoreschRestraintGeometry) assert geom[0][0].guest_atoms == [1779, 1778, 1777] assert geom[0][0].host_atoms == [802, 801, 800] assert pytest.approx(geom[0][0].r_aA0, abs=0.01) == 0.75 * offunit.nanometer assert pytest.approx(geom[0][0].theta_A0, abs=0.01) == 1.95 * offunit.radian assert pytest.approx(geom[0][0].theta_B0, abs=0.01) == 1.33 * offunit.radian assert pytest.approx(geom[0][0].phi_A0, abs=0.01) == 1.01 * offunit.radian assert pytest.approx(geom[0][0].phi_B0, abs=0.01) == -1.24 * offunit.radian assert pytest.approx(geom[0][0].phi_C0, abs=0.01) == -1.08 * offunit.radian ================================================ FILE: src/openfe/tests/protocols/openmm_septop/test_septop_resume.py ================================================ # This code is part of OpenFE and is licensed under the MIT license. # For details, see https://github.com/OpenFreeEnergy/openfe import copy import logging import os import pathlib import shutil import gufe import openmm import pytest from gufe.protocols.errors import ProtocolUnitExecutionError from numpy.testing import assert_allclose from openfe_analysis.utils.multistate import _determine_position_indices from openff.units import unit as offunit from openff.units.openmm import from_openmm from openmmtools.multistate import MultiStateReporter, ReplicaExchangeSampler import openfe from openfe.data._registry import POOCH_CACHE from openfe.protocols.openmm_septop import ( SepTopComplexRunUnit, SepTopProtocol, SepTopSolventAnalysisUnit, SepTopSolventRunUnit, SepTopSolventSetupUnit, ) from ...conftest import HAS_INTERNET from .utils import _get_units @pytest.fixture() def protocol_settings(): settings = SepTopProtocol.default_settings() settings.protocol_repeats = 1 settings.solvent_output_settings.output_indices = "resname UNK" settings.complex_solvation_settings.solvent_padding = None settings.complex_solvation_settings.number_of_solvent_molecules = 50000 settings.complex_solvation_settings.box_shape = "dodecahedron" settings.solvent_solvation_settings.solvent_padding = None settings.solvent_solvation_settings.number_of_solvent_molecules = 1000 settings.solvent_solvation_settings.box_shape = "dodecahedron" settings.complex_simulation_settings.equilibration_length = 50 * offunit.picosecond settings.complex_simulation_settings.production_length = 50 * offunit.picosecond settings.solvent_simulation_settings.equilibration_length = 50 * offunit.picosecond settings.solvent_simulation_settings.production_length = 50 * offunit.picosecond settings.complex_simulation_settings.time_per_iteration = 2.5 * offunit.picosecond settings.solvent_simulation_settings.time_per_iteration = 2.5 * offunit.picosecond settings.complex_output_settings.checkpoint_interval = 25 * offunit.picosecond settings.solvent_output_settings.checkpoint_interval = 25 * offunit.picosecond settings.complex_output_settings.positions_write_frequency = 25 * offunit.picosecond settings.solvent_output_settings.positions_write_frequency = 25 * offunit.picosecond settings.engine_settings.compute_platform = None return settings def test_verify_execution_environment(): # Verification should pass SepTopComplexRunUnit._verify_execution_environment( setup_outputs={ "gufe_version": gufe.__version__, "openfe_version": openfe.__version__, "openmm_version": openmm.__version__, }, ) def test_verify_execution_environment_fail(): # Passing a bad version should fail with pytest.raises(ProtocolUnitExecutionError, match="Python environment"): SepTopComplexRunUnit._verify_execution_environment( setup_outputs={ "gufe_version": 0.1, "openfe_version": openfe.__version__, "openmm_version": openmm.__version__, }, ) def test_verify_execution_env_missing_key(): errmsg = "Missing environment information from setup outputs." with pytest.raises(ProtocolUnitExecutionError, match=errmsg): SepTopComplexRunUnit._verify_execution_environment( setup_outputs={ "foo_version": 0.1, "openfe_version": openfe.__version__, "openmm_version": openmm.__version__, }, ) @pytest.mark.skipif( not os.path.exists(POOCH_CACHE) and not HAS_INTERNET, reason="Internet unavailable and test data is not cached locally", ) def test_check_restart(protocol_settings, septop_solv_trajectory_path): assert SepTopSolventRunUnit._check_restart( output_settings=protocol_settings.solvent_output_settings, shared_path=septop_solv_trajectory_path.parent, ) assert not SepTopSolventRunUnit._check_restart( output_settings=protocol_settings.solvent_output_settings, shared_path=pathlib.Path("."), ) @pytest.mark.skipif( not os.path.exists(POOCH_CACHE) and not HAS_INTERNET, reason="Internet unavailable and test data is not cached locally", ) def test_check_restart_one_file_missing(protocol_settings, septop_solv_trajectory_path): protocol_settings.solvent_output_settings.checkpoint_storage_filename = "foo.nc" errmsg = "the trajectory file is present but not the checkpoint file." with pytest.raises(IOError, match=errmsg): SepTopSolventRunUnit._check_restart( output_settings=protocol_settings.solvent_output_settings, shared_path=septop_solv_trajectory_path.parent, ) class TestCheckpointResuming: @pytest.fixture() def protocol_dag( self, protocol_settings, benzene_complex_system, toluene_complex_system, ): protocol = SepTopProtocol(settings=protocol_settings) return protocol.create( stateA=benzene_complex_system, stateB=toluene_complex_system, mapping=None, ) @pytest.fixture() def protocol_units(self, protocol_dag): pus = list(protocol_dag.protocol_units) setup_unit = _get_units(pus, SepTopSolventSetupUnit)[0] sim_unit = _get_units(pus, SepTopSolventRunUnit)[0] analysis_unit = _get_units(pus, SepTopSolventAnalysisUnit)[0] return setup_unit, sim_unit, analysis_unit @pytest.fixture() def setup_results(self, protocol_units, tmp_path): setup_unit, _, _ = protocol_units return setup_unit.run( dry=True, scratch_basepath=tmp_path, shared_basepath=tmp_path, ) @pytest.fixture() def pdb_file(self, setup_results): return openmm.app.pdbfile.PDBFile(str(setup_results["topology"])) @staticmethod def _check_sampler(sampler, num_iterations: int): # Helper method to do some checks on the sampler assert sampler._iteration == num_iterations assert sampler.number_of_iterations == 20 assert sampler.is_completed is (num_iterations == 20) assert sampler.n_states == sampler.n_replicas == 27 assert sampler.is_periodic assert sampler.mcmc_moves[0].n_steps == 625 assert from_openmm(sampler.mcmc_moves[0].timestep) == 4 * offunit.fs @staticmethod def _get_positions(dataset): frame_list = _determine_position_indices(dataset) positions = [] for frame in frame_list: positions.append(copy.deepcopy(dataset.variables["positions"][frame].data)) return positions @staticmethod def _copy_simfiles(cwd: pathlib.Path, filepath): shutil.copyfile(filepath, f"{cwd}/{filepath.name}") @pytest.mark.integration def test_resume( self, protocol_dag, protocol_units, setup_results, pdb_file, septop_solv_trajectory_path, septop_solv_checkpoint_path, tmp_path, ): """ Attempt to resume a simulation unit with pre-existing checkpoint & trajectory files. """ self._copy_simfiles(tmp_path, septop_solv_trajectory_path) self._copy_simfiles(tmp_path, septop_solv_checkpoint_path) # 1. Check that the trajectory / checkpoint contain what we expect reporter = MultiStateReporter( tmp_path / "solvent.nc", checkpoint_storage="solvent_checkpoint.nc", ) sampler = ReplicaExchangeSampler.from_storage(reporter) self._check_sampler(sampler, num_iterations=10) # Deep copy energies & positions for later comparison init_energies = copy.deepcopy(reporter.read_energies())[0] assert init_energies.shape == (11, 27, 27) init_positions = self._get_positions(reporter._storage[0]) assert len(init_positions) == 2 reporter.close() del sampler # 2. get & run the units _, sim_unit, analysis_unit = protocol_units # Now we run the simulation in resume mode sim_results = sim_unit.run( setup_results["alchem_restrained_system"], pdb_file, setup_results["selection_indices"], scratch_basepath=tmp_path, shared_basepath=tmp_path, ) # Finally we analyze the results _ = analysis_unit.run( trajectory=sim_results["trajectory"], checkpoint=sim_results["checkpoint"], scratch_basepath=tmp_path, shared_basepath=tmp_path, ) # Analyze the trajectory / checkpoint again reporter = MultiStateReporter( tmp_path / "solvent.nc", checkpoint_storage="solvent_checkpoint.nc", ) sampler = ReplicaExchangeSampler.from_storage(reporter) self._check_sampler(sampler, num_iterations=20) # Check the energies and positions energies = reporter.read_energies()[0] assert energies.shape == (21, 27, 27) assert_allclose(init_energies, energies[:11]) positions = self._get_positions(reporter._storage[0]) assert len(positions) == 3 for i in range(2): assert_allclose(positions[i], init_positions[i]) reporter.close() del sampler # Check the free energy plots are there mbar_overlap_file = tmp_path / "mbar_overlap_matrix.png" assert (mbar_overlap_file).exists() @pytest.mark.slow def test_resume_fail_particles( self, protocol_dag, protocol_units, setup_results, pdb_file, septop_solv_trajectory_path, septop_solv_checkpoint_path, tmp_path, ): """ Test that the run unit will fail with a system incompatible to the one present in the trajectory/checkpoint files. Here we check that we don't have the same particles / mass. """ # copy files self._copy_simfiles(tmp_path, septop_solv_trajectory_path) self._copy_simfiles(tmp_path, septop_solv_checkpoint_path) _, sim_unit, _ = protocol_units # Create a fake system where we will add a particle fake_system = copy.deepcopy(setup_results["alchem_restrained_system"]) fake_system.addParticle(42) # Fake system should trigger a mismatch errmsg = "Stored checkpoint System particles do not" with pytest.raises(ValueError, match=errmsg): _ = sim_unit.run( fake_system, pdb_file, setup_results["selection_indices"], scratch_basepath=tmp_path, shared_basepath=tmp_path, ) @pytest.mark.slow def test_resume_fail_constraints( self, protocol_dag, protocol_units, setup_results, pdb_file, septop_solv_trajectory_path, septop_solv_checkpoint_path, tmp_path, ): """ Test that the run unit will fail with a system incompatible to the one present in the trajectory/checkpoint files. Here we check that we don't have the same constraints. """ # copy files self._copy_simfiles(tmp_path, septop_solv_trajectory_path) self._copy_simfiles(tmp_path, septop_solv_checkpoint_path) _, sim_unit, _ = protocol_units # Create a fake system without constraints fake_system = copy.deepcopy(setup_results["alchem_restrained_system"]) for i in reversed(range(fake_system.getNumConstraints())): fake_system.removeConstraint(i) # Fake system should trigger a mismatch errmsg = "Stored checkpoint System constraints do not" with pytest.raises(ValueError, match=errmsg): _ = sim_unit.run( fake_system, pdb_file, setup_results["selection_indices"], scratch_basepath=tmp_path, shared_basepath=tmp_path, ) @pytest.mark.slow def test_resume_fail_forces( self, protocol_dag, protocol_units, setup_results, pdb_file, septop_solv_trajectory_path, septop_solv_checkpoint_path, tmp_path, ): """ Test that the run unit will fail with a system incompatible to the one present in the trajectory/checkpoint files. Here we check we don't have the same forces. """ # copy files self._copy_simfiles(tmp_path, septop_solv_trajectory_path) self._copy_simfiles(tmp_path, septop_solv_checkpoint_path) _, sim_unit, _ = protocol_units # Create a fake system without the last force fake_system = copy.deepcopy(setup_results["alchem_restrained_system"]) fake_system.removeForce(fake_system.getNumForces() - 1) # Fake system should trigger a mismatch errmsg = "Number of forces stored in checkpoint System" with pytest.raises(ValueError, match=errmsg): _ = sim_unit.run( fake_system, pdb_file, setup_results["selection_indices"], scratch_basepath=tmp_path, shared_basepath=tmp_path, ) @pytest.mark.slow def test_resume_differ_barostat( self, protocol_dag, protocol_units, setup_results, pdb_file, septop_solv_trajectory_path, septop_solv_checkpoint_path, tmp_path, ): """ Test that the run unit will fail with a system incompatible to the one present in the trajectory/checkpoint files. Here we check what happens if you have a different barostat """ # copy files self._copy_simfiles(tmp_path, septop_solv_trajectory_path) self._copy_simfiles(tmp_path, septop_solv_checkpoint_path) _, sim_unit, _ = protocol_units # Create a fake system with the fake force type fake_system = copy.deepcopy(setup_results["alchem_restrained_system"]) # Loop through forces and remove the force matching force type for i, f in enumerate(fake_system.getForces()): if isinstance(f, openmm.MonteCarloBarostat): findex = i fake_system.removeForce(findex) # Now add the new barostat new_force = openmm.MonteCarloBarostat( 1 * openmm.unit.atmosphere, 300 * openmm.unit.kelvin, 100 ) fake_system.addForce(new_force) # Fake system should trigger a mismatch errmsg = "stored checkpoint System does not match the same force" with pytest.raises(ValueError, match=errmsg): _ = sim_unit.run( fake_system, pdb_file, setup_results["selection_indices"], scratch_basepath=tmp_path, shared_basepath=tmp_path, ) @pytest.mark.slow def test_resume_differ_forces( self, protocol_dag, protocol_units, setup_results, pdb_file, septop_solv_trajectory_path, septop_solv_checkpoint_path, tmp_path, caplog, ): """ Test that the run unit will fail with a system incompatible to the one present in the trajectory/checkpoint files. Here we check we have a different force """ # copy files self._copy_simfiles(tmp_path, septop_solv_trajectory_path) self._copy_simfiles(tmp_path, septop_solv_checkpoint_path) _, sim_unit, _ = protocol_units # Create a fake system with the fake force type fake_system = copy.deepcopy(setup_results["alchem_system"]) # Loop through forces and remove the force matching force type for i, f in enumerate(fake_system.getForces()): if isinstance(f, openmm.NonbondedForce): findex = i fake_system.removeForce(findex) # Now add a fake force new_force = openmm.NonbondedForce() new_force.setNonbondedMethod(openmm.NonbondedForce.PME) new_force.addGlobalParameter("lambda_electrostatics_A", 1.0) new_force.addGlobalParameter("lambda_electrostatics_B", 0.0) fake_system.addForce(new_force) # Mismatching force should trigger a warning wmsg = "does not exactly match one of the forces in the simulated System" caplog.set_level(logging.INFO) _ = sim_unit.run( fake_system, pdb_file, setup_results["selection_indices"], scratch_basepath=tmp_path, shared_basepath=tmp_path, ) assert wmsg in caplog.text @pytest.mark.slow @pytest.mark.parametrize("bad_file", ["trajectory", "checkpoint"]) def test_resume_bad_files( self, protocol_dag, protocol_units, setup_results, pdb_file, septop_solv_trajectory_path, septop_solv_checkpoint_path, bad_file, tmp_path, ): """ Test what happens when you have a bad trajectory and/or checkpoint files. """ # copy files if bad_file == "trajectory": with open(tmp_path / "solvent.nc", "w") as f: f.write("foo") else: self._copy_simfiles(tmp_path, septop_solv_trajectory_path) if bad_file == "checkpoint": with open(tmp_path / "solvent_checkpoint.nc", "w") as f: f.write("bar") else: self._copy_simfiles(tmp_path, septop_solv_checkpoint_path) _, sim_unit, _ = protocol_units with pytest.raises(OSError, match="Unknown file format"): _ = sim_unit.run( setup_results["alchem_restrained_system"], pdb_file, setup_results["selection_indices"], scratch_basepath=tmp_path, shared_basepath=tmp_path, ) ================================================ FILE: src/openfe/tests/protocols/openmm_septop/test_septop_settings.py ================================================ # This code is part of OpenFE and is licensed under the MIT license. # For details, see https://github.com/OpenFreeEnergy/openfe import pytest from openfe import ChemicalSystem, SolventComponent from openfe.protocols.openmm_septop import ( SepTopProtocol, ) from openfe.protocols.openmm_septop.equil_septop_settings import SepTopSettings @pytest.fixture() def protocol_dry_settings(): # a set of settings for dry run tests s = SepTopProtocol.default_settings() s.engine_settings.compute_platform = None s.protocol_repeats = 1 return s @pytest.fixture() def default_settings(): s = SepTopProtocol.default_settings() return s def test_create_default_settings(): settings = SepTopProtocol.default_settings() assert settings @pytest.mark.parametrize( "val", [ {"elec": [0.0, -1], "vdw": [0.0, 1.0], "restraints": [0.0, 1.0]}, {"elec": [0.0, 1], "vdw": [0.0, 1.5], "restraints": [0.0, 1.0]}, {"elec": [0.0, 1], "vdw": [0.0, 1], "restraints": [-0.1, 1.0]}, ], ) def test_incorrect_window_settings(val, default_settings): errmsg = "Lambda windows must be between 0 and 1." lambda_settings = default_settings.complex_lambda_settings with pytest.raises(ValueError, match=errmsg): lambda_settings.lambda_elec_A = val["elec"] lambda_settings.lambda_vdw_A = val["vdw"] lambda_settings.lambda_restraints_A = val["restraints"] @pytest.mark.parametrize( "val", [ { "elec": [0.0, 0.1, 0.0], "vdw": [0.0, 1.0, 1.0], "restraints": [0.0, 1.0, 1.0], }, { "elec": [0.0, 0.0, 0.0], "vdw": [0.0, 1.0, 0.0], "restraints": [0.0, 1.0, 1.0], }, { "elec": [0.0, 0.0, 0.0], "vdw": [0.0, 1.0, 1.0], "restraints": [0.0, 1.0, 0.0], }, ], ) def test_monotonic_lambda_windows_A(val, default_settings): errmsg = "The lambda schedule for ligand A" lambda_settings = default_settings.complex_lambda_settings with pytest.raises(ValueError, match=errmsg): lambda_settings.lambda_elec_A = val["elec"] lambda_settings.lambda_vdw_A = val["vdw"] lambda_settings.lambda_restraints_A = val["restraints"] @pytest.mark.parametrize( "val", [ { "elec": [1.0, 0.1, 1.0], "vdw": [1.0, 1.0, 1.0], "restraints": [1.0, 1.0, 1.0], }, { "elec": [1.0, 1.0, 1.0], "vdw": [1.0, 0.0, 1.0], "restraints": [1.0, 1.0, 1.0], }, { "elec": [1.0, 1.0, 1.0], "vdw": [1.0, 1.0, 1.0], "restraints": [1.0, 0.0, 1.0], }, ], ) def test_monotonic_lambda_windows_B(val, default_settings): errmsg = "The lambda schedule for ligand B" lambda_settings = default_settings.complex_lambda_settings with pytest.raises(ValueError, match=errmsg): lambda_settings.lambda_elec_B = val["elec"] lambda_settings.lambda_vdw_B = val["vdw"] lambda_settings.lambda_restraints_B = val["restraints"] def test_output_induces_not_all(default_settings): errmsg = "Equilibration simulations need to output the full system" with pytest.raises(ValueError, match=errmsg): default_settings.complex_equil_output_settings.output_indices = "no water" def test_adaptive_settings_no_protein_membrane(toluene_complex_system, default_settings): settings = SepTopProtocol._adaptive_settings( toluene_complex_system, toluene_complex_system, default_settings ) assert isinstance(settings, SepTopSettings) # Should use default barostat since no ProteinMembraneComponent assert settings.complex_integrator_settings.barostat == "MonteCarloBarostat" def test_adaptive_settings_with_protein_membrane(a2a_protein_membrane_component, a2a_ligands): stateA = ChemicalSystem( { "ligandA": a2a_ligands[0], "protein": a2a_protein_membrane_component, "solvent": SolventComponent(), } ) settings = SepTopProtocol._adaptive_settings(stateA, stateA) assert isinstance(settings, SepTopSettings) # Barostat should have been updated assert settings.complex_integrator_settings.barostat == "MonteCarloMembraneBarostat" ================================================ FILE: src/openfe/tests/protocols/openmm_septop/test_septop_slow.py ================================================ # This code is part of OpenFE and is licensed under the MIT license. # For details, see https://github.com/OpenFreeEnergy/openfe import pathlib import mdtraj as md import numpy as np import openmm import pytest from gufe.protocols import execute_DAG from numpy.testing import assert_allclose from openff.units import unit from openff.units.openmm import from_openmm import openfe from openfe import ChemicalSystem, SolventComponent from openfe.protocols.openmm_septop import ( SepTopProtocol, SepTopSolventSetupUnit, ) from openfe.protocols.openmm_septop.utils import SepTopParameterState from openfe.protocols.openmm_utils.serialization import deserialize @pytest.fixture() def default_settings(): s = SepTopProtocol.default_settings() s.engine_settings.compute_platform = None return s def compare_energies(alchemical_system, positions): alchemical_state = SepTopParameterState.from_system(alchemical_system) from openmmtools.alchemy import AbsoluteAlchemicalFactory energy = AbsoluteAlchemicalFactory.get_energy_components( alchemical_system, alchemical_state, positions ) na_A = "alchemically modified NonbondedForce for non-alchemical/alchemical sterics for region A" na_B = "alchemically modified NonbondedForce for non-alchemical/alchemical sterics for region B" nonbonded = "unmodified NonbondedForce" # Lambda 0: LigandA sterics on, elec on, ligand B sterics off, elec off alchemical_state.lambda_sterics_A = 1 alchemical_state.lambda_sterics_B = 0 alchemical_state.lambda_electrostatics_A = 1 alchemical_state.lambda_electrostatics_B = 0 energy_0 = AbsoluteAlchemicalFactory.get_energy_components( alchemical_system, alchemical_state, positions ) # Lambda 7: LigandA sterics on, elec on, ligand B sterics on, elec off alchemical_state.lambda_sterics_A = 1 alchemical_state.lambda_sterics_B = 1 alchemical_state.lambda_electrostatics_A = 1 alchemical_state.lambda_electrostatics_B = 0 energy_7 = AbsoluteAlchemicalFactory.get_energy_components( alchemical_system, alchemical_state, positions ) # Lambda 8: LigandA sterics on, elec partially on, # ligand B sterics on, elec partially on alchemical_state.lambda_sterics_A = 1 alchemical_state.lambda_sterics_B = 1 alchemical_state.lambda_electrostatics_A = 0.75 alchemical_state.lambda_electrostatics_B = 0.25 energy_8 = AbsoluteAlchemicalFactory.get_energy_components( alchemical_system, alchemical_state, positions ) # Lambda 12: LigandA sterics on, elec off, ligand B sterics on, elec on alchemical_state.lambda_sterics_A = 1 alchemical_state.lambda_sterics_B = 1 alchemical_state.lambda_electrostatics_A = 0 alchemical_state.lambda_electrostatics_B = 1 energy_12 = AbsoluteAlchemicalFactory.get_energy_components( alchemical_system, alchemical_state, positions ) # Lambda 13: LigandA sterics partially on, elec off, ligand B sterics on, elec on alchemical_state.lambda_sterics_A = 0.857142857 alchemical_state.lambda_sterics_B = 1 alchemical_state.lambda_electrostatics_A = 0 alchemical_state.lambda_electrostatics_B = 1 energy_13 = AbsoluteAlchemicalFactory.get_energy_components( alchemical_system, alchemical_state, positions ) return ( na_A, na_B, nonbonded, energy, energy_0, energy_7, energy_8, energy_12, energy_13, ) @pytest.mark.flaky(reruns=3) # pytest-rerunfailures; we can get bad minimisation def test_lambda_energies( eg5_ligands, eg5_protein, eg5_cofactor, tmp_path, default_settings, ): # check system parametrisation works even if confgen fails default_settings.protocol_repeats = 1 default_settings.solvent_equil_simulation_settings.minimization_steps = 100 default_settings.solvent_equil_simulation_settings.equilibration_length_nvt = ( 10 * unit.picosecond ) default_settings.solvent_equil_simulation_settings.equilibration_length = 10 * unit.picosecond default_settings.solvent_equil_simulation_settings.production_length = 1 * unit.picosecond default_settings.solvent_solvation_settings.box_shape = "dodecahedron" default_settings.solvent_solvation_settings.solvent_padding = 1.8 * unit.nanometer protocol = SepTopProtocol( settings=default_settings, ) stateA = ChemicalSystem( { "lig_02": eg5_ligands[0], "protein": eg5_protein, "cofactor": eg5_cofactor, "solvent": SolventComponent(), } ) stateB = ChemicalSystem( { "lig_03": eg5_ligands[1], "protein": eg5_protein, "cofactor": eg5_cofactor, "solvent": SolventComponent(), } ) # Create DAG from protocol, get the vacuum and solvent units # and eventually dry run the first vacuum unit dag = protocol.create( stateA=stateA, stateB=stateB, mapping=None, ) prot_units = list(dag.protocol_units) solv_setup_unit = [u for u in prot_units if isinstance(u, SepTopSolventSetupUnit)] output = solv_setup_unit[0].run(scratch_basepath=tmp_path, shared_basepath=tmp_path) system = output["system"] alchemical_system = deserialize(system) topology = output["topology"] pdb = openmm.app.pdbfile.PDBFile(str(topology)) positions = pdb.getPositions(asNumpy=True) # Remove Harmonic restraint force solvent alchemical_system.removeForce(13) ( na_A, na_B, nonbonded, energy, energy_0, energy_7, energy_8, energy_12, energy_13, ) = compare_energies(alchemical_system, positions) for key, value in energy.items(): if key == na_A: assert_allclose(from_openmm(value), from_openmm(energy_0[key])) assert_allclose(from_openmm(value), from_openmm(energy_7[key])) assert_allclose(from_openmm(value), from_openmm(energy_8[key])) assert_allclose(from_openmm(value), from_openmm(energy_12[key])) assert not np.allclose(from_openmm(value), from_openmm(energy_13[key])) elif key == na_B: assert not np.allclose(from_openmm(value), from_openmm(energy_0[key])) assert_allclose(from_openmm(energy_0[key]), 0) assert_allclose(from_openmm(value), from_openmm(energy_7[key])) assert_allclose(from_openmm(value), from_openmm(energy_8[key])) assert_allclose(from_openmm(value), from_openmm(energy_12[key])) assert_allclose(from_openmm(value), from_openmm(energy_13[key])) elif key == nonbonded: assert not np.allclose(from_openmm(value), from_openmm(energy_0[key])) assert_allclose( from_openmm(energy_0[key]), from_openmm(energy_7[key]), rtol=1e-05, ) assert not np.allclose(from_openmm(energy_0[key]), from_openmm(energy_8[key])) assert not np.allclose(from_openmm(energy_0[key]), from_openmm(energy_12[key])) assert not np.allclose(from_openmm(energy_0[key]), from_openmm(energy_13[key])) else: assert_allclose(from_openmm(value), from_openmm(energy_0[key])) assert_allclose(from_openmm(value), from_openmm(energy_7[key])) assert_allclose(from_openmm(value), from_openmm(energy_8[key])) assert_allclose(from_openmm(value), from_openmm(energy_12[key])) assert_allclose(from_openmm(value), from_openmm(energy_13[key])) @pytest.mark.integration @pytest.mark.flaky(reruns=3) # pytest-rerunfailures; we can get bad minimisation @pytest.mark.parametrize("platform", ["CUDA"]) def test_openmm_run_engine( platform, available_platforms, benzene_modifications, T4_protein_component, tmp_path, default_settings, ): if platform not in available_platforms: pytest.skip(f"OpenMM Platform: {platform} not available") # Run a really short calculation to check everything is going well default_settings.protocol_repeats = 1 default_settings.solvent_output_settings.output_indices = "resname UNK" default_settings.complex_equil_simulation_settings.equilibration_length = 0.1 * unit.picosecond default_settings.complex_equil_simulation_settings.production_length = 0.1 * unit.picosecond default_settings.complex_simulation_settings.equilibration_length = 0.1 * unit.picosecond default_settings.complex_simulation_settings.production_length = 0.1 * unit.picosecond default_settings.solvent_equil_simulation_settings.equilibration_length_nvt = ( 0.1 * unit.picosecond ) default_settings.solvent_equil_simulation_settings.equilibration_length = 0.1 * unit.picosecond default_settings.solvent_equil_simulation_settings.production_length = 0.1 * unit.picosecond default_settings.solvent_simulation_settings.equilibration_length = 0.1 * unit.picosecond default_settings.solvent_simulation_settings.production_length = 0.1 * unit.picosecond default_settings.engine_settings.compute_platform = platform default_settings.complex_simulation_settings.time_per_iteration = 20 * unit.femtosecond default_settings.solvent_simulation_settings.time_per_iteration = 20 * unit.femtosecond default_settings.complex_output_settings.checkpoint_interval = 20 * unit.femtosecond default_settings.solvent_output_settings.checkpoint_interval = 20 * unit.femtosecond protocol = SepTopProtocol( settings=default_settings, ) stateA = openfe.ChemicalSystem( { "benzene": benzene_modifications["benzene"], "T4L": T4_protein_component, "solvent": openfe.SolventComponent(), } ) stateB = openfe.ChemicalSystem( { "toluene": benzene_modifications["toluene"], "T4L": T4_protein_component, "solvent": openfe.SolventComponent(), } ) # Create DAG from protocol dag = protocol.create( stateA=stateA, stateB=stateB, mapping=None, ) r = execute_DAG(dag, shared_basedir=tmp_path, scratch_basedir=tmp_path, keep_shared=True) assert r.ok() for pur in r.protocol_unit_results: unit_shared = tmp_path / f"shared_{pur.source_key}_attempt_0" assert unit_shared.exists() assert pathlib.Path(unit_shared).is_dir() if "SepTopComplexRunUnit" in pur.source_key.split("-") or "SepTopSolventRunUnit" in pur.source_key.split("-"): # fmt: skip checkpoint = pur.outputs["checkpoint"] assert checkpoint == unit_shared / f"{pur.outputs['simtype']}_checkpoint.nc" assert (unit_shared / checkpoint).exists() nc = pur.outputs["trajectory"] assert nc == unit_shared / f"{pur.outputs['simtype']}.nc" assert nc.exists() # Test results methods that need files present results = protocol.gather([r]) states = results.get_replica_states() assert len(states.items()) == 2 assert len(states["solvent"]) == 1 assert states["solvent"][0].shape[1] == 27 @pytest.mark.flaky(reruns=1) # pytest-rerunfailures; we can get bad minimisation @pytest.mark.parametrize("platform", ["CUDA"]) def test_restraints_solvent( platform, available_platforms, benzene_complex_system, toluene_complex_system, tmp_path, default_settings, ): if platform not in available_platforms: pytest.skip(f"OpenMM Platform: {platform} not available") # Run a really short calculation to check everything is going well default_settings.protocol_repeats = 1 default_settings.solvent_equil_simulation_settings.equilibration_length_nvt = ( 10 * unit.picosecond ) default_settings.solvent_equil_simulation_settings.equilibration_length = 10 * unit.picosecond default_settings.solvent_equil_simulation_settings.production_length = 10 * unit.picosecond default_settings.engine_settings.compute_platform = platform protocol = SepTopProtocol( settings=default_settings, ) # Create DAG from protocol, get the vacuum and solvent units # and eventually dry run the first solvent unit dag = protocol.create( stateA=benzene_complex_system, stateB=toluene_complex_system, mapping=None, ) prot_units = list(dag.protocol_units) solv_setup_unit = [u for u in prot_units if isinstance(u, SepTopSolventSetupUnit)] solv_setup_output = solv_setup_unit[0].run(scratch_basepath=tmp_path, shared_basepath=tmp_path) pdb = md.load_pdb(tmp_path / "topology.pdb") assert pdb.n_atoms == 1762 central_atoms = np.array([[2, 19]], dtype=np.int32) distance = md.compute_distances(pdb, central_atoms)[0][0] # For right now just checking that ligands at least somewhat apart assert distance > 0.5 ================================================ FILE: src/openfe/tests/protocols/openmm_septop/test_septop_tokenization.py ================================================ # This code is part of OpenFE and is licensed under the MIT license. # For details, see https://github.com/OpenFreeEnergy/openfe import json import gufe import pytest from gufe.tests.test_tokenization import GufeTokenizableTestsMixin from openfe.protocols import openmm_septop @pytest.fixture def protocol(): return openmm_septop.SepTopProtocol(openmm_septop.SepTopProtocol.default_settings()) @pytest.fixture def protocol_units(protocol, benzene_complex_system, toluene_complex_system): pus = protocol.create( stateA=benzene_complex_system, stateB=toluene_complex_system, mapping=None, ) return list(pus.protocol_units) @pytest.fixture def solvent_setup_protocol_unit(protocol_units): for pu in protocol_units: if isinstance(pu, openmm_septop.SepTopSolventSetupUnit): return pu @pytest.fixture def solvent_run_protocol_unit(protocol_units): for pu in protocol_units: if isinstance(pu, openmm_septop.SepTopSolventRunUnit): return pu @pytest.fixture def solvent_analysis_protocol_unit(protocol_units): for pu in protocol_units: if isinstance(pu, openmm_septop.SepTopSolventAnalysisUnit): return pu @pytest.fixture def complex_setup_protocol_unit(protocol_units): for pu in protocol_units: if isinstance(pu, openmm_septop.SepTopComplexSetupUnit): return pu @pytest.fixture def complex_run_protocol_unit(protocol_units): for pu in protocol_units: if isinstance(pu, openmm_septop.SepTopComplexRunUnit): return pu @pytest.fixture def complex_analysis_protocol_unit(protocol_units): for pu in protocol_units: if isinstance(pu, openmm_septop.SepTopComplexAnalysisUnit): return pu @pytest.fixture def protocol_result(septop_json): d = json.loads( septop_json, cls=gufe.tokenization.JSON_HANDLER.decoder, ) pr = openmm_septop.SepTopProtocolResult.from_dict(d["protocol_result"]) return pr class TestSepTopProtocol(GufeTokenizableTestsMixin): cls = openmm_septop.SepTopProtocol key = None repr = " 1], aromatic_only=aromatic, ) assert angles == expected def test_sort_by_distance(eg5_ligands): rd_mol = eg5_ligands[0].to_rdkit() sorted_atoms = _sort_by_distance_from_atom(rdmol=rd_mol, target_idx=33, atom_idxs=[1, 12, 18]) assert sorted_atoms == [12, 18, 1] def test_get_guest_atom_pool(eg5_ligands): rd_mol = eg5_ligands[0].to_rdkit() rmsf = np.zeros(rd_mol.GetNumAtoms()) * unit.nanometer pool_atoms, rings = _get_guest_atom_pool( rdmol=rd_mol, rmsf=rmsf, rmsf_cutoff=0.1 * unit.nanometer ) # make sure only rings were found assert rings # make sure all aromatic ring atoms are found rings = get_aromatic_rings(rd_mol) ring_atoms = [a for ring in rings for a in ring] assert pool_atoms == set(ring_atoms) def test_get_guest_atom_pool_all_heavy(eg5_ligands): rd_mol = eg5_ligands[0].to_rdkit() rmsf = np.zeros(rd_mol.GetNumAtoms()) * unit.nanometer rings = get_aromatic_rings(rd_mol) ring_atoms = [a for ring in rings for a in ring] # add high rmsf values for all ring atoms for i in ring_atoms: rmsf[i] = 1 * unit.nanometer pool_atoms, rings = _get_guest_atom_pool( rdmol=rd_mol, rmsf=rmsf, rmsf_cutoff=0.1 * unit.nanometer ) # make sure no rings were found assert not rings # make sure we get heavy atoms with no rings heavy_atoms = get_heavy_atom_idxs(rd_mol) assert pool_atoms == set(heavy_atoms) - set(ring_atoms) def test_get_guest_atom_pool_no_atoms(eg5_ligands): rd_mol = eg5_ligands[0].to_rdkit() rmsf = np.ones(rd_mol.GetNumAtoms()) * unit.nanometer pool_atoms, rings = _get_guest_atom_pool( rdmol=rd_mol, rmsf=rmsf, rmsf_cutoff=0.1 * unit.nanometer ) # make sure no rings were found assert not rings # make sure no atoms are returned assert pool_atoms is None def test_find_guest_atoms_normal(eg5_ligands): rd_mol = eg5_ligands[0].to_rdkit() lig = mda.Universe(rd_mol) angles = find_guest_atom_candidates( universe=lig, rdmol=rd_mol, guest_idxs=[a.ix for a in lig.atoms], ) assert len(angles) == 24 def test_find_guest_atoms_no_atom_pool(): with pytest.raises(ValueError, match="No suitable ligand atoms were found for the restraint"): lig = mda.Universe.from_smiles("CC") _ = find_guest_atom_candidates( universe=lig, rdmol=lig.atoms.convert_to("RDKIT"), guest_idxs=[a.ix for a in lig.atoms], ) ================================================ FILE: src/openfe/tests/protocols/restraints/test_geometry_boresch_host.py ================================================ # This code is part of OpenFE and is licensed under the MIT license. # For details, see https://github.com/OpenFreeEnergy/openfe import os import MDAnalysis as mda import numpy as np import pytest from numpy.testing import assert_equal from openff.units import unit from openfe.data._registry import POOCH_CACHE from openfe.protocols.restraint_utils.geometry.boresch.host import ( EvaluateBoreschAtoms, EvaluateHostAtoms1, EvaluateHostAtoms2, find_host_anchor_bonded, find_host_anchor_multi, find_host_atom_candidates, ) from openfe.protocols.restraint_utils.geometry.utils import ( check_angle_not_flat, check_dihedral_bounds, is_collinear, ) from ...conftest import HAS_INTERNET @pytest.fixture def eg5_protein_ligand_universe(eg5_protein_pdb, eg5_ligands): protein = mda.Universe(eg5_protein_pdb) lig = mda.Universe(eg5_ligands[1].to_rdkit()) # add the residue name of the ligand lig.add_TopologyAttr("resname", ["LIG"]) return mda.Merge(protein.atoms, lig.atoms) @pytest.fixture def eg5_protein_ligand_universe_bonded(eg5_protein_pdb, eg5_ligands): protein = mda.Universe(eg5_protein_pdb) lig = mda.Universe(eg5_ligands[1].to_rdkit()) # add the residue name of the ligand lig.add_TopologyAttr("resname", ["LIG"]) merged_u = mda.Merge(protein.atoms, lig.atoms) merged_u.guess_TopologyAttrs(context="default", to_guess=["bonds", "angles"]) return merged_u def test_host_atom_candidates_dssp(eg5_protein_ligand_universe): """ Run DSSP search normally """ host_atoms = eg5_protein_ligand_universe.select_atoms("protein") idxs = find_host_atom_candidates( universe=eg5_protein_ligand_universe, host_idxs=host_atoms.ix, # hand picked guest_anchor_idx=5508, host_selection="backbone and resnum 212:221", dssp_filter=True, ) expected = np.array( [ 3144, 3146, 3145, 3143, 3162, 3206, 3200, 3207, 3126, 3201, 3127, 3163, 3199, 3202, 3164, 3125, 3165, 3177, 3208, 3179, 3124, 3216, 3209, 3109, 3107, 3178, 3110, 3180, 3108, 3248, 3217, 3249, 3226, 3218, 3228, 3227, 3250, 3219, 3251, 3229 ] ) # fmt: skip assert_equal(idxs, expected) def test_host_atom_candidates_dssp_too_few_atoms(eg5_protein_ligand_universe): """ Make sure both dssp warnings are triggered """ host_atoms = eg5_protein_ligand_universe.select_atoms("protein") with ( pytest.warns(match="DSSP filter found"), pytest.warns(match="protein chain filter found"), ): _ = find_host_atom_candidates( universe=eg5_protein_ligand_universe, host_idxs=host_atoms.ix, # hand picked guest_anchor_idx=5508, host_selection="backbone and resnum 15:25", dssp_filter=True, max_search_distance=2 * unit.nanometer, ) def test_host_atom_candidate_small_search(eg5_protein_ligand_universe): host_atoms = eg5_protein_ligand_universe.select_atoms("protein") with pytest.raises(ValueError, match="No host atoms found within the search distance"): _ = find_host_atom_candidates( universe=eg5_protein_ligand_universe, host_idxs=host_atoms.ix, # hand picked guest_anchor_idx=5508, host_selection="backbone", dssp_filter=False, max_search_distance=0.1 * unit.angstrom, ) def test_evaluate_host1_bad_ref(eg5_protein_ligand_universe): with pytest.raises(ValueError, match="Incorrect number of reference atoms passed"): _ = EvaluateHostAtoms1( reference=eg5_protein_ligand_universe.atoms, host_atom_pool=eg5_protein_ligand_universe.atoms, angle_force_constant=83.68 * unit.kilojoule_per_mole / unit.radians**2, temperature=298.15 * unit.kelvin, minimum_distance=1 * unit.nanometer, ) def test_evaluate_host1_good(eg5_protein_ligand_universe): angle_fc = 83.68 * unit.kilojoule_per_mole / unit.radians**2 min_distance = 1 * unit.nanometer temp = 298.15 * unit.kelvin ho_eval = EvaluateHostAtoms1( # picked from a successful boresch restraint search reference=eg5_protein_ligand_universe.atoms[[5528, 5507, 5508]], host_atom_pool=eg5_protein_ligand_universe.select_atoms("backbone and resnum 239"), minimum_distance=min_distance, angle_force_constant=angle_fc, temperature=temp, ) # make sure properties are used during the evaluation assert ho_eval.minimum_distance == min_distance.to("angstrom").m assert ho_eval.temperature == temp assert ho_eval.angle_force_constant == angle_fc ho_eval.run() # make sure all atoms in this residue are valid as this is the residue selected # during the automated search assert ho_eval.results.valid.all() assert not ho_eval.results.collinear.all() assert np.allclose( ho_eval.results.distances, np.array([[10.79778922], [10.15903706], [11.19430463], [11.36472103]]), ) assert np.allclose( ho_eval.results.angles, np.array([[1.26279048], [1.23561539], [1.15134184], [1.04697413]]), ) assert np.allclose( ho_eval.results.dihedrals, np.array([[0.10499465], [-0.02396901], [-0.09271532], [-0.06136335]]), ) def test_evaluate_host2_good(eg5_protein_ligand_universe): h2_eval = EvaluateHostAtoms2( # picked from a successful boresch restraint search reference=eg5_protein_ligand_universe.atoms[[5528, 5507, 5508]], host_atom_pool=eg5_protein_ligand_universe.select_atoms("backbone and resnum 264"), minimum_distance=1 * unit.nanometer, angle_force_constant=83.68 * unit.kilojoule_per_mole / unit.radians**2, temperature=298.15 * unit.kelvin, ) h2_eval.run() # make sure all atoms in this residue are valid as this is the residue selected # during the automated search assert h2_eval.results.valid.all() assert not h2_eval.results.collinear.all() assert np.allclose( h2_eval.results.distances1, np.array([[12.91959211], [13.2744748], [12.9710364], [13.44522909]]), ) assert np.allclose( h2_eval.results.distances2, np.array([[12.2098888], [12.68587248], [12.38582154], [12.77150153]]), ) assert np.allclose( h2_eval.results.dihedrals, np.array([[0.4069051], [0.46465918], [0.59372385], [0.65580398]]), ) @pytest.mark.slow class TestFindAnchorMulti: # G0-G1-G2 guest_atoms = [5528, 5507, 5508] ref_anchor_indices = [133, 1, 16] ref_h0g0_distance = 20.612924 ref_h0h1_distance = 25.805103 ref_h0h2_distance = 19.68613 ref_h1h2_distance = 7.47768 @pytest.fixture def universe(self, eg5_protein_ligand_universe): return eg5_protein_ligand_universe @pytest.fixture def host_anchor(self, universe): return find_host_anchor_multi( guest_atoms=universe.atoms[self.guest_atoms], host_atom_pool=universe.select_atoms("backbone"), host_minimum_distance=0.5 * unit.nanometer, guest_minimum_distance=2 * unit.nanometer, angle_force_constant=83.68 * unit.kilojoule_per_mole / unit.radians**2, temperature=298.15 * unit.kelvin, ) def test_anchor_regression(self, host_anchor): # regression test the anchor we find assert_equal(host_anchor, self.ref_anchor_indices) def test_host_guest_bond_distance(self, host_anchor, universe): # check that the l0 g0 distance is at least the `guest_minimum_distance` (2nm) for the `host_anchor` fixture. dist = mda.lib.distances.calc_bonds( universe.atoms[host_anchor[0]].position, universe.atoms[self.guest_atoms[0]].position, box=universe.dimensions, ) assert dist == pytest.approx(self.ref_h0g0_distance, abs=1e-5) def test_host_distances(self, host_anchor, universe): # check the h0-h1, h1-h2, and h0-h2 distances for i, j, ref in [ [0, 1, self.ref_h0h1_distance], [1, 2, self.ref_h1h2_distance], [0, 2, self.ref_h0h2_distance], ]: dist = mda.lib.distances.calc_bonds( universe.atoms[host_anchor[i]].position, universe.atoms[host_anchor[j]].position, box=universe.dimensions, ) assert dist == pytest.approx(ref, abs=1e-5) def test_not_collinear(self, host_anchor, universe): # check none of the g2-g1-g0-h0-h1-h2 vectors are not collinear assert not is_collinear( positions=np.vstack( ( universe.atoms[self.guest_atoms[::-1]].positions, universe.atoms[host_anchor].positions, ) ), atoms=[0, 1, 2, 3, 4, 5], dimensions=universe.dimensions, ) def test_angles(self, host_anchor, universe): # check that the angles aren't flat ag1 = mda.lib.distances.calc_angles( universe.atoms[self.guest_atoms[1]].position, universe.atoms[self.guest_atoms[0]].position, universe.atoms[host_anchor[0]].position, box=universe.dimensions, ) ag2 = mda.lib.distances.calc_angles( universe.atoms[self.guest_atoms[0]].position, universe.atoms[host_anchor[0]].position, universe.atoms[host_anchor[1]].position, box=universe.dimensions, ) for angle in [ag1, ag2]: assert check_angle_not_flat( angle=angle * unit.radians, force_constant=83.68 * unit.kilojoule_per_mole / unit.radians**2, temperature=298.15 * unit.kelvin, ) def test_dihedrals(self, host_anchor, universe): dih1 = mda.lib.distances.calc_dihedrals( universe.atoms[self.guest_atoms[2]].position, universe.atoms[self.guest_atoms[1]].position, universe.atoms[self.guest_atoms[0]].position, universe.atoms[host_anchor[0]].position, box=universe.dimensions, ) dih2 = mda.lib.distances.calc_dihedrals( universe.atoms[self.guest_atoms[1]].position, universe.atoms[self.guest_atoms[0]].position, universe.atoms[host_anchor[0]].position, universe.atoms[host_anchor[1]].position, box=universe.dimensions, ) dih3 = mda.lib.distances.calc_dihedrals( universe.atoms[self.guest_atoms[0]].position, universe.atoms[host_anchor[0]].position, universe.atoms[host_anchor[1]].position, universe.atoms[host_anchor[2]].position, box=universe.dimensions, ) assert check_dihedral_bounds(dih1 * unit.radians) assert check_dihedral_bounds(dih2 * unit.radians) assert check_dihedral_bounds(dih3 * unit.radians) @pytest.mark.slow class TestFindAnchorBonded(TestFindAnchorMulti): ref_anchor_indices = [133, 119, 118] ref_h0g0_distance = 20.612924 ref_h0h1_distance = 1.34244 ref_h0h2_distance = 2.44758 ref_h1h2_distance = 1.53359 @pytest.fixture def universe(self, eg5_protein_ligand_universe_bonded): return eg5_protein_ligand_universe_bonded @pytest.fixture def host_anchor(self, universe): return find_host_anchor_bonded( guest_atoms=universe.atoms[self.guest_atoms], host_atom_pool=universe.select_atoms("backbone"), guest_minimum_distance=0.5 * unit.nanometer, angle_force_constant=83.68 * unit.kilojoule_per_mole / unit.radians**2, temperature=298.15 * unit.kelvin, ) @pytest.mark.slow @pytest.mark.skipif( not os.path.exists(POOCH_CACHE) and not HAS_INTERNET, reason="Internet seems to be unavailable and test data is not cached locally.", ) class TestFindAnchorBondedTrajectory(TestFindAnchorMulti): guest_atoms = [2611, 2612, 2613] ref_anchor_indices = [1253, 1254, 1255] ref_h0g0_distance = 13.08494 ref_h0h1_distance = 1.50217 ref_h0h2_distance = 2.61515 ref_h1h2_distance = 1.55881 @pytest.fixture(scope="class") def universe(self, t4_lysozyme_trajectory_dir): cache_dir = t4_lysozyme_trajectory_dir universe = mda.Universe( str(cache_dir / "t4_toluene_complex.pdb"), str(cache_dir / "t4_toluene_complex.xtc"), ) # guess bonds for the protein atoms universe.select_atoms("protein").guess_bonds() return universe @pytest.fixture(scope="class") def host_anchor(self, universe): return find_host_anchor_bonded( guest_atoms=universe.atoms[self.guest_atoms], host_atom_pool=universe.select_atoms("backbone"), guest_minimum_distance=0.0 * unit.nanometer, angle_force_constant=83.68 * unit.kilojoule_per_mole / unit.radians**2, temperature=298.15 * unit.kelvin, ) def test_boresch_evaluation_noatomgroup_error(): errmsg = "Need to have at least one restraint" with pytest.raises(ValueError, match=errmsg): EvaluateBoreschAtoms( restraints=[], angle_force_constant=83.68 * unit.kilojoule_per_mole / unit.radians**2, temperature=298.15 * unit.kelvin, ) def test_boresch_evaluation_incorrectnumber_error(eg5_protein_ligand_universe): ag = eg5_protein_ligand_universe.atoms[:4] errmsg = "Incorrect number of restraint atoms passed" with pytest.raises(ValueError, match=errmsg): EvaluateBoreschAtoms( restraints=[ag], angle_force_constant=83.68 * unit.kilojoule_per_mole / unit.radians**2, temperature=298.15 * unit.kelvin, ) @pytest.mark.slow def test_find_host_anchor_multi_none(eg5_protein_ligand_universe): host_anchor = find_host_anchor_multi( guest_atoms=eg5_protein_ligand_universe.atoms[[5528, 5507, 5508]], host_atom_pool=eg5_protein_ligand_universe.select_atoms("backbone"), # Setting host and guest minimum distances to a large value so # we find no atoms. host_minimum_distance=4.5 * unit.nanometer, guest_minimum_distance=4.5 * unit.nanometer, angle_force_constant=83.68 * unit.kilojoule_per_mole / unit.radians**2, temperature=298.15 * unit.kelvin, ) # we should get None if no atoms can be found assert host_anchor is None @pytest.mark.slow def test_find_host_anchor_bonded_none(eg5_protein_ligand_universe_bonded): host_anchor = find_host_anchor_bonded( guest_atoms=eg5_protein_ligand_universe_bonded.atoms[[5528, 5507, 5508]], host_atom_pool=eg5_protein_ligand_universe_bonded.select_atoms("backbone"), # Setting host and guest minimum distances to a large value so # we find no atoms. guest_minimum_distance=4.5 * unit.nanometer, angle_force_constant=83.68 * unit.kilojoule_per_mole / unit.radians**2, temperature=298.15 * unit.kelvin, ) # we should get None if no atoms can be found assert host_anchor is None @pytest.mark.slow def test_find_host_anchor_bonded_nobonds_none(eg5_protein_ligand_universe): # No angles were found, so it will attempt to find some # It'll fail because there are no bonds available. with pytest.warns(UserWarning, match="no angles found"): host_anchor = find_host_anchor_bonded( guest_atoms=eg5_protein_ligand_universe.atoms[[5528, 5507, 5508]], host_atom_pool=eg5_protein_ligand_universe.select_atoms("backbone"), # Setting host and guest minimum distances to a large value so # we find no atoms. guest_minimum_distance=0.5 * unit.nanometer, angle_force_constant=83.68 * unit.kilojoule_per_mole / unit.radians**2, temperature=298.15 * unit.kelvin, ) # we should get None if no atoms can be found assert host_anchor is None ================================================ FILE: src/openfe/tests/protocols/restraints/test_geometry_flatbottom.py ================================================ # This code is part of OpenFE and is licensed under the MIT license. # For details, see https://github.com/OpenFreeEnergy/openfe import MDAnalysis as mda import pytest from openff.units import unit from openfe.protocols.restraint_utils.geometry.flatbottom import ( FlatBottomDistanceGeometry, get_flatbottom_distance_restraint, ) @pytest.fixture() def eg5_protein_ligand_universe(eg5_protein_pdb, eg5_ligands): protein = mda.Universe(eg5_protein_pdb) lig = mda.Universe(eg5_ligands[1].to_rdkit()) # add the residue name of the ligand lig.add_TopologyAttr("resname", ["LIG"]) return mda.Merge(protein.atoms, lig.atoms) def test_no_atoms_found(eg5_protein_ligand_universe): with pytest.raises(ValueError, match="no atoms found in either the host or guest"): _ = get_flatbottom_distance_restraint( universe=eg5_protein_ligand_universe, # the protein starts at 15 host_selection="resnum 2", # the ligand is resnum 1, get only the heavy atoms guest_selection="resname LIG and not name H*", ) @pytest.mark.parametrize( "padding, well_radius", [ pytest.param(0.5, 0.666, id="0.5"), pytest.param(0.8, 0.966, id="0.8"), ], ) def test_get_flatbottom_restraint_from_selection(eg5_protein_ligand_universe, padding, well_radius): expected_guest_atoms = eg5_protein_ligand_universe.select_atoms("resname LIG and not name H*") water_atoms = eg5_protein_ligand_universe.select_atoms("resname HOH") restraint_geometry = get_flatbottom_distance_restraint( universe=eg5_protein_ligand_universe, # select all residues around the ligand host_selection="backbone and same resid as (around 4 resname LIG) and not resname HOH", # get all heavy atoms in the ligand guest_selection="resname LIG and not name H*", padding=padding * unit.nanometer, ) # make sure the guest atoms cover all heavy atoms in the ligand assert restraint_geometry.guest_atoms == [a.ix for a in expected_guest_atoms] # make sure no water atoms are selected as a host assert not any(a.ix for a in water_atoms if a.ix in restraint_geometry.host_atoms) assert isinstance(restraint_geometry, FlatBottomDistanceGeometry) # probably could have a tighter check if we wanted assert well_radius == pytest.approx(restraint_geometry.well_radius.to("nanometer").m, abs=1e-4) def test_get_flatbottom_restraint_from_atoms(eg5_protein_ligand_universe): expected_guest_atoms = eg5_protein_ligand_universe.select_atoms("resname LIG and not name H*") host_atoms = eg5_protein_ligand_universe.select_atoms( "backbone and same resid as (around 4 resname LIG) and not resname HOH" ) host_atom_ix = [a.ix for a in host_atoms] restraint_geometry = get_flatbottom_distance_restraint( universe=eg5_protein_ligand_universe, # take all host atoms within 4 angstroms host_atoms=host_atom_ix, # take the first few ligand atoms guest_atoms=[5496, 5497, 5498, 5500], ) guest_atoms = [a.ix for a in expected_guest_atoms] assert all(i in guest_atoms for i in restraint_geometry.guest_atoms) assert restraint_geometry.host_atoms == host_atom_ix assert 1.1415 == pytest.approx(restraint_geometry.well_radius.to("nanometer").m, abs=1e-4) ================================================ FILE: src/openfe/tests/protocols/restraints/test_geometry_harmonic.py ================================================ # This code is part of OpenFE and is licensed under the MIT license. # For details, see https://github.com/OpenFreeEnergy/openfe import MDAnalysis as mda import pytest from openfe.protocols.restraint_utils.geometry.harmonic import ( DistanceRestraintGeometry, get_distance_restraint, get_molecule_centers_restraint, ) @pytest.fixture() def eg5_protein_ligand_universe(eg5_protein_pdb, eg5_ligands): protein = mda.Universe(eg5_protein_pdb) lig = mda.Universe(eg5_ligands[1].to_rdkit()) # add the residue name of the ligand lig.add_TopologyAttr("resname", ["LIG"]) return mda.Merge(protein.atoms, lig.atoms) def test_hostguest_geometry(): """ A very basic will it build test. """ geom = DistanceRestraintGeometry(guest_atoms=[1, 2, 3], host_atoms=[4]) assert isinstance(geom, DistanceRestraintGeometry) def test_get_distance_restraint_selection(eg5_protein_ligand_universe): """ Check that you get a distance restraint using atom selections. """ expected_guest_atoms = eg5_protein_ligand_universe.select_atoms("resname LIG and not name H*") water_atoms = eg5_protein_ligand_universe.select_atoms("resname HOH") restraint_geometry = get_distance_restraint( universe=eg5_protein_ligand_universe, host_selection="backbone and same resid as (around 4 resname LIG) and not resname HOH", guest_selection="resname LIG and not name H*", ) # make sure the guest atoms cover all heavy atoms in the ligand assert restraint_geometry.guest_atoms == [a.ix for a in expected_guest_atoms] # make sure no water atoms are selected as a host assert not any(a.ix for a in water_atoms if a.ix in restraint_geometry.host_atoms) assert isinstance(restraint_geometry, DistanceRestraintGeometry) def test_get_distance_restraint_atom_list(eg5_protein_ligand_universe): """ Check that we can get a restraint using a set of host and guest atom lists """ expected_guest_atoms = eg5_protein_ligand_universe.select_atoms("resname LIG and not name H*") host_atoms = [1, 2, 3] restraint_geometry = get_distance_restraint( universe=eg5_protein_ligand_universe, # take the first few protein atoms host_atoms=host_atoms, # take the first few ligand atoms guest_atoms=[5496, 5497, 5498, 5500], ) guest_atoms = [a.ix for a in expected_guest_atoms] assert all(i in guest_atoms for i in restraint_geometry.guest_atoms) assert restraint_geometry.host_atoms == host_atoms def test_get_molecule_centers_restraint(eg5_ligands): """ Create a centers distance restraint between pairs of ligands """ ligand_a, ligand_b = eg5_ligands lig_a_rdmol = ligand_a.to_rdkit() n_atoms_a = lig_a_rdmol.GetNumAtoms() lig_b_rdmol = ligand_b.to_rdkit() restraint_geometry = get_molecule_centers_restraint( molA_rdmol=lig_a_rdmol, molB_rdmol=lig_b_rdmol, molA_idxs=[i for i in range(n_atoms_a)], molB_idxs=[i + n_atoms_a for i in range(lig_b_rdmol.GetNumAtoms())], ) assert isinstance(restraint_geometry, DistanceRestraintGeometry) assert restraint_geometry.guest_atoms[0] <= n_atoms_a assert restraint_geometry.host_atoms[0] > n_atoms_a ================================================ FILE: src/openfe/tests/protocols/restraints/test_geometry_utils.py ================================================ # This code is part of OpenFE and is licensed under the MIT license. # For details, see https://github.com/OpenFreeEnergy/openfe import itertools import os from importlib import resources import MDAnalysis as mda import numpy as np import pytest from openff.units import unit from rdkit import Chem from openfe.data._registry import POOCH_CACHE from openfe.protocols.restraint_utils.geometry.utils import ( CentroidDistanceSort, FindHostAtoms, _atomgroup_has_bonds, _get_mda_selection, _wrap_angle, check_angle_not_flat, check_angular_variance, check_dihedral_bounds, get_aromatic_atom_idxs, get_aromatic_rings, get_central_atom_idx, get_heavy_atom_idxs, get_local_rmsf, is_collinear, protein_chain_selection, stable_secondary_structure_selection, ) from ...conftest import HAS_INTERNET @pytest.fixture(scope="module") def eg5_pdb_universe(eg5_protein_pdb): return mda.Universe(eg5_protein_pdb) @pytest.fixture def eg5_protein_ligand_universe(eg5_protein_pdb, eg5_ligands): protein = mda.Universe(eg5_protein_pdb) lig = mda.Universe(eg5_ligands[1].to_rdkit()) # add the residue name of the ligand lig.add_TopologyAttr("resname", ["LIG"]) return mda.Merge(protein.atoms, lig.atoms) @pytest.fixture def beta_barrel_universe(): with resources.as_file(resources.files("openfe.tests.data")) as d: beta_barrel_universe = mda.Universe(str(d / "6CZJ.pdb.gz")) return beta_barrel_universe def test_mda_selection_none_error(eg5_pdb_universe): with pytest.raises(ValueError, match="one of either"): _ = _get_mda_selection(eg5_pdb_universe) def test_mda_selection_both_args_error(eg5_pdb_universe): with pytest.raises(ValueError, match="both atom_list and"): _ = _get_mda_selection(eg5_pdb_universe, atom_list=[0, 1, 2, 3], selection="all") def test_mda_selection_universe_atom_list(eg5_pdb_universe): test_ag = _get_mda_selection(eg5_pdb_universe, atom_list=[0, 1, 2]) assert eg5_pdb_universe.atoms[[0, 1, 2]] == test_ag def test_mda_selection_atomgroup_string(eg5_pdb_universe): # test that the selection is reducing the atom group test_ag = _get_mda_selection(eg5_pdb_universe.atoms, selection="protein") assert test_ag != eg5_pdb_universe.atoms assert test_ag.n_atoms == 5474 @pytest.mark.parametrize( "smiles, expected", [ ["C1CCCCC1", []], ["[C@@H]1([C@@H]([C@@H](OC([C@@H]1O)O)C(=O)O)O)O", []], ["C1=CC=CC=C1", [6]], ["C1=CC2C=CC1C=C2", [8]], ["C1CC2=CC=CC=C2C1", [6]], ["C1=COC=C1", [5]], ["C1=CC=C2C=CC=CC2=C1", [10]], ["C1=CC=C(C=C1)C2=CC=CC=C2", [6, 6]], ["C1=CC=C(C=C1)C(C2=CC=CC=C2)(C3=CC=CC=C3Cl)N4C=CN=C4", [6, 6, 6, 5]], ], ) def test_aromatic_rings(smiles, expected): mol = Chem.AddHs(Chem.MolFromSmiles(smiles)) # get the rings rings = get_aromatic_rings(mol) # check we have the right number of rings & their size for i, r in enumerate(rings): assert len(r) == expected[i] # check that there is no overlap in atoms between each ring for x, y in itertools.combinations(rings, 2): assert x.isdisjoint(y) # get the aromatic idx arom_idxs = get_aromatic_atom_idxs(mol) # Check that all the ring indices are aromatic assert all(idx in arom_idxs for idx in itertools.chain(*rings)) # Also check the lengths match assert sum(len(r) for r in rings) == len(arom_idxs) # Finally check that all the arom_idxs are actually aromatic for idx in arom_idxs: at = mol.GetAtomWithIdx(idx) assert at.GetIsAromatic() @pytest.mark.parametrize( "smiles, nheavy, nlight", [ ["C1CCCCC1", 6, 12], ["[C@@H]1([C@@H]([C@@H](OC([C@@H]1O)O)C(=O)O)O)O", 13, 10], ["C1=CC=CC=C1", 6, 6], ["C1=CC2C=CC1C=C2", 8, 8], ["C1CC2=CC=CC=C2C1", 9, 10], ["C1=COC=C1", 5, 4], ["C1=CC=C2C=CC=CC2=C1", 10, 8], ["C1=CC=C(C=C1)C2=CC=CC=C2", 12, 10], ["C1=CC=C(C=C1)C(C2=CC=CC=C2)(C3=CC=CC=C3Cl)N4C=CN=C4", 25, 17], ], ) def test_heavy_atoms(smiles, nheavy, nlight): mol = Chem.AddHs(Chem.MolFromSmiles(smiles)) n_atoms = len(list(mol.GetAtoms())) heavy_atoms = get_heavy_atom_idxs(mol) # check all the heavy atoms are indeed heavy for idx in heavy_atoms: at = mol.GetAtomWithIdx(idx) assert at.GetAtomicNum() > 1 assert len(heavy_atoms) == nheavy assert n_atoms == nheavy + nlight @pytest.mark.parametrize( "smiles, idx", [ ["C1CCCCC1", 2], ["[C@@H]1([C@@H]([C@@H](OC([C@@H]1O)O)C(=O)O)O)O", 3], ["C1=CC=CC=C1", 2], ["C1=CC2C=CC1C=C2", 2], ["C1CC2=CC=CC=C2C1", 2], ["C1=COC=C1", 4], ["C1=CC=C2C=CC=CC2=C1", 3], ["C1=CC=C(C=C1)C2=CC=CC=C2", 6], ["C1=CC=C(C=C1)C(C2=CC=CC=C2)(C3=CC=CC=C3Cl)N4C=CN=C4", 6], ["OC(COc1ccc(cc1)CC(=O)N)CNC(C)C", 3], ], ) def test_central_idx(smiles, idx): """ Regression tests for getting central atom idx. """ rdmol = Chem.AddHs(Chem.MolFromSmiles(smiles)) assert get_central_atom_idx(rdmol) == idx def test_central_atom_disconnected(): mol = Chem.AddHs(Chem.MolFromSmiles("C.C")) with pytest.raises(ValueError, match="disconnected molecule"): _ = get_central_atom_idx(mol) def test_collinear_too_few_atoms(): with pytest.raises(ValueError, match="Too few atoms passed"): _ = is_collinear(None, [1, 2], None) def test_collinear_index_match_error_length(): with pytest.raises(ValueError, match="indices do not match"): _ = is_collinear( positions=np.zeros((3, 3)), atoms=[0, 1, 2, 3], ) def test_collinear_index_match_error_index(): with pytest.raises(ValueError, match="atoms is not a list of index integers"): _ = is_collinear( positions=np.zeros((4, 3)), atoms=[1, 2.5, 3], ) @pytest.mark.parametrize( "arr, thresh, truth", [ [[[0, 0, -1], [1, 0, 0], [2, 0, 1]], 0.9, True], [[[0, 0, -1], [1, 0, 0], [2, 0, 2]], 0.9, True], [[[0, 0, -1], [1, 0, 0], [2, 0, 2]], 0.95, False], [[[0, 1, -1], [1, 0, 0], [2, 0, 1]], 0.9, False], [[[0, 1, -1], [1, 1, 0], [2, 1, 1]], 0.9, True], [[[0, 1, -1], [1, 1, 0], [2, 1, 2]], 0.95, False], [[[0, 0, -1], [1, 1, 0], [2, 2, 1]], 0.95, True], [[[0, 0, -1], [1, 0, 0], [2, 0, 1]], 0.95, True], [[[2, 0, -1], [1, 0, 0], [0, 0, 1]], 0.95, True], [[[0, 0, 1], [0, 0, 0], [0, 0, 2]], 0.95, True], [[[1, 1, 1], [0, 0, 0], [2, 2, 2]], 0.9, True], ], ) def test_is_collinear_three_atoms(arr, thresh, truth): assert ( is_collinear( positions=np.array(arr), atoms=[0, 1, 2], threshold=thresh, ) == truth ) @pytest.mark.parametrize( "arr, truth, dims", [ [[[0, 0, -1], [1, 0, 0], [2, 0, 1]], True, True], [[[0, 0, -1], [1, 0, 0], [2, 0, 11]], False, False], [[[0, 0, -1], [1, 0, 0], [2, 0, 11]], True, True], [[[0, 0, -1], [1, 0, 0], [2, 0, 2]], False, True], [[[0, 0, -1], [1, 0, 0], [2, 0, 12]], False, False], [[[0, 0, -1], [1, 0, 0], [2, 0, 12]], False, True], ], ) def test_is_collinear_three_atoms_dimensions(arr, truth, dims): if dims: dimensions = np.array([10.0, 10.0, 10.0, 90.0, 90.0, 90.0], dtype=float) else: dimensions = None assert ( is_collinear( positions=np.array(arr, dtype=float), atoms=[0, 1, 2], threshold=0.99, dimensions=dimensions, ) == truth ) @pytest.mark.parametrize( "arr, tresh, truth", [ # collinear all [[[0, 0, -1], [1, 0, 0], [2, 0, 1], [3, 0, 2]], 0.99, True], # not collinear for all [[[0, 0, -1], [1, 0, 0], [2, 0, 2], [3, 0, 2]], 0.99, False], # not collinear but within threshold [[[0, 0, -1], [1, 0, 0], [2, 0, 2], [3, 0, 2]], 0.9, True], # collinear for v3 and v4 [[[0, 0, -1], [1, 0, 0], [2, 0, 2], [3, 0, 4]], 0.99, True], # collinear for v1 and v2 [[[0, 0, -1], [1, 0, 0], [2, 0, 1], [3, 0, 4]], 0.99, True], # not collinear for all [[[0, 1, -1], [1, 0, 0], [2, 0, 2], [3, 0, 2]], 0.99, False], ], ) def test_is_collinear_four_atoms(arr, tresh, truth): assert ( is_collinear( positions=np.array(arr), atoms=[0, 1, 2, 3], threshold=tresh, ) == truth ) def test_wrap_angle_degrees(): for i in range(0, 361, 1): angle = _wrap_angle(i * unit.degrees) if i > 180: expected = ((i - 360) * unit.degrees).to("radians").m else: expected = (i * unit.degrees).to("radians").m assert angle.m == pytest.approx(expected) @pytest.mark.parametrize( "angle, expected", [ [0 * unit.radians, 0 * unit.radians], [1 * unit.radians, 1 * unit.radians], [4 * unit.radians, 4 - (2 * np.pi) * unit.radians], [-4 * unit.radians, -4 + (2 * np.pi) * unit.radians], ], ) def test_wrap_angle_radians(angle, expected): assert _wrap_angle(angle) == pytest.approx(expected) @pytest.mark.parametrize( "limit, force, temperature", [ [0.7695366605411506, 83.68, 298.15], [0.8339791717799163, 83.68, 350.0], [0.5441445910402979, 167.36, 298.15], ], ) def test_angle_not_flat(limit, force, temperature): limit = limit * unit.radians force = force * unit.kilojoule_per_mole / unit.radians**2 temperature = temperature * unit.kelvin # test upper assert check_angle_not_flat(limit + 0.01, force, temperature) assert not check_angle_not_flat(limit - 0.01, force, temperature) # test lower limit = np.pi - limit assert check_angle_not_flat(limit - 0.01, force, temperature) assert not check_angle_not_flat(limit + 0.01, force, temperature) @pytest.mark.parametrize( "dihed, expected", [ [3 * unit.radians, False], [0 * unit.radians, True], [-3 * unit.radians, False], [300 * unit.degrees, True], [181 * unit.degrees, False], ], ) def test_check_dihedral_bounds(dihed, expected): ret = check_dihedral_bounds(dihed) assert ret == expected @pytest.mark.parametrize( "dihed, lower, upper, expected", [ [3 * unit.radians, -3.1 * unit.radians, 3.1 * unit.radians, True], [300 * unit.degrees, -61 * unit.degrees, 301 * unit.degrees, True], [300 * unit.degrees, 299 * unit.degrees, -61 * unit.degrees, False], ], ) def test_check_dihedral_bounds_defined(dihed, lower, upper, expected): ret = check_dihedral_bounds(dihed, lower_cutoff=lower, upper_cutoff=upper) assert ret == expected def test_angular_variance(): """ Manual check with for an input number of angles with a known variance of 0.36216 """ angles = [0, 1, 2, 6] assert check_angular_variance( angles=angles * unit.radians, upper_bound=np.pi * unit.radians, lower_bound=-np.pi * unit.radians, width=0.37 * unit.radians, ) assert not check_angular_variance( angles=angles * unit.radians, upper_bound=np.pi * unit.radians, lower_bound=-np.pi * unit.radians, width=0.35 * unit.radians, ) def test_atomgroup_has_bonds(eg5_protein_pdb): # Creating a new universe because we'll modify this one u = mda.Universe(eg5_protein_pdb) # PDB has water bonds assert len(u.bonds) == 14 assert not _atomgroup_has_bonds(u) assert _atomgroup_has_bonds(u.select_atoms("resname HOH")) # Delete the topology attr and everything is false u.del_TopologyAttr("bonds") assert not _atomgroup_has_bonds(u) assert not _atomgroup_has_bonds(u.select_atoms("resname HOH")) # Guess some bonds back ag = u.atoms[:100] ag.guess_bonds() assert _atomgroup_has_bonds(ag) @pytest.fixture() def t4_lysozyme_trajectory_universe(t4_lysozyme_trajectory_dir): cache_dir = t4_lysozyme_trajectory_dir universe = mda.Universe( str(cache_dir / "t4_toluene_complex.pdb"), str(cache_dir / "t4_toluene_complex.xtc"), ) return universe @pytest.mark.skipif( not os.path.exists(POOCH_CACHE) and not HAS_INTERNET, reason="Internet seems to be unavailable and test data is not cached locally.", ) def test_atomgroup_has_bonds_ions(t4_lysozyme_trajectory_universe): # make a copy of the universe so we don't change things u = t4_lysozyme_trajectory_universe.copy() # Toluene (16) and cap (5) have bonds assert len(u.bonds) == 21 assert not _atomgroup_has_bonds(u) assert _atomgroup_has_bonds(u.select_atoms("resname UNK")) # Guess the bonds, ions won't have them but otherwise all residues should u.select_atoms("not resname NA CL").guess_bonds() # don't guess ions assert _atomgroup_has_bonds(u) def test_centroid_distance_sort(eg5_protein_ligand_universe): # quickly sort the atoms of the first residue atom_sort = CentroidDistanceSort( sortable_atoms=eg5_protein_ligand_universe.select_atoms("backbone and resnum 15"), reference_atoms=eg5_protein_ligand_universe.select_atoms("resname LIG"), ) atom_sort.run() sorted_ids = [a.ix for a in atom_sort.results.sorted_atomgroup] # hard code the ids we expect assert sorted_ids == [2, 1] def test_find_host_atoms(eg5_protein_ligand_universe): # very small window to limit atoms for speed min_cutoff = 1 * unit.nanometer max_cutoff = 1.1 * unit.nanometer atom_finder = FindHostAtoms( host_atoms=eg5_protein_ligand_universe.select_atoms("backbone"), # hand picked ring atom guest_atoms=eg5_protein_ligand_universe.atoms[5528], min_search_distance=min_cutoff, max_search_distance=max_cutoff, ) atom_finder.min_cutoff == min_cutoff.to("angstrom").m atom_finder.max_cutoff == max_cutoff.to("angstrom").m atom_finder.run() # should find the 28 close backbone atoms assert len(atom_finder.results.host_idxs) == 28 def test_get_rmsf_single_frame(eg5_protein_ligand_universe): ligand = eg5_protein_ligand_universe.select_atoms("resname LIG") rmsf = get_local_rmsf(atomgroup=ligand) # as we have a single frame we should get all zeros back assert np.allclose(rmsf.m, np.zeros(ligand.n_atoms)) @pytest.mark.skipif( not os.path.exists(POOCH_CACHE) and not HAS_INTERNET, reason="Internet seems to be unavailable and test data is not cached locally.", ) def test_get_rmsf_trajectory(t4_lysozyme_trajectory_universe): # get the RMSF of just the ligand ligand = t4_lysozyme_trajectory_universe.select_atoms("resname UNK") rmsf = get_local_rmsf(atomgroup=ligand) assert len(rmsf) == ligand.n_atoms # regression test the calculation of the rmsf assert np.allclose( rmsf.to("angstrom").m, np.array( [ 0.054697843819888965, 0.07512308066036011, 0.06000502046267635, 0.07180001811557828, 0.043416981393784, 0.05909972948285153, 0.13061051498104648, 0.15166255437235665, 0.17860692733595412, 0.1483198866730507, 0.14193714526412668, 0.06730488032625732, 1.0235330857263523, 1.0048466548200004, 1.0209553834502236, ] ), ) @pytest.mark.skipif( not os.path.exists(POOCH_CACHE) and not HAS_INTERNET, reason="Internet seems to be unavailable and test data is not cached locally.", ) class TestStableSelection: def test_stable_ss_selection(self, t4_lysozyme_trajectory_universe): ligand = t4_lysozyme_trajectory_universe.select_atoms("resname LIG") # Topology is PDB so bonds will be missing with pytest.warns(match="No bonds found in input Universe, will attempt to guess them."): stable_protein = stable_secondary_structure_selection( # DDSP should filter by protein we will check at the end atomgroup=t4_lysozyme_trajectory_universe.atoms, ) # make sure the ligand is not in this selection overlapping_ligand = stable_protein.intersection(ligand.atoms) assert overlapping_ligand.n_atoms == 0 # make sure we get the expected number of atoms assert stable_protein.n_atoms == 780 def test_small_chain(self, t4_lysozyme_trajectory_universe): """ Artificially set min_structure_size so large that no chains are recognised. """ stable_protein = stable_secondary_structure_selection( atomgroup=t4_lysozyme_trajectory_universe.atoms, min_structure_size=999, ) # Should have an empty atomgroup assert len(stable_protein) == 0 def test_bad_dssp(self, t4_lysozyme_trajectory_universe): """ Cause DSSP to fail to yield an empty atomgroup. """ u_copy = t4_lysozyme_trajectory_universe.copy() # rename all CA atoms to LA to make things break for at in u_copy.atoms: at.name = "LA" stable_protein = stable_secondary_structure_selection( atomgroup=u_copy.atoms, ) # Should have an empty atomgroup assert len(stable_protein) == 0 def test_beta_dssp(self, beta_barrel_universe): """ 6CZJ is a straight up beta-barrel """ stable_protein = stable_secondary_structure_selection( atomgroup=beta_barrel_universe.atoms, ) assert len(stable_protein.residues) == 59 def test_protein_chain_selection(eg5_protein_ligand_universe): ligand = eg5_protein_ligand_universe.select_atoms("resname LIG") # Topology is PDB so bonds will be missing with pytest.warns(match="No bonds found in input Universe, will attempt to guess them."): chain_selection = protein_chain_selection( # the selection should filter for the protein we will check at the end atomgroup=eg5_protein_ligand_universe.atoms, ) overlapping_ligand = chain_selection.intersection(ligand.atoms) assert overlapping_ligand.n_atoms == 0 # make sure we get the expected number of atoms assert chain_selection.n_atoms == 5150 def test_protein_chain_selection_subchain(eg5_pdb_universe): """ Pass a subset of the residues in a chain """ sele = protein_chain_selection( atomgroup=eg5_pdb_universe.residues[:28].atoms, ) assert len(sele.residues) == 18 assert len(sele) == 282 def test_protein_chain_selection_nochains(eg5_pdb_universe): """ Artificially bump up the minimum number of residues per chain such that we don't have any chains. """ sele = protein_chain_selection( atomgroup=eg5_pdb_universe.atoms, min_chain_length=99999, ) assert len(sele) == 0 def test_protein_chain_selection_trim_too_large(eg5_pdb_universe): """ Use artificially large trim sizes that are greater than the length of the residue. """ sele = protein_chain_selection( atomgroup=eg5_pdb_universe.atoms, min_chain_length=30, trim_chain_start=5000, trim_chain_end=8000, ) assert len(sele) == 0 ================================================ FILE: src/openfe/tests/protocols/restraints/test_omm_restraints.py ================================================ # This code is part of OpenFE and is licensed under the MIT license. # For details, see https://github.com/OpenFreeEnergy/openfe import os import openmm import pytest from gufe import SmallMoleculeComponent from openff.units import unit from openmmtools.states import ThermodynamicState from openfe.data._registry import POOCH_CACHE from openfe.protocols.restraint_utils.openmm.omm_restraints import ( BoreschRestraint, BoreschRestraintGeometry, BoreschRestraintSettings, CentroidFlatBottomRestraint, CentroidHarmonicRestraint, DistanceRestraintGeometry, FlatBottomBondRestraint, FlatBottomDistanceGeometry, HarmonicBondRestraint, RestraintParameterState, ) from openfe.protocols.restraint_utils.settings import ( DistanceRestraintSettings, FlatBottomRestraintSettings, ) from ...conftest import HAS_INTERNET def test_parameter_state_default(): param_state = RestraintParameterState() assert param_state.lambda_restraints is None @pytest.mark.parametrize("suffix", [None, "foo"]) @pytest.mark.parametrize("lambda_var", [0, 0.5, 1.0]) def test_parameter_state_suffix(suffix, lambda_var): param_state = RestraintParameterState( parameters_name_suffix=suffix, lambda_restraints=lambda_var ) if suffix is not None: param_name = f"lambda_restraints_{suffix}" else: param_name = "lambda_restraints" assert getattr(param_state, param_name) == lambda_var assert len(param_state._parameters.keys()) == 1 assert param_state._parameters[param_name] == lambda_var assert param_state._parameters_name_suffix == suffix @pytest.mark.parametrize( "restraint, geometry_settings", [ pytest.param(HarmonicBondRestraint, {}, id="Harmonic"), pytest.param( FlatBottomBondRestraint, {"well_radius": 0.1 * unit.nanometer}, id="Flatbottom", ), ], ) def test_single_bond_mixin(restraint, geometry_settings): res = restraint( restraint_settings=restraint._settings_cls( spring_constant=20 * unit.kilojoule_per_mole / unit.nanometer**2 ) ) geometry_settings.update({"guest_atoms": [0, 1], "host_atoms": [2, 3]}) with pytest.raises( ValueError, match="host_atoms and guest_atoms must only include a single index" ): res._verify_geometry(geometry=res._geometry_cls(**geometry_settings)) def test_verify_inputs(): with pytest.raises(ValueError, match="Incorrect settings type DistanceRestraintSettings"): _ = FlatBottomBondRestraint( restraint_settings=DistanceRestraintSettings( spring_constant=20 * unit.kilojoule_per_mole / unit.nanometer**2 ) ) def test_verify_geometry(): with pytest.raises(ValueError, match="Incorrect geometry class type DistanceRestraintGeometry"): restraint = FlatBottomBondRestraint( restraint_settings=FlatBottomRestraintSettings( spring_constant=20 * unit.kilojoule_per_mole / unit.nanometer**2 ) ) geometry = DistanceRestraintGeometry(guest_atoms=[0], host_atoms=[1]) restraint._verify_geometry(geometry) @pytest.fixture def tyk2_protein_ligand_system(industry_benchmark_files): with open( str(industry_benchmark_files / "jacs_set" / "tyk2" / "protein_ligand_system.xml") ) as xml: return openmm.XmlSerializer.deserialize(xml.read()) @pytest.fixture def tyk2_rdkit_ligand(industry_benchmark_files): ligand = SmallMoleculeComponent.from_sdf_file( str(industry_benchmark_files / "jacs_set" / "tyk2" / "test_ligand.sdf") ) return ligand.to_rdkit() @pytest.mark.skipif( not os.path.exists(POOCH_CACHE) and not HAS_INTERNET, reason="Internet seems to be unavailable and test data is not cached locally.", ) def test_harmonic_add_force(tyk2_protein_ligand_system): restraint = HarmonicBondRestraint( restraint_settings=DistanceRestraintSettings( spring_constant=20 * unit.kilojoule_per_mole / unit.nanometer**2 ) ) state = ThermodynamicState(system=tyk2_protein_ligand_system) geometry = DistanceRestraintGeometry(host_atoms=[0], guest_atoms=[4706]) restraint.add_force( thermodynamic_state=state, geometry=geometry, controlling_parameter_name="lambda_restraints", ) system = state.system forces = {force.__class__.__name__: force for force in system.getForces()} restraint_force = forces["CustomBondForce"] # some other random global parameter is included in this force assert restraint_force.getGlobalParameterName(1) == "lambda_restraints" assert restraint_force.getEnergyFunction() == "lambda_restraints * ((K/2)*r^2)" assert restraint_force.getNumBonds() == 1 # some other random global parameter is included in this force otherwise there should be 1 assert restraint_force.getNumGlobalParameters() == 2 # check the restraint parameters host_atom, guest_atom, params = restraint_force.getBondParameters(0) assert host_atom == geometry.host_atoms[0] assert guest_atom == geometry.guest_atoms[0] assert params[0] == restraint.settings.spring_constant.m @pytest.mark.skipif( not os.path.exists(POOCH_CACHE) and not HAS_INTERNET, reason="Internet seems to be unavailable and test data is not cached locally.", ) def test_flatbottom_add_force(tyk2_protein_ligand_system): restraint = FlatBottomBondRestraint( restraint_settings=FlatBottomRestraintSettings( spring_constant=20 * unit.kilojoule_per_mole / unit.nanometer**2 ) ) state = ThermodynamicState(system=tyk2_protein_ligand_system) geometry = FlatBottomDistanceGeometry( host_atoms=[0], guest_atoms=[4706], well_radius=1 * unit.nanometer ) restraint.add_force( thermodynamic_state=state, geometry=geometry, controlling_parameter_name="lambda_restraints", ) system = state.system forces = {force.__class__.__name__: force for force in system.getForces()} restraint_force = forces["CustomBondForce"] # some other random global parameter is included in this force assert restraint_force.getGlobalParameterName(1) == "lambda_restraints" assert ( restraint_force.getEnergyFunction() == "lambda_restraints * (step(r-r0) * (K/2)*(r-r0)^2)" ) assert restraint_force.getNumBonds() == 1 # some other random global parameter is included in this force otherwise there should be 1 assert restraint_force.getNumGlobalParameters() == 2 # check the restraint parameters host_atom, guest_atom, params = restraint_force.getBondParameters(0) assert host_atom == geometry.host_atoms[0] assert guest_atom == geometry.guest_atoms[0] assert params[0] == restraint.settings.spring_constant.m assert params[1] == geometry.well_radius.m @pytest.mark.skipif( not os.path.exists(POOCH_CACHE) and not HAS_INTERNET, reason="Internet seems to be unavailable and test data is not cached locally.", ) def test_centriod_harmonic_add_force(tyk2_protein_ligand_system): restraint = CentroidHarmonicRestraint( restraint_settings=DistanceRestraintSettings( spring_constant=20 * unit.kilojoule_per_mole / unit.nanometer**2 ) ) state = ThermodynamicState(system=tyk2_protein_ligand_system) geometry = DistanceRestraintGeometry( host_atoms=[0, 1, 2], guest_atoms=[4706, 4705, 4704], ) restraint.add_force( thermodynamic_state=state, geometry=geometry, controlling_parameter_name="lambda_restraints", ) system = state.system forces = {force.__class__.__name__: force for force in system.getForces()} restraint_force = forces["CustomCentroidBondForce"] assert restraint_force.getGlobalParameterName(1) == "lambda_restraints" assert restraint_force.getEnergyFunction() == "lambda_restraints * ((K/2)*distance(g1,g2)^2)" assert restraint_force.getNumBonds() == 1 # some other random global parameter is included in this force otherwise there should be 1 assert restraint_force.getNumGlobalParameters() == 2 # check the restraint parameters groups, params = restraint_force.getBondParameters(0) assert params[0] == restraint.settings.spring_constant.m host_atoms = list(restraint_force.getGroupParameters(0)[0]) guest_atoms = list(restraint_force.getGroupParameters(1)[0]) assert host_atoms == geometry.host_atoms assert guest_atoms == geometry.guest_atoms @pytest.mark.skipif( not os.path.exists(POOCH_CACHE) and not HAS_INTERNET, reason="Internet seems to be unavailable and test data is not cached locally.", ) def test_centroid_flat_bottom_add_force(tyk2_protein_ligand_system): restraint = CentroidFlatBottomRestraint( restraint_settings=FlatBottomRestraintSettings( spring_constant=20 * unit.kilojoule_per_mole / unit.nanometer**2 ) ) state = ThermodynamicState(system=tyk2_protein_ligand_system) geometry = FlatBottomDistanceGeometry( host_atoms=[0, 1, 2], guest_atoms=[4706, 4705, 4704], well_radius=1 * unit.nanometer, ) restraint.add_force( thermodynamic_state=state, geometry=geometry, controlling_parameter_name="lambda_restraints", ) system = state.system forces = {force.__class__.__name__: force for force in system.getForces()} restraint_force = forces["CustomCentroidBondForce"] # some other random global parameter is included in this force assert restraint_force.getGlobalParameterName(1) == "lambda_restraints" assert ( restraint_force.getEnergyFunction() == "lambda_restraints * (step(distance(g1,g2)-r0) * (K/2)*(distance(g1,g2)-r0)^2)" ) assert restraint_force.getNumBonds() == 1 # some other random global parameter is included in this force otherwise there should be 1 assert restraint_force.getNumGlobalParameters() == 2 # check the restraint parameters groups, params = restraint_force.getBondParameters(0) assert params[0] == restraint.settings.spring_constant.m assert params[1] == geometry.well_radius.m host_atoms = list(restraint_force.getGroupParameters(0)[0]) guest_atoms = list(restraint_force.getGroupParameters(1)[0]) assert host_atoms == geometry.host_atoms assert guest_atoms == geometry.guest_atoms @pytest.mark.skipif( not os.path.exists(POOCH_CACHE) and not HAS_INTERNET, reason="Internet seems to be unavailable and test data is not cached locally.", ) def test_add_boresch_force(tyk2_protein_ligand_system, tyk2_rdkit_ligand): restraint = BoreschRestraint(restraint_settings=BoreschRestraintSettings()) # create the geometry from the saved values in the sdf file geometry = BoreschRestraintGeometry( r_aA0=tyk2_rdkit_ligand.GetDoubleProp("r_aA0") * unit.nanometer, theta_A0=tyk2_rdkit_ligand.GetDoubleProp("theta_A0") * unit.radians, theta_B0=tyk2_rdkit_ligand.GetDoubleProp("theta_B0") * unit.radians, phi_A0=tyk2_rdkit_ligand.GetDoubleProp("phi_A0") * unit.radians, phi_B0=tyk2_rdkit_ligand.GetDoubleProp("phi_B0") * unit.radians, phi_C0=tyk2_rdkit_ligand.GetDoubleProp("phi_C0") * unit.radians, host_atoms=[tyk2_rdkit_ligand.GetIntProp(f"Host{i}") for i in range(3)], guest_atoms=[tyk2_rdkit_ligand.GetIntProp(f"Guest{i}") for i in range(3)], ) state = ThermodynamicState(system=tyk2_protein_ligand_system) restraint.add_force( thermodynamic_state=state, geometry=geometry, controlling_parameter_name="lambda_restraints", ) system = state.system forces = {force.__class__.__name__: force for force in system.getForces()} restraint_force = forces["CustomCompoundBondForce"] assert restraint_force.getGlobalParameterName(0) == "lambda_restraints" assert "lambda_restraints" in restraint_force.getEnergyFunction() assert restraint_force.getNumGlobalParameters() == 1 assert restraint_force.getNumBonds() == 1 atoms, parameters = restraint_force.getBondParameters(0) assert geometry.host_atoms == list(atoms[:3][::-1]) assert geometry.guest_atoms == list(atoms[3:]) # check all the parameters for i in range(restraint_force.getNumPerBondParameters()): per_bond_parameter = restraint_force.getPerBondParameterName(i) # if we have a force constant check the settings if per_bond_parameter[0] == "K": assert parameters[i] == getattr(restraint.settings, per_bond_parameter).m # else check the geometry else: assert parameters[i] == getattr(geometry, per_bond_parameter).m @pytest.mark.skipif( not os.path.exists(POOCH_CACHE) and not HAS_INTERNET, reason="Internet seems to be unavailable and test data is not cached locally.", ) def test_get_boresch_state_correction(tyk2_protein_ligand_system, tyk2_rdkit_ligand): restraint = BoreschRestraint(restraint_settings=BoreschRestraintSettings()) # create the geometry from the saved values in the sdf file geometry = BoreschRestraintGeometry( r_aA0=tyk2_rdkit_ligand.GetDoubleProp("r_aA0") * unit.nanometer, theta_A0=tyk2_rdkit_ligand.GetDoubleProp("theta_A0") * unit.radians, theta_B0=tyk2_rdkit_ligand.GetDoubleProp("theta_B0") * unit.radians, phi_A0=tyk2_rdkit_ligand.GetDoubleProp("phi_A0") * unit.radians, phi_B0=tyk2_rdkit_ligand.GetDoubleProp("phi_B0") * unit.radians, phi_C0=tyk2_rdkit_ligand.GetDoubleProp("phi_C0") * unit.radians, host_atoms=[tyk2_rdkit_ligand.GetIntProp(f"Host{i}") for i in range(3)], guest_atoms=[tyk2_rdkit_ligand.GetIntProp(f"Guest{i}") for i in range(3)], ) state = ThermodynamicState(system=tyk2_protein_ligand_system) correction = restraint.get_standard_state_correction( thermodynamic_state=state, geometry=geometry ) assert pytest.approx(correction.to(unit.kilocalorie_per_mole).m) == -9.28421610202858 ================================================ FILE: src/openfe/tests/protocols/restraints/test_openmm_forces.py ================================================ # This code is part of OpenFE and is licensed under the MIT license. # For details, see https://github.com/OpenFreeEnergy/openfe import numpy as np import openmm import pytest from openfe.protocols.restraint_utils.openmm.omm_forces import ( add_force_in_separate_group, get_boresch_energy_function, get_custom_compound_bond_force, get_periodic_boresch_energy_function, ) @pytest.mark.parametrize("param", ["foo", "bar"]) def test_boresch_energy_function(param): """ Base regression test for the energy function """ fn = get_boresch_energy_function(param) assert fn == ( f"{param} * E; " "E = (K_r/2)*(distance(p3,p4) - r_aA0)^2 " "+ (K_thetaA/2)*(angle(p2,p3,p4)-theta_A0)^2 + (K_thetaB/2)*(angle(p3,p4,p5)-theta_B0)^2 " "+ (K_phiA/2)*dphi_A^2 + (K_phiB/2)*dphi_B^2 + (K_phiC/2)*dphi_C^2; " "dphi_A = dA - floor(dA/(2.0*pi)+0.5)*(2.0*pi); dA = dihedral(p1,p2,p3,p4) - phi_A0; " "dphi_B = dB - floor(dB/(2.0*pi)+0.5)*(2.0*pi); dB = dihedral(p2,p3,p4,p5) - phi_B0; " "dphi_C = dC - floor(dC/(2.0*pi)+0.5)*(2.0*pi); dC = dihedral(p3,p4,p5,p6) - phi_C0; " f"pi = {np.pi}; " ) @pytest.mark.parametrize("param", ["foo", "bar"]) def test_periodic_boresch_energy_function(param): """ Base regression test for the energy function """ fn = get_periodic_boresch_energy_function(param) assert fn == ( f"{param} * E; " "E = (K_r/2)*(distance(p3,p4) - r_aA0)^2 " "+ (K_thetaA/2)*(angle(p2,p3,p4)-theta_A0)^2 + (K_thetaB/2)*(angle(p3,p4,p5)-theta_B0)^2 " "+ (K_phiA/2)*uphi_A + (K_phiB/2)*uphi_B + (K_phiC/2)*uphi_C; " "uphi_A = (1-cos(dA)); dA = dihedral(p1,p2,p3,p4) - phi_A0; " "uphi_B = (1-cos(dB)); dB = dihedral(p2,p3,p4,p5) - phi_B0; " "uphi_C = (1-cos(dC)); dC = dihedral(p3,p4,p5,p6) - phi_C0; " f"pi = {np.pi}; " ) @pytest.mark.parametrize("num_atoms", [6, 20]) def test_custom_compound_force(num_atoms): fn = get_boresch_energy_function("lambda_restraints") force = get_custom_compound_bond_force(fn, num_atoms) # Check we have the right object assert isinstance(force, openmm.CustomCompoundBondForce) # Check the energy function assert force.getEnergyFunction() == fn # Check the number of particles assert force.getNumParticlesPerBond() == num_atoms @pytest.mark.parametrize( "groups, expected", [ [[0, 1, 2, 3, 4], 5], [[1, 2, 3, 4, 5], 0], ], ) def test_add_force_in_separate_group(groups, expected): # Create an empty system system = openmm.System() # Create some forces with some force groups base_forces = [ openmm.NonbondedForce(), openmm.HarmonicBondForce(), openmm.HarmonicAngleForce(), openmm.PeriodicTorsionForce(), openmm.CMMotionRemover(), ] for force, group in zip(base_forces, groups): force.setForceGroup(group) [system.addForce(force) for force in base_forces] # Get your CustomCompoundBondForce fn = get_boresch_energy_function("lambda_restraints") new_force = get_custom_compound_bond_force(fn, 6) # new_force.setForceGroup(5) # system.addForce(new_force) add_force_in_separate_group(system=system, force=new_force) # Loop through and check that we go assigned the expected force group for force in system.getForces(): if isinstance(force, openmm.CustomCompoundBondForce): assert force.getForceGroup() == expected def test_add_too_many_force_groups(): # Create a system system = openmm.System() # Fill it upu with 32 forces with different groups for i in range(32): f = openmm.HarmonicBondForce() f.setForceGroup(i) system.addForce(f) # Now try to add another force with pytest.raises(ValueError, match="No available force group"): add_force_in_separate_group(system=system, force=openmm.HarmonicBondForce()) ================================================ FILE: src/openfe/tests/protocols/restraints/test_settings.py ================================================ # This code is part of OpenFE and is licensed under the MIT license. # For details, see https://github.com/OpenFreeEnergy/openfe """ Test the restraint settings. """ import pytest from openff.units import unit from openfe.protocols.restraint_utils.settings import ( BoreschRestraintSettings, DistanceRestraintSettings, FlatBottomRestraintSettings, ) def test_distance_restraint_settings_default(): """ Basic settings regression test """ settings = DistanceRestraintSettings( spring_constant=10 * unit.kilojoule_per_mole / unit.nm**2, ) assert settings.central_atoms_only is False assert isinstance(settings, DistanceRestraintSettings) def test_distance_restraint_negative_idxs(): """ Check that an error is raised if you have negative atom indices in host atoms. """ with pytest.raises(ValueError, match="negative indices passed"): _ = DistanceRestraintSettings( spring_constant=10 * unit.kilojoule_per_mole / unit.nm**2, host_atoms=[-1, 0, 2], guest_atoms=[0, 1, 2], ) def test_flatbottom_restraint_settings_default(): """ Basic settings regression test """ settings = FlatBottomRestraintSettings( spring_constant=10 * unit.kilojoule_per_mole / unit.nm**2, well_radius=1 * unit.nanometer, ) assert isinstance(settings, FlatBottomRestraintSettings) def test_flatbottom_restraint_negative_well(): """ Check that an error is raised if you have a negative well radius. """ with pytest.raises(ValueError, match="well radius cannot be negative"): _ = FlatBottomRestraintSettings( spring_constant=10 * unit.kilojoule_per_mole / unit.nm**2, well_radius=-1 * unit.nm, ) def test_boresch_restraint_settings_default(): """ Basic settings regression test """ settings = BoreschRestraintSettings( K_r=10 * unit.kilojoule_per_mole / unit.nm**2, K_thetaA=10 * unit.kilojoule_per_mole / unit.radians**2, K_thetaB=10 * unit.kilojoule_per_mole / unit.radians**2, K_phiA=10 * unit.kilojoule_per_mole / unit.radians**2, K_phiB=10 * unit.kilojoule_per_mole / unit.radians**2, K_phiC=10 * unit.kilojoule_per_mole / unit.radians**2, ) assert isinstance(settings, BoreschRestraintSettings) # TODO: re-enable this Issue #1556 # def test_boresch_restraint_negative_idxs(): # """ # Check that the positive_idxs_list validator is # working as expected. # """ # with pytest.raises(ValueError, match="negative indices"): # _ = BoreschRestraintSettings( # K_r=10 * unit.kilojoule_per_mole / unit.nm**2, # K_thetaA=10 * unit.kilojoule_per_mole / unit.radians**2, # K_thetaB=10 * unit.kilojoule_per_mole / unit.radians**2, # phi_A0=10 * unit.kilojoule_per_mole / unit.radians**2, # phi_B0=10 * unit.kilojoule_per_mole / unit.radians**2, # phi_C0=10 * unit.kilojoule_per_mole / unit.radians**2, # host_atoms=[-1, 0], # guest_atoms=[0, 1], # ) ================================================ FILE: src/openfe/tests/protocols/test_openmm_settings.py ================================================ # This code is part of OpenFE and is licensed under the MIT license. # For details, see https://github.com/OpenFreeEnergy/openfe import numpy as np import pytest from openff.units import unit from openfe.protocols.openmm_rfe import equil_rfe_settings # afe settings currently have no FloatQuantity values from openfe.protocols.openmm_utils import omm_settings class TestOMMSettingsFromStrings: # checks that we can set Settings fields via strings def test_system_settings(self): s = omm_settings.OpenMMSystemGeneratorFFSettings() s.nonbonded_cutoff = "1.1 nm" assert s.nonbonded_cutoff == 1.1 * unit.nanometer def test_solvation_settings(self): s = omm_settings.OpenMMSolvationSettings() s.solvent_padding = "1.1 nm" assert s.solvent_padding == 1.1 * unit.nanometer def test_alchemical_sampler_settings(self): # todo: early_termination_target_error is in kT, how to pass this as string? pass def test_integator_settings(self): s = omm_settings.IntegratorSettings() s.timestep = "3 fs" assert s.timestep == 3.0 * unit.femtosecond s.langevin_collision_rate = "1.1 / ps" assert s.langevin_collision_rate == 1.1 / unit.picosecond # todo: nsteps, barostat frequency require IntQuantity def test_simulation_settings(self): s = omm_settings.SimulationSettings( equilibration_length=2.0 * unit.nanosecond, production_length=5.0 * unit.nanosecond, ) s.equilibration_length = "2.5 ns" s.production_length = "10 ns" assert s.equilibration_length == 2.5 * unit.nanosecond assert s.production_length == 10.0 * unit.nanosecond class TestEquilRFESettingsFromString: def test_alchemical_settings(self): s = equil_rfe_settings.AlchemicalSettings(softcore_LJ="gapsys") s.explicit_charge_correction_cutoff = "0.85 nm" assert s.explicit_charge_correction_cutoff == 0.85 * unit.nanometer class TestOpenMMSolvationSettings: def test_unreduced_box_vectors(self): s = omm_settings.OpenMMSolvationSettings() # Taken from interchange tests, but we require units # rhombic dodecahedron with first and last rows swapped box_vectors = ( np.asarray( [ [0.5, 0.5, np.sqrt(2.0) / 2.0], [0.0, 1.0, 0.0], [1.0, 0.0, 0.0], ], ) * unit.nanometer ) with pytest.raises(ValueError, match="not in OpenMM reduced form"): s.box_vectors = box_vectors @pytest.mark.parametrize("n_solv", [0, -1]) def test_non_positive_solvent(self, n_solv): s = omm_settings.OpenMMSolvationSettings() with pytest.raises(ValueError, match="must be positive"): s.number_of_solvent_molecules = n_solv def test_box_size_properties_non_1d(self): s = omm_settings.OpenMMSolvationSettings() with pytest.raises(ValueError, match="must be a 1-D array"): s.box_size = np.array([[1, 2, 3], [1, 2, 3]]) * unit.angstrom class TestOpenMMEngineSettings: @pytest.mark.parametrize("platform", ["CUDA", "OpenCL", "cPu"]) def test_ok_platforms(self, platform): s = omm_settings.OpenMMEngineSettings(compute_platform=platform) assert isinstance(s, omm_settings.OpenMMEngineSettings) def test_fail_platform(self): with pytest.raises(ValueError, match="OpenMM compute backends"): _ = omm_settings.OpenMMEngineSettings(compute_platform="foo") ================================================ FILE: src/openfe/tests/protocols/test_openmmutils.py ================================================ # This code is part of OpenFE and is licensed under the MIT license. # For details, see https://github.com/OpenFreeEnergy/openfe import copy import gzip import os import sys from importlib import resources from pathlib import Path from unittest import mock import numpy as np import pooch import pytest from gufe import BaseSolventComponent from gufe.components.errors import ComponentValidationError from gufe.settings import OpenMMSystemGeneratorFFSettings, ThermoSettings from numpy.testing import assert_allclose, assert_equal from openff.toolkit import Molecule as OFFMol from openff.toolkit.utils.toolkit_registry import ToolkitRegistry from openff.toolkit.utils.toolkits import RDKitToolkitWrapper from openff.units import unit from openff.units.openmm import ensure_quantity, from_openmm, to_openmm from openmm import MonteCarloBarostat, MonteCarloMembraneBarostat, NonbondedForce, app from openmm import unit as ommunit from openmmtools import multistate from pymbar.utils import ParameterError import openfe from openfe.data._registry import POOCH_CACHE from openfe.protocols.openmm_rfe.equil_rfe_settings import ( IntegratorSettings, OpenMMSolvationSettings, ) from openfe.protocols.openmm_utils import ( charge_generation, multistate_analysis, omm_settings, settings_validation, system_creation, system_validation, ) from openfe.protocols.openmm_utils.charge_generation import ( HAS_ESPALOMA_CHARGE, HAS_NAGL, HAS_OPENEYE, ) from ..conftest import HAS_INTERNET @pytest.mark.parametrize( "padding, number_solv, box_vectors, box_size", [ [1.2 * unit.nanometer, 20, 20 * np.identity(3) * unit.angstrom, [2, 2, 2] * unit.angstrom], [1.2 * unit.nanometer, None, None, [2, 2, 2] * unit.angstrom], [1.2 * unit.nanometer, None, 20 * np.identity(3) * unit.angstrom, None], [1.2 * unit.nanometer, 20, None, None], ], ) def test_validate_ommsolvation_settings_unique_settings( padding, number_solv, box_vectors, box_size ): settings = OpenMMSolvationSettings( solvent_padding=padding, number_of_solvent_molecules=number_solv, box_vectors=box_vectors, box_size=box_size, ) errmsg = "Only one of solvent_padding, number_of_solvent_molecules," with pytest.raises(ValueError, match=errmsg): settings_validation.validate_openmm_solvation_settings(settings) @pytest.mark.parametrize( "box_vectors, box_size", [ [20 * np.identity(3) * unit.angstrom, None], [None, [2, 2, 2] * unit.angstrom], ], ) def test_validate_ommsolvation_settings_shape_conflicts( box_vectors, box_size, ): settings = OpenMMSolvationSettings( solvent_padding=None, box_vectors=box_vectors, box_size=box_size, box_shape="cube", ) errmsg = "box_shape cannot be defined alongside either box_size" with pytest.raises(ValueError, match=errmsg): settings_validation.validate_openmm_solvation_settings(settings) def test_validate_timestep(): with pytest.raises(ValueError, match="too large for hydrogen mass"): settings_validation.validate_timestep(2.0, 4.0 * unit.femtoseconds) @pytest.mark.parametrize( "s,ts,mc,es", [ [5 * unit.nanoseconds, 4 * unit.femtoseconds, 250, 1250000], [1 * unit.nanoseconds, 4 * unit.femtoseconds, 250, 250000], [1 * unit.picoseconds, 2 * unit.femtoseconds, 250, 500], ], ) def test_get_simsteps(s, ts, mc, es): sim_steps = settings_validation.get_simsteps(s, ts, mc) assert sim_steps == es def test_get_simsteps_indivisible_simtime(): errmsg = "Simulation time not divisible by timestep" timelength = 1.003 * unit.picosecond with pytest.raises(ValueError, match=errmsg): settings_validation.get_simsteps(timelength, 2 * unit.femtoseconds, 100) def test_mc_indivisible(): errmsg = "Simulation time 1.0 ps should contain" timelength = 1 * unit.picoseconds with pytest.raises(ValueError, match=errmsg): settings_validation.get_simsteps(timelength, 2 * unit.femtoseconds, 1000) def test_get_alchemical_components(benzene_modifications, T4_protein_component): stateA = openfe.ChemicalSystem( { "A": benzene_modifications["benzene"], "B": benzene_modifications["toluene"], "P": T4_protein_component, "S": openfe.SolventComponent(smiles="C"), } ) stateB = openfe.ChemicalSystem( { "A": benzene_modifications["benzene"], "B": benzene_modifications["benzonitrile"], "P": T4_protein_component, "S": openfe.SolventComponent(), } ) alchem_comps = system_validation.get_alchemical_components(stateA, stateB) assert len(alchem_comps["stateA"]) == 2 assert benzene_modifications["toluene"] in alchem_comps["stateA"] assert openfe.SolventComponent(smiles="C") in alchem_comps["stateA"] assert len(alchem_comps["stateB"]) == 2 assert benzene_modifications["benzonitrile"] in alchem_comps["stateB"] assert openfe.SolventComponent() in alchem_comps["stateB"] def test_duplicate_chemical_components(benzene_modifications): stateA = openfe.ChemicalSystem( { "A": benzene_modifications["toluene"], "B": benzene_modifications["toluene"], } ) stateB = openfe.ChemicalSystem({"A": benzene_modifications["toluene"]}) errmsg = "state A components B:" with pytest.raises(ValueError, match=errmsg): system_validation.get_alchemical_components(stateA, stateB) def test_validate_solvent_nocutoff(benzene_modifications): state = openfe.ChemicalSystem( {"A": benzene_modifications["toluene"], "S": openfe.SolventComponent()} ) with pytest.raises(ValueError, match="nocutoff cannot be used"): system_validation.validate_solvent(state, "nocutoff") def test_validate_solvent_multiple_solvent(benzene_modifications): state = openfe.ChemicalSystem( { "A": benzene_modifications["toluene"], "S": openfe.SolventComponent(), "S2": openfe.SolventComponent(), } ) with pytest.raises(ValueError, match="Multiple SolventComponent"): system_validation.validate_solvent(state, "pme") def test_validate_solvent_multiple_solvated(benzene_modifications, a2a_protein_membrane_component): state = openfe.ChemicalSystem( { "A": benzene_modifications["toluene"], "S": a2a_protein_membrane_component, "S2": a2a_protein_membrane_component, } ) with pytest.raises(ValueError, match="Multiple SolvatedPDBComponent"): system_validation.validate_solvent(state, "pme") def test_not_water_solvent(benzene_modifications): state = openfe.ChemicalSystem( {"A": benzene_modifications["toluene"], "S": openfe.SolventComponent(smiles="C")} ) with pytest.raises(ValueError, match="Non water solvent"): system_validation.validate_solvent(state, "pme") def test_multiple_proteins(T4_protein_component): state = openfe.ChemicalSystem({"A": T4_protein_component, "B": T4_protein_component}) with pytest.raises(ValueError, match="Multiple ProteinComponent"): system_validation.validate_protein(state) def test_membrane_protein_warns_with_non_membrane_barostat(a2a_protein_membrane_component): state = openfe.ChemicalSystem({"A": a2a_protein_membrane_component}) with pytest.warns(UserWarning, match="ProteinMembraneComponent"): system_validation.validate_barostat( state, barostat="MonteCarloBarostat", ) def test_non_membrane_protein_warns_with_membrane_barostat(T4_protein_component): state = openfe.ChemicalSystem({"A": T4_protein_component}) with pytest.warns(UserWarning, match="MonteCarloMembraneBarostat"): system_validation.validate_barostat( state, barostat="MonteCarloMembraneBarostat", ) def test_get_components_gas(benzene_modifications): state = openfe.ChemicalSystem( { "A": benzene_modifications["benzene"], "B": benzene_modifications["toluene"], } ) s, p, mols = system_validation.get_components(state) assert s is None assert p is None assert len(mols) == 2 def test_components_solvent(benzene_modifications): state = openfe.ChemicalSystem( { "S": openfe.SolventComponent(), "A": benzene_modifications["benzene"], "B": benzene_modifications["toluene"], } ) s, p, mols = system_validation.get_components(state) assert s == openfe.SolventComponent() assert p is None assert len(mols) == 2 def test_components_complex(T4_protein_component, benzene_modifications): state = openfe.ChemicalSystem( { "S": openfe.SolventComponent(), "A": benzene_modifications["benzene"], "B": benzene_modifications["toluene"], "P": T4_protein_component, } ) s, p, mols = system_validation.get_components(state) assert s == openfe.SolventComponent() assert p == T4_protein_component assert len(mols) == 2 def test_validate_chemical_system(a2a_protein_membrane_pdb): inflated_box_vectors = ( np.asarray( [ [1000, 0, 0], [0, 1000, 0], [0, 0, 1000], ] ) * unit.nanometer ) with gzip.open(a2a_protein_membrane_pdb, "rb") as f: comp = openfe.ProteinMembraneComponent.from_pdb_file( f, name="a2a", box_vectors=inflated_box_vectors ) chemical_system = openfe.ChemicalSystem({"protein": comp}, name="A") errmsg = "Component protein from ChemicalSystem A failed validation" with pytest.raises(ComponentValidationError, match=errmsg): system_validation.validate_chemical_system(chemical_system) @pytest.fixture(scope="module") def get_settings(): forcefield_settings = OpenMMSystemGeneratorFFSettings() integrator_settings = IntegratorSettings() thermo_settings = ThermoSettings( temperature=298.15 * unit.kelvin, pressure=1 * unit.bar, ) return forcefield_settings, integrator_settings, thermo_settings class TestFEAnalysis: # Note: class scope _will_ cause this to segfault - the reporter has to close @pytest.fixture(scope="function") def reporter(self): with resources.as_file(resources.files("openfe.tests.data.openmm_rfe")) as d: ncfile = str(d / "vacuum_nocoord.nc") with resources.as_file(resources.files("openfe.tests.data.openmm_rfe")) as d: chkfile = str(d / "vacuum_nocoord_checkpoint.nc") r = multistate.MultiStateReporter(storage=ncfile, checkpoint_storage=chkfile) try: yield r finally: r.close() @pytest.fixture() def analyzer(self, reporter): return multistate_analysis.MultistateEquilFEAnalysis( reporter, sampling_method="repex", result_units=unit.kilocalorie_per_mole, ) def test_free_energies(self, analyzer): ret_dict = analyzer.unit_results_dict assert len(ret_dict.items()) == 7 assert pytest.approx(ret_dict["unit_estimate"].m) == -47.9606 # more variation when using bootstrap errors so we need a loser tolerance assert pytest.approx(ret_dict["unit_estimate_error"].m, rel=1e4) == 0.0251 # forward and reverse (since we do this ourselves) assert_allclose( ret_dict['forward_and_reverse_energies']['fractions'], np.array( [ 0.08988764, 0.191011, 0.292135, 0.393258, 0.494382, 0.595506, 0.696629, 0.797753, 0.898876, 1.0 ] ), rtol=1e-04, ) # fmt: skip assert_allclose( ret_dict["forward_and_reverse_energies"]["forward_DGs"].m, np.array( [ -48.057326, -48.038367, -48.033994, -48.0228, -48.028532, -48.025258, -48.006349, -47.986304, -47.972138, -47.960623, ] ), rtol=1e-04, ) # fmt: skip # results generated using pymbar3 with 1000 bootstrap iterations assert_allclose( ret_dict["forward_and_reverse_energies"]["forward_dDGs"].m, np.array( [ 0.077645, 0.054695, 0.044680, 0.03947, 0.034822, 0.033443, 0.030793, 0.028777, 0.026683, 0.026199, ] ), rtol=5e-01, ) # fmt: skip assert_allclose( ret_dict["forward_and_reverse_energies"]["reverse_DGs"].m, np.array( [ -47.823839, -47.833107, -47.845866, -47.858173, -47.883887, -47.915963, -47.93319, -47.939125, -47.949016, -47.960623, ] ), rtol=1e-04, ) # fmt: skip # results generated using pymbar3 with 1000 bootstrap iterations assert_allclose( ret_dict["forward_and_reverse_energies"]["reverse_dDGs"].m, np.array( [ 0.088335, 0.059483, 0.046254, 0.041504, 0.03877, 0.035495, 0.031981, 0.029707, 0.027095, 0.026296, ] ), rtol=5e-01, ) # fmt: skip def test_plots(self, analyzer, tmp_path): analyzer.plot(filepath=Path(tmp_path), filename_prefix="") assert Path(tmp_path / "forward_reverse_convergence.png").is_file() assert Path(tmp_path / "mbar_overlap_matrix.png").is_file() assert Path(tmp_path / "replica_exchange_matrix.png").is_file() assert Path(tmp_path / "replica_state_timeseries.png").is_file() def test_plot_convergence_bad_units(self, analyzer): with pytest.raises(ValueError, match="Unknown plotting units"): openfe.analysis.plotting.plot_convergence( analyzer.forward_and_reverse_free_energies, unit.nanometer, ) def test_analyze_unknown_method_warning_and_error(self, reporter): with pytest.warns(UserWarning, match="Unknown sampling method"): ana = multistate_analysis.MultistateEquilFEAnalysis( reporter, sampling_method="replex", result_units=unit.kilocalorie_per_mole, ) with pytest.raises(ValueError, match="Exchange matrix"): ana.replica_exchange_statistics class TestSystemCreation: def test_system_generator_nosolv_nocache(self, get_settings): ffsets, intsets, thermosets = get_settings generator = system_creation.get_system_generator(ffsets, thermosets, intsets, None, False) assert generator.barostat is None assert generator.template_generator._cache is None assert not generator.postprocess_system forcefield_kwargs = { "constraints": app.HBonds, "rigidWater": True, "removeCMMotion": False, "hydrogenMass": 3.0 * ommunit.amu, } assert generator.forcefield_kwargs == forcefield_kwargs periodic_kwargs = { "nonbondedMethod": app.PME, "nonbondedCutoff": 0.9 * ommunit.nanometer, } nonperiodic_kwargs = {"nonbondedMethod": app.NoCutoff} assert generator.nonperiodic_forcefield_kwargs == nonperiodic_kwargs assert generator.periodic_forcefield_kwargs == periodic_kwargs def test_system_generator_solv_cache(self, get_settings): ffsets, intsets, thermosets = get_settings thermosets.temperature = 320 * unit.kelvin thermosets.pressure = 1.25 * unit.bar intsets.barostat_frequency = 200 * unit.timestep generator = system_creation.get_system_generator( ffsets, thermosets, intsets, Path("./db.json"), True ) # Check barostat conditions assert isinstance(generator.barostat, MonteCarloBarostat) pressure = ensure_quantity(generator.barostat.getDefaultPressure(), "openff") temperature = ensure_quantity(generator.barostat.getDefaultTemperature(), "openff") assert pressure.m == pytest.approx(1.25) assert pressure.units == unit.bar assert temperature.m == pytest.approx(320) assert temperature.units == unit.kelvin assert generator.barostat.getFrequency() == 200 # Check cache file assert generator.template_generator._cache == "db.json" def test_system_generator_membrane(self, get_settings): ffsets, intsets, thermosets = get_settings thermosets.temperature = 320 * unit.kelvin thermosets.pressure = 1.25 * unit.bar intsets.barostat = "MonteCarloMembraneBarostat" intsets.barostat_frequency = 200 * unit.timestep generator = system_creation.get_system_generator( ffsets, thermosets, intsets, Path("./db.json"), True ) # Check barostat conditions assert isinstance(generator.barostat, MonteCarloMembraneBarostat) pressure = ensure_quantity(generator.barostat.getDefaultPressure(), "openff") temperature = ensure_quantity(generator.barostat.getDefaultTemperature(), "openff") assert pressure.m == pytest.approx(1.25) assert pressure.units == unit.bar assert temperature.m == pytest.approx(320) assert temperature.units == unit.kelvin assert generator.barostat.getFrequency() == 200 def test_get_omm_modeller_complex( self, T4_protein_component, benzene_modifications, get_settings, ): ffsets, intsets, thermosets = get_settings generator = system_creation.get_system_generator(ffsets, thermosets, intsets, None, True) smc = benzene_modifications["toluene"] mol = smc.to_openff() generator.create_system(mol.to_topology().to_openmm(), molecules=[mol]) model, comp_resids = system_creation.get_omm_modeller( T4_protein_component, openfe.SolventComponent(), {smc: mol}, generator.forcefield, OpenMMSolvationSettings(), ) resids = [r for r in model.topology.residues()] assert resids[163].name == "NME" assert resids[164].name == "UNK" assert resids[165].name == "HOH" assert_equal(comp_resids[T4_protein_component], np.linspace(0, 163, 164)) assert_equal(comp_resids[smc], np.array([164])) assert_equal( comp_resids[openfe.SolventComponent()], np.linspace(165, len(resids) - 1, len(resids) - 165), ) def test_get_omm_modeller_membrane_box( self, a2a_protein_membrane_component, a2a_ligands, get_settings, ): ffsets, intsets, thermosets = get_settings intsets.barostat = "MonteCarloMembraneBarostat" ffsets.forcefields = [ "amber/ff14SB.xml", "amber/tip3p_standard.xml", "amber/tip3p_HFE_multivalent.xml", "amber/lipid17_merged.xml", "amber/phosaa10.xml", ] generator = system_creation.get_system_generator(ffsets, thermosets, intsets, None, True) smc = a2a_ligands[0] mol = smc.to_openff() generator.create_system(mol.to_topology().to_openmm(), molecules=[mol]) model, comp_resids = system_creation.get_omm_modeller( a2a_protein_membrane_component, a2a_protein_membrane_component, {smc: mol}, generator.forcefield, OpenMMSolvationSettings(), ) # Check the number of particles hasn't changed assert model.topology.getNumAtoms() == 39426 # check residue contents residues = [r for r in model.topology.residues()] # No waters should have been added / removed # Note: waters are renamed to HOH water_residues = [r for r in residues if r.name == "HOH"] assert len(water_residues) == 7782 # Should be one ligand ligand_residues = [r for r in residues if r.name == "UNK"] assert len(ligand_residues) == 1 # Should be one sodium, no chloride sodium_residues = [r for r in residues if r.name == "NA"] assert len(sodium_residues) == 1 chloride_residues = [r for r in residues if r.name == "CL"] assert len(chloride_residues) == 0 # Check the periodic box vectors are the same box_modeller = model.topology.getPeriodicBoxVectors() box_protein = a2a_protein_membrane_component.box_vectors assert np.allclose(box_modeller, to_openmm(box_protein), atol=1e-6) @pytest.fixture(scope="module") def ligand_mol_and_generator(self, get_settings): # Create offmol offmol = OFFMol.from_smiles("[O-]C=O") offmol.generate_conformers() offmol.assign_partial_charges(partial_charge_method="am1bcc") smc = openfe.SmallMoleculeComponent.from_openff(offmol) ffsets, intsets, thermosets = get_settings generator = system_creation.get_system_generator(ffsets, thermosets, intsets, None, True) # Register offmol in generator generator.create_system(offmol.to_topology().to_openmm(), molecules=[offmol]) return (offmol, smc, generator) def test_get_omm_modeller_ligand_no_neutralize(self, ligand_mol_and_generator): offmol, smc, generator = ligand_mol_and_generator model, comp_resids = system_creation.get_omm_modeller( None, openfe.SolventComponent(neutralize=False), {smc: offmol}, generator.forcefield, OpenMMSolvationSettings(), ) system = generator.create_system( model.topology, molecules=[offmol], ) # Now let's check the total charge nonbonded = [f for f in system.getForces() if isinstance(f, NonbondedForce)][0] charge = 0 * ommunit.elementary_charge for i in range(system.getNumParticles()): c, s, e = nonbonded.getParticleParameters(i) charge += c charge = ensure_quantity(charge, "openff") assert pytest.approx(charge.m) == -1.0 @pytest.mark.parametrize( "n_expected, neutralize, shape", [[400, False, "cube"], [399, True, "dodecahedron"], [400, False, "octahedron"]], ) def test_omm_modeller_ligand_n_solv( self, ligand_mol_and_generator, n_expected, neutralize, shape ): offmol, smc, generator = ligand_mol_and_generator solv_settings = OpenMMSolvationSettings( solvent_padding=None, number_of_solvent_molecules=400, box_vectors=None, box_size=None, box_shape=shape, ) model, comp_resids = system_creation.get_omm_modeller( None, openfe.SolventComponent( neutralize=neutralize, ion_concentration=0 * unit.molar, ), {smc: offmol}, generator.forcefield, solv_settings, ) waters = [r for r in model.topology.residues() if r.name == "HOH"] assert len(waters) == n_expected def test_omm_modeller_box_size(self, ligand_mol_and_generator): offmol, smc, generator = ligand_mol_and_generator solv_settings = OpenMMSolvationSettings( solvent_padding=None, number_of_solvent_molecules=None, box_vectors=None, box_size=[2, 2, 2] * unit.nanometer, box_shape=None, ) model, comp_resids = system_creation.get_omm_modeller( None, openfe.SolventComponent(), {smc: offmol}, generator.forcefield, solv_settings, ) vectors = model.topology.getPeriodicBoxVectors() assert_allclose( from_openmm(vectors), [[2, 0, 0], [0, 2, 0], [0, 0, 2]] * unit.nanometer, ) def test_omm_modeller_box_vectors(self, ligand_mol_and_generator): offmol, smc, generator = ligand_mol_and_generator solv_settings = OpenMMSolvationSettings( solvent_padding=None, number_of_solvent_molecules=None, box_vectors=[[2, 0, 0], [0, 2, 0], [0, 0, 5]] * unit.nanometer, box_size=None, box_shape=None, ) model, comp_resids = system_creation.get_omm_modeller( None, openfe.SolventComponent(), {smc: offmol}, generator.forcefield, solv_settings, ) vectors = model.topology.getPeriodicBoxVectors() assert_allclose( from_openmm(vectors), [[2, 0, 0], [0, 2, 0], [0, 0, 5]] * unit.nanometer, ) def test_convert_steps_per_iteration(): sim = omm_settings.MultiStateSimulationSettings( equilibration_length="10 ps", production_length="10 ps", time_per_iteration="1.0 ps", ) inty = omm_settings.IntegratorSettings(timestep="4 fs") spi = settings_validation.convert_steps_per_iteration(sim, inty) assert spi == 250 def test_convert_steps_per_iteration_failure(): sim = omm_settings.MultiStateSimulationSettings( equilibration_length="10 ps", production_length="10 ps", time_per_iteration="1.0 ps", ) inty = omm_settings.IntegratorSettings(timestep="3 fs") with pytest.raises(ValueError, match="does not evenly divide"): settings_validation.convert_steps_per_iteration(sim, inty) def test_convert_real_time_analysis_iterations(): sim = omm_settings.MultiStateSimulationSettings( equilibration_length="10 ps", production_length="10 ps", time_per_iteration="1.0 ps", real_time_analysis_interval="250 ps", real_time_analysis_minimum_time="500 ps", ) rta_its, rta_min_its = settings_validation.convert_real_time_analysis_iterations(sim) assert rta_its == 250, 500 def test_convert_real_time_analysis_iterations_interval_fail(): # shouldn't like 250.5 ps / 1.0 ps sim = omm_settings.MultiStateSimulationSettings( equilibration_length="10 ps", production_length="10 ps", time_per_iteration="1.0 ps", real_time_analysis_interval="250.5 ps", real_time_analysis_minimum_time="500 ps", ) with pytest.raises(ValueError, match="does not evenly divide"): settings_validation.convert_real_time_analysis_iterations(sim) def test_convert_real_time_analysis_iterations_min_interval_fail(): # shouldn't like 500.5 ps / 1 ps sim = omm_settings.MultiStateSimulationSettings( equilibration_length="10 ps", production_length="10 ps", time_per_iteration="1.0 ps", real_time_analysis_interval="250 ps", real_time_analysis_minimum_time="500.5 ps", ) with pytest.raises(ValueError, match="does not evenly divide"): settings_validation.convert_real_time_analysis_iterations(sim) def test_convert_real_time_analysis_iterations_None(): sim = omm_settings.MultiStateSimulationSettings( equilibration_length="10 ps", production_length="10 ps", time_per_iteration="1.0 ps", real_time_analysis_interval=None, real_time_analysis_minimum_time="500 ps", ) rta_its, rta_min_its = settings_validation.convert_real_time_analysis_iterations(sim) assert rta_its is None assert rta_min_its is None def test_convert_target_error_from_kcal_per_mole_to_kT(): kT = settings_validation.convert_target_error_from_kcal_per_mole_to_kT( temperature=298.15 * unit.kelvin, target_error=0.12 * unit.kilocalorie_per_mole, ) assert kT == pytest.approx(0.20253681663365392) def test_convert_target_error_from_kcal_per_mole_to_kT_zero(): # special case, 0 input gives 0 output kT = settings_validation.convert_target_error_from_kcal_per_mole_to_kT( temperature=298.15 * unit.kelvin, target_error=0.0 * unit.kilocalorie_per_mole, ) assert kT == 0.0 class TestOFFPartialCharge: @pytest.fixture(scope="function") def uncharged_mol(self, CN_molecule): return CN_molecule.to_openff() @pytest.mark.parametrize("overwrite", [True, False]) def test_offmol_chg_gen_charged_overwrite(self, overwrite, uncharged_mol): chg = [1 for _ in range(len(uncharged_mol.atoms))] * unit.elementary_charge uncharged_mol.partial_charges = copy.deepcopy(chg) charge_generation.assign_offmol_partial_charges( uncharged_mol, overwrite=overwrite, method="am1bcc", toolkit_backend="ambertools", generate_n_conformers=None, nagl_model=None, ) assert np.allclose(uncharged_mol.partial_charges, chg) != overwrite def test_unknown_method(self, uncharged_mol): with pytest.raises(ValueError, match="Unknown partial charge method"): charge_generation.assign_offmol_partial_charges( uncharged_mol, overwrite=False, method="foo", toolkit_backend="ambertools", generate_n_conformers=None, nagl_model=None, ) @pytest.mark.parametrize( "method, backend", [ ["am1bcc", "rdkit"], ["am1bccelf10", "ambertools"], ["nagl", "bar"], ["espaloma", "openeye"], ], ) def test_incompatible_backend_am1bcc(self, method, backend, uncharged_mol): with pytest.raises(ValueError, match="Selected toolkit_backend"): charge_generation.assign_offmol_partial_charges( uncharged_mol, overwrite=False, method=method, toolkit_backend=backend, generate_n_conformers=None, nagl_model=None, ) def test_no_conformers(self, uncharged_mol): uncharged_mol._conformers = None with pytest.raises(ValueError, match="No conformers"): charge_generation.assign_offmol_partial_charges( uncharged_mol, overwrite=False, method="am1bcc", toolkit_backend="ambertools", generate_n_conformers=None, nagl_model=None, ) def test_too_many_existing_conformers(self, uncharged_mol): uncharged_mol.generate_conformers( n_conformers=2, rms_cutoff=0.001 * unit.angstrom, toolkit_registry=RDKitToolkitWrapper(), ) with pytest.raises(ValueError, match="too many conformers"): charge_generation.assign_offmol_partial_charges( uncharged_mol, overwrite=False, method="am1bcc", toolkit_backend="ambertools", generate_n_conformers=None, nagl_model=None, ) def test_too_many_requested_conformers(self, uncharged_mol): with pytest.raises(ValueError, match="5 conformers were requested"): charge_generation.assign_offmol_partial_charges( uncharged_mol, overwrite=False, method="am1bcc", toolkit_backend="ambertools", generate_n_conformers=5, nagl_model=None, ) def test_am1bcc_no_conformer(self, uncharged_mol): uncharged_mol._conformers = None with pytest.raises(ValueError, match="at least one conformer"): charge_generation.assign_offmol_am1bcc_charges( uncharged_mol, partial_charge_method="am1bcc", toolkit_registry=ToolkitRegistry([RDKitToolkitWrapper()]), ) @pytest.mark.slow def test_am1bcc_conformer_nochange(self, eg5_ligands): lig = eg5_ligands[0].to_openff() conf = copy.deepcopy(lig.conformers) # Get charges without conf generation charge_generation.assign_offmol_partial_charges( lig, overwrite=False, method="am1bcc", toolkit_backend="ambertools", generate_n_conformers=None, nagl_model=None, ) # check the conformation hasn't changed assert_allclose(conf, lig.conformers) # copy the charges to check that the conf gen will change things charges = copy.deepcopy(lig.partial_charges) # now with conformer generation charge_generation.assign_offmol_partial_charges( lig, overwrite=True, method="am1bcc", toolkit_backend="ambertools", generate_n_conformers=1, nagl_model=None, ) # conformer shouldn't have changed assert_allclose(conf, lig.conformers) # but the charges should have assert not np.allclose(charges, lig.partial_charges) @pytest.mark.skipif( not HAS_NAGL or HAS_OPENEYE, reason="NAGL is not available or oechem is installed" ) def test_latest_production_nagl(self, uncharged_mol): """We expect to find a NAGL model and be able to generate partial charges with it.""" charge_generation.assign_offmol_partial_charges( uncharged_mol, overwrite=False, method="nagl", toolkit_backend="rdkit", generate_n_conformers=None, nagl_model=None, ) assert uncharged_mol.partial_charges.units == "elementary_charge" @pytest.mark.skipif( not HAS_NAGL or HAS_OPENEYE, reason="NAGL is not available or oechem is installed" ) def test_no_production_nagl(self, uncharged_mol): """Cleanly handle the case where a NAGL model isn't found.""" with mock.patch( "openfe.protocols.openmm_utils.charge_generation.get_models_by_type", return_value=[] ): with pytest.raises(ValueError, match="No production am1bcc NAGL"): charge_generation.assign_offmol_partial_charges( uncharged_mol, overwrite=False, method="nagl", toolkit_backend="rdkit", generate_n_conformers=None, nagl_model=None, ) # Note: skipping nagl tests on macos/darwin due to known issues # see: https://github.com/openforcefield/openff-nagl/issues/78 @pytest.mark.parametrize( "method, backend, ref_key, confs", [ ("am1bcc", "ambertools", "ambertools", None), pytest.param( "am1bcc", "openeye", "openeye", None, marks=pytest.mark.skipif( not HAS_OPENEYE, reason="needs oechem", ), ), pytest.param( "am1bccelf10", "openeye", "openeye", 500, marks=pytest.mark.skipif( not HAS_OPENEYE, reason="needs oechem", ), ), pytest.param( "nagl", "rdkit", "nagl", None, marks=pytest.mark.skipif( not HAS_NAGL or HAS_OPENEYE or sys.platform.startswith("darwin"), reason="needs NAGL (without oechem) and/or on macos", ), ), pytest.param( "nagl", "ambertools", "nagl", None, marks=pytest.mark.skipif( not HAS_NAGL or HAS_OPENEYE or sys.platform.startswith("darwin"), reason="needs NAGL (without oechem) and/or on macos", ), ), pytest.param( "nagl", "openeye", "nagl", None, marks=pytest.mark.skipif( not HAS_NAGL or not HAS_OPENEYE or sys.platform.startswith("darwin"), reason="needs NAGL and oechem and not on macos", ), ), pytest.param( "espaloma", "rdkit", "espaloma", None, marks=pytest.mark.skipif( not HAS_ESPALOMA_CHARGE, reason="needs espaloma charge", ), ), pytest.param( "espaloma", "ambertools", "espaloma", None, marks=pytest.mark.skipif( not HAS_ESPALOMA_CHARGE, reason="needs espaloma charge", ), ), ], ) def test_am1bcc_reference( self, uncharged_mol, method, backend, ref_key, confs, am1bcc_ref_charges, ): """ Check partial charge generation using what would be intended default settings for a CN molecule """ charge_generation.assign_offmol_partial_charges( uncharged_mol, overwrite=False, method=method, toolkit_backend=backend, generate_n_conformers=None, nagl_model="openff-gnn-am1bcc-0.1.0-rc.1.pt", ) assert_allclose( am1bcc_ref_charges[ref_key], uncharged_mol.partial_charges, rtol=1e-4, ) @pytest.mark.skipif(not HAS_OPENEYE, reason="OEToolkit is not available") def test_nagl_oechem_not_openeye_error(self, uncharged_mol): errmsg = "OpenEye toolkit is installed but not used in the OpenFF toolkit registry." with pytest.raises(ValueError, match=errmsg): charge_generation.assign_offmol_partial_charges( uncharged_mol, overwrite=False, method="nagl", toolkit_backend="rdkit", generate_n_conformers=None, nagl_model=None, ) @pytest.mark.skipif( HAS_OPENEYE, reason="NAGL does not work with OpenEye when using the rdkit backend" ) def test_nagl_import_error(self, monkeypatch, uncharged_mol): monkeypatch.setattr( sys.modules["openfe.protocols.openmm_utils.charge_generation"], "HAS_NAGL", False, ) with pytest.raises(ImportError, match="NAGL toolkit is not available"): charge_generation.assign_offmol_partial_charges( uncharged_mol, overwrite=False, method="nagl", toolkit_backend="rdkit", generate_n_conformers=None, nagl_model=None, ) def test_espaloma_import_error(self, monkeypatch, uncharged_mol): monkeypatch.setattr( sys.modules["openfe.protocols.openmm_utils.charge_generation"], "HAS_ESPALOMA_CHARGE", False, ) with pytest.raises(ImportError, match="Espaloma"): charge_generation.assign_offmol_partial_charges( uncharged_mol, overwrite=False, method="espaloma", toolkit_backend="rdkit", generate_n_conformers=None, nagl_model=None, ) def test_openeye_import_error(self, monkeypatch, uncharged_mol): monkeypatch.setattr( sys.modules["openfe.protocols.openmm_utils.charge_generation"], "HAS_OPENEYE", False, ) with pytest.raises(ImportError, match="OpenEye is not available"): charge_generation.assign_offmol_partial_charges( uncharged_mol, overwrite=False, method="am1bcc", toolkit_backend="openeye", generate_n_conformers=None, nagl_model=None, ) @pytest.mark.slow @pytest.mark.skipif( not os.path.exists(POOCH_CACHE) and not HAS_INTERNET, reason="Internet seems to be unavailable and test data is not cached locally.", ) def test_forward_backwards_failure(simulation_nc): rep = multistate.multistatereporter.MultiStateReporter(simulation_nc, open_mode="r") ana = multistate_analysis.MultistateEquilFEAnalysis( rep, sampling_method="repex", result_units=unit.kilocalorie_per_mole, ) with mock.patch( "openfe.protocols.openmm_utils.multistate_analysis.MultistateEquilFEAnalysis._get_free_energy", side_effect=ParameterError, ): ret = ana.get_forward_and_reverse_analysis() assert ret is None ================================================ FILE: src/openfe/tests/protocols/test_openmmutils_serialization.py ================================================ # This code is part of OpenFE and is licensed under the MIT license. # For details, see https://github.com/OpenFreeEnergy/openfe import bz2 import gzip import pathlib from unittest import mock from openfe.protocols.openmm_utils.serialization import deserialize, serialize def test_serialize_creates_parent_directory(tmp_path): filename = tmp_path / "file.xml" with mock.patch("openmm.XmlSerializer.serialize", return_value=""): serialize(object(), filename) assert filename.exists() assert filename.read_text() == "" def test_serialize_xml(tmp_path): filename = tmp_path / "file.xml" with mock.patch("openmm.XmlSerializer.serialize", return_value=""): serialize(object(), filename) with open(filename, "r") as f: assert f.read() == "" def test_serialize_bz2(tmp_path): filename = pathlib.Path(tmp_path / "file.xml.bz2") expected = "" with mock.patch("openmm.XmlSerializer.serialize", return_value=expected): serialize(object(), filename) with bz2.open(filename, "rb") as f: read_back = f.read().decode() assert read_back == expected def test_deserialize_xml(tmp_path): filename = pathlib.Path(tmp_path / "file.xml") filename.write_text("things") with mock.patch("openmm.XmlSerializer.deserialize", return_value="DESERIALIZED") as deser: result = deserialize(filename) deser.assert_called_once_with("things") assert result == "DESERIALIZED" def test_deserialize_bz2(tmp_path): filename = pathlib.Path(tmp_path / "file.xml.bz2") expected_serialized = "bz2" with bz2.open(filename, "wb") as f: f.write(expected_serialized.encode()) with mock.patch("openmm.XmlSerializer.deserialize", return_value="FROM_BZ2") as deser: result = deserialize(filename) deser.assert_called_once_with(expected_serialized) assert result == "FROM_BZ2" ================================================ FILE: src/openfe/tests/setup/__init__.py ================================================ ================================================ FILE: src/openfe/tests/setup/alchemical_network_planner/__init__.py ================================================ ================================================ FILE: src/openfe/tests/setup/alchemical_network_planner/edge_types.py ================================================ from gufe import Transformation from ..chemicalsystem_generator.component_checks import ( ligandC_in_chem_sys, proteinC_in_chem_sys, solventC_in_chem_sys, ) def both_states_proteinC_edge(edge: Transformation) -> bool: return proteinC_in_chem_sys(edge.stateA) and proteinC_in_chem_sys(edge.stateB) def both_states_solventC_edge(edge: Transformation) -> bool: return solventC_in_chem_sys(edge.stateA) and solventC_in_chem_sys(edge.stateB) def both_states_ligandC_edge(edge: Transformation) -> bool: return ligandC_in_chem_sys(edge.stateA) and ligandC_in_chem_sys(edge.stateB) def r_vacuum_edge(edge: Transformation) -> bool: return ( both_states_ligandC_edge(edge) and not both_states_solventC_edge(edge) and not both_states_proteinC_edge(edge) ) def r_solvent_edge(edge: Transformation) -> bool: return ( both_states_ligandC_edge(edge) and both_states_solventC_edge(edge) and not both_states_proteinC_edge(edge) ) def r_complex_edge(edge: Transformation) -> bool: return ( both_states_ligandC_edge(edge) and both_states_solventC_edge(edge) and both_states_proteinC_edge(edge) ) ================================================ FILE: src/openfe/tests/setup/alchemical_network_planner/test_relative_alchemical_network_planner.py ================================================ # This code is part of OpenFE and is licensed under the MIT license. # For details, see https://github.com/OpenFreeEnergy/openfe import pytest from gufe import AlchemicalNetwork, SolventComponent import openfe from openfe.setup.alchemical_network_planner import ( RBFEAlchemicalNetworkPlanner, RHFEAlchemicalNetworkPlanner, ) from .edge_types import r_complex_edge, r_solvent_edge, r_vacuum_edge def test_rhfe_alchemical_network_planner_init(): alchem_planner = RHFEAlchemicalNetworkPlanner() assert alchem_planner.name == "rhfe" def test_rbfe_alchemical_network_planner_init(): alchem_planner = RBFEAlchemicalNetworkPlanner() assert alchem_planner.name == "rbfe" def test_rbfe_alchemical_network_planner_call(atom_mapping_basic_test_files, T4_protein_component): alchem_planner = RBFEAlchemicalNetworkPlanner( # these aren't default settings, but the test ligands aren't aligned mappers=[ openfe.LomapAtomMapper( time=20, element_change=False, max3d=1, shift=True, ) ] ) alchem_network = alchem_planner( ligands=atom_mapping_basic_test_files.values(), solvent=SolventComponent(), protein=T4_protein_component, ) assert isinstance(alchem_network, AlchemicalNetwork) edges = alchem_network.edges assert len(edges) == 14 # we build 2envs * (8 ligands - 1) = 14 relative edges. assert ( sum([r_complex_edge(e) for e in edges]) == 7 ) # half of the transformations should be complex (they always are)! assert ( sum([r_solvent_edge(e) for e in edges]) == 7 ) # half of the transformations should be solvent! assert sum([r_vacuum_edge(e) for e in edges]) == 0 # no vacuum here! expected_names = { "rbfe_1,3,7-trimethylnaphthalene_solvent_1-butyl-4-methylbenzene_solvent", "rbfe_2-methylnaphthalene_complex_methylcyclohexane_complex", "rbfe_2,6-dimethylnaphthalene_solvent_2-methyl-6-propylnaphthalene_solvent", "rbfe_2-methylnaphthalene_complex_toluene_complex", "rbfe_2,6-dimethylnaphthalene_complex_2-methyl-6-propylnaphthalene_complex", "rbfe_2,6-dimethylnaphthalene_solvent_toluene_solvent", "rbfe_1,3,7-trimethylnaphthalene_complex_1-butyl-4-methylbenzene_complex", "rbfe_1,3,7-trimethylnaphthalene_solvent_2,6-dimethylnaphthalene_solvent", "rbfe_2,6-dimethylnaphthalene_complex_toluene_complex", "rbfe_2-naftanol_solvent_toluene_solvent", "rbfe_2-naftanol_complex_toluene_complex", "rbfe_2-methylnaphthalene_solvent_toluene_solvent", "rbfe_1,3,7-trimethylnaphthalene_complex_2,6-dimethylnaphthalene_complex", "rbfe_2-methylnaphthalene_solvent_methylcyclohexane_solvent", } result_names = {e.name for e in alchem_network.edges} assert result_names == expected_names def test_rhfe_alchemical_network_planner_call_multigraph(atom_mapping_basic_test_files): alchem_planner = RHFEAlchemicalNetworkPlanner( mappers=[ openfe.LomapAtomMapper( time=20, element_change=False, max3d=1, shift=True, ) ] ) ligand_network = alchem_planner._construct_ligand_network(atom_mapping_basic_test_files.values()) # fmt: skip ligand_network_edges = list(ligand_network.edges) ligand_network_edges.extend(list(ligand_network.edges)) chemical_system_generator = alchem_planner._chemical_system_generator_type( solvent=SolventComponent() ) with pytest.raises( ValueError, match="There were multiple transformations with the same edge label! This might lead to overwriting your files.", ): _ = alchem_planner._build_transformations( ligand_network_edges=ligand_network_edges, protocol=alchem_planner.transformation_protocol, chemical_system_generator=chemical_system_generator, ) def test_rhfe_alchemical_network_planner_call(atom_mapping_basic_test_files): alchem_planner = RHFEAlchemicalNetworkPlanner( mappers=[openfe.LomapAtomMapper(time=20, element_change=False, max3d=1, shift=True)] ) alchem_network = alchem_planner( ligands=atom_mapping_basic_test_files.values(), solvent=SolventComponent() ) assert isinstance(alchem_network, AlchemicalNetwork) edges = alchem_network.edges assert len(edges) == 14 # we build 2envs*(8 ligands - 1) = 14 relative edges. expected_names = { "rhfe_2,6-dimethylnaphthalene_solvent_toluene_solvent", "rhfe_1,3,7-trimethylnaphthalene_vacuum_2,6-dimethylnaphthalene_vacuum", "rhfe_2-methylnaphthalene_vacuum_toluene_vacuum", "rhfe_2-methylnaphthalene_vacuum_methylcyclohexane_vacuum", "rhfe_2,6-dimethylnaphthalene_vacuum_2-methyl-6-propylnaphthalene_vacuum", "rhfe_1,3,7-trimethylnaphthalene_vacuum_1-butyl-4-methylbenzene_vacuum", "rhfe_1,3,7-trimethylnaphthalene_solvent_2,6-dimethylnaphthalene_solvent", "rhfe_2-methylnaphthalene_solvent_methylcyclohexane_solvent", "rhfe_2-naftanol_vacuum_toluene_vacuum", "rhfe_2-naftanol_solvent_toluene_solvent", "rhfe_2-methylnaphthalene_solvent_toluene_solvent", "rhfe_1,3,7-trimethylnaphthalene_solvent_1-butyl-4-methylbenzene_solvent", "rhfe_2,6-dimethylnaphthalene_vacuum_toluene_vacuum", "rhfe_2,6-dimethylnaphthalene_solvent_2-methyl-6-propylnaphthalene_solvent", } assert sum([r_complex_edge(e) for e in edges]) == 0 # no complex! assert ( sum([r_solvent_edge(e) for e in edges]) == 7 ) # half of the transformations should be solvent! assert ( sum([r_vacuum_edge(e) for e in edges]) == 7 ) # half of the transformations should be vacuum! result_names = {e.name for e in alchem_network.edges} assert result_names == expected_names ================================================ FILE: src/openfe/tests/setup/atom_mapping/__init__.py ================================================ ================================================ FILE: src/openfe/tests/setup/atom_mapping/conftest.py ================================================ # This code is part of OpenFE and is licensed under the MIT license. # For details, see https://github.com/OpenFreeEnergy/openfe from typing import Dict, Tuple import lomap import pytest from gufe import SmallMoleculeComponent from rdkit import Chem from openfe import LigandAtomMapping from ...conftest import mol_from_smiles def _translate_lomap_mapping(atom_mapping_str: str) -> Dict[int, int]: mapped_atom_tuples = map(lambda x: tuple(map(int, x.split(":"))), atom_mapping_str.split(",")) return {i: j for i, j in mapped_atom_tuples} def _get_atom_mapping_dict(lomap_atom_mappings) -> Dict[Tuple[int, int], Dict[int, int]]: return { mol_pair: _translate_lomap_mapping(atom_mapping_str) for mol_pair, atom_mapping_str in lomap_atom_mappings.mcs_map_store.items() } @pytest.fixture() def gufe_atom_mapping_matrix( lomap_basic_test_files_dir, atom_mapping_basic_test_files ) -> Dict[Tuple[int, int], LigandAtomMapping]: dbmols = lomap.DBMolecules(lomap_basic_test_files_dir, verbose="off") _, _ = dbmols.build_matrices() molecule_pair_atom_mappings = _get_atom_mapping_dict(dbmols) ligand_atom_mappings = {} for (i, j), val in molecule_pair_atom_mappings.items(): nm1 = dbmols[i].getName()[:-5] nm2 = dbmols[j].getName()[:-5] ligand_atom_mappings[(i, j)] = LigandAtomMapping( componentA=atom_mapping_basic_test_files[nm1], componentB=atom_mapping_basic_test_files[nm2], componentA_to_componentB=val, ) return ligand_atom_mappings @pytest.fixture() def mol_pair_to_shock_perses_mapper() -> Tuple[SmallMoleculeComponent, SmallMoleculeComponent]: """ This pair of Molecules leads to an empty Atom mapping in Perses Mapper with certain settings. Returns: Tuple[SmallMoleculeComponent]: two molecule objs for the test """ molA = SmallMoleculeComponent(mol_from_smiles("c1ccccc1"), "benzene") molB = SmallMoleculeComponent(mol_from_smiles("C1CCCCC1"), "cyclohexane") return molA, molB ================================================ FILE: src/openfe/tests/setup/atom_mapping/test_atommapper.py ================================================ import pytest from openfe.setup.atom_mapping.ligandatommapper import LigandAtomMapper from openfe.utils import ligand_utils class TestAtomMapper: def test_abstract_error(self, simple_mapping): # suggest_mappings should fail with NotImplementedError if the user # tries to directly user the abstract class molA = simple_mapping.componentA molB = simple_mapping.componentB with pytest.raises(TypeError): mapper = LigandAtomMapper() list(mapper.suggest_mappings(molA, molB)) def test_concrete_mapper(self, simple_mapping, other_mapping): # a correctly implemented concrete atom mapping should return the # mappings generated by the _mappings_generator molA = simple_mapping.componentA molB = simple_mapping.componentB class ConcreteLigandAtomMapper(LigandAtomMapper): def __init__(self, mappings): self.mappings = mappings @classmethod def _defaults(cls): return {} def _to_dict(self): return {"mappings": self.mappings} @classmethod def _from_dict(cls, dct): return cls(**dct) def _mappings_generator(self, componentA, componentB): for mapping in self.mappings: yield mapping.componentA_to_componentB mapper = ConcreteLigandAtomMapper([simple_mapping, other_mapping]) results = list(mapper.suggest_mappings(molA, molB)) assert len(results) == 2 assert results == [simple_mapping, other_mapping] def test_alchemical_charge_deprecation_warning(self, simple_mapping): with pytest.warns(DeprecationWarning, match=r"Use gufe\.LigandAtomMapping"): ligand_utils.get_alchemical_charge_difference(simple_mapping) ================================================ FILE: src/openfe/tests/setup/atom_mapping/test_lomap_atommapper.py ================================================ # This code is part of OpenFE and is licensed under the MIT license. # For details, see https://github.com/OpenFreeEnergy/openfe import pytest from gufe import SmallMoleculeComponent from rdkit import Chem from rdkit.Chem import AllChem import openfe from openfe.setup.atom_mapping import LomapAtomMapper from .conftest import mol_from_smiles def test_simple(atom_mapping_basic_test_files, lomap_old_mapper): # basic sanity check on the LigandAtomMapper mol1 = atom_mapping_basic_test_files["methylcyclohexane"] mol2 = atom_mapping_basic_test_files["toluene"] mapper = lomap_old_mapper mapping_gen = mapper.suggest_mappings(mol1, mol2) mapping = next(mapping_gen) assert isinstance(mapping, openfe.setup.atom_mapping.LigandAtomMapping) # maps (CH3) off methyl and (6C + 5H) on ring assert len(mapping.componentA_to_componentB) == 15 def test_distances(atom_mapping_basic_test_files, lomap_old_mapper): # basic sanity check on the LigandAtomMapper mol1 = atom_mapping_basic_test_files["methylcyclohexane"] mol2 = atom_mapping_basic_test_files["toluene"] mapper = lomap_old_mapper mapping = next(mapper.suggest_mappings(mol1, mol2)) dists = mapping.get_distances() assert len(dists) == len(mapping.componentA_to_componentB) i, j = next(iter(mapping.componentA_to_componentB.items())) ref_d = ( mol1.to_rdkit() .GetConformer() .GetAtomPosition(i) .Distance(mol2.to_rdkit().GetConformer().GetAtomPosition(j)) ) assert pytest.approx(dists[0], rel=1e-5) == ref_d assert pytest.approx(dists[0], rel=1e-5) == 0.07249779 def test_generator_length(atom_mapping_basic_test_files, lomap_old_mapper): # check that we get one mapping back from Lomap LigandAtomMapper then the # generator stops correctly mol1 = atom_mapping_basic_test_files["methylcyclohexane"] mol2 = atom_mapping_basic_test_files["toluene"] mapper = lomap_old_mapper mapping_gen = mapper.suggest_mappings(mol1, mol2) _ = next(mapping_gen) with pytest.raises(StopIteration): next(mapping_gen) def test_bad_mapping(atom_mapping_basic_test_files, lomap_old_mapper): toluene = atom_mapping_basic_test_files["toluene"] NigelTheNitrogen = SmallMoleculeComponent(mol_from_smiles("N"), name="Nigel") mapper = lomap_old_mapper mapping_gen = mapper.suggest_mappings(toluene, NigelTheNitrogen) with pytest.raises(StopIteration): next(mapping_gen) # TODO: Remove these test when element changes are allowed - START def test_simple_no_element_changes(atom_mapping_basic_test_files, lomap_old_mapper): # basic sanity check on the LigandAtomMapper mol1 = atom_mapping_basic_test_files["methylcyclohexane"] mol2 = atom_mapping_basic_test_files["toluene"] mapper = lomap_old_mapper mapper._no_element_changes = True mapping_gen = mapper.suggest_mappings(mol1, mol2) mapping = next(mapping_gen) assert isinstance(mapping, openfe.setup.atom_mapping.LigandAtomMapping) # maps (CH3) off methyl and (6C + 5H) on ring assert len(mapping.componentA_to_componentB) == 15 def test_bas_mapping_no_element_changes(atom_mapping_basic_test_files, lomap_old_mapper): toluene = atom_mapping_basic_test_files["toluene"] NigelTheNitrogen = SmallMoleculeComponent(mol_from_smiles("N"), name="Nigel") mapper = lomap_old_mapper mapper._no_element_changes = True mapping_gen = mapper.suggest_mappings(toluene, NigelTheNitrogen) with pytest.raises(StopIteration): next(mapping_gen) # TODO: Remove these test when element changes are allowed - END ================================================ FILE: src/openfe/tests/setup/atom_mapping/test_lomap_scorers.py ================================================ # This code is part of OpenFE and is licensed under the MIT license. # For details, see https://github.com/OpenFreeEnergy/openfe import itertools import math import lomap import numpy as np import pytest from numpy.testing import assert_allclose from rdkit import Chem from rdkit.Chem.AllChem import Compute2DCoords # type: ignore[attr-defined] import openfe from openfe.setup import LigandAtomMapping, lomap_scorers from .conftest import mol_from_smiles @pytest.fixture() def toluene_to_cyclohexane(atom_mapping_basic_test_files): meth = atom_mapping_basic_test_files["methylcyclohexane"] tolu = atom_mapping_basic_test_files["toluene"] mapping = [(0, 0), (1, 1), (2, 6), (3, 5), (4, 4), (5, 3), (6, 2)] return LigandAtomMapping(tolu, meth, componentA_to_componentB=dict(mapping)) @pytest.fixture() def toluene_to_methylnaphthalene(atom_mapping_basic_test_files): tolu = atom_mapping_basic_test_files["toluene"] naph = atom_mapping_basic_test_files["2-methylnaphthalene"] mapping = [(0, 0), (1, 1), (2, 2), (3, 3), (4, 8), (5, 9), (6, 10)] return LigandAtomMapping(tolu, naph, componentA_to_componentB=dict(mapping)) @pytest.fixture() def toluene_to_heptane(atom_mapping_basic_test_files): tolu = atom_mapping_basic_test_files["toluene"] hept = Chem.MolFromSmiles("CCCCCCC") Chem.rdDepictor.Compute2DCoords(hept) hept = openfe.SmallMoleculeComponent(hept) mapping = [(6, 0)] return LigandAtomMapping(tolu, hept, componentA_to_componentB=dict(mapping)) @pytest.fixture() def methylnaphthalene_to_naphthol(atom_mapping_basic_test_files): m1 = atom_mapping_basic_test_files["2-methylnaphthalene"] m2 = atom_mapping_basic_test_files["2-naftanol"] mapping = [ (0, 0), (1, 1), (2, 10), (3, 9), (4, 8), (5, 7), (6, 6), (7, 5), (8, 4), (9, 3), (10, 2), ] return LigandAtomMapping(m1, m2, componentA_to_componentB=dict(mapping)) def test_mcsr_zero(toluene_to_cyclohexane): score = lomap_scorers.mcsr_score(toluene_to_cyclohexane) # all atoms map, so perfect score assert score == 1 def test_mcsr_nonzero(toluene_to_methylnaphthalene): score = lomap_scorers.mcsr_score(toluene_to_methylnaphthalene) assert score == pytest.approx(math.exp(-0.1 * 4)) def test_mcsr_custom_beta(toluene_to_methylnaphthalene): score = lomap_scorers.mcsr_score(toluene_to_methylnaphthalene, beta=0.2) assert score == pytest.approx(math.exp(-0.2 * 4)) def test_mcnar_score_pass(toluene_to_cyclohexane): score = lomap_scorers.mncar_score(toluene_to_cyclohexane) assert score == 1.0 def test_mcnar_score_fail(toluene_to_heptane): score = lomap_scorers.mncar_score(toluene_to_heptane) assert score == 0.0 def test_atomic_number_score_pass(toluene_to_cyclohexane): score = lomap_scorers.atomic_number_score(toluene_to_cyclohexane) assert score == 1.0 def test_atomic_number_score_fail(methylnaphthalene_to_naphthol): score = lomap_scorers.atomic_number_score(methylnaphthalene_to_naphthol) # single mismatch @ 0.5 assert score == pytest.approx(math.exp(-0.1 * 0.5)) def test_atomic_number_score_weights(methylnaphthalene_to_naphthol): difficulty = { 8: {6: 0.75}, # oxygen to carbon @ 12 } score = lomap_scorers.atomic_number_score(methylnaphthalene_to_naphthol, difficulty=difficulty) # single mismatch @ (1 - 0.75) assert score == pytest.approx(math.exp(-0.1 * 0.25)) class TestSulfonamideRule: @staticmethod @pytest.fixture def ethylbenzene(): m = Chem.AddHs(mol_from_smiles("c1ccccc1CCC")) return openfe.SmallMoleculeComponent.from_rdkit(m) @staticmethod @pytest.fixture def sulfonamide(): # technically 3-phenylbutane-1-sulfonamide m = Chem.AddHs(mol_from_smiles("c1ccccc1C(C)CCS(=O)(=O)N")) return openfe.SmallMoleculeComponent.from_rdkit(m) @staticmethod @pytest.fixture def from_sulf_mapping(): # this is the standard output from lomap_scorers return { 0: 0, 1: 1, 2: 2, 3: 3, 4: 4, 5: 5, 6: 6, 7: 14, 8: 7, 9: 8, 10: 18, 14: 9, 15: 10, 16: 11, 17: 12, 18: 13, 19: 15, 23: 16, 24: 17, 25: 19, 26: 20, } @staticmethod def test_sulfonamide_hit_backwards(ethylbenzene, sulfonamide, from_sulf_mapping): # a sulfonamide completely disappears on the RHS, so should trigger # the sulfonamide score to try and forbid this mapping = LigandAtomMapping( componentA=sulfonamide, componentB=ethylbenzene, componentA_to_componentB=from_sulf_mapping, ) expected = math.exp(-1 * 0.4) assert lomap_scorers.sulfonamides_score(mapping) == expected @staticmethod def test_sulfonamide_hit_forwards(ethylbenzene, sulfonamide, from_sulf_mapping): AtoB = {v: k for k, v in from_sulf_mapping.items()} # this is the standard output from lomap_scorers mapping = LigandAtomMapping( componentA=ethylbenzene, componentB=sulfonamide, componentA_to_componentB=AtoB ) expected = math.exp(-1 * 0.4) assert lomap_scorers.sulfonamides_score(mapping) == expected @pytest.mark.parametrize( "base,other,name,hit", [ ("CCc1ccccc1", "CCc1ccc(-c2ccco2)cc1", "phenylfuran", False), ("CCc1ccccc1", "CCc1ccc(-c2cnc[nH]2)cc1", "phenylimidazole", True), ("CCc1ccccc1", "CCc1ccc(-c2ccno2)cc1", "phenylisoxazole", True), ("CCc1ccccc1", "CCc1ccc(-c2cnco2)cc1", "phenyloxazole", True), ("CCc1ccccc1", "CCc1ccc(-c2cccnc2)cc1", "phenylpyridine1", True), ("CCc1ccccc1", "CCc1ccc(-c2ccccn2)cc1", "phenylpyridine2", True), ("CCc1ccccc1", "CCc1ccc(-c2cncnc2)cc1", "phenylpyrimidine", True), ("CCc1ccccc1", "CCc1ccc(-c2ccc[nH]2)cc1", "phenylpyrrole", False), ("CCc1ccccc1", "CCc1ccc(-c2ccccc2)cc1", "phenylphenyl", False), ], ) def test_heterocycle_score(base, other, name, hit): # base -> other transform, if *hit* a forbidden heterocycle is created r1 = Chem.AddHs(mol_from_smiles(base)) r2 = Chem.AddHs(mol_from_smiles(other)) # add 2d coords to stop Lomap crashing for now for r in [r1, r2]: Compute2DCoords(r) m1 = openfe.SmallMoleculeComponent.from_rdkit(r1) m2 = openfe.SmallMoleculeComponent.from_rdkit(r2) mapper = openfe.setup.atom_mapping.LomapAtomMapper( time=20, threed=False, max3d=1000.0, element_change=True, seed="", shift=True, ) mapping = next(mapper.suggest_mappings(m1, m2)) score = lomap_scorers.heterocycles_score(mapping) assert score == 1.0 if not hit else score == math.exp(-0.4) # test individual scoring functions against lomap SCORE_NAMES = { "mcsr": "mcsr_score", "mncar": "mncar_score", "atomic_number_rule": "atomic_number_score", "hybridization_rule": "hybridization_score", "sulfonamides_rule": "sulfonamides_score", "heterocycles_rule": "heterocycles_score", "transmuting_methyl_into_ring_rule": "transmuting_methyl_into_ring_score", "transmuting_ring_sizes_rule": "transmuting_ring_sizes_score", } IX = itertools.combinations(range(8), 2) @pytest.mark.parametrize("params", itertools.product(SCORE_NAMES, IX)) def test_lomap_individual_scores(params, atom_mapping_basic_test_files): scorename, (i, j) = params mols = sorted(atom_mapping_basic_test_files.items()) _, molA = mols[i] _, molB = mols[j] # reference value lomap_version = getattr(lomap.MCS(molA.to_rdkit(), molB.to_rdkit()), scorename)() # longer way mapper = openfe.setup.atom_mapping.LomapAtomMapper( time=20, threed=False, max3d=1000.0, element_change=True, seed="", shift=True, ) mapping = next(mapper.suggest_mappings(molA, molB)) openfe_version = getattr(lomap_scorers, SCORE_NAMES[scorename])(mapping) assert lomap_version == pytest.approx(openfe_version), f"{molA.name} {molB.name} {scorename}" # full back to back test again lomap def test_lomap_regression( lomap_basic_test_files_dir, # in a dir for lomap atom_mapping_basic_test_files, ): # run lomap dbmols = lomap.DBMolecules(lomap_basic_test_files_dir) matrix, _ = dbmols.build_matrices() matrix = matrix.to_numpy_2D_array() assert matrix.shape == (8, 8) # now run the openfe equivalent # first, get the order identical to lomap smallmols = [] for i in range(matrix.shape[0]): nm = dbmols[i].getName() smallmols.append(atom_mapping_basic_test_files[nm[:-5]]) # - ".mol2" mapper = openfe.setup.atom_mapping.LomapAtomMapper( time=20, threed=False, max3d=1000.0, element_change=True, seed="", shift=True, ) scorer = lomap_scorers.default_lomap_score scores = np.zeros_like(matrix) for i, j in itertools.combinations(range(matrix.shape[0]), 2): molA = smallmols[i] molB = smallmols[j] mapping = next(mapper.suggest_mappings(molA, molB)) score = scorer(mapping) scores[i, j] = scores[j, i] = score # fudge diagonal for comparison for i in range(matrix.shape[0]): scores[i, i] = 0 assert_allclose(matrix, scores) def test_transmuting_methyl_into_ring_score(): """ Sets up two mappings: RC_to_RPh = [CCC]C -> [CCC]Ph RH_to_RPh = [CCC]H -> [CCC]Ph Where square brackets show mapped (core) region The first mapping should trigger this rule, the second shouldn't """ def makemol(smi): m = Chem.MolFromSmiles(smi) m = Chem.AddHs(m) m.Compute2DCoords() return openfe.SmallMoleculeComponent(m) core = "CCC{}" RC = makemol(core.format("C")) RPh = makemol(core.format("c1ccccc1")) RH = makemol(core.format("[H]")) RC_to_RPh = openfe.LigandAtomMapping(RC, RPh, {i: i for i in range(3)}) RH_to_RPh = openfe.LigandAtomMapping(RH, RPh, {i: i for i in range(3)}) score1 = lomap_scorers.transmuting_methyl_into_ring_score(RC_to_RPh) score2 = lomap_scorers.transmuting_methyl_into_ring_score(RH_to_RPh) assert score1 == pytest.approx(math.exp(-0.1 * 6.0)) assert score2 == 1.0 ================================================ FILE: src/openfe/tests/setup/atom_mapping/test_perses_atommapper.py ================================================ # This code is part of OpenFE and is licensed under the MIT license. # For details, see https://github.com/OpenFreeEnergy/openfe import pytest from openff.units import unit from openff.utilities.testing import skip_if_missing from openfe.setup.atom_mapping import LigandAtomMapping, PersesAtomMapper @skip_if_missing("openeye") @skip_if_missing("perses") def test_simple(atom_mapping_basic_test_files): # basic sanity check on the LigandAtomMapper mol1 = atom_mapping_basic_test_files["methylcyclohexane"] mol2 = atom_mapping_basic_test_files["toluene"] with pytest.warns(DeprecationWarning, match="PersesAtomMapper"): mapper = PersesAtomMapper() mapping_gen = mapper.suggest_mappings(mol1, mol2) mapping = next(mapping_gen) assert isinstance(mapping, LigandAtomMapping) # maps (CH3) off methyl and (6C + 5H) on ring assert len(mapping.componentA_to_componentB) == 4 @skip_if_missing("openeye") @skip_if_missing("perses") def test_generator_length(atom_mapping_basic_test_files): # check that we get one mapping back from Lomap LigandAtomMapper then the # generator stops correctly mol1 = atom_mapping_basic_test_files["methylcyclohexane"] mol2 = atom_mapping_basic_test_files["toluene"] with pytest.warns(DeprecationWarning, match="PersesAtomMapper"): mapper = PersesAtomMapper() mapping_gen = mapper.suggest_mappings(mol1, mol2) _ = next(mapping_gen) with pytest.raises(StopIteration): next(mapping_gen) @skip_if_missing("openeye") @skip_if_missing("perses") def test_empty_atommappings(mol_pair_to_shock_perses_mapper): mol1, mol2 = mol_pair_to_shock_perses_mapper with pytest.warns(DeprecationWarning, match="PersesAtomMapper"): mapper = PersesAtomMapper() mapping_gen = mapper.suggest_mappings(mol1, mol2) # The expected return is an empty mapping assert len(list(mapping_gen)) == 0 with pytest.raises(StopIteration): next(mapping_gen) @skip_if_missing("openeye") @skip_if_missing("perses") def test_dict_round_trip(): with pytest.warns(DeprecationWarning, match="PersesAtomMapper"): # use some none defaults mapper1 = PersesAtomMapper( allow_ring_breaking=False, preserve_chirality=False, coordinate_tolerance=0.01 * unit.nanometer, ) mapper2 = PersesAtomMapper.from_dict(mapper1.to_dict()) assert mapper2.to_dict() == mapper1.to_dict() ================================================ FILE: src/openfe/tests/setup/atom_mapping/test_perses_scorers.py ================================================ # This code is part of OpenFE and is licensed under the MIT license. # For details, see https://github.com/OpenFreeEnergy/openfe import numpy as np import pytest from numpy.testing import assert_, assert_allclose from openff.utilities import skip_if_missing from openfe.setup import perses_scorers from ....utils.silence_root_logging import silence_root_logging USING_OLD_OFF = False @skip_if_missing("openeye") @skip_if_missing("perses") @pytest.mark.xfail(not USING_OLD_OFF, reason="perses #1108") def test_perses_normalization_not_using_positions(gufe_atom_mapping_matrix): # now run the openfe equivalent with the same ligand atom _mappings with pytest.warns(DeprecationWarning, match="default_perses_scorer"): scorer = perses_scorers.default_perses_scorer molecule_row = np.max(list(gufe_atom_mapping_matrix.keys())) + 1 norm_scores = np.zeros([molecule_row, molecule_row]) for (i, j), ligand_atom_mapping in gufe_atom_mapping_matrix.items(): norm_score = scorer( ligand_atom_mapping, use_positions=False, normalize=True, ) norm_scores[i, j] = norm_scores[j, i] = norm_score assert norm_scores.shape == (8, 8) assert_( np.all((norm_scores <= 1) & (norm_scores >= 0.0)), msg="OpenFE norm value larger than 1 or smaller than 0", ) @skip_if_missing("openeye") @skip_if_missing("perses") @pytest.mark.xfail(not USING_OLD_OFF, reason="perses #1108") def test_perses_not_implemented_position_using(gufe_atom_mapping_matrix): with pytest.warns(DeprecationWarning, match="default_perses_scorer"): scorer = perses_scorers.default_perses_scorer first_key = list(gufe_atom_mapping_matrix.keys())[0] match_re = "normalizing using positions is not currently implemented" with pytest.raises(NotImplementedError, match=match_re): norm_score = scorer( gufe_atom_mapping_matrix[first_key], use_positions=True, normalize=True, ) @skip_if_missing("openeye") @skip_if_missing("perses") @pytest.mark.xfail(not USING_OLD_OFF, reason="perses #1108") def test_perses_regression(gufe_atom_mapping_matrix): with silence_root_logging(): from perses.rjmc.atom_mapping import AtomMapper, AtomMapping # This is the way how perses does scoring molecule_row = np.max(list(gufe_atom_mapping_matrix.keys())) + 1 matrix = np.zeros([molecule_row, molecule_row]) for x in gufe_atom_mapping_matrix.items(): (i, j), ligand_atom_mapping = x # Build Perses Mapping: perses_atom_mapping = AtomMapping( old_mol=ligand_atom_mapping.componentA.to_openff(), new_mol=ligand_atom_mapping.componentB.to_openff(), old_to_new_atom_map=ligand_atom_mapping.componentA_to_componentB, ) # score Perses Mapping - Perses Style matrix[i, j] = matrix[j, i] = AtomMapper().score_mapping(perses_atom_mapping) assert matrix.shape == (8, 8) # now run the openfe equivalent with the same ligand atom _mappings with pytest.warns(DeprecationWarning, match="default_perses_scorer"): scorer = perses_scorers.default_perses_scorer scores = np.zeros_like(matrix) for (i, j), ligand_atom_mapping in gufe_atom_mapping_matrix.items(): score = scorer( ligand_atom_mapping, use_positions=True, normalize=False, ) scores[i, j] = scores[j, i] = score assert_allclose( actual=matrix, desired=scores, err_msg="openFE was not close to perses", ) ================================================ FILE: src/openfe/tests/setup/chemicalsystem_generator/__init__.py ================================================ ================================================ FILE: src/openfe/tests/setup/chemicalsystem_generator/component_checks.py ================================================ from gufe import ChemicalSystem from openfe.setup.chemicalsystem_generator import RFEComponentLabels # Boolean Test logic lambdas: def ligandC_in_chem_sys(chemical_system: ChemicalSystem) -> bool: return RFEComponentLabels.LIGAND in chemical_system.components def solventC_in_chem_sys(chemical_system: ChemicalSystem) -> bool: return RFEComponentLabels.SOLVENT in chemical_system.components def proteinC_in_chem_sys(chemical_system: ChemicalSystem) -> bool: return RFEComponentLabels.PROTEIN in chemical_system.components def cofactorC_in_chem_sys(chemical_system: ChemicalSystem) -> bool: # cofactors are numbered from 1 return f"{RFEComponentLabels.COFACTOR.value}1" in chemical_system.components ================================================ FILE: src/openfe/tests/setup/chemicalsystem_generator/test_easy_chemicalsystem_generator.py ================================================ # This code is part of OpenFE and is licensed under the MIT license. # For details, see https://github.com/OpenFreeEnergy/openfe import pytest from gufe import ChemicalSystem, SolventComponent from rdkit import Chem from openfe.setup.chemicalsystem_generator.easy_chemicalsystem_generator import ( EasyChemicalSystemGenerator, ) from ...conftest import T4_protein_component from .component_checks import ( cofactorC_in_chem_sys, ligandC_in_chem_sys, proteinC_in_chem_sys, solventC_in_chem_sys, ) def test_easy_chemical_system_generator_init(T4_protein_component): chem_sys_generator = EasyChemicalSystemGenerator(do_vacuum=True) chem_sys_generator = EasyChemicalSystemGenerator(solvent=SolventComponent()) chem_sys_generator = EasyChemicalSystemGenerator( solvent=SolventComponent(), protein=T4_protein_component ) chem_sys_generator = EasyChemicalSystemGenerator( solvent=SolventComponent(), protein=T4_protein_component, do_vacuum=True ) with pytest.raises( ValueError, match="Chemical system generator is unable to generate any chemical systems with neither protein nor solvent nor do_vacuum", ): chem_sys_generator = EasyChemicalSystemGenerator() def test_build_vacuum_chemical_system(ethane): chem_sys_generator = EasyChemicalSystemGenerator(do_vacuum=True) chem_sys = next(chem_sys_generator(ethane)) assert chem_sys is not None assert isinstance(chem_sys, ChemicalSystem) assert not proteinC_in_chem_sys(chem_sys) assert not solventC_in_chem_sys(chem_sys) assert ligandC_in_chem_sys(chem_sys) def test_build_solvent_chemical_system(ethane): chem_sys_generator = EasyChemicalSystemGenerator(solvent=SolventComponent()) chem_sys = next(chem_sys_generator(ethane)) assert chem_sys is not None assert isinstance(chem_sys, ChemicalSystem) assert not proteinC_in_chem_sys(chem_sys) assert solventC_in_chem_sys(chem_sys) assert ligandC_in_chem_sys(chem_sys) def test_build_protein_chemical_system(ethane, T4_protein_component): chem_sys_generator = EasyChemicalSystemGenerator( protein=T4_protein_component, ) chem_sys = next(chem_sys_generator(ethane)) assert chem_sys is not None assert isinstance(chem_sys, ChemicalSystem) assert proteinC_in_chem_sys(chem_sys) assert not solventC_in_chem_sys(chem_sys) assert ligandC_in_chem_sys(chem_sys) assert not cofactorC_in_chem_sys(chem_sys) def test_build_cofactor_chemical_system(eg5_cofactor, eg5_ligands, eg5_protein): chem_sys_generator = EasyChemicalSystemGenerator(cofactors=[eg5_cofactor], protein=eg5_protein) chem_sys = next(chem_sys_generator(eg5_ligands[0])) assert chem_sys is not None assert isinstance(chem_sys, ChemicalSystem) assert proteinC_in_chem_sys(chem_sys) assert not solventC_in_chem_sys(chem_sys) assert ligandC_in_chem_sys(chem_sys) assert cofactorC_in_chem_sys(chem_sys) def test_build_hydr_scenario_chemical_systems(ethane): chem_sys_generator = EasyChemicalSystemGenerator(do_vacuum=True, solvent=SolventComponent()) chem_sys_gen = chem_sys_generator(ethane) chem_syss = [chem_sys for chem_sys in chem_sys_gen] assert len(chem_syss) == 2 assert all([isinstance(chem_sys, ChemicalSystem) for chem_sys in chem_syss]) assert [proteinC_in_chem_sys(chem_sys) for chem_sys in chem_syss] == [False, False] assert [solventC_in_chem_sys(chem_sys) for chem_sys in chem_syss] == [False, True] assert [ligandC_in_chem_sys(chem_sys) for chem_sys in chem_syss] == [True, True] def test_build_binding_scenario_chemical_systems(ethane, T4_protein_component): chem_sys_generator = EasyChemicalSystemGenerator( solvent=SolventComponent(), protein=T4_protein_component, ) chem_sys_gen = chem_sys_generator(ethane) chem_syss = [chem_sys for chem_sys in chem_sys_gen] assert len(chem_syss) == 2 assert all([isinstance(chem_sys, ChemicalSystem) for chem_sys in chem_syss]) assert [proteinC_in_chem_sys(chem_sys) for chem_sys in chem_syss] == [False, True] assert [solventC_in_chem_sys(chem_sys) for chem_sys in chem_syss] == [True, True] assert [ligandC_in_chem_sys(chem_sys) for chem_sys in chem_syss] == [True, True] def test_build_hbinding_scenario_chemical_systems(ethane, T4_protein_component): chem_sys_generator = EasyChemicalSystemGenerator( do_vacuum=True, solvent=SolventComponent(), protein=T4_protein_component, ) chem_sys_gen = chem_sys_generator(ethane) chem_syss = [chem_sys for chem_sys in chem_sys_gen] assert len(chem_syss) == 3 assert all([isinstance(chem_sys, ChemicalSystem) for chem_sys in chem_syss]) assert [proteinC_in_chem_sys(chem_sys) for chem_sys in chem_syss] == [False, False, True] assert [solventC_in_chem_sys(chem_sys) for chem_sys in chem_syss] == [False, True, True] assert [ligandC_in_chem_sys(chem_sys) for chem_sys in chem_syss] == [True, True, True] ================================================ FILE: src/openfe/tests/setup/test_network_planning.py ================================================ # This code is part of OpenFE and is licensed under the MIT license. # For details, see https://github.com/OpenFreeEnergy/openfe from typing import Callable import pytest import openfe from ..conftest import mol_from_smiles class BadMapper(openfe.setup.atom_mapping.LigandAtomMapper): @classmethod def _defaults(cls): return {} def _to_dict(self): return {} @classmethod def _from_dict(cls, d): return cls() def _mappings_generator(self, molA, molB): yield {0: 0} @pytest.fixture() def toluene_vs_others(atom_mapping_basic_test_files): central_ligand_name = "toluene" others = [ v for (k, v) in atom_mapping_basic_test_files.items() if k != central_ligand_name ] # fmt: skip toluene = atom_mapping_basic_test_files[central_ligand_name] return toluene, others @pytest.fixture() def simple_scorer() -> Callable: def _scorer(mapping) -> float: "Returns a score proportional to the length of the mapping, normalized to be in [0,1]" return 1 - (1 / len(mapping.componentA_to_componentB)) return _scorer @pytest.fixture() def deterministic_toluene_mst_scorer() -> Callable: def _scorer(mapping) -> float: """These scores give the same mst or rmst every time for the toluene_vs_others dataset.""" scores = { # MST edges ("1,3,7-trimethylnaphthalene", "2,6-dimethylnaphthalene"): 0.3, ("1-butyl-4-methylbenzene", "2-methyl-6-propylnaphthalene"): 0.3, ("2,6-dimethylnaphthalene", "2-methyl-6-propylnaphthalene"): 0.3, ("2,6-dimethylnaphthalene", "2-methylnaphthalene"): 0.3, ("2,6-dimethylnaphthalene", "2-naftanol"): 0.3, ("2,6-dimethylnaphthalene", "methylcyclohexane"): 0.3, ("2,6-dimethylnaphthalene", "toluene"): 0.3, # MST redundant edges ("1,3,7-trimethylnaphthalene", "2-methyl-6-propylnaphthalene"): 0.2, ("1-butyl-4-methylbenzene", "2,6-dimethylnaphthalene"): 0.2, ("1-butyl-4-methylbenzene", "toluene"): 0.2, ("2-methyl-6-propylnaphthalene", "2-methylnaphthalene"): 0.2, ("2-methylnaphthalene", "2-naftanol"): 0.2, ("2-methylnaphthalene", "methylcyclohexane"): 0.2, ("2-methylnaphthalene", "toluene"): 0.2, } return scores.get((mapping.componentA.name, mapping.componentB.name), 0.1) return _scorer @pytest.fixture() def deterministic_minimal_spanning_network( toluene_vs_others, lomap_old_mapper, deterministic_toluene_mst_scorer ): # TODO: I'm not convinced this needs to be its own fixture toluene, others = toluene_vs_others scorer = deterministic_toluene_mst_scorer network = openfe.setup.ligand_network_planning.generate_minimal_spanning_network( ligands=others + [toluene], mappers=lomap_old_mapper, scorer=scorer, ) return network @pytest.fixture() def deterministic_minimal_redundant_network( toluene_vs_others, lomap_old_mapper, deterministic_toluene_mst_scorer ): # TODO: I'm not convinced this needs to be its own fixture toluene, others = toluene_vs_others scorer = deterministic_toluene_mst_scorer network = openfe.setup.ligand_network_planning.generate_minimal_redundant_network( ligands=others + [toluene], mappers=lomap_old_mapper, scorer=scorer, mst_num=2, ) return network class TestRadialNetworkGenerator: @pytest.mark.parametrize("as_list", [False, True]) def test_radial_network( self, toluene_vs_others, as_list, lomap_old_mapper, ): toluene, others = toluene_vs_others central_ligand_name = "toluene" mapper = lomap_old_mapper if as_list: mapper = [mapper] network = openfe.setup.ligand_network_planning.generate_radial_network( ligands=others, central_ligand=toluene, mappers=mapper, scorer=None, ) expected_names = set([c.name for c in others] + [central_ligand_name]) # couple sanity checks assert len(network.nodes) == len(expected_names) assert len(network.edges) == len(expected_names) - 1 # check that all ligands are present, i.e. we included everyone ligands_in_network = {mol.name for mol in network.nodes} assert ligands_in_network == expected_names # check that every edge contains the central ligand as a node assert all( (central_ligand_name in {mapping.componentA.name, mapping.componentB.name}) for mapping in network.edges ) @pytest.mark.parametrize("central_ligand_arg", [0, "toluene"]) def test_radial_network_central_ligand_int_str( self, toluene_vs_others, central_ligand_arg, lomap_old_mapper, ): """check that passing either an integer or string to indicate the central ligand works""" toluene, others = toluene_vs_others ligands = [toluene] + others network = openfe.setup.ligand_network_planning.generate_radial_network( ligands=ligands, central_ligand=central_ligand_arg, mappers=lomap_old_mapper, scorer=None, ) central_ligand_name = "toluene" expected_names = set([c.name for c in others] + [central_ligand_name]) # couple sanity checks assert len(network.nodes) == len(expected_names) assert len(network.edges) == len(expected_names) - 1 # check that all ligands are present, i.e. we included everyone ligands_in_network = {mol.name for mol in network.nodes} assert ligands_in_network == expected_names # check that every edge contains the central ligand as a node assert all( (central_ligand_name in {mapping.componentA.name, mapping.componentB.name}) for mapping in network.edges ) def test_radial_network_bad_name(self, toluene_vs_others, lomap_old_mapper): """Error if the central ligand requested is not present.""" toluene, others = toluene_vs_others ligands = [toluene] + others with pytest.raises(ValueError, match="No ligand called 'unobtainium"): _ = openfe.setup.ligand_network_planning.generate_radial_network( ligands=ligands, central_ligand="unobtainium", mappers=lomap_old_mapper, scorer=None, ) def test_radial_network_multiple_str(self, toluene_vs_others, lomap_old_mapper): """Error if more than one ligand has the name passed to 'central_ligand'.""" toluene, others = toluene_vs_others ligands = [toluene, toluene] + others with pytest.raises(ValueError, match="Multiple ligands called"): _ = openfe.setup.ligand_network_planning.generate_radial_network( ligands=ligands, central_ligand="toluene", mappers=lomap_old_mapper, scorer=None, ) def test_radial_network_index_error(self, toluene_vs_others, lomap_old_mapper): """Throw a helpful error if the index value passed to 'central_ligand' is out-of-bounds.""" toluene, others = toluene_vs_others ligands = [toluene] + others with pytest.raises(ValueError, match="index '2077' out of bounds, there are 8 ligands"): _ = openfe.setup.ligand_network_planning.generate_radial_network( ligands=ligands, central_ligand=2077, mappers=lomap_old_mapper, scorer=None, ) def test_radial_network_self_central(self, toluene_vs_others, lomap_old_mapper): """(issue #544) If the central ligand is included in "ligands", there shouldn't be a self-edge to the central ligand, and a warning should be raised. """ toluene, others = toluene_vs_others ligands = [toluene] + others with pytest.warns( UserWarning, match="The central component 'toluene' is present in the list of components", ): network = openfe.setup.ligand_network_planning.generate_radial_network( ligands=ligands, central_ligand=toluene, mappers=lomap_old_mapper, scorer=None, ) # make sure there's no self-edge for the central ligand (toluene) assert ("toluene", "toluene") not in { (e.componentA.name, e.componentB.name) for e in network.edges } assert len(network.edges) == len(ligands) - 1 # explicitly check to make sure there is no toluene self-edge name_pairs = [(c.componentA, c.componentB) for c in network.edges] assert ("toluene", "toluene") not in name_pairs def test_radial_network_with_scorer(self, toluene_vs_others, lomap_old_mapper, simple_scorer): """Test that the scorer chooses the mapper with the best score (in this case, the LOMAP mapper).""" toluene, others = toluene_vs_others mappers = [BadMapper(), lomap_old_mapper] scorer = simple_scorer network = openfe.setup.ligand_network_planning.generate_radial_network( ligands=others, central_ligand=toluene, mappers=mappers, scorer=scorer, ) expected_names = set([c.name for c in others] + ["toluene"]) # couple sanity checks assert len(network.nodes) == len(expected_names) assert len(network.edges) == len(expected_names) - 1 # check that all ligands are present, i.e. we included everyone ligands_in_network = {mol.name for mol in network.nodes} assert ligands_in_network == expected_names for edge in network.edges: # make sure we didn't take the bad mapper, which would always be a length of 1 ({0:0}) assert len(edge.componentA_to_componentB) > 1 assert "score" in edge.annotations assert edge.annotations["score"] == 1 - 1 / len(edge.componentA_to_componentB) def test_radial_network_multiple_mappers_no_scorer(self, toluene_vs_others, lomap_old_mapper): toluene, others = toluene_vs_others mappers = [BadMapper(), lomap_old_mapper] network = openfe.setup.ligand_network_planning.generate_radial_network( ligands=others, central_ligand=toluene, mappers=mappers, ) expected_names = set([c.name for c in others] + ["toluene"]) # couple sanity checks assert len(network.nodes) == len(expected_names) assert len(network.edges) == len(expected_names) - 1 # check that all ligands are present, i.e. we included everyone ligands_in_network = {mol.name for mol in network.nodes} assert ligands_in_network == expected_names for edge in network.edges: # we should always take the first valid mapper (BadMapper) when there is no scorer. assert edge.componentA_to_componentB == {0: 0} assert "score" not in edge.annotations def test_radial_network_no_mapping_failure(self, toluene_vs_others, lomap_old_mapper): """Error if any node does not have a mapping to the central component.""" toluene, others = toluene_vs_others # lomap cannot make a mapping to nimrod, and will return nothing for the (toluene, nimrod) pair nimrod = openfe.SmallMoleculeComponent(mol_from_smiles("N"), name="nimrod") err_str = r"No mapping found between the central ligand \('toluene'\) and the following node\(s\): \['nimrod'\]" with pytest.raises(RuntimeError, match=err_str): _ = openfe.setup.ligand_network_planning.generate_radial_network( ligands=others + [nimrod], central_ligand=toluene, mappers=[lomap_old_mapper], scorer=None, ) @pytest.mark.parametrize("with_progress", [True, False]) @pytest.mark.parametrize("with_scorer", [True, False]) @pytest.mark.parametrize("extra_mapper", [True, False]) def test_generate_maximal_network( toluene_vs_others, with_progress, with_scorer, extra_mapper, lomap_old_mapper, simple_scorer, ): toluene, others = toluene_vs_others if extra_mapper: mappers = [lomap_old_mapper, BadMapper()] else: mappers = lomap_old_mapper scorer = simple_scorer if with_scorer else None network = openfe.setup.ligand_network_planning.generate_maximal_network( ligands=others + [toluene], mappers=mappers, scorer=scorer, progress=with_progress, ) expected_names = set([c.name for c in others] + ["toluene"]) assert len(network.nodes) == len(expected_names) # check that all ligands are present, i.e. we included everyone ligands_in_network = {mol.name for mol in network.nodes} assert ligands_in_network == expected_names edge_count = len(others) * (len(others) + 1) / 2 assert len(network.edges) == edge_count if with_scorer: for edge in network.edges: score = edge.annotations["score"] assert score == 1 - 1 / len(edge.componentA_to_componentB) else: for edge in network.edges: assert "score" not in edge.annotations assert "score" not in edge.annotations class TestMinimalSpanningNetworkGenerator: @pytest.mark.parametrize("multi_mappers", [False, True]) def test_minimal_spanning_network( self, toluene_vs_others, multi_mappers, lomap_old_mapper, simple_scorer ): toluene, others = toluene_vs_others ligands = [toluene] + others if multi_mappers: mappers = [BadMapper(), lomap_old_mapper] else: mappers = lomap_old_mapper scorer = simple_scorer network = openfe.ligand_network_planning.generate_minimal_spanning_network( ligands=ligands, mappers=mappers, scorer=scorer, ) expected_names = {c.name for c in ligands} # couple sanity checks assert len(network.nodes) == len(expected_names) assert len(network.edges) == len(expected_names) - 1 assert network.is_connected() # check that all ligands are present, i.e. we included everyone ligands_in_network = {mol.name for mol in network.nodes} assert ligands_in_network == expected_names for edge in network.edges: # make sure we didn't take the bad mapper, which would always be a length of 1 ({0:0}) assert len(edge.componentA_to_componentB) > 1 assert "score" in edge.annotations assert edge.annotations["score"] == 1 - 1 / len(edge.componentA_to_componentB) def test_minimal_spanning_network_no_scorer_error(self, toluene_vs_others, lomap_old_mapper): """Expect a KeyError if no scorer is passed.""" # NOTE: I'm not making this error handling prettier until the konnektor integration toluene, others = toluene_vs_others ligands = [toluene] + others with pytest.raises(KeyError, match="score"): _ = openfe.ligand_network_planning.generate_minimal_spanning_network( ligands=ligands, mappers=lomap_old_mapper, scorer=None, ) def test_minimal_spanning_network_connectedness(self, deterministic_minimal_spanning_network): # makes sure we don't have duplicate edges? found_pairs = set() for edge in deterministic_minimal_spanning_network.edges: pair = frozenset([edge.componentA, edge.componentB]) assert pair not in found_pairs found_pairs.add(pair) assert deterministic_minimal_spanning_network.is_connected() def test_minimal_spanning_network_regression(self, deterministic_minimal_spanning_network): """issue #244, this was previously giving non-reproducible (yet valid) networks when scores were tied.""" edge_names = { (e.componentA.name, e.componentB.name) for e in deterministic_minimal_spanning_network.edges } expected_edge_names = { ("1,3,7-trimethylnaphthalene", "2,6-dimethylnaphthalene"), ("1-butyl-4-methylbenzene", "2-methyl-6-propylnaphthalene"), ("2,6-dimethylnaphthalene", "2-methyl-6-propylnaphthalene"), ("2,6-dimethylnaphthalene", "2-methylnaphthalene"), ("2,6-dimethylnaphthalene", "2-naftanol"), ("2,6-dimethylnaphthalene", "methylcyclohexane"), ("2,6-dimethylnaphthalene", "toluene"), } assert len(deterministic_minimal_spanning_network.nodes) == 8 assert len(edge_names) == len(expected_edge_names) assert edge_names == expected_edge_names def test_minimal_spanning_network_unreachable( self, toluene_vs_others, lomap_old_mapper, simple_scorer ): toluene, others = toluene_vs_others nimrod = openfe.SmallMoleculeComponent(mol_from_smiles("N"), name="nimrod") scorer = simple_scorer with pytest.raises( RuntimeError, match=r"Unable to create edges for the following nodes: \[SmallMoleculeComponent\(name=nimrod\)\]", ): _ = openfe.setup.ligand_network_planning.generate_minimal_spanning_network( ligands=others + [toluene, nimrod], mappers=[lomap_old_mapper], scorer=scorer, ) class TestMinimalRedundantNetworkGenerator: def test_minimal_redundant_network( self, deterministic_minimal_redundant_network, toluene_vs_others ): toluene, others = toluene_vs_others ligands = [toluene] + others expected_names = {c.name for c in ligands} # check that all ligands are present, i.e. we included everyone assert len(deterministic_minimal_redundant_network.nodes) == len(ligands) ligands_in_network = {mol.name for mol in deterministic_minimal_redundant_network.nodes} assert ligands_in_network == expected_names # we expect double the number of edges of an mst assert len(deterministic_minimal_redundant_network.edges) == 2 * (len(ligands) - 1) for edge in deterministic_minimal_redundant_network.edges: # lomap should find something assert edge.componentA_to_componentB != {0: 0} def test_minimal_redundant_network_connectedness(self, deterministic_minimal_redundant_network): # makes sure we don't have duplicate edges? found_pairs = set() for edge in deterministic_minimal_redundant_network.edges: pair = frozenset([edge.componentA, edge.componentB]) assert pair not in found_pairs found_pairs.add(pair) assert deterministic_minimal_redundant_network.is_connected() def test_redundant_vs_spanning_network( self, toluene_vs_others, lomap_old_mapper, deterministic_toluene_mst_scorer, deterministic_minimal_spanning_network, ): """when setting minimal redundant network to only take one MST, it should be equivalent to the base MST.""" toluene, others = toluene_vs_others scorer = deterministic_toluene_mst_scorer minimal_redundant_network = ( openfe.setup.ligand_network_planning.generate_minimal_redundant_network( ligands=others + [toluene], mappers=lomap_old_mapper, scorer=scorer, mst_num=1, ) ) assert deterministic_minimal_spanning_network.edges == minimal_redundant_network.edges def test_minimal_redundant_network_edges(self, deterministic_minimal_redundant_network): """issue #244, this was previously giving non-reproducible (yet valid) networks when scores were tied.""" edge_names = { (e.componentA.name, e.componentB.name) for e in deterministic_minimal_redundant_network.edges } expected_names = { ("1,3,7-trimethylnaphthalene", "2,6-dimethylnaphthalene"), ("1,3,7-trimethylnaphthalene", "2-methyl-6-propylnaphthalene"), ("1-butyl-4-methylbenzene", "2,6-dimethylnaphthalene"), ("1-butyl-4-methylbenzene", "2-methyl-6-propylnaphthalene"), ("1-butyl-4-methylbenzene", "toluene"), ("2,6-dimethylnaphthalene", "2-methyl-6-propylnaphthalene"), ("2,6-dimethylnaphthalene", "2-methylnaphthalene"), ("2,6-dimethylnaphthalene", "2-naftanol"), ("2,6-dimethylnaphthalene", "methylcyclohexane"), ("2,6-dimethylnaphthalene", "toluene"), ("2-methyl-6-propylnaphthalene", "2-methylnaphthalene"), ("2-methylnaphthalene", "2-naftanol"), ("2-methylnaphthalene", "methylcyclohexane"), ("2-methylnaphthalene", "toluene"), } assert len(edge_names) == len(expected_names) assert edge_names == expected_names def test_minimal_redundant_network_redundant(self, deterministic_minimal_redundant_network): """test that each node is connected to 2 edges""" network = deterministic_minimal_redundant_network for node in network.nodes: assert len(network.graph.in_edges(node)) + len(network.graph.out_edges(node)) >= 2 def test_minimal_redundant_network_unreachable( self, toluene_vs_others, lomap_old_mapper, simple_scorer ): toluene, others = toluene_vs_others nimrod = openfe.SmallMoleculeComponent(mol_from_smiles("N"), name="nimrod") scorer = simple_scorer err_str = r"ERROR: Unable to create edges for the following nodes: \[SmallMoleculeComponent\(name=nimrod\)\]" with pytest.raises(RuntimeError, match=err_str): _ = openfe.setup.ligand_network_planning.generate_minimal_spanning_network( ligands=others + [toluene, nimrod], mappers=[lomap_old_mapper], scorer=scorer, ) class TestGenerateNetworkFromNames: def test_generate_network_from_names(self, atom_mapping_basic_test_files, lomap_old_mapper): ligands = list(atom_mapping_basic_test_files.values()) requested_names = [ ("toluene", "2-naftanol"), ("2-methylnaphthalene", "2-naftanol"), ] network = openfe.setup.ligand_network_planning.generate_network_from_names( ligands=ligands, names=requested_names, mapper=lomap_old_mapper, ) assert len(network.nodes) == len(ligands) assert len(network.edges) == 2 expected_node_names = {c.name for c in ligands} actual_node_names = {n.name for n in network.nodes} assert actual_node_names == expected_node_names actual_edges = {(e.componentA.name, e.componentB.name) for e in network.edges} assert set(requested_names) == actual_edges def test_generate_network_from_names_bad_name_error( self, atom_mapping_basic_test_files, lomap_old_mapper ): ligands = list(atom_mapping_basic_test_files.values()) requested = [ ("hank", "2-naftanol"), ("2-methylnaphthalene", "2-naftanol"), ] with pytest.raises(KeyError, match=r"Invalid name\(s\) requested \['hank'\]."): _ = openfe.setup.ligand_network_planning.generate_network_from_names( ligands=ligands, names=requested, mapper=lomap_old_mapper, ) def test_generate_network_from_names_duplicate_name( self, atom_mapping_basic_test_files, lomap_old_mapper ): ligands = list(atom_mapping_basic_test_files.values()) ligands = ligands + [ligands[0]] requested = [ ("toluene", "2-naftanol"), ("2-methylnaphthalene", "2-naftanol"), ] with pytest.raises(ValueError, match=r"Duplicate names: \['1,3,7-trimethylnaphthalene'\]"): _ = openfe.setup.ligand_network_planning.generate_network_from_names( ligands=ligands, names=requested, mapper=lomap_old_mapper, ) class TestNetworkFromIndices: def test_network_from_indices(self, atom_mapping_basic_test_files, lomap_old_mapper): ligands = list(atom_mapping_basic_test_files.values()) requested = [(0, 1), (2, 3)] network = openfe.setup.ligand_network_planning.generate_network_from_indices( ligands=ligands, indices=requested, mapper=lomap_old_mapper, ) assert len(network.nodes) == len(ligands) assert len(network.edges) == 2 edges = list(network.edges) expected_edges = {(ligands[0], ligands[1]), (ligands[2], ligands[3])} actual_edges = { (edges[0].componentA, edges[0].componentB), (edges[1].componentA, edges[1].componentB), } assert actual_edges == expected_edges def test_network_from_indices_indexerror(self, atom_mapping_basic_test_files, lomap_old_mapper): ligands = list(atom_mapping_basic_test_files.values()) requested = [(20, 1), (2, 3)] with pytest.raises(IndexError, match="Invalid ligand index"): _ = openfe.setup.ligand_network_planning.generate_network_from_indices( ligands=ligands, indices=requested, mapper=lomap_old_mapper, ) def test_network_from_indices_disconnected_warning( self, atom_mapping_basic_test_files, lomap_old_mapper ): ligands = list(atom_mapping_basic_test_files.values()) requested = [(0, 1), (1, 2)] with pytest.warns(UserWarning): _ = openfe.setup.ligand_network_planning.generate_network_from_indices( ligands=ligands, indices=requested, mapper=lomap_old_mapper, ) @pytest.mark.parametrize( "file_fixture, loader", [ ["orion_network", openfe.setup.ligand_network_planning.load_orion_network], ["fepplus_network", openfe.setup.ligand_network_planning.load_fepplus_network], ], ) def test_network_from_external(file_fixture, loader, request, benzene_modifications): network_file = request.getfixturevalue(file_fixture) network = loader( ligands=[lig for lig in benzene_modifications.values()], mapper=openfe.LomapAtomMapper(), network_file=network_file, ) expected_edges = { (benzene_modifications["benzene"], benzene_modifications["toluene"]), (benzene_modifications["benzene"], benzene_modifications["phenol"]), (benzene_modifications["benzene"], benzene_modifications["benzonitrile"]), (benzene_modifications["benzene"], benzene_modifications["anisole"]), (benzene_modifications["benzene"], benzene_modifications["styrene"]), (benzene_modifications["benzene"], benzene_modifications["benzaldehyde"]), } actual_edges = {(e.componentA, e.componentB) for e in list(network.edges)} assert len(network.nodes) == 7 assert len(network.edges) == 6 assert actual_edges == expected_edges @pytest.mark.parametrize( "file_fixture, loader", [ ["orion_network", openfe.setup.ligand_network_planning.load_orion_network], ["fepplus_network", openfe.setup.ligand_network_planning.load_fepplus_network], ], ) def test_network_from_external_unknown_edge(file_fixture, loader, request, benzene_modifications): network_file = request.getfixturevalue(file_fixture) ligands = [lig for lig in benzene_modifications.values() if lig.name != "phenol"] with pytest.raises(KeyError, match="Invalid name"): _ = loader( ligands=ligands, mapper=openfe.LomapAtomMapper(), network_file=network_file, ) BAD_ORION_NETWORK = """\ # Total number of edges: 6 # ------------------------ benzene >>> toluene benzene >> phenol benzene >> benzonitrile benzene >> anisole benzene >> styrene benzene >> benzaldehyde """ def test_bad_orion_network(benzene_modifications, tmp_path): with open(tmp_path / "bad_orion_net.dat", "w") as f: f.write(BAD_ORION_NETWORK) with pytest.raises(KeyError, match="line does not match"): _ = openfe.setup.ligand_network_planning.load_orion_network( ligands=[lig for lig in benzene_modifications.values()], mapper=openfe.LomapAtomMapper(), network_file=tmp_path / "bad_orion_net.dat", ) BAD_EDGES = """\ 1c91235:9c91235 benzene -> toluene 1c91235:7876633 benzene -> phenol 1c91235:2a51f95 benzene -> benzonitrile 1c91235:efja0bc benzene -> anisole 1c91235:7877722 benzene -> styrene 1c91235:99930cd benzene -> benzaldehyde """ def test_bad_edges_network(benzene_modifications, tmp_path): with open(tmp_path / "bad_edges.edges", "w") as f: f.write(BAD_EDGES) with pytest.raises(KeyError, match="line does not match"): _ = openfe.setup.ligand_network_planning.load_fepplus_network( ligands=[lig for lig in benzene_modifications.values()], mapper=openfe.LomapAtomMapper(), network_file=tmp_path / "bad_edges.edges", ) ================================================ FILE: src/openfe/tests/storage/__init__.py ================================================ ================================================ FILE: src/openfe/tests/storage/conftest.py ================================================ import gufe import pytest from gufe import ChemicalSystem, SolventComponent from gufe.tests.test_protocol import DummyProtocol from openff.units import unit @pytest.fixture def solv_comp(): yield SolventComponent(positive_ion="K", negative_ion="Cl", ion_concentration=0.0 * unit.molar) @pytest.fixture def solvated_complex(T4_protein_component, benzene_transforms, solv_comp): return ChemicalSystem( { "ligand": benzene_transforms["toluene"], "protein": T4_protein_component, "solvent": solv_comp, } ) @pytest.fixture def solvated_ligand(benzene_transforms, solv_comp): return ChemicalSystem( { "ligand": benzene_transforms["toluene"], "solvent": solv_comp, } ) @pytest.fixture def absolute_transformation(solvated_ligand, solvated_complex): return gufe.Transformation( solvated_ligand, solvated_complex, protocol=DummyProtocol(settings=DummyProtocol.default_settings()), mapping=None, ) @pytest.fixture def complex_equilibrium(solvated_complex): return gufe.NonTransformation( solvated_complex, protocol=DummyProtocol(settings=DummyProtocol.default_settings()), ) @pytest.fixture def benzene_variants_star_map(benzene_transforms, solv_comp, T4_protein_component): variants = ["toluene", "phenol", "benzonitrile", "anisole", "benzaldehyde", "styrene"] # define the solvent chemical systems and transformations between # benzene and the others solvated_ligands = {} solvated_ligand_transformations = {} solvated_ligands["benzene"] = ChemicalSystem( { "solvent": solv_comp, "ligand": benzene_transforms["benzene"], }, name="benzene-solvent", ) for ligand in variants: solvated_ligands[ligand] = ChemicalSystem( { "solvent": solv_comp, "ligand": benzene_transforms[ligand], }, name=f"{ligand}-solvent", ) solvated_ligand_transformations[("benzene", ligand)] = gufe.Transformation( solvated_ligands["benzene"], solvated_ligands[ligand], protocol=DummyProtocol(settings=DummyProtocol.default_settings()), mapping=None, ) # define the complex chemical systems and transformations between # benzene and the others solvated_complexes = {} solvated_complex_transformations = {} solvated_complexes["benzene"] = gufe.ChemicalSystem( { "protein": T4_protein_component, "solvent": solv_comp, "ligand": benzene_transforms["benzene"], }, name="benzene-complex", ) for ligand in variants: solvated_complexes[ligand] = gufe.ChemicalSystem( { "protein": T4_protein_component, "solvent": solv_comp, "ligand": benzene_transforms[ligand], }, name=f"{ligand}-complex", ) solvated_complex_transformations[("benzene", ligand)] = gufe.Transformation( solvated_complexes["benzene"], solvated_complexes[ligand], protocol=DummyProtocol(settings=DummyProtocol.default_settings()), mapping=None, ) return gufe.AlchemicalNetwork( list(solvated_ligand_transformations.values()) + list(solvated_complex_transformations.values()) ) ================================================ FILE: src/openfe/tests/storage/test_metadatastore.py ================================================ import json import pathlib import pytest from gufe.storage.errors import ChangedExternalResourceError, MissingExternalResourceError from gufe.storage.externalresource import FileStorage from gufe.storage.externalresource.base import Metadata from openfe.storage.metadatastore import JSONMetadataStore, PerFileJSONMetadataStore @pytest.fixture def json_metadata(tmp_path): metadata_dict = {"path/to/foo.txt": {"md5": "bar"}} external_store = FileStorage(tmp_path) with open(tmp_path / "metadata.json", mode="wb") as f: f.write(json.dumps(metadata_dict).encode("utf-8")) json_metadata = JSONMetadataStore(external_store) return json_metadata @pytest.fixture def per_file_metadata(tmp_path): metadata_dict = {"path": "path/to/foo.txt", "metadata": {"md5": "bar"}} metadata_loc = "metadata/path/to/foo.txt.json" external_store = FileStorage(tmp_path) metadata_path = tmp_path / pathlib.Path(metadata_loc) metadata_path.parent.mkdir(parents=True, exist_ok=True) with open(metadata_path, mode="wb") as f: f.write(json.dumps(metadata_dict).encode("utf-8")) per_file_metadata = PerFileJSONMetadataStore(external_store) return per_file_metadata class MetadataTests: """Mixin with a few tests for any subclass of MetadataStore""" def test_store_metadata(self, metadata): raise NotImplementedError() def test_load_all_metadata(self): raise NotImplementedError("This should call self._test_load_all_metadata") def test_delete(self): raise NotImplementedError("This should call self._test_delete") def _test_load_all_metadata(self, metadata): expected = {"path/to/foo.txt": Metadata(md5="bar")} metadata._metadata_cache = {} loaded = metadata.load_all_metadata() assert loaded == expected def _test_delete(self, metadata): assert "path/to/foo.txt" in metadata assert len(metadata) == 1 del metadata["path/to/foo.txt"] assert "path/to/foo.txt" not in metadata assert len(metadata) == 0 def _test_iter(self, metadata): assert list(metadata) == ["path/to/foo.txt"] def _test_len(self, metadata): assert len(metadata) == 1 def _test_getitem(self, metadata): assert metadata["path/to/foo.txt"] == Metadata(md5="bar") class TestJSONMetadataStore(MetadataTests): def test_store_metadata(self, json_metadata): meta = Metadata(md5="other") json_metadata.store_metadata("path/to/other.txt", meta) base_path = json_metadata.external_store.root_dir metadata_json = base_path / "metadata.json" assert metadata_json.exists() with open(metadata_json, mode="r") as f: metadata_dict = json.load(f) metadata = {key: Metadata(**val) for key, val in metadata_dict.items()} assert metadata == json_metadata._metadata_cache assert json_metadata["path/to/other.txt"] == meta assert len(metadata) == 2 def test_load_all_metadata(self, json_metadata): self._test_load_all_metadata(json_metadata) def test_load_all_metadata_nofile(self, tmp_path): json_metadata = JSONMetadataStore(FileStorage(tmp_path)) # implicitly called on init anyway assert json_metadata._metadata_cache == {} # but we also call explicitly assert json_metadata.load_all_metadata() == {} def test_delete(self, json_metadata): self._test_delete(json_metadata) def test_iter(self, json_metadata): self._test_iter(json_metadata) def test_len(self, json_metadata): self._test_len(json_metadata) def test_getitem(self, json_metadata): self._test_getitem(json_metadata) class TestPerFileJSONMetadataStore(MetadataTests): def test_store_metadata(self, per_file_metadata): expected_loc = "metadata/path/to/other.txt.json" root = per_file_metadata.external_store.root_dir expected_path = root / expected_loc assert not expected_path.exists() meta = Metadata(md5="other") per_file_metadata.store_metadata("path/to/other.txt", meta) assert expected_path.exists() expected = {"path": "path/to/other.txt", "metadata": {"md5": "other"}} with open(expected_path, mode="r") as f: assert json.load(f) == expected def test_load_all_metadata(self, per_file_metadata): self._test_load_all_metadata(per_file_metadata) def test_delete(self, per_file_metadata): self._test_delete(per_file_metadata) # TODO: add additional test that the file is gone def test_iter(self, per_file_metadata): self._test_iter(per_file_metadata) def test_len(self, per_file_metadata): self._test_len(per_file_metadata) def test_getitem(self, per_file_metadata): self._test_getitem(per_file_metadata) def test_bad_metadata_contents(self, tmp_path): loc = tmp_path / "metadata/foo.txt.json" loc.parent.mkdir(parents=True, exist_ok=True) bad_dict = {"foo": "bar"} with open(loc, mode="wb") as f: f.write(json.dumps(bad_dict).encode("utf-8")) with pytest.raises(ChangedExternalResourceError, match="Bad metadata"): PerFileJSONMetadataStore(FileStorage(tmp_path)) ================================================ FILE: src/openfe/tests/storage/test_resultclient.py ================================================ import os from unittest import mock import pytest from gufe.storage.externalresource import MemoryStorage from gufe.tokenization import TOKENIZABLE_REGISTRY from openfe.storage.resultclient import ( CloneResult, ExtensionResult, ResultClient, TransformationResult, ) @pytest.fixture def result_client(): external = MemoryStorage() result_client = ResultClient(external) # store one file with contents "foo" result_client.result_server.store_bytes( "transformations/MAIN_TRANS/0/0/file.txt", "foo".encode("utf-8"), ) # create some empty files as well empty_files = [ "transformations/MAIN_TRANS/0/0/other.txt", "transformations/MAIN_TRANS/0/1/file.txt", "transformations/MAIN_TRANS/1/0/file.txt", "transformations/OTHER_TRANS/0/0/file.txt", "other_dir/file.txt", ] for file in empty_files: result_client.result_server.store_bytes(file, b"") # empty return result_client def _make_mock_transformation(hash_str): return mock.Mock( # TODO: fill this in so that it mocks out the digest we use ) def test_load_file(result_client): file_handler = result_client / "MAIN_TRANS" / "0" / 0 / "file.txt" with file_handler as f: assert f.read().decode("utf-8") == "foo" class _ResultContainerTest: @staticmethod def get_container(result_client): raise NotImplementedError() def _getitem_object(self, container): raise NotImplementedError() def test_iter(self, result_client): container = self.get_container(result_client) assert set(container) == set(self.expected_files) def _get_key(self, as_object, container): # TODO: this isn't working yet -- need an interface that allows me # to patch the hex digest that we'll be using if as_object: pytest.skip("Waiting on hex digest patching") obj = self._getitem_object(container) # next line uses some internal implementation key = obj if as_object else obj._path_component return key, obj @pytest.mark.parametrize("as_object", [True, False]) def test_getitem(self, as_object, result_client): container = self.get_container(result_client) key, obj = self._get_key(as_object, container) assert container[key] == obj @pytest.mark.parametrize("as_object", [True, False]) def test_div(self, as_object, result_client): container = self.get_container(result_client) key, obj = self._get_key(as_object, container) assert container / key == obj @pytest.mark.parametrize("load_with", ["div", "getitem"]) def test_caching(self, result_client, load_with): # used to test caching regardless of how first loaded was loaded container = self.get_container(result_client) key, obj = self._get_key(False, container) if load_with == "div": loaded = container / key elif load_with == "getitem": loaded = container[key] else: # -no-cov- raise RuntimeError(f"Bad input: can't load with '{load_with}'") assert loaded == obj assert loaded is not obj reloaded_div = container / key reloaded_getitem = container[key] assert loaded is reloaded_div assert reloaded_div is reloaded_getitem def test_load_stream(self, result_client): container = self.get_container(result_client) loc = "transformations/MAIN_TRANS/0/0/file.txt" with container.load_stream(loc) as f: assert f.read().decode("utf-8") == "foo" def test_load_bytes(self, result_client): container = self.get_container(result_client) loc = "transformations/MAIN_TRANS/0/0/file.txt" assert container.load_bytes(loc).decode("utf-8") == "foo" def test_path(self, result_client): container = self.get_container(result_client) assert container.path == self.expected_path def test_result_server(self, result_client): container = self.get_container(result_client) assert container.result_server == result_client.result_server class TestResultClient(_ResultContainerTest): expected_files = [ "transformations/MAIN_TRANS/0/0/file.txt", "transformations/MAIN_TRANS/0/0/other.txt", "transformations/MAIN_TRANS/0/1/file.txt", "transformations/MAIN_TRANS/1/0/file.txt", "transformations/OTHER_TRANS/0/0/file.txt", ] expected_path = "transformations" @staticmethod def get_container(result_client): return result_client def _getitem_object(self, container): return TransformationResult( parent=container, transformation=_make_mock_transformation("MAIN_TRANS"), ) def test_store_protocol_dag_result(self): pytest.skip("Not implemented yet") @staticmethod def _test_store_load_same_process(obj, store_func_name, load_func_name): store = MemoryStorage() client = ResultClient(store) store_func = getattr(client, store_func_name) load_func = getattr(client, load_func_name) assert store._data == {} store_func(obj) assert store._data != {} reloaded = load_func(obj.key) assert reloaded is obj @staticmethod def _test_store_load_different_process(obj, store_func_name, load_func_name): store = MemoryStorage() client = ResultClient(store) store_func = getattr(client, store_func_name) load_func = getattr(client, load_func_name) assert store._data == {} store_func(obj) assert store._data != {} # make it look like we have an empty cache, as if this was a # different process key = obj.key registry_dict = "gufe.tokenization.TOKENIZABLE_REGISTRY" with mock.patch.dict(registry_dict, {}, clear=True): reload = load_func(key) assert reload == obj assert reload is not obj @pytest.mark.parametrize( "fixture", ["absolute_transformation", "complex_equilibrium"], ) def test_store_load_transformation_same_process(self, request, fixture): transformation = request.getfixturevalue(fixture) self._test_store_load_same_process( transformation, "store_transformation", "load_transformation", ) @pytest.mark.parametrize( "fixture", ["absolute_transformation", "complex_equilibrium"], ) def test_store_load_transformation_different_process(self, request, fixture): transformation = request.getfixturevalue(fixture) self._test_store_load_different_process( transformation, "store_transformation", "load_transformation", ) @pytest.mark.parametrize("fixture", ["benzene_variants_star_map"]) def test_store_load_network_same_process(self, request, fixture): network = request.getfixturevalue(fixture) self._test_store_load_same_process(network, "store_network", "load_network") @pytest.mark.parametrize("fixture", ["benzene_variants_star_map"]) def test_store_load_network_different_process(self, request, fixture): network = request.getfixturevalue(fixture) self._test_store_load_different_process(network, "store_network", "load_network") def test_delete(self, result_client): file_to_delete = self.expected_files[0] storage = result_client.result_server.external_store assert storage.exists(file_to_delete) result_client.delete(file_to_delete) assert not storage.exists(file_to_delete) class TestTransformationResults(_ResultContainerTest): expected_files = [ "transformations/MAIN_TRANS/0/0/file.txt", "transformations/MAIN_TRANS/0/0/other.txt", "transformations/MAIN_TRANS/0/1/file.txt", "transformations/MAIN_TRANS/1/0/file.txt", ] expected_path = "transformations/MAIN_TRANS" @staticmethod def get_container(result_client): container = TransformationResult( parent=TestResultClient.get_container(result_client), transformation=_make_mock_transformation("MAIN_TRANS"), ) container._path_component = "MAIN_TRANS" return container def _getitem_object(self, container): return CloneResult(parent=container, clone=0) class TestCloneResults(_ResultContainerTest): expected_files = [ "transformations/MAIN_TRANS/0/0/file.txt", "transformations/MAIN_TRANS/0/0/other.txt", "transformations/MAIN_TRANS/0/1/file.txt", ] expected_path = "transformations/MAIN_TRANS/0" @staticmethod def get_container(result_client): return CloneResult( parent=TestTransformationResults.get_container(result_client), clone=0, ) def _getitem_object(self, container): return ExtensionResult(parent=container, extension=0) class TestExtensionResults(_ResultContainerTest): expected_files = [ "transformations/MAIN_TRANS/0/0/file.txt", "transformations/MAIN_TRANS/0/0/other.txt", ] expected_path = "transformations/MAIN_TRANS/0/0" @staticmethod def get_container(result_client): return ExtensionResult( parent=TestCloneResults.get_container(result_client), extension=0, ) def _get_key(self, as_object, container): if self.as_object: # -no-cov- raise RuntimeError("TestExtensionResults does not support as_object=True") path = "transformations/MAIN_TRANS/0/0/" fname = "file.txt" return fname, container.result_server.load_stream(path + fname) # things involving div and getitem need custom treatment def test_div(self, result_client): container = self.get_container(result_client) with container / "file.txt" as f: assert f.read().decode("utf-8") == "foo" def test_getitem(self, result_client): container = self.get_container(result_client) with container["file.txt"] as f: assert f.read().decode("utf-8") == "foo" def test_caching(self, result_client): # this one does not cache results; the cache should remain empty container = self.get_container(result_client) assert container._cache == {} from_div = container / "file.txt" assert container._cache == {} from_getitem = container["file.txt"] assert container._cache == {} ================================================ FILE: src/openfe/tests/storage/test_resultserver.py ================================================ import pathlib from unittest import mock import pytest from gufe.storage.errors import ChangedExternalResourceError, MissingExternalResourceError from gufe.storage.externalresource import FileStorage from gufe.storage.externalresource.base import Metadata from openfe.storage.metadatastore import JSONMetadataStore from openfe.storage.resultserver import ResultServer @pytest.fixture def result_server(tmp_path): external = FileStorage(tmp_path) metadata = JSONMetadataStore(external) result_server = ResultServer(external, metadata) result_server.store_bytes("path/to/foo.txt", "foo".encode("utf-8")) return result_server class TestResultServer: def test_store_bytes(self, result_server): # first check the thing stored during the fixture metadata_store = result_server.metadata_store foo_loc = "path/to/foo.txt" assert len(metadata_store) == 1 assert foo_loc in metadata_store assert result_server.external_store.exists(foo_loc) # also explicitly test storing here mock_hash = mock.Mock( return_value=mock.Mock( hexdigest=mock.Mock(return_value="deadbeef"), ) ) bar_loc = "path/to/bar.txt" with mock.patch("hashlib.md5", mock_hash): result_server.store_bytes(bar_loc, "bar".encode("utf-8")) assert len(metadata_store) == 2 assert bar_loc in metadata_store assert result_server.external_store.exists(bar_loc) assert metadata_store[bar_loc].to_dict() == {"md5": "deadbeef"} external = result_server.external_store with external.load_stream(bar_loc) as f: assert f.read().decode("utf-8") == "bar" def test_store_path(self, result_server, tmp_path): orig_file = tmp_path / ".hidden" / "bar.txt" orig_file.parent.mkdir(parents=True, exist_ok=True) with open(orig_file, mode="wb") as f: f.write("bar".encode("utf-8")) mock_hash = mock.Mock( return_value=mock.Mock( hexdigest=mock.Mock(return_value="deadc0de"), ) ) bar_loc = "path/to/bar.txt" assert len(result_server.metadata_store) == 1 assert bar_loc not in result_server.metadata_store with mock.patch("hashlib.md5", mock_hash): result_server.store_path(bar_loc, orig_file) assert len(result_server.metadata_store) == 2 assert bar_loc in result_server.metadata_store metadata_dict = result_server.metadata_store[bar_loc].to_dict() assert metadata_dict == {"md5": "deadc0de"} external = result_server.external_store with external.load_stream(bar_loc) as f: assert f.read().decode("utf-8") == "bar" def test_iter(self, result_server): assert list(result_server) == ["path/to/foo.txt"] def test_find_missing_files(self, result_server): meta = Metadata(md5="1badc0de") result_server.metadata_store.store_metadata("fake/file.txt", meta) assert result_server.find_missing_files() == ["fake/file.txt"] def test_load_stream(self, result_server): with result_server.load_stream("path/to/foo.txt") as f: contents = f.read() assert contents.decode("utf-8") == "foo" def test_delete(self, result_server, tmp_path): location = "path/to/foo.txt" path = tmp_path / pathlib.Path(location) assert path.exists() assert location in result_server.metadata_store result_server.delete(location) assert not path.exists() assert location not in result_server.metadata_store def test_load_stream_missing(self, result_server): with pytest.raises(MissingExternalResourceError, match="not found"): result_server.load_stream("path/does/not/exist.txt") def test_load_stream_error_bad_hash(self, result_server): meta = Metadata(md5="1badc0de") result_server.metadata_store.store_metadata("path/to/foo.txt", meta) with pytest.raises(ChangedExternalResourceError): result_server.load_stream("path/to/foo.txt") def test_load_stream_allow_bad_hash(self, result_server): meta = Metadata(md5="1badc0de") result_server.metadata_store.store_metadata("path/to/foo.txt", meta) with pytest.warns(UserWarning, match="Metadata mismatch"): file = result_server.load_stream("path/to/foo.txt", allow_changed=True) with file as f: assert f.read().decode("utf-8") == "foo" ================================================ FILE: src/openfe/tests/utils/__init__.py ================================================ ================================================ FILE: src/openfe/tests/utils/conftest.py ================================================ # This code is part of OpenFE and is licensed under the MIT license. # For details, see https://github.com/OpenFreeEnergy/openfe from importlib import resources from typing import Iterable, NamedTuple import pytest from rdkit import Chem from openfe import LigandAtomMapping, LigandNetwork, SmallMoleculeComponent from ..conftest import mol_from_smiles class _NetworkTestContainer(NamedTuple): """Container to facilitate network testing""" network: LigandNetwork nodes: Iterable[SmallMoleculeComponent] edges: Iterable[LigandAtomMapping] n_nodes: int n_edges: int @pytest.fixture def mols(): mol1 = SmallMoleculeComponent(mol_from_smiles("CCO")) mol2 = SmallMoleculeComponent(mol_from_smiles("CC")) mol3 = SmallMoleculeComponent(mol_from_smiles("CO")) return mol1, mol2, mol3 @pytest.fixture def std_edges(mols): mol1, mol2, mol3 = mols edge12 = LigandAtomMapping(mol1, mol2, {0: 0, 1: 1}) edge23 = LigandAtomMapping(mol2, mol3, {0: 0}) edge13 = LigandAtomMapping(mol1, mol3, {0: 0, 2: 1}) return edge12, edge23, edge13 @pytest.fixture def simple_network(mols, std_edges): """Network with no edges duplicated and all nodes in edges""" network = LigandNetwork(std_edges) return _NetworkTestContainer( network=network, nodes=mols, edges=std_edges, n_nodes=3, n_edges=3, ) @pytest.fixture(scope="session") def benzene_transforms(): # a dict of Molecules for benzene transformations mols = {} with resources.as_file(resources.files("openfe.tests.data")) as d: fn = str(d / "benzene_modifications.sdf") supplier = Chem.SDMolSupplier(fn, removeHs=False) for mol in supplier: mols[mol.GetProp("_Name")] = SmallMoleculeComponent(mol) return mols ================================================ FILE: src/openfe/tests/utils/test_atommapping_network_plotting.py ================================================ import importlib.resources import inspect from unittest import mock import matplotlib import matplotlib.figure import pytest from matplotlib import pyplot as plt from openfe.tests.utils.test_network_plotting import mock_event from openfe.utils.atommapping_network_plotting import ( AtomMappingNetworkDrawing, LigandNode, plot_atommapping_network, ) def bound_args(func, args, kwargs): """Return a dictionary mapping parameter name to value. Parameters ---------- func : Callable this must be inspectable; mocks will require a spec args : List args list kwargs : Dict kwargs Dict Returns ------- Dict[str, Any] : mapping of string name of function parameter to the value it would be bound to """ sig = inspect.Signature.from_callable(func) bound = sig.bind(*args, **kwargs) return bound.arguments @pytest.fixture def network_drawing(simple_network): nx_graph = simple_network.network.graph node_dict = {node.smiles: node for node in nx_graph.nodes} positions = { node_dict["CC"]: (0.0, 0.0), node_dict["CO"]: (0.5, 0.0), node_dict["CCO"]: (0.25, 0.25), } graph = AtomMappingNetworkDrawing(nx_graph, positions) graph.ax.set_xlim(0, 1) graph.ax.set_ylim(0, 1) yield graph plt.close(graph.fig) @pytest.fixture def default_edge(network_drawing): node_dict = {node.smiles: node for node in network_drawing.graph.nodes} yield network_drawing.edges[node_dict["CC"], node_dict["CO"]] @pytest.fixture def default_node(network_drawing): node_dict = {node.smiles: node for node in network_drawing.graph.nodes} yield LigandNode(node_dict["CC"], 0.5, 0.5, 0.1, 0.1) class TestAtomMappingEdge: def test_draw_mapped_molecule(self, default_edge): assert len(default_edge.artist.axes.images) == 0 im = default_edge._draw_mapped_molecule( (0.05, 0.45, 0.5, 0.9), default_edge.node_artists[0].node, default_edge.node_artists[1].node, {0: 0}, ) # maybe add something about im itself? not sure what to test here assert len(default_edge.artist.axes.images) == 1 assert default_edge.artist.axes.images[0] == im def test_get_image_extents(self, default_edge): left_extent, right_extent = default_edge._get_image_extents() assert left_extent == (0.05, 0.45, 0.5, 0.9) assert right_extent == (0.55, 0.95, 0.5, 0.9) def test_select(self, default_edge, network_drawing): assert not default_edge.picked assert len(default_edge.artist.axes.images) == 0 event = mock_event("mouseup", 0.25, 0.0, network_drawing.fig) default_edge.select(event, network_drawing) assert default_edge.picked assert len(default_edge.artist.axes.images) == 2 @pytest.mark.parametrize( "edge_str,left_right,molA_to_molB", [ (("CCO", "CC"), ("CC", "CCO"), {0: 0, 1: 1}), (("CC", "CO"), ("CC", "CO"), {0: 0}), (("CCO", "CO"), ("CCO", "CO"), {0: 0, 2: 1}), ], ) def test_select_mock_drawing(self, edge_str, left_right, molA_to_molB, network_drawing): # this tests that we call _draw_mapped_molecule with the correct # kwargs -- in particular, it ensures that we get the left and right # molecules correctly node_dict = {node.smiles: node for node in network_drawing.graph.nodes} edge_tuple = tuple(node_dict[node] for node in edge_str) edge = network_drawing.edges[edge_tuple] left, right = [network_drawing.nodes[node_dict[node]] for node in left_right] # ensure that we have them labelled correctly assert left.xy[0] < right.xy[0] func = edge._draw_mapped_molecule # save for bound_args edge._draw_mapped_molecule = mock.Mock() event = mock_event("mouseup", 0.25, 0.0, network_drawing.fig) edge.select(event, network_drawing) arg_dicts = [ bound_args(func, call.args, call.kwargs) for call in edge._draw_mapped_molecule.mock_calls ] expected_left = { "extent": (0.05, 0.45, 0.5, 0.9), "molA": left.node, "molB": right.node, "molA_to_molB": molA_to_molB, } expected_right = { "extent": (0.55, 0.95, 0.5, 0.9), "molA": right.node, "molB": left.node, "molA_to_molB": {v: k for k, v in molA_to_molB.items()}, } assert len(arg_dicts) == 2 assert expected_left in arg_dicts assert expected_right in arg_dicts def test_unselect(self, default_edge, network_drawing): # start by selecting; hard to be sure we mocked all the side effects # of select event = mock_event("mouseup", 0.25, 0.0, network_drawing.fig) default_edge.select(event, network_drawing) assert default_edge.picked assert len(default_edge.artist.axes.images) == 2 assert default_edge.right_image is not None assert default_edge.left_image is not None default_edge.unselect() assert not default_edge.picked assert len(default_edge.artist.axes.images) == 0 assert default_edge.right_image is None assert default_edge.left_image is None class TestLigandNode: def setup_method(self): self.fig, self.ax = plt.subplots() def teardown_method(self): plt.close(self.fig) def test_register_artist(self, default_node): assert len(self.ax.texts) == 0 default_node.register_artist(self.ax) assert len(self.ax.texts) == 1 assert self.ax.texts[0] == default_node.artist def test_extent(self, default_node): default_node.register_artist(self.ax) xmin, xmax, ymin, ymax = default_node.extent assert xmin == pytest.approx(0.5) assert ymin == pytest.approx(0.5) # can't do anything about upper bounds def test_xy(self, default_node): # default_node.register_artist(self.ax) x, y = default_node.xy assert x == pytest.approx(0.5) assert y == pytest.approx(0.5) def test_plot_atommapping_network(simple_network): fig = plot_atommapping_network(simple_network.network) assert isinstance(fig, matplotlib.figure.Figure) ================================================ FILE: src/openfe/tests/utils/test_duecredit.py ================================================ import importlib import os import pytest from openff.utilities.testing import skip_if_missing import openfe @skip_if_missing("duecredit") @pytest.mark.skipif( (os.environ.get("DUECREDIT_ENABLE", "no").lower() in ("no", "0", "false")), reason="duecredit is disabled", ) class TestDuecredit: @pytest.mark.parametrize( "module, dois", [ [ "openfe.protocols.openmm_afe.equil_solvation_afe_method", [ "10.5281/zenodo.596504", "10.48550/arxiv.2302.06758", "10.5281/zenodo.596622", "10.1371/journal.pcbi.1005659", ], ], [ "openfe.protocols.openmm_afe.equil_binding_afe_method", [ "10.5281/zenodo.596504", "10.5281/zenodo.596622", "10.1371/journal.pcbi.1005659", ], ], [ "openfe.protocols.openmm_rfe.hybridtop_protocols", ["10.5281/zenodo.1297683", "10.5281/zenodo.596622", "10.1371/journal.pcbi.1005659"], ], [ "openfe.protocols.openmm_utils.multistate_analysis", [ "10.5281/zenodo.596622", "10.1063/1.2978177", "10.1021/ct0502864", "10.1021/acs.jctc.5b00784", "10.5281/zenodo.596220", ], ], [ "openfe.protocols.openmm_septop.equil_septop_method", [ "10.1021/acs.jctc.3c00282", "10.5281/zenodo.596622", "10.1371/journal.pcbi.1005659", ], ], ], ) def test_duecredit_protocol_collection(self, module, dois): importlib.import_module(module) for doi in dois: assert openfe.due.due.citations[(module, doi)].cites_module def test_duecredit_active(self): assert openfe.due.due.active ================================================ FILE: src/openfe/tests/utils/test_log_control.py ================================================ import logging import pytest from openfe.utils import logging_control from openfe.utils.logging_control import ( _AppendMsgFilter, _BaseLogFilter, _MsgIncludesStringFilter, ) @pytest.fixture def logger(): """Create a test logger with a handler that captures log records.""" test_logger = logging.getLogger("test_logger") test_logger.setLevel(logging.DEBUG) test_logger.handlers = [] # Clear any existing handlers # Create a handler that stores log records class ListHandler(logging.Handler): def __init__(self): super().__init__() self.records = [] def emit(self, record): self.records.append(record) handler = ListHandler() test_logger.addHandler(handler) yield test_logger, handler # Cleanup test_logger.handlers = [] test_logger.filters = [] class Test_MsgIncludesStringFilter: """Tests for _MsgIncludesStringFilter.""" def test_single_string_blocks_matching_message(self): """Test that a single string blocks messages containing it.""" filter_obj = _MsgIncludesStringFilter("block this") record = logging.LogRecord( name="test", level=logging.INFO, pathname="", lineno=0, msg="Please block this message", args=(), exc_info=None, ) assert filter_obj.filter(record) is False def test_single_string_allows_non_matching_message(self): """Test that messages not containing the string are allowed.""" filter_obj = _MsgIncludesStringFilter("block this") record = logging.LogRecord( name="test", level=logging.INFO, pathname="", lineno=0, msg="This is fine", args=(), exc_info=None, ) assert filter_obj.filter(record) is True def test_list_of_strings_blocks_any_match(self): """Test that any string in the list blocks the message.""" filter_obj = _MsgIncludesStringFilter(["warning1", "warning2", "warning3"]) record1 = logging.LogRecord( name="test", level=logging.INFO, pathname="", lineno=0, msg="This has warning1 in it", args=(), exc_info=None, ) assert filter_obj.filter(record1) is False record2 = logging.LogRecord( name="test", level=logging.INFO, pathname="", lineno=0, msg="This has warning3 in it", args=(), exc_info=None, ) assert filter_obj.filter(record2) is False def test_list_allows_non_matching_messages(self): """Test that messages not matching any string are allowed.""" filter_obj = _MsgIncludesStringFilter(["warning1", "warning2"]) record = logging.LogRecord( name="test", level=logging.INFO, pathname="", lineno=0, msg="This is completely different", args=(), exc_info=None, ) assert filter_obj.filter(record) is True def test_substring_matching(self): """Test that substring matching works correctly.""" filter_obj = _MsgIncludesStringFilter("JAX") record = logging.LogRecord( name="test", level=logging.INFO, pathname="", lineno=0, msg="****** PyMBAR will use 64-bit JAX! *******", args=(), exc_info=None, ) assert filter_obj.filter(record) is False def test_case_sensitive_matching(self): """Test that matching is case-sensitive.""" filter_obj = _MsgIncludesStringFilter("Error") record1 = logging.LogRecord( name="test", level=logging.INFO, pathname="", lineno=0, msg="This has Error in it", args=(), exc_info=None, ) assert filter_obj.filter(record1) is False record2 = logging.LogRecord( name="test", level=logging.INFO, pathname="", lineno=0, msg="This has error in it", args=(), exc_info=None, ) assert filter_obj.filter(record2) is True class Test_AppendMsgFilter: """Tests for _AppendMsgFilter.""" def test_single_suffix_appends(self): """Test that a single suffix is appended to the message.""" filter_obj = _AppendMsgFilter(" [DEPRECATED]") record = logging.LogRecord( name="test", level=logging.INFO, pathname="", lineno=0, msg="Original message", args=(), exc_info=None, ) result = filter_obj.filter(record) assert result is True assert record.msg == "Original message [DEPRECATED]" def test_multiple_suffixes_append_in_order(self): """Test that multiple suffixes are appended in order.""" filter_obj = _AppendMsgFilter([" [DEPRECATED]", " - see docs"]) record = logging.LogRecord( name="test", level=logging.INFO, pathname="", lineno=0, msg="Original message", args=(), exc_info=None, ) filter_obj.filter(record) assert record.msg == "Original message [DEPRECATED] - see docs" def test_idempotent_single_suffix(self): """Test that applying the same suffix twice is idempotent.""" filter_obj = _AppendMsgFilter(" [DEPRECATED]") record = logging.LogRecord( name="test", level=logging.INFO, pathname="", lineno=0, msg="Original message [DEPRECATED]", args=(), exc_info=None, ) filter_obj.filter(record) assert record.msg == "Original message [DEPRECATED]" def test_idempotent_multiple_suffixes(self): """Test idempotency with multiple suffixes.""" filter_obj = _AppendMsgFilter([" [DEPRECATED] - see docs", " [DEPRECATED] - see docs"]) record = logging.LogRecord( name="test", level=logging.INFO, pathname="", lineno=0, msg="Original message [DEPRECATED] - see docs", args=(), exc_info=None, ) filter_obj.filter(record) assert record.msg == "Original message [DEPRECATED] - see docs" def test_always_returns_true(self): """Test that the filter always returns True to allow logging.""" filter_obj = _AppendMsgFilter(" [INFO]") record = logging.LogRecord( name="test", level=logging.INFO, pathname="", lineno=0, msg="Message", args=(), exc_info=None, ) assert filter_obj.filter(record) is True class Testlogging_control: """Tests for logging_control module.""" def test__silence_message_single_string_single_logger(self, logger): """Test silencing a single message from a single logger.""" test_logger, handler = logger logging_control._silence_message(msg="block this", logger_names="test_logger") test_logger.info("block this message") test_logger.info("allow this message") assert len(handler.records) == 1 assert handler.records[0].msg == "allow this message" def test__silence_message_multiple_strings_single_logger(self, logger): """Test silencing multiple messages from a single logger.""" test_logger, handler = logger logging_control._silence_message(msg=["warning1", "warning2"], logger_names="test_logger") test_logger.info("This has warning1") test_logger.info("This has warning2") test_logger.info("This is fine") assert len(handler.records) == 1 assert handler.records[0].msg == "This is fine" def test__silence_message_single_string_multiple_loggers(self): """Test silencing a message from multiple loggers.""" logger1 = logging.getLogger("test_logger1") logger2 = logging.getLogger("test_logger2") # Clear any existing filters logger1.filters = [] logger2.filters = [] logging_control._silence_message( msg="block this", logger_names=["test_logger1", "test_logger2"] ) assert len(logger1.filters) == 1 assert len(logger2.filters) == 1 # Cleanup logger1.filters = [] logger2.filters = [] def test__silence_message_multiple_strings_multiple_loggers(self): """Test silencing multiple messages from multiple loggers.""" logger1 = logging.getLogger("test_logger1") logger2 = logging.getLogger("test_logger2") logger1.filters = [] logger2.filters = [] logging_control._silence_message( msg=["warning1", "warning2"], logger_names=["test_logger1", "test_logger2"] ) # Should have one filter per logger (not one per message) assert len(logger1.filters) == 1 assert len(logger2.filters) == 1 # Cleanup logger1.filters = [] logger2.filters = [] def test__silence_logger_single(self, logger): """Test completely silencing a single logger.""" test_logger, handler = logger logging_control._silence_logger(logger_names="test_logger") test_logger.debug("debug message") test_logger.info("info message") test_logger.warning("warning message") test_logger.error("error message") # All messages should be blocked assert len(handler.records) == 0 def test__silence_logger_multiple(self): """Test silencing multiple loggers.""" logger1 = logging.getLogger("test_logger1") logger2 = logging.getLogger("test_logger2") original_level1 = logger1.level original_level2 = logger2.level logging_control._silence_logger(logger_names=["test_logger1", "test_logger2"]) assert logger1.level == logging.CRITICAL assert logger2.level == logging.CRITICAL # Cleanup logger1.setLevel(original_level1) logger2.setLevel(original_level2) def test__silence_logger_custom_level(self, logger): """Test silencing logger with custom level.""" test_logger, handler = logger logging_control._silence_logger(logger_names="test_logger", level=logging.ERROR) test_logger.debug("debug message") test_logger.info("info message") test_logger.warning("warning message") test_logger.error("error message") # Only error and above should pass through assert len(handler.records) == 1 assert handler.records[0].msg == "error message" def test__append_logger_single_suffix_single_logger(self, logger): """Test appending a single suffix to a single logger.""" test_logger, handler = logger logging_control._append_logger(suffix=" [DEPRECATED]", logger_names="test_logger") test_logger.info("Original message") assert len(handler.records) == 1 assert handler.records[0].msg == "Original message [DEPRECATED]" def test__append_logger_multiple_suffixes(self, logger): """Test appending multiple suffixes.""" test_logger, handler = logger logging_control._append_logger( suffix=[" [DEPRECATED]", " - see docs"], logger_names="test_logger" ) test_logger.info("Original message") assert len(handler.records) == 1 assert handler.records[0].msg == "Original message [DEPRECATED] - see docs" def test__append_logger_multiple_loggers(self): """Test appending to multiple loggers.""" logger1 = logging.getLogger("test_logger1") logger2 = logging.getLogger("test_logger2") logger1.filters = [] logger2.filters = [] logging_control._append_logger( suffix=" [INFO]", logger_names=["test_logger1", "test_logger2"] ) assert len(logger1.filters) == 1 assert len(logger2.filters) == 1 # Cleanup logger1.filters = [] logger2.filters = [] def test_pymbar_example(self, logger): """Test the PyMBAR use case.""" test_logger, handler = logger logging_control._silence_message( msg="****** PyMBAR will use 64-bit JAX! *******", logger_names="test_logger" ) test_logger.info("****** PyMBAR will use 64-bit JAX! *******") test_logger.info("Other message") assert len(handler.records) == 1 assert handler.records[0].msg == "Other message" def test_combining_multiple_controls(self, logger): """Test combining silence and append on the same logger.""" test_logger, handler = logger logging_control._silence_message(msg="block", logger_names="test_logger") logging_control._append_logger(suffix=" [INFO]", logger_names="test_logger") test_logger.info("block this") test_logger.info("allow this") assert len(handler.records) == 1 assert handler.records[0].msg == "allow this [INFO]" class TestBaseLogFilter: """Tests for _BaseLogFilter base class.""" def test_cannot_instantiate_abstract_class(self): """Test that _BaseLogFilter cannot be instantiated directly.""" with pytest.raises(TypeError): _BaseLogFilter("test") def test_subclass_must_implement_filter(self): """Test that subclasses must implement the filter method.""" class IncompleteFilter(_BaseLogFilter): pass with pytest.raises(TypeError): IncompleteFilter("test") def test_subclass_with_filter_works(self): """Test that a proper subclass can be instantiated.""" class CompleteFilter(_BaseLogFilter): def filter(self, record): return True filter_obj = CompleteFilter("test") assert filter_obj.strings == ["test"] def test_string_conversion_to_list(self): """Test that single strings are converted to lists.""" filter_obj = _MsgIncludesStringFilter("single") assert isinstance(filter_obj.strings, list) assert filter_obj.strings == ["single"] def test_list_stays_as_list(self): """Test that lists remain as lists.""" filter_obj = _MsgIncludesStringFilter(["one", "two", "three"]) assert isinstance(filter_obj.strings, list) assert filter_obj.strings == ["one", "two", "three"] class TestEdgeCases: """Tests for edge cases and error conditions.""" def test_empty_string(self, logger): """Test behavior with empty string.""" test_logger, handler = logger logging_control._silence_message(msg="", logger_names="test_logger") test_logger.info("message") # Empty string matches everything as substring assert len(handler.records) == 0 def test_empty_list(self, logger): """Test behavior with empty list.""" test_logger, handler = logger logging_control._silence_message(msg=[], logger_names="test_logger") test_logger.info("message") # Empty list should not block anything assert len(handler.records) == 1 def test_special_characters_in_message(self, logger): """Test that special characters are handled correctly.""" test_logger, handler = logger logging_control._silence_message( msg="[WARNING] *special* $chars$", logger_names="test_logger" ) test_logger.info("[WARNING] *special* $chars$ in message") test_logger.info("normal message") assert len(handler.records) == 1 assert handler.records[0].msg == "normal message" def test_unicode_characters(self, logger): """Test that unicode characters work correctly.""" test_logger, handler = logger logging_control._silence_message(msg="🚫 blocked", logger_names="test_logger") logging_control._append_logger(suffix=" ✅", logger_names="test_logger") test_logger.info("🚫 blocked message") test_logger.info("allowed message") assert len(handler.records) == 1 assert handler.records[0].msg == "allowed message ✅" def test_very_long_message(self, logger): """Test handling of very long messages.""" test_logger, handler = logger long_msg = "x" * 10000 logging_control._silence_message(msg="needle", logger_names="test_logger") test_logger.info(long_msg + "needle" + long_msg) test_logger.info("short message") assert len(handler.records) == 1 assert handler.records[0].msg == "short message" ================================================ FILE: src/openfe/tests/utils/test_network_plotting.py ================================================ from unittest import mock import networkx as nx import pytest from matplotlib import pyplot as plt from matplotlib.backend_bases import MouseButton, MouseEvent from numpy import testing as npt from openfe.utils.network_plotting import Edge, EventHandler, GraphDrawing, Node def _get_fig_ax(fig): if fig is None: fig, _ = plt.subplots() if len(fig.axes) != 1: # -no-cov- raise RuntimeError( "Error in test setup: figure must have exactly one Axes object associated" ) return fig, fig.axes[0] def mock_event(event_name, xdata, ydata, fig=None): fig, ax = _get_fig_ax(fig) name = { "mousedown": "button_press_event", "mouseup": "button_release_event", "drag": "motion_notify_event", }[event_name] matplotlib_buttons = { "mousedown": MouseButton.LEFT, "mouseup": MouseButton.LEFT, "drag": MouseButton.LEFT, } button = matplotlib_buttons.get(event_name, None) x, y = ax.transData.transform((xdata, ydata)) return MouseEvent(name, fig.canvas, x, y, button) def make_mock_graph(fig=None): fig, ax = _get_fig_ax(fig) def make_mock_node(node, x, y): return mock.Mock(node=node, x=x, y=y) def make_mock_edge(node1, node2, data): return mock.Mock(node_artists=[node1, node2], data=data) node_A = make_mock_node("A", 0.0, 0.0) node_B = make_mock_node("B", 0.5, 0.0) node_C = make_mock_node("C", 0.5, 0.5) node_D = make_mock_node("D", 0.0, 0.5) edge_AB = make_mock_edge(node_A, node_B, {"data": "AB"}) edge_BC = make_mock_edge(node_B, node_C, {"data": "BC"}) edge_BD = make_mock_edge(node_B, node_D, {"data": "BD"}) mock_graph = mock.Mock( nodes={node.node: node for node in [node_A, node_B, node_C, node_D]}, edges={tuple(edge.node_artists): edge for edge in [edge_AB, edge_BC, edge_BD]}, ) return mock_graph class TestNode: def setup_method(self): self.node = Node("B", 0.5, 0.0) self.fig, self.ax = plt.subplots() self.node.register_artist(self.ax) def teardown_method(self): plt.close(self.fig) def test_register_artist(self): node = Node("B", 0.6, 0.0) fig, ax = plt.subplots() assert len(ax.patches) == 0 node.register_artist(ax) assert len(ax.patches) == 1 assert node.artist == ax.patches[0] plt.close(fig) def test_extent(self): assert self.node.extent == (0.5, 0.6, 0.0, 0.1) def test_xy(self): assert self.node.xy == (0.5, 0.0) def test_unselect(self): # initially blue; turn it red; unselect should switch it back assert self.node.artist.get_facecolor() == (0.0, 0.0, 1.0, 1.0) self.node.artist.set(color="red") assert self.node.artist.get_facecolor() != (0.0, 0.0, 1.0, 1.0) self.node.unselect() assert self.node.artist.get_facecolor() == (0.0, 0.0, 1.0, 1.0) def test_edge_select(self): # initially blue; edge_select should turn it red assert self.node.artist.get_facecolor() == (0.0, 0.0, 1.0, 1.0) edge = mock.Mock() # unused in this method self.node.edge_select(edge) assert self.node.artist.get_facecolor() == (1.0, 0.0, 0.0, 1.0) def test_update_location(self): assert self.node.artist.xy == (0.5, 0.0) self.node.update_location(0.7, 0.5) assert self.node.artist.xy == (0.7, 0.5) assert self.node.xy == (0.7, 0.5) @pytest.mark.parametrize( "point,expected", [ ((0.55, 0.05), True), ((0.5, 0.5), False), ((-10, -10), False), ], ) def test_contains(self, point, expected): event = mock_event("drag", *point, fig=self.fig) assert self.node.contains(event) == expected def test_on_mousedown_in_rect(self): event = mock_event("mousedown", 0.55, 0.05, self.fig) drawing_graph = make_mock_graph(self.fig) assert Node.lock is None assert self.node.press is None self.node.on_mousedown(event, drawing_graph) assert Node.lock == self.node assert self.node.press is not None Node.lock = None def test_on_mousedown_in_axes(self): event = mock_event("mousedown", 0.25, 0.25, self.fig) drawing_graph = make_mock_graph(self.fig) assert Node.lock is None assert self.node.press is None self.node.on_mousedown(event, drawing_graph) assert Node.lock is None assert self.node.press is None def test_on_mousedown_out_axes(self): node = Node("B", 0.5, 0.6) event = mock_event("mousedown", 0.55, 0.05, self.fig) drawing_graph = make_mock_graph(self.fig) fig2, ax2 = plt.subplots() node.register_artist(ax2) assert Node.lock is None assert node.press is None node.on_mousedown(event, drawing_graph) assert Node.lock is None assert node.press is None plt.close(fig2) def test_on_drag(self): event = mock_event("drag", 0.7, 0.7, self.fig) # this test some integration, so we need more than a mock drawing_graph = GraphDrawing( nx.MultiDiGraph(([("A", "B"), ("B", "C"), ("B", "D")])), positions={ "A": (0.0, 0.0), "B": (0.5, 0.0), "C": (0.5, 0.5), "D": (0.0, 0.5) } ) # fmt: skip # set up things that should happen on mousedown Node.lock = self.node self.node.press = (0.5, 0.0), (0.55, 0.05) self.node.on_drag(event, drawing_graph) npt.assert_allclose(self.node.xy, (0.65, 0.65)) # undo the lock; normally handled by mouseup Node.lock = None def test_on_drag_do_nothing(self): event = mock_event("drag", 0.7, 0.7, self.fig) drawing_graph = make_mock_graph(self.fig) # don't set lock -- early exit original = self.node.xy self.node.on_drag(event, drawing_graph) assert self.node.xy == original def test_on_drag_no_mousedown(self): event = mock_event("drag", 0.7, 0.7, self.fig) drawing_graph = make_mock_graph(self.fig) Node.lock = self.node with pytest.raises(RuntimeError, match="drag until mouse down"): self.node.on_drag(event, drawing_graph) Node.lock = None def test_on_mouseup(self): event = mock_event("drag", 0.7, 0.7, self.fig) drawing_graph = make_mock_graph(self.fig) Node.lock = self.node self.node.press = (0.5, 0.0), (0.55, 0.05) self.node.on_mouseup(event, drawing_graph) assert Node.lock is None assert self.node.press is None def test_blitting(self): pytest.skip("Blitting hasn't been implemented yet") class TestEdge: def setup_method(self): self.nodes = [Node("A", 0.0, 0.0), Node("B", 0.5, 0.0)] self.data = {"data": "values"} self.edge = Edge(*self.nodes, self.data) self.fig, self.ax = plt.subplots() self.ax.set_xlim(-1, 1) self.ax.set_ylim(-1, 1) self.edge.register_artist(self.ax) def teardown_method(self): plt.close(self.fig) def test_register_artist(self): fig, ax = plt.subplots() edge = Edge(*self.nodes, self.data) assert len(ax.get_lines()) == 0 edge.register_artist(ax) assert len(ax.get_lines()) == 1 assert ax.get_lines()[0] == edge.artist plt.close(fig) @pytest.mark.parametrize( "point,expected", [ ((0.25, 0.05), True), ((0.6, 0.1), False), ], ) def test_contains(self, point, expected): event = mock_event("drag", *point, fig=self.fig) assert self.edge.contains(event) == expected def test_edge_xs_ys(self): npt.assert_allclose(self.edge._edge_xs_ys(*self.nodes), ((0.05, 0.55), (0.05, 0.05))) def _get_colors(self): colors = {node: node.artist.get_facecolor() for node in self.nodes} colors[self.edge] = self.edge.artist.get_color() return colors def test_unselect(self): original = self._get_colors() for node in self.nodes: node.artist.set(color="red") self.edge.artist.set(color="red") # ensure that we have changed from the original values changed = self._get_colors() for key in original: assert changed[key] != original[key] self.edge.unselect() after = self._get_colors() assert after == original def test_select(self): event = mock_event("mouseup", 0.25, 0.05, self.fig) drawing_graph = make_mock_graph(self.fig) original = self._get_colors() self.edge.select(event, drawing_graph) changed = self._get_colors() for key in self.nodes: assert changed[key] != original[key] assert changed[key] == (1.0, 0.0, 0.0, 1.0) # red assert changed[self.edge] == "red" # mpl doesn't convert to RGBA?! # it might be better in the future to pass that through some MPL # func that converts color string to RGBA; the fact that MPL keeps # color name in line2d seems like an implementation detail def test_update_locations(self): for node in self.nodes: x, y = node.xy node.update_location(x + 0.2, y + 0.2) self.edge.update_locations() npt.assert_allclose(self.edge.artist.get_xdata(), [0.25, 0.75]) npt.assert_allclose(self.edge.artist.get_ydata(), [0.25, 0.25]) class TestEventHandler: def setup_method(self): self.fig, self.ax = plt.subplots() self.event_handler = EventHandler(graph=make_mock_graph(self.fig)) graph = self.event_handler.graph node = graph.nodes["C"] edge = graph.edges[graph.nodes["B"], graph.nodes["C"]] self.setup_contains = { "node": (node, [node]), "edge": (edge, [edge]), "node+edge": (node, [node, edge]), "miss": (None, []), } def teardown_method(self): plt.close(self.fig) def _mock_for_connections(self): self.event_handler.on_mousedown = mock.Mock() self.event_handler.on_mouseup = mock.Mock() self.event_handler.on_drag = mock.Mock() @pytest.mark.parametrize("event_type", ["mousedown", "mouseup", "drag"]) def test_connect(self, event_type): self._mock_for_connections() event = mock_event(event_type, 0.2, 0.2, self.fig) methods = { "mousedown": self.event_handler.on_mousedown, "mouseup": self.event_handler.on_mouseup, "drag": self.event_handler.on_drag, } should_call = methods[event_type] should_not_call = set(methods.values()) - {should_call} assert len(self.event_handler.connections) == 0 self.event_handler.connect(self.fig.canvas) assert len(self.event_handler.connections) == 3 # check that the event is processed self.fig.canvas.callbacks.process(event.name, event) should_call.assert_called_once() for method in should_not_call: assert not method.called @pytest.mark.parametrize("event_type", ["mousedown", "mouseup", "drag"]) def test_disconnect(self, event_type): self._mock_for_connections() fig, _ = plt.subplots() event = mock_event(event_type, 0.2, 0.2, fig) self.event_handler.connect(fig.canvas) # not quite full isolation assert len(self.event_handler.connections) == 3 self.event_handler.disconnect(fig.canvas) assert len(self.event_handler.connections) == 0 methods = [ self.event_handler.on_mousedown, self.event_handler.on_mousedown, self.event_handler.on_drag, ] fig.canvas.callbacks.process(event.name, event) for method in methods: assert not method.called plt.close(fig) def _mock_contains(self, mock_objs): graph = self.event_handler.graph objs = list(graph.nodes.values()) + list(graph.edges.values()) for obj in objs: if obj in mock_objs: obj.contains = mock.Mock(return_value=True) else: obj.contains = mock.Mock(return_value=False) @pytest.mark.parametrize("hit", ["node", "edge", "node+edge", "miss"]) def test_get_event_container_select_node(self, hit): expected, contains_event = self.setup_contains[hit] expected_count = { "node": 3, # nodes A, B, C "edge": 6, # nodes A, B, C, D; edges AB, BC "node+edge": 3, # nodes A, B, C "miss": 7, # nodes A, B, C, D; edges AB BC, BD }[hit] self._mock_contains(contains_event) event = mock.Mock() found = self.event_handler._get_event_container(event) assert found is expected for container in contains_event: if container is not expected: assert not container.called graph = self.event_handler.graph all_objs = list(graph.nodes.values()) + list(graph.edges.values()) contains_count = sum(obj.contains.called for obj in all_objs) assert contains_count == expected_count @pytest.mark.parametrize("hit", ["node", "edge", "node+edge", "miss"]) def test_on_mousedown(self, hit): expected, contains_event = self.setup_contains[hit] self._mock_contains(contains_event) event = mock_event("mousedown", 0.5, 0.5) assert self.event_handler.click_location is None assert self.event_handler.active is None self.event_handler.on_mousedown(event) npt.assert_allclose(self.event_handler.click_location, (0.5, 0.5)) assert self.event_handler.active is expected if expected is not None: expected.on_mousedown.assert_called_once() plt.close(event.canvas.figure) @pytest.mark.parametrize("is_active", [True, False]) def test_on_drag(self, is_active): node = self.event_handler.graph.nodes["C"] node.artist.axes = self.ax event = mock_event("drag", 0.25, 0.25, self.fig) if is_active: self.event_handler.active = node self.event_handler.on_drag(event) if is_active: node.on_drag.assert_called_once() else: assert not node.on_drag.called @pytest.mark.parametrize("has_selected", [True, False]) def test_on_mouseup_click_select(self, has_selected): # start: mouse hasn't moved, and something is active graph = self.event_handler.graph edge = graph.edges[graph.nodes["B"], graph.nodes["C"]] if has_selected: old_selected = graph.edges[graph.nodes["A"], graph.nodes["B"]] self.event_handler.selected = old_selected self._mock_contains([edge]) event = mock_event("mouseup", 0.25, 0.25) self.event_handler.click_location = (event.xdata, event.ydata) self.event_handler.active = edge # this should select the active object self.event_handler.on_mouseup(event) if has_selected: old_selected.unselect.assert_called_once() edge.select.assert_called_once() edge.on_mouseup.assert_called_once() assert self.event_handler.selected is edge assert self.event_handler.active is None assert self.event_handler.click_location is None graph.draw.assert_called_once() plt.close(event.canvas.figure) @pytest.mark.parametrize("has_selected", [True, False]) def test_on_mouseup_click_not_select(self, has_selected): # start: mouse hasn't moved, nothing is active graph = self.event_handler.graph if has_selected: old_selected = graph.edges[graph.nodes["A"], graph.nodes["B"]] self.event_handler.selected = old_selected event = mock_event("mouseup", 0.25, 0.25) self.event_handler.click_location = (event.xdata, event.ydata) self.event_handler.on_mouseup(event) if has_selected: old_selected.unselect.assert_called_once() assert self.event_handler.selected is None assert self.event_handler.active is None assert self.event_handler.click_location is None graph.draw.assert_called_once() plt.close(event.canvas.figure) @pytest.mark.parametrize("has_selected", [True, False]) def test_on_mouseup_drag(self, has_selected): # start: mouse has moved, something is active graph = self.event_handler.graph edge = graph.edges[graph.nodes["B"], graph.nodes["C"]] if has_selected: old_selected = graph.edges[graph.nodes["A"], graph.nodes["B"]] self.event_handler.selected = old_selected event = mock_event("mouseup", 0.25, 0.25) self.event_handler.click_location = (0.5, 0.5) self.event_handler.active = edge self.event_handler.on_mouseup(event) if has_selected: assert not old_selected.unselect.called assert not edge.selected.called edge.on_mouseup.assert_called_once() assert self.event_handler.active is None assert self.event_handler.click_location is None graph.draw.assert_called_once() plt.close(event.canvas.figure) class TestGraphDrawing: def setup_method(self): self.nx_graph = nx.MultiDiGraph() self.nx_graph.add_edges_from( [ ("A", "B", {"data": "AB"}), ("B", "C", {"data": "BC"}), ("B", "D", {"data": "BD"}), ] ) self.positions = {"A": (0.0, 0.0), "B": (0.5, 0.0), "C": (0.5, 0.5), "D": (-0.1, 0.6)} self.graph = GraphDrawing(self.nx_graph, positions=self.positions) def test_init(self): # this also tests _register_node, _register_edge assert len(self.graph.nodes) == 4 assert len(self.graph.edges) == 3 assert len(self.graph.fig.axes) == 1 assert self.graph.fig.axes[0] is self.graph.ax assert len(self.graph.ax.patches) == 4 assert len(self.graph.ax.lines) == 3 def test_init_custom_ax(self): fig, ax = plt.subplots() graph = GraphDrawing(self.nx_graph, positions=self.positions, ax=ax) assert graph.fig is fig assert graph.ax is ax plt.close(fig) def test_register_node_error(self): with pytest.raises(RuntimeError, match="multiple times"): self.graph._register_node( node=list(self.nx_graph.nodes)[0], position=(0, 0), ) @pytest.mark.parametrize( "node,edges", [ ("A", [("A", "B")]), ("B", [("A", "B"), ("B", "C"), ("B", "D")]), ("C", [("B", "C")]), ], ) def test_edges_for_node(self, node, edges): expected_edges = {self.graph.edges[n1, n2] for n1, n2 in edges} assert set(self.graph.edges_for_node(node)) == expected_edges def test_get_nodes_extent(self): assert self.graph._get_nodes_extent() == (-0.1, 0.6, 0.0, 0.7) def test_reset_bounds(self): old_xlim = self.graph.ax.get_xlim() old_ylim = self.graph.ax.get_ylim() self.graph.ax.set_xlim(old_xlim[0] * 2, old_xlim[1] * 2) self.graph.ax.set_ylim(old_ylim[0] * 2, old_ylim[1] * 2) self.graph.reset_bounds() assert self.graph.ax.get_xlim() == old_xlim assert self.graph.ax.get_ylim() == old_ylim def test_draw(self): # just a smoke test; there's really nothing that we can test here # other that integration self.graph.draw() ================================================ FILE: src/openfe/tests/utils/test_optional_imports.py ================================================ # This code is part of OpenFE and is licensed under the MIT license. # For details, see https://github.com/OpenFreeEnergy/openfe import pytest from openfe.utils import requires_package @requires_package("no_such_package_hopefully") def the_answer(): return 42 def test_requires_decorator(): with pytest.raises(ImportError): the_answer() ================================================ FILE: src/openfe/tests/utils/test_remove_oechem.py ================================================ # This code is part of OpenFE and is licensed under the MIT license. # For details, see https://github.com/OpenFreeEnergy/openfe from openff.toolkit import GLOBAL_TOOLKIT_REGISTRY, OpenEyeToolkitWrapper from openfe.utils import without_oechem_backend def test_remove_oechem(): original_tks = GLOBAL_TOOLKIT_REGISTRY.registered_toolkits original_n_tks = len(GLOBAL_TOOLKIT_REGISTRY.registered_toolkits) with without_oechem_backend(): for tk in GLOBAL_TOOLKIT_REGISTRY.registered_toolkits: assert not isinstance(tk, OpenEyeToolkitWrapper) assert len(GLOBAL_TOOLKIT_REGISTRY.registered_toolkits) == original_n_tks for ref_tk, tk in zip(original_tks, GLOBAL_TOOLKIT_REGISTRY.registered_toolkits): assert isinstance(tk, type(ref_tk)) ================================================ FILE: src/openfe/tests/utils/test_system_probe.py ================================================ import contextlib import logging import pathlib import subprocess import sys from collections import namedtuple from unittest.mock import Mock, patch import pytest try: from psutil._ntuples import sdiskusage except ImportError: from psutil._common import sdiskusage from openfe.utils.system_probe import ( _get_disk_usage, _get_gpu_info, _get_hostname, _get_psutil_info, _probe_system, log_system_probe, ) # Named tuples from https://github.com/giampaolo/psutil/blob/master/psutil/_pslinux.py svmem = namedtuple( "svmem", [ "total", "available", "percent", "used", "free", "active", "inactive", "buffers", "cached", "shared", "slab", ], ) pfullmem = namedtuple( "pfullmem", ["rss", "vms", "shared", "text", "lib", "data", "dirty", "uss", "pss", "swap"], ) EXPECTED_SYSTEM_INFO = { "system information": { "hostname": "mock-hostname", "gpu information": { "GPU-UUID-1": { "name": "NVIDIA GeForce RTX 2060", "compute_mode": "Default", "pstate": "P8", "temperature.gpu": "47", "utilization.memory [%]": "6 %", "memory.total [MiB]": "6144 MiB", "driver_version": "525.116.04", }, "GPU-UUID-2": { "name": "NVIDIA GeForce RTX 2060", "compute_mode": "Default", "pstate": "P8", "temperature.gpu": "47", "utilization.memory [%]": "6 %", "memory.total [MiB]": "6144 MiB", "driver_version": "525.116.04", }, }, "psutil information": { "pid": 1590579, "status": "running", "exe": "/home/winry/micromamba/envs/openfe/bin/python3.10", "cpu_percent": 0.0, "num_fds": 4, "create_time": 1690999298.62, "memory_percent": 0.02006491389254216, "memory_full_info": { "rss": 13500416, "vms": 31858688, "shared": 6946816, "text": 2121728, "lib": 0, "data": 7852032, "dirty": 0, "uss": 10764288, "pss": 10777600, "swap": 0, }, "RLIMIT_AS": (-1, -1), "virtual_memory": { "total": 67283697664, "available": 31731806208, "percent": 52.8, "used": 29899350016, "free": 3136847872, "active": 25971789824, "inactive": 34514595840, "buffers": 136404992, "cached": 34111094784, "shared": 1021571072, "slab": 1518297088, }, }, "disk usage information": { "/dev/mapper/data-root": { "size": "1.8T", "used": "626G", "available": "1.1T", "percent_used": "37%", "mount_point": "/", }, "/dev/dm-3": { "size": "3.7T", "used": "1.6T", "available": "2.2T", "percent_used": "42%", "mount_point": "/mnt/data", }, }, } } def fake_disk_usage(path): if str(path) == "/foo": return sdiskusage(total=1958854045696, used=1232985415680, free=626288726016, percent=66.3) if str(path) == "/bar": return sdiskusage(total=4000770252800, used=1678226952192, free=2322615496704, percent=41.9) @contextlib.contextmanager def patch_system(): # single patch to fully patch the system patch_hostname = patch("socket.gethostname", Mock(return_value="mock-hostname")) patch_psutil_Process_as_dict = patch( "psutil.Process.as_dict", Mock( return_value={ "pid": 1590579, "status": "running", "exe": "/home/winry/micromamba/envs/openfe/bin/python3.10", "cpu_percent": 0.0, "num_fds": 4, "create_time": 1690999298.62, "memory_percent": 0.02006491389254216, "memory_full_info": pfullmem( rss=13500416, vms=31858688, shared=6946816, text=2121728, lib=0, data=7852032, dirty=0, uss=10764288, pss=10777600, swap=0, ), } ), ) # Since this attribute doesn't exist on OSX, we have to create it patch_psutil_Process_rlimit = patch("psutil.Process.rlimit", Mock(return_value=(-1, -1))) patch_psutil_virtual_memory = patch( "psutil.virtual_memory", Mock( return_value=svmem( total=67283697664, available=31731806208, percent=52.8, used=29899350016, free=3136847872, active=25971789824, inactive=34514595840, buffers=136404992, cached=34111094784, shared=1021571072, slab=1518297088, ) ), ) patch_psutil_disk_usage = patch("psutil.disk_usage", Mock(side_effect=fake_disk_usage)) # assumes that each shell command is called in only one way cmd_to_output = { "nvidia-smi": ( b"uuid, name, compute_mode, pstate, temperature.gpu, utilization.memory [%], memory.total [MiB], driver_version\n" b"GPU-UUID-1, NVIDIA GeForce RTX 2060, Default, P8, 47, 6 %, 6144 MiB, 525.116.04\n" b"GPU-UUID-2, NVIDIA GeForce RTX 2060, Default, P8, 47, 6 %, 6144 MiB, 525.116.04\n" ), "df": ( b"Filesystem Size Used Avail Use% Mounted on\n" b"/dev/mapper/data-root 1.8T 626G 1.1T 37% /\n" b"/dev/dm-3 3.7T 1.6T 2.2T 42% /mnt/data\n" ), } patch_check_output = patch( "subprocess.check_output", Mock(side_effect=lambda args, **kwargs: cmd_to_output[args[0]]), ) with contextlib.ExitStack() as stack: for ctx in [ patch_check_output, patch_hostname, patch_psutil_Process_as_dict, patch_psutil_Process_rlimit, patch_psutil_disk_usage, patch_psutil_virtual_memory, ]: stack.enter_context(ctx) yield stack @pytest.mark.skipif(sys.platform == "darwin", reason="test requires psutil.Process.rlimit") def test_get_hostname(): with patch_system(): hostname = _get_hostname() assert hostname == "mock-hostname" @pytest.mark.skipif(sys.platform == "darwin", reason="test requires psutil.Process.rlimit") def test_get_gpu_info(): with patch_system(): gpu_info = _get_gpu_info() expected_gpu_info = { "GPU-UUID-1": { "name": "NVIDIA GeForce RTX 2060", "compute_mode": "Default", "pstate": "P8", "temperature.gpu": "47", "utilization.memory [%]": "6 %", "memory.total [MiB]": "6144 MiB", "driver_version": "525.116.04", }, "GPU-UUID-2": { "name": "NVIDIA GeForce RTX 2060", "compute_mode": "Default", "pstate": "P8", "temperature.gpu": "47", "utilization.memory [%]": "6 %", "memory.total [MiB]": "6144 MiB", "driver_version": "525.116.04", }, } assert gpu_info == expected_gpu_info @pytest.mark.skipif(sys.platform == "darwin", reason="test requires psutil.Process.rlimit") def test_get_psutil_info(): with patch_system(): psutil_info = _get_psutil_info() expected_psutil_info = { "pid": 1590579, "status": "running", "exe": "/home/winry/micromamba/envs/openfe/bin/python3.10", "cpu_percent": 0.0, "num_fds": 4, "create_time": 1690999298.62, "memory_percent": 0.02006491389254216, "memory_full_info": { "rss": 13500416, "vms": 31858688, "shared": 6946816, "text": 2121728, "lib": 0, "data": 7852032, "dirty": 0, "uss": 10764288, "pss": 10777600, "swap": 0, }, "RLIMIT_AS": (-1, -1), "virtual_memory": { "total": 67283697664, "available": 31731806208, "percent": 52.8, "used": 29899350016, "free": 3136847872, "active": 25971789824, "inactive": 34514595840, "buffers": 136404992, "cached": 34111094784, "shared": 1021571072, "slab": 1518297088, }, } assert psutil_info == expected_psutil_info @pytest.mark.skipif(sys.platform == "darwin", reason="test requires psutil.Process.rlimit") def test_get_disk_usage(): with patch_system(): disk_info = _get_disk_usage() expected_disk_info = { "/dev/mapper/data-root": { "size": "1.8T", "used": "626G", "available": "1.1T", "percent_used": "37%", "mount_point": "/", }, "/dev/dm-3": { "size": "3.7T", "used": "1.6T", "available": "2.2T", "percent_used": "42%", "mount_point": "/mnt/data", }, } assert disk_info == expected_disk_info @pytest.mark.skipif(sys.platform == "darwin", reason="test requires psutil.Process.rlimit") def test_get_disk_usage_with_path(): with patch_system(): disk_info = _get_disk_usage(paths=[pathlib.Path("/foo"), pathlib.Path("/bar")]) expected_disk_info = { "/bar": { "available": "2.1T", "percent_used": "42%", "size": "3.6T", "used": "1.5T", }, "/foo": { "available": "583.3G", "percent_used": "66%", "size": "1.8T", "used": "1.1T", }, } assert disk_info == expected_disk_info @pytest.mark.skipif(sys.platform == "darwin", reason="test requires psutil.Process.rlimit") def test_probe_system(): with patch_system(): system_info = _probe_system() expected_system_info = { "system information": { "hostname": "mock-hostname", "gpu information": { "GPU-UUID-1": { "name": "NVIDIA GeForce RTX 2060", "compute_mode": "Default", "pstate": "P8", "temperature.gpu": "47", "utilization.memory [%]": "6 %", "memory.total [MiB]": "6144 MiB", "driver_version": "525.116.04", }, "GPU-UUID-2": { "name": "NVIDIA GeForce RTX 2060", "compute_mode": "Default", "pstate": "P8", "temperature.gpu": "47", "utilization.memory [%]": "6 %", "memory.total [MiB]": "6144 MiB", "driver_version": "525.116.04", }, }, "psutil information": { "pid": 1590579, "status": "running", "exe": "/home/winry/micromamba/envs/openfe/bin/python3.10", "cpu_percent": 0.0, "num_fds": 4, "create_time": 1690999298.62, "memory_percent": 0.02006491389254216, "memory_full_info": { "rss": 13500416, "vms": 31858688, "shared": 6946816, "text": 2121728, "lib": 0, "data": 7852032, "dirty": 0, "uss": 10764288, "pss": 10777600, "swap": 0, }, "RLIMIT_AS": (-1, -1), "virtual_memory": { "total": 67283697664, "available": 31731806208, "percent": 52.8, "used": 29899350016, "free": 3136847872, "active": 25971789824, "inactive": 34514595840, "buffers": 136404992, "cached": 34111094784, "shared": 1021571072, "slab": 1518297088, }, }, "disk usage information": { "/dev/mapper/data-root": { "size": "1.8T", "used": "626G", "available": "1.1T", "percent_used": "37%", "mount_point": "/", }, "/dev/dm-3": { "size": "3.7T", "used": "1.6T", "available": "2.2T", "percent_used": "42%", "mount_point": "/mnt/data", }, }, } } assert system_info == expected_system_info def test_probe_system_smoke_test(): _probe_system() _probe_system(paths=[pathlib.Path("/")]) def test_log_system_probe_unconfigured(): # if probe loggers aren't configured to run, then we shouldn't even call # _probe_system() logger_names = [ "openfe.utils.system_probe.log", "openfe.utils.system_probe.log.gpu", "openfe.utils.system_probe.log.hostname", ] # check that initial conditions are as expected for logger_name in logger_names: logger = logging.getLogger(logger_name) assert not logger.isEnabledFor(logging.DEBUG) sysprobe_mock = Mock(return_value=EXPECTED_SYSTEM_INFO) with patch("openfe.utils.system_probe._probe_system", sysprobe_mock): log_system_probe(logging.DEBUG) assert sysprobe_mock.call_count == 0 # now check that it does get called if we use a level that will emit # (this is effectively tests that the previous assert isn't a false # positive) with patch("openfe.utils.system_probe._probe_system", sysprobe_mock): log_system_probe(logging.WARNING) assert sysprobe_mock.call_count == 1 def test_log_system_probe(caplog): # this checks that the expected contents show up in log_system_probe sysprobe_mock = Mock(return_value=EXPECTED_SYSTEM_INFO) with patch("openfe.utils.system_probe._probe_system", sysprobe_mock): with caplog.at_level(logging.DEBUG): log_system_probe() expected = [ "hostname: 'mock-hostname'", "GPU: uuid='GPU-UUID-1' NVIDIA GeForce RTX 2060 mode=Default", "GPU: uuid='GPU-UUID-2' NVIDIA GeForce RTX 2060 mode=Default", "Memory used: 27.8G (52.8%)", "/dev/mapper/data-root: 37% full (1.1T free)", "/dev/dm-3: 42% full (2.2T free)", ] for line in expected: assert line in caplog.text @pytest.mark.parametrize( "error_type,expected", [ (FileNotFoundError, "nvidia-smi command not found"), (subprocess.CalledProcessError(returncode=6, cmd="foo"), "no GPU available"), ( subprocess.CalledProcessError(returncode=9, cmd="foo"), "can't communicate with NVIDIA driver", ), ( subprocess.CalledProcessError(returncode=42, cmd="foo"), "command foo returned error code 42", ), ], ) def test_nvidia_smi_error(error_type, expected, caplog): with caplog.at_level(logging.DEBUG): with patch("subprocess.check_output", side_effect=error_type): assert _get_gpu_info() == {} assert expected in caplog.text ================================================ FILE: src/openfe/tests/utils/test_visualization_3D.py ================================================ import pytest from openff.utilities.testing import skip_if_missing from openfe.setup import LigandAtomMapping from openfe.utils.visualization_3D import view_components_3d, view_mapping_3d @pytest.fixture(scope="module") def maps(): MAPS = { "phenol": {0: 0, 1: 1, 2: 2, 3: 3, 4: 4, 5: 5, 6: 6, 7: 7, 8: 8, 9: 9, 10: 12, 11: 11}, "anisole": {0: 5, 1: 6, 2: 7, 3: 8, 4: 9, 5: 10, 6: 11, 7: 12, 8: 13, 9: 14, 10: 2, 11: 15}, } return MAPS @pytest.fixture(scope="module") def benzene_phenol_mapping(benzene_transforms, maps): mol1 = benzene_transforms["benzene"] mol2 = benzene_transforms["phenol"] mapping = maps["phenol"] return LigandAtomMapping(mol1, mol2, mapping) @skip_if_missing("py3Dmol") def test_visualize_component_coords_give_iterable(benzene_transforms): """ smoke test just checking if nothing goes horribly wrong """ components = [benzene_transforms["benzene"], benzene_transforms["phenol"]] view_components_3d(components, style="stick") @skip_if_missing("py3Dmol") def test_visualize_component_coords_give_iterable_shift(benzene_transforms): """ smoke test just checking if nothing goes horribly wrong """ components = [benzene_transforms["benzene"], benzene_transforms["phenol"]] view_components_3d(components, shift=(1, 1, 1)) @skip_if_missing("py3Dmol") def test_visualize_component_coords_reuse_view(benzene_transforms): """ smoke test just checking if nothing goes horribly wrong """ components = [benzene_transforms["benzene"], benzene_transforms["phenol"]] view = view_components_3d(components, shift=(1, 1, 1)) view_components_3d(components, view=view) @skip_if_missing("py3Dmol") def test_visualize_3D_mapping(benzene_phenol_mapping): """ smoke test just checking if nothing goes horribly wrong """ with pytest.warns(DeprecationWarning, match=r"LigandAtomMapping"): view_mapping_3d(mapping=benzene_phenol_mapping) ================================================ FILE: src/openfe/utils/__init__.py ================================================ # This code is part of OpenFE and is licensed under the MIT license. # For details, see https://github.com/OpenFreeEnergy/openfe from . import ( custom_typing, logging_control, ) from .optional_imports import requires_package from .remove_oechem import without_oechem_backend from .system_probe import log_system_probe ================================================ FILE: src/openfe/utils/atommapping_network_plotting.py ================================================ # This code is part of OpenFE and is licensed under the MIT license. # For details, see https://github.com/OpenFreeEnergy/openfe import io from typing import Dict, Tuple import matplotlib from gufe.visualization.mapping_visualization import ( draw_one_molecule_mapping, ) from rdkit import Chem from openfe import LigandNetwork, SmallMoleculeComponent from openfe.utils.custom_typing import MPL_MouseEvent from openfe.utils.network_plotting import Edge, GraphDrawing, Node class AtomMappingEdge(Edge): """Edge to draw AtomMapping from a LigandNetwork. The ``select`` and ``unselect`` methods are implemented here to force the mapped molecule to be drawn/disappear. Parameters ---------- node_artist1, node_artist2 : :class:`.Node` GraphDrawing nodes for this edge data : Dict Data dictionary for this edge. Must have key ``object``, which maps to an :class:`.AtomMapping`. """ def __init__(self, node_artist1: Node, node_artist2: Node, data: Dict): super().__init__(node_artist1, node_artist2, data) self.left_image = None self.right_image = None def _draw_mapped_molecule( self, extent: Tuple[float, float, float, float], molA: SmallMoleculeComponent, molB: SmallMoleculeComponent, molA_to_molB: Dict[int, int], ): # create the image in a format matplotlib can handle d2d = Chem.Draw.rdMolDraw2D.MolDraw2DCairo(300, 300, 300, 300) # type: ignore[attr-defined] d2d.drawOptions().setBackgroundColour((1, 1, 1, 0.7)) # TODO: use a custom draw2d object; figure size from transforms img_bytes = draw_one_molecule_mapping( molA_to_molB, molA.to_rdkit(), molB.to_rdkit(), d2d=d2d, ) img_filelike = io.BytesIO(img_bytes) # imread needs filelike img_data = matplotlib.pyplot.imread(img_filelike) ax = self.artist.axes x0, x1, y0, y1 = extent # version A: using AxesImage im = matplotlib.image.AxesImage(ax, extent=extent, zorder=10) # version B: using BboxImage # keep this commented code around for later performance checks # bounds = (x0, y0, x1 - x0, y1 - y0) # bounds = (0.2, 0.2, 0.3, 0.3) # bbox0 = matplotlib.transforms.Bbox.from_bounds(*bounds) # bbox = matplotlib.transforms.TransformedBbox(bbox0, ax.transAxes) # im = matplotlib.image.BboxImage(bbox) # set image data and register im.set_data(img_data) ax.add_artist(im) return im def _get_image_extents(self): # figure out the extent for left and right x0, x1 = self.artist.axes.get_xlim() dx = x1 - x0 left_x0, left_x1 = 0.05 * dx + x0, 0.45 * dx + x0 right_x0, right_x1 = 0.55 * dx + x0, 0.95 * dx + x0 y0, y1 = self.artist.axes.get_ylim() dy = y1 - y0 y_bottom, y_top = 0.5 * dx + y0, 0.9 * dx + y0 left_extent = (left_x0, left_x1, y_bottom, y_top) right_extent = (right_x0, right_x1, y_bottom, y_top) return left_extent, right_extent def select(self, event, graph): super().select(event, graph) mapping = self.data["object"] # figure out which node is to the left and which to the right xs = [node.xy[0] for node in self.node_artists] if xs[0] <= xs[1]: left = mapping.componentA right = mapping.componentB left_to_right = mapping.componentA_to_componentB right_to_left = mapping.componentB_to_componentA else: left = mapping.componentB right = mapping.componentA left_to_right = mapping.componentB_to_componentA right_to_left = mapping.componentA_to_componentB left_extent, right_extent = self._get_image_extents() self.left_image = self._draw_mapped_molecule(left_extent, left, right, left_to_right) self.right_image = self._draw_mapped_molecule(right_extent, right, left, right_to_left) graph.fig.canvas.draw() def unselect(self): super().unselect() for artist in [self.left_image, self.right_image]: if artist is not None: artist.remove() self.left_image = None self.right_image = None class LigandNode(Node): def _make_artist(self, x, y, dx, dy): artist = matplotlib.text.Text(x, y, self.node.name, color="blue", backgroundcolor="white") return artist def register_artist(self, ax): ax.add_artist(self.artist) @property def extent(self): txt = self.artist ext = txt.axes.transData.inverted().transform(txt.get_window_extent()) [[xmin, ymin], [xmax, ymax]] = ext return xmin, xmax, ymin, ymax @property def xy(self): return self.artist.get_position() class AtomMappingNetworkDrawing(GraphDrawing): """ Class for drawing atom mappings from a provided ligand network. Parameters ---------- graph : nx.MultiDiGraph NetworkX representation of the LigandNetwork positions : Optional[Dict[SmallMoleculeComponent, Tuple[float, float]]] mapping of node to position """ NodeCls = LigandNode EdgeCls = AtomMappingEdge def plot_atommapping_network(network: LigandNetwork): """Convenience method for plotting the atom mapping network Parameters ---------- network : :class:`.Network` the network to plot Returns ------- :class:`matplotlib.figure.Figure` : the matplotlib figure containing the interactive visualization """ fig = AtomMappingNetworkDrawing(network.graph).fig axes = fig.axes for ax in axes: ax.set_frame_on(False) # remove the black frame for t in ax.texts: t.set_clip_on(False) # do not clip the label in the network plot return fig ================================================ FILE: src/openfe/utils/custom_typing.py ================================================ # This code is part of OpenFE and is licensed under the MIT license. # For details, see https://github.com/OpenFreeEnergy/openfe from typing import TypeVar import matplotlib.axes import matplotlib.backend_bases from rdkit import Chem try: from typing import TypeAlias except ImportError: from typing_extensions import TypeAlias RDKitMol: TypeAlias = Chem.rdchem.Mol OEMol = TypeVar("OEMol") MPL_FigureCanvasBase: TypeAlias = matplotlib.backend_bases.FigureCanvasBase MPL_MouseEvent: TypeAlias = matplotlib.backend_bases.MouseEvent MPL_Axes: TypeAlias = matplotlib.axes.Axes ================================================ FILE: src/openfe/utils/ligand_utils.py ================================================ import warnings from gufe import LigandAtomMapping def get_alchemical_charge_difference(mapping: LigandAtomMapping) -> int: """ Return the difference in formal charge between stateA and stateB defined as (formal charge A - formal charge B) Parameters ---------- mapping: LigandAtomMapping The mapping between the end states A and B. Returns ------- int: The difference in formal charge between the end states. """ warnings.warn( "Use gufe.LigandAtomMapping.get_alchemical_charge_difference() instead.", DeprecationWarning ) return mapping.get_alchemical_charge_difference() ================================================ FILE: src/openfe/utils/logging_control.py ================================================ import logging from abc import ABC, abstractmethod class _BaseLogFilter(ABC): """Base class for log filters that handle string or list of strings. Parameters ---------- strings : str or list of str String(s) to use in the filter logic """ def __init__(self, strings: str | list[str]) -> None: if isinstance(strings, str): strings = [strings] self.strings: list[str] = strings @abstractmethod def filter(self, record: logging.LogRecord) -> bool: """Filter method to be implemented by subclasses. Parameters ---------- record : logging.LogRecord Log record to filter/modify Returns ------- bool True to allow the record, False to block it """ ... class _MsgIncludesStringFilter(_BaseLogFilter): """Logging filter to silence specific log messages. See https://docs.python.org/3/library/logging.html#filter-objects Parameters ---------- strings : str or list of str If string(s) match in log messages (substring match) then the log record is suppressed """ def filter(self, record: logging.LogRecord) -> bool: """Filter log records that contain any of the specified strings. Parameters ---------- record : logging.LogRecord Log record to filter Returns ------- bool False if the record should be blocked, True if it should be logged """ for string in self.strings: if string in record.msg: return False return True class _AppendMsgFilter(_BaseLogFilter): """Logging filter to append a message to a specific log message. See https://docs.python.org/3/library/logging.html#filter-objects Parameters ---------- strings : str or list of str Suffix text(s) to append to log messages """ def __init__(self, strings: str | list[str]) -> None: super().__init__(strings) # Rename for clarity in this context self.suffixes = self.strings def filter(self, record: logging.LogRecord) -> bool: """Append suffix to log record message. Parameters ---------- record : logging.LogRecord Log record to modify Returns ------- bool Always True to allow the record to be logged """ for suffix in self.suffixes: # Only modify if not already appended (idempotent) if not record.msg.endswith(suffix): record.msg = f"{record.msg}{suffix}" return True def _silence_message(msg: str | list[str], logger_names: str | list[str]) -> None: """Silence specific log messages from one or more loggers. Parameters ---------- msg : str or list of str String(s) to match in log messages (substring match) logger_names : str or list of str Logger name(s) to apply the filter to Examples -------- >>> _silence_message( ... msg="****** PyMBAR will use 64-bit JAX! *******", ... logger_names=["pymbar.timeseries", "pymbar.mbar_solvers"], ... ) """ if isinstance(logger_names, str): logger_names = [logger_names] filter_obj = _MsgIncludesStringFilter(msg) for name in logger_names: logging.getLogger(name).addFilter(filter_obj) def _silence_logger(logger_names: str | list[str], level: int = logging.CRITICAL) -> None: """Completely silence one or more loggers. Parameters ---------- logger_names : str or list of str Logger name(s) to silence level : int Set logger level (default: CRITICAL to silence everything) Examples -------- >>> _silence_logger(logger_names=["urllib3", "requests"]) """ if isinstance(logger_names, str): logger_names = [logger_names] for name in logger_names: logging.getLogger(name).setLevel(level) def _append_logger(suffix: str | list[str], logger_names: str | list[str]) -> None: """Append text to logger messages. Parameters ---------- suffix : str or list of str Suffix text to append to log messages logger_names : str or list of str Logger name(s) to modify Examples -------- >>> _append_logger(suffix=" [DEPRECATED]", logger_names="myapp") """ if isinstance(logger_names, str): logger_names = [logger_names] filter_obj = _AppendMsgFilter(suffix) for name in logger_names: logging.getLogger(name).addFilter(filter_obj) ================================================ FILE: src/openfe/utils/network_plotting.py ================================================ # This code is part of OpenFE and is licensed under the MIT license. # For details, see https://github.com/OpenFreeEnergy/openfe """ Generic tools for plotting networks. Interfaces NetworkX and matplotlib. Create subclasses of ``Node``, ``Edge``, and ``GraphDrawing`` to customize behavior how the graph is visualized or what happens on interactive events. """ from __future__ import annotations import itertools from typing import Any, Optional, Union, cast import networkx as nx from matplotlib import pyplot as plt from matplotlib.lines import Line2D from matplotlib.patches import Rectangle from openfe.utils.custom_typing import MPL_Axes, MPL_FigureCanvasBase, MPL_MouseEvent, TypeAlias ClickLocation: TypeAlias = tuple[tuple[float, float], tuple[Any, Any]] class Node: """Node in the GraphDrawing network. This connects a node in the NetworkX graph to the matplotlib artist. This is the only object that should directly use the matplotlib artist for this node. This acts as an adapter class, allowing different artists to be used, as well as enabling different functionalities. """ # TODO: someday it might be good to separate the artist adapter from the # functionality on select, etc. draggable = True pickable = False lock = None # lock used while dragging; only one Node dragged at a time def __init__(self, node, x: float, y: float, dx=0.1, dy=0.1): self.node = node self.dx = dx self.dy = dx self.artist = self._make_artist(x, y, dx, dy) self.picked = False self.press: Optional[ClickLocation] = None def _make_artist(self, x, y, dx, dy): return Rectangle((x, y), dx, dy, color="blue") def register_artist(self, ax: MPL_Axes): """Register this node's artist with the matplotlib Axes""" ax.add_patch(self.artist) @property def extent(self) -> tuple[float, float, float, float]: """extent of this node in matplotlib data coordinates""" bounds = self.artist.get_bbox().bounds return (bounds[0], bounds[0] + bounds[2], bounds[1], bounds[1] + bounds[3]) @property def xy(self) -> tuple[float, float]: """lower left (matplotlib data coordinates) position of this node""" return self.artist.xy def select(self, event: MPL_MouseEvent, graph: GraphDrawing): # -no-cov- """Set this node to its state when it is selected (clicked on)""" return def unselect(self): """Reset this node to its standard, unselected visualization""" self.artist.set(color="blue") def edge_select(self, edge: Edge): """Change node visualization when one of its edges is selected""" self.artist.set(color="red") def update_location(self, x: float, y: float): """Update the location of the underlying artist""" self.artist.set(x=x, y=y) # note: much the stuff below is based on the "Draggable rectangle" # exercise at: # https://matplotlib.org/stable/users/explain/event_handling.html#draggable-rectangle-exercise def contains(self, event: MPL_MouseEvent) -> bool: """Report whether this object contains the given event""" return self.artist.contains(event)[0] def on_mousedown(self, event: MPL_MouseEvent, graph: GraphDrawing): """Handle mousedown event (button_press_event)""" # these early returns probably won't be called in practice, since # the event handler should only call this method when those # conditions are met; still, defensive programming! if event.inaxes != self.artist.axes: return if not self.contains(event): return # record the original click location; lock that we're the only # object being dragged self.press = self.xy, (event.xdata, event.ydata) Node.lock = self # TODO: blitting def on_drag(self, event: MPL_MouseEvent, graph: GraphDrawing): """Handle dragging this node""" if event.inaxes != self.artist.axes or Node.lock is not self: return if self.press: (x0, y0), (xpress, ypress) = self.press else: # this should be impossible in practice, but mypy needed the # explicit check so it didn't unpack None raise RuntimeError("Can't drag until mouse down!") dx = event.xdata - xpress dy = event.ydata - ypress self.update_location(x0 + dx, y0 + dy) # TODO: this might be cached on mousedown edges = graph.edges_for_node(self.node) for edge in edges: edge.update_locations() # TODO: blitting self.artist.figure.canvas.draw() def on_mouseup(self, event: MPL_MouseEvent, graph: GraphDrawing): """Handle mouseup event (button_release_event)""" self.press = None Node.lock = None # TODO: blitting self.artist.figure.canvas.draw() class Edge: """Edge in the GraphDrawing network. This connects an edge in the NetworkX graph to the matplotlib artist. In addition to the edge data, this needs to know the two GraphDrawing ``Node`` instances associated with this edge. Parameters ---------- node_artist1, node_artist2 : :class:`.Node` GraphDrawing nodes for this edge data : Dict data dictionary for this edge """ pickable = True def __init__(self, node_artist1: Node, node_artist2: Node, data: dict): self.data = data self.node_artists = [node_artist1, node_artist2] self.artist = self._make_artist(node_artist1, node_artist2, data) self.picked = False def _make_artist(self, node_artist1: Node, node_artist2: Node, data: dict) -> Any: xs, ys = self._edge_xs_ys(node_artist1, node_artist2) return Line2D(xs, ys, color="black", picker=True, zorder=-1) def register_artist(self, ax: MPL_Axes): """Register this edge's artist with the matplotlib Axes""" ax.add_line(self.artist) def contains(self, event: MPL_MouseEvent) -> bool: """Report whether this object contains the given event""" return self.artist.contains(event)[0] @staticmethod def _edge_xs_ys(node1: Node, node2: Node): def get_midpoint(node): x0, x1, y0, y1 = node.extent return (0.5 * (x0 + x1), 0.5 * (y0 + y1)) midpt1 = get_midpoint(node1) midpt2 = get_midpoint(node2) xs, ys = list(zip(*[midpt1, midpt2])) return xs, ys def on_mousedown(self, event: MPL_MouseEvent, graph: GraphDrawing): """Handle mousedown event (button_press_event)""" return # -no-cov- def on_drag(self, event: MPL_MouseEvent, graph: GraphDrawing): """Handle drag event""" return # -no-cov- def on_mouseup(self, event: MPL_MouseEvent, graph: GraphDrawing): """Handle mouseup event (button_release_event)""" return # -no-cov- def unselect(self): """Reset this edge to its standard, unselected visualization""" self.artist.set(color="black") for node_artist in self.node_artists: node_artist.unselect() self.picked = False def select(self, event: MPL_MouseEvent, graph: GraphDrawing): """Mark this edge as selected, update visualization""" self.artist.set(color="red") for artist in self.node_artists: artist.edge_select(self) self.picked = True return True def update_locations(self): """Update the location of this edge based on node locations""" xs, ys = self._edge_xs_ys(*self.node_artists) self.artist.set(xdata=xs, ydata=ys) class EventHandler: """Pass event information to nodes/edges. This is the single place where we connect to the matplotlib event system. This object receives matplotlib events and delegates to the appropriate node or edge. Parameters ---------- graph : GraphDrawing the graph drawing that we're handling events for Attributes ---------- active : Optional[Union[Node, Edge]] Object activated by a mousedown event, or None if either no object activated by mousedown or if mouse is not currently pressed. This is primarily used to handle drag events. selected : Optional[Union[Node, Edge]] Object selected by a mouse click (after mouse is up), or None if no object has been selected in the graph. click_location : Optional[tuple[Optional[float], Optional[float]]] Cached location of the mousedown event, or None if mouse is up connections : List[int] list of IDs for connections to matplotlib canvas """ def __init__(self, graph: GraphDrawing): self.graph = graph self.active: Optional[Union[Node, Edge]] = None self.selected: Optional[Union[Node, Edge]] = None self.click_location: Optional[tuple[Optional[float], Optional[float]]] = None self.connections: list[int] = [] def connect(self, canvas: MPL_FigureCanvasBase): """Connect our methods to events in the matplotlib canvas""" self.connections.extend( [ canvas.mpl_connect("button_press_event", self.on_mousedown), # type: ignore canvas.mpl_connect("motion_notify_event", self.on_drag), # type: ignore canvas.mpl_connect("button_release_event", self.on_mouseup), # type: ignore ] ) def disconnect(self, canvas: MPL_FigureCanvasBase): """Disconnect all connections to the canvas.""" for cid in self.connections: canvas.mpl_disconnect(cid) self.connections = [] def _get_event_container(self, event: MPL_MouseEvent): """Identify which object should process an event. Note that we prefer nodes to edges: If you click somewhere that could be a node or an edge, it is interpreted as clicking on the node. """ containers = itertools.chain(self.graph.nodes.values(), self.graph.edges.values()) for container in containers: if container.contains(event): break else: container = None return container def on_mousedown(self, event: MPL_MouseEvent): """Handle mousedown event (button_press_event)""" self.click_location = event.xdata, event.ydata container = self._get_event_container(event) if container is None: return # cast because mypy can't tell that we did early return if None self.active = cast(Union[Node, Edge], container) self.active.on_mousedown(event, self.graph) def on_drag(self, event: MPL_MouseEvent): """Handle dragging""" if not self.active or event.inaxes != self.active.artist.axes: return self.active.on_drag(event, self.graph) def on_mouseup(self, event: MPL_MouseEvent): """Handle mouseup event (button_release_event)""" if self.click_location == (event.xdata, event.ydata): # mouse hasn't moved; call it a click # first unselect whatever was previously selected if self.selected: self.selected.unselect() # if it is a click and the active object contains it, select it; # otherwise unset selection if self.active and self.active.contains(event): self.active.select(event, self.graph) self.selected = self.active else: self.selected = None if self.active: self.active.on_mouseup(event, self.graph) self.active = None self.click_location = None self.graph.draw() class GraphDrawing: """ Base class for drawing networks with matplotlib. Connects to the matplotlib figure and to the underlying NetworkX graph. Typical use will require a subclass with custom values of ``NodeCls`` and ``EdgeCls`` to handle the specific visualization. Parameters ---------- graph : nx.MultiDiGraph NetworkX graph with information in nodes and edges to be drawn positions : Optional[Dict[Any, Tuple[float, float]]] mapping of node to position """ NodeCls = Node EdgeCls = Edge def __init__(self, graph: nx.Graph, positions=None, ax=None): # TODO: use scale to scale up the positions? self.event_handler = EventHandler(self) self.graph = graph self.nodes: dict[Node, Any] = {} self.edges: dict[tuple[Node, Node], Any] = {} if positions is None: positions = nx.nx_agraph.graphviz_layout(self.graph, prog="neato") was_interactive = plt.isinteractive() plt.ioff() if ax is None: self.fig, self.ax = plt.subplots(figsize=(8, 8)) else: self.fig, self.ax = ax.figure, ax for node, pos in positions.items(): self._register_node(node, pos) self.fig.canvas.draw() # required to get renderer for edge in graph.edges(data=True): self._register_edge(edge) self.reset_bounds() self.ax.set_aspect(1) self.ax.set_xticks([]) self.ax.set_yticks([]) if was_interactive: plt.ion() # -no-cov- self.event_handler.connect(self.fig.canvas) def _ipython_display_(self): # -no-cov- return self.fig def edges_for_node(self, node: Node) -> list[Edge]: """List of edges for the given node""" edges = list(self.graph.in_edges(node)) + list(self.graph.out_edges(node)) return [self.edges[edge] for edge in edges] def _get_nodes_extent(self): """Find the extent of all nodes (used in setting bounds)""" min_xs, max_xs, min_ys, max_ys = zip(*(node.extent for node in self.nodes.values())) return min(min_xs), max(max_xs), min(min_ys), max(max_ys) def reset_bounds(self): """Set the bounds of the matplotlib Axes to include all nodes""" # I feel like the following should be a better approach, but it # doesn't seem to work # renderer = self.fig.canvas.get_renderer() # bbox = self.ax.get_tightbbox(renderer) # trans = self.ax.transData.inverted() # [[min_x, min_y], [max_x, max_y]] = trans.transform(bbox) min_x, max_x, min_y, max_y = self._get_nodes_extent() pad_x = (max_x - min_x) * 0.05 pad_y = (max_y - min_y) * 0.05 self.ax.set_xlim(min_x - pad_x, max_x + pad_x) self.ax.set_ylim(min_y - pad_y, max_y + pad_y) def draw(self): """Draw the current canvas""" self.fig.canvas.draw() self.fig.canvas.flush_events() def _register_node(self, node: Any, position: tuple[float, float]): """Create and register ``Node`` from NetworkX node and position""" if node in self.nodes: raise RuntimeError("node provided multiple times") draw_node = self.NodeCls(node, *position) self.nodes[node] = draw_node draw_node.register_artist(self.ax) def _register_edge(self, edge: tuple[Node, Node, dict]): """Create and register ``Edge`` from NetworkX edge information""" node1, node2, data = edge draw_edge = self.EdgeCls(self.nodes[node1], self.nodes[node2], data) self.edges[(node1, node2)] = draw_edge draw_edge.register_artist(self.ax) ================================================ FILE: src/openfe/utils/optional_imports.py ================================================ """ Tools for integration with miscellaneous non-required packages. shamelessly borrowed from openff.toolkit """ # don't format vendored code # fmt: off import functools from typing import Callable def requires_package(package_name: str) -> Callable: """ Helper function to denote that a function requires some optional dependency. A function decorated with this decorator will raise `MissingDependencyError` if the package is not found by `importlib.import_module()`. Parameters ---------- package_name : str The directory path to enter within the context Raises ------ MissingDependencyError """ def test_import_for_require_package(function: Callable) -> Callable: @functools.wraps(function) def wrapper(*args, **kwargs): import importlib try: importlib.import_module(package_name) except (ImportError, ModuleNotFoundError): raise ImportError(function.__name__ + " requires package: " + package_name) except Exception as e: raise e return function(*args, **kwargs) return wrapper return test_import_for_require_package ================================================ FILE: src/openfe/utils/remove_oechem.py ================================================ # This code is part of OpenFE and is licensed under the MIT license. # For details, see https://github.com/OpenFreeEnergy/openfe from contextlib import contextmanager from openff.toolkit import GLOBAL_TOOLKIT_REGISTRY, OpenEyeToolkitWrapper from openff.toolkit.utils.toolkit_registry import ToolkitUnavailableException @contextmanager def without_oechem_backend(): """For temporarily removing oechem from openff's toolkit registry""" current_toolkits = [type(tk) for tk in GLOBAL_TOOLKIT_REGISTRY.registered_toolkits] try: GLOBAL_TOOLKIT_REGISTRY.deregister_toolkit(OpenEyeToolkitWrapper()) except ToolkitUnavailableException: pass try: yield None finally: # this is order dependent; we want to prepend OEChem back to first while GLOBAL_TOOLKIT_REGISTRY.registered_toolkits: GLOBAL_TOOLKIT_REGISTRY.deregister_toolkit( GLOBAL_TOOLKIT_REGISTRY.registered_toolkits[0] ) for tk in current_toolkits: GLOBAL_TOOLKIT_REGISTRY.register_toolkit(tk) ================================================ FILE: src/openfe/utils/silence_root_logging.py ================================================ import contextlib import logging @contextlib.contextmanager def silence_root_logging(): """Context manager to silence logging from root logging handlers. a.k.a, "Why are you using basicConfig during import -- or in library code at all?" """ root = logging.getLogger() old_handlers = list(root.handlers) for handler in old_handlers: root.removeHandler(handler) null = logging.NullHandler() root.addHandler(null) try: yield finally: root.removeHandler(null) for handler in old_handlers: root.addHandler(handler) ================================================ FILE: src/openfe/utils/system_probe.py ================================================ import logging import os import pathlib import socket import subprocess import sys from typing import Iterable, Optional import psutil from psutil._common import bytes2human def _get_disk_usage( paths: Optional[Iterable[pathlib.Path]] = None, ) -> dict[str, dict[str, str]]: """ Get disk usage information for all filesystems or specified paths. Parameters ---------- paths : Optional[Iterable[pathlib.Path]], default=None An optional iterable of `pathlib.Path` objects representing specific paths for which the disk usage information is required. If not provided (or set to None), the function retrieves disk usage information for all filesystems mounted on the system. Returns ------- dict[str, dict[str, str]] A dictionary with filesystem names as keys and dictionaries containing disk usage information as values. Notes ----- This function uses the 'df' command-line utility to gather disk usage information for all filesystems mounted on the system. The output is then processed to extract relevant information. The returned dictionary has filesystem names (or paths) as keys, and each corresponding value is a dictionary containing the following disk usage information: - 'size': The total size of the filesystem. - 'used': The used space on the filesystem. - 'available': The available space on the filesystem. - 'percent_used': Percentage of the filesystem's space that is currently in use. - 'mount_point': The mount point directory where the filesystem is mounted. This key will not be present if the "paths" argument is used. Note that the disk space values are represented as strings, which include units (e.g., 'G' for gigabytes, 'M' for megabytes). The function decodes the 'df' command's output using 'utf-8'. Raises ------ subprocess.CalledProcessError If the 'df' command execution fails or returns a non-zero exit code. OSError If an operating system-related error occurs during the 'df' command execution. Returns an empty dictionary if the 'df' command output is empty or cannot be processed. Examples -------- >>> _get_disk_usage() { '/dev/sda1': { 'size': '30G', 'used': '15G', 'available': '14G', 'percent_used': '52%', 'mount_point': '/' }, '/dev/sda2': { 'size': '100G', 'used': '20G', 'available': '80G', 'percent_used': '20%', 'mount_point': '/home' }, ... } """ disk_usage_dict: dict[str, dict[str, str]] = {} if paths: for path in paths: usage_info = psutil.disk_usage(str(path))._asdict() disk_usage_dict[str(path)] = { "available": bytes2human(usage_info["free"]), "percent_used": f"{round(usage_info['percent'])}%", "size": bytes2human(usage_info["total"]), "used": bytes2human(usage_info["used"]), } return disk_usage_dict else: output = subprocess.check_output(["df", "-h"]).decode("utf-8") lines = output.strip().split(os.linesep) lines = lines[1:] for line in lines: columns = line.split() filesystem = columns[0] size = columns[1] used = columns[2] available = columns[3] percent_used = columns[4] mount_point = columns[5] disk_usage_dict[filesystem] = { "size": size, "used": used, "available": available, "percent_used": percent_used, "mount_point": mount_point, } return disk_usage_dict def _get_psutil_info() -> dict[str, dict[str, str]]: """ Get process information using the psutil library. Returns ------- dict[str, dict[str, str]] A dictionary containing various process information. Notes ----- This function utilizes the psutil library to retrieve information about the current process and system memory. The returned dictionary includes the following process information: - 'cpu_percent': The percentage of CPU usage by the current process. - 'create_time': The timestamp indicating the process creation time. - 'exe': The absolute path to the executable file associated with the process. - 'memory_full_info': A dictionary containing detailed memory information about the process. - 'memory_percent': The percentage of memory usage by the current process. - 'num_fds': The number of file descriptors used by the process. - 'pid': The Process ID (PID) of the current process. - 'status': The current status of the process (e.g., 'running', 'sleeping', 'stopped'). Additionally, the dictionary includes the following system memory information: - 'RLIMIT_AS': The maximum size of the process's virtual memory. - 'virtual_memory': A dictionary containing various virtual memory statistics for the system. Note that the memory-related values are represented as strings, which include units (e.g., 'MB', 'GB'). Note that RLIMIT_AS key will be missing when this function is executed on macOS systems. Raises ------ NoSuchProcess If the process with the specified PID (Process ID) does not exist or is not running. AccessDenied If access to the process information is denied due to permission restrictions. Examples -------- >>> _get_psutil_info() { "memory_percent": 0.019870108903294176, "exe": "/usr/bin/python3.10", "pid": 1531909, "cpu_percent": 0.0, "create_time": 1690995569.42, "memory_full_info": { "rss": 13369344, "vms": 31834112, "shared": 6815744, "text": 2121728, "lib": 0, "data": 7827456, "dirty": 0, "uss": 10633216, "pss": 10646528, "swap": 0, }, "status": "running", "num_fds": 4, "RLIMIT_AS": (-1, -1), "virtual_memory": { "total": 67283697664, "available": 32223358976, "percent": 52.1, "used": 29410000896, "free": 3407593472, "active": 33954336768, "inactive": 26209050624, "buffers": 144347136, "cached": 34321756160, "shared": 1021435904, "slab": 1520009216, }, } """ p = psutil.Process() with p.oneshot(): info = p.as_dict( attrs=[ "cpu_percent", "create_time", "exe", "memory_full_info", "memory_percent", "num_fds", "pid", "status", ] ) # OSX doesn't have rlimit for Process if sys.platform != "darwin": RLIMIT_AS = p.rlimit(psutil.RLIMIT_AS) info["RLIMIT_AS"] = RLIMIT_AS # The maximum size of the process's virtual memory mem = psutil.virtual_memory() # memory_full_info is a named tuple, and we need to dict-ify it mem_full_info = info["memory_full_info"]._asdict() info["memory_full_info"] = mem_full_info info["virtual_memory"] = mem._asdict() return info def _get_hostname() -> str: """ Get the hostname of the current system. Returns ------- str The hostname of the system. Notes ----- This function uses the 'socket' library to retrieve the hostname of the current system. The returned hostname is a string representing the name of the system within a network. Raises ------ socket.error If an error occurs while trying to fetch the hostname. Examples -------- >>> _get_hostname() 'winry-comp' """ return socket.gethostname() def _get_gpu_info() -> dict[str, dict[str, str]]: """ Get GPU information using the 'nvidia-smi' command-line utility. Returns ------- dict[str, dict[str, str]] A dictionary with GPU UUIDs as keys and dictionaries containing GPU information as values. Notes ----- This function queries the NVIDIA System Management Interface ('nvidia-smi') to retrieve information about the available GPUs on the system. The returned dictionary includes the following GPU information for each detected GPU: - 'gpu_name': The name of the GPU. - 'compute_mode': The compute mode of the GPU. - 'pstate': The current performance state of the GPU. - 'temperature.gpu': The temperature of the GPU. - 'utilization.memory': The memory utilization of the GPU. - 'memory.total': The total memory available on the GPU. - 'driver_version': The version of the installed NVIDIA GPU driver. The GPU information is extracted from the output of the 'nvidia-smi' command, which is invoked with specific query parameters. The output is then parsed as CSV, and the relevant information is stored in the dictionary. Note that the GPU information values are represented as strings. Note that if no GPU is detected, an empty dictionary is returned. Examples -------- >>> _get_gpu_info() { 'GPU-UUID-1': { 'name': 'NVIDIA GeForce RTX 3080', 'compute_mode': 'Default', 'pstate': 'P0', 'temperature.gpu': '78 C', 'utilization.memory [%]': '50 %', 'memory.total [MiB]': '10.7 GB', 'driver_version': '470.57.02', }, 'GPU-UUID-2': { 'name': 'NVIDIA GeForce GTX 1660 Ti', 'compute_mode': 'Default', 'pstate': 'P2', 'temperature.gpu': '65 C', 'utilization.memory [%]': '30 %', 'memory.total [MiB]': '5.8 GB', 'driver_version': '470.57.02', }, ... } """ GPU_QUERY = ( "--query-gpu=gpu_uuid,gpu_name,compute_mode,pstate,temperature.gpu," "utilization.memory,memory.total,driver_version," ) try: nvidia_smi_output = subprocess.check_output( ["nvidia-smi", GPU_QUERY, "--format=csv"] ).decode("utf-8") except FileNotFoundError: logging.debug( "Error: nvidia-smi command not found. Make sure NVIDIA drivers are" " installed, this is expected if there is no GPU available" ) return {} except subprocess.CalledProcessError as e: match e.returncode: case 6: logging.debug("Error: no GPU available") return {} case 9: logging.debug("Error: can't communicate with NVIDIA driver") return {} case _: # New error code we haven't ran into before # Dump full error to debug log logging.debug( f"command {e.cmd} returned error code {e.returncode} {e.output=} {e.stdout=} {e.stderr=}" ) return {} nvidia_smi_output_lines = nvidia_smi_output.strip().split(os.linesep) header = nvidia_smi_output_lines[0].split(",") # Parse each line as CSV and build the dictionary # Skip the header gpu_info: dict[str, dict] = {} for line in nvidia_smi_output_lines[1:]: data = line.split(",") # Get UUID of GPU gpu_uuid = data[0].strip() gpu_info[gpu_uuid] = {} # Stuff info we asked for into dict with UUID as key for i in range(1, len(header)): field_name = header[i].strip() gpu_info[gpu_uuid][field_name] = data[i].strip() return gpu_info def _probe_system(paths: Optional[Iterable[pathlib.Path]] = None) -> dict: """ Probe the system and gather various system information. Returns ------- dict A dictionary containing system information. Notes ----- This function gathers information about the system by calling several internal functions. The returned dictionary contains the following system information: - 'system information': A dictionary containing various system-related details. - 'hostname': The hostname of the current system. - 'gpu information': GPU information retrieved using the '_get_gpu_info' function. - 'psutil information': Process and memory-related information obtained using the '_get_psutil_info' function. - 'disk usage information': Disk usage details for all filesystems, obtained through the '_get_disk_usage' function. Each nested dictionary provides specific details about the corresponding system component. Examples -------- >>> _probe_system() { "system information": { "hostname": "winry-comp", "gpu information": { "GPU-5b97c87b-4646-cfdd-efd6-3ee9bb3b371d": { "name": "NVIDIA GeForce RTX 2060", "compute_mode": "Default", "pstate": "P0", "temperature.gpu": "48", "utilization.memory [%]": "0 %", "memory.total [MiB]": "6144 MiB", "driver_version": "525.116.04", } }, "psutil information": { "exe": "/home/winry/micromamba/envs/openfe/bin/python3.10", "memory_percent": 0.02006491389254216, "create_time": 1690996699.21, "status": "running", "pid": 1549447, "num_fds": 4, "memory_full_info": { "rss": 13500416, "vms": 31850496, "shared": 6946816, "text": 2121728, "lib": 0, "data": 7843840, "dirty": 0, "uss": 10752000, "pss": 10765312, "swap": 0, }, "cpu_percent": 0.0, "RLIMIT_AS": (-1, -1), "virtual_memory": { "total": 67283697664, "available": 31865221120, "percent": 52.6, "used": 29719117824, "free": 2608443392, "active": 34446774272, "inactive": 26320441344, "buffers": 168124416, "cached": 34788012032, "shared": 1069752320, "slab": 1520705536, }, }, "disk usage information": { "/dev/mapper/data-root": { "size": "1.8T", "used": "626G", "available": "1.1T", "percent_used": "37%", "mount_point": "/", }, "/dev/dm-3": { "size": "3.7T", "used": "1.6T", "available": "2.2T", "percent_used": "42%", "mount_point": "/mnt/data", }, }, } } """ hostname = _get_hostname() gpu_info = _get_gpu_info() psutil_info = _get_psutil_info() disk_usage_info = _get_disk_usage(paths) return { "system information": { "hostname": hostname, "gpu information": gpu_info, "psutil information": psutil_info, "disk usage information": disk_usage_info, } } def log_system_probe(level=logging.DEBUG, paths: Optional[Iterable[os.PathLike]] = None): """Print the system information via configurable logging. This creates a logger tree under "{__name__}.log", allowing one to turn on/off logging of GPU info or hostname info the with "{__name__}.log.gpu" and "{__name__}.log.hostname" loggers. """ if paths is None: paths = [] pl_paths = (pathlib.Path(p) for p in paths) basename = __name__ + ".log" base = logging.getLogger(basename) gpu = logging.getLogger(basename + ".gpu") hostname = logging.getLogger(basename + ".hostname") loggers = [base, gpu, hostname] if any(logger.isEnabledFor(level) for logger in loggers): sysinfo = _probe_system(pl_paths)["system information"] base.log(level, "SYSTEM CONFIG DETAILS:") hostname.log(level, f"hostname: '{sysinfo['hostname']}'") if gpuinfo := sysinfo["gpu information"]: for uuid, gpu_card in gpuinfo.items(): gpu.log( level, f"GPU: {uuid=} {gpu_card['name']} mode={gpu_card['compute_mode']}", ) # gpu.log(level, f"CUDA driver: {...}") # gpu.log(level, f"CUDA toolkit: {...}") else: # -no-cov- gpu.log(level, "CUDA-based GPU not found") psutilinfo = sysinfo["psutil information"] memused = psutilinfo["virtual_memory"]["used"] mempct = psutilinfo["virtual_memory"]["percent"] base.log(level, f"Memory used: {bytes2human(memused)} ({mempct}%)") for diskdev, disk in sysinfo["disk usage information"].items(): base.log( level, f"{diskdev}: {disk['percent_used']} full ({disk['available']} free)", ) if __name__ == "__main__": from pprint import pprint pprint(_probe_system()) ================================================ FILE: src/openfe/utils/visualization_3D.py ================================================ import warnings from typing import Dict, Iterable, Optional, Tuple, Union import numpy as np from matplotlib import pyplot as plt from matplotlib.colors import rgb2hex from numpy.typing import NDArray from rdkit import Chem from rdkit.Geometry.rdGeometry import Point3D try: import py3Dmol except ImportError: pass # Don't throw error, will happen later from gufe.components.explicitmoleculecomponent import ExplicitMoleculeComponent from gufe.mapping import AtomMapping from openfe.utils import requires_package def _get_max_dist_in_x(atom_mapping: AtomMapping) -> float: """helper function find the correct mol shift, so no overlap happens in vis Returns ------- float maximal size of mol in x dimension """ posA = atom_mapping.componentA.to_rdkit().GetConformer().GetPositions() posB = atom_mapping.componentB.to_rdkit().GetConformer().GetPositions() max_d = [] for pos in [posA, posB]: d = np.zeros(shape=(len(pos), len(pos))) for i, pA in enumerate(pos): for j, pB in enumerate(pos[i:], start=i): d[i, j] = (pB - pA)[0] max_d.append(np.max(d)) estm = float(np.round(max(max_d), 1)) return estm if (estm > 5) else 5 def _translate(mol, shift: Union[Tuple[float, float, float], NDArray[np.float64]]): """ shifts the molecule by the shift vector Parameters ---------- mol : Chem.Mol rdkit mol that get shifted shift : Tuple[float, float, float] shift vector Returns ------- Chem.Mol shifted Molecule (copy of original one) """ mol = Chem.Mol(mol) conf = mol.GetConformer() for i, atom in enumerate(mol.GetAtoms()): x, y, z = conf.GetAtomPosition(i) point = Point3D(x + shift[0], y + shift[1], z + shift[2]) conf.SetAtomPosition(i, point) return mol def _add_spheres(view: py3Dmol.view, mol1: Chem.Mol, mol2: Chem.Mol, mapping: Dict[int, int]): """ will add spheres according to mapping to the view. (inplace!) Parameters ---------- view : py3Dmol.view view to be edited mol1 : Chem.Mol molecule 1 of the mapping mol2 : Chem.Mol molecule 2 of the mapping mapping : Dict[int, int] mapping of atoms from mol1 to mol2 """ # Get colourmap of size mapping cmap = plt.get_cmap("hsv", len(mapping)) for i, pair in enumerate(mapping.items()): p1 = mol1.GetConformer().GetAtomPosition(pair[0]) p2 = mol2.GetConformer().GetAtomPosition(pair[1]) color = rgb2hex(cmap(i)) view.addSphere( { "center": {"x": p1.x, "y": p1.y, "z": p1.z}, "radius": 0.6, "color": color, "alpha": 0.8, } ) view.addSphere( { "center": {"x": p2.x, "y": p2.y, "z": p2.z}, "radius": 0.6, "color": color, "alpha": 0.8, } ) @requires_package("py3Dmol") def view_components_3d( mols: Iterable[ExplicitMoleculeComponent], style: Optional[str] = "stick", shift: Optional[Tuple[float, float, float]] = None, view: py3Dmol.view = None, ) -> py3Dmol.view: """visualize multiple component coordinates in one interactive view. It helps to understand how the components are aligned in the system to each other. py3Dmol is an optional dependency, it can be installed with: pip install py3Dmol Parameters ---------- mols : Iterable[ExplicitMoleculeComponent] collection of components style : Optional[str], optional py3Dmol style, by default "stick" shift : Tuple of floats, optional Amount to i*shift each mols_i in order to allow inspection of them in heavy overlap cases. view : py3Dmol, optional Allows to pass an already existing view, by default None Returns ------- py3Dmol.view view containing all component coordinates """ if view is None: view = py3Dmol.view(width=600, height=600) for i, component in enumerate(mols): mol = Chem.Mol(component.to_rdkit()) if shift is not None: tmp_shift = np.array(shift, dtype=np.float64) * i mol = _translate(mol, tmp_shift) view.addModel(Chem.MolToMolBlock(mol)) view.setStyle({style: {}}) view.zoomTo() return view @requires_package("py3Dmol") def view_mapping_3d( mapping: AtomMapping, spheres: Optional[bool] = True, show_atomIDs: Optional[bool] = False, style: Optional[str] = "stick", shift: Optional[Union[Tuple[float, float, float], NDArray[np.float64]]] = None, ) -> py3Dmol.view: """ Render relative transformation edge in 3D using py3Dmol. By default matching atoms will be annotated using colored spheres. py3Dmol is an optional dependency, it can be installed with: pip install py3Dmol Parameters ---------- mapping : LigandAtomMapping The ligand transformation edge to visualize. spheres : bool, optional Whether or not to show matching atoms as spheres. show_atomIDs: bool, optional Whether or not to show atom ids in the mapping visualization style : str, optional Style in which to represent the molecules in py3Dmol. shift : Tuple of floats, optional Amount to shift molB by in order to visualize the two ligands. If None, the default shift will be estimated as the largest intraMol distance of both mols. Returns ------- view : py3Dmol.view View of the system containing both molecules in the edge. """ warnings.warn( "view_mapping_3d is deprecated, please use the class method LigandAtomMapping.view_3d() instead.", DeprecationWarning, ) if shift is None: shift = np.array([_get_max_dist_in_x(mapping) * 1.5, 0, 0]) else: shift = np.array(shift) molA = mapping.componentA.to_rdkit() molB = mapping.componentB.to_rdkit() # 0 * shift is the centrepoint # shift either side of the mapping +- a shift to clear the centre view lmol = _translate(molA, -1 * shift) rmol = _translate(molB, +1 * shift) view = py3Dmol.view(width=600, height=600) view.addModel(Chem.MolToMolBlock(lmol), "molA") view.addModel(Chem.MolToMolBlock(rmol), "molB") if spheres: _add_spheres(view, lmol, rmol, mapping.componentA_to_componentB) if show_atomIDs: view.addPropertyLabels( "index", {"not": {"resn": ["molA_overlay", "molA_overlay"]}}, { "fontColor": "black", "font": "sans-serif", "fontSize": "10", "showBackground": "false", "alignment": "center", }, ) # middle fig view.addModel(Chem.MolToMolBlock(molA), "molA_overlay") view.addModel(Chem.MolToMolBlock(molB), "molB_overlay") view.setStyle({style: {}}) view.zoomTo() return view ================================================ FILE: src/openfecli/README.md ================================================ # Contributing CLI Subcommands Adding a new subcommand to the `openfe` CLI is pretty straightforward, but there are some best practices that will make your contribution easier to maintain. ## How the CLI finds subcommands Subcommands are registered with the CLI based on the existence of an instance of `CommandPlugin` in modules located in particular directories or namespaces. This means that after you create the command function, you need to wrap it in a `CommandPlugin`, which must be assigned to a variable name. The variable name itself is unimportant (I usually use `PLUGIN`). It's perfectly fine to include more than one plugin in the same file, but the each must have a different variable name. The allowed locations for command plugins may change, but currently includes: * modules located in the namespace `openfecli.commands` When contributing to the core CLI, all you need to do is add your subcommand module to the `openfecli/commands/` directory, and the CLI should register it automatically. ## Best practices ### The CLI should be a thin wrapper around the library The intent of the CLI is to provide convenient ways of accomplishing things that can also be accomplished with the core library. This means that CLI commands should be thin wrappers that either just call a method from the core library, or run a very simple workflow based on methods from the core library. If you find that your CLI command starts to have some more complex logic, this probably means that some of that logic would be beneficial to users of the library as well. Consider moving that code into the core library. This also implies that we can split any CLI subcommand into two stages: 1. Convert from user input to objects that have meaning to the library. 2. Run some code as if we were users of the library, with no reference to the fact that the inputs came from the command line. ### Divide the subcommand module into three components The recommended way of structuring a subcommand module is to split it into three parts (where `command` is replaced by the name of your subcommand): 1. `command`: The command method, which is decorated by `@click.command`. The purpose of this method is to convert user input to objects that can be used by the core library. Then it calls the `command_main` method. 2. `command_main`: The workflow method, which is written using code from the underlying library, with no reference to the fact that this is part of the CLI. This typically contains a very simple workflow script. Although the output from this process is usually saved to some output file as part of the script in `command_main`, the best practice is to also return the result of this method. The `command` method will ignore this return value, but returning it makes it so that the `command_main` method can be reused in other CLI commands to create more complex workflows. 3. `PLUGIN`: a `CommandPlugin` instance, which wraps the `command` object with metadata about the subcommand, such as which help section to display it in, and which versions of the library and CLI the plugin is compatible with. As an example, here's a rough skeleton for a subcommand called `my_command` (imports excluded) ```python @click.command("my_command", short_help="This is my command") ... # add decorators for arguments/options def my_command(...): # input params are based on arguments options """Docstring here is the help given by ``openfe my-command --help``""" ... # do whatever you need to convert the user input to library objects my_command_main(...) # takes library objects def my_command_main(...): # takes library objects ... # run some simple library code return result PLUGIN = CommandPlugin( command=my_command, section="My Section", requires_lib=(1, 0), requires_cli=(1, 0) ) ``` ### Use reusable subcommand arguments/options In `click`, command-line arguments and options are declared by attaching decorators for each option to a method. The method must then take parameters based on the option name as specified by the decorator. Because of this, it is straightforward to create an object associated with a given input option/argument, which contains details such as the help string and even a method to get a library object from the user input string. The best practice is to create this object outside a given subcommand, and then reuse it between different subcommands. This ensures that the user sees consistency in the interface and behavior between different CLI subcommands. Details on how we'll do this in OpenFE are still being developed. ### Delay slow imports Usually in Python, we put all imports at the top of a file. That is the best practice for libraries and scripts, because it makes it easy for a developer to find dependencies, and helps prevent developers from repeating import statements. However, when dealing with a CLI script like this, it's important to remember that some user interactions, such as subcommand autocomplete or enquiring about the CLI with `--version` or `--help`, will also run any top-level imports. If imports are slow, then these user-facing interactions will be slow. Because of this, the best practice when writing CLI subcommands is to move slow imports inside the method that needs them. ### Testing your subcommand Dividing the subcommand as recommended above facilitates testing. When testing the `command` method itself, mock out the `command_main`, and use tools within `click` to mock the user command inputs. The purpose of testing the `command` method is to ensure that you correctly convert from user input to library object. The purpose of testing the `command_main` method is to ensure that integration with the library works. If this is truly a thin wrapper (and with the assumption that the core library is thoroughly tested), then a smoke test may be sufficient for `command_main`. ================================================ FILE: src/openfecli/__init__.py ================================================ # This code is part of OpenFE and is licensed under the MIT license. # For details, see https://github.com/OpenFreeEnergy/openfe from importlib.metadata import version from . import commands from .plugins import OFECommandPlugin __version__ = version("openfe") ================================================ FILE: src/openfecli/cli.py ================================================ # This code is part of OpenFE and is licensed under the MIT license. # For details, see https://github.com/OpenFreeEnergy/openfe import logging.config import pathlib import click from plugcli.cli import CLI, CONTEXT_SETTINGS from plugcli.plugin_management import FilePluginLoader import openfecli from openfecli.plugins import OFECommandPlugin class OpenFECLI(CLI): # COMMAND_SECTIONS = ["Setup", "Simulation", "Orchestration", "Analysis"] COMMAND_SECTIONS = ["Network Planning", "Quickrun Executor", "Miscellaneous"] def get_loaders(self): commands = str(pathlib.Path(__file__).parent.resolve() / "commands") loader = FilePluginLoader(commands, OFECommandPlugin) return [loader] def get_installed_plugins(self): loader = self.get_loaders()[0] return list(loader()) _MAIN_HELP = """ A command line interface to provide access to basic functionality of the openfe Python library. """ @click.command(cls=OpenFECLI, name="openfe", help=_MAIN_HELP, context_settings=CONTEXT_SETTINGS) @click.version_option(version=openfecli.__version__) @click.option( "--log", type=click.Path(exists=True, readable=True), help="logging configuration file", ) def main(log): # Subcommand runs after this is processed. # set logging if provided if log: logging.config.fileConfig(log, disable_existing_loggers=False) if __name__ == "__main__": # -no-cov- (useful in debugging) main() ================================================ FILE: src/openfecli/clicktypes/__init__.py ================================================ from .hyphenchoice import HyphenAwareChoice ================================================ FILE: src/openfecli/clicktypes/hyphenchoice.py ================================================ import click def _normalize_to_hyphen(string): return string.replace("_", "-") class HyphenAwareChoice(click.Choice): def __init__(self, choices, case_sensitive=True): choices = [_normalize_to_hyphen(choice) for choice in choices] super().__init__(choices, case_sensitive) def convert(self, value, param, ctx): value = _normalize_to_hyphen(value) return super().convert(value, param, ctx) ================================================ FILE: src/openfecli/commands/__init__.py ================================================ ================================================ FILE: src/openfecli/commands/atommapping.py ================================================ # This code is part of OpenFE and is licensed under the MIT license. # For details, see https://github.com/OpenFreeEnergy/openfe import click from openfecli import OFECommandPlugin from openfecli.parameters import MAPPER, MOL, OUTPUT_FILE_AND_EXT def allow_two_molecules(ctx, param, value): """click callback to require that --mol is specified exactly twice""" if len(value) != 2: raise click.BadParameter("Must specify --mol exactly twice.") return value @click.command("atommapping", short_help="Check the atom mapping of a given pair of ligands") @MOL.parameter( multiple=True, callback=allow_two_molecules, required=True, help=MOL.kwargs["help"] + " Must be specified twice.", ) @MAPPER.parameter(required=True) @OUTPUT_FILE_AND_EXT.parameter(help=OUTPUT_FILE_AND_EXT.kwargs["help"] + " (PNG format)") def atommapping(mol, mapper, output): """ This provides tools for looking at a specific atommapping. """ # note that the text of the docstring will be the help when you run # `openfe atommapping --help`. molA_str, molB_str = mol molA = MOL.get(molA_str) molB = MOL.get(molB_str) mapper_cls = MAPPER.get(mapper) mapper_obj = mapper_cls() file, ext = OUTPUT_FILE_AND_EXT.get(output) if file: atommapping_visualize_main(mapper_obj, molA, molB, file, ext) else: atommapping_print_dict_main(mapper_obj, molA, molB) def generate_mapping(mapper, molA, molB): """Utility method to extract a single mapping from a mapper. Parameters ---------- mapper : :class:`.LigandAtomMapper` the mapper to use to generate the mapping molA, molB : :class:`.SmallMoleculeComponent` molecules to map between Returns ------ :class:`.LigandAtomMapping` : the mapping generated by the mapper; errors if there is not exactly one mapping generated """ mappings = list(mapper.suggest_mappings(molA, molB)) if len(mappings) != 1: raise click.UsageError( f"Found {len(mappings)} mappings; this command requires a mapper " "to provide exactly 1 mapping" ) return mappings[0] def atommapping_print_dict_main(mapper, molA, molB): """Main function for generating and printing out the mapping""" mapping = generate_mapping(mapper, molA, molB) print(mapping.componentA_to_componentB) def atommapping_visualize_main(mapper, molA, molB, file, ext): from gufe.visualization import mapping_visualization as vis from rdkit.Chem import Draw mapping = generate_mapping(mapper, molA, molB) ext_to_artist = { "png": Draw.rdMolDraw2D.MolDraw2DCairo(600, 300, 300, 300), } try: artist = ext_to_artist[ext] except KeyError: raise click.BadParameter( f"Unknown file format: '{ext}'. The following formats are " "supported: " + ", ".join([f"'{ext}'" for ext in ext_to_artist]) ) contents = vis.draw_mapping( mapping.componentA_to_componentB, mapping.componentA.to_rdkit(), mapping.componentB.to_rdkit(), d2d=artist, ) file.write(contents) PLUGIN = OFECommandPlugin( command=atommapping, section="hidden", requires_ofe=(0, 0, 1), ) ================================================ FILE: src/openfecli/commands/fetch.py ================================================ # This code is part of OpenFE and is licensed under the MIT license. # For details, see https://github.com/OpenFreeEnergy/openfe # MOVE SINGLEMODULEPLUGINLOADER UPSTREAM TO PLUGCLI import importlib import shutil import urllib import click from plugcli.cli import CLI, CONTEXT_SETTINGS from plugcli.plugin_management import CLIPluginLoader from openfecli import OFECommandPlugin from openfecli.fetching import FetchablePlugin class SingleModulePluginLoader(CLIPluginLoader): """Load plugins from a specific module""" def __init__(self, module_name, plugin_class): super().__init__( plugin_type="single_module", search_path=module_name, plugin_class=plugin_class, ) def _find_candidates(self): return [importlib.import_module(self.search_path)] @staticmethod def _make_nsdict(candidate): return vars(candidate) class FetchCLI(CLI): """Custom command class for the Fetch subcommand. This provides the command sections used in help and defines where plugins should be kept. """ COMMAND_SECTIONS = ["Tutorials"] def get_loaders(self): return [SingleModulePluginLoader("openfecli.fetchables", FetchablePlugin)] def get_installed_plugins(self): loader = self.get_loaders()[0] return list(loader()) @click.command(cls=FetchCLI, short_help="Fetch tutorial or other resource.") def fetch(): """ Fetch the given resource. Some resources require internet; others are built-in. """ PLUGIN = OFECommandPlugin( command=fetch, section="Miscellaneous", requires_ofe=(0, 7), ) if __name__ == "__main__": # it's useful to keep a main here for debugging where problems happen in # the command tree fetch() ================================================ FILE: src/openfecli/commands/gather.py ================================================ # This code is part of OpenFE and is licensed under the MIT license. # For details, see https://github.com/OpenFreeEnergy/openfe import os import pathlib import sys from typing import List, Literal import click import pandas as pd from openfecli import OFECommandPlugin from openfecli.clicktypes import HyphenAwareChoice FAIL_STR = "Error" # string used to indicate a failed run in output tables. def _get_column(val: float | int) -> int: """Determine the index (where the 0th index is the decimal) at which the first non-zero value occurs in a full-precision string representation of a value. Parameters ---------- val : float|int The raw value. Returns ------- int Column index """ import numpy as np if val == 0: return 0 log10 = np.log10(val) if log10 >= 0.0: col = np.floor(log10 + 1) else: col = np.floor(log10) return int(col) def format_estimate_uncertainty( est: float, unc: float, unc_prec: int = 1, ) -> tuple[str, str]: """ Round raw estimate and uncertainty values to the appropriate precision. The premise here is that, if you're reporting your uncertainty to a certain number of significant figures, your estimate should be reported to the same precision. As an example, assume your raw estimate is 12.34567 and your raw uncertainty is 0.0123. Say you want to report your uncertainty to 2 significant figures. So your rounded uncertainty is 0.012. You should report your estimate to the same precision, so your rounded estimate should be 12.346. On the other hand, if you wanted to report your uncertainty to the first significant figure (0.01), then you should report your estimate as 12.35. You need to report these to the same precision (not the same number of significant figures) because the two numbers need to be added together. If you report both to 2 significant figures, you'd have 12.0 +/- 0.0012, and your actual estimate falls way outside your error bars! It has to be the uncertainty that determines the precision of the estimate, because if you said you had 3 significant figures in the estimate and used that to set the precision of the uncertainty, you'd have 12.3 +/- 0.0 -- no error at all! We implement this by thinking of the decimal representation as "columns" centered on the decimal point. We get the column index of the first non-zero number in the decimal representation of the uncertainty, and use the fact that ``np.round`` rounds to the number of decimal places you give it to report the estimate. The uncertainty is rounded to the desired number of significant figures. Parameters ---------- est : float Raw estimate value. unc : float Raw uncertainty value. unc_prec : int, optional Precision, by default 1 Returns ------- tuple[str, str] The truncated raw and uncertainty values. """ import numpy as np # get the last column needed for uncertainty unc_col = _get_column(unc) - (unc_prec - 1) if unc_col < 0: est_str = f"{est:.{-unc_col}f}" unc_str = f"{unc:.{-unc_col}f}" else: est_str = f"{np.round(est, -unc_col + 1)}" unc_str = f"{np.round(unc, -unc_col + 1)}" return est_str, unc_str def format_df_with_precision( df: pd.DataFrame, est_col_name: str, unc_col_name: str, unc_prec: int = 1 ) -> pd.DataFrame: """ Returns a new DataFrame with the columns `est_col_name` and `unc_col_name` formatted as strings reported to `unc_prec` precision. The uncertainty column will be rounded to `unc_prec` precision, then the estimate column will be reported to the same precision. Any entries that are not floats (such as strings indicating errors), will not be modified. Parameters ---------- df : pd.DataFrame DataFrame to format est_col_name : str Name of the column containing estimates to format. unc_col_name : str Name of the column containing uncertainties to format. unc_prec : int, optional Precision to round the uncertainty column to, by default 1. Returns ------- pd.DataFrame DataFrame with formatted uncertainty and estimate columns. Example ------- >>> df ligand_i ligand_j DDG(i->j) (kcal/mol) uncertainty (kcal/mol) 0 lig_ejm_31 lig_ejm_42 Error Error 1 lig_ejm_31 lig_ejm_46 -0.891077 0.064825 2 lig_ejm_31 lig_ejm_47 0.023341 0.145625 3 lig_ejm_31 lig_ejm_48 0.614103 0.088704 4 lig_ejm_31 lig_ejm_50 0.999904 0.044457 5 lig_ejm_42 lig_ejm_43 1.354348 0.156009 6 lig_ejm_46 lig_jmc_23 0.294761 0.086632 7 lig_ejm_46 lig_jmc_27 -0.101737 0.100997 8 lig_ejm_46 lig_jmc_28 Error Error >>> df_out = format_df_with_precision(df, "DDG(i->j) (kcal/mol)", "uncertainty (kcal/mol)") >>> df_formatted ligand_i ligand_j DDG(i->j) (kcal/mol) uncertainty (kcal/mol) 0 lig_ejm_31 lig_ejm_42 Error Error 1 lig_ejm_31 lig_ejm_46 -0.89 0.06 2 lig_ejm_31 lig_ejm_47 0.0 0.1 3 lig_ejm_31 lig_ejm_48 0.61 0.09 4 lig_ejm_31 lig_ejm_50 1.00 0.04 5 lig_ejm_42 lig_ejm_43 1.4 0.2 6 lig_ejm_46 lig_jmc_23 0.29 0.09 7 lig_ejm_46 lig_jmc_27 -0.1 0.1 8 lig_ejm_46 lig_jmc_28 Error Error """ # find all entries in both columns that contain strings: df_is_string = df[[est_col_name, unc_col_name]].map(lambda x: isinstance(x, str)) # if either the estimate or uncertainty entries are strings, dont format no_strings_mask = ~(df_is_string[est_col_name] | df_is_string[unc_col_name]) # skip rows that contain striangs and only round and format numerical vals df_floats_formatted = df[no_strings_mask].apply( lambda row: format_estimate_uncertainty(row[est_col_name], row[unc_col_name], unc_prec), axis=1, result_type="expand", ) # explicitly cast to string to make pandas happy df[[est_col_name, unc_col_name]] = df[[est_col_name, unc_col_name]].astype(str) # if there are no floats, assigning an empty array will break things if df_floats_formatted.empty: pass else: df.loc[no_strings_mask, [est_col_name, unc_col_name]] = df_floats_formatted.values return df def is_results_json(fpath: os.PathLike | str) -> bool: """Sanity check that file is a result json before we try to deserialize""" return "estimate" in open(fpath, "r").read(20) def load_json(fpath: os.PathLike | str) -> dict: """Load a JSON file containing a gufe object. Parameters ---------- fpath : os.PathLike | str The path to a gufe-serialized JSON. Returns ------- dict A dict containing data from the results JSON. """ # TODO: move this function to openfe/utils import json from gufe.tokenization import JSON_HANDLER return json.load(open(fpath, "r"), cls=JSON_HANDLER.decoder) def _get_names(result: dict) -> tuple[str, str]: """Get the ligand names from a unit's results data. Parameters ---------- result : dict A results dict. Returns ------- tuple[str, str] Ligand names corresponding to the results. """ # TODO: I don't like this [0][0] indexing, but I can't think of a better way currently protocol_data = list(result["protocol_result"]["data"].values())[0][0] try: name_A = protocol_data["inputs"]["setup_results"]["inputs"]["ligandmapping"]["componentA"][ "molprops" ]["ofe-name"] name_B = protocol_data["inputs"]["setup_results"]["inputs"]["ligandmapping"]["componentB"][ "molprops" ]["ofe-name"] except KeyError: name_A = protocol_data["inputs"]["ligandmapping"]["componentA"]["molprops"]["ofe-name"] name_B = protocol_data["inputs"]["ligandmapping"]["componentB"]["molprops"]["ofe-name"] return str(name_A), str(name_B) def _get_type(result: dict) -> Literal["vacuum", "solvent", "complex"]: """Determine the simulation type based on the component types.""" protocol_data = list(result["protocol_result"]["data"].values())[0][0] try: component_types = [ x["__module__"] for x in protocol_data["inputs"]["setup_results"]["inputs"]["stateA"][ "components" ].values() ] except KeyError: component_types = [ x["__module__"] for x in protocol_data["inputs"]["stateA"]["components"].values() ] if ( "gufe.components.proteincomponent" in component_types or "gufe.components.solvatedpdbcomponent" in component_types or "gufe.components.proteinmembranecomponent" in component_types ): return "complex" elif "gufe.components.solventcomponent" in component_types: return "solvent" else: return "vacuum" def _legacy_get_type(res_fn: os.PathLike | str) -> Literal["vacuum", "solvent", "complex"]: # TODO: Deprecate this when we no longer rely on key names in `_get_type()` if "solvent" in res_fn: return "solvent" elif "vacuum" in res_fn: return "vacuum" # TODO: if there is no identifier in the filename, do we really want to assume it's a complex? else: return "complex" def _get_result_id( result: dict, result_fn: os.PathLike | str ) -> tuple[tuple[str, str], Literal["vacuum", "solvent", "complex"]]: """Extract the name and simulation type from a results dict. Parameters ---------- result : dict A result object result_fn : os.PathLike | str The path to deserialized results, only used if unable to extract from results dict. Returns ------- tuple Identifying information (ligand names and simulation type) for the given results data. """ ligA, ligB = _get_names(result) try: simtype = _get_type(result) except KeyError: simtype = _legacy_get_type(result_fn) # TODO: remove this and result_fn in 2.0 return (ligA, ligB), simtype def _load_valid_result_json(fpath: os.PathLike | str) -> tuple[tuple | None, dict | None]: """Load the data from a results JSON into a dict. Parameters ---------- fpath : os.PathLike | str The path to deserialized results. Returns ------- dict | None A dict containing data from the results JSON, or None if the JSON file is invalid or missing. """ # TODO: only load this once during collection, then pass namedtuple(fname, dict) into this function # for now though, it's not the bottleneck on performance result = load_json(fpath) try: result_id = _get_result_id(result, fpath) except (ValueError, IndexError): click.secho(f"{fpath}: Missing ligand names and/or simulation type. Skipping.",err=True, fg="yellow") # fmt: skip return None, None if result["estimate"] is None: click.secho(f"{fpath}: No 'estimate' found, assuming to be a failed simulation.",err=True, fg="yellow") # fmt: skip return result_id, None if result["uncertainty"] is None: click.secho(f"{fpath}: No 'uncertainty' found, assuming to be a failed simulation.",err=True, fg="yellow") # fmt: skip return result_id, None if result["unit_results"] == {}: click.secho(f"{fpath}: No 'unit_results' found, assuming to be a failed simulation.",err=True, fg="yellow") # fmt: skip return result_id, None if all("exception" in u for u in result["unit_results"].values()): click.secho(f"{fpath}: Exception found in all 'unit_results', assuming to be a failed simulation.",err=True, fg="yellow") # fmt: skip return result_id, None return result_id, result def _generate_bad_legs_error_message(bad_legs: list[tuple[set[str], tuple[str]]]) -> str: """Format output describing RBFE or RHFE legs that are missing runs. Parameters ---------- bad_legs : list[set[str], tuple[str]]] A list of tuples of (leg_types, ligpair) pairs from failed edges/legs. Returns ------- str An error message containing information on all failed legs. """ msg = ( "\nSome edge(s) are missing runs!\n" "The following edges were found but are missing one or more run types " "('solvent', 'complex', or 'vacuum') to complete the calculation:\n\n" "ligand_i\tligand_j\trun_type_found\n" ) # TODO: format this better for ligA, ligB, leg_types in bad_legs: msg += f"{ligA}\t{ligB}\t{','.join(leg_types)}\n" return msg def _get_ddgs(legs: dict, allow_partial=False) -> pd.DataFrame: import numpy as np from openfe.protocols.openmm_rfe.equil_rfe_methods import ( RelativeHybridTopologyProtocolResult as rfe_result, ) # TODO: if there's a failed edge but other valid results in a leg, ddgs will be computed # only fails if there are no valid results DDGs = [] bad_legs = [] for ligpair, vals in sorted(legs.items()): leg_types = set(vals) # drop any leg types that have no values (these are failed runs) valid_leg_types = {k for k in vals if vals[k]} DDGbind = None DDGhyd = None bind_unc = None hyd_unc = None do_rbfe = len(valid_leg_types & {"complex", "solvent"}) == 2 do_rhfe = len(valid_leg_types & {"vacuum", "solvent"}) == 2 if do_rbfe: DG1_mag = rfe_result.compute_mean_estimate(vals["complex"]) DG1_unc = rfe_result.compute_uncertainty(vals["complex"]) DG2_mag = rfe_result.compute_mean_estimate(vals["solvent"]) DG2_unc = rfe_result.compute_uncertainty(vals["solvent"]) if not ((DG1_mag is None) or (DG2_mag is None)): # DDG(2,1)bind = DG(1->2)complex - DG(1->2)solvent DDGbind = (DG1_mag - DG2_mag).m bind_unc = np.sqrt(np.sum(np.square([DG1_unc.m, DG2_unc.m]))) if do_rhfe: DG1_mag = rfe_result.compute_mean_estimate(vals["solvent"]) DG1_unc = rfe_result.compute_uncertainty(vals["solvent"]) DG2_mag = rfe_result.compute_mean_estimate(vals["vacuum"]) DG2_unc = rfe_result.compute_uncertainty(vals["vacuum"]) if not ((DG1_mag is None) or (DG2_mag is None)): DDGhyd = (DG1_mag - DG2_mag).m hyd_unc = np.sqrt(np.sum(np.square([DG1_unc.m, DG2_unc.m]))) if not do_rbfe and not do_rhfe: bad_legs.append((*ligpair, leg_types)) DDGs.append((*ligpair, None, None, None, None)) else: DDGs.append((*ligpair, DDGbind, bind_unc, DDGhyd, hyd_unc)) if bad_legs: err_msg = _generate_bad_legs_error_message(bad_legs) if allow_partial: click.secho(err_msg, err=True, fg="yellow") else: err_msg += ( "\nYou can force partial gathering of results, without " "problematic edges, by using the --allow-partial flag of the gather " "command.\nNOTE: This may cause problems with predicting " "absolute free energies from the relative free energies." ) click.secho(err_msg, err=True, fg="red") sys.exit(1) df_ddg = pd.DataFrame( DDGs, columns=["ligand_i", "ligand_j", "DDG_bind", "bind_unc", "DDG_hyd", "hyd_unc"], ) return df_ddg def _generate_ddg(legs: dict, allow_partial: bool) -> pd.DataFrame: """Compute and write out DDG values for the given legs. Parameters ---------- legs : dict Dict of legs to write out. allow_partial : bool If ``True``, no error will be thrown for incomplete or invalid results, and DDGs will be reported for whatever valid results are found. """ DDGs = _get_ddgs(legs, allow_partial=allow_partial) data = [] for _, row in DDGs.iterrows(): ligA, ligB, DDGbind, bind_unc, DDGhyd, hyd_unc = row.to_list() if not pd.isna(DDGbind): data.append((ligA, ligB, DDGbind, bind_unc)) if not pd.isna(DDGhyd): data.append((ligA, ligB, DDGhyd, hyd_unc)) elif pd.isna(DDGbind) and pd.isna(DDGhyd): data.append((ligA, ligB, FAIL_STR, FAIL_STR)) df = pd.DataFrame( data, columns=["ligand_i", "ligand_j", "DDG(i->j) (kcal/mol)", "uncertainty (kcal/mol)"], ) df_out = format_df_with_precision(df, "DDG(i->j) (kcal/mol)", "uncertainty (kcal/mol)") return df_out def _generate_raw(legs: dict, allow_partial=True) -> pd.DataFrame: """ Write out all legs found and their DG values, or indicate that they have failed. Parameters ---------- legs : dict Dict of legs to write out. allow_partial : bool, optional Unused for this function, since all results will be included. """ data = [] for ligpair, results in sorted(legs.items()): for simtype, repeats in sorted(results.items()): for repeat in repeats: for m, u in repeat: if m is None: m, u = FAIL_STR, FAIL_STR else: m, u = (m.m, u.m) data.append((simtype, ligpair[0], ligpair[1], m, u)) df = pd.DataFrame( data, columns=[ "leg", "ligand_i", "ligand_j", "DG(i->j) (kcal/mol)", "MBAR uncertainty (kcal/mol)", ], ) df_out = format_df_with_precision(df, "DG(i->j) (kcal/mol)", "MBAR uncertainty (kcal/mol)") return df_out def _check_legs_have_sufficient_repeats(legs): """Throw an error if all legs do not have 2 or more simulation repeat results""" for leg in legs.values(): for run_type, sim_results in leg.items(): if len(sim_results) < 2: msg = "ERROR: Every edge must have at least two simulation repeats" click.secho(msg, err=True, fg="red") sys.exit(1) def _generate_dg_mle(legs: dict, allow_partial: bool) -> pd.DataFrame: """Compute and write out DG values for the given legs. Parameters ---------- legs : dict Dict of legs to write out. allow_partial : bool If ``True``, no error will be thrown for incomplete or invalid results, and DGs will be reported for whatever valid results are found. """ import networkx as nx import numpy as np from cinnabar.stats import mle _check_legs_have_sufficient_repeats(legs) DDGs = _get_ddgs(legs, allow_partial=allow_partial) MLEs = [] expected_ligs = [] # perform MLE g = nx.DiGraph() nm_to_idx = {} DDGbind_count = 0 for _, row in DDGs.iterrows(): ligA, ligB, DDGbind, bind_unc, _, _ = row.to_list() for lig in (ligA, ligB): if lig not in expected_ligs: expected_ligs.append(lig) if pd.isna(DDGbind) or DDGbind == FAIL_STR: continue DDGbind_count += 1 # tl;dr this is super paranoid, but safer for now: # cinnabar seems to rely on the ordering of values within the graph # to correspond to the matrix that comes out from mle() # internally they also convert the ligand names to ints, which I think # has a side effect of giving the graph nodes a predictable order. # fwiw this code didn't affect ordering locally try: idA = nm_to_idx[ligA] except KeyError: idA = len(nm_to_idx) nm_to_idx[ligA] = idA try: idB = nm_to_idx[ligB] except KeyError: idB = len(nm_to_idx) nm_to_idx[ligB] = idB g.add_edge(idA, idB, calc_DDG=DDGbind, calc_dDDG=bind_unc) if DDGbind_count > 2: if not nx.is_weakly_connected(g): # TODO: dump the network for debugging? # TODO: use largest connected component when possible msg = ( "ERROR: The results network is disconnected due to failed or missing edges.\n" "Absolute free energies cannot be calculated in a disconnected network.\n" "Please either connect the network by addressing failed runs or adding edges.\n" "You can still compute relative free energies using the ``--report=ddg`` flag." ) click.secho(msg, err=True, fg="red") sys.exit(1) idx_to_nm = {v: k for k, v in nm_to_idx.items()} f_i, df_i = mle(g, factor="calc_DDG") df_i = np.diagonal(df_i) ** 0.5 for node, f, df in zip(g.nodes, f_i, df_i): ligname = idx_to_nm[node] MLEs.append((ligname, f, df)) else: click.secho( f"The results network has {DDGbind_count} edge(s), but 3 or more edges are required to calculate DG values.", err=True, fg="red", ) sys.exit(1) data = [] for ligA, DG, unc_DG in MLEs: data.append({"ligand": ligA, "DG(MLE) (kcal/mol)": DG, "uncertainty (kcal/mol)": unc_DG}) expected_ligs.remove(ligA) for ligA in expected_ligs: data.append({"ligand": ligA, "DG(MLE) (kcal/mol)": FAIL_STR, "uncertainty (kcal/mol)": FAIL_STR}) # fmt: skip df = pd.DataFrame(data) df_out = format_df_with_precision(df, "DG(MLE) (kcal/mol)", "uncertainty (kcal/mol)") return df_out def _collect_result_jsons(results: List[os.PathLike | str]) -> List[pathlib.Path]: """Recursively collects all results JSONs from the paths in ``results``, which can include directories and/or filepaths. """ import glob def collect_jsons(results: List[os.PathLike]): all_jsons = [] for p in results: if str(p).endswith("json"): all_jsons.append(p) elif p.is_dir(): all_jsons.extend(glob.glob(f"{p}/**/*json", recursive=True)) return all_jsons def is_results_json(fpath: os.PathLike | str) -> bool: """Sanity check that file is a result json before we try to deserialize""" return "estimate" in open(fpath, "r").read(20) results = sorted(results) # ensures reproducible output order regardless of input order # 1) find all possible jsons json_fns = collect_jsons(results) # 2) filter only result jsons result_fns = list(filter(is_results_json, json_fns)) return result_fns def _get_legs_from_result_jsons( result_fns: list[pathlib.Path], report: Literal["dg", "ddg", "raw"] ) -> dict[tuple[str, str], dict[str, list]]: """ Iterate over a list of result JSONs and populate a dict of dicts with all data needed for results processing. Parameters ---------- result_fns : list[pathlib.Path] List of filepaths containing results formatted as JSON. report : Literal["dg", "ddg", "raw"] Type of report to generate. Returns ------- legs: dict[tuple[str,str],dict[str, list]] Data extracted from the given result JSONs, organized by the leg's ligand names and simulation type. """ from collections import defaultdict legs = defaultdict(lambda: defaultdict(list)) with click.progressbar( result_fns, label="Loading results:", fill_char="▇", empty_char=" ", bar_template="%(label)s %(bar)s %(info)s files", length=len(result_fns), show_percent=False, show_pos=True, show_eta=False, ) as bar: for result_fn in bar: result_info, result = _load_valid_result_json(result_fn) if result_info is None: # this means it couldn't find names and/or simtype continue names, simtype = result_info if report.lower() == "raw": if result is None: parsed_raw_data = [(None, None)] else: parsed_raw_data = [ ( v[0]["outputs"]["unit_estimate"], v[0]["outputs"]["unit_estimate_error"], ) for v in result["protocol_result"]["data"].values() ] legs[names][simtype].append(parsed_raw_data) else: if result is None: # we want the dict name/simtype entry to exist for error reporting, even if there's no valid data dGs = [] else: dGs = [ v[0]["outputs"]["unit_estimate"] for v in result["protocol_result"]["data"].values() ] legs[names][simtype].extend(dGs) return legs def rich_print_to_stdout(df: pd.DataFrame) -> None: """Use rich to pretty print a table to stdout.""" from rich import box from rich.console import Console from rich.table import Table table = Table(box=box.SQUARE) for col in df.columns: table.add_column(col) for row_values in df.values: row = [str(val) for val in row_values] table.add_row(*row) console = Console() console.print(table) @click.command( "gather", short_help="Gather result JSONs for network of RBFE results into a TSV file.", ) @click.argument( "results", nargs=-1, # accept any number of results type=click.Path(dir_okay=True, file_okay=True, path_type=pathlib.Path), required=True, ) @click.option( "--report", type=HyphenAwareChoice(["dg", "ddg", "raw"], case_sensitive=False), default="dg", show_default=True, help=( "What data to report. 'dg' gives maximum-likelihood estimate of " "absolute deltaG, 'ddg' gives delta-delta-G, and 'raw' gives " "the raw result of the deltaG for a leg." ), ) @click.option( "output", "-o", type=click.File(mode="w"), default="-", help="Filepath at which to write the tsv report.", ) @click.option( "--tsv", is_flag=True, default=False, help=( "Results that are output to stdout will be formatted as tab-separated, " "identical to the formatting used when writing to file." "By default, the output table will be formatted for human-readability." ), ) @click.option( "--allow-partial", is_flag=True, default=False, help=( "Do not raise errors if results are missing parts for some edges. " "(Skip those edges and issue warning instead.)" ), ) def gather( results: List[os.PathLike | str], output: os.PathLike | str, report: Literal["dg", "ddg", "raw"], tsv: bool, allow_partial: bool, ): """Gather simulation result JSON files from RBFE simulations and generate a report. RESULTS is the path(s) to JSON files or directories of JSON files containing RBFE protocol results as generated by ``openfe quickrun``. All directories will be walked recursively and any valid JSON results files will be gathered. Files must end in .json to be collected, and invalid files will be ignored. The results reported depends on ``--report`` flag: \b * ``--report=dg`` (default) reports the ligand, its absolute free energy, and the associated uncertainty as the maximum likelihood estimate obtained from DDG replica averages and standard deviations. These MLE estimates are centred around 0.0, and when plotted can be shifted to match experimental values. * ``--report=ddg`` reports pairs of ligand_i and ligand_j, the calculated relative free energy DDG(i->j) = DG(j) - DG(i) and its uncertainty. * ``--report=raw`` reports the raw results, which each repeat simulation given separately (i.e. no combining of redundant simulations is performed) The output is a table of **tab** separated values. By default, this outputs to stdout, use the -o option to specify an output filepath. """ # find and filter result jsons result_fns = _collect_result_jsons(results) # pair legs of simulations together into dict of dicts legs = _get_legs_from_result_jsons(result_fns, report) if legs == {}: click.secho("No results JSON files found.", err=True) sys.exit(1) # compute report report_func = { "dg": _generate_dg_mle, "ddg": _generate_ddg, "raw": _generate_raw, }[report.lower()] df = report_func(legs, allow_partial) # write output is_output_file = isinstance(output, click.utils.LazyFile) if is_output_file: click.echo(f"writing {report} output to '{output.name}'") if is_output_file or tsv: df.to_csv(output, sep="\t", lineterminator="\n", index=False) # TODO: we can add a --pretty flag if we want this to be optional/preserve backwards compatibility else: rich_print_to_stdout(df) PLUGIN = OFECommandPlugin( command=gather, section="Quickrun Executor", requires_ofe=(0, 6), ) if __name__ == "__main__": gather() ================================================ FILE: src/openfecli/commands/gather_abfe.py ================================================ import os import pathlib import sys from typing import List, Literal import click import numpy as np import pandas as pd from openfecli import OFECommandPlugin from openfecli.clicktypes import HyphenAwareChoice from openfecli.commands.gather import ( _collect_result_jsons, format_df_with_precision, load_json, rich_print_to_stdout, ) def _get_name(result: dict) -> str: """Get the ligand name from a unit's results data. Parameters ---------- result : dict A results dict. Returns ------- str Ligand name corresponding to the results. """ solvent_data = list(result["protocol_result"]["data"]["solvent"].values())[0][0] try: name = solvent_data["inputs"]["setup_results"]["inputs"]["alchemical_components"]["stateA"][ 0 ]["molprops"]["ofe-name"] except KeyError: name = solvent_data["inputs"]["alchemical_components"]["stateA"][0]["molprops"]["ofe-name"] return str(name) def _load_valid_result_json(fpath: os.PathLike | str) -> tuple[tuple | None, dict | None]: """Load the data from a results JSON into a dict. Parameters ---------- fpath : os.PathLike | str The path to deserialized results. Returns ------- dict | None A dict containing data from the results JSON, or None if the JSON file is invalid or missing. Raises ------ ValueError If the JSON file contains an ``estimate`` or ``uncertainty`` key with the value ``None``. If """ # TODO: replace this with gather's _load_valid_result # TODO: only load this once during collection, then pass namedtuple(fname, dict) into this function # for now though, it's not the bottleneck on performance result = load_json(fpath) try: names = _get_name(result) except (ValueError, IndexError): click.secho(f"{fpath}: Missing ligand names and/or simulation type. Skipping.",err=True, fg="yellow") # fmt: skip return None, None if result["estimate"] is None: click.secho(f"{fpath}: No 'estimate' found, assuming to be a failed simulation.",err=True, fg="yellow") # fmt: skip return names, None if result["uncertainty"] is None: click.secho(f"{fpath}: No 'uncertainty' found, assuming to be a failed simulation.",err=True, fg="yellow") # fmt: skip return names, None if all("exception" in u for u in result["unit_results"].values()): click.secho(f"{fpath}: Exception found in all 'unit_results', assuming to be a failed simulation.",err=True, fg="yellow") # fmt: skip return names, None return names, result def _get_legs_from_result_jsons( result_fns: list[pathlib.Path], ) -> dict[str, dict[str, list]]: """ Iterate over a list of result JSONs and populate a dict of dicts with all data needed for results processing. Parameters ---------- result_fns : list[pathlib.Path] List of filepaths containing results formatted as JSON. report : Literal["dg", "raw"] Type of report to generate. Returns ------- legs: dict[str, dict[str, list]] Data extracted from the given result JSONs, organized by the leg's ligand name and simulation type. """ from collections import defaultdict from openff.units import unit dgs = defaultdict(lambda: defaultdict(list)) for result_fn in result_fns: name, result = _load_valid_result_json(result_fn) if name is None: # this means it couldn't find name and/or simtype continue dgs[name]["overall"].append([result["estimate"], result["uncertainty"]]) proto_key = [k for k in result["unit_results"].keys() if k.startswith("ProtocolUnitResult")] for p in proto_key: # In openfe v1.9+, we only want to pick up results from # the Analysis Unit. To ensure backwards compatibility with # prior releases of openfe v1.x, we exclude Setup and Simulation if ( "Setup" in result["unit_results"][p]["source_key"] or "Simulation" in result["unit_results"][p]["source_key"] ): continue if "unit_estimate" in result["unit_results"][p]["outputs"]: simtype = result["unit_results"][p]["outputs"]["simtype"] dg = result["unit_results"][p]["outputs"]["unit_estimate"] dg_error = result["unit_results"][p]["outputs"]["unit_estimate_error"] dgs[name][simtype].append([dg, dg_error]) if "standard_state_correction" in result["unit_results"][p]["outputs"]: corr = result["unit_results"][p]["outputs"]["standard_state_correction"] # In openfe v1.9+, standard state corrections are set to 0 kcal/mol # when no correction is being applied (e.g. no restraints). # To make raw outputs similar to pre-v1.9, we exclude corrections # if they are close to 0. if not np.isclose(corr.m, 0): dgs[name]["standard_state_correction"].append( [corr, 0 * unit.kilocalorie_per_mole] ) else: continue return dgs def _error_std(r): """ Calculate the error of the estimate as the std of the repeats """ return np.std([v[0].m for v in r["overall"]]) def _error_mbar(r): """ Calculate the error of the estimate using the reported MBAR errors. This also takes into account that repeats may have been run for this edge by using the average MBAR error """ complex_errors = np.array([x[1].m for x in r["complex"]]) solvent_errors = np.array([x[1].m for x in r["solvent"]]) return np.sqrt(np.mean(complex_errors**2) + np.mean(solvent_errors**2)) def _generate_dg(results_dict: dict[str, dict[str, list]], allow_partial: bool) -> pd.DataFrame: """Compute and write out DG values for the given results. Parameters ---------- results_dict : dict[str, dict[str, list]] Dictionary of results created by ``_get_legs_from_result_jsons``. Returns ------- pd.DataFrame A pandas DataFrame with the dG results for each ligand. """ # check the type of error which should be used based on the number of repeats n_repeats = {len(v["overall"]) for v in results_dict.values()} if 1 in n_repeats: error_func = _error_mbar unc_col_name = "MBAR uncertainty (kcal/mol)" else: error_func = _error_std unc_col_name = "std dev uncertainty (kcal/mol)" data = [] for lig, results in sorted(results_dict.items()): dg = np.mean([v[0].m for v in results["overall"]]) error = error_func(results) data.append((lig, dg, error)) df = pd.DataFrame( data, columns=[ "ligand", "DG (kcal/mol)", unc_col_name, ], ) df_out = format_df_with_precision(df, "DG (kcal/mol)", unc_col_name, unc_prec=2) return df_out def _generate_dg_raw(results_dict: dict[str, dict[str, list]], allow_partial: bool) -> pd.DataFrame: """ Get all the transformation cycle legs found and their DG values. Parameters ---------- results_dict : dict[str, dict[str, list]] Dictionary of results created by ``_get_legs_from_result_jsons``. Returns ------- pd.DataFrame A pandas DataFrame with the individual cycle leg dG results. """ data = [] for lig, results in sorted(results_dict.items()): for simtype, repeats in sorted(results.items()): if simtype != "overall": for repeat in repeats: measurement, uncertainty = (repeat[0].m, repeat[1].m) data.append((simtype, lig, measurement, uncertainty)) df = pd.DataFrame( data, columns=[ "leg", "ligand", "DG (kcal/mol)", "MBAR uncertainty (kcal/mol)", ], ) df_out = format_df_with_precision( df, "DG (kcal/mol)", "MBAR uncertainty (kcal/mol)", unc_prec=2 ) return df_out @click.command( "gather-abfe", short_help="Gather result JSONs for network of ABFE results into a TSV file." ) @click.argument( "results", nargs=-1, # accept any number of results type=click.Path(dir_okay=True, file_okay=True, path_type=pathlib.Path), required=True, ) @click.option( "--report", type=HyphenAwareChoice(["dg", "raw"], case_sensitive=False), default="dg", show_default=True, help=( "What data to report. 'dg' computes the overall binding free energy of each ligand in the dataset (dG), and" "'raw' outputs the raw dG values for each individual leg in the ABFE transformation cycles." ), ) @click.option( "output", "-o", type=click.File(mode="w"), default="-", help="Filepath at which to write the tsv report.", ) @click.option( "--tsv", is_flag=True, default=False, help=( "Results that are output to stdout will be formatted as tab-separated, " "identical to the formatting used when writing to file." "By default, the output table will be formatted for human-readability." ), ) @click.option( "--allow-partial", is_flag=True, default=False, help=( "Do not raise errors if results are missing parts for some edges. " "(Skip those edges and issue warning instead.)" ), ) def gather_abfe( results: List[os.PathLike | str], output: os.PathLike | str, report: Literal["dg", "raw"], tsv: bool, allow_partial: bool, ): """ .. warning:: Gathering of ABFE results with ``openfe gather-abfe`` is an experimental feature and is subject to change in a future release of openfe! Gather simulation result JSON files from ABFE simulations and generate a report. RESULTS is the path(s) to JSON files or directories of JSON files containing ABFE protocol results as generated by ``openfe quickrun``. All directories will be walked recursively and any valid JSON results files will be gathered. Files must end in .json to be collected, and invalid files will be ignored. Each JSON contains the results of a separate leg from an Absolute Binding Free Energy calculation. See https://docs.openfree.energy/en/latest/tutorials/abfe_tutorial.html for details on running ABFE calculations. The results reported depends on the ``--report`` flag: \b * ``--report=dg`` (default) reports the ligand, its absolute free energy, and the associated uncertainty obtained from DG replica averages and standard deviations. * ``--report=raw`` reports the raw results, which each repeat simulation given separately (i.e. no combining of redundant simulations is performed) The output is a table of **tab** separated values. By default, this outputs to stdout, use the -o option to specify an output filepath. """ msg = "WARNING! Gathering of ABFE results with `openfe gather-abfe` is an experimental feature and is subject to change in a future release of openfe." click.secho(msg, err=True, fg="yellow") # fmt: skip # find and filter result jsons result_fns = _collect_result_jsons(results) # pair legs of simulations together into dict of dicts legs = _get_legs_from_result_jsons(result_fns) if legs == {}: click.secho("No results JSON files found.", err=True) sys.exit(1) # compute report report_func = { "dg": _generate_dg, "raw": _generate_dg_raw, }[report.lower()] df = report_func(legs, allow_partial) # write output is_output_file = isinstance(output, click.utils.LazyFile) if is_output_file: click.echo(f"writing {report} output to '{output.name}'") if is_output_file or tsv: df.to_csv(output, sep="\t", lineterminator="\n", index=False) # TODO: we can add a --pretty flag if we want this to be optional/preserve backwards compatibility else: rich_print_to_stdout(df) PLUGIN = OFECommandPlugin( command=gather_abfe, section="Quickrun Executor", requires_ofe=(0, 6), ) ================================================ FILE: src/openfecli/commands/gather_septop.py ================================================ import os import pathlib import sys from typing import List, Literal import click import numpy as np import pandas as pd from openfecli import OFECommandPlugin from openfecli.clicktypes import HyphenAwareChoice from openfecli.commands.gather import ( _collect_result_jsons, format_df_with_precision, load_json, rich_print_to_stdout, ) def _load_valid_result_json(fpath: os.PathLike | str) -> tuple[tuple | None, dict | None]: """Load the data from a results JSON into a dict. Parameters ---------- fpath : os.PathLike | str The path to deserialized results. Returns ------- dict | None A dict containing data from the results JSON, or None if the JSON file is invalid or missing. Raises ------ ValueError If the JSON file contains an ``estimate`` or ``uncertainty`` key with the value ``None``. If """ # TODO: replace this with gather's _load_valid_result # TODO: only load this once during collection, then pass namedtuple(fname, dict) into this function # for now though, it's not the bottleneck on performance result = load_json(fpath) try: names = _get_names(result) except (ValueError, IndexError): click.secho(f"{fpath}: Missing ligand names and/or simulation type. Skipping.",err=True, fg="yellow") # fmt: skip return None, None if result["estimate"] is None: click.secho(f"{fpath}: No 'estimate' found, assuming to be a failed simulation.",err=True, fg="yellow") # fmt: skip return names, None if result["uncertainty"] is None: click.secho(f"{fpath}: No 'uncertainty' found, assuming to be a failed simulation.",err=True, fg="yellow") # fmt: skip return names, None if all("exception" in u for u in result["unit_results"].values()): click.secho(f"{fpath}: Exception found in all 'unit_results', assuming to be a failed simulation.",err=True, fg="yellow") # fmt: skip return names, None return names, result def _get_legs_from_result_jsons( result_fns: list[pathlib.Path], ) -> dict[str, dict[str, list]]: """ Iterate over a list of result JSONs and populate a dict of dicts with all data needed for results processing. Parameters ---------- result_fns : list[pathlib.Path] List of filepaths containing results formatted as JSON. report : Literal["dg", "ddg", "raw"] Type of report to generate. Returns ------- legs: dict[str, dict[str, list]] Data extracted from the given result JSONs, organized by the leg's ligand names and simulation type. """ from collections import defaultdict from openff.units import unit ddgs = defaultdict(lambda: defaultdict(list)) for result_fn in result_fns: names, result = _load_valid_result_json(result_fn) if names is None: # this means it couldn't find names and/or simtype continue ddgs[names]["overall"].append([result["estimate"], result["uncertainty"]]) proto_key = [ k for k in result["unit_results"].keys() if k.startswith("ProtocolUnitResult") ] # fmt: skip # In openfe v1.11+, we only want to pick up results from # the Analysis Unit. To ensure backwards compatibility, # we check if there are any analysis units. If so, # we set a flag and later exclude Setup and Run. has_analysis_units = any( ["Analysis" in result["unit_results"][p]["source_key"] for p in proto_key] ) for p in proto_key: # Skip non-analysis units if we have any if has_analysis_units and ( "Setup" in result["unit_results"][p]["source_key"] or "Run" in result["unit_results"][p]["source_key"] ): continue if "unit_estimate" in result["unit_results"][p]["outputs"]: simtype = result["unit_results"][p]["outputs"]["simtype"] dg = result["unit_results"][p]["outputs"]["unit_estimate"] dg_error = result["unit_results"][p]["outputs"]["unit_estimate_error"] ddgs[names][simtype].append([dg, dg_error]) if "standard_state_correction_A" in result["unit_results"][p]["outputs"]: corr_A = result["unit_results"][p]["outputs"]["standard_state_correction_A"] corr_B = result["unit_results"][p]["outputs"]["standard_state_correction_B"] ddgs[names]["standard_state_correction_A"].append( [corr_A, 0 * unit.kilocalorie_per_mole] ) ddgs[names]["standard_state_correction_B"].append( [corr_B, 0 * unit.kilocalorie_per_mole] ) return ddgs def _get_names(result: dict) -> tuple[str, str]: """Get the ligand names from a unit's results data. Parameters ---------- result : dict A results dict. Returns ------- tuple[str, str] Ligand names corresponding to the results. """ solvent_data = list(result["protocol_result"]["data"]["solvent"].values())[0][0] try: setup_data = solvent_data["inputs"]["setup"]["inputs"] except KeyError: setup_data = solvent_data["inputs"] name_A = setup_data["alchemical_components"]["stateA"][0]["molprops"]["ofe-name"] name_B = setup_data["alchemical_components"]["stateB"][0]["molprops"]["ofe-name"] return str(name_A), str(name_B) def _error_std(r): """ Calculate the error of the estimate as the std of the repeats """ return np.std([v[0].m for v in r["overall"]]) def _error_mbar(r): """ Calculate the error of the estimate using the reported MBAR errors. This also takes into account that repeats may have been run for this edge by using the average MBAR error """ complex_errors = np.array([x[1].m for x in r["complex"]]) solvent_errors = np.array([x[1].m for x in r["solvent"]]) return np.sqrt(np.mean(complex_errors**2) + np.mean(solvent_errors**2)) def _get_ddgs( results_dict: dict[str, dict[str, list]], allow_partial: bool = False ) -> pd.DataFrame: """Compute and write out DDG values for the given results. Parameters ---------- results_dict : dict[str, dict[str, list]] Dictionary of results created by ``_get_legs_from_result_jsons``. Returns ------- pd.DataFrame A pandas DataFrame with the ddG results for each ligand pair. """ # check the type of error which should be used based on the number of repeats n_repeats = {len(v["overall"]) for v in results_dict.values()} if 1 in n_repeats: error_func = _error_mbar unc_col_name = "MBAR uncertainty (kcal/mol)" else: error_func = _error_std unc_col_name = "std dev uncertainty (kcal/mol)" data = [] for ligpair, results in sorted(results_dict.items()): ddg = np.mean([v[0].m for v in results["overall"]]) error = error_func(results) data.append((ligpair[0], ligpair[1], ddg, error)) df = pd.DataFrame( data, columns=[ "ligand_i", "ligand_j", "DDG(i->j) (kcal/mol)", unc_col_name, ], ) return df def _infer_unc_col_name(df: pd.DataFrame) -> str: """Return the full name of the first column name in df containing "uncertainty".""" unc_col_name = df.filter(regex="uncertainty").columns[0] return unc_col_name def _generate_ddg(results_dict, allow_partial: bool = False) -> pd.DataFrame: df_ddgs = _get_ddgs(results_dict) unc_col_name = _infer_unc_col_name(df_ddgs) df_out = format_df_with_precision(df_ddgs, "DDG(i->j) (kcal/mol)", unc_col_name, unc_prec=2) return df_out def _generate_dg_mle( results_dict: dict[str, dict[str, list]], allow_partial: bool = False ) -> pd.DataFrame: """Compute and write out MLE-derived DG values for the given results. Parameters ---------- results_dict : dict[str, dict[str, list]] Dictionary of results created by ``_get_legs_from_result_jsons``. Returns ------- pd.DataFrame A pandas DataFrame with the dG results for each ligand pair. """ from cinnabar import FEMap, Measurement from openff.units import unit DDGs = _get_ddgs(results_dict) fe_results = [] for inx, row in DDGs.iterrows(): ligA, ligB, DDGbind, bind_unc = row.tolist() m = Measurement( labelA=ligA, labelB=ligB, DG=DDGbind * unit.kilocalorie_per_mole, uncertainty=bind_unc * unit.kilocalorie_per_mole, computational=True, ) fe_results.append(m) # Feed into the FEMap object femap = FEMap() for entry in fe_results: femap.add_measurement(entry) femap.generate_absolute_values() df = femap.get_absolute_dataframe() df = df.iloc[:, :3] unc_col_name = _infer_unc_col_name(DDGs) df.rename( {"label": "ligand", "uncertainty (kcal/mol)": unc_col_name}, axis="columns", inplace=True ) df_out = format_df_with_precision(df, "DG (kcal/mol)", unc_col_name, unc_prec=2) return df_out def _generate_raw( results_dict: dict[str, dict[str, list]], allow_partial: bool = True ) -> pd.DataFrame: """ Get all the transformation cycle legs found and their DG values. Parameters ---------- results_dict : dict[str, dict[str, list]] Dictionary of results created by ``_get_legs_from_result_jsons``. Returns ------- pd.DataFrame A pandas DataFrame with the individual cycle leg dG results. """ data = [] for ligpair, results in sorted(results_dict.items()): for simtype, repeats in sorted(results.items()): if simtype != "overall": for repeat in repeats: m, u = (repeat[0].m, repeat[1].m) data.append((simtype, ligpair[0], ligpair[1], m, u)) df = pd.DataFrame( data, columns=[ "leg", "ligand_i", "ligand_j", "DG(i->j) (kcal/mol)", "MBAR uncertainty (kcal/mol)", ], ) df_out = format_df_with_precision( df, "DG(i->j) (kcal/mol)", "MBAR uncertainty (kcal/mol)", unc_prec=2 ) return df_out @click.command( "gather-septop", short_help="Gather result JSONs for a network of SepTop results into a TSV file.", ) @click.argument( "results", nargs=-1, # accept any number of results type=click.Path(dir_okay=True, file_okay=True, path_type=pathlib.Path), required=True, ) @click.option( "--report", type=HyphenAwareChoice(["dg", "ddg", "raw"], case_sensitive=False), default="dg", show_default=True, help=( "What data to report. 'dg' gives the maximum-likelihood estimate derived " "absolute deltaG value, 'ddg' gives delta-delta-G, and 'raw' gives " "the raw result of the deltaG for a leg." ), ) @click.option( "output", "-o", type=click.File(mode="w"), default="-", help="Filepath at which to write the tsv report.", ) @click.option( "--tsv", is_flag=True, default=False, help=( "Results that are output to stdout will be formatted as tab-separated, " "identical to the formatting used when writing to file." "By default, the output table will be formatted for human-readability." ), ) @click.option( "--allow-partial", is_flag=True, default=False, help=( "Do not raise errors if results are missing parts for some edges. " "(Skip those edges and issue warning instead.)" ), ) def gather_septop( results: List[os.PathLike | str], output: os.PathLike | str, report: Literal["dg", "ddg", "raw"], tsv: bool, allow_partial: bool, ): """ .. warning:: Gathering of SepTop results with ``openfe gather-septop`` is an experimental feature and is subject to change in a future release of openfe! Gather simulation result JSON files from SepTop simulations and generate a report. RESULTS is the path(s) to JSON files or directories of JSON files containing SepTop protocol results as generated by ``openfe quickrun``. All directories will be walked recursively and any valid JSON results files will be gathered. Files must end in .json to be collected, and invalid files will be ignored. Each JSON contains the results of a separate leg from a Separated Topologies calculation. See https://docs.openfree.energy/en/latest/tutorials/septop_tutorial.html for details on running SepTop calculations. The results reported depends on ``--report`` flag: \b * ``--report=dg`` (default) reports the ligand, its absolute free energy, and the associated uncertainty as the maximum likelihood estimate obtained from DDG replica averages and standard deviations. These MLE estimates are centred around 0.0, and when plotted can be shifted to match experimental values. * ``--report=ddg`` reports pairs of ligand_i and ligand_j, the calculated relative free energy DDG(i->j) = DG(j) - DG(i) and its uncertainty. * ``--report=raw`` reports the raw results, which each repeat simulation given separately (i.e. no combining of redundant simulations is performed) The output is a table of **tab** separated values. By default, this outputs to stdout, use the -o option to specify an output filepath. """ msg = "WARNING! Gathering of SepTop results with `openfe gather-septop` is an experimental feature and is subject to change in a future release of openfe." click.secho(msg, err=True, fg="yellow") # fmt: skip # find and filter result jsons result_fns = _collect_result_jsons(results) # pair legs of simulations together into dict of dicts legs = _get_legs_from_result_jsons(result_fns) if legs == {}: click.secho("No results JSON files found.", err=True) sys.exit(1) # compute report report_func = { "dg": _generate_dg_mle, "ddg": _generate_ddg, "raw": _generate_raw, }[report.lower()] df = report_func(legs, allow_partial) # write output is_output_file = isinstance(output, click.utils.LazyFile) if is_output_file: click.echo(f"writing {report} output to '{output.name}'") if is_output_file or tsv: df.to_csv(output, sep="\t", lineterminator="\n", index=False) # TODO: we can add a --pretty flag if we want this to be optional/preserve backwards compatibility else: rich_print_to_stdout(df) PLUGIN = OFECommandPlugin( command=gather_septop, section="Quickrun Executor", requires_ofe=(0, 6), ) ================================================ FILE: src/openfecli/commands/generate_partial_charges.py ================================================ import pathlib import click from openfecli import OFECommandPlugin from openfecli.parameters import MOL_DIR, NCORES, OUTPUT_FILE_AND_EXT, OVERWRITE, YAML_OPTIONS YAML_HELP = """ Path to a YAML file specifying the method to use to charge the molecules (any atom mapper or network generation options will be ignored). Supported partial charge method choices are: - ``am1bcc`` - ``am1bccelf10`` (only possible if ``off_toolkit_backend`` is ``openeye``) - ``nagl`` (must have openff-nagl installed) - ``espaloma`` (must have espaloma_charge installed) ``settings`` allows for passing in any keyword arguments of the method's corresponding Python API. For example: :: partial_charge: method: am1bcc settings: off_toolkit_backend: ambertools """ @click.command("charge-molecules", short_help="Generate partial charges for a set of molecules.") @MOL_DIR.parameter(required=True, help=MOL_DIR.kwargs["help"] + " Any number of sdf paths.") @YAML_OPTIONS.parameter(multiple=False, required=False, default=None, help=YAML_HELP) @OUTPUT_FILE_AND_EXT.parameter( help="The name of the SDF file the charged ligands should be written to.", required=True, type=click.Path(exists=False, path_type=pathlib.Path), ) @NCORES.parameter(help=NCORES.kwargs["help"], default=1) @OVERWRITE.parameter(help=OVERWRITE.kwargs["help"], default=OVERWRITE.kwargs["default"], is_flag=True) # fmt: skip def charge_molecules(molecules, yaml_settings, output, n_cores, overwrite_charges): """ Generate partial charges for the set of input molecules and write them to file. """ from openfecli.utils import write if output.exists(): raise FileExistsError( f"The output file {output} already exists, choose a new file to write the charged ligands to" ) write("SMALL MOLECULE PARTIAL CHARGE GENERATOR") write("_________________________________________") write("") from openfe.protocols.openmm_utils.charge_generation import bulk_assign_partial_charges write("Parsing in Files: ") # INPUT write("\tGot input: ") small_molecules = MOL_DIR.get(molecules) write("\t\tSmall Molecules: " + " ".join([str(sm) for sm in small_molecules])) yaml_options = YAML_OPTIONS.get(yaml_settings) partial_charge = yaml_options.partial_charge write("Using Options:") write("\tPartial Charge Generation: " + str(partial_charge.partial_charge_method)) if overwrite_charges: write("\tOverwriting partial charges") write("") charged_molecules = bulk_assign_partial_charges( molecules=small_molecules, overwrite=overwrite_charges, method=partial_charge.partial_charge_method, toolkit_backend=partial_charge.off_toolkit_backend, generate_n_conformers=partial_charge.number_of_conformers, nagl_model=partial_charge.nagl_model, processors=n_cores, ) write("\tDone") write("") # OUTPUT write("Output:") write(f"\tSaving to: {output}") with output.open(mode="w") as output: for mol in charged_molecules: output.write(mol.to_sdf()) PLUGIN = OFECommandPlugin(command=charge_molecules, section="Miscellaneous", requires_ofe=(0, 3)) ================================================ FILE: src/openfecli/commands/plan_rbfe_network.py ================================================ # This code is part of OpenFE and is licensed under the MIT license. # For details, see https://github.com/OpenFreeEnergy/openfe import click from openfecli import OFECommandPlugin from openfecli.parameters import ( COFACTORS, MOL_DIR, N_PROTOCOL_REPEATS, NCORES, OUTPUT_DIR, OVERWRITE, PROTEIN, PROTEIN_MEMBRANE, YAML_OPTIONS, ) from openfecli.utils import print_duration, write def plan_rbfe_network_main( mapper, mapping_scorer, ligand_network_planner, small_molecules, solvent, protein, cofactors, n_protocol_repeats, partial_charge_settings, processors, overwrite_charges, ): """Utility method to plan a relative binding free energy network. Parameters ---------- mapper : list[LigandAtomMapper] list of mappers to use to generate the mapping mapping_scorer : Callable scorer, that evaluates the generated mappings ligand_network_planner : Callable function building the network from the ligands, mappers and mapping_scorer small_molecules : Iterable[SmallMoleculeComponent] ligands of the system solvent : SolventComponent Solvent component used for solvation protein : ProteinComponent ProteinComponent for complex simulations, to which the ligands are bound. cofactors : Iterable[SmallMoleculeComponent] any cofactors alongside the protein, can be empty list n_protocol_repeats: int number of completely independent repeats of the entire sampling process any cofactors alongside the protein, can be empty list partial_charge_settings : OpenFFPartialChargeSettings how to assign partial charges to the input ligands (if they don't already have partial charges). processors: int The number of processors that should be used when generating the charges overwrite_charges: bool If any partial charges already present on the small molecules should be overwritten Returns ------- Tuple[AlchemicalNetwork, LigandNetwork] Alchemical network with protocol for executing simulations, and the associated ligand network """ from openfe.protocols.openmm_utils.charge_generation import bulk_assign_partial_charges from openfe.setup.alchemical_network_planner.relative_alchemical_network_planner import ( RBFEAlchemicalNetworkPlanner, RelativeHybridTopologyProtocol, ) protocol_settings = RelativeHybridTopologyProtocol.default_settings() protocol_settings.protocol_repeats = n_protocol_repeats protocol = RelativeHybridTopologyProtocol(protocol_settings) write("assigning ligand partial charges -- this may be slow") charged_small_molecules = bulk_assign_partial_charges( molecules=small_molecules, overwrite=overwrite_charges, method=partial_charge_settings.partial_charge_method, toolkit_backend=partial_charge_settings.off_toolkit_backend, generate_n_conformers=partial_charge_settings.number_of_conformers, nagl_model=partial_charge_settings.nagl_model, processors=processors, ) if cofactors: write("assigning cofactor partial charges -- this may be slow") cofactors = bulk_assign_partial_charges( molecules=cofactors, overwrite=overwrite_charges, method=partial_charge_settings.partial_charge_method, toolkit_backend=partial_charge_settings.off_toolkit_backend, generate_n_conformers=partial_charge_settings.number_of_conformers, nagl_model=partial_charge_settings.nagl_model, processors=processors, ) network_planner = RBFEAlchemicalNetworkPlanner( mappers=mapper, mapping_scorer=mapping_scorer, ligand_network_planner=ligand_network_planner, protocol=protocol, ) alchemical_network = network_planner( ligands=charged_small_molecules, solvent=solvent, protein=protein, cofactors=cofactors, ) return alchemical_network, network_planner._ligand_network @click.command( "plan-rbfe-network", short_help=( "Plan a relative binding free energy network, saved as JSON files for the quickrun command." ), ) @MOL_DIR.parameter(required=True, help=MOL_DIR.kwargs["help"] + " Any number of sdf paths.") @PROTEIN.parameter(multiple=False, required=False, default=None, help=PROTEIN.kwargs["help"]) @PROTEIN_MEMBRANE.parameter( multiple=False, required=False, default=None, help=PROTEIN_MEMBRANE.kwargs["help"] ) @COFACTORS.parameter(multiple=True, required=False, default=None, help=COFACTORS.kwargs["help"]) @YAML_OPTIONS.parameter(multiple=False, required=False, default=None, help=YAML_OPTIONS.kwargs["help"]) # fmt: skip @OUTPUT_DIR.parameter(help=OUTPUT_DIR.kwargs["help"] + " Defaults to `./alchemicalNetwork`.", default="alchemicalNetwork") # fmt: skip @N_PROTOCOL_REPEATS.parameter(multiple=False, required=False, default=3, help=N_PROTOCOL_REPEATS.kwargs["help"]) # fmt: skip @NCORES.parameter(help=NCORES.kwargs["help"], default=1) @OVERWRITE.parameter(help=OVERWRITE.kwargs["help"], default=OVERWRITE.kwargs["default"], is_flag=True) # fmt: skip @print_duration def plan_rbfe_network( molecules: list[str], protein: str | None, protein_membrane: str | None, cofactors: tuple[str], yaml_settings: str, output_dir: str, n_protocol_repeats: int, n_cores: int, overwrite_charges: bool, ): """ Plan a relative binding free energy AlchemicalNetwork, saved as JSON files for use by the quickrun command. This tool is an easy way to set up a RBFE calculation campaign. The generated AlchemicalNetwork will be stored in --output-directory along with JSON files for each alchemical transformation that can be used to execute the campaign using ``openfe quickrun``. .. note:: To ensure a consistent set of partial charges are used for each molecule across different transformations, this tool will automatically generate charges ahead of planning the network. ``am1bcc`` charges will be generated via ``ambertools``, this can also be customized using the settings yaml file. By default, this tool makes the following choices: * Atom mappings performed by KartografAtomMapper, with settings atom_max_distance=0.95, atom_map_hydrogens=True, map_hydrogens_on_hydrogens_only=True, map_exact_ring_matches_only=True, allow_partial_fused_rings=True, and allow_bond_breaks=False. * Minimal spanning network as the network planner, with LOMAP default score as the weight function * Water as solvent, with NaCl counter ions at 0.15 M concentration. * Protocol is the OpenMM-based relative hybrid topology protocol, with default settings. These choices can be customized by creating a settings yaml file, which is passed in via the ``-s settings.yaml`` option. For more advanced setups, please consider using the Python layer of openfe. """ write("RBFE-NETWORK PLANNER") write("______________________") write("") from openfecli.plan_alchemical_networks_utils import plan_alchemical_network_output write("Parsing in Files: ") # INPUT write("\tGot input: ") small_molecules = MOL_DIR.get(molecules) write("\t\tSmall Molecules: " + " ".join([str(sm) for sm in small_molecules])) if protein and protein_membrane: raise click.UsageError( "Only --protein (-p) or --protein-membrane may be provided, not both." ) elif protein: protein_component = PROTEIN.get(protein) write("\t\tProteinComponent: " + str(protein_component)) elif protein_membrane: protein_component = PROTEIN_MEMBRANE.get(protein_membrane) write("\t\tProteinMembraneComponent: " + str(protein_component)) else: raise click.UsageError("Either --protein or --protein-membrane must be provided.") if cofactors is not None: cofactors = sum((COFACTORS.get(c) for c in cofactors), start=[]) else: cofactors = [] write("\t\tCofactors: " + str(cofactors)) yaml_options = YAML_OPTIONS.get(yaml_settings) mapper_obj = yaml_options.mapper mapping_scorer = yaml_options.scorer ligand_network_planner = yaml_options.ligand_network_planner solvent = yaml_options.solvent partial_charge = yaml_options.partial_charge write("\t\tSolvent: " + str(solvent)) write("") write("Using Options:") write("\tMapper: " + str(mapper_obj)) write("\tMapping Scorer: " + str(mapping_scorer)) write("\tNetwork Generation: " + str(ligand_network_planner)) write("\tPartial Charge Generation: " + str(partial_charge.partial_charge_method)) if overwrite_charges: write("\tOverwriting partial charges") write("") write(f"\t{n_protocol_repeats=} ({n_protocol_repeats} simulation repeat(s) per transformation)\n") # fmt: skip # DO write("Planning RBFE-Campaign:") alchemical_network, ligand_network = plan_rbfe_network_main( mapper=[mapper_obj], mapping_scorer=mapping_scorer, ligand_network_planner=ligand_network_planner, small_molecules=small_molecules, solvent=solvent, protein=protein_component, cofactors=cofactors, n_protocol_repeats=n_protocol_repeats, partial_charge_settings=partial_charge, processors=n_cores, overwrite_charges=overwrite_charges, ) write("\tDone") write("") # OUTPUT write("Output:") write("\tSaving to: " + str(output_dir)) plan_alchemical_network_output( alchemical_network=alchemical_network, ligand_network=ligand_network, folder_path=OUTPUT_DIR.get(output_dir), ) PLUGIN = OFECommandPlugin( command=plan_rbfe_network, section="Network Planning", requires_ofe=(0, 3) ) ================================================ FILE: src/openfecli/commands/plan_rhfe_network.py ================================================ # This code is part of OpenFE and is licensed under the MIT license. # For details, see https://github.com/OpenFreeEnergy/openfe from typing import List import click from openfecli import OFECommandPlugin from openfecli.parameters import ( MAPPER, MOL_DIR, N_PROTOCOL_REPEATS, NCORES, OUTPUT_DIR, OVERWRITE, YAML_OPTIONS, ) from openfecli.utils import print_duration, write def plan_rhfe_network_main( mapper, mapping_scorer, ligand_network_planner, small_molecules, solvent, n_protocol_repeats, partial_charge_settings, processors, overwrite_charges, ): """Utility method to plan a relative hydration free energy network. Parameters ---------- mapper : list[LigandAtomMapper] list of mappers to use to generate the mapping mapping_scorer : Callable scorer, that evaluates the generated mappings ligand_network_planner : Callable function building the network from the ligands, mappers and mapping_scorer small_molecules : Iterable[SmallMoleculeComponent] molecules of the system solvent : SolventComponent Solvent component used for solvation n_protocol_repeats: int number of completely independent repeats of the entire sampling process partial_charge_settings : OpenFFPartialChargeSettings how to assign partial charges to the input ligands (if they don't already have partial charges). processors: int The number of processors that should be used when generating the charges overwrite_charges: bool If any partial charges already present on the small molecules should be overwritten Returns ------- Tuple[AlchemicalNetwork, LigandNetwork] Alchemical network with protocol for executing simulations, and the associated ligand network """ from openfe.protocols.openmm_utils.charge_generation import bulk_assign_partial_charges from openfe.setup.alchemical_network_planner.relative_alchemical_network_planner import ( RelativeHybridTopologyProtocol, RHFEAlchemicalNetworkPlanner, ) protocol_settings = RelativeHybridTopologyProtocol.default_settings() protocol_settings.protocol_repeats = n_protocol_repeats protocol = RelativeHybridTopologyProtocol(protocol_settings) write("assigning ligand partial charges -- this may be slow") charged_small_molecules = bulk_assign_partial_charges( molecules=small_molecules, overwrite=overwrite_charges, method=partial_charge_settings.partial_charge_method, toolkit_backend=partial_charge_settings.off_toolkit_backend, generate_n_conformers=partial_charge_settings.number_of_conformers, nagl_model=partial_charge_settings.nagl_model, processors=processors, ) network_planner = RHFEAlchemicalNetworkPlanner( mappers=mapper, mapping_scorer=mapping_scorer, ligand_network_planner=ligand_network_planner, protocol=protocol, ) alchemical_network = network_planner(ligands=charged_small_molecules, solvent=solvent) return alchemical_network, network_planner._ligand_network @click.command( "plan-rhfe-network", short_help=( "Plan a relative hydration free energy network, saved as JSON files " "for the quickrun command." ), ) @MOL_DIR.parameter(required=True, help=MOL_DIR.kwargs["help"] + " Any number of sdf paths.") @YAML_OPTIONS.parameter(multiple=False, required=False, default=None, help=YAML_OPTIONS.kwargs["help"]) # fmt: skip @OUTPUT_DIR.parameter(help=OUTPUT_DIR.kwargs["help"] + " Defaults to `./alchemicalNetwork`.", default="alchemicalNetwork") # fmt: skip @N_PROTOCOL_REPEATS.parameter(multiple=False, required=False, default=3, help=N_PROTOCOL_REPEATS.kwargs["help"]) # fmt: skip @NCORES.parameter(help=NCORES.kwargs["help"], default=1) @OVERWRITE.parameter(help=OVERWRITE.kwargs["help"], default=OVERWRITE.kwargs["default"], is_flag=True) # fmt: skip @print_duration def plan_rhfe_network( molecules: List[str], yaml_settings: str, output_dir: str, n_cores: int, overwrite_charges: bool, n_protocol_repeats: int, ): # TODO: make this match the rbfe network docstring, or vice-versa? """ Plan a relative hydration free energy network, saved as JSON files for use by the quickrun command. This tool is an easy way to setup a RHFE calculation campaign. This can be useful for testing our tools. Plan-rhfe-network finds a reasonable network of transformations and adds the openfe rbfe protocol of year one to the transformations. The output of the command can be used, in order to run the planned transformations with the quickrun tool. For more sophisticated setups, please consider using the python layer of openfe. .. note:: To ensure a consistent set of partial charges are used for each molecule across different transformations, this tool will automatically generate charges ahead of planning the network. ``am1bcc`` charges will be generated via ``ambertools``, this can also be customized using the settings yaml file. The tool will parse the input and run the rbfe network planner, which executes following steps: 1. generate an atom mapping for all possible ligand pairs. (default: Lomap) 2. score all atom mappings. (default: Lomap default score) 3. build network form all atom mapping scores (default: minimal spanning graph) The generated Network will be stored in a folder containing for each transformation a JSON file, that can be run with quickrun (or other future tools). """ write("RHFE-NETWORK PLANNER") write("______________________") write("") from openfecli.plan_alchemical_networks_utils import plan_alchemical_network_output write("Parsing in Files: ") # INPUT write("\tGot input: ") small_molecules = MOL_DIR.get(molecules) write("\t\tSmall Molecules: " + " ".join([str(sm) for sm in small_molecules])) yaml_options = YAML_OPTIONS.get(yaml_settings) mapper_obj = yaml_options.mapper mapping_scorer = yaml_options.scorer ligand_network_planner = yaml_options.ligand_network_planner solvent = yaml_options.solvent partial_charge = yaml_options.partial_charge write("\t\tSolvent: " + str(solvent)) write("") write("Using Options:") write("\tMapper: " + str(mapper_obj)) # TODO: write nice parameter write("\tMapping Scorer: " + str(mapping_scorer)) # TODO: write nice parameter write("\tNetworker: " + str(ligand_network_planner)) write("\tPartial Charge Generation: " + str(partial_charge.partial_charge_method)) if overwrite_charges: write("\tOverwriting partial charges") write("") write(f"\t{n_protocol_repeats=} ({n_protocol_repeats} simulation repeat(s) per transformation)\n") # fmt: skip # DO write("Planning RHFE-Campaign:") alchemical_network, ligand_network = plan_rhfe_network_main( mapper=[mapper_obj], mapping_scorer=mapping_scorer, ligand_network_planner=ligand_network_planner, small_molecules=small_molecules, solvent=solvent, n_protocol_repeats=n_protocol_repeats, partial_charge_settings=partial_charge, processors=n_cores, overwrite_charges=overwrite_charges, ) write("\tDone") write("") # OUTPUT write("Output:") write("\tSaving to: " + output_dir) plan_alchemical_network_output( alchemical_network=alchemical_network, ligand_network=ligand_network, folder_path=OUTPUT_DIR.get(output_dir), ) PLUGIN = OFECommandPlugin( command=plan_rhfe_network, section="Network Planning", requires_ofe=(0, 3) ) ================================================ FILE: src/openfecli/commands/quickrun.py ================================================ # This code is part of OpenFE and is licensed under the MIT license. # For details, see https://github.com/OpenFreeEnergy/openfe import hashlib import json import pathlib import warnings import click from openfecli import OFECommandPlugin from openfecli.utils import configure_logger, print_duration, write def _format_exception(exception) -> str: """Takes the exception as stored by Gufe and reformats it.""" return f"{exception[0]}: {exception[1][0]}" def _hash_quickrun_inputs(output, transformation): string_rep = f"{output.absolute()}{transformation.key}" hasher = hashlib.md5(string_rep.encode(), usedforsecurity=False) return hasher.hexdigest() @click.command("quickrun", short_help="Run a given transformation, saved as a JSON file") @click.argument("transformation", type=click.File(mode="r"), required=True) @click.option( "--work-dir", "-d", default=None, type=click.Path(dir_okay=True, file_okay=False, writable=True, path_type=pathlib.Path), help=( "Directory in which to store files in (defaults to current directory). " "If the directory does not exist, it will be created at runtime." ), ) # fmt: skip @click.option( "output", "-o", default=None, type=click.Path(dir_okay=False, file_okay=False, path_type=pathlib.Path), help="Filepath at which to create and write the JSON-formatted results.", ) # fmt: skip @click.option( "--resume", is_flag=True, default=False, help=("Attempt to resume this transformation's execution using the cache."), ) @print_duration def quickrun(transformation, work_dir, output, resume): """Run the transformation (edge) in the given JSON file. Simulation JSON files can be created with the :ref:`cli_plan-rbfe-network` or from Python a :class:`.Transformation` can be saved using its to_json method:: transformation.to_json("filename.json") That will save a JSON file suitable to be input for this command. Running this command will execute the simulation defined in the JSON file, creating a directory for each individual task (``Unit``) in the workflow. For example, when running the OpenMM HREX Protocol a directory will be created for each repeat of the sampling process (by default 3). """ import logging import os import sys from json import JSONDecodeError from gufe import ProtocolDAG from gufe.protocols.protocoldag import execute_DAG from gufe.tokenization import JSON_HANDLER from gufe.transformations.transformation import Transformation from openfe.utils import logging_control # avoid problems with output not showing if queueing system kills a job sys.stdout.reconfigure(line_buffering=True) stdout_handler = logging.StreamHandler(sys.stdout) configure_logger("gufekey", handler=stdout_handler) configure_logger("gufe", handler=stdout_handler) configure_logger("openfe", handler=stdout_handler) # silence the openmmtools.multistate API warning logging_control._silence_message( msg=[ "The openmmtools.multistate API is experimental and may change in future releases", ], logger_names=[ "openmmtools.multistate.multistatereporter", "openmmtools.multistate.multistateanalyzer", "openmmtools.multistate.multistatesampler", ], ) # turn warnings into log message (don't show stack trace) logging.captureWarnings(True) click.secho(f"\nCurrent directory: {os.getcwd()}/") if work_dir is None: click.secho(f"Creating working directory: {work_dir}/") work_dir = pathlib.Path(os.getcwd()) else: click.secho(f"Using existing working directory: {work_dir}/") work_dir.mkdir(exist_ok=True, parents=True) trans = Transformation.from_json(transformation) if output is None: output = work_dir / (str(trans.key) + "_results.json") else: output.parent.mkdir(exist_ok=True, parents=True) click.secho(f"Loading transformation from: {transformation.name}") click.secho(f"When simulation is complete, results will be written to: {output}\n") resume_command = f"openfe quickrun {transformation.name} -o {output} -d {work_dir} --resume\n" click.secho( "If this simulation is interrupted or fails, you may attempt to resume execution using:", bold=True, ) click.secho(resume_command) # Attempt to either deserialize or freshly create DAG cache_basedir = work_dir / "quickrun_cache" hashed_key = _hash_quickrun_inputs(output, trans) cached_dag_path = cache_basedir / f"dag-cache-{hashed_key}.json" if cached_dag_path.is_file(): if resume: write(f"Attempting to resume execution using '{cached_dag_path}'") try: dag = ProtocolDAG.from_json(cached_dag_path) except JSONDecodeError: # we can't tell the user which gufe-generated cache dir to delete, since we'd need to load the JSON to know the DAG's key # however, just removing the cached_dag_path is sufficient to trigger a fresh DAG to be generated, and the gufe-generated cached dir will just be stale. errmsg = f"Recovery failed, please remove {cached_dag_path} before executing a new transformation simulation." raise click.ClickException(errmsg) write("Success. Resuming execution...") else: errmsg = f"Transformation has been started but is incomplete. Please remove {cached_dag_path} and rerun, or resume execution using the ``--resume`` flag." raise click.ClickException(click.style(errmsg, fg="red")) else: if resume: write( f"openfe quickrun was run with --resume, but no cached results found at {cached_dag_path}. Starting new execution." ) # Create the DAG instead and then serialize for later resuming write("Planning simulations for this edge...") dag = trans.create() cache_basedir.mkdir(exist_ok=True) dag.to_json(cached_dag_path) write("\nStarting the simulations for this edge...\n") dagresult = execute_DAG( dag, shared_basedir=work_dir, scratch_basedir=work_dir, cache_basedir=cache_basedir, keep_shared=True, raise_error=False, n_retries=2, ) write("Done with all simulations! Analyzing the results....") prot_result = trans.protocol.gather([dagresult]) if dagresult.ok(): estimate = prot_result.get_estimate() uncertainty = prot_result.get_uncertainty() else: estimate = uncertainty = None # for output file out_dict = { "estimate": estimate, "uncertainty": uncertainty, "protocol_result": prot_result.to_dict(), "unit_results": { unit.key: unit.to_keyed_dict() for unit in dagresult.protocol_unit_results }, } with open(output, mode="w") as outf: json.dump(out_dict, outf, cls=JSON_HANDLER.encoder) # remove the cached dag since the job has completed os.remove(cached_dag_path) write(f"Here is the result:\n\tdG = {estimate} ± {uncertainty}\n") write("") if not dagresult.ok(): # there can be only one, MacCleod failure = dagresult.protocol_unit_failures[-1] raise click.ClickException( f"The protocol unit '{failure.name}' failed with the error " f"message:\n{_format_exception(failure.exception)}\n\n" "Details provided in output." ) PLUGIN = OFECommandPlugin(command=quickrun, section="Quickrun Executor", requires_ofe=(0, 3)) if __name__ == "__main__": quickrun() ================================================ FILE: src/openfecli/commands/test.py ================================================ import os import sys import click import pytest from openfecli import OFECommandPlugin from openfecli.utils import write @click.command("test", short_help="Run the OpenFE test suite") @click.option('--long', is_flag=True, default=False, help="Run additional tests (takes much longer)") # fmt: skip @click.option( "--download-only", is_flag=True, default=False, help="Download data to the cache if not already present (this is helpful if internet is unreliable). If all data exists in the cache, only the cache location is shown.", ) def test(long, download_only): """ Run the OpenFE test suite. This first checks that OpenFE is correctly imported, and then runs the main test suite, which should take several minutes. If given the ``--long`` flag, this will include several tests that take significantly longer, but ensure that we're able to fully run in your environment. A successful run will include tests that pass, skip, or "xfail". In many terminals, these show as green or yellow. Warnings are not a concern. However, You should not see anything that fails or errors (red). """ if download_only: from openfe.data import _downloader from openfe.data._registry import zenodo_data_registry as api_test_data_registry from openfecli.data._registry import POOCH_CACHE from openfecli.data._registry import zenodo_data_registry as cli_test_data_registry click.echo(f"Checking for test data in cache location:\n{POOCH_CACHE}") _downloader.retrieve_registry_data( cli_test_data_registry + api_test_data_registry, POOCH_CACHE ) sys.exit(0) try: old_env = dict(os.environ) os.environ["OFE_SLOW_TESTS"] = str(long) write("Testing can import....") import openfe write("Running the main package tests") return_value = pytest.main(["-v", "--pyargs", "openfe", "--pyargs", "openfecli"]) finally: os.environ.clear() os.environ.update(old_env) sys.exit(return_value) PLUGIN = OFECommandPlugin(test, "Miscellaneous", requires_ofe=(0, 7, 5)) ================================================ FILE: src/openfecli/commands/view_ligand_network.py ================================================ import os import click from openfecli import OFECommandPlugin @click.command("view-ligand-network", short_help="Visualize a ligand network from a .graphml file.") @click.argument( "ligand-network", type=click.Path(exists=True, readable=True, dir_okay=False, file_okay=True), ) def view_ligand_network(ligand_network: os.PathLike): """ Visualize a ligand network from a .graphml file. e.g. ``openfe view-ligand-network network_setup/ligand_network.graphml`` """ import matplotlib from openfe.setup import LigandNetwork from openfe.utils.atommapping_network_plotting import plot_atommapping_network matplotlib.use("TkAgg") with open(ligand_network) as f: graphml = f.read() network = LigandNetwork.from_graphml(graphml) fig = plot_atommapping_network(network) matplotlib.pyplot.show() PLUGIN = OFECommandPlugin( command=view_ligand_network, section="Network Planning", requires_ofe=(0, 7, 0), ) ================================================ FILE: src/openfecli/data/__init__.py ================================================ ================================================ FILE: src/openfecli/data/_registry.py ================================================ """Registry for all remotely-stored CLI test data.""" import pooch POOCH_CACHE = pooch.os_cache("openfe") zenodo_cmet_data = dict( base_url="doi:10.5281/zenodo.15200083/", fname="cmet_results.tar.gz", known_hash="md5:a4ca67a907f744c696b09660dc1eb8ec", ) zenodo_rbfe_serial_data = dict( base_url="doi:10.5281/zenodo.15042470/", fname="rbfe_results_serial_repeats.tar.gz", known_hash="md5:2355ecc80e03242a4c7fcbf20cb45487", ) zenodo_rbfe_parallel_data = dict( base_url="doi:10.5281/zenodo.15042470/", fname="rbfe_results_parallel_repeats.tar.gz", known_hash="md5:ff7313e14eb6f2940c6ffd50f2192181", ) zenodo_abfe_data = dict( base_url="doi:10.5281/zenodo.19498687/", fname="abfe_results.zip", known_hash="md5:44db4ce8195f4fe99989f8f57e0d7081", ) zenodo_septop_data = dict( base_url="doi:10.5281/zenodo.19805681/", fname="septop_results.zip", known_hash="md5:5de5cac5acdf195a13b0f1ce016a8660", ) zenodo_data_registry = [ zenodo_cmet_data, zenodo_rbfe_serial_data, zenodo_rbfe_parallel_data, zenodo_abfe_data, zenodo_septop_data, ] ================================================ FILE: src/openfecli/fetchables.py ================================================ """Plugins for the ``fetch`` command""" from openfecli.fetching import PkgResourceFetcher, URLFetcher _EXAMPLE_NB_BASE = "https://raw.githubusercontent.com/OpenFreeEnergy/ExampleNotebooks/main/" RBFE_TUTORIAL = URLFetcher( resources=[ (_EXAMPLE_NB_BASE + "rbfe_tutorial/", "tyk2_ligands.sdf"), (_EXAMPLE_NB_BASE + "rbfe_tutorial/", "tyk2_protein.pdb"), (_EXAMPLE_NB_BASE + "rbfe_tutorial/", "cli_tutorial.md"), (_EXAMPLE_NB_BASE + "rbfe_tutorial/", "rbfe_python_tutorial.ipynb"), ], short_name="rbfe-tutorial", short_help="CLI and Python tutorial on relative binding free energies", section="Tutorials", requires_ofe=(0, 7, 0), ).plugin RBFE_TUTORIAL_RESULTS = PkgResourceFetcher( resources=[ ("openfecli.tests.data", "rbfe_results.tar.gz"), ], short_name="rbfe-tutorial-results", short_help="Results package to follow-up the rbfe-tutorial", section="Tutorials", requires_ofe=(0, 7, 5), ).plugin ================================================ FILE: src/openfecli/fetching.py ================================================ import importlib.resources import pathlib import shutil import urllib.request import click from plugcli.plugin_management import CommandPlugin from .utils import write class _Fetcher: """Base class for fetchers. Defines the API and plugin creation. Parameters ---------- resources: Iterable[Tuple[str, str]] resources to be downloaded, as (source, filename) short_name: str name of the command used after openfe fetch short_help: str short help shown in openfe fetch --help long_help: str help shown in openfe fetch short_name --help requires_ofe: Tuple minimum version of OpenFE required """ REQUIRES_INTERNET = None def __init__( self, resources, short_name, short_help, requires_ofe, section=None, long_help=None, ): self._resources = resources self.short_name = short_name self.short_help = short_help self.requires_ofe = requires_ofe self.section = section self.long_help = long_help @property def resources(self): yield from self._resources def __call__(self, directory: pathlib.Path): raise NotImplementedError() @property def plugin(self): """Plugin used by this fetcher""" docs = self.long_help or "" docs += "\n\nThis will fetch the following files:\n\n" # if you're getting a problem with unpacking here, you probably # forgot to make resources a list of tuple of (base, filename) for _, filename in self.resources: docs += f"* {filename}\n" if self.REQUIRES_INTERNET is True: short_help = self.short_help + " [requires internet]" section = "Requires Internet" elif self.REQUIRES_INTERNET is False: short_help = self.short_help section = "Built-in" else: # -no-cov- raise RuntimeError("Class must set boolean REQUIRES_INTERNET") @click.command( self.short_name, short_help=short_help, help=docs, ) @click.option( '-d', '--directory', default='.', help="output directory, defaults to current directory", type=click.Path(file_okay=False, dir_okay=True, writable=True), ) # fmt: skip def command(directory): directory = pathlib.Path(directory) directory.mkdir(parents=True, exist_ok=True) self(directory) return FetchablePlugin( command, section=self.section, requires_ofe=self.requires_ofe, fetcher=self, ) class URLFetcher(_Fetcher): """Fetcher for URLs. Resources should be (base, filename), e.g., ("https://google.com/", "index.html). """ REQUIRES_INTERNET = True def __call__(self, dest_dir): for base, filename in self.resources: # let's just prevent one footgun here if not base.endswith("/"): base += "/" write(f"Fetching {base}{filename}") with urllib.request.urlopen(base + filename) as resp: contents = resp.read() with open(dest_dir / filename, mode="wb") as f: f.write(contents) class PkgResourceFetcher(_Fetcher): """Fetcher for data included with the package Resources should be (package, filename), e.g., ("openfecli", "__init__.py"). """ REQUIRES_INTERNET = False def __call__(self, dest_dir): for package, filename in self.resources: ref = importlib.resources.files(package) / filename write(f"Fetching {str(ref)}") with importlib.resources.as_file(ref) as f: shutil.copyfile(ref, dest_dir / filename) # should work, but don't want to write tests yet or deal with typing # class MixedResourcesFetcher(_Fetcher): # @property # def REQUIRES_INTERNET(self): # return any([fetcher.REQUIRES_INTERNET # for fetcher in self._resources]) # @property # def resources(self): # for resource in self._resources: # yield from resource.resources # def __call__(self): # for fetcher in self._resources: # fetcher() class FetchablePlugin(CommandPlugin): """Plugin class for Fetchables. This includes the fetcher to simplify testing and introspection. """ def __init__(self, command, section, requires_ofe, fetcher): super().__init__( command=command, section=section, requires_lib=requires_ofe, requires_cli=requires_ofe, ) self.fetcher = fetcher @property def filenames(self): return [res[1] for res in self.fetcher.resources] ================================================ FILE: src/openfecli/parameters/__init__.py ================================================ # This code is part of OpenFE and is licensed under the MIT license. # For details, see https://github.com/OpenFreeEnergy/openfe from .mapper import MAPPER from .misc import N_PROTOCOL_REPEATS, NCORES, OVERWRITE from .mol import MOL from .molecules import COFACTORS, MOL_DIR from .output import OUTPUT_FILE_AND_EXT from .output_dir import OUTPUT_DIR from .plan_network_options import YAML_OPTIONS from .protein import PROTEIN, PROTEIN_MEMBRANE ================================================ FILE: src/openfecli/parameters/mapper.py ================================================ # This code is part of OpenFE and is licensed under the MIT license. # For details, see https://github.com/OpenFreeEnergy/openfe from plugcli.params import MultiStrategyGetter, Option from openfecli.parameters.utils import import_parameter def _atommapper_from_openfe_setup(user_input, context): return import_parameter("openfe.setup." + user_input) def _atommapper_from_qualname(user_input, context): return import_parameter(user_input) get_atommapper = MultiStrategyGetter( strategies=[ _atommapper_from_qualname, _atommapper_from_openfe_setup, ], error_message=( "Unable to create atom mapper from user input " "'{user_input}'. Please check spelling and " "capitalization." ), ) MAPPER = Option( "--mapper", getter=get_atommapper, help=( "Atom mapper; can either be a name in the openfe.setup namespace " "or a custom fully-qualified name." ), ) ================================================ FILE: src/openfecli/parameters/misc.py ================================================ import click from plugcli.params import Option N_PROTOCOL_REPEATS = Option( "--n-protocol-repeats", type=click.INT, help="Number of independent repeat(s) to be run per execution of a transformation using the ``openfe quickrun`` command.\n\n" "For example:\n\n ``--n-protocol-repeats=3`` means ``openfe quickrun`` will execute 3 repeats in serial.\n\n" " ``--n-protocol-repeats=1`` means ``openfe quickrun`` will execute only 1 repeat per call, " "which allows for individual repeats to be submitted in parallel by calling ``openfe quickrun`` on the same input JSON file multiple times.", ) NCORES = Option("-n", "--n-cores", help="Number of cores to use for multiprocessing.") OVERWRITE = Option( "--overwrite-charges", is_flag=True, default=False, help="Overwrite any partial charges present in the input molecules.", ) ================================================ FILE: src/openfecli/parameters/mol.py ================================================ # This code is part of OpenFE and is licensed under the MIT license. # For details, see https://github.com/OpenFreeEnergy/openfe from plugcli.params import NOT_PARSED, MultiStrategyGetter, Option def _load_molecule_from_smiles(user_input, context): from rdkit import Chem from openfe import SmallMoleculeComponent # MolFromSmiles returns None if the string is not a molecule # TODO: find some way to redirect the error messages? Messages stayed # after either redirect_stdout or redirect_stderr. mol = Chem.MolFromSmiles(user_input) if mol is None: return NOT_PARSED # TODO: next is (temporary?) hack: see # https://github.com/OpenFreeEnergy/Lomap/issues/4 Chem.rdDepictor.Compute2DCoords(mol) return SmallMoleculeComponent(rdkit=mol) def _load_molecule_from_sdf(user_input, context): if ".sdf" not in str(user_input): # this silences some stderr spam return NOT_PARSED from openfe import SmallMoleculeComponent try: return SmallMoleculeComponent.from_sdf_file(user_input) except ValueError: # any exception should try other strategies return NOT_PARSED def _load_molecule_from_mol2(user_input, context): if ".mol2" not in str(user_input): return NOT_PARSED from rdkit import Chem from openfe import SmallMoleculeComponent m = Chem.MolFromMol2File(user_input) if m is None: return NOT_PARSED else: return SmallMoleculeComponent(m) get_molecule = MultiStrategyGetter( strategies=[ _load_molecule_from_sdf, _load_molecule_from_mol2, # NOTE: I think loading from smiles must be last choice, because # failure will give meaningless user-facing errors _load_molecule_from_smiles, ], error_message="Unable to generate a molecule from '{user_input}'.", ) MOL = Option( "-m", "--mol", help=("SmallMoleculeComponent. Can be provided as an SDF file or as a SMILES string."), getter=get_molecule, ) ================================================ FILE: src/openfecli/parameters/molecules.py ================================================ # This code is part of OpenFE and is licensed under the MIT license. # For details, see https://github.com/OpenFreeEnergy/openfe import glob import itertools import pathlib import click from plugcli.params import NOT_PARSED, MultiStrategyGetter, Option # MOVE TO GUFE #################################################### def _smcs_from_sdf(sdf): from rdkit import Chem from openfe import SmallMoleculeComponent supp = Chem.SDMolSupplier(str(sdf), removeHs=False) mols = [SmallMoleculeComponent(mol) for mol in supp] return mols def _smcs_from_mol2(mol2): from rdkit import Chem from openfe import SmallMoleculeComponent rdmol = Chem.MolFromMol2File(str(mol2), removeHs=False) return [SmallMoleculeComponent.from_rdkit(rdmol)] def load_molecules(file_or_directory): """ Load SmallMoleculeComponents in the given file or directory. This always returns a list. The input can be a directory, in which all files ending with .sdf are loaded as SDF and all files ending in .mol2 are loaded as MOL2. Parameters ---------- file_or_directory : pathlib.Path Returns ------- list[SmallMoleculeComponent] """ inp = pathlib.Path(file_or_directory) # for shorter lines if inp.is_dir(): sdf_files = [f for f in inp.iterdir() if f.suffix.lower() == ".sdf"] mol2_files = [f for f in inp.iterdir() if f.suffix.lower() == ".mol2"] else: sdf_files = [inp] if inp.suffix.lower() == ".sdf" else [] mol2_files = [inp] if inp.suffix.lower() == ".mol2" else [] if not sdf_files + mol2_files: raise ValueError(f"Unable to find molecules in {file_or_directory}") sdf_mols = sum([_smcs_from_sdf(sdf) for sdf in sdf_files], []) mol2_mols = sum([_smcs_from_mol2(mol2) for mol2 in mol2_files], []) return sdf_mols + mol2_mols # END MOVE TO GUFE ################################################ def molecule_getter(user_input, context): return load_molecules(user_input) MOL_DIR = Option( "-M", "--molecules", type=click.Path(exists=True), help=( "A directory or file containing all molecules to be loaded, either" " as a single SDF or multiple MOL2/SDFs." ), getter=molecule_getter, ) COFACTORS = Option( "-C", "--cofactors", type=click.Path(exists=True), help="Path to cofactors sdf file. This may contain multiple molecules", getter=molecule_getter, ) ================================================ FILE: src/openfecli/parameters/output.py ================================================ import pathlib import click from plugcli.params import NOT_PARSED, MultiStrategyGetter, Option def get_file_and_extension(user_input, context): file = user_input ext = file.name.split(".")[-1] if file else None return file, ext OUTPUT_FILE_AND_EXT = Option( "-o", "--output", help="output file", getter=get_file_and_extension, type=click.File(mode="wb"), ) ================================================ FILE: src/openfecli/parameters/output_dir.py ================================================ import os import pathlib import click from plugcli.params import NOT_PARSED, MultiStrategyGetter, Option def get_dir(user_input, context): dir_path = pathlib.Path(user_input) return dir_path OUTPUT_DIR = Option( "-o", "--output-dir", help="Path to the output directory. ", getter=get_dir, type=click.Path(file_okay=False, resolve_path=True), ) ================================================ FILE: src/openfecli/parameters/plan_network_options.py ================================================ # This code is part of OpenFE and is licensed under the MIT license. # For details, see https://github.com/OpenFreeEnergy/openfe """Pydantic models for the definition of advanced CLI options""" import warnings from collections import namedtuple from typing import Any, Optional import click import yaml from plugcli.params import Option from pydantic import BaseModel, ConfigDict PlanNetworkOptions = namedtuple( "PlanNetworkOptions", [ "mapper", "scorer", "ligand_network_planner", "solvent", "partial_charge", ], ) class MapperSelection(BaseModel): model_config = ConfigDict(extra="allow", str_to_lower=True) method: Optional[str] = None settings: dict[str, Any] = {} class NetworkSelection(BaseModel): model_config = ConfigDict(extra="allow", str_to_lower=True) method: Optional[str] = None settings: dict[str, Any] = {} class PartialChargeSelection(BaseModel): model_config = ConfigDict(extra="allow", str_to_lower=True) method: Optional[str] = "am1bcc" settings: dict[str, Any] = {} class CliYaml(BaseModel): model_config = ConfigDict(extra="allow") mapper: Optional[MapperSelection] = None network: Optional[NetworkSelection] = None partial_charge: Optional[PartialChargeSelection] = None def parse_yaml_planner_options(contents: str) -> CliYaml: """Parse and minimally validate a user provided yaml Parameters ---------- contents : str raw yaml formatted input to parse Returns ------- options : CliOptions will have keys for mapper, network topology, and partial charge choices Raises ------ ValueError for any malformed inputs """ raw = yaml.safe_load(contents) expected_fields = {"mapper", "network", "partial_charge"} present_fields = set(raw.keys()) usable_fields = present_fields.intersection(expected_fields) ignored_fields = present_fields.difference(expected_fields) for field in ignored_fields: warnings.warn(f"Ignoring unexpected section: '{field}'") filtered = {k: raw[k] for k in usable_fields} return CliYaml(**filtered) def load_yaml_planner_options(path: Optional[str], context) -> PlanNetworkOptions: """Load cli options from yaml file path and resolve these to objects Parameters ---------- path : str path to the yaml file context unused Returns ------- PlanNetworkOptions : namedtuple a namedtuple with fields 'mapper', 'scorer', 'network_planning_algorithm', and 'solvent' fields. these fields each hold appropriate objects ready for use """ from functools import partial from gufe import SolventComponent from openfe.protocols.openmm_utils.omm_settings import OpenFFPartialChargeSettings from openfe.setup import ( KartografAtomMapper, LomapAtomMapper, ) from openfe.setup.atom_mapping.lomap_scorers import ( default_lomap_score, ) from openfe.setup.ligand_network_planning import ( generate_lomap_network, generate_maximal_network, generate_minimal_redundant_network, generate_minimal_spanning_network, generate_radial_network, ) if path is not None: with open(path, "r") as f: raw = f.read() # convert raw yaml to normalised pydantic model opt = parse_yaml_planner_options(raw) else: opt = None # convert normalised inputs to objects if opt and opt.mapper: mapper_choices = { "lomap": LomapAtomMapper, "lomapatommapper": LomapAtomMapper, "kartograf": KartografAtomMapper, "kartografatommapper": KartografAtomMapper, } try: cls = mapper_choices[opt.mapper.method] except KeyError: raise KeyError(f"Bad mapper choice: '{opt.mapper.method}'") mapper_obj = cls(**opt.mapper.settings) else: mapper_obj = KartografAtomMapper( atom_max_distance=0.95, atom_map_hydrogens=True, # Non-default setting, as we remove these later anyway when correcting for constraints map_hydrogens_on_hydrogens_only=True, map_exact_ring_matches_only=True, # Current default, but should be changed in future Kartograf releases allow_partial_fused_rings=True, allow_bond_breaks=False, ) # todo: choice of scorer goes here mapping_scorer = default_lomap_score if opt and opt.network: network_choices = { "generate_radial_network": generate_radial_network, "radial": generate_radial_network, "generate_minimal_spanning_network": generate_minimal_spanning_network, "mst": generate_minimal_spanning_network, "generate_minimal_redundant_network": generate_minimal_redundant_network, "generate_maximal_network": generate_maximal_network, "generate_lomap_network": generate_lomap_network, } try: func = network_choices[opt.network.method] except KeyError: raise KeyError(f"Bad network algorithm choice: '{opt.network.method}'") ligand_network_planner = partial(func, **opt.network.settings) else: ligand_network_planner = generate_minimal_spanning_network # We default to am1bcc on ambertools partial_charge_settings = OpenFFPartialChargeSettings() if opt and opt.partial_charge: partial_charge_settings.partial_charge_method = opt.partial_charge.method for setting in opt.partial_charge.settings: setattr( partial_charge_settings, setting, opt.partial_charge.settings[setting], ) # todo: choice of solvent goes here solvent = SolventComponent() return PlanNetworkOptions( mapper_obj, mapping_scorer, ligand_network_planner, solvent, partial_charge_settings, ) # TODO: do we want this in the docs anywhere? DEFAULT_YAML = """ mapper: kartograf settings: atom_max_distance: 0.95 atom_map_hydrogens: true map_hydrogens_on_hydrogens_only: true map_exact_ring_matches_only: true allow_partial_fused_rings: true allow_bond_breaks: false network: method: generate_minimal_spanning_network partial_charge: method: am1bcc settings: off_toolkit_backend: ambertools number_of_conformers: None nagl_model: None """ _yaml_help = """ Path to a YAML file specifying the atom mapper (``mapper``), network planning algorithm (``network``), and/or partial charge method (``partial_charge``) to use. \b Supported atom mapper choices are: - ``KartografAtomMapper`` (default as of v1.7.0) - ``LomapAtomMapper`` \b Supported network planning algorithms include (but are not limited to): - ``generate_minimal_spanning_network`` (default) - ``generate_minimal_redundant_network`` - ``generate_radial_network`` - ``generate_lomap_network`` \b Supported partial charge method choices are: - ``am1bcc`` (default) - ``am1bccelf10`` (only possible if ``off_toolkit_backend`` is ``openeye``) - ``nagl`` (must have openff-nagl installed) - ``espaloma`` (must have espaloma_charge installed) ``settings:`` allows for passing in any keyword arguments of the method's corresponding Python API. For example: :: mapper: method: LomapAtomMapper settings: element_change: false network: method: generate_minimal_redundant_network settings: mst_num: 3 partial_charge: method: am1bcc settings: off_toolkit_backend: ambertools """ YAML_OPTIONS = Option( "-s", "--settings", "yaml_settings", type=click.Path(exists=True, dir_okay=False), help=_yaml_help, getter=load_yaml_planner_options, ) ================================================ FILE: src/openfecli/parameters/protein.py ================================================ # This code is part of OpenFE and is licensed under the MIT license. # For details, see https://github.com/OpenFreeEnergy/openfe from typing import Iterable import click from plugcli.params import Option _PDB_EXT = [".pdb"] _PDBX_EXT = [".cif", ".pdbx"] def _contains_any_substring(input: str, substrings: Iterable[str]) -> bool: return any([substring in input for substring in substrings]) def _load_protein_from_file(input_file, protein_class): valid_ext = _PDB_EXT + _PDBX_EXT info_str = ( f"Unable to load a {protein_class.__name__} from {click.format_filename(input_file)}: " ) if not _contains_any_substring(input_file, valid_ext): raise click.BadParameter(info_str + f"File extension must contain one of: {valid_ext}.") try: if _contains_any_substring(input_file, _PDB_EXT): return protein_class.from_pdb_file(input_file) elif _contains_any_substring(input_file, _PDBX_EXT): return protein_class.from_pdbx_file(input_file) except ValueError as e: raise click.BadParameter(info_str + f"{e}") # TODO: these functions are shims to work with plugcli. We should consider migrating to just click. def _get_protein(user_input, context): from openfe import ProteinComponent return _load_protein_from_file(user_input, ProteinComponent) def _get_protein_membrane(user_input, context): from openfe import ProteinMembraneComponent return _load_protein_from_file(user_input, ProteinMembraneComponent) PROTEIN = Option( "-p", "--protein", help=( "Path to a PDB or PDBx/mmCIF file containing a protein. Mutually exclusive with --protein-membrane." ), getter=_get_protein, ) PROTEIN_MEMBRANE = Option( "--protein-membrane", help=( 'Path to a PDB or PDBx/mmCIF file containing a fully solvated protein-membrane system. Mutually exclusive with --protein. See "Combining System Components into a Single PDB File"' ), getter=_get_protein_membrane, ) ================================================ FILE: src/openfecli/parameters/utils.py ================================================ # This code is part of OpenFE and is licensed under the MIT license. # For details, see https://github.com/OpenFreeEnergy/openfe from plugcli.params import NOT_PARSED from openfecli.utils import import_thing def import_parameter(import_str: str): """Return object from a qualname, or NOT_PARSED if not valid. This is used specifically for parameter instantiation strategies based on importing an object given by the user on the command line. If the user input cannot interpreted as a qualname, then NOT_PARSED is returned. Parameters ---------- import_str : str the qualname Returns ------- Any : the desired object or NOT_PARSED if an error was encountered. """ try: result = import_thing(import_str) except (ImportError, AttributeError): result = NOT_PARSED return result ================================================ FILE: src/openfecli/plan_alchemical_networks_utils.py ================================================ # This code is part of OpenFE and is licensed under the MIT license. # For details, see https://github.com/OpenFreeEnergy/openfe from __future__ import annotations import pathlib from openfe import AlchemicalNetwork, LigandNetwork from openfecli.utils import write def plan_alchemical_network_output( alchemical_network: AlchemicalNetwork, ligand_network: LigandNetwork, folder_path: pathlib.Path, ): """Write the contents of an alchemical network into the structure""" base_name = folder_path.name folder_path.mkdir(parents=True, exist_ok=True) an_json = folder_path / f"{base_name}.json" alchemical_network.to_json(an_json) write("\t\t- " + base_name + ".json") ln_fname = "ligand_network.graphml" with open(folder_path / ln_fname, mode="w") as f: f.write(ligand_network.to_graphml()) write(f"\t\t- {ln_fname}") transformations_dir = folder_path / "transformations" transformations_dir.mkdir(parents=True, exist_ok=True) for transformation in alchemical_network.edges: transformation_name = transformation.name or transformation.key filename = f"{transformation_name}.json" transformation.to_json(transformations_dir / filename) write("\t\t\t\t- " + filename) ================================================ FILE: src/openfecli/plugins.py ================================================ # This code is part of OpenFE and is licensed under the MIT license. # For details, see https://github.com/OpenFreeEnergy/openfe from plugcli.plugin_management import CommandPlugin class OFECommandPlugin(CommandPlugin): def __init__(self, command, section, requires_ofe): super().__init__( command=command, section=section, requires_lib=requires_ofe, requires_cli=requires_ofe, ) ================================================ FILE: src/openfecli/tests/__init__.py ================================================ ================================================ FILE: src/openfecli/tests/clicktypes/test_hyphenchoice.py ================================================ import click import pytest from openfecli.clicktypes.hyphenchoice import HyphenAwareChoice class TestHyphenAwareChoice: @pytest.mark.parametrize("value", ["foo_bar_baz", "foo_bar-baz", "foo-bar_baz", "foo-bar-baz"]) def test_init(self, value): ch = HyphenAwareChoice([value]) assert ch.choices == ("foo-bar-baz",) @pytest.mark.parametrize("value", ["foo_bar_baz", "foo_bar-baz", "foo-bar_baz", "foo-bar-baz"]) def test_convert(self, value): ch = HyphenAwareChoice(["foo-bar-baz"]) # counting on __call__ to get to convert() assert ch(value) == "foo-bar-baz" ================================================ FILE: src/openfecli/tests/commands/__init__.py ================================================ ================================================ FILE: src/openfecli/tests/commands/conftest.py ================================================ import pytest @pytest.fixture def min_result_json(): """The minimal information a results json must have to be loaded by `openfe gather`.""" result = { "estimate": {}, "uncertainty": {}, "protocol_result": { "data": { "22940961": [ { "name": "lig_ejm_31 to lig_ejm_42 repeat 0 generation 0", "inputs": { "stateA": { "components": { "ligand": { "atoms": [ [1, 0, 0, False, 0, 0, {}], [6, 0, 0, True, 0, 0, {}], [6, 0, 0, True, 0, 0, {}], [6, 0, 0, True, 0, 0, {}], [6, 0, 0, True, 0, 0, {}], [6, 0, 0, True, 0, 0, {}], [6, 0, 0, True, 0, 0, {}], [1, 0, 0, False, 0, 0, {}], [17, 0, 0, False, 0, 0, {}], [6, 0, 0, False, 0, 0, {}], [8, 0, 0, False, 0, 0, {}], [7, 0, 0, False, 0, 0, {}], [1, 0, 0, False, 0, 0, {}], [6, 0, 0, True, 0, 0, {}], [6, 0, 0, True, 0, 0, {}], [6, 0, 0, True, 0, 0, {}], [7, 0, 0, True, 0, 0, {}], [6, 0, 0, True, 0, 0, {}], [6, 0, 0, True, 0, 0, {}], [1, 0, 0, False, 0, 0, {}], [7, 0, 0, False, 0, 0, {}], [1, 0, 0, False, 0, 0, {}], [6, 0, 0, False, 0, 0, {}], [8, 0, 0, False, 0, 0, {}], [6, 0, 0, False, 0, 0, {}], [1, 0, 0, False, 0, 0, {}], [1, 0, 0, False, 0, 0, {}], [1, 0, 0, False, 0, 0, {}], [1, 0, 0, False, 0, 0, {}], [1, 0, 0, False, 0, 0, {}], [17, 0, 0, False, 0, 0, {}], [1, 0, 0, False, 0, 0, {}], ], "bonds": [ [0, 1, 1, 0, {}], [1, 6, 12, 0, {}], [1, 2, 12, 0, {}], [2, 3, 12, 0, {}], [2, 31, 1, 0, {}], [3, 4, 12, 0, {}], [3, 30, 1, 0, {}], [4, 5, 12, 0, {}], [4, 9, 1, 0, {}], [5, 6, 12, 0, {}], [5, 8, 1, 0, {}], [6, 7, 1, 0, {}], [9, 10, 2, 0, {}], [9, 11, 1, 0, {}], [11, 12, 1, 0, {}], [11, 13, 1, 0, {}], [13, 18, 12, 0, {}], [13, 14, 12, 0, {}], [14, 15, 12, 0, {}], [14, 29, 1, 0, {}], [15, 16, 12, 0, {}], [15, 28, 1, 0, {}], [16, 17, 12, 0, {}], [17, 18, 12, 0, {}], [17, 20, 1, 0, {}], [18, 19, 1, 0, {}], [20, 21, 1, 0, {}], [20, 22, 1, 0, {}], [22, 23, 2, 0, {}], [22, 24, 1, 0, {}], [24, 25, 1, 0, {}], [24, 26, 1, 0, {}], [24, 27, 1, 0, {}], ], "conformer": [ "\u0093NUMPY\u0001\u0000v\u0000{'descr': '\u00e8\u00d9\u00ac\u001a\"\u00c0\u0080\u00b7@\u0082\u00e2\u00e7)\u00c0\b=\u009bU\u009f\u009b4\u00c0r\u00f9\u000f\u00e9\u00b7O\"\u00c0\u00de\u0093\u0087\u0085Z\u00f3+\u00c0o\u0012\u0083\u00c0\u00caA4\u00c0\u008a\u008e\u00e4\u00f2\u001f\u0092 \u00c0\u00aa`TR'\u00e0)\u00c0n4\u0080\u00b7@b5\u00c0\u00e8j+\u00f6\u0097\u00fd#\u00c0\u00b3{\u00f2\u00b0PK)\u00c0:#J{\u0083\u000f5\u00c0\u008c\u00dbh\u0000o!&\u00c0\u00d9=yX\u00a8\u0015&\u00c0\u0012\u0014?\u00c6\u00dc\u00b5,\u00c0\u00a5\u00bd\u00c1\u0017&S#\u00c0io\u00f0\u0085\u00c9\u0014\"\u00c0\u00ab\u00cf\u00d5V\u00ec\u000f,\u00c0\u00e0\u009c\u0011\u00a5\u00bd\u0001\u0013\u00c0\u00ad\u00fa\\m\u00c5~\u001e\u00c0L7\u0089A`\u00a5/\u00c0\u0002\u009a\b\u001b\u009e\u00de\r\u00c0\u00c8\u0098\u00bb\u0096\u0090O\u0014\u00c0N\u00d1\u0091\\\u00fes0\u00c0", {}, ], "molprops": {"ofe-name": "lig_ejm_31"}, "__qualname__": "SmallMoleculeComponent", "__module__": "gufe.components.smallmoleculecomponent", }, "solvent": { "smiles": "O", "positive_ion": "Na+", "negative_ion": "Cl-", "ion_concentration": "0.15 molar", "neutralize": True, "__qualname__": "SolventComponent", "__module__": "gufe.components.solventcomponent", }, }, "name": "lig_ejm_31_solvent", "__qualname__": "ChemicalSystem", "__module__": "gufe.chemicalsystem", }, "stateB": { "components": { "ligand": { "atoms": [ [1, 0, 0, False, 0, 0, {}], [6, 0, 0, True, 0, 0, {}], [6, 0, 0, True, 0, 0, {}], [6, 0, 0, True, 0, 0, {}], [6, 0, 0, True, 0, 0, {}], [6, 0, 0, True, 0, 0, {}], [6, 0, 0, True, 0, 0, {}], [1, 0, 0, False, 0, 0, {}], [17, 0, 0, False, 0, 0, {}], [6, 0, 0, False, 0, 0, {}], [8, 0, 0, False, 0, 0, {}], [7, 0, 0, False, 0, 0, {}], [1, 0, 0, False, 0, 0, {}], [6, 0, 0, True, 0, 0, {}], [6, 0, 0, True, 0, 0, {}], [6, 0, 0, True, 0, 0, {}], [7, 0, 0, True, 0, 0, {}], [6, 0, 0, True, 0, 0, {}], [6, 0, 0, True, 0, 0, {}], [1, 0, 0, False, 0, 0, {}], [7, 0, 0, False, 0, 0, {}], [1, 0, 0, False, 0, 0, {}], [6, 0, 0, False, 0, 0, {}], [8, 0, 0, False, 0, 0, {}], [6, 0, 0, False, 0, 0, {}], [1, 0, 0, False, 0, 0, {}], [1, 0, 0, False, 0, 0, {}], [6, 0, 0, False, 0, 0, {}], [1, 0, 0, False, 0, 0, {}], [1, 0, 0, False, 0, 0, {}], [1, 0, 0, False, 0, 0, {}], [1, 0, 0, False, 0, 0, {}], [1, 0, 0, False, 0, 0, {}], [17, 0, 0, False, 0, 0, {}], [1, 0, 0, False, 0, 0, {}], ], "bonds": [ [0, 1, 1, 0, {}], [1, 6, 12, 0, {}], [1, 2, 12, 0, {}], [2, 3, 12, 0, {}], [2, 34, 1, 0, {}], [3, 4, 12, 0, {}], [3, 33, 1, 0, {}], [4, 5, 12, 0, {}], [4, 9, 1, 0, {}], [5, 6, 12, 0, {}], [5, 8, 1, 0, {}], [6, 7, 1, 0, {}], [9, 10, 2, 0, {}], [9, 11, 1, 0, {}], [11, 12, 1, 0, {}], [11, 13, 1, 0, {}], [13, 18, 12, 0, {}], [13, 14, 12, 0, {}], [14, 15, 12, 0, {}], [14, 32, 1, 0, {}], [15, 16, 12, 0, {}], [15, 31, 1, 0, {}], [16, 17, 12, 0, {}], [17, 18, 12, 0, {}], [17, 20, 1, 0, {}], [18, 19, 1, 0, {}], [20, 21, 1, 0, {}], [20, 22, 1, 0, {}], [22, 23, 2, 0, {}], [22, 24, 1, 0, {}], [24, 25, 1, 0, {}], [24, 26, 1, 0, {}], [24, 27, 1, 0, {}], [27, 28, 1, 0, {}], [27, 29, 1, 0, {}], [27, 30, 1, 0, {}], ], "conformer": [ "\u0093NUMPY\u0001\u0000v\u0000{'descr': '\u00e8\u00d9\u00ac\u00fa\\\f\u00c0\u00aeG\u00e1z\u0014\u00ce/\u00c0\u0001M\u0084\rO\u00af\u001c\u00c0\u00d5x\u00e9&1\u0088\u0004\u00c0M\u00f3\u008eSt\u00e4/\u00c0\u009c3\u00a2\u00b47X\"\u00c0\u0088\u00f4\u00db\u00d7\u0081\u00b3\u0011\u00c0U\u00c1\u00a8\u00a4N`.\u00c0q\u001b\r\u00e0-\u00d0\u001e\u00c0\u00af%\u00e4\u0083\u009e\u008d\u001c\u00c0\u0002+\u0087\u0016\u00d9\u000e.\u00c0-!\u001f\u00f4l6 \u00c0\u009bU\u009f\u00ab\u00ad\u00d8\u001c\u00c0xz\u00a5,C\u00bc+\u00c0T\u00e3\u00a5\u009b\u00c4\u00a0\u001f\u00c0\u0099\u00bb\u0096\u0090\u000f\u001a \u00c09\u00b4\u00c8v\u00be\u00ff/\u00c0:\u0092\u00cb\u007fH\u00bf\u001d\u00c0:#J{\u0083o\u001f\u00c0\u001f\u0085\u00ebQ\u00b8\u00de0\u00c0\u00f8\u00c2d\u00aa`t!\u00c0\t\u001b\u009e^)k\"\u00c0\u00fee\u00f7\u00e4a\u00010\u00c0b\u0010X9\u00b4(#\u00c0\u0006\u0081\u0095C\u008b,#\u00c0h\"lxz\u00e5-\u00c0\u0016\u00fb\u00cb\u00ee\u00c9\u00c3$\u00c0\u00c1\u00ca\u00a1E\u00b6s%\u00c0\u00cd;N\u00d1\u0091<.\u00c0\u0093\u00a9\u0082QI\u00bd$\u00c0xz\u00a5,C\u00fc&\u00c0\u00ec/\u00bb'\u000f;0\u00c0\u00b6\u0084|\u00d0\u00b3\u0019#\u00c0\u0002+\u0087\u0016\u00d9N&\u00c0\u008c\u00dbh\u0000oA1\u00c0\u00fc\u0018s\u00d7\u0012r!\u00c0R'\u00a0\u0089\u00b0\u0001$\u00c0A\u00f1c\u00cc]+1\u00c04\u00116<\u00bd2 \u00c0\u0010\u00e9\u00b7\u00af\u0003g#\u00c0 c\u00eeZB\u00fe1\u00c0\u00b2\u009d\u00ef\u00a7\u00c6+#\u00c0\u00b8\u00af\u0003\u00e7\u008c\u00e8'\u00c0V\u000e-\u00b2\u009do2\u00c00\u00bb'\u000f\u000b\u00d5$\u00c0\u00e8\u00d9\u00ac\u00fa\\\r)\u00c0+\u00f6\u0097\u00dd\u0093\u00872\u00c0\u00ac\u001cZd;_!\u00c0\u00b8\u00af\u0003\u00e7\u008c((\u00c0X\u00ca2\u00c4\u00b1n3\u00c0\u00deq\u008a\u008e\u00e4r\u001e\u00c0\u00a0\u0089\u00b0\u00e1\u00e9\u00f5&\u00c0\"\u00fd\u00f6u\u00e0|3\u00c0yX\u00a85\u00cd\u001b\"\u00c0(\u000f\u000b\u00b5\u00a6\u0019*\u00c0\u00e3\u00a5\u009b\u00c4 \u00904\u00c01\b\u00ac\u001cZ\u00e4\"\u00c0Y\u00868\u00d6\u00c5\u00ed(\u00c0\u00a2E\u00b6\u00f3\u00fdd5\u00c0\u00d5\u00e7j+\u00f6\u00b7#\u00c0\u008cJ\u00ea\u00044q+\u00c0\u00e0\u00be\u000e\u009c3B4\u00c0\u00b3{\u00f2\u00b0Pk\u001f\u00c0\u00bb'\u000f\u000b\u00b5\u00c6+\u00c0\u00b6\u00f3\u00fd\u00d4x\t5\u00c0vq\u001b\r\u00e0M \u00c0\u008c\u00dbh\u0000o!-\u00c0\u00bc\u0096\u0090\u000fz\u00d65\u00c0_\u0098L\u0015\u008c\u00ca\u001d\u00c0\u00d1\u0091\\\u00feC\u00fa,\u00c0a\u00c3\u00d3+e94\u00c0K\u00ea\u00044\u00116\u001c\u00c0\u00a2\u00b47\u00f8\u00c2\u0084*\u00c0[\u00b1\u00bf\u00ec\u009el5\u00c0X9\u00b4\u00c8v\u001e&\u00c0p_\u0007\u00ce\u0019\u0011&\u00c0\u00ce\u0088\u00d2\u00de\u00e0\u00ab,\u00c0\u00d5\u00e7j+\u00f6W#\u00c0^\u00baI\f\u0002\u000b\"\u00c08gDio\u0010,\u00c0\u00c6m4\u0080\u00b7\u0000\u0013\u00c0\\ A\u00f1c\u008c\u001e\u00c0\u009e^)\u00cb\u0010\u00a7/\u00c0\u00e7\u00fb\u00a9\u00f1\u00d2\u00cd\r\u00c0\u009d\u0011\u00a5\u00bd\u00c1W\u0014\u00c0\u00f7\u00e4a\u00a1\u00d6t0\u00c0", {}, ], "molprops": {"ofe-name": "lig_ejm_42"}, "__qualname__": "SmallMoleculeComponent", "__module__": "gufe.components.smallmoleculecomponent", }, "solvent": { "smiles": "O", "positive_ion": "Na+", "negative_ion": "Cl-", "ion_concentration": "0.15 molar", "neutralize": True, "__qualname__": "SolventComponent", "__module__": "gufe.components.solventcomponent", }, }, "name": "lig_ejm_42_solvent", "__qualname__": "ChemicalSystem", "__module__": "gufe.chemicalsystem", }, "ligandmapping": { "componentA": { "atoms": [ [1, 0, 0, False, 0, 0, {}], [6, 0, 0, True, 0, 0, {}], [6, 0, 0, True, 0, 0, {}], [6, 0, 0, True, 0, 0, {}], [6, 0, 0, True, 0, 0, {}], [6, 0, 0, True, 0, 0, {}], [6, 0, 0, True, 0, 0, {}], [1, 0, 0, False, 0, 0, {}], [17, 0, 0, False, 0, 0, {}], [6, 0, 0, False, 0, 0, {}], [8, 0, 0, False, 0, 0, {}], [7, 0, 0, False, 0, 0, {}], [1, 0, 0, False, 0, 0, {}], [6, 0, 0, True, 0, 0, {}], [6, 0, 0, True, 0, 0, {}], [6, 0, 0, True, 0, 0, {}], [7, 0, 0, True, 0, 0, {}], [6, 0, 0, True, 0, 0, {}], [6, 0, 0, True, 0, 0, {}], [1, 0, 0, False, 0, 0, {}], [7, 0, 0, False, 0, 0, {}], [1, 0, 0, False, 0, 0, {}], [6, 0, 0, False, 0, 0, {}], [8, 0, 0, False, 0, 0, {}], [6, 0, 0, False, 0, 0, {}], [1, 0, 0, False, 0, 0, {}], [1, 0, 0, False, 0, 0, {}], [1, 0, 0, False, 0, 0, {}], [1, 0, 0, False, 0, 0, {}], [1, 0, 0, False, 0, 0, {}], [17, 0, 0, False, 0, 0, {}], [1, 0, 0, False, 0, 0, {}], ], "bonds": [ [0, 1, 1, 0, {}], [1, 6, 12, 0, {}], [1, 2, 12, 0, {}], [2, 3, 12, 0, {}], [2, 31, 1, 0, {}], [3, 4, 12, 0, {}], [3, 30, 1, 0, {}], [4, 5, 12, 0, {}], [4, 9, 1, 0, {}], [5, 6, 12, 0, {}], [5, 8, 1, 0, {}], [6, 7, 1, 0, {}], [9, 10, 2, 0, {}], [9, 11, 1, 0, {}], [11, 12, 1, 0, {}], [11, 13, 1, 0, {}], [13, 18, 12, 0, {}], [13, 14, 12, 0, {}], [14, 15, 12, 0, {}], [14, 29, 1, 0, {}], [15, 16, 12, 0, {}], [15, 28, 1, 0, {}], [16, 17, 12, 0, {}], [17, 18, 12, 0, {}], [17, 20, 1, 0, {}], [18, 19, 1, 0, {}], [20, 21, 1, 0, {}], [20, 22, 1, 0, {}], [22, 23, 2, 0, {}], [22, 24, 1, 0, {}], [24, 25, 1, 0, {}], [24, 26, 1, 0, {}], [24, 27, 1, 0, {}], ], "conformer": [ "\u0093NUMPY\u0001\u0000v\u0000{'descr': '\u00e8\u00d9\u00ac\u001a\"\u00c0\u0080\u00b7@\u0082\u00e2\u00e7)\u00c0\b=\u009bU\u009f\u009b4\u00c0r\u00f9\u000f\u00e9\u00b7O\"\u00c0\u00de\u0093\u0087\u0085Z\u00f3+\u00c0o\u0012\u0083\u00c0\u00caA4\u00c0\u008a\u008e\u00e4\u00f2\u001f\u0092 \u00c0\u00aa`TR'\u00e0)\u00c0n4\u0080\u00b7@b5\u00c0\u00e8j+\u00f6\u0097\u00fd#\u00c0\u00b3{\u00f2\u00b0PK)\u00c0:#J{\u0083\u000f5\u00c0\u008c\u00dbh\u0000o!&\u00c0\u00d9=yX\u00a8\u0015&\u00c0\u0012\u0014?\u00c6\u00dc\u00b5,\u00c0\u00a5\u00bd\u00c1\u0017&S#\u00c0io\u00f0\u0085\u00c9\u0014\"\u00c0\u00ab\u00cf\u00d5V\u00ec\u000f,\u00c0\u00e0\u009c\u0011\u00a5\u00bd\u0001\u0013\u00c0\u00ad\u00fa\\m\u00c5~\u001e\u00c0L7\u0089A`\u00a5/\u00c0\u0002\u009a\b\u001b\u009e\u00de\r\u00c0\u00c8\u0098\u00bb\u0096\u0090O\u0014\u00c0N\u00d1\u0091\\\u00fes0\u00c0", {}, ], "molprops": {"ofe-name": "lig_ejm_31"}, "__qualname__": "SmallMoleculeComponent", "__module__": "gufe.components.smallmoleculecomponent", }, "componentB": { "atoms": [ [1, 0, 0, False, 0, 0, {}], [6, 0, 0, True, 0, 0, {}], [6, 0, 0, True, 0, 0, {}], [6, 0, 0, True, 0, 0, {}], [6, 0, 0, True, 0, 0, {}], [6, 0, 0, True, 0, 0, {}], [6, 0, 0, True, 0, 0, {}], [1, 0, 0, False, 0, 0, {}], [17, 0, 0, False, 0, 0, {}], [6, 0, 0, False, 0, 0, {}], [8, 0, 0, False, 0, 0, {}], [7, 0, 0, False, 0, 0, {}], [1, 0, 0, False, 0, 0, {}], [6, 0, 0, True, 0, 0, {}], [6, 0, 0, True, 0, 0, {}], [6, 0, 0, True, 0, 0, {}], [7, 0, 0, True, 0, 0, {}], [6, 0, 0, True, 0, 0, {}], [6, 0, 0, True, 0, 0, {}], [1, 0, 0, False, 0, 0, {}], [7, 0, 0, False, 0, 0, {}], [1, 0, 0, False, 0, 0, {}], [6, 0, 0, False, 0, 0, {}], [8, 0, 0, False, 0, 0, {}], [6, 0, 0, False, 0, 0, {}], [1, 0, 0, False, 0, 0, {}], [1, 0, 0, False, 0, 0, {}], [6, 0, 0, False, 0, 0, {}], [1, 0, 0, False, 0, 0, {}], [1, 0, 0, False, 0, 0, {}], [1, 0, 0, False, 0, 0, {}], [1, 0, 0, False, 0, 0, {}], [1, 0, 0, False, 0, 0, {}], [17, 0, 0, False, 0, 0, {}], [1, 0, 0, False, 0, 0, {}], ], "bonds": [ [0, 1, 1, 0, {}], [1, 6, 12, 0, {}], [1, 2, 12, 0, {}], [2, 3, 12, 0, {}], [2, 34, 1, 0, {}], [3, 4, 12, 0, {}], [3, 33, 1, 0, {}], [4, 5, 12, 0, {}], [4, 9, 1, 0, {}], [5, 6, 12, 0, {}], [5, 8, 1, 0, {}], [6, 7, 1, 0, {}], [9, 10, 2, 0, {}], [9, 11, 1, 0, {}], [11, 12, 1, 0, {}], [11, 13, 1, 0, {}], [13, 18, 12, 0, {}], [13, 14, 12, 0, {}], [14, 15, 12, 0, {}], [14, 32, 1, 0, {}], [15, 16, 12, 0, {}], [15, 31, 1, 0, {}], [16, 17, 12, 0, {}], [17, 18, 12, 0, {}], [17, 20, 1, 0, {}], [18, 19, 1, 0, {}], [20, 21, 1, 0, {}], [20, 22, 1, 0, {}], [22, 23, 2, 0, {}], [22, 24, 1, 0, {}], [24, 25, 1, 0, {}], [24, 26, 1, 0, {}], [24, 27, 1, 0, {}], [27, 28, 1, 0, {}], [27, 29, 1, 0, {}], [27, 30, 1, 0, {}], ], "conformer": [ "\u0093NUMPY\u0001\u0000v\u0000{'descr': '\u00e8\u00d9\u00ac\u00fa\\\f\u00c0\u00aeG\u00e1z\u0014\u00ce/\u00c0\u0001M\u0084\rO\u00af\u001c\u00c0\u00d5x\u00e9&1\u0088\u0004\u00c0M\u00f3\u008eSt\u00e4/\u00c0\u009c3\u00a2\u00b47X\"\u00c0\u0088\u00f4\u00db\u00d7\u0081\u00b3\u0011\u00c0U\u00c1\u00a8\u00a4N`.\u00c0q\u001b\r\u00e0-\u00d0\u001e\u00c0\u00af%\u00e4\u0083\u009e\u008d\u001c\u00c0\u0002+\u0087\u0016\u00d9\u000e.\u00c0-!\u001f\u00f4l6 \u00c0\u009bU\u009f\u00ab\u00ad\u00d8\u001c\u00c0xz\u00a5,C\u00bc+\u00c0T\u00e3\u00a5\u009b\u00c4\u00a0\u001f\u00c0\u0099\u00bb\u0096\u0090\u000f\u001a \u00c09\u00b4\u00c8v\u00be\u00ff/\u00c0:\u0092\u00cb\u007fH\u00bf\u001d\u00c0:#J{\u0083o\u001f\u00c0\u001f\u0085\u00ebQ\u00b8\u00de0\u00c0\u00f8\u00c2d\u00aa`t!\u00c0\t\u001b\u009e^)k\"\u00c0\u00fee\u00f7\u00e4a\u00010\u00c0b\u0010X9\u00b4(#\u00c0\u0006\u0081\u0095C\u008b,#\u00c0h\"lxz\u00e5-\u00c0\u0016\u00fb\u00cb\u00ee\u00c9\u00c3$\u00c0\u00c1\u00ca\u00a1E\u00b6s%\u00c0\u00cd;N\u00d1\u0091<.\u00c0\u0093\u00a9\u0082QI\u00bd$\u00c0xz\u00a5,C\u00fc&\u00c0\u00ec/\u00bb'\u000f;0\u00c0\u00b6\u0084|\u00d0\u00b3\u0019#\u00c0\u0002+\u0087\u0016\u00d9N&\u00c0\u008c\u00dbh\u0000oA1\u00c0\u00fc\u0018s\u00d7\u0012r!\u00c0R'\u00a0\u0089\u00b0\u0001$\u00c0A\u00f1c\u00cc]+1\u00c04\u00116<\u00bd2 \u00c0\u0010\u00e9\u00b7\u00af\u0003g#\u00c0 c\u00eeZB\u00fe1\u00c0\u00b2\u009d\u00ef\u00a7\u00c6+#\u00c0\u00b8\u00af\u0003\u00e7\u008c\u00e8'\u00c0V\u000e-\u00b2\u009do2\u00c00\u00bb'\u000f\u000b\u00d5$\u00c0\u00e8\u00d9\u00ac\u00fa\\\r)\u00c0+\u00f6\u0097\u00dd\u0093\u00872\u00c0\u00ac\u001cZd;_!\u00c0\u00b8\u00af\u0003\u00e7\u008c((\u00c0X\u00ca2\u00c4\u00b1n3\u00c0\u00deq\u008a\u008e\u00e4r\u001e\u00c0\u00a0\u0089\u00b0\u00e1\u00e9\u00f5&\u00c0\"\u00fd\u00f6u\u00e0|3\u00c0yX\u00a85\u00cd\u001b\"\u00c0(\u000f\u000b\u00b5\u00a6\u0019*\u00c0\u00e3\u00a5\u009b\u00c4 \u00904\u00c01\b\u00ac\u001cZ\u00e4\"\u00c0Y\u00868\u00d6\u00c5\u00ed(\u00c0\u00a2E\u00b6\u00f3\u00fdd5\u00c0\u00d5\u00e7j+\u00f6\u00b7#\u00c0\u008cJ\u00ea\u00044q+\u00c0\u00e0\u00be\u000e\u009c3B4\u00c0\u00b3{\u00f2\u00b0Pk\u001f\u00c0\u00bb'\u000f\u000b\u00b5\u00c6+\u00c0\u00b6\u00f3\u00fd\u00d4x\t5\u00c0vq\u001b\r\u00e0M \u00c0\u008c\u00dbh\u0000o!-\u00c0\u00bc\u0096\u0090\u000fz\u00d65\u00c0_\u0098L\u0015\u008c\u00ca\u001d\u00c0\u00d1\u0091\\\u00feC\u00fa,\u00c0a\u00c3\u00d3+e94\u00c0K\u00ea\u00044\u00116\u001c\u00c0\u00a2\u00b47\u00f8\u00c2\u0084*\u00c0[\u00b1\u00bf\u00ec\u009el5\u00c0X9\u00b4\u00c8v\u001e&\u00c0p_\u0007\u00ce\u0019\u0011&\u00c0\u00ce\u0088\u00d2\u00de\u00e0\u00ab,\u00c0\u00d5\u00e7j+\u00f6W#\u00c0^\u00baI\f\u0002\u000b\"\u00c08gDio\u0010,\u00c0\u00c6m4\u0080\u00b7\u0000\u0013\u00c0\\ A\u00f1c\u008c\u001e\u00c0\u009e^)\u00cb\u0010\u00a7/\u00c0\u00e7\u00fb\u00a9\u00f1\u00d2\u00cd\r\u00c0\u009d\u0011\u00a5\u00bd\u00c1W\u0014\u00c0\u00f7\u00e4a\u00a1\u00d6t0\u00c0", {}, ], "molprops": {"ofe-name": "lig_ejm_42"}, "__qualname__": "SmallMoleculeComponent", "__module__": "gufe.components.smallmoleculecomponent", }, "componentA_to_componentB": { "0": 0, "1": 1, "2": 2, "3": 3, "4": 4, "5": 5, "6": 6, "7": 7, "8": 8, "9": 9, "10": 10, "11": 11, "12": 12, "13": 13, "14": 14, "15": 15, "16": 16, "17": 17, "18": 18, "19": 19, "20": 20, "21": 21, "22": 22, "23": 23, "24": 24, "25": 26, "27": 25, "28": 31, "29": 32, "30": 33, "31": 34, }, "annotations": '{"score": 0.09516258196404048}', "__qualname__": "LigandAtomMapping", "__module__": "gufe.mapping.ligandatommapping", }, }, } ] } }, "unit_results": { "ProtocolUnitResult-e85": {"name": "lig_ejm_31 to lig_ejm_42 repeat 0 generation 0"}, "ProtocolUnitFailure-4c9": { "name": "lig_ejm_31 to lig_ejm_42 repeat 0 generation 0", "exception": ["Simulation_NanError"], }, }, } return result ================================================ FILE: src/openfecli/tests/commands/test_atommapping.py ================================================ from unittest import mock import click import pytest from click.testing import CliRunner from openfe.setup import LigandAtomMapping, LomapAtomMapper from openfecli.commands.atommapping import ( atommapping, atommapping_print_dict_main, atommapping_visualize_main, generate_mapping, ) from openfecli.parameters import MOL @pytest.fixture def molA_args(): return ["--mol", "Cc1ccccc1"] @pytest.fixture def molB_args(): return ["--mol", "CC1CCCCC1"] @pytest.fixture def mapper_args(): return ["--mapper", "LomapAtomMapper"] @pytest.fixture def mols_AB(molA_args, molB_args): return MOL.get(molA_args[1]), MOL.get(molB_args[1]) def print_test(mapper, molA, molB): print(molA.smiles) print(molB.smiles) print(mapper.__class__.__name__) def print_test_with_file(mapper, molA, molB, file, ext): print_test(mapper, molA, molB) print(file.name) print(ext) @pytest.mark.parametrize("with_file", [True, False]) def test_atommapping(molA_args, molB_args, mapper_args, with_file): # Patch out the main function with a simple function to output # information about the objects we pass to the main; test the output of # that using tools from click. This tests the creation of objects from # user input on the command line. args = molA_args + molB_args + mapper_args expected_output = f"{molA_args[1]}\n{molB_args[1]}\n{mapper_args[1]}\n" patch_base = "openfecli.commands.atommapping." if with_file: args += ["-o", "myfile.png"] expected_output += "myfile.png\npng\n" patch_loc = patch_base + "atommapping_visualize_main" patch_func = print_test_with_file else: patch_loc = patch_base + "atommapping_print_dict_main" patch_func = print_test runner = CliRunner() with mock.patch(patch_loc, patch_func): with runner.isolated_filesystem(): result = runner.invoke(atommapping, args) assert result.exit_code == 0 assert result.output == expected_output def test_atommapping_bad_number_of_mols(molA_args, mapper_args): runner = CliRunner() with runner.isolated_filesystem(): result = runner.invoke(atommapping, molA_args + mapper_args) assert result.exit_code == click.BadParameter.exit_code assert "exactly twice" in result.output def test_atommapping_missing_mapper(molA_args, molB_args): runner = CliRunner() with runner.isolated_filesystem(): result = runner.invoke(atommapping, molA_args + molB_args) assert result.exit_code == click.BadParameter.exit_code assert "Missing option '--mapper'" in result.output @pytest.mark.parametrize("n_mappings", [0, 1, 2]) def test_generate_mapping(n_mappings, mols_AB): molA, molB = mols_AB mappings = [ LigandAtomMapping(molA, molB, {i: i for i in range(7)}), LigandAtomMapping(molA, molB, {i: (i + 1) % 7 for i in range(7)}), ] mapper = mock.Mock(suggest_mappings=mock.Mock(return_value=mappings[:n_mappings])) if n_mappings == 1: assert generate_mapping(mapper, molA, molB) == mappings[0] else: with pytest.raises(click.UsageError, match="exactly 1 mapping"): generate_mapping(mapper, molA, molB) def test_atommapping_print_dict_main(capsys, mols_AB): molA, molB = mols_AB mapper = LomapAtomMapper mapping = LigandAtomMapping(molA, molB, {i: i for i in range(7)}) with mock.patch("openfecli.commands.atommapping.generate_mapping", mock.Mock(return_value=mapping)): # fmt: skip atommapping_print_dict_main(mapper, molA, molB) captured = capsys.readouterr() assert captured.out == str(mapping.componentA_to_componentB) + "\n" def test_atommapping_visualize_main(mols_AB): molA, molB = mols_AB mapper = LomapAtomMapper pytest.skip() # TODO: probably with a smoke test def test_atommapping_visualize_main_bad_extension(mols_AB, tmp_path): molA, molB = mols_AB mapper = LomapAtomMapper mapping = LigandAtomMapping(molA, molB, {i: i for i in range(7)}) with mock.patch("openfecli.commands.atommapping.generate_mapping", mock.Mock(return_value=mapping)): # fmt: skip with open(tmp_path / "foo.bar", mode="w") as f: with pytest.raises(click.BadParameter, match="Unknown file format"): atommapping_visualize_main(mapper, molA, molB, f, "bar") ================================================ FILE: src/openfecli/tests/commands/test_charge_generation.py ================================================ import logging import numpy as np import pytest from click import ClickException from click.testing import CliRunner from gufe import SmallMoleculeComponent from openff.toolkit import Molecule from openff.units import unit from openff.utilities.testing import skip_if_missing from openfe.protocols.openmm_utils.charge_generation import ( HAS_NAGL, HAS_OPENEYE, ) from openfecli.commands.generate_partial_charges import charge_molecules @pytest.fixture def yaml_nagl_settings(): return """\ partial_charge: method: nagl settings: nagl_model: openff-gnn-am1bcc-0.1.0-rc.3.pt """ @pytest.fixture def methane() -> Molecule: # ensure consistent atom ordering methane = Molecule.from_mapped_smiles("[C:1]([H:2])([H:3])([H:4])[H:5]") methane.generate_conformers(n_conformers=1) return methane @pytest.fixture def methane_with_charges(methane) -> Molecule: methane._partial_charges = [-1.0, 0.25, 0.25, 0.25, 0.25] * unit.elementary_charge return methane def test_missing_output(methane, tmp_path): runner = CliRunner() mol_path = tmp_path / "methane.sdf" methane.to_file(str(mol_path), "sdf") cli_result = runner.invoke(charge_molecules, ["-M", mol_path]) assert cli_result.exit_code == 2 assert "Missing option '-o'" in cli_result.output def test_write_charges_to_input(methane, tmp_path): runner = CliRunner() mol_path = tmp_path / "methane.sdf" methane.to_file(str(mol_path), "sdf") with runner.isolated_filesystem(): # check an error is raised if we try to overwrite the input with pytest.raises(FileExistsError, match="The output file "): _ = runner.invoke( charge_molecules, ["-M", mol_path, "-o", mol_path], catch_exceptions=False ) def test_charge_molecules_default(methane, tmp_path, caplog): runner = CliRunner() mol_path = tmp_path / "methane.sdf" methane.to_file(str(mol_path), "sdf") output_file = str(tmp_path / "charged_methane.sdf") caplog.set_level(logging.INFO) with runner.isolated_filesystem(): # make sure the charges are picked up result = runner.invoke(charge_molecules, ["-M", mol_path, "-o", output_file]) assert result.exit_code == 0 assert "Partial charges are present for" in caplog.text assert "Partial Charge Generation: am1bcc" in result.output # make sure the charges have been saved methane = SmallMoleculeComponent.from_sdf_file(filename=output_file) off_methane = methane.to_openff() assert off_methane.partial_charges is not None assert len(off_methane.partial_charges) == 5 @pytest.mark.parametrize( "overwrite, expected_charges", [ pytest.param(False, [-1.0, 0.25, 0.25, 0.25, 0.25], id="Don't overwrite"), pytest.param(True, [-0.1084, 0.0271, 0.0271, 0.0271, 0.0271], id="Overwrite"), ], ) def test_charge_molecules_overwrite( overwrite, tmp_path, caplog, methane_with_charges, expected_charges ): runner = CliRunner() mol_path = tmp_path / "methane.sdf" methane_with_charges.to_file(str(mol_path), "sdf") output_file = str(tmp_path / "charged_methane.sdf") args = ["-M", mol_path, "-o", output_file] if overwrite: args.append("--overwrite-charges") with runner.isolated_filesystem(): # make sure the charges are picked up caplog.set_level(logging.INFO) result = runner.invoke(charge_molecules, args) assert result.exit_code == 0 assert "Partial charges are present for" in caplog.text assert "Partial Charge Generation: am1bcc" in result.output if overwrite: assert "Overwriting partial charges" in result.output # make sure the charges have not changed from the inputs methane = SmallMoleculeComponent.from_sdf_file(filename=output_file) off_methane = methane.to_openff() assert np.allclose(off_methane.partial_charges.m, expected_charges) @pytest.mark.parametrize( "ncores", [ pytest.param(1, id="1"), pytest.param(2, id="2"), ], ) @pytest.mark.skipif( not HAS_NAGL, reason="needs NAGL", ) @pytest.mark.skipif( HAS_OPENEYE, reason="cannot use NAGL with rdkit backend when OpenEye is installed" ) def test_charge_settings(methane, tmp_path, caplog, yaml_nagl_settings, ncores): runner = CliRunner() mol_path = tmp_path / "methane.sdf" methane.to_file(str(mol_path), "sdf") output_file = str(tmp_path / "charged_methane.sdf") # use nagl charges for CI speed! settings_path = tmp_path / "settings.yaml" with open(settings_path, "w") as f: f.write(yaml_nagl_settings) with runner.isolated_filesystem(): caplog.set_level(logging.INFO) # make sure the charges are picked up result = runner.invoke( charge_molecules, ["-M", mol_path, "-o", output_file, "-s", settings_path, "-n", ncores] ) assert result.exit_code == 0 assert "Partial charges are present for" in caplog.text assert "Partial Charge Generation: nagl" in result.output # make sure the charges have been saved methane = SmallMoleculeComponent.from_sdf_file(filename=output_file) off_methane = methane.to_openff() assert off_methane.partial_charges is not None assert len(off_methane.partial_charges) == 5 ================================================ FILE: src/openfecli/tests/commands/test_gather/test_abfe_full_results_multiple_units_dg_.tsv ================================================ ligand DG (kcal/mol) std dev uncertainty (kcal/mol) 1 -20.87 0.47 ================================================ FILE: src/openfecli/tests/commands/test_gather/test_abfe_full_results_multiple_units_raw_.tsv ================================================ leg ligand DG (kcal/mol) MBAR uncertainty (kcal/mol) complex 1 34.77 0.81 complex 1 36.17 0.80 complex 1 36.34 0.91 solvent 1 5.5 1.4 solvent 1 5.4 1.4 solvent 1 6.5 1.4 standard_state_correction 1 -9.0 0.0 standard_state_correction 1 -9.3 0.0 standard_state_correction 1 -8.9 0.0 ================================================ FILE: src/openfecli/tests/commands/test_gather/test_abfe_full_results_single_unit_dg_.tsv ================================================ ligand DG (kcal/mol) std dev uncertainty (kcal/mol) 1 -18.36 0.98 ================================================ FILE: src/openfecli/tests/commands/test_gather/test_abfe_full_results_single_unit_raw_.tsv ================================================ leg ligand DG (kcal/mol) MBAR uncertainty (kcal/mol) complex 1 36.87 0.36 complex 1 39.24 0.44 complex 1 37.46 0.48 solvent 1 10.57 0.66 solvent 1 10.48 0.65 solvent 1 10.41 0.66 standard_state_correction 1 -8.9 0.0 standard_state_correction 1 -9.1 0.0 standard_state_correction 1 -9.0 0.0 ================================================ FILE: src/openfecli/tests/commands/test_gather/test_abfe_single_repeat_multiple_units_dg_.tsv ================================================ ligand DG (kcal/mol) MBAR uncertainty (kcal/mol) 1 -20.3 1.6 ================================================ FILE: src/openfecli/tests/commands/test_gather/test_abfe_single_repeat_multiple_units_raw_.tsv ================================================ leg ligand DG (kcal/mol) MBAR uncertainty (kcal/mol) complex 1 34.77 0.81 solvent 1 5.5 1.4 standard_state_correction 1 -9.0 0.0 ================================================ FILE: src/openfecli/tests/commands/test_gather/test_abfe_single_repeat_single_unit_dg_.tsv ================================================ ligand DG (kcal/mol) MBAR uncertainty (kcal/mol) 1 -17.36 0.75 ================================================ FILE: src/openfecli/tests/commands/test_gather/test_abfe_single_repeat_single_unit_raw_.tsv ================================================ leg ligand DG (kcal/mol) MBAR uncertainty (kcal/mol) complex 1 36.87 0.36 solvent 1 10.57 0.66 standard_state_correction 1 -8.9 0.0 ================================================ FILE: src/openfecli/tests/commands/test_gather/test_cmet_failed_edge_ddg_.tsv ================================================ Loading results: ligand_i ligand_j DDG(i->j) (kcal/mol) uncertainty (kcal/mol) lig_CHEMBL3402745_200_5 lig_CHEMBL3402744_300_4 1.1 0.1 ================================================ FILE: src/openfecli/tests/commands/test_gather/test_cmet_failed_edge_raw_.tsv ================================================ Loading results: leg ligand_i ligand_j DG(i->j) (kcal/mol) MBAR uncertainty (kcal/mol) complex lig_CHEMBL3402745_200_5 lig_CHEMBL3402744_300_4 -12.54 0.06 complex lig_CHEMBL3402745_200_5 lig_CHEMBL3402744_300_4 -12.31 0.06 complex lig_CHEMBL3402745_200_5 lig_CHEMBL3402744_300_4 -12.19 0.07 solvent lig_CHEMBL3402745_200_5 lig_CHEMBL3402744_300_4 Error Error solvent lig_CHEMBL3402745_200_5 lig_CHEMBL3402744_300_4 -13.48 0.06 solvent lig_CHEMBL3402745_200_5 lig_CHEMBL3402744_300_4 -13.50 0.05 ================================================ FILE: src/openfecli/tests/commands/test_gather/test_cmet_full_results_ddg_.tsv ================================================ Loading results: ligand_i ligand_j DDG(i->j) (kcal/mol) uncertainty (kcal/mol) lig_CHEMBL3402745_200_5 lig_CHEMBL3402744_300_4 1.2 0.1 lig_CHEMBL3402745_200_5 lig_CHEMBL3402749_500_9 3.6 0.2 lig_CHEMBL3402745_200_5 lig_CHEMBL3402754_40_14 -1.2 0.2 lig_CHEMBL3402754_40_14 lig_CHEMBL3402761_1_21 -1.0 0.4 ================================================ FILE: src/openfecli/tests/commands/test_gather/test_cmet_full_results_dg_.tsv ================================================ Loading results: ligand DG(MLE) (kcal/mol) uncertainty (kcal/mol) lig_CHEMBL3402745_200_5 -0.3 0.1 lig_CHEMBL3402744_300_4 0.9 0.2 lig_CHEMBL3402749_500_9 3.4 0.2 lig_CHEMBL3402754_40_14 -1.5 0.2 lig_CHEMBL3402761_1_21 -2.5 0.4 ================================================ FILE: src/openfecli/tests/commands/test_gather/test_cmet_full_results_raw_.tsv ================================================ Loading results: leg ligand_i ligand_j DG(i->j) (kcal/mol) MBAR uncertainty (kcal/mol) complex lig_CHEMBL3402745_200_5 lig_CHEMBL3402744_300_4 -12.54 0.06 complex lig_CHEMBL3402745_200_5 lig_CHEMBL3402744_300_4 -12.31 0.06 complex lig_CHEMBL3402745_200_5 lig_CHEMBL3402744_300_4 -12.19 0.07 solvent lig_CHEMBL3402745_200_5 lig_CHEMBL3402744_300_4 -13.51 0.05 solvent lig_CHEMBL3402745_200_5 lig_CHEMBL3402744_300_4 -13.48 0.06 solvent lig_CHEMBL3402745_200_5 lig_CHEMBL3402744_300_4 -13.50 0.05 complex lig_CHEMBL3402745_200_5 lig_CHEMBL3402749_500_9 -51.37 0.10 complex lig_CHEMBL3402745_200_5 lig_CHEMBL3402749_500_9 -51.5 0.1 complex lig_CHEMBL3402745_200_5 lig_CHEMBL3402749_500_9 -51.6 0.1 solvent lig_CHEMBL3402745_200_5 lig_CHEMBL3402749_500_9 -55.13 0.08 solvent lig_CHEMBL3402745_200_5 lig_CHEMBL3402749_500_9 -54.98 0.09 solvent lig_CHEMBL3402745_200_5 lig_CHEMBL3402749_500_9 -55.30 0.08 complex lig_CHEMBL3402745_200_5 lig_CHEMBL3402754_40_14 -70.55 0.10 complex lig_CHEMBL3402745_200_5 lig_CHEMBL3402754_40_14 -70.9 0.1 complex lig_CHEMBL3402745_200_5 lig_CHEMBL3402754_40_14 -70.3 0.1 solvent lig_CHEMBL3402745_200_5 lig_CHEMBL3402754_40_14 -69.31 0.09 solvent lig_CHEMBL3402745_200_5 lig_CHEMBL3402754_40_14 -69.38 0.09 solvent lig_CHEMBL3402745_200_5 lig_CHEMBL3402754_40_14 -69.45 0.09 complex lig_CHEMBL3402754_40_14 lig_CHEMBL3402761_1_21 35.6 0.2 complex lig_CHEMBL3402754_40_14 lig_CHEMBL3402761_1_21 36.5 0.3 complex lig_CHEMBL3402754_40_14 lig_CHEMBL3402761_1_21 36.4 0.2 solvent lig_CHEMBL3402754_40_14 lig_CHEMBL3402761_1_21 37.2 0.1 solvent lig_CHEMBL3402754_40_14 lig_CHEMBL3402761_1_21 37.3 0.2 solvent lig_CHEMBL3402754_40_14 lig_CHEMBL3402761_1_21 37.0 0.1 ================================================ FILE: src/openfecli/tests/commands/test_gather/test_cmet_missing_all_complex_legs_allow_partial_ddg_.tsv ================================================ Loading results: ligand_i ligand_j DDG(i->j) (kcal/mol) uncertainty (kcal/mol) lig_CHEMBL3402745_200_5 lig_CHEMBL3402744_300_4 Error Error lig_CHEMBL3402745_200_5 lig_CHEMBL3402749_500_9 Error Error lig_CHEMBL3402745_200_5 lig_CHEMBL3402754_40_14 Error Error lig_CHEMBL3402754_40_14 lig_CHEMBL3402761_1_21 Error Error ================================================ FILE: src/openfecli/tests/commands/test_gather/test_cmet_missing_all_complex_legs_fail_ddg_.tsv ================================================ Loading results: ================================================ FILE: src/openfecli/tests/commands/test_gather/test_cmet_missing_all_complex_legs_fail_dg_.tsv ================================================ Loading results: ================================================ FILE: src/openfecli/tests/commands/test_gather/test_cmet_missing_complex_leg_ddg_.tsv ================================================ Loading results: ligand_i ligand_j DDG(i->j) (kcal/mol) uncertainty (kcal/mol) lig_CHEMBL3402745_200_5 lig_CHEMBL3402744_300_4 1.2 0.1 lig_CHEMBL3402745_200_5 lig_CHEMBL3402749_500_9 3.6 0.2 lig_CHEMBL3402745_200_5 lig_CHEMBL3402754_40_14 -1.2 0.2 lig_CHEMBL3402754_40_14 lig_CHEMBL3402761_1_21 -0.7 0.1 ================================================ FILE: src/openfecli/tests/commands/test_gather/test_cmet_missing_complex_leg_dg_.tsv ================================================ Loading results: ligand DG(MLE) (kcal/mol) uncertainty (kcal/mol) lig_CHEMBL3402745_200_5 -0.3 0.1 lig_CHEMBL3402744_300_4 0.8 0.2 lig_CHEMBL3402749_500_9 3.3 0.2 lig_CHEMBL3402754_40_14 -1.5 0.2 lig_CHEMBL3402761_1_21 -2.2 0.2 ================================================ FILE: src/openfecli/tests/commands/test_gather/test_cmet_missing_complex_leg_raw_.tsv ================================================ Loading results: leg ligand_i ligand_j DG(i->j) (kcal/mol) MBAR uncertainty (kcal/mol) complex lig_CHEMBL3402745_200_5 lig_CHEMBL3402744_300_4 -12.54 0.06 complex lig_CHEMBL3402745_200_5 lig_CHEMBL3402744_300_4 -12.31 0.06 complex lig_CHEMBL3402745_200_5 lig_CHEMBL3402744_300_4 -12.19 0.07 solvent lig_CHEMBL3402745_200_5 lig_CHEMBL3402744_300_4 -13.51 0.05 solvent lig_CHEMBL3402745_200_5 lig_CHEMBL3402744_300_4 -13.48 0.06 solvent lig_CHEMBL3402745_200_5 lig_CHEMBL3402744_300_4 -13.50 0.05 complex lig_CHEMBL3402745_200_5 lig_CHEMBL3402749_500_9 -51.37 0.10 complex lig_CHEMBL3402745_200_5 lig_CHEMBL3402749_500_9 -51.5 0.1 complex lig_CHEMBL3402745_200_5 lig_CHEMBL3402749_500_9 -51.6 0.1 solvent lig_CHEMBL3402745_200_5 lig_CHEMBL3402749_500_9 -55.13 0.08 solvent lig_CHEMBL3402745_200_5 lig_CHEMBL3402749_500_9 -54.98 0.09 solvent lig_CHEMBL3402745_200_5 lig_CHEMBL3402749_500_9 -55.30 0.08 complex lig_CHEMBL3402745_200_5 lig_CHEMBL3402754_40_14 -70.55 0.10 complex lig_CHEMBL3402745_200_5 lig_CHEMBL3402754_40_14 -70.9 0.1 complex lig_CHEMBL3402745_200_5 lig_CHEMBL3402754_40_14 -70.3 0.1 solvent lig_CHEMBL3402745_200_5 lig_CHEMBL3402754_40_14 -69.31 0.09 solvent lig_CHEMBL3402745_200_5 lig_CHEMBL3402754_40_14 -69.38 0.09 solvent lig_CHEMBL3402745_200_5 lig_CHEMBL3402754_40_14 -69.45 0.09 complex lig_CHEMBL3402754_40_14 lig_CHEMBL3402761_1_21 36.5 0.3 complex lig_CHEMBL3402754_40_14 lig_CHEMBL3402761_1_21 36.4 0.2 solvent lig_CHEMBL3402754_40_14 lig_CHEMBL3402761_1_21 37.2 0.1 solvent lig_CHEMBL3402754_40_14 lig_CHEMBL3402761_1_21 37.3 0.2 solvent lig_CHEMBL3402754_40_14 lig_CHEMBL3402761_1_21 37.0 0.1 ================================================ FILE: src/openfecli/tests/commands/test_gather/test_cmet_missing_edge_ddg_.tsv ================================================ Loading results: ligand_i ligand_j DDG(i->j) (kcal/mol) uncertainty (kcal/mol) lig_CHEMBL3402745_200_5 lig_CHEMBL3402744_300_4 1.2 0.1 lig_CHEMBL3402745_200_5 lig_CHEMBL3402749_500_9 3.6 0.2 lig_CHEMBL3402745_200_5 lig_CHEMBL3402754_40_14 -1.2 0.2 ================================================ FILE: src/openfecli/tests/commands/test_gather/test_cmet_missing_edge_dg_.tsv ================================================ Loading results: ligand DG(MLE) (kcal/mol) uncertainty (kcal/mol) lig_CHEMBL3402745_200_5 -0.90 0.08 lig_CHEMBL3402744_300_4 0.3 0.1 lig_CHEMBL3402749_500_9 2.8 0.1 lig_CHEMBL3402754_40_14 -2.1 0.2 ================================================ FILE: src/openfecli/tests/commands/test_gather/test_cmet_missing_edge_raw_.tsv ================================================ Loading results: leg ligand_i ligand_j DG(i->j) (kcal/mol) MBAR uncertainty (kcal/mol) complex lig_CHEMBL3402745_200_5 lig_CHEMBL3402744_300_4 -12.54 0.06 complex lig_CHEMBL3402745_200_5 lig_CHEMBL3402744_300_4 -12.31 0.06 complex lig_CHEMBL3402745_200_5 lig_CHEMBL3402744_300_4 -12.19 0.07 solvent lig_CHEMBL3402745_200_5 lig_CHEMBL3402744_300_4 -13.51 0.05 solvent lig_CHEMBL3402745_200_5 lig_CHEMBL3402744_300_4 -13.48 0.06 solvent lig_CHEMBL3402745_200_5 lig_CHEMBL3402744_300_4 -13.50 0.05 complex lig_CHEMBL3402745_200_5 lig_CHEMBL3402749_500_9 -51.37 0.10 complex lig_CHEMBL3402745_200_5 lig_CHEMBL3402749_500_9 -51.5 0.1 complex lig_CHEMBL3402745_200_5 lig_CHEMBL3402749_500_9 -51.6 0.1 solvent lig_CHEMBL3402745_200_5 lig_CHEMBL3402749_500_9 -55.13 0.08 solvent lig_CHEMBL3402745_200_5 lig_CHEMBL3402749_500_9 -54.98 0.09 solvent lig_CHEMBL3402745_200_5 lig_CHEMBL3402749_500_9 -55.30 0.08 complex lig_CHEMBL3402745_200_5 lig_CHEMBL3402754_40_14 -70.55 0.10 complex lig_CHEMBL3402745_200_5 lig_CHEMBL3402754_40_14 -70.9 0.1 complex lig_CHEMBL3402745_200_5 lig_CHEMBL3402754_40_14 -70.3 0.1 solvent lig_CHEMBL3402745_200_5 lig_CHEMBL3402754_40_14 -69.31 0.09 solvent lig_CHEMBL3402745_200_5 lig_CHEMBL3402754_40_14 -69.38 0.09 solvent lig_CHEMBL3402745_200_5 lig_CHEMBL3402754_40_14 -69.45 0.09 ================================================ FILE: src/openfecli/tests/commands/test_gather/test_septop_full_results_ddg_current_.tsv ================================================ ligand_i ligand_j DDG(i->j) (kcal/mol) MBAR uncertainty (kcal/mol) 1 25 0.2 1.4 1 7a 1.3 1.6 1 7b 1.7 1.6 7a 7b 1.8 1.6 ================================================ FILE: src/openfecli/tests/commands/test_gather/test_septop_full_results_ddg_pre_openfe_v1_11_.tsv ================================================ ligand_i ligand_j DDG(i->j) (kcal/mol) MBAR uncertainty (kcal/mol) 1 25 2.0 1.6 1 7a 0.6 1.5 1 7b 0.1 1.5 7a 7b 1.9 1.5 ================================================ FILE: src/openfecli/tests/commands/test_gather/test_septop_full_results_dg_current_.tsv ================================================ ligand DG (kcal/mol) MBAR uncertainty (kcal/mol) 1 -0.78 0.67 25 -0.6 1.2 7a 0.04 0.93 7b 1.34 0.92 ================================================ FILE: src/openfecli/tests/commands/test_gather/test_septop_full_results_dg_pre_openfe_v1_11_.tsv ================================================ ligand DG (kcal/mol) MBAR uncertainty (kcal/mol) 1 -0.72 0.66 25 1.3 1.3 7a -0.89 0.89 7b 0.28 0.90 ================================================ FILE: src/openfecli/tests/commands/test_gather/test_septop_full_results_raw_current_.tsv ================================================ leg ligand_i ligand_j DG(i->j) (kcal/mol) MBAR uncertainty (kcal/mol) complex 1 25 42.66 0.73 solvent 1 25 42.4 1.2 standard_state_correction_A 1 25 -9.2 0.0 standard_state_correction_B 1 25 9.0 0.0 complex 1 7a 0.59 0.69 complex 1 7a 0.32 0.89 complex 1 7a 0.82 0.84 solvent 1 7a -0.8 1.4 solvent 1 7a -0.7 1.4 solvent 1 7a -1.1 1.4 standard_state_correction_A 1 7a -9.1 0.0 standard_state_correction_A 1 7a -9.2 0.0 standard_state_correction_A 1 7a -9.1 0.0 standard_state_correction_B 1 7a 9.0 0.0 standard_state_correction_B 1 7a 9.0 0.0 standard_state_correction_B 1 7a 9.0 0.0 complex 1 7b 0.82 0.78 complex 1 7b 0.39 0.73 solvent 1 7b -0.8 1.4 solvent 1 7b -1.3 1.3 standard_state_correction_A 1 7b -9.3 0.0 standard_state_correction_A 1 7b -9.3 0.0 standard_state_correction_B 1 7b 9.3 0.0 standard_state_correction_B 1 7b 9.4 0.0 complex 7a 7b 3.74 0.63 complex 7a 7b -1.53 0.78 complex 7a 7b -0.64 0.53 solvent 7a 7b -1.2 1.4 solvent 7a 7b -1.3 1.5 solvent 7a 7b -1.0 1.4 standard_state_correction_A 7a 7b -9.2 0.0 standard_state_correction_A 7a 7b -9.1 0.0 standard_state_correction_A 7a 7b -9.0 0.0 standard_state_correction_B 7a 7b 9.2 0.0 standard_state_correction_B 7a 7b 8.9 0.0 standard_state_correction_B 7a 7b 9.4 0.0 ================================================ FILE: src/openfecli/tests/commands/test_gather/test_septop_full_results_raw_pre_openfe_v1_11_.tsv ================================================ leg ligand_i ligand_j DG(i->j) (kcal/mol) MBAR uncertainty (kcal/mol) complex 1 25 39.88 0.61 solvent 1 25 37.9 1.4 standard_state_correction_A 1 25 -9.2 0.0 standard_state_correction_B 1 25 9.3 0.0 complex 1 7a -0.82 0.71 complex 1 7a -0.35 0.69 complex 1 7a -2.10 0.62 solvent 1 7a -1.9 1.2 solvent 1 7a -1.5 1.4 solvent 1 7a -1.6 1.4 standard_state_correction_A 1 7a -8.8 0.0 standard_state_correction_A 1 7a -9.0 0.0 standard_state_correction_A 1 7a -9.1 0.0 standard_state_correction_B 1 7a 9.1 0.0 standard_state_correction_B 1 7a 9.1 0.0 standard_state_correction_B 1 7a 9.0 0.0 complex 1 7b 2.48 0.84 complex 1 7b 3.63 0.74 solvent 1 7b 2.8 1.3 solvent 1 7b 3.1 1.3 standard_state_correction_A 1 7b -9.0 0.0 standard_state_correction_A 1 7b -9.3 0.0 standard_state_correction_B 1 7b 9.1 0.0 standard_state_correction_B 1 7b 9.3 0.0 complex 7a 7b 3.17 0.80 complex 7a 7b 1.65 0.68 complex 7a 7b -2.06 0.58 solvent 7a 7b -1.2 1.3 solvent 7a 7b -0.9 1.3 solvent 7a 7b -1.1 1.2 standard_state_correction_A 7a 7b -9.0 0.0 standard_state_correction_A 7a 7b -9.4 0.0 standard_state_correction_A 7a 7b -9.0 0.0 standard_state_correction_B 7a 7b 8.9 0.0 standard_state_correction_B 7a 7b 9.3 0.0 standard_state_correction_B 7a 7b 9.0 0.0 ================================================ FILE: src/openfecli/tests/commands/test_gather/test_septop_single_repeat_ddg_current_.tsv ================================================ ligand_i ligand_j DDG(i->j) (kcal/mol) MBAR uncertainty (kcal/mol) 1 25 0.2 1.4 1 7a 1.3 1.5 1 7b 1.6 1.6 7a 7b 5.0 1.5 ================================================ FILE: src/openfecli/tests/commands/test_gather/test_septop_single_repeat_ddg_pre_openfe_v1_11_.tsv ================================================ ligand_i ligand_j DDG(i->j) (kcal/mol) MBAR uncertainty (kcal/mol) 1 25 2.0 1.6 1 7a 1.2 1.4 1 7b -0.3 1.5 7a 7b 4.2 1.5 ================================================ FILE: src/openfecli/tests/commands/test_gather/test_septop_single_repeat_dg_current_.tsv ================================================ ligand DG (kcal/mol) MBAR uncertainty (kcal/mol) 1 -0.82 0.66 25 -0.6 1.2 7a -1.02 0.89 7b 2.49 0.92 ================================================ FILE: src/openfecli/tests/commands/test_gather/test_septop_single_repeat_dg_pre_openfe_v1_11_.tsv ================================================ ligand DG (kcal/mol) MBAR uncertainty (kcal/mol) 1 -0.84 0.65 25 1.2 1.3 7a -1.31 0.87 7b 0.95 0.91 ================================================ FILE: src/openfecli/tests/commands/test_gather/test_septop_single_repeat_raw_current_.tsv ================================================ leg ligand_i ligand_j DG(i->j) (kcal/mol) MBAR uncertainty (kcal/mol) complex 1 25 42.66 0.73 solvent 1 25 42.4 1.2 standard_state_correction_A 1 25 -9.2 0.0 standard_state_correction_B 1 25 9.0 0.0 complex 1 7a 0.59 0.69 solvent 1 7a -0.8 1.4 standard_state_correction_A 1 7a -9.1 0.0 standard_state_correction_B 1 7a 9.0 0.0 complex 1 7b 0.82 0.78 solvent 1 7b -0.8 1.4 standard_state_correction_A 1 7b -9.3 0.0 standard_state_correction_B 1 7b 9.3 0.0 complex 7a 7b 3.74 0.63 solvent 7a 7b -1.2 1.4 standard_state_correction_A 7a 7b -9.2 0.0 standard_state_correction_B 7a 7b 9.2 0.0 ================================================ FILE: src/openfecli/tests/commands/test_gather/test_septop_single_repeat_raw_pre_openfe_v1_11_.tsv ================================================ leg ligand_i ligand_j DG(i->j) (kcal/mol) MBAR uncertainty (kcal/mol) complex 1 25 39.88 0.61 solvent 1 25 37.9 1.4 standard_state_correction_A 1 25 -9.2 0.0 standard_state_correction_B 1 25 9.3 0.0 complex 1 7a -0.82 0.71 solvent 1 7a -1.9 1.2 standard_state_correction_A 1 7a -8.8 0.0 standard_state_correction_B 1 7a 9.1 0.0 complex 1 7b 2.48 0.84 solvent 1 7b 2.8 1.3 standard_state_correction_A 1 7b -9.0 0.0 standard_state_correction_B 1 7b 9.1 0.0 complex 7a 7b 3.17 0.80 solvent 7a 7b -1.2 1.3 standard_state_correction_A 7a 7b -9.0 0.0 standard_state_correction_B 7a 7b 8.9 0.0 ================================================ FILE: src/openfecli/tests/commands/test_gather.py ================================================ import glob import os import pathlib from unittest import mock import pandas as pd import pooch import pytest from click.testing import CliRunner from openfecli.commands.gather import ( _get_column, _get_legs_from_result_jsons, _load_valid_result_json, format_estimate_uncertainty, gather, ) from openfecli.commands.gather_abfe import gather_abfe from openfecli.commands.gather_septop import gather_septop from openfecli.data._registry import ( POOCH_CACHE, zenodo_abfe_data, zenodo_cmet_data, zenodo_rbfe_parallel_data, zenodo_rbfe_serial_data, zenodo_septop_data, ) from ..conftest import HAS_INTERNET from ..utils import assert_click_success pooch_rbfe_serial = pooch.create( path=POOCH_CACHE, base_url=zenodo_rbfe_serial_data["base_url"], registry={zenodo_rbfe_serial_data["fname"]: zenodo_rbfe_serial_data["known_hash"]}, ) pooch_rbfe_parallel = pooch.create( path=POOCH_CACHE, base_url=zenodo_rbfe_parallel_data["base_url"], registry={zenodo_rbfe_parallel_data["fname"]: zenodo_rbfe_parallel_data["known_hash"]}, ) pooch_cmet = pooch.create( path=POOCH_CACHE, base_url=zenodo_cmet_data["base_url"], registry={zenodo_cmet_data["fname"]: zenodo_cmet_data["known_hash"]}, ) @pytest.mark.parametrize( "est,unc,unc_prec,est_str,unc_str", [ (12.432, 0.111, 2, "12.43", "0.11"), (0.9999, 0.01, 2, "1.000", "0.010"), (1234, 100, 2, "1230", "100"), ], ) def test_format_estimate_uncertainty(est, unc, unc_prec, est_str, unc_str): assert format_estimate_uncertainty(est, unc, unc_prec) == (est_str, unc_str) @pytest.mark.parametrize( "val, col", [ (1.0, 1), (0.1, -1), (-0.0, 0), (0.0, 0), (0.2, -1), (0.9, -1), (0.011, -2), (9, 1), (10, 2), (15, 2), ], ) def test_get_column(val, col): assert _get_column(val) == col class TestResultLoading: def test_minimal_valid_results(self, capsys, min_result_json): with mock.patch("openfecli.commands.gather.load_json", return_value=min_result_json): result = _load_valid_result_json(fpath="") captured = capsys.readouterr() assert result == ((("lig_ejm_31", "lig_ejm_42"), "solvent"), min_result_json) assert captured.err == "" def test_skip_missing_unit_result(self, capsys, min_result_json): min_result_json["unit_results"] = {} with mock.patch("openfecli.commands.gather.load_json", return_value=min_result_json): result = _load_valid_result_json(fpath="") captured = capsys.readouterr() assert result == ((("lig_ejm_31", "lig_ejm_42"), "solvent"), None) assert "No 'unit_results' found" in captured.err def test_skip_missing_estimate(self, capsys, min_result_json): min_result_json["estimate"] = None with mock.patch("openfecli.commands.gather.load_json", return_value=min_result_json): result = _load_valid_result_json(fpath="") captured = capsys.readouterr() assert result == ((("lig_ejm_31", "lig_ejm_42"), "solvent"), None) assert "No 'estimate' found" in captured.err def test_skip_missing_uncertainty(self, capsys, min_result_json): min_result_json["uncertainty"] = None with mock.patch("openfecli.commands.gather.load_json", return_value=min_result_json): result = _load_valid_result_json(fpath="") captured = capsys.readouterr() assert result == ((("lig_ejm_31", "lig_ejm_42"), "solvent"), None) assert "No 'uncertainty' found" in captured.err def test_skip_all_failed_runs(self, capsys, min_result_json): del min_result_json["unit_results"]["ProtocolUnitResult-e85"] with mock.patch("openfecli.commands.gather.load_json", return_value=min_result_json): result = _load_valid_result_json(fpath="") captured = capsys.readouterr() assert result == ((("lig_ejm_31", "lig_ejm_42"), "solvent"), None) assert "Exception found in all" in captured.err def test_missing_pr_data(self, capsys, min_result_json): min_result_json["protocol_result"]["data"] = {} with mock.patch("openfecli.commands.gather.load_json", return_value=min_result_json): result = _load_valid_result_json(fpath="") captured = capsys.readouterr() assert result == (None, None) assert "Missing ligand names and/or simulation type. Skipping" in captured.err def test_get_legs_from_result_jsons(self, capsys, min_result_json): """Test that exceptions are handled correctly at the _get_legs_from_results_json level.""" min_result_json["protocol_result"]["data"] = {} with mock.patch("openfecli.commands.gather.load_json", return_value=min_result_json): result = _get_legs_from_result_jsons(result_fns=[""], report="dg") captured = capsys.readouterr() assert result == {} assert "Missing ligand names and/or simulation type. Skipping" in captured.err def test_no_results_found(): runner = CliRunner() cli_result = runner.invoke(gather, "not_a_file.txt") assert cli_result.exit_code == 1 assert "No results JSON files found" in str(cli_result.stderr) _RBFE_EXPECTED_DG = b""" Loading results: ligand DG(MLE) (kcal/mol) uncertainty (kcal/mol) lig_ejm_31 -0.09 0.05 lig_ejm_42 0.7 0.1 lig_ejm_46 -0.98 0.05 lig_ejm_47 -0.1 0.1 lig_ejm_48 0.53 0.09 lig_ejm_50 0.91 0.06 lig_ejm_43 2.0 0.2 lig_jmc_23 -0.68 0.09 lig_jmc_27 -1.1 0.1 lig_jmc_28 -1.25 0.08 """ _RBFE_EXPECTED_DDG = b""" Loading results: ligand_i ligand_j DDG(i->j) (kcal/mol) uncertainty (kcal/mol) lig_ejm_31 lig_ejm_42 0.8 0.1 lig_ejm_31 lig_ejm_46 -0.89 0.06 lig_ejm_31 lig_ejm_47 0.0 0.1 lig_ejm_31 lig_ejm_48 0.61 0.09 lig_ejm_31 lig_ejm_50 1.00 0.04 lig_ejm_42 lig_ejm_43 1.4 0.2 lig_ejm_46 lig_jmc_23 0.29 0.09 lig_ejm_46 lig_jmc_27 -0.1 0.1 lig_ejm_46 lig_jmc_28 -0.27 0.06 """ _RBFE_EXPECTED_RAW = b"""\ Loading results: leg ligand_i ligand_j DG(i->j) (kcal/mol) MBAR uncertainty (kcal/mol) complex lig_ejm_31 lig_ejm_42 -14.9 0.8 complex lig_ejm_31 lig_ejm_42 -14.8 0.8 complex lig_ejm_31 lig_ejm_42 -15.1 0.8 solvent lig_ejm_31 lig_ejm_42 -15.7 0.8 solvent lig_ejm_31 lig_ejm_42 -15.7 0.8 solvent lig_ejm_31 lig_ejm_42 -15.7 0.8 complex lig_ejm_31 lig_ejm_46 -40.7 0.8 complex lig_ejm_31 lig_ejm_46 -40.7 0.8 complex lig_ejm_31 lig_ejm_46 -40.8 0.8 solvent lig_ejm_31 lig_ejm_46 -39.8 0.8 solvent lig_ejm_31 lig_ejm_46 -39.9 0.8 solvent lig_ejm_31 lig_ejm_46 -39.8 0.8 complex lig_ejm_31 lig_ejm_47 -27.8 0.8 complex lig_ejm_31 lig_ejm_47 -28.0 0.8 complex lig_ejm_31 lig_ejm_47 -27.7 0.8 solvent lig_ejm_31 lig_ejm_47 -27.8 0.8 solvent lig_ejm_31 lig_ejm_47 -27.8 0.8 solvent lig_ejm_31 lig_ejm_47 -27.9 0.8 complex lig_ejm_31 lig_ejm_48 -16.2 0.8 complex lig_ejm_31 lig_ejm_48 -16.2 0.8 complex lig_ejm_31 lig_ejm_48 -16.0 0.8 solvent lig_ejm_31 lig_ejm_48 -16.8 0.8 solvent lig_ejm_31 lig_ejm_48 -16.7 0.8 solvent lig_ejm_31 lig_ejm_48 -16.8 0.8 complex lig_ejm_31 lig_ejm_50 -57.3 0.8 complex lig_ejm_31 lig_ejm_50 -57.3 0.8 complex lig_ejm_31 lig_ejm_50 -57.4 0.8 solvent lig_ejm_31 lig_ejm_50 -58.3 0.8 solvent lig_ejm_31 lig_ejm_50 -58.4 0.8 solvent lig_ejm_31 lig_ejm_50 -58.3 0.8 complex lig_ejm_42 lig_ejm_43 -19.0 0.8 complex lig_ejm_42 lig_ejm_43 -18.7 0.8 complex lig_ejm_42 lig_ejm_43 -19.0 0.8 solvent lig_ejm_42 lig_ejm_43 -20.3 0.8 solvent lig_ejm_42 lig_ejm_43 -20.3 0.8 solvent lig_ejm_42 lig_ejm_43 -20.3 0.8 complex lig_ejm_46 lig_jmc_23 17.3 0.8 complex lig_ejm_46 lig_jmc_23 17.4 0.8 complex lig_ejm_46 lig_jmc_23 17.5 0.8 solvent lig_ejm_46 lig_jmc_23 17.2 0.8 solvent lig_ejm_46 lig_jmc_23 17.1 0.8 solvent lig_ejm_46 lig_jmc_23 17.1 0.8 complex lig_ejm_46 lig_jmc_27 15.9 0.8 complex lig_ejm_46 lig_jmc_27 15.8 0.8 complex lig_ejm_46 lig_jmc_27 15.7 0.8 solvent lig_ejm_46 lig_jmc_27 16.0 0.8 solvent lig_ejm_46 lig_jmc_27 15.9 0.8 solvent lig_ejm_46 lig_jmc_27 15.9 0.8 complex lig_ejm_46 lig_jmc_28 23.1 0.8 complex lig_ejm_46 lig_jmc_28 23.2 0.8 complex lig_ejm_46 lig_jmc_28 23.1 0.8 solvent lig_ejm_46 lig_jmc_28 23.5 0.8 solvent lig_ejm_46 lig_jmc_28 23.3 0.8 solvent lig_ejm_46 lig_jmc_28 23.4 0.8 """ @pytest.fixture def cmet_result_dir() -> pathlib.Path: pooch_cmet.fetch("cmet_results.tar.gz", processor=pooch.Untar()) result_dir = pathlib.Path(POOCH_CACHE) / "cmet_results.tar.gz.untar/cmet_results/" return result_dir class TestGatherCMET: @pytest.mark.parametrize("report", ["dg", "ddg", "raw"]) def test_cmet_full_results(self, cmet_result_dir, report, file_regression): results = [str(cmet_result_dir / f"results_{i}") for i in range(3)] args = ["--report", report] runner = CliRunner() cli_result = runner.invoke(gather, results + args + ["--tsv"]) assert_click_success(cli_result) file_regression.check(cli_result.stdout, extension=".tsv") # TODO: add --allow-partial behavior checks @pytest.mark.parametrize("report", ["dg", "ddg", "raw"]) def test_cmet_missing_complex_leg(self, cmet_result_dir, report, file_regression): """Missing one complex replicate from one leg.""" results = [ str(cmet_result_dir / d) for d in ["results_0_partial", "results_1", "results_2"] ] args = ["--report", report] runner = CliRunner() cli_result = runner.invoke(gather, results + args + ["--tsv"]) assert_click_success(cli_result) file_regression.check(cli_result.stdout, extension=".tsv") @pytest.mark.parametrize("report", ["dg", "ddg", "raw"]) def test_cmet_missing_edge(self, cmet_result_dir, report, file_regression): results = [str(cmet_result_dir / f"results_{i}_remove_edge") for i in range(3)] args = ["--report", report] runner = CliRunner() cli_result = runner.invoke(gather, results + args + ["--tsv"]) file_regression.check(cli_result.stdout, extension=".tsv") assert_click_success(cli_result) file_regression.check(cli_result.stdout, extension=".tsv") @pytest.mark.parametrize("report", ["ddg", "raw"]) def test_cmet_failed_edge(self, cmet_result_dir, report, file_regression): results = [str(cmet_result_dir / f"results_{i}_failed_edge") for i in range(3)] args = ["--report", report] runner = CliRunner() cli_result = runner.invoke(gather, results + args + ["--tsv"]) assert_click_success(cli_result) file_regression.check(cli_result.stdout, extension=".tsv") @pytest.mark.parametrize("allow_partial", [True, False]) def test_cmet_too_few_edges_error(self, cmet_result_dir, allow_partial): results = [str(cmet_result_dir / f"results_{i}_failed_edge") for i in range(3)] args = ["--report", "dg"] runner = CliRunner() if allow_partial: args += ["--allow-partial"] cli_result = runner.invoke(gather, results + args + ["--tsv"]) assert cli_result.exit_code == 1 assert "The results network has 1 edge(s), but 3 or more edges are required" in str( cli_result.stderr ) @pytest.mark.parametrize("report", ["dg", "ddg"]) def test_cmet_missing_all_complex_legs_fail(self, cmet_result_dir, report, file_regression): """Missing one complex replicate from one leg.""" results = glob.glob(f"{cmet_result_dir}/results_*/*solvent*", recursive=True) args = ["--report", report] runner = CliRunner() cli_result = runner.invoke(gather, results + args + ["-o", "-"]) cli_result.exit_code == 1 file_regression.check(cli_result.stdout, extension=".tsv") @pytest.mark.parametrize("report", ["ddg"]) def test_cmet_missing_all_complex_legs_allow_partial(self, cmet_result_dir, report, file_regression): # fmt: skip """Missing one complex replicate from one leg.""" results = glob.glob(f"{cmet_result_dir}/results_*/*solvent*", recursive=True) args = ["--report", report, "--allow-partial"] runner = CliRunner() cli_result = runner.invoke(gather, results + args + ["--tsv"]) assert_click_success(cli_result) file_regression.check(cli_result.stdout, extension=".tsv") @pytest.mark.parametrize("report", ["dg", "ddg", "raw"]) def test_pretty_print(self, cmet_result_dir, report, file_regression): results = [str(cmet_result_dir / f"results_{i}") for i in range(3)] args = ["--report", report] runner = CliRunner() cli_result = runner.invoke(gather, results + args) assert_click_success(cli_result) # TODO: figure out how to mock terminal size, since it affects the table wrapping # file_regression.check(cli_result.stdout, extension='.txt') def test_write_to_file(self, cmet_result_dir): runner = CliRunner() with runner.isolated_filesystem(): results = [str(cmet_result_dir / f"results_{i}") for i in range(3)] fname = "output.tsv" args = ["--report", "raw", "-o", fname] cli_result = runner.invoke(gather, results + args) assert "writing raw output to 'output.tsv'" in cli_result.stdout assert pathlib.Path(fname).is_file() @pytest.fixture def rbfe_results_serial_dir() -> pathlib.Path: pooch_rbfe_serial.fetch("rbfe_results_serial_repeats.tar.gz", processor=pooch.Untar()) result_dir = ( pathlib.Path(POOCH_CACHE) / "rbfe_results_serial_repeats.tar.gz.untar/rbfe_results_serial_repeats/" ) return result_dir @pytest.fixture def rbfe_results_parallel_dir() -> pathlib.Path: pooch_rbfe_parallel.fetch("rbfe_results_parallel_repeats.tar.gz", processor=pooch.Untar()) result_dir = ( pathlib.Path(POOCH_CACHE) / "rbfe_results_parallel_repeats.tar.gz.untar/rbfe_results_parallel_repeats/" ) return result_dir @pytest.mark.skipif( not os.path.exists(POOCH_CACHE) and not HAS_INTERNET, reason="Internet seems to be unavailable and test data is not cached locally.", ) @pytest.mark.parametrize("dataset", ["rbfe_results_serial_dir", "rbfe_results_parallel_dir"]) # fmt: skip @pytest.mark.parametrize("report", ["", "dg", "ddg", "raw"]) @pytest.mark.parametrize("input_mode", ["directory", "filepaths"]) def test_rbfe_gather(request, dataset, report, input_mode): expected = { "": _RBFE_EXPECTED_DG, "dg": _RBFE_EXPECTED_DG, "ddg": _RBFE_EXPECTED_DDG, "raw": _RBFE_EXPECTED_RAW, }[report] runner = CliRunner() if report: args = ["--report", report] else: args = [] results = request.getfixturevalue(dataset) if input_mode == "directory": results = [str(results)] elif input_mode == "filepaths": results = glob.glob(f"{results}/*", recursive=True) assert len(results) > 1 # sanity check to make sure we're passing in multiple paths cli_result = runner.invoke(gather, results + args + ["--tsv"]) assert_click_success(cli_result) actual_lines = set(cli_result.stdout_bytes.split(b"\n")) assert set(expected.split(b"\n")) == actual_lines def test_rbfe_gather_single_repeats_dg_error(rbfe_results_parallel_dir): """A single repeat is insufficient for a dg calculation - should fail cleanly.""" runner = CliRunner() results = rbfe_results_parallel_dir args = ["report", "dg"] cli_result = runner.invoke(gather, [f"{results}/replicate_0"] + args + ["--tsv"]) assert cli_result.exit_code == 1 @pytest.mark.skipif( not os.path.exists(POOCH_CACHE) and not HAS_INTERNET, reason="Internet seems to be unavailable and test data is not cached locally.", ) class TestRBFEGatherFailedEdges: @pytest.fixture() def results_paths_serial_missing_legs(self, rbfe_results_serial_dir) -> str: """Example output data, with replicates run in serial and two missing results JSONs.""" result_dir = rbfe_results_serial_dir results = glob.glob(f"{result_dir}/*", recursive=True) files_to_skip = [ "rbfe_lig_ejm_31_complex_lig_ejm_42_complex.json", "rbfe_lig_ejm_46_solvent_lig_jmc_28_solvent.json", ] results_filtered = [f for f in results if os.path.basename(f) not in files_to_skip] return results_filtered def test_missing_leg_error(self, results_paths_serial_missing_legs: str): runner = CliRunner() result = runner.invoke(gather, results_paths_serial_missing_legs + ["--report", "dg"]) assert result.exit_code == 1 assert "Some edge(s) are missing runs" in str(result.stderr) assert "lig_ejm_31\tlig_ejm_42\tsolvent" in str(result.stderr) assert "lig_ejm_46\tlig_jmc_28\tcomplex" in str(result.stderr) assert "using the --allow-partial flag" in str(result.stderr) def test_missing_leg_allow_partial_disconnected(self, results_paths_serial_missing_legs: str): runner = CliRunner() with pytest.warns(): args = ["--report", "dg", "--allow-partial"] result = runner.invoke(gather, results_paths_serial_missing_legs + args + ["--tsv"]) assert result.exit_code == 1 assert "The results network is disconnected" in str(result.stderr) def test_allow_partial_msg_not_printed(self, results_paths_serial_missing_legs: str): # we *dont* want the suggestion to use --allow-partial if the user already used it! runner = CliRunner() args = ["--report", "ddg", "--allow-partial"] result = runner.invoke(gather, results_paths_serial_missing_legs + args + ["--tsv"]) assert_click_success(result) assert "--allow-partial" not in result.output ZENODO_ABFE_DATA = pooch.create( path=POOCH_CACHE, base_url=zenodo_abfe_data["base_url"], registry={zenodo_abfe_data["fname"]: zenodo_abfe_data["known_hash"]}, ) ZENODO_SEPTOP_DATA = pooch.create( path=POOCH_CACHE, base_url=zenodo_septop_data["base_url"], registry={zenodo_septop_data["fname"]: zenodo_septop_data["known_hash"]}, ) @pytest.fixture def abfe_result_dir() -> pathlib.Path: """for pre-PR #1776 backwards compatability""" ZENODO_ABFE_DATA.fetch("abfe_results.zip", processor=pooch.Unzip()) result_dir = pathlib.Path(POOCH_CACHE) / "abfe_results.zip.unzip/abfe_results/" return result_dir class TestGatherABFE: @pytest.mark.parametrize("report", ["raw", "dg"]) @pytest.mark.parametrize("protocol_type", ["single_unit", "multiple_units"]) def test_abfe_full_results(self, abfe_result_dir, report, protocol_type, file_regression): results_dir = abfe_result_dir / f"abfe_results_{protocol_type}" results = [str(results_dir / f"results_{i}") for i in range(3)] args = ["--report", report] runner = CliRunner() cli_result = runner.invoke(gather_abfe, results + args + ["--tsv"]) assert_click_success(cli_result) assert "WARNING! Gathering of ABFE results" in cli_result.stderr file_regression.check(cli_result.stdout, extension=".tsv") @pytest.mark.parametrize("report", ["raw", "dg"]) @pytest.mark.parametrize("protocol_type", ["single_unit", "multiple_units"]) def test_abfe_single_repeat(self, abfe_result_dir, report, protocol_type, file_regression): results_dir = str(abfe_result_dir / f"abfe_results_{protocol_type}" / "results_0") args = ["--report", report] runner = CliRunner() cli_result = runner.invoke(gather_abfe, [results_dir] + args + ["--tsv"]) assert_click_success(cli_result) assert "WARNING! Gathering of ABFE results" in cli_result.stderr file_regression.check(cli_result.stdout, extension=".tsv") @pytest.fixture def septop_result_dir() -> pathlib.Path: ZENODO_SEPTOP_DATA.fetch("septop_results.zip", processor=pooch.Unzip()) result_dir = pathlib.Path(POOCH_CACHE) / "septop_results.zip.unzip/septop_results/" return result_dir class TestGatherSepTop: """ Test SepTop gathering. Notes ----- * Version parameterize option allows for testing of backwards reproducible gathering behaviour as the ProtocolUnit behaviour was changed in openfe v1.11 """ @pytest.mark.parametrize("version", ["current", "pre_openfe_v1.11"]) @pytest.mark.parametrize("report", ["raw", "ddg", "dg"]) def test_septop_full_results(self, version, septop_result_dir, report, file_regression): results = [str(septop_result_dir / version / f"results_{i}") for i in range(3)] args = ["--report", report] runner = CliRunner() cli_result = runner.invoke(gather_septop, results + args + ["--tsv"]) assert_click_success(cli_result) assert "WARNING! Gathering of SepTop results" in cli_result.stderr file_regression.check(cli_result.stdout, extension=".tsv") @pytest.mark.parametrize("version", ["current", "pre_openfe_v1.11"]) @pytest.mark.parametrize("report", ["raw", "ddg", "dg"]) def test_septop_single_repeat(self, version, septop_result_dir, report, file_regression): results = [str(septop_result_dir / version / "results_0")] args = ["--report", report] runner = CliRunner() cli_result = runner.invoke(gather_septop, results + args + ["--tsv"]) assert_click_success(cli_result) assert "WARNING! Gathering of SepTop results" in cli_result.stderr file_regression.check(cli_result.stdout, extension=".tsv") ================================================ FILE: src/openfecli/tests/commands/test_ligand_network_viewer.py ================================================ import importlib.resources from unittest import mock import matplotlib import pytest from click.testing import CliRunner from openfecli.commands.view_ligand_network import view_ligand_network @pytest.mark.filterwarnings("ignore:.*non-GUI backend") def test_view_ligand_network(): # smoke test resource = importlib.resources.files("openfe.tests.data.serialization") ref = resource / "network_template.graphml" runner = CliRunner() backend = matplotlib.get_backend() matplotlib.use("ps") loc = "openfe.utils.atommapping_network_plotting.matplotlib.use" with runner.isolated_filesystem(): with mock.patch(loc, mock.Mock()): result = runner.invoke(view_ligand_network, [str(ref)]) assert result.exit_code == 0 matplotlib.use(backend) ================================================ FILE: src/openfecli/tests/commands/test_plan_rbfe_network.py ================================================ import shutil from importlib import resources from unittest import mock import gufe import numpy as np import pytest from click.testing import CliRunner from openff.units import unit from openfe import ( AlchemicalNetwork, ProteinMembraneComponent, SmallMoleculeComponent, SolventComponent, ) from openfe.protocols.openmm_utils.charge_generation import HAS_NAGL, HAS_OPENEYE from openfe.protocols.openmm_utils.omm_settings import OpenFFPartialChargeSettings from openfe.setup import ( LomapAtomMapper, ligand_network_planning, lomap_scorers, ) from openfe.tests.conftest import ( T4_protein_component, T4_protein_component_pdb, a2a_protein_membrane_component, a2a_protein_membrane_pdb, ) from openfecli.commands.plan_rbfe_network import plan_rbfe_network, plan_rbfe_network_main from ..utils import assert_click_success @pytest.fixture(scope="session") def mol_dir_args(tmp_path_factory): ofe_dir_path = tmp_path_factory.mktemp("moldir") with resources.as_file(resources.files("openfe.tests.data.openmm_rfe")) as d: for f in ["ligand_23.sdf", "ligand_55.sdf"]: shutil.copyfile(d / f, ofe_dir_path / f) return ["--molecules", ofe_dir_path] @pytest.fixture(scope="session") def dummy_charge_dir_args(tmp_path_factory): ofe_dir_path = tmp_path_factory.mktemp("charge_moldir") with resources.as_file(resources.files("openfe.tests.data.openmm_rfe")) as d: for f in ["dummy_charge_ligand_23.sdf", "dummy_charge_ligand_55.sdf"]: shutil.copyfile(d / f, ofe_dir_path / f) return ["--molecules", ofe_dir_path] @pytest.fixture def protein_args(T4_protein_component_pdb): with resources.as_file(resources.files("openfe.tests.data")) as d: return ["--protein", T4_protein_component_pdb] @pytest.fixture def protein_membrane_args(a2a_protein_membrane_pdb): return ["--protein-membrane", a2a_protein_membrane_pdb] def print_test_with_file( mapping_scorer, ligand_network_planner, small_molecules, solvent, protein, ): print(mapping_scorer) print(ligand_network_planner) print(small_molecules) print(solvent) print(protein) def validate_charges(smc): """ Validate that the SmallMoleculeComponent has partial charges assigned. """ off_mol = smc.to_openff() assert off_mol.partial_charges is not None assert len(off_mol.partial_charges) == off_mol.n_atoms @pytest.fixture def ligs_23_55() -> list[SmallMoleculeComponent]: with resources.as_file(resources.files("openfe.tests.data.openmm_rfe")) as d: return [ SmallMoleculeComponent.from_sdf_file(d / f) for f in ["ligand_23.sdf", "ligand_55.sdf"] ] @pytest.mark.skipif(not HAS_NAGL, reason="needs NAGL") @pytest.mark.skipif( HAS_OPENEYE, reason="cannot use NAGL with rdkit backend when OpenEye is installed" ) @pytest.mark.parametrize( "protein_fixture", ["T4_protein_component", "a2a_protein_membrane_component"] ) def test_plan_rbfe_network_main(request, protein_fixture, ligs_23_55): smallM_components = ligs_23_55 protein_component = request.getfixturevalue(protein_fixture) solvent_component = SolventComponent() alchemical_network, _ = plan_rbfe_network_main( mapper=[LomapAtomMapper()], mapping_scorer=lomap_scorers.default_lomap_score, ligand_network_planner=ligand_network_planning.generate_minimal_spanning_network, small_molecules=smallM_components, solvent=solvent_component, protein=protein_component, cofactors=[], n_protocol_repeats=3, # use nagl to keep testing fast partial_charge_settings=OpenFFPartialChargeSettings( partial_charge_method="nagl", nagl_model="openff-gnn-am1bcc-0.1.0-rc.3.pt" ), processors=1, overwrite_charges=False, ) # check the ligands have charges assigned for node in alchemical_network.nodes: validate_charges(node.components["ligand"]) for edge in alchemical_network.edges: settings = edge.protocol.settings expected_barostat = "MonteCarloBarostat" if "complex" in edge.name: padding = 1.0 # nm if isinstance(protein_component, ProteinMembraneComponent): expected_barostat = "MonteCarloMembraneBarostat" else: padding = 1.5 # nm assert settings.solvation_settings.solvent_padding == padding * unit.nanometer assert settings.forcefield_settings.nonbonded_cutoff == 0.9 * unit.nanometer assert settings.solvation_settings.box_shape == "dodecahedron" assert settings.simulation_settings.time_per_iteration == 2.5 * unit.picosecond assert settings.integrator_settings.barostat == expected_barostat @pytest.fixture def yaml_nagl_settings(): return """\ partial_charge: method: nagl settings: nagl_model: openff-gnn-am1bcc-0.1.0-rc.3.pt """ @pytest.mark.skipif(not HAS_NAGL, reason="needs NAGL") @pytest.mark.skipif( HAS_OPENEYE, reason="cannot use NAGL with rdkit backend when OpenEye is installed" ) @pytest.mark.parametrize("protein_fixture", ["protein_args", "protein_membrane_args"]) def test_plan_rbfe_network(mol_dir_args, request, protein_fixture, tmp_path, yaml_nagl_settings): """ smoke test """ # use nagl charges for CI speed! settings_path = tmp_path / "settings.yaml" with open(settings_path, "w") as f: f.write(yaml_nagl_settings) args = mol_dir_args + request.getfixturevalue(protein_fixture) # TODO: this depends on the fixture name, which I do not like expected_protein_type = ( "ProteinMembraneComponent" if "membrane" in protein_fixture else "ProteinComponent" ) expected_output_always = [ "RBFE-NETWORK PLANNER", f"{expected_protein_type}: {expected_protein_type}(name=)", "Solvent: SolventComponent(name=O, Na+, Cl-)", "- tmp_network.json", # make sure the partial charge settings are picked up "Partial Charge Generation: nagl", "assigning ligand partial charges -- this may be slow", ] # we can get these in either order: 22 first or 55 first expected_output_1 = [ "Small Molecules: SmallMoleculeComponent(name=ligand_23) SmallMoleculeComponent(name=ligand_55)", "- rbfe_ligand_23_complex_ligand_55_complex.json", "- rbfe_ligand_23_solvent_ligand_55_solvent.json", ] expected_output_2 = [ "Small Molecules: SmallMoleculeComponent(name=ligand_55) SmallMoleculeComponent(name=ligand_23)", "- rbfe_ligand_55_complex_ligand_23_complex.json", "- rbfe_ligand_55_solvent_ligand_23_solvent.json", ] patch_base = "openfecli.commands.plan_rbfe_network." args += ["-o", "tmp_network"] args += ["-s", settings_path] patch_loc = patch_base + "plan_rbfe_network" patch_func = print_test_with_file runner = CliRunner() with mock.patch(patch_loc, patch_func): with runner.isolated_filesystem(): result = runner.invoke(plan_rbfe_network, args) assert result.exit_code == 0 for line in expected_output_always: assert line in result.output for l1, l2 in zip(expected_output_1, expected_output_2): assert l1 in result.output or l2 in result.output @pytest.mark.parametrize( ["input_n_repeat", "expected_n_repeat"], [ ([], 3), (["--n-protocol-repeats", "1"], 1), ], ) def test_plan_rbfe_network_n_repeats(mol_dir_args, protein_args, input_n_repeat, expected_n_repeat): runner = CliRunner() args = mol_dir_args + protein_args + input_n_repeat with runner.isolated_filesystem(): result = runner.invoke(plan_rbfe_network, args) assert_click_success(result) # make sure the number of repeats is correct network = AlchemicalNetwork.from_json("alchemicalNetwork/alchemicalNetwork.json") for edge in network.edges: assert edge.protocol.settings.protocol_repeats == expected_n_repeat @pytest.mark.parametrize( "overwrite", [ pytest.param(True, id="Overwrite"), pytest.param(False, id="No overwrite"), ], ) @pytest.mark.skipif(not HAS_NAGL, reason="needs NAGL") @pytest.mark.skipif( HAS_OPENEYE, reason="cannot use NAGL with rdkit backend when OpenEye is installed" ) def test_plan_rbfe_network_charge_overwrite(dummy_charge_dir_args, protein_args, tmp_path, yaml_nagl_settings, overwrite): # fmt: skip # make sure the dummy charges are overwritten when requested # use nagl charges for CI speed! settings_path = tmp_path / "settings.yaml" with open(settings_path, "w") as f: f.write(yaml_nagl_settings) args = dummy_charge_dir_args + protein_args + ["-s", settings_path] # get the input charges for the molecules to check they have been overwritten charges_by_name = {} for f in ["dummy_charge_ligand_23.sdf", "dummy_charge_ligand_55.sdf"]: smc = SmallMoleculeComponent.from_sdf_file(dummy_charge_dir_args[1] / f) charges_by_name[smc.name] = smc.to_openff().partial_charges.m if overwrite: args.append("--overwrite-charges") runner = CliRunner() with runner.isolated_filesystem(): result = runner.invoke(plan_rbfe_network, args) assert result.exit_code == 0 if overwrite: assert "Overwriting partial charges" in result.output network = AlchemicalNetwork.from_json("alchemicalNetwork/alchemicalNetwork.json") # make sure the ligands don't have dummy charges for node in network.nodes: off_mol = node.components["ligand"].to_openff() if overwrite: assert not np.allclose(off_mol.partial_charges.m, charges_by_name[off_mol.name]) else: assert np.allclose(off_mol.partial_charges.m, charges_by_name[off_mol.name]) @pytest.fixture def eg5_files(): with resources.as_file(resources.files("openfe.tests.data.eg5")) as p: pdb_path = str(p.joinpath("eg5_protein.pdb")) lig_path = str(p.joinpath("eg5_ligands.sdf")) cof_path = str(p.joinpath("eg5_cofactor.sdf")) yield pdb_path, lig_path, cof_path @pytest.mark.skipif(not HAS_NAGL, reason="needs NAGL") @pytest.mark.skipif( HAS_OPENEYE, reason="cannot use NAGL with rdkit backend when OpenEye is installed" ) def test_plan_rbfe_network_cofactors(eg5_files, tmp_path, yaml_nagl_settings): # use nagl charges for CI speed! settings_path = tmp_path / "settings.yaml" with open(settings_path, "w") as f: f.write(yaml_nagl_settings) runner = CliRunner() args = ["-p", eg5_files[0], "-M", eg5_files[1], "-C", eg5_files[2], "-s", settings_path] with runner.isolated_filesystem(): result = runner.invoke(plan_rbfe_network, args) assert result.exit_code == 0 # check charges are assigned assert "Partial Charge Generation: nagl" in result.output assert "assigning ligand partial charges -- this may be slow" in result.output assert "assigning cofactor partial charges -- this may be slow" # make sure the cofactor is in the transformations network = AlchemicalNetwork.from_json("alchemicalNetwork/alchemicalNetwork.json") for edge in network.edges: if "protein" in edge.stateA.components: assert "cofactor1" in edge.stateA.components assert "cofactor1" in edge.stateB.components else: assert "cofactor1" not in edge.stateA.components assert "cofactor1" not in edge.stateB.components # make sure the ligands and cofactors have charges for node in network.nodes: validate_charges(node.components["ligand"]) if "cofactor1" in node.components: validate_charges(node.components["cofactor1"]) @pytest.fixture def cdk8_files(): with resources.as_file(resources.files("openfe.tests.data.cdk8")) as p: pdb_path = str(p.joinpath("cdk8_protein.pdb")) lig_path = str(p.joinpath("cdk8_ligands.sdf")) yield pdb_path, lig_path def test_plan_rbfe_network_charge_changes(cdk8_files, caplog): """ Make sure the protocol settings are changed and a warning is printed when we plan a network with a net charge change. """ runner = CliRunner() args = ["-p", cdk8_files[0], "-M", cdk8_files[1]] with runner.isolated_filesystem(): result = runner.invoke(plan_rbfe_network, args) assert result.exit_code == 0 # load the transformations and check the settings network = AlchemicalNetwork.from_json("alchemicalNetwork/alchemicalNetwork.json") for edge in network.edges: settings = edge.protocol.settings # check the charged transform if ( edge.stateA.components["ligand"].name == "lig_40" and edge.stateB.components["ligand"].name == "lig_41" ): assert settings.alchemical_settings.explicit_charge_correction is True assert settings.simulation_settings.production_length.m == 20.0 assert settings.simulation_settings.n_replicas == 22 assert settings.lambda_settings.lambda_windows == 22 else: assert settings.alchemical_settings.explicit_charge_correction is False assert settings.simulation_settings.production_length.m == 5.0 assert settings.simulation_settings.n_replicas == 11 assert settings.lambda_settings.lambda_windows == 11 assert "Charge changing transformation between ligands lig_40 and lig_41" in caplog.text @pytest.fixture def lomap_yaml_settings(): return """\ network: method: generate_lomap_network settings: max_path_length: 6 mapper: method: LomapAtomMapper settings: time: 45 element_change: True partial_charge: method: nagl settings: nagl_model: openff-gnn-am1bcc-0.1.0-rc.3.pt """ @pytest.mark.skipif(not HAS_NAGL, reason="needs NAGL") @pytest.mark.skipif( HAS_OPENEYE, reason="cannot use NAGL with rdkit backend when OpenEye is installed" ) def test_lomap_yaml_plan_rbfe_smoke_test(lomap_yaml_settings, cdk8_files, tmp_path): protein, ligand = cdk8_files settings_path = tmp_path / "settings.yaml" with open(settings_path, "w") as f: f.write(lomap_yaml_settings) assert settings_path.exists() args = ["-p", protein, "-M", ligand, "-s", settings_path] runner = CliRunner() with runner.isolated_filesystem(): result = runner.invoke(plan_rbfe_network, args) assert result.exit_code == 0 @pytest.fixture def custom_yaml_radial(): return """\ network: method: generate_radial_network settings: central_ligand: lig_CHEMBL1078774 mapper: method: LomapAtomMapper settings: time: 45 element_change: True partial_charge: method: nagl settings: nagl_model: openff-gnn-am1bcc-0.1.0-rc.3.pt """ @pytest.mark.skipif(not HAS_NAGL, reason="needs NAGL") @pytest.mark.skipif( HAS_OPENEYE, reason="cannot use NAGL with rdkit backend when OpenEye is installed" ) def test_custom_yaml_plan_radial_smoke_test(custom_yaml_radial, eg5_files, tmp_path): protein, ligand, cofactor = eg5_files settings_path = tmp_path / "settings.yaml" with open(settings_path, "w") as f: f.write(custom_yaml_radial) assert settings_path.exists() args = ["-p", protein, "-M", ligand, "-C", cofactor, "-s", settings_path] runner = CliRunner() with runner.isolated_filesystem(): result = runner.invoke(plan_rbfe_network, args) assert result.exit_code == 0 def test_plan_rbfe_invalid_membrane(eg5_files): """eg5_protein has box vectors but no membrane. ProteinMembraneComponent validation should catch this.""" args = ["--protein-membrane", eg5_files[0], "-M", eg5_files[1]] runner = CliRunner() with pytest.raises( gufe.components.errors.ComponentValidationError, match="This usually indicates missing solvent or incorrect box vectors", ): _ = runner.invoke(plan_rbfe_network, args, catch_exceptions=False) def test_plan_rbfe_missing_protein_args(eg5_files): args = ["-M", eg5_files[1]] runner = CliRunner(catch_exceptions=False) result = runner.invoke(plan_rbfe_network, args) assert result.exit_code == 2 assert "Either --protein or --protein-membrane must be provided." in result.stderr def test_plan_rbfe_too_many_protein_error(eg5_files): args = ["-M", eg5_files[1], "--protein-membrane", eg5_files[0], "-p", eg5_files[0]] runner = CliRunner(catch_exceptions=False) result = runner.invoke(plan_rbfe_network, args) assert "Only --protein (-p) or --protein-membrane may be provided, not both." in result.stderr ================================================ FILE: src/openfecli/tests/commands/test_plan_rhfe_network.py ================================================ import json import shutil from importlib import resources from unittest import mock import numpy as np import pytest from click.testing import CliRunner from gufe import AlchemicalNetwork, SmallMoleculeComponent, SolventComponent from gufe.tokenization import JSON_HANDLER from openff.utilities.testing import skip_if_missing from openfe.protocols.openmm_utils.charge_generation import ( HAS_NAGL, HAS_OPENEYE, ) from openfecli.commands.plan_rhfe_network import ( plan_rhfe_network, plan_rhfe_network_main, ) @pytest.fixture(scope="session") def mol_dir_args(tmp_path_factory): ofe_dir_path = tmp_path_factory.mktemp("moldir") with resources.as_file(resources.files("openfe.tests.data.openmm_rfe")) as d: for f in ["ligand_23.sdf", "ligand_55.sdf"]: shutil.copyfile(d / f, ofe_dir_path / f) return ["--molecules", ofe_dir_path] @pytest.fixture(scope="session") def dummy_charge_dir_args(tmp_path_factory): ofe_dir_path = tmp_path_factory.mktemp("charge_moldir") with resources.as_file(resources.files("openfe.tests.data.openmm_rfe")) as d: for f in ["dummy_charge_ligand_23.sdf", "dummy_charge_ligand_55.sdf"]: shutil.copyfile(d / f, ofe_dir_path / f) return ["--molecules", ofe_dir_path] def print_test_with_file(mapping_scorer, ligand_network_planner, small_molecules, solvent): print(mapping_scorer) print(ligand_network_planner) print(small_molecules) print(solvent) def validate_charges(smc): """ Validate that the SmallMoleculeComponent has partial charges assigned. """ off_mol = smc.to_openff() assert off_mol.partial_charges is not None assert len(off_mol.partial_charges) == off_mol.n_atoms @pytest.mark.skipif( not HAS_NAGL, reason="needs NAGL", ) @pytest.mark.skipif( HAS_OPENEYE, reason="cannot use NAGL with rdkit backend when OpenEye is installed" ) def test_plan_rhfe_network_main(): from openfe.protocols.openmm_utils.omm_settings import OpenFFPartialChargeSettings from openfe.setup import ( LomapAtomMapper, ligand_network_planning, lomap_scorers, ) with resources.as_file(resources.files("openfe.tests.data.openmm_rfe")) as d: smallM_components = [ SmallMoleculeComponent.from_sdf_file(d / f) for f in ["ligand_23.sdf", "ligand_55.sdf"] ] solvent_component = SolventComponent() alchemical_network, ligand_network = plan_rhfe_network_main( mapper=[LomapAtomMapper()], mapping_scorer=lomap_scorers.default_lomap_score, ligand_network_planner=ligand_network_planning.generate_minimal_spanning_network, small_molecules=smallM_components, solvent=solvent_component, n_protocol_repeats=3, partial_charge_settings=OpenFFPartialChargeSettings( partial_charge_method="nagl", nagl_model="openff-gnn-am1bcc-0.1.0-rc.3.pt" ), processors=1, overwrite_charges=False, ) assert alchemical_network assert ligand_network # check the ligands have charges for node in alchemical_network.nodes: validate_charges(node.components["ligand"]) @pytest.fixture def yaml_nagl_settings(): return """\ partial_charge: method: nagl settings: nagl_model: openff-gnn-am1bcc-0.1.0-rc.3.pt """ @pytest.mark.skipif( not HAS_NAGL, reason="needs NAGL", ) @pytest.mark.skipif( HAS_OPENEYE, reason="cannot use NAGL with rdkit backend when OpenEye is installed" ) def test_plan_rhfe_network(mol_dir_args, tmp_path, yaml_nagl_settings): """ smoke test """ # use nagl charges for CI speed! settings_path = tmp_path / "settings.yaml" with open(settings_path, "w") as f: f.write(yaml_nagl_settings) args = mol_dir_args expected_output_always = [ "RHFE-NETWORK PLANNER", "Solvent: SolventComponent(name=O, Na+, Cl-)", "- tmp_network.json", # make sure the partial charge settings are picked up "Partial Charge Generation: nagl", "assigning ligand partial charges -- this may be slow", ] # we can get these in either order: 22 then 55 or 55 then 22 expected_output_1 = [ "Small Molecules: SmallMoleculeComponent(name=ligand_23) SmallMoleculeComponent(name=ligand_55)", "- rhfe_ligand_23_vacuum_ligand_55_vacuum.json", "- rhfe_ligand_23_solvent_ligand_55_solvent.json", ] expected_output_2 = [ "Small Molecules: SmallMoleculeComponent(name=ligand_55) SmallMoleculeComponent(name=ligand_23)", "- rhfe_ligand_55_vacuum_ligand_23_vacuum.json", "- rhfe_ligand_55_solvent_ligand_23_solvent.json", ] patch_base = "openfecli.commands.plan_rhfe_network." args += ["-o", "tmp_network"] args += ["-s", settings_path] patch_loc = patch_base + "plan_rhfe_network" patch_func = print_test_with_file runner = CliRunner() with mock.patch(patch_loc, patch_func): with runner.isolated_filesystem(): result = runner.invoke(plan_rhfe_network, args) print(result.output) assert result.exit_code == 0 for line in expected_output_always: assert line in result.output for l1, l2 in zip(expected_output_1, expected_output_2): assert l1 in result.output or l2 in result.output @pytest.fixture def custom_yaml_settings(): return """\ network: method: generate_minimal_redundant_network settings: mst_num: 2 mapper: method: LomapAtomMapper settings: time: 45 element_change: True partial_charge: method: nagl settings: nagl_model: openff-gnn-am1bcc-0.1.0-rc.3.pt """ @pytest.mark.skipif( not HAS_NAGL, reason="needs NAGL", ) @pytest.mark.skipif( HAS_OPENEYE, reason="cannot use NAGL with rdkit backend when OpenEye is installed" ) def test_custom_yaml_plan_rhfe_smoke_test(custom_yaml_settings, mol_dir_args, tmp_path): settings_path = tmp_path / "settings.yaml" with open(settings_path, "w") as f: f.write(custom_yaml_settings) assert settings_path.exists() args = mol_dir_args + ["-s", settings_path] runner = CliRunner() with runner.isolated_filesystem(): result = runner.invoke(plan_rhfe_network, args) assert result.exit_code == 0 @pytest.mark.parametrize( "overwrite", [ pytest.param(True, id="Overwrite"), pytest.param(False, id="No overwrite"), ], ) @pytest.mark.skipif( not HAS_NAGL, reason="needs NAGL", ) @pytest.mark.skipif( HAS_OPENEYE, reason="cannot use NAGL with rdkit backend when OpenEye is installed" ) def test_plan_rhfe_network_charge_overwrite(dummy_charge_dir_args, tmp_path, yaml_nagl_settings, overwrite): # fmt: skip # make sure the dummy charges are overwritten when requested # use nagl charges for CI speed! settings_path = tmp_path / "settings.yaml" with open(settings_path, "w") as f: f.write(yaml_nagl_settings) args = dummy_charge_dir_args + ["-s", settings_path] # get the input charges for the molecules to check they have been overwritten charges_by_name = {} for f in ["dummy_charge_ligand_23.sdf", "dummy_charge_ligand_55.sdf"]: smc = SmallMoleculeComponent.from_sdf_file(dummy_charge_dir_args[1] / f) charges_by_name[smc.name] = smc.to_openff().partial_charges.m if overwrite: args.append("--overwrite-charges") runner = CliRunner() with runner.isolated_filesystem(): result = runner.invoke(plan_rhfe_network, args) assert result.exit_code == 0 if overwrite: assert "Overwriting partial charges" in result.output network = AlchemicalNetwork.from_json("alchemicalNetwork/alchemicalNetwork.json") # make sure the ligands don't have dummy charges for node in network.nodes: off_mol = node.components["ligand"].to_openff() if overwrite: assert not np.allclose(off_mol.partial_charges.m, charges_by_name[off_mol.name]) else: assert np.allclose(off_mol.partial_charges.m, charges_by_name[off_mol.name]) ================================================ FILE: src/openfecli/tests/commands/test_quickrun.py ================================================ import json import os import pathlib from importlib import resources from unittest import mock import pytest from click.testing import CliRunner from gufe import Transformation from gufe.tokenization import JSON_HANDLER from openfecli.commands.quickrun import _hash_quickrun_inputs, quickrun from ..utils import assert_click_success @pytest.fixture def json_file(): with resources.as_file(resources.files("openfecli.tests.data")) as d: json_file = str(d / "transformation.json") return json_file @pytest.mark.parametrize("extra_args", [{}, {"-d": "foo_dir", "-o": "foo.json"}]) def test_quickrun(extra_args, json_file): extras = sum([list(kv) for kv in extra_args.items()], []) runner = CliRunner() with runner.isolated_filesystem(): # figure out what cached json should be trans = Transformation.from_json(json_file) work_dir = extra_args.get("-d", ".") outfile = pathlib.Path(extra_args.get("-o", f"{trans.key}_results.json")) hashed_key = _hash_quickrun_inputs(outfile, trans) # output json shouldn't be created before quickrun is executed assert not pathlib.Path(outfile).exists() result = runner.invoke(quickrun, [json_file] + extras) assert_click_success(result) assert "Here is the result" in result.output # cache should be deleted when job is complete assert not pathlib.Path(work_dir, "quickrun_cache", f"dag-cache-{hashed_key}.json").exists() # output json should exist with data when job is complete assert pathlib.Path(outfile).exists() with open(outfile, mode="r") as outf: dct = json.load(outf, cls=JSON_HANDLER.decoder) assert set(dct) == {"estimate", "uncertainty", "protocol_result", "unit_results"} # TODO: need a protocol that drops files to actually do this! # if directory := extra_args.get('-d'): # dirpath = pathlib.Path(directory) # assert dirpath.exists() # assert dirpath.is_dir() # assert len(list(dirpath.iterdir())) > 0 @pytest.mark.parametrize("extra_args", [{}, {"-d": "foo_dir", "-o": "foo.json"}]) def test_quickrun_interrupted(extra_args, json_file): """If quickrun starts but is unable to complete, the cached DAG should exist.""" extras = sum([list(kv) for kv in extra_args.items()], []) runner = CliRunner() with runner.isolated_filesystem(): # figure out what cached json should be trans = Transformation.from_json(json_file) work_dir = pathlib.Path(extra_args.get("-d", ".")).absolute() outfile = pathlib.Path(extra_args.get("-o", f"{trans.key}_results.json")) hashed_key = _hash_quickrun_inputs(outfile, trans) with mock.patch("gufe.protocols.protocoldag.execute_DAG", side_effect=RuntimeError): result = runner.invoke(quickrun, [json_file] + extras) assert "Here is the result" not in result.output assert pathlib.Path(work_dir, "quickrun_cache", f"dag-cache-{hashed_key}.json").exists() def test_quickrun_output_file_exists(json_file): """Fail if the output file already exists.""" runner = CliRunner() with runner.isolated_filesystem(): pathlib.Path("foo.json").touch() result = runner.invoke(quickrun, [json_file, "-o", "foo.json"]) assert result.exit_code == 2 # usage error assert "is a file." in result.output def test_quickrun_output_file_in_nonexistent_directory(json_file): """Should create the parent directory for output file if it doesn't exist.""" runner = CliRunner() with runner.isolated_filesystem(): outfile = pathlib.Path("not_dir/foo.json") result = runner.invoke(quickrun, [json_file, "-o", outfile]) assert_click_success(result) assert outfile.parent.is_dir() def test_quickrun_dir_created_at_runtime(json_file): """It should be valid to have a new directory created by the -d flag.""" runner = CliRunner() with runner.isolated_filesystem(): outdir = "not_dir" outfile = outdir + "foo.json" result = runner.invoke(quickrun, [json_file, "-d", outdir, "-o", outfile]) assert_click_success(result) def test_quickrun_unit_error(): with resources.as_file(resources.files("openfecli.tests.data")) as d: json_file = str(d / "bad_transformation.json") runner = CliRunner() with runner.isolated_filesystem(): result = runner.invoke(quickrun, [json_file, "-o", "foo.json"]) assert result.exit_code == 1 assert pathlib.Path("foo.json").exists() # TODO: I'm still not happy with this... failure result does not see # to be stored in JSON # not sure whether that means we should always be storing all # protocol dag results maybe? def test_quickrun_existing_cache_error(json_file): """In the default case where resume=False, if the cache exists, quickrun should error out and not attempt to execute.""" trans = Transformation.from_json(json_file) dag = trans.create() runner = CliRunner() with runner.isolated_filesystem(): outfile = pathlib.Path(f"{trans.key}_results.json") hashed_key = _hash_quickrun_inputs(outfile, trans) pathlib.Path("quickrun_cache").mkdir() dag.to_json(pathlib.Path("quickrun_cache", f"dag-cache-{hashed_key}.json")) result = runner.invoke(quickrun, [json_file]) assert result.exit_code == 1 assert "Attempting to resume" not in result.output assert "Transformation has been started but is incomplete." in result.stderr def test_quickrun_resume_from_cache(json_file): trans = Transformation.from_json(json_file) dag = trans.create() runner = CliRunner() with runner.isolated_filesystem(): outfile = pathlib.Path(f"{trans.key}_results.json") hashed_key = _hash_quickrun_inputs(outfile, trans) pathlib.Path("quickrun_cache").mkdir() dag_cache = pathlib.Path("quickrun_cache", f"dag-cache-{hashed_key}.json") dag.to_json(dag_cache) result = runner.invoke(quickrun, [json_file, "--resume"]) assert_click_success(result) assert f"resume execution using '{dag_cache.absolute()}" in result.output assert "Success" in result.output def test_quickrun_resume_invalid_cache(json_file): """Fail if the output file doesn't load properly.""" trans = Transformation.from_json(json_file) runner = CliRunner() with runner.isolated_filesystem(): outfile = pathlib.Path(f"{trans.key}_results.json") hashed_key = _hash_quickrun_inputs(outfile, trans) pathlib.Path("quickrun_cache").mkdir() dag_cache = pathlib.Path("quickrun_cache", f"dag-cache-{hashed_key}.json") dag_cache.touch() result = runner.invoke(quickrun, [json_file, "--resume"]) assert result.exit_code == 1 assert f"resume execution using '{dag_cache.absolute()}" in result.output assert "Recovery failed" in result.stderr def test_quickrun_resume_missing_cache(json_file): """If --resume is passed but there's no cache, just echo a message and start from scratch.""" runner = CliRunner() with runner.isolated_filesystem(): # determine what the cache to be looked for should be named trans = Transformation.from_json(json_file) outfile = pathlib.Path(f"{trans.key}_results.json") hashed_key = _hash_quickrun_inputs(outfile, trans) dag_cache = pathlib.Path("quickrun_cache", f"dag-cache-{hashed_key}.json") result = runner.invoke(quickrun, [json_file, "--resume"]) assert_click_success(result) assert ( f"openfe quickrun was run with --resume, but no cached results found at {dag_cache.absolute()}" in result.output ) ================================================ FILE: src/openfecli/tests/commands/test_test.py ================================================ import os from unittest import mock import pytest from click.testing import CliRunner from openfecli.commands.test import test def mock_func(args): print(os.environ.get("OFE_SLOW_TESTS")) @pytest.mark.parametrize("slow", [True, False]) def test_test(slow): runner = CliRunner() args = ["--long"] if slow else [] patchloc = "openfecli.commands.test.pytest.main" ofe_slow_tests = os.environ.get("OFE_SLOW_TESTS") with mock.patch(patchloc, mock_func): with runner.isolated_filesystem(): result = runner.invoke(test, args) assert result.exit_code == 0 l1, l2, l3, _ = result.output.split("\n") assert l1 == "Testing can import...." assert l2 == "Running the main package tests" assert l3 == str(slow) assert ofe_slow_tests == os.environ.get("OFE_SLOW_TESTS") ================================================ FILE: src/openfecli/tests/conftest.py ================================================ import urllib.error import urllib.request try: urllib.request.urlopen("https://www.google.com") except urllib.error.URLError: # -no-cov- HAS_INTERNET = False else: HAS_INTERNET = True ================================================ FILE: src/openfecli/tests/data/__init__.py ================================================ ================================================ FILE: src/openfecli/tests/data/bad_transformation.json ================================================ {":version:": 1, "__module__": "gufe.transformations.transformation", "__qualname__": "Transformation", "mapping": {":version:": 1, "__module__": "gufe.mapping.ligandatommapping", "__qualname__": "LigandAtomMapping", "annotations": "{}", "componentA": {":version:": 1, "__module__": "gufe.components.smallmoleculecomponent", "__qualname__": "SmallMoleculeComponent", "atoms": [[6, 0, 0, true, 0, 0, {}], [6, 0, 0, true, 0, 0, {}], [6, 0, 0, true, 0, 0, {}], [6, 0, 0, true, 0, 0, {}], [6, 0, 0, true, 0, 0, {}], [6, 0, 0, true, 0, 0, {}], [1, 0, 0, false, 0, 0, {}], [1, 0, 0, false, 0, 0, {}], [1, 0, 0, false, 0, 0, {}], [1, 0, 0, false, 0, 0, {}], [1, 0, 0, false, 0, 0, {}], [1, 0, 0, false, 0, 0, {}]], "bonds": [[0, 1, 12, 0, {}], [0, 5, 12, 0, {}], [0, 6, 1, 0, {}], [1, 2, 12, 0, {}], [1, 7, 1, 0, {}], [2, 3, 12, 0, {}], [2, 8, 1, 0, {}], [3, 4, 12, 0, {}], [3, 9, 1, 0, {}], [4, 5, 12, 0, {}], [4, 10, 1, 0, {}], [5, 11, 1, 0, {}]], "conformer": ["\u0093NUMPY\u0001\u0000v\u0000{'descr': '\u00e8<@[\u00b1\u00bf\u00ec\u009e|!@\u00b0rh\u0091\u00ed|\u0014@\u00c3d\u00aa`T2<@\u009a\b\u001b\u009e^I @\u00caT\u00c1\u00a8\u00a4\u008e\u001a@?\u00c6\u00dc\u00b5\u0084\u00fc;@\u00da\u001b|a2\u00d5 @$(~\u008c\u00b9k\u0016@n\u00a3\u0001\u00bc\u0005B;@\u00c0\u00ec\u009e<,t\"@\u0084\u009e\u00cd\u00aa\u00cfU\u0016@\u00ee|?5^\u00fa9@\u0002+\u0087\u0016\u00d9N\u0015@\u0004V\u000e-\u00b2\u001d\u0013@\u0085\u00ebQ\u00b8\u001ee:@\u00b2\u009d\u00ef\u00a7\u00c6K\u0014@\u00cb\u00a1E\u00b6\u00f3\u00fd\u000b@\u00d7\u00a3p=\nW;@q=\n\u00d7\u00a3p\u0017@\u009e\u00ef\u00a7\u00c6K7\u0007@\u0083\u00c0\u00ca\u00a1E\u00d6;@\u00c9v\u00be\u009f\u001a\u00af\u001b@Zd;\u00dfO\u008d\f@\u00ecQ\u00b8\u001e\u0085k;@b\u0010X9\u00b4\u00c8\u001c@\u0006\u0081\u0095C\u008bl\u0013@sh\u0091\u00ed|\u007f:@j\u00bct\u0093\u0018\u0084\u0019@\u00c7K7\u0089A\u00e0\u0015@\u00ed\u009e<,\u00d4:9@\u00e8<@[\u00b1\u00bf\u00ec\u009e|!@\u00b0rh\u0091\u00ed|\u0014@\u00c3d\u00aa`T2<@\u009a\b\u001b\u009e^I @\u00caT\u00c1\u00a8\u00a4\u008e\u001a@?\u00c6\u00dc\u00b5\u0084\u00fc;@\u00da\u001b|a2\u00d5 @$(~\u008c\u00b9k\u0016@n\u00a3\u0001\u00bc\u0005B;@\u00c0\u00ec\u009e<,t\"@\u0084\u009e\u00cd\u00aa\u00cfU\u0016@\u00ee|?5^\u00fa9@\u0002+\u0087\u0016\u00d9N\u0015@\u0004V\u000e-\u00b2\u001d\u0013@\u0085\u00ebQ\u00b8\u001ee:@\u00b2\u009d\u00ef\u00a7\u00c6K\u0014@\u00cb\u00a1E\u00b6\u00f3\u00fd\u000b@\u00d7\u00a3p=\nW;@q=\n\u00d7\u00a3p\u0017@\u009e\u00ef\u00a7\u00c6K7\u0007@\u0083\u00c0\u00ca\u00a1E\u00d6;@\u00c9v\u00be\u009f\u001a\u00af\u001b@Zd;\u00dfO\u008d\f@\u00ecQ\u00b8\u001e\u0085k;@b\u0010X9\u00b4\u00c8\u001c@\u0006\u0081\u0095C\u008bl\u0013@sh\u0091\u00ed|\u007f:@j\u00bct\u0093\u0018\u0084\u0019@\u00c7K7\u0089A\u00e0\u0015@\u00ed\u009e<,\u00d4:9@ lig_ejm_31 > 0.14809375 -0.095906249999999998 -0.12890625 0.052493750000000006 -0.14350625 0.052493750000000006 -0.12890625 0.15709375 -0.060306249999999999 0.69179374999999999 -0.55000625000000003 -0.46000625000000001 0.33059375000000002 0.12769374999999999 -0.30420625000000001 0.44529374999999999 -0.73790624999999999 0.55129375000000003 -0.32320624999999997 0.18009375 -0.55330625 0.33159375000000002 0.67119375000000003 -0.59300624999999996 -0.17800625 0.070793750000000003 0.070793750000000003 0.070793750000000003 0.025193750000000004 0.18309375 -0.060306249999999999 0.15709375 $$$$ lig_ejm_42 RDKit 3D 35 36 0 0 0 0 0 0 0 0999 V2000 -4.7651 -2.8327 -16.5085 H 0 0 0 0 0 0 0 0 0 0 0 0 -5.3566 -3.6931 -16.2274 C 0 0 0 0 0 0 0 0 0 0 0 0 -4.7703 -4.9699 -16.2000 C 0 0 0 0 0 0 0 0 0 0 0 0 -5.5308 -6.0951 -15.8304 C 0 0 0 0 0 0 0 0 0 0 0 0 -6.8949 -5.9511 -15.4713 C 0 0 0 0 0 0 0 0 0 0 0 0 -7.4890 -4.6634 -15.5282 C 0 0 0 0 0 0 0 0 0 0 0 0 -6.7163 -3.5454 -15.9025 C 0 0 0 0 0 0 0 0 0 0 0 0 -7.1712 -2.5665 -15.9462 H 0 0 0 0 0 0 0 0 0 0 0 0 -9.1723 -4.4253 -15.1881 Cl 0 0 0 0 0 0 0 0 0 0 0 0 -7.7033 -7.1383 -15.0290 C 0 0 0 0 0 0 0 0 0 0 0 0 -8.1063 -7.2116 -13.8677 O 0 0 0 0 0 0 0 0 0 0 0 0 -7.9070 -8.0509 -15.9995 N 0 0 0 0 0 0 0 0 0 0 0 0 -7.4368 -7.8589 -16.8700 H 0 0 0 0 0 0 0 0 0 0 0 0 -8.7273 -9.2093 -16.0054 C 0 0 0 0 0 0 0 0 0 0 0 0 -9.5795 -9.5870 -14.9482 C 0 0 0 0 0 0 0 0 0 0 0 0 -10.3824 -10.7260 -15.1183 C 0 0 0 0 0 0 0 0 0 0 0 0 -10.3697 -11.4927 -16.2307 N 0 0 0 0 0 0 0 0 0 0 0 0 -9.5502 -11.1540 -17.2556 C 0 0 0 0 0 0 0 0 0 0 0 0 -8.7228 -10.0033 -17.1694 C 0 0 0 0 0 0 0 0 0 0 0 0 -8.0991 -9.7012 -17.9932 H 0 0 0 0 0 0 0 0 0 0 0 0 -9.5855 -11.9542 -18.4360 N 0 0 0 0 0 0 0 0 0 0 0 0 -10.4161 -12.5261 -18.5296 H 0 0 0 0 0 0 0 0 0 0 0 0 -8.6860 -12.0792 -19.4324 C 0 0 0 0 0 0 0 0 0 0 0 0 -7.6122 -11.4803 -19.4878 O 0 0 0 0 0 0 0 0 0 0 0 0 -9.0543 -13.0501 -20.5630 C 0 0 0 0 0 0 0 0 0 0 0 0 -9.4460 -12.4644 -21.3945 H 0 0 0 0 0 0 0 0 0 0 0 0 -9.8593 -13.7211 -20.2586 H 0 0 0 0 0 0 0 0 0 0 0 0 -7.8548 -13.8881 -21.0370 C 0 0 0 0 0 0 0 0 0 0 0 0 -8.1521 -14.5653 -21.8378 H 0 0 0 0 0 0 0 0 0 0 0 0 -7.4478 -14.4888 -20.2242 H 0 0 0 0 0 0 0 0 0 0 0 0 -7.0528 -13.2593 -21.4243 H 0 0 0 0 0 0 0 0 0 0 0 0 -11.0595 -11.0334 -14.3357 H 0 0 0 0 0 0 0 0 0 0 0 0 -9.6718 -9.0215 -14.0321 H 0 0 0 0 0 0 0 0 0 0 0 0 -4.7507 -7.6371 -15.8263 Cl 0 0 0 0 0 0 0 0 0 0 0 0 -3.7255 -5.0857 -16.4564 H 0 0 0 0 0 0 0 0 0 0 0 0 1 2 1 0 2 7 2 0 2 3 1 0 3 4 2 0 3 35 1 0 4 5 1 0 4 34 1 0 5 6 2 0 5 10 1 0 6 7 1 0 6 9 1 0 7 8 1 0 10 11 2 0 10 12 1 0 12 13 1 0 12 14 1 0 14 19 1 0 14 15 2 0 15 16 1 0 15 33 1 0 16 17 2 0 16 32 1 0 17 18 1 0 18 19 2 0 18 21 1 0 19 20 1 0 21 22 1 0 21 23 1 0 23 24 2 0 23 25 1 0 25 26 1 0 25 27 1 0 25 28 1 0 28 29 1 0 28 30 1 0 28 31 1 0 M END > lig_ejm_42 > 0.14794282857142857 -0.096057171428571425 -0.12905717142857143 0.052342828571428572 -0.14365717142857143 0.052342828571428572 -0.12905717142857143 0.15694282857142858 -0.059957171428571432 0.69164282857142856 -0.55015717142857146 -0.46015717142857143 0.33044282857142859 0.12754282857142857 -0.30335717142857144 0.44414282857142856 -0.73705717142857141 0.5501428285714286 -0.3203571714285714 0.17894282857142857 -0.54945717142857142 0.33144282857142859 0.6690428285714286 -0.59315717142857138 -0.15645717142857143 0.07564282857142858 0.07564282857142858 -0.097157171428571429 0.045309828571428568 0.045309828571428568 0.045309828571428568 0.025042828571428571 0.18294282857142857 -0.059957171428571432 0.15694282857142858 $$$$ lig_ejm_43 RDKit 3D 38 39 0 0 0 0 0 0 0 0999 V2000 -4.7758 -2.7864 -16.4082 H 0 0 0 0 0 0 0 0 0 0 0 0 -5.3657 -3.6568 -16.1610 C 0 0 0 0 0 0 0 0 0 0 0 0 -4.7770 -4.9320 -16.1583 C 0 0 0 0 0 0 0 0 0 0 0 0 -5.5388 -6.0668 -15.8207 C 0 0 0 0 0 0 0 0 0 0 0 0 -6.9087 -5.9356 -15.4763 C 0 0 0 0 0 0 0 0 0 0 0 0 -7.4997 -4.6467 -15.5030 C 0 0 0 0 0 0 0 0 0 0 0 0 -6.7268 -3.5203 -15.8414 C 0 0 0 0 0 0 0 0 0 0 0 0 -7.1830 -2.5426 -15.8586 H 0 0 0 0 0 0 0 0 0 0 0 0 -9.1769 -4.4070 -15.1619 Cl 0 0 0 0 0 0 0 0 0 0 0 0 -7.7202 -7.1315 -15.0648 C 0 0 0 0 0 0 0 0 0 0 0 0 -8.1427 -7.2196 -13.9119 O 0 0 0 0 0 0 0 0 0 0 0 0 -7.9075 -8.0393 -16.0420 N 0 0 0 0 0 0 0 0 0 0 0 0 -7.4294 -7.8412 -16.9085 H 0 0 0 0 0 0 0 0 0 0 0 0 -8.7331 -9.1970 -16.0628 C 0 0 0 0 0 0 0 0 0 0 0 0 -9.5813 -9.5943 -15.0077 C 0 0 0 0 0 0 0 0 0 0 0 0 -10.3875 -10.7275 -15.1925 C 0 0 0 0 0 0 0 0 0 0 0 0 -10.3747 -11.4776 -16.3137 N 0 0 0 0 0 0 0 0 0 0 0 0 -9.5525 -11.1298 -17.3300 C 0 0 0 0 0 0 0 0 0 0 0 0 -8.7317 -9.9757 -17.2380 C 0 0 0 0 0 0 0 0 0 0 0 0 -8.1078 -9.6660 -18.0619 H 0 0 0 0 0 0 0 0 0 0 0 0 -9.5769 -11.9365 -18.5018 N 0 0 0 0 0 0 0 0 0 0 0 0 -10.4090 -12.5045 -18.5971 H 0 0 0 0 0 0 0 0 0 0 0 0 -8.6442 -12.0954 -19.4628 C 0 0 0 0 0 0 0 0 0 0 0 0 -7.5769 -11.4851 -19.5059 O 0 0 0 0 0 0 0 0 0 0 0 0 -8.9538 -13.1242 -20.5645 C 0 0 0 0 0 0 0 0 0 0 0 0 -9.8786 -13.6562 -20.3326 H 0 0 0 0 0 0 0 0 0 0 0 0 -7.8024 -14.1443 -20.7182 C 0 0 0 0 0 0 0 0 0 0 0 0 -7.5769 -14.7000 -19.8218 H 0 0 0 0 0 0 0 0 0 0 0 0 -6.8777 -13.6545 -21.0281 H 0 0 0 0 0 0 0 0 0 0 0 0 -8.0460 -14.8838 -21.4813 H 0 0 0 0 0 0 0 0 0 0 0 0 -9.0660 -12.4773 -21.9486 C 0 0 0 0 0 0 0 0 0 0 0 0 -9.9769 -11.9211 -22.0282 H 0 0 0 0 0 0 0 0 0 0 0 0 -8.2320 -11.8090 -22.1675 H 0 0 0 0 0 0 0 0 0 0 0 0 -9.1067 -13.2257 -22.7407 H 0 0 0 0 0 0 0 0 0 0 0 0 -11.0613 -11.0504 -14.4126 H 0 0 0 0 0 0 0 0 0 0 0 0 -9.6587 -9.0508 -14.0795 H 0 0 0 0 0 0 0 0 0 0 0 0 -4.7498 -7.6003 -15.8230 Cl 0 0 0 0 0 0 0 0 0 0 0 0 -3.7302 -5.0379 -16.4049 H 0 0 0 0 0 0 0 0 0 0 0 0 1 2 1 0 2 7 2 0 2 3 1 0 3 4 2 0 3 38 1 0 4 5 1 0 4 37 1 0 5 6 2 0 5 10 1 0 6 7 1 0 6 9 1 0 7 8 1 0 10 11 2 0 10 12 1 0 12 13 1 0 12 14 1 0 14 19 1 0 14 15 2 0 15 16 1 0 15 36 1 0 16 17 2 0 16 35 1 0 17 18 1 0 18 19 2 0 18 21 1 0 19 20 1 0 21 22 1 0 21 23 1 0 23 24 2 0 23 25 1 0 25 26 1 0 25 27 1 0 25 31 1 0 27 28 1 0 27 29 1 0 27 30 1 0 31 32 1 0 31 33 1 0 31 34 1 0 M END > lig_ejm_43 > 0.14792105263157893 -0.096078947368421055 -0.12907894736842107 0.052321052631578949 -0.14367894736842107 0.052321052631578949 -0.12907894736842107 0.15692105263157893 -0.059978947368421055 0.69162105263157891 -0.5501789473684211 -0.46017894736842108 0.33042105263157895 0.12752105263157892 -0.30337894736842108 0.44412105263157892 -0.73707894736842106 0.55012105263157896 -0.32037894736842104 0.17792105263157892 -0.55147894736842107 0.33042105263157895 0.66902105263157896 -0.58917894736842102 -0.13277894736842108 0.066621052631578942 -0.091178947368421054 0.047121052631578945 0.047121052631578945 0.047121052631578945 -0.091178947368421054 0.047121052631578945 0.047121052631578945 0.047121052631578945 0.025021052631578947 0.18292105263157893 -0.059978947368421055 0.15692105263157893 $$$$ lig_ejm_46 RDKit 3D 36 38 0 0 0 0 0 0 0 0999 V2000 -4.7642 -2.8405 -16.5095 H 0 0 0 0 0 0 0 0 0 0 0 0 -5.3549 -3.7036 -16.2280 C 0 0 0 0 0 0 0 0 0 0 0 0 -4.7655 -4.9789 -16.1978 C 0 0 0 0 0 0 0 0 0 0 0 0 -5.5250 -6.1059 -15.8276 C 0 0 0 0 0 0 0 0 0 0 0 0 -6.8908 -5.9630 -15.4706 C 0 0 0 0 0 0 0 0 0 0 0 0 -7.4868 -4.6765 -15.5285 C 0 0 0 0 0 0 0 0 0 0 0 0 -6.7155 -3.5576 -15.9050 C 0 0 0 0 0 0 0 0 0 0 0 0 -7.1711 -2.5800 -15.9497 H 0 0 0 0 0 0 0 0 0 0 0 0 -9.1671 -4.4347 -15.1879 Cl 0 0 0 0 0 0 0 0 0 0 0 0 -7.7019 -7.1485 -15.0306 C 0 0 0 0 0 0 0 0 0 0 0 0 -8.1203 -7.2180 -13.8734 O 0 0 0 0 0 0 0 0 0 0 0 0 -7.9020 -8.0626 -15.9990 N 0 0 0 0 0 0 0 0 0 0 0 0 -7.4296 -7.8726 -16.8697 H 0 0 0 0 0 0 0 0 0 0 0 0 -8.7245 -9.2193 -16.0067 C 0 0 0 0 0 0 0 0 0 0 0 0 -9.5810 -9.6038 -14.9544 C 0 0 0 0 0 0 0 0 0 0 0 0 -10.3869 -10.7402 -15.1394 C 0 0 0 0 0 0 0 0 0 0 0 0 -10.3684 -11.4988 -16.2561 N 0 0 0 0 0 0 0 0 0 0 0 0 -9.5411 -11.1531 -17.2713 C 0 0 0 0 0 0 0 0 0 0 0 0 -8.7144 -10.0045 -17.1736 C 0 0 0 0 0 0 0 0 0 0 0 0 -8.0887 -9.6938 -17.9918 H 0 0 0 0 0 0 0 0 0 0 0 0 -9.5589 -11.9408 -18.4576 N 0 0 0 0 0 0 0 0 0 0 0 0 -10.3650 -12.5441 -18.5562 H 0 0 0 0 0 0 0 0 0 0 0 0 -8.6360 -12.0467 -19.4396 C 0 0 0 0 0 0 0 0 0 0 0 0 -7.5689 -11.4309 -19.4796 O 0 0 0 0 0 0 0 0 0 0 0 0 -9.0181 -13.0160 -20.5102 C 0 0 0 0 0 0 0 0 0 0 0 0 -8.6057 -12.7169 -21.9357 C 0 0 0 0 0 0 0 0 0 0 0 0 -7.9060 -13.8101 -21.1676 C 0 0 0 0 0 0 0 0 0 0 0 0 -8.1255 -14.8406 -21.4327 H 0 0 0 0 0 0 0 0 0 0 0 0 -6.8762 -13.6193 -20.8697 H 0 0 0 0 0 0 0 0 0 0 0 0 -8.0355 -11.8125 -22.1402 H 0 0 0 0 0 0 0 0 0 0 0 0 -9.3172 -12.9932 -22.7102 H 0 0 0 0 0 0 0 0 0 0 0 0 -9.9736 -13.5213 -20.3895 H 0 0 0 0 0 0 0 0 0 0 0 0 -11.0748 -11.0441 -14.3639 H 0 0 0 0 0 0 0 0 0 0 0 0 -9.6684 -9.0431 -14.0367 H 0 0 0 0 0 0 0 0 0 0 0 0 -4.7380 -7.6418 -15.8227 Cl 0 0 0 0 0 0 0 0 0 0 0 0 -3.7213 -5.0916 -16.4542 H 0 0 0 0 0 0 0 0 0 0 0 0 1 2 1 0 2 7 2 0 2 3 1 0 3 4 2 0 3 36 1 0 4 5 1 0 4 35 1 0 5 6 2 0 5 10 1 0 6 7 1 0 6 9 1 0 7 8 1 0 10 11 2 0 10 12 1 0 12 13 1 0 12 14 1 0 14 19 1 0 14 15 2 0 15 16 1 0 15 34 1 0 16 17 2 0 16 33 1 0 17 18 1 0 18 19 2 0 18 21 1 0 19 20 1 0 21 22 1 0 21 23 1 0 23 24 2 0 23 25 1 0 25 27 1 0 25 26 1 0 25 32 1 0 26 27 1 0 26 30 1 0 26 31 1 0 27 28 1 0 27 29 1 0 M END > lig_ejm_46 > 0.14799999999999999 -0.096000000000000002 -0.129 0.052400000000000002 -0.14360000000000001 0.052400000000000002 -0.129 0.157 -0.059900000000000002 0.69169999999999998 -0.55010000000000003 -0.46010000000000001 0.33050000000000002 0.12659999999999999 -0.30330000000000001 0.44419999999999998 -0.73599999999999999 0.55020000000000002 -0.32029999999999997 0.17799999999999999 -0.5474 0.33350000000000002 0.70009999999999994 -0.59309999999999996 -0.22969999999999999 -0.10390000000000001 -0.10390000000000001 0.084199999999999997 0.084199999999999997 0.084199999999999997 0.084199999999999997 0.098699999999999996 0.025100000000000001 0.183 -0.059900000000000002 0.157 $$$$ lig_ejm_47 RDKit 3D 39 41 0 0 0 0 0 0 0 0999 V2000 -4.7710 -2.7958 -16.4978 H 0 0 0 0 0 0 0 0 0 0 0 0 -5.3622 -3.6601 -16.2251 C 0 0 0 0 0 0 0 0 0 0 0 0 -6.7228 -3.5154 -15.9047 C 0 0 0 0 0 0 0 0 0 0 0 0 -7.4990 -4.6316 -15.5395 C 0 0 0 0 0 0 0 0 0 0 0 0 -6.9098 -5.9210 -15.4840 C 0 0 0 0 0 0 0 0 0 0 0 0 -5.5411 -6.0619 -15.8372 C 0 0 0 0 0 0 0 0 0 0 0 0 -4.7773 -4.9364 -16.1997 C 0 0 0 0 0 0 0 0 0 0 0 0 -3.7298 -5.0464 -16.4444 H 0 0 0 0 0 0 0 0 0 0 0 0 -4.7493 -7.5935 -15.8222 Cl 0 0 0 0 0 0 0 0 0 0 0 0 -7.7221 -7.1086 -15.0399 C 0 0 0 0 0 0 0 0 0 0 0 0 -8.1200 -7.1967 -13.8766 O 0 0 0 0 0 0 0 0 0 0 0 0 -7.9177 -8.0239 -16.0075 N 0 0 0 0 0 0 0 0 0 0 0 0 -7.4448 -7.8335 -16.8781 H 0 0 0 0 0 0 0 0 0 0 0 0 -8.7460 -9.1777 -16.0235 C 0 0 0 0 0 0 0 0 0 0 0 0 -9.5772 -9.5870 -14.9614 C 0 0 0 0 0 0 0 0 0 0 0 0 -10.3788 -10.7255 -15.1522 C 0 0 0 0 0 0 0 0 0 0 0 0 -10.3750 -11.4658 -16.2840 N 0 0 0 0 0 0 0 0 0 0 0 0 -9.5645 -11.1035 -17.3073 C 0 0 0 0 0 0 0 0 0 0 0 0 -8.7559 -9.9418 -17.2069 C 0 0 0 0 0 0 0 0 0 0 0 0 -8.1406 -9.6119 -18.0290 H 0 0 0 0 0 0 0 0 0 0 0 0 -9.5782 -11.8937 -18.4963 N 0 0 0 0 0 0 0 0 0 0 0 0 -10.4038 -12.4664 -18.6054 H 0 0 0 0 0 0 0 0 0 0 0 0 -8.6353 -12.0193 -19.4573 C 0 0 0 0 0 0 0 0 0 0 0 0 -7.5764 -11.3926 -19.4774 O 0 0 0 0 0 0 0 0 0 0 0 0 -8.9229 -13.0284 -20.5859 C 0 0 0 0 0 0 0 0 0 0 0 0 -8.6756 -12.5134 -22.0198 C 0 0 0 0 0 0 0 0 0 0 0 0 -8.0186 -13.8555 -22.3469 C 0 0 0 0 0 0 0 0 0 0 0 0 -7.7694 -14.0202 -20.8465 C 0 0 0 0 0 0 0 0 0 0 0 0 -7.9493 -15.0312 -20.4860 H 0 0 0 0 0 0 0 0 0 0 0 0 -6.7826 -13.6664 -20.5416 H 0 0 0 0 0 0 0 0 0 0 0 0 -7.1203 -13.7980 -22.9633 H 0 0 0 0 0 0 0 0 0 0 0 0 -8.7315 -14.5837 -22.7394 H 0 0 0 0 0 0 0 0 0 0 0 0 -7.9803 -11.6755 -22.0897 H 0 0 0 0 0 0 0 0 0 0 0 0 -9.5770 -12.3187 -22.5983 H 0 0 0 0 0 0 0 0 0 0 0 0 -9.8902 -13.5295 -20.4978 H 0 0 0 0 0 0 0 0 0 0 0 0 -11.0408 -11.0611 -14.3663 H 0 0 0 0 0 0 0 0 0 0 0 0 -9.6397 -9.0467 -14.0281 H 0 0 0 0 0 0 0 0 0 0 0 0 -9.1773 -4.3783 -15.2060 Cl 0 0 0 0 0 0 0 0 0 0 0 0 -7.1757 -2.5362 -15.9443 H 0 0 0 0 0 0 0 0 0 0 0 0 1 2 1 0 2 7 2 0 2 3 1 0 3 4 2 0 3 39 1 0 4 5 1 0 4 38 1 0 5 6 2 0 5 10 1 0 6 7 1 0 6 9 1 0 7 8 1 0 10 11 2 0 10 12 1 0 12 13 1 0 12 14 1 0 14 19 1 0 14 15 2 0 15 16 1 0 15 37 1 0 16 17 2 0 16 36 1 0 17 18 1 0 18 19 2 0 18 21 1 0 19 20 1 0 21 22 1 0 21 23 1 0 23 24 2 0 23 25 1 0 25 28 1 0 25 26 1 0 25 35 1 0 26 27 1 0 26 33 1 0 26 34 1 0 27 28 1 0 27 31 1 0 27 32 1 0 28 29 1 0 28 30 1 0 M END > lig_ejm_47 > 0.14797435897435895 -0.096025641025641026 -0.12902564102564104 0.052374358974358971 -0.14362564102564104 0.052374358974358971 -0.12902564102564104 0.15697435897435896 -0.059925641025641033 0.69167435897435892 -0.5501256410256411 -0.46012564102564102 0.33047435897435901 0.12757435897435895 -0.30332564102564102 0.44417435897435897 -0.73702564102564105 0.55017435897435896 -0.32032564102564098 0.17797435897435895 -0.55142564102564107 0.33147435897435901 0.68207435897435897 -0.59112564102564102 -0.16772564102564103 -0.082425641025641025 -0.094425641025641022 -0.082425641025641025 0.062924358974358982 0.062924358974358982 0.055674358974358969 0.055674358974358969 0.062924358974358982 0.062924358974358982 0.085674358974358975 0.025074358974358973 0.18197435897435896 -0.059925641025641033 0.15697435897435896 $$$$ lig_ejm_48 RDKit 3D 42 44 0 0 0 0 0 0 0 0999 V2000 -4.7806 -2.7772 -16.4434 H 0 0 0 0 0 0 0 0 0 0 0 0 -5.3676 -3.6465 -16.1852 C 0 0 0 0 0 0 0 0 0 0 0 0 -4.7769 -4.9205 -16.1714 C 0 0 0 0 0 0 0 0 0 0 0 0 -5.5376 -6.0528 -15.8227 C 0 0 0 0 0 0 0 0 0 0 0 0 -6.9070 -5.9191 -15.4756 C 0 0 0 0 0 0 0 0 0 0 0 0 -7.4992 -4.6314 -15.5128 C 0 0 0 0 0 0 0 0 0 0 0 0 -6.7276 -3.5087 -15.8630 C 0 0 0 0 0 0 0 0 0 0 0 0 -7.1848 -2.5317 -15.8892 H 0 0 0 0 0 0 0 0 0 0 0 0 -9.1769 -4.3893 -15.1746 Cl 0 0 0 0 0 0 0 0 0 0 0 0 -7.7212 -7.1103 -15.0571 C 0 0 0 0 0 0 0 0 0 0 0 0 -8.1393 -7.1981 -13.9030 O 0 0 0 0 0 0 0 0 0 0 0 0 -7.9218 -8.0129 -16.0346 N 0 0 0 0 0 0 0 0 0 0 0 0 -7.4512 -7.8119 -16.9045 H 0 0 0 0 0 0 0 0 0 0 0 0 -8.7481 -9.1686 -16.0525 C 0 0 0 0 0 0 0 0 0 0 0 0 -9.5798 -9.5825 -14.9913 C 0 0 0 0 0 0 0 0 0 0 0 0 -10.3775 -10.7221 -15.1791 C 0 0 0 0 0 0 0 0 0 0 0 0 -10.3682 -11.4628 -16.3069 N 0 0 0 0 0 0 0 0 0 0 0 0 -9.5623 -11.0966 -17.3301 C 0 0 0 0 0 0 0 0 0 0 0 0 -8.7569 -9.9317 -17.2354 C 0 0 0 0 0 0 0 0 0 0 0 0 -8.1457 -9.5990 -18.0592 H 0 0 0 0 0 0 0 0 0 0 0 0 -9.5769 -11.9004 -18.5054 N 0 0 0 0 0 0 0 0 0 0 0 0 -10.3792 -12.5129 -18.5798 H 0 0 0 0 0 0 0 0 0 0 0 0 -8.6637 -12.0054 -19.4887 C 0 0 0 0 0 0 0 0 0 0 0 0 -7.6404 -11.3231 -19.5605 O 0 0 0 0 0 0 0 0 0 0 0 0 -8.9216 -13.0751 -20.5678 C 0 0 0 0 0 0 0 0 0 0 0 0 -8.9524 -12.4999 -21.9980 C 0 0 0 0 0 0 0 0 0 0 0 0 -8.2926 -13.5073 -22.9488 C 0 0 0 0 0 0 0 0 0 0 0 0 -7.7436 -14.6222 -22.0660 C 0 0 0 0 0 0 0 0 0 0 0 0 -7.6746 -13.9986 -20.6761 C 0 0 0 0 0 0 0 0 0 0 0 0 -7.5769 -14.7512 -19.8963 H 0 0 0 0 0 0 0 0 0 0 0 0 -6.7547 -13.4133 -20.6284 H 0 0 0 0 0 0 0 0 0 0 0 0 -6.7769 -14.9877 -22.4122 H 0 0 0 0 0 0 0 0 0 0 0 0 -8.4370 -15.4622 -22.0644 H 0 0 0 0 0 0 0 0 0 0 0 0 -7.4882 -13.0244 -23.5058 H 0 0 0 0 0 0 0 0 0 0 0 0 -9.0044 -13.8985 -23.6767 H 0 0 0 0 0 0 0 0 0 0 0 0 -8.4190 -11.5446 -22.0668 H 0 0 0 0 0 0 0 0 0 0 0 0 -9.9768 -12.3220 -22.3078 H 0 0 0 0 0 0 0 0 0 0 0 0 -9.8199 -13.6608 -20.3658 H 0 0 0 0 0 0 0 0 0 0 0 0 -11.0370 -11.0599 -14.3932 H 0 0 0 0 0 0 0 0 0 0 0 0 -9.6473 -9.0490 -14.0569 H 0 0 0 0 0 0 0 0 0 0 0 0 -4.7462 -7.5852 -15.8223 Cl 0 0 0 0 0 0 0 0 0 0 0 0 -3.7312 -5.0277 -16.4208 H 0 0 0 0 0 0 0 0 0 0 0 0 1 2 1 0 2 7 2 0 2 3 1 0 3 4 2 0 3 42 1 0 4 5 1 0 4 41 1 0 5 6 2 0 5 10 1 0 6 7 1 0 6 9 1 0 7 8 1 0 10 11 2 0 10 12 1 0 12 13 1 0 12 14 1 0 14 19 1 0 14 15 2 0 15 16 1 0 15 40 1 0 16 17 2 0 16 39 1 0 17 18 1 0 18 19 2 0 18 21 1 0 19 20 1 0 21 22 1 0 21 23 1 0 23 24 2 0 23 25 1 0 25 29 1 0 25 26 1 0 25 38 1 0 26 27 1 0 26 36 1 0 26 37 1 0 27 28 1 0 27 34 1 0 27 35 1 0 28 29 1 0 28 32 1 0 28 33 1 0 29 30 1 0 29 31 1 0 M END > lig_ejm_48 > 0.14797619047619048 -0.096023809523809525 -0.12902380952380951 0.052376190476190479 -0.14362380952380951 0.052376190476190479 -0.12902380952380951 0.15697619047619049 -0.059923809523809525 0.69167619047619044 -0.55012380952380957 -0.46012380952380955 0.33047619047619048 0.12657619047619048 -0.30332380952380955 0.44417619047619045 -0.73702380952380953 0.54917619047619048 -0.31932380952380951 0.17797619047619048 -0.55142380952380954 0.33147619047619048 0.6740761904761905 -0.5911238095238095 -0.1387238095238095 -0.076423809523809519 -0.079423809523809522 -0.079423809523809522 -0.076423809523809519 0.055926190476190477 0.055926190476190477 0.045426190476190474 0.045426190476190474 0.045426190476190474 0.045426190476190474 0.055926190476190477 0.055926190476190477 0.074676190476190479 0.025076190476190481 0.18297619047619049 -0.059923809523809525 0.15697619047619049 $$$$ lig_ejm_50 RDKit 3D 33 34 0 0 0 0 0 0 0 0999 V2000 -4.7971 -2.7828 -16.4669 H 0 0 0 0 0 0 0 0 0 0 0 0 -5.3788 -3.6540 -16.2032 C 0 0 0 0 0 0 0 0 0 0 0 0 -4.7842 -4.9254 -16.1895 C 0 0 0 0 0 0 0 0 0 0 0 0 -5.5365 -6.0583 -15.8239 C 0 0 0 0 0 0 0 0 0 0 0 0 -6.9024 -5.9288 -15.4613 C 0 0 0 0 0 0 0 0 0 0 0 0 -7.4999 -4.6438 -15.5003 C 0 0 0 0 0 0 0 0 0 0 0 0 -6.7356 -3.5208 -15.8669 C 0 0 0 0 0 0 0 0 0 0 0 0 -7.1930 -2.5443 -15.8928 H 0 0 0 0 0 0 0 0 0 0 0 0 -9.1769 -4.4052 -15.1506 Cl 0 0 0 0 0 0 0 0 0 0 0 0 -7.7083 -7.1203 -15.0262 C 0 0 0 0 0 0 0 0 0 0 0 0 -8.1436 -7.1856 -13.8767 O 0 0 0 0 0 0 0 0 0 0 0 0 -7.8838 -8.0479 -15.9847 N 0 0 0 0 0 0 0 0 0 0 0 0 -7.4002 -7.8655 -16.8511 H 0 0 0 0 0 0 0 0 0 0 0 0 -8.7100 -9.2031 -15.9928 C 0 0 0 0 0 0 0 0 0 0 0 0 -9.5717 -9.5861 -14.9420 C 0 0 0 0 0 0 0 0 0 0 0 0 -10.3774 -10.7205 -15.1209 C 0 0 0 0 0 0 0 0 0 0 0 0 -10.3600 -11.4760 -16.2385 N 0 0 0 0 0 0 0 0 0 0 0 0 -9.5290 -11.1353 -17.2521 C 0 0 0 0 0 0 0 0 0 0 0 0 -8.6974 -9.9916 -17.1601 C 0 0 0 0 0 0 0 0 0 0 0 0 -8.0618 -9.6948 -17.9809 H 0 0 0 0 0 0 0 0 0 0 0 0 -9.5770 -11.9206 -18.4322 N 0 0 0 0 0 0 0 0 0 0 0 0 -10.4274 -12.4608 -18.5322 H 0 0 0 0 0 0 0 0 0 0 0 0 -8.6810 -12.0611 -19.4286 C 0 0 0 0 0 0 0 0 0 0 0 0 -7.5776 -11.5115 -19.4762 O 0 0 0 0 0 0 0 0 0 0 0 0 -9.1224 -12.9805 -20.5744 C 0 0 0 0 0 0 0 0 0 0 0 0 -9.3530 -12.3758 -21.4514 H 0 0 0 0 0 0 0 0 0 0 0 0 -10.0327 -13.5198 -20.3069 H 0 0 0 0 0 0 0 0 0 0 0 0 -8.1134 -13.9200 -20.8980 O 0 0 0 0 0 0 0 0 0 0 0 0 -8.4590 -14.4776 -21.5795 H 0 0 0 0 0 0 0 0 0 0 0 0 -11.0554 -11.0362 -14.3423 H 0 0 0 0 0 0 0 0 0 0 0 0 -9.6558 -9.0323 -14.0202 H 0 0 0 0 0 0 0 0 0 0 0 0 -4.7358 -7.5856 -15.8221 Cl 0 0 0 0 0 0 0 0 0 0 0 0 -3.7408 -5.0305 -16.4513 H 0 0 0 0 0 0 0 0 0 0 0 0 1 2 1 0 2 7 2 0 2 3 1 0 3 4 2 0 3 33 1 0 4 5 1 0 4 32 1 0 5 6 2 0 5 10 1 0 6 7 1 0 6 9 1 0 7 8 1 0 10 11 2 0 10 12 1 0 12 13 1 0 12 14 1 0 14 19 1 0 14 15 2 0 15 16 1 0 15 31 1 0 16 17 2 0 16 30 1 0 17 18 1 0 18 19 2 0 18 21 1 0 19 20 1 0 21 22 1 0 21 23 1 0 23 24 2 0 23 25 1 0 25 26 1 0 25 27 1 0 25 28 1 0 28 29 1 0 M END > lig_ejm_50 > 0.14796969696969697 -0.096030303030303021 -0.12853030303030302 0.052369696969696976 -0.14363030303030302 0.052369696969696976 -0.12853030303030302 0.15696969696969698 -0.060430303030303029 0.69166969696969693 -0.54913030303030308 -0.46113030303030306 0.33046969696969697 0.12756969696969697 -0.30133030303030306 0.44416969696969694 -0.73103030303030303 0.54716969696969697 -0.32033030303030302 0.17796969696969697 -0.54143030303030304 0.34646969696969693 0.62606969696969694 -0.59413030303030301 0.055369696969696972 0.084669696969696978 0.084669696969696978 -0.58783030303030304 0.41096969696969693 0.027069696969696973 0.18296969696969698 -0.060430303030303029 0.15696969696969698 $$$$ lig_jmc_23 RDKit 3D 36 38 0 0 0 0 0 0 0 0999 V2000 -4.7871 -2.7885 -16.4970 H 0 0 0 0 0 0 0 0 0 0 0 0 -5.3697 -3.6577 -16.2217 C 0 0 0 0 0 0 0 0 0 0 0 0 -4.7769 -4.9309 -16.1922 C 0 0 0 0 0 0 0 0 0 0 0 0 -5.5340 -6.0593 -15.8230 C 0 0 0 0 0 0 0 0 0 0 0 0 -6.9023 -5.9231 -15.4705 C 0 0 0 0 0 0 0 0 0 0 0 0 -7.4977 -4.6364 -15.5270 C 0 0 0 0 0 0 0 0 0 0 0 0 -6.7277 -3.5164 -15.8967 C 0 0 0 0 0 0 0 0 0 0 0 0 -7.1783 -2.5375 -15.9389 H 0 0 0 0 0 0 0 0 0 0 0 0 -9.1769 -4.3939 -15.1975 Cl 0 0 0 0 0 0 0 0 0 0 0 0 -7.7122 -7.1118 -15.0366 C 0 0 0 0 0 0 0 0 0 0 0 0 -8.1396 -7.1851 -13.8839 O 0 0 0 0 0 0 0 0 0 0 0 0 -7.9032 -8.0308 -15.9995 N 0 0 0 0 0 0 0 0 0 0 0 0 -7.4257 -7.8484 -16.8690 H 0 0 0 0 0 0 0 0 0 0 0 0 -8.7261 -9.1875 -16.0036 C 0 0 0 0 0 0 0 0 0 0 0 0 -9.5483 -9.5964 -14.9328 C 0 0 0 0 0 0 0 0 0 0 0 0 -10.3511 -10.7349 -15.1078 C 0 0 0 0 0 0 0 0 0 0 0 0 -10.3507 -11.4835 -16.2324 N 0 0 0 0 0 0 0 0 0 0 0 0 -9.5485 -11.1226 -17.2638 C 0 0 0 0 0 0 0 0 0 0 0 0 -8.7412 -9.9596 -17.1804 C 0 0 0 0 0 0 0 0 0 0 0 0 -8.1391 -9.6368 -18.0149 H 0 0 0 0 0 0 0 0 0 0 0 0 -9.5669 -11.9191 -18.4439 N 0 0 0 0 0 0 0 0 0 0 0 0 -10.3812 -12.5111 -18.5394 H 0 0 0 0 0 0 0 0 0 0 0 0 -8.6403 -12.0386 -19.4227 C 0 0 0 0 0 0 0 0 0 0 0 0 -7.5787 -11.4151 -19.4628 O 0 0 0 0 0 0 0 0 0 0 0 0 -9.0326 -13.0172 -20.4895 C 0 0 2 0 0 0 0 0 0 0 0 0 -7.9828 -13.8780 -21.1725 C 0 0 1 0 0 0 0 0 0 0 0 0 -8.5985 -12.7210 -21.9125 C 0 0 0 0 0 0 0 0 0 0 0 0 -7.9711 -11.8488 -22.0970 H 0 0 0 0 0 0 0 0 0 0 0 0 -9.3252 -12.9339 -22.6915 H 0 0 0 0 0 0 0 0 0 0 0 0 -8.2299 -14.9031 -21.4408 H 0 0 0 0 0 0 0 0 0 0 0 0 -6.6531 -13.7447 -20.8110 F 0 0 0 0 0 0 0 0 0 0 0 0 -10.0144 -13.4741 -20.3734 H 0 0 0 0 0 0 0 0 0 0 0 0 -11.0124 -11.0557 -14.3155 H 0 0 0 0 0 0 0 0 0 0 0 0 -9.6070 -9.0544 -14.0007 H 0 0 0 0 0 0 0 0 0 0 0 0 -4.7367 -7.5877 -15.8252 Cl 0 0 0 0 0 0 0 0 0 0 0 0 -3.7329 -5.0446 -16.4497 H 0 0 0 0 0 0 0 0 0 0 0 0 1 2 1 0 2 7 2 0 2 3 1 0 3 4 2 0 3 36 1 0 4 5 1 0 4 35 1 0 5 6 2 0 5 10 1 0 6 7 1 0 6 9 1 0 7 8 1 0 10 11 2 0 10 12 1 0 12 13 1 0 12 14 1 0 14 19 1 0 14 15 2 0 15 16 1 0 15 34 1 0 16 17 2 0 16 33 1 0 17 18 1 0 18 19 2 0 18 21 1 0 19 20 1 0 21 22 1 0 21 23 1 0 23 24 2 0 23 25 1 0 25 27 1 0 25 26 1 0 25 32 1 6 26 27 1 0 26 30 1 6 26 31 1 0 27 28 1 0 27 29 1 0 M END > lig_jmc_23 > 0.14802777777777779 -0.095972222222222223 -0.12897222222222221 0.052427777777777781 -0.14357222222222221 0.052427777777777781 -0.12897222222222221 0.15702777777777779 -0.060372222222222223 0.69172777777777772 -0.5500722222222223 -0.46107222222222222 0.33052777777777781 0.12662777777777778 -0.30127222222222222 0.44422777777777778 -0.72997222222222224 0.54722777777777776 -0.31927222222222218 0.17702777777777778 -0.54137222222222225 0.34252777777777782 0.70112777777777768 -0.58607222222222222 -0.2336722222222222 0.12062777777777778 -0.12037222222222221 0.095227777777777786 0.095227777777777786 0.099727777777777776 -0.20527222222222222 0.11872777777777778 0.026127777777777781 0.18302777777777779 -0.060372222222222223 0.15702777777777779 $$$$ lig_jmc_27 RDKit 3D 36 38 0 0 0 0 0 0 0 0999 V2000 -4.7850 -2.7769 -16.4290 H 0 0 0 0 0 0 0 0 0 0 0 0 -5.3697 -3.6480 -16.1728 C 0 0 0 0 0 0 0 0 0 0 0 0 -4.7769 -4.9212 -16.1644 C 0 0 0 0 0 0 0 0 0 0 0 0 -5.5349 -6.0557 -15.8170 C 0 0 0 0 0 0 0 0 0 0 0 0 -6.9040 -5.9250 -15.4663 C 0 0 0 0 0 0 0 0 0 0 0 0 -7.4991 -4.6383 -15.5006 C 0 0 0 0 0 0 0 0 0 0 0 0 -6.7300 -3.5136 -15.8503 C 0 0 0 0 0 0 0 0 0 0 0 0 -7.1893 -2.5374 -15.8751 H 0 0 0 0 0 0 0 0 0 0 0 0 -9.1768 -4.3997 -15.1586 Cl 0 0 0 0 0 0 0 0 0 0 0 0 -7.7148 -7.1180 -15.0457 C 0 0 0 0 0 0 0 0 0 0 0 0 -8.1389 -7.1991 -13.8934 O 0 0 0 0 0 0 0 0 0 0 0 0 -7.9049 -8.0287 -16.0180 N 0 0 0 0 0 0 0 0 0 0 0 0 -7.4294 -7.8335 -16.8865 H 0 0 0 0 0 0 0 0 0 0 0 0 -8.7326 -9.1839 -16.0340 C 0 0 0 0 0 0 0 0 0 0 0 0 -9.5767 -9.5845 -14.9768 C 0 0 0 0 0 0 0 0 0 0 0 0 -10.3787 -10.7211 -15.1617 C 0 0 0 0 0 0 0 0 0 0 0 0 -10.3684 -11.4682 -16.2855 N 0 0 0 0 0 0 0 0 0 0 0 0 -9.5511 -11.1143 -17.3033 C 0 0 0 0 0 0 0 0 0 0 0 0 -8.7345 -9.9579 -17.2108 C 0 0 0 0 0 0 0 0 0 0 0 0 -8.1156 -9.6410 -18.0354 H 0 0 0 0 0 0 0 0 0 0 0 0 -9.5769 -11.9102 -18.4820 N 0 0 0 0 0 0 0 0 0 0 0 0 -10.4125 -12.4719 -18.5849 H 0 0 0 0 0 0 0 0 0 0 0 0 -8.6418 -12.0583 -19.4429 C 0 0 0 0 0 0 0 0 0 0 0 0 -7.5768 -11.4445 -19.4773 O 0 0 0 0 0 0 0 0 0 0 0 0 -9.0300 -13.0424 -20.5007 C 0 0 2 0 0 0 0 0 0 0 0 0 -7.9790 -13.8599 -21.2474 C 0 0 1 0 0 0 0 0 0 0 0 0 -8.6725 -12.7173 -21.9374 C 0 0 0 0 0 0 0 0 0 0 0 0 -8.0920 -11.8168 -22.1314 H 0 0 0 0 0 0 0 0 0 0 0 0 -9.4254 -12.9488 -22.6885 H 0 0 0 0 0 0 0 0 0 0 0 0 -8.2615 -14.8677 -21.5420 H 0 0 0 0 0 0 0 0 0 0 0 0 -6.2468 -13.7466 -21.0219 Cl 0 0 0 0 0 0 0 0 0 0 0 0 -9.9956 -13.5261 -20.3580 H 0 0 0 0 0 0 0 0 0 0 0 0 -11.0483 -11.0477 -14.3796 H 0 0 0 0 0 0 0 0 0 0 0 0 -9.6507 -9.0421 -14.0475 H 0 0 0 0 0 0 0 0 0 0 0 0 -4.7400 -7.5863 -15.8220 Cl 0 0 0 0 0 0 0 0 0 0 0 0 -3.7318 -5.0262 -16.4169 H 0 0 0 0 0 0 0 0 0 0 0 0 1 2 1 0 2 7 2 0 2 3 1 0 3 4 2 0 3 36 1 0 4 5 1 0 4 35 1 0 5 6 2 0 5 10 1 0 6 7 1 0 6 9 1 0 7 8 1 0 10 11 2 0 10 12 1 0 12 13 1 0 12 14 1 0 14 19 1 0 14 15 2 0 15 16 1 0 15 34 1 0 16 17 2 0 16 33 1 0 17 18 1 0 18 19 2 0 18 21 1 0 19 20 1 0 21 22 1 0 21 23 1 0 23 24 2 0 23 25 1 0 25 27 1 0 25 26 1 0 25 32 1 6 26 27 1 0 26 30 1 6 26 31 1 0 27 28 1 0 27 29 1 0 M END > lig_jmc_27 > 0.14802777777777779 -0.095972222222222223 -0.12897222222222221 0.052427777777777781 -0.14357222222222221 0.052427777777777781 -0.12897222222222221 0.15702777777777779 -0.060372222222222223 0.69172777777777772 -0.5500722222222223 -0.46107222222222222 0.33052777777777781 0.12662777777777778 -0.30227222222222222 0.44422777777777778 -0.73097222222222225 0.54822777777777776 -0.31927222222222218 0.17702777777777778 -0.53937222222222225 0.33852777777777782 0.70012777777777768 -0.58207222222222221 -0.21167222222222221 -0.024272222222222219 -0.092372222222222217 0.095727777777777773 0.095727777777777773 0.10972777777777779 -0.11737222222222223 0.11472777777777778 0.026127777777777781 0.18302777777777779 -0.060372222222222223 0.15702777777777779 $$$$ lig_jmc_28 RDKit 3D 39 41 0 0 0 0 0 0 0 0999 V2000 -4.7734 -2.7882 -16.4516 H 0 0 0 0 0 0 0 0 0 0 0 0 -5.3693 -3.6534 -16.1928 C 0 0 0 0 0 0 0 0 0 0 0 0 -4.7771 -4.9295 -16.1748 C 0 0 0 0 0 0 0 0 0 0 0 0 -5.5384 -6.0580 -15.8222 C 0 0 0 0 0 0 0 0 0 0 0 0 -6.9079 -5.9170 -15.4723 C 0 0 0 0 0 0 0 0 0 0 0 0 -7.5021 -4.6266 -15.5098 C 0 0 0 0 0 0 0 0 0 0 0 0 -6.7258 -3.5070 -15.8679 C 0 0 0 0 0 0 0 0 0 0 0 0 -7.1773 -2.5281 -15.8986 H 0 0 0 0 0 0 0 0 0 0 0 0 -9.1766 -4.3876 -15.1626 Cl 0 0 0 0 0 0 0 0 0 0 0 0 -7.7200 -7.1066 -15.0434 C 0 0 0 0 0 0 0 0 0 0 0 0 -8.1390 -7.1894 -13.8908 O 0 0 0 0 0 0 0 0 0 0 0 0 -7.9167 -8.0154 -16.0156 N 0 0 0 0 0 0 0 0 0 0 0 0 -7.4475 -7.8102 -16.8862 H 0 0 0 0 0 0 0 0 0 0 0 0 -8.7431 -9.1695 -16.0273 C 0 0 0 0 0 0 0 0 0 0 0 0 -9.5769 -9.5853 -14.9643 C 0 0 0 0 0 0 0 0 0 0 0 0 -10.3771 -10.7245 -15.1583 C 0 0 0 0 0 0 0 0 0 0 0 0 -10.3740 -11.4620 -16.2885 N 0 0 0 0 0 0 0 0 0 0 0 0 -9.5582 -11.0924 -17.3052 C 0 0 0 0 0 0 0 0 0 0 0 0 -8.7548 -9.9313 -17.2084 C 0 0 0 0 0 0 0 0 0 0 0 0 -8.1464 -9.5935 -18.0346 H 0 0 0 0 0 0 0 0 0 0 0 0 -9.5735 -11.8790 -18.4906 N 0 0 0 0 0 0 0 0 0 0 0 0 -10.4150 -12.4196 -18.6299 H 0 0 0 0 0 0 0 0 0 0 0 0 -8.6246 -12.0098 -19.4382 C 0 0 0 0 0 0 0 0 0 0 0 0 -7.5447 -11.4192 -19.4291 O 0 0 0 0 0 0 0 0 0 0 0 0 -9.0144 -12.9414 -20.5374 C 0 0 2 0 0 0 0 0 0 0 0 0 -7.9968 -13.8618 -21.2117 C 0 0 1 0 0 0 0 0 0 0 0 0 -8.4999 -12.6404 -21.9316 C 0 0 0 0 0 0 0 0 0 0 0 0 -7.8110 -11.8050 -22.0554 H 0 0 0 0 0 0 0 0 0 0 0 0 -9.1848 -12.7929 -22.7629 H 0 0 0 0 0 0 0 0 0 0 0 0 -8.4286 -14.8054 -21.5270 H 0 0 0 0 0 0 0 0 0 0 0 0 -6.5243 -14.0038 -20.8986 C 0 0 0 0 0 0 0 0 0 0 0 0 -6.0378 -13.0412 -20.7510 H 0 0 0 0 0 0 0 0 0 0 0 0 -6.0098 -14.5270 -21.7113 H 0 0 0 0 0 0 0 0 0 0 0 0 -6.4164 -14.5984 -19.9932 H 0 0 0 0 0 0 0 0 0 0 0 0 -10.0347 -13.3181 -20.4861 H 0 0 0 0 0 0 0 0 0 0 0 0 -11.0392 -11.0690 -14.3787 H 0 0 0 0 0 0 0 0 0 0 0 0 -9.6406 -9.0508 -14.0279 H 0 0 0 0 0 0 0 0 0 0 0 0 -4.7554 -7.5923 -15.8220 Cl 0 0 0 0 0 0 0 0 0 0 0 0 -3.7300 -5.0400 -16.4263 H 0 0 0 0 0 0 0 0 0 0 0 0 1 2 1 0 2 7 2 0 2 3 1 0 3 4 2 0 3 39 1 0 4 5 1 0 4 38 1 0 5 6 2 0 5 10 1 0 6 7 1 0 6 9 1 0 7 8 1 0 10 11 2 0 10 12 1 0 12 13 1 0 12 14 1 0 14 19 1 0 14 15 2 0 15 16 1 0 15 37 1 0 16 17 2 0 16 36 1 0 17 18 1 0 18 19 2 0 18 21 1 0 19 20 1 0 21 22 1 0 21 23 1 0 23 24 2 0 23 25 1 0 25 27 1 0 25 26 1 0 25 35 1 6 26 27 1 0 26 30 1 6 26 31 1 0 27 28 1 0 27 29 1 0 31 32 1 0 31 33 1 0 31 34 1 0 M END > lig_jmc_28 > 0.14807692307692308 -0.095923076923076916 -0.12892307692307692 0.051976923076923087 -0.14352307692307692 0.051976923076923087 -0.12892307692307692 0.15707692307692309 -0.059823076923076916 0.69177692307692307 -0.55002307692307695 -0.46002307692307692 0.3305769230769231 0.12667692307692308 -0.30322307692307693 0.44427692307692307 -0.7359230769230769 0.54927692307692311 -0.31922307692307689 0.17807692307692308 -0.54732307692307691 0.3325769230769231 0.70317692307692303 -0.59502307692307688 -0.2286230769230769 -0.089623076923076916 -0.099323076923076917 0.087276923076923085 0.087276923076923085 0.08177692307692308 -0.084023076923076909 0.048776923076923086 0.048776923076923086 0.048776923076923086 0.09677692307692308 0.025176923076923083 0.18207692307692308 -0.059823076923076916 0.15707692307692309 $$$$ ================================================ FILE: src/openfecli/tests/data/rbfe_tutorial/tyk2_protein.pdb ================================================ HEADER TRANSFERASE/TRANSFERASE INHIBITOR 08-AUG-12 4GIH TITLE TYK2 (JH1) IN COMPLEX WITH TITLE 2 2,6-DICHLORO-N-{2-[(CYCLOPROPYLCARBONYL) TITLE 3 AMINO]PYRIDIN-4-YL}BENZAMIDE EXPDTA X-RAY DIFFRACTION REMARK 2 RESOLUTION. 2.00 ANGSTROMS REMARK 3 R VALUE : 0.188000 REMARK 3 FREE R VALUE : 0.217000 REMARK 4 4GIH COMPLIES WITH FORMAT V. 3.30, REMARK 200 TEMPERATURE (KELVIN) : 173.00 REMARK 200 PH : 6.50 REMARK 350 BIOMOLECULE: 1 REMARK 350 APPLY THE FOLLOWING TO CHAINS: A REMARK 350 BIOMT1 1 1.000000 0.000000 0.000000 0.000000 REMARK 350 BIOMT2 1 0.000000 1.000000 0.000000 0.000000 REMARK 350 BIOMT3 1 0.000000 0.000000 1.000000 0.000000 REMARK 888 REMARK 888 WRITTEN BY MAESTRO (A PRODUCT OF SCHRODINGER, LLC) SEQRES 1 A 290 ACE THR VAL PHE HIS LYS ARG TYR LEU LYS LYS ILE ARG SEQRES 2 A 290 ASP LEU GLY GLU GLY HIS PHE GLY LYS VAL SER LEU TYR SEQRES 3 A 290 CYS TYR ASP PRO THR ASN ASP GLY THR GLY GLU MET VAL SEQRES 4 A 290 ALA VAL LYS ALA LEU LYS ALA ASP ALA GLY PRO GLN HIS SEQRES 5 A 290 ARG SER GLY TRP LYS GLN GLU ILE ASP ILE LEU ARG THR SEQRES 6 A 290 LEU TYR HIS GLU HIS ILE ILE LYS TYR LYS GLY CYS CYS SEQRES 7 A 290 GLU ASP ALA GLY ALA ALA SER LEU GLN LEU VAL MET GLU SEQRES 8 A 290 TYR VAL PRO LEU GLY SER LEU ARG ASP TYR LEU PRO ARG SEQRES 9 A 290 HIS SER ILE GLY LEU ALA GLN LEU LEU LEU PHE ALA GLN SEQRES 10 A 290 GLN ILE CYS GLU GLY MET ALA TYR LEU HIS ALA GLN HIS SEQRES 11 A 290 TYR ILE HIS ARG ASN LEU ALA ALA ARG ASN VAL LEU LEU SEQRES 12 A 290 ASP ASN ASP ARG LEU VAL LYS ILE GLY ASP PHE GLY LEU SEQRES 13 A 290 ALA LYS ALA VAL PRO GLU GLY HIS GLU TYR TYR ARG VAL SEQRES 14 A 290 ARG GLU ASP GLY ASP SER PRO VAL PHE TRP TYR ALA PRO SEQRES 15 A 290 GLU CYS LEU LYS GLU TYR LYS PHE TYR TYR ALA SER ASP SEQRES 16 A 290 VAL TRP SER PHE GLY VAL THR LEU TYR GLU LEU LEU THR SEQRES 17 A 290 HIS CYS ASP SER SER GLN SER PRO PRO THR LYS PHE LEU SEQRES 18 A 290 GLU LEU ILE GLY ILE ALA GLN GLY GLN MET THR VAL LEU SEQRES 19 A 290 ARG LEU THR GLU LEU LEU GLU ARG GLY GLU ARG LEU PRO SEQRES 20 A 290 ARG PRO ASP LYS CYS PRO ALA GLU VAL TYR HIS LEU MET SEQRES 21 A 290 LYS ASN CYS TRP GLU THR GLU ALA SER PHE ARG PRO THR SEQRES 22 A 290 PHE GLU ASN LEU ILE PRO ILE LEU LYS THR VAL HIS GLU SEQRES 23 A 290 LYS TYR ARG NME FORMUL 2 HOH *46(H2 0) HELIX 1 1 HIS A 940 HIS A 940 1 HELIX 2 2 ARG A 941 ARG A 941 1 HELIX 3 3 SER A 942 SER A 942 1 HELIX 4 4 GLY A 943 GLY A 943 1 HELIX 5 5 TRP A 944 TRP A 944 1 HELIX 6 6 LYS A 945 LYS A 945 1 HELIX 7 7 GLN A 946 GLN A 946 1 HELIX 8 8 GLU A 947 GLU A 947 1 HELIX 9 9 ILE A 948 ILE A 948 1 HELIX 10 10 ASP A 949 ASP A 949 1 HELIX 11 11 ILE A 950 ILE A 950 1 HELIX 12 12 LEU A 951 LEU A 951 1 HELIX 13 13 ARG A 952 ARG A 952 1 HELIX 14 14 THR A 953 THR A 953 1 HELIX 15 15 LEU A 986 LEU A 986 1 HELIX 16 16 ARG A 987 ARG A 987 1 HELIX 17 17 ASP A 988 ASP A 988 1 HELIX 18 18 TYR A 989 TYR A 989 1 HELIX 19 19 LEU A 997 LEU A 997 1 HELIX 20 20 ALA A 998 ALA A 998 1 HELIX 21 21 GLN A 999 GLN A 999 1 HELIX 22 22 LEU A 1000 LEU A 1000 1 HELIX 23 23 LEU A 1001 LEU A 1001 1 HELIX 24 24 LEU A 1002 LEU A 1002 1 HELIX 25 25 PHE A 1003 PHE A 1003 1 HELIX 26 26 ALA A 1004 ALA A 1004 1 HELIX 27 27 GLN A 1005 GLN A 1005 1 HELIX 28 28 GLN A 1006 GLN A 1006 1 HELIX 29 29 ILE A 1007 ILE A 1007 1 HELIX 30 30 CYS A 1008 CYS A 1008 1 HELIX 31 31 GLU A 1009 GLU A 1009 1 HELIX 32 32 GLY A 1010 GLY A 1010 1 HELIX 33 33 MET A 1011 MET A 1011 1 HELIX 34 34 ALA A 1012 ALA A 1012 1 HELIX 35 35 TYR A 1013 TYR A 1013 1 HELIX 36 36 LEU A 1014 LEU A 1014 1 HELIX 37 37 HIS A 1015 HIS A 1015 1 HELIX 38 38 ALA A 1016 ALA A 1016 1 HELIX 39 39 TYR A 1080 TYR A 1080 1 HELIX 40 40 ALA A 1081 ALA A 1081 1 HELIX 41 41 SER A 1082 SER A 1082 1 HELIX 42 42 ASP A 1083 ASP A 1083 1 HELIX 43 43 VAL A 1084 VAL A 1084 1 HELIX 44 44 TRP A 1085 TRP A 1085 1 HELIX 45 45 SER A 1086 SER A 1086 1 HELIX 46 46 PHE A 1087 PHE A 1087 1 HELIX 47 47 GLY A 1088 GLY A 1088 1 HELIX 48 48 VAL A 1089 VAL A 1089 1 HELIX 49 49 THR A 1090 THR A 1090 1 HELIX 50 50 LEU A 1091 LEU A 1091 1 HELIX 51 51 TYR A 1092 TYR A 1092 1 HELIX 52 52 GLU A 1093 GLU A 1093 1 HELIX 53 53 LEU A 1094 LEU A 1094 1 HELIX 54 54 LEU A 1095 LEU A 1095 1 HELIX 55 55 LYS A 1107 LYS A 1107 1 HELIX 56 56 PHE A 1108 PHE A 1108 1 HELIX 57 57 LEU A 1109 LEU A 1109 1 HELIX 58 58 GLU A 1110 GLU A 1110 1 HELIX 59 59 LEU A 1111 LEU A 1111 1 HELIX 60 60 ILE A 1112 ILE A 1112 1 HELIX 61 61 THR A 1120 THR A 1120 1 HELIX 62 62 VAL A 1121 VAL A 1121 1 HELIX 63 63 LEU A 1122 LEU A 1122 1 HELIX 64 64 ARG A 1123 ARG A 1123 1 HELIX 65 65 LEU A 1124 LEU A 1124 1 HELIX 66 66 THR A 1125 THR A 1125 1 HELIX 67 67 GLU A 1126 GLU A 1126 1 HELIX 68 68 LEU A 1127 LEU A 1127 1 HELIX 69 69 LEU A 1128 LEU A 1128 1 HELIX 70 70 GLU A 1129 GLU A 1129 1 HELIX 71 71 GLU A 1143 GLU A 1143 1 HELIX 72 72 VAL A 1144 VAL A 1144 1 HELIX 73 73 TYR A 1145 TYR A 1145 1 HELIX 74 74 HIS A 1146 HIS A 1146 1 HELIX 75 75 LEU A 1147 LEU A 1147 1 HELIX 76 76 MET A 1148 MET A 1148 1 HELIX 77 77 LYS A 1149 LYS A 1149 1 HELIX 78 78 ASN A 1150 ASN A 1150 1 HELIX 79 79 CYS A 1151 CYS A 1151 1 HELIX 80 80 PHE A 1162 PHE A 1162 1 HELIX 81 81 GLU A 1163 GLU A 1163 1 HELIX 82 82 ASN A 1164 ASN A 1164 1 HELIX 83 83 LEU A 1165 LEU A 1165 1 HELIX 84 84 ILE A 1166 ILE A 1166 1 HELIX 85 85 PRO A 1167 PRO A 1167 1 HELIX 86 86 ILE A 1168 ILE A 1168 1 HELIX 87 87 LEU A 1169 LEU A 1169 1 HELIX 88 88 LYS A 1170 LYS A 1170 1 HELIX 89 89 THR A 1171 THR A 1171 1 HELIX 90 90 VAL A 1172 VAL A 1172 1 HELIX 91 91 HIS A 1173 HIS A 1173 1 HELIX 92 92 GLU A 1174 GLU A 1174 1 HELIX 93 93 LYS A 1175 LYS A 1175 1 HELIX 94 94 TYR A 1176 TYR A 1176 1 TURN 1 1 THR A 890 THR A 890 TURN 2 2 VAL A 891 VAL A 891 TURN 3 3 HIS A 893 HIS A 893 TURN 4 4 LYS A 894 LYS A 894 TURN 5 5 ARG A 895 ARG A 895 TURN 6 6 TYR A 896 TYR A 896 TURN 7 7 GLY A 906 GLY A 906 TURN 8 8 HIS A 907 HIS A 907 TURN 9 9 PHE A 908 PHE A 908 TURN 10 10 GLY A 909 GLY A 909 TURN 11 11 ASP A 917 ASP A 917 TURN 12 12 PRO A 918 PRO A 918 TURN 13 13 THR A 919 THR A 919 TURN 14 14 ASN A 920 ASN A 920 TURN 15 15 ASP A 921 ASP A 921 TURN 16 16 GLY A 922 GLY A 922 TURN 17 17 THR A 923 THR A 923 TURN 18 18 GLY A 924 GLY A 924 TURN 19 19 ALA A 931 ALA A 931 TURN 20 20 LEU A 932 LEU A 932 TURN 21 21 LYS A 933 LYS A 933 TURN 22 22 ALA A 934 ALA A 934 TURN 23 23 ASP A 935 ASP A 935 TURN 24 24 ALA A 936 ALA A 936 TURN 25 25 GLY A 937 GLY A 937 TURN 26 26 PRO A 938 PRO A 938 TURN 27 27 GLN A 939 GLN A 939 TURN 28 28 LEU A 954 LEU A 954 TURN 29 29 TYR A 955 TYR A 955 TURN 30 30 HIS A 956 HIS A 956 TURN 31 31 GLU A 957 GLU A 957 TURN 32 32 HIS A 958 HIS A 958 TURN 33 33 ILE A 959 ILE A 959 TURN 34 34 ILE A 960 ILE A 960 TURN 35 35 LYS A 961 LYS A 961 TURN 36 36 ALA A 969 ALA A 969 TURN 37 37 GLY A 970 GLY A 970 TURN 38 38 ALA A 971 ALA A 971 TURN 39 39 ALA A 972 ALA A 972 TURN 40 40 TYR A 980 TYR A 980 TURN 41 41 VAL A 981 VAL A 981 TURN 42 42 PRO A 982 PRO A 982 TURN 43 43 LEU A 983 LEU A 983 TURN 44 44 LEU A 990 LEU A 990 TURN 45 45 PRO A 991 PRO A 991 TURN 46 46 ARG A 992 ARG A 992 TURN 47 47 HIS A 993 HIS A 993 TURN 48 48 SER A 994 SER A 994 TURN 49 49 ILE A 995 ILE A 995 TURN 50 50 GLY A 996 GLY A 996 TURN 51 51 GLN A1017 GLN A1017 TURN 52 52 HIS A1018 HIS A1018 TURN 53 53 HIS A1021 HIS A1021 TURN 54 54 ARG A1022 ARG A1022 TURN 55 55 ASN A1023 ASN A1023 TURN 56 56 LEU A1024 LEU A1024 TURN 57 57 ALA A1025 ALA A1025 TURN 58 58 ALA A1026 ALA A1026 TURN 59 59 ARG A1027 ARG A1027 TURN 60 60 ASN A1028 ASN A1028 TURN 61 61 ASP A1034 ASP A1034 TURN 62 62 ARG A1035 ARG A1035 TURN 63 63 GLY A1040 GLY A1040 TURN 64 64 ASP A1041 ASP A1041 TURN 65 65 PHE A1042 PHE A1042 TURN 66 66 GLY A1043 GLY A1043 TURN 67 67 LEU A1044 LEU A1044 TURN 68 68 ALA A1045 ALA A1045 TURN 69 69 VAL A1048 VAL A1048 TURN 70 70 PRO A1049 PRO A1049 TURN 71 71 GLU A1050 GLU A1050 TURN 72 72 GLY A1051 GLY A1051 TURN 73 73 HIS A1052 HIS A1052 TURN 74 74 GLU A1053 GLU A1053 TURN 75 75 VAL A1057 VAL A1057 TURN 76 76 ARG A1058 ARG A1058 TURN 77 77 GLU A1059 GLU A1059 TURN 78 78 ASP A1060 ASP A1060 TURN 79 79 GLY A1061 GLY A1061 TURN 80 80 ASP A1062 ASP A1062 TURN 81 81 SER A1063 SER A1063 TURN 82 82 PRO A1064 PRO A1064 TURN 83 83 VAL A1065 VAL A1065 TURN 84 84 PHE A1066 PHE A1066 TURN 85 85 TRP A1067 TRP A1067 TURN 86 86 TYR A1068 TYR A1068 TURN 87 87 ALA A1069 ALA A1069 TURN 88 88 PRO A1070 PRO A1070 TURN 89 89 GLU A1071 GLU A1071 TURN 90 90 CYS A1072 CYS A1072 TURN 91 91 LEU A1073 LEU A1073 TURN 92 92 LYS A1074 LYS A1074 TURN 93 93 GLU A1075 GLU A1075 TURN 94 94 TYR A1076 TYR A1076 TURN 95 95 THR A1096 THR A1096 TURN 96 96 HIS A1097 HIS A1097 TURN 97 97 CYS A1098 CYS A1098 TURN 98 98 ASP A1099 ASP A1099 TURN 99 99 SER A1100 SER A1100 TURN 100 100 SER A1101 SER A1101 TURN 101 101 GLN A1102 GLN A1102 TURN 102 102 SER A1103 SER A1103 TURN 103 103 PRO A1104 PRO A1104 TURN 104 104 PRO A1105 PRO A1105 TURN 105 105 THR A1106 THR A1106 TURN 106 106 GLY A1113 GLY A1113 TURN 107 107 ILE A1114 ILE A1114 TURN 108 108 ALA A1115 ALA A1115 TURN 109 109 GLN A1116 GLN A1116 TURN 110 110 GLY A1117 GLY A1117 TURN 111 111 GLN A1118 GLN A1118 TURN 112 112 MET A1119 MET A1119 TURN 113 113 ARG A1130 ARG A1130 TURN 114 114 GLY A1131 GLY A1131 TURN 115 115 GLU A1132 GLU A1132 TURN 116 116 ARG A1133 ARG A1133 TURN 117 117 LEU A1134 LEU A1134 TURN 118 118 PRO A1135 PRO A1135 TURN 119 119 ARG A1136 ARG A1136 TURN 120 120 PRO A1137 PRO A1137 TURN 121 121 ASP A1138 ASP A1138 TURN 122 122 LYS A1139 LYS A1139 TURN 123 123 CYS A1140 CYS A1140 TURN 124 124 PRO A1141 PRO A1141 TURN 125 125 ALA A1142 ALA A1142 TURN 126 126 TRP A1152 TRP A1152 TURN 127 127 GLU A1153 GLU A1153 TURN 128 128 THR A1154 THR A1154 TURN 129 129 GLU A1155 GLU A1155 TURN 130 130 ALA A1156 ALA A1156 TURN 131 131 SER A1157 SER A1157 TURN 132 132 PHE A1158 PHE A1158 TURN 133 133 ARG A1159 ARG A1159 TURN 134 134 PRO A1160 PRO A1160 TURN 135 135 THR A1161 THR A1161 TURN 136 136 ARG A1177 ARG A1177 SHEET 1 1 1 PHE A 892 PHE A 892 0 SHEET 1 2 1 LEU A 897 LEU A 897 0 SHEET 1 3 1 LYS A 898 LYS A 898 0 SHEET 1 4 1 LYS A 899 LYS A 899 0 SHEET 1 5 1 ILE A 900 ILE A 900 0 SHEET 1 6 1 ARG A 901 ARG A 901 0 SHEET 1 7 1 ASP A 902 ASP A 902 0 SHEET 1 8 1 LEU A 903 LEU A 903 0 SHEET 1 9 1 GLY A 904 GLY A 904 0 SHEET 1 10 1 GLU A 905 GLU A 905 0 SHEET 1 11 1 LYS A 910 LYS A 910 0 SHEET 1 12 1 VAL A 911 VAL A 911 0 SHEET 1 13 1 SER A 912 SER A 912 0 SHEET 1 14 1 LEU A 913 LEU A 913 0 SHEET 1 15 1 TYR A 914 TYR A 914 0 SHEET 1 16 1 CYS A 915 CYS A 915 0 SHEET 1 17 1 TYR A 916 TYR A 916 0 SHEET 1 18 1 GLU A 925 GLU A 925 0 SHEET 1 19 1 MET A 926 MET A 926 0 SHEET 1 20 1 VAL A 927 VAL A 927 0 SHEET 1 21 1 ALA A 928 ALA A 928 0 SHEET 1 22 1 VAL A 929 VAL A 929 0 SHEET 1 23 1 LYS A 930 LYS A 930 0 SHEET 1 24 1 TYR A 962 TYR A 962 0 SHEET 1 25 1 LYS A 963 LYS A 963 0 SHEET 1 26 1 GLY A 964 GLY A 964 0 SHEET 1 27 1 CYS A 965 CYS A 965 0 SHEET 1 28 1 CYS A 966 CYS A 966 0 SHEET 1 29 1 GLU A 967 GLU A 967 0 SHEET 1 30 1 ASP A 968 ASP A 968 0 SHEET 1 31 1 SER A 973 SER A 973 0 SHEET 1 32 1 LEU A 974 LEU A 974 0 SHEET 1 33 1 GLN A 975 GLN A 975 0 SHEET 1 34 1 LEU A 976 LEU A 976 0 SHEET 1 35 1 VAL A 977 VAL A 977 0 SHEET 1 36 1 MET A 978 MET A 978 0 SHEET 1 37 1 GLU A 979 GLU A 979 0 SHEET 1 38 1 GLY A 984 GLY A 984 0 SHEET 1 39 1 SER A 985 SER A 985 0 SHEET 1 40 1 TYR A1019 TYR A1019 0 SHEET 1 41 1 ILE A1020 ILE A1020 0 SHEET 1 42 1 VAL A1029 VAL A1029 0 SHEET 1 43 1 LEU A1030 LEU A1030 0 SHEET 1 44 1 LEU A1031 LEU A1031 0 SHEET 1 45 1 ASP A1032 ASP A1032 0 SHEET 1 46 1 ASN A1033 ASN A1033 0 SHEET 1 47 1 LEU A1036 LEU A1036 0 SHEET 1 48 1 VAL A1037 VAL A1037 0 SHEET 1 49 1 LYS A1038 LYS A1038 0 SHEET 1 50 1 ILE A1039 ILE A1039 0 SHEET 1 51 1 LYS A1046 LYS A1046 0 SHEET 1 52 1 ALA A1047 ALA A1047 0 SHEET 1 53 1 TYR A1054 TYR A1054 0 SHEET 1 54 1 TYR A1055 TYR A1055 0 SHEET 1 55 1 ARG A1056 ARG A1056 0 SHEET 1 56 1 LYS A1077 LYS A1077 0 SHEET 1 57 1 PHE A1078 PHE A1078 0 SHEET 1 58 1 TYR A1079 TYR A1079 0 CRYST1 36.165 74.378 105.855 90.00 90.00 90.00 P 21 21 21 4 HETATM 1 CH3 ACE A 889 -15.732 -12.864 4.220 1.00 0.00 C HETATM 2 C ACE A 889 -15.275 -14.196 3.637 1.00 0.00 C HETATM 3 O ACE A 889 -14.652 -14.991 4.340 1.00 0.00 O HETATM 4 H1 ACE A 889 -16.002 -12.982 5.270 1.00 0.00 H HETATM 5 H2 ACE A 889 -14.929 -12.130 4.152 1.00 0.00 H HETATM 6 H3 ACE A 889 -16.601 -12.476 3.688 1.00 0.00 H ATOM 7 N THR A 890 -15.598 -14.429 2.353 1.00 62.43 N ATOM 8 CA THR A 890 -15.253 -15.636 1.596 1.00 60.76 C ATOM 9 C THR A 890 -13.728 -15.808 1.437 1.00 61.63 C ATOM 10 O THR A 890 -13.057 -14.865 1.010 1.00 59.62 O ATOM 11 CB THR A 890 -15.878 -15.600 0.175 1.00 68.55 C ATOM 12 OG1 THR A 890 -17.275 -15.404 0.279 1.00 68.98 O ATOM 13 CG2 THR A 890 -15.641 -16.864 -0.673 1.00 67.10 C ATOM 14 H THR A 890 -16.131 -13.741 1.843 1.00 62.43 H ATOM 15 HA THR A 890 -15.657 -16.495 2.138 1.00 60.76 H ATOM 16 HB THR A 890 -15.486 -14.740 -0.370 1.00 68.55 H ATOM 17 HG1 THR A 890 -17.660 -15.485 -0.597 1.00 68.98 H ATOM 18 HG21 THR A 890 -16.174 -16.811 -1.622 1.00 67.10 H ATOM 19 HG22 THR A 890 -14.586 -17.003 -0.909 1.00 67.10 H ATOM 20 HG23 THR A 890 -15.983 -17.757 -0.151 1.00 67.10 H ATOM 21 N VAL A 891 -13.227 -17.004 1.789 1.00 57.37 N ATOM 22 CA VAL A 891 -11.803 -17.336 1.789 1.00 55.39 C ATOM 23 C VAL A 891 -11.483 -18.439 0.760 1.00 56.21 C ATOM 24 O VAL A 891 -12.250 -19.389 0.602 1.00 57.24 O ATOM 25 CB VAL A 891 -11.320 -17.758 3.209 1.00 60.85 C ATOM 26 CG1 VAL A 891 -11.950 -19.060 3.745 1.00 62.96 C ATOM 27 CG2 VAL A 891 -9.784 -17.834 3.316 1.00 59.88 C ATOM 28 H VAL A 891 -13.847 -17.732 2.112 1.00 57.37 H ATOM 29 HA VAL A 891 -11.234 -16.448 1.521 1.00 55.39 H ATOM 30 HB VAL A 891 -11.634 -16.961 3.885 1.00 60.85 H ATOM 31 HG11 VAL A 891 -11.669 -19.225 4.785 1.00 62.96 H ATOM 32 HG12 VAL A 891 -13.039 -19.021 3.707 1.00 62.96 H ATOM 33 HG13 VAL A 891 -11.625 -19.935 3.183 1.00 62.96 H ATOM 34 HG21 VAL A 891 -9.472 -17.993 4.349 1.00 59.88 H ATOM 35 HG22 VAL A 891 -9.371 -18.651 2.725 1.00 59.88 H ATOM 36 HG23 VAL A 891 -9.317 -16.908 2.976 1.00 59.88 H ATOM 37 N PHE A 892 -10.332 -18.268 0.093 1.00 49.19 N ATOM 38 CA PHE A 892 -9.736 -19.179 -0.880 1.00 47.07 C ATOM 39 C PHE A 892 -8.379 -19.653 -0.337 1.00 52.74 C ATOM 40 O PHE A 892 -7.608 -18.826 0.150 1.00 53.11 O ATOM 41 CB PHE A 892 -9.546 -18.424 -2.216 1.00 45.10 C ATOM 42 CG PHE A 892 -10.806 -18.200 -3.035 1.00 44.18 C ATOM 43 CD1 PHE A 892 -11.099 -19.048 -4.122 1.00 44.87 C ATOM 44 CD2 PHE A 892 -11.756 -17.229 -2.654 1.00 45.07 C ATOM 45 CE1 PHE A 892 -12.289 -18.908 -4.823 1.00 45.27 C ATOM 46 CE2 PHE A 892 -12.944 -17.110 -3.362 1.00 46.87 C ATOM 47 CZ PHE A 892 -13.211 -17.944 -4.440 1.00 44.38 C ATOM 48 H PHE A 892 -9.787 -17.438 0.287 1.00 49.19 H ATOM 49 HA PHE A 892 -10.371 -20.052 -1.044 1.00 47.07 H ATOM 50 HB3 PHE A 892 -8.819 -18.942 -2.845 1.00 45.10 H ATOM 51 HB2 PHE A 892 -9.116 -17.444 -2.011 1.00 45.10 H ATOM 52 HD1 PHE A 892 -10.391 -19.801 -4.420 1.00 44.87 H ATOM 53 HD2 PHE A 892 -11.569 -16.581 -1.809 1.00 45.07 H ATOM 54 HE1 PHE A 892 -12.501 -19.556 -5.660 1.00 45.27 H ATOM 55 HE2 PHE A 892 -13.672 -16.374 -3.064 1.00 46.87 H ATOM 56 HZ PHE A 892 -14.142 -17.847 -4.977 1.00 44.38 H ATOM 57 N HIS A 893 -8.096 -20.961 -0.436 1.00 50.80 N ATOM 58 CA HIS A 893 -6.829 -21.549 0.015 1.00 51.86 C ATOM 59 C HIS A 893 -5.854 -21.664 -1.167 1.00 53.50 C ATOM 60 O HIS A 893 -6.229 -22.208 -2.207 1.00 52.26 O ATOM 61 CB HIS A 893 -7.080 -22.921 0.672 1.00 55.68 C ATOM 62 CG HIS A 893 -8.193 -22.954 1.691 1.00 61.81 C ATOM 63 ND1 HIS A 893 -9.452 -23.496 1.413 1.00 65.50 N ATOM 64 CD2 HIS A 893 -8.184 -22.495 2.993 1.00 65.19 C ATOM 65 CE1 HIS A 893 -10.148 -23.333 2.531 1.00 67.02 C ATOM 66 NE2 HIS A 893 -9.446 -22.747 3.501 1.00 67.16 N ATOM 67 H HIS A 893 -8.769 -21.596 -0.844 1.00 50.80 H ATOM 68 HA HIS A 893 -6.383 -20.908 0.779 1.00 51.86 H ATOM 69 HB3 HIS A 893 -6.171 -23.242 1.179 1.00 55.68 H ATOM 70 HB2 HIS A 893 -7.292 -23.675 -0.087 1.00 55.68 H ATOM 71 HD2 HIS A 893 -7.410 -22.016 3.574 1.00 65.19 H ATOM 72 HE1 HIS A 893 -11.176 -23.645 2.643 1.00 67.02 H ATOM 73 HE2 HIS A 893 -9.776 -22.523 4.430 1.00 67.16 H ATOM 74 N LYS A 894 -4.615 -21.166 -0.990 1.00 50.22 N ATOM 75 CA LYS A 894 -3.603 -21.102 -2.055 1.00 49.02 C ATOM 76 C LYS A 894 -3.093 -22.481 -2.531 1.00 53.09 C ATOM 77 O LYS A 894 -2.649 -22.591 -3.672 1.00 51.68 O ATOM 78 CB LYS A 894 -2.443 -20.167 -1.638 1.00 52.12 C ATOM 79 CG LYS A 894 -1.600 -19.701 -2.841 1.00 67.25 C ATOM 80 CD LYS A 894 -0.571 -18.609 -2.518 1.00 79.06 C ATOM 81 CE LYS A 894 0.105 -18.102 -3.806 1.00 86.18 C ATOM 82 NZ LYS A 894 1.179 -17.132 -3.537 1.00 95.28 N1+ ATOM 83 H LYS A 894 -4.367 -20.734 -0.111 1.00 50.22 H ATOM 84 HA LYS A 894 -4.096 -20.649 -2.916 1.00 49.02 H ATOM 85 HB3 LYS A 894 -1.815 -20.639 -0.881 1.00 52.12 H ATOM 86 HB2 LYS A 894 -2.857 -19.278 -1.165 1.00 52.12 H ATOM 87 HG3 LYS A 894 -2.267 -19.334 -3.621 1.00 67.25 H ATOM 88 HG2 LYS A 894 -1.071 -20.551 -3.272 1.00 67.25 H ATOM 89 HD3 LYS A 894 0.177 -19.010 -1.831 1.00 79.06 H ATOM 90 HD2 LYS A 894 -1.058 -17.783 -1.996 1.00 79.06 H ATOM 91 HE3 LYS A 894 -0.633 -17.631 -4.457 1.00 86.18 H ATOM 92 HE2 LYS A 894 0.534 -18.936 -4.361 1.00 86.18 H ATOM 93 HZ1 LYS A 894 1.906 -17.573 -2.992 1.00 95.28 H ATOM 94 HZ2 LYS A 894 1.567 -16.796 -4.406 1.00 95.28 H ATOM 95 HZ3 LYS A 894 0.818 -16.346 -3.009 1.00 95.28 H ATOM 96 N ARG A 895 -3.219 -23.513 -1.678 1.00 51.74 N ATOM 97 CA ARG A 895 -2.936 -24.922 -1.981 1.00 52.94 C ATOM 98 C ARG A 895 -3.820 -25.522 -3.099 1.00 55.31 C ATOM 99 O ARG A 895 -3.417 -26.518 -3.700 1.00 55.61 O ATOM 100 CB ARG A 895 -3.055 -25.742 -0.675 1.00 57.62 C ATOM 101 CG ARG A 895 -4.449 -25.700 -0.018 1.00 70.70 C ATOM 102 CD ARG A 895 -4.551 -26.532 1.269 1.00 85.20 C ATOM 103 NE ARG A 895 -5.826 -26.282 1.965 1.00 97.62 N ATOM 104 CZ ARG A 895 -6.474 -27.088 2.829 1.00116.87 C ATOM 105 NH1 ARG A 895 -6.007 -28.297 3.178 1.00109.22 N ATOM 106 NH2 ARG A 895 -7.629 -26.662 3.356 1.00103.80 N1+ ATOM 107 H ARG A 895 -3.593 -23.332 -0.758 1.00 51.74 H ATOM 108 HA ARG A 895 -1.902 -24.980 -2.325 1.00 52.94 H ATOM 109 HB3 ARG A 895 -2.322 -25.366 0.041 1.00 57.62 H ATOM 110 HB2 ARG A 895 -2.772 -26.779 -0.866 1.00 57.62 H ATOM 111 HG3 ARG A 895 -5.142 -26.145 -0.732 1.00 70.70 H ATOM 112 HG2 ARG A 895 -4.799 -24.681 0.135 1.00 70.70 H ATOM 113 HD3 ARG A 895 -3.681 -26.417 1.916 1.00 85.20 H ATOM 114 HD2 ARG A 895 -4.581 -27.578 0.965 1.00 85.20 H ATOM 115 HE ARG A 895 -6.255 -25.393 1.754 1.00 97.62 H ATOM 116 HH12 ARG A 895 -6.515 -28.879 3.827 1.00109.22 H ATOM 117 HH11 ARG A 895 -5.149 -28.646 2.769 1.00109.22 H ATOM 118 HH22 ARG A 895 -8.146 -27.249 3.995 1.00103.80 H ATOM 119 HH21 ARG A 895 -8.011 -25.764 3.096 1.00103.80 H ATOM 120 N TYR A 896 -4.993 -24.917 -3.353 1.00 49.98 N ATOM 121 CA TYR A 896 -5.948 -25.341 -4.378 1.00 49.28 C ATOM 122 C TYR A 896 -5.900 -24.464 -5.642 1.00 50.16 C ATOM 123 O TYR A 896 -6.491 -24.862 -6.644 1.00 48.17 O ATOM 124 CB TYR A 896 -7.364 -25.348 -3.770 1.00 51.36 C ATOM 125 CG TYR A 896 -7.587 -26.246 -2.560 1.00 55.87 C ATOM 126 CD1 TYR A 896 -6.988 -27.524 -2.475 1.00 59.63 C ATOM 127 CD2 TYR A 896 -8.449 -25.818 -1.529 1.00 57.59 C ATOM 128 CE1 TYR A 896 -7.261 -28.365 -1.380 1.00 63.33 C ATOM 129 CE2 TYR A 896 -8.717 -26.657 -0.430 1.00 61.39 C ATOM 130 CZ TYR A 896 -8.130 -27.935 -0.360 1.00 71.07 C ATOM 131 OH TYR A 896 -8.409 -28.757 0.692 1.00 74.22 O ATOM 132 H TYR A 896 -5.258 -24.104 -2.814 1.00 49.98 H ATOM 133 HA TYR A 896 -5.716 -26.351 -4.712 1.00 49.28 H ATOM 134 HB3 TYR A 896 -8.095 -25.639 -4.525 1.00 51.36 H ATOM 135 HB2 TYR A 896 -7.618 -24.330 -3.482 1.00 51.36 H ATOM 136 HD1 TYR A 896 -6.338 -27.885 -3.257 1.00 59.63 H ATOM 137 HD2 TYR A 896 -8.922 -24.848 -1.582 1.00 57.59 H ATOM 138 HE1 TYR A 896 -6.810 -29.346 -1.334 1.00 63.33 H ATOM 139 HE2 TYR A 896 -9.385 -26.322 0.350 1.00 61.39 H ATOM 140 HH TYR A 896 -7.997 -29.621 0.612 1.00 74.22 H ATOM 141 N LEU A 897 -5.197 -23.318 -5.597 1.00 46.72 N ATOM 142 CA LEU A 897 -5.001 -22.416 -6.732 1.00 44.74 C ATOM 143 C LEU A 897 -3.851 -22.919 -7.625 1.00 48.16 C ATOM 144 O LEU A 897 -2.685 -22.753 -7.264 1.00 48.59 O ATOM 145 CB LEU A 897 -4.714 -20.987 -6.202 1.00 44.20 C ATOM 146 CG LEU A 897 -5.924 -20.222 -5.622 1.00 48.88 C ATOM 147 CD1 LEU A 897 -5.488 -18.979 -4.825 1.00 51.85 C ATOM 148 CD2 LEU A 897 -6.961 -19.837 -6.697 1.00 47.58 C ATOM 149 H LEU A 897 -4.710 -23.068 -4.748 1.00 46.72 H ATOM 150 HA LEU A 897 -5.907 -22.403 -7.338 1.00 44.74 H ATOM 151 HB3 LEU A 897 -4.297 -20.372 -6.995 1.00 44.20 H ATOM 152 HB2 LEU A 897 -3.930 -21.049 -5.447 1.00 44.20 H ATOM 153 HG LEU A 897 -6.405 -20.889 -4.908 1.00 48.88 H ATOM 154 HD11 LEU A 897 -5.824 -19.067 -3.792 1.00 51.85 H ATOM 155 HD12 LEU A 897 -4.406 -18.850 -4.810 1.00 51.85 H ATOM 156 HD13 LEU A 897 -5.915 -18.056 -5.220 1.00 51.85 H ATOM 157 HD21 LEU A 897 -7.934 -19.654 -6.242 1.00 47.58 H ATOM 158 HD22 LEU A 897 -6.673 -18.927 -7.224 1.00 47.58 H ATOM 159 HD23 LEU A 897 -7.099 -20.607 -7.454 1.00 47.58 H ATOM 160 N LYS A 898 -4.206 -23.500 -8.784 1.00 44.15 N ATOM 161 CA LYS A 898 -3.275 -23.916 -9.836 1.00 44.11 C ATOM 162 C LYS A 898 -3.159 -22.787 -10.871 1.00 46.50 C ATOM 163 O LYS A 898 -4.147 -22.500 -11.546 1.00 45.72 O ATOM 164 CB LYS A 898 -3.788 -25.205 -10.521 1.00 48.28 C ATOM 165 CG LYS A 898 -3.559 -26.517 -9.749 1.00 70.59 C ATOM 166 CD LYS A 898 -4.421 -26.693 -8.490 1.00 82.83 C ATOM 167 CE LYS A 898 -4.393 -28.144 -7.981 1.00 97.68 C ATOM 168 NZ LYS A 898 -5.185 -28.320 -6.753 1.00107.26 N1+ ATOM 169 H LYS A 898 -5.188 -23.612 -9.002 1.00 44.15 H ATOM 170 HA LYS A 898 -2.289 -24.117 -9.411 1.00 44.11 H ATOM 171 HB3 LYS A 898 -3.252 -25.321 -11.464 1.00 48.28 H ATOM 172 HB2 LYS A 898 -4.839 -25.106 -10.797 1.00 48.28 H ATOM 173 HG3 LYS A 898 -2.505 -26.604 -9.484 1.00 70.59 H ATOM 174 HG2 LYS A 898 -3.761 -27.344 -10.431 1.00 70.59 H ATOM 175 HD3 LYS A 898 -5.444 -26.381 -8.702 1.00 82.83 H ATOM 176 HD2 LYS A 898 -4.049 -26.031 -7.707 1.00 82.83 H ATOM 177 HE3 LYS A 898 -3.368 -28.453 -7.777 1.00 97.68 H ATOM 178 HE2 LYS A 898 -4.788 -28.816 -8.743 1.00 97.68 H ATOM 179 HZ1 LYS A 898 -4.817 -27.724 -6.025 1.00107.26 H ATOM 180 HZ2 LYS A 898 -6.153 -28.082 -6.930 1.00107.26 H ATOM 181 HZ3 LYS A 898 -5.133 -29.284 -6.455 1.00107.26 H ATOM 182 N LYS A 899 -1.972 -22.166 -10.979 1.00 42.86 N ATOM 183 CA LYS A 899 -1.712 -21.052 -11.897 1.00 42.35 C ATOM 184 C LYS A 899 -1.708 -21.508 -13.365 1.00 45.75 C ATOM 185 O LYS A 899 -1.008 -22.465 -13.695 1.00 46.24 O ATOM 186 CB LYS A 899 -0.382 -20.375 -11.512 1.00 45.46 C ATOM 187 CG LYS A 899 -0.117 -19.063 -12.271 1.00 54.73 C ATOM 188 CD LYS A 899 1.114 -18.319 -11.740 1.00 64.90 C ATOM 189 CE LYS A 899 1.426 -17.068 -12.571 1.00 74.92 C ATOM 190 NZ LYS A 899 2.594 -16.337 -12.051 1.00 84.51 N1+ ATOM 191 H LYS A 899 -1.198 -22.461 -10.402 1.00 42.86 H ATOM 192 HA LYS A 899 -2.511 -20.319 -11.766 1.00 42.35 H ATOM 193 HB3 LYS A 899 0.450 -21.065 -11.661 1.00 45.46 H ATOM 194 HB2 LYS A 899 -0.393 -20.156 -10.446 1.00 45.46 H ATOM 195 HG3 LYS A 899 -0.991 -18.414 -12.196 1.00 54.73 H ATOM 196 HG2 LYS A 899 0.021 -19.269 -13.333 1.00 54.73 H ATOM 197 HD3 LYS A 899 1.973 -18.993 -11.741 1.00 64.90 H ATOM 198 HD2 LYS A 899 0.939 -18.039 -10.700 1.00 64.90 H ATOM 199 HE3 LYS A 899 0.570 -16.395 -12.579 1.00 74.92 H ATOM 200 HE2 LYS A 899 1.622 -17.344 -13.608 1.00 74.92 H ATOM 201 HZ1 LYS A 899 2.755 -15.539 -12.651 1.00 84.51 H ATOM 202 HZ2 LYS A 899 2.411 -16.027 -11.108 1.00 84.51 H ATOM 203 HZ3 LYS A 899 3.406 -16.938 -12.065 1.00 84.51 H ATOM 204 N ILE A 900 -2.473 -20.796 -14.207 1.00 41.32 N ATOM 205 CA ILE A 900 -2.604 -21.076 -15.636 1.00 41.22 C ATOM 206 C ILE A 900 -1.686 -20.142 -16.451 1.00 44.92 C ATOM 207 O ILE A 900 -0.918 -20.640 -17.272 1.00 45.41 O ATOM 208 CB ILE A 900 -4.078 -20.931 -16.133 1.00 44.36 C ATOM 209 CG1 ILE A 900 -5.025 -21.868 -15.338 1.00 45.50 C ATOM 210 CG2 ILE A 900 -4.224 -21.186 -17.654 1.00 46.17 C ATOM 211 CD1 ILE A 900 -6.527 -21.664 -15.604 1.00 56.14 C ATOM 212 H ILE A 900 -3.010 -20.012 -13.856 1.00 41.32 H ATOM 213 HA ILE A 900 -2.293 -22.103 -15.839 1.00 41.22 H ATOM 214 HB ILE A 900 -4.399 -19.906 -15.939 1.00 44.36 H ATOM 215 HG13 ILE A 900 -4.869 -21.739 -14.267 1.00 45.50 H ATOM 216 HG12 ILE A 900 -4.762 -22.906 -15.546 1.00 45.50 H ATOM 217 HG21 ILE A 900 -5.257 -21.102 -17.988 1.00 46.17 H ATOM 218 HG22 ILE A 900 -3.655 -20.476 -18.252 1.00 46.17 H ATOM 219 HG23 ILE A 900 -3.880 -22.187 -17.914 1.00 46.17 H ATOM 220 HD11 ILE A 900 -6.981 -22.574 -15.996 1.00 56.14 H ATOM 221 HD12 ILE A 900 -7.057 -21.403 -14.689 1.00 56.14 H ATOM 222 HD13 ILE A 900 -6.724 -20.869 -16.318 1.00 56.14 H ATOM 223 N ARG A 901 -1.769 -18.822 -16.202 1.00 40.97 N ATOM 224 CA ARG A 901 -0.997 -17.785 -16.899 1.00 41.13 C ATOM 225 C ARG A 901 -1.153 -16.426 -16.197 1.00 44.46 C ATOM 226 O ARG A 901 -2.028 -16.266 -15.349 1.00 43.07 O ATOM 227 CB ARG A 901 -1.415 -17.689 -18.393 1.00 41.29 C ATOM 228 CG ARG A 901 -2.893 -17.330 -18.655 1.00 52.38 C ATOM 229 CD ARG A 901 -3.184 -17.151 -20.154 1.00 59.92 C ATOM 230 NE ARG A 901 -4.626 -17.047 -20.439 1.00 68.07 N ATOM 231 CZ ARG A 901 -5.470 -18.056 -20.731 1.00 83.41 C ATOM 232 NH1 ARG A 901 -5.064 -19.333 -20.802 1.00 64.57 N ATOM 233 NH2 ARG A 901 -6.760 -17.779 -20.958 1.00 77.22 N1+ ATOM 234 H ARG A 901 -2.406 -18.484 -15.493 1.00 40.97 H ATOM 235 HA ARG A 901 0.058 -18.059 -16.843 1.00 41.13 H ATOM 236 HB3 ARG A 901 -1.194 -18.631 -18.895 1.00 41.29 H ATOM 237 HB2 ARG A 901 -0.782 -16.954 -18.894 1.00 41.29 H ATOM 238 HG3 ARG A 901 -3.069 -16.365 -18.179 1.00 52.38 H ATOM 239 HG2 ARG A 901 -3.588 -18.026 -18.182 1.00 52.38 H ATOM 240 HD3 ARG A 901 -2.658 -17.871 -20.782 1.00 59.92 H ATOM 241 HD2 ARG A 901 -2.800 -16.172 -20.446 1.00 59.92 H ATOM 242 HE ARG A 901 -5.007 -16.113 -20.381 1.00 68.07 H ATOM 243 HH12 ARG A 901 -5.714 -20.071 -21.028 1.00 64.57 H ATOM 244 HH11 ARG A 901 -4.093 -19.560 -20.642 1.00 64.57 H ATOM 245 HH22 ARG A 901 -7.411 -18.517 -21.182 1.00 77.22 H ATOM 246 HH21 ARG A 901 -7.103 -16.830 -20.897 1.00 77.22 H ATOM 247 N ASP A 902 -0.327 -15.455 -16.617 1.00 41.92 N ATOM 248 CA ASP A 902 -0.466 -14.033 -16.281 1.00 41.86 C ATOM 249 C ASP A 902 -1.534 -13.379 -17.179 1.00 43.46 C ATOM 250 O ASP A 902 -1.649 -13.756 -18.347 1.00 42.68 O ATOM 251 CB ASP A 902 0.870 -13.255 -16.417 1.00 46.10 C ATOM 252 CG ASP A 902 2.075 -13.816 -15.638 1.00 63.12 C ATOM 253 OD1 ASP A 902 1.868 -14.510 -14.618 1.00 62.46 O ATOM 254 OD2 ASP A 902 3.207 -13.412 -15.980 1.00 75.36 O1- ATOM 255 H ASP A 902 0.372 -15.668 -17.314 1.00 41.92 H ATOM 256 HA ASP A 902 -0.795 -13.952 -15.245 1.00 41.86 H ATOM 257 HB3 ASP A 902 0.722 -12.227 -16.081 1.00 46.10 H ATOM 258 HB2 ASP A 902 1.153 -13.205 -17.470 1.00 46.10 H ATOM 259 N LEU A 903 -2.271 -12.398 -16.628 1.00 39.42 N ATOM 260 CA LEU A 903 -3.273 -11.609 -17.359 1.00 38.97 C ATOM 261 C LEU A 903 -2.810 -10.164 -17.625 1.00 45.51 C ATOM 262 O LEU A 903 -3.374 -9.534 -18.520 1.00 47.25 O ATOM 263 CB LEU A 903 -4.619 -11.607 -16.593 1.00 37.74 C ATOM 264 CG LEU A 903 -5.296 -12.990 -16.448 1.00 40.14 C ATOM 265 CD1 LEU A 903 -6.586 -12.886 -15.603 1.00 39.42 C ATOM 266 CD2 LEU A 903 -5.545 -13.682 -17.807 1.00 39.39 C ATOM 267 H LEU A 903 -2.124 -12.142 -15.660 1.00 39.42 H ATOM 268 HA LEU A 903 -3.440 -12.040 -18.346 1.00 38.97 H ATOM 269 HB3 LEU A 903 -5.320 -10.938 -17.097 1.00 37.74 H ATOM 270 HB2 LEU A 903 -4.461 -11.178 -15.603 1.00 37.74 H ATOM 271 HG LEU A 903 -4.609 -13.626 -15.891 1.00 40.14 H ATOM 272 HD11 LEU A 903 -7.473 -13.231 -16.134 1.00 39.42 H ATOM 273 HD12 LEU A 903 -6.505 -13.482 -14.694 1.00 39.42 H ATOM 274 HD13 LEU A 903 -6.792 -11.860 -15.296 1.00 39.42 H ATOM 275 HD21 LEU A 903 -6.525 -14.154 -17.871 1.00 39.39 H ATOM 276 HD22 LEU A 903 -5.480 -12.984 -18.642 1.00 39.39 H ATOM 277 HD23 LEU A 903 -4.806 -14.466 -17.979 1.00 39.39 H ATOM 278 N GLY A 904 -1.802 -9.669 -16.884 1.00 41.87 N ATOM 279 CA GLY A 904 -1.253 -8.324 -17.054 1.00 43.49 C ATOM 280 C GLY A 904 -1.005 -7.670 -15.690 1.00 48.38 C ATOM 281 O GLY A 904 -1.010 -8.335 -14.653 1.00 47.59 O ATOM 282 H GLY A 904 -1.396 -10.235 -16.152 1.00 41.87 H ATOM 283 HA3 GLY A 904 -1.915 -7.681 -17.638 1.00 43.49 H ATOM 284 HA2 GLY A 904 -0.308 -8.393 -17.594 1.00 43.49 H ATOM 285 N GLU A 905 -0.757 -6.351 -15.724 1.00 46.73 N ATOM 286 CA GLU A 905 -0.417 -5.520 -14.569 1.00 47.46 C ATOM 287 C GLU A 905 -1.527 -4.496 -14.305 1.00 51.67 C ATOM 288 O GLU A 905 -1.856 -3.713 -15.197 1.00 51.35 O ATOM 289 CB GLU A 905 0.926 -4.797 -14.834 1.00 51.27 C ATOM 290 CG GLU A 905 2.146 -5.732 -15.018 1.00 66.56 C ATOM 291 CD GLU A 905 2.576 -6.520 -13.769 1.00 94.70 C ATOM 292 OE1 GLU A 905 2.395 -6.005 -12.643 1.00 96.75 O ATOM 293 OE2 GLU A 905 3.103 -7.639 -13.964 1.00 86.75 O1- ATOM 294 H GLU A 905 -0.773 -5.869 -16.611 1.00 46.73 H ATOM 295 HA GLU A 905 -0.307 -6.133 -13.677 1.00 47.46 H ATOM 296 HB3 GLU A 905 1.125 -4.080 -14.036 1.00 51.27 H ATOM 297 HB2 GLU A 905 0.832 -4.191 -15.737 1.00 51.27 H ATOM 298 HG3 GLU A 905 3.002 -5.131 -15.326 1.00 66.56 H ATOM 299 HG2 GLU A 905 1.960 -6.422 -15.843 1.00 66.56 H ATOM 300 N GLY A 906 -2.038 -4.492 -13.063 1.00 48.81 N ATOM 301 CA GLY A 906 -2.898 -3.437 -12.529 1.00 50.44 C ATOM 302 C GLY A 906 -2.033 -2.425 -11.758 1.00 59.13 C ATOM 303 O GLY A 906 -0.802 -2.468 -11.826 1.00 59.62 O ATOM 304 H GLY A 906 -1.693 -5.164 -12.391 1.00 48.81 H ATOM 305 HA3 GLY A 906 -3.632 -3.885 -11.863 1.00 50.44 H ATOM 306 HA2 GLY A 906 -3.453 -2.925 -13.317 1.00 50.44 H ATOM 307 N HIS A 907 -2.685 -1.495 -11.037 1.00 58.87 N ATOM 308 CA HIS A 907 -2.024 -0.392 -10.326 1.00 61.58 C ATOM 309 C HIS A 907 -1.031 -0.830 -9.225 1.00 65.75 C ATOM 310 O HIS A 907 0.140 -0.461 -9.313 1.00 67.01 O ATOM 311 CB HIS A 907 -3.071 0.615 -9.806 1.00 64.07 C ATOM 312 CG HIS A 907 -2.464 1.855 -9.191 1.00 71.10 C ATOM 313 ND1 HIS A 907 -2.421 2.072 -7.824 1.00 74.01 N ATOM 314 CD2 HIS A 907 -1.844 2.946 -9.759 1.00 75.68 C ATOM 315 CE1 HIS A 907 -1.781 3.227 -7.629 1.00 76.67 C ATOM 316 NE2 HIS A 907 -1.401 3.813 -8.758 1.00 78.22 N ATOM 317 H HIS A 907 -3.695 -1.465 -11.060 1.00 58.87 H ATOM 318 HA HIS A 907 -1.436 0.136 -11.080 1.00 61.58 H ATOM 319 HB3 HIS A 907 -3.722 0.137 -9.074 1.00 64.07 H ATOM 320 HB2 HIS A 907 -3.717 0.935 -10.625 1.00 64.07 H ATOM 321 HD1 HIS A 907 -2.801 1.473 -7.103 1.00 74.01 H ATOM 322 HD2 HIS A 907 -1.664 3.165 -10.801 1.00 75.68 H ATOM 323 HE1 HIS A 907 -1.598 3.647 -6.651 1.00 76.67 H ATOM 324 N PHE A 908 -1.500 -1.593 -8.220 1.00 61.05 N ATOM 325 CA PHE A 908 -0.670 -2.041 -7.090 1.00 61.65 C ATOM 326 C PHE A 908 0.158 -3.312 -7.352 1.00 63.63 C ATOM 327 O PHE A 908 1.051 -3.603 -6.555 1.00 65.29 O ATOM 328 CB PHE A 908 -1.529 -2.186 -5.816 1.00 63.30 C ATOM 329 CG PHE A 908 -2.026 -0.870 -5.245 1.00 67.27 C ATOM 330 CD1 PHE A 908 -1.113 0.118 -4.816 1.00 73.63 C ATOM 331 CD2 PHE A 908 -3.407 -0.616 -5.143 1.00 68.80 C ATOM 332 CE1 PHE A 908 -1.582 1.333 -4.333 1.00 76.93 C ATOM 333 CE2 PHE A 908 -3.854 0.595 -4.639 1.00 73.69 C ATOM 334 CZ PHE A 908 -2.947 1.573 -4.254 1.00 75.01 C ATOM 335 H PHE A 908 -2.475 -1.851 -8.194 1.00 61.05 H ATOM 336 HA PHE A 908 0.075 -1.268 -6.889 1.00 61.65 H ATOM 337 HB3 PHE A 908 -0.967 -2.687 -5.026 1.00 63.30 H ATOM 338 HB2 PHE A 908 -2.382 -2.833 -6.027 1.00 63.30 H ATOM 339 HD1 PHE A 908 -0.050 -0.062 -4.872 1.00 73.63 H ATOM 340 HD2 PHE A 908 -4.123 -1.361 -5.449 1.00 68.80 H ATOM 341 HE1 PHE A 908 -0.886 2.096 -4.018 1.00 76.93 H ATOM 342 HE2 PHE A 908 -4.914 0.778 -4.550 1.00 73.69 H ATOM 343 HZ PHE A 908 -3.306 2.520 -3.880 1.00 75.01 H ATOM 344 N GLY A 909 -0.118 -4.030 -8.451 1.00 56.05 N ATOM 345 CA GLY A 909 0.641 -5.220 -8.813 1.00 53.59 C ATOM 346 C GLY A 909 -0.135 -6.069 -9.822 1.00 52.99 C ATOM 347 O GLY A 909 -1.181 -5.674 -10.342 1.00 51.95 O ATOM 348 H GLY A 909 -0.847 -3.737 -9.086 1.00 56.05 H ATOM 349 HA3 GLY A 909 0.870 -5.821 -7.931 1.00 53.59 H ATOM 350 HA2 GLY A 909 1.590 -4.917 -9.258 1.00 53.59 H ATOM 351 N LYS A 910 0.446 -7.242 -10.114 1.00 47.39 N ATOM 352 CA LYS A 910 0.039 -8.174 -11.161 1.00 44.86 C ATOM 353 C LYS A 910 -1.302 -8.879 -10.907 1.00 43.37 C ATOM 354 O LYS A 910 -1.655 -9.140 -9.759 1.00 42.02 O ATOM 355 CB LYS A 910 1.174 -9.198 -11.371 1.00 48.19 C ATOM 356 CG LYS A 910 1.463 -10.135 -10.177 1.00 70.18 C ATOM 357 CD LYS A 910 2.696 -11.044 -10.355 1.00 80.07 C ATOM 358 CE LYS A 910 2.500 -12.254 -11.290 1.00 90.27 C ATOM 359 NZ LYS A 910 2.509 -11.895 -12.720 1.00 99.37 N1+ ATOM 360 H LYS A 910 1.299 -7.487 -9.634 1.00 47.39 H ATOM 361 HA LYS A 910 -0.058 -7.598 -12.079 1.00 44.86 H ATOM 362 HB3 LYS A 910 2.088 -8.663 -11.624 1.00 48.19 H ATOM 363 HB2 LYS A 910 0.918 -9.787 -12.250 1.00 48.19 H ATOM 364 HG3 LYS A 910 0.595 -10.759 -9.970 1.00 70.18 H ATOM 365 HG2 LYS A 910 1.611 -9.535 -9.280 1.00 70.18 H ATOM 366 HD3 LYS A 910 2.986 -11.415 -9.371 1.00 80.07 H ATOM 367 HD2 LYS A 910 3.543 -10.445 -10.692 1.00 80.07 H ATOM 368 HE3 LYS A 910 1.575 -12.777 -11.046 1.00 90.27 H ATOM 369 HE2 LYS A 910 3.311 -12.965 -11.133 1.00 90.27 H ATOM 370 HZ1 LYS A 910 1.759 -11.248 -12.914 1.00 99.37 H ATOM 371 HZ2 LYS A 910 3.388 -11.459 -12.961 1.00 99.37 H ATOM 372 HZ3 LYS A 910 2.383 -12.725 -13.287 1.00 99.37 H ATOM 373 N VAL A 911 -1.971 -9.225 -12.016 1.00 37.15 N ATOM 374 CA VAL A 911 -3.138 -10.101 -12.065 1.00 34.94 C ATOM 375 C VAL A 911 -2.732 -11.374 -12.827 1.00 36.97 C ATOM 376 O VAL A 911 -2.030 -11.287 -13.838 1.00 35.74 O ATOM 377 CB VAL A 911 -4.323 -9.449 -12.832 1.00 38.64 C ATOM 378 CG1 VAL A 911 -5.604 -10.312 -12.836 1.00 37.50 C ATOM 379 CG2 VAL A 911 -4.665 -8.046 -12.301 1.00 39.45 C ATOM 380 H VAL A 911 -1.594 -8.964 -12.919 1.00 37.15 H ATOM 381 HA VAL A 911 -3.461 -10.380 -11.067 1.00 34.94 H ATOM 382 HB VAL A 911 -4.013 -9.331 -13.869 1.00 38.64 H ATOM 383 HG11 VAL A 911 -6.413 -9.808 -13.365 1.00 37.50 H ATOM 384 HG12 VAL A 911 -5.459 -11.273 -13.327 1.00 37.50 H ATOM 385 HG13 VAL A 911 -5.949 -10.509 -11.820 1.00 37.50 H ATOM 386 HG21 VAL A 911 -5.489 -7.603 -12.859 1.00 39.45 H ATOM 387 HG22 VAL A 911 -4.967 -8.091 -11.259 1.00 39.45 H ATOM 388 HG23 VAL A 911 -3.822 -7.359 -12.381 1.00 39.45 H ATOM 389 N SER A 912 -3.188 -12.530 -12.325 1.00 32.82 N ATOM 390 CA SER A 912 -2.920 -13.839 -12.909 1.00 32.44 C ATOM 391 C SER A 912 -4.187 -14.693 -12.861 1.00 36.01 C ATOM 392 O SER A 912 -4.950 -14.617 -11.899 1.00 34.87 O ATOM 393 CB SER A 912 -1.780 -14.527 -12.136 1.00 36.04 C ATOM 394 OG SER A 912 -0.549 -13.884 -12.379 1.00 45.71 O ATOM 395 H SER A 912 -3.765 -12.527 -11.494 1.00 32.82 H ATOM 396 HA SER A 912 -2.642 -13.737 -13.958 1.00 32.44 H ATOM 397 HB3 SER A 912 -1.683 -15.572 -12.436 1.00 36.04 H ATOM 398 HB2 SER A 912 -1.975 -14.516 -11.066 1.00 36.04 H ATOM 399 HG SER A 912 -0.594 -13.012 -11.977 1.00 45.71 H ATOM 400 N LEU A 913 -4.360 -15.518 -13.900 1.00 32.94 N ATOM 401 CA LEU A 913 -5.421 -16.505 -14.016 1.00 32.73 C ATOM 402 C LEU A 913 -5.002 -17.794 -13.295 1.00 36.98 C ATOM 403 O LEU A 913 -3.924 -18.324 -13.568 1.00 35.71 O ATOM 404 CB LEU A 913 -5.708 -16.725 -15.517 1.00 33.31 C ATOM 405 CG LEU A 913 -6.770 -17.793 -15.857 1.00 38.67 C ATOM 406 CD1 LEU A 913 -8.125 -17.524 -15.168 1.00 39.26 C ATOM 407 CD2 LEU A 913 -6.897 -17.945 -17.387 1.00 40.96 C ATOM 408 H LEU A 913 -3.653 -15.554 -14.623 1.00 32.94 H ATOM 409 HA LEU A 913 -6.319 -16.103 -13.545 1.00 32.73 H ATOM 410 HB3 LEU A 913 -4.776 -16.989 -16.019 1.00 33.31 H ATOM 411 HB2 LEU A 913 -6.024 -15.778 -15.951 1.00 33.31 H ATOM 412 HG LEU A 913 -6.411 -18.748 -15.479 1.00 38.67 H ATOM 413 HD11 LEU A 913 -8.969 -17.675 -15.835 1.00 39.26 H ATOM 414 HD12 LEU A 913 -8.270 -18.198 -14.324 1.00 39.26 H ATOM 415 HD13 LEU A 913 -8.203 -16.505 -14.788 1.00 39.26 H ATOM 416 HD21 LEU A 913 -6.656 -18.960 -17.702 1.00 40.96 H ATOM 417 HD22 LEU A 913 -7.896 -17.721 -17.755 1.00 40.96 H ATOM 418 HD23 LEU A 913 -6.216 -17.279 -17.917 1.00 40.96 H ATOM 419 N TYR A 914 -5.887 -18.270 -12.410 1.00 34.34 N ATOM 420 CA TYR A 914 -5.761 -19.522 -11.672 1.00 35.26 C ATOM 421 C TYR A 914 -7.035 -20.352 -11.864 1.00 40.97 C ATOM 422 O TYR A 914 -8.122 -19.790 -11.984 1.00 41.41 O ATOM 423 CB TYR A 914 -5.585 -19.230 -10.167 1.00 36.25 C ATOM 424 CG TYR A 914 -4.258 -18.632 -9.738 1.00 37.55 C ATOM 425 CD1 TYR A 914 -3.251 -19.461 -9.207 1.00 41.10 C ATOM 426 CD2 TYR A 914 -4.046 -17.242 -9.800 1.00 37.73 C ATOM 427 CE1 TYR A 914 -2.054 -18.909 -8.717 1.00 42.72 C ATOM 428 CE2 TYR A 914 -2.845 -16.686 -9.315 1.00 39.24 C ATOM 429 CZ TYR A 914 -1.847 -17.519 -8.776 1.00 49.59 C ATOM 430 OH TYR A 914 -0.685 -16.979 -8.308 1.00 54.45 O ATOM 431 H TYR A 914 -6.749 -17.762 -12.251 1.00 34.34 H ATOM 432 HA TYR A 914 -4.909 -20.094 -12.040 1.00 35.26 H ATOM 433 HB3 TYR A 914 -5.705 -20.158 -9.605 1.00 36.25 H ATOM 434 HB2 TYR A 914 -6.386 -18.578 -9.817 1.00 36.25 H ATOM 435 HD1 TYR A 914 -3.405 -20.526 -9.149 1.00 41.10 H ATOM 436 HD2 TYR A 914 -4.816 -16.599 -10.198 1.00 37.73 H ATOM 437 HE1 TYR A 914 -1.299 -19.558 -8.297 1.00 42.72 H ATOM 438 HE2 TYR A 914 -2.701 -15.617 -9.335 1.00 39.24 H ATOM 439 HH TYR A 914 -0.088 -17.635 -7.941 1.00 54.45 H ATOM 440 N CYS A 915 -6.871 -21.680 -11.807 1.00 39.05 N ATOM 441 CA CYS A 915 -7.950 -22.649 -11.663 1.00 40.20 C ATOM 442 C CYS A 915 -7.988 -23.052 -10.181 1.00 43.77 C ATOM 443 O CYS A 915 -7.093 -23.769 -9.728 1.00 43.29 O ATOM 444 CB CYS A 915 -7.745 -23.856 -12.604 1.00 41.99 C ATOM 445 SG CYS A 915 -9.062 -25.098 -12.432 1.00 48.59 S ATOM 446 H CYS A 915 -5.935 -22.054 -11.712 1.00 39.05 H ATOM 447 HA CYS A 915 -8.905 -22.191 -11.927 1.00 40.20 H ATOM 448 HB3 CYS A 915 -6.786 -24.339 -12.412 1.00 41.99 H ATOM 449 HB2 CYS A 915 -7.727 -23.525 -13.642 1.00 41.99 H ATOM 450 HG CYS A 915 -10.049 -24.342 -12.923 1.00 48.59 H ATOM 451 N TYR A 916 -9.007 -22.565 -9.452 1.00 39.62 N ATOM 452 CA TYR A 916 -9.266 -22.950 -8.066 1.00 39.96 C ATOM 453 C TYR A 916 -9.955 -24.317 -8.054 1.00 45.20 C ATOM 454 O TYR A 916 -11.103 -24.411 -8.485 1.00 45.42 O ATOM 455 CB TYR A 916 -10.123 -21.883 -7.362 1.00 40.18 C ATOM 456 CG TYR A 916 -10.338 -22.159 -5.882 1.00 41.11 C ATOM 457 CD1 TYR A 916 -9.235 -22.141 -5.005 1.00 41.72 C ATOM 458 CD2 TYR A 916 -11.625 -22.431 -5.372 1.00 43.06 C ATOM 459 CE1 TYR A 916 -9.421 -22.339 -3.626 1.00 42.69 C ATOM 460 CE2 TYR A 916 -11.807 -22.654 -3.991 1.00 44.62 C ATOM 461 CZ TYR A 916 -10.704 -22.596 -3.116 1.00 47.56 C ATOM 462 OH TYR A 916 -10.866 -22.784 -1.774 1.00 49.11 O ATOM 463 H TYR A 916 -9.717 -21.999 -9.899 1.00 39.62 H ATOM 464 HA TYR A 916 -8.313 -23.020 -7.541 1.00 39.96 H ATOM 465 HB3 TYR A 916 -11.089 -21.777 -7.861 1.00 40.18 H ATOM 466 HB2 TYR A 916 -9.641 -20.909 -7.450 1.00 40.18 H ATOM 467 HD1 TYR A 916 -8.244 -21.965 -5.390 1.00 41.72 H ATOM 468 HD2 TYR A 916 -12.478 -22.459 -6.035 1.00 43.06 H ATOM 469 HE1 TYR A 916 -8.578 -22.297 -2.958 1.00 42.69 H ATOM 470 HE2 TYR A 916 -12.797 -22.853 -3.609 1.00 44.62 H ATOM 471 HH TYR A 916 -11.780 -22.931 -1.519 1.00 49.11 H ATOM 472 N ASP A 917 -9.224 -25.343 -7.600 1.00 46.60 N ATOM 473 CA ASP A 917 -9.548 -26.742 -7.857 1.00 48.33 C ATOM 474 C ASP A 917 -9.310 -27.589 -6.586 1.00 54.57 C ATOM 475 O ASP A 917 -8.280 -28.261 -6.507 1.00 54.85 O ATOM 476 CB ASP A 917 -8.720 -27.202 -9.088 1.00 50.11 C ATOM 477 CG ASP A 917 -8.948 -28.619 -9.626 1.00 62.07 C ATOM 478 OD1 ASP A 917 -10.074 -29.144 -9.481 1.00 63.23 O ATOM 479 OD2 ASP A 917 -8.018 -29.099 -10.308 1.00 69.60 O1- ATOM 480 H ASP A 917 -8.291 -25.168 -7.248 1.00 46.60 H ATOM 481 HA ASP A 917 -10.604 -26.840 -8.110 1.00 48.33 H ATOM 482 HB3 ASP A 917 -7.660 -27.061 -8.876 1.00 50.11 H ATOM 483 HB2 ASP A 917 -8.925 -26.518 -9.911 1.00 50.11 H ATOM 484 N PRO A 918 -10.233 -27.531 -5.592 1.00 52.47 N ATOM 485 CA PRO A 918 -10.097 -28.298 -4.337 1.00 54.47 C ATOM 486 C PRO A 918 -10.108 -29.832 -4.468 1.00 61.35 C ATOM 487 O PRO A 918 -9.390 -30.493 -3.718 1.00 62.40 O ATOM 488 CB PRO A 918 -11.249 -27.795 -3.449 1.00 56.45 C ATOM 489 CG PRO A 918 -11.619 -26.442 -4.028 1.00 58.90 C ATOM 490 CD PRO A 918 -11.398 -26.646 -5.519 1.00 53.43 C ATOM 491 HA PRO A 918 -9.154 -28.002 -3.890 1.00 54.47 H ATOM 492 HB3 PRO A 918 -10.970 -27.730 -2.397 1.00 56.45 H ATOM 493 HB2 PRO A 918 -12.112 -28.460 -3.518 1.00 56.45 H ATOM 494 HG3 PRO A 918 -10.924 -25.686 -3.658 1.00 58.90 H ATOM 495 HG2 PRO A 918 -12.631 -26.122 -3.778 1.00 58.90 H ATOM 496 HD2 PRO A 918 -12.253 -27.150 -5.969 1.00 53.43 H ATOM 497 HD3 PRO A 918 -11.278 -25.684 -6.008 1.00 53.43 H ATOM 498 N THR A 919 -10.909 -30.361 -5.407 1.00 59.02 N ATOM 499 CA THR A 919 -11.072 -31.799 -5.649 1.00 61.06 C ATOM 500 C THR A 919 -9.985 -32.394 -6.578 1.00 66.39 C ATOM 501 O THR A 919 -9.864 -33.618 -6.624 1.00 67.71 O ATOM 502 CB THR A 919 -12.460 -32.093 -6.275 1.00 69.24 C ATOM 503 OG1 THR A 919 -12.585 -31.469 -7.533 1.00 68.64 O ATOM 504 CG2 THR A 919 -13.638 -31.637 -5.400 1.00 68.24 C ATOM 505 H THR A 919 -11.466 -29.756 -5.994 1.00 59.02 H ATOM 506 HA THR A 919 -11.011 -32.326 -4.695 1.00 61.06 H ATOM 507 HB THR A 919 -12.561 -33.168 -6.437 1.00 69.24 H ATOM 508 HG1 THR A 919 -13.251 -31.932 -8.052 1.00 68.64 H ATOM 509 HG21 THR A 919 -14.591 -31.908 -5.855 1.00 68.24 H ATOM 510 HG22 THR A 919 -13.598 -32.106 -4.417 1.00 68.24 H ATOM 511 HG23 THR A 919 -13.640 -30.556 -5.253 1.00 68.24 H ATOM 512 N ASN A 920 -9.199 -31.539 -7.261 1.00 62.42 N ATOM 513 CA ASN A 920 -8.037 -31.885 -8.094 1.00 62.48 C ATOM 514 C ASN A 920 -8.379 -32.616 -9.418 1.00 68.30 C ATOM 515 O ASN A 920 -7.483 -33.225 -10.005 1.00 68.75 O ATOM 516 CB ASN A 920 -6.961 -32.649 -7.260 1.00 64.50 C ATOM 517 CG ASN A 920 -5.483 -32.372 -7.591 1.00 90.28 C ATOM 518 OD1 ASN A 920 -4.611 -32.755 -6.815 1.00 80.74 O ATOM 519 ND2 ASN A 920 -5.167 -31.729 -8.718 1.00 86.67 N ATOM 520 H ASN A 920 -9.390 -30.550 -7.183 1.00 62.42 H ATOM 521 HA ASN A 920 -7.608 -30.945 -8.433 1.00 62.48 H ATOM 522 HB3 ASN A 920 -7.149 -33.724 -7.262 1.00 64.50 H ATOM 523 HB2 ASN A 920 -7.058 -32.342 -6.217 1.00 64.50 H ATOM 524 HD22 ASN A 920 -4.198 -31.571 -8.954 1.00 86.67 H ATOM 525 HD21 ASN A 920 -5.888 -31.454 -9.372 1.00 86.67 H ATOM 526 N ASP A 921 -9.638 -32.539 -9.885 1.00 65.11 N ATOM 527 CA ASP A 921 -10.110 -33.196 -11.116 1.00 65.45 C ATOM 528 C ASP A 921 -9.985 -32.313 -12.380 1.00 68.10 C ATOM 529 O ASP A 921 -10.142 -32.837 -13.482 1.00 68.54 O ATOM 530 CB ASP A 921 -11.542 -33.785 -10.972 1.00 68.72 C ATOM 531 CG ASP A 921 -12.662 -32.858 -10.464 1.00 75.04 C ATOM 532 OD1 ASP A 921 -12.517 -31.619 -10.549 1.00 72.94 O ATOM 533 OD2 ASP A 921 -13.716 -33.411 -10.080 1.00 81.22 O1- ATOM 534 H ASP A 921 -10.326 -31.995 -9.382 1.00 65.11 H ATOM 535 HA ASP A 921 -9.464 -34.056 -11.306 1.00 65.45 H ATOM 536 HB3 ASP A 921 -11.484 -34.629 -10.282 1.00 68.72 H ATOM 537 HB2 ASP A 921 -11.865 -34.214 -11.922 1.00 68.72 H ATOM 538 N GLY A 922 -9.711 -31.008 -12.210 1.00 62.38 N ATOM 539 CA GLY A 922 -9.551 -30.041 -13.297 1.00 60.09 C ATOM 540 C GLY A 922 -10.863 -29.330 -13.668 1.00 63.42 C ATOM 541 O GLY A 922 -10.834 -28.480 -14.557 1.00 62.74 O ATOM 542 H GLY A 922 -9.599 -30.648 -11.270 1.00 62.38 H ATOM 543 HA3 GLY A 922 -9.136 -30.518 -14.186 1.00 60.09 H ATOM 544 HA2 GLY A 922 -8.828 -29.287 -12.986 1.00 60.09 H ATOM 545 N THR A 923 -11.995 -29.645 -13.011 1.00 59.47 N ATOM 546 CA THR A 923 -13.310 -29.037 -13.264 1.00 58.79 C ATOM 547 C THR A 923 -13.573 -27.766 -12.417 1.00 58.95 C ATOM 548 O THR A 923 -14.667 -27.206 -12.506 1.00 58.00 O ATOM 549 CB THR A 923 -14.472 -30.055 -13.053 1.00 71.45 C ATOM 550 OG1 THR A 923 -14.846 -30.240 -11.699 1.00 74.26 O ATOM 551 CG2 THR A 923 -14.234 -31.420 -13.720 1.00 71.82 C ATOM 552 H THR A 923 -11.966 -30.341 -12.275 1.00 59.47 H ATOM 553 HA THR A 923 -13.355 -28.722 -14.308 1.00 58.79 H ATOM 554 HB THR A 923 -15.355 -29.634 -13.535 1.00 71.45 H ATOM 555 HG1 THR A 923 -14.145 -30.727 -11.249 1.00 74.26 H ATOM 556 HG21 THR A 923 -15.102 -32.069 -13.603 1.00 71.82 H ATOM 557 HG22 THR A 923 -14.051 -31.305 -14.788 1.00 71.82 H ATOM 558 HG23 THR A 923 -13.377 -31.943 -13.294 1.00 71.82 H ATOM 559 N GLY A 924 -12.571 -27.323 -11.637 1.00 53.95 N ATOM 560 CA GLY A 924 -12.623 -26.151 -10.763 1.00 52.08 C ATOM 561 C GLY A 924 -12.788 -24.830 -11.535 1.00 53.45 C ATOM 562 O GLY A 924 -12.426 -24.728 -12.708 1.00 52.18 O ATOM 563 H GLY A 924 -11.706 -27.844 -11.632 1.00 53.95 H ATOM 564 HA3 GLY A 924 -11.683 -26.125 -10.215 1.00 52.08 H ATOM 565 HA2 GLY A 924 -13.425 -26.270 -10.033 1.00 52.08 H ATOM 566 N GLU A 925 -13.324 -23.810 -10.844 1.00 49.00 N ATOM 567 CA GLU A 925 -13.602 -22.474 -11.376 1.00 47.60 C ATOM 568 C GLU A 925 -12.333 -21.684 -11.730 1.00 48.02 C ATOM 569 O GLU A 925 -11.391 -21.647 -10.938 1.00 45.98 O ATOM 570 CB GLU A 925 -14.441 -21.680 -10.347 1.00 49.51 C ATOM 571 CG GLU A 925 -15.856 -22.247 -10.096 1.00 66.63 C ATOM 572 CD GLU A 925 -16.796 -22.122 -11.304 1.00 94.52 C ATOM 573 OE1 GLU A 925 -16.972 -20.979 -11.784 1.00 89.72 O ATOM 574 OE2 GLU A 925 -17.331 -23.170 -11.725 1.00 93.17 O1- ATOM 575 H GLU A 925 -13.590 -23.957 -9.880 1.00 49.00 H ATOM 576 HA GLU A 925 -14.185 -22.600 -12.290 1.00 47.60 H ATOM 577 HB3 GLU A 925 -14.507 -20.633 -10.646 1.00 49.51 H ATOM 578 HB2 GLU A 925 -13.910 -21.669 -9.394 1.00 49.51 H ATOM 579 HG3 GLU A 925 -16.312 -21.709 -9.264 1.00 66.63 H ATOM 580 HG2 GLU A 925 -15.791 -23.287 -9.773 1.00 66.63 H ATOM 581 N MET A 926 -12.376 -21.016 -12.893 1.00 43.85 N ATOM 582 CA MET A 926 -11.372 -20.052 -13.336 1.00 42.46 C ATOM 583 C MET A 926 -11.611 -18.704 -12.636 1.00 43.50 C ATOM 584 O MET A 926 -12.731 -18.192 -12.664 1.00 43.72 O ATOM 585 CB MET A 926 -11.429 -19.907 -14.871 1.00 44.66 C ATOM 586 CG MET A 926 -11.085 -21.206 -15.622 1.00 50.18 C ATOM 587 SD MET A 926 -11.210 -21.107 -17.430 1.00 55.18 S ATOM 588 CE MET A 926 -9.740 -20.126 -17.815 1.00 50.66 C ATOM 589 H MET A 926 -13.209 -21.073 -13.464 1.00 43.85 H ATOM 590 HA MET A 926 -10.384 -20.428 -13.070 1.00 42.46 H ATOM 591 HB3 MET A 926 -10.737 -19.124 -15.180 1.00 44.66 H ATOM 592 HB2 MET A 926 -12.419 -19.565 -15.178 1.00 44.66 H ATOM 593 HG3 MET A 926 -11.755 -22.005 -15.304 1.00 50.18 H ATOM 594 HG2 MET A 926 -10.078 -21.532 -15.362 1.00 50.18 H ATOM 595 HE1 MET A 926 -9.634 -20.012 -18.894 1.00 50.66 H ATOM 596 HE2 MET A 926 -9.824 -19.135 -17.376 1.00 50.66 H ATOM 597 HE3 MET A 926 -8.844 -20.609 -17.427 1.00 50.66 H ATOM 598 N VAL A 927 -10.551 -18.168 -12.017 1.00 36.95 N ATOM 599 CA VAL A 927 -10.570 -16.927 -11.247 1.00 34.96 C ATOM 600 C VAL A 927 -9.331 -16.077 -11.575 1.00 36.30 C ATOM 601 O VAL A 927 -8.232 -16.612 -11.722 1.00 35.86 O ATOM 602 CB VAL A 927 -10.610 -17.194 -9.711 1.00 39.31 C ATOM 603 CG1 VAL A 927 -11.992 -17.683 -9.251 1.00 40.52 C ATOM 604 CG2 VAL A 927 -9.507 -18.134 -9.180 1.00 39.38 C ATOM 605 H VAL A 927 -9.662 -18.654 -12.039 1.00 36.95 H ATOM 606 HA VAL A 927 -11.448 -16.339 -11.522 1.00 34.96 H ATOM 607 HB VAL A 927 -10.456 -16.236 -9.212 1.00 39.31 H ATOM 608 HG11 VAL A 927 -12.038 -17.771 -8.165 1.00 40.52 H ATOM 609 HG12 VAL A 927 -12.769 -16.982 -9.554 1.00 40.52 H ATOM 610 HG13 VAL A 927 -12.235 -18.658 -9.674 1.00 40.52 H ATOM 611 HG21 VAL A 927 -9.586 -18.255 -8.099 1.00 39.38 H ATOM 612 HG22 VAL A 927 -9.578 -19.128 -9.623 1.00 39.38 H ATOM 613 HG23 VAL A 927 -8.510 -17.750 -9.382 1.00 39.38 H ATOM 614 N ALA A 928 -9.546 -14.756 -11.667 1.00 33.12 N ATOM 615 CA ALA A 928 -8.506 -13.752 -11.857 1.00 33.29 C ATOM 616 C ALA A 928 -8.086 -13.216 -10.483 1.00 37.02 C ATOM 617 O ALA A 928 -8.817 -12.428 -9.884 1.00 37.68 O ATOM 618 CB ALA A 928 -9.054 -12.636 -12.757 1.00 33.26 C ATOM 619 H ALA A 928 -10.476 -14.395 -11.503 1.00 33.12 H ATOM 620 HA ALA A 928 -7.640 -14.190 -12.357 1.00 33.29 H ATOM 621 HB1 ALA A 928 -8.316 -11.845 -12.901 1.00 33.26 H ATOM 622 HB2 ALA A 928 -9.308 -13.028 -13.742 1.00 33.26 H ATOM 623 HB3 ALA A 928 -9.953 -12.181 -12.339 1.00 33.26 H ATOM 624 N VAL A 929 -6.929 -13.685 -9.998 1.00 32.01 N ATOM 625 CA VAL A 929 -6.385 -13.331 -8.692 1.00 31.43 C ATOM 626 C VAL A 929 -5.339 -12.221 -8.875 1.00 34.06 C ATOM 627 O VAL A 929 -4.322 -12.445 -9.535 1.00 33.04 O ATOM 628 CB VAL A 929 -5.698 -14.547 -8.012 1.00 35.67 C ATOM 629 CG1 VAL A 929 -5.130 -14.225 -6.617 1.00 35.66 C ATOM 630 CG2 VAL A 929 -6.643 -15.756 -7.910 1.00 35.86 C ATOM 631 H VAL A 929 -6.365 -14.309 -10.561 1.00 32.01 H ATOM 632 HA VAL A 929 -7.179 -12.977 -8.034 1.00 31.43 H ATOM 633 HB VAL A 929 -4.857 -14.854 -8.629 1.00 35.67 H ATOM 634 HG11 VAL A 929 -4.714 -15.115 -6.143 1.00 35.66 H ATOM 635 HG12 VAL A 929 -4.328 -13.487 -6.657 1.00 35.66 H ATOM 636 HG13 VAL A 929 -5.914 -13.838 -5.965 1.00 35.66 H ATOM 637 HG21 VAL A 929 -6.160 -16.590 -7.401 1.00 35.86 H ATOM 638 HG22 VAL A 929 -7.545 -15.504 -7.357 1.00 35.86 H ATOM 639 HG23 VAL A 929 -6.942 -16.112 -8.895 1.00 35.86 H ATOM 640 N LYS A 930 -5.610 -11.055 -8.273 1.00 30.97 N ATOM 641 CA LYS A 930 -4.688 -9.925 -8.224 1.00 30.96 C ATOM 642 C LYS A 930 -3.874 -9.976 -6.925 1.00 37.68 C ATOM 643 O LYS A 930 -4.421 -10.310 -5.875 1.00 36.55 O ATOM 644 CB LYS A 930 -5.482 -8.618 -8.397 1.00 33.16 C ATOM 645 CG LYS A 930 -4.599 -7.367 -8.542 1.00 48.15 C ATOM 646 CD LYS A 930 -5.416 -6.121 -8.900 1.00 51.77 C ATOM 647 CE LYS A 930 -4.523 -4.890 -9.108 1.00 60.76 C ATOM 648 NZ LYS A 930 -5.318 -3.714 -9.493 1.00 63.79 N1+ ATOM 649 H LYS A 930 -6.465 -10.954 -7.740 1.00 30.97 H ATOM 650 HA LYS A 930 -3.992 -9.993 -9.053 1.00 30.96 H ATOM 651 HB3 LYS A 930 -6.191 -8.486 -7.580 1.00 33.16 H ATOM 652 HB2 LYS A 930 -6.087 -8.710 -9.299 1.00 33.16 H ATOM 653 HG3 LYS A 930 -3.847 -7.538 -9.312 1.00 48.15 H ATOM 654 HG2 LYS A 930 -4.040 -7.183 -7.626 1.00 48.15 H ATOM 655 HD3 LYS A 930 -6.143 -5.928 -8.109 1.00 51.77 H ATOM 656 HD2 LYS A 930 -5.995 -6.317 -9.804 1.00 51.77 H ATOM 657 HE3 LYS A 930 -3.789 -5.088 -9.888 1.00 60.76 H ATOM 658 HE2 LYS A 930 -3.969 -4.658 -8.199 1.00 60.76 H ATOM 659 HZ1 LYS A 930 -5.988 -3.511 -8.759 1.00 63.79 H ATOM 660 HZ2 LYS A 930 -4.721 -2.911 -9.618 1.00 63.79 H ATOM 661 HZ3 LYS A 930 -5.818 -3.896 -10.350 1.00 63.79 H ATOM 662 N ALA A 931 -2.580 -9.642 -7.031 1.00 37.96 N ATOM 663 CA ALA A 931 -1.623 -9.687 -5.933 1.00 40.37 C ATOM 664 C ALA A 931 -0.830 -8.379 -5.859 1.00 49.88 C ATOM 665 O ALA A 931 -0.449 -7.826 -6.890 1.00 48.28 O ATOM 666 CB ALA A 931 -0.678 -10.880 -6.150 1.00 41.64 C ATOM 667 H ALA A 931 -2.209 -9.351 -7.928 1.00 37.96 H ATOM 668 HA ALA A 931 -2.145 -9.825 -4.984 1.00 40.37 H ATOM 669 HB1 ALA A 931 0.015 -10.988 -5.314 1.00 41.64 H ATOM 670 HB2 ALA A 931 -1.235 -11.814 -6.232 1.00 41.64 H ATOM 671 HB3 ALA A 931 -0.088 -10.766 -7.060 1.00 41.64 H ATOM 672 N LEU A 932 -0.559 -7.956 -4.618 1.00 51.32 N ATOM 673 CA LEU A 932 0.354 -6.877 -4.255 1.00 53.72 C ATOM 674 C LEU A 932 1.768 -7.462 -4.129 1.00 62.30 C ATOM 675 O LEU A 932 1.938 -8.492 -3.473 1.00 63.20 O ATOM 676 CB LEU A 932 -0.203 -6.237 -2.959 1.00 54.88 C ATOM 677 CG LEU A 932 0.643 -5.234 -2.140 1.00 61.02 C ATOM 678 CD1 LEU A 932 1.578 -5.910 -1.118 1.00 63.21 C ATOM 679 CD2 LEU A 932 1.333 -4.164 -3.002 1.00 63.43 C ATOM 680 H LEU A 932 -0.898 -8.507 -3.839 1.00 51.32 H ATOM 681 HA LEU A 932 0.353 -6.121 -5.044 1.00 53.72 H ATOM 682 HB3 LEU A 932 -0.550 -7.017 -2.280 1.00 54.88 H ATOM 683 HB2 LEU A 932 -1.098 -5.708 -3.275 1.00 54.88 H ATOM 684 HG LEU A 932 -0.082 -4.685 -1.537 1.00 61.02 H ATOM 685 HD11 LEU A 932 2.578 -5.486 -1.128 1.00 63.21 H ATOM 686 HD12 LEU A 932 1.192 -5.785 -0.107 1.00 63.21 H ATOM 687 HD13 LEU A 932 1.671 -6.983 -1.281 1.00 63.21 H ATOM 688 HD21 LEU A 932 1.351 -3.201 -2.490 1.00 63.43 H ATOM 689 HD22 LEU A 932 2.361 -4.440 -3.233 1.00 63.43 H ATOM 690 HD23 LEU A 932 0.815 -4.017 -3.948 1.00 63.43 H ATOM 691 N LYS A 933 2.746 -6.805 -4.775 1.00 61.35 N ATOM 692 CA LYS A 933 4.151 -7.223 -4.806 1.00 63.52 C ATOM 693 C LYS A 933 4.791 -7.220 -3.401 1.00 70.14 C ATOM 694 O LYS A 933 4.505 -6.330 -2.602 1.00 70.50 O ATOM 695 CB LYS A 933 4.920 -6.342 -5.819 1.00 66.45 C ATOM 696 CG LYS A 933 5.118 -4.872 -5.401 1.00 83.56 C ATOM 697 CD LYS A 933 5.932 -4.051 -6.408 1.00 96.14 C ATOM 698 CE LYS A 933 6.299 -2.668 -5.844 1.00107.75 C ATOM 699 NZ LYS A 933 7.319 -1.991 -6.663 1.00116.59 N1+ ATOM 700 H LYS A 933 2.523 -5.965 -5.289 1.00 61.35 H ATOM 701 HA LYS A 933 4.168 -8.249 -5.180 1.00 63.52 H ATOM 702 HB3 LYS A 933 4.426 -6.386 -6.790 1.00 66.45 H ATOM 703 HB2 LYS A 933 5.906 -6.784 -5.971 1.00 66.45 H ATOM 704 HG3 LYS A 933 5.647 -4.840 -4.451 1.00 83.56 H ATOM 705 HG2 LYS A 933 4.149 -4.396 -5.240 1.00 83.56 H ATOM 706 HD3 LYS A 933 5.354 -3.933 -7.326 1.00 96.14 H ATOM 707 HD2 LYS A 933 6.830 -4.606 -6.684 1.00 96.14 H ATOM 708 HE3 LYS A 933 6.712 -2.771 -4.840 1.00107.75 H ATOM 709 HE2 LYS A 933 5.413 -2.038 -5.765 1.00107.75 H ATOM 710 HZ1 LYS A 933 8.154 -2.563 -6.671 1.00116.59 H ATOM 711 HZ2 LYS A 933 6.989 -1.866 -7.610 1.00116.59 H ATOM 712 HZ3 LYS A 933 7.539 -1.092 -6.261 1.00116.59 H ATOM 713 N ALA A 934 5.650 -8.217 -3.131 1.00 68.33 N ATOM 714 CA ALA A 934 6.298 -8.425 -1.831 1.00 69.84 C ATOM 715 C ALA A 934 7.265 -7.306 -1.401 1.00 75.29 C ATOM 716 O ALA A 934 7.435 -7.096 -0.201 1.00 75.68 O ATOM 717 CB ALA A 934 7.019 -9.781 -1.846 1.00 71.23 C ATOM 718 H ALA A 934 5.847 -8.909 -3.840 1.00 68.33 H ATOM 719 HA ALA A 934 5.511 -8.468 -1.076 1.00 69.84 H ATOM 720 HB1 ALA A 934 7.460 -10.006 -0.874 1.00 71.23 H ATOM 721 HB2 ALA A 934 6.330 -10.591 -2.085 1.00 71.23 H ATOM 722 HB3 ALA A 934 7.820 -9.799 -2.587 1.00 71.23 H ATOM 723 N ASP A 935 7.863 -6.609 -2.380 1.00 72.17 N ATOM 724 CA ASP A 935 8.836 -5.527 -2.197 1.00 73.50 C ATOM 725 C ASP A 935 8.185 -4.144 -1.962 1.00 75.83 C ATOM 726 O ASP A 935 8.922 -3.179 -1.754 1.00 76.32 O ATOM 727 CB ASP A 935 9.864 -5.475 -3.361 1.00 76.23 C ATOM 728 CG ASP A 935 9.276 -5.328 -4.776 1.00 89.05 C ATOM 729 OD1 ASP A 935 8.665 -6.306 -5.264 1.00 88.80 O ATOM 730 OD2 ASP A 935 9.356 -4.200 -5.311 1.00 97.21 O1- ATOM 731 H ASP A 935 7.672 -6.851 -3.344 1.00 72.17 H ATOM 732 HA ASP A 935 9.406 -5.746 -1.292 1.00 73.50 H ATOM 733 HB3 ASP A 935 10.432 -6.406 -3.352 1.00 76.23 H ATOM 734 HB2 ASP A 935 10.609 -4.697 -3.179 1.00 76.23 H ATOM 735 N ALA A 936 6.842 -4.054 -1.996 1.00 70.25 N ATOM 736 CA ALA A 936 6.074 -2.822 -1.798 1.00 69.55 C ATOM 737 C ALA A 936 6.250 -2.196 -0.405 1.00 73.05 C ATOM 738 O ALA A 936 6.327 -2.920 0.589 1.00 73.05 O ATOM 739 CB ALA A 936 4.591 -3.122 -2.034 1.00 68.72 C ATOM 740 H ALA A 936 6.301 -4.891 -2.162 1.00 70.25 H ATOM 741 HA ALA A 936 6.404 -2.099 -2.546 1.00 69.55 H ATOM 742 HB1 ALA A 936 3.968 -2.252 -1.839 1.00 68.72 H ATOM 743 HB2 ALA A 936 4.413 -3.419 -3.064 1.00 68.72 H ATOM 744 HB3 ALA A 936 4.241 -3.921 -1.381 1.00 68.72 H ATOM 745 N GLY A 937 6.263 -0.854 -0.374 1.00 68.94 N ATOM 746 CA GLY A 937 6.335 -0.057 0.850 1.00 69.45 C ATOM 747 C GLY A 937 4.933 0.143 1.460 1.00 71.44 C ATOM 748 O GLY A 937 3.934 -0.265 0.865 1.00 69.33 O ATOM 749 H GLY A 937 6.175 -0.344 -1.241 1.00 68.94 H ATOM 750 HA3 GLY A 937 6.771 0.911 0.607 1.00 69.45 H ATOM 751 HA2 GLY A 937 6.996 -0.534 1.576 1.00 69.45 H ATOM 752 N PRO A 938 4.847 0.779 2.651 1.00 68.74 N ATOM 753 CA PRO A 938 3.589 0.933 3.409 1.00 68.21 C ATOM 754 C PRO A 938 2.501 1.788 2.729 1.00 71.10 C ATOM 755 O PRO A 938 1.321 1.556 2.990 1.00 70.04 O ATOM 756 CB PRO A 938 4.043 1.532 4.751 1.00 71.88 C ATOM 757 CG PRO A 938 5.339 2.259 4.429 1.00 77.34 C ATOM 758 CD PRO A 938 5.977 1.366 3.372 1.00 72.04 C ATOM 759 HA PRO A 938 3.163 -0.053 3.593 1.00 68.21 H ATOM 760 HB3 PRO A 938 4.244 0.723 5.455 1.00 71.88 H ATOM 761 HB2 PRO A 938 3.305 2.188 5.216 1.00 71.88 H ATOM 762 HG3 PRO A 938 5.975 2.421 5.300 1.00 77.34 H ATOM 763 HG2 PRO A 938 5.111 3.233 3.994 1.00 77.34 H ATOM 764 HD2 PRO A 938 6.648 1.939 2.732 1.00 72.04 H ATOM 765 HD3 PRO A 938 6.549 0.565 3.842 1.00 72.04 H ATOM 766 N GLN A 939 2.905 2.724 1.853 1.00 67.61 N ATOM 767 CA GLN A 939 2.021 3.560 1.038 1.00 66.36 C ATOM 768 C GLN A 939 1.200 2.757 0.008 1.00 68.88 C ATOM 769 O GLN A 939 0.018 3.051 -0.168 1.00 67.37 O ATOM 770 CB GLN A 939 2.817 4.723 0.389 1.00 68.30 C ATOM 771 CG GLN A 939 3.855 4.379 -0.712 1.00 77.62 C ATOM 772 CD GLN A 939 5.122 3.666 -0.222 1.00 79.26 C ATOM 773 OE1 GLN A 939 5.529 3.809 0.929 1.00 70.91 O ATOM 774 NE2 GLN A 939 5.769 2.907 -1.106 1.00 67.19 N ATOM 775 H GLN A 939 3.896 2.872 1.712 1.00 67.61 H ATOM 776 HA GLN A 939 1.304 4.015 1.725 1.00 66.36 H ATOM 777 HB3 GLN A 939 3.296 5.311 1.174 1.00 68.30 H ATOM 778 HB2 GLN A 939 2.092 5.403 -0.059 1.00 68.30 H ATOM 779 HG3 GLN A 939 4.183 5.309 -1.175 1.00 77.62 H ATOM 780 HG2 GLN A 939 3.393 3.803 -1.513 1.00 77.62 H ATOM 781 HE22 GLN A 939 6.630 2.450 -0.845 1.00 67.19 H ATOM 782 HE21 GLN A 939 5.407 2.784 -2.042 1.00 67.19 H ATOM 783 N HIS A 940 1.825 1.743 -0.617 1.00 64.95 N ATOM 784 CA HIS A 940 1.173 0.836 -1.562 1.00 63.06 C ATOM 785 C HIS A 940 0.336 -0.247 -0.865 1.00 62.55 C ATOM 786 O HIS A 940 -0.666 -0.669 -1.435 1.00 60.85 O ATOM 787 CB HIS A 940 2.221 0.189 -2.485 1.00 64.66 C ATOM 788 CG HIS A 940 2.915 1.133 -3.435 1.00 69.42 C ATOM 789 ND1 HIS A 940 4.296 1.361 -3.394 1.00 71.01 N ATOM 790 CD2 HIS A 940 2.373 1.877 -4.463 1.00 73.12 C ATOM 791 CE1 HIS A 940 4.528 2.217 -4.381 1.00 71.34 C ATOM 792 NE2 HIS A 940 3.425 2.560 -5.046 1.00 72.94 N ATOM 793 H HIS A 940 2.793 1.547 -0.404 1.00 64.95 H ATOM 794 HA HIS A 940 0.488 1.415 -2.185 1.00 63.06 H ATOM 795 HB3 HIS A 940 1.764 -0.598 -3.086 1.00 64.66 H ATOM 796 HB2 HIS A 940 2.982 -0.293 -1.874 1.00 64.66 H ATOM 797 HD2 HIS A 940 1.359 1.973 -4.821 1.00 73.12 H ATOM 798 HE1 HIS A 940 5.511 2.597 -4.622 1.00 71.34 H ATOM 799 HE2 HIS A 940 3.370 3.192 -5.834 1.00 72.94 H ATOM 800 N ARG A 941 0.746 -0.666 0.344 1.00 57.11 N ATOM 801 CA ARG A 941 0.052 -1.670 1.157 1.00 55.94 C ATOM 802 C ARG A 941 -1.244 -1.135 1.786 1.00 58.15 C ATOM 803 O ARG A 941 -2.224 -1.878 1.834 1.00 56.90 O ATOM 804 CB ARG A 941 1.002 -2.196 2.248 1.00 56.27 C ATOM 805 CG ARG A 941 2.156 -3.035 1.684 1.00 60.46 C ATOM 806 CD ARG A 941 3.217 -3.361 2.743 1.00 68.18 C ATOM 807 NE ARG A 941 4.165 -4.372 2.252 1.00 73.45 N ATOM 808 CZ ARG A 941 4.018 -5.707 2.308 1.00 81.37 C ATOM 809 NH1 ARG A 941 2.961 -6.288 2.896 1.00 62.04 N ATOM 810 NH2 ARG A 941 4.956 -6.483 1.753 1.00 66.65 N1+ ATOM 811 H ARG A 941 1.591 -0.278 0.739 1.00 57.11 H ATOM 812 HA ARG A 941 -0.219 -2.508 0.511 1.00 55.94 H ATOM 813 HB3 ARG A 941 0.446 -2.825 2.943 1.00 56.27 H ATOM 814 HB2 ARG A 941 1.388 -1.363 2.836 1.00 56.27 H ATOM 815 HG3 ARG A 941 2.640 -2.439 0.911 1.00 60.46 H ATOM 816 HG2 ARG A 941 1.797 -3.928 1.174 1.00 60.46 H ATOM 817 HD3 ARG A 941 2.794 -3.586 3.722 1.00 68.18 H ATOM 818 HD2 ARG A 941 3.836 -2.474 2.881 1.00 68.18 H ATOM 819 HE ARG A 941 4.974 -4.003 1.765 1.00 73.45 H ATOM 820 HH12 ARG A 941 2.887 -7.298 2.921 1.00 62.04 H ATOM 821 HH11 ARG A 941 2.246 -5.725 3.329 1.00 62.04 H ATOM 822 HH22 ARG A 941 4.856 -7.489 1.785 1.00 66.65 H ATOM 823 HH21 ARG A 941 5.763 -6.083 1.293 1.00 66.65 H ATOM 824 N SER A 942 -1.239 0.131 2.236 1.00 54.55 N ATOM 825 CA SER A 942 -2.417 0.822 2.767 1.00 53.96 C ATOM 826 C SER A 942 -3.462 1.145 1.681 1.00 53.99 C ATOM 827 O SER A 942 -4.658 1.084 1.968 1.00 53.04 O ATOM 828 CB SER A 942 -1.974 2.067 3.564 1.00 59.58 C ATOM 829 OG SER A 942 -1.436 3.085 2.742 1.00 72.10 O ATOM 830 H SER A 942 -0.386 0.673 2.189 1.00 54.55 H ATOM 831 HA SER A 942 -2.895 0.143 3.476 1.00 53.96 H ATOM 832 HB3 SER A 942 -1.237 1.795 4.320 1.00 59.58 H ATOM 833 HB2 SER A 942 -2.827 2.484 4.101 1.00 59.58 H ATOM 834 HG SER A 942 -0.537 2.843 2.506 1.00 72.10 H ATOM 835 N GLY A 943 -2.996 1.435 0.454 1.00 48.43 N ATOM 836 CA GLY A 943 -3.852 1.679 -0.702 1.00 46.49 C ATOM 837 C GLY A 943 -4.391 0.364 -1.290 1.00 48.75 C ATOM 838 O GLY A 943 -5.500 0.360 -1.821 1.00 47.89 O ATOM 839 H GLY A 943 -1.998 1.478 0.302 1.00 48.43 H ATOM 840 HA3 GLY A 943 -3.269 2.198 -1.462 1.00 46.49 H ATOM 841 HA2 GLY A 943 -4.681 2.335 -0.430 1.00 46.49 H ATOM 842 N TRP A 944 -3.627 -0.738 -1.184 1.00 44.46 N ATOM 843 CA TRP A 944 -4.021 -2.081 -1.615 1.00 42.89 C ATOM 844 C TRP A 944 -5.169 -2.670 -0.781 1.00 46.22 C ATOM 845 O TRP A 944 -6.091 -3.245 -1.358 1.00 45.15 O ATOM 846 CB TRP A 944 -2.793 -3.010 -1.631 1.00 42.12 C ATOM 847 CG TRP A 944 -3.080 -4.467 -1.824 1.00 42.65 C ATOM 848 CD1 TRP A 944 -2.885 -5.439 -0.904 1.00 46.33 C ATOM 849 CD2 TRP A 944 -3.681 -5.119 -2.981 1.00 41.21 C ATOM 850 NE1 TRP A 944 -3.284 -6.649 -1.429 1.00 45.34 N ATOM 851 CE2 TRP A 944 -3.782 -6.515 -2.707 1.00 45.67 C ATOM 852 CE3 TRP A 944 -4.149 -4.674 -4.238 1.00 41.70 C ATOM 853 CZ2 TRP A 944 -4.298 -7.428 -3.640 1.00 44.10 C ATOM 854 CZ3 TRP A 944 -4.676 -5.579 -5.179 1.00 42.27 C ATOM 855 CH2 TRP A 944 -4.740 -6.953 -4.884 1.00 43.10 C ATOM 856 H TRP A 944 -2.705 -0.662 -0.777 1.00 44.46 H ATOM 857 HA TRP A 944 -4.393 -2.009 -2.639 1.00 42.89 H ATOM 858 HB3 TRP A 944 -2.239 -2.906 -0.699 1.00 42.12 H ATOM 859 HB2 TRP A 944 -2.112 -2.699 -2.425 1.00 42.12 H ATOM 860 HD1 TRP A 944 -2.471 -5.278 0.081 1.00 46.33 H ATOM 861 HE1 TRP A 944 -3.228 -7.524 -0.922 1.00 45.34 H ATOM 862 HE3 TRP A 944 -4.103 -3.624 -4.481 1.00 41.70 H ATOM 863 HZ2 TRP A 944 -4.352 -8.480 -3.407 1.00 44.10 H ATOM 864 HZ3 TRP A 944 -5.029 -5.218 -6.131 1.00 42.27 H ATOM 865 HH2 TRP A 944 -5.129 -7.641 -5.615 1.00 43.10 H ATOM 866 N LYS A 945 -5.105 -2.485 0.550 1.00 43.92 N ATOM 867 CA LYS A 945 -6.191 -2.822 1.471 1.00 44.34 C ATOM 868 C LYS A 945 -7.476 -2.042 1.160 1.00 46.56 C ATOM 869 O LYS A 945 -8.554 -2.623 1.243 1.00 45.36 O ATOM 870 CB LYS A 945 -5.751 -2.571 2.926 1.00 49.05 C ATOM 871 CG LYS A 945 -4.726 -3.589 3.445 1.00 67.10 C ATOM 872 CD LYS A 945 -4.305 -3.287 4.894 1.00 82.17 C ATOM 873 CE LYS A 945 -3.208 -4.218 5.438 1.00 95.75 C ATOM 874 NZ LYS A 945 -1.895 -3.952 4.822 1.00106.63 N1+ ATOM 875 H LYS A 945 -4.304 -2.017 0.951 1.00 43.92 H ATOM 876 HA LYS A 945 -6.411 -3.885 1.350 1.00 44.34 H ATOM 877 HB3 LYS A 945 -6.625 -2.624 3.579 1.00 49.05 H ATOM 878 HB2 LYS A 945 -5.361 -1.556 3.025 1.00 49.05 H ATOM 879 HG3 LYS A 945 -3.858 -3.605 2.789 1.00 67.10 H ATOM 880 HG2 LYS A 945 -5.156 -4.590 3.397 1.00 67.10 H ATOM 881 HD3 LYS A 945 -5.182 -3.377 5.537 1.00 82.17 H ATOM 882 HD2 LYS A 945 -3.988 -2.245 4.978 1.00 82.17 H ATOM 883 HE3 LYS A 945 -3.481 -5.262 5.281 1.00 95.75 H ATOM 884 HE2 LYS A 945 -3.108 -4.074 6.514 1.00 95.75 H ATOM 885 HZ1 LYS A 945 -1.958 -4.096 3.824 1.00106.63 H ATOM 886 HZ2 LYS A 945 -1.626 -2.996 5.006 1.00106.63 H ATOM 887 HZ3 LYS A 945 -1.206 -4.578 5.214 1.00106.63 H ATOM 888 N GLN A 946 -7.327 -0.768 0.757 1.00 43.11 N ATOM 889 CA GLN A 946 -8.435 0.101 0.379 1.00 42.59 C ATOM 890 C GLN A 946 -9.104 -0.329 -0.944 1.00 44.21 C ATOM 891 O GLN A 946 -10.323 -0.212 -1.029 1.00 44.62 O ATOM 892 CB GLN A 946 -7.949 1.562 0.342 1.00 44.07 C ATOM 893 CG GLN A 946 -9.112 2.570 0.435 1.00 72.22 C ATOM 894 CD GLN A 946 -8.722 4.039 0.262 1.00 92.80 C ATOM 895 OE1 GLN A 946 -9.605 4.886 0.154 1.00 86.97 O ATOM 896 NE2 GLN A 946 -7.426 4.364 0.235 1.00 85.94 N ATOM 897 H GLN A 946 -6.402 -0.366 0.700 1.00 43.11 H ATOM 898 HA GLN A 946 -9.185 0.018 1.169 1.00 42.59 H ATOM 899 HB3 GLN A 946 -7.370 1.733 -0.566 1.00 44.07 H ATOM 900 HB2 GLN A 946 -7.272 1.737 1.180 1.00 44.07 H ATOM 901 HG3 GLN A 946 -9.613 2.463 1.399 1.00 72.22 H ATOM 902 HG2 GLN A 946 -9.861 2.347 -0.322 1.00 72.22 H ATOM 903 HE22 GLN A 946 -7.136 5.321 0.106 1.00 85.94 H ATOM 904 HE21 GLN A 946 -6.724 3.644 0.323 1.00 85.94 H ATOM 905 N GLU A 947 -8.341 -0.874 -1.917 1.00 38.42 N ATOM 906 CA GLU A 947 -8.896 -1.497 -3.128 1.00 36.42 C ATOM 907 C GLU A 947 -9.773 -2.720 -2.812 1.00 41.24 C ATOM 908 O GLU A 947 -10.865 -2.832 -3.369 1.00 41.44 O ATOM 909 CB GLU A 947 -7.793 -1.835 -4.165 1.00 36.47 C ATOM 910 CG GLU A 947 -8.321 -2.647 -5.383 1.00 37.83 C ATOM 911 CD GLU A 947 -7.332 -2.963 -6.510 1.00 51.81 C ATOM 912 OE1 GLU A 947 -6.118 -2.704 -6.360 1.00 50.51 O ATOM 913 OE2 GLU A 947 -7.819 -3.483 -7.537 1.00 44.67 O1- ATOM 914 H GLU A 947 -7.338 -0.927 -1.800 1.00 38.42 H ATOM 915 HA GLU A 947 -9.549 -0.755 -3.593 1.00 36.42 H ATOM 916 HB3 GLU A 947 -6.983 -2.382 -3.682 1.00 36.47 H ATOM 917 HB2 GLU A 947 -7.355 -0.901 -4.515 1.00 36.47 H ATOM 918 HG3 GLU A 947 -9.177 -2.127 -5.813 1.00 37.83 H ATOM 919 HG2 GLU A 947 -8.692 -3.617 -5.051 1.00 37.83 H ATOM 920 N ILE A 948 -9.272 -3.599 -1.926 1.00 37.07 N ATOM 921 CA ILE A 948 -9.967 -4.801 -1.461 1.00 37.44 C ATOM 922 C ILE A 948 -11.283 -4.464 -0.730 1.00 42.50 C ATOM 923 O ILE A 948 -12.288 -5.117 -1.003 1.00 40.78 O ATOM 924 CB ILE A 948 -9.054 -5.688 -0.558 1.00 40.85 C ATOM 925 CG1 ILE A 948 -7.887 -6.291 -1.375 1.00 40.33 C ATOM 926 CG2 ILE A 948 -9.796 -6.814 0.199 1.00 41.59 C ATOM 927 CD1 ILE A 948 -6.671 -6.699 -0.527 1.00 45.34 C ATOM 928 H ILE A 948 -8.358 -3.431 -1.528 1.00 37.07 H ATOM 929 HA ILE A 948 -10.228 -5.382 -2.348 1.00 37.44 H ATOM 930 HB ILE A 948 -8.610 -5.037 0.195 1.00 40.85 H ATOM 931 HG13 ILE A 948 -7.538 -5.577 -2.122 1.00 40.33 H ATOM 932 HG12 ILE A 948 -8.245 -7.151 -1.939 1.00 40.33 H ATOM 933 HG21 ILE A 948 -9.110 -7.460 0.744 1.00 41.59 H ATOM 934 HG22 ILE A 948 -10.494 -6.421 0.937 1.00 41.59 H ATOM 935 HG23 ILE A 948 -10.361 -7.442 -0.491 1.00 41.59 H ATOM 936 HD11 ILE A 948 -6.199 -7.594 -0.931 1.00 45.34 H ATOM 937 HD12 ILE A 948 -5.924 -5.906 -0.520 1.00 45.34 H ATOM 938 HD13 ILE A 948 -6.932 -6.902 0.510 1.00 45.34 H ATOM 939 N ASP A 949 -11.260 -3.427 0.129 1.00 41.37 N ATOM 940 CA ASP A 949 -12.433 -2.867 0.812 1.00 43.58 C ATOM 941 C ASP A 949 -13.472 -2.293 -0.166 1.00 46.27 C ATOM 942 O ASP A 949 -14.650 -2.611 -0.023 1.00 45.58 O ATOM 943 CB ASP A 949 -12.082 -1.793 1.877 1.00 47.36 C ATOM 944 CG ASP A 949 -11.137 -2.216 3.016 1.00 66.46 C ATOM 945 OD1 ASP A 949 -11.033 -3.431 3.296 1.00 66.64 O ATOM 946 OD2 ASP A 949 -10.616 -1.293 3.681 1.00 76.34 O1- ATOM 947 H ASP A 949 -10.380 -2.965 0.319 1.00 41.37 H ATOM 948 HA ASP A 949 -12.919 -3.699 1.326 1.00 43.58 H ATOM 949 HB3 ASP A 949 -13.001 -1.432 2.342 1.00 47.36 H ATOM 950 HB2 ASP A 949 -11.627 -0.936 1.377 1.00 47.36 H ATOM 951 N ILE A 950 -13.021 -1.484 -1.143 1.00 42.07 N ATOM 952 CA ILE A 950 -13.865 -0.856 -2.165 1.00 41.21 C ATOM 953 C ILE A 950 -14.584 -1.879 -3.065 1.00 44.57 C ATOM 954 O ILE A 950 -15.796 -1.776 -3.223 1.00 44.89 O ATOM 955 CB ILE A 950 -13.074 0.179 -3.030 1.00 43.50 C ATOM 956 CG1 ILE A 950 -12.772 1.447 -2.199 1.00 44.25 C ATOM 957 CG2 ILE A 950 -13.743 0.588 -4.366 1.00 43.82 C ATOM 958 CD1 ILE A 950 -11.740 2.389 -2.835 1.00 47.81 C ATOM 959 H ILE A 950 -12.034 -1.263 -1.187 1.00 42.07 H ATOM 960 HA ILE A 950 -14.646 -0.310 -1.630 1.00 41.21 H ATOM 961 HB ILE A 950 -12.115 -0.277 -3.283 1.00 43.50 H ATOM 962 HG13 ILE A 950 -12.436 1.183 -1.197 1.00 44.25 H ATOM 963 HG12 ILE A 950 -13.700 1.993 -2.049 1.00 44.25 H ATOM 964 HG21 ILE A 950 -13.176 1.363 -4.881 1.00 43.82 H ATOM 965 HG22 ILE A 950 -13.808 -0.244 -5.066 1.00 43.82 H ATOM 966 HG23 ILE A 950 -14.750 0.974 -4.203 1.00 43.82 H ATOM 967 HD11 ILE A 950 -11.203 2.958 -2.077 1.00 47.81 H ATOM 968 HD12 ILE A 950 -11.002 1.842 -3.421 1.00 47.81 H ATOM 969 HD13 ILE A 950 -12.224 3.110 -3.494 1.00 47.81 H ATOM 970 N LEU A 951 -13.844 -2.860 -3.609 1.00 41.27 N ATOM 971 CA LEU A 951 -14.394 -3.889 -4.496 1.00 41.85 C ATOM 972 C LEU A 951 -15.322 -4.889 -3.774 1.00 47.62 C ATOM 973 O LEU A 951 -16.249 -5.398 -4.403 1.00 47.54 O ATOM 974 CB LEU A 951 -13.231 -4.574 -5.249 1.00 41.42 C ATOM 975 CG LEU A 951 -13.649 -5.508 -6.410 1.00 46.53 C ATOM 976 CD1 LEU A 951 -14.414 -4.752 -7.521 1.00 46.18 C ATOM 977 CD2 LEU A 951 -12.432 -6.278 -6.956 1.00 49.35 C ATOM 978 H LEU A 951 -12.847 -2.896 -3.436 1.00 41.27 H ATOM 979 HA LEU A 951 -15.012 -3.367 -5.227 1.00 41.85 H ATOM 980 HB3 LEU A 951 -12.633 -5.137 -4.530 1.00 41.42 H ATOM 981 HB2 LEU A 951 -12.564 -3.808 -5.649 1.00 41.42 H ATOM 982 HG LEU A 951 -14.325 -6.266 -6.019 1.00 46.53 H ATOM 983 HD11 LEU A 951 -14.019 -4.940 -8.518 1.00 46.18 H ATOM 984 HD12 LEU A 951 -15.464 -5.047 -7.534 1.00 46.18 H ATOM 985 HD13 LEU A 951 -14.385 -3.672 -7.381 1.00 46.18 H ATOM 986 HD21 LEU A 951 -12.413 -6.333 -8.044 1.00 49.35 H ATOM 987 HD22 LEU A 951 -11.496 -5.819 -6.643 1.00 49.35 H ATOM 988 HD23 LEU A 951 -12.429 -7.303 -6.584 1.00 49.35 H ATOM 989 N ARG A 952 -15.086 -5.118 -2.470 1.00 45.43 N ATOM 990 CA ARG A 952 -15.912 -5.959 -1.601 1.00 47.25 C ATOM 991 C ARG A 952 -17.298 -5.357 -1.286 1.00 52.09 C ATOM 992 O ARG A 952 -18.247 -6.129 -1.145 1.00 53.68 O ATOM 993 CB ARG A 952 -15.091 -6.318 -0.340 1.00 49.60 C ATOM 994 CG ARG A 952 -15.843 -7.068 0.779 1.00 64.86 C ATOM 995 CD ARG A 952 -14.937 -7.823 1.770 1.00 76.56 C ATOM 996 NE ARG A 952 -13.881 -6.986 2.376 1.00 87.65 N ATOM 997 CZ ARG A 952 -12.715 -7.407 2.908 1.00104.51 C ATOM 998 NH1 ARG A 952 -12.352 -8.699 2.914 1.00 93.37 N ATOM 999 NH2 ARG A 952 -11.884 -6.512 3.453 1.00 92.17 N1+ ATOM 1000 H ARG A 952 -14.301 -4.663 -2.025 1.00 45.43 H ATOM 1001 HA ARG A 952 -16.101 -6.892 -2.134 1.00 47.25 H ATOM 1002 HB3 ARG A 952 -14.697 -5.398 0.092 1.00 49.60 H ATOM 1003 HB2 ARG A 952 -14.226 -6.906 -0.649 1.00 49.60 H ATOM 1004 HG3 ARG A 952 -16.421 -7.837 0.264 1.00 64.86 H ATOM 1005 HG2 ARG A 952 -16.577 -6.448 1.297 1.00 64.86 H ATOM 1006 HD3 ARG A 952 -14.592 -8.768 1.357 1.00 76.56 H ATOM 1007 HD2 ARG A 952 -15.557 -8.089 2.626 1.00 76.56 H ATOM 1008 HE ARG A 952 -14.078 -5.996 2.402 1.00 87.65 H ATOM 1009 HH12 ARG A 952 -11.476 -8.988 3.325 1.00 93.37 H ATOM 1010 HH11 ARG A 952 -12.951 -9.389 2.485 1.00 93.37 H ATOM 1011 HH22 ARG A 952 -12.087 -5.519 3.426 1.00 92.17 H ATOM 1012 HH21 ARG A 952 -11.009 -6.805 3.861 1.00 92.17 H ATOM 1013 N THR A 953 -17.407 -4.018 -1.203 1.00 47.85 N ATOM 1014 CA THR A 953 -18.679 -3.317 -0.978 1.00 48.24 C ATOM 1015 C THR A 953 -19.466 -3.052 -2.282 1.00 50.96 C ATOM 1016 O THR A 953 -20.681 -2.871 -2.196 1.00 52.21 O ATOM 1017 CB THR A 953 -18.474 -1.955 -0.257 1.00 56.81 C ATOM 1018 OG1 THR A 953 -17.729 -1.035 -1.034 1.00 60.06 O ATOM 1019 CG2 THR A 953 -17.848 -2.087 1.139 1.00 56.45 C ATOM 1020 H THR A 953 -16.592 -3.432 -1.323 1.00 47.85 H ATOM 1021 HA THR A 953 -19.313 -3.933 -0.338 1.00 48.24 H ATOM 1022 HB THR A 953 -19.453 -1.494 -0.115 1.00 56.81 H ATOM 1023 HG1 THR A 953 -17.579 -0.237 -0.518 1.00 60.06 H ATOM 1024 HG21 THR A 953 -17.701 -1.110 1.601 1.00 56.45 H ATOM 1025 HG22 THR A 953 -18.495 -2.666 1.798 1.00 56.45 H ATOM 1026 HG23 THR A 953 -16.885 -2.591 1.111 1.00 56.45 H ATOM 1027 N LEU A 954 -18.797 -3.053 -3.450 1.00 45.03 N ATOM 1028 CA LEU A 954 -19.441 -2.879 -4.754 1.00 43.59 C ATOM 1029 C LEU A 954 -20.046 -4.200 -5.254 1.00 47.51 C ATOM 1030 O LEU A 954 -19.407 -5.248 -5.151 1.00 46.90 O ATOM 1031 CB LEU A 954 -18.416 -2.343 -5.779 1.00 41.91 C ATOM 1032 CG LEU A 954 -17.939 -0.893 -5.544 1.00 44.98 C ATOM 1033 CD1 LEU A 954 -16.672 -0.604 -6.360 1.00 43.77 C ATOM 1034 CD2 LEU A 954 -19.026 0.163 -5.817 1.00 45.62 C ATOM 1035 H LEU A 954 -17.798 -3.203 -3.455 1.00 45.03 H ATOM 1036 HA LEU A 954 -20.251 -2.157 -4.649 1.00 43.59 H ATOM 1037 HB3 LEU A 954 -18.832 -2.405 -6.787 1.00 41.91 H ATOM 1038 HB2 LEU A 954 -17.551 -3.010 -5.778 1.00 41.91 H ATOM 1039 HG LEU A 954 -17.680 -0.790 -4.492 1.00 44.98 H ATOM 1040 HD11 LEU A 954 -16.372 0.440 -6.268 1.00 43.77 H ATOM 1041 HD12 LEU A 954 -15.835 -1.211 -6.014 1.00 43.77 H ATOM 1042 HD13 LEU A 954 -16.821 -0.822 -7.417 1.00 43.77 H ATOM 1043 HD21 LEU A 954 -18.846 1.060 -5.227 1.00 45.62 H ATOM 1044 HD22 LEU A 954 -19.047 0.454 -6.867 1.00 45.62 H ATOM 1045 HD23 LEU A 954 -20.022 -0.184 -5.556 1.00 45.62 H ATOM 1046 N TYR A 955 -21.260 -4.105 -5.819 1.00 44.63 N ATOM 1047 CA TYR A 955 -21.983 -5.219 -6.422 1.00 45.07 C ATOM 1048 C TYR A 955 -22.881 -4.667 -7.538 1.00 45.96 C ATOM 1049 O TYR A 955 -23.879 -4.007 -7.245 1.00 46.41 O ATOM 1050 CB TYR A 955 -22.766 -5.994 -5.338 1.00 49.65 C ATOM 1051 CG TYR A 955 -23.413 -7.280 -5.825 1.00 54.91 C ATOM 1052 CD1 TYR A 955 -22.690 -8.491 -5.774 1.00 57.41 C ATOM 1053 CD2 TYR A 955 -24.729 -7.275 -6.334 1.00 57.57 C ATOM 1054 CE1 TYR A 955 -23.279 -9.687 -6.228 1.00 59.75 C ATOM 1055 CE2 TYR A 955 -25.314 -8.469 -6.797 1.00 60.10 C ATOM 1056 CZ TYR A 955 -24.590 -9.676 -6.742 1.00 68.68 C ATOM 1057 OH TYR A 955 -25.161 -10.833 -7.187 1.00 72.06 O ATOM 1058 H TYR A 955 -21.733 -3.211 -5.844 1.00 44.63 H ATOM 1059 HA TYR A 955 -21.264 -5.905 -6.873 1.00 45.07 H ATOM 1060 HB3 TYR A 955 -23.529 -5.356 -4.888 1.00 49.65 H ATOM 1061 HB2 TYR A 955 -22.091 -6.258 -4.522 1.00 49.65 H ATOM 1062 HD1 TYR A 955 -21.681 -8.504 -5.389 1.00 57.41 H ATOM 1063 HD2 TYR A 955 -25.291 -6.353 -6.378 1.00 57.57 H ATOM 1064 HE1 TYR A 955 -22.717 -10.608 -6.181 1.00 59.75 H ATOM 1065 HE2 TYR A 955 -26.320 -8.458 -7.190 1.00 60.10 H ATOM 1066 HH TYR A 955 -24.592 -11.599 -7.087 1.00 72.06 H ATOM 1067 N HIS A 956 -22.500 -4.944 -8.794 1.00 39.68 N ATOM 1068 CA HIS A 956 -23.212 -4.512 -9.996 1.00 38.26 C ATOM 1069 C HIS A 956 -22.866 -5.445 -11.162 1.00 41.07 C ATOM 1070 O HIS A 956 -21.760 -5.986 -11.208 1.00 39.48 O ATOM 1071 CB HIS A 956 -22.844 -3.047 -10.318 1.00 37.69 C ATOM 1072 CG HIS A 956 -23.836 -2.324 -11.193 1.00 40.30 C ATOM 1073 ND1 HIS A 956 -23.676 -2.210 -12.577 1.00 40.74 N ATOM 1074 CD2 HIS A 956 -25.002 -1.686 -10.825 1.00 42.24 C ATOM 1075 CE1 HIS A 956 -24.733 -1.519 -12.984 1.00 40.29 C ATOM 1076 NE2 HIS A 956 -25.550 -1.179 -11.989 1.00 41.53 N ATOM 1077 H HIS A 956 -21.665 -5.494 -8.953 1.00 39.68 H ATOM 1078 HA HIS A 956 -24.284 -4.585 -9.796 1.00 38.26 H ATOM 1079 HB3 HIS A 956 -21.857 -2.986 -10.778 1.00 37.69 H ATOM 1080 HB2 HIS A 956 -22.772 -2.476 -9.395 1.00 37.69 H ATOM 1081 HD2 HIS A 956 -25.467 -1.557 -9.859 1.00 42.24 H ATOM 1082 HE1 HIS A 956 -24.909 -1.252 -14.014 1.00 40.29 H ATOM 1083 HE2 HIS A 956 -26.411 -0.655 -12.072 1.00 41.53 H ATOM 1084 N GLU A 957 -23.808 -5.580 -12.110 1.00 37.79 N ATOM 1085 CA GLU A 957 -23.646 -6.366 -13.338 1.00 37.07 C ATOM 1086 C GLU A 957 -22.581 -5.811 -14.309 1.00 38.36 C ATOM 1087 O GLU A 957 -22.069 -6.584 -15.119 1.00 38.29 O ATOM 1088 CB GLU A 957 -25.017 -6.521 -14.032 1.00 39.83 C ATOM 1089 CG GLU A 957 -25.639 -5.202 -14.545 1.00 51.33 C ATOM 1090 CD GLU A 957 -26.973 -5.377 -15.283 1.00 75.08 C ATOM 1091 OE1 GLU A 957 -27.876 -4.551 -15.023 1.00 76.02 O ATOM 1092 OE2 GLU A 957 -27.077 -6.311 -16.109 1.00 61.54 O1- ATOM 1093 H GLU A 957 -24.697 -5.109 -11.999 1.00 37.79 H ATOM 1094 HA GLU A 957 -23.315 -7.363 -13.038 1.00 37.07 H ATOM 1095 HB3 GLU A 957 -25.713 -7.007 -13.347 1.00 39.83 H ATOM 1096 HB2 GLU A 957 -24.898 -7.214 -14.866 1.00 39.83 H ATOM 1097 HG3 GLU A 957 -24.955 -4.731 -15.244 1.00 51.33 H ATOM 1098 HG2 GLU A 957 -25.753 -4.493 -13.725 1.00 51.33 H ATOM 1099 N HIS A 958 -22.266 -4.507 -14.202 1.00 33.06 N ATOM 1100 CA HIS A 958 -21.263 -3.805 -15.008 1.00 30.23 C ATOM 1101 C HIS A 958 -20.045 -3.370 -14.175 1.00 34.52 C ATOM 1102 O HIS A 958 -19.363 -2.415 -14.546 1.00 33.24 O ATOM 1103 CB HIS A 958 -21.913 -2.635 -15.775 1.00 29.49 C ATOM 1104 CG HIS A 958 -23.094 -3.030 -16.626 1.00 32.84 C ATOM 1105 ND1 HIS A 958 -23.069 -4.116 -17.483 1.00 34.50 N ATOM 1106 CD2 HIS A 958 -24.367 -2.515 -16.722 1.00 35.61 C ATOM 1107 CE1 HIS A 958 -24.286 -4.227 -18.018 1.00 34.74 C ATOM 1108 NE2 HIS A 958 -25.123 -3.285 -17.606 1.00 35.88 N ATOM 1109 H HIS A 958 -22.751 -3.939 -13.519 1.00 33.06 H ATOM 1110 HA HIS A 958 -20.862 -4.495 -15.749 1.00 30.23 H ATOM 1111 HB3 HIS A 958 -21.178 -2.172 -16.435 1.00 29.49 H ATOM 1112 HB2 HIS A 958 -22.237 -1.860 -15.079 1.00 29.49 H ATOM 1113 HD1 HIS A 958 -22.273 -4.714 -17.661 1.00 34.50 H ATOM 1114 HD2 HIS A 958 -24.807 -1.676 -16.210 1.00 35.61 H ATOM 1115 HE1 HIS A 958 -24.562 -4.994 -18.726 1.00 34.74 H ATOM 1116 N ILE A 959 -19.758 -4.122 -13.102 1.00 33.55 N ATOM 1117 CA ILE A 959 -18.513 -4.085 -12.339 1.00 33.44 C ATOM 1118 C ILE A 959 -18.048 -5.543 -12.152 1.00 38.25 C ATOM 1119 O ILE A 959 -18.891 -6.426 -11.973 1.00 38.75 O ATOM 1120 CB ILE A 959 -18.700 -3.369 -10.959 1.00 37.20 C ATOM 1121 CG1 ILE A 959 -18.910 -1.848 -11.173 1.00 36.98 C ATOM 1122 CG2 ILE A 959 -17.554 -3.612 -9.949 1.00 38.30 C ATOM 1123 CD1 ILE A 959 -19.229 -1.049 -9.902 1.00 43.20 C ATOM 1124 H ILE A 959 -20.381 -4.880 -12.858 1.00 33.55 H ATOM 1125 HA ILE A 959 -17.747 -3.561 -12.911 1.00 33.44 H ATOM 1126 HB ILE A 959 -19.610 -3.762 -10.502 1.00 37.20 H ATOM 1127 HG13 ILE A 959 -19.722 -1.677 -11.879 1.00 36.98 H ATOM 1128 HG12 ILE A 959 -18.021 -1.424 -11.638 1.00 36.98 H ATOM 1129 HG21 ILE A 959 -17.680 -3.036 -9.034 1.00 38.30 H ATOM 1130 HG22 ILE A 959 -17.504 -4.652 -9.633 1.00 38.30 H ATOM 1131 HG23 ILE A 959 -16.590 -3.347 -10.379 1.00 38.30 H ATOM 1132 HD11 ILE A 959 -19.719 -0.110 -10.158 1.00 43.20 H ATOM 1133 HD12 ILE A 959 -19.889 -1.604 -9.235 1.00 43.20 H ATOM 1134 HD13 ILE A 959 -18.323 -0.797 -9.352 1.00 43.20 H ATOM 1135 N ILE A 960 -16.722 -5.778 -12.199 1.00 34.04 N ATOM 1136 CA ILE A 960 -16.103 -7.089 -11.969 1.00 34.30 C ATOM 1137 C ILE A 960 -16.404 -7.598 -10.542 1.00 39.83 C ATOM 1138 O ILE A 960 -16.171 -6.877 -9.571 1.00 39.81 O ATOM 1139 CB ILE A 960 -14.562 -7.077 -12.223 1.00 35.69 C ATOM 1140 CG1 ILE A 960 -13.980 -8.512 -12.252 1.00 36.05 C ATOM 1141 CG2 ILE A 960 -13.761 -6.184 -11.246 1.00 35.48 C ATOM 1142 CD1 ILE A 960 -12.566 -8.631 -12.844 1.00 37.96 C ATOM 1143 H ILE A 960 -16.085 -5.009 -12.369 1.00 34.04 H ATOM 1144 HA ILE A 960 -16.557 -7.774 -12.688 1.00 34.30 H ATOM 1145 HB ILE A 960 -14.424 -6.656 -13.220 1.00 35.69 H ATOM 1146 HG13 ILE A 960 -14.642 -9.150 -12.839 1.00 36.05 H ATOM 1147 HG12 ILE A 960 -13.984 -8.936 -11.247 1.00 36.05 H ATOM 1148 HG21 ILE A 960 -12.742 -6.020 -11.594 1.00 35.48 H ATOM 1149 HG22 ILE A 960 -14.222 -5.203 -11.131 1.00 35.48 H ATOM 1150 HG23 ILE A 960 -13.683 -6.633 -10.257 1.00 35.48 H ATOM 1151 HD11 ILE A 960 -11.934 -9.264 -12.221 1.00 37.96 H ATOM 1152 HD12 ILE A 960 -12.597 -9.084 -13.834 1.00 37.96 H ATOM 1153 HD13 ILE A 960 -12.065 -7.670 -12.948 1.00 37.96 H ATOM 1154 N LYS A 961 -16.984 -8.804 -10.450 1.00 38.47 N ATOM 1155 CA LYS A 961 -17.508 -9.334 -9.197 1.00 40.15 C ATOM 1156 C LYS A 961 -16.382 -9.870 -8.302 1.00 44.21 C ATOM 1157 O LYS A 961 -15.549 -10.660 -8.753 1.00 42.58 O ATOM 1158 CB LYS A 961 -18.572 -10.416 -9.471 1.00 43.99 C ATOM 1159 CG LYS A 961 -19.531 -10.611 -8.279 1.00 65.82 C ATOM 1160 CD LYS A 961 -20.376 -11.889 -8.358 1.00 82.27 C ATOM 1161 CE LYS A 961 -19.590 -13.141 -7.933 1.00 98.09 C ATOM 1162 NZ LYS A 961 -20.439 -14.344 -7.951 1.00108.33 N1+ ATOM 1163 H LYS A 961 -17.162 -9.351 -11.285 1.00 38.47 H ATOM 1164 HA LYS A 961 -18.005 -8.516 -8.672 1.00 40.15 H ATOM 1165 HB3 LYS A 961 -18.087 -11.352 -9.750 1.00 43.99 H ATOM 1166 HB2 LYS A 961 -19.179 -10.126 -10.330 1.00 43.99 H ATOM 1167 HG3 LYS A 961 -20.200 -9.751 -8.233 1.00 65.82 H ATOM 1168 HG2 LYS A 961 -18.986 -10.605 -7.335 1.00 65.82 H ATOM 1169 HD3 LYS A 961 -20.746 -12.012 -9.378 1.00 82.27 H ATOM 1170 HD2 LYS A 961 -21.259 -11.767 -7.729 1.00 82.27 H ATOM 1171 HE3 LYS A 961 -19.197 -13.012 -6.923 1.00 98.09 H ATOM 1172 HE2 LYS A 961 -18.735 -13.304 -8.589 1.00 98.09 H ATOM 1173 HZ1 LYS A 961 -20.777 -14.500 -8.890 1.00108.33 H ATOM 1174 HZ2 LYS A 961 -19.902 -15.143 -7.647 1.00108.33 H ATOM 1175 HZ3 LYS A 961 -21.224 -14.213 -7.329 1.00108.33 H ATOM 1176 N TYR A 962 -16.430 -9.444 -7.032 1.00 42.43 N ATOM 1177 CA TYR A 962 -15.610 -9.940 -5.935 1.00 43.53 C ATOM 1178 C TYR A 962 -16.001 -11.390 -5.592 1.00 47.09 C ATOM 1179 O TYR A 962 -17.139 -11.625 -5.182 1.00 48.07 O ATOM 1180 CB TYR A 962 -15.807 -8.977 -4.743 1.00 46.00 C ATOM 1181 CG TYR A 962 -15.052 -9.322 -3.473 1.00 48.99 C ATOM 1182 CD1 TYR A 962 -13.693 -8.973 -3.349 1.00 50.72 C ATOM 1183 CD2 TYR A 962 -15.708 -9.972 -2.407 1.00 51.43 C ATOM 1184 CE1 TYR A 962 -12.986 -9.292 -2.173 1.00 52.08 C ATOM 1185 CE2 TYR A 962 -15.003 -10.287 -1.231 1.00 53.15 C ATOM 1186 CZ TYR A 962 -13.638 -9.957 -1.118 1.00 59.98 C ATOM 1187 OH TYR A 962 -12.946 -10.296 0.007 1.00 63.78 O ATOM 1188 H TYR A 962 -17.144 -8.781 -6.769 1.00 42.43 H ATOM 1189 HA TYR A 962 -14.562 -9.907 -6.242 1.00 43.53 H ATOM 1190 HB3 TYR A 962 -16.868 -8.902 -4.498 1.00 46.00 H ATOM 1191 HB2 TYR A 962 -15.510 -7.972 -5.041 1.00 46.00 H ATOM 1192 HD1 TYR A 962 -13.193 -8.463 -4.159 1.00 50.72 H ATOM 1193 HD2 TYR A 962 -16.752 -10.238 -2.492 1.00 51.43 H ATOM 1194 HE1 TYR A 962 -11.942 -9.032 -2.085 1.00 52.08 H ATOM 1195 HE2 TYR A 962 -15.506 -10.796 -0.421 1.00 53.15 H ATOM 1196 HH TYR A 962 -12.006 -10.107 -0.068 1.00 63.78 H ATOM 1197 N LYS A 963 -15.056 -12.326 -5.771 1.00 42.37 N ATOM 1198 CA LYS A 963 -15.203 -13.726 -5.366 1.00 42.56 C ATOM 1199 C LYS A 963 -14.894 -13.913 -3.870 1.00 48.47 C ATOM 1200 O LYS A 963 -15.618 -14.649 -3.202 1.00 50.00 O ATOM 1201 CB LYS A 963 -14.273 -14.612 -6.220 1.00 43.06 C ATOM 1202 CG LYS A 963 -14.767 -14.929 -7.644 1.00 48.30 C ATOM 1203 CD LYS A 963 -15.641 -16.192 -7.735 1.00 61.25 C ATOM 1204 CE LYS A 963 -15.976 -16.567 -9.192 1.00 72.82 C ATOM 1205 NZ LYS A 963 -16.598 -17.901 -9.298 1.00 84.70 N1+ ATOM 1206 H LYS A 963 -14.146 -12.058 -6.119 1.00 42.37 H ATOM 1207 HA LYS A 963 -16.234 -14.043 -5.540 1.00 42.56 H ATOM 1208 HB3 LYS A 963 -14.079 -15.557 -5.715 1.00 43.06 H ATOM 1209 HB2 LYS A 963 -13.305 -14.125 -6.282 1.00 43.06 H ATOM 1210 HG3 LYS A 963 -13.891 -15.083 -8.273 1.00 48.30 H ATOM 1211 HG2 LYS A 963 -15.294 -14.072 -8.064 1.00 48.30 H ATOM 1212 HD3 LYS A 963 -16.561 -16.038 -7.170 1.00 61.25 H ATOM 1213 HD2 LYS A 963 -15.118 -17.020 -7.253 1.00 61.25 H ATOM 1214 HE3 LYS A 963 -15.071 -16.580 -9.798 1.00 72.82 H ATOM 1215 HE2 LYS A 963 -16.640 -15.822 -9.633 1.00 72.82 H ATOM 1216 HZ1 LYS A 963 -17.463 -17.922 -8.778 1.00 84.70 H ATOM 1217 HZ2 LYS A 963 -16.786 -18.114 -10.268 1.00 84.70 H ATOM 1218 HZ3 LYS A 963 -15.968 -18.599 -8.928 1.00 84.70 H ATOM 1219 N GLY A 964 -13.828 -13.257 -3.383 1.00 44.37 N ATOM 1220 CA GLY A 964 -13.322 -13.425 -2.026 1.00 45.35 C ATOM 1221 C GLY A 964 -11.876 -12.923 -1.976 1.00 49.58 C ATOM 1222 O GLY A 964 -11.436 -12.157 -2.835 1.00 45.71 O ATOM 1223 H GLY A 964 -13.284 -12.660 -3.993 1.00 44.37 H ATOM 1224 HA3 GLY A 964 -13.348 -14.475 -1.734 1.00 45.35 H ATOM 1225 HA2 GLY A 964 -13.937 -12.871 -1.318 1.00 45.35 H ATOM 1226 N CYS A 965 -11.142 -13.356 -0.943 1.00 49.54 N ATOM 1227 CA CYS A 965 -9.711 -13.105 -0.776 1.00 51.02 C ATOM 1228 C CYS A 965 -8.996 -14.425 -0.468 1.00 57.60 C ATOM 1229 O CYS A 965 -9.612 -15.360 0.039 1.00 57.77 O ATOM 1230 CB CYS A 965 -9.421 -12.070 0.332 1.00 52.68 C ATOM 1231 SG CYS A 965 -9.626 -10.388 -0.314 1.00 55.96 S ATOM 1232 H CYS A 965 -11.563 -13.969 -0.256 1.00 49.54 H ATOM 1233 HA CYS A 965 -9.296 -12.749 -1.718 1.00 51.02 H ATOM 1234 HB3 CYS A 965 -8.393 -12.146 0.688 1.00 52.68 H ATOM 1235 HB2 CYS A 965 -10.070 -12.219 1.196 1.00 52.68 H ATOM 1236 HG CYS A 965 -8.572 -10.428 -1.135 1.00 55.96 H ATOM 1237 N CYS A 966 -7.692 -14.458 -0.772 1.00 56.83 N ATOM 1238 CA CYS A 966 -6.805 -15.582 -0.501 1.00 59.37 C ATOM 1239 C CYS A 966 -5.684 -15.111 0.433 1.00 64.61 C ATOM 1240 O CYS A 966 -5.062 -14.084 0.157 1.00 62.66 O ATOM 1241 CB CYS A 966 -6.273 -16.194 -1.818 1.00 59.95 C ATOM 1242 SG CYS A 966 -5.028 -17.487 -1.549 1.00 65.77 S ATOM 1243 H CYS A 966 -7.257 -13.642 -1.183 1.00 56.83 H ATOM 1244 HA CYS A 966 -7.354 -16.359 0.028 1.00 59.37 H ATOM 1245 HB3 CYS A 966 -5.833 -15.427 -2.450 1.00 59.95 H ATOM 1246 HB2 CYS A 966 -7.087 -16.624 -2.397 1.00 59.95 H ATOM 1247 HG CYS A 966 -5.856 -18.347 -0.947 1.00 65.77 H ATOM 1248 N GLU A 967 -5.426 -15.894 1.495 1.00 64.28 N ATOM 1249 CA GLU A 967 -4.285 -15.722 2.393 1.00 65.86 C ATOM 1250 C GLU A 967 -2.977 -16.001 1.633 1.00 70.57 C ATOM 1251 O GLU A 967 -2.751 -17.140 1.218 1.00 70.73 O ATOM 1252 CB GLU A 967 -4.432 -16.675 3.601 1.00 69.10 C ATOM 1253 CG GLU A 967 -3.299 -16.537 4.661 1.00 81.26 C ATOM 1254 CD GLU A 967 -2.819 -17.832 5.345 1.00 98.19 C ATOM 1255 OE1 GLU A 967 -1.791 -17.730 6.051 1.00 78.88 O ATOM 1256 OE2 GLU A 967 -3.452 -18.898 5.170 1.00 93.22 O1- ATOM 1257 H GLU A 967 -5.983 -16.723 1.647 1.00 64.28 H ATOM 1258 HA GLU A 967 -4.285 -14.693 2.759 1.00 65.86 H ATOM 1259 HB3 GLU A 967 -4.506 -17.692 3.214 1.00 69.10 H ATOM 1260 HB2 GLU A 967 -5.388 -16.487 4.092 1.00 69.10 H ATOM 1261 HG3 GLU A 967 -3.640 -15.856 5.442 1.00 81.26 H ATOM 1262 HG2 GLU A 967 -2.419 -16.055 4.236 1.00 81.26 H ATOM 1263 N ASP A 968 -2.146 -14.959 1.486 1.00 66.99 N ATOM 1264 CA ASP A 968 -0.819 -15.061 0.893 1.00 67.07 C ATOM 1265 C ASP A 968 0.183 -15.084 2.058 1.00 72.70 C ATOM 1266 O ASP A 968 0.385 -14.059 2.713 1.00 72.95 O ATOM 1267 CB ASP A 968 -0.562 -13.898 -0.102 1.00 67.90 C ATOM 1268 CG ASP A 968 0.531 -14.115 -1.163 1.00 83.41 C ATOM 1269 OD1 ASP A 968 1.212 -15.166 -1.136 1.00 85.94 O ATOM 1270 OD2 ASP A 968 0.684 -13.199 -2.001 1.00 90.83 O1- ATOM 1271 H ASP A 968 -2.394 -14.052 1.856 1.00 66.99 H ATOM 1272 HA ASP A 968 -0.742 -16.003 0.347 1.00 67.07 H ATOM 1273 HB3 ASP A 968 -0.318 -12.982 0.436 1.00 67.90 H ATOM 1274 HB2 ASP A 968 -1.498 -13.674 -0.611 1.00 67.90 H ATOM 1275 N ALA A 969 0.769 -16.269 2.300 1.00 69.93 N ATOM 1276 CA ALA A 969 1.803 -16.496 3.313 1.00 70.98 C ATOM 1277 C ALA A 969 3.133 -15.800 2.972 1.00 74.28 C ATOM 1278 O ALA A 969 3.798 -15.301 3.880 1.00 74.55 O ATOM 1279 CB ALA A 969 1.999 -18.007 3.503 1.00 72.54 C ATOM 1280 H ALA A 969 0.520 -17.067 1.734 1.00 69.93 H ATOM 1281 HA ALA A 969 1.442 -16.082 4.258 1.00 70.98 H ATOM 1282 HB1 ALA A 969 2.753 -18.215 4.264 1.00 72.54 H ATOM 1283 HB2 ALA A 969 1.072 -18.482 3.826 1.00 72.54 H ATOM 1284 HB3 ALA A 969 2.317 -18.490 2.579 1.00 72.54 H ATOM 1285 N GLY A 970 3.455 -15.723 1.668 1.00 69.45 N ATOM 1286 CA GLY A 970 4.486 -14.840 1.127 1.00 69.02 C ATOM 1287 C GLY A 970 3.895 -13.429 0.997 1.00 72.14 C ATOM 1288 O GLY A 970 2.682 -13.266 0.899 1.00 71.87 O ATOM 1289 H GLY A 970 2.832 -16.144 0.993 1.00 69.45 H ATOM 1290 HA3 GLY A 970 4.784 -15.198 0.141 1.00 69.02 H ATOM 1291 HA2 GLY A 970 5.374 -14.835 1.761 1.00 69.02 H ATOM 1292 N ALA A 971 4.753 -12.396 1.021 1.00 67.87 N ATOM 1293 CA ALA A 971 4.399 -10.968 0.975 1.00 66.36 C ATOM 1294 C ALA A 971 3.642 -10.423 2.209 1.00 68.68 C ATOM 1295 O ALA A 971 3.602 -9.204 2.353 1.00 67.93 O ATOM 1296 CB ALA A 971 3.635 -10.620 -0.324 1.00 65.39 C ATOM 1297 H ALA A 971 5.740 -12.592 1.108 1.00 67.87 H ATOM 1298 HA ALA A 971 5.351 -10.437 0.943 1.00 66.36 H ATOM 1299 HB1 ALA A 971 3.520 -9.542 -0.439 1.00 65.39 H ATOM 1300 HB2 ALA A 971 4.163 -10.985 -1.204 1.00 65.39 H ATOM 1301 HB3 ALA A 971 2.631 -11.045 -0.345 1.00 65.39 H ATOM 1302 N ALA A 972 3.071 -11.293 3.066 1.00 64.62 N ATOM 1303 CA ALA A 972 2.294 -10.981 4.274 1.00 64.42 C ATOM 1304 C ALA A 972 1.103 -10.047 3.984 1.00 65.37 C ATOM 1305 O ALA A 972 1.060 -8.921 4.484 1.00 65.17 O ATOM 1306 CB ALA A 972 3.227 -10.442 5.377 1.00 66.93 C ATOM 1307 H ALA A 972 3.134 -12.278 2.848 1.00 64.62 H ATOM 1308 HA ALA A 972 1.876 -11.926 4.624 1.00 64.42 H ATOM 1309 HB1 ALA A 972 2.682 -10.275 6.307 1.00 66.93 H ATOM 1310 HB2 ALA A 972 4.025 -11.154 5.594 1.00 66.93 H ATOM 1311 HB3 ALA A 972 3.695 -9.499 5.094 1.00 66.93 H ATOM 1312 N SER A 973 0.184 -10.522 3.129 1.00 59.44 N ATOM 1313 CA SER A 973 -0.932 -9.741 2.593 1.00 57.90 C ATOM 1314 C SER A 973 -2.075 -10.655 2.119 1.00 59.01 C ATOM 1315 O SER A 973 -1.921 -11.876 2.086 1.00 59.49 O ATOM 1316 CB SER A 973 -0.403 -8.798 1.481 1.00 60.76 C ATOM 1317 OG SER A 973 0.026 -9.508 0.334 1.00 68.97 O ATOM 1318 H SER A 973 0.267 -11.466 2.774 1.00 59.44 H ATOM 1319 HA SER A 973 -1.339 -9.130 3.402 1.00 57.90 H ATOM 1320 HB3 SER A 973 0.421 -8.183 1.842 1.00 60.76 H ATOM 1321 HB2 SER A 973 -1.186 -8.105 1.171 1.00 60.76 H ATOM 1322 HG SER A 973 0.794 -10.035 0.572 1.00 68.97 H ATOM 1323 N LEU A 974 -3.205 -10.033 1.747 1.00 52.28 N ATOM 1324 CA LEU A 974 -4.302 -10.697 1.044 1.00 50.34 C ATOM 1325 C LEU A 974 -4.106 -10.533 -0.466 1.00 50.70 C ATOM 1326 O LEU A 974 -3.776 -9.438 -0.918 1.00 49.90 O ATOM 1327 CB LEU A 974 -5.652 -10.057 1.444 1.00 50.33 C ATOM 1328 CG LEU A 974 -6.133 -10.385 2.872 1.00 55.89 C ATOM 1329 CD1 LEU A 974 -7.390 -9.560 3.225 1.00 55.99 C ATOM 1330 CD2 LEU A 974 -6.349 -11.900 3.087 1.00 57.89 C ATOM 1331 H LEU A 974 -3.270 -9.028 1.815 1.00 52.28 H ATOM 1332 HA LEU A 974 -4.317 -11.761 1.282 1.00 50.34 H ATOM 1333 HB3 LEU A 974 -6.429 -10.378 0.746 1.00 50.33 H ATOM 1334 HB2 LEU A 974 -5.580 -8.974 1.322 1.00 50.33 H ATOM 1335 HG LEU A 974 -5.348 -10.068 3.560 1.00 55.89 H ATOM 1336 HD11 LEU A 974 -7.239 -9.004 4.151 1.00 55.99 H ATOM 1337 HD12 LEU A 974 -7.635 -8.832 2.451 1.00 55.99 H ATOM 1338 HD13 LEU A 974 -8.277 -10.179 3.359 1.00 55.99 H ATOM 1339 HD21 LEU A 974 -7.274 -12.124 3.617 1.00 57.89 H ATOM 1340 HD22 LEU A 974 -6.384 -12.447 2.144 1.00 57.89 H ATOM 1341 HD23 LEU A 974 -5.535 -12.324 3.676 1.00 57.89 H ATOM 1342 N GLN A 975 -4.395 -11.603 -1.216 1.00 44.54 N ATOM 1343 CA GLN A 975 -4.655 -11.549 -2.651 1.00 42.17 C ATOM 1344 C GLN A 975 -6.158 -11.329 -2.878 1.00 43.56 C ATOM 1345 O GLN A 975 -6.971 -11.919 -2.168 1.00 42.93 O ATOM 1346 CB GLN A 975 -4.191 -12.855 -3.311 1.00 43.83 C ATOM 1347 CG GLN A 975 -2.665 -12.973 -3.441 1.00 59.19 C ATOM 1348 CD GLN A 975 -2.252 -14.354 -3.950 1.00 77.91 C ATOM 1349 OE1 GLN A 975 -1.888 -14.512 -5.113 1.00 74.64 O ATOM 1350 NE2 GLN A 975 -2.324 -15.365 -3.082 1.00 71.32 N ATOM 1351 H GLN A 975 -4.643 -12.473 -0.760 1.00 44.54 H ATOM 1352 HA GLN A 975 -4.101 -10.725 -3.104 1.00 42.17 H ATOM 1353 HB3 GLN A 975 -4.625 -12.926 -4.306 1.00 43.83 H ATOM 1354 HB2 GLN A 975 -4.582 -13.695 -2.742 1.00 43.83 H ATOM 1355 HG3 GLN A 975 -2.186 -12.784 -2.484 1.00 59.19 H ATOM 1356 HG2 GLN A 975 -2.291 -12.209 -4.121 1.00 59.19 H ATOM 1357 HE22 GLN A 975 -2.096 -16.302 -3.374 1.00 71.32 H ATOM 1358 HE21 GLN A 975 -2.627 -15.202 -2.132 1.00 71.32 H ATOM 1359 N LEU A 976 -6.488 -10.492 -3.868 1.00 37.72 N ATOM 1360 CA LEU A 976 -7.847 -10.131 -4.255 1.00 36.76 C ATOM 1361 C LEU A 976 -8.327 -11.093 -5.350 1.00 38.66 C ATOM 1362 O LEU A 976 -7.956 -10.919 -6.512 1.00 37.25 O ATOM 1363 CB LEU A 976 -7.819 -8.656 -4.717 1.00 36.56 C ATOM 1364 CG LEU A 976 -9.143 -8.055 -5.237 1.00 41.61 C ATOM 1365 CD1 LEU A 976 -10.288 -8.184 -4.216 1.00 43.42 C ATOM 1366 CD2 LEU A 976 -8.926 -6.598 -5.699 1.00 42.85 C ATOM 1367 H LEU A 976 -5.752 -10.099 -4.441 1.00 37.72 H ATOM 1368 HA LEU A 976 -8.510 -10.216 -3.392 1.00 36.76 H ATOM 1369 HB3 LEU A 976 -7.085 -8.565 -5.513 1.00 36.56 H ATOM 1370 HB2 LEU A 976 -7.445 -8.039 -3.900 1.00 36.56 H ATOM 1371 HG LEU A 976 -9.442 -8.613 -6.124 1.00 41.61 H ATOM 1372 HD11 LEU A 976 -10.930 -7.303 -4.187 1.00 43.42 H ATOM 1373 HD12 LEU A 976 -10.920 -9.035 -4.469 1.00 43.42 H ATOM 1374 HD13 LEU A 976 -9.917 -8.343 -3.204 1.00 43.42 H ATOM 1375 HD21 LEU A 976 -9.526 -5.885 -5.134 1.00 42.85 H ATOM 1376 HD22 LEU A 976 -7.888 -6.282 -5.594 1.00 42.85 H ATOM 1377 HD23 LEU A 976 -9.185 -6.482 -6.752 1.00 42.85 H ATOM 1378 N VAL A 977 -9.134 -12.091 -4.958 1.00 35.03 N ATOM 1379 CA VAL A 977 -9.722 -13.059 -5.882 1.00 34.91 C ATOM 1380 C VAL A 977 -10.993 -12.447 -6.502 1.00 38.85 C ATOM 1381 O VAL A 977 -11.896 -12.025 -5.778 1.00 39.08 O ATOM 1382 CB VAL A 977 -10.085 -14.406 -5.191 1.00 39.71 C ATOM 1383 CG1 VAL A 977 -10.564 -15.484 -6.188 1.00 39.45 C ATOM 1384 CG2 VAL A 977 -8.900 -14.967 -4.381 1.00 39.89 C ATOM 1385 H VAL A 977 -9.424 -12.162 -3.993 1.00 35.03 H ATOM 1386 HA VAL A 977 -9.005 -13.279 -6.676 1.00 34.91 H ATOM 1387 HB VAL A 977 -10.902 -14.237 -4.489 1.00 39.71 H ATOM 1388 HG11 VAL A 977 -10.841 -16.401 -5.668 1.00 39.45 H ATOM 1389 HG12 VAL A 977 -11.429 -15.174 -6.770 1.00 39.45 H ATOM 1390 HG13 VAL A 977 -9.779 -15.739 -6.898 1.00 39.45 H ATOM 1391 HG21 VAL A 977 -9.153 -15.924 -3.927 1.00 39.89 H ATOM 1392 HG22 VAL A 977 -8.024 -15.122 -5.011 1.00 39.89 H ATOM 1393 HG23 VAL A 977 -8.610 -14.298 -3.573 1.00 39.89 H ATOM 1394 N MET A 978 -11.015 -12.404 -7.839 1.00 34.03 N ATOM 1395 CA MET A 978 -12.113 -11.896 -8.660 1.00 34.32 C ATOM 1396 C MET A 978 -12.538 -12.993 -9.643 1.00 36.69 C ATOM 1397 O MET A 978 -11.818 -13.978 -9.822 1.00 35.63 O ATOM 1398 CB MET A 978 -11.644 -10.647 -9.443 1.00 36.81 C ATOM 1399 CG MET A 978 -10.999 -9.544 -8.586 1.00 41.50 C ATOM 1400 SD MET A 978 -10.358 -8.128 -9.522 1.00 45.78 S ATOM 1401 CE MET A 978 -8.942 -8.902 -10.352 1.00 42.96 C ATOM 1402 H MET A 978 -10.221 -12.753 -8.360 1.00 34.03 H ATOM 1403 HA MET A 978 -12.972 -11.635 -8.040 1.00 34.32 H ATOM 1404 HB3 MET A 978 -12.500 -10.218 -9.964 1.00 36.81 H ATOM 1405 HB2 MET A 978 -10.949 -10.945 -10.226 1.00 36.81 H ATOM 1406 HG3 MET A 978 -10.167 -9.942 -8.007 1.00 41.50 H ATOM 1407 HG2 MET A 978 -11.729 -9.178 -7.865 1.00 41.50 H ATOM 1408 HE1 MET A 978 -8.326 -8.141 -10.832 1.00 42.96 H ATOM 1409 HE2 MET A 978 -8.328 -9.444 -9.634 1.00 42.96 H ATOM 1410 HE3 MET A 978 -9.276 -9.600 -11.120 1.00 42.96 H ATOM 1411 N GLU A 979 -13.692 -12.793 -10.297 1.00 33.63 N ATOM 1412 CA GLU A 979 -14.132 -13.639 -11.407 1.00 33.95 C ATOM 1413 C GLU A 979 -13.224 -13.450 -12.637 1.00 35.56 C ATOM 1414 O GLU A 979 -12.741 -12.343 -12.884 1.00 32.73 O ATOM 1415 CB GLU A 979 -15.611 -13.341 -11.735 1.00 36.17 C ATOM 1416 CG GLU A 979 -15.895 -11.927 -12.301 1.00 42.68 C ATOM 1417 CD GLU A 979 -17.362 -11.631 -12.644 1.00 58.73 C ATOM 1418 OE1 GLU A 979 -18.206 -12.554 -12.607 1.00 57.48 O ATOM 1419 OE2 GLU A 979 -17.624 -10.444 -12.930 1.00 43.43 O1- ATOM 1420 H GLU A 979 -14.250 -11.971 -10.107 1.00 33.63 H ATOM 1421 HA GLU A 979 -14.064 -14.680 -11.082 1.00 33.95 H ATOM 1422 HB3 GLU A 979 -16.208 -13.495 -10.835 1.00 36.17 H ATOM 1423 HB2 GLU A 979 -15.958 -14.090 -12.449 1.00 36.17 H ATOM 1424 HG3 GLU A 979 -15.329 -11.770 -13.218 1.00 42.68 H ATOM 1425 HG2 GLU A 979 -15.547 -11.175 -11.591 1.00 42.68 H ATOM 1426 N TYR A 980 -13.046 -14.537 -13.401 1.00 33.04 N ATOM 1427 CA TYR A 980 -12.435 -14.501 -14.725 1.00 34.05 C ATOM 1428 C TYR A 980 -13.483 -14.026 -15.745 1.00 39.90 C ATOM 1429 O TYR A 980 -14.472 -14.726 -15.958 1.00 41.17 O ATOM 1430 CB TYR A 980 -11.868 -15.895 -15.054 1.00 36.60 C ATOM 1431 CG TYR A 980 -11.332 -16.062 -16.464 1.00 38.89 C ATOM 1432 CD1 TYR A 980 -10.181 -15.355 -16.870 1.00 40.20 C ATOM 1433 CD2 TYR A 980 -11.982 -16.925 -17.372 1.00 40.57 C ATOM 1434 CE1 TYR A 980 -9.674 -15.525 -18.172 1.00 41.79 C ATOM 1435 CE2 TYR A 980 -11.480 -17.085 -18.677 1.00 41.35 C ATOM 1436 CZ TYR A 980 -10.325 -16.386 -19.077 1.00 46.65 C ATOM 1437 OH TYR A 980 -9.838 -16.543 -20.341 1.00 46.21 O ATOM 1438 H TYR A 980 -13.471 -15.414 -13.135 1.00 33.04 H ATOM 1439 HA TYR A 980 -11.599 -13.798 -14.714 1.00 34.05 H ATOM 1440 HB3 TYR A 980 -12.642 -16.648 -14.893 1.00 36.60 H ATOM 1441 HB2 TYR A 980 -11.066 -16.137 -14.355 1.00 36.60 H ATOM 1442 HD1 TYR A 980 -9.678 -14.693 -16.181 1.00 40.20 H ATOM 1443 HD2 TYR A 980 -12.868 -17.466 -17.073 1.00 40.57 H ATOM 1444 HE1 TYR A 980 -8.783 -14.995 -18.472 1.00 41.79 H ATOM 1445 HE2 TYR A 980 -11.986 -17.745 -19.366 1.00 41.35 H ATOM 1446 HH TYR A 980 -10.419 -17.063 -20.902 1.00 46.21 H ATOM 1447 N VAL A 981 -13.243 -12.844 -16.331 1.00 35.70 N ATOM 1448 CA VAL A 981 -14.105 -12.203 -17.322 1.00 35.13 C ATOM 1449 C VAL A 981 -13.580 -12.610 -18.729 1.00 39.95 C ATOM 1450 O VAL A 981 -12.511 -12.123 -19.104 1.00 40.49 O ATOM 1451 CB VAL A 981 -14.061 -10.658 -17.131 1.00 37.53 C ATOM 1452 CG1 VAL A 981 -14.865 -9.900 -18.194 1.00 37.76 C ATOM 1453 CG2 VAL A 981 -14.577 -10.251 -15.736 1.00 36.89 C ATOM 1454 H VAL A 981 -12.403 -12.336 -16.094 1.00 35.70 H ATOM 1455 HA VAL A 981 -15.141 -12.487 -17.157 1.00 35.13 H ATOM 1456 HB VAL A 981 -13.027 -10.316 -17.194 1.00 37.53 H ATOM 1457 HG11 VAL A 981 -15.030 -8.860 -17.916 1.00 37.76 H ATOM 1458 HG12 VAL A 981 -14.337 -9.900 -19.144 1.00 37.76 H ATOM 1459 HG13 VAL A 981 -15.848 -10.347 -18.332 1.00 37.76 H ATOM 1460 HG21 VAL A 981 -14.545 -9.169 -15.601 1.00 36.89 H ATOM 1461 HG22 VAL A 981 -15.608 -10.571 -15.585 1.00 36.89 H ATOM 1462 HG23 VAL A 981 -13.974 -10.689 -14.942 1.00 36.89 H ATOM 1463 N PRO A 982 -14.241 -13.581 -19.416 1.00 37.29 N ATOM 1464 CA PRO A 982 -13.592 -14.428 -20.446 1.00 36.67 C ATOM 1465 C PRO A 982 -12.871 -13.788 -21.645 1.00 38.06 C ATOM 1466 O PRO A 982 -11.842 -14.330 -22.047 1.00 37.41 O ATOM 1467 CB PRO A 982 -14.705 -15.369 -20.926 1.00 39.18 C ATOM 1468 CG PRO A 982 -15.606 -15.513 -19.720 1.00 44.96 C ATOM 1469 CD PRO A 982 -15.576 -14.120 -19.111 1.00 40.09 C ATOM 1470 HA PRO A 982 -12.855 -15.022 -19.904 1.00 36.67 H ATOM 1471 HB3 PRO A 982 -14.326 -16.330 -21.276 1.00 39.18 H ATOM 1472 HB2 PRO A 982 -15.269 -14.915 -21.745 1.00 39.18 H ATOM 1473 HG3 PRO A 982 -15.167 -16.226 -19.021 1.00 44.96 H ATOM 1474 HG2 PRO A 982 -16.612 -15.855 -19.966 1.00 44.96 H ATOM 1475 HD2 PRO A 982 -16.322 -13.488 -19.589 1.00 40.09 H ATOM 1476 HD3 PRO A 982 -15.833 -14.200 -18.058 1.00 40.09 H ATOM 1477 N LEU A 983 -13.410 -12.695 -22.212 1.00 33.36 N ATOM 1478 CA LEU A 983 -12.867 -12.076 -23.431 1.00 31.91 C ATOM 1479 C LEU A 983 -11.838 -10.960 -23.155 1.00 34.62 C ATOM 1480 O LEU A 983 -11.266 -10.441 -24.114 1.00 34.03 O ATOM 1481 CB LEU A 983 -14.023 -11.600 -24.346 1.00 31.79 C ATOM 1482 CG LEU A 983 -14.935 -12.735 -24.868 1.00 36.75 C ATOM 1483 CD1 LEU A 983 -16.149 -12.165 -25.617 1.00 37.07 C ATOM 1484 CD2 LEU A 983 -14.182 -13.760 -25.739 1.00 39.07 C ATOM 1485 H LEU A 983 -14.253 -12.283 -21.835 1.00 33.36 H ATOM 1486 HA LEU A 983 -12.308 -12.827 -23.990 1.00 31.91 H ATOM 1487 HB3 LEU A 983 -13.617 -11.066 -25.205 1.00 31.79 H ATOM 1488 HB2 LEU A 983 -14.631 -10.871 -23.818 1.00 31.79 H ATOM 1489 HG LEU A 983 -15.336 -13.264 -24.002 1.00 36.75 H ATOM 1490 HD11 LEU A 983 -16.944 -12.908 -25.684 1.00 37.07 H ATOM 1491 HD12 LEU A 983 -16.559 -11.295 -25.106 1.00 37.07 H ATOM 1492 HD13 LEU A 983 -15.890 -11.865 -26.633 1.00 37.07 H ATOM 1493 HD21 LEU A 983 -14.730 -14.004 -26.649 1.00 39.07 H ATOM 1494 HD22 LEU A 983 -13.202 -13.396 -26.048 1.00 39.07 H ATOM 1495 HD23 LEU A 983 -14.030 -14.692 -25.194 1.00 39.07 H ATOM 1496 N GLY A 984 -11.577 -10.645 -21.872 1.00 30.54 N ATOM 1497 CA GLY A 984 -10.542 -9.702 -21.438 1.00 29.44 C ATOM 1498 C GLY A 984 -10.893 -8.247 -21.772 1.00 30.46 C ATOM 1499 O GLY A 984 -12.035 -7.935 -22.104 1.00 29.51 O ATOM 1500 H GLY A 984 -12.090 -11.120 -21.142 1.00 30.54 H ATOM 1501 HA3 GLY A 984 -9.590 -9.962 -21.901 1.00 29.44 H ATOM 1502 HA2 GLY A 984 -10.415 -9.792 -20.359 1.00 29.44 H ATOM 1503 N SER A 985 -9.900 -7.349 -21.647 1.00 25.72 N ATOM 1504 CA SER A 985 -10.058 -5.906 -21.855 1.00 25.55 C ATOM 1505 C SER A 985 -10.449 -5.533 -23.295 1.00 28.85 C ATOM 1506 O SER A 985 -10.017 -6.199 -24.235 1.00 26.31 O ATOM 1507 CB SER A 985 -8.804 -5.158 -21.361 1.00 29.24 C ATOM 1508 OG SER A 985 -7.724 -5.184 -22.273 1.00 35.45 O ATOM 1509 H SER A 985 -8.976 -7.668 -21.385 1.00 25.72 H ATOM 1510 HA SER A 985 -10.867 -5.593 -21.205 1.00 25.55 H ATOM 1511 HB3 SER A 985 -8.479 -5.544 -20.395 1.00 29.24 H ATOM 1512 HB2 SER A 985 -9.060 -4.111 -21.202 1.00 29.24 H ATOM 1513 HG SER A 985 -7.369 -6.078 -22.315 1.00 35.45 H ATOM 1514 N LEU A 986 -11.219 -4.440 -23.432 1.00 27.52 N ATOM 1515 CA LEU A 986 -11.584 -3.835 -24.717 1.00 27.90 C ATOM 1516 C LEU A 986 -10.369 -3.303 -25.499 1.00 31.20 C ATOM 1517 O LEU A 986 -10.426 -3.281 -26.727 1.00 30.54 O ATOM 1518 CB LEU A 986 -12.621 -2.712 -24.492 1.00 27.75 C ATOM 1519 CG LEU A 986 -14.045 -3.208 -24.157 1.00 32.92 C ATOM 1520 CD1 LEU A 986 -14.956 -2.019 -23.808 1.00 33.36 C ATOM 1521 CD2 LEU A 986 -14.667 -4.058 -25.284 1.00 36.70 C ATOM 1522 H LEU A 986 -11.542 -3.953 -22.605 1.00 27.52 H ATOM 1523 HA LEU A 986 -12.030 -4.614 -25.334 1.00 27.90 H ATOM 1524 HB3 LEU A 986 -12.688 -2.084 -25.381 1.00 27.75 H ATOM 1525 HB2 LEU A 986 -12.263 -2.052 -23.700 1.00 27.75 H ATOM 1526 HG LEU A 986 -13.980 -3.829 -23.262 1.00 32.92 H ATOM 1527 HD11 LEU A 986 -15.724 -2.314 -23.100 1.00 33.36 H ATOM 1528 HD12 LEU A 986 -14.399 -1.202 -23.350 1.00 33.36 H ATOM 1529 HD13 LEU A 986 -15.463 -1.625 -24.690 1.00 33.36 H ATOM 1530 HD21 LEU A 986 -15.731 -3.859 -25.406 1.00 36.70 H ATOM 1531 HD22 LEU A 986 -14.192 -3.868 -26.245 1.00 36.70 H ATOM 1532 HD23 LEU A 986 -14.561 -5.121 -25.075 1.00 36.70 H ATOM 1533 N ARG A 987 -9.286 -2.929 -24.793 1.00 29.06 N ATOM 1534 CA ARG A 987 -8.017 -2.516 -25.394 1.00 29.96 C ATOM 1535 C ARG A 987 -7.291 -3.652 -26.137 1.00 34.81 C ATOM 1536 O ARG A 987 -6.680 -3.387 -27.172 1.00 34.10 O ATOM 1537 CB ARG A 987 -7.130 -1.836 -24.336 1.00 32.11 C ATOM 1538 CG ARG A 987 -5.888 -1.139 -24.920 1.00 46.98 C ATOM 1539 CD ARG A 987 -5.085 -0.392 -23.849 1.00 59.29 C ATOM 1540 NE ARG A 987 -3.827 0.162 -24.375 1.00 65.62 N ATOM 1541 CZ ARG A 987 -2.647 -0.473 -24.496 1.00 80.85 C ATOM 1542 NH1 ARG A 987 -1.601 0.204 -24.984 1.00 71.30 N ATOM 1543 NH2 ARG A 987 -2.483 -1.757 -24.139 1.00 64.23 N1+ ATOM 1544 H ARG A 987 -9.312 -2.973 -23.784 1.00 29.06 H ATOM 1545 HA ARG A 987 -8.262 -1.763 -26.133 1.00 29.96 H ATOM 1546 HB3 ARG A 987 -6.823 -2.568 -23.588 1.00 32.11 H ATOM 1547 HB2 ARG A 987 -7.722 -1.088 -23.808 1.00 32.11 H ATOM 1548 HG3 ARG A 987 -6.268 -0.398 -25.626 1.00 46.98 H ATOM 1549 HG2 ARG A 987 -5.251 -1.807 -25.500 1.00 46.98 H ATOM 1550 HD3 ARG A 987 -4.953 -0.979 -22.940 1.00 59.29 H ATOM 1551 HD2 ARG A 987 -5.653 0.492 -23.566 1.00 59.29 H ATOM 1552 HE ARG A 987 -3.886 1.115 -24.706 1.00 65.62 H ATOM 1553 HH12 ARG A 987 -0.701 -0.246 -25.082 1.00 71.30 H ATOM 1554 HH11 ARG A 987 -1.705 1.173 -25.259 1.00 71.30 H ATOM 1555 HH22 ARG A 987 -1.576 -2.198 -24.220 1.00 64.23 H ATOM 1556 HH21 ARG A 987 -3.272 -2.303 -23.824 1.00 64.23 H ATOM 1557 N ASP A 988 -7.393 -4.883 -25.612 1.00 32.33 N ATOM 1558 CA ASP A 988 -6.818 -6.091 -26.208 1.00 32.03 C ATOM 1559 C ASP A 988 -7.773 -6.753 -27.216 1.00 34.79 C ATOM 1560 O ASP A 988 -7.292 -7.360 -28.172 1.00 33.45 O ATOM 1561 CB ASP A 988 -6.383 -7.129 -25.141 1.00 34.09 C ATOM 1562 CG ASP A 988 -5.386 -6.633 -24.076 1.00 50.64 C ATOM 1563 OD1 ASP A 988 -4.621 -5.682 -24.352 1.00 52.94 O ATOM 1564 OD2 ASP A 988 -5.324 -7.306 -23.023 1.00 55.56 O1- ATOM 1565 H ASP A 988 -7.905 -5.013 -24.750 1.00 32.33 H ATOM 1566 HA ASP A 988 -5.926 -5.807 -26.770 1.00 32.03 H ATOM 1567 HB3 ASP A 988 -5.929 -7.992 -25.631 1.00 34.09 H ATOM 1568 HB2 ASP A 988 -7.271 -7.493 -24.620 1.00 34.09 H ATOM 1569 N TYR A 989 -9.092 -6.640 -26.993 1.00 30.87 N ATOM 1570 CA TYR A 989 -10.115 -7.301 -27.799 1.00 30.93 C ATOM 1571 C TYR A 989 -10.388 -6.577 -29.130 1.00 31.61 C ATOM 1572 O TYR A 989 -10.312 -7.223 -30.174 1.00 30.88 O ATOM 1573 CB TYR A 989 -11.391 -7.498 -26.954 1.00 32.58 C ATOM 1574 CG TYR A 989 -12.492 -8.296 -27.630 1.00 35.88 C ATOM 1575 CD1 TYR A 989 -12.518 -9.702 -27.516 1.00 38.76 C ATOM 1576 CD2 TYR A 989 -13.493 -7.638 -28.372 1.00 37.33 C ATOM 1577 CE1 TYR A 989 -13.542 -10.443 -28.137 1.00 41.81 C ATOM 1578 CE2 TYR A 989 -14.514 -8.378 -28.996 1.00 39.43 C ATOM 1579 CZ TYR A 989 -14.541 -9.782 -28.878 1.00 47.08 C ATOM 1580 OH TYR A 989 -15.532 -10.501 -29.479 1.00 54.57 O ATOM 1581 H TYR A 989 -9.417 -6.150 -26.170 1.00 30.87 H ATOM 1582 HA TYR A 989 -9.748 -8.300 -28.046 1.00 30.93 H ATOM 1583 HB3 TYR A 989 -11.794 -6.531 -26.652 1.00 32.58 H ATOM 1584 HB2 TYR A 989 -11.134 -8.012 -26.026 1.00 32.58 H ATOM 1585 HD1 TYR A 989 -11.755 -10.216 -26.949 1.00 38.76 H ATOM 1586 HD2 TYR A 989 -13.476 -6.563 -28.464 1.00 37.33 H ATOM 1587 HE1 TYR A 989 -13.559 -11.519 -28.045 1.00 41.81 H ATOM 1588 HE2 TYR A 989 -15.272 -7.863 -29.563 1.00 39.43 H ATOM 1589 HH TYR A 989 -16.158 -9.956 -29.961 1.00 54.57 H ATOM 1590 N LEU A 990 -10.706 -5.269 -29.079 1.00 26.64 N ATOM 1591 CA LEU A 990 -11.169 -4.493 -30.238 1.00 26.55 C ATOM 1592 C LEU A 990 -10.208 -4.338 -31.443 1.00 32.26 C ATOM 1593 O LEU A 990 -10.730 -4.254 -32.554 1.00 32.40 O ATOM 1594 CB LEU A 990 -11.721 -3.111 -29.816 1.00 25.29 C ATOM 1595 CG LEU A 990 -12.967 -3.137 -28.906 1.00 28.64 C ATOM 1596 CD1 LEU A 990 -13.282 -1.724 -28.386 1.00 28.39 C ATOM 1597 CD2 LEU A 990 -14.197 -3.752 -29.604 1.00 27.70 C ATOM 1598 H LEU A 990 -10.708 -4.785 -28.191 1.00 26.64 H ATOM 1599 HA LEU A 990 -12.009 -5.067 -30.634 1.00 26.55 H ATOM 1600 HB3 LEU A 990 -11.971 -2.532 -30.706 1.00 25.29 H ATOM 1601 HB2 LEU A 990 -10.926 -2.554 -29.318 1.00 25.29 H ATOM 1602 HG LEU A 990 -12.740 -3.756 -28.038 1.00 28.64 H ATOM 1603 HD11 LEU A 990 -14.289 -1.658 -27.974 1.00 28.39 H ATOM 1604 HD12 LEU A 990 -12.591 -1.441 -27.593 1.00 28.39 H ATOM 1605 HD13 LEU A 990 -13.197 -0.978 -29.176 1.00 28.39 H ATOM 1606 HD21 LEU A 990 -15.056 -3.083 -29.591 1.00 27.70 H ATOM 1607 HD22 LEU A 990 -14.006 -3.989 -30.651 1.00 27.70 H ATOM 1608 HD23 LEU A 990 -14.506 -4.670 -29.108 1.00 27.70 H ATOM 1609 N PRO A 991 -8.862 -4.368 -31.272 1.00 29.17 N ATOM 1610 CA PRO A 991 -7.934 -4.390 -32.422 1.00 30.32 C ATOM 1611 C PRO A 991 -7.982 -5.660 -33.292 1.00 37.04 C ATOM 1612 O PRO A 991 -7.685 -5.568 -34.482 1.00 39.83 O ATOM 1613 CB PRO A 991 -6.545 -4.175 -31.796 1.00 31.53 C ATOM 1614 CG PRO A 991 -6.828 -3.468 -30.483 1.00 34.07 C ATOM 1615 CD PRO A 991 -8.127 -4.120 -30.032 1.00 29.12 C ATOM 1616 HA PRO A 991 -8.172 -3.530 -33.048 1.00 30.32 H ATOM 1617 HB3 PRO A 991 -5.880 -3.597 -32.438 1.00 31.53 H ATOM 1618 HB2 PRO A 991 -6.059 -5.130 -31.592 1.00 31.53 H ATOM 1619 HG3 PRO A 991 -6.998 -2.407 -30.671 1.00 34.07 H ATOM 1620 HG2 PRO A 991 -6.017 -3.559 -29.761 1.00 34.07 H ATOM 1621 HD2 PRO A 991 -7.914 -5.074 -29.554 1.00 29.12 H ATOM 1622 HD3 PRO A 991 -8.663 -3.490 -29.323 1.00 29.12 H ATOM 1623 N ARG A 992 -8.364 -6.801 -32.693 1.00 33.12 N ATOM 1624 CA ARG A 992 -8.473 -8.101 -33.362 1.00 35.22 C ATOM 1625 C ARG A 992 -9.923 -8.477 -33.721 1.00 42.35 C ATOM 1626 O ARG A 992 -10.101 -9.442 -34.464 1.00 43.35 O ATOM 1627 CB ARG A 992 -7.847 -9.181 -32.452 1.00 36.79 C ATOM 1628 CG ARG A 992 -6.321 -9.042 -32.266 1.00 49.00 C ATOM 1629 CD ARG A 992 -5.895 -8.581 -30.862 1.00 65.39 C ATOM 1630 NE ARG A 992 -4.429 -8.630 -30.709 1.00 83.52 N ATOM 1631 CZ ARG A 992 -3.697 -8.245 -29.646 1.00101.34 C ATOM 1632 NH1 ARG A 992 -4.252 -7.730 -28.539 1.00 87.97 N ATOM 1633 NH2 ARG A 992 -2.366 -8.382 -29.694 1.00 90.05 N1+ ATOM 1634 H ARG A 992 -8.610 -6.788 -31.713 1.00 33.12 H ATOM 1635 HA ARG A 992 -7.920 -8.089 -34.303 1.00 35.22 H ATOM 1636 HB3 ARG A 992 -8.028 -10.163 -32.891 1.00 36.79 H ATOM 1637 HB2 ARG A 992 -8.353 -9.200 -31.486 1.00 36.79 H ATOM 1638 HG3 ARG A 992 -5.962 -8.307 -32.988 1.00 49.00 H ATOM 1639 HG2 ARG A 992 -5.815 -9.970 -32.534 1.00 49.00 H ATOM 1640 HD3 ARG A 992 -6.407 -9.141 -30.079 1.00 65.39 H ATOM 1641 HD2 ARG A 992 -6.177 -7.534 -30.743 1.00 65.39 H ATOM 1642 HE ARG A 992 -3.934 -9.003 -31.505 1.00 83.52 H ATOM 1643 HH12 ARG A 992 -3.684 -7.448 -27.753 1.00 87.97 H ATOM 1644 HH11 ARG A 992 -5.259 -7.626 -28.485 1.00 87.97 H ATOM 1645 HH22 ARG A 992 -1.795 -8.104 -28.909 1.00 90.05 H ATOM 1646 HH21 ARG A 992 -1.920 -8.767 -30.514 1.00 90.05 H ATOM 1647 N HIS A 993 -10.920 -7.742 -33.199 1.00 39.31 N ATOM 1648 CA HIS A 993 -12.343 -8.029 -33.380 1.00 40.02 C ATOM 1649 C HIS A 993 -13.064 -6.735 -33.771 1.00 44.39 C ATOM 1650 O HIS A 993 -13.235 -5.856 -32.926 1.00 42.90 O ATOM 1651 CB HIS A 993 -12.933 -8.636 -32.087 1.00 40.24 C ATOM 1652 CG HIS A 993 -12.280 -9.913 -31.615 1.00 43.95 C ATOM 1653 ND1 HIS A 993 -11.178 -9.921 -30.777 1.00 44.82 N ATOM 1654 CD2 HIS A 993 -12.584 -11.239 -31.832 1.00 46.86 C ATOM 1655 CE1 HIS A 993 -10.862 -11.196 -30.543 1.00 45.15 C ATOM 1656 NE2 HIS A 993 -11.674 -12.053 -31.151 1.00 46.64 N ATOM 1657 H HIS A 993 -10.700 -6.953 -32.607 1.00 39.31 H ATOM 1658 HA HIS A 993 -12.488 -8.755 -34.182 1.00 40.02 H ATOM 1659 HB3 HIS A 993 -13.998 -8.834 -32.223 1.00 40.24 H ATOM 1660 HB2 HIS A 993 -12.864 -7.911 -31.275 1.00 40.24 H ATOM 1661 HD1 HIS A 993 -10.706 -9.101 -30.417 1.00 44.82 H ATOM 1662 HD2 HIS A 993 -13.381 -11.668 -32.421 1.00 46.86 H ATOM 1663 HE1 HIS A 993 -10.035 -11.499 -29.918 1.00 45.15 H ATOM 1664 N SER A 994 -13.470 -6.644 -35.048 1.00 43.61 N ATOM 1665 CA SER A 994 -14.209 -5.516 -35.617 1.00 44.09 C ATOM 1666 C SER A 994 -15.687 -5.527 -35.171 1.00 48.55 C ATOM 1667 O SER A 994 -16.525 -6.165 -35.809 1.00 49.91 O ATOM 1668 CB SER A 994 -14.007 -5.502 -37.150 1.00 50.40 C ATOM 1669 OG SER A 994 -14.571 -6.626 -37.802 1.00 64.99 O ATOM 1670 H SER A 994 -13.279 -7.408 -35.685 1.00 43.61 H ATOM 1671 HA SER A 994 -13.757 -4.597 -35.238 1.00 44.09 H ATOM 1672 HB3 SER A 994 -12.944 -5.455 -37.390 1.00 50.40 H ATOM 1673 HB2 SER A 994 -14.458 -4.603 -37.573 1.00 50.40 H ATOM 1674 HG SER A 994 -15.515 -6.632 -37.619 1.00 64.99 H ATOM 1675 N ILE A 995 -15.965 -4.828 -34.059 1.00 42.04 N ATOM 1676 CA ILE A 995 -17.296 -4.714 -33.464 1.00 40.91 C ATOM 1677 C ILE A 995 -18.064 -3.520 -34.068 1.00 43.90 C ATOM 1678 O ILE A 995 -17.480 -2.455 -34.267 1.00 43.46 O ATOM 1679 CB ILE A 995 -17.192 -4.556 -31.916 1.00 42.36 C ATOM 1680 CG1 ILE A 995 -16.536 -5.790 -31.248 1.00 42.65 C ATOM 1681 CG2 ILE A 995 -18.529 -4.242 -31.218 1.00 41.71 C ATOM 1682 CD1 ILE A 995 -17.228 -7.139 -31.513 1.00 43.19 C ATOM 1683 H ILE A 995 -15.219 -4.349 -33.575 1.00 42.04 H ATOM 1684 HA ILE A 995 -17.863 -5.619 -33.689 1.00 40.91 H ATOM 1685 HB ILE A 995 -16.532 -3.711 -31.714 1.00 42.36 H ATOM 1686 HG13 ILE A 995 -16.475 -5.629 -30.172 1.00 42.65 H ATOM 1687 HG12 ILE A 995 -15.501 -5.868 -31.578 1.00 42.65 H ATOM 1688 HG21 ILE A 995 -18.434 -4.276 -30.134 1.00 41.71 H ATOM 1689 HG22 ILE A 995 -18.899 -3.250 -31.464 1.00 41.71 H ATOM 1690 HG23 ILE A 995 -19.292 -4.958 -31.512 1.00 41.71 H ATOM 1691 HD11 ILE A 995 -16.639 -7.748 -32.199 1.00 43.19 H ATOM 1692 HD12 ILE A 995 -17.348 -7.704 -30.589 1.00 43.19 H ATOM 1693 HD13 ILE A 995 -18.221 -7.025 -31.946 1.00 43.19 H ATOM 1694 N GLY A 996 -19.363 -3.733 -34.347 1.00 39.60 N ATOM 1695 CA GLY A 996 -20.252 -2.755 -34.979 1.00 39.64 C ATOM 1696 C GLY A 996 -20.596 -1.588 -34.040 1.00 40.81 C ATOM 1697 O GLY A 996 -20.520 -1.711 -32.818 1.00 40.20 O ATOM 1698 H GLY A 996 -19.764 -4.635 -34.139 1.00 39.60 H ATOM 1699 HA3 GLY A 996 -21.173 -3.256 -35.273 1.00 39.64 H ATOM 1700 HA2 GLY A 996 -19.788 -2.377 -35.892 1.00 39.64 H ATOM 1701 N LEU A 997 -20.997 -0.458 -34.647 1.00 36.29 N ATOM 1702 CA LEU A 997 -21.277 0.836 -34.014 1.00 34.21 C ATOM 1703 C LEU A 997 -22.273 0.785 -32.840 1.00 36.59 C ATOM 1704 O LEU A 997 -21.980 1.361 -31.794 1.00 34.53 O ATOM 1705 CB LEU A 997 -21.711 1.829 -35.121 1.00 34.53 C ATOM 1706 CG LEU A 997 -22.124 3.249 -34.665 1.00 38.00 C ATOM 1707 CD1 LEU A 997 -21.037 3.947 -33.824 1.00 36.32 C ATOM 1708 CD2 LEU A 997 -22.558 4.106 -35.869 1.00 39.98 C ATOM 1709 H LEU A 997 -21.051 -0.455 -35.657 1.00 36.29 H ATOM 1710 HA LEU A 997 -20.326 1.179 -33.603 1.00 34.21 H ATOM 1711 HB3 LEU A 997 -22.545 1.391 -35.671 1.00 34.53 H ATOM 1712 HB2 LEU A 997 -20.897 1.921 -35.842 1.00 34.53 H ATOM 1713 HG LEU A 997 -23.015 3.149 -34.047 1.00 38.00 H ATOM 1714 HD11 LEU A 997 -20.949 5.005 -34.060 1.00 36.32 H ATOM 1715 HD12 LEU A 997 -21.263 3.882 -32.760 1.00 36.32 H ATOM 1716 HD13 LEU A 997 -20.056 3.499 -33.980 1.00 36.32 H ATOM 1717 HD21 LEU A 997 -23.419 4.725 -35.614 1.00 39.98 H ATOM 1718 HD22 LEU A 997 -21.763 4.769 -36.208 1.00 39.98 H ATOM 1719 HD23 LEU A 997 -22.845 3.494 -36.724 1.00 39.98 H ATOM 1720 N ALA A 998 -23.409 0.089 -33.016 1.00 34.25 N ATOM 1721 CA ALA A 998 -24.444 -0.055 -31.989 1.00 34.26 C ATOM 1722 C ALA A 998 -23.979 -0.830 -30.750 1.00 36.18 C ATOM 1723 O ALA A 998 -24.385 -0.484 -29.643 1.00 35.22 O ATOM 1724 CB ALA A 998 -25.666 -0.747 -32.595 1.00 36.52 C ATOM 1725 H ALA A 998 -23.583 -0.370 -33.900 1.00 34.25 H ATOM 1726 HA ALA A 998 -24.741 0.949 -31.677 1.00 34.26 H ATOM 1727 HB1 ALA A 998 -26.532 -0.659 -31.938 1.00 36.52 H ATOM 1728 HB2 ALA A 998 -25.920 -0.291 -33.546 1.00 36.52 H ATOM 1729 HB3 ALA A 998 -25.492 -1.807 -32.778 1.00 36.52 H ATOM 1730 N GLN A 999 -23.130 -1.847 -30.960 1.00 32.90 N ATOM 1731 CA GLN A 999 -22.559 -2.689 -29.914 1.00 31.66 C ATOM 1732 C GLN A 999 -21.446 -1.975 -29.116 1.00 31.83 C ATOM 1733 O GLN A 999 -21.293 -2.274 -27.934 1.00 31.42 O ATOM 1734 CB GLN A 999 -22.134 -4.016 -30.571 1.00 33.78 C ATOM 1735 CG GLN A 999 -21.621 -5.106 -29.611 1.00 53.37 C ATOM 1736 CD GLN A 999 -21.398 -6.443 -30.329 1.00 79.04 C ATOM 1737 OE1 GLN A 999 -22.211 -6.864 -31.150 1.00 77.41 O ATOM 1738 NE2 GLN A 999 -20.304 -7.132 -30.005 1.00 70.04 N ATOM 1739 H GLN A 999 -22.847 -2.066 -31.906 1.00 32.90 H ATOM 1740 HA GLN A 999 -23.358 -2.921 -29.208 1.00 31.66 H ATOM 1741 HB3 GLN A 999 -21.389 -3.822 -31.342 1.00 33.78 H ATOM 1742 HB2 GLN A 999 -23.006 -4.407 -31.098 1.00 33.78 H ATOM 1743 HG3 GLN A 999 -22.345 -5.266 -28.811 1.00 53.37 H ATOM 1744 HG2 GLN A 999 -20.695 -4.784 -29.133 1.00 53.37 H ATOM 1745 HE22 GLN A 999 -20.123 -8.026 -30.439 1.00 70.04 H ATOM 1746 HE21 GLN A 999 -19.667 -6.780 -29.305 1.00 70.04 H ATOM 1747 N LEU A1000 -20.751 -0.997 -29.732 1.00 27.73 N ATOM 1748 CA LEU A1000 -19.837 -0.069 -29.050 1.00 27.15 C ATOM 1749 C LEU A1000 -20.595 0.953 -28.181 1.00 30.03 C ATOM 1750 O LEU A1000 -20.124 1.276 -27.092 1.00 28.40 O ATOM 1751 CB LEU A1000 -18.945 0.674 -30.074 1.00 27.39 C ATOM 1752 CG LEU A1000 -17.991 -0.227 -30.886 1.00 31.72 C ATOM 1753 CD1 LEU A1000 -17.371 0.546 -32.070 1.00 31.24 C ATOM 1754 CD2 LEU A1000 -16.934 -0.917 -29.997 1.00 32.46 C ATOM 1755 H LEU A1000 -20.916 -0.817 -30.713 1.00 27.73 H ATOM 1756 HA LEU A1000 -19.200 -0.650 -28.383 1.00 27.15 H ATOM 1757 HB3 LEU A1000 -18.351 1.434 -29.562 1.00 27.39 H ATOM 1758 HB2 LEU A1000 -19.586 1.222 -30.765 1.00 27.39 H ATOM 1759 HG LEU A1000 -18.585 -1.019 -31.332 1.00 31.72 H ATOM 1760 HD11 LEU A1000 -16.292 0.426 -32.140 1.00 31.24 H ATOM 1761 HD12 LEU A1000 -17.786 0.194 -33.015 1.00 31.24 H ATOM 1762 HD13 LEU A1000 -17.569 1.617 -32.011 1.00 31.24 H ATOM 1763 HD21 LEU A1000 -15.920 -0.822 -30.385 1.00 32.46 H ATOM 1764 HD22 LEU A1000 -16.925 -0.518 -28.983 1.00 32.46 H ATOM 1765 HD23 LEU A1000 -17.146 -1.982 -29.914 1.00 32.46 H ATOM 1766 N LEU A1001 -21.763 1.420 -28.659 1.00 27.18 N ATOM 1767 CA LEU A1001 -22.668 2.317 -27.931 1.00 26.38 C ATOM 1768 C LEU A1001 -23.415 1.608 -26.786 1.00 30.80 C ATOM 1769 O LEU A1001 -23.803 2.280 -25.831 1.00 31.19 O ATOM 1770 CB LEU A1001 -23.664 2.964 -28.916 1.00 26.55 C ATOM 1771 CG LEU A1001 -23.009 3.940 -29.919 1.00 30.43 C ATOM 1772 CD1 LEU A1001 -23.960 4.224 -31.098 1.00 31.54 C ATOM 1773 CD2 LEU A1001 -22.500 5.228 -29.235 1.00 29.53 C ATOM 1774 H LEU A1001 -22.074 1.125 -29.576 1.00 27.18 H ATOM 1775 HA LEU A1001 -22.066 3.104 -27.475 1.00 26.38 H ATOM 1776 HB3 LEU A1001 -24.448 3.493 -28.371 1.00 26.55 H ATOM 1777 HB2 LEU A1001 -24.174 2.171 -29.464 1.00 26.55 H ATOM 1778 HG LEU A1001 -22.132 3.458 -30.347 1.00 30.43 H ATOM 1779 HD11 LEU A1001 -23.986 5.276 -31.382 1.00 31.54 H ATOM 1780 HD12 LEU A1001 -23.649 3.668 -31.980 1.00 31.54 H ATOM 1781 HD13 LEU A1001 -24.984 3.918 -30.880 1.00 31.54 H ATOM 1782 HD21 LEU A1001 -22.846 6.137 -29.725 1.00 29.53 H ATOM 1783 HD22 LEU A1001 -22.816 5.291 -28.193 1.00 29.53 H ATOM 1784 HD23 LEU A1001 -21.410 5.261 -29.241 1.00 29.53 H ATOM 1785 N LEU A1002 -23.566 0.274 -26.876 1.00 28.48 N ATOM 1786 CA LEU A1002 -24.071 -0.573 -25.798 1.00 29.15 C ATOM 1787 C LEU A1002 -23.034 -0.720 -24.674 1.00 32.78 C ATOM 1788 O LEU A1002 -23.419 -0.645 -23.512 1.00 33.09 O ATOM 1789 CB LEU A1002 -24.495 -1.945 -26.361 1.00 30.13 C ATOM 1790 CG LEU A1002 -25.243 -2.859 -25.364 1.00 35.32 C ATOM 1791 CD1 LEU A1002 -26.559 -2.231 -24.853 1.00 35.94 C ATOM 1792 CD2 LEU A1002 -25.461 -4.257 -25.970 1.00 37.39 C ATOM 1793 H LEU A1002 -23.251 -0.204 -27.709 1.00 28.48 H ATOM 1794 HA LEU A1002 -24.950 -0.077 -25.383 1.00 29.15 H ATOM 1795 HB3 LEU A1002 -23.607 -2.464 -26.722 1.00 30.13 H ATOM 1796 HB2 LEU A1002 -25.123 -1.797 -27.238 1.00 30.13 H ATOM 1797 HG LEU A1002 -24.597 -3.010 -24.498 1.00 35.32 H ATOM 1798 HD11 LEU A1002 -27.382 -2.945 -24.829 1.00 35.94 H ATOM 1799 HD12 LEU A1002 -26.434 -1.855 -23.837 1.00 35.94 H ATOM 1800 HD13 LEU A1002 -26.882 -1.394 -25.473 1.00 35.94 H ATOM 1801 HD21 LEU A1002 -25.178 -5.038 -25.263 1.00 37.39 H ATOM 1802 HD22 LEU A1002 -26.499 -4.429 -26.254 1.00 37.39 H ATOM 1803 HD23 LEU A1002 -24.861 -4.403 -26.868 1.00 37.39 H ATOM 1804 N PHE A1003 -21.743 -0.871 -25.023 1.00 28.23 N ATOM 1805 CA PHE A1003 -20.641 -0.882 -24.054 1.00 28.18 C ATOM 1806 C PHE A1003 -20.492 0.469 -23.336 1.00 29.97 C ATOM 1807 O PHE A1003 -20.248 0.473 -22.133 1.00 28.15 O ATOM 1808 CB PHE A1003 -19.312 -1.272 -24.735 1.00 29.26 C ATOM 1809 CG PHE A1003 -19.273 -2.605 -25.466 1.00 30.64 C ATOM 1810 CD1 PHE A1003 -20.024 -3.718 -25.024 1.00 35.83 C ATOM 1811 CD2 PHE A1003 -18.349 -2.783 -26.518 1.00 32.41 C ATOM 1812 CE1 PHE A1003 -19.919 -4.932 -25.687 1.00 37.36 C ATOM 1813 CE2 PHE A1003 -18.254 -4.007 -27.165 1.00 35.63 C ATOM 1814 CZ PHE A1003 -19.051 -5.071 -26.763 1.00 35.58 C ATOM 1815 H PHE A1003 -21.488 -0.949 -25.998 1.00 28.23 H ATOM 1816 HA PHE A1003 -20.872 -1.624 -23.287 1.00 28.18 H ATOM 1817 HB3 PHE A1003 -18.513 -1.280 -23.993 1.00 29.26 H ATOM 1818 HB2 PHE A1003 -19.040 -0.498 -25.453 1.00 29.26 H ATOM 1819 HD1 PHE A1003 -20.697 -3.642 -24.184 1.00 35.83 H ATOM 1820 HD2 PHE A1003 -17.720 -1.964 -26.835 1.00 32.41 H ATOM 1821 HE1 PHE A1003 -20.509 -5.774 -25.354 1.00 37.36 H ATOM 1822 HE2 PHE A1003 -17.555 -4.132 -27.978 1.00 35.63 H ATOM 1823 HZ PHE A1003 -18.975 -6.020 -27.272 1.00 35.58 H ATOM 1824 N ALA A1004 -20.705 1.578 -24.067 1.00 26.49 N ATOM 1825 CA ALA A1004 -20.726 2.944 -23.542 1.00 26.36 C ATOM 1826 C ALA A1004 -21.860 3.187 -22.532 1.00 28.13 C ATOM 1827 O ALA A1004 -21.618 3.810 -21.500 1.00 27.39 O ATOM 1828 CB ALA A1004 -20.837 3.926 -24.715 1.00 27.23 C ATOM 1829 H ALA A1004 -20.890 1.484 -25.057 1.00 26.49 H ATOM 1830 HA ALA A1004 -19.773 3.115 -23.041 1.00 26.36 H ATOM 1831 HB1 ALA A1004 -20.637 4.947 -24.390 1.00 27.23 H ATOM 1832 HB2 ALA A1004 -20.122 3.678 -25.500 1.00 27.23 H ATOM 1833 HB3 ALA A1004 -21.829 3.918 -25.164 1.00 27.23 H ATOM 1834 N GLN A1005 -23.060 2.661 -22.839 1.00 24.98 N ATOM 1835 CA GLN A1005 -24.241 2.670 -21.976 1.00 26.13 C ATOM 1836 C GLN A1005 -24.005 1.880 -20.676 1.00 30.14 C ATOM 1837 O GLN A1005 -24.287 2.400 -19.601 1.00 29.23 O ATOM 1838 CB GLN A1005 -25.433 2.097 -22.770 1.00 27.37 C ATOM 1839 CG GLN A1005 -26.787 2.123 -22.034 1.00 34.59 C ATOM 1840 CD GLN A1005 -27.753 1.102 -22.634 1.00 45.52 C ATOM 1841 OE1 GLN A1005 -28.014 1.121 -23.835 1.00 37.97 O ATOM 1842 NE2 GLN A1005 -28.296 0.216 -21.798 1.00 40.39 N ATOM 1843 H GLN A1005 -23.170 2.180 -23.722 1.00 24.98 H ATOM 1844 HA GLN A1005 -24.463 3.706 -21.713 1.00 26.13 H ATOM 1845 HB3 GLN A1005 -25.200 1.069 -23.046 1.00 27.37 H ATOM 1846 HB2 GLN A1005 -25.542 2.624 -23.717 1.00 27.37 H ATOM 1847 HG3 GLN A1005 -27.223 3.120 -22.095 1.00 34.59 H ATOM 1848 HG2 GLN A1005 -26.674 1.906 -20.973 1.00 34.59 H ATOM 1849 HE22 GLN A1005 -28.941 -0.481 -22.142 1.00 40.39 H ATOM 1850 HE21 GLN A1005 -28.027 0.204 -20.821 1.00 40.39 H ATOM 1851 N GLN A1006 -23.477 0.652 -20.811 1.00 27.56 N ATOM 1852 CA GLN A1006 -23.173 -0.270 -19.716 1.00 27.14 C ATOM 1853 C GLN A1006 -22.072 0.236 -18.768 1.00 28.50 C ATOM 1854 O GLN A1006 -22.194 0.035 -17.560 1.00 29.35 O ATOM 1855 CB GLN A1006 -22.838 -1.652 -20.304 1.00 28.20 C ATOM 1856 CG GLN A1006 -24.071 -2.360 -20.908 1.00 30.44 C ATOM 1857 CD GLN A1006 -23.732 -3.689 -21.587 1.00 43.69 C ATOM 1858 OE1 GLN A1006 -22.570 -4.021 -21.806 1.00 40.01 O ATOM 1859 NE2 GLN A1006 -24.762 -4.459 -21.939 1.00 39.19 N ATOM 1860 H GLN A1006 -23.289 0.300 -21.741 1.00 27.56 H ATOM 1861 HA GLN A1006 -24.079 -0.372 -19.117 1.00 27.14 H ATOM 1862 HB3 GLN A1006 -22.408 -2.289 -19.530 1.00 28.20 H ATOM 1863 HB2 GLN A1006 -22.063 -1.537 -21.063 1.00 28.20 H ATOM 1864 HG3 GLN A1006 -24.572 -1.725 -21.635 1.00 30.44 H ATOM 1865 HG2 GLN A1006 -24.815 -2.535 -20.135 1.00 30.44 H ATOM 1866 HE22 GLN A1006 -24.602 -5.353 -22.387 1.00 39.19 H ATOM 1867 HE21 GLN A1006 -25.716 -4.155 -21.777 1.00 39.19 H ATOM 1868 N ILE A1007 -21.062 0.943 -19.312 1.00 24.53 N ATOM 1869 CA ILE A1007 -20.069 1.692 -18.536 1.00 23.52 C ATOM 1870 C ILE A1007 -20.727 2.816 -17.713 1.00 26.94 C ATOM 1871 O ILE A1007 -20.405 2.941 -16.536 1.00 25.88 O ATOM 1872 CB ILE A1007 -18.931 2.286 -19.427 1.00 26.23 C ATOM 1873 CG1 ILE A1007 -18.024 1.167 -19.988 1.00 26.44 C ATOM 1874 CG2 ILE A1007 -18.040 3.356 -18.749 1.00 26.63 C ATOM 1875 CD1 ILE A1007 -17.291 1.555 -21.285 1.00 29.19 C ATOM 1876 H ILE A1007 -21.013 1.046 -20.317 1.00 24.53 H ATOM 1877 HA ILE A1007 -19.614 0.992 -17.831 1.00 23.52 H ATOM 1878 HB ILE A1007 -19.417 2.769 -20.276 1.00 26.23 H ATOM 1879 HG13 ILE A1007 -18.608 0.270 -20.180 1.00 26.44 H ATOM 1880 HG12 ILE A1007 -17.298 0.870 -19.230 1.00 26.44 H ATOM 1881 HG21 ILE A1007 -17.216 3.653 -19.397 1.00 26.63 H ATOM 1882 HG22 ILE A1007 -18.590 4.267 -18.511 1.00 26.63 H ATOM 1883 HG23 ILE A1007 -17.606 2.974 -17.825 1.00 26.63 H ATOM 1884 HD11 ILE A1007 -17.143 0.685 -21.925 1.00 29.19 H ATOM 1885 HD12 ILE A1007 -17.847 2.290 -21.866 1.00 29.19 H ATOM 1886 HD13 ILE A1007 -16.313 1.980 -21.071 1.00 29.19 H ATOM 1887 N CYS A1008 -21.665 3.570 -18.316 1.00 24.96 N ATOM 1888 CA CYS A1008 -22.405 4.643 -17.644 1.00 26.23 C ATOM 1889 C CYS A1008 -23.328 4.144 -16.518 1.00 28.78 C ATOM 1890 O CYS A1008 -23.468 4.853 -15.526 1.00 27.82 O ATOM 1891 CB CYS A1008 -23.199 5.533 -18.619 1.00 27.44 C ATOM 1892 SG CYS A1008 -22.060 6.457 -19.678 1.00 31.30 S ATOM 1893 H CYS A1008 -21.894 3.406 -19.288 1.00 24.96 H ATOM 1894 HA CYS A1008 -21.653 5.263 -17.158 1.00 26.23 H ATOM 1895 HB3 CYS A1008 -23.802 6.261 -18.076 1.00 27.44 H ATOM 1896 HB2 CYS A1008 -23.879 4.950 -19.240 1.00 27.44 H ATOM 1897 HG CYS A1008 -21.658 5.407 -20.404 1.00 31.30 H ATOM 1898 N GLU A1009 -23.905 2.938 -16.664 1.00 27.13 N ATOM 1899 CA GLU A1009 -24.712 2.274 -15.636 1.00 27.79 C ATOM 1900 C GLU A1009 -23.884 1.789 -14.430 1.00 31.65 C ATOM 1901 O GLU A1009 -24.361 1.902 -13.301 1.00 32.67 O ATOM 1902 CB GLU A1009 -25.530 1.130 -16.269 1.00 29.33 C ATOM 1903 CG GLU A1009 -26.650 1.632 -17.202 1.00 35.16 C ATOM 1904 CD GLU A1009 -27.432 0.501 -17.874 1.00 58.21 C ATOM 1905 OE1 GLU A1009 -26.942 -0.003 -18.909 1.00 48.70 O ATOM 1906 OE2 GLU A1009 -28.529 0.175 -17.369 1.00 60.77 O1- ATOM 1907 H GLU A1009 -23.769 2.425 -17.524 1.00 27.13 H ATOM 1908 HA GLU A1009 -25.420 3.006 -15.244 1.00 27.79 H ATOM 1909 HB3 GLU A1009 -25.961 0.497 -15.492 1.00 29.33 H ATOM 1910 HB2 GLU A1009 -24.857 0.492 -16.843 1.00 29.33 H ATOM 1911 HG3 GLU A1009 -26.235 2.264 -17.984 1.00 35.16 H ATOM 1912 HG2 GLU A1009 -27.341 2.262 -16.641 1.00 35.16 H ATOM 1913 N GLY A1010 -22.657 1.295 -14.679 1.00 27.84 N ATOM 1914 CA GLY A1010 -21.732 0.852 -13.634 1.00 27.29 C ATOM 1915 C GLY A1010 -21.077 2.043 -12.915 1.00 30.56 C ATOM 1916 O GLY A1010 -20.854 1.969 -11.707 1.00 30.70 O ATOM 1917 H GLY A1010 -22.337 1.226 -15.636 1.00 27.84 H ATOM 1918 HA3 GLY A1010 -20.956 0.239 -14.093 1.00 27.29 H ATOM 1919 HA2 GLY A1010 -22.247 0.220 -12.909 1.00 27.29 H ATOM 1920 N MET A1011 -20.798 3.140 -13.643 1.00 27.80 N ATOM 1921 CA MET A1011 -20.230 4.381 -13.113 1.00 26.42 C ATOM 1922 C MET A1011 -21.251 5.243 -12.348 1.00 31.30 C ATOM 1923 O MET A1011 -20.854 5.901 -11.387 1.00 31.07 O ATOM 1924 CB MET A1011 -19.591 5.196 -14.253 1.00 27.40 C ATOM 1925 CG MET A1011 -18.266 4.634 -14.804 1.00 29.13 C ATOM 1926 SD MET A1011 -16.888 4.453 -13.634 1.00 32.16 S ATOM 1927 CE MET A1011 -16.919 6.084 -12.860 1.00 29.76 C ATOM 1928 H MET A1011 -20.981 3.129 -14.638 1.00 27.80 H ATOM 1929 HA MET A1011 -19.451 4.119 -12.397 1.00 26.42 H ATOM 1930 HB3 MET A1011 -19.416 6.218 -13.918 1.00 27.40 H ATOM 1931 HB2 MET A1011 -20.304 5.291 -15.073 1.00 27.40 H ATOM 1932 HG3 MET A1011 -17.929 5.278 -15.615 1.00 29.13 H ATOM 1933 HG2 MET A1011 -18.424 3.657 -15.250 1.00 29.13 H ATOM 1934 HE1 MET A1011 -15.990 6.273 -12.328 1.00 29.76 H ATOM 1935 HE2 MET A1011 -17.055 6.852 -13.618 1.00 29.76 H ATOM 1936 HE3 MET A1011 -17.742 6.148 -12.148 1.00 29.76 H ATOM 1937 N ALA A1012 -22.535 5.211 -12.749 1.00 27.75 N ATOM 1938 CA ALA A1012 -23.634 5.849 -12.016 1.00 28.69 C ATOM 1939 C ALA A1012 -23.888 5.180 -10.659 1.00 34.11 C ATOM 1940 O ALA A1012 -24.101 5.891 -9.678 1.00 34.50 O ATOM 1941 CB ALA A1012 -24.917 5.843 -12.856 1.00 29.26 C ATOM 1942 H ALA A1012 -22.793 4.685 -13.573 1.00 27.75 H ATOM 1943 HA ALA A1012 -23.360 6.890 -11.829 1.00 28.69 H ATOM 1944 HB1 ALA A1012 -25.767 6.222 -12.287 1.00 29.26 H ATOM 1945 HB2 ALA A1012 -24.815 6.478 -13.734 1.00 29.26 H ATOM 1946 HB3 ALA A1012 -25.167 4.837 -13.194 1.00 29.26 H ATOM 1947 N TYR A1013 -23.802 3.837 -10.621 1.00 31.58 N ATOM 1948 CA TYR A1013 -23.833 3.052 -9.389 1.00 32.97 C ATOM 1949 C TYR A1013 -22.647 3.367 -8.458 1.00 36.19 C ATOM 1950 O TYR A1013 -22.873 3.547 -7.265 1.00 37.27 O ATOM 1951 CB TYR A1013 -23.952 1.546 -9.717 1.00 34.46 C ATOM 1952 CG TYR A1013 -23.724 0.624 -8.528 1.00 37.28 C ATOM 1953 CD1 TYR A1013 -24.733 0.447 -7.560 1.00 41.29 C ATOM 1954 CD2 TYR A1013 -22.475 -0.004 -8.357 1.00 37.10 C ATOM 1955 CE1 TYR A1013 -24.484 -0.335 -6.415 1.00 41.87 C ATOM 1956 CE2 TYR A1013 -22.228 -0.795 -7.220 1.00 38.57 C ATOM 1957 CZ TYR A1013 -23.227 -0.947 -6.240 1.00 45.11 C ATOM 1958 OH TYR A1013 -22.971 -1.682 -5.119 1.00 46.37 O ATOM 1959 H TYR A1013 -23.632 3.324 -11.475 1.00 31.58 H ATOM 1960 HA TYR A1013 -24.744 3.336 -8.858 1.00 32.97 H ATOM 1961 HB3 TYR A1013 -23.229 1.281 -10.489 1.00 34.46 H ATOM 1962 HB2 TYR A1013 -24.932 1.339 -10.149 1.00 34.46 H ATOM 1963 HD1 TYR A1013 -25.691 0.933 -7.679 1.00 41.29 H ATOM 1964 HD2 TYR A1013 -21.699 0.134 -9.093 1.00 37.10 H ATOM 1965 HE1 TYR A1013 -25.254 -0.453 -5.668 1.00 41.87 H ATOM 1966 HE2 TYR A1013 -21.271 -1.279 -7.103 1.00 38.57 H ATOM 1967 HH TYR A1013 -23.715 -1.718 -4.512 1.00 46.37 H ATOM 1968 N LEU A1014 -21.426 3.458 -9.016 1.00 29.93 N ATOM 1969 CA LEU A1014 -20.195 3.785 -8.288 1.00 29.88 C ATOM 1970 C LEU A1014 -20.270 5.149 -7.570 1.00 33.60 C ATOM 1971 O LEU A1014 -19.846 5.249 -6.419 1.00 34.49 O ATOM 1972 CB LEU A1014 -19.001 3.715 -9.269 1.00 29.28 C ATOM 1973 CG LEU A1014 -17.604 3.885 -8.634 1.00 33.67 C ATOM 1974 CD1 LEU A1014 -17.247 2.688 -7.739 1.00 34.68 C ATOM 1975 CD2 LEU A1014 -16.526 4.121 -9.705 1.00 34.91 C ATOM 1976 H LEU A1014 -21.321 3.285 -10.007 1.00 29.93 H ATOM 1977 HA LEU A1014 -20.068 3.014 -7.526 1.00 29.88 H ATOM 1978 HB3 LEU A1014 -19.131 4.492 -10.023 1.00 29.28 H ATOM 1979 HB2 LEU A1014 -19.028 2.770 -9.814 1.00 29.28 H ATOM 1980 HG LEU A1014 -17.600 4.778 -8.012 1.00 33.67 H ATOM 1981 HD11 LEU A1014 -16.188 2.679 -7.476 1.00 34.68 H ATOM 1982 HD12 LEU A1014 -17.808 2.711 -6.806 1.00 34.68 H ATOM 1983 HD13 LEU A1014 -17.477 1.744 -8.233 1.00 34.68 H ATOM 1984 HD21 LEU A1014 -15.644 3.497 -9.557 1.00 34.91 H ATOM 1985 HD22 LEU A1014 -16.898 3.915 -10.707 1.00 34.91 H ATOM 1986 HD23 LEU A1014 -16.193 5.159 -9.688 1.00 34.91 H ATOM 1987 N HIS A1015 -20.849 6.150 -8.253 1.00 30.39 N ATOM 1988 CA HIS A1015 -21.057 7.508 -7.748 1.00 30.40 C ATOM 1989 C HIS A1015 -22.203 7.615 -6.730 1.00 37.10 C ATOM 1990 O HIS A1015 -22.134 8.480 -5.858 1.00 37.94 O ATOM 1991 CB HIS A1015 -21.294 8.459 -8.934 1.00 29.83 C ATOM 1992 CG HIS A1015 -20.101 8.684 -9.828 1.00 31.72 C ATOM 1993 ND1 HIS A1015 -20.082 9.715 -10.769 1.00 32.83 N ATOM 1994 CD2 HIS A1015 -18.898 8.007 -9.891 1.00 32.40 C ATOM 1995 CE1 HIS A1015 -18.890 9.629 -11.339 1.00 31.99 C ATOM 1996 NE2 HIS A1015 -18.143 8.644 -10.852 1.00 31.94 N ATOM 1997 H HIS A1015 -21.169 5.978 -9.197 1.00 30.39 H ATOM 1998 HA HIS A1015 -20.152 7.828 -7.229 1.00 30.40 H ATOM 1999 HB3 HIS A1015 -21.608 9.438 -8.569 1.00 29.83 H ATOM 2000 HB2 HIS A1015 -22.112 8.089 -9.554 1.00 29.83 H ATOM 2001 HD2 HIS A1015 -18.524 7.155 -9.345 1.00 32.40 H ATOM 2002 HE1 HIS A1015 -18.573 10.275 -12.138 1.00 31.99 H ATOM 2003 HE2 HIS A1015 -17.190 8.424 -11.119 1.00 31.94 H ATOM 2004 N ALA A1016 -23.211 6.730 -6.834 1.00 34.33 N ATOM 2005 CA ALA A1016 -24.292 6.585 -5.856 1.00 35.70 C ATOM 2006 C ALA A1016 -23.821 5.922 -4.546 1.00 40.39 C ATOM 2007 O ALA A1016 -24.360 6.244 -3.489 1.00 42.00 O ATOM 2008 CB ALA A1016 -25.451 5.800 -6.489 1.00 36.70 C ATOM 2009 H ALA A1016 -23.210 6.064 -7.594 1.00 34.33 H ATOM 2010 HA ALA A1016 -24.662 7.581 -5.608 1.00 35.70 H ATOM 2011 HB1 ALA A1016 -26.291 5.712 -5.799 1.00 36.70 H ATOM 2012 HB2 ALA A1016 -25.818 6.300 -7.386 1.00 36.70 H ATOM 2013 HB3 ALA A1016 -25.152 4.791 -6.772 1.00 36.70 H ATOM 2014 N GLN A1017 -22.787 5.064 -4.635 1.00 37.13 N ATOM 2015 CA GLN A1017 -22.036 4.512 -3.502 1.00 37.34 C ATOM 2016 C GLN A1017 -20.962 5.483 -2.955 1.00 40.83 C ATOM 2017 O GLN A1017 -20.257 5.120 -2.013 1.00 41.85 O ATOM 2018 CB GLN A1017 -21.413 3.155 -3.915 1.00 37.57 C ATOM 2019 CG GLN A1017 -22.410 2.027 -4.261 1.00 50.69 C ATOM 2020 CD GLN A1017 -23.428 1.735 -3.159 1.00 63.42 C ATOM 2021 OE1 GLN A1017 -23.055 1.428 -2.030 1.00 61.45 O ATOM 2022 NE2 GLN A1017 -24.719 1.815 -3.487 1.00 53.50 N ATOM 2023 H GLN A1017 -22.426 4.834 -5.551 1.00 37.13 H ATOM 2024 HA GLN A1017 -22.727 4.347 -2.674 1.00 37.34 H ATOM 2025 HB3 GLN A1017 -20.770 2.791 -3.113 1.00 37.57 H ATOM 2026 HB2 GLN A1017 -20.758 3.304 -4.773 1.00 37.57 H ATOM 2027 HG3 GLN A1017 -21.859 1.109 -4.466 1.00 50.69 H ATOM 2028 HG2 GLN A1017 -22.944 2.264 -5.177 1.00 50.69 H ATOM 2029 HE22 GLN A1017 -25.427 1.631 -2.791 1.00 53.50 H ATOM 2030 HE21 GLN A1017 -24.995 2.075 -4.422 1.00 53.50 H ATOM 2031 N HIS A1018 -20.868 6.694 -3.535 1.00 43.65 N ATOM 2032 CA HIS A1018 -19.987 7.804 -3.159 1.00 42.72 C ATOM 2033 C HIS A1018 -18.485 7.544 -3.385 1.00 42.39 C ATOM 2034 O HIS A1018 -17.658 8.063 -2.636 1.00 42.28 O ATOM 2035 CB HIS A1018 -20.325 8.353 -1.751 1.00 46.64 C ATOM 2036 CG HIS A1018 -21.690 8.984 -1.654 1.00 52.37 C ATOM 2037 ND1 HIS A1018 -21.945 10.278 -2.076 1.00 54.35 N ATOM 2038 CD2 HIS A1018 -22.888 8.509 -1.166 1.00 56.51 C ATOM 2039 CE1 HIS A1018 -23.236 10.521 -1.839 1.00 55.92 C ATOM 2040 NE2 HIS A1018 -23.871 9.493 -1.289 1.00 57.64 N ATOM 2041 H HIS A1018 -21.499 6.901 -4.297 1.00 43.65 H ATOM 2042 HA HIS A1018 -20.228 8.589 -3.873 1.00 42.72 H ATOM 2043 HB3 HIS A1018 -19.613 9.122 -1.457 1.00 46.64 H ATOM 2044 HB2 HIS A1018 -20.245 7.572 -0.994 1.00 46.64 H ATOM 2045 HD1 HIS A1018 -21.281 10.930 -2.475 1.00 54.35 H ATOM 2046 HD2 HIS A1018 -23.116 7.542 -0.744 1.00 56.51 H ATOM 2047 HE1 HIS A1018 -23.715 11.462 -2.067 1.00 55.92 H ATOM 2048 N TYR A1019 -18.162 6.786 -4.443 1.00 35.47 N ATOM 2049 CA TYR A1019 -16.796 6.540 -4.899 1.00 33.30 C ATOM 2050 C TYR A1019 -16.560 7.203 -6.265 1.00 34.14 C ATOM 2051 O TYR A1019 -17.489 7.334 -7.060 1.00 33.14 O ATOM 2052 CB TYR A1019 -16.557 5.022 -5.022 1.00 34.28 C ATOM 2053 CG TYR A1019 -16.661 4.215 -3.739 1.00 38.78 C ATOM 2054 CD1 TYR A1019 -15.668 4.330 -2.746 1.00 41.85 C ATOM 2055 CD2 TYR A1019 -17.732 3.318 -3.549 1.00 40.74 C ATOM 2056 CE1 TYR A1019 -15.753 3.568 -1.566 1.00 44.99 C ATOM 2057 CE2 TYR A1019 -17.808 2.539 -2.378 1.00 43.80 C ATOM 2058 CZ TYR A1019 -16.817 2.663 -1.385 1.00 51.67 C ATOM 2059 OH TYR A1019 -16.885 1.906 -0.251 1.00 54.79 O ATOM 2060 H TYR A1019 -18.894 6.392 -5.020 1.00 35.47 H ATOM 2061 HA TYR A1019 -16.081 6.951 -4.188 1.00 33.30 H ATOM 2062 HB3 TYR A1019 -15.565 4.835 -5.438 1.00 34.28 H ATOM 2063 HB2 TYR A1019 -17.263 4.613 -5.740 1.00 34.28 H ATOM 2064 HD1 TYR A1019 -14.835 4.996 -2.893 1.00 41.85 H ATOM 2065 HD2 TYR A1019 -18.492 3.220 -4.308 1.00 40.74 H ATOM 2066 HE1 TYR A1019 -14.987 3.663 -0.812 1.00 44.99 H ATOM 2067 HE2 TYR A1019 -18.625 1.845 -2.245 1.00 43.80 H ATOM 2068 HH TYR A1019 -16.158 2.067 0.354 1.00 54.79 H ATOM 2069 N ILE A1020 -15.289 7.536 -6.521 1.00 29.77 N ATOM 2070 CA ILE A1020 -14.732 7.899 -7.826 1.00 28.07 C ATOM 2071 C ILE A1020 -13.745 6.798 -8.262 1.00 32.77 C ATOM 2072 O ILE A1020 -13.145 6.156 -7.399 1.00 34.18 O ATOM 2073 CB ILE A1020 -13.975 9.261 -7.762 1.00 30.74 C ATOM 2074 CG1 ILE A1020 -12.981 9.361 -6.573 1.00 31.83 C ATOM 2075 CG2 ILE A1020 -14.990 10.419 -7.776 1.00 31.74 C ATOM 2076 CD1 ILE A1020 -12.103 10.614 -6.545 1.00 34.37 C ATOM 2077 H ILE A1020 -14.600 7.396 -5.793 1.00 29.77 H ATOM 2078 HA ILE A1020 -15.529 7.954 -8.569 1.00 28.07 H ATOM 2079 HB ILE A1020 -13.387 9.362 -8.676 1.00 30.74 H ATOM 2080 HG13 ILE A1020 -12.317 8.498 -6.563 1.00 31.83 H ATOM 2081 HG12 ILE A1020 -13.528 9.323 -5.635 1.00 31.83 H ATOM 2082 HG21 ILE A1020 -14.504 11.393 -7.804 1.00 31.74 H ATOM 2083 HG22 ILE A1020 -15.631 10.362 -8.656 1.00 31.74 H ATOM 2084 HG23 ILE A1020 -15.638 10.391 -6.901 1.00 31.74 H ATOM 2085 HD11 ILE A1020 -11.396 10.561 -5.718 1.00 34.37 H ATOM 2086 HD12 ILE A1020 -11.523 10.701 -7.459 1.00 34.37 H ATOM 2087 HD13 ILE A1020 -12.688 11.525 -6.418 1.00 34.37 H ATOM 2088 N HIS A1021 -13.614 6.578 -9.582 1.00 29.57 N ATOM 2089 CA HIS A1021 -12.786 5.511 -10.155 1.00 28.01 C ATOM 2090 C HIS A1021 -11.322 5.937 -10.347 1.00 30.31 C ATOM 2091 O HIS A1021 -10.436 5.175 -9.969 1.00 28.41 O ATOM 2092 CB HIS A1021 -13.403 5.013 -11.479 1.00 27.19 C ATOM 2093 CG HIS A1021 -12.853 3.693 -11.959 1.00 29.30 C ATOM 2094 ND1 HIS A1021 -11.667 3.594 -12.689 1.00 30.35 N ATOM 2095 CD2 HIS A1021 -13.363 2.425 -11.774 1.00 30.30 C ATOM 2096 CE1 HIS A1021 -11.504 2.297 -12.912 1.00 29.49 C ATOM 2097 NE2 HIS A1021 -12.474 1.556 -12.382 1.00 29.77 N ATOM 2098 H HIS A1021 -14.123 7.159 -10.238 1.00 29.57 H ATOM 2099 HA HIS A1021 -12.801 4.668 -9.461 1.00 28.01 H ATOM 2100 HB3 HIS A1021 -13.282 5.753 -12.271 1.00 27.19 H ATOM 2101 HB2 HIS A1021 -14.474 4.880 -11.356 1.00 27.19 H ATOM 2102 HD2 HIS A1021 -14.255 2.085 -11.273 1.00 30.30 H ATOM 2103 HE1 HIS A1021 -10.667 1.883 -13.456 1.00 29.49 H ATOM 2104 HE2 HIS A1021 -12.538 0.547 -12.425 1.00 29.77 H ATOM 2105 N ARG A1022 -11.096 7.121 -10.943 1.00 26.88 N ATOM 2106 CA ARG A1022 -9.784 7.722 -11.235 1.00 26.62 C ATOM 2107 C ARG A1022 -8.908 6.986 -12.278 1.00 29.84 C ATOM 2108 O ARG A1022 -7.774 7.416 -12.489 1.00 30.79 O ATOM 2109 CB ARG A1022 -8.980 7.994 -9.941 1.00 26.30 C ATOM 2110 CG ARG A1022 -9.678 8.917 -8.919 1.00 34.16 C ATOM 2111 CD ARG A1022 -8.867 9.205 -7.638 1.00 40.37 C ATOM 2112 NE ARG A1022 -7.494 9.662 -7.927 1.00 53.37 N ATOM 2113 CZ ARG A1022 -6.339 9.249 -7.370 1.00 66.01 C ATOM 2114 NH1 ARG A1022 -6.301 8.376 -6.352 1.00 50.08 N ATOM 2115 NH2 ARG A1022 -5.186 9.718 -7.861 1.00 58.24 N1+ ATOM 2116 H ARG A1022 -11.894 7.664 -11.248 1.00 26.88 H ATOM 2117 HA ARG A1022 -10.003 8.685 -11.691 1.00 26.62 H ATOM 2118 HB3 ARG A1022 -8.038 8.461 -10.224 1.00 26.30 H ATOM 2119 HB2 ARG A1022 -8.703 7.055 -9.468 1.00 26.30 H ATOM 2120 HG3 ARG A1022 -10.571 8.380 -8.599 1.00 34.16 H ATOM 2121 HG2 ARG A1022 -10.035 9.838 -9.374 1.00 34.16 H ATOM 2122 HD3 ARG A1022 -8.962 8.416 -6.896 1.00 40.37 H ATOM 2123 HD2 ARG A1022 -9.304 10.086 -7.170 1.00 40.37 H ATOM 2124 HE ARG A1022 -7.428 10.323 -8.688 1.00 53.37 H ATOM 2125 HH12 ARG A1022 -5.420 8.065 -5.971 1.00 50.08 H ATOM 2126 HH11 ARG A1022 -7.160 7.948 -6.033 1.00 50.08 H ATOM 2127 HH22 ARG A1022 -4.301 9.402 -7.489 1.00 58.24 H ATOM 2128 HH21 ARG A1022 -5.185 10.345 -8.654 1.00 58.24 H ATOM 2129 N ASN A1023 -9.418 5.931 -12.935 1.00 25.28 N ATOM 2130 CA ASN A1023 -8.672 5.162 -13.934 1.00 24.95 C ATOM 2131 C ASN A1023 -9.615 4.581 -15.005 1.00 27.49 C ATOM 2132 O ASN A1023 -9.413 3.447 -15.436 1.00 27.32 O ATOM 2133 CB ASN A1023 -7.816 4.068 -13.232 1.00 27.86 C ATOM 2134 CG ASN A1023 -6.588 3.573 -14.014 1.00 46.94 C ATOM 2135 OD1 ASN A1023 -6.243 4.089 -15.076 1.00 37.71 O ATOM 2136 ND2 ASN A1023 -5.925 2.544 -13.483 1.00 47.99 N ATOM 2137 H ASN A1023 -10.358 5.614 -12.735 1.00 25.28 H ATOM 2138 HA ASN A1023 -8.030 5.821 -14.520 1.00 24.95 H ATOM 2139 HB3 ASN A1023 -8.437 3.219 -12.941 1.00 27.86 H ATOM 2140 HB2 ASN A1023 -7.417 4.470 -12.303 1.00 27.86 H ATOM 2141 HD22 ASN A1023 -5.119 2.161 -13.957 1.00 47.99 H ATOM 2142 HD21 ASN A1023 -6.237 2.118 -12.622 1.00 47.99 H ATOM 2143 N LEU A1024 -10.648 5.336 -15.411 1.00 23.70 N ATOM 2144 CA LEU A1024 -11.619 4.879 -16.405 1.00 23.85 C ATOM 2145 C LEU A1024 -11.026 4.992 -17.823 1.00 29.77 C ATOM 2146 O LEU A1024 -10.781 6.099 -18.301 1.00 30.30 O ATOM 2147 CB LEU A1024 -12.947 5.643 -16.212 1.00 23.60 C ATOM 2148 CG LEU A1024 -14.133 5.123 -17.053 1.00 28.86 C ATOM 2149 CD1 LEU A1024 -14.514 3.664 -16.722 1.00 29.18 C ATOM 2150 CD2 LEU A1024 -15.338 6.057 -16.884 1.00 32.57 C ATOM 2151 H LEU A1024 -10.782 6.267 -15.035 1.00 23.70 H ATOM 2152 HA LEU A1024 -11.821 3.825 -16.203 1.00 23.85 H ATOM 2153 HB3 LEU A1024 -12.786 6.698 -16.431 1.00 23.60 H ATOM 2154 HB2 LEU A1024 -13.227 5.603 -15.157 1.00 23.60 H ATOM 2155 HG LEU A1024 -13.855 5.162 -18.107 1.00 28.86 H ATOM 2156 HD11 LEU A1024 -15.581 3.551 -16.533 1.00 29.18 H ATOM 2157 HD12 LEU A1024 -14.259 2.998 -17.547 1.00 29.18 H ATOM 2158 HD13 LEU A1024 -14.004 3.295 -15.832 1.00 29.18 H ATOM 2159 HD21 LEU A1024 -16.218 5.670 -17.397 1.00 32.57 H ATOM 2160 HD22 LEU A1024 -15.592 6.194 -15.833 1.00 32.57 H ATOM 2161 HD23 LEU A1024 -15.118 7.041 -17.292 1.00 32.57 H ATOM 2162 N ALA A1025 -10.781 3.825 -18.437 1.00 25.59 N ATOM 2163 CA ALA A1025 -10.140 3.647 -19.741 1.00 24.45 C ATOM 2164 C ALA A1025 -10.518 2.265 -20.300 1.00 24.35 C ATOM 2165 O ALA A1025 -10.969 1.410 -19.538 1.00 23.60 O ATOM 2166 CB ALA A1025 -8.617 3.790 -19.578 1.00 25.60 C ATOM 2167 H ALA A1025 -11.033 2.965 -17.971 1.00 25.59 H ATOM 2168 HA ALA A1025 -10.493 4.413 -20.432 1.00 24.45 H ATOM 2169 HB1 ALA A1025 -8.133 3.871 -20.549 1.00 25.60 H ATOM 2170 HB2 ALA A1025 -8.354 4.689 -19.019 1.00 25.60 H ATOM 2171 HB3 ALA A1025 -8.180 2.936 -19.064 1.00 25.60 H ATOM 2172 N ALA A1026 -10.313 2.052 -21.613 1.00 21.93 N ATOM 2173 CA ALA A1026 -10.616 0.790 -22.307 1.00 22.59 C ATOM 2174 C ALA A1026 -9.798 -0.431 -21.830 1.00 27.08 C ATOM 2175 O ALA A1026 -10.290 -1.554 -21.927 1.00 26.36 O ATOM 2176 CB ALA A1026 -10.453 0.991 -23.819 1.00 24.44 C ATOM 2177 H ALA A1026 -9.928 2.793 -22.186 1.00 21.93 H ATOM 2178 HA ALA A1026 -11.668 0.563 -22.117 1.00 22.59 H ATOM 2179 HB1 ALA A1026 -10.733 0.090 -24.365 1.00 24.44 H ATOM 2180 HB2 ALA A1026 -11.089 1.800 -24.179 1.00 24.44 H ATOM 2181 HB3 ALA A1026 -9.423 1.233 -24.083 1.00 24.44 H ATOM 2182 N ARG A1027 -8.591 -0.185 -21.289 1.00 25.25 N ATOM 2183 CA ARG A1027 -7.742 -1.139 -20.565 1.00 25.45 C ATOM 2184 C ARG A1027 -8.425 -1.710 -19.307 1.00 28.29 C ATOM 2185 O ARG A1027 -8.223 -2.878 -18.976 1.00 27.42 O ATOM 2186 CB ARG A1027 -6.432 -0.403 -20.184 1.00 27.95 C ATOM 2187 CG ARG A1027 -5.435 -1.193 -19.307 1.00 42.70 C ATOM 2188 CD ARG A1027 -4.162 -0.408 -18.947 1.00 56.67 C ATOM 2189 NE ARG A1027 -3.234 -0.266 -20.085 1.00 69.04 N ATOM 2190 CZ ARG A1027 -2.191 0.580 -20.180 1.00 82.45 C ATOM 2191 NH1 ARG A1027 -1.417 0.527 -21.271 1.00 58.12 N ATOM 2192 NH2 ARG A1027 -1.893 1.468 -19.218 1.00 78.84 N1+ ATOM 2193 H ARG A1027 -8.243 0.766 -21.316 1.00 25.25 H ATOM 2194 HA ARG A1027 -7.506 -1.970 -21.231 1.00 25.45 H ATOM 2195 HB3 ARG A1027 -6.693 0.509 -19.645 1.00 27.95 H ATOM 2196 HB2 ARG A1027 -5.932 -0.070 -21.091 1.00 27.95 H ATOM 2197 HG3 ARG A1027 -5.149 -2.068 -19.890 1.00 42.70 H ATOM 2198 HG2 ARG A1027 -5.880 -1.580 -18.390 1.00 42.70 H ATOM 2199 HD3 ARG A1027 -3.675 -0.813 -18.060 1.00 56.67 H ATOM 2200 HD2 ARG A1027 -4.467 0.608 -18.695 1.00 56.67 H ATOM 2201 HE ARG A1027 -3.396 -0.904 -20.850 1.00 69.04 H ATOM 2202 HH12 ARG A1027 -0.649 1.172 -21.381 1.00 58.12 H ATOM 2203 HH11 ARG A1027 -1.615 -0.134 -22.007 1.00 58.12 H ATOM 2204 HH22 ARG A1027 -1.107 2.094 -19.316 1.00 78.84 H ATOM 2205 HH21 ARG A1027 -2.462 1.513 -18.385 1.00 78.84 H ATOM 2206 N ASN A1028 -9.194 -0.846 -18.632 1.00 25.48 N ATOM 2207 CA ASN A1028 -9.823 -1.077 -17.334 1.00 25.69 C ATOM 2208 C ASN A1028 -11.317 -1.429 -17.473 1.00 31.11 C ATOM 2209 O ASN A1028 -11.999 -1.498 -16.454 1.00 31.65 O ATOM 2210 CB ASN A1028 -9.602 0.176 -16.449 1.00 25.12 C ATOM 2211 CG ASN A1028 -8.115 0.495 -16.245 1.00 40.47 C ATOM 2212 OD1 ASN A1028 -7.402 -0.253 -15.588 1.00 35.79 O ATOM 2213 ND2 ASN A1028 -7.627 1.597 -16.814 1.00 30.20 N ATOM 2214 H ASN A1028 -9.333 0.079 -19.016 1.00 25.48 H ATOM 2215 HA ASN A1028 -9.355 -1.930 -16.841 1.00 25.69 H ATOM 2216 HB3 ASN A1028 -10.038 0.026 -15.461 1.00 25.12 H ATOM 2217 HB2 ASN A1028 -10.111 1.042 -16.878 1.00 25.12 H ATOM 2218 HD22 ASN A1028 -6.658 1.847 -16.685 1.00 30.20 H ATOM 2219 HD21 ASN A1028 -8.239 2.229 -17.310 1.00 30.20 H ATOM 2220 N VAL A1029 -11.798 -1.668 -18.706 1.00 26.95 N ATOM 2221 CA VAL A1029 -13.139 -2.175 -18.986 1.00 26.70 C ATOM 2222 C VAL A1029 -12.988 -3.520 -19.714 1.00 31.33 C ATOM 2223 O VAL A1029 -12.373 -3.583 -20.778 1.00 31.48 O ATOM 2224 CB VAL A1029 -13.976 -1.193 -19.852 1.00 30.65 C ATOM 2225 CG1 VAL A1029 -15.338 -1.776 -20.277 1.00 31.45 C ATOM 2226 CG2 VAL A1029 -14.220 0.131 -19.105 1.00 29.49 C ATOM 2227 H VAL A1029 -11.183 -1.583 -19.503 1.00 26.95 H ATOM 2228 HA VAL A1029 -13.684 -2.346 -18.056 1.00 26.70 H ATOM 2229 HB VAL A1029 -13.412 -0.960 -20.757 1.00 30.65 H ATOM 2230 HG11 VAL A1029 -15.924 -1.049 -20.837 1.00 31.45 H ATOM 2231 HG12 VAL A1029 -15.230 -2.654 -20.910 1.00 31.45 H ATOM 2232 HG13 VAL A1029 -15.921 -2.070 -19.403 1.00 31.45 H ATOM 2233 HG21 VAL A1029 -14.744 0.849 -19.734 1.00 29.49 H ATOM 2234 HG22 VAL A1029 -14.822 -0.027 -18.209 1.00 29.49 H ATOM 2235 HG23 VAL A1029 -13.291 0.602 -18.790 1.00 29.49 H ATOM 2236 N LEU A1030 -13.548 -4.562 -19.088 1.00 29.26 N ATOM 2237 CA LEU A1030 -13.434 -5.968 -19.450 1.00 29.87 C ATOM 2238 C LEU A1030 -14.733 -6.447 -20.113 1.00 34.28 C ATOM 2239 O LEU A1030 -15.816 -6.037 -19.705 1.00 33.78 O ATOM 2240 CB LEU A1030 -13.138 -6.783 -18.169 1.00 30.51 C ATOM 2241 CG LEU A1030 -11.936 -6.290 -17.328 1.00 34.35 C ATOM 2242 CD1 LEU A1030 -11.856 -7.064 -16.001 1.00 34.54 C ATOM 2243 CD2 LEU A1030 -10.610 -6.344 -18.112 1.00 35.67 C ATOM 2244 H LEU A1030 -14.085 -4.388 -18.246 1.00 29.26 H ATOM 2245 HA LEU A1030 -12.621 -6.109 -20.154 1.00 29.87 H ATOM 2246 HB3 LEU A1030 -12.970 -7.825 -18.443 1.00 30.51 H ATOM 2247 HB2 LEU A1030 -14.023 -6.771 -17.529 1.00 30.51 H ATOM 2248 HG LEU A1030 -12.099 -5.248 -17.048 1.00 34.35 H ATOM 2249 HD11 LEU A1030 -10.853 -7.056 -15.576 1.00 34.54 H ATOM 2250 HD12 LEU A1030 -12.517 -6.617 -15.257 1.00 34.54 H ATOM 2251 HD13 LEU A1030 -12.155 -8.106 -16.124 1.00 34.54 H ATOM 2252 HD21 LEU A1030 -9.796 -6.774 -17.533 1.00 35.67 H ATOM 2253 HD22 LEU A1030 -10.700 -6.943 -19.016 1.00 35.67 H ATOM 2254 HD23 LEU A1030 -10.295 -5.343 -18.409 1.00 35.67 H ATOM 2255 N LEU A1031 -14.593 -7.319 -21.118 1.00 30.49 N ATOM 2256 CA LEU A1031 -15.677 -7.865 -21.925 1.00 32.51 C ATOM 2257 C LEU A1031 -15.990 -9.291 -21.448 1.00 35.33 C ATOM 2258 O LEU A1031 -15.113 -10.153 -21.506 1.00 35.33 O ATOM 2259 CB LEU A1031 -15.209 -7.845 -23.396 1.00 33.91 C ATOM 2260 CG LEU A1031 -16.302 -8.174 -24.433 1.00 41.72 C ATOM 2261 CD1 LEU A1031 -17.357 -7.065 -24.522 1.00 42.04 C ATOM 2262 CD2 LEU A1031 -15.696 -8.439 -25.818 1.00 45.52 C ATOM 2263 H LEU A1031 -13.662 -7.617 -21.389 1.00 30.49 H ATOM 2264 HA LEU A1031 -16.567 -7.241 -21.825 1.00 32.51 H ATOM 2265 HB3 LEU A1031 -14.375 -8.541 -23.507 1.00 33.91 H ATOM 2266 HB2 LEU A1031 -14.790 -6.866 -23.627 1.00 33.91 H ATOM 2267 HG LEU A1031 -16.801 -9.093 -24.128 1.00 41.72 H ATOM 2268 HD11 LEU A1031 -17.957 -7.181 -25.423 1.00 42.04 H ATOM 2269 HD12 LEU A1031 -18.043 -7.102 -23.679 1.00 42.04 H ATOM 2270 HD13 LEU A1031 -16.903 -6.074 -24.546 1.00 42.04 H ATOM 2271 HD21 LEU A1031 -16.156 -9.306 -26.290 1.00 45.52 H ATOM 2272 HD22 LEU A1031 -15.839 -7.592 -26.491 1.00 45.52 H ATOM 2273 HD23 LEU A1031 -14.625 -8.629 -25.764 1.00 45.52 H ATOM 2274 N ASP A1032 -17.230 -9.515 -20.985 1.00 33.70 N ATOM 2275 CA ASP A1032 -17.712 -10.827 -20.543 1.00 35.49 C ATOM 2276 C ASP A1032 -18.166 -11.661 -21.755 1.00 42.98 C ATOM 2277 O ASP A1032 -17.727 -12.798 -21.921 1.00 43.01 O ATOM 2278 CB ASP A1032 -18.822 -10.678 -19.476 1.00 38.24 C ATOM 2279 CG ASP A1032 -19.218 -11.987 -18.779 1.00 57.45 C ATOM 2280 OD1 ASP A1032 -20.169 -12.639 -19.268 1.00 62.50 O ATOM 2281 OD2 ASP A1032 -18.465 -12.387 -17.864 1.00 62.05 O1- ATOM 2282 H ASP A1032 -17.907 -8.764 -20.978 1.00 33.70 H ATOM 2283 HA ASP A1032 -16.879 -11.358 -20.082 1.00 35.49 H ATOM 2284 HB3 ASP A1032 -19.703 -10.217 -19.924 1.00 38.24 H ATOM 2285 HB2 ASP A1032 -18.498 -9.962 -18.720 1.00 38.24 H ATOM 2286 N ASN A1033 -19.010 -11.038 -22.589 1.00 43.24 N ATOM 2287 CA ASN A1033 -19.496 -11.544 -23.869 1.00 46.44 C ATOM 2288 C ASN A1033 -19.762 -10.349 -24.801 1.00 51.69 C ATOM 2289 O ASN A1033 -19.561 -9.203 -24.398 1.00 49.09 O ATOM 2290 CB ASN A1033 -20.703 -12.502 -23.675 1.00 48.31 C ATOM 2291 CG ASN A1033 -21.947 -11.875 -23.033 1.00 66.28 C ATOM 2292 OD1 ASN A1033 -22.671 -11.117 -23.674 1.00 59.86 O ATOM 2293 ND2 ASN A1033 -22.211 -12.205 -21.767 1.00 59.92 N ATOM 2294 H ASN A1033 -19.289 -10.090 -22.377 1.00 43.24 H ATOM 2295 HA ASN A1033 -18.694 -12.117 -24.331 1.00 46.44 H ATOM 2296 HB3 ASN A1033 -20.389 -13.358 -23.076 1.00 48.31 H ATOM 2297 HB2 ASN A1033 -21.002 -12.918 -24.638 1.00 48.31 H ATOM 2298 HD22 ASN A1033 -23.026 -11.828 -21.307 1.00 59.92 H ATOM 2299 HD21 ASN A1033 -21.579 -12.797 -21.242 1.00 59.92 H ATOM 2300 N ASP A1034 -20.218 -10.631 -26.032 1.00 52.34 N ATOM 2301 CA ASP A1034 -20.535 -9.640 -27.073 1.00 53.71 C ATOM 2302 C ASP A1034 -21.507 -8.516 -26.646 1.00 56.50 C ATOM 2303 O ASP A1034 -21.409 -7.420 -27.190 1.00 55.06 O ATOM 2304 CB ASP A1034 -20.990 -10.266 -28.427 1.00 59.25 C ATOM 2305 CG ASP A1034 -21.924 -11.494 -28.402 1.00 77.62 C ATOM 2306 OD1 ASP A1034 -22.639 -11.706 -27.397 1.00 79.51 O ATOM 2307 OD2 ASP A1034 -22.007 -12.140 -29.469 1.00 88.40 O1- ATOM 2308 H ASP A1034 -20.398 -11.592 -26.284 1.00 52.34 H ATOM 2309 HA ASP A1034 -19.585 -9.140 -27.273 1.00 53.71 H ATOM 2310 HB3 ASP A1034 -20.095 -10.532 -28.993 1.00 59.25 H ATOM 2311 HB2 ASP A1034 -21.495 -9.512 -29.032 1.00 59.25 H ATOM 2312 N ARG A1035 -22.406 -8.796 -25.687 1.00 52.42 N ATOM 2313 CA ARG A1035 -23.448 -7.882 -25.216 1.00 52.12 C ATOM 2314 C ARG A1035 -23.343 -7.580 -23.704 1.00 53.91 C ATOM 2315 O ARG A1035 -24.336 -7.124 -23.136 1.00 54.42 O ATOM 2316 CB ARG A1035 -24.835 -8.467 -25.595 1.00 56.06 C ATOM 2317 CG ARG A1035 -25.086 -8.703 -27.101 1.00 68.03 C ATOM 2318 CD ARG A1035 -24.897 -7.444 -27.966 1.00 74.26 C ATOM 2319 NE ARG A1035 -25.309 -7.644 -29.365 1.00 83.22 N ATOM 2320 CZ ARG A1035 -26.494 -7.332 -29.925 1.00103.41 C ATOM 2321 NH1 ARG A1035 -27.506 -6.799 -29.222 1.00 95.23 N ATOM 2322 NH2 ARG A1035 -26.668 -7.561 -31.233 1.00 92.56 N1+ ATOM 2323 H ARG A1035 -22.419 -9.724 -25.282 1.00 52.42 H ATOM 2324 HA ARG A1035 -23.344 -6.910 -25.700 1.00 52.12 H ATOM 2325 HB3 ARG A1035 -25.620 -7.801 -25.237 1.00 56.06 H ATOM 2326 HB2 ARG A1035 -24.983 -9.410 -25.066 1.00 56.06 H ATOM 2327 HG3 ARG A1035 -26.057 -9.166 -27.280 1.00 68.03 H ATOM 2328 HG2 ARG A1035 -24.352 -9.442 -27.423 1.00 68.03 H ATOM 2329 HD3 ARG A1035 -23.832 -7.242 -28.056 1.00 74.26 H ATOM 2330 HD2 ARG A1035 -25.331 -6.559 -27.506 1.00 74.26 H ATOM 2331 HE ARG A1035 -24.607 -8.071 -29.954 1.00 83.22 H ATOM 2332 HH12 ARG A1035 -28.382 -6.569 -29.667 1.00 95.23 H ATOM 2333 HH11 ARG A1035 -27.412 -6.662 -28.223 1.00 95.23 H ATOM 2334 HH22 ARG A1035 -27.544 -7.335 -31.681 1.00 92.56 H ATOM 2335 HH21 ARG A1035 -25.921 -7.962 -31.782 1.00 92.56 H ATOM 2336 N LEU A1036 -22.174 -7.803 -23.070 1.00 47.46 N ATOM 2337 CA LEU A1036 -21.967 -7.538 -21.640 1.00 44.95 C ATOM 2338 C LEU A1036 -20.533 -7.065 -21.368 1.00 44.87 C ATOM 2339 O LEU A1036 -19.582 -7.752 -21.739 1.00 44.01 O ATOM 2340 CB LEU A1036 -22.340 -8.791 -20.812 1.00 46.48 C ATOM 2341 CG LEU A1036 -22.180 -8.679 -19.274 1.00 50.35 C ATOM 2342 CD1 LEU A1036 -22.973 -7.502 -18.671 1.00 50.69 C ATOM 2343 CD2 LEU A1036 -22.529 -10.018 -18.591 1.00 54.50 C ATOM 2344 H LEU A1036 -21.382 -8.171 -23.579 1.00 47.46 H ATOM 2345 HA LEU A1036 -22.630 -6.724 -21.343 1.00 44.95 H ATOM 2346 HB3 LEU A1036 -21.719 -9.617 -21.159 1.00 46.48 H ATOM 2347 HB2 LEU A1036 -23.369 -9.073 -21.040 1.00 46.48 H ATOM 2348 HG LEU A1036 -21.127 -8.494 -19.056 1.00 50.35 H ATOM 2349 HD11 LEU A1036 -23.473 -7.760 -17.737 1.00 50.69 H ATOM 2350 HD12 LEU A1036 -22.306 -6.670 -18.448 1.00 50.69 H ATOM 2351 HD13 LEU A1036 -23.741 -7.137 -19.353 1.00 50.69 H ATOM 2352 HD21 LEU A1036 -21.721 -10.346 -17.938 1.00 54.50 H ATOM 2353 HD22 LEU A1036 -23.433 -9.959 -17.986 1.00 54.50 H ATOM 2354 HD23 LEU A1036 -22.691 -10.816 -19.315 1.00 54.50 H ATOM 2355 N VAL A1037 -20.428 -5.918 -20.680 1.00 38.25 N ATOM 2356 CA VAL A1037 -19.183 -5.244 -20.316 1.00 36.27 C ATOM 2357 C VAL A1037 -19.170 -4.944 -18.803 1.00 39.75 C ATOM 2358 O VAL A1037 -20.229 -4.712 -18.218 1.00 42.27 O ATOM 2359 CB VAL A1037 -19.016 -3.946 -21.177 1.00 39.78 C ATOM 2360 CG1 VAL A1037 -19.009 -2.583 -20.456 1.00 38.54 C ATOM 2361 CG2 VAL A1037 -17.802 -4.070 -22.103 1.00 38.84 C ATOM 2362 H VAL A1037 -21.272 -5.428 -20.415 1.00 38.25 H ATOM 2363 HA VAL A1037 -18.349 -5.920 -20.508 1.00 36.27 H ATOM 2364 HB VAL A1037 -19.873 -3.887 -21.850 1.00 39.78 H ATOM 2365 HG11 VAL A1037 -18.916 -1.774 -21.181 1.00 38.54 H ATOM 2366 HG12 VAL A1037 -19.935 -2.413 -19.907 1.00 38.54 H ATOM 2367 HG13 VAL A1037 -18.179 -2.490 -19.757 1.00 38.54 H ATOM 2368 HG21 VAL A1037 -17.730 -3.211 -22.767 1.00 38.84 H ATOM 2369 HG22 VAL A1037 -16.873 -4.154 -21.540 1.00 38.84 H ATOM 2370 HG23 VAL A1037 -17.890 -4.953 -22.732 1.00 38.84 H ATOM 2371 N LYS A1038 -17.968 -4.982 -18.204 1.00 33.36 N ATOM 2372 CA LYS A1038 -17.714 -4.878 -16.766 1.00 33.06 C ATOM 2373 C LYS A1038 -16.485 -4.002 -16.491 1.00 35.92 C ATOM 2374 O LYS A1038 -15.436 -4.235 -17.082 1.00 35.20 O ATOM 2375 CB LYS A1038 -17.479 -6.290 -16.190 1.00 36.83 C ATOM 2376 CG LYS A1038 -18.749 -7.145 -16.080 1.00 43.54 C ATOM 2377 CD LYS A1038 -18.421 -8.608 -15.749 1.00 43.25 C ATOM 2378 CE LYS A1038 -19.663 -9.482 -15.509 1.00 48.33 C ATOM 2379 NZ LYS A1038 -20.306 -9.193 -14.214 1.00 58.37 N1+ ATOM 2380 H LYS A1038 -17.149 -5.184 -18.767 1.00 33.36 H ATOM 2381 HA LYS A1038 -18.574 -4.425 -16.277 1.00 33.06 H ATOM 2382 HB3 LYS A1038 -17.052 -6.212 -15.188 1.00 36.83 H ATOM 2383 HB2 LYS A1038 -16.730 -6.807 -16.793 1.00 36.83 H ATOM 2384 HG3 LYS A1038 -19.317 -7.118 -17.009 1.00 43.54 H ATOM 2385 HG2 LYS A1038 -19.391 -6.713 -15.312 1.00 43.54 H ATOM 2386 HD3 LYS A1038 -17.751 -8.642 -14.891 1.00 43.25 H ATOM 2387 HD2 LYS A1038 -17.852 -9.036 -16.575 1.00 43.25 H ATOM 2388 HE3 LYS A1038 -19.380 -10.535 -15.514 1.00 48.33 H ATOM 2389 HE2 LYS A1038 -20.386 -9.341 -16.312 1.00 48.33 H ATOM 2390 HZ1 LYS A1038 -20.568 -8.218 -14.175 1.00 58.37 H ATOM 2391 HZ2 LYS A1038 -21.132 -9.766 -14.115 1.00 58.37 H ATOM 2392 HZ3 LYS A1038 -19.651 -9.405 -13.472 1.00 58.37 H ATOM 2393 N ILE A1039 -16.614 -3.050 -15.556 1.00 32.33 N ATOM 2394 CA ILE A1039 -15.529 -2.171 -15.108 1.00 30.26 C ATOM 2395 C ILE A1039 -14.627 -2.911 -14.094 1.00 36.96 C ATOM 2396 O ILE A1039 -15.145 -3.519 -13.160 1.00 36.41 O ATOM 2397 CB ILE A1039 -16.108 -0.894 -14.429 1.00 32.08 C ATOM 2398 CG1 ILE A1039 -17.001 -0.080 -15.398 1.00 32.40 C ATOM 2399 CG2 ILE A1039 -15.044 0.034 -13.803 1.00 30.46 C ATOM 2400 CD1 ILE A1039 -18.035 0.790 -14.673 1.00 32.90 C ATOM 2401 H ILE A1039 -17.509 -2.910 -15.106 1.00 32.33 H ATOM 2402 HA ILE A1039 -14.934 -1.867 -15.971 1.00 30.26 H ATOM 2403 HB ILE A1039 -16.746 -1.235 -13.613 1.00 32.08 H ATOM 2404 HG13 ILE A1039 -17.551 -0.733 -16.075 1.00 32.40 H ATOM 2405 HG12 ILE A1039 -16.380 0.544 -16.043 1.00 32.40 H ATOM 2406 HG21 ILE A1039 -15.498 0.926 -13.372 1.00 30.46 H ATOM 2407 HG22 ILE A1039 -14.493 -0.448 -12.997 1.00 30.46 H ATOM 2408 HG23 ILE A1039 -14.320 0.364 -14.550 1.00 30.46 H ATOM 2409 HD11 ILE A1039 -18.793 1.149 -15.368 1.00 32.90 H ATOM 2410 HD12 ILE A1039 -18.548 0.231 -13.890 1.00 32.90 H ATOM 2411 HD13 ILE A1039 -17.570 1.656 -14.208 1.00 32.90 H ATOM 2412 N GLY A1040 -13.302 -2.826 -14.292 1.00 34.99 N ATOM 2413 CA GLY A1040 -12.289 -3.434 -13.430 1.00 35.46 C ATOM 2414 C GLY A1040 -11.231 -2.398 -13.023 1.00 40.57 C ATOM 2415 O GLY A1040 -11.286 -1.237 -13.431 1.00 40.24 O ATOM 2416 H GLY A1040 -12.951 -2.287 -15.075 1.00 34.99 H ATOM 2417 HA3 GLY A1040 -11.814 -4.254 -13.968 1.00 35.46 H ATOM 2418 HA2 GLY A1040 -12.724 -3.850 -12.522 1.00 35.46 H ATOM 2419 N ASP A1041 -10.271 -2.859 -12.199 1.00 37.60 N ATOM 2420 CA ASP A1041 -9.139 -2.132 -11.605 1.00 37.19 C ATOM 2421 C ASP A1041 -9.620 -0.924 -10.778 1.00 39.90 C ATOM 2422 O ASP A1041 -9.731 0.180 -11.309 1.00 40.83 O ATOM 2423 CB ASP A1041 -8.025 -1.778 -12.635 1.00 38.16 C ATOM 2424 CG ASP A1041 -6.667 -1.263 -12.095 1.00 45.68 C ATOM 2425 OD1 ASP A1041 -5.762 -1.083 -12.938 1.00 47.53 O ATOM 2426 OD2 ASP A1041 -6.511 -1.058 -10.870 1.00 46.86 O1- ATOM 2427 H ASP A1041 -10.325 -3.828 -11.918 1.00 37.60 H ATOM 2428 HA ASP A1041 -8.695 -2.841 -10.905 1.00 37.19 H ATOM 2429 HB3 ASP A1041 -8.418 -1.044 -13.339 1.00 38.16 H ATOM 2430 HB2 ASP A1041 -7.825 -2.662 -13.241 1.00 38.16 H ATOM 2431 N PHE A1042 -9.874 -1.177 -9.486 1.00 32.99 N ATOM 2432 CA PHE A1042 -10.252 -0.180 -8.482 1.00 32.48 C ATOM 2433 C PHE A1042 -9.048 0.246 -7.614 1.00 35.62 C ATOM 2434 O PHE A1042 -9.241 0.681 -6.480 1.00 35.44 O ATOM 2435 CB PHE A1042 -11.446 -0.723 -7.659 1.00 35.36 C ATOM 2436 CG PHE A1042 -12.746 -0.802 -8.444 1.00 36.03 C ATOM 2437 CD1 PHE A1042 -13.628 0.299 -8.473 1.00 39.47 C ATOM 2438 CD2 PHE A1042 -12.997 -1.898 -9.298 1.00 37.32 C ATOM 2439 CE1 PHE A1042 -14.757 0.263 -9.281 1.00 39.56 C ATOM 2440 CE2 PHE A1042 -14.124 -1.908 -10.107 1.00 40.21 C ATOM 2441 CZ PHE A1042 -15.004 -0.835 -10.094 1.00 38.02 C ATOM 2442 H PHE A1042 -9.761 -2.121 -9.143 1.00 32.99 H ATOM 2443 HA PHE A1042 -10.592 0.732 -8.974 1.00 32.48 H ATOM 2444 HB3 PHE A1042 -11.630 -0.106 -6.779 1.00 35.36 H ATOM 2445 HB2 PHE A1042 -11.210 -1.720 -7.281 1.00 35.36 H ATOM 2446 HD1 PHE A1042 -13.434 1.171 -7.865 1.00 39.47 H ATOM 2447 HD2 PHE A1042 -12.311 -2.731 -9.331 1.00 37.32 H ATOM 2448 HE1 PHE A1042 -15.438 1.099 -9.293 1.00 39.56 H ATOM 2449 HE2 PHE A1042 -14.309 -2.752 -10.753 1.00 40.21 H ATOM 2450 HZ PHE A1042 -15.878 -0.849 -10.728 1.00 38.02 H ATOM 2451 N GLY A1043 -7.822 0.119 -8.156 1.00 33.72 N ATOM 2452 CA GLY A1043 -6.562 0.403 -7.464 1.00 35.61 C ATOM 2453 C GLY A1043 -6.236 1.898 -7.376 1.00 40.83 C ATOM 2454 O GLY A1043 -5.336 2.268 -6.627 1.00 42.94 O ATOM 2455 H GLY A1043 -7.738 -0.245 -9.097 1.00 33.72 H ATOM 2456 HA3 GLY A1043 -5.756 -0.110 -7.987 1.00 35.61 H ATOM 2457 HA2 GLY A1043 -6.588 -0.000 -6.454 1.00 35.61 H ATOM 2458 N LEU A1044 -6.964 2.757 -8.101 1.00 35.95 N ATOM 2459 CA LEU A1044 -6.868 4.212 -8.002 1.00 35.55 C ATOM 2460 C LEU A1044 -8.174 4.815 -7.450 1.00 38.20 C ATOM 2461 O LEU A1044 -8.207 6.019 -7.209 1.00 37.43 O ATOM 2462 CB LEU A1044 -6.463 4.769 -9.392 1.00 34.71 C ATOM 2463 CG LEU A1044 -5.546 6.012 -9.370 1.00 41.15 C ATOM 2464 CD1 LEU A1044 -4.267 5.793 -8.534 1.00 45.80 C ATOM 2465 CD2 LEU A1044 -5.202 6.468 -10.803 1.00 40.55 C ATOM 2466 H LEU A1044 -7.669 2.407 -8.738 1.00 35.95 H ATOM 2467 HA LEU A1044 -6.111 4.481 -7.266 1.00 35.55 H ATOM 2468 HB3 LEU A1044 -7.359 4.978 -9.980 1.00 34.71 H ATOM 2469 HB2 LEU A1044 -5.931 3.993 -9.948 1.00 34.71 H ATOM 2470 HG LEU A1044 -6.111 6.821 -8.906 1.00 41.15 H ATOM 2471 HD11 LEU A1044 -3.368 6.181 -9.013 1.00 45.80 H ATOM 2472 HD12 LEU A1044 -4.346 6.292 -7.569 1.00 45.80 H ATOM 2473 HD13 LEU A1044 -4.091 4.735 -8.341 1.00 45.80 H ATOM 2474 HD21 LEU A1044 -5.457 7.516 -10.941 1.00 40.55 H ATOM 2475 HD22 LEU A1044 -4.144 6.362 -11.044 1.00 40.55 H ATOM 2476 HD23 LEU A1044 -5.746 5.901 -11.558 1.00 40.55 H ATOM 2477 N ALA A1045 -9.209 3.982 -7.223 1.00 34.45 N ATOM 2478 CA ALA A1045 -10.511 4.387 -6.698 1.00 35.33 C ATOM 2479 C ALA A1045 -10.439 4.900 -5.252 1.00 41.48 C ATOM 2480 O ALA A1045 -9.613 4.431 -4.467 1.00 41.92 O ATOM 2481 CB ALA A1045 -11.497 3.216 -6.820 1.00 35.84 C ATOM 2482 H ALA A1045 -9.099 2.998 -7.419 1.00 34.45 H ATOM 2483 HA ALA A1045 -10.854 5.202 -7.333 1.00 35.33 H ATOM 2484 HB1 ALA A1045 -12.507 3.520 -6.545 1.00 35.84 H ATOM 2485 HB2 ALA A1045 -11.536 2.843 -7.844 1.00 35.84 H ATOM 2486 HB3 ALA A1045 -11.218 2.387 -6.170 1.00 35.84 H ATOM 2487 N LYS A1046 -11.313 5.867 -4.943 1.00 39.67 N ATOM 2488 CA LYS A1046 -11.335 6.594 -3.679 1.00 41.51 C ATOM 2489 C LYS A1046 -12.769 6.933 -3.274 1.00 46.70 C ATOM 2490 O LYS A1046 -13.584 7.254 -4.135 1.00 45.21 O ATOM 2491 CB LYS A1046 -10.496 7.886 -3.832 1.00 43.95 C ATOM 2492 CG LYS A1046 -9.006 7.725 -3.484 1.00 52.94 C ATOM 2493 CD LYS A1046 -8.701 7.356 -2.018 1.00 61.30 C ATOM 2494 CE LYS A1046 -9.532 8.134 -0.976 1.00 72.46 C ATOM 2495 NZ LYS A1046 -9.060 7.912 0.401 1.00 80.50 N1+ ATOM 2496 H LYS A1046 -11.985 6.167 -5.638 1.00 39.67 H ATOM 2497 HA LYS A1046 -10.921 5.960 -2.893 1.00 41.51 H ATOM 2498 HB3 LYS A1046 -10.898 8.679 -3.200 1.00 43.95 H ATOM 2499 HB2 LYS A1046 -10.597 8.276 -4.845 1.00 43.95 H ATOM 2500 HG3 LYS A1046 -8.499 8.654 -3.726 1.00 52.94 H ATOM 2501 HG2 LYS A1046 -8.557 6.980 -4.141 1.00 52.94 H ATOM 2502 HD3 LYS A1046 -7.640 7.539 -1.844 1.00 61.30 H ATOM 2503 HD2 LYS A1046 -8.836 6.282 -1.891 1.00 61.30 H ATOM 2504 HE3 LYS A1046 -10.578 7.837 -1.019 1.00 72.46 H ATOM 2505 HE2 LYS A1046 -9.499 9.201 -1.183 1.00 72.46 H ATOM 2506 HZ1 LYS A1046 -8.099 8.211 0.485 1.00 80.50 H ATOM 2507 HZ2 LYS A1046 -9.635 8.436 1.044 1.00 80.50 H ATOM 2508 HZ3 LYS A1046 -9.132 6.925 0.616 1.00 80.50 H ATOM 2509 N ALA A1047 -13.023 6.914 -1.956 1.00 45.97 N ATOM 2510 CA ALA A1047 -14.239 7.449 -1.350 1.00 47.89 C ATOM 2511 C ALA A1047 -14.187 8.983 -1.308 1.00 53.43 C ATOM 2512 O ALA A1047 -13.174 9.547 -0.891 1.00 53.75 O ATOM 2513 CB ALA A1047 -14.388 6.876 0.067 1.00 51.21 C ATOM 2514 H ALA A1047 -12.304 6.619 -1.313 1.00 45.97 H ATOM 2515 HA ALA A1047 -15.102 7.133 -1.938 1.00 47.89 H ATOM 2516 HB1 ALA A1047 -15.310 7.226 0.534 1.00 51.21 H ATOM 2517 HB2 ALA A1047 -14.428 5.787 0.048 1.00 51.21 H ATOM 2518 HB3 ALA A1047 -13.557 7.165 0.711 1.00 51.21 H ATOM 2519 N VAL A1048 -15.298 9.611 -1.716 1.00 51.14 N ATOM 2520 CA VAL A1048 -15.535 11.047 -1.614 1.00 52.52 C ATOM 2521 C VAL A1048 -16.597 11.229 -0.503 1.00 61.61 C ATOM 2522 O VAL A1048 -17.722 10.765 -0.700 1.00 62.08 O ATOM 2523 CB VAL A1048 -16.114 11.607 -2.948 1.00 54.59 C ATOM 2524 CG1 VAL A1048 -16.530 13.092 -2.876 1.00 55.28 C ATOM 2525 CG2 VAL A1048 -15.135 11.410 -4.114 1.00 51.78 C ATOM 2526 H VAL A1048 -16.088 9.063 -2.035 1.00 51.14 H ATOM 2527 HA VAL A1048 -14.610 11.585 -1.415 1.00 52.52 H ATOM 2528 HB VAL A1048 -17.003 11.032 -3.204 1.00 54.59 H ATOM 2529 HG11 VAL A1048 -16.861 13.457 -3.849 1.00 55.28 H ATOM 2530 HG12 VAL A1048 -17.357 13.256 -2.187 1.00 55.28 H ATOM 2531 HG13 VAL A1048 -15.699 13.722 -2.555 1.00 55.28 H ATOM 2532 HG21 VAL A1048 -15.521 11.853 -5.033 1.00 51.78 H ATOM 2533 HG22 VAL A1048 -14.167 11.868 -3.908 1.00 51.78 H ATOM 2534 HG23 VAL A1048 -14.975 10.351 -4.307 1.00 51.78 H ATOM 2535 N PRO A1049 -16.236 11.864 0.641 1.00 62.00 N ATOM 2536 CA PRO A1049 -17.184 12.176 1.737 1.00 66.09 C ATOM 2537 C PRO A1049 -18.459 12.905 1.278 1.00 73.83 C ATOM 2538 O PRO A1049 -18.379 13.730 0.371 1.00 71.64 O ATOM 2539 CB PRO A1049 -16.360 13.056 2.691 1.00 69.51 C ATOM 2540 CG PRO A1049 -14.922 12.638 2.458 1.00 71.48 C ATOM 2541 CD PRO A1049 -14.889 12.341 0.967 1.00 63.48 C ATOM 2542 HA PRO A1049 -17.442 11.236 2.228 1.00 66.09 H ATOM 2543 HB3 PRO A1049 -16.661 12.943 3.733 1.00 69.51 H ATOM 2544 HB2 PRO A1049 -16.469 14.109 2.431 1.00 69.51 H ATOM 2545 HG3 PRO A1049 -14.718 11.723 3.016 1.00 71.48 H ATOM 2546 HG2 PRO A1049 -14.195 13.390 2.766 1.00 71.48 H ATOM 2547 HD2 PRO A1049 -14.690 13.250 0.396 1.00 63.48 H ATOM 2548 HD3 PRO A1049 -14.110 11.611 0.746 1.00 63.48 H ATOM 2549 N GLU A1050 -19.602 12.569 1.895 1.00 75.69 N ATOM 2550 CA GLU A1050 -20.946 13.047 1.546 1.00 77.51 C ATOM 2551 C GLU A1050 -21.137 14.581 1.530 1.00 84.15 C ATOM 2552 O GLU A1050 -21.986 15.059 0.779 1.00 83.15 O ATOM 2553 CB GLU A1050 -22.008 12.341 2.426 1.00 82.22 C ATOM 2554 CG GLU A1050 -21.885 12.532 3.963 1.00 97.93 C ATOM 2555 CD GLU A1050 -20.916 11.603 4.721 1.00120.70 C ATOM 2556 OE1 GLU A1050 -20.359 10.662 4.111 1.00108.26 O ATOM 2557 OE2 GLU A1050 -20.744 11.858 5.932 1.00119.67 O1- ATOM 2558 H GLU A1050 -19.579 11.872 2.631 1.00 75.69 H ATOM 2559 HA GLU A1050 -21.125 12.712 0.524 1.00 77.51 H ATOM 2560 HB3 GLU A1050 -22.050 11.282 2.167 1.00 82.22 H ATOM 2561 HB2 GLU A1050 -22.989 12.719 2.132 1.00 82.22 H ATOM 2562 HG3 GLU A1050 -22.872 12.366 4.398 1.00 97.93 H ATOM 2563 HG2 GLU A1050 -21.638 13.568 4.194 1.00 97.93 H ATOM 2564 N GLY A1051 -20.338 15.319 2.321 1.00 83.36 N ATOM 2565 CA GLY A1051 -20.349 16.784 2.369 1.00 84.58 C ATOM 2566 C GLY A1051 -19.399 17.422 1.337 1.00 86.36 C ATOM 2567 O GLY A1051 -19.389 18.646 1.220 1.00 86.86 O ATOM 2568 H GLY A1051 -19.670 14.844 2.911 1.00 83.36 H ATOM 2569 HA3 GLY A1051 -20.033 17.094 3.366 1.00 84.58 H ATOM 2570 HA2 GLY A1051 -21.358 17.172 2.226 1.00 84.58 H ATOM 2571 N HIS A1052 -18.603 16.617 0.612 1.00 79.97 N ATOM 2572 CA HIS A1052 -17.629 17.044 -0.396 1.00 76.91 C ATOM 2573 C HIS A1052 -18.094 16.595 -1.790 1.00 76.64 C ATOM 2574 O HIS A1052 -18.787 15.585 -1.914 1.00 75.70 O ATOM 2575 CB HIS A1052 -16.251 16.409 -0.088 1.00 77.26 C ATOM 2576 CG HIS A1052 -15.567 16.850 1.187 1.00 83.91 C ATOM 2577 ND1 HIS A1052 -16.152 16.768 2.440 1.00 88.78 N ATOM 2578 CD2 HIS A1052 -14.313 17.378 1.406 1.00 86.52 C ATOM 2579 CE1 HIS A1052 -15.265 17.223 3.327 1.00 90.57 C ATOM 2580 NE2 HIS A1052 -14.124 17.610 2.771 1.00 89.68 N ATOM 2581 H HIS A1052 -18.692 15.614 0.718 1.00 79.97 H ATOM 2582 HA HIS A1052 -17.523 18.131 -0.401 1.00 76.91 H ATOM 2583 HB3 HIS A1052 -15.563 16.629 -0.906 1.00 77.26 H ATOM 2584 HB2 HIS A1052 -16.332 15.322 -0.062 1.00 77.26 H ATOM 2585 HD1 HIS A1052 -17.082 16.431 2.642 1.00 88.78 H ATOM 2586 HD2 HIS A1052 -13.535 17.600 0.692 1.00 86.52 H ATOM 2587 HE1 HIS A1052 -15.456 17.273 4.389 1.00 90.57 H ATOM 2588 N GLU A1053 -17.659 17.337 -2.818 1.00 70.38 N ATOM 2589 CA GLU A1053 -17.883 17.022 -4.230 1.00 67.41 C ATOM 2590 C GLU A1053 -16.584 16.601 -4.949 1.00 65.39 C ATOM 2591 O GLU A1053 -16.664 16.257 -6.128 1.00 62.86 O ATOM 2592 CB GLU A1053 -18.593 18.212 -4.927 1.00 69.51 C ATOM 2593 CG GLU A1053 -17.779 19.512 -5.135 1.00 81.78 C ATOM 2594 CD GLU A1053 -17.774 20.453 -3.921 1.00109.48 C ATOM 2595 OE1 GLU A1053 -16.893 20.272 -3.050 1.00107.26 O ATOM 2596 OE2 GLU A1053 -18.640 21.354 -3.893 1.00107.68 O1- ATOM 2597 H GLU A1053 -17.139 18.188 -2.639 1.00 70.38 H ATOM 2598 HA GLU A1053 -18.554 16.164 -4.313 1.00 67.41 H ATOM 2599 HB3 GLU A1053 -19.513 18.442 -4.385 1.00 69.51 H ATOM 2600 HB2 GLU A1053 -18.934 17.872 -5.906 1.00 69.51 H ATOM 2601 HG3 GLU A1053 -18.205 20.053 -5.981 1.00 81.78 H ATOM 2602 HG2 GLU A1053 -16.758 19.288 -5.435 1.00 81.78 H ATOM 2603 N TYR A1054 -15.432 16.620 -4.250 1.00 59.91 N ATOM 2604 CA TYR A1054 -14.128 16.231 -4.792 1.00 57.06 C ATOM 2605 C TYR A1054 -13.225 15.603 -3.718 1.00 59.88 C ATOM 2606 O TYR A1054 -13.480 15.733 -2.520 1.00 61.73 O ATOM 2607 CB TYR A1054 -13.443 17.442 -5.481 1.00 57.75 C ATOM 2608 CG TYR A1054 -12.910 18.540 -4.568 1.00 61.72 C ATOM 2609 CD1 TYR A1054 -13.741 19.618 -4.206 1.00 65.51 C ATOM 2610 CD2 TYR A1054 -11.587 18.494 -4.077 1.00 63.03 C ATOM 2611 CE1 TYR A1054 -13.273 20.625 -3.342 1.00 68.28 C ATOM 2612 CE2 TYR A1054 -11.118 19.497 -3.207 1.00 66.37 C ATOM 2613 CZ TYR A1054 -11.960 20.564 -2.838 1.00 76.35 C ATOM 2614 OH TYR A1054 -11.500 21.539 -2.001 1.00 81.80 O ATOM 2615 H TYR A1054 -15.438 16.902 -3.281 1.00 59.91 H ATOM 2616 HA TYR A1054 -14.295 15.452 -5.536 1.00 57.06 H ATOM 2617 HB3 TYR A1054 -14.127 17.883 -6.202 1.00 57.75 H ATOM 2618 HB2 TYR A1054 -12.603 17.084 -6.077 1.00 57.75 H ATOM 2619 HD1 TYR A1054 -14.747 19.671 -4.589 1.00 65.51 H ATOM 2620 HD2 TYR A1054 -10.931 17.684 -4.358 1.00 63.03 H ATOM 2621 HE1 TYR A1054 -13.928 21.440 -3.069 1.00 68.28 H ATOM 2622 HE2 TYR A1054 -10.112 19.450 -2.823 1.00 66.37 H ATOM 2623 HH TYR A1054 -12.176 22.187 -1.785 1.00 81.80 H ATOM 2624 N TYR A1055 -12.149 14.975 -4.212 1.00 53.09 N ATOM 2625 CA TYR A1055 -11.007 14.471 -3.457 1.00 53.10 C ATOM 2626 C TYR A1055 -9.726 15.055 -4.077 1.00 56.32 C ATOM 2627 O TYR A1055 -9.573 14.988 -5.298 1.00 53.18 O ATOM 2628 CB TYR A1055 -11.033 12.925 -3.512 1.00 53.04 C ATOM 2629 CG TYR A1055 -9.744 12.229 -3.105 1.00 55.26 C ATOM 2630 CD1 TYR A1055 -9.403 12.116 -1.742 1.00 59.33 C ATOM 2631 CD2 TYR A1055 -8.864 11.731 -4.090 1.00 54.82 C ATOM 2632 CE1 TYR A1055 -8.189 11.509 -1.366 1.00 60.69 C ATOM 2633 CE2 TYR A1055 -7.648 11.129 -3.714 1.00 56.92 C ATOM 2634 CZ TYR A1055 -7.317 11.005 -2.350 1.00 68.28 C ATOM 2635 OH TYR A1055 -6.152 10.396 -1.981 1.00 72.13 O ATOM 2636 H TYR A1055 -12.056 14.902 -5.217 1.00 53.09 H ATOM 2637 HA TYR A1055 -11.071 14.792 -2.416 1.00 53.10 H ATOM 2638 HB3 TYR A1055 -11.259 12.613 -4.532 1.00 53.04 H ATOM 2639 HB2 TYR A1055 -11.853 12.545 -2.902 1.00 53.04 H ATOM 2640 HD1 TYR A1055 -10.066 12.505 -0.983 1.00 59.33 H ATOM 2641 HD2 TYR A1055 -9.109 11.827 -5.138 1.00 54.82 H ATOM 2642 HE1 TYR A1055 -7.931 11.427 -0.320 1.00 60.69 H ATOM 2643 HE2 TYR A1055 -6.979 10.757 -4.475 1.00 56.92 H ATOM 2644 HH TYR A1055 -5.609 10.143 -2.731 1.00 72.13 H ATOM 2645 N ARG A1056 -8.817 15.579 -3.235 1.00 56.46 N ATOM 2646 CA ARG A1056 -7.489 16.027 -3.666 1.00 57.19 C ATOM 2647 C ARG A1056 -6.566 14.824 -3.911 1.00 61.89 C ATOM 2648 O ARG A1056 -6.398 13.993 -3.019 1.00 62.29 O ATOM 2649 CB ARG A1056 -6.850 16.976 -2.627 1.00 60.29 C ATOM 2650 CG ARG A1056 -6.976 18.462 -2.999 1.00 71.82 C ATOM 2651 CD ARG A1056 -6.155 19.357 -2.056 1.00 85.08 C ATOM 2652 NE ARG A1056 -6.336 20.793 -2.326 1.00 93.43 N ATOM 2653 CZ ARG A1056 -7.282 21.607 -1.821 1.00108.81 C ATOM 2654 NH1 ARG A1056 -8.250 21.157 -1.008 1.00 96.57 N ATOM 2655 NH2 ARG A1056 -7.252 22.907 -2.136 1.00 96.30 N1+ ATOM 2656 H ARG A1056 -8.994 15.588 -2.241 1.00 56.46 H ATOM 2657 HA ARG A1056 -7.612 16.564 -4.604 1.00 57.19 H ATOM 2658 HB3 ARG A1056 -5.781 16.771 -2.542 1.00 60.29 H ATOM 2659 HB2 ARG A1056 -7.256 16.789 -1.632 1.00 60.29 H ATOM 2660 HG3 ARG A1056 -8.009 18.791 -3.096 1.00 71.82 H ATOM 2661 HG2 ARG A1056 -6.539 18.558 -3.995 1.00 71.82 H ATOM 2662 HD3 ARG A1056 -5.101 19.189 -2.278 1.00 85.08 H ATOM 2663 HD2 ARG A1056 -6.280 19.090 -1.006 1.00 85.08 H ATOM 2664 HE ARG A1056 -5.661 21.191 -2.965 1.00 93.43 H ATOM 2665 HH12 ARG A1056 -8.966 21.778 -0.657 1.00 96.57 H ATOM 2666 HH11 ARG A1056 -8.277 20.181 -0.750 1.00 96.57 H ATOM 2667 HH22 ARG A1056 -7.936 23.542 -1.749 1.00 96.30 H ATOM 2668 HH21 ARG A1056 -6.504 23.276 -2.706 1.00 96.30 H ATOM 2669 N VAL A1057 -5.959 14.797 -5.106 1.00 58.85 N ATOM 2670 CA VAL A1057 -5.003 13.780 -5.542 1.00 59.44 C ATOM 2671 C VAL A1057 -3.557 14.281 -5.359 1.00 68.20 C ATOM 2672 O VAL A1057 -3.329 15.483 -5.206 1.00 69.34 O ATOM 2673 CB VAL A1057 -5.225 13.404 -7.038 1.00 60.80 C ATOM 2674 CG1 VAL A1057 -6.682 12.977 -7.283 1.00 59.13 C ATOM 2675 CG2 VAL A1057 -4.790 14.446 -8.089 1.00 60.31 C ATOM 2676 H VAL A1057 -6.124 15.552 -5.759 1.00 58.85 H ATOM 2677 HA VAL A1057 -5.125 12.877 -4.941 1.00 59.44 H ATOM 2678 HB VAL A1057 -4.617 12.519 -7.229 1.00 60.80 H ATOM 2679 HG11 VAL A1057 -6.821 12.608 -8.299 1.00 59.13 H ATOM 2680 HG12 VAL A1057 -6.979 12.188 -6.594 1.00 59.13 H ATOM 2681 HG13 VAL A1057 -7.368 13.812 -7.139 1.00 59.13 H ATOM 2682 HG21 VAL A1057 -4.998 14.090 -9.099 1.00 60.31 H ATOM 2683 HG22 VAL A1057 -5.330 15.380 -7.961 1.00 60.31 H ATOM 2684 HG23 VAL A1057 -3.723 14.663 -8.049 1.00 60.31 H ATOM 2685 N ARG A1058 -2.607 13.334 -5.385 1.00 67.56 N ATOM 2686 CA ARG A1058 -1.172 13.599 -5.282 1.00 70.37 C ATOM 2687 C ARG A1058 -0.536 13.789 -6.667 1.00 74.80 C ATOM 2688 O ARG A1058 -1.065 13.300 -7.667 1.00 72.29 O ATOM 2689 CB ARG A1058 -0.482 12.425 -4.555 1.00 73.21 C ATOM 2690 CG ARG A1058 -1.096 12.069 -3.190 1.00 89.24 C ATOM 2691 CD ARG A1058 -0.267 11.012 -2.441 1.00105.70 C ATOM 2692 NE ARG A1058 -0.997 10.452 -1.291 1.00119.40 N ATOM 2693 CZ ARG A1058 -1.790 9.362 -1.293 1.00134.49 C ATOM 2694 NH1 ARG A1058 -1.990 8.620 -2.394 1.00120.12 N ATOM 2695 NH2 ARG A1058 -2.400 9.001 -0.157 1.00122.85 N1+ ATOM 2696 H ARG A1058 -2.868 12.371 -5.537 1.00 67.56 H ATOM 2697 HA ARG A1058 -1.012 14.506 -4.696 1.00 70.37 H ATOM 2698 HB3 ARG A1058 0.576 12.656 -4.421 1.00 73.21 H ATOM 2699 HB2 ARG A1058 -0.516 11.536 -5.188 1.00 73.21 H ATOM 2700 HG3 ARG A1058 -2.147 11.782 -3.259 1.00 89.24 H ATOM 2701 HG2 ARG A1058 -1.072 12.989 -2.605 1.00 89.24 H ATOM 2702 HD3 ARG A1058 0.578 11.523 -1.980 1.00105.70 H ATOM 2703 HD2 ARG A1058 0.168 10.261 -3.102 1.00105.70 H ATOM 2704 HE ARG A1058 -0.910 10.974 -0.431 1.00119.40 H ATOM 2705 HH12 ARG A1058 -2.574 7.793 -2.360 1.00120.12 H ATOM 2706 HH11 ARG A1058 -1.525 8.863 -3.256 1.00120.12 H ATOM 2707 HH22 ARG A1058 -2.991 8.183 -0.135 1.00122.85 H ATOM 2708 HH21 ARG A1058 -2.266 9.536 0.689 1.00122.85 H ATOM 2709 N GLU A1059 0.632 14.450 -6.673 1.00 74.50 N ATOM 2710 CA GLU A1059 1.553 14.525 -7.807 1.00 74.23 C ATOM 2711 C GLU A1059 2.254 13.163 -7.955 1.00 77.46 C ATOM 2712 O GLU A1059 3.042 12.795 -7.083 1.00 79.77 O ATOM 2713 CB GLU A1059 2.560 15.668 -7.559 1.00 78.25 C ATOM 2714 CG GLU A1059 1.890 17.055 -7.402 1.00 89.76 C ATOM 2715 CD GLU A1059 2.828 18.212 -7.020 1.00113.50 C ATOM 2716 OE1 GLU A1059 4.065 18.018 -7.008 1.00107.60 O ATOM 2717 OE2 GLU A1059 2.274 19.295 -6.731 1.00107.56 O1- ATOM 2718 H GLU A1059 0.989 14.826 -5.807 1.00 74.50 H ATOM 2719 HA GLU A1059 0.987 14.746 -8.714 1.00 74.23 H ATOM 2720 HB3 GLU A1059 3.270 15.702 -8.387 1.00 78.25 H ATOM 2721 HB2 GLU A1059 3.147 15.447 -6.666 1.00 78.25 H ATOM 2722 HG3 GLU A1059 1.105 17.011 -6.647 1.00 89.76 H ATOM 2723 HG2 GLU A1059 1.396 17.315 -8.337 1.00 89.76 H ATOM 2724 N ASP A1060 1.895 12.418 -9.011 1.00 70.23 N ATOM 2725 CA ASP A1060 2.226 11.001 -9.159 1.00 68.85 C ATOM 2726 C ASP A1060 2.470 10.671 -10.644 1.00 68.50 C ATOM 2727 O ASP A1060 1.778 11.208 -11.510 1.00 66.16 O ATOM 2728 CB ASP A1060 1.134 10.133 -8.477 1.00 69.42 C ATOM 2729 CG ASP A1060 1.308 8.615 -8.603 1.00 81.45 C ATOM 2730 OD1 ASP A1060 0.565 8.022 -9.413 1.00 81.04 O ATOM 2731 OD2 ASP A1060 2.259 8.097 -7.975 1.00 89.83 O1- ATOM 2732 H ASP A1060 1.248 12.789 -9.693 1.00 70.23 H ATOM 2733 HA ASP A1060 3.171 10.811 -8.645 1.00 68.85 H ATOM 2734 HB3 ASP A1060 0.147 10.430 -8.837 1.00 69.42 H ATOM 2735 HB2 ASP A1060 1.112 10.376 -7.413 1.00 69.42 H ATOM 2736 N GLY A1061 3.463 9.803 -10.905 1.00 63.47 N ATOM 2737 CA GLY A1061 3.919 9.458 -12.253 1.00 61.92 C ATOM 2738 C GLY A1061 3.025 8.411 -12.936 1.00 61.80 C ATOM 2739 O GLY A1061 2.926 8.424 -14.163 1.00 61.49 O ATOM 2740 H GLY A1061 3.960 9.380 -10.133 1.00 63.47 H ATOM 2741 HA3 GLY A1061 4.930 9.056 -12.184 1.00 61.92 H ATOM 2742 HA2 GLY A1061 3.980 10.354 -12.873 1.00 61.92 H ATOM 2743 N ASP A1062 2.365 7.532 -12.159 1.00 55.28 N ATOM 2744 CA ASP A1062 1.462 6.477 -12.645 1.00 52.23 C ATOM 2745 C ASP A1062 0.018 6.962 -12.892 1.00 50.35 C ATOM 2746 O ASP A1062 -0.809 6.161 -13.330 1.00 49.00 O ATOM 2747 CB ASP A1062 1.471 5.215 -11.744 1.00 54.90 C ATOM 2748 CG ASP A1062 2.871 4.616 -11.542 1.00 73.36 C ATOM 2749 OD1 ASP A1062 3.348 3.959 -12.494 1.00 75.14 O ATOM 2750 OD2 ASP A1062 3.499 4.932 -10.507 1.00 82.10 O1- ATOM 2751 H ASP A1062 2.477 7.575 -11.155 1.00 55.28 H ATOM 2752 HA ASP A1062 1.824 6.157 -13.624 1.00 52.23 H ATOM 2753 HB3 ASP A1062 0.835 4.437 -12.171 1.00 54.90 H ATOM 2754 HB2 ASP A1062 1.050 5.454 -10.766 1.00 54.90 H ATOM 2755 N SER A1063 -0.262 8.254 -12.645 1.00 43.08 N ATOM 2756 CA SER A1063 -1.541 8.912 -12.926 1.00 39.71 C ATOM 2757 C SER A1063 -1.834 8.917 -14.445 1.00 36.74 C ATOM 2758 O SER A1063 -0.950 9.325 -15.200 1.00 35.65 O ATOM 2759 CB SER A1063 -1.451 10.363 -12.416 1.00 44.05 C ATOM 2760 OG SER A1063 -1.561 10.394 -11.008 1.00 56.19 O ATOM 2761 H SER A1063 0.470 8.845 -12.278 1.00 43.08 H ATOM 2762 HA SER A1063 -2.308 8.385 -12.360 1.00 39.71 H ATOM 2763 HB3 SER A1063 -2.274 10.959 -12.814 1.00 44.05 H ATOM 2764 HB2 SER A1063 -0.529 10.848 -12.736 1.00 44.05 H ATOM 2765 HG SER A1063 -0.820 9.909 -10.633 1.00 56.19 H ATOM 2766 N PRO A1064 -3.031 8.450 -14.878 1.00 30.99 N ATOM 2767 CA PRO A1064 -3.409 8.434 -16.303 1.00 29.59 C ATOM 2768 C PRO A1064 -3.804 9.836 -16.823 1.00 32.01 C ATOM 2769 O PRO A1064 -4.987 10.123 -17.008 1.00 29.67 O ATOM 2770 CB PRO A1064 -4.545 7.398 -16.344 1.00 29.56 C ATOM 2771 CG PRO A1064 -5.231 7.543 -14.998 1.00 33.51 C ATOM 2772 CD PRO A1064 -4.076 7.842 -14.049 1.00 30.17 C ATOM 2773 HA PRO A1064 -2.580 8.066 -16.908 1.00 29.59 H ATOM 2774 HB3 PRO A1064 -4.115 6.399 -16.418 1.00 29.56 H ATOM 2775 HB2 PRO A1064 -5.230 7.518 -17.184 1.00 29.56 H ATOM 2776 HG3 PRO A1064 -5.811 6.671 -14.703 1.00 33.51 H ATOM 2777 HG2 PRO A1064 -5.910 8.392 -15.038 1.00 33.51 H ATOM 2778 HD2 PRO A1064 -4.396 8.489 -13.233 1.00 30.17 H ATOM 2779 HD3 PRO A1064 -3.692 6.913 -13.624 1.00 30.17 H ATOM 2780 N VAL A1065 -2.786 10.690 -17.026 1.00 29.66 N ATOM 2781 CA VAL A1065 -2.902 12.106 -17.382 1.00 29.04 C ATOM 2782 C VAL A1065 -3.565 12.389 -18.746 1.00 30.30 C ATOM 2783 O VAL A1065 -4.209 13.429 -18.873 1.00 30.19 O ATOM 2784 CB VAL A1065 -1.522 12.819 -17.348 1.00 34.62 C ATOM 2785 CG1 VAL A1065 -0.968 12.886 -15.914 1.00 34.92 C ATOM 2786 CG2 VAL A1065 -0.478 12.246 -18.328 1.00 35.44 C ATOM 2787 H VAL A1065 -1.845 10.366 -16.844 1.00 29.66 H ATOM 2788 HA VAL A1065 -3.532 12.562 -16.618 1.00 29.04 H ATOM 2789 HB VAL A1065 -1.673 13.855 -17.651 1.00 34.62 H ATOM 2790 HG11 VAL A1065 -0.022 13.424 -15.880 1.00 34.92 H ATOM 2791 HG12 VAL A1065 -1.661 13.400 -15.247 1.00 34.92 H ATOM 2792 HG13 VAL A1065 -0.786 11.895 -15.503 1.00 34.92 H ATOM 2793 HG21 VAL A1065 0.477 12.764 -18.227 1.00 35.44 H ATOM 2794 HG22 VAL A1065 -0.296 11.188 -18.145 1.00 35.44 H ATOM 2795 HG23 VAL A1065 -0.788 12.357 -19.367 1.00 35.44 H ATOM 2796 N PHE A1066 -3.447 11.462 -19.715 1.00 25.62 N ATOM 2797 CA PHE A1066 -4.084 11.560 -21.034 1.00 24.82 C ATOM 2798 C PHE A1066 -5.578 11.163 -21.042 1.00 26.45 C ATOM 2799 O PHE A1066 -6.220 11.285 -22.086 1.00 25.78 O ATOM 2800 CB PHE A1066 -3.251 10.779 -22.074 1.00 26.47 C ATOM 2801 CG PHE A1066 -1.844 11.322 -22.286 1.00 27.98 C ATOM 2802 CD1 PHE A1066 -1.649 12.632 -22.772 1.00 31.46 C ATOM 2803 CD2 PHE A1066 -0.713 10.538 -21.974 1.00 29.97 C ATOM 2804 CE1 PHE A1066 -0.365 13.135 -22.936 1.00 33.77 C ATOM 2805 CE2 PHE A1066 0.563 11.055 -22.150 1.00 33.43 C ATOM 2806 CZ PHE A1066 0.737 12.349 -22.625 1.00 32.31 C ATOM 2807 H PHE A1066 -2.904 10.626 -19.541 1.00 25.62 H ATOM 2808 HA PHE A1066 -4.075 12.609 -21.337 1.00 24.82 H ATOM 2809 HB3 PHE A1066 -3.756 10.782 -23.040 1.00 26.47 H ATOM 2810 HB2 PHE A1066 -3.184 9.732 -21.779 1.00 26.47 H ATOM 2811 HD1 PHE A1066 -2.496 13.256 -23.012 1.00 31.46 H ATOM 2812 HD2 PHE A1066 -0.829 9.530 -21.608 1.00 29.97 H ATOM 2813 HE1 PHE A1066 -0.222 14.140 -23.303 1.00 33.77 H ATOM 2814 HE2 PHE A1066 1.426 10.449 -21.914 1.00 33.43 H ATOM 2815 HZ PHE A1066 1.733 12.745 -22.753 1.00 32.31 H ATOM 2816 N TRP A1067 -6.110 10.745 -19.880 1.00 22.72 N ATOM 2817 CA TRP A1067 -7.531 10.523 -19.603 1.00 23.65 C ATOM 2818 C TRP A1067 -8.099 11.559 -18.615 1.00 26.48 C ATOM 2819 O TRP A1067 -9.285 11.467 -18.304 1.00 25.01 O ATOM 2820 CB TRP A1067 -7.743 9.090 -19.059 1.00 21.85 C ATOM 2821 CG TRP A1067 -7.607 7.990 -20.066 1.00 23.25 C ATOM 2822 CD1 TRP A1067 -8.642 7.341 -20.645 1.00 25.76 C ATOM 2823 CD2 TRP A1067 -6.398 7.444 -20.678 1.00 23.75 C ATOM 2824 NE1 TRP A1067 -8.162 6.446 -21.576 1.00 25.21 N ATOM 2825 CE2 TRP A1067 -6.788 6.472 -21.648 1.00 27.61 C ATOM 2826 CE3 TRP A1067 -5.010 7.675 -20.529 1.00 25.53 C ATOM 2827 CZ2 TRP A1067 -5.855 5.779 -22.436 1.00 27.61 C ATOM 2828 CZ3 TRP A1067 -4.067 6.991 -21.323 1.00 27.51 C ATOM 2829 CH2 TRP A1067 -4.488 6.046 -22.275 1.00 28.26 C ATOM 2830 H TRP A1067 -5.501 10.650 -19.078 1.00 22.72 H ATOM 2831 HA TRP A1067 -8.122 10.631 -20.512 1.00 23.65 H ATOM 2832 HB3 TRP A1067 -8.742 8.988 -18.631 1.00 21.85 H ATOM 2833 HB2 TRP A1067 -7.054 8.892 -18.237 1.00 21.85 H ATOM 2834 HD1 TRP A1067 -9.684 7.521 -20.419 1.00 25.76 H ATOM 2835 HE1 TRP A1067 -8.763 5.856 -22.143 1.00 25.21 H ATOM 2836 HE3 TRP A1067 -4.665 8.393 -19.801 1.00 25.53 H ATOM 2837 HZ2 TRP A1067 -6.179 5.054 -23.162 1.00 27.61 H ATOM 2838 HZ3 TRP A1067 -3.015 7.191 -21.200 1.00 27.51 H ATOM 2839 HH2 TRP A1067 -3.763 5.530 -22.885 1.00 28.26 H ATOM 2840 N TYR A1068 -7.272 12.497 -18.115 1.00 25.06 N ATOM 2841 CA TYR A1068 -7.642 13.429 -17.048 1.00 24.40 C ATOM 2842 C TYR A1068 -8.088 14.804 -17.559 1.00 29.09 C ATOM 2843 O TYR A1068 -7.539 15.325 -18.530 1.00 29.03 O ATOM 2844 CB TYR A1068 -6.472 13.562 -16.048 1.00 25.40 C ATOM 2845 CG TYR A1068 -6.380 12.528 -14.932 1.00 26.29 C ATOM 2846 CD1 TYR A1068 -7.163 11.349 -14.925 1.00 27.65 C ATOM 2847 CD2 TYR A1068 -5.512 12.778 -13.847 1.00 27.90 C ATOM 2848 CE1 TYR A1068 -7.106 10.464 -13.835 1.00 28.32 C ATOM 2849 CE2 TYR A1068 -5.448 11.886 -12.759 1.00 27.93 C ATOM 2850 CZ TYR A1068 -6.256 10.733 -12.747 1.00 32.15 C ATOM 2851 OH TYR A1068 -6.220 9.881 -11.685 1.00 34.10 O ATOM 2852 H TYR A1068 -6.314 12.541 -18.432 1.00 25.06 H ATOM 2853 HA TYR A1068 -8.495 13.017 -16.518 1.00 24.40 H ATOM 2854 HB3 TYR A1068 -6.558 14.518 -15.532 1.00 25.40 H ATOM 2855 HB2 TYR A1068 -5.525 13.618 -16.580 1.00 25.40 H ATOM 2856 HD1 TYR A1068 -7.828 11.106 -15.737 1.00 27.65 H ATOM 2857 HD2 TYR A1068 -4.905 13.672 -13.836 1.00 27.90 H ATOM 2858 HE1 TYR A1068 -7.730 9.583 -13.840 1.00 28.32 H ATOM 2859 HE2 TYR A1068 -4.789 12.095 -11.929 1.00 27.93 H ATOM 2860 HH TYR A1068 -6.736 9.083 -11.841 1.00 34.10 H ATOM 2861 N ALA A1069 -9.063 15.368 -16.828 1.00 26.27 N ATOM 2862 CA ALA A1069 -9.621 16.707 -17.003 1.00 27.33 C ATOM 2863 C ALA A1069 -8.659 17.817 -16.518 1.00 31.87 C ATOM 2864 O ALA A1069 -7.763 17.513 -15.730 1.00 30.37 O ATOM 2865 CB ALA A1069 -10.947 16.754 -16.231 1.00 27.85 C ATOM 2866 H ALA A1069 -9.448 14.841 -16.054 1.00 26.27 H ATOM 2867 HA ALA A1069 -9.810 16.823 -18.066 1.00 27.33 H ATOM 2868 HB1 ALA A1069 -11.438 17.722 -16.320 1.00 27.85 H ATOM 2869 HB2 ALA A1069 -11.646 16.004 -16.594 1.00 27.85 H ATOM 2870 HB3 ALA A1069 -10.785 16.554 -15.172 1.00 27.85 H ATOM 2871 N PRO A1070 -8.853 19.082 -16.970 1.00 28.98 N ATOM 2872 CA PRO A1070 -7.923 20.191 -16.665 1.00 30.25 C ATOM 2873 C PRO A1070 -7.700 20.518 -15.175 1.00 34.14 C ATOM 2874 O PRO A1070 -6.573 20.852 -14.818 1.00 33.30 O ATOM 2875 CB PRO A1070 -8.493 21.396 -17.433 1.00 33.24 C ATOM 2876 CG PRO A1070 -9.331 20.784 -18.540 1.00 37.12 C ATOM 2877 CD PRO A1070 -9.901 19.534 -17.888 1.00 31.16 C ATOM 2878 HA PRO A1070 -6.962 19.920 -17.107 1.00 30.25 H ATOM 2879 HB3 PRO A1070 -7.714 22.051 -17.825 1.00 33.24 H ATOM 2880 HB2 PRO A1070 -9.134 22.001 -16.791 1.00 33.24 H ATOM 2881 HG3 PRO A1070 -8.680 20.494 -19.364 1.00 37.12 H ATOM 2882 HG2 PRO A1070 -10.095 21.455 -18.934 1.00 37.12 H ATOM 2883 HD2 PRO A1070 -10.795 19.780 -17.314 1.00 31.16 H ATOM 2884 HD3 PRO A1070 -10.174 18.813 -18.654 1.00 31.16 H ATOM 2885 N GLU A1071 -8.744 20.397 -14.334 1.00 30.48 N ATOM 2886 CA GLU A1071 -8.670 20.632 -12.886 1.00 31.43 C ATOM 2887 C GLU A1071 -8.015 19.474 -12.104 1.00 36.54 C ATOM 2888 O GLU A1071 -7.610 19.696 -10.965 1.00 37.63 O ATOM 2889 CB GLU A1071 -10.061 21.021 -12.323 1.00 32.56 C ATOM 2890 CG GLU A1071 -11.111 19.899 -12.136 1.00 35.76 C ATOM 2891 CD GLU A1071 -11.663 19.243 -13.409 1.00 37.74 C ATOM 2892 OE1 GLU A1071 -11.773 19.921 -14.455 1.00 31.58 O ATOM 2893 OE2 GLU A1071 -12.001 18.047 -13.308 1.00 25.56 O1- ATOM 2894 H GLU A1071 -9.652 20.128 -14.691 1.00 30.48 H ATOM 2895 HA GLU A1071 -8.027 21.502 -12.737 1.00 31.43 H ATOM 2896 HB3 GLU A1071 -10.485 21.824 -12.925 1.00 32.56 H ATOM 2897 HB2 GLU A1071 -9.904 21.480 -11.346 1.00 32.56 H ATOM 2898 HG3 GLU A1071 -11.971 20.327 -11.620 1.00 35.76 H ATOM 2899 HG2 GLU A1071 -10.723 19.135 -11.462 1.00 35.76 H ATOM 2900 N CYS A1072 -7.886 18.284 -12.717 1.00 32.49 N ATOM 2901 CA CYS A1072 -7.132 17.152 -12.167 1.00 32.58 C ATOM 2902 C CYS A1072 -5.622 17.310 -12.419 1.00 37.39 C ATOM 2903 O CYS A1072 -4.826 16.835 -11.611 1.00 38.08 O ATOM 2904 CB CYS A1072 -7.587 15.806 -12.759 1.00 31.25 C ATOM 2905 SG CYS A1072 -9.352 15.554 -12.470 1.00 34.42 S ATOM 2906 H CYS A1072 -8.257 18.161 -13.649 1.00 32.49 H ATOM 2907 HA CYS A1072 -7.287 17.115 -11.087 1.00 32.58 H ATOM 2908 HB3 CYS A1072 -7.039 14.977 -12.309 1.00 31.25 H ATOM 2909 HB2 CYS A1072 -7.406 15.766 -13.832 1.00 31.25 H ATOM 2910 HG CYS A1072 -9.290 15.627 -11.137 1.00 34.42 H ATOM 2911 N LEU A1073 -5.266 17.967 -13.536 1.00 33.94 N ATOM 2912 CA LEU A1073 -3.891 18.219 -13.963 1.00 35.43 C ATOM 2913 C LEU A1073 -3.294 19.478 -13.307 1.00 43.48 C ATOM 2914 O LEU A1073 -2.085 19.509 -13.081 1.00 44.33 O ATOM 2915 CB LEU A1073 -3.869 18.390 -15.499 1.00 35.06 C ATOM 2916 CG LEU A1073 -4.341 17.170 -16.321 1.00 37.87 C ATOM 2917 CD1 LEU A1073 -4.517 17.552 -17.804 1.00 38.52 C ATOM 2918 CD2 LEU A1073 -3.436 15.937 -16.139 1.00 39.19 C ATOM 2919 H LEU A1073 -5.988 18.313 -14.153 1.00 33.94 H ATOM 2920 HA LEU A1073 -3.265 17.368 -13.686 1.00 35.43 H ATOM 2921 HB3 LEU A1073 -2.858 18.647 -15.817 1.00 35.06 H ATOM 2922 HB2 LEU A1073 -4.489 19.252 -15.755 1.00 35.06 H ATOM 2923 HG LEU A1073 -5.329 16.889 -15.963 1.00 37.87 H ATOM 2924 HD11 LEU A1073 -5.382 17.049 -18.237 1.00 38.52 H ATOM 2925 HD12 LEU A1073 -4.671 18.624 -17.940 1.00 38.52 H ATOM 2926 HD13 LEU A1073 -3.644 17.286 -18.396 1.00 38.52 H ATOM 2927 HD21 LEU A1073 -3.149 15.499 -17.094 1.00 39.19 H ATOM 2928 HD22 LEU A1073 -2.519 16.169 -15.600 1.00 39.19 H ATOM 2929 HD23 LEU A1073 -3.949 15.160 -15.574 1.00 39.19 H ATOM 2930 N LYS A1074 -4.137 20.497 -13.064 1.00 42.49 N ATOM 2931 CA LYS A1074 -3.729 21.836 -12.643 1.00 45.58 C ATOM 2932 C LYS A1074 -3.934 22.044 -11.135 1.00 51.72 C ATOM 2933 O LYS A1074 -2.973 22.372 -10.442 1.00 52.85 O ATOM 2934 CB LYS A1074 -4.514 22.869 -13.483 1.00 49.18 C ATOM 2935 CG LYS A1074 -4.055 24.328 -13.301 1.00 71.38 C ATOM 2936 CD LYS A1074 -4.725 25.346 -14.249 1.00 85.44 C ATOM 2937 CE LYS A1074 -6.183 25.718 -13.902 1.00 97.19 C ATOM 2938 NZ LYS A1074 -7.173 24.740 -14.390 1.00104.18 N1+ ATOM 2939 H LYS A1074 -5.112 20.390 -13.308 1.00 42.49 H ATOM 2940 HA LYS A1074 -2.667 21.980 -12.852 1.00 45.58 H ATOM 2941 HB3 LYS A1074 -5.576 22.781 -13.261 1.00 49.18 H ATOM 2942 HB2 LYS A1074 -4.402 22.609 -14.535 1.00 49.18 H ATOM 2943 HG3 LYS A1074 -2.977 24.371 -13.462 1.00 71.38 H ATOM 2944 HG2 LYS A1074 -4.211 24.646 -12.269 1.00 71.38 H ATOM 2945 HD3 LYS A1074 -4.664 24.985 -15.278 1.00 85.44 H ATOM 2946 HD2 LYS A1074 -4.129 26.259 -14.237 1.00 85.44 H ATOM 2947 HE3 LYS A1074 -6.429 26.674 -14.365 1.00 97.19 H ATOM 2948 HE2 LYS A1074 -6.297 25.853 -12.826 1.00 97.19 H ATOM 2949 HZ1 LYS A1074 -7.139 24.699 -15.403 1.00104.18 H ATOM 2950 HZ2 LYS A1074 -6.976 23.827 -14.010 1.00104.18 H ATOM 2951 HZ3 LYS A1074 -8.101 25.030 -14.113 1.00104.18 H ATOM 2952 N GLU A1075 -5.180 21.863 -10.665 1.00 48.00 N ATOM 2953 CA GLU A1075 -5.585 22.077 -9.272 1.00 49.76 C ATOM 2954 C GLU A1075 -5.469 20.825 -8.390 1.00 53.28 C ATOM 2955 O GLU A1075 -5.564 20.955 -7.169 1.00 53.10 O ATOM 2956 CB GLU A1075 -7.027 22.637 -9.249 1.00 51.48 C ATOM 2957 CG GLU A1075 -7.124 24.120 -9.674 1.00 66.34 C ATOM 2958 CD GLU A1075 -6.547 25.137 -8.670 1.00 98.88 C ATOM 2959 OE1 GLU A1075 -6.396 24.794 -7.475 1.00 95.63 O ATOM 2960 OE2 GLU A1075 -6.278 26.270 -9.122 1.00 98.68 O1- ATOM 2961 H GLU A1075 -5.913 21.578 -11.297 1.00 48.00 H ATOM 2962 HA GLU A1075 -4.918 22.813 -8.819 1.00 49.76 H ATOM 2963 HB3 GLU A1075 -7.494 22.492 -8.274 1.00 51.48 H ATOM 2964 HB2 GLU A1075 -7.647 22.060 -9.934 1.00 51.48 H ATOM 2965 HG3 GLU A1075 -8.175 24.373 -9.823 1.00 66.34 H ATOM 2966 HG2 GLU A1075 -6.644 24.255 -10.644 1.00 66.34 H ATOM 2967 N TYR A1076 -5.279 19.648 -9.014 1.00 50.13 N ATOM 2968 CA TYR A1076 -5.184 18.331 -8.378 1.00 50.19 C ATOM 2969 C TYR A1076 -6.446 17.957 -7.577 1.00 52.11 C ATOM 2970 O TYR A1076 -6.327 17.366 -6.507 1.00 53.52 O ATOM 2971 CB TYR A1076 -3.875 18.202 -7.561 1.00 54.13 C ATOM 2972 CG TYR A1076 -2.614 18.454 -8.368 1.00 57.78 C ATOM 2973 CD1 TYR A1076 -1.910 19.668 -8.226 1.00 62.12 C ATOM 2974 CD2 TYR A1076 -2.156 17.481 -9.280 1.00 57.80 C ATOM 2975 CE1 TYR A1076 -0.757 19.910 -8.998 1.00 64.82 C ATOM 2976 CE2 TYR A1076 -1.005 17.725 -10.054 1.00 59.85 C ATOM 2977 CZ TYR A1076 -0.305 18.940 -9.913 1.00 71.28 C ATOM 2978 OH TYR A1076 0.811 19.178 -10.660 1.00 75.29 O ATOM 2979 H TYR A1076 -5.206 19.646 -10.021 1.00 50.13 H ATOM 2980 HA TYR A1076 -5.136 17.606 -9.189 1.00 50.19 H ATOM 2981 HB3 TYR A1076 -3.793 17.199 -7.144 1.00 54.13 H ATOM 2982 HB2 TYR A1076 -3.889 18.877 -6.704 1.00 54.13 H ATOM 2983 HD1 TYR A1076 -2.257 20.423 -7.536 1.00 62.12 H ATOM 2984 HD2 TYR A1076 -2.693 16.552 -9.399 1.00 57.80 H ATOM 2985 HE1 TYR A1076 -0.223 20.842 -8.889 1.00 64.82 H ATOM 2986 HE2 TYR A1076 -0.665 16.978 -10.756 1.00 59.85 H ATOM 2987 HH TYR A1076 1.035 18.453 -11.248 1.00 75.29 H ATOM 2988 N LYS A1077 -7.625 18.303 -8.117 1.00 44.81 N ATOM 2989 CA LYS A1077 -8.935 17.968 -7.561 1.00 43.60 C ATOM 2990 C LYS A1077 -9.643 17.020 -8.530 1.00 41.76 C ATOM 2991 O LYS A1077 -9.712 17.322 -9.722 1.00 38.21 O ATOM 2992 CB LYS A1077 -9.773 19.248 -7.392 1.00 46.62 C ATOM 2993 CG LYS A1077 -9.225 20.227 -6.347 1.00 58.33 C ATOM 2994 CD LYS A1077 -10.181 21.413 -6.133 1.00 67.59 C ATOM 2995 CE LYS A1077 -9.692 22.437 -5.097 1.00 79.50 C ATOM 2996 NZ LYS A1077 -8.547 23.225 -5.587 1.00 87.69 N1+ ATOM 2997 H LYS A1077 -7.639 18.785 -9.007 1.00 44.81 H ATOM 2998 HA LYS A1077 -8.838 17.480 -6.589 1.00 43.60 H ATOM 2999 HB3 LYS A1077 -10.784 18.965 -7.093 1.00 46.62 H ATOM 3000 HB2 LYS A1077 -9.869 19.760 -8.351 1.00 46.62 H ATOM 3001 HG3 LYS A1077 -8.247 20.587 -6.666 1.00 58.33 H ATOM 3002 HG2 LYS A1077 -9.067 19.705 -5.403 1.00 58.33 H ATOM 3003 HD3 LYS A1077 -11.151 21.030 -5.811 1.00 67.59 H ATOM 3004 HD2 LYS A1077 -10.370 21.908 -7.087 1.00 67.59 H ATOM 3005 HE3 LYS A1077 -9.420 21.938 -4.166 1.00 79.50 H ATOM 3006 HE2 LYS A1077 -10.500 23.130 -4.860 1.00 79.50 H ATOM 3007 HZ1 LYS A1077 -8.803 23.715 -6.432 1.00 87.69 H ATOM 3008 HZ2 LYS A1077 -8.267 23.900 -4.892 1.00 87.69 H ATOM 3009 HZ3 LYS A1077 -7.769 22.614 -5.792 1.00 87.69 H ATOM 3010 N PHE A1078 -10.177 15.913 -7.995 1.00 36.93 N ATOM 3011 CA PHE A1078 -10.895 14.905 -8.764 1.00 34.49 C ATOM 3012 C PHE A1078 -12.338 14.858 -8.243 1.00 39.60 C ATOM 3013 O PHE A1078 -12.585 14.362 -7.144 1.00 40.48 O ATOM 3014 CB PHE A1078 -10.163 13.553 -8.631 1.00 35.26 C ATOM 3015 CG PHE A1078 -10.493 12.591 -9.753 1.00 34.98 C ATOM 3016 CD1 PHE A1078 -9.616 12.456 -10.849 1.00 36.30 C ATOM 3017 CD2 PHE A1078 -11.752 11.962 -9.802 1.00 35.94 C ATOM 3018 CE1 PHE A1078 -9.990 11.692 -11.946 1.00 35.94 C ATOM 3019 CE2 PHE A1078 -12.103 11.200 -10.902 1.00 37.30 C ATOM 3020 CZ PHE A1078 -11.232 11.074 -11.975 1.00 34.53 C ATOM 3021 H PHE A1078 -10.074 15.726 -7.005 1.00 36.93 H ATOM 3022 HA PHE A1078 -10.911 15.172 -9.822 1.00 34.49 H ATOM 3023 HB3 PHE A1078 -10.381 13.079 -7.673 1.00 35.26 H ATOM 3024 HB2 PHE A1078 -9.086 13.717 -8.642 1.00 35.26 H ATOM 3025 HD1 PHE A1078 -8.660 12.960 -10.852 1.00 36.30 H ATOM 3026 HD2 PHE A1078 -12.462 12.090 -8.999 1.00 35.94 H ATOM 3027 HE1 PHE A1078 -9.324 11.597 -12.788 1.00 35.94 H ATOM 3028 HE2 PHE A1078 -13.078 10.743 -10.924 1.00 37.30 H ATOM 3029 HZ PHE A1078 -11.523 10.502 -12.843 1.00 34.53 H ATOM 3030 N TYR A1079 -13.251 15.383 -9.069 1.00 35.49 N ATOM 3031 CA TYR A1079 -14.699 15.432 -8.867 1.00 35.71 C ATOM 3032 C TYR A1079 -15.372 14.145 -9.384 1.00 36.13 C ATOM 3033 O TYR A1079 -14.705 13.288 -9.964 1.00 33.76 O ATOM 3034 CB TYR A1079 -15.243 16.673 -9.619 1.00 37.14 C ATOM 3035 CG TYR A1079 -14.753 18.019 -9.104 1.00 41.82 C ATOM 3036 CD1 TYR A1079 -15.584 18.803 -8.276 1.00 45.55 C ATOM 3037 CD2 TYR A1079 -13.470 18.498 -9.452 1.00 42.95 C ATOM 3038 CE1 TYR A1079 -15.127 20.039 -7.777 1.00 48.19 C ATOM 3039 CE2 TYR A1079 -13.011 19.728 -8.945 1.00 44.97 C ATOM 3040 CZ TYR A1079 -13.835 20.496 -8.101 1.00 54.63 C ATOM 3041 OH TYR A1079 -13.381 21.681 -7.599 1.00 58.40 O ATOM 3042 H TYR A1079 -12.940 15.728 -9.968 1.00 35.49 H ATOM 3043 HA TYR A1079 -14.910 15.528 -7.804 1.00 35.71 H ATOM 3044 HB3 TYR A1079 -16.331 16.687 -9.569 1.00 37.14 H ATOM 3045 HB2 TYR A1079 -15.004 16.605 -10.682 1.00 37.14 H ATOM 3046 HD1 TYR A1079 -16.571 18.454 -8.007 1.00 45.55 H ATOM 3047 HD2 TYR A1079 -12.828 17.919 -10.099 1.00 42.95 H ATOM 3048 HE1 TYR A1079 -15.767 20.629 -7.137 1.00 48.19 H ATOM 3049 HE2 TYR A1079 -12.025 20.081 -9.205 1.00 44.97 H ATOM 3050 HH TYR A1079 -14.028 22.123 -7.043 1.00 58.40 H ATOM 3051 N TYR A1080 -16.702 14.042 -9.223 1.00 32.40 N ATOM 3052 CA TYR A1080 -17.512 13.046 -9.939 1.00 30.87 C ATOM 3053 C TYR A1080 -17.542 13.317 -11.455 1.00 32.51 C ATOM 3054 O TYR A1080 -17.430 12.377 -12.238 1.00 30.72 O ATOM 3055 CB TYR A1080 -18.938 12.999 -9.362 1.00 32.98 C ATOM 3056 CG TYR A1080 -19.032 12.486 -7.936 1.00 35.85 C ATOM 3057 CD1 TYR A1080 -18.695 11.147 -7.644 1.00 37.45 C ATOM 3058 CD2 TYR A1080 -19.477 13.336 -6.902 1.00 38.07 C ATOM 3059 CE1 TYR A1080 -18.818 10.655 -6.331 1.00 40.49 C ATOM 3060 CE2 TYR A1080 -19.600 12.844 -5.588 1.00 40.41 C ATOM 3061 CZ TYR A1080 -19.277 11.503 -5.305 1.00 44.30 C ATOM 3062 OH TYR A1080 -19.410 11.026 -4.036 1.00 44.69 O ATOM 3063 H TYR A1080 -17.208 14.750 -8.710 1.00 32.40 H ATOM 3064 HA TYR A1080 -17.052 12.066 -9.794 1.00 30.87 H ATOM 3065 HB3 TYR A1080 -19.560 12.345 -9.974 1.00 32.98 H ATOM 3066 HB2 TYR A1080 -19.400 13.985 -9.425 1.00 32.98 H ATOM 3067 HD1 TYR A1080 -18.346 10.490 -8.426 1.00 37.45 H ATOM 3068 HD2 TYR A1080 -19.735 14.363 -7.111 1.00 38.07 H ATOM 3069 HE1 TYR A1080 -18.566 9.627 -6.116 1.00 40.49 H ATOM 3070 HE2 TYR A1080 -19.946 13.496 -4.799 1.00 40.41 H ATOM 3071 HH TYR A1080 -19.090 10.127 -3.938 1.00 44.69 H ATOM 3072 N ALA A1081 -17.605 14.604 -11.842 1.00 29.56 N ATOM 3073 CA ALA A1081 -17.512 15.064 -13.228 1.00 27.95 C ATOM 3074 C ALA A1081 -16.170 14.748 -13.915 1.00 27.99 C ATOM 3075 O ALA A1081 -16.124 14.729 -15.142 1.00 26.14 O ATOM 3076 CB ALA A1081 -17.798 16.573 -13.264 1.00 28.95 C ATOM 3077 H ALA A1081 -17.713 15.325 -11.141 1.00 29.56 H ATOM 3078 HA ALA A1081 -18.290 14.551 -13.796 1.00 27.95 H ATOM 3079 HB1 ALA A1081 -17.793 16.956 -14.285 1.00 28.95 H ATOM 3080 HB2 ALA A1081 -18.781 16.794 -12.847 1.00 28.95 H ATOM 3081 HB3 ALA A1081 -17.061 17.135 -12.690 1.00 28.95 H ATOM 3082 N SER A1082 -15.102 14.505 -13.138 1.00 25.39 N ATOM 3083 CA SER A1082 -13.776 14.151 -13.646 1.00 24.95 C ATOM 3084 C SER A1082 -13.745 12.745 -14.282 1.00 27.35 C ATOM 3085 O SER A1082 -13.055 12.563 -15.284 1.00 26.99 O ATOM 3086 CB SER A1082 -12.763 14.260 -12.500 1.00 28.68 C ATOM 3087 OG SER A1082 -12.732 15.566 -11.967 1.00 33.92 O ATOM 3088 H SER A1082 -15.195 14.533 -12.132 1.00 25.39 H ATOM 3089 HA SER A1082 -13.498 14.869 -14.420 1.00 24.95 H ATOM 3090 HB3 SER A1082 -11.764 14.000 -12.839 1.00 28.68 H ATOM 3091 HB2 SER A1082 -13.008 13.569 -11.703 1.00 28.68 H ATOM 3092 HG SER A1082 -12.333 16.169 -12.606 1.00 33.92 H ATOM 3093 N ASP A1083 -14.537 11.799 -13.743 1.00 23.13 N ATOM 3094 CA ASP A1083 -14.788 10.488 -14.354 1.00 22.18 C ATOM 3095 C ASP A1083 -15.611 10.564 -15.651 1.00 25.02 C ATOM 3096 O ASP A1083 -15.428 9.691 -16.496 1.00 23.63 O ATOM 3097 CB ASP A1083 -15.474 9.498 -13.386 1.00 24.19 C ATOM 3098 CG ASP A1083 -14.601 8.937 -12.259 1.00 28.00 C ATOM 3099 OD1 ASP A1083 -13.433 8.581 -12.529 1.00 27.87 O ATOM 3100 OD2 ASP A1083 -15.162 8.716 -11.167 1.00 31.18 O1- ATOM 3101 H ASP A1083 -15.083 12.016 -12.921 1.00 23.13 H ATOM 3102 HA ASP A1083 -13.818 10.082 -14.642 1.00 22.18 H ATOM 3103 HB3 ASP A1083 -15.865 8.648 -13.943 1.00 24.19 H ATOM 3104 HB2 ASP A1083 -16.333 9.997 -12.937 1.00 24.19 H ATOM 3105 N VAL A1084 -16.478 11.581 -15.808 1.00 23.20 N ATOM 3106 CA VAL A1084 -17.237 11.816 -17.043 1.00 22.46 C ATOM 3107 C VAL A1084 -16.326 12.236 -18.215 1.00 25.25 C ATOM 3108 O VAL A1084 -16.560 11.779 -19.334 1.00 23.49 O ATOM 3109 CB VAL A1084 -18.378 12.855 -16.849 1.00 25.40 C ATOM 3110 CG1 VAL A1084 -19.004 13.409 -18.149 1.00 24.52 C ATOM 3111 CG2 VAL A1084 -19.467 12.272 -15.928 1.00 25.38 C ATOM 3112 H VAL A1084 -16.590 12.265 -15.073 1.00 23.20 H ATOM 3113 HA VAL A1084 -17.704 10.870 -17.322 1.00 22.46 H ATOM 3114 HB VAL A1084 -17.970 13.719 -16.335 1.00 25.40 H ATOM 3115 HG11 VAL A1084 -19.744 14.170 -17.923 1.00 24.52 H ATOM 3116 HG12 VAL A1084 -18.280 13.911 -18.790 1.00 24.52 H ATOM 3117 HG13 VAL A1084 -19.487 12.624 -18.732 1.00 24.52 H ATOM 3118 HG21 VAL A1084 -20.235 13.007 -15.704 1.00 25.38 H ATOM 3119 HG22 VAL A1084 -19.957 11.412 -16.385 1.00 25.38 H ATOM 3120 HG23 VAL A1084 -19.053 11.952 -14.972 1.00 25.38 H ATOM 3121 N TRP A1085 -15.279 13.034 -17.932 1.00 23.54 N ATOM 3122 CA TRP A1085 -14.206 13.342 -18.882 1.00 23.20 C ATOM 3123 C TRP A1085 -13.454 12.077 -19.319 1.00 25.99 C ATOM 3124 O TRP A1085 -13.253 11.889 -20.518 1.00 26.38 O ATOM 3125 CB TRP A1085 -13.269 14.426 -18.303 1.00 22.62 C ATOM 3126 CG TRP A1085 -12.128 14.881 -19.175 1.00 22.84 C ATOM 3127 CD1 TRP A1085 -11.055 14.132 -19.515 1.00 25.30 C ATOM 3128 CD2 TRP A1085 -11.921 16.174 -19.828 1.00 22.79 C ATOM 3129 NE1 TRP A1085 -10.233 14.839 -20.359 1.00 24.54 N ATOM 3130 CE2 TRP A1085 -10.718 16.104 -20.594 1.00 26.50 C ATOM 3131 CE3 TRP A1085 -12.618 17.404 -19.853 1.00 24.28 C ATOM 3132 CZ2 TRP A1085 -10.252 17.180 -21.365 1.00 26.19 C ATOM 3133 CZ3 TRP A1085 -12.152 18.496 -20.615 1.00 25.94 C ATOM 3134 CH2 TRP A1085 -10.975 18.384 -21.378 1.00 26.22 C ATOM 3135 H TRP A1085 -15.153 13.373 -16.988 1.00 23.54 H ATOM 3136 HA TRP A1085 -14.660 13.744 -19.784 1.00 23.20 H ATOM 3137 HB3 TRP A1085 -12.840 14.080 -17.363 1.00 22.62 H ATOM 3138 HB2 TRP A1085 -13.860 15.308 -18.052 1.00 22.62 H ATOM 3139 HD1 TRP A1085 -10.890 13.120 -19.184 1.00 25.30 H ATOM 3140 HE1 TRP A1085 -9.371 14.455 -20.731 1.00 24.54 H ATOM 3141 HE3 TRP A1085 -13.527 17.507 -19.285 1.00 24.28 H ATOM 3142 HZ2 TRP A1085 -9.346 17.075 -21.938 1.00 26.19 H ATOM 3143 HZ3 TRP A1085 -12.701 19.424 -20.620 1.00 25.94 H ATOM 3144 HH2 TRP A1085 -10.626 19.223 -21.962 1.00 26.22 H ATOM 3145 N SER A1086 -13.092 11.228 -18.343 1.00 23.27 N ATOM 3146 CA SER A1086 -12.412 9.953 -18.565 1.00 22.29 C ATOM 3147 C SER A1086 -13.274 8.947 -19.353 1.00 25.76 C ATOM 3148 O SER A1086 -12.707 8.181 -20.130 1.00 25.35 O ATOM 3149 CB SER A1086 -11.978 9.362 -17.215 1.00 24.31 C ATOM 3150 OG SER A1086 -11.144 10.256 -16.504 1.00 27.11 O ATOM 3151 H SER A1086 -13.281 11.465 -17.378 1.00 23.27 H ATOM 3152 HA SER A1086 -11.518 10.152 -19.159 1.00 22.29 H ATOM 3153 HB3 SER A1086 -11.420 8.439 -17.370 1.00 24.31 H ATOM 3154 HB2 SER A1086 -12.840 9.115 -16.597 1.00 24.31 H ATOM 3155 HG SER A1086 -10.415 10.519 -17.077 1.00 27.11 H ATOM 3156 N PHE A1087 -14.612 9.007 -19.195 1.00 22.49 N ATOM 3157 CA PHE A1087 -15.589 8.295 -20.022 1.00 21.87 C ATOM 3158 C PHE A1087 -15.618 8.765 -21.483 1.00 26.76 C ATOM 3159 O PHE A1087 -15.773 7.924 -22.363 1.00 27.22 O ATOM 3160 CB PHE A1087 -16.998 8.282 -19.373 1.00 24.21 C ATOM 3161 CG PHE A1087 -18.139 7.909 -20.310 1.00 25.86 C ATOM 3162 CD1 PHE A1087 -18.280 6.574 -20.745 1.00 28.01 C ATOM 3163 CD2 PHE A1087 -18.909 8.917 -20.932 1.00 26.70 C ATOM 3164 CE1 PHE A1087 -19.174 6.264 -21.760 1.00 28.28 C ATOM 3165 CE2 PHE A1087 -19.803 8.585 -21.941 1.00 28.37 C ATOM 3166 CZ PHE A1087 -19.928 7.266 -22.358 1.00 26.26 C ATOM 3167 H PHE A1087 -14.996 9.642 -18.508 1.00 22.49 H ATOM 3168 HA PHE A1087 -15.264 7.254 -20.052 1.00 21.87 H ATOM 3169 HB3 PHE A1087 -17.220 9.244 -18.916 1.00 24.21 H ATOM 3170 HB2 PHE A1087 -17.001 7.559 -18.562 1.00 24.21 H ATOM 3171 HD1 PHE A1087 -17.662 5.798 -20.320 1.00 28.01 H ATOM 3172 HD2 PHE A1087 -18.781 9.951 -20.647 1.00 26.70 H ATOM 3173 HE1 PHE A1087 -19.270 5.244 -22.097 1.00 28.28 H ATOM 3174 HE2 PHE A1087 -20.388 9.359 -22.416 1.00 28.37 H ATOM 3175 HZ PHE A1087 -20.613 7.022 -23.156 1.00 26.26 H ATOM 3176 N GLY A1088 -15.463 10.078 -21.725 1.00 25.20 N ATOM 3177 CA GLY A1088 -15.397 10.647 -23.072 1.00 24.53 C ATOM 3178 C GLY A1088 -14.144 10.153 -23.812 1.00 25.56 C ATOM 3179 O GLY A1088 -14.215 9.886 -25.010 1.00 24.64 O ATOM 3180 H GLY A1088 -15.360 10.718 -20.948 1.00 25.20 H ATOM 3181 HA3 GLY A1088 -15.369 11.734 -23.000 1.00 24.53 H ATOM 3182 HA2 GLY A1088 -16.295 10.385 -23.634 1.00 24.53 H ATOM 3183 N VAL A1089 -13.018 9.990 -23.092 1.00 22.27 N ATOM 3184 CA VAL A1089 -11.773 9.430 -23.621 1.00 21.54 C ATOM 3185 C VAL A1089 -11.845 7.892 -23.772 1.00 25.32 C ATOM 3186 O VAL A1089 -11.253 7.367 -24.713 1.00 25.91 O ATOM 3187 CB VAL A1089 -10.538 9.818 -22.757 1.00 24.92 C ATOM 3188 CG1 VAL A1089 -9.205 9.300 -23.330 1.00 24.42 C ATOM 3189 CG2 VAL A1089 -10.419 11.342 -22.593 1.00 24.24 C ATOM 3190 H VAL A1089 -13.022 10.219 -22.107 1.00 22.27 H ATOM 3191 HA VAL A1089 -11.612 9.844 -24.616 1.00 21.54 H ATOM 3192 HB VAL A1089 -10.659 9.389 -21.761 1.00 24.92 H ATOM 3193 HG11 VAL A1089 -8.358 9.619 -22.723 1.00 24.42 H ATOM 3194 HG12 VAL A1089 -9.165 8.214 -23.374 1.00 24.42 H ATOM 3195 HG13 VAL A1089 -9.045 9.679 -24.340 1.00 24.42 H ATOM 3196 HG21 VAL A1089 -9.521 11.613 -22.042 1.00 24.24 H ATOM 3197 HG22 VAL A1089 -10.373 11.837 -23.563 1.00 24.24 H ATOM 3198 HG23 VAL A1089 -11.258 11.760 -22.043 1.00 24.24 H ATOM 3199 N THR A1090 -12.615 7.201 -22.911 1.00 22.27 N ATOM 3200 CA THR A1090 -12.918 5.771 -23.052 1.00 21.73 C ATOM 3201 C THR A1090 -13.803 5.497 -24.282 1.00 24.89 C ATOM 3202 O THR A1090 -13.496 4.581 -25.038 1.00 24.37 O ATOM 3203 CB THR A1090 -13.638 5.177 -21.811 1.00 26.43 C ATOM 3204 OG1 THR A1090 -12.855 5.394 -20.661 1.00 23.21 O ATOM 3205 CG2 THR A1090 -13.917 3.664 -21.880 1.00 26.50 C ATOM 3206 H THR A1090 -13.071 7.685 -22.149 1.00 22.27 H ATOM 3207 HA THR A1090 -11.974 5.239 -23.187 1.00 21.73 H ATOM 3208 HB THR A1090 -14.587 5.688 -21.652 1.00 26.43 H ATOM 3209 HG1 THR A1090 -12.746 6.342 -20.526 1.00 23.21 H ATOM 3210 HG21 THR A1090 -14.289 3.293 -20.925 1.00 26.50 H ATOM 3211 HG22 THR A1090 -14.666 3.418 -22.633 1.00 26.50 H ATOM 3212 HG23 THR A1090 -13.011 3.107 -22.118 1.00 26.50 H ATOM 3213 N LEU A1091 -14.844 6.326 -24.480 1.00 21.38 N ATOM 3214 CA LEU A1091 -15.754 6.315 -25.626 1.00 21.26 C ATOM 3215 C LEU A1091 -15.027 6.594 -26.953 1.00 25.55 C ATOM 3216 O LEU A1091 -15.338 5.943 -27.948 1.00 24.92 O ATOM 3217 CB LEU A1091 -16.902 7.321 -25.358 1.00 21.18 C ATOM 3218 CG LEU A1091 -18.043 7.343 -26.400 1.00 26.34 C ATOM 3219 CD1 LEU A1091 -18.736 5.972 -26.517 1.00 27.66 C ATOM 3220 CD2 LEU A1091 -19.046 8.478 -26.096 1.00 28.91 C ATOM 3221 H LEU A1091 -15.031 7.043 -23.789 1.00 21.38 H ATOM 3222 HA LEU A1091 -16.172 5.309 -25.684 1.00 21.26 H ATOM 3223 HB3 LEU A1091 -16.476 8.322 -25.277 1.00 21.18 H ATOM 3224 HB2 LEU A1091 -17.339 7.107 -24.381 1.00 21.18 H ATOM 3225 HG LEU A1091 -17.612 7.573 -27.373 1.00 26.34 H ATOM 3226 HD11 LEU A1091 -19.820 6.049 -26.604 1.00 27.66 H ATOM 3227 HD12 LEU A1091 -18.386 5.428 -27.392 1.00 27.66 H ATOM 3228 HD13 LEU A1091 -18.522 5.346 -25.651 1.00 27.66 H ATOM 3229 HD21 LEU A1091 -19.158 9.136 -26.959 1.00 28.91 H ATOM 3230 HD22 LEU A1091 -20.039 8.108 -25.839 1.00 28.91 H ATOM 3231 HD23 LEU A1091 -18.721 9.099 -25.260 1.00 28.91 H ATOM 3232 N TYR A1092 -14.031 7.499 -26.923 1.00 23.80 N ATOM 3233 CA TYR A1092 -13.099 7.753 -28.021 1.00 23.59 C ATOM 3234 C TYR A1092 -12.315 6.491 -28.425 1.00 28.07 C ATOM 3235 O TYR A1092 -12.272 6.181 -29.614 1.00 28.26 O ATOM 3236 CB TYR A1092 -12.173 8.936 -27.658 1.00 24.03 C ATOM 3237 CG TYR A1092 -11.033 9.197 -28.626 1.00 25.49 C ATOM 3238 CD1 TYR A1092 -11.301 9.688 -29.920 1.00 27.64 C ATOM 3239 CD2 TYR A1092 -9.705 8.903 -28.251 1.00 25.28 C ATOM 3240 CE1 TYR A1092 -10.251 9.863 -30.838 1.00 27.61 C ATOM 3241 CE2 TYR A1092 -8.652 9.096 -29.166 1.00 25.84 C ATOM 3242 CZ TYR A1092 -8.929 9.573 -30.462 1.00 31.24 C ATOM 3243 OH TYR A1092 -7.926 9.744 -31.367 1.00 30.99 O ATOM 3244 H TYR A1092 -13.854 8.006 -26.066 1.00 23.80 H ATOM 3245 HA TYR A1092 -13.698 8.053 -28.883 1.00 23.59 H ATOM 3246 HB3 TYR A1092 -11.731 8.761 -26.683 1.00 24.03 H ATOM 3247 HB2 TYR A1092 -12.756 9.847 -27.538 1.00 24.03 H ATOM 3248 HD1 TYR A1092 -12.315 9.900 -30.224 1.00 27.64 H ATOM 3249 HD2 TYR A1092 -9.491 8.520 -27.264 1.00 25.28 H ATOM 3250 HE1 TYR A1092 -10.457 10.196 -31.843 1.00 27.61 H ATOM 3251 HE2 TYR A1092 -7.639 8.871 -28.867 1.00 25.84 H ATOM 3252 HH TYR A1092 -7.106 9.333 -31.072 1.00 30.99 H ATOM 3253 N GLU A1093 -11.768 5.761 -27.435 1.00 24.82 N ATOM 3254 CA GLU A1093 -11.086 4.484 -27.646 1.00 23.87 C ATOM 3255 C GLU A1093 -11.975 3.389 -28.258 1.00 29.02 C ATOM 3256 O GLU A1093 -11.477 2.664 -29.115 1.00 29.63 O ATOM 3257 CB GLU A1093 -10.427 3.973 -26.356 1.00 24.44 C ATOM 3258 CG GLU A1093 -9.237 4.821 -25.884 1.00 27.04 C ATOM 3259 CD GLU A1093 -8.637 4.226 -24.611 1.00 39.48 C ATOM 3260 OE1 GLU A1093 -9.243 4.419 -23.533 1.00 26.77 O ATOM 3261 OE2 GLU A1093 -7.591 3.554 -24.738 1.00 32.38 O1- ATOM 3262 H GLU A1093 -11.845 6.074 -26.476 1.00 24.82 H ATOM 3263 HA GLU A1093 -10.281 4.673 -28.357 1.00 23.87 H ATOM 3264 HB3 GLU A1093 -10.087 2.947 -26.501 1.00 24.44 H ATOM 3265 HB2 GLU A1093 -11.167 3.920 -25.560 1.00 24.44 H ATOM 3266 HG3 GLU A1093 -9.531 5.852 -25.702 1.00 27.04 H ATOM 3267 HG2 GLU A1093 -8.481 4.862 -26.670 1.00 27.04 H ATOM 3268 N LEU A1094 -13.259 3.299 -27.860 1.00 26.56 N ATOM 3269 CA LEU A1094 -14.192 2.306 -28.409 1.00 27.12 C ATOM 3270 C LEU A1094 -14.478 2.531 -29.905 1.00 29.23 C ATOM 3271 O LEU A1094 -14.481 1.561 -30.660 1.00 30.58 O ATOM 3272 CB LEU A1094 -15.520 2.246 -27.615 1.00 27.75 C ATOM 3273 CG LEU A1094 -15.421 2.018 -26.089 1.00 33.45 C ATOM 3274 CD1 LEU A1094 -16.789 1.644 -25.482 1.00 34.25 C ATOM 3275 CD2 LEU A1094 -14.323 1.027 -25.666 1.00 37.20 C ATOM 3276 H LEU A1094 -13.614 3.919 -27.144 1.00 26.56 H ATOM 3277 HA LEU A1094 -13.708 1.330 -28.327 1.00 27.12 H ATOM 3278 HB3 LEU A1094 -16.113 1.436 -28.041 1.00 27.75 H ATOM 3279 HB2 LEU A1094 -16.100 3.154 -27.790 1.00 27.75 H ATOM 3280 HG LEU A1094 -15.166 2.977 -25.652 1.00 33.45 H ATOM 3281 HD11 LEU A1094 -17.053 2.322 -24.669 1.00 34.25 H ATOM 3282 HD12 LEU A1094 -17.592 1.700 -26.216 1.00 34.25 H ATOM 3283 HD13 LEU A1094 -16.794 0.632 -25.076 1.00 34.25 H ATOM 3284 HD21 LEU A1094 -14.466 0.703 -24.636 1.00 37.20 H ATOM 3285 HD22 LEU A1094 -14.313 0.140 -26.299 1.00 37.20 H ATOM 3286 HD23 LEU A1094 -13.335 1.487 -25.711 1.00 37.20 H ATOM 3287 N LEU A1095 -14.672 3.802 -30.304 1.00 26.35 N ATOM 3288 CA LEU A1095 -14.961 4.209 -31.682 1.00 28.85 C ATOM 3289 C LEU A1095 -13.734 4.120 -32.619 1.00 32.34 C ATOM 3290 O LEU A1095 -13.931 3.898 -33.813 1.00 33.48 O ATOM 3291 CB LEU A1095 -15.577 5.632 -31.691 1.00 29.95 C ATOM 3292 CG LEU A1095 -17.110 5.748 -31.482 1.00 37.01 C ATOM 3293 CD1 LEU A1095 -17.928 4.993 -32.548 1.00 41.99 C ATOM 3294 CD2 LEU A1095 -17.598 5.424 -30.060 1.00 37.43 C ATOM 3295 H LEU A1095 -14.644 4.545 -29.618 1.00 26.35 H ATOM 3296 HA LEU A1095 -15.694 3.506 -32.081 1.00 28.85 H ATOM 3297 HB3 LEU A1095 -15.375 6.094 -32.658 1.00 29.95 H ATOM 3298 HB2 LEU A1095 -15.062 6.260 -30.963 1.00 29.95 H ATOM 3299 HG LEU A1095 -17.340 6.802 -31.630 1.00 37.01 H ATOM 3300 HD11 LEU A1095 -18.648 5.658 -33.026 1.00 41.99 H ATOM 3301 HD12 LEU A1095 -17.300 4.585 -33.335 1.00 41.99 H ATOM 3302 HD13 LEU A1095 -18.483 4.155 -32.126 1.00 41.99 H ATOM 3303 HD21 LEU A1095 -18.614 5.029 -30.052 1.00 37.43 H ATOM 3304 HD22 LEU A1095 -16.973 4.692 -29.555 1.00 37.43 H ATOM 3305 HD23 LEU A1095 -17.608 6.330 -29.455 1.00 37.43 H ATOM 3306 N THR A1096 -12.506 4.251 -32.084 1.00 28.49 N ATOM 3307 CA THR A1096 -11.253 3.995 -32.816 1.00 28.46 C ATOM 3308 C THR A1096 -10.852 2.497 -32.815 1.00 34.09 C ATOM 3309 O THR A1096 -9.856 2.153 -33.452 1.00 34.31 O ATOM 3310 CB THR A1096 -10.059 4.808 -32.236 1.00 31.93 C ATOM 3311 OG1 THR A1096 -9.741 4.419 -30.916 1.00 28.23 O ATOM 3312 CG2 THR A1096 -10.258 6.329 -32.269 1.00 33.74 C ATOM 3313 H THR A1096 -12.415 4.453 -31.098 1.00 28.49 H ATOM 3314 HA THR A1096 -11.377 4.297 -33.856 1.00 28.46 H ATOM 3315 HB THR A1096 -9.172 4.597 -32.833 1.00 31.93 H ATOM 3316 HG1 THR A1096 -10.439 4.736 -30.336 1.00 28.23 H ATOM 3317 HG21 THR A1096 -9.410 6.848 -31.821 1.00 33.74 H ATOM 3318 HG22 THR A1096 -10.359 6.687 -33.292 1.00 33.74 H ATOM 3319 HG23 THR A1096 -11.150 6.635 -31.735 1.00 33.74 H ATOM 3320 N HIS A1097 -11.615 1.642 -32.103 1.00 31.69 N ATOM 3321 CA HIS A1097 -11.381 0.204 -31.900 1.00 31.97 C ATOM 3322 C HIS A1097 -10.062 -0.104 -31.165 1.00 33.69 C ATOM 3323 O HIS A1097 -9.451 -1.146 -31.396 1.00 33.12 O ATOM 3324 CB HIS A1097 -11.554 -0.597 -33.212 1.00 35.14 C ATOM 3325 CG HIS A1097 -12.938 -0.518 -33.800 1.00 40.55 C ATOM 3326 ND1 HIS A1097 -13.357 0.538 -34.617 1.00 43.74 N ATOM 3327 CD2 HIS A1097 -13.982 -1.406 -33.645 1.00 43.94 C ATOM 3328 CE1 HIS A1097 -14.618 0.257 -34.914 1.00 44.01 C ATOM 3329 NE2 HIS A1097 -15.038 -0.885 -34.369 1.00 44.57 N ATOM 3330 H HIS A1097 -12.425 2.012 -31.624 1.00 31.69 H ATOM 3331 HA HIS A1097 -12.165 -0.123 -31.216 1.00 31.97 H ATOM 3332 HB3 HIS A1097 -11.341 -1.653 -33.046 1.00 35.14 H ATOM 3333 HB2 HIS A1097 -10.844 -0.264 -33.967 1.00 35.14 H ATOM 3334 HD2 HIS A1097 -14.056 -2.331 -33.092 1.00 43.94 H ATOM 3335 HE1 HIS A1097 -15.240 0.888 -35.531 1.00 44.01 H ATOM 3336 HE2 HIS A1097 -15.963 -1.292 -34.456 1.00 44.57 H ATOM 3337 N CYS A1098 -9.658 0.828 -30.285 1.00 28.70 N ATOM 3338 CA CYS A1098 -8.478 0.796 -29.422 1.00 27.70 C ATOM 3339 C CYS A1098 -7.155 0.700 -30.208 1.00 30.22 C ATOM 3340 O CYS A1098 -6.198 0.093 -29.727 1.00 27.75 O ATOM 3341 CB CYS A1098 -8.592 -0.268 -28.315 1.00 27.86 C ATOM 3342 SG CYS A1098 -10.039 0.093 -27.277 1.00 31.27 S ATOM 3343 H CYS A1098 -10.254 1.635 -30.150 1.00 28.70 H ATOM 3344 HA CYS A1098 -8.453 1.767 -28.928 1.00 27.70 H ATOM 3345 HB3 CYS A1098 -7.706 -0.255 -27.682 1.00 27.86 H ATOM 3346 HB2 CYS A1098 -8.685 -1.270 -28.729 1.00 27.86 H ATOM 3347 HG CYS A1098 -10.014 -1.059 -26.600 1.00 31.27 H ATOM 3348 N ASP A1099 -7.130 1.319 -31.404 1.00 28.20 N ATOM 3349 CA ASP A1099 -5.967 1.423 -32.283 1.00 29.09 C ATOM 3350 C ASP A1099 -4.871 2.253 -31.590 1.00 32.04 C ATOM 3351 O ASP A1099 -5.137 3.386 -31.191 1.00 29.80 O ATOM 3352 CB ASP A1099 -6.383 2.011 -33.658 1.00 31.01 C ATOM 3353 CG ASP A1099 -5.334 2.058 -34.786 1.00 42.86 C ATOM 3354 OD1 ASP A1099 -4.205 1.546 -34.615 1.00 44.82 O ATOM 3355 OD2 ASP A1099 -5.706 2.585 -35.856 1.00 55.40 O1- ATOM 3356 H ASP A1099 -7.968 1.778 -31.732 1.00 28.20 H ATOM 3357 HA ASP A1099 -5.599 0.408 -32.440 1.00 29.09 H ATOM 3358 HB3 ASP A1099 -6.782 3.015 -33.511 1.00 31.01 H ATOM 3359 HB2 ASP A1099 -7.232 1.442 -34.033 1.00 31.01 H ATOM 3360 N SER A1100 -3.673 1.660 -31.457 1.00 30.26 N ATOM 3361 CA SER A1100 -2.501 2.255 -30.813 1.00 30.30 C ATOM 3362 C SER A1100 -2.007 3.557 -31.475 1.00 34.31 C ATOM 3363 O SER A1100 -1.544 4.442 -30.757 1.00 34.07 O ATOM 3364 CB SER A1100 -1.395 1.186 -30.688 1.00 35.14 C ATOM 3365 OG SER A1100 -0.812 0.863 -31.936 1.00 49.21 O ATOM 3366 H SER A1100 -3.544 0.722 -31.816 1.00 30.26 H ATOM 3367 HA SER A1100 -2.810 2.508 -29.798 1.00 30.30 H ATOM 3368 HB3 SER A1100 -1.789 0.278 -30.231 1.00 35.14 H ATOM 3369 HB2 SER A1100 -0.604 1.548 -30.030 1.00 35.14 H ATOM 3370 HG SER A1100 -0.171 0.161 -31.804 1.00 49.21 H ATOM 3371 N SER A1101 -2.165 3.675 -32.806 1.00 31.40 N ATOM 3372 CA SER A1101 -1.859 4.886 -33.572 1.00 31.93 C ATOM 3373 C SER A1101 -2.867 6.034 -33.343 1.00 35.91 C ATOM 3374 O SER A1101 -2.506 7.191 -33.557 1.00 36.89 O ATOM 3375 CB SER A1101 -1.697 4.523 -35.064 1.00 36.50 C ATOM 3376 OG SER A1101 -2.929 4.318 -35.729 1.00 42.36 O ATOM 3377 H SER A1101 -2.558 2.902 -33.327 1.00 31.40 H ATOM 3378 HA SER A1101 -0.886 5.241 -33.226 1.00 31.93 H ATOM 3379 HB3 SER A1101 -1.073 3.636 -35.181 1.00 36.50 H ATOM 3380 HB2 SER A1101 -1.179 5.333 -35.580 1.00 36.50 H ATOM 3381 HG SER A1101 -3.291 3.462 -35.475 1.00 42.36 H ATOM 3382 N GLN A1102 -4.091 5.700 -32.898 1.00 29.85 N ATOM 3383 CA GLN A1102 -5.158 6.649 -32.581 1.00 28.09 C ATOM 3384 C GLN A1102 -5.318 6.881 -31.067 1.00 29.55 C ATOM 3385 O GLN A1102 -6.205 7.643 -30.690 1.00 27.73 O ATOM 3386 CB GLN A1102 -6.487 6.161 -33.198 1.00 29.07 C ATOM 3387 CG GLN A1102 -6.456 6.050 -34.735 1.00 37.94 C ATOM 3388 CD GLN A1102 -7.845 5.775 -35.316 1.00 47.98 C ATOM 3389 OE1 GLN A1102 -8.717 6.640 -35.277 1.00 45.96 O ATOM 3390 NE2 GLN A1102 -8.059 4.581 -35.868 1.00 43.70 N ATOM 3391 H GLN A1102 -4.308 4.725 -32.740 1.00 29.85 H ATOM 3392 HA GLN A1102 -4.936 7.620 -33.021 1.00 28.09 H ATOM 3393 HB3 GLN A1102 -7.282 6.854 -32.919 1.00 29.07 H ATOM 3394 HB2 GLN A1102 -6.763 5.199 -32.764 1.00 29.07 H ATOM 3395 HG3 GLN A1102 -5.755 5.277 -35.050 1.00 37.94 H ATOM 3396 HG2 GLN A1102 -6.095 6.985 -35.164 1.00 37.94 H ATOM 3397 HE22 GLN A1102 -8.960 4.358 -36.266 1.00 43.70 H ATOM 3398 HE21 GLN A1102 -7.316 3.889 -35.901 1.00 43.70 H ATOM 3399 N SER A1103 -4.496 6.236 -30.218 1.00 26.76 N ATOM 3400 CA SER A1103 -4.636 6.266 -28.758 1.00 25.27 C ATOM 3401 C SER A1103 -4.416 7.666 -28.134 1.00 28.60 C ATOM 3402 O SER A1103 -3.673 8.456 -28.717 1.00 28.62 O ATOM 3403 CB SER A1103 -3.733 5.180 -28.139 1.00 27.32 C ATOM 3404 OG SER A1103 -2.362 5.531 -28.107 1.00 35.29 O ATOM 3405 H SER A1103 -3.775 5.633 -30.588 1.00 26.76 H ATOM 3406 HA SER A1103 -5.664 5.963 -28.587 1.00 25.27 H ATOM 3407 HB3 SER A1103 -3.855 4.235 -28.667 1.00 27.32 H ATOM 3408 HB2 SER A1103 -4.052 4.997 -27.114 1.00 27.32 H ATOM 3409 HG SER A1103 -1.996 5.451 -28.995 1.00 35.29 H ATOM 3410 N PRO A1104 -5.039 7.954 -26.962 1.00 25.17 N ATOM 3411 CA PRO A1104 -4.893 9.264 -26.293 1.00 24.67 C ATOM 3412 C PRO A1104 -3.456 9.762 -26.008 1.00 26.87 C ATOM 3413 O PRO A1104 -3.206 10.927 -26.311 1.00 25.99 O ATOM 3414 CB PRO A1104 -5.768 9.172 -25.030 1.00 26.01 C ATOM 3415 CG PRO A1104 -6.761 8.063 -25.336 1.00 29.46 C ATOM 3416 CD PRO A1104 -5.996 7.109 -26.241 1.00 25.85 C ATOM 3417 HA PRO A1104 -5.359 9.984 -26.965 1.00 24.67 H ATOM 3418 HB3 PRO A1104 -6.271 10.113 -24.806 1.00 26.01 H ATOM 3419 HB2 PRO A1104 -5.186 8.913 -24.146 1.00 26.01 H ATOM 3420 HG3 PRO A1104 -7.598 8.483 -25.894 1.00 29.46 H ATOM 3421 HG2 PRO A1104 -7.161 7.577 -24.447 1.00 29.46 H ATOM 3422 HD2 PRO A1104 -5.453 6.369 -25.652 1.00 25.85 H ATOM 3423 HD3 PRO A1104 -6.704 6.583 -26.879 1.00 25.85 H ATOM 3424 N PRO A1105 -2.512 8.903 -25.540 1.00 24.58 N ATOM 3425 CA PRO A1105 -1.095 9.290 -25.409 1.00 24.76 C ATOM 3426 C PRO A1105 -0.414 9.681 -26.728 1.00 29.78 C ATOM 3427 O PRO A1105 0.275 10.696 -26.749 1.00 30.24 O ATOM 3428 CB PRO A1105 -0.416 8.074 -24.751 1.00 25.88 C ATOM 3429 CG PRO A1105 -1.547 7.335 -24.062 1.00 29.87 C ATOM 3430 CD PRO A1105 -2.716 7.555 -25.010 1.00 25.57 C ATOM 3431 HA PRO A1105 -1.051 10.139 -24.727 1.00 24.76 H ATOM 3432 HB3 PRO A1105 0.372 8.361 -24.055 1.00 25.88 H ATOM 3433 HB2 PRO A1105 0.031 7.420 -25.501 1.00 25.88 H ATOM 3434 HG3 PRO A1105 -1.760 7.813 -23.106 1.00 29.87 H ATOM 3435 HG2 PRO A1105 -1.332 6.283 -23.876 1.00 29.87 H ATOM 3436 HD2 PRO A1105 -2.673 6.841 -25.829 1.00 25.57 H ATOM 3437 HD3 PRO A1105 -3.660 7.421 -24.492 1.00 25.57 H ATOM 3438 N THR A1106 -0.644 8.900 -27.798 1.00 26.99 N ATOM 3439 CA THR A1106 -0.097 9.143 -29.134 1.00 27.47 C ATOM 3440 C THR A1106 -0.563 10.483 -29.734 1.00 31.84 C ATOM 3441 O THR A1106 0.284 11.263 -30.166 1.00 32.09 O ATOM 3442 CB THR A1106 -0.470 7.995 -30.114 1.00 33.90 C ATOM 3443 OG1 THR A1106 0.169 6.812 -29.680 1.00 35.61 O ATOM 3444 CG2 THR A1106 -0.091 8.228 -31.588 1.00 32.59 C ATOM 3445 H THR A1106 -1.225 8.079 -27.705 1.00 26.99 H ATOM 3446 HA THR A1106 0.990 9.178 -29.039 1.00 27.47 H ATOM 3447 HB THR A1106 -1.542 7.801 -30.070 1.00 33.90 H ATOM 3448 HG1 THR A1106 1.077 6.817 -30.001 1.00 35.61 H ATOM 3449 HG21 THR A1106 -0.167 7.307 -32.166 1.00 32.59 H ATOM 3450 HG22 THR A1106 -0.747 8.958 -32.064 1.00 32.59 H ATOM 3451 HG23 THR A1106 0.931 8.592 -31.679 1.00 32.59 H ATOM 3452 N LYS A1107 -1.881 10.734 -29.718 1.00 27.48 N ATOM 3453 CA LYS A1107 -2.498 11.914 -30.325 1.00 28.03 C ATOM 3454 C LYS A1107 -2.239 13.220 -29.553 1.00 32.41 C ATOM 3455 O LYS A1107 -2.116 14.260 -30.199 1.00 32.90 O ATOM 3456 CB LYS A1107 -4.004 11.655 -30.524 1.00 29.00 C ATOM 3457 CG LYS A1107 -4.332 10.463 -31.452 1.00 40.91 C ATOM 3458 CD LYS A1107 -3.799 10.551 -32.893 1.00 47.46 C ATOM 3459 CE LYS A1107 -4.424 11.691 -33.711 1.00 56.00 C ATOM 3460 NZ LYS A1107 -3.900 11.720 -35.087 1.00 65.65 N1+ ATOM 3461 H LYS A1107 -2.514 10.051 -29.322 1.00 27.48 H ATOM 3462 HA LYS A1107 -2.042 12.056 -31.305 1.00 28.03 H ATOM 3463 HB3 LYS A1107 -4.486 12.553 -30.910 1.00 29.00 H ATOM 3464 HB2 LYS A1107 -4.459 11.467 -29.551 1.00 29.00 H ATOM 3465 HG3 LYS A1107 -5.412 10.339 -31.485 1.00 40.91 H ATOM 3466 HG2 LYS A1107 -3.949 9.546 -31.011 1.00 40.91 H ATOM 3467 HD3 LYS A1107 -3.999 9.605 -33.395 1.00 47.46 H ATOM 3468 HD2 LYS A1107 -2.713 10.638 -32.883 1.00 47.46 H ATOM 3469 HE3 LYS A1107 -4.217 12.652 -33.244 1.00 56.00 H ATOM 3470 HE2 LYS A1107 -5.507 11.575 -33.750 1.00 56.00 H ATOM 3471 HZ1 LYS A1107 -2.898 11.867 -35.052 1.00 65.65 H ATOM 3472 HZ2 LYS A1107 -4.094 10.843 -35.549 1.00 65.65 H ATOM 3473 HZ3 LYS A1107 -4.332 12.478 -35.596 1.00 65.65 H ATOM 3474 N PHE A1108 -2.117 13.159 -28.214 1.00 27.91 N ATOM 3475 CA PHE A1108 -1.728 14.312 -27.396 1.00 26.74 C ATOM 3476 C PHE A1108 -0.225 14.638 -27.463 1.00 30.76 C ATOM 3477 O PHE A1108 0.112 15.819 -27.437 1.00 31.53 O ATOM 3478 CB PHE A1108 -2.223 14.161 -25.939 1.00 27.18 C ATOM 3479 CG PHE A1108 -3.708 14.423 -25.709 1.00 27.38 C ATOM 3480 CD1 PHE A1108 -4.294 15.643 -26.113 1.00 29.59 C ATOM 3481 CD2 PHE A1108 -4.499 13.500 -24.989 1.00 28.32 C ATOM 3482 CE1 PHE A1108 -5.631 15.902 -25.840 1.00 30.31 C ATOM 3483 CE2 PHE A1108 -5.834 13.775 -24.728 1.00 29.39 C ATOM 3484 CZ PHE A1108 -6.397 14.972 -25.151 1.00 28.52 C ATOM 3485 H PHE A1108 -2.248 12.280 -27.730 1.00 27.91 H ATOM 3486 HA PHE A1108 -2.218 15.191 -27.816 1.00 26.74 H ATOM 3487 HB3 PHE A1108 -1.680 14.842 -25.282 1.00 27.18 H ATOM 3488 HB2 PHE A1108 -1.976 13.159 -25.590 1.00 27.18 H ATOM 3489 HD1 PHE A1108 -3.706 16.390 -26.627 1.00 29.59 H ATOM 3490 HD2 PHE A1108 -4.075 12.576 -24.629 1.00 28.32 H ATOM 3491 HE1 PHE A1108 -6.075 16.835 -26.155 1.00 30.31 H ATOM 3492 HE2 PHE A1108 -6.435 13.059 -24.188 1.00 29.39 H ATOM 3493 HZ PHE A1108 -7.436 15.180 -24.942 1.00 28.52 H ATOM 3494 N LEU A1109 0.650 13.622 -27.593 1.00 27.77 N ATOM 3495 CA LEU A1109 2.100 13.811 -27.752 1.00 28.51 C ATOM 3496 C LEU A1109 2.516 14.255 -29.168 1.00 34.25 C ATOM 3497 O LEU A1109 3.626 14.765 -29.315 1.00 34.88 O ATOM 3498 CB LEU A1109 2.860 12.542 -27.309 1.00 28.11 C ATOM 3499 CG LEU A1109 2.842 12.310 -25.779 1.00 32.10 C ATOM 3500 CD1 LEU A1109 3.338 10.893 -25.419 1.00 30.45 C ATOM 3501 CD2 LEU A1109 3.605 13.410 -25.010 1.00 36.17 C ATOM 3502 H LEU A1109 0.319 12.666 -27.597 1.00 27.77 H ATOM 3503 HA LEU A1109 2.404 14.626 -27.095 1.00 28.51 H ATOM 3504 HB3 LEU A1109 3.901 12.592 -27.634 1.00 28.11 H ATOM 3505 HB2 LEU A1109 2.437 11.682 -27.830 1.00 28.11 H ATOM 3506 HG LEU A1109 1.804 12.362 -25.449 1.00 32.10 H ATOM 3507 HD11 LEU A1109 2.593 10.366 -24.822 1.00 30.45 H ATOM 3508 HD12 LEU A1109 3.521 10.287 -26.306 1.00 30.45 H ATOM 3509 HD13 LEU A1109 4.266 10.903 -24.848 1.00 30.45 H ATOM 3510 HD21 LEU A1109 4.230 13.014 -24.210 1.00 36.17 H ATOM 3511 HD22 LEU A1109 4.255 13.987 -25.667 1.00 36.17 H ATOM 3512 HD23 LEU A1109 2.908 14.111 -24.549 1.00 36.17 H ATOM 3513 N GLU A1110 1.626 14.116 -30.166 1.00 32.96 N ATOM 3514 CA GLU A1110 1.757 14.754 -31.480 1.00 35.44 C ATOM 3515 C GLU A1110 1.538 16.278 -31.416 1.00 38.81 C ATOM 3516 O GLU A1110 2.214 17.004 -32.143 1.00 38.69 O ATOM 3517 CB GLU A1110 0.776 14.106 -32.477 1.00 36.99 C ATOM 3518 CG GLU A1110 1.234 12.724 -32.992 1.00 47.30 C ATOM 3519 CD GLU A1110 0.184 11.941 -33.801 1.00 70.21 C ATOM 3520 OE1 GLU A1110 -0.902 12.492 -34.093 1.00 64.58 O ATOM 3521 OE2 GLU A1110 0.490 10.773 -34.124 1.00 65.32 O1- ATOM 3522 H GLU A1110 0.748 13.648 -29.986 1.00 32.96 H ATOM 3523 HA GLU A1110 2.773 14.593 -31.847 1.00 35.44 H ATOM 3524 HB3 GLU A1110 0.605 14.769 -33.327 1.00 36.99 H ATOM 3525 HB2 GLU A1110 -0.188 13.999 -31.980 1.00 36.99 H ATOM 3526 HG3 GLU A1110 1.562 12.107 -32.159 1.00 47.30 H ATOM 3527 HG2 GLU A1110 2.115 12.857 -33.622 1.00 47.30 H ATOM 3528 N LEU A1111 0.621 16.731 -30.540 1.00 35.92 N ATOM 3529 CA LEU A1111 0.318 18.147 -30.309 1.00 37.14 C ATOM 3530 C LEU A1111 1.372 18.829 -29.418 1.00 40.62 C ATOM 3531 O LEU A1111 1.740 19.971 -29.693 1.00 41.55 O ATOM 3532 CB LEU A1111 -1.087 18.286 -29.673 1.00 36.92 C ATOM 3533 CG LEU A1111 -2.260 17.801 -30.555 1.00 41.87 C ATOM 3534 CD1 LEU A1111 -3.572 17.728 -29.743 1.00 41.05 C ATOM 3535 CD2 LEU A1111 -2.410 18.636 -31.845 1.00 44.81 C ATOM 3536 H LEU A1111 0.107 16.071 -29.975 1.00 35.92 H ATOM 3537 HA LEU A1111 0.322 18.664 -31.270 1.00 37.14 H ATOM 3538 HB3 LEU A1111 -1.265 19.329 -29.406 1.00 36.92 H ATOM 3539 HB2 LEU A1111 -1.100 17.738 -28.731 1.00 36.92 H ATOM 3540 HG LEU A1111 -2.038 16.781 -30.864 1.00 41.87 H ATOM 3541 HD11 LEU A1111 -4.009 16.731 -29.803 1.00 41.05 H ATOM 3542 HD12 LEU A1111 -3.410 17.942 -28.686 1.00 41.05 H ATOM 3543 HD13 LEU A1111 -4.325 18.435 -30.089 1.00 41.05 H ATOM 3544 HD21 LEU A1111 -3.440 18.931 -32.041 1.00 44.81 H ATOM 3545 HD22 LEU A1111 -1.820 19.552 -31.810 1.00 44.81 H ATOM 3546 HD23 LEU A1111 -2.074 18.066 -32.712 1.00 44.81 H ATOM 3547 N ILE A1112 1.827 18.124 -28.368 1.00 34.80 N ATOM 3548 CA ILE A1112 2.759 18.628 -27.356 1.00 34.93 C ATOM 3549 C ILE A1112 4.230 18.572 -27.815 1.00 40.11 C ATOM 3550 O ILE A1112 4.994 19.473 -27.471 1.00 41.74 O ATOM 3551 CB ILE A1112 2.614 17.819 -26.027 1.00 36.99 C ATOM 3552 CG1 ILE A1112 1.226 18.047 -25.391 1.00 35.84 C ATOM 3553 CG2 ILE A1112 3.707 18.065 -24.963 1.00 37.00 C ATOM 3554 CD1 ILE A1112 0.810 16.938 -24.417 1.00 35.00 C ATOM 3555 H ILE A1112 1.452 17.199 -28.201 1.00 34.80 H ATOM 3556 HA ILE A1112 2.514 19.672 -27.148 1.00 34.93 H ATOM 3557 HB ILE A1112 2.677 16.764 -26.294 1.00 36.99 H ATOM 3558 HG13 ILE A1112 0.460 18.112 -26.162 1.00 35.84 H ATOM 3559 HG12 ILE A1112 1.208 19.011 -24.881 1.00 35.84 H ATOM 3560 HG21 ILE A1112 3.496 17.533 -24.036 1.00 37.00 H ATOM 3561 HG22 ILE A1112 4.688 17.726 -25.289 1.00 37.00 H ATOM 3562 HG23 ILE A1112 3.786 19.123 -24.726 1.00 37.00 H ATOM 3563 HD11 ILE A1112 -0.272 16.926 -24.293 1.00 35.00 H ATOM 3564 HD12 ILE A1112 1.106 15.951 -24.774 1.00 35.00 H ATOM 3565 HD13 ILE A1112 1.261 17.086 -23.438 1.00 35.00 H ATOM 3566 N GLY A1113 4.598 17.509 -28.549 1.00 36.74 N ATOM 3567 CA GLY A1113 5.986 17.125 -28.807 1.00 38.59 C ATOM 3568 C GLY A1113 6.458 16.152 -27.712 1.00 41.94 C ATOM 3569 O GLY A1113 5.723 15.847 -26.772 1.00 39.30 O ATOM 3570 H GLY A1113 3.896 16.830 -28.812 1.00 36.74 H ATOM 3571 HA3 GLY A1113 6.645 17.994 -28.846 1.00 38.59 H ATOM 3572 HA2 GLY A1113 6.038 16.630 -29.777 1.00 38.59 H ATOM 3573 N ILE A1114 7.697 15.653 -27.849 1.00 41.30 N ATOM 3574 CA ILE A1114 8.305 14.668 -26.942 1.00 41.02 C ATOM 3575 C ILE A1114 9.607 15.170 -26.275 1.00 47.14 C ATOM 3576 O ILE A1114 10.221 14.411 -25.524 1.00 48.03 O ATOM 3577 CB ILE A1114 8.578 13.319 -27.673 1.00 43.24 C ATOM 3578 CG1 ILE A1114 9.541 13.438 -28.881 1.00 44.89 C ATOM 3579 CG2 ILE A1114 7.256 12.629 -28.061 1.00 42.60 C ATOM 3580 CD1 ILE A1114 10.047 12.085 -29.402 1.00 50.07 C ATOM 3581 H ILE A1114 8.254 15.920 -28.647 1.00 41.30 H ATOM 3582 HA ILE A1114 7.632 14.455 -26.109 1.00 41.02 H ATOM 3583 HB ILE A1114 9.054 12.649 -26.955 1.00 43.24 H ATOM 3584 HG13 ILE A1114 10.411 14.042 -28.624 1.00 44.89 H ATOM 3585 HG12 ILE A1114 9.044 13.969 -29.694 1.00 44.89 H ATOM 3586 HG21 ILE A1114 7.425 11.627 -28.454 1.00 42.60 H ATOM 3587 HG22 ILE A1114 6.597 12.528 -27.198 1.00 42.60 H ATOM 3588 HG23 ILE A1114 6.716 13.194 -28.821 1.00 42.60 H ATOM 3589 HD11 ILE A1114 10.937 12.217 -30.019 1.00 50.07 H ATOM 3590 HD12 ILE A1114 10.311 11.414 -28.585 1.00 50.07 H ATOM 3591 HD13 ILE A1114 9.294 11.590 -30.015 1.00 50.07 H ATOM 3592 N ALA A1115 9.991 16.433 -26.530 1.00 42.26 N ATOM 3593 CA ALA A1115 11.194 17.067 -25.991 1.00 43.31 C ATOM 3594 C ALA A1115 10.820 18.401 -25.327 1.00 48.36 C ATOM 3595 O ALA A1115 11.240 19.462 -25.791 1.00 49.43 O ATOM 3596 CB ALA A1115 12.223 17.220 -27.127 1.00 45.24 C ATOM 3597 H ALA A1115 9.424 17.010 -27.133 1.00 42.26 H ATOM 3598 HA ALA A1115 11.645 16.449 -25.212 1.00 43.31 H ATOM 3599 HB1 ALA A1115 13.140 17.690 -26.770 1.00 45.24 H ATOM 3600 HB2 ALA A1115 12.495 16.247 -27.537 1.00 45.24 H ATOM 3601 HB3 ALA A1115 11.832 17.826 -27.946 1.00 45.24 H ATOM 3602 N GLN A1116 10.012 18.309 -24.258 1.00 44.35 N ATOM 3603 CA GLN A1116 9.464 19.450 -23.516 1.00 44.30 C ATOM 3604 C GLN A1116 9.925 19.478 -22.046 1.00 49.79 C ATOM 3605 O GLN A1116 9.447 20.327 -21.292 1.00 49.85 O ATOM 3606 CB GLN A1116 7.918 19.420 -23.615 1.00 44.27 C ATOM 3607 CG GLN A1116 7.347 19.441 -25.051 1.00 53.29 C ATOM 3608 CD GLN A1116 7.835 20.599 -25.930 1.00 72.09 C ATOM 3609 OE1 GLN A1116 8.158 20.396 -27.098 1.00 65.48 O ATOM 3610 NE2 GLN A1116 7.883 21.818 -25.389 1.00 65.05 N ATOM 3611 H GLN A1116 9.716 17.395 -23.938 1.00 44.35 H ATOM 3612 HA GLN A1116 9.827 20.386 -23.941 1.00 44.30 H ATOM 3613 HB3 GLN A1116 7.499 20.263 -23.064 1.00 44.27 H ATOM 3614 HB2 GLN A1116 7.541 18.532 -23.106 1.00 44.27 H ATOM 3615 HG3 GLN A1116 6.262 19.478 -25.007 1.00 53.29 H ATOM 3616 HG2 GLN A1116 7.588 18.503 -25.555 1.00 53.29 H ATOM 3617 HE22 GLN A1116 8.200 22.601 -25.942 1.00 65.05 H ATOM 3618 HE21 GLN A1116 7.607 21.967 -24.430 1.00 65.05 H ATOM 3619 N GLY A1117 10.844 18.574 -21.657 1.00 46.41 N ATOM 3620 CA GLY A1117 11.368 18.465 -20.296 1.00 44.66 C ATOM 3621 C GLY A1117 10.279 17.930 -19.358 1.00 42.63 C ATOM 3622 O GLY A1117 9.610 16.945 -19.673 1.00 37.23 O ATOM 3623 H GLY A1117 11.190 17.910 -22.334 1.00 46.41 H ATOM 3624 HA3 GLY A1117 11.738 19.434 -19.957 1.00 44.66 H ATOM 3625 HA2 GLY A1117 12.213 17.776 -20.293 1.00 44.66 H ATOM 3626 N GLN A1118 10.122 18.593 -18.202 1.00 39.82 N ATOM 3627 CA GLN A1118 9.103 18.311 -17.187 1.00 38.37 C ATOM 3628 C GLN A1118 7.702 18.861 -17.532 1.00 40.30 C ATOM 3629 O GLN A1118 6.772 18.611 -16.767 1.00 41.07 O ATOM 3630 CB GLN A1118 9.579 18.887 -15.835 1.00 41.27 C ATOM 3631 CG GLN A1118 10.836 18.198 -15.270 1.00 52.25 C ATOM 3632 CD GLN A1118 11.326 18.877 -13.990 1.00 66.80 C ATOM 3633 OE1 GLN A1118 11.669 20.058 -14.005 1.00 64.29 O ATOM 3634 NE2 GLN A1118 11.383 18.133 -12.884 1.00 50.92 N ATOM 3635 H GLN A1118 10.710 19.396 -18.014 1.00 39.82 H ATOM 3636 HA GLN A1118 9.006 17.229 -17.079 1.00 38.37 H ATOM 3637 HB3 GLN A1118 8.784 18.797 -15.092 1.00 41.27 H ATOM 3638 HB2 GLN A1118 9.757 19.958 -15.946 1.00 41.27 H ATOM 3639 HG3 GLN A1118 11.650 18.234 -15.995 1.00 52.25 H ATOM 3640 HG2 GLN A1118 10.632 17.142 -15.085 1.00 52.25 H ATOM 3641 HE22 GLN A1118 11.710 18.541 -12.020 1.00 50.92 H ATOM 3642 HE21 GLN A1118 11.099 17.164 -12.899 1.00 50.92 H ATOM 3643 N MET A1119 7.569 19.615 -18.638 1.00 34.93 N ATOM 3644 CA MET A1119 6.375 20.393 -18.980 1.00 34.58 C ATOM 3645 C MET A1119 5.309 19.636 -19.797 1.00 34.58 C ATOM 3646 O MET A1119 4.432 20.303 -20.340 1.00 34.71 O ATOM 3647 CB MET A1119 6.788 21.702 -19.694 1.00 38.63 C ATOM 3648 CG MET A1119 7.827 22.543 -18.940 1.00 44.95 C ATOM 3649 SD MET A1119 8.154 24.140 -19.731 1.00 52.97 S ATOM 3650 CE MET A1119 9.330 24.826 -18.536 1.00 51.70 C ATOM 3651 H MET A1119 8.371 19.756 -19.237 1.00 34.93 H ATOM 3652 HA MET A1119 5.885 20.689 -18.052 1.00 34.58 H ATOM 3653 HB3 MET A1119 5.908 22.328 -19.853 1.00 38.63 H ATOM 3654 HB2 MET A1119 7.169 21.473 -20.690 1.00 38.63 H ATOM 3655 HG3 MET A1119 8.773 22.006 -18.862 1.00 44.95 H ATOM 3656 HG2 MET A1119 7.483 22.729 -17.922 1.00 44.95 H ATOM 3657 HE1 MET A1119 9.653 25.818 -18.853 1.00 51.70 H ATOM 3658 HE2 MET A1119 8.868 24.912 -17.553 1.00 51.70 H ATOM 3659 HE3 MET A1119 10.208 24.186 -18.455 1.00 51.70 H ATOM 3660 N THR A1120 5.357 18.294 -19.887 1.00 29.62 N ATOM 3661 CA THR A1120 4.382 17.500 -20.655 1.00 28.01 C ATOM 3662 C THR A1120 2.922 17.666 -20.173 1.00 30.48 C ATOM 3663 O THR A1120 2.044 17.875 -21.008 1.00 31.09 O ATOM 3664 CB THR A1120 4.714 15.984 -20.657 1.00 32.05 C ATOM 3665 OG1 THR A1120 6.047 15.796 -21.089 1.00 33.94 O ATOM 3666 CG2 THR A1120 3.806 15.122 -21.558 1.00 34.10 C ATOM 3667 H THR A1120 6.099 17.780 -19.434 1.00 29.62 H ATOM 3668 HA THR A1120 4.429 17.856 -21.687 1.00 28.01 H ATOM 3669 HB THR A1120 4.654 15.596 -19.640 1.00 32.05 H ATOM 3670 HG1 THR A1120 6.086 15.941 -22.042 1.00 33.94 H ATOM 3671 HG21 THR A1120 4.157 14.090 -21.595 1.00 34.10 H ATOM 3672 HG22 THR A1120 2.778 15.093 -21.197 1.00 34.10 H ATOM 3673 HG23 THR A1120 3.789 15.501 -22.580 1.00 34.10 H ATOM 3674 N VAL A1121 2.703 17.617 -18.846 1.00 28.98 N ATOM 3675 CA VAL A1121 1.392 17.805 -18.215 1.00 29.28 C ATOM 3676 C VAL A1121 0.911 19.271 -18.238 1.00 34.54 C ATOM 3677 O VAL A1121 -0.286 19.494 -18.411 1.00 33.68 O ATOM 3678 CB VAL A1121 1.377 17.249 -16.760 1.00 33.58 C ATOM 3679 CG1 VAL A1121 0.177 17.681 -15.888 1.00 33.26 C ATOM 3680 CG2 VAL A1121 1.457 15.714 -16.784 1.00 32.88 C ATOM 3681 H VAL A1121 3.476 17.441 -18.218 1.00 28.98 H ATOM 3682 HA VAL A1121 0.669 17.224 -18.791 1.00 29.28 H ATOM 3683 HB VAL A1121 2.275 17.603 -16.253 1.00 33.58 H ATOM 3684 HG11 VAL A1121 0.163 17.145 -14.938 1.00 33.26 H ATOM 3685 HG12 VAL A1121 0.205 18.744 -15.644 1.00 33.26 H ATOM 3686 HG13 VAL A1121 -0.765 17.478 -16.396 1.00 33.26 H ATOM 3687 HG21 VAL A1121 1.485 15.304 -15.775 1.00 32.88 H ATOM 3688 HG22 VAL A1121 0.594 15.285 -17.294 1.00 32.88 H ATOM 3689 HG23 VAL A1121 2.350 15.362 -17.300 1.00 32.88 H ATOM 3690 N LEU A1122 1.842 20.235 -18.115 1.00 32.43 N ATOM 3691 CA LEU A1122 1.585 21.672 -18.261 1.00 33.01 C ATOM 3692 C LEU A1122 1.097 22.028 -19.675 1.00 36.61 C ATOM 3693 O LEU A1122 0.147 22.792 -19.813 1.00 35.87 O ATOM 3694 CB LEU A1122 2.865 22.455 -17.871 1.00 35.17 C ATOM 3695 CG LEU A1122 2.831 23.990 -18.076 1.00 42.10 C ATOM 3696 CD1 LEU A1122 1.697 24.666 -17.275 1.00 43.87 C ATOM 3697 CD2 LEU A1122 4.213 24.615 -17.788 1.00 45.28 C ATOM 3698 H LEU A1122 2.802 19.973 -17.936 1.00 32.43 H ATOM 3699 HA LEU A1122 0.790 21.933 -17.561 1.00 33.01 H ATOM 3700 HB3 LEU A1122 3.699 22.056 -18.448 1.00 35.17 H ATOM 3701 HB2 LEU A1122 3.102 22.243 -16.827 1.00 35.17 H ATOM 3702 HG LEU A1122 2.640 24.189 -19.131 1.00 42.10 H ATOM 3703 HD11 LEU A1122 2.023 25.573 -16.765 1.00 43.87 H ATOM 3704 HD12 LEU A1122 0.879 24.954 -17.937 1.00 43.87 H ATOM 3705 HD13 LEU A1122 1.280 24.004 -16.515 1.00 43.87 H ATOM 3706 HD21 LEU A1122 4.553 25.207 -18.639 1.00 45.28 H ATOM 3707 HD22 LEU A1122 4.206 25.272 -16.919 1.00 45.28 H ATOM 3708 HD23 LEU A1122 4.975 23.858 -17.601 1.00 45.28 H ATOM 3709 N ARG A1123 1.746 21.445 -20.692 1.00 32.17 N ATOM 3710 CA ARG A1123 1.467 21.679 -22.105 1.00 32.60 C ATOM 3711 C ARG A1123 0.200 20.951 -22.588 1.00 33.95 C ATOM 3712 O ARG A1123 -0.493 21.472 -23.462 1.00 32.13 O ATOM 3713 CB ARG A1123 2.736 21.303 -22.888 1.00 37.04 C ATOM 3714 CG ARG A1123 2.892 21.997 -24.254 1.00 59.77 C ATOM 3715 CD ARG A1123 4.363 22.141 -24.691 1.00 74.58 C ATOM 3716 NE ARG A1123 5.119 23.067 -23.819 1.00 91.08 N ATOM 3717 CZ ARG A1123 5.295 24.392 -23.966 1.00107.84 C ATOM 3718 NH1 ARG A1123 4.844 25.057 -25.040 1.00 95.16 N ATOM 3719 NH2 ARG A1123 5.939 25.067 -23.005 1.00 96.44 N1+ ATOM 3720 H ARG A1123 2.526 20.832 -20.491 1.00 32.17 H ATOM 3721 HA ARG A1123 1.305 22.752 -22.216 1.00 32.60 H ATOM 3722 HB3 ARG A1123 2.821 20.221 -22.983 1.00 37.04 H ATOM 3723 HB2 ARG A1123 3.583 21.603 -22.275 1.00 37.04 H ATOM 3724 HG3 ARG A1123 2.490 23.004 -24.140 1.00 59.77 H ATOM 3725 HG2 ARG A1123 2.293 21.525 -25.033 1.00 59.77 H ATOM 3726 HD3 ARG A1123 4.461 22.348 -25.756 1.00 74.58 H ATOM 3727 HD2 ARG A1123 4.854 21.184 -24.530 1.00 74.58 H ATOM 3728 HE ARG A1123 5.455 22.651 -22.962 1.00 91.08 H ATOM 3729 HH12 ARG A1123 4.979 26.054 -25.126 1.00 95.16 H ATOM 3730 HH11 ARG A1123 4.356 24.557 -25.770 1.00 95.16 H ATOM 3731 HH22 ARG A1123 6.066 26.066 -23.080 1.00 96.44 H ATOM 3732 HH21 ARG A1123 6.276 24.592 -22.179 1.00 96.44 H ATOM 3733 N LEU A1124 -0.112 19.805 -21.954 1.00 29.63 N ATOM 3734 CA LEU A1124 -1.388 19.096 -22.055 1.00 27.63 C ATOM 3735 C LEU A1124 -2.543 19.916 -21.454 1.00 32.17 C ATOM 3736 O LEU A1124 -3.597 19.988 -22.075 1.00 30.80 O ATOM 3737 CB LEU A1124 -1.248 17.704 -21.396 1.00 26.83 C ATOM 3738 CG LEU A1124 -2.516 16.823 -21.323 1.00 30.02 C ATOM 3739 CD1 LEU A1124 -3.141 16.553 -22.711 1.00 28.94 C ATOM 3740 CD2 LEU A1124 -2.214 15.525 -20.543 1.00 30.63 C ATOM 3741 H LEU A1124 0.538 19.434 -21.274 1.00 29.63 H ATOM 3742 HA LEU A1124 -1.597 18.955 -23.116 1.00 27.63 H ATOM 3743 HB3 LEU A1124 -0.887 17.844 -20.379 1.00 26.83 H ATOM 3744 HB2 LEU A1124 -0.465 17.145 -21.905 1.00 26.83 H ATOM 3745 HG LEU A1124 -3.267 17.355 -20.740 1.00 30.02 H ATOM 3746 HD11 LEU A1124 -3.376 15.502 -22.874 1.00 28.94 H ATOM 3747 HD12 LEU A1124 -4.075 17.103 -22.827 1.00 28.94 H ATOM 3748 HD13 LEU A1124 -2.488 16.857 -23.527 1.00 28.94 H ATOM 3749 HD21 LEU A1124 -2.585 14.631 -21.039 1.00 30.63 H ATOM 3750 HD22 LEU A1124 -1.145 15.379 -20.382 1.00 30.63 H ATOM 3751 HD23 LEU A1124 -2.678 15.549 -19.558 1.00 30.63 H ATOM 3752 N THR A1125 -2.322 20.555 -20.291 1.00 30.97 N ATOM 3753 CA THR A1125 -3.292 21.455 -19.661 1.00 31.58 C ATOM 3754 C THR A1125 -3.564 22.701 -20.526 1.00 35.29 C ATOM 3755 O THR A1125 -4.728 23.042 -20.712 1.00 34.46 O ATOM 3756 CB THR A1125 -2.835 21.924 -18.252 1.00 40.93 C ATOM 3757 OG1 THR A1125 -2.671 20.794 -17.421 1.00 39.64 O ATOM 3758 CG2 THR A1125 -3.789 22.892 -17.526 1.00 41.19 C ATOM 3759 H THR A1125 -1.430 20.452 -19.824 1.00 30.97 H ATOM 3760 HA THR A1125 -4.231 20.908 -19.552 1.00 31.58 H ATOM 3761 HB THR A1125 -1.860 22.404 -18.322 1.00 40.93 H ATOM 3762 HG1 THR A1125 -1.976 20.241 -17.794 1.00 39.64 H ATOM 3763 HG21 THR A1125 -3.407 23.132 -16.535 1.00 41.19 H ATOM 3764 HG22 THR A1125 -3.900 23.840 -18.054 1.00 41.19 H ATOM 3765 HG23 THR A1125 -4.782 22.457 -17.407 1.00 41.19 H ATOM 3766 N GLU A1126 -2.501 23.309 -21.082 1.00 33.17 N ATOM 3767 CA GLU A1126 -2.564 24.482 -21.955 1.00 34.02 C ATOM 3768 C GLU A1126 -3.392 24.279 -23.235 1.00 37.28 C ATOM 3769 O GLU A1126 -4.216 25.145 -23.522 1.00 35.08 O ATOM 3770 CB GLU A1126 -1.143 24.993 -22.262 1.00 36.83 C ATOM 3771 CG GLU A1126 -0.506 25.747 -21.070 1.00 44.51 C ATOM 3772 CD GLU A1126 0.990 26.084 -21.204 1.00 58.80 C ATOM 3773 OE1 GLU A1126 1.481 26.792 -20.298 1.00 49.54 O ATOM 3774 OE2 GLU A1126 1.634 25.646 -22.185 1.00 45.75 O1- ATOM 3775 H GLU A1126 -1.572 22.967 -20.873 1.00 33.17 H ATOM 3776 HA GLU A1126 -3.075 25.262 -21.386 1.00 34.02 H ATOM 3777 HB3 GLU A1126 -1.153 25.649 -23.133 1.00 36.83 H ATOM 3778 HB2 GLU A1126 -0.524 24.139 -22.539 1.00 36.83 H ATOM 3779 HG3 GLU A1126 -0.641 25.179 -20.151 1.00 44.51 H ATOM 3780 HG2 GLU A1126 -1.051 26.680 -20.919 1.00 44.51 H ATOM 3781 N LEU A1127 -3.213 23.152 -23.954 1.00 34.11 N ATOM 3782 CA LEU A1127 -4.014 22.845 -25.150 1.00 33.79 C ATOM 3783 C LEU A1127 -5.491 22.548 -24.835 1.00 35.23 C ATOM 3784 O LEU A1127 -6.346 22.943 -25.626 1.00 34.81 O ATOM 3785 CB LEU A1127 -3.321 21.794 -26.055 1.00 33.69 C ATOM 3786 CG LEU A1127 -3.213 20.336 -25.549 1.00 37.11 C ATOM 3787 CD1 LEU A1127 -4.490 19.501 -25.786 1.00 35.27 C ATOM 3788 CD2 LEU A1127 -1.978 19.633 -26.146 1.00 40.08 C ATOM 3789 H LEU A1127 -2.527 22.467 -23.671 1.00 34.11 H ATOM 3790 HA LEU A1127 -4.026 23.762 -25.744 1.00 33.79 H ATOM 3791 HB3 LEU A1127 -2.314 22.167 -26.235 1.00 33.69 H ATOM 3792 HB2 LEU A1127 -3.792 21.791 -27.039 1.00 33.69 H ATOM 3793 HG LEU A1127 -3.048 20.386 -24.476 1.00 37.11 H ATOM 3794 HD11 LEU A1127 -4.753 18.940 -24.890 1.00 35.27 H ATOM 3795 HD12 LEU A1127 -5.351 20.108 -26.056 1.00 35.27 H ATOM 3796 HD13 LEU A1127 -4.367 18.778 -26.592 1.00 35.27 H ATOM 3797 HD21 LEU A1127 -2.160 18.585 -26.384 1.00 40.08 H ATOM 3798 HD22 LEU A1127 -1.629 20.117 -27.058 1.00 40.08 H ATOM 3799 HD23 LEU A1127 -1.156 19.657 -25.433 1.00 40.08 H ATOM 3800 N LEU A1128 -5.779 21.925 -23.675 1.00 30.68 N ATOM 3801 CA LEU A1128 -7.149 21.698 -23.203 1.00 29.82 C ATOM 3802 C LEU A1128 -7.868 23.003 -22.796 1.00 37.95 C ATOM 3803 O LEU A1128 -9.078 23.099 -23.001 1.00 37.53 O ATOM 3804 CB LEU A1128 -7.182 20.679 -22.042 1.00 28.63 C ATOM 3805 CG LEU A1128 -6.730 19.245 -22.401 1.00 31.65 C ATOM 3806 CD1 LEU A1128 -6.586 18.387 -21.126 1.00 31.42 C ATOM 3807 CD2 LEU A1128 -7.611 18.567 -23.467 1.00 31.56 C ATOM 3808 H LEU A1128 -5.032 21.625 -23.062 1.00 30.68 H ATOM 3809 HA LEU A1128 -7.696 21.275 -24.042 1.00 29.82 H ATOM 3810 HB3 LEU A1128 -8.195 20.625 -21.642 1.00 28.63 H ATOM 3811 HB2 LEU A1128 -6.560 21.058 -21.229 1.00 28.63 H ATOM 3812 HG LEU A1128 -5.745 19.305 -22.850 1.00 31.65 H ATOM 3813 HD11 LEU A1128 -5.551 18.077 -20.987 1.00 31.42 H ATOM 3814 HD12 LEU A1128 -6.877 18.930 -20.226 1.00 31.42 H ATOM 3815 HD13 LEU A1128 -7.192 17.482 -21.154 1.00 31.42 H ATOM 3816 HD21 LEU A1128 -7.634 17.483 -23.356 1.00 31.56 H ATOM 3817 HD22 LEU A1128 -8.638 18.927 -23.434 1.00 31.56 H ATOM 3818 HD23 LEU A1128 -7.222 18.763 -24.465 1.00 31.56 H ATOM 3819 N GLU A1129 -7.122 23.993 -22.277 1.00 37.30 N ATOM 3820 CA GLU A1129 -7.628 25.331 -21.956 1.00 38.66 C ATOM 3821 C GLU A1129 -7.904 26.197 -23.204 1.00 42.10 C ATOM 3822 O GLU A1129 -8.801 27.037 -23.141 1.00 42.78 O ATOM 3823 CB GLU A1129 -6.670 26.032 -20.967 1.00 41.41 C ATOM 3824 CG GLU A1129 -6.622 25.388 -19.556 1.00 54.54 C ATOM 3825 CD GLU A1129 -7.801 25.679 -18.612 1.00 90.90 C ATOM 3826 OE1 GLU A1129 -8.677 26.501 -18.958 1.00 94.26 O ATOM 3827 OE2 GLU A1129 -7.797 25.060 -17.524 1.00 91.13 O1- ATOM 3828 H GLU A1129 -6.137 23.838 -22.107 1.00 37.30 H ATOM 3829 HA GLU A1129 -8.591 25.207 -21.456 1.00 38.66 H ATOM 3830 HB3 GLU A1129 -6.907 27.094 -20.890 1.00 41.41 H ATOM 3831 HB2 GLU A1129 -5.662 26.002 -21.380 1.00 41.41 H ATOM 3832 HG3 GLU A1129 -5.711 25.719 -19.055 1.00 54.54 H ATOM 3833 HG2 GLU A1129 -6.543 24.307 -19.642 1.00 54.54 H ATOM 3834 N ARG A1130 -7.195 25.946 -24.324 1.00 37.87 N ATOM 3835 CA ARG A1130 -7.499 26.535 -25.639 1.00 37.84 C ATOM 3836 C ARG A1130 -8.697 25.873 -26.351 1.00 41.63 C ATOM 3837 O ARG A1130 -9.138 26.406 -27.369 1.00 42.60 O ATOM 3838 CB ARG A1130 -6.265 26.498 -26.566 1.00 37.09 C ATOM 3839 CG ARG A1130 -5.073 27.342 -26.080 1.00 43.14 C ATOM 3840 CD ARG A1130 -4.008 27.588 -27.166 1.00 47.74 C ATOM 3841 NE ARG A1130 -3.331 26.356 -27.610 1.00 51.85 N ATOM 3842 CZ ARG A1130 -2.239 25.772 -27.088 1.00 60.61 C ATOM 3843 NH1 ARG A1130 -1.609 26.260 -26.010 1.00 54.41 N ATOM 3844 NH2 ARG A1130 -1.770 24.664 -27.673 1.00 41.74 N1+ ATOM 3845 H ARG A1130 -6.458 25.254 -24.302 1.00 37.87 H ATOM 3846 HA ARG A1130 -7.769 27.582 -25.491 1.00 37.84 H ATOM 3847 HB3 ARG A1130 -6.554 26.873 -27.549 1.00 37.09 H ATOM 3848 HB2 ARG A1130 -5.950 25.465 -26.724 1.00 37.09 H ATOM 3849 HG3 ARG A1130 -4.609 26.808 -25.257 1.00 43.14 H ATOM 3850 HG2 ARG A1130 -5.394 28.295 -25.660 1.00 43.14 H ATOM 3851 HD3 ARG A1130 -3.308 28.371 -26.873 1.00 47.74 H ATOM 3852 HD2 ARG A1130 -4.508 27.966 -28.058 1.00 47.74 H ATOM 3853 HE ARG A1130 -3.771 25.882 -28.391 1.00 51.85 H ATOM 3854 HH12 ARG A1130 -0.771 25.815 -25.659 1.00 54.41 H ATOM 3855 HH11 ARG A1130 -1.965 27.084 -25.548 1.00 54.41 H ATOM 3856 HH22 ARG A1130 -0.975 24.169 -27.288 1.00 41.74 H ATOM 3857 HH21 ARG A1130 -2.235 24.287 -28.490 1.00 41.74 H ATOM 3858 N GLY A1131 -9.207 24.747 -25.824 1.00 36.22 N ATOM 3859 CA GLY A1131 -10.366 24.048 -26.376 1.00 35.40 C ATOM 3860 C GLY A1131 -9.974 22.960 -27.390 1.00 37.10 C ATOM 3861 O GLY A1131 -10.871 22.416 -28.034 1.00 36.00 O ATOM 3862 H GLY A1131 -8.801 24.371 -24.979 1.00 36.22 H ATOM 3863 HA3 GLY A1131 -11.060 24.747 -26.845 1.00 35.40 H ATOM 3864 HA2 GLY A1131 -10.909 23.585 -25.554 1.00 35.40 H ATOM 3865 N GLU A1132 -8.676 22.623 -27.532 1.00 32.13 N ATOM 3866 CA GLU A1132 -8.205 21.537 -28.397 1.00 31.71 C ATOM 3867 C GLU A1132 -8.525 20.162 -27.793 1.00 33.67 C ATOM 3868 O GLU A1132 -8.257 19.935 -26.613 1.00 31.64 O ATOM 3869 CB GLU A1132 -6.694 21.640 -28.670 1.00 33.82 C ATOM 3870 CG GLU A1132 -6.247 22.982 -29.287 1.00 48.90 C ATOM 3871 CD GLU A1132 -4.778 23.022 -29.744 1.00 65.96 C ATOM 3872 OE1 GLU A1132 -4.195 21.948 -30.019 1.00 51.67 O ATOM 3873 OE2 GLU A1132 -4.249 24.151 -29.826 1.00 68.15 O1- ATOM 3874 H GLU A1132 -7.970 23.086 -26.976 1.00 32.13 H ATOM 3875 HA GLU A1132 -8.720 21.634 -29.353 1.00 31.71 H ATOM 3876 HB3 GLU A1132 -6.426 20.815 -29.330 1.00 33.82 H ATOM 3877 HB2 GLU A1132 -6.135 21.468 -27.752 1.00 33.82 H ATOM 3878 HG3 GLU A1132 -6.417 23.786 -28.569 1.00 48.90 H ATOM 3879 HG2 GLU A1132 -6.869 23.208 -30.154 1.00 48.90 H ATOM 3880 N ARG A1133 -9.080 19.277 -28.631 1.00 30.19 N ATOM 3881 CA ARG A1133 -9.515 17.933 -28.263 1.00 28.71 C ATOM 3882 C ARG A1133 -8.945 16.892 -29.230 1.00 31.32 C ATOM 3883 O ARG A1133 -8.505 17.230 -30.331 1.00 31.52 O ATOM 3884 CB ARG A1133 -11.063 17.876 -28.305 1.00 28.69 C ATOM 3885 CG ARG A1133 -11.789 18.793 -27.309 1.00 29.69 C ATOM 3886 CD ARG A1133 -11.505 18.482 -25.831 1.00 29.80 C ATOM 3887 NE ARG A1133 -12.141 19.468 -24.947 1.00 30.88 N ATOM 3888 CZ ARG A1133 -11.592 20.560 -24.393 1.00 38.38 C ATOM 3889 NH1 ARG A1133 -10.317 20.890 -24.594 1.00 29.25 N ATOM 3890 NH2 ARG A1133 -12.340 21.342 -23.612 1.00 30.33 N1+ ATOM 3891 H ARG A1133 -9.223 19.537 -29.599 1.00 30.19 H ATOM 3892 HA ARG A1133 -9.150 17.666 -27.270 1.00 28.71 H ATOM 3893 HB3 ARG A1133 -11.401 16.856 -28.123 1.00 28.69 H ATOM 3894 HB2 ARG A1133 -11.407 18.118 -29.312 1.00 28.69 H ATOM 3895 HG3 ARG A1133 -12.848 18.588 -27.471 1.00 29.69 H ATOM 3896 HG2 ARG A1133 -11.659 19.851 -27.538 1.00 29.69 H ATOM 3897 HD3 ARG A1133 -10.455 18.302 -25.603 1.00 29.80 H ATOM 3898 HD2 ARG A1133 -12.018 17.554 -25.586 1.00 29.80 H ATOM 3899 HE ARG A1133 -13.129 19.321 -24.780 1.00 30.88 H ATOM 3900 HH12 ARG A1133 -9.923 21.702 -24.135 1.00 29.25 H ATOM 3901 HH11 ARG A1133 -9.733 20.336 -25.209 1.00 29.25 H ATOM 3902 HH22 ARG A1133 -11.950 22.154 -23.148 1.00 30.33 H ATOM 3903 HH21 ARG A1133 -13.297 21.079 -23.419 1.00 30.33 H ATOM 3904 N LEU A1134 -9.055 15.621 -28.811 1.00 26.90 N ATOM 3905 CA LEU A1134 -8.918 14.425 -29.644 1.00 26.48 C ATOM 3906 C LEU A1134 -9.928 14.480 -30.815 1.00 31.07 C ATOM 3907 O LEU A1134 -11.084 14.845 -30.581 1.00 29.22 O ATOM 3908 CB LEU A1134 -9.227 13.190 -28.766 1.00 25.80 C ATOM 3909 CG LEU A1134 -8.165 12.863 -27.694 1.00 28.43 C ATOM 3910 CD1 LEU A1134 -8.717 11.905 -26.614 1.00 27.29 C ATOM 3911 CD2 LEU A1134 -6.854 12.349 -28.325 1.00 31.24 C ATOM 3912 H LEU A1134 -9.416 15.453 -27.879 1.00 26.90 H ATOM 3913 HA LEU A1134 -7.887 14.406 -29.992 1.00 26.48 H ATOM 3914 HB3 LEU A1134 -9.362 12.309 -29.394 1.00 25.80 H ATOM 3915 HB2 LEU A1134 -10.189 13.350 -28.280 1.00 25.80 H ATOM 3916 HG LEU A1134 -7.928 13.796 -27.183 1.00 28.43 H ATOM 3917 HD11 LEU A1134 -8.755 12.402 -25.644 1.00 27.29 H ATOM 3918 HD12 LEU A1134 -9.729 11.570 -26.840 1.00 27.29 H ATOM 3919 HD13 LEU A1134 -8.107 11.011 -26.487 1.00 27.29 H ATOM 3920 HD21 LEU A1134 -5.992 12.885 -27.926 1.00 31.24 H ATOM 3921 HD22 LEU A1134 -6.697 11.289 -28.144 1.00 31.24 H ATOM 3922 HD23 LEU A1134 -6.840 12.471 -29.408 1.00 31.24 H ATOM 3923 N PRO A1135 -9.478 14.161 -32.051 1.00 29.27 N ATOM 3924 CA PRO A1135 -10.320 14.269 -33.257 1.00 29.71 C ATOM 3925 C PRO A1135 -11.484 13.263 -33.276 1.00 33.63 C ATOM 3926 O PRO A1135 -11.495 12.320 -32.486 1.00 33.51 O ATOM 3927 CB PRO A1135 -9.324 14.011 -34.400 1.00 32.38 C ATOM 3928 CG PRO A1135 -8.283 13.086 -33.794 1.00 35.83 C ATOM 3929 CD PRO A1135 -8.159 13.605 -32.368 1.00 30.45 C ATOM 3930 HA PRO A1135 -10.734 15.274 -33.346 1.00 29.71 H ATOM 3931 HB3 PRO A1135 -8.853 14.953 -34.686 1.00 32.38 H ATOM 3932 HB2 PRO A1135 -9.779 13.590 -35.298 1.00 32.38 H ATOM 3933 HG3 PRO A1135 -7.340 13.077 -34.339 1.00 35.83 H ATOM 3934 HG2 PRO A1135 -8.673 12.068 -33.776 1.00 35.83 H ATOM 3935 HD2 PRO A1135 -7.859 12.805 -31.691 1.00 30.45 H ATOM 3936 HD3 PRO A1135 -7.419 14.404 -32.314 1.00 30.45 H ATOM 3937 N ARG A1136 -12.446 13.482 -34.185 1.00 30.63 N ATOM 3938 CA ARG A1136 -13.533 12.542 -34.459 1.00 30.68 C ATOM 3939 C ARG A1136 -12.962 11.261 -35.110 1.00 36.51 C ATOM 3940 O ARG A1136 -12.376 11.380 -36.188 1.00 36.37 O ATOM 3941 CB ARG A1136 -14.560 13.241 -35.376 1.00 28.69 C ATOM 3942 CG ARG A1136 -15.806 12.379 -35.679 1.00 33.51 C ATOM 3943 CD ARG A1136 -16.847 13.056 -36.590 1.00 37.56 C ATOM 3944 NE ARG A1136 -16.358 13.227 -37.972 1.00 52.22 N ATOM 3945 CZ ARG A1136 -16.281 12.291 -38.939 1.00 71.16 C ATOM 3946 NH1 ARG A1136 -15.733 12.618 -40.115 1.00 60.58 N ATOM 3947 NH2 ARG A1136 -16.728 11.038 -38.774 1.00 53.25 N1+ ATOM 3948 H ARG A1136 -12.389 14.291 -34.792 1.00 30.63 H ATOM 3949 HA ARG A1136 -14.039 12.330 -33.523 1.00 30.68 H ATOM 3950 HB3 ARG A1136 -14.076 13.535 -36.309 1.00 28.69 H ATOM 3951 HB2 ARG A1136 -14.883 14.169 -34.905 1.00 28.69 H ATOM 3952 HG3 ARG A1136 -16.278 12.004 -34.771 1.00 33.51 H ATOM 3953 HG2 ARG A1136 -15.454 11.489 -36.199 1.00 33.51 H ATOM 3954 HD3 ARG A1136 -16.998 14.074 -36.231 1.00 37.56 H ATOM 3955 HD2 ARG A1136 -17.825 12.577 -36.532 1.00 37.56 H ATOM 3956 HE ARG A1136 -15.982 14.141 -38.177 1.00 52.22 H ATOM 3957 HH12 ARG A1136 -15.652 11.923 -40.844 1.00 60.58 H ATOM 3958 HH11 ARG A1136 -15.382 13.551 -40.280 1.00 60.58 H ATOM 3959 HH22 ARG A1136 -16.634 10.363 -39.522 1.00 53.25 H ATOM 3960 HH21 ARG A1136 -17.185 10.766 -37.912 1.00 53.25 H ATOM 3961 N PRO A1137 -13.133 10.074 -34.473 1.00 34.19 N ATOM 3962 CA PRO A1137 -12.794 8.777 -35.100 1.00 34.79 C ATOM 3963 C PRO A1137 -13.518 8.551 -36.438 1.00 39.69 C ATOM 3964 O PRO A1137 -14.654 9.000 -36.591 1.00 37.63 O ATOM 3965 CB PRO A1137 -13.235 7.730 -34.059 1.00 35.61 C ATOM 3966 CG PRO A1137 -13.270 8.479 -32.741 1.00 38.50 C ATOM 3967 CD PRO A1137 -13.716 9.872 -33.145 1.00 34.62 C ATOM 3968 HA PRO A1137 -11.711 8.740 -35.234 1.00 34.79 H ATOM 3969 HB3 PRO A1137 -12.572 6.866 -34.029 1.00 35.61 H ATOM 3970 HB2 PRO A1137 -14.230 7.351 -34.286 1.00 35.61 H ATOM 3971 HG3 PRO A1137 -12.259 8.534 -32.343 1.00 38.50 H ATOM 3972 HG2 PRO A1137 -13.904 8.021 -31.984 1.00 38.50 H ATOM 3973 HD2 PRO A1137 -14.802 9.926 -33.221 1.00 34.62 H ATOM 3974 HD3 PRO A1137 -13.386 10.595 -32.401 1.00 34.62 H ATOM 3975 N ASP A1138 -12.853 7.868 -37.383 1.00 39.28 N ATOM 3976 CA ASP A1138 -13.426 7.546 -38.693 1.00 41.69 C ATOM 3977 C ASP A1138 -14.685 6.666 -38.532 1.00 47.14 C ATOM 3978 O ASP A1138 -14.612 5.633 -37.867 1.00 46.83 O ATOM 3979 CB ASP A1138 -12.387 6.871 -39.624 1.00 45.59 C ATOM 3980 CG ASP A1138 -12.841 6.652 -41.080 1.00 68.02 C ATOM 3981 OD1 ASP A1138 -13.557 7.527 -41.620 1.00 70.17 O ATOM 3982 OD2 ASP A1138 -12.365 5.662 -41.676 1.00 78.75 O1- ATOM 3983 H ASP A1138 -11.925 7.516 -37.195 1.00 39.28 H ATOM 3984 HA ASP A1138 -13.719 8.501 -39.135 1.00 41.69 H ATOM 3985 HB3 ASP A1138 -12.074 5.921 -39.186 1.00 45.59 H ATOM 3986 HB2 ASP A1138 -11.481 7.478 -39.648 1.00 45.59 H ATOM 3987 N LYS A1139 -15.800 7.116 -39.131 1.00 45.46 N ATOM 3988 CA LYS A1139 -17.138 6.507 -39.107 1.00 46.10 C ATOM 3989 C LYS A1139 -17.911 6.699 -37.781 1.00 48.03 C ATOM 3990 O LYS A1139 -19.010 6.158 -37.663 1.00 49.27 O ATOM 3991 CB LYS A1139 -17.123 5.027 -39.585 1.00 50.14 C ATOM 3992 CG LYS A1139 -16.482 4.798 -40.972 1.00 69.71 C ATOM 3993 CD LYS A1139 -17.332 5.278 -42.167 1.00 83.93 C ATOM 3994 CE LYS A1139 -18.382 4.259 -42.647 1.00 98.25 C ATOM 3995 NZ LYS A1139 -17.770 3.130 -43.374 1.00107.70 N1+ ATOM 3996 H LYS A1139 -15.734 7.966 -39.674 1.00 45.46 H ATOM 3997 HA LYS A1139 -17.712 7.081 -39.834 1.00 46.10 H ATOM 3998 HB3 LYS A1139 -18.137 4.626 -39.598 1.00 50.14 H ATOM 3999 HB2 LYS A1139 -16.590 4.415 -38.858 1.00 50.14 H ATOM 4000 HG3 LYS A1139 -16.252 3.738 -41.079 1.00 69.71 H ATOM 4001 HG2 LYS A1139 -15.512 5.290 -41.017 1.00 69.71 H ATOM 4002 HD3 LYS A1139 -16.672 5.557 -42.990 1.00 83.93 H ATOM 4003 HD2 LYS A1139 -17.850 6.199 -41.901 1.00 83.93 H ATOM 4004 HE3 LYS A1139 -19.082 4.749 -43.326 1.00 98.25 H ATOM 4005 HE2 LYS A1139 -18.968 3.879 -41.809 1.00 98.25 H ATOM 4006 HZ1 LYS A1139 -17.132 2.641 -42.762 1.00107.70 H ATOM 4007 HZ2 LYS A1139 -18.490 2.494 -43.686 1.00107.70 H ATOM 4008 HZ3 LYS A1139 -17.261 3.480 -44.174 1.00107.70 H ATOM 4009 N CYS A1140 -17.379 7.501 -36.836 1.00 40.64 N ATOM 4010 CA CYS A1140 -18.096 7.964 -35.642 1.00 37.44 C ATOM 4011 C CYS A1140 -19.135 9.023 -36.075 1.00 40.28 C ATOM 4012 O CYS A1140 -18.716 10.015 -36.674 1.00 40.75 O ATOM 4013 CB CYS A1140 -17.119 8.571 -34.608 1.00 35.57 C ATOM 4014 SG CYS A1140 -17.956 9.233 -33.132 1.00 37.88 S ATOM 4015 H CYS A1140 -16.464 7.904 -36.986 1.00 40.64 H ATOM 4016 HA CYS A1140 -18.547 7.094 -35.169 1.00 37.44 H ATOM 4017 HB3 CYS A1140 -16.551 9.391 -35.044 1.00 35.57 H ATOM 4018 HB2 CYS A1140 -16.407 7.814 -34.285 1.00 35.57 H ATOM 4019 HG CYS A1140 -18.601 10.222 -33.759 1.00 37.88 H ATOM 4020 N PRO A1141 -20.442 8.825 -35.776 1.00 34.69 N ATOM 4021 CA PRO A1141 -21.483 9.846 -36.018 1.00 34.83 C ATOM 4022 C PRO A1141 -21.161 11.214 -35.391 1.00 36.98 C ATOM 4023 O PRO A1141 -20.604 11.262 -34.294 1.00 34.16 O ATOM 4024 CB PRO A1141 -22.754 9.238 -35.404 1.00 36.57 C ATOM 4025 CG PRO A1141 -22.512 7.741 -35.389 1.00 40.74 C ATOM 4026 CD PRO A1141 -21.014 7.635 -35.148 1.00 36.09 C ATOM 4027 HA PRO A1141 -21.603 9.941 -37.099 1.00 34.83 H ATOM 4028 HB3 PRO A1141 -23.645 9.500 -35.973 1.00 36.57 H ATOM 4029 HB2 PRO A1141 -22.903 9.592 -34.384 1.00 36.57 H ATOM 4030 HG3 PRO A1141 -22.751 7.330 -36.371 1.00 40.74 H ATOM 4031 HG2 PRO A1141 -23.108 7.209 -34.648 1.00 40.74 H ATOM 4032 HD2 PRO A1141 -20.788 7.650 -34.081 1.00 36.09 H ATOM 4033 HD3 PRO A1141 -20.634 6.709 -35.576 1.00 36.09 H ATOM 4034 N ALA A1142 -21.496 12.292 -36.118 1.00 34.46 N ATOM 4035 CA ALA A1142 -21.237 13.677 -35.716 1.00 34.01 C ATOM 4036 C ALA A1142 -21.858 14.063 -34.363 1.00 35.94 C ATOM 4037 O ALA A1142 -21.196 14.741 -33.582 1.00 33.77 O ATOM 4038 CB ALA A1142 -21.717 14.626 -36.823 1.00 35.94 C ATOM 4039 H ALA A1142 -21.956 12.168 -37.008 1.00 34.46 H ATOM 4040 HA ALA A1142 -20.155 13.788 -35.623 1.00 34.01 H ATOM 4041 HB1 ALA A1142 -21.528 15.667 -36.559 1.00 35.94 H ATOM 4042 HB2 ALA A1142 -21.199 14.427 -37.761 1.00 35.94 H ATOM 4043 HB3 ALA A1142 -22.788 14.519 -37.005 1.00 35.94 H ATOM 4044 N GLU A1143 -23.085 13.585 -34.095 1.00 34.04 N ATOM 4045 CA GLU A1143 -23.816 13.835 -32.853 1.00 34.34 C ATOM 4046 C GLU A1143 -23.305 12.992 -31.664 1.00 35.13 C ATOM 4047 O GLU A1143 -23.390 13.458 -30.528 1.00 31.94 O ATOM 4048 CB GLU A1143 -25.318 13.650 -33.135 1.00 37.10 C ATOM 4049 CG GLU A1143 -26.246 14.080 -31.978 1.00 51.53 C ATOM 4050 CD GLU A1143 -27.740 14.125 -32.340 1.00 70.35 C ATOM 4051 OE1 GLU A1143 -28.153 13.422 -33.291 1.00 77.38 O ATOM 4052 OE2 GLU A1143 -28.460 14.869 -31.638 1.00 51.45 O1- ATOM 4053 H GLU A1143 -23.564 13.026 -34.790 1.00 34.04 H ATOM 4054 HA GLU A1143 -23.664 14.883 -32.589 1.00 34.34 H ATOM 4055 HB3 GLU A1143 -25.505 12.606 -33.385 1.00 37.10 H ATOM 4056 HB2 GLU A1143 -25.577 14.225 -34.027 1.00 37.10 H ATOM 4057 HG3 GLU A1143 -25.936 15.065 -31.626 1.00 51.53 H ATOM 4058 HG2 GLU A1143 -26.129 13.400 -31.134 1.00 51.53 H ATOM 4059 N VAL A1144 -22.731 11.805 -31.940 1.00 32.23 N ATOM 4060 CA VAL A1144 -22.009 10.987 -30.957 1.00 30.46 C ATOM 4061 C VAL A1144 -20.648 11.617 -30.584 1.00 31.37 C ATOM 4062 O VAL A1144 -20.236 11.503 -29.430 1.00 28.93 O ATOM 4063 CB VAL A1144 -21.807 9.523 -31.459 1.00 34.90 C ATOM 4064 CG1 VAL A1144 -20.858 8.650 -30.606 1.00 34.06 C ATOM 4065 CG2 VAL A1144 -23.162 8.803 -31.593 1.00 35.48 C ATOM 4066 H VAL A1144 -22.686 11.488 -32.898 1.00 32.23 H ATOM 4067 HA VAL A1144 -22.610 10.949 -30.046 1.00 30.46 H ATOM 4068 HB VAL A1144 -21.371 9.566 -32.457 1.00 34.90 H ATOM 4069 HG11 VAL A1144 -20.841 7.622 -30.969 1.00 34.06 H ATOM 4070 HG12 VAL A1144 -19.827 9.004 -30.638 1.00 34.06 H ATOM 4071 HG13 VAL A1144 -21.173 8.625 -29.562 1.00 34.06 H ATOM 4072 HG21 VAL A1144 -23.040 7.798 -31.997 1.00 35.48 H ATOM 4073 HG22 VAL A1144 -23.654 8.713 -30.625 1.00 35.48 H ATOM 4074 HG23 VAL A1144 -23.843 9.336 -32.256 1.00 35.48 H ATOM 4075 N TYR A1145 -20.010 12.320 -31.540 1.00 28.72 N ATOM 4076 CA TYR A1145 -18.815 13.130 -31.305 1.00 28.17 C ATOM 4077 C TYR A1145 -19.111 14.402 -30.483 1.00 32.85 C ATOM 4078 O TYR A1145 -18.270 14.789 -29.676 1.00 32.29 O ATOM 4079 CB TYR A1145 -18.111 13.449 -32.643 1.00 29.44 C ATOM 4080 CG TYR A1145 -16.805 14.215 -32.495 1.00 31.74 C ATOM 4081 CD1 TYR A1145 -15.727 13.605 -31.826 1.00 33.16 C ATOM 4082 CD2 TYR A1145 -16.667 15.532 -32.980 1.00 33.69 C ATOM 4083 CE1 TYR A1145 -14.533 14.312 -31.597 1.00 33.08 C ATOM 4084 CE2 TYR A1145 -15.457 16.230 -32.785 1.00 34.55 C ATOM 4085 CZ TYR A1145 -14.395 15.627 -32.079 1.00 36.66 C ATOM 4086 OH TYR A1145 -13.233 16.310 -31.864 1.00 35.20 O ATOM 4087 H TYR A1145 -20.399 12.353 -32.473 1.00 28.72 H ATOM 4088 HA TYR A1145 -18.129 12.519 -30.716 1.00 28.17 H ATOM 4089 HB3 TYR A1145 -18.775 14.007 -33.302 1.00 29.44 H ATOM 4090 HB2 TYR A1145 -17.894 12.516 -33.163 1.00 29.44 H ATOM 4091 HD1 TYR A1145 -15.827 12.586 -31.495 1.00 33.16 H ATOM 4092 HD2 TYR A1145 -17.486 16.012 -33.496 1.00 33.69 H ATOM 4093 HE1 TYR A1145 -13.720 13.833 -31.071 1.00 33.08 H ATOM 4094 HE2 TYR A1145 -15.352 17.237 -33.161 1.00 34.55 H ATOM 4095 HH TYR A1145 -12.591 15.787 -31.372 1.00 35.20 H ATOM 4096 N HIS A1146 -20.303 15.000 -30.665 1.00 31.34 N ATOM 4097 CA HIS A1146 -20.779 16.145 -29.881 1.00 31.80 C ATOM 4098 C HIS A1146 -21.146 15.778 -28.433 1.00 32.90 C ATOM 4099 O HIS A1146 -20.947 16.611 -27.550 1.00 31.97 O ATOM 4100 CB HIS A1146 -21.955 16.843 -30.592 1.00 33.81 C ATOM 4101 CG HIS A1146 -21.650 17.391 -31.965 1.00 37.86 C ATOM 4102 ND1 HIS A1146 -22.623 17.473 -32.968 1.00 40.76 N ATOM 4103 CD2 HIS A1146 -20.458 17.881 -32.464 1.00 39.65 C ATOM 4104 CE1 HIS A1146 -21.991 17.984 -34.016 1.00 40.91 C ATOM 4105 NE2 HIS A1146 -20.706 18.244 -33.776 1.00 40.63 N ATOM 4106 H HIS A1146 -20.940 14.639 -31.363 1.00 31.34 H ATOM 4107 HA HIS A1146 -19.959 16.864 -29.820 1.00 31.80 H ATOM 4108 HB3 HIS A1146 -22.316 17.675 -29.985 1.00 33.81 H ATOM 4109 HB2 HIS A1146 -22.794 16.152 -30.679 1.00 33.81 H ATOM 4110 HD2 HIS A1146 -19.485 17.986 -32.008 1.00 39.65 H ATOM 4111 HE1 HIS A1146 -22.472 18.171 -34.965 1.00 40.91 H ATOM 4112 HE2 HIS A1146 -20.043 18.638 -34.428 1.00 40.63 H ATOM 4113 N LEU A1147 -21.611 14.536 -28.202 1.00 29.07 N ATOM 4114 CA LEU A1147 -21.778 13.940 -26.872 1.00 28.56 C ATOM 4115 C LEU A1147 -20.424 13.756 -26.160 1.00 31.25 C ATOM 4116 O LEU A1147 -20.338 13.997 -24.958 1.00 29.28 O ATOM 4117 CB LEU A1147 -22.590 12.626 -27.011 1.00 29.23 C ATOM 4118 CG LEU A1147 -22.817 11.793 -25.720 1.00 34.50 C ATOM 4119 CD1 LEU A1147 -24.077 10.917 -25.842 1.00 34.68 C ATOM 4120 CD2 LEU A1147 -21.606 10.922 -25.312 1.00 36.84 C ATOM 4121 H LEU A1147 -21.788 13.924 -28.986 1.00 29.07 H ATOM 4122 HA LEU A1147 -22.369 14.632 -26.270 1.00 28.56 H ATOM 4123 HB3 LEU A1147 -22.149 11.983 -27.771 1.00 29.23 H ATOM 4124 HB2 LEU A1147 -23.558 12.917 -27.419 1.00 29.23 H ATOM 4125 HG LEU A1147 -23.013 12.499 -24.911 1.00 34.50 H ATOM 4126 HD11 LEU A1147 -24.525 10.753 -24.862 1.00 34.68 H ATOM 4127 HD12 LEU A1147 -24.837 11.371 -26.478 1.00 34.68 H ATOM 4128 HD13 LEU A1147 -23.850 9.940 -26.269 1.00 34.68 H ATOM 4129 HD21 LEU A1147 -21.884 9.888 -25.107 1.00 36.84 H ATOM 4130 HD22 LEU A1147 -20.841 10.896 -26.088 1.00 36.84 H ATOM 4131 HD23 LEU A1147 -21.140 11.306 -24.405 1.00 36.84 H ATOM 4132 N MET A1148 -19.396 13.361 -26.929 1.00 29.35 N ATOM 4133 CA MET A1148 -18.014 13.182 -26.484 1.00 30.67 C ATOM 4134 C MET A1148 -17.339 14.513 -26.107 1.00 31.09 C ATOM 4135 O MET A1148 -16.638 14.554 -25.099 1.00 28.70 O ATOM 4136 CB MET A1148 -17.240 12.431 -27.592 1.00 34.60 C ATOM 4137 CG MET A1148 -16.460 11.203 -27.102 1.00 40.60 C ATOM 4138 SD MET A1148 -16.144 9.982 -28.405 1.00 46.94 S ATOM 4139 CE MET A1148 -14.969 10.895 -29.430 1.00 42.17 C ATOM 4140 H MET A1148 -19.567 13.172 -27.907 1.00 29.35 H ATOM 4141 HA MET A1148 -18.055 12.563 -25.586 1.00 30.67 H ATOM 4142 HB3 MET A1148 -16.552 13.112 -28.095 1.00 34.60 H ATOM 4143 HB2 MET A1148 -17.922 12.103 -28.375 1.00 34.60 H ATOM 4144 HG3 MET A1148 -17.018 10.688 -26.320 1.00 40.60 H ATOM 4145 HG2 MET A1148 -15.515 11.514 -26.657 1.00 40.60 H ATOM 4146 HE1 MET A1148 -14.862 10.415 -30.402 1.00 42.17 H ATOM 4147 HE2 MET A1148 -15.302 11.918 -29.569 1.00 42.17 H ATOM 4148 HE3 MET A1148 -13.997 10.931 -28.953 1.00 42.17 H ATOM 4149 N LYS A1149 -17.598 15.580 -26.886 1.00 27.88 N ATOM 4150 CA LYS A1149 -17.154 16.946 -26.595 1.00 27.39 C ATOM 4151 C LYS A1149 -17.917 17.609 -25.435 1.00 30.73 C ATOM 4152 O LYS A1149 -17.329 18.451 -24.759 1.00 30.19 O ATOM 4153 CB LYS A1149 -17.207 17.818 -27.865 1.00 30.13 C ATOM 4154 CG LYS A1149 -16.108 17.472 -28.889 1.00 40.57 C ATOM 4155 CD LYS A1149 -15.915 18.539 -29.980 1.00 49.92 C ATOM 4156 CE LYS A1149 -15.173 19.793 -29.484 1.00 55.31 C ATOM 4157 NZ LYS A1149 -14.911 20.746 -30.577 1.00 61.18 N1+ ATOM 4158 H LYS A1149 -18.158 15.460 -27.720 1.00 27.88 H ATOM 4159 HA LYS A1149 -16.112 16.888 -26.279 1.00 27.39 H ATOM 4160 HB3 LYS A1149 -17.079 18.859 -27.571 1.00 30.13 H ATOM 4161 HB2 LYS A1149 -18.193 17.764 -28.329 1.00 30.13 H ATOM 4162 HG3 LYS A1149 -16.348 16.522 -29.364 1.00 40.57 H ATOM 4163 HG2 LYS A1149 -15.157 17.313 -28.382 1.00 40.57 H ATOM 4164 HD3 LYS A1149 -16.890 18.818 -30.383 1.00 49.92 H ATOM 4165 HD2 LYS A1149 -15.361 18.095 -30.805 1.00 49.92 H ATOM 4166 HE3 LYS A1149 -14.215 19.514 -29.049 1.00 55.31 H ATOM 4167 HE2 LYS A1149 -15.743 20.306 -28.710 1.00 55.31 H ATOM 4168 HZ1 LYS A1149 -14.403 21.541 -30.215 1.00 61.18 H ATOM 4169 HZ2 LYS A1149 -14.362 20.296 -31.294 1.00 61.18 H ATOM 4170 HZ3 LYS A1149 -15.788 21.058 -30.970 1.00 61.18 H ATOM 4171 N ASN A1150 -19.178 17.207 -25.195 1.00 27.52 N ATOM 4172 CA ASN A1150 -19.961 17.623 -24.027 1.00 27.53 C ATOM 4173 C ASN A1150 -19.491 16.903 -22.745 1.00 29.61 C ATOM 4174 O ASN A1150 -19.527 17.504 -21.674 1.00 29.79 O ATOM 4175 CB ASN A1150 -21.466 17.425 -24.321 1.00 28.97 C ATOM 4176 CG ASN A1150 -22.410 17.975 -23.243 1.00 41.34 C ATOM 4177 OD1 ASN A1150 -23.302 17.265 -22.787 1.00 34.75 O ATOM 4178 ND2 ASN A1150 -22.230 19.234 -22.833 1.00 35.14 N ATOM 4179 H ASN A1150 -19.616 16.537 -25.812 1.00 27.52 H ATOM 4180 HA ASN A1150 -19.788 18.690 -23.883 1.00 27.53 H ATOM 4181 HB3 ASN A1150 -21.683 16.367 -24.477 1.00 28.97 H ATOM 4182 HB2 ASN A1150 -21.722 17.929 -25.254 1.00 28.97 H ATOM 4183 HD22 ASN A1150 -22.824 19.619 -22.112 1.00 35.14 H ATOM 4184 HD21 ASN A1150 -21.495 19.813 -23.220 1.00 35.14 H ATOM 4185 N CYS A1151 -18.978 15.668 -22.883 1.00 24.02 N ATOM 4186 CA CYS A1151 -18.226 14.967 -21.839 1.00 24.87 C ATOM 4187 C CYS A1151 -16.843 15.601 -21.590 1.00 28.35 C ATOM 4188 O CYS A1151 -16.282 15.363 -20.527 1.00 26.56 O ATOM 4189 CB CYS A1151 -18.067 13.466 -22.147 1.00 25.12 C ATOM 4190 SG CYS A1151 -19.666 12.631 -21.997 1.00 29.56 S ATOM 4191 H CYS A1151 -19.008 15.218 -23.787 1.00 24.02 H ATOM 4192 HA CYS A1151 -18.778 15.060 -20.903 1.00 24.87 H ATOM 4193 HB3 CYS A1151 -17.376 12.992 -21.451 1.00 25.12 H ATOM 4194 HB2 CYS A1151 -17.671 13.297 -23.146 1.00 25.12 H ATOM 4195 HG CYS A1151 -20.221 13.209 -23.068 1.00 29.56 H ATOM 4196 N TRP A1152 -16.334 16.407 -22.539 1.00 24.56 N ATOM 4197 CA TRP A1152 -15.064 17.120 -22.440 1.00 24.31 C ATOM 4198 C TRP A1152 -15.252 18.648 -22.357 1.00 28.86 C ATOM 4199 O TRP A1152 -14.462 19.368 -22.962 1.00 29.11 O ATOM 4200 CB TRP A1152 -14.150 16.769 -23.635 1.00 23.52 C ATOM 4201 CG TRP A1152 -13.769 15.351 -23.905 1.00 23.91 C ATOM 4202 CD1 TRP A1152 -13.464 14.411 -22.983 1.00 26.64 C ATOM 4203 CD2 TRP A1152 -13.493 14.748 -25.205 1.00 24.07 C ATOM 4204 NE1 TRP A1152 -13.028 13.271 -23.624 1.00 25.72 N ATOM 4205 CE2 TRP A1152 -13.021 13.419 -24.996 1.00 26.84 C ATOM 4206 CE3 TRP A1152 -13.581 15.195 -26.545 1.00 25.78 C ATOM 4207 CZ2 TRP A1152 -12.651 12.581 -26.063 1.00 25.92 C ATOM 4208 CZ3 TRP A1152 -13.229 14.360 -27.624 1.00 27.26 C ATOM 4209 CH2 TRP A1152 -12.760 13.055 -27.383 1.00 27.17 C ATOM 4210 H TRP A1152 -16.861 16.563 -23.386 1.00 24.56 H ATOM 4211 HA TRP A1152 -14.549 16.820 -21.531 1.00 24.31 H ATOM 4212 HB3 TRP A1152 -13.195 17.278 -23.504 1.00 23.52 H ATOM 4213 HB2 TRP A1152 -14.587 17.165 -24.551 1.00 23.52 H ATOM 4214 HD1 TRP A1152 -13.530 14.552 -21.914 1.00 26.64 H ATOM 4215 HE1 TRP A1152 -12.743 12.443 -23.118 1.00 25.72 H ATOM 4216 HE3 TRP A1152 -13.922 16.199 -26.746 1.00 25.78 H ATOM 4217 HZ2 TRP A1152 -12.280 11.586 -25.875 1.00 25.92 H ATOM 4218 HZ3 TRP A1152 -13.304 14.727 -28.637 1.00 27.26 H ATOM 4219 HH2 TRP A1152 -12.468 12.425 -28.209 1.00 27.17 H ATOM 4220 N GLU A1153 -16.243 19.166 -21.612 1.00 25.75 N ATOM 4221 CA GLU A1153 -16.288 20.607 -21.306 1.00 26.82 C ATOM 4222 C GLU A1153 -15.165 20.957 -20.317 1.00 30.62 C ATOM 4223 O GLU A1153 -14.982 20.213 -19.355 1.00 26.79 O ATOM 4224 CB GLU A1153 -17.661 21.015 -20.731 1.00 28.38 C ATOM 4225 CG GLU A1153 -18.853 20.780 -21.684 1.00 35.13 C ATOM 4226 CD GLU A1153 -19.078 21.826 -22.787 1.00 54.88 C ATOM 4227 OE1 GLU A1153 -18.283 22.786 -22.903 1.00 51.30 O ATOM 4228 OE2 GLU A1153 -20.072 21.633 -23.523 1.00 50.04 O1- ATOM 4229 H GLU A1153 -16.909 18.570 -21.143 1.00 25.75 H ATOM 4230 HA GLU A1153 -16.126 21.170 -22.227 1.00 26.82 H ATOM 4231 HB3 GLU A1153 -17.632 22.059 -20.419 1.00 28.38 H ATOM 4232 HB2 GLU A1153 -17.847 20.473 -19.807 1.00 28.38 H ATOM 4233 HG3 GLU A1153 -19.767 20.707 -21.096 1.00 35.13 H ATOM 4234 HG2 GLU A1153 -18.736 19.816 -22.172 1.00 35.13 H ATOM 4235 N THR A1154 -14.438 22.064 -20.561 1.00 30.88 N ATOM 4236 CA THR A1154 -13.383 22.571 -19.668 1.00 31.88 C ATOM 4237 C THR A1154 -13.939 22.913 -18.271 1.00 35.93 C ATOM 4238 O THR A1154 -13.325 22.547 -17.269 1.00 35.75 O ATOM 4239 CB THR A1154 -12.699 23.849 -20.233 1.00 43.66 C ATOM 4240 OG1 THR A1154 -12.085 23.555 -21.471 1.00 44.97 O ATOM 4241 CG2 THR A1154 -11.623 24.496 -19.338 1.00 43.44 C ATOM 4242 H THR A1154 -14.652 22.640 -21.363 1.00 30.88 H ATOM 4243 HA THR A1154 -12.631 21.787 -19.556 1.00 31.88 H ATOM 4244 HB THR A1154 -13.464 24.600 -20.437 1.00 43.66 H ATOM 4245 HG1 THR A1154 -11.510 24.290 -21.702 1.00 44.97 H ATOM 4246 HG21 THR A1154 -11.136 25.325 -19.853 1.00 43.44 H ATOM 4247 HG22 THR A1154 -12.041 24.904 -18.417 1.00 43.44 H ATOM 4248 HG23 THR A1154 -10.847 23.781 -19.063 1.00 43.44 H ATOM 4249 N GLU A1155 -15.129 23.536 -18.254 1.00 34.13 N ATOM 4250 CA GLU A1155 -15.937 23.784 -17.069 1.00 35.75 C ATOM 4251 C GLU A1155 -16.604 22.467 -16.627 1.00 37.89 C ATOM 4252 O GLU A1155 -17.335 21.863 -17.414 1.00 35.58 O ATOM 4253 CB GLU A1155 -16.967 24.873 -17.437 1.00 38.82 C ATOM 4254 CG GLU A1155 -17.778 25.452 -16.258 1.00 56.26 C ATOM 4255 CD GLU A1155 -17.038 26.450 -15.348 1.00 89.36 C ATOM 4256 OE1 GLU A1155 -15.839 26.728 -15.577 1.00 94.02 O ATOM 4257 OE2 GLU A1155 -17.704 26.925 -14.403 1.00 89.74 O1- ATOM 4258 H GLU A1155 -15.563 23.781 -19.134 1.00 34.13 H ATOM 4259 HA GLU A1155 -15.283 24.149 -16.275 1.00 35.75 H ATOM 4260 HB3 GLU A1155 -17.672 24.451 -18.153 1.00 38.82 H ATOM 4261 HB2 GLU A1155 -16.479 25.683 -17.982 1.00 38.82 H ATOM 4262 HG3 GLU A1155 -18.176 24.641 -15.648 1.00 56.26 H ATOM 4263 HG2 GLU A1155 -18.645 25.972 -16.663 1.00 56.26 H ATOM 4264 N ALA A1156 -16.319 22.041 -15.385 1.00 35.19 N ATOM 4265 CA ALA A1156 -16.766 20.766 -14.818 1.00 35.22 C ATOM 4266 C ALA A1156 -18.288 20.639 -14.646 1.00 38.77 C ATOM 4267 O ALA A1156 -18.817 19.540 -14.816 1.00 37.90 O ATOM 4268 CB ALA A1156 -16.044 20.526 -13.484 1.00 36.33 C ATOM 4269 H ALA A1156 -15.724 22.604 -14.793 1.00 35.19 H ATOM 4270 HA ALA A1156 -16.466 19.984 -15.513 1.00 35.22 H ATOM 4271 HB1 ALA A1156 -16.329 19.570 -13.043 1.00 36.33 H ATOM 4272 HB2 ALA A1156 -14.962 20.512 -13.622 1.00 36.33 H ATOM 4273 HB3 ALA A1156 -16.273 21.306 -12.757 1.00 36.33 H ATOM 4274 N SER A1157 -18.958 21.763 -14.341 1.00 35.61 N ATOM 4275 CA SER A1157 -20.409 21.866 -14.176 1.00 35.08 C ATOM 4276 C SER A1157 -21.211 21.665 -15.479 1.00 37.46 C ATOM 4277 O SER A1157 -22.359 21.228 -15.400 1.00 37.36 O ATOM 4278 CB SER A1157 -20.732 23.206 -13.483 1.00 40.33 C ATOM 4279 OG SER A1157 -20.526 24.317 -14.335 1.00 48.92 O ATOM 4280 H SER A1157 -18.442 22.623 -14.209 1.00 35.61 H ATOM 4281 HA SER A1157 -20.705 21.071 -13.490 1.00 35.08 H ATOM 4282 HB3 SER A1157 -20.130 23.330 -12.582 1.00 40.33 H ATOM 4283 HB2 SER A1157 -21.774 23.216 -13.163 1.00 40.33 H ATOM 4284 HG SER A1157 -20.612 25.124 -13.820 1.00 48.92 H ATOM 4285 N PHE A1158 -20.600 21.963 -16.641 1.00 32.83 N ATOM 4286 CA PHE A1158 -21.225 21.832 -17.962 1.00 32.10 C ATOM 4287 C PHE A1158 -21.262 20.383 -18.487 1.00 33.92 C ATOM 4288 O PHE A1158 -22.027 20.112 -19.414 1.00 31.85 O ATOM 4289 CB PHE A1158 -20.509 22.753 -18.976 1.00 33.90 C ATOM 4290 CG PHE A1158 -20.583 24.263 -18.780 1.00 37.34 C ATOM 4291 CD1 PHE A1158 -21.365 24.870 -17.770 1.00 41.32 C ATOM 4292 CD2 PHE A1158 -19.866 25.090 -19.671 1.00 39.43 C ATOM 4293 CE1 PHE A1158 -21.392 26.253 -17.648 1.00 43.51 C ATOM 4294 CE2 PHE A1158 -19.906 26.471 -19.532 1.00 43.26 C ATOM 4295 CZ PHE A1158 -20.663 27.049 -18.523 1.00 42.52 C ATOM 4296 H PHE A1158 -19.654 22.318 -16.628 1.00 32.83 H ATOM 4297 HA PHE A1158 -22.266 22.152 -17.891 1.00 32.10 H ATOM 4298 HB3 PHE A1158 -20.891 22.555 -19.979 1.00 33.90 H ATOM 4299 HB2 PHE A1158 -19.452 22.489 -19.006 1.00 33.90 H ATOM 4300 HD1 PHE A1158 -21.944 24.280 -17.075 1.00 41.32 H ATOM 4301 HD2 PHE A1158 -19.276 24.647 -20.460 1.00 39.43 H ATOM 4302 HE1 PHE A1158 -21.982 26.712 -16.868 1.00 43.51 H ATOM 4303 HE2 PHE A1158 -19.346 27.095 -20.212 1.00 43.26 H ATOM 4304 HZ PHE A1158 -20.689 28.124 -18.419 1.00 42.52 H ATOM 4305 N ARG A1159 -20.451 19.483 -17.901 1.00 27.94 N ATOM 4306 CA ARG A1159 -20.401 18.062 -18.254 1.00 27.11 C ATOM 4307 C ARG A1159 -21.635 17.307 -17.701 1.00 29.97 C ATOM 4308 O ARG A1159 -22.017 17.562 -16.558 1.00 28.45 O ATOM 4309 CB ARG A1159 -19.085 17.447 -17.725 1.00 27.28 C ATOM 4310 CG ARG A1159 -17.826 18.123 -18.307 1.00 37.58 C ATOM 4311 CD ARG A1159 -16.511 17.352 -18.102 1.00 43.51 C ATOM 4312 NE ARG A1159 -16.026 17.327 -16.716 1.00 43.50 N ATOM 4313 CZ ARG A1159 -14.971 17.962 -16.172 1.00 45.54 C ATOM 4314 NH1 ARG A1159 -14.222 18.856 -16.830 1.00 36.88 N ATOM 4315 NH2 ARG A1159 -14.648 17.676 -14.910 1.00 30.01 N1+ ATOM 4316 H ARG A1159 -19.858 19.776 -17.138 1.00 27.94 H ATOM 4317 HA ARG A1159 -20.378 18.025 -19.340 1.00 27.11 H ATOM 4318 HB3 ARG A1159 -19.064 16.393 -18.001 1.00 27.28 H ATOM 4319 HB2 ARG A1159 -19.056 17.476 -16.635 1.00 27.28 H ATOM 4320 HG3 ARG A1159 -17.736 19.090 -17.808 1.00 37.58 H ATOM 4321 HG2 ARG A1159 -17.947 18.333 -19.368 1.00 37.58 H ATOM 4322 HD3 ARG A1159 -15.755 17.616 -18.840 1.00 43.51 H ATOM 4323 HD2 ARG A1159 -16.727 16.298 -18.268 1.00 43.51 H ATOM 4324 HE ARG A1159 -16.515 16.670 -16.123 1.00 43.50 H ATOM 4325 HH12 ARG A1159 -13.443 19.305 -16.367 1.00 36.88 H ATOM 4326 HH11 ARG A1159 -14.479 19.148 -17.766 1.00 36.88 H ATOM 4327 HH22 ARG A1159 -13.828 18.092 -14.480 1.00 30.01 H ATOM 4328 HH21 ARG A1159 -15.177 16.993 -14.389 1.00 30.01 H ATOM 4329 N PRO A1160 -22.245 16.402 -18.505 1.00 26.80 N ATOM 4330 CA PRO A1160 -23.417 15.614 -18.080 1.00 26.98 C ATOM 4331 C PRO A1160 -23.023 14.501 -17.094 1.00 32.02 C ATOM 4332 O PRO A1160 -22.041 13.808 -17.342 1.00 31.35 O ATOM 4333 CB PRO A1160 -23.937 15.030 -19.406 1.00 28.34 C ATOM 4334 CG PRO A1160 -22.695 14.855 -20.268 1.00 31.76 C ATOM 4335 CD PRO A1160 -21.826 16.039 -19.861 1.00 27.47 C ATOM 4336 HA PRO A1160 -24.178 16.252 -17.628 1.00 26.98 H ATOM 4337 HB3 PRO A1160 -24.608 15.750 -19.876 1.00 28.34 H ATOM 4338 HB2 PRO A1160 -24.491 14.098 -19.289 1.00 28.34 H ATOM 4339 HG3 PRO A1160 -22.907 14.822 -21.337 1.00 31.76 H ATOM 4340 HG2 PRO A1160 -22.192 13.923 -20.004 1.00 31.76 H ATOM 4341 HD2 PRO A1160 -20.769 15.781 -19.915 1.00 27.47 H ATOM 4342 HD3 PRO A1160 -22.012 16.890 -20.516 1.00 27.47 H ATOM 4343 N THR A1161 -23.789 14.324 -16.007 1.00 29.10 N ATOM 4344 CA THR A1161 -23.603 13.217 -15.056 1.00 28.91 C ATOM 4345 C THR A1161 -23.827 11.838 -15.722 1.00 29.63 C ATOM 4346 O THR A1161 -24.454 11.766 -16.780 1.00 26.66 O ATOM 4347 CB THR A1161 -24.557 13.351 -13.832 1.00 34.86 C ATOM 4348 OG1 THR A1161 -25.865 12.856 -14.057 1.00 34.53 O ATOM 4349 CG2 THR A1161 -24.617 14.763 -13.229 1.00 35.90 C ATOM 4350 H THR A1161 -24.607 14.901 -15.863 1.00 29.10 H ATOM 4351 HA THR A1161 -22.573 13.254 -14.697 1.00 28.91 H ATOM 4352 HB THR A1161 -24.153 12.711 -13.047 1.00 34.86 H ATOM 4353 HG1 THR A1161 -26.454 13.221 -13.388 1.00 34.53 H ATOM 4354 HG21 THR A1161 -25.175 14.766 -12.292 1.00 35.90 H ATOM 4355 HG22 THR A1161 -23.616 15.139 -13.017 1.00 35.90 H ATOM 4356 HG23 THR A1161 -25.103 15.469 -13.903 1.00 35.90 H ATOM 4357 N PHE A1162 -23.334 10.762 -15.088 1.00 26.26 N ATOM 4358 CA PHE A1162 -23.561 9.392 -15.560 1.00 25.89 C ATOM 4359 C PHE A1162 -25.040 8.966 -15.610 1.00 30.07 C ATOM 4360 O PHE A1162 -25.403 8.218 -16.515 1.00 29.53 O ATOM 4361 CB PHE A1162 -22.699 8.388 -14.777 1.00 27.11 C ATOM 4362 CG PHE A1162 -21.246 8.362 -15.201 1.00 25.98 C ATOM 4363 CD1 PHE A1162 -20.898 7.838 -16.459 1.00 26.41 C ATOM 4364 CD2 PHE A1162 -20.245 8.943 -14.402 1.00 27.86 C ATOM 4365 CE1 PHE A1162 -19.573 7.805 -16.862 1.00 26.21 C ATOM 4366 CE2 PHE A1162 -18.922 8.912 -14.824 1.00 29.34 C ATOM 4367 CZ PHE A1162 -18.586 8.329 -16.039 1.00 25.75 C ATOM 4368 H PHE A1162 -22.822 10.869 -14.222 1.00 26.26 H ATOM 4369 HA PHE A1162 -23.226 9.366 -16.598 1.00 25.89 H ATOM 4370 HB3 PHE A1162 -23.079 7.379 -14.930 1.00 27.11 H ATOM 4371 HB2 PHE A1162 -22.764 8.571 -13.705 1.00 27.11 H ATOM 4372 HD1 PHE A1162 -21.672 7.455 -17.102 1.00 26.41 H ATOM 4373 HD2 PHE A1162 -20.507 9.395 -13.461 1.00 27.86 H ATOM 4374 HE1 PHE A1162 -19.316 7.369 -17.815 1.00 26.21 H ATOM 4375 HE2 PHE A1162 -18.153 9.342 -14.206 1.00 29.34 H ATOM 4376 HZ PHE A1162 -17.554 8.293 -16.350 1.00 25.75 H ATOM 4377 N GLU A1163 -25.873 9.500 -14.699 1.00 27.87 N ATOM 4378 CA GLU A1163 -27.330 9.355 -14.724 1.00 28.69 C ATOM 4379 C GLU A1163 -28.021 10.100 -15.882 1.00 33.26 C ATOM 4380 O GLU A1163 -29.087 9.652 -16.303 1.00 32.51 O ATOM 4381 CB GLU A1163 -27.927 9.769 -13.366 1.00 31.37 C ATOM 4382 CG GLU A1163 -27.608 8.760 -12.239 1.00 44.54 C ATOM 4383 CD GLU A1163 -28.145 9.129 -10.846 1.00 68.84 C ATOM 4384 OE1 GLU A1163 -28.711 10.233 -10.679 1.00 67.02 O ATOM 4385 OE2 GLU A1163 -27.958 8.284 -9.944 1.00 62.94 O1- ATOM 4386 H GLU A1163 -25.498 10.099 -13.976 1.00 27.87 H ATOM 4387 HA GLU A1163 -27.551 8.297 -14.871 1.00 28.69 H ATOM 4388 HB3 GLU A1163 -29.009 9.882 -13.452 1.00 31.37 H ATOM 4389 HB2 GLU A1163 -27.540 10.753 -13.095 1.00 31.37 H ATOM 4390 HG3 GLU A1163 -26.530 8.625 -12.158 1.00 44.54 H ATOM 4391 HG2 GLU A1163 -28.013 7.785 -12.512 1.00 44.54 H ATOM 4392 N ASN A1164 -27.417 11.190 -16.392 1.00 30.86 N ATOM 4393 CA ASN A1164 -27.882 11.893 -17.596 1.00 30.74 C ATOM 4394 C ASN A1164 -27.503 11.131 -18.879 1.00 32.00 C ATOM 4395 O ASN A1164 -28.280 11.151 -19.832 1.00 31.36 O ATOM 4396 CB ASN A1164 -27.317 13.336 -17.689 1.00 30.05 C ATOM 4397 CG ASN A1164 -27.571 14.258 -16.490 1.00 41.44 C ATOM 4398 OD1 ASN A1164 -26.746 15.121 -16.200 1.00 30.45 O ATOM 4399 ND2 ASN A1164 -28.701 14.110 -15.795 1.00 30.02 N ATOM 4400 H ASN A1164 -26.552 11.521 -15.984 1.00 30.86 H ATOM 4401 HA ASN A1164 -28.972 11.954 -17.582 1.00 30.74 H ATOM 4402 HB3 ASN A1164 -27.734 13.831 -18.567 1.00 30.05 H ATOM 4403 HB2 ASN A1164 -26.240 13.302 -17.853 1.00 30.05 H ATOM 4404 HD22 ASN A1164 -28.879 14.703 -14.997 1.00 30.02 H ATOM 4405 HD21 ASN A1164 -29.374 13.396 -16.037 1.00 30.02 H ATOM 4406 N LEU A1165 -26.326 10.480 -18.882 1.00 27.37 N ATOM 4407 CA LEU A1165 -25.766 9.760 -20.028 1.00 26.17 C ATOM 4408 C LEU A1165 -26.478 8.435 -20.352 1.00 30.32 C ATOM 4409 O LEU A1165 -26.504 8.068 -21.525 1.00 29.57 O ATOM 4410 CB LEU A1165 -24.259 9.516 -19.791 1.00 24.98 C ATOM 4411 CG LEU A1165 -23.381 10.779 -19.932 1.00 27.47 C ATOM 4412 CD1 LEU A1165 -21.985 10.567 -19.304 1.00 26.17 C ATOM 4413 CD2 LEU A1165 -23.312 11.261 -21.400 1.00 28.90 C ATOM 4414 H LEU A1165 -25.739 10.526 -18.060 1.00 27.37 H ATOM 4415 HA LEU A1165 -25.886 10.396 -20.907 1.00 26.17 H ATOM 4416 HB3 LEU A1165 -23.883 8.764 -20.486 1.00 24.98 H ATOM 4417 HB2 LEU A1165 -24.131 9.083 -18.798 1.00 24.98 H ATOM 4418 HG LEU A1165 -23.853 11.578 -19.359 1.00 27.47 H ATOM 4419 HD11 LEU A1165 -21.169 10.782 -19.992 1.00 26.17 H ATOM 4420 HD12 LEU A1165 -21.850 11.218 -18.439 1.00 26.17 H ATOM 4421 HD13 LEU A1165 -21.842 9.544 -18.956 1.00 26.17 H ATOM 4422 HD21 LEU A1165 -22.294 11.315 -21.782 1.00 28.90 H ATOM 4423 HD22 LEU A1165 -23.857 10.602 -22.076 1.00 28.90 H ATOM 4424 HD23 LEU A1165 -23.747 12.255 -21.501 1.00 28.90 H ATOM 4425 N ILE A1166 -27.040 7.749 -19.341 1.00 27.97 N ATOM 4426 CA ILE A1166 -27.745 6.467 -19.487 1.00 28.85 C ATOM 4427 C ILE A1166 -28.953 6.492 -20.460 1.00 33.75 C ATOM 4428 O ILE A1166 -28.925 5.705 -21.406 1.00 32.47 O ATOM 4429 CB ILE A1166 -28.146 5.868 -18.102 1.00 32.86 C ATOM 4430 CG1 ILE A1166 -26.891 5.392 -17.344 1.00 32.40 C ATOM 4431 CG2 ILE A1166 -29.182 4.719 -18.139 1.00 34.79 C ATOM 4432 CD1 ILE A1166 -27.093 5.273 -15.829 1.00 41.27 C ATOM 4433 H ILE A1166 -26.962 8.109 -18.400 1.00 27.97 H ATOM 4434 HA ILE A1166 -27.016 5.782 -19.927 1.00 28.85 H ATOM 4435 HB ILE A1166 -28.578 6.676 -17.513 1.00 32.86 H ATOM 4436 HG13 ILE A1166 -26.060 6.066 -17.526 1.00 32.40 H ATOM 4437 HG12 ILE A1166 -26.559 4.439 -17.750 1.00 32.40 H ATOM 4438 HG21 ILE A1166 -29.368 4.322 -17.141 1.00 34.79 H ATOM 4439 HG22 ILE A1166 -30.151 5.039 -18.522 1.00 34.79 H ATOM 4440 HG23 ILE A1166 -28.826 3.895 -18.757 1.00 34.79 H ATOM 4441 HD11 ILE A1166 -26.139 5.370 -15.317 1.00 41.27 H ATOM 4442 HD12 ILE A1166 -27.751 6.049 -15.441 1.00 41.27 H ATOM 4443 HD13 ILE A1166 -27.519 4.310 -15.552 1.00 41.27 H ATOM 4444 N PRO A1167 -29.961 7.381 -20.270 1.00 32.13 N ATOM 4445 CA PRO A1167 -31.104 7.471 -21.200 1.00 32.58 C ATOM 4446 C PRO A1167 -30.756 7.999 -22.606 1.00 34.66 C ATOM 4447 O PRO A1167 -31.441 7.626 -23.559 1.00 34.80 O ATOM 4448 CB PRO A1167 -32.110 8.379 -20.476 1.00 35.43 C ATOM 4449 CG PRO A1167 -31.254 9.243 -19.567 1.00 39.58 C ATOM 4450 CD PRO A1167 -30.159 8.280 -19.129 1.00 34.49 C ATOM 4451 HA PRO A1167 -31.550 6.482 -21.322 1.00 32.58 H ATOM 4452 HB3 PRO A1167 -32.779 7.765 -19.871 1.00 35.43 H ATOM 4453 HB2 PRO A1167 -32.734 8.973 -21.146 1.00 35.43 H ATOM 4454 HG3 PRO A1167 -31.803 9.681 -18.734 1.00 39.58 H ATOM 4455 HG2 PRO A1167 -30.817 10.057 -20.147 1.00 39.58 H ATOM 4456 HD2 PRO A1167 -29.269 8.825 -18.831 1.00 34.49 H ATOM 4457 HD3 PRO A1167 -30.503 7.693 -18.277 1.00 34.49 H ATOM 4458 N ILE A1168 -29.692 8.816 -22.719 1.00 31.51 N ATOM 4459 CA ILE A1168 -29.174 9.311 -23.996 1.00 32.13 C ATOM 4460 C ILE A1168 -28.515 8.176 -24.809 1.00 34.20 C ATOM 4461 O ILE A1168 -28.819 8.042 -25.992 1.00 33.26 O ATOM 4462 CB ILE A1168 -28.157 10.480 -23.813 1.00 35.61 C ATOM 4463 CG1 ILE A1168 -28.818 11.695 -23.122 1.00 36.57 C ATOM 4464 CG2 ILE A1168 -27.491 10.936 -25.133 1.00 37.22 C ATOM 4465 CD1 ILE A1168 -27.816 12.756 -22.635 1.00 41.21 C ATOM 4466 H ILE A1168 -29.178 9.087 -21.893 1.00 31.51 H ATOM 4467 HA ILE A1168 -30.019 9.689 -24.577 1.00 32.13 H ATOM 4468 HB ILE A1168 -27.363 10.125 -23.154 1.00 35.61 H ATOM 4469 HG13 ILE A1168 -29.409 11.372 -22.266 1.00 36.57 H ATOM 4470 HG12 ILE A1168 -29.529 12.160 -23.806 1.00 36.57 H ATOM 4471 HG21 ILE A1168 -26.825 11.783 -24.973 1.00 37.22 H ATOM 4472 HG22 ILE A1168 -26.886 10.153 -25.588 1.00 37.22 H ATOM 4473 HG23 ILE A1168 -28.240 11.243 -25.864 1.00 37.22 H ATOM 4474 HD11 ILE A1168 -28.223 13.321 -21.796 1.00 41.21 H ATOM 4475 HD12 ILE A1168 -26.881 12.305 -22.300 1.00 41.21 H ATOM 4476 HD13 ILE A1168 -27.581 13.469 -23.424 1.00 41.21 H ATOM 4477 N LEU A1169 -27.664 7.367 -24.155 1.00 29.74 N ATOM 4478 CA LEU A1169 -26.967 6.225 -24.756 1.00 29.80 C ATOM 4479 C LEU A1169 -27.885 5.031 -25.075 1.00 35.11 C ATOM 4480 O LEU A1169 -27.557 4.280 -25.991 1.00 36.14 O ATOM 4481 CB LEU A1169 -25.777 5.814 -23.865 1.00 29.09 C ATOM 4482 CG LEU A1169 -24.581 6.789 -23.960 1.00 32.75 C ATOM 4483 CD1 LEU A1169 -23.587 6.570 -22.808 1.00 32.66 C ATOM 4484 CD2 LEU A1169 -23.883 6.727 -25.337 1.00 36.03 C ATOM 4485 H LEU A1169 -27.456 7.545 -23.180 1.00 29.74 H ATOM 4486 HA LEU A1169 -26.565 6.559 -25.711 1.00 29.80 H ATOM 4487 HB3 LEU A1169 -25.421 4.823 -24.144 1.00 29.09 H ATOM 4488 HB2 LEU A1169 -26.125 5.721 -22.835 1.00 29.09 H ATOM 4489 HG LEU A1169 -24.969 7.801 -23.834 1.00 32.75 H ATOM 4490 HD11 LEU A1169 -23.208 7.523 -22.440 1.00 32.66 H ATOM 4491 HD12 LEU A1169 -24.047 6.060 -21.962 1.00 32.66 H ATOM 4492 HD13 LEU A1169 -22.731 5.971 -23.114 1.00 32.66 H ATOM 4493 HD21 LEU A1169 -22.797 6.684 -25.255 1.00 36.03 H ATOM 4494 HD22 LEU A1169 -24.195 5.856 -25.915 1.00 36.03 H ATOM 4495 HD23 LEU A1169 -24.124 7.609 -25.930 1.00 36.03 H ATOM 4496 N LYS A1170 -29.028 4.905 -24.376 1.00 32.29 N ATOM 4497 CA LYS A1170 -30.116 3.981 -24.717 1.00 33.11 C ATOM 4498 C LYS A1170 -30.825 4.360 -26.028 1.00 37.39 C ATOM 4499 O LYS A1170 -31.078 3.477 -26.846 1.00 37.67 O ATOM 4500 CB LYS A1170 -31.124 3.899 -23.551 1.00 37.22 C ATOM 4501 CG LYS A1170 -30.641 3.002 -22.404 1.00 43.25 C ATOM 4502 CD LYS A1170 -31.551 3.030 -21.170 1.00 49.41 C ATOM 4503 CE LYS A1170 -31.093 2.016 -20.108 1.00 57.38 C ATOM 4504 NZ LYS A1170 -31.915 2.081 -18.888 1.00 64.71 N1+ ATOM 4505 H LYS A1170 -29.207 5.536 -23.606 1.00 32.29 H ATOM 4506 HA LYS A1170 -29.678 2.992 -24.863 1.00 33.11 H ATOM 4507 HB3 LYS A1170 -32.069 3.483 -23.907 1.00 37.22 H ATOM 4508 HB2 LYS A1170 -31.357 4.899 -23.187 1.00 37.22 H ATOM 4509 HG3 LYS A1170 -29.633 3.290 -22.111 1.00 43.25 H ATOM 4510 HG2 LYS A1170 -30.573 1.978 -22.773 1.00 43.25 H ATOM 4511 HD3 LYS A1170 -32.578 2.820 -21.472 1.00 49.41 H ATOM 4512 HD2 LYS A1170 -31.550 4.038 -20.751 1.00 49.41 H ATOM 4513 HE3 LYS A1170 -30.052 2.195 -19.835 1.00 57.38 H ATOM 4514 HE2 LYS A1170 -31.143 1.003 -20.508 1.00 57.38 H ATOM 4515 HZ1 LYS A1170 -32.877 1.875 -19.115 1.00 64.71 H ATOM 4516 HZ2 LYS A1170 -31.574 1.402 -18.221 1.00 64.71 H ATOM 4517 HZ3 LYS A1170 -31.852 3.005 -18.484 1.00 64.71 H ATOM 4518 N THR A1171 -31.102 5.663 -26.212 1.00 34.80 N ATOM 4519 CA THR A1171 -31.738 6.219 -27.411 1.00 35.33 C ATOM 4520 C THR A1171 -30.800 6.208 -28.638 1.00 39.05 C ATOM 4521 O THR A1171 -31.260 5.941 -29.748 1.00 39.67 O ATOM 4522 CB THR A1171 -32.220 7.675 -27.167 1.00 44.81 C ATOM 4523 OG1 THR A1171 -33.137 7.683 -26.089 1.00 44.59 O ATOM 4524 CG2 THR A1171 -32.908 8.359 -28.363 1.00 42.98 C ATOM 4525 H THR A1171 -30.845 6.329 -25.497 1.00 34.80 H ATOM 4526 HA THR A1171 -32.610 5.604 -27.647 1.00 35.33 H ATOM 4527 HB THR A1171 -31.373 8.291 -26.863 1.00 44.81 H ATOM 4528 HG1 THR A1171 -32.663 7.467 -25.282 1.00 44.59 H ATOM 4529 HG21 THR A1171 -33.310 9.332 -28.077 1.00 42.98 H ATOM 4530 HG22 THR A1171 -32.218 8.533 -29.189 1.00 42.98 H ATOM 4531 HG23 THR A1171 -33.736 7.757 -28.739 1.00 42.98 H ATOM 4532 N VAL A1172 -29.501 6.461 -28.407 1.00 34.64 N ATOM 4533 CA VAL A1172 -28.437 6.393 -29.409 1.00 35.04 C ATOM 4534 C VAL A1172 -28.142 4.943 -29.854 1.00 37.21 C ATOM 4535 O VAL A1172 -27.962 4.722 -31.050 1.00 35.63 O ATOM 4536 CB VAL A1172 -27.153 7.107 -28.887 1.00 39.11 C ATOM 4537 CG1 VAL A1172 -25.823 6.718 -29.557 1.00 39.01 C ATOM 4538 CG2 VAL A1172 -27.323 8.636 -28.939 1.00 39.06 C ATOM 4539 H VAL A1172 -29.207 6.702 -27.470 1.00 34.64 H ATOM 4540 HA VAL A1172 -28.785 6.931 -30.293 1.00 35.04 H ATOM 4541 HB VAL A1172 -27.044 6.843 -27.837 1.00 39.11 H ATOM 4542 HG11 VAL A1172 -25.005 7.334 -29.184 1.00 39.01 H ATOM 4543 HG12 VAL A1172 -25.555 5.686 -29.335 1.00 39.01 H ATOM 4544 HG13 VAL A1172 -25.867 6.841 -30.639 1.00 39.01 H ATOM 4545 HG21 VAL A1172 -26.478 9.144 -28.472 1.00 39.06 H ATOM 4546 HG22 VAL A1172 -27.395 8.990 -29.967 1.00 39.06 H ATOM 4547 HG23 VAL A1172 -28.223 8.960 -28.417 1.00 39.06 H ATOM 4548 N HIS A1173 -28.170 3.976 -28.917 1.00 33.86 N ATOM 4549 CA HIS A1173 -28.096 2.540 -29.214 1.00 34.98 C ATOM 4550 C HIS A1173 -29.277 2.060 -30.084 1.00 39.49 C ATOM 4551 O HIS A1173 -29.043 1.349 -31.059 1.00 38.50 O ATOM 4552 CB HIS A1173 -27.984 1.732 -27.901 1.00 35.81 C ATOM 4553 CG HIS A1173 -28.090 0.234 -28.062 1.00 39.76 C ATOM 4554 ND1 HIS A1173 -27.102 -0.535 -28.649 1.00 41.19 N ATOM 4555 CD2 HIS A1173 -29.100 -0.647 -27.743 1.00 42.70 C ATOM 4556 CE1 HIS A1173 -27.538 -1.797 -28.663 1.00 41.61 C ATOM 4557 NE2 HIS A1173 -28.744 -1.941 -28.129 1.00 43.01 N ATOM 4558 H HIS A1173 -28.305 4.222 -27.946 1.00 33.86 H ATOM 4559 HA HIS A1173 -27.183 2.367 -29.788 1.00 34.98 H ATOM 4560 HB3 HIS A1173 -28.760 2.045 -27.201 1.00 35.81 H ATOM 4561 HB2 HIS A1173 -27.032 1.952 -27.414 1.00 35.81 H ATOM 4562 HD1 HIS A1173 -26.205 -0.215 -28.995 1.00 41.19 H ATOM 4563 HD2 HIS A1173 -30.059 -0.445 -27.288 1.00 42.70 H ATOM 4564 HE1 HIS A1173 -26.961 -2.619 -29.062 1.00 41.61 H ATOM 4565 N GLU A1174 -30.502 2.495 -29.734 1.00 37.68 N ATOM 4566 CA GLU A1174 -31.744 2.256 -30.476 1.00 39.70 C ATOM 4567 C GLU A1174 -31.727 2.760 -31.930 1.00 42.94 C ATOM 4568 O GLU A1174 -32.312 2.102 -32.790 1.00 44.72 O ATOM 4569 CB GLU A1174 -32.935 2.873 -29.702 1.00 42.32 C ATOM 4570 CG GLU A1174 -33.555 1.928 -28.651 1.00 60.01 C ATOM 4571 CD GLU A1174 -34.443 0.805 -29.219 1.00 92.87 C ATOM 4572 OE1 GLU A1174 -34.832 0.871 -30.407 1.00 94.43 O ATOM 4573 OE2 GLU A1174 -34.715 -0.138 -28.446 1.00 90.73 O1- ATOM 4574 H GLU A1174 -30.599 3.061 -28.901 1.00 37.68 H ATOM 4575 HA GLU A1174 -31.882 1.176 -30.525 1.00 39.70 H ATOM 4576 HB3 GLU A1174 -33.706 3.247 -30.379 1.00 42.32 H ATOM 4577 HB2 GLU A1174 -32.594 3.762 -29.175 1.00 42.32 H ATOM 4578 HG3 GLU A1174 -34.171 2.518 -27.971 1.00 60.01 H ATOM 4579 HG2 GLU A1174 -32.763 1.493 -28.038 1.00 60.01 H ATOM 4580 N LYS A1175 -31.050 3.893 -32.178 1.00 37.93 N ATOM 4581 CA LYS A1175 -30.917 4.504 -33.500 1.00 37.53 C ATOM 4582 C LYS A1175 -30.053 3.674 -34.468 1.00 41.18 C ATOM 4583 O LYS A1175 -30.453 3.507 -35.620 1.00 39.68 O ATOM 4584 CB LYS A1175 -30.402 5.952 -33.337 1.00 38.66 C ATOM 4585 CG LYS A1175 -30.187 6.714 -34.659 1.00 48.52 C ATOM 4586 CD LYS A1175 -29.780 8.180 -34.438 1.00 57.93 C ATOM 4587 CE LYS A1175 -29.465 8.944 -35.737 1.00 71.38 C ATOM 4588 NZ LYS A1175 -30.655 9.138 -36.585 1.00 86.87 N1+ ATOM 4589 H LYS A1175 -30.605 4.381 -31.413 1.00 37.93 H ATOM 4590 HA LYS A1175 -31.920 4.562 -33.929 1.00 37.53 H ATOM 4591 HB3 LYS A1175 -29.462 5.948 -32.786 1.00 38.66 H ATOM 4592 HB2 LYS A1175 -31.109 6.507 -32.720 1.00 38.66 H ATOM 4593 HG3 LYS A1175 -31.100 6.660 -35.253 1.00 48.52 H ATOM 4594 HG2 LYS A1175 -29.406 6.228 -35.246 1.00 48.52 H ATOM 4595 HD3 LYS A1175 -28.898 8.205 -33.797 1.00 57.93 H ATOM 4596 HD2 LYS A1175 -30.561 8.700 -33.881 1.00 57.93 H ATOM 4597 HE3 LYS A1175 -28.705 8.416 -36.313 1.00 71.38 H ATOM 4598 HE2 LYS A1175 -29.056 9.926 -35.497 1.00 71.38 H ATOM 4599 HZ1 LYS A1175 -31.353 9.660 -36.073 1.00 86.87 H ATOM 4600 HZ2 LYS A1175 -30.398 9.649 -37.418 1.00 86.87 H ATOM 4601 HZ3 LYS A1175 -31.032 8.238 -36.845 1.00 86.87 H ATOM 4602 N TYR A1176 -28.889 3.197 -33.995 1.00 37.88 N ATOM 4603 CA TYR A1176 -27.868 2.567 -34.838 1.00 38.84 C ATOM 4604 C TYR A1176 -27.921 1.028 -34.865 1.00 43.27 C ATOM 4605 O TYR A1176 -27.210 0.447 -35.688 1.00 45.60 O ATOM 4606 CB TYR A1176 -26.473 3.100 -34.436 1.00 39.66 C ATOM 4607 CG TYR A1176 -26.302 4.594 -34.682 1.00 42.14 C ATOM 4608 CD1 TYR A1176 -26.315 5.101 -35.999 1.00 44.87 C ATOM 4609 CD2 TYR A1176 -26.162 5.487 -33.601 1.00 42.46 C ATOM 4610 CE1 TYR A1176 -26.229 6.489 -36.227 1.00 44.19 C ATOM 4611 CE2 TYR A1176 -26.089 6.875 -33.825 1.00 43.50 C ATOM 4612 CZ TYR A1176 -26.135 7.378 -35.138 1.00 49.64 C ATOM 4613 OH TYR A1176 -26.106 8.725 -35.354 1.00 54.89 O ATOM 4614 H TYR A1176 -28.635 3.369 -33.031 1.00 37.88 H ATOM 4615 HA TYR A1176 -28.033 2.870 -35.874 1.00 38.84 H ATOM 4616 HB3 TYR A1176 -25.694 2.591 -35.006 1.00 39.66 H ATOM 4617 HB2 TYR A1176 -26.271 2.873 -33.387 1.00 39.66 H ATOM 4618 HD1 TYR A1176 -26.412 4.428 -36.839 1.00 44.87 H ATOM 4619 HD2 TYR A1176 -26.126 5.113 -32.593 1.00 42.46 H ATOM 4620 HE1 TYR A1176 -26.257 6.870 -37.237 1.00 44.19 H ATOM 4621 HE2 TYR A1176 -26.007 7.551 -32.986 1.00 43.50 H ATOM 4622 HH TYR A1176 -26.186 9.238 -34.543 1.00 54.89 H ATOM 4623 N ARG A1177 -28.744 0.383 -34.014 1.00 37.76 N ATOM 4624 CA ARG A1177 -28.935 -1.075 -34.023 1.00 53.07 C ATOM 4625 C ARG A1177 -29.798 -1.553 -35.209 1.00 74.57 C ATOM 4626 O ARG A1177 -30.502 -0.752 -35.827 1.00 46.90 O ATOM 4627 CB ARG A1177 -29.496 -1.560 -32.664 1.00 52.87 C ATOM 4628 CG ARG A1177 -30.982 -1.254 -32.399 1.00 64.39 C ATOM 4629 CD ARG A1177 -31.514 -1.954 -31.138 1.00 74.69 C ATOM 4630 NE ARG A1177 -32.978 -1.851 -31.034 1.00 82.78 N ATOM 4631 CZ ARG A1177 -33.907 -2.569 -31.694 1.00 98.29 C ATOM 4632 NH1 ARG A1177 -33.589 -3.553 -32.550 1.00 84.15 N ATOM 4633 NH2 ARG A1177 -35.199 -2.283 -31.493 1.00 87.75 N1+ ATOM 4634 H ARG A1177 -29.299 0.909 -33.353 1.00 37.76 H ATOM 4635 HA ARG A1177 -27.950 -1.532 -34.140 1.00 53.07 H ATOM 4636 HB3 ARG A1177 -28.888 -1.173 -31.846 1.00 52.87 H ATOM 4637 HB2 ARG A1177 -29.369 -2.643 -32.620 1.00 52.87 H ATOM 4638 HG3 ARG A1177 -31.630 -1.450 -33.253 1.00 64.39 H ATOM 4639 HG2 ARG A1177 -31.028 -0.179 -32.238 1.00 64.39 H ATOM 4640 HD3 ARG A1177 -31.155 -1.396 -30.273 1.00 74.69 H ATOM 4641 HD2 ARG A1177 -31.139 -2.971 -31.017 1.00 74.69 H ATOM 4642 HE ARG A1177 -33.319 -1.100 -30.445 1.00 82.78 H ATOM 4643 HH12 ARG A1177 -34.318 -4.055 -33.040 1.00 84.15 H ATOM 4644 HH11 ARG A1177 -32.621 -3.779 -32.721 1.00 84.15 H ATOM 4645 HH22 ARG A1177 -35.921 -2.787 -31.991 1.00 87.75 H ATOM 4646 HH21 ARG A1177 -35.454 -1.517 -30.880 1.00 87.75 H HETATM 4647 N NME A1178 -29.749 -2.869 -35.465 1.00 0.00 N HETATM 4648 C NME A1178 -30.535 -3.522 -36.502 1.00 0.00 C HETATM 4649 H NME A1178 -29.154 -3.459 -34.899 1.00 0.00 H HETATM 4650 H1 NME A1178 -30.743 -2.862 -37.345 1.00 0.00 H HETATM 4651 H2 NME A1178 -29.994 -4.388 -36.884 1.00 0.00 H HETATM 4652 H3 NME A1178 -31.485 -3.868 -36.092 1.00 0.00 H TER 4653 NME A1178 HETATM 4654 O HOH A1301 -7.805 13.717 -21.733 1.00 23.87 O HETATM 4655 H1 HOH A1301 -7.442 12.805 -21.938 1.00 23.87 H HETATM 4656 H2 HOH A1301 -7.037 14.314 -21.478 1.00 23.87 H HETATM 4657 O HOH A1302 -7.300 4.134 -29.382 1.00 26.50 O HETATM 4658 H1 HOH A1302 -6.564 3.946 -30.038 1.00 26.50 H HETATM 4659 H2 HOH A1302 -8.155 4.275 -29.890 1.00 26.50 H HETATM 4660 O HOH A1303 -21.765 11.544 -12.438 1.00 28.48 O HETATM 4661 H1 HOH A1303 -21.483 12.499 -12.298 1.00 28.48 H HETATM 4662 H2 HOH A1303 -21.181 10.951 -11.877 1.00 28.48 H HETATM 4663 O HOH A1304 -9.035 2.704 -10.281 1.00 29.39 O HETATM 4664 H1 HOH A1304 -9.409 1.932 -10.803 1.00 29.39 H HETATM 4665 H2 HOH A1304 -9.652 3.492 -10.355 1.00 29.39 H HETATM 4666 O HOH A1305 -10.327 13.333 -14.896 1.00 24.85 O HETATM 4667 H1 HOH A1305 -11.176 12.866 -15.157 1.00 24.85 H HETATM 4668 H2 HOH A1305 -10.176 13.221 -13.913 1.00 24.85 H HETATM 4669 O HOH A1306 -11.177 8.182 -14.397 1.00 26.19 O HETATM 4670 H1 HOH A1306 -11.137 8.958 -15.033 1.00 26.19 H HETATM 4671 H2 HOH A1306 -11.960 8.307 -13.778 1.00 26.19 H HETATM 4672 O HOH A1307 -5.575 15.209 -20.665 1.00 23.28 O HETATM 4673 H1 HOH A1307 -6.230 15.538 -19.979 1.00 23.28 H HETATM 4674 H2 HOH A1307 -4.863 14.683 -20.193 1.00 23.28 H HETATM 4675 O HOH A1310 -7.035 2.198 -22.168 1.00 28.39 O HETATM 4676 H1 HOH A1310 -7.249 2.734 -22.991 1.00 28.39 H HETATM 4677 H2 HOH A1310 -6.202 2.562 -21.741 1.00 28.39 H HETATM 4678 O HOH A1319 -24.975 8.619 -9.410 1.00 28.29 O HETATM 4679 H1 HOH A1319 -25.977 8.575 -9.470 1.00 28.29 H HETATM 4680 H2 HOH A1319 -24.615 7.682 -9.428 1.00 28.29 H HETATM 4681 O HOH A1322 9.260 15.797 -22.620 1.00 33.09 O HETATM 4682 H1 HOH A1322 9.238 15.995 -21.638 1.00 33.09 H HETATM 4683 H2 HOH A1322 9.718 14.919 -22.770 1.00 33.09 H HETATM 4684 O HOH A1323 -15.175 20.060 -25.940 1.00 37.91 O HETATM 4685 H1 HOH A1323 -15.823 19.549 -25.369 1.00 37.91 H HETATM 4686 H2 HOH A1323 -15.622 20.901 -26.256 1.00 37.91 H HETATM 4687 O HOH A1325 -7.181 -8.809 -21.143 1.00 38.47 O HETATM 4688 H1 HOH A1325 -6.991 -9.743 -20.831 1.00 38.47 H HETATM 4689 H2 HOH A1325 -6.455 -8.515 -21.774 1.00 38.47 H HETATM 4690 O HOH A1326 7.389 15.381 -18.526 1.00 32.26 O HETATM 4691 H1 HOH A1326 8.315 15.733 -18.681 1.00 32.26 H HETATM 4692 H2 HOH A1326 6.915 15.335 -19.410 1.00 32.26 H HETATM 4693 O HOH A1329 -19.714 -6.468 -9.012 1.00 36.73 O HETATM 4694 H1 HOH A1329 -19.884 -6.507 -10.000 1.00 36.73 H HETATM 4695 H2 HOH A1329 -18.743 -6.288 -8.854 1.00 36.73 H HETATM 4696 O HOH A1330 4.141 19.654 -16.124 1.00 36.06 O HETATM 4697 H1 HOH A1330 5.109 19.392 -16.168 1.00 36.06 H HETATM 4698 H2 HOH A1330 3.830 19.606 -15.174 1.00 36.06 H HETATM 4699 O HOH A1333 4.982 16.327 -16.962 1.00 30.05 O HETATM 4700 H1 HOH A1333 5.483 17.156 -16.704 1.00 30.05 H HETATM 4701 H2 HOH A1333 5.635 15.674 -17.353 1.00 30.05 H HETATM 4702 O HOH A1339 -8.401 9.401 -34.311 1.00 35.17 O HETATM 4703 H1 HOH A1339 -8.558 8.457 -34.614 1.00 35.17 H HETATM 4704 H2 HOH A1339 -8.352 9.426 -33.310 1.00 35.17 H HETATM 4705 O HOH A1344 -1.246 -9.880 -2.385 1.00 46.63 O HETATM 4706 H1 HOH A1344 -2.115 -9.784 -1.894 1.00 46.63 H HETATM 4707 H2 HOH A1344 -0.512 -10.016 -1.717 1.00 46.63 H HETATM 4708 O HOH A1346 -2.546 14.870 -33.057 1.00 40.94 O HETATM 4709 H1 HOH A1346 -1.902 14.222 -33.475 1.00 40.94 H HETATM 4710 H2 HOH A1346 -2.400 14.877 -32.065 1.00 40.94 H HETATM 4711 O HOH A1349 -15.113 -20.319 -14.132 1.00 44.85 O HETATM 4712 H1 HOH A1349 -15.777 -20.591 -13.428 1.00 44.85 H HETATM 4713 H2 HOH A1349 -15.496 -19.565 -14.665 1.00 44.85 H HETATM 4714 O HOH A1350 -21.241 18.275 -13.756 1.00 31.90 O HETATM 4715 H1 HOH A1350 -21.949 18.493 -14.431 1.00 31.90 H HETATM 4716 H2 HOH A1350 -20.384 18.717 -14.034 1.00 31.90 H HETATM 4717 O HOH A1352 -12.770 -28.593 -8.238 1.00 61.97 O HETATM 4718 H1 HOH A1352 -11.940 -28.665 -8.798 1.00 61.97 H HETATM 4719 H2 HOH A1352 -13.089 -29.522 -8.039 1.00 61.97 H HETATM 4720 O HOH A1353 0.753 -1.961 -23.720 1.00 67.38 O HETATM 4721 H1 HOH A1353 1.280 -1.741 -22.898 1.00 67.38 H HETATM 4722 H2 HOH A1353 1.234 -2.673 -24.233 1.00 67.38 H HETATM 4723 O HOH A1356 -12.183 -25.973 -15.343 1.00 59.40 O HETATM 4724 H1 HOH A1356 -12.353 -25.498 -14.476 1.00 59.40 H HETATM 4725 H2 HOH A1356 -11.675 -26.817 -15.157 1.00 59.40 H HETATM 4726 O HOH A1360 0.186 23.081 -25.812 1.00 35.26 O HETATM 4727 H1 HOH A1360 0.760 23.841 -25.494 1.00 35.26 H HETATM 4728 H2 HOH A1360 -0.066 22.506 -25.030 1.00 35.26 H HETATM 4729 O HOH A1361 6.492 16.072 -23.950 1.00 37.72 O HETATM 4730 H1 HOH A1361 7.475 15.916 -23.823 1.00 37.72 H HETATM 4731 H2 HOH A1361 6.255 15.954 -24.918 1.00 37.72 H HETATM 4732 O HOH A1362 -12.299 4.648 -36.322 1.00 42.24 O HETATM 4733 H1 HOH A1362 -13.007 4.928 -36.975 1.00 42.24 H HETATM 4734 H2 HOH A1362 -12.726 4.127 -35.581 1.00 42.24 H HETATM 4735 O HOH A1364 -16.446 24.494 -21.075 1.00 34.81 O HETATM 4736 H1 HOH A1364 -17.058 23.972 -21.679 1.00 34.81 H HETATM 4737 H2 HOH A1364 -16.735 25.452 -21.068 1.00 34.81 H HETATM 4738 O HOH A1366 -15.941 9.353 -41.405 1.00 52.63 O HETATM 4739 H1 HOH A1366 -15.091 8.827 -41.524 1.00 52.63 H HETATM 4740 H2 HOH A1366 -16.453 9.327 -42.264 1.00 52.63 H HETATM 4741 O HOH A1367 -16.053 4.806 -35.554 1.00 51.77 O HETATM 4742 H1 HOH A1367 -15.366 4.407 -34.941 1.00 51.77 H HETATM 4743 H2 HOH A1367 -15.611 5.066 -36.416 1.00 51.77 H HETATM 4744 O HOH A1374 -11.258 22.843 -15.256 1.00 45.38 O HETATM 4745 H1 HOH A1374 -11.414 21.917 -14.904 1.00 45.38 H HETATM 4746 H2 HOH A1374 -11.922 23.020 -15.986 1.00 45.38 H HETATM 4747 O HOH A1379 1.460 25.653 -25.134 1.00 53.63 O HETATM 4748 H1 HOH A1379 1.558 25.650 -24.132 1.00 53.63 H HETATM 4749 H2 HOH A1379 1.812 26.519 -25.489 1.00 53.63 H HETATM 4750 O HOH A1381 -10.785 -4.363 -35.468 1.00 52.69 O HETATM 4751 H1 HOH A1381 -10.882 -4.287 -34.472 1.00 52.69 H HETATM 4752 H2 HOH A1381 -9.819 -4.506 -35.690 1.00 52.69 H HETATM 4753 O HOH A1382 11.586 21.266 -17.552 1.00 44.12 O HETATM 4754 H1 HOH A1382 12.072 22.022 -17.992 1.00 44.12 H HETATM 4755 H2 HOH A1382 11.771 21.284 -16.568 1.00 44.12 H HETATM 4756 O HOH A1388 -20.268 13.044 -1.959 1.00 51.68 O HETATM 4757 H1 HOH A1388 -19.953 13.996 -1.925 1.00 51.68 H HETATM 4758 H2 HOH A1388 -19.556 12.459 -1.568 1.00 51.68 H HETATM 4759 O HOH A1394 -8.203 1.938 -4.105 1.00 43.33 O HETATM 4760 H1 HOH A1394 -8.463 1.333 -4.861 1.00 43.33 H HETATM 4761 H2 HOH A1394 -8.767 2.767 -4.151 1.00 43.33 H HETATM 4762 O HOH A1396 -27.765 -2.906 -18.989 1.00 50.68 O HETATM 4763 H1 HOH A1396 -27.731 -1.905 -18.908 1.00 50.68 H HETATM 4764 H2 HOH A1396 -27.014 -3.284 -18.440 1.00 50.68 H HETATM 4765 O HOH A1397 -30.874 11.872 -15.139 1.00 52.33 O HETATM 4766 H1 HOH A1397 -30.767 11.983 -14.146 1.00 52.33 H HETATM 4767 H2 HOH A1397 -30.470 10.998 -15.416 1.00 52.33 H HETATM 4768 O HOH A1400 -36.880 -3.993 -33.716 1.00 50.72 O HETATM 4769 H1 HOH A1400 -37.147 -3.437 -34.504 1.00 50.72 H HETATM 4770 H2 HOH A1400 -37.524 -4.752 -33.618 1.00 50.72 H HETATM 4771 O HOH A1401 -24.206 -1.279 -35.770 1.00 53.88 O HETATM 4772 H1 HOH A1401 -23.632 -1.063 -36.562 1.00 53.88 H HETATM 4773 H2 HOH A1401 -25.118 -0.889 -35.914 1.00 53.88 H HETATM 4774 O HOH A1406 -1.292 8.841 -35.635 1.00 44.73 O HETATM 4775 H1 HOH A1406 -1.662 8.240 -34.923 1.00 44.73 H HETATM 4776 H2 HOH A1406 -0.648 9.487 -35.214 1.00 44.73 H HETATM 4777 O HOH A1412 -0.946 21.652 -15.116 1.00 53.19 O HETATM 4778 H1 HOH A1412 -1.600 21.432 -15.844 1.00 53.19 H HETATM 4779 H2 HOH A1412 -1.078 21.016 -14.353 1.00 53.19 H HETATM 4780 O HOH A1415 -23.399 -9.578 -15.048 1.00 55.01 O HETATM 4781 H1 HOH A1415 -23.421 -8.698 -15.526 1.00 55.01 H HETATM 4782 H2 HOH A1415 -24.267 -10.053 -15.194 1.00 55.01 H HETATM 4783 O HOH A1416 5.715 22.275 -28.185 1.00110.14 O HETATM 4784 H1 HOH A1416 6.698 22.109 -28.267 1.00110.14 H HETATM 4785 H2 HOH A1416 5.253 21.393 -28.063 1.00110.14 H HETATM 4786 O HOH A1417 -27.286 10.455 -33.143 1.00 53.90 O HETATM 4787 H1 HOH A1417 -27.557 11.412 -33.288 1.00 53.90 H HETATM 4788 H2 HOH A1417 -27.516 10.197 -32.205 1.00 53.90 H HETATM 4789 O HOH A1419 -33.125 0.444 -35.100 1.00 58.72 O HETATM 4790 H1 HOH A1419 -32.946 1.047 -34.319 1.00 58.72 H HETATM 4791 H2 HOH A1419 -32.253 0.120 -35.472 1.00 58.72 H CONECT 1 4 5 6 CONECT 4 1 CONECT 5 1 CONECT 6 1 CONECT 4654 4655 4656 CONECT 4655 4654 CONECT 4656 4654 CONECT 4657 4658 4659 CONECT 4658 4657 CONECT 4659 4657 CONECT 4660 4661 4662 CONECT 4661 4660 CONECT 4662 4660 CONECT 4663 4664 4665 CONECT 4664 4663 CONECT 4665 4663 CONECT 4666 4667 4668 CONECT 4667 4666 CONECT 4668 4666 CONECT 4669 4670 4671 CONECT 4670 4669 CONECT 4671 4669 CONECT 4672 4673 4674 CONECT 4673 4672 CONECT 4674 4672 CONECT 4675 4676 4677 CONECT 4676 4675 CONECT 4677 4675 CONECT 4678 4679 4680 CONECT 4679 4678 CONECT 4680 4678 CONECT 4681 4682 4683 CONECT 4682 4681 CONECT 4683 4681 CONECT 4684 4685 4686 CONECT 4685 4684 CONECT 4686 4684 CONECT 4687 4688 4689 CONECT 4688 4687 CONECT 4689 4687 CONECT 4690 4691 4692 CONECT 4691 4690 CONECT 4692 4690 CONECT 4693 4694 4695 CONECT 4694 4693 CONECT 4695 4693 CONECT 4696 4697 4698 CONECT 4697 4696 CONECT 4698 4696 CONECT 4699 4700 4701 CONECT 4700 4699 CONECT 4701 4699 CONECT 4702 4703 4704 CONECT 4703 4702 CONECT 4704 4702 CONECT 4705 4706 4707 CONECT 4706 4705 CONECT 4707 4705 CONECT 4708 4709 4710 CONECT 4709 4708 CONECT 4710 4708 CONECT 4711 4712 4713 CONECT 4712 4711 CONECT 4713 4711 CONECT 4714 4715 4716 CONECT 4715 4714 CONECT 4716 4714 CONECT 4717 4718 4719 CONECT 4718 4717 CONECT 4719 4717 CONECT 4720 4721 4722 CONECT 4721 4720 CONECT 4722 4720 CONECT 4723 4724 4725 CONECT 4724 4723 CONECT 4725 4723 CONECT 4726 4727 4728 CONECT 4727 4726 CONECT 4728 4726 CONECT 4729 4730 4731 CONECT 4730 4729 CONECT 4731 4729 CONECT 4732 4733 4734 CONECT 4733 4732 CONECT 4734 4732 CONECT 4735 4736 4737 CONECT 4736 4735 CONECT 4737 4735 CONECT 4738 4739 4740 CONECT 4739 4738 CONECT 4740 4738 CONECT 4741 4742 4743 CONECT 4742 4741 CONECT 4743 4741 CONECT 4744 4745 4746 CONECT 4745 4744 CONECT 4746 4744 CONECT 4747 4748 4749 CONECT 4748 4747 CONECT 4749 4747 CONECT 4750 4751 4752 CONECT 4751 4750 CONECT 4752 4750 CONECT 4753 4754 4755 CONECT 4754 4753 CONECT 4755 4753 CONECT 4756 4757 4758 CONECT 4757 4756 CONECT 4758 4756 CONECT 4759 4760 4761 CONECT 4760 4759 CONECT 4761 4759 CONECT 4762 4763 4764 CONECT 4763 4762 CONECT 4764 4762 CONECT 4765 4766 4767 CONECT 4766 4765 CONECT 4767 4765 CONECT 4768 4769 4770 CONECT 4769 4768 CONECT 4770 4768 CONECT 4771 4772 4773 CONECT 4772 4771 CONECT 4773 4771 CONECT 4774 4775 4776 CONECT 4775 4774 CONECT 4776 4774 CONECT 4777 4778 4779 CONECT 4778 4777 CONECT 4779 4777 CONECT 4780 4781 4782 CONECT 4781 4780 CONECT 4782 4780 CONECT 4783 4784 4785 CONECT 4784 4783 CONECT 4785 4783 CONECT 4786 4787 4788 CONECT 4787 4786 CONECT 4788 4786 CONECT 4789 4790 4791 CONECT 4790 4789 CONECT 4791 4789 END ================================================ FILE: src/openfecli/tests/data/transformation.json ================================================ {":version:": 1, "__module__": "gufe.transformations.transformation", "__qualname__": "Transformation", "mapping": {":version:": 1, "__module__": "gufe.mapping.ligandatommapping", "__qualname__": "LigandAtomMapping", "annotations": "{}", "componentA": {":version:": 1, "__module__": "gufe.components.smallmoleculecomponent", "__qualname__": "SmallMoleculeComponent", "atoms": [[6, 0, 0, true, 0, 0, {}], [6, 0, 0, true, 0, 0, {}], [6, 0, 0, true, 0, 0, {}], [6, 0, 0, true, 0, 0, {}], [6, 0, 0, true, 0, 0, {}], [6, 0, 0, true, 0, 0, {}], [1, 0, 0, false, 0, 0, {}], [1, 0, 0, false, 0, 0, {}], [1, 0, 0, false, 0, 0, {}], [1, 0, 0, false, 0, 0, {}], [1, 0, 0, false, 0, 0, {}], [1, 0, 0, false, 0, 0, {}]], "bonds": [[0, 1, 12, 0, {}], [0, 5, 12, 0, {}], [0, 6, 1, 0, {}], [1, 2, 12, 0, {}], [1, 7, 1, 0, {}], [2, 3, 12, 0, {}], [2, 8, 1, 0, {}], [3, 4, 12, 0, {}], [3, 9, 1, 0, {}], [4, 5, 12, 0, {}], [4, 10, 1, 0, {}], [5, 11, 1, 0, {}]], "conformer": ["\u0093NUMPY\u0001\u0000v\u0000{'descr': '\u00e8<@[\u00b1\u00bf\u00ec\u009e|!@\u00b0rh\u0091\u00ed|\u0014@\u00c3d\u00aa`T2<@\u009a\b\u001b\u009e^I @\u00caT\u00c1\u00a8\u00a4\u008e\u001a@?\u00c6\u00dc\u00b5\u0084\u00fc;@\u00da\u001b|a2\u00d5 @$(~\u008c\u00b9k\u0016@n\u00a3\u0001\u00bc\u0005B;@\u00c0\u00ec\u009e<,t\"@\u0084\u009e\u00cd\u00aa\u00cfU\u0016@\u00ee|?5^\u00fa9@\u0002+\u0087\u0016\u00d9N\u0015@\u0004V\u000e-\u00b2\u001d\u0013@\u0085\u00ebQ\u00b8\u001ee:@\u00b2\u009d\u00ef\u00a7\u00c6K\u0014@\u00cb\u00a1E\u00b6\u00f3\u00fd\u000b@\u00d7\u00a3p=\nW;@q=\n\u00d7\u00a3p\u0017@\u009e\u00ef\u00a7\u00c6K7\u0007@\u0083\u00c0\u00ca\u00a1E\u00d6;@\u00c9v\u00be\u009f\u001a\u00af\u001b@Zd;\u00dfO\u008d\f@\u00ecQ\u00b8\u001e\u0085k;@b\u0010X9\u00b4\u00c8\u001c@\u0006\u0081\u0095C\u008bl\u0013@sh\u0091\u00ed|\u007f:@j\u00bct\u0093\u0018\u0084\u0019@\u00c7K7\u0089A\u00e0\u0015@\u00ed\u009e<,\u00d4:9@\u00e8<@[\u00b1\u00bf\u00ec\u009e|!@\u00b0rh\u0091\u00ed|\u0014@\u00c3d\u00aa`T2<@\u009a\b\u001b\u009e^I @\u00caT\u00c1\u00a8\u00a4\u008e\u001a@?\u00c6\u00dc\u00b5\u0084\u00fc;@\u00da\u001b|a2\u00d5 @$(~\u008c\u00b9k\u0016@n\u00a3\u0001\u00bc\u0005B;@\u00c0\u00ec\u009e<,t\"@\u0084\u009e\u00cd\u00aa\u00cfU\u0016@\u00ee|?5^\u00fa9@\u0002+\u0087\u0016\u00d9N\u0015@\u0004V\u000e-\u00b2\u001d\u0013@\u0085\u00ebQ\u00b8\u001ee:@\u00b2\u009d\u00ef\u00a7\u00c6K\u0014@\u00cb\u00a1E\u00b6\u00f3\u00fd\u000b@\u00d7\u00a3p=\nW;@q=\n\u00d7\u00a3p\u0017@\u009e\u00ef\u00a7\u00c6K7\u0007@\u0083\u00c0\u00ca\u00a1E\u00d6;@\u00c9v\u00be\u009f\u001a\u00af\u001b@Zd;\u00dfO\u008d\f@\u00ecQ\u00b8\u001e\u0085k;@b\u0010X9\u00b4\u00c8\u001c@\u0006\u0081\u0095C\u008bl\u0013@sh\u0091\u00ed|\u007f:@j\u00bct\u0093\u0018\u0084\u0019@\u00c7K7\u0089A\u00e0\u0015@\u00ed\u009e<,\u00d4:9@ 0 @pytest.mark.parametrize("with_log", [True, False]) def test_main_log(with_log): logged_text = "Running null command\n" logfile_text = "\n".join( [ "[loggers]", "keys=root", "", "[handlers]", "keys=std", "", "[formatters]", "keys=default", "", "[formatter_default]", "format=%(message)s", "", "[handler_std]", "class=StreamHandler", "level=NOTSET", "formatter=default", "args=(sys.stdout,)", "[logger_root]", "level=DEBUG", "handlers=std", ] ) runner = click.testing.CliRunner() invocation = ["null_command"] if with_log: invocation = ["--log", "logging.conf"] + invocation expected = logged_text if with_log else "" with runner.isolated_filesystem(): with open("logging.conf", mode="w") as log_conf: log_conf.write(logfile_text) with null_command_context(main): result = runner.invoke(main, invocation) found = result.stdout_bytes assert found.decode("utf-8") == expected ================================================ FILE: src/openfecli/tests/test_fetchables.py ================================================ import pathlib import pytest from click.testing import CliRunner from openfecli.fetchables import RBFE_TUTORIAL, RBFE_TUTORIAL_RESULTS from openfecli.fetching import FetchablePlugin from .conftest import HAS_INTERNET def fetchable_test(fetchable): """Unit test to ensure that a given FetchablePlugin works""" assert isinstance(fetchable, FetchablePlugin) expected_paths = [pathlib.Path(f) for f in fetchable.filenames] runner = CliRunner() if fetchable.fetcher.REQUIRES_INTERNET and not HAS_INTERNET: # -no-cov- pytest.skip("Internet seems to be unavailable") with runner.isolated_filesystem(): result = runner.invoke(fetchable.command, ["-doutput-dir"]) assert result.exit_code == 0 for path in expected_paths: assert (pathlib.Path("output-dir") / path).exists() @pytest.mark.flaky(reruns=3) # in case of Too Many Request error def test_rbfe_tutorial(): fetchable_test(RBFE_TUTORIAL) @pytest.mark.flaky(reruns=3) # in case of Too Many Request error def test_rbfe_tutorial_results(): fetchable_test(RBFE_TUTORIAL_RESULTS) ================================================ FILE: src/openfecli/tests/test_fetching.py ================================================ import pytest from openfecli.fetching import FetchablePlugin, PkgResourceFetcher, URLFetcher from .conftest import HAS_INTERNET class FetcherTester: @pytest.fixture def fetcher(self): raise NotImplementedError() def test_resources(self): raise NotImplementedError() def test_plugin(self, fetcher): # this is just a smoke test; individual plugins should test that # they work plugin = fetcher.plugin assert isinstance(plugin, FetchablePlugin) def test_call(self, fetcher, tmp_path): # Here we just check that the machinery works. Each plugin should # have a test to ensure that we're getting the right kind of file. paths = [tmp_path / filename for _, filename in fetcher.resources] for path in paths: assert not path.exists() fetcher(tmp_path) for path in paths: assert path.exists() class TestURLFetcher(FetcherTester): @pytest.fixture def fetcher(self): return URLFetcher( resources=[("https://www.google.com/", "index.html")], short_name="google", short_help="The Goog", requires_ofe=(0, 7, 0), long_help="Google, an Alphabet company", ) def test_resources(self, fetcher): expected = [("https://www.google.com/", "index.html")] assert list(fetcher.resources) == expected @pytest.mark.skipif(not HAS_INTERNET, reason="Internet seems to be unavailable") def test_call(self, fetcher, tmp_path): super().test_call(fetcher, tmp_path) @pytest.mark.skipif(not HAS_INTERNET, reason="Internet seems to be unavailable") def test_without_trailing_slash(self, tmp_path): fetcher = URLFetcher( resources=[("https://www.google.com", "index.html")], short_name="goog2", short_help="more goog", requires_ofe=(0, 7, 0), long_help="What if you forget the trailing slash?", ) self.test_call(fetcher, tmp_path) class TestPkgResourceFetcher(FetcherTester): @pytest.fixture def fetcher(self): return PkgResourceFetcher( resources=[("openfecli.tests", "test_fetching.py")], short_name="me", short_help="download this file", requires_ofe=(0, 7, 4), long_help="whoa, meta.", ) def test_resources(self, fetcher): expected = [("openfecli.tests", "test_fetching.py")] assert list(fetcher.resources) == expected ================================================ FILE: src/openfecli/tests/test_plugins.py ================================================ import click from openfecli.plugins import OFECommandPlugin @click.command("fake") def fake(): pass # -no-cov- a fake placeholder click subcommand class TestOFECommandPlugin: def setup_method(self): self.plugin = OFECommandPlugin( command=fake, section="Some Section", requires_ofe=(0, 0, 1), ) def test_plugin_setup(self): assert self.plugin.command is fake assert isinstance(self.plugin.command, click.Command) assert self.plugin.section == "Some Section" assert self.plugin.requires_lib == self.plugin.requires_cli assert self.plugin.requires_lib == (0, 0, 1) assert self.plugin.requires_cli == (0, 0, 1) ================================================ FILE: src/openfecli/tests/test_rbfe_tutorial.py ================================================ """ Tests the easy start guide - runs plan_rbfe_network with tyk2 inputs and checks the network created - mocks the calculations and performs gathers on the mocked outputs """ import os from importlib import resources from os import path from pathlib import Path from unittest import mock import numpy as np import pytest from click.testing import CliRunner from openff.units import unit from openfecli.commands.gather import gather from openfecli.commands.plan_rbfe_network import plan_rbfe_network from openfecli.commands.quickrun import quickrun from .utils import assert_click_success @pytest.fixture def tyk2_ligands(): with resources.as_file(resources.files("openfecli.tests.data.rbfe_tutorial")) as d: yield str(d / "tyk2_ligands.sdf") @pytest.fixture def tyk2_protein(): with resources.as_file(resources.files("openfecli.tests.data.rbfe_tutorial")) as d: yield str(d / "tyk2_protein.pdb") @pytest.fixture def expected_transformations(): return [ "rbfe_lig_ejm_31_solvent_lig_ejm_48_solvent.json", "rbfe_lig_ejm_46_solvent_lig_jmc_28_solvent.json", "rbfe_lig_jmc_27_complex_lig_jmc_28_complex.json", "rbfe_lig_jmc_23_solvent_lig_jmc_28_solvent.json", "rbfe_lig_ejm_42_solvent_lig_ejm_50_solvent.json", "rbfe_lig_ejm_31_complex_lig_ejm_46_complex.json", "rbfe_lig_ejm_31_solvent_lig_ejm_50_solvent.json", "rbfe_lig_ejm_42_solvent_lig_ejm_43_solvent.json", "rbfe_lig_ejm_31_complex_lig_ejm_47_complex.json", "rbfe_lig_jmc_27_solvent_lig_jmc_28_solvent.json", "rbfe_lig_jmc_23_complex_lig_jmc_28_complex.json", "rbfe_lig_ejm_42_complex_lig_ejm_50_complex.json", "rbfe_lig_ejm_31_solvent_lig_ejm_46_solvent.json", "rbfe_lig_ejm_31_complex_lig_ejm_50_complex.json", "rbfe_lig_ejm_42_complex_lig_ejm_43_complex.json", "rbfe_lig_ejm_31_solvent_lig_ejm_47_solvent.json", "rbfe_lig_ejm_31_complex_lig_ejm_48_complex.json", "rbfe_lig_ejm_46_complex_lig_jmc_28_complex.json", ] def test_plan_tyk2(tyk2_ligands, tyk2_protein, expected_transformations): runner = CliRunner() with runner.isolated_filesystem(): result = runner.invoke( plan_rbfe_network, [ "-M", tyk2_ligands, "-p", tyk2_protein, ], ) # fmt: skip assert_click_success(result) assert path.exists("alchemicalNetwork/transformations") for f in expected_transformations: assert path.exists(path.join("alchemicalNetwork/transformations", f)) # make sure these are the only transforms assert len(os.listdir("alchemicalNetwork/transformations")) == len(expected_transformations) # check that the correct default settings are used, we currently have no provenance on the object so check # the output string # check the atom mapper assert "Mapper: j) (kcal/mol)\tuncertainty (kcal/mol) lig_ejm_31\tlig_ejm_46\t0.0\t0.0 lig_ejm_31\tlig_ejm_47\t0.0\t0.0 lig_ejm_31\tlig_ejm_48\t0.0\t0.0 lig_ejm_31\tlig_ejm_50\t0.0\t0.0 lig_ejm_42\tlig_ejm_43\t0.0\t0.0 lig_ejm_42\tlig_ejm_50\t0.0\t0.0 lig_ejm_46\tlig_jmc_28\t0.0\t0.0 lig_jmc_23\tlig_jmc_28\t0.0\t0.0 lig_jmc_27\tlig_jmc_28\t0.0\t0.0 """ @pytest.fixture def fake_setup_execute_results(): """Use for mocking the expensive _execute step and instead directly return plausible results.""" def _fake_execute_results(*args, **kwargs): return { "repeat_id": kwargs["repeat_id"], "generation": kwargs["generation"], "system": Path("system.xml.bz2"), "positions": Path("positions.npy"), "pdb_structure": Path("hybrid_system.pdb"), "selection_indices": np.arange(50), } return _fake_execute_results @pytest.fixture def fake_sim_execute_results(): """Use for mocking the expensive _execute step and instead directly return plausible results.""" def _fake_execute_results(*args, **kwargs): return { "repeat_id": kwargs["repeat_id"], "generation": kwargs["generation"], "nc": Path("file.nc"), "checkpoint": Path("chk.chk"), } return _fake_execute_results @pytest.fixture def fake_analysis_execute_results(): """Use for mocking the expensive _execute step and instead directly return plausible results.""" def _fake_execute_results(*args, **kwargs): return { "repeat_id": kwargs["repeat_id"], "generation": kwargs["generation"], "pdb_structure": Path("hybrid_system.pdb"), "checkpoint": Path("chk.chk"), "selection_indices": np.arange(50), "unit_estimate": 4.2 * unit.kilocalories_per_mole, } return _fake_execute_results def test_run_tyk2( tyk2_ligands, tyk2_protein, expected_transformations, fake_setup_execute_results, fake_sim_execute_results, fake_analysis_execute_results, ref_gather, ): runner = CliRunner() with runner.isolated_filesystem(): result_setup = runner.invoke( plan_rbfe_network, [ "-M", tyk2_ligands, "-p", tyk2_protein, ], ) # fmt: skip assert_click_success(result_setup) with ( mock.patch( "openfe.protocols.openmm_rfe.hybridtop_units.HybridTopologySetupUnit._execute", side_effect=fake_setup_execute_results, ), mock.patch( "openfe.protocols.openmm_rfe.hybridtop_units.HybridTopologyMultiStateSimulationUnit._execute", side_effect=fake_sim_execute_results, ), mock.patch( "openfe.protocols.openmm_rfe.hybridtop_units.HybridTopologyMultiStateAnalysisUnit._execute", side_effect=fake_analysis_execute_results, ), ): for f in expected_transformations: fn = path.join("alchemicalNetwork/transformations", f) result_run = runner.invoke(quickrun, [fn]) assert_click_success(result_run) result_gather = runner.invoke(gather, ["--report", "ddg", ".", "--tsv"]) assert_click_success(result_gather) assert result_gather.stdout == ref_gather ================================================ FILE: src/openfecli/tests/test_utils.py ================================================ import contextlib import logging import os from unittest.mock import patch import pytest from openfecli.utils import _should_configure_logger, configure_logger, import_thing # looks like this can't be done as a fixture; related to # https://github.com/pytest-dev/pytest/issues/2974 @contextlib.contextmanager def patch_root_logger(): # use this to hide away some handlers that pytest attaches old_manager = logging.Logger.manager old_root = logging.root new_root = logging.RootLogger(logging.WARNING) manager = logging.Manager(new_root) logging.Logger.manager = manager logging.root = new_root yield new_root logging.Logger.manager = old_manager logging.root = old_root @pytest.mark.parametrize( "import_string,expected", [ ("os.path.exists", os.path.exists), ("os.getcwd", os.getcwd), ("os", os), ], ) def test_import_thing(import_string, expected): assert import_thing(import_string) is expected def test_import_thing_import_error(): with pytest.raises(ImportError): import_thing("foo.bar") def test_import_thing_attribute_error(): with pytest.raises(AttributeError): import_thing("os.foo") @pytest.mark.parametrize( "logger_name, expected", [ ("default", True), ("default.default", True), ("level", False), ("level.default", False), ("handler", False), ("handler.default", False), ("default.noprop", False), ], ) @pytest.mark.parametrize("with_adapter", [True, False]) def test_should_configure_logger(logger_name, expected, with_adapter): with patch_root_logger(): logging.getLogger("level").setLevel(logging.INFO) logging.getLogger("handler").addHandler(logging.NullHandler()) logging.getLogger("default.noprop").propagate = False logger = logging.getLogger(logger_name) if with_adapter: logger = logging.LoggerAdapter(logger, extra={"foo": "bar"}) assert _should_configure_logger(logger) == expected def test_root_logger_level_configured(): with patch_root_logger(): root = logging.getLogger() root.setLevel(logging.INFO) logger = logging.getLogger("default.default") assert not _should_configure_logger(logger) @pytest.mark.parametrize("with_handler", [True, False]) def test_configure_logger(with_handler): handler = logging.NullHandler() if with_handler else None expected_handlers = [handler] if handler else [] with patch_root_logger(): configure_logger("default.default", handler=handler) logger = logging.getLogger("default.default") parent = logging.getLogger("default") assert logger.isEnabledFor(logging.INFO) assert not parent.isEnabledFor(logging.INFO) assert logger.handlers == expected_handlers assert parent.handlers == [] ================================================ FILE: src/openfecli/tests/utils.py ================================================ """Helper utilities for CLI tests""" import traceback import click def assert_click_success(result: click.testing.Result): # -no-cov- """Pass through error message if a click test fails. Taken from https://github.com/openpathsampling/openpathsampling-cli/blob/main/paths_cli/commands/pathsampling.py """ if result.exit_code != 0: print(result.output) traceback.print_tb(result.exc_info[2]) print(result.exc_info[0], result.exc_info[1]) assert result.exit_code == 0 ================================================ FILE: src/openfecli/utils.py ================================================ # This code is part of OpenFE and is licensed under the MIT license. # For details, see https://github.com/OpenFreeEnergy/openfe import functools import importlib import logging from datetime import datetime from typing import Callable, Optional import click def import_thing(import_string: str): """Obtain an object from a valid qualname (or fully qualified name) Parameters ---------- import_string : str the qualname Returns ------- Any : the object from that namespace """ splitted = import_string.split(".") if len(splitted) > 1: # if the string has a dot, import the module and getattr the object obj = splitted[-1] mod = ".".join(splitted[:-1]) module = importlib.import_module(mod) result = getattr(module, obj) else: # if there is no dot, import and return the module mod = splitted[0] result = importlib.import_module(mod) return result def write(string: str): """ This is abstracted so that we can change output mechanism here and it will automatically update in all commands. """ click.echo(string) def _should_configure_logger(logger: logging.Logger): """Determine whether a logger should be configured. Separated from configure_logger for ease of testing. """ if isinstance(logger, logging.LoggerAdapter): logger = logger.logger if logger.hasHandlers(): return False # walk up the logging tree to see if any parent loggers are not default _logger = logger while ( _logger.parent is not None # not the root logger and _logger.level == logging.NOTSET # level not already set and _logger.propagate # configured to use parent when not set ): _logger = _logger.parent is_default = (_logger == logging.root and _logger.level == logging.WARNING) # fmt: skip return is_default def configure_logger( logger_name: str, level: int = logging.INFO, *, handler: Optional[logging.Handler] = None, ): """Configure the logger at ``logger_name`` to be at ``level``. This is used to prevent accidentally overwriting existing logging configurations. This is particularly useful for setting INFO-level log messages to be seen in the CLI (with the default handler/formatter). Parameters ---------- logger_name: str name of the logger to configure level: int level to set the logger to use, typically one of the constants defined in the ``logging`` module. """ logger = logging.getLogger(logger_name) if _should_configure_logger(logger): logger.setLevel(level) if handler is not None: logger.addHandler(handler) def print_duration(function: Callable) -> Callable: """ Helper function to denote that a function should print a duration information. A function decorated with this decorator will print out the execution time of the decorated function. """ @functools.wraps(function) def wrapper(*args, **kwargs): start_time = datetime.now() result = function(*args, **kwargs) end_time = datetime.now() duration = end_time - start_time write("\tDuration: " + str(duration) + "\n") return result return wrapper