Compare commits

...

187 Commits

Author SHA1 Message Date
Maarten L. Hekkelman
18088457d3 last updates in develop 2021-09-29 14:21:41 +02:00
Maarten L. Hekkelman
056697d901 imported libname for stdc++fs 2021-09-29 13:24:16 +02:00
Maarten L. Hekkelman
2681cfad50 Merge branch 'develop' of github.com:PDB-REDO/libcifpp into develop 2021-09-29 13:21:45 +02:00
Maarten L. Hekkelman
8aaa7925a3 fix lib name 2021-09-29 13:21:37 +02:00
Maarten L. Hekkelman
d4f73e471b No need to search zlib/bzip2 in Windows 2021-09-29 11:08:05 +02:00
Maarten L. Hekkelman
750be0c4a4 for 18.04 2021-09-28 15:26:15 +02:00
Maarten L. Hekkelman
0f4a2a26fc dependencies
check compiler version
2021-09-28 14:15:17 +02:00
Maarten L. Hekkelman
6adb56341d remove boost::date_time dependency 2021-09-28 12:48:15 +02:00
Maarten L. Hekkelman
4524357cd3 zlib, again (use the zlib from boost in Windows) 2021-09-28 11:20:02 +02:00
Maarten L. Hekkelman
0b05b6f6e3 run tests in build dir 2021-09-28 10:40:40 +02:00
Maarten L. Hekkelman
6382170157 zlib 2021-09-28 09:39:15 +02:00
Maarten L. Hekkelman
c2eeb69dcc optional static libs boost 2021-09-28 09:38:35 +02:00
Maarten L. Hekkelman
f32261fc59 revert zlib in boost 2021-09-28 09:37:42 +02:00
Maarten L. Hekkelman
90c967c8c6 Merge branch 'develop' of github.com:PDB-REDO/libcifpp into develop 2021-09-28 09:30:56 +02:00
Maarten L. Hekkelman
4ac90128db zlib in boost 2021-09-28 09:30:43 +02:00
Maarten L. Hekkelman
3d71db1bb7 less stringent test for compiler version 2021-09-28 09:30:22 +02:00
Maarten L. Hekkelman
5e35ea5168 warnings and compiler detection 2021-09-28 09:17:28 +02:00
Maarten L. Hekkelman
2fc88d52eb Updating cmake file to install correct update mechanism 2021-09-28 08:50:28 +02:00
Maarten L. Hekkelman
567b0f3b57 Merge branch 'develop' of github.com:PDB-REDO/libcifpp into develop 2021-09-28 07:57:05 +02:00
Maarten L. Hekkelman
8f29386998 fix file read test 2021-09-26 14:52:34 +02:00
Maarten L. Hekkelman
d2427d57d9 unit test for reading files 2021-09-27 11:36:24 +02:00
Maarten L. Hekkelman
14a9499962 fix cmake files, pkg-config file 2021-09-27 09:36:33 +02:00
Maarten L. Hekkelman
0fafb80d44 Remove bzip2 support 2021-09-27 08:40:05 +02:00
Maarten L. Hekkelman
b5454f0943 Merge branch 'develop' of github.com:PDB-REDO/libcifpp into develop 2021-09-26 13:41:21 +02:00
Maarten L. Hekkelman
b698260d73 Merge branch 'trunk' of github.com:PDB-REDO/libcifpp into develop 2021-09-26 13:40:39 +02:00
Maarten L. Hekkelman
ccdd1b74a0 required 2021-09-26 13:39:49 +02:00
Maarten L. Hekkelman
298fe20a1b improve cmake files? 2021-09-25 12:05:42 +02:00
Maarten L. Hekkelman
12a7c45452 Merge branch 'develop' of github.com:PDB-REDO/libcifpp into develop 2021-09-24 16:02:22 +02:00
Maarten L. Hekkelman
02a28c2fd6 clean up makefile 2021-09-24 16:01:48 +02:00
Maarten L. Hekkelman
68e182b0bd Merge branch 'develop' of github.com:PDB-REDO/libcifpp into develop 2021-09-24 15:31:31 +02:00
Maarten L. Hekkelman
b0ec88f469 link compression libs 2021-09-24 15:30:34 +02:00
Maarten L. Hekkelman
4feee6ac22 Merge branch 'develop' of github.com:PDB-REDO/libcifpp into develop 2021-09-24 15:27:48 +02:00
Maarten L. Hekkelman
ee8a85ec2f static boost libs 2021-09-24 15:27:13 +02:00
Maarten L. Hekkelman
0245d4a881 Merge branch 'develop' of github.com:PDB-REDO/libcifpp into develop 2021-09-24 15:24:42 +02:00
Maarten L. Hekkelman
e8f0058956 add link of stdc++fs 2021-09-24 15:24:30 +02:00
Maarten L. Hekkelman
9c75dbaae0 Merge branch 'develop' of github.com:PDB-REDO/libcifpp into develop 2021-09-24 15:22:15 +02:00
Maarten L. Hekkelman
5bd39b598e Add filesystem check, with libstdc++fs test 2021-09-24 15:21:12 +02:00
Maarten L. Hekkelman
25a43abffd update version number, fix revision file 2021-09-24 14:06:47 +02:00
Maarten L. Hekkelman
9a7ca022e2 check for existence of run-parts to be more compatible 2021-09-21 08:56:22 +02:00
Maarten L. Hekkelman
46fe0d7caf fixed cmake file
reduced verbosity for missing atoms
update script, more cross platform
2021-09-21 08:52:48 +02:00
Maarten L. Hekkelman
0371cec415 Merge branch 'develop' of github.com:PDB-REDO/libcifpp into develop 2021-09-21 08:40:25 +02:00
Maarten L. Hekkelman
2b1020cbb9 Merge branch 'trunk' into develop 2021-09-21 08:16:57 +02:00
Andrius Merkys
8c3ce2a87d Update OpenStructure compounds.chemlib if OpenStructure is found (#8)
* Update OpenStructure compounds.chemlib if OpenStructure is found.

* Replacing the code to update OpenStructure compounds.chemlib with a call to its internal script.

* Implementing more flexible approach allowing notifying all dependent software.
2021-09-20 12:39:15 +02:00
Maarten L. Hekkelman
d633622e27 Creating new nonpoly compounds 2021-09-20 11:34:07 +02:00
Maarten L. Hekkelman
19b652f615 Merge commit '37f7dd0' into develop 2021-09-15 16:06:43 +02:00
Maarten L. Hekkelman
37f7dd0631 load compound if needed 2021-09-15 16:04:49 +02:00
Maarten L. Hekkelman
4c99710fb3 Refactored iterators (Category, Row)
const versions of find
2021-09-15 11:38:12 +02:00
Maarten L. Hekkelman
59865cdb44 Rotate and Translate of structure data
update unit-test for create_nonpoly
2021-09-14 16:09:08 +02:00
Maarten L. Hekkelman
c3434507da new find1 2021-09-14 11:25:59 +02:00
Maarten L. Hekkelman
79ecf20b85 Sometimes extracting archives does not work in cmake 2021-09-10 09:24:06 +02:00
Maarten L. Hekkelman
1de9681bb7 revert mrc test
extended nonpoly unit-test
2021-09-10 09:22:37 +02:00
Maarten L. Hekkelman
345c4778e6 start structure-test unit test
added compare functions for Datablock and Category
2021-09-08 16:58:50 +02:00
Maarten L. Hekkelman
0ccb2f88ca Added more 3d code (alignpoints) 2021-09-08 11:44:27 +02:00
Maarten L. Hekkelman
f7bef8b0e9 update dictionary
do not throw from Category::isValid()
2021-09-07 14:50:06 +02:00
Maarten L. Hekkelman
9da8608f8f Merge branch 'cmake' into trunk
install update script (optionally, unix only)
2021-09-07 10:12:46 +02:00
Maarten L. Hekkelman
496cb0b909 last minute changes for building inside CCP4 2021-09-07 10:10:38 +02:00
Maarten L. Hekkelman
583cafa91e Merge branch 'cmake' of github.com:PDB-REDO/libcifpp into cmake 2021-09-07 09:23:02 +02:00
Maarten L. Hekkelman
01da665243 test nieuwe CCP4 regels 2021-09-07 09:15:47 +02:00
Maarten L. Hekkelman
e900cd1e3d Windows 2021-09-06 14:58:47 +02:00
Maarten L. Hekkelman
a8a838b33e extract using gzip for cmake < 3.19 (?) 2021-09-02 08:43:12 +02:00
Maarten L. Hekkelman
072be25335 install update script 2021-09-01 16:53:05 +02:00
Maarten L. Hekkelman
5f50429cdb last minute changes to cmake files 2021-08-31 15:53:29 +02:00
Maarten L. Hekkelman
db3fb04172 Merged cmake changes
Updated version to 1.1.1
2021-08-31 15:50:36 +02:00
Maarten L. Hekkelman
839385c3fb update readme 2021-08-31 15:45:01 +02:00
Maarten L. Hekkelman
d508b7b2df updated changelog 2021-08-31 15:43:43 +02:00
Maarten L. Hekkelman
b1456b87c0 Updated readme 2021-08-31 14:27:51 +02:00
Maarten L. Hekkelman
58d2dcaef2 fix weak linking in Linux (when resources are not available) 2021-08-31 13:56:04 +02:00
Maarten L. Hekkelman
a9468d1cbb Fix test in cmake file 2021-08-31 12:49:52 +02:00
Maarten L. Hekkelman
a29e3e8da3 create symop table 2021-08-30 12:06:36 +02:00
Maarten L. Hekkelman
dd5df1bb2a debug code: print atom id 2021-08-25 13:08:15 +02:00
Maarten L. Hekkelman
d5d6f3a7b3 Merge branch 'newer-cmake-files' of github.com:PDB-REDO/libcifpp into newer-cmake-files 2021-08-24 12:50:26 +02:00
Maarten L. Hekkelman
9d2f2b3026 pkgconfig support 2021-08-24 12:50:20 +02:00
Maarten L. Hekkelman
74717a3047 Do not bail out in bondmap creation if compound is unknown 2021-08-24 10:52:18 +02:00
Maarten L. Hekkelman
c13ee92f1e on windows 2021-08-23 17:20:45 +02:00
Maarten L. Hekkelman
0ca04bed4f Updated cmake file, configurable data dir 2021-08-23 17:00:49 +02:00
Maarten L. Hekkelman
89850de660 export symbols in windows 2021-08-18 21:21:14 +02:00
Maarten L. Hekkelman
8bb4ebd897 update cmake rules 2021-08-18 16:31:44 +02:00
Maarten L. Hekkelman
6a67208d24 date in revision file 2021-08-18 15:19:41 +02:00
Maarten L. Hekkelman
139f32c3e8 correct dependency for tests 2021-08-18 14:29:40 +02:00
Maarten L. Hekkelman
81c0d01944 Cleaning up all warnings in MSVC 2021-08-18 14:12:56 +02:00
Maarten L. Hekkelman
1d2f997efb export stuff 2021-08-18 09:53:46 +02:00
Maarten L. Hekkelman
f126b1dac3 include boost libs 2021-08-17 14:35:51 +02:00
Maarten L. Hekkelman
bbc38262ce setting up tests in cmake 2021-08-17 14:11:19 +02:00
Maarten L. Hekkelman
caeafd3189 clean up 2021-08-17 13:43:01 +02:00
Maarten L. Hekkelman
98e3c47cdf remove configure 2021-08-17 13:38:32 +02:00
Maarten L. Hekkelman
390b230cac generate version string with cmake 2021-08-17 13:30:38 +02:00
Maarten L. Hekkelman
c5c3950c91 revision, first attempt 2021-08-17 11:33:22 +02:00
Maarten L. Hekkelman
2aea0b3b1f resources in Windows 2021-08-13 11:38:48 +02:00
Maarten L. Hekkelman
6b16e02b34 clean up warning on Windows, start using resources on Windows 2021-08-12 12:01:48 +02:00
Maarten L. Hekkelman
bb2f81318a Newer CMakeLists.txt file, now creating more correct config files. 2021-08-10 16:21:02 +02:00
Maarten L. Hekkelman
ec91d0fb22 fix test isWater in Residue when mCompound is null 2021-08-10 11:23:56 +02:00
Maarten L. Hekkelman
760e23693e remove suprious error messages,
fix getUniqueID to use correct key field
2021-08-09 15:11:18 +02:00
Maarten L. Hekkelman
cfba00ae46 Merge branch 'trunk' of github.com:PDB-REDO/libcifpp into trunk 2021-08-09 10:01:20 +02:00
Maarten L. Hekkelman
dc1cfb60ff Fix reading AlphaFold files (missing auth_seq_id error) 2021-08-09 10:00:50 +02:00
Maarten L. Hekkelman
92148304ee Safer CompoundFactoryImpl 2021-07-12 11:25:39 +02:00
Maarten L. Hekkelman
9329c0c0f6 optimisation of creating compound 2021-07-12 10:51:52 +02:00
Maarten L. Hekkelman
de3ac001fc added import statement for Windows DLL 2021-07-07 13:06:43 +02:00
Maarten L. Hekkelman
b1047154a4 missing include, export symbols on Windows 2021-06-29 10:39:47 +02:00
Maarten L. Hekkelman
c361af3792 z and bz2 finding, component.cif download 2021-05-26 14:59:59 +02:00
Maarten L. Hekkelman
73487fc24b updated for windows 2021-05-25 15:51:37 +02:00
Maarten L. Hekkelman
73513fd700 cmake file, now working on windows 2021-05-25 15:25:39 +02:00
Maarten L. Hekkelman
6b7723eb2a cmake file can now build unit-test 2021-05-25 09:42:21 +02:00
Maarten L. Hekkelman
7056c15366 Merge branch 'trunk' of github.com:PDB-REDO/libcifpp into trunk 2021-05-21 09:25:34 +02:00
Maarten L. Hekkelman
8539e050ae add code to load default components.cif file 2021-05-21 09:25:20 +02:00
Maarten L. Hekkelman
5d4c2641f6 fix cmake file, now creates unit-test 2021-05-19 15:37:07 +02:00
Maarten L. Hekkelman
bc32071576 fix cmake file 2021-05-18 15:36:46 +02:00
Maarten L. Hekkelman
3b2c57314f initial cmake file 2021-05-18 13:54:03 +02:00
Maarten L. Hekkelman
36351a0608 fix for libc++, not using in_avail anymore 2021-05-17 10:38:06 +02:00
Maarten L. Hekkelman
047b454c1d disable download ccd in configure, for travis 2021-04-28 16:49:14 +02:00
Maarten L. Hekkelman
3f5e620102 loading compound info, finished with error checking and verbose mode 2021-04-28 16:18:08 +02:00
Maarten L. Hekkelman
851a43ba4b Alternative layering of compound factory object implementations 2021-04-26 16:52:18 +02:00
Maarten L. Hekkelman
47ae50f704 only load compound when really needed 2021-04-26 13:16:58 +02:00
Maarten L. Hekkelman
33bdd6ae82 Merge branch 'trunk' of github.com:PDB-REDO/libcifpp into trunk 2021-04-21 16:03:07 +02:00
Maarten L. Hekkelman
433021727e count molecules 2021-04-21 16:02:22 +02:00
Maarten L. Hekkelman
7f23c84287 clean-up 2021-04-21 15:36:46 +02:00
Maarten L. Hekkelman
74bd2585e7 renaming, nonpoly_scheme 2021-04-21 14:41:06 +02:00
Maarten L. Hekkelman
ebb27638ff renaming compound code... 2021-04-21 14:20:36 +02:00
Maarten L. Hekkelman
3eb7e4c5bf Potential fix 2021-04-21 11:38:36 +02:00
Maarten L. Hekkelman
112f859b19 ms windows work 2021-04-21 08:32:10 +02:00
Maarten L. Hekkelman
fd08678ff6 backup 2021-04-20 17:18:15 +02:00
Maarten L. Hekkelman
2e2fc11fe1 renaming, first steps 2021-04-20 13:33:56 +02:00
Maarten L. Hekkelman
d44ed57cf9 load correct dictionary 2021-04-20 13:30:08 +02:00
Maarten L. Hekkelman
aa31acb056 no atomic? 2021-04-15 09:26:45 +02:00
Maarten L. Hekkelman
232003cb2e added sample PDB file 2021-04-14 17:31:30 +02:00
Maarten L. Hekkelman
db21dd1659 fix making, testing 2021-04-14 17:15:02 +02:00
Maarten L. Hekkelman
2f3279a5ff stand alone, write complete update scripts and config 2021-04-14 17:03:00 +02:00
Maarten L. Hekkelman
ab21317156 at least some tests should now work 2021-04-14 16:25:08 +02:00
Maarten L. Hekkelman
43cb312225 addFileResource added 2021-04-14 16:02:22 +02:00
Maarten L. Hekkelman
ce28cb7a48 Moved BondMap from libpdb-redo to libcifpp 2021-04-14 14:55:55 +02:00
Maarten L. Hekkelman
1e47fa557c indexed CCD file 2021-04-14 11:32:03 +02:00
Maarten L. Hekkelman
1ae3cf7b99 moving towards using CCD, parsing single datablock 2021-04-14 10:59:58 +02:00
Maarten L. Hekkelman
915d6504a2 First steps, remove CCP4 info from compound 2021-04-13 16:39:03 +02:00
Maarten L. Hekkelman
5e63ca7a82 Check for zlib/bzip2 linking 2021-04-13 14:13:25 +02:00
Maarten L. Hekkelman
e0777e74c2 minor updates 2021-04-08 09:26:10 +02:00
Maarten L. Hekkelman
cf465134fd fixing linux again 2021-03-10 16:46:10 +01:00
Maarten L. Hekkelman
873ac70d18 Build with MSVC 2021-03-10 14:10:25 +01:00
Maarten L. Hekkelman
9ca3c50c83 Build with MSVC 2021-03-10 14:10:02 +01:00
Maarten L. Hekkelman
cc1c7c39b1 do not build pdb2cif test for now 2021-03-10 10:37:45 +01:00
Maarten L. Hekkelman
2c6222984d link distance calculation 2021-03-10 08:46:14 +01:00
Maarten L. Hekkelman
58d7e17165 Add Anomalous remark 3 fields for phenix 2021-03-09 11:50:46 +01:00
Maarten L. Hekkelman
57618095bf fix LINK record (length position) 2021-03-09 09:09:33 +01:00
Maarten L. Hekkelman
492a1ad8ec LINK distance 2021-03-08 18:55:54 +01:00
Maarten L. Hekkelman
71da0ce345 fix in fixing distance for LINK records 2021-03-08 16:56:11 +01:00
Maarten L. Hekkelman
7dc574b534 Merge branch 'trunk' of github.com:PDB-REDO/libcifpp into trunk 2021-03-05 11:50:53 +01:00
Maarten L. Hekkelman
ff8a7a1bfd for g++-11 2021-03-05 11:50:08 +01:00
Maarten L. Hekkelman
0f963eeab1 @travis 2021-02-22 19:22:45 +01:00
Maarten L. Hekkelman
8f02665e6d symop table generator, now requires output argument 2021-02-22 17:13:50 +01:00
Maarten L. Hekkelman
8604c3ab03 merged 2021-02-22 15:23:51 +01:00
Maarten L. Hekkelman
7a61129388 refactor configure 2021-02-22 15:21:47 +01:00
Maarten L. Hekkelman
516db3d8be for travis 2021-02-20 19:40:07 +01:00
Maarten L. Hekkelman
34bdc5056a fix parsing PDB files containing carriage returns 2021-02-20 19:23:14 +01:00
Maarten L. Hekkelman
9402fd5cf3 boost flags order 2021-02-17 20:54:27 +01:00
Maarten L. Hekkelman
a6faa5ce0c fix libcifpp.pc, ax_pkg_require is not implemented in this configure yet 2021-02-17 19:44:02 +01:00
Maarten L. Hekkelman
5735a70e47 using resources... 2021-02-17 15:27:05 +01:00
Maarten L. Hekkelman
8f997658d7 update configure to configure data directories 2021-02-17 11:28:50 +01:00
Maarten L. Hekkelman
5069316326 When converting pdb to cif, calculate distance for LINKR records 2021-02-16 09:55:54 +01:00
Maarten L. Hekkelman
143f17fb2a reorganize resources 2021-02-10 13:55:40 +01:00
Maarten L. Hekkelman
900d7fa07a moved dictionaries 2021-02-10 13:28:33 +01:00
Maarten L. Hekkelman
a4389542fd pic 2021-02-10 10:42:49 +01:00
Maarten L. Hekkelman
b7f4e40917 ouch... wrong type in verbose output generation 2021-02-09 16:37:21 +01:00
Maarten L. Hekkelman
a0447ba91c implemented missing function cif::Category::find1 2021-02-08 16:24:02 +01:00
Maarten L. Hekkelman
17c9d208ad revert back to boost::regex for validator since gnu std::regex implementation is recursive without proper checks... 2021-01-25 16:51:12 +01:00
Maarten L. Hekkelman
e89311fcff init compound factory in absence of CLIBD_MON 2021-01-18 14:25:27 +01:00
Maarten L. Hekkelman
bab750fa6c USE_RSRC is really needed 2021-01-12 11:33:39 +01:00
Maarten L. Hekkelman
0caaf23767 Thread local compound factory, for servers that manipulate the factory. 2021-01-12 09:37:38 +01:00
Maarten L. Hekkelman
c5676f1dfb accept compressed raw data in mmcif::File constructor 2021-01-12 09:36:43 +01:00
Maarten L. Hekkelman
86854581f8 Add contructor loading raw data to mmcif::File 2021-01-11 16:37:18 +01:00
Maarten L. Hekkelman
ef81944826 fix hang in pdb parsing with single line file 2021-01-11 16:36:30 +01:00
Maarten L. Hekkelman
b3b53ebcc0 travis job with clang 2021-01-11 13:19:52 +01:00
Maarten L. Hekkelman
3bc0384100 Merge branch 'trunk' of github.com:PDB-REDO/libcifpp into trunk 2021-01-11 13:01:28 +01:00
Maarten L. Hekkelman
24b1c2ae58 remove Config.hpp from list of files to install 2021-01-11 13:01:20 +01:00
Maarten L. Hekkelman
c996bfcfaf added pthread flags 2021-01-11 13:00:06 +01:00
Maarten L. Hekkelman
3814635aa0 shared libraries, disable by default. Not my favourite, but hey, we need to build on MacOS as well... 2021-01-11 11:54:40 +01:00
Maarten L. Hekkelman
2b6c09cfad shared libraries, default action again 2021-01-11 11:19:34 +01:00
Maarten L. Hekkelman
9ee474081e search data_dir as well as cache_dir, for MacOS 2021-01-11 10:38:51 +01:00
Maarten L. Hekkelman
5bab298f74 search data_dir as well as cache_dir, for MacOS 2021-01-11 10:31:57 +01:00
Maarten L. Hekkelman
fd42b7f443 search data_dir as well as cache_dir, for MacOS 2021-01-11 10:28:49 +01:00
Maarten L. Hekkelman
edcea220f6 search data_dir as well as cache_dir, for MacOS 2021-01-11 10:12:14 +01:00
Maarten L. Hekkelman
a92e85f8db config.h file 2021-01-11 09:12:23 +01:00
Maarten L. Hekkelman
6fbe8bb192 refactored config file, avoid clashes in defines by autoconf 2021-01-11 08:54:49 +01:00
Maarten L. Hekkelman
5f45fd9b5b revert writing SOURCE_DATE_EPOCH since that is a Debian thing 2021-01-06 14:54:38 +01:00
Maarten L. Hekkelman
46925331c7 Merge branch 'trunk' of github.com:PDB-REDO/libcifpp into trunk 2021-01-06 13:04:06 +01:00
Maarten L. Hekkelman
84123df996 changes from Debian included 2021-01-06 13:03:52 +01:00
drlemmus
641b446195 Update update-dictionary-script
Updated URL for the mmcif dictionary download to HTTPS.
2021-01-06 08:53:54 +01:00
Maarten L. Hekkelman
34bbf06793 update config.hpp.in, fix update script to write correct filename 2020-12-17 08:49:39 +01:00
Maarten L. Hekkelman
53a88e236b check for libatomic in configure 2020-12-16 08:51:03 +01:00
Maarten L. Hekkelman
c2069a12b4 stupid typo 2020-12-15 20:24:31 +01:00
70 changed files with 15985 additions and 53591 deletions

20
.gitignore vendored
View File

@@ -1,16 +1,14 @@
obj.dbg/
obj/
.libs/
build/
.vscode/
.vs/
.pc/
autom4te.cache/
GNUmakefile
include/cif++/Config.hpp
tools/symop-map-generator
test/unit-test
libcifpp.pc
libcifpp.la
config.status
config.log
libtool
test/pdb2cif-test
test/rename-compound-test
tools/update-dictionary-script
data/
CMakeSettings.json
msvc/
Testing/

View File

@@ -11,7 +11,7 @@ osx_image:
compiler:
- gcc
# - clang
- clang
addons:
apt:
@@ -22,7 +22,7 @@ before_install:
- if [ "$TRAVIS_OS_NAME" = "osx" ]; then brew install make; fi
script:
- if [ "$TRAVIS_OS_NAME" = "osx" ]; then ./configure --disable-shared ; else ./configure ; fi
- if [ "$TRAVIS_OS_NAME" = "osx" ]; then ./configure --disable-shared --disable-revision --disable-download-ccd ; else ./configure --disable-revision --disable-download-ccd ; fi
- if [ "$TRAVIS_OS_NAME" = "osx" ]; then gmake ; else make ; fi
- if [ "$TRAVIS_OS_NAME" = "osx" ]; then gmake test ; else make test ; fi
- if [ "$TRAVIS_OS_NAME" = "osx" ]; then sudo gmake install ; else sudo make install; fi

494
CMakeLists.txt Normal file
View File

@@ -0,0 +1,494 @@
# SPDX-License-Identifier: BSD-2-Clause
# Copyright (c) 2021 NKI/AVL, Netherlands Cancer Institute
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
# 1. Redistributions of source code must retain the above copyright notice, this
# list of conditions and the following disclaimer
# 2. Redistributions in binary form must reproduce the above copyright notice,
# this list of conditions and the following disclaimer in the documentation
# and/or other materials provided with the distribution.
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
cmake_minimum_required(VERSION 3.16)
# set the project name
project(cifpp VERSION 2.0.0 LANGUAGES CXX)
list(PREPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
enable_testing()
include(GNUInstallDirs)
include(CheckFunctionExists)
include(CheckIncludeFiles)
include(CheckLibraryExists)
include(CMakePackageConfigHelpers)
include(Dart)
include(FindFilesystem)
include(GenerateExportHeader)
set(CXX_EXTENSIONS OFF)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
find_package(Filesystem REQUIRED)
if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
# https://stackoverflow.com/questions/63902528/program-crashes-when-filesystempath-is-destroyed
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -Wno-unused-parameter -Wno-missing-field-initializers")
elseif(MSVC)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /W4")
endif()
# Building shared libraries?
option(BUILD_SHARED_LIBS "Build a shared library instead of a static one" OFF)
# We do not want to write an export file for all our symbols...
set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS ON)
# Optionally build a version to be installed inside CCP4
option(BUILD_FOR_CCP4 "Build a version to be installed in CCP4" OFF)
if(BUILD_FOR_CCP4)
if("$ENV{CCP4}" STREQUAL "" OR NOT EXISTS $ENV{CCP4})
message(FATAL_ERROR "A CCP4 built was requested but CCP4 was not sourced")
else()
list(APPEND CMAKE_MODULE_PATH "$ENV{CCP4}")
list(APPEND CMAKE_PREFIX_PATH "$ENV{CCP4}")
set(CMAKE_INSTALL_PREFIX "$ENV{CCP4}")
# This is the only option:
if(WIN32)
set(BUILD_SHARED_LIBS ON)
endif()
endif("$ENV{CCP4}" STREQUAL "" OR NOT EXISTS $ENV{CCP4})
endif()
# Check if CCP4 is available
if(EXISTS "$ENV{CCP4}")
set(CCP4 $ENV{CCP4})
set(CLIBD ${CCP4}/lib/data)
endif()
if(CCP4 AND NOT CLIBD)
set(CLIBD ${CCP4}/lib/data)
endif()
# When CCP4 is sourced in the environment, we can recreate the symmetry operations table
if(EXISTS "${CCP4}")
if(RECREATE_SYMOP_DATA AND NOT EXISTS "${CLIBD}/syminfo.lib")
message(WARNING "Symop data table recreation requested, but file syminfo.lib was not found in ${CLIBD}")
set(RECREATE_SYMOP_DATA OFF)
else()
option(RECREATE_SYMOP_DATA "Recreate SymOp data table in case it is out of date" ON)
endif()
else()
set(RECREATE_SYMOP_DATA OFF)
message("Not trying to recreate SymOpTable_data.hpp since CCP4 is not defined")
endif()
set(CMAKE_DEBUG_POSTFIX d)
if(MSVC)
# make msvc standards compliant...
add_compile_options(/permissive-)
macro(get_WIN32_WINNT version)
if (WIN32 AND CMAKE_SYSTEM_VERSION)
set(ver ${CMAKE_SYSTEM_VERSION})
string(REPLACE "." "" ver ${ver})
string(REGEX REPLACE "([0-9])" "0\\1" ver ${ver})
set(${version} "0x${ver}")
endif()
endmacro()
get_WIN32_WINNT(ver)
add_definitions(-D_WIN32_WINNT=${ver})
# On Windows, do not install in the system location
if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT AND NOT BUILD_FOR_CCP4)
message(STATUS "The library and auxiliary files will be installed in $ENV{LOCALAPPDATA}/${PROJECT_NAME}")
set(CMAKE_INSTALL_PREFIX "$ENV{LOCALAPPDATA}/${PROJECT_NAME}" CACHE PATH "..." FORCE)
endif()
# Find out the processor type for the target
if(${CMAKE_SYSTEM_PROCESSOR} STREQUAL "AMD64")
set(COFF_TYPE "x64")
elseif(${CMAKE_SYSTEM_PROCESSOR} STREQUAL "i386")
set(COFF_TYPE "x86")
elseif(${CMAKE_SYSTEM_PROCESSOR} STREQUAL "ARM64")
set(COFF_TYPE "arm64")
else()
message(FATAL_ERROR "Unsupported or unknown processor type ${CMAKE_SYSTEM_PROCESSOR}")
endif()
set(COFF_SPEC "--coff=${COFF_TYPE}")
# for mrc, just in case
list(APPEND CMAKE_PREFIX_PATH "$ENV{LOCALAPPDATA}/mrc")
endif()
if(UNIX AND NOT APPLE AND NOT BUILD_FOR_CCP4 AND CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT)
# On Linux, install in the $HOME/.local folder by default
message(STATUS "The library and auxiliary files will be installed in $ENV{HOME}/.local")
set(CMAKE_INSTALL_PREFIX "$ENV{HOME}/.local" CACHE PATH "..." FORCE)
endif()
# Optionally use mrc to create resources
if(WIN32 AND BUILD_SHARED_LIBS)
message("Not using resources when building shared libraries for Windows")
else()
find_program(MRC mrc)
if(MRC)
option(USE_RSRC "Use mrc to create resources" ON)
else()
message("Using resources not possible since mrc was not found")
endif()
if(USE_RSRC STREQUAL "ON")
set(USE_RSRC 1)
message("Using resources compiled with ${MRC}")
add_compile_definitions(USE_RSRC)
endif()
endif()
# Libraries
set(CMAKE_THREAD_PREFER_PTHREAD)
set(THREADS_PREFER_PTHREAD_FLAG)
find_package(Threads)
set(Boost_DETAILED_FAILURE_MSG ON)
if(NOT BUILD_SHARED_LIBS)
set(Boost_USE_STATIC_LIBS ON)
endif()
find_package(Boost 1.70.0 REQUIRED COMPONENTS system iostreams regex program_options)
if(NOT MSVC AND Boost_USE_STATIC_LIBS)
find_package(ZLIB REQUIRED)
find_package(BZip2 REQUIRED)
endif()
# Create a revision file, containing the current git version info
find_package(Git)
if(GIT_FOUND AND EXISTS "${CMAKE_SOURCE_DIR}/.git")
include(GetGitRevisionDescription)
get_git_head_revision(REFSPEC COMMITHASH)
# Generate our own version string
git_describe_working_tree(BUILD_VERSION_STRING --match=build --dirty)
else()
message(WARNING "Git not found, cannot set version info")
SET(BUILD_VERSION_STRING ${PROJECT_VERSION})
endif()
# generate version.h
string(TIMESTAMP BUILD_DATE_TIME "%Y-%m-%dT%H:%M:%SZ" UTC)
configure_file("${CMAKE_SOURCE_DIR}/src/revision.hpp.in" "${CMAKE_BINARY_DIR}/revision.hpp" @ONLY)
# SymOp data table
if(RECREATE_SYMOP_DATA)
# The tool to create the table
add_executable(symop-map-generator "${CMAKE_SOURCE_DIR}/tools/symop-map-generator.cpp")
target_link_libraries(symop-map-generator Threads::Threads ${Boost_LIBRARIES} std::filesystem ${ZLIB_LIBRARIES} ${BZip2_LIBRARIES})
if(Boost_INCLUDE_DIR)
target_include_directories(symop-map-generator PUBLIC ${Boost_INCLUDE_DIR})
endif()
set($ENV{CLIBD} ${CLIBD})
add_custom_command(
OUTPUT ${CMAKE_SOURCE_DIR}/src/SymOpTable_data.hpp
COMMAND $<TARGET_FILE:symop-map-generator> ${CLIBD}/syminfo.lib ${CMAKE_SOURCE_DIR}/src/SymOpTable_data.hpp
)
add_custom_target(
OUTPUT ${CMAKE_SOURCE_DIR}/src/SymOpTable_data.hpp
DEPENDS symop-map-generator "$ENV{CLIBD}/syminfo.lib"
)
endif()
# Sources
set(project_sources
${PROJECT_SOURCE_DIR}/src/AtomType.cpp
${PROJECT_SOURCE_DIR}/src/BondMap.cpp
${PROJECT_SOURCE_DIR}/src/Cif++.cpp
${PROJECT_SOURCE_DIR}/src/Cif2PDB.cpp
${PROJECT_SOURCE_DIR}/src/CifParser.cpp
${PROJECT_SOURCE_DIR}/src/CifUtils.cpp
${PROJECT_SOURCE_DIR}/src/CifValidator.cpp
${PROJECT_SOURCE_DIR}/src/Compound.cpp
${PROJECT_SOURCE_DIR}/src/PDB2Cif.cpp
${PROJECT_SOURCE_DIR}/src/PDB2CifRemark3.cpp
${PROJECT_SOURCE_DIR}/src/Point.cpp
${PROJECT_SOURCE_DIR}/src/Secondary.cpp
${PROJECT_SOURCE_DIR}/src/Structure.cpp
${PROJECT_SOURCE_DIR}/src/Symmetry.cpp
${PROJECT_SOURCE_DIR}/src/TlsParser.cpp
)
set(project_headers
${PROJECT_SOURCE_DIR}/include/cif++/AtomType.hpp
${PROJECT_SOURCE_DIR}/include/cif++/BondMap.hpp
${PROJECT_SOURCE_DIR}/include/cif++/Cif++.hpp
${PROJECT_SOURCE_DIR}/include/cif++/Cif2PDB.hpp
${PROJECT_SOURCE_DIR}/include/cif++/CifParser.hpp
${PROJECT_SOURCE_DIR}/include/cif++/CifUtils.hpp
${PROJECT_SOURCE_DIR}/include/cif++/CifValidator.hpp
${PROJECT_SOURCE_DIR}/include/cif++/Compound.hpp
${PROJECT_SOURCE_DIR}/include/cif++/Matrix.hpp
${PROJECT_SOURCE_DIR}/include/cif++/PDB2Cif.hpp
${PROJECT_SOURCE_DIR}/include/cif++/PDB2CifRemark3.hpp
${PROJECT_SOURCE_DIR}/include/cif++/Point.hpp
${PROJECT_SOURCE_DIR}/include/cif++/Secondary.hpp
${PROJECT_SOURCE_DIR}/include/cif++/Structure.hpp
${PROJECT_SOURCE_DIR}/include/cif++/Symmetry.hpp
${PROJECT_SOURCE_DIR}/include/cif++/TlsParser.hpp
)
add_library(cifpp ${project_sources} ${project_headers} ${CMAKE_SOURCE_DIR}/src/SymOpTable_data.hpp)
set_target_properties(cifpp PROPERTIES POSITION_INDEPENDENT_CODE ON)
target_include_directories(cifpp
PUBLIC
"$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/include>"
"$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>"
${Boost_INCLUDE_DIR}
)
target_include_directories(cifpp
PRIVATE
${CMAKE_BINARY_DIR}
)
target_link_libraries(cifpp Threads::Threads ${Boost_LIBRARIES} std::filesystem ${ZLIB_LIBRARIES} ${BZip2_LIBRARIES})
if (CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang")
target_link_options(cifpp PRIVATE -undefined dynamic_lookup)
endif (CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang")
# download the components.cif file from CCD
set(COMPONENTS_CIF ${PROJECT_SOURCE_DIR}/data/components.cif)
if (NOT EXISTS ${COMPONENTS_CIF})
if (NOT EXISTS ${PROJECT_SOURCE_DIR}/data)
file(MAKE_DIRECTORY ${PROJECT_SOURCE_DIR}/data/)
endif()
# if(${CMAKE_VERSION} VERSION_LESS "3.19.0")
find_program(GUNZIP gunzip)
if(GUNZIP)
file(DOWNLOAD ftp://ftp.wwpdb.org/pub/pdb/data/monomers/components.cif.gz ${COMPONENTS_CIF}.gz
SHOW_PROGRESS)
add_custom_command(OUTPUT ${COMPONENTS_CIF}
COMMAND ${GUNZIP} ${COMPONENTS_CIF}.gz
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/data/)
else()
file(DOWNLOAD ftp://ftp.wwpdb.org/pub/pdb/data/monomers/components.cif ${COMPONENTS_CIF}
SHOW_PROGRESS)
endif()
# else()
# file(DOWNLOAD ftp://ftp.wwpdb.org/pub/pdb/data/monomers/components.cif.gz ${COMPONENTS_CIF}.gz
# SHOW_PROGRESS)
# file(ARCHIVE_EXTRACT INPUT ${COMPONENTS_CIF}.gz
# DESTINATION ${CMAKE_SOURCE_DIR}/data/
# VERBOSE)
# endif()
endif()
add_custom_target(COMPONENTS ALL DEPENDS ${COMPONENTS_CIF})
if(UNIX)
option(INSTALL_UPDATE_SCRIPT "Install the script to update CCD and dictionary files" OFF)
if(INSTALL_UPDATE_SCRIPT)
set(CIFPP_CACHE_DIR "/var/cache/libcifpp")
if(NOT "${CIFPP_CACHE_DIR}" STREQUAL "OFF")
target_compile_definitions(cifpp PUBLIC CACHE_DIR="${CIFPP_CACHE_DIR}")
endif()
endif()
endif()
generate_export_header(cifpp
EXPORT_FILE_NAME cif++/Cif++Export.hpp)
set(INCLUDE_INSTALL_DIR ${CMAKE_INSTALL_INCLUDEDIR} )
set(LIBRARY_INSTALL_DIR ${CMAKE_INSTALL_LIBDIR} )
set(SHARE_INSTALL_DIR ${CMAKE_INSTALL_DATADIR}/libcifpp)
target_compile_definitions(cifpp PUBLIC DATA_DIR="${CMAKE_INSTALL_PREFIX}/${SHARE_INSTALL_DIR}")
# Install rules
install(TARGETS cifpp
EXPORT cifppTargets
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
install(EXPORT cifppTargets
FILE "cifppTargets.cmake"
NAMESPACE cifpp::
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/cifpp
)
install(
DIRECTORY include/cif++
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
COMPONENT Devel
)
install(
FILES "${CMAKE_CURRENT_BINARY_DIR}/cif++/Cif++Export.hpp"
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/cif++
COMPONENT Devel
)
install(FILES
${PROJECT_SOURCE_DIR}/rsrc/mmcif_ddl.dic
${PROJECT_SOURCE_DIR}/rsrc/mmcif_pdbx_v50.dic
${PROJECT_SOURCE_DIR}/data/components.cif
DESTINATION ${SHARE_INSTALL_DIR}
)
configure_package_config_file(Config.cmake.in
${CMAKE_CURRENT_BINARY_DIR}/cifpp/cifppConfig.cmake
INSTALL_DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/cifpp
PATH_VARS INCLUDE_INSTALL_DIR LIBRARY_INSTALL_DIR SHARE_INSTALL_DIR
)
install(FILES
"${CMAKE_CURRENT_BINARY_DIR}/cifpp/cifppConfig.cmake"
"${CMAKE_CURRENT_BINARY_DIR}/cifpp/cifppConfigVersion.cmake"
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/cifpp
COMPONENT Devel
)
set(cifpp_MAJOR_VERSION ${CMAKE_PROJECT_VERSION_MAJOR})
set_target_properties(cifpp PROPERTIES
VERSION ${PROJECT_VERSION}
SOVERSION ${cifpp_MAJOR_VERSION}
INTERFACE_cifpp_MAJOR_VERSION ${cifpp_MAJOR_VERSION})
set_property(TARGET cifpp APPEND PROPERTY
COMPATIBLE_INTERFACE_STRING cifpp_MAJOR_VERSION
)
write_basic_package_version_file(
"${CMAKE_CURRENT_BINARY_DIR}/cifpp/cifppConfigVersion.cmake"
VERSION ${PROJECT_VERSION}
COMPATIBILITY AnyNewerVersion
)
# pkgconfig support
set(prefix ${CMAKE_INSTALL_PREFIX})
set(exec_prefix ${CMAKE_INSTALL_PREFIX})
set(libdir ${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR})
set(includedir ${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_INCLUDEDIR})
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/libcifpp.pc.in
${CMAKE_CURRENT_BINARY_DIR}/libcifpp.pc.in @ONLY)
file(GENERATE OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/libcifpp.pc
INPUT ${CMAKE_CURRENT_BINARY_DIR}/libcifpp.pc.in)
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/libcifpp.pc DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig)
# Unit tests
option(CIFPP_BUILD_TESTS "Build test exectuables" OFF)
if(CIFPP_BUILD_TESTS)
if(USE_RSRC)
add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/cifpp_test_rsrc.obj
COMMAND ${MRC} -o ${CMAKE_CURRENT_BINARY_DIR}/cifpp_test_rsrc.obj ${CMAKE_SOURCE_DIR}/rsrc/mmcif_pdbx_v50.dic ${COFF_SPEC}
)
set(CIFPP_TEST_RESOURCE ${CMAKE_CURRENT_BINARY_DIR}/cifpp_test_rsrc.obj)
endif()
list(APPEND CIFPP_tests
# pdb2cif
rename-compound
structure
unit)
foreach(CIFPP_TEST IN LISTS CIFPP_tests)
set(CIFPP_TEST "${CIFPP_TEST}-test")
set(CIFPP_TEST_SOURCE "${CMAKE_CURRENT_SOURCE_DIR}/test/${CIFPP_TEST}.cpp")
add_executable(${CIFPP_TEST} ${CIFPP_TEST_SOURCE} ${CIFPP_TEST_RESOURCE})
target_include_directories(${CIFPP_TEST} PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}/include
${CMAKE_CURRENT_BINARY_DIR} # for config.h
)
target_link_libraries(${CIFPP_TEST} PRIVATE Threads::Threads cifpp ${Boost_LIBRARIES} std::filesystem ${ZLIB_LIBRARIES} ${BZip2_LIBRARIES})
if(MSVC)
# Specify unwind semantics so that MSVC knowns how to handle exceptions
target_compile_options(${CIFPP_TEST} PRIVATE /EHsc)
endif()
add_custom_target("run-${CIFPP_TEST}" DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/Run${CIFPP_TEST}.touch ${CIFPP_TEST})
add_custom_command(
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/Run${CIFPP_TEST}.touch
COMMAND $<TARGET_FILE:${CIFPP_TEST}> -- ${PROJECT_SOURCE_DIR}/test)
add_test(NAME ${CIFPP_TEST}
COMMAND $<TARGET_FILE:${CIFPP_TEST}> -- ${PROJECT_SOURCE_DIR}/test)
endforeach()
endif()
message("Will install in ${CMAKE_INSTALL_PREFIX}")
# Optionally install the update scripts for CCD and dictionary files
if(INSTALL_UPDATE_SCRIPT)
set(CIFPP_CRON_DIR "$ENV{DESTDIR}/etc/cron.weekly")
configure_file(${CMAKE_SOURCE_DIR}/tools/update-dictionary-script.in update-dictionary-script @ONLY)
install(
FILES ${CMAKE_CURRENT_BINARY_DIR}/update-dictionary-script
DESTINATION ${CIFPP_CRON_DIR}
PERMISSIONS OWNER_EXECUTE OWNER_READ GROUP_EXECUTE GROUP_READ WORLD_EXECUTE WORLD_READ
)
install(DIRECTORY DESTINATION ${CIFPP_CACHE_DIR})
install(DIRECTORY DESTINATION "$ENV{DESTDIR}/etc/libcifpp/cache-update.d")
# a config to, to make it complete
file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/libcifpp.conf [[# Uncomment the next line to enable automatic updates
# update=true
]])
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/libcifpp.conf DESTINATION "$ENV{DESTDIR}/etc")
target_compile_definitions(cifpp PUBLIC CACHE_DIR="${CIFPP_CACHE_DIR}")
install(CODE "message(\"A configuration file has been written to $ENV{DESTDIR}/etc/libcifpp.conf, please edit this file to enable automatic updates\")")
endif()

16
Config.cmake.in Normal file
View File

@@ -0,0 +1,16 @@
@PACKAGE_INIT@
include(CMakeFindDependencyMacro)
find_dependency(Boost 1.70.0 REQUIRED COMPONENTS system iostreams regex program_options)
if(NOT WIN32)
find_dependency(ZLIB)
find_dependency(BZip2)
endif()
INCLUDE("${CMAKE_CURRENT_LIST_DIR}/cifppTargets.cmake")
set_and_check(CIFPP_INCLUDE_DIR "@PACKAGE_INCLUDE_INSTALL_DIR@")
set_and_check(CIFPP_LIBRARY_DIR "@PACKAGE_LIBRARY_INSTALL_DIR@")
set_and_check(CIFPP_SHARE_DIR "@PACKAGE_SHARE_INSTALL_DIR@")
check_required_components(cifpp)

View File

@@ -1,273 +0,0 @@
# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2020 NKI/AVL, Netherlands Cancer Institute
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
# 1. Redistributions of source code must retain the above copyright notice, this
# list of conditions and the following disclaimer
# 2. Redistributions in binary form must reproduce the above copyright notice,
# this list of conditions and the following disclaimer in the documentation
# and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
# makefile for libcifpp
.PHONY: firstTarget
firstTarget: all
CXX = @CXX@
CXXFLAGS = @CPPFLAGS@ @CXXFLAGS@ @BOOST_CPPFLAGS@
LDFLAGS = @LDFLAGS@ @LIBS@ @BOOST_LDFLAGS@
LIBS = @LIBS@ \
-latomic \
@BOOST_IOSTREAMS_LIB@ \
@BOOST_DATE_TIME_LIB@
prefix = $(DESTDIR)@prefix@
exec_prefix = @exec_prefix@
libdir = @libdir@
includedir = @includedir@
datarootdir = @datarootdir@
datadir = @datadir@
docdir = @docdir@
pkgconfigdir = $(libdir)/pkgconfig
CCP4DIR = @CCP4@
CLIBD = $(CCP4DIR:%=%/lib/data)
CACHE_DIR = $(DESTDIR)/var/cache/libcifpp
CRON_DIR = $(DESTDIR)/etc/cron.weekly
DEFINES += CACHE_DIR='"$(CACHE_DIR)"'
GNUmakefile: config.status GNUmakefile.in
$(SHELL) ./config.status
ifeq "$(CHECK_CONFIG)" "1"
config.status: configure
$(SHELL) ./config.status --recheck
configure: configure.ac
autoconf
endif
LIB_NAME = @PACKAGE_NAME@
LIB_VERSION = @LIBCIF_LT_VERSION@
LIB_CURRENT = @LIBCIF_LT_CURRENT@
LIB_TARGET = $(LIB_NAME).la
VERSION = @LIBCIF_SEMANTIC_VERSION@
DIST_NAME = @PACKAGE_NAME@-$(subst :,.,$(VERSION))
# libtool stuff
LIBTOOL_DEPS = @LIBTOOL_DEPS@
libtool: $(LIBTOOL_DEPS)
$(SHELL) ./config.status libtool
LIBTOOL = $(SHELL) @abs_top_builddir@/libtool
CXXCOMPILE = $(LIBTOOL) --silent --tag=CXX --mode=compile $(CXX) $(CXXFLAGS)
CXXLINK = $(LIBTOOL) --silent --tag=CXX --mode=link $(CXX) $(CXXFLAGS) $(LDFLAGS) -version-info $(LIB_VERSION) -o $@
# main build variables
CXXFLAGS += -Wall -Wno-multichar -I include
# Use the DEBUG flag to build debug versions of the code
DEBUG = @DEBUG@
ifeq "$(DEBUG)" "1"
DEFINES += DEBUG
CXXFLAGS += -g -O0
LDFLAGS += -g
else
CXXFLAGS += -O2
DEFINES += NDEBUG
endif
# targets
VPATH += src:test
CXXFLAGS += $(DEFINES:%=-D%)
OBJDIR = obj
ifeq "$(DEBUG)" "1"
OBJDIR := $(OBJDIR).dbg
endif
$(OBJDIR):
mkdir -p $(OBJDIR)
OBJECTS = $(OBJDIR)/AtomType.lo \
$(OBJDIR)/Cif2PDB.lo \
$(OBJDIR)/Cif++.lo \
$(OBJDIR)/CifParser.lo \
$(OBJDIR)/CifUtils.lo \
$(OBJDIR)/CifValidator.lo \
$(OBJDIR)/Compound.lo \
$(OBJDIR)/PDB2Cif.lo \
$(OBJDIR)/PDB2CifRemark3.lo \
$(OBJDIR)/Point.lo \
$(OBJDIR)/Secondary.lo \
$(OBJDIR)/Structure.lo \
$(OBJDIR)/Symmetry.lo \
$(OBJDIR)/TlsParser.lo
ifneq "$(CCP4DIR)" ""
# Special rules to generate symmetry operation number table
tools/symop-map-generator: tools/symop-map-generator.cpp
src/SymOpTable_data.cpp: tools/symop-map-generator $(CLIBD)/symop.lib
tools/symop-map-generator > $@
$(OBJDIR)/Symmetry.lo: src/SymOpTable_data.cpp
endif
# We have development releases and official releases, for each we
# maintain different versioning schemes.
ifneq "x@UPDATE_REVISION@" "x"
REVISION = $(shell git log --pretty=format:%h --max-count=1)
REVISION_FILE = version-info-$(REVISION).txt
$(REVISION_FILE):
rm -f version-info-*.txt
@ echo libcifpp-version: $(VERSION) > $@
@ git describe --match=build --dirty >> $@
@ git log --pretty=medium --date=iso8601 -1 >> $@
src/revision.hpp: $(REVISION_FILE)
@ echo 'const char kRevision[] = R"(' > $@
@ cat $? >> $@
@ echo ')";' >> $@
else
src/revision.hpp:
@ echo 'const char kRevision[] = R"(' > $@
@ echo libcifpp-version: $(VERSION) >> $@
@ echo Date: $$(date --iso-8601) >> $@
@ echo ')";' >> $@
endif
$(OBJDIR)/CifUtils.o: src/revision.hpp
$(OBJDIR)/CifUtils.lo: src/revision.hpp
$(LIB_TARGET): $(OBJECTS)
$(CXXLINK) -rpath $(libdir) $(OBJECTS) $(LIBS)
.PHONY: lib
lib: $(LIB_TARGET)
.PHONY: all
all: $(LIB_TARGET)
-include $(OBJECTS:%.lo=%.d)
$(OBJECTS:.lo=.d):
$(OBJDIR)/%.lo: %.cpp | $(OBJDIR)
@ echo ">>" $<
@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(OBJDIR)/$*.d -c -o $@ $<
$(OBJDIR)/%.o: %.cpp | $(OBJDIR)
@ echo ">>" $<
@ $(CXX) $(CXXFLAGS) -MT $@ -MD -MP -MF $(OBJDIR)/$*.d -c -o $@ $<
.PHONY: clean
clean:
rm -rf .libs $(OBJDIR)/* $(LIB_TARGET)
rm -f $(TESTS:%=test/%-test)
.PHONY: distclean
distclean: clean
rm -f libtool config.lt
rm -f config.status config.cache config.log configure.lineno config.status.lineno
rm -f GNUmakefile
# Test rules
define TEST_template =
-include $$(OBJDIR)/$(1)-test.d
$(1)_OBJECTS = $$(OBJDIR)/$(1)-test.o
test/$(1)-test: $(LIB_TARGET) $$($(1)_OBJECTS)
@ echo ">>> building $(1)-test"
$(CXX) $(CXXFLAGS) $(LDFLAGS) -o $$@ $$($(1)_OBJECTS) -L.libs -lcifpp $(LIBS)
.PHONY: $(1)-test
$(1)-test: test/$(1)-test
cd test; LD_LIBRARY_PATH=../.libs ./$(1)-test $$($(1)_PARAMS)
endef
TESTS = unit
$(foreach part,$(TESTS),$(eval $(call TEST_template,$(part))))
.PHONY: test
test: $(TESTS:%=%-test)
HEADERS = \
AtomType.hpp \
CifParser.hpp \
Compound.hpp \
PDB2CifRemark3.hpp \
Structure.hpp \
Cif2PDB.hpp \
CifUtils.hpp \
Config.hpp \
Point.hpp \
Symmetry.hpp \
Cif++.hpp \
CifValidator.hpp \
PDB2Cif.hpp \
Secondary.hpp \
TlsParser.hpp
.PHONY: install
install: lib
install -d $(libdir)
$(LIBTOOL) --mode=install install $(LIB_TARGET) $(libdir)
install -d $(datadir)/libcifpp
for d in isomers.txt dictionaries/mmcif_ddl.dic dictionaries/mmcif_pdbx_v50.dic; do \
install -m644 rsrc/$$d $(datadir)/libcifpp; \
done
gzip -f $(datadir)/libcifpp/*
install -d $(CRON_DIR)
install -m755 tools/update-dictionary-script $(CRON_DIR)/libcifpp
install -d $(includedir)/cif++
for f in $(HEADERS); do install include/cif++/$$f $(includedir)/cif++/$$f; done
install -d $(pkgconfigdir)
install -m 644 $(LIB_NAME).pc $(pkgconfigdir)/$(LIB_NAME).pc
dist-clean: clean
.PHONY: dist
dist:
rm -rf $(DIST_NAME)
mkdir $(DIST_NAME)
git archive trunk | tar -x -C $(DIST_NAME)
tar czf $(DIST_NAME).tgz $(DIST_NAME)
rm -rf $(DIST_NAME)
FORCE:

View File

@@ -1,32 +1,47 @@
[![Build Status](https://travis-ci.org/PDB-REDO/libcifpp.svg?branch=trunk)](https://travis-ci.org/PDB-REDO/libcifpp)
libcifpp
========
This library contains code to work with mmCIF and PDB files.
Requirements
------------
The code for this library was written in C++17. You therefore need a
recent compiler to build it. For the development gcc 9.3 and clang 9.0
have been used.
have been used as well as MSVC version 2019.
Other requirements are:
- GNU make version 4.1 or higher.
- Boost libraries, at least version 1.71
- Boost libraries, at least version 1.70
- [mrc](https://github.com/mhekkel/mrc), a resource compiler that
allows including data files into the executable making them easier to
install. Strictly this is optional, but at the expense of a lot of
functionality.
install. Strictly this is optional, but at the expense of functionality.
Building
--------
Simply configure, make and make install.
This library uses [cmake](https://cmake.org). The usual way of building
and installing is to create a `build` directory and run cmake there.
On linux e.g. you would issue the following commands:
```
git clone https://github.com/PDB-REDO/libcifpp.git
cd libcifpp
mkdir build
cd build
cmake ..
cmake --build . --config Release
ctest -C Release
cmake --install .
```
This checks out the source code from github, creates a new directory
where cmake stores its files. Run a configure, build the code and run
tests. And then it installs the library and auxiliary files.
The default is to install everything in `$HOME/.local` on Linux and
`%LOCALAPPDATA%` on Windows (the AppData/Local folder in your home directory).
You can change this by specifying the prefix with the
[CMAKE_INSTALL_PREFIX](https://cmake.org/cmake/help/v3.21/variable/CMAKE_INSTALL_PREFIX.html)
variable.
There's one configure flag that might be of interest: if you specify
DEBUG=1 the make will create a debug version by default. Otherwise,
you can run make with DEBUG=1 to create a debug version.

View File

@@ -1,6 +1,18 @@
Version 2.0.0
- New API interface for accessing query results
- Removed bzip2 support
- improved makefiles
Version 1.1.1
- Now with full support for MS Windows
Version 1.1.0
- Changed from GNU configure to CMake.
- Loading compound information from CCD file
Version 1.0.1
- Changed the way resources are looked up, local dir first,
then /var/cache and finally compiled in resources (with mrc).
Version 1.0.0
- First public release
- First public release

View File

@@ -0,0 +1,74 @@
# Simplistic reimplementation of https://github.com/vector-of-bool/CMakeCM/blob/master/modules/FindFilesystem.cmake
if(TARGET std::filesystem)
return()
endif()
cmake_minimum_required(VERSION 3.10)
include(CMakePushCheckState)
include(CheckIncludeFileCXX)
include(CheckCXXSourceCompiles)
cmake_push_check_state()
set(CMAKE_CXX_STANDARD 17)
check_include_file_cxx("filesystem" _CXX_FILESYSTEM_HAVE_HEADER)
mark_as_advanced(_CXX_FILESYSTEM_HAVE_HEADER)
set(code [[
#include <cstdlib>
#include <filesystem>
int main() {
auto cwd = std::filesystem::current_path();
return EXIT_SUCCESS;
}
]])
if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU" AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS_EQUAL 8.4.0)
# >> https://stackoverflow.com/questions/63902528/program-crashes-when-filesystempath-is-destroyed
set(CXX_FILESYSTEM_NO_LINK_NEEDED 0)
else()
# Check a simple filesystem program without any linker flags
check_cxx_source_compiles("${code}" CXX_FILESYSTEM_NO_LINK_NEEDED)
endif()
if(CXX_FILESYSTEM_NO_LINK_NEEDED)
set(_found 1)
else()
set(prev_libraries ${CMAKE_REQUIRED_LIBRARIES})
# Add the libstdc++ flag
set(CMAKE_REQUIRED_LIBRARIES ${prev_libraries} -lstdc++fs)
check_cxx_source_compiles("${code}" CXX_FILESYSTEM_STDCPPFS_NEEDED)
set(_found ${CXX_FILESYSTEM_STDCPPFS_NEEDED})
if(NOT CXX_FILESYSTEM_STDCPPFS_NEEDED)
# Try the libc++ flag
set(CMAKE_REQUIRED_LIBRARIES ${prev_libraries} -lc++fs)
check_cxx_source_compiles("${code}" CXX_FILESYSTEM_CPPFS_NEEDED)
set(_found ${CXX_FILESYSTEM_CPPFS_NEEDED})
endif()
endif()
if(_found)
add_library(std::filesystem INTERFACE IMPORTED)
set_property(TARGET std::filesystem APPEND PROPERTY INTERFACE_COMPILE_FEATURES cxx_std_17)
if(CXX_FILESYSTEM_NO_LINK_NEEDED)
# Nothing to add...
elseif(CXX_FILESYSTEM_STDCPPFS_NEEDED)
set_target_properties(std::filesystem PROPERTIES IMPORTED_LIBNAME stdc++fs)
elseif(CXX_FILESYSTEM_CPPFS_NEEDED)
set_target_properties(std::filesystem PROPERTIES IMPORTED_LIBNAME c++fs)
endif()
endif()
cmake_pop_check_state()
set(Filesystem_FOUND ${_found} CACHE BOOL "TRUE if we can run a program using std::filesystem" FORCE)
if(Filesystem_FIND_REQUIRED AND NOT Filesystem_FOUND)
message(FATAL_ERROR "Cannot run simple program using std::filesystem")
endif()

View File

@@ -0,0 +1,284 @@
# - Returns a version string from Git
#
# These functions force a re-configure on each git commit so that you can
# trust the values of the variables in your build system.
#
# get_git_head_revision(<refspecvar> <hashvar> [ALLOW_LOOKING_ABOVE_CMAKE_SOURCE_DIR])
#
# Returns the refspec and sha hash of the current head revision
#
# git_describe(<var> [<additional arguments to git describe> ...])
#
# Returns the results of git describe on the source tree, and adjusting
# the output so that it tests false if an error occurs.
#
# git_describe_working_tree(<var> [<additional arguments to git describe> ...])
#
# Returns the results of git describe on the working tree (--dirty option),
# and adjusting the output so that it tests false if an error occurs.
#
# git_get_exact_tag(<var> [<additional arguments to git describe> ...])
#
# Returns the results of git describe --exact-match on the source tree,
# and adjusting the output so that it tests false if there was no exact
# matching tag.
#
# git_local_changes(<var>)
#
# Returns either "CLEAN" or "DIRTY" with respect to uncommitted changes.
# Uses the return code of "git diff-index --quiet HEAD --".
# Does not regard untracked files.
#
# Requires CMake 2.6 or newer (uses the 'function' command)
#
# Original Author:
# 2009-2020 Ryan Pavlik <ryan.pavlik@gmail.com> <abiryan@ryand.net>
# http://academic.cleardefinition.com
#
# Copyright 2009-2013, Iowa State University.
# Copyright 2013-2020, Ryan Pavlik
# Copyright 2013-2020, Contributors
# SPDX-License-Identifier: BSL-1.0
# Distributed under the Boost Software License, Version 1.0.
# (See accompanying file LICENSE_1_0.txt or copy at
# http://www.boost.org/LICENSE_1_0.txt)
if(__get_git_revision_description)
return()
endif()
set(__get_git_revision_description YES)
# We must run the following at "include" time, not at function call time,
# to find the path to this module rather than the path to a calling list file
get_filename_component(_gitdescmoddir ${CMAKE_CURRENT_LIST_FILE} PATH)
# Function _git_find_closest_git_dir finds the next closest .git directory
# that is part of any directory in the path defined by _start_dir.
# The result is returned in the parent scope variable whose name is passed
# as variable _git_dir_var. If no .git directory can be found, the
# function returns an empty string via _git_dir_var.
#
# Example: Given a path C:/bla/foo/bar and assuming C:/bla/.git exists and
# neither foo nor bar contain a file/directory .git. This wil return
# C:/bla/.git
#
function(_git_find_closest_git_dir _start_dir _git_dir_var)
set(cur_dir "${_start_dir}")
set(git_dir "${_start_dir}/.git")
while(NOT EXISTS "${git_dir}")
# .git dir not found, search parent directories
set(git_previous_parent "${cur_dir}")
get_filename_component(cur_dir "${cur_dir}" DIRECTORY)
if(cur_dir STREQUAL git_previous_parent)
# We have reached the root directory, we are not in git
set(${_git_dir_var}
""
PARENT_SCOPE)
return()
endif()
set(git_dir "${cur_dir}/.git")
endwhile()
set(${_git_dir_var}
"${git_dir}"
PARENT_SCOPE)
endfunction()
function(get_git_head_revision _refspecvar _hashvar)
_git_find_closest_git_dir("${CMAKE_CURRENT_SOURCE_DIR}" GIT_DIR)
if("${ARGN}" STREQUAL "ALLOW_LOOKING_ABOVE_CMAKE_SOURCE_DIR")
set(ALLOW_LOOKING_ABOVE_CMAKE_SOURCE_DIR TRUE)
else()
set(ALLOW_LOOKING_ABOVE_CMAKE_SOURCE_DIR FALSE)
endif()
if(NOT "${GIT_DIR}" STREQUAL "")
file(RELATIVE_PATH _relative_to_source_dir "${CMAKE_SOURCE_DIR}"
"${GIT_DIR}")
if("${_relative_to_source_dir}" MATCHES "[.][.]" AND NOT ALLOW_LOOKING_ABOVE_CMAKE_SOURCE_DIR)
# We've gone above the CMake root dir.
set(GIT_DIR "")
endif()
endif()
if("${GIT_DIR}" STREQUAL "")
set(${_refspecvar}
"GITDIR-NOTFOUND"
PARENT_SCOPE)
set(${_hashvar}
"GITDIR-NOTFOUND"
PARENT_SCOPE)
return()
endif()
# Check if the current source dir is a git submodule or a worktree.
# In both cases .git is a file instead of a directory.
#
if(NOT IS_DIRECTORY ${GIT_DIR})
# The following git command will return a non empty string that
# points to the super project working tree if the current
# source dir is inside a git submodule.
# Otherwise the command will return an empty string.
#
execute_process(
COMMAND "${GIT_EXECUTABLE}" rev-parse
--show-superproject-working-tree
WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
OUTPUT_VARIABLE out
ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE)
if(NOT "${out}" STREQUAL "")
# If out is empty, GIT_DIR/CMAKE_CURRENT_SOURCE_DIR is in a submodule
file(READ ${GIT_DIR} submodule)
string(REGEX REPLACE "gitdir: (.*)$" "\\1" GIT_DIR_RELATIVE
${submodule})
string(STRIP ${GIT_DIR_RELATIVE} GIT_DIR_RELATIVE)
get_filename_component(SUBMODULE_DIR ${GIT_DIR} PATH)
get_filename_component(GIT_DIR ${SUBMODULE_DIR}/${GIT_DIR_RELATIVE}
ABSOLUTE)
set(HEAD_SOURCE_FILE "${GIT_DIR}/HEAD")
else()
# GIT_DIR/CMAKE_CURRENT_SOURCE_DIR is in a worktree
file(READ ${GIT_DIR} worktree_ref)
# The .git directory contains a path to the worktree information directory
# inside the parent git repo of the worktree.
#
string(REGEX REPLACE "gitdir: (.*)$" "\\1" git_worktree_dir
${worktree_ref})
string(STRIP ${git_worktree_dir} git_worktree_dir)
_git_find_closest_git_dir("${git_worktree_dir}" GIT_DIR)
set(HEAD_SOURCE_FILE "${git_worktree_dir}/HEAD")
endif()
else()
set(HEAD_SOURCE_FILE "${GIT_DIR}/HEAD")
endif()
set(GIT_DATA "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/git-data")
if(NOT EXISTS "${GIT_DATA}")
file(MAKE_DIRECTORY "${GIT_DATA}")
endif()
if(NOT EXISTS "${HEAD_SOURCE_FILE}")
return()
endif()
set(HEAD_FILE "${GIT_DATA}/HEAD")
configure_file("${HEAD_SOURCE_FILE}" "${HEAD_FILE}" COPYONLY)
configure_file("${_gitdescmoddir}/GetGitRevisionDescription.cmake.in"
"${GIT_DATA}/grabRef.cmake" @ONLY)
include("${GIT_DATA}/grabRef.cmake")
set(${_refspecvar}
"${HEAD_REF}"
PARENT_SCOPE)
set(${_hashvar}
"${HEAD_HASH}"
PARENT_SCOPE)
endfunction()
function(git_describe _var)
if(NOT GIT_FOUND)
find_package(Git QUIET)
endif()
get_git_head_revision(refspec hash)
if(NOT GIT_FOUND)
set(${_var}
"GIT-NOTFOUND"
PARENT_SCOPE)
return()
endif()
if(NOT hash)
set(${_var}
"HEAD-HASH-NOTFOUND"
PARENT_SCOPE)
return()
endif()
# TODO sanitize
#if((${ARGN}" MATCHES "&&") OR
# (ARGN MATCHES "||") OR
# (ARGN MATCHES "\\;"))
# message("Please report the following error to the project!")
# message(FATAL_ERROR "Looks like someone's doing something nefarious with git_describe! Passed arguments ${ARGN}")
#endif()
#message(STATUS "Arguments to execute_process: ${ARGN}")
execute_process(
COMMAND "${GIT_EXECUTABLE}" describe --tags --always ${hash} ${ARGN}
WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
RESULT_VARIABLE res
OUTPUT_VARIABLE out
ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE)
if(NOT res EQUAL 0)
set(out "${out}-${res}-NOTFOUND")
endif()
set(${_var}
"${out}"
PARENT_SCOPE)
endfunction()
function(git_describe_working_tree _var)
if(NOT GIT_FOUND)
find_package(Git QUIET)
endif()
if(NOT GIT_FOUND)
set(${_var}
"GIT-NOTFOUND"
PARENT_SCOPE)
return()
endif()
execute_process(
COMMAND "${GIT_EXECUTABLE}" describe --dirty ${ARGN}
WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
RESULT_VARIABLE res
OUTPUT_VARIABLE out
ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE)
if(NOT res EQUAL 0)
set(out "${out}-${res}-NOTFOUND")
endif()
set(${_var}
"${out}"
PARENT_SCOPE)
endfunction()
function(git_get_exact_tag _var)
git_describe(out --exact-match ${ARGN})
set(${_var}
"${out}"
PARENT_SCOPE)
endfunction()
function(git_local_changes _var)
if(NOT GIT_FOUND)
find_package(Git QUIET)
endif()
get_git_head_revision(refspec hash)
if(NOT GIT_FOUND)
set(${_var}
"GIT-NOTFOUND"
PARENT_SCOPE)
return()
endif()
if(NOT hash)
set(${_var}
"HEAD-HASH-NOTFOUND"
PARENT_SCOPE)
return()
endif()
execute_process(
COMMAND "${GIT_EXECUTABLE}" diff-index --quiet HEAD --
WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
RESULT_VARIABLE res
OUTPUT_VARIABLE out
ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE)
if(res EQUAL 0)
set(${_var}
"CLEAN"
PARENT_SCOPE)
else()
set(${_var}
"DIRTY"
PARENT_SCOPE)
endif()
endfunction()

View File

@@ -0,0 +1,43 @@
#
# Internal file for GetGitRevisionDescription.cmake
#
# Requires CMake 2.6 or newer (uses the 'function' command)
#
# Original Author:
# 2009-2010 Ryan Pavlik <rpavlik@iastate.edu> <abiryan@ryand.net>
# http://academic.cleardefinition.com
# Iowa State University HCI Graduate Program/VRAC
#
# Copyright 2009-2012, Iowa State University
# Copyright 2011-2015, Contributors
# Distributed under the Boost Software License, Version 1.0.
# (See accompanying file LICENSE_1_0.txt or copy at
# http://www.boost.org/LICENSE_1_0.txt)
# SPDX-License-Identifier: BSL-1.0
set(HEAD_HASH)
file(READ "@HEAD_FILE@" HEAD_CONTENTS LIMIT 1024)
string(STRIP "${HEAD_CONTENTS}" HEAD_CONTENTS)
if(HEAD_CONTENTS MATCHES "ref")
# named branch
string(REPLACE "ref: " "" HEAD_REF "${HEAD_CONTENTS}")
if(EXISTS "@GIT_DIR@/${HEAD_REF}")
configure_file("@GIT_DIR@/${HEAD_REF}" "@GIT_DATA@/head-ref" COPYONLY)
else()
configure_file("@GIT_DIR@/packed-refs" "@GIT_DATA@/packed-refs" COPYONLY)
file(READ "@GIT_DATA@/packed-refs" PACKED_REFS)
if(${PACKED_REFS} MATCHES "([0-9a-z]*) ${HEAD_REF}")
set(HEAD_HASH "${CMAKE_MATCH_1}")
endif()
endif()
else()
# detached HEAD
configure_file("@GIT_DIR@/HEAD" "@GIT_DATA@/head-ref" COPYONLY)
endif()
if(NOT HEAD_HASH)
file(READ "@GIT_DATA@/head-ref" HEAD_HASH LIMIT 1024)
string(STRIP "${HEAD_HASH}" HEAD_HASH)
endif()

View File

@@ -1,19 +0,0 @@
#include <algorithm>
template<typename COMP>
class foo
{
public:
foo(int a, COMP&& b)
: m_a(a), m_b(std::move(b)) {}
int m_a;
COMP m_b;
};
void bar(const int& b)
{
int c = 1;
auto f = new foo(c, [tag = c, b](const int& x)
{ x < b; });
}

1480
config/config.guess vendored

File diff suppressed because it is too large Load Diff

1801
config/config.sub vendored

File diff suppressed because it is too large Load Diff

View File

@@ -1,518 +0,0 @@
#!/bin/sh
# install - install a program, script, or datafile
scriptversion=2018-03-11.20; # UTC
# This originates from X11R5 (mit/util/scripts/install.sh), which was
# later released in X11R6 (xc/config/util/install.sh) with the
# following copyright and license.
#
# Copyright (C) 1994 X Consortium
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to
# deal in the Software without restriction, including without limitation the
# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
# sell copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC-
# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
# Except as contained in this notice, the name of the X Consortium shall not
# be used in advertising or otherwise to promote the sale, use or other deal-
# ings in this Software without prior written authorization from the X Consor-
# tium.
#
#
# FSF changes to this file are in the public domain.
#
# Calling this script install-sh is preferred over install.sh, to prevent
# 'make' implicit rules from creating a file called install from it
# when there is no Makefile.
#
# This script is compatible with the BSD install script, but was written
# from scratch.
tab=' '
nl='
'
IFS=" $tab$nl"
# Set DOITPROG to "echo" to test this script.
doit=${DOITPROG-}
doit_exec=${doit:-exec}
# Put in absolute file names if you don't have them in your path;
# or use environment vars.
chgrpprog=${CHGRPPROG-chgrp}
chmodprog=${CHMODPROG-chmod}
chownprog=${CHOWNPROG-chown}
cmpprog=${CMPPROG-cmp}
cpprog=${CPPROG-cp}
mkdirprog=${MKDIRPROG-mkdir}
mvprog=${MVPROG-mv}
rmprog=${RMPROG-rm}
stripprog=${STRIPPROG-strip}
posix_mkdir=
# Desired mode of installed file.
mode=0755
chgrpcmd=
chmodcmd=$chmodprog
chowncmd=
mvcmd=$mvprog
rmcmd="$rmprog -f"
stripcmd=
src=
dst=
dir_arg=
dst_arg=
copy_on_change=false
is_target_a_directory=possibly
usage="\
Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE
or: $0 [OPTION]... SRCFILES... DIRECTORY
or: $0 [OPTION]... -t DIRECTORY SRCFILES...
or: $0 [OPTION]... -d DIRECTORIES...
In the 1st form, copy SRCFILE to DSTFILE.
In the 2nd and 3rd, copy all SRCFILES to DIRECTORY.
In the 4th, create DIRECTORIES.
Options:
--help display this help and exit.
--version display version info and exit.
-c (ignored)
-C install only if different (preserve the last data modification time)
-d create directories instead of installing files.
-g GROUP $chgrpprog installed files to GROUP.
-m MODE $chmodprog installed files to MODE.
-o USER $chownprog installed files to USER.
-s $stripprog installed files.
-t DIRECTORY install into DIRECTORY.
-T report an error if DSTFILE is a directory.
Environment variables override the default commands:
CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG
RMPROG STRIPPROG
"
while test $# -ne 0; do
case $1 in
-c) ;;
-C) copy_on_change=true;;
-d) dir_arg=true;;
-g) chgrpcmd="$chgrpprog $2"
shift;;
--help) echo "$usage"; exit $?;;
-m) mode=$2
case $mode in
*' '* | *"$tab"* | *"$nl"* | *'*'* | *'?'* | *'['*)
echo "$0: invalid mode: $mode" >&2
exit 1;;
esac
shift;;
-o) chowncmd="$chownprog $2"
shift;;
-s) stripcmd=$stripprog;;
-t)
is_target_a_directory=always
dst_arg=$2
# Protect names problematic for 'test' and other utilities.
case $dst_arg in
-* | [=\(\)!]) dst_arg=./$dst_arg;;
esac
shift;;
-T) is_target_a_directory=never;;
--version) echo "$0 $scriptversion"; exit $?;;
--) shift
break;;
-*) echo "$0: invalid option: $1" >&2
exit 1;;
*) break;;
esac
shift
done
# We allow the use of options -d and -T together, by making -d
# take the precedence; this is for compatibility with GNU install.
if test -n "$dir_arg"; then
if test -n "$dst_arg"; then
echo "$0: target directory not allowed when installing a directory." >&2
exit 1
fi
fi
if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then
# When -d is used, all remaining arguments are directories to create.
# When -t is used, the destination is already specified.
# Otherwise, the last argument is the destination. Remove it from $@.
for arg
do
if test -n "$dst_arg"; then
# $@ is not empty: it contains at least $arg.
set fnord "$@" "$dst_arg"
shift # fnord
fi
shift # arg
dst_arg=$arg
# Protect names problematic for 'test' and other utilities.
case $dst_arg in
-* | [=\(\)!]) dst_arg=./$dst_arg;;
esac
done
fi
if test $# -eq 0; then
if test -z "$dir_arg"; then
echo "$0: no input file specified." >&2
exit 1
fi
# It's OK to call 'install-sh -d' without argument.
# This can happen when creating conditional directories.
exit 0
fi
if test -z "$dir_arg"; then
if test $# -gt 1 || test "$is_target_a_directory" = always; then
if test ! -d "$dst_arg"; then
echo "$0: $dst_arg: Is not a directory." >&2
exit 1
fi
fi
fi
if test -z "$dir_arg"; then
do_exit='(exit $ret); exit $ret'
trap "ret=129; $do_exit" 1
trap "ret=130; $do_exit" 2
trap "ret=141; $do_exit" 13
trap "ret=143; $do_exit" 15
# Set umask so as not to create temps with too-generous modes.
# However, 'strip' requires both read and write access to temps.
case $mode in
# Optimize common cases.
*644) cp_umask=133;;
*755) cp_umask=22;;
*[0-7])
if test -z "$stripcmd"; then
u_plus_rw=
else
u_plus_rw='% 200'
fi
cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;;
*)
if test -z "$stripcmd"; then
u_plus_rw=
else
u_plus_rw=,u+rw
fi
cp_umask=$mode$u_plus_rw;;
esac
fi
for src
do
# Protect names problematic for 'test' and other utilities.
case $src in
-* | [=\(\)!]) src=./$src;;
esac
if test -n "$dir_arg"; then
dst=$src
dstdir=$dst
test -d "$dstdir"
dstdir_status=$?
else
# Waiting for this to be detected by the "$cpprog $src $dsttmp" command
# might cause directories to be created, which would be especially bad
# if $src (and thus $dsttmp) contains '*'.
if test ! -f "$src" && test ! -d "$src"; then
echo "$0: $src does not exist." >&2
exit 1
fi
if test -z "$dst_arg"; then
echo "$0: no destination specified." >&2
exit 1
fi
dst=$dst_arg
# If destination is a directory, append the input filename.
if test -d "$dst"; then
if test "$is_target_a_directory" = never; then
echo "$0: $dst_arg: Is a directory" >&2
exit 1
fi
dstdir=$dst
dstbase=`basename "$src"`
case $dst in
*/) dst=$dst$dstbase;;
*) dst=$dst/$dstbase;;
esac
dstdir_status=0
else
dstdir=`dirname "$dst"`
test -d "$dstdir"
dstdir_status=$?
fi
fi
case $dstdir in
*/) dstdirslash=$dstdir;;
*) dstdirslash=$dstdir/;;
esac
obsolete_mkdir_used=false
if test $dstdir_status != 0; then
case $posix_mkdir in
'')
# Create intermediate dirs using mode 755 as modified by the umask.
# This is like FreeBSD 'install' as of 1997-10-28.
umask=`umask`
case $stripcmd.$umask in
# Optimize common cases.
*[2367][2367]) mkdir_umask=$umask;;
.*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;;
*[0-7])
mkdir_umask=`expr $umask + 22 \
- $umask % 100 % 40 + $umask % 20 \
- $umask % 10 % 4 + $umask % 2
`;;
*) mkdir_umask=$umask,go-w;;
esac
# With -d, create the new directory with the user-specified mode.
# Otherwise, rely on $mkdir_umask.
if test -n "$dir_arg"; then
mkdir_mode=-m$mode
else
mkdir_mode=
fi
posix_mkdir=false
case $umask in
*[123567][0-7][0-7])
# POSIX mkdir -p sets u+wx bits regardless of umask, which
# is incompatible with FreeBSD 'install' when (umask & 300) != 0.
;;
*)
# Note that $RANDOM variable is not portable (e.g. dash); Use it
# here however when possible just to lower collision chance.
tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$
trap 'ret=$?; rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir" 2>/dev/null; exit $ret' 0
# Because "mkdir -p" follows existing symlinks and we likely work
# directly in world-writeable /tmp, make sure that the '$tmpdir'
# directory is successfully created first before we actually test
# 'mkdir -p' feature.
if (umask $mkdir_umask &&
$mkdirprog $mkdir_mode "$tmpdir" &&
exec $mkdirprog $mkdir_mode -p -- "$tmpdir/a/b") >/dev/null 2>&1
then
if test -z "$dir_arg" || {
# Check for POSIX incompatibilities with -m.
# HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or
# other-writable bit of parent directory when it shouldn't.
# FreeBSD 6.1 mkdir -m -p sets mode of existing directory.
test_tmpdir="$tmpdir/a"
ls_ld_tmpdir=`ls -ld "$test_tmpdir"`
case $ls_ld_tmpdir in
d????-?r-*) different_mode=700;;
d????-?--*) different_mode=755;;
*) false;;
esac &&
$mkdirprog -m$different_mode -p -- "$test_tmpdir" && {
ls_ld_tmpdir_1=`ls -ld "$test_tmpdir"`
test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1"
}
}
then posix_mkdir=:
fi
rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir"
else
# Remove any dirs left behind by ancient mkdir implementations.
rmdir ./$mkdir_mode ./-p ./-- "$tmpdir" 2>/dev/null
fi
trap '' 0;;
esac;;
esac
if
$posix_mkdir && (
umask $mkdir_umask &&
$doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir"
)
then :
else
# The umask is ridiculous, or mkdir does not conform to POSIX,
# or it failed possibly due to a race condition. Create the
# directory the slow way, step by step, checking for races as we go.
case $dstdir in
/*) prefix='/';;
[-=\(\)!]*) prefix='./';;
*) prefix='';;
esac
oIFS=$IFS
IFS=/
set -f
set fnord $dstdir
shift
set +f
IFS=$oIFS
prefixes=
for d
do
test X"$d" = X && continue
prefix=$prefix$d
if test -d "$prefix"; then
prefixes=
else
if $posix_mkdir; then
(umask=$mkdir_umask &&
$doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break
# Don't fail if two instances are running concurrently.
test -d "$prefix" || exit 1
else
case $prefix in
*\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;;
*) qprefix=$prefix;;
esac
prefixes="$prefixes '$qprefix'"
fi
fi
prefix=$prefix/
done
if test -n "$prefixes"; then
# Don't fail if two instances are running concurrently.
(umask $mkdir_umask &&
eval "\$doit_exec \$mkdirprog $prefixes") ||
test -d "$dstdir" || exit 1
obsolete_mkdir_used=true
fi
fi
fi
if test -n "$dir_arg"; then
{ test -z "$chowncmd" || $doit $chowncmd "$dst"; } &&
{ test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } &&
{ test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false ||
test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1
else
# Make a couple of temp file names in the proper directory.
dsttmp=${dstdirslash}_inst.$$_
rmtmp=${dstdirslash}_rm.$$_
# Trap to clean up those temp files at exit.
trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0
# Copy the file name to the temp name.
(umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") &&
# and set any options; do chmod last to preserve setuid bits.
#
# If any of these fail, we abort the whole thing. If we want to
# ignore errors from any of these, just make sure not to ignore
# errors from the above "$doit $cpprog $src $dsttmp" command.
#
{ test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } &&
{ test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } &&
{ test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } &&
{ test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } &&
# If -C, don't bother to copy if it wouldn't change the file.
if $copy_on_change &&
old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` &&
new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` &&
set -f &&
set X $old && old=:$2:$4:$5:$6 &&
set X $new && new=:$2:$4:$5:$6 &&
set +f &&
test "$old" = "$new" &&
$cmpprog "$dst" "$dsttmp" >/dev/null 2>&1
then
rm -f "$dsttmp"
else
# Rename the file to the real destination.
$doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null ||
# The rename failed, perhaps because mv can't rename something else
# to itself, or perhaps because mv is so ancient that it does not
# support -f.
{
# Now remove or move aside any old file at destination location.
# We try this two ways since rm can't unlink itself on some
# systems and the destination file might be busy for other
# reasons. In this case, the final cleanup might fail but the new
# file should still install successfully.
{
test ! -f "$dst" ||
$doit $rmcmd -f "$dst" 2>/dev/null ||
{ $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null &&
{ $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; }
} ||
{ echo "$0: cannot unlink or rename $dst" >&2
(exit 1); exit 1
}
} &&
# Now rename the file to the real destination.
$doit $mvcmd "$dsttmp" "$dst"
}
fi || exit 1
trap '' 0
fi
done
# Local variables:
# eval: (add-hook 'before-save-hook 'time-stamp)
# time-stamp-start: "scriptversion="
# time-stamp-format: "%:y-%02m-%02d.%02H"
# time-stamp-time-zone: "UTC0"
# time-stamp-end: "; # UTC"
# End:

File diff suppressed because it is too large Load Diff

8394
config/m4/libtool.m4 vendored

File diff suppressed because it is too large Load Diff

437
config/m4/ltoptions.m4 vendored
View File

@@ -1,437 +0,0 @@
# Helper functions for option handling. -*- Autoconf -*-
#
# Copyright (C) 2004-2005, 2007-2009, 2011-2015 Free Software
# Foundation, Inc.
# Written by Gary V. Vaughan, 2004
#
# This file is free software; the Free Software Foundation gives
# unlimited permission to copy and/or distribute it, with or without
# modifications, as long as this notice is preserved.
# serial 8 ltoptions.m4
# This is to help aclocal find these macros, as it can't see m4_define.
AC_DEFUN([LTOPTIONS_VERSION], [m4_if([1])])
# _LT_MANGLE_OPTION(MACRO-NAME, OPTION-NAME)
# ------------------------------------------
m4_define([_LT_MANGLE_OPTION],
[[_LT_OPTION_]m4_bpatsubst($1__$2, [[^a-zA-Z0-9_]], [_])])
# _LT_SET_OPTION(MACRO-NAME, OPTION-NAME)
# ---------------------------------------
# Set option OPTION-NAME for macro MACRO-NAME, and if there is a
# matching handler defined, dispatch to it. Other OPTION-NAMEs are
# saved as a flag.
m4_define([_LT_SET_OPTION],
[m4_define(_LT_MANGLE_OPTION([$1], [$2]))dnl
m4_ifdef(_LT_MANGLE_DEFUN([$1], [$2]),
_LT_MANGLE_DEFUN([$1], [$2]),
[m4_warning([Unknown $1 option '$2'])])[]dnl
])
# _LT_IF_OPTION(MACRO-NAME, OPTION-NAME, IF-SET, [IF-NOT-SET])
# ------------------------------------------------------------
# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise.
m4_define([_LT_IF_OPTION],
[m4_ifdef(_LT_MANGLE_OPTION([$1], [$2]), [$3], [$4])])
# _LT_UNLESS_OPTIONS(MACRO-NAME, OPTION-LIST, IF-NOT-SET)
# -------------------------------------------------------
# Execute IF-NOT-SET unless all options in OPTION-LIST for MACRO-NAME
# are set.
m4_define([_LT_UNLESS_OPTIONS],
[m4_foreach([_LT_Option], m4_split(m4_normalize([$2])),
[m4_ifdef(_LT_MANGLE_OPTION([$1], _LT_Option),
[m4_define([$0_found])])])[]dnl
m4_ifdef([$0_found], [m4_undefine([$0_found])], [$3
])[]dnl
])
# _LT_SET_OPTIONS(MACRO-NAME, OPTION-LIST)
# ----------------------------------------
# OPTION-LIST is a space-separated list of Libtool options associated
# with MACRO-NAME. If any OPTION has a matching handler declared with
# LT_OPTION_DEFINE, dispatch to that macro; otherwise complain about
# the unknown option and exit.
m4_defun([_LT_SET_OPTIONS],
[# Set options
m4_foreach([_LT_Option], m4_split(m4_normalize([$2])),
[_LT_SET_OPTION([$1], _LT_Option)])
m4_if([$1],[LT_INIT],[
dnl
dnl Simply set some default values (i.e off) if boolean options were not
dnl specified:
_LT_UNLESS_OPTIONS([LT_INIT], [dlopen], [enable_dlopen=no
])
_LT_UNLESS_OPTIONS([LT_INIT], [win32-dll], [enable_win32_dll=no
])
dnl
dnl If no reference was made to various pairs of opposing options, then
dnl we run the default mode handler for the pair. For example, if neither
dnl 'shared' nor 'disable-shared' was passed, we enable building of shared
dnl archives by default:
_LT_UNLESS_OPTIONS([LT_INIT], [shared disable-shared], [_LT_ENABLE_SHARED])
_LT_UNLESS_OPTIONS([LT_INIT], [static disable-static], [_LT_ENABLE_STATIC])
_LT_UNLESS_OPTIONS([LT_INIT], [pic-only no-pic], [_LT_WITH_PIC])
_LT_UNLESS_OPTIONS([LT_INIT], [fast-install disable-fast-install],
[_LT_ENABLE_FAST_INSTALL])
_LT_UNLESS_OPTIONS([LT_INIT], [aix-soname=aix aix-soname=both aix-soname=svr4],
[_LT_WITH_AIX_SONAME([aix])])
])
])# _LT_SET_OPTIONS
## --------------------------------- ##
## Macros to handle LT_INIT options. ##
## --------------------------------- ##
# _LT_MANGLE_DEFUN(MACRO-NAME, OPTION-NAME)
# -----------------------------------------
m4_define([_LT_MANGLE_DEFUN],
[[_LT_OPTION_DEFUN_]m4_bpatsubst(m4_toupper([$1__$2]), [[^A-Z0-9_]], [_])])
# LT_OPTION_DEFINE(MACRO-NAME, OPTION-NAME, CODE)
# -----------------------------------------------
m4_define([LT_OPTION_DEFINE],
[m4_define(_LT_MANGLE_DEFUN([$1], [$2]), [$3])[]dnl
])# LT_OPTION_DEFINE
# dlopen
# ------
LT_OPTION_DEFINE([LT_INIT], [dlopen], [enable_dlopen=yes
])
AU_DEFUN([AC_LIBTOOL_DLOPEN],
[_LT_SET_OPTION([LT_INIT], [dlopen])
AC_DIAGNOSE([obsolete],
[$0: Remove this warning and the call to _LT_SET_OPTION when you
put the 'dlopen' option into LT_INIT's first parameter.])
])
dnl aclocal-1.4 backwards compatibility:
dnl AC_DEFUN([AC_LIBTOOL_DLOPEN], [])
# win32-dll
# ---------
# Declare package support for building win32 dll's.
LT_OPTION_DEFINE([LT_INIT], [win32-dll],
[enable_win32_dll=yes
case $host in
*-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-cegcc*)
AC_CHECK_TOOL(AS, as, false)
AC_CHECK_TOOL(DLLTOOL, dlltool, false)
AC_CHECK_TOOL(OBJDUMP, objdump, false)
;;
esac
test -z "$AS" && AS=as
_LT_DECL([], [AS], [1], [Assembler program])dnl
test -z "$DLLTOOL" && DLLTOOL=dlltool
_LT_DECL([], [DLLTOOL], [1], [DLL creation program])dnl
test -z "$OBJDUMP" && OBJDUMP=objdump
_LT_DECL([], [OBJDUMP], [1], [Object dumper program])dnl
])# win32-dll
AU_DEFUN([AC_LIBTOOL_WIN32_DLL],
[AC_REQUIRE([AC_CANONICAL_HOST])dnl
_LT_SET_OPTION([LT_INIT], [win32-dll])
AC_DIAGNOSE([obsolete],
[$0: Remove this warning and the call to _LT_SET_OPTION when you
put the 'win32-dll' option into LT_INIT's first parameter.])
])
dnl aclocal-1.4 backwards compatibility:
dnl AC_DEFUN([AC_LIBTOOL_WIN32_DLL], [])
# _LT_ENABLE_SHARED([DEFAULT])
# ----------------------------
# implement the --enable-shared flag, and supports the 'shared' and
# 'disable-shared' LT_INIT options.
# DEFAULT is either 'yes' or 'no'. If omitted, it defaults to 'yes'.
m4_define([_LT_ENABLE_SHARED],
[m4_define([_LT_ENABLE_SHARED_DEFAULT], [m4_if($1, no, no, yes)])dnl
AC_ARG_ENABLE([shared],
[AS_HELP_STRING([--enable-shared@<:@=PKGS@:>@],
[build shared libraries @<:@default=]_LT_ENABLE_SHARED_DEFAULT[@:>@])],
[p=${PACKAGE-default}
case $enableval in
yes) enable_shared=yes ;;
no) enable_shared=no ;;
*)
enable_shared=no
# Look at the argument we got. We use all the common list separators.
lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR,
for pkg in $enableval; do
IFS=$lt_save_ifs
if test "X$pkg" = "X$p"; then
enable_shared=yes
fi
done
IFS=$lt_save_ifs
;;
esac],
[enable_shared=]_LT_ENABLE_SHARED_DEFAULT)
_LT_DECL([build_libtool_libs], [enable_shared], [0],
[Whether or not to build shared libraries])
])# _LT_ENABLE_SHARED
LT_OPTION_DEFINE([LT_INIT], [shared], [_LT_ENABLE_SHARED([yes])])
LT_OPTION_DEFINE([LT_INIT], [disable-shared], [_LT_ENABLE_SHARED([no])])
# Old names:
AC_DEFUN([AC_ENABLE_SHARED],
[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[shared])
])
AC_DEFUN([AC_DISABLE_SHARED],
[_LT_SET_OPTION([LT_INIT], [disable-shared])
])
AU_DEFUN([AM_ENABLE_SHARED], [AC_ENABLE_SHARED($@)])
AU_DEFUN([AM_DISABLE_SHARED], [AC_DISABLE_SHARED($@)])
dnl aclocal-1.4 backwards compatibility:
dnl AC_DEFUN([AM_ENABLE_SHARED], [])
dnl AC_DEFUN([AM_DISABLE_SHARED], [])
# _LT_ENABLE_STATIC([DEFAULT])
# ----------------------------
# implement the --enable-static flag, and support the 'static' and
# 'disable-static' LT_INIT options.
# DEFAULT is either 'yes' or 'no'. If omitted, it defaults to 'yes'.
m4_define([_LT_ENABLE_STATIC],
[m4_define([_LT_ENABLE_STATIC_DEFAULT], [m4_if($1, no, no, yes)])dnl
AC_ARG_ENABLE([static],
[AS_HELP_STRING([--enable-static@<:@=PKGS@:>@],
[build static libraries @<:@default=]_LT_ENABLE_STATIC_DEFAULT[@:>@])],
[p=${PACKAGE-default}
case $enableval in
yes) enable_static=yes ;;
no) enable_static=no ;;
*)
enable_static=no
# Look at the argument we got. We use all the common list separators.
lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR,
for pkg in $enableval; do
IFS=$lt_save_ifs
if test "X$pkg" = "X$p"; then
enable_static=yes
fi
done
IFS=$lt_save_ifs
;;
esac],
[enable_static=]_LT_ENABLE_STATIC_DEFAULT)
_LT_DECL([build_old_libs], [enable_static], [0],
[Whether or not to build static libraries])
])# _LT_ENABLE_STATIC
LT_OPTION_DEFINE([LT_INIT], [static], [_LT_ENABLE_STATIC([yes])])
LT_OPTION_DEFINE([LT_INIT], [disable-static], [_LT_ENABLE_STATIC([no])])
# Old names:
AC_DEFUN([AC_ENABLE_STATIC],
[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[static])
])
AC_DEFUN([AC_DISABLE_STATIC],
[_LT_SET_OPTION([LT_INIT], [disable-static])
])
AU_DEFUN([AM_ENABLE_STATIC], [AC_ENABLE_STATIC($@)])
AU_DEFUN([AM_DISABLE_STATIC], [AC_DISABLE_STATIC($@)])
dnl aclocal-1.4 backwards compatibility:
dnl AC_DEFUN([AM_ENABLE_STATIC], [])
dnl AC_DEFUN([AM_DISABLE_STATIC], [])
# _LT_ENABLE_FAST_INSTALL([DEFAULT])
# ----------------------------------
# implement the --enable-fast-install flag, and support the 'fast-install'
# and 'disable-fast-install' LT_INIT options.
# DEFAULT is either 'yes' or 'no'. If omitted, it defaults to 'yes'.
m4_define([_LT_ENABLE_FAST_INSTALL],
[m4_define([_LT_ENABLE_FAST_INSTALL_DEFAULT], [m4_if($1, no, no, yes)])dnl
AC_ARG_ENABLE([fast-install],
[AS_HELP_STRING([--enable-fast-install@<:@=PKGS@:>@],
[optimize for fast installation @<:@default=]_LT_ENABLE_FAST_INSTALL_DEFAULT[@:>@])],
[p=${PACKAGE-default}
case $enableval in
yes) enable_fast_install=yes ;;
no) enable_fast_install=no ;;
*)
enable_fast_install=no
# Look at the argument we got. We use all the common list separators.
lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR,
for pkg in $enableval; do
IFS=$lt_save_ifs
if test "X$pkg" = "X$p"; then
enable_fast_install=yes
fi
done
IFS=$lt_save_ifs
;;
esac],
[enable_fast_install=]_LT_ENABLE_FAST_INSTALL_DEFAULT)
_LT_DECL([fast_install], [enable_fast_install], [0],
[Whether or not to optimize for fast installation])dnl
])# _LT_ENABLE_FAST_INSTALL
LT_OPTION_DEFINE([LT_INIT], [fast-install], [_LT_ENABLE_FAST_INSTALL([yes])])
LT_OPTION_DEFINE([LT_INIT], [disable-fast-install], [_LT_ENABLE_FAST_INSTALL([no])])
# Old names:
AU_DEFUN([AC_ENABLE_FAST_INSTALL],
[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[fast-install])
AC_DIAGNOSE([obsolete],
[$0: Remove this warning and the call to _LT_SET_OPTION when you put
the 'fast-install' option into LT_INIT's first parameter.])
])
AU_DEFUN([AC_DISABLE_FAST_INSTALL],
[_LT_SET_OPTION([LT_INIT], [disable-fast-install])
AC_DIAGNOSE([obsolete],
[$0: Remove this warning and the call to _LT_SET_OPTION when you put
the 'disable-fast-install' option into LT_INIT's first parameter.])
])
dnl aclocal-1.4 backwards compatibility:
dnl AC_DEFUN([AC_ENABLE_FAST_INSTALL], [])
dnl AC_DEFUN([AM_DISABLE_FAST_INSTALL], [])
# _LT_WITH_AIX_SONAME([DEFAULT])
# ----------------------------------
# implement the --with-aix-soname flag, and support the `aix-soname=aix'
# and `aix-soname=both' and `aix-soname=svr4' LT_INIT options. DEFAULT
# is either `aix', `both' or `svr4'. If omitted, it defaults to `aix'.
m4_define([_LT_WITH_AIX_SONAME],
[m4_define([_LT_WITH_AIX_SONAME_DEFAULT], [m4_if($1, svr4, svr4, m4_if($1, both, both, aix))])dnl
shared_archive_member_spec=
case $host,$enable_shared in
power*-*-aix[[5-9]]*,yes)
AC_MSG_CHECKING([which variant of shared library versioning to provide])
AC_ARG_WITH([aix-soname],
[AS_HELP_STRING([--with-aix-soname=aix|svr4|both],
[shared library versioning (aka "SONAME") variant to provide on AIX, @<:@default=]_LT_WITH_AIX_SONAME_DEFAULT[@:>@.])],
[case $withval in
aix|svr4|both)
;;
*)
AC_MSG_ERROR([Unknown argument to --with-aix-soname])
;;
esac
lt_cv_with_aix_soname=$with_aix_soname],
[AC_CACHE_VAL([lt_cv_with_aix_soname],
[lt_cv_with_aix_soname=]_LT_WITH_AIX_SONAME_DEFAULT)
with_aix_soname=$lt_cv_with_aix_soname])
AC_MSG_RESULT([$with_aix_soname])
if test aix != "$with_aix_soname"; then
# For the AIX way of multilib, we name the shared archive member
# based on the bitwidth used, traditionally 'shr.o' or 'shr_64.o',
# and 'shr.imp' or 'shr_64.imp', respectively, for the Import File.
# Even when GNU compilers ignore OBJECT_MODE but need '-maix64' flag,
# the AIX toolchain works better with OBJECT_MODE set (default 32).
if test 64 = "${OBJECT_MODE-32}"; then
shared_archive_member_spec=shr_64
else
shared_archive_member_spec=shr
fi
fi
;;
*)
with_aix_soname=aix
;;
esac
_LT_DECL([], [shared_archive_member_spec], [0],
[Shared archive member basename, for filename based shared library versioning on AIX])dnl
])# _LT_WITH_AIX_SONAME
LT_OPTION_DEFINE([LT_INIT], [aix-soname=aix], [_LT_WITH_AIX_SONAME([aix])])
LT_OPTION_DEFINE([LT_INIT], [aix-soname=both], [_LT_WITH_AIX_SONAME([both])])
LT_OPTION_DEFINE([LT_INIT], [aix-soname=svr4], [_LT_WITH_AIX_SONAME([svr4])])
# _LT_WITH_PIC([MODE])
# --------------------
# implement the --with-pic flag, and support the 'pic-only' and 'no-pic'
# LT_INIT options.
# MODE is either 'yes' or 'no'. If omitted, it defaults to 'both'.
m4_define([_LT_WITH_PIC],
[AC_ARG_WITH([pic],
[AS_HELP_STRING([--with-pic@<:@=PKGS@:>@],
[try to use only PIC/non-PIC objects @<:@default=use both@:>@])],
[lt_p=${PACKAGE-default}
case $withval in
yes|no) pic_mode=$withval ;;
*)
pic_mode=default
# Look at the argument we got. We use all the common list separators.
lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR,
for lt_pkg in $withval; do
IFS=$lt_save_ifs
if test "X$lt_pkg" = "X$lt_p"; then
pic_mode=yes
fi
done
IFS=$lt_save_ifs
;;
esac],
[pic_mode=m4_default([$1], [default])])
_LT_DECL([], [pic_mode], [0], [What type of objects to build])dnl
])# _LT_WITH_PIC
LT_OPTION_DEFINE([LT_INIT], [pic-only], [_LT_WITH_PIC([yes])])
LT_OPTION_DEFINE([LT_INIT], [no-pic], [_LT_WITH_PIC([no])])
# Old name:
AU_DEFUN([AC_LIBTOOL_PICMODE],
[_LT_SET_OPTION([LT_INIT], [pic-only])
AC_DIAGNOSE([obsolete],
[$0: Remove this warning and the call to _LT_SET_OPTION when you
put the 'pic-only' option into LT_INIT's first parameter.])
])
dnl aclocal-1.4 backwards compatibility:
dnl AC_DEFUN([AC_LIBTOOL_PICMODE], [])
## ----------------- ##
## LTDL_INIT Options ##
## ----------------- ##
m4_define([_LTDL_MODE], [])
LT_OPTION_DEFINE([LTDL_INIT], [nonrecursive],
[m4_define([_LTDL_MODE], [nonrecursive])])
LT_OPTION_DEFINE([LTDL_INIT], [recursive],
[m4_define([_LTDL_MODE], [recursive])])
LT_OPTION_DEFINE([LTDL_INIT], [subproject],
[m4_define([_LTDL_MODE], [subproject])])
m4_define([_LTDL_TYPE], [])
LT_OPTION_DEFINE([LTDL_INIT], [installable],
[m4_define([_LTDL_TYPE], [installable])])
LT_OPTION_DEFINE([LTDL_INIT], [convenience],
[m4_define([_LTDL_TYPE], [convenience])])

124
config/m4/ltsugar.m4 vendored
View File

@@ -1,124 +0,0 @@
# ltsugar.m4 -- libtool m4 base layer. -*-Autoconf-*-
#
# Copyright (C) 2004-2005, 2007-2008, 2011-2015 Free Software
# Foundation, Inc.
# Written by Gary V. Vaughan, 2004
#
# This file is free software; the Free Software Foundation gives
# unlimited permission to copy and/or distribute it, with or without
# modifications, as long as this notice is preserved.
# serial 6 ltsugar.m4
# This is to help aclocal find these macros, as it can't see m4_define.
AC_DEFUN([LTSUGAR_VERSION], [m4_if([0.1])])
# lt_join(SEP, ARG1, [ARG2...])
# -----------------------------
# Produce ARG1SEPARG2...SEPARGn, omitting [] arguments and their
# associated separator.
# Needed until we can rely on m4_join from Autoconf 2.62, since all earlier
# versions in m4sugar had bugs.
m4_define([lt_join],
[m4_if([$#], [1], [],
[$#], [2], [[$2]],
[m4_if([$2], [], [], [[$2]_])$0([$1], m4_shift(m4_shift($@)))])])
m4_define([_lt_join],
[m4_if([$#$2], [2], [],
[m4_if([$2], [], [], [[$1$2]])$0([$1], m4_shift(m4_shift($@)))])])
# lt_car(LIST)
# lt_cdr(LIST)
# ------------
# Manipulate m4 lists.
# These macros are necessary as long as will still need to support
# Autoconf-2.59, which quotes differently.
m4_define([lt_car], [[$1]])
m4_define([lt_cdr],
[m4_if([$#], 0, [m4_fatal([$0: cannot be called without arguments])],
[$#], 1, [],
[m4_dquote(m4_shift($@))])])
m4_define([lt_unquote], $1)
# lt_append(MACRO-NAME, STRING, [SEPARATOR])
# ------------------------------------------
# Redefine MACRO-NAME to hold its former content plus 'SEPARATOR''STRING'.
# Note that neither SEPARATOR nor STRING are expanded; they are appended
# to MACRO-NAME as is (leaving the expansion for when MACRO-NAME is invoked).
# No SEPARATOR is output if MACRO-NAME was previously undefined (different
# than defined and empty).
#
# This macro is needed until we can rely on Autoconf 2.62, since earlier
# versions of m4sugar mistakenly expanded SEPARATOR but not STRING.
m4_define([lt_append],
[m4_define([$1],
m4_ifdef([$1], [m4_defn([$1])[$3]])[$2])])
# lt_combine(SEP, PREFIX-LIST, INFIX, SUFFIX1, [SUFFIX2...])
# ----------------------------------------------------------
# Produce a SEP delimited list of all paired combinations of elements of
# PREFIX-LIST with SUFFIX1 through SUFFIXn. Each element of the list
# has the form PREFIXmINFIXSUFFIXn.
# Needed until we can rely on m4_combine added in Autoconf 2.62.
m4_define([lt_combine],
[m4_if(m4_eval([$# > 3]), [1],
[m4_pushdef([_Lt_sep], [m4_define([_Lt_sep], m4_defn([lt_car]))])]]dnl
[[m4_foreach([_Lt_prefix], [$2],
[m4_foreach([_Lt_suffix],
]m4_dquote(m4_dquote(m4_shift(m4_shift(m4_shift($@)))))[,
[_Lt_sep([$1])[]m4_defn([_Lt_prefix])[$3]m4_defn([_Lt_suffix])])])])])
# lt_if_append_uniq(MACRO-NAME, VARNAME, [SEPARATOR], [UNIQ], [NOT-UNIQ])
# -----------------------------------------------------------------------
# Iff MACRO-NAME does not yet contain VARNAME, then append it (delimited
# by SEPARATOR if supplied) and expand UNIQ, else NOT-UNIQ.
m4_define([lt_if_append_uniq],
[m4_ifdef([$1],
[m4_if(m4_index([$3]m4_defn([$1])[$3], [$3$2$3]), [-1],
[lt_append([$1], [$2], [$3])$4],
[$5])],
[lt_append([$1], [$2], [$3])$4])])
# lt_dict_add(DICT, KEY, VALUE)
# -----------------------------
m4_define([lt_dict_add],
[m4_define([$1($2)], [$3])])
# lt_dict_add_subkey(DICT, KEY, SUBKEY, VALUE)
# --------------------------------------------
m4_define([lt_dict_add_subkey],
[m4_define([$1($2:$3)], [$4])])
# lt_dict_fetch(DICT, KEY, [SUBKEY])
# ----------------------------------
m4_define([lt_dict_fetch],
[m4_ifval([$3],
m4_ifdef([$1($2:$3)], [m4_defn([$1($2:$3)])]),
m4_ifdef([$1($2)], [m4_defn([$1($2)])]))])
# lt_if_dict_fetch(DICT, KEY, [SUBKEY], VALUE, IF-TRUE, [IF-FALSE])
# -----------------------------------------------------------------
m4_define([lt_if_dict_fetch],
[m4_if(lt_dict_fetch([$1], [$2], [$3]), [$4],
[$5],
[$6])])
# lt_dict_filter(DICT, [SUBKEY], VALUE, [SEPARATOR], KEY, [...])
# --------------------------------------------------------------
m4_define([lt_dict_filter],
[m4_if([$5], [], [],
[lt_join(m4_quote(m4_default([$4], [[, ]])),
lt_unquote(m4_split(m4_normalize(m4_foreach(_Lt_key, lt_car([m4_shiftn(4, $@)]),
[lt_if_dict_fetch([$1], _Lt_key, [$2], [$3], [_Lt_key ])])))))])[]dnl
])

View File

@@ -1,23 +0,0 @@
# ltversion.m4 -- version numbers -*- Autoconf -*-
#
# Copyright (C) 2004, 2011-2015 Free Software Foundation, Inc.
# Written by Scott James Remnant, 2004
#
# This file is free software; the Free Software Foundation gives
# unlimited permission to copy and/or distribute it, with or without
# modifications, as long as this notice is preserved.
# @configure_input@
# serial 4179 ltversion.m4
# This file is part of GNU Libtool
m4_define([LT_PACKAGE_VERSION], [2.4.6])
m4_define([LT_PACKAGE_REVISION], [2.4.6])
AC_DEFUN([LTVERSION_VERSION],
[macro_version='2.4.6'
macro_revision='2.4.6'
_LT_DECL(, macro_version, 0, [Which release of libtool.m4 was used?])
_LT_DECL(, macro_revision, 0)
])

View File

@@ -1,99 +0,0 @@
# lt~obsolete.m4 -- aclocal satisfying obsolete definitions. -*-Autoconf-*-
#
# Copyright (C) 2004-2005, 2007, 2009, 2011-2015 Free Software
# Foundation, Inc.
# Written by Scott James Remnant, 2004.
#
# This file is free software; the Free Software Foundation gives
# unlimited permission to copy and/or distribute it, with or without
# modifications, as long as this notice is preserved.
# serial 5 lt~obsolete.m4
# These exist entirely to fool aclocal when bootstrapping libtool.
#
# In the past libtool.m4 has provided macros via AC_DEFUN (or AU_DEFUN),
# which have later been changed to m4_define as they aren't part of the
# exported API, or moved to Autoconf or Automake where they belong.
#
# The trouble is, aclocal is a bit thick. It'll see the old AC_DEFUN
# in /usr/share/aclocal/libtool.m4 and remember it, then when it sees us
# using a macro with the same name in our local m4/libtool.m4 it'll
# pull the old libtool.m4 in (it doesn't see our shiny new m4_define
# and doesn't know about Autoconf macros at all.)
#
# So we provide this file, which has a silly filename so it's always
# included after everything else. This provides aclocal with the
# AC_DEFUNs it wants, but when m4 processes it, it doesn't do anything
# because those macros already exist, or will be overwritten later.
# We use AC_DEFUN over AU_DEFUN for compatibility with aclocal-1.6.
#
# Anytime we withdraw an AC_DEFUN or AU_DEFUN, remember to add it here.
# Yes, that means every name once taken will need to remain here until
# we give up compatibility with versions before 1.7, at which point
# we need to keep only those names which we still refer to.
# This is to help aclocal find these macros, as it can't see m4_define.
AC_DEFUN([LTOBSOLETE_VERSION], [m4_if([1])])
m4_ifndef([AC_LIBTOOL_LINKER_OPTION], [AC_DEFUN([AC_LIBTOOL_LINKER_OPTION])])
m4_ifndef([AC_PROG_EGREP], [AC_DEFUN([AC_PROG_EGREP])])
m4_ifndef([_LT_AC_PROG_ECHO_BACKSLASH], [AC_DEFUN([_LT_AC_PROG_ECHO_BACKSLASH])])
m4_ifndef([_LT_AC_SHELL_INIT], [AC_DEFUN([_LT_AC_SHELL_INIT])])
m4_ifndef([_LT_AC_SYS_LIBPATH_AIX], [AC_DEFUN([_LT_AC_SYS_LIBPATH_AIX])])
m4_ifndef([_LT_PROG_LTMAIN], [AC_DEFUN([_LT_PROG_LTMAIN])])
m4_ifndef([_LT_AC_TAGVAR], [AC_DEFUN([_LT_AC_TAGVAR])])
m4_ifndef([AC_LTDL_ENABLE_INSTALL], [AC_DEFUN([AC_LTDL_ENABLE_INSTALL])])
m4_ifndef([AC_LTDL_PREOPEN], [AC_DEFUN([AC_LTDL_PREOPEN])])
m4_ifndef([_LT_AC_SYS_COMPILER], [AC_DEFUN([_LT_AC_SYS_COMPILER])])
m4_ifndef([_LT_AC_LOCK], [AC_DEFUN([_LT_AC_LOCK])])
m4_ifndef([AC_LIBTOOL_SYS_OLD_ARCHIVE], [AC_DEFUN([AC_LIBTOOL_SYS_OLD_ARCHIVE])])
m4_ifndef([_LT_AC_TRY_DLOPEN_SELF], [AC_DEFUN([_LT_AC_TRY_DLOPEN_SELF])])
m4_ifndef([AC_LIBTOOL_PROG_CC_C_O], [AC_DEFUN([AC_LIBTOOL_PROG_CC_C_O])])
m4_ifndef([AC_LIBTOOL_SYS_HARD_LINK_LOCKS], [AC_DEFUN([AC_LIBTOOL_SYS_HARD_LINK_LOCKS])])
m4_ifndef([AC_LIBTOOL_OBJDIR], [AC_DEFUN([AC_LIBTOOL_OBJDIR])])
m4_ifndef([AC_LTDL_OBJDIR], [AC_DEFUN([AC_LTDL_OBJDIR])])
m4_ifndef([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH], [AC_DEFUN([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH])])
m4_ifndef([AC_LIBTOOL_SYS_LIB_STRIP], [AC_DEFUN([AC_LIBTOOL_SYS_LIB_STRIP])])
m4_ifndef([AC_PATH_MAGIC], [AC_DEFUN([AC_PATH_MAGIC])])
m4_ifndef([AC_PROG_LD_GNU], [AC_DEFUN([AC_PROG_LD_GNU])])
m4_ifndef([AC_PROG_LD_RELOAD_FLAG], [AC_DEFUN([AC_PROG_LD_RELOAD_FLAG])])
m4_ifndef([AC_DEPLIBS_CHECK_METHOD], [AC_DEFUN([AC_DEPLIBS_CHECK_METHOD])])
m4_ifndef([AC_LIBTOOL_PROG_COMPILER_NO_RTTI], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_NO_RTTI])])
m4_ifndef([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE], [AC_DEFUN([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE])])
m4_ifndef([AC_LIBTOOL_PROG_COMPILER_PIC], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_PIC])])
m4_ifndef([AC_LIBTOOL_PROG_LD_SHLIBS], [AC_DEFUN([AC_LIBTOOL_PROG_LD_SHLIBS])])
m4_ifndef([AC_LIBTOOL_POSTDEP_PREDEP], [AC_DEFUN([AC_LIBTOOL_POSTDEP_PREDEP])])
m4_ifndef([LT_AC_PROG_EGREP], [AC_DEFUN([LT_AC_PROG_EGREP])])
m4_ifndef([LT_AC_PROG_SED], [AC_DEFUN([LT_AC_PROG_SED])])
m4_ifndef([_LT_CC_BASENAME], [AC_DEFUN([_LT_CC_BASENAME])])
m4_ifndef([_LT_COMPILER_BOILERPLATE], [AC_DEFUN([_LT_COMPILER_BOILERPLATE])])
m4_ifndef([_LT_LINKER_BOILERPLATE], [AC_DEFUN([_LT_LINKER_BOILERPLATE])])
m4_ifndef([_AC_PROG_LIBTOOL], [AC_DEFUN([_AC_PROG_LIBTOOL])])
m4_ifndef([AC_LIBTOOL_SETUP], [AC_DEFUN([AC_LIBTOOL_SETUP])])
m4_ifndef([_LT_AC_CHECK_DLFCN], [AC_DEFUN([_LT_AC_CHECK_DLFCN])])
m4_ifndef([AC_LIBTOOL_SYS_DYNAMIC_LINKER], [AC_DEFUN([AC_LIBTOOL_SYS_DYNAMIC_LINKER])])
m4_ifndef([_LT_AC_TAGCONFIG], [AC_DEFUN([_LT_AC_TAGCONFIG])])
m4_ifndef([AC_DISABLE_FAST_INSTALL], [AC_DEFUN([AC_DISABLE_FAST_INSTALL])])
m4_ifndef([_LT_AC_LANG_CXX], [AC_DEFUN([_LT_AC_LANG_CXX])])
m4_ifndef([_LT_AC_LANG_F77], [AC_DEFUN([_LT_AC_LANG_F77])])
m4_ifndef([_LT_AC_LANG_GCJ], [AC_DEFUN([_LT_AC_LANG_GCJ])])
m4_ifndef([AC_LIBTOOL_LANG_C_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_C_CONFIG])])
m4_ifndef([_LT_AC_LANG_C_CONFIG], [AC_DEFUN([_LT_AC_LANG_C_CONFIG])])
m4_ifndef([AC_LIBTOOL_LANG_CXX_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_CXX_CONFIG])])
m4_ifndef([_LT_AC_LANG_CXX_CONFIG], [AC_DEFUN([_LT_AC_LANG_CXX_CONFIG])])
m4_ifndef([AC_LIBTOOL_LANG_F77_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_F77_CONFIG])])
m4_ifndef([_LT_AC_LANG_F77_CONFIG], [AC_DEFUN([_LT_AC_LANG_F77_CONFIG])])
m4_ifndef([AC_LIBTOOL_LANG_GCJ_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_GCJ_CONFIG])])
m4_ifndef([_LT_AC_LANG_GCJ_CONFIG], [AC_DEFUN([_LT_AC_LANG_GCJ_CONFIG])])
m4_ifndef([AC_LIBTOOL_LANG_RC_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_RC_CONFIG])])
m4_ifndef([_LT_AC_LANG_RC_CONFIG], [AC_DEFUN([_LT_AC_LANG_RC_CONFIG])])
m4_ifndef([AC_LIBTOOL_CONFIG], [AC_DEFUN([AC_LIBTOOL_CONFIG])])
m4_ifndef([_LT_AC_FILE_LTDLL_C], [AC_DEFUN([_LT_AC_FILE_LTDLL_C])])
m4_ifndef([_LT_REQUIRED_DARWIN_CHECKS], [AC_DEFUN([_LT_REQUIRED_DARWIN_CHECKS])])
m4_ifndef([_LT_AC_PROG_CXXCPP], [AC_DEFUN([_LT_AC_PROG_CXXCPP])])
m4_ifndef([_LT_PREPARE_SED_QUOTE_VARS], [AC_DEFUN([_LT_PREPARE_SED_QUOTE_VARS])])
m4_ifndef([_LT_PROG_ECHO_BACKSLASH], [AC_DEFUN([_LT_PROG_ECHO_BACKSLASH])])
m4_ifndef([_LT_PROG_F77], [AC_DEFUN([_LT_PROG_F77])])
m4_ifndef([_LT_PROG_FC], [AC_DEFUN([_LT_PROG_FC])])
m4_ifndef([_LT_PROG_CXX], [AC_DEFUN([_LT_PROG_CXX])])

19493
configure vendored

File diff suppressed because it is too large Load Diff

View File

@@ -1,113 +0,0 @@
AC_PREREQ([2.69])
AC_INIT([libcifpp], 1.0, [m.hekkelman@nki.nl])
dnl Switch to a C++ compiler, and check if it works.
AC_LANG(C++)
AX_CXX_COMPILE_STDCXX_17([noext])
AX_CHECK_COMPILE_FLAG([-fstandalone-debug], [ CXXFLAGS="$CXXFLAGS -fstandalone-debug" ], , [-Werror])
AC_CONFIG_SRCDIR([src/Cif++.cpp])
AC_CONFIG_AUX_DIR(config)
AC_CONFIG_MACRO_DIR([config/m4])
AC_CONFIG_HEADERS([include/cif++/Config.hpp])
AC_PREFIX_DEFAULT(/usr/local)
AC_CHECK_HEADER([filesystem], [], [AC_MSG_ERROR([The file <filesystem> is missing, perhaps you should install a more recent libstdc++ implementation.])])
dnl check if we need stdc++fs as library
AC_MSG_CHECKING([if linking to stdc++fs is required])
AC_TRY_LINK(
[#include <filesystem>],
[(void)std::filesystem::current_path();],
[
AC_MSG_RESULT(no)
],
[
LIBS="$LIBS -lstdc++fs"
AC_TRY_LINK(
[#include <filesystem>],
[(void)std::filesystem::current_path();],
[
AC_MSG_RESULT(yes)
],
[
AC_MSG_ERROR([Could not link filesystem])
]
)
]
)
dnl AC_DEFUN([read_test], [AC_LANG_SOURCE(
dnl esyscmd(tools/m4esc.sh config-tests/$1))])
dnl
dnl AC_MSG_CHECKING([compiler standards compliance])
dnl AC_COMPILE_IFELSE(
dnl [read_test(cpp-17-test.cpp)], [],
dnl [AC_MSG_ERROR([Your c++ compiler is not capable of compiling libcifpp, please upgrade])])
dnl AC_MSG_RESULT(ok)
AC_PROG_INSTALL
dnl Shared libraries are not convenient
dnl LT_INIT([disable-shared])
LT_INIT
AC_SUBST(LIBTOOL_DEPS)
dnl versioning, first for libtool
LIBCIF_CURRENT=1
LIBCIF_REVISION=0
LIBCIF_AGE=0
LIBCIF_LT_CURRENT="${LIBCIF_CURRENT}"
LIBCIF_LT_VERSION="${LIBCIF_CURRENT}:${LIBCIF_REVISION}:${LIBCIF_AGE}"
AC_SUBST(LIBCIF_LT_CURRENT)
AC_SUBST(LIBCIF_LT_VERSION)
dnl and now for the semantic version
LIBCIF_SEMANTIC_VERSION=1.0.0
AC_SUBST(LIBCIF_SEMANTIC_VERSION)
AC_ARG_VAR([DEBUG], [Build a debug version of the library])
dnl revision numbering is something used internally at the NKI
AC_ARG_ENABLE(
revision,
[AS_HELP_STRING([--enable-revision], [Create a build number as revision])])
AS_IF([test "x$enable_revision" != "xyes" ], [
UPDATE_REVISION=1
])
dnl disable resources on macOS
AS_CASE([$host],
[*-apple-*], [USE_RSRC=0],
[USE_RSRC=1]
)
AC_SUBST([USE_RSRC])
AC_SUBST([UPDATE_REVISION], [$UPDATE_REVISION])
AC_ARG_VAR([CCP4], [The location where CCP4 is installed])
AC_PATH_PROG([PKG_CONFIG], [pkg-config])
AC_CHECK_FUNCS([floor pow rint sqrt strchr strerror])
AC_CHECK_HEADERS([sys/ioctl.h])
AC_CHECK_HEADERS([termios.h])
AC_CHECK_HEADER_STDBOOL
AC_CHECK_TYPES([ptrdiff_t])
AC_PROG_MAKE_SET
AX_BOOST_BASE([1.71], [], [
AC_MSG_ERROR([Sorry, your boost is not found or not up-to-date.])
])
AX_BOOST_IOSTREAMS
AX_BOOST_DATE_TIME
AC_OUTPUT([GNUmakefile
libcifpp.pc])

1573
examples/pdb1cbs.ent Normal file

File diff suppressed because it is too large Load Diff

BIN
examples/pdb1cbs.ent.gz Normal file

Binary file not shown.

View File

@@ -32,8 +32,6 @@
#include <string>
#include <stdexcept>
#include "cif++/Config.hpp"
namespace mmcif
{

101
include/cif++/BondMap.hpp Normal file
View File

@@ -0,0 +1,101 @@
/*-
* SPDX-License-Identifier: BSD-2-Clause
*
* Copyright (c) 2020 NKI/AVL, Netherlands Cancer Institute
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#pragma once
#include <unordered_map>
#include <filesystem>
#include <stdexcept>
#include "cif++/Structure.hpp"
namespace mmcif
{
class BondMapException : public std::runtime_error
{
public:
BondMapException(const std::string& msg)
: runtime_error(msg) {}
};
class BondMap
{
public:
BondMap(const Structure& p);
BondMap(const BondMap&) = delete;
BondMap& operator=(const BondMap&) = delete;
bool operator()(const Atom& a, const Atom& b) const
{
return isBonded(index.at(a.id()), index.at(b.id()));
}
bool is1_4(const Atom& a, const Atom& b) const
{
uint32_t ixa = index.at(a.id());
uint32_t ixb = index.at(b.id());
return bond_1_4.count(key(ixa, ixb));
}
// links coming from the struct_conn records:
std::vector<std::string> linked(const Atom& a) const;
// This list of atomID's is comming from either CCD or the CCP4 dictionaries loaded
static std::vector<std::string> atomIDsForCompound(const std::string& compoundID);
private:
bool isBonded(uint32_t ai, uint32_t bi) const
{
return bond.count(key(ai, bi)) != 0;
}
uint64_t key(uint32_t a, uint32_t b) const
{
if (a > b)
std::swap(a, b);
return static_cast<uint64_t>(a) | (static_cast<uint64_t>(b) << 32);
}
std::tuple<uint32_t,uint32_t> dekey(uint64_t k) const
{
return std::make_tuple(
static_cast<uint32_t>(k >> 32),
static_cast<uint32_t>(k)
);
}
uint32_t dim;
std::unordered_map<std::string,uint32_t> index;
std::set<uint64_t> bond, bond_1_4;
std::map<std::string,std::set<std::string>> link;
};
}

File diff suppressed because it is too large Load Diff

View File

@@ -29,6 +29,7 @@
#include "cif++/Cif++.hpp"
#include <stack>
#include <map>
namespace cif
{
@@ -95,13 +96,17 @@ inline bool isUnquotedString(const char* s)
std::tuple<std::string,std::string> splitTagName(const std::string& tag);
// --------------------------------------------------------------------
using DatablockIndex = std::map<std::string,std::size_t>;
// --------------------------------------------------------------------
// sac Parser, analogous to SAX Parser (simple api for xml)
class SacParser
{
public:
SacParser(std::istream& is);
SacParser(std::istream& is, bool init = true);
virtual ~SacParser() {}
enum CIFToken
@@ -142,6 +147,11 @@ class SacParser
CIFToken getNextToken();
void match(CIFToken token);
bool parseSingleDatablock(const std::string& datablock);
DatablockIndex indexDatablocks();
bool parseSingleDatablock(const std::string& datablock, const DatablockIndex &index);
void parseFile();
void parseGlobal();
void parseDataBlock();
@@ -197,7 +207,7 @@ class SacParser
class Parser : public SacParser
{
public:
Parser(std::istream& is, File& f);
Parser(std::istream& is, File& f, bool init = true);
virtual void produceDatablock(const std::string& name);
virtual void produceCategory(const std::string& name);

View File

@@ -26,17 +26,34 @@
#pragma once
#include "cif++/Config.hpp"
#include <vector>
#include <set>
#include <cassert>
#include <memory>
#include <list>
#include <iostream>
#include <filesystem>
#include <iostream>
#include <list>
#include <memory>
#include <set>
#include <vector>
#ifndef STDOUT_FILENO
#define STDOUT_FILENO 1
#endif
#if _MSC_VER
#include <io.h>
#define isatty _isatty
#else
#include <unistd.h>
#endif
#include "cif++/Cif++Export.hpp"
#if _MSC_VER
#pragma warning(disable : 4996) // unsafe function or variable (strcpy e.g.)
#pragma warning(disable : 4068) // unknown pragma
#pragma warning(disable : 4100) // unreferenced formal parameter
#pragma warning(disable : 4101) // unreferenced local variable
#define _SILENCE_CXX17_CODECVT_HEADER_DEPRECATION_WARNING 1
#endif
namespace cif
{
@@ -50,45 +67,50 @@ std::string get_version_nr();
// some basic utilities: Since we're using ASCII input only, we define for optimisation
// our own case conversion routines.
bool iequals(const std::string& a, const std::string& b);
int icompare(const std::string& a, const std::string& b);
bool iequals(const std::string &a, const std::string &b);
int icompare(const std::string &a, const std::string &b);
bool iequals(const char* a, const char* b);
int icompare(const char* a, const char* b);
bool iequals(const char *a, const char *b);
int icompare(const char *a, const char *b);
void toLower(std::string& s);
std::string toLowerCopy(const std::string& s);
void toLower(std::string &s);
std::string toLowerCopy(const std::string &s);
// To make life easier, we also define iless and iset using iequals
struct iless
{
bool operator()(const std::string& a, const std::string& b) const
bool operator()(const std::string &a, const std::string &b) const
{
return icompare(a, b) < 0;
}
};
typedef std::set<std::string, iless> iset;
typedef std::set<std::string, iless> iset;
// --------------------------------------------------------------------
// This really makes a difference, having our own tolower routines
extern const uint8_t kCharToLowerMap[256];
inline char tolower(char ch)
inline char tolower(int ch)
{
return static_cast<char>(kCharToLowerMap[static_cast<uint8_t>(ch)]);
}
// --------------------------------------------------------------------
std::tuple<std::string,std::string> splitTagName(const std::string& tag);
std::tuple<std::string, std::string> splitTagName(const std::string &tag);
// --------------------------------------------------------------------
// generate a cif name, mainly used to generate asym_id's
std::string cifIdForNumber(int number);
// --------------------------------------------------------------------
// custom wordwrapping routine
std::vector<std::string> wordWrap(const std::string& text, unsigned int width);
std::vector<std::string> wordWrap(const std::string &text, size_t width);
// --------------------------------------------------------------------
// Code helping with terminal i/o
@@ -103,26 +125,41 @@ std::string get_executable_path();
// --------------------------------------------------------------------
// some manipulators to write coloured text to terminals
enum StringColour {
scBLACK = 0, scRED, scGREEN, scYELLOW, scBLUE, scMAGENTA, scCYAN, scWHITE, scNONE = 9 };
enum StringColour
{
scBLACK = 0,
scRED,
scGREEN,
scYELLOW,
scBLUE,
scMAGENTA,
scCYAN,
scWHITE,
scNONE = 9
};
template<typename String, typename CharT>
template <typename String, typename CharT>
struct ColouredString
{
static_assert(std::is_reference<String>::value or std::is_pointer<String>::value, "String type must be pointer or reference");
ColouredString(String s, StringColour fore, StringColour back, bool bold = true)
: m_s(s), m_fore(fore), m_back(back), m_bold(bold) {}
ColouredString& operator=(const ColouredString&) = delete;
: m_s(s)
, m_fore(fore)
, m_back(back)
, m_bold(bold)
{
}
ColouredString &operator=(const ColouredString &) = delete;
String m_s;
StringColour m_fore, m_back;
bool m_bold;
};
template<typename CharT, typename Traits>
std::basic_ostream<CharT, Traits>& operator<<(std::basic_ostream<CharT, Traits>& os, const ColouredString<const CharT*,CharT>& s)
template <typename CharT, typename Traits>
std::basic_ostream<CharT, Traits> &operator<<(std::basic_ostream<CharT, Traits> &os, const ColouredString<const CharT *, CharT> &s)
{
if (isatty(STDOUT_FILENO))
{
@@ -130,15 +167,15 @@ std::basic_ostream<CharT, Traits>& operator<<(std::basic_ostream<CharT, Traits>&
ostr << "\033[" << (30 + s.m_fore) << ';' << (s.m_bold ? "1" : "22") << ';' << (40 + s.m_back) << 'm'
<< s.m_s
<< "\033[0m";
return os << ostr.str();
}
else
return os << s.m_s;
}
template<typename CharT, typename Traits, typename String>
std::basic_ostream<CharT, Traits>& operator<<(std::basic_ostream<CharT, Traits>& os, const ColouredString<String,CharT>& s)
template <typename CharT, typename Traits, typename String>
std::basic_ostream<CharT, Traits> &operator<<(std::basic_ostream<CharT, Traits> &os, const ColouredString<String, CharT> &s)
{
if (isatty(STDOUT_FILENO))
{
@@ -146,27 +183,27 @@ std::basic_ostream<CharT, Traits>& operator<<(std::basic_ostream<CharT, Traits>&
ostr << "\033[" << (30 + s.m_fore) << ';' << (s.m_bold ? "1" : "22") << ';' << (40 + s.m_back) << 'm'
<< s.m_s
<< "\033[0m";
return os << ostr.str();
}
else
return os << s.m_s;
}
template<typename CharT>
inline auto coloured(const CharT* s, StringColour fore = scWHITE, StringColour back = scRED, bool bold = true)
template <typename CharT>
inline auto coloured(const CharT *s, StringColour fore = scWHITE, StringColour back = scRED, bool bold = true)
{
return ColouredString<const CharT*, CharT>(s, fore, back, bold);
return ColouredString<const CharT *, CharT>(s, fore, back, bold);
}
template<typename CharT, typename Traits, typename Alloc>
inline auto coloured(const std::basic_string<CharT, Traits, Alloc>& s, StringColour fore = scWHITE, StringColour back = scRED, bool bold = true)
template <typename CharT, typename Traits, typename Alloc>
inline auto coloured(const std::basic_string<CharT, Traits, Alloc> &s, StringColour fore = scWHITE, StringColour back = scRED, bool bold = true)
{
return ColouredString<const std::basic_string<CharT, Traits, Alloc>, CharT>(s, fore, back, bold);
}
template<typename CharT, typename Traits, typename Alloc>
inline auto coloured(std::basic_string<CharT, Traits, Alloc>& s, StringColour fore = scWHITE, StringColour back = scRED, bool bold = true)
template <typename CharT, typename Traits, typename Alloc>
inline auto coloured(std::basic_string<CharT, Traits, Alloc> &s, StringColour fore = scWHITE, StringColour back = scRED, bool bold = true)
{
return ColouredString<std::basic_string<CharT, Traits, Alloc>, CharT>(s, fore, back, bold);
}
@@ -177,26 +214,26 @@ inline auto coloured(std::basic_string<CharT, Traits, Alloc>& s, StringColour fo
class Progress
{
public:
Progress(int64_t inMax, const std::string& inAction);
virtual ~Progress();
void consumed(int64_t inConsumed); // consumed is relative
void progress(int64_t inProgress); // progress is absolute
Progress(int64_t inMax, const std::string &inAction);
virtual ~Progress();
void message(const std::string& inMessage);
void consumed(int64_t inConsumed); // consumed is relative
void progress(int64_t inProgress); // progress is absolute
void message(const std::string &inMessage);
private:
Progress(const Progress&);
Progress& operator=(const Progress&);
Progress(const Progress &) = delete;
Progress &operator=(const Progress &) = delete;
struct ProgressImpl* mImpl;
struct ProgressImpl *mImpl;
};
// --------------------------------------------------------------------
// Resources
std::unique_ptr<std::istream> loadResource(std::filesystem::path name);
void addFileResource(const std::string &name, std::filesystem::path dataFile);
void addDataDirectory(std::filesystem::path dataDir);
}
} // namespace cif

View File

@@ -28,7 +28,10 @@
#include "cif++/Cif++.hpp"
#include <regex>
// duh.. https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86164
// #include <regex>
#include <boost/regex.hpp>
#include <set>
namespace cif
@@ -61,7 +64,8 @@ struct ValidateType
{
std::string mName;
DDL_PrimitiveType mPrimitiveType;
std::regex mRx;
// std::regex mRx;
boost::regex mRx;
bool operator<(const ValidateType& rhs) const
{

View File

@@ -26,10 +26,13 @@
#pragma once
/// \file This file contains the definition for the class Compound, encapsulating
/// the information found for compounds in the CCD.
#include <map>
#include <set>
#include <tuple>
#include <vector>
#include <map>
#include "cif++/AtomType.hpp"
#include "cif++/Cif++.hpp"
@@ -38,305 +41,155 @@ namespace mmcif
{
// --------------------------------------------------------------------
// The chemical composition of the structure in an mmCIF file is
// defined in the class composition. A compositon consists of
// entities. Each Entity can be either a polymer, a non-polymer
// a macrolide or a water molecule.
// Entities themselves are made up of compounds. And compounds
// contain CompoundAtom records for each atom.
class Compound;
class Link;
struct CompoundAtom;
class CompoundFactoryImpl;
enum BondType { singleBond, doubleBond, tripleBond, delocalizedBond };
/// \brief The bond type as defined in the CCD, possible values taken from the mmcif_pdbx_v50 file
enum class BondType
{
sing, // 'single bond'
doub, // 'double bond'
trip, // 'triple bond'
quad, // 'quadruple bond'
arom, // 'aromatic bond'
poly, // 'polymeric bond'
delo, // 'delocalized double bond'
pi, // 'pi bond'
};
// --------------------------------------------------------------------
// struct containing information about an atom in a chemical compound
// This information comes from the CCP4 monomer library.
std::string to_string(BondType bondType);
BondType from_string(const std::string& bondType);
/// --------------------------------------------------------------------
/// \brief struct containing information about an atom in a chemical compound.
/// This is a subset of the available information. Contact the author if you need more fields.
struct CompoundAtom
{
std::string id;
AtomType typeSymbol;
std::string typeEnergy;
float partialCharge;
std::string id;
AtomType typeSymbol;
int charge = 0;
bool aromatic = false;
bool leavingAtom = false;
bool stereoConfig = false;
float x, y, z;
};
// --------------------------------------------------------------------
// struct containing information about the bonds
// This information comes from the CCP4 monomer library.
/// --------------------------------------------------------------------
/// \brief struct containing information about the bonds
struct CompoundBond
{
std::string atomID[2];
BondType type;
float distance;
float esd;
std::string atomID[2];
BondType type;
bool aromatic = false, stereoConfig = false;
};
// --------------------------------------------------------------------
// struct containing information about the bond-angles
// This information comes from the CCP4 monomer library.
struct CompoundAngle
{
std::string atomID[3];
float angle;
float esd;
};
// --------------------------------------------------------------------
// struct containing information about the bond-angles
// This information comes from the CCP4 monomer library.
struct CompoundTorsion
{
std::string atomID[4];
float angle;
float esd;
int period;
};
// --------------------------------------------------------------------
// struct containing information about the bond-angles
// This information comes from the CCP4 monomer library.
struct CompoundPlane
{
std::string id;
std::vector<std::string> atomID;
float esd;
};
// --------------------------------------------------------------------
// struct containing information about a chiral centre
// This information comes from the CCP4 monomer library.
enum ChiralVolumeSign { negativ, positiv, both };
struct CompoundChiralCentre
{
std::string id;
std::string atomIDCentre;
std::string atomID[3];
ChiralVolumeSign volumeSign;
};
// --------------------------------------------------------------------
// a class that contains information about a chemical compound.
// This information is derived from the ccp4 monomer library by default.
// To create compounds, you'd best use the factory method.
/// --------------------------------------------------------------------
/// \brief a class that contains information about a chemical compound.
/// This information is derived from the CDD by default.
///
/// To create compounds, you use the factory method. You can add your own
/// compound definitions by calling the addExtraComponents function and
/// pass it a valid CCD formatted file.
class Compound
{
public:
Compound(const std::string& file, const std::string& id, const std::string& name,
const std::string& group);
// factory method, create a Compound based on the three letter code
// (for amino acids) or the one-letter code (for bases) or the
// code as it is known in the CCP4 monomer library.
static const Compound* create(const std::string& id);
// this second factory method can create a Compound even if it is not
// recorded in the library. It will take the values from the CCP4 lib
// unless the value passed to this function is not empty.
static const Compound* create(const std::string& id, const std::string& name,
const std::string& type, const std::string& formula);
// add an additional path to the monomer library.
static void addMonomerLibraryPath(const std::string& dir);
// accessors
std::string id() const { return mID; }
std::string name() const { return mName; }
std::string type() const;
std::string group() const { return mGroup; }
std::vector<CompoundAtom> atoms() const { return mAtoms; }
std::vector<CompoundBond> bonds() const { return mBonds; }
std::vector<CompoundAngle> angles() const { return mAngles; }
std::vector<CompoundChiralCentre> chiralCentres() const
{ return mChiralCentres; }
std::vector<CompoundPlane> planes() const { return mPlanes; }
std::vector<CompoundTorsion> torsions() const { return mTorsions; }
CompoundAtom getAtomByID(const std::string& atomID) const;
bool atomsBonded(const std::string& atomId_1, const std::string& atomId_2) const;
float atomBondValue(const std::string& atomId_1, const std::string& atomId_2) const;
float bondAngle(const std::string& atomId_1, const std::string& atomId_2, const std::string& atomId_3) const;
float chiralVolume(const std::string& centreID) const;
std::string formula() const;
float formulaWeight() const;
int charge() const;
bool isWater() const;
bool isSugar() const;
std::string id() const { return mID; }
std::string name() const { return mName; }
std::string type() const { return mType; }
std::string formula() const { return mFormula; }
float formulaWeight() const { return mFormulaWeight; }
int formalCharge() const { return mFormalCharge; }
std::vector<std::string> isomers() const;
bool isIsomerOf(const Compound& c) const;
std::vector<std::tuple<std::string,std::string>> mapToIsomer(const Compound& c) const;
const std::vector<CompoundAtom> &atoms() const { return mAtoms; }
const std::vector<CompoundBond> &bonds() const { return mBonds; }
CompoundAtom getAtomByID(const std::string &atomID) const;
bool atomsBonded(const std::string &atomId_1, const std::string &atomId_2) const;
// float atomBondValue(const std::string &atomId_1, const std::string &atomId_2) const;
// float bondAngle(const std::string &atomId_1, const std::string &atomId_2, const std::string &atomId_3) const;
// float chiralVolume(const std::string &centreID) const;
bool isWater() const
{
return mID == "HOH" or mID == "H2O" or mID == "WAT";
}
private:
~Compound();
friend class CompoundFactoryImpl;
friend class CCDCompoundFactoryImpl;
friend class CCP4CompoundFactoryImpl;
cif::File mCF;
Compound(cif::Datablock &db);
Compound(cif::Datablock &db, const std::string &id, const std::string &name, const std::string &type);
std::string mID;
std::string mName;
std::string mGroup;
std::vector<CompoundAtom> mAtoms;
std::vector<CompoundBond> mBonds;
std::vector<CompoundAngle> mAngles;
std::vector<CompoundTorsion>mTorsions;
std::vector<CompoundChiralCentre>
mChiralCentres;
std::vector<CompoundPlane> mPlanes;
};
// --------------------------------------------------------------------
// struct containing information about the bonds
// This information comes from the CCP4 monomer library.
struct LinkAtom
{
int compID;
std::string atomID;
bool operator==(const LinkAtom& rhs) const { return compID == rhs.compID and atomID == rhs.atomID; }
};
struct LinkBond
{
LinkAtom atom[2];
BondType type;
float distance;
float esd;
};
// --------------------------------------------------------------------
// struct containing information about the bond-angles
// This information comes from the CCP4 monomer library.
struct LinkAngle
{
LinkAtom atom[3];
float angle;
float esd;
};
// --------------------------------------------------------------------
// struct containing information about the bond-torsions
// This information comes from the CCP4 monomer library.
struct LinkTorsion
{
LinkAtom atom[4];
float angle;
float esd;
int period;
};
// --------------------------------------------------------------------
// struct containing information about the bond-angles
// This information comes from the CCP4 monomer library.
struct LinkPlane
{
std::string id;
std::vector<LinkAtom> atoms;
float esd;
};
// --------------------------------------------------------------------
// struct containing information about a chiral centre
// This information comes from the CCP4 monomer library.
struct LinkChiralCentre
{
std::string id;
LinkAtom atomCentre;
LinkAtom atom[3];
ChiralVolumeSign volumeSign;
};
// --------------------------------------------------------------------
// a class that contains information about a chemical link between compounds.
// This information is derived from the ccp4 monomer library by default.
class Link
{
public:
Link(cif::Datablock& db);
// Factory method.
static const Link& create(const std::string& id);
// accessors
std::string id() const { return mID; }
std::vector<LinkBond> bonds() const { return mBonds; }
std::vector<LinkAngle> angles() const { return mAngles; }
std::vector<LinkChiralCentre> chiralCentres() const { return mChiralCentres; }
std::vector<LinkPlane> planes() const { return mPlanes; }
std::vector<LinkTorsion> torsions() const { return mTorsions; }
float atomBondValue(const LinkAtom& atomId_1, const LinkAtom& atomId_2) const;
float bondAngle(const LinkAtom& atomId_1, const LinkAtom& atomId_2, const LinkAtom& atomId_3) const;
float chiralVolume(const std::string& id) const;
private:
~Link();
std::string mID;
std::vector<LinkBond> mBonds;
std::vector<LinkAngle> mAngles;
std::vector<LinkTorsion> mTorsions;
std::vector<LinkChiralCentre> mChiralCentres;
std::vector<LinkPlane> mPlanes;
std::string mID;
std::string mName;
std::string mType;
std::string mFormula;
float mFormulaWeight = 0;
int mFormalCharge = 0;
std::vector<CompoundAtom> mAtoms;
std::vector<CompoundBond> mBonds;
};
// --------------------------------------------------------------------
// Factory class for Compound and Link objects
extern const std::map<std::string,char> kAAMap, kBaseMap;
CIFPP_EXPORT extern const std::map<std::string, char> kAAMap, kBaseMap;
class CompoundFactory
{
public:
static CompoundFactory& instance();
void pushDictionary(const std::string& inDictFile);
/// \brief Initialise a singleton instance.
///
/// If you have a multithreaded application and want to have different
/// compounds in each thread (e.g. a web service processing user requests
/// with different sets of compounds) you can set the \a useThreadLocalInstanceOnly
/// flag to true.
static void init(bool useThreadLocalInstanceOnly);
static CompoundFactory &instance();
static void clear();
void setDefaultDictionary(const std::filesystem::path &inDictFile);
void pushDictionary(const std::filesystem::path &inDictFile);
void popDictionary();
bool isKnownPeptide(const std::string& res_name) const;
bool isKnownBase(const std::string& res_name) const;
bool isKnownPeptide(const std::string &res_name) const;
bool isKnownBase(const std::string &res_name) const;
std::string unalias(const std::string& res_name) const;
/// \brief Create the Compound object for \a id
///
/// This will create the Compound instance for \a id if it doesn't exist already.
/// The result is owned by this factory and should not be deleted by the user.
/// \param id The Compound ID, a three letter code usually
/// \result The compound, or nullptr if it could not be created (missing info)
const Compound *create(std::string id);
const Compound* get(std::string id);
const Compound* create(std::string id);
const Link* getLink(std::string id);
const Link* createLink(std::string id);
~CompoundFactory();
private:
CompoundFactory();
~CompoundFactory();
CompoundFactory(const CompoundFactory&) = delete;
CompoundFactory& operator=(const CompoundFactory&) = delete;
static CompoundFactory* sInstance;
class CompoundFactoryImpl* mImpl;
CompoundFactory(const CompoundFactory &) = delete;
CompoundFactory &operator=(const CompoundFactory &) = delete;
static std::unique_ptr<CompoundFactory> sInstance;
static thread_local std::unique_ptr<CompoundFactory> tlInstance;
static bool sUseThreadLocalInstance;
std::shared_ptr<CompoundFactoryImpl> mImpl;
};
}
} // namespace mmcif

391
include/cif++/Matrix.hpp Normal file
View File

@@ -0,0 +1,391 @@
/*-
* SPDX-License-Identifier: BSD-2-Clause
*
* Copyright Maarten L. Hekkelman, Radboud University 2008-2011.
* Copyright (c) 2021 NKI/AVL, Netherlands Cancer Institute
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
// --------------------------------------------------------------------
// uBlas compatible matrix types
#pragma once
#include <iostream>
#include <vector>
// matrix is m x n, addressing i,j is 0 <= i < m and 0 <= j < n
// element m i,j is mapped to [i * n + j] and thus storage is row major
template <typename T>
class MatrixBase
{
public:
using value_type = T;
virtual ~MatrixBase() {}
virtual uint32_t dim_m() const = 0;
virtual uint32_t dim_n() const = 0;
virtual value_type &operator()(uint32_t i, uint32_t j) { throw std::runtime_error("unimplemented method"); }
virtual value_type operator()(uint32_t i, uint32_t j) const = 0;
MatrixBase &operator*=(const value_type &rhs);
MatrixBase &operator-=(const value_type &rhs);
};
template <typename T>
MatrixBase<T> &MatrixBase<T>::operator*=(const T &rhs)
{
for (uint32_t i = 0; i < dim_m(); ++i)
{
for (uint32_t j = 0; j < dim_n(); ++j)
{
operator()(i, j) *= rhs;
}
}
return *this;
}
template <typename T>
MatrixBase<T> &MatrixBase<T>::operator-=(const T &rhs)
{
for (uint32_t i = 0; i < dim_m(); ++i)
{
for (uint32_t j = 0; j < dim_n(); ++j)
{
operator()(i, j) -= rhs;
}
}
return *this;
}
template <typename T>
std::ostream &operator<<(std::ostream &lhs, const MatrixBase<T> &rhs)
{
lhs << '[' << rhs.dim_m() << ',' << rhs.dim_n() << ']' << '(';
for (uint32_t i = 0; i < rhs.dim_m(); ++i)
{
lhs << '(';
for (uint32_t j = 0; j < rhs.dim_n(); ++j)
{
if (j > 0)
lhs << ',';
lhs << rhs(i, j);
}
lhs << ')';
}
lhs << ')';
return lhs;
}
template <typename T>
class Matrix : public MatrixBase<T>
{
public:
using value_type = T;
template <typename T2>
Matrix(const MatrixBase<T2> &m)
: m_m(m.dim_m())
, m_n(m.dim_n())
{
m_data = new value_type[m_m * m_n];
for (uint32_t i = 0; i < m_m; ++i)
{
for (uint32_t j = 0; j < m_n; ++j)
operator()(i, j) = m(i, j);
}
}
Matrix()
: m_data(nullptr)
, m_m(0)
, m_n(0)
{
}
Matrix(const Matrix &m)
: m_m(m.m_m)
, m_n(m.m_n)
{
m_data = new value_type[m_m * m_n];
std::copy(m.m_data, m.m_data + (m_m * m_n), m_data);
}
Matrix &operator=(const Matrix &m)
{
value_type *t = new value_type[m.m_m * m.m_n];
std::copy(m.m_data, m.m_data + (m.m_m * m.m_n), t);
delete[] m_data;
m_data = t;
m_m = m.m_m;
m_n = m.m_n;
return *this;
}
Matrix(uint32_t m, uint32_t n, T v = T())
: m_m(m)
, m_n(n)
{
m_data = new value_type[m_m * m_n];
std::fill(m_data, m_data + (m_m * m_n), v);
}
virtual ~Matrix()
{
delete[] m_data;
}
virtual uint32_t dim_m() const { return m_m; }
virtual uint32_t dim_n() const { return m_n; }
virtual value_type operator()(uint32_t i, uint32_t j) const
{
assert(i < m_m);
assert(j < m_n);
return m_data[i * m_n + j];
}
virtual value_type &operator()(uint32_t i, uint32_t j)
{
assert(i < m_m);
assert(j < m_n);
return m_data[i * m_n + j];
}
template <typename Func>
void each(Func f)
{
for (uint32_t i = 0; i < m_m * m_n; ++i)
f(m_data[i]);
}
template <typename U>
Matrix &operator/=(U v)
{
for (uint32_t i = 0; i < m_m * m_n; ++i)
m_data[i] /= v;
return *this;
}
private:
value_type *m_data;
uint32_t m_m, m_n;
};
// --------------------------------------------------------------------
template <typename T>
class SymmetricMatrix : public MatrixBase<T>
{
public:
typedef typename MatrixBase<T>::value_type value_type;
SymmetricMatrix(uint32_t n, T v = T())
: m_owner(true)
, m_n(n)
{
uint32_t N = (m_n * (m_n + 1)) / 2;
m_data = new value_type[N];
std::fill(m_data, m_data + N, v);
}
SymmetricMatrix(const T *data, uint32_t n)
: m_owner(false)
, m_data(const_cast<T *>(data))
, m_n(n)
{
}
virtual ~SymmetricMatrix()
{
if (m_owner)
delete[] m_data;
}
virtual uint32_t dim_m() const { return m_n; }
virtual uint32_t dim_n() const { return m_n; }
T operator()(uint32_t i, uint32_t j) const;
virtual T &operator()(uint32_t i, uint32_t j);
// erase two rows, add one at the end (for neighbour joining)
void erase_2(uint32_t i, uint32_t j);
template <typename Func>
void each(Func f)
{
uint32_t N = (m_n * (m_n + 1)) / 2;
for (uint32_t i = 0; i < N; ++i)
f(m_data[i]);
}
template <typename U>
SymmetricMatrix &operator/=(U v)
{
uint32_t N = (m_n * (m_n + 1)) / 2;
for (uint32_t i = 0; i < N; ++i)
m_data[i] /= v;
return *this;
}
private:
bool m_owner;
value_type *m_data;
uint32_t m_n;
};
template <typename T>
inline T SymmetricMatrix<T>::operator()(uint32_t i, uint32_t j) const
{
return i < j
? m_data[(j * (j + 1)) / 2 + i]
: m_data[(i * (i + 1)) / 2 + j];
}
template <typename T>
inline T &SymmetricMatrix<T>::operator()(uint32_t i, uint32_t j)
{
if (i > j)
std::swap(i, j);
assert(j < m_n);
return m_data[(j * (j + 1)) / 2 + i];
}
template <typename T>
void SymmetricMatrix<T>::erase_2(uint32_t di, uint32_t dj)
{
uint32_t s = 0, d = 0;
for (uint32_t i = 0; i < m_n; ++i)
{
for (uint32_t j = 0; j < i; ++j)
{
if (i != di and j != dj and i != dj and j != di)
{
if (s != d)
m_data[d] = m_data[s];
++d;
}
++s;
}
}
--m_n;
}
template <typename T>
class IdentityMatrix : public MatrixBase<T>
{
public:
typedef typename MatrixBase<T>::value_type value_type;
IdentityMatrix(uint32_t n)
: m_n(n)
{
}
virtual uint32_t dim_m() const { return m_n; }
virtual uint32_t dim_n() const { return m_n; }
virtual value_type operator()(uint32_t i, uint32_t j) const
{
value_type result = 0;
if (i == j)
result = 1;
return result;
}
private:
uint32_t m_n;
};
// --------------------------------------------------------------------
// matrix functions
template <typename T>
Matrix<T> operator*(const MatrixBase<T> &lhs, const MatrixBase<T> &rhs)
{
Matrix<T> result(std::min(lhs.dim_m(), rhs.dim_m()), std::min(lhs.dim_n(), rhs.dim_n()));
for (uint32_t i = 0; i < result.dim_m(); ++i)
{
for (uint32_t j = 0; j < result.dim_n(); ++j)
{
for (uint32_t li = 0, rj = 0; li < lhs.dim_m() and rj < rhs.dim_n(); ++li, ++rj)
result(i, j) += lhs(li, j) * rhs(i, rj);
}
}
return result;
}
template <typename T>
Matrix<T> operator*(const MatrixBase<T> &lhs, T rhs)
{
Matrix<T> result(lhs);
result *= rhs;
return result;
}
template <typename T>
Matrix<T> operator-(const MatrixBase<T> &lhs, const MatrixBase<T> &rhs)
{
Matrix<T> result(std::min(lhs.dim_m(), rhs.dim_m()), std::min(lhs.dim_n(), rhs.dim_n()));
for (uint32_t i = 0; i < result.dim_m(); ++i)
{
for (uint32_t j = 0; j < result.dim_n(); ++j)
{
result(i, j) = lhs(i, j) - rhs(i, j);
}
}
return result;
}
template <typename T>
Matrix<T> operator-(const MatrixBase<T> &lhs, T rhs)
{
Matrix<T> result(lhs.dim_m(), lhs.dim_n());
result -= rhs;
return result;
}
// template <typename T>
// symmetric_matrix<T> hammingDistance(const MatrixBase<T> &lhs, T rhs);
// template <typename T>
// std::vector<T> sum(const MatrixBase<T> &m);

View File

@@ -32,22 +32,23 @@
struct PDBRecord
{
PDBRecord* mNext;
uint32_t mLineNr;
char mName[11];
size_t mVlen;
char mValue[0];
PDBRecord *mNext;
uint32_t mLineNr;
char mName[11];
size_t mVlen;
char mValue[1];
PDBRecord(uint32_t lineNr, const std::string& name, const std::string& value);
PDBRecord(uint32_t lineNr, const std::string &name, const std::string &value);
~PDBRecord();
void* operator new(size_t);
void* operator new(size_t size, size_t vLen);
void operator delete(void* p);
bool is(const char* name) const;
void *operator new(size_t);
void *operator new(size_t size, size_t vLen);
void operator delete(void *p);
void operator delete(void *p, size_t vLen);
bool is(const char *name) const;
char vC(size_t column);
std::string vS(size_t columnFirst, size_t columnLast = std::numeric_limits<size_t>::max());
int vI(int columnFirst, int columnLast);
@@ -56,4 +57,4 @@ struct PDBRecord
// --------------------------------------------------------------------
void ReadPDBFile(std::istream& pdbFile, cif::File& cifFile);
void ReadPDBFile(std::istream &pdbFile, cif::File &cifFile);

View File

@@ -32,17 +32,15 @@
#include <clipper/core/coords.h>
#endif
#include "cif++/Config.hpp"
#include <boost/math/quaternion.hpp>
namespace mmcif
{
typedef boost::math::quaternion<float> quaternion;
typedef boost::math::quaternion<float> Quaternion;
const long double
kPI = 3.141592653589793238462643383279502884L;
const double
kPI = 3.141592653589793238462643383279502884;
// --------------------------------------------------------------------
@@ -342,6 +340,16 @@ double CosinusAngle(const PointF<F>& p1, const PointF<F>& p2, const PointF<F>& p
return result;
}
template<typename F>
auto DistancePointToLine(const PointF<F> &l1, const PointF<F> &l2, const PointF<F> &p)
{
auto line = l2 - l1;
auto p_to_l1 = p - l1;
auto p_to_l2 = p - l2;
auto cross = CrossProduct(p_to_l1, p_to_l2);
return cross.length() / line.length();
}
// --------------------------------------------------------------------
// For e.g. simulated annealing, returns a new point that is moved in
// a random direction with a distance randomly chosen from a normal
@@ -353,12 +361,12 @@ PointF<F> Nudge(PointF<F> p, F offset);
// --------------------------------------------------------------------
// We use quaternions to do rotations in 3d space
quaternion Normalize(quaternion q);
Quaternion Normalize(Quaternion q);
//std::tuple<double,Point> QuaternionToAngleAxis(quaternion q);
std::tuple<double,Point> QuaternionToAngleAxis(Quaternion q);
Point Centroid(std::vector<Point>& Points);
Point CenterPoints(std::vector<Point>& Points);
quaternion AlignPoints(const std::vector<Point>& a, const std::vector<Point>& b);
Quaternion AlignPoints(const std::vector<Point>& a, const std::vector<Point>& b);
double RMSd(const std::vector<Point>& a, const std::vector<Point>& b);
// --------------------------------------------------------------------

View File

@@ -130,7 +130,7 @@ class DSSP
DSSP_Statistics GetStatistics() const;
class iterator;
using res_iter = typename std::vector<Res>::iterator;
using res_iterator = typename std::vector<Res>::iterator;
class ResidueInfo
{
@@ -169,7 +169,7 @@ class DSSP
std::tuple<ResidueInfo,double> donor(int i) const;
private:
ResidueInfo(Res* res);
ResidueInfo(Res* res) : mImpl(res) {}
Res* mImpl;
};
@@ -184,7 +184,7 @@ class DSSP
using reference = value_type&;
iterator(const iterator& i);
iterator(res_iter cur);
iterator(Res* res);
iterator& operator=(const iterator& i);
reference operator*() { return mCurrent; }

View File

@@ -29,9 +29,9 @@
#include <numeric>
#include "cif++/AtomType.hpp"
#include "cif++/Point.hpp"
#include "cif++/Compound.hpp"
#include "cif++/Cif++.hpp"
#include "cif++/Compound.hpp"
#include "cif++/Point.hpp"
/*
To modify a structure, you will have to use actions.
@@ -61,29 +61,36 @@ class File;
class Atom
{
public:
// Atom(const structure& s, const std::string& id);
Atom();
Atom(struct AtomImpl* impl);
Atom(const Atom& rhs);
Atom(struct AtomImpl *impl);
Atom(const Atom &rhs);
Atom(cif::Datablock &db, cif::Row &row);
// a special constructor to create symmetry copies
Atom(const Atom& rhs, const Point& symmmetry_location, const std::string& symmetry_operation);
Atom(const Atom &rhs, const Point &symmmetry_location, const std::string &symmetry_operation);
~Atom();
explicit operator bool() const { return mImpl_ != nullptr; }
explicit operator bool() const { return mImpl_ != nullptr; }
// return a copy of this atom, with data copied instead of referenced
Atom clone() const;
Atom& operator=(const Atom& rhs);
const std::string& id() const;
Atom &operator=(const Atom &rhs);
const std::string &id() const;
AtomType type() const;
Point location() const;
void location(Point p);
/// \brief Translate the position of this atom by \a t
void translate(Point t);
/// \brief Rotate the position of this atom by \a q
void rotate(Quaternion q);
// for direct access to underlying data, be careful!
const cif::Row getRow() const;
const cif::Row getRowAniso() const;
@@ -92,45 +99,46 @@ class Atom
bool isSymmetryCopy() const;
std::string symmetry() const;
// const clipper::RTop_orth& symop() const;
const Compound& comp() const;
const Compound &comp() const;
bool isWater() const;
int charge() const;
float uIso() const;
bool getAnisoU(float anisou[6]) const;
float occupancy() const;
template<typename T>
T property(const std::string& name) const;
void property(const std::string& name, const std::string& value);
template<typename T, std::enable_if_t<std::is_arithmetic_v<T>, int> = 0>
void property(const std::string& name, const T& value)
template <typename T>
T property(const std::string &name) const;
void property(const std::string &name, const std::string &value);
template <typename T, std::enable_if_t<std::is_arithmetic_v<T>, int> = 0>
void property(const std::string &name, const T &value)
{
property(name, std::to_string(value));
}
// specifications
std::string labelAtomID() const;
std::string labelCompID() const;
std::string labelAsymID() const;
std::string labelEntityID() const;
int labelSeqID() const;
std::string labelAltID() const;
bool isAlternate() const;
std::string authAtomID() const;
std::string authCompID() const;
std::string authAsymID() const;
std::string authSeqID() const;
std::string pdbxAuthInsCode() const;
std::string pdbxAuthAltID() const;
std::string labelID() const;// label_comp_id + '_' + label_asym_id + '_' + label_seq_id
std::string pdbID() const; // auth_comp_id + '_' + auth_asym_id + '_' + auth_seq_id + pdbx_PDB_ins_code
bool operator==(const Atom& rhs) const;
std::string labelID() const; // label_comp_id + '_' + label_asym_id + '_' + label_seq_id
std::string pdbID() const; // auth_comp_id + '_' + auth_asym_id + '_' + auth_seq_id + pdbx_PDB_ins_code
bool operator==(const Atom &rhs) const;
// // get clipper format Atom
// clipper::Atom toClipper() const;
@@ -138,54 +146,51 @@ class Atom
// Radius calculation based on integrating the density until perc of electrons is found
void calculateRadius(float resHigh, float resLow, float perc);
float radius() const;
// access data in compound for this atom
// the energy-type field
std::string energyType() const;
// convenience routine
bool isBackBone() const
{
auto atomID = labelAtomID();
return atomID == "N" or atomID == "O" or atomID == "C" or atomID == "CA";
}
void swap(Atom& b)
void swap(Atom &b)
{
std::swap(mImpl_, b.mImpl_);
}
int compare(const Atom& b) const;
int compare(const Atom &b) const;
bool operator<(const Atom& rhs) const
bool operator<(const Atom &rhs) const
{
return compare(rhs) < 0;
}
friend std::ostream& operator<<(std::ostream& os, const Atom& atom);
friend std::ostream &operator<<(std::ostream &os, const Atom &atom);
private:
friend class Structure;
void setID(int id);
AtomImpl* impl();
const AtomImpl* impl() const;
AtomImpl *impl();
const AtomImpl *impl() const;
struct AtomImpl* mImpl_;
struct AtomImpl *mImpl_;
};
inline void swap(mmcif::Atom& a, mmcif::Atom& b)
inline void swap(mmcif::Atom &a, mmcif::Atom &b)
{
a.swap(b);
}
inline double Distance(const Atom& a, const Atom& b)
inline double Distance(const Atom &a, const Atom &b)
{
return Distance(a.location(), b.location());
}
inline double DistanceSquared(const Atom& a, const Atom& b)
inline double DistanceSquared(const Atom &a, const Atom &b)
{
return DistanceSquared(a.location(), b.location());
}
@@ -198,58 +203,61 @@ class Residue
{
public:
// constructors should be private, but that's not possible for now (needed in emplace)
// constructor for waters
Residue(const Structure& structure, const std::string& compoundID,
const std::string& asymID, const std::string& authSeqID);
Residue(const Structure &structure, const std::string &compoundID,
const std::string &asymID, const std::string &authSeqID);
Residue(const Structure& structure, const std::string& compoundID,
const std::string& asymID, int seqID = 0);
// constructor for a residue without a sequence number
Residue(const Structure &structure, const std::string &compoundID,
const std::string &asymID);
Residue(const Residue& rhs) = delete;
Residue& operator=(const Residue& rhs) = delete;
// constructor for a residue with a sequence number
Residue(const Structure &structure, const std::string &compoundID,
const std::string &asymID, int seqID, const std::string &authSeqID);
Residue(Residue&& rhs);
Residue& operator=(Residue&& rhs);
Residue(const Residue &rhs) = delete;
Residue &operator=(const Residue &rhs) = delete;
Residue(Residue &&rhs);
Residue &operator=(Residue &&rhs);
virtual ~Residue();
const Compound& compound() const;
const AtomView& atoms() const;
const Compound &compound() const;
const AtomView &atoms() const;
/// \brief Unique atoms returns only the atoms without alternates and the first of each alternate atom id.
AtomView unique_atoms() const;
AtomView unique_atoms() const;
/// \brief The alt ID used for the unique atoms
std::string unique_alt_id() const;
std::string unique_alt_id() const;
Atom atomByID(const std::string& atomID) const;
Atom atomByID(const std::string &atomID) const;
const std::string &compoundID() const { return mCompoundID; }
const std::string &asymID() const { return mAsymID; }
int seqID() const { return mSeqID; }
std::string entityID() const;
std::string authAsymID() const;
std::string authSeqID() const;
std::string authInsCode() const;
const std::string& compoundID() const { return mCompoundID; }
const std::string& asymID() const { return mAsymID; }
int seqID() const { return mSeqID; }
std::string authAsymID() const;
std::string authSeqID() const;
std::string authInsCode() const;
// return a human readable PDB-like auth id (chain+seqnr+iCode)
std::string authID() const;
std::string authID() const;
// similar for mmCIF space
std::string labelID() const;
std::string labelID() const;
// Is this residue a single entity?
bool isEntity() const;
bool isWater() const { return mCompoundID == "HOH"; }
bool isSugar() const;
bool isPyranose() const;
bool isFuranose() const;
const Structure& structure() const { return *mStructure; }
bool isWater() const { return mCompoundID == "HOH"; }
bool empty() const { return mStructure == nullptr; }
const Structure &structure() const { return *mStructure; }
bool empty() const { return mStructure == nullptr; }
bool hasAlternateAtoms() const;
@@ -260,42 +268,43 @@ class Residue
std::set<std::string> getAtomIDs() const;
/// \brief Return the list of atoms having ID \a atomID
AtomView getAtomsByID(const std::string& atomID) const;
AtomView getAtomsByID(const std::string &atomID) const;
// some routines for 3d work
std::tuple<Point,float> centerAndRadius() const;
std::tuple<Point, float> centerAndRadius() const;
friend std::ostream& operator<<(std::ostream& os, const Residue& res);
friend std::ostream &operator<<(std::ostream &os, const Residue &res);
protected:
Residue() {}
friend class Polymer;
const Structure* mStructure = nullptr;
std::string mCompoundID, mAsymID;
const Structure *mStructure = nullptr;
std::string mCompoundID, mAsymID;
int mSeqID = 0;
// Watch out, this is used only to label waters... The rest of the code relies on
// MapLabelToAuth to get this info. Perhaps we should rename this member field.
std::string mAuthSeqID;
AtomView mAtoms;
};
// --------------------------------------------------------------------
// a monomer models a single Residue in a protein chain
// a monomer models a single Residue in a protein chain
class Monomer : public Residue
{
public:
// Monomer();
Monomer(const Monomer& rhs) = delete;
Monomer& operator=(const Monomer& rhs) = delete;
Monomer(Monomer&& rhs);
Monomer& operator=(Monomer&& rhs);
// Monomer();
Monomer(const Monomer &rhs) = delete;
Monomer &operator=(const Monomer &rhs) = delete;
// Monomer(const Polymer& polymer, uint32_t index);
Monomer(const Polymer& polymer, uint32_t index, int seqID,
const std::string& compoundID);
Monomer(Monomer &&rhs);
Monomer &operator=(Monomer &&rhs);
Monomer(const Polymer &polymer, size_t index, int seqID, const std::string &authSeqID,
const std::string &compoundID);
bool is_first_in_chain() const;
bool is_last_in_chain() const;
@@ -305,7 +314,7 @@ class Monomer : public Residue
bool has_kappa() const;
// Assuming this is really an amino acid...
float phi() const;
float psi() const;
float alpha() const;
@@ -313,10 +322,10 @@ class Monomer : public Residue
float tco() const;
float omega() const;
// torsion angles
size_t nrOfChis() const;
float chi(size_t i) const;
// torsion angles
size_t nrOfChis() const;
float chi(size_t i) const;
bool isCis() const;
/// \brief Returns true if the four atoms C, CA, N and O are present
@@ -325,27 +334,27 @@ class Monomer : public Residue
/// \brief Returns true if any of the backbone atoms has an alternate
bool hasAlternateBackboneAtoms() const;
Atom CAlpha() const { return atomByID("CA"); }
Atom C() const { return atomByID("C"); }
Atom N() const { return atomByID("N"); }
Atom O() const { return atomByID("O"); }
Atom H() const { return atomByID("H"); }
Atom CAlpha() const { return atomByID("CA"); }
Atom C() const { return atomByID("C"); }
Atom N() const { return atomByID("N"); }
Atom O() const { return atomByID("O"); }
Atom H() const { return atomByID("H"); }
bool isBondedTo(const Monomer& rhs) const
bool isBondedTo(const Monomer &rhs) const
{
return this != &rhs and areBonded(*this, rhs);
}
static bool areBonded(const Monomer& a, const Monomer& b, float errorMargin = 0.5f);
static bool isCis(const Monomer& a, const Monomer& b);
static float omega(const Monomer& a, const Monomer& b);
static bool areBonded(const Monomer &a, const Monomer &b, float errorMargin = 0.5f);
static bool isCis(const Monomer &a, const Monomer &b);
static float omega(const Monomer &a, const Monomer &b);
// for LEU and VAL
float chiralVolume() const;
// for LEU and VAL
float chiralVolume() const;
private:
const Polymer* mPolymer;
uint32_t mIndex;
const Polymer *mPolymer;
size_t mIndex;
};
// --------------------------------------------------------------------
@@ -353,32 +362,31 @@ class Monomer : public Residue
class Polymer : public std::vector<Monomer>
{
public:
Polymer(const Structure& s, const std::string& entityID, const std::string& asymID);
Polymer(const Structure &s, const std::string &entityID, const std::string &asymID);
Polymer(const Polymer&) = delete;
Polymer& operator=(const Polymer&) = delete;
// Polymer(Polymer&& rhs) = delete;
// Polymer& operator=(Polymer&& rhs) = de;
Polymer(const Polymer &) = delete;
Polymer &operator=(const Polymer &) = delete;
Monomer& getBySeqID(int seqID);
const Monomer& getBySeqID(int seqID) const;
// Polymer(Polymer&& rhs) = delete;
// Polymer& operator=(Polymer&& rhs) = de;
Monomer &getBySeqID(int seqID);
const Monomer &getBySeqID(int seqID) const;
Structure *structure() const { return mStructure; }
std::string asymID() const { return mAsymID; }
std::string entityID() const { return mEntityID; }
Structure* structure() const { return mStructure; }
std::string asymID() const { return mAsymID; }
std::string entityID() const { return mEntityID; }
std::string chainID() const;
int Distance(const Monomer& a, const Monomer& b) const;
int Distance(const Monomer &a, const Monomer &b) const;
private:
Structure* mStructure;
std::string mEntityID;
std::string mAsymID;
cif::RowSet mPolySeq;
Structure *mStructure;
std::string mEntityID;
std::string mAsymID;
cif::RowSet mPolySeq;
};
// --------------------------------------------------------------------
@@ -389,32 +397,34 @@ class File : public std::enable_shared_from_this<File>
{
public:
File();
File(const std::string& path);
File(const std::filesystem::path &path);
File(const char *data, size_t length); // good luck trying to find out what it is...
~File();
File(const File&) = delete;
File& operator=(const File&) = delete;
File(const File &) = delete;
File &operator=(const File &) = delete;
void load(const std::string& path);
void save(const std::string& path);
Structure* model(size_t nr = 1);
cif::Datablock& createDatablock(const std::string &name);
struct FileImpl& impl() const { return *mImpl; }
void load(const std::filesystem::path &path);
void save(const std::filesystem::path &path);
cif::Datablock& data();
cif::File& file();
Structure *model(size_t nr = 1);
struct FileImpl &impl() const { return *mImpl; }
cif::Datablock &data();
cif::File &file();
private:
struct FileImpl* mImpl;
struct FileImpl *mImpl;
};
// --------------------------------------------------------------------
enum class StructureOpenOptions
{
SkipHydrogen = 1 << 0
SkipHydrogen = 1 << 0
};
inline bool operator&(StructureOpenOptions a, StructureOpenOptions b)
@@ -427,86 +437,108 @@ inline bool operator&(StructureOpenOptions a, StructureOpenOptions b)
class Structure
{
public:
Structure(File& p, uint32_t modelNr = 1, StructureOpenOptions options = {});
Structure& operator=(const Structure&) = delete;
Structure(File &p, size_t modelNr = 1, StructureOpenOptions options = {});
Structure &operator=(const Structure &) = delete;
~Structure();
// Create a read-only clone of the current structure (for multithreaded calculations that move atoms)
Structure(const Structure&);
Structure(const Structure &);
File& getFile() const;
File &getFile() const;
const AtomView& atoms() const { return mAtoms; }
const AtomView &atoms() const { return mAtoms; }
AtomView waters() const;
const std::list<Polymer>& polymers() const { return mPolymers; }
std::list<Polymer>& polymers() { return mPolymers; }
const std::vector<Residue>& nonPolymers() const { return mNonPolymers; }
const std::vector<Residue>& branchResidues() const { return mBranchResidues; }
const std::list<Polymer> &polymers() const { return mPolymers; }
std::list<Polymer> &polymers() { return mPolymers; }
const std::vector<Residue> &nonPolymers() const { return mNonPolymers; }
const std::vector<Residue> &branchResidues() const { return mBranchResidues; }
Atom getAtomByID(std::string id) const;
// Atom getAtomByLocation(Point pt, float maxDistance) const;
Atom getAtomByLabel(const std::string& atomID, const std::string& asymID,
const std::string& compID, int seqID, const std::string& altID = "");
const Residue& getResidue(const std::string& asymID, const std::string& compID, int seqID) const;
Atom getAtomByLabel(const std::string &atomID, const std::string &asymID,
const std::string &compID, int seqID, const std::string &altID = "");
/// \brief Get a residue, if \a seqID is zero, the non-polymers are searched
const Residue &getResidue(const std::string &asymID, const std::string &compID, int seqID = 0) const;
// map between auth and label locations
std::tuple<std::string,int,std::string> MapAuthToLabel(const std::string& asymID,
const std::string& seqID, const std::string& compID, const std::string& insCode = "");
std::tuple<std::string,std::string,std::string,std::string> MapLabelToAuth(
const std::string& asymID, int seqID, const std::string& compID);
std::tuple<std::string, int, std::string> MapAuthToLabel(const std::string &asymID,
const std::string &seqID, const std::string &compID, const std::string &insCode = "");
std::tuple<std::string, std::string, std::string, std::string> MapLabelToAuth(
const std::string &asymID, int seqID, const std::string &compID);
// returns chain, seqnr, icode
std::tuple<char,int,char> MapLabelToAuth(
const std::string& asymID, int seqID) const;
std::tuple<char, int, char> MapLabelToAuth(
const std::string &asymID, int seqID) const;
// returns chain,seqnr,comp,iCode
std::tuple<std::string,int,std::string,std::string> MapLabelToPDB(
const std::string& asymID, int seqID, const std::string& compID,
const std::string& authSeqID) const;
std::tuple<std::string, int, std::string, std::string> MapLabelToPDB(
const std::string &asymID, int seqID, const std::string &compID,
const std::string &authSeqID) const;
std::tuple<std::string, int, std::string> MapPDBToLabel(
const std::string &asymID, int seqID, const std::string &compID, const std::string &iCode) const;
std::tuple<std::string,int,std::string> MapPDBToLabel(
const std::string& asymID, int seqID, const std::string& compID, const std::string& iCode) const;
// Actions
void removeAtom(Atom& a);
void swapAtoms(Atom& a1, Atom& a2); // swap the labels for these atoms
void moveAtom(Atom& a, Point p); // move atom to a new location
void changeResidue(const Residue& res, const std::string& newCompound,
const std::vector<std::tuple<std::string,std::string>>& remappedAtoms);
void removeAtom(Atom &a);
void swapAtoms(Atom &a1, Atom &a2); // swap the labels for these atoms
void moveAtom(Atom &a, Point p); // move atom to a new location
void changeResidue(const Residue &res, const std::string &newCompound,
const std::vector<std::tuple<std::string, std::string>> &remappedAtoms);
/// To sort the atoms in order of model > asym-id > res-id > atom-id
/// \brief Create a new non-polymer entity, returns new ID
/// \param mon_id The mon_id for the new nonpoly, must be an existing and known compound from CCD
/// \return The ID of the created entity
std::string createNonPolyEntity(const std::string &mon_id);
/// \brief Create a new NonPolymer struct_asym with atoms constructed from \a atoms, returns asym_id.
/// This method assumes you are copying data from one cif file to another.
///
/// \param entity_id The entity ID of the new nonpoly
/// \param atoms The array of atom_site rows containing the data.
/// \return The newly create asym ID
std::string createNonpoly(const std::string &entity_id, const std::vector<mmcif::Atom> &atoms);
/// \brief To sort the atoms in order of model > asym-id > res-id > atom-id
/// Will asssign new atom_id's to all atoms. Be carefull
void sortAtoms();
const std::vector<Residue>& getNonPolymers() const { return mNonPolymers; }
const std::vector<Residue>& getBranchResidues() const { return mBranchResidues; }
/// \brief Translate the coordinates of all atoms in the structure by \a t
void translate(Point t);
/// \brief Rotate the coordinates of all atoms in the structure by \a q
void rotate(Quaternion t);
const std::vector<Residue> &getNonPolymers() const { return mNonPolymers; }
const std::vector<Residue> &getBranchResidues() const { return mBranchResidues; }
void cleanupEmptyCategories();
private:
friend Polymer;
friend Residue;
// friend residue_view;
// friend residue_iterator;
cif::Category& category(const char* name) const;
cif::Datablock& datablock() const;
cif::Category &category(const char *name) const;
cif::Datablock &datablock() const;
std::string insertCompound(const std::string &compoundID, bool isEntity);
void insertCompound(const std::string& compoundID, bool isEntity);
void loadData();
void updateAtomIndex();
File& mFile;
uint32_t mModelNr;
AtomView mAtoms;
std::vector<size_t> mAtomIndex;
std::list<Polymer> mPolymers;
std::vector<Residue> mNonPolymers, mBranchResidues;
File &mFile;
size_t mModelNr;
AtomView mAtoms;
std::vector<size_t> mAtomIndex;
std::list<Polymer> mPolymers;
std::vector<Residue> mNonPolymers, mBranchResidues;
};
}
} // namespace mmcif

View File

@@ -26,9 +26,12 @@
#pragma once
#include <string>
#include <cstdint>
#include <array>
#include "CifUtils.hpp"
namespace mmcif
{
@@ -42,8 +45,8 @@ struct Spacegroup
int nr;
};
extern const Spacegroup kSpaceGroups[];
extern const std::size_t kNrOfSpaceGroups;
CIFPP_EXPORT extern const Spacegroup kSpaceGroups[];
CIFPP_EXPORT extern const std::size_t kNrOfSpaceGroups;
// --------------------------------------------------------------------
@@ -73,6 +76,27 @@ struct SymopData
return m_packed == rhs.m_packed;
}
std::array<int,15> data() const
{
return {
static_cast<int>(m_packed >> 34) bitand 0x03,
static_cast<int>(m_packed >> 32) bitand 0x03,
static_cast<int>(m_packed >> 30) bitand 0x03,
static_cast<int>(m_packed >> 28) bitand 0x03,
static_cast<int>(m_packed >> 26) bitand 0x03,
static_cast<int>(m_packed >> 24) bitand 0x03,
static_cast<int>(m_packed >> 22) bitand 0x03,
static_cast<int>(m_packed >> 20) bitand 0x03,
static_cast<int>(m_packed >> 18) bitand 0x03,
static_cast<int>(m_packed >> 15) bitand 0x07,
static_cast<int>(m_packed >> 12) bitand 0x07,
static_cast<int>(m_packed >> 9) bitand 0x07,
static_cast<int>(m_packed >> 6) bitand 0x07,
static_cast<int>(m_packed >> 3) bitand 0x07,
static_cast<int>(m_packed >> 0) bitand 0x07,
};
}
private:
friend struct SymopDataBlock;
@@ -104,8 +128,8 @@ struct SymopDataBlock
static_assert(sizeof(SymopDataBlock) == sizeof(uint64_t), "Size of SymopData is wrong");
extern const SymopDataBlock kSymopNrTable[];
extern const std::size_t kSymopNrTableSize;
CIFPP_EXPORT extern const SymopDataBlock kSymopNrTable[];
CIFPP_EXPORT extern const std::size_t kSymopNrTableSize;
// --------------------------------------------------------------------

View File

@@ -47,7 +47,7 @@ struct TLSResidue;
struct TLSSelection
{
virtual ~TLSSelection() {}
virtual void CollectResidues(cif::Datablock& db, std::vector<TLSResidue>& residues, int indentLevel = 0) const = 0;
virtual void CollectResidues(cif::Datablock& db, std::vector<TLSResidue>& residues, std::size_t indentLevel = 0) const = 0;
std::vector<std::tuple<std::string,int,int>> GetRanges(cif::Datablock& db, bool pdbNamespace) const;
};

View File

@@ -2,9 +2,11 @@ prefix=@prefix@
exec_prefix=@exec_prefix@
libdir=@libdir@
includedir=@includedir@
datalibdir=@datarootdir@/libcifpp
Name: libcifpp
Description: C++ library for the manipulation of mmCIF files.
Version: @PACKAGE_VERSION@
Libs: -L${libdir} -lcifpp
Cflags: -I${includedir}
Libs: -L${libdir} -lcifpp @PRIVATE_LIBS@
Cflags: -I${includedir} @PRIVATE_INC_DIRS@

File diff suppressed because it is too large Load Diff

View File

@@ -35,131 +35,131 @@ namespace mmcif
namespace data
{
const float kNA = std::nan("1");
const float kNA = std::nanf("1");
const AtomTypeInfo kKnownAtoms[] =
{
{ Nn, "Unknown", "Nn", 0, false, { kNA, kNA, kNA, kNA, kNA, kNA, kNA } }, // 0 Nn Unknown
{ H, "Hydrogen", "H", 1.008, false, { 53, 25, 37, 32, kNA, kNA, 120 } }, // 1 H Hydro­gen
{ He, "Helium", "He", 4.0026, false, { 31, kNA, 32, 46, kNA, kNA, 140 } }, // 2 He He­lium
{ Li, "Lithium", "Li", 6.94, true, { 167, 145, 134, 133, 124, kNA, 182 } }, // 3 Li Lith­ium
{ Be, "Beryllium", "Be", 9.0122, true, { 112, 105, 90, 102, 90, 85, kNA } }, // 4 Be Beryl­lium
{ B, "Boron", "B", 10.81, true, { 87, 85, 82, 85, 78, 73, kNA } }, // 5 B Boron
{ C, "Carbon", "C", 12.011, false, { 67, 70, 77, 75, 67, 60, 170 } }, // 6 C Carbon
{ N, "Nitrogen", "N", 14.007, false, { 56, 65, 75, 71, 60, 54, 155 } }, // 7 N Nitro­gen
{ O, "Oxygen", "O", 15.999, false, { 48, 60, 73, 63, 57, 53, 152 } }, // 8 O Oxy­gen
{ F, "Fluorine", "F", 18.998, false, { 42, 50, 71, 64, 59, 53, 147 } }, // 9 F Fluor­ine
{ Ne, "Neon", "Ne", 20.180, false, { 38, kNA, 69, 67, 96, kNA, 154 } }, // 10 Ne Neon
{ Na, "Sodium", "Na", 22.990, true, { 190, 180, 154, 155, 160, kNA, 227 } }, // 11 Na So­dium
{ Mg, "Magnesium", "Mg", 24.305, true, { 145, 150, 130, 139, 132, 127, 173 } }, // 12 Mg Magne­sium
{ Al, "Aluminium", "Al", 26.982, true, { 118, 125, 118, 126, 113, 111, kNA } }, // 13 Al Alumin­ium
{ Si, "Silicon", "Si", 28.085, true, { 111, 110, 111, 116, 107, 102, 210 } }, // 14 Si Sili­con
{ P, "Phosphorus", "P", 30.974, false, { 98, 100, 106, 111, 102, 94, 180 } }, // 15 P Phos­phorus
{ S, "Sulfur", "S", 32.06, false, { 88, 100, 102, 103, 94, 95, 180 } }, // 16 S Sulfur
{ Cl, "Chlorine", "Cl", 35.45, false, { 79, 100, 99, 99, 95, 93, 175 } }, // 17 Cl Chlor­ine
{ Ar, "Argon", "Ar", 39.948, false, { 71, kNA, 97, 96, 107, 96, 188 } }, // 18 Ar Argon
{ K, "Potassium", "K", 39.098, true, { 243, 220, 196, 196, 193, kNA, 275 } }, // 19 K Potas­sium
{ Ca, "Calcium", "Ca", 40.078, true, { 194, 180, 174, 171, 147, 133, kNA } }, // 20 Ca Cal­cium
{ Sc, "Scandium", "Sc", 44.956, true, { 184, 160, 144, 148, 116, 114, kNA } }, // 21 Sc Scan­dium
{ Ti, "Titanium", "Ti", 47.867, true, { 176, 140, 136, 136, 117, 108, kNA } }, // 22 Ti Tita­nium
{ V, "Vanadium", "V", 50.942, true, { 171, 135, 125, 134, 112, 106, kNA } }, // 23 V Vana­dium
{ Cr, "Chromium", "Cr", 51.996, true, { 166, 140, 127, 122, 111, 103, kNA } }, // 24 Cr Chrom­ium
{ Mn, "Manganese", "Mn", 54.938, true, { 161, 140, 139, 119, 105, 103, kNA } }, // 25 Mn Manga­nese
{ Fe, "Iron", "Fe", 55.845, true, { 156, 140, 125, 116, 109, 102, kNA } }, // 26 Fe Iron
{ Co, "Cobalt", "Co", 58.933, true, { 152, 135, 126, 111, 103, 96, kNA } }, // 27 Co Cobalt
{ Ni, "Nickel", "Ni", 58.693, true, { 149, 135, 121, 110, 101, 101, 163 } }, // 28 Ni Nickel
{ Cu, "Copper", "Cu", 63.546, true, { 145, 135, 138, 112, 115, 120, 140 } }, // 29 Cu Copper
{ Zn, "Zinc", "Zn", 65.38, true, { 142, 135, 131, 118, 120, kNA, 139 } }, // 30 Zn Zinc
{ Ga, "Gallium", "Ga", 69.723, true, { 136, 130, 126, 124, 117, 121, 187 } }, // 31 Ga Gallium
{ Ge, "Germanium", "Ge", 72.630, true, { 125, 125, 122, 121, 111, 114, kNA } }, // 32 Ge Germa­nium
{ As, "Arsenic", "As", 74.922, true, { 114, 115, 119, 121, 114, 106, 185 } }, // 33 As Arsenic
{ Se, "Selenium", "Se", 78.971, false, { 103, 115, 116, 116, 107, 107, 190 } }, // 34 Se Sele­nium
{ Br, "Bromine", "Br", 79.904, false, { 94, 115, 114, 114, 109, 110, 185 } }, // 35 Br Bromine
{ Kr, "Krypton", "Kr", 83.798, false, { 88, kNA, 110, 117, 121, 108, 202 } }, // 36 Kr Kryp­ton
{ Rb, "Rubidium", "Rb", 85.468, true, { 265, 235, 211, 210, 202, kNA, kNA } }, // 37 Rb Rubid­ium
{ Sr, "Strontium", "Sr", 87.62, true, { 219, 200, 192, 185, 157, 139, kNA } }, // 38 Sr Stront­ium
{ Y, "Yttrium", "Y", 88.906, true, { 212, 180, 162, 163, 130, 124, kNA } }, // 39 Y Yttrium
{ Zr, "Zirconium", "Zr", 91.224, true, { 206, 155, 148, 154, 127, 121, kNA } }, // 40 Zr Zirco­nium
{ Nb, "Niobium", "Nb", 92.906, true, { 198, 145, 137, 147, 125, 116, kNA } }, // 41 Nb Nio­bium
{ Mo, "Molybdenum", "Mo", 95.95, true, { 190, 145, 145, 138, 121, 113, kNA } }, // 42 Mo Molyb­denum
{ Tc, "Technetium", "Tc", 98, true, { 183, 135, 156, 128, 120, 110, kNA } }, // 43 Tc Tech­netium
{ Ru, "Ruthenium", "Ru", 101.07, true, { 178, 130, 126, 125, 114, 103, kNA } }, // 44 Ru Ruthe­nium
{ Rh, "Rhodium", "Rh", 102.91, true, { 173, 135, 135, 125, 110, 106, kNA } }, // 45 Rh Rho­dium
{ Pd, "Palladium", "Pd", 106.42, true, { 169, 140, 131, 120, 117, 112, 163 } }, // 46 Pd Pallad­ium
{ Ag, "Silver", "Ag", 107.87, true, { 165, 160, 153, 128, 139, 137, 172 } }, // 47 Ag Silver
{ Cd, "Cadmium", "Cd", 112.41, true, { 161, 155, 148, 136, 144, kNA, 158 } }, // 48 Cd Cad­mium
{ In, "Indium", "In", 114.82, true, { 156, 155, 144, 142, 136, 146, 193 } }, // 49 In Indium
{ Sn, "Tin", "Sn", 118.71, true, { 145, 145, 141, 140, 130, 132, 217 } }, // 50 Sn Tin
{ Sb, "Antimony", "Sb", 121.76, false, { 133, 145, 138, 140, 133, 127, kNA } }, // 51 Sb Anti­mony
{ Te, "Tellurium", "Te", 127.60, false, { 123, 140, 135, 136, 128, 121, 206 } }, // 52 Te Tellurium
{ I, "Iodine", "I", 126.90, false, { 115, 140, 133, 133, 129, 125, 198 } }, // 53 I Iodine
{ Xe, "Xenon", "Xe", 131.29, false, { 108, kNA, 130, 131, 135, 122, 216 } }, // 54 Xe Xenon
{ Cs, "Caesium", "Cs", 132.91, true, { 298, 260, 225, 232, 209, kNA, kNA } }, // 55 Cs Cae­sium
{ Ba, "Barium", "Ba", 137.33, true, { 253, 215, 198, 196, 161, 149, kNA } }, // 56 Ba Ba­rium
{ La, "Lanthanum", "La", 138.91, true, { kNA, 195, 169, 180, 139, 139, kNA } }, // 57 La Lan­thanum
{ Ce, "Cerium", "Ce", 140.12, true, { kNA, 185, kNA, 163, 137, 131, kNA } }, // 58 Ce Cerium
{ Pr, "Praseodymium", "Pr", 140.91, true, { 247, 185, kNA, 176, 138, 128, kNA } }, // 59 Pr Praseo­dymium
{ Nd, "Neodymium", "Nd", 144.24, true, { 206, 185, kNA, 174, 137, kNA, kNA } }, // 60 Nd Neo­dymium
{ Pm, "Promethium", "Pm", 145, true, { 205, 185, kNA, 173, 135, kNA, kNA } }, // 61 Pm Prome­thium
{ Sm, "Samarium", "Sm", 150.36, true, { 238, 185, kNA, 172, 134, kNA, kNA } }, // 62 Sm Sama­rium
{ Eu, "Europium", "Eu", 151.96, true, { 231, 185, kNA, 168, 134, kNA, kNA } }, // 63 Eu Europ­ium
{ Gd, "Gadolinium", "Gd", 157.25, true, { 233, 180, kNA, 169, 135, 132, kNA } }, // 64 Gd Gadolin­ium
{ Tb, "Terbium", "Tb", 158.93, true, { 225, 175, kNA, 168, 135, kNA, kNA } }, // 65 Tb Ter­bium
{ Dy, "Dysprosium", "Dy", 162.50, true, { 228, 175, kNA, 167, 133, kNA, kNA } }, // 66 Dy Dyspro­sium
{ Ho, "Holmium", "Ho", 164.93, true, { 226, 175, kNA, 166, 133, kNA, kNA } }, // 67 Ho Hol­mium
{ Er, "Erbium", "Er", 167.26, true, { 226, 175, kNA, 165, 133, kNA, kNA } }, // 68 Er Erbium
{ Tm, "Thulium", "Tm", 168.93, true, { 222, 175, kNA, 164, 131, kNA, kNA } }, // 69 Tm Thulium
{ Yb, "Ytterbium", "Yb", 173.05, true, { 222, 175, kNA, 170, 129, kNA, kNA } }, // 70 Yb Ytter­bium
{ Lu, "Lutetium", "Lu", 174.97, true, { 217, 175, 160, 162, 131, 131, kNA } }, // 71 Lu Lute­tium
{ Hf, "Hafnium", "Hf", 178.49, true, { 208, 155, 150, 152, 128, 122, kNA } }, // 72 Hf Haf­nium
{ Ta, "Tantalum", "Ta", 180.95, true, { 200, 145, 138, 146, 126, 119, kNA } }, // 73 Ta Tanta­lum
{ W, "Tungsten", "W", 183.84, true, { 193, 135, 146, 137, 120, 115, kNA } }, // 74 W Tung­sten
{ Re, "Rhenium", "Re", 186.21, true, { 188, 135, 159, 131, 119, 110, kNA } }, // 75 Re Rhe­nium
{ Os, "Osmium", "Os", 190.23, true, { 185, 130, 128, 129, 116, 109, kNA } }, // 76 Os Os­mium
{ Ir, "Iridium", "Ir", 192.22, true, { 180, 135, 137, 122, 115, 107, kNA } }, // 77 Ir Iridium
{ Pt, "Platinum", "Pt", 195.08, true, { 177, 135, 128, 123, 112, 110, 175 } }, // 78 Pt Plat­inum
{ Au, "Gold", "Au", 196.97, true, { 174, 135, 144, 124, 121, 123, 166 } }, // 79 Au Gold
{ Hg, "Mercury", "Hg", 200.59, true, { 171, 150, 149, 133, 142, kNA, 155 } }, // 80 Hg Mer­cury
{ Tl, "Thallium", "Tl", 204.38, true, { 156, 190, 148, 144, 142, 150, 196 } }, // 81 Tl Thallium
{ Pb, "Lead", "Pb", 207.2, true, { 154, 180, 147, 144, 135, 137, 202 } }, // 82 Pb Lead
{ Bi, "Bismuth", "Bi", 208.98, true, { 143, 160, 146, 151, 141, 135, kNA } }, // 83 Bi Bis­muth
{ Po, "Polonium", "Po", 209, true, { 135, 190, kNA, 145, 135, 129, kNA } }, // 84 Po Polo­nium
{ At, "Astatine", "At", 210, false, { 127, kNA, kNA, 147, 138, 138, kNA } }, // 85 At Asta­tine
{ Rn, "Radon", "Rn", 222, false, { 120, kNA, 145, 142, 145, 133, kNA } }, // 86 Rn Radon
{ Fr, "Francium", "Fr", 223, true, { kNA, kNA, kNA, 223, 218, kNA, kNA } }, // 87 Fr Fran­cium
{ Ra, "Radium", "Ra", 226, true, { kNA, 215, kNA, 201, 173, 159, kNA } }, // 88 Ra Ra­dium
{ Ac, "Actinium", "Ac", 227, true, { kNA, 195, kNA, 186, 153, 140, kNA } }, // 89 Ac Actin­ium
{ Th, "Thorium", "Th", 232.04, true, { kNA, 180, kNA, 175, 143, 136, kNA } }, // 90 Th Thor­ium
{ Pa, "Protactinium", "Pa", 231.04, true, { kNA, 180, kNA, 169, 138, 129, kNA } }, // 91 Pa Protac­tinium
{ U, "Uranium", "U", 238.03, true, { kNA, 175, kNA, 170, 134, 118, 186 } }, // 92 U Ura­nium
{ Np, "Neptunium", "Np", 237, true, { kNA, 175, kNA, 171, 136, 116, kNA } }, // 93 Np Neptu­nium
{ Pu, "Plutonium", "Pu", 244, true, { kNA, 175, kNA, 172, 135, kNA, kNA } }, // 94 Pu Pluto­nium
{ Am, "Americium", "Am", 243, true, { kNA, 175, kNA, 166, 135, kNA, kNA } }, // 95 Am Ameri­cium
{ Cm, "Curium", "Cm", 247, true, { kNA, kNA, kNA, 166, 136, kNA, kNA } }, // 96 Cm Curium
{ Bk, "Berkelium", "Bk", 247, true, { kNA, kNA, kNA, 168, 139, kNA, kNA } }, // 97 Bk Berkel­ium
{ Cf, "Californium", "Cf", 251, true, { kNA, kNA, kNA, 168, 140, kNA, kNA } }, // 98 Cf Califor­nium
{ Es, "Einsteinium", "Es", 252, true, { kNA, kNA, kNA, 165, 140, kNA, kNA } }, // 99 Es Einstei­nium
{ Fm, "Fermium", "Fm", 257, true, { kNA, kNA, kNA, 167, kNA, kNA, kNA } }, // 100 Fm Fer­mium
{ Md, "Mendelevium", "Md", 258, true, { kNA, kNA, kNA, 173, 139, kNA, kNA } }, // 101 Md Mende­levium
{ No, "Nobelium", "No", 259, true, { kNA, kNA, kNA, 176, kNA, kNA, kNA } }, // 102 No Nobel­ium
{ Lr, "Lawrencium", "Lr", 266, true, { kNA, kNA, kNA, 161, 141, kNA, kNA } }, // 103 Lr Lawren­cium
{ Rf, "Rutherfordium", "Rf", 267, true, { kNA, kNA, kNA, 157, 140, 131, kNA } }, // 104 Rf Ruther­fordium
{ Db, "Dubnium", "Db", 268, true, { kNA, kNA, kNA, 149, 136, 126, kNA } }, // 105 Db Dub­nium
{ Sg, "Seaborgium", "Sg", 269, true, { kNA, kNA, kNA, 143, 128, 121, kNA } }, // 106 Sg Sea­borgium
{ Bh, "Bohrium", "Bh", 270, true, { kNA, kNA, kNA, 141, 128, 119, kNA } }, // 107 Bh Bohr­ium
{ Hs, "Hassium", "Hs", 277, true, { kNA, kNA, kNA, 134, 125, 118, kNA } }, // 108 Hs Has­sium
{ Mt, "Meitnerium", "Mt", 278, true, { kNA, kNA, kNA, 129, 125, 113, kNA } }, // 109 Mt Meit­nerium
{ Ds, "Darmstadtium", "Ds", 281, true, { kNA, kNA, kNA, 128, 116, 112, kNA } }, // 110 Ds Darm­stadtium
{ Rg, "Roentgenium", "Rg", 282, true, { kNA, kNA, kNA, 121, 116, 118, kNA } }, // 111 Rg Roent­genium
{ Cn, "Copernicium", "Cn", 285, true, { kNA, kNA, kNA, 122, 137, 130, kNA } }, // 112 Cn Coper­nicium
{ Nh, "Nihonium", "Nh", 286, true, { kNA, kNA, kNA, 136, kNA, kNA, kNA } }, // 113 Nh Nihon­ium
{ Fl, "Flerovium", "Fl", 289, true, { kNA, kNA, kNA, 143, kNA, kNA, kNA } }, // 114 Fl Flerov­ium
{ Mc, "Moscovium", "Mc", 290, true, { kNA, kNA, kNA, 162, kNA, kNA, kNA } }, // 115 Mc Moscov­ium
{ Lv, "Livermorium", "Lv", 293, true, { kNA, kNA, kNA, 175, kNA, kNA, kNA } }, // 116 Lv Liver­morium
{ Ts, "Tennessine", "Ts", 294, true, { kNA, kNA, kNA, 165, kNA, kNA, kNA } }, // 117 Ts Tenness­ine
{ Og, "Oganesson", "Og", 294, true, { kNA, kNA, kNA, 157, kNA, kNA, kNA } }, // 118 Og Oga­nesson
{ Nn, "Unknown", "Nn", 0, false, { kNA, kNA, kNA, kNA, kNA, kNA, kNA } }, // 0 Nn Unknown
{ H, "Hydrogen", "H", 1.008f, false, { 53, 25, 37, 32, kNA, kNA, 120 } }, // 1 H Hydro­gen
{ He, "Helium", "He", 4.0026f, false, { 31, kNA, 32, 46, kNA, kNA, 140 } }, // 2 He He­lium
{ Li, "Lithium", "Li", 6.94f, true, { 167, 145, 134, 133, 124, kNA, 182 } }, // 3 Li Lith­ium
{ Be, "Beryllium", "Be", 9.0122f, true, { 112, 105, 90, 102, 90, 85, kNA } }, // 4 Be Beryl­lium
{ B, "Boron", "B", 10.81f, true, { 87, 85, 82, 85, 78, 73, kNA } }, // 5 B Boron
{ C, "Carbon", "C", 12.011f, false, { 67, 70, 77, 75, 67, 60, 170 } }, // 6 C Carbon
{ N, "Nitrogen", "N", 14.007f, false, { 56, 65, 75, 71, 60, 54, 155 } }, // 7 N Nitro­gen
{ O, "Oxygen", "O", 15.999f, false, { 48, 60, 73, 63, 57, 53, 152 } }, // 8 O Oxy­gen
{ F, "Fluorine", "F", 18.998f, false, { 42, 50, 71, 64, 59, 53, 147 } }, // 9 F Fluor­ine
{ Ne, "Neon", "Ne", 20.180f, false, { 38, kNA, 69, 67, 96, kNA, 154 } }, // 10 Ne Neon
{ Na, "Sodium", "Na", 22.990f, true, { 190, 180, 154, 155, 160, kNA, 227 } }, // 11 Na So­dium
{ Mg, "Magnesium", "Mg", 24.305f, true, { 145, 150, 130, 139, 132, 127, 173 } }, // 12 Mg Magne­sium
{ Al, "Aluminium", "Al", 26.982f, true, { 118, 125, 118, 126, 113, 111, kNA } }, // 13 Al Alumin­ium
{ Si, "Silicon", "Si", 28.085f, true, { 111, 110, 111, 116, 107, 102, 210 } }, // 14 Si Sili­con
{ P, "Phosphorus", "P", 30.974f, false, { 98, 100, 106, 111, 102, 94, 180 } }, // 15 P Phos­phorus
{ S, "Sulfur", "S", 32.06f, false, { 88, 100, 102, 103, 94, 95, 180 } }, // 16 S Sulfur
{ Cl, "Chlorine", "Cl", 35.45f, false, { 79, 100, 99, 99, 95, 93, 175 } }, // 17 Cl Chlor­ine
{ Ar, "Argon", "Ar", 39.948f, false, { 71, kNA, 97, 96, 107, 96, 188 } }, // 18 Ar Argon
{ K, "Potassium", "K", 39.098f, true, { 243, 220, 196, 196, 193, kNA, 275 } }, // 19 K Potas­sium
{ Ca, "Calcium", "Ca", 40.078f, true, { 194, 180, 174, 171, 147, 133, kNA } }, // 20 Ca Cal­cium
{ Sc, "Scandium", "Sc", 44.956f, true, { 184, 160, 144, 148, 116, 114, kNA } }, // 21 Sc Scan­dium
{ Ti, "Titanium", "Ti", 47.867f, true, { 176, 140, 136, 136, 117, 108, kNA } }, // 22 Ti Tita­nium
{ V, "Vanadium", "V", 50.942f, true, { 171, 135, 125, 134, 112, 106, kNA } }, // 23 V Vana­dium
{ Cr, "Chromium", "Cr", 51.996f, true, { 166, 140, 127, 122, 111, 103, kNA } }, // 24 Cr Chrom­ium
{ Mn, "Manganese", "Mn", 54.938f, true, { 161, 140, 139, 119, 105, 103, kNA } }, // 25 Mn Manga­nese
{ Fe, "Iron", "Fe", 55.845f, true, { 156, 140, 125, 116, 109, 102, kNA } }, // 26 Fe Iron
{ Co, "Cobalt", "Co", 58.933f, true, { 152, 135, 126, 111, 103, 96, kNA } }, // 27 Co Cobalt
{ Ni, "Nickel", "Ni", 58.693f, true, { 149, 135, 121, 110, 101, 101, 163 } }, // 28 Ni Nickel
{ Cu, "Copper", "Cu", 63.546f, true, { 145, 135, 138, 112, 115, 120, 140 } }, // 29 Cu Copper
{ Zn, "Zinc", "Zn", 65.38f, true, { 142, 135, 131, 118, 120, kNA, 139 } }, // 30 Zn Zinc
{ Ga, "Gallium", "Ga", 69.723f, true, { 136, 130, 126, 124, 117, 121, 187 } }, // 31 Ga Gallium
{ Ge, "Germanium", "Ge", 72.630f, true, { 125, 125, 122, 121, 111, 114, kNA } }, // 32 Ge Germa­nium
{ As, "Arsenic", "As", 74.922f, true, { 114, 115, 119, 121, 114, 106, 185 } }, // 33 As Arsenic
{ Se, "Selenium", "Se", 78.971f, false, { 103, 115, 116, 116, 107, 107, 190 } }, // 34 Se Sele­nium
{ Br, "Bromine", "Br", 79.904f, false, { 94, 115, 114, 114, 109, 110, 185 } }, // 35 Br Bromine
{ Kr, "Krypton", "Kr", 83.798f, false, { 88, kNA, 110, 117, 121, 108, 202 } }, // 36 Kr Kryp­ton
{ Rb, "Rubidium", "Rb", 85.468f, true, { 265, 235, 211, 210, 202, kNA, kNA } }, // 37 Rb Rubid­ium
{ Sr, "Strontium", "Sr", 87.62f, true, { 219, 200, 192, 185, 157, 139, kNA } }, // 38 Sr Stront­ium
{ Y, "Yttrium", "Y", 88.906f, true, { 212, 180, 162, 163, 130, 124, kNA } }, // 39 Y Yttrium
{ Zr, "Zirconium", "Zr", 91.224f, true, { 206, 155, 148, 154, 127, 121, kNA } }, // 40 Zr Zirco­nium
{ Nb, "Niobium", "Nb", 92.906f, true, { 198, 145, 137, 147, 125, 116, kNA } }, // 41 Nb Nio­bium
{ Mo, "Molybdenum", "Mo", 95.95f, true, { 190, 145, 145, 138, 121, 113, kNA } }, // 42 Mo Molyb­denum
{ Tc, "Technetium", "Tc", 98, true, { 183, 135, 156, 128, 120, 110, kNA } }, // 43 Tc Tech­netium
{ Ru, "Ruthenium", "Ru", 101.07f, true, { 178, 130, 126, 125, 114, 103, kNA } }, // 44 Ru Ruthe­nium
{ Rh, "Rhodium", "Rh", 102.91f, true, { 173, 135, 135, 125, 110, 106, kNA } }, // 45 Rh Rho­dium
{ Pd, "Palladium", "Pd", 106.42f, true, { 169, 140, 131, 120, 117, 112, 163 } }, // 46 Pd Pallad­ium
{ Ag, "Silver", "Ag", 107.87f, true, { 165, 160, 153, 128, 139, 137, 172 } }, // 47 Ag Silver
{ Cd, "Cadmium", "Cd", 112.41f, true, { 161, 155, 148, 136, 144, kNA, 158 } }, // 48 Cd Cad­mium
{ In, "Indium", "In", 114.82f, true, { 156, 155, 144, 142, 136, 146, 193 } }, // 49 In Indium
{ Sn, "Tin", "Sn", 118.71f, true, { 145, 145, 141, 140, 130, 132, 217 } }, // 50 Sn Tin
{ Sb, "Antimony", "Sb", 121.76f, false, { 133, 145, 138, 140, 133, 127, kNA } }, // 51 Sb Anti­mony
{ Te, "Tellurium", "Te", 127.60f, false, { 123, 140, 135, 136, 128, 121, 206 } }, // 52 Te Tellurium
{ I, "Iodine", "I", 126.90f, false, { 115, 140, 133, 133, 129, 125, 198 } }, // 53 I Iodine
{ Xe, "Xenon", "Xe", 131.29f, false, { 108, kNA, 130, 131, 135, 122, 216 } }, // 54 Xe Xenon
{ Cs, "Caesium", "Cs", 132.91f, true, { 298, 260, 225, 232, 209, kNA, kNA } }, // 55 Cs Cae­sium
{ Ba, "Barium", "Ba", 137.33f, true, { 253, 215, 198, 196, 161, 149, kNA } }, // 56 Ba Ba­rium
{ La, "Lanthanum", "La", 138.91f, true, { kNA, 195, 169, 180, 139, 139, kNA } }, // 57 La Lan­thanum
{ Ce, "Cerium", "Ce", 140.12f, true, { kNA, 185, kNA, 163, 137, 131, kNA } }, // 58 Ce Cerium
{ Pr, "Praseodymium", "Pr", 140.91f, true, { 247, 185, kNA, 176, 138, 128, kNA } }, // 59 Pr Praseo­dymium
{ Nd, "Neodymium", "Nd", 144.24f, true, { 206, 185, kNA, 174, 137, kNA, kNA } }, // 60 Nd Neo­dymium
{ Pm, "Promethium", "Pm", 145, true, { 205, 185, kNA, 173, 135, kNA, kNA } }, // 61 Pm Prome­thium
{ Sm, "Samarium", "Sm", 150.36f, true, { 238, 185, kNA, 172, 134, kNA, kNA } }, // 62 Sm Sama­rium
{ Eu, "Europium", "Eu", 151.96f, true, { 231, 185, kNA, 168, 134, kNA, kNA } }, // 63 Eu Europ­ium
{ Gd, "Gadolinium", "Gd", 157.25f, true, { 233, 180, kNA, 169, 135, 132, kNA } }, // 64 Gd Gadolin­ium
{ Tb, "Terbium", "Tb", 158.93f, true, { 225, 175, kNA, 168, 135, kNA, kNA } }, // 65 Tb Ter­bium
{ Dy, "Dysprosium", "Dy", 162.50f, true, { 228, 175, kNA, 167, 133, kNA, kNA } }, // 66 Dy Dyspro­sium
{ Ho, "Holmium", "Ho", 164.93f, true, { 226, 175, kNA, 166, 133, kNA, kNA } }, // 67 Ho Hol­mium
{ Er, "Erbium", "Er", 167.26f, true, { 226, 175, kNA, 165, 133, kNA, kNA } }, // 68 Er Erbium
{ Tm, "Thulium", "Tm", 168.93f, true, { 222, 175, kNA, 164, 131, kNA, kNA } }, // 69 Tm Thulium
{ Yb, "Ytterbium", "Yb", 173.05f, true, { 222, 175, kNA, 170, 129, kNA, kNA } }, // 70 Yb Ytter­bium
{ Lu, "Lutetium", "Lu", 174.97f, true, { 217, 175, 160, 162, 131, 131, kNA } }, // 71 Lu Lute­tium
{ Hf, "Hafnium", "Hf", 178.49f, true, { 208, 155, 150, 152, 128, 122, kNA } }, // 72 Hf Haf­nium
{ Ta, "Tantalum", "Ta", 180.95f, true, { 200, 145, 138, 146, 126, 119, kNA } }, // 73 Ta Tanta­lum
{ W, "Tungsten", "W", 183.84f, true, { 193, 135, 146, 137, 120, 115, kNA } }, // 74 W Tung­sten
{ Re, "Rhenium", "Re", 186.21f, true, { 188, 135, 159, 131, 119, 110, kNA } }, // 75 Re Rhe­nium
{ Os, "Osmium", "Os", 190.23f, true, { 185, 130, 128, 129, 116, 109, kNA } }, // 76 Os Os­mium
{ Ir, "Iridium", "Ir", 192.22f, true, { 180, 135, 137, 122, 115, 107, kNA } }, // 77 Ir Iridium
{ Pt, "Platinum", "Pt", 195.08f, true, { 177, 135, 128, 123, 112, 110, 175 } }, // 78 Pt Plat­inum
{ Au, "Gold", "Au", 196.97f, true, { 174, 135, 144, 124, 121, 123, 166 } }, // 79 Au Gold
{ Hg, "Mercury", "Hg", 200.59f, true, { 171, 150, 149, 133, 142, kNA, 155 } }, // 80 Hg Mer­cury
{ Tl, "Thallium", "Tl", 204.38f, true, { 156, 190, 148, 144, 142, 150, 196 } }, // 81 Tl Thallium
{ Pb, "Lead", "Pb", 207.2f, true, { 154, 180, 147, 144, 135, 137, 202 } }, // 82 Pb Lead
{ Bi, "Bismuth", "Bi", 208.98f, true, { 143, 160, 146, 151, 141, 135, kNA } }, // 83 Bi Bis­muth
{ Po, "Polonium", "Po", 209, true, { 135, 190, kNA, 145, 135, 129, kNA } }, // 84 Po Polo­nium
{ At, "Astatine", "At", 210, false, { 127, kNA, kNA, 147, 138, 138, kNA } }, // 85 At Asta­tine
{ Rn, "Radon", "Rn", 222, false, { 120, kNA, 145, 142, 145, 133, kNA } }, // 86 Rn Radon
{ Fr, "Francium", "Fr", 223, true, { kNA, kNA, kNA, 223, 218, kNA, kNA } }, // 87 Fr Fran­cium
{ Ra, "Radium", "Ra", 226, true, { kNA, 215, kNA, 201, 173, 159, kNA } }, // 88 Ra Ra­dium
{ Ac, "Actinium", "Ac", 227, true, { kNA, 195, kNA, 186, 153, 140, kNA } }, // 89 Ac Actin­ium
{ Th, "Thorium", "Th", 232.04f, true, { kNA, 180, kNA, 175, 143, 136, kNA } }, // 90 Th Thor­ium
{ Pa, "Protactinium", "Pa", 231.04f, true, { kNA, 180, kNA, 169, 138, 129, kNA } }, // 91 Pa Protac­tinium
{ U, "Uranium", "U", 238.03f, true, { kNA, 175, kNA, 170, 134, 118, 186 } }, // 92 U Ura­nium
{ Np, "Neptunium", "Np", 237, true, { kNA, 175, kNA, 171, 136, 116, kNA } }, // 93 Np Neptu­nium
{ Pu, "Plutonium", "Pu", 244, true, { kNA, 175, kNA, 172, 135, kNA, kNA } }, // 94 Pu Pluto­nium
{ Am, "Americium", "Am", 243, true, { kNA, 175, kNA, 166, 135, kNA, kNA } }, // 95 Am Ameri­cium
{ Cm, "Curium", "Cm", 247, true, { kNA, kNA, kNA, 166, 136, kNA, kNA } }, // 96 Cm Curium
{ Bk, "Berkelium", "Bk", 247, true, { kNA, kNA, kNA, 168, 139, kNA, kNA } }, // 97 Bk Berkel­ium
{ Cf, "Californium", "Cf", 251, true, { kNA, kNA, kNA, 168, 140, kNA, kNA } }, // 98 Cf Califor­nium
{ Es, "Einsteinium", "Es", 252, true, { kNA, kNA, kNA, 165, 140, kNA, kNA } }, // 99 Es Einstei­nium
{ Fm, "Fermium", "Fm", 257, true, { kNA, kNA, kNA, 167, kNA, kNA, kNA } }, // 100 Fm Fer­mium
{ Md, "Mendelevium", "Md", 258, true, { kNA, kNA, kNA, 173, 139, kNA, kNA } }, // 101 Md Mende­levium
{ No, "Nobelium", "No", 259, true, { kNA, kNA, kNA, 176, kNA, kNA, kNA } }, // 102 No Nobel­ium
{ Lr, "Lawrencium", "Lr", 266, true, { kNA, kNA, kNA, 161, 141, kNA, kNA } }, // 103 Lr Lawren­cium
{ Rf, "Rutherfordium", "Rf", 267, true, { kNA, kNA, kNA, 157, 140, 131, kNA } }, // 104 Rf Ruther­fordium
{ Db, "Dubnium", "Db", 268, true, { kNA, kNA, kNA, 149, 136, 126, kNA } }, // 105 Db Dub­nium
{ Sg, "Seaborgium", "Sg", 269, true, { kNA, kNA, kNA, 143, 128, 121, kNA } }, // 106 Sg Sea­borgium
{ Bh, "Bohrium", "Bh", 270, true, { kNA, kNA, kNA, 141, 128, 119, kNA } }, // 107 Bh Bohr­ium
{ Hs, "Hassium", "Hs", 277, true, { kNA, kNA, kNA, 134, 125, 118, kNA } }, // 108 Hs Has­sium
{ Mt, "Meitnerium", "Mt", 278, true, { kNA, kNA, kNA, 129, 125, 113, kNA } }, // 109 Mt Meit­nerium
{ Ds, "Darmstadtium", "Ds", 281, true, { kNA, kNA, kNA, 128, 116, 112, kNA } }, // 110 Ds Darm­stadtium
{ Rg, "Roentgenium", "Rg", 282, true, { kNA, kNA, kNA, 121, 116, 118, kNA } }, // 111 Rg Roent­genium
{ Cn, "Copernicium", "Cn", 285, true, { kNA, kNA, kNA, 122, 137, 130, kNA } }, // 112 Cn Coper­nicium
{ Nh, "Nihonium", "Nh", 286, true, { kNA, kNA, kNA, 136, kNA, kNA, kNA } }, // 113 Nh Nihon­ium
{ Fl, "Flerovium", "Fl", 289, true, { kNA, kNA, kNA, 143, kNA, kNA, kNA } }, // 114 Fl Flerov­ium
{ Mc, "Moscovium", "Mc", 290, true, { kNA, kNA, kNA, 162, kNA, kNA, kNA } }, // 115 Mc Moscov­ium
{ Lv, "Livermorium", "Lv", 293, true, { kNA, kNA, kNA, 175, kNA, kNA, kNA } }, // 116 Lv Liver­morium
{ Ts, "Tennessine", "Ts", 294, true, { kNA, kNA, kNA, 165, kNA, kNA, kNA } }, // 117 Ts Tenness­ine
{ Og, "Oganesson", "Og", 294, true, { kNA, kNA, kNA, 157, kNA, kNA, kNA } }, // 118 Og Oga­nesson
{ D, "Deuterium", "D", 2.014, false, { 53, 25, 37, 32, kNA, kNA, 120 } }, // 1 D Deuterium
{ D, "Deuterium", "D", 2.014f, false, { 53, 25, 37, 32, kNA, kNA, 120 } }, // 1 D Deuterium
};
uint32_t kKnownAtomsCount = sizeof(kKnownAtoms) / sizeof(AtomTypeInfo);

627
src/BondMap.cpp Normal file
View File

@@ -0,0 +1,627 @@
/*-
* SPDX-License-Identifier: BSD-2-Clause
*
* Copyright (c) 2020 NKI/AVL, Netherlands Cancer Institute
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <fstream>
#include <algorithm>
#include <mutex>
#include "cif++/Cif++.hpp"
#include "cif++/Compound.hpp"
#include "cif++/CifUtils.hpp"
#include "cif++/BondMap.hpp"
namespace mmcif
{
namespace
{
union IDType
{
IDType() : id_n(0){}
IDType(const IDType& rhs) : id_n(rhs.id_n) {}
IDType(const std::string& s)
: IDType()
{
assert(s.length() <= 4);
if (s.length() > 4)
throw BondMapException("Atom ID '" + s + "' is too long");
std::copy(s.begin(), s.end(), id_s);
}
IDType& operator=(const IDType& rhs)
{
id_n = rhs.id_n;
return *this;
}
IDType& operator=(const std::string& s)
{
id_n = 0;
assert(s.length() <= 4);
if (s.length() > 4)
throw BondMapException("Atom ID '" + s + "' is too long");
std::copy(s.begin(), s.end(), id_s);
return *this;
}
bool operator<(const IDType& rhs) const
{
return id_n < rhs.id_n;
}
bool operator<=(const IDType& rhs) const
{
return id_n <= rhs.id_n;
}
bool operator==(const IDType& rhs) const
{
return id_n == rhs.id_n;
}
bool operator!=(const IDType& rhs) const
{
return id_n != rhs.id_n;
}
char id_s[4];
uint32_t id_n;
};
static_assert(sizeof(IDType) == 4, "atom_id_type should be 4 bytes");
}
// // --------------------------------------------------------------------
// void createBondInfoFile(const fs::path& components, const fs::path& infofile)
// {
// std::ofstream outfile(infofile.string() + ".tmp", std::ios::binary);
// if (not outfile.is_open())
// throw BondMapException("Could not create bond info file " + infofile.string() + ".tmp");
// cif::File infile(components);
// std::set<atom_id_type> atomIDs;
// std::vector<atom_id_type> compoundIDs;
// for (auto& db: infile)
// {
// auto chem_comp_bond = db.get("chem_comp_bond");
// if (not chem_comp_bond)
// {
// if (cif::VERBOSE > 1)
// std::cerr << "Missing chem_comp_bond category in data block " << db.getName() << std::endl;
// continue;
// }
// for (const auto& [atom_id_1, atom_id_2]: chem_comp_bond->rows<std::string,std::string>({"atom_id_1", "atom_id_2"}))
// {
// atomIDs.insert(atom_id_1);
// atomIDs.insert(atom_id_2);
// }
// compoundIDs.push_back({ db.getName() });
// }
// if (cif::VERBOSE)
// std::cout << "Number of unique atom names is " << atomIDs.size() << std::endl
// << "Number of unique residue names is " << compoundIDs.size() << std::endl;
// CompoundBondInfoFileHeader header = {};
// header.indexEntries = compoundIDs.size();
// header.atomEntries = atomIDs.size();
// outfile << header;
// for (auto atomID: atomIDs)
// outfile << atomID;
// auto dataOffset = outfile.tellp();
// std::vector<CompoundBondInfo> entries;
// entries.reserve(compoundIDs.size());
// std::map<atom_id_type, uint16_t> atomIDMap;
// for (auto& atomID: atomIDs)
// atomIDMap[atomID] = atomIDMap.size();
// for (auto& db: infile)
// {
// auto chem_comp_bond = db.get("chem_comp_bond");
// if (not chem_comp_bond)
// continue;
// std::set<uint16_t> bondedAtoms;
// for (const auto& [atom_id_1, atom_id_2]: chem_comp_bond->rows<std::string,std::string>({"atom_id_1", "atom_id_2"}))
// {
// bondedAtoms.insert(atomIDMap[atom_id_1]);
// bondedAtoms.insert(atomIDMap[atom_id_2]);
// }
// std::map<uint16_t, int32_t> bondedAtomMap;
// for (auto id: bondedAtoms)
// bondedAtomMap[id] = static_cast<int32_t>(bondedAtomMap.size());
// CompoundBondInfo info = {
// db.getName(),
// static_cast<uint32_t>(bondedAtomMap.size()),
// outfile.tellp() - dataOffset
// };
// entries.push_back(info);
// // An now first write the array of atom ID's in this compound
// for (uint16_t id: bondedAtoms)
// write(outfile, id);
// // And then the symmetric matrix with bonds
// size_t N = bondedAtoms.size();
// size_t M = (N * (N - 1)) / 2;
// size_t K = M / 8;
// if (M % 8)
// K += 1;
// std::vector<uint8_t> m(K);
// for (const auto& [atom_id_1, atom_id_2]: chem_comp_bond->rows<std::string,std::string>({"atom_id_1", "atom_id_2"}))
// {
// auto a = bondedAtomMap[atomIDMap[atom_id_1]];
// auto b = bondedAtomMap[atomIDMap[atom_id_2]];
// assert(a != b);
// assert((int)b < (int)N);
// if (a > b)
// std::swap(a, b);
// size_t ix = ((b - 1) * b) / 2 + a;
// assert(ix < M);
// auto Bix = ix / 8;
// auto bix = ix % 8;
// m[Bix] |= 1 << bix;
// }
// outfile.write(reinterpret_cast<char*>(m.data()), m.size());
// }
// header.dataSize = outfile.tellp() - dataOffset;
// std::sort(entries.begin(), entries.end(), [](CompoundBondInfo& a, CompoundBondInfo& b)
// {
// return a.id < b.id;
// });
// for (auto& info: entries)
// outfile << info;
// outfile.seekp(0);
// outfile << header;
// // compress
// outfile.close();
// std::ifstream in(infofile.string() + ".tmp", std::ios::binary);
// std::ofstream out(infofile, std::ios::binary);
// {
// io::filtering_stream<io::output> os;
// os.push(io::gzip_compressor());
// os.push(out);
// io::copy(in, os);
// }
// in.close();
// out.close();
// fs::remove(infofile.string() + ".tmp");
// }
// --------------------------------------------------------------------
struct CompoundBondInfo
{
IDType mID;
std::set<std::tuple<uint32_t,uint32_t>> mBonded;
bool bonded(uint32_t a1, uint32_t a2) const
{
return mBonded.count({ a1, a2 }) > 0;
}
};
// --------------------------------------------------------------------
class CompoundBondMap
{
public:
static CompoundBondMap &instance()
{
static std::unique_ptr<CompoundBondMap> s_instance(new CompoundBondMap);
return *s_instance;
}
bool bonded(const std::string& compoundID, const std::string& atomID1, const std::string& atomID2);
private:
CompoundBondMap() {}
uint32_t getAtomID(const std::string& atomID)
{
IDType id(atomID);
uint32_t result;
auto i = mAtomIDIndex.find(id);
if (i == mAtomIDIndex.end())
{
result = uint32_t(mAtomIDIndex.size());
mAtomIDIndex[id] = result;
}
else
result = i->second;
return result;
}
std::map<IDType,uint32_t> mAtomIDIndex;
std::vector<CompoundBondInfo> mCompounds;
std::mutex mMutex;
};
bool CompoundBondMap::bonded(const std::string &compoundID, const std::string& atomID1, const std::string& atomID2)
{
std::lock_guard lock(mMutex);
using namespace std::literals;
IDType id(compoundID);
uint32_t a1 = getAtomID(atomID1);
uint32_t a2 = getAtomID(atomID2);
if (a1 > a2)
std::swap(a1, a2);
for (auto &bi: mCompounds)
{
if (bi.mID != id)
continue;
return bi.bonded(a1, a2);
}
bool result = false;
// not found in our cache, calculate
CompoundBondInfo bondInfo{ id };
auto compound = mmcif::CompoundFactory::instance().create(compoundID);
if (not compound)
std::cerr << "Missing compound bond info for " << compoundID << std::endl;
else
{
for (auto &atom: compound->bonds())
{
uint32_t ca1 = getAtomID(atom.atomID[0]);
uint32_t ca2 = getAtomID(atom.atomID[1]);
if (ca1 > ca2)
std::swap(ca1, ca2);
bondInfo.mBonded.insert({ca1, ca2});
result = result or (a1 == ca1 and a2 == ca2);
}
}
mCompounds.push_back(bondInfo);
return result;
}
// --------------------------------------------------------------------
BondMap::BondMap(const Structure& p)
{
auto& compoundBondInfo = CompoundBondMap::instance();
auto atoms = p.atoms();
dim = uint32_t(atoms.size());
// bond = std::vector<bool>(dim * (dim - 1), false);
for (auto& atom: atoms)
index[atom.id()] = uint32_t(index.size());
auto bindAtoms = [this](const std::string& a, const std::string& b)
{
uint32_t ixa = index[a];
uint32_t ixb = index[b];
bond.insert(key(ixa, ixb));
};
auto linkAtoms = [this,&bindAtoms](const std::string& a, const std::string& b)
{
bindAtoms(a, b);
link[a].insert(b);
link[b].insert(a);
};
cif::Datablock& db = p.getFile().data();
// collect all compounds first
std::set<std::string> compounds;
for (auto c: db["chem_comp"])
compounds.insert(c["id"].as<std::string>());
// make sure we also have all residues in the polyseq
for (auto m: db["entity_poly_seq"])
{
std::string c = m["mon_id"].as<std::string>();
if (compounds.count(c))
continue;
if (cif::VERBOSE > 1)
std::cerr << "Warning: mon_id " << c << " is missing in the chem_comp category" << std::endl;
compounds.insert(c);
}
cif::Progress progress(compounds.size(), "Creating bond map");
// some helper indices to speed things up a bit
std::map<std::tuple<std::string,int,std::string>,std::string> atomMapByAsymSeqAndAtom;
for (auto& a: p.atoms())
{
auto key = make_tuple(a.labelAsymID(), a.labelSeqID(), a.labelAtomID());
atomMapByAsymSeqAndAtom[key] = a.id();
}
// first link all residues in a polyseq
std::string lastAsymID;
int lastSeqID = 0;
for (auto r: db["pdbx_poly_seq_scheme"])
{
std::string asymID;
int seqID;
cif::tie(asymID, seqID) = r.get("asym_id", "seq_id");
if (asymID != lastAsymID) // first in a new sequece
{
lastAsymID = asymID;
lastSeqID = seqID;
continue;
}
auto c = atomMapByAsymSeqAndAtom[make_tuple(asymID, lastSeqID, "C")];
auto n = atomMapByAsymSeqAndAtom[make_tuple(asymID, seqID, "N")];
if (not (c.empty() or n.empty()))
bindAtoms(c, n);
lastSeqID = seqID;
}
for (auto l: db["struct_conn"])
{
std::string asym1, asym2, atomId1, atomId2;
int seqId1 = 0, seqId2 = 0;
cif::tie(asym1, asym2, atomId1, atomId2, seqId1, seqId2) =
l.get("ptnr1_label_asym_id", "ptnr2_label_asym_id",
"ptnr1_label_atom_id", "ptnr2_label_atom_id",
"ptnr1_label_seq_id", "ptnr2_label_seq_id");
std::string a = atomMapByAsymSeqAndAtom[make_tuple(asym1, seqId1, atomId1)];
std::string b = atomMapByAsymSeqAndAtom[make_tuple(asym2, seqId2, atomId2)];
if (not (a.empty() or b.empty()))
linkAtoms(a, b);
}
// then link all atoms in the compounds
for (auto c: compounds)
{
if (c == "HOH" or c == "H2O" or c == "WAT")
{
if (cif::VERBOSE)
std::cerr << "skipping water in bond map calculation" << std::endl;
continue;
}
auto bonded = [c, &compoundBondInfo](const Atom& a, const Atom& b)
{
auto label_a = a.labelAtomID();
auto label_b = b.labelAtomID();
return compoundBondInfo.bonded(c, label_a, label_b);
};
// loop over poly_seq_scheme
for (auto r: db["pdbx_poly_seq_scheme"].find(cif::Key("mon_id") == c))
{
std::string asymID;
int seqID;
cif::tie(asymID, seqID) = r.get("asym_id", "seq_id");
std::vector<Atom> rAtoms;
copy_if(atoms.begin(), atoms.end(), back_inserter(rAtoms),
[&](auto& a) { return a.labelAsymID() == asymID and a.labelSeqID() == seqID; });
for (uint32_t i = 0; i + 1 < rAtoms.size(); ++i)
{
for (uint32_t j = i + 1; j < rAtoms.size(); ++j)
{
if (bonded(rAtoms[i], rAtoms[j]))
bindAtoms(rAtoms[i].id(), rAtoms[j].id());
}
}
}
// loop over pdbx_nonpoly_scheme
for (auto r: db["pdbx_nonpoly_scheme"].find(cif::Key("mon_id") == c))
{
std::string asymID;
cif::tie(asymID) = r.get("asym_id");
std::vector<Atom> rAtoms;
copy_if(atoms.begin(), atoms.end(), back_inserter(rAtoms),
[&](auto& a) { return a.labelAsymID() == asymID; });
for (uint32_t i = 0; i + 1 < rAtoms.size(); ++i)
{
for (uint32_t j = i + 1; j < rAtoms.size(); ++j)
{
if (bonded(rAtoms[i], rAtoms[j]))
{
uint32_t ixa = index[rAtoms[i].id()];
uint32_t ixb = index[rAtoms[j].id()];
bond.insert(key(ixa, ixb));
}
}
}
}
// loop over pdbx_branch_scheme
for (auto r: db["pdbx_branch_scheme"].find(cif::Key("mon_id") == c))
{
std::string asymID;
cif::tie(asymID) = r.get("asym_id");
std::vector<Atom> rAtoms;
copy_if(atoms.begin(), atoms.end(), back_inserter(rAtoms),
[&](auto& a) { return a.labelAsymID() == asymID; });
for (uint32_t i = 0; i + 1 < rAtoms.size(); ++i)
{
for (uint32_t j = i + 1; j < rAtoms.size(); ++j)
{
if (bonded(rAtoms[i], rAtoms[j]))
{
uint32_t ixa = index[rAtoms[i].id()];
uint32_t ixb = index[rAtoms[j].id()];
bond.insert(key(ixa, ixb));
}
}
}
}
}
// start by creating an index for single bonds
std::multimap<uint32_t,uint32_t> b1_2;
for (auto& bk: bond)
{
uint32_t a, b;
std::tie(a, b) = dekey(bk);
b1_2.insert({ a, b });
b1_2.insert({ b, a });
}
std::multimap<uint32_t,uint32_t> b1_3;
for (uint32_t i = 0; i < dim; ++i)
{
auto a = b1_2.equal_range(i);
std::vector<uint32_t> s;
for (auto j = a.first; j != a.second; ++j)
s.push_back(j->second);
for (size_t si1 = 0; si1 + 1 < s.size(); ++si1)
{
for (size_t si2 = si1 + 1; si2 < s.size(); ++si2)
{
uint32_t x = s[si1];
uint32_t y = s[si2];
if (isBonded(x, y))
continue;
b1_3.insert({ x, y });
b1_3.insert({ y, x });
}
}
}
for (uint32_t i = 0; i < dim; ++i)
{
auto a1 = b1_2.equal_range(i);
auto a2 = b1_3.equal_range(i);
for (auto ai1 = a1.first; ai1 != a1.second; ++ai1)
{
for (auto ai2 = a2.first; ai2 != a2.second; ++ai2)
{
uint32_t b1 = ai1->second;
uint32_t b2 = ai2->second;
if (isBonded(b1, b2))
continue;
bond_1_4.insert(key(b1, b2));
}
}
}
}
std::vector<std::string> BondMap::linked(const Atom& a) const
{
auto i = link.find(a.id());
std::vector<std::string> result;
if (i != link.end())
result = std::vector<std::string>(i->second.begin(), i->second.end());
return result;
}
std::vector<std::string> BondMap::atomIDsForCompound(const std::string& compoundID)
{
std::vector<std::string> result;
auto* compound = mmcif::CompoundFactory::instance().create(compoundID);
if (compound == nullptr)
throw BondMapException("Missing bond information for compound " + compoundID);
for (auto& compAtom: compound->atoms())
result.push_back(compAtom.id);
return result;
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -27,8 +27,9 @@
#include <map>
#include <set>
#include <regex>
#include <cmath>
#include <iomanip>
#include <boost/date_time/gregorian/gregorian.hpp>
#include <boost/algorithm/string.hpp>
#include <boost/format.hpp>
@@ -232,7 +233,7 @@ std::vector<std::string> MapAsymIDs2ChainIDs(const std::vector<std::string>& asy
}
// support for wrapping text using a 'continuation marker'
int WriteContinuedLine(std::ostream& pdbFile, std::string header, int& count, int cLen, std::string text, int lStart = 0)
size_t WriteContinuedLine(std::ostream& pdbFile, std::string header, int& count, int cLen, std::string text, std::string::size_type lStart = 0)
{
if (lStart == 0)
{
@@ -242,7 +243,7 @@ int WriteContinuedLine(std::ostream& pdbFile, std::string header, int& count, in
lStart = header.length() + cLen;
}
int maxLength = 80 - lStart - 1;
std::string::size_type maxLength = 80 - lStart - 1;
std::vector<std::string> lines = cif::wordWrap(text, maxLength);
@@ -268,15 +269,15 @@ int WriteContinuedLine(std::ostream& pdbFile, std::string header, int& count, in
}
int WriteOneContinuedLine(std::ostream& pdbFile, std::string header, int cLen, std::string line, int lStart = 0)
size_t WriteOneContinuedLine(std::ostream& pdbFile, std::string header, int cLen, std::string line, int lStart = 0)
{
int count = 0;
return WriteContinuedLine(pdbFile, header, count, cLen, line, lStart);
}
int WriteCitation(std::ostream& pdbFile, Datablock& db, Row r, int reference)
size_t WriteCitation(std::ostream& pdbFile, Datablock& db, Row r, int reference)
{
int result = 0;
size_t result = 0;
std::string s1;
@@ -624,7 +625,10 @@ void WriteTitle(std::ostream& pdbFile, Datablock& db)
pdbFile << (boost::format(" %-6.6s") % (i < types.size() ? types[i] : std::string())).str();
pdbFile << std::endl;
types.erase(types.begin(), types.begin() + std::min(types.size(), 4UL));
if (types.size() > 4)
types.erase(types.begin(), types.begin() + 4);
else
types.clear();
}
while (types.empty() == false);
}
@@ -2438,18 +2442,18 @@ void WriteRemark350(std::ostream& pdbFile, Datablock& db)
for (auto bm: c1)
{
std::string id, details, method, oligomer;
cif::tie(id, details, method, oligomer) = bm.get("id", "details", "method_details", "oligomeric_details");
std::string id, detail, method, oligomer;
cif::tie(id, detail, method, oligomer) = bm.get("id", "details", "method_details", "oligomeric_details");
pdbFile << RM("") << std::endl
<< RM("BIOMOLECULE: ") << id << std::endl;
ba::to_upper(oligomer);
if (details == "author_defined_assembly" or details == "author_and_software_defined_assembly")
if (detail == "author_defined_assembly" or detail == "author_and_software_defined_assembly")
pdbFile << RM("AUTHOR DETERMINED BIOLOGICAL UNIT: ") << oligomer << std::endl;
if (details == "software_defined_assembly" or details == "author_and_software_defined_assembly")
if (detail == "software_defined_assembly" or detail == "author_and_software_defined_assembly")
pdbFile << RM("SOFTWARE DETERMINED QUATERNARY STRUCTURE: ") << oligomer << std::endl;
if (not method.empty())
@@ -3067,7 +3071,7 @@ int WriteHeterogen(std::ostream& pdbFile, Datablock& db)
}
}
int nr = count_if(hets.begin(), hets.end(), [hetID](auto& h) -> bool { return h.hetID == hetID; });
auto nr = count_if(hets.begin(), hets.end(), [hetID](auto& h) -> bool { return h.hetID == hetID; });
for (auto r: db["chem_comp"].find(cif::Key("id") == hetID))
{
@@ -3365,7 +3369,7 @@ void WriteConnectivity(std::ostream& pdbFile, cif::Datablock& db)
% sym2);
if (not Length.empty())
pdbFile << boost::format("%5.2f") % stod(Length);
pdbFile << boost::format(" %5.2f") % stod(Length);
pdbFile << std::endl;
}
@@ -3425,7 +3429,7 @@ int WriteMiscellaneousFeatures(std::ostream& pdbFile, Datablock& db)
std::string siteID = std::get<0>(s);
std::deque<std::string>& res = std::get<1>(s);
int numRes = res.size();
size_t numRes = res.size();
int nr = 1;
while (res.empty() == false)
@@ -3530,7 +3534,7 @@ std::tuple<int,int> WriteCoordinatesForModel(std::ostream& pdbFile, Datablock& d
auto ri = atom_site.begin();
std::string id, group, name, altLoc, resName, chainID, iCode, element;
int resSeq, charge;
int resSeq = 0, charge;
for (;;)
{
@@ -3635,12 +3639,12 @@ std::tuple<int,int> WriteCoordinatesForModel(std::ostream& pdbFile, Datablock& d
% chainID
% resSeq
% iCode
% lrintf(u11 * 10000)
% lrintf(u22 * 10000)
% lrintf(u33 * 10000)
% lrintf(u12 * 10000)
% lrintf(u13 * 10000)
% lrintf(u23 * 10000)
% std::lrintf(u11 * 10000)
% std::lrintf(u22 * 10000)
% std::lrintf(u33 * 10000)
% std::lrintf(u12 * 10000)
% std::lrintf(u13 * 10000)
% std::lrintf(u23 * 10000)
% element
% sCharge) << std::endl;
}
@@ -3919,8 +3923,7 @@ std::string GetPDBSOURCELine(cif::File& cifFile, std::string::size_type truncate
{ "pdbx_host_org_vector_type", "EXPRESSION_SYSTEM_VECTOR_TYPE" },
{ "pdbx_host_org_vector", "EXPRESSION_SYSTEM_VECTOR" },
{ "pdbx_host_org_gene", "EXPRESSION_SYSTEM_GENE" },
{ "plasmid_name", "EXPRESSION_SYSTEM_PLASMID" },
{ "details", "OTHER_DETAILS" }
{ "plasmid_name", "EXPRESSION_SYSTEM_PLASMID" }
};
for (auto gr: gen.find(cif::Key("entity_id") == entityID))

View File

@@ -84,13 +84,15 @@ const char* SacParser::kValueName[] = {
// --------------------------------------------------------------------
SacParser::SacParser(std::istream& is)
SacParser::SacParser(std::istream& is, bool init)
: mData(is)
{
mValidate = true;
mLineNr = 1;
mBol = true;
mLookahead = getNextToken();
if (init)
mLookahead = getNextToken();
}
void SacParser::error(const std::string& msg)
@@ -521,6 +523,203 @@ SacParser::CIFToken SacParser::getNextToken()
return result;
}
DatablockIndex SacParser::indexDatablocks()
{
DatablockIndex index;
// first locate the start, as fast as we can
auto &sb = *mData.rdbuf();
enum {
start, comment, string, string_quote, qstring, data, data_name
} state = start;
int quote = 0;
bool bol = true;
const char dblk[] = "data_";
std::string::size_type si = 0;
std::string datablock;
for (auto ch = sb.sbumpc(); ch != std::streambuf::traits_type::eof(); ch = sb.sbumpc())
{
switch (state)
{
case start:
switch (ch)
{
case '#': state = comment; break;
case 'd':
case 'D':
state = data;
si = 1;
break;
case '\'':
case '"':
state = string;
quote = ch;
break;
case ';':
if (bol)
state = qstring;
break;
}
break;
case comment:
if (ch == '\n')
state = start;
break;
case string:
if (ch == quote)
state = string_quote;
break;
case string_quote:
if (std::isspace(ch))
state = start;
else
state = string;
break;
case qstring:
if (ch == ';' and bol)
state = start;
break;
case data:
if (dblk[si] == 0 and isNonBlank(ch))
{
datablock = { static_cast<char>(ch) };
state = data_name;
}
else if (dblk[si++] != ch)
state = start;
break;
case data_name:
if (isNonBlank(ch))
datablock.insert(datablock.end(), char(ch));
else if (isspace(ch))
{
if (not datablock.empty())
index[datablock] = mData.tellg();
state = start;
}
else
state = start;
break;
}
bol = (ch == '\n');
}
return index;
}
bool SacParser::parseSingleDatablock(const std::string& datablock)
{
// first locate the start, as fast as we can
auto &sb = *mData.rdbuf();
enum {
start, comment, string, string_quote, qstring, data
} state = start;
int quote = 0;
bool bol = true;
std::string dblk = "data_" + datablock;
std::string::size_type si = 0;
bool found = false;
for (auto ch = sb.sbumpc(); not found and ch != std::streambuf::traits_type::eof(); ch = sb.sbumpc())
{
switch (state)
{
case start:
switch (ch)
{
case '#': state = comment; break;
case 'd':
case 'D':
state = data;
si = 1;
break;
case '\'':
case '"':
state = string;
quote = ch;
break;
case ';':
if (bol)
state = qstring;
break;
}
break;
case comment:
if (ch == '\n')
state = start;
break;
case string:
if (ch == quote)
state = string_quote;
break;
case string_quote:
if (std::isspace(ch))
state = start;
else
state = string;
break;
case qstring:
if (ch == ';' and bol)
state = start;
break;
case data:
if (isspace(ch) and dblk[si] == 0)
found = true;
else if (dblk[si++] != ch)
state = start;
break;
}
bol = (ch == '\n');
}
if (found)
{
produceDatablock(datablock);
mLookahead = getNextToken();
parseDataBlock();
}
return found;
}
bool SacParser::parseSingleDatablock(const std::string& datablock, const DatablockIndex &index)
{
bool result = false;
auto i = index.find(datablock);
if (i != index.end())
{
mData.seekg(i->second);
produceDatablock(datablock);
mLookahead = getNextToken();
parseDataBlock();
result = true;
}
return result;
}
void SacParser::parseFile()
{
while (mLookahead != eCIFTokenEOF)
@@ -642,8 +841,8 @@ void SacParser::parseSaveFrame()
// --------------------------------------------------------------------
Parser::Parser(std::istream& is, File& f)
: SacParser(is), mFile(f), mDataBlock(nullptr)
Parser::Parser(std::istream& is, File& f, bool init)
: SacParser(is, init), mFile(f), mDataBlock(nullptr)
{
}
@@ -687,9 +886,9 @@ void Parser::produceItem(const std::string& category, const std::string& item, c
struct DictParserDataImpl
{
// temporary values for constructing dictionaries
std::vector<ValidateCategory> mCategoryValidators;
std::vector<ValidateCategory> mCategoryValidators;
std::map<std::string,std::vector<ValidateItem>> mItemValidators;
std::set<std::tuple<std::string,std::string>> mLinkedItems;
std::set<std::tuple<std::string,std::string>> mLinkedItems;
};
DictParser::DictParser(Validator& validator, std::istream& is)
@@ -1036,7 +1235,7 @@ void DictParser::loadDictionary()
}
}
}
catch (const std::exception& ex)
catch (const std::exception&)
{
std::cerr << "Error parsing dictionary" << std::endl;
throw;
@@ -1099,12 +1298,12 @@ bool DictParser::collectItemTypes()
try
{
ValidateType v = {
code, mapToPrimitiveType(primitiveCode), std::regex(construct, std::regex::extended | std::regex::optimize)
code, mapToPrimitiveType(primitiveCode), boost::regex(construct, boost::regex::extended | boost::regex::optimize)
};
mValidator.addTypeValidator(std::move(v));
}
catch (const std::exception& ex)
catch (const std::exception&)
{
throw_with_nested(CifParserError(t.lineNr(), "error in regular expression"));
}

File diff suppressed because it is too large Load Diff

View File

@@ -121,8 +121,8 @@ int ValidateType::compare(const char* a, const char* b) const
if (mPrimitiveType == DDL_PrimitiveType::UChar)
{
ca = toupper(ca);
cb = toupper(cb);
ca = tolower(ca);
cb = tolower(cb);
}
result = ca - cb;
@@ -181,7 +181,7 @@ void ValidateItem::operator()(std::string value) const
{
if (not value.empty() and value != "?" and value != ".")
{
if (mType != nullptr and not std::regex_match(value, mType->mRx))
if (mType != nullptr and not regex_match(value, mType->mRx))
throw ValidationError(mCategory->mName, mTag, "Value '" + value + "' does not match type expression for type " + mType->mName);
if (not mEnums.empty())
@@ -238,7 +238,7 @@ const ValidateType* Validator::getValidatorForType(std::string typeCode) const
{
const ValidateType* result = nullptr;
auto i = mTypeValidators.find(ValidateType{ typeCode, DDL_PrimitiveType::Char, std::regex() });
auto i = mTypeValidators.find(ValidateType{ typeCode, DDL_PrimitiveType::Char, boost::regex() });
if (i != mTypeValidators.end())
result = &*i;
else if (VERBOSE > 4)

File diff suppressed because it is too large Load Diff

11
src/Config-cmake.hpp.in Normal file
View File

@@ -0,0 +1,11 @@
/* Define to the name of this package. */
#cmakedefine PACKAGE_NAME "@PACKAGE_NAME@"
/* Define to the version of this package. */
#cmakedefine PACKAGE_VERSION "@PACKAGE_VERSION@"
/* Define the complete package string */
#cmakedefine PACKAGE_STRING "@PACKAGE_STRING@"
/* Using resources? */
#cmakedefine USE_RSRC @USE_RSRC@

View File

@@ -1,4 +1,4 @@
/* include/cif++/Config.hpp.in. Generated from configure.ac by autoheader. */
/* src/Config.hpp.in. Generated from configure.ac by autoheader. */
/* define if the Boost library is available */
#undef HAVE_BOOST
@@ -9,6 +9,9 @@
/* define if the Boost::IOStreams library is available */
#undef HAVE_BOOST_IOSTREAMS
/* define if the Boost::Regex library is available */
#undef HAVE_BOOST_REGEX
/* define if the compiler supports basic C++17 syntax */
#undef HAVE_CXX17
@@ -27,6 +30,12 @@
/* Define to 1 if you have the `pow' function. */
#undef HAVE_POW
/* Define if you have POSIX threads libraries and header files. */
#undef HAVE_PTHREAD
/* Have PTHREAD_PRIO_INHERIT. */
#undef HAVE_PTHREAD_PRIO_INHERIT
/* Define to 1 if the system has the type `ptrdiff_t'. */
#undef HAVE_PTRDIFF_T
@@ -93,5 +102,12 @@
/* Define to the version of this package. */
#undef PACKAGE_VERSION
/* Define to necessary symbol if this constant uses a non-standard name on
your system. */
#undef PTHREAD_CREATE_JOINABLE
/* Define to 1 if you have the ANSI C header files. */
#undef STDC_HEADERS
/* Use mrc to store resources */
#undef USE_RSRC

File diff suppressed because it is too large Load Diff

View File

@@ -24,13 +24,11 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "cif++/Config.hpp"
#include "cif++/Cif++.hpp"
#include <map>
#include <set>
#include <boost/date_time/gregorian/gregorian.hpp>
#include <boost/algorithm/string.hpp>
#include <boost/format.hpp>
@@ -330,8 +328,14 @@ const TemplateLine kPHENIX_Template[] = {
/* 60 */ { R"(S11\s*:\s*(.+) S12\s*:\s*(.+) S13\s*:\s*(.+))", 1, "pdbx_refine_tls", { "S[1][1]", "S[1][2]", "S[1][3]" } },
/* 61 */ { R"(S21\s*:\s*(.+) S22\s*:\s*(.+) S23\s*:\s*(.+))", 1, "pdbx_refine_tls", { "S[2][1]", "S[2][2]", "S[2][3]" } },
/* 62 */ { R"(S31\s*:\s*(.+) S32\s*:\s*(.+) S33\s*:\s*(.+))", 48 - 62, "pdbx_refine_tls", { "S[3][1]", "S[3][2]", "S[3][3]" } },
/* 63 */ { R"(NCS DETAILS)", 1 },
/* 64 */ { R"(NUMBER OF NCS GROUPS\s*:\s*(.+))", 1 },
/* 63 */ { R"(ANOMALOUS SCATTERER GROUPS DETAILS\.)", 1 },
/* 64 */ { R"(NUMBER OF ANOMALOUS SCATTERER GROUPS\s*:\s*\d+)", 1 },
/* 65 */ { R"(ANOMALOUS SCATTERER GROUP\s*:\s*\d+)", 1 },
/* 66 */ { R"(SELECTION: .+)", 1 },
/* 67 */ { R"(fp\s*:\s*.+)", 1 },
/* 68 */ { R"(fdp\s*:\s*.+)", 63 - 68 },
/* 69 */ { R"(NCS DETAILS)", 1 },
/* 70 */ { R"(NUMBER OF NCS GROUPS\s*:\s*(.+))", 1 },
};
class PHENIX_Remark3Parser : public Remark3Parser
@@ -1474,8 +1478,8 @@ bool Remark3Parser::parse(const std::string& expMethod, PDBRecord* r, cif::Datab
}
else
{
for (auto r: cat1)
cat2.emplace(r);
for (auto rs: cat1)
cat2.emplace(rs);
}
}
}

View File

@@ -28,13 +28,14 @@
#include <valarray>
#include "cif++/Point.hpp"
#include "cif++/Matrix.hpp"
namespace mmcif
{
// --------------------------------------------------------------------
quaternion Normalize(quaternion q)
Quaternion Normalize(Quaternion q)
{
std::valarray<double> t(4);
@@ -45,19 +46,19 @@ quaternion Normalize(quaternion q)
t *= t;
double length = sqrt(t.sum());
double length = std::sqrt(t.sum());
if (length > 0.001)
q /= length;
q /= static_cast<Quaternion::value_type>(length);
else
q = quaternion(1, 0, 0, 0);
q = Quaternion(1, 0, 0, 0);
return q;
}
// --------------------------------------------------------------------
std::tuple<double,Point> QuaternionToAngleAxis(quaternion q)
std::tuple<double,Point> QuaternionToAngleAxis(Quaternion q)
{
if (q.R_component_1() > 1)
q = Normalize(q);
@@ -67,7 +68,7 @@ std::tuple<double,Point> QuaternionToAngleAxis(quaternion q)
angle = angle * 180 / kPI;
// axis:
double s = sqrt(1 - q.R_component_1() * q.R_component_1());
float s = std::sqrt(1 - q.R_component_1() * q.R_component_1());
if (s < 0.001)
s = 1;
@@ -108,7 +109,7 @@ Point Centroid(std::vector<Point>& Points)
for (Point& pt : Points)
result += pt;
result /= Points.size();
result /= static_cast<float>(Points.size());
return result;
}
@@ -158,7 +159,7 @@ double LargestDepressedQuarticSolution(double a, double b, double c)
std::complex<double> W = std::sqrt(a + 2.0 * y);
// And to get the final result:
// result = (±W + sqrt(-(3 * alpha + 2 * y ± 2 * beta / W))) / 2;
// result = (±W + std::sqrt(-(3 * alpha + 2 * y ± 2 * beta / W))) / 2;
// We want the largest result, so:
std::valarray<double> t(4);
@@ -171,113 +172,113 @@ double LargestDepressedQuarticSolution(double a, double b, double c)
return t.max();
}
//quaternion AlignPoints(const vector<Point>& pa, const vector<Point>& pb)
//{
// // First calculate M, a 3x3 matrix containing the sums of products of the coordinates of A and B
// matrix<double> M(3, 3, 0);
//
// for (uint32_t i = 0; i < pa.size(); ++i)
// {
// const Point& a = pa[i];
// const Point& b = pb[i];
//
// M(0, 0) += a.mX * b.mX; M(0, 1) += a.mX * b.mY; M(0, 2) += a.mX * b.mZ;
// M(1, 0) += a.mY * b.mX; M(1, 1) += a.mY * b.mY; M(1, 2) += a.mY * b.mZ;
// M(2, 0) += a.mZ * b.mX; M(2, 1) += a.mZ * b.mY; M(2, 2) += a.mZ * b.mZ;
// }
//
// // Now calculate N, a symmetric 4x4 matrix
// symmetric_matrix<double> N(4);
//
// N(0, 0) = M(0, 0) + M(1, 1) + M(2, 2);
// N(0, 1) = M(1, 2) - M(2, 1);
// N(0, 2) = M(2, 0) - M(0, 2);
// N(0, 3) = M(0, 1) - M(1, 0);
//
// N(1, 1) = M(0, 0) - M(1, 1) - M(2, 2);
// N(1, 2) = M(0, 1) + M(1, 0);
// N(1, 3) = M(0, 2) + M(2, 0);
//
// N(2, 2) = -M(0, 0) + M(1, 1) - M(2, 2);
// N(2, 3) = M(1, 2) + M(2, 1);
//
// N(3, 3) = -M(0, 0) - M(1, 1) + M(2, 2);
//
// // det(N - λI) = 0
// // find the largest λ (λm)
// //
// // Aλ4 + Bλ3 + Cλ2 + Dλ + E = 0
// // A = 1
// // B = 0
// // and so this is a so-called depressed quartic
// // solve it using Ferrari's algorithm
//
// double C = -2 * (
// M(0, 0) * M(0, 0) + M(0, 1) * M(0, 1) + M(0, 2) * M(0, 2) +
// M(1, 0) * M(1, 0) + M(1, 1) * M(1, 1) + M(1, 2) * M(1, 2) +
// M(2, 0) * M(2, 0) + M(2, 1) * M(2, 1) + M(2, 2) * M(2, 2));
//
// double D = 8 * (M(0, 0) * M(1, 2) * M(2, 1) +
// M(1, 1) * M(2, 0) * M(0, 2) +
// M(2, 2) * M(0, 1) * M(1, 0)) -
// 8 * (M(0, 0) * M(1, 1) * M(2, 2) +
// M(1, 2) * M(2, 0) * M(0, 1) +
// M(2, 1) * M(1, 0) * M(0, 2));
//
// double E =
// (N(0,0) * N(1,1) - N(0,1) * N(0,1)) * (N(2,2) * N(3,3) - N(2,3) * N(2,3)) +
// (N(0,1) * N(0,2) - N(0,0) * N(2,1)) * (N(2,1) * N(3,3) - N(2,3) * N(1,3)) +
// (N(0,0) * N(1,3) - N(0,1) * N(0,3)) * (N(2,1) * N(2,3) - N(2,2) * N(1,3)) +
// (N(0,1) * N(2,1) - N(1,1) * N(0,2)) * (N(0,2) * N(3,3) - N(2,3) * N(0,3)) +
// (N(1,1) * N(0,3) - N(0,1) * N(1,3)) * (N(0,2) * N(2,3) - N(2,2) * N(0,3)) +
// (N(0,2) * N(1,3) - N(2,1) * N(0,3)) * (N(0,2) * N(1,3) - N(2,1) * N(0,3));
//
// // solve quartic
// double lm = LargestDepressedQuarticSolution(C, D, E);
//
// // calculate t = (N - λI)
// matrix<double> li = identity_matrix<double>(4) * lm;
// matrix<double> t = N - li;
//
// // calculate a matrix of cofactors for t
// matrix<double> cf(4, 4);
//
// const uint32_t ixs[4][3] =
// {
// { 1, 2, 3 },
// { 0, 2, 3 },
// { 0, 1, 3 },
// { 0, 1, 2 }
// };
//
// uint32_t maxR = 0;
// for (uint32_t r = 0; r < 4; ++r)
// {
// const uint32_t* ir = ixs[r];
//
// for (uint32_t c = 0; c < 4; ++c)
// {
// const uint32_t* ic = ixs[c];
//
// cf(r, c) =
// t(ir[0], ic[0]) * t(ir[1], ic[1]) * t(ir[2], ic[2]) +
// t(ir[0], ic[1]) * t(ir[1], ic[2]) * t(ir[2], ic[0]) +
// t(ir[0], ic[2]) * t(ir[1], ic[0]) * t(ir[2], ic[1]) -
// t(ir[0], ic[2]) * t(ir[1], ic[1]) * t(ir[2], ic[0]) -
// t(ir[0], ic[1]) * t(ir[1], ic[0]) * t(ir[2], ic[2]) -
// t(ir[0], ic[0]) * t(ir[1], ic[2]) * t(ir[2], ic[1]);
// }
//
// if (r > maxR and cf(r, 0) > cf(maxR, 0))
// maxR = r;
// }
//
// // NOTE the negation of the y here, why? Maybe I swapped r/c above?
// quaternion q(cf(maxR, 0), cf(maxR, 1), -cf(maxR, 2), cf(maxR, 3));
// q = Normalize(q);
//
// return q;
//}
Quaternion AlignPoints(const std::vector<Point>& pa, const std::vector<Point>& pb)
{
// First calculate M, a 3x3 Matrix containing the sums of products of the coordinates of A and B
Matrix<double> M(3, 3, 0);
for (uint32_t i = 0; i < pa.size(); ++i)
{
const Point& a = pa[i];
const Point& b = pb[i];
M(0, 0) += a.mX * b.mX; M(0, 1) += a.mX * b.mY; M(0, 2) += a.mX * b.mZ;
M(1, 0) += a.mY * b.mX; M(1, 1) += a.mY * b.mY; M(1, 2) += a.mY * b.mZ;
M(2, 0) += a.mZ * b.mX; M(2, 1) += a.mZ * b.mY; M(2, 2) += a.mZ * b.mZ;
}
// Now calculate N, a symmetric 4x4 Matrix
SymmetricMatrix<double> N(4);
N(0, 0) = M(0, 0) + M(1, 1) + M(2, 2);
N(0, 1) = M(1, 2) - M(2, 1);
N(0, 2) = M(2, 0) - M(0, 2);
N(0, 3) = M(0, 1) - M(1, 0);
N(1, 1) = M(0, 0) - M(1, 1) - M(2, 2);
N(1, 2) = M(0, 1) + M(1, 0);
N(1, 3) = M(0, 2) + M(2, 0);
N(2, 2) = -M(0, 0) + M(1, 1) - M(2, 2);
N(2, 3) = M(1, 2) + M(2, 1);
N(3, 3) = -M(0, 0) - M(1, 1) + M(2, 2);
// det(N - λI) = 0
// find the largest λ (λm)
//
// Aλ4 + Bλ3 + Cλ2 + Dλ + E = 0
// A = 1
// B = 0
// and so this is a so-called depressed quartic
// solve it using Ferrari's algorithm
double C = -2 * (
M(0, 0) * M(0, 0) + M(0, 1) * M(0, 1) + M(0, 2) * M(0, 2) +
M(1, 0) * M(1, 0) + M(1, 1) * M(1, 1) + M(1, 2) * M(1, 2) +
M(2, 0) * M(2, 0) + M(2, 1) * M(2, 1) + M(2, 2) * M(2, 2));
double D = 8 * (M(0, 0) * M(1, 2) * M(2, 1) +
M(1, 1) * M(2, 0) * M(0, 2) +
M(2, 2) * M(0, 1) * M(1, 0)) -
8 * (M(0, 0) * M(1, 1) * M(2, 2) +
M(1, 2) * M(2, 0) * M(0, 1) +
M(2, 1) * M(1, 0) * M(0, 2));
double E =
(N(0,0) * N(1,1) - N(0,1) * N(0,1)) * (N(2,2) * N(3,3) - N(2,3) * N(2,3)) +
(N(0,1) * N(0,2) - N(0,0) * N(2,1)) * (N(2,1) * N(3,3) - N(2,3) * N(1,3)) +
(N(0,0) * N(1,3) - N(0,1) * N(0,3)) * (N(2,1) * N(2,3) - N(2,2) * N(1,3)) +
(N(0,1) * N(2,1) - N(1,1) * N(0,2)) * (N(0,2) * N(3,3) - N(2,3) * N(0,3)) +
(N(1,1) * N(0,3) - N(0,1) * N(1,3)) * (N(0,2) * N(2,3) - N(2,2) * N(0,3)) +
(N(0,2) * N(1,3) - N(2,1) * N(0,3)) * (N(0,2) * N(1,3) - N(2,1) * N(0,3));
// solve quartic
double lm = LargestDepressedQuarticSolution(C, D, E);
// calculate t = (N - λI)
Matrix<double> li = IdentityMatrix<double>(4) * lm;
Matrix<double> t = N - li;
// calculate a Matrix of cofactors for t
Matrix<double> cf(4, 4);
const uint32_t ixs[4][3] =
{
{ 1, 2, 3 },
{ 0, 2, 3 },
{ 0, 1, 3 },
{ 0, 1, 2 }
};
uint32_t maxR = 0;
for (uint32_t r = 0; r < 4; ++r)
{
const uint32_t* ir = ixs[r];
for (uint32_t c = 0; c < 4; ++c)
{
const uint32_t* ic = ixs[c];
cf(r, c) =
t(ir[0], ic[0]) * t(ir[1], ic[1]) * t(ir[2], ic[2]) +
t(ir[0], ic[1]) * t(ir[1], ic[2]) * t(ir[2], ic[0]) +
t(ir[0], ic[2]) * t(ir[1], ic[0]) * t(ir[2], ic[1]) -
t(ir[0], ic[2]) * t(ir[1], ic[1]) * t(ir[2], ic[0]) -
t(ir[0], ic[1]) * t(ir[1], ic[0]) * t(ir[2], ic[2]) -
t(ir[0], ic[0]) * t(ir[1], ic[2]) * t(ir[2], ic[1]);
}
if (r > maxR and cf(r, 0) > cf(maxR, 0))
maxR = r;
}
// NOTE the negation of the y here, why? Maybe I swapped r/c above?
Quaternion q(cf(maxR, 0), cf(maxR, 1), -cf(maxR, 2), cf(maxR, 3));
q = Normalize(q);
return q;
}
// --------------------------------------------------------------------
@@ -289,15 +290,15 @@ Point Nudge(Point p, float offset)
std::uniform_real_distribution<> randomAngle(0, 2 * kPI);
std::normal_distribution<> randomOffset(0, offset);
float theta = randomAngle(rng);
float phi1 = randomAngle(rng) - kPI;
float phi2 = randomAngle(rng) - kPI;
float theta = static_cast<float>(randomAngle(rng));
float phi1 = static_cast<float>(randomAngle(rng) - kPI);
float phi2 = static_cast<float>(randomAngle(rng) - kPI);
quaternion q = boost::math::spherical(1.0f, theta, phi1, phi2);
Quaternion q = boost::math::spherical(1.0f, theta, phi1, phi2);
Point r{ 0, 0, 1 };
r.rotate(q);
r *= randomOffset(rng);
r *= static_cast<float>(randomOffset(rng));
return p + r;
}

View File

@@ -26,8 +26,6 @@
// Calculate DSSP-like secondary structure information
#include "cif++/Config.hpp"
#include <numeric>
#include <iomanip>
#include <thread>
@@ -156,21 +154,21 @@ struct BridgeParner
// --------------------------------------------------------------------
const float
// kSSBridgeDistance = 3.0,
kMinimalDistance = 0.5,
kMinimalCADistance = 9.0,
kMinHBondEnergy = -9.9,
kMaxHBondEnergy = -0.5,
kCouplingConstant = -27.888, // = -332 * 0.42 * 0.2
kMaxPeptideBondLength = 2.5;
// kSSBridgeDistance = 3.0f,
kMinimalDistance = 0.5f,
kMinimalCADistance = 9.0f,
kMinHBondEnergy = -9.9f,
kMaxHBondEnergy = -0.5f,
kCouplingConstant = -27.888f, // = -332 * 0.42 * 0.2
kMaxPeptideBondLength = 2.5f;
const float
kRadiusN = 1.65,
kRadiusCA = 1.87,
kRadiusC = 1.76,
kRadiusO = 1.4,
kRadiusSideAtom = 1.8,
kRadiusWater = 1.4;
kRadiusN = 1.65f,
kRadiusCA = 1.87f,
kRadiusC = 1.76f,
kRadiusO = 1.4f,
kRadiusSideAtom = 1.8f,
kRadiusWater = 1.4f;
struct Res
{
@@ -180,8 +178,8 @@ struct Res
, mChainBreak(brk)
{
// update the box containing all atoms
mBox[0].mX = mBox[0].mY = mBox[0].mZ = std::numeric_limits<double>::max();
mBox[1].mX = mBox[1].mY = mBox[1].mZ = -std::numeric_limits<double>::max();
mBox[0].mX = mBox[0].mY = mBox[0].mZ = std::numeric_limits<float>::max();
mBox[1].mX = mBox[1].mY = mBox[1].mZ = -std::numeric_limits<float>::max();
mH = mmcif::Point{ std::numeric_limits<float>::max(), std::numeric_limits<float>::max(), std::numeric_limits<float>::max() };
@@ -235,7 +233,7 @@ struct Res
auto pc = mPrev->mC;
auto po = mPrev->mO;
double CODistance = Distance(pc, po);
float CODistance = static_cast<float>(Distance(pc, po));
mH.mX += (pc.mX - po.mX) / CODistance;
mH.mY += (pc.mY - po.mY) / CODistance;
@@ -431,16 +429,16 @@ MSurfaceDots::MSurfaceDots(int32_t N)
{
auto P = 2 * N + 1;
const double kGoldenRatio = (1 + sqrt(5.0)) / 2;
const float kGoldenRatio = (1 + std::sqrt(5.0f)) / 2;
mWeight = (4 * kPI) / P;
for (auto i = -N; i <= N; ++i)
{
double lat = asin((2.0 * i) / P);
double lon = fmod(i, kGoldenRatio) * 2 * kPI / kGoldenRatio;
float lat = std::asin((2.0f * i) / P);
float lon = static_cast<float>(std::fmod(i, kGoldenRatio) * 2 * kPI / kGoldenRatio);
mPoints.emplace_back(sin(lon) * cos(lat), cos(lon) * cos(lat), sin(lat));
mPoints.emplace_back(std::sin(lon) * std::cos(lat), std::cos(lon) * std::cos(lat), std::sin(lat));
}
}
@@ -510,11 +508,7 @@ double Res::CalculateSurface(const std::vector<Res>& inResidues)
void CalculateAccessibilities(std::vector<Res>& inResidues, DSSP_Statistics& stats)
{
if (cif::VERBOSE)
std::cerr << "Calculate accessibilities" << std::endl;
stats.accessibleSurface = 0;
for (auto& residue: inResidues)
stats.accessibleSurface += residue.CalculateSurface(inResidues);
}
@@ -774,7 +768,7 @@ void CalculateBetaSheets(std::vector<Res>& inResidues, DSSP_Statistics& stats)
{
ladderset.insert(&bridge);
uint32_t n = bridge.i.size();
size_t n = bridge.i.size();
if (n > kHistogramSize)
n = kHistogramSize;
@@ -821,7 +815,7 @@ void CalculateBetaSheets(std::vector<Res>& inResidues, DSSP_Statistics& stats)
++ladder;
}
uint32_t nrOfLaddersPerSheet = sheetset.size();
size_t nrOfLaddersPerSheet = sheetset.size();
if (nrOfLaddersPerSheet > kHistogramSize)
nrOfLaddersPerSheet = kHistogramSize;
if (nrOfLaddersPerSheet == 1 and (*sheetset.begin())->i.size() > 1)
@@ -1184,13 +1178,10 @@ DSSPImpl::DSSPImpl(const Structure& s, int min_poly_proline_stretch_length)
, mPolymers(mStructure.polymers())
, m_min_poly_proline_stretch_length(min_poly_proline_stretch_length)
{
if (cif::VERBOSE)
std::cerr << "Calculating DSSP ";
size_t nRes = accumulate(mPolymers.begin(), mPolymers.end(),
0.0, [](double s, auto& p) { return s + p.size(); });
0ULL, [](size_t s, auto& p) { return s + p.size(); });
mStats.nrOfChains = mPolymers.size();
mStats.nrOfChains = static_cast<uint32_t>(mPolymers.size());
mResidues.reserve(nRes);
int resNumber = 0;
@@ -1223,7 +1214,7 @@ DSSPImpl::DSSPImpl(const Structure& s, int min_poly_proline_stretch_length)
}
}
mStats.nrOfResidues = mResidues.size();
mStats.nrOfResidues = static_cast<uint32_t>(mResidues.size());
for (size_t i = 0; i + 1 < mResidues.size(); ++i)
{
@@ -1264,20 +1255,11 @@ void DSSPImpl::calculateSecondaryStructure()
mSSBonds.emplace_back(&*r1, &*r2);
}
if (cif::VERBOSE) std::cerr << ".";
CalculateHBondEnergies(mResidues);
if (cif::VERBOSE) std::cerr << ".";
CalculateBetaSheets(mResidues, mStats);
if (cif::VERBOSE) std::cerr << ".";
CalculateAlphaHelices(mResidues, mStats);
if (cif::VERBOSE) std::cerr << ".";
CalculatePPHelices(mResidues, mStats, m_min_poly_proline_stretch_length);
if (cif::VERBOSE) std::cerr << std::endl;
if (cif::VERBOSE > 1)
{
for (auto& r: mResidues)
@@ -1290,7 +1272,7 @@ void DSSPImpl::calculateSecondaryStructure()
switch (r.GetHelixFlag(helixType))
{
case Helix::Start: helix[static_cast<int>(helixType)] = '>'; break;
case Helix::Middle: helix[static_cast<int>(helixType)] = helixType == HelixType::rh_pp ? 'P' : '3' + static_cast<int>(helixType); break;
case Helix::Middle: helix[static_cast<int>(helixType)] = helixType == HelixType::rh_pp ? 'P' : '3' + static_cast<char>(helixType); break;
case Helix::StartAndEnd: helix[static_cast<int>(helixType)] = 'X'; break;
case Helix::End: helix[static_cast<int>(helixType)] = '<'; break;
case Helix::None: helix[static_cast<int>(helixType)] = ' '; break;
@@ -1307,10 +1289,10 @@ void DSSPImpl::calculateSecondaryStructure()
}
// finish statistics
mStats.nrOfSSBridges = mSSBonds.size();
mStats.nrOfSSBridges = static_cast<uint32_t>(mSSBonds.size());
mStats.nrOfIntraChainSSBridges = 0;
int ssBondNr = 0;
uint8_t ssBondNr = 0;
for (const auto& [a, b]: mSSBonds)
{
if (a == b)
@@ -1351,11 +1333,6 @@ void DSSPImpl::calculateSurface()
// --------------------------------------------------------------------
DSSP::ResidueInfo::ResidueInfo(Res* res)
: mImpl(res)
{
}
const Monomer& DSSP::ResidueInfo::residue() const
{
return mImpl->mM;
@@ -1429,8 +1406,8 @@ std::tuple<DSSP::ResidueInfo,double> DSSP::ResidueInfo::donor(int i) const
// --------------------------------------------------------------------
DSSP::iterator::iterator(res_iter cur)
: mCurrent(&*cur)
DSSP::iterator::iterator(Res* res)
: mCurrent(res)
{
}
@@ -1473,12 +1450,20 @@ DSSP::~DSSP()
DSSP::iterator DSSP::begin() const
{
return iterator(mImpl->mResidues.begin());
return iterator(mImpl->mResidues.empty() ? nullptr : mImpl->mResidues.data());
}
DSSP::iterator DSSP::end() const
{
return iterator(mImpl->mResidues.end());
// careful now, MSVC is picky when it comes to dereferencing iterators that are at the end.
Res* res = nullptr;
if (not mImpl->mResidues.empty())
{
res = mImpl->mResidues.data();
res += mImpl->mResidues.size();
}
return iterator(res);
}
SecondaryStructureType DSSP::operator()(const std::string& inAsymID, int inSeqID) const

File diff suppressed because it is too large Load Diff

View File

@@ -4,6 +4,9 @@
#include "cif++/Symmetry.hpp"
namespace mmcif
{
const Spacegroup kSpaceGroups[] =
{
{ "" , "P 2 1 1" , " P 2y (y,z,x)" , 10005 },
@@ -8653,4 +8656,5 @@ const SymopDataBlock kSymopNrTable[] = {
const size_t kSymopNrTableSize = sizeof(kSymopNrTable) / sizeof(SymopDataBlock);
} // namespace mmcif

View File

@@ -24,14 +24,14 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "cif++/Config.hpp"
#include <atomic>
#include <mutex>
#include "cif++/Symmetry.hpp"
#include "cif++/CifUtils.hpp"
#include "SymOpTable_data.hpp"
namespace mmcif
{
@@ -40,8 +40,6 @@ namespace mmcif
// for rotation numbers. So we created a table to map those.
// Perhaps a bit over the top, but hey....
#include "SymOpTable_data.cpp"
// --------------------------------------------------------------------
int GetSpacegroupNumber(std::string spacegroup)

View File

@@ -24,8 +24,6 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "cif++/Config.hpp"
#include <boost/algorithm/string.hpp>
#include "cif++/TlsParser.hpp"
@@ -65,7 +63,7 @@ struct TLSResidue
}
};
void DumpSelection(const std::vector<TLSResidue>& selected, int indentLevel)
void DumpSelection(const std::vector<TLSResidue>& selected, std::size_t indentLevel)
{
std::string indent(indentLevel * 2, ' ');
@@ -243,7 +241,7 @@ struct TLSSelectionNot : public TLSSelection
TLSSelectionNot(TLSSelectionPtr selection)
: selection(selection.release()) {}
virtual void CollectResidues(Datablock& db, std::vector<TLSResidue>& residues, int indentLevel) const
virtual void CollectResidues(Datablock& db, std::vector<TLSResidue>& residues, std::size_t indentLevel) const
{
selection->CollectResidues(db, residues, indentLevel + 1);
@@ -264,7 +262,7 @@ struct TLSSelectionAll : public TLSSelection
{
TLSSelectionAll() {}
virtual void CollectResidues(Datablock& db, std::vector<TLSResidue>& residues, int indentLevel) const
virtual void CollectResidues(Datablock& db, std::vector<TLSResidue>& residues, std::size_t indentLevel) const
{
for (auto& r: residues)
r.selected = true;
@@ -282,7 +280,7 @@ struct TLSSelectionChain : public TLSSelectionAll
TLSSelectionChain(const std::string& chainID)
: m_chain(chainID) {}
virtual void CollectResidues(Datablock& db, std::vector<TLSResidue>& residues, int indentLevel) const
virtual void CollectResidues(Datablock& db, std::vector<TLSResidue>& residues, std::size_t indentLevel) const
{
bool allChains = m_chain == "*";
@@ -304,7 +302,7 @@ struct TLSSelectionResID : public TLSSelectionAll
TLSSelectionResID(int seqNr, char iCode)
: m_seq_nr(seqNr), m_icode(iCode) {}
virtual void CollectResidues(Datablock& db, std::vector<TLSResidue>& residues, int indentLevel) const
virtual void CollectResidues(Datablock& db, std::vector<TLSResidue>& residues, std::size_t indentLevel) const
{
for (auto& r: residues)
r.selected = r.seqNr == m_seq_nr and r.iCode == m_icode;
@@ -325,7 +323,7 @@ struct TLSSelectionRangeSeq : public TLSSelectionAll
TLSSelectionRangeSeq(int first, int last)
: m_first(first), m_last(last) {}
virtual void CollectResidues(Datablock& db, std::vector<TLSResidue>& residues, int indentLevel) const
virtual void CollectResidues(Datablock& db, std::vector<TLSResidue>& residues, std::size_t indentLevel) const
{
for (auto& r: residues)
{
@@ -348,7 +346,7 @@ struct TLSSelectionRangeID : public TLSSelectionAll
TLSSelectionRangeID(int first, int last, char icodeFirst = 0, char icodeLast = 0)
: m_first(first), m_last(last), m_icode_first(icodeFirst), m_icode_last(icodeLast) {}
virtual void CollectResidues(Datablock& db, std::vector<TLSResidue>& residues, int indentLevel) const
virtual void CollectResidues(Datablock& db, std::vector<TLSResidue>& residues, std::size_t indentLevel) const
{
// need to do this per chain
std::set<std::string> chains;
@@ -395,7 +393,7 @@ struct TLSSelectionUnion : public TLSSelection
TLSSelectionUnion(TLSSelectionPtr& lhs, TLSSelectionPtr&& rhs)
: lhs(lhs.release()), rhs(rhs.release()) {}
virtual void CollectResidues(Datablock& db, std::vector<TLSResidue>& residues, int indentLevel) const
virtual void CollectResidues(Datablock& db, std::vector<TLSResidue>& residues, std::size_t indentLevel) const
{
auto a = residues;
for_each(a.begin(), a.end(), [](auto& r) { r.selected = false; });
@@ -428,7 +426,7 @@ struct TLSSelectionIntersection : public TLSSelection
TLSSelectionIntersection(TLSSelectionPtr& lhs, TLSSelectionPtr&& rhs)
: lhs(lhs.release()), rhs(rhs.release()) {}
virtual void CollectResidues(Datablock& db, std::vector<TLSResidue>& residues, int indentLevel) const
virtual void CollectResidues(Datablock& db, std::vector<TLSResidue>& residues, std::size_t indentLevel) const
{
auto a = residues;
for_each(a.begin(), a.end(), [](auto& r) { r.selected = false; });
@@ -459,7 +457,7 @@ struct TLSSelectionByName : public TLSSelectionAll
TLSSelectionByName(const std::string& resname)
: m_name(resname) {}
virtual void CollectResidues(Datablock& db, std::vector<TLSResidue>& residues, int indentLevel) const
virtual void CollectResidues(Datablock& db, std::vector<TLSResidue>& residues, std::size_t indentLevel) const
{
for (auto& r: residues)
r.selected = r.name == m_name;
@@ -480,7 +478,7 @@ struct TLSSelectionByElement : public TLSSelectionAll
TLSSelectionByElement(const std::string& element)
: m_element(element) {}
virtual void CollectResidues(Datablock& db, std::vector<TLSResidue>& residues, int indentLevel) const
virtual void CollectResidues(Datablock& db, std::vector<TLSResidue>& residues, std::size_t indentLevel) const
{
// rationale... We want to select residues only. So we select
// residues that have just a single atom of type m_element.
@@ -518,7 +516,7 @@ class TLSSelectionParserImpl
std::string m_selection;
std::string::iterator m_p, m_end;
int m_lookahead;
int m_lookahead = 0;
std::string m_token;
};

5
src/revision.hpp.in Normal file
View File

@@ -0,0 +1,5 @@
const char kRevision[] = R"(
lib@PROJECT_NAME@-version: @PROJECT_VERSION@
@BUILD_VERSION_STRING@
Date: @BUILD_DATE_TIME@
)";

189
test/RXA.cif Normal file
View File

@@ -0,0 +1,189 @@
data_RXA
#
_chem_comp.id RXA
_chem_comp.name "RENAMED RETINOIC ACID"
_chem_comp.type NON-POLYMER
_chem_comp.pdbx_type HETAIN
_chem_comp.formula "C20 H28 O2"
_chem_comp.mon_nstd_parent_comp_id ?
_chem_comp.pdbx_synonyms ?
_chem_comp.pdbx_formal_charge 0
_chem_comp.pdbx_initial_date 1999-07-08
_chem_comp.pdbx_modified_date 2016-10-18
_chem_comp.pdbx_ambiguous_flag N
_chem_comp.pdbx_release_status REL
_chem_comp.pdbx_replaced_by ?
_chem_comp.pdbx_replaces 3KV
_chem_comp.formula_weight 300.435
_chem_comp.one_letter_code ?
_chem_comp.three_letter_code RXA
_chem_comp.pdbx_model_coordinates_details ?
_chem_comp.pdbx_model_coordinates_missing_flag N
_chem_comp.pdbx_ideal_coordinates_details Corina
_chem_comp.pdbx_ideal_coordinates_missing_flag N
_chem_comp.pdbx_model_coordinates_db_code 1CBS
_chem_comp.pdbx_subcomponent_list ?
_chem_comp.pdbx_processing_site RCSB
#
loop_
_chem_comp_atom.comp_id
_chem_comp_atom.atom_id
_chem_comp_atom.alt_atom_id
_chem_comp_atom.type_symbol
_chem_comp_atom.charge
_chem_comp_atom.pdbx_align
_chem_comp_atom.pdbx_aromatic_flag
_chem_comp_atom.pdbx_leaving_atom_flag
_chem_comp_atom.pdbx_stereo_config
_chem_comp_atom.model_Cartn_x
_chem_comp_atom.model_Cartn_y
_chem_comp_atom.model_Cartn_z
_chem_comp_atom.pdbx_model_Cartn_x_ideal
_chem_comp_atom.pdbx_model_Cartn_y_ideal
_chem_comp_atom.pdbx_model_Cartn_z_ideal
_chem_comp_atom.pdbx_component_atom_id
_chem_comp_atom.pdbx_component_comp_id
_chem_comp_atom.pdbx_ordinal
RXA C1 C1 C 0 1 N N N 21.972 29.831 16.739 -4.684 0.932 -0.497 C1 RXA 1
RXA C2 C2 C 0 1 N N N 20.921 30.524 15.841 -5.837 0.190 -1.176 C2 RXA 2
RXA C3 C3 C 0 1 N N N 20.245 29.635 14.848 -6.441 -0.798 -0.171 C3 RXA 3
RXA C4 C4 C 0 1 N N N 19.555 28.479 15.488 -5.418 -1.903 0.100 C4 RXA 4
RXA C5 C5 C 0 1 N N N 20.389 27.812 16.587 -4.082 -1.301 0.429 C5 RXA 5
RXA C6 C6 C 0 1 N N N 21.425 28.446 17.218 -3.756 -0.048 0.161 C6 RXA 6
RXA C7 C7 C 0 1 N N N 22.242 27.851 18.297 -2.457 0.396 0.516 C7 RXA 7
RXA C8 C8 C 0 1 N N N 21.868 26.977 19.240 -1.363 -0.229 0.007 C8 RXA 8
RXA C9 C9 C 0 1 N N N 22.705 26.434 20.286 -0.076 0.257 0.298 C9 RXA 9
RXA C10 C10 C 0 1 N N N 22.159 25.536 21.131 1.022 -0.370 -0.213 C10 RXA 10
RXA C11 C11 C 0 1 N N N 22.875 24.924 22.234 2.306 0.115 0.077 C11 RXA 11
RXA C12 C12 C 0 1 N N N 22.237 24.026 22.990 3.405 -0.513 -0.435 C12 RXA 12
RXA C13 C13 C 0 1 N N N 22.856 23.377 24.125 4.689 -0.028 -0.144 C13 RXA 13
RXA C14 C14 C 0 1 N N N 22.135 22.473 24.834 5.787 -0.655 -0.656 C14 RXA 14
RXA C15 C15 C 0 1 N N N 22.563 21.710 26.016 7.077 -0.265 -0.244 C15 RXA 15
RXA C16 C16 C 0 1 N N N 22.238 30.737 17.948 -5.246 1.886 0.559 C16 RXA 16
RXA C17 C17 C 0 1 N N N 23.292 29.620 15.948 -3.911 1.737 -1.544 C17 RXA 17
RXA C18 C18 C 0 1 N N N 19.791 26.449 16.947 -3.056 -2.175 1.103 C18 RXA 18
RXA C19 C19 C 0 1 N N N 24.181 26.841 20.385 0.090 1.471 1.175 C19 RXA 19
RXA C20 C20 C 0 1 N N N 24.303 23.747 24.489 4.855 1.186 0.733 C20 RXA 20
RXA O1 O1 O 0 1 N N N 23.640 21.075 25.978 7.210 0.553 0.648 O1 RXA 21
RXA O2 O2 O 0 1 N N N 21.840 21.712 27.037 8.166 -0.798 -0.840 O2 RXA 22
RXA H21 H21 H 0 1 N N N 20.147 30.955 16.494 -6.598 0.905 -1.490 H21 RXA 23
RXA H22 H22 H 0 1 N N N 21.425 31.330 15.288 -5.462 -0.353 -2.044 H22 RXA 24
RXA H31 H31 H 0 1 N N N 19.501 30.227 14.295 -6.673 -0.278 0.759 H31 RXA 25
RXA H32 H32 H 0 1 N N N 21.001 29.250 14.148 -7.349 -1.234 -0.586 H32 RXA 26
RXA H41 H41 H 0 1 N N N 18.613 28.835 15.931 -5.756 -2.511 0.938 H41 RXA 27
RXA H42 H42 H 0 1 N N N 19.335 27.730 14.713 -5.322 -2.531 -0.786 H42 RXA 28
RXA H7 H7 H 0 1 N N N 23.276 28.162 18.329 -2.337 1.230 1.191 H7 RXA 29
RXA H8 H8 H 0 1 N N N 20.840 26.645 19.217 -1.482 -1.100 -0.622 H8 RXA 30
RXA H10 H10 H 0 1 N N N 21.127 25.256 20.977 0.903 -1.241 -0.842 H10 RXA 31
RXA H11 H11 H 0 1 N N N 23.902 25.189 22.440 2.425 0.985 0.706 H11 RXA 32
RXA H12 H12 H 0 1 N N N 21.216 23.774 22.743 3.286 -1.383 -1.063 H12 RXA 33
RXA H14 H14 H 0 1 N N N 21.127 22.292 24.490 5.667 -1.451 -1.376 H14 RXA 34
RXA H161 H161 H 0 0 N N N 22.984 30.265 18.604 -5.802 1.316 1.303 H161 RXA 35
RXA H162 H162 H 0 0 N N N 22.618 31.709 17.601 -4.426 2.415 1.044 H162 RXA 36
RXA H163 H163 H 0 0 N N N 21.302 30.887 18.506 -5.911 2.605 0.081 H163 RXA 37
RXA H171 H171 H 0 0 N N N 24.033 29.127 16.595 -4.598 2.394 -2.077 H171 RXA 38
RXA H172 H172 H 0 0 N N N 23.095 28.989 15.069 -3.146 2.335 -1.050 H172 RXA 39
RXA H173 H173 H 0 0 N N N 23.683 30.595 15.620 -3.439 1.054 -2.251 H173 RXA 40
RXA H181 H181 H 0 0 N N N 20.397 25.979 17.736 -3.448 -3.187 1.201 H181 RXA 41
RXA H182 H182 H 0 0 N N N 18.761 26.584 17.308 -2.145 -2.194 0.503 H182 RXA 42
RXA H183 H183 H 0 0 N N N 19.786 25.804 16.056 -2.831 -1.775 2.092 H183 RXA 43
RXA H191 H191 H 0 0 N N N 24.647 26.327 21.238 0.171 1.159 2.216 H191 RXA 44
RXA H192 H192 H 0 0 N N N 24.702 26.559 19.458 0.993 2.008 0.885 H192 RXA 45
RXA H193 H193 H 0 0 N N N 24.252 27.929 20.529 -0.774 2.125 1.058 H193 RXA 46
RXA H201 H201 H 0 0 N N N 24.620 23.168 25.369 5.026 0.871 1.762 H201 RXA 47
RXA H202 H202 H 0 0 N N N 24.965 23.516 23.641 5.707 1.771 0.386 H202 RXA 48
RXA H203 H203 H 0 0 N N N 24.360 24.822 24.717 3.952 1.795 0.685 H203 RXA 49
RXA HO2 HO2 H 0 1 N N N 22.244 21.180 27.713 9.006 -0.469 -0.490 HO2 RXA 50
#
loop_
_chem_comp_bond.comp_id
_chem_comp_bond.atom_id_1
_chem_comp_bond.atom_id_2
_chem_comp_bond.value_order
_chem_comp_bond.pdbx_aromatic_flag
_chem_comp_bond.pdbx_stereo_config
_chem_comp_bond.pdbx_ordinal
RXA C1 C2 SING N N 1
RXA C1 C6 SING N N 2
RXA C1 C16 SING N N 3
RXA C1 C17 SING N N 4
RXA C2 C3 SING N N 5
RXA C2 H21 SING N N 6
RXA C2 H22 SING N N 7
RXA C3 C4 SING N N 8
RXA C3 H31 SING N N 9
RXA C3 H32 SING N N 10
RXA C4 C5 SING N N 11
RXA C4 H41 SING N N 12
RXA C4 H42 SING N N 13
RXA C5 C6 DOUB N N 14
RXA C5 C18 SING N N 15
RXA C6 C7 SING N N 16
RXA C7 C8 DOUB N E 17
RXA C7 H7 SING N N 18
RXA C8 C9 SING N N 19
RXA C8 H8 SING N N 20
RXA C9 C10 DOUB N E 21
RXA C9 C19 SING N N 22
RXA C10 C11 SING N N 23
RXA C10 H10 SING N N 24
RXA C11 C12 DOUB N E 25
RXA C11 H11 SING N N 26
RXA C12 C13 SING N N 27
RXA C12 H12 SING N N 28
RXA C13 C14 DOUB N E 29
RXA C13 C20 SING N N 30
RXA C14 C15 SING N N 31
RXA C14 H14 SING N N 32
RXA C15 O1 DOUB N N 33
RXA C15 O2 SING N N 34
RXA C16 H161 SING N N 35
RXA C16 H162 SING N N 36
RXA C16 H163 SING N N 37
RXA C17 H171 SING N N 38
RXA C17 H172 SING N N 39
RXA C17 H173 SING N N 40
RXA C18 H181 SING N N 41
RXA C18 H182 SING N N 42
RXA C18 H183 SING N N 43
RXA C19 H191 SING N N 44
RXA C19 H192 SING N N 45
RXA C19 H193 SING N N 46
RXA C20 H201 SING N N 47
RXA C20 H202 SING N N 48
RXA C20 H203 SING N N 49
RXA O2 HO2 SING N N 50
#
loop_
_pdbx_chem_comp_descriptor.comp_id
_pdbx_chem_comp_descriptor.type
_pdbx_chem_comp_descriptor.program
_pdbx_chem_comp_descriptor.program_version
_pdbx_chem_comp_descriptor.descriptor
RXA SMILES ACDLabs 12.01 "C1(CCCC(=C1\C=C\C(=C\C=C\C(=C\C(=O)O)C)C)C)(C)C"
RXA InChI InChI 1.03 "InChI=1S/C20H28O2/c1-15(8-6-9-16(2)14-19(21)22)11-12-18-17(3)10-7-13-20(18,4)5/h6,8-9,11-12,14H,7,10,13H2,1-5H3,(H,21,22)/b9-6+,12-11+,15-8+,16-14+"
RXA InChIKey InChI 1.03 SHGAZHPCJJPHSC-YCNIQYBTSA-N
RXA SMILES_CANONICAL CACTVS 3.385 "CC1=C(\C=C\C(C)=C\C=C\C(C)=C\C(O)=O)C(C)(C)CCC1"
RXA SMILES CACTVS 3.385 "CC1=C(C=CC(C)=CC=CC(C)=CC(O)=O)C(C)(C)CCC1"
RXA SMILES_CANONICAL "OpenEye OEToolkits" 1.7.6 "CC1=C(C(CCC1)(C)C)/C=C/C(=C/C=C/C(=C/C(=O)O)/C)/C"
RXA SMILES "OpenEye OEToolkits" 1.7.6 "CC1=C(C(CCC1)(C)C)C=CC(=CC=CC(=CC(=O)O)C)C"
#
loop_
_pdbx_chem_comp_identifier.comp_id
_pdbx_chem_comp_identifier.type
_pdbx_chem_comp_identifier.program
_pdbx_chem_comp_identifier.program_version
_pdbx_chem_comp_identifier.identifier
RXA "SYSTEMATIC NAME" ACDLabs 12.01 "retinoic acid"
RXA "SYSTEMATIC NAME" "OpenEye OEToolkits" 1.7.6 "(2E,4E,6E,8E)-3,7-dimethyl-9-(2,6,6-trimethylcyclohexen-1-yl)nona-2,4,6,8-tetraenoic acid"
#
loop_
_pdbx_chem_comp_audit.comp_id
_pdbx_chem_comp_audit.action_type
_pdbx_chem_comp_audit.date
_pdbx_chem_comp_audit.processing_site
RXA "Create component" 1999-07-08 RCSB
RXA "Modify descriptor" 2011-06-04 RCSB
RXA "Other modification" 2016-10-18 RCSB
#

152
test/UN_.cif Normal file
View File

@@ -0,0 +1,152 @@
#
data_comp_list
loop_
_chem_comp.id
_chem_comp.three_letter_code
_chem_comp.name
_chem_comp.group
_chem_comp.number_atoms_all
_chem_comp.number_atoms_nh
_chem_comp.desc_level
UN_ UN_ UN_NINE L-peptide 13 6 .
#
data_comp_UN_
#
loop_
_chem_comp_atom.comp_id
_chem_comp_atom.atom_id
_chem_comp_atom.type_symbol
_chem_comp_atom.type_energy
_chem_comp_atom.charge
_chem_comp_atom.x
_chem_comp_atom.y
_chem_comp_atom.z
UN_ N N NT3 1 0.227 -1.259 0.452
UN_ H H H 0 0.069 -1.019 1.421
UN_ H2 H H 0 1.104 -1.640 0.356
UN_ H3 H H 0 -0.424 -1.909 0.174
UN_ CA C CH1 0 0.103 -0.030 -0.392
UN_ HA H H 0 0.160 -0.299 -1.339
UN_ CB C CH3 0 -1.244 0.625 -0.159
UN_ HB3 H H 0 -1.857 -0.018 0.234
UN_ HB2 H H 0 -1.605 0.932 -1.008
UN_ HB1 H H 0 -1.150 1.385 0.442
UN_ C C C 0 1.270 0.922 -0.094
UN_ O O O 0 2.008 1.323 -0.994
UN_ OXT O OC -1 1.498 1.305 1.054
loop_
_chem_comp_tree.comp_id
_chem_comp_tree.atom_id
_chem_comp_tree.atom_back
_chem_comp_tree.atom_forward
_chem_comp_tree.connect_type
UN_ N n/a CA START
UN_ H N . .
UN_ H2 N . .
UN_ H3 N . .
UN_ CA N C .
UN_ HA CA . .
UN_ CB CA HB3 .
UN_ HB1 CB . .
UN_ HB2 CB . .
UN_ HB3 CB . .
UN_ C CA . END
UN_ O C . .
UN_ OXT C . .
loop_
_chem_comp_bond.comp_id
_chem_comp_bond.atom_id_1
_chem_comp_bond.atom_id_2
_chem_comp_bond.type
_chem_comp_bond.aromatic
_chem_comp_bond.value_dist
_chem_comp_bond.value_dist_esd
UN_ CB CA SINGLE n 1.509 0.014
UN_ CA C SINGLE n 1.533 0.011
UN_ C O DOUBLE n 1.247 0.019
UN_ C OXT SINGLE n 1.247 0.019
UN_ CA N SINGLE n 1.482 0.010
UN_ CB HB3 SINGLE n 0.972 0.015
UN_ CB HB2 SINGLE n 0.972 0.015
UN_ CB HB1 SINGLE n 0.972 0.015
UN_ CA HA SINGLE n 0.986 0.020
UN_ N H SINGLE n 0.911 0.020
UN_ N H2 SINGLE n 0.911 0.020
UN_ N H3 SINGLE n 0.911 0.020
loop_
_chem_comp_angle.comp_id
_chem_comp_angle.atom_id_1
_chem_comp_angle.atom_id_2
_chem_comp_angle.atom_id_3
_chem_comp_angle.value_angle
_chem_comp_angle.value_angle_esd
UN_ CA CB HB3 109.546 1.50
UN_ CA CB HB2 109.546 1.50
UN_ CA CB HB1 109.546 1.50
UN_ HB3 CB HB2 109.386 1.50
UN_ HB3 CB HB1 109.386 1.50
UN_ HB2 CB HB1 109.386 1.50
UN_ CB CA C 111.490 1.50
UN_ CB CA N 109.912 1.50
UN_ CB CA HA 108.878 1.50
UN_ C CA N 109.627 1.50
UN_ C CA HA 108.541 1.50
UN_ N CA HA 108.529 1.50
UN_ CA C O 117.159 1.57
UN_ CA C OXT 117.159 1.57
UN_ O C OXT 125.683 1.50
UN_ CA N H 109.643 1.50
UN_ CA N H2 109.643 1.50
UN_ CA N H3 109.643 1.50
UN_ H N H2 109.028 2.41
UN_ H N H3 109.028 2.41
UN_ H2 N H3 109.028 2.41
loop_
_chem_comp_tor.comp_id
_chem_comp_tor.id
_chem_comp_tor.atom_id_1
_chem_comp_tor.atom_id_2
_chem_comp_tor.atom_id_3
_chem_comp_tor.atom_id_4
_chem_comp_tor.value_angle
_chem_comp_tor.value_angle_esd
_chem_comp_tor.period
UN_ hh1 N CA CB HB3 60.000 15.000 3
UN_ sp2_sp3_1 O C CA CB 0.000 10.00 6
UN_ sp3_sp3_10 CB CA N H 180.000 10.00 3
loop_
_chem_comp_chir.comp_id
_chem_comp_chir.id
_chem_comp_chir.atom_id_centre
_chem_comp_chir.atom_id_1
_chem_comp_chir.atom_id_2
_chem_comp_chir.atom_id_3
_chem_comp_chir.volume_sign
UN_ chir_1 CA N C CB positive
loop_
_chem_comp_plane_atom.comp_id
_chem_comp_plane_atom.plane_id
_chem_comp_plane_atom.atom_id
_chem_comp_plane_atom.dist_esd
UN_ plan-1 C 0.020
UN_ plan-1 CA 0.020
UN_ plan-1 O 0.020
UN_ plan-1 OXT 0.020
loop_
_pdbx_chem_comp_descriptor.comp_id
_pdbx_chem_comp_descriptor.type
_pdbx_chem_comp_descriptor.program
_pdbx_chem_comp_descriptor.program_version
_pdbx_chem_comp_descriptor.descriptor
UN_ SMILES ACDLabs 10.04 "O=C(O)C(N)C"
UN_ SMILES_CANONICAL CACTVS 3.341 "C[C@H](N)C(O)=O"
UN_ SMILES CACTVS 3.341 "C[CH](N)C(O)=O"
UN_ SMILES_CANONICAL "OpenEye OEToolkits" 1.5.0 "C[C@@H](C(=O)O)N"
UN_ SMILES "OpenEye OEToolkits" 1.5.0 "CC(C(=O)O)N"
UN_ InChI InChI 1.03 "InChI=1S/C3H7NO2/c1-2(4)3(5)6/h2H,4H2,1H3,(H,5,6)/t2-/m0/s1"
UN_ InChIKey InChI 1.03 QNAYBMKLOCPYGJ-REOHCLBHSA-N
UN_ ? acedrg 195 "dictionary generator"
UN_ ? acedrg_database 11 "data source"
UN_ ? rdkit 2017.03.2 "Chemoinformatics tool"
UN_ ? refmac5 5.8.0189 "optimization tool"

57
test/pdb2cif-test.cpp Normal file
View File

@@ -0,0 +1,57 @@
#include "../include/cif++/Cif++.hpp"
#include "../include/cif++/PDB2Cif.hpp"
#include <iostream>
#include <fstream>
#include <boost/program_options.hpp>
// #include "pdb2cif.h"
namespace po = boost::program_options;
int main(int argc, char* argv[])
{
using namespace std::literals;
po::options_description desc("pdb2cif-test options");
desc.add_options()
("input,i", po::value<std::string>(), "Input file")
("help,h", "Display help message")
("version", "Print version")
("verbose,v", "Verbose output")
("debug,d", po::value<int>(), "Debug level (for even more verbose output)");
po::positional_options_description p;
p.add("input", 1);
po::variables_map vm;
po::store(po::command_line_parser(argc, argv).options(desc).positional(p).run(), vm);
po::notify(vm);
if (vm.count("version"))
{
std::cout << argv[0] << " version " PACKAGE_VERSION << std::endl;
exit(0);
}
if (vm.count("help") or vm.count("input") == 0)
{
std::cerr << desc << std::endl;
exit(1);
}
cif::VERBOSE = vm.count("verbose") != 0;
if (vm.count("debug"))
cif::VERBOSE = vm["debug"].as<int>();
std::ifstream is(vm["input"].as<std::string>());
if (not is.is_open())
throw std::runtime_error("Could not open file " + vm["input"].as<std::string>());
cif::File f;
ReadPDBFile(is, f);
f.save(std::cout);
return 0;
}

View File

@@ -0,0 +1,45 @@
#include "../include/cif++/Cif++.hpp"
#include "../include/cif++/PDB2Cif.hpp"
#include "../include/cif++/Structure.hpp"
#include <iostream>
#include <fstream>
#include <boost/program_options.hpp>
namespace po = boost::program_options;
int main(int argc, char* argv[])
{
cif::VERBOSE = 3;
try
{
std::filesystem::path testdir = std::filesystem::current_path();
if (argc == 3)
testdir = argv[2];
if (std::filesystem::exists(testdir / ".."/"data"/"components.cif"))
cif::addFileResource("components.cif", testdir / ".."/"data"/"components.cif");
mmcif::CompoundFactory::instance().pushDictionary(testdir / "RXA.cif");
mmcif::File f(testdir / ".."/"examples"/"1cbs.cif.gz");
mmcif::Structure structure(f);
auto &res = structure.getResidue("B", "REA");
structure.changeResidue(res, "RXA", {});
structure.cleanupEmptyCategories();
f.file().save(std::cout);
}
catch (const std::exception& e)
{
std::cerr << e.what() << std::endl;
exit(1);
}
return 0;
}

161
test/structure-test.cpp Normal file
View File

@@ -0,0 +1,161 @@
/*-
* SPDX-License-Identifier: BSD-2-Clause
*
* Copyright (c) 2021 NKI/AVL, Netherlands Cancer Institute
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#define BOOST_TEST_MODULE Structure_Test
#include <boost/test/included/unit_test.hpp>
#include <stdexcept>
#include "cif++/Cif++.hpp"
#include "cif++/Structure.hpp"
// --------------------------------------------------------------------
cif::File operator""_cf(const char* text, size_t length)
{
struct membuf : public std::streambuf
{
membuf(char* text, size_t length)
{
this->setg(text, text, text + length);
}
} buffer(const_cast<char*>(text), length);
std::istream is(&buffer);
return cif::File(is);
}
// --------------------------------------------------------------------
BOOST_AUTO_TEST_CASE(create_nonpoly_1)
{
cif::VERBOSE = 1;
// do this now, avoids the need for installing
cif::addFileResource("mmcif_pdbx_v50.dic", "../rsrc/mmcif_pdbx_v50.dic");
mmcif::File file;
file.file().loadDictionary("mmcif_pdbx_v50.dic");
file.createDatablock("TEST"); // create a datablock
mmcif::Structure structure(file);
std::string entity_id = structure.createNonPolyEntity("HEM");
auto atoms = R"(
data_HEM
loop_
_atom_site.group_PDB
_atom_site.type_symbol
_atom_site.label_atom_id
_atom_site.label_alt_id
_atom_site.pdbx_PDB_ins_code
_atom_site.Cartn_x
_atom_site.Cartn_y
_atom_site.Cartn_z
_atom_site.occupancy
_atom_site.B_iso_or_equiv
_atom_site.pdbx_formal_charge
HETATM C CHA . ? -5.248 39.769 -0.250 1.00 7.67 ?
HETATM C CHB . ? -3.774 36.790 3.280 1.00 7.05 ?
HETATM C CHC . ? -2.879 33.328 0.013 1.00 7.69 ?
HETATM C CHD . ? -4.342 36.262 -3.536 1.00 8.00 ?
# that's enough to test with
)"_cf;
auto &hem_data = atoms["HEM"];
auto &atom_site = hem_data["atom_site"];
auto hem_atoms = atom_site.rows();
std::vector<mmcif::Atom> atom_data;
for (auto &hem_atom: hem_atoms)
atom_data.emplace_back(hem_data, hem_atom);
structure.createNonpoly(entity_id, atom_data);
auto expected = R"(
data_TEST
#
loop_
_atom_site.id
_atom_site.auth_asym_id
_atom_site.label_alt_id
_atom_site.label_asym_id
_atom_site.label_atom_id
_atom_site.label_comp_id
_atom_site.label_entity_id
_atom_site.label_seq_id
_atom_site.type_symbol
_atom_site.group_PDB
_atom_site.pdbx_PDB_ins_code
_atom_site.Cartn_x
_atom_site.Cartn_y
_atom_site.Cartn_z
_atom_site.occupancy
_atom_site.B_iso_or_equiv
_atom_site.pdbx_formal_charge
_atom_site.auth_seq_id
_atom_site.auth_comp_id
_atom_site.auth_atom_id
_atom_site.pdbx_PDB_model_num
1 A ? A CHA HEM 1 . C HETATM ? -5.248 39.769 -0.250 1.00 7.67 ? ? HEM CHA 1
2 A ? A CHB HEM 1 . C HETATM ? -3.774 36.790 3.280 1.00 7.05 ? ? HEM CHB 1
3 A ? A CHC HEM 1 . C HETATM ? -2.879 33.328 0.013 1.00 7.69 ? ? HEM CHC 1
4 A ? A CHD HEM 1 . C HETATM ? -4.342 36.262 -3.536 1.00 8.00 ? ? HEM CHD 1
#
_chem_comp.id HEM
_chem_comp.type NON-POLYMER
_chem_comp.name 'PROTOPORPHYRIN IX CONTAINING FE'
_chem_comp.formula 'C34 H32 Fe N4 O4'
_chem_comp.formula_weight 616.487000
#
_pdbx_entity_nonpoly.entity_id 1
_pdbx_entity_nonpoly.name 'PROTOPORPHYRIN IX CONTAINING FE'
_pdbx_entity_nonpoly.comp_id HEM
#
_entity.id 1
_entity.type non-polymer
_entity.pdbx_description 'PROTOPORPHYRIN IX CONTAINING FE'
_entity.formula_weight 616.487000
#
_struct_asym.id A
_struct_asym.entity_id 1
_struct_asym.pdbx_blank_PDB_chainid_flag N
_struct_asym.pdbx_modified N
_struct_asym.details ?
#
)"_cf;
expected.loadDictionary("mmcif_pdbx_v50.dic");
if (not (expected.firstDatablock() == structure.getFile().data()))
{
BOOST_TEST(false);
std::cout << expected.firstDatablock() << std::endl
<< std::endl
<< structure.getFile().data() << std::endl;
}
}

View File

@@ -31,6 +31,9 @@
// #include "cif++/DistanceMap.hpp"
#include "cif++/Cif++.hpp"
#include "cif++/BondMap.hpp"
std::filesystem::path gTestDir = std::filesystem::current_path(); // filled in first test
// --------------------------------------------------------------------
@@ -50,10 +53,23 @@ cif::File operator""_cf(const char* text, size_t length)
// --------------------------------------------------------------------
BOOST_AUTO_TEST_CASE(init)
{
// not a test, just initialize test dir
if (boost::unit_test::framework::master_test_suite().argc == 2)
gTestDir = boost::unit_test::framework::master_test_suite().argv[1];
}
// --------------------------------------------------------------------
BOOST_AUTO_TEST_CASE(ut1)
{
cif::VERBOSE = 1;
// do this now, avoids the need for installing
cif::addFileResource("mmcif_pdbx_v50.dic", gTestDir / ".." / "rsrc" / "mmcif_pdbx_v50.dic");
// using namespace mmcif;
auto f = R"(data_TEST
@@ -1154,7 +1170,7 @@ _test.name
// query tests
for (const auto& [id, name]: db["test"].rows<int, std::optional<std::string>>({ "id", "name" }))
for (const auto& [id, name]: db["test"].rows<int, std::optional<std::string>>("id", "name"))
{
switch (id)
{
@@ -1189,7 +1205,7 @@ _test.name
auto& db = f.firstDatablock();
// query tests
for (const auto& [id, name]: db["test"].find<int, std::optional<std::string>>(cif::All(), { "id", "name" }))
for (const auto& [id, name]: db["test"].find<int, std::optional<std::string>>(cif::All(), "id", "name"))
{
switch (id)
{
@@ -1203,8 +1219,469 @@ _test.name
}
}
const auto& [id, name] = db["test"].find1<int, std::string>(cif::Key("id") == 1, { "id", "name" });
const auto& [id, name] = db["test"].find1<int, std::string>(cif::Key("id") == 1, "id", "name");
BOOST_CHECK(id == 1);
BOOST_CHECK(name == "aap");
}
// --------------------------------------------------------------------
// rename test
BOOST_AUTO_TEST_CASE(r1)
{
/*
Rationale:
The pdbx_mmcif dictionary contains inconsistent child-parent relations. E.g. atom_site is parent
of pdbx_nonpoly_scheme which itself is a parent of pdbx_entity_nonpoly. If I want to rename a residue
I cannot update pdbx_nonpoly_scheme since changing a parent changes children, but not vice versa.
But if I change the comp_id in atom_site, the pdbx_nonpoly_scheme is update, that's good, and then
pdbx_entity_nonpoly is updated and that's bad.
The idea is now that if we update a parent and a child that must change as well, we first check
if there are more parents of this child that will not change. In that case we have to split the
child into two, one with the new value and one with the old. We then of course have to split all
children of this split row that are direct children.
*/
const char dict[] = R"(
data_test_dict.dic
_datablock.id test_dict.dic
_datablock.description
;
A test dictionary
;
_dictionary.title test_dict.dic
_dictionary.datablock_id test_dict.dic
_dictionary.version 1.0
loop_
_item_type_list.code
_item_type_list.primitive_code
_item_type_list.construct
code char
'[][_,.;:"&<>()/\{}'`~!@#$%A-Za-z0-9*|+-]*'
text char
'[][ \n\t()_,.;:"&<>/\{}'`~!@#$%?+=*A-Za-z0-9|^-]*'
int numb
'[+-]?[0-9]+'
save_cat_1
_category.description 'A simple test category'
_category.id cat_1
_category.mandatory_code no
_category_key.name '_cat_1.id'
save_
save__cat_1.id
_item.name '_cat_1.id'
_item.category_id cat_1
_item.mandatory_code yes
_item_linked.child_name '_cat_2.parent_id'
_item_linked.parent_name '_cat_1.id'
_item_type.code int
save_
save__cat_1.name
_item.name '_cat_1.name'
_item.category_id cat_1
_item.mandatory_code yes
_item_type.code code
save_
save__cat_1.desc
_item.name '_cat_1.desc'
_item.category_id cat_1
_item.mandatory_code yes
_item_type.code text
save_
save_cat_2
_category.description 'A second simple test category'
_category.id cat_2
_category.mandatory_code no
_category_key.name '_cat_2.id'
save_
save__cat_2.id
_item.name '_cat_2.id'
_item.category_id cat_2
_item.mandatory_code yes
_item_type.code int
save_
save__cat_2.name
_item.name '_cat_2.name'
_item.category_id cat_2
_item.mandatory_code yes
_item_type.code code
save_
save__cat_2.num
_item.name '_cat_2.num'
_item.category_id cat_2
_item.mandatory_code yes
_item_type.code int
save_
save__cat_2.desc
_item.name '_cat_2.desc'
_item.category_id cat_2
_item.mandatory_code yes
_item_type.code text
save_
save_cat_3
_category.description 'A third simple test category'
_category.id cat_3
_category.mandatory_code no
_category_key.name '_cat_3.id'
save_
save__cat_3.id
_item.name '_cat_3.id'
_item.category_id cat_3
_item.mandatory_code yes
_item_type.code int
save_
save__cat_3.name
_item.name '_cat_3.name'
_item.category_id cat_3
_item.mandatory_code yes
_item_type.code code
save_
save__cat_3.num
_item.name '_cat_3.num'
_item.category_id cat_3
_item.mandatory_code yes
_item_type.code int
save_
loop_
_pdbx_item_linked_group_list.child_category_id
_pdbx_item_linked_group_list.link_group_id
_pdbx_item_linked_group_list.child_name
_pdbx_item_linked_group_list.parent_name
_pdbx_item_linked_group_list.parent_category_id
cat_1 1 '_cat_1.name' '_cat_2.name' cat_2
cat_2 1 '_cat_2.name' '_cat_3.name' cat_3
cat_2 1 '_cat_2.num' '_cat_3.num' cat_3
)";
struct membuf : public std::streambuf
{
membuf(char* text, size_t length)
{
this->setg(text, text, text + length);
}
} buffer(const_cast<char*>(dict), sizeof(dict) - 1);
std::istream is_dict(&buffer);
cif::File f;
f.loadDictionary(is_dict);
// --------------------------------------------------------------------
const char data[] = R"(
data_test
loop_
_cat_1.id
_cat_1.name
_cat_1.desc
1 aap Aap
2 noot Noot
3 mies Mies
loop_
_cat_2.id
_cat_2.name
_cat_2.num
_cat_2.desc
1 aap 1 'Een dier'
2 aap 2 'Een andere aap'
3 noot 1 'walnoot bijvoorbeeld'
loop_
_cat_3.id
_cat_3.name
_cat_3.num
1 aap 1
2 aap 2
)";
using namespace cif::literals;
struct data_membuf : public std::streambuf
{
data_membuf(char* text, size_t length)
{
this->setg(text, text, text + length);
}
} data_buffer(const_cast<char*>(data), sizeof(data) - 1);
std::istream is_data(&data_buffer);
f.load(is_data);
auto& cat1 = f.firstDatablock()["cat_1"];
auto& cat2 = f.firstDatablock()["cat_2"];
auto& cat3 = f.firstDatablock()["cat_3"];
cat3.update_value("name"_key == "aap" and "num"_key == 1, "name", "aapje");
BOOST_CHECK(cat3.size() == 2);
{
int id, num;
std::string name;
cif::tie(id, name, num) = cat3.front().get("id", "name", "num");
BOOST_CHECK(id == 1);
BOOST_CHECK(num == 1);
BOOST_CHECK(name == "aapje");
cif::tie(id, name, num) = cat3.back().get("id", "name", "num");
BOOST_CHECK(id == 2);
BOOST_CHECK(num == 2);
BOOST_CHECK(name == "aap");
}
int i = 0;
for (const auto &[id, name, num, desc]: cat2.rows<int,std::string,int,std::string>("id", "name", "num", "desc"))
{
switch (++i)
{
case 1:
BOOST_CHECK(id == 1);
BOOST_CHECK(num == 1);
BOOST_CHECK(name == "aapje");
BOOST_CHECK(desc == "Een dier");
break;
case 2:
BOOST_CHECK(id == 2);
BOOST_CHECK(num == 2);
BOOST_CHECK(name == "aap");
BOOST_CHECK(desc == "Een andere aap");
break;
case 3:
BOOST_CHECK(id == 3);
BOOST_CHECK(num == 1);
BOOST_CHECK(name == "noot");
BOOST_CHECK(desc == "walnoot bijvoorbeeld");
break;
default:
BOOST_FAIL("Unexpected record");
}
}
BOOST_CHECK(cat1.size() == 4);
i = 0;
for (const auto &[id, name, desc]: cat1.rows<int,std::string,std::string>("id", "name", "desc"))
{
switch (++i)
{
case 1:
BOOST_CHECK(id == 1);
BOOST_CHECK(name == "aapje");
BOOST_CHECK(desc == "Aap");
break;
case 2:
BOOST_CHECK(id == 2);
BOOST_CHECK(name == "noot");
BOOST_CHECK(desc == "Noot");
break;
case 3:
BOOST_CHECK(id == 3);
BOOST_CHECK(name == "mies");
BOOST_CHECK(desc == "Mies");
break;
case 4:
BOOST_CHECK(id == 4);
BOOST_CHECK(name == "aap");
BOOST_CHECK(desc == "Aap");
break;
default:
BOOST_FAIL("Unexpected record");
}
}
f.save(std::cout);
}
// --------------------------------------------------------------------
BOOST_AUTO_TEST_CASE(bondmap_1)
{
cif::VERBOSE = 2;
cif::addFileResource("components.cif", gTestDir / ".." / "data" / "components.cif");
// sections taken from CCD compounds.cif
auto components = R"(
data_ASN
loop_
_chem_comp_bond.comp_id
_chem_comp_bond.atom_id_1
_chem_comp_bond.atom_id_2
_chem_comp_bond.value_order
_chem_comp_bond.pdbx_aromatic_flag
_chem_comp_bond.pdbx_stereo_config
_chem_comp_bond.pdbx_ordinal
ASN N CA SING N N 1
ASN N H SING N N 2
ASN N H2 SING N N 3
ASN CA C SING N N 4
ASN CA CB SING N N 5
ASN CA HA SING N N 6
ASN C O DOUB N N 7
ASN C OXT SING N N 8
ASN CB CG SING N N 9
ASN CB HB2 SING N N 10
ASN CB HB3 SING N N 11
ASN CG OD1 DOUB N N 12
ASN CG ND2 SING N N 13
ASN ND2 HD21 SING N N 14
ASN ND2 HD22 SING N N 15
ASN OXT HXT SING N N 16
data_PHE
loop_
_chem_comp_bond.comp_id
_chem_comp_bond.atom_id_1
_chem_comp_bond.atom_id_2
_chem_comp_bond.value_order
_chem_comp_bond.pdbx_aromatic_flag
_chem_comp_bond.pdbx_stereo_config
_chem_comp_bond.pdbx_ordinal
PHE N CA SING N N 1
PHE N H SING N N 2
PHE N H2 SING N N 3
PHE CA C SING N N 4
PHE CA CB SING N N 5
PHE CA HA SING N N 6
PHE C O DOUB N N 7
PHE C OXT SING N N 8
PHE CB CG SING N N 9
PHE CB HB2 SING N N 10
PHE CB HB3 SING N N 11
PHE CG CD1 DOUB Y N 12
PHE CG CD2 SING Y N 13
PHE CD1 CE1 SING Y N 14
PHE CD1 HD1 SING N N 15
PHE CD2 CE2 DOUB Y N 16
PHE CD2 HD2 SING N N 17
PHE CE1 CZ DOUB Y N 18
PHE CE1 HE1 SING N N 19
PHE CE2 CZ SING Y N 20
PHE CE2 HE2 SING N N 21
PHE CZ HZ SING N N 22
PHE OXT HXT SING N N 23
data_PRO
loop_
_chem_comp_bond.comp_id
_chem_comp_bond.atom_id_1
_chem_comp_bond.atom_id_2
_chem_comp_bond.value_order
_chem_comp_bond.pdbx_aromatic_flag
_chem_comp_bond.pdbx_stereo_config
_chem_comp_bond.pdbx_ordinal
PRO N CA SING N N 1
PRO N CD SING N N 2
PRO N H SING N N 3
PRO CA C SING N N 4
PRO CA CB SING N N 5
PRO CA HA SING N N 6
PRO C O DOUB N N 7
PRO C OXT SING N N 8
PRO CB CG SING N N 9
PRO CB HB2 SING N N 10
PRO CB HB3 SING N N 11
PRO CG CD SING N N 12
PRO CG HG2 SING N N 13
PRO CG HG3 SING N N 14
PRO CD HD2 SING N N 15
PRO CD HD3 SING N N 16
PRO OXT HXT SING N N 17
)"_cf;
const std::filesystem::path example(gTestDir / ".."/"examples"/"1cbs.cif.gz");
mmcif::File file(example.string());
mmcif::Structure structure(file);
(void)file.file().isValid();
mmcif::BondMap bm(structure);
// Test the bonds of the first three residues, that's PRO A 1, ASN A 2, PHE A 3
for (const auto& [compound, seqnr]: std::initializer_list<std::tuple<std::string,int>>{ { "PRO", 1 }, { "ASN", 2 }, { "PHE", 3 } })
{
auto& res = structure.getResidue("A", compound, seqnr);
auto atoms = res.atoms();
auto dc = components.get(compound);
BOOST_ASSERT(dc != nullptr);
auto cc = dc->get("chem_comp_bond");
BOOST_ASSERT(cc != nullptr);
std::set<std::tuple<std::string,std::string>> bonded;
for (const auto& [atom_id_1, atom_id_2]: cc->rows<std::string,std::string>("atom_id_1", "atom_id_2"))
{
if (atom_id_1 > atom_id_2)
bonded.insert({ atom_id_2, atom_id_1 });
else
bonded.insert({ atom_id_1, atom_id_2 });
}
for (size_t i = 0; i + 1 < atoms.size(); ++i)
{
auto label_i = atoms[i].labelAtomID();
for (size_t j = i + 1; j < atoms.size(); ++j)
{
auto label_j = atoms[j].labelAtomID();
bool bonded_1 = bm(atoms[i], atoms[j]);
bool bonded_1_i = bm(atoms[j], atoms[i]);
bool bonded_t = label_i > label_j
? bonded.count({ label_j, label_i })
: bonded.count({ label_i, label_j });
BOOST_CHECK(bonded_1 == bonded_t);
BOOST_CHECK(bonded_1_i == bonded_t);
}
}
}
}
BOOST_AUTO_TEST_CASE(bondmap_2)
{
BOOST_CHECK_THROW(mmcif::BondMap::atomIDsForCompound("UN_"), mmcif::BondMapException);
mmcif::CompoundFactory::instance().pushDictionary(gTestDir / "UN_.cif");
BOOST_CHECK(mmcif::BondMap::atomIDsForCompound("UN_").empty() == false);
}
BOOST_AUTO_TEST_CASE(reading_file_1)
{
std::istringstream is("Hello, world!");
cif::File file;
BOOST_CHECK_THROW(file.load(is), std::runtime_error);
}

View File

@@ -26,15 +26,20 @@
#include <cassert>
#include <array>
#include <iostream>
#include <iomanip>
#include <fstream>
#include <regex>
#include <map>
#include <filesystem>
#include <boost/program_options.hpp>
#include <cstdlib>
using namespace std;
namespace fs = std::filesystem;
namespace po = boost::program_options;
std::regex kNameRx(R"(^(\d+) +(\d+) +(\d+) +(\S+) +(\S+) +(\S+) +'([^']+)'( +'([^']+)')?(?: +!.+)?$)");
@@ -43,7 +48,7 @@ class SymopParser
public:
SymopParser() {}
array<int,15> parse(const string& s)
std::array<int,15> parse(const std::string& s)
{
m_p = s.begin();
m_e = s.end();
@@ -56,7 +61,7 @@ class SymopParser
parsepart(2);
if (m_lookahead != 0 or m_p != m_e)
throw runtime_error("symmetry expression contains more data than expected");
throw std::runtime_error("symmetry expression contains more data than expected");
return {
m_rot[0][0], m_rot[0][1], m_rot[0][2],
@@ -72,7 +77,7 @@ class SymopParser
enum Token : int { Eof = 0, Number = 256, XYZ };
string to_string(Token t)
std::string to_string(Token t)
{
switch (t)
{
@@ -81,7 +86,7 @@ class SymopParser
case XYZ: return "'x', 'y' or 'z'";
default:
if (isprint(t))
return string({'\'', static_cast<char>(t), '\''});
return std::string({'\'', static_cast<char>(t), '\''});
return "invalid character " + std::to_string(static_cast<int>(t));
}
}
@@ -134,7 +139,7 @@ class SymopParser
void match(Token token)
{
if (m_lookahead != token)
throw runtime_error("Unexpected character " + to_string(m_lookahead) + " expected " + to_string(token));
throw std::runtime_error("Unexpected character " + to_string(m_lookahead) + " expected " + to_string(token));
m_lookahead = next_token();
}
@@ -169,56 +174,90 @@ class SymopParser
Token m_lookahead;
int m_nr;
string m_s;
string::const_iterator m_p, m_e;
std::string m_s;
std::string::const_iterator m_p, m_e;
int m_rot[3][3] = {};
int m_trn[3][2] = {};
};
int main()
int main(int argc, char* const argv[])
{
using namespace std::literals;
fs::path tmpFile;
try
{
const char* CLIBD = getenv("CLIBD");
po::options_description visible_options("symop-map-generator symlib-file output-file");
visible_options.add_options()
( "help,h", "Display help message" )
( "verbose,v", "Verbose output") ;
po::options_description hidden_options("hidden options");
hidden_options.add_options()
( "input,i", po::value<std::string>(), "Input file")
( "output,o", po::value<std::string>(), "Output file");
po::options_description cmdline_options;
cmdline_options.add(visible_options).add(hidden_options);
po::positional_options_description p;
p.add("input", 1);
p.add("output", 1);
po::variables_map vm;
po::store(po::command_line_parser(argc, argv).options(cmdline_options).positional(p).run(), vm);
po::notify(vm);
if (CLIBD == nullptr)
throw runtime_error("CCP4 not sourced");
if (vm.count("input") == 0 or vm.count("output") == 0 or vm.count("help"))
{
std::cerr << visible_options << std::endl;
exit(vm.count("help") == 0);
}
fs::path input(vm["input"].as<std::string>());
fs::path output(vm["output"].as<std::string>());
tmpFile = output.parent_path() / (output.filename().string() + ".tmp");
std::ofstream out(tmpFile);
if (not out.is_open())
throw std::runtime_error("Failed to open output file");
// --------------------------------------------------------------------
// store symop data here
vector<tuple<int,int,array<int,15>>> data;
std::vector<std::tuple<int,int,std::array<int,15>>> data;
// -----------------------------------------------------------------------
struct SymInfoBlock
{
int nr;
string xHM;
string Hall;
string old[2];
std::string xHM;
std::string Hall;
std::string old[2];
};
map<int,SymInfoBlock> symInfo;
std::map<int,SymInfoBlock> symInfo;
int symopnr, mysymnr = 10000;
ifstream file(CLIBD + "/syminfo.lib"s);
std::ifstream file(input);
if (not file.is_open())
throw runtime_error("Could not open syminfo.lib file");
throw std::runtime_error("Could not open syminfo.lib file");
enum class State { skip, spacegroup } state = State::skip;
string line;
string Hall;
vector<string> old;
std::string line;
const regex rx(R"(^symbol +(Hall|xHM|old) +'(.+?)'(?: +'(.+?)')?$)"),
const std::regex rx(R"(^symbol +(Hall|xHM|old) +'(.+?)'(?: +'(.+?)')?$)"),
rx2(R"(symbol ccp4 (\d+))");;
SymInfoBlock cur = {};
std::vector<array<int,15>> symops, cenops;
std::vector<std::array<int,15>> symops, cenops;
while (getline(file, line))
{
@@ -236,8 +275,8 @@ int main()
case State::spacegroup:
{
smatch m;
if (regex_match(line, m, rx))
std::smatch m;
if (std::regex_match(line, m, rx))
{
if (m[1] == "old")
{
@@ -291,86 +330,26 @@ int main()
}
}
// // --------------------------------------------------------------------
// string line;
// string spacegroupName;
// int spacegroupNr, symopnr;
// enum class State { Initial, InSpacegroup, Error } state = State::Initial;
// while (getline(file, line))
// {
// if (line.empty())
// throw runtime_error("Invalid symop.lib file, contains empty line");
// switch (state)
// {
// case State::Error:
// case State::InSpacegroup:
// if (line[0] == ' ')
// {
// if (state == State::Error)
// continue;
// try
// {
// SymopParser p;
// data.emplace_back(spacegroupNr, symopnr, spacegroupName, p.parse(line));
// ++symopnr;
// }
// catch (const exception& e)
// {
// cerr << line << endl
// << e.what() << endl;
// }
// continue;
// }
// // fall through
// case State::Initial:
// {
// smatch m;
// if (not regex_match(line, m, kNameRx))
// {
// cerr << line << endl;
// throw runtime_error("Name line does not match regular expression");
// }
// spacegroupNr = stoi(m[1]);
// spacegroupName = m[7];
// symopnr = 1;
// if (not symInfo.count(spacegroupNr))
// throw runtime_error("Symmetry nr not found in syminfo.lib");
// if (symInfo[spacegroupNr].xHM != spacegroupName)
// cerr << "Inconsistent data between symop.lib and syminfo.lib for spacegroup nr " << to_string(spacegroupNr) << endl;
// state = State::InSpacegroup;
// break;
// }
// }
// }
// --------------------------------------------------------------------
sort(data.begin(), data.end());
// --------------------------------------------------------------------
cout << R"(// This file was generated from $CLIBD/symop.lib
out << R"(// This file was generated from $CLIBD/symop.lib
// and $CLIBD/syminfo.lib using symop-map-generator,
// part of the PDB-REDO suite of programs.
#include "cif++/Symmetry.hpp"
namespace mmcif
{
const Spacegroup kSpaceGroups[] =
{
)";
vector<tuple<string,int,string,string>> spacegroups;
std::vector<std::tuple<std::string,int,std::string,std::string>> spacegroups;
for (auto& [nr, info]: symInfo)
{
@@ -383,56 +362,60 @@ const Spacegroup kSpaceGroups[] =
for (auto [old, nr, xHM, Hall]: spacegroups)
{
old = '"' + old + '"' + string(20 - old.length(), ' ');
xHM = '"' + xHM + '"' + string(30 - xHM.length(), ' ');
old = '"' + old + '"' + std::string(20 - old.length(), ' ');
xHM = '"' + xHM + '"' + std::string(30 - xHM.length(), ' ');
for (string::size_type p = Hall.length(); p > 0; --p)
for (std::string::size_type p = Hall.length(); p > 0; --p)
{
if (Hall[p - 1] == '"')
Hall.insert(p - 1, "\\", 1);
}
Hall = '"' + Hall + '"' + string(40 - Hall.length(), ' ');
Hall = '"' + Hall + '"' + std::string(40 - Hall.length(), ' ');
cout << "\t{ " << old << ", " << xHM << ", " << Hall << ", " << nr << " }," << endl;
out << "\t{ " << old << ", " << xHM << ", " << Hall << ", " << nr << " }," << std::endl;
}
cout << R"(
out << R"(
};
const size_t kNrOfSpaceGroups = sizeof(kSpaceGroups) / sizeof(Spacegroup);
const SymopDataBlock kSymopNrTable[] = {
)" << endl;
)" << std::endl;
int spacegroupNr = 0;
for (auto& sd: data)
{
int sp, o;
tie(sp, o, ignore) = sd;
std::tie(sp, o, std::ignore) = sd;
if (sp > spacegroupNr)
cout << " // " << symInfo[sp].xHM << endl;
out << " // " << symInfo[sp].xHM << std::endl;
spacegroupNr = sp;
cout << " { " << setw(3) << sp
<< ", " << setw(3) << o << ", { ";
for (auto i: get<2>(sd))
cout << setw(2) << i << ',';
cout << " } }," << endl;
out << " { " << std::setw(3) << sp
<< ", " << std::setw(3) << o << ", { ";
for (auto& i: std::get<2>(sd))
out << std::setw(2) << i << ',';
out << " } }," << std::endl;
}
cout << R"(};
out << R"(};
const size_t kSymopNrTableSize = sizeof(kSymopNrTable) / sizeof(SymopDataBlock);
)" << endl;
} // namespace mmcif
)" << std::endl;
out.close();
fs::rename(tmpFile, output);
}
catch (const exception& ex)
catch (const std::exception& ex)
{
cerr << endl
<< "Program terminated due to error:" << endl
<< ex.what() << endl;
std::cerr << std::endl
<< "Program terminated due to error:" << std::endl
<< ex.what() << std::endl;
}
return 0;

View File

@@ -1,33 +0,0 @@
#!/bin/sh
set -e
if [ "$EUID" -ne 0 ]
then echo "Please run as root"
exit
fi
# create cache directory if it doesn't exist
if ! [ -d /var/cache/libcifpp ]; then
install -d -m755 /var/cache/libcifpp
fi
# fetch the dictionary
dict=/var/cache/libcifpp/mmcif_pdbx_v50.cif
source=http://mmcif.wwpdb.org/dictionaries/ascii/mmcif_pdbx_v50.dic.gz
wget -O${dict}.gz ${source}
# be careful not to nuke an existing dictionary file
# extract to a temporary file first
gunzip -c ${dict}.gz > ${dict}-tmp
# then move the extracted file to the final location
mv ${dict}-tmp ${dict}
# and clean up afterwards
rm ${dict}.gz

View File

@@ -0,0 +1,53 @@
#!/bin/bash
set -e
if [ "$EUID" -ne 0 ]
then echo "Please run as root"
exit
fi
if [ -f /etc/libcifpp.conf ] ; then
. /etc/libcifpp.conf
fi
# check to see if we're supposed to run at all
if [ "$update" != "true" ] ; then
exit
fi
# if cache directory doesn't exist, exit.
if ! [ -d @CIFPP_CACHE_DIR@ ]; then
exit
fi
fetch_dictionary () {
dict=$1
source=$2
wget -O${dict}.gz ${source}
# be careful not to nuke an existing dictionary file
# extract to a temporary file first
gunzip -c ${dict}.gz > ${dict}-tmp
# then move the extracted file to the final location
mv ${dict}-tmp ${dict}
# and clean up afterwards
rm ${dict}.gz
}
# fetch the dictionaries
fetch_dictionary "@CIFPP_CACHE_DIR@/mmcif_pdbx_v50.dic" "https://mmcif.wwpdb.org/dictionaries/ascii/mmcif_pdbx_v50.dic.gz"
fetch_dictionary "@CIFPP_CACHE_DIR@/components.cif" "ftp://ftp.wwpdb.org/pub/pdb/data/monomers/components.cif.gz"
# notify subscribers
if [ -d /etc/libcifpp/cache-update.d ] && [ -x /bin/run-parts ]; then
run-parts --arg "@CIFPP_CACHE_DIR@" -- /etc/libcifpp/cache-update.d
fi