├── .gitignore ├── LICENSE ├── README.md ├── bsite_extraction.py ├── features.py ├── lds ├── __init__.py ├── amul.py ├── amul_kernel_cube.cc ├── amul_kernel_cube.cu.cc ├── amul_kernel_cube_grad.cc ├── amul_kernel_cube_grad.cu.cc └── compile.sh ├── multi_predict.py ├── net ├── __init__.py ├── resnet_3d.py ├── resnet_3d_utils.py └── resnet_lds_3d_bottleneck.py ├── network.py ├── predict.py ├── protein.py ├── requirements.txt ├── test ├── 1a2kC.pdb ├── 1a4kH.pdb ├── 1eveA.pdb ├── 1oa8_A.pdb └── 4j2j_A.pdb ├── tfbio_data.py ├── training_subset_of_scpdb.proteins └── utils.py /.gitignore: -------------------------------------------------------------------------------- 1 | __pycache__/ 2 | *.py[cod] 3 | *~ 4 | results/ 5 | *models/ 6 | *.so 7 | *.o 8 | *.7z 9 | 10 | 11 | # Environments 12 | .env 13 | .venv 14 | env/ 15 | venv/ 16 | ENV/ 17 | env.bak/ 18 | venv.bak/ 19 | 20 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | GNU AFFERO GENERAL PUBLIC LICENSE 2 | Version 3, 19 November 2007 3 | 4 | Copyright (C) 2007 Free Software Foundation, Inc. 5 | Everyone is permitted to copy and distribute verbatim copies 6 | of this license document, but changing it is not allowed. 7 | 8 | Preamble 9 | 10 | The GNU Affero General Public License is a free, copyleft license for 11 | software and other kinds of works, specifically designed to ensure 12 | cooperation with the community in the case of network server software. 13 | 14 | The licenses for most software and other practical works are designed 15 | to take away your freedom to share and change the works. By contrast, 16 | our General Public Licenses are intended to guarantee your freedom to 17 | share and change all versions of a program--to make sure it remains free 18 | software for all its users. 19 | 20 | When we speak of free software, we are referring to freedom, not 21 | price. Our General Public Licenses are designed to make sure that you 22 | have the freedom to distribute copies of free software (and charge for 23 | them if you wish), that you receive source code or can get it if you 24 | want it, that you can change the software or use pieces of it in new 25 | free programs, and that you know you can do these things. 26 | 27 | Developers that use our General Public Licenses protect your rights 28 | with two steps: (1) assert copyright on the software, and (2) offer 29 | you this License which gives you legal permission to copy, distribute 30 | and/or modify the software. 31 | 32 | A secondary benefit of defending all users' freedom is that 33 | improvements made in alternate versions of the program, if they 34 | receive widespread use, become available for other developers to 35 | incorporate. Many developers of free software are heartened and 36 | encouraged by the resulting cooperation. However, in the case of 37 | software used on network servers, this result may fail to come about. 38 | The GNU General Public License permits making a modified version and 39 | letting the public access it on a server without ever releasing its 40 | source code to the public. 41 | 42 | The GNU Affero General Public License is designed specifically to 43 | ensure that, in such cases, the modified source code becomes available 44 | to the community. It requires the operator of a network server to 45 | provide the source code of the modified version running there to the 46 | users of that server. Therefore, public use of a modified version, on 47 | a publicly accessible server, gives the public access to the source 48 | code of the modified version. 49 | 50 | An older license, called the Affero General Public License and 51 | published by Affero, was designed to accomplish similar goals. This is 52 | a different license, not a version of the Affero GPL, but Affero has 53 | released a new version of the Affero GPL which permits relicensing under 54 | this license. 55 | 56 | The precise terms and conditions for copying, distribution and 57 | modification follow. 58 | 59 | TERMS AND CONDITIONS 60 | 61 | 0. Definitions. 62 | 63 | "This License" refers to version 3 of the GNU Affero General Public License. 64 | 65 | "Copyright" also means copyright-like laws that apply to other kinds of 66 | works, such as semiconductor masks. 67 | 68 | "The Program" refers to any copyrightable work licensed under this 69 | License. Each licensee is addressed as "you". "Licensees" and 70 | "recipients" may be individuals or organizations. 71 | 72 | To "modify" a work means to copy from or adapt all or part of the work 73 | in a fashion requiring copyright permission, other than the making of an 74 | exact copy. The resulting work is called a "modified version" of the 75 | earlier work or a work "based on" the earlier work. 76 | 77 | A "covered work" means either the unmodified Program or a work based 78 | on the Program. 79 | 80 | To "propagate" a work means to do anything with it that, without 81 | permission, would make you directly or secondarily liable for 82 | infringement under applicable copyright law, except executing it on a 83 | computer or modifying a private copy. Propagation includes copying, 84 | distribution (with or without modification), making available to the 85 | public, and in some countries other activities as well. 86 | 87 | To "convey" a work means any kind of propagation that enables other 88 | parties to make or receive copies. Mere interaction with a user through 89 | a computer network, with no transfer of a copy, is not conveying. 90 | 91 | An interactive user interface displays "Appropriate Legal Notices" 92 | to the extent that it includes a convenient and prominently visible 93 | feature that (1) displays an appropriate copyright notice, and (2) 94 | tells the user that there is no warranty for the work (except to the 95 | extent that warranties are provided), that licensees may convey the 96 | work under this License, and how to view a copy of this License. If 97 | the interface presents a list of user commands or options, such as a 98 | menu, a prominent item in the list meets this criterion. 99 | 100 | 1. Source Code. 101 | 102 | The "source code" for a work means the preferred form of the work 103 | for making modifications to it. "Object code" means any non-source 104 | form of a work. 105 | 106 | A "Standard Interface" means an interface that either is an official 107 | standard defined by a recognized standards body, or, in the case of 108 | interfaces specified for a particular programming language, one that 109 | is widely used among developers working in that language. 110 | 111 | The "System Libraries" of an executable work include anything, other 112 | than the work as a whole, that (a) is included in the normal form of 113 | packaging a Major Component, but which is not part of that Major 114 | Component, and (b) serves only to enable use of the work with that 115 | Major Component, or to implement a Standard Interface for which an 116 | implementation is available to the public in source code form. A 117 | "Major Component", in this context, means a major essential component 118 | (kernel, window system, and so on) of the specific operating system 119 | (if any) on which the executable work runs, or a compiler used to 120 | produce the work, or an object code interpreter used to run it. 121 | 122 | The "Corresponding Source" for a work in object code form means all 123 | the source code needed to generate, install, and (for an executable 124 | work) run the object code and to modify the work, including scripts to 125 | control those activities. However, it does not include the work's 126 | System Libraries, or general-purpose tools or generally available free 127 | programs which are used unmodified in performing those activities but 128 | which are not part of the work. For example, Corresponding Source 129 | includes interface definition files associated with source files for 130 | the work, and the source code for shared libraries and dynamically 131 | linked subprograms that the work is specifically designed to require, 132 | such as by intimate data communication or control flow between those 133 | subprograms and other parts of the work. 134 | 135 | The Corresponding Source need not include anything that users 136 | can regenerate automatically from other parts of the Corresponding 137 | Source. 138 | 139 | The Corresponding Source for a work in source code form is that 140 | same work. 141 | 142 | 2. Basic Permissions. 143 | 144 | All rights granted under this License are granted for the term of 145 | copyright on the Program, and are irrevocable provided the stated 146 | conditions are met. This License explicitly affirms your unlimited 147 | permission to run the unmodified Program. The output from running a 148 | covered work is covered by this License only if the output, given its 149 | content, constitutes a covered work. This License acknowledges your 150 | rights of fair use or other equivalent, as provided by copyright law. 151 | 152 | You may make, run and propagate covered works that you do not 153 | convey, without conditions so long as your license otherwise remains 154 | in force. You may convey covered works to others for the sole purpose 155 | of having them make modifications exclusively for you, or provide you 156 | with facilities for running those works, provided that you comply with 157 | the terms of this License in conveying all material for which you do 158 | not control copyright. Those thus making or running the covered works 159 | for you must do so exclusively on your behalf, under your direction 160 | and control, on terms that prohibit them from making any copies of 161 | your copyrighted material outside their relationship with you. 162 | 163 | Conveying under any other circumstances is permitted solely under 164 | the conditions stated below. Sublicensing is not allowed; section 10 165 | makes it unnecessary. 166 | 167 | 3. Protecting Users' Legal Rights From Anti-Circumvention Law. 168 | 169 | No covered work shall be deemed part of an effective technological 170 | measure under any applicable law fulfilling obligations under article 171 | 11 of the WIPO copyright treaty adopted on 20 December 1996, or 172 | similar laws prohibiting or restricting circumvention of such 173 | measures. 174 | 175 | When you convey a covered work, you waive any legal power to forbid 176 | circumvention of technological measures to the extent such circumvention 177 | is effected by exercising rights under this License with respect to 178 | the covered work, and you disclaim any intention to limit operation or 179 | modification of the work as a means of enforcing, against the work's 180 | users, your or third parties' legal rights to forbid circumvention of 181 | technological measures. 182 | 183 | 4. Conveying Verbatim Copies. 184 | 185 | You may convey verbatim copies of the Program's source code as you 186 | receive it, in any medium, provided that you conspicuously and 187 | appropriately publish on each copy an appropriate copyright notice; 188 | keep intact all notices stating that this License and any 189 | non-permissive terms added in accord with section 7 apply to the code; 190 | keep intact all notices of the absence of any warranty; and give all 191 | recipients a copy of this License along with the Program. 192 | 193 | You may charge any price or no price for each copy that you convey, 194 | and you may offer support or warranty protection for a fee. 195 | 196 | 5. Conveying Modified Source Versions. 197 | 198 | You may convey a work based on the Program, or the modifications to 199 | produce it from the Program, in the form of source code under the 200 | terms of section 4, provided that you also meet all of these conditions: 201 | 202 | a) The work must carry prominent notices stating that you modified 203 | it, and giving a relevant date. 204 | 205 | b) The work must carry prominent notices stating that it is 206 | released under this License and any conditions added under section 207 | 7. This requirement modifies the requirement in section 4 to 208 | "keep intact all notices". 209 | 210 | c) You must license the entire work, as a whole, under this 211 | License to anyone who comes into possession of a copy. This 212 | License will therefore apply, along with any applicable section 7 213 | additional terms, to the whole of the work, and all its parts, 214 | regardless of how they are packaged. This License gives no 215 | permission to license the work in any other way, but it does not 216 | invalidate such permission if you have separately received it. 217 | 218 | d) If the work has interactive user interfaces, each must display 219 | Appropriate Legal Notices; however, if the Program has interactive 220 | interfaces that do not display Appropriate Legal Notices, your 221 | work need not make them do so. 222 | 223 | A compilation of a covered work with other separate and independent 224 | works, which are not by their nature extensions of the covered work, 225 | and which are not combined with it such as to form a larger program, 226 | in or on a volume of a storage or distribution medium, is called an 227 | "aggregate" if the compilation and its resulting copyright are not 228 | used to limit the access or legal rights of the compilation's users 229 | beyond what the individual works permit. Inclusion of a covered work 230 | in an aggregate does not cause this License to apply to the other 231 | parts of the aggregate. 232 | 233 | 6. Conveying Non-Source Forms. 234 | 235 | You may convey a covered work in object code form under the terms 236 | of sections 4 and 5, provided that you also convey the 237 | machine-readable Corresponding Source under the terms of this License, 238 | in one of these ways: 239 | 240 | a) Convey the object code in, or embodied in, a physical product 241 | (including a physical distribution medium), accompanied by the 242 | Corresponding Source fixed on a durable physical medium 243 | customarily used for software interchange. 244 | 245 | b) Convey the object code in, or embodied in, a physical product 246 | (including a physical distribution medium), accompanied by a 247 | written offer, valid for at least three years and valid for as 248 | long as you offer spare parts or customer support for that product 249 | model, to give anyone who possesses the object code either (1) a 250 | copy of the Corresponding Source for all the software in the 251 | product that is covered by this License, on a durable physical 252 | medium customarily used for software interchange, for a price no 253 | more than your reasonable cost of physically performing this 254 | conveying of source, or (2) access to copy the 255 | Corresponding Source from a network server at no charge. 256 | 257 | c) Convey individual copies of the object code with a copy of the 258 | written offer to provide the Corresponding Source. This 259 | alternative is allowed only occasionally and noncommercially, and 260 | only if you received the object code with such an offer, in accord 261 | with subsection 6b. 262 | 263 | d) Convey the object code by offering access from a designated 264 | place (gratis or for a charge), and offer equivalent access to the 265 | Corresponding Source in the same way through the same place at no 266 | further charge. You need not require recipients to copy the 267 | Corresponding Source along with the object code. If the place to 268 | copy the object code is a network server, the Corresponding Source 269 | may be on a different server (operated by you or a third party) 270 | that supports equivalent copying facilities, provided you maintain 271 | clear directions next to the object code saying where to find the 272 | Corresponding Source. Regardless of what server hosts the 273 | Corresponding Source, you remain obligated to ensure that it is 274 | available for as long as needed to satisfy these requirements. 275 | 276 | e) Convey the object code using peer-to-peer transmission, provided 277 | you inform other peers where the object code and Corresponding 278 | Source of the work are being offered to the general public at no 279 | charge under subsection 6d. 280 | 281 | A separable portion of the object code, whose source code is excluded 282 | from the Corresponding Source as a System Library, need not be 283 | included in conveying the object code work. 284 | 285 | A "User Product" is either (1) a "consumer product", which means any 286 | tangible personal property which is normally used for personal, family, 287 | or household purposes, or (2) anything designed or sold for incorporation 288 | into a dwelling. In determining whether a product is a consumer product, 289 | doubtful cases shall be resolved in favor of coverage. For a particular 290 | product received by a particular user, "normally used" refers to a 291 | typical or common use of that class of product, regardless of the status 292 | of the particular user or of the way in which the particular user 293 | actually uses, or expects or is expected to use, the product. A product 294 | is a consumer product regardless of whether the product has substantial 295 | commercial, industrial or non-consumer uses, unless such uses represent 296 | the only significant mode of use of the product. 297 | 298 | "Installation Information" for a User Product means any methods, 299 | procedures, authorization keys, or other information required to install 300 | and execute modified versions of a covered work in that User Product from 301 | a modified version of its Corresponding Source. The information must 302 | suffice to ensure that the continued functioning of the modified object 303 | code is in no case prevented or interfered with solely because 304 | modification has been made. 305 | 306 | If you convey an object code work under this section in, or with, or 307 | specifically for use in, a User Product, and the conveying occurs as 308 | part of a transaction in which the right of possession and use of the 309 | User Product is transferred to the recipient in perpetuity or for a 310 | fixed term (regardless of how the transaction is characterized), the 311 | Corresponding Source conveyed under this section must be accompanied 312 | by the Installation Information. But this requirement does not apply 313 | if neither you nor any third party retains the ability to install 314 | modified object code on the User Product (for example, the work has 315 | been installed in ROM). 316 | 317 | The requirement to provide Installation Information does not include a 318 | requirement to continue to provide support service, warranty, or updates 319 | for a work that has been modified or installed by the recipient, or for 320 | the User Product in which it has been modified or installed. Access to a 321 | network may be denied when the modification itself materially and 322 | adversely affects the operation of the network or violates the rules and 323 | protocols for communication across the network. 324 | 325 | Corresponding Source conveyed, and Installation Information provided, 326 | in accord with this section must be in a format that is publicly 327 | documented (and with an implementation available to the public in 328 | source code form), and must require no special password or key for 329 | unpacking, reading or copying. 330 | 331 | 7. Additional Terms. 332 | 333 | "Additional permissions" are terms that supplement the terms of this 334 | License by making exceptions from one or more of its conditions. 335 | Additional permissions that are applicable to the entire Program shall 336 | be treated as though they were included in this License, to the extent 337 | that they are valid under applicable law. If additional permissions 338 | apply only to part of the Program, that part may be used separately 339 | under those permissions, but the entire Program remains governed by 340 | this License without regard to the additional permissions. 341 | 342 | When you convey a copy of a covered work, you may at your option 343 | remove any additional permissions from that copy, or from any part of 344 | it. (Additional permissions may be written to require their own 345 | removal in certain cases when you modify the work.) You may place 346 | additional permissions on material, added by you to a covered work, 347 | for which you have or can give appropriate copyright permission. 348 | 349 | Notwithstanding any other provision of this License, for material you 350 | add to a covered work, you may (if authorized by the copyright holders of 351 | that material) supplement the terms of this License with terms: 352 | 353 | a) Disclaiming warranty or limiting liability differently from the 354 | terms of sections 15 and 16 of this License; or 355 | 356 | b) Requiring preservation of specified reasonable legal notices or 357 | author attributions in that material or in the Appropriate Legal 358 | Notices displayed by works containing it; or 359 | 360 | c) Prohibiting misrepresentation of the origin of that material, or 361 | requiring that modified versions of such material be marked in 362 | reasonable ways as different from the original version; or 363 | 364 | d) Limiting the use for publicity purposes of names of licensors or 365 | authors of the material; or 366 | 367 | e) Declining to grant rights under trademark law for use of some 368 | trade names, trademarks, or service marks; or 369 | 370 | f) Requiring indemnification of licensors and authors of that 371 | material by anyone who conveys the material (or modified versions of 372 | it) with contractual assumptions of liability to the recipient, for 373 | any liability that these contractual assumptions directly impose on 374 | those licensors and authors. 375 | 376 | All other non-permissive additional terms are considered "further 377 | restrictions" within the meaning of section 10. If the Program as you 378 | received it, or any part of it, contains a notice stating that it is 379 | governed by this License along with a term that is a further 380 | restriction, you may remove that term. If a license document contains 381 | a further restriction but permits relicensing or conveying under this 382 | License, you may add to a covered work material governed by the terms 383 | of that license document, provided that the further restriction does 384 | not survive such relicensing or conveying. 385 | 386 | If you add terms to a covered work in accord with this section, you 387 | must place, in the relevant source files, a statement of the 388 | additional terms that apply to those files, or a notice indicating 389 | where to find the applicable terms. 390 | 391 | Additional terms, permissive or non-permissive, may be stated in the 392 | form of a separately written license, or stated as exceptions; 393 | the above requirements apply either way. 394 | 395 | 8. Termination. 396 | 397 | You may not propagate or modify a covered work except as expressly 398 | provided under this License. Any attempt otherwise to propagate or 399 | modify it is void, and will automatically terminate your rights under 400 | this License (including any patent licenses granted under the third 401 | paragraph of section 11). 402 | 403 | However, if you cease all violation of this License, then your 404 | license from a particular copyright holder is reinstated (a) 405 | provisionally, unless and until the copyright holder explicitly and 406 | finally terminates your license, and (b) permanently, if the copyright 407 | holder fails to notify you of the violation by some reasonable means 408 | prior to 60 days after the cessation. 409 | 410 | Moreover, your license from a particular copyright holder is 411 | reinstated permanently if the copyright holder notifies you of the 412 | violation by some reasonable means, this is the first time you have 413 | received notice of violation of this License (for any work) from that 414 | copyright holder, and you cure the violation prior to 30 days after 415 | your receipt of the notice. 416 | 417 | Termination of your rights under this section does not terminate the 418 | licenses of parties who have received copies or rights from you under 419 | this License. If your rights have been terminated and not permanently 420 | reinstated, you do not qualify to receive new licenses for the same 421 | material under section 10. 422 | 423 | 9. Acceptance Not Required for Having Copies. 424 | 425 | You are not required to accept this License in order to receive or 426 | run a copy of the Program. Ancillary propagation of a covered work 427 | occurring solely as a consequence of using peer-to-peer transmission 428 | to receive a copy likewise does not require acceptance. However, 429 | nothing other than this License grants you permission to propagate or 430 | modify any covered work. These actions infringe copyright if you do 431 | not accept this License. Therefore, by modifying or propagating a 432 | covered work, you indicate your acceptance of this License to do so. 433 | 434 | 10. Automatic Licensing of Downstream Recipients. 435 | 436 | Each time you convey a covered work, the recipient automatically 437 | receives a license from the original licensors, to run, modify and 438 | propagate that work, subject to this License. You are not responsible 439 | for enforcing compliance by third parties with this License. 440 | 441 | An "entity transaction" is a transaction transferring control of an 442 | organization, or substantially all assets of one, or subdividing an 443 | organization, or merging organizations. If propagation of a covered 444 | work results from an entity transaction, each party to that 445 | transaction who receives a copy of the work also receives whatever 446 | licenses to the work the party's predecessor in interest had or could 447 | give under the previous paragraph, plus a right to possession of the 448 | Corresponding Source of the work from the predecessor in interest, if 449 | the predecessor has it or can get it with reasonable efforts. 450 | 451 | You may not impose any further restrictions on the exercise of the 452 | rights granted or affirmed under this License. For example, you may 453 | not impose a license fee, royalty, or other charge for exercise of 454 | rights granted under this License, and you may not initiate litigation 455 | (including a cross-claim or counterclaim in a lawsuit) alleging that 456 | any patent claim is infringed by making, using, selling, offering for 457 | sale, or importing the Program or any portion of it. 458 | 459 | 11. Patents. 460 | 461 | A "contributor" is a copyright holder who authorizes use under this 462 | License of the Program or a work on which the Program is based. The 463 | work thus licensed is called the contributor's "contributor version". 464 | 465 | A contributor's "essential patent claims" are all patent claims 466 | owned or controlled by the contributor, whether already acquired or 467 | hereafter acquired, that would be infringed by some manner, permitted 468 | by this License, of making, using, or selling its contributor version, 469 | but do not include claims that would be infringed only as a 470 | consequence of further modification of the contributor version. For 471 | purposes of this definition, "control" includes the right to grant 472 | patent sublicenses in a manner consistent with the requirements of 473 | this License. 474 | 475 | Each contributor grants you a non-exclusive, worldwide, royalty-free 476 | patent license under the contributor's essential patent claims, to 477 | make, use, sell, offer for sale, import and otherwise run, modify and 478 | propagate the contents of its contributor version. 479 | 480 | In the following three paragraphs, a "patent license" is any express 481 | agreement or commitment, however denominated, not to enforce a patent 482 | (such as an express permission to practice a patent or covenant not to 483 | sue for patent infringement). To "grant" such a patent license to a 484 | party means to make such an agreement or commitment not to enforce a 485 | patent against the party. 486 | 487 | If you convey a covered work, knowingly relying on a patent license, 488 | and the Corresponding Source of the work is not available for anyone 489 | to copy, free of charge and under the terms of this License, through a 490 | publicly available network server or other readily accessible means, 491 | then you must either (1) cause the Corresponding Source to be so 492 | available, or (2) arrange to deprive yourself of the benefit of the 493 | patent license for this particular work, or (3) arrange, in a manner 494 | consistent with the requirements of this License, to extend the patent 495 | license to downstream recipients. "Knowingly relying" means you have 496 | actual knowledge that, but for the patent license, your conveying the 497 | covered work in a country, or your recipient's use of the covered work 498 | in a country, would infringe one or more identifiable patents in that 499 | country that you have reason to believe are valid. 500 | 501 | If, pursuant to or in connection with a single transaction or 502 | arrangement, you convey, or propagate by procuring conveyance of, a 503 | covered work, and grant a patent license to some of the parties 504 | receiving the covered work authorizing them to use, propagate, modify 505 | or convey a specific copy of the covered work, then the patent license 506 | you grant is automatically extended to all recipients of the covered 507 | work and works based on it. 508 | 509 | A patent license is "discriminatory" if it does not include within 510 | the scope of its coverage, prohibits the exercise of, or is 511 | conditioned on the non-exercise of one or more of the rights that are 512 | specifically granted under this License. You may not convey a covered 513 | work if you are a party to an arrangement with a third party that is 514 | in the business of distributing software, under which you make payment 515 | to the third party based on the extent of your activity of conveying 516 | the work, and under which the third party grants, to any of the 517 | parties who would receive the covered work from you, a discriminatory 518 | patent license (a) in connection with copies of the covered work 519 | conveyed by you (or copies made from those copies), or (b) primarily 520 | for and in connection with specific products or compilations that 521 | contain the covered work, unless you entered into that arrangement, 522 | or that patent license was granted, prior to 28 March 2007. 523 | 524 | Nothing in this License shall be construed as excluding or limiting 525 | any implied license or other defenses to infringement that may 526 | otherwise be available to you under applicable patent law. 527 | 528 | 12. No Surrender of Others' Freedom. 529 | 530 | If conditions are imposed on you (whether by court order, agreement or 531 | otherwise) that contradict the conditions of this License, they do not 532 | excuse you from the conditions of this License. If you cannot convey a 533 | covered work so as to satisfy simultaneously your obligations under this 534 | License and any other pertinent obligations, then as a consequence you may 535 | not convey it at all. For example, if you agree to terms that obligate you 536 | to collect a royalty for further conveying from those to whom you convey 537 | the Program, the only way you could satisfy both those terms and this 538 | License would be to refrain entirely from conveying the Program. 539 | 540 | 13. Remote Network Interaction; Use with the GNU General Public License. 541 | 542 | Notwithstanding any other provision of this License, if you modify the 543 | Program, your modified version must prominently offer all users 544 | interacting with it remotely through a computer network (if your version 545 | supports such interaction) an opportunity to receive the Corresponding 546 | Source of your version by providing access to the Corresponding Source 547 | from a network server at no charge, through some standard or customary 548 | means of facilitating copying of software. This Corresponding Source 549 | shall include the Corresponding Source for any work covered by version 3 550 | of the GNU General Public License that is incorporated pursuant to the 551 | following paragraph. 552 | 553 | Notwithstanding any other provision of this License, you have 554 | permission to link or combine any covered work with a work licensed 555 | under version 3 of the GNU General Public License into a single 556 | combined work, and to convey the resulting work. The terms of this 557 | License will continue to apply to the part which is the covered work, 558 | but the work with which it is combined will remain governed by version 559 | 3 of the GNU General Public License. 560 | 561 | 14. Revised Versions of this License. 562 | 563 | The Free Software Foundation may publish revised and/or new versions of 564 | the GNU Affero General Public License from time to time. Such new versions 565 | will be similar in spirit to the present version, but may differ in detail to 566 | address new problems or concerns. 567 | 568 | Each version is given a distinguishing version number. If the 569 | Program specifies that a certain numbered version of the GNU Affero General 570 | Public License "or any later version" applies to it, you have the 571 | option of following the terms and conditions either of that numbered 572 | version or of any later version published by the Free Software 573 | Foundation. If the Program does not specify a version number of the 574 | GNU Affero General Public License, you may choose any version ever published 575 | by the Free Software Foundation. 576 | 577 | If the Program specifies that a proxy can decide which future 578 | versions of the GNU Affero General Public License can be used, that proxy's 579 | public statement of acceptance of a version permanently authorizes you 580 | to choose that version for the Program. 581 | 582 | Later license versions may give you additional or different 583 | permissions. However, no additional obligations are imposed on any 584 | author or copyright holder as a result of your choosing to follow a 585 | later version. 586 | 587 | 15. Disclaimer of Warranty. 588 | 589 | THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY 590 | APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT 591 | HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY 592 | OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, 593 | THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 594 | PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM 595 | IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF 596 | ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 597 | 598 | 16. Limitation of Liability. 599 | 600 | IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING 601 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS 602 | THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY 603 | GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE 604 | USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF 605 | DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD 606 | PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), 607 | EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF 608 | SUCH DAMAGES. 609 | 610 | 17. Interpretation of Sections 15 and 16. 611 | 612 | If the disclaimer of warranty and limitation of liability provided 613 | above cannot be given local legal effect according to their terms, 614 | reviewing courts shall apply local law that most closely approximates 615 | an absolute waiver of all civil liability in connection with the 616 | Program, unless a warranty or assumption of liability accompanies a 617 | copy of the Program in return for a fee. 618 | 619 | END OF TERMS AND CONDITIONS 620 | 621 | How to Apply These Terms to Your New Programs 622 | 623 | If you develop a new program, and you want it to be of the greatest 624 | possible use to the public, the best way to achieve this is to make it 625 | free software which everyone can redistribute and change under these terms. 626 | 627 | To do so, attach the following notices to the program. It is safest 628 | to attach them to the start of each source file to most effectively 629 | state the exclusion of warranty; and each file should have at least 630 | the "copyright" line and a pointer to where the full notice is found. 631 | 632 | 633 | Copyright (C) 634 | 635 | This program is free software: you can redistribute it and/or modify 636 | it under the terms of the GNU Affero General Public License as published 637 | by the Free Software Foundation, either version 3 of the License, or 638 | (at your option) any later version. 639 | 640 | This program is distributed in the hope that it will be useful, 641 | but WITHOUT ANY WARRANTY; without even the implied warranty of 642 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 643 | GNU Affero General Public License for more details. 644 | 645 | You should have received a copy of the GNU Affero General Public License 646 | along with this program. If not, see . 647 | 648 | Also add information on how to contact you by electronic and paper mail. 649 | 650 | If your software can interact with users remotely through a computer 651 | network, you should also make sure that it provides a way for users to 652 | get its source. For example, if your program is a web application, its 653 | interface could display a "Source" link that leads users to an archive 654 | of the code. There are many ways you could offer source, and different 655 | solutions will be better for different programs; see section 13 for the 656 | specific requirements. 657 | 658 | You should also get your employer (if you work as a programmer) or school, 659 | if any, to sign a "copyright disclaimer" for the program, if necessary. 660 | For more information on this, and how to apply and follow the GNU AGPL, see 661 | . 662 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # DeepSurf 2 | A surface-based deep learning approach for the prediction of ligand binding sites on proteins (https://doi.org/10.1093/bioinformatics/btab009) 3 | 4 | Setup 5 | --------------- 6 | 7 | Experiments were conducted on an Ubuntu 18.04 machine with Python 3.6.9 and CUDA 10.0 8 | 9 | 1) Install dependencies 10 | ``` 11 | sudo apt-get update && apt-get install python3-venv, p7zip, swig, libopenbabel-dev, g++ 12 | ``` 13 | 2) Clone this repository 14 | ``` 15 | git clone https://github.com/stemylonas/DeepSurf 16 | cd DeepSurf 17 | ``` 18 | 3) Create environment and install python dependencies 19 | ``` 20 | python3 -m venv venv --prompt DeepSurf 21 | source venv/bin/activate 22 | pip install -r requirements.txt 23 | ``` 24 | 4) Compile custom LDS module 25 | ``` 26 | cd lds 27 | chmod a+x compile.sh 28 | ./compile.sh 29 | cd .. 30 | ``` 31 | 5) Download pretrained models 32 | ``` 33 | pip install gdown 34 | gdown 1nIBoD3_5nuMqgRGx4G1OHZwLsiUjb7JG 35 | p7zip -d models.7z 36 | ``` 37 | 6) Collect and install DMS 38 | ``` 39 | wget www.cgl.ucsf.edu/Overview/ftp/dms.zip 40 | unzip dms.zip 41 | rm dms.zip 42 | cd dms 43 | sudo make install 44 | cd .. 45 | ``` 46 | 47 | Usage example 48 | --------------- 49 | 50 | ``` 51 | python predict.py -p protein.pdb -mp model_path -o output_path 52 | ``` 53 | 54 | For more input options, check 'predict.py'. All other molecules (waters, ions, ligands) should be removed from the structure. If the input protein has not been protonated, add --protonate to the execution command.\ 55 | The provided models have been trained on a subset of scPDB (training_subset_of_scpdb.proteins) 56 | -------------------------------------------------------------------------------- /bsite_extraction.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python2 2 | # -*- coding: utf-8 -*- 3 | """ 4 | Created on Thu Jan 30 16:00:46 2020 5 | 6 | @author: smylonas 7 | """ 8 | 9 | import numpy as np 10 | from sklearn.cluster import MeanShift 11 | 12 | 13 | class Bsite_extractor(): 14 | def __init__(self,lig_thres,bw=15): 15 | self.T = lig_thres 16 | self.ms = MeanShift(bandwidth=bw,bin_seeding=True,cluster_all=False,n_jobs=4) 17 | 18 | def _cluster_points(self,prot,lig_scores): 19 | T_new = self.T 20 | while sum(lig_scores>=T_new) < 10 and T_new>0.3001: # at least 10 points with prob>P and P>=0.3 21 | T_new -= 0.1 22 | 23 | filtered_points = prot.surf_points[lig_scores>T_new] 24 | filtered_scores = lig_scores[lig_scores>T_new] 25 | if len(filtered_points)<5: 26 | return () 27 | 28 | clustering = self.ms.fit(filtered_points) 29 | labels = clustering.labels_ 30 | 31 | unique_l,freq = np.unique(labels,return_counts=True) 32 | 33 | if len(unique_l[freq>=5])!=0: 34 | unique_l = unique_l[freq>=5] # keep clusters with 5 points and more 35 | else: 36 | return () 37 | 38 | if unique_l[0]==-1: # discard the "unclustered" cluster 39 | unique_l = unique_l[1:] 40 | 41 | clusters = [(filtered_points[labels==l],filtered_scores[labels==l]) for l in unique_l] 42 | 43 | return clusters 44 | 45 | def extract_bsites(self,prot,lig_scores): 46 | clusters = self._cluster_points(prot,lig_scores) 47 | if len(clusters)==0: 48 | print('No binding site found') 49 | return 50 | for cluster in clusters: 51 | prot.add_bsite(cluster) 52 | prot.sort_bsites() 53 | prot.write_bsites() 54 | 55 | 56 | -------------------------------------------------------------------------------- /features.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python2 2 | # -*- coding: utf-8 -*- 3 | """ 4 | Created on Mon Oct 21 11:46:54 2019 5 | 6 | @author: smylonas 7 | """ 8 | 9 | import tfbio_data 10 | from utils import rotation 11 | import numpy as np 12 | 13 | 14 | class KalasantyFeaturizer: 15 | def __init__(self,gridSize,voxelSize): 16 | grid_limit = (gridSize/2-0.5)*voxelSize 17 | grid_radius = grid_limit*np.sqrt(3) 18 | self.neigh_radius = 4 + grid_radius # 4 > 2*R_vdw 19 | self.featurizer = tfbio_data.Featurizer(save_molecule_codes=False) 20 | self.grid_resolution = voxelSize 21 | self.max_dist = (gridSize-1)*voxelSize/2 22 | 23 | def get_channels(self,mol): 24 | _, self.channels = self.featurizer.get_features(mol) # returns only heavy atoms 25 | 26 | def grid_feats(self,point,normal,mol_coords): 27 | neigh_atoms = np.sqrt(np.sum((mol_coords-point)**2,axis=1)) dim(5); 17 | DimensionHandle dimtemp; 18 | 19 | dim[0] = c->Dim(c->input(0),0); 20 | dim[4] = c->Dim(c->input(0),4); 21 | 22 | c->Subtract(c->Dim(c->input(0),1), 2, &dimtemp); 23 | c->Multiply(dimtemp, 3, &dim[1]); 24 | 25 | c->Subtract(c->Dim(c->input(0),2), 2, &dimtemp); 26 | c->Multiply(dimtemp, 3, &dim[2]); 27 | 28 | c->Subtract(c->Dim(c->input(0),3), 2, &dimtemp); 29 | c->Multiply(dimtemp, 3, &dim[3]); 30 | 31 | ShapeHandle outputShape = c->MakeShape(dim); 32 | 33 | c->set_output(0, outputShape); 34 | return tensorflow::Status::OK(); 35 | }) 36 | ; 37 | 38 | 39 | void AmulKernelLauncher(const float* input, const float* weight, float* output, const int batchSize, 40 | const int input_xSize, const int input_ySize, const int input_zSize, const int numChannels); 41 | 42 | class AmulOp : public OpKernel { 43 | public: 44 | explicit AmulOp(OpKernelConstruction* context) : OpKernel(context) {} 45 | 46 | void Compute(OpKernelContext* context) override { 47 | 48 | // Grab the input tensor 49 | const Tensor& input_tensor = context->input(0); 50 | auto input_flat = input_tensor.flat(); 51 | 52 | const Tensor& weight_tensor = context->input(1); 53 | auto weight = weight_tensor.flat(); 54 | 55 | 56 | int batchSize = input_tensor.shape().dim_size(0); 57 | int input_xSize = input_tensor.shape().dim_size(1); 58 | int input_ySize = input_tensor.shape().dim_size(2); 59 | int input_zSize = input_tensor.shape().dim_size(3); 60 | int numChannels = input_tensor.shape().dim_size(4); 61 | 62 | //int N = batchSize * input_xSize * input_ySize * numChannels; 63 | 64 | //printf("\n\n%d %d %d %d \n\n", batchSize,input_xSize, input_ySize, numChannels); 65 | 66 | TensorShape output_tensor_shape; 67 | 68 | output_tensor_shape.AddDim(batchSize); 69 | output_tensor_shape.AddDim(3 * (input_xSize - 2)); 70 | output_tensor_shape.AddDim(3 * (input_ySize - 2)); 71 | output_tensor_shape.AddDim(3 * (input_zSize - 2)); 72 | 73 | output_tensor_shape.AddDim(numChannels); 74 | 75 | // Create an output tensor 76 | Tensor* output_tensor = nullptr; 77 | OP_REQUIRES_OK(context, context->allocate_output(0, output_tensor_shape, &output_tensor)); 78 | auto output_flat = output_tensor->template flat(); 79 | 80 | // Call the cuda kernel launcher 81 | AmulKernelLauncher(input_flat.data(), weight.data(), output_flat.data(), batchSize, input_xSize, input_ySize, input_zSize, numChannels); 82 | 83 | } 84 | }; 85 | 86 | REGISTER_KERNEL_BUILDER(Name("Amul").Device(DEVICE_GPU), AmulOp); 87 | -------------------------------------------------------------------------------- /lds/amul_kernel_cube.cu.cc: -------------------------------------------------------------------------------- 1 | /* Copyright 2015 The TensorFlow Authors. All Rights Reserved. 2 | Licensed under the Apache License, Version 2.0 (the "License"); 3 | you may not use this file except in compliance with the License. 4 | You may obtain a copy of the License at 5 | http://www.apache.org/licenses/LICENSE-2.0 6 | Unless required by applicable law or agreed to in writing, software 7 | distributed under the License is distributed on an "AS IS" BASIS, 8 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 9 | See the License for the specific language governing permissions and 10 | limitations under the License. 11 | ==============================================================================*/ 12 | 13 | #if GOOGLE_CUDA 14 | #define EIGEN_USE_GPU 15 | #include "third_party/eigen3/unsupported/Eigen/CXX11/Tensor" 16 | 17 | 18 | 19 | __global__ void AmulKernel(const float* input, const float* weight, float* output, const int batchSize, 20 | const int input_xSize, const int input_ySize, const int input_zSize, const int numChannels) { 21 | //int blockDim = 10; 22 | 23 | int b = blockIdx.x/numChannels; 24 | int ch = blockIdx.x - b * numChannels; 25 | 26 | int x = threadIdx.x; 27 | int y = blockIdx.y * blockDim.y + threadIdx.y; 28 | int z = blockIdx.z * blockDim.z + threadIdx.z; 29 | //printf("%d %d %d",x,y,z); 30 | extern __shared__ float mem[]; 31 | float y0; 32 | const float* weight_start; 33 | 34 | int inputBatchStride = b * input_xSize * input_ySize * input_zSize * numChannels; 35 | for (int j=0; j>>(input, weight, output, batchSize, input_xSize, input_ySize, input_zSize, numChannels); 94 | 95 | } 96 | 97 | #endif 98 | -------------------------------------------------------------------------------- /lds/amul_kernel_cube_grad.cc: -------------------------------------------------------------------------------- 1 | /* Copyright 2015 The TensorFlow Authors. All Rights Reserved. 2 | Licensed under the Apache License, Version 2.0 (the "License"); 3 | you may not use this file except in compliance with the License. 4 | You may obtain a copy of the License at 5 | http://www.apache.org/licenses/LICENSE-2.0 6 | Unless required by applicable law or agreed to in writing, software 7 | distributed under the License is distributed on an "AS IS" BASIS, 8 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 9 | See the License for the specific language governing permissions and 10 | limitations under the License. 11 | ==============================================================================*/ 12 | 13 | #include "tensorflow/core/framework/op.h" 14 | #include "tensorflow/core/framework/op_kernel.h" 15 | #include "tensorflow/core/framework/shape_inference.h" 16 | 17 | using namespace tensorflow; // NOLINT(build/namespaces) 18 | 19 | REGISTER_OP("AmulBackward") 20 | .Input("input: float") 21 | .Input("weight: float") 22 | .Input("grad_output: float") 23 | .Output("grad_input: float") 24 | .Output("grad_weight: float") 25 | .SetShapeFn([](shape_inference::InferenceContext* c) { 26 | c->set_output(0, c->input(0)); 27 | c->set_output(1, c->input(1)); 28 | return Status::OK(); 29 | }) 30 | ; 31 | 32 | void AmulBackwardKernelLauncher(const float* input, const float* weight, const float* gradOutput, float* gradInput, float* gradWeight, 33 | const int batchSize, const int input_xSize, const int input_ySize, const int input_zSize, const int numChannels); 34 | 35 | class AmulBackwardOp : public OpKernel { 36 | public: 37 | explicit AmulBackwardOp(OpKernelConstruction* context) : OpKernel(context) {} 38 | 39 | void Compute(OpKernelContext* context) override { 40 | 41 | // Grab the input tensor 42 | 43 | const Tensor& input_tensor = context->input(0); 44 | auto input = input_tensor.flat(); 45 | 46 | const Tensor& weight_tensor = context->input(1); 47 | auto weight = weight_tensor.flat(); 48 | 49 | const Tensor& grad_output_tensor = context->input(2); 50 | auto grad_output = grad_output_tensor.flat(); 51 | 52 | 53 | // calculate output tensor shape 54 | 55 | int batchSize = input_tensor.shape().dim_size(0); 56 | int input_xSize = input_tensor.shape().dim_size(1); 57 | int input_ySize = input_tensor.shape().dim_size(2); 58 | int input_zSize = input_tensor.shape().dim_size(3); 59 | int numChannels = input_tensor.shape().dim_size(4); 60 | 61 | // Create an output tensor 62 | Tensor* gradInput_tensor = nullptr; 63 | OP_REQUIRES_OK(context, context->allocate_output(0, input_tensor.shape(), &gradInput_tensor)); 64 | auto grad_input = gradInput_tensor->template flat(); 65 | 66 | //TensorShape gradWeight_shape; 67 | //gradWeight_shape.AddDim(numChannels); 68 | //gradWeight_shape.AddDim(3); 69 | //gradWeight_shape.AddDim(3); 70 | Tensor* gradWeight_tensor = nullptr; 71 | OP_REQUIRES_OK(context, context->allocate_output(1, weight_tensor.shape(), &gradWeight_tensor)); 72 | auto grad_weight = gradWeight_tensor->template flat(); 73 | 74 | // Call the cuda kernel launcher 75 | AmulBackwardKernelLauncher(input.data(), weight.data(), grad_output.data(), grad_input.data(), grad_weight.data(), batchSize, input_xSize, input_ySize, input_zSize, numChannels); 76 | 77 | } 78 | }; 79 | 80 | REGISTER_KERNEL_BUILDER(Name("AmulBackward").Device(DEVICE_GPU), AmulBackwardOp); 81 | -------------------------------------------------------------------------------- /lds/amul_kernel_cube_grad.cu.cc: -------------------------------------------------------------------------------- 1 | 2 | #include "stdio.h" 3 | 4 | #if GOOGLE_CUDA 5 | #define EIGEN_USE_GPU 6 | #include "third_party/eigen3/unsupported/Eigen/CXX11/Tensor" 7 | 8 | __global__ void AmulBackwardInputKernel(const float* weight, const float* gradOutput, float* gradInput, const int batchSize, 9 | const int gradInput_xSize, const int gradInput_ySize, const int gradInput_zSize, const int numChannels) { 10 | 11 | // int blockDim = 10; 12 | 13 | int b = blockIdx.x/numChannels; 14 | int ch = blockIdx.x - b * numChannels; 15 | 16 | int x = threadIdx.x; 17 | int y = blockIdx.y * blockDim.y + threadIdx.y; 18 | int z = blockIdx.z * blockDim.z + threadIdx.z; 19 | 20 | int gradInputBatchStride = b * gradInput_xSize * gradInput_ySize * gradInput_zSize * numChannels; 21 | 22 | int gradOutput_xSize = (gradInput_xSize-2) * 3; 23 | int gradOutput_ySize = (gradInput_ySize-2) * 3; 24 | int gradOutput_zSize = (gradInput_zSize-2) * 3; 25 | 26 | int gradOutputBatchStride = b * gradOutput_xSize * gradOutput_ySize * gradOutput_zSize * numChannels; 27 | 28 | if (x < (gradInput_xSize-2) && y < (gradInput_ySize-2) && z < (gradInput_zSize-2)) { 29 | 30 | float grad_y[27], temp; 31 | int i,j,k,l; 32 | for (i=0; i<3; i++) 33 | for (j=0; j<3; j++) 34 | for (k=0; k<3; k++) 35 | grad_y[9*i+3*j+k] = gradOutput[gradOutputBatchStride + ((3*x+i)*gradOutput_ySize*gradOutput_zSize + (3*y+j)*gradOutput_zSize + (3*z+k))*numChannels + ch]; 36 | 37 | const float* weight_start; 38 | float* gradInputAddr = gradInput + gradInputBatchStride + (x*gradInput_ySize*gradInput_zSize + y*gradInput_zSize + z)*numChannels + ch; 39 | 40 | for (i=0; i<3; i++) 41 | for (j=0; j<3; j++) 42 | for (k=0; k<3; k++){ 43 | weight_start = weight + 9*i + 3*j + k; 44 | 45 | temp = 0; 46 | for(l=0; l<27; l++) 47 | temp += *(weight_start+27*l) * grad_y[l]; 48 | 49 | atomicAdd(gradInputAddr+(i*gradInput_ySize*gradInput_zSize+j*gradInput_zSize+k)*numChannels, temp); 50 | } 51 | } 52 | 53 | 54 | } 55 | 56 | 57 | __global__ void ZeroGradInputKernel(float *gradInput, int N){ 58 | 59 | for (int i=threadIdx.x; i>>(gradInput, batchSize*input_xSize*input_ySize*input_zSize*numChannels); 216 | 217 | cudaDeviceSynchronize(); 218 | 219 | float *gradWblocks; 220 | int k = maxThreads; 221 | cudaMalloc(&gradWblocks, k*27*27*sizeof(float)); 222 | 223 | ZeroGradWeightKernel<<<1,27*27>>>(gradWeight, gradWblocks, 27*27, k); 224 | 225 | cudaDeviceSynchronize(); 226 | 227 | dim3 blockSize(input_xSize, ny, nz); 228 | 229 | int blockY = (input_ySize+ny-1)/ny; 230 | int blockZ = (input_zSize+nz-1)/nz; 231 | 232 | dim3 gridSize(batchSize*numChannels, blockY, blockZ); 233 | 234 | cudaEventCreate(&start1); 235 | cudaEventCreate(&stop1); 236 | cudaEventRecord(start1,0); 237 | AmulBackwardInputKernel<<>>(weight, gradOutput, gradInput, batchSize, input_xSize, input_ySize, input_zSize, numChannels); 238 | 239 | cudaDeviceSynchronize(); 240 | 241 | cudaEventRecord(stop1,0); 242 | cudaEventSynchronize(stop1); 243 | cudaEventElapsedTime(&time1, start1, stop1) ; 244 | cudaEventCreate(&start2); 245 | cudaEventCreate(&stop2); 246 | cudaEventRecord(start2,0); 247 | int nblocks = batchSize*numChannels*blockY*blockZ; 248 | //float gradWblocks[27*27*nblocks]; 249 | 250 | 251 | // int maxSharedMem = prop.sharedMemPerBlock; 252 | //int k = (maxSharedMem/sizeof(float)-input_xSize*(ny+2)*(nz+2))/(27*27); 253 | 254 | // printf("k=%d\n",k); 255 | //if ((27*27*k+input_xSize*(ny+2)*(nz+2))*sizeof(float)>maxSharedMem) 256 | // printf("dsaasa\n\n"); 257 | AmulBackwardWeightKernel<<>>(input, gradOutput, gradWblocks, batchSize, input_xSize, input_ySize, input_zSize, numChannels, k); 258 | 259 | cudaDeviceSynchronize(); 260 | 261 | cudaEventRecord(stop2,0); 262 | cudaEventSynchronize(stop2); 263 | cudaEventElapsedTime(&time2, start2, stop2) ; 264 | // printf("Time1: %3.2f ms \t\t Time2: %3.2f ms, Dims (%dx%dx%d), Blocks %d \n", time1, time2, input_xSize, ny, nz, nblocks); 265 | AggregationWeightKernel<<<1,27*27>>>(gradWeight, gradWblocks, 27*27, k); 266 | cudaFree(gradWblocks); 267 | } 268 | 269 | #endif 270 | -------------------------------------------------------------------------------- /lds/compile.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | TF_INC=$(python -c 'import tensorflow as tf; print(tf.sysconfig.get_include())') 4 | TF_LIB=$(python -c 'import tensorflow as tf; print(tf.sysconfig.get_lib())') 5 | 6 | NVCC_FLAGS="-std=c++11 -I$TF_INC -D GOOGLE_CUDA=1 -x cu -gencode arch=compute_61,code=sm_61 -Xcompiler -fPIC -O3 --expt-relaxed-constexpr -lprotobuf" 7 | GCC_FLAGS="-std=c++11 -shared -I$TF_INC -fPIC -L$TF_LIB -ltensorflow_framework" 8 | 9 | G_VERSION="$(g++ -dumpversion)" 10 | compared_ver="5.0.0" 11 | 12 | if [ "$(printf '%s\n' "$compared_ver" "$G_VERSION" | sort -V | head -n1)" = "$compared_ver" ]; then 13 | GCC_FLAGS+=" -D_GLIBCXX_USE_CXX11_ABI=0" 14 | fi 15 | 16 | mkdir -p lib 17 | 18 | #### FORWARD 19 | 20 | nvcc -c amul_kernel_cube.cu.cc -o lib/amul_kernel_cube.cu.o $NVCC_FLAGS 21 | 22 | g++ amul_kernel_cube.cc -o lib/amul_kernel_cube.so lib/amul_kernel_cube.cu.o $GCC_FLAGS 23 | 24 | #### GRAD 25 | 26 | nvcc -c amul_kernel_cube_grad.cu.cc -o lib/amul_kernel_cube_grad.cu.o $NVCC_FLAGS 27 | 28 | g++ amul_kernel_cube_grad.cc -o lib/amul_kernel_cube_grad.so lib/amul_kernel_cube_grad.cu.o $GCC_FLAGS 29 | -------------------------------------------------------------------------------- /multi_predict.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python2 2 | # -*- coding: utf-8 -*- 3 | """ 4 | Created on Tue Feb 25 16:04:47 2020 5 | 6 | @author: smylonas 7 | """ 8 | 9 | import argparse, os, time 10 | from network import Network 11 | from protein import Protein 12 | from bsite_extraction import Bsite_extractor 13 | from tqdm import tqdm 14 | 15 | 16 | def parse_args(): 17 | parser = argparse.ArgumentParser(formatter_class=argparse.ArgumentDefaultsHelpFormatter) 18 | 19 | parser.add_argument('--dataset_file', '-d', required=True, help='dataset file with protein names') 20 | parser.add_argument('--protein_path', '-pp', required=True, help='directory of protein files') 21 | parser.add_argument('--model_path', '-mp', required=True, help='directory of models') 22 | parser.add_argument('--model', '-m', choices=['orig','lds'], default='orig', help='select model') 23 | parser.add_argument('--output', '-o', required=True, help='name of the output directory') 24 | parser.add_argument('--f', type=int, default=10, help='parameter for the simplification of points mesh') 25 | parser.add_argument('--T', type=float, default=0.9, help='ligandability threshold') 26 | parser.add_argument('--batch', type=int, default=32, help='batch size') 27 | parser.add_argument('--voxel_size', type=float, default=1.0, help='size of voxel in angstrom') 28 | parser.add_argument('--protonate', action='store_true', help='whether to protonate or not the input protein') 29 | parser.add_argument('--expand', action='store_true', help='whether to expand on residue level the extracted binding sites') 30 | parser.add_argument('--discard_points', action='store_true', help='whether to output or not the computed surface points') 31 | parser.add_argument('--seed', type=int, default=None, help='random seed for KMeans clustering') 32 | 33 | return parser.parse_args() 34 | 35 | 36 | args = parse_args() 37 | 38 | if not os.path.exists(args.protein_path): 39 | raise IOError('%s does not exist.' % args.protein_path) 40 | if not os.path.exists(args.model_path): 41 | raise IOError('%s does not exist.' % args.model_path) 42 | if not os.path.exists(args.output): 43 | os.makedirs(args.output) 44 | 45 | st = time.time() 46 | 47 | with open(args.dataset_file,'r') as f: 48 | lines = f.readlines() 49 | 50 | protein_names = [line.strip() for line in lines if line!='\n'] 51 | 52 | nn = Network(args.model_path, args.model, args.voxel_size) 53 | extractor = Bsite_extractor(args.T) 54 | 55 | for prot in tqdm(protein_names): 56 | print(prot) 57 | protein = Protein(os.path.join(args.protein_path,prot+'.pdb'), args.protonate, args.expand, args.f, args.output, args.discard_points, args.seed) 58 | 59 | lig_scores = nn.get_lig_scores(protein, args.batch) 60 | 61 | extractor.extract_bsites(protein, lig_scores) 62 | 63 | print('Total time:', time.time()-st) 64 | -------------------------------------------------------------------------------- /net/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stemylonas/DeepSurf/ff2f85d4d3466bc770e86394fe77daa81eef3363/net/__init__.py -------------------------------------------------------------------------------- /net/resnet_3d.py: -------------------------------------------------------------------------------- 1 | """ 2 | Created on Thu Nov 1 12:04:04 2018 3 | 4 | @author: smylonas 5 | """ 6 | 7 | import tensorflow as tf 8 | from tensorflow.contrib import layers 9 | from tensorflow.contrib.framework.python.ops import add_arg_scope 10 | from tensorflow.contrib.framework.python.ops import arg_scope 11 | from tensorflow.contrib.layers.python.layers import layers as layers_lib 12 | from tensorflow.contrib.layers.python.layers import utils 13 | from tensorflow.python.ops import math_ops 14 | from tensorflow.python.ops import nn_ops 15 | from tensorflow.python.ops import variable_scope 16 | from net import resnet_3d_utils 17 | 18 | resnet_arg_scope = resnet_3d_utils.resnet_arg_scope 19 | 20 | 21 | @add_arg_scope 22 | def resid_unit(inputs, 23 | depth, 24 | depth_bottleneck, 25 | stride, 26 | rate=1, 27 | outputs_collections=None, 28 | scope=None): 29 | """Residual unit with BN after convolutions. 30 | This is the original residual unit proposed in [1]. See Fig. 1(a) of [2] for 31 | its definition. 32 | When putting together two consecutive ResNet blocks that use this unit, one 33 | should use stride = 2 in the last unit of the first block. 34 | Args: 35 | inputs: A tensor of size [batch, height, width, channels]. 36 | depth: The depth of the ResNet unit output. 37 | depth_bottleneck: The depth of the bottleneck layers. 38 | stride: The ResNet unit's stride. Determines the amount of downsampling of 39 | the units output compared to its input. 40 | rate: An integer, rate for atrous convolution. 41 | outputs_collections: Collection to add the ResNet unit output. 42 | scope: Optional variable_scope. 43 | Returns: 44 | The ResNet unit's output. 45 | """ 46 | with variable_scope.variable_scope(scope, 'resid_v1', [inputs]) as sc: 47 | # print (inputs.shape) 48 | depth_in = utils.last_dimension(inputs.get_shape(), min_rank=5) 49 | if depth == depth_in: 50 | shortcut = resnet_3d_utils.subsample(inputs, stride, 'shortcut') 51 | else: 52 | shortcut = layers.conv3d( 53 | inputs, 54 | depth, [1, 1, 1], 55 | stride=stride, 56 | activation_fn=None, 57 | scope='shortcut') 58 | 59 | residual = resnet_3d_utils.conv3d_same(inputs, depth_bottleneck, 3, stride=1, scope='conv1') 60 | residual = layers.conv3d(residual, depth_bottleneck, 3, stride, scope='conv2') 61 | 62 | output = nn_ops.relu(shortcut + residual) 63 | 64 | return utils.collect_named_outputs(outputs_collections, sc.name, output) 65 | 66 | 67 | def resnet_v1(inputs, 68 | blocks, 69 | num_classes=None, 70 | is_training=True, 71 | global_pool=True, 72 | output_stride=None, 73 | include_root_block=True, 74 | reuse=None, 75 | scope=None): 76 | """Generator for v1 ResNet models. 77 | Args: 78 | inputs: A tensor of size [batch, height_in, width_in, channels]. 79 | blocks: A list of length equal to the number of ResNet blocks. Each element 80 | is a resnet_utils.Block object describing the units in the block. 81 | num_classes: Number of predicted classes for classification tasks. If None 82 | we return the features before the logit layer. 83 | is_training: whether batch_norm layers are in training mode. 84 | global_pool: If True, we perform global average pooling before computing the 85 | logits. Set to True for image classification, False for dense prediction. 86 | output_stride: If None, then the output will be computed at the nominal 87 | network stride. If output_stride is not None, it specifies the requested 88 | ratio of input to output spatial resolution. 89 | include_root_block: If True, include the initial convolution followed by 90 | max-pooling, if False excludes it. 91 | reuse: whether or not the network and its variables should be reused. To be 92 | able to reuse 'scope' must be given. 93 | scope: Optional variable_scope. 94 | Returns: 95 | net: A rank-4 tensor of size [batch, height_out, width_out, channels_out]. 96 | If global_pool is False, then height_out and width_out are reduced by a 97 | factor of output_stride compared to the respective height_in and width_in, 98 | else both height_out and width_out equal one. If num_classes is None, then 99 | net is the output of the last ResNet block, potentially after global 100 | average pooling. If num_classes is not None, net contains the pre-softmax 101 | activations. 102 | end_points: A dictionary from components of the network to the corresponding 103 | activation. 104 | Raises: 105 | ValueError: If the target output_stride is not valid. 106 | """ 107 | with variable_scope.variable_scope( 108 | scope, 'resnet_v1', [inputs], reuse=reuse) as sc: 109 | end_points_collection = sc.original_name_scope + '_end_points' 110 | with arg_scope( 111 | [layers.conv3d, resid_unit, resnet_3d_utils.stack_blocks_dense], 112 | outputs_collections=end_points_collection): 113 | with arg_scope([layers.batch_norm], is_training=is_training): 114 | net = inputs 115 | net = resnet_3d_utils.stack_blocks_dense(net, blocks, output_stride) 116 | if global_pool: 117 | net = math_ops.reduce_mean(net, [1, 2, 3], name='pool5', keepdims=True) 118 | if num_classes is not None: 119 | net = layers.conv3d( 120 | net, 121 | num_classes, [1, 1, 1], 122 | activation_fn=None, 123 | normalizer_fn=None, 124 | scope='logits') 125 | 126 | # Convert end_points_collection into a dictionary of end_points. 127 | end_points = utils.convert_collection_to_dict(end_points_collection) 128 | if num_classes is not None and num_classes != 1: 129 | end_points['predictions'] = layers_lib.softmax(net, scope='predictions') 130 | net = tf.squeeze(net) 131 | elif num_classes == 1: 132 | net = tf.squeeze(net) 133 | end_points['probs'] = tf.nn.sigmoid(net) 134 | 135 | return net, end_points 136 | 137 | 138 | def resnet_v1_block(scope, depth_out, num_units, stride): 139 | """Args: 140 | scope: The scope of the block. 141 | base_depth: The depth of the bottleneck layer for each unit. 142 | num_units: The number of units in the block. 143 | stride: The stride of the block, implemented as a stride in the last unit. 144 | All other units have stride=1. 145 | Returns: 146 | A resnet_v1 bottleneck block. 147 | """ 148 | return resnet_3d_utils.Block(scope, resid_unit, [{ 149 | 'depth': depth_out, 150 | 'depth_bottleneck': depth_out, 151 | 'stride': 1 152 | }] * (num_units - 1) + [{ 153 | 'depth': depth_out, 154 | 'depth_bottleneck': depth_out, 155 | 'stride': stride 156 | }]) 157 | 158 | 159 | def resnet_v1_18(inputs, 160 | num_classes, 161 | is_training, 162 | global_pool=True, 163 | output_stride=None, 164 | reuse=None, 165 | scope='resnet3d_v1_18'): 166 | blocks = [ 167 | resnet_v1_block('block1', depth_out=64, num_units=2, stride=2), 168 | resnet_v1_block('block2', depth_out=128, num_units=2, stride=2), 169 | resnet_v1_block('block3', depth_out=256, num_units=2, stride=2), 170 | resnet_v1_block('block4', depth_out=512, num_units=2, stride=1) 171 | ] 172 | return resnet_v1( 173 | inputs, 174 | blocks, 175 | num_classes, 176 | is_training, 177 | global_pool, 178 | output_stride, 179 | include_root_block=False, 180 | reuse=reuse, 181 | scope=scope) 182 | 183 | -------------------------------------------------------------------------------- /net/resnet_3d_utils.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python2 2 | # -*- coding: utf-8 -*- 3 | """ 4 | Created on Thu Nov 1 17:04:52 2018 5 | 6 | @author: smylonas 7 | """ 8 | 9 | 10 | 11 | 12 | 13 | import collections, numpy as np 14 | 15 | from tensorflow.contrib import layers as layers_lib 16 | from tensorflow.contrib.framework import deprecated_args 17 | from tensorflow.contrib.framework.python.ops import add_arg_scope 18 | from tensorflow.contrib.framework.python.ops import arg_scope 19 | from tensorflow.contrib.layers.python.layers import initializers 20 | from tensorflow.contrib.layers.python.layers import layers 21 | from tensorflow.contrib.layers.python.layers import regularizers 22 | from tensorflow.contrib.layers.python.layers import utils 23 | from tensorflow.python.framework import ops 24 | from tensorflow.python.ops import array_ops 25 | from tensorflow.python.ops import nn_ops 26 | from tensorflow.python.ops import variable_scope 27 | import tensorflow as tf 28 | 29 | 30 | class Block(collections.namedtuple('Block', ['scope', 'unit_fn', 'args'])): 31 | """A named tuple describing a ResNet block. 32 | 33 | Its parts are: 34 | scope: The scope of the `Block`. 35 | unit_fn: The ResNet unit function which takes as input a `Tensor` and 36 | returns another `Tensor` with the output of the ResNet unit. 37 | args: A list of length equal to the number of units in the `Block`. The list 38 | contains one (depth, depth_bottleneck, stride) tuple for each unit in the 39 | block to serve as argument to unit_fn. 40 | """ 41 | 42 | 43 | def subsample(inputs, factor, scope=None): 44 | """Subsamples the input along the spatial dimensions. 45 | 46 | Args: 47 | inputs: A `Tensor` of size [batch, height_in, width_in, channels]. 48 | factor: The subsampling factor. 49 | scope: Optional variable_scope. 50 | 51 | Returns: 52 | output: A `Tensor`with the input, either intact (if factor == 1) or subsampled (if factor > 1). 53 | """ 54 | if factor == 1: 55 | return inputs 56 | else: 57 | return layers.max_pool3d(inputs, 1, stride=factor, scope=scope) 58 | 59 | 60 | def conv3d_same(inputs, num_outputs, kernel_size, stride, rate=1, scope=None, outputs_collections=None): 61 | """Strided 3-D convolution with 'SAME' padding. 62 | 63 | When stride > 1, then we do explicit zero-padding, followed by conv2d with 64 | 'VALID' padding. 65 | 66 | Note that 67 | 68 | net = conv2d_same(inputs, num_outputs, 3, stride=stride) 69 | 70 | is equivalent to 71 | 72 | net = tf.contrib.layers.conv2d(inputs, num_outputs, 3, stride=1, 73 | padding='SAME') 74 | net = subsample(net, factor=stride) 75 | 76 | whereas 77 | 78 | net = tf.contrib.layers.conv2d(inputs, num_outputs, 3, stride=stride, 79 | padding='SAME') 80 | 81 | is different when the input's height or width is even, which is why we add the 82 | current function. For more details, see ResnetUtilsTest.testConv2DSameEven(). 83 | 84 | Args: 85 | inputs: A 4-D tensor of size [batch, height_in, width_in, channels]. 86 | num_outputs: An integer, the number of output filters. 87 | kernel_size: An int with the kernel_size of the filters. 88 | stride: An integer, the output stride. 89 | rate: An integer, rate for atrous convolution. 90 | scope: Scope. 91 | 92 | Returns: 93 | output: A 4-D tensor of size [batch, height_out, width_out, channels] with 94 | the convolution output. 95 | """ 96 | if stride == 1: 97 | return layers_lib.conv3d( 98 | inputs, 99 | num_outputs, 100 | kernel_size, 101 | stride=1, 102 | rate=rate, 103 | padding='SAME', 104 | scope=scope, 105 | outputs_collections=None) 106 | else: 107 | if type(kernel_size)==list: 108 | kernel = np.array(kernel_size) 109 | pad_total = kernel - 1 110 | pad_beg = pad_total // 2 111 | pad_end = pad_total - pad_beg 112 | inputs = array_ops.pad(inputs, [[0, 0], [pad_beg[0], pad_end[0]], [pad_beg[1], pad_end[1]], [pad_beg[2], pad_end[2]], [0, 0]]) 113 | else: 114 | kernel_size_effective = kernel_size + (kernel_size - 1) * (rate - 1) 115 | pad_total = kernel_size_effective - 1 116 | pad_beg = pad_total // 2 117 | pad_end = pad_total - pad_beg 118 | inputs = array_ops.pad(inputs, [[0, 0], [pad_beg, pad_end], [pad_beg, pad_end], [pad_beg, pad_end], [0, 0]]) 119 | 120 | return layers_lib.conv3d( 121 | inputs, 122 | num_outputs, 123 | kernel_size, 124 | stride=stride, 125 | rate=rate, 126 | padding='VALID', 127 | scope=scope, 128 | outputs_collections=None) 129 | 130 | 131 | @add_arg_scope 132 | def stack_blocks_dense(net, 133 | blocks, 134 | output_stride=None, 135 | outputs_collections=None): 136 | """Stacks ResNet `Blocks` and controls output feature density. 137 | 138 | First, this function creates scopes for the ResNet in the form of 139 | 'block_name/unit_1', 'block_name/unit_2', etc. 140 | 141 | Second, this function allows the user to explicitly control the ResNet 142 | output_stride, which is the ratio of the input to output spatial resolution. 143 | This is useful for dense prediction tasks such as semantic segmentation or 144 | object detection. 145 | 146 | Most ResNets consist of 4 ResNet blocks and subsample the activations by a 147 | factor of 2 when transitioning between consecutive ResNet blocks. This results 148 | to a nominal ResNet output_stride equal to 8. If we set the output_stride to 149 | half the nominal network stride (e.g., output_stride=4), then we compute 150 | responses twice. 151 | 152 | Control of the output feature density is implemented by atrous convolution. 153 | 154 | Args: 155 | net: A `Tensor` of size [batch, height, width, channels]. 156 | blocks: A list of length equal to the number of ResNet `Blocks`. Each 157 | element is a ResNet `Block` object describing the units in the `Block`. 158 | output_stride: If `None`, then the output will be computed at the nominal 159 | network stride. If output_stride is not `None`, it specifies the requested 160 | ratio of input to output spatial resolution, which needs to be equal to 161 | the product of unit strides from the start up to some level of the ResNet. 162 | For example, if the ResNet employs units with strides 1, 2, 1, 3, 4, 1, 163 | then valid values for the output_stride are 1, 2, 6, 24 or None (which 164 | is equivalent to output_stride=24). 165 | outputs_collections: Collection to add the ResNet block outputs. 166 | 167 | Returns: 168 | net: Output tensor with stride equal to the specified output_stride. 169 | 170 | Raises: 171 | ValueError: If the target output_stride is not valid. 172 | """ 173 | # The current_stride variable keeps track of the effective stride of the 174 | # activations. This allows us to invoke atrous convolution whenever applying 175 | # the next residual unit would result in the activations having stride larger 176 | # than the target output_stride. 177 | current_stride = 1 178 | 179 | # The atrous convolution rate parameter. 180 | rate = 1 181 | 182 | for block in blocks: 183 | with variable_scope.variable_scope(block.scope, 'block', [net]) as sc: 184 | for i, unit in enumerate(block.args): 185 | if output_stride is not None and current_stride > output_stride: 186 | raise ValueError('The target output_stride cannot be reached.') 187 | 188 | with variable_scope.variable_scope('unit_%d' % (i + 1), values=[net]): 189 | # If we have reached the target output_stride, then we need to employ 190 | # atrous convolution with stride=1 and multiply the atrous rate by the 191 | # current unit's stride for use in subsequent layers. 192 | if output_stride is not None and current_stride == output_stride: 193 | net = block.unit_fn(net, rate=rate, **dict(unit, stride=1)) 194 | rate *= unit.get('stride', 1) 195 | 196 | else: 197 | net = block.unit_fn(net, rate=1, **unit) 198 | current_stride *= unit.get('stride', 1) 199 | net = utils.collect_named_outputs(outputs_collections, sc.name, net) 200 | 201 | if output_stride is not None and current_stride != output_stride: 202 | raise ValueError('The target output_stride cannot be reached.') 203 | 204 | return net 205 | 206 | 207 | def resnet_arg_scope(is_training=True, 208 | weight_decay=0.0001, 209 | batch_norm_decay=0.997, 210 | batch_norm_epsilon=0.00001, 211 | batch_norm_scale=True): 212 | """Defines the default ResNet arg scope. 213 | 214 | Args: 215 | is_training: Whether or not we are training the parameters in the batch 216 | normalization layers of the model. (deprecated) 217 | weight_decay: The weight decay to use for regularizing the model. 218 | batch_norm_decay: The moving average decay when estimating layer activation 219 | statistics in batch normalization. 220 | batch_norm_epsilon: Small constant to prevent division by zero when 221 | normalizing activations by their variance in batch normalization. 222 | batch_norm_scale: If True, uses an explicit `gamma` multiplier to scale the 223 | activations in the batch normalization layer. 224 | 225 | Returns: 226 | An `arg_scope` to use for the resnet models. 227 | """ 228 | batch_norm_params = { 229 | 'is_training': is_training, 230 | 'decay': batch_norm_decay, 231 | 'epsilon': batch_norm_epsilon, 232 | 'scale': batch_norm_scale, 233 | 'updates_collections': tf.GraphKeys.UPDATE_OPS 234 | #'updates_collections': None, 235 | #'renorm': True 236 | } 237 | 238 | with arg_scope( 239 | [layers_lib.conv3d], 240 | weights_regularizer=regularizers.l2_regularizer(weight_decay), 241 | weights_initializer=initializers.variance_scaling_initializer(), 242 | activation_fn=nn_ops.relu, 243 | normalizer_fn=layers.batch_norm): 244 | with arg_scope([layers.batch_norm], **batch_norm_params): 245 | with arg_scope([layers.max_pool3d], padding='SAME') as arg_sc: 246 | return arg_sc 247 | 248 | 249 | def resnet_pre_arg_scope(#is_training=True, 250 | weight_decay=0.0001, 251 | batch_norm_decay=0.997, 252 | batch_norm_epsilon=1e-5, 253 | batch_norm_scale=True): 254 | 255 | batch_norm_params = { 256 | #'is_training': is_training, 257 | 'decay': batch_norm_decay, 258 | 'epsilon': batch_norm_epsilon, 259 | 'scale': batch_norm_scale, 260 | # 'activation_fn': nn_ops.relu, 261 | 'variables_collections': ["batch_norm_params"], 262 | 'updates_collections': tf.GraphKeys.UPDATE_OPS 263 | } 264 | 265 | with arg_scope( 266 | [layers_lib.conv3d], 267 | weights_regularizer=regularizers.l2_regularizer(weight_decay), 268 | weights_initializer=initializers.variance_scaling_initializer(), 269 | activation_fn=None): 270 | with arg_scope([layers.batch_norm], **batch_norm_params): 271 | with arg_scope([layers.max_pool3d], padding='SAME') as arg_sc: 272 | return arg_sc -------------------------------------------------------------------------------- /net/resnet_lds_3d_bottleneck.py: -------------------------------------------------------------------------------- 1 | """ 2 | Created on Wed Jan 2 13:35:32 2019 3 | 4 | @author: smylonas 5 | """ 6 | 7 | import tensorflow as tf 8 | from tensorflow.contrib import layers 9 | from tensorflow.contrib.framework.python.ops import add_arg_scope 10 | from tensorflow.contrib.framework.python.ops import arg_scope 11 | from tensorflow.contrib.layers.python.layers import layers as layers_lib 12 | from tensorflow.contrib.layers.python.layers import utils 13 | from tensorflow.python.ops import math_ops 14 | from tensorflow.python.ops import nn_ops 15 | from tensorflow.python.ops import variable_scope 16 | from net import resnet_3d_utils 17 | from lds import amul as amul_module 18 | 19 | resnet_arg_scope = resnet_3d_utils.resnet_arg_scope 20 | 21 | 22 | @add_arg_scope 23 | def bottleneck(inputs, 24 | depth_out, 25 | depth_bottleneck, 26 | stride, 27 | rate=1, 28 | outputs_collections=None, 29 | scope=None): 30 | 31 | with variable_scope.variable_scope(scope, 'resid_v1', [inputs]) as sc: 32 | 33 | depth_in = utils.last_dimension(inputs.get_shape(), min_rank=5) 34 | if depth_out == depth_in: 35 | shortcut = resnet_3d_utils.subsample(inputs, stride, 'shortcut') 36 | else: 37 | shortcut = layers.conv3d(inputs, depth_out, [1, 1, 1], stride=stride, activation_fn=None, scope='shortcut') 38 | 39 | residual = layers.conv3d(inputs, depth_bottleneck, 1, stride=1, scope='conv1') 40 | 41 | residual1 = resnet_3d_utils.conv3d_same(residual, depth_bottleneck, 3, stride, scope='conv2') 42 | 43 | with tf.variable_scope(scope, 'Amul', [inputs]): 44 | amul = amul_module.amul 45 | 46 | residual2 = tf.pad(residual, [[0,0],[1,1],[1,1],[1,1],[0,0]], "CONSTANT") 47 | Amul_weight = tf.contrib.slim.model_variable('Amul_weight', shape=[27,27]) 48 | residual2 = amul(residual2, Amul_weight) 49 | residual2 = layers.conv3d(residual2, depth_bottleneck, [3, 3, 3], padding='SAME', stride=[x*stride for x in [3,3,3]], scope='conv_amul') 50 | 51 | residual_concat = tf.concat([residual1, residual2], 4) 52 | residual_concat = layers.conv3d(residual_concat, depth_out, [1, 1, 1], stride=1, scope='conv_concat', activation_fn=None) 53 | output = nn_ops.relu(shortcut + residual_concat) 54 | 55 | return utils.collect_named_outputs(outputs_collections, sc.name, output) 56 | 57 | 58 | def resnet_v1(inputs, 59 | blocks, 60 | num_classes=None, 61 | is_training=True, 62 | global_pool=True, 63 | output_stride=None, 64 | include_root_block=True, 65 | reuse=None, 66 | scope=None): 67 | """Generator for v1 ResNet models. 68 | Args: 69 | inputs: A tensor of size [batch, height_in, width_in, channels]. 70 | blocks: A list of length equal to the number of ResNet blocks. Each element 71 | is a resnet_utils.Block object describing the units in the block. 72 | num_classes: Number of predicted classes for classification tasks. If None 73 | we return the features before the logit layer. 74 | is_training: whether batch_norm layers are in training mode. 75 | global_pool: If True, we perform global average pooling before computing the 76 | logits. Set to True for image classification, False for dense prediction. 77 | output_stride: If None, then the output will be computed at the nominal 78 | network stride. If output_stride is not None, it specifies the requested 79 | ratio of input to output spatial resolution. 80 | include_root_block: If True, include the initial convolution followed by 81 | max-pooling, if False excludes it. 82 | reuse: whether or not the network and its variables should be reused. To be 83 | able to reuse 'scope' must be given. 84 | scope: Optional variable_scope. 85 | Returns: 86 | net: A rank-4 tensor of size [batch, height_out, width_out, channels_out]. 87 | If global_pool is False, then height_out and width_out are reduced by a 88 | factor of output_stride compared to the respective height_in and width_in, 89 | else both height_out and width_out equal one. If num_classes is None, then 90 | net is the output of the last ResNet block, potentially after global 91 | average pooling. If num_classes is not None, net contains the pre-softmax 92 | activations. 93 | end_points: A dictionary from components of the network to the corresponding 94 | activation. 95 | Raises: 96 | ValueError: If the target output_stride is not valid. 97 | """ 98 | with variable_scope.variable_scope( 99 | scope, 'resnet_v1', [inputs], reuse=reuse) as sc: 100 | end_points_collection = sc.original_name_scope + '_end_points' 101 | with arg_scope( 102 | [layers.conv3d, bottleneck, resnet_3d_utils.stack_blocks_dense], 103 | outputs_collections=end_points_collection): 104 | with arg_scope([layers.batch_norm], is_training=is_training): 105 | net = inputs 106 | net = resnet_3d_utils.stack_blocks_dense(net, blocks, output_stride) 107 | if global_pool: 108 | net = math_ops.reduce_mean(net, [1, 2, 3], name='pool5', keepdims=True) 109 | if num_classes is not None: 110 | net = layers.conv3d( 111 | net, 112 | num_classes, [1, 1, 1], 113 | activation_fn=None, 114 | normalizer_fn=None, 115 | scope='logits') 116 | 117 | # Convert end_points_collection into a dictionary of end_points. 118 | end_points = utils.convert_collection_to_dict(end_points_collection) 119 | if num_classes is not None and num_classes != 1: 120 | end_points['predictions'] = layers_lib.softmax(net, scope='predictions') 121 | net = tf.squeeze(net) 122 | elif num_classes == 1: 123 | net = tf.squeeze(net) 124 | end_points['probs'] = tf.nn.sigmoid(net) 125 | 126 | return net, end_points 127 | 128 | 129 | def resnet_block(scope, depth_out, num_units, stride): 130 | """Args: 131 | scope: The scope of the block. 132 | base_depth: The depth of the bottleneck layer for each unit. 133 | num_units: The number of units in the block. 134 | stride: The stride of the block, implemented as a stride in the last unit. 135 | All other units have stride=1. 136 | Returns: 137 | A resnet_v1 bottleneck block. 138 | """ 139 | return resnet_3d_utils.Block(scope, bottleneck, [{ 140 | 'depth_out': depth_out, 141 | 'depth_bottleneck': depth_out/4, 142 | 'stride': 1 143 | }] * (num_units - 1) + [{ 144 | 'depth_out': depth_out, 145 | 'depth_bottleneck': depth_out/4, 146 | 'stride': stride 147 | }]) 148 | 149 | 150 | def resnet_v1_18(inputs, 151 | num_classes, 152 | is_training, 153 | global_pool=True, 154 | output_stride=None, 155 | reuse=None, 156 | scope='resnet3d'): 157 | blocks = [ 158 | resnet_block('block1', depth_out=64, num_units=2, stride=2), 159 | resnet_block('block2', depth_out=128, num_units=2, stride=2), 160 | resnet_block('block3', depth_out=256, num_units=2, stride=2), 161 | resnet_block('block4', depth_out=512, num_units=2, stride=1), 162 | ] 163 | return resnet_v1( 164 | inputs, 165 | blocks, 166 | num_classes, 167 | is_training, 168 | global_pool, 169 | output_stride, 170 | include_root_block=False, 171 | reuse=reuse, 172 | scope=scope) 173 | 174 | -------------------------------------------------------------------------------- /network.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python2 2 | # -*- coding: utf-8 -*- 3 | """ 4 | Created on Thu Jan 30 15:13:37 2020 5 | 6 | @author: smylonas 7 | """ 8 | 9 | import numpy as np, os 10 | import tensorflow as tf 11 | from tensorflow.contrib import slim 12 | from features import KalasantyFeaturizer 13 | 14 | 15 | class Network: 16 | def __init__(self,model_path,model,voxelSize): 17 | gridSize = 16 18 | tf.reset_default_graph() 19 | self.inputs = tf.placeholder(tf.float32,shape=(None,gridSize,gridSize,gridSize,18)) 20 | 21 | if model=='orig': 22 | from net.resnet_3d import resnet_arg_scope, resnet_v1_18 23 | elif model=='lds': 24 | from net.resnet_lds_3d_bottleneck import resnet_arg_scope, resnet_v1_18 25 | 26 | with slim.arg_scope(resnet_arg_scope()): 27 | self.net, self.end_points = resnet_v1_18(self.inputs, 1, is_training=False) 28 | 29 | config = tf.ConfigProto() 30 | config.gpu_options.allow_growth = True 31 | self.sess = tf.Session(config=config) 32 | 33 | self.sess.run(tf.global_variables_initializer()) 34 | saver = tf.train.Saver() 35 | if model=='orig': 36 | saver.restore(self.sess,os.path.join(model_path,'resnet18')) 37 | elif model=='lds': 38 | saver.restore(self.sess,os.path.join(model_path,'bot_lds_resnet18')) 39 | 40 | self.featurizer = KalasantyFeaturizer(gridSize,voxelSize) 41 | 42 | def get_lig_scores(self, prot, batch_size): 43 | self.featurizer.get_channels(prot.mol) 44 | 45 | gridSize = 16 46 | lig_scores = [] 47 | input_data = np.zeros((batch_size,gridSize,gridSize,gridSize,18)) 48 | batch_cnt = 0 49 | for p,n in zip(prot.surf_points,prot.surf_normals): 50 | input_data[batch_cnt,:,:,:,:] = self.featurizer.grid_feats(p,n,prot.heavy_atom_coords) 51 | batch_cnt += 1 52 | if batch_cnt==batch_size: 53 | output = self.sess.run(self.end_points,feed_dict={self.inputs:input_data}) 54 | lig_scores += list(output['probs']) 55 | batch_cnt = 0 56 | 57 | if batch_cnt>0: 58 | output = self.sess.run(self.end_points,feed_dict={self.inputs:input_data[:batch_cnt,:,:,:,:]}) 59 | if batch_cnt==1: 60 | lig_scores.append(output['probs']) 61 | else: 62 | lig_scores += list(output['probs']) 63 | 64 | return np.array(lig_scores) 65 | 66 | -------------------------------------------------------------------------------- /predict.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python2 2 | # -*- coding: utf-8 -*- 3 | """ 4 | Created on Mon Jan 20 16:16:56 2020 5 | 6 | @author: smylonas 7 | """ 8 | 9 | import argparse, os 10 | from network import Network 11 | from protein import Protein 12 | from bsite_extraction import Bsite_extractor 13 | 14 | def parse_args(): 15 | parser = argparse.ArgumentParser(formatter_class=argparse.ArgumentDefaultsHelpFormatter) 16 | 17 | parser.add_argument('--prot_file', '-p', required=True, help='input protein file (pdb)') 18 | parser.add_argument('--model_path', '-mp', required=True, help='directory of models') 19 | parser.add_argument('--model', '-m', choices=['orig','lds'], default='orig', help='select model') 20 | parser.add_argument('--output', '-o', required=True, help='name of the output directory') 21 | parser.add_argument('--f', type=int, default=10, help='parameter for the simplification of points mesh') 22 | parser.add_argument('--T', type=float, default=0.9, help='ligandability threshold') 23 | parser.add_argument('--batch', type=int, default=32, help='batch size') 24 | parser.add_argument('--voxel_size', type=float, default=1.0, help='size of voxel in angstrom') 25 | parser.add_argument('--protonate', action='store_true', help='whether to protonate or not the input protein') 26 | parser.add_argument('--expand', action='store_true', help='whether to expand on residue level the extracted binding sites') 27 | parser.add_argument('--discard_points', action='store_true', help='whether to output or not the computed surface points') 28 | parser.add_argument('--seed', type=int, default=None, help='random seed for KMeans clustering') 29 | 30 | return parser.parse_args() 31 | 32 | 33 | args = parse_args() 34 | 35 | if not os.path.exists(args.prot_file): 36 | raise IOError('%s does not exist.' % args.prot_file) 37 | if not os.path.exists(args.model_path): 38 | raise IOError('%s does not exist.' % args.model_path) 39 | if not os.path.exists(args.output): 40 | os.makedirs(args.output) 41 | 42 | prot = Protein(args.prot_file,args.protonate,args.expand,args.f,args.output, args.discard_points, args.seed) 43 | 44 | nn = Network(args.model_path,args.model,args.voxel_size) 45 | 46 | lig_scores = nn.get_lig_scores(prot,args.batch) 47 | 48 | extractor = Bsite_extractor(args.T) 49 | 50 | extractor.extract_bsites(prot,lig_scores) 51 | 52 | -------------------------------------------------------------------------------- /protein.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python2 2 | # -*- coding: utf-8 -*- 3 | """ 4 | Created on Thu Jan 30 12:45:54 2020 5 | 6 | @author: smylonas 7 | """ 8 | 9 | import os, numpy as np 10 | import pybel 11 | from utils import simplify_dms 12 | 13 | 14 | class Protein: 15 | def __init__(self,prot_file,protonate,expand_residue,f,save_path,discard_points,seed=None): 16 | prot_id = prot_file.split('/')[-1].split('.')[0] 17 | self.save_path = os.path.join(save_path,prot_id) 18 | if not os.path.exists(self.save_path): 19 | os.makedirs(self.save_path) 20 | 21 | self.mol = next(pybel.readfile(prot_file.split('.')[-1],prot_file)) 22 | 23 | surfpoints_file = os.path.join(self.save_path,prot_id+'.surfpoints') 24 | os.system('dms '+prot_file+' -d 0.2 -n -o '+surfpoints_file) 25 | if not os.path.exists(surfpoints_file): 26 | raise Exception('probably DMS not installed') 27 | self.surf_points, self.surf_normals = simplify_dms(surfpoints_file, f, seed=seed) 28 | if discard_points: 29 | os.remove(surfpoints_file) 30 | 31 | self.expand_residue = expand_residue 32 | if expand_residue: 33 | self.mol.removeh() 34 | self.atom2residue = np.array([atom.residue.idx for atom in self.mol.atoms]) 35 | self.residue2atom = np.array([[atom.idx - 1 for atom in resid.atoms] for resid in self.mol.residues]) 36 | self.mol.addh() 37 | else: 38 | if protonate: 39 | self.mol.addh() 40 | 41 | self.heavy_atom_coords = np.array([atom.coords for atom in self.mol.atoms if atom.atomicnum > 1]) 42 | 43 | self.binding_sites = [] 44 | if prot_file.endswith('pdb'): 45 | with open(prot_file,'r') as f: 46 | lines = f.readlines() 47 | self.heavy_atom_lines = [line for line in lines if line[:4]=='ATOM' and line.split()[2][0]!='H'] 48 | if len(self.heavy_atom_lines) != len(self.heavy_atom_coords): 49 | ligand_in_pdb = len([line for line in lines if line.startswith('HETATM')])>0 50 | if ligand_in_pdb: 51 | raise Exception('Ligand found in PDBfile. Please remove it to procede.') 52 | else: 53 | raise Exception('Incosistency between Coords and PDBLines') 54 | else: 55 | raise IOError('Protein file should be .pdb') 56 | 57 | def _surfpoints_to_atoms(self,surfpoints): 58 | close_atoms = np.zeros(len(surfpoints),dtype=int) 59 | for p,surf_coord in enumerate(surfpoints): 60 | dist = np.sqrt(np.sum((self.heavy_atom_coords-surf_coord)**2,axis=1)) 61 | close_atoms[p] = np.argmin(dist) 62 | 63 | return np.unique(close_atoms) 64 | 65 | def add_bsite(self,cluster): # cluster -> tuple: (surf_points,scores) 66 | atom_idxs = self._surfpoints_to_atoms(cluster[0]) 67 | if self.expand_residue: 68 | residue_idxs = np.unique(self.atom2residue[atom_idxs]) 69 | atom_idxs = np.concatenate(self.residue2atom[residue_idxs]) 70 | self.binding_sites.append(Bsite(self.heavy_atom_coords,atom_idxs,cluster[1])) 71 | 72 | def sort_bsites(self): 73 | avg_scores = np.array([bsite.score for bsite in self.binding_sites]) 74 | sorted_idxs = np.flip(np.argsort(avg_scores),axis=0) 75 | self.binding_sites = [self.binding_sites[idx] for idx in sorted_idxs] 76 | 77 | def write_bsites(self): 78 | if not os.path.exists(self.save_path): 79 | os.makedirs(self.save_path) 80 | 81 | centers = np.array([bsite.center for bsite in self.binding_sites]) 82 | np.savetxt(os.path.join(self.save_path,'centers.txt'), centers, delimiter=' ', fmt='%10.3f') 83 | 84 | for i,bsite in enumerate(self.binding_sites): 85 | with open(os.path.join(self.save_path,'pocket'+str(i+1)+'.pdb'),'w') as f: 86 | outlines = [self.heavy_atom_lines[idx] for idx in bsite.atom_idxs] 87 | f.writelines(outlines) 88 | 89 | 90 | class Bsite: 91 | def __init__(self,mol_coords,atom_idxs,scores): 92 | self.coords = mol_coords[atom_idxs] 93 | self.center = np.average(self.coords,axis=0) 94 | self.score = np.average(scores) 95 | self.atom_idxs = atom_idxs 96 | 97 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | numpy==1.13.3 2 | tensorflow-gpu==1.13.1 3 | openbabel==2.4.1 4 | scipy==1.2.2 5 | scikit-learn==0.20.3 6 | protobuf==3.6.1 7 | -------------------------------------------------------------------------------- /test/4j2j_A.pdb: -------------------------------------------------------------------------------- 1 | ATOM 1 N PRO A 569 83.737 24.898 3.693 1.00105.50 N 2 | ATOM 2 CA PRO A 569 83.299 24.341 4.997 1.00105.50 C 3 | ATOM 3 C PRO A 569 81.811 24.579 5.258 1.00105.50 C 4 | ATOM 4 O PRO A 569 81.031 24.746 4.320 1.00105.50 O 5 | ATOM 5 CB PRO A 569 84.158 24.994 6.076 1.00 78.24 C 6 | ATOM 6 CG PRO A 569 84.615 26.281 5.376 1.00 78.24 C 7 | ATOM 7 CD PRO A 569 84.803 25.895 3.901 1.00 78.24 C 8 | ATOM 8 N THR A 570 81.420 24.588 6.530 1.00 83.65 N 9 | ATOM 9 CA THR A 570 80.021 24.800 6.903 1.00 83.65 C 10 | ATOM 10 C THR A 570 79.869 25.705 8.129 1.00 83.65 C 11 | ATOM 11 O THR A 570 80.862 26.167 8.695 1.00 83.65 O 12 | ATOM 12 CB THR A 570 79.308 23.459 7.174 1.00102.06 C 13 | ATOM 13 OG1 THR A 570 80.021 22.732 8.183 1.00102.06 O 14 | ATOM 14 CG2 THR A 570 79.243 22.628 5.897 1.00102.06 C 15 | ATOM 15 N LEU A 571 78.625 25.957 8.535 1.00 70.91 N 16 | ATOM 16 CA LEU A 571 78.367 26.830 9.676 1.00 70.91 C 17 | ATOM 17 C LEU A 571 77.595 26.213 10.819 1.00 70.91 C 18 | ATOM 18 O LEU A 571 76.480 25.717 10.645 1.00 70.91 O 19 | ATOM 19 CB LEU A 571 77.644 28.092 9.223 1.00 48.54 C 20 | ATOM 20 CG LEU A 571 78.582 29.125 8.614 1.00 48.54 C 21 | ATOM 21 CD1 LEU A 571 77.776 30.128 7.835 1.00 48.54 C 22 | ATOM 22 CD2 LEU A 571 79.391 29.791 9.715 1.00 48.54 C 23 | ATOM 23 N PRO A 572 78.186 26.252 12.021 1.00 55.17 N 24 | ATOM 24 CA PRO A 572 77.573 25.700 13.227 1.00 55.17 C 25 | ATOM 25 C PRO A 572 76.441 26.589 13.721 1.00 55.17 C 26 | ATOM 26 O PRO A 572 76.383 27.774 13.390 1.00 55.17 O 27 | ATOM 27 CB PRO A 572 78.746 25.630 14.201 1.00 36.81 C 28 | ATOM 28 CG PRO A 572 79.573 26.799 13.804 1.00 36.81 C 29 | ATOM 29 CD PRO A 572 79.555 26.719 12.300 1.00 36.81 C 30 | ATOM 30 N PRO A 573 75.521 26.019 14.511 1.00 47.44 N 31 | ATOM 31 CA PRO A 573 74.370 26.737 15.069 1.00 47.44 C 32 | ATOM 32 C PRO A 573 74.638 27.644 16.268 1.00 47.44 C 33 | ATOM 33 O PRO A 573 73.756 28.390 16.674 1.00 47.44 O 34 | ATOM 34 CB PRO A 573 73.407 25.607 15.440 1.00 29.83 C 35 | ATOM 35 CG PRO A 573 74.342 24.512 15.864 1.00 29.83 C 36 | ATOM 36 CD PRO A 573 75.405 24.570 14.767 1.00 29.83 C 37 | ATOM 37 N TYR A 574 75.835 27.604 16.837 1.00 50.68 N 38 | ATOM 38 CA TYR A 574 76.069 28.424 18.012 1.00 50.68 C 39 | ATOM 39 C TYR A 574 76.364 29.896 17.808 1.00 50.68 C 40 | ATOM 40 O TYR A 574 76.596 30.618 18.776 1.00 50.68 O 41 | ATOM 41 CB TYR A 574 77.127 27.785 18.915 1.00 46.31 C 42 | ATOM 42 CG TYR A 574 78.323 27.194 18.211 1.00 46.31 C 43 | ATOM 43 CD1 TYR A 574 79.291 28.011 17.643 1.00 46.31 C 44 | ATOM 44 CD2 TYR A 574 78.500 25.811 18.147 1.00 46.31 C 45 | ATOM 45 CE1 TYR A 574 80.416 27.471 17.029 1.00 46.31 C 46 | ATOM 46 CE2 TYR A 574 79.614 25.257 17.536 1.00 46.31 C 47 | ATOM 47 CZ TYR A 574 80.573 26.094 16.979 1.00 46.31 C 48 | ATOM 48 OH TYR A 574 81.693 25.568 16.375 1.00 46.31 O 49 | ATOM 49 N PHE A 575 76.360 30.362 16.565 1.00 36.03 N 50 | ATOM 50 CA PHE A 575 76.579 31.782 16.351 1.00 36.03 C 51 | ATOM 51 C PHE A 575 75.215 32.494 16.364 1.00 36.03 C 52 | ATOM 52 O PHE A 575 75.135 33.715 16.403 1.00 36.03 O 53 | ATOM 53 CB PHE A 575 77.312 32.020 15.033 1.00 43.59 C 54 | ATOM 54 CG PHE A 575 78.756 31.609 15.068 1.00 43.59 C 55 | ATOM 55 CD1 PHE A 575 79.622 32.155 16.007 1.00 43.59 C 56 | ATOM 56 CD2 PHE A 575 79.252 30.669 14.170 1.00 43.59 C 57 | ATOM 57 CE1 PHE A 575 80.963 31.773 16.056 1.00 43.59 C 58 | ATOM 58 CE2 PHE A 575 80.590 30.281 14.213 1.00 43.59 C 59 | ATOM 59 CZ PHE A 575 81.447 30.836 15.161 1.00 43.59 C 60 | HETATM 60 N MSE A 576 74.150 31.700 16.356 1.00 45.35 N 61 | HETATM 61 CA MSE A 576 72.776 32.189 16.363 1.00 45.35 C 62 | HETATM 62 C MSE A 576 72.469 32.982 17.642 1.00 45.35 C 63 | HETATM 63 O MSE A 576 72.794 32.553 18.756 1.00 45.35 O 64 | HETATM 64 CB MSE A 576 71.831 30.989 16.243 1.00 99.79 C 65 | HETATM 65 CG MSE A 576 70.366 31.324 16.048 1.00 99.79 C 66 | HETATM 66 SE MSE A 576 70.019 32.313 14.429 1.00 99.79 SE 67 | HETATM 67 CE MSE A 576 70.903 31.158 13.152 1.00 99.79 C 68 | ATOM 68 N LYS A 577 71.838 34.140 17.481 1.00 37.30 N 69 | ATOM 69 CA LYS A 577 71.491 34.978 18.623 1.00 37.30 C 70 | ATOM 70 C LYS A 577 70.712 34.207 19.693 1.00 37.30 C 71 | ATOM 71 O LYS A 577 69.799 33.427 19.388 1.00 37.30 O 72 | ATOM 72 CB LYS A 577 70.676 36.186 18.165 1.00 54.49 C 73 | ATOM 73 CG LYS A 577 70.450 37.226 19.254 1.00 54.49 C 74 | ATOM 74 CD LYS A 577 69.579 38.359 18.739 1.00 54.49 C 75 | ATOM 75 CE LYS A 577 69.385 39.449 19.770 1.00 54.49 C 76 | ATOM 76 NZ LYS A 577 68.390 40.434 19.262 1.00 54.49 N 77 | ATOM 77 N GLY A 578 71.077 34.428 20.949 1.00 42.36 N 78 | ATOM 78 CA GLY A 578 70.399 33.744 22.028 1.00 42.36 C 79 | ATOM 79 C GLY A 578 70.985 32.379 22.342 1.00 42.36 C 80 | ATOM 80 O GLY A 578 70.434 31.653 23.177 1.00 42.36 O 81 | ATOM 81 N SER A 579 72.084 32.017 21.674 1.00 46.18 N 82 | ATOM 82 CA SER A 579 72.733 30.729 21.928 1.00 46.18 C 83 | ATOM 83 C SER A 579 73.444 30.756 23.276 1.00 46.18 C 84 | ATOM 84 O SER A 579 74.314 31.594 23.519 1.00 46.18 O 85 | ATOM 85 CB SER A 579 73.745 30.395 20.830 1.00 56.29 C 86 | ATOM 86 OG SER A 579 73.100 29.916 19.664 1.00 56.29 O 87 | HETATM 87 N MSE A 580 73.060 29.842 24.157 1.00 31.92 N 88 | HETATM 88 CA MSE A 580 73.669 29.777 25.469 1.00 31.92 C 89 | HETATM 89 C MSE A 580 75.099 29.263 25.345 1.00 31.92 C 90 | HETATM 90 O MSE A 580 75.335 28.175 24.829 1.00 31.92 O 91 | HETATM 91 CB MSE A 580 72.854 28.872 26.387 1.00 77.57 C 92 | HETATM 92 CG MSE A 580 72.782 29.373 27.825 1.00 77.57 C 93 | HETATM 93 SE MSE A 580 72.140 31.209 27.984 1.00 77.57 SE 94 | HETATM 94 CE MSE A 580 70.531 31.037 26.935 1.00 77.57 C 95 | ATOM 95 N ILE A 581 76.054 30.069 25.796 1.00 30.24 N 96 | ATOM 96 CA ILE A 581 77.455 29.685 25.755 1.00 30.24 C 97 | ATOM 97 C ILE A 581 77.930 29.556 27.177 1.00 30.24 C 98 | ATOM 98 O ILE A 581 77.749 30.474 27.965 1.00 30.24 O 99 | ATOM 99 CB ILE A 581 78.347 30.756 25.092 1.00 29.78 C 100 | ATOM 100 CG1 ILE A 581 77.749 31.209 23.752 1.00 29.78 C 101 | ATOM 101 CG2 ILE A 581 79.752 30.189 24.900 1.00 29.78 C 102 | ATOM 102 CD1 ILE A 581 77.441 30.075 22.791 1.00 29.78 C 103 | ATOM 103 N GLN A 582 78.533 28.423 27.510 1.00 33.45 N 104 | ATOM 104 CA GLN A 582 79.052 28.206 28.860 1.00 33.45 C 105 | ATOM 105 C GLN A 582 80.530 28.635 28.959 1.00 33.45 C 106 | ATOM 106 O GLN A 582 81.400 28.078 28.278 1.00 33.45 O 107 | ATOM 107 CB GLN A 582 78.905 26.735 29.258 1.00 40.58 C 108 | ATOM 108 CG GLN A 582 79.430 26.434 30.658 1.00 40.58 C 109 | ATOM 109 CD GLN A 582 78.818 25.177 31.280 1.00 40.58 C 110 | ATOM 110 OE1 GLN A 582 79.073 24.058 30.836 1.00 40.58 O 111 | ATOM 111 NE2 GLN A 582 78.000 25.370 32.317 1.00 40.58 N 112 | ATOM 112 N LEU A 583 80.804 29.641 29.792 1.00 30.31 N 113 | ATOM 113 CA LEU A 583 82.172 30.107 29.981 1.00 30.31 C 114 | ATOM 114 C LEU A 583 82.955 29.080 30.813 1.00 30.31 C 115 | ATOM 115 O LEU A 583 82.374 28.152 31.389 1.00 30.31 O 116 | ATOM 116 CB LEU A 583 82.176 31.476 30.668 1.00 28.45 C 117 | ATOM 117 CG LEU A 583 81.386 32.588 29.944 1.00 28.45 C 118 | ATOM 118 CD1 LEU A 583 81.582 33.923 30.658 1.00 28.45 C 119 | ATOM 119 CD2 LEU A 583 81.845 32.720 28.509 1.00 28.45 C 120 | ATOM 120 N ALA A 584 84.272 29.240 30.866 1.00 32.87 N 121 | ATOM 121 CA ALA A 584 85.138 28.326 31.613 1.00 32.87 C 122 | ATOM 122 C ALA A 584 84.714 28.062 33.065 1.00 32.87 C 123 | ATOM 123 O ALA A 584 84.723 26.927 33.504 1.00 32.87 O 124 | ATOM 124 CB ALA A 584 86.571 28.841 31.583 1.00 31.95 C 125 | ATOM 125 N ASN A 585 84.336 29.109 33.799 1.00 34.07 N 126 | ATOM 126 CA ASN A 585 83.931 28.965 35.197 1.00 34.07 C 127 | ATOM 127 C ASN A 585 82.497 28.473 35.414 1.00 34.07 C 128 | ATOM 128 O ASN A 585 82.025 28.423 36.551 1.00 34.07 O 129 | ATOM 129 CB ASN A 585 84.110 30.290 35.925 1.00 28.37 C 130 | ATOM 130 CG ASN A 585 83.041 31.312 35.553 1.00 28.37 C 131 | ATOM 131 OD1 ASN A 585 82.478 31.294 34.459 1.00 28.37 O 132 | ATOM 132 ND2 ASN A 585 82.771 32.218 36.471 1.00 28.37 N 133 | ATOM 133 N GLY A 586 81.796 28.131 34.336 1.00 34.11 N 134 | ATOM 134 CA GLY A 586 80.436 27.631 34.483 1.00 34.11 C 135 | ATOM 135 C GLY A 586 79.354 28.659 34.201 1.00 34.11 C 136 | ATOM 136 O GLY A 586 78.185 28.316 34.019 1.00 34.11 O 137 | ATOM 137 N GLU A 587 79.745 29.925 34.170 1.00 37.65 N 138 | ATOM 138 CA GLU A 587 78.803 31.003 33.911 1.00 37.65 C 139 | ATOM 139 C GLU A 587 78.229 30.841 32.504 1.00 37.65 C 140 | ATOM 140 O GLU A 587 78.930 30.411 31.583 1.00 37.65 O 141 | ATOM 141 CB GLU A 587 79.505 32.356 34.055 1.00 58.18 C 142 | ATOM 142 CG GLU A 587 78.597 33.558 33.892 1.00 58.18 C 143 | ATOM 143 CD GLU A 587 79.326 34.876 34.113 1.00 58.18 C 144 | ATOM 144 OE1 GLU A 587 78.727 35.940 33.854 1.00 58.18 O 145 | ATOM 145 OE2 GLU A 587 80.497 34.849 34.547 1.00 58.18 O 146 | ATOM 146 N LEU A 588 76.942 31.159 32.368 1.00 40.80 N 147 | ATOM 147 CA LEU A 588 76.216 31.075 31.107 1.00 40.80 C 148 | ATOM 148 C LEU A 588 75.959 32.467 30.573 1.00 40.80 C 149 | ATOM 149 O LEU A 588 75.543 33.367 31.319 1.00 40.80 O 150 | ATOM 150 CB LEU A 588 74.869 30.378 31.304 1.00 29.13 C 151 | ATOM 151 CG LEU A 588 74.915 28.912 31.730 1.00 29.13 C 152 | ATOM 152 CD1 LEU A 588 73.506 28.313 31.768 1.00 29.13 C 153 | ATOM 153 CD2 LEU A 588 75.778 28.149 30.721 1.00 29.13 C 154 | ATOM 154 N LYS A 589 76.194 32.635 29.278 1.00 35.38 N 155 | ATOM 155 CA LYS A 589 75.988 33.912 28.603 1.00 35.38 C 156 | ATOM 156 C LYS A 589 75.480 33.725 27.176 1.00 35.38 C 157 | ATOM 157 O LYS A 589 75.751 32.711 26.540 1.00 35.38 O 158 | ATOM 158 CB LYS A 589 77.291 34.700 28.554 1.00 46.47 C 159 | ATOM 159 CG LYS A 589 77.589 35.528 29.769 1.00 46.47 C 160 | ATOM 160 CD LYS A 589 78.572 36.611 29.352 1.00 46.47 C 161 | ATOM 161 CE LYS A 589 78.908 37.583 30.465 1.00 46.47 C 162 | ATOM 162 NZ LYS A 589 79.674 38.728 29.887 1.00 46.47 N 163 | ATOM 163 N LYS A 590 74.734 34.703 26.674 1.00 34.56 N 164 | ATOM 164 CA LYS A 590 74.237 34.623 25.314 1.00 34.56 C 165 | ATOM 165 C LYS A 590 75.384 35.018 24.417 1.00 34.56 C 166 | ATOM 166 O LYS A 590 76.103 35.977 24.709 1.00 34.56 O 167 | ATOM 167 CB LYS A 590 73.033 35.543 25.124 1.00 53.34 C 168 | ATOM 168 CG LYS A 590 71.815 35.066 25.911 1.00 53.34 C 169 | ATOM 169 CD LYS A 590 70.522 35.782 25.542 1.00 53.34 C 170 | ATOM 170 CE LYS A 590 70.550 37.258 25.913 1.00 53.34 C 171 | ATOM 171 NZ LYS A 590 71.436 38.044 25.011 1.00 53.34 N 172 | ATOM 172 N VAL A 591 75.576 34.263 23.340 1.00 36.40 N 173 | ATOM 173 CA VAL A 591 76.666 34.517 22.405 1.00 36.40 C 174 | ATOM 174 C VAL A 591 76.798 35.968 21.939 1.00 36.40 C 175 | ATOM 175 O VAL A 591 77.911 36.435 21.683 1.00 36.40 O 176 | ATOM 176 CB VAL A 591 76.570 33.595 21.171 1.00 27.23 C 177 | ATOM 177 CG1 VAL A 591 75.299 33.870 20.396 1.00 27.23 C 178 | ATOM 178 CG2 VAL A 591 77.773 33.797 20.287 1.00 27.23 C 179 | ATOM 179 N GLU A 592 75.690 36.694 21.834 1.00 40.31 N 180 | ATOM 180 CA GLU A 592 75.776 38.085 21.398 1.00 40.31 C 181 | ATOM 181 C GLU A 592 76.389 38.984 22.486 1.00 40.31 C 182 | ATOM 182 O GLU A 592 76.937 40.048 22.176 1.00 40.31 O 183 | ATOM 183 CB GLU A 592 74.394 38.619 21.017 1.00 49.45 C 184 | ATOM 184 CG GLU A 592 73.396 38.571 22.155 1.00 49.45 C 185 | ATOM 185 CD GLU A 592 72.469 37.360 22.100 1.00 49.45 C 186 | ATOM 186 OE1 GLU A 592 72.938 36.224 21.825 1.00 49.45 O 187 | ATOM 187 OE2 GLU A 592 71.256 37.555 22.346 1.00 49.45 O 188 | ATOM 188 N ASP A 593 76.311 38.559 23.752 1.00 41.33 N 189 | ATOM 189 CA ASP A 593 76.855 39.361 24.857 1.00 41.33 C 190 | ATOM 190 C ASP A 593 78.298 39.073 25.222 1.00 41.33 C 191 | ATOM 191 O ASP A 593 78.826 39.699 26.128 1.00 41.33 O 192 | ATOM 192 CB ASP A 593 76.025 39.192 26.132 1.00 43.33 C 193 | ATOM 193 CG ASP A 593 74.568 39.504 25.922 1.00 43.33 C 194 | ATOM 194 OD1 ASP A 593 74.271 40.443 25.152 1.00 43.33 O 195 | ATOM 195 OD2 ASP A 593 73.712 38.821 26.530 1.00 43.33 O 196 | ATOM 196 N LEU A 594 78.939 38.130 24.539 1.00 39.31 N 197 | ATOM 197 CA LEU A 594 80.321 37.782 24.857 1.00 39.31 C 198 | ATOM 198 C LEU A 594 81.253 38.934 24.580 1.00 39.31 C 199 | ATOM 199 O LEU A 594 81.099 39.640 23.579 1.00 39.31 O 200 | ATOM 200 CB LEU A 594 80.763 36.559 24.057 1.00 36.81 C 201 | ATOM 201 CG LEU A 594 80.061 35.274 24.472 1.00 36.81 C 202 | ATOM 202 CD1 LEU A 594 80.282 34.225 23.434 1.00 36.81 C 203 | ATOM 203 CD2 LEU A 594 80.580 34.825 25.827 1.00 36.81 C 204 | ATOM 204 N LYS A 595 82.221 39.115 25.476 1.00 41.38 N 205 | ATOM 205 CA LYS A 595 83.207 40.187 25.359 1.00 41.38 C 206 | ATOM 206 C LYS A 595 84.597 39.585 25.368 1.00 41.38 C 207 | ATOM 207 O LYS A 595 84.779 38.434 25.746 1.00 41.38 O 208 | ATOM 208 CB LYS A 595 83.093 41.164 26.536 1.00 59.07 C 209 | ATOM 209 CG LYS A 595 81.737 41.800 26.711 1.00 59.07 C 210 | ATOM 210 CD LYS A 595 81.413 42.781 25.596 1.00 59.07 C 211 | ATOM 211 CE LYS A 595 80.066 43.449 25.873 1.00 59.07 C 212 | ATOM 212 NZ LYS A 595 79.734 44.537 24.916 1.00 59.07 N 213 | ATOM 213 N THR A 596 85.580 40.377 24.976 1.00 39.76 N 214 | ATOM 214 CA THR A 596 86.948 39.908 24.955 1.00 39.76 C 215 | ATOM 215 C THR A 596 87.356 39.302 26.286 1.00 39.76 C 216 | ATOM 216 O THR A 596 87.881 38.194 26.322 1.00 39.76 O 217 | ATOM 217 CB THR A 596 87.910 41.049 24.575 1.00 32.95 C 218 | ATOM 218 OG1 THR A 596 87.619 41.463 23.236 1.00 32.95 O 219 | ATOM 219 CG2 THR A 596 89.363 40.588 24.633 1.00 32.95 C 220 | ATOM 220 N GLU A 597 87.094 40.008 27.380 1.00 36.52 N 221 | ATOM 221 CA GLU A 597 87.470 39.509 28.688 1.00 36.52 C 222 | ATOM 222 C GLU A 597 86.865 38.149 29.009 1.00 36.52 C 223 | ATOM 223 O GLU A 597 87.483 37.358 29.731 1.00 36.52 O 224 | ATOM 224 CB GLU A 597 87.113 40.521 29.779 1.00 69.23 C 225 | ATOM 225 CG GLU A 597 85.643 40.880 29.876 1.00 69.23 C 226 | ATOM 226 CD GLU A 597 85.393 42.011 30.869 1.00 69.23 C 227 | ATOM 227 OE1 GLU A 597 85.718 41.832 32.064 1.00 69.23 O 228 | ATOM 228 OE2 GLU A 597 84.880 43.078 30.453 1.00 69.23 O 229 | ATOM 229 N ASP A 598 85.676 37.856 28.478 1.00 34.36 N 230 | ATOM 230 CA ASP A 598 85.075 36.555 28.750 1.00 34.36 C 231 | ATOM 231 C ASP A 598 85.945 35.438 28.167 1.00 34.36 C 232 | ATOM 232 O ASP A 598 86.058 34.372 28.756 1.00 34.36 O 233 | ATOM 233 CB ASP A 598 83.656 36.454 28.182 1.00 40.50 C 234 | ATOM 234 CG ASP A 598 82.668 37.389 28.873 1.00 40.50 C 235 | ATOM 235 OD1 ASP A 598 82.685 37.507 30.117 1.00 40.50 O 236 | ATOM 236 OD2 ASP A 598 81.847 38.003 28.167 1.00 40.50 O 237 | ATOM 237 N PHE A 599 86.568 35.677 27.015 1.00 35.67 N 238 | ATOM 238 CA PHE A 599 87.413 34.656 26.406 1.00 35.67 C 239 | ATOM 239 C PHE A 599 88.739 34.585 27.122 1.00 35.67 C 240 | ATOM 240 O PHE A 599 89.249 33.506 27.394 1.00 35.67 O 241 | ATOM 241 CB PHE A 599 87.667 34.946 24.926 1.00 33.72 C 242 | ATOM 242 CG PHE A 599 86.486 34.658 24.030 1.00 33.72 C 243 | ATOM 243 CD1 PHE A 599 85.665 35.687 23.588 1.00 33.72 C 244 | ATOM 244 CD2 PHE A 599 86.220 33.357 23.604 1.00 33.72 C 245 | ATOM 245 CE1 PHE A 599 84.604 35.426 22.735 1.00 33.72 C 246 | ATOM 246 CE2 PHE A 599 85.163 33.086 22.750 1.00 33.72 C 247 | ATOM 247 CZ PHE A 599 84.351 34.119 22.312 1.00 33.72 C 248 | ATOM 248 N ILE A 600 89.307 35.748 27.406 1.00 31.95 N 249 | ATOM 249 CA ILE A 600 90.573 35.823 28.109 1.00 31.95 C 250 | ATOM 250 C ILE A 600 90.451 35.154 29.471 1.00 31.95 C 251 | ATOM 251 O ILE A 600 91.297 34.354 29.859 1.00 31.95 O 252 | ATOM 252 CB ILE A 600 90.996 37.290 28.288 1.00 30.08 C 253 | ATOM 253 CG1 ILE A 600 91.394 37.865 26.924 1.00 30.08 C 254 | ATOM 254 CG2 ILE A 600 92.115 37.398 29.309 1.00 30.08 C 255 | ATOM 255 CD1 ILE A 600 91.806 39.305 26.978 1.00 30.08 C 256 | ATOM 256 N GLN A 601 89.396 35.479 30.204 1.00 41.23 N 257 | ATOM 257 CA GLN A 601 89.193 34.878 31.511 1.00 41.23 C 258 | ATOM 258 C GLN A 601 88.999 33.376 31.382 1.00 41.23 C 259 | ATOM 259 O GLN A 601 89.560 32.622 32.165 1.00 41.23 O 260 | ATOM 260 CB GLN A 601 87.999 35.526 32.216 1.00 61.67 C 261 | ATOM 261 CG GLN A 601 88.381 36.783 32.996 1.00 61.67 C 262 | ATOM 262 CD GLN A 601 87.270 37.829 33.050 1.00 61.67 C 263 | ATOM 263 OE1 GLN A 601 86.121 37.533 33.399 1.00 61.67 O 264 | ATOM 264 NE2 GLN A 601 87.619 39.068 32.712 1.00 61.67 N 265 | ATOM 265 N SER A 602 88.227 32.936 30.389 1.00 37.65 N 266 | ATOM 266 CA SER A 602 87.999 31.506 30.195 1.00 37.65 C 267 | ATOM 267 C SER A 602 89.268 30.724 29.875 1.00 37.65 C 268 | ATOM 268 O SER A 602 89.392 29.565 30.260 1.00 37.65 O 269 | ATOM 269 CB SER A 602 86.988 31.259 29.089 1.00 33.66 C 270 | ATOM 270 OG SER A 602 85.676 31.450 29.561 1.00 33.66 O 271 | ATOM 271 N ALA A 603 90.200 31.343 29.159 1.00 50.38 N 272 | ATOM 272 CA ALA A 603 91.447 30.672 28.828 1.00 50.38 C 273 | ATOM 273 C ALA A 603 92.257 30.511 30.106 1.00 50.38 C 274 | ATOM 274 O ALA A 603 92.877 29.467 30.323 1.00 50.38 O 275 | ATOM 275 CB ALA A 603 92.228 31.477 27.806 1.00 41.23 C 276 | ATOM 276 N GLU A 604 92.245 31.549 30.946 1.00 50.11 N 277 | ATOM 277 CA GLU A 604 92.961 31.532 32.225 1.00 50.11 C 278 | ATOM 278 C GLU A 604 92.383 30.442 33.130 1.00 50.11 C 279 | ATOM 279 O GLU A 604 93.115 29.662 33.756 1.00 50.11 O 280 | ATOM 280 CB GLU A 604 92.823 32.881 32.936 1.00 97.69 C 281 | ATOM 281 CG GLU A 604 93.490 34.053 32.236 1.00 97.69 C 282 | ATOM 282 CD GLU A 604 93.184 35.386 32.913 1.00 97.69 C 283 | ATOM 283 OE1 GLU A 604 92.019 35.835 32.853 1.00 97.69 O 284 | ATOM 284 OE2 GLU A 604 94.106 35.982 33.511 1.00 97.69 O 285 | HETATM 285 N MSE A 605 91.057 30.400 33.181 1.00 43.37 N 286 | HETATM 286 CA MSE A 605 90.331 29.443 34.000 1.00 43.37 C 287 | HETATM 287 C MSE A 605 90.597 28.008 33.577 1.00 43.37 C 288 | HETATM 288 O MSE A 605 90.662 27.112 34.411 1.00 43.37 O 289 | HETATM 289 CB MSE A 605 88.832 29.725 33.906 1.00112.58 C 290 | HETATM 290 CG MSE A 605 87.995 28.972 34.907 1.00112.58 C 291 | HETATM 291 SE MSE A 605 88.420 29.562 36.677 1.00112.58 SE 292 | HETATM 292 CE MSE A 605 87.622 31.324 36.608 1.00112.58 C 293 | ATOM 293 N SER A 606 90.753 27.800 32.277 1.00 39.81 N 294 | ATOM 294 CA SER A 606 90.988 26.472 31.726 1.00 39.81 C 295 | ATOM 295 C SER A 606 92.363 25.913 32.047 1.00 39.81 C 296 | ATOM 296 O SER A 606 93.316 26.656 32.211 1.00 39.81 O 297 | ATOM 297 CB SER A 606 90.794 26.508 30.219 1.00 54.55 C 298 | ATOM 298 OG SER A 606 91.083 25.250 29.660 1.00 54.55 O 299 | ATOM 299 N ASN A 607 92.465 24.595 32.134 1.00 49.40 N 300 | ATOM 300 CA ASN A 607 93.741 23.958 32.432 1.00 49.40 C 301 | ATOM 301 C ASN A 607 94.428 23.445 31.176 1.00 49.40 C 302 | ATOM 302 O ASN A 607 95.577 23.024 31.244 1.00 49.40 O 303 | ATOM 303 CB ASN A 607 93.557 22.787 33.410 1.00 55.60 C 304 | ATOM 304 CG ASN A 607 93.106 23.241 34.797 1.00 55.60 C 305 | ATOM 305 OD1 ASN A 607 93.621 24.223 35.338 1.00 55.60 O 306 | ATOM 306 ND2 ASN A 607 92.153 22.517 35.384 1.00 55.60 N 307 | ATOM 307 N ASP A 608 93.741 23.495 30.033 1.00 44.93 N 308 | ATOM 308 CA ASP A 608 94.320 22.990 28.783 1.00 44.93 C 309 | ATOM 309 C ASP A 608 94.357 23.920 27.574 1.00 44.93 C 310 | ATOM 310 O ASP A 608 95.165 23.722 26.661 1.00 44.93 O 311 | ATOM 311 CB ASP A 608 93.608 21.707 28.374 1.00 48.12 C 312 | ATOM 312 CG ASP A 608 93.688 20.649 29.438 1.00 48.12 C 313 | ATOM 313 OD1 ASP A 608 94.822 20.286 29.827 1.00 48.12 O 314 | ATOM 314 OD2 ASP A 608 92.621 20.188 29.888 1.00 48.12 O 315 | ATOM 315 N LEU A 609 93.490 24.922 27.554 1.00 55.24 N 316 | ATOM 316 CA LEU A 609 93.449 25.841 26.425 1.00 55.24 C 317 | ATOM 317 C LEU A 609 93.981 27.212 26.800 1.00 55.24 C 318 | ATOM 318 O LEU A 609 93.779 27.686 27.915 1.00 55.24 O 319 | ATOM 319 CB LEU A 609 92.011 25.966 25.909 1.00 35.69 C 320 | ATOM 320 CG LEU A 609 91.338 24.627 25.588 1.00 35.69 C 321 | ATOM 321 CD1 LEU A 609 89.873 24.851 25.297 1.00 35.69 C 322 | ATOM 322 CD2 LEU A 609 92.037 23.958 24.403 1.00 35.69 C 323 | ATOM 323 N LYS A 610 94.683 27.834 25.865 1.00 49.54 N 324 | ATOM 324 CA LYS A 610 95.218 29.171 26.072 1.00 49.54 C 325 | ATOM 325 C LYS A 610 94.883 29.980 24.826 1.00 49.54 C 326 | ATOM 326 O LYS A 610 94.569 29.412 23.787 1.00 49.54 O 327 | ATOM 327 CB LYS A 610 96.725 29.133 26.298 1.00 61.15 C 328 | ATOM 328 CG LYS A 610 97.530 28.662 25.119 1.00 61.15 C 329 | ATOM 329 CD LYS A 610 99.008 28.798 25.422 1.00 61.15 C 330 | ATOM 330 CE LYS A 610 99.338 30.222 25.866 1.00 61.15 C 331 | ATOM 331 NZ LYS A 610 100.804 30.456 26.052 1.00 61.15 N 332 | ATOM 332 N ILE A 611 94.942 31.301 24.934 1.00 44.57 N 333 | ATOM 333 CA ILE A 611 94.613 32.168 23.810 1.00 44.57 C 334 | ATOM 334 C ILE A 611 95.832 32.561 22.992 1.00 44.57 C 335 | ATOM 335 O ILE A 611 96.894 32.876 23.538 1.00 44.57 O 336 | ATOM 336 CB ILE A 611 93.891 33.449 24.302 1.00 59.34 C 337 | ATOM 337 CG1 ILE A 611 92.497 33.089 24.811 1.00 59.34 C 338 | ATOM 338 CG2 ILE A 611 93.781 34.468 23.179 1.00 59.34 C 339 | ATOM 339 CD1 ILE A 611 91.750 34.254 25.346 1.00 59.34 C 340 | ATOM 340 N ASP A 612 95.663 32.535 21.676 1.00 53.81 N 341 | ATOM 341 CA ASP A 612 96.726 32.884 20.748 1.00 53.81 C 342 | ATOM 342 C ASP A 612 96.223 33.939 19.770 1.00 53.81 C 343 | ATOM 343 O ASP A 612 95.271 33.703 19.040 1.00 53.81 O 344 | ATOM 344 CB ASP A 612 97.164 31.642 19.972 1.00 94.73 C 345 | ATOM 345 CG ASP A 612 98.630 31.323 20.164 1.00 94.73 C 346 | ATOM 346 OD1 ASP A 612 99.476 32.188 19.855 1.00 94.73 O 347 | ATOM 347 OD2 ASP A 612 98.938 30.204 20.623 1.00 94.73 O 348 | ATOM 348 N SER A 613 96.852 35.104 19.756 1.00 50.07 N 349 | ATOM 349 CA SER A 613 96.448 36.164 18.839 1.00 50.07 C 350 | ATOM 350 C SER A 613 96.743 35.738 17.411 1.00 50.07 C 351 | ATOM 351 O SER A 613 97.826 35.243 17.119 1.00 50.07 O 352 | ATOM 352 CB SER A 613 97.221 37.451 19.122 1.00 67.67 C 353 | ATOM 353 OG SER A 613 97.107 37.846 20.476 1.00 67.67 O 354 | ATOM 354 N SER A 614 95.776 35.924 16.522 1.00 37.90 N 355 | ATOM 355 CA SER A 614 95.967 35.596 15.120 1.00 37.90 C 356 | ATOM 356 C SER A 614 95.643 36.850 14.315 1.00 37.90 C 357 | ATOM 357 O SER A 614 94.514 37.331 14.333 1.00 37.90 O 358 | ATOM 358 CB SER A 614 95.067 34.429 14.716 1.00 44.29 C 359 | ATOM 359 OG SER A 614 95.555 33.220 15.272 1.00 44.29 O 360 | ATOM 360 N THR A 615 96.647 37.381 13.619 1.00 49.02 N 361 | ATOM 361 CA THR A 615 96.486 38.598 12.834 1.00 49.02 C 362 | ATOM 362 C THR A 615 96.200 38.366 11.357 1.00 49.02 C 363 | ATOM 363 O THR A 615 96.985 37.732 10.663 1.00 49.02 O 364 | ATOM 364 CB THR A 615 97.736 39.475 12.934 1.00 54.72 C 365 | ATOM 365 OG1 THR A 615 97.990 39.791 14.304 1.00 54.72 O 366 | ATOM 366 CG2 THR A 615 97.539 40.761 12.159 1.00 54.72 C 367 | ATOM 367 N VAL A 616 95.082 38.911 10.884 1.00 42.75 N 368 | ATOM 368 CA VAL A 616 94.675 38.778 9.491 1.00 42.75 C 369 | ATOM 369 C VAL A 616 95.633 39.537 8.596 1.00 42.75 C 370 | ATOM 370 O VAL A 616 95.672 40.763 8.637 1.00 42.75 O 371 | ATOM 371 CB VAL A 616 93.267 39.353 9.258 1.00 17.11 C 372 | ATOM 372 CG1 VAL A 616 92.897 39.239 7.772 1.00 17.11 C 373 | ATOM 373 CG2 VAL A 616 92.235 38.619 10.154 1.00 17.11 C 374 | ATOM 374 N GLU A 617 96.391 38.809 7.779 1.00 63.46 N 375 | ATOM 375 CA GLU A 617 97.357 39.430 6.883 1.00 63.46 C 376 | ATOM 376 C GLU A 617 96.780 39.684 5.500 1.00 63.46 C 377 | ATOM 377 O GLU A 617 97.279 40.531 4.765 1.00 63.46 O 378 | ATOM 378 CB GLU A 617 98.614 38.563 6.782 1.00 97.11 C 379 | ATOM 379 CG GLU A 617 99.300 38.363 8.125 1.00 97.11 C 380 | ATOM 380 CD GLU A 617 100.625 37.638 8.019 1.00 97.11 C 381 | ATOM 381 OE1 GLU A 617 100.666 36.551 7.403 1.00 97.11 O 382 | ATOM 382 OE2 GLU A 617 101.625 38.155 8.563 1.00 97.11 O 383 | ATOM 383 N ARG A 618 95.719 38.964 5.153 1.00 39.83 N 384 | ATOM 384 CA ARG A 618 95.088 39.133 3.856 1.00 39.83 C 385 | ATOM 385 C ARG A 618 93.789 38.343 3.698 1.00 39.83 C 386 | ATOM 386 O ARG A 618 93.659 37.215 4.181 1.00 39.83 O 387 | ATOM 387 CB ARG A 618 96.062 38.737 2.747 1.00 59.00 C 388 | ATOM 388 CG ARG A 618 95.469 38.791 1.353 1.00 59.00 C 389 | ATOM 389 CD ARG A 618 96.469 38.315 0.321 1.00 59.00 C 390 | ATOM 390 NE ARG A 618 97.616 39.218 0.194 1.00 59.00 N 391 | ATOM 391 CZ ARG A 618 97.612 40.343 -0.516 1.00 59.00 C 392 | ATOM 392 NH1 ARG A 618 96.515 40.715 -1.173 1.00 59.00 N 393 | ATOM 393 NH2 ARG A 618 98.711 41.089 -0.575 1.00 59.00 N 394 | ATOM 394 N ILE A 619 92.832 38.955 3.004 1.00 51.05 N 395 | ATOM 395 CA ILE A 619 91.533 38.346 2.743 1.00 51.05 C 396 | ATOM 396 C ILE A 619 91.344 38.216 1.230 1.00 51.05 C 397 | ATOM 397 O ILE A 619 91.286 39.215 0.521 1.00 51.05 O 398 | ATOM 398 CB ILE A 619 90.408 39.221 3.310 1.00 40.44 C 399 | ATOM 399 CG1 ILE A 619 90.695 39.516 4.784 1.00 40.44 C 400 | ATOM 400 CG2 ILE A 619 89.055 38.533 3.105 1.00 40.44 C 401 | ATOM 401 CD1 ILE A 619 89.607 40.303 5.492 1.00 40.44 C 402 | ATOM 402 N GLU A 620 91.259 36.988 0.732 1.00 61.43 N 403 | ATOM 403 CA GLU A 620 91.082 36.786 -0.698 1.00 61.43 C 404 | ATOM 404 C GLU A 620 89.680 36.283 -0.973 1.00 61.43 C 405 | ATOM 405 O GLU A 620 89.477 35.118 -1.296 1.00 61.43 O 406 | ATOM 406 CB GLU A 620 92.116 35.798 -1.233 1.00 96.11 C 407 | ATOM 407 CG GLU A 620 92.333 35.905 -2.738 1.00 96.11 C 408 | ATOM 408 CD GLU A 620 92.729 37.310 -3.174 1.00 96.11 C 409 | ATOM 409 OE1 GLU A 620 93.721 37.848 -2.634 1.00 96.11 O 410 | ATOM 410 OE2 GLU A 620 92.049 37.874 -4.059 1.00 96.11 O 411 | ATOM 411 N ASP A 621 88.724 37.197 -0.843 1.00 71.37 N 412 | ATOM 412 CA ASP A 621 87.305 36.934 -1.035 1.00 71.37 C 413 | ATOM 413 C ASP A 621 86.926 36.224 -2.341 1.00 71.37 C 414 | ATOM 414 O ASP A 621 87.715 36.155 -3.294 1.00 71.37 O 415 | ATOM 415 CB ASP A 621 86.540 38.251 -0.943 1.00 93.58 C 416 | ATOM 416 CG ASP A 621 85.171 38.081 -0.346 1.00 93.58 C 417 | ATOM 417 OD1 ASP A 621 84.472 37.124 -0.741 1.00 93.58 O 418 | ATOM 418 OD2 ASP A 621 84.795 38.904 0.516 1.00 93.58 O 419 | ATOM 419 N SER A 622 85.696 35.713 -2.371 1.00 56.77 N 420 | ATOM 420 CA SER A 622 85.156 34.994 -3.521 1.00 56.77 C 421 | ATOM 421 C SER A 622 86.118 33.992 -4.142 1.00 56.77 C 422 | ATOM 422 O SER A 622 86.444 34.073 -5.326 1.00 56.77 O 423 | ATOM 423 CB SER A 622 84.664 35.974 -4.587 1.00 80.50 C 424 | ATOM 424 OG SER A 622 83.451 36.587 -4.181 1.00 80.50 O 425 | ATOM 425 N HIS A 623 86.559 33.045 -3.321 1.00 68.04 N 426 | ATOM 426 CA HIS A 623 87.465 31.978 -3.735 1.00 68.04 C 427 | ATOM 427 C HIS A 623 86.630 31.034 -4.604 1.00 68.04 C 428 | ATOM 428 O HIS A 623 87.046 30.607 -5.683 1.00 68.04 O 429 | ATOM 429 CB HIS A 623 87.984 31.269 -2.477 1.00101.38 C 430 | ATOM 430 CG HIS A 623 88.754 30.015 -2.744 1.00101.38 C 431 | ATOM 431 ND1 HIS A 623 89.867 29.977 -3.556 1.00101.38 N 432 | ATOM 432 CD2 HIS A 623 88.594 28.757 -2.268 1.00101.38 C 433 | ATOM 433 CE1 HIS A 623 90.360 28.751 -3.567 1.00101.38 C 434 | ATOM 434 NE2 HIS A 623 89.607 27.992 -2.793 1.00101.38 N 435 | ATOM 435 N SER A 624 85.434 30.735 -4.110 1.00 37.38 N 436 | ATOM 436 CA SER A 624 84.475 29.879 -4.789 1.00 37.38 C 437 | ATOM 437 C SER A 624 83.118 30.291 -4.217 1.00 37.38 C 438 | ATOM 438 O SER A 624 83.063 31.086 -3.282 1.00 37.38 O 439 | ATOM 439 CB SER A 624 84.783 28.399 -4.523 1.00 45.41 C 440 | ATOM 440 OG SER A 624 84.751 28.077 -3.146 1.00 45.41 O 441 | ATOM 441 N PRO A 625 82.011 29.766 -4.761 1.00 55.21 N 442 | ATOM 442 CA PRO A 625 80.699 30.156 -4.235 1.00 55.21 C 443 | ATOM 443 C PRO A 625 80.572 30.148 -2.704 1.00 55.21 C 444 | ATOM 444 O PRO A 625 80.705 29.101 -2.070 1.00 55.21 O 445 | ATOM 445 CB PRO A 625 79.749 29.151 -4.897 1.00 51.32 C 446 | ATOM 446 CG PRO A 625 80.436 28.809 -6.179 1.00 51.32 C 447 | ATOM 447 CD PRO A 625 81.878 28.677 -5.745 1.00 51.32 C 448 | ATOM 448 N GLY A 626 80.318 31.325 -2.130 1.00 59.21 N 449 | ATOM 449 CA GLY A 626 80.138 31.467 -0.690 1.00 59.21 C 450 | ATOM 450 C GLY A 626 81.323 31.286 0.250 1.00 59.21 C 451 | ATOM 451 O GLY A 626 81.151 31.257 1.471 1.00 59.21 O 452 | ATOM 452 N VAL A 627 82.526 31.198 -0.306 1.00 46.49 N 453 | ATOM 453 CA VAL A 627 83.729 30.984 0.485 1.00 46.49 C 454 | ATOM 454 C VAL A 627 84.806 32.032 0.290 1.00 46.49 C 455 | ATOM 455 O VAL A 627 85.026 32.524 -0.815 1.00 46.49 O 456 | ATOM 456 CB VAL A 627 84.367 29.614 0.147 1.00 44.98 C 457 | ATOM 457 CG1 VAL A 627 85.758 29.520 0.754 1.00 44.98 C 458 | ATOM 458 CG2 VAL A 627 83.476 28.479 0.639 1.00 44.98 C 459 | ATOM 459 N ALA A 628 85.498 32.334 1.383 1.00 41.68 N 460 | ATOM 460 CA ALA A 628 86.599 33.286 1.407 1.00 41.68 C 461 | ATOM 461 C ALA A 628 87.816 32.533 1.910 1.00 41.68 C 462 | ATOM 462 O ALA A 628 87.692 31.527 2.593 1.00 41.68 O 463 | ATOM 463 CB ALA A 628 86.288 34.427 2.358 1.00 21.39 C 464 | ATOM 464 N VAL A 629 88.993 33.023 1.558 1.00 43.65 N 465 | ATOM 465 CA VAL A 629 90.234 32.427 2.009 1.00 43.65 C 466 | ATOM 466 C VAL A 629 90.927 33.513 2.796 1.00 43.65 C 467 | ATOM 467 O VAL A 629 91.192 34.595 2.280 1.00 43.65 O 468 | ATOM 468 CB VAL A 629 91.127 31.981 0.821 1.00 29.54 C 469 | ATOM 469 CG1 VAL A 629 92.593 31.944 1.238 1.00 29.54 C 470 | ATOM 470 CG2 VAL A 629 90.697 30.586 0.361 1.00 29.54 C 471 | ATOM 471 N ILE A 630 91.197 33.232 4.060 1.00 37.63 N 472 | ATOM 472 CA ILE A 630 91.860 34.198 4.912 1.00 37.63 C 473 | ATOM 473 C ILE A 630 93.242 33.685 5.266 1.00 37.63 C 474 | ATOM 474 O ILE A 630 93.445 32.495 5.499 1.00 37.63 O 475 | ATOM 475 CB ILE A 630 91.023 34.457 6.191 1.00 38.46 C 476 | ATOM 476 CG1 ILE A 630 89.622 34.935 5.790 1.00 38.46 C 477 | ATOM 477 CG2 ILE A 630 91.697 35.504 7.074 1.00 38.46 C 478 | ATOM 478 CD1 ILE A 630 88.681 35.074 6.948 1.00 38.46 C 479 | ATOM 479 N GLN A 631 94.198 34.596 5.292 1.00 42.40 N 480 | ATOM 480 CA GLN A 631 95.569 34.259 5.598 1.00 42.40 C 481 | ATOM 481 C GLN A 631 95.955 34.981 6.887 1.00 42.40 C 482 | ATOM 482 O GLN A 631 95.972 36.214 6.944 1.00 42.40 O 483 | ATOM 483 CB GLN A 631 96.441 34.694 4.423 1.00 68.63 C 484 | ATOM 484 CG GLN A 631 97.873 34.217 4.442 1.00 68.63 C 485 | ATOM 485 CD GLN A 631 98.527 34.393 3.087 1.00 68.63 C 486 | ATOM 486 OE1 GLN A 631 98.451 35.467 2.478 1.00 68.63 O 487 | ATOM 487 NE2 GLN A 631 99.174 33.338 2.602 1.00 68.63 N 488 | ATOM 488 N PHE A 632 96.250 34.203 7.923 1.00 42.82 N 489 | ATOM 489 CA PHE A 632 96.612 34.747 9.230 1.00 42.82 C 490 | ATOM 490 C PHE A 632 98.077 34.530 9.531 1.00 42.82 C 491 | ATOM 491 O PHE A 632 98.746 33.749 8.868 1.00 42.82 O 492 | ATOM 492 CB PHE A 632 95.852 34.033 10.351 1.00 26.04 C 493 | ATOM 493 CG PHE A 632 94.370 34.274 10.366 1.00 26.04 C 494 | ATOM 494 CD1 PHE A 632 93.831 35.317 11.113 1.00 26.04 C 495 | ATOM 495 CD2 PHE A 632 93.503 33.390 9.726 1.00 26.04 C 496 | ATOM 496 CE1 PHE A 632 92.442 35.467 11.234 1.00 26.04 C 497 | ATOM 497 CE2 PHE A 632 92.118 33.533 9.838 1.00 26.04 C 498 | ATOM 498 CZ PHE A 632 91.585 34.575 10.599 1.00 26.04 C 499 | ATOM 499 N ALA A 633 98.551 35.225 10.558 1.00 54.46 N 500 | ATOM 500 CA ALA A 633 99.907 35.081 11.066 1.00 54.46 C 501 | ATOM 501 C ALA A 633 99.568 34.677 12.491 1.00 54.46 C 502 | ATOM 502 O ALA A 633 99.242 35.533 13.316 1.00 54.46 O 503 | ATOM 503 CB ALA A 633 100.631 36.396 11.059 1.00 29.34 C 504 | ATOM 504 N VAL A 634 99.615 33.375 12.767 1.00 56.13 N 505 | ATOM 505 CA VAL A 634 99.252 32.848 14.079 1.00 56.13 C 506 | ATOM 506 C VAL A 634 100.313 32.818 15.167 1.00 56.13 C 507 | ATOM 507 O VAL A 634 101.425 32.325 14.964 1.00 56.13 O 508 | ATOM 508 CB VAL A 634 98.690 31.422 13.953 1.00 66.02 C 509 | ATOM 509 CG1 VAL A 634 98.286 30.898 15.326 1.00 66.02 C 510 | ATOM 510 CG2 VAL A 634 97.500 31.420 13.008 1.00 66.02 C 511 | ATOM 511 N GLY A 635 99.943 33.342 16.331 1.00 56.59 N 512 | ATOM 512 CA GLY A 635 100.826 33.349 17.485 1.00 56.59 C 513 | ATOM 513 C GLY A 635 102.164 34.055 17.403 1.00 56.59 C 514 | ATOM 514 O GLY A 635 102.531 34.624 16.372 1.00 56.59 O 515 | ATOM 515 N GLU A 636 102.885 33.995 18.522 1.00109.27 N 516 | ATOM 516 CA GLU A 636 104.206 34.597 18.707 1.00109.27 C 517 | ATOM 517 C GLU A 636 105.053 34.656 17.438 1.00109.27 C 518 | ATOM 518 O GLU A 636 105.245 35.723 16.853 1.00109.27 O 519 | ATOM 519 CB GLU A 636 104.966 33.815 19.783 1.00118.24 C 520 | ATOM 520 CG GLU A 636 106.306 34.405 20.191 1.00118.24 C 521 | ATOM 521 CD GLU A 636 106.217 35.250 21.451 1.00118.24 C 522 | ATOM 522 OE1 GLU A 636 105.489 36.268 21.432 1.00118.24 O 523 | ATOM 523 OE2 GLU A 636 106.874 34.894 22.459 1.00118.24 O 524 | ATOM 524 N HIS A 637 105.561 33.498 17.029 1.00168.42 N 525 | ATOM 525 CA HIS A 637 106.404 33.383 15.844 1.00168.42 C 526 | ATOM 526 C HIS A 637 105.775 33.938 14.568 1.00168.42 C 527 | ATOM 527 O HIS A 637 106.486 34.347 13.650 1.00168.42 O 528 | ATOM 528 CB HIS A 637 106.782 31.917 15.630 1.00159.33 C 529 | ATOM 529 CG HIS A 637 105.609 30.988 15.636 1.00159.33 C 530 | ATOM 530 ND1 HIS A 637 104.785 30.840 16.731 1.00159.33 N 531 | ATOM 531 CD2 HIS A 637 105.117 30.166 14.680 1.00159.33 C 532 | ATOM 532 CE1 HIS A 637 103.835 29.966 16.449 1.00159.33 C 533 | ATOM 533 NE2 HIS A 637 104.014 29.542 15.211 1.00159.33 N 534 | ATOM 534 N ARG A 638 104.446 33.946 14.513 1.00 96.09 N 535 | ATOM 535 CA ARG A 638 103.714 34.445 13.350 1.00 96.09 C 536 | ATOM 536 C ARG A 638 103.783 33.464 12.182 1.00 96.09 C 537 | ATOM 537 O ARG A 638 104.257 33.810 11.098 1.00 96.09 O 538 | ATOM 538 CB ARG A 638 104.268 35.802 12.897 1.00143.03 C 539 | ATOM 539 CG ARG A 638 104.226 36.897 13.948 1.00143.03 C 540 | ATOM 540 CD ARG A 638 104.942 38.141 13.443 1.00143.03 C 541 | ATOM 541 NE ARG A 638 105.106 39.155 14.482 1.00143.03 N 542 | ATOM 542 CZ ARG A 638 105.863 40.242 14.353 1.00143.03 C 543 | ATOM 543 NH1 ARG A 638 106.529 40.460 13.227 1.00143.03 N 544 | ATOM 544 NH2 ARG A 638 105.959 41.110 15.352 1.00143.03 N 545 | ATOM 545 N ALA A 639 103.312 32.241 12.405 1.00 99.74 N 546 | ATOM 546 CA ALA A 639 103.318 31.223 11.358 1.00 99.74 C 547 | ATOM 547 C ALA A 639 102.202 31.511 10.360 1.00 99.74 C 548 | ATOM 548 O ALA A 639 101.048 31.681 10.750 1.00 99.74 O 549 | ATOM 549 CB ALA A 639 103.125 29.839 11.970 1.00 99.38 C 550 | ATOM 550 N GLN A 640 102.542 31.566 9.075 1.00 70.23 N 551 | ATOM 551 CA GLN A 640 101.541 31.840 8.051 1.00 70.23 C 552 | ATOM 552 C GLN A 640 100.550 30.686 7.899 1.00 70.23 C 553 | ATOM 553 O GLN A 640 100.920 29.574 7.538 1.00 70.23 O 554 | ATOM 554 CB GLN A 640 102.213 32.139 6.710 1.00 94.05 C 555 | ATOM 555 CG GLN A 640 103.139 33.344 6.751 1.00 94.05 C 556 | ATOM 556 CD GLN A 640 103.670 33.733 5.379 1.00 94.05 C 557 | ATOM 557 OE1 GLN A 640 104.553 34.585 5.262 1.00 94.05 O 558 | ATOM 558 NE2 GLN A 640 103.128 33.113 4.333 1.00 94.05 N 559 | ATOM 559 N VAL A 641 99.285 30.967 8.192 1.00 47.80 N 560 | ATOM 560 CA VAL A 641 98.222 29.982 8.097 1.00 47.80 C 561 | ATOM 561 C VAL A 641 97.120 30.551 7.222 1.00 47.80 C 562 | ATOM 562 O VAL A 641 96.684 31.682 7.425 1.00 47.80 O 563 | ATOM 563 CB VAL A 641 97.598 29.682 9.476 1.00 38.46 C 564 | ATOM 564 CG1 VAL A 641 96.546 28.585 9.344 1.00 38.46 C 565 | ATOM 565 CG2 VAL A 641 98.669 29.276 10.453 1.00 38.46 C 566 | ATOM 566 N SER A 642 96.678 29.769 6.246 1.00 36.59 N 567 | ATOM 567 CA SER A 642 95.608 30.189 5.367 1.00 36.59 C 568 | ATOM 568 C SER A 642 94.469 29.223 5.624 1.00 36.59 C 569 | ATOM 569 O SER A 642 94.681 28.022 5.773 1.00 36.59 O 570 | ATOM 570 CB SER A 642 96.045 30.141 3.906 1.00 42.56 C 571 | ATOM 571 OG SER A 642 97.035 31.127 3.645 1.00 42.56 O 572 | ATOM 572 N VAL A 643 93.258 29.756 5.693 1.00 45.35 N 573 | ATOM 573 CA VAL A 643 92.109 28.931 5.976 1.00 45.35 C 574 | ATOM 574 C VAL A 643 90.971 29.282 5.019 1.00 45.35 C 575 | ATOM 575 O VAL A 643 90.978 30.333 4.390 1.00 45.35 O 576 | ATOM 576 CB VAL A 643 91.720 29.111 7.464 1.00 39.71 C 577 | ATOM 577 CG1 VAL A 643 90.859 30.335 7.647 1.00 39.71 C 578 | ATOM 578 CG2 VAL A 643 91.067 27.877 7.976 1.00 39.71 C 579 | ATOM 579 N GLU A 644 90.005 28.388 4.893 1.00 48.01 N 580 | ATOM 580 CA GLU A 644 88.890 28.586 3.984 1.00 48.01 C 581 | ATOM 581 C GLU A 644 87.579 28.523 4.760 1.00 48.01 C 582 | ATOM 582 O GLU A 644 87.304 27.520 5.434 1.00 48.01 O 583 | ATOM 583 CB GLU A 644 88.936 27.479 2.944 1.00 62.79 C 584 | ATOM 584 CG GLU A 644 87.982 27.594 1.795 1.00 62.79 C 585 | ATOM 585 CD GLU A 644 88.093 26.397 0.879 1.00 62.79 C 586 | ATOM 586 OE1 GLU A 644 87.679 25.295 1.291 1.00 62.79 O 587 | ATOM 587 OE2 GLU A 644 88.611 26.551 -0.244 1.00 62.79 O 588 | ATOM 588 N VAL A 645 86.767 29.580 4.669 1.00 35.14 N 589 | ATOM 589 CA VAL A 645 85.499 29.610 5.394 1.00 35.14 C 590 | ATOM 590 C VAL A 645 84.349 30.213 4.628 1.00 35.14 C 591 | ATOM 591 O VAL A 645 84.551 30.942 3.673 1.00 35.14 O 592 | ATOM 592 CB VAL A 645 85.615 30.410 6.686 1.00 40.68 C 593 | ATOM 593 CG1 VAL A 645 86.689 29.821 7.553 1.00 40.68 C 594 | ATOM 594 CG2 VAL A 645 85.918 31.867 6.363 1.00 40.68 C 595 | ATOM 595 N LEU A 646 83.133 29.887 5.058 1.00 31.76 N 596 | ATOM 596 CA LEU A 646 81.933 30.447 4.461 1.00 31.76 C 597 | ATOM 597 C LEU A 646 82.028 31.925 4.812 1.00 31.76 C 598 | ATOM 598 O LEU A 646 82.431 32.280 5.928 1.00 31.76 O 599 | ATOM 599 CB LEU A 646 80.692 29.826 5.088 1.00 43.26 C 600 | ATOM 600 CG LEU A 646 80.474 28.371 4.684 1.00 43.26 C 601 | ATOM 601 CD1 LEU A 646 79.361 27.780 5.517 1.00 43.26 C 602 | ATOM 602 CD2 LEU A 646 80.134 28.293 3.202 1.00 43.26 C 603 | ATOM 603 N VAL A 647 81.675 32.785 3.861 1.00 45.17 N 604 | ATOM 604 CA VAL A 647 81.784 34.227 4.072 1.00 45.17 C 605 | ATOM 605 C VAL A 647 81.148 34.740 5.355 1.00 45.17 C 606 | ATOM 606 O VAL A 647 81.658 35.682 5.959 1.00 45.17 O 607 | ATOM 607 CB VAL A 647 81.214 35.021 2.860 1.00 37.36 C 608 | ATOM 608 CG1 VAL A 647 82.019 34.691 1.616 1.00 37.36 C 609 | ATOM 609 CG2 VAL A 647 79.730 34.698 2.650 1.00 37.36 C 610 | ATOM 610 N GLU A 648 80.062 34.106 5.791 1.00 42.81 N 611 | ATOM 611 CA GLU A 648 79.379 34.549 7.000 1.00 42.81 C 612 | ATOM 612 C GLU A 648 79.945 34.066 8.336 1.00 42.81 C 613 | ATOM 613 O GLU A 648 79.370 34.360 9.386 1.00 42.81 O 614 | ATOM 614 CB GLU A 648 77.880 34.217 6.918 1.00 54.66 C 615 | ATOM 615 CG GLU A 648 77.532 32.881 6.280 1.00 54.66 C 616 | ATOM 616 CD GLU A 648 77.283 32.961 4.780 1.00 54.66 C 617 | ATOM 617 OE1 GLU A 648 76.472 33.793 4.336 1.00 54.66 O 618 | ATOM 618 OE2 GLU A 648 77.888 32.175 4.037 1.00 54.66 O 619 | ATOM 619 N TYR A 649 81.075 33.353 8.300 1.00 38.91 N 620 | ATOM 620 CA TYR A 649 81.722 32.838 9.512 1.00 38.91 C 621 | ATOM 621 C TYR A 649 82.337 33.979 10.315 1.00 38.91 C 622 | ATOM 622 O TYR A 649 83.169 34.727 9.808 1.00 38.91 O 623 | ATOM 623 CB TYR A 649 82.830 31.841 9.159 1.00 45.40 C 624 | ATOM 624 CG TYR A 649 83.489 31.243 10.378 1.00 45.40 C 625 | ATOM 625 CD1 TYR A 649 82.996 30.078 10.954 1.00 45.40 C 626 | ATOM 626 CD2 TYR A 649 84.554 31.890 11.006 1.00 45.40 C 627 | ATOM 627 CE1 TYR A 649 83.539 29.572 12.123 1.00 45.40 C 628 | ATOM 628 CE2 TYR A 649 85.101 31.396 12.178 1.00 45.40 C 629 | ATOM 629 CZ TYR A 649 84.587 30.231 12.733 1.00 45.40 C 630 | ATOM 630 OH TYR A 649 85.113 29.730 13.905 1.00 45.40 O 631 | ATOM 631 N PRO A 650 81.964 34.104 11.593 1.00 34.53 N 632 | ATOM 632 CA PRO A 650 82.523 35.191 12.396 1.00 34.53 C 633 | ATOM 633 C PRO A 650 83.701 34.876 13.306 1.00 34.53 C 634 | ATOM 634 O PRO A 650 83.682 33.885 14.045 1.00 34.53 O 635 | ATOM 635 CB PRO A 650 81.319 35.660 13.192 1.00 31.64 C 636 | ATOM 636 CG PRO A 650 80.644 34.353 13.503 1.00 31.64 C 637 | ATOM 637 CD PRO A 650 80.721 33.593 12.191 1.00 31.64 C 638 | ATOM 638 N PHE A 651 84.714 35.740 13.257 1.00 32.17 N 639 | ATOM 639 CA PHE A 651 85.887 35.601 14.100 1.00 32.17 C 640 | ATOM 640 C PHE A 651 85.701 36.597 15.221 1.00 32.17 C 641 | ATOM 641 O PHE A 651 84.943 37.556 15.076 1.00 32.17 O 642 | ATOM 642 CB PHE A 651 87.168 35.924 13.337 1.00 27.06 C 643 | ATOM 643 CG PHE A 651 87.480 34.945 12.238 1.00 27.06 C 644 | ATOM 644 CD1 PHE A 651 86.881 35.066 10.986 1.00 27.06 C 645 | ATOM 645 CD2 PHE A 651 88.348 33.868 12.469 1.00 27.06 C 646 | ATOM 646 CE1 PHE A 651 87.141 34.133 9.989 1.00 27.06 C 647 | ATOM 647 CE2 PHE A 651 88.607 32.933 11.473 1.00 27.06 C 648 | ATOM 648 CZ PHE A 651 88.006 33.063 10.236 1.00 27.06 C 649 | ATOM 649 N PHE A 652 86.357 36.381 16.353 1.00 46.46 N 650 | ATOM 650 CA PHE A 652 86.201 37.322 17.442 1.00 46.46 C 651 | ATOM 651 C PHE A 652 87.460 38.149 17.549 1.00 46.46 C 652 | ATOM 652 O PHE A 652 88.505 37.658 17.981 1.00 46.46 O 653 | ATOM 653 CB PHE A 652 85.911 36.602 18.757 1.00 32.67 C 654 | ATOM 654 CG PHE A 652 85.343 37.505 19.809 1.00 32.67 C 655 | ATOM 655 CD1 PHE A 652 86.153 38.452 20.448 1.00 32.67 C 656 | ATOM 656 CD2 PHE A 652 83.980 37.467 20.114 1.00 32.67 C 657 | ATOM 657 CE1 PHE A 652 85.608 39.354 21.378 1.00 32.67 C 658 | ATOM 658 CE2 PHE A 652 83.422 38.367 21.040 1.00 32.67 C 659 | ATOM 659 CZ PHE A 652 84.240 39.312 21.672 1.00 32.67 C 660 | ATOM 660 N VAL A 653 87.355 39.409 17.140 1.00 38.99 N 661 | ATOM 661 CA VAL A 653 88.493 40.323 17.157 1.00 38.99 C 662 | ATOM 662 C VAL A 653 88.700 40.964 18.521 1.00 38.99 C 663 | ATOM 663 O VAL A 653 87.767 41.485 19.118 1.00 38.99 O 664 | ATOM 664 CB VAL A 653 88.315 41.420 16.085 1.00 28.04 C 665 | ATOM 665 CG1 VAL A 653 89.501 42.363 16.103 1.00 28.04 C 666 | ATOM 666 CG2 VAL A 653 88.182 40.774 14.713 1.00 28.04 C 667 | ATOM 667 N PHE A 654 89.934 40.916 19.009 1.00 41.67 N 668 | ATOM 668 CA PHE A 654 90.260 41.488 20.312 1.00 41.67 C 669 | ATOM 669 C PHE A 654 89.764 42.915 20.438 1.00 41.67 C 670 | ATOM 670 O PHE A 654 90.107 43.773 19.631 1.00 41.67 O 671 | ATOM 671 CB PHE A 654 91.770 41.467 20.550 1.00 43.49 C 672 | ATOM 672 CG PHE A 654 92.301 40.145 21.029 1.00 43.49 C 673 | ATOM 673 CD1 PHE A 654 92.941 39.272 20.151 1.00 43.49 C 674 | ATOM 674 CD2 PHE A 654 92.221 39.797 22.376 1.00 43.49 C 675 | ATOM 675 CE1 PHE A 654 93.504 38.071 20.613 1.00 43.49 C 676 | ATOM 676 CE2 PHE A 654 92.779 38.603 22.843 1.00 43.49 C 677 | ATOM 677 CZ PHE A 654 93.423 37.741 21.962 1.00 43.49 C 678 | ATOM 678 N GLY A 655 88.956 43.163 21.457 1.00 41.19 N 679 | ATOM 679 CA GLY A 655 88.426 44.496 21.693 1.00 41.19 C 680 | ATOM 680 C GLY A 655 87.384 44.977 20.700 1.00 41.19 C 681 | ATOM 681 O GLY A 655 86.986 46.134 20.747 1.00 41.19 O 682 | ATOM 682 N GLN A 656 86.917 44.094 19.824 1.00 41.64 N 683 | ATOM 683 CA GLN A 656 85.940 44.474 18.808 1.00 41.64 C 684 | ATOM 684 C GLN A 656 84.760 43.514 18.683 1.00 41.64 C 685 | ATOM 685 O GLN A 656 83.646 43.944 18.403 1.00 41.64 O 686 | ATOM 686 CB GLN A 656 86.653 44.616 17.458 1.00 46.27 C 687 | ATOM 687 CG GLN A 656 85.749 44.851 16.268 1.00 46.27 C 688 | ATOM 688 CD GLN A 656 86.536 45.137 14.998 1.00 46.27 C 689 | ATOM 689 OE1 GLN A 656 87.115 46.223 14.834 1.00 46.27 O 690 | ATOM 690 NE2 GLN A 656 86.576 44.155 14.097 1.00 46.27 N 691 | ATOM 691 N GLY A 657 85.001 42.217 18.871 1.00 30.61 N 692 | ATOM 692 CA GLY A 657 83.916 41.256 18.792 1.00 30.61 C 693 | ATOM 693 C GLY A 657 83.698 40.624 17.436 1.00 30.61 C 694 | ATOM 694 O GLY A 657 84.538 40.725 16.554 1.00 30.61 O 695 | ATOM 695 N TRP A 658 82.549 39.988 17.259 1.00 39.78 N 696 | ATOM 696 CA TRP A 658 82.242 39.310 16.015 1.00 39.78 C 697 | ATOM 697 C TRP A 658 82.560 40.129 14.772 1.00 39.78 C 698 | ATOM 698 O TRP A 658 82.062 41.237 14.596 1.00 39.78 O 699 | ATOM 699 CB TRP A 658 80.779 38.862 16.029 1.00 36.23 C 700 | ATOM 700 CG TRP A 658 80.509 37.951 17.179 1.00 36.23 C 701 | ATOM 701 CD1 TRP A 658 79.611 38.146 18.190 1.00 36.23 C 702 | ATOM 702 CD2 TRP A 658 81.231 36.752 17.511 1.00 36.23 C 703 | ATOM 703 NE1 TRP A 658 79.737 37.151 19.139 1.00 36.23 N 704 | ATOM 704 CE2 TRP A 658 80.724 36.284 18.747 1.00 36.23 C 705 | ATOM 705 CE3 TRP A 658 82.261 36.034 16.888 1.00 36.23 C 706 | ATOM 706 CZ2 TRP A 658 81.210 35.132 19.369 1.00 36.23 C 707 | ATOM 707 CZ3 TRP A 658 82.747 34.877 17.514 1.00 36.23 C 708 | ATOM 708 CH2 TRP A 658 82.218 34.443 18.741 1.00 36.23 C 709 | ATOM 709 N SER A 659 83.405 39.576 13.916 1.00 44.09 N 710 | ATOM 710 CA SER A 659 83.796 40.243 12.683 1.00 44.09 C 711 | ATOM 711 C SER A 659 83.883 39.213 11.561 1.00 44.09 C 712 | ATOM 712 O SER A 659 84.489 38.158 11.737 1.00 44.09 O 713 | ATOM 713 CB SER A 659 85.149 40.935 12.872 1.00 27.68 C 714 | ATOM 714 OG SER A 659 85.090 41.887 13.921 1.00 27.68 O 715 | ATOM 715 N SER A 660 83.271 39.515 10.416 1.00 45.80 N 716 | ATOM 716 CA SER A 660 83.286 38.600 9.278 1.00 45.80 C 717 | ATOM 717 C SER A 660 83.584 39.314 7.962 1.00 45.80 C 718 | ATOM 718 O SER A 660 83.807 40.525 7.933 1.00 45.80 O 719 | ATOM 719 CB SER A 660 81.941 37.889 9.153 1.00 38.72 C 720 | ATOM 720 OG SER A 660 80.974 38.759 8.597 1.00 38.72 O 721 | ATOM 721 N CYS A 661 83.591 38.549 6.873 1.00 73.81 N 722 | ATOM 722 CA CYS A 661 83.852 39.099 5.548 1.00 73.81 C 723 | ATOM 723 C CYS A 661 82.649 39.891 5.089 1.00 73.81 C 724 | ATOM 724 O CYS A 661 82.778 40.990 4.552 1.00 73.81 O 725 | ATOM 725 CB CYS A 661 84.106 37.983 4.540 1.00 75.82 C 726 | ATOM 726 SG CYS A 661 85.603 37.070 4.838 1.00 75.82 S 727 | ATOM 727 N CYS A 662 81.476 39.306 5.300 1.00 40.98 N 728 | ATOM 728 CA CYS A 662 80.219 39.919 4.918 1.00 40.98 C 729 | ATOM 729 C CYS A 662 79.389 40.164 6.164 1.00 40.98 C 730 | ATOM 730 O CYS A 662 78.457 39.406 6.459 1.00 40.98 O 731 | ATOM 731 CB CYS A 662 79.456 38.988 3.980 1.00 87.24 C 732 | ATOM 732 SG CYS A 662 80.527 38.083 2.863 1.00 87.24 S 733 | ATOM 733 N PRO A 663 79.723 41.218 6.924 1.00 33.37 N 734 | ATOM 734 CA PRO A 663 78.987 41.556 8.149 1.00 33.37 C 735 | ATOM 735 C PRO A 663 77.495 41.454 7.888 1.00 33.37 C 736 | ATOM 736 O PRO A 663 76.747 40.841 8.659 1.00 33.37 O 737 | ATOM 737 CB PRO A 663 79.398 42.997 8.409 1.00 36.13 C 738 | ATOM 738 CG PRO A 663 80.779 43.044 7.887 1.00 36.13 C 739 | ATOM 739 CD PRO A 663 80.720 42.252 6.605 1.00 36.13 C 740 | ATOM 740 N GLU A 664 77.076 42.048 6.772 1.00 42.79 N 741 | ATOM 741 CA GLU A 664 75.675 42.059 6.387 1.00 42.79 C 742 | ATOM 742 C GLU A 664 75.069 40.668 6.409 1.00 42.79 C 743 | ATOM 743 O GLU A 664 74.053 40.445 7.063 1.00 42.79 O 744 | ATOM 744 CB GLU A 664 75.514 42.685 5.002 1.00 75.66 C 745 | ATOM 745 CG GLU A 664 74.070 42.910 4.598 1.00 75.66 C 746 | ATOM 746 CD GLU A 664 73.937 43.819 3.387 1.00 75.66 C 747 | ATOM 747 OE1 GLU A 664 74.487 44.941 3.429 1.00 75.66 O 748 | ATOM 748 OE2 GLU A 664 73.280 43.419 2.397 1.00 75.66 O 749 | ATOM 749 N ARG A 665 75.697 39.724 5.717 1.00 43.57 N 750 | ATOM 750 CA ARG A 665 75.173 38.361 5.669 1.00 43.57 C 751 | ATOM 751 C ARG A 665 75.231 37.660 7.031 1.00 43.57 C 752 | ATOM 752 O ARG A 665 74.308 36.930 7.399 1.00 43.57 O 753 | ATOM 753 CB ARG A 665 75.913 37.544 4.601 1.00 70.99 C 754 | ATOM 754 CG ARG A 665 75.746 38.086 3.178 1.00 70.99 C 755 | ATOM 755 CD ARG A 665 76.195 37.075 2.132 1.00 70.99 C 756 | ATOM 756 NE ARG A 665 75.375 35.861 2.155 1.00 70.99 N 757 | ATOM 757 CZ ARG A 665 74.126 35.790 1.703 1.00 70.99 C 758 | ATOM 758 NH1 ARG A 665 73.549 36.865 1.182 1.00 70.99 N 759 | ATOM 759 NH2 ARG A 665 73.450 34.651 1.779 1.00 70.99 N 760 | ATOM 760 N THR A 666 76.304 37.882 7.781 1.00 39.27 N 761 | ATOM 761 CA THR A 666 76.426 37.271 9.100 1.00 39.27 C 762 | ATOM 762 C THR A 666 75.279 37.782 9.985 1.00 39.27 C 763 | ATOM 763 O THR A 666 74.644 37.015 10.721 1.00 39.27 O 764 | ATOM 764 CB THR A 666 77.774 37.635 9.753 1.00 38.00 C 765 | ATOM 765 OG1 THR A 666 78.844 37.091 8.967 1.00 38.00 O 766 | ATOM 766 CG2 THR A 666 77.842 37.104 11.175 1.00 38.00 C 767 | ATOM 767 N SER A 667 75.027 39.088 9.914 1.00 34.40 N 768 | ATOM 768 CA SER A 667 73.947 39.697 10.666 1.00 34.40 C 769 | ATOM 769 C SER A 667 72.595 39.159 10.198 1.00 34.40 C 770 | ATOM 770 O SER A 667 71.750 38.783 11.005 1.00 34.40 O 771 | ATOM 771 CB SER A 667 73.972 41.214 10.488 1.00 50.62 C 772 | ATOM 772 OG SER A 667 72.814 41.791 11.064 1.00 50.62 O 773 | ATOM 773 N GLN A 668 72.372 39.112 8.894 1.00 44.84 N 774 | ATOM 774 CA GLN A 668 71.085 38.618 8.424 1.00 44.84 C 775 | ATOM 775 C GLN A 668 70.857 37.160 8.802 1.00 44.84 C 776 | ATOM 776 O GLN A 668 69.814 36.794 9.346 1.00 44.84 O 777 | ATOM 777 CB GLN A 668 70.975 38.789 6.912 1.00 67.12 C 778 | ATOM 778 CG GLN A 668 70.710 40.210 6.485 1.00 67.12 C 779 | ATOM 779 CD GLN A 668 70.640 40.354 4.980 1.00 67.12 C 780 | ATOM 780 OE1 GLN A 668 71.660 40.301 4.286 1.00 67.12 O 781 | ATOM 781 NE2 GLN A 668 69.428 40.524 4.462 1.00 67.12 N 782 | ATOM 782 N LEU A 669 71.855 36.336 8.515 1.00 50.50 N 783 | ATOM 783 CA LEU A 669 71.791 34.913 8.785 1.00 50.50 C 784 | ATOM 784 C LEU A 669 71.787 34.587 10.272 1.00 50.50 C 785 | ATOM 785 O LEU A 669 70.977 33.778 10.729 1.00 50.50 O 786 | ATOM 786 CB LEU A 669 72.975 34.221 8.110 1.00 54.26 C 787 | ATOM 787 CG LEU A 669 73.111 32.716 8.324 1.00 54.26 C 788 | ATOM 788 CD1 LEU A 669 71.965 31.983 7.621 1.00 54.26 C 789 | ATOM 789 CD2 LEU A 669 74.456 32.259 7.781 1.00 54.26 C 790 | ATOM 790 N PHE A 670 72.679 35.230 11.027 1.00 48.64 N 791 | ATOM 791 CA PHE A 670 72.795 34.958 12.456 1.00 48.64 C 792 | ATOM 792 C PHE A 670 72.104 35.908 13.417 1.00 48.64 C 793 | ATOM 793 O PHE A 670 71.921 35.569 14.587 1.00 48.64 O 794 | ATOM 794 CB PHE A 670 74.273 34.847 12.856 1.00 33.16 C 795 | ATOM 795 CG PHE A 670 74.931 33.591 12.386 1.00 33.16 C 796 | ATOM 796 CD1 PHE A 670 74.322 32.359 12.588 1.00 33.16 C 797 | ATOM 797 CD2 PHE A 670 76.157 33.636 11.738 1.00 33.16 C 798 | ATOM 798 CE1 PHE A 670 74.928 31.180 12.143 1.00 33.16 C 799 | ATOM 799 CE2 PHE A 670 76.777 32.460 11.287 1.00 33.16 C 800 | ATOM 800 CZ PHE A 670 76.158 31.231 11.491 1.00 33.16 C 801 | ATOM 801 N ASP A 671 71.721 37.087 12.936 1.00 42.27 N 802 | ATOM 802 CA ASP A 671 71.059 38.077 13.782 1.00 42.27 C 803 | ATOM 803 C ASP A 671 72.081 38.466 14.844 1.00 42.27 C 804 | ATOM 804 O ASP A 671 71.768 38.596 16.027 1.00 42.27 O 805 | ATOM 805 CB ASP A 671 69.815 37.463 14.421 1.00 72.28 C 806 | ATOM 806 CG ASP A 671 68.813 38.503 14.853 1.00 72.28 C 807 | ATOM 807 OD1 ASP A 671 68.933 39.667 14.399 1.00 72.28 O 808 | ATOM 808 OD2 ASP A 671 67.896 38.152 15.632 1.00 72.28 O 809 | ATOM 809 N LEU A 672 73.314 38.648 14.381 1.00 31.15 N 810 | ATOM 810 CA LEU A 672 74.441 38.998 15.223 1.00 31.15 C 811 | ATOM 811 C LEU A 672 75.058 40.310 14.766 1.00 31.15 C 812 | ATOM 812 O LEU A 672 75.565 40.402 13.655 1.00 31.15 O 813 | ATOM 813 CB LEU A 672 75.518 37.918 15.102 1.00 40.15 C 814 | ATOM 814 CG LEU A 672 76.070 37.145 16.291 1.00 40.15 C 815 | ATOM 815 CD1 LEU A 672 77.406 36.519 15.878 1.00 40.15 C 816 | ATOM 816 CD2 LEU A 672 76.268 38.066 17.451 1.00 40.15 C 817 | ATOM 817 N PRO A 673 75.017 41.351 15.598 1.00 36.11 N 818 | ATOM 818 CA PRO A 673 75.652 42.561 15.068 1.00 36.11 C 819 | ATOM 819 C PRO A 673 77.081 42.123 14.721 1.00 36.11 C 820 | ATOM 820 O PRO A 673 77.633 41.270 15.408 1.00 36.11 O 821 | ATOM 821 CB PRO A 673 75.572 43.534 16.238 1.00 31.34 C 822 | ATOM 822 CG PRO A 673 75.539 42.632 17.437 1.00 31.34 C 823 | ATOM 823 CD PRO A 673 74.646 41.499 17.014 1.00 31.34 C 824 | ATOM 824 N CYS A 674 77.683 42.692 13.678 1.00 45.31 N 825 | ATOM 825 CA CYS A 674 79.003 42.232 13.265 1.00 45.31 C 826 | ATOM 826 C CYS A 674 79.852 43.264 12.520 1.00 45.31 C 827 | ATOM 827 O CYS A 674 79.329 44.069 11.768 1.00 45.31 O 828 | ATOM 828 CB CYS A 674 78.793 40.994 12.393 1.00 62.44 C 829 | ATOM 829 SG CYS A 674 80.255 40.232 11.734 1.00 62.44 S 830 | ATOM 830 N SER A 675 81.164 43.241 12.733 1.00 41.73 N 831 | ATOM 831 CA SER A 675 82.061 44.177 12.060 1.00 41.73 C 832 | ATOM 832 C SER A 675 82.587 43.613 10.747 1.00 41.73 C 833 | ATOM 833 O SER A 675 82.303 42.465 10.381 1.00 41.73 O 834 | ATOM 834 CB SER A 675 83.264 44.510 12.936 1.00 39.59 C 835 | ATOM 835 OG SER A 675 82.889 45.254 14.075 1.00 39.59 O 836 | ATOM 836 N LYS A 676 83.368 44.425 10.043 1.00 36.68 N 837 | ATOM 837 CA LYS A 676 83.959 44.011 8.785 1.00 36.68 C 838 | ATOM 838 C LYS A 676 85.371 43.509 9.095 1.00 36.68 C 839 | ATOM 839 O LYS A 676 86.234 44.303 9.468 1.00 36.68 O 840 | ATOM 840 CB LYS A 676 84.018 45.203 7.827 1.00 65.81 C 841 | ATOM 841 CG LYS A 676 84.605 44.901 6.462 1.00 65.81 C 842 | ATOM 842 CD LYS A 676 83.818 43.817 5.744 1.00 65.81 C 843 | ATOM 843 CE LYS A 676 84.282 43.698 4.303 1.00 65.81 C 844 | ATOM 844 NZ LYS A 676 85.772 43.720 4.256 1.00 65.81 N 845 | ATOM 845 N LEU A 677 85.604 42.202 8.957 1.00 36.42 N 846 | ATOM 846 CA LEU A 677 86.930 41.637 9.239 1.00 36.42 C 847 | ATOM 847 C LEU A 677 87.934 42.364 8.367 1.00 36.42 C 848 | ATOM 848 O LEU A 677 87.676 42.597 7.202 1.00 36.42 O 849 | ATOM 849 CB LEU A 677 86.971 40.131 8.919 1.00 26.79 C 850 | ATOM 850 CG LEU A 677 88.286 39.358 9.189 1.00 26.79 C 851 | ATOM 851 CD1 LEU A 677 88.611 39.327 10.685 1.00 26.79 C 852 | ATOM 852 CD2 LEU A 677 88.144 37.923 8.656 1.00 26.79 C 853 | ATOM 853 N SER A 678 89.088 42.721 8.908 1.00 45.23 N 854 | ATOM 854 CA SER A 678 90.047 43.441 8.084 1.00 45.23 C 855 | ATOM 855 C SER A 678 91.520 43.131 8.295 1.00 45.23 C 856 | ATOM 856 O SER A 678 91.948 42.762 9.381 1.00 45.23 O 857 | ATOM 857 CB SER A 678 89.820 44.938 8.252 1.00 60.64 C 858 | ATOM 858 OG SER A 678 88.511 45.264 7.841 1.00 60.64 O 859 | ATOM 859 N VAL A 679 92.289 43.300 7.230 1.00 42.87 N 860 | ATOM 860 CA VAL A 679 93.716 43.078 7.279 1.00 42.87 C 861 | ATOM 861 C VAL A 679 94.237 43.853 8.470 1.00 42.87 C 862 | ATOM 862 O VAL A 679 94.036 45.064 8.550 1.00 42.87 O 863 | ATOM 863 CB VAL A 679 94.388 43.595 6.005 1.00 39.62 C 864 | ATOM 864 CG1 VAL A 679 95.898 43.543 6.151 1.00 39.62 C 865 | ATOM 865 CG2 VAL A 679 93.953 42.744 4.831 1.00 39.62 C 866 | ATOM 866 N GLY A 680 94.888 43.152 9.396 1.00 37.03 N 867 | ATOM 867 CA GLY A 680 95.407 43.803 10.586 1.00 37.03 C 868 | ATOM 868 C GLY A 680 94.592 43.471 11.832 1.00 37.03 C 869 | ATOM 869 O GLY A 680 95.056 43.687 12.942 1.00 37.03 O 870 | ATOM 870 N ASP A 681 93.375 42.956 11.674 1.00 42.16 N 871 | ATOM 871 CA ASP A 681 92.576 42.600 12.849 1.00 42.16 C 872 | ATOM 872 C ASP A 681 93.160 41.395 13.590 1.00 42.16 C 873 | ATOM 873 O ASP A 681 93.420 40.347 12.999 1.00 42.16 O 874 | ATOM 874 CB ASP A 681 91.136 42.275 12.462 1.00 48.55 C 875 | ATOM 875 CG ASP A 681 90.371 43.483 11.984 1.00 48.55 C 876 | ATOM 876 OD1 ASP A 681 90.819 44.621 12.234 1.00 48.55 O 877 | ATOM 877 OD2 ASP A 681 89.305 43.290 11.363 1.00 48.55 O 878 | ATOM 878 N VAL A 682 93.356 41.545 14.891 1.00 45.39 N 879 | ATOM 879 CA VAL A 682 93.893 40.468 15.699 1.00 45.39 C 880 | ATOM 880 C VAL A 682 92.752 39.622 16.228 1.00 45.39 C 881 | ATOM 881 O VAL A 682 91.983 40.059 17.072 1.00 45.39 O 882 | ATOM 882 CB VAL A 682 94.679 41.029 16.865 1.00 33.98 C 883 | ATOM 883 CG1 VAL A 682 95.410 39.898 17.601 1.00 33.98 C 884 | ATOM 884 CG2 VAL A 682 95.654 42.086 16.346 1.00 33.98 C 885 | ATOM 885 N CYS A 683 92.639 38.404 15.725 1.00 38.60 N 886 | ATOM 886 CA CYS A 683 91.575 37.510 16.147 1.00 38.60 C 887 | ATOM 887 C CYS A 683 91.941 36.601 17.309 1.00 38.60 C 888 | ATOM 888 O CYS A 683 93.111 36.361 17.587 1.00 38.60 O 889 | ATOM 889 CB CYS A 683 91.157 36.656 14.971 1.00 40.31 C 890 | ATOM 890 SG CYS A 683 90.715 37.651 13.584 1.00 40.31 S 891 | ATOM 891 N ILE A 684 90.925 36.092 17.988 1.00 35.58 N 892 | ATOM 892 CA ILE A 684 91.154 35.181 19.089 1.00 35.58 C 893 | ATOM 893 C ILE A 684 91.148 33.772 18.517 1.00 35.58 C 894 | ATOM 894 O ILE A 684 90.222 33.392 17.810 1.00 35.58 O 895 | ATOM 895 CB ILE A 684 90.042 35.277 20.149 1.00 29.36 C 896 | ATOM 896 CG1 ILE A 684 90.100 36.631 20.853 1.00 29.36 C 897 | ATOM 897 CG2 ILE A 684 90.190 34.142 21.166 1.00 29.36 C 898 | ATOM 898 CD1 ILE A 684 89.048 36.793 21.940 1.00 29.36 C 899 | ATOM 899 N SER A 685 92.204 33.016 18.797 1.00 53.68 N 900 | ATOM 900 CA SER A 685 92.302 31.630 18.352 1.00 53.68 C 901 | ATOM 901 C SER A 685 92.801 30.852 19.552 1.00 53.68 C 902 | ATOM 902 O SER A 685 93.227 31.447 20.542 1.00 53.68 O 903 | ATOM 903 CB SER A 685 93.255 31.486 17.154 1.00 37.79 C 904 | ATOM 904 OG SER A 685 94.512 32.083 17.403 1.00 37.79 O 905 | ATOM 905 N LEU A 686 92.751 29.529 19.483 1.00 43.04 N 906 | ATOM 906 CA LEU A 686 93.177 28.719 20.615 1.00 43.04 C 907 | ATOM 907 C LEU A 686 94.225 27.676 20.274 1.00 43.04 C 908 | ATOM 908 O LEU A 686 94.294 27.192 19.139 1.00 43.04 O 909 | ATOM 909 CB LEU A 686 91.967 28.005 21.224 1.00 34.20 C 910 | ATOM 910 CG LEU A 686 90.803 28.827 21.786 1.00 34.20 C 911 | ATOM 911 CD1 LEU A 686 89.682 27.916 22.264 1.00 34.20 C 912 | ATOM 912 CD2 LEU A 686 91.305 29.692 22.920 1.00 34.20 C 913 | ATOM 913 N THR A 687 95.021 27.324 21.283 1.00 48.07 N 914 | ATOM 914 CA THR A 687 96.064 26.303 21.182 1.00 48.07 C 915 | ATOM 915 C THR A 687 96.143 25.633 22.554 1.00 48.07 C 916 | ATOM 916 O THR A 687 95.802 26.242 23.565 1.00 48.07 O 917 | ATOM 917 CB THR A 687 97.448 26.897 20.889 1.00 52.43 C 918 | ATOM 918 OG1 THR A 687 97.870 27.680 22.013 1.00 52.43 O 919 | ATOM 919 CG2 THR A 687 97.408 27.763 19.632 1.00 52.43 C 920 | ATOM 920 N LEU A 688 96.599 24.388 22.594 1.00 43.09 N 921 | ATOM 921 CA LEU A 688 96.694 23.674 23.858 1.00 43.09 C 922 | ATOM 922 C LEU A 688 97.798 24.264 24.716 1.00 43.09 C 923 | ATOM 923 O LEU A 688 98.743 24.854 24.199 1.00 43.09 O 924 | ATOM 924 CB LEU A 688 96.973 22.191 23.601 1.00 42.37 C 925 | ATOM 925 CG LEU A 688 95.927 21.464 22.753 1.00 42.37 C 926 | ATOM 926 CD1 LEU A 688 96.386 20.043 22.499 1.00 42.37 C 927 | ATOM 927 CD2 LEU A 688 94.589 21.459 23.454 1.00 42.37 C 928 | ATOM 928 N LYS A 689 97.671 24.124 26.030 1.00 43.85 N 929 | ATOM 929 CA LYS A 689 98.705 24.630 26.923 1.00 43.85 C 930 | ATOM 930 C LYS A 689 98.942 23.695 28.110 1.00 43.85 C 931 | ATOM 931 O LYS A 689 98.055 22.863 28.400 1.00 43.85 O 932 | ATOM 932 CB LYS A 689 98.349 26.053 27.390 1.00 56.36 C 933 | ATOM 933 CG LYS A 689 97.969 26.233 28.853 1.00 56.36 C 934 | ATOM 934 CD LYS A 689 96.593 25.715 29.147 1.00 56.36 C 935 | ATOM 935 CE LYS A 689 96.089 26.279 30.457 1.00 56.36 C 936 | ATOM 936 NZ LYS A 689 95.918 27.752 30.397 1.00 56.36 N 937 | ATOM 937 OXT LYS A 689 100.022 23.800 28.737 1.00 56.36 O 938 | TER 938 LYS A 689 939 | -------------------------------------------------------------------------------- /tfbio_data.py: -------------------------------------------------------------------------------- 1 | """ 2 | Original source of this file: 3 | from https://gitlab.com/cheminfIBB/tfbio 4 | """ 5 | 6 | import pickle 7 | 8 | import numpy as np 9 | 10 | import pybel 11 | from math import ceil, sin, cos, sqrt, pi 12 | from itertools import combinations 13 | import collections 14 | 15 | 16 | class Featurizer(): 17 | """Calcaulates atomic features for molecules. Features can encode atom type, 18 | native pybel properties or any property defined with SMARTS patterns 19 | 20 | Attributes 21 | ---------- 22 | FEATURE_NAMES: list of strings 23 | Labels for features (in the same order as features) 24 | NUM_ATOM_CLASSES: int 25 | Number of atom codes 26 | ATOM_CODES: dict 27 | Dictionary mapping atomic numbers to codes 28 | NAMED_PROPS: list of string 29 | Names of atomic properties to retrieve from pybel.Atom object 30 | CALLABLES: list of callables 31 | Callables used to calculcate custom atomic properties 32 | SMARTS: list of SMARTS strings 33 | SMARTS patterns defining additional atomic properties 34 | """ 35 | 36 | def __init__(self, atom_codes=None, atom_labels=None, 37 | named_properties=None, save_molecule_codes=True, 38 | custom_properties=None, smarts_properties=None, 39 | smarts_labels=None): 40 | 41 | """Creates Featurizer with specified types of features. Elements of a 42 | feature vector will be in a following order: atom type encoding 43 | (defined by atom_codes), Pybel atomic properties (defined by 44 | named_properties), molecule code (if present), custom atomic properties 45 | (defined `custom_properties`), and additional properties defined with 46 | SMARTS (defined with `smarts_properties`). 47 | 48 | Parameters 49 | ---------- 50 | atom_codes: dict, optional 51 | Dictionary mapping atomic numbers to codes. It will be used for 52 | one-hot encoging therefore if n different types are used, codes 53 | shpuld be from 0 to n-1. Multiple atoms can have the same code, 54 | e.g. you can use {6: 0, 7: 1, 8: 1} to encode carbons with [1, 0] 55 | and nitrogens and oxygens with [0, 1] vectors. If not provided, 56 | default encoding is used. 57 | atom_labels: list of strings, optional 58 | Labels for atoms codes. It should have the same length as the 59 | number of used codes, e.g. for `atom_codes={6: 0, 7: 1, 8: 1}` you 60 | should provide something like ['C', 'O or N']. If not specified 61 | labels 'atom0', 'atom1' etc are used. If `atom_codes` is not 62 | specified this argument is ignored. 63 | named_properties: list of strings, optional 64 | Names of atomic properties to retrieve from pybel.Atom object. If 65 | not specified ['hyb', 'heavyvalence', 'heterovalence', 66 | 'partialcharge'] is used. 67 | save_molecule_codes: bool, optional (default True) 68 | If set to True, there will be an additional feature to save 69 | molecule code. It is usefeul when saving molecular complex in a 70 | single array. 71 | custom_properties: list of callables, optional 72 | Custom functions to calculate atomic properties. Each element of 73 | this list should be a callable that takes pybel.Atom object and 74 | returns a float. If callable has `__name__` property it is used as 75 | feature label. Otherwise labels 'func' etc are used, where i is 76 | the index in `custom_properties` list. 77 | smarts_properties: list of strings, optional 78 | Additional atomic properties defined with SMARTS patterns. These 79 | patterns should match a single atom. If not specified, deafult 80 | patterns are used. 81 | smarts_labels: list of strings, optional 82 | Labels for properties defined with SMARTS. Should have the same 83 | length as `smarts_properties`. If not specified labels 'smarts0', 84 | 'smarts1' etc are used. If `smarts_properties` is not specified 85 | this argument is ignored. 86 | """ 87 | 88 | # Remember namse of all features in the correct order 89 | self.FEATURE_NAMES = [] 90 | 91 | if atom_codes is not None: 92 | if not isinstance(atom_codes, dict): 93 | raise TypeError('Atom codes should be dict, got %s instead' 94 | % type(atom_codes)) 95 | codes = set(atom_codes.values()) 96 | for i in range(len(codes)): 97 | if i not in codes: 98 | raise ValueError('Incorrect atom code %s' % i) 99 | 100 | self.NUM_ATOM_CLASSES = len(codes) 101 | self.ATOM_CODES = atom_codes 102 | if atom_labels is not None: 103 | if len(atom_labels) != self.NUM_ATOM_CLASSES: 104 | raise ValueError('Incorrect number of atom labels: ' 105 | '%s instead of %s' 106 | % (len(atom_labels), self.NUM_ATOM_CLASSES)) 107 | else: 108 | atom_labels = ['atom%s' % i for i in range(self.NUM_ATOM_CLASSES)] 109 | self.FEATURE_NAMES += atom_labels 110 | else: 111 | self.ATOM_CODES = {} 112 | 113 | metals = ([3, 4, 11, 12, 13] + list(range(19, 32)) 114 | + list(range(37, 51)) + list(range(55, 84)) 115 | + list(range(87, 104))) 116 | 117 | # List of tuples (atomic_num, class_name) with atom types to encode. 118 | atom_classes = [ 119 | (5, 'B'), 120 | (6, 'C'), 121 | (7, 'N'), 122 | (8, 'O'), 123 | (15, 'P'), 124 | (16, 'S'), 125 | (34, 'Se'), 126 | ([9, 17, 35, 53], 'halogen'), 127 | (metals, 'metal') 128 | ] 129 | 130 | for code, (atom, name) in enumerate(atom_classes): 131 | if type(atom) is list: 132 | for a in atom: 133 | self.ATOM_CODES[a] = code 134 | else: 135 | self.ATOM_CODES[atom] = code 136 | self.FEATURE_NAMES.append(name) 137 | 138 | self.NUM_ATOM_CLASSES = len(atom_classes) 139 | 140 | if named_properties is not None: 141 | if not isinstance(named_properties, (list, tuple, np.ndarray)): 142 | raise TypeError('named_properties must be a list') 143 | allowed_props = [prop for prop in dir(pybel.Atom) 144 | if not prop.startswith('__')] 145 | for prop_id, prop in enumerate(named_properties): 146 | if prop not in allowed_props: 147 | raise ValueError( 148 | 'named_properties must be in pybel.Atom attributes,' 149 | ' %s was given at position %s' % (prop_id, prop) 150 | ) 151 | self.NAMED_PROPS = named_properties 152 | else: 153 | # pybel.Atom properties to save 154 | self.NAMED_PROPS = ['hyb', 'heavyvalence', 'heterovalence', 155 | 'partialcharge'] 156 | self.FEATURE_NAMES += self.NAMED_PROPS 157 | 158 | if not isinstance(save_molecule_codes, bool): 159 | raise TypeError('save_molecule_codes should be bool, got %s ' 160 | 'instead' % type(save_molecule_codes)) 161 | self.save_molecule_codes = save_molecule_codes 162 | if save_molecule_codes: 163 | # Remember if an atom belongs to the ligand or to the protein 164 | self.FEATURE_NAMES.append('molcode') 165 | 166 | self.CALLABLES = [] 167 | if custom_properties is not None: 168 | for i, func in enumerate(custom_properties): 169 | if not isinstance(func, collections.Callable): 170 | raise TypeError('custom_properties should be list of' 171 | ' callables, got %s instead' % type(func)) 172 | name = getattr(func, '__name__', '') 173 | if name == '': 174 | name = 'func%s' % i 175 | self.CALLABLES.append(func) 176 | self.FEATURE_NAMES.append(name) 177 | 178 | if smarts_properties is None: 179 | # SMARTS definition for other properties 180 | self.SMARTS = [ 181 | '[#6+0!$(*~[#7,#8,F]),SH0+0v2,s+0,S^3,Cl+0,Br+0,I+0]', 182 | '[a]', 183 | '[!$([#1,#6,F,Cl,Br,I,o,s,nX3,#7v5,#15v5,#16v4,#16v6,*+1,*+2,*+3])]', 184 | '[!$([#6,H0,-,-2,-3]),$([!H0;#7,#8,#9])]', 185 | '[r]' 186 | ] 187 | smarts_labels = ['hydrophobic', 'aromatic', 'acceptor', 'donor', 188 | 'ring'] 189 | elif not isinstance(smarts_properties, (list, tuple, np.ndarray)): 190 | raise TypeError('smarts_properties must be a list') 191 | else: 192 | self.SMARTS = smarts_properties 193 | 194 | if smarts_labels is not None: 195 | if len(smarts_labels) != len(self.SMARTS): 196 | raise ValueError('Incorrect number of SMARTS labels: %s' 197 | ' instead of %s' 198 | % (len(smarts_labels), len(self.SMARTS))) 199 | else: 200 | smarts_labels = ['smarts%s' % i for i in range(len(self.SMARTS))] 201 | 202 | # Compile patterns 203 | self.compile_smarts() 204 | self.FEATURE_NAMES += smarts_labels 205 | 206 | def compile_smarts(self): 207 | self.__PATTERNS = [] 208 | for smarts in self.SMARTS: 209 | self.__PATTERNS.append(pybel.Smarts(smarts)) 210 | 211 | def encode_num(self, atomic_num): 212 | """Encode atom type with a binary vector. If atom type is not included in 213 | the `atom_classes`, its encoding is an all-zeros vector. 214 | 215 | Parameters 216 | ---------- 217 | atomic_num: int 218 | Atomic number 219 | 220 | Returns 221 | ------- 222 | encoding: np.ndarray 223 | Binary vector encoding atom type (one-hot or null). 224 | """ 225 | 226 | if not isinstance(atomic_num, int): 227 | raise TypeError('Atomic number must be int, %s was given' 228 | % type(atomic_num)) 229 | 230 | encoding = np.zeros(self.NUM_ATOM_CLASSES) 231 | try: 232 | encoding[self.ATOM_CODES[atomic_num]] = 1.0 233 | except: 234 | pass 235 | return encoding 236 | 237 | def find_smarts(self, molecule): 238 | """Find atoms that match SMARTS patterns. 239 | 240 | Parameters 241 | ---------- 242 | molecule: pybel.Molecule 243 | 244 | Returns 245 | ------- 246 | features: np.ndarray 247 | NxM binary array, where N is the number of atoms in the `molecule` 248 | and M is the number of patterns. `features[i, j]` == 1.0 if i'th 249 | atom has j'th property 250 | """ 251 | 252 | if not isinstance(molecule, pybel.Molecule): 253 | raise TypeError('molecule must be pybel.Molecule object, %s was given' 254 | % type(molecule)) 255 | # print 'Here' 256 | #print len(self.__PATTERNS) 257 | features = np.zeros((len(molecule.atoms), len(self.__PATTERNS))) 258 | #print 'Here' 259 | for (pattern_id, pattern) in enumerate(self.__PATTERNS): 260 | atoms_with_prop = np.array(list(*list(zip(*pattern.findall(molecule)))), 261 | dtype=int) - 1 262 | features[atoms_with_prop, pattern_id] = 1.0 263 | return features 264 | 265 | def get_features(self, molecule, molcode=None): 266 | """Get coordinates and features for all heavy atoms in the molecule. 267 | 268 | Parameters 269 | ---------- 270 | molecule: pybel.Molecule 271 | molcode: float, optional 272 | Molecule type. You can use it to encode whether an atom belongs to 273 | the ligand (1.0) or to the protein (-1.0) etc. 274 | 275 | Returns 276 | ------- 277 | coords: np.ndarray, shape = (N, 3) 278 | Coordinates of all heavy atoms in the `molecule`. 279 | features: np.ndarray, shape = (N, F) 280 | Features of all heavy atoms in the `molecule`: atom type 281 | (one-hot encoding), pybel.Atom attributes, type of a molecule 282 | (e.g protein/ligand distinction), and other properties defined with 283 | SMARTS patterns 284 | """ 285 | 286 | if not isinstance(molecule, pybel.Molecule): 287 | raise TypeError('molecule must be pybel.Molecule object,' 288 | ' %s was given' % type(molecule)) 289 | if molcode is None: 290 | if self.save_molecule_codes is True: 291 | raise ValueError('save_molecule_codes is set to True,' 292 | ' you must specify code for the molecule') 293 | elif not isinstance(molcode, (float, int)): 294 | raise TypeError('motlype must be float, %s was given' 295 | % type(molcode)) 296 | 297 | coords = [] 298 | features = [] 299 | heavy_atoms = [] 300 | #print 'nAtoms=',len(molecule.atoms) 301 | for i, atom in enumerate(molecule): 302 | # ignore hydrogens and dummy atoms (they have atomicnum set to 0) 303 | if atom.atomicnum > 1: 304 | heavy_atoms.append(i) 305 | coords.append(atom.coords) 306 | 307 | features.append(np.concatenate(( 308 | self.encode_num(atom.atomicnum), 309 | [atom.__getattribute__(prop) for prop in self.NAMED_PROPS], 310 | [func(atom) for func in self.CALLABLES], 311 | ))) 312 | #print 'nAtoms=',len(molecule.atoms) 313 | coords = np.array(coords, dtype=np.float32) 314 | features = np.array(features, dtype=np.float32) 315 | 316 | if self.save_molecule_codes: 317 | features = np.hstack((features, molcode * np.ones((len(features), 1)))) 318 | 319 | features = np.hstack([features, self.find_smarts(molecule)[heavy_atoms]]) 320 | 321 | if np.isnan(features).any(): 322 | raise RuntimeError('Got NaN when calculating features') 323 | 324 | return coords, features 325 | 326 | def to_pickle(self, fname='featurizer.pkl'): 327 | """Save featurizer in a given file. Featurizer can be restored with 328 | `from_pickle` method. 329 | 330 | Parameters 331 | ---------- 332 | fname: str, optional 333 | Path to file in which featurizer will be saved 334 | """ 335 | 336 | # patterns can't be pickled, we need to temporarily remove them 337 | patterns = self.__PATTERNS[:] 338 | del self.__PATTERNS 339 | try: 340 | with open(fname, 'wb') as f: 341 | pickle.dump(self, f) 342 | finally: 343 | self.__PATTERNS = patterns[:] 344 | 345 | @staticmethod 346 | def from_pickle(fname): 347 | """Load pickled featurizer from a given file 348 | 349 | Parameters 350 | ---------- 351 | fname: str, optional 352 | Path to file with saved featurizer 353 | 354 | Returns 355 | ------- 356 | featurizer: Featurizer object 357 | Loaded featurizer 358 | """ 359 | with open(fname, 'rb') as f: 360 | featurizer = pickle.load(f) 361 | featurizer.compile_smarts() 362 | return featurizer 363 | 364 | 365 | def rotation_matrix(axis, theta): 366 | """Counterclockwise rotation about a given axis by theta radians""" 367 | 368 | if not isinstance(axis, (np.ndarray, list, tuple)): 369 | raise TypeError('axis must be an array of floats of shape (3,)') 370 | try: 371 | axis = np.asarray(axis, dtype=np.float) 372 | except ValueError: 373 | raise ValueError('axis must be an array of floats of shape (3,)') 374 | 375 | if axis.shape != (3,): 376 | raise ValueError('axis must be an array of floats of shape (3,)') 377 | 378 | if not isinstance(theta, (float, int)): 379 | raise TypeError('theta must be a float') 380 | 381 | axis = axis / sqrt(np.dot(axis, axis)) 382 | a = cos(theta / 2.0) 383 | b, c, d = -axis * sin(theta / 2.0) 384 | aa, bb, cc, dd = a * a, b * b, c * c, d * d 385 | bc, ad, ac, ab, bd, cd = b * c, a * d, a * c, a * b, b * d, c * d 386 | return np.array([[aa + bb - cc - dd, 2 * (bc + ad), 2 * (bd - ac)], 387 | [2 * (bc - ad), aa + cc - bb - dd, 2 * (cd + ab)], 388 | [2 * (bd + ac), 2 * (cd - ab), aa + dd - bb - cc]]) 389 | 390 | 391 | # Create matrices for all possible 90* rotations of a box 392 | ROTATIONS = [rotation_matrix([1, 1, 1], 0)] 393 | 394 | # about X, Y and Z - 9 rotations 395 | for a1 in range(3): 396 | for t in range(1, 4): 397 | axis = np.zeros(3) 398 | axis[a1] = 1 399 | theta = t * pi / 2.0 400 | ROTATIONS.append(rotation_matrix(axis, theta)) 401 | 402 | # about each face diagonal - 6 rotations 403 | for (a1, a2) in combinations(list(range(3)), 2): 404 | axis = np.zeros(3) 405 | axis[[a1, a2]] = 1.0 406 | theta = pi 407 | ROTATIONS.append(rotation_matrix(axis, theta)) 408 | axis[a2] = -1.0 409 | ROTATIONS.append(rotation_matrix(axis, theta)) 410 | 411 | # about each space diagonal - 8 rotations 412 | for t in [1, 2]: 413 | theta = t * 2 * pi / 3 414 | axis = np.ones(3) 415 | ROTATIONS.append(rotation_matrix(axis, theta)) 416 | for a1 in range(3): 417 | axis = np.ones(3) 418 | axis[a1] = -1 419 | ROTATIONS.append(rotation_matrix(axis, theta)) 420 | 421 | 422 | def rotate(coords, rotation): 423 | """Rotate coordinates by a given rotation 424 | 425 | Parameters 426 | ---------- 427 | coords: array-like, shape (N, 3) 428 | Arrays with coordinates and features for each atoms. 429 | rotation: int or array-like, shape (3, 3) 430 | Rotation to perform. You can either select predefined rotation by 431 | giving its index or specify rotation matrix. 432 | 433 | Returns 434 | ------- 435 | coords: np.ndarray, shape = (N, 3) 436 | Rotated coordinates. 437 | """ 438 | 439 | global ROTATIONS 440 | 441 | if not isinstance(coords, (np.ndarray, list, tuple)): 442 | raise TypeError('coords must be an array of floats of shape (N, 3)') 443 | try: 444 | coords = np.asarray(coords, dtype=np.float) 445 | except ValueError: 446 | raise ValueError('coords must be an array of floats of shape (N, 3)') 447 | shape = coords.shape 448 | if len(shape) != 2 or shape[1] != 3: 449 | raise ValueError('coords must be an array of floats of shape (N, 3)') 450 | 451 | if isinstance(rotation, int): 452 | if rotation >= 0 and rotation < len(ROTATIONS): 453 | return np.dot(coords, ROTATIONS[rotation]) 454 | else: 455 | raise ValueError('Invalid rotation number %s!' % rotation) 456 | elif isinstance(rotation, np.ndarray) and rotation.shape == (3, 3): 457 | return np.dot(coords, rotation) 458 | 459 | else: 460 | raise ValueError('Invalid rotation %s!' % rotation) 461 | 462 | 463 | # TODO: add make_grid variant for GPU 464 | 465 | def make_grid(coords, features, grid_resolution=1.0, max_dist=10.0): 466 | """Convert atom coordinates and features represented as 2D arrays into a 467 | fixed-sized 3D box. 468 | 469 | Parameters 470 | ---------- 471 | coords, features: array-likes, shape (N, 3) and (N, F) 472 | Arrays with coordinates and features for each atoms. 473 | grid_resolution: float, optional 474 | Resolution of a grid (in Angstroms). 475 | max_dist: float, optional 476 | Maximum distance between atom and box center. Resulting box has size of 477 | 2*`max_dist`+1 Angstroms and atoms that are too far away are not 478 | included. 479 | 480 | Returns 481 | ------- 482 | coords: np.ndarray, shape = (M, M, M, F) 483 | 4D array with atom properties distributed in 3D space. M is equal to 484 | 2 * `max_dist` / `grid_resolution` + 1 485 | """ 486 | 487 | try: 488 | coords = np.asarray(coords, dtype=np.float) 489 | except ValueError: 490 | raise ValueError('coords must be an array of floats of shape (N, 3)') 491 | c_shape = coords.shape 492 | if len(c_shape) != 2 or c_shape[1] != 3: 493 | raise ValueError('coords must be an array of floats of shape (N, 3)') 494 | # print 'coods shape', c_shape 495 | N = len(coords) 496 | try: 497 | features = np.asarray(features, dtype=np.float) 498 | except ValueError: 499 | raise ValueError('features must be an array of floats of shape (N, F)') 500 | f_shape = features.shape 501 | if len(f_shape) != 2 or f_shape[0] != N: 502 | raise ValueError('features must be an array of floats of shape (N, F)') 503 | #print 'features shape', f_shape 504 | if not isinstance(grid_resolution, (float, int)): 505 | raise TypeError('grid_resolution must be float') 506 | if grid_resolution <= 0: 507 | raise ValueError('grid_resolution must be positive') 508 | 509 | if not isinstance(max_dist, (float, int)): 510 | raise TypeError('max_dist must be float') 511 | if max_dist <= 0: 512 | raise ValueError('max_dist must be positive') 513 | 514 | num_features = f_shape[1] 515 | max_dist = float(max_dist) 516 | grid_resolution = float(grid_resolution) 517 | #print 'max_dist =', max_dist 518 | #print 'grid_resolution =', grid_resolution 519 | box_size = int(ceil(2 * max_dist / grid_resolution + 1)) 520 | # print 'box_size =', box_size 521 | # move all atoms to the nearest grid point 522 | grid_coords = (coords + max_dist) / grid_resolution 523 | grid_coords = grid_coords.round().astype(int) 524 | 525 | # remove atoms outside the box 526 | in_box = ((grid_coords >= 0) & (grid_coords < box_size)).all(axis=1) 527 | grid = np.zeros((1, box_size, box_size, box_size, num_features),dtype=np.float32) 528 | for (x, y, z), f in zip(grid_coords[in_box], features[in_box]): 529 | grid[0, x, y, z] += f 530 | 531 | return grid 532 | -------------------------------------------------------------------------------- /utils.py: -------------------------------------------------------------------------------- 1 | """ 2 | Created on Tue Jul 30 13:39:49 2019 3 | 4 | @author: smylonas 5 | """ 6 | 7 | import warnings 8 | import numpy as np 9 | from scipy.spatial.distance import euclidean 10 | from sklearn.cluster import KMeans 11 | 12 | 13 | def mol2_reader(mol_file): # does not handle H2 14 | if mol_file[-4:] != 'mol2': 15 | raise Exception("File's extension is not .mol2") 16 | 17 | with open(mol_file,'r') as f: 18 | lines = f.readlines() 19 | 20 | for i,line in enumerate(lines): 21 | if '@ATOM' in line: 22 | first_atom_idx = i+1 23 | if '@BOND' in line: 24 | last_atom_idx = i-1 25 | 26 | return lines[first_atom_idx:last_atom_idx+1] 27 | 28 | 29 | def readSurfPoints(surf_file): 30 | with open(surf_file,'r') as f: 31 | lines = f.readlines() 32 | 33 | lines = [l for l in lines if len(l.split())>7] 34 | if len(lines)>100000: 35 | warnings.warn('{} has too many points'.format(surf_file)) 36 | return 37 | if len(lines)==0: 38 | warnings.warn('{} is empty'.format(surf_file)) 39 | return 40 | 41 | coords = np.zeros((len(lines),3)) 42 | normals = np.zeros((len(lines),3)) 43 | for i,l in enumerate(lines): 44 | parts = l.split() 45 | try: 46 | coords[i,0] = float(parts[3]) 47 | coords[i,1] = float(parts[4]) 48 | coords[i,2] = float(parts[5]) 49 | normals[i,0] = float(parts[8]) 50 | normals[i,1] = float(parts[9]) 51 | normals[i,2] = float(parts[10]) 52 | except: 53 | coords[i,0] = float(parts[2][-8:]) 54 | coords[i,1] = float(parts[3]) 55 | coords[i,2] = float(parts[4]) 56 | normals[i,0] = float(parts[7]) 57 | normals[i,1] = float(parts[8]) 58 | normals[i,2] = float(parts[9]) 59 | 60 | return coords, normals 61 | 62 | 63 | def simplify_dms(init_surf_file, factor, seed=None): 64 | 65 | coords, normals = readSurfPoints(init_surf_file) 66 | 67 | if factor == 1: 68 | return coords, normals 69 | 70 | nPoints = len(coords) 71 | nCl = nPoints//factor 72 | 73 | kmeans = KMeans(n_clusters=nCl, max_iter=300, n_init=1, random_state=seed).fit(coords) 74 | point_labels = kmeans.labels_ 75 | centers = kmeans.cluster_centers_ 76 | cluster_idx,freq = np.unique(point_labels,return_counts=True) 77 | if len(cluster_idx)!=nCl: 78 | raise Exception('Number of created clusters should be equal to nCl') 79 | 80 | idxs = [] 81 | for cl in cluster_idx: 82 | cluster_points_idxs = np.where(point_labels==cl)[0] 83 | closest_idx_to_center = np.argmin([euclidean(centers[cl],coords[idx]) for idx in cluster_points_idxs]) 84 | idxs.append(cluster_points_idxs[closest_idx_to_center]) 85 | 86 | return coords[idxs], normals[idxs] 87 | 88 | 89 | def rotation(n): 90 | if n[0]==0.0 and n[1]==0.0: 91 | if n[2]==1.0: 92 | return np.identity(3) 93 | elif n[2]==-1.0: 94 | Q = np.identity(3) 95 | Q[0,0] = -1 96 | return Q 97 | else: 98 | print('not possible') 99 | 100 | rx = -n[1]/np.sqrt(n[0]*n[0]+n[1]*n[1]) 101 | ry = n[0]/np.sqrt(n[0]*n[0]+n[1]*n[1]) 102 | rz = 0 103 | th = np.arccos(n[2]) 104 | 105 | q0 = np.cos(th/2) 106 | q1 = np.sin(th/2)*rx 107 | q2 = np.sin(th/2)*ry 108 | q3 = np.sin(th/2)*rz 109 | 110 | Q = np.zeros((3,3)) 111 | Q[0,0] = q0*q0+q1*q1-q2*q2-q3*q3 112 | Q[0,1] = 2*(q1*q2-q0*q3) 113 | Q[0,2] = 2*(q1*q3+q0*q2) 114 | Q[1,0] = 2*(q1*q2+q0*q3) 115 | Q[1,1] = q0*q0-q1*q1+q2*q2-q3*q3 116 | Q[1,2] = 2*(q3*q2-q0*q1) 117 | Q[2,0] = 2*(q1*q3-q0*q2) 118 | Q[2,1] = 2*(q3*q2+q0*q1) 119 | Q[2,2] = q0*q0-q1*q1-q2*q2+q3*q3 120 | 121 | return Q 122 | 123 | --------------------------------------------------------------------------------