travis-src-190101/0040777000000000000000000000000013412726057010651 5ustar00travis-src-190101/COPYING0100777000000000000000000010451411643644067011715 0ustar00 GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007 Copyright (C) 2007 Free Software Foundation, Inc. Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The GNU General Public License is a free, copyleft license for software and other kinds of works. The licenses for most software and other practical works are designed to take away your freedom to share and change the works. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change all versions of a program--to make sure it remains free software for all its users. We, the Free Software Foundation, use the GNU General Public License for most of our software; it applies also to any other work released this way by its authors. You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for them if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs, and that you know you can do these things. To protect your rights, we need to prevent others from denying you these rights or asking you to surrender the rights. Therefore, you have certain responsibilities if you distribute copies of the software, or if you modify it: responsibilities to respect the freedom of others. For example, if you distribute copies of such a program, whether gratis or for a fee, you must pass on to the recipients the same freedoms that you received. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. Developers that use the GNU GPL protect your rights with two steps: (1) assert copyright on the software, and (2) offer you this License giving you legal permission to copy, distribute and/or modify it. For the developers' and authors' protection, the GPL clearly explains that there is no warranty for this free software. For both users' and authors' sake, the GPL requires that modified versions be marked as changed, so that their problems will not be attributed erroneously to authors of previous versions. Some devices are designed to deny users access to install or run modified versions of the software inside them, although the manufacturer can do so. This is fundamentally incompatible with the aim of protecting users' freedom to change the software. The systematic pattern of such abuse occurs in the area of products for individuals to use, which is precisely where it is most unacceptable. Therefore, we have designed this version of the GPL to prohibit the practice for those products. If such problems arise substantially in other domains, we stand ready to extend this provision to those domains in future versions of the GPL, as needed to protect the freedom of users. Finally, every program is threatened constantly by software patents. States should not allow patents to restrict development and use of software on general-purpose computers, but in those that do, we wish to avoid the special danger that patents applied to a free program could make it effectively proprietary. To prevent this, the GPL assures that patents cannot be used to render the program non-free. The precise terms and conditions for copying, distribution and modification follow. TERMS AND CONDITIONS 0. Definitions. "This License" refers to version 3 of the GNU General Public License. "Copyright" also means copyright-like laws that apply to other kinds of works, such as semiconductor masks. "The Program" refers to any copyrightable work licensed under this License. Each licensee is addressed as "you". "Licensees" and "recipients" may be individuals or organizations. To "modify" a work means to copy from or adapt all or part of the work in a fashion requiring copyright permission, other than the making of an exact copy. The resulting work is called a "modified version" of the earlier work or a work "based on" the earlier work. A "covered work" means either the unmodified Program or a work based on the Program. To "propagate" a work means to do anything with it that, without permission, would make you directly or secondarily liable for infringement under applicable copyright law, except executing it on a computer or modifying a private copy. Propagation includes copying, distribution (with or without modification), making available to the public, and in some countries other activities as well. To "convey" a work means any kind of propagation that enables other parties to make or receive copies. Mere interaction with a user through a computer network, with no transfer of a copy, is not conveying. An interactive user interface displays "Appropriate Legal Notices" to the extent that it includes a convenient and prominently visible feature that (1) displays an appropriate copyright notice, and (2) tells the user that there is no warranty for the work (except to the extent that warranties are provided), that licensees may convey the work under this License, and how to view a copy of this License. If the interface presents a list of user commands or options, such as a menu, a prominent item in the list meets this criterion. 1. Source Code. The "source code" for a work means the preferred form of the work for making modifications to it. "Object code" means any non-source form of a work. A "Standard Interface" means an interface that either is an official standard defined by a recognized standards body, or, in the case of interfaces specified for a particular programming language, one that is widely used among developers working in that language. The "System Libraries" of an executable work include anything, other than the work as a whole, that (a) is included in the normal form of packaging a Major Component, but which is not part of that Major Component, and (b) serves only to enable use of the work with that Major Component, or to implement a Standard Interface for which an implementation is available to the public in source code form. A "Major Component", in this context, means a major essential component (kernel, window system, and so on) of the specific operating system (if any) on which the executable work runs, or a compiler used to produce the work, or an object code interpreter used to run it. The "Corresponding Source" for a work in object code form means all the source code needed to generate, install, and (for an executable work) run the object code and to modify the work, including scripts to control those activities. However, it does not include the work's System Libraries, or general-purpose tools or generally available free programs which are used unmodified in performing those activities but which are not part of the work. For example, Corresponding Source includes interface definition files associated with source files for the work, and the source code for shared libraries and dynamically linked subprograms that the work is specifically designed to require, such as by intimate data communication or control flow between those subprograms and other parts of the work. The Corresponding Source need not include anything that users can regenerate automatically from other parts of the Corresponding Source. The Corresponding Source for a work in source code form is that same work. 2. Basic Permissions. All rights granted under this License are granted for the term of copyright on the Program, and are irrevocable provided the stated conditions are met. This License explicitly affirms your unlimited permission to run the unmodified Program. The output from running a covered work is covered by this License only if the output, given its content, constitutes a covered work. This License acknowledges your rights of fair use or other equivalent, as provided by copyright law. You may make, run and propagate covered works that you do not convey, without conditions so long as your license otherwise remains in force. You may convey covered works to others for the sole purpose of having them make modifications exclusively for you, or provide you with facilities for running those works, provided that you comply with the terms of this License in conveying all material for which you do not control copyright. Those thus making or running the covered works for you must do so exclusively on your behalf, under your direction and control, on terms that prohibit them from making any copies of your copyrighted material outside their relationship with you. Conveying under any other circumstances is permitted solely under the conditions stated below. Sublicensing is not allowed; section 10 makes it unnecessary. 3. Protecting Users' Legal Rights From Anti-Circumvention Law. No covered work shall be deemed part of an effective technological measure under any applicable law fulfilling obligations under article 11 of the WIPO copyright treaty adopted on 20 December 1996, or similar laws prohibiting or restricting circumvention of such measures. When you convey a covered work, you waive any legal power to forbid circumvention of technological measures to the extent such circumvention is effected by exercising rights under this License with respect to the covered work, and you disclaim any intention to limit operation or modification of the work as a means of enforcing, against the work's users, your or third parties' legal rights to forbid circumvention of technological measures. 4. Conveying Verbatim Copies. You may convey verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice; keep intact all notices stating that this License and any non-permissive terms added in accord with section 7 apply to the code; keep intact all notices of the absence of any warranty; and give all recipients a copy of this License along with the Program. You may charge any price or no price for each copy that you convey, and you may offer support or warranty protection for a fee. 5. Conveying Modified Source Versions. You may convey a work based on the Program, or the modifications to produce it from the Program, in the form of source code under the terms of section 4, provided that you also meet all of these conditions: a) The work must carry prominent notices stating that you modified it, and giving a relevant date. b) The work must carry prominent notices stating that it is released under this License and any conditions added under section 7. This requirement modifies the requirement in section 4 to "keep intact all notices". c) You must license the entire work, as a whole, under this License to anyone who comes into possession of a copy. This License will therefore apply, along with any applicable section 7 additional terms, to the whole of the work, and all its parts, regardless of how they are packaged. This License gives no permission to license the work in any other way, but it does not invalidate such permission if you have separately received it. d) If the work has interactive user interfaces, each must display Appropriate Legal Notices; however, if the Program has interactive interfaces that do not display Appropriate Legal Notices, your work need not make them do so. A compilation of a covered work with other separate and independent works, which are not by their nature extensions of the covered work, and which are not combined with it such as to form a larger program, in or on a volume of a storage or distribution medium, is called an "aggregate" if the compilation and its resulting copyright are not used to limit the access or legal rights of the compilation's users beyond what the individual works permit. Inclusion of a covered work in an aggregate does not cause this License to apply to the other parts of the aggregate. 6. Conveying Non-Source Forms. You may convey a covered work in object code form under the terms of sections 4 and 5, provided that you also convey the machine-readable Corresponding Source under the terms of this License, in one of these ways: a) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by the Corresponding Source fixed on a durable physical medium customarily used for software interchange. b) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by a written offer, valid for at least three years and valid for as long as you offer spare parts or customer support for that product model, to give anyone who possesses the object code either (1) a copy of the Corresponding Source for all the software in the product that is covered by this License, on a durable physical medium customarily used for software interchange, for a price no more than your reasonable cost of physically performing this conveying of source, or (2) access to copy the Corresponding Source from a network server at no charge. c) Convey individual copies of the object code with a copy of the written offer to provide the Corresponding Source. This alternative is allowed only occasionally and noncommercially, and only if you received the object code with such an offer, in accord with subsection 6b. d) Convey the object code by offering access from a designated place (gratis or for a charge), and offer equivalent access to the Corresponding Source in the same way through the same place at no further charge. You need not require recipients to copy the Corresponding Source along with the object code. If the place to copy the object code is a network server, the Corresponding Source may be on a different server (operated by you or a third party) that supports equivalent copying facilities, provided you maintain clear directions next to the object code saying where to find the Corresponding Source. Regardless of what server hosts the Corresponding Source, you remain obligated to ensure that it is available for as long as needed to satisfy these requirements. e) Convey the object code using peer-to-peer transmission, provided you inform other peers where the object code and Corresponding Source of the work are being offered to the general public at no charge under subsection 6d. A separable portion of the object code, whose source code is excluded from the Corresponding Source as a System Library, need not be included in conveying the object code work. A "User Product" is either (1) a "consumer product", which means any tangible personal property which is normally used for personal, family, or household purposes, or (2) anything designed or sold for incorporation into a dwelling. In determining whether a product is a consumer product, doubtful cases shall be resolved in favor of coverage. For a particular product received by a particular user, "normally used" refers to a typical or common use of that class of product, regardless of the status of the particular user or of the way in which the particular user actually uses, or expects or is expected to use, the product. A product is a consumer product regardless of whether the product has substantial commercial, industrial or non-consumer uses, unless such uses represent the only significant mode of use of the product. "Installation Information" for a User Product means any methods, procedures, authorization keys, or other information required to install and execute modified versions of a covered work in that User Product from a modified version of its Corresponding Source. The information must suffice to ensure that the continued functioning of the modified object code is in no case prevented or interfered with solely because modification has been made. If you convey an object code work under this section in, or with, or specifically for use in, a User Product, and the conveying occurs as part of a transaction in which the right of possession and use of the User Product is transferred to the recipient in perpetuity or for a fixed term (regardless of how the transaction is characterized), the Corresponding Source conveyed under this section must be accompanied by the Installation Information. But this requirement does not apply if neither you nor any third party retains the ability to install modified object code on the User Product (for example, the work has been installed in ROM). The requirement to provide Installation Information does not include a requirement to continue to provide support service, warranty, or updates for a work that has been modified or installed by the recipient, or for the User Product in which it has been modified or installed. Access to a network may be denied when the modification itself materially and adversely affects the operation of the network or violates the rules and protocols for communication across the network. Corresponding Source conveyed, and Installation Information provided, in accord with this section must be in a format that is publicly documented (and with an implementation available to the public in source code form), and must require no special password or key for unpacking, reading or copying. 7. Additional Terms. "Additional permissions" are terms that supplement the terms of this License by making exceptions from one or more of its conditions. Additional permissions that are applicable to the entire Program shall be treated as though they were included in this License, to the extent that they are valid under applicable law. If additional permissions apply only to part of the Program, that part may be used separately under those permissions, but the entire Program remains governed by this License without regard to the additional permissions. When you convey a copy of a covered work, you may at your option remove any additional permissions from that copy, or from any part of it. (Additional permissions may be written to require their own removal in certain cases when you modify the work.) You may place additional permissions on material, added by you to a covered work, for which you have or can give appropriate copyright permission. Notwithstanding any other provision of this License, for material you add to a covered work, you may (if authorized by the copyright holders of that material) supplement the terms of this License with terms: a) Disclaiming warranty or limiting liability differently from the terms of sections 15 and 16 of this License; or b) Requiring preservation of specified reasonable legal notices or author attributions in that material or in the Appropriate Legal Notices displayed by works containing it; or c) Prohibiting misrepresentation of the origin of that material, or requiring that modified versions of such material be marked in reasonable ways as different from the original version; or d) Limiting the use for publicity purposes of names of licensors or authors of the material; or e) Declining to grant rights under trademark law for use of some trade names, trademarks, or service marks; or f) Requiring indemnification of licensors and authors of that material by anyone who conveys the material (or modified versions of it) with contractual assumptions of liability to the recipient, for any liability that these contractual assumptions directly impose on those licensors and authors. All other non-permissive additional terms are considered "further restrictions" within the meaning of section 10. If the Program as you received it, or any part of it, contains a notice stating that it is governed by this License along with a term that is a further restriction, you may remove that term. If a license document contains a further restriction but permits relicensing or conveying under this License, you may add to a covered work material governed by the terms of that license document, provided that the further restriction does not survive such relicensing or conveying. If you add terms to a covered work in accord with this section, you must place, in the relevant source files, a statement of the additional terms that apply to those files, or a notice indicating where to find the applicable terms. Additional terms, permissive or non-permissive, may be stated in the form of a separately written license, or stated as exceptions; the above requirements apply either way. 8. Termination. You may not propagate or modify a covered work except as expressly provided under this License. Any attempt otherwise to propagate or modify it is void, and will automatically terminate your rights under this License (including any patent licenses granted under the third paragraph of section 11). However, if you cease all violation of this License, then your license from a particular copyright holder is reinstated (a) provisionally, unless and until the copyright holder explicitly and finally terminates your license, and (b) permanently, if the copyright holder fails to notify you of the violation by some reasonable means prior to 60 days after the cessation. Moreover, your license from a particular copyright holder is reinstated permanently if the copyright holder notifies you of the violation by some reasonable means, this is the first time you have received notice of violation of this License (for any work) from that copyright holder, and you cure the violation prior to 30 days after your receipt of the notice. Termination of your rights under this section does not terminate the licenses of parties who have received copies or rights from you under this License. If your rights have been terminated and not permanently reinstated, you do not qualify to receive new licenses for the same material under section 10. 9. Acceptance Not Required for Having Copies. You are not required to accept this License in order to receive or run a copy of the Program. Ancillary propagation of a covered work occurring solely as a consequence of using peer-to-peer transmission to receive a copy likewise does not require acceptance. However, nothing other than this License grants you permission to propagate or modify any covered work. These actions infringe copyright if you do not accept this License. Therefore, by modifying or propagating a covered work, you indicate your acceptance of this License to do so. 10. Automatic Licensing of Downstream Recipients. Each time you convey a covered work, the recipient automatically receives a license from the original licensors, to run, modify and propagate that work, subject to this License. You are not responsible for enforcing compliance by third parties with this License. An "entity transaction" is a transaction transferring control of an organization, or substantially all assets of one, or subdividing an organization, or merging organizations. If propagation of a covered work results from an entity transaction, each party to that transaction who receives a copy of the work also receives whatever licenses to the work the party's predecessor in interest had or could give under the previous paragraph, plus a right to possession of the Corresponding Source of the work from the predecessor in interest, if the predecessor has it or can get it with reasonable efforts. You may not impose any further restrictions on the exercise of the rights granted or affirmed under this License. For example, you may not impose a license fee, royalty, or other charge for exercise of rights granted under this License, and you may not initiate litigation (including a cross-claim or counterclaim in a lawsuit) alleging that any patent claim is infringed by making, using, selling, offering for sale, or importing the Program or any portion of it. 11. Patents. A "contributor" is a copyright holder who authorizes use under this License of the Program or a work on which the Program is based. The work thus licensed is called the contributor's "contributor version". A contributor's "essential patent claims" are all patent claims owned or controlled by the contributor, whether already acquired or hereafter acquired, that would be infringed by some manner, permitted by this License, of making, using, or selling its contributor version, but do not include claims that would be infringed only as a consequence of further modification of the contributor version. For purposes of this definition, "control" includes the right to grant patent sublicenses in a manner consistent with the requirements of this License. Each contributor grants you a non-exclusive, worldwide, royalty-free patent license under the contributor's essential patent claims, to make, use, sell, offer for sale, import and otherwise run, modify and propagate the contents of its contributor version. In the following three paragraphs, a "patent license" is any express agreement or commitment, however denominated, not to enforce a patent (such as an express permission to practice a patent or covenant not to sue for patent infringement). To "grant" such a patent license to a party means to make such an agreement or commitment not to enforce a patent against the party. If you convey a covered work, knowingly relying on a patent license, and the Corresponding Source of the work is not available for anyone to copy, free of charge and under the terms of this License, through a publicly available network server or other readily accessible means, then you must either (1) cause the Corresponding Source to be so available, or (2) arrange to deprive yourself of the benefit of the patent license for this particular work, or (3) arrange, in a manner consistent with the requirements of this License, to extend the patent license to downstream recipients. "Knowingly relying" means you have actual knowledge that, but for the patent license, your conveying the covered work in a country, or your recipient's use of the covered work in a country, would infringe one or more identifiable patents in that country that you have reason to believe are valid. If, pursuant to or in connection with a single transaction or arrangement, you convey, or propagate by procuring conveyance of, a covered work, and grant a patent license to some of the parties receiving the covered work authorizing them to use, propagate, modify or convey a specific copy of the covered work, then the patent license you grant is automatically extended to all recipients of the covered work and works based on it. A patent license is "discriminatory" if it does not include within the scope of its coverage, prohibits the exercise of, or is conditioned on the non-exercise of one or more of the rights that are specifically granted under this License. You may not convey a covered work if you are a party to an arrangement with a third party that is in the business of distributing software, under which you make payment to the third party based on the extent of your activity of conveying the work, and under which the third party grants, to any of the parties who would receive the covered work from you, a discriminatory patent license (a) in connection with copies of the covered work conveyed by you (or copies made from those copies), or (b) primarily for and in connection with specific products or compilations that contain the covered work, unless you entered into that arrangement, or that patent license was granted, prior to 28 March 2007. Nothing in this License shall be construed as excluding or limiting any implied license or other defenses to infringement that may otherwise be available to you under applicable patent law. 12. No Surrender of Others' Freedom. If conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot convey a covered work so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not convey it at all. For example, if you agree to terms that obligate you to collect a royalty for further conveying from those to whom you convey the Program, the only way you could satisfy both those terms and this License would be to refrain entirely from conveying the Program. 13. Use with the GNU Affero General Public License. Notwithstanding any other provision of this License, you have permission to link or combine any covered work with a work licensed under version 3 of the GNU Affero General Public License into a single combined work, and to convey the resulting work. The terms of this License will continue to apply to the part which is the covered work, but the special requirements of the GNU Affero General Public License, section 13, concerning interaction through a network will apply to the combination as such. 14. Revised Versions of this License. The Free Software Foundation may publish revised and/or new versions of the GNU General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies that a certain numbered version of the GNU General Public License "or any later version" applies to it, you have the option of following the terms and conditions either of that numbered version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of the GNU General Public License, you may choose any version ever published by the Free Software Foundation. If the Program specifies that a proxy can decide which future versions of the GNU General Public License can be used, that proxy's public statement of acceptance of a version permanently authorizes you to choose that version for the Program. Later license versions may give you additional or different permissions. However, no additional obligations are imposed on any author or copyright holder as a result of your choosing to follow a later version. 15. Disclaimer of Warranty. THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 16. Limitation of Liability. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 17. Interpretation of Sections 15 and 16. If the disclaimer of warranty and limitation of liability provided above cannot be given local legal effect according to their terms, reviewing courts shall apply local law that most closely approximates an absolute waiver of all civil liability in connection with the Program, unless a warranty or assumption of liability accompanies a copy of the Program in return for a fee. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively state the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . Also add information on how to contact you by electronic and paper mail. If the program does terminal interaction, make it output a short notice like this when it starts in an interactive mode: Copyright (C) This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, your program's commands might be different; for a GUI interface, you would use an "about box". You should also get your employer (if you work as a programmer) or school, if any, to sign a "copyright disclaimer" for the program, if necessary. For more information on this, and how to apply and follow the GNU GPL, see . The GNU General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. But first, please read . travis-src-190101/Makefile0100777000000000000000000000434113412726130012303 0ustar00#***************************************************************************** # TRAVIS - Trajectory Analyzer and Visualizer # http://www.travis-analyzer.de/ # # Copyright (c) 2009-2019 Martin Brehm # 2012-2019 Martin Thomas # 2016-2019 Sascha Gehrke # # This file written by Martin Brehm. # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . #***************************************************************************** # TRAVIS Makefile # Edit the follwing lines according to your needs # Your C++ compiler CXX = g++ #************************************************************************** # You should not need to edit the following part #************************************************************************** CFLAGS = -g -Wall -Wextra -Wformat -Wformat-security -pedantic -ansi -O2 $(FFTW_INCLUDE) CFLAGS_PROF = -g -Wall -Wextra -Wformat -Wformat-security -pedantic -ansi -O2 -pg $(FFTW_INCLUDE) CFLAGS_DEB = -g -Wall -Wextra -Wformat -Wformat-security -pedantic -ansi -O0 $(FFTW_INCLUDE) CFLAGS_REL = -g -Wall -Wextra -Wformat -Wformat-security -pedantic -ansi -O3 $(FFTW_INCLUDE) -march=athlon-fx LDFLAGS = $(FFTW_LIB) SRC = $(wildcard src/*.cpp) OBJ = $(SRC:%.cpp=%.o) BIN = exe/travis all: executable debug: CFLAGS = $(CFLAGS_DEB) debug: executable release: CFLAGS = $(CFLAGS_REL) release: executable profile: CFLAGS = $(CFLAGS_PROF) profile: executable executable: $(OBJ) mkdir -p exe $(CXX) $(CFLAGS) -o $(BIN) $(OBJ) $(LDFLAGS) %.o: %.cpp $(CXX) $(CFLAGS) -c $< -o $@ .PHONY: clean clean: rm -f $(OBJ) .PHONY: distclean distclean: rm -f $(OBJ) rm -rf exe travis-src-190101/README0100777000000000000000000000244513412726076011537 0ustar00 *************************************************** *** TRAVIS - Trajectory Analyzer and Visualizer *** *************************************************** http://www.travis-analyzer.de/ Copyright (c) 2009-2019 Martin Brehm 2012-2019 Martin Thomas 2016-2019 Sascha Gehrke Please read our article: M. Brehm and B. Kirchner, J. Chem. Inf. Model. 2011, 51 (8), pp 2007-2023 TRAVIS ("TRajectory Analyzer and VISualizer") is a program package for analyzing and visualizing Monte Carlo and molecular dynamics trajectories. TRAVIS is open-source freeware and licensed under the terms of the GNU General Public License v3 (see file COPYING). * Installation * To compile TRAVIS, open the Makefile and set the CXX variable to the C++ compiler of your choice. Then just enter "make". If everything worked, an executable ("travis") should appear in the "exe" directory. TRAVIS does not require any external libraries. When compiling TRAVIS on systems that are not running Linux, you may have to edit the "config.h" file in the "src" directory. Comment out the "TARGET_LINUX" line. If you are building an Windows version, you may want to uncomment the "TARGET_WINDOWS" line. With both lines commented out, you get a platform-independent build without special features. travis-src-190101/src/0040777000000000000000000000000013412726045011435 5ustar00travis-src-190101/src/2df.cpp0100777000000000000000000100672113412725624012625 0ustar00/***************************************************************************** TRAVIS - Trajectory Analyzer and Visualizer http://www.travis-analyzer.de/ Copyright (c) 2009-2019 Martin Brehm 2012-2019 Martin Thomas 2016-2019 Sascha Gehrke This file was written by Martin Brehm. --------------------------------------------------------------------------- This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . *****************************************************************************/ // This must always be the first include directive #include "config.h" #include "2df.h" #include "travis.h" const char *GetRevisionInfo_2df(unsigned int len) { static char buf[256]; GET_REVISION_INFO( buf, len ); return buf; } const char *GetSourceVersion_2df() { static char buf[256]; GET_SOURCE_VERSION( buf ); return buf; } C2DF::C2DF() { m_sLabelX = NULL; m_sLabelY = NULL; m_sLabelZ = NULL; m_pBin = NULL; m_pStepsY = NULL; m_fCountX = NULL; m_fCountY = NULL; m_iHistogramRes = 0; m_iPlotType = 1; m_iSmoothGrade = 1; m_iInterpolationOrder = 2; if (g_pDatabase != NULL) m_fPlotExp = g_pDatabase->GetFloat("/PLOT2D/DEFAULTS/PLOT_EXP"); else m_fPlotExp = 0.5; m_iExpLegend = 1; m_iColorScale = 1; m_iGPInterpolation = 5; m_bContourLines = true; m_fAspectRatio = 1.0; m_bDrawMesh = true; if (g_pDatabase != NULL) m_iPlotPixel = g_pDatabase->GetInt("/PLOT2D/DEFAULTS/IMAGE_RES"); else m_iPlotPixel = 1000; if (g_pDatabase != NULL) m_iContourLines = g_pDatabase->GetInt("/PLOT2D/DEFAULTS/CONTOUR_LINES"); else m_iContourLines = 30; m_oaCircles.SetName("C2DF::m_oaCircles"); } C2DF::~C2DF() { if (m_sLabelX != NULL) { delete[] m_sLabelX; m_sLabelX = NULL; } if (m_sLabelY != NULL) { delete[] m_sLabelY; m_sLabelY = NULL; } if (m_sLabelZ != NULL) { delete[] m_sLabelZ; m_sLabelZ = NULL; } if (m_pBin != NULL) { delete[] m_pBin; m_pBin = NULL; } if (m_pStepsY != NULL) { delete[] m_pStepsY; m_pStepsY = NULL; } if (m_fCountX != NULL) { delete[] m_fCountX; m_fCountX = NULL; } if (m_fCountY != NULL) { delete[] m_fCountY; m_fCountY = NULL; } } void C2DF::CorrectAngle(int channel) { BTIN; int z, z2; double d; if (channel == 0) { for (z=0;z m_fMaxVal[0]) || (y > m_fMaxVal[1])) { m_fSkipEntries++; BXOUT; return; } m_fBinEntries++; rx = (x-m_fMinVal[0])*m_fFac[0] - 0.5; ix = (int)floor(rx); if (ix < 0) { ix = 0; rx = 0; } else if (ix > m_iRes[0]-2) { ix = m_iRes[0]-2; rx = 1.0; } else rx -= ix; ry = (y-m_fMinVal[1])*m_fFac[1] - 0.5; iy = (int)floor(ry); if (iy < 0) { iy = 0; ry = 0; } else if (iy > m_iRes[1]-2) { iy = m_iRes[1]-2; ry = 1.0; } else ry -= iy; m_pBin[ iy * m_iRes[0] + ix ] += (1.0-rx) * (1.0-ry); m_pBin[ iy * m_iRes[0] + ix + 1] += rx * (1.0-ry); m_pBin[(iy+1) * m_iRes[0] + ix ] += (1.0-rx) * ry; m_pBin[(iy+1) * m_iRes[0] + ix + 1] += rx * ry; m_fCountX[ix ] += (1.0-rx); m_fCountX[ix+1] += rx; m_fCountY[iy ] += (1.0-ry); m_fCountY[iy+1] += ry; BXOUT; } void C2DF::AddToBin(double x, double y, double val) { BXIN; double rx, ry; int ix, iy; if ((x < m_fMinVal[0]) || (y < m_fMinVal[1]) || (x > m_fMaxVal[0]) || (y > m_fMaxVal[1])) { m_fSkipEntries++; BXOUT; return; } m_fBinEntries++; rx = (x-m_fMinVal[0])*m_fFac[0] - 0.5; ix = (int)floor(rx); if (ix < 0) { ix = 0; rx = 0; } else if (ix > m_iRes[0]-2) { ix = m_iRes[0]-2; rx = 1.0; } else rx -= ix; ry = (y-m_fMinVal[1])*m_fFac[1] - 0.5; iy = (int)floor(ry); if (iy < 0) { iy = 0; ry = 0; } else if (iy > m_iRes[1]-2) { iy = m_iRes[1]-2; ry = 1.0; } else ry -= iy; m_pBin[ iy * m_iRes[0] + ix ] += (1.0-rx) * (1.0-ry) * val; m_pBin[ iy * m_iRes[0] + ix + 1] += rx * (1.0-ry) * val; m_pBin[(iy+1) * m_iRes[0] + ix ] += (1.0-rx) * ry * val; m_pBin[(iy+1) * m_iRes[0] + ix + 1] += rx * ry * val; m_fCountX[ix ] += (1.0-rx); m_fCountX[ix+1] += rx; m_fCountY[iy ] += (1.0-ry); m_fCountY[iy+1] += ry; BXOUT; } void C2DF::AddToBin_IntX(int x, double y, double val) { BXIN; double ry; int iy; if ((y < m_fMinVal[1]) || (y > m_fMaxVal[1])) { m_fSkipEntries++; BXOUT; return; } m_fBinEntries++; ry = (y-m_fMinVal[1])*m_fFac[1] - 0.5; iy = (int)floor(ry); if (iy < 0) { iy = 0; ry = 0; } else if (iy > m_iRes[1]-2) { iy = m_iRes[1]-2; ry = 1.0; } else ry -= iy; m_pBin[ iy * m_iRes[0] + x] += (1.0-ry) * val; m_pBin[(iy+1) * m_iRes[0] + x] += ry * val; m_fCountX[x]++; m_fCountY[iy ] += (1.0-ry); m_fCountY[iy+1] += ry; BXOUT; } void C2DF::AddToBin_IntY(double x, int y, double val) { BXIN; double rx; int ix; if ((x < m_fMinVal[0]) || (x > m_fMaxVal[0])) { m_fSkipEntries++; BXOUT; return; } m_fBinEntries++; rx = (x-m_fMinVal[0])*m_fFac[0] - 0.5; ix = (int)floor(rx); if (ix < 0) { ix = 0; rx = 0; } else if (ix > m_iRes[0]-2) { ix = m_iRes[0]-2; rx = 1.0; } else rx -= ix; m_pBin[ ix + y * m_iRes[0]] += (1.0-rx) * val; m_pBin[(ix+1) + y * m_iRes[0]] += rx * val; m_fCountY[y]++; m_fCountX[ix ] += (1.0-rx); m_fCountX[ix+1] += rx; BXOUT; } void C2DF::AddToBin_IntY(double x, int y) { BXIN; double rx; int ix; if ((x < m_fMinVal[0]) || (x > m_fMaxVal[0])) { m_fSkipEntries++; BXOUT; return; } m_fBinEntries++; rx = (x-m_fMinVal[0])*m_fFac[0] - 0.5; ix = (int)floor(rx); if (ix < 0) { ix = 0; rx = 0; } else if (ix > m_iRes[0]-2) { ix = m_iRes[0]-2; rx = 1.0; } else rx -= ix; m_pBin[ ix + y * m_iRes[0]] += (1.0-rx); m_pBin[(ix+1) + y * m_iRes[0]] += rx ; m_fCountY[y]++; m_fCountX[ix ] += (1.0-rx); m_fCountX[ix+1] += rx; BXOUT; } /*void C2DF::AddToSingleBin(double x, double y, double val) { BXIN; double rx, ry; int ix, iy; if ((x < m_fMinVal[0]) || (y < m_fMinVal[1]) || (x > m_fMaxVal[0]) || (y > m_fMaxVal[1])) { m_fSkipEntries++; BXOUT; return; } m_fBinEntries++; rx = ((x-m_fMinVal[0])/(m_fMaxVal[0]-m_fMinVal[0]))*((double)m_iRes[0]-1); ry = ((y-m_fMinVal[1])/(m_fMaxVal[1]-m_fMinVal[1]))*((double)m_iRes[1]-1); ix = (int)(rx+0.5); iy = (int)(ry+0.5); m_pBin[iy*(m_iRes[0]+1) + ix] += val; BXOUT; }*/ //DEL void C2DF::CorrectRadialDist(bool xdim) //DEL { //DEL BTIN; //DEL int x, y; //DEL double f; //DEL //DEL if (xdim) //DEL { //DEL for (x=0;xm_laSingleMolIndex.GetSize(); if (f < m_pBin[z]) f = m_pBin[z]; } BTOUT; return f; } void C2DF::NormalizeBin(double mi, double ma) { BTIN; int z; double tmi, tma, d, td; tmi = 99999999.0; tma = 0.0; for (z=0;z tma) tma = m_pBin[z]; } if (tma-tmi < 1E-20) tma += 0.00001; d = ma - mi; td = tma - tmi; for (z=0;zCurrentGraph()->m_bLegend = true; if (channel == 0) { g->SetLabelX(m_sLabelY); if (m_sLabelZ == NULL) g->SetLabelY("Occurrence"); else g->SetLabelY(m_sLabelZ); CalcMaxEntry(); g->SetRangeX(m_fMinVal[1],m_fMaxVal[1]); g->SetRangeY(0,m_fMaxEntry*1.1*fac); g->MakeTicks(); // sprintf(buf,"Legend unit is %s",m_sLabelX); buf.sprintf("Legend unit is %s",m_sLabelX); g->SetSubTitle(buf); for (x=0;xAddDataset(); // sprintf(buf,"%.2f",m_fMinVal[0]+t*(m_fMaxVal[0]-m_fMinVal[0])/m_iRes[0]); buf.sprintf("%.2f",m_fMinVal[0]+t*(m_fMaxVal[0]-m_fMinVal[0])/m_iRes[0]); g->SetDatasetName(buf); g->CurrentGraph()->CurrentDataset()->m_faValues.SetMaxSize(m_iRes[1]*2); for (y=0;yAddXYTupel(m_fMinVal[1]+(y+0.5)*(m_fMaxVal[1]-m_fMinVal[1])/m_iRes[1],m_pBin[y*m_iRes[0]+t]*fac); } } else { g->SetLabelX(m_sLabelX); if (m_sLabelZ == NULL) g->SetLabelY("Occurrence"); else g->SetLabelY(m_sLabelZ); CalcMaxEntry(); g->SetRangeX(m_fMinVal[0],m_fMaxVal[0]); g->SetRangeY(0,m_fMaxEntry*1.1*fac); g->MakeTicks(); // sprintf(buf,"Legend unit is %s",m_sLabelY); buf.sprintf("Legend unit is %s",m_sLabelY); g->SetSubTitle(buf); for (y=0;yAddDataset(); // sprintf(buf,"%.2f",m_fMinVal[1]+t*(m_fMaxVal[1]-m_fMinVal[1])/m_iRes[1]); buf.sprintf("%.2f",m_fMinVal[1]+t*(m_fMaxVal[1]-m_fMinVal[1])/m_iRes[1]); g->SetDatasetName(buf); g->CurrentGraph()->CurrentDataset()->m_faValues.SetMaxSize(m_iRes[0]*2); for (x=0;xAddXYTupel(m_fMinVal[0]+(x+0.5)*(m_fMaxVal[0]-m_fMinVal[0])/m_iRes[0],m_pBin[t*m_iRes[0]+x]*fac); } } // strcpy(buf,prefix); // strcat(buf,name); // strcat(buf,suffix); buf.strcpy(prefix); buf.strcat(name); buf.strcat(suffix); g->WriteAgr(buf,false); *strrchr(buf.GetWritePointer(),'.') = 0; buf.strcat(".csv"); g->WriteCSV(buf); BTOUT; } void C2DF::WriteCSV(const char *prefix, const char *name, const char *suffix) { BTIN; FILE *a; int z, z2; // char buf[32768]; CxString buf; // strcpy(buf,prefix); // strcat(buf,name); // strcat(buf,suffix); buf.strcpy(prefix); buf.strcat(name); buf.strcat(suffix); a = OpenFileWrite(buf,true); if (m_sLabelX == NULL) mfprintf(a,"(no label) \\ "); else mfprintf(a,"%s \\ ",m_sLabelX); if (m_sLabelY == NULL) mfprintf(a,"(no label)"); else mfprintf(a,"%s",m_sLabelY); for (z=0;z abs(s_zmax)) s_zmax=abs(s_zmin); else s_zmin=-abs(s_zmax)\n\n"); mfprintf(b,"font_string = sprintf(\"%cs,%cd\", \"Helvetica\", 24*s_scale)\n",'%','%'); mfprintf(b,"titlefont_string = sprintf(\"%cs,%cd\", \"Helvetica\", 24*1.2*s_scale*s_titlefontscale)\n",'%','%'); mfprintf(b,"labelfont_string = sprintf(\"%cs,%cd\", \"Helvetica\", 24*s_scale*s_labelfontscale)\n",'%','%'); mfprintf(b,"ticsfont_string = sprintf(\"%cs,%cd\", \"Helvetica\", 24*s_scale*s_ticsfontscale)\n",'%','%'); mfprintf(b,"\n"); mfprintf(b,"set term pngcairo enhanced font font_string linewidth 4.0*s_scale size 1024*s_scale,1024*s_scale\n"); mfprintf(b,"set output \"%s.png\"\n",(const char*)out2); mfprintf(b,"set size ratio s_ratio\n"); mfprintf(b,"\n"); mfprintf(b,"set title s_title font titlefont_string\n"); mfprintf(b,"set xlabel s_xtitle font labelfont_string\n"); mfprintf(b,"set ylabel s_ytitle font labelfont_string\n"); mfprintf(b,"unset key\n"); mfprintf(b,"unset clabel\n"); mfprintf(b,"\n"); mfprintf(b,"set pm3d interpolate s_xipl,s_yipl map\n"); mfprintf(b,"\n"); if (m_iColorScale == 4) // Plus-Minus-Plot mfprintf(b,"set palette model RGB functions gray<=0.0 ? 0.0 : gray<0.1 ? 0.0 : gray<0.4 ? 0.0 : gray<0.5 ? (gray-0.4)/0.1 : gray<0.6 ? 1.0 : gray<0.8 ? 1.0 : gray<1.0 ? 1.0 : 1.0, gray<=0.0 ? 0.0 : gray<0.1 ? 0.0 : gray<0.4 ? (gray-0.1)/0.3 : gray<0.5 ? 1.0 : gray<0.6 ? 1.0 : gray<0.8 ? ((0.8-gray)/0.2)**0.5 : gray<1.0 ? 0.0 : 0.0, gray<=0.0 ? 0.5 : gray<0.1 ? 0.5+gray*5.0 : gray<0.4 ? 1.0 : gray<0.5 ? 1.0 : gray<0.6 ? (0.6-gray)/0.1 : gray<0.8 ? 0.0 : gray<1.0 ? (gray-0.8)/0.1 : 1.0\n"); else mfprintf(b,"set palette model RGB functions gray<=0.0 ? 1.0 : gray<0.2 ? 1.0-(5.0**1.5*gray**1.5)*0.8 : gray<0.4 ? 0.2-(gray-0.2) : gray<0.6 ? 5.0**0.5*(gray-0.4)**0.5 : gray<0.8 ? 1.0 : gray<1.0 ? 1.0 : 1.0, gray<=0.0 ? 1.0 : gray<0.2 ? 1.0-(5.0**1.5*gray**1.5)*0.8 : gray<0.4 ? 0.2+0.8*(5.0**0.75*(gray-0.2)**0.75) : gray<0.6 ? 1.0 : gray<0.8 ? 1.0-5.0*(gray-0.6) : gray<1.0 ? 0.0 : 0.0, gray<=0.0 ? 1.0 : gray<0.2 ? 1.0 : gray<0.4 ? 1.0-5.0**1.33*(gray-0.2)**1.33 : gray<0.6 ? 0.0 : gray<0.8 ? 0.0 : gray<1.0 ? 5.0*(gray-0.8) : 1.0\n"); mfprintf(b,"\n"); mfprintf(b,"if (s_contour) set palette maxcolors s_ncontour; else set palette maxcolors 0\n"); mfprintf(b,"\n"); mfprintf(b,"set xrange [s_xmin:s_xmax]\n"); mfprintf(b,"set yrange [s_ymin:s_ymax]\n"); mfprintf(b,"set zrange [f_plot(s_zmin):f_plot(s_zmax)]\n"); mfprintf(b,"set cbrange [f_plot(s_zmin):f_plot(s_zmax)]\n"); mfprintf(b,"unset colorbox\n"); mfprintf(b,"\n"); mfprintf(b,"set tics font ticsfont_string\n"); mfprintf(b,"set xtics s_xtics out scale 0.5*s_borderscale offset 0,0.5\n"); mfprintf(b,"set mxtics s_mxtics\n"); mfprintf(b,"set ytics s_ytics out scale 0.5*s_borderscale offset 0.5,0\n"); mfprintf(b,"set mytics s_mytics\n"); mfprintf(b,"\n"); mfprintf(b,"set border linewidth s_borderscale\n"); mfprintf(b,"\n"); mfprintf(b,"set multiplot\n"); mfprintf(b,"\n"); mfprintf(b,"set origin -0.05,-0.05\n"); mfprintf(b,"set size 1.15,1.15\n"); mfprintf(b,"\n"); mfprintf(b,"splot \"%s\" matrix using ($2*%G+%G):($1*%G+%G):(f_plot($3))\n",(const char*)out,(m_fMaxVal[0]-m_fMinVal[0])/m_iRes[0],m_fMinVal[0]+(m_fMaxVal[0]-m_fMinVal[0])/m_iRes[0]/2.0,(m_fMaxVal[1]-m_fMinVal[1])/m_iRes[1],m_fMinVal[1]+(m_fMaxVal[1]-m_fMinVal[1])/m_iRes[1]/2.0); // mfprintf(b,"splot \"test5.dat\" matrix using ($2*1.5+50.75):($1*5.0+2.5):(f_plot($3))\n"); mfprintf(b,"\n"); mfprintf(b,"set grid xtics mxtics ytics mytics back linestyle -1 linewidth 0.15*s_gridscale linecolor rgbcolor \"gray40\"\n"); mfprintf(b,"set title \"\"\n"); mfprintf(b,"set xlabel \"\"\n"); mfprintf(b,"set ylabel \"\"\n"); mfprintf(b,"set xtics in format \"\"\n"); mfprintf(b,"set ytics in format \"\"\n"); mfprintf(b,"if (s_contour) set contour base; set cntrparam bspline; set cntrparam levels incremental f_plot(s_zmin),1.0*(f_plot(s_zmax)-f_plot(s_zmin))/s_ncontour,f_plot(s_zmax)\n"); mfprintf(b,"\n"); mfprintf(b,"splot \"%s\" matrix using ($2*%G+%G):($1*%G+%G):(s_contour ? f_plot($3) : 1/0) with lines linewidth 0.15*s_contourscale linecolor rgbcolor \"black\" nosurface\n",(const char*)out,(m_fMaxVal[0]-m_fMinVal[0])/m_iRes[0],m_fMinVal[0]+(m_fMaxVal[0]-m_fMinVal[0])/m_iRes[0]/2.0,(m_fMaxVal[1]-m_fMinVal[1])/m_iRes[1],m_fMinVal[1]+(m_fMaxVal[1]-m_fMinVal[1])/m_iRes[1]/2.0); mfprintf(b,"\n"); mfprintf(b,"unset multiplot\n"); mfprintf(b,"\n"); mfprintf(b,"if (s_lorient) t_x = 196*s_scale; else t_x = 896*s_scale\n"); mfprintf(b,"if (s_lorient) t_y = 896*s_scale; else t_y = 196*s_scale\n"); mfprintf(b,"\n"); mfprintf(b,"set term pngcairo enhanced font font_string linewidth 4.0*s_scale size t_x,t_y\n"); mfprintf(b,"set output \"%s_box.png\"\n",(const char*)out2); mfprintf(b,"\n"); mfprintf(b,"if (s_lorient) t_ratio = 20; else t_ratio = 0.05\n"); mfprintf(b,"\n"); mfprintf(b,"set origin -0.13,-0.13\n"); mfprintf(b,"set size ratio t_ratio 1.25,1.25\n"); mfprintf(b,"\n"); mfprintf(b,"unset title\n"); mfprintf(b,"unset xlabel\n"); mfprintf(b,"unset ylabel\n"); mfprintf(b,"\n"); mfprintf(b,"set grid front\n"); mfprintf(b,"unset grid\n"); mfprintf(b,"\n"); mfprintf(b,"if (s_lorient) set xrange [0:1]; else set xrange [s_zmin:s_zmax]\n"); mfprintf(b,"if (s_lorient) set yrange [s_zmin:s_zmax]; else set yrange [0:1]\n"); mfprintf(b,"if (s_lorient) set format y; else set format x\n"); mfprintf(b,"if (s_zauto) set xtics scale 0.5*s_borderscale offset s_lorient ? -0.5 : 0,s_lorient ? 0 : 0.5 autofreq; else set xtics scale 0.5*s_borderscale offset 0,0.5 s_ztics\n"); mfprintf(b,"if (s_zauto) set mxtics default; else set mxtics s_mztics\n"); mfprintf(b,"if (s_zauto) set ytics scale 0.5*s_borderscale offset s_lorient ? -0.5 : 0,s_lorient ? 0 : 0.5 autofreq; else set ytics scale 0.5*s_borderscale offset 0,0.5 s_ztics\n"); mfprintf(b,"if (s_zauto) set mytics default; else set mytics s_mztics\n"); mfprintf(b,"if (s_lorient) unset xtics; else unset ytics\n"); mfprintf(b,"\n"); mfprintf(b,"if (s_lorient) set isosamples 2,500\n"); mfprintf(b,"\n"); mfprintf(b,"if (s_lorient) set view 0,0; set border 15; unset ztics; set size 0.85,1.5; set origin -0.13,-0.25\n"); mfprintf(b,"\n"); mfprintf(b,"splot f_plot(s_lorient ? y : x) nocontour, s_contour ? f_plot(s_lorient ? y : x) : 1/0 with lines linewidth 0.15*s_contourscale linecolor rgbcolor \"black\" nosurface\n"); fclose(b); } void C2DF::WriteMathematicaNb(const char *prefix, const char *name, const char *suffix, bool manrange, bool printinfo) { BTIN; FILE *a; int z, z2; // char buf[32768]; CxString buf; int minorx, majorx, minory, majory; // strcpy(buf,prefix); // strcat(buf,name); // strcat(buf,suffix); buf.strcpy(prefix); buf.strcat(name); buf.strcat(suffix); if (!manrange) CalcMaxEntry(); if ((m_iPlotType == 1) && (!m_bContourLines)) m_iPlotType = 2; CreateTicks(m_fMinVal[0],m_fMaxVal[0],majorx,minorx,printinfo); CreateTicks(m_fMinVal[1],m_fMaxVal[1],majory,minory,printinfo); a = OpenFileWrite(buf,true); mfprintf(a,"\n"); mfprintf(a,"Notebook[{\n"); mfprintf(a,"Cell[BoxData[\n"); mfprintf(a," StyleBox[\n"); mfprintf(a," RowBox[{\"TRAVIS\", \" \", \"Analysis\"}], \"Section\",\n"); mfprintf(a," Evaluatable->False]], \"Input\",\n"); mfprintf(a," Evaluatable->False],\n"); mfprintf(a,"\n"); mfprintf(a,"Cell[CellGroupData[{\n"); mfprintf(a,"Cell[\"Input Data\", \"Section\",\n"); mfprintf(a," CellDingbat->DynamicModuleBox[{$CellContext`state$$ = False}, \n"); mfprintf(a," OpenerBox[\n"); mfprintf(a," Dynamic[$CellContext`state$$, (FrontEndExecute[{\n"); mfprintf(a," FrontEnd`SelectionMove[\n"); mfprintf(a," FrontEnd`ButtonNotebook[], All, ButtonCell], \n"); mfprintf(a," FrontEndToken[\"OpenCloseGroup\"]}]; $CellContext`state$$ = #)& ]], \n"); mfprintf(a," DynamicModuleValues :> {}]],\n"); mfprintf(a,"\n"); mfprintf(a,"Cell[BoxData[\n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"dat\", \"=\",\n"); mfprintf(a," RowBox[{\"dat2\", \"=\", \n"); mfprintf(a," RowBox[{\"{\", \n"); mfprintf(a," RowBox[{\n"); for (z=0;zDynamicModuleBox[{$CellContext`state$$ = False}, \n"); mfprintf(a," OpenerBox[\n"); mfprintf(a," Dynamic[$CellContext`state$$, (FrontEndExecute[{\n"); mfprintf(a," FrontEnd`SelectionMove[\n"); mfprintf(a," FrontEnd`ButtonNotebook[], All, ButtonCell], \n"); mfprintf(a," FrontEndToken[\"OpenCloseGroup\"]}]; $CellContext`state$$ = #)& ]], \n"); mfprintf(a," DynamicModuleValues :> {}]],\n"); mfprintf(a,"\n"); mfprintf(a,"Cell[BoxData[{\n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"prim\", \"=\", \n"); mfprintf(a," RowBox[{\"{\", \"}\"}]}], \";\"}], \"\\[IndentingNewLine]\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"funcX\", \"=\", \n"); mfprintf(a," RowBox[{\"{\", \"}\"}]}], \";\"}], \"\\[IndentingNewLine]\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"funcY\", \"=\", \n"); mfprintf(a," RowBox[{\"{\", \"}\"}]}], \";\"}], \"\\[IndentingNewLine]\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"x\", \"=.\"}], \";\"}], \"\\[IndentingNewLine]\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"s\", \"=.\"}], \";\"}], \"\\[IndentingNewLine]\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"maxsig\", \"[\",\n"); mfprintf(a," RowBox[{\"x_\", \",\", \"s_\"}], \"]\"}], \"=\",\n"); mfprintf(a," RowBox[{\"N\", \"[\",\n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"If\", \"[\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"x\", \"\\[Equal]\", \"0\"}], \",\", \"0\", \",\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"Ceiling\", \"[\", \n"); mfprintf(a," RowBox[{\"x\", \"/\", \n"); mfprintf(a," RowBox[{\"10\", \"^\", \n"); mfprintf(a," RowBox[{\"Floor\", \"[\", \n"); mfprintf(a," RowBox[{\"N\", \"[\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"Log\", \"[\", \n"); mfprintf(a," RowBox[{\"10\", \",\", \n"); mfprintf(a," RowBox[{\"Abs\", \"[\", \"x\", \"]\"}]}], \"]\"}], \"+\", \"1\", \"-\", \"s\"}],\n"); mfprintf(a," \"]\"}], \"]\"}]}]}], \"]\"}], \"*\", \n"); mfprintf(a," RowBox[{\"10\", \"^\", \n"); mfprintf(a," RowBox[{\"Floor\", \"[\", \n"); mfprintf(a," RowBox[{\"N\", \"[\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"Log\", \"[\", \n"); mfprintf(a," RowBox[{\"10\", \",\", \n"); mfprintf(a," RowBox[{\"Abs\", \"[\", \"x\", \"]\"}]}], \"]\"}], \"+\", \"1\", \"-\", \"s\"}], \n"); mfprintf(a," \"]\"}], \"]\"}]}]}]}], \"]\"}], \"+\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"Abs\", \"[\", \"x\", \"]\"}], \"/\", \"1000000\"}]}], \"]\"}]}], \n"); mfprintf(a," \";\"}], \"\\n\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"minsig\", \"[\", \n"); mfprintf(a," RowBox[{\"x_\", \",\", \"s_\"}], \"]\"}], \"=\", \n"); mfprintf(a," RowBox[{\"N\", \"[\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"If\", \"[\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"x\", \"\\[Equal]\", \"0\"}], \",\", \"0\", \",\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"Floor\", \"[\", \n"); mfprintf(a," RowBox[{\"x\", \"/\", \n"); mfprintf(a," RowBox[{\"10\", \"^\", \n"); mfprintf(a," RowBox[{\"Floor\", \"[\", \n"); mfprintf(a," RowBox[{\"N\", \"[\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"Log\", \"[\", \n"); mfprintf(a," RowBox[{\"10\", \",\", \n"); mfprintf(a," RowBox[{\"Abs\", \"[\", \"x\", \"]\"}]}], \"]\"}], \"+\", \"1\", \"-\", \"s\"}],\n"); mfprintf(a," \"]\"}], \"]\"}]}]}], \"]\"}], \"*\", \n"); mfprintf(a," RowBox[{\"10\", \"^\", \n"); mfprintf(a," RowBox[{\"Floor\", \"[\", \n"); mfprintf(a," RowBox[{\"N\", \"[\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"Log\", \"[\", \n"); mfprintf(a," RowBox[{\"10\", \",\", \n"); mfprintf(a," RowBox[{\"Abs\", \"[\", \"x\", \"]\"}]}], \"]\"}], \"+\", \"1\", \"-\", \"s\"}], \n"); mfprintf(a," \"]\"}], \"]\"}]}]}]}], \"]\"}], \"-\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"Abs\", \"[\", \"x\", \"]\"}], \"/\", \"1000000\"}]}], \"]\"}]}], \n"); mfprintf(a," \";\"}], \"\\n\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"prec\", \"[\", \"x_\", \"]\"}], \"=\", \n"); mfprintf(a," RowBox[{\"Max\", \"[\", \n"); mfprintf(a," RowBox[{\"0\", \",\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"Floor\", \"[\", \n"); mfprintf(a," RowBox[{\"N\", \"[\", \n"); mfprintf(a," RowBox[{\"Log\", \"[\", \n"); mfprintf(a," RowBox[{\"10\", \",\", \n"); mfprintf(a," RowBox[{\"1\", \"/\", \n"); mfprintf(a," RowBox[{\"Abs\", \"[\", \"x\", \"]\"}]}]}], \"]\"}], \"]\"}], \"]\"}], \"+\", \n"); mfprintf(a," \"2\"}]}], \"]\"}]}], \";\"}], \"\\[IndentingNewLine]\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"plot\", \":=\", \n"); mfprintf(a," RowBox[{\"(\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"x\", \"=.\"}], \";\", \n"); mfprintf(a," RowBox[{\"y\", \"=.\"}], \";\", \"\\[IndentingNewLine]\", \"\\[IndentingNewLine]\", \n"); mfprintf(a," RowBox[{\"(*\", \" \", \n"); mfprintf(a," RowBox[{\"Select\", \" \", \"Color\", \" \", \"Function\"}], \" \", \"*)\"}],"); mfprintf(a," \"\\[IndentingNewLine]\","); mfprintf(a," RowBox[{\"If\", \"[\", "); mfprintf(a," RowBox[{"); mfprintf(a," RowBox[{\"coloring\", \"\\[Equal]\", \"1\"}], \",\", "); mfprintf(a," RowBox[{"); mfprintf(a," RowBox[{\"ColFunc\", \"[\", \"x_\", \"]\"}], \"=\", "); mfprintf(a," RowBox[{\"If\", \"[\", "); mfprintf(a," RowBox[{"); mfprintf(a," RowBox[{\"x\", \"\\[LessEqual]\", \"0\"}], \",\", "); mfprintf(a," RowBox[{\"RGBColor\", \"[\", "); mfprintf(a," RowBox[{\"1\", \",\", \"1\", \",\", \"1\"}], \"]\"}], \",\", "); mfprintf(a," RowBox[{\"If\", \"[\", "); mfprintf(a," RowBox[{"); mfprintf(a," RowBox[{\"x\", \"<\", "); mfprintf(a," RowBox[{\"1\", \"/\", \"5\"}]}], \",\", "); mfprintf(a," RowBox[{\"RGBColor\", \"[\", "); mfprintf(a," RowBox[{"); mfprintf(a," RowBox[{\"1\", \"-\", "); mfprintf(a," RowBox[{"); mfprintf(a," RowBox[{\"(\", "); mfprintf(a," RowBox[{"); mfprintf(a," RowBox[{\"5\", \"^\", \"1.5\"}], \"*\", "); mfprintf(a," RowBox[{\"x\", \"^\", \"1.5\"}]}], \")\"}], \"*\", \"0.8\"}]}], \",\", "); mfprintf(a," RowBox[{\"1\", \"-\", "); mfprintf(a," RowBox[{"); mfprintf(a," RowBox[{\"(\", "); mfprintf(a," RowBox[{"); mfprintf(a," RowBox[{\"5\", \"^\", \"1.5\"}], \"*\", "); mfprintf(a," RowBox[{\"x\", \"^\", \"1.5\"}]}], \")\"}], \"*\", \"0.8\"}]}], \",\", "); mfprintf(a," \"1\"}], \"]\"}], \",\", "); mfprintf(a," RowBox[{\"If\", \"[\", "); mfprintf(a," RowBox[{"); mfprintf(a," RowBox[{\"x\", \"<\", "); mfprintf(a," RowBox[{\"2\", \"/\", \"5\"}]}], \",\", "); mfprintf(a," RowBox[{\"RGBColor\", \"[\", "); mfprintf(a," RowBox[{"); mfprintf(a," RowBox[{\"0.2\", \"-\", "); mfprintf(a," RowBox[{\"(\", "); mfprintf(a," RowBox[{\"x\", \"-\", "); mfprintf(a," RowBox[{\"1\", \"/\", \"5\"}]}], \")\"}]}], \",\", "); mfprintf(a," RowBox[{\"0.2\", \"+\", "); mfprintf(a," RowBox[{\"0.8\", \"*\", "); mfprintf(a," RowBox[{\"(\", "); mfprintf(a," RowBox[{"); mfprintf(a," RowBox[{\"5\", \"^\", \"0.75\"}], \"*\", "); mfprintf(a," RowBox[{"); mfprintf(a," RowBox[{\"(\", "); mfprintf(a," RowBox[{\"x\", \"-\", "); mfprintf(a," RowBox[{\"1\", \"/\", \"5\"}]}], \")\"}], \"^\", \"0.75\"}]}], "); mfprintf(a," \")\"}]}]}], \",\", "); mfprintf(a," RowBox[{\"1\", \"-\", "); mfprintf(a," RowBox[{"); mfprintf(a," RowBox[{\"5\", \"^\", \"1.33\"}], \"*\", "); mfprintf(a," RowBox[{"); mfprintf(a," RowBox[{\"(\", "); mfprintf(a," RowBox[{\"x\", \"-\", "); mfprintf(a," RowBox[{\"1\", \"/\", \"5\"}]}], \")\"}], \"^\", \"1.33\"}]}]}]}], "); mfprintf(a," \"]\"}], \",\", "); mfprintf(a," RowBox[{\"If\", \"[\", "); mfprintf(a," RowBox[{"); mfprintf(a," RowBox[{\"x\", \"<\", "); mfprintf(a," RowBox[{\"3\", \"/\", \"5\"}]}], \",\", "); mfprintf(a," RowBox[{\"RGBColor\", \"[\", "); mfprintf(a," RowBox[{"); mfprintf(a," RowBox[{"); mfprintf(a," RowBox[{\"5\", \"^\", \"0.5\"}], \"*\", "); mfprintf(a," RowBox[{"); mfprintf(a," RowBox[{\"(\", "); mfprintf(a," RowBox[{\"x\", \"-\", "); mfprintf(a," RowBox[{\"2\", \"/\", \"5\"}]}], \")\"}], \"^\", \"0.5\"}]}], \",\", "); mfprintf(a," \"1\", \",\", \"0\"}], \"]\"}], \",\", "); mfprintf(a," RowBox[{\"If\", \"[\", "); mfprintf(a," RowBox[{"); mfprintf(a," RowBox[{\"x\", \"<\", "); mfprintf(a," RowBox[{\"4\", \"/\", \"5\"}]}], \",\", "); mfprintf(a," RowBox[{\"RGBColor\", \"[\", "); mfprintf(a," RowBox[{\"1\", \",\", "); mfprintf(a," RowBox[{\"1\", \"-\", "); mfprintf(a," RowBox[{\"5\", \"*\", "); mfprintf(a," RowBox[{\"(\", "); mfprintf(a," RowBox[{\"x\", \"-\", "); mfprintf(a," RowBox[{\"3\", \"/\", \"5\"}]}], \")\"}]}]}], \",\", \"0\"}], \"]\"}], "); mfprintf(a," \",\", "); mfprintf(a," RowBox[{\"If\", \"[\", "); mfprintf(a," RowBox[{"); mfprintf(a," RowBox[{\"x\", \"<\", \"1\"}], \",\", "); mfprintf(a," RowBox[{\"RGBColor\", \"[\", "); mfprintf(a," RowBox[{\"1\", \",\", \"0\", \",\", "); mfprintf(a," RowBox[{\"5\", \"*\", "); mfprintf(a," RowBox[{\"(\", "); mfprintf(a," RowBox[{\"x\", \"-\", "); mfprintf(a," RowBox[{\"4\", \"/\", \"5\"}]}], \")\"}]}]}], \"]\"}], \",\", "); mfprintf(a," RowBox[{\"RGBColor\", \"[\", "); mfprintf(a," RowBox[{\"1\", \",\", \"0\", \",\", \"1\"}], \"]\"}]}], \"]\"}]}], "); mfprintf(a," \"]\"}]}], \"]\"}]}], \"]\"}]}], \"]\"}]}], \"]\"}]}], \",\", "); mfprintf(a," RowBox[{\"If\", \"[\", "); mfprintf(a," RowBox[{"); mfprintf(a," RowBox[{\"coloring\", \"\\[Equal]\", \"2\"}], \",\", "); mfprintf(a," RowBox[{"); mfprintf(a," RowBox[{\"ColFunc\", \"[\", \"x_\", \"]\"}], \"=\", "); mfprintf(a," RowBox[{\"RGBColor\", \"[\", "); mfprintf(a," RowBox[{"); mfprintf(a," RowBox[{\"1\", \"-\", \"x\"}], \",\", "); mfprintf(a," RowBox[{\"1\", \"-\", \"x\"}], \",\", "); mfprintf(a," RowBox[{\"1\", \"-\", \"x\"}]}], \"]\"}]}], \",\", "); mfprintf(a," RowBox[{\"If\", \"[\", "); mfprintf(a," RowBox[{"); mfprintf(a," RowBox[{\"coloring\", \"\\[Equal]\", \"3\"}], \",\", "); mfprintf(a," RowBox[{"); mfprintf(a," RowBox[{\"ColFunc\", \"[\", \"x_\", \"]\"}], \"=\", "); mfprintf(a," RowBox[{"); mfprintf(a," RowBox[{\"ColorData\", \"[\", \"\\\"\\\\\"\", \"]\"}], \"[\", "); mfprintf(a," \"x\", \"]\"}]}], \",\", "); mfprintf(a," RowBox[{"); mfprintf(a," RowBox[{\"ColFunc\", \"[\", \"x_\", \"]\"}], \"=\", "); mfprintf(a," RowBox[{\"If\", \"[\", "); mfprintf(a," RowBox[{"); mfprintf(a," RowBox[{\"x\", \"\\[LessEqual]\", \"0\"}], \",\", "); mfprintf(a," RowBox[{\"RGBColor\", \"[\", "); mfprintf(a," RowBox[{\"0\", \",\", \"0\", \",\", \"0.5\"}], \"]\"}], \",\", "); mfprintf(a," RowBox[{\"If\", \"[\", "); mfprintf(a," RowBox[{"); mfprintf(a," RowBox[{\"x\", \"<\", \"0.1\"}], \",\", "); mfprintf(a," RowBox[{\"RGBColor\", \"[\", "); mfprintf(a," RowBox[{\"0\", \",\", \"0\", \",\", "); mfprintf(a," RowBox[{\"0.5\", \"+\", "); mfprintf(a," RowBox[{\"5\", \"*\", \"x\"}]}]}], \"]\"}], \",\", "); mfprintf(a," RowBox[{\"If\", \"[\", "); mfprintf(a," RowBox[{"); mfprintf(a," RowBox[{\"x\", \"<\", \"0.4\"}], \",\", "); mfprintf(a," RowBox[{\"RGBColor\", \"[\", "); mfprintf(a," RowBox[{\"0\", \",\", "); mfprintf(a," RowBox[{"); mfprintf(a," RowBox[{\"(\", "); mfprintf(a," RowBox[{\"x\", \"-\", \"0.1\"}], \")\"}], \"/\", \"0.3\"}], \",\", "); mfprintf(a," \"1\"}], \"]\"}], \",\", "); mfprintf(a," RowBox[{\"If\", \"[\", "); mfprintf(a," RowBox[{"); mfprintf(a," RowBox[{\"x\", \"<\", \"0.5\"}], \",\", "); mfprintf(a," RowBox[{\"RGBColor\", \"[\", "); mfprintf(a," RowBox[{"); mfprintf(a," RowBox[{"); mfprintf(a," RowBox[{\"(\", "); mfprintf(a," RowBox[{\"x\", \"-\", \"0.4\"}], \")\"}], \"/\", \"0.1\"}], \",\", \"1\", "); mfprintf(a," \",\", \"1\"}], \"]\"}], \",\", "); mfprintf(a," RowBox[{\"If\", \"[\", "); mfprintf(a," RowBox[{"); mfprintf(a," RowBox[{\"x\", \"<\", \"0.6\"}], \",\", "); mfprintf(a," RowBox[{\"RGBColor\", \"[\", "); mfprintf(a," RowBox[{\"1\", \",\", \"1\", \",\", "); mfprintf(a," RowBox[{"); mfprintf(a," RowBox[{\"(\", "); mfprintf(a," RowBox[{\"0.6\", \"-\", \"x\"}], \")\"}], \"*\", \"10\"}]}], \"]\"}], "); mfprintf(a," \",\", "); mfprintf(a," RowBox[{\"If\", \"[\", "); mfprintf(a," RowBox[{"); mfprintf(a," RowBox[{\"x\", \"<\", \"0.8\"}], \",\", "); mfprintf(a," RowBox[{\"RGBColor\", \"[\", "); mfprintf(a," RowBox[{\"1\", \",\", "); mfprintf(a," RowBox[{"); mfprintf(a," RowBox[{\"(\", "); mfprintf(a," RowBox[{"); mfprintf(a," RowBox[{\"(\", "); mfprintf(a," RowBox[{\"0.8\", \"-\", \"x\"}], \")\"}], \"/\", \"0.2\"}], \")\"}], "); mfprintf(a," \"^\", \"0.5\"}], \",\", \"0\"}], \"]\"}], \",\", "); mfprintf(a," RowBox[{\"If\", \"[\", "); mfprintf(a," RowBox[{"); mfprintf(a," RowBox[{\"x\", \"<\", \"1\"}], \",\", "); mfprintf(a," RowBox[{\"RGBColor\", \"[\", "); mfprintf(a," RowBox[{\"1\", \",\", \"0\", \",\", "); mfprintf(a," RowBox[{"); mfprintf(a," RowBox[{\"(\", "); mfprintf(a," RowBox[{\"x\", \"-\", \"0.9\"}], \")\"}], \"*\", \"10\"}]}], \"]\"}], "); mfprintf(a," \",\", "); mfprintf(a," RowBox[{\"RGBColor\", \"[\", "); mfprintf(a," RowBox[{\"1\", \",\", \"0\", \",\", \"1\"}], \"]\"}]}], \"]\"}]}], "); mfprintf(a," \"]\"}]}], \"]\"}]}], \"]\"}]}], \"]\"}]}], \"]\"}]}], \"]\"}]}]}], "); mfprintf(a," \"]\"}]}], \"]\"}]}], \"]\"}], \";\", \"\\[IndentingNewLine]\", "); mfprintf(a," \"\\[IndentingNewLine]\", "); mfprintf(a," RowBox[{\"oplotrangeX1\", \"=\", \"%f\"}], \";\", \"\\[IndentingNewLine]\", \n",m_fMinVal[0]); mfprintf(a," RowBox[{\"oplotrangeY1\", \"=\", \"%f\"}], \";\", \"\\[IndentingNewLine]\", \n",m_fMinVal[1]); mfprintf(a," RowBox[{\"oplotrangeX2\", \"=\", \"%f\"}], \";\", \"\\[IndentingNewLine]\", \n",m_fMaxVal[0]); mfprintf(a," RowBox[{\"oplotrangeY2\", \"=\", \"%f\"}], \";\", \"\\[IndentingNewLine]\", \n",m_fMaxVal[1]); mfprintf(a," RowBox[{\"oplotresX\", \"=\", \"%d\"}], \";\", \"\\[IndentingNewLine]\", \n",m_iRes[0]); mfprintf(a," RowBox[{\"oplotresY\", \"=\", \"%d\"}], \";\", \"\\[IndentingNewLine]\", \n",m_iRes[1]); mfprintf(a," \"\\[IndentingNewLine]\", \n"); mfprintf(a," RowBox[{\"plotresX\", \"=\", \n"); mfprintf(a," RowBox[{\"Ceiling\", \"[\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"(\", \n"); mfprintf(a," RowBox[{\"plotrangeX2\", \"-\", \"plotrangeX1\"}], \")\"}], \"/\", \n"); mfprintf(a," RowBox[{\"(\", \n"); mfprintf(a," RowBox[{\"oplotrangeX2\", \"-\", \"oplotrangeX1\"}], \")\"}]}], \"*\", \n"); mfprintf(a," \"oplotresX\"}], \"]\"}]}], \";\", \"\\[IndentingNewLine]\", \n"); mfprintf(a," RowBox[{\"plotresY\", \"=\", \n"); mfprintf(a," RowBox[{\"Ceiling\", \"[\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"(\", \n"); mfprintf(a," RowBox[{\"plotrangeY2\", \"-\", \"plotrangeY1\"}], \")\"}], \"/\", \n"); mfprintf(a," RowBox[{\"(\", \n"); mfprintf(a," RowBox[{\"oplotrangeY2\", \"-\", \"oplotrangeY1\"}], \")\"}]}], \"*\", \n"); mfprintf(a," \"oplotresY\"}], \"]\"}]}], \";\", \"\\[IndentingNewLine]\", \n"); mfprintf(a," RowBox[{\"plotresIndX\", \"=\", \n"); mfprintf(a," RowBox[{\"Ceiling\", \"[\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"(\", \n"); mfprintf(a," RowBox[{\"plotrangeX1\", \"-\", \"oplotrangeX1\"}], \")\"}], \"/\", \n"); mfprintf(a," RowBox[{\"(\", \n"); mfprintf(a," RowBox[{\"oplotrangeX2\", \"-\", \"oplotrangeX1\"}], \")\"}]}], \"*\", \n"); mfprintf(a," \"oplotresX\"}], \"]\"}]}], \";\", \"\\[IndentingNewLine]\", \n"); mfprintf(a," RowBox[{\"plotresIndY\", \"=\", \n"); mfprintf(a," RowBox[{\"Ceiling\", \"[\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"(\", \n"); mfprintf(a," RowBox[{\"plotrangeY1\", \"-\", \"oplotrangeY1\"}], \")\"}], \"/\", \n"); mfprintf(a," RowBox[{\"(\", \n"); mfprintf(a," RowBox[{\"oplotrangeY2\", \"-\", \"oplotrangeY1\"}], \")\"}]}], \"*\", \n"); mfprintf(a," \"oplotresY\"}], \"]\"}]}], \";\", \"\\[IndentingNewLine]\", \n"); mfprintf(a," \"\\[IndentingNewLine]\", \n"); mfprintf(a," RowBox[{\"(*\", \" \", \n"); mfprintf(a," RowBox[{\"Smoothen\", \" \", \"Data\"}], \" \", \"*)\"}], \"\\[IndentingNewLine]\", \n"); mfprintf(a," RowBox[{\"dat\", \"=\", \n"); mfprintf(a," RowBox[{\"Table\", \"[\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"ox\", \"=\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"Mod\", \"[\", \n"); mfprintf(a," RowBox[{\"i\", \",\", \"plotresX\"}], \"]\"}], \"+\", \"plotresIndX\"}]}], \n"); mfprintf(a," \";\", \n"); mfprintf(a," RowBox[{\"oy\", \"=\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"Quotient\", \"[\", \n"); mfprintf(a," RowBox[{\"i\", \",\", \"plotresX\"}], \"]\"}], \"+\", \"plotresIndY\"}]}], \n"); mfprintf(a," \";\", \n"); mfprintf(a," RowBox[{\"x\", \"=\", \n"); mfprintf(a," RowBox[{\"Mod\", \"[\", \n"); mfprintf(a," RowBox[{\"i\", \",\", \"plotresX\"}], \"]\"}]}], \";\", \n"); mfprintf(a," RowBox[{\"y\", \"=\", \n"); mfprintf(a," RowBox[{\"Quotient\", \"[\", \n"); mfprintf(a," RowBox[{\"i\", \",\", \"plotresX\"}], \"]\"}]}], \";\", \n"); mfprintf(a," RowBox[{\"{\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"plotrangeX1\", \"+\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"(\", \n"); mfprintf(a," RowBox[{\"plotrangeX2\", \"-\", \"plotrangeX1\"}], \")\"}], \"*\", \n"); mfprintf(a," RowBox[{\"x\", \"/\", \n"); mfprintf(a," RowBox[{\"(\", \n"); mfprintf(a," RowBox[{\"plotresX\", \"-\", \"1\"}], \")\"}]}]}]}], \",\", \n"); mfprintf(a," RowBox[{\"plotrangeY1\", \"+\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"(\", \n"); mfprintf(a," RowBox[{\"plotrangeY2\", \"-\", \"plotrangeY1\"}], \")\"}], \"*\", \n"); mfprintf(a," RowBox[{\"y\", \"/\", \n"); mfprintf(a," RowBox[{\"(\", \n"); mfprintf(a," RowBox[{\"plotresY\", \"-\", \"1\"}], \")\"}]}]}]}], \",\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"s\", \"=\", \"0\"}], \";\", \n"); mfprintf(a," RowBox[{\"t\", \"=\", \"0\"}], \";\", \n"); mfprintf(a," RowBox[{\"For\", \"[\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"ty\", \"=\", \n"); mfprintf(a," RowBox[{\"-\", \"smoothgrade\"}]}], \",\", \n"); mfprintf(a," RowBox[{\"ty\", \"\\[LessEqual]\", \"smoothgrade\"}], \",\", \n"); mfprintf(a," RowBox[{\"ty\", \"++\"}], \",\", \n"); mfprintf(a," RowBox[{\"For\", \"[\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"tx\", \"=\", \n"); mfprintf(a," RowBox[{\"-\", \"smoothgrade\"}]}], \",\", \n"); mfprintf(a," RowBox[{\"tx\", \"\\[LessEqual]\", \"smoothgrade\"}], \",\", \n"); mfprintf(a," RowBox[{\"tx\", \"++\"}], \",\", \n"); mfprintf(a," RowBox[{\"If\", \"[\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"tx\", \"^\", \"2\"}], \"+\", \n"); mfprintf(a," RowBox[{\"ty\", \"^\", \"2\"}]}], \"\\[LessEqual]\", \n"); mfprintf(a," RowBox[{\"smoothgrade\", \"^\", \"2\"}]}], \",\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"r\", \"=\", \n"); mfprintf(a," RowBox[{\"1\", \"/\", \n"); mfprintf(a," RowBox[{\"(\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"tx\", \"^\", \"2\"}], \"+\", \n"); mfprintf(a," RowBox[{\"ty\", \"^\", \"2\"}], \"+\", \"1\"}], \")\"}]}]}], \";\", \n"); mfprintf(a," RowBox[{\"t\", \"+=\", \"r\"}], \";\", \n"); mfprintf(a," RowBox[{\"s\", \"+=\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"dat2\", \"[\", \n"); mfprintf(a," RowBox[{\"[\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"Max\", \"[\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"Min\", \"[\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"ox\", \"+\", \"tx\"}], \",\", \n"); mfprintf(a," RowBox[{\"oplotresX\", \"-\", \"1\"}]}], \"]\"}], \",\", \"0\"}], \n"); mfprintf(a," \"]\"}], \"+\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"Max\", \"[\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"Min\", \"[\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"oy\", \"+\", \"ty\"}], \",\", \n"); mfprintf(a," RowBox[{\"oplotresY\", \"-\", \"1\"}]}], \"]\"}], \",\", \"0\"}], \n"); mfprintf(a," \"]\"}], \"*\", \"oplotresX\"}], \"+\", \"1\"}], \"]\"}], \"]\"}], \"[\", \n"); mfprintf(a," RowBox[{\"[\", \"3\", \"]\"}], \"]\"}], \"*\", \"r\"}]}]}], \",\"}], \n"); mfprintf(a," \"]\"}]}], \"]\"}]}], \"]\"}], \";\", \n"); mfprintf(a," RowBox[{\"s\", \"/\", \"t\"}]}]}], \"}\"}]}], \",\", \n"); mfprintf(a," RowBox[{\"{\", \n"); mfprintf(a," RowBox[{\"i\", \",\", \"0\", \",\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"plotresX\", \"*\", \"plotresY\"}], \"-\", \"1\"}]}], \"}\"}]}], \n"); mfprintf(a," \"]\"}]}], \";\", \"\\[IndentingNewLine]\", \"\\[IndentingNewLine]\", \n"); mfprintf(a," RowBox[{\"(*\", \" \", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," \"Add\", \" \", \"Functions\", \" \", \"to\", \" \", \"primitive\", \" \", \"list\"}], \n"); mfprintf(a," \" \", \"*)\"}], \"\\[IndentingNewLine]\", \n"); mfprintf(a," RowBox[{\"For\", \"[\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"i\", \"=\", \"1\"}], \",\", \n"); mfprintf(a," RowBox[{\"i\", \"<=\", \n"); mfprintf(a," RowBox[{\"Length\", \"[\", \"funcX\", \"]\"}]}], \",\", \n"); mfprintf(a," RowBox[{\"i\", \"++\"}], \",\", \n"); mfprintf(a," RowBox[{\"AppendTo\", \"[\", \n"); mfprintf(a," RowBox[{\"prim\", \",\", \n"); mfprintf(a," RowBox[{\"ListLinePlot\", \"[\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"Table\", \"[\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"{\", \n"); mfprintf(a," RowBox[{\"x\", \",\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"funcX\", \"[\", \n"); mfprintf(a," RowBox[{\"[\", \"i\", \"]\"}], \"]\"}], \"[\", \n"); mfprintf(a," RowBox[{\"[\", \"1\", \"]\"}], \"]\"}]}], \"}\"}], \",\", \n"); mfprintf(a," RowBox[{\"{\", \n"); mfprintf(a," RowBox[{\"x\", \",\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"funcX\", \"[\", \n"); mfprintf(a," RowBox[{\"[\", \"i\", \"]\"}], \"]\"}], \"[\", \n"); mfprintf(a," RowBox[{\"[\", \"2\", \"]\"}], \"]\"}], \"[\", \n"); mfprintf(a," RowBox[{\"[\", \"1\", \"]\"}], \"]\"}], \",\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"funcX\", \"[\", \n"); mfprintf(a," RowBox[{\"[\", \"i\", \"]\"}], \"]\"}], \"[\", \n"); mfprintf(a," RowBox[{\"[\", \"2\", \"]\"}], \"]\"}], \"[\", \n"); mfprintf(a," RowBox[{\"[\", \"2\", \"]\"}], \"]\"}], \",\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"(\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"funcX\", \"[\", \n"); mfprintf(a," RowBox[{\"[\", \"i\", \"]\"}], \"]\"}], \"[\", \n"); mfprintf(a," RowBox[{\"[\", \"2\", \"]\"}], \"]\"}], \"[\", \n"); mfprintf(a," RowBox[{\"[\", \"2\", \"]\"}], \"]\"}], \"-\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"funcX\", \"[\", \n"); mfprintf(a," RowBox[{\"[\", \"i\", \"]\"}], \"]\"}], \"[\", \n"); mfprintf(a," RowBox[{\"[\", \"2\", \"]\"}], \"]\"}], \"[\", \n"); mfprintf(a," RowBox[{\"[\", \"1\", \"]\"}], \"]\"}]}], \")\"}], \"/\", \"1000\"}]}], \n"); mfprintf(a," \"}\"}]}], \"]\"}], \",\", \n"); mfprintf(a," RowBox[{\"PlotStyle\", \"\\[Rule]\", \n"); mfprintf(a," RowBox[{\"Evaluate\", \"[\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"funcX\", \"[\", \n"); mfprintf(a," RowBox[{\"[\", \"i\", \"]\"}], \"]\"}], \"[\", \n"); mfprintf(a," RowBox[{\"[\", \"3\", \"]\"}], \"]\"}], \"]\"}]}]}], \"]\"}]}], \"]\"}]}], \n"); mfprintf(a," \"]\"}], \";\", \"\\[IndentingNewLine]\", \n"); mfprintf(a," RowBox[{\"For\", \"[\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"i\", \"=\", \"1\"}], \",\", \n"); mfprintf(a," RowBox[{\"i\", \"<=\", \n"); mfprintf(a," RowBox[{\"Length\", \"[\", \"funcY\", \"]\"}]}], \",\", \n"); mfprintf(a," RowBox[{\"i\", \"++\"}], \",\", \n"); mfprintf(a," RowBox[{\"AppendTo\", \"[\", \n"); mfprintf(a," RowBox[{\"prim\", \",\", \n"); mfprintf(a," RowBox[{\"ListLinePlot\", \"[\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"Table\", \"[\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"{\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"funcY\", \"[\", \n"); mfprintf(a," RowBox[{\"[\", \"i\", \"]\"}], \"]\"}], \"[\", \n"); mfprintf(a," RowBox[{\"[\", \"1\", \"]\"}], \"]\"}], \",\", \"y\"}], \"}\"}], \",\", \n"); mfprintf(a," RowBox[{\"{\", \n"); mfprintf(a," RowBox[{\"y\", \",\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"funcY\", \"[\", \n"); mfprintf(a," RowBox[{\"[\", \"i\", \"]\"}], \"]\"}], \"[\", \n"); mfprintf(a," RowBox[{\"[\", \"2\", \"]\"}], \"]\"}], \"[\", \n"); mfprintf(a," RowBox[{\"[\", \"1\", \"]\"}], \"]\"}], \",\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"funcY\", \"[\", \n"); mfprintf(a," RowBox[{\"[\", \"i\", \"]\"}], \"]\"}], \"[\", \n"); mfprintf(a," RowBox[{\"[\", \"2\", \"]\"}], \"]\"}], \"[\", \n"); mfprintf(a," RowBox[{\"[\", \"2\", \"]\"}], \"]\"}], \",\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"(\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"funcY\", \"[\", \n"); mfprintf(a," RowBox[{\"[\", \"i\", \"]\"}], \"]\"}], \"[\", \n"); mfprintf(a," RowBox[{\"[\", \"2\", \"]\"}], \"]\"}], \"[\", \n"); mfprintf(a," RowBox[{\"[\", \"2\", \"]\"}], \"]\"}], \"-\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"funcY\", \"[\", \n"); mfprintf(a," RowBox[{\"[\", \"i\", \"]\"}], \"]\"}], \"[\", \n"); mfprintf(a," RowBox[{\"[\", \"2\", \"]\"}], \"]\"}], \"[\", \n"); mfprintf(a," RowBox[{\"[\", \"1\", \"]\"}], \"]\"}]}], \")\"}], \"/\", \"1000\"}]}], \n"); mfprintf(a," \"}\"}]}], \"]\"}], \",\", \n"); mfprintf(a," RowBox[{\"PlotStyle\", \"\\[Rule]\", \n"); mfprintf(a," RowBox[{\"Evaluate\", \"[\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"funcY\", \"[\", \n"); mfprintf(a," RowBox[{\"[\", \"i\", \"]\"}], \"]\"}], \"[\", \n"); mfprintf(a," RowBox[{\"[\", \"3\", \"]\"}], \"]\"}], \"]\"}]}]}], \"]\"}]}], \"]\"}]}], \n"); mfprintf(a," \"]\"}], \";\", \"\\[IndentingNewLine]\", \"\\[IndentingNewLine]\", \n"); mfprintf(a," RowBox[{\"tfx\", \":=\", \n"); mfprintf(a," RowBox[{\"Table\", \"[\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"i2\", \"=\", \n"); mfprintf(a," RowBox[{\"tickminX\", \"+\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"i\", \"/\", \n"); mfprintf(a," RowBox[{\"(\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"(\", \n"); mfprintf(a," RowBox[{\"majorticksX\", \"-\", \"1\"}], \")\"}], \"*\", \n"); mfprintf(a," RowBox[{\"(\", \n"); mfprintf(a," RowBox[{\"minorticksX\", \"+\", \"1\"}], \")\"}]}], \")\"}]}], \"*\", \n"); mfprintf(a," RowBox[{\"(\", \n"); mfprintf(a," RowBox[{\"tickmaxX\", \"-\", \"tickminX\"}], \")\"}]}]}]}], \";\", \n"); mfprintf(a," RowBox[{\"{\", \n"); mfprintf(a," RowBox[{\"i2\", \",\", \n"); mfprintf(a," RowBox[{\"If\", \"[\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"Mod\", \"[\", \n"); mfprintf(a," RowBox[{\"i\", \",\", \n"); mfprintf(a," RowBox[{\"minorticksX\", \"+\", \"1\"}]}], \"]\"}], \"\\[Equal]\", \n"); mfprintf(a," \"0\"}], \",\", \n"); mfprintf(a," RowBox[{\"ticklabelprefixX\", \"<>\", \n"); mfprintf(a," RowBox[{\"ToString\", \"[\", \n"); mfprintf(a," RowBox[{\"If\", \"[\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"tickprecX\", \"\\[Equal]\", \"0\"}], \",\", \n"); mfprintf(a," RowBox[{\"Round\", \"[\", \n"); mfprintf(a," RowBox[{\"i2\", \",\", \"1\"}], \"]\"}], \",\", \n"); mfprintf(a," RowBox[{\"PaddedForm\", \"[\", \n"); mfprintf(a," RowBox[{\"i2\", \",\", \n"); mfprintf(a," RowBox[{\"{\", \n"); mfprintf(a," RowBox[{\"20\", \",\", \"tickprecX\"}], \"}\"}], \",\", \n"); mfprintf(a," RowBox[{\"NumberPadding\", \"\\[Rule]\", \n"); mfprintf(a," RowBox[{\"{\", \n"); mfprintf(a," RowBox[{\"\\\"\\<\\>\\\"\", \",\", \"\\\"\\<0\\>\\\"\"}], \"}\"}]}]}], \n"); mfprintf(a," \"]\"}]}], \"]\"}], \"]\"}], \"<>\", \"ticklabelsuffixX\"}], \",\", \n"); mfprintf(a," \"\\\"\\<\\>\\\"\"}], \"]\"}], \",\", \n"); mfprintf(a," RowBox[{\"If\", \"[\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"Mod\", \"[\", \n"); mfprintf(a," RowBox[{\"i\", \",\", \n"); mfprintf(a," RowBox[{\"minorticksX\", \"+\", \"1\"}]}], \"]\"}], \"\\[Equal]\", \n"); mfprintf(a," \"0\"}], \",\", \n"); mfprintf(a," RowBox[{\"{\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"majorticklength\", \"*\", \n"); mfprintf(a," RowBox[{\"(\", \n"); mfprintf(a," RowBox[{\"1\", \"-\", \"majortickshift\"}], \")\"}]}], \",\", \n"); mfprintf(a," RowBox[{\"majorticklength\", \"*\", \"majortickshift\"}]}], \"}\"}], \n"); mfprintf(a," \",\", \n"); mfprintf(a," RowBox[{\"{\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"minorticklength\", \"*\", \n"); mfprintf(a," RowBox[{\"(\", \n"); mfprintf(a," RowBox[{\"1\", \"-\", \"minortickshift\"}], \")\"}]}], \",\", \n"); mfprintf(a," RowBox[{\"minorticklength\", \"*\", \"minortickshift\"}]}], \"}\"}]}],\n"); mfprintf(a," \"]\"}]}], \"}\"}]}], \",\", \n"); mfprintf(a," RowBox[{\"{\", \n"); mfprintf(a," RowBox[{\"i\", \",\", \"0\", \",\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"(\", \n"); mfprintf(a," RowBox[{\"majorticksX\", \"-\", \"1\"}], \")\"}], \"*\", \n"); mfprintf(a," RowBox[{\"(\", \n"); mfprintf(a," RowBox[{\"minorticksX\", \"+\", \"1\"}], \")\"}]}]}], \"}\"}]}], \"]\"}]}], \n"); mfprintf(a," \";\", \"\\[IndentingNewLine]\", \"\\[IndentingNewLine]\", \n"); mfprintf(a," RowBox[{\"tfxnolabel\", \":=\", \n"); mfprintf(a," RowBox[{\"Table\", \"[\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"i2\", \"=\", \n"); mfprintf(a," RowBox[{\"tickminX\", \"+\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"i\", \"/\", \n"); mfprintf(a," RowBox[{\"(\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"(\", \n"); mfprintf(a," RowBox[{\"majorticksX\", \"-\", \"1\"}], \")\"}], \"*\", \n"); mfprintf(a," RowBox[{\"(\", \n"); mfprintf(a," RowBox[{\"minorticksX\", \"+\", \"1\"}], \")\"}]}], \")\"}]}], \"*\", \n"); mfprintf(a," RowBox[{\"(\", \n"); mfprintf(a," RowBox[{\"tickmaxX\", \"-\", \"tickminX\"}], \")\"}]}]}]}], \";\", \n"); mfprintf(a," RowBox[{\"{\", \n"); mfprintf(a," RowBox[{\"i2\", \",\", \"\\\"\\<\\>\\\"\", \",\", \n"); mfprintf(a," RowBox[{\"If\", \"[\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"Mod\", \"[\", \n"); mfprintf(a," RowBox[{\"i\", \",\", \n"); mfprintf(a," RowBox[{\"minorticksX\", \"+\", \"1\"}]}], \"]\"}], \"\\[Equal]\", \n"); mfprintf(a," \"0\"}], \",\", \n"); mfprintf(a," RowBox[{\"{\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"majorticklength\", \"*\", \n"); mfprintf(a," RowBox[{\"(\", \n"); mfprintf(a," RowBox[{\"1\", \"-\", \"majortickshift\"}], \")\"}]}], \",\", \n"); mfprintf(a," RowBox[{\"majorticklength\", \"*\", \"majortickshift\"}]}], \"}\"}], \n"); mfprintf(a," \",\", \n"); mfprintf(a," RowBox[{\"{\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"minorticklength\", \"*\", \n"); mfprintf(a," RowBox[{\"(\", \n"); mfprintf(a," RowBox[{\"1\", \"-\", \"minortickshift\"}], \")\"}]}], \",\", \n"); mfprintf(a," RowBox[{\"minorticklength\", \"*\", \"minortickshift\"}]}], \"}\"}]}],\n"); mfprintf(a," \"]\"}]}], \"}\"}]}], \",\", \n"); mfprintf(a," RowBox[{\"{\", \n"); mfprintf(a," RowBox[{\"i\", \",\", \"0\", \",\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"(\", \n"); mfprintf(a," RowBox[{\"majorticksX\", \"-\", \"1\"}], \")\"}], \"*\", \n"); mfprintf(a," RowBox[{\"(\", \n"); mfprintf(a," RowBox[{\"minorticksX\", \"+\", \"1\"}], \")\"}]}]}], \"}\"}]}], \"]\"}]}], \n"); mfprintf(a," \";\", \"\\[IndentingNewLine]\", \"\\[IndentingNewLine]\", \n"); mfprintf(a," RowBox[{\"tfy\", \":=\", \n"); mfprintf(a," RowBox[{\"Table\", \"[\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"i2\", \"=\", \n"); mfprintf(a," RowBox[{\"tickminY\", \"+\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"i\", \"/\", \n"); mfprintf(a," RowBox[{\"(\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"(\", \n"); mfprintf(a," RowBox[{\"majorticksY\", \"-\", \"1\"}], \")\"}], \"*\", \n"); mfprintf(a," RowBox[{\"(\", \n"); mfprintf(a," RowBox[{\"minorticksY\", \"+\", \"1\"}], \")\"}]}], \")\"}]}], \"*\", \n"); mfprintf(a," RowBox[{\"(\", \n"); mfprintf(a," RowBox[{\"tickmaxY\", \"-\", \"tickminY\"}], \")\"}]}]}]}], \";\", \n"); mfprintf(a," RowBox[{\"{\", \n"); mfprintf(a," RowBox[{\"i2\", \",\", \n"); mfprintf(a," RowBox[{\"If\", \"[\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"Mod\", \"[\", \n"); mfprintf(a," RowBox[{\"i\", \",\", \n"); mfprintf(a," RowBox[{\"minorticksY\", \"+\", \"1\"}]}], \"]\"}], \"\\[Equal]\", \n"); mfprintf(a," \"0\"}], \",\", \n"); mfprintf(a," RowBox[{\"ticklabelprefixY\", \"<>\", \n"); mfprintf(a," RowBox[{\"ToString\", \"[\", \n"); mfprintf(a," RowBox[{\"If\", \"[\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"tickprecY\", \"\\[Equal]\", \"0\"}], \",\", \n"); mfprintf(a," RowBox[{\"Round\", \"[\", \n"); mfprintf(a," RowBox[{\"i2\", \",\", \"1\"}], \"]\"}], \",\", \n"); mfprintf(a," RowBox[{\"PaddedForm\", \"[\", \n"); mfprintf(a," RowBox[{\"i2\", \",\", \n"); mfprintf(a," RowBox[{\"{\", \n"); mfprintf(a," RowBox[{\"20\", \",\", \"tickprecY\"}], \"}\"}], \",\", \n"); mfprintf(a," RowBox[{\"NumberPadding\", \"\\[Rule]\", \n"); mfprintf(a," RowBox[{\"{\", \n"); mfprintf(a," RowBox[{\"\\\"\\<\\>\\\"\", \",\", \"\\\"\\<0\\>\\\"\"}], \"}\"}]}]}], \n"); mfprintf(a," \"]\"}]}], \"]\"}], \"]\"}], \"<>\", \"ticklabelsuffixY\"}], \",\", \n"); mfprintf(a," \"\\\"\\<\\>\\\"\"}], \"]\"}], \",\", \n"); mfprintf(a," RowBox[{\"If\", \"[\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"Mod\", \"[\", \n"); mfprintf(a," RowBox[{\"i\", \",\", \n"); mfprintf(a," RowBox[{\"minorticksY\", \"+\", \"1\"}]}], \"]\"}], \"\\[Equal]\", \n"); mfprintf(a," \"0\"}], \",\", \n"); mfprintf(a," RowBox[{\"{\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"majorticklength\", \"*\", \n"); mfprintf(a," RowBox[{\"(\", \n"); mfprintf(a," RowBox[{\"1\", \"-\", \"majortickshift\"}], \")\"}]}], \",\", \n"); mfprintf(a," RowBox[{\"majorticklength\", \"*\", \"majortickshift\"}]}], \"}\"}], \n"); mfprintf(a," \",\", \n"); mfprintf(a," RowBox[{\"{\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"minorticklength\", \"*\", \n"); mfprintf(a," RowBox[{\"(\", \n"); mfprintf(a," RowBox[{\"1\", \"-\", \"minortickshift\"}], \")\"}]}], \",\", \n"); mfprintf(a," RowBox[{\"minorticklength\", \"*\", \"minortickshift\"}]}], \"}\"}]}],\n"); mfprintf(a," \"]\"}]}], \"}\"}]}], \",\", \n"); mfprintf(a," RowBox[{\"{\", \n"); mfprintf(a," RowBox[{\"i\", \",\", \"0\", \",\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"(\", \n"); mfprintf(a," RowBox[{\"majorticksY\", \"-\", \"1\"}], \")\"}], \"*\", \n"); mfprintf(a," RowBox[{\"(\", \n"); mfprintf(a," RowBox[{\"minorticksY\", \"+\", \"1\"}], \")\"}]}]}], \"}\"}]}], \"]\"}]}], \n"); mfprintf(a," \";\", \"\\[IndentingNewLine]\", \"\\[IndentingNewLine]\", \n"); mfprintf(a," RowBox[{\"tfynolabel\", \":=\", \n"); mfprintf(a," RowBox[{\"Table\", \"[\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"i2\", \"=\", \n"); mfprintf(a," RowBox[{\"tickminY\", \"+\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"i\", \"/\", \n"); mfprintf(a," RowBox[{\"(\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"(\", \n"); mfprintf(a," RowBox[{\"majorticksY\", \"-\", \"1\"}], \")\"}], \"*\", \n"); mfprintf(a," RowBox[{\"(\", \n"); mfprintf(a," RowBox[{\"minorticksY\", \"+\", \"1\"}], \")\"}]}], \")\"}]}], \"*\", \n"); mfprintf(a," RowBox[{\"(\", \n"); mfprintf(a," RowBox[{\"tickmaxY\", \"-\", \"tickminY\"}], \")\"}]}]}]}], \";\", \n"); mfprintf(a," RowBox[{\"{\", \n"); mfprintf(a," RowBox[{\"i2\", \",\", \"\\\"\\<\\>\\\"\", \",\", \n"); mfprintf(a," RowBox[{\"If\", \"[\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"Mod\", \"[\", \n"); mfprintf(a," RowBox[{\"i\", \",\", \n"); mfprintf(a," RowBox[{\"minorticksY\", \"+\", \"1\"}]}], \"]\"}], \"\\[Equal]\", \n"); mfprintf(a," \"0\"}], \",\", \n"); mfprintf(a," RowBox[{\"{\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"majorticklength\", \"*\", \n"); mfprintf(a," RowBox[{\"(\", \n"); mfprintf(a," RowBox[{\"1\", \"-\", \"majortickshift\"}], \")\"}]}], \",\", \n"); mfprintf(a," RowBox[{\"majorticklength\", \"*\", \"majortickshift\"}]}], \"}\"}], \n"); mfprintf(a," \",\", \n"); mfprintf(a," RowBox[{\"{\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"minorticklength\", \"*\", \n"); mfprintf(a," RowBox[{\"(\", \n"); mfprintf(a," RowBox[{\"1\", \"-\", \"minortickshift\"}], \")\"}]}], \",\", \n"); mfprintf(a," RowBox[{\"minorticklength\", \"*\", \"minortickshift\"}]}], \"}\"}]}],\n"); mfprintf(a," \"]\"}]}], \"}\"}]}], \",\", \n"); mfprintf(a," RowBox[{\"{\", \n"); mfprintf(a," RowBox[{\"i\", \",\", \"0\", \",\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"(\", \n"); mfprintf(a," RowBox[{\"majorticksY\", \"-\", \"1\"}], \")\"}], \"*\", \n"); mfprintf(a," RowBox[{\"(\", \n"); mfprintf(a," RowBox[{\"minorticksY\", \"+\", \"1\"}], \")\"}]}]}], \"}\"}]}], \"]\"}]}], \n"); mfprintf(a," \";\", \"\\[IndentingNewLine]\", \"\\[IndentingNewLine]\", \n"); mfprintf(a," RowBox[{\"tfz\", \":=\", \n"); mfprintf(a," RowBox[{\"Table\", \"[\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"i2\", \"=\", \n"); mfprintf(a," RowBox[{\"tickminZ\", \"+\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"i\", \"/\", \n"); mfprintf(a," RowBox[{\"(\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"(\", \n"); mfprintf(a," RowBox[{\"majorticksZ\", \"-\", \"1\"}], \")\"}], \"*\", \n"); mfprintf(a," RowBox[{\"(\", \n"); mfprintf(a," RowBox[{\"minorticksZ\", \"+\", \"1\"}], \")\"}]}], \")\"}]}], \"*\", \n"); mfprintf(a," RowBox[{\"(\", \n"); mfprintf(a," RowBox[{\"tickmaxZ\", \"-\", \"tickminZ\"}], \")\"}]}]}]}], \";\", \n"); mfprintf(a," RowBox[{\"{\", \n"); mfprintf(a," RowBox[{\"i2\", \",\", \n"); mfprintf(a," RowBox[{\"If\", \"[\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"Mod\", \"[\", \n"); mfprintf(a," RowBox[{\"i\", \",\", \n"); mfprintf(a," RowBox[{\"minorticksZ\", \"+\", \"1\"}]}], \"]\"}], \"\\[Equal]\", \n"); mfprintf(a," \"0\"}], \",\", \n"); mfprintf(a," RowBox[{\"ticklabelprefixZ\", \"<>\", \n"); mfprintf(a," RowBox[{\"ToString\", \"[\", \n"); mfprintf(a," RowBox[{\"If\", \"[\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"tickprecZ\", \"\\[Equal]\", \"0\"}], \",\", \n"); mfprintf(a," RowBox[{\"Round\", \"[\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"i2\", \"^\", \n"); mfprintf(a," RowBox[{\"(\", \n"); mfprintf(a," RowBox[{\"1\", \"/\", \"exp\"}], \")\"}]}], \",\", \"1\"}], \"]\"}], \n"); mfprintf(a," \",\", \n"); mfprintf(a," RowBox[{\"PaddedForm\", \"[\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"i2\", \"^\", \n"); mfprintf(a," RowBox[{\"(\", \n"); mfprintf(a," RowBox[{\"1\", \"/\", \"exp\"}], \")\"}]}], \",\", \n"); mfprintf(a," RowBox[{\"{\", \n"); mfprintf(a," RowBox[{\"20\", \",\", \"tickprecZ\"}], \"}\"}], \",\", \n"); mfprintf(a," RowBox[{\"NumberPadding\", \"\\[Rule]\", \n"); mfprintf(a," RowBox[{\"{\", \n"); mfprintf(a," RowBox[{\"\\\"\\<\\>\\\"\", \",\", \"\\\"\\<0\\>\\\"\"}], \"}\"}]}]}], \n"); mfprintf(a," \"]\"}]}], \"]\"}], \"]\"}], \"<>\", \"ticklabelsuffixZ\"}], \",\", \n"); mfprintf(a," \"\\\"\\<\\>\\\"\"}], \"]\"}], \",\", \n"); mfprintf(a," RowBox[{\"If\", \"[\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"Mod\", \"[\", \n"); mfprintf(a," RowBox[{\"i\", \",\", \n"); mfprintf(a," RowBox[{\"minorticksZ\", \"+\", \"1\"}]}], \"]\"}], \"\\[Equal]\", \n"); mfprintf(a," \"0\"}], \",\", \n"); mfprintf(a," RowBox[{\"{\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"majorticklength\", \"*\", \n"); mfprintf(a," RowBox[{\"(\", \n"); mfprintf(a," RowBox[{\"1\", \"-\", \"majortickshift\"}], \")\"}]}], \",\", \n"); mfprintf(a," RowBox[{\"majorticklength\", \"*\", \"majortickshift\"}]}], \"}\"}], \n"); mfprintf(a," \",\", \n"); mfprintf(a," RowBox[{\"{\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"minorticklength\", \"*\", \n"); mfprintf(a," RowBox[{\"(\", \n"); mfprintf(a," RowBox[{\"1\", \"-\", \"minortickshift\"}], \")\"}]}], \",\", \n"); mfprintf(a," RowBox[{\"minorticklength\", \"*\", \"minortickshift\"}]}], \"}\"}]}],\n"); mfprintf(a," \"]\"}]}], \"}\"}]}], \",\", \n"); mfprintf(a," RowBox[{\"{\", \n"); mfprintf(a," RowBox[{\"i\", \",\", \"0\", \",\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"(\", \n"); mfprintf(a," RowBox[{\"majorticksZ\", \"-\", \"1\"}], \")\"}], \"*\", \n"); mfprintf(a," RowBox[{\"(\", \n"); mfprintf(a," RowBox[{\"minorticksZ\", \"+\", \"1\"}], \")\"}]}]}], \"}\"}]}], \"]\"}]}], \n"); mfprintf(a," \";\", \"\\[IndentingNewLine]\", \"\\[IndentingNewLine]\", \n"); mfprintf(a," RowBox[{\"tfznolabel\", \":=\", \n"); mfprintf(a," RowBox[{\"Table\", \"[\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"i2\", \"=\", \n"); mfprintf(a," RowBox[{\"tickminZ\", \"+\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"i\", \"/\", \n"); mfprintf(a," RowBox[{\"(\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"(\", \n"); mfprintf(a," RowBox[{\"majorticksZ\", \"-\", \"1\"}], \")\"}], \"*\", \n"); mfprintf(a," RowBox[{\"(\", \n"); mfprintf(a," RowBox[{\"minorticksZ\", \"+\", \"1\"}], \")\"}]}], \")\"}]}], \"*\", \n"); mfprintf(a," RowBox[{\"(\", \n"); mfprintf(a," RowBox[{\"tickmaxZ\", \"-\", \"tickminZ\"}], \")\"}]}]}]}], \";\", \n"); mfprintf(a," RowBox[{\"{\", \n"); mfprintf(a," RowBox[{\"i2\", \",\", \"\\\"\\<\\>\\\"\", \",\", \n"); mfprintf(a," RowBox[{\"If\", \"[\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"Mod\", \"[\", \n"); mfprintf(a," RowBox[{\"i\", \",\", \n"); mfprintf(a," RowBox[{\"minorticksZ\", \"+\", \"1\"}]}], \"]\"}], \"\\[Equal]\", \n"); mfprintf(a," \"0\"}], \",\", \n"); mfprintf(a," RowBox[{\"{\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"majorticklength\", \"*\", \n"); mfprintf(a," RowBox[{\"(\", \n"); mfprintf(a," RowBox[{\"1\", \"-\", \"majortickshift\"}], \")\"}]}], \",\", \n"); mfprintf(a," RowBox[{\"majorticklength\", \"*\", \"majortickshift\"}]}], \"}\"}], \n"); mfprintf(a," \",\", \n"); mfprintf(a," RowBox[{\"{\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"minorticklength\", \"*\", \n"); mfprintf(a," RowBox[{\"(\", \n"); mfprintf(a," RowBox[{\"1\", \"-\", \"minortickshift\"}], \")\"}]}], \",\", \n"); mfprintf(a," RowBox[{\"minorticklength\", \"*\", \"minortickshift\"}]}], \"}\"}]}],\n"); mfprintf(a," \"]\"}]}], \"}\"}]}], \",\", \n"); mfprintf(a," RowBox[{\"{\", \n"); mfprintf(a," RowBox[{\"i\", \",\", \"0\", \",\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"(\", \n"); mfprintf(a," RowBox[{\"majorticksZ\", \"-\", \"1\"}], \")\"}], \"*\", \n"); mfprintf(a," RowBox[{\"(\", \n"); mfprintf(a," RowBox[{\"minorticksZ\", \"+\", \"1\"}], \")\"}]}]}], \"}\"}]}], \"]\"}]}], \n"); mfprintf(a," \";\", \"\\[IndentingNewLine]\", \"\\[IndentingNewLine]\", \n"); mfprintf(a," RowBox[{\"tfl\", \":=\", \n"); mfprintf(a," RowBox[{\"Table\", \"[\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"i2\", \"=\", \n"); mfprintf(a," RowBox[{\"tickminL\", \"+\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"i\", \"/\", \n"); mfprintf(a," RowBox[{\"(\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"(\", \n"); mfprintf(a," RowBox[{\"majorticksL\", \"-\", \"1\"}], \")\"}], \"*\", \n"); mfprintf(a," RowBox[{\"(\", \n"); mfprintf(a," RowBox[{\"minorticksL\", \"+\", \"1\"}], \")\"}]}], \")\"}]}], \"*\", \n"); mfprintf(a," RowBox[{\"(\", \n"); mfprintf(a," RowBox[{\"tickmaxL\", \"-\", \"tickminL\"}], \")\"}]}]}]}], \";\", \n"); mfprintf(a," RowBox[{\"{\", \n"); mfprintf(a," RowBox[{\"i2\", \",\", \n"); mfprintf(a," RowBox[{\"If\", \"[\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"Mod\", \"[\", \n"); mfprintf(a," RowBox[{\"i\", \",\", \n"); mfprintf(a," RowBox[{\"minorticksL\", \"+\", \"1\"}]}], \"]\"}], \"\\[Equal]\", \n"); mfprintf(a," \"0\"}], \",\", \n"); mfprintf(a," RowBox[{\"ToString\", \"[\", \n"); mfprintf(a," RowBox[{\"If\", \"[\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"tickprecL\", \"\\[Equal]\", \"0\"}], \",\", \n"); mfprintf(a," RowBox[{\"Round\", \"[\", \n"); mfprintf(a," RowBox[{\"i2\", \",\", \"1\"}], \"]\"}], \",\", \n"); mfprintf(a," RowBox[{\"PaddedForm\", \"[\", \n"); mfprintf(a," RowBox[{\"i2\", \",\", \n"); mfprintf(a," RowBox[{\"{\", \n"); mfprintf(a," RowBox[{\"20\", \",\", \"tickprecL\"}], \"}\"}], \",\", \n"); mfprintf(a," RowBox[{\"NumberPadding\", \"\\[Rule]\", \n"); mfprintf(a," RowBox[{\"{\", \n"); mfprintf(a," RowBox[{\"\\\"\\<\\>\\\"\", \",\", \"\\\"\\<0\\>\\\"\"}], \"}\"}]}]}], \n"); mfprintf(a," \"]\"}]}], \"]\"}], \"]\"}], \",\", \"\\\"\\<\\>\\\"\"}], \"]\"}], \",\", \n"); mfprintf(a," RowBox[{\"If\", \"[\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"Mod\", \"[\", \n"); mfprintf(a," RowBox[{\"i\", \",\", \n"); mfprintf(a," RowBox[{\"minorticksL\", \"+\", \"1\"}]}], \"]\"}], \"\\[Equal]\", \n"); mfprintf(a," \"0\"}], \",\", \n"); mfprintf(a," RowBox[{\"{\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"majorticklengthL\", \"*\", \n"); mfprintf(a," RowBox[{\"(\", \n"); mfprintf(a," RowBox[{\"1\", \"-\", \"majortickshiftL\"}], \")\"}]}], \",\", \n"); mfprintf(a," RowBox[{\"majorticklengthL\", \"*\", \"majortickshiftL\"}]}], \"}\"}],\n"); mfprintf(a," \",\", \n"); mfprintf(a," RowBox[{\"{\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"minorticklengthL\", \"*\", \n"); mfprintf(a," RowBox[{\"(\", \n"); mfprintf(a," RowBox[{\"1\", \"-\", \"minortickshiftL\"}], \")\"}]}], \",\", \n"); mfprintf(a," RowBox[{\"minorticklengthL\", \"*\", \"minortickshiftL\"}]}], \n"); mfprintf(a," \"}\"}]}], \"]\"}]}], \"}\"}]}], \",\", \n"); mfprintf(a," RowBox[{\"{\", \n"); mfprintf(a," RowBox[{\"i\", \",\", \"0\", \",\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"(\", \n"); mfprintf(a," RowBox[{\"majorticksL\", \"-\", \"1\"}], \")\"}], \"*\", \n"); mfprintf(a," RowBox[{\"(\", \n"); mfprintf(a," RowBox[{\"minorticksL\", \"+\", \"1\"}], \")\"}]}]}], \"}\"}]}], \"]\"}]}], \n"); mfprintf(a," \";\", \"\\[IndentingNewLine]\", \"\\[IndentingNewLine]\", \n"); mfprintf(a," RowBox[{\"tflnolabel\", \":=\", \n"); mfprintf(a," RowBox[{\"Table\", \"[\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"i2\", \"=\", \n"); mfprintf(a," RowBox[{\"tickminL\", \"+\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"i\", \"/\", \n"); mfprintf(a," RowBox[{\"(\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"(\", \n"); mfprintf(a," RowBox[{\"majorticksL\", \"-\", \"1\"}], \")\"}], \"*\", \n"); mfprintf(a," RowBox[{\"(\", \n"); mfprintf(a," RowBox[{\"minorticksL\", \"+\", \"1\"}], \")\"}]}], \")\"}]}], \"*\", \n"); mfprintf(a," RowBox[{\"(\", \n"); mfprintf(a," RowBox[{\"tickmaxL\", \"-\", \"tickminL\"}], \")\"}]}]}]}], \";\", \n"); mfprintf(a," RowBox[{\"{\", \n"); mfprintf(a," RowBox[{\"i2\", \",\", \"\\\"\\<\\>\\\"\", \",\", \n"); mfprintf(a," RowBox[{\"If\", \"[\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"Mod\", \"[\", \n"); mfprintf(a," RowBox[{\"i\", \",\", \n"); mfprintf(a," RowBox[{\"minorticksL\", \"+\", \"1\"}]}], \"]\"}], \"\\[Equal]\", \n"); mfprintf(a," \"0\"}], \",\", \n"); mfprintf(a," RowBox[{\"{\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"majorticklengthL\", \"*\", \n"); mfprintf(a," RowBox[{\"(\", \n"); mfprintf(a," RowBox[{\"1\", \"-\", \"majortickshiftL\"}], \")\"}]}], \",\", \n"); mfprintf(a," RowBox[{\"majorticklengthL\", \"*\", \"majortickshiftL\"}]}], \"}\"}],\n"); mfprintf(a," \",\", \n"); mfprintf(a," RowBox[{\"{\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"minorticklengthL\", \"*\", \n"); mfprintf(a," RowBox[{\"(\", \n"); mfprintf(a," RowBox[{\"1\", \"-\", \"minortickshiftL\"}], \")\"}]}], \",\", \n"); mfprintf(a," RowBox[{\"minorticklengthL\", \"*\", \"minortickshiftL\"}]}], \n"); mfprintf(a," \"}\"}]}], \"]\"}]}], \"}\"}]}], \",\", \n"); mfprintf(a," RowBox[{\"{\", \n"); mfprintf(a," RowBox[{\"i\", \",\", \"0\", \",\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"(\", \n"); mfprintf(a," RowBox[{\"majorticksL\", \"-\", \"1\"}], \")\"}], \"*\", \n"); mfprintf(a," RowBox[{\"(\", \n"); mfprintf(a," RowBox[{\"minorticksL\", \"+\", \"1\"}], \")\"}]}]}], \"}\"}]}], \"]\"}]}], \n"); mfprintf(a," \";\", \"\\[IndentingNewLine]\", \"\\[IndentingNewLine]\", \n"); mfprintf(a," RowBox[{\"(*\", \" \", \n"); mfprintf(a," RowBox[{\"Create\", \" \", \"Contour\", \" \", \"Plot\"}], \" \", \"*)\"}], \n"); mfprintf(a," \"\\[IndentingNewLine]\", \n"); mfprintf(a," RowBox[{\"datmin\", \"=\", \n"); mfprintf(a," RowBox[{\"If\", \"[\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"ValueQ\", \"[\", \"mincolorvalue\", \"]\"}], \",\", \n"); mfprintf(a," \"mincolorvalue\", \",\", \n"); mfprintf(a," RowBox[{\"Min\", \"[\", \n"); mfprintf(a," RowBox[{\"Table\", \"[\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"dat\", \"[\", \n"); mfprintf(a," RowBox[{\"[\", \"i\", \"]\"}], \"]\"}], \"[\", \n"); mfprintf(a," RowBox[{\"[\", \"3\", \"]\"}], \"]\"}], \",\", \n"); mfprintf(a," RowBox[{\"{\", \n"); mfprintf(a," RowBox[{\"i\", \",\", \"1\", \",\", \n"); mfprintf(a," RowBox[{\"plotresX\", \"*\", \"plotresY\"}]}], \"}\"}]}], \"]\"}], \n"); mfprintf(a," \"]\"}]}], \"]\"}]}], \";\", \"\\[IndentingNewLine]\", \n"); mfprintf(a," RowBox[{\"datminexp\", \"=\", \n"); mfprintf(a," RowBox[{\"If\", \"[\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"ValueQ\", \"[\", \"mincolorvalue\", \"]\"}], \",\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"Sign\", \"[\", \"mincolorvalue\", \"]\"}], \"*\", \n"); mfprintf(a," RowBox[{\"Abs\", \"[\", \n"); mfprintf(a," RowBox[{\"mincolorvalue\", \"^\", \"exp\"}], \"]\"}]}], \",\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"Sign\", \"[\", \"datmin\", \"]\"}], \"*\", \n"); mfprintf(a," RowBox[{\"Abs\", \"[\", \n"); mfprintf(a," RowBox[{\"datmin\", \"^\", \"exp\"}], \"]\"}]}]}], \"]\"}]}], \";\", \n"); mfprintf(a," \"\\[IndentingNewLine]\", \n"); mfprintf(a," RowBox[{\"datmax\", \"=\", \n"); mfprintf(a," RowBox[{\"If\", \"[\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"ValueQ\", \"[\", \"maxcolorvalue\", \"]\"}], \",\", \n"); mfprintf(a," \"maxcolorvalue\", \",\", \n"); mfprintf(a," RowBox[{\"Max\", \"[\", \n"); mfprintf(a," RowBox[{\"Table\", \"[\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"dat\", \"[\", \n"); mfprintf(a," RowBox[{\"[\", \"i\", \"]\"}], \"]\"}], \"[\", \n"); mfprintf(a," RowBox[{\"[\", \"3\", \"]\"}], \"]\"}], \",\", \n"); mfprintf(a," RowBox[{\"{\", \n"); mfprintf(a," RowBox[{\"i\", \",\", \"1\", \",\", \n"); mfprintf(a," RowBox[{\"plotresX\", \"*\", \"plotresY\"}]}], \"}\"}]}], \"]\"}], \n"); mfprintf(a," \"]\"}]}], \"]\"}]}], \";\", \"\\[IndentingNewLine]\", \n"); mfprintf(a," RowBox[{\"datmaxexp\", \"=\",\n"); mfprintf(a," RowBox[{\"If\", \"[\",\n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"ValueQ\", \"[\", \"maxcolorvalue\", \"]\"}], \",\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"Sign\", \"[\", \"maxcolorvalue\", \"]\"}], \"*\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"Abs\", \"[\", \"maxcolorvalue\", \"]\"}], \"^\", \"exp\"}]}], \",\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"Sign\", \"[\", \"datmax\", \"]\"}], \"*\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"Abs\", \"[\", \"datmax\", \"]\"}], \"^\", \"exp\"}]}]}], \"]\"}]}], \n"); mfprintf(a," \";\", \"\\[IndentingNewLine]\", \"\\[IndentingNewLine]\", \n"); mfprintf(a," RowBox[{\"If\", \"[\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"coloring\", \"\\[Equal]\", \"4\"}], \",\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"If\", \"[\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"Abs\", \"[\", \"datmin\", \"]\"}], \">\", \n"); mfprintf(a," RowBox[{\"Abs\", \"[\", \"datmax\", \"]\"}]}], \",\", \n"); mfprintf(a," RowBox[{\"datmax\", \"=\", \n"); mfprintf(a," RowBox[{\"Abs\", \"[\", \"datmin\", \"]\"}]}], \",\", \n"); mfprintf(a," RowBox[{\"datmin\", \"=\", \n"); mfprintf(a," RowBox[{\"-\", \n"); mfprintf(a," RowBox[{\"Abs\", \"[\", \"datmax\", \"]\"}]}]}]}], \"]\"}], \";\", \n"); mfprintf(a," RowBox[{\"If\", \"[\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"Abs\", \"[\", \"datminexp\", \"]\"}], \">\", \n"); mfprintf(a," RowBox[{\"Abs\", \"[\", \"datmaxexp\", \"]\"}]}], \",\", \n"); mfprintf(a," RowBox[{\"datmaxexp\", \"=\", \n"); mfprintf(a," RowBox[{\"Abs\", \"[\", \"datminexp\", \"]\"}]}], \",\", \n"); mfprintf(a," RowBox[{\"datminexp\", \"=\", \n"); mfprintf(a," RowBox[{\"-\", \n"); mfprintf(a," RowBox[{\"Abs\", \"[\", \"datmaxexp\", \"]\"}]}]}]}], \"]\"}]}], \",\"}], \n"); mfprintf(a," \"]\"}], \";\", \"\\[IndentingNewLine]\", \"\\[IndentingNewLine]\",\n"); mfprintf(a," RowBox[{\"If\", \"[\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"plottype\", \"\\[Equal]\", \"1\"}], \",\", \"\\[IndentingNewLine]\", \n"); mfprintf(a," RowBox[{\"Show\", \"[\", \"\\[IndentingNewLine]\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"ListContourPlot\", \"[\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"Table\", \"[\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"{\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"dat\", \"[\", \n"); mfprintf(a," RowBox[{\"[\", \"i\", \"]\"}], \"]\"}], \"[\", \n"); mfprintf(a," RowBox[{\"[\", \"1\", \"]\"}], \"]\"}], \",\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"dat\", \"[\", \n"); mfprintf(a," RowBox[{\"[\", \"i\", \"]\"}], \"]\"}], \"[\", \n"); mfprintf(a," RowBox[{\"[\", \"2\", \"]\"}], \"]\"}], \",\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"Sign\", \"[\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"dat\", \"[\", \n"); mfprintf(a," RowBox[{\"[\", \"i\", \"]\"}], \"]\"}], \"[\", \n"); mfprintf(a," RowBox[{\"[\", \"3\", \"]\"}], \"]\"}], \"]\"}], \"*\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"Abs\", \"[\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"dat\", \"[\", \n"); mfprintf(a," RowBox[{\"[\", \"i\", \"]\"}], \"]\"}], \"[\", \n"); mfprintf(a," RowBox[{\"[\", \"3\", \"]\"}], \"]\"}], \"]\"}], \"^\", \"exp\"}]}]}], \n"); mfprintf(a," \"}\"}], \",\", \n"); mfprintf(a," RowBox[{\"{\", \n"); mfprintf(a," RowBox[{\"i\", \",\", \"1\", \",\", \n"); mfprintf(a," RowBox[{\"plotresX\", \"*\", \"plotresY\"}]}], \"}\"}]}], \"]\"}], \",\", \n"); mfprintf(a," RowBox[{\"{\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"PlotRange\", \"\\[Rule]\", \n"); mfprintf(a," RowBox[{\"{\", \n"); mfprintf(a," RowBox[{\"datminexp\", \",\", \"datmaxexp\"}], \"}\"}]}], \",\", \n"); mfprintf(a," RowBox[{\"ColorFunction\", \"\\[Rule]\", \n"); mfprintf(a," RowBox[{\"Function\", \"[\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"{\", \"z\", \"}\"}], \",\", \n"); mfprintf(a," RowBox[{\"ColFunc\", \"[\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"(\", \n"); mfprintf(a," RowBox[{\"z\", \"+\", \n"); mfprintf(a," RowBox[{\"If\", \"[\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"ValueQ\", \"[\", \"mincolorvalue\", \"]\"}], \",\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"-\", \n"); mfprintf(a," RowBox[{\"Sign\", \"[\", \"mincolorvalue\", \"]\"}]}], \"*\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"Abs\", \"[\", \"mincolorvalue\", \"]\"}], \"^\", \n"); mfprintf(a," \"exp\"}]}], \",\", \n"); mfprintf(a," RowBox[{\"-\", \"datminexp\"}]}], \"]\"}]}], \")\"}], \"/\", \n"); mfprintf(a," RowBox[{\"(\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"If\", \"[\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"ValueQ\", \"[\", \"maxcolorvalue\", \"]\"}], \",\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"Sign\", \"[\", \"maxcolorvalue\", \"]\"}], \"*\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"Abs\", \"[\", \"maxcolorvalue\", \"]\"}], \"^\", \n"); mfprintf(a," \"exp\"}]}], \"-\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"Sign\", \"[\", \"mincolorvalue\", \"]\"}], \"*\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"Abs\", \"[\", \"mincolorvalue\", \"]\"}], \"^\", \n"); mfprintf(a," \"exp\"}]}]}], \",\", \n"); mfprintf(a," RowBox[{\"datmaxexp\", \"-\", \"datminexp\"}]}], \"]\"}], \"/\", \n"); mfprintf(a," \"colorscale\"}], \")\"}]}], \"]\"}]}], \"]\"}]}], \",\", \n"); mfprintf(a," RowBox[{\"ColorFunctionScaling\", \"\\[Rule]\", \"False\"}], \",\", \n"); mfprintf(a," RowBox[{\"Contours\", \"\\[Rule]\", \"contours\"}], \",\", \n"); mfprintf(a," RowBox[{\"PlotRangePadding\", \"\\[Rule]\", \"framemargins\"}], \",\", \n"); mfprintf(a," RowBox[{\"FrameStyle\", \"\\[Rule]\", \n"); mfprintf(a," RowBox[{\"Directive\", \"[\", \n"); mfprintf(a," RowBox[{\"Thickness\", \"[\", \"framethickness\", \"]\"}], \"]\"}]}], \n"); mfprintf(a," \",\", \n"); mfprintf(a," RowBox[{\"FrameTicks\", \"\\[Rule]\", \n"); mfprintf(a," RowBox[{\"{\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"{\", \n"); mfprintf(a," RowBox[{\"tfy\", \",\", \n"); mfprintf(a," RowBox[{\"If\", \"[\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"ValueQ\", \"[\", \"ticksbothsidesY\", \"]\"}], \",\", \n"); mfprintf(a," RowBox[{\"If\", \"[\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"ValueQ\", \"[\", \"labelsbothsidesY\", \"]\"}], \",\", \n"); mfprintf(a," \"tfy\", \",\", \"tfynolabel\"}], \"]\"}], \",\", \"None\"}], \"]\"}]}],\n"); mfprintf(a," \"}\"}], \",\", \n"); mfprintf(a," RowBox[{\"{\", \n"); mfprintf(a," RowBox[{\"tfx\", \",\", \n"); mfprintf(a," RowBox[{\"If\", \"[\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"ValueQ\", \"[\", \"ticksbothsidesX\", \"]\"}], \",\", \n"); mfprintf(a," RowBox[{\"If\", \"[\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"ValueQ\", \"[\", \"labelsbothsidesX\", \"]\"}], \",\", \n"); mfprintf(a," \"tfx\", \",\", \"tfxnolabel\"}], \"]\"}], \",\", \"None\"}], \"]\"}]}],\n"); mfprintf(a," \"}\"}]}], \"}\"}]}], \",\", \n"); mfprintf(a," RowBox[{\"FrameLabel\", \"\\[Rule]\", \n"); mfprintf(a," RowBox[{\"{\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"Style\", \"[\", \n"); mfprintf(a," RowBox[{\"xlabel\", \",\", \n"); mfprintf(a," RowBox[{\"FontSize\", \"\\[Rule]\", \n"); mfprintf(a," RowBox[{\"labelsize\", \"*\", \n"); mfprintf(a," RowBox[{\"plotpixels\", \"/\", \"800\"}]}]}]}], \"]\"}], \",\", \n"); mfprintf(a," RowBox[{\"Style\", \"[\", \n"); mfprintf(a," RowBox[{\"ylabel\", \",\", \n"); mfprintf(a," RowBox[{\"FontSize\", \"\\[Rule]\", \n"); mfprintf(a," RowBox[{\"labelsize\", \"*\", \n"); mfprintf(a," RowBox[{\"plotpixels\", \"/\", \"800\"}]}]}]}], \"]\"}], \",\", \n"); mfprintf(a," \"\\\"\\<\\>\\\"\"}], \"}\"}]}], \",\", \n"); mfprintf(a," RowBox[{\"ContourLabels\", \"\\[Rule]\", \n"); mfprintf(a," RowBox[{\"If\", \"[\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"ValueQ\", \"[\", \"usecontourlabels\", \"]\"}], \",\", \n"); mfprintf(a," RowBox[{\"(\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"Text\", \"[\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"Style\", \"[\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"#3\", \"^\", \n"); mfprintf(a," RowBox[{\"(\", \n"); mfprintf(a," RowBox[{\"1\", \"/\", \"exp\"}], \")\"}]}], \",\", \n"); mfprintf(a," RowBox[{\"FontFamily\", \"\\[Rule]\", \"\\\"\\\\\"\"}], \",\", \n"); mfprintf(a," RowBox[{\"FontSize\", \"\\[Rule]\", \n"); mfprintf(a," RowBox[{\"contourlabelsize\", \"*\", \n"); mfprintf(a," RowBox[{\"plotpixels\", \"/\", \"800\"}]}]}]}], \"]\"}], \",\", \n"); mfprintf(a," RowBox[{\"{\", \n"); mfprintf(a," RowBox[{\"#1\", \",\", \"#2\"}], \"}\"}]}], \"]\"}], \"&\"}], \")\"}], \n"); mfprintf(a," \",\", \"None\"}], \"]\"}]}], \",\", \n"); mfprintf(a," RowBox[{\"InterpolationOrder\", \"\\[Rule]\", \"interpolationorder\"}],\n"); mfprintf(a," \",\", \n"); mfprintf(a," RowBox[{\"ContourStyle\", \"\\[Rule]\", \n"); mfprintf(a," RowBox[{\"Directive\", \"[\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"Thickness\", \"[\", \"contourthickness\", \"]\"}], \",\", \n"); mfprintf(a," \"contourcolor\", \",\", \n"); mfprintf(a," RowBox[{\"Opacity\", \"[\", \"contouropacity\", \"]\"}], \",\", \n"); mfprintf(a," RowBox[{\"Dashing\", \"[\", \"contourdash\", \"]\"}]}], \"]\"}]}], \",\", \n"); mfprintf(a," RowBox[{\"LabelStyle\", \"\\[Rule]\", \n"); /*********************************************/ mfprintf(a," RowBox[{\"{\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"FontFamily\", \"\\[Rule]\", \"\\\"\\\\\"\"}], \",\", \n"); mfprintf(a," RowBox[{\"FontSize\", \"\\[Rule]\", \n"); mfprintf(a," RowBox[{\"ticklabelsize\", \"*\", \n"); mfprintf(a," RowBox[{\"plotpixels\", \"/\", \"800\"}]}]}]}], \"}\"}]}], \",\", \n"); mfprintf(a," RowBox[{\"AspectRatio\", \"\\[Rule]\", \"aspectratio\"}], \",\", \n"); mfprintf(a," RowBox[{\"ImageSize\", \"\\[Rule]\", \"plotpixels\"}], \",\", \n"); mfprintf(a," RowBox[{\"If\", \"[\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"drawmesh\", \"\\[Equal]\", \"1\"}], \",\", \n"); mfprintf(a," RowBox[{\"{\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"Mesh\", \"\\[Rule]\", \n"); mfprintf(a," RowBox[{\"{\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"majorticksX\", \"-\", \"2\", \"+\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"(\", \n"); mfprintf(a," RowBox[{\"majorticksX\", \"-\", \"1\"}], \")\"}], \"*\", \n"); mfprintf(a," \"minorticksX\"}]}], \",\", \n"); mfprintf(a," RowBox[{\"majorticksY\", \"-\", \"2\", \"+\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"(\", \n"); mfprintf(a," RowBox[{\"majorticksY\", \"-\", \"1\"}], \")\"}], \"*\", \n"); mfprintf(a," \"minorticksY\"}]}]}], \"}\"}]}], \",\", \n"); mfprintf(a," RowBox[{\"MeshFunctions\", \"\\[Rule]\", \n"); mfprintf(a," RowBox[{\"{\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"#1\", \"&\"}], \",\", \n"); mfprintf(a," RowBox[{\"#2\", \"&\"}]}], \"}\"}]}], \",\", \n"); mfprintf(a," RowBox[{\"MeshStyle\", \"\\[Rule]\", \n"); mfprintf(a," RowBox[{\"{\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"Directive\", \"[\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"Thickness\", \"[\", \"meshthicknessX\", \"]\"}], \",\", \n"); mfprintf(a," RowBox[{\"Opacity\", \"[\", \"meshopacityX\", \"]\"}], \",\", \n"); mfprintf(a," \"meshcolorX\"}], \"]\"}], \",\", \n"); mfprintf(a," RowBox[{\"Directive\", \"[\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"Thickness\", \"[\", \"meshthicknessY\", \"]\"}], \",\", \n"); mfprintf(a," RowBox[{\"Opacity\", \"[\", \"meshopacityY\", \"]\"}], \",\", \n"); mfprintf(a," \"meshcolorY\"}], \"]\"}]}], \"}\"}]}]}], \"}\"}], \",\", \n"); mfprintf(a," RowBox[{\"Mesh\", \"\\[Rule]\", \"None\"}]}], \"]\"}], \",\", \n"); mfprintf(a," RowBox[{\"PerformanceGoal\", \"\\[Rule]\", \"\\\"\\\\\"\"}]}], \n"); mfprintf(a," \"}\"}]}], \"]\"}], \",\", \"\\[IndentingNewLine]\", \"prim\"}], \"]\"}], \",\",\n"); mfprintf(a," \"\\[IndentingNewLine]\", \"\\[IndentingNewLine]\", \n"); mfprintf(a," RowBox[{\"If\", \"[\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"plottype\", \"\\[Equal]\", \"2\"}], \",\", \"\\[IndentingNewLine]\", \n"); mfprintf(a," RowBox[{\"Show\", \"[\", \"\\[IndentingNewLine]\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"ListDensityPlot\", \"[\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"Table\", \"[\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"{\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"dat\", \"[\", \n"); mfprintf(a," RowBox[{\"[\", \"i\", \"]\"}], \"]\"}], \"[\", \n"); mfprintf(a," RowBox[{\"[\", \"1\", \"]\"}], \"]\"}], \",\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"dat\", \"[\", \n"); mfprintf(a," RowBox[{\"[\", \"i\", \"]\"}], \"]\"}], \"[\", \n"); mfprintf(a," RowBox[{\"[\", \"2\", \"]\"}], \"]\"}], \",\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"Sign\", \"[\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"dat\", \"[\", \n"); mfprintf(a," RowBox[{\"[\", \"i\", \"]\"}], \"]\"}], \"[\", \n"); mfprintf(a," RowBox[{\"[\", \"3\", \"]\"}], \"]\"}], \"]\"}], \"*\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"Abs\", \"[\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"dat\", \"[\", \n"); mfprintf(a," RowBox[{\"[\", \"i\", \"]\"}], \"]\"}], \"[\", \n"); mfprintf(a," RowBox[{\"[\", \"3\", \"]\"}], \"]\"}], \"]\"}], \"^\", \"exp\"}]}]}], \n"); mfprintf(a," \"}\"}], \",\", \n"); mfprintf(a," RowBox[{\"{\", \n"); mfprintf(a," RowBox[{\"i\", \",\", \"1\", \",\", \n"); mfprintf(a," RowBox[{\"plotresX\", \"*\", \"plotresY\"}]}], \"}\"}]}], \"]\"}], \n"); mfprintf(a," \",\", \n"); mfprintf(a," RowBox[{\"{\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"PlotRange\", \"\\[Rule]\", \n"); mfprintf(a," RowBox[{\"{\", \n"); mfprintf(a," RowBox[{\"datminexp\", \",\", \"datmaxexp\"}], \"}\"}]}], \",\", \n"); mfprintf(a," RowBox[{\"ColorFunction\", \"\\[Rule]\", \n"); mfprintf(a," RowBox[{\"Function\", \"[\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"{\", \"z\", \"}\"}], \",\", \n"); mfprintf(a," RowBox[{\"ColFunc\", \"[\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"(\", \n"); mfprintf(a," RowBox[{\"z\", \"+\", \n"); mfprintf(a," RowBox[{\"If\", \"[\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"ValueQ\", \"[\", \"mincolorvalue\", \"]\"}], \",\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"-\", \n"); mfprintf(a," RowBox[{\"Sign\", \"[\", \"mincolorvalue\", \"]\"}]}], \"*\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"Abs\", \"[\", \"mincolorvalue\", \"]\"}], \"^\", \n"); mfprintf(a," \"exp\"}]}], \",\", \n"); mfprintf(a," RowBox[{\"-\", \"datminexp\"}]}], \"]\"}]}], \")\"}], \"/\", \n"); mfprintf(a," RowBox[{\"(\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"If\", \"[\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"ValueQ\", \"[\", \"maxcolorvalue\", \"]\"}], \",\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"Sign\", \"[\", \"maxcolorvalue\", \"]\"}], \"*\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"Abs\", \"[\", \"maxcolorvalue\", \"]\"}], \"^\", \n"); mfprintf(a," \"exp\"}]}], \"-\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"Sign\", \"[\", \"mincolorvalue\", \"]\"}], \"*\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"Abs\", \"[\", \"mincolorvalue\", \"]\"}], \"^\", \n"); mfprintf(a," \"exp\"}]}]}], \",\", \n"); mfprintf(a," RowBox[{\"datmaxexp\", \"-\", \"datminexp\"}]}], \"]\"}], \"/\", \n"); mfprintf(a," \"colorscale\"}], \")\"}]}], \"]\"}]}], \"]\"}]}], \",\", \n"); mfprintf(a," RowBox[{\"ColorFunctionScaling\", \"\\[Rule]\", \"False\"}], \",\", \n"); mfprintf(a," RowBox[{\"PlotRangePadding\", \"\\[Rule]\", \"framemargins\"}], \",\", \n"); mfprintf(a," RowBox[{\"FrameStyle\", \"\\[Rule]\", \n"); mfprintf(a," RowBox[{\"Directive\", \"[\", \n"); mfprintf(a," RowBox[{\"Thickness\", \"[\", \"framethickness\", \"]\"}], \"]\"}]}], \n"); mfprintf(a," \",\", \n"); mfprintf(a," RowBox[{\"FrameTicks\", \"\\[Rule]\", \n"); mfprintf(a," RowBox[{\"{\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"{\", \n"); mfprintf(a," RowBox[{\"tfy\", \",\", \n"); mfprintf(a," RowBox[{\"If\", \"[\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"ValueQ\", \"[\", \"ticksbothsidesY\", \"]\"}], \",\", \n"); mfprintf(a," RowBox[{\"If\", \"[\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"ValueQ\", \"[\", \"labelsbothsidesY\", \"]\"}], \",\", \n"); mfprintf(a," \"tfy\", \",\", \"tfynolabel\"}], \"]\"}], \",\", \"None\"}], \"]\"}]}],\n"); mfprintf(a," \"}\"}], \",\", \n"); mfprintf(a," RowBox[{\"{\", \n"); mfprintf(a," RowBox[{\"tfx\", \",\", \n"); mfprintf(a," RowBox[{\"If\", \"[\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"ValueQ\", \"[\", \"ticksbothsidesX\", \"]\"}], \",\", \n"); mfprintf(a," RowBox[{\"If\", \"[\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"ValueQ\", \"[\", \"labelsbothsidesX\", \"]\"}], \",\", \n"); mfprintf(a," \"tfx\", \",\", \"tfxnolabel\"}], \"]\"}], \",\", \"None\"}], \"]\"}]}],\n"); mfprintf(a," \"}\"}]}], \"}\"}]}], \",\", \n"); mfprintf(a," RowBox[{\"FrameLabel\", \"\\[Rule]\", \n"); mfprintf(a," RowBox[{\"{\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"Style\", \"[\", \n"); mfprintf(a," RowBox[{\"xlabel\", \",\", \n"); mfprintf(a," RowBox[{\"FontSize\", \"\\[Rule]\", \n"); mfprintf(a," RowBox[{\"labelsize\", \"*\", \n"); mfprintf(a," RowBox[{\"plotpixels\", \"/\", \"800\"}]}]}]}], \"]\"}], \",\", \n"); mfprintf(a," RowBox[{\"Style\", \"[\", \n"); mfprintf(a," RowBox[{\"ylabel\", \",\", \n"); mfprintf(a," RowBox[{\"FontSize\", \"\\[Rule]\", \n"); mfprintf(a," RowBox[{\"labelsize\", \"*\", \n"); mfprintf(a," RowBox[{\"plotpixels\", \"/\", \"800\"}]}]}]}], \"]\"}], \",\", \n"); mfprintf(a," \"\\\"\\<\\>\\\"\"}], \"}\"}]}], \",\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," \"InterpolationOrder\", \"\\[Rule]\", \"interpolationorder\"}], \",\", \n"); mfprintf(a," RowBox[{\"LabelStyle\", \"\\[Rule]\", \n"); /*********************************************/ mfprintf(a," RowBox[{\"{\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"FontFamily\", \"\\[Rule]\", \"\\\"\\\\\"\"}], \",\", \n"); mfprintf(a," RowBox[{\"FontSize\", \"\\[Rule]\", \n"); mfprintf(a," RowBox[{\"ticklabelsize\", \"*\", \n"); mfprintf(a," RowBox[{\"plotpixels\", \"/\", \"800\"}]}]}]}], \"}\"}]}], \",\", \n"); mfprintf(a," RowBox[{\"AspectRatio\", \"\\[Rule]\", \"aspectratio\"}], \",\", \n"); mfprintf(a," RowBox[{\"ImageSize\", \"\\[Rule]\", \"plotpixels\"}], \",\", \n"); mfprintf(a," RowBox[{\"If\", \"[\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"drawmesh\", \"\\[Equal]\", \"1\"}], \",\", \n"); mfprintf(a," RowBox[{\"{\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"Mesh\", \"\\[Rule]\", \n"); mfprintf(a," RowBox[{\"{\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"majorticksX\", \"-\", \"2\", \"+\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"(\", \n"); mfprintf(a," RowBox[{\"majorticksX\", \"-\", \"1\"}], \")\"}], \"*\", \n"); mfprintf(a," \"minorticksX\"}]}], \",\", \n"); mfprintf(a," RowBox[{\"majorticksY\", \"-\", \"2\", \"+\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"(\", \n"); mfprintf(a," RowBox[{\"majorticksY\", \"-\", \"1\"}], \")\"}], \"*\", \n"); mfprintf(a," \"minorticksY\"}]}]}], \"}\"}]}], \",\", \n"); mfprintf(a," RowBox[{\"MeshFunctions\", \"\\[Rule]\", \n"); mfprintf(a," RowBox[{\"{\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"#1\", \"&\"}], \",\", \n"); mfprintf(a," RowBox[{\"#2\", \"&\"}]}], \"}\"}]}], \",\", \n"); mfprintf(a," RowBox[{\"MeshStyle\", \"\\[Rule]\", \n"); mfprintf(a," RowBox[{\"{\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"Directive\", \"[\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"Thickness\", \"[\", \"meshthicknessX\", \"]\"}], \",\", \n"); mfprintf(a," RowBox[{\"Opacity\", \"[\", \"meshopacityX\", \"]\"}], \",\", \n"); mfprintf(a," \"meshcolorX\"}], \"]\"}], \",\", \n"); mfprintf(a," RowBox[{\"Directive\", \"[\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"Thickness\", \"[\", \"meshthicknessY\", \"]\"}], \",\", \n"); mfprintf(a," RowBox[{\"Opacity\", \"[\", \"meshopacityY\", \"]\"}], \",\", \n"); mfprintf(a," \"meshcolorY\"}], \"]\"}]}], \"}\"}]}]}], \"}\"}], \",\", \n"); mfprintf(a," RowBox[{\"Mesh\", \"\\[Rule]\", \"None\"}]}], \"]\"}], \",\", \n"); mfprintf(a," RowBox[{\"PerformanceGoal\", \"\\[Rule]\", \"\\\"\\\\\"\"}]}], \n"); mfprintf(a," \"}\"}]}], \"]\"}], \",\", \"\\[IndentingNewLine]\", \"prim\"}], \"]\"}], \n"); mfprintf(a," \",\", \"\\[IndentingNewLine]\", \"\\[IndentingNewLine]\", \n"); mfprintf(a," RowBox[{\"If\", \"[\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"plottype\", \"\\[Equal]\", \"3\"}], \",\", \"\\[IndentingNewLine]\", \n"); mfprintf(a," RowBox[{\"ReliefPlot\", \"[\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"Table\", \"[\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"Sign\", \"[\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"dat\", \"[\", \n"); mfprintf(a," RowBox[{\"[\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"i\", \"*\", \"plotresX\"}], \"+\", \"j\"}], \"]\"}], \"]\"}], \n"); mfprintf(a," \"[\", \n"); mfprintf(a," RowBox[{\"[\", \"3\", \"]\"}], \"]\"}], \"]\"}], \"*\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"Abs\", \"[\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"dat\", \"[\", \n"); mfprintf(a," RowBox[{\"[\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"i\", \"*\", \"plotresX\"}], \"+\", \"j\"}], \"]\"}], \"]\"}], \n"); mfprintf(a," \"[\", \n"); mfprintf(a," RowBox[{\"[\", \"3\", \"]\"}], \"]\"}], \"]\"}], \"^\", \"exp\"}]}], \n"); mfprintf(a," \",\", \n"); mfprintf(a," RowBox[{\"{\", \n"); mfprintf(a," RowBox[{\"i\", \",\", \"1\", \",\", \n"); mfprintf(a," RowBox[{\"plotresY\", \"-\", \"1\"}]}], \"}\"}], \",\", \n"); mfprintf(a," RowBox[{\"{\", \n"); mfprintf(a," RowBox[{\"j\", \",\", \"1\", \",\", \n"); mfprintf(a," RowBox[{\"plotresX\", \"-\", \"1\"}]}], \"}\"}]}], \"]\"}], \",\", \n"); mfprintf(a," RowBox[{\"{\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"PlotRange\", \"\\[Rule]\", \n"); mfprintf(a," RowBox[{\"{\", \n"); mfprintf(a," RowBox[{\"datminexp\", \",\", \"datmaxexp\"}], \"}\"}]}], \",\", \n"); mfprintf(a," RowBox[{\"ColorFunction\", \"\\[Rule]\", \n"); mfprintf(a," RowBox[{\"Function\", \"[\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"{\", \"z\", \"}\"}], \",\", \n"); mfprintf(a," RowBox[{\"ColFunc\", \"[\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"(\", \n"); mfprintf(a," RowBox[{\"z\", \"+\", \n"); mfprintf(a," RowBox[{\"If\", \"[\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"ValueQ\", \"[\", \"mincolorvalue\", \"]\"}], \",\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"-\", \n"); mfprintf(a," RowBox[{\"Sign\", \"[\", \"mincolorvalue\", \"]\"}]}], \"*\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"Abs\", \"[\", \"mincolorvalue\", \"]\"}], \"^\", \n"); mfprintf(a," \"exp\"}]}], \",\", \n"); mfprintf(a," RowBox[{\"-\", \"datminexp\"}]}], \"]\"}]}], \")\"}], \"/\", \n"); mfprintf(a," RowBox[{\"(\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"If\", \"[\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"ValueQ\", \"[\", \"maxcolorvalue\", \"]\"}], \",\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"Sign\", \"[\", \"maxcolorvalue\", \"]\"}], \"*\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"Abs\", \"[\", \"maxcolorvalue\", \"]\"}], \"^\", \n"); mfprintf(a," \"exp\"}]}], \"-\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"Sign\", \"[\", \"mincolorvalue\", \"]\"}], \"*\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"Abs\", \"[\", \"mincolorvalue\", \"]\"}], \"^\", \n"); mfprintf(a," \"exp\"}]}]}], \",\", \n"); mfprintf(a," RowBox[{\"datmaxexp\", \"-\", \"datminexp\"}]}], \"]\"}], \"/\", \n"); mfprintf(a," \"colorscale\"}], \")\"}]}], \"]\"}]}], \"]\"}]}], \",\", \n"); mfprintf(a," RowBox[{\"ColorFunctionScaling\", \"\\[Rule]\", \"False\"}], \",\", \n"); mfprintf(a," RowBox[{\"PlotRangePadding\", \"\\[Rule]\", \"framemargins\"}], \",\", \n"); mfprintf(a," RowBox[{\"FrameStyle\", \"\\[Rule]\", \n"); mfprintf(a," RowBox[{\"Directive\", \"[\", \n"); mfprintf(a," RowBox[{\"Thickness\", \"[\", \"framethickness\", \"]\"}], \"]\"}]}], \n"); mfprintf(a," \",\", \n"); mfprintf(a," RowBox[{\"FrameTicks\", \"\\[Rule]\", \n"); mfprintf(a," RowBox[{\"{\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"{\", \n"); mfprintf(a," RowBox[{\"tfy\", \",\", \n"); mfprintf(a," RowBox[{\"If\", \"[\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"ValueQ\", \"[\", \"ticksbothsidesY\", \"]\"}], \",\", \n"); mfprintf(a," RowBox[{\"If\", \"[\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"ValueQ\", \"[\", \"labelsbothsidesY\", \"]\"}], \",\", \n"); mfprintf(a," \"tfy\", \",\", \"tfynolabel\"}], \"]\"}], \",\", \"None\"}], \"]\"}]}],\n"); mfprintf(a," \"}\"}], \",\", \n"); mfprintf(a," RowBox[{\"{\", \n"); mfprintf(a," RowBox[{\"tfx\", \",\", \n"); mfprintf(a," RowBox[{\"If\", \"[\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"ValueQ\", \"[\", \"ticksbothsidesX\", \"]\"}], \",\", \n"); mfprintf(a," RowBox[{\"If\", \"[\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"ValueQ\", \"[\", \"labelsbothsidesX\", \"]\"}], \",\", \n"); mfprintf(a," \"tfx\", \",\", \"tfxnolabel\"}], \"]\"}], \",\", \"None\"}], \"]\"}]}],\n"); mfprintf(a," \"}\"}]}], \"}\"}]}], \",\", \n"); mfprintf(a," RowBox[{\"FrameLabel\", \"\\[Rule]\", \n"); mfprintf(a," RowBox[{\"{\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"Style\", \"[\", \n"); mfprintf(a," RowBox[{\"xlabel\", \",\", \n"); mfprintf(a," RowBox[{\"FontSize\", \"\\[Rule]\", \n"); mfprintf(a," RowBox[{\"labelsize\", \"*\", \n"); mfprintf(a," RowBox[{\"plotpixels\", \"/\", \"800\"}]}]}]}], \"]\"}], \",\", \n"); mfprintf(a," RowBox[{\"Style\", \"[\", \n"); mfprintf(a," RowBox[{\"ylabel\", \",\", \n"); mfprintf(a," RowBox[{\"FontSize\", \"\\[Rule]\", \n"); mfprintf(a," RowBox[{\"labelsize\", \"*\", \n"); mfprintf(a," RowBox[{\"plotpixels\", \"/\", \"800\"}]}]}]}], \"]\"}], \",\", \n"); mfprintf(a," \"\\\"\\<\\>\\\"\"}], \"}\"}]}], \",\", \n"); mfprintf(a," RowBox[{\"AspectRatio\", \"\\[Rule]\", \"aspectratio\"}], \",\", \n"); mfprintf(a," RowBox[{\"ImageSize\", \"\\[Rule]\", \"plotpixels\"}], \",\", \n"); mfprintf(a," RowBox[{\"DataRange\", \"\\[Rule]\", \n"); mfprintf(a," RowBox[{\"{\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"{\", \n"); mfprintf(a," RowBox[{\"plotrangeX1\", \",\", \"plotrangeX2\"}], \"}\"}], \",\", \n"); mfprintf(a," RowBox[{\"{\", \n"); mfprintf(a," RowBox[{\"plotrangeY1\", \",\", \"plotrangeY2\"}], \"}\"}]}], \n"); mfprintf(a," \"}\"}]}], \",\", \n"); mfprintf(a," RowBox[{\"LabelStyle\", \"\\[Rule]\", \n"); mfprintf(a," RowBox[{\"{\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"FontFamily\", \"\\[Rule]\", \"\\\"\\\\\"\"}], \",\", \n"); mfprintf(a," RowBox[{\"FontSize\", \"\\[Rule]\", \n"); mfprintf(a," RowBox[{\"ticklabelsize\", \"*\", \n"); mfprintf(a," RowBox[{\"plotpixels\", \"/\", \"800\"}]}]}]}], \"}\"}]}]}], \n"); mfprintf(a," \"}\"}]}], \"]\"}], \",\", \"\\[IndentingNewLine]\", \n"); mfprintf(a," \"\\[IndentingNewLine]\", \n"); mfprintf(a," RowBox[{\"If\", \"[\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"plottype\", \"\\[Equal]\", \"4\"}], \",\", \n"); mfprintf(a," \"\\[IndentingNewLine]\", \n"); mfprintf(a," RowBox[{\"ListPlot3D\", \"[\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"Table\", \"[\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"{\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"dat\", \"[\", \n"); mfprintf(a," RowBox[{\"[\", \"i\", \"]\"}], \"]\"}], \"[\", \n"); mfprintf(a," RowBox[{\"[\", \"1\", \"]\"}], \"]\"}], \",\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"dat\", \"[\", \n"); mfprintf(a," RowBox[{\"[\", \"i\", \"]\"}], \"]\"}], \"[\", \n"); mfprintf(a," RowBox[{\"[\", \"2\", \"]\"}], \"]\"}], \",\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"Sign\", \"[\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"dat\", \"[\", \n"); mfprintf(a," RowBox[{\"[\", \"i\", \"]\"}], \"]\"}], \"[\", \n"); mfprintf(a," RowBox[{\"[\", \"3\", \"]\"}], \"]\"}], \"]\"}], \"*\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"Abs\", \"[\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"dat\", \"[\", \n"); mfprintf(a," RowBox[{\"[\", \"i\", \"]\"}], \"]\"}], \"[\", \n"); mfprintf(a," RowBox[{\"[\", \"3\", \"]\"}], \"]\"}], \"]\"}], \"^\", \"exp\"}]}]}], \n"); mfprintf(a," \"}\"}], \",\", \n"); mfprintf(a," RowBox[{\"{\", \n"); mfprintf(a," RowBox[{\"i\", \",\", \"1\", \",\", \n"); mfprintf(a," RowBox[{\"plotresX\", \"*\", \"plotresY\"}]}], \"}\"}]}], \"]\"}], \n"); mfprintf(a," \",\", \n"); mfprintf(a," RowBox[{\"{\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"PlotRange\", \"\\[Rule]\", \n"); mfprintf(a," RowBox[{\"{\", \n"); mfprintf(a," RowBox[{\"datminexp\", \",\", \"datmaxexp\"}], \"}\"}]}], \",\", \n"); mfprintf(a," RowBox[{\"ColorFunction\", \"\\[Rule]\", \n"); mfprintf(a," RowBox[{\"Function\", \"[\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"{\", \n"); mfprintf(a," RowBox[{\"x\", \",\", \"y\", \",\", \"z\"}], \"}\"}], \",\", \n"); mfprintf(a," RowBox[{\"ColFunc\", \"[\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"(\", \n"); mfprintf(a," RowBox[{\"z\", \"+\", \n"); mfprintf(a," RowBox[{\"If\", \"[\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"ValueQ\", \"[\", \"mincolorvalue\", \"]\"}], \",\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"-\", \n"); mfprintf(a," RowBox[{\"Sign\", \"[\", \"mincolorvalue\", \"]\"}]}], \"*\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"Abs\", \"[\", \"mincolorvalue\", \"]\"}], \"^\", \n"); mfprintf(a," \"exp\"}]}], \",\", \n"); mfprintf(a," RowBox[{\"-\", \"datminexp\"}]}], \"]\"}]}], \")\"}], \"/\", \n"); mfprintf(a," RowBox[{\"(\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"If\", \"[\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"ValueQ\", \"[\", \"maxcolorvalue\", \"]\"}], \",\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"Sign\", \"[\", \"maxcolorvalue\", \"]\"}], \"*\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"Abs\", \"[\", \"maxcolorvalue\", \"]\"}], \"^\", \n"); mfprintf(a," \"exp\"}]}], \"-\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"Sign\", \"[\", \"mincolorvalue\", \"]\"}], \"*\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"Abs\", \"[\", \"mincolorvalue\", \"]\"}], \"^\", \n"); mfprintf(a," \"exp\"}]}]}], \",\", \n"); mfprintf(a," RowBox[{\"datmaxexp\", \"-\", \"datminexp\"}]}], \"]\"}], \"/\", \n"); mfprintf(a," \"colorscale\"}], \")\"}]}], \"]\"}]}], \"]\"}]}], \",\", \n"); mfprintf(a," RowBox[{\"ColorFunctionScaling\", \"\\[Rule]\", \"False\"}], \",\", \n"); mfprintf(a," RowBox[{\"PlotRangePadding\", \"\\[Rule]\", \"framemargins\"}], \n"); mfprintf(a," \",\", \n"); mfprintf(a," RowBox[{\"InterpolationOrder\", \"\\[Rule]\", \"2\"}], \",\", \n"); mfprintf(a," RowBox[{\"AspectRatio\", \"\\[Rule]\", \"aspectratio\"}], \",\", \n"); mfprintf(a," RowBox[{\"ImageSize\", \"\\[Rule]\", \"plotpixels\"}], \",\", \n"); mfprintf(a," RowBox[{\"Mesh\", \"\\[Rule]\", \n"); mfprintf(a," RowBox[{\"{\", \n"); mfprintf(a," RowBox[{\"gridxcount\", \",\", \"gridycount\"}], \"}\"}]}], \",\", \n"); mfprintf(a," RowBox[{\"MeshStyle\", \"\\[Rule]\", \n"); mfprintf(a," RowBox[{\"{\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"Directive\", \"[\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"Thickness\", \"[\", \"gridxthickness\", \"]\"}], \",\", \n"); mfprintf(a," RowBox[{\"Opacity\", \"[\", \"gridxopacity\", \"]\"}], \",\", \n"); mfprintf(a," \"gridxcolor\"}], \"]\"}], \",\", \n"); mfprintf(a," RowBox[{\"Directive\", \"[\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"Thickness\", \"[\", \"gridythickness\", \"]\"}], \",\", \n"); mfprintf(a," RowBox[{\"Opacity\", \"[\", \"gridyopacity\", \"]\"}], \",\", \n"); mfprintf(a," \"gridycolor\"}], \"]\"}]}], \"}\"}]}], \",\", \n"); mfprintf(a," RowBox[{\"Boxed\", \"\\[Rule]\", \n"); mfprintf(a," RowBox[{\"If\", \"[\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"ValueQ\", \"[\", \"boxed\", \"]\"}], \",\", \"True\", \",\", \n"); mfprintf(a," \"False\"}], \"]\"}]}], \",\", \n"); mfprintf(a," RowBox[{\"BoxStyle\", \"\\[Rule]\", \n"); mfprintf(a," RowBox[{\"Directive\", \"[\", \n"); mfprintf(a," RowBox[{\"boxcolor\", \",\", \n"); mfprintf(a," RowBox[{\"Thickness\", \"[\", \"boxthickness\", \"]\"}], \",\", \n"); mfprintf(a," RowBox[{\"Opacity\", \"[\", \"boxopacity\", \"]\"}]}], \"]\"}]}], \n"); mfprintf(a," \",\", \n"); mfprintf(a," RowBox[{\"Ticks\", \"\\[Rule]\", \n"); mfprintf(a," RowBox[{\"{\", \n"); mfprintf(a," RowBox[{\"tfx\", \",\", \"tfy\", \",\", \n"); mfprintf(a," RowBox[{\"If\", \"[\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"ValueQ\", \"[\", \"labelsz\", \"]\"}], \",\", \"tfz\", \",\", \n"); mfprintf(a," \"tfznolabel\"}], \"]\"}]}], \"}\"}]}], \",\", \n"); mfprintf(a," RowBox[{\"TicksStyle\", \"\\[Rule]\", \n"); mfprintf(a," RowBox[{\"Directive\", \"[\", \n"); mfprintf(a," RowBox[{\"Thickness\", \"[\", \"axesthickness\", \"]\"}], \"]\"}]}],\n"); mfprintf(a," \",\", \n"); mfprintf(a," RowBox[{\"AxesStyle\", \"\\[Rule]\", \n"); mfprintf(a," RowBox[{\"Thickness\", \"[\", \"axesthickness\", \"]\"}]}], \",\", \n"); mfprintf(a," RowBox[{\"AxesEdge\", \"\\[Rule]\", \n"); mfprintf(a," RowBox[{\"{\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," \"xaxisposition\", \",\", \"yaxisposition\", \",\", \n"); mfprintf(a," \"zaxisposition\"}], \"}\"}]}], \",\", \n"); mfprintf(a," RowBox[{\"AxesLabel\", \"\\[Rule]\", \n"); mfprintf(a," RowBox[{\"{\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"Style\", \"[\", \n"); mfprintf(a," RowBox[{\"xlabel\", \",\", \n"); mfprintf(a," RowBox[{\"FontSize\", \"\\[Rule]\", \n"); mfprintf(a," RowBox[{\"labelsize\", \"*\", \n"); mfprintf(a," RowBox[{\"plotpixels\", \"/\", \"800\"}]}]}]}], \"]\"}], \",\", \n"); mfprintf(a," RowBox[{\"Style\", \"[\", \n"); mfprintf(a," RowBox[{\"ylabel\", \",\", \n"); mfprintf(a," RowBox[{\"FontSize\", \"\\[Rule]\", \n"); mfprintf(a," RowBox[{\"labelsize\", \"*\", \n"); mfprintf(a," RowBox[{\"plotpixels\", \"/\", \"800\"}]}]}]}], \"]\"}], \",\", \n"); mfprintf(a," RowBox[{\"Style\", \"[\", \n"); mfprintf(a," RowBox[{\"zlabel\", \",\", \n"); mfprintf(a," RowBox[{\"FontSize\", \"\\[Rule]\", \n"); mfprintf(a," RowBox[{\"labelsize\", \"*\", \n"); mfprintf(a," RowBox[{\"plotpixels\", \"/\", \"800\"}]}]}]}], \"]\"}]}], \n"); mfprintf(a," \"}\"}]}], \",\", \n"); mfprintf(a," RowBox[{\"LabelStyle\", \"\\[Rule]\", \n"); /*********************************************/ mfprintf(a," RowBox[{\"{\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"FontFamily\", \"\\[Rule]\", \"\\\"\\\\\"\"}], \",\", \n"); mfprintf(a," RowBox[{\"FontSize\", \"\\[Rule]\", \n"); mfprintf(a," RowBox[{\"ticklabelsize\", \"*\", \n"); mfprintf(a," RowBox[{\"plotpixels\", \"/\", \"800\"}]}]}]}], \"}\"}]}]}], \n"); mfprintf(a," \"}\"}]}], \"]\"}], \"\\[IndentingNewLine]\", \",\"}], \"]\"}]}], \n"); mfprintf(a," \"]\"}]}], \"]\"}]}], \"]\"}]}], \"\\[IndentingNewLine]\", \")\"}]}], \";\"}], \n"); mfprintf(a," \"\\[IndentingNewLine]\", \"\\[IndentingNewLine]\", \n"); mfprintf(a," RowBox[{\"(*\", \" \", \n"); mfprintf(a," RowBox[{\"Create\", \" \", \"Legend\"}], \" \", \"*)\"}]}], \"\\[IndentingNewLine]\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"plotlegend\", \":=\", \n"); mfprintf(a," RowBox[{\"(\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"x\", \"=.\"}], \";\", \n"); mfprintf(a," RowBox[{\"y\", \"=.\"}], \";\", \n"); mfprintf(a," RowBox[{\"If\", \"[\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"plottype\", \">\", \"1\"}], \",\", \"\\[IndentingNewLine]\", \n"); mfprintf(a," \"\\[IndentingNewLine]\", \n"); mfprintf(a," RowBox[{\"DensityPlot\", \"[\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"If\", \"[\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"explegend\", \"==\", \"1\"}], \",\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"Sign\", \"[\", \"x\", \"]\"}], \"*\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"Abs\", \"[\", \"x\", \"]\"}], \"^\", \"exp\"}]}], \",\", \"x\"}], \n"); mfprintf(a," \"]\"}], \",\", \n"); mfprintf(a," RowBox[{\"{\", \n"); mfprintf(a," RowBox[{\"x\", \",\", \"datmin\", \",\", \"datmax\"}], \"}\"}], \",\", \n"); mfprintf(a," RowBox[{\"{\", \n"); mfprintf(a," RowBox[{\"y\", \",\", \"0\", \",\", \"1\"}], \"}\"}], \",\", \n"); mfprintf(a," RowBox[{\"{\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"PlotRange\", \"\\[Rule]\", \n"); mfprintf(a," RowBox[{\"If\", \"[\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"explegend\", \"==\", \"1\"}], \",\", \n"); mfprintf(a," RowBox[{\"{\", \n"); mfprintf(a," RowBox[{\"datminexp\", \",\", \"datmaxexp\"}], \"}\"}], \",\", \n"); mfprintf(a," RowBox[{\"{\", \n"); mfprintf(a," RowBox[{\"datmin\", \",\", \"datmax\"}], \"}\"}]}], \"]\"}]}], \",\", \n"); mfprintf(a," RowBox[{\"ColorFunction\", \"\\[Rule]\", \n"); mfprintf(a," RowBox[{\"Function\", \"[\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"{\", \"z\", \"}\"}], \",\", \n"); mfprintf(a," RowBox[{\"ColFunc\", \"[\", \n"); mfprintf(a," RowBox[{\"If\", \"[\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"explegend\", \"==\", \"1\"}], \",\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"(\", \n"); mfprintf(a," RowBox[{\"z\", \" \", \"-\", \"datminexp\"}], \")\"}], \"/\", \n"); mfprintf(a," RowBox[{\"(\", \n"); mfprintf(a," RowBox[{\"datmaxexp\", \"-\", \"datminexp\"}], \")\"}]}], \",\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"(\", \n"); mfprintf(a," RowBox[{\"z\", \"+\", \n"); mfprintf(a," RowBox[{\"If\", \"[\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"ValueQ\", \"[\", \"mincolorvalue\", \"]\"}], \",\", \n"); mfprintf(a," RowBox[{\"-\", \"mincolorvalue\"}], \",\", \n"); mfprintf(a," RowBox[{\"-\", \"datmin\"}]}], \"]\"}]}], \")\"}], \"/\", \n"); mfprintf(a," RowBox[{\"If\", \"[\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"ValueQ\", \"[\", \"maxcolorvalue\", \"]\"}], \",\", \n"); mfprintf(a," RowBox[{\"maxcolorvalue\", \"-\", \"mincolorvalue\"}], \",\", \n"); mfprintf(a," RowBox[{\"datmax\", \"-\", \"datmin\"}]}], \"]\"}]}]}], \"]\"}], \n"); mfprintf(a," \"]\"}]}], \"]\"}]}], \",\", \n"); mfprintf(a," RowBox[{\"ColorFunctionScaling\", \"\\[Rule]\", \"False\"}], \",\", \n"); mfprintf(a," RowBox[{\"Axes\", \"\\[Rule]\", \"False\"}], \",\", \n"); mfprintf(a," RowBox[{\"Frame\", \"\\[Rule]\", \"True\"}], \",\", \n"); mfprintf(a," RowBox[{\"FrameStyle\", \"\\[Rule]\", \n"); mfprintf(a," RowBox[{\"Directive\", \"[\", \n"); mfprintf(a," RowBox[{\"Thickness\", \"[\", \"framethickness\", \"]\"}], \"]\"}]}], \",\", \n"); mfprintf(a," RowBox[{\"FrameTicks\", \"\\[Rule]\", \n"); mfprintf(a," RowBox[{\"{\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"{\", \n"); mfprintf(a," RowBox[{\"None\", \",\", \"None\"}], \"}\"}], \",\", \n"); mfprintf(a," RowBox[{\"{\", \n"); mfprintf(a," RowBox[{\"tfl\", \",\", \"None\"}], \"}\"}]}], \"}\"}]}], \",\", \n"); mfprintf(a," RowBox[{\"PlotRangePadding\", \"\\[Rule]\", \"None\"}], \",\", \n"); mfprintf(a," RowBox[{\"FrameLabel\", \"\\[Rule]\", \n"); mfprintf(a," RowBox[{\"{\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"Style\", \"[\", \n"); mfprintf(a," RowBox[{\"zlabel\", \",\", \n"); mfprintf(a," RowBox[{\"FontSize\", \"\\[Rule]\", \n"); mfprintf(a," RowBox[{\"labelsize\", \"*\", \n"); mfprintf(a," RowBox[{\"plotpixels\", \"/\", \"800\"}]}]}]}], \"]\"}], \",\", \n"); mfprintf(a," \"\\\"\\<\\>\\\"\", \",\", \"\\\"\\<\\>\\\"\"}], \"}\"}]}], \",\", \n"); mfprintf(a," RowBox[{\"LabelStyle\", \"\\[Rule]\", \n"); /*********************************************/ mfprintf(a," RowBox[{\"{\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"FontFamily\", \"\\[Rule]\", \"\\\"\\\\\"\"}], \",\", \n"); mfprintf(a," RowBox[{\"FontSize\", \"\\[Rule]\", \n"); mfprintf(a," RowBox[{\"ticklabelsize\", \"*\", \n"); mfprintf(a," RowBox[{\"plotpixels\", \"/\", \"800\"}]}]}]}], \"}\"}]}], \",\", \n"); mfprintf(a," RowBox[{\"AspectRatio\", \"\\[Rule]\", \"0.04\"}], \",\", \n"); mfprintf(a," RowBox[{\"ImageSize\", \"\\[Rule]\", \n"); mfprintf(a," RowBox[{\"plotpixels\", \"*\", \n"); mfprintf(a," RowBox[{\"7\", \"/\", \"8\"}]}]}], \",\", \n"); mfprintf(a," RowBox[{\"PlotPoints\", \"\\[Rule]\", \n"); mfprintf(a," RowBox[{\"{\", \n"); mfprintf(a," RowBox[{\"2000\", \",\", \"2\"}], \"}\"}]}]}], \"}\"}]}], \"]\"}], \",\", \n"); mfprintf(a," \"\\[IndentingNewLine]\", \"\\[IndentingNewLine]\", \n"); mfprintf(a," RowBox[{\"ContourPlot\", \"[\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"If\", \"[\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"explegend\", \"==\", \"1\"}], \",\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"Sign\", \"[\", \"x\", \"]\"}], \"*\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"Abs\", \"[\", \"x\", \"]\"}], \"^\", \"exp\"}]}], \",\", \"x\"}], \n"); mfprintf(a," \"]\"}], \",\", \n"); mfprintf(a," RowBox[{\"{\", \n"); mfprintf(a," RowBox[{\"x\", \",\", \"datmin\", \",\", \"datmax\"}], \"}\"}], \",\", \n"); mfprintf(a," RowBox[{\"{\", \n"); mfprintf(a," RowBox[{\"y\", \",\", \"0\", \",\", \"1\"}], \"}\"}], \",\", \n"); mfprintf(a," RowBox[{\"{\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"PlotRange\", \"\\[Rule]\", \n"); mfprintf(a," RowBox[{\"If\", \"[\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"explegend\", \"==\", \"1\"}], \",\", \n"); mfprintf(a," RowBox[{\"{\", \n"); mfprintf(a," RowBox[{\"datminexp\", \",\", \"datmaxexp\"}], \"}\"}], \",\", \n"); mfprintf(a," RowBox[{\"{\", \n"); mfprintf(a," RowBox[{\"datmin\", \",\", \"datmax\"}], \"}\"}]}], \"]\"}]}], \",\", \n"); mfprintf(a," RowBox[{\"ColorFunction\", \"\\[Rule]\", \n"); mfprintf(a," RowBox[{\"Function\", \"[\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"{\", \"z\", \"}\"}], \",\", \n"); mfprintf(a," RowBox[{\"ColFunc\", \"[\", \n"); mfprintf(a," RowBox[{\"If\", \"[\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"explegend\", \"==\", \"1\"}], \",\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"(\", \n"); mfprintf(a," RowBox[{\"z\", \" \", \"-\", \"datminexp\"}], \")\"}], \"/\", \n"); mfprintf(a," RowBox[{\"(\", \n"); mfprintf(a," RowBox[{\"datmaxexp\", \"-\", \"datminexp\"}], \")\"}]}], \",\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"(\", \n"); mfprintf(a," RowBox[{\"z\", \"+\", \n"); mfprintf(a," RowBox[{\"If\", \"[\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"ValueQ\", \"[\", \"mincolorvalue\", \"]\"}], \",\", \n"); mfprintf(a," RowBox[{\"-\", \"mincolorvalue\"}], \",\", \n"); mfprintf(a," RowBox[{\"-\", \"datmin\"}]}], \"]\"}]}], \")\"}], \"/\", \n"); mfprintf(a," RowBox[{\"If\", \"[\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"ValueQ\", \"[\", \"maxcolorvalue\", \"]\"}], \",\", \n"); mfprintf(a," RowBox[{\"maxcolorvalue\", \"-\", \"mincolorvalue\"}], \",\", \n"); mfprintf(a," RowBox[{\"datmax\", \"-\", \"datmin\"}]}], \"]\"}]}]}], \"]\"}], \n"); mfprintf(a," \"]\"}]}], \"]\"}]}], \",\", \n"); mfprintf(a," RowBox[{\"ColorFunctionScaling\", \"\\[Rule]\", \"False\"}], \",\", \n"); mfprintf(a," RowBox[{\"Axes\", \"\\[Rule]\", \"False\"}], \",\", \n"); mfprintf(a," RowBox[{\"Frame\", \"\\[Rule]\", \"True\"}], \",\", \n"); mfprintf(a," RowBox[{\"FrameStyle\", \"\\[Rule]\", \n"); mfprintf(a," RowBox[{\"Directive\", \"[\", \n"); mfprintf(a," RowBox[{\"Thickness\", \"[\", \"framethickness\", \"]\"}], \"]\"}]}], \",\", \n"); mfprintf(a," RowBox[{\"Contours\", \"\\[Rule]\", \"contours\"}], \",\", \n"); mfprintf(a," RowBox[{\"FrameTicks\", \"\\[Rule]\", \n"); mfprintf(a," RowBox[{\"{\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"{\", \n"); mfprintf(a," RowBox[{\"None\", \",\", \"None\"}], \"}\"}], \",\", \n"); mfprintf(a," RowBox[{\"{\", \n"); mfprintf(a," RowBox[{\"tfl\", \",\", \"None\"}], \"}\"}]}], \"}\"}]}], \",\", \n"); mfprintf(a," RowBox[{\"PlotRangePadding\", \"\\[Rule]\", \"None\"}], \",\", \n"); mfprintf(a," RowBox[{\"ContourStyle\", \"\\[Rule]\", \n"); mfprintf(a," RowBox[{\"Directive\", \"[\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"Thickness\", \"[\", \"contourthickness\", \"]\"}], \",\", \n"); mfprintf(a," \"contourcolor\", \",\", \n"); mfprintf(a," RowBox[{\"Opacity\", \"[\", \"contouropacity\", \"]\"}], \",\", \n"); mfprintf(a," RowBox[{\"Dashing\", \"[\", \"contourdash\", \"]\"}]}], \"]\"}]}], \",\", \n"); mfprintf(a," RowBox[{\"FrameLabel\", \"\\[Rule]\", \n"); mfprintf(a," RowBox[{\"{\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"Style\", \"[\", \n"); mfprintf(a," RowBox[{\"zlabel\", \",\", \n"); mfprintf(a," RowBox[{\"FontSize\", \"\\[Rule]\", \n"); mfprintf(a," RowBox[{\"labelsize\", \"*\", \n"); mfprintf(a," RowBox[{\"plotpixels\", \"/\", \"800\"}]}]}]}], \"]\"}], \",\", \n"); mfprintf(a," \"\\\"\\<\\>\\\"\", \",\", \"\\\"\\<\\>\\\"\"}], \"}\"}]}], \",\", \n"); mfprintf(a," RowBox[{\"LabelStyle\", \"\\[Rule]\", \n"); /*********************************************/ mfprintf(a," RowBox[{\"{\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"FontFamily\", \"\\[Rule]\", \"\\\"\\\\\"\"}], \",\", \n"); mfprintf(a," RowBox[{\"FontSize\", \"\\[Rule]\", \n"); mfprintf(a," RowBox[{\"ticklabelsize\", \"*\", \n"); mfprintf(a," RowBox[{\"plotpixels\", \"/\", \"800\"}]}]}]}], \"}\"}]}], \",\", \n"); mfprintf(a," RowBox[{\"AspectRatio\", \"\\[Rule]\", \"0.04\"}], \",\", \n"); mfprintf(a," RowBox[{\"ImageSize\", \"\\[Rule]\", \n"); mfprintf(a," RowBox[{\"plotpixels\", \"*\", \n"); mfprintf(a," RowBox[{\"7\", \"/\", \"8\"}]}]}]}], \"}\"}]}], \"]\"}]}], \"]\"}]}], \n"); mfprintf(a," \")\"}]}], \";\"}]}], \"Input\" ]\n"); mfprintf(a,"}, Closed]],\n"); mfprintf(a,"\n"); mfprintf(a,"Cell[CellGroupData[{\n"); mfprintf(a,"\n"); mfprintf(a,"Cell[\"Plotting Parameters\", \"Section\",\n"); mfprintf(a," CellDingbat->DynamicModuleBox[{$CellContext`state$$ = False}, \n"); mfprintf(a," OpenerBox[\n"); mfprintf(a," Dynamic[$CellContext`state$$, (FrontEndExecute[{\n"); mfprintf(a," FrontEnd`SelectionMove[\n"); mfprintf(a," FrontEnd`ButtonNotebook[], All, ButtonCell],\n"); mfprintf(a," FrontEndToken[\"OpenCloseGroup\"]}]; $CellContext`state$$ = #)& ]], \n"); mfprintf(a," DynamicModuleValues :> {}]],\n"); mfprintf(a,"\n"); mfprintf(a,"Cell[CellGroupData[{\n"); mfprintf(a,"\n"); mfprintf(a,"Cell[\"Misc. Properties\", \"Subsection\",\n"); mfprintf(a," CellDingbat->DynamicModuleBox[{$CellContext`state$$ = True}, \n"); mfprintf(a," OpenerBox[\n"); mfprintf(a," Dynamic[$CellContext`state$$, (FrontEndExecute[{\n"); mfprintf(a," FrontEnd`SelectionMove[\n"); mfprintf(a," FrontEnd`ButtonNotebook[], All, ButtonCell], \n"); mfprintf(a," FrontEndToken[\"OpenCloseGroup\"]}]; $CellContext`state$$ = #)& ]], \n"); mfprintf(a," DynamicModuleValues :> {}]],\n"); mfprintf(a,"\n"); mfprintf(a,"Cell[BoxData[\n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"(*\", \" \", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"Choose\", \" \", \"the\", \" \", \"plot\", \" \", \n"); mfprintf(a," RowBox[{\"type\", \".\", \" \", \"1\"}]}], \" \", \"=\", \" \", \n"); mfprintf(a," RowBox[{\"Contour\", \" \", \"Plot\"}]}], \",\", \" \", \n"); mfprintf(a," RowBox[{\"2\", \" \", \"=\", \" \", \n"); mfprintf(a," RowBox[{\"Density\", \" \", \"Plot\"}]}], \",\", \" \", \n"); mfprintf(a," RowBox[{\"3\", \" \", \"=\", \" \", \n"); mfprintf(a," RowBox[{\"Relief\", \" \", \"Plot\"}]}], \",\", \" \", \n"); mfprintf(a," RowBox[{\"4\", \" \", \"=\", \" \", \n"); mfprintf(a," RowBox[{\"3\", \"D\", \" \", \"Plot\"}]}]}], \" \", \"*)\"}], \"\\[IndentingNewLine]\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"plottype\", \"=\", \"%d\"}], \";\"}]}]], \"Input\"],\n",m_iPlotType); mfprintf(a,"\n"); mfprintf(a,"Cell[BoxData[\n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"(*\", \" \", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"Choose\", \" \", \"the\", \" \", \"color\", \" \", \n"); mfprintf(a," RowBox[{\"scale\", \":\", \"1\"}]}], \"=\", \n"); mfprintf(a," RowBox[{\"Travis\", \" \", \"Scale\"}]}], \",\", \n"); mfprintf(a," RowBox[{\"2\", \"=\", \n"); mfprintf(a," RowBox[{\"black\", \" \", \"and\", \" \", \"white\"}]}], \",\", \n"); mfprintf(a," RowBox[{\"3\", \"=\", \n"); mfprintf(a," RowBox[{\"Temperature\", \" \", \"scale\"}]}], \",\", \n"); mfprintf(a," RowBox[{\"4\", \"=\", \n"); mfprintf(a," RowBox[{\"PlusMinus\", \" \", \"scale\"}]}]}], \" \", \"*)\"}], \n"); mfprintf(a," \"\\[IndentingNewLine]\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"coloring\", \"=\", \"%d\"}], \";\"}]}]], \"Input\"],\n",m_iColorScale); mfprintf(a,"\n"); mfprintf(a,"Cell[BoxData[\n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"(*\", \" \", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," \"Choose\", \" \", \"the\", \" \", \"exponent\", \" \", \"your\", \" \", \"data\", \" \", \n"); mfprintf(a," \"will\", \" \", \"be\", \" \", \"processed\", \" \", \n"); mfprintf(a," RowBox[{\"with\", \".\", \" \", \"Try\"}], \" \", \"values\", \" \", \"between\", \" \", \n"); mfprintf(a," \"0.2\", \" \", \"and\", \" \", \"1.\"}], \" \", \"*)\"}], \"\\[IndentingNewLine]\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"exp\", \"=\", \"%.1f\"}], \";\"}]}]], \"Input\"],\n",m_fPlotExp); mfprintf(a,"\n"); mfprintf(a,"Cell[BoxData[\n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"(*\", \" \", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," \"Also\", \" \", \"scale\", \" \", \"the\", \" \", \"legend\", \" \", \"with\", \" \", \"the\", \n"); mfprintf(a," \" \", \"exponent\"}], \" \", \"*)\"}], \"\\[IndentingNewLine]\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"explegend\", \"=\", \"%d\"}], \";\"}]}]], \"Input\"],\n",m_iExpLegend); mfprintf(a,"\n"); mfprintf(a,"Cell[BoxData[\n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"(*\", \" \", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\n"); mfprintf(a," \"Choose\", \" \", \"the\", \" \", \"smoothing\", \" \", \"grade\", \" \", \"for\", \" \", \n"); mfprintf(a," \"your\", \" \", \n"); mfprintf(a," RowBox[{\"data\", \".\", \" \", \"The\"}], \" \", \"higher\", \" \", \"it\", \" \", \"is\"}],\n"); mfprintf(a," \",\", \" \", \n"); mfprintf(a," RowBox[{\"the\", \" \", \"longer\", \" \", \"it\", \" \", \n"); mfprintf(a," RowBox[{\"takes\", \".\", \" \", \"0\"}], \" \", \"means\", \" \", \"no\", \" \", \n"); mfprintf(a," RowBox[{\"smoothing\", \".\"}]}]}], \" \", \"*)\"}], \"\\[IndentingNewLine]\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"smoothgrade\", \"=\", \"%d\"}], \";\"}]}]], \"Input\"],\n",m_iSmoothGrade); mfprintf(a,"\n"); mfprintf(a,"Cell[BoxData[\n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"(*\", \" \", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," \"The\", \" \", \"interpolation\", \" \", \"order\", \" \", \"mathematica\", \" \", \"uses\",\n"); mfprintf(a," \" \", \"between\", \" \", \"the\", \" \", \"data\", \" \", \n"); mfprintf(a," RowBox[{\"points\", \".\", \" \", \"0\"}], \" \", \"shows\", \" \", \"the\", \" \", \"data\", \n"); mfprintf(a," \" \", \"points\", \" \", \"like\", \" \", \"they\", \" \", \n"); mfprintf(a," RowBox[{\"are\", \".\"}]}], \" \", \"*)\"}], \"\\[IndentingNewLine]\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"interpolationorder\", \"=\", \"%d\"}], \";\"}]}]], \"Input\"],\n",m_iInterpolationOrder); mfprintf(a,"\n"); mfprintf(a,"Cell[BoxData[\n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"(*\", \" \", \n"); mfprintf(a," RowBox[{\"Choose\", \" \", \"the\", \" \", \"color\", \" \", \n"); mfprintf(a," RowBox[{\"scaling\", \".\", \" \", \"1\"}], \" \", \"means\", \" \", \"that\", \" \", \"the\",\n"); mfprintf(a," \" \", \"highest\", \" \", \"peak\", \" \", \"only\", \" \", \"gets\", \" \", \"the\", \" \", \n"); mfprintf(a," \"highest\", \" \", \n"); mfprintf(a," RowBox[{\"color\", \".\"}]}], \" \", \"*)\"}], \"\\[IndentingNewLine]\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"colorscale\", \"=\", \"1.0\"}], \";\"}]}]], \"Input\"],\n"); mfprintf(a,"\n"); mfprintf(a,"Cell[BoxData[\n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"(*\", \" \", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," \"The\", \" \", \"width\", \" \", \"of\", \" \", \"the\", \" \", \"Plot\", \" \", \"in\", \" \", \n"); mfprintf(a," \"pixels\"}], \" \", \"*)\"}], \"\\[IndentingNewLine]\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"plotpixels\", \"=\", \"%d\"}], \";\"}]}]], \"Input\"],\n",m_iPlotPixel); mfprintf(a,"\n"); mfprintf(a,"Cell[BoxData[\n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"(*\", \" \", \n"); mfprintf(a," RowBox[{\"The\", \" \", \"aspect\", \" \", \"ratio\", \" \", \"of\", \" \", \"the\", \" \", \n"); mfprintf(a," RowBox[{\"plot\", \".\", \" \", \"1\"}], \" \", \"means\", \" \", \n"); mfprintf(a," RowBox[{\"quadratic\", \".\"}]}], \" \", \"*)\"}], \"\\[IndentingNewLine]\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"aspectratio\", \"=\", \"%f\"}], \";\"}]}]], \"Input\"],\n",m_fAspectRatio); mfprintf(a,"Cell[BoxData[\n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"(*\", \" \", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\n"); mfprintf(a," \"Controls\", \" \", \"if\", \" \", \"a\", \" \", \"mesh\", \" \", \"is\", \" \", \"drawn\", \n"); mfprintf(a," \" \", \"across\", \" \", \"the\", \" \", \n"); mfprintf(a," RowBox[{\"plot\", \".\", \" \", \"1\"}]}], \"=\", \"enable\"}], \",\", \" \", \n"); mfprintf(a," RowBox[{\"0\", \"=\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"disable\", \".\", \" \", \"For\"}], \" \", \"mesh\", \" \", \"appearance\", \n"); mfprintf(a," \" \", \"see\", \" \", \"\\\"\\\\\"\"}], \" \", \"\\[Rule]\", \" \", \n"); mfprintf(a," \"\\\"\\\\\"\"}]}]}], \"*)\"}], \"\\[IndentingNewLine]\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"drawmesh\", \"=\", \"%d\"}], \";\"}]}]], \"Input\"]\n",m_bDrawMesh?1:0); mfprintf(a,"}, Open ]],\n"); mfprintf(a,"\n"); mfprintf(a,"Cell[CellGroupData[{\n"); mfprintf(a,"\n"); mfprintf(a,"Cell[\"Contour Properties\", \"Subsection\",\n"); mfprintf(a," CellDingbat->DynamicModuleBox[{$CellContext`state$$ = False}, \n"); mfprintf(a," OpenerBox[\n"); mfprintf(a," Dynamic[$CellContext`state$$, (FrontEndExecute[{\n"); mfprintf(a," FrontEnd`SelectionMove[\n"); mfprintf(a," FrontEnd`ButtonNotebook[], All, ButtonCell], \n"); mfprintf(a," FrontEndToken[\"OpenCloseGroup\"]}]; $CellContext`state$$ = #)& ]], \n"); mfprintf(a," DynamicModuleValues :> {}]],\n"); mfprintf(a,"\n"); mfprintf(a,"Cell[BoxData[\n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"(*\", \" \", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," \"Choose\", \" \", \"the\", \" \", \"number\", \" \", \"of\", \" \", \"contours\", \" \", \n"); mfprintf(a," \"that\", \" \", \"will\", \" \", \"be\", \" \", \"displayed\"}], \" \", \"*)\"}], \n"); mfprintf(a," \"\\[IndentingNewLine]\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"contours\", \"=\", \"%lu\"}], \";\"}]}]], \"Input\"],\n",m_iContourLines); mfprintf(a,"\n"); mfprintf(a,"Cell[BoxData[\n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"(*\", \" \", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\n"); mfprintf(a," \"Print\", \" \", \"the\", \" \", \"height\", \" \", \"value\", \" \", \"onto\", \" \", \n"); mfprintf(a," \"each\", \" \", \"contour\", \" \", \n"); mfprintf(a," RowBox[{\"line\", \"?\", \" \", \"If\"}], \" \", \"desired\"}], \",\", \" \", \n"); mfprintf(a," RowBox[{\"replace\", \" \", \"the\", \" \", \"dot\", \" \", \"by\", \" \", \n"); mfprintf(a," RowBox[{\"\\\"\\<1\\>\\\"\", \".\"}]}]}], \" \", \"*)\"}], \"\\[IndentingNewLine]\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"usecontourlabels\", \"=.\"}], \";\"}]}]], \"Input\"],\n"); mfprintf(a,"\n"); mfprintf(a,"Cell[BoxData[\n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"(*\", \" \", \n"); mfprintf(a," RowBox[{\"If\", \" \", \"contour\", \" \", \"labels\", \" \", \"are\", \" \", \n"); mfprintf(a," RowBox[{\"used\", \":\", \" \", \n"); mfprintf(a," RowBox[{\"The\", \" \", \"font\", \" \", \"size\", \" \", \"of\", \" \", \"these\", \" \", \n"); mfprintf(a," RowBox[{\"labels\", \".\"}]}]}]}], \" \", \"*)\"}], \"\\[IndentingNewLine]\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"contourlabelsize\", \"=\", \"10\"}], \";\"}]}]], \"Input\"],\n"); mfprintf(a,"\n"); mfprintf(a,"Cell[BoxData[\n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"(*\", \" \", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," \"The\", \" \", \"thickness\", \" \", \"of\", \" \", \"the\", \" \", \"contour\", \" \", \n"); mfprintf(a," \"lines\", \" \", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"(\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," \"relative\", \" \", \"to\", \" \", \"the\", \" \", \"overall\", \" \", \"plot\", \" \", \n"); mfprintf(a," \"width\"}], \")\"}], \".\"}]}], \" \", \"*)\"}], \"\\[IndentingNewLine]\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"contourthickness\", \"=\", \"0.001\"}], \";\"}]}]], \"Input\"],\n"); mfprintf(a,"\n"); mfprintf(a,"Cell[BoxData[\n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"(*\", \" \", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"The\", \" \", \"color\", \" \", \"of\", \" \", \"the\", \" \", \"contour\", \" \", \n"); mfprintf(a," RowBox[{\"lines\", \".\", \" \", \"Enter\"}], \" \", \"three\", \" \", \"values\", \" \", \n"); mfprintf(a," \"between\", \" \", \"0\", \" \", \"and\", \" \", \"1\", \" \", \"for\", \" \", \"red\"}], \",\",\n"); mfprintf(a," \" \", \n"); mfprintf(a," RowBox[{\"green\", \" \", \"and\", \" \", \"blue\", \" \", \"color\", \" \", \n"); mfprintf(a," RowBox[{\"component\", \".\"}]}]}], \" \", \"*)\"}], \"\\[IndentingNewLine]\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"contourcolor\", \"=\", \n"); mfprintf(a," RowBox[{\"RGBColor\", \"[\", \n"); mfprintf(a," RowBox[{\"0\", \",\", \"0\", \",\", \"0\"}], \"]\"}]}], \";\"}]}]], \"Input\"],\n"); mfprintf(a,"\n"); mfprintf(a,"Cell[BoxData[\n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"(*\", \" \", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"The\", \" \", \"opacity\", \" \", \"of\", \" \", \"the\", \" \", \"contour\", \" \", \n"); mfprintf(a," RowBox[{\"lines\", \".\", \" \", \"1\"}], \" \", \"means\", \" \", \"fully\", \" \", \n"); mfprintf(a," \"opaque\"}], \",\", \" \", \n"); mfprintf(a," RowBox[{\"0\", \" \", \"means\", \" \", \"totally\", \" \", \"transparent\", \" \", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"(\", \"invisible\", \")\"}], \".\"}]}]}], \" \", \"*)\"}], \n"); mfprintf(a," \"\\[IndentingNewLine]\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"contouropacity\", \"=\", \"0.7\"}], \";\"}]}]], \"Input\"],\n"); mfprintf(a,"\n"); mfprintf(a,"Cell[BoxData[\n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"(*\", \" \", \n"); mfprintf(a," RowBox[{\"The\", \" \", \"pattern\", \" \", \"of\", \" \", \"the\", \" \", \"contour\", \" \", \n"); mfprintf(a," RowBox[{\"lines\", \".\", \" \", \"Large\"}], \" \", \"values\", \" \", \"like\", \" \", \n"); mfprintf(a," \"1000\", \" \", \"mean\", \" \", \"no\", \" \", \n"); mfprintf(a," RowBox[{\"dashing\", \".\", \" \", \"e\", \".\", \"g\", \".\", \" \", \"0.01\"}], \" \", \n"); mfprintf(a," \"results\", \" \", \"in\", \" \", \"dashed\", \" \", \n"); mfprintf(a," RowBox[{\"lines\", \".\"}]}], \" \", \"*)\"}], \"\\[IndentingNewLine]\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"contourdash\", \"=\", \"1000\"}], \";\"}]}]], \"Input\"]\n"); mfprintf(a,"}, Closed]],\n"); mfprintf(a,"\n"); mfprintf(a,"Cell[CellGroupData[{\n"); mfprintf(a,"\n"); mfprintf(a,"Cell[\"3D Plot Properties\", \"Subsection\",\n"); mfprintf(a," CellDingbat->DynamicModuleBox[{$CellContext`state$$ = False}, \n"); mfprintf(a," OpenerBox[\n"); mfprintf(a," Dynamic[$CellContext`state$$, (FrontEndExecute[{\n"); mfprintf(a," FrontEnd`SelectionMove[\n"); mfprintf(a," FrontEnd`ButtonNotebook[], All, ButtonCell], \n"); mfprintf(a," FrontEndToken[\"OpenCloseGroup\"]}]; $CellContext`state$$ = #)& ]], \n"); mfprintf(a," DynamicModuleValues :> {}]],\n"); mfprintf(a,"\n"); mfprintf(a,"Cell[BoxData[\n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"(*\", \" \", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," \"Draw\", \" \", \"Tick\", \" \", \"labels\", \" \", \"on\", \" \", \"the\", \" \", \"Z\", \" \", \n"); mfprintf(a," \"axis\"}], \" \", \"*)\"}], \"\\[IndentingNewLine]\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"labelsz\", \"=\", \".\"}], \";\"}]}]], \"Input\"],\n"); mfprintf(a,"\n"); mfprintf(a,"Cell[BoxData[\n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"(*\", \" \", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," \"Draw\", \" \", \"a\", \" \", \"rectangular\", \" \", \"box\", \" \", \"around\", \" \", \n"); mfprintf(a," \"the\", \" \", \"3\", \"D\", \" \", \"plot\"}], \" \", \"*)\"}], \"\\[IndentingNewLine]\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"boxed\", \"=\", \".\"}], \";\"}]}]], \"Input\"],\n"); mfprintf(a,"\n"); mfprintf(a,"Cell[BoxData[\n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"(*\", \" \", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," \"The\", \" \", \"line\", \" \", \"width\", \" \", \"of\", \" \", \"this\", \" \", \"box\"}], \n"); mfprintf(a," \" \", \"*)\"}], \"\\[IndentingNewLine]\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"boxthickness\", \"=\", \"0.002\"}], \";\"}]}]], \"Input\"],\n"); mfprintf(a,"\n"); mfprintf(a,"Cell[BoxData[\n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"(*\", \" \", \n"); mfprintf(a," RowBox[{\"The\", \" \", \"color\", \" \", \"of\", \" \", \"this\", \" \", \"box\"}], \" \", \n"); mfprintf(a," \"*)\"}], \"\\[IndentingNewLine]\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"boxcolor\", \"=\", \n"); mfprintf(a," RowBox[{\"RGBColor\", \"[\", \n"); mfprintf(a," RowBox[{\"0\", \",\", \"0\", \",\", \"0\"}], \"]\"}]}], \";\"}]}]], \"Input\"],\n"); mfprintf(a,"\n"); mfprintf(a,"Cell[BoxData[\n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"(*\", \" \", \n"); mfprintf(a," RowBox[{\"The\", \" \", \"opacity\", \" \", \"of\", \" \", \"this\", \" \", \"box\"}], \" \", \n"); mfprintf(a," \"*)\"}], \"\\[IndentingNewLine]\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"boxopacity\", \"=\", \"1\"}], \";\"}]}]], \"Input\"],\n"); mfprintf(a,"\n"); mfprintf(a,"Cell[BoxData[\n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"(*\", \" \", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"May\", \" \", \"be\", \" \", \"either\", \" \", \n"); mfprintf(a," RowBox[{\"{\", \n"); mfprintf(a," RowBox[{\"y\", \",\", \"z\"}], \"}\"}], \" \", \"with\", \" \", \"y\"}], \",\", \" \", \n"); mfprintf(a," RowBox[{\"z\", \" \", \"=\", \" \", \n"); mfprintf(a," RowBox[{\"1\", \" \", \"/\", \" \", \n"); mfprintf(a," RowBox[{\"-\", \"1\"}]}]}], \",\", \" \", \n"); mfprintf(a," RowBox[{\"or\", \" \", \"Automatic\"}], \",\", \" \", \n"); mfprintf(a," RowBox[{\"or\", \" \", \"None\"}]}], \" \", \"*)\"}], \"\\[IndentingNewLine]\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"xaxisposition\", \"=\", \n"); mfprintf(a," RowBox[{\"{\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"-\", \"1\"}], \",\", \n"); mfprintf(a," RowBox[{\"-\", \"1\"}]}], \"}\"}]}], \";\"}]}]], \"Input\"],\n"); mfprintf(a,"\n"); mfprintf(a,"Cell[BoxData[\n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"(*\", \" \", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"May\", \" \", \"be\", \" \", \"either\", \" \", \n"); mfprintf(a," RowBox[{\"{\", \n"); mfprintf(a," RowBox[{\"x\", \",\", \"z\"}], \"}\"}], \" \", \"with\", \" \", \"x\"}], \",\", \" \", \n"); mfprintf(a," RowBox[{\"z\", \" \", \"=\", \" \", \n"); mfprintf(a," RowBox[{\"1\", \" \", \"/\", \" \", \n"); mfprintf(a," RowBox[{\"-\", \"1\"}]}]}], \",\", \" \", \n"); mfprintf(a," RowBox[{\"or\", \" \", \"Automatic\"}], \",\", \" \", \n"); mfprintf(a," RowBox[{\"or\", \" \", \"None\"}]}], \" \", \"*)\"}], \"\\[IndentingNewLine]\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"yaxisposition\", \"=\", \n"); mfprintf(a," RowBox[{\"{\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"-\", \"1\"}], \",\", \n"); mfprintf(a," RowBox[{\"-\", \"1\"}]}], \"}\"}]}], \";\"}]}]], \"Input\"],\n"); mfprintf(a,"\n"); mfprintf(a,"Cell[BoxData[\n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"(*\", \" \", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"May\", \" \", \"be\", \" \", \"either\", \" \", \n"); mfprintf(a," RowBox[{\"{\", \n"); mfprintf(a," RowBox[{\"x\", \",\", \"y\"}], \"}\"}], \" \", \"with\", \" \", \"x\"}], \",\", \" \", \n"); mfprintf(a," RowBox[{\"y\", \" \", \"=\", \" \", \n"); mfprintf(a," RowBox[{\"1\", \" \", \"/\", \" \", \n"); mfprintf(a," RowBox[{\"-\", \"1\"}]}]}], \",\", \" \", \n"); mfprintf(a," RowBox[{\"or\", \" \", \"Automatic\"}], \",\", \" \", \n"); mfprintf(a," RowBox[{\"or\", \" \", \"None\"}]}], \" \", \"*)\"}], \"\\[IndentingNewLine]\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"zaxisposition\", \"=\", \"None\"}], \";\"}]}]], \"Input\"],\n"); mfprintf(a,"\n"); mfprintf(a,"Cell[BoxData[\n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"(*\", \" \", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," \"The\", \" \", \"thickness\", \" \", \"of\", \" \", \"the\", \" \", \"axes\", \" \", \"and\", \n"); mfprintf(a," \" \", \"tick\", \" \", \"marks\"}], \" \", \"*)\"}], \"\\[IndentingNewLine]\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"axesthickness\", \"=\", \"0.005\"}], \";\"}]}]], \"Input\"],\n"); mfprintf(a,"\n"); mfprintf(a,"Cell[BoxData[\n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"(*\", \" \", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," \"The\", \" \", \"label\", \" \", \"to\", \" \", \"plot\", \" \", \"on\", \" \", \"the\", \" \", \n"); mfprintf(a," \"Z\", \" \", \"axis\"}], \" \", \"*)\"}], \"\\[IndentingNewLine]\", \n"); mfprintf(a," RowBox[{\n"); if (m_sLabelZ == NULL) mfprintf(a," RowBox[{\"zlabel\", \"=\", \"\\\"\\\\\"\"}], \";\"}]}]], \"Input\"],\n"); else mfprintf(a," RowBox[{\"zlabel\", \"=\", \"\\\"\\<%s\\>\\\"\"}], \";\"}]}]], \"Input\"],\n",m_sLabelZ); mfprintf(a,"\n"); mfprintf(a,"Cell[BoxData[\n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"(*\", \" \", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," \"How\", \" \", \"many\", \" \", \"grid\", \" \", \"lines\", \" \", \"to\", \" \", \"draw\", \" \",\n"); mfprintf(a," \"in\", \" \", \"X\", \" \", \"direction\"}], \" \", \"*)\"}], \"\\[IndentingNewLine]\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"gridxcount\", \"=\", \"25\"}], \";\"}]}]], \"Input\"],\n"); mfprintf(a,"\n"); mfprintf(a,"Cell[BoxData[\n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"(*\", \" \", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," \"Color\", \" \", \"for\", \" \", \"the\", \" \", \"grid\", \" \", \"lines\", \" \", \"in\", \" \",\n"); mfprintf(a," \"X\", \" \", \"direction\"}], \" \", \"*)\"}], \"\\[IndentingNewLine]\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"gridxcolor\", \"=\", \n"); mfprintf(a," RowBox[{\"RGBColor\", \"[\", \n"); mfprintf(a," RowBox[{\"0\", \",\", \"0\", \",\", \"0\"}], \"]\"}]}], \";\"}]}]], \"Input\"],\n"); mfprintf(a,"\n"); mfprintf(a,"Cell[BoxData[\n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"(*\", \" \", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," \"Thickness\", \" \", \"of\", \" \", \"the\", \" \", \"grid\", \" \", \"lines\", \" \", \"in\", \n"); mfprintf(a," \" \", \"X\", \" \", \"direction\"}], \" \", \"*)\"}], \"\\[IndentingNewLine]\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"gridxthickness\", \"=\", \"0.001\"}], \";\"}]}]], \"Input\"],\n"); mfprintf(a,"\n"); mfprintf(a,"Cell[BoxData[\n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"(*\", \" \", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," \"Opacity\", \" \", \"of\", \" \", \"the\", \" \", \"grid\", \" \", \"lines\", \" \", \"in\", \n"); mfprintf(a," \" \", \"X\", \" \", \"direction\"}], \" \", \"*)\"}], \"\\[IndentingNewLine]\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"gridxopacity\", \"=\", \"1\"}], \";\"}]}]], \"Input\"],\n"); mfprintf(a,"\n"); mfprintf(a,"Cell[BoxData[\n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"(*\", \" \", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," \"How\", \" \", \"many\", \" \", \"grid\", \" \", \"lines\", \" \", \"to\", \" \", \"draw\", \" \",\n"); mfprintf(a," \"in\", \" \", \"Y\", \" \", \"direction\"}], \" \", \"*)\"}], \"\\[IndentingNewLine]\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"gridycount\", \"=\", \"25\"}], \";\"}]}]], \"Input\"],\n"); mfprintf(a,"\n"); mfprintf(a,"Cell[BoxData[\n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"(*\", \" \", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," \"Color\", \" \", \"for\", \" \", \"the\", \" \", \"grid\", \" \", \"lines\", \" \", \"in\", \" \",\n"); mfprintf(a," \"Y\", \" \", \"direction\"}], \" \", \"*)\"}], \"\\[IndentingNewLine]\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"gridycolor\", \"=\", \n"); mfprintf(a," RowBox[{\"RGBColor\", \"[\", \n"); mfprintf(a," RowBox[{\"0\", \",\", \"0\", \",\", \"0\"}], \"]\"}]}], \";\"}]}]], \"Input\"],\n"); mfprintf(a,"\n"); mfprintf(a,"Cell[BoxData[\n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"(*\", \" \", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," \"Thickness\", \" \", \"of\", \" \", \"the\", \" \", \"grid\", \" \", \"lines\", \" \", \"in\", \n"); mfprintf(a," \" \", \"Y\", \" \", \"direction\"}], \" \", \"*)\"}], \"\\[IndentingNewLine]\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"gridythickness\", \"=\", \"0.001\"}], \";\"}]}]], \"Input\"],\n"); mfprintf(a,"\n"); mfprintf(a,"Cell[BoxData[\n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"(*\", \" \", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," \"Opacity\", \" \", \"of\", \" \", \"the\", \" \", \"grid\", \" \", \"lines\", \" \", \"in\", \n"); mfprintf(a," \" \", \"Y\", \" \", \"direction\"}], \" \", \"*)\"}], \"\\[IndentingNewLine]\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"gridyopacity\", \"=\", \"1\"}], \";\"}]}]], \"Input\"]\n"); mfprintf(a,"}, Closed]],\n"); mfprintf(a,"\n"); mfprintf(a,"Cell[CellGroupData[{\n"); mfprintf(a,"\n"); mfprintf(a,"Cell[\"Plot Range\", \"Subsection\",\n"); mfprintf(a," CellDingbat->DynamicModuleBox[{$CellContext`state$$ = False}, \n"); mfprintf(a," OpenerBox[\n"); mfprintf(a," Dynamic[$CellContext`state$$, (FrontEndExecute[{\n"); mfprintf(a," FrontEnd`SelectionMove[\n"); mfprintf(a," FrontEnd`ButtonNotebook[], All, ButtonCell], \n"); mfprintf(a," FrontEndToken[\"OpenCloseGroup\"]}]; $CellContext`state$$ = #)& ]], \n"); mfprintf(a," DynamicModuleValues :> {}]],\n"); mfprintf(a,"\n"); mfprintf(a,"Cell[BoxData[\n"); mfprintf(a," RowBox[{\"(*\", \" \",\n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\n"); mfprintf(a," \"Here\", \" \", \"you\", \" \", \"can\", \" \", \"\\\"\\\\\"\", \" \", \"into\", \" \", \n"); mfprintf(a," \"a\", \" \", \"specified\", \" \", \"area\", \" \", \"of\", \" \", \"your\", \" \", \n"); mfprintf(a," RowBox[{\"plot\", \".\", \" \", \"The\"}], \" \", \"range\", \" \", \"of\", \" \", \"your\", \n"); mfprintf(a," \" \", \"data\", \" \", \"was\", \" \", \"originally\", \" \", \"X1\"}], \"=\", \"%f\"}], \n",m_fMinVal[0]); mfprintf(a," \",\", \" \", \n"); mfprintf(a," RowBox[{\"Y1\", \"=\", \"%f\"}], \",\", \" \", \n",m_fMinVal[1]); mfprintf(a," RowBox[{\"X2\", \"=\", \"%f\"}], \",\", \" \", \n",m_fMaxVal[0]); mfprintf(a," RowBox[{\"Y2\", \"=\", \"%f.\"}]}], \" \", \"*)\"}]], \"Input\"],\n",m_fMaxVal[1]); mfprintf(a,"\n"); mfprintf(a,"Cell[BoxData[\n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"plotrangeX1\", \"=\", \"%f\"}], \";\"}]], \"Input\"],\n",m_fMinVal[0]); mfprintf(a,"\n"); mfprintf(a,"Cell[BoxData[\n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"plotrangeY1\", \"=\", \"%f\"}], \";\"}]], \"Input\"],\n",m_fMinVal[1]); mfprintf(a,"\n"); mfprintf(a,"Cell[BoxData[\n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"plotrangeX2\", \"=\", \"%f\"}], \";\"}]], \"Input\"],\n",m_fMaxVal[0]); mfprintf(a,"\n"); mfprintf(a,"Cell[BoxData[\n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"plotrangeY2\", \"=\", \"%f\"}], \";\"}]], \"Input\"]\n",m_fMaxVal[1]); mfprintf(a,"}, Closed]],\n"); mfprintf(a,"\n"); mfprintf(a,"Cell[CellGroupData[{\n"); mfprintf(a,"\n"); mfprintf(a,"Cell[\"Manual Color/Contour Scale\", \"Subsection\",\n"); mfprintf(a," CellDingbat->DynamicModuleBox[{$CellContext`state$$ = False}, \n"); mfprintf(a," OpenerBox[\n"); mfprintf(a," Dynamic[$CellContext`state$$, (FrontEndExecute[{\n"); mfprintf(a," FrontEnd`SelectionMove[\n"); mfprintf(a," FrontEnd`ButtonNotebook[], All, ButtonCell], \n"); mfprintf(a," FrontEndToken[\"OpenCloseGroup\"]}]; $CellContext`state$$ = #)& ]], \n"); mfprintf(a," DynamicModuleValues :> {}]],\n"); mfprintf(a,"\n"); mfprintf(a,"Cell[BoxData[\n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"(*\", \" \", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\n"); mfprintf(a," \"Enter\", \" \", \"a\", \" \", \"value\", \" \", \"here\", \" \", \"ONLY\", \" \", \"if\", \n"); mfprintf(a," \" \", \"you\", \" \", \"want\", \" \", \"to\", \" \", \"create\", \" \", \"different\", \n"); mfprintf(a," \" \", \"plots\", \" \", \"with\", \" \", \"the\", \" \", \"same\", \" \", \"color\", \" \", \n"); mfprintf(a," RowBox[{\"scale\", \".\", \"\\[IndentingNewLine]\", \"Then\"}], \" \", \"no\", \" \", \n"); mfprintf(a," \"rescaling\", \" \", \"for\", \" \", \"smoothened\", \" \", \"data\", \" \", \"will\", \n"); mfprintf(a," \" \", \n"); mfprintf(a," RowBox[{\"occur\", \".\", \" \", \"Data\"}], \" \", \"for\", \" \", \"this\", \" \", \n"); mfprintf(a," RowBox[{\"plot\", \":\", \" \", \"maxcolorvalue\"}]}], \" \", \"=\", \" \", \n"); mfprintf(a," \"%f\"}], \";\", \" \", \n",m_fMaxEntry); mfprintf(a," RowBox[{\"mincolorvalue\", \" \", \"=\", \" \", \n"); mfprintf(a," RowBox[{\"%c\", \"%f\"}]}]}], \" \", \"*)\"}], \"\\[IndentingNewLine]\", \n",(m_fMinEntry<0)?'-':'+',m_fMinEntry); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\n"); if (manrange) mfprintf(a," RowBox[{\"mincolorvalue\", \"=\", \"%f\"}], \";\"}], \"\\[IndentingNewLine]\", \n",0.0); else mfprintf(a," RowBox[{\"mincolorvalue\", \"=.\"}], \";\"}], \"\\[IndentingNewLine]\", \n"); mfprintf(a," RowBox[{\n"); if (manrange) mfprintf(a," RowBox[{\"maxcolorvalue\", \"=\", \"%f\"}], \";\"}]}]}]], \"Input\"],\n",m_fMaxEntry); else mfprintf(a," RowBox[{\"maxcolorvalue\", \"=.\"}], \";\"}]}]}]], \"Input\"]\n"); mfprintf(a,"\n"); mfprintf(a,"}, Closed]],\n"); mfprintf(a,"\n"); mfprintf(a,"Cell[CellGroupData[{\n"); mfprintf(a,"\n"); mfprintf(a,"Cell[\"Frame Thickness / Font Sizes\", \"Subsection\",\n"); mfprintf(a," CellDingbat->DynamicModuleBox[{$CellContext`state$$ = False}, \n"); mfprintf(a," OpenerBox[\n"); mfprintf(a," Dynamic[$CellContext`state$$, (FrontEndExecute[{\n"); mfprintf(a," FrontEnd`SelectionMove[\n"); mfprintf(a," FrontEnd`ButtonNotebook[], All, ButtonCell], \n"); mfprintf(a," FrontEndToken[\"OpenCloseGroup\"]}]; $CellContext`state$$ = #)& ]], \n"); mfprintf(a," DynamicModuleValues :> {}]],\n"); mfprintf(a,"\n"); mfprintf(a,"Cell[BoxData[\n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"(*\", \" \", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," \"Choose\", \" \", \"the\", \" \", \"font\", \" \", \"size\", \" \", \"for\", \" \", \"the\", \n"); mfprintf(a," \" \", \"tick\", \" \", \"labels\"}], \" \", \"*)\"}], \"\\[IndentingNewLine]\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"ticklabelsize\", \"=\", \"28\"}], \";\"}]}]], \"Input\"],\n"); mfprintf(a,"\n"); mfprintf(a,"Cell[BoxData[\n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"(*\", \" \", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," \"Choose\", \" \", \"the\", \" \", \"font\", \" \", \"size\", \" \", \"for\", \" \", \"the\", \n"); mfprintf(a," \" \", \"axis\", \" \", \"labels\"}], \" \", \"*)\"}], \"\\[IndentingNewLine]\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"labelsize\", \"=\", \"32\"}], \";\"}]}]], \"Input\"],\n"); mfprintf(a,"\n"); mfprintf(a,"Cell[BoxData[\n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"(*\", \" \", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," \"Choose\", \" \", \"the\", \" \", \"thickness\", \" \", \"of\", \" \", \"the\", \" \", \n"); mfprintf(a," \"frame\", \" \", \"and\", \" \", \"the\", \" \", \"axis\", \" \", \"ticks\"}], \" \", \"*)\"}],\n"); mfprintf(a," \"\\[IndentingNewLine]\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"framethickness\", \"=\", \"0.005\"}], \";\"}]}]], \"Input\"],\n"); mfprintf(a,"\n"); mfprintf(a,"Cell[BoxData[\n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"(*\", \" \", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," \"Define\", \" \", \"if\", \" \", \"space\", \" \", \"should\", \" \", \"be\", \" \", \"left\", \n"); mfprintf(a," \" \", \"between\", \" \", \"the\", \" \", \"plot\", \" \", \"and\", \" \", \"the\", \" \", \n"); mfprintf(a," RowBox[{\"axes\", \".\", \" \", \"Set\"}], \" \", \"this\", \" \", \"to\", \" \", \n"); mfprintf(a," \"\\\"\\\\\"\", \" \", \"or\", \" \", \"to\", \" \", \n"); mfprintf(a," RowBox[{\"\\\"\\<0\\>\\\"\", \".\"}]}], \" \", \"*)\"}], \"\\[IndentingNewLine]\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"framemargins\", \"=\", \"0\"}], \";\"}]}]], \"Input\"]\n"); mfprintf(a,"}, Closed]]\n"); mfprintf(a,"}, Closed]],\n"); mfprintf(a,"\n"); mfprintf(a,"Cell[CellGroupData[{\n"); mfprintf(a,"\n"); mfprintf(a,"Cell[\"Axis Properties\", \"Section\",\n"); mfprintf(a," CellDingbat->DynamicModuleBox[{$CellContext`state$$ = False}, \n"); mfprintf(a," OpenerBox[\n"); mfprintf(a," Dynamic[$CellContext`state$$, (FrontEndExecute[{\n"); mfprintf(a," FrontEnd`SelectionMove[\n"); mfprintf(a," FrontEnd`ButtonNotebook[], All, ButtonCell], \n"); mfprintf(a," FrontEndToken[\"OpenCloseGroup\"]}]; $CellContext`state$$ = #)& ]], \n"); mfprintf(a," DynamicModuleValues :> {}]],\n"); mfprintf(a,"\n"); mfprintf(a,"Cell[CellGroupData[{\n"); mfprintf(a,"\n"); mfprintf(a,"Cell[\"General Properties\", \"Subsection\",\n"); mfprintf(a," CellDingbat->DynamicModuleBox[{$CellContext`state$$ = False}, \n"); mfprintf(a," OpenerBox[\n"); mfprintf(a," Dynamic[$CellContext`state$$, (FrontEndExecute[{\n"); mfprintf(a," FrontEnd`SelectionMove[\n"); mfprintf(a," FrontEnd`ButtonNotebook[], All, ButtonCell], \n"); mfprintf(a," FrontEndToken[\"OpenCloseGroup\"]}]; $CellContext`state$$ = #)& ]], \n"); mfprintf(a," DynamicModuleValues :> {}]],\n"); mfprintf(a,"\n"); mfprintf(a,"Cell[BoxData[\n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"(*\", \" \", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," \"The\", \" \", \"length\", \" \", \"of\", \" \", \"the\", \" \", \"major\", \" \", \"ticks\", \n"); mfprintf(a," \" \", \"on\", \" \", \"the\", \" \", \n"); mfprintf(a," RowBox[{\"axes\", \".\"}]}], \" \", \"*)\"}], \"\\[IndentingNewLine]\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"majorticklength\", \"=\", \"0.03\"}], \";\"}]}]], \"Input\"],\n"); mfprintf(a,"\n"); mfprintf(a,"Cell[BoxData[\n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"(*\", \" \", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," \"The\", \" \", \"length\", \" \", \"of\", \" \", \"the\", \" \", \"minor\", \" \", \"ticks\", \n"); mfprintf(a," \" \", \n"); mfprintf(a," RowBox[{\"(\", \n"); mfprintf(a," RowBox[{\"the\", \" \", \"ones\", \" \", \"without\", \" \", \"tick\", \" \", \"labels\"}],\n"); mfprintf(a," \")\"}], \" \", \"on\", \" \", \"the\", \" \", \n"); mfprintf(a," RowBox[{\"axes\", \".\"}]}], \" \", \"*)\"}], \"\\[IndentingNewLine]\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"minorticklength\", \"=\", \"0.015\"}], \";\"}]}]], \"Input\"],\n"); mfprintf(a,"\n"); mfprintf(a,"Cell[BoxData[\n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"(*\", \" \", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\n"); mfprintf(a," \"Controls\", \" \", \"if\", \" \", \"the\", \" \", \"major\", \" \", \"ticks\", \" \", \n"); mfprintf(a," \"point\", \" \", \"to\", \" \", \"the\", \" \", \"inside\", \" \", \"or\", \" \", \n"); mfprintf(a," RowBox[{\"outside\", \".\", \" \", \"0\"}], \" \", \"is\", \" \", \"inside\"}], \",\", \" \", \n"); mfprintf(a," RowBox[{\"0.5\", \" \", \"is\", \" \", \"symmetrical\"}], \",\", \" \", \n"); mfprintf(a," RowBox[{\"1\", \" \", \"is\", \" \", \n"); mfprintf(a," RowBox[{\"outside\", \".\"}]}]}], \" \", \"*)\"}], \"\\[IndentingNewLine]\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"majortickshift\", \"=\", \"0.5\"}], \";\"}]}]], \"Input\"],\n"); mfprintf(a,"\n"); mfprintf(a,"Cell[BoxData[\n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"(*\", \" \", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\n"); mfprintf(a," \"Controls\", \" \", \"if\", \" \", \"the\", \" \", \"minor\", \" \", \"ticks\", \" \", \n"); mfprintf(a," \"point\", \" \", \"to\", \" \", \"the\", \" \", \"inside\", \" \", \"or\", \" \", \n"); mfprintf(a," RowBox[{\"outside\", \".\", \" \", \"0\"}], \" \", \"is\", \" \", \"inside\"}], \",\", \" \", \n"); mfprintf(a," RowBox[{\"0.5\", \" \", \"is\", \" \", \"symmetrical\"}], \",\", \" \", \n"); mfprintf(a," RowBox[{\"1\", \" \", \"is\", \" \", \n"); mfprintf(a," RowBox[{\"outside\", \".\"}]}]}], \" \", \"*)\"}], \"\\[IndentingNewLine]\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"minortickshift\", \"=\", \"0.5\"}], \";\"}]}]], \"Input\"]\n"); mfprintf(a,"}, Closed]],\n"); mfprintf(a,"\n"); mfprintf(a,"Cell[CellGroupData[{\n"); mfprintf(a,"\n"); mfprintf(a,"Cell[\"Mesh Properties\", \"Subsection\",\n"); mfprintf(a," CellDingbat->DynamicModuleBox[{$CellContext`state$$ = False}, \n"); mfprintf(a," OpenerBox[\n"); mfprintf(a," Dynamic[$CellContext`state$$, (FrontEndExecute[{\n"); mfprintf(a," FrontEnd`SelectionMove[\n"); mfprintf(a," FrontEnd`ButtonNotebook[], All, ButtonCell], \n"); mfprintf(a," FrontEndToken[\"OpenCloseGroup\"]}]; $CellContext`state$$ = #)& ]],\n"); mfprintf(a," DynamicModuleValues :> {}]],\n"); mfprintf(a,"\n"); mfprintf(a,"Cell[BoxData[\n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"(*\", \" \", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," \"The\", \" \", \"thickness\", \" \", \"of\", \" \", \"the\", \" \", \"mesh\", \" \", \n"); mfprintf(a," \"perpendicular\", \" \", \"to\", \" \", \"the\", \" \", \"X\", \" \", \"axis\", \" \", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"(\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," \"relative\", \" \", \"to\", \" \", \"the\", \" \", \"overall\", \" \", \"plot\", \" \", \n"); mfprintf(a," \"width\"}], \")\"}], \".\"}]}], \" \", \"*)\"}], \"\\[IndentingNewLine]\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"meshthicknessX\", \"=\", \"0.002\"}], \";\"}]}]], \"Input\"],\n"); mfprintf(a,"\n"); mfprintf(a,"Cell[BoxData[\n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"(*\", \" \",\n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\n"); mfprintf(a," \"The\", \" \", \"color\", \" \", \"of\", \" \", \"the\", \" \", \"mesh\", \" \", \n"); mfprintf(a," \"perpendicular\", \" \", \"to\", \" \", \"the\", \" \", \"X\", \" \", \n"); mfprintf(a," RowBox[{\"axis\", \".\", \" \", \"Enter\"}], \" \", \"three\", \" \", \"values\", \" \", \n"); mfprintf(a," \"between\", \" \", \"0\", \" \", \"and\", \" \", \"1\", \" \", \"for\", \" \", \"red\"}], \",\",\n"); mfprintf(a," \" \", \n"); mfprintf(a," RowBox[{\"green\", \" \", \"and\", \" \", \"blue\", \" \", \"color\", \" \", \n"); mfprintf(a," RowBox[{\"component\", \".\"}]}]}], \" \", \"*)\"}], \"\\[IndentingNewLine]\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"meshcolorX\", \"=\", \n"); mfprintf(a," RowBox[{\"RGBColor\", \"[\", \n"); mfprintf(a," RowBox[{\"0\", \",\", \"0\", \",\", \"0\"}], \"]\"}]}], \";\"}]}]], \"Input\"],\n"); mfprintf(a,"\n"); mfprintf(a,"Cell[BoxData[\n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"(*\", \" \", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\n"); mfprintf(a," \"The\", \" \", \"opacity\", \" \", \"of\", \" \", \"the\", \" \", \"mesh\", \" \", \n"); mfprintf(a," \"perpendicular\", \" \", \"to\", \" \", \"the\", \" \", \"X\", \" \", \n"); mfprintf(a," RowBox[{\"axis\", \".\", \" \", \"1\"}], \" \", \"means\", \" \", \"fully\", \" \", \n"); mfprintf(a," \"opaque\"}], \",\", \" \", \n"); mfprintf(a," RowBox[{\"0\", \" \", \"means\", \" \", \"totally\", \" \", \"transparent\", \" \", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"(\", \"invisible\", \")\"}], \".\"}]}]}], \" \", \"*)\"}], \n"); mfprintf(a," \"\\[IndentingNewLine]\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"meshopacityX\", \"=\", \"0.5\"}], \";\"}]}]], \"Input\"],\n"); mfprintf(a,"\n"); mfprintf(a,"Cell[BoxData[\n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"(*\", \" \", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," \"The\", \" \", \"thickness\", \" \", \"of\", \" \", \"the\", \" \", \"mesh\", \" \", \n"); mfprintf(a," \"perpendicular\", \" \", \"to\", \" \", \"the\", \" \", \"Y\", \" \", \"axis\", \" \", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"(\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," \"relative\", \" \", \"to\", \" \", \"the\", \" \", \"overall\", \" \", \"plot\", \" \", \n"); mfprintf(a," \"width\"}], \")\"}], \".\"}]}], \" \", \"*)\"}], \"\\[IndentingNewLine]\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"meshthicknessY\", \"=\", \"0.002\"}], \";\"}]}]], \"Input\"],\n"); mfprintf(a,"\n"); mfprintf(a,"Cell[BoxData[\n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"(*\", \" \", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\n"); mfprintf(a," \"The\", \" \", \"color\", \" \", \"of\", \" \", \"the\", \" \", \"mesh\", \" \", \n"); mfprintf(a," \"perpendicular\", \" \", \"to\", \" \", \"the\", \" \", \"Y\", \" \", \n"); mfprintf(a," RowBox[{\"axis\", \".\", \" \", \"Enter\"}], \" \", \"three\", \" \", \"values\", \" \", \n"); mfprintf(a," \"between\", \" \", \"0\", \" \", \"and\", \" \", \"1\", \" \", \"for\", \" \", \"red\"}], \",\",\n"); mfprintf(a," \" \", \n"); mfprintf(a," RowBox[{\"green\", \" \", \"and\", \" \", \"blue\", \" \", \"color\", \" \", \n"); mfprintf(a," RowBox[{\"component\", \".\"}]}]}], \" \", \"*)\"}], \"\\[IndentingNewLine]\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"meshcolorY\", \"=\", \n"); mfprintf(a," RowBox[{\"RGBColor\", \"[\", \n"); mfprintf(a," RowBox[{\"0\", \",\", \"0\", \",\", \"0\"}], \"]\"}]}], \";\"}]}]], \"Input\"],\n"); mfprintf(a,"\n"); mfprintf(a,"Cell[BoxData[\n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"(*\", \" \", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\n"); mfprintf(a," \"The\", \" \", \"opacity\", \" \", \"of\", \" \", \"the\", \" \", \"mesh\", \" \", \n"); mfprintf(a," \"perpendicular\", \" \", \"to\", \" \", \"the\", \" \", \"Y\", \" \", \n"); mfprintf(a," RowBox[{\"axis\", \".\", \" \", \"1\"}], \" \", \"means\", \" \", \"fully\", \" \", \n"); mfprintf(a," \"opaque\"}], \",\", \" \", \n"); mfprintf(a," RowBox[{\"0\", \" \", \"means\", \" \", \"totally\", \" \", \"transparent\", \" \", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"(\", \"invisible\", \")\"}], \".\"}]}]}], \" \", \"*)\"}], \n"); mfprintf(a," \"\\[IndentingNewLine]\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"meshopacityY\", \"=\", \"0.5\"}], \";\"}]}]], \"Input\"]\n"); mfprintf(a,"}, Closed ]],\n"); mfprintf(a,"Cell[CellGroupData[{\n"); mfprintf(a,"\n"); mfprintf(a,"Cell[\"X Axis\", \"Subsection\",\n"); mfprintf(a," CellDingbat->DynamicModuleBox[{$CellContext`state$$ = False}, \n"); mfprintf(a," OpenerBox[\n"); mfprintf(a," Dynamic[$CellContext`state$$, (FrontEndExecute[{\n"); mfprintf(a," FrontEnd`SelectionMove[\n"); mfprintf(a," FrontEnd`ButtonNotebook[], All, ButtonCell], \n"); mfprintf(a," FrontEndToken[\"OpenCloseGroup\"]}]; $CellContext`state$$ = #)& ]], \n"); mfprintf(a," DynamicModuleValues :> {}]],\n"); mfprintf(a,"\n"); mfprintf(a,"Cell[BoxData[\n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"(*\", \" \", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," \"The\", \" \", \"label\", \" \", \"to\", \" \", \"appear\", \" \", \"on\", \" \", \"the\", \" \", \n"); mfprintf(a," \"x\", \" \", \"axis\"}], \" \", \"*)\"}], \"\\[IndentingNewLine]\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"xlabel\", \"=\", \"\\\"\\<%s\\>\\\"\"}], \n",m_sLabelX); mfprintf(a," \";\"}]}]], \"Input\"],\n"); mfprintf(a,"\n"); mfprintf(a,"Cell[BoxData[\n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"(*\", \" \", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," \"The\", \" \", \"lowest\", \" \", \"tick\", \" \", \"value\", \" \", \"for\", \" \", \"the\", \n"); mfprintf(a," \" \", \"x\", \" \", \n"); mfprintf(a," RowBox[{\"axis\", \".\"}]}], \" \", \"*)\"}], \"\\[IndentingNewLine]\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"tickminX\", \":=\", \n"); mfprintf(a," RowBox[{\"maxsig\", \"[\", \n"); mfprintf(a," RowBox[{\"plotrangeX1\", \",\", \"2\"}], \"]\"}]}], \";\"}]}]], \"Input\"],\n"); mfprintf(a,"\n"); mfprintf(a,"Cell[BoxData[\n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"(*\", \" \", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," \"The\", \" \", \"highest\", \" \", \"tick\", \" \", \"value\", \" \", \"for\", \" \", \"the\", \n"); mfprintf(a," \" \", \"x\", \" \", \n"); mfprintf(a," RowBox[{\"axis\", \".\"}]}], \" \", \"*)\"}], \"\\[IndentingNewLine]\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"tickmaxX\", \":=\", \n"); mfprintf(a," RowBox[{\"minsig\", \"[\", \n"); mfprintf(a," RowBox[{\"plotrangeX2\", \",\", \"2\"}], \"]\"}]}], \";\"}]}]], \"Input\"],\n"); mfprintf(a,"\n"); mfprintf(a,"Cell[BoxData[\n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"(*\", \" \", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," \"Print\", \" \", \"this\", \" \", \"number\", \" \", \"of\", \" \", \"digits\", \" \", \n"); mfprintf(a," \"after\", \" \", \"the\", \" \", \"decimal\", \" \", \"point\", \" \", \"of\", \" \", \"the\", \n"); mfprintf(a," \" \", \"tick\", \" \", \n"); mfprintf(a," RowBox[{\"labels\", \".\", \" \", \"0\"}], \" \", \"means\", \" \", \"no\", \" \", \n"); mfprintf(a," \"decimal\", \" \", \n"); mfprintf(a," RowBox[{\"point\", \".\"}]}], \" \", \"*)\"}], \"\\[IndentingNewLine]\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"tickprecX\", \":=\", \n"); mfprintf(a," RowBox[{\"prec\", \"[\", \"plotrangeX2\", \"]\"}]}], \";\"}]}]], \"Input\"],\n"); mfprintf(a,"\n"); mfprintf(a,"Cell[BoxData[\n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"(*\", \" \", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," \"Use\", \" \", \"this\", \" \", \"count\", \" \", \"of\", \" \", \"major\", \" \", \"ticks\", \n"); mfprintf(a," \" \", \n"); mfprintf(a," RowBox[{\"(\", \n"); mfprintf(a," RowBox[{\"with\", \" \", \"tick\", \" \", \"label\"}], \")\"}], \" \", \"on\", \" \", \n"); mfprintf(a," \"the\", \" \", \"x\", \" \", \n"); mfprintf(a," RowBox[{\"axis\", \".\"}]}], \" \", \"*)\"}], \"\\[IndentingNewLine]\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"majorticksX\", \"=\", \"%d\"}], \";\"}]}]], \"Input\"],\n",majorx); mfprintf(a,"\n"); mfprintf(a,"Cell[BoxData[\n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"(*\", \" \", \n"); mfprintf(a," RowBox[{\"How\", \" \", \"many\", \" \", \"minor\", \" \", \"ticks\", \" \", \n"); mfprintf(a," RowBox[{\"(\", \n"); mfprintf(a," RowBox[{\"without\", \" \", \"tick\", \" \", \"label\"}], \")\"}], \" \", \"to\", \" \", \n"); mfprintf(a," \"show\", \" \", \"PER\", \" \", \"MAJOR\", \" \", \n"); mfprintf(a," RowBox[{\"TICK\", \".\"}]}], \" \", \"*)\"}], \"\\[IndentingNewLine]\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"minorticksX\", \"=\", \"%d\"}], \";\"}]}]], \"Input\"],\n",minorx); mfprintf(a,"\n"); mfprintf(a,"Cell[BoxData[\n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"(*\", \" \", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," \"A\", \" \", \"character\", \" \", \"string\", \" \", \"to\", \" \", \"stand\", \" \", \n"); mfprintf(a," \"before\", \" \", \"each\", \" \", \"tick\", \" \", \n"); mfprintf(a," RowBox[{\"label\", \".\"}]}], \" \", \"*)\"}], \"\\[IndentingNewLine]\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"ticklabelprefixX\", \"=\", \"\\\"\\<\\>\\\"\"}], \";\"}]}]], \"Input\"],\n"); mfprintf(a,"\n"); mfprintf(a,"Cell[BoxData[\n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"(*\", \" \", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," \"A\", \" \", \"character\", \" \", \"string\", \" \", \"to\", \" \", \"stand\", \" \", \n"); mfprintf(a," \"after\", \" \", \"each\", \" \", \"tick\", \" \", \n"); mfprintf(a," RowBox[{\"label\", \".\"}]}], \" \", \"*)\"}], \"\\[IndentingNewLine]\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"ticklabelsuffixX\", \"=\", \"\\\"\\<\\>\\\"\"}], \";\"}]}]], \"Input\"],\n"); mfprintf(a,"\n"); mfprintf(a,"Cell[BoxData[\n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"(*\", \" \", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," \"Show\", \" \", \"tick\", \" \", \"marks\", \" \", \"on\", \" \", \"both\", \" \", \"the\", \" \",\n"); mfprintf(a," \"top\", \" \", \"X\", \" \", \"axis\", \" \", \"and\", \" \", \"the\", \" \", \"bottom\", \" \",\n"); mfprintf(a," \"X\", \" \", \n"); mfprintf(a," RowBox[{\"axis\", \"?\", \" \", \"Set\"}], \" \", \"to\", \" \", \"\\\"\\<1\\>\\\"\", \" \", \"if\",\n"); mfprintf(a," \" \", \"desired\", \" \", \"or\", \" \", \"to\", \" \", \"\\\"\\<.\\>\\\"\", \" \", \"if\", \" \", \n"); mfprintf(a," RowBox[{\"not\", \".\"}]}], \" \", \"*)\"}], \"\\[IndentingNewLine]\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"ticksbothsidesX\", \"=\", \"1\"}], \";\"}]}]], \"Input\"],\n"); mfprintf(a,"\n"); mfprintf(a,"Cell[BoxData[\n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"(*\", \" \", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," \"Show\", \" \", \"tick\", \" \", \"labels\", \" \", \"on\", \" \", \"both\", \" \", \"the\", \n"); mfprintf(a," \" \", \"top\", \" \", \"X\", \" \", \"axis\", \" \", \"and\", \" \", \"the\", \" \", \"bottom\", \n"); mfprintf(a," \" \", \"X\", \" \", \n"); mfprintf(a," RowBox[{\"axis\", \"?\", \" \", \"Set\"}], \" \", \"to\", \" \", \"\\\"\\<1\\>\\\"\", \" \", \"if\",\n"); mfprintf(a," \" \", \"desired\", \" \", \"or\", \" \", \"to\", \" \", \"\\\"\\<.\\>\\\"\", \" \", \"if\", \" \", \n"); mfprintf(a," RowBox[{\"not\", \".\"}]}], \" \", \"*)\"}], \"\\[IndentingNewLine]\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"labelsbothsidesX\", \"=.\"}], \";\"}]}]], \"Input\"]\n"); mfprintf(a,"}, Closed]],\n"); mfprintf(a,"\n"); mfprintf(a,"Cell[CellGroupData[{\n"); mfprintf(a,"\n"); mfprintf(a,"Cell[\"Y Axis\", \"Subsection\",\n"); mfprintf(a," CellDingbat->DynamicModuleBox[{$CellContext`state$$ = False}, \n"); mfprintf(a," OpenerBox[\n"); mfprintf(a," Dynamic[$CellContext`state$$, (FrontEndExecute[{\n"); mfprintf(a," FrontEnd`SelectionMove[\n"); mfprintf(a," FrontEnd`ButtonNotebook[], All, ButtonCell], \n"); mfprintf(a," FrontEndToken[\"OpenCloseGroup\"]}]; $CellContext`state$$ = #)& ]], \n"); mfprintf(a," DynamicModuleValues :> {}]],\n"); mfprintf(a,"\n"); mfprintf(a,"Cell[BoxData[\n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"(*\", \" \", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," \"The\", \" \", \"label\", \" \", \"to\", \" \", \"appear\", \" \", \"on\", \" \", \"the\", \" \", \n"); mfprintf(a," \"Y\", \" \", \"axis\"}], \" \", \"*)\"}], \"\\[IndentingNewLine]\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"ylabel\", \"=\", \"\\\"\\<%s\\>\\\"\"}], \n",m_sLabelY); mfprintf(a," \";\"}]}]], \"Input\"],\n"); mfprintf(a,"\n"); mfprintf(a,"Cell[BoxData[\n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"(*\", \" \", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," \"The\", \" \", \"lowest\", \" \", \"tick\", \" \", \"value\", \" \", \"for\", \" \", \"the\", \n"); mfprintf(a," \" \", \"Y\", \" \", \n"); mfprintf(a," RowBox[{\"axis\", \".\"}]}], \" \", \"*)\"}], \"\\[IndentingNewLine]\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"tickminY\", \":=\", \n"); mfprintf(a," RowBox[{\"maxsig\", \"[\", \n"); mfprintf(a," RowBox[{\"plotrangeY1\", \",\", \"2\"}], \"]\"}]}], \";\"}]}]], \"Input\"],\n"); mfprintf(a,"\n"); mfprintf(a,"Cell[BoxData[\n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"(*\", \" \", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," \"The\", \" \", \"highest\", \" \", \"tick\", \" \", \"value\", \" \", \"for\", \" \", \"the\", \n"); mfprintf(a," \" \", \"Y\", \" \", \n"); mfprintf(a," RowBox[{\"axis\", \".\"}]}], \" \", \"*)\"}], \"\\[IndentingNewLine]\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"tickmaxY\", \":=\", \n"); mfprintf(a," RowBox[{\"minsig\", \"[\", \n"); mfprintf(a," RowBox[{\"plotrangeY2\", \",\", \"2\"}], \"]\"}]}], \";\"}]}]], \"Input\"],\n"); mfprintf(a,"\n"); mfprintf(a,"Cell[BoxData[\n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"(*\", \" \", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," \"Print\", \" \", \"this\", \" \", \"number\", \" \", \"of\", \" \", \"digits\", \" \", \n"); mfprintf(a," \"after\", \" \", \"the\", \" \", \"decimal\", \" \", \"point\", \" \", \"of\", \" \", \"the\", \n"); mfprintf(a," \" \", \"tick\", \" \", \n"); mfprintf(a," RowBox[{\"labels\", \".\", \" \", \"0\"}], \" \", \"means\", \" \", \"no\", \" \", \n"); mfprintf(a," \"decimal\", \" \", \n"); mfprintf(a," RowBox[{\"point\", \".\"}]}], \" \", \"*)\"}], \"\\[IndentingNewLine]\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"tickprecY\", \":=\", \n"); mfprintf(a," RowBox[{\"prec\", \"[\", \"plotrangeY2\", \"]\"}]}], \";\"}]}]], \"Input\"],\n"); mfprintf(a,"\n"); mfprintf(a,"Cell[BoxData[\n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"(*\", \" \", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," \"Use\", \" \", \"this\", \" \", \"count\", \" \", \"of\", \" \", \"major\", \" \", \"ticks\", \n"); mfprintf(a," \" \", \n"); mfprintf(a," RowBox[{\"(\", \n"); mfprintf(a," RowBox[{\"with\", \" \", \"tick\", \" \", \"label\"}], \")\"}], \" \", \"on\", \" \", \n"); mfprintf(a," \"the\", \" \", \"Y\", \" \", \n"); mfprintf(a," RowBox[{\"axis\", \".\"}]}], \" \", \"*)\"}], \"\\[IndentingNewLine]\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"majorticksY\", \"=\", \"%d\"}], \";\"}]}]], \"Input\"],\n",majory); mfprintf(a,"\n"); mfprintf(a,"Cell[BoxData[\n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"(*\", \" \", \n"); mfprintf(a," RowBox[{\"How\", \" \", \"many\", \" \", \"minor\", \" \", \"ticks\", \" \", \n"); mfprintf(a," RowBox[{\"(\", \n"); mfprintf(a," RowBox[{\"without\", \" \", \"tick\", \" \", \"label\"}], \")\"}], \" \", \"to\", \" \", \n"); mfprintf(a," \"show\", \" \", \"PER\", \" \", \"MAJOR\", \" \", \n"); mfprintf(a," RowBox[{\"TICK\", \".\"}]}], \" \", \"*)\"}], \"\\[IndentingNewLine]\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"minorticksY\", \"=\", \"%d\"}], \";\"}]}]], \"Input\"],\n",minory); mfprintf(a,"\n"); mfprintf(a,"Cell[BoxData[\n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"(*\", \" \", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," \"A\", \" \", \"character\", \" \", \"string\", \" \", \"to\", \" \", \"stand\", \" \", \n"); mfprintf(a," \"before\", \" \", \"each\", \" \", \"tick\", \" \", \n"); mfprintf(a," RowBox[{\"label\", \".\"}]}], \" \", \"*)\"}], \"\\[IndentingNewLine]\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"ticklabelprefixY\", \"=\", \"\\\"\\<\\>\\\"\"}], \";\"}]}]], \"Input\"],\n"); mfprintf(a,"\n"); mfprintf(a,"Cell[BoxData[\n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"(*\", \" \", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," \"A\", \" \", \"character\", \" \", \"string\", \" \", \"to\", \" \", \"stand\", \" \", \n"); mfprintf(a," \"after\", \" \", \"each\", \" \", \"tick\", \" \", \n"); mfprintf(a," RowBox[{\"label\", \".\"}]}], \" \", \"*)\"}], \"\\[IndentingNewLine]\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"ticklabelsuffixY\", \"=\", \"\\\"\\<\\>\\\"\"}], \";\"}]}]], \"Input\"],\n"); mfprintf(a,"\n"); mfprintf(a,"Cell[BoxData[\n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"(*\", \" \", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," \"Show\", \" \", \"tick\", \" \", \"marks\", \" \", \"on\", \" \", \"both\", \" \", \"the\", \" \",\n"); mfprintf(a," \"left\", \" \", \"Y\", \" \", \"axis\", \" \", \"and\", \" \", \"the\", \" \", \"right\", \" \",\n"); mfprintf(a," \"Y\", \" \", \n"); mfprintf(a," RowBox[{\"axis\", \"?\", \" \", \"Set\"}], \" \", \"to\", \" \", \"\\\"\\<1\\>\\\"\", \" \", \"if\",\n"); mfprintf(a," \" \", \"desired\", \" \", \"or\", \" \", \"to\", \" \", \"\\\"\\<.\\>\\\"\", \" \", \"if\", \" \", \n"); mfprintf(a," RowBox[{\"not\", \".\"}]}], \" \", \"*)\"}], \"\\[IndentingNewLine]\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"ticksbothsidesY\", \"=\", \"1\"}], \";\"}]}]], \"Input\"],\n"); mfprintf(a,"\n"); mfprintf(a,"Cell[BoxData[\n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"(*\", \" \", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," \"Show\", \" \", \"tick\", \" \", \"labels\", \" \", \"on\", \" \", \"both\", \" \", \"the\", \n"); mfprintf(a," \" \", \"left\", \" \", \"Y\", \" \", \"axis\", \" \", \"and\", \" \", \"the\", \" \", \"right\", \n"); mfprintf(a," \" \", \"Y\", \" \", \n"); mfprintf(a," RowBox[{\"axis\", \"?\", \" \", \"Set\"}], \" \", \"to\", \" \", \"\\\"\\<1\\>\\\"\", \" \", \"if\",\n"); mfprintf(a," \" \", \"desired\", \" \", \"or\", \" \", \"to\", \" \", \"\\\"\\<.\\>\\\"\", \" \", \"if\", \" \", \n"); mfprintf(a," RowBox[{\"not\", \".\"}]}], \" \", \"*)\"}], \"\\[IndentingNewLine]\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"labelsbothsidesY\", \"=.\"}], \";\"}]}]], \"Input\"]\n"); mfprintf(a,"}, Closed]],\n"); mfprintf(a,"\n"); mfprintf(a,"Cell[CellGroupData[{\n"); mfprintf(a,"\n"); mfprintf(a,"Cell[\"Z Axis\", \"Subsection\",\n"); mfprintf(a," CellDingbat->DynamicModuleBox[{$CellContext`state$$ = False},\n"); mfprintf(a," OpenerBox[\n"); mfprintf(a," Dynamic[$CellContext`state$$, (FrontEndExecute[{\n"); mfprintf(a," FrontEnd`SelectionMove[\n"); mfprintf(a," FrontEnd`ButtonNotebook[], All, ButtonCell], \n"); mfprintf(a," FrontEndToken[\"OpenCloseGroup\"]}]; $CellContext`state$$ = #)& ]], \n"); mfprintf(a," DynamicModuleValues :> {}]],\n"); mfprintf(a,"\n"); mfprintf(a,"Cell[BoxData[\n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"(*\", \" \", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," \"The\", \" \", \"label\", \" \", \"to\", \" \", \"appear\", \" \", \"on\", \" \", \"the\", \" \", \n"); mfprintf(a," \"Z\", \" \", \"axis\"}], \" \", \"*)\"}], \"\\[IndentingNewLine]\", \n"); mfprintf(a," RowBox[{\n"); if (m_sLabelZ == NULL) mfprintf(a," RowBox[{\"zlabel\", \"=\", \"\\\"\\\\\"\"}], \n"); else mfprintf(a," RowBox[{\"zlabel\", \"=\", \"\\\"\\<%s\\>\\\"\"}], \n",m_sLabelZ); mfprintf(a," \";\"}]}]], \"Input\"],\n"); mfprintf(a,"\n"); mfprintf(a,"Cell[BoxData[\n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"(*\", \" \", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," \"The\", \" \", \"lowest\", \" \", \"tick\", \" \", \"value\", \" \", \"for\", \" \", \"the\", \n"); mfprintf(a," \" \", \"Z\", \" \", \n"); mfprintf(a," RowBox[{\"axis\", \".\"}]}], \" \", \"*)\"}], \"\\[IndentingNewLine]\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"tickminZ\", \":=\", \n"); mfprintf(a," RowBox[{\"maxsig\", \"[\", \n"); mfprintf(a," RowBox[{\"datminexp\", \",\", \"2\"}], \"]\"}]}], \";\"}]}]], \"Input\"],\n"); mfprintf(a,"\n"); mfprintf(a,"Cell[BoxData[\n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"(*\", \" \", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," \"The\", \" \", \"highest\", \" \", \"tick\", \" \", \"value\", \" \", \"for\", \" \", \"the\", \n"); mfprintf(a," \" \", \"Z\", \" \", \n"); mfprintf(a," RowBox[{\"axis\", \".\"}]}], \" \", \"*)\"}], \"\\[IndentingNewLine]\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"tickmaxZ\", \":=\", \n"); mfprintf(a," RowBox[{\"minsig\", \"[\", \n"); mfprintf(a," RowBox[{\"datmaxexp\", \",\", \"2\"}], \"]\"}]}], \";\"}]}]], \"Input\"],\n"); mfprintf(a,"\n"); mfprintf(a,"Cell[BoxData[\n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"(*\", \" \", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," \"Print\", \" \", \"this\", \" \", \"number\", \" \", \"of\", \" \", \"digits\", \" \", \n"); mfprintf(a," \"after\", \" \", \"the\", \" \", \"decimal\", \" \", \"point\", \" \", \"of\", \" \", \"the\", \n"); mfprintf(a," \" \", \"tick\", \" \", \n"); mfprintf(a," RowBox[{\"labels\", \".\", \" \", \"0\"}], \" \", \"means\", \" \", \"no\", \" \", \n"); mfprintf(a," \"decimal\", \" \", \n"); mfprintf(a," RowBox[{\"point\", \".\"}]}], \" \", \"*)\"}], \"\\[IndentingNewLine]\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"tickprecZ\", \":=\", \n"); mfprintf(a," RowBox[{\"prec\", \"[\", \"datmaxexp\", \"]\"}]}], \";\"}]}]], \"Input\"],\n"); mfprintf(a,"\n"); mfprintf(a,"Cell[BoxData[\n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"(*\", \" \", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," \"Use\", \" \", \"this\", \" \", \"count\", \" \", \"of\", \" \", \"major\", \" \", \"ticks\", \n"); mfprintf(a," \" \", \n"); mfprintf(a," RowBox[{\"(\", \n"); mfprintf(a," RowBox[{\"with\", \" \", \"tick\", \" \", \"label\"}], \")\"}], \" \", \"on\", \" \", \n"); mfprintf(a," \"the\", \" \", \"Z\", \" \", \n"); mfprintf(a," RowBox[{\"axis\", \".\"}]}], \" \", \"*)\"}], \"\\[IndentingNewLine]\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"majorticksZ\", \"=\", \"5\"}], \";\"}]}]], \"Input\"],\n"); mfprintf(a,"\n"); mfprintf(a,"Cell[BoxData[\n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"(*\", \" \", \n"); mfprintf(a," RowBox[{\"How\", \" \", \"many\", \" \", \"minor\", \" \", \"ticks\", \" \", \n"); mfprintf(a," RowBox[{\"(\", \n"); mfprintf(a," RowBox[{\"without\", \" \", \"tick\", \" \", \"label\"}], \")\"}], \" \", \"to\", \" \", \n"); mfprintf(a," \"show\", \" \", \"PER\", \" \", \"MAJOR\", \" \", \n"); mfprintf(a," RowBox[{\"TICK\", \".\"}]}], \" \", \"*)\"}], \"\\[IndentingNewLine]\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"minorticksZ\", \"=\", \"3\"}], \";\"}]}]], \"Input\"],\n"); mfprintf(a,"\n"); mfprintf(a,"Cell[BoxData[\n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"(*\", \" \", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," \"A\", \" \", \"character\", \" \", \"string\", \" \", \"to\", \" \", \"stand\", \" \", \n"); mfprintf(a," \"before\", \" \", \"each\", \" \", \"tick\", \" \", \n"); mfprintf(a," RowBox[{\"label\", \".\"}]}], \" \", \"*)\"}], \"\\[IndentingNewLine]\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"ticklabelprefixZ\", \"=\", \"\\\"\\<\\>\\\"\"}], \";\"}]}]], \"Input\"],\n"); mfprintf(a,"\n"); mfprintf(a,"Cell[BoxData[\n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"(*\", \" \", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," \"A\", \" \", \"character\", \" \", \"string\", \" \", \"to\", \" \", \"stand\", \" \", \n"); mfprintf(a," \"after\", \" \", \"each\", \" \", \"tick\", \" \", \n"); mfprintf(a," RowBox[{\"label\", \".\"}]}], \" \", \"*)\"}], \"\\[IndentingNewLine]\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"ticklabelsuffixZ\", \"=\", \"\\\"\\<\\>\\\"\"}], \";\"}]}]], \"Input\"]\n"); mfprintf(a,"}, Closed]],\n"); mfprintf(a,"\n"); mfprintf(a,"Cell[CellGroupData[{\n"); mfprintf(a,"\n"); mfprintf(a,"Cell[\"Legend Axis\", \"Subsection\",\n"); mfprintf(a," CellDingbat->DynamicModuleBox[{$CellContext`state$$ = False}, \n"); mfprintf(a," OpenerBox[\n"); mfprintf(a," Dynamic[$CellContext`state$$, (FrontEndExecute[{\n"); mfprintf(a," FrontEnd`SelectionMove[\n"); mfprintf(a," FrontEnd`ButtonNotebook[], All, ButtonCell], \n"); mfprintf(a," FrontEndToken[\"OpenCloseGroup\"]}]; $CellContext`state$$ = #)& ]], \n"); mfprintf(a," DynamicModuleValues :> {}]],\n"); mfprintf(a,"\n"); mfprintf(a,"Cell[BoxData[\n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"(*\", \" \", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," \"The\", \" \", \"lowest\", \" \", \"tick\", \" \", \"value\", \" \", \"for\", \" \", \"the\", \n"); mfprintf(a," \" \", \"legend\", \" \", \"X\", \" \", \n"); mfprintf(a," RowBox[{\"axis\", \".\", \" \", \"\\\"\\\\\"\"}], \" \", \"sets\", \" \", \"this\", \n"); mfprintf(a," \" \", \"automatically\", \" \", \"to\", \" \", \"the\", \" \", \"lowest\", \" \", \"plot\", \n"); mfprintf(a," \" \", \n"); mfprintf(a," RowBox[{\"element\", \".\"}]}], \" \", \"*)\"}], \"\\[IndentingNewLine]\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"tickminL\", \":=\", \n"); mfprintf(a," RowBox[{\"maxsig\", \"[\", \n"); mfprintf(a," RowBox[{\"datmin\", \",\", \"3\"}], \"]\"}]}], \";\"}]}]], \"Input\"],\n"); mfprintf(a,"\n"); mfprintf(a,"Cell[BoxData[\n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"(*\", \" \", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," \"The\", \" \", \"highest\", \" \", \"tick\", \" \", \"value\", \" \", \"for\", \" \", \"the\", \n"); mfprintf(a," \" \", \"legend\", \" \", \"Y\", \" \", \n"); mfprintf(a," RowBox[{\"axis\", \".\", \" \", \"\\\"\\\\\"\"}], \" \", \"sets\", \" \", \"this\", \n"); mfprintf(a," \" \", \"automatically\", \" \", \"to\", \" \", \"the\", \" \", \"highest\", \" \", \"plot\", \n"); mfprintf(a," \" \", \n"); mfprintf(a," RowBox[{\"element\", \".\"}]}], \" \", \"*)\"}], \"\\[IndentingNewLine]\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"tickmaxL\", \":=\", \n"); mfprintf(a," RowBox[{\"minsig\", \"[\", \n"); mfprintf(a," RowBox[{\"datmax\", \",\", \"3\"}], \"]\"}]}], \";\"}]}]], \"Input\"],\n"); mfprintf(a,"\n"); mfprintf(a,"Cell[BoxData[\n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"(*\", \" \", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," \"Print\", \" \", \"this\", \" \", \"number\", \" \", \"of\", \" \", \"digits\", \" \", \n"); mfprintf(a," \"after\", \" \", \"the\", \" \", \"decimal\", \" \", \"point\", \" \", \"of\", \" \", \"the\", \n"); mfprintf(a," \" \", \"tick\", \" \", \n"); mfprintf(a," RowBox[{\"labels\", \".\", \" \", \"0\"}], \" \", \"means\", \" \", \"no\", \" \", \n"); mfprintf(a," \"decimal\", \" \", \n"); mfprintf(a," RowBox[{\"point\", \".\"}]}], \" \", \"*)\"}], \"\\[IndentingNewLine]\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"tickprecL\", \":=\", \n"); mfprintf(a," RowBox[{\"prec\", \"[\", \"datmax\", \"]\"}]}], \";\"}]}]], \"Input\"],\n"); mfprintf(a,"\n"); mfprintf(a,"Cell[BoxData[\n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"(*\", \" \", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," \"Use\", \" \", \"this\", \" \", \"count\", \" \", \"of\", \" \", \"major\", \" \", \"ticks\", \n"); mfprintf(a," \" \", \n"); mfprintf(a," RowBox[{\"(\", \n"); mfprintf(a," RowBox[{\"with\", \" \", \"tick\", \" \", \"label\"}], \")\"}], \" \", \"on\", \" \", \n"); mfprintf(a," \"the\", \" \", \"legend\", \" \", \"X\", \" \", \n"); mfprintf(a," RowBox[{\"axis\", \".\"}]}], \" \", \"*)\"}], \"\\[IndentingNewLine]\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"majorticksL\", \"=\", \"5\"}], \";\"}]}]], \"Input\"],\n"); mfprintf(a,"\n"); mfprintf(a,"Cell[BoxData[\n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"(*\", \" \", \n"); mfprintf(a," RowBox[{\"How\", \" \", \"many\", \" \", \"minor\", \" \", \"ticks\", \" \", \n"); mfprintf(a," RowBox[{\"(\", \n"); mfprintf(a," RowBox[{\"without\", \" \", \"tick\", \" \", \"label\"}], \")\"}], \" \", \"to\", \" \", \n"); mfprintf(a," \"show\", \" \", \"PER\", \" \", \"MAJOR\", \" \", \n"); mfprintf(a," RowBox[{\"TICK\", \".\"}]}], \" \", \"*)\"}], \"\\[IndentingNewLine]\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"minorticksL\", \"=\", \"3\"}], \";\"}]}]], \"Input\"],\n"); mfprintf(a,"\n"); mfprintf(a,"Cell[BoxData[\n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"(*\", \" \", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," \"The\", \" \", \"length\", \" \", \"of\", \" \", \"the\", \" \", \"major\", \" \", \"ticks\", \n"); mfprintf(a," \" \", \"on\", \" \", \"the\", \" \", \"legend\", \" \", \"X\", \" \", \n"); mfprintf(a," RowBox[{\"axis\", \".\"}]}], \" \", \"*)\"}], \"\\[IndentingNewLine]\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"majorticklengthL\", \"=\", \"0.015\"}], \";\"}]}]], \"Input\"],\n"); mfprintf(a,"\n"); mfprintf(a,"Cell[BoxData[\n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"(*\", \" \", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," \"The\", \" \", \"length\", \" \", \"of\", \" \", \"the\", \" \", \"minor\", \" \", \"ticks\", \n"); mfprintf(a," \" \", \n"); mfprintf(a," RowBox[{\"(\", \n"); mfprintf(a," RowBox[{\"the\", \" \", \"ones\", \" \", \"without\", \" \", \"tick\", \" \", \"labels\"}],\n"); mfprintf(a," \")\"}], \" \", \"on\", \" \", \"the\", \" \", \"legend\", \" \", \"X\", \" \", \n"); mfprintf(a," RowBox[{\"axis\", \".\"}]}], \" \", \"*)\"}], \"\\[IndentingNewLine]\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"minorticklengthL\", \"=\", \"0.008\"}], \";\"}]}]], \"Input\"],\n"); mfprintf(a,"\n"); mfprintf(a,"Cell[BoxData[\n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"(*\", \" \", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\n"); mfprintf(a," \"Controls\", \" \", \"if\", \" \", \"the\", \" \", \"major\", \" \", \"ticks\", \" \", \n"); mfprintf(a," \"point\", \" \", \"to\", \" \", \"the\", \" \", \"inside\", \" \", \"or\", \" \", \n"); mfprintf(a," RowBox[{\"outside\", \".\", \" \", \"0\"}], \" \", \"is\", \" \", \"inside\"}], \",\", \" \", \n"); mfprintf(a," RowBox[{\"0.5\", \" \", \"is\", \" \", \"symmetrical\"}], \",\", \" \", \n"); mfprintf(a," RowBox[{\"1\", \" \", \"is\", \" \", \n"); mfprintf(a," RowBox[{\"outside\", \".\"}]}]}], \" \", \"*)\"}], \"\\[IndentingNewLine]\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"majortickshiftL\", \"=\", \"0\"}], \";\"}]}]], \"Input\"],\n"); mfprintf(a,"\n"); mfprintf(a,"Cell[BoxData[\n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"(*\", \" \", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\n"); mfprintf(a," \"Controls\", \" \", \"if\", \" \", \"the\", \" \", \"minor\", \" \", \"ticks\", \" \", \n"); mfprintf(a," \"point\", \" \", \"to\", \" \", \"the\", \" \", \"inside\", \" \", \"or\", \" \", \n"); mfprintf(a," RowBox[{\"outside\", \".\", \" \", \"0\"}], \" \", \"is\", \" \", \"inside\"}], \",\", \" \", \n"); mfprintf(a," RowBox[{\"0.5\", \" \", \"is\", \" \", \"symmetrical\"}], \",\", \" \", \n"); mfprintf(a," RowBox[{\"1\", \" \", \"is\", \" \", \n"); mfprintf(a," RowBox[{\"outside\", \".\"}]}]}], \" \", \"*)\"}], \"\\[IndentingNewLine]\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"minortickshiftL\", \"=\", \"0\"}], \";\"}]}]], \"Input\"]\n"); mfprintf(a,"}, Closed]]\n"); mfprintf(a,"}, Closed]],\n"); mfprintf(a,"\n"); mfprintf(a,"Cell[CellGroupData[{\n"); mfprintf(a,"\n"); mfprintf(a,"Cell[\"Lines / Rectangles / Functions\", \"Section\",\n"); mfprintf(a," CellDingbat->DynamicModuleBox[{$CellContext`state$$ = False}, \n"); mfprintf(a," OpenerBox[\n"); mfprintf(a," Dynamic[$CellContext`state$$, (FrontEndExecute[{\n"); mfprintf(a," FrontEnd`SelectionMove[\n"); mfprintf(a," FrontEnd`ButtonNotebook[], All, ButtonCell], \n"); mfprintf(a," FrontEndToken[\"OpenCloseGroup\"]}]; $CellContext`state$$ = #)& ]], \n"); mfprintf(a," DynamicModuleValues :> {}]],\n"); mfprintf(a,"\n"); mfprintf(a,"Cell[CellGroupData[{\n"); mfprintf(a,"\n"); mfprintf(a,"Cell[\"Function Drawing\", \"Subsection\",\n"); mfprintf(a," CellDingbat->DynamicModuleBox[{$CellContext`state$$ = False}, \n"); mfprintf(a," OpenerBox[\n"); mfprintf(a," Dynamic[$CellContext`state$$, (FrontEndExecute[{\n"); mfprintf(a," FrontEnd`SelectionMove[\n"); mfprintf(a," FrontEnd`ButtonNotebook[], All, ButtonCell], \n"); mfprintf(a," FrontEndToken[\"OpenCloseGroup\"]}]; $CellContext`state$$ = #)& ]], \n"); mfprintf(a," DynamicModuleValues :> {}]],\n"); mfprintf(a,"\n"); mfprintf(a,"Cell[BoxData[\n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"(*\", \" \", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\n"); mfprintf(a," \"Here\", \" \", \"some\", \" \", \"functions\", \" \", \"of\", \" \", \"the\", \" \", \"form\",\n"); mfprintf(a," \" \", \"f\", \n"); mfprintf(a," RowBox[{\"(\", \"x\", \")\"}]}], \" \", \"=\", \" \", \n"); mfprintf(a," RowBox[{\"y\", \" \", \"are\", \" \", \n"); mfprintf(a," RowBox[{\"defined\", \".\", \" \", \"Uncomment\"}], \" \", \"them\", \" \", \"for\", \" \",\n"); mfprintf(a," \"testing\", \" \", \"and\", \" \", \"define\", \" \", \"your\", \" \", \"own\", \" \", \n"); mfprintf(a," RowBox[{\"ones\", \".\"}]}]}], \" \", \"*)\"}], \"\\[IndentingNewLine]\", \n"); mfprintf(a," RowBox[{\"(*\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"AppendTo\", \"[\", \n"); mfprintf(a," RowBox[{\"funcX\", \",\", \n"); mfprintf(a," RowBox[{\"{\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"(\", \n"); mfprintf(a," RowBox[{\"x\", \"/\", \"%f\"}], \")\"}], \"^\", \"2\"}], \"*\", \n",m_fMaxVal[0]); mfprintf(a," \"%f\"}], \",\", \n",m_fMaxVal[1]); mfprintf(a," RowBox[{\"{\", \n"); mfprintf(a," RowBox[{\"%f\", \",\", \"%f\"}], \"}\"}], \",\", \n",m_fMinVal[0],m_fMaxVal[0]); mfprintf(a," RowBox[{\"{\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"Thickness\", \"[\", \"0.01\", \"]\"}], \",\", \n"); mfprintf(a," RowBox[{\"RGBColor\", \"[\", \n"); mfprintf(a," RowBox[{\"1\", \",\", \"1\", \",\", \"0\"}], \"]\"}], \",\", \n"); mfprintf(a," RowBox[{\"Dashing\", \"[\", \"0.02\", \"]\"}]}], \"}\"}]}], \"}\"}]}], \"]\"}], \n"); mfprintf(a," \";\"}], \"*)\"}], \"\\[IndentingNewLine]\", \n"); mfprintf(a," RowBox[{\"(*\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"AppendTo\", \"[\", \n"); mfprintf(a," RowBox[{\"funcX\", \",\", \n"); mfprintf(a," RowBox[{\"{\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"(\", \n"); mfprintf(a," RowBox[{\"x\", \"/\", \"%f\"}], \")\"}], \"^\", \"3\"}], \"*\", \n",m_fMaxVal[0]); mfprintf(a," \"%f\"}], \",\", \n",m_fMaxVal[1]); mfprintf(a," RowBox[{\"{\", \n"); mfprintf(a," RowBox[{\"%f\", \",\", \"%f\"}], \"}\"}], \",\", \n",m_fMinVal[0]+(m_fMaxVal[0]-m_fMinVal[0])*0.2,m_fMaxVal[0]-(m_fMaxVal[0]-m_fMinVal[0])*0.2); mfprintf(a," RowBox[{\"{\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"Thickness\", \"[\", \"0.02\", \"]\"}], \",\", \n"); mfprintf(a," RowBox[{\"RGBColor\", \"[\", \n"); mfprintf(a," RowBox[{\"0\", \",\", \"1\", \",\", \"1\"}], \"]\"}]}], \"}\"}]}], \"}\"}]}], \n"); mfprintf(a," \"]\"}], \";\"}], \"*)\"}]}]], \"Input\"],\n"); mfprintf(a,"\n"); mfprintf(a,"Cell[BoxData[\n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"(*\", \" \", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\n"); mfprintf(a," \"Here\", \" \", \"some\", \" \", \"functions\", \" \", \"of\", \" \", \"the\", \" \", \"form\",\n"); mfprintf(a," \" \", \"f\", \n"); mfprintf(a," RowBox[{\"(\", \"y\", \")\"}]}], \" \", \"=\", \" \", \n"); mfprintf(a," RowBox[{\"x\", \" \", \"are\", \" \", \n"); mfprintf(a," RowBox[{\"defined\", \".\", \" \", \"Uncomment\"}], \" \", \"them\", \" \", \"for\", \" \",\n"); mfprintf(a," \"testing\", \" \", \"and\", \" \", \"define\", \" \", \"your\", \" \", \"own\", \" \", \n"); mfprintf(a," RowBox[{\"ones\", \".\"}]}]}], \" \", \"*)\"}], \"\\[IndentingNewLine]\", \n"); mfprintf(a," RowBox[{\"(*\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"AppendTo\", \"[\", \n"); mfprintf(a," RowBox[{\"funcY\", \",\", \n"); mfprintf(a," RowBox[{\"{\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"Sin\", \"[\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"y\", \"/\", \"%f\"}], \"*\", \"10\", \"Pi\"}], \"]\"}], \"*\", \n",m_fMaxVal[1]); mfprintf(a," \"%f\"}], \",\", \n",m_fMaxVal[0]*0.5); mfprintf(a," RowBox[{\"{\", \n"); mfprintf(a," RowBox[{\"%f\", \",\", \"%f\"}], \"}\"}], \",\", \n",m_fMinVal[1],m_fMaxVal[1]); mfprintf(a," RowBox[{\"{\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"Thickness\", \"[\", \"0.01\", \"]\"}], \",\", \n"); mfprintf(a," RowBox[{\"RGBColor\", \"[\", \n"); mfprintf(a," RowBox[{\"0\", \",\", \"0\", \",\", \"0\"}], \"]\"}]}], \"}\"}]}], \"}\"}]}], \n"); mfprintf(a," \"]\"}], \";\"}], \"*)\"}], \"\\[IndentingNewLine]\", \n"); mfprintf(a," RowBox[{\"(*\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"AppendTo\", \"[\", \n"); mfprintf(a," RowBox[{\"funcY\", \",\", \n"); mfprintf(a," RowBox[{\"{\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"y\", \"*\", \"%f\"}], \",\", \n",m_fMaxVal[0]/m_fMaxVal[1]); mfprintf(a," RowBox[{\"{\", \n"); mfprintf(a," RowBox[{\"%f\", \",\", \"%f\"}], \"}\"}], \",\", \n",m_fMinVal[1],m_fMaxVal[1]*0.5); mfprintf(a," RowBox[{\"{\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"Thickness\", \"[\", \"0.02\", \"]\"}], \",\", \n"); mfprintf(a," RowBox[{\"RGBColor\", \"[\", \n"); mfprintf(a," RowBox[{\"1\", \",\", \"0\", \",\", \"0\"}], \"]\"}]}], \"}\"}]}], \"}\"}]}], \n"); mfprintf(a," \"]\"}], \";\"}], \"*)\"}]}]], \"Input\"]\n"); mfprintf(a,"}, Closed]],\n"); mfprintf(a,"\n"); mfprintf(a,"Cell[CellGroupData[{\n"); mfprintf(a,"Cell[\"Rectangle and Circle Drawing\", \"Subsection\",\n"); mfprintf(a," CellDingbat->DynamicModuleBox[{$CellContext`state$$ = False}, \n"); mfprintf(a," OpenerBox[\n"); mfprintf(a," Dynamic[$CellContext`state$$, (FrontEndExecute[{\n"); mfprintf(a," FrontEnd`SelectionMove[\n"); mfprintf(a," FrontEnd`ButtonNotebook[], All, ButtonCell], \n"); mfprintf(a," FrontEndToken[\"OpenCloseGroup\"]}]; $CellContext`state$$ = #)& ]], \n"); mfprintf(a," DynamicModuleValues :> {}]],\n"); mfprintf(a,"Cell[BoxData[\n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"(*\", \" \", \n"); mfprintf(a," RowBox[{\"Draw\", \" \", \"Rectangles\", \" \", \"and\", \" \", \n"); mfprintf(a," RowBox[{\"Circles\", \".\", \" \", \"Uncomment\"}], \" \", \"the\", \" \", \"examples\", \n"); mfprintf(a," \" \", \"below\", \" \", \"and\", \" \", \"try\", \" \", \"it\", \" \", \n"); mfprintf(a," RowBox[{\"out\", \".\"}]}], \" \", \"*)\"}], \"\\[IndentingNewLine]\", \n"); mfprintf(a," RowBox[{\"(*\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"AppendTo\", \"[\", \n"); mfprintf(a," RowBox[{\"prim\", \",\", \n"); mfprintf(a," RowBox[{\"Graphics\", \"[\", \n"); mfprintf(a," RowBox[{\"{\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"EdgeForm\", \"[\", \n"); mfprintf(a," RowBox[{\"{\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"Thickness\", \"[\", \"0.006\", \"]\"}], \",\", \n"); mfprintf(a," RowBox[{\"RGBColor\", \"[\", \n"); mfprintf(a," RowBox[{\"1\", \",\", \"0\", \",\", \"1\"}], \"]\"}], \",\", \n"); mfprintf(a," RowBox[{\"Dashing\", \"[\", \"0.02\", \"]\"}]}], \"}\"}], \"]\"}], \",\", \n"); mfprintf(a," RowBox[{\"RGBColor\", \"[\", \n"); mfprintf(a," RowBox[{\"1\", \",\", \"0\", \",\", \"0\"}], \"]\"}], \",\", \n"); mfprintf(a," RowBox[{\"Opacity\", \"[\", \"0\", \"]\"}], \",\", \n"); mfprintf(a," RowBox[{\"Rectangle\", \"[\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"{\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"%f\"}], \",\", \n",m_fMinVal[0]); mfprintf(a," RowBox[{\"%f\"}]}], \"}\"}], \",\", \n",m_fMinVal[1]); mfprintf(a," RowBox[{\"{\", \n"); mfprintf(a," RowBox[{\"%f\", \",\", \"%f\"}], \"}\"}]}], \"]\"}]}], \n",m_fMaxVal[0]*0.7,m_fMaxVal[1]*0.3); mfprintf(a," \"}\"}], \"]\"}]}], \"]\"}], \";\", \"\\[IndentingNewLine]\", \n"); mfprintf(a," RowBox[{\"AppendTo\", \"[\", \n"); mfprintf(a," RowBox[{\"prim\", \",\", \n"); mfprintf(a," RowBox[{\"Graphics\", \"[\", \n"); mfprintf(a," RowBox[{\"{\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"EdgeForm\", \"[\", \n"); mfprintf(a," RowBox[{\"{\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"Thickness\", \"[\", \"0.004\", \"]\"}], \",\", \n"); mfprintf(a," RowBox[{\"RGBColor\", \"[\", \n"); mfprintf(a," RowBox[{\"0\", \",\", \"0\", \",\", \"0\"}], \"]\"}]}], \"}\"}], \"]\"}], \",\", \n"); mfprintf(a," RowBox[{\"RGBColor\", \"[\", \n"); mfprintf(a," RowBox[{\"0\", \",\", \"1\", \",\", \"0\"}], \"]\"}], \",\", \n"); mfprintf(a," RowBox[{\"Opacity\", \"[\", \"1\", \"]\"}], \",\", \n"); mfprintf(a," RowBox[{\"Disk\", \"[\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"{\", \n"); mfprintf(a," RowBox[{\"%f\", \",\", \"%f\"}], \"}\"}], \",\", RowBox[{\"{\", RowBox[{\"%f\", \",\", \"%f\"}], \"}\"}]}], \"]\"}]}], \"}\"}], \n",m_fMinVal[0]+(m_fMaxVal[0]-m_fMinVal[0])*0.41666,(m_fMaxVal[0]-m_fMinVal[0])*0.0625,(m_fMaxVal[0]-m_fMinVal[0])*0.0625,(m_fMaxVal[1]-m_fMinVal[1])*0.0625); mfprintf(a," \"]\"}]}], \"]\"}], \";\"}], \"*)\"}]\n"); if (m_oaCircles.GetSize() > 0) { mfprintf(a,",\"\\[IndentingNewLine]\", \n"); mfprintf(a,"RowBox[{\n"); for (z=0;zm_fColorR,((CMathematicaCircle*)m_oaCircles[z])->m_fColorG,((CMathematicaCircle*)m_oaCircles[z])->m_fColorB); mfprintf(a," RowBox[{\"Opacity\", \"[\", \"1\", \"]\"}], \",\", \n"); mfprintf(a," RowBox[{\"Disk\", \"[\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"{\", \n"); mfprintf(a," RowBox[{\"%f\", \",\", \"%f\"}], \"}\"}], \",\", \"%f\"}], \"]\"}]}], \"}\"}], \n",((CMathematicaCircle*)m_oaCircles[z])->m_fPosX,((CMathematicaCircle*)m_oaCircles[z])->m_fPosY,((CMathematicaCircle*)m_oaCircles[z])->m_fRadius); mfprintf(a," \"]\"}]}], \"]\"}], \";\"}]"); if (z < m_oaCircles.GetSize()-1) mfprintf(a,", \"\\[IndentingNewLine]\", "); mfprintf(a,"\n"); } mfprintf(a,"}]\n"); } mfprintf(a,"}]], \"Input\"]\n"); mfprintf(a,"}, Closed ]],\n"); mfprintf(a,"\n"); mfprintf(a,"Cell[CellGroupData[{\n"); mfprintf(a,"\n"); mfprintf(a,"Cell[\"Line Drawing\", \"Subsection\",\n"); mfprintf(a," CellDingbat->DynamicModuleBox[{$CellContext`state$$ = False},\n"); mfprintf(a," OpenerBox[\n"); mfprintf(a," Dynamic[$CellContext`state$$, (FrontEndExecute[{\n"); mfprintf(a," FrontEnd`SelectionMove[\n"); mfprintf(a," FrontEnd`ButtonNotebook[], All, ButtonCell], \n"); mfprintf(a," FrontEndToken[\"OpenCloseGroup\"]}]; $CellContext`state$$ = #)& ]], \n"); mfprintf(a," DynamicModuleValues :> {}]],\n"); mfprintf(a,"\n"); mfprintf(a,"Cell[BoxData[\n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"(*\", \" \", \n"); mfprintf(a," RowBox[{\"Draw\", \" \", \n"); mfprintf(a," RowBox[{\"Lines\", \".\", \" \", \"Uncomment\"}], \" \", \"the\", \" \", \"example\", \" \",\n"); mfprintf(a," \"below\", \" \", \"and\", \" \", \"try\", \" \", \"it\", \" \", \n"); mfprintf(a," RowBox[{\"out\", \".\"}]}], \" \", \"*)\"}], \"\\[IndentingNewLine]\", \n"); mfprintf(a," RowBox[{\"(*\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"AppendTo\", \"[\", \n"); mfprintf(a," RowBox[{\"prim\", \",\", \n"); mfprintf(a," RowBox[{\"Graphics\", \"[\", \n"); mfprintf(a," RowBox[{\"{\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"Thickness\", \"[\", \"0.01\", \"]\"}], \",\", \n"); mfprintf(a," RowBox[{\"RGBColor\", \"[\", \n"); mfprintf(a," RowBox[{\"0\", \",\", \"0\", \",\", \"1\"}], \"]\"}], \",\", \n"); mfprintf(a," RowBox[{\"Dashing\", \"[\", \"1000\", \"]\"}], \",\", \n"); mfprintf(a," RowBox[{\"Line\", \"[\", \n"); mfprintf(a," RowBox[{\"{\", \n"); mfprintf(a," RowBox[{\n"); mfprintf(a," RowBox[{\"{\", \n"); mfprintf(a," RowBox[{\"%f\", \",\", \"%f\"}], \"}\"}], \",\", \n",m_fMinVal[0],m_fMinVal[1]); mfprintf(a," RowBox[{\"{\", \n"); mfprintf(a," RowBox[{\"%f\", \",\", \"%f\"}], \"}\"}], \",\", \n",m_fMaxVal[0]*0.4,m_fMaxVal[1]*0.8); mfprintf(a," RowBox[{\"{\", \n"); mfprintf(a," RowBox[{\"%f\", \",\", \"%f\"}], \"}\"}]}], \"}\"}], \"]\"}]}],\n",m_fMaxVal[0]*0.4,m_fMinVal[1]); mfprintf(a," \"}\"}], \"]\"}]}], \"]\"}], \";\"}], \"*)\"}]}]], \"Input\"]\n"); mfprintf(a,"}, Closed]]\n"); mfprintf(a,"}, Closed]],\n"); mfprintf(a,"\n"); mfprintf(a,"Cell[CellGroupData[{\n"); mfprintf(a,"\n"); mfprintf(a,"Cell[\"\\<\\\n"); mfprintf(a,"Plot output. Click \\\"Evaluation -> Evaluate Notebook\\\" to draw/redraw!\\\n"); mfprintf(a,"\\>\", \"Section\",\n"); mfprintf(a," CellDingbat->DynamicModuleBox[{$CellContext`state$$ = True}, \n"); mfprintf(a," OpenerBox[\n"); mfprintf(a," Dynamic[$CellContext`state$$, (FrontEndExecute[{\n"); mfprintf(a," FrontEnd`SelectionMove[\n"); mfprintf(a," FrontEnd`ButtonNotebook[], All, ButtonCell], \n"); mfprintf(a," FrontEndToken[\"OpenCloseGroup\"]}]; $CellContext`state$$ = #)& ]], \n"); mfprintf(a," DynamicModuleValues :> {}]],\n"); mfprintf(a,"\n"); mfprintf(a,"Cell[BoxData[\"plot\"], \"Input\"],\n"); mfprintf(a,"\n"); mfprintf(a,"Cell[BoxData[\"plotlegend\"], \"Input\"]\n"); mfprintf(a,"}, Open ]]\n"); mfprintf(a,"}\n"); mfprintf(a,"]\n"); fclose(a); BTOUT; } void C2DF::NormRDF(double n) { BTIN; int x, y; double f; for (y=0;y m_fMaxEntry) m_fMaxEntry = m_pBin[z*m_iRes[0]+z2]; if (m_pBin[z*m_iRes[0]+z2] < m_fMinEntry) m_fMinEntry = m_pBin[z*m_iRes[0]+z2]; } } if (fabs(m_fMinEntry) > m_fMaxEntry) a = fabs(m_fMinEntry); else a = m_fMaxEntry; m_fEps = nextafter(a,2.0*a) - a; BTOUT; } void C2DF::SetLabelX(const char *s) { if (m_sLabelX != NULL) delete[] m_sLabelX; try { m_sLabelX = new char[strlen(s)+1]; } catch(...) { m_sLabelX = NULL; } if (m_sLabelX == NULL) NewException((double)(strlen(s)+1)*sizeof(char),__FILE__,__LINE__,__PRETTY_FUNCTION__); strcpy(m_sLabelX,s); } void C2DF::SetLabelY(const char *s) { if (m_sLabelY != NULL) delete[] m_sLabelY; try { m_sLabelY = new char[strlen(s)+1]; } catch(...) { m_sLabelY = NULL; } if (m_sLabelY == NULL) NewException((double)(strlen(s)+1)*sizeof(char),__FILE__,__LINE__,__PRETTY_FUNCTION__); strcpy(m_sLabelY,s); } void C2DF::SetLabelZ(const char *s) { if (m_sLabelZ != NULL) delete[] m_sLabelZ; try { m_sLabelZ = new char[strlen(s)+1]; } catch(...) { m_sLabelZ = NULL; } if (m_sLabelZ == NULL) NewException((double)(strlen(s)+1)*sizeof(char),__FILE__,__LINE__,__PRETTY_FUNCTION__); strcpy(m_sLabelZ,s); } void C2DF::MakeTensorProduct(C2DF *inp) { int x, y; double tf, *px, *py; try { px = new double[m_iRes[0]]; } catch(...) { px = NULL; } if (px == NULL) NewException((double)m_iRes[0]*sizeof(double),__FILE__,__LINE__,__PRETTY_FUNCTION__); try { py = new double[m_iRes[1]]; } catch(...) { py = NULL; } if (py == NULL) NewException((double)m_iRes[1]*sizeof(double),__FILE__,__LINE__,__PRETTY_FUNCTION__); for (y=0;ym_pBin[y*m_iRes[0]+x]; tf /= (double)m_iRes[0]; py[y] = tf; } for (x=0;xm_pBin[y*m_iRes[0]+x]; tf /= (double)m_iRes[1]; px[x] = tf; } for (x=0;xm_sLabelX != NULL) { try { m_sLabelX = new char[strlen(df->m_sLabelX)+1]; } catch(...) { m_sLabelX = NULL; } if (m_sLabelX == NULL) NewException((double)(strlen(df->m_sLabelX)+1)*sizeof(char),__FILE__,__LINE__,__PRETTY_FUNCTION__); strcpy(m_sLabelX,df->m_sLabelX); } if (df->m_sLabelY != NULL) { try { m_sLabelY = new char[strlen(df->m_sLabelY)+1]; } catch(...) { m_sLabelY = NULL; } if (m_sLabelY == NULL) NewException((double)(strlen(df->m_sLabelY)+1)*sizeof(char),__FILE__,__LINE__,__PRETTY_FUNCTION__); strcpy(m_sLabelY,df->m_sLabelY); } if (df->m_sLabelZ != NULL) { try { m_sLabelZ = new char[strlen(df->m_sLabelZ)+1]; } catch(...) { m_sLabelZ = NULL; } if (m_sLabelZ == NULL) NewException((double)(strlen(df->m_sLabelZ)+1)*sizeof(char),__FILE__,__LINE__,__PRETTY_FUNCTION__); strcpy(m_sLabelZ,df->m_sLabelZ); } m_iRes[0] = df->m_iRes[0]; m_iRes[1] = df->m_iRes[1]; m_fMinVal[0] = df->m_fMinVal[0]; m_fMinVal[1] = df->m_fMinVal[1]; m_fMaxVal[0] = df->m_fMaxVal[0]; m_fMaxVal[1] = df->m_fMaxVal[1]; try { m_fCountX = new double[m_iRes[0]]; } catch(...) { m_fCountX = NULL; } if (m_fCountX == NULL) NewException((double)m_iRes[0]*sizeof(double),__FILE__,__LINE__,__PRETTY_FUNCTION__); try { m_fCountY = new double[m_iRes[1]]; } catch(...) { m_fCountY = NULL; } if (m_fCountY == NULL) NewException((double)m_iRes[1]*sizeof(double),__FILE__,__LINE__,__PRETTY_FUNCTION__); try { m_pStepsY = new unsigned long[m_iRes[1]]; } catch(...) { m_pStepsY = NULL; } if (m_pStepsY == NULL) NewException((double)m_iRes[0]*sizeof(unsigned long),__FILE__,__LINE__,__PRETTY_FUNCTION__); for (z=0;zm_fCountX[z]; for (z=0;zm_fCountY[z]; m_pStepsY[z] = df->m_pStepsY[z]; } try { m_pBin = new double[m_iRes[0]*m_iRes[1]]; } catch(...) { m_pBin = NULL; } if (m_pBin == NULL) NewException((double)m_iRes[0]*m_iRes[1]*sizeof(double),__FILE__,__LINE__,__PRETTY_FUNCTION__); for (z=0;zm_pBin[z]; m_fFac[0] = m_iRes[0] / (m_fMaxVal[0]-m_fMinVal[0]); m_fFac[1] = m_iRes[1] / (m_fMaxVal[1]-m_fMinVal[1]); m_fBinEntries = df->m_fBinEntries; m_fSkipEntries = df->m_fSkipEntries; // m_fMathematicaColorScale = df->m_fMathematicaColorScale; // m_fMathematicaColorOffset = df->m_fMathematicaColorOffset; m_pChannels[0] = df->m_pChannels[0]; m_pChannels[1] = df->m_pChannels[1]; } void C2DF::Subtract(C2DF *df) { int z; if ((m_iRes[0] != df->m_iRes[0]) || (m_iRes[1] != df->m_iRes[1])) { eprintf("C2DF::Subtract(C2DF*): Resolution of CDFs must be identical.\n"); return; } for (z=0;zm_pBin[z]; } void C2DF::WriteCombinedPlot(const char *prefix, const char *name, const char *suffix) { CGrace *comb; // char buf[32768]; CxString buf; int z; try { comb = new CGrace(); } catch(...) { comb = NULL; } if (comb == NULL) NewException((double)sizeof(CGrace),__FILE__,__LINE__,__PRETTY_FUNCTION__); m_pChannels[0]->CalcMinMax(); m_pChannels[1]->CalcMinMax(); comb->SetViewport(0.15,0.8,0.8,0.95); comb->CurrentGraph()->m_bTicks = false; comb->CurrentGraph()->m_bTickLabels = false; comb->CurrentGraph()->m_fFrameWidth = 0.5; comb->SetRangeX(m_pChannels[0]->m_fMinVal,m_pChannels[0]->m_fMaxVal); comb->SetRangeY(/*m_pChannels[0]->m_fMinEntry*/0.0,m_pChannels[0]->m_fMaxEntry+(m_pChannels[0]->m_fMaxEntry/*-m_pChannels[0]->m_fMinEntry*/)*0.1); comb->MakeTicks(); if (g_iObsChannel[0] == 0) // RDF comb->AddLine(m_pChannels[0]->m_fMinVal,1,m_pChannels[0]->m_fMaxVal,1,1,1); comb->AddDataset(); comb->CurrentGraph()->CurrentDataset()->m_faValues.SetMaxSize(m_pChannels[0]->m_iResolution*2); for (z=0;zm_iResolution-1;z++) comb->AddXYTupel(0,m_pChannels[0]->m_fMinVal+(z+0.5)*(m_pChannels[0]->m_fMaxVal-m_pChannels[0]->m_fMinVal)/m_pChannels[0]->m_iResolution,m_pChannels[0]->m_pBin[z]); comb->AddGraph(); comb->SetViewport(0.8, 0.15, 0.95, 0.8); comb->CurrentGraph()->m_bTicks = false; comb->CurrentGraph()->m_bTickLabels = false; comb->CurrentGraph()->m_fFrameWidth = 0.5; comb->SetRangeX(/*m_pChannels[1]->m_fMinEntry*/0.0,m_pChannels[1]->m_fMaxEntry+(m_pChannels[1]->m_fMaxEntry/*-m_pChannels[1]->m_fMinEntry*/)*0.1); comb->SetRangeY(m_pChannels[1]->m_fMinVal,m_pChannels[1]->m_fMaxVal); comb->MakeTicks(); if (g_iObsChannel[1] == 0) // RDF comb->AddLine(1,m_pChannels[1]->m_fMinVal,1,m_pChannels[1]->m_fMaxVal,1,1); comb->AddDataset(); comb->CurrentGraph()->CurrentDataset()->m_faValues.SetMaxSize(m_pChannels[1]->m_iResolution*2); for (z=0;zm_iResolution-1;z++) comb->AddXYTupel(0,m_pChannels[1]->m_pBin[z],m_pChannels[1]->m_fMinVal+(z+0.5)*(m_pChannels[1]->m_fMaxVal-m_pChannels[1]->m_fMinVal)/m_pChannels[1]->m_iResolution); comb->AddGraph(); comb->SetViewport(0.15, 0.15, 0.8, 0.8); comb->CurrentGraph()->m_bTicksBothSidesX = true; comb->CurrentGraph()->m_bTicksBothSidesY = true; comb->CurrentGraph()->m_bTickInX = false; comb->CurrentGraph()->m_bTickInY = false; comb->SetLabelX(m_sLabelX); comb->SetLabelY(m_sLabelY); comb->SetRangeX(m_pChannels[0]->m_fMinVal,m_pChannels[0]->m_fMaxVal); comb->SetRangeY(m_pChannels[1]->m_fMinVal,m_pChannels[1]->m_fMaxVal); comb->MakeTicks(); comb->AddDataset(); /* strcpy(buf,prefix); strcat(buf,name); strcat(buf,suffix);*/ buf.strcpy(prefix); buf.strcat(name); buf.strcat(suffix); comb->WriteAgr(buf,false); } void C2DF::Mirror(double plane, int channel) { int x, y, t; double *tbin, p; try { tbin = new double[m_iRes[0]*m_iRes[1]]; } catch(...) { tbin = NULL; } if (tbin == NULL) NewException((double)m_iRes[0]*m_iRes[1]*sizeof(double),__FILE__,__LINE__,__PRETTY_FUNCTION__); if (channel == 0) { p = (plane-m_fMinVal[0])*m_fFac[0]; for (x=0;x= 0) && (t < m_iRes[0])) { tbin[y*m_iRes[0]+x] += m_pBin[y*m_iRes[0]+t]; tbin[y*m_iRes[0]+x] /= 2.0; } } } } else if (channel == 1) { p = (plane-m_fMinVal[1])*m_fFac[1]; for (x=0;x= 0) && (t < m_iRes[1])) { tbin[y*m_iRes[0]+x] += m_pBin[t*m_iRes[0]+x]; tbin[y*m_iRes[0]+x] /= 2.0; } } } } delete[] m_pBin; m_pBin = tbin; } void C2DF::SwapAxes() { char *t; int x, y; double *pd; double d; int i; CDF *df; t = m_sLabelX; m_sLabelX = m_sLabelY; m_sLabelY = t; try { pd = new double[m_iRes[0]*m_iRes[1]]; } catch(...) { pd = NULL; } if (pd == NULL) NewException((double)m_iRes[0]*m_iRes[1]*sizeof(double),__FILE__,__LINE__,__PRETTY_FUNCTION__); for (y=0;ym_fPosX = x; c->m_fPosY = y; c->m_fRadius = r; c->m_fColorR = cr; c->m_fColorG = cg; c->m_fColorB = cb; m_oaCircles.Add(c); } double C2DF::GetValue(double x, double y) { BXIN; double rx, ry, r; int ix, iy; if ((x < m_fMinVal[0]) || (y < m_fMinVal[1]) || (x > m_fMaxVal[0]) || (y > m_fMaxVal[1])) { BXOUT; return 0; } rx = (x-m_fMinVal[0])*m_fFac[0] - 0.5; ix = (int)floor(rx); if (ix < 0) { ix = 0; rx = 0; } else if (ix > m_iRes[0]-2) { ix = m_iRes[0]-2; rx = 1.0; } else rx -= ix; ry = (y-m_fMinVal[1])*m_fFac[1] - 0.5; iy = (int)floor(ry); if (iy < 0) { iy = 0; ry = 0; } else if (iy > m_iRes[1]-2) { iy = m_iRes[1]-2; ry = 1.0; } else ry -= iy; r = m_pBin[ iy * m_iRes[0] + ix ] * (1.0-rx) * (1.0-ry); r += m_pBin[ iy * m_iRes[0] + ix + 1] * rx * (1.0-ry); r += m_pBin[(iy+1) * m_iRes[0] + ix ] * (1.0-rx) * ry; r += m_pBin[(iy+1) * m_iRes[0] + ix + 1] * rx * ry; BXOUT; return r; } void C2DF::AddToBin(int x, int y, double val) { BXIN; m_fBinEntries++; m_pBin[y*m_iRes[0] + x] += val; m_fCountX[x]++; m_fCountY[y]++; BXOUT; } void C2DF::CalcHistogram() { int z, z2, t; CalcMaxEntry(); try { m_pHistogram = new double[m_iHistogramRes]; } catch(...) { m_pHistogram = NULL; } if (m_pHistogram == NULL) NewException((double)m_iHistogramRes*sizeof(double),__FILE__,__LINE__,__PRETTY_FUNCTION__); for (z=0;z= 1.0E-10) m_pBin[z] = log10(m_pBin[z])+10.0; else m_pBin[z] = 0; } } void C2DF::NormalizeUniform(double fac) { int zx, zy; double r1, r2, a1, a2, dca, vol; for (zy=0;zy. *****************************************************************************/ #ifndef _2DF_H #define _2DF_H // This must always be the first include directive #include "config.h" #include #include #include "xdvector3.h" #include "xdoublearray.h" #include "backtrace.h" #include "df.h" class CMathematicaCircle : public CxObject { public: CMathematicaCircle() { } ~CMathematicaCircle() { } double m_fPosX, m_fPosY, m_fRadius; double m_fColorR, m_fColorG, m_fColorB; }; class C2DF : public CxObject { public: double CalcCorrelationFactor(); void NormalizeUniform(double fac); void Log(); void WriteHistogram(const char *prefix, const char *name, const char *suffix); void CalcHistogram(); double GetValue(double x, double y); void AddCircle(double x, double y, double r, double cr, double cg, double cb); void NormalizeYCount(); void NormalizeXCount(); void SwapAxes(); void Mirror(double plane, int channel); void WriteCombinedPlot(const char *prefix, const char *name, const char *suffix); // double m_fMathematicaColorOffset; // double m_fMathematicaColorScale; void Subtract(C2DF *df); void CopyFrom(C2DF *df); void MakeTensorProduct(C2DF *inp); void SetLabelX(const char *s); void SetLabelY(const char *s); void SetLabelZ(const char *s); void CalcMaxEntry(); void StepY(int y); void NormRDF(double n); C2DF(); ~C2DF(); void MultiplyBin(double m); // void AddToBin(double x, const CxVector3 &vec); void AddToBin(double x, double y); // void AddToBin(double x, int y); void AddToBin(int x, int y, double val); void AddToBin(double x, double y, double val); void AddToBin_IntX(int x, double y, double val); void AddToBin_IntY(double x, int y, double val); void AddToBin_IntY(double x, int y); // void AddToBin_IntX_fast(int x, double y); // void AddToSingleBin(double x, double y, double val); void NormalizeBin(double mi, double ma); double NormalizeBinIntegral(double val); double PPMBin(); void Write(const char *prefix, const char *name, const char *suffix); void WriteGraceBunch(int channel, int graphs, double fac, const char *prefix, const char *name, const char *suffix); void WriteCSV(const char *prefix, const char *name, const char *suffix); void WriteXProjection(const char *prefix, const char *name, const char *suffix); void WriteYProjection(const char *prefix, const char *name, const char *suffix); void WriteMathematica(const char *prefix, const char *name, const char *suffix); void WriteGnuplotInput(const char *prefix, const char *name, const char *suffix, bool manrange, bool printinfo=true); void WriteMathematicaNb(const char *prefix, const char *name, const char *suffix, bool manrange, bool printinfo=true); void Create(); void CorrectRadialDist(int channel); void CorrectLiRadialDist(int channel); void UnCorrectRadialDist(int channel); void CorrectAngle(int channel); void UnCorrectAngle(int channel); // void AngleCorrectX(); double m_fMinVal[2]; double m_fMaxVal[2]; double m_fFac[2]; CDF *m_pChannels[2]; double m_fAspectRatio; double m_fMinEntry; double m_fMaxEntry; char *m_sLabelX; char *m_sLabelY; char *m_sLabelZ; char* m_sName; char* m_sShortName; double *m_fCountX; double *m_fCountY; int m_iRes[2]; int m_iHistogramRes; double *m_pBin; double *m_pHistogram; double m_fBinEntries; double m_fSkipEntries; unsigned long *m_pStepsY; int m_iPlotType; int m_iSmoothGrade; int m_iInterpolationOrder; double m_fPlotExp; unsigned long m_iContourLines; bool m_bDrawMesh; int m_iExpLegend; int m_iColorScale; int m_iGPInterpolation; bool m_bContourLines; int m_iPlotPixel; double m_fEps; CxObArray m_oaCircles; void AddToBin_IntX_fast(int x, double y) { double ry; int iy; if (y > m_fMaxVal[1]) return; m_fBinEntries++; ry = (y-m_fMinVal[1])*m_fFac[1] - 0.5; iy = (int)floor(ry); if (iy < 0) { iy = 0; ry = 0; } else if (iy > m_iRes[1]-2) { iy = m_iRes[1]-2; ry = 1.0; } else ry -= iy; m_pBin[ iy * m_iRes[0] + x] += (1.0-ry); m_pBin[(iy+1) * m_iRes[0] + x] += ry ; } }; /*inline void C2DF::AddToBin(double x, int y) { BXIN; double rx; int ix; if ((x < m_fMinVal[0]) || (x > m_fMaxVal[0])) { m_fSkipEntries++; BXOUT; return; } m_fBinEntries++; rx = ((x-m_fMinVal[0])/(m_fMaxVal[0]-m_fMinVal[0]))*((double)m_iRes[0]-1); ix = (int)floor(rx); rx -= ix; m_pBin[y*m_iRes[0] + ix] += 1-rx; m_pBin[y*m_iRes[0] + ix +1] += rx; m_fCountX[ix] += 1.0-rx; m_fCountX[ix+1] += rx; m_fCountY[y]++; BXOUT; }*/ #endif travis-src-190101/src/3df.h0100777000000000000000000014237513412725663012303 0ustar00/***************************************************************************** TRAVIS - Trajectory Analyzer and Visualizer http://www.travis-analyzer.de/ Copyright (c) 2009-2019 Martin Brehm 2012-2019 Martin Thomas 2016-2019 Sascha Gehrke This file was written by Martin Brehm. --------------------------------------------------------------------------- This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . *****************************************************************************/ #ifndef _3DF_H #define _3DF_H // This must always be the first include directive #include "config.h" #include "xobject.h" #include "df.h" #include "2df.h" #include "xmemfile.h" #include "xstring.h" #include "bqb.h" #include "fastatof.h" extern int g_iCubeXStride; extern int g_iCubeYStride; extern int g_iCubeZStride; extern int g_iCubeXMismatch; extern int g_iCubeYMismatch; extern int g_iCubeZMismatch; extern double g_fBoxX; extern double g_fBoxY; extern double g_fBoxZ; extern double g_fCubeXStep; extern double g_fCubeYStep; extern double g_fCubeZStep; template class C3DF : public CxObject { public: void AddToBin(const CxDVector3 &vec) { AddToBin(vec[0],vec[1],vec[2]); } void AddToBin_Sphere(const CxDVector3 &vec, double r) { AddToBin_Sphere(vec[0],vec[1],vec[2],r); } void AddToBin_SphereWrap(const CxDVector3 &vec, double r) { AddToBin_SphereWrap(vec[0],vec[1],vec[2],r); } void AddToBin_Single(double x, double y, double z, T val) { int ix, iy, iz; if ((x < m_fMinVal[0]) || (x > m_fMaxVal[0]) || (y < m_fMinVal[1]) || (y > m_fMaxVal[1]) || (z < m_fMinVal[2]) || (z > m_fMaxVal[2])) return; ix = (int)floor((x-m_fMinVal[0])*m_fFac[0]); if (ix < 0) ix = 0; if (ix >= m_iRes[0]) ix = m_iRes[0] - 1; iy = (int)floor((y-m_fMinVal[1])*m_fFac[1]); if (iy < 0) iy = 0; if (iy >= m_iRes[1]) iy = m_iRes[1] - 1; iz = (int)floor((z-m_fMinVal[2])*m_fFac[2]); if (iz < 0) iz = 0; if (iz >= m_iRes[2]) iz = m_iRes[2] - 1; m_pBin[ iz*m_iResXY + iy*m_iRes[0] + ix ] += val; } T GetBinValue_Single(double x, double y, double z) const { int ix, iy, iz; if ((x < m_fMinVal[0]) || (x > m_fMaxVal[0]) || (y < m_fMinVal[1]) || (y > m_fMaxVal[1]) || (z < m_fMinVal[2]) || (z > m_fMaxVal[2])) return -1; ix = (int)floor((x-m_fMinVal[0])*m_fFac[0]); if (ix < 0) ix = 0; if (ix >= m_iRes[0]) ix = m_iRes[0] - 1; iy = (int)floor((y-m_fMinVal[1])*m_fFac[1]); if (iy < 0) iy = 0; if (iy >= m_iRes[1]) iy = m_iRes[1] - 1; iz = (int)floor((z-m_fMinVal[2])*m_fFac[2]); if (iz < 0) iz = 0; if (iz >= m_iRes[2]) iz = m_iRes[2] - 1; return m_pBin[ iz*m_iResXY + iy*m_iRes[0] + ix ]; } void SetBinValue_Single(double x, double y, double z, T val) { int ix, iy, iz; if ((x < m_fMinVal[0]) || (x > m_fMaxVal[0]) || (y < m_fMinVal[1]) || (y > m_fMaxVal[1]) || (z < m_fMinVal[2]) || (z > m_fMaxVal[2])) return; ix = (int)floor((x-m_fMinVal[0])*m_fFac[0]); if (ix < 0) ix = 0; if (ix >= m_iRes[0]) ix = m_iRes[0] - 1; iy = (int)floor((y-m_fMinVal[1])*m_fFac[1]); if (iy < 0) iy = 0; if (iy >= m_iRes[1]) iy = m_iRes[1] - 1; iz = (int)floor((z-m_fMinVal[2])*m_fFac[2]); if (iz < 0) iz = 0; if (iz >= m_iRes[2]) iz = m_iRes[2] - 1; m_pBin[ iz*m_iResXY + iy*m_iRes[0] + ix ] = val; } double m_fMinVal[3]; double m_fMaxVal[3]; CDF *m_pChannels[3]; C2DF *m_p2DF[3]; T m_fMinEntry; T m_fMaxEntry; char *m_sLabelX; char *m_sLabelY; char *m_sLabelZ; double *m_fCountX; double *m_fCountY; double *m_fCountZ; int m_iRes[3]; int m_iHistogramRes; long m_iResXY; double m_fBinEntries; double m_fSkipEntries; T *m_pBin; double *m_pHistogram; double m_fFac[3]; double m_fEps; /******************************************************************************************/ C3DF() { m_sLabelX = NULL; m_sLabelY = NULL; m_sLabelZ = NULL; m_pBin = NULL; m_fCountX = NULL; m_fCountY = NULL; m_fCountZ = NULL; m_iHistogramRes = 0; m_pHistogram = NULL; } ~C3DF() { if (m_sLabelX != NULL) { delete[] m_sLabelX; m_sLabelX = NULL; } if (m_sLabelY != NULL) { delete[] m_sLabelY; m_sLabelY = NULL; } if (m_sLabelZ != NULL) { delete[] m_sLabelZ; m_sLabelZ = NULL; } if (m_pBin != NULL) { delete[] m_pBin; m_pBin = NULL; } if (m_fCountX != NULL) { delete[] m_fCountX; m_fCountX = NULL; } if (m_fCountY != NULL) { delete[] m_fCountY; m_fCountY = NULL; } if (m_fCountZ != NULL) { delete[] m_fCountZ; m_fCountZ = NULL; } } void Create() { BTIN; int z; m_fBinEntries = 0; m_fSkipEntries = 0; if (m_fCountX != NULL) delete[] m_fCountX; try { m_fCountX = new double[m_iRes[0]]; } catch(...) { m_fCountX = NULL; } if (m_fCountX == NULL) NewException((double)m_iRes[0]*sizeof(double),__FILE__,__LINE__,__PRETTY_FUNCTION__); if (m_fCountY != NULL) delete[] m_fCountY; try { m_fCountY = new double[m_iRes[1]]; } catch(...) { m_fCountY = NULL; } if (m_fCountY == NULL) NewException((double)m_iRes[1]*sizeof(double),__FILE__,__LINE__,__PRETTY_FUNCTION__); if (m_fCountZ != NULL) delete[] m_fCountZ; try { m_fCountZ = new double[m_iRes[2]]; } catch(...) { m_fCountZ = NULL; } if (m_fCountZ == NULL) NewException((double)m_iRes[2]*sizeof(double),__FILE__,__LINE__,__PRETTY_FUNCTION__); for (z=0;z m_fMaxVal[0]) || (y < m_fMinVal[1]) || (y > m_fMaxVal[1]) || (z < m_fMinVal[2]) || (z > m_fMaxVal[2])) { m_fSkipEntries++; BXOUT; return; } m_fBinEntries++; rx = (T)((x-m_fMinVal[0])*m_fFac[0] - 0.5); ix = (int)floor(rx); if (ix < 0) { ix = 0; rx = 0; } else if (ix > m_iRes[0]-2) { ix = m_iRes[0]-2; rx = 1.0; } else rx -= ix; ry = (T)((y-m_fMinVal[1])*m_fFac[1] - 0.5); iy = (int)floor(ry); if (iy < 0) { iy = 0; ry = 0; } else if (iy > m_iRes[1]-2) { iy = m_iRes[1]-2; ry = 1.0; } else ry -= iy; rz = (T)((z-m_fMinVal[2])*m_fFac[2] - 0.5); iz = (int)floor(rz); if (iz < 0) { iz = 0; rz = 0; } else if (iz > m_iRes[2]-2) { iz = m_iRes[2]-2; rz = 1.0; } else rz -= iz; m_pBin[ iz * m_iResXY + iy * m_iRes[0] + ix ] += ((T)(1.0)-rx) * ((T)(1.0)-ry) * ((T)(1.0)-rz); m_pBin[ iz * m_iResXY + iy * m_iRes[0] + ix + 1] += rx * ((T)(1.0)-ry) * ((T)(1.0)-rz); m_pBin[ iz * m_iResXY + (iy+1) * m_iRes[0] + ix ] += ((T)(1.0)-rx) * ry * ((T)(1.0)-rz); m_pBin[ iz * m_iResXY + (iy+1) * m_iRes[0] + ix + 1] += rx * ry * ((T)(1.0)-rz); m_pBin[(iz+1) * m_iResXY + iy * m_iRes[0] + ix ] += ((T)(1.0)-rx) * ((T)(1.0)-ry) * rz; m_pBin[(iz+1) * m_iResXY + iy * m_iRes[0] + ix + 1] += rx * ((T)(1.0)-ry) * rz; m_pBin[(iz+1) * m_iResXY + (iy+1) * m_iRes[0] + ix ] += ((T)(1.0)-rx) * ry * rz; m_pBin[(iz+1) * m_iResXY + (iy+1) * m_iRes[0] + ix + 1] += rx * ry * rz; BXOUT; } void AddToBin_Sphere(double x, double y, double z, double r) { BXIN; int ix, iy, iz, k, kq, zx, zy, zz, zzq, zyq, tz, ty; if ((x < m_fMinVal[0]) || (x > m_fMaxVal[0]) || (y < m_fMinVal[1]) || (y > m_fMaxVal[1]) || (z < m_fMinVal[2]) || (z > m_fMaxVal[2])) { m_fSkipEntries++; BXOUT; return; } m_fBinEntries++; ix = (int)floor((x-m_fMinVal[0])*m_fFac[0]); iy = (int)floor((y-m_fMinVal[1])*m_fFac[1]); iz = (int)floor((z-m_fMinVal[2])*m_fFac[2]); k = (int)ceil(r * m_fFac[0] - 1.0); kq = k * k; for (zz=-k;zz<=k;zz++) { if (zz+iz < 0) continue; if (zz+iz >= m_iRes[2]) continue; tz = (zz+iz) * m_iResXY; zzq = zz * zz; for (zy=-k;zy<=k;zy++) { if (zy+iy < 0) continue; if (zy+iy >= m_iRes[1]) continue; ty = ix + tz + (zy+iy) * m_iRes[0]; zyq = zzq + zy*zy; for (zx=-k;zx<=k;zx++) { if (zx+ix < 0) continue; if (zx+ix >= m_iRes[0]) continue; if (zyq + zx*zx <= kq) m_pBin[ty+zx]++; } } } BXOUT; } void AddToBin_SphereWrap(double x, double y, double z, double r) { BXIN; int ix, iy, iz, k, kq, zx, zy, zz, zzq, zyq, tz, ty; if ((x < m_fMinVal[0]) || (x > m_fMaxVal[0]) || (y < m_fMinVal[1]) || (y > m_fMaxVal[1]) || (z < m_fMinVal[2]) || (z > m_fMaxVal[2])) { m_fSkipEntries++; BXOUT; return; } m_fBinEntries++; ix = (int)floor((x-m_fMinVal[0])*m_fFac[0]); iy = (int)floor((y-m_fMinVal[1])*m_fFac[1]); iz = (int)floor((z-m_fMinVal[2])*m_fFac[2]); k = (int)ceil(r * m_fFac[0] - 1.0); kq = k * k; for (zz=-k;zz<=k;zz++) { if (zz+iz < 0) tz = (zz+iz+m_iRes[2]) * m_iResXY; else if (zz+iz >= m_iRes[2]) tz = (zz+iz-m_iRes[2]) * m_iResXY; else tz = (zz+iz) * m_iResXY; zzq = zz * zz; for (zy=-k;zy<=k;zy++) { if (zy+iy < 0) ty = tz + (zy+iy+m_iRes[1]) * m_iRes[0]; else if (zy+iy >= m_iRes[1]) ty = tz + (zy+iy-m_iRes[1]) * m_iRes[0]; else ty = tz + (zy+iy) * m_iRes[0]; zyq = zzq + zy*zy; for (zx=-k;zx<=k;zx++) { if (zyq + zx*zx > kq) continue; if (zx+ix < 0) m_pBin[ty+ix+zx+m_iRes[0]]++; else if (zx+ix >= m_iRes[0]) m_pBin[ty+ix+zx-m_iRes[0]]++; else m_pBin[ty+ix+zx]++; } } } BXOUT; } void AddToBin_IntZ(double x, double y, int z) { BXIN; double rx, ry; int ix, iy; if ((x < m_fMinVal[0]) || (x > m_fMaxVal[0]) || (y < m_fMinVal[1]) || (y > m_fMaxVal[1])) { m_fSkipEntries++; BXOUT; return; } m_fBinEntries++; rx = (x-m_fMinVal[0])*m_fFac[0] - 0.5; ix = (int)floor(rx); if (ix < 0) { ix = 0; rx = 0; } else if (ix > m_iRes[0]-2) { ix = m_iRes[0]-2; rx = 1.0; } else rx -= ix; ry = (y-m_fMinVal[1])*m_fFac[1] - 0.5; iy = (int)floor(ry); if (iy < 0) { iy = 0; ry = 0; } else if (iy > m_iRes[1]-2) { iy = m_iRes[1]-2; ry = 1.0; } else ry -= iy; m_pBin[z * m_iResXY + iy * m_iRes[0] + ix ] += (1.0-rx) * (1.0-ry); m_pBin[z * m_iResXY + iy * m_iRes[0] + ix + 1] += rx * (1.0-ry); m_pBin[z * m_iResXY + (iy+1) * m_iRes[0] + ix ] += (1.0-rx) * ry ; m_pBin[z * m_iResXY + (iy+1) * m_iRes[0] + ix + 1] += rx * ry ; BXOUT; } T GetValue(double x, double y, double z) { BXIN; T rx, ry, rz, r; int ix, iy, iz; if ((x < m_fMinVal[0]) || (x > m_fMaxVal[0]) || (y < m_fMinVal[1]) || (y > m_fMaxVal[1]) || (z < m_fMinVal[2]) || (z > m_fMaxVal[2])) { BXOUT; return 0; } rx = (T)((x-m_fMinVal[0])*m_fFac[0] - 0.5); ix = (int)floor(rx); if (ix < 0) { ix = 0; rx = 0; } else if (ix > m_iRes[0]-2) { ix = m_iRes[0]-2; rx = 1.0; } else rx -= ix; ry = (T)((y-m_fMinVal[1])*m_fFac[1] - 0.5); iy = (int)floor(ry); if (iy < 0) { iy = 0; ry = 0; } else if (iy > m_iRes[1]-2) { iy = m_iRes[1]-2; ry = 1.0; } else ry -= iy; rz = (T)((z-m_fMinVal[2])*m_fFac[2] - 0.5); iz = (int)floor(rz); if (iz < 0) { iz = 0; rz = 0; } else if (iz > m_iRes[2]-2) { iz = m_iRes[2]-2; rz = 1.0; } else rz -= iz; r = m_pBin[ iz * m_iResXY + iy * m_iRes[0] + ix ] * ((T)(1.0)-rx) * ((T)(1.0)-ry) * ((T)(1.0)-rz); r += m_pBin[ iz * m_iResXY + iy * m_iRes[0] + ix + 1] * rx * ((T)(1.0)-ry) * ((T)(1.0)-rz); r += m_pBin[ iz * m_iResXY + (iy+1) * m_iRes[0] + ix ] * ((T)(1.0)-rx) * ry * ((T)(1.0)-rz); r += m_pBin[ iz * m_iResXY + (iy+1) * m_iRes[0] + ix + 1] * rx * ry * ((T)(1.0)-rz); r += m_pBin[(iz+1) * m_iResXY + iy * m_iRes[0] + ix ] * ((T)(1.0)-rx) * ((T)(1.0)-ry) * rz; r += m_pBin[(iz+1) * m_iResXY + iy * m_iRes[0] + ix + 1] * rx * ((T)(1.0)-ry) * rz; r += m_pBin[(iz+1) * m_iResXY + (iy+1) * m_iRes[0] + ix ] * ((T)(1.0)-rx) * ry * rz; r += m_pBin[(iz+1) * m_iResXY + (iy+1) * m_iRes[0] + ix + 1] * rx * ry * rz; BXOUT; return r; } bool IsZero(double x, double y, double z) { double rx, ry, rz; int ix, iy, iz; if ((x < m_fMinVal[0]) || (x > m_fMaxVal[0]) || (y < m_fMinVal[1]) || (y > m_fMaxVal[1]) || (z < m_fMinVal[2]) || (z > m_fMaxVal[2])) return false; rx = (x-m_fMinVal[0])*m_fFac[0] - 0.5; ix = (int)floor(rx); if (ix < 0) ix = 0; else if (ix > m_iRes[0]-2) ix = m_iRes[0]-2; ry = (y-m_fMinVal[1])*m_fFac[1] - 0.5; iy = (int)floor(ry); if (iy < 0) iy = 0; else if (iy > m_iRes[1]-2) iy = m_iRes[1]-2; rz = (z-m_fMinVal[2])*m_fFac[2] - 0.5; iz = (int)floor(rz); if (iz < 0) iz = 0; else if (iz > m_iRes[2]-2) iz = m_iRes[2]-2; if (m_pBin[ iz * m_iResXY + iy * m_iRes[0] + ix ] != 0) return false; if (m_pBin[ iz * m_iResXY + iy * m_iRes[0] + ix + 1] != 0) return false; if (m_pBin[ iz * m_iResXY + (iy+1) * m_iRes[0] + ix ] != 0) return false; if (m_pBin[ iz * m_iResXY + (iy+1) * m_iRes[0] + ix + 1] != 0) return false; if (m_pBin[(iz+1) * m_iResXY + iy * m_iRes[0] + ix ] != 0) return false; if (m_pBin[(iz+1) * m_iResXY + iy * m_iRes[0] + ix + 1] != 0) return false; if (m_pBin[(iz+1) * m_iResXY + (iy+1) * m_iRes[0] + ix ] != 0) return false; if (m_pBin[(iz+1) * m_iResXY + (iy+1) * m_iRes[0] + ix + 1] != 0) return false; return true; } T GetValue(const CxDVector3 &vec) { return GetValue(vec[0],vec[1],vec[2]); } void SetLabelX(const char *s) { if (m_sLabelX != NULL) delete[] m_sLabelX; try { m_sLabelX = new char[strlen(s)+1]; } catch(...) { m_sLabelX = NULL; } if (m_sLabelX == NULL) NewException((double)(strlen(s)+1)*sizeof(char),__FILE__,__LINE__,__PRETTY_FUNCTION__); strcpy(m_sLabelX,s); } void SetLabelY(const char *s) { if (m_sLabelY != NULL) delete[] m_sLabelY; try { m_sLabelY = new char[strlen(s)+1]; } catch(...) { m_sLabelY = NULL; } if (m_sLabelY == NULL) NewException((double)(strlen(s)+1)*sizeof(char),__FILE__,__LINE__,__PRETTY_FUNCTION__); strcpy(m_sLabelY,s); } void SetLabelZ(const char *s) { if (m_sLabelZ != NULL) delete[] m_sLabelZ; try { m_sLabelZ = new char[strlen(s)+1]; } catch(...) { m_sLabelZ = NULL; } if (m_sLabelZ == NULL) NewException((double)(strlen(s)+1)*sizeof(char),__FILE__,__LINE__,__PRETTY_FUNCTION__); strcpy(m_sLabelZ,s); } void WritePLT(const char *s1, const char *s2, const char *s3, bool sdf) { BTIN; FILE *a; unsigned int i; int x, y, z; float ff; // char buf[256]; CxString buf; // strcpy(buf,s1); // strcat(buf,s2); // strcat(buf,s3); buf.strcpy(s1); buf.strcat(s2); buf.strcat(s3); a = OpenFileWrite(buf,false); i = 3; fwrite(&i,4,1,a); i = 50; fwrite(&i,4,1,a); if (sdf) { i = m_iRes[0]; fwrite(&i,4,1,a); i = m_iRes[1]; fwrite(&i,4,1,a); i = m_iRes[2]; fwrite(&i,4,1,a); ff = (float)(m_fMinVal[0]/100.0); fwrite(&ff,4,1,a); ff = (float)(m_fMaxVal[0]/100.0); fwrite(&ff,4,1,a); ff = (float)(m_fMinVal[1]/100.0); fwrite(&ff,4,1,a); ff = (float)(m_fMaxVal[1]/100.0); fwrite(&ff,4,1,a); ff = (float)(m_fMinVal[2]/100.0); fwrite(&ff,4,1,a); ff = (float)(m_fMaxVal[2]/100.0); fwrite(&ff,4,1,a); } else { i = m_iRes[0]+2; fwrite(&i,4,1,a); i = m_iRes[1]+2; fwrite(&i,4,1,a); i = m_iRes[2]+2; fwrite(&i,4,1,a); ff = (float)0; fwrite(&ff,4,1,a); ff = (float)100; fwrite(&ff,4,1,a); ff = (float)0; fwrite(&ff,4,1,a); ff = (float)100; fwrite(&ff,4,1,a); ff = (float)0; fwrite(&ff,4,1,a); ff = (float)100; fwrite(&ff,4,1,a); } if (sdf) { for (z=0;z m_fMaxEntry) m_fMaxEntry = m_pBin[z*m_iResXY+z2*m_iRes[0]+z3]; if (m_pBin[z*m_iResXY+z2*m_iRes[0]+z3] < m_fMinEntry) m_fMinEntry = m_pBin[z*m_iResXY+z2*m_iRes[0]+z3]; } } } if (fabs(m_fMinEntry) > m_fMaxEntry) a = fabs(m_fMinEntry); else a = m_fMaxEntry; m_fEps = nextafter(a,2.0*a) - a; BTOUT; } void NormalizeBin(T mi, T ma) { BTIN; int z; T tmi, tma, d, td; tmi = (T)99999999.0; tma = (T)0.0; for (z=0;z tma) tma = m_pBin[z]; } if (tma-tmi < (T)1E-20) tma += (T)0.00001; d = ma - mi; td = tma - tmi; for (z=0;z= m_iRes[2])) continue; tz = (z-pz)*(z-pz); iz = pz*m_iResXY; for (py=y-n;py<=y+n;py++) { if ((py < 0) || (py >= m_iRes[1])) continue; ty = (y-py)*(y-py); iy = py*m_iRes[0]; for (px=x-n;px<=x+n;px++) { if ((px < 0) || (px >= m_iRes[0])) continue; r = 1.0/((x-px)*(x-px)+ty+tz+1.0); a += m_pBin[iz+iy+px]*r; b += r; } } } tbuf[z*m_iResXY+y*m_iRes[0]+x] = a / b; } } } delete[] m_pBin; m_pBin = tbuf; mprintf("Done.\n"); BTOUT; } void CopyFrom(C3DF *p) { BTIN; int z; m_fBinEntries = p->m_fBinEntries; m_fSkipEntries = p->m_fSkipEntries; m_iRes[0] = p->m_iRes[0]; m_iRes[1] = p->m_iRes[1]; m_iRes[2] = p->m_iRes[2]; m_iResXY = p->m_iResXY; m_iHistogramRes = p->m_iHistogramRes; m_fMinVal[0] = p->m_fMinVal[0]; m_fMaxVal[0] = p->m_fMaxVal[0]; m_fMinVal[1] = p->m_fMinVal[1]; m_fMaxVal[1] = p->m_fMaxVal[1]; m_fMinVal[2] = p->m_fMinVal[2]; m_fMaxVal[2] = p->m_fMaxVal[2]; m_fFac[0] = p->m_fFac[0]; m_fFac[1] = p->m_fFac[1]; m_fFac[2] = p->m_fFac[2]; m_fMinEntry = p->m_fMinEntry; m_fMaxEntry = p->m_fMaxEntry; if (m_pBin != NULL) delete[] m_pBin; try { m_pBin = new T[m_iRes[0]*m_iRes[1]*m_iRes[2]]; } catch(...) { m_pBin = NULL; } if (m_pBin == NULL) NewException((double)m_iRes[0]*m_iRes[1]*m_iRes[2]*sizeof(T),__FILE__,__LINE__,__PRETTY_FUNCTION__); // for (z=0;zm_pBin[z]; memcpy(m_pBin,p->m_pBin,sizeof(T)*m_iRes[0]*m_iRes[1]*m_iRes[2]); if (m_iHistogramRes != 0) { try { m_pHistogram = new double[m_iHistogramRes]; } catch(...) { m_pHistogram = NULL; } if (m_pHistogram == NULL) NewException((double)m_iHistogramRes*sizeof(double),__FILE__,__LINE__,__PRETTY_FUNCTION__); for (z=0;zm_pHistogram[z]; } if (p->m_sLabelX != NULL) { try { m_sLabelX = new char[strlen(p->m_sLabelX)+1]; } catch(...) { m_sLabelX = NULL; } if (m_sLabelX == NULL) NewException((double)(strlen(p->m_sLabelX)+1)*sizeof(char),__FILE__,__LINE__,__PRETTY_FUNCTION__); strcpy(m_sLabelX,p->m_sLabelX); } if (p->m_sLabelY != NULL) { try { m_sLabelY = new char[strlen(p->m_sLabelY)+1]; } catch(...) { m_sLabelY = NULL; } if (m_sLabelY == NULL) NewException((double)(strlen(p->m_sLabelY)+1)*sizeof(char),__FILE__,__LINE__,__PRETTY_FUNCTION__); strcpy(m_sLabelY,p->m_sLabelY); } if (p->m_sLabelZ != NULL) { try { m_sLabelZ = new char[strlen(p->m_sLabelZ)+1]; } catch(...) { m_sLabelZ = NULL; } if (m_sLabelZ == NULL) NewException((double)(strlen(p->m_sLabelZ)+1)*sizeof(char),__FILE__,__LINE__,__PRETTY_FUNCTION__); strcpy(m_sLabelZ,p->m_sLabelZ); } BTOUT; } void WriteCube(const char *prefix, const char *name, const char *suffix, bool sdf) { BTIN; FILE *a; int x, y, z; // char buf[256]; CxString buf; // strcpy(buf,prefix); // strcat(buf,name); // strcat(buf,suffix); buf.strcpy(prefix); buf.strcat(name); buf.strcat(suffix); a = OpenFileWrite(buf,true); mfprintf(a,"GAUSSIAN CUBE FILE; written by TRAVIS\n"); mfprintf(a,"OUTER LOOP: X, MIDDLE LOOP: Y, INNER LOOP: Z\n"); if (sdf) { mfprintf(a,"1 %f %f %f\n",(m_fMinVal[0]+0.5*(m_fMaxVal[0]-m_fMinVal[0])/m_iRes[0])/100.0/0.529177249,(m_fMinVal[1]+0.5*(m_fMaxVal[1]-m_fMinVal[1])/m_iRes[1])/100.0/0.529177,(m_fMinVal[2]+0.5*(m_fMaxVal[2]-m_fMinVal[2])/m_iRes[2])/100.0/0.529177); mfprintf(a,"%d %f 0.000 0.000\n",m_iRes[0],(m_fMaxVal[0]-m_fMinVal[0])/m_iRes[0]/100.0/0.529177249); mfprintf(a,"%d 0.000 %f 0.000\n",m_iRes[1],(m_fMaxVal[1]-m_fMinVal[1])/m_iRes[1]/100.0/0.529177249); mfprintf(a,"%d 0.000 0.000 %f\n",m_iRes[2],(m_fMaxVal[2]-m_fMinVal[2])/m_iRes[2]/100.0/0.529177249); } else { mfprintf(a,"1 0.0 0.0 0.0\n"); mfprintf(a,"%d %f 0.000 0.000\n",m_iRes[0]+2,100.0/m_iRes[0]/0.529177249); mfprintf(a,"%d 0.000 %f 0.000\n",m_iRes[1]+2,100.0/m_iRes[1]/0.529177249); mfprintf(a,"%d 0.000 0.000 %f\n",m_iRes[2]+2,100.0/m_iRes[2]/0.529177249); } mfprintf(a,"0 0 0 0 0\n"); if (sdf) { for (x=0;x= rz) { iz = 0; iy++; if (iy >= ry) { iy = 0; ix++; if (verbose) if (fmod(ix,rx/60.0) < 1.0) mprintf(WHITE,"#"); } } if (ix == rx) break; p++; goto _next; } if (feof(a)) { eprintf("C3DF::ReadCube(): Error: Unexpected end of cube file stream.\n"); abort(); } if (verbose) { mprintf(WHITE,"]"); mprintf(" done.\n"); mprintf(" Sum is %f, equals %f electrons.\n",su,su*(g_fBoxX/100.0/0.529177249/rx)*(g_fBoxY/100.0/0.529177249/ry)*(g_fBoxZ/100.0/0.529177249/rz)); } BTOUT; } void ReadCubeData(FILE *a, bool verbose) { BTIN; int ix, iy, iz; char buf[256], *p, *q; T su, tf; if (verbose) { mprintf(" Reading cube file (resolution %d x %d x %d)...\n",m_iRes[0],m_iRes[1],m_iRes[2]); mprintf(WHITE," ["); } ix = 0; iy = 0; iz = 0; su = 0; while (!feof(a)) { _read: (void)fgets(buf,256,a); if (feof(a)) break; p = buf; _next: while (*p == ' ') p++; q = p; while ((*p != ' ') && (*p != '\n') && (*p != 0)) p++; if ((p-q) < 8) goto _read; *p = 0; #ifdef FAST_ATOF tf = (T)fast_atof(q); #else tf = (T)atof(q); #endif m_pBin[iz*m_iResXY+iy*m_iRes[0]+ix] = tf; if (verbose) su += tf; iz += g_iCubeZStride; if (iz >= m_iRes[2] + g_iCubeZMismatch) { iz = 0; iy += g_iCubeYStride; if (iy >= m_iRes[1] + g_iCubeYMismatch) { iy = 0; ix += g_iCubeXStride; if (verbose) if (fmod(ix,m_iRes[0]/60.0) < 1.0) mprintf(WHITE,"#"); } } if (ix == m_iRes[0] + g_iCubeXMismatch) break; // iz++; // if (iz >= m_iRes[2]) // { // iz = 0; // iy++; // if (iy >= m_iRes[1]) // { // iy = 0; // ix++; // if (verbose) // if (fmod(ix,m_iRes[0]/60.0) < 1.0) // mprintf(WHITE,"#"); // } // } // // if (ix == m_iRes[0]) // break; p++; goto _next; } if (g_iCubeXStride > 1) { int i; for (i = 0; i < m_iRes[2]; i += g_iCubeZStride) { int j; for (j = 0; j < m_iRes[1]; j += g_iCubeYStride) { int k; for (k = 0; k < m_iRes[0] - g_iCubeXStride; k += g_iCubeXStride) { int l; for (l = 1; l < g_iCubeXStride; l++) { m_pBin[i*m_iResXY + j*m_iRes[0] + k + l] = m_pBin[i*m_iResXY + j*m_iRes[0] + k] * (g_iCubeXStride - l) / g_iCubeXStride + m_pBin[i*m_iResXY + j*m_iRes[0] + k + g_iCubeXStride] * l / g_iCubeXStride; } } for (k = 1; k < g_iCubeXStride - g_iCubeXMismatch; k++) { m_pBin[i*m_iResXY + j*m_iRes[0] + m_iRes[0] - g_iCubeXStride + g_iCubeXMismatch + k] = m_pBin[i*m_iResXY + j*m_iRes[0] + m_iRes[0] - g_iCubeXStride + g_iCubeXMismatch] * (g_iCubeXStride - g_iCubeXMismatch - k) / (g_iCubeXStride - g_iCubeXMismatch) + m_pBin[i*m_iResXY + j*m_iRes[0]] * k / (g_iCubeXStride - g_iCubeXMismatch); } } } } if (g_iCubeYStride > 1) { int i; for (i = 0; i < m_iRes[2]; i += g_iCubeZStride) { int j; for (j = 0; j < m_iRes[0]; j++) { int k; for (k = 0; k < m_iRes[1] - g_iCubeYStride; k += g_iCubeYStride) { int l; for (l = 1; l < g_iCubeYStride; l++) { m_pBin[i*m_iResXY + (k + l)*m_iRes[0] + j] = m_pBin[i*m_iResXY + k*m_iRes[0] + j] * (g_iCubeYStride - l) / g_iCubeYStride + m_pBin[i*m_iResXY + (k + g_iCubeYStride)*m_iRes[0] + j] * l / g_iCubeYStride; } } for (k = 1; k < g_iCubeYStride - g_iCubeYMismatch; k++) { m_pBin[i*m_iResXY + (m_iRes[1] - g_iCubeYStride + g_iCubeYMismatch + k)*m_iRes[0] + j] = m_pBin[i*m_iResXY + (m_iRes[1] - g_iCubeYStride + g_iCubeYMismatch)*m_iRes[0] + j] * (g_iCubeYStride - g_iCubeYMismatch - k) / (g_iCubeYStride - g_iCubeYMismatch) + m_pBin[i*m_iResXY + j] * k / (g_iCubeYStride - g_iCubeYMismatch); } } } } if (g_iCubeZStride > 1) { int i; for (i = 0; i < m_iRes[1]; i++) { int j; for (j = 0; j < m_iRes[0]; j++) { int k; for (k = 0; k < m_iRes[2] - g_iCubeZStride; k += g_iCubeZStride) { int l; for (l = 1; l < g_iCubeZStride; l++) { m_pBin[(k + l)*m_iResXY + i*m_iRes[0] + j] = m_pBin[k*m_iResXY + i*m_iRes[0] + j] * (g_iCubeZStride - l) / g_iCubeZStride + m_pBin[(k + g_iCubeZStride)*m_iResXY + i*m_iRes[0] + j] * l / g_iCubeZStride; } } for (k = 1; k < g_iCubeZStride - g_iCubeZMismatch; k++) { m_pBin[(m_iRes[2] - g_iCubeZStride + g_iCubeZMismatch + k)*m_iResXY + i*m_iRes[0] + j] = m_pBin[(m_iRes[2] - g_iCubeZStride + g_iCubeZMismatch)*m_iResXY + i*m_iRes[0] + j] * (g_iCubeZStride - g_iCubeZMismatch - k) / (g_iCubeZStride - g_iCubeZMismatch) + m_pBin[i*m_iRes[0] + j] * k / (g_iCubeZStride - g_iCubeZMismatch); } } } } if (feof(a)) { eprintf("C3DF::ReadCubeData(): Error: Unexpected end of cube file stream.\n"); abort(); } if (verbose) { mprintf(WHITE,"]"); mprintf(" done.\n"); // mprintf(" Sum is %f, equals %f electrons.\n",su,su*(g_fBoxX/100.0/0.529177249/m_iRes[0])*(g_fBoxY/100.0/0.529177249/m_iRes[1])*(g_fBoxZ/100.0/0.529177249/m_iRes[2])); mprintf(" Sum is %f, equals %f electrons.\n",su,su*g_fCubeXStep*g_fCubeYStep*g_fCubeZStep); } BTOUT; } void ReadCubeData(CBQBCubeFrame *cfr, bool verbose) { BTIN; int ix, iy, iz; T su; if (verbose) mprintf(">>> ReadCubeData(CBQBCubeFrame*) >>>\n"); if (verbose) { mprintf(" Reading cube file (resolution %d x %d x %d)...\n",m_iRes[0],m_iRes[1],m_iRes[2]); mprintf(WHITE," ["); } ix = 0; iy = 0; iz = 0; su = 0; while (true) { _next: m_pBin[iz*m_iResXY+iy*m_iRes[0]+ix] = cfr->m_faBin[iz+iy*m_iRes[2]+ix*m_iRes[1]*m_iRes[2]]; if (verbose) su += cfr->m_faBin[iz*m_iResXY+iy*m_iRes[0]+ix]; iz += g_iCubeZStride; if (iz >= m_iRes[2] + g_iCubeZMismatch) { iz = 0; iy += g_iCubeYStride; if (iy >= m_iRes[1] + g_iCubeYMismatch) { iy = 0; ix += g_iCubeXStride; if (verbose) if (fmod(ix,m_iRes[0]/60.0) < 1.0) mprintf(WHITE,"#"); } } if (ix == m_iRes[0] + g_iCubeXMismatch) break; goto _next; } if (g_iCubeXStride > 1) { int i; for (i = 0; i < m_iRes[2]; i += g_iCubeZStride) { int j; for (j = 0; j < m_iRes[1]; j += g_iCubeYStride) { int k; for (k = 0; k < m_iRes[0] - g_iCubeXStride; k += g_iCubeXStride) { int l; for (l = 1; l < g_iCubeXStride; l++) { m_pBin[i*m_iResXY + j*m_iRes[0] + k + l] = m_pBin[i*m_iResXY + j*m_iRes[0] + k] * (g_iCubeXStride - l) / g_iCubeXStride + m_pBin[i*m_iResXY + j*m_iRes[0] + k + g_iCubeXStride] * l / g_iCubeXStride; } } for (k = 1; k < g_iCubeXStride - g_iCubeXMismatch; k++) { m_pBin[i*m_iResXY + j*m_iRes[0] + m_iRes[0] - g_iCubeXStride + g_iCubeXMismatch + k] = m_pBin[i*m_iResXY + j*m_iRes[0] + m_iRes[0] - g_iCubeXStride + g_iCubeXMismatch] * (g_iCubeXStride - g_iCubeXMismatch - k) / (g_iCubeXStride - g_iCubeXMismatch) + m_pBin[i*m_iResXY + j*m_iRes[0]] * k / (g_iCubeXStride - g_iCubeXMismatch); } } } } if (g_iCubeYStride > 1) { int i; for (i = 0; i < m_iRes[2]; i += g_iCubeZStride) { int j; for (j = 0; j < m_iRes[0]; j++) { int k; for (k = 0; k < m_iRes[1] - g_iCubeYStride; k += g_iCubeYStride) { int l; for (l = 1; l < g_iCubeYStride; l++) { m_pBin[i*m_iResXY + (k + l)*m_iRes[0] + j] = m_pBin[i*m_iResXY + k*m_iRes[0] + j] * (g_iCubeYStride - l) / g_iCubeYStride + m_pBin[i*m_iResXY + (k + g_iCubeYStride)*m_iRes[0] + j] * l / g_iCubeYStride; } } for (k = 1; k < g_iCubeYStride - g_iCubeYMismatch; k++) { m_pBin[i*m_iResXY + (m_iRes[1] - g_iCubeYStride + g_iCubeYMismatch + k)*m_iRes[0] + j] = m_pBin[i*m_iResXY + (m_iRes[1] - g_iCubeYStride + g_iCubeYMismatch)*m_iRes[0] + j] * (g_iCubeYStride - g_iCubeYMismatch - k) / (g_iCubeYStride - g_iCubeYMismatch) + m_pBin[i*m_iResXY + j] * k / (g_iCubeYStride - g_iCubeYMismatch); } } } } if (g_iCubeZStride > 1) { int i; for (i = 0; i < m_iRes[1]; i++) { int j; for (j = 0; j < m_iRes[0]; j++) { int k; for (k = 0; k < m_iRes[2] - g_iCubeZStride; k += g_iCubeZStride) { int l; for (l = 1; l < g_iCubeZStride; l++) { m_pBin[(k + l)*m_iResXY + i*m_iRes[0] + j] = m_pBin[k*m_iResXY + i*m_iRes[0] + j] * (g_iCubeZStride - l) / g_iCubeZStride + m_pBin[(k + g_iCubeZStride)*m_iResXY + i*m_iRes[0] + j] * l / g_iCubeZStride; } } for (k = 1; k < g_iCubeZStride - g_iCubeZMismatch; k++) { m_pBin[(m_iRes[2] - g_iCubeZStride + g_iCubeZMismatch + k)*m_iResXY + i*m_iRes[0] + j] = m_pBin[(m_iRes[2] - g_iCubeZStride + g_iCubeZMismatch)*m_iResXY + i*m_iRes[0] + j] * (g_iCubeZStride - g_iCubeZMismatch - k) / (g_iCubeZStride - g_iCubeZMismatch) + m_pBin[i*m_iRes[0] + j] * k / (g_iCubeZStride - g_iCubeZMismatch); } } } } if (verbose) { mprintf(WHITE,"]"); mprintf(" done.\n"); // mprintf(" Sum is %f, equals %f electrons.\n",su,su*(g_fBoxX/100.0/0.529177249/m_iRes[0])*(g_fBoxY/100.0/0.529177249/m_iRes[1])*(g_fBoxZ/100.0/0.529177249/m_iRes[2])); mprintf(" Sum is %f, equals %f electrons.\n",su,su*g_fCubeXStep*g_fCubeYStep*g_fCubeZStep); } if (verbose) mprintf("<<< ReadCubeData(CBQBCubeFrame*) <<<\n"); BTOUT; } void ReadCube(CxMemFile *mf, bool verbose, bool create) { BTIN; int ac, rx, ry, rz, z, ix, iy, iz; char buf[256], *p, *q; T su, tf; mf->Seek(0); (void)mf->fgets(buf,256); (void)mf->fgets(buf,256); (void)mf->fgets(buf,256); p = buf; while (*p == ' ') p++; while (*p != ' ') p++; *p = 0; ac = atoi(buf); (void)mf->fgets(buf,256); p = buf; while (*p == ' ') p++; while (*p != ' ') p++; *p = 0; rx = atoi(buf); (void)mf->fgets(buf,256); p = buf; while (*p == ' ') p++; while (*p != ' ') p++; *p = 0; ry = atoi(buf); (void)mf->fgets(buf,256); p = buf; while (*p == ' ') p++; while (*p != ' ') p++; *p = 0; rz = atoi(buf); for (z=0;zfgets(buf,256); if (mf->Eof()) { eprintf("C3DF::ReadCube(): Error: Unexpected end of cube file stream.\n"); abort(); } if (create) { m_iRes[0] = rx; m_iRes[1] = ry; m_iRes[2] = rz; m_fMinVal[0] = 0; m_fMaxVal[0] = g_fBoxX; m_fMinVal[1] = 0; m_fMaxVal[1] = g_fBoxY; m_fMinVal[2] = 0; m_fMaxVal[2] = g_fBoxZ; Create(); mprintf("\n"); } else { if ((rx != m_iRes[0]) || (ry != m_iRes[1]) || (rz != m_iRes[2])) { eprintf("C3DF::ReadCube(): Error: Cube file dimension mismatch (%d-%d, %d-%d, %d-%d).\n",rx,m_iRes[0],ry,m_iRes[1],rz,m_iRes[2]); abort(); } for (z=0;zEof()) { _read: (void)mf->fgets(buf,256); if (mf->Eof()) break; p = buf; _next: while (*p == ' ') p++; q = p; while ((*p != ' ') && (*p != '\n') && (*p != 0)) p++; if ((p-q) < 8) goto _read; *p = 0; #ifdef FAST_ATOF tf = (T)fast_atof(q); #else tf = (T)atof(q); #endif m_pBin[iz*m_iResXY+iy*m_iRes[0]+ix] = tf; if (verbose) su += tf; iz++; if (iz >= rz) { iz = 0; iy++; if (iy >= ry) { iy = 0; ix++; if (verbose) if (fmod(ix,rx/60.0) < 1.0) mprintf(WHITE,"#"); } } if (ix == rx) break; p++; goto _next; } if (mf->Eof()) { eprintf("C3DF::ReadCube(): Error: Unexpected end of cube file stream.\n"); abort(); } if (verbose) { mprintf(WHITE,"]"); mprintf(" done.\n"); mprintf(" Sum is %f, equals %f electrons.\n",su,su*(g_fBoxX/100.0/0.529177249/rx)*(g_fBoxY/100.0/0.529177249/ry)*(g_fBoxZ/100.0/0.529177249/rz)); } BTOUT; } void ReadCubeData(CxMemFile *mf, bool verbose) { BTIN; int ix, iy, iz; char buf[256], *p, *q; T su, tf; if (verbose) { mprintf(" Reading cube file (resolution %d x %d x %d)...\n",m_iRes[0],m_iRes[1],m_iRes[2]); mprintf(WHITE," ["); } ix = 0; iy = 0; iz = 0; su = 0; while (!mf->Eof()) { _read: (void)mf->fgets(buf,256); if (mf->Eof()) break; p = buf; _next: while (*p == ' ') p++; q = p; while ((*p != ' ') && (*p != '\n') && (*p != 0)) p++; if ((p-q) < 8) goto _read; *p = 0; #ifdef FAST_ATOF tf = (T)fast_atof(q); #else tf = (T)atof(q); #endif m_pBin[iz*m_iResXY+iy*m_iRes[0]+ix] = tf; if (verbose) su += tf; iz += g_iCubeZStride; if (iz >= m_iRes[2] + g_iCubeZMismatch) { iz = 0; iy += g_iCubeYStride; if (iy >= m_iRes[1] + g_iCubeYMismatch) { iy = 0; ix += g_iCubeXStride; if (verbose) if (fmod(ix,m_iRes[0]/60.0) < 1.0) mprintf(WHITE,"#"); } } if (ix == m_iRes[0] + g_iCubeXMismatch) break; // iz++; // if (iz >= m_iRes[2]) // { // iz = 0; // iy++; // if (iy >= m_iRes[1]) // { // iy = 0; // ix++; // if (verbose) // if (fmod(ix,m_iRes[0]/60.0) < 1.0) // mprintf(WHITE,"#"); // } // } // // if (ix == m_iRes[0]) // break; p++; goto _next; } if (g_iCubeXStride > 1) { int i; for (i = 0; i < m_iRes[2]; i += g_iCubeZStride) { int j; for (j = 0; j < m_iRes[1]; j += g_iCubeYStride) { int k; for (k = 0; k < m_iRes[0] - g_iCubeXStride; k += g_iCubeXStride) { int l; for (l = 1; l < g_iCubeXStride; l++) { m_pBin[i*m_iResXY + j*m_iRes[0] + k + l] = m_pBin[i*m_iResXY + j*m_iRes[0] + k] * (g_iCubeXStride - l) / g_iCubeXStride + m_pBin[i*m_iResXY + j*m_iRes[0] + k + g_iCubeXStride] * l / g_iCubeXStride; } } for (k = 1; k < g_iCubeXStride - g_iCubeXMismatch; k++) { m_pBin[i*m_iResXY + j*m_iRes[0] + m_iRes[0] - g_iCubeXStride + g_iCubeXMismatch + k] = m_pBin[i*m_iResXY + j*m_iRes[0] + m_iRes[0] - g_iCubeXStride + g_iCubeXMismatch] * (g_iCubeXStride - g_iCubeXMismatch - k) / (g_iCubeXStride - g_iCubeXMismatch) + m_pBin[i*m_iResXY + j*m_iRes[0]] * k / (g_iCubeXStride - g_iCubeXMismatch); } } } } if (g_iCubeYStride > 1) { int i; for (i = 0; i < m_iRes[2]; i += g_iCubeZStride) { int j; for (j = 0; j < m_iRes[0]; j++) { int k; for (k = 0; k < m_iRes[1] - g_iCubeYStride; k += g_iCubeYStride) { int l; for (l = 1; l < g_iCubeYStride; l++) { m_pBin[i*m_iResXY + (k + l)*m_iRes[0] + j] = m_pBin[i*m_iResXY + k*m_iRes[0] + j] * (g_iCubeYStride - l) / g_iCubeYStride + m_pBin[i*m_iResXY + (k + g_iCubeYStride)*m_iRes[0] + j] * l / g_iCubeYStride; } } for (k = 1; k < g_iCubeYStride - g_iCubeYMismatch; k++) { m_pBin[i*m_iResXY + (m_iRes[1] - g_iCubeYStride + g_iCubeYMismatch + k)*m_iRes[0] + j] = m_pBin[i*m_iResXY + (m_iRes[1] - g_iCubeYStride + g_iCubeYMismatch)*m_iRes[0] + j] * (g_iCubeYStride - g_iCubeYMismatch - k) / (g_iCubeYStride - g_iCubeYMismatch) + m_pBin[i*m_iResXY + j] * k / (g_iCubeYStride - g_iCubeYMismatch); } } } } if (g_iCubeZStride > 1) { int i; for (i = 0; i < m_iRes[1]; i++) { int j; for (j = 0; j < m_iRes[0]; j++) { int k; for (k = 0; k < m_iRes[2] - g_iCubeZStride; k += g_iCubeZStride) { int l; for (l = 1; l < g_iCubeZStride; l++) { m_pBin[(k + l)*m_iResXY + i*m_iRes[0] + j] = m_pBin[k*m_iResXY + i*m_iRes[0] + j] * (g_iCubeZStride - l) / g_iCubeZStride + m_pBin[(k + g_iCubeZStride)*m_iResXY + i*m_iRes[0] + j] * l / g_iCubeZStride; } } for (k = 1; k < g_iCubeZStride - g_iCubeZMismatch; k++) { m_pBin[(m_iRes[2] - g_iCubeZStride + g_iCubeZMismatch + k)*m_iResXY + i*m_iRes[0] + j] = m_pBin[(m_iRes[2] - g_iCubeZStride + g_iCubeZMismatch)*m_iResXY + i*m_iRes[0] + j] * (g_iCubeZStride - g_iCubeZMismatch - k) / (g_iCubeZStride - g_iCubeZMismatch) + m_pBin[i*m_iRes[0] + j] * k / (g_iCubeZStride - g_iCubeZMismatch); } } } } if (mf->Eof()) { eprintf("C3DF::ReadCubeData(): Error: Unexpected end of cube file stream.\n"); abort(); } if (verbose) { mprintf(WHITE,"]"); mprintf(" done.\n"); // mprintf(" Sum is %f, equals %f electrons.\n",su,su*(g_fBoxX/100.0/0.529177249/m_iRes[0])*(g_fBoxY/100.0/0.529177249/m_iRes[1])*(g_fBoxZ/100.0/0.529177249/m_iRes[2])); mprintf(" Sum is %f, equals %f electrons.\n",su,su*g_fCubeXStep*g_fCubeYStep*g_fCubeZStep); } BTOUT; } void MultiplyBin(T d) { int z; for (z=0;zm_iRes[0] = m_iRes[1]; cdf->m_fMinVal[0] = m_fMinVal[1]; cdf->m_fMaxVal[0] = m_fMaxVal[1]; cdf->SetLabelX(m_sLabelY); cdf->m_iRes[1] = m_iRes[2]; cdf->m_fMinVal[1] = m_fMinVal[2]; cdf->m_fMaxVal[1] = m_fMaxVal[2]; cdf->SetLabelY(m_sLabelZ); cdf->SetLabelZ("Occurence"); cdf->Create(); cdf->m_iSmoothGrade = 0; for (i3=0;i3m_pBin[i3*m_iRes[1]+i2] += m_pBin[i3*m_iResXY+i2*m_iRes[0]+i1]; } } } cdf->CalcMaxEntry(); } else if (axis == 1) { cdf->m_iRes[0] = m_iRes[0]; cdf->m_fMinVal[0] = m_fMinVal[0]; cdf->m_fMaxVal[0] = m_fMaxVal[0]; cdf->SetLabelX(m_sLabelX); cdf->m_iRes[1] = m_iRes[2]; cdf->m_fMinVal[1] = m_fMinVal[2]; cdf->m_fMaxVal[1] = m_fMaxVal[2]; cdf->SetLabelY(m_sLabelZ); cdf->SetLabelZ("Occurence"); cdf->Create(); cdf->m_iSmoothGrade = 0; for (i3=0;i3m_pBin[i3*m_iRes[0]+i1] += m_pBin[i3*m_iResXY+i2*m_iRes[0]+i1]; } } } cdf->CalcMaxEntry(); } else if (axis == 2) { cdf->m_iRes[0] = m_iRes[0]; cdf->m_fMinVal[0] = m_fMinVal[0]; cdf->m_fMaxVal[0] = m_fMaxVal[0]; cdf->SetLabelX(m_sLabelX); cdf->m_iRes[1] = m_iRes[1]; cdf->m_fMinVal[1] = m_fMinVal[1]; cdf->m_fMaxVal[1] = m_fMaxVal[1]; cdf->SetLabelY(m_sLabelY); cdf->SetLabelZ("Occurence"); cdf->Create(); cdf->m_iSmoothGrade = 0; for (i1=0;i1m_pBin[i2*m_iRes[0]+i1] += m_pBin[i3*m_iResXY+i2*m_iRes[0]+i1]; } } } cdf->CalcMaxEntry(); } } void Clear() { int z; for (z=0;z. *****************************************************************************/ // This must always be the first include directive #include "config.h" #include "acf.h" #include "travis.h" #include "maintools.h" const char *GetRevisionInfo_acf(unsigned int len) { static char buf[256]; GET_REVISION_INFO( buf, len ); return buf; } const char *GetSourceVersion_acf() { static char buf[256]; GET_SOURCE_VERSION( buf ); return buf; } CACF::CACF() { BTIN; m_pData = NULL; m_pCounter = NULL; m_iShowMol = -1; // m_bSplitCart = false; // m_b2ndDerivative = false; m_oaCache.SetName("CACF::m_oaCache"); m_oaCCRMatrix.SetName("CACF::m_oaCCRMatrix"); BTOUT; } CACF::~CACF() { BTIN; if (m_pData != NULL) delete[] m_pData; if (m_pCounter != NULL) delete[] m_pCounter; BTOUT; } void CACF::Create() { BTIN; int z; if (m_pData != NULL) { delete[] m_pData; delete[] m_pCounter; } mprintf(" ACF: Trying to reserve %s of memory...\n",FormatBytes((double)m_iSize*sizeof(double)+(double)m_iSize*sizeof(long))); try { m_pData = new double[m_iSize]; } catch(...) { m_pData = NULL; } if (m_pData == NULL) NewException((double)m_iSize*sizeof(double),__FILE__,__LINE__,__PRETTY_FUNCTION__); try { m_pCounter = new unsigned long[m_iSize]; } catch(...) { m_pCounter = NULL; } if (m_pCounter == NULL) NewException((double)m_iSize*sizeof(unsigned long),__FILE__,__LINE__,__PRETTY_FUNCTION__); for (z=0;zm_iSize = m_iSize; m_pSpectrum->m_fWaveNumber = m_fSpecWaveNumber; } BTOUT; } void CACF::Normalize() { BTIN; double d; int z; if (m_pData[0] < 1E-20) return; d = m_pCounter[0] / m_pData[0]; for (z=0;zm_pInput,m_pData,sizeof(double)*(m_iSize/m_iStride)); /* if (m_bMirror) { for (z=0;z<(m_iSize+m_iZeroPadding)*2;z++) { fft->m_pInput[z*2] = 0; fft->m_pInput[z*2+1] = 0; } for (z=0;zm_pInput[(m_iSize+m_iZeroPadding+z)*2] = (double)m_pData[z]; fft->m_pInput[(m_iSize+m_iZeroPadding+z)*2+1] = 0; fft->m_pInput[(m_iSize+m_iZeroPadding-z)*2] = (double)m_pData[z]; fft->m_pInput[(m_iSize+m_iZeroPadding-z)*2+1] = 0; } } else { for (z=0;zm_pInput[z*2] = 0; fft->m_pInput[z*2+1] = 0; }*/ /******** MT Neu ************/ /* for(z = 0; z < m_iZeroPadding / 2; z++) { fft->m_pInput[z * 2] = 0.0; fft->m_pInput[z * 2 + 1] = 0.0; } for(z = 0; z < m_iSize; z++) { fft->m_pInput[(m_iZeroPadding / 2 + z) * 2] = (double)m_pData[z]; fft->m_pInput[(m_iZeroPadding / 2 + z) * 2 + 1] = 0.0; } for(z = 0; z < m_iZeroPadding / 2; z++) { fft->m_pInput[(m_iZeroPadding / 2 + m_iSize + z) * 2] = 0.0; fft->m_pInput[(m_iZeroPadding / 2 + m_iSize + z) * 2 + 1] = 0.0; }*/ /******** MT Neu ************/ for(z = 0; z < m_iSize/2; z++) { fft->m_pInput[z * 2] = (double)m_pData[z]; fft->m_pInput[z * 2 + 1] = 0.0; } for(z = 0; z < m_iZeroPadding; z++) { fft->m_pInput[(m_iSize/2 + z) * 2] = 0.0; fft->m_pInput[(m_iSize/2 + z) * 2 + 1] = 0.0; } for(z = 0; z < m_iSize/2; z++) { fft->m_pInput[(m_iSize/2 + m_iZeroPadding + z) * 2] = (double)m_pData[m_iSize/2 + z]; fft->m_pInput[(m_iSize/2 + m_iZeroPadding + z) * 2 + 1] = 0.0; } /******** MB Alt ************/ /* for (z=0;zm_pInput[z*2] = (double)m_pData[z]; fft->m_pInput[z*2+1] = 0; } for (z=m_iSize;zm_pInput[z*2] = 0; fft->m_pInput[z*2+1] = 0; }*/ // } fft->DoFFT(); // m_pSpectrum = new CSpectrum(); // if (m_bMirror) // m_pSpectrum->Create((m_iSize+m_iZeroPadding)*2); /* else */ m_pSpectrum->Create(m_iSize+m_iZeroPadding); m_pSpectrum->FromComplex((double*)fft->m_pOutput); BTOUT; } void CACF::Parse() { BTIN; // char buf[256]; CxString buf; int ti, z; double tf; CFFT tfft; eprintf("CACF::Parse(): Internal Error: This code is no longer in use.\n"); abort(); if (m_iShowMol != -1) { _atoms: mprintf(" Which atoms to observe in %s (e.g. \"C1,C3-5,H\")? [all] ",((CMolecule*)g_oaMolecules[m_iShowMol])->m_sName); inpprintf("! Which atoms to observe (e.g. \"C1,C3-5,H\")? [all]\n"); myget(&buf); if (buf.GetLength() == 0) { m_oAtoms.AddAllAtoms((CMolecule*)g_oaMolecules[m_iShowMol],false); } else { if (!m_oAtoms.ParseAtoms((CMolecule*)g_oaMolecules[m_iShowMol],buf)) { eprintf("Invalid input.\n"); inpprintf("! Invalid input.\n"); goto _atoms; } } m_iShowAtomGes = m_oAtoms.m_iAtomGes; } else { m_iShowAtomGes = 0; for (z=0;zm_pElement->m_fRadius == 0) { m_bExcludeR0 = AskYesNo(" Neglect atoms excluded from system (e.g. wannier centers) from VACF (y/n)? [yes] ",true); mprintf("\n"); goto _r0done; } } m_bExcludeR0 = false; mprintf(" Observing all atoms in the system.\n\n"); _r0done:; } //_acfdepth: mprintf(WHITE," Hint: "); mprintf("The resolution of the ACF may never be higher than the number of processed steps.\n"); mprintf(" Suggested is 75 percent of the processed steps, but not more than approx. 16384.\n\n"); if (g_iTrajSteps != -1) ti = (int(g_iTrajSteps*0.75)<5120)?int(g_iTrajSteps*0.75):4096; else ti = 4096; m_iSize = AskUnsignedInteger(" Enter the resolution (=depth) of the velocity ACF (in time steps): [%d] ",ti,ti); if (g_bPowerSpec) mprintf("\n This corresponds to a spectral resolution of %.4f cm^-1.\n",33356.41/g_fTimestepLength/2.0/m_iSize); // if (m_iSize*g_iGesVirtAtomCount*12.0f*sizeof(double)/1024.0f/1024.0f >= 10.0f) // if (!AskYesNo("\nThis needs about %.0f MB Memory. Is this OK (y/n)? [yes] ",true,m_iSize*g_iGesVirtAtomCount*4.0f*sizeof(double)/1024.0f/1024.0f)) // goto _acfdepth; if (g_bACFFFT) { ti = CalcFFTSize(m_iSize,false); if (m_iSize != ti) { mprintf(WHITE," The next \"fast\" size for FFT is %d. Using this instead of %d as size.\n\n",ti,m_iSize); m_iSize = ti; } } // m_iStride = AskUnsignedInteger(" Take every n-th time step for the Velocity ACF? [1] ",1); m_bDerivative = AskYesNo(" Derive the velocity before autocorrelating (y/n)? [no] ",false); m_bMassWeight = AskYesNo(" Weight the autocorrelation functions by atomic mass (y/n)? [yes] ",true); m_bWindowFunction = AskYesNo(" Apply window function (Cos^2) to Autocorrelation function (y/n)? [yes] ",true); // mprintf("\n"); // if (g_bPowerSpec) // m_bSplitCart = AskYesNo(" Split this power spectrum into cartesian contributions x, y, z, xy, xz, yz (y/n)? [no] ",false); // else // m_bSplitCart = AskYesNo(" Split this autocorrelation into cartesian contributions x, y, z, xy, xz, yz (y/n)? [no] ",false); // m_bSpectrum = AskYesNo(" Also calculate power spectrum (= Fourier Transform of velocity ACF) (y/n)? [yes] ",true); m_bSpectrum = g_bPowerSpec; if (m_bSpectrum) { tf = 33356.41 / g_fTimestepLength / 2.0; mprintf("\n A time step length of %.1f fs allows a spectral range up to %.1f cm^-1.\n\n",g_fTimestepLength,tf); m_fSpecWaveNumber = AskRangeFloat(" Calculate spectrum up to which wave number (cm^-1)? [%.1f cm^-1] ",0,tf,(tf<5000.0)?tf:5000.0,(tf<5000.0)?tf:5000.0); m_iMirror = AskUnsignedInteger(" No mirroring (0), short-time enhancing (1) or long-time enhancing (2)? [1] ",1); m_iZeroPadding = AskUnsignedInteger(" Zero Padding: How many zeros to insert? [%d] ",m_iSize*3,m_iSize*3); ti = CalcFFTSize(m_iSize+m_iZeroPadding,false); if (m_iSize+m_iZeroPadding != ti) { mprintf(WHITE," The next \"fast\" size for FFT is %d. Using %d zeros for zero padding.\n\n",ti,ti-m_iSize); m_iZeroPadding = ti-m_iSize; } m_iZeroPadding0 = m_iZeroPadding; mprintf(" Zero padding increases the spectral resolution to %.4f cm^-1.\n\n",33356.41/g_fTimestepLength/2.0/(m_iSize+m_iZeroPadding)); m_bACF_DB = AskYesNo(" Convert intensity axis of spectrum to decibel (y/n)? [no] ",false); if (g_bAdvanced2) m_bDecomposeModes = AskYesNo(" Decompose power spectrum into normal modes (y/n)? [no] ",false); else m_bDecomposeModes = false; } BuildName(); BTOUT; } void CACF::BuildName() { BTIN; // char tmp[32768]; CxString tmp; if (m_iShowMol == -1) tmp.sprintf("global"); else tmp.sprintf("%s_%s",((CMolecule*)g_oaMolecules[m_iShowMol])->m_sName,m_oAtoms.m_sName); try { m_sName = new char[strlen(tmp)+1]; } catch(...) { m_sName = NULL; } if (m_sName == NULL) NewException((double)(strlen(tmp)+1)*sizeof(char),__FILE__,__LINE__,__PRETTY_FUNCTION__); strcpy(m_sName,tmp); BTOUT; } void CACF::BuildAtomList(CSingleMolecule *obs, CxIntArray *vec) { BXIN; int z1t, z1a; CxIntArray *a1; vec->RemoveAll_KeepSize(); for (z1t=0;z1tGetSize();z1a++) vec->Add(((CxIntArray*)obs->m_oaAtomOffset[m_oAtoms.m_baAtomType[z1t]])->GetAt(a1->GetAt(z1a))); } BXOUT; } void CACF::NormalizeCached() { BTIN; int z; for (z=1;z. *****************************************************************************/ #ifndef ACF_H #define ACF_H // This must always be the first include directive #include "config.h" #include "xobject.h" #include "backtrace.h" #include "spectrum.h" #include "fft.h" #include "atomgroup.h" #include "xintarray.h" class CSingleMolecule; class CACF : public CxObject { public: bool m_bExcludeR0; // bool m_b2ndDerivative; int m_iDerivative; bool m_bDerivative; void Mirror(int i); int m_iShowAtomGes; void BuildAtomList(CSingleMolecule *obs, CxIntArray *vec); CAtomGroup m_oAtoms; int m_iShowMol; void BuildName(); CACF(); ~CACF(); void Window(); void WriteACF(const char *pre, const char *s, const char *post); void Normalize(); void NormalizeCached(); void Multiply(double f); void MultiplyCached(double f); void Create(); void Transform(CFFT *fft); void Parse(); char* m_sName; double *m_pData; unsigned long *m_pCounter; int m_iSize; CSpectrum *m_pSpectrum; // int m_iStride; bool m_bWindowFunction; bool m_bSpectrum; bool m_bMassWeight; double m_fSpecWaveNumber; int m_iZeroPadding; int m_iZeroPadding0; int m_iMirror; bool m_bACF_DB; CxObArray m_oaCache; bool m_bDecomposeModes; int m_iParticles; CxObArray m_oaCCRMatrix; //bool m_bSplitCart; }; #endif travis-src-190101/src/aggregate.h0100777000000000000000000000322213412725654013540 0ustar00/***************************************************************************** TRAVIS - Trajectory Analyzer and Visualizer http://www.travis-analyzer.de/ Copyright (c) 2009-2019 Martin Brehm 2012-2019 Martin Thomas 2016-2019 Sascha Gehrke This file was written by Martin Brehm. --------------------------------------------------------------------------- This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . *****************************************************************************/ #ifndef AGGREGATE_H #define AGGREGATE_H // This must always be the first include directive #include "config.h" #include "xobject.h" #include "xdvector3.h" #include "xintarray.h" class CAggregate : public CxObject { public: CxIntArray m_laLifeIntervals; CAggregate() { } ~CAggregate() { } int m_iSingleMol2; CxDVector3 m_vStart; CxDVector3 m_vFirstStart; CxDoubleArray m_faTempTrace; unsigned long m_iStart; unsigned long m_iFirstStart; CxDVector3 m_vEnd; signed long m_iEnd; bool m_bStillAlive; }; #endif travis-src-190101/src/analysis.h0100777000000000000000000000313413412725656013441 0ustar00/***************************************************************************** TRAVIS - Trajectory Analyzer and Visualizer http://www.travis-analyzer.de/ Copyright (c) 2009-2019 Martin Brehm 2012-2019 Martin Thomas 2016-2019 Sascha Gehrke This file was written by Martin Brehm. --------------------------------------------------------------------------- This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . *****************************************************************************/ #ifndef ANALYSIS_H #define ANALYSIS_H // This must always be the first include directive #include "config.h" #include "backtrace.h" #include "xobject.h" class CAnalysis : public CxObject { public: CAnalysis() { m_sAbbrev = NULL; m_sName = NULL; } ~CAnalysis() { if (m_sAbbrev != NULL) { delete[] m_sAbbrev; m_sAbbrev = NULL; } if (m_sName != NULL) { delete[] m_sName; m_sName = NULL; } } char* m_sAbbrev; char* m_sName; }; #endif travis-src-190101/src/analysisgroup.cpp0100777000000000000000000000330713412725620015042 0ustar00/***************************************************************************** TRAVIS - Trajectory Analyzer and Visualizer http://www.travis-analyzer.de/ Copyright (c) 2009-2019 Martin Brehm 2012-2019 Martin Thomas 2016-2019 Sascha Gehrke This file was written by Martin Brehm. --------------------------------------------------------------------------- This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . *****************************************************************************/ // This must always be the first include directive #include "config.h" #include "analysisgroup.h" const char *GetRevisionInfo_analysisgroup(unsigned int len) { static char buf[256]; GET_REVISION_INFO( buf, len ); return buf; } const char *GetSourceVersion_analysisgroup() { static char buf[256]; GET_SOURCE_VERSION( buf ); return buf; } CAnalysisGroup::CAnalysisGroup() { m_sGroupName = NULL; m_oaAnalyses.SetName("CAnalysisGroup::m_oaAnalyses"); } CAnalysisGroup::~CAnalysisGroup() { if (m_sGroupName != NULL) { delete[] m_sGroupName; m_sGroupName = NULL; } } travis-src-190101/src/analysisgroup.h0100777000000000000000000000274713412725662014524 0ustar00/***************************************************************************** TRAVIS - Trajectory Analyzer and Visualizer http://www.travis-analyzer.de/ Copyright (c) 2009-2019 Martin Brehm 2012-2019 Martin Thomas 2016-2019 Sascha Gehrke This file was written by Martin Brehm. --------------------------------------------------------------------------- This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . *****************************************************************************/ #ifndef ANALYSISGROUP_H #define ANALYSISGROUP_H // This must always be the first include directive #include "config.h" #include "backtrace.h" #include "xobject.h" #include "xobarray.h" #include "analysis.h" class CAnalysisGroup : public CxObject { public: CAnalysisGroup(); ~CAnalysisGroup(); char* m_sGroupName; CxObArray m_oaAnalyses; }; #endif travis-src-190101/src/asciiart.cpp0100777000000000000000000002341613412725625013751 0ustar00/***************************************************************************** TRAVIS - Trajectory Analyzer and Visualizer http://www.travis-analyzer.de/ Copyright (c) 2009-2019 Martin Brehm 2012-2019 Martin Thomas 2016-2019 Sascha Gehrke This file was written by Martin Brehm. --------------------------------------------------------------------------- This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . *****************************************************************************/ // This must always be the first include directive #include "config.h" #include "asciiart.h" const char *GetRevisionInfo_asciiart(unsigned int len) { static char buf[256]; GET_REVISION_INFO( buf, len ); return buf; } const char *GetSourceVersion_asciiart() { static char buf[256]; GET_SOURCE_VERSION( buf ); return buf; } CAsciiArt::CAsciiArt() { BTIN; m_iPosX = -1; m_iPosY = -1; m_iSelectedPiece = -1; m_oaAsciiPieces.SetName("CAsciiArt::m_oaAsciiPieces"); AddPiece(" , \n\ ,::.::::. / `. \n\ ;:: `. ( ,--. \n\ ,; : _,--'\"\\/\"\"-.\\_ \n\ ,: `./ ,---./( O )) `; \n\ ; `. _,' ( `-' ) /_. \n\ ; : ,' \\ , (o\\\\ \n\ ; : \\ \\-. -.__--' \\' ) \n\ ; ; /\\ ( `-._`-._ \\/ \n\ ';, ; : | -.`._'\\ `. \n\ ; ; : `-.,-.. ) \\'\\ ^. \n\ ; ; `.__ )))\\ ) (`.\\ \\ \n\ ; ; `-`///(, \\ \\ \\) ,ooo. \n\ ;,; ; `` ))))_;'( 88888p \n\ ; ; ((-='--',-,Y8888' \n\ ; : ; ,:'-' `\"' \n\ ; ` ; | \n\ ; (_ __ _,-' \n\ `---. ;\"(,-' / ____ \n\ -hrr- \\ (__/\\\\_`-.-. _____/ \n\ ,(( '/\\/\\/\\`-;;)) ______// \n\ ((\\''/\\/\\/\\/\\/\\/`/\\ _____/ ____/ \n\ /'/\\/\\/\\/\\/\\/\\/\\/\\/) __/ _____/ \n\ (\\/\\/\\/\\/\\/\\/\\/\\/\\_/ _/ ___/ \n\ `-|\"\"--\"-.___,--'|-'__/ \n\ | | / \n\ | __,--' \n\ _\\,----\"\"'"); AddPiece(" ,--\"`-.-._ \n\ ,' ,.:::::. `. \n\ | ;' `:: | \n\ ,--,-, .::::..;',' \n\ ,' ,' \"\" ,'_ \n\ '-)\",'o \"_\\ \n\ _,' \"\"' .::. .:o; \n\ ; :::' ; \n\ ; `::; ; \n\ : (_;_ ;:: ;\\ \n\ ; / ;::. ; \\ \n\ / / ,:' ;:: \\ \n\ __|__/_ /:: ; \\ ` \n\ _,-' `-<::'___ ;| \\ \\ \n\ ,-' _,-\"\"\";-._`.(__ `. ;| \\ | ____ \n\ ( ,--'__,--' |`-`(@) \\( `. `. ,-' `-. \n\ \\___.-' \\ |::. \\ : `. `./,-'\"\"`. \\ \n\ \\ |::. ) : .-. `-._ ' `--.--' ) \n\ \\ .-`.:' / : / `-.__ __,-' \n\ -hrr- ) `.' ; / `\"' \n\ ( `' ,\\ , ---.( \n\ ,' --- `:`--' : : \\ \n\ ( : : ; `--`--`-' \n\ `-`--`--' "); AddPiece(" ,--.\"\"\n\ __,----( o )) \n\ ,'--. , ( \n\ -\"\",:-( o ),-'/ ; \n\ ( o) `o _,'\\ / ;( \n\ `-;_-<'\\_|-'/ ' ) \n\ `.`-.__/ ' | \n\ \\`. `. .__, ; \n\ )_;--. \\` | \n\ /'(__,-: ) ; \n\ ;' (_,-: _,:: .| \n\ ; ( , ) _,':::' ,; \n\ ; )-,;' `:' .:: \n\ | `' ; `:::\\ \n\ : ,' ' `:\\ \n\ ;: ' _,-': .' `-. \n\ ';::..,' ' , ` ,__ `. \n\ `;'' / ; _;_,-' `. \n\ / _;--. \\ \n\ ,' / ,' `. \\ \n\ /: (_( ,' \\ ) \n\ /:. \\_( /-. .:::,;/ \n\ (::.. `-'\\ \"`\"\"' \n\ ;::::. \\ __ \n\ ,::::::. .:' ) ,-' ) \n\ / `;:::::::'`__,:.:::' /`---' ,' \n\ ; `\"\"\"\"' ( \\:::' / _,-'\n\ ; \\ \\:' ,';:.,-' \n\ ( : )\\ ( \n\ `. \\ \\ ; \n\ -hrr- `-.___ : ,\\ \\ ( \n\ ,','._::::| \\ \\ \\ \\ \n\ (,(,---;;;;; \\ \\|;;;) \n\ `._\\_\\"); AddPiece(" ,::::.._\n\ ,':::::::::.\n\ _,-'`:::,::(o)::`-,.._\n\ _.', ', `:::::::::;'-..__`.\n\ _.-'' ' ,' ,' ,\\:::,'::-`'''\n\ _.-'' , ' , ,' ' ,' `:::/\n\ _..-'' , ' , ' ,' , ,' ',' '/::\n\ _...:::'`-..'_, ' , ,' , ' ,'' , ,'::|\n\ _`.:::::,':::::,'::`-:..'_',_'_,'..-'::,'|\n\ _..-:::'::,':::::::,':::,':,'::,':::,'::::::,':::;\n\ `':,'::::::,:,':::::::::::::::::':::,'::_:::,'/\n\ __..:'::,':::::::--''' `-:,':,':::'::-' ,':::/\n\ _.::::::,:::.-''-`-`..'_,'. ,', , ' , ,' ', `','\n\ ,::SSt:''''` \\:. . ,' ' ,',' '_,'\n\ ``::._,'_'_,',.-'\n\ \\\\ \\\\\n\ \\\\_\\\\\n\ \\\\`-`.-'_\n\ .`-.\\\\__`. ``\n\ ``-.-._\n\ `"); SelectOne(); BTOUT; } CAsciiArt::~CAsciiArt() { } void CAsciiArt::AddPiece(const char *s) { BTIN; CAsciiPiece *p; const char *q; int tw, th, z; try { p = new CAsciiPiece(); } catch(...) { p = NULL; } if (p == NULL) NewException((double)sizeof(CAsciiPiece),__FILE__,__LINE__,__PRETTY_FUNCTION__); m_oaAsciiPieces.Add(p); p->m_iWidth = 0; tw = 0; p->m_iHeight = 0; q = s; while (*q != 0) { q++; tw++; if ((*q == '\n') || (*q == 0)) { if (tw-1 > p->m_iWidth) p->m_iWidth = (unsigned short)tw-1; tw = 0; p->m_iHeight++; if (*q == 0) break; } } try { p->m_pBuf = new char[p->m_iWidth*p->m_iHeight]; } catch(...) { p->m_pBuf = NULL; } if (p->m_pBuf == NULL) NewException((double)p->m_iWidth*p->m_iHeight*sizeof(char),__FILE__,__LINE__,__PRETTY_FUNCTION__); tw = 0; th = 0; q = s; while (*q != 0) { p->m_pBuf[tw+th*p->m_iWidth] = *q; q++; tw++; if ((*q == '\n') || (*q == 0)) { for (z=tw;zm_iWidth;z++) p->m_pBuf[z+th*p->m_iWidth] = ' '; tw = 0; th++; if (*q == 0) break; q++; } } /* printf("### Anfang ###\n"); for (th=0;thm_iHeight;th++) { printf("\""); for (tw=0;twm_iWidth;tw++) printf("%c",p->m_pBuf[tw+th*p->m_iWidth]); printf("\"\n"); } printf("### Ende ###\n");*/ BTOUT; } void CAsciiArt::SelectOne() { BTIN; m_iSelectedPiece = rand()%m_oaAsciiPieces.GetSize(); BTOUT; } int CAsciiArt::GetHeight() { BTIN; if (m_iSelectedPiece == -1) SelectOne(); BTOUT; return ((CAsciiPiece*)m_oaAsciiPieces[m_iSelectedPiece])->m_iHeight; } int CAsciiArt::GetWidth() { BTIN; if (m_iSelectedPiece == -1) SelectOne(); BTOUT; return ((CAsciiPiece*)m_oaAsciiPieces[m_iSelectedPiece])->m_iWidth; } char CAsciiArt::GetChar() { BTIN; char c; if (m_iSelectedPiece == -1) SelectOne(); if (m_iPosY == -1) { if (m_iPosX == -1) c = '/'; else if (m_iPosX == ((CAsciiPiece*)m_oaAsciiPieces[m_iSelectedPiece])->m_iWidth) c = '\\'; else if (m_iPosX > ((CAsciiPiece*)m_oaAsciiPieces[m_iSelectedPiece])->m_iWidth) c = 0; else c = '='; } else if (m_iPosY == ((CAsciiPiece*)m_oaAsciiPieces[m_iSelectedPiece])->m_iHeight+1) { if (m_iPosX > 0) c = 0; else c = ' '; } else if (m_iPosY == ((CAsciiPiece*)m_oaAsciiPieces[m_iSelectedPiece])->m_iHeight) { if (m_iPosX == -1) c = '\\'; else if (m_iPosX == ((CAsciiPiece*)m_oaAsciiPieces[m_iSelectedPiece])->m_iWidth) c = '/'; else if (m_iPosX > ((CAsciiPiece*)m_oaAsciiPieces[m_iSelectedPiece])->m_iWidth) c = 0; else c = '='; } else if (m_iPosX == ((CAsciiPiece*)m_oaAsciiPieces[m_iSelectedPiece])->m_iWidth) c = '|'; else if (m_iPosX == -1) c = '|'; else if (m_iPosX > ((CAsciiPiece*)m_oaAsciiPieces[m_iSelectedPiece])->m_iWidth) c = 0; else c = ((CAsciiPiece*)m_oaAsciiPieces[m_iSelectedPiece])->GetAt(m_iPosX,m_iPosY); m_iPosX++; BTOUT; return c; } char CAsciiPiece::GetAt(int x, int y) { return m_pBuf[x+y*m_iWidth]; } void CAsciiArt::NewLine() { BTIN; if (m_iSelectedPiece == -1) SelectOne(); m_iPosX = -1; m_iPosY++; if (m_iPosY > ((CAsciiPiece*)m_oaAsciiPieces[m_iSelectedPiece])->m_iHeight+1) { SelectOne(); m_iPosY = -1; } BTOUT; } travis-src-190101/src/asciiart.h0100777000000000000000000000340513412725655013415 0ustar00/***************************************************************************** TRAVIS - Trajectory Analyzer and Visualizer http://www.travis-analyzer.de/ Copyright (c) 2009-2019 Martin Brehm 2012-2019 Martin Thomas 2016-2019 Sascha Gehrke This file was written by Martin Brehm. --------------------------------------------------------------------------- This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . *****************************************************************************/ #ifndef ASCIIART_H #define ASCIIART_H // This must always be the first include directive #include "config.h" #include "xobject.h" #include "xobarray.h" #include "backtrace.h" class CAsciiPiece : public CxObject { public: char GetAt(int x, int y); CAsciiPiece() { } ~CAsciiPiece() { } unsigned short m_iWidth; unsigned short m_iHeight; char *m_pBuf; }; class CAsciiArt : public CxObject { public: void NewLine(); char GetChar(); int GetWidth(); int GetHeight(); int m_iPosX; int m_iPosY; void SelectOne(); CAsciiArt(); ~CAsciiArt(); void AddPiece(const char *s); int m_iSelectedPiece; CxObArray m_oaAsciiPieces; }; #endif travis-src-190101/src/atomgroup.cpp0100777000000000000000000002320513412725626014164 0ustar00/***************************************************************************** TRAVIS - Trajectory Analyzer and Visualizer http://www.travis-analyzer.de/ Copyright (c) 2009-2019 Martin Brehm 2012-2019 Martin Thomas 2016-2019 Sascha Gehrke This file was written by Martin Brehm. --------------------------------------------------------------------------- This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . *****************************************************************************/ // This must always be the first include directive #include "config.h" #include "atomgroup.h" #include "moltools.h" #include "travis.h" const char *GetRevisionInfo_atomgroup(unsigned int len) { static char buf[256]; GET_REVISION_INFO( buf, len ); return buf; } const char *GetSourceVersion_atomgroup() { static char buf[256]; GET_SOURCE_VERSION( buf ); return buf; } CAtomGroup::CAtomGroup() { m_iAtomGes = 0; m_pMolecule = NULL; m_sName = NULL; m_bAllAtoms = false; m_baAtomType.SetName("CAtomGroup::m_baAtomType"); m_baRealAtomType.SetName("CAtomGroup::m_baRealAtomType"); m_baAllAtoms.SetName("CAtomGroup::m_baAllAtoms"); m_oaAtoms.SetName("CAtomGroup::m_oaAtoms"); } CAtomGroup::~CAtomGroup() { if (m_sName != NULL) { delete[] m_sName; m_sName = NULL; } } void CAtomGroup::AddAtom(int atom, int num, bool all) { BTIN; int z, z2; CxIntArray *atoms; for (z=0;zGetSize();z2++) { if (atoms->GetAt(z2) == num) { eprintf("CAtomGroup::AddAtom(): Atom %s%d already included, ignoring this.\n",(const char*)((CAtom*)g_oaAtoms[atom])->m_sName,num+1); BTOUT; return; } } atoms->Add(num); m_iAtomGes++; if (all && (m_baAllAtoms[z]==0)) m_baAllAtoms[z] = 1; BTOUT; return; } } m_baAtomType.Add((unsigned char)atom); m_baRealAtomType.Add(m_pMolecule->m_baAtomIndex[atom]); try { atoms = new CxIntArray("CAtomGroup::AddAtom():atoms"); } catch(...) { atoms = NULL; } if (atoms == NULL) NewException((double)sizeof(CxIntArray),__FILE__,__LINE__,__PRETTY_FUNCTION__); atoms->Add(num); m_oaAtoms.Add(atoms); m_baAllAtoms.Add(all?1:0); m_iAtomGes++; BTOUT; } void CAtomGroup::AddAllAtoms(CMolecule *m, bool virt) { BTIN; int z, z2; CxIntArray *atoms; m_pMolecule = m; for (z=0;zm_baAtomIndex.GetSize()-(virt?0:1);z++) // Virtuellen Atome mitnehmen? { try { atoms = new CxIntArray("CAtomGroup::AddAllAtoms():atoms"); } catch(...) { atoms = NULL; } if (atoms == NULL) NewException((double)sizeof(CxIntArray),__FILE__,__LINE__,__PRETTY_FUNCTION__); for (z2=0;z2m_waAtomCount[z];z2++) atoms->Add(z2); m_iAtomGes += m->m_waAtomCount[z]; m_oaAtoms.Add(atoms); m_baAtomType.Add((unsigned char)z); m_baRealAtomType.Add(m_pMolecule->m_baAtomIndex[z]); m_baAllAtoms.Add(1); } m_bAllAtoms = true; BuildName(); BTOUT; } bool CAtomGroup::ParseAtoms(CMolecule *mol, const char *s) { BTIN; const char *p, *q; char buf[32]; // CxString buf; int atom, la, i, i2, z; bool m, all; const char *allowed = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890,-#_ "; if ((s[0] == '*') && (s[1] == 0)) { AddAllAtoms(mol,false); return true; } Reset(); m_pMolecule = mol; p = s; atom = -1; la = -1; i = -1; i2 = -1; m = false; all = false; while (*p != 0) { while (*p == ' ') p++; if (strchr(allowed,*p) == NULL) { eprintf("Error: Character \"%c\" not allowed.\n",*p); BTOUT; return false; } q = p; if (isalpha(*q) || (*q == '_') || (*q == '#')) { if (m) { eprintf("Error: Only digit allowed after \"-\".\n"); BTOUT; return false; } while (isalpha(*q) || (*q == '_') || (*q == '#')) q++; if (q-p >= 32) { eprintf("ParseAtoms(): Internal Error A (%ld >= 32).\n",q-p); return false; } memcpy(buf,p,q-p); buf[q-p] = 0; atom = mol->FindAtomInMol(buf); if (atom == -1) { eprintf("Error: Atom \"%s\" not in the molecule.\n",buf); BTOUT; return false; } } else if (isdigit(*q)) { if (atom == -1) atom = la; if (atom == -1) { eprintf("Error: Number in the beginning not possible.\n"); BTOUT; return false; } while (isdigit(*q)) q++; if ((*q != '-') && (*q != ',') && (*q != ' ') && (*q != 0)) { eprintf("Error: Only \",\" or \"-\" may follow after a number.\n"); BTOUT; return false; } if (q-p >= 32) { eprintf("ParseAtoms(): Internal Error B (%ld >= 32).\n",q-p); return false; } memcpy(buf,p,q-p); buf[q-p] = 0; if (atoi(buf)-1 >= mol->m_waAtomCount[atom]) { eprintf("Error: Only %d %s atoms in the molecule (requested: %d)\n",mol->m_waAtomCount[atom],(const char*)((CAtom*)g_oaAtoms[mol->m_baAtomIndex[atom]])->m_sName,atoi(buf)); BTOUT; return false; } if (m) { i2 = atoi(buf)-1; if (i2 < i) { eprintf("Error: Invalid atom range, %d < %d.\n",i2+1,i+1); BTOUT; return false; } } else i = atoi(buf)-1; } else if (*q == '-') { if (i == -1) { eprintf("Error: \"-\" without preceding number.\n"); BTOUT; return false; } m = true; q++; } else if (*q == ',') { if (atom == -1) { eprintf("Error: Comma without atom.\n"); BTOUT; return false; } if (i == -1) { i = 0; i2 = mol->m_waAtomCount[atom]-1; all = true; } else all = false; if (all) { for (z=i;z<=i2;z++) AddAtom(atom,z,true); } else if (m) { for (z=i;z<=i2;z++) AddAtom(atom,z,false); } else AddAtom(atom,i,false); la = atom; m = false; i = -1; i2 = -1; atom = -1; q++; } // _end: p = q; } if (atom != -1) { if (i == -1) { i = 0; i2 = mol->m_waAtomCount[atom]-1; all = true; } else all = false; if (all) { for (z=i;z<=i2;z++) AddAtom(atom,z,true); } else if (m) { for (z=i;z<=i2;z++) AddAtom(atom,z,false); } else AddAtom(atom,i,false); } if (m_iAtomGes == 0) return false; SortAtoms(); BuildName(); BTOUT; return true; } void CAtomGroup::BuildName() { // char tmp[4096], buf2[32]; CxString tmp, buf2; CxIntArray *atoms; int z, z2, z3; tmp = ""; for (z=0;zm_sName); tmp.strcat(((CAtom*)g_oaAtoms[m_baRealAtomType[z]])->m_sName); } else { atoms = (CxIntArray*)m_oaAtoms[z]; for (z2=0;z2GetSize();z2++) { z3 = z2; if (z2 < atoms->GetSize()-1) { while (atoms->GetAt(z3)+1 == atoms->GetAt(z3+1)) { z3++; if (z3 >= atoms->GetSize()-1) break; } // if (z3 > z2) // z3--; } if (z3 > z2) { // sprintf(buf2,"%s%d-%d",((CAtom*)g_oaAtoms[m_baRealAtomType[z]])->m_sName,atoms->GetAt(z2)+1,atoms->GetAt(z3)+1); buf2.sprintf("%s%d-%d",(const char*)((CAtom*)g_oaAtoms[m_baRealAtomType[z]])->m_sName,atoms->GetAt(z2)+1,atoms->GetAt(z3)+1); z2 = z3; } else buf2.sprintf("%s%d",(const char*)((CAtom*)g_oaAtoms[m_baRealAtomType[z]])->m_sName,atoms->GetAt(z2)+1); // sprintf(buf2,"%s%d",((CAtom*)g_oaAtoms[m_baRealAtomType[z]])->m_sName,atoms->GetAt(z2)+1); // strcat(tmp,buf2); tmp.strcat(buf2); } } } try { m_sName = new char[strlen(tmp)+1]; } catch(...) { m_sName = NULL; } if (m_sName == NULL) NewException((double)(strlen(tmp)+1)*sizeof(char),__FILE__,__LINE__,__PRETTY_FUNCTION__); strcpy(m_sName,tmp); } void CAtomGroup::SortAtoms() { CxIntArray *atoms; int z, z2, z3, i, j; for (z=0;zGetSize();z2++) { j = 999999; i = -1; for (z3=z2;z3GetSize();z3++) { if (atoms->GetAt(z3) < j) { j = atoms->GetAt(z3); i = z3; } } j = atoms->GetAt(i); atoms->SetAt(i,atoms->GetAt(z2)); atoms->SetAt(z2,j); } } } } void CAtomGroup::Reset() { int z; m_iAtomGes = 0; m_baAllAtoms.RemoveAll(); m_baAtomType.RemoveAll(); m_baRealAtomType.RemoveAll(); for (z=0;zm_baAllAtoms); m_baAtomType.CopyFrom(&p->m_baAtomType); m_baRealAtomType.CopyFrom(&p->m_baRealAtomType); m_iAtomGes = p->m_iAtomGes; m_pMolecule = p->m_pMolecule; m_bAllAtoms = p->m_bAllAtoms; if (p->m_sName != NULL) { try { m_sName = new char[strlen(p->m_sName)+1]; } catch(...) { m_sName = NULL; } if (m_sName == NULL) NewException((double)(strlen(p->m_sName)+1)*sizeof(char),__FILE__,__LINE__,__PRETTY_FUNCTION__); strcpy(m_sName,p->m_sName); } for (z=0;zCopyFrom((CxIntArray*)p->m_oaAtoms[z]); m_oaAtoms.Add(wa); } } travis-src-190101/src/atomgroup.h0100777000000000000000000000352313412725650013627 0ustar00/***************************************************************************** TRAVIS - Trajectory Analyzer and Visualizer http://www.travis-analyzer.de/ Copyright (c) 2009-2019 Martin Brehm 2012-2019 Martin Thomas 2016-2019 Sascha Gehrke This file was written by Martin Brehm. --------------------------------------------------------------------------- This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . *****************************************************************************/ #ifndef ATOMGROUP_H #define ATOMGROUP_H // This must always be the first include directive #include "config.h" #include "xobject.h" #include "xbytearray.h" #include "tools.h" class CMolecule; class CAtomGroup : public CxObject { public: void CopyFrom(CAtomGroup *p); void Reset(); void SortAtoms(); CAtomGroup(); ~CAtomGroup(); CMolecule* m_pMolecule; CxByteArray m_baAtomType; CxByteArray m_baRealAtomType; CxByteArray m_baAllAtoms; CxObArray m_oaAtoms; // Enthaelt CxWordArrays int m_iAtomGes; bool m_bAllAtoms; bool ParseAtoms(CMolecule *m, const char *s); void AddAtom(int atom, int num, bool all); void AddAllAtoms(CMolecule *m, bool virt); void BuildName(); char *m_sName; }; #endif travis-src-190101/src/backtrace.cpp0100777000000000000000000002637413412725620014072 0ustar00/***************************************************************************** TRAVIS - Trajectory Analyzer and Visualizer http://www.travis-analyzer.de/ Copyright (c) 2009-2019 Martin Brehm 2012-2019 Martin Thomas 2016-2019 Sascha Gehrke This file was written by Martin Brehm. --------------------------------------------------------------------------- This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . *****************************************************************************/ // This must always be the first include directive #include "config.h" #include "backtrace.h" #include "travis.h" #include "maintools.h" #ifdef TARGET_LINUX #include #endif const char *GetRevisionInfo_backtrace(unsigned int len) { static char buf[256]; GET_REVISION_INFO( buf, len ); return buf; } const char *GetSourceVersion_backtrace() { static char buf[256]; GET_SOURCE_VERSION( buf ); return buf; } CxObArray g_oaBackTrace; char *g_sExeName; void DumpBacktrace() { int z; CxTracePoint *p; mprintf(YELLOW,">>> Backtrace\n"); for (z=0;zm_sMessage[0] == 0) mprintf(" %d.) %s in %s after line %lu.\n",z+1,p->m_sFunction,p->m_sFile,p->m_iLine); else mprintf(" %d.) %s in %s after line %lu: \"%s\"\n",z+1,p->m_sFunction,p->m_sFile,p->m_iLine,p->m_sMessage); } mprintf(YELLOW,"<<< Backtrace\n"); } #ifdef TARGET_LINUX void DumpLinuxBacktrace() { void *buffer[4096]; char **strings, buf[256], *p; int n, z, i, j; bool showall; FILE *a; // mprintf(YELLOW,"*** Linux Backtrace ***\n"); n = backtrace(buffer,4096); if (n <= 0) { eprintf("Could not retrieve stack trace.\n"); return; } // mprintf("Stack contains %d Frames.\n",n); strings = backtrace_symbols(buffer,n); if (strings == NULL) eprintf("Could not retrieve debug symbol strings.\n"); /* for (z=0;z -f -i -C -e %s\")\n",g_sExeName); a = fopen(g_sExeName,"rb"); if (a == NULL) { eprintf("Could not locate \"%s\" :-(\n",g_sExeName); } else { fclose(a); j = 0; for (z=0;z (void*)0x400000)) j++; if (j < 3) showall = true; else showall = false; for (z=0;z (void*)0x400000))) { mprintf(GREEN," # %2d ",n-z); sprintf(buf,"addr2line %p -f -i -C -e %s > tmp.txt",buffer[z],g_sExeName); (void)system(buf); a = fopen("tmp.txt","rt"); if (a == NULL) { eprintf("Error. Make sure you have the addr2line tool installed (it is part of \"binutils\")\nand writing permission to this directory.\n"); continue; } mprintf("- [%10p] ",buffer[z]); i = 0; while (true) { (void)fgets(buf,256,a); if (feof(a)) break; if (strlen(buf) > 2) { if (i == 2) { i = 0; mprintf("\n "); } buf[strlen(buf)-1] = 0; p = strrchr(buf,'/'); if (p == NULL) p = buf; else p++; mprintf("- %s ",p); i++; } } fclose(a); mprintf("\n"); } } (void)system("rm tmp.txt"); } } #endif void Crash() { bool b; g_bCheckWrite = false; UninstallSignalHandler(); b = g_bGlobalPsycho; g_bGlobalPsycho = false; mprintf(WHITE,"TRAVIS apparently has crashed :-( Sorry.\n"); mprintf(WHITE,"Please send the log file (travis.log) to the developers,\n"); mprintf(WHITE,"making them able to analyze and fix this error.\n"); BTDUMP; #ifdef TARGET_LINUX DumpLinuxBacktrace(); #endif if (g_bSMode) { mprintf("\n"); g_bGlobalPsycho = b; PrintSMode(); g_bGlobalPsycho = false; mprintf("\n"); } eprintf("Delivering control to operating system.\n"); /*#ifdef TARGET_WINDOWS char buf[2]; gets(buf); #endif*/ abort(); } void CrashAbort() { bool b; g_bCheckWrite = false; UninstallSignalHandler(); b = g_bGlobalPsycho; g_bGlobalPsycho = false; mprintf(WHITE,"TRAVIS had to abort execution.\n"); mprintf(WHITE,"Hopefully, the reason was printed above this message.\n"); BTDUMP; #ifdef TARGET_LINUX DumpLinuxBacktrace(); #endif if (g_bSMode) { mprintf("\n"); g_bGlobalPsycho = b; PrintSMode(); g_bGlobalPsycho = false; mprintf("\n"); } eprintf("Delivering control to operating system.\n"); /*#ifdef TARGET_WINDOWS char buf[2]; gets(buf); #endif*/ abort(); } void CrashTerm() { bool b; g_bCheckWrite = false; UninstallSignalHandler(); b = g_bGlobalPsycho; g_bGlobalPsycho = false; mprintf(WHITE,"TRAVIS received a termination request (SIGTERM) from the operating system\n"); mprintf(WHITE,"and therefore has to stop execution.\n"); BTDUMP; #ifdef TARGET_LINUX DumpLinuxBacktrace(); #endif if (g_bSMode) { mprintf("\n"); g_bGlobalPsycho = b; PrintSMode(); g_bGlobalPsycho = false; mprintf("\n"); } eprintf("Delivering control to operating system.\n"); /*#ifdef TARGET_WINDOWS char buf[2]; gets(buf); #endif*/ abort(); } void CrashInt() { bool b; UninstallSignalHandler(); b = g_bGlobalPsycho; g_bGlobalPsycho = false; BTDUMP; #ifdef TARGET_LINUX DumpLinuxBacktrace(); #endif if (g_bSMode) { mprintf("\n"); g_bGlobalPsycho = b; PrintSMode(); g_bGlobalPsycho = false; mprintf("\n"); } eprintf("Delivering control to operating system.\n"); /*#ifdef TARGET_WINDOWS char buf[2]; gets(buf); #endif*/ abort(); } void SIGNAL_SEGV(int param) { UNUSED(param); // Suppress "unused parameter" warning eprintf("\n\n*** SIGSEGV caught: Segmentation fault ***\n"); Crash(); } void SIGNAL_FPE(int param) { UNUSED(param); // Suppress "unused parameter" warning eprintf("\n\n*** SIGFPE caught: Floating point exception ***\n"); Crash(); } void SIGNAL_ILL(int param) { UNUSED(param); // Suppress "unused parameter" warning eprintf("\n\n*** SIGILL caught: Illegal instruction ***\n"); Crash(); } void SIGNAL_INT(int param) { bool b; UNUSED(param); // Suppress "unused parameter" warning b = g_bGlobalPsycho; if (!g_bAbortAnalysis) { mprintf("\n\n*** SIGINT: Analysis softly interrupted by user ***\n"); mprintf(" Press CTRL+C again to immediately stop execution.\n"); g_bAbortAnalysis = true; signal(SIGINT,SIGNAL_INT); return; } else { g_bGlobalPsycho = false; eprintf("\n\n*** SIGINT caught: Hard interrupt by user ***\n"); eprintf("Stopping execution.\n"); g_bGlobalPsycho = b; CrashInt(); exit(0); } } void SIGNAL_ABRT(int param) { UNUSED(param); // Suppress "unused parameter" warning eprintf("\n\n*** SIGABRT caught: Abnormal program termination ***\n"); CrashAbort(); } void SIGNAL_TERM(int param) { UNUSED(param); // Suppress "unused parameter" warning eprintf("\n\n*** SIGTERM caught: Terminating ***\n"); CrashTerm(); } #ifdef TARGET_LINUX void SIGNAL_HANGUP(int param) { UNUSED(param); // Suppress "unused parameter" warning eprintf("\n\n*** SIGHUP caught: Trying to ignore hangup ^^ ***\n"); signal(SIGHUP,SIGNAL_HANGUP); } #endif void InstallSignalHandler() { BTIN; signal(SIGSEGV,SIGNAL_SEGV); signal(SIGFPE,SIGNAL_FPE); signal(SIGILL,SIGNAL_ILL); signal(SIGINT,SIGNAL_INT); signal(SIGABRT,SIGNAL_ABRT); signal(SIGTERM,SIGNAL_TERM); #ifdef TARGET_LINUX signal(SIGHUP,SIGNAL_HANGUP); #endif BTOUT; } void UninstallSignalHandler() { BTIN; signal(SIGSEGV,SIG_DFL); signal(SIGFPE,SIG_DFL); signal(SIGILL,SIG_DFL); signal(SIGINT,SIG_DFL); signal(SIGABRT,SIG_DFL); signal(SIGTERM,SIG_DFL); #ifdef TARGET_LINUX signal(SIGHUP,SIG_DFL); #endif BTOUT; } void BoundsException(int i, int j, const char *filename, int line, const char *function) { UninstallSignalHandler(); g_bGlobalPsycho = false; eprintf("\n*** Array Boundary Violation ***\n\n"); eprintf("Caught an exception while accessing array element %d/%d (valid range 0-%d).\n",i,j,j-1); mprintf("The exception was raised in %s:%d",filename,line); if (function[0] != 0) mprintf(" - %s",function); mprintf(".\n\n"); BTDUMP; #ifdef TARGET_LINUX DumpLinuxBacktrace(); #endif eprintf("Delivering control to operating system.\n"); abort(); } void BoundsException(int i, int j, const char *filename, int line, const char *function, const char *info) { UninstallSignalHandler(); g_bGlobalPsycho = false; eprintf("\n*** Array Boundary Violation ***\n\n"); eprintf("Caught an exception while accessing array element %d/%d (valid range 0-%d).\n",i,j,j-1); mprintf("The exception was raised in %s:%d",filename,line); if (function[0] != 0) mprintf(" - %s",function); if (info != NULL) mprintf(", concerning %s",info); mprintf(".\n\n"); BTDUMP; #ifdef TARGET_LINUX DumpLinuxBacktrace(); #endif eprintf("Delivering control to operating system.\n"); abort(); } void NewException(double d, const char *filename, int line, const char *function) { UninstallSignalHandler(); g_bGlobalPsycho = false; eprintf("\n*** Out of Memory ***\n\n"); eprintf("Caught an exception while allocating %s of memory.\n",FormatBytes(d)); mprintf("The exception was raised in %s:%d",filename,line); if (function[0] != 0) mprintf(" - %s",function); mprintf(".\n"); if (d <= 0) { mprintf("TRAVIS tried to allocate a negative amount of memory, which is clearly\n"); mprintf("due to a bug.\n"); } else { mprintf("It is likely that TRAVIS requested more RAM than available on this machine.\n"); if (d >= 4000000000.0) mprintf("Apart from that, more than 4 GB cannot be allocated in one single call.\n"); mprintf("Adjust your input parameters.\n\n"); } BTDUMP; #ifdef TARGET_LINUX DumpLinuxBacktrace(); #endif eprintf("Delivering control to operating system.\n"); abort(); } void NewException(double d, const char *filename, int line, const char *function, const char *info) { UninstallSignalHandler(); g_bGlobalPsycho = false; eprintf("\n*** Out of Memory ***\n\n"); eprintf("Caught an exception while allocating %s of memory.\n",FormatBytes(d)); mprintf("The exception was raised in %s:%d",filename,line); if (function[0] != 0) mprintf(" - %s",function); if (info != NULL) mprintf(", concerning %s",info); mprintf(".\n"); if (d <= 0) { mprintf("TRAVIS tried to allocate a negative amount of memory, which is clearly\n"); mprintf("due to a bug.\n"); } else { mprintf("It is likely that TRAVIS requested more RAM than available on this machine.\n"); if (d >= 4000000000.0) mprintf("Apart from that, more than 4 GB cannot be allocated in one single call.\n"); mprintf("Adjust your input parameters.\n\n"); } BTDUMP; #ifdef TARGET_LINUX DumpLinuxBacktrace(); #endif eprintf("Delivering control to operating system.\n"); abort(); } travis-src-190101/src/backtrace.h0100777000000000000000000001276313412725657013546 0ustar00/***************************************************************************** TRAVIS - Trajectory Analyzer and Visualizer http://www.travis-analyzer.de/ Copyright (c) 2009-2019 Martin Brehm 2012-2019 Martin Thomas 2016-2019 Sascha Gehrke This file was written by Martin Brehm. --------------------------------------------------------------------------- This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . *****************************************************************************/ #ifndef BACKTRACE_H #define BACKTRACE_H // This must always be the first include directive #include "config.h" #include #include #include "tools.h" #include "xobject.h" #include "xobarray.h" class CxTracePoint : public CxObject { public: CxTracePoint() { } ~CxTracePoint() { } char m_sFunction[256]; char m_sFile[64]; unsigned long m_iLine; char m_sMessage[256]; }; class CxObArray; extern CxObArray g_oaBackTrace; extern char *g_sExeName; #ifdef DEBUG_BACKTRACE #define BTDUMP DumpBacktrace() #ifdef TARGET_WINDOWS #define BTIN { if (g_oaBackTrace.GetSize() > 500) { eprintf("*** Trace to deep ***\n"); DumpBacktrace(); abort(); } CxTracePoint *ctp = new CxTracePoint(); strcpy(ctp->m_sFile,__FILE__); ctp->m_sFunction[0] = 0; ctp->m_iLine = __LINE__; ctp->m_sMessage[0] = 0; g_oaBackTrace.Add(ctp); } #define BTOUT { if (g_oaBackTrace.GetSize() == 0) { eprintf("*** BTOUT Error ***\n"); abort(); } delete (CxTracePoint*)g_oaBackTrace[g_oaBackTrace.GetSize()-1]; g_oaBackTrace.RemoveAt(g_oaBackTrace.GetSize()-1,1); } #define BTL ((CxTracePoint*)g_oaBackTrace[g_oaBackTrace.GetSize()-1])->m_iLine = __LINE__; #define BTMSG(msg) { ((CxTracePoint*)g_oaBackTrace[g_oaBackTrace.GetSize()-1])->m_iLine = __LINE__; strcpy(((CxTracePoint*)g_oaBackTrace[g_oaBackTrace.GetSize()-1])->m_sMessage,msg); } #else #define BTIN { if (g_oaBackTrace.GetSize() > 500) { eprintf("*** Trace to deep ***\n"); DumpBacktrace(); abort(); } CxTracePoint *ctp = new CxTracePoint(); strcpy(ctp->m_sFile,__FILE__); strcpy(ctp->m_sFunction,__PRETTY_FUNCTION__); ctp->m_iLine = __LINE__; ctp->m_sMessage[0] = 0; g_oaBackTrace.Add(ctp); } #define BTOUT { if (g_oaBackTrace.GetSize() == 0) { eprintf("*** BTOUT Error ***\n"); abort(); } delete (CxTracePoint*)g_oaBackTrace[g_oaBackTrace.GetSize()-1]; g_oaBackTrace.RemoveAt(g_oaBackTrace.GetSize()-1,1); } #define BTL ((CxTracePoint*)g_oaBackTrace[g_oaBackTrace.GetSize()-1])->m_iLine = __LINE__; #define BTMSG(msg) { ((CxTracePoint*)g_oaBackTrace[g_oaBackTrace.GetSize()-1])->m_iLine = __LINE__; strcpy(((CxTracePoint*)g_oaBackTrace[g_oaBackTrace.GetSize()-1])->m_sMessage,msg); } #endif #else #define BTDUMP #define BTIN #define BTOUT #define BTL #define BTMSG(msg) #endif #ifdef DEBUG_EXTENDED_BACKTRACE #ifdef TARGET_WINDOWS #define BXIN { if (g_oaBackTrace.GetSize() > 500) { eprintf("*** Trace to deep ***\n"); DumpBacktrace(); abort(); } CxTracePoint *ctp = new CxTracePoint(); strcpy(ctp->m_sFile,__FILE__); ctp->m_sFunction[0] = 0; ctp->m_iLine = __LINE__; ctp->m_sMessage[0] = 0; g_oaBackTrace.Add(ctp); } #define BXOUT { if (g_oaBackTrace.GetSize() == 0) { eprintf("*** BXOUT Error ***\n"); abort(); } delete (CxTracePoint*)g_oaBackTrace[g_oaBackTrace.GetSize()-1]; g_oaBackTrace.RemoveAt(g_oaBackTrace.GetSize()-1,1); } #define BXL ((CxTracePoint*)g_oaBackTrace[g_oaBackTrace.GetSize()-1])->m_iLine = __LINE__; #define BXMSG(msg) { ((CxTracePoint*)g_oaBackTrace[g_oaBackTrace.GetSize()-1])->m_iLine = __LINE__; strcpy(((CxTracePoint*)g_oaBackTrace[g_oaBackTrace.GetSize()-1])->m_sMessage,msg); } #else #define BXIN { if (g_oaBackTrace.GetSize() > 500) { eprintf("*** Trace to deep ***\n"); DumpBacktrace(); abort(); } CxTracePoint *ctp = new CxTracePoint(); strcpy(ctp->m_sFile,__FILE__); strcpy(ctp->m_sFunction,__PRETTY_FUNCTION__); ctp->m_iLine = __LINE__; ctp->m_sMessage[0] = 0; g_oaBackTrace.Add(ctp); } #define BXOUT { if (g_oaBackTrace.GetSize() == 0) { eprintf("*** BXOUT Error ***\n"); abort(); } delete (CxTracePoint*)g_oaBackTrace[g_oaBackTrace.GetSize()-1]; g_oaBackTrace.RemoveAt(g_oaBackTrace.GetSize()-1,1); } #define BXL ((CxTracePoint*)g_oaBackTrace[g_oaBackTrace.GetSize()-1])->m_iLine = __LINE__; #define BXMSG(msg) { ((CxTracePoint*)g_oaBackTrace[g_oaBackTrace.GetSize()-1])->m_iLine = __LINE__; strcpy(((CxTracePoint*)g_oaBackTrace[g_oaBackTrace.GetSize()-1])->m_sMessage,msg); } #endif #else #define BXIN #define BXOUT #define BXL #define BXMSG(msg) #endif void SIGNAL_SEGV(int param); void InstallSignalHandler(); void UninstallSignalHandler(); void DumpBacktrace(); void NewException(double d, const char *filename, int line, const char *function); void NewException(double d, const char *filename, int line, const char *function, const char *info); void BoundsException(int i, int j, const char *filename, int line, const char *function); void BoundsException(int i, int j, const char *filename, int line, const char *function, const char *info); #endif travis-src-190101/src/base64.cpp0100777000000000000000000000517413412725635013240 0ustar00/***************************************************************************** TRAVIS - Trajectory Analyzer and Visualizer http://www.travis-analyzer.de/ Copyright (c) 2009-2019 Martin Brehm 2012-2019 Martin Thomas 2016-2019 Sascha Gehrke This file was written by Martin Brehm. --------------------------------------------------------------------------- This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . *****************************************************************************/ // This must always be the first include directive #include "config.h" #include "base64.h" #include "string.h" const char *GetRevisionInfo_base64(unsigned int len) { static char buf[256]; GET_REVISION_INFO( buf, len ); return buf; } const char *GetSourceVersion_base64() { static char buf[256]; GET_SOURCE_VERSION( buf ); return buf; } static const char BASE64_table[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; //static const int BASE64_INPUT_SIZE = 57; bool isbase64(char c) { return c && strchr(BASE64_table, c) != NULL; } inline char BASE64_value(char c) { const char *p = strchr(BASE64_table, c); if(p) { return (char)(p-BASE64_table); } else { return 0; } } int UnBase64(unsigned char *dest, const unsigned char *src, int srclen) { *dest = 0; if(*src == 0) { return 0; } unsigned char *p = dest; do { char a = BASE64_value(src[0]); char b = BASE64_value(src[1]); char c = BASE64_value(src[2]); char d = BASE64_value(src[3]); *p++ = (a << 2) | (b >> 4); *p++ = (b << 4) | (c >> 2); *p++ = (c << 6) | d; if(!isbase64(src[1])) { p -= 2; break; } else if(!isbase64(src[2])) { p -= 2; break; } else if(!isbase64(src[3])) { p--; break; } src += 4; while(*src && (*src == 13 || *src == 10)) src++; } while(srclen-= 4); *p = 0; return (int)(p-dest); } travis-src-190101/src/base64.h0100777000000000000000000000247413412725666012711 0ustar00/***************************************************************************** TRAVIS - Trajectory Analyzer and Visualizer http://www.travis-analyzer.de/ Copyright (c) 2009-2019 Martin Brehm 2012-2019 Martin Thomas 2016-2019 Sascha Gehrke This file was written by Martin Brehm. --------------------------------------------------------------------------- This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . *****************************************************************************/ #ifndef BASE64_H #define BASE64_H // This must always be the first include directive #include "config.h" int UnBase64(unsigned char *dest, const unsigned char *src, int srclen); #endif travis-src-190101/src/bicgstab.cpp0100777000000000000000000006531313412725634013732 0ustar00/***************************************************************************** TRAVIS - Trajectory Analyzer and Visualizer http://www.travis-analyzer.de/ Copyright (c) 2009-2019 Martin Brehm 2012-2019 Martin Thomas 2016-2019 Sascha Gehrke This file was written by Martin Thomas. --------------------------------------------------------------------------- This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . *****************************************************************************/ // This must always be the first include directive #include "config.h" #include "bicgstab.h" #include "3df.h" #include "globalvar.h" const char *GetRevisionInfo_bicgstab(unsigned int len) { static char buf[256]; GET_REVISION_INFO( buf, len ); return buf; } const char *GetSourceVersion_bicgstab() { static char buf[256]; GET_SOURCE_VERSION( buf ); return buf; } CSparseMatrix::CSparseMatrix() { m_size = 0; m_val = NULL; m_colInd = NULL; m_rowPtr = NULL; } CSparseMatrix::CSparseMatrix(const CSparseMatrix &matrix) { m_size = matrix.m_size; try { m_val = new double[matrix.m_rowPtr[matrix.m_size]]; } catch(...) { m_val = NULL; } if (m_val == NULL) NewException((double)matrix.m_rowPtr[matrix.m_size] * sizeof(double), __FILE__, __LINE__, __PRETTY_FUNCTION__); memcpy(m_val, matrix.m_val, matrix.m_rowPtr[matrix.m_size] * sizeof(double)); try { m_colInd = new int[matrix.m_rowPtr[matrix.m_size]]; } catch(...) { m_colInd = NULL; } if (m_colInd == NULL) NewException((double)matrix.m_rowPtr[matrix.m_size] * sizeof(int), __FILE__, __LINE__, __PRETTY_FUNCTION__); memcpy(m_colInd, matrix.m_colInd, matrix.m_rowPtr[matrix.m_size] * sizeof(int)); try { m_rowPtr = new int[matrix.m_size + 1]; } catch(...) { m_rowPtr = NULL; } if (m_rowPtr == NULL) NewException((double)(matrix.m_size + 1) * sizeof(int), __FILE__, __LINE__, __PRETTY_FUNCTION__); memcpy(m_rowPtr, matrix.m_rowPtr, (matrix.m_size + 1) * sizeof(int)); } CSparseMatrix::~CSparseMatrix() { if (m_val != NULL) delete[] m_val; if (m_colInd != NULL) delete[] m_colInd; if (m_rowPtr != NULL) delete[] m_rowPtr; } void CSparseMatrix::setTest() { m_size = 9; m_val = new double[45]; m_colInd = new int[45]; m_rowPtr = new int[10]; m_val[0] = 8.0; m_val[1] = -0.5; m_val[2] = -1.5; m_val[3] = -0.5; m_val[4] = -1.5; m_val[5] = -1.5; m_val[6] = 3.0; m_val[7] = -0.5; m_val[8] = -0.5; m_val[9] = -1.5; m_val[10] = -0.5; m_val[11] = -1.5; m_val[12] = 4.0; m_val[13] = -0.5; m_val[14] = -1.5; m_val[15] = -1.5; m_val[16] = 2.0; m_val[17] = -0.5; m_val[18] = -1.5; m_val[19] = -0.5; m_val[20] = -1.5; m_val[21] = -1.5; m_val[22] = 1.0; m_val[23] = -0.5; m_val[24] = -0.5; m_val[25] = -1.5; m_val[26] = -0.5; m_val[27] = -1.5; m_val[28] = 3.0; m_val[29] = -0.5; m_val[30] = -0.5; m_val[31] = -1.5; m_val[32] = 5.0; m_val[33] = -0.5; m_val[34] = -1.5; m_val[35] = -0.5; m_val[36] = -1.5; m_val[37] = -1.5; m_val[38] = 6.0; m_val[39] = -0.5; m_val[40] = -0.5; m_val[41] = -1.5; m_val[42] = -0.5; m_val[43] = -1.5; m_val[44] = 2.0; m_colInd[0] = 0; m_colInd[1] = 1; m_colInd[2] = 2; m_colInd[3] = 3; m_colInd[4] = 6; m_colInd[5] = 0; m_colInd[6] = 1; m_colInd[7] = 2; m_colInd[8] = 4; m_colInd[9] = 7; m_colInd[10] = 0; m_colInd[11] = 1; m_colInd[12] = 2; m_colInd[13] = 5; m_colInd[14] = 8; m_colInd[15] = 0; m_colInd[16] = 3; m_colInd[17] = 4; m_colInd[18] = 5; m_colInd[19] = 6; m_colInd[20] = 1; m_colInd[21] = 3; m_colInd[22] = 4; m_colInd[23] = 5; m_colInd[24] = 7; m_colInd[25] = 2; m_colInd[26] = 3; m_colInd[27] = 4; m_colInd[28] = 5; m_colInd[29] = 8; m_colInd[30] = 0; m_colInd[31] = 3; m_colInd[32] = 6; m_colInd[33] = 7; m_colInd[34] = 8; m_colInd[35] = 1; m_colInd[36] = 4; m_colInd[37] = 6; m_colInd[38] = 7; m_colInd[39] = 8; m_colInd[40] = 2; m_colInd[41] = 5; m_colInd[42] = 6; m_colInd[43] = 7; m_colInd[44] = 8; m_rowPtr[0] = 0; m_rowPtr[1] = 5; m_rowPtr[2] = 10; m_rowPtr[3] = 15; m_rowPtr[4] = 20; m_rowPtr[5] = 25; m_rowPtr[6] = 30; m_rowPtr[7] = 35; m_rowPtr[8] = 40; m_rowPtr[9] = 45; } void CSparseMatrix::matrixVectorProduct(const double *vect, double *result) const { int i; for (i = 0; i < m_size; i++) { result[i] = 0.0; int j; for (j = m_rowPtr[i]; j < m_rowPtr[i + 1]; j++) { result[i] += m_val[j] * vect[m_colInd[j]]; } } } void CCurrentPDEDiscretizer::discretize(CSparseMatrix *pdeMatrix, const C3DF &electronDensity, const C3DF &electronDensityGradientX, const C3DF &electronDensityGradientY, const C3DF &electronDensityGradientZ) { if (pdeMatrix->m_val != NULL) delete[] pdeMatrix->m_val; if (pdeMatrix->m_colInd != NULL) delete[] pdeMatrix->m_colInd; if (pdeMatrix->m_rowPtr != NULL) delete[] pdeMatrix->m_rowPtr; pdeMatrix->m_size = electronDensity.m_iRes[0] * electronDensity.m_iRes[1] * electronDensity.m_iRes[2]; int numEntries = 7 * pdeMatrix->m_size; try { pdeMatrix->m_val = new double[numEntries]; } catch(...) { pdeMatrix->m_val = NULL; } if (pdeMatrix->m_val == NULL) NewException((double)numEntries * sizeof(double), __FILE__, __LINE__, __PRETTY_FUNCTION__); try { pdeMatrix->m_colInd = new int[numEntries]; } catch(...) { pdeMatrix->m_colInd = NULL; } if (pdeMatrix->m_colInd == NULL) NewException((double)numEntries * sizeof(int), __FILE__, __LINE__, __PRETTY_FUNCTION__); try { pdeMatrix->m_rowPtr = new int[pdeMatrix->m_size + 1]; } catch(...) { pdeMatrix->m_rowPtr = NULL; } if (pdeMatrix->m_rowPtr == NULL) NewException((double)(pdeMatrix->m_size + 1) * sizeof(int), __FILE__, __LINE__, __PRETTY_FUNCTION__); // mprintf(GREEN, "%#.10g %#.10g %#.10g %#.10g %#.10g\n", electronDensity.m_pBin[0], electronDensityGradientX.m_pBin[0], electronDensityGradientY.m_pBin[0], electronDensityGradientZ.m_pBin[0], g_fCubeXStep); int j = 0; int i; for (i = 0; i < pdeMatrix->m_size; i++) { pdeMatrix->m_rowPtr[i] = j; if (i >= electronDensity.m_iRes[0] * electronDensity.m_iRes[1] * (electronDensity.m_iRes[2] - 1)) { pdeMatrix->m_val[j] = 1.0 * electronDensity.m_pBin[i] / (g_fCubeZStep * g_fCubeZStep) + 0.5 * electronDensityGradientZ.m_pBin[i] / g_fCubeZStep; pdeMatrix->m_colInd[j] = i - electronDensity.m_iRes[0] * electronDensity.m_iRes[1] * (electronDensity.m_iRes[2] - 1); j++; } if (i >= electronDensity.m_iRes[0] * electronDensity.m_iRes[1]) { pdeMatrix->m_val[j] = 1.0 * electronDensity.m_pBin[i] / (g_fCubeZStep * g_fCubeZStep) - 0.5 * electronDensityGradientZ.m_pBin[i] / g_fCubeZStep; pdeMatrix->m_colInd[j] = i - electronDensity.m_iRes[0] * electronDensity.m_iRes[1]; // if (j == 13600000) { // mprintf(GREEN, "%#.10g %#.10g\n", electronDensity.m_pBin[i], electronDensityGradientZ.m_pBin[i]); // } j++; } if (i % (electronDensity.m_iRes[0] * electronDensity.m_iRes[1]) >= electronDensity.m_iRes[0] * (electronDensity.m_iRes[1] - 1)) { pdeMatrix->m_val[j] = 1.0 * electronDensity.m_pBin[i] / (g_fCubeYStep * g_fCubeYStep) + 0.5 * electronDensityGradientY.m_pBin[i] / g_fCubeYStep; pdeMatrix->m_colInd[j] = i - electronDensity.m_iRes[0] * (electronDensity.m_iRes[1] - 1); j++; } if (i % (electronDensity.m_iRes[0] * electronDensity.m_iRes[1]) >= electronDensity.m_iRes[0]) { pdeMatrix->m_val[j] = 1.0 * electronDensity.m_pBin[i] / (g_fCubeYStep * g_fCubeYStep) - 0.5 * electronDensityGradientY.m_pBin[i] / g_fCubeYStep; pdeMatrix->m_colInd[j] = i - electronDensity.m_iRes[0]; j++; } if (i % electronDensity.m_iRes[0] == electronDensity.m_iRes[0] - 1) { pdeMatrix->m_val[j] = 1.0 * electronDensity.m_pBin[i] / (g_fCubeXStep * g_fCubeXStep) + 0.5 * electronDensityGradientX.m_pBin[i] / g_fCubeXStep; pdeMatrix->m_colInd[j] = i - electronDensity.m_iRes[0] + 1; j++; } if (i % electronDensity.m_iRes[0] != 0) { pdeMatrix->m_val[j] = 1.0 * electronDensity.m_pBin[i] / (g_fCubeXStep * g_fCubeXStep) - 0.5 * electronDensityGradientX.m_pBin[i] / g_fCubeXStep; pdeMatrix->m_colInd[j] = i - 1; j++; } pdeMatrix->m_val[j] = -2.0 * electronDensity.m_pBin[i] / (g_fCubeXStep * g_fCubeXStep) - 2.0 * electronDensity.m_pBin[i] / (g_fCubeYStep * g_fCubeYStep) - 2.0 * electronDensity.m_pBin[i] / (g_fCubeZStep * g_fCubeZStep); pdeMatrix->m_colInd[j] = i; j++; if (i % electronDensity.m_iRes[0] != electronDensity.m_iRes[0] - 1) { pdeMatrix->m_val[j] = 1.0 * electronDensity.m_pBin[i] / (g_fCubeXStep * g_fCubeXStep) + 0.5 * electronDensityGradientX.m_pBin[i] / g_fCubeXStep; pdeMatrix->m_colInd[j] = i + 1; j++; } if (i % electronDensity.m_iRes[0] == 0) { pdeMatrix->m_val[j] = 1.0 * electronDensity.m_pBin[i] / (g_fCubeXStep * g_fCubeXStep) - 0.5 * electronDensityGradientX.m_pBin[i] / g_fCubeXStep; pdeMatrix->m_colInd[j] = i + electronDensity.m_iRes[0] - 1; j++; } if (i % (electronDensity.m_iRes[0] * electronDensity.m_iRes[1]) < electronDensity.m_iRes[0] * (electronDensity.m_iRes[1] - 1)) { pdeMatrix->m_val[j] = 1.0 * electronDensity.m_pBin[i] / (g_fCubeYStep * g_fCubeYStep) + 0.5 * electronDensityGradientY.m_pBin[i] / g_fCubeYStep; pdeMatrix->m_colInd[j] = i + electronDensity.m_iRes[0]; j++; } if (i % (electronDensity.m_iRes[0] * electronDensity.m_iRes[1]) < electronDensity.m_iRes[0]) { pdeMatrix->m_val[j] = 1.0 * electronDensity.m_pBin[i] / (g_fCubeYStep * g_fCubeYStep) - 0.5 * electronDensityGradientY.m_pBin[i] / g_fCubeYStep; pdeMatrix->m_colInd[j] = i + electronDensity.m_iRes[0] * (electronDensity.m_iRes[1] - 1); j++; } if (i < electronDensity.m_iRes[0] * electronDensity.m_iRes[1] * (electronDensity.m_iRes[2] - 1)) { pdeMatrix->m_val[j] = 1.0 * electronDensity.m_pBin[i] / (g_fCubeZStep * g_fCubeZStep) + 0.5 * electronDensityGradientZ.m_pBin[i] / g_fCubeZStep; pdeMatrix->m_colInd[j] = i + electronDensity.m_iRes[0] * electronDensity.m_iRes[1]; j++; } if (i < electronDensity.m_iRes[0] * electronDensity.m_iRes[1]) { pdeMatrix->m_val[j] = 1.0 * electronDensity.m_pBin[i] / (g_fCubeZStep * g_fCubeZStep) - 0.5 * electronDensityGradientZ.m_pBin[i] / g_fCubeZStep; pdeMatrix->m_colInd[j] = i + electronDensity.m_iRes[0] * electronDensity.m_iRes[1] * (electronDensity.m_iRes[2] - 1); j++; } } if (j != numEntries) { eprintf("CCurrentPDEDiscretizer::discretize(): Error in PDE discretizer.\n"); abort(); } pdeMatrix->m_rowPtr[pdeMatrix->m_size] = numEntries; // mprintf(GREEN, "%#.10g\n", pdeMatrix->m_val[13600000]); } // For this implementation, the Fortran code provided at http://www.staff.science.uu.nl/~vorst102/software.html (November 07, 2014) was adopted /*********************************************************** * This code is based on: * * * * subroutine bicgstab2 * * Copyright (c) 1998 by M.A.Botchev * * Permission to copy all or part of this work is granted, * * provided that the copies are not made or distributed * * for resale, and that the copyright notice and this * * notice are retained. * * * * subroutine bistbl * * Copyright (c) 1995 by D.R. Fokkema. * * Permission to copy all or part of this work is granted, * * provided that the copies are not made or distributed * * for resale, and that the copyright notice and this * * notice are retained. * ***********************************************************/ bool CCurrentPDESolver::bicgstabl(const int l, const CSparseMatrix *pdeMatrix, double *solution, const double *rightHandSide, const int maxIter, double *thresh, FILE *infoFile, bool fastmode) { double **r; try { r = new double *[l + 1]; } catch(...) { r = NULL; } if (r == NULL) NewException((double)(l + 1) * sizeof(double *), __FILE__, __LINE__, __PRETTY_FUNCTION__); double **u; try { u = new double *[l + 1]; } catch(...) { u = NULL; } if (u == NULL) NewException((double)(l + 1) * sizeof(double *), __FILE__, __LINE__, __PRETTY_FUNCTION__); int i, j, k; for (i = 0; i < l + 1; i++) { try { r[i] = new double[pdeMatrix->m_size]; } catch(...) { r[i] = NULL; } if (r[i] == NULL) NewException((double)pdeMatrix->m_size * sizeof(double), __FILE__, __LINE__, __PRETTY_FUNCTION__); try { u[i] = new double[pdeMatrix->m_size]; } catch(...) { u[i] = NULL; } if (u[i] == NULL) NewException((double)pdeMatrix->m_size * sizeof(double), __FILE__, __LINE__, __PRETTY_FUNCTION__); } double *r0; try { r0 = new double[pdeMatrix->m_size]; } catch(...) { r0 = NULL; } if (r0 == NULL) NewException((double)pdeMatrix->m_size * sizeof(double), __FILE__, __LINE__, __PRETTY_FUNCTION__); double *b; try { b = new double[pdeMatrix->m_size]; } catch(...) { b = NULL; } if (b == NULL) NewException((double)pdeMatrix->m_size * sizeof(double), __FILE__, __LINE__, __PRETTY_FUNCTION__); double *x; try { x = new double[pdeMatrix->m_size]; } catch(...) { x = NULL; } if (x == NULL) NewException((double)pdeMatrix->m_size * sizeof(double), __FILE__, __LINE__, __PRETTY_FUNCTION__); double alpha, beta, omega, sigma, rho0, rho1; double *rwork; try { rwork = new double[(l + 1) * (3 + l + 1)]; } catch(...) { rwork = NULL; } if (rwork == NULL) NewException((double)(l + 1) * (3 + l + 1) * sizeof(double), __FILE__, __LINE__, __PRETTY_FUNCTION__); double *rtemp; try { rtemp = new double[(l - 1) * (l - 1)]; } catch(...) { rtemp = NULL; } if (rtemp == NULL) NewException((double)(l - 1) * (l - 1) * sizeof(double), __FILE__, __LINE__, __PRETTY_FUNCTION__); int *rperm; try { rperm = new int[l - 1]; } catch(...) { rperm = NULL; } if (rperm == NULL) NewException((double)(l - 1) * sizeof(int), __FILE__, __LINE__, __PRETTY_FUNCTION__); int z = 0; int y0 = z + (l + 1); int y1 = y0 + 1; int y = y1 + 1; double kappa0, kappal, varrho, hatgamma; double resNorm0, maxNormX, maxNormR; double retVal; double *bestsol, bestresi; if (fastmode) { try { bestsol = new double[pdeMatrix->m_size]; } catch(...) { bestsol = NULL; } if (bestsol == NULL) NewException((double)pdeMatrix->m_size * sizeof(double), __FILE__, __LINE__, __PRETTY_FUNCTION__); bestresi = 1.0e30; } else bestsol = NULL; if (infoFile != NULL) fprintf(infoFile, " Starting BICGSTABL(%d) with %d maximum iterations and %g threshold\n", l, maxIter, *thresh); for (i=0;im_size;k++) u[i][k] = 0; CSparseMatrix precondMatrix(*pdeMatrix); CILUPreconditioner::precondition(&precondMatrix); pdeMatrix->matrixVectorProduct(solution, r[0]); for (i = 0; i < pdeMatrix->m_size; i++) r[0][i] = rightHandSide[i] - r[0][i]; CILUPreconditioner::solve(&precondMatrix, r[0]); // mprintf(GREEN, "%#.10g\n", r[0][10]); double resNorm = 0.0; for (i = 0; i < pdeMatrix->m_size; i++) { resNorm += r[0][i] * r[0][i]; r0[i] = r[0][i]; b[i] = r[0][i]; x[i] = solution[i]; solution[i] = 0.0; } resNorm = sqrt(resNorm); if (infoFile != NULL) { fprintf(infoFile, " %5d %20.14g\n", 0, resNorm); fflush(infoFile); } if (g_bROA ) mprintf("#"); resNorm0 = resNorm; maxNormX = resNorm0; maxNormR = resNorm0; retVal = resNorm0; alpha = 0.0; omega = 1.0; sigma = 1.0; rho0 = 1.0; int numIter = 0; while (numIter < maxIter && resNorm > *thresh) { numIter++; rho0 *= -omega; for (i = 0; i < l; i++) { rho1 = 0.0; for (j = 0; j < pdeMatrix->m_size; j++) rho1 += r0[j] * r[i][j]; if (rho0 == 0.0) { eprintf("CCurrentPDESolver::BiCGSTABl(): Error: Rho0 is zero!\n"); abort(); } beta = alpha * (rho1 / rho0); rho0 = rho1; for (j = 0; j <= i; j++) for (k = 0; k < pdeMatrix->m_size; k++) u[j][k] = r[j][k] - beta * u[j][k]; pdeMatrix->matrixVectorProduct(u[i], u[i + 1]); CILUPreconditioner::solve(&precondMatrix, u[i + 1]); sigma = 0.0; for (j = 0; j < pdeMatrix->m_size; j++) sigma += r0[j] * u[i + 1][j]; if (sigma == 0.0) { eprintf("CCurrentPDESolver::BiCGSTABl(): Error: Sigma is zero!\n"); abort(); } alpha = rho1 / sigma; for (j = 0; j < pdeMatrix->m_size; j++) solution[j] += alpha * u[0][j]; for (j = 0; j <= i; j++) for (k = 0; k < pdeMatrix->m_size; k++) r[j][k] -= alpha * u[j + 1][k]; pdeMatrix->matrixVectorProduct(r[i], r[i + 1]); CILUPreconditioner::solve(&precondMatrix, r[i + 1]); resNorm = 0.0; for (j = 0; j < pdeMatrix->m_size; j++) resNorm += r[0][j] * r[0][j]; resNorm = sqrt(resNorm); // mprintf(GREEN, "%#.14g %#.10g\n", resNorm, r[0][1942857]); if (resNorm > maxNormX) maxNormX = resNorm; if (resNorm > maxNormR) maxNormR = resNorm; } for (i = 0; i < l + 1; i++) { for (j = 0; j < l + 1 - i; j++) { rwork[(z + i) * (l + 1) + i + j] = 0.0; for (k = 0; k < pdeMatrix->m_size; k++) rwork[(z + i) * (l + 1) + i + j] += r[i + j][k] * r[i][k]; } for (j = 0; j < l - i; j++) rwork[(z + i + 1 + j) * (l + 1) + i] = rwork[(z + i) * (l + 1) + i + 1 + j]; } for (i = 0; i < (l - 1); i++) for (j = 0; j < (l - 1); j++) rtemp[i * (l - 1) + j] = rwork[(z + i + 1) * (l + 1) + j + 1]; luFactorization(rtemp, rperm, l - 1); rwork[y0 * (l + 1)] = -1.0; for (i = 0; i < l - 1; i++) rwork[y0 * (l + 1) + i + 1] = rwork[z * (l + 1) + i + 1]; forwardBackward(rtemp, rperm, l - 1, &rwork[y0 * (l + 1) + 1]); rwork[y0 * (l + 1) + l] = 0.0; rwork[y1 * (l + 1)] = 0.0; for (i = 0; i < l - 1; i++) rwork[y1 * (l + 1) + i + 1] = rwork[(z + l) * (l + 1) + i + 1]; forwardBackward(rtemp, rperm, l - 1, &rwork[y1 * (l + 1) + 1]); rwork[y1 * (l + 1) + l] = -1.0; for (i = 0; i < l + 1; i++) { rwork[y * (l + 1) + i] = 0.0; for (j = 0; j < l + 1; j++) rwork[y * (l + 1) + i] += rwork[(z + i) * (l + 1) + j] * rwork[y0 * (l + 1) + j]; } kappa0 = 0.0; for (i = 0; i < l + 1; i++) kappa0 += rwork[y0 * (l + 1) + i] * rwork[y * (l + 1) + i]; kappa0 = sqrt(kappa0); for (i = 0; i < l + 1; i++) { rwork[y * (l + 1) + i] = 0.0; for (j = 0; j < l + 1; j++) rwork[y * (l + 1) + i] += rwork[(z + i) * (l + 1) + j] * rwork[y1 * (l + 1) + j]; } kappal = 0.0; for (i = 0; i < l + 1; i++) kappal += rwork[y1 * (l + 1) + i] * rwork[y * (l + 1) + i]; kappal = sqrt(kappal); for (i = 0; i < l + 1; i++) { rwork[y * (l + 1) + i] = 0.0; for (j = 0; j < l + 1; j++) rwork[y * (l + 1) + i] += rwork[(z + i) * (l + 1) + j] * rwork[y0 * (l + 1) + j]; } varrho = 0.0; for (i = 0; i < l + 1; i++) varrho += rwork[y1 * (l + 1) + i] * rwork[y * (l + 1) + i]; varrho /= (kappa0 * kappal); if (fabs(varrho) < 0.7) #ifdef TARGET_WINDOWS hatgamma = _copysign(1.0, varrho) * 0.7 * (kappa0 / kappal); #else hatgamma = copysign(1.0, varrho) * 0.7 * (kappa0 / kappal); #endif else #ifdef TARGET_WINDOWS hatgamma = _copysign(1.0, varrho) * fabs(varrho) * (kappa0 / kappal); #else hatgamma = copysign(1.0, varrho) * fabs(varrho) * (kappa0 / kappal); #endif for (i = 0; i < l + 1; i++) rwork[y0 * (l + 1) + i] -= hatgamma * rwork[y1 * (l + 1) + i]; omega = rwork[y0 * (l + 1) + l]; for (i = 0; i < pdeMatrix->m_size; i++) for (j = 0; j < l; j++) u[0][i] -= u[j + 1][i] * rwork[y0 * (l + 1) + j + 1]; for (i = 0; i < pdeMatrix->m_size; i++) for (j = 0; j < l; j++) solution[i] += r[j][i] * rwork[y0 * (l + 1) + j + 1]; for (i = 0; i < pdeMatrix->m_size; i++) for (j = 0; j < l; j++) r[0][i] -= r[j + 1][i] * rwork[y0 * (l + 1) + j + 1]; for (i = 0; i < l + 1; i++) { rwork[y * (l + 1) + i] = 0.0; for (j = 0; j < l + 1; j++) rwork[y * (l + 1) + i] += rwork[(z + i) * (l + 1) + j] * rwork[y0 * (l + 1) + j]; } resNorm = 0.0; for (i = 0; i < l + 1; i++) resNorm += rwork[y0 * (l + 1) + i] * rwork[y * (l + 1) + i]; resNorm = sqrt(resNorm); if (resNorm < retVal) retVal = resNorm; if (infoFile != NULL) { fprintf(infoFile, " %5d %20.14g\n", numIter, resNorm); fflush(infoFile); } if (g_bROA ) mprintf("#"); if (resNorm > maxNormX) maxNormX = resNorm; if (resNorm > maxNormR) maxNormR = resNorm; if ((resNorm < 0.01 * maxNormR && resNorm0 < maxNormR) || (resNorm < 0.01 * resNorm0 && resNorm0 < maxNormX)) { if (infoFile != NULL) fprintf(infoFile, " Updating residuals\n"); if (g_bROA ) mprintf("*"); pdeMatrix->matrixVectorProduct(solution, r[0]); CILUPreconditioner::solve(&precondMatrix, r[0]); for (i = 0; i < pdeMatrix->m_size; i++) r[0][i] = b[i] - r[0][i]; maxNormR = resNorm; if (resNorm < 0.01 * resNorm0 && resNorm0 < maxNormX) { if (infoFile != NULL) fprintf(infoFile, " On-the-fly restart\n"); if (g_bROA ) mprintf("+"); for (i = 0; i < pdeMatrix->m_size; i++) { x[i] += solution[i]; solution[i] = 0.0; b[i] = r[0][i]; } maxNormX = resNorm; } } if (fastmode && (resNorm < bestresi)) { bestresi = resNorm; for (i = 0; i < pdeMatrix->m_size; i++) bestsol[i] = solution[i] + x[i]; } } if ((resNorm <= *thresh) && (numIter == maxIter)) // Detect convergence in last step numIter--; if (fastmode) { for (i = 0; i < pdeMatrix->m_size; i++) solution[i] = bestsol[i]; } else { for (i = 0; i < pdeMatrix->m_size; i++) solution[i] += x[i]; } pdeMatrix->matrixVectorProduct(solution, r[0]); for (i = 0; i < pdeMatrix->m_size; i++) r[0][i] = rightHandSide[i] - r[0][i]; CILUPreconditioner::solve(&precondMatrix, r[0]); resNorm = 0.0; for (i = 0; i < pdeMatrix->m_size; i++) resNorm += r[0][i] * r[0][i]; resNorm = sqrt(resNorm); if (infoFile != NULL) { fprintf(infoFile, " Final %20.14g\n", resNorm); if (numIter == maxIter) fprintf(infoFile, " Not converged\n"); } if (g_bROA ) { if (numIter == maxIter) mprintf("N"); else mprintf("C"); } for (i = 0; i < l + 1; i++) { delete[] r[i]; delete[] u[i]; } delete[] r; delete[] u; delete[] r0; delete[] b; delete[] x; delete[] rwork; delete[] rtemp; delete[] rperm; if (fastmode) delete[] bestsol; *thresh = retVal; return !(numIter == maxIter); } double CCurrentPDESolver::calcResidual(const CSparseMatrix *pdeMatrix, const double *solution, const double *rightHandSide) { double *temp; try { temp = new double[pdeMatrix->m_size]; } catch(...) { temp = NULL; } if (temp == NULL) NewException((double)pdeMatrix->m_size * sizeof(double), __FILE__, __LINE__, __PRETTY_FUNCTION__); CSparseMatrix precondMatrix(*pdeMatrix); CILUPreconditioner::precondition(&precondMatrix); pdeMatrix->matrixVectorProduct(solution, temp); int i; for (i = 0; i < pdeMatrix->m_size; i++) { temp[i] = rightHandSide[i] - temp[i]; } CILUPreconditioner::solve(&precondMatrix, temp); double resNorm = 0.0; for (i = 0; i < pdeMatrix->m_size; i++) { resNorm += temp[i] * temp[i]; } resNorm = sqrt(resNorm); delete[] temp; return resNorm; } void CCurrentPDESolver::luFactorization(double *matrix, int *perm, int size) { int i; for (i = 0; i < size; i++) { double max = fabs(matrix[i * size + i]); int maxRow = i; int j; for (j = i; j < size; j++) { if (fabs(matrix[j * size + i]) > max) { max = fabs(matrix[j * size + i]); maxRow = j; } } if (maxRow != i) { for (j = 0; j < size; j++) { double temp = matrix[i * size + j]; matrix[i * size + j] = matrix[maxRow * size + j]; matrix[maxRow * size + j] = temp; } } perm[i] = maxRow; int k; for (k = 0; k < i; k++) { matrix[i * size + k] /= matrix[k * size + k]; for (j = k + 1; j < size; j++) { matrix[i * size + j] -= matrix[i * size + k] * matrix[k * size + j]; } } } } void CCurrentPDESolver::forwardBackward(double *luMatrix, int *perm, int size, double *sol) { int i; for (i = 0; i < size; i++) { if (perm[i] != i) { double temp = sol[i]; sol[i] = sol[perm[i]]; sol[perm[i]] = temp; } } for (i = 0; i < size; i++) { int j; for (j = 0; j < i; j++) { sol[i] -= luMatrix[i * size + j] * sol[j]; } } for (i = size - 1; i >= 0; i--) { int j; for (j = size - 1; j > i; j--) { sol[i] -= luMatrix[i * size + j] * sol[j]; } sol[i] /= luMatrix[i * size + i]; } } void CILUPreconditioner::precondition(CSparseMatrix *matrix) { // mprintf(GREEN, "%#.10g\n", matrix->m_val[13600000]); int *diagInd; try { diagInd = new int[matrix->m_size]; } catch(...) { diagInd = NULL; } if (diagInd == NULL) NewException((double)matrix->m_size * sizeof(double), __FILE__, __LINE__, __PRETTY_FUNCTION__); int i; for (i = 0; i < matrix->m_size; i++) { diagInd[i] = -1; int j; for (j = matrix->m_rowPtr[i]; j < matrix->m_rowPtr[i + 1]; j++) { if (i == matrix->m_colInd[j]) { diagInd[i] = j; break; } } if (diagInd[i] == -1) { eprintf("CILUPreconditioner::precondition(): Error: Missing diagonal element in row %d!\n", i + 1); abort(); } } for (i = 1; i < matrix->m_size; i++) { int k; for (k = matrix->m_rowPtr[i]; matrix->m_colInd[k] < i && k < matrix->m_rowPtr[i + 1]; k++) { matrix->m_val[k] /= matrix->m_val[diagInd[matrix->m_colInd[k]]]; int j; for (j = k + 1; j < matrix->m_rowPtr[i + 1]; j++) { int l; for (l = matrix->m_rowPtr[matrix->m_colInd[k]]; l < matrix->m_rowPtr[matrix->m_colInd[k] + 1]; l++) { if (matrix->m_colInd[l] == matrix->m_colInd[j]) { matrix->m_val[j] -= matrix->m_val[k] * matrix->m_val[l]; break; } } } } } delete[] diagInd; } void CILUPreconditioner::solve(CSparseMatrix *matrix, double *vect) { int i; // mprintf(GREEN, "%#.10g\n", vector[1953124]); for (i = 0; i < matrix->m_size; i++) { int j; for (j = matrix->m_rowPtr[i]; matrix->m_colInd[j] < i && j < matrix->m_rowPtr[i + 1]; j++) { vect[i] -= matrix->m_val[j] * vect[matrix->m_colInd[j]]; // if (i == 1953124) { // mprintf(GREEN, "%d %#.10g %#.10g\n", j, matrix->m_val[j], vector[matrix->m_colInd[j]]); // } } } // mprintf(GREEN, "%#.10g\n", vector[1953124]); for (i = matrix->m_size - 1; i >= 0; i--) { int j; for (j = matrix->m_rowPtr[i + 1] - 1; matrix->m_colInd[j] > i && j >= matrix->m_rowPtr[i]; j--) { vect[i] -= matrix->m_val[j] * vect[matrix->m_colInd[j]]; // if (i == 1953124) { // mprintf(GREEN, "%d %#.10g %#.10g\n", j, matrix->m_val[j], vector[matrix->m_colInd[j]]); // } } for (j = matrix->m_rowPtr[i]; j < matrix->m_rowPtr[i + 1]; j++) { if (matrix->m_colInd[j] == i) { vect[i] /= matrix->m_val[j]; break; } } } // mprintf(GREEN, "%#.10g\n", vector[1953124]); } travis-src-190101/src/bicgstab.h0100777000000000000000000000513713412725656013401 0ustar00/***************************************************************************** TRAVIS - Trajectory Analyzer and Visualizer http://www.travis-analyzer.de/ Copyright (c) 2009-2019 Martin Brehm 2012-2019 Martin Thomas 2016-2019 Sascha Gehrke This file was written by Martin Thomas. --------------------------------------------------------------------------- This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . *****************************************************************************/ #ifndef BICGSTAB_H #define BICGSTAB_H // This must always be the first include directive #include "config.h" #include "3df.h" #include class CxDoubleArray; class CSparseMatrix { public: friend class CCurrentPDEDiscretizer; friend class CCurrentPDESolver; friend class CILUPreconditioner; CSparseMatrix(); CSparseMatrix(const CSparseMatrix &matrix); ~CSparseMatrix(); void setTest(); void matrixVectorProduct(const double *vect, double *result) const; private: int m_size; double *m_val; int *m_colInd; int *m_rowPtr; }; class CCurrentPDEDiscretizer { public: static void discretize(CSparseMatrix *pdeMatrix, const C3DF &electronDensity, const C3DF &electronDensityGradientX, const C3DF &electronDensityGradientY, const C3DF &electronDensityGradientZ); }; class CCurrentPDESolver { public: static bool bicgstabl(const int l, const CSparseMatrix *pdeMatrix, double *solution, const double *rightHandSide, const int maxIter, double *thresh, FILE *infoFile, bool fastmode=false); static double calcResidual(const CSparseMatrix *pdeMatrix, const double *solution, const double *rightHandSide); private: static void luFactorization(double *matrix, int *perm, int size); static void forwardBackward(double *luMatrix, int *perm, int size, double *sol); }; class CILUPreconditioner { public: static void precondition(CSparseMatrix *matrix); static void solve(CSparseMatrix *matrix, double *vect); }; #endif travis-src-190101/src/bintools.cpp0100777000000000000000000004425313412725630014001 0ustar00/***************************************************************************** TRAVIS - Trajectory Analyzer and Visualizer http://www.travis-analyzer.de/ Copyright (c) 2009-2019 Martin Brehm 2012-2019 Martin Thomas 2016-2019 Sascha Gehrke This file was written by Martin Brehm. --------------------------------------------------------------------------- This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . *****************************************************************************/ // This must always be the first include directive #include "config.h" #include "bintools.h" #include "travis.h" const char *GetRevisionInfo_bintools(unsigned int len) { static char buf[256]; GET_REVISION_INFO( buf, len ); return buf; } const char *GetSourceVersion_bintools() { static char buf[256]; GET_SOURCE_VERSION( buf ); return buf; } /*void CMSDF::CalcHistogram() { BTIN; int z, z2, t; m_fMaxAvg = 0; for (z=0;z z*m_fMaxAvg/(g_iHistogramRes-1)) && (m_pBin[z2] <= (z+1)*m_fMaxAvg/(g_iHistogramRes-1))) t++; } m_pHistogram[z] = (double)t; } BTOUT; } void CMSDF::NormHistogramIntegral() { BTIN; int z; double f; f = 0; for (z=0;z z*m_fMaxP[z0]/(g_iHistogramRes-1)) && (m_pBin[z0][z2] <= (z+1)*m_fMaxP[z0]/(g_iHistogramRes-1))) t++; m_pHistogram[z0][z] = (double)t; } } BTOUT; }*/ /*void CS6DF::WriteHistogram(const char *prefix, const char *name, const char *suffix) { BTIN; FILE *a; int z, z0; char buf[256], buf2[32]; for (z0=0;z0 m_fRadius) { BXOUT; return; } if (m_bCutSDF) { switch(m_iCutPlane) { case 0: if (vec[0] > g_fCutValue) { BXOUT; return; } break; case 1: if (vec[1] > g_fCutValue) { BXOUT; return; } break; case 2: if (vec[2] > g_fCutValue) { BXOUT; return; } break; } } d = val.GetLength(); // printf("AddToBin x=%f y=%f z=%f d=%f Level=%d\n",vec[0],vec[1],vec[2],d,m_iLevelCount); m_fGesBinEntries++; x = ((vec[0]+g_fSDFRadius)/(2*g_fSDFRadius))*((double)g_iSDFResolution-1); y = ((vec[1]+g_fSDFRadius)/(2*g_fSDFRadius))*((double)g_iSDFResolution-1); z = ((vec[2]+g_fSDFRadius)/(2*g_fSDFRadius))*((double)g_iSDFResolution-1); ix = (int)floor(x); iy = (int)floor(y); iz = (int)floor(z); j = 0; while (d > m_fLevelThres[j]) { j++; if (j >= m_iLevelCount) break; } if (j >= m_iLevelCount) j = m_iLevelCount-1; // printf(" Ok. x=%f y=%f z=%f d=%f j=%d Level=%d\n",vec[0],vec[1],vec[2],d,j,g_iLevelCount); m_fBinEntries[j]++; // switch(g_iBinning) // { // case 1: // Einfach einsortieren // m_pBin[j][iz*g_iSDFResSqr + iy*g_iSDFResolution + ix] += 1.0f; // break; // case 2: // Auf 8 Bins aufspalten x -= ix; y -= iy; z -= iz; tx = 1-x; ty = 1-y; tz = 1-z; m_pBin[j][iz*g_iSDFResSqr + iy*g_iSDFResolution + ix] += tx*ty*tz; m_pBin[j][iz*g_iSDFResSqr + iy*g_iSDFResolution + ix +1] += x*ty*tz; m_pBin[j][iz*g_iSDFResSqr + (iy+1)*g_iSDFResolution + ix] += tx* y*tz; m_pBin[j][iz*g_iSDFResSqr + (iy+1)*g_iSDFResolution + ix +1] += x* y*tz; m_pBin[j][(iz+1)*g_iSDFResSqr + iy*g_iSDFResolution + ix] += tx*ty* z; m_pBin[j][(iz+1)*g_iSDFResSqr + iy*g_iSDFResolution + ix +1] += x*ty* z; m_pBin[j][(iz+1)*g_iSDFResSqr + (iy+1)*g_iSDFResolution + ix] += tx* y* z; m_pBin[j][(iz+1)*g_iSDFResSqr + (iy+1)*g_iSDFResolution + ix +1] += x* y* z; // break; // default: // printf("CS6DF::AddToBin(): Error!\n"); // break; // } // printf(" Fertig.\n"); BXOUT; }*/ /*void CMSDF::AddToBinMean(const CxVector3 &vec, const CxVector3 &val) { BXIN; double x, y, z, tx, ty, tz, v; int ix, iy, iz; if (vec.GetLength() > g_fSDFRadius) { BXOUT; return; } if (g_bCutSDF) { switch(g_iCutPlane) { case 0: if (vec[0] > g_fCutValue) { BXOUT; return; } break; case 1: if (vec[1] > g_fCutValue) { BXOUT; return; } break; case 2: if (vec[2] > g_fCutValue) { BXOUT; return; } break; } } v = val.GetLength(); m_fBinEntries++; x = ((vec[0]+g_fSDFRadius)/(2*g_fSDFRadius))*((double)g_iSDFResolution-1); y = ((vec[1]+g_fSDFRadius)/(2*g_fSDFRadius))*((double)g_iSDFResolution-1); z = ((vec[2]+g_fSDFRadius)/(2*g_fSDFRadius))*((double)g_iSDFResolution-1); ix = (int)floor(x); iy = (int)floor(y); iz = (int)floor(z); // printf("AddToBin x=%f y=%f z=%f d=%f\n",vec[0],vec[1],vec[2],v); // switch(g_iBinning) // { // case 1: // Einfach einsortieren // m_pBin [iz*g_iSDFResSqr + iy*g_iSDFResolution + ix] += v; // m_pRefBin[iz*g_iSDFResSqr + iy*g_iSDFResolution + ix] += 1.0; // break; // case 2: // Auf 8 Bins aufspalten x -= ix; y -= iy; z -= iz; tx = 1-x; ty = 1-y; tz = 1-z; m_pBin [iz*g_iSDFResSqr + iy*g_iSDFResolution + ix] += tx*ty*tz*v; m_pBin [iz*g_iSDFResSqr + iy*g_iSDFResolution + ix +1] += x*ty*tz*v; m_pBin [iz*g_iSDFResSqr + (iy+1)*g_iSDFResolution + ix] += tx* y*tz*v; m_pBin [iz*g_iSDFResSqr + (iy+1)*g_iSDFResolution + ix +1] += x* y*tz*v; m_pBin [(iz+1)*g_iSDFResSqr + iy*g_iSDFResolution + ix] += tx*ty* z*v; m_pBin [(iz+1)*g_iSDFResSqr + iy*g_iSDFResolution + ix +1] += x*ty* z*v; m_pBin [(iz+1)*g_iSDFResSqr + (iy+1)*g_iSDFResolution + ix] += tx* y* z*v; m_pBin [(iz+1)*g_iSDFResSqr + (iy+1)*g_iSDFResolution + ix +1] += x* y* z*v; m_pRefBin[iz*g_iSDFResSqr + iy*g_iSDFResolution + ix] += tx*ty*tz; m_pRefBin[iz*g_iSDFResSqr + iy*g_iSDFResolution + ix +1] += x*ty*tz; m_pRefBin[iz*g_iSDFResSqr + (iy+1)*g_iSDFResolution + ix] += tx* y*tz; m_pRefBin[iz*g_iSDFResSqr + (iy+1)*g_iSDFResolution + ix +1] += x* y*tz; m_pRefBin[(iz+1)*g_iSDFResSqr + iy*g_iSDFResolution + ix] += tx*ty* z; m_pRefBin[(iz+1)*g_iSDFResSqr + iy*g_iSDFResolution + ix +1] += x*ty* z; m_pRefBin[(iz+1)*g_iSDFResSqr + (iy+1)*g_iSDFResolution + ix] += tx* y* z; m_pRefBin[(iz+1)*g_iSDFResSqr + (iy+1)*g_iSDFResolution + ix +1] += x* y* z; // break; // default: // printf("CMSDF::AddToBin(): Error!\n"); // break; // } BXOUT; }*/ /*void CMSDF::AddToBinMax(const CxVector3 &vec, const CxVector3 &val) { BXIN; double x, y, z, tx, ty, tz, v; int ix, iy, iz; if (vec.GetLength() > g_fSDFRadius) { BXOUT; return; } if (g_bCutSDF) { switch(g_iCutPlane) { case 0: if (vec[0] > g_fCutValue) { BXOUT; return; } break; case 1: if (vec[1] > g_fCutValue) { BXOUT; return; } break; case 2: if (vec[2] > g_fCutValue) { BXOUT; return; } break; } } v = val.GetLength(); m_fBinEntries++; x = ((vec[0]+g_fSDFRadius)/(2*g_fSDFRadius))*((double)g_iSDFResolution-1); y = ((vec[1]+g_fSDFRadius)/(2*g_fSDFRadius))*((double)g_iSDFResolution-1); z = ((vec[2]+g_fSDFRadius)/(2*g_fSDFRadius))*((double)g_iSDFResolution-1); ix = (int)floor(x); iy = (int)floor(y); iz = (int)floor(z); // printf("AddToBin x=%f y=%f z=%f d=%f\n",vec[0],vec[1],vec[2],v); // switch(g_iBinning) // { // case 1: // Einfach einsortieren // if (m_pBin[iz*g_iSDFResSqr + iy*g_iSDFResolution + ix] < v) // m_pBin[iz*g_iSDFResSqr + iy*g_iSDFResolution + ix] = v; // break; // case 2: // Auf 8 Bins aufspalten x -= ix; y -= iy; z -= iz; tx = 1-x; ty = 1-y; tz = 1-z; if (m_pBin[iz*g_iSDFResSqr + iy*g_iSDFResolution + ix] < tx*ty*tz*v) m_pBin[iz*g_iSDFResSqr + iy*g_iSDFResolution + ix] = tx*ty*tz*v; if (m_pBin[iz*g_iSDFResSqr + iy*g_iSDFResolution + ix +1] < x*ty*tz*v) m_pBin[iz*g_iSDFResSqr + iy*g_iSDFResolution + ix +1] = x*ty*tz*v; if (m_pBin[iz*g_iSDFResSqr + (iy+1)*g_iSDFResolution + ix] < tx* y*tz*v) m_pBin[iz*g_iSDFResSqr + (iy+1)*g_iSDFResolution + ix] = tx* y*tz*v; if (m_pBin[iz*g_iSDFResSqr + (iy+1)*g_iSDFResolution + ix +1] < x* y*tz*v) m_pBin[iz*g_iSDFResSqr + (iy+1)*g_iSDFResolution + ix +1] = x* y*tz*v; if (m_pBin[(iz+1)*g_iSDFResSqr + iy*g_iSDFResolution + ix] < tx*ty* z*v) m_pBin[(iz+1)*g_iSDFResSqr + iy*g_iSDFResolution + ix] = tx*ty* z*v; if (m_pBin[(iz+1)*g_iSDFResSqr + iy*g_iSDFResolution + ix +1] < x*ty* z*v) m_pBin[(iz+1)*g_iSDFResSqr + iy*g_iSDFResolution + ix +1] = x*ty* z*v; if (m_pBin[(iz+1)*g_iSDFResSqr + (iy+1)*g_iSDFResolution + ix] < tx* y* z*v) m_pBin[(iz+1)*g_iSDFResSqr + (iy+1)*g_iSDFResolution + ix] = tx* y* z*v; if (m_pBin[(iz+1)*g_iSDFResSqr + (iy+1)*g_iSDFResolution + ix +1] < x* y* z*v) m_pBin[(iz+1)*g_iSDFResSqr + (iy+1)*g_iSDFResolution + ix +1] = x* y* z*v; // break; // default: // printf("CMSDF::AddToBin(): Error!\n"); // break; // } BXOUT; }*/ /* void CMRDF::AddToBin(double d, double val[3]) { double p, v; int ip; if (d > g_fRDFRadius) return; v = length(val); m_fBinEntries++; p = (d/g_fRDFRadius)*(g_iRDFResolution-1.0); ip = floor(p); switch(g_iBinning) { case 1: // Einfach einsortieren m_pBin [ip] += v; m_pRefBin[ip] += 1.0; break; case 2: // Auf 2 Bins aufspalten p -= ip; m_pBin [ip] += v*(1-p); m_pBin [ip+1] += v* p; m_pRefBin[ip] += (1-p); m_pRefBin[ip+1] += p; break; default: printf("CMRDF::AddToBin(): Error!\n"); break; } } */ CAF::CAF() { m_pBin = NULL; m_pDBin = NULL; m_faEntries.SetName("CAF::m_faEntries"); } CAF::~CAF() { } void CAF::AddToBin(double x, double y) { BXIN; double p; int ip; if ((x < m_fMinVal) || (x > m_fMaxVal)) { BXOUT; return; } m_fBinEntries++; p = ((x-m_fMinVal)/(m_fMaxVal-m_fMinVal))*(m_iResolution-1.0); ip = (int)floor(p); // switch(g_iBinning) // { // case 1: // Einfach einsortieren // m_pBin[ip] += y; // m_faEntries[ip]++; // break; // case 2: // Auf 2 Bins aufspalten p -= ip; m_pBin[ip] += (1-p)*y; m_pBin[ip+1] += p *y; m_faEntries[ip] += (1-p); m_faEntries[ip+1] += p; // break; // default: // printf("CDF::AddToBin(): Error!\n"); // break; // } BXOUT; } void CAF::AddToBin_Index(int i, double y) { BXIN; if ((i < 0) || (i >= m_iResolution)) { BXOUT; return; } m_fBinEntries++; // switch(g_iBinning) // { // case 1: // Einfach einsortieren // m_pBin[ip] += y; // m_faEntries[ip]++; // break; // case 2: // Auf 2 Bins aufspalten m_pBin[i] += y; m_faEntries[i]++; // break; // default: // printf("CDF::AddToBin(): Error!\n"); // break; // } BXOUT; } void CAF::BuildAverage() { BTIN; int z; for (z=0;zm_waSingleMolIndex.GetSize(); if (f < m_pBin[z2][z]) f = m_pBin[z2][z]; } } BTOUT; return f; }*/ /*void CMSDF::Create() { BTIN; int z; m_fBinEntries = 0; m_pBin = new double[g_iSDFResTri]; m_pRefBin = new double[g_iSDFResTri]; // m_pDBin[0] = new double[g_iSDFResTri]; // m_pDBin[1] = new double[g_iSDFResTri]; // m_pDBin[2] = new double[g_iSDFResTri]; for (z=0;z. *****************************************************************************/ #ifndef BINTOOLS_H #define BINTOOLS_H // This must always be the first include directive #include "config.h" #include #include #include "xdvector3.h" #include "xdoublearray.h" #include "backtrace.h" /*class CS6DF : public CxObject { public: CS6DF(); ~CS6DF(); void AddToBin(const CxVector3 &vec, const CxVector3 &val); double NormalizeBin(double mi, double ma); double PPMBin(); void Write(const char *prefix, const char *name, const char *suffix); void Create(); void WriteHistogram(const char *prefix, const char *name, const char *suffix); void CalcHistogram(); // double m_fRadius; // int m_iResolution, m_iResSqr, m_iResTri; int m_iLevelCount; double m_fLevelThres[32]; double *m_pHistogram[32]; // double *m_pDHistogram[32]; double *m_pBin[32]; // double *m_pDBin[3][32]; double m_fMaxP[32]; // double m_fMaxDP[32]; double m_fBinEntries[32]; double m_fGesBinEntries; }; class CMSDF : public CxObject { public: CMSDF() { }; ~CMSDF() { }; void AddToBinMean(const CxVector3 &vec, const CxVector3 &val); void AddToBinMax(const CxVector3 &vec, const CxVector3 &val); double NormalizeBin(double mi, double ma); void Write(const char *prefix, const char *name, const char *suffix); void Create(); void CalcAvg(); void WriteHistogram(const char *prefix, const char *name, const char *suffix); void CalcHistogram(); void NormHistogramIntegral(); // double *m_pDBin[3]; double m_fMaxAvg; double *m_pHistogram; // double m_fRadius; // int m_iResolution, m_iResSqr, m_iResTri; double *m_pBin; double *m_pRefBin; double m_fBinEntries; }; class CMRDF { public: CMRDF() { }; ~CMRDF() { }; void AddToBin(double d, double vec[3]); double NormalizeBin(double mi, double ma); void Write(char *s); void Create(); int m_iLevelCount; double m_fLevelMin, m_fLevelMax; double *m_pDBin[3]; // double m_fRadius; // int m_iResolution; double *m_pBin; double *m_pRefBin; double m_fBinEntries; }; */ class CAF : public CxObject { public: void LinReg(int i1, int i2, double *a0, double *a1, double *r); void CalcDeriv(double f); CAF(); ~CAF(); void AddToBin(double x, double y); void AddToBin_Index(int i, double y); void Write(const char *prefix, const char *name, const char *suffix); void Create(); void BuildAverage(); double m_fMinVal, m_fMaxVal; int m_iResolution; double *m_pBin; double *m_pDBin; double m_fBinEntries; CxDoubleArray m_faEntries; }; class CNDF : public CxObject { public: CNDF() { }; ~CNDF() { }; // void MultiplyBin(double m); // void AddToBin(double x, const CxVector3 &vec); /* void AddToBin(double x, int y); void AddToBin(double x, double y, double val); double NormalizeBin(double mi, double ma); double PPMBin(); void Write(const char *prefix, const char *name, const char *suffix); void WriteCSV(const char *prefix, const char *name, const char *suffix); void WriteXProjection(const char *prefix, const char *name, const char *suffix); void WriteYProjection(const char *prefix, const char *name, const char *suffix); void WriteMathematica(const char *prefix, const char *name, const char *suffix); void WriteLogMathematica(const char *prefix, const char *name, const char *suffix); void WriteVHDFLogMathematica(const char *prefix, const char *name, const char *suffix); void Create(); void AngleCorrect(); void AngleCorrectX(); void CorrectRadialDistX();*/ void AddToBin(double *d); int m_iDimensions; double *m_fMinVal; double *m_fMaxVal; double *m_fFac; int *m_iRes; double *m_pBin; double m_fBinEntries; }; #endif travis-src-190101/src/bintree.cpp0100777000000000000000000000300013412725616013565 0ustar00/***************************************************************************** TRAVIS - Trajectory Analyzer and Visualizer http://www.travis-analyzer.de/ Copyright (c) 2009-2019 Martin Brehm 2012-2019 Martin Thomas 2016-2019 Sascha Gehrke This file was written by Martin Brehm. --------------------------------------------------------------------------- This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . *****************************************************************************/ // This must always be the first include directive #include "config.h" #include "bintree.h" const char *GetRevisionInfo_bintree(unsigned int len) { static char buf[256]; GET_REVISION_INFO( buf, len ); return buf; } const char *GetSourceVersion_bintree() { static char buf[256]; GET_SOURCE_VERSION( buf ); return buf; } CBinTree::CBinTree() { } CBinTree::~CBinTree() { } travis-src-190101/src/bintree.h0100777000000000000000000000255413412725667013255 0ustar00/***************************************************************************** TRAVIS - Trajectory Analyzer and Visualizer http://www.travis-analyzer.de/ Copyright (c) 2009-2019 Martin Brehm 2012-2019 Martin Thomas 2016-2019 Sascha Gehrke This file was written by Martin Brehm. --------------------------------------------------------------------------- This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . *****************************************************************************/ // This must always be the first include directive #include "config.h" #include "xobject.h" class CBinTree : public CxObject { public: CBinTree(); ~CBinTree(); CBinTree *m_pParent; CBinTree *m_pChildren[2]; void *m_pValue; }; travis-src-190101/src/bqb.h0100777000000000000000000000324713412725666012370 0ustar00/*********************************************************************************** LibBQB - File Format and Compression Algorithms for Trajectories of Volumetric Data and Atom Positions https://brehm-research.de/bqb Free software, licensed under GNU LGPL v3 Copyright (c) Martin Brehm and Martin Thomas, Martin Luther University Halle-Wittenberg, Germany, 2016 - 2019. Please cite: M. Brehm, M. Thomas: "An Efficient Lossless Compression Algorithm for Trajectories of Atom Positions and Volumetric Data", J. Chem. Inf. Model. 2018, 58 (10), pp 2092-2107. -------------------------------------------------------------------------------- LibBQB is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program. If not, see . ***********************************************************************************/ #ifndef BQB_H #define BQB_H // This must always be the first include directive #include "bqb_config.h" #include "bqb_format.h" #include "bqb_driver.h" #include "bqb_engine.h" #endif travis-src-190101/src/bqbtool.cpp0100777000000000000000000041661313412725631013616 0ustar00/*********************************************************************************** LibBQB - File Format and Compression Algorithms for Trajectories of Volumetric Data and Atom Positions https://brehm-research.de/bqb Free software, licensed under GNU LGPL v3 Copyright (c) Martin Brehm and Martin Thomas, Martin Luther University Halle-Wittenberg, Germany, 2016 - 2019. Please cite: M. Brehm, M. Thomas: "An Efficient Lossless Compression Algorithm for Trajectories of Atom Positions and Volumetric Data", J. Chem. Inf. Model. 2018, 58 (10), pp 2092-2107. -------------------------------------------------------------------------------- LibBQB is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program. If not, see . ***********************************************************************************/ // This must always be the first include directive #include "bqb_config.h" #include #include #include #include #include "bqb.h" const char *GetRevisionInfo_bqbtool(unsigned int len) { static char buf[256]; GET_REVISION_INFO( buf, len ); return buf; } const char *GetSourceVersion_bqbtool() { static char buf[256]; GET_SOURCE_VERSION( buf ); return buf; } // Headers required for Linux stack trace #ifndef BQB_INSIDE_TRAVIS #if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) #include #include #endif #endif // Headers required for obtaining host name and working directory #if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) #include #elif defined(_WIN32) #include #include #endif char *gc_sExeName = NULL; char *gc_sWorkingDir = NULL; char *gc_sHostName = NULL; FILE *gc_fLogFile = NULL; CBQBInterface *gc_pBQBInterface = NULL; bool gc_bCompress; bool gc_bDecompress; bool gc_bCheck; bool gc_bCompare; bool gc_bMerge; bool gc_bSplit; bool gc_bFile; bool gc_bCube; bool gc_bXYZ; const char *gc_sInFile; const char *gc_sOutFile; const char *gc_sRefFile; std::vector gc_sInFileList; CBQBParameterSet_Compressor *gc_pParmFile = NULL; int gc_iFileVerbose; CBQBParameterSet_PosAndVol *gc_pParmVol = NULL; int gc_iCubeStart; int gc_iCubeSteps; int gc_iCubeStride; bool gc_bCubeKeepComment; bool gc_bCubeCompare; const char *gc_sCubeRefOut; int gc_iCubeVerbose; bool gc_bCubeDummyRead; int gc_iCubeKey; int gc_iCubeOptimize; int gc_iCubeOptSteps; bool gc_bCubeOnlyOpt; int gc_iCubeOptIncludeFirst; CBQBParameterSet_Position *gc_pParmPos = NULL; int gc_iAtomStart; int gc_iAtomSteps; int gc_iAtomStride; bool gc_bAtomKeepComment; bool gc_bAtomCompare; const char *gc_sAtomRefOut; int gc_iAtomVerbose; int gc_iAtomKey; int gc_iAtomOptimize; int gc_iAtomOptSteps; bool gc_bAtomOnlyOpt; int gc_iAtomOptIncludeFirst; int gc_iCheckVerbose; int gc_iCompareVerbose; int gc_iMergeVerbose; int gc_iSplitVerbose; int gc_iSplitLength; int gc_iSplitSteps; bool gc_bOptTouched; bool gc_bDryRun; void CBQBStatistics::ResetStatistics() { m_oaStatStack.clear(); m_oStat.reset(); } void BQBWriteRevisionInfo() { std::vector sa; unsigned int z, len; gc_pBQBInterface->printf("Revision information of the source code files:\n\n"); len = 0; _begin: sa.push_back( GetRevisionInfo_bqb_alphabet( len ) ); sa.push_back( GetRevisionInfo_bqb_bitset( len ) ); sa.push_back( GetRevisionInfo_bqb_crc( len ) ); sa.push_back( GetRevisionInfo_bqb_cubeframe( len ) ); sa.push_back( GetRevisionInfo_bqb_driver( len ) ); sa.push_back( GetRevisionInfo_bqb_engine( len ) ); sa.push_back( GetRevisionInfo_bqb_extrapolator( len ) ); sa.push_back( GetRevisionInfo_bqb_format( len ) ); sa.push_back( GetRevisionInfo_bqb_hilbert( len ) ); sa.push_back( GetRevisionInfo_bqb_hufftree( len ) ); sa.push_back( GetRevisionInfo_bqb_integerengine( len ) ); sa.push_back( GetRevisionInfo_bqb_interface( len ) ); sa.push_back( GetRevisionInfo_bqb_largeinteger( len ) ); sa.push_back( GetRevisionInfo_bqb_linalg( len ) ); sa.push_back( GetRevisionInfo_bqb_math( len ) ); sa.push_back( GetRevisionInfo_bqb_parmset( len ) ); sa.push_back( GetRevisionInfo_bqb_tools( len ) ); sa.push_back( GetRevisionInfo_bqbtool( len ) ); if (len == 0) { for (z=0;z len) len = strlen(sa[z]); sa.clear(); goto _begin; } for (z=0;zprintf( " %s\n", sa[z] ); gc_pBQBInterface->printf( "\n"); } void BQBCheckSourceVersion() { const char *p; bool b; b = false; p = GetSourceVersion_bqb_alphabet(); if (strcmp( p, GetSourceVersion_bqb_bitset() ) != 0) b = true; if (strcmp( p, GetSourceVersion_bqb_crc() ) != 0) b = true; if (strcmp( p, GetSourceVersion_bqb_cubeframe() ) != 0) b = true; if (strcmp( p, GetSourceVersion_bqb_driver() ) != 0) b = true; if (strcmp( p, GetSourceVersion_bqb_engine() ) != 0) b = true; if (strcmp( p, GetSourceVersion_bqb_extrapolator() ) != 0) b = true; if (strcmp( p, GetSourceVersion_bqb_format() ) != 0) b = true; if (strcmp( p, GetSourceVersion_bqb_hilbert() ) != 0) b = true; if (strcmp( p, GetSourceVersion_bqb_hufftree() ) != 0) b = true; if (strcmp( p, GetSourceVersion_bqb_integerengine() ) != 0) b = true; if (strcmp( p, GetSourceVersion_bqb_interface() ) != 0) b = true; if (strcmp( p, GetSourceVersion_bqb_largeinteger() ) != 0) b = true; if (strcmp( p, GetSourceVersion_bqb_linalg() ) != 0) b = true; if (strcmp( p, GetSourceVersion_bqb_math() ) != 0) b = true; if (strcmp( p, GetSourceVersion_bqb_parmset() ) != 0) b = true; if (strcmp( p, GetSourceVersion_bqb_tools() ) != 0) b = true; if (strcmp( p, GetSourceVersion_bqbtool() ) != 0) b = true; if (b) { gc_pBQBInterface->printf("\n"); gc_pBQBInterface->eprintf("!!!! Warning !!!!\n"); gc_pBQBInterface->printf("The object files do not belong to the same source code version.\n"); gc_pBQBInterface->printf("Something went wrong with compiling. Expect problems and crashes.\n"); gc_pBQBInterface->printf("\n"); BQBWriteRevisionInfo(); } } void CC_InitGlobalVars() { gc_bOptTouched = false; gc_sInFile = NULL; gc_sOutFile = NULL; gc_sRefFile = NULL; gc_bCompress = false; gc_bDecompress = false; gc_bCheck = false; gc_bCompare = false; gc_bMerge = false; gc_bSplit = false; gc_bFile = false; gc_bCube = false; gc_bXYZ = false; gc_pParmFile = new CBQBParameterSet_Compressor(*gc_pBQBInterface); gc_pParmFile->SetTableCount( 6 ); gc_pParmFile->SetOptTables( false ); gc_pParmFile->SetBlockLength( 50 ); gc_pParmFile->SetBW( true ); gc_pParmFile->SetMTF( true ); gc_pParmFile->SetRLE( true ); gc_pParmFile->SetMaxIter( 10 ); gc_pParmFile->SetMaxChunk( 4194304 ); gc_iFileVerbose = 0; gc_iCubeStart = 0; gc_iCubeSteps = -1; gc_iCubeStride = 1; gc_bCubeKeepComment = true; gc_bCubeCompare = true; gc_sCubeRefOut = NULL; gc_bCubeDummyRead = false; gc_iCubeVerbose = 0; gc_iCubeKey = 0; gc_pParmVol = new CBQBParameterSet_PosAndVol(*gc_pBQBInterface); gc_pParmVol->SetVolSigni(5); gc_pParmVol->SetVolEps(12); gc_pParmVol->SetVolOrder(8); gc_pParmVol->SetVolOptOrder(true); gc_pParmVol->SetVolHilbert(true); gc_pParmVol->SetVolNbhFac(1.075); gc_pParmVol->SetVolSplit(10); gc_pParmVol->SetVolTableCount(6); gc_pParmVol->SetVolOptTables(false); gc_pParmVol->SetVolBlockLength(20); gc_pParmVol->SetVolBW(false); gc_pParmVol->SetVolMTF(false); gc_pParmVol->SetVolMaxIter(10); gc_pParmVol->SetVolRLE(true); gc_pParmVol->SetVolMaxChunk(0); gc_pParmVol->SetPosPrecision(6); gc_pParmVol->SetPosOrder(8); gc_pParmVol->SetPosOptOrder(true); gc_pParmVol->SetPosSplit(14); gc_pParmVol->SetPosTableCount(1); gc_pParmVol->SetPosOptTables(false); gc_pParmVol->SetPosBlockLength(40); gc_pParmVol->SetPosBW(false); gc_pParmVol->SetPosMTF(false); gc_pParmVol->SetPosRLE(true); gc_pParmVol->SetPosMaxIter(10); gc_pParmVol->SetPosSortAtom(true); gc_pParmVol->SetPosMaxChunk(0); gc_pParmVol->SetVolUseExtra(true); gc_pParmVol->SetVolExtraSRange(7); gc_pParmVol->SetVolExtraTRange(6); gc_pParmVol->SetVolExtraSOrder(3); gc_pParmVol->SetVolExtraTOrder(2); gc_pParmVol->SetVolExtraOffset(3); gc_pParmVol->SetVolExtraCrossS(true); gc_pParmVol->SetVolExtraCrossT(false); gc_pParmVol->SetVolExtraWrap(true); gc_pParmVol->SetVolExtraCrossRangeS(true); gc_pParmVol->SetVolExtraCrossRangeT(false); gc_pParmVol->SetVolExtraDistExpo(3.0); gc_pParmVol->SetVolExtraTimeExpo(1.0); gc_pParmVol->SetVolExtraPredCorr(true); gc_pParmVol->SetPosUseExtra(true); gc_pParmVol->SetPosExtraTRange(9); gc_pParmVol->SetPosExtraTOrder(6); gc_pParmVol->SetPosExtraTimeExpo(4.0); gc_iCubeOptimize = 1; gc_iCubeOptSteps = -1; gc_bCubeOnlyOpt = false; gc_iCubeOptIncludeFirst = -1; gc_iAtomStart = 0; gc_iAtomSteps = -1; gc_iAtomStride = 1; gc_bAtomKeepComment = true; gc_bAtomCompare = true; gc_sAtomRefOut = NULL; gc_iAtomVerbose = 0; gc_iAtomKey = 0; gc_bDryRun = false; gc_pParmPos = new CBQBParameterSet_Position(*gc_pBQBInterface); gc_pParmPos->SetPrecision(5); gc_pParmPos->SetOrder(8); gc_pParmPos->SetOptOrder(true); gc_pParmPos->SetSplit(14); gc_pParmPos->SetTableCount(1); gc_pParmPos->SetOptTables(false); gc_pParmPos->SetBlockLength(40); gc_pParmPos->SetBW(false); gc_pParmPos->SetMTF(false); gc_pParmPos->SetRLE(true); gc_pParmPos->SetMaxIter(10); gc_pParmPos->SetSortAtom(true); gc_pParmPos->SetMaxChunk(0); gc_pParmPos->SetUseExtra(true); gc_pParmPos->SetExtraTRange(9); gc_pParmPos->SetExtraTOrder(6); gc_pParmPos->SetExtraTimeExpo(4.0); gc_iAtomOptimize = 2; gc_iAtomOptSteps = -1; gc_bAtomOnlyOpt = false; gc_iAtomOptIncludeFirst = -1; gc_iCheckVerbose = 0; gc_iCompareVerbose = 0; gc_iMergeVerbose = 0; gc_iSplitVerbose = 0; gc_iSplitLength = -1; gc_iSplitSteps = -1; } void CC_CommandLineHelp() { gc_pBQBInterface->printf("\n"); gc_pBQBInterface->bprintf("Command line usage:\n\n"); gc_pBQBInterface->printf(" compress {file|voltraj|postraj} [options] \n"); gc_pBQBInterface->printf(" decompress {file|voltraj|postraj} [options] \n"); /* gc_pBQBInterface->printf(" check [options] \n"); gc_pBQBInterface->printf(" compare [options] \n"); gc_pBQBInterface->printf(" merge [options] [infile2.bqb ...]\n"); gc_pBQBInterface->printf(" split [options] \n\n");*/ gc_pBQBInterface->printf("\n"); gc_pBQBInterface->printf("More operating modes (check, compare, split, merge) will be added soon.\n"); gc_pBQBInterface->printf("\n"); gc_pBQBInterface->printf("For volumetric trajectories, currently only the Gaussian Cube file format\n"); gc_pBQBInterface->printf("is supported.\n"); gc_pBQBInterface->printf("\n"); gc_pBQBInterface->printf("For position trajectories, currently only the XMol XYZ file format\n"); gc_pBQBInterface->printf("is supported. More formats will be added soon.\n"); gc_pBQBInterface->printf("\n"); gc_pBQBInterface->printf("In case of \"compress\" or \"decompress\", may be left out,\n"); gc_pBQBInterface->printf("then no output is written (e.g. to check compression ratio or timings).\n\n"); gc_pBQBInterface->printf("To see a list of possible options and their default values,\n"); gc_pBQBInterface->printf("enter the corresponding command without input and output file names.\n"); gc_pBQBInterface->printf("\n"); } bool CC_ParseArguments(int argc, const char *argv[]) { int z, i, ti; double tf; bool b; gc_pBQBInterface->printf("Parsing command line arguments...\n"); if (argc < 3) { gc_pBQBInterface->eprintf("Error: Not enough command line arguments.\n"); return false; } if (strcmp(argv[1],"compress") == 0) gc_bCompress = true; else if (strcmp(argv[1],"decompress") == 0) gc_bDecompress = true; /* else if (strcmp(argv[1],"check") == 0) gc_bCheck = true; else if (strcmp(argv[1],"compare") == 0) gc_bCompare = true; else if (strcmp(argv[1],"merge") == 0) gc_bMerge = true; else if (strcmp(argv[1],"split") == 0) gc_bSplit = true;*/ else { gc_pBQBInterface->eprintf("Error: Unknown first argument \"%s\".\n",argv[1]); return false; } if (gc_bCheck) { b = true; i = 0; for (z=2;zeprintf("Error: Missing value after \"-verbose\".\n"); return false; } if (strcmp(argv[z+1],"2") == 0) { gc_iCheckVerbose = 2; z++; } else if (strcmp(argv[z+1],"1") == 0) { gc_iCheckVerbose = 1; z++; } else if (strcmp(argv[z+1],"0") == 0) { gc_iCheckVerbose = 0; z++; } else gc_iCheckVerbose = 1; gc_pBQBInterface->printf(" -verbose %d\n",gc_iCheckVerbose); continue; } gc_pBQBInterface->eprintf("Error: Unknown command line argument \"%s\".\n",argv[z]); return false; } else { b = false; if (i == 0) { gc_sInFile = argv[z]; gc_pBQBInterface->printf(" infile %s\n",gc_sInFile); } else { gc_pBQBInterface->eprintf("Error: Unrecognized trailing argument: \"%s\".\n",argv[z]); return false; } i++; } } } else if (gc_bSplit) { b = true; i = 0; for (z=2;zeprintf("Error: Missing value after \"-steps\".\n"); return false; } z++; gc_iSplitSteps = atoi(argv[z]); if ((gc_iSplitSteps < -1) || (gc_iSplitSteps == 0)) { gc_pBQBInterface->eprintf("Error: Invalid value for \"-steps\": \"%s\".\n",argv[z]); gc_pBQBInterface->printf(" Allowed values are -1 (=all) or > 0.\n"); return false; } gc_pBQBInterface->printf(" -steps %d\n",gc_iSplitSteps); continue; } if (strcmp(argv[z],"-verbose") == 0) { if (z+1 == argc) { gc_pBQBInterface->eprintf("Error: Missing value after \"-verbose\".\n"); return false; } if (strcmp(argv[z+1],"2") == 0) { gc_iSplitVerbose = 2; z++; } else if (strcmp(argv[z+1],"1") == 0) { gc_iSplitVerbose = 1; z++; } else if (strcmp(argv[z+1],"0") == 0) { gc_iSplitVerbose = 0; z++; } else gc_iSplitVerbose = 1; gc_pBQBInterface->printf(" -verbose %d\n",gc_iSplitVerbose); continue; } gc_pBQBInterface->eprintf("Error: Unknown command line argument \"%s\".\n",argv[z]); return false; } else { b = false; if (i == 0) { gc_sInFile = argv[z]; gc_pBQBInterface->printf(" infile %s\n",gc_sInFile); } else if (i == 1) { gc_sOutFile = argv[z]; gc_pBQBInterface->printf(" outbasename %s\n",gc_sOutFile); } else if (i == 2) { gc_iSplitLength = atoi(argv[z]); gc_pBQBInterface->printf(" splitlength %d\n",gc_iSplitLength); } else { gc_pBQBInterface->eprintf("Error: Unrecognized trailing argument: \"%s\".\n",argv[z]); return false; } i++; } } } else if (gc_bCompare) { b = true; i = 0; for (z=2;zeprintf("Error: Missing value after \"-verbose\".\n"); return false; } if (strcmp(argv[z+1],"2") == 0) { gc_iCompareVerbose = 2; z++; } else if (strcmp(argv[z+1],"1") == 0) { gc_iCompareVerbose = 1; z++; } else if (strcmp(argv[z+1],"0") == 0) { gc_iCompareVerbose = 0; z++; } else gc_iCompareVerbose = 1; gc_pBQBInterface->printf(" -verbose %d\n",gc_iCompareVerbose); continue; } gc_pBQBInterface->eprintf("Error: Unknown command line argument \"%s\".\n",argv[z]); return false; } else { b = false; if (i == 0) { gc_sInFile = argv[z]; gc_pBQBInterface->printf(" infile %s\n",gc_sInFile); } else if (i == 1) { gc_sRefFile = argv[z]; gc_pBQBInterface->printf(" reffile %s\n",gc_sRefFile); } else { gc_pBQBInterface->eprintf("Error: Unrecognized trailing argument: \"%s\".\n",argv[z]); return false; } i++; } } } else if (gc_bMerge) { b = true; i = 0; for (z=2;zeprintf("Error: Missing value after \"-verbose\".\n"); return false; } if (strcmp(argv[z+1],"2") == 0) { gc_iMergeVerbose = 2; z++; } else if (strcmp(argv[z+1],"1") == 0) { gc_iMergeVerbose = 1; z++; } else if (strcmp(argv[z+1],"0") == 0) { gc_iMergeVerbose = 0; z++; } else gc_iMergeVerbose = 1; gc_pBQBInterface->printf(" -verbose %d\n",gc_iMergeVerbose); continue; } gc_pBQBInterface->eprintf("Error: Unknown command line argument \"%s\".\n",argv[z]); return false; } else { b = false; if (i == 0) { gc_sOutFile = argv[z]; gc_pBQBInterface->printf(" outfile %s\n",gc_sInFile); } else { gc_sInFileList.push_back(argv[z]); gc_pBQBInterface->printf(" infile %s\n",argv[z]); } i++; } } } else { if (strcmp(argv[2],"file") == 0) gc_bFile = true; else if (strcmp(argv[2],"voltraj") == 0) gc_bCube = true; else if (strcmp(argv[2],"postraj") == 0) gc_bXYZ = true; else { gc_pBQBInterface->eprintf("Error: Unknown second argument \"%s\".\n",argv[2]); return false; } b = true; i = 0; for (z=3;zprintf(" -dryrun %s\n",gc_bDryRun?"yes":"no"); continue; } if (strcmp(argv[z],"-pkey") == 0) { if (z+1 == argc) { gc_pBQBInterface->eprintf("Error: Missing value after \"-pkey\".\n"); return false; } z++; if (!gc_pParmFile->FromKey(argv[z])) { gc_pBQBInterface->eprintf("Error: Invalid value for \"-pkey\": \"%s\".\n",argv[z]); return false; } gc_pBQBInterface->printf(" -pkey %s\n",argv[z]); continue; } if (strcmp(argv[z],"-tables") == 0) { if (z+1 == argc) { gc_pBQBInterface->eprintf("Error: Missing value after \"-tables\".\n"); return false; } z++; ti = atoi(argv[z]); if ((ti < 1) || (ti > 31)) { gc_pBQBInterface->eprintf("Error: Invalid value for \"-tables\": \"%s\".\n",argv[z]); gc_pBQBInterface->printf(" Allowed values are 1 .. 31.\n"); return false; } gc_pParmFile->SetTableCount(ti); gc_pBQBInterface->printf(" -tables %d\n",gc_pParmFile->GetTableCount()); continue; } if (strcmp(argv[z],"-opttables") == 0) { if (z+1 == argc) { gc_pBQBInterface->eprintf("Error: Missing value after \"-opttables\".\n"); return false; } if ((strcmp(argv[z+1],"yes") == 0) || (strcmp(argv[z+1],"y") == 0)) { gc_pParmFile->SetOptTables(true); z++; } else if ((strcmp(argv[z+1],"no") == 0) || (strcmp(argv[z+1],"n") == 0)) { gc_pParmFile->SetOptTables(false); z++; } else gc_pParmFile->SetOptTables(true); gc_pBQBInterface->printf(" -opttables %s\n",gc_pParmFile->GetOptTables()?"yes":"no"); continue; } if (strcmp(argv[z],"-block") == 0) { if (z+1 == argc) { gc_pBQBInterface->eprintf("Error: Missing value after \"-block\".\n"); return false; } z++; ti = atoi(argv[z]); if ((ti < 1) || (ti > 31)) { gc_pBQBInterface->eprintf("Error: Invalid value for \"-block\": \"%s\".\n",argv[z]); gc_pBQBInterface->printf(" Allowed values are 1 .. 255.\n"); return false; } gc_pParmFile->SetBlockLength(ti); gc_pBQBInterface->printf(" -block %d\n",gc_pParmFile->GetBlockLength()); continue; } if (strcmp(argv[z],"-bw") == 0) { if (z+1 == argc) { gc_pBQBInterface->eprintf("Error: Missing value after \"-bw\".\n"); return false; } if ((strcmp(argv[z+1],"yes") == 0) || (strcmp(argv[z+1],"y") == 0)) { gc_pParmFile->SetBW(true); z++; } else if ((strcmp(argv[z+1],"no") == 0) || (strcmp(argv[z+1],"n") == 0)) { gc_pParmFile->SetBW(false); z++; } else gc_pParmFile->SetBW(true); gc_pBQBInterface->printf(" -bw %s\n",gc_pParmFile->GetBW()?"yes":"no"); continue; } if (strcmp(argv[z],"-mtf") == 0) { if (z+1 == argc) { gc_pBQBInterface->eprintf("Error: Missing value after \"-mtf\".\n"); return false; } if ((strcmp(argv[z+1],"yes") == 0) || (strcmp(argv[z+1],"y") == 0)) { gc_pParmFile->SetMTF(true); z++; } else if ((strcmp(argv[z+1],"no") == 0) || (strcmp(argv[z+1],"n") == 0)) { gc_pParmFile->SetMTF(false); z++; } else gc_pParmFile->SetMTF(true); gc_pBQBInterface->printf(" -mtf %s\n",gc_pParmFile->GetMTF()?"yes":"no"); continue; } if (strcmp(argv[z],"-rle") == 0) { if (z+1 == argc) { gc_pBQBInterface->eprintf("Error: Missing value after \"-rle\".\n"); return false; } if ((strcmp(argv[z+1],"yes") == 0) || (strcmp(argv[z+1],"y") == 0)) { gc_pParmFile->SetRLE(true); z++; } else if ((strcmp(argv[z+1],"no") == 0) || (strcmp(argv[z+1],"n") == 0)) { gc_pParmFile->SetRLE(false); z++; } else gc_pParmFile->SetRLE(true); gc_pBQBInterface->printf(" -rle %s\n",gc_pParmFile->GetRLE()?"yes":"no"); continue; } if (strcmp(argv[z],"-verbose") == 0) { if (z+1 == argc) { gc_pBQBInterface->eprintf("Error: Missing value after \"-verbose\".\n"); return false; } if (strcmp(argv[z+1],"2") == 0) { gc_iFileVerbose = 2; z++; } else if (strcmp(argv[z+1],"1") == 0) { gc_iFileVerbose = 1; z++; } else if (strcmp(argv[z+1],"0") == 0) { gc_iFileVerbose = 0; z++; } else gc_iFileVerbose = 1; gc_pBQBInterface->printf(" -verbose %d\n",gc_iFileVerbose); continue; } if (strcmp(argv[z],"-iter") == 0) { if (z+1 == argc) { gc_pBQBInterface->eprintf("Error: Missing value after \"-iter\".\n"); return false; } z++; ti = atoi(argv[z]); if ((ti < 0) || (ti > 126)) { gc_pBQBInterface->eprintf("Error: Invalid value for \"-iter\": \"%s\".\n",argv[z]); gc_pBQBInterface->printf(" Allowed values are 0 .. 126.\n"); return false; } gc_pParmFile->SetMaxIter(ti); gc_pBQBInterface->printf(" -iter %d\n",gc_pParmFile->GetMaxIter()); continue; } if (strcmp(argv[z],"-maxchunk") == 0) { if (z+1 == argc) { gc_pBQBInterface->eprintf("Error: Missing value after \"-maxchunk\".\n"); return false; } z++; ti = atoi(argv[z]); if ((ti < 0) || (ti > 16777216)) { gc_pBQBInterface->eprintf("Error: Invalid value for \"-maxchunk\": \"%s\".\n",argv[z]); gc_pBQBInterface->printf(" Allowed values are 0 .. 16777216.\n"); return false; } gc_pParmFile->SetMaxChunk(ti); gc_pBQBInterface->printf(" -maxchunk %d\n",gc_pParmFile->GetMaxChunk()); continue; } gc_pBQBInterface->eprintf("Error: Unknown command line argument \"%s\".\n",argv[z]); return false; } else { b = false; if (i == 0) { gc_sInFile = argv[z]; gc_pBQBInterface->printf(" infile %s\n",gc_sInFile); } else if (i == 1) { gc_sOutFile = argv[z]; gc_pBQBInterface->printf(" outfile %s\n",gc_sOutFile); } else { gc_pBQBInterface->eprintf("Error: Unrecognized trailing argument: \"%s\".\n",argv[z]); return false; } i++; } } // END IF FILE if (gc_bCube) { if ((argv[z][0] == '-') && b) { if (strcmp(argv[z],"-dryrun") == 0) { if (z+1 != argc) { if ((strcmp(argv[z+1],"yes") == 0) || (strcmp(argv[z+1],"y") == 0)) { gc_bDryRun = true; z++; } else if ((strcmp(argv[z+1],"no") == 0) || (strcmp(argv[z+1],"n") == 0)) { gc_bDryRun = false; z++; } else gc_bDryRun = true; } else gc_bDryRun = true; gc_pBQBInterface->printf(" -dryrun %s\n",gc_bDryRun?"yes":"no"); continue; } if (strcmp(argv[z],"-pkey") == 0) { if (z+1 == argc) { gc_pBQBInterface->eprintf("Error: Missing value after \"-pkey\".\n"); return false; } z++; if (!gc_pParmVol->FromKey(argv[z])) { gc_pBQBInterface->eprintf("Error: Invalid value for \"-pkey\": \"%s\".\n",argv[z]); return false; } gc_pBQBInterface->printf(" -pkey %s\n",argv[z]); gc_iCubeOptimize = 0; continue; } if (strcmp(argv[z],"-start") == 0) { if (z+1 == argc) { gc_pBQBInterface->eprintf("Error: Missing value after \"-start\".\n"); return false; } z++; gc_iCubeStart = atoi(argv[z]); if (gc_iCubeStart < 1) { gc_pBQBInterface->eprintf("Error: Invalid value for \"-start\": \"%s\".\n",argv[z]); gc_pBQBInterface->printf(" Allowed values are >= 1.\n"); return false; } gc_iCubeStart -= 1; gc_pBQBInterface->printf(" -start %d\n",gc_iCubeStart+1); continue; } if (strcmp(argv[z],"-steps") == 0) { if (z+1 == argc) { gc_pBQBInterface->eprintf("Error: Missing value after \"-steps\".\n"); return false; } z++; gc_iCubeSteps = atoi(argv[z]); if ((gc_iCubeSteps < -1) || (gc_iCubeSteps == 0)) { gc_pBQBInterface->eprintf("Error: Invalid value for \"-steps\": \"%s\".\n",argv[z]); gc_pBQBInterface->printf(" Allowed values are -1 (=all) or > 0.\n"); return false; } gc_pBQBInterface->printf(" -steps %d\n",gc_iCubeSteps); continue; } if (strcmp(argv[z],"-stride") == 0) { if (z+1 == argc) { gc_pBQBInterface->eprintf("Error: Missing value after \"-stride\".\n"); return false; } z++; gc_iCubeStride = atoi(argv[z]); if (gc_iCubeStride < 1) { gc_pBQBInterface->eprintf("Error: Invalid value for \"-stride\": \"%s\".\n",argv[z]); gc_pBQBInterface->printf(" Allowed values are > 0.\n"); return false; } gc_pBQBInterface->printf(" -stride %d\n",gc_iCubeStride); continue; } if (strcmp(argv[z],"-keyframe") == 0) { if (z+1 == argc) { gc_pBQBInterface->eprintf("Error: Missing value after \"-keyframe\".\n"); return false; } z++; gc_iCubeKey = atoi(argv[z]); if (gc_iCubeKey < 1) { gc_pBQBInterface->eprintf("Error: Invalid value for \"-keyframe\": \"%s\".\n",argv[z]); gc_pBQBInterface->printf(" Allowed values are >= 1.\n"); return false; } gc_pBQBInterface->printf(" -keyframe %d\n",gc_iCubeKey); continue; } if (strcmp(argv[z],"-comment") == 0) { if (z+1 == argc) { gc_pBQBInterface->eprintf("Error: Missing value after \"-comment\".\n"); return false; } if ((strcmp(argv[z+1],"yes") == 0) || (strcmp(argv[z+1],"y") == 0)) { gc_bCubeKeepComment = true; z++; } else if ((strcmp(argv[z+1],"no") == 0) || (strcmp(argv[z+1],"n") == 0)) { gc_bCubeKeepComment = false; z++; } else gc_bCubeKeepComment = true; gc_pBQBInterface->printf(" -comment %s\n",gc_bCubeKeepComment?"yes":"no"); continue; } if (strcmp(argv[z],"-check") == 0) { if (z+1 == argc) { gc_pBQBInterface->eprintf("Error: Missing value after \"-check\".\n"); return false; } if ((strcmp(argv[z+1],"yes") == 0) || (strcmp(argv[z+1],"y") == 0)) { gc_bCubeCompare = true; z++; } else if ((strcmp(argv[z+1],"no") == 0) || (strcmp(argv[z+1],"n") == 0)) { gc_bCubeCompare = false; z++; } else gc_bCubeCompare = true; gc_pBQBInterface->printf(" -check %s\n",gc_bCubeCompare?"yes":"no"); continue; } if (strcmp(argv[z],"-dummyread") == 0) { if (z+1 == argc) { gc_pBQBInterface->eprintf("Error: Missing value after \"-dummyread\".\n"); return false; } if ((strcmp(argv[z+1],"yes") == 0) || (strcmp(argv[z+1],"y") == 0)) { gc_bCubeDummyRead = true; z++; } else if ((strcmp(argv[z+1],"no") == 0) || (strcmp(argv[z+1],"n") == 0)) { gc_bCubeDummyRead = false; z++; } else gc_bCubeDummyRead = true; gc_pBQBInterface->printf(" -dummyread %s\n",gc_bCubeDummyRead?"yes":"no"); continue; } if (strcmp(argv[z],"-verbose") == 0) { if (z+1 == argc) { gc_pBQBInterface->eprintf("Error: Missing value after \"-verbose\".\n"); return false; } if (strcmp(argv[z+1],"2") == 0) { gc_iCubeVerbose = 2; z++; } else if (strcmp(argv[z+1],"1") == 0) { gc_iCubeVerbose = 1; z++; } else if (strcmp(argv[z+1],"0") == 0) { gc_iCubeVerbose = 0; z++; } else gc_iCubeVerbose = 1; gc_pBQBInterface->printf(" -verbose %d\n",gc_iCubeVerbose); continue; } if (strcmp(argv[z],"-refout") == 0) { if (z+1 == argc) { gc_pBQBInterface->eprintf("Error: Missing value after \"-verbose\".\n"); return false; } z++; gc_sCubeRefOut = argv[z]; gc_pBQBInterface->printf(" -refout %s\n",gc_sCubeRefOut); continue; } if (strcmp(argv[z],"-vsigni") == 0) { if (z+1 == argc) { gc_pBQBInterface->eprintf("Error: Missing value after \"-vsigni\".\n"); return false; } z++; ti = atoi(argv[z]); if ((ti < 1) || (ti > 9)) { gc_pBQBInterface->eprintf("Error: Invalid value for \"-vsigni\": \"%s\".\n",argv[z]); gc_pBQBInterface->printf(" Allowed values are 1 .. 9.\n"); return false; } gc_pParmVol->SetVolSigni(ti); gc_pBQBInterface->printf(" -vsigni %d\n",gc_pParmVol->GetVolSigni()); continue; } if (strcmp(argv[z],"-veps") == 0) { if (z+1 == argc) { gc_pBQBInterface->eprintf("Error: Missing value after \"-veps\".\n"); return false; } z++; ti = atoi(argv[z]); if ((ti < 0) || (ti > 63)) { gc_pBQBInterface->eprintf("Error: Invalid value for \"-veps\": \"%s\".\n",argv[z]); gc_pBQBInterface->printf(" Allowed values are 0 .. 63.\n"); return false; } gc_pParmVol->SetVolEps(ti); gc_pBQBInterface->printf(" -veps %d\n",gc_pParmVol->GetVolEps()); continue; } if (strcmp(argv[z],"-vorder") == 0) { if (z+1 == argc) { gc_pBQBInterface->eprintf("Error: Missing value after \"-vorder\".\n"); return false; } z++; ti = atoi(argv[z]); if ((ti < 0) || (ti > 15)) { gc_pBQBInterface->eprintf("Error: Invalid value for \"-vorder\": \"%s\".\n",argv[z]); gc_pBQBInterface->printf(" Allowed values are 0 .. 15.\n"); return false; } gc_pParmVol->SetVolOrder(ti); gc_pBQBInterface->printf(" -vorder %d\n",gc_pParmVol->GetVolOrder()); continue; } if (strcmp(argv[z],"-voptorder") == 0) { if (z+1 == argc) { gc_pBQBInterface->eprintf("Error: Missing value after \"-voptorder\".\n"); return false; } if ((strcmp(argv[z+1],"yes") == 0) || (strcmp(argv[z+1],"y") == 0)) { gc_pParmVol->SetVolOptOrder(true); z++; } else if ((strcmp(argv[z+1],"no") == 0) || (strcmp(argv[z+1],"n") == 0)) { gc_pParmVol->SetVolOptOrder(false); z++; } else gc_pParmVol->SetVolOptOrder(true); gc_pBQBInterface->printf(" -voptorder %s\n",gc_pParmVol->GetVolOptOrder()?"yes":"no"); continue; } if (strcmp(argv[z],"-vhilbert") == 0) { if (z+1 == argc) { gc_pBQBInterface->eprintf("Error: Missing value after \"-vhilbert\".\n"); return false; } if ((strcmp(argv[z+1],"yes") == 0) || (strcmp(argv[z+1],"y") == 0)) { gc_pParmVol->SetVolHilbert(true); z++; } else if ((strcmp(argv[z+1],"no") == 0) || (strcmp(argv[z+1],"n") == 0)) { gc_pParmVol->SetVolHilbert(false); z++; } else gc_pParmVol->SetVolHilbert(true); gc_pBQBInterface->printf(" -vhilbert %s\n",gc_pParmVol->GetVolHilbert()?"yes":"no"); continue; } if (strcmp(argv[z],"-vnbhfac") == 0) { if (z+1 == argc) { gc_pBQBInterface->eprintf("Error: Missing value after \"-vnbhfac\".\n"); return false; } z++; tf = atof(argv[z]); if ((tf < 0.0) || (tf > 4.0)) { gc_pBQBInterface->eprintf("Error: Invalid value for \"-vnbhfac\": \"%s\".\n",argv[z]); gc_pBQBInterface->printf(" Allowed values are 0.0 .. 4.0\n"); return false; } gc_pParmVol->SetVolNbhFac(tf); gc_pBQBInterface->printf(" -vnbhfac %.3f\n",gc_pParmVol->GetVolNbhFac()); continue; } if (strcmp(argv[z],"-vsplit") == 0) { if (z+1 == argc) { gc_pBQBInterface->eprintf("Error: Missing value after \"-vsplit\".\n"); return false; } z++; ti = atoi(argv[z]); if ((ti < 1) || (ti > 31)) { gc_pBQBInterface->eprintf("Error: Invalid value for \"-vsplit\": \"%s\".\n",argv[z]); gc_pBQBInterface->printf(" Allowed values are 1 .. 31.\n"); return false; } gc_pParmVol->SetVolSplit(ti); gc_pBQBInterface->printf(" -vsplit %d\n",gc_pParmVol->GetVolSplit()); continue; } if (strcmp(argv[z],"-vtables") == 0) { if (z+1 == argc) { gc_pBQBInterface->eprintf("Error: Missing value after \"-vtables\".\n"); return false; } z++; ti = atoi(argv[z]); if ((ti < 1) || (ti > 64)) { gc_pBQBInterface->eprintf("Error: Invalid value for \"-vtables\": \"%s\".\n",argv[z]); gc_pBQBInterface->printf(" Allowed values are 1 .. 64.\n"); return false; } gc_pParmVol->SetVolTableCount(ti); gc_pBQBInterface->printf(" -vtables %d\n",gc_pParmVol->GetVolTableCount()); continue; } if (strcmp(argv[z],"-vopttables") == 0) { if (z+1 == argc) { gc_pBQBInterface->eprintf("Error: Missing value after \"-vopttables\".\n"); return false; } if ((strcmp(argv[z+1],"yes") == 0) || (strcmp(argv[z+1],"y") == 0)) { gc_pParmVol->SetVolOptTables(true); z++; } else if ((strcmp(argv[z+1],"no") == 0) || (strcmp(argv[z+1],"n") == 0)) { gc_pParmVol->SetVolOptTables(false); z++; } else gc_pParmVol->SetVolOptTables(true); gc_pBQBInterface->printf(" -vopttables %s\n",gc_pParmVol->GetVolOptTables()?"yes":"no"); continue; } if (strcmp(argv[z],"-vblock") == 0) { if (z+1 == argc) { gc_pBQBInterface->eprintf("Error: Missing value after \"-vblock\".\n"); return false; } z++; ti = atoi(argv[z]); if ((ti < 1) || (ti > 128)) { gc_pBQBInterface->eprintf("Error: Invalid value for \"-vblock\": \"%s\".\n",argv[z]); gc_pBQBInterface->printf(" Allowed values are 1 .. 128.\n"); return false; } gc_pParmVol->SetVolBlockLength(ti); gc_pBQBInterface->printf(" -vblock %d\n",gc_pParmVol->GetVolBlockLength()); continue; } if (strcmp(argv[z],"-vbw") == 0) { if (z+1 == argc) { gc_pBQBInterface->eprintf("Error: Missing value after \"-vbw\".\n"); return false; } if ((strcmp(argv[z+1],"yes") == 0) || (strcmp(argv[z+1],"y") == 0)) { gc_pParmVol->SetVolBW(true); z++; } else if ((strcmp(argv[z+1],"no") == 0) || (strcmp(argv[z+1],"n") == 0)) { gc_pParmVol->SetVolBW(false); z++; } else gc_pParmVol->SetVolBW(true); gc_pBQBInterface->printf(" -vbw %s\n",gc_pParmVol->GetVolBW()?"yes":"no"); continue; } if (strcmp(argv[z],"-vmtf") == 0) { if (z+1 == argc) { gc_pBQBInterface->eprintf("Error: Missing value after \"-vmtf\".\n"); return false; } if ((strcmp(argv[z+1],"yes") == 0) || (strcmp(argv[z+1],"y") == 0)) { gc_pParmVol->SetVolMTF(true); z++; } else if ((strcmp(argv[z+1],"no") == 0) || (strcmp(argv[z+1],"n") == 0)) { gc_pParmVol->SetVolMTF(false); z++; } else gc_pParmVol->SetVolMTF(true); gc_pBQBInterface->printf(" -vmtf %s\n",gc_pParmVol->GetVolMTF()?"yes":"no"); continue; } if (strcmp(argv[z],"-vrle") == 0) { if (z+1 == argc) { gc_pBQBInterface->eprintf("Error: Missing value after \"-vrle\".\n"); return false; } if ((strcmp(argv[z+1],"yes") == 0) || (strcmp(argv[z+1],"y") == 0)) { gc_pParmVol->SetVolRLE(true); z++; } else if ((strcmp(argv[z+1],"no") == 0) || (strcmp(argv[z+1],"n") == 0)) { gc_pParmVol->SetVolRLE(false); z++; } else gc_pParmVol->SetVolRLE(true); gc_pBQBInterface->printf(" -vrle %s\n",gc_pParmVol->GetVolRLE()?"yes":"no"); continue; } if (strcmp(argv[z],"-viter") == 0) { if (z+1 == argc) { gc_pBQBInterface->eprintf("Error: Missing value after \"-viter\".\n"); return false; } z++; ti = atoi(argv[z]); if ((ti < 0) || (ti > 126)) { gc_pBQBInterface->eprintf("Error: Invalid value for \"-viter\": \"%s\".\n",argv[z]); gc_pBQBInterface->printf(" Allowed values are 0 .. 126.\n"); return false; } gc_pParmVol->SetVolMaxIter(ti); gc_pBQBInterface->printf(" -viter %d\n",gc_pParmVol->GetVolMaxIter()); continue; } if (strcmp(argv[z],"-vmaxchunk") == 0) { if (z+1 == argc) { gc_pBQBInterface->eprintf("Error: Missing value after \"-vmaxchunk\".\n"); return false; } z++; ti = atoi(argv[z]); if ((ti < 0) || (ti > 16777216)) { gc_pBQBInterface->eprintf("Error: Invalid value for \"-vmaxchunk\": \"%s\".\n",argv[z]); gc_pBQBInterface->printf(" Allowed values are 0 .. 16777216.\n"); return false; } gc_pParmVol->SetVolMaxChunk(ti); gc_pBQBInterface->printf(" -vmaxchunk %d\n",gc_pParmVol->GetVolMaxChunk()); continue; } if (strcmp(argv[z],"-optimize") == 0) { if (z+1 == argc) { gc_pBQBInterface->eprintf("Error: Missing value after \"-optimize\".\n"); return false; } if ((strcmp(argv[z+1],"0") == 0) || (strcmp(argv[z+1],"1") == 0) || (strcmp(argv[z+1],"2") == 0) || (strcmp(argv[z+1],"3") == 0) || (strcmp(argv[z+1],"4") == 0)) { gc_iCubeOptimize = atoi(argv[z+1]); z++; } else if (bqbisinteger(argv[z+1])) { gc_pBQBInterface->eprintf("Error: Invalid value \"%s\" after \"-optimize\". Allowed range is 0 to 4.\n", argv[z+1]); return false; } else gc_iCubeOptimize = 2; if ((gc_iCubeOptimize < 0) || (gc_iCubeOptimize > 4)) { gc_pBQBInterface->eprintf("Error: Invalid value for \"-optimize\": \"%s\".\n",argv[z]); gc_pBQBInterface->printf(" Allowed values are 0 .. 4.\n"); return false; } gc_pBQBInterface->printf(" -optimize %d\n",gc_iCubeOptimize); gc_bOptTouched = true; continue; } if (strcmp(argv[z],"-optsteps") == 0) { if (z+1 == argc) { gc_pBQBInterface->eprintf("Error: Missing value after \"-optsteps\".\n"); return false; } z++; gc_iCubeOptSteps = atoi(argv[z]); if (gc_iCubeOptSteps < 1) { gc_pBQBInterface->eprintf("Error: Invalid value for \"-optsteps\": \"%s\".\n",argv[z]); gc_pBQBInterface->printf(" Allowed values are > 0.\n"); return false; } gc_pBQBInterface->printf(" -optsteps %d\n",gc_iCubeOptSteps); continue; } if (strcmp(argv[z],"-onlyopt") == 0) { if (z+1 == argc) { gc_pBQBInterface->eprintf("Error: Missing value after \"-onlyopt\".\n"); return false; } if ((strcmp(argv[z+1],"yes") == 0) || (strcmp(argv[z+1],"y") == 0)) { gc_bCubeOnlyOpt = true; z++; } else if ((strcmp(argv[z+1],"no") == 0) || (strcmp(argv[z+1],"n") == 0)) { gc_bCubeOnlyOpt = false; z++; } else gc_bCubeOnlyOpt = true; gc_pBQBInterface->printf(" -onlyopt %s\n",gc_bCubeOnlyOpt?"yes":"no"); continue; } if (strcmp(argv[z],"-optstart") == 0) { if (z+1 == argc) { gc_pBQBInterface->eprintf("Error: Missing value after \"-optstart\".\n"); return false; } if ((strcmp(argv[z+1],"yes") == 0) || (strcmp(argv[z+1],"y") == 0)) { gc_iCubeOptIncludeFirst = 1; z++; } else if ((strcmp(argv[z+1],"no") == 0) || (strcmp(argv[z+1],"n") == 0)) { gc_iCubeOptIncludeFirst = 0; z++; } else gc_iCubeOptIncludeFirst = 1; gc_pBQBInterface->printf(" -optstart %s\n",(gc_iCubeOptIncludeFirst>0)?"yes":"no"); continue; } if (strcmp(argv[z],"-vextra") == 0) { if (z+1 == argc) { gc_pBQBInterface->eprintf("Error: Missing value after \"-vextra\".\n"); return false; } if ((strcmp(argv[z+1],"yes") == 0) || (strcmp(argv[z+1],"y") == 0)) { gc_pParmVol->SetVolUseExtra(true); z++; } else if ((strcmp(argv[z+1],"no") == 0) || (strcmp(argv[z+1],"n") == 0)) { gc_pParmVol->SetVolUseExtra(false); z++; } else gc_pParmVol->SetVolUseExtra(true); gc_pBQBInterface->printf(" -vextra %s\n",gc_pParmVol->GetVolUseExtra()?"yes":"no"); continue; } if (strcmp(argv[z],"-vexsrange") == 0) { if (z+1 == argc) { gc_pBQBInterface->eprintf("Error: Missing value after \"-vexsrange\".\n"); return false; } z++; ti = atoi(argv[z]); if ((ti < 1) || (ti > 15)) { gc_pBQBInterface->eprintf("Error: Invalid value for \"-vexsrange\": \"%s\".\n",argv[z]); gc_pBQBInterface->printf(" Allowed values are 1 .. 15.\n"); return false; } gc_pParmVol->SetVolExtraSRange(ti); gc_pBQBInterface->printf(" -vexsrange %d\n",gc_pParmVol->GetVolExtraSRangeX()); continue; } if (strcmp(argv[z],"-vexsrangex") == 0) { if (z+1 == argc) { gc_pBQBInterface->eprintf("Error: Missing value after \"-vexsrangex\".\n"); return false; } z++; ti = atoi(argv[z]); if ((ti < 1) || (ti > 15)) { gc_pBQBInterface->eprintf("Error: Invalid value for \"-vexsrangex\": \"%s\".\n",argv[z]); gc_pBQBInterface->printf(" Allowed values are 1 .. 15.\n"); return false; } gc_pParmVol->SetVolExtraSRangeX(ti); gc_pBQBInterface->printf(" -vexsrangex %d\n",gc_pParmVol->GetVolExtraSRangeX()); continue; } if (strcmp(argv[z],"-vexsrangey") == 0) { if (z+1 == argc) { gc_pBQBInterface->eprintf("Error: Missing value after \"-vexsrangey\".\n"); return false; } z++; ti = atoi(argv[z]); if ((ti < 1) || (ti > 15)) { gc_pBQBInterface->eprintf("Error: Invalid value for \"-vexsrangey\": \"%s\".\n",argv[z]); gc_pBQBInterface->printf(" Allowed values are 1 .. 15.\n"); return false; } gc_pParmVol->SetVolExtraSRangeY(ti); gc_pBQBInterface->printf(" -vexsrangey %d\n",gc_pParmVol->GetVolExtraSRangeY()); continue; } if (strcmp(argv[z],"-vexsrangez") == 0) { if (z+1 == argc) { gc_pBQBInterface->eprintf("Error: Missing value after \"-vexsrangez\".\n"); return false; } z++; ti = atoi(argv[z]); if ((ti < 1) || (ti > 15)) { gc_pBQBInterface->eprintf("Error: Invalid value for \"-vexsrangez\": \"%s\".\n",argv[z]); gc_pBQBInterface->printf(" Allowed values are 1 .. 15.\n"); return false; } gc_pParmVol->SetVolExtraSRangeZ(ti); gc_pBQBInterface->printf(" -vexsrangez %d\n",gc_pParmVol->GetVolExtraSRangeZ()); continue; } if (strcmp(argv[z],"-vextrange") == 0) { if (z+1 == argc) { gc_pBQBInterface->eprintf("Error: Missing value after \"-vextrange\".\n"); return false; } z++; ti = atoi(argv[z]); if ((ti < 1) || (ti > 15)) { gc_pBQBInterface->eprintf("Error: Invalid value for \"-vextrange\": \"%s\".\n",argv[z]); gc_pBQBInterface->printf(" Allowed values are 1 .. 15.\n"); return false; } gc_pParmVol->SetVolExtraTRange(ti); gc_pBQBInterface->printf(" -vextrange %d\n",gc_pParmVol->GetVolExtraTRange()); continue; } if (strcmp(argv[z],"-vexsorder") == 0) { if (z+1 == argc) { gc_pBQBInterface->eprintf("Error: Missing value after \"-vexsorder\".\n"); return false; } z++; ti = atoi(argv[z]); if ((ti < 0) || (ti > 15)) { gc_pBQBInterface->eprintf("Error: Invalid value for \"-vexsorder\": \"%s\".\n",argv[z]); gc_pBQBInterface->printf(" Allowed values are 0 .. 15.\n"); return false; } gc_pParmVol->SetVolExtraSOrder(ti); gc_pBQBInterface->printf(" -vexsorder %d\n",gc_pParmVol->GetVolExtraSOrder()); continue; } if (strcmp(argv[z],"-vextorder") == 0) { if (z+1 == argc) { gc_pBQBInterface->eprintf("Error: Missing value after \"-vextorder\".\n"); return false; } z++; ti = atoi(argv[z]); if ((ti < 0) || (ti > 15)) { gc_pBQBInterface->eprintf("Error: Invalid value for \"-vextorder\": \"%s\".\n",argv[z]); gc_pBQBInterface->printf(" Allowed values are 0 .. 15.\n"); return false; } gc_pParmVol->SetVolExtraTOrder(ti); gc_pBQBInterface->printf(" -vextorder %d\n",gc_pParmVol->GetVolExtraTOrder()); continue; } if (strcmp(argv[z],"-vexoffset") == 0) { if (z+1 == argc) { gc_pBQBInterface->eprintf("Error: Missing value after \"-vexoffset\".\n"); return false; } z++; ti = atoi(argv[z]); if ((ti < 0) || (ti > 15)) { gc_pBQBInterface->eprintf("Error: Invalid value for \"-vexoffset\": \"%s\".\n",argv[z]); gc_pBQBInterface->printf(" Allowed values are 0 .. 15.\n"); return false; } gc_pParmVol->SetVolExtraOffset(ti); gc_pBQBInterface->printf(" -vexoffset %d\n",gc_pParmVol->GetVolExtraOffsetX()); continue; } if (strcmp(argv[z],"-vexoffsetx") == 0) { if (z+1 == argc) { gc_pBQBInterface->eprintf("Error: Missing value after \"-vexoffsetx\".\n"); return false; } z++; ti = atoi(argv[z]); if ((ti < 0) || (ti > 15)) { gc_pBQBInterface->eprintf("Error: Invalid value for \"-vexoffsetx\": \"%s\".\n",argv[z]); gc_pBQBInterface->printf(" Allowed values are 0 .. 15?.\n"); return false; } gc_pParmVol->SetVolExtraOffsetX(ti); gc_pBQBInterface->printf(" -vexoffsetx %d\n",gc_pParmVol->GetVolExtraOffsetX()); continue; } if (strcmp(argv[z],"-vexoffsety") == 0) { if (z+1 == argc) { gc_pBQBInterface->eprintf("Error: Missing value after \"-vexoffsety\".\n"); return false; } z++; ti = atoi(argv[z]); if ((ti < 0) || (ti > 15)) { gc_pBQBInterface->eprintf("Error: Invalid value for \"-vexoffsety\": \"%s\".\n",argv[z]); gc_pBQBInterface->printf(" Allowed values are 0 .. 15.\n"); return false; } gc_pParmVol->SetVolExtraOffsetY(ti); gc_pBQBInterface->printf(" -vexoffsety %d\n",gc_pParmVol->GetVolExtraOffsetY()); continue; } if (strcmp(argv[z],"-vexoffsetz") == 0) { if (z+1 == argc) { gc_pBQBInterface->eprintf("Error: Missing value after \"-vexoffsetz\".\n"); return false; } z++; ti = atoi(argv[z]); if ((ti < 0) || (ti > 15)) { gc_pBQBInterface->eprintf("Error: Invalid value for \"-vexoffsetz\": \"%s\".\n",argv[z]); gc_pBQBInterface->printf(" Allowed values are 0 .. 15.\n"); return false; } gc_pParmVol->SetVolExtraOffsetZ(ti); gc_pBQBInterface->printf(" -vexoffsetz %d\n",gc_pParmVol->GetVolExtraOffsetZ()); continue; } if (strcmp(argv[z],"-vexscross") == 0) { if (z+1 == argc) { gc_pBQBInterface->eprintf("Error: Missing value after \"-vexscross\".\n"); return false; } if ((strcmp(argv[z+1],"yes") == 0) || (strcmp(argv[z+1],"y") == 0)) { gc_pParmVol->SetVolExtraCrossS(true); z++; } else if ((strcmp(argv[z+1],"no") == 0) || (strcmp(argv[z+1],"n") == 0)) { gc_pParmVol->SetVolExtraCrossS(false); z++; } else gc_pParmVol->SetVolExtraCrossS(true); gc_pBQBInterface->printf(" -vexscross %s\n",gc_pParmVol->GetVolExtraCrossS()?"yes":"no"); continue; } if (strcmp(argv[z],"-vextcross") == 0) { if (z+1 == argc) { gc_pBQBInterface->eprintf("Error: Missing value after \"-vextcross\".\n"); return false; } if ((strcmp(argv[z+1],"yes") == 0) || (strcmp(argv[z+1],"y") == 0)) { gc_pParmVol->SetVolExtraCrossT(true); z++; } else if ((strcmp(argv[z+1],"no") == 0) || (strcmp(argv[z+1],"n") == 0)) { gc_pParmVol->SetVolExtraCrossT(false); z++; } else gc_pParmVol->SetVolExtraCrossT(true); gc_pBQBInterface->printf(" -vextcross %s\n",gc_pParmVol->GetVolExtraCrossT()?"yes":"no"); continue; } if (strcmp(argv[z],"-vexwrap") == 0) { if (z+1 == argc) { gc_pBQBInterface->eprintf("Error: Missing value after \"-vexwrap\".\n"); return false; } if ((strcmp(argv[z+1],"yes") == 0) || (strcmp(argv[z+1],"y") == 0)) { gc_pParmVol->SetVolExtraWrap(true); z++; } else if ((strcmp(argv[z+1],"no") == 0) || (strcmp(argv[z+1],"n") == 0)) { gc_pParmVol->SetVolExtraWrap(false); z++; } else gc_pParmVol->SetVolExtraWrap(true); gc_pBQBInterface->printf(" -vexwrap %s\n",gc_pParmVol->GetVolExtraWrap()?"yes":"no"); continue; } if (strcmp(argv[z],"-vexscrossrange") == 0) { if (z+1 == argc) { gc_pBQBInterface->eprintf("Error: Missing value after \"-vexscrossrange\".\n"); return false; } if ((strcmp(argv[z+1],"yes") == 0) || (strcmp(argv[z+1],"y") == 0)) { gc_pParmVol->SetVolExtraCrossRangeS(true); z++; } else if ((strcmp(argv[z+1],"no") == 0) || (strcmp(argv[z+1],"n") == 0)) { gc_pParmVol->SetVolExtraCrossRangeS(false); z++; } else gc_pParmVol->SetVolExtraCrossRangeS(true); gc_pBQBInterface->printf(" -vexscrossrange %s\n",gc_pParmVol->GetVolExtraCrossRangeS()?"yes":"no"); continue; } if (strcmp(argv[z],"-vextcrossrange") == 0) { if (z+1 == argc) { gc_pBQBInterface->eprintf("Error: Missing value after \"-vextcrossrange\".\n"); return false; } if ((strcmp(argv[z+1],"yes") == 0) || (strcmp(argv[z+1],"y") == 0)) { gc_pParmVol->SetVolExtraCrossRangeT(true); z++; } else if ((strcmp(argv[z+1],"no") == 0) || (strcmp(argv[z+1],"n") == 0)) { gc_pParmVol->SetVolExtraCrossRangeT(false); z++; } else gc_pParmVol->SetVolExtraCrossRangeT(true); gc_pBQBInterface->printf(" -vextcrossrange %s\n",gc_pParmVol->GetVolExtraCrossRangeT()?"yes":"no"); continue; } if (strcmp(argv[z],"-vexdistexpo") == 0) { if (z+1 == argc) { gc_pBQBInterface->eprintf("Error: Missing value after \"-vexdistexpo\".\n"); return false; } z++; tf = atof(argv[z]); if ((tf < 0.0) || (tf > 16.0)) { gc_pBQBInterface->eprintf("Error: Invalid value for \"-vexdistexpo\": \"%s\".\n",argv[z]); gc_pBQBInterface->printf(" Allowed values are 0.0 .. 16.0\n"); return false; } gc_pParmVol->SetVolExtraDistExpo(tf); gc_pBQBInterface->printf(" -vexdistexpo %.3f\n",gc_pParmVol->GetVolExtraDistExpo()); continue; } if (strcmp(argv[z],"-vextimeexpo") == 0) { if (z+1 == argc) { gc_pBQBInterface->eprintf("Error: Missing value after \"-vextimeexpo\".\n"); return false; } z++; tf = atof(argv[z]); if ((tf < 0.0) || (tf > 16.0)) { gc_pBQBInterface->eprintf("Error: Invalid value for \"-vextimeexpo\": \"%s\".\n",argv[z]); gc_pBQBInterface->printf(" Allowed values are 0.0 .. 16.0\n"); return false; } gc_pParmVol->SetVolExtraTimeExpo(tf); gc_pBQBInterface->printf(" -vextimeexpo %.3f\n",gc_pParmVol->GetVolExtraTimeExpo()); continue; } if (strcmp(argv[z],"-vexpredcorr") == 0) { if (z+1 == argc) { gc_pBQBInterface->eprintf("Error: Missing value after \"-vexpredcorr\".\n"); return false; } if ((strcmp(argv[z+1],"yes") == 0) || (strcmp(argv[z+1],"y") == 0)) { gc_pParmVol->SetVolExtraPredCorr(true); z++; } else if ((strcmp(argv[z+1],"no") == 0) || (strcmp(argv[z+1],"n") == 0)) { gc_pParmVol->SetVolExtraPredCorr(false); z++; } else gc_pParmVol->SetVolExtraPredCorr(true); gc_pBQBInterface->printf(" -vexpredcorr %s\n",gc_pParmVol->GetVolExtraPredCorr()?"yes":"no"); continue; } if (strcmp(argv[z],"-pextra") == 0) { if (z+1 == argc) { gc_pBQBInterface->eprintf("Error: Missing value after \"-pextra\".\n"); return false; } if ((strcmp(argv[z+1],"yes") == 0) || (strcmp(argv[z+1],"y") == 0)) { gc_pParmVol->SetPosUseExtra(true); z++; } else if ((strcmp(argv[z+1],"no") == 0) || (strcmp(argv[z+1],"n") == 0)) { gc_pParmVol->SetPosUseExtra(false); z++; } else gc_pParmVol->SetPosUseExtra(true); gc_pBQBInterface->printf(" -pextra %s\n",gc_pParmVol->GetPosUseExtra()?"yes":"no"); continue; } if (strcmp(argv[z],"-pextrange") == 0) { if (z+1 == argc) { gc_pBQBInterface->eprintf("Error: Missing value after \"-pextrange\".\n"); return false; } z++; ti = atoi(argv[z]); if ((ti < 1) || (ti > 15)) { gc_pBQBInterface->eprintf("Error: Invalid value for \"-pextrange\": \"%s\".\n",argv[z]); gc_pBQBInterface->printf(" Allowed values are 1 .. 15.\n"); return false; } gc_pParmVol->SetPosExtraTRange(ti); gc_pBQBInterface->printf(" -pextrange %d\n",gc_pParmVol->GetPosExtraTRange()); continue; } if (strcmp(argv[z],"-pextorder") == 0) { if (z+1 == argc) { gc_pBQBInterface->eprintf("Error: Missing value after \"-pextorder\".\n"); return false; } z++; ti = atoi(argv[z]); if ((ti < 0) || (ti > 15)) { gc_pBQBInterface->eprintf("Error: Invalid value for \"-pextorder\": \"%s\".\n",argv[z]); gc_pBQBInterface->printf(" Allowed values are 0 .. 15.\n"); return false; } gc_pParmVol->SetPosExtraTOrder(ti); gc_pBQBInterface->printf(" -pextorder %d\n",gc_pParmVol->GetPosExtraTOrder()); continue; } if (strcmp(argv[z],"-pextimeexpo") == 0) { if (z+1 == argc) { gc_pBQBInterface->eprintf("Error: Missing value after \"-pextimeexpo\".\n"); return false; } z++; tf = atof(argv[z]); if ((tf < 0.0) || (tf > 16.0)) { gc_pBQBInterface->eprintf("Error: Invalid value for \"-pextimeexpo\": \"%s\".\n",argv[z]); gc_pBQBInterface->printf(" Allowed values are 0.0 .. 16.0\n"); return false; } gc_pParmVol->SetPosExtraTimeExpo(tf); gc_pBQBInterface->printf(" -pextimeexpo %.3f\n",gc_pParmVol->GetPosExtraTimeExpo()); continue; } if (strcmp(argv[z],"-pprec") == 0) { if (z+1 == argc) { gc_pBQBInterface->eprintf("Error: Missing value after \"-pprec\".\n"); return false; } z++; ti = atoi(argv[z]); if ((ti < 0) || (ti > 7)) { gc_pBQBInterface->eprintf("Error: Invalid value for \"-pprec\": \"%s\".\n",argv[z]); gc_pBQBInterface->printf(" Allowed values are 0 .. 7.\n"); return false; } gc_pParmVol->SetPosPrecision(ti); gc_pBQBInterface->printf(" -pprec %d\n",gc_pParmVol->GetPosPrecision()); continue; } if (strcmp(argv[z],"-porder") == 0) { if (z+1 == argc) { gc_pBQBInterface->eprintf("Error: Missing value after \"-porder\".\n"); return false; } z++; ti = atoi(argv[z]); if ((ti < 0) || (ti > 15)) { gc_pBQBInterface->eprintf("Error: Invalid value for \"-porder\": \"%s\".\n",argv[z]); gc_pBQBInterface->printf(" Allowed values are 0 .. 15.\n"); return false; } gc_pParmVol->SetPosOrder(ti); gc_pBQBInterface->printf(" -porder %d\n",gc_pParmVol->GetPosOrder()); continue; } if (strcmp(argv[z],"-poptorder") == 0) { if (z+1 == argc) { gc_pBQBInterface->eprintf("Error: Missing value after \"-poptorder\".\n"); return false; } if ((strcmp(argv[z+1],"yes") == 0) || (strcmp(argv[z+1],"y") == 0)) { gc_pParmVol->SetPosOptOrder(true); z++; } else if ((strcmp(argv[z+1],"no") == 0) || (strcmp(argv[z+1],"n") == 0)) { gc_pParmVol->SetPosOptOrder(false); z++; } else gc_pParmVol->SetPosOptOrder(true); gc_pBQBInterface->printf(" -poptorder %s\n",gc_pParmVol->GetPosOptOrder()?"yes":"no"); continue; } if (strcmp(argv[z],"-psplit") == 0) { if (z+1 == argc) { gc_pBQBInterface->eprintf("Error: Missing value after \"-psplit\".\n"); return false; } z++; ti = atoi(argv[z]); if ((ti < 1) || (ti > 31)) { gc_pBQBInterface->eprintf("Error: Invalid value for \"-psplit\": \"%s\".\n",argv[z]); gc_pBQBInterface->printf(" Allowed values are 1 .. 31.\n"); return false; } gc_pParmVol->SetPosSplit(ti); gc_pBQBInterface->printf(" -psplit %d\n",gc_pParmVol->GetPosSplit()); continue; } if (strcmp(argv[z],"-ptables") == 0) { if (z+1 == argc) { gc_pBQBInterface->eprintf("Error: Missing value after \"-ptables\".\n"); return false; } z++; ti = atoi(argv[z]); if ((ti < 1) || (ti > 64)) { gc_pBQBInterface->eprintf("Error: Invalid value for \"-ptables\": \"%s\".\n",argv[z]); gc_pBQBInterface->printf(" Allowed values are 1 .. 64.\n"); return false; } gc_pParmVol->SetPosTableCount(ti); gc_pBQBInterface->printf(" -ptables %d\n",gc_pParmVol->GetPosTableCount()); continue; } if (strcmp(argv[z],"-popttables") == 0) { if (z+1 == argc) { gc_pBQBInterface->eprintf("Error: Missing value after \"-popttables\".\n"); return false; } if ((strcmp(argv[z+1],"yes") == 0) || (strcmp(argv[z+1],"y") == 0)) { gc_pParmVol->SetPosOptTables(true); z++; } else if ((strcmp(argv[z+1],"no") == 0) || (strcmp(argv[z+1],"n") == 0)) { gc_pParmVol->SetPosOptTables(false); z++; } else gc_pParmVol->SetPosOptTables(true); gc_pBQBInterface->printf(" -popttables %s\n",gc_pParmVol->GetPosOptTables()?"yes":"no"); continue; } if (strcmp(argv[z],"-pblock") == 0) { if (z+1 == argc) { gc_pBQBInterface->eprintf("Error: Missing value after \"-pblock\".\n"); return false; } z++; ti = atoi(argv[z]); if ((ti < 1) || (ti > 128)) { gc_pBQBInterface->eprintf("Error: Invalid value for \"-pblock\": \"%s\".\n",argv[z]); gc_pBQBInterface->printf(" Allowed values are 1 .. 128.\n"); return false; } gc_pParmVol->SetPosBlockLength(ti); gc_pBQBInterface->printf(" -pblock %d\n",gc_pParmVol->GetPosBlockLength()); continue; } if (strcmp(argv[z],"-pbw") == 0) { if (z+1 == argc) { gc_pBQBInterface->eprintf("Error: Missing value after \"-pbw\".\n"); return false; } if ((strcmp(argv[z+1],"yes") == 0) || (strcmp(argv[z+1],"y") == 0)) { gc_pParmVol->SetPosBW(true); z++; } else if ((strcmp(argv[z+1],"no") == 0) || (strcmp(argv[z+1],"n") == 0)) { gc_pParmVol->SetPosBW(false); z++; } else gc_pParmVol->SetPosBW(true); gc_pBQBInterface->printf(" -pbw %s\n",gc_pParmVol->GetPosBW()?"yes":"no"); continue; } if (strcmp(argv[z],"-pmtf") == 0) { if (z+1 == argc) { gc_pBQBInterface->eprintf("Error: Missing value after \"-pmtf\".\n"); return false; } if ((strcmp(argv[z+1],"yes") == 0) || (strcmp(argv[z+1],"y") == 0)) { gc_pParmVol->SetPosMTF(true); z++; } else if ((strcmp(argv[z+1],"no") == 0) || (strcmp(argv[z+1],"n") == 0)) { gc_pParmVol->SetPosMTF(false); z++; } else gc_pParmVol->SetPosMTF(true); gc_pBQBInterface->printf(" -pmtf %s\n",gc_pParmVol->GetPosMTF()?"yes":"no"); continue; } if (strcmp(argv[z],"-prle") == 0) { if (z+1 == argc) { gc_pBQBInterface->eprintf("Error: Missing value after \"-prle\".\n"); return false; } if ((strcmp(argv[z+1],"yes") == 0) || (strcmp(argv[z+1],"y") == 0)) { gc_pParmVol->SetPosRLE(true); z++; } else if ((strcmp(argv[z+1],"no") == 0) || (strcmp(argv[z+1],"n") == 0)) { gc_pParmVol->SetPosRLE(false); z++; } else gc_pParmVol->SetPosRLE(true); gc_pBQBInterface->printf(" -prle %s\n",gc_pParmVol->GetPosRLE()?"yes":"no"); continue; } if (strcmp(argv[z],"-piter") == 0) { if (z+1 == argc) { gc_pBQBInterface->eprintf("Error: Missing value after \"-piter\".\n"); return false; } z++; ti = atoi(argv[z]); if ((ti < 0) || (ti > 126)) { gc_pBQBInterface->eprintf("Error: Invalid value for \"-piter\": \"%s\".\n",argv[z]); gc_pBQBInterface->printf(" Allowed values are 0 .. 126.\n"); return false; } gc_pParmVol->SetPosMaxIter(ti); gc_pBQBInterface->printf(" -piter %d\n",gc_pParmVol->GetPosMaxIter()); continue; } if (strcmp(argv[z],"-psortatom") == 0) { if (z+1 == argc) { gc_pBQBInterface->eprintf("Error: Missing value after \"-psortatom\".\n"); return false; } if ((strcmp(argv[z+1],"yes") == 0) || (strcmp(argv[z+1],"y") == 0)) { gc_pParmVol->SetPosSortAtom(true); z++; } else if ((strcmp(argv[z+1],"no") == 0) || (strcmp(argv[z+1],"n") == 0)) { gc_pParmVol->SetPosSortAtom(false); z++; } else gc_pParmVol->SetPosSortAtom(true); gc_pBQBInterface->printf(" -psortatom %s\n",gc_pParmVol->GetPosSortAtom()?"yes":"no"); continue; } if (strcmp(argv[z],"-pmaxchunk") == 0) { if (z+1 == argc) { gc_pBQBInterface->eprintf("Error: Missing value after \"-pmaxchunk\".\n"); return false; } z++; ti = atoi(argv[z]); if ((ti < 0) || (ti > 16777216)) { gc_pBQBInterface->eprintf("Error: Invalid value for \"-pmaxchunk\": \"%s\".\n",argv[z]); gc_pBQBInterface->printf(" Allowed values are 0 .. 16777216.\n"); return false; } gc_pParmVol->SetPosMaxChunk(ti); gc_pBQBInterface->printf(" -pmaxchunk %d\n",gc_pParmVol->GetPosMaxChunk()); continue; } gc_pBQBInterface->eprintf("Error: Unknown command line argument \"%s\".\n",argv[z]); return false; } else { b = false; if (i == 0) { gc_sInFile = argv[z]; gc_pBQBInterface->printf(" infile %s\n",gc_sInFile); } else if (i == 1) { gc_sOutFile = argv[z]; gc_pBQBInterface->printf(" outfile %s\n",gc_sOutFile); } else { gc_pBQBInterface->eprintf("Error: Unrecognized trailing argument: \"%s\".\n",argv[z]); return false; } i++; } } // END IF CUBE if (gc_bXYZ) { if ((argv[z][0] == '-') && b) { if (strcmp(argv[z],"-dryrun") == 0) { if (z+1 != argc) { if ((strcmp(argv[z+1],"yes") == 0) || (strcmp(argv[z+1],"y") == 0)) { gc_bDryRun = true; z++; } else if ((strcmp(argv[z+1],"no") == 0) || (strcmp(argv[z+1],"n") == 0)) { gc_bDryRun = false; z++; } else gc_bDryRun = true; } else gc_bDryRun = true; gc_pBQBInterface->printf(" -dryrun %s\n",gc_bDryRun?"yes":"no"); continue; } if (strcmp(argv[z],"-pkey") == 0) { if (z+1 == argc) { gc_pBQBInterface->eprintf("Error: Missing value after \"-pkey\".\n"); return false; } z++; if (!gc_pParmPos->FromKey(argv[z])) { gc_pBQBInterface->eprintf("Error: Invalid value for \"-pkey\": \"%s\".\n",argv[z]); return false; } gc_pBQBInterface->printf(" -pkey %s\n",argv[z]); gc_iAtomOptimize = 0; continue; } if (strcmp(argv[z],"-start") == 0) { if (z+1 == argc) { gc_pBQBInterface->eprintf("Error: Missing value after \"-start\".\n"); return false; } z++; gc_iAtomStart = atoi(argv[z]); if (gc_iAtomStart < 1) { gc_pBQBInterface->eprintf("Error: Invalid value for \"-start\": \"%s\".\n",argv[z]); gc_pBQBInterface->printf(" Allowed values are > 1.\n"); return false; } gc_iAtomStart -= 1; gc_pBQBInterface->printf(" -start %d\n",gc_iAtomStart+1); continue; } if (strcmp(argv[z],"-steps") == 0) { if (z+1 == argc) { gc_pBQBInterface->eprintf("Error: Missing value after \"-steps\".\n"); return false; } z++; gc_iAtomSteps = atoi(argv[z]); if ((gc_iAtomSteps < -1) || (gc_iAtomSteps == 0)) { gc_pBQBInterface->eprintf("Error: Invalid value for \"-steps\": \"%s\".\n",argv[z]); gc_pBQBInterface->printf(" Allowed values are -1 (=all) or > 0.\n"); return false; } gc_pBQBInterface->printf(" -steps %d\n",gc_iAtomSteps); continue; } if (strcmp(argv[z],"-stride") == 0) { if (z+1 == argc) { gc_pBQBInterface->eprintf("Error: Missing value after \"-stride\".\n"); return false; } z++; gc_iAtomStride = atoi(argv[z]); if (gc_iAtomStride < 1) { gc_pBQBInterface->eprintf("Error: Invalid value for \"-stride\": \"%s\".\n",argv[z]); gc_pBQBInterface->printf(" Allowed values are > 0.\n"); return false; } gc_pBQBInterface->printf(" -stride %d\n",gc_iAtomStride); continue; } if (strcmp(argv[z],"-keyframe") == 0) { if (z+1 == argc) { gc_pBQBInterface->eprintf("Error: Missing value after \"-keyframe\".\n"); return false; } z++; gc_iAtomKey = atoi(argv[z]); if (gc_iAtomKey < 1) { gc_pBQBInterface->eprintf("Error: Invalid value for \"-keyframe\": \"%s\".\n",argv[z]); gc_pBQBInterface->printf(" Allowed values are >= 1.\n"); return false; } gc_pBQBInterface->printf(" -keyframe %d\n",gc_iAtomKey); continue; } if (strcmp(argv[z],"-comment") == 0) { if (z+1 == argc) { gc_pBQBInterface->eprintf("Error: Missing value after \"-comment\".\n"); return false; } if ((strcmp(argv[z+1],"yes") == 0) || (strcmp(argv[z+1],"y") == 0)) { gc_bAtomKeepComment = true; z++; } else if ((strcmp(argv[z+1],"no") == 0) || (strcmp(argv[z+1],"n") == 0)) { gc_bAtomKeepComment = false; z++; } else gc_bAtomKeepComment = true; gc_pBQBInterface->printf(" -comment %s\n",gc_bAtomKeepComment?"yes":"no"); continue; } if (strcmp(argv[z],"-check") == 0) { if (z+1 == argc) { gc_pBQBInterface->eprintf("Error: Missing value after \"-check\".\n"); return false; } if ((strcmp(argv[z+1],"yes") == 0) || (strcmp(argv[z+1],"y") == 0)) { gc_bAtomCompare = true; z++; } else if ((strcmp(argv[z+1],"no") == 0) || (strcmp(argv[z+1],"n") == 0)) { gc_bAtomCompare = false; z++; } else gc_bAtomCompare = true; gc_pBQBInterface->printf(" -check %s\n",gc_bAtomCompare?"yes":"no"); continue; } if (strcmp(argv[z],"-verbose") == 0) { if (z+1 == argc) { gc_pBQBInterface->eprintf("Error: Missing value after \"-verbose\".\n"); return false; } if (strcmp(argv[z+1],"2") == 0) { gc_iAtomVerbose = 2; z++; } else if (strcmp(argv[z+1],"1") == 0) { gc_iAtomVerbose = 1; z++; } else if (strcmp(argv[z+1],"0") == 0) { gc_iAtomVerbose = 0; z++; } else gc_iAtomVerbose = 1; gc_pBQBInterface->printf(" -verbose %d\n",gc_iAtomVerbose); continue; } if (strcmp(argv[z],"-refout") == 0) { if (z+1 == argc) { gc_pBQBInterface->eprintf("Error: Missing value after \"-verbose\".\n"); return false; } z++; gc_sAtomRefOut = argv[z]; gc_pBQBInterface->printf(" -refout %s\n",gc_sAtomRefOut); continue; } if (strcmp(argv[z],"-prec") == 0) { if (z+1 == argc) { gc_pBQBInterface->eprintf("Error: Missing value after \"-prec\".\n"); return false; } z++; ti = atoi(argv[z]); if ((ti < 0) || (ti > 7)) { gc_pBQBInterface->eprintf("Error: Invalid value for \"-prec\": \"%s\".\n",argv[z]); gc_pBQBInterface->printf(" Allowed values are 0 .. 7.\n"); return false; } gc_pParmPos->SetPrecision(ti); gc_pBQBInterface->printf(" -prec %d\n",gc_pParmPos->GetPrecision()); continue; } if (strcmp(argv[z],"-order") == 0) { if (z+1 == argc) { gc_pBQBInterface->eprintf("Error: Missing value after \"-order\".\n"); return false; } z++; ti = atoi(argv[z]); if ((ti < 0) || (ti > 15)) { gc_pBQBInterface->eprintf("Error: Invalid value for \"-order\": \"%s\".\n",argv[z]); gc_pBQBInterface->printf(" Allowed values are 0 .. 15.\n"); return false; } gc_pParmPos->SetOrder(ti); gc_pBQBInterface->printf(" -order %d\n",gc_pParmPos->GetOrder()); continue; } if (strcmp(argv[z],"-optorder") == 0) { if (z+1 == argc) { gc_pBQBInterface->eprintf("Error: Missing value after \"-optorder\".\n"); return false; } if ((strcmp(argv[z+1],"yes") == 0) || (strcmp(argv[z+1],"y") == 0)) { gc_pParmPos->SetOptOrder(true); z++; } else if ((strcmp(argv[z+1],"no") == 0) || (strcmp(argv[z+1],"n") == 0)) { gc_pParmPos->SetOptOrder(false); z++; } else gc_pParmPos->SetOptOrder(true); gc_pBQBInterface->printf(" -optorder %s\n",gc_pParmPos->GetOptOrder()?"yes":"no"); continue; } if (strcmp(argv[z],"-split") == 0) { if (z+1 == argc) { gc_pBQBInterface->eprintf("Error: Missing value after \"-split\".\n"); return false; } z++; ti = atoi(argv[z]); if ((ti < 1) || (ti > 31)) { gc_pBQBInterface->eprintf("Error: Invalid value for \"-split\": \"%s\".\n",argv[z]); gc_pBQBInterface->printf(" Allowed values are 1 .. 31.\n"); return false; } gc_pParmPos->SetSplit(ti); gc_pBQBInterface->printf(" -split %d\n",gc_pParmPos->GetSplit()); continue; } if (strcmp(argv[z],"-tables") == 0) { if (z+1 == argc) { gc_pBQBInterface->eprintf("Error: Missing value after \"-tables\".\n"); return false; } z++; ti = atoi(argv[z]); if ((ti < 1) || (ti > 64)) { gc_pBQBInterface->eprintf("Error: Invalid value for \"-tables\": \"%s\".\n",argv[z]); gc_pBQBInterface->printf(" Allowed values are 1 .. 64.\n"); return false; } gc_pParmPos->SetTableCount(ti); gc_pBQBInterface->printf(" -tables %d\n",gc_pParmPos->GetTableCount()); continue; } if (strcmp(argv[z],"-opttables") == 0) { if (z+1 == argc) { gc_pBQBInterface->eprintf("Error: Missing value after \"-opttables\".\n"); return false; } if ((strcmp(argv[z+1],"yes") == 0) || (strcmp(argv[z+1],"y") == 0)) { gc_pParmPos->SetOptTables(true); z++; } else if ((strcmp(argv[z+1],"no") == 0) || (strcmp(argv[z+1],"n") == 0)) { gc_pParmPos->SetOptTables(false); z++; } else gc_pParmPos->SetOptTables(true); gc_pBQBInterface->printf(" -opttables %s\n",gc_pParmPos->GetOptTables()?"yes":"no"); continue; } if (strcmp(argv[z],"-block") == 0) { if (z+1 == argc) { gc_pBQBInterface->eprintf("Error: Missing value after \"-block\".\n"); return false; } z++; ti = atoi(argv[z]); if ((ti < 1) || (ti > 128)) { gc_pBQBInterface->eprintf("Error: Invalid value for \"-block\": \"%s\".\n",argv[z]); gc_pBQBInterface->printf(" Allowed values are 1 .. 128.\n"); return false; } gc_pParmPos->SetBlockLength(ti); gc_pBQBInterface->printf(" -block %d\n",gc_pParmPos->GetBlockLength()); continue; } if (strcmp(argv[z],"-bw") == 0) { if (z+1 == argc) { gc_pBQBInterface->eprintf("Error: Missing value after \"-bw\".\n"); return false; } if ((strcmp(argv[z+1],"yes") == 0) || (strcmp(argv[z+1],"y") == 0)) { gc_pParmPos->SetBW(true); z++; } else if ((strcmp(argv[z+1],"no") == 0) || (strcmp(argv[z+1],"n") == 0)) { gc_pParmPos->SetBW(false); z++; } else gc_pParmPos->SetBW(true); gc_pBQBInterface->printf(" -bw %s\n",gc_pParmPos->GetBW()?"yes":"no"); continue; } if (strcmp(argv[z],"-mtf") == 0) { if (z+1 == argc) { gc_pBQBInterface->eprintf("Error: Missing value after \"-mtf\".\n"); return false; } if ((strcmp(argv[z+1],"yes") == 0) || (strcmp(argv[z+1],"y") == 0)) { gc_pParmPos->SetMTF(true); z++; } else if ((strcmp(argv[z+1],"no") == 0) || (strcmp(argv[z+1],"n") == 0)) { gc_pParmPos->SetMTF(false); z++; } else gc_pParmPos->SetMTF(true); gc_pBQBInterface->printf(" -mtf %s\n",gc_pParmPos->GetMTF()?"yes":"no"); continue; } if (strcmp(argv[z],"-rle") == 0) { if (z+1 == argc) { gc_pBQBInterface->eprintf("Error: Missing value after \"-rle\".\n"); return false; } if ((strcmp(argv[z+1],"yes") == 0) || (strcmp(argv[z+1],"y") == 0)) { gc_pParmPos->SetRLE(true); z++; } else if ((strcmp(argv[z+1],"no") == 0) || (strcmp(argv[z+1],"n") == 0)) { gc_pParmPos->SetRLE(false); z++; } else gc_pParmPos->SetRLE(true); gc_pBQBInterface->printf(" -rle %s\n",gc_pParmPos->GetRLE()?"yes":"no"); continue; } if (strcmp(argv[z],"-iter") == 0) { if (z+1 == argc) { gc_pBQBInterface->eprintf("Error: Missing value after \"-iter\".\n"); return false; } z++; ti = atoi(argv[z]); if ((ti < 0) || (ti > 126)) { gc_pBQBInterface->eprintf("Error: Invalid value for \"-iter\": \"%s\".\n",argv[z]); gc_pBQBInterface->printf(" Allowed values are 0 .. 126.\n"); return false; } gc_pParmPos->SetMaxIter(ti); gc_pBQBInterface->printf(" -iter %d\n",gc_pParmPos->GetMaxIter()); continue; } if (strcmp(argv[z],"-sortatom") == 0) { if (z+1 == argc) { gc_pBQBInterface->eprintf("Error: Missing value after \"-sortatom\".\n"); return false; } if ((strcmp(argv[z+1],"yes") == 0) || (strcmp(argv[z+1],"y") == 0)) { gc_pParmPos->SetSortAtom(true); z++; } else if ((strcmp(argv[z+1],"no") == 0) || (strcmp(argv[z+1],"n") == 0)) { gc_pParmPos->SetSortAtom(false); z++; } else gc_pParmPos->SetSortAtom(true); gc_pBQBInterface->printf(" -sortatom %s\n",gc_pParmPos->GetSortAtom()?"yes":"no"); continue; } if (strcmp(argv[z],"-maxchunk") == 0) { if (z+1 == argc) { gc_pBQBInterface->eprintf("Error: Missing value after \"-maxchunk\".\n"); return false; } z++; ti = atoi(argv[z]); if ((ti < 0) || (ti > 16777216)) { gc_pBQBInterface->eprintf("Error: Invalid value for \"-maxchunk\": \"%s\".\n",argv[z]); gc_pBQBInterface->printf(" Allowed values are 0 .. 16777216.\n"); return false; } gc_pParmPos->SetMaxChunk(ti); gc_pBQBInterface->printf(" -maxchunk %d\n",gc_pParmPos->GetMaxChunk()); continue; } if (strcmp(argv[z],"-extra") == 0) { if (z+1 == argc) { gc_pBQBInterface->eprintf("Error: Missing value after \"-extra\".\n"); return false; } if ((strcmp(argv[z+1],"yes") == 0) || (strcmp(argv[z+1],"y") == 0)) { gc_pParmPos->SetUseExtra(true); z++; } else if ((strcmp(argv[z+1],"no") == 0) || (strcmp(argv[z+1],"n") == 0)) { gc_pParmPos->SetUseExtra(false); z++; } else gc_pParmPos->SetUseExtra(true); gc_pBQBInterface->printf(" -extra %s\n",gc_pParmPos->GetUseExtra()?"yes":"no"); continue; } if (strcmp(argv[z],"-extrange") == 0) { if (z+1 == argc) { gc_pBQBInterface->eprintf("Error: Missing value after \"-extrange\".\n"); return false; } z++; ti = atoi(argv[z]); if ((ti < 1) || (ti > 15)) { gc_pBQBInterface->eprintf("Error: Invalid value for \"-extrange\": \"%s\".\n",argv[z]); gc_pBQBInterface->printf(" Allowed values are 1 .. 15.\n"); return false; } gc_pParmPos->SetExtraTRange(ti); gc_pBQBInterface->printf(" -extrange %d\n",gc_pParmPos->GetExtraTRange()); continue; } if (strcmp(argv[z],"-extorder") == 0) { if (z+1 == argc) { gc_pBQBInterface->eprintf("Error: Missing value after \"-extorder\".\n"); return false; } z++; ti = atoi(argv[z]); if ((ti < 0) || (ti > 15)) { gc_pBQBInterface->eprintf("Error: Invalid value for \"-extorder\": \"%s\".\n",argv[z]); gc_pBQBInterface->printf(" Allowed values are 0 .. 15.\n"); return false; } gc_pParmPos->SetExtraTOrder(ti); gc_pBQBInterface->printf(" -extorder %d\n",gc_pParmPos->GetExtraTOrder()); continue; } if (strcmp(argv[z],"-extimeexpo") == 0) { if (z+1 == argc) { gc_pBQBInterface->eprintf("Error: Missing value after \"-extimeexpo\".\n"); return false; } z++; tf = atof(argv[z]); if ((tf < 0) || (tf > 16.0)) { gc_pBQBInterface->eprintf("Error: Invalid value for \"-extimeexpo\": \"%s\".\n",argv[z]); gc_pBQBInterface->printf(" Allowed values are 0.0 .. 16.0\n"); return false; } gc_pParmPos->SetExtraTimeExpo(tf); gc_pBQBInterface->printf(" -extimeexpo %.3f\n",gc_pParmPos->GetExtraTimeExpo()); continue; } if (strcmp(argv[z],"-optimize") == 0) { if (z+1 == argc) { gc_pBQBInterface->eprintf("Error: Missing value after \"-optimize\".\n"); return false; } if ((strcmp(argv[z+1],"0") == 0) || (strcmp(argv[z+1],"1") == 0) || (strcmp(argv[z+1],"2") == 0) || (strcmp(argv[z+1],"3") == 0) || (strcmp(argv[z+1],"4") == 0)) { gc_iAtomOptimize = atoi(argv[z+1]); z++; } else if (bqbisinteger(argv[z+1])) { gc_pBQBInterface->eprintf("Error: Invalid value \"%s\" after \"-optimize\". Allowed range is 0 to 3.\n", argv[z+1]); return false; } else gc_iAtomOptimize = 3; if ((gc_iAtomOptimize < 0) || (gc_iAtomOptimize > 4)) { gc_pBQBInterface->eprintf("Error: Invalid value for \"-optimize\": \"%s\".\n",argv[z]); gc_pBQBInterface->printf(" Allowed values are 0 .. 4.\n"); return false; } gc_pBQBInterface->printf(" -optimize %d\n",gc_iAtomOptimize); gc_bOptTouched = true; continue; } if (strcmp(argv[z],"-optsteps") == 0) { if (z+1 == argc) { gc_pBQBInterface->eprintf("Error: Missing value after \"-optsteps\".\n"); return false; } z++; gc_iAtomOptSteps = atoi(argv[z]); if (gc_iAtomOptSteps < 1) { gc_pBQBInterface->eprintf("Error: Invalid value for \"-optsteps\": \"%s\".\n",argv[z]); gc_pBQBInterface->printf(" Allowed values are > 0.\n"); return false; } gc_pBQBInterface->printf(" -optsteps %d\n",gc_iAtomOptSteps); continue; } if (strcmp(argv[z],"-onlyopt") == 0) { if (z+1 == argc) { gc_pBQBInterface->eprintf("Error: Missing value after \"-onlyopt\".\n"); return false; } if ((strcmp(argv[z+1],"yes") == 0) || (strcmp(argv[z+1],"y") == 0)) { gc_bAtomOnlyOpt = true; z++; } else if ((strcmp(argv[z+1],"no") == 0) || (strcmp(argv[z+1],"n") == 0)) { gc_bAtomOnlyOpt = false; z++; } else gc_bAtomOnlyOpt = true; gc_pBQBInterface->printf(" -onlyopt %s\n",gc_bAtomOnlyOpt?"yes":"no"); continue; } if (strcmp(argv[z],"-optstart") == 0) { if (z+1 == argc) { gc_pBQBInterface->eprintf("Error: Missing value after \"-optstart\".\n"); return false; } if ((strcmp(argv[z+1],"yes") == 0) || (strcmp(argv[z+1],"y") == 0)) { gc_iAtomOptIncludeFirst = 1; z++; } else if ((strcmp(argv[z+1],"no") == 0) || (strcmp(argv[z+1],"n") == 0)) { gc_iAtomOptIncludeFirst = 0; z++; } else gc_iAtomOptIncludeFirst = 1; gc_pBQBInterface->printf(" -optstart %s\n",(gc_iAtomOptIncludeFirst>0)?"yes":"no"); continue; } gc_pBQBInterface->eprintf("Error: Unknown command line argument \"%s\".\n",argv[z]); return false; } else { b = false; if (i == 0) { gc_sInFile = argv[z]; gc_pBQBInterface->printf(" infile %s\n",gc_sInFile); } else if (i == 1) { gc_sOutFile = argv[z]; gc_pBQBInterface->printf(" outfile %s\n",gc_sOutFile); } else { gc_pBQBInterface->eprintf("Error: Unrecognized trailing argument: \"%s\".\n",argv[z]); return false; } i++; } } // END IF XYZ } // END IF COMPRESS if (gc_bDecompress) { if (gc_bFile) { if ((argv[z][0] == '-') && b) { if (strcmp(argv[z],"-verbose") == 0) { if (z+1 == argc) { gc_pBQBInterface->eprintf("Error: Missing value after \"-verbose\".\n"); return false; } if (strcmp(argv[z+1],"2") == 0) { gc_iFileVerbose = 2; z++; } else if (strcmp(argv[z+1],"1") == 0) { gc_iFileVerbose = 1; z++; } else if (strcmp(argv[z+1],"0") == 0) { gc_iFileVerbose = 0; z++; } else gc_iFileVerbose = 1; gc_pBQBInterface->printf(" -verbose %d\n",gc_iFileVerbose); continue; } if (strcmp(argv[z],"-refcompare") == 0) { if (z+1 == argc) { gc_pBQBInterface->eprintf("Error: Missing value after \"-refcompare\".\n"); return false; } z++; gc_sRefFile = argv[z]; gc_pBQBInterface->printf(" -refcompare %s\n",gc_sRefFile); continue; } gc_pBQBInterface->eprintf("Error: Unknown command line argument \"%s\".\n",argv[z]); return false; } else { b = false; if (i == 0) { gc_sInFile = argv[z]; gc_pBQBInterface->printf(" infile %s\n",gc_sInFile); } else if (i == 1) { gc_sOutFile = argv[z]; gc_pBQBInterface->printf(" outfile %s\n",gc_sOutFile); } else { gc_pBQBInterface->eprintf("Error: Unrecognized trailing argument: \"%s\".\n",argv[z]); return false; } i++; } } // END IF FILE if (gc_bCube) { if ((argv[z][0] == '-') && b) { if (strcmp(argv[z],"-steps") == 0) { if (z+1 == argc) { gc_pBQBInterface->eprintf("Error: Missing value after \"-steps\".\n"); return false; } z++; gc_iCubeSteps = atoi(argv[z]); if ((gc_iCubeSteps < -1) || (gc_iCubeSteps == 0)) { gc_pBQBInterface->eprintf("Error: Invalid value for \"-steps\": \"%s\".\n",argv[z]); gc_pBQBInterface->printf(" Allowed values are -1 (=all) or > 0.\n"); return false; } gc_pBQBInterface->printf(" -steps %d\n",gc_iCubeSteps); continue; } if (strcmp(argv[z],"-stride") == 0) { if (z+1 == argc) { gc_pBQBInterface->eprintf("Error: Missing value after \"-stride\".\n"); return false; } z++; gc_iCubeStride = atoi(argv[z]); if (gc_iCubeStride < 1) { gc_pBQBInterface->eprintf("Error: Invalid value for \"-stride\": \"%s\".\n",argv[z]); gc_pBQBInterface->printf(" Allowed values are > 0.\n"); return false; } gc_pBQBInterface->printf(" -stride %d\n",gc_iCubeStride); continue; } if (strcmp(argv[z],"-verbose") == 0) { if (z+1 == argc) { gc_pBQBInterface->eprintf("Error: Missing value after \"-verbose\".\n"); return false; } if (strcmp(argv[z+1],"2") == 0) { gc_iCubeVerbose = 2; z++; } else if (strcmp(argv[z+1],"1") == 0) { gc_iCubeVerbose = 1; z++; } else if (strcmp(argv[z+1],"0") == 0) { gc_iCubeVerbose = 0; z++; } else gc_iCubeVerbose = 1; gc_pBQBInterface->printf(" -verbose %d\n",gc_iCubeVerbose); continue; } if (strcmp(argv[z],"-refcompare") == 0) { if (z+1 == argc) { gc_pBQBInterface->eprintf("Error: Missing value after \"-refcompare\".\n"); return false; } z++; gc_sRefFile = argv[z]; gc_pBQBInterface->printf(" -refcompare %s\n",gc_sRefFile); continue; } gc_pBQBInterface->eprintf("Error: Unknown command line argument \"%s\".\n",argv[z]); return false; } else { b = false; if (i == 0) { gc_sInFile = argv[z]; gc_pBQBInterface->printf(" infile %s\n",gc_sInFile); } else if (i == 1) { gc_sOutFile = argv[z]; gc_pBQBInterface->printf(" outfile %s\n",gc_sOutFile); } else { gc_pBQBInterface->eprintf("Error: Unrecognized trailing argument: \"%s\".\n",argv[z]); return false; } i++; } } // END IF CUBE if (gc_bXYZ) { if ((argv[z][0] == '-') && b) { if (strcmp(argv[z],"-steps") == 0) { if (z+1 == argc) { gc_pBQBInterface->eprintf("Error: Missing value after \"-steps\".\n"); return false; } z++; gc_iAtomSteps = atoi(argv[z]); if ((gc_iAtomSteps < -1) || (gc_iAtomSteps == 0)) { gc_pBQBInterface->eprintf("Error: Invalid value for \"-steps\": \"%s\".\n",argv[z]); gc_pBQBInterface->printf(" Allowed values are -1 (=all) or > 0.\n"); return false; } gc_pBQBInterface->printf(" -steps %d\n",gc_iAtomSteps); continue; } if (strcmp(argv[z],"-stride") == 0) { if (z+1 == argc) { gc_pBQBInterface->eprintf("Error: Missing value after \"-stride\".\n"); return false; } z++; gc_iAtomStride = atoi(argv[z]); if (gc_iAtomStride < 1) { gc_pBQBInterface->eprintf("Error: Invalid value for \"-stride\": \"%s\".\n",argv[z]); gc_pBQBInterface->printf(" Allowed values are > 0.\n"); return false; } gc_pBQBInterface->printf(" -stride %d\n",gc_iAtomStride); continue; } if (strcmp(argv[z],"-verbose") == 0) { if (z+1 == argc) { gc_pBQBInterface->eprintf("Error: Missing value after \"-verbose\".\n"); return false; } if (strcmp(argv[z+1],"2") == 0) { gc_iAtomVerbose = 2; z++; } else if (strcmp(argv[z+1],"1") == 0) { gc_iAtomVerbose = 1; z++; } else if (strcmp(argv[z+1],"0") == 0) { gc_iAtomVerbose = 0; z++; } else gc_iAtomVerbose = 1; gc_pBQBInterface->printf(" -verbose %d\n",gc_iAtomVerbose); continue; } if (strcmp(argv[z],"-refcompare") == 0) { if (z+1 == argc) { gc_pBQBInterface->eprintf("Error: Missing value after \"-refcompare\".\n"); return false; } z++; gc_sRefFile = argv[z]; gc_pBQBInterface->printf(" -refcompare %s\n",gc_sRefFile); continue; } gc_pBQBInterface->eprintf("Error: Unknown command line argument \"%s\".\n",argv[z]); return false; } else { b = false; if (i == 0) { gc_sInFile = argv[z]; gc_pBQBInterface->printf(" infile %s\n",gc_sInFile); } else if (i == 1) { gc_sOutFile = argv[z]; gc_pBQBInterface->printf(" outfile %s\n",gc_sOutFile); } else { gc_pBQBInterface->eprintf("Error: Unrecognized trailing argument: \"%s\".\n",argv[z]); return false; } i++; } } // END IF XYZ } // END IF DECOMPRESS } } gc_pBQBInterface->printf("Finished.\n\n"); return true; } static const char BQB_BASE64_table[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; bool bqb_isbase64(char c) { return c && strchr(BQB_BASE64_table, c) != NULL; } inline char BQB_BASE64_value(char c) { const char *p = strchr(BQB_BASE64_table, c); if(p) { return (char)(p-BQB_BASE64_table); } else { return 0; } } int BQB_UnBase64(unsigned char *dest, const unsigned char *src, int srclen) { *dest = 0; if(*src == 0) { return 0; } unsigned char *p = dest; do { char a = BQB_BASE64_value(src[0]); char b = BQB_BASE64_value(src[1]); char c = BQB_BASE64_value(src[2]); char d = BQB_BASE64_value(src[3]); *p++ = (a << 2) | (b >> 4); *p++ = (b << 4) | (c >> 2); *p++ = (c << 6) | d; if(!bqb_isbase64(src[1])) { p -= 2; break; } else if(!bqb_isbase64(src[2])) { p -= 2; break; } else if(!bqb_isbase64(src[3])) { p--; break; } src += 4; while(*src && (*src == 13 || *src == 10)) src++; } while(srclen-= 4); *p = 0; return (int)(p-dest); } void BQB_PrintBMode() { const char *stext[15]; char buf[256]; int z; stext[0] = "ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIF8sIC4u"; stext[1] = "ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdfKF8wbylvKCku"; stext[2] = "ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAsbyhfXyksXyksKF9fKW8="; stext[3] = "ICAgICAgICAgXy4oLSkuXyAgICAgICAgICAgICAgICAgICAgbyhfLC1vKF8gKSgoXylvTylf"; stext[4] = "ICAgICAgLicgICAgICAgICAnLiAgICAgICAgICAgICAgICAgLk8oX18pbyxfXylvKF8pT29fKQ=="; stext[5] = "ICAgICAvICAgICAgICAgICAgIFwgICAgICAgICAgICAuLS0tLXwgICB8ICAgfCAgIHxfKTA="; stext[6] = "ICAgICB8Jy0uLi5fX18uLi4tJ3wgICAgICAgICAgIC8gIC4tLXwgICB8ICAgfCAgIHwsXyk="; stext[7] = "ICAgICAgXCAgICAnPScgICAgLyAgICAgICAgICAgfCAgLyAgIHwgICB8ICAgfCAgIHxvKF8p"; stext[8] = "ICAgICAgIGAnLl9fX19fLidgICAgICAgICAgICAgfCAgfCAgIHwgICB8ICAgfCAgIHxfL2Ap"; stext[9] = "ICAgICAgICAvICAgfCAgIFwgICAgICAgICAgICAgfCAgfCAgIHwgICB8ICAgfCAgIHxPXyk="; stext[10] = "ICAgICAgIC8uLS0nfCctLS5cICAgICAgICAgICAgfCAgXCAgIHwgICB8ICAgfCAgIHw="; stext[11] = "ICAgIFtdLyctLl9ffF9fLi0nXFtdICAgICAgICAgIFwgICctLXwgICB8ICAgfCAgIHw="; stext[12] = "ICAgICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAnLS0tLXwgICB8ICAgfCAgIHw="; stext[13] = "ICAgICAgICAgICBbXSAgICAgICAgICAgICAgICAgICAgICAgIFwgICBcICAgLyAgIC8="; stext[14] = "ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBgIiIiIiIiIiIiYA=="; //gc_pBQBInterface->printf("\n"); for (z=0;z<15;z++) { BQB_UnBase64((unsigned char*)buf,(const unsigned char*)stext[z],(int)strlen(stext[z])); gc_pBQBInterface->bprintf(" %s\n",buf); } gc_pBQBInterface->printf("\n"); } // Functions for Linux signal handling / stack trace #ifndef BQB_INSIDE_TRAVIS void bqb_printf(const char *s, ...) { va_list args; va_start(args,s); vprintf(s,args); va_end(args); if (gc_fLogFile != NULL) { va_start(args,s); vfprintf(gc_fLogFile,s,args); va_end(args); fflush(gc_fLogFile); } } #if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) void UninstallSignalHandler() { signal(SIGSEGV,SIG_DFL); signal(SIGFPE,SIG_DFL); signal(SIGILL,SIG_DFL); signal(SIGINT,SIG_DFL); signal(SIGABRT,SIG_DFL); signal(SIGTERM,SIG_DFL); signal(SIGHUP,SIG_DFL); } void DumpLinuxBacktrace() { void *buffer[4096]; char **strings, buf[256], *p; int n, z, i, j; bool showall; FILE *a; n = backtrace(buffer,4096); if (n <= 0) { bqb_printf("DumpLinuxBacktrace(): Error: Could not retrieve stack trace.\n"); return; } strings = backtrace_symbols(buffer,n); if (strings == NULL) bqb_printf("Could not retrieve debug symbol strings.\n"); bqb_printf("Decoding line numbers... "); bqb_printf("(\"addr2line -f -i -C -e %s\")\n",gc_sExeName); a = fopen(gc_sExeName,"rb"); if (a == NULL) { bqb_printf("Could not locate \"%s\" :-(\n",gc_sExeName); } else { fclose(a); j = 0; for (z=0;z (void*)0x400000)) j++; if (j < 3) showall = true; else showall = false; for (z=0;z (void*)0x400000))) { bqb_printf(" # %2d ",n-z); sprintf(buf,"addr2line %p -f -i -C -e %s > tmp.txt",buffer[z],gc_sExeName); (void)system(buf); a = fopen("tmp.txt","rt"); if (a == NULL) { bqb_printf("Error. Make sure you have the addr2line tool installed (it is part of \"binutils\")\nand writing permission to this directory.\n"); continue; } bqb_printf("- [%10p] ",buffer[z]); i = 0; while (true) { (void)fgets(buf,256,a); if (feof(a)) break; if (strlen(buf) > 2) { if (i == 2) { i = 0; bqb_printf("\n "); } buf[strlen(buf)-1] = 0; p = strrchr(buf,'/'); if (p == NULL) p = buf; else p++; bqb_printf("- %s ",p); i++; } } fclose(a); bqb_printf("\n"); } } (void)system("rm tmp.txt"); } } void Crash() { UninstallSignalHandler(); bqb_printf("bqbtool apparently has crashed :-( Sorry.\n"); bqb_printf("Please send the screen output to the developers,\n"); bqb_printf("making them able to analyze and fix this error.\n"); DumpLinuxBacktrace(); bqb_printf("Delivering control to operating system.\n"); abort(); } void CrashAbort() { UninstallSignalHandler(); bqb_printf("bqbtool had to abort execution.\n"); bqb_printf("Hopefully, the reason was printed above this message.\n"); DumpLinuxBacktrace(); bqb_printf("Delivering control to operating system.\n"); abort(); } void CrashTerm() { UninstallSignalHandler(); bqb_printf("bqbtool received a termination request (SIGTERM) from the operating system\n"); bqb_printf("and therefore has to stop execution.\n"); DumpLinuxBacktrace(); bqb_printf("Delivering control to operating system.\n"); abort(); } void CrashInt() { UninstallSignalHandler(); DumpLinuxBacktrace(); bqb_printf("Delivering control to operating system.\n"); abort(); } void SIGNAL_SEGV(int param) { UNUSED(param); // Suppress "unused parameter" warning bqb_printf("\n\n*** SIGSEGV caught: Segmentation fault ***\n"); Crash(); } void SIGNAL_FPE(int param) { UNUSED(param); // Suppress "unused parameter" warning bqb_printf("\n\n*** SIGFPE caught: Floating point exception ***\n"); Crash(); } void SIGNAL_ILL(int param) { UNUSED(param); // Suppress "unused parameter" warning bqb_printf("\n\n*** SIGILL caught: Illegal instruction ***\n"); Crash(); } void SIGNAL_INT(int param) { UNUSED(param); // Suppress "unused parameter" warning bqb_printf("\n\n*** SIGINT caught: Hard interrupt by user ***\n"); bqb_printf("Stopping execution.\n"); CrashInt(); exit(0); } void SIGNAL_ABRT(int param) { UNUSED(param); // Suppress "unused parameter" warning bqb_printf("\n\n*** SIGABRT caught: Abnormal program termination ***\n"); CrashAbort(); } void SIGNAL_TERM(int param) { UNUSED(param); // Suppress "unused parameter" warning bqb_printf("\n\n*** SIGTERM caught: Terminating ***\n"); CrashTerm(); } void SIGNAL_HANGUP(int param) { UNUSED(param); // Suppress "unused parameter" warning bqb_printf("\n\n*** SIGHUP caught: Trying to ignore hangup ^^ ***\n"); signal(SIGHUP,SIGNAL_HANGUP); } void InstallSignalHandler() { signal(SIGSEGV,SIGNAL_SEGV); signal(SIGFPE,SIGNAL_FPE); signal(SIGILL,SIGNAL_ILL); signal(SIGINT,SIGNAL_INT); signal(SIGABRT,SIGNAL_ABRT); signal(SIGTERM,SIGNAL_TERM); signal(SIGHUP,SIGNAL_HANGUP); } #endif #endif #ifdef BQB_INSIDE_TRAVIS int bqbtool_main(int argc, const char *argv[]) { #else int main(int argc, const char *argv[]) { #endif CBQBDriver *driver = NULL; int z; bool err, b; struct tm *today; time_t ltime; char buf[256]; gc_sExeName = new char[strlen(argv[0])+1]; strcpy(gc_sExeName,argv[0]); // Install Linux signal handlers #ifndef BQB_INSIDE_TRAVIS #if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) InstallSignalHandler(); #endif #endif // Before this command, no printing should occur gc_pBQBInterface = BQBCreateInterface( 0 ); if (gc_pBQBInterface == NULL) { printf("Error: Could not create BQB interface.\n"); printf("Aborting execution.\n\n"); return 1; } // Use TRAVIS functions for screen output #ifdef BQB_INSIDE_TRAVIS gc_pBQBInterface->SetPrintCallback( &mprintf ); gc_pBQBInterface->SetBPrintCallback( &bprintf ); gc_pBQBInterface->SetEPrintCallback( &eprintf ); #else gc_fLogFile = fopen("bqbtool.log","wt"); if (gc_fLogFile == NULL) { printf("Error: Could not open \"bqbtool.log\" for writing.\n"); printf("Aborting execution.\n\n"); return 1; } gc_pBQBInterface->SetPrintCallback( &bqb_printf ); gc_pBQBInterface->SetBPrintCallback( &bqb_printf ); gc_pBQBInterface->SetEPrintCallback( &bqb_printf ); #endif // Get host name and working directory #if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) if (gethostname(buf,256)==0) { gc_sHostName = new char[strlen(buf)+1]; strcpy(gc_sHostName,buf); } else gc_sHostName = NULL; gc_sWorkingDir = getcwd(NULL,1024); #elif defined(_WIN32) unsigned long l; l = 256; if (GetComputerNameA(buf,&l)) { gc_sHostName = new char[strlen(buf)+1]; strcpy(gc_sHostName,buf); } else gc_sHostName = NULL; gc_sWorkingDir = _getcwd(NULL,1024); #else gc_sHostName = NULL; gc_sWorkingDir = NULL; #endif gc_pBQBInterface->bprintf("\n"); gc_pBQBInterface->bprintf(" __ __ __ __\n"); gc_pBQBInterface->bprintf(" / | / | / | / |\n"); gc_pBQBInterface->bprintf(" ## |____ ______ ## |____ _## |_ ______ ______ ## |\n"); gc_pBQBInterface->bprintf(" ## \\ / \\ ## \\ / ## | / \\ / \\ ## |\n"); gc_pBQBInterface->bprintf(" ####### | /###### | ####### | ######/ /###### | /###### | ## |\n"); gc_pBQBInterface->bprintf(" ## | ## | ## | ## | ## | ## | ## | __ ## | ## | ## | ## | ## |\n"); gc_pBQBInterface->bprintf(" ## |__## | ## \\__## | ## |__## | ## |/ | ## \\__## | ## \\__## | ## |\n"); gc_pBQBInterface->bprintf(" ## ##/ ## ## | ## ##/ ## ##/ ## ##/ ## ##/ ## \\\n"); gc_pBQBInterface->bprintf(" #######/ ####### | #######/ ####/ ######/ ######/ ##/\n"); gc_pBQBInterface->bprintf(" ## |\n"); gc_pBQBInterface->bprintf(" ## |\n"); gc_pBQBInterface->bprintf(" ##/\n"); gc_pBQBInterface->printf("\n"); gc_pBQBInterface->printf(" LibBQB - File Format and Compression Algorithms for Trajectories of\n"); gc_pBQBInterface->printf(" Volumetric Data and Atom Positions\n"); gc_pBQBInterface->printf("\n"); gc_pBQBInterface->bprintf(" https://brehm-research.de/bqb\n"); gc_pBQBInterface->printf("\n"); gc_pBQBInterface->printf(" Free software, licensed under GNU LGPL v3\n"); gc_pBQBInterface->printf("\n"); gc_pBQBInterface->printf(" Copyright (c) Martin Brehm and Martin Thomas,\n"); gc_pBQBInterface->printf(" Martin Luther University Halle-Wittenberg (Germany), 2016 - 2019.\n"); gc_pBQBInterface->printf("\n"); time(<ime); today = localtime(<ime); strcpy(buf,asctime(today)); buf[strlen(buf)-1] = 0; if (gc_sHostName != NULL) gc_pBQBInterface->printf(" # Running on %s at %s",gc_sHostName,buf); else gc_pBQBInterface->printf(" # Running at %s",buf); #if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) gc_pBQBInterface->printf(" (PID %d)\n",getpid()); #elif defined(_WIN32) gc_pBQBInterface->printf(" (PID %d)\n",GetCurrentProcessId()); #else gc_pBQBInterface->printf("\n"); #endif if (gc_sWorkingDir != NULL) gc_pBQBInterface->printf(" # Running in %s\n",gc_sWorkingDir); gc_pBQBInterface->printf(" # Source code version: "); gc_pBQBInterface->printf("%s\n",BQB_SOURCE_VERSION); gc_pBQBInterface->printf(" # Compiled at "); gc_pBQBInterface->printf("%s, %s\n",__DATE__,__TIME__); #if defined(__VERSION) || defined(__GNUC__) || defined(_MSC_VER) || defined(__clang__) || defined(__llvm__) gc_pBQBInterface->printf(" # Compiler"); b = false; #ifdef __VERSION__ gc_pBQBInterface->printf(" \"%s\"",__VERSION__); b = true; #endif #ifdef __llvm__ if (b) gc_pBQBInterface->printf(","); gc_pBQBInterface->printf(" LLVM"); b = true; #endif #ifdef __clang__ if (b) gc_pBQBInterface->printf(","); #if defined(__clang_major__) && defined(__clang_minor__) && defined(__clang_patchlevel__) gc_pBQBInterface->printf(" CLANG %d.%d.%d",__clang_major__,__clang_minor__,__clang_patchlevel__); #elif defined(__clang_version__) gc_pBQBInterface->printf(" CLANG \"%s\"",__clang_version__); #else gc_pBQBInterface->printf(" CLANG"); #endif b = true; #endif #ifdef __GNUC__ if (b) gc_pBQBInterface->printf(","); #ifdef __MINGW32__ gc_pBQBInterface->printf(" MinGW GCC %d.%d.%d",__GNUC__,__GNUC_MINOR__,__GNUC_PATCHLEVEL__); #else gc_pBQBInterface->printf(" GCC %d.%d.%d",__GNUC__,__GNUC_MINOR__,__GNUC_PATCHLEVEL__); #endif b = true; #endif #ifdef _MSC_VER if (b) gc_pBQBInterface->printf(","); gc_pBQBInterface->printf(" MSVC++ "); switch(_MSC_VER) { case 1916: gc_pBQBInterface->printf("15.9, VS 2017"); break; case 1915: gc_pBQBInterface->printf("15.8, VS 2017"); break; case 1914: gc_pBQBInterface->printf("15.7, VS 2017"); break; case 1913: gc_pBQBInterface->printf("15.6, VS 2017"); break; case 1912: gc_pBQBInterface->printf("15.5, VS 2017"); break; case 1911: gc_pBQBInterface->printf("15.3, VS 2017"); break; case 1910: gc_pBQBInterface->printf("15.1, VS 2017"); break; case 1900: gc_pBQBInterface->printf("14.0, VS 2015"); break; case 1800: gc_pBQBInterface->printf("12.0, VS 2013"); break; case 1700: gc_pBQBInterface->printf("11.0, VS 2012"); break; case 1600: gc_pBQBInterface->printf("10.0, VS 2010"); break; case 1500: gc_pBQBInterface->printf("9.0, VS 2008"); break; case 1400: gc_pBQBInterface->printf("8.0, VS 2005"); break; case 1310: gc_pBQBInterface->printf("7.1, VS 2003"); break; case 1300: gc_pBQBInterface->printf("7.0"); break; case 1200: gc_pBQBInterface->printf("6.0"); break; case 1100: gc_pBQBInterface->printf("5.0"); break; default: gc_pBQBInterface->printf("%d",_MSC_VER); break; } b = true; #endif gc_pBQBInterface->printf("\n"); #endif gc_pBQBInterface->printf("\n"); gc_pBQBInterface->bprintf(" Please cite:"); gc_pBQBInterface->printf(" M. Brehm, M. Thomas: \"An Efficient Lossless Compression Algorithm\n"); gc_pBQBInterface->printf(" for Trajectories of Atom Positions and Volumetric Data\",\n"); gc_pBQBInterface->printf(" J. Chem. Inf. Model. 2018, 58 (10), pp 2092-2107.\n"); gc_pBQBInterface->printf("\n"); err = false; gc_pBQBInterface->printf("Command line:\n"); gc_pBQBInterface->printf(" \""); for (z=1;zprintf("%s",argv[z]); if (z+1 < argc) gc_pBQBInterface->printf(" "); } gc_pBQBInterface->printf("\"\n\n"); CC_InitGlobalVars(); BQBCheckSourceVersion(); if (argc == 2) { if (strcmp(argv[1],"-revision") == 0) { BQBWriteRevisionInfo(); goto _end; } } if (!CC_ParseArguments(argc,argv)) { CC_CommandLineHelp(); return 1; } driver = gc_pBQBInterface->CreateDriver( 0 ); if (gc_bCompress) { if (gc_bFile) { gc_pBQBInterface->printf("Will compress file.\n\n"); gc_pBQBInterface->bprintf("*** Parameters ***\n"); gc_pBQBInterface->printf(" Input file: %s\n", (gc_sInFile!=NULL)?gc_sInFile:"(NULL)"); gc_pBQBInterface->printf(" Output file: %s\n", (gc_sOutFile!=NULL)?gc_sOutFile:"(NULL)"); gc_pBQBInterface->printf(" Verbose: -verbose %d\n", gc_iFileVerbose); gc_pBQBInterface->printf(" Dry run: -dryrun %s\n", gc_bDryRun?"yes":"no"); gc_pBQBInterface->printf("%s",gc_pParmFile->ToString(4).c_str()); gc_pBQBInterface->printf("\n"); gc_pBQBInterface->bprintf("Parameter Key:"); gc_pBQBInterface->printf(" %s\n\n",gc_pParmFile->ToKey().c_str()); if (gc_bDryRun) { gc_pBQBInterface->printf("This is a dry run. Not processing file. Leaving now.\n\n"); goto _end; } if (gc_sInFile == NULL) { gc_pBQBInterface->eprintf("Error: Input file name is required.\n"); err = true; goto _end; } if (gc_sOutFile != NULL) { if (strlen(gc_sOutFile) > 4) { if (bqb_strcmp_nocase(&gc_sOutFile[strlen(gc_sOutFile)-4],".bqb") == 0) goto _okcfile; if (bqb_strcmp_nocase(&gc_sOutFile[strlen(gc_sOutFile)-4],".bbq") == 0) { BQB_PrintBMode(); goto _okcfile; } } gc_pBQBInterface->eprintf("Error: Output file extension needs to be \".bqb\".\n"); err = true; goto _end; _okcfile:; } if (gc_iFileVerbose == 2) gc_pBQBInterface->SetPrintLevel(BQB_PL_DEBUG); else if (gc_iFileVerbose == 1) gc_pBQBInterface->SetPrintLevel(BQB_PL_VERBOSE); else gc_pBQBInterface->SetPrintLevel(BQB_PL_STANDARD); if (!driver->CompressFile( gc_sInFile, // Input File gc_sOutFile, // Output File gc_pParmFile )) { gc_pBQBInterface->eprintf("CompressFile returned an error.\n"); err = true; goto _end; } else gc_pBQBInterface->printf("CompressFile successfully returned.\n"); } if (gc_bCube) { gc_pBQBInterface->printf("Will compress cube file.\n\n"); b = false; if (gc_iCubeOptimize != 0) { if (gc_iCubeOptSteps == -1) { gc_pBQBInterface->printf(" -optsteps not specified, defaulting to 20.\n"); gc_iCubeOptSteps = 20; b = true; } if ((gc_iCubeOptSteps > gc_iCubeSteps) && (gc_iCubeSteps != -1)) { gc_pBQBInterface->printf(" -optsteps larger than -steps, reducing to %d.\n",gc_iCubeSteps); gc_iCubeOptSteps = gc_iCubeSteps; b = true; } } if (b) gc_pBQBInterface->printf("\n"); gc_pBQBInterface->bprintf("*** Parameters ***\n"); gc_pBQBInterface->printf(" General:\n"); gc_pBQBInterface->printf(" Infile: %s\n", (gc_sInFile!=NULL)?gc_sInFile:"(NULL)"); gc_pBQBInterface->printf(" Outfile: %s\n", (gc_sOutFile!=NULL)?gc_sOutFile:"(NULL)"); gc_pBQBInterface->printf(" Output Ref. Traj.: -refout %s\n", (gc_sCubeRefOut!=NULL)?gc_sCubeRefOut:"(NULL)"); gc_pBQBInterface->printf(" Start: -start %d\n", gc_iCubeStart+1); gc_pBQBInterface->printf(" Steps: -steps %d\n", gc_iCubeSteps); gc_pBQBInterface->printf(" Stride: -stride %d\n", gc_iCubeStride); gc_pBQBInterface->printf(" Keyframe frequency: -keyframe %d\n", gc_iCubeKey); gc_pBQBInterface->printf(" Keep Comment Line: -comment %s\n", gc_bCubeKeepComment?"yes":"no"); gc_pBQBInterface->printf(" Check Compressed Data: -check %s\n", gc_bCubeCompare?"yes":"no"); gc_pBQBInterface->printf(" Dummy Read (no comp.): -dummyread %s\n", gc_bCubeDummyRead?"yes":"no"); gc_pBQBInterface->printf(" Optimize Parameters: -optimize %d (0=off, 1=quick, 2=patient, 3=precise, 4=exhaustive)\n", gc_iCubeOptimize); gc_pBQBInterface->printf(" Optimization Frames: -optsteps %d\n", gc_iCubeOptSteps); gc_pBQBInterface->printf(" Quit after Optim.: -onlyopt %s\n", gc_bCubeOnlyOpt?"yes":"no"); gc_pBQBInterface->printf(" Opt. from Start on: -optstart %s\n", (gc_iCubeOptIncludeFirst==1)?"yes":((gc_iCubeOptIncludeFirst==0)?"no":"(undef)")); gc_pBQBInterface->printf(" Verbose: -verbose %d\n", gc_iCubeVerbose); gc_pBQBInterface->printf(" Dry run: -dryrun %s\n", gc_bDryRun?"yes":"no"); gc_pBQBInterface->printf("%s",gc_pParmVol->ToString(2).c_str()); gc_pBQBInterface->printf("\n"); gc_pBQBInterface->bprintf("Parameter Key:"); gc_pBQBInterface->printf(" %s\n\n",gc_pParmVol->ToKey().c_str()); if (gc_bDryRun) { gc_pBQBInterface->printf("This is a dry run. Not processing file. Leaving now.\n\n"); goto _end; } if (gc_sInFile == NULL) { gc_pBQBInterface->eprintf("Error: Input file name is required.\n"); err = true; goto _end; } if (strlen(gc_sInFile) < 6) { gc_pBQBInterface->eprintf("Error: Input file name is too short (needs to be *.cube).\n"); err = true; goto _end; } if (bqb_strcmp_nocase( &gc_sInFile[strlen(gc_sInFile)-5], ".cube" ) != 0) { gc_pBQBInterface->eprintf("Error: Only Gaussian Cube trajectories are currently supported as input.\n"); err = true; goto _end; } if (!gc_bOptTouched) gc_pBQBInterface->printf("To disable the automatic parameter optimization, add \"-optimize 0\" to the command line.\n\n"); if (gc_iCubeOptimize == 3) gc_pBQBInterface->printf("To achieve highest compression ratio (at the cost of compression time), add \"-csplit 14 -citer 40\".\n\n"); if (gc_sOutFile != NULL) { if (strlen(gc_sOutFile) > 4) { if (bqb_strcmp_nocase(&gc_sOutFile[strlen(gc_sOutFile)-4],".bqb") == 0) goto _okcvol; if (bqb_strcmp_nocase(&gc_sOutFile[strlen(gc_sOutFile)-4],".bbq") == 0) { BQB_PrintBMode(); goto _okcvol; } } gc_pBQBInterface->eprintf("Error: Output file extension needs to be \".bqb\".\n"); err = true; goto _end; _okcvol:; } driver->m_iOptIncludeFirst = gc_iCubeOptIncludeFirst; if (gc_iCubeVerbose == 2) gc_pBQBInterface->SetPrintLevel(BQB_PL_DEBUG); else if (gc_iCubeVerbose == 1) gc_pBQBInterface->SetPrintLevel(BQB_PL_VERBOSE); else gc_pBQBInterface->SetPrintLevel(BQB_PL_STANDARD); if (!driver->CompressCube( gc_sInFile, // Cube Trajectory gc_sOutFile, gc_sCubeRefOut, // Output reference file gc_iCubeStart, // Start gc_iCubeSteps, // Steps gc_iCubeStride, // Stride gc_iCubeKey, gc_pParmVol, gc_iCubeOptimize, gc_iCubeOptSteps, gc_bCubeOnlyOpt, gc_bCubeKeepComment, // Keep Comment Line gc_bCubeCompare, // Compare decompressed results gc_bCubeDummyRead // Dummy Read (no compression or output) )) { gc_pBQBInterface->eprintf("CompressCube returned an error.\n"); err = true; goto _end; } else gc_pBQBInterface->printf("CompressCube successfully returned.\n"); } if (gc_bXYZ) { gc_pBQBInterface->printf("Will compress XYZ file.\n\n"); b = false; if (gc_iAtomOptimize != 0) { if (gc_iAtomOptSteps == -1) { gc_pBQBInterface->printf(" -optsteps not specified, defaulting to 50.\n"); gc_iAtomOptSteps = 50; b = true; } if ((gc_iAtomOptSteps > gc_iAtomSteps) && (gc_iAtomSteps != -1)) { gc_pBQBInterface->printf(" -optsteps larger than -steps, reducing to %d.\n",gc_iAtomSteps); gc_iAtomOptSteps = gc_iAtomSteps; b = true; } } if (b) gc_pBQBInterface->printf("\n"); gc_pBQBInterface->bprintf("*** Parameters ***\n"); gc_pBQBInterface->printf(" General:\n"); gc_pBQBInterface->printf(" Infile: %s\n", (gc_sInFile!=NULL)?gc_sInFile:"(NULL)"); gc_pBQBInterface->printf(" Outfile: %s\n", (gc_sOutFile!=NULL)?gc_sOutFile:"(NULL)"); gc_pBQBInterface->printf(" Output Ref. Traj.: -refout %s\n", (gc_sAtomRefOut!=NULL)?gc_sAtomRefOut:"(NULL)"); gc_pBQBInterface->printf(" Start: -start %d\n", gc_iAtomStart); gc_pBQBInterface->printf(" Steps: -steps %d\n", gc_iAtomSteps); gc_pBQBInterface->printf(" Stride: -stride %d\n", gc_iAtomStride); gc_pBQBInterface->printf(" Keyframe frequency: -keyframe %d\n", gc_iAtomKey); gc_pBQBInterface->printf(" Keep Comment Line: -comment %s\n", gc_bAtomKeepComment?"yes":"no"); gc_pBQBInterface->printf(" Check Compressed Data: -check %s\n", gc_bAtomCompare?"yes":"no"); gc_pBQBInterface->printf(" Optimize Parameters: -optimize %d (0=off, 1=quick, 2=patient, 3=precise, 4=exhaustive)\n", gc_iAtomOptimize); gc_pBQBInterface->printf(" Optimization Frames: -optsteps %d\n", gc_iAtomOptSteps); gc_pBQBInterface->printf(" Quit after Optim.: -onlyopt %s\n", gc_bAtomOnlyOpt?"yes":"no"); gc_pBQBInterface->printf(" Opt. from Start on: -optstart %s\n", (gc_iAtomOptIncludeFirst==1)?"yes":((gc_iAtomOptIncludeFirst==0)?"no":"(undef)")); gc_pBQBInterface->printf(" Verbose: -verbose %d\n", gc_iAtomVerbose); gc_pBQBInterface->printf(" Dry run: -dryrun %s\n", gc_bDryRun?"yes":"no"); gc_pBQBInterface->printf("%s",gc_pParmPos->ToString(2).c_str()); gc_pBQBInterface->printf("\n"); gc_pBQBInterface->bprintf("Parameter Key:"); gc_pBQBInterface->printf(" %s\n\n",gc_pParmPos->ToKey().c_str()); if (gc_bDryRun) { gc_pBQBInterface->printf("This is a dry run. Not processing file. Leaving now.\n\n"); goto _end; } if (gc_sInFile == NULL) { gc_pBQBInterface->eprintf("Error: Input file name is required.\n"); err = true; goto _end; } if (strlen(gc_sInFile) < 5) { gc_pBQBInterface->eprintf("Error: Input file name is too short (needs to be *.xyz).\n"); gc_pBQBInterface->printf(" More formats will be added in future releases.\n"); err = true; goto _end; } if (bqb_strcmp_nocase( &gc_sInFile[strlen(gc_sInFile)-4], ".xyz" ) != 0) { gc_pBQBInterface->eprintf("Error: Only XMol XYZ trajectories are currently supported as input.\n"); gc_pBQBInterface->printf(" More formats will be added in future releases.\n"); err = true; goto _end; } if (!gc_bOptTouched) gc_pBQBInterface->printf("To disable the automatic parameter optimization, add \"-optimize 0\" to the command line.\n\n"); if (gc_sOutFile != NULL) { if (strlen(gc_sOutFile) > 4) { if (bqb_strcmp_nocase(&gc_sOutFile[strlen(gc_sOutFile)-4],".bqb") == 0) goto _okcpos; if (bqb_strcmp_nocase(&gc_sOutFile[strlen(gc_sOutFile)-4],".btr") == 0) goto _okcpos; if (bqb_strcmp_nocase(&gc_sOutFile[strlen(gc_sOutFile)-4],".bbq") == 0) { BQB_PrintBMode(); goto _okcpos; } } gc_pBQBInterface->eprintf("Error: Output file extension needs to be \".bqb\" or \".btr\".\n"); err = true; goto _end; _okcpos:; } driver->m_iOptIncludeFirst = gc_iAtomOptIncludeFirst; if (gc_iAtomVerbose == 2) gc_pBQBInterface->SetPrintLevel(BQB_PL_DEBUG); else if (gc_iAtomVerbose == 1) gc_pBQBInterface->SetPrintLevel(BQB_PL_VERBOSE); else gc_pBQBInterface->SetPrintLevel(BQB_PL_STANDARD); if (!driver->CompressXYZ( gc_sInFile, // XYZ file name gc_sOutFile, // gc_sAtomRefOut, // Output reference trajectory gc_iAtomStart, // Start gc_iAtomSteps, // Steps gc_iAtomStride, // Stride gc_iAtomKey, gc_pParmPos, gc_bAtomKeepComment, // Keep Comment Line gc_bAtomCompare, // Compare decompressed results gc_iAtomOptimize, gc_iAtomOptSteps, gc_bAtomOnlyOpt )) { gc_pBQBInterface->eprintf("CompressXYZ returned an error.\n"); err = true; goto _end; } else gc_pBQBInterface->printf("CompressXYZ successfully returned.\n"); } } if (gc_bDecompress) { if (gc_bFile) { gc_pBQBInterface->printf("Will decompress file.\n\n"); gc_pBQBInterface->bprintf("*** Parameters ***\n"); gc_pBQBInterface->printf(" Infile: %s\n", (gc_sInFile!=NULL)?gc_sInFile:"(NULL)"); gc_pBQBInterface->printf(" Outfile: %s\n", (gc_sOutFile!=NULL)?gc_sOutFile:"(NULL)"); gc_pBQBInterface->printf(" Reference File: -refcompare %s\n", (gc_sRefFile!=NULL)?gc_sRefFile:"(NULL)"); gc_pBQBInterface->printf(" Verbose: -verbose %d\n", gc_iFileVerbose); gc_pBQBInterface->printf("\n"); if (gc_sInFile == NULL) { gc_pBQBInterface->eprintf("Error: Input file name is required.\n"); err = true; goto _end; } if (strlen(gc_sInFile) > 4) { if (bqb_strcmp_nocase(&gc_sInFile[strlen(gc_sInFile)-4],".bqb") == 0) goto _okdfile; if (bqb_strcmp_nocase(&gc_sInFile[strlen(gc_sInFile)-4],".bbq") == 0) { BQB_PrintBMode(); goto _okdfile; } } gc_pBQBInterface->eprintf("Error: Input file extension needs to be \".bqb\".\n"); err = true; goto _end; _okdfile: if (gc_iFileVerbose == 2) gc_pBQBInterface->SetPrintLevel(BQB_PL_DEBUG); else if (gc_iFileVerbose == 1) gc_pBQBInterface->SetPrintLevel(BQB_PL_VERBOSE); else gc_pBQBInterface->SetPrintLevel(BQB_PL_STANDARD); if (!driver->DecompressFile( gc_sInFile, // Input File gc_sOutFile, // Output File gc_sRefFile // Ref File )) { gc_pBQBInterface->eprintf("DecompressFile returned an error.\n"); err = true; goto _end; } else gc_pBQBInterface->printf("DecompressFile successfully returned.\n"); } if (gc_bCube) { gc_pBQBInterface->printf("Will decompress Cube file.\n\n"); gc_pBQBInterface->bprintf("*** Parameters ***\n"); gc_pBQBInterface->printf(" Infile: %s\n", (gc_sInFile!=NULL)?gc_sInFile:"(NULL)"); gc_pBQBInterface->printf(" Outfile: %s\n", (gc_sOutFile!=NULL)?gc_sOutFile:"(NULL)"); gc_pBQBInterface->printf(" Reference File: -refcompare %s\n", (gc_sRefFile!=NULL)?gc_sRefFile:"(NULL)"); gc_pBQBInterface->printf(" Steps: -steps %d\n", gc_iCubeSteps); gc_pBQBInterface->printf(" Stride: -stride %d\n", gc_iCubeStride); gc_pBQBInterface->printf(" Verbose: -verbose %d\n", gc_iCubeVerbose); gc_pBQBInterface->printf("\n"); if (gc_sInFile == NULL) { gc_pBQBInterface->eprintf("Error: Input file name is required.\n"); err = true; goto _end; } if (gc_sOutFile != NULL) { if (strlen(gc_sOutFile) < 6) { gc_pBQBInterface->eprintf("Error: Output file name is too short (needs to be *.cube).\n"); err = true; goto _end; } if (bqb_strcmp_nocase( &gc_sOutFile[strlen(gc_sOutFile)-5], ".cube" ) != 0) { gc_pBQBInterface->eprintf("Error: Only Gaussian Cube trajectories are currently supported as output.\n"); err = true; goto _end; } } if (strlen(gc_sInFile) > 4) { if (bqb_strcmp_nocase(&gc_sInFile[strlen(gc_sInFile)-4],".bqb") == 0) goto _okdcube; if (strlen(gc_sInFile) > 6) if (bqb_strcmp_nocase(&gc_sInFile[strlen(gc_sInFile)-6],".blist") == 0) goto _okdcube; if (bqb_strcmp_nocase(&gc_sInFile[strlen(gc_sInFile)-4],".bbq") == 0) { BQB_PrintBMode(); goto _okdcube; } } gc_pBQBInterface->eprintf("Error: Input file extension needs to be \".bqb\" or \".blist\".\n"); err = true; goto _end; _okdcube: if (gc_iCubeVerbose == 2) gc_pBQBInterface->SetPrintLevel(BQB_PL_DEBUG); else if (gc_iCubeVerbose == 1) gc_pBQBInterface->SetPrintLevel(BQB_PL_VERBOSE); else gc_pBQBInterface->SetPrintLevel(BQB_PL_STANDARD); if (!driver->DecompressCube( gc_sInFile, gc_sOutFile, gc_sRefFile, // Input reference file gc_iCubeSteps, // Steps gc_iCubeStride, // Stride NULL )) { gc_pBQBInterface->eprintf("DecompressCube returned an error.\n"); err = true; goto _end; } else gc_pBQBInterface->printf("DecompressCube successfully returned.\n"); } if (gc_bXYZ) { gc_pBQBInterface->printf("Will decompress XYZ file.\n\n"); gc_pBQBInterface->bprintf("*** Parameters ***\n"); gc_pBQBInterface->printf(" Infile: %s\n", (gc_sInFile!=NULL)?gc_sInFile:"(NULL)"); gc_pBQBInterface->printf(" Outfile: %s\n", (gc_sOutFile!=NULL)?gc_sOutFile:"(NULL)"); gc_pBQBInterface->printf(" Reference File: -refcompare %s\n", (gc_sRefFile!=NULL)?gc_sRefFile:"(NULL)"); gc_pBQBInterface->printf(" Steps: -steps %d\n", gc_iAtomSteps); gc_pBQBInterface->printf(" Stride: -stride %d\n", gc_iAtomStride); gc_pBQBInterface->printf(" Verbose: -verbose %d\n", gc_iAtomVerbose); gc_pBQBInterface->printf("\n"); if (gc_sInFile == NULL) { gc_pBQBInterface->eprintf("Error: Input file name is required.\n"); err = true; goto _end; } if (gc_sOutFile != NULL) { if (strlen(gc_sOutFile) < 5) { gc_pBQBInterface->eprintf("Error: Output file name is too short (needs to be *.xyz).\n"); gc_pBQBInterface->printf(" More formats will be added in future releases.\n"); err = true; goto _end; } if (bqb_strcmp_nocase( &gc_sOutFile[strlen(gc_sOutFile)-4], ".xyz" ) != 0) { gc_pBQBInterface->eprintf("Error: Only XMol XYZ trajectories are currently supported as output.\n"); gc_pBQBInterface->printf(" More formats will be added in future releases.\n"); err = true; goto _end; } } if (strlen(gc_sInFile) > 4) { if (bqb_strcmp_nocase(&gc_sInFile[strlen(gc_sInFile)-4],".bqb") == 0) goto _okdpos; if (bqb_strcmp_nocase(&gc_sInFile[strlen(gc_sInFile)-4],".btr") == 0) goto _okdpos; if (strlen(gc_sInFile) > 6) if (bqb_strcmp_nocase(&gc_sInFile[strlen(gc_sInFile)-6],".blist") == 0) goto _okdpos; if (bqb_strcmp_nocase(&gc_sInFile[strlen(gc_sInFile)-4],".bbq") == 0) { BQB_PrintBMode(); goto _okdpos; } } gc_pBQBInterface->eprintf("Error: Input file extension needs to be \".bqb\", \".btr\", or \".blist\".\n"); err = true; goto _end; _okdpos: if (gc_iAtomVerbose == 2) gc_pBQBInterface->SetPrintLevel(BQB_PL_DEBUG); else if (gc_iAtomVerbose == 1) gc_pBQBInterface->SetPrintLevel(BQB_PL_VERBOSE); else gc_pBQBInterface->SetPrintLevel(BQB_PL_STANDARD); if (!driver->DecompressXYZ( gc_sInFile, // gc_sOutFile, // XYZ file name gc_sRefFile, // gc_iAtomSteps, // Steps gc_iAtomStride, // Stride NULL )) { gc_pBQBInterface->eprintf("DecompressXYZ returned an error.\n"); err = true; goto _end; } else gc_pBQBInterface->printf("DecompressXYZ successfully returned.\n"); } } if (gc_bCheck) { gc_pBQBInterface->eprintf("\"check\": Not yet implemented.\n"); err = true; goto _end; /* gc_pBQBInterface->printf("\n###### Seek Test ######\n\n"); FILE *a; gc_pBQBInterface->printf("\n"); gc_pBQBInterface->printf("##########################\n"); gc_pBQBInterface->printf("### 1.) Seek to 17 ###\n"); gc_pBQBInterface->printf("##########################\n"); bf.OpenRead(gc_sInFile); SetBQBVerbose(true); bf.SeekFrame(17); bf.ReadFrame(); SetBQBVerbose(false); a = OpenFileWrite("seek_17.bqb",false); WriteArrayToFile(a,*bf.GetFramePayload()); fclose(a); bf.Close(); gc_pBQBInterface->printf("\n"); gc_pBQBInterface->printf("##########################\n"); gc_pBQBInterface->printf("### 2.) Skip to 17 ###\n"); gc_pBQBInterface->printf("##########################\n"); bf.OpenRead(gc_sInFile); bf.SkipFrames(17); bf.ReadFrame(); a = OpenFileWrite("skip_17.bqb",false); WriteArrayToFile(a,*bf.GetFramePayload()); fclose(a); bf.Close(); gc_pBQBInterface->printf("\n"); gc_pBQBInterface->printf("#############################\n"); gc_pBQBInterface->printf("### 3.) Seek to 19999 ###\n"); gc_pBQBInterface->printf("#############################\n"); bf.OpenRead(gc_sInFile); SetBQBVerbose(true); bf.SeekFrame(19999); bf.ReadFrame(); SetBQBVerbose(false); a = OpenFileWrite("seek_19999.bqb",false); WriteArrayToFile(a,*bf.GetFramePayload()); fclose(a); bf.Close(); gc_pBQBInterface->printf("\n"); gc_pBQBInterface->printf("#############################\n"); gc_pBQBInterface->printf("### 4.) Skip to 19999 ###\n"); gc_pBQBInterface->printf("#############################\n"); bf.OpenRead(gc_sInFile); bf.SkipFrames(19999); bf.ReadFrame(); a = OpenFileWrite("skip_19999.bqb",false); WriteArrayToFile(a,*bf.GetFramePayload()); fclose(a); bf.Close(); gc_pBQBInterface->printf("\n"); gc_pBQBInterface->printf("#############################\n"); gc_pBQBInterface->printf("### 5.) Seek to 20000 ###\n"); gc_pBQBInterface->printf("#############################\n"); bf.OpenRead(gc_sInFile); SetBQBVerbose(true); bf.SeekFrame(20000); bf.ReadFrame(); SetBQBVerbose(false); a = OpenFileWrite("seek_20000.bqb",false); WriteArrayToFile(a,*bf.GetFramePayload()); fclose(a); bf.Close(); gc_pBQBInterface->printf("\n"); gc_pBQBInterface->printf("#############################\n"); gc_pBQBInterface->printf("### 6.) Skip to 20000 ###\n"); gc_pBQBInterface->printf("#############################\n"); bf.OpenRead(gc_sInFile); bf.SkipFrames(20000); bf.ReadFrame(); a = OpenFileWrite("skip_20000.bqb",false); WriteArrayToFile(a,*bf.GetFramePayload()); fclose(a); bf.Close(); gc_pBQBInterface->printf("\n"); gc_pBQBInterface->printf("#############################\n"); gc_pBQBInterface->printf("### 7.) Seek to 20017 ###\n"); gc_pBQBInterface->printf("#############################\n"); bf.OpenRead(gc_sInFile); SetBQBVerbose(true); bf.SeekFrame(20017); bf.ReadFrame(); SetBQBVerbose(false); a = OpenFileWrite("seek_20017.bqb",false); WriteArrayToFile(a,*bf.GetFramePayload()); fclose(a); bf.Close(); gc_pBQBInterface->printf("\n"); gc_pBQBInterface->printf("#############################\n"); gc_pBQBInterface->printf("### 8.) Skip to 20017 ###\n"); gc_pBQBInterface->printf("#############################\n"); bf.OpenRead(gc_sInFile); bf.SkipFrames(20017); bf.ReadFrame(); a = OpenFileWrite("skip_20017.bqb",false); WriteArrayToFile(a,*bf.GetFramePayload()); fclose(a); bf.Close(); gc_pBQBInterface->printf("\n###### Seek Test done ######\n\n"); return 0;*/ gc_pBQBInterface->printf("Will check BQB file.\n\n"); gc_pBQBInterface->bprintf("*** Parameters ***\n"); gc_pBQBInterface->printf(" Infile: %s\n",(gc_sInFile!=NULL)?gc_sInFile:"(NULL)"); gc_pBQBInterface->printf(" Verbose: -verbose %d\n",gc_iCheckVerbose); gc_pBQBInterface->printf("\n"); if (gc_sInFile == NULL) { gc_pBQBInterface->eprintf("Error: Input file name is required.\n"); err = true; goto _end; } gc_pBQBInterface->printf("Checking integrity of compressed file \"%s\".\n\n",gc_sInFile); if (gc_iCheckVerbose == 2) gc_pBQBInterface->SetPrintLevel(BQB_PL_DEBUG); else if (gc_iCheckVerbose == 1) gc_pBQBInterface->SetPrintLevel(BQB_PL_VERBOSE); else gc_pBQBInterface->SetPrintLevel(BQB_PL_STANDARD); /* if (!bf.CheckIntegrity(gc_sInFile,gc_bCheckVerbose)) { gc_pBQBInterface->eprintf("Integrity check failed.\n"); err = true; }*/ } if (gc_bCompare) { gc_pBQBInterface->eprintf("\"compare\": Not yet implemented.\n"); goto _end; gc_pBQBInterface->printf("Will compare BQB coordinates to XYZ file.\n\n"); gc_pBQBInterface->bprintf("*** Parameters ***\n"); gc_pBQBInterface->printf(" Infile: %s\n",(gc_sInFile!=NULL)?gc_sInFile:"(NULL)"); gc_pBQBInterface->printf(" Reffile: %s\n",(gc_sRefFile!=NULL)?gc_sRefFile:"(NULL)"); gc_pBQBInterface->printf(" Verbose: -verbose %d\n",gc_iCompareVerbose); gc_pBQBInterface->printf("\n"); if (gc_sInFile == NULL) { gc_pBQBInterface->eprintf("Error: Input file name is required.\n"); err = true; goto _end; } if (gc_sRefFile == NULL) { gc_pBQBInterface->eprintf("Error: Reference file name is required.\n"); err = true; goto _end; } gc_pBQBInterface->printf("Comparing atom coordinates between %s and %s.\n\n",gc_sInFile,gc_sRefFile); if (gc_iCompareVerbose == 2) gc_pBQBInterface->SetPrintLevel(BQB_PL_DEBUG); else if (gc_iCompareVerbose == 1) gc_pBQBInterface->SetPrintLevel(BQB_PL_VERBOSE); else gc_pBQBInterface->SetPrintLevel(BQB_PL_STANDARD); /* if (!bf.CompareCoords(gc_sInFile,gc_sRefFile,gc_bCompareVerbose)) { gc_pBQBInterface->eprintf("Comparison failed.\n"); err = true; }*/ } if (gc_bMerge) { gc_pBQBInterface->eprintf("\"merge\": Not yet implemented.\n"); goto _end; gc_pBQBInterface->printf("Will merge BQB files.\n\n"); gc_pBQBInterface->bprintf("*** Parameters ***\n"); gc_pBQBInterface->printf(" Outfile: %s\n",(gc_sOutFile!=NULL)?gc_sOutFile:"(NULL)"); if (gc_sInFileList.size() != 0) { gc_pBQBInterface->printf(" Infile: %s\n",(gc_sInFileList[0]!=NULL)?gc_sInFileList[0]:"(NULL)"); for (z=1;z<(int)gc_sInFileList.size();z++) gc_pBQBInterface->printf(" %s\n",(gc_sInFileList[z]!=NULL)?gc_sInFileList[z]:"(NULL)"); } else gc_pBQBInterface->printf(" Infile: (NULL)\n"); gc_pBQBInterface->printf(" Verbose: -verbose %d\n",gc_iMergeVerbose); gc_pBQBInterface->printf("\n"); if (gc_sOutFile == NULL) { gc_pBQBInterface->eprintf("Error: Output file name is required.\n"); err = true; goto _end; } if (gc_sInFileList.size() == 0) { gc_pBQBInterface->eprintf("Error: At least one input file name is required.\n"); err = true; goto _end; } gc_pBQBInterface->printf("Merging %lu BQB files into \"%s\".\n\n",gc_sInFileList.size(),gc_sOutFile); if (gc_iMergeVerbose == 2) gc_pBQBInterface->SetPrintLevel(BQB_PL_DEBUG); else if (gc_iMergeVerbose == 1) gc_pBQBInterface->SetPrintLevel(BQB_PL_VERBOSE); else gc_pBQBInterface->SetPrintLevel(BQB_PL_STANDARD); if (!driver->MergeBQB( gc_sOutFile, gc_sInFileList //gc_bMergeVerbose )) { gc_pBQBInterface->eprintf("Merging failed.\n"); err = true; goto _end; } } if (gc_bSplit) { gc_pBQBInterface->eprintf("\"split\": Not yet implemented.\n"); goto _end; gc_pBQBInterface->printf("Will split BQB file.\n\n"); gc_pBQBInterface->bprintf("*** Parameters ***\n"); gc_pBQBInterface->printf(" Infile: %s\n",(gc_sInFile!=NULL)?gc_sInFile:"(NULL)"); gc_pBQBInterface->printf(" Outfile: %s\n",(gc_sOutFile!=NULL)?gc_sOutFile:"(NULL)"); gc_pBQBInterface->printf(" Split length: %d\n",gc_iSplitLength); gc_pBQBInterface->printf(" Steps: -steps %d\n",gc_iSplitSteps); gc_pBQBInterface->printf(" Verbose: -verbose %d\n",gc_iSplitVerbose); gc_pBQBInterface->printf("\n"); if (gc_sInFile == NULL) { gc_pBQBInterface->eprintf("Error: Input file name is required.\n"); err = true; goto _end; } if (gc_sOutFile == NULL) { gc_pBQBInterface->eprintf("Error: Output base name is required.\n"); err = true; goto _end; } if (gc_iSplitLength == -1) { gc_pBQBInterface->eprintf("Error: Split length is required.\n"); err = true; goto _end; } gc_pBQBInterface->printf("Splitting BQB file \"%s\" into pieces of %d frames with base name \"%s\".\n\n",gc_sInFile,gc_iSplitLength,gc_sOutFile); if (gc_iSplitVerbose == 2) gc_pBQBInterface->SetPrintLevel(BQB_PL_DEBUG); else if (gc_iSplitVerbose == 1) gc_pBQBInterface->SetPrintLevel(BQB_PL_VERBOSE); else gc_pBQBInterface->SetPrintLevel(BQB_PL_STANDARD); /* if (!engine->SplitBQB(gc_sInFile,gc_sOutFile,gc_iSplitLength,gc_iSplitSteps,gc_bSplitVerbose)) { gc_pBQBInterface->eprintf("Splitting failed.\n"); err = true; }*/ } _end: gc_pBQBInterface->DestroyDriver( driver ); gc_pBQBInterface->printf("\n"); gc_pBQBInterface->bprintf(" Please cite:"); gc_pBQBInterface->printf(" M. Brehm, M. Thomas: \"An Efficient Lossless Compression Algorithm\n"); gc_pBQBInterface->printf(" for Trajectories of Atom Positions and Volumetric Data\",\n"); gc_pBQBInterface->printf(" J. Chem. Inf. Model. 2018, 58 (10), pp 2092-2107.\n"); gc_pBQBInterface->bprintf("\n *** bqbtool leaving ***\n\n"); // After this command, no more printing should occur BQBDestroyInterface( gc_pBQBInterface ); #ifndef BQB_INSIDE_TRAVIS if (gc_fLogFile != NULL) fclose(gc_fLogFile); #endif if (err) return 1; else return 0; } travis-src-190101/src/bqb_alphabet.cpp0100777000000000000000000003617613412725621014561 0ustar00/*********************************************************************************** LibBQB - File Format and Compression Algorithms for Trajectories of Volumetric Data and Atom Positions https://brehm-research.de/bqb Free software, licensed under GNU LGPL v3 Copyright (c) Martin Brehm and Martin Thomas, Martin Luther University Halle-Wittenberg, Germany, 2016 - 2019. Please cite: M. Brehm, M. Thomas: "An Efficient Lossless Compression Algorithm for Trajectories of Atom Positions and Volumetric Data", J. Chem. Inf. Model. 2018, 58 (10), pp 2092-2107. -------------------------------------------------------------------------------- LibBQB is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program. If not, see . ***********************************************************************************/ // This must always be the first include directive #include "bqb_config.h" #include "bqb_tools.h" #include #include #include #include "bqb_alphabet.h" #include "bqb_hufftree.h" #include "bqb_interface.h" const char *GetRevisionInfo_bqb_alphabet(unsigned int len) { static char buf[256]; GET_REVISION_INFO( buf, len ); return buf; } const char *GetSourceVersion_bqb_alphabet() { static char buf[256]; GET_SOURCE_VERSION( buf ); return buf; } bool SORT_Alphabet_Freq(const CBQBAlphabetEntry *e1, const CBQBAlphabetEntry *e2) { return (e1->m_iFrequency > e2->m_iFrequency); } bool SORT_Alphabet_Symbol(const CBQBAlphabetEntry *e1, const CBQBAlphabetEntry *e2) { return (e1->m_iSymbol < e2->m_iSymbol); } void CBQBAlphabet::BuildAlphabet(const std::vector &inp) { int z, z2; CBQBAlphabetEntry *ae; std::vector > ta; int ti2; const unsigned int hash_size = 1024; if (m_IF.IsPL(BQB_PL_DEBUG)) { m_IF.printf("Building alphabet (%lu symbols)...\n",inp.size()); m_IF.printf(" ["); } for (z=0;z<(int)m_oaAlphabet.size();z++) delete m_oaAlphabet[z]; m_oaAlphabet.clear(); m_oaAlphabetSortFreq.clear(); ta.resize(hash_size); for (z=C_MIN_RESERVED;true;z++) { ti2 = positive_modulo(z, hash_size); ae = new CBQBAlphabetEntry(); ae->m_iSymbol = z; ae->m_iFrequency = 0; m_oaAlphabet.push_back(ae); ta[ti2].push_back(ae); if (z == C_MAX_RESERVED) break; } for (z=0;z<(int)inp.size();z++) { if (m_IF.IsPL(BQB_PL_DEBUG)) { if (fmod(z,inp.size()/60.0) < 1.0) { m_IF.printf("#"); m_IF.FlushLog(); } } ti2 = positive_modulo(inp[z], hash_size); for (z2=0;z2<(int)ta[ti2].size();z2++) if (ta[ti2][z2]->m_iSymbol == inp[z]) goto _found2; z2 = (int)ta[ti2].size(); ae = new CBQBAlphabetEntry(); ae->m_iSymbol = inp[z]; ae->m_iFrequency = 0; m_oaAlphabet.push_back(ae); ta[ti2].push_back(ae); _found2: ta[ti2][z2]->m_iFrequency++; } if (m_IF.IsPL(BQB_PL_DEBUG)) { m_IF.printf("]\n"); m_IF.printf("Found %lu symbol types.\n",m_oaAlphabet.size()); m_IF.printf("Sorting alphabet by symbols...\n"); } m_oaAlphabetSortFreq.assign(m_oaAlphabet.begin(),m_oaAlphabet.end()); std::sort(m_oaAlphabet.begin(),m_oaAlphabet.end(),SORT_Alphabet_Symbol); if (m_IF.IsPL(BQB_PL_DEBUG)) m_IF.printf("Sorting alphabet by frequencies...\n"); std::sort(m_oaAlphabetSortFreq.begin(),m_oaAlphabetSortFreq.end(),SORT_Alphabet_Freq); for (z=0;z<(int)m_oaAlphabet.size();z++) m_oaAlphabet[z]->m_iIndex = z; if (m_IF.IsPL(BQB_PL_DEBUG)) { m_IF.printf("Creating alphabet indices...\n"); m_IF.printf(" ["); } // m_IF.printf("Assigning output alphabet...\n"); m_iaIndices.resize(inp.size()); for (z=0;z<(int)inp.size();z++) { if (m_IF.IsPL(BQB_PL_DEBUG)) { if (fmod(z,inp.size()/60.0) < 1.0) { m_IF.printf("#"); m_IF.FlushLog(); } } //ti2 = inp[z] % hash_size; ti2 = positive_modulo(inp[z], hash_size); for (z2=0;z2<(int)ta[ti2].size();z2++) if (ta[ti2][z2]->m_iSymbol == inp[z]) break; m_iaIndices[z] = ta[ti2][z2]->m_iIndex; } if (m_IF.IsPL(BQB_PL_DEBUG)) { m_IF.printf("]\n"); m_IF.printf("Finished building alphabet.\n"); } } void CBQBAlphabet::Export(CBQBBitSet *bs, bool huffman, bool chr) const { int z, bits, ti, border, bborder, bsize, bold; long mis, mas, s, m, cht; std::vector ia, ia2; CBQBHuffmanTree *ht, *ht2; if (m_IF.IsPL(BQB_PL_DEBUG)) { if (chr) m_IF.printf("Exporting alphabet (char flag)...\n"); else m_IF.printf("Exporting alphabet (no char flag)...\n"); } mis = 0x7FFFFFF0; mas = -0x7FFFFFF0; for (z=0;z<(int)m_oaAlphabet.size();z++) { if (m_oaAlphabet[z]->m_iSymbol >= C_MIN_RESERVED) break; if (m_oaAlphabet[z]->m_iSymbol > mas) mas = m_oaAlphabet[z]->m_iSymbol; if (m_oaAlphabet[z]->m_iSymbol < mis) mis = m_oaAlphabet[z]->m_iSymbol; } if (m_IF.IsPL(BQB_PL_DEBUG)) m_IF.printf("Will write %d symbol types.\n",z); if (!chr) { bits = (int)ceil(mylog2(z+1)); if (bits <= 8) { bs->WriteBit(0); if (m_IF.IsPL(BQB_PL_DEBUG)) m_IF.printf("Using short format (8 bits) for symbol type count.\n"); bs->WriteBits(z,8); } else { bs->WriteBit(1); bs->WriteBits(bits,6); if (m_IF.IsPL(BQB_PL_DEBUG)) m_IF.printf("Using %d bits for symbol type count.\n",bits); bs->WriteBits(z,bits); } } else bs->WriteBits(z,8); if (m_IF.IsPL(BQB_PL_DEBUG)) m_IF.printf("Symbols range from %ld to %ld.\n",mis,mas); if (huffman) { if (m_IF.IsPL(BQB_PL_DEBUG)) m_IF.printf(">>> Huffman coding of alphabet >>>\n"); bs->WriteBit(1); if (!chr) { bits = (int)ceil(mylog2(abs(m_oaAlphabet[0]->m_iSymbol)+1)); if (m_IF.IsPL(BQB_PL_DEBUG)) m_IF.printf("First alphabet entry is %d, using %d bits.\n",m_oaAlphabet[0]->m_iSymbol,bits); bs->WriteBits(bits,6); if (m_oaAlphabet[0]->m_iSymbol < 0) bs->WriteBit(1); else bs->WriteBit(0); bs->WriteBits(abs(m_oaAlphabet[0]->m_iSymbol),bits); } else bs->WriteBits(m_oaAlphabet[0]->m_iSymbol,8); m = 0; for (z=0;z<(int)m_oaAlphabet.size()-1;z++) { if (m_oaAlphabet[z+1]->m_iSymbol >= C_MIN_RESERVED) break; if (m_oaAlphabet[z+1]->m_iSymbol-m_oaAlphabet[z]->m_iSymbol > m) m = m_oaAlphabet[z+1]->m_iSymbol-m_oaAlphabet[z]->m_iSymbol; ia.push_back(m_oaAlphabet[z+1]->m_iSymbol-m_oaAlphabet[z]->m_iSymbol); } bits = (int)ceil(mylog2(m+1)); if (m_IF.IsPL(BQB_PL_DEBUG)) m_IF.printf("Largest difference is %ld, using %d bits.\n",m,bits); ia2.resize(bits+1); for (z=0;z<(int)ia2.size();z++) ia2[z] = 0; for (z=0;z<(int)ia.size();z++) ia2[(int)ceil(mylog2(ia[z]+1))]++; if (m_IF.IsPL(BQB_PL_DEBUG)) for (z=0;z<(int)ia2.size();z++) m_IF.printf(" %2d bits: %6d\n",z,ia2[z]); bborder = -1; bsize = 1000000000; for (border=0;borderInit(m+1); for (z=0;z<(int)ia.size();z++) ht->m_iaFrequencies[ia[z]]++; ht->BuildTree(false); ti = ht->ExportTree(NULL,chr); for (z=0;z<(int)ia.size();z++) ti += ht->m_oaBitStrings[ia[z]]->GetLength(); if (m_IF.IsPL(BQB_PL_DEBUG)) m_IF.printf("Creating Canonical Huffman tree...\n"); ht2 = new CBQBHuffmanTree(m_IF); ht2->Init(m+1); for (z=0;z<(int)ia.size();z++) ht2->m_iaFrequencies[ia[z]]++; ht2->BuildTree(true); cht = ht2->ExportTree(NULL,chr); for (z=0;z<(int)ia.size();z++) cht += ht2->m_oaBitStrings[ia[z]]->GetLength(); if (m_IF.IsPL(BQB_PL_DEBUG)) { m_IF.printf("Best border storage would require %8.2f bytes.\n",bsize/8.0); m_IF.printf("Huffman alphabet storage requires %8.2f Bytes.\n",ti/8.0); m_IF.printf("Canonical Huffman would require %8.2f Bytes.\n",cht/8.0); } if ((bsize <= ti) && (bsize <= cht)) { if (m_IF.IsPL(BQB_PL_DEBUG)) m_IF.printf("Falling back to more efficient border algorithm.\n"); bs->WriteBit(0); if (chr) { bs->WriteBits(bits,4); bs->WriteBits(bborder,3); } else { bs->WriteBits(bits,6); bs->WriteBits(bborder,5); } for (z=0;z<(int)ia.size();z++) { if ((int)ceil(mylog2(ia[z]+1)) <= bborder) { bs->WriteBit(0); bs->WriteBits(ia[z],bborder); } else { bs->WriteBit(1); bs->WriteBits(ia[z],bits); } } } else if (ti <= cht) { if (m_IF.IsPL(BQB_PL_DEBUG)) m_IF.printf("Exporting Normal Huffman tree...\n"); bs->WriteBit(1); bold = bs->GetLength(); ht->ExportTree(bs,chr); if (m_IF.IsPL(BQB_PL_DEBUG)) m_IF.printf("%d bits written to Huffman tree.\n",bs->GetLength()-bold); if (m_IF.IsPL(BQB_PL_DEBUG)) m_IF.printf("Exporting Normal Huffman data (count %lu)...\n",ia.size()); bold = bs->GetLength(); for (z=0;z<(int)ia.size();z++) bs->WriteBits(ht->m_oaBitStrings[ia[z]]); if (m_IF.IsPL(BQB_PL_DEBUG)) m_IF.printf("%d bits written to Huffman data.\n",bs->GetLength()-bold); } else { if (m_IF.IsPL(BQB_PL_DEBUG)) m_IF.printf("Exporting Canonical Huffman tree...\n"); bs->WriteBit(1); ht2->ExportTree(bs,chr); if (m_IF.IsPL(BQB_PL_DEBUG)) m_IF.printf("Exporting Canonical Huffman data...\n"); for (z=0;z<(int)ia.size();z++) bs->WriteBits(ht2->m_oaBitStrings[ia[z]]); } delete ht; delete ht2; if (m_IF.IsPL(BQB_PL_DEBUG)) m_IF.printf("Done.\n"); } else { // Not Huffman bs->WriteBit(0); mis = bqbabs(mis); mas = bqbabs(mas); if (mis > mas) mas = mis; bits = (int)ceil(mylog2(mas+1))+1; s = ((unsigned long)1)<<(bits-1); if (m_IF.IsPL(BQB_PL_DEBUG)) m_IF.printf("Requires %d bits per symbol, s=%ld.\n",bits,s); bs->WriteBits(bits,6); for (z=0;z<(int)m_oaAlphabet.size();z++) { if (m_oaAlphabet[z]->m_iSymbol >= C_MIN_RESERVED) break; bs->WriteBits(m_oaAlphabet[z]->m_iSymbol+s,bits); } } if (m_IF.IsPL(BQB_PL_DEBUG)) m_IF.printf("Exporting alphabet done.\n"); } void CBQBAlphabet::Import(CBQBBitSet *bs, bool chr) { int z, ti, bits, border, bold; unsigned long i; long l; long s; CBQBAlphabetEntry *ae; CBQBHuffmanTree *ht; if (m_IF.IsPL(BQB_PL_DEBUG)) { if (chr) m_IF.printf("Importing alphabet (char flag)...\n"); else m_IF.printf("Importing alphabet (no char flag)...\n"); } if (!chr) { if (bs->ReadBit()) { bits = bs->ReadBitsInteger(6); if (m_IF.IsPL(BQB_PL_DEBUG)) m_IF.printf("Symbol type count is stored with %d bits.\n",bits); i = bs->ReadBitsInteger(bits); } else { if (m_IF.IsPL(BQB_PL_DEBUG)) m_IF.printf("Symbol type count short format (8 bits).\n"); i = bs->ReadBitsInteger(8); } } else i = bs->ReadBitsInteger(8); if (chr && (i == 0)) { if (m_IF.IsPL(BQB_PL_DEBUG)) m_IF.printf("Warning: Symbol type count was 0, assuming 256.\n"); i = 256; } if (m_IF.IsPL(BQB_PL_DEBUG)) m_IF.printf("Will read %lu symbol types.\n",i); m_oaAlphabet.reserve(i); if (bs->ReadBit()) { // Huffman if (m_IF.IsPL(BQB_PL_DEBUG)) m_IF.printf("Reading Huffman-coded alphabet.\n"); if (!chr) { bits = bs->ReadBitsInteger(6); if (m_IF.IsPL(BQB_PL_DEBUG)) m_IF.printf("First alphabet symbol has %d bits.\n",bits); if (bs->ReadBit()) l = -((long)bs->ReadBitsInteger(bits)); else l = bs->ReadBitsInteger(bits); } else l = bs->ReadBitsInteger(8); if (m_IF.IsPL(BQB_PL_DEBUG)) m_IF.printf("First alphabet symbol is %ld.\n",l); ae = new CBQBAlphabetEntry(); ae->m_iFrequency = 0; ae->m_iIndex = 0; ae->m_iSymbol = l; m_oaAlphabet.push_back(ae); if (bs->ReadBit()) { // Huffman ht = new CBQBHuffmanTree(m_IF); if (m_IF.IsPL(BQB_PL_DEBUG)) m_IF.printf("Reading Huffman table...\n"); bold = bs->GetReadPos(); ht->ImportTree(bs,chr); if (m_IF.IsPL(BQB_PL_DEBUG)) m_IF.printf("Read %d bits from Huffman table.\n",bs->GetReadPos()-bold); if (m_IF.IsPL(BQB_PL_DEBUG)) m_IF.printf("Tree root element has %lu children.\n",ht->m_pTree->m_oaChildren.size()); if (m_IF.IsPL(BQB_PL_DEBUG)) m_IF.printf("Reading Huffman data (%ld symbols)...\n",((long)i)-1); bold = bs->GetReadPos(); for (z=0;z<((long)i)-1;z++) { ae = new CBQBAlphabetEntry(); ae->m_iFrequency = 0; ae->m_iIndex = (int)m_oaAlphabet.size(); ae->m_iSymbol = m_oaAlphabet[m_oaAlphabet.size()-1]->m_iSymbol + ht->DecodeSymbol(bs); m_oaAlphabet.push_back(ae); } if (m_IF.IsPL(BQB_PL_DEBUG)) m_IF.printf("Read %d bits from Huffman data.\n",bs->GetReadPos()-bold); delete ht; } else { // Fallback Border Storage if (m_IF.IsPL(BQB_PL_DEBUG)) m_IF.printf("Fallback border storage.\n"); if (chr) { bits = bs->ReadBitsInteger(4); border = bs->ReadBitsInteger(3); } else { bits = bs->ReadBitsInteger(6); border = bs->ReadBitsInteger(5); } if (m_IF.IsPL(BQB_PL_DEBUG)) m_IF.printf("%d bits maximum, %d bits border.\n",bits,border); for (z=0;z<((long)i)-1;z++) { if (bs->ReadBit()) ti = bs->ReadBitsInteger(bits); else ti = bs->ReadBitsInteger(border); ae = new CBQBAlphabetEntry(); ae->m_iFrequency = 0; ae->m_iIndex = (int)m_oaAlphabet.size(); ae->m_iSymbol = m_oaAlphabet[m_oaAlphabet.size()-1]->m_iSymbol + ti; m_oaAlphabet.push_back(ae); } } if (m_IF.IsPL(BQB_PL_DEBUG)) m_IF.printf("Done.\n"); } else { // Not Huffman bits = bs->ReadBitsInteger(6); s = ((unsigned long)1)<<(bits-1); if (m_IF.IsPL(BQB_PL_DEBUG)) m_IF.printf("%lu symbol types, %d bits per symbol type, s=%ld.\n",i,bits,s); for (z=0;z<(long)i;z++) { ae = new CBQBAlphabetEntry(); ae->m_iIndex = z; m_oaAlphabet.push_back(ae); ae->m_iSymbol = bs->ReadBitsInteger(bits) - s; } } for (z=C_MIN_RESERVED;true;z++) { ae = new CBQBAlphabetEntry(); ae->m_iSymbol = z; ae->m_iFrequency = 0; m_oaAlphabet.push_back(ae); if (z == C_MAX_RESERVED) break; } if (m_IF.IsPL(BQB_PL_DEBUG)) m_IF.printf("Importing alphabet done.\n"); } int CBQBAlphabet::FindIndex(int symbol) const { int z; for (z=0;z<(int)m_oaAlphabet.size();z++) if (m_oaAlphabet[z]->m_iSymbol == symbol) return z; return -1; } void CBQBAlphabet::RecalcFrequencies(const std::vector &ia) { int z; for (z=0;z<(int)m_oaAlphabet.size();z++) m_oaAlphabet[z]->m_iFrequency = 0; for (z=0;z<(int)ia.size();z++) m_oaAlphabet[ia[z]]->m_iFrequency++; std::sort(m_oaAlphabetSortFreq.begin(),m_oaAlphabetSortFreq.end(),SORT_Alphabet_Freq); } travis-src-190101/src/bqb_alphabet.h0100777000000000000000000000466713412725651014231 0ustar00/*********************************************************************************** LibBQB - File Format and Compression Algorithms for Trajectories of Volumetric Data and Atom Positions https://brehm-research.de/bqb Free software, licensed under GNU LGPL v3 Copyright (c) Martin Brehm and Martin Thomas, Martin Luther University Halle-Wittenberg, Germany, 2016 - 2019. Please cite: M. Brehm, M. Thomas: "An Efficient Lossless Compression Algorithm for Trajectories of Atom Positions and Volumetric Data", J. Chem. Inf. Model. 2018, 58 (10), pp 2092-2107. -------------------------------------------------------------------------------- LibBQB is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program. If not, see . ***********************************************************************************/ #ifndef BQB_ALPHABET_H #define BQB_ALPHABET_H // This must always be the first include directive #include "bqb_config.h" #include "bqb_tools.h" #include #include "bqb_bitset.h" class CBQBInterface; class CBQBAlphabetEntry { public: CBQBAlphabetEntry() : m_iSymbol(0), m_iFrequency(0), m_iIndex(0) { } int m_iSymbol; int m_iFrequency; int m_iIndex; }; class CBQBAlphabet { public: CBQBAlphabet(CBQBInterface &i) : m_IF(i) { } ~CBQBAlphabet() { for (int z=0;z<(int)m_oaAlphabet.size();z++) delete m_oaAlphabet[z]; } void BuildAlphabet(const std::vector &inp); void Export(CBQBBitSet *bs, bool huffman, bool chr) const; void Import(CBQBBitSet *bs, bool chr); int FindIndex(int symbol) const; void RecalcFrequencies(const std::vector &ia); std::vector m_oaAlphabet; std::vector m_oaAlphabetSortFreq; std::vector m_iaIndices; private: CBQBInterface &m_IF; }; #endif travis-src-190101/src/bqb_bitset.cpp0100777000000000000000000001637513412725623014274 0ustar00/*********************************************************************************** LibBQB - File Format and Compression Algorithms for Trajectories of Volumetric Data and Atom Positions https://brehm-research.de/bqb Free software, licensed under GNU LGPL v3 Copyright (c) Martin Brehm and Martin Thomas, Martin Luther University Halle-Wittenberg, Germany, 2016 - 2019. Please cite: M. Brehm, M. Thomas: "An Efficient Lossless Compression Algorithm for Trajectories of Atom Positions and Volumetric Data", J. Chem. Inf. Model. 2018, 58 (10), pp 2092-2107. -------------------------------------------------------------------------------- LibBQB is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program. If not, see . ***********************************************************************************/ // This must always be the first include directive #include "bqb_config.h" #include "bqb_bitset.h" #include "bqb_crc.h" #include "bqb_interface.h" const char *GetRevisionInfo_bqb_bitset(unsigned int len) { static char buf[256]; GET_REVISION_INFO( buf, len ); return buf; } const char *GetSourceVersion_bqb_bitset() { static char buf[256]; GET_SOURCE_VERSION( buf ); return buf; } const char *g_sBQBKeyAlpha = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz+-"; std::string CBQBBitSet::ExportKey() { std::string key; CBQBCRC8 crc; unsigned char c1, c2, c3; int z, len; len = GetLength(); //printf("Export: len=%d\n",len); if (len > 1023) { m_IF.eprintf("CBQBBitSet::ExportKey(): Error: Maximum key length is 1023 bits (Bitset is %d bits).\n",len); abort(); } c1 = len%64; c2 = (len/64)%16; for (z=0;z tia; Clear(); if (s.length() < 4) { m_IF.eprintf("CBQBBitSet::ImportKey(): Error: Key requires at least four characters (has only %lu).\n",s.length()); return false; } if (s[0] != '@') { m_IF.eprintf("CBQBBitSet::ImportKey(): Error: Key required to start with \"@\" (found \"%c\").\n",s[0]); return false; } tia.resize(s.length()-1); for (z=1;z<(int)s.length();z++) { p = strchr(g_sBQBKeyAlpha,s[z]); if (p == NULL) { m_IF.eprintf("CBQBBitSet::ImportKey(): Error: Found invalid character \"%c\" in key.\n",s[z]); return false; } tia[z-1] = (unsigned char)(p - g_sBQBKeyAlpha); } len = tia[0] + (tia[1]%16)*64; //printf("Import: len=%d\n",len); if ((len+5)/6 < (int)s.length()-4) m_IF.printf("CBQBBitSet::ImportKey(): Warning: Key contains %d extra characters at the end.\n",(int)s.length()-4-(len+5)/6); if ((len+5)/6 > (int)s.length()-4) { m_IF.eprintf("CBQBBitSet::ImportKey(): Error: Key is too short by %d characters.\n",(len+5)/6-(int)s.length()+4); return false; } c = (tia[1]/16) + tia[2]*4; for (z=0;z= pow2i(len%6)) { m_IF.eprintf("CBQBBitSet::ImportKey(): Error: Last byte too large (%d, %d bits).\n",tia.back(),len%6); return false; } WriteBits(tia.back(),len % 6); } for (z=0;z bits) { m_IF.eprintf("CBitSet::WriteBits(): Error: %lu does not fit into %d bits.\n",i,bits); abort(); } for (int z=0;z bits-1) { m_IF.eprintf("CBitSet::WriteSignedBits(): Error: %ld does not fit into %d bits.\n",i,bits); abort(); } for (int z=0;z= 0) WriteBit(0); else WriteBit(1); } bool CBQBBitSet::ReadBit() { bool b; if (m_iReadPosBytes >= (int)m_iaData.size()) { m_IF.eprintf("CBQBBitSet::ReadBit(): Error: End of BitSet reached.\n"); abort(); } b = (m_iaData[m_iReadPosBytes] & (1<=0;z2--) m_IF.printf("%d",(m_iaData[z]&(1<<(7-z2)))!=0?1:0); for (z2=m_iExcessBits-1;z2>=0;z2--) m_IF.printf("%d",(m_iaData[z]&(1<<(m_iExcessBits-z2-1)))!=0?1:0); } void CBQBBitSet::ExportToFile(FILE *a) const { int z; // unsigned char c; for (z=0;z<(int)m_iaData.size()/4096;z++) fwrite(&m_iaData[z*4096],4096,1,a); if ((m_iaData.size()%4096) != 0) fwrite(&m_iaData[z*4096],m_iaData.size()%4096,1,a); /* for (z=0;z<(int)m_iaData.size();z++) { c = m_iaData[z]; fwrite(&c,1,1,a); }*/ } bool CBQBBitSet::ImportFromFile(FILE *a, int bytes) { int z; // unsigned char c; m_iaData.resize(bytes); // m_iaData.clear(); m_iExcessBits = 0; m_iReadPosBytes = 0; m_iReadPosExcess = 0; for (z=0;z. ***********************************************************************************/ #ifndef BQB_BITSET_H #define BQB_BITSET_H // This must always be the first include directive #include "bqb_config.h" #include "bqb_tools.h" #include class CBQBInterface; class CBQBBitSet { public: CBQBBitSet(CBQBInterface &i) : m_iExcessBits(0), m_iReadPosBytes(0), m_iReadPosExcess(0), m_IF(i) { } CBQBBitSet(const CBQBBitSet &set) : m_iExcessBits(set.m_iExcessBits), m_iReadPosBytes(set.m_iReadPosBytes), m_iReadPosExcess(set.m_iReadPosExcess), m_IF(set.m_IF) { m_iaData.assign(set.m_iaData.begin(),set.m_iaData.end()); } explicit CBQBBitSet(CBQBBitSet *set) : m_iExcessBits(set->m_iExcessBits), m_IF(set->m_IF) { m_iaData.assign(set->m_iaData.begin(),set->m_iaData.end()); } CBQBBitSet& operator=(const CBQBBitSet &rhs) { m_iExcessBits = rhs.m_iExcessBits; m_iReadPosBytes = rhs.m_iReadPosBytes; m_iReadPosExcess = rhs.m_iReadPosExcess; m_iaData.assign(rhs.m_iaData.begin(),rhs.m_iaData.end()); return *this; } int GetLength() const { if (m_iExcessBits == 0) return (int)(8*m_iaData.size()); else return (int)(8*(m_iaData.size()-1) + m_iExcessBits); } int GetByteLength() const { return (int)m_iaData.size(); } void ResetReadPos() { m_iReadPosBytes = 0; m_iReadPosExcess = 0; } void Dump() const; void DumpPlain() const; void ExportToFile(FILE *a) const; bool ImportFromFile(FILE *a, int bytes); std::string ExportKey(); bool ImportKey(std::string s); void Clear() { m_iExcessBits = 0; m_iReadPosBytes = 0; m_iReadPosExcess = 0; m_iaData.clear(); } void WriteBit(unsigned char i) { if (m_iExcessBits == 0) m_iaData.push_back(i); else m_iaData[m_iaData.size()-1] |= i<(&f); for (z=0;z<4;z++) WriteBits(uc[z],8); } void WriteBitsDouble(double f) { unsigned char *uc; int z; uc = reinterpret_cast(&f); for (z=0;z<8;z++) WriteBits(uc[z],8); } float ReadBitsFloat() { unsigned char uc[4]; char *p; int z; for (z=0;z<4;z++) uc[z] = (unsigned char)ReadBitsInteger(8); p = (char*)uc; // This is to comply with strict-aliasing rules (char* may alias to anything) return *reinterpret_cast(p); } double ReadBitsDouble() { unsigned char uc[8]; int z; char *p; for (z=0;z<8;z++) uc[z] = (unsigned char)ReadBitsInteger(8); p = (char*)uc; // This is to comply with strict-aliasing rules (char* may alias to anything) return *reinterpret_cast(p); } void WriteBits(CBQBBitSet *set) { int z, z2; if (set->m_iExcessBits == 0) { for (z=0;z<(int)set->m_iaData.size();z++) for (z2=0;z2<8;z2++) WriteBit((set->m_iaData[z]&(((unsigned long)1)<m_iaData.size()-1;z++) for (z2=0;z2<8;z2++) WriteBit((set->m_iaData[z]&(((unsigned long)1)<m_iExcessBits;z2++) WriteBit((set->m_iaData[set->m_iaData.size()-1]&(((unsigned long)1)< m_iaData; int m_iExcessBits; int m_iReadPosBytes; int m_iReadPosExcess; private: CBQBInterface &m_IF; }; #endif travis-src-190101/src/bqb_config.h0100777000000000000000000001131413412725654013704 0ustar00/*********************************************************************************** LibBQB - File Format and Compression Algorithms for Trajectories of Volumetric Data and Atom Positions https://brehm-research.de/bqb Free software, licensed under GNU LGPL v3 Copyright (c) Martin Brehm and Martin Thomas, Martin Luther University Halle-Wittenberg, Germany, 2016 - 2019. Please cite: M. Brehm, M. Thomas: "An Efficient Lossless Compression Algorithm for Trajectories of Atom Positions and Volumetric Data", J. Chem. Inf. Model. 2018, 58 (10), pp 2092-2107. -------------------------------------------------------------------------------- LibBQB is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program. If not, see . ***********************************************************************************/ // This file is always included before any other include file. #ifndef BQB_CONFIG_H #define BQB_CONFIG_H // Build this library together with TRAVIS? #define BQB_INSIDE_TRAVIS // Options for stand-alone build #ifndef BQB_INSIDE_TRAVIS // Last change to this version of the source code #define BQB_SOURCE_VERSION "Jan 01 2019" // Use faster hard-coded string to floating point conversion (atof). // This speeds up reading CUBE files by a factor of > 2, and also other file formats. // Seems to give identical results to system atof(), but comment out if problems occur. #define BQB_FAST_ATOF #define _FILE_OFFSET_BITS 64 #ifdef _MSC_VER #pragma warning(disable:4786) // Warning "Debug Info truncated to 255 characters" #pragma warning(disable:4702) // Warning "Unreachable Code" #define _CRT_SECURE_NO_WARNINGS #define _CRT_SECURE_NO_DEPRECATE #endif // Revision Information #include #define GET_REVISION_INFO(X,LEN) { if (LEN == 0) sprintf( X, "%s", "\"" __FILE__ "\"" ); else sprintf( X, "File %-*s compiled at %s %s, source version %s.", LEN, "\"" __FILE__ "\"", __DATE__, __TIME__, BQB_SOURCE_VERSION ); } #define GET_SOURCE_VERSION(X) sprintf( X, "%s", BQB_SOURCE_VERSION ) #else // BQB_INSIDE_TRAVIS // Include the TRAVIS main config file #include "config.h" #define BQB_SOURCE_VERSION SOURCE_VERSION #ifdef FAST_ATOF #define BQB_FAST_ATOF #endif #endif const char *GetRevisionInfo_bqb_alphabet(unsigned int len); const char *GetSourceVersion_bqb_alphabet(); const char *GetRevisionInfo_bqb_bitset(unsigned int len); const char *GetSourceVersion_bqb_bitset(); const char *GetRevisionInfo_bqb_crc(unsigned int len); const char *GetSourceVersion_bqb_crc(); const char *GetRevisionInfo_bqb_cubeframe(unsigned int len); const char *GetSourceVersion_bqb_cubeframe(); const char *GetRevisionInfo_bqb_driver(unsigned int len); const char *GetSourceVersion_bqb_driver(); const char *GetRevisionInfo_bqb_engine(unsigned int len); const char *GetSourceVersion_bqb_engine(); const char *GetRevisionInfo_bqb_extrapolator(unsigned int len); const char *GetSourceVersion_bqb_extrapolator(); const char *GetRevisionInfo_bqb_format(unsigned int len); const char *GetSourceVersion_bqb_format(); const char *GetRevisionInfo_bqb_hilbert(unsigned int len); const char *GetSourceVersion_bqb_hilbert(); const char *GetRevisionInfo_bqb_hufftree(unsigned int len); const char *GetSourceVersion_bqb_hufftree(); const char *GetRevisionInfo_bqb_integerengine(unsigned int len); const char *GetSourceVersion_bqb_integerengine(); const char *GetRevisionInfo_bqb_interface(unsigned int len); const char *GetSourceVersion_bqb_interface(); const char *GetRevisionInfo_bqb_largeinteger(unsigned int len); const char *GetSourceVersion_bqb_largeinteger(); const char *GetRevisionInfo_bqb_linalg(unsigned int len); const char *GetSourceVersion_bqb_linalg(); const char *GetRevisionInfo_bqb_math(unsigned int len); const char *GetSourceVersion_bqb_math(); const char *GetRevisionInfo_bqb_parmset(unsigned int len); const char *GetSourceVersion_bqb_parmset(); const char *GetRevisionInfo_bqb_tools(unsigned int len); const char *GetSourceVersion_bqb_tools(); const char *GetRevisionInfo_bqbtool(unsigned int len); const char *GetSourceVersion_bqbtool(); #endif travis-src-190101/src/bqb_crc.cpp0100777000000000000000000001055113412725621013535 0ustar00/*********************************************************************************** LibBQB - File Format and Compression Algorithms for Trajectories of Volumetric Data and Atom Positions https://brehm-research.de/bqb Free software, licensed under GNU LGPL v3 Copyright (c) Martin Brehm and Martin Thomas, Martin Luther University Halle-Wittenberg, Germany, 2016 - 2019. Please cite: M. Brehm, M. Thomas: "An Efficient Lossless Compression Algorithm for Trajectories of Atom Positions and Volumetric Data", J. Chem. Inf. Model. 2018, 58 (10), pp 2092-2107. -------------------------------------------------------------------------------- LibBQB is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program. If not, see . ***********************************************************************************/ // This must always be the first include directive #include "bqb_config.h" #include "bqb_crc.h" const char *GetRevisionInfo_bqb_crc(unsigned int len) { static char buf[256]; GET_REVISION_INFO( buf, len ); return buf; } const char *GetSourceVersion_bqb_crc() { static char buf[256]; GET_SOURCE_VERSION( buf ); return buf; } /* This code is adapted from http://www.rajivchakravorty.com/source-code/uncertainty/multimedia-sim/html/crc8_8c-source.html */ CBQBCRC8::CBQBCRC8() { #define CRC8_DI 0x2F /* x^8 + x^5 + x^3 + x^2 + x + 1 */ int i, j; unsigned char crc; for (i=0; i<256; i++) { crc = (unsigned char)i; for (j=0; j<8; j++) crc = (crc << 1) ^ ((crc & 0x80) ? CRC8_DI : 0); m_iTable[i] = crc & 0xFF; /* printf("table[%d] = %d (0x%X)\n", i, crc, crc); */ } Reset(); } /* This code is adapted from http://www.networkdls.com/Software/View/CRC32 */ CBQBCRC32::CBQBCRC32() { //0x04C11DB7 is the official polynomial used by PKZip, WinZip and Ethernet. unsigned int iPolynomial = 0x04C11DB7; memset(&this->iTable, 0, sizeof(this->iTable)); // 256 values representing ASCII character codes. for(int iCodes = 0; iCodes <= 0xFF; iCodes++) { this->iTable[iCodes] = this->Reflect(iCodes, 8) << 24; for(int iPos = 0; iPos < 8; iPos++) { this->iTable[iCodes] = (this->iTable[iCodes] << 1) ^ ((this->iTable[iCodes] & (1 << 31)) ? iPolynomial : 0); } this->iTable[iCodes] = this->Reflect(this->iTable[iCodes], 32); } } unsigned int CBQBCRC32::Reflect(unsigned int iReflect, const char cChar) const { unsigned int iValue = 0; // Swap bit 0 for bit 7, bit 1 for bit 6, etc.... for (int iPos = 1; iPos < (cChar + 1); iPos++) { if (iReflect & 1) iValue |= (1 << (cChar - iPos)); iReflect >>= 1; } return iValue; } unsigned int CBQBCRC32::ComputeCRC32(const std::vector &data, int from, int to) const { unsigned int crc; int z; crc = 0xffffffff; // Initialize the CRC. if (to == -1) to = (int)data.size()-1; for (z=from;z<=to;z++) crc = (crc >> 8) ^ this->iTable[(crc & 0xFF) ^ data[z]]; crc ^= 0xffffffff; // Finalize the CRC. return crc; } unsigned int CBQBCRC32::ComputeCRC32_Begin(const std::vector &data, int from, int to) const { unsigned int crc; int z; crc = 0xffffffff; // Initialize the CRC. if (to == -1) to = (int)data.size()-1; for (z=from;z<=to;z++) crc = (crc >> 8) ^ this->iTable[(crc & 0xFF) ^ data[z]]; return crc; } unsigned int CBQBCRC32::ComputeCRC32_Continue(const std::vector &data, unsigned int last, int from, int to) const { unsigned int crc; int z; crc = last; // Initialize the CRC. if (to == -1) to = (int)data.size()-1; for (z=from;z<=to;z++) crc = (crc >> 8) ^ this->iTable[(crc & 0xFF) ^ data[z]]; return crc; } unsigned int CBQBCRC32::ComputeCRC32_Finish(unsigned int last) const { return last ^ 0xffffffff; // Finalize the CRC. } travis-src-190101/src/bqb_crc.h0100777000000000000000000000552313412725660013210 0ustar00/*********************************************************************************** LibBQB - File Format and Compression Algorithms for Trajectories of Volumetric Data and Atom Positions https://brehm-research.de/bqb Free software, licensed under GNU LGPL v3 Copyright (c) Martin Brehm and Martin Thomas, Martin Luther University Halle-Wittenberg, Germany, 2016 - 2019. Please cite: M. Brehm, M. Thomas: "An Efficient Lossless Compression Algorithm for Trajectories of Atom Positions and Volumetric Data", J. Chem. Inf. Model. 2018, 58 (10), pp 2092-2107. -------------------------------------------------------------------------------- LibBQB is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program. If not, see . ***********************************************************************************/ #ifndef BQB_CRC32_H #define BQB_CRC32_H // This must always be the first include directive #include "bqb_config.h" #include "bqb_tools.h" #include #include /* This code is adapted from http://www.rajivchakravorty.com/source-code/uncertainty/multimedia-sim/html/crc8_8c-source.html */ class CBQBCRC8 { public: CBQBCRC8(); void Reset() { m_iCRC8 = 0xFF; } void Finalize() { m_iCRC8 ^= 0xFF; } void PushByte(unsigned char m) { // For a byte array whose accumulated crc value is stored in *crc, computes // resultant crc obtained by appending m to the byte array m_iCRC8 = m_iTable[m_iCRC8 ^ m]; m_iCRC8 &= 0xFF; } unsigned char m_iCRC8; unsigned char m_iTable[256]; }; /* This code is adapted from http://www.networkdls.com/Software/View/CRC32 */ class CBQBCRC32 { public: CBQBCRC32(); unsigned int ComputeCRC32(const std::vector &data, int from=0, int to=-1) const; unsigned int ComputeCRC32_Begin(const std::vector &data, int from=0, int to=-1) const; unsigned int ComputeCRC32_Continue(const std::vector &data, unsigned int last, int from=0, int to=-1) const; unsigned int ComputeCRC32_Finish(unsigned int last) const; private: unsigned int Reflect(unsigned int iReflect, const char cChar) const; unsigned int iTable[256]; // CRC lookup table array. }; #endif travis-src-190101/src/bqb_cubeframe.cpp0100777000000000000000000004256613412725633014735 0ustar00/*********************************************************************************** LibBQB - File Format and Compression Algorithms for Trajectories of Volumetric Data and Atom Positions https://brehm-research.de/bqb Free software, licensed under GNU LGPL v3 Copyright (c) Martin Brehm and Martin Thomas, Martin Luther University Halle-Wittenberg, Germany, 2016 - 2019. Please cite: M. Brehm, M. Thomas: "An Efficient Lossless Compression Algorithm for Trajectories of Atom Positions and Volumetric Data", J. Chem. Inf. Model. 2018, 58 (10), pp 2092-2107. -------------------------------------------------------------------------------- LibBQB is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program. If not, see . ***********************************************************************************/ // This must always be the first include directive #include "bqb_config.h" #include "bqb_tools.h" #include #include "bqb_cubeframe.h" #include "bqb_fastatof.h" #include "bqb_interface.h" const char *GetRevisionInfo_bqb_cubeframe(unsigned int len) { static char buf[256]; GET_REVISION_INFO( buf, len ); return buf; } const char *GetSourceVersion_bqb_cubeframe() { static char buf[256]; GET_SOURCE_VERSION( buf ); return buf; } bool CBQBCubeFrame::ReadFrame(FILE *a, int eps, int csigni, int asigni, bool verbose) { int ac, z, z2, i, trunc; char buf[256], buf2[256], *p, *q; double tf, mi, ma; CBQBAtom *ta; m_iEps = eps; m_iSigni = csigni; if (m_pAtoms != NULL) delete m_pAtoms; m_pAtoms = new CBQBAtomSet(); m_pAtoms->m_iSigni = asigni; m_pAtoms->m_bOrd = true; if (feof(a)) return false; (void)fgets(buf,256,a); if (feof(a)) return false; buf[strlen(buf)-1] = 0; (void)fgets(buf2,256,a); if (feof(a)) return false; buf2[strlen(buf2)-1] = 0; m_pAtoms->m_sComment = new char[strlen(buf)+strlen(buf2)+2]; strcpy(m_pAtoms->m_sComment,buf); strcat(m_pAtoms->m_sComment,"\n"); strcat(m_pAtoms->m_sComment,buf2); (void)fgets(buf,256,a); if (feof(a)) return false; p = buf; while (*p == ' ') p++; q = p; while (*q != ' ') q++; *q = 0; ac = atoi(p); p = q+1; while (*p == ' ') p++; q = p; while (*q != ' ') q++; *q = 0; m_fCenter[0] = atof(p); p = q+1; while (*p == ' ') p++; q = p; while (*q != ' ') q++; *q = 0; m_fCenter[1] = atof(p); p = q+1; while (*p == ' ') p++; q = p; while ((*q != ' ') && (*q != 0)) q++; *q = 0; m_fCenter[2] = atof(p); (void)fgets(buf,256,a); p = buf; while (*p == ' ') p++; q = p; while (*q != ' ') q++; *q = 0; m_iRes[0] = atoi(p); p = q+1; while (*p == ' ') p++; q = p; while (*q != ' ') q++; *q = 0; m_fStrideA[0] = atof(p); p = q+1; while (*p == ' ') p++; q = p; while (*q != ' ') q++; *q = 0; m_fStrideA[1] = atof(p); p = q+1; while (*p == ' ') p++; q = p; while ((*q != ' ') && (*q != 0)) q++; *q = 0; m_fStrideA[2] = atof(p); (void)fgets(buf,256,a); p = buf; while (*p == ' ') p++; q = p; while (*q != ' ') q++; *q = 0; m_iRes[1] = atoi(p); p = q+1; while (*p == ' ') p++; q = p; while (*q != ' ') q++; *q = 0; m_fStrideB[0] = atof(p); p = q+1; while (*p == ' ') p++; q = p; while (*q != ' ') q++; *q = 0; m_fStrideB[1] = atof(p); p = q+1; while (*p == ' ') p++; q = p; while ((*q != ' ') && (*q != 0)) q++; *q = 0; m_fStrideB[2] = atof(p); (void)fgets(buf,256,a); p = buf; while (*p == ' ') p++; q = p; while (*q != ' ') q++; *q = 0; m_iRes[2] = atoi(p); p = q+1; while (*p == ' ') p++; q = p; while (*q != ' ') q++; *q = 0; m_fStrideC[0] = atof(p); p = q+1; while (*p == ' ') p++; q = p; while (*q != ' ') q++; *q = 0; m_fStrideC[1] = atof(p); p = q+1; while (*p == ' ') p++; q = p; while ((*q != ' ') && (*q != 0)) q++; *q = 0; m_fStrideC[2] = atof(p); for (z=0;z<3;z++) { if (fabs(m_fStrideA[z]) > 2000.0) { m_IF.printf("CBQBCubeFrame::ReadFrame(): Error: m_fStrideA[%d] > 2000 a.u. (is %f a.u.).\n",z,m_fStrideA[z]); return false; } if (fabs(m_fStrideB[z]) > 2000.0) { m_IF.printf("CBQBCubeFrame::ReadFrame(): Error: m_fStrideB[%d] > 2000 a.u. (is %f a.u.).\n",z,m_fStrideB[z]); return false; } if (fabs(m_fStrideC[z]) > 2000.0) { m_IF.printf("CBQBCubeFrame::ReadFrame(): Error: m_fStrideC[%d] > 2000 a.u. (is %f a.u.).\n",z,m_fStrideC[z]); return false; } if (fabs(m_fCenter[z]) > 2000.0) { m_IF.printf("CBQBCubeFrame::ReadFrame(): Error: m_fCenter[%d] > 2000 a.u. (is %f a.u.).\n",z,m_fCenter[z]); return false; } m_iStrideA[z] = FloatToFixed(m_fStrideA[z],6); m_iStrideB[z] = FloatToFixed(m_fStrideB[z],6); m_iStrideC[z] = FloatToFixed(m_fStrideC[z],6); m_iCenter[z] = FloatToFixed(m_fCenter[z],6); } for (z=0;zm_oaAtoms.push_back(ta); (void)fgets(buf,256,a); p = buf; while (*p == ' ') p++; q = p; while (*q != ' ') q++; *q = 0; ta->m_iOrd = atoi(p); p = q+1; while (*p == ' ') p++; q = p; while (*q != ' ') q++; p = q+1; while (*p == ' ') p++; q = p; while (*q != ' ') q++; *q = 0; ta->m_fCoord[0] = atof(p); p = q+1; while (*p == ' ') p++; q = p; while (*q != ' ') q++; *q = 0; ta->m_fCoord[1] = atof(p); p = q+1; while (*p == ' ') p++; q = p; while ((*q != ' ') && (*q != 0)) q++; *q = 0; ta->m_fCoord[2] = atof(p); for (z2=0;z2<3;z2++) { if (fabs(ta->m_fCoord[z2]) > 2000.0) { m_IF.printf("CBQBCubeFrame::ReadFrame(): Error: m_oaAtoms[%d][%d] > 2000 a.u. (is %f a.u.).\n",z,z2,ta->m_fCoord[z2]); return false; } m_pAtoms->m_faCOM[z2] += ta->m_fCoord[z2]; ta->m_iCoord[z2] = FloatToFixed(ta->m_fCoord[z2],asigni); // ta->m_fCoord[z2] = FixedToFloat(ta->m_iCoord[z2],asigni); // ta->m_fCoord[z2] *= 0.52917721; } // m_IF.printf("%d %f %f %f\n",ta->m_iOrd,ta->m_fCoord[0],ta->m_fCoord[1],ta->m_fCoord[2]); } for (z2=0;z2<3;z2++) { m_pAtoms->m_faCOM[z2] /= m_pAtoms->m_oaAtoms.size(); m_pAtoms->m_iaCOM[z2] = FloatToFixed(m_pAtoms->m_faCOM[z2],asigni); m_pAtoms->m_faCOM[z2] = FixedToFloat(m_pAtoms->m_iaCOM[z2],asigni); } for (z=0;z<(int)m_pAtoms->m_oaAtoms.size();z++) { for (z2=0;z2<3;z2++) { //m_pAtoms->m_oaAtoms[z]->m_fRelCoord[z2] = m_pAtoms->m_oaAtoms[z]->m_fCoord[z2] - m_pAtoms->m_faCOM[z2]; //m_pAtoms->m_oaAtoms[z]->m_iRelCoord[z2] = FloatToFixed(m_pAtoms->m_oaAtoms[z]->m_fRelCoord[z2],asigni); m_pAtoms->m_oaAtoms[z]->m_iRelCoord[z2] = m_pAtoms->m_oaAtoms[z]->m_iCoord[z2] - m_pAtoms->m_iaCOM[z2]; m_pAtoms->m_oaAtoms[z]->m_fRelCoord[z2] = FixedToFloat(m_pAtoms->m_oaAtoms[z]->m_iRelCoord[z2],asigni); } } if (feof(a)) { m_IF.printf("Error: Unexpected end of cube file.\n"); return false; } /* for (z=0;z<3;z++) { m_fCenter[z] *= 0.52917721; m_fStride[z] *= 0.52917721; }*/ m_iResXY = m_iRes[0] * m_iRes[1]; m_iResYZ = m_iRes[1] * m_iRes[2]; m_iResXYZ = m_iRes[0] * m_iRes[1] * m_iRes[2]; m_fMinVal[0] = m_fCenter[0]; m_fMaxVal[0] = m_fCenter[0] + m_fStrideA[0] * m_iRes[0]; m_fMinVal[1] = m_fCenter[1]; m_fMaxVal[1] = m_fCenter[1] + m_fStrideB[1] * m_iRes[1]; m_fMinVal[2] = m_fCenter[2]; m_fMaxVal[2] = m_fCenter[2] + m_fStrideC[2] * m_iRes[2]; if (verbose) { m_IF.printf("Res: %d %d %d\n",m_iRes[0],m_iRes[1],m_iRes[2]); m_IF.printf("Center: %f %f %f a.u.\n",m_fCenter[0],m_fCenter[1],m_fCenter[2]); m_IF.printf("Stride A: %f %f %f a.u.\n",m_fStrideA[0],m_fStrideA[1],m_fStrideA[2]); m_IF.printf("Stride B: %f %f %f a.u.\n",m_fStrideB[0],m_fStrideB[1],m_fStrideB[2]); m_IF.printf("Stride C: %f %f %f a.u.\n",m_fStrideC[0],m_fStrideC[1],m_fStrideC[2]); m_IF.printf("Range: X %f - %f, Y %f - %f, Z %f - %f a.u.\n",m_fMinVal[0],m_fMaxVal[0],m_fMinVal[1],m_fMaxVal[1],m_fMinVal[2],m_fMaxVal[2]); m_IF.printf("\n"); m_IF.printf(" Reading cube file (resolution %d x %d x %d, %d atoms)...\n",m_iRes[0],m_iRes[1],m_iRes[2],ac); m_IF.printf(" ["); } m_faBin.resize(m_iResXYZ); m_iaExpo.resize(m_iResXYZ); m_iaMantis.resize(m_iResXYZ); i = 0; mi = 1.0e30f; ma = -1.0e30f; trunc = 0; while (!feof(a)) { _read: (void)fgets(buf,256,a); if (feof(a)) break; p = buf; _next: while (*p == ' ') p++; q = p; while ((*p != ' ') && (*p != '\n') && (*p != 0)) p++; if ((p-q) < 8) goto _read; *p = 0; #ifdef BQB_FAST_ATOF tf = bqb_fast_atof(q); #else tf = atof(q); #endif if (tf < mi) mi = tf; if (tf > ma) ma = tf; m_faBin[i] = tf; m_iaExpo[i] = (char)((int)floor(log10(fabs(tf)))-csigni+1); if (m_iaExpo[i] < -eps) { m_iaExpo[i] = (char)-eps; trunc++; // m_IF.printf("%s --> %15.10G --> %6d E %2d\n",q,tf,(int)(tf*pow(10,-m_pExpo[i])+0.5),m_pExpo[i]); } m_iaMantis[i] = (int)floor(tf*pow10(-m_iaExpo[i])+0.5); // MB Hack 26.01.2018 m_faBin[i] = (double)m_iaMantis[i] * pow10(m_iaExpo[i]); i++; if (verbose) { if (fmod(i,m_iResXYZ/60.0) < 1.0) { m_IF.printf("#"); fflush(stdout); } } if (i == m_iResXYZ) break; p++; goto _next; } if (feof(a)) { m_IF.printf("Error: Unexpected end of cube file stream.\n"); return false; } if (verbose) { m_IF.printf("]\n"); m_IF.printf(" %d values truncated due to EPS.\n",trunc); m_IF.printf(" Value range: %10.6G ... %10.6G\n\n",mi,ma); } return true; } bool CBQBCubeFrame::SkipFrame(FILE *a, bool verbose) const { UNUSED(verbose); int ac, z, i, resx, resy, resz; char buf[256], *p, *q; if (feof(a)) return false; (void)fgets(buf,256,a); if (feof(a)) return false; (void)fgets(buf,256,a); if (feof(a)) return false; (void)fgets(buf,256,a); if (feof(a)) return false; p = buf; while (*p == ' ') p++; q = p; while (*q != ' ') q++; *q = 0; ac = atoi(p); /* p = q+1; while (*p == ' ') p++; q = p; while (*q != ' ') q++; *q = 0; m_fCenter[0] = atof(p); p = q+1; while (*p == ' ') p++; q = p; while (*q != ' ') q++; *q = 0; m_fCenter[1] = atof(p); p = q+1; while (*p == ' ') p++; q = p; while ((*q != ' ') && (*q != 0)) q++; *q = 0; m_fCenter[2] = atof(p);*/ (void)fgets(buf,256,a); p = buf; while (*p == ' ') p++; q = p; while (*q != ' ') q++; *q = 0; resx = atoi(p); /* p = q+1; while (*p == ' ') p++; q = p; while (*q != ' ') q++; *q = 0; m_fStride[0] = atof(p);*/ (void)fgets(buf,256,a); p = buf; while (*p == ' ') p++; q = p; while (*q != ' ') q++; *q = 0; resy = atoi(p); /* p = q+1; while (*p == ' ') p++; q = p; while (*q != ' ') q++; p = q+1; while (*p == ' ') p++; q = p; while (*q != ' ') q++; *q = 0; m_fStride[1] = atof(p);*/ (void)fgets(buf,256,a); p = buf; while (*p == ' ') p++; q = p; while (*q != ' ') q++; *q = 0; resz = atoi(p); /* p = q+1; while (*p == ' ') p++; q = p; while (*q != ' ') q++; p = q+1; while (*p == ' ') p++; q = p; while (*q != ' ') q++; p = q+1; while (*p == ' ') p++; q = p; while ((*q != ' ') && (*q != 0)) q++; *q = 0; m_fStride[2] = atof(p);*/ /* fgets(buf,256,a); if (feof(a)) return false; p = buf; while (*p == ' ') p++; q = p; while (*q != ' ') q++; *q = 0; ac = atoi(p); fgets(buf,256,a); fgets(buf,256,a); fgets(buf,256,a);*/ for (z=0;zm_sComment != NULL) fprintf(a,"%s\n",m_pAtoms->m_sComment); else fprintf(a,"(Comment 1)\n(Comment 2)\n"); fprintf(a,"%5lu %11.6f %11.6f %11.6f\n",(unsigned long)m_pAtoms->m_oaAtoms.size(),m_fCenter[0],m_fCenter[1],m_fCenter[2]); fprintf(a,"%5d %11.6f %11.6f %11.6f\n",m_iRes[0],m_fStrideA[0],m_fStrideA[1],m_fStrideA[2]); fprintf(a,"%5d %11.6f %11.6f %11.6f\n",m_iRes[1],m_fStrideB[0],m_fStrideB[1],m_fStrideB[2]); fprintf(a,"%5d %11.6f %11.6f %11.6f\n",m_iRes[2],m_fStrideC[0],m_fStrideC[1],m_fStrideC[2]); for (z=0;z<(int)m_pAtoms->m_oaAtoms.size();z++) fprintf(a,"%5d %11.6f %11.6f %11.6f %11.6f\n",m_pAtoms->m_oaAtoms[z]->m_iOrd,0.0,m_pAtoms->m_oaAtoms[z]->m_fCoord[0],m_pAtoms->m_oaAtoms[z]->m_fCoord[1],m_pAtoms->m_oaAtoms[z]->m_fCoord[2]); i = 0; for (ix=0;ixm_sComment != NULL) fprintf(a,"%s\n",m_pAtoms->m_sComment); else fprintf(a,"(Comment 1)\n(Comment 2)\n"); fprintf(a,"%5lu %11.6f %11.6f %11.6f\n",(unsigned long)m_pAtoms->m_oaAtoms.size(),m_fCenter[0],m_fCenter[1],m_fCenter[2]); fprintf(a,"%5d %11.6f %11.6f %11.6f\n",m_iRes[0],m_fStrideA[0],m_fStrideA[1],m_fStrideA[2]); fprintf(a,"%5d %11.6f %11.6f %11.6f\n",m_iRes[1],m_fStrideB[0],m_fStrideB[1],m_fStrideB[2]); fprintf(a,"%5d %11.6f %11.6f %11.6f\n",m_iRes[2],m_fStrideC[0],m_fStrideC[1],m_fStrideC[2]); for (z=0;z<(int)m_pAtoms->m_oaAtoms.size();z++) fprintf(a,"%5d %11.6f %11.6f %11.6f %11.6f\n",m_pAtoms->m_oaAtoms[z]->m_iOrd,0.0,m_pAtoms->m_oaAtoms[z]->m_fCoord[0],m_pAtoms->m_oaAtoms[z]->m_fCoord[1],m_pAtoms->m_oaAtoms[z]->m_fCoord[2]); i = 0; for (ix=0;ixm_sLabel.c_str(),l,signi,m_oaAtoms[z]->m_fCoord[0],l,signi,m_oaAtoms[z]->m_fCoord[1],l,signi,m_oaAtoms[z]->m_fCoord[2]); } bool CBQBAtomSet::ReadXYZ(FILE *a, int signi, FILE *ref) { char buf[256], *p, *q; int i, z, z2; CBQBAtom *at; m_iSigni = signi; m_bLabels = true; for (z=0;z<(int)m_oaAtoms.size();z++) delete m_oaAtoms[z]; m_oaAtoms.clear(); (void)fgets(buf,256,a); buf[strlen(buf)-1] = 0; i = atoi(buf); if (feof(a)) return false; (void)fgets(buf,256,a); buf[strlen(buf)-1] = 0; m_sComment = new char[strlen(buf)+1]; strcpy(m_sComment,buf); for (z=0;z<3;z++) m_faCOM[z] = 0; for (z=0;zm_sLabel = p; at->m_iOrd = GetAtomOrd(p); p = q+1; while (*p == ' ') p++; q = strchr(p,' '); *q = 0; //at->m_fCoord[0] = atof(p); #ifdef BQB_FAST_ATOF at->m_fCoord[0] = bqb_fast_atof(p); #else at->m_fCoord[0] = atof(p); #endif p = q+1; while (*p == ' ') p++; q = strchr(p,' '); *q = 0; //at->m_fCoord[1] = atof(p); #ifdef BQB_FAST_ATOF at->m_fCoord[1] = bqb_fast_atof(p); #else at->m_fCoord[1] = atof(p); #endif p = q+1; while (*p == ' ') p++; //at->m_fCoord[2] = atof(p); #ifdef BQB_FAST_ATOF at->m_fCoord[2] = bqb_fast_atof(p); #else at->m_fCoord[2] = atof(p); #endif for (z2=0;z2<3;z2++) { at->m_iCoord[z2] = FloatToFixed(at->m_fCoord[z2],signi); at->m_fCoord[z2] = FixedToFloat(at->m_iCoord[z2],signi); m_faCOM[z2] += at->m_fCoord[z2]; } } for (z=0;z<3;z++) { m_faCOM[z] /= m_oaAtoms.size(); m_iaCOM[z] = FloatToFixed(m_faCOM[z],signi); m_faCOM[z] = FixedToFloat(m_iaCOM[z],signi); } for (z=0;z<(int)m_oaAtoms.size();z++) { for (z2=0;z2<3;z2++) { //m_oaAtoms[z]->m_fRelCoord[z2] = m_oaAtoms[z]->m_fCoord[z2] - m_faCOM[z2]; //m_oaAtoms[z]->m_iRelCoord[z2] = FloatToFixed(m_oaAtoms[z]->m_fRelCoord[z2],signi); m_oaAtoms[z]->m_iRelCoord[z2] = m_oaAtoms[z]->m_iCoord[z2] - m_iaCOM[z2]; m_oaAtoms[z]->m_fRelCoord[z2] = FixedToFloat(m_oaAtoms[z]->m_iRelCoord[z2],signi); } } if (ref != NULL) WriteXYZ(ref,signi); return true; } bool CBQBAtomSet::SkipXYZ(FILE *a) { char buf[256]; int i, z; (void)fgets(buf,256,a); buf[strlen(buf)-1] = 0; i = atoi(buf); (void)fgets(buf,256,a); if (feof(a)) return false; for (z=0;z. ***********************************************************************************/ #ifndef BQB_CUBEFRAME_H #define BQB_CUBEFRAME_H // This must always be the first include directive #include "bqb_config.h" #include "bqb_tools.h" #include #include #include class CBQBInterface; class CBQBAtom { public: CBQBAtom() : m_iOrd(0) { } int m_iOrd; std::string m_sLabel; double m_fCoord[3]; double m_fRelCoord[3]; long m_iCoord[3]; long m_iRelCoord[3]; }; class CBQBAtomSet { public: CBQBAtomSet() : m_bOrd(false), m_bLabels(false), m_sComment(NULL) { for (int z=0;z<3;z++) { m_faCOM[z] = 0; m_iaCOM[z] = 0; } } ~CBQBAtomSet() { for (int z=0;z<(int)m_oaAtoms.size();z++) delete m_oaAtoms[z]; if (m_sComment != NULL) delete[] m_sComment; } bool ReadXYZ(FILE *a, int signi, FILE *ref); void WriteXYZ(FILE *a, int signi); bool SkipXYZ(FILE *a); bool m_bOrd; bool m_bLabels; int m_iSigni; double m_faCOM[3]; int m_iaCOM[3]; std::vector m_oaAtoms; char *m_sComment; }; class CBQBCubeFrame { public: CBQBCubeFrame(CBQBInterface &i) : m_iResXY(0), m_iResYZ(0), m_iResXYZ(0), m_pAtoms(NULL), m_IF(i) { for (int z=0;z<3;z++) { m_iRes[z] = 0; m_fMinVal[z] = 0; m_fMaxVal[z] = 0; m_fCenter[z] = 0; m_fStrideA[z] = 0; m_fStrideB[z] = 0; m_fStrideC[z] = 0; m_iCenter[z] = 0; m_iStrideA[z] = 0; m_iStrideB[z] = 0; m_iStrideC[z] = 0; } } ~CBQBCubeFrame() { // if (m_pAtoms != NULL) // delete m_pAtoms; } void CopyHeader(const CBQBCubeFrame *p) { m_iRes[0] = p->m_iRes[0]; m_iRes[1] = p->m_iRes[1]; m_iRes[2] = p->m_iRes[2]; m_fStrideA[0] = p->m_fStrideA[0]; m_fStrideA[1] = p->m_fStrideA[1]; m_fStrideA[2] = p->m_fStrideA[2]; m_iStrideA[0] = p->m_iStrideA[0]; m_iStrideA[1] = p->m_iStrideA[1]; m_iStrideA[2] = p->m_iStrideA[2]; m_fStrideB[0] = p->m_fStrideB[0]; m_fStrideB[1] = p->m_fStrideB[1]; m_fStrideB[2] = p->m_fStrideB[2]; m_iStrideB[0] = p->m_iStrideB[0]; m_iStrideB[1] = p->m_iStrideB[1]; m_iStrideB[2] = p->m_iStrideB[2]; m_fStrideC[0] = p->m_fStrideC[0]; m_fStrideC[1] = p->m_fStrideC[1]; m_fStrideC[2] = p->m_fStrideC[2]; m_iStrideC[0] = p->m_iStrideC[0]; m_iStrideC[1] = p->m_iStrideC[1]; m_iStrideC[2] = p->m_iStrideC[2]; m_fCenter[0] = p->m_fCenter[0]; m_fCenter[1] = p->m_fCenter[1]; m_fCenter[2] = p->m_fCenter[2]; m_iCenter[0] = p->m_iCenter[0]; m_iCenter[1] = p->m_iCenter[1]; m_iCenter[2] = p->m_iCenter[2]; m_iResXY = m_iRes[0] * m_iRes[1]; m_iResYZ = m_iRes[1] * m_iRes[2]; m_iResXYZ = m_iRes[0] * m_iRes[1] * m_iRes[2]; m_faBin.resize(m_iResXYZ); m_iaExpo.resize(m_iResXYZ); m_iaMantis.resize(m_iResXYZ); } bool ReadFrame(FILE *a, int eps, int csigni, int asigni, bool verbose=false); bool SkipFrame(FILE *a, bool verbose=false) const; void WriteFrame(FILE *a, bool verbose=false); void WriteFrame_Double(FILE *a, bool verbose=false); int m_iEps; int m_iSigni; std::vector m_faBin; std::vector m_iaMantis; std::vector m_iaExpo; int m_iRes[3]; int m_iResXY; int m_iResYZ; int m_iResXYZ; double m_fMinVal[3]; double m_fMaxVal[3]; double m_fCenter[3]; double m_fStrideA[3]; double m_fStrideB[3]; double m_fStrideC[3]; long m_iCenter[3]; long m_iStrideA[3]; long m_iStrideB[3]; long m_iStrideC[3]; CBQBAtomSet *m_pAtoms; private: CBQBInterface &m_IF; }; #endif travis-src-190101/src/bqb_driver.cpp0100777000000000000000000033311613412725627014274 0ustar00/*********************************************************************************** LibBQB - File Format and Compression Algorithms for Trajectories of Volumetric Data and Atom Positions https://brehm-research.de/bqb Free software, licensed under GNU LGPL v3 Copyright (c) Martin Brehm and Martin Thomas, Martin Luther University Halle-Wittenberg, Germany, 2016 - 2019. Please cite: M. Brehm, M. Thomas: "An Efficient Lossless Compression Algorithm for Trajectories of Atom Positions and Volumetric Data", J. Chem. Inf. Model. 2018, 58 (10), pp 2092-2107. -------------------------------------------------------------------------------- LibBQB is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program. If not, see . ***********************************************************************************/ // This must always be the first include directive #include "bqb_config.h" #include "bqb_driver.h" #include "bqb_format.h" #include "bqb_integerengine.h" #include "bqb_bitset.h" #include #include const char *GetRevisionInfo_bqb_driver(unsigned int len) { static char buf[256]; GET_REVISION_INFO( buf, len ); return buf; } const char *GetSourceVersion_bqb_driver() { static char buf[256]; GET_SOURCE_VERSION( buf ); return buf; } CBQBDriver::CBQBDriver(CBQBInterface &i) : m_ParmPosAndVol(i), m_ParmPos(i), m_iHistogramCounter(0), m_iOptIncludeFirst(-1), m_IF(i) { m_pEngine = new CBQBEngine(m_IF); } CBQBDriver::~CBQBDriver() { if (m_pEngine != NULL) { delete m_pEngine; m_pEngine = NULL; } } bool CBQBDriver::CompressCube( const char *inp, const char *outp, const char *ref, int start, int steps, int stride, int keyfreq, CBQBParameterSet_PosAndVol *parm, int optimize, int optsteps, bool onlyopt, bool comment, bool compare, bool dummyread ) { const CBQBCubeFrame *cfr; CBQBCubeFrame *cfr2; int z, z2, i, k, co, ao, ft, lcsize, lasize, morder, histused, thu, vmo, pmo; double tb, tb2, tf, tf2; long insize; std::vector ia, ia2; CBQBBitSet bsat(m_IF), bscu(m_IF), bshe(m_IF), bstemp(m_IF); bool err, to; unsigned long t0, rxyz=1; CBQBFile bf(m_IF); CBQBStatistics stat(m_IF); if (parm == NULL) { m_IF.eprintf("CBQBDriver::CompressCube(): Error: parm == NULL.\n"); return false; } if (parm->GetVolUseExtra()) if (parm->GetVolExtraTRange() > parm->GetVolOrder()) parm->SetVolOrder(parm->GetVolExtraTRange()); if (parm->GetPosUseExtra()) if (parm->GetPosExtraTRange() > parm->GetPosOrder()) parm->SetPosOrder(parm->GetPosExtraTRange()); if (m_IF.IsPL(BQB_PL_STANDARD)) m_IF.printf("Opening cube file \"%s\" ...\n",inp); m_pEngine->m_pReadCacheCube = new CBQBReadCubeCache(m_IF); m_pEngine->m_pReadCacheCube->SetReadParameters(parm->GetVolEps(),parm->GetVolSigni(),parm->GetPosPrecision()); if (!m_pEngine->m_pReadCacheCube->FileOpenRead(inp,ref)) { m_IF.eprintf("Error: Could not open file for reading.\n"); return false; } if (optimize != 0) { if (MAX(parm->GetPosOrder(),parm->GetVolOrder())+1 > optsteps) m_pEngine->m_pReadCacheCube->SetHistoryDepth(MAX(parm->GetPosOrder(),parm->GetVolOrder())+1); else m_pEngine->m_pReadCacheCube->SetHistoryDepth(optsteps); m_IF.printf("\n"); m_pEngine->m_pReadCacheCube->CacheSteps(optsteps,true); m_IF.printf("\n"); if (m_iOptIncludeFirst == -1) { if ((m_pEngine->m_pReadCacheCube->GetCachedSteps() < optsteps) || (optsteps < 10)) { if (m_IF.IsPL(BQB_PL_STANDARD)) m_IF.printf(" Low step count, switching on -optstart.\n\n"); m_iOptIncludeFirst = 1; } else { if (m_IF.IsPL(BQB_PL_STANDARD)) m_IF.printf(" Large step count, switching off -optstart.\n\n"); m_iOptIncludeFirst = 0; } } m_pEngine->m_pReadCacheCube->SetStartLock(); if (!OptimizeXYZParameters( optimize, // int level, parm->GetPositionParameterSet(), comment, // bool comment, true // bool cubepart )) { m_IF.eprintf("Error: Position data parameter optimization failed.\n"); delete m_pEngine->m_pReadCacheCube; m_pEngine->m_pReadCacheCube = NULL; return false; } if (m_IF.IsPL(BQB_PL_STANDARD)) m_IF.printf("\n"); if (!OptimizeCubeParameters( optimize, // int level, parm->GetVolumetricParameterSet() )) { m_IF.eprintf("Error: Volumetric data parameter optimization failed.\n"); delete m_pEngine->m_pReadCacheCube; m_pEngine->m_pReadCacheCube = NULL; return false; } if (m_IF.IsPL(BQB_PL_STANDARD)) { m_IF.bprintf("\n The optimal parameters for this trajectory are:\n\n"); m_IF.printf("%s",parm->ToString(4).c_str()); m_IF.printf("\n"); m_IF.bprintf(" Parameter key:"); m_IF.printf(" %s\n\n",parm->ToKey().c_str()); } if (onlyopt) { m_pEngine->m_pReadCacheCube->CloseFile(); delete m_pEngine->m_pReadCacheCube; m_pEngine->m_pReadCacheCube = NULL; return true; } m_pEngine->m_pReadCacheCube->RewindReadPos(); m_pEngine->m_pReadCacheCube->LiftStartLock(); if (parm->GetVolUseExtra()) if (parm->GetVolExtraTRange() > parm->GetVolOrder()) parm->SetVolOrder(parm->GetVolExtraTRange()); if (parm->GetPosUseExtra()) if (parm->GetPosExtraTRange() > parm->GetPosOrder()) parm->SetPosOrder(parm->GetPosExtraTRange()); } else { m_pEngine->m_pReadCacheCube->SetHistoryDepth(MAX(parm->GetPosOrder(),parm->GetVolOrder())+1); } t0 = (unsigned long)time(NULL); stat.m_oStat.reset(); if (!dummyread) { if (outp != NULL) { if (m_IF.IsPL(BQB_PL_STANDARD)) m_IF.printf("Opening compressed file \"%s\" ...\n",outp); if (!bf.OpenWriteAppend(outp)) { m_IF.eprintf("Error: Could not open file for writing.\n"); m_pEngine->m_pReadCacheCube->CloseFile(); delete m_pEngine->m_pReadCacheCube; m_pEngine->m_pReadCacheCube = NULL; return false; } } } else { ref = NULL; outp = NULL; if (m_IF.IsPL(BQB_PL_STANDARD)) m_IF.printf("Dummy Read Mode (no compression / output is performed).\n"); } m_pEngine->m_oaOutputCubeBuf.resize(parm->GetVolOrder()+1); for (z=0;zGetVolOrder()+1;z++) m_pEngine->m_oaOutputCubeBuf[z] = NULL; m_pEngine->m_iOutputCubeBufPos = 0; m_pEngine->m_oaOutputAtomBuf.resize(parm->GetPosOrder()+1); for (z=0;zGetPosOrder()+1;z++) m_pEngine->m_oaOutputAtomBuf[z] = NULL; m_pEngine->m_iOutputAtomBufPos = 0; if (m_IF.IsPL(BQB_PL_STANDARD)) m_IF.printf("Starting process...\n"); if (start != 0) { if (m_IF.IsPL(BQB_PL_STANDARD)) m_IF.printf("Fast-forwarding to step %d: ",start+1); for (z=0;zm_pReadCacheCube->SkipOneStep()) { m_pEngine->m_pReadCacheCube->CloseFile(); delete m_pEngine->m_pReadCacheCube; m_pEngine->m_pReadCacheCube = NULL; return false; } if (m_IF.IsPL(BQB_PL_STANDARD)) { m_IF.printf("."); m_IF.FlushLog(); } } if (m_IF.IsPL(BQB_PL_STANDARD)) m_IF.printf(" Done.\n"); } if (parm->GetVolUseExtra()) vmo = parm->GetVolExtraTRange(); else vmo = parm->GetVolOptOrder(); if (parm->GetPosUseExtra()) pmo = parm->GetPosExtraTRange(); else pmo = parm->GetPosOptOrder(); morder = vmo; if (pmo > morder) morder = pmo; stat.ResetStatistics(); err = false; i = 0; k = 0; tb = 0; tb2 = 0; tf = 0; tf2 = 0; to = false; if (parm->GetVolOptOrder() && !parm->GetVolUseExtra()) lcsize = 1000000000; else lcsize = -1; if (parm->GetPosOptOrder() && !parm->GetPosUseExtra()) lasize = 1000000000; else lasize = -1; while (true) { if (m_IF.IsPL(BQB_PL_VERBOSE)) m_IF.printf("\n\n"); if (m_IF.IsPL(BQB_PL_STANDARD)) { if (i != 0) m_IF.printf(" Step %6d ... (avg %5.1f s/step)\n",i+1,((double)(time(NULL)-t0))/i); else m_IF.printf(" Step %6d ...\n",i+1); } cfr = m_pEngine->m_pReadCacheCube->GetNextFrame(); if (cfr == NULL) { if (m_IF.IsPL(BQB_PL_STANDARD)) m_IF.printf(" Reached end of input trajectory.\n"); break; } if (i == 0) { rxyz = cfr->m_iResXYZ; if (parm->GetVolUseExtra()) { if (parm->GetVolExtraPredCorr()) { if (m_IF.IsPL(BQB_PL_STANDARD)) m_IF.printf(" Initializing Volumetric Predictor Extrapolator (%d/%d)...\n", parm->GetVolExtraTRange(),parm->GetVolExtraTOrder()); m_pEngine->m_pExtrapolator = new CBQBExtrapolator(m_IF); m_pEngine->m_pExtrapolator->Initialize( cfr->m_iRes[0], // resx, cfr->m_iRes[1], // resy, cfr->m_iRes[2], // resz, 1, // srangex, 1, // srangey, 1, // srangez, parm->GetVolExtraTRange(), // trange, 0, // sorder, parm->GetVolExtraTOrder(), // torder, 0, // offsetx, 0, // offsety, 0, // offsetz, false, // crosss, false, // crosst, false, // wrap, false, // crossranges, false, // crossranget 0, // distexpo parm->GetVolExtraTimeExpo(), // timeexpo false ); if (m_IF.IsPL(BQB_PL_STANDARD)) { if (parm->IsVolExtraSRangeXYZEqual()) m_IF.printf(" Initializing Volumetric Corrector Extrapolator (%d/%d)...\n", parm->GetVolExtraSRangeX(),parm->GetVolExtraSOrder()); else m_IF.printf(" Initializing Volumetric Corrector Extrapolator (%d|%d|%d/%d)...\n", parm->GetVolExtraSRangeX(),parm->GetVolExtraSRangeY(),parm->GetVolExtraSRangeZ(),parm->GetVolExtraSOrder()); } m_pEngine->m_pExtrapolatorCorr = new CBQBExtrapolator(m_IF); m_pEngine->m_pExtrapolatorCorr->Initialize( cfr->m_iRes[0], // resx, cfr->m_iRes[1], // resy, cfr->m_iRes[2], // resz, parm->GetVolExtraSRangeX(), // srangex, parm->GetVolExtraSRangeY(), // srangey, parm->GetVolExtraSRangeZ(), // srangez, 1, // trange, parm->GetVolExtraSOrder(), // sorder, 0, // torder, parm->GetVolExtraOffsetX(), // offsetx, parm->GetVolExtraOffsetY(), // offsety, parm->GetVolExtraOffsetZ(), // offsetz, parm->GetVolExtraCrossS(), // crosss, false, // crosst, parm->GetVolExtraWrap(), // wrap, parm->GetVolExtraCrossRangeS(), // crossranges, false, // crossranget parm->GetVolExtraDistExpo(), // distexpo 0, // timeexpo false ); } else { if (m_IF.IsPL(BQB_PL_STANDARD)) { if (parm->IsVolExtraSRangeXYZEqual()) m_IF.printf(" Initializing Volumetric Extrapolator (%d/%d;%d/%d)...\n", parm->GetVolExtraSRangeX(), parm->GetVolExtraSOrder(), parm->GetVolExtraTRange(), parm->GetVolExtraTOrder() ); else m_IF.printf(" Initializing Volumetric Extrapolator (%d|%d|%d/%d;%d|%d)...\n", parm->GetVolExtraSRangeX(), parm->GetVolExtraSRangeY(), parm->GetVolExtraSRangeZ(), parm->GetVolExtraSOrder(), parm->GetVolExtraTRange(), parm->GetVolExtraTOrder() ); } m_pEngine->m_pExtrapolator = new CBQBExtrapolator(m_IF); m_pEngine->m_pExtrapolator->Initialize( cfr->m_iRes[0], // resx, cfr->m_iRes[1], // resy, cfr->m_iRes[2], // resz, parm->GetVolExtraSRangeX(), // srangex, parm->GetVolExtraSRangeY(), // srangey, parm->GetVolExtraSRangeZ(), // srangez, parm->GetVolExtraTRange(), // trange, parm->GetVolExtraSOrder(), // sorder, parm->GetVolExtraTOrder(), // torder, parm->GetVolExtraOffsetX(), // offsetx, parm->GetVolExtraOffsetY(), // offsety, parm->GetVolExtraOffsetZ(), // offsetz, parm->GetVolExtraCrossS(), // crosss, parm->GetVolExtraCrossT(), // crosst, parm->GetVolExtraWrap(), // wrap, parm->GetVolExtraCrossRangeS(), // crossranges, parm->GetVolExtraCrossRangeT(), // crossranget parm->GetVolExtraDistExpo(), // distexpo parm->GetVolExtraTimeExpo(), // timeexpo false ); } } if (parm->GetPosUseExtra()) { if (m_IF.IsPL(BQB_PL_STANDARD)) m_IF.printf(" Initializing Position Extrapolator (%d/%d)...\n", parm->GetPosExtraTRange(),parm->GetPosExtraTOrder()); m_pEngine->m_pExtrapolatorXYZ = new CBQBExtrapolator(m_IF); m_pEngine->m_pExtrapolatorXYZ->InitializeXYZ( parm->GetPosExtraTRange(), parm->GetPosExtraTOrder(), parm->GetPosExtraTimeExpo(), false ); } } for (z=0;zm_pReadCacheCube->SkipOneStep()) { if (m_IF.IsPL(BQB_PL_STANDARD)) m_IF.printf(" Reached end of input trajectory.\n"); break; } } if (dummyread) // Just benchmark the CUBE reading speed goto _dummy; if (m_pEngine->m_pExtrapolator != NULL) m_pEngine->m_pExtrapolator->PushCubeFrame(cfr); if (m_pEngine->m_pExtrapolatorXYZ != NULL) m_pEngine->m_pExtrapolatorXYZ->PushAtomFrame(cfr->m_pAtoms); if ((i != 0) && (keyfreq != 0) && ((i % keyfreq) == 0)) { if (m_IF.IsPL(BQB_PL_STANDARD)) m_IF.printf(" Enforcing key frame.\n"); k = 0; // Enforce this frame to be a keyframe } _again: if (i < vmo) co = i; else if (k < vmo) co = k; else co = vmo; if (i < pmo) ao = i; else if (k < pmo) ao = k; else ao = pmo; _aagain: bsat.Clear(); stat.PushStatistics(); histused = 0; m_pEngine->CompressAtomFrame( &bsat, ao, parm->GetPositionParameterSet(), histused, (i==0), // Store static trajectory information? comment, &stat ); if (m_IF.IsPL(BQB_PL_STANDARD)) { if (m_pEngine->m_pExtrapolatorXYZ == NULL) m_IF.printf(" Atoms: Order %d, output size %9.3f KiB.\n",ao,bsat.GetByteLength()/1024.0); else m_IF.printf(" Atoms: History %2d, output size %9.3f KiB.\n",histused,bsat.GetByteLength()/1024.0); } if (lasize >= 0) { if (to) { to = false; if (bsat.GetByteLength() <= bstemp.GetByteLength()) { if (m_IF.IsPL(BQB_PL_STANDARD)) m_IF.printf(" Size is indeed smaller with lower order. Limiting atom order to %d.\n",ao); stat.PopDiffStatistics(); parm->SetPosOrder(ao); pmo = ao; lasize = -1; } else { if (m_IF.IsPL(BQB_PL_STANDARD)) m_IF.printf(" Size was smaller with higher order. Not limiting.\n"); stat.PopStatistics(); bsat = bstemp; lasize = bsat.GetByteLength(); } } else { if ((ao != 0) && ((double)bsat.GetByteLength() >= (double)lasize*0.97)) { if (m_IF.IsPL(BQB_PL_STANDARD)) m_IF.printf(" Size did not decrease any further with order %d. Trying order %d...\n",ao,ao-1); bstemp = CBQBBitSet(bsat); to = true; ao--; goto _aagain; } else if (ao == pmo) lasize = -1; else lasize = bsat.GetByteLength(); } } stat.PopIgnoreStatistics(); _cagain: bscu.Clear(); stat.PushStatistics(); m_pEngine->CompressCubeFrame( &bscu, co, parm->GetVolumetricParameterSet(), thu, (i==0), // Store static info? &stat ); if (thu > histused) histused = thu; if (m_IF.IsPL(BQB_PL_STANDARD)) { if (m_pEngine->m_pExtrapolator == NULL) m_IF.printf(" Cube: Order %d, output size %9.3f KiB.\n",co,bscu.GetByteLength()/1024.0); else m_IF.printf(" Cube: History %2d, output size %9.3f KiB.\n",thu,bscu.GetByteLength()/1024.0); } if (lcsize >= 0) { if (to) { to = false; if (bscu.GetByteLength() <= bstemp.GetByteLength()) { if (m_IF.IsPL(BQB_PL_STANDARD)) m_IF.printf(" Size is indeed smaller with lower order. Limiting cube order to %d.\n",co); stat.PopDiffStatistics(); parm->SetVolOrder(co); vmo = co; lcsize = -1; } else { if (m_IF.IsPL(BQB_PL_STANDARD)) m_IF.printf(" Size was smaller with higher order. Not limiting.\n"); stat.PopStatistics(); bscu = CBQBBitSet(bstemp); lcsize = bscu.GetByteLength(); } } else { if ((co != 0) && ((double)bscu.GetByteLength() >= (double)lcsize*0.97)) { if (m_IF.IsPL(BQB_PL_STANDARD)) m_IF.printf(" Size did not decrease any further with order %d. Trying order %d...\n",co,co-1); bstemp = CBQBBitSet(bscu); to = true; co--; goto _cagain; } else if (co == vmo) lcsize = -1; else lcsize = bscu.GetByteLength(); } } stat.PopIgnoreStatistics(); if (MAX(pmo,vmo) < morder) morder = MAX(pmo,vmo); if (compare) { cfr2 = new CBQBCubeFrame(m_IF); m_pEngine->PushOutputCubeFrame(cfr2); cfr2->m_pAtoms = new CBQBAtomSet(); m_pEngine->PushOutputAtomFrame(cfr2->m_pAtoms); m_pEngine->DecompressAtomFrame( &bsat, BQB_FRAMETYPE_COMPTRAJ_VERSION, parm->GetPositionParameterSet(), NULL, // histused false, true ); m_pEngine->DecompressCubeFrame( &bscu, BQB_FRAMETYPE_COMPCUBE_VERSION, parm->GetVolumetricParameterSet(), NULL, // histused false, true ); if (m_IF.IsPL(BQB_PL_VERBOSE)) m_IF.printf("Comparing input and output...\n"); for (z=0;z<(int)cfr2->m_pAtoms->m_oaAtoms.size();z++) for (z2=0;z2<3;z2++) if (cfr->m_pAtoms->m_oaAtoms[z]->m_iCoord[z2] != cfr2->m_pAtoms->m_oaAtoms[z]->m_iCoord[z2]) { m_IF.eprintf(" Error in atom coordinate %d[%d]: %.6f (%ld) != %.6f (%ld)\n", z,z2,cfr->m_pAtoms->m_oaAtoms[z]->m_fCoord[z2],cfr->m_pAtoms->m_oaAtoms[z]->m_iCoord[z2], cfr2->m_pAtoms->m_oaAtoms[z]->m_fCoord[z2],cfr2->m_pAtoms->m_oaAtoms[z]->m_iCoord[z2]); err = true; goto _skerr; } for (z=0;zm_iResXYZ;z++) if (!ExpMantisEqual(cfr->m_iaExpo[z],cfr->m_iaMantis[z],cfr2->m_iaExpo[z],cfr2->m_iaMantis[z])) { m_IF.eprintf(" Error in volumetric data element %7d: %.10G vs %.10G\n", z,cfr->m_faBin[z],cfr2->m_faBin[z]); err = true; goto _skerr; } _skerr: if (err) { if (k != 0) { m_IF.eprintf("Errors occured. Compressing frame again with history zero.\n"); err = false; k = 0; goto _again; } else { m_IF.eprintf("Errors occured despite of zero history. Aborting.\n"); goto _end; } } if (m_IF.IsPL(BQB_PL_VERBOSE)) m_IF.printf("Done.\n"); } bshe.Clear(); bshe.WriteBits(bsat.GetByteLength(),32); bshe.WriteBits(bscu.GetByteLength(),32); tb += bshe.GetByteLength(); tb += bsat.GetByteLength(); tb += bscu.GetByteLength(); tf++; stat.m_oStat.m_lOverhead += bshe.GetLength(); if ((bsat.GetLength()%8) != 0) stat.m_oStat.m_lOverhead += 8 - (bsat.GetLength()%8); if ((bscu.GetLength()%8) != 0) stat.m_oStat.m_lOverhead += 8 - (bscu.GetLength()%8); if (i >= morder) { tb2 += bshe.GetByteLength(); tb2 += bsat.GetByteLength(); tb2 += bscu.GetByteLength(); tf2++; } if (outp != NULL) { if (i == 0) ft = BQB_FRAMETYPE_COMPCUBESTART; else if (k == 0) ft = BQB_FRAMETYPE_COMPCUBEKEY; else ft = BQB_FRAMETYPE_COMPCUBE; bf.CreateShortFrame( ft, BQB_FRAMETYPE_COMPCUBE_VERSION, i+1 ); bf.PushPayload(bshe.m_iaData); bf.PushPayload(bsat.m_iaData); bf.PushPayload(bscu.m_iaData); bf.FinalizeFrame(&stat); } _dummy: i++; k++; if (i == steps) break; } if (outp != NULL) bf.WriteIndexFrame(true,&stat); _end: if (outp != NULL) bf.Close(); insize = m_pEngine->m_pReadCacheCube->ftell(); m_pEngine->m_pReadCacheCube->CloseFile(); delete m_pEngine->m_pReadCacheCube; m_pEngine->m_pReadCacheCube = NULL; if (m_pEngine->m_pExtrapolator != NULL) { delete m_pEngine->m_pExtrapolator; m_pEngine->m_pExtrapolator = NULL; } if (m_pEngine->m_pExtrapolatorCorr != NULL) { delete m_pEngine->m_pExtrapolatorCorr; m_pEngine->m_pExtrapolatorCorr = NULL; } if (m_pEngine->m_pExtrapolatorXYZ != NULL) { delete m_pEngine->m_pExtrapolatorXYZ; m_pEngine->m_pExtrapolatorXYZ = NULL; } if (err) { if (m_IF.IsPL(BQB_PL_STANDARD)) m_IF.eprintf("Errors occurred while compressing the cube file.\n"); return false; } else if (m_IF.IsPL(BQB_PL_STANDARD)) { m_IF.printf("Finished compressing the cube file.\n\n"); m_IF.printf("%10.3f MiB (%12s Bytes) overhead.\n", double(stat.m_oStat.m_lOverhead)/1024.0/1024.0/8.0, (stat.m_oStat.m_lOverhead>>3).string()); m_IF.printf("%10.3f MiB (%12s Bytes) alphabet data.\n", double(stat.m_oStat.m_lAlphabet)/1024.0/1024.0/8.0, (stat.m_oStat.m_lAlphabet>>3).string()); m_IF.printf("%10.3f MiB (%12s Bytes) Huffman tables.\n", double(stat.m_oStat.m_lHuffmanTables)/1024.0/1024.0/8.0, (stat.m_oStat.m_lHuffmanTables>>3).string()); m_IF.printf("%10.3f MiB (%12s Bytes) table switching.\n", double(stat.m_oStat.m_lTableSwitch)/1024.0/1024.0/8.0, (stat.m_oStat.m_lTableSwitch>>3).string()); m_IF.printf("%10.3f MiB (%12s Bytes) payload data.\n", double(stat.m_oStat.m_lHuffmanData)/1024.0/1024.0/8.0, (stat.m_oStat.m_lHuffmanData>>3).string()); m_IF.printf("%10.3f MiB (%12s Bytes) in total.\n\n", double(stat.m_oStat.m_lOverhead+stat.m_oStat.m_lAlphabet+stat.m_oStat.m_lHuffmanTables+stat.m_oStat.m_lTableSwitch+stat.m_oStat.m_lHuffmanData)/1024.0/1024.0/8.0, ((stat.m_oStat.m_lOverhead+stat.m_oStat.m_lAlphabet+stat.m_oStat.m_lHuffmanTables+stat.m_oStat.m_lTableSwitch+stat.m_oStat.m_lHuffmanData)>>3).string()); if (tf > 0) { m_IF.bprintf("\n * Totals:\n"); m_IF.printf(" %9.3f KiB per frame on average.\n",tb/1024.0/tf); m_IF.printf(" %9.3f bits per bin entry on average.\n",tb/tf/rxyz*8.0); m_IF.printf(" Compression ratio of %.3f : 1\n",(double)insize/tb); } if (tf2 > 0) { m_IF.bprintf("\n * Starting from step %d:\n",morder+1); m_IF.printf(" %9.3f KiB per frame on average.\n",tb2/1024.0/tf2); m_IF.printf(" %9.3f bits per bin entry on average.\n",(tb2/tf2)/rxyz*8.0); m_IF.printf(" Compression ratio of %.3f : 1\n",((double)insize/tf*tf2)/tb2); } m_IF.printf("\n"); } return true; } double CBQBDriver::CompressCubeBenchmark( CBQBParameterSet_Volumetric *parm, bool realsize, double *presi, std::vector > *tciaa ) { const CBQBCubeFrame *cfr; int i, co, histused; double tb, tf, resi, tresi; CBQBBitSet bscu(m_IF); unsigned long t0, rxyz=1; if (parm == NULL) { m_IF.eprintf("CBQBDriver::CompressCube(): Error: parm == NULL.\n"); return false; } resi = 0; t0 = (unsigned long)time(NULL); if (parm->GetUseExtra()) if (parm->GetExtraTRange() > parm->GetOrder()) parm->SetOrder(parm->GetExtraTRange()); if (m_IF.IsPL(BQB_PL_VERBOSE)) m_IF.printf("Starting process...\n"); m_pEngine->m_pReadCacheCube->RewindReadPos(); i = 0; tb = 0; tf = 0; while (true) { if (m_IF.IsPL(BQB_PL_DEBUG)) m_IF.printf("\n\n"); if (m_IF.IsPL(BQB_PL_VERBOSE)) { if (i != 0) m_IF.printf(" Step %6d ... (avg %5.1f s/step)\n", i+1,((double)(time(NULL)-t0))/i); else m_IF.printf(" Step %6d ...\n",i+1); } cfr = m_pEngine->m_pReadCacheCube->GetNextFrame(); if (cfr == NULL) break; if (i == 0) { rxyz = cfr->m_iResXYZ; if (parm->GetUseExtra()) { if (parm->GetExtraPredCorr()) { if (m_IF.IsPL(BQB_PL_VERBOSE)) m_IF.printf(" Initializing Predictor Extrapolator...\n"); m_pEngine->m_pExtrapolator = new CBQBExtrapolator(m_IF); m_pEngine->m_pExtrapolator->Initialize( cfr->m_iRes[0], // resx, cfr->m_iRes[1], // resy, cfr->m_iRes[2], // resz, 1, // srangex, 1, // srangey, 1, // srangez, parm->GetExtraTRange(), // trange, 0, // sorder, parm->GetExtraTOrder(), // torder, 0, // offsetx, 0, // offsety, 0, // offsetz, false, // crosss, false, // crosst, false, // wrap, false, // crossranges, false, // crossranget 0, // distexpo parm->GetExtraTimeExpo(), // timeexpo !m_IF.IsPL(BQB_PL_VERBOSE) ); if (m_IF.IsPL(BQB_PL_VERBOSE)) m_IF.printf(" Initializing Corrector Extrapolator...\n"); m_pEngine->m_pExtrapolatorCorr = new CBQBExtrapolator(m_IF); m_pEngine->m_pExtrapolatorCorr->Initialize( cfr->m_iRes[0], // resx, cfr->m_iRes[1], // resy, cfr->m_iRes[2], // resz, parm->GetExtraSRangeX(), // srangex, parm->GetExtraSRangeY(), // srangey, parm->GetExtraSRangeZ(), // srangez, 1, // trange, parm->GetExtraSOrder(), // sorder, 0, // torder, parm->GetExtraOffsetX(), // offsetx, parm->GetExtraOffsetY(), // offsety, parm->GetExtraOffsetZ(), // offsetz, parm->GetExtraCrossS(), // crosss, false, // crosst, parm->GetExtraWrap(), // wrap, parm->GetExtraCrossRangeS(), // crossranges, false, // crossranget parm->GetExtraDistExpo(), // distexpo 0, // timeexpo !m_IF.IsPL(BQB_PL_VERBOSE) ); } else { if (m_IF.IsPL(BQB_PL_VERBOSE)) m_IF.printf(" Initializing Extrapolator...\n"); m_pEngine->m_pExtrapolator = new CBQBExtrapolator(m_IF); m_pEngine->m_pExtrapolator->Initialize( cfr->m_iRes[0], // resx, cfr->m_iRes[1], // resy, cfr->m_iRes[2], // resz, parm->GetExtraSRangeX(), // srangex, parm->GetExtraSRangeY(), // srangey, parm->GetExtraSRangeZ(), // srangez, parm->GetExtraTRange(), // trange, parm->GetExtraSOrder(), // sorder, parm->GetExtraTOrder(), // torder, parm->GetExtraOffsetX(), // offsetx, parm->GetExtraOffsetY(), // offsety, parm->GetExtraOffsetZ(), // offsetz, parm->GetExtraCrossS(), // crosss, parm->GetExtraCrossT(), // crosst, parm->GetExtraWrap(), // wrap, parm->GetExtraCrossRangeS(), // crossranges, parm->GetExtraCrossRangeT(), // crossranget parm->GetExtraDistExpo(), // distexpo parm->GetExtraTimeExpo(), // timeexpo !m_IF.IsPL(BQB_PL_VERBOSE) ); } } } if (m_pEngine->m_pExtrapolator != NULL) m_pEngine->m_pExtrapolator->PushCubeFrame(cfr); if (i < parm->GetOrder()) co = i; else co = parm->GetOrder(); if ((i+1 > parm->GetExtraTRange()) || (m_iOptIncludeFirst > 0)) { bscu.Clear(); m_pEngine->CompressCubeFrame( &bscu, co, parm, histused, (i==0), // Store static info NULL, !realsize, &tresi, tciaa ); resi += tresi; tf++; if (realsize) { tb += bscu.GetByteLength(); /* if (m_fResiCorrFrame != NULL) { mfprintf(m_fResiCorrFrame,"%.3f; %.3f; %d\n", bscu.GetByteLength()/1024.0, mypow( tresi / rxyz, 1.0/m_fEntropyExpoCube ), m_iHistogramCounter-1 ); fflush(m_fResiCorrFrame); }*/ } } i++; if (m_pEngine->m_pReadCacheCube->GetCachedSteps() == 0) break; } if (m_pEngine->m_pExtrapolator != NULL) { delete m_pEngine->m_pExtrapolator; m_pEngine->m_pExtrapolator = NULL; } if (m_pEngine->m_pExtrapolatorCorr != NULL) { delete m_pEngine->m_pExtrapolatorCorr; m_pEngine->m_pExtrapolatorCorr = NULL; } if (m_pEngine->m_pExtrapolatorXYZ != NULL) { delete m_pEngine->m_pExtrapolatorXYZ; m_pEngine->m_pExtrapolatorXYZ = NULL; } resi = bqbpow2( resi / (tf * rxyz) ); if (presi != NULL) *presi = resi; if (realsize) { /* if (m_fResiCorrTraj != NULL) { mfprintf(m_fResiCorrTraj,"%.4f; %.4f\n", tb / tf / 1024.0, resi ); fflush(m_fResiCorrTraj); }*/ return tb / tf / 1024.0; } else return resi; } double CBQBDriver::OptimizeCube_ObjectiveTExpo(double texpo) { double entropy, resi; m_pVolParm->SetExtraTimeExpo(texpo); entropy = CompressCubeBenchmark( m_pVolParm, m_bOptCubeRealSize, // bool realsize &resi, // double *presi NULL // std::vector > *tciaa ); if (m_IF.IsPL(BQB_PL_STANDARD)) { if (m_bOptCubeRealSize) m_IF.printf(" %2d %2d %2d %2d %6.3f %6.3f %14.4f (%10.3f kiB)\n", m_pVolParm->GetExtraSRangeX(), m_pVolParm->GetExtraSOrder(), m_pVolParm->GetExtraTRange(), m_pVolParm->GetExtraTOrder(), m_pVolParm->GetExtraDistExpo(), texpo, resi, entropy ); else m_IF.printf(" %2d %2d %2d %2d %6.3f %6.3f %14.4f\n", m_pVolParm->GetExtraSRangeX(), m_pVolParm->GetExtraSOrder(), m_pVolParm->GetExtraTRange(), m_pVolParm->GetExtraTOrder(), m_pVolParm->GetExtraDistExpo(), texpo, entropy ); } return entropy; } double CBQBDriver::OptimizeCube_ObjectiveSExpo(double sexpo) { double entropy, resi; m_pVolParm->SetExtraDistExpo(sexpo); entropy = CompressCubeBenchmark( m_pVolParm, m_bOptCubeRealSize, // bool realsize &resi, // double *presi NULL // std::vector > *tciaa ); if (m_IF.IsPL(BQB_PL_STANDARD)) { if (m_bOptCubeRealSize) m_IF.printf(" %2d %2d %2d %2d %6.3f %6.3f %14.4f (%10.3f kiB)\n", m_pVolParm->GetExtraSRangeX(), m_pVolParm->GetExtraSOrder(), m_pVolParm->GetExtraTRange(), m_pVolParm->GetExtraTOrder(), sexpo, m_pVolParm->GetExtraTimeExpo(), resi, entropy ); else m_IF.printf(" %2d %2d %2d %2d %6.3f %6.3f %14.4f\n", m_pVolParm->GetExtraSRangeX(), m_pVolParm->GetExtraSOrder(), m_pVolParm->GetExtraTRange(), m_pVolParm->GetExtraTOrder(), sexpo, m_pVolParm->GetExtraTimeExpo(), entropy ); } return entropy; } class VARPARAMS{ public: VARPARAMS(int srx, int sry, int srz, int so, int ofx, int ofy, int ofz, int tr, int to, double de, double te) : srangex(srx), srangey(sry), srangez(srz), sorder(so), offsetx(ofx), offsety(ofy), offsetz(ofz), trange(tr), torder(to), distexp(de), timeexp(te) { } bool operator < (const VARPARAMS& v) const { UNUSED(v); return true; } int srangex; int srangey; int srangez; int sorder; int offsetx; int offsety; int offsetz; int trange; int torder; double distexp; double timeexp; }; bool CBQBDriver::OptimizeCubeParameters( int level, CBQBParameterSet_Volumetric *parm ) { int steps, z, z2, z3, ti, zsr,zso, btr, bto, bsrx, bsry, bsrz, bsofx, bsofy, bsofz, bso, ca, bi; int zsrx, zsry, zsrz, zsofx, zsofy, zsofz; int tia[12]; double tf, tflast, btv, resi, tfa[12], tfa2[12], fac; bool realsize; unsigned long t0; const CBQBCubeFrame *cfr; char buf[256]; std::vector > rlist; std::vector > rlist2, rlist3; std::vector > tciaa; std::vector iatc, iabl; CBQBBitSet bs(m_IF); CBQBIntegerEngine *tie; if (m_IF.IsPL(BQB_PL_STANDARD)) m_IF.bprintf(" >>> Volumetric Trajectory Parameter Optimization >>>\n"); /* if (level == 3) { m_fResiCorrFrame = OpenFileWrite("corrframecube.csv",true); m_fResiCorrTraj = OpenFileWrite("corrtrajcube.csv",true); }*/ if (level >= 3) realsize = true; else realsize = false; t0 = (unsigned long)time(NULL); m_pEngine->m_pReadCacheCube->RewindReadPos(); cfr = m_pEngine->m_pReadCacheCube->GetNextFrame(); if (parm->GetHilbert()) m_pEngine->BuildHilbertIdx(cfr->m_iRes[0],cfr->m_iRes[1],cfr->m_iRes[2]/*,verbose*/); m_pEngine->m_pReadCacheCube->RewindReadPos(); steps = m_pEngine->m_pReadCacheCube->GetCachedSteps(); if (m_IF.IsPL(BQB_PL_STANDARD)) { m_IF.printf(" Optimization level %d\n",level); m_IF.printf(" Have %d cached steps.\n",steps); m_IF.printf(" SR SO TR TO DistExp TimeExp Residuum\n"); } tflast = 0; btv = 1.0e30; tf = 0; btr = -1; bto = -1; bsrx = -1; bsry = -1; bsrz = -1; bsofx = -1; bsofy = -1; bsofz = -1; bso = -1; parm->SetUseExtra(true); //cextratimeexpo = 1.0; //cextradistexpo = 3.0; parm->SetExtraSOrder(0); parm->SetExtraSRange(1); parm->SetExtraOffset(0); if (level == 2) parm->SetTableCount(1); /********************* Separate Code Block for Level 1 *************************************************/ if (level == 1) { rlist2.clear(); switch(steps) { case 1: // RX RY RZ SO OX OY OZ TR TO SE TE rlist2.push_back( std::pair( 0, VARPARAMS( 7, 7, 7, 4, 3, 3, 3, 1, 0, 3.5, 1.5 ) ) ); rlist2.push_back( std::pair( 0, VARPARAMS( 7, 7, 7, 5, 3, 3, 3, 1, 0, 3.5, 1.5 ) ) ); rlist2.push_back( std::pair( 0, VARPARAMS( 7, 7, 7, 6, 3, 3, 3, 1, 0, 3.5, 1.5 ) ) ); rlist2.push_back( std::pair( 0, VARPARAMS( 5, 7, 7, 3, 2, 2, 2, 1, 0, 3.5, 1.5 ) ) ); rlist2.push_back( std::pair( 0, VARPARAMS( 5, 5, 5, 2, 2, 2, 2, 1, 0, 3.5, 1.5 ) ) ); rlist2.push_back( std::pair( 0, VARPARAMS( 3, 3, 3, 2, 1, 1, 1, 1, 0, 3.5, 1.5 ) ) ); break; case 2: // RX RY RZ SO OX OY OZ TR TO SE TE rlist2.push_back( std::pair( 0, VARPARAMS( 7, 7, 7, 4, 3, 3, 3, 2, 0, 3.5, 1.5 ) ) ); rlist2.push_back( std::pair( 0, VARPARAMS( 7, 7, 7, 4, 3, 3, 3, 1, 0, 3.5, 1.5 ) ) ); rlist2.push_back( std::pair( 0, VARPARAMS( 7, 7, 7, 5, 3, 3, 3, 2, 0, 3.5, 1.5 ) ) ); rlist2.push_back( std::pair( 0, VARPARAMS( 7, 7, 7, 5, 3, 3, 3, 1, 0, 3.5, 1.5 ) ) ); rlist2.push_back( std::pair( 0, VARPARAMS( 5, 5, 5, 3, 2, 2, 2, 2, 0, 3.5, 1.5 ) ) ); rlist2.push_back( std::pair( 0, VARPARAMS( 3, 3, 3, 2, 1, 1, 1, 2, 0, 3.5, 1.5 ) ) ); break; case 3: // RX RY RZ SO OX OY OZ TR TO SE TE rlist2.push_back( std::pair( 0, VARPARAMS( 7, 7, 7, 4, 3, 3, 3, 3, 1, 3.5, 1.5 ) ) ); rlist2.push_back( std::pair( 0, VARPARAMS( 7, 7, 7, 4, 3, 3, 3, 2, 0, 3.5, 1.5 ) ) ); rlist2.push_back( std::pair( 0, VARPARAMS( 7, 7, 7, 4, 3, 3, 3, 1, 0, 3.5, 1.5 ) ) ); rlist2.push_back( std::pair( 0, VARPARAMS( 7, 7, 7, 5, 3, 3, 3, 2, 0, 3.5, 1.5 ) ) ); rlist2.push_back( std::pair( 0, VARPARAMS( 7, 7, 7, 5, 3, 3, 3, 1, 0, 3.5, 1.5 ) ) ); rlist2.push_back( std::pair( 0, VARPARAMS( 5, 5, 5, 3, 2, 2, 2, 3, 1, 3.5, 1.5 ) ) ); break; case 4: // RX RY RZ SO OX OY OZ TR TO SE TE rlist2.push_back( std::pair( 0, VARPARAMS( 7, 7, 7, 4, 3, 3, 3, 4, 1, 3.5, 1.5 ) ) ); rlist2.push_back( std::pair( 0, VARPARAMS( 7, 7, 7, 4, 3, 3, 3, 2, 0, 3.5, 1.5 ) ) ); rlist2.push_back( std::pair( 0, VARPARAMS( 7, 7, 7, 4, 3, 3, 3, 1, 0, 3.5, 1.5 ) ) ); rlist2.push_back( std::pair( 0, VARPARAMS( 7, 7, 7, 5, 3, 3, 3, 1, 0, 3.5, 1.5 ) ) ); rlist2.push_back( std::pair( 0, VARPARAMS( 7, 7, 7, 5, 3, 3, 3, 2, 0, 3.5, 1.5 ) ) ); rlist2.push_back( std::pair( 0, VARPARAMS( 5, 5, 5, 3, 2, 2, 2, 4, 1, 3.5, 1.5 ) ) ); break; default: // RX RY RZ SO OX OY OZ TR TO SE TE rlist2.push_back( std::pair( 0, VARPARAMS( 7, 7, 7, 4, 3, 3, 3, 5, 1, 3.5, 1.5 ) ) ); rlist2.push_back( std::pair( 0, VARPARAMS( 7, 7, 7, 4, 3, 3, 3, 2, 0, 3.5, 1.5 ) ) ); rlist2.push_back( std::pair( 0, VARPARAMS( 7, 7, 7, 4, 3, 3, 3, 1, 0, 3.5, 1.5 ) ) ); rlist2.push_back( std::pair( 0, VARPARAMS( 7, 7, 7, 5, 3, 3, 3, 1, 0, 3.5, 1.5 ) ) ); rlist2.push_back( std::pair( 0, VARPARAMS( 7, 7, 7, 5, 3, 3, 3, 2, 0, 3.5, 1.5 ) ) ); rlist2.push_back( std::pair( 0, VARPARAMS( 5, 5, 5, 3, 2, 2, 2, 4, 1, 3.5, 1.5 ) ) ); break; } for (z=0;z<(int)rlist2.size();z++) { parm->SetExtraSRangeX(rlist2[z].second.srangex); parm->SetExtraSRangeY(rlist2[z].second.srangey); parm->SetExtraSRangeZ(rlist2[z].second.srangez); parm->SetExtraTRange(rlist2[z].second.trange); parm->SetExtraSOrder(rlist2[z].second.sorder); parm->SetExtraTOrder(rlist2[z].second.torder); parm->SetExtraOffsetX(rlist2[z].second.offsetx); parm->SetExtraOffsetY(rlist2[z].second.offsety); parm->SetExtraOffsetZ(rlist2[z].second.offsetz); parm->SetExtraDistExpo(rlist2[z].second.distexp); parm->SetExtraTimeExpo(rlist2[z].second.timeexp); tf = CompressCubeBenchmark( parm, false, // bool realsize &resi, // double *presi NULL // std::vector > *tciaa ); if (m_IF.IsPL(BQB_PL_STANDARD)) m_IF.printf(" %2d %2d %2d %2d %6.3f %6.3f %14.4f", rlist2[z].second.srangex,rlist2[z].second.sorder,rlist2[z].second.trange, rlist2[z].second.torder,rlist2[z].second.distexp,rlist2[z].second.timeexp,tf); if (tf < btv) { btv = tf; btr = z; if (m_IF.IsPL(BQB_PL_STANDARD)) m_IF.printf(" <---"); } if (m_IF.IsPL(BQB_PL_STANDARD)) m_IF.printf("\n"); } parm->SetExtraSRangeX(rlist2[btr].second.srangex); parm->SetExtraSRangeY(rlist2[btr].second.srangey); parm->SetExtraSRangeZ(rlist2[btr].second.srangez); parm->SetExtraTRange(rlist2[btr].second.trange); parm->SetExtraSOrder(rlist2[btr].second.sorder); parm->SetExtraTOrder(rlist2[btr].second.torder); parm->SetExtraOffsetX(rlist2[btr].second.offsetx); parm->SetExtraOffsetY(rlist2[btr].second.offsety); parm->SetExtraOffsetZ(rlist2[btr].second.offsetz); parm->SetExtraDistExpo(rlist2[btr].second.distexp); parm->SetExtraTimeExpo(rlist2[btr].second.timeexp); tflast = parm->GetExtraTimeExpo(); if (parm->GetExtraTRange() != parm->GetExtraTOrder()+2) { tfa[0] = 0.5; tfa[1] = 1.0; for (z=0;z<2;z++) { parm->SetExtraTimeExpo(tfa[z]); tfa2[z] = CompressCubeBenchmark( parm, false, // bool realsize &resi, // double *presi NULL // std::vector > *tciaa ); if (m_IF.IsPL(BQB_PL_STANDARD)) m_IF.printf(" %2d %2d %2d %2d %6.3f %6.3f %14.4f\n", parm->GetExtraSRangeX(), parm->GetExtraSOrder(), parm->GetExtraTRange(), parm->GetExtraTOrder(), parm->GetExtraDistExpo(), tfa[z], tfa2[z] ); } if ((tfa2[0] < tfa2[1]) && (tfa2[0] < btv)) tflast = tfa[0]; else if ((tfa2[1] < tfa2[0]) && (tfa2[1] < btv)) tflast = tfa[1]; } tfa[0] = 4.5; tfa[1] = 6.0; for (z=0;z<2;z++) { parm->SetExtraDistExpo(tfa[z]); tfa2[z] = CompressCubeBenchmark( parm, false, // bool realsize &resi, // double *presi NULL // std::vector > *tciaa ); if (m_IF.IsPL(BQB_PL_STANDARD)) m_IF.printf(" %2d %2d %2d %2d %6.3f %6.3f %14.4f\n", parm->GetExtraSRangeX(), parm->GetExtraSOrder(), parm->GetExtraTRange(), parm->GetExtraTOrder(), tfa[z], parm->GetExtraTimeExpo(), tfa2[z] ); } if ((tfa2[0] < tfa2[1]) && (tfa2[0] < btv)) parm->SetExtraDistExpo(tfa[0]); else if ((tfa2[1] < tfa2[0]) && (tfa2[1] < btv)) parm->SetExtraDistExpo(tfa[1]); parm->SetExtraTimeExpo(tflast); goto _end; } /********************* End of Separate Code Block for Level 1 ******************************************/ for (z=0;z<3;z++) tfa[z] = 1.0e30; for (z=0;z<3;z++) { if (z+1 > steps) break; parm->SetExtraSRange(1); parm->SetExtraTRange(z+1); parm->SetExtraSOrder(0); parm->SetExtraTOrder(MAX(z-1,0)); parm->SetExtraOffset(0); tfa[z] = CompressCubeBenchmark( parm, realsize, // bool realsize &resi, // double *presi NULL // std::vector > *tciaa ); if (m_IF.IsPL(BQB_PL_STANDARD)) { if (realsize) sprintf(buf," %2d %2d %2d %2d %6.3f %6.3f %14.4f (%10.3f kiB)", 1, 0, z+1, MAX(z-1,0), parm->GetExtraDistExpo(), parm->GetExtraTimeExpo(), resi, tfa[z] ); else sprintf(buf," %2d %2d %2d %2d %6.3f %6.3f %14.4f", 1, 0, z+1, MAX(z-1,0), parm->GetExtraDistExpo(), parm->GetExtraTimeExpo(), tfa[z] ); m_IF.printf("%s",(const char*)buf); } else buf[0] = 0; if (tfa[z] < btv) { btv = tfa[z]; bto = MAX(z-1,0); btr = z+1; bsrx = 1; bsry = 1; bsrz = 1; bso = 0; bsofx = 0; bsofy = 0; bsofz = 0; if (m_IF.IsPL(BQB_PL_STANDARD)) m_IF.printf(" <---"); } if (m_IF.IsPL(BQB_PL_STANDARD)) m_IF.printf("\n"); rlist.push_back(std::pair(tfa[z],(const char*)buf)); rlist2.push_back(std::pair(tfa[z],VARPARAMS( 1, 1, 1, 0, 0, 0, 0, z+1, MAX(z-1,0), parm->GetExtraDistExpo(), parm->GetExtraTimeExpo() ))); } if ((tfa[2]+0.001 < tfa[0]) && (tfa[2]+0.001 < tfa[1])) { if (m_IF.IsPL(BQB_PL_STANDARD)) m_IF.printf(" ---> Time-continuous case.\n"); ca = 0; } else if ((tfa[1]+0.001 < tfa[0]) && (tfa[1]+0.001 < tfa[2])) { if (m_IF.IsPL(BQB_PL_STANDARD)) m_IF.printf(" ---> Semi-time-continuous case.\n"); ca = 1; } else { if (m_IF.IsPL(BQB_PL_STANDARD)) m_IF.printf(" ---> Time-discontinuous case.\n"); ca = 2; } if (level == 4) { if (m_IF.IsPL(BQB_PL_STANDARD)) m_IF.printf(" SRX SRY SRZ OFX OFY OFZ SO TR TO DistExp TimeExp Residuum\n"); bi = 0; for (zsrx=1;zsrx<10;zsrx++) { for (zsry=1;zsry<10;zsry++) { for (zsrz=1;zsrz<10;zsrz++) { if (MAX3(zsrx,zsry,zsrz) - MIN3(zsrx,zsry,zsrz) > 2) continue; for (zsofx=0;zsofx 0) continue; } else if (MAX3(zsrx,zsry,zsrz) <= 5) { if (MAX3(abs(zsofx-(zsrx/2)),abs(zsofy-(zsry/2)),abs(zsofz-(zsrz/2))) > 1) continue; } else { if (MAX3(abs(zsofx-(zsrx/2)),abs(zsofy-(zsry/2)),abs(zsofz-(zsrz/2))) > 2) continue; } for (zso=0;zso 1) m_IF.printf("\n"); bi = 0; if (((zsrx >= 5) || (zsry >= 5) || (zsrz >= 5)) && (zso == 0)) continue; if (((zsrx >= 7) || (zsry >= 7) || (zsrz >= 7)) && (zso < 2)) continue; if (((zsrx == 9) || (zsry == 9) || (zsrz == 9)) && (zso < 3)) continue; for (z=1;z=-1;z2--) { // torder if ((z > 1) && (z2 == -1)) continue; if ((z > 3) && (z2 == 0)) continue; // The three cases from above if ((zsrx == 1) && (zsry == 1) && (zsrz == 1) && (z == 1) && (z2 == -1)) continue; if ((zsrx == 1) && (zsry == 1) && (zsrz == 1) && (z == 2) && (z2 == 0)) continue; if ((zsrx == 1) && (zsry == 1) && (zsrz == 1) && (z == 3) && (z2 == 1)) continue; if (ca == 0) { if ((z2 < 0) || ((z2 < 1) && (z > 3))) continue; } else if (ca == 1) { if ((z2 < 0) || (z2 > 1)) continue; } else { if (z2 > -1) continue; } tflast = tf; parm->SetExtraSRangeX(zsrx); parm->SetExtraSRangeY(zsry); parm->SetExtraSRangeZ(zsrz); parm->SetExtraTRange(z); parm->SetExtraSOrder(zso); parm->SetExtraTOrder(z2); parm->SetExtraOffsetX(zsofx); parm->SetExtraOffsetY(zsofy); parm->SetExtraOffsetZ(zsofz); tf = CompressCubeBenchmark( parm, realsize, // bool realsize &resi, // double *presi NULL // std::vector > *tciaa ); if (m_IF.IsPL(BQB_PL_STANDARD)) { if (realsize) sprintf(buf," %3d %3d %3d %3d %3d %3d %2d %2d %2d %6.3f %6.3f %14.4f (%10.3f kiB)", zsrx, zsry, zsrz, zsofx, zsofy, zsofz, zso, z, z2, parm->GetExtraDistExpo(), parm->GetExtraTimeExpo(), resi, tf ); else sprintf(buf," %3d %3d %3d %3d %3d %3d %2d %2d %2d %6.3f %6.3f %14.4f", zsrx, zsry, zsrz, zsofx, zsofy, zsofz, zso, z, z2, parm->GetExtraDistExpo(), parm->GetExtraTimeExpo(), tf ); m_IF.printf("%s",(const char*)buf); } else buf[0] = 0; bi++; rlist.push_back(std::pair(tf,(const char*)buf)); rlist2.push_back(std::pair(tf,VARPARAMS( zsrx, zsry, zsrz, zso, zsofx, zsofy, zsofz, z, z2, parm->GetExtraDistExpo(), parm->GetExtraTimeExpo() ))); if (tf < btv) { btv = tf; bto = z2; btr = z; bsrx = zsrx; bsry = zsry; bsrz = zsrz; bsofx = zsofx; bsofy = zsofy; bsofz = zsofz; bso = zso; if (m_IF.IsPL(BQB_PL_STANDARD)) m_IF.printf(" <---"); } if (m_IF.IsPL(BQB_PL_STANDARD)) m_IF.printf("\n"); if ((z2 < z-2) && (tflast < tf)) break; } } } } } } } } } } else { bi = 0; for (zsr=1;zsr<10;zsr+=2) { if ((zsr == 9) && (level < 3)) break; for (zso=0;zso 1) m_IF.printf("\n"); bi = 0; if ((zsr >= 5) && (zso == 0)) continue; if ((zsr >= 7) && (zso < 2)) continue; if ((zsr == 9) && (zso < 3)) continue; for (z=1;z 2)) { if (zso > 4) continue; if ((zsr == 5) && (zso == 4)) continue; } for (z2=z-2;z2>=-1;z2--) { // torder if ((z > 1) && (z2 == -1)) continue; if ((z > 3) && (z2 == 0)) continue; // The three cases from above if ((zsr == 1) && (z == 1) && (z2 == -1)) continue; if ((zsr == 1) && (z == 2) && (z2 == 0)) continue; if ((zsr == 1) && (z == 3) && (z2 == 1)) continue; if (ca == 0) { if ((z2 < 0) || ((z2 < 1) && (z > 3))) continue; } else if (ca == 1) { if ((z2 < 0) || (z2 > 1)) continue; } else { if (z2 > -1) continue; } tflast = tf; parm->SetExtraSRangeX(zsr); parm->SetExtraTRange(z); parm->SetExtraSOrder(zso); parm->SetExtraTOrder(z2); parm->SetExtraOffset(zsr/2); tf = CompressCubeBenchmark( parm, realsize, // bool realsize &resi, // double *presi NULL // std::vector > *tciaa ); if (m_IF.IsPL(BQB_PL_STANDARD)) { if (realsize) sprintf(buf," %2d %2d %2d %2d %6.3f %6.3f %14.4f (%10.3f kiB)", zsr, zso, z, z2, parm->GetExtraDistExpo(), parm->GetExtraTimeExpo(), resi, tf ); else sprintf(buf," %2d %2d %2d %2d %6.3f %6.3f %14.4f", zsr, zso, z, z2, parm->GetExtraDistExpo(), parm->GetExtraTimeExpo(), tf ); m_IF.printf("%s",(const char*)buf); } else buf[0] = 0; bi++; rlist.push_back(std::pair(tf,(const char*)buf)); rlist2.push_back(std::pair(tf,VARPARAMS( zsr, zsr, zsr, zso, zsr/2, zsr/2, zsr/2, z, z2, parm->GetExtraDistExpo(), parm->GetExtraTimeExpo() ))); if (tf < btv) { btv = tf; bto = z2; btr = z; bsrx = zsr; bsry = zsr; bsrz = zsr; bsofx = zsr/2; bsofy = zsr/2; bsofz = zsr/2; bso = zso; if (m_IF.IsPL(BQB_PL_STANDARD)) m_IF.printf(" <---"); } if (m_IF.IsPL(BQB_PL_STANDARD)) m_IF.printf("\n"); if ((z2 < z-2) && (tflast < tf)) break; } } } } } std::sort(rlist.begin(),rlist.end()); /* FILE *a; a = OpenFileWrite("opticube_list.txt",true); mfprintf(a," sr so tr to distexp timeexp residuum\n"); for (z=0;z<(int)rlist.size();z++) mfprintf(a,"%s\n",rlist[z].second.c_str()); fclose(a);*/ if (level == 2) { if (m_IF.IsPL(BQB_PL_STANDARD)) m_IF.printf(" Evaluating best 10:\n"); std::sort(rlist2.begin(),rlist2.end()); for (z=0;z<10;z++) rlist3.push_back(rlist2[z]); //int tia[4]; for (z=0;z<4;z++) tia[z] = 0; for (z=0;z<(int)rlist3.size();z++) tia[rlist3[z].second.srangex/2]++; // Make sure that at least 2 sets from each srange are included for (z=0;z<4;z++) { if ((tia[z] < 1) || ((z > 0) && (tia[z] < 2))) { for (z2=10;z2<(int)rlist2.size();z2++) { if ((rlist2[z2].second.srangex/2) == z) { rlist3.push_back(rlist2[z2]); tia[z]++; if ((tia[z] >= 2) || ((z == 0) && (tia[z] == 1))) break; } } } } // Crop the total number back to 10 if (rlist3.size() > 10) { for (z=(int)rlist3.size()-1;z>=0;z--) { if ((tia[rlist3[z].second.srangex/2] > 2) || ((rlist3[z].second.srangex == 1) && (tia[rlist3[z].second.srangex/2] > 1))) { tia[rlist3[z].second.srangex/2]--; rlist3.erase(rlist3.begin()+z); } if (rlist3.size() == 10) break; } } std::sort(rlist3.begin(),rlist3.end()); btr = -1; btv = 1.0e30; for (z=0;z<(int)rlist3.size();z++) { parm->SetExtraSRangeX(rlist3[z].second.srangex); parm->SetExtraSRangeY(rlist3[z].second.srangey); parm->SetExtraSRangeZ(rlist3[z].second.srangez); parm->SetExtraTRange(rlist3[z].second.trange); parm->SetExtraSOrder(rlist3[z].second.sorder); parm->SetExtraTOrder(rlist3[z].second.torder); parm->SetExtraOffsetX(rlist3[z].second.offsetx); parm->SetExtraOffsetY(rlist3[z].second.offsety); parm->SetExtraOffsetZ(rlist3[z].second.offsetz); parm->SetExtraDistExpo(rlist3[z].second.distexp); parm->SetExtraTimeExpo(rlist3[z].second.timeexp); tf = CompressCubeBenchmark( parm, true, // bool realsize &resi, // double *presi NULL // std::vector > *tciaa ); if (m_IF.IsPL(BQB_PL_STANDARD)) { sprintf(buf," %2d %2d %2d %2d %6.3f %6.3f %14.4f (%10.3f kiB)", rlist3[z].second.srangex,rlist3[z].second.sorder,rlist3[z].second.trange, rlist3[z].second.torder,rlist3[z].second.distexp,rlist3[z].second.timeexp,resi,tf); m_IF.printf("%s",(const char*)buf); } else buf[0] = 0; if (tf < btv) { btv = tf; btr = z; if (m_IF.IsPL(BQB_PL_STANDARD)) m_IF.printf(" <---"); } if (m_IF.IsPL(BQB_PL_STANDARD)) m_IF.printf("\n"); } parm->SetExtraSRangeX(rlist3[btr].second.srangex); parm->SetExtraSRangeY(rlist3[btr].second.srangey); parm->SetExtraSRangeZ(rlist3[btr].second.srangez); parm->SetExtraTRange(rlist3[btr].second.trange); parm->SetExtraSOrder(rlist3[btr].second.sorder); parm->SetExtraTOrder(rlist3[btr].second.torder); parm->SetExtraOffsetX(rlist3[btr].second.offsetx); parm->SetExtraOffsetY(rlist3[btr].second.offsety); parm->SetExtraOffsetZ(rlist3[btr].second.offsetz); } else { parm->SetExtraSRangeX(bsrx); parm->SetExtraSRangeY(bsry); parm->SetExtraSRangeZ(bsrz); parm->SetExtraTRange(btr); parm->SetExtraSOrder(bso); parm->SetExtraTOrder(bto); parm->SetExtraOffsetX(bsofx); parm->SetExtraOffsetY(bsofy); parm->SetExtraOffsetZ(bsofz); } if (level >= 2) { m_pVolParm = parm; m_bOptCubeRealSize = realsize; if (parm->GetExtraTOrder()+2 != parm->GetExtraTRange()) { if (m_IF.IsPL(BQB_PL_STANDARD)) m_IF.printf(" Optimizing time exponent:\n"); tf = GoldenSectionSearch(4.0, (level>=3)?0.02:0.2, &CBQBDriver::OptimizeCube_ObjectiveTExpo); if (level >= 3) parm->SetExtraTimeExpo( floor(tf*1000.0+0.5)/1000.0 ); else parm->SetExtraTimeExpo( floor(tf*100.0+0.5)/100.0 ); } else parm->SetExtraTimeExpo( 0 ); if (m_IF.IsPL(BQB_PL_STANDARD)) m_IF.printf(" Optimizing distance exponent:\n"); tf = GoldenSectionSearch(8.0, (level>=3)?0.02:0.2, &CBQBDriver::OptimizeCube_ObjectiveSExpo); if (level >= 3) parm->SetExtraDistExpo( floor(tf*1000.0+0.5)/1000.0 ); else parm->SetExtraDistExpo( floor(tf*100.0+0.5)/100.0 ); } if (level >= 2) { if (m_IF.IsPL(BQB_PL_STANDARD)) m_IF.printf(" Optimizing Compressor settings:\n"); tciaa.clear(); tf = CompressCubeBenchmark( parm, true, // bool realsize NULL, // double *presi &tciaa // std::vector > *tciaa ); if (m_IF.IsPL(BQB_PL_STANDARD)) m_IF.printf(" TC BL BW MTF Frame Size [kiB]\n"); if (level >= 4) { iatc.push_back(1); iatc.push_back(2); iatc.push_back(3); iatc.push_back(4); iatc.push_back(6); iatc.push_back(8); iatc.push_back(10); iatc.push_back(12); iatc.push_back(15); iatc.push_back(18); iatc.push_back(21); iatc.push_back(24); iabl.push_back(10); iabl.push_back(12); iabl.push_back(14); iabl.push_back(16); iabl.push_back(20); iabl.push_back(24); iabl.push_back(28); iabl.push_back(32); iabl.push_back(36); iabl.push_back(40); iabl.push_back(48); iabl.push_back(56); iabl.push_back(64); btv = 1.0e30; btr = -1; for (z=0;z<(int)iatc.size();z++) { for (z2=0;z2<(int)iabl.size();z2++) { tf = 0; for (z3=0;z3<(int)tciaa.size();z3++) { bs.Clear(); tie = new CBQBIntegerEngine(m_IF); parm->SetBlockLength(iabl[z2]); parm->SetTableCount(iatc[z]); tie->Compress( tciaa[z3], &bs, parm->GetCompressorParameterSet(), false, NULL ); delete tie; tf += bs.GetByteLength(); } if (m_IF.IsPL(BQB_PL_STANDARD)) m_IF.printf(" %2d %2d %3s %3s %10.4f", iatc[z], iabl[z2], parm->GetBW()?"yes":"no", parm->GetMTF()?"yes":"no", tf/tciaa.size()/1024.0 ); if (tf < btv) { btv = tf; parm->SetTableCount(iatc[z]); parm->SetBlockLength(iabl[z2]); if (m_IF.IsPL(BQB_PL_STANDARD)) m_IF.printf(" <---"); } if (m_IF.IsPL(BQB_PL_STANDARD)) m_IF.printf("\n"); if (iatc[z] == 1) break; // One table: Block length does not matter } } } else { if (level >= 3) { ti = 11; tia[0] = 28; tia[1] = 24; tia[2] = 20; tia[3] = 16; tia[4] = 12; tia[5] = 8; tia[6] = 6; tia[7] = 4; tia[8] = 3; tia[9] = 2; tia[10] = 1; } else { ti = 4; tia[0] = 10; tia[1] = 6; tia[2] = 3; tia[3] = 1; } btv = 1.0e30; btr = -1; for (z=0;zSetTableCount(tia[z]); tie->Compress( tciaa[z2], &bs, parm->GetCompressorParameterSet(), false, NULL ); delete tie; tfa[z] += bs.GetByteLength(); } if (m_IF.IsPL(BQB_PL_STANDARD)) m_IF.printf(" %2d %2d %3s %3s %10.3f", tia[z], parm->GetBlockLength(), parm->GetBW()?"yes":"no", parm->GetMTF()?"yes":"no", tfa[z]/1024.0/tciaa.size() ); if (tfa[z] < btv) { btv = tfa[z]; btr = z; if (m_IF.IsPL(BQB_PL_STANDARD)) m_IF.printf(" <---"); } if (m_IF.IsPL(BQB_PL_STANDARD)) m_IF.printf("\n"); if ((z > 0) && (tfa[z] > tflast)) break; tflast = tfa[z]; } parm->SetTableCount(tia[btr]); if (parm->GetTableCount() != 1) { if (m_IF.IsPL(BQB_PL_STANDARD)) m_IF.printf("\n"); if (level >= 3) { ti = 10; tia[0] = 10; tia[1] = 12; tia[2] = 14; tia[3] = 16; tia[4] = 20; tia[5] = 24; tia[6] = 28; tia[7] = 32; tia[8] = 36; tia[9] = 40; } else { ti = 4; tia[0] = 15; tia[1] = 20; tia[2] = 30; tia[3] = 40; } btv = 1.0e30; btr = -1; for (z=0;zSetBlockLength(tia[z]); tie->Compress( tciaa[z2], &bs, parm->GetCompressorParameterSet(), false, NULL ); delete tie; tfa[z] += bs.GetByteLength(); } if (m_IF.IsPL(BQB_PL_STANDARD)) m_IF.printf(" %2d %2d %3s %3s %10.3f", parm->GetTableCount(), tia[z], parm->GetBW()?"yes":"no", parm->GetMTF()?"yes":"no", tfa[z]/1024.0/tciaa.size() ); if (tfa[z] < btv) { btv = tfa[z]; btr = z; if (m_IF.IsPL(BQB_PL_STANDARD)) m_IF.printf(" <---"); } if (m_IF.IsPL(BQB_PL_STANDARD)) m_IF.printf("\n"); if ((z > 0) && (tfa[z] > tflast)) break; tflast = tfa[z]; } parm->SetBlockLength(tia[btr]); } } if (level >= 3) { for (z=0;z<3;z++) { switch(z) { case 0: parm->SetBW(true); parm->SetMTF(true); break; case 1: parm->SetBW(true); parm->SetMTF(false); break; case 2: parm->SetBW(false); parm->SetMTF(false); break; } tfa[z] = 0; for (z2=0;z2<(int)tciaa.size();z2++) { bs.Clear(); tie = new CBQBIntegerEngine(m_IF); tie->Compress( tciaa[z2], &bs, parm->GetCompressorParameterSet(), false, NULL ); delete tie; tfa[z] += bs.GetByteLength(); } if (m_IF.IsPL(BQB_PL_STANDARD)) m_IF.printf(" %2d %2d %3s %3s %10.3f\n", parm->GetTableCount(), parm->GetBlockLength(), parm->GetBW()?"yes":"no", parm->GetMTF()?"yes":"no", tfa[z]/1024.0/tciaa.size() ); } fac = 1.0; if ((tfa[0] <= tfa[1]) && (tfa[0] <= tfa[2]/fac)) { parm->SetBW(true); parm->SetMTF(true); } else if ((tfa[1] <= tfa[0]) && (tfa[1] <= tfa[2]/fac)) { parm->SetBW(true); parm->SetMTF(false); } else { parm->SetBW(false); parm->SetMTF(false); } } } _end: if (m_IF.IsPL(BQB_PL_STANDARD)) { BQBFormatTime((unsigned long)time(NULL)-t0,buf); m_IF.printf(" Optimization took %s\n",(const char*)buf); } /* if (m_fResiCorrFrame != NULL) { fclose(m_fResiCorrFrame); m_fResiCorrFrame = NULL; } if (m_fResiCorrTraj != NULL) { fclose(m_fResiCorrTraj); m_fResiCorrTraj = NULL; }*/ if (m_IF.IsPL(BQB_PL_STANDARD)) m_IF.bprintf(" <<< Volumetric Trajectory Parameter Optimization Done <<<\n"); return true; } bool CBQBDriver::DecompressCube( const char *inp, const char *outp, const char *readref, int steps, int stride, CBQBParameterSet_PosAndVol *parm ) { UNUSED(stride); CBQBCubeFrame *cfr, *cfr2; int z, i, al, cl, ty, ver; int ahistused, chistused; CBQBBitSet bsat(m_IF), bscu(m_IF), bshe(m_IF); FILE *b, *fref; CBQBFile bf(m_IF); if (parm == NULL) parm = &m_ParmPosAndVol; if (m_IF.IsPL(BQB_PL_STANDARD)) m_IF.printf("Opening archive file \"%s\" ...\n",inp); if (!bf.OpenRead(inp)) { m_IF.eprintf("Error: Could not open file for reading.\n"); return false; } if (outp != NULL) { if (m_IF.IsPL(BQB_PL_STANDARD)) m_IF.printf("Opening output cube file \"%s\" ...\n",outp); b = fopen(outp,"wb"); if (b == NULL) { m_IF.eprintf("Error: Could not open file for writing.\n"); return false; } } else { b = NULL; if (m_IF.IsPL(BQB_PL_STANDARD)) m_IF.printf("No output file specified; no output will be written.\n"); } fref = NULL; if (readref != NULL) { if (m_IF.IsPL(BQB_PL_STANDARD)) m_IF.printf("Opening reference cube file \"%s\" ...\n",readref); fref = fopen(readref,"rb"); if (fref == NULL) { m_IF.eprintf("Error: Could not open file for reading.\n"); return false; } } m_pEngine->m_oaOutputCubeBuf.resize(7); for (z=0;z<7;z++) m_pEngine->m_oaOutputCubeBuf[z] = NULL; m_pEngine->m_iOutputCubeBufPos = 0; m_pEngine->m_oaOutputAtomBuf.resize(11); for (z=0;z<11;z++) m_pEngine->m_oaOutputAtomBuf[z] = NULL; m_pEngine->m_iOutputAtomBufPos = 0; if (m_IF.IsPL(BQB_PL_STANDARD)) m_IF.printf("Starting process...\n"); i = 0; while (true) { if (m_IF.IsPL(BQB_PL_VERBOSE)) m_IF.printf("\n\n"); if (!bf.ReadFrame()) break; ty = bf.GetFrameType(); ver = bf.GetFrameTypeVersion(); if ((ty == BQB_FRAMETYPE_IDX) || (ty == BQB_FRAMETYPE_COMPIDX)) continue; if ((ty == BQB_FRAMETYPE_COMPCUBE) || (ty == BQB_FRAMETYPE_COMPCUBESTART) || (ty == BQB_FRAMETYPE_COMPCUBEKEY)) { if (ver > BQB_FRAMETYPE_COMPCUBE_VERSION) { m_IF.eprintf("Error: Unexpected frame type version (%d v%d).\n",ty,ver); m_IF.eprintf(" Probably the BQB file is more recent than the libbqb version.\n"); return false; } } else { m_IF.eprintf("Error: Unexpected frame type (%d v%d).\n",ty,ver); return false; } bshe.Clear(); bshe.m_iaData.assign(bf.GetFramePayload()->begin(),bf.GetFramePayload()->begin()+8); if (m_IF.IsPL(BQB_PL_STANDARD)) { if (i == 0) m_IF.printf("Reading first time step from compressed trajectory...\n"); else m_IF.printf(" Step %d ...\n",i+1); } al = bshe.ReadBitsInteger(32); cl = bshe.ReadBitsInteger(32); if (m_IF.IsPL(BQB_PL_VERBOSE)) m_IF.printf("Atom block %d bytes, Cube block %d bytes.\n",al,cl); cfr = new CBQBCubeFrame(m_IF); m_pEngine->PushOutputCubeFrame(cfr); cfr->m_pAtoms = new CBQBAtomSet(); m_pEngine->PushOutputAtomFrame(cfr->m_pAtoms); bsat.Clear(); bsat.m_iaData.assign(bf.GetFramePayload()->begin()+8,bf.GetFramePayload()->begin()+8+al); bscu.Clear(); bscu.m_iaData.assign(bf.GetFramePayload()->begin()+8+al,bf.GetFramePayload()->begin()+8+al+cl); if (!m_pEngine->DecompressAtomFrame( &bsat, ver, parm->GetPositionParameterSet(), &ahistused, false, false )) return false; if (!m_pEngine->DecompressCubeFrame( &bscu, ver, parm->GetVolumetricParameterSet(), &chistused, false, false )) return false; if (m_IF.IsPL(BQB_PL_STANDARD) && (i == 0)) { m_IF.bprintf("\nThe following parameters have been used for compressing this file:\n\n"); m_IF.printf("%s\n",parm->ToString(4).c_str()); m_IF.bprintf("Parameter Key:"); m_IF.printf(" %s\n\n",parm->ToKey().c_str()); } if (readref != NULL) { if (m_IF.IsPL(BQB_PL_STANDARD)) m_IF.printf(" Comparing to reference...\n"); cfr2 = new CBQBCubeFrame(m_IF); if (!cfr2->ReadFrame( fref, cfr->m_iEps, cfr->m_iSigni, cfr->m_pAtoms->m_iSigni )) break; for (z=0;zm_iResXYZ;z++) if (!ExpMantisEqual(cfr->m_iaExpo[z],cfr->m_iaMantis[z],cfr2->m_iaExpo[z],cfr2->m_iaMantis[z])) { m_IF.eprintf(" Error %7d: %.10G vs %.10G\n",z,cfr->m_faBin[z],cfr2->m_faBin[z]); break; } delete cfr2; if (m_IF.IsPL(BQB_PL_VERBOSE)) m_IF.printf("Done.\n"); } if (m_IF.IsPL(BQB_PL_STANDARD)) m_IF.printf(" %9.3f KiB compressed data unpacked (history: position %2d, volumetric %2d).\n", (al+cl)/1024.0, ahistused, chistused ); if (outp != NULL) cfr->WriteFrame(b); if (m_IF.IsPL(BQB_PL_VERBOSE)) m_IF.printf("Done.\n"); i++; if (i == steps) break; } bf.Close(); if (outp != NULL) fclose(b); if (readref != NULL) fclose(fref); if (m_IF.IsPL(BQB_PL_STANDARD)) m_IF.printf("Finished decompressing the cube file.\n\n"); return true; } bool CBQBDriver::CompressXYZ( const char *inp, const char *outp, const char *ref, int start, int steps, int stride, int keyfreq, CBQBParameterSet_Position *parm, bool comment, bool compare, int optimize, int optsteps, bool onlyopt ) { const CBQBAtomSet *as; CBQBAtomSet *as2; int z, z2, i, k, o, ft, lasize, morder, atc, histused, mo; long insize; double tb, tb2, tf, tf2; CBQBBitSet bsat(m_IF), bstemp(m_IF); bool err, to; CBQBFile bf(m_IF); CBQBStatistics stat(m_IF); atc = 0; if (m_IF.IsPL(BQB_PL_STANDARD)) m_IF.printf("Opening XYZ file \"%s\" ...\n",inp); m_pEngine->m_pReadCacheXYZ = new CBQBReadXYZCache(m_IF); m_pEngine->m_pReadCacheXYZ->SetReadParameters( parm->GetPrecision() ); if (!m_pEngine->m_pReadCacheXYZ->FileOpenRead(inp,ref)) { m_IF.eprintf("Error: Could not open file for reading.\n"); return false; } if (parm->GetUseExtra() && (parm->GetExtraTRange() > parm->GetOrder())) parm->SetOrder(parm->GetExtraTRange()); if (optimize != 0) { if (parm->GetOrder()+1 > optsteps) m_pEngine->m_pReadCacheXYZ->SetHistoryDepth(parm->GetOrder()+1); else m_pEngine->m_pReadCacheXYZ->SetHistoryDepth(optsteps); if (m_IF.IsPL(BQB_PL_STANDARD)) m_IF.printf("\n"); m_pEngine->m_pReadCacheXYZ->CacheSteps(optsteps,true); if (m_IF.IsPL(BQB_PL_STANDARD)) m_IF.printf("\n"); if (m_iOptIncludeFirst == -1) { if ((m_pEngine->m_pReadCacheXYZ->GetCachedSteps() < optsteps) || (optsteps < 10)) { if (m_IF.IsPL(BQB_PL_STANDARD)) m_IF.printf(" Low step count, switching on -optstart.\n\n"); m_iOptIncludeFirst = 1; } else { if (m_IF.IsPL(BQB_PL_STANDARD)) m_IF.printf(" Large step count, switching off -optstart.\n\n"); m_iOptIncludeFirst = 0; } } m_pEngine->m_pReadCacheXYZ->SetStartLock(); if (!OptimizeXYZParameters( optimize, // int level, parm, comment, // bool comment, false // bool cubepart )) { m_IF.eprintf("Error: Parameter optimization failed.\n"); delete m_pEngine->m_pReadCacheXYZ; m_pEngine->m_pReadCacheXYZ = NULL; return false; } if (m_IF.IsPL(BQB_PL_STANDARD)) { m_IF.bprintf("\n The optimal parameters for this trajectory are:\n\n"); m_IF.printf("%s",parm->ToString(4).c_str()); m_IF.printf("\n"); m_IF.bprintf(" Parameter key:"); m_IF.printf(" %s\n\n",parm->ToKey().c_str()); } if (onlyopt) { m_pEngine->m_pReadCacheXYZ->CloseFile(); delete m_pEngine->m_pReadCacheXYZ; m_pEngine->m_pReadCacheXYZ = NULL; return true; } m_pEngine->m_pReadCacheXYZ->RewindReadPos(); m_pEngine->m_pReadCacheXYZ->LiftStartLock(); } else { m_pEngine->m_pReadCacheXYZ->SetHistoryDepth(parm->GetOrder()+1); } stat.m_oStat.reset(); if (outp != NULL) { if (m_IF.IsPL(BQB_PL_STANDARD)) m_IF.printf("Opening compressed output file \"%s\" ...\n",outp); if (!bf.OpenWriteAppend(outp)) { m_IF.eprintf("Error: Could not open file for writing.\n"); m_pEngine->m_pReadCacheXYZ->CloseFile(); delete m_pEngine->m_pReadCacheXYZ; m_pEngine->m_pReadCacheXYZ = NULL; return false; } } m_pEngine->m_oaOutputAtomBuf.resize(parm->GetOrder()+1); for (z=0;zGetOrder()+1;z++) m_pEngine->m_oaOutputAtomBuf[z] = NULL; m_pEngine->m_iOutputAtomBufPos = 0; if (m_IF.IsPL(BQB_PL_STANDARD)) m_IF.printf("Starting process...\n"); if (start != 0) { if (m_IF.IsPL(BQB_PL_STANDARD)) m_IF.printf("Fast-forwarding to step %d ...\n",start+1); for (z=0;zm_pReadCacheXYZ->SkipOneStep()) { delete m_pEngine->m_pReadCacheXYZ; m_pEngine->m_pReadCacheXYZ = NULL; return false; } } if (parm->GetUseExtra()) mo = parm->GetExtraTOrder(); else mo = parm->GetOrder(); morder = mo; i = 0; k = 0; tb = 0; tb2 = 0; tf = 0; tf2 = 0; to = false; if (parm->GetOptOrder()) lasize = 1000000000; else lasize = -1; err = false; while (true) { if (m_IF.IsPL(BQB_PL_VERBOSE)) m_IF.printf("\n\n"); if (m_IF.IsPL(BQB_PL_STANDARD)) m_IF.printf(" Step %d ...\n",i+1); as = m_pEngine->m_pReadCacheXYZ->GetNextFrame(); if (i == 0) atc = (int)as->m_oaAtoms.size(); if (as == NULL) { if (m_IF.IsPL(BQB_PL_STANDARD)) m_IF.printf(" Reached end of input trajectory.\n"); break; } for (z=0;zm_pReadCacheXYZ->SkipOneStep()) { if (m_IF.IsPL(BQB_PL_STANDARD)) m_IF.printf(" Reached end of input trajectory.\n"); break; } } if (i == 0) { if (parm->GetUseExtra()) { if (m_IF.IsPL(BQB_PL_STANDARD)) m_IF.printf(" Initializing Extrapolator (%d/%d)...\n", parm->GetExtraTRange(), parm->GetExtraTOrder() ); m_pEngine->m_pExtrapolatorXYZ = new CBQBExtrapolator(m_IF); m_pEngine->m_pExtrapolatorXYZ->InitializeXYZ( parm->GetExtraTRange(), parm->GetExtraTOrder(), parm->GetExtraTimeExpo(), false ); } } if (m_pEngine->m_pExtrapolatorXYZ != NULL) m_pEngine->m_pExtrapolatorXYZ->PushAtomFrame(as); if ((i != 0) && (keyfreq != 0) && ((i % keyfreq) == 0)) { if (m_IF.IsPL(BQB_PL_STANDARD)) m_IF.printf(" Enforcing key frame.\n"); k = 0; // Enforce this frame to be a keyframe } _again: if (i < mo) o = i; else if (k < mo) o = k; else o = mo; _aagain: bsat.Clear(); stat.PushStatistics(); m_pEngine->CompressAtomFrame( &bsat, o, parm, histused, (i==0), // Store static trajectory information? comment, &stat ); if (m_IF.IsPL(BQB_PL_STANDARD)) { if (parm->GetUseExtra()) m_IF.printf(" History %2d, output size %9.3f KiB.\n",histused,bsat.GetByteLength()/1024.0); else m_IF.printf(" Order %d, output size %9.3f KiB.\n",o,bsat.GetByteLength()/1024.0); } if (lasize >= 0) { // Only happens if optorder == true if (!parm->GetUseExtra()) { if (to) { to = false; if (bsat.GetByteLength() <= bstemp.GetByteLength()) { if (m_IF.IsPL(BQB_PL_STANDARD)) m_IF.printf(" Size is indeed smaller with lower order. Limiting atom order to %d.\n",o); stat.PopDiffStatistics(); parm->SetOrder(o); mo = o; lasize = -1; } else { if (m_IF.IsPL(BQB_PL_STANDARD)) m_IF.printf(" Size was smaller with higher order. Not limiting.\n"); stat.PopStatistics(); bsat = CBQBBitSet(bstemp); lasize = bsat.GetByteLength(); } } else { if ((o != 0) && ((double)bsat.GetByteLength() >= (double)lasize*0.97)) { if (m_IF.IsPL(BQB_PL_STANDARD)) m_IF.printf(" Size did not decrease any further with order %d. Trying order %d...\n",o,o-1); bstemp = CBQBBitSet(bsat); to = true; o--; goto _aagain; } else if (o == mo) lasize = -1; else lasize = bsat.GetByteLength(); } } } stat.PopIgnoreStatistics(); tb += bsat.GetByteLength(); tf++; if ((bsat.GetLength()%8) != 0) stat.m_oStat.m_lOverhead += 8 - (bsat.GetLength()%8); if (i >= morder) { tb2 += bsat.GetByteLength(); tf2++; } if (compare) { as2 = new CBQBAtomSet(); m_pEngine->PushOutputAtomFrame(as2); m_pEngine->DecompressAtomFrame( &bsat, BQB_FRAMETYPE_COMPTRAJ_VERSION, parm, NULL, // histused false, true ); if (m_IF.IsPL(BQB_PL_VERBOSE)) m_IF.printf("Comparing input and output...\n"); for (z=0;z<(int)as2->m_oaAtoms.size();z++) { for (z2=0;z2<3;z2++) { if (as->m_oaAtoms[z]->m_iCoord[z2] != as2->m_oaAtoms[z]->m_iCoord[z2]) { m_IF.eprintf(" Error %d[%d]: %.6f != %.6f\n", z, z2, as->m_oaAtoms[z]->m_fCoord[z2], as2->m_oaAtoms[z]->m_fCoord[z2] ); err = true; goto _skerr; } } } _skerr: if (err) { if (k != 0) { m_IF.eprintf("Errors occured. Compressing frame again with history zero.\n"); err = false; k = 0; goto _again; } else { m_IF.eprintf("Errors occured despite of zero history. Aborting.\n"); goto _end; } } if (m_IF.IsPL(BQB_PL_VERBOSE)) m_IF.printf("Done.\n"); } if (outp != NULL) { if (i == 0) ft = BQB_FRAMETYPE_COMPTRAJSTART; else if (k == 0) ft = BQB_FRAMETYPE_COMPTRAJKEY; else ft = BQB_FRAMETYPE_COMPTRAJ; bf.CreateShortFrame( ft, BQB_FRAMETYPE_COMPTRAJ_VERSION, i+1 ); bf.PushPayload(bsat.m_iaData); bf.FinalizeFrame(&stat); } i++; k++; if (i == steps) break; } _end: if (outp != NULL) { bf.WriteIndexFrame(true,&stat); bf.Close(); } insize = m_pEngine->m_pReadCacheXYZ->ftell(); m_pEngine->m_pReadCacheXYZ->CloseFile(); delete m_pEngine->m_pReadCacheXYZ; m_pEngine->m_pReadCacheXYZ = NULL; if (m_pEngine->m_pExtrapolatorXYZ != NULL) { delete m_pEngine->m_pExtrapolatorXYZ; m_pEngine->m_pExtrapolatorXYZ = NULL; } if (err) { if (m_IF.IsPL(BQB_PL_STANDARD)) m_IF.eprintf("Errors occurred while compressing the XYZ file.\n"); return false; } else if (m_IF.IsPL(BQB_PL_STANDARD)) { m_IF.printf("Finished compressing the XYZ file.\n"); m_IF.printf("%10.3f MiB (%12s Bytes) overhead.\n", double(stat.m_oStat.m_lOverhead)/1024.0/1024.0/8.0,(stat.m_oStat.m_lOverhead>>3).string()); m_IF.printf("%10.3f MiB (%12s Bytes) alphabet data.\n", double(stat.m_oStat.m_lAlphabet)/1024.0/1024.0/8.0,(stat.m_oStat.m_lAlphabet>>3).string()); m_IF.printf("%10.3f MiB (%12s Bytes) Huffman tables.\n", double(stat.m_oStat.m_lHuffmanTables)/1024.0/1024.0/8.0,(stat.m_oStat.m_lHuffmanTables>>3).string()); m_IF.printf("%10.3f MiB (%12s Bytes) table switching.\n", double(stat.m_oStat.m_lTableSwitch)/1024.0/1024.0/8.0,(stat.m_oStat.m_lTableSwitch>>3).string()); m_IF.printf("%10.3f MiB (%12s Bytes) payload data.\n", double(stat.m_oStat.m_lHuffmanData)/1024.0/1024.0/8.0,(stat.m_oStat.m_lHuffmanData>>3).string()); m_IF.printf("%10.3f MiB (%12s Bytes) in total.\n", double(stat.m_oStat.m_lOverhead+stat.m_oStat.m_lAlphabet+stat.m_oStat.m_lHuffmanTables+stat.m_oStat.m_lTableSwitch+stat.m_oStat.m_lHuffmanData)/1024.0/1024.0/8.0, ((stat.m_oStat.m_lOverhead+stat.m_oStat.m_lAlphabet+stat.m_oStat.m_lHuffmanTables+stat.m_oStat.m_lTableSwitch+stat.m_oStat.m_lHuffmanData)>>3).string()); if (tf > 0) { m_IF.bprintf("\n * Totals:\n"); m_IF.printf(" %9.3f KiB per frame on average.\n",tb/1024.0/tf); m_IF.printf(" %9.3f bits per coodinate on average.\n",tb/tf/atc/3.0*8.0); m_IF.printf(" Compression ratio of %.3f : 1\n",(double)insize/tb); } if (tf2 > 0) { m_IF.bprintf("\n * Starting from step %d:\n",morder+1); m_IF.printf(" %9.3f KiB per frame on average.\n",tb2/1024.0/tf2); m_IF.printf(" %9.3f bits per coodinate on average.\n",tb2/tf2/atc/3.0*8.0); m_IF.printf(" Compression ratio of %.3f : 1\n",((double)insize/tf*tf2)/tb2); } m_IF.printf("\n"); } return true; } double CBQBDriver::CompressXYZBenchmark( CBQBParameterSet_Position *parm, bool comment, bool realsize, double *presi, std::vector > *tciaa ) { const CBQBAtomSet *as; int i, o, histused; double tb, tf, resi, tresi; CBQBBitSet bsat(m_IF); resi = 0; if (parm->GetUseExtra() && (parm->GetExtraTRange() > parm->GetOrder())) parm->SetOrder(parm->GetExtraTRange()); if (m_IF.IsPL(BQB_PL_VERBOSE)) m_IF.printf("Starting process...\n"); i = 0; tb = 0; tf = 0; if (m_pEngine->m_pReadCacheCube != NULL) m_pEngine->m_pReadCacheCube->RewindReadPos(); else m_pEngine->m_pReadCacheXYZ->RewindReadPos(); while (true) { if (m_IF.IsPL(BQB_PL_DEBUG)) m_IF.printf("\n\n"); if (m_IF.IsPL(BQB_PL_VERBOSE)) m_IF.printf(" Step %d ...\n",i+1); if (m_pEngine->m_pReadCacheCube != NULL) as = m_pEngine->m_pReadCacheCube->GetNextFrame()->m_pAtoms; else as = m_pEngine->m_pReadCacheXYZ->GetNextFrame(); if (as == NULL) break; if (i == 0) { if (!realsize) m_pEngine->BuildIdentityAtomSort(as); if (parm->GetUseExtra()) { if (m_IF.IsPL(BQB_PL_VERBOSE)) m_IF.printf(" Initializing Extrapolator (%d|%d)...\n", parm->GetExtraTRange(), parm->GetExtraTOrder() ); m_pEngine->m_pExtrapolatorXYZ = new CBQBExtrapolator(m_IF); m_pEngine->m_pExtrapolatorXYZ->InitializeXYZ( parm->GetExtraTRange(), parm->GetExtraTOrder(), parm->GetExtraTimeExpo(), !m_IF.IsPL(BQB_PL_VERBOSE) ); } } if (m_pEngine->m_pExtrapolatorXYZ != NULL) m_pEngine->m_pExtrapolatorXYZ->PushAtomFrame(as); if (i < parm->GetOrder()) o = i; else o = parm->GetOrder(); if ((i+1 >= parm->GetExtraTRange()) || (m_iOptIncludeFirst > 0)) { bsat.Clear(); m_pEngine->CompressAtomFrame( &bsat, o, parm, histused, (i==0), // Store static trajectory information? comment, NULL, !realsize, &tresi, tciaa ); resi += tresi; tf++; if (realsize) { tb += bsat.GetByteLength(); /* if (m_fResiCorrFrame != NULL) { mfprintf(m_fResiCorrFrame,"%d; %.3f\n", bsat.GetByteLength(), mypow( tresi / ((as->m_oaAtoms.size() + 1) * 3.0), 1.0/m_fEntropyExpoXYZ ) ); fflush(m_fResiCorrFrame); }*/ } } i++; if (m_pEngine->m_pReadCacheCube != NULL) { if (m_pEngine->m_pReadCacheCube->GetCachedSteps() == 0) break; } else { if (m_pEngine->m_pReadCacheXYZ->GetCachedSteps() == 0) break; } } if (m_pEngine->m_pExtrapolatorXYZ != NULL) { delete m_pEngine->m_pExtrapolatorXYZ; m_pEngine->m_pExtrapolatorXYZ = NULL; } resi = sqrt( resi / (tf * (as->m_oaAtoms.size() + 1) * 3.0) ); if (presi != NULL) *presi = resi; if (realsize) { /* if (m_fResiCorrTraj != NULL) { mfprintf(m_fResiCorrTraj,"%.1f; %.4f\n",tb / tf,resi); fflush(m_fResiCorrTraj); }*/ return tb / tf; } else return resi; } double CBQBDriver::GoldenSectionSearch(double maxl, double eps, double (CBQBDriver::*fobj)(double)) { double a, c, fa, fc; a = 0; fa = (this->*fobj)(a); c = maxl; fc = (this->*fobj)(c); return REC_GoldenSectionSearch(a,c,c,fa,fc,fc,fobj,eps,0); } double CBQBDriver::REC_GoldenSectionSearch(double a, double b, double c, double fa, double fb, double fc, double (CBQBDriver::*fobj)(double), double eps, int depth) { double x, fx; if ((c - b) > (b - a)) x = b + (2 - (1 + sqrt(5)) / 2) * (c - b); else x = b - (2 - (1 + sqrt(5)) / 2) * (b - a); if (fabs(c - a) < eps) return (c + a) / 2.0; fx = (this->*fobj)(x); if (fx < fb) { if ((c - b) > (b - a)) return REC_GoldenSectionSearch(b, x, c, fb, fx, fc, fobj, eps, depth+1); else return REC_GoldenSectionSearch(a, x, b, fa, fx, fb, fobj, eps, depth+1); } else { if ((c - b) > (b - a)) return REC_GoldenSectionSearch(a, b, x, fa, fb, fx, fobj, eps, depth+1); else return REC_GoldenSectionSearch(x, b, c, fx, fb, fc, fobj, eps, depth+1); } } double CBQBDriver::OptimizeXYZ_ObjectiveTExpo(double texpo) { double entropy, resi; m_pPosParm->SetExtraTimeExpo(texpo); entropy = CompressXYZBenchmark( m_pPosParm, m_bOptXYZComment, // bool comment, m_bOptXYZRealSize, // bool realsize &resi, // double *presi NULL // std::vector > *tciaa ); if (m_IF.IsPL(BQB_PL_STANDARD)) { if (m_bOptXYZRealSize) m_IF.printf(" %5d %5d %8.3f %14.5f (%10.4f kiB)\n", m_pPosParm->GetExtraTRange(), m_pPosParm->GetExtraTOrder(), texpo, resi, entropy/1024.0 ); else m_IF.printf(" %5d %5d %8.3f %14.5f\n", m_pPosParm->GetExtraTRange(), m_pPosParm->GetExtraTOrder(), texpo, entropy ); } return entropy; } bool CBQBDriver::OptimizeXYZParameters( int level, CBQBParameterSet_Position *parm, bool comment, bool cubepart ) { int z, z2, z3, smr, smo, steps, btr, btr2; int tia[5]; double smv, tf, tflast, resi, btv, tfa[5], fac; bool realsize; unsigned long t0; char buf[256]; std::vector > rlist; std::vector > tciaa; std::vector iabl, iatc; CBQBBitSet bs(m_IF); CBQBIntegerEngine *tie; UNUSED(cubepart); tflast = 0; if (m_IF.IsPL(BQB_PL_STANDARD)) m_IF.bprintf(" >>> Position Trajectory Parameter Optimization >>>\n"); /* if (level == 3) { m_fResiCorrFrame = OpenFileWrite("corrframexyz.csv",true); m_fResiCorrTraj = OpenFileWrite("corrtrajxyz.csv",true); }*/ t0 = (unsigned long)time(NULL); if (level >= 3) realsize = true; else realsize = false; if (m_pEngine->m_pReadCacheCube != NULL) { m_pEngine->m_pReadCacheCube->RewindReadPos(); steps = m_pEngine->m_pReadCacheCube->GetCachedSteps(); } else { m_pEngine->m_pReadCacheXYZ->RewindReadPos(); steps = m_pEngine->m_pReadCacheXYZ->GetCachedSteps(); } if (m_IF.IsPL(BQB_PL_STANDARD)) { m_IF.printf(" Optimization level %d\n",level); if ((level == 1) && !cubepart) m_IF.printf(" Please note: Level 1 and 2 are identical for position trajectories.\n"); m_IF.printf(" Have %d cached steps.\n",steps); m_IF.printf(" Range Order Exponent Residuum\n"); } smv = 1.0e30; tf = 0; smr = -1; smo = -1; parm->SetUseExtra(true); //extratimeexpo = 1.0; for (z=1;z=0;z2--) { // torder // if ((z > 1) && (z2 == -1)) // continue; tflast = tf; parm->SetExtraTRange(z); parm->SetExtraTOrder(z2); tf = CompressXYZBenchmark( parm, comment, // bool comment, realsize, // bool realsize &resi, // double *presi NULL // std::vector > *tciaa ); if (m_IF.IsPL(BQB_PL_STANDARD)) { if (realsize) sprintf(buf," %5d %5d %8.3f %14.5f (%10.4f kiB)", z, z2, parm->GetExtraTimeExpo(), resi, tf/1024.0 ); else sprintf(buf," %5d %5d %8.3f %14.5f", z, z2, parm->GetExtraTimeExpo(), tf ); m_IF.printf("%s",(const char*)buf); } else buf[0] = 0; rlist.push_back(std::pair(tf,(const char*)buf)); if (tf < smv) { if (m_IF.IsPL(BQB_PL_STANDARD)) m_IF.printf(" <---"); smv = tf; smo = z2; smr = z; } if (m_IF.IsPL(BQB_PL_STANDARD)) m_IF.printf("\n"); if ((z2 < z-2) && (tflast < tf)) break; } } std::sort(rlist.begin(),rlist.end()); /* FILE *a; a = OpenFileWrite("optixyz_list.txt",true); mfprintf(a," Range Order Exponent Entropy\n"); for (z=0;z<(int)rlist.size();z++) mfprintf(a,"%s\n",rlist[z].second.c_str()); fclose(a);*/ parm->SetExtraTRange(smr); parm->SetExtraTOrder(smo); if (parm->GetExtraTOrder()+2 != parm->GetExtraTRange()) { m_pPosParm = parm; m_bOptXYZRealSize = realsize; if (m_IF.IsPL(BQB_PL_STANDARD)) m_IF.printf("\n"); tf = GoldenSectionSearch(7.0, (level>=3)?0.02:0.1, &CBQBDriver::OptimizeXYZ_ObjectiveTExpo); if (level >= 3) parm->SetExtraTimeExpo( floor(tf*1000.0+0.5)/1000.0 ); else parm->SetExtraTimeExpo( floor(tf*100.0+0.5)/100.0 ); } else parm->SetExtraTimeExpo( 0 ); if (level >= 2) { if (m_IF.IsPL(BQB_PL_STANDARD)) m_IF.printf(" Optimizing Compressor settings:\n"); tciaa.clear(); tf = CompressXYZBenchmark( parm, comment, // bool comment, true, // bool realsize NULL, // double *presi &tciaa // std::vector > *tciaa ); if (m_IF.IsPL(BQB_PL_STANDARD)) m_IF.printf(" TC BL BW MTF Frame Size [kiB]\n"); if (level >= 4) { iatc.push_back(1); iatc.push_back(2); iatc.push_back(3); iatc.push_back(4); iatc.push_back(6); iatc.push_back(8); /* iatc.push_back(10); iatc.push_back(12); iatc.push_back(15); iatc.push_back(18); iatc.push_back(21); iatc.push_back(24);*/ iabl.push_back(10); iabl.push_back(12); iabl.push_back(14); iabl.push_back(16); iabl.push_back(20); iabl.push_back(24); iabl.push_back(28); iabl.push_back(32); iabl.push_back(36); iabl.push_back(40); iabl.push_back(48); iabl.push_back(56); iabl.push_back(64); btv = 1.0e30; btr = -1; btr2 = -1; for (z=0;z<(int)iatc.size();z++) { for (z2=0;z2<(int)iabl.size();z2++) { parm->SetBlockLength(iabl[z2]); parm->SetTableCount(iatc[z]); tf = 0; for (z3=0;z3<(int)tciaa.size();z3++) { bs.Clear(); tie = new CBQBIntegerEngine(m_IF); tie->Compress( tciaa[z3], &bs, parm->GetCompressorParameterSet(), false, NULL ); delete tie; tf += bs.GetByteLength(); } if (m_IF.IsPL(BQB_PL_STANDARD)) m_IF.printf(" %2d %2d %3s %3s %10.4f", iatc[z], iabl[z2], parm->GetBW()?"yes":"no", parm->GetMTF()?"yes":"no", tf/tciaa.size()/1024.0 ); if (tf < btv) { btv = tf; if (m_IF.IsPL(BQB_PL_STANDARD)) m_IF.printf(" <---"); btr = z; btr2 = z2; } if (m_IF.IsPL(BQB_PL_STANDARD)) m_IF.printf("\n"); if (iatc[z] == 1) break; // One table: Block length does not matter } } parm->SetTableCount(iatc[btr]); parm->SetBlockLength(iabl[btr2]); } else { tia[0] = 1; tia[1] = 2; tia[2] = 3; tia[3] = 6; tia[4] = 12; btv = 1.0e30; btr = -1; for (z=0;z<5;z++) { tfa[z] = 0; for (z2=0;z2<(int)tciaa.size();z2++) { bs.Clear(); tie = new CBQBIntegerEngine(m_IF); parm->SetTableCount(tia[z]); tie->Compress( tciaa[z2], &bs, parm->GetCompressorParameterSet(), false, NULL ); delete tie; tfa[z] += bs.GetByteLength(); } if (m_IF.IsPL(BQB_PL_STANDARD)) m_IF.printf(" %2d %2d %3s %3s %10.4f", tia[z], parm->GetBlockLength(), parm->GetBW()?"yes":"no", parm->GetMTF()?"yes":"no", tfa[z]/tciaa.size()/1024.0 ); if (tfa[z] < btv) { btv = tfa[z]; btr = z; if (m_IF.IsPL(BQB_PL_STANDARD)) m_IF.printf(" <---"); } if (m_IF.IsPL(BQB_PL_STANDARD)) m_IF.printf("\n"); if ((z > 0) && (tfa[z] > tflast)) break; tflast = tfa[z]; } parm->SetTableCount(tia[btr]); if (parm->GetTableCount() != 1) { tia[0] = 12; tia[1] = 16; tia[2] = 24; tia[3] = 32; tia[4] = 40; btv = 1.0e30; btr = -1; for (z=0;z<5;z++) { tfa[z] = 0; for (z2=0;z2<(int)tciaa.size();z2++) { bs.Clear(); tie = new CBQBIntegerEngine(m_IF); parm->SetBlockLength(tia[z]); tie->Compress( tciaa[z2], &bs, parm->GetCompressorParameterSet(), false, NULL ); delete tie; tfa[z] += bs.GetByteLength(); } if (m_IF.IsPL(BQB_PL_STANDARD)) m_IF.printf(" %2d %2d %3s %3s %10.4f", parm->GetTableCount(), tia[z], parm->GetBW()?"yes":"no", parm->GetMTF()?"yes":"no", tfa[z]/tciaa.size()/1024.0 ); if (tfa[z] < btv) { btv = tfa[z]; btr = z; if (m_IF.IsPL(BQB_PL_STANDARD)) m_IF.printf(" <---"); } if (m_IF.IsPL(BQB_PL_STANDARD)) m_IF.printf("\n"); if ((z > 0) && (tfa[z] > tflast)) break; tflast = tfa[z]; } parm->SetBlockLength(tia[btr]); } } if (level >= 3) { for (z=0;z<3;z++) { switch(z) { case 0: parm->SetBW(true); parm->SetMTF(true); break; case 1: parm->SetBW(true); parm->SetMTF(false); break; case 2: parm->SetBW(false); parm->SetMTF(false); break; } tfa[z] = 0; for (z2=0;z2<(int)tciaa.size();z2++) { bs.Clear(); tie = new CBQBIntegerEngine(m_IF); tie->Compress( tciaa[z2], &bs, parm->GetCompressorParameterSet(), false, NULL ); delete tie; tfa[z] += bs.GetByteLength(); } if (m_IF.IsPL(BQB_PL_STANDARD)) m_IF.printf(" %2d %2d %3s %3s %10.4f\n", parm->GetTableCount(), parm->GetBlockLength(), parm->GetBW()?"yes":"no", parm->GetMTF()?"yes":"no", tfa[z]/tciaa.size()/1024.0 ); } fac = 1.0; if ((tfa[0] <= tfa[1]) && (tfa[0] <= tfa[2]/fac)) { parm->SetBW(true); parm->SetMTF(true); } else if ((tfa[1] <= tfa[0]) && (tfa[1] <= tfa[2]/fac)) { parm->SetBW(true); parm->SetMTF(false); } else { parm->SetBW(false); parm->SetMTF(false); } } } if (m_IF.IsPL(BQB_PL_STANDARD)) { BQBFormatTime((unsigned long)time(NULL)-t0,buf); m_IF.printf(" Optimization took %s\n",(const char*)buf); } /* if (m_fResiCorrFrame != NULL) { fclose(m_fResiCorrFrame); m_fResiCorrFrame = NULL; } if (m_fResiCorrTraj != NULL) { fclose(m_fResiCorrTraj); m_fResiCorrTraj = NULL; }*/ if (m_IF.IsPL(BQB_PL_STANDARD)) m_IF.bprintf(" <<< Position Trajectory Parameter Optimization Done <<<\n"); return true; } bool CBQBDriver::DecompressXYZ( const char *inp, const char *outp, const char *readref, int steps, int stride, CBQBParameterSet_Position *parm ) { UNUSED(stride); CBQBAtomSet *as, *as2; int z, z2, i, ty, ver, histused; CBQBBitSet bsat(m_IF); FILE *b, *fref; CBQBFile bf(m_IF); if (parm == NULL) parm = &m_ParmPos; if (m_IF.IsPL(BQB_PL_STANDARD)) m_IF.printf("Opening archive file \"%s\" ...\n",inp); if (!bf.OpenRead(inp)) { m_IF.eprintf("Error: Could not open file for reading.\n"); return false; } b = NULL; if (outp != NULL) { if (m_IF.IsPL(BQB_PL_STANDARD)) m_IF.printf("Opening output XYZ file \"%s\" ...\n",outp); b = fopen(outp,"wb"); if (b == NULL) { m_IF.eprintf("Error: Could not open file for writing.\n"); return false; } } fref = NULL; if (readref != NULL) { if (m_IF.IsPL(BQB_PL_STANDARD)) m_IF.printf("Opening reference XYZ file \"%s\" ...\n",readref); fref = fopen(readref,"rb"); if (fref == NULL) { m_IF.eprintf("Error: Could not open file for reading.\n"); fclose(b); return false; } } m_pEngine->m_oaOutputAtomBuf.resize(11); for (z=0;z<11;z++) m_pEngine->m_oaOutputAtomBuf[z] = NULL; m_pEngine->m_iOutputAtomBufPos = 0; if (m_IF.IsPL(BQB_PL_STANDARD)) m_IF.printf("Starting process...\n"); i = 0; while (true) { if (m_IF.IsPL(BQB_PL_VERBOSE)) m_IF.printf("\n\n"); if (!bf.ReadFrame()) break; ty = bf.GetFrameType(); ver = bf.GetFrameTypeVersion(); if ((ty == BQB_FRAMETYPE_IDX) || (ty == BQB_FRAMETYPE_COMPIDX)) continue; if ((ty == BQB_FRAMETYPE_COMPTRAJ) || (ty == BQB_FRAMETYPE_COMPTRAJSTART) || (ty == BQB_FRAMETYPE_COMPTRAJKEY)) { if (ver > BQB_FRAMETYPE_COMPTRAJ_VERSION) { m_IF.eprintf("Error: Unexpected frame type version (%d v%d).\n",ty,ver); m_IF.eprintf(" Probably the BQB file is more recent than the libbqb version.\n"); return false; } } else { m_IF.eprintf("Error: Unexpected frame type (%d v%d).\n",ty,ver); return false; } if (m_IF.IsPL(BQB_PL_STANDARD)) { if (i == 0) m_IF.printf("Reading first time step from compressed trajectory...\n"); else m_IF.printf(" Step %d ...\n",i+1); } if (m_IF.IsPL(BQB_PL_VERBOSE)) m_IF.printf("Atom block %lu bytes.\n",bf.GetFramePayload()->size()); as = new CBQBAtomSet(); m_pEngine->PushOutputAtomFrame(as); bsat.Clear(); bsat.m_iaData.assign(bf.GetFramePayload()->begin(),bf.GetFramePayload()->end()); m_pEngine->DecompressAtomFrame( &bsat, ver, parm, &histused, false, false ); if (m_IF.IsPL(BQB_PL_STANDARD) && (i == 0)) { m_IF.bprintf("\nThe following parameters have been used for compressing this file:\n\n"); m_IF.printf("%s\n",parm->ToString(4).c_str()); m_IF.bprintf("Parameter Key:"); m_IF.printf(" %s\n\n",parm->ToKey().c_str()); } if (readref != NULL) { if (m_IF.IsPL(BQB_PL_STANDARD)) m_IF.printf(" Comparing to reference...\n"); as2 = new CBQBAtomSet(); if (!as2->ReadXYZ(fref,as->m_iSigni,NULL)) break; for (z=0;z<(int)as2->m_oaAtoms.size();z++) { for (z2=0;z2<3;z2++) if (as->m_oaAtoms[z]->m_iCoord[z2] != as2->m_oaAtoms[z]->m_iCoord[z2]) m_IF.eprintf(" Error %d[%d]: %.6f != %.6f\n", z,z2,as->m_oaAtoms[z]->m_fCoord[z2],as2->m_oaAtoms[z]->m_fCoord[z2]); } delete as2; if (m_IF.IsPL(BQB_PL_VERBOSE)) m_IF.printf("Done.\n"); } if (m_IF.IsPL(BQB_PL_STANDARD)) m_IF.printf(" %8.3f KiB compressed data unpacked (history %2d).\n", bf.GetFramePayload()->size()/1024.0,histused); if (b != NULL) as->WriteXYZ(b,as->m_iSigni); if (m_IF.IsPL(BQB_PL_VERBOSE)) m_IF.printf("Done.\n"); i++; if (i == steps) break; } bf.Close(); if (b != NULL) fclose(b); if (readref != NULL) fclose(fref); if (m_IF.IsPL(BQB_PL_STANDARD)) m_IF.printf("Finished decompressing the XYZ file.\n\n"); return true; } bool CBQBDriver::CompressFile( const char *inp, const char *outp, const CBQBParameterSet_Compressor *parm ) { FILE *a; unsigned char buf[4096]; std::vector ia; CBQBBitSet bs(m_IF); CBQBIntegerEngine ie(m_IF); CBQBFile bf(m_IF); int i, z; CBQBStatistics stat(m_IF); if (m_IF.IsPL(BQB_PL_VERBOSE)) m_IF.printf(">>> CEngine::CompressFile >>>\n"); stat.m_oStat.reset(); a = fopen(inp,"rb"); if (a == NULL) { m_IF.eprintf("Error: Could not open file \"%s\" for reading.\n",inp); return false; } if (outp != NULL) { if (!bf.OpenWriteReplace(outp)) { m_IF.eprintf("Error: Could not open file \"%s\" for writing.\n",outp); fclose(a); return false; } } while (!feof(a)) { i = (int)fread(buf,1,4096,a); for (z=0;z>3).string()); m_IF.printf("%10.3f MiB (%12s Bytes) alphabet data.\n", double(stat.m_oStat.m_lAlphabet)/1024.0/1024.0/8.0,(stat.m_oStat.m_lAlphabet>>3).string()); m_IF.printf("%10.3f MiB (%12s Bytes) Huffman tables.\n", double(stat.m_oStat.m_lHuffmanTables)/1024.0/1024.0/8.0,(stat.m_oStat.m_lHuffmanTables>>3).string()); m_IF.printf("%10.3f MiB (%12s Bytes) table switching.\n", double(stat.m_oStat.m_lTableSwitch)/1024.0/1024.0/8.0,(stat.m_oStat.m_lTableSwitch>>3).string()); m_IF.printf("%10.3f MiB (%12s Bytes) payload data.\n", double(stat.m_oStat.m_lHuffmanData)/1024.0/1024.0/8.0,(stat.m_oStat.m_lHuffmanData>>3).string()); m_IF.printf("%10.3f MiB (%12s Bytes) in total.\n\n", double(stat.m_oStat.m_lOverhead+stat.m_oStat.m_lAlphabet+stat.m_oStat.m_lHuffmanTables+stat.m_oStat.m_lTableSwitch+stat.m_oStat.m_lHuffmanData)/1024.0/1024.0/8.0, ((stat.m_oStat.m_lOverhead+stat.m_oStat.m_lAlphabet+stat.m_oStat.m_lHuffmanTables+stat.m_oStat.m_lTableSwitch+stat.m_oStat.m_lHuffmanData)>>3).string()); } if (m_IF.IsPL(BQB_PL_VERBOSE)) m_IF.printf("<<< CEngine::CompressFile <<<\n"); return true; } bool CBQBDriver::DecompressFile(const char *inp, const char *outp, const char *ref) { UNUSED(ref); FILE *b; unsigned char buf[4096]; std::vector ia; CBQBBitSet bs(m_IF); CBQBIntegerEngine ie(m_IF); int z, z2; CBQBFile bf(m_IF); CBQBParameterSet_Compressor parm(m_IF); if (m_IF.IsPL(BQB_PL_VERBOSE)) m_IF.printf(">>> CEngine::DecompressFile >>>\n"); if (!bf.OpenRead(inp)) { m_IF.eprintf("Error: Could not open file \"%s\" for reading.\n",inp); return false; } b = fopen(outp,"wb"); if (b == NULL) { m_IF.eprintf("Error: Could not open file \"%s\" for writing.\n",outp); return false; } bf.ReadFrame(); if ((bf.GetFrameType() != BQB_FRAMETYPE_COMPFILE) || (bf.GetFrameTypeVersion() != 0)) { m_IF.eprintf("Error: Unexpected frame type (expected %d v0, found %d v%d).\n", BQB_FRAMETYPE_COMPFILE,bf.GetFrameType(),bf.GetFrameTypeVersion()); fclose(b); return false; } bs.m_iaData.assign(bf.GetFramePayload()->begin(),bf.GetFramePayload()->end()); bf.Close(); if (m_IF.IsPL(BQB_PL_STANDARD)) m_IF.printf("%lu bytes of payload read from input file.\n",bs.m_iaData.size()); if (!ie.Decompress( &bs, ia, &parm )) { if (m_IF.IsPL(BQB_PL_STANDARD)) m_IF.eprintf("IntegerEngine returned an error.\n"); fclose(b); return false; } if (m_IF.IsPL(BQB_PL_VERBOSE)) m_IF.printf("Decompressed to %lu Bytes.\n",ia.size()); if (m_IF.IsPL(BQB_PL_STANDARD)) { m_IF.bprintf("\nThe following parameters have been used for compressing this file:\n\n"); m_IF.printf("%s\n",parm.ToString(4).c_str()); m_IF.bprintf("Parameter Key:"); m_IF.printf(" %s\n\n",parm.ToKey().c_str()); } for (z=0;z<(int)ia.size()/4096;z++) { for (z2=0;z2<4096;z2++) buf[z2] = (unsigned char)ia[z*4096+z2]; fwrite(buf,4096,1,b); } if ((ia.size()%4096) != 0) { for (z2=0;z2<(int)ia.size()%4096;z2++) buf[z2] = (unsigned char)ia[z*4096+z2]; fwrite(buf,ia.size()%4096,1,b); } fclose(b); if (m_IF.IsPL(BQB_PL_VERBOSE)) m_IF.printf("<<< CEngine::DecompressFile <<<\n"); return true; } bool CBQBDriver::MergeBQB(const char *outfile, const std::vector &infile) { int z, i, zi, zo; CBQBFile *pout; std::vector pin; CBQBStatistics stat(m_IF); if (m_IF.IsPL(BQB_PL_STANDARD)) { m_IF.printf("\n"); m_IF.printf(" *****************************\n"); m_IF.printf(" *** Merging BQB Files ***\n"); m_IF.printf(" *****************************\n\n"); m_IF.printf(" Will merge the input files\n"); for (z=0;z<(int)infile.size();z++) m_IF.printf(" [%d] %s\n",z+1,infile[z]); m_IF.printf(" into the output file %s.\n\n",outfile); } if (m_IF.IsPL(BQB_PL_STANDARD)) m_IF.printf(" Opening input files...\n"); pin.resize(infile.size()); for (z=0;z<(int)infile.size();z++) { if (m_IF.IsPL(BQB_PL_STANDARD)) m_IF.printf(" [%d] %s... ",z+1,infile[z]); pin[z] = new CBQBFile(m_IF); if (!pin[z]->OpenRead(infile[z])) { if (m_IF.IsPL(BQB_PL_STANDARD)) m_IF.eprintf("Error.\n"); return false; } if (m_IF.IsPL(BQB_PL_STANDARD)) { if ((i = pin[z]->GetTotalFrameCount()) != -1) m_IF.printf("Ok, %d frames (index).",i); else m_IF.printf("Ok, no index."); m_IF.printf("\n"); } } if (m_IF.IsPL(BQB_PL_STANDARD)) m_IF.printf("\n Opening output file...\n"); pout = new CBQBFile(m_IF); if (!pout->OpenWriteReplace(outfile)) { if (m_IF.IsPL(BQB_PL_STANDARD)) m_IF.eprintf("Error.\n"); return false; } zo = 0; for (z=0;z<(int)pin.size();z++) { if (m_IF.IsPL(BQB_PL_STANDARD)) m_IF.printf(" Processing input file %d.\n",z+1); zi = 0; while (true) { if (!pin[z]->ReadFrame()) { if (m_IF.IsPL(BQB_PL_STANDARD)) m_IF.printf(" Reached end of input file %d after reading %d frames.\n", z+1,zi); break; } zi++; if (m_IF.IsPL(BQB_PL_STANDARD)) m_IF.printf(" Input file %d frame %6d: Type %2d.%d, ID %6d, Size %7.2f KiB", z+1, zi, pin[z]->GetFrameType(), pin[z]->GetFrameTypeVersion(), pin[z]->GetFrameID(), pin[z]->GetFramePayload()->size()/1024.0 ); if ((pin[z]->GetFrameType() == 2) || (pin[z]->GetFrameType() == 3)) { if (m_IF.IsPL(BQB_PL_STANDARD)) m_IF.printf(" --> Skipping index frame.\n"); continue; } if (m_IF.IsPL(BQB_PL_STANDARD)) m_IF.printf(" --> Output frame %6d.\n",zo); pout->CreateShortFrame( pin[z]->GetFrameType(), pin[z]->GetFrameTypeVersion(), pin[z]->GetFrameID() ); pout->PushPayload(*pin[z]->GetFramePayload()); pout->FinalizeFrame(&stat); zo++; } } if (m_IF.IsPL(BQB_PL_STANDARD)) m_IF.printf(" Merged %d frames from %lu input files into output file.\n\n", zo,infile.size()); if (m_IF.IsPL(BQB_PL_STANDARD)) m_IF.printf(" Writing new index frame for output file...\n"); pout->WriteIndexFrame(true,&stat); if (m_IF.IsPL(BQB_PL_STANDARD)) m_IF.printf(" All done.\n\n"); pout->Close(); delete pout; for (z=0;z<(int)pin.size();z++) { pin[z]->Close(); delete pin[z]; } return true; } /*bool CBQBEngine::SplitBQB(const char *infile, const char *outbase, int splitlength, int steps, bool verbose) { int z, z2, i, k, ofc, ofc2, al, cl; int ao, co, aorder, corder; int lcsize, lasize, ty, ver; bool err, to; CBQBFile bqin, *bqout; CBQBCubeFrame *cfr, *cfr2; CBQBBitSet bshe, bsat, bscu, bstemp; CxString buf; lcsize = 1000000000; // To avoid "use of uninitialized variable" warning lasize = 1000000000; ofc = 0; ofc2 = 0; m_IF.printf("\n"); m_IF.printf(WHITE," ******************************\n"); m_IF.printf(WHITE," *** Splitting BQB File ***\n"); m_IF.printf(WHITE," ******************************\n\n"); SetBarbecubeVerbose(verbose); if (!bqin.OpenRead(infile)) { m_IF.eprintf("CBQBEngine::SplitBQB(): Error: Could not open BQB file \"%s\" for reading.\n",infile); return false; } m_oaOutputCubeBuf.resize(9); m_oaOutput2CubeBuf.resize(9); m_oaInputCubeBuf.resize(9); m_oaInputAtomBuf.resize(9); m_oaOutputAtomBuf.resize(9); m_oaOutput2AtomBuf.resize(9); for (z=0;z<9;z++) { m_oaInputCubeBuf[z] = NULL; m_oaOutputCubeBuf[z] = NULL; m_oaOutput2CubeBuf[z] = NULL; m_oaInputAtomBuf[z] = NULL; m_oaOutputAtomBuf[z] = NULL; m_oaOutput2AtomBuf[z] = NULL; } m_iInputCubeBufPos = 0; m_iOutputCubeBufPos = 0; m_iOutput2CubeBufPos = 0; m_iInputAtomBufPos = 0; m_iOutputAtomBufPos = 0; m_iOutput2AtomBufPos = 0; i = 0; k = 0; aorder = 8; corder = 8; bqout = NULL; to = false; m_IF.printf("\n"); while (true) { m_IF.printf(" Reading input frame %d...\n",i+1); if (!bqin.ReadFrame()) { m_IF.printf("Could not read further frame from input file.\n"); break; } ty = bqin.GetFrameType(); ver = bqin.GetFrameTypeVersion(); if ((ty == 2) || (ty == 3)) { m_IF.printf(" Skipping index frame.\n"); goto _skip; } if ((ty != 8) && (ty != 9)) { m_IF.eprintf("CBQBEngine::SplitBQB(): Error: Splitting only implemented for compressed cube frames yet.\n"); return false; } if (bqout == NULL) { buf.sprintf("%s%03d.bqb",outbase,k+1); m_IF.printf("Creating next output file \"%s\".\n",(const char*)buf); bqout = new CBQBFile(); if (!bqout->OpenWriteReplace((const char*)buf)) { m_IF.eprintf("CBQBEngine::SplitBQB(): Error: Could not open BQB file \"%s\" for writing.\n",(const char*)buf); return false; } lcsize = 1000000000; lasize = 1000000000; aorder = 8; corder = 8; ofc = 0; ofc2 = 0; } m_IF.printf(" Decompressing...\n"); bshe.Clear(); bshe.m_iaData.assign(bqin.GetFramePayload()->begin(),bqin.GetFramePayload()->begin()+8); al = bshe.ReadBitsInteger(32); cl = bshe.ReadBitsInteger(32); cfr = new CBQBCubeFrame(); PushOutputCubeFrame(cfr); PushInputCubeFrame_NoDelete(cfr); cfr->m_pAtoms = new CBQBAtomSet(); PushOutputAtomFrame(cfr->m_pAtoms); PushInputAtomFrame_NoDelete(cfr->m_pAtoms); bsat.Clear(); bsat.m_iaData.assign(bqin.GetFramePayload()->begin()+8,bqin.GetFramePayload()->begin()+8+al); bscu.Clear(); bscu.m_iaData.assign(bqin.GetFramePayload()->begin()+8+al,bqin.GetFramePayload()->begin()+8+al+cl); if (!DecompressAtomFrame(&bsat,ver,verbose,false)) return false; if (!DecompressCubeFrame(&bscu,ver,verbose,false)) return false; if (ofc >= 9) { m_IF.printf(" Pass-through writing output file %d, frame %d...\n",k+1,ofc+1); bqout->CreateShortFrame((ofc==0)?BQB_FRAMETYPE_COMPCUBESTART:BQB_FRAMETYPE_COMPCUBE,0,i+1); bqout->PushPayload(*bqin.GetFramePayload()); bqout->FinalizeFrame(); } else { m_IF.printf(" Re-compressing...\n"); _again: if (ofc2 < corder) co = ofc2; else if (ofc < corder) co = ofc; else co = corder; if (ofc2 < aorder) ao = ofc2; else if (ofc < aorder) ao = ofc; else ao = aorder; _aagain: bsat.Clear(); CompressAtomFrame( &bsat, ao, 6, // aprecision 31, // asplit 40, // ablock 4, // atables false, // optatables true, // acoderun true, // abw true, // amtf (ofc2>=2), // apreopt 10, // amaxiter true, // asortatom (ofc==0), // atominfo true, // keepcomment 0, // amaxchunk verbose ); m_IF.printf(" Atoms: Order %d, output size %9.3f KiB.\n",ao,bsat.GetByteLength()/1024.0); if (lasize >= 0) { if (to) { to = false; if (bsat.GetByteLength() <= bstemp.GetByteLength()) { m_IF.printf(" Size is indeed smaller with lower order. Limiting atom order to %d.\n",ao); aorder = ao; lasize = -1; } else { m_IF.printf(" Size was smaller with higher order. Not limiting.\n"); bsat = CBQBBitSet(bstemp); lasize = bsat.GetByteLength(); } } else { if ((ao != 0) && ((double)bsat.GetByteLength() >= (double)lasize*0.97)) { m_IF.printf(" Size did not decrease any further with order %d. Trying order %d...\n",ao,ao-1); bstemp = CBQBBitSet(bsat); to = true; ao--; goto _aagain; } else if (ao == aorder) lasize = -1; else lasize = bsat.GetByteLength(); } } _cagain: bscu.Clear(); CompressCubeFrame( &bscu, co, 12, // ceps 5, // csigni 31, // csplit 40, // cblock 6, // ctables false, // copttables true, // chilbert 1.075, // nbhfac true, // ccoderun false, // cbw false, // cmtf false, // cpreopt 10, // cmaxiter (ofc==0), // atominfo 0, // cmaxchunk verbose ); m_IF.printf(" Cube: Order %d, output size %9.3f KiB.\n",co,bscu.GetByteLength()/1024.0); if (lcsize >= 0) { if (to) { to = false; if (bscu.GetByteLength() <= bstemp.GetByteLength()) { m_IF.printf(" Size is indeed smaller with lower order. Limiting cube order to %d.\n",co); corder = co; lcsize = -1; } else { m_IF.printf(" Size was smaller with higher order. Not limiting.\n"); bscu = CBQBBitSet(bstemp); lcsize = bscu.GetByteLength(); } } else { if ((co != 0) && ((double)bscu.GetByteLength() >= (double)lcsize*0.97)) { m_IF.printf(" Size did not decrease any further with order %d. Trying order %d...\n",co,co-1); bstemp = CBQBBitSet(bscu); to = true; co--; goto _cagain; } else if (co == corder) lcsize = -1; else lcsize = bscu.GetByteLength(); } } m_IF.printf(" Comparing input and output...\n"); cfr2 = new CBQBCubeFrame(); PushOutput2CubeFrame(cfr2); cfr2->m_pAtoms = new CBQBAtomSet(); PushOutput2AtomFrame(cfr2->m_pAtoms); DecompressAtomFrame(&bsat,1,verbose,true); DecompressCubeFrame(&bscu,1,verbose,true); err = false; for (z=0;z<(int)cfr2->m_pAtoms->m_oaAtoms.size();z++) for (z2=0;z2<3;z2++) if (cfr->m_pAtoms->m_oaAtoms[z]->m_iCoord[z2] != cfr2->m_pAtoms->m_oaAtoms[z]->m_iCoord[z2]) { m_IF.eprintf(" Error in atom coordinate %d[%d]: %.6f (%ld) != %.6f (%ld)\n",z,z2,cfr->m_pAtoms->m_oaAtoms[z]->m_fCoord[z2],cfr->m_pAtoms->m_oaAtoms[z]->m_iCoord[z2],cfr2->m_pAtoms->m_oaAtoms[z]->m_fCoord[z2],cfr2->m_pAtoms->m_oaAtoms[z]->m_iCoord[z2]); err = true; } for (z=0;zm_iResXYZ;z++) if (!ExpMantisEqual(cfr->m_iaExpo[z],cfr->m_iaMantis[z],cfr2->m_iaExpo[z],cfr2->m_iaMantis[z])) { m_IF.eprintf(" Error in volumetric data element %7d: %.10G vs %.10G\n",z,cfr->m_faBin[z],cfr2->m_faBin[z]); err = true; } if (err) { if (ofc2 != 0) { m_IF.eprintf("Errors occured. Compressing frame again with order zero.\n"); err = false; ofc2 = 0; goto _again; } else { m_IF.eprintf("Errors occured despite of order zero. Aborting.\n"); return false; } } bshe.Clear(); bshe.WriteBits(bsat.GetByteLength(),32); bshe.WriteBits(bscu.GetByteLength(),32); m_IF.printf(" Writing output file %d, frame %d...\n",k+1,ofc+1); bqout->CreateShortFrame((ofc2==0)?BQB_FRAMETYPE_COMPCUBESTART:BQB_FRAMETYPE_COMPCUBE,0,i+1); bqout->PushPayload(bshe.m_iaData); bqout->PushPayload(bsat.m_iaData); bqout->PushPayload(bscu.m_iaData); bqout->FinalizeFrame(); } _skip: i++; ofc++; ofc2++; if ((i % splitlength) == 0) { m_IF.printf("Closing output file \"%s\".\n",(const char*)buf); bqout->WriteIndexFrame(true); bqout->Close(); delete bqout; bqout = NULL; k++; } if (i == steps) { m_IF.printf("Reached step limit.\n\n"); break; } } if (bqout != NULL) { m_IF.printf("Closing output file \"%s\".\n\n",(const char*)buf); bqout->WriteIndexFrame(true); bqout->Close(); delete bqout; bqout = NULL; k++; } m_IF.printf("Processed %d frames, wrote %d output files.\n\n",i,k); bqin.Close(); // Those are duplicates of the output buffers and deleted there m_oaInputAtomBuf.clear(); m_oaInputCubeBuf.clear(); m_IF.printf("All done. Leaving.\n"); return true; }*/ travis-src-190101/src/bqb_driver.h0100777000000000000000000001034013412725665013732 0ustar00/*********************************************************************************** LibBQB - File Format and Compression Algorithms for Trajectories of Volumetric Data and Atom Positions https://brehm-research.de/bqb Free software, licensed under GNU LGPL v3 Copyright (c) Martin Brehm and Martin Thomas, Martin Luther University Halle-Wittenberg, Germany, 2016 - 2019. Please cite: M. Brehm, M. Thomas: "An Efficient Lossless Compression Algorithm for Trajectories of Atom Positions and Volumetric Data", J. Chem. Inf. Model. 2018, 58 (10), pp 2092-2107. -------------------------------------------------------------------------------- LibBQB is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program. If not, see . ***********************************************************************************/ #ifndef BQB_DRIVER_H #define BQB_DRIVER_H // This must always be the first include directive #include "bqb_config.h" #include "bqb_engine.h" #include "bqb_interface.h" #include class CBQBDriver { public: CBQBDriver(CBQBInterface &i); ~CBQBDriver(); bool MergeBQB(const char *outfile, const std::vector &infile); // bool SplitBQB(const char *infile, const char *outbase, int splitlength, int steps); bool CompressFile( const char *inp, const char *outp, const CBQBParameterSet_Compressor *parm ); bool DecompressFile(const char *inp, const char *outp, const char *ref); bool CompressCube( const char *inp, const char *outp, const char *ref, int start, int steps, int stride, int keyfreq, CBQBParameterSet_PosAndVol *parm, int optimize, int optsteps, bool onlyopt, bool comment, bool compare, bool dummyread ); double CompressCubeBenchmark( CBQBParameterSet_Volumetric *parm, bool realsize, double *presi, std::vector > *tciaa ); double OptimizeCube_ObjectiveTExpo(double texpo); double OptimizeCube_ObjectiveSExpo(double sexpo); bool OptimizeCubeParameters( int level, CBQBParameterSet_Volumetric *parm ); bool DecompressCube( const char *inp, const char *outp, const char *readref, int steps, int stride, CBQBParameterSet_PosAndVol *parm ); bool CompressXYZ( const char *inp, const char *outp, const char *ref, int start, int steps, int stride, int keyfreq, CBQBParameterSet_Position *parm, bool comment, bool compare, int optimize, int optsteps, bool onlyopt ); double CompressXYZBenchmark( CBQBParameterSet_Position *parm, bool comment, bool realsize, double *presi, std::vector > *tciaa ); double GoldenSectionSearch(double maxl, double eps, double (CBQBDriver::*fobj)(double)); double REC_GoldenSectionSearch( double a, double b, double c, double fa, double fb, double fc, double (CBQBDriver::*fobj)(double), double eps, int depth ); double OptimizeXYZ_ObjectiveTExpo(double texpo); bool OptimizeXYZParameters( int level, CBQBParameterSet_Position *parm, bool comment, bool cubepart ); bool DecompressXYZ( const char *inp, const char *outp, const char *readref, int steps, int stride, CBQBParameterSet_Position *parm ); CBQBEngine *m_pEngine; CBQBParameterSet_Volumetric *m_pVolParm; CBQBParameterSet_Position *m_pPosParm; CBQBParameterSet_PosAndVol m_ParmPosAndVol; CBQBParameterSet_Position m_ParmPos; std::vector m_iaAtomOrd; int m_iHistogramCounter; bool m_bOptCubeRealSize; bool m_bOptXYZComment; bool m_bOptXYZRealSize; int m_iOptIncludeFirst; private: CBQBInterface &m_IF; }; #endif travis-src-190101/src/bqb_engine.cpp0100777000000000000000000033222413412725635014244 0ustar00/*********************************************************************************** LibBQB - File Format and Compression Algorithms for Trajectories of Volumetric Data and Atom Positions https://brehm-research.de/bqb Free software, licensed under GNU LGPL v3 Copyright (c) Martin Brehm and Martin Thomas, Martin Luther University Halle-Wittenberg, Germany, 2016 - 2019. Please cite: M. Brehm, M. Thomas: "An Efficient Lossless Compression Algorithm for Trajectories of Atom Positions and Volumetric Data", J. Chem. Inf. Model. 2018, 58 (10), pp 2092-2107. -------------------------------------------------------------------------------- LibBQB is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program. If not, see . ***********************************************************************************/ // This must always be the first include directive #include "bqb_config.h" #include "bqb_tools.h" #include #include #include #include "bqb_engine.h" #include "bqb_hilbert.h" #include "bqb_integerengine.h" #include "bqb_bitset.h" #include "bqb_crc.h" #include "bqb_format.h" #include "bqb_math.h" const char *GetRevisionInfo_bqb_engine(unsigned int len) { static char buf[256]; GET_REVISION_INFO( buf, len ); return buf; } const char *GetSourceVersion_bqb_engine() { static char buf[256]; GET_SOURCE_VERSION( buf ); return buf; } #define AR_EPS (0.0001) #define CR_EPS (0.0001) CBQBEngine::CBQBEngine(CBQBInterface &i) : m_pExtrapolator(NULL), m_pExtrapolatorCorr(NULL), m_pExtrapolatorXYZ(NULL), m_pReadCacheXYZ(NULL), m_pReadCacheCube(NULL), m_IF(i) { } CBQBEngine::~CBQBEngine() { int z; for (z=0;z<(int)m_oaOutputAtomBuf.size();z++) { if (m_oaOutputAtomBuf[z] != NULL) { delete m_oaOutputAtomBuf[z]; m_oaOutputAtomBuf[z] = NULL; } } for (z=0;z<(int)m_oaOutputCubeBuf.size();z++) { if (m_oaOutputAtomBuf[z] != NULL) { delete m_oaOutputCubeBuf[z]; m_oaOutputCubeBuf[z] = NULL; } } for (z=0;z<(int)m_oaOutput2AtomBuf.size();z++) { if (m_oaOutputAtomBuf[z] != NULL) { delete m_oaOutput2AtomBuf[z]; m_oaOutput2AtomBuf[z] = NULL; } } for (z=0;z<(int)m_oaOutput2CubeBuf.size();z++) { if (m_oaOutputAtomBuf[z] != NULL) { delete m_oaOutput2CubeBuf[z]; m_oaOutput2CubeBuf[z] = NULL; } } if (m_pExtrapolator != NULL) { delete m_pExtrapolator; m_pExtrapolator = NULL; } if (m_pExtrapolatorCorr != NULL) { delete m_pExtrapolatorCorr; m_pExtrapolatorCorr = NULL; } if (m_pExtrapolatorXYZ != NULL) { delete m_pExtrapolatorXYZ; m_pExtrapolatorXYZ = NULL; } if (m_pReadCacheXYZ != NULL) { delete m_pReadCacheXYZ; m_pReadCacheXYZ = NULL; } if (m_pReadCacheCube != NULL) { delete m_pReadCacheCube; m_pReadCacheCube = NULL; } } void CBQBEngine::Reset() { int z; for (z=0;z<(int)m_oaOutputAtomBuf.size();z++) { if (m_oaOutputAtomBuf[z] != NULL) { delete m_oaOutputAtomBuf[z]; m_oaOutputAtomBuf[z] = NULL; } } for (z=0;z<(int)m_oaOutputCubeBuf.size();z++) { if (m_oaOutputAtomBuf[z] != NULL) { delete m_oaOutputCubeBuf[z]; m_oaOutputCubeBuf[z] = NULL; } } for (z=0;z<(int)m_oaOutput2AtomBuf.size();z++) { if (m_oaOutputAtomBuf[z] != NULL) { delete m_oaOutput2AtomBuf[z]; m_oaOutput2AtomBuf[z] = NULL; } } for (z=0;z<(int)m_oaOutput2CubeBuf.size();z++) { if (m_oaOutputAtomBuf[z] != NULL) { delete m_oaOutput2CubeBuf[z]; m_oaOutput2CubeBuf[z] = NULL; } } if (m_pExtrapolator != NULL) m_pExtrapolator->Reset(); if (m_pExtrapolatorCorr != NULL) m_pExtrapolatorCorr->Reset(); if (m_pExtrapolatorXYZ != NULL) m_pExtrapolatorXYZ->Reset(); if (m_pReadCacheXYZ != NULL) { delete m_pReadCacheXYZ; m_pReadCacheXYZ = NULL; } if (m_pReadCacheCube != NULL) { delete m_pReadCacheCube; m_pReadCacheCube = NULL; } } typedef struct { unsigned long m_iN; unsigned long m_iH; } THilbertPair; int CompareHilbertPair( const void *arg1, const void *arg2 ) { if (((THilbertPair*)arg1)->m_iH > ((THilbertPair*)arg2)->m_iH) return 1; else if (((THilbertPair*)arg1)->m_iH < ((THilbertPair*)arg2)->m_iH) return -1; else return 0; } void CBQBEngine::BuildHilbertIdx(int resx, int resy, int resz) { int b, bt; int resxyz, resyz; bitmask_t mi; unsigned long crd[3], /*crd2[3],*/ tul; FILE *a; unsigned char *uc; THilbertPair *hlist; CBQBTools bqbtools(m_IF); if (m_IF.IsPL(BQB_PL_VERBOSE)) m_IF.printf("\nCreating Hilbert curve index table...\n"); else if (m_IF.IsPL(BQB_PL_STANDARD)) m_IF.printf(" Creating Hilbert curve index table (%dx%dx%d)...\n",resx,resy,resz); b = (int)(ceil(mylog2(resx))+0.5); bt = (int)(ceil(mylog2(resy))+0.5); if (bt > b) b = bt; bt = (int)(ceil(mylog2(resz))+0.5); if (bt > b) b = bt; mi = ((unsigned long)2)<<(3*b-1); if (b > 10) { m_IF.eprintf("CBQBEngine::BuildHilbertIdx(): Error: Cube file resolution is too large (%d x %d x %d).\n\n", resx,resy,resz); m_IF.printf("Resolutions >= 1024 are not supported by Hilbert curve indexing.\n"); m_IF.printf("You can disable Hilbert curve indexing by specifying \"-chilbert no\".\n"); abort(); } resxyz = resx*resy*resz; resyz = resy*resz; m_iaHilbertIdx.resize(resxyz); if (m_IF.IsPL(BQB_PL_VERBOSE)) { m_IF.printf("Resolution %d | %d | %d --> Bits %d\n",resx,resy,resz,b); m_IF.printf("Requires %lu indices, %.3f MiB of RAM.\n",mi,resxyz*sizeof(int)/1024.0/1024.0); m_IF.printf("Running...\n"); } if (m_IF.IsPL(BQB_PL_STANDARD)) { m_IF.printf(" ["); m_IF.FlushLog(); } uc = new unsigned char[resxyz]; memset(uc,0,resxyz); /* int ti; bitmask_t index, coords[3]; ti = 0; for (index=0;index= resx) || ((long)coords[1] >= resy) || ((long)coords[0] >= resz)) continue; m_iaHilbertIdx[ti] = coords[2]*resyz+coords[1]*resz+coords[0]; uc[m_iaHilbertIdx[ti]]++; ti++; }*/ hlist = new THilbertPair[resxyz]; for (crd[0]=0;(long)crd[0] 1) { m_IF.eprintf("CBQBEngine::BuildHilbertIdx(): Error: Element %d touched multiple times (%u).\n", b,uc[b]); m_IF.eprintf("Hilbert curve index creation failed.\n"); m_IF.printf("\nYou can disable Hilbert curve indexing by specifying \"-chilbert no\".\n"); abort(); } if (uc[b] == 0) { m_IF.eprintf("CBQBEngine::BuildHilbertIdx(): Error: Element %d never touched.\n",b); m_IF.eprintf("Hilbert curve index creation failed.\n"); m_IF.printf("\nYou can disable Hilbert curve indexing by specifying \"-chilbert no\".\n"); abort(); } } delete[] uc; if (m_IF.IsPL(BQB_PL_VERBOSE)) { m_IF.printf("Finished. %lu entries.\n",m_iaHilbertIdx.size()); m_IF.printf("Dumping Hilbert index to file \"hilbert.csv\"...\n"); a = bqbtools.BQBOpenFileWrite("hilbert.csv",true); m_IF.printf(" ["); for (b=0;bIsCubic()) { bs->WriteBit(1); bs->WriteBits( (unsigned long)(ci->m_mCell(0,0)*10000.0+0.5), 32 ); } else { bs->WriteBit(0); if (ci->IsOrthorhombic()) { bs->WriteBit(1); bs->WriteBits( (unsigned long)(ci->m_mCell(0,0)*10000.0+0.5), 32 ); bs->WriteBits( (unsigned long)(ci->m_mCell(1,1)*10000.0+0.5), 32 ); bs->WriteBits( (unsigned long)(ci->m_mCell(2,2)*10000.0+0.5), 32 ); } else { bs->WriteBit(0); bs->WriteSignedBits( (long)(ci->m_mCell(0,0)*10000.0+0.5), 32 ); bs->WriteSignedBits( (long)(ci->m_mCell(0,1)*10000.0+0.5), 32 ); bs->WriteSignedBits( (long)(ci->m_mCell(0,2)*10000.0+0.5), 32 ); bs->WriteSignedBits( (long)(ci->m_mCell(1,0)*10000.0+0.5), 32 ); bs->WriteSignedBits( (long)(ci->m_mCell(1,1)*10000.0+0.5), 32 ); bs->WriteSignedBits( (long)(ci->m_mCell(1,2)*10000.0+0.5), 32 ); bs->WriteSignedBits( (long)(ci->m_mCell(2,0)*10000.0+0.5), 32 ); bs->WriteSignedBits( (long)(ci->m_mCell(2,1)*10000.0+0.5), 32 ); bs->WriteSignedBits( (long)(ci->m_mCell(2,2)*10000.0+0.5), 32 ); } } } bool CBQBEngine::ImportCellInfo(CBQBCellInfo *ci, CBQBBitSet *bs) { double tfxx, tfxy, tfxz, tfyx, tfyy, tfyz, tfzx, tfzy, tfzz; if (bs->ReadBit()) { // Cubic tfxx = ((double)bs->ReadBitsInteger(32))/10000.0; ci->SetCellInfo( tfxx, tfxx, tfxx ); } else { // Not Cubic if (bs->ReadBit()) { // Orthorhombic tfxx = ((double)bs->ReadBitsInteger(32))/10000.0; tfyy = ((double)bs->ReadBitsInteger(32))/10000.0; tfzz = ((double)bs->ReadBitsInteger(32))/10000.0; ci->SetCellInfo( tfxx, tfyy, tfzz ); } else { // Non-orthorhombic tfxx = ((double)bs->ReadBitsSignedInteger(32))/10000.0; tfxy = ((double)bs->ReadBitsSignedInteger(32))/10000.0; tfxz = ((double)bs->ReadBitsSignedInteger(32))/10000.0; tfyx = ((double)bs->ReadBitsSignedInteger(32))/10000.0; tfyy = ((double)bs->ReadBitsSignedInteger(32))/10000.0; tfyz = ((double)bs->ReadBitsSignedInteger(32))/10000.0; tfzx = ((double)bs->ReadBitsSignedInteger(32))/10000.0; tfzy = ((double)bs->ReadBitsSignedInteger(32))/10000.0; tfzz = ((double)bs->ReadBitsSignedInteger(32))/10000.0; ci->SetCellInfo( tfxx, tfxy, tfxz, tfyx, tfyy, tfyz, tfzx, tfzy, tfzz ); } } return true; } //#define DEBUG_VOL_ELEMENT_FROM 0 //#define DEBUG_VOL_ELEMENT_TO 2 bool CBQBEngine::CubeToIntegerArray( std::vector &outp, int order, CBQBParameterSet_Volumetric *parm, int &histused, bool skipcomp, double *resi ) { int z, z2, ti, tiov, tiuf, tiuf2, zx, zy, zz, zi, ii, ex, res, mantis, split; const CBQBCubeFrame *cfr; double tf=0, tf2, tf3, tfa2; int maxsymb; bool uf, of; if (parm == NULL) { m_IF.eprintf("CBQBEngine::CubeToIntegerArray(): Error: parm == NULL.\n"); return false; } /* CDF df; if (resi != NULL) { df.m_iResolution = 250; df.m_fMinVal = 0.0; df.m_fMaxVal = 8.0; df.Create(); }*/ if (m_IF.IsPL(BQB_PL_VERBOSE)) m_IF.printf("** CubeToIntegerArray order=%d ***\n",order); split = ((unsigned long)1) << parm->GetSplit(); cfr = m_pReadCacheCube->GetFrameHistory(0); if (!skipcomp) // Reserve some space (lower boundary estimate) outp.reserve(outp.size()+cfr->m_iResXYZ); maxsymb = pow10i(parm->GetSigni())-1; if (m_pExtrapolator != NULL) { if (order+1 < m_pExtrapolator->m_iCubeFrameVisibleCount) m_pExtrapolator->m_iCubeFrameVisibleCount = order+1; histused = MIN( m_pExtrapolator->m_iTRange, m_pExtrapolator->m_iCubeFrameVisibleCount ) - 1; } else histused = order; if (m_pExtrapolator != NULL) { if (m_IF.IsPL(BQB_PL_VERBOSE)) { m_IF.printf("Extrapolator running...\n"); m_IF.printf(" ["); } if (m_pExtrapolatorCorr != NULL) { m_faTempPred.resize(cfr->m_iResXYZ); m_faTempPred2.resize(cfr->m_iResXYZ); if (m_IF.IsPL(BQB_PL_VERBOSE)) tf = cfr->m_iRes[0] / 60.0; zi = 0; for (zx=0;zxm_iRes[0];zx++) { if (m_IF.IsPL(BQB_PL_VERBOSE)) { if (fmod(zx,tf) < 1.0) { m_IF.printf("#"); m_IF.FlushLog(); } } for (zy=0;zym_iRes[1];zy++) { if ((zx >= m_pExtrapolatorCorr->m_iSOffset[0]) && (zx <= m_pExtrapolatorCorr->m_iTempVal[0]) && (zy >= m_pExtrapolatorCorr->m_iSOffset[1]) && (zy <= m_pExtrapolatorCorr->m_iTempVal[1])) { for (zz=0;zzm_iSOffset[2];zz++) { tf2 = m_pExtrapolator->ExtrapolatePred(zi); //m_faTempPred[zi] = ((double)cfr->m_iaMantis[zi]*pow10(cfr->m_iaExpo[zi])) - tf2; m_faTempPred[zi] = cfr->m_faBin[zi] - tf2; m_faTempPred2[zi] = tf2 + m_pExtrapolatorCorr->ExtrapolateCorr(m_faTempPred,zx,zy,zz,zi); zi++; } for (;zz<=m_pExtrapolatorCorr->m_iTempVal[2];zz++) { tf2 = m_pExtrapolator->ExtrapolatePred(zi); //m_faTempPred[zi] = ((double)cfr->m_iaMantis[zi]*pow10(cfr->m_iaExpo[zi])) - tf2; m_faTempPred[zi] = cfr->m_faBin[zi] - tf2; m_faTempPred2[zi] = tf2 + m_pExtrapolatorCorr->ExtrapolateKnownCorr(m_faTempPred,0,zi); zi++; } for (;zzm_iRes[2];zz++) { tf2 = m_pExtrapolator->ExtrapolatePred(zi); //m_faTempPred[zi] = ((double)cfr->m_iaMantis[zi]*pow10(cfr->m_iaExpo[zi])) - tf2; m_faTempPred[zi] = cfr->m_faBin[zi] - tf2; m_faTempPred2[zi] = tf2 + m_pExtrapolatorCorr->ExtrapolateCorr(m_faTempPred,zx,zy,zz,zi); zi++; } } else { for (zz=0;zzm_iRes[2];zz++) { tf2 = m_pExtrapolator->ExtrapolatePred(zi); //m_faTempPred[zi] = ((double)cfr->m_iaMantis[zi]*pow10(cfr->m_iaExpo[zi])) - tf2; m_faTempPred[zi] = cfr->m_faBin[zi] - tf2; m_faTempPred2[zi] = tf2 + m_pExtrapolatorCorr->ExtrapolateCorr(m_faTempPred,zx,zy,zz,zi); zi++; } } } } } else { m_faTempPred2.resize(cfr->m_iResXYZ); if (m_IF.IsPL(BQB_PL_VERBOSE)) tf = cfr->m_iRes[0] / 60.0; zi = 0; for (zx=0;zxm_iRes[0];zx++) { if (m_IF.IsPL(BQB_PL_VERBOSE)) { if (fmod(zx,tf) < 1.0) { m_IF.printf("#"); m_IF.FlushLog(); } } for (zy=0;zym_iRes[1];zy++) { for (zz=0;zzm_iRes[2];zz++) { m_faTempPred2[zi] = m_pExtrapolator->Extrapolate(zx,zy,zz,zi); zi++; } } } } if (m_IF.IsPL(BQB_PL_VERBOSE)) m_IF.printf("] Done.\n"); } else { // No Extrapolator m_faTempPred.resize(cfr->m_iResXYZ); m_faTempPred2.resize(cfr->m_iResXYZ); for (z=0;zm_iResXYZ;z++) m_faTempPred[z] = 0; if (m_IF.IsPL(BQB_PL_VERBOSE)) m_IF.printf("Polynomial extrapolation...\n"); for (z=1;zGetFrameHistory(z); tf = 1.0; for (z2=1;z2<=order;z2++) { if (z2 == z) continue; tf *= z2 / ((double)z2 - z); } for (z2=0;z2m_iResXYZ;z2++) m_faTempPred[z2] += tf * cfr->m_iaMantis[z2] * pow10(cfr->m_iaExpo[z2]); } cfr = m_pReadCacheCube->GetFrameHistory(0); if (parm->GetNbhFac() != 0) { if (m_IF.IsPL(BQB_PL_VERBOSE)) m_IF.printf("Neighborhood extrapolation...\n"); zi = 0; for (zx=0;zxm_iRes[0];zx++) { for (zy=0;zym_iRes[1];zy++) { for (zz=0;zzm_iRes[2];zz++) { tf2 = 0; tf3 = 0; if (zz > 0) { tf2++; tf3 += ((double)cfr->m_iaMantis[zi-1]*pow10(cfr->m_iaExpo[zi-1])) - m_faTempPred[zi-1]; } if (zy > 0) { tf2++; tf3 += ((double)cfr->m_iaMantis[zi-cfr->m_iRes[2]]*pow10(cfr->m_iaExpo[zi-cfr->m_iRes[2]])) - m_faTempPred[zi-cfr->m_iRes[2]]; } if (zx > 0) { tf2++; tf3 += ((double)cfr->m_iaMantis[zi-cfr->m_iResYZ]*pow10(cfr->m_iaExpo[zi-cfr->m_iResYZ])) - m_faTempPred[zi-cfr->m_iResYZ]; } if (tf2 != 0) tf3 /= tf2 * parm->GetNbhFac(); tf3 += m_faTempPred[zi]; m_faTempPred2[zi] = tf3; zi++; } } } } else m_faTempPred2.assign(m_faTempPred.begin(),m_faTempPred.end()); } // End No Extrapolator if (m_IF.IsPL(BQB_PL_VERBOSE)) m_IF.printf("Discretizing and serializing symbols...\n"); tiov = 0; tiuf = 0; tiuf2 = 0; tfa2 = 0; for (zi=0;zim_iResXYZ;zi++) { if (parm->GetHilbert()) ii = m_iaHilbertIdx[zi]; else ii = zi; if (m_faTempPred2[ii] == 0) ex = -parm->GetEps(); else ex = (int)floor(log10(fabs(m_faTempPred2[ii])))-parm->GetSigni()+1; if (ex < -parm->GetEps()) ex = -parm->GetEps(); uf = false; of = false; _again: mantis = (int)floor(cfr->m_faBin[ii]*pow10(-ex)+0.5); if (floor(m_faTempPred2[ii]*pow10(-ex)+0.5+CR_EPS) != floor(m_faTempPred2[ii]*pow10(-ex)+0.5-CR_EPS)) { ti = (int)floor(m_faTempPred2[ii]*pow10(-ex)); // m_IF.printf("Sanitized rounding of %f.\n",m_faTempPred2[ii]*pow10(-ex)); } else ti = (int)floor(m_faTempPred2[ii]*pow10(-ex)+0.5); res = mantis - ti; if (resi != NULL) { *resi += sqrt(bqbabs(res)); //*resi += mypow(fabs(res),m_fEntropyExpoCube); //if (res != 0) // df.AddToBin(log10(fabs(res))); } if (skipcomp) continue; if (ExpMantisEqual(cfr->m_iaExpo[ii],cfr->m_iaMantis[ii],ex,mantis) && (abs(res) <= maxsymb)) { if (uf) outp.push_back(C_UNDERFLOW); if (of) outp.push_back(C_OVERFLOW); if (abs(res) >= split) { #ifdef DEBUG_VOL_ELEMENT_FROM if ((ii >= DEBUG_VOL_ELEMENT_FROM) && (ii <= DEBUG_VOL_ELEMENT_TO)) m_IF.printf("@> %d: Equal with split (%d): %d = %d & %d\n",ii,split,res,res/split,abs(res)%split); #endif outp.push_back(C_SPLIT); outp.push_back(res/split); if (res < 0) outp.push_back(-(abs(res)%split)); else outp.push_back(res%split); } else { outp.push_back(res); #ifdef DEBUG_VOL_ELEMENT_FROM if ((ii >= DEBUG_VOL_ELEMENT_FROM) && (ii <= DEBUG_VOL_ELEMENT_TO)) m_IF.printf("@> %d: Equal without split: %d\n",ii,res); #endif } } else if ((ex == cfr->m_iaExpo[ii]+1) && (ex > -parm->GetEps())) { tiuf2++; ex--; // tia.push_back(maxsymb+2); uf = true; #ifdef DEBUG_VOL_ELEMENT_FROM if ((ii >= DEBUG_VOL_ELEMENT_FROM) && (ii <= DEBUG_VOL_ELEMENT_TO)) m_IF.printf("@> %d: Soft Underflow 1.\n",ii); #endif goto _again; } else if (ex == cfr->m_iaExpo[ii]-1) { tiuf2++; ex++; of = true; #ifdef DEBUG_VOL_ELEMENT_FROM if ((ii >= DEBUG_VOL_ELEMENT_FROM) && (ii <= DEBUG_VOL_ELEMENT_TO)) m_IF.printf("@> %d: Soft Underflow 2.\n",ii); #endif goto _again; } else if (ex > cfr->m_iaExpo[ii]) { tiuf++; outp.push_back(C_FULLNUMBER); outp.push_back(cfr->m_iaExpo[ii]); outp.push_back(cfr->m_iaMantis[ii]/split); if (cfr->m_iaMantis[ii] < 0) outp.push_back(-(abs(cfr->m_iaMantis[ii])%split)); else outp.push_back(cfr->m_iaMantis[ii]%split); if (m_IF.IsPL(BQB_PL_VERBOSE)) m_IF.printf("Underflow %d\n",ex-cfr->m_iaExpo[ii]); #ifdef DEBUG_VOL_ELEMENT_FROM if ((ii >= DEBUG_VOL_ELEMENT_FROM) && (ii <= DEBUG_VOL_ELEMENT_TO) && (!verbose)) m_IF.printf("@> %d: Underflow %d\n",ii,ex-cfr->m_iaExpo[ii]); #endif } else if (abs(res) > maxsymb) { tiov++; outp.push_back(C_FULLNUMBER); #ifdef DEBUG_VOL_ELEMENT_FROM if ((ii >= DEBUG_VOL_ELEMENT_FROM) && (ii <= DEBUG_VOL_ELEMENT_TO)) m_IF.printf("@> %d: @0: %d\n",ii,outp[outp.size()-1]); #endif outp.push_back(cfr->m_iaExpo[ii]); outp.push_back(cfr->m_iaMantis[ii]/split); if (cfr->m_iaMantis[ii] < 0) outp.push_back(-(abs(cfr->m_iaMantis[ii])%split)); else outp.push_back(cfr->m_iaMantis[ii]%split); #ifdef DEBUG_VOL_ELEMENT_FROM if ((ii >= DEBUG_VOL_ELEMENT_FROM) && (ii <= DEBUG_VOL_ELEMENT_TO)) m_IF.printf("@> %d: Full Number: %d %d %d\n", ii,cfr->m_iaExpo[ii],cfr->m_iaMantis[ii]/split,abs(cfr->m_iaMantis[ii])%split); #endif } else { if (m_IF.IsPL(BQB_PL_VERBOSE)) m_IF.printf("UE: idx=%d, val=%.10f, pred=%.10f, cexpo=%d, pexpo=%d, cmantis=%d, pmantis=%d, res=%d.\n", ii,cfr->m_faBin[ii],m_faTempPred2[ii],cfr->m_iaExpo[ii],ex,cfr->m_iaMantis[ii],mantis,res); outp.push_back(C_FULLNUMBER); outp.push_back(cfr->m_iaExpo[ii]); outp.push_back(cfr->m_iaMantis[ii]/split); if (cfr->m_iaMantis[ii] < 0) outp.push_back(-(abs(cfr->m_iaMantis[ii])%split)); else outp.push_back(cfr->m_iaMantis[ii]%split); } #ifdef DEBUG_VOL_ELEMENT_FROM if ((ii >= DEBUG_VOL_ELEMENT_FROM) && (ii <= DEBUG_VOL_ELEMENT_TO)) m_IF.printf("@> UE: idx=%6d, val=%.10f, pred=%.22f, cexpo=%d, pexpo=%d, cmantis=%d, pmantis=%d, res=%d.\n", ii,cfr->m_faBin[ii],m_faTempPred2[ii],cfr->m_iaExpo[ii],ex,cfr->m_iaMantis[ii],mantis,res); #endif tfa2 += res; } if (m_IF.IsPL(BQB_PL_VERBOSE)) { tfa2 /= cfr->m_iResXYZ; m_IF.printf(" tfa2 = %8.6f\n",tfa2); m_IF.printf(" Overflow: %d, Underflow: %d, Soft Underflow: %d\n",tiov,tiuf,tiuf2); m_IF.printf(" Produced %lu symbols.\n",outp.size()); } /* if (resi != 0) { df.NormBinIntegral(1000.0); CxString buf; buf.sprintf("histo%06d.csv",gc_iHistogramCounter++); df.Write("",(const char*)buf,"",false); }*/ return true; } bool CBQBEngine::IntegerArrayToCube( std::vector &inp, int order, CBQBParameterSet_Volumetric *parm, int ver, bool second ) { int z, z2, zx, zy, zz, zi, ii, ex, split; CBQBCubeFrame *ofr, *cfr; double tf, tf2, tf3; std::vector tresi, texpo, tmantis; if (m_IF.IsPL(BQB_PL_VERBOSE)) m_IF.printf("** IntegerArrayToCube order=%d ***\n",order); if (ver >= 1) split = ((unsigned long)1) << parm->GetSplit(); else split = parm->GetSplit(); // Backward compatibility with bug if (second) ofr = GetOutput2CubeFrame(0); else ofr = GetOutputCubeFrame(0); m_faTempPred.resize(ofr->m_iResXYZ); if (m_pExtrapolator == NULL) { for (z=0;zm_iResXYZ;z++) m_faTempPred[z] = 0; if (m_IF.IsPL(BQB_PL_VERBOSE)) m_IF.printf("Polynomial extrapolation...\n"); for (z=1;zm_iResXYZ;z2++) m_faTempPred[z2] += tf * cfr->m_iaMantis[z2] * pow10(cfr->m_iaExpo[z2]); } } else { if (order+1 > m_pExtrapolator->m_iCubeFrameVisibleCount) { m_IF.eprintf("CBQBEngine::IntegerArrayToCube(): Error: Frame is of temporal order %d, step history is too short (%d).\n", order,m_pExtrapolator->m_iCubeFrameVisibleCount); abort(); } m_pExtrapolator->m_iCubeFrameVisibleCount = order+1; if (m_pExtrapolatorCorr != NULL) for (z2=0;z2m_iResXYZ;z2++) m_faTempPred[z2] = m_pExtrapolator->ExtrapolatePred(z2); } tresi.resize(ofr->m_iResXYZ); texpo.resize(ofr->m_iResXYZ); tmantis.resize(ofr->m_iResXYZ); if (m_IF.IsPL(BQB_PL_VERBOSE)) m_IF.printf("Decoding input...\n"); zi = 0; z = 0; while (zi < (int)inp.size()) { if (parm->GetHilbert()) ii = m_iaHilbertIdx[z]; else ii = z; if (inp[zi] == C_FULLNUMBER) { // Full Number texpo[ii] = inp[++zi]; tmantis[ii] = inp[++zi]*split; tmantis[ii] += inp[zi+1]; // if (inp[zi+1] < 0) // tmantis[ii] = -tmantis[ii]; #ifdef DEBUG_VOL_ELEMENT_FROM if ((ii >= DEBUG_VOL_ELEMENT_FROM) && (ii <= DEBUG_VOL_ELEMENT_TO)) m_IF.printf("@< %d: Full Number: %d %d %d --> %d %d\n", ii,inp[zi-1],inp[zi],inp[zi+1],texpo[ii],tmantis[ii]); #endif zi++; } else if (inp[zi] == C_UNDERFLOW) { // Soft Underflow if (inp[++zi] == C_SPLIT) { #ifdef DEBUG_VOL_ELEMENT_FROM if ((ii >= DEBUG_VOL_ELEMENT_FROM) && (ii <= DEBUG_VOL_ELEMENT_TO)) m_IF.printf("@< %d: Soft Underflow with split: %d & %d = %d\n", ii,inp[zi+1],inp[zi+2],inp[zi+1]*split+inp[zi+2]); #endif tresi[ii] = inp[++zi]*split; tresi[ii] += inp[zi+1]; // if (inp[zi+1] < 0) // tresi[ii] = -tresi[ii]; zi++; #ifdef DEBUG_VOL_ELEMENT_FROM if ((ii >= DEBUG_VOL_ELEMENT_FROM) && (ii <= DEBUG_VOL_ELEMENT_TO)) m_IF.printf("@< %d: --> %d\n",ii,tresi[ii]); #endif } else { #ifdef DEBUG_VOL_ELEMENT_FROM if ((ii >= DEBUG_VOL_ELEMENT_FROM) && (ii <= DEBUG_VOL_ELEMENT_TO)) m_IF.printf("@< %d: Soft Underflow without split.\n",ii); #endif tresi[ii] = inp[zi]; } texpo[ii] = -101; } else if (inp[zi] == C_OVERFLOW) { // Soft Overflow if (inp[++zi] == C_SPLIT) { #ifdef DEBUG_VOL_ELEMENT_FROM if ((ii >= DEBUG_VOL_ELEMENT_FROM) && (ii <= DEBUG_VOL_ELEMENT_TO)) m_IF.printf("@< %d: Soft Underflow with split: %d & %d = %d\n", ii,inp[zi+1],inp[zi+2],inp[zi+1]*split+inp[zi+2]); #endif tresi[ii] = inp[++zi]*split; tresi[ii] += inp[zi+1]; // if (inp[zi+1] < 0) // tresi[ii] = -tresi[ii]; zi++; #ifdef DEBUG_VOL_ELEMENT_FROM if ((ii >= DEBUG_VOL_ELEMENT_FROM) && (ii <= DEBUG_VOL_ELEMENT_TO)) m_IF.printf("@< %d: --> %d\n",ii,tresi[ii]); #endif } else { #ifdef DEBUG_VOL_ELEMENT_FROM if ((ii >= DEBUG_VOL_ELEMENT_FROM) && (ii <= DEBUG_VOL_ELEMENT_TO)) m_IF.printf("@< %d: Soft Underflow without split.\n",ii); #endif tresi[ii] = inp[zi]; } texpo[ii] = -102; } else if (inp[zi] == C_SPLIT) { // Splitted Residue tresi[ii] = inp[++zi]*split; tresi[ii] += inp[zi+1]; // if (inp[zi+1] < 0) // tresi[ii] = -tresi[ii]; zi++; texpo[ii] = -100; #ifdef DEBUG_VOL_ELEMENT_FROM if ((ii >= DEBUG_VOL_ELEMENT_FROM) && (ii <= DEBUG_VOL_ELEMENT_TO)) m_IF.printf("@< %d: Splitted residue.\n",ii); #endif } else { // Standard Residue tresi[ii] = inp[zi]; texpo[ii] = -100; #ifdef DEBUG_VOL_ELEMENT_FROM if ((ii >= DEBUG_VOL_ELEMENT_FROM) && (ii <= DEBUG_VOL_ELEMENT_TO)) m_IF.printf("@< %d: Standard residue.\n",ii); #endif } #ifdef DEBUG_VOL_ELEMENT_FROM if ((ii >= DEBUG_VOL_ELEMENT_FROM) && (ii <= DEBUG_VOL_ELEMENT_TO)) m_IF.printf("@< %d: resi=%d, expo=%d, mantis=%d\n",ii,tresi[ii],texpo[ii],tmantis[ii]); #endif zi++; z++; } if (m_IF.IsPL(BQB_PL_VERBOSE)) { m_IF.printf("Read %d symbols and %d grid points.\n",zi,z); m_IF.printf("Neighborhood extrapolation...\n"); } zi = 0; for (zx=0;zxm_iRes[0];zx++) { for (zy=0;zym_iRes[1];zy++) { for (zz=0;zzm_iRes[2];zz++) { if (texpo[zi] > -100) { ofr->m_iaMantis[zi] = tmantis[zi]; ofr->m_iaExpo[zi] = (char)texpo[zi]; ofr->m_faBin[zi] = ofr->m_iaMantis[zi] * pow10(ofr->m_iaExpo[zi]); if (m_pExtrapolatorCorr != NULL) { #ifdef DEBUG_VOL_ELEMENT_FROM if ((zi >= DEBUG_VOL_ELEMENT_FROM) && (zi <= DEBUG_VOL_ELEMENT_TO)) m_IF.printf("@< %d: X-Updating TempPred %.10G with true %.10G: %.10G\n", zi,m_faTempPred[zi],ofr->m_faBin[zi],ofr->m_faBin[zi]-m_faTempPred[zi]); #endif m_faTempPred[zi] = ofr->m_faBin[zi] - m_faTempPred[zi]; } zi++; continue; } if (m_pExtrapolator != NULL) { if (m_pExtrapolatorCorr != NULL) { tf3 = m_faTempPred[zi] + m_pExtrapolatorCorr->ExtrapolateCorr(m_faTempPred,zx,zy,zz,zi); #ifdef DEBUG_VOL_ELEMENT_FROM if ((zi >= DEBUG_VOL_ELEMENT_FROM) && (zi <= DEBUG_VOL_ELEMENT_TO)) m_IF.printf("@< %d: Pred %.10G, Corr %.10G --> %.10G\n", zi,m_faTempPred[zi],tf3-m_faTempPred[zi],tf3); #endif } else tf3 = m_pExtrapolator->Extrapolate(zx,zy,zz,zi); } else { // Classical Neighborhood correction tf2 = 0; tf3 = 0; if (parm->GetNbhFac() != 0) { if (zz > 0) { tf2++; tf3 += ((double)ofr->m_iaMantis[zi-1]*pow10(ofr->m_iaExpo[zi-1])) - m_faTempPred[zi-1]; } if (zy > 0) { tf2++; tf3 += ((double)ofr->m_iaMantis[zi-ofr->m_iRes[2]]*pow10(ofr->m_iaExpo[zi-ofr->m_iRes[2]])) - m_faTempPred[zi-ofr->m_iRes[2]]; } if (zx > 0) { tf2++; tf3 += ((double)ofr->m_iaMantis[zi-ofr->m_iResYZ]*pow10(ofr->m_iaExpo[zi-ofr->m_iResYZ])) - m_faTempPred[zi-ofr->m_iResYZ]; } if (tf2 != 0) tf3 /= tf2 * parm->GetNbhFac(); } tf3 += m_faTempPred[zi]; } if (tf3 == 0) ex = -parm->GetEps(); else ex = (int)floor(log10(fabs(tf3)))-parm->GetSigni()+1; if (ex < -parm->GetEps()) ex = -parm->GetEps(); if (texpo[zi] == -101) ex--; else if (texpo[zi] == -102) ex++; if (floor(tf3*pow10(-ex)+0.5+CR_EPS) != floor(tf3*pow10(-ex)+0.5-CR_EPS)) { ofr->m_iaMantis[zi] = (int)floor(tf3*pow10(-ex)); // m_IF.printf("Sanitized rounding of %f.\n",tf3*pow10(-ex)); } else ofr->m_iaMantis[zi] = (int)floor(tf3*pow10(-ex)+0.5); ofr->m_iaMantis[zi] += tresi[zi]; ofr->m_iaExpo[zi] = (char)ex; //while (ofr->m_iaMantis[zi] >= pow10i(signi)) { while (abs(ofr->m_iaMantis[zi]) >= pow10i(parm->GetSigni())) { #ifdef DEBUG_VOL_ELEMENT_FROM if ((zi >= DEBUG_VOL_ELEMENT_FROM) && (zi <= DEBUG_VOL_ELEMENT_TO)) m_IF.printf("@< %d: A %d %d %d\n",zi,ofr->m_iaMantis[zi],ofr->m_iaExpo[zi],parm->GetSigni()); #endif ofr->m_iaMantis[zi] /= 10; ofr->m_iaExpo[zi]++; } //while ((ofr->m_iaMantis[zi] < pow10i(signi-1)) && (ofr->m_iaExpo[zi] > -eps)) { while ((abs(ofr->m_iaMantis[zi]) < pow10i(parm->GetSigni()-1)) && (ofr->m_iaExpo[zi] > -parm->GetEps())) { #ifdef DEBUG_VOL_ELEMENT_FROM if ((zi >= DEBUG_VOL_ELEMENT_FROM) && (zi <= DEBUG_VOL_ELEMENT_TO)) m_IF.printf("@< %d: B %d %d %d\n",zi,ofr->m_iaMantis[zi],ofr->m_iaExpo[zi],parm->GetSigni()); #endif ofr->m_iaMantis[zi] *= 10; ofr->m_iaExpo[zi]--; } ofr->m_faBin[zi] = ofr->m_iaMantis[zi] * pow10(ofr->m_iaExpo[zi]); if (m_pExtrapolatorCorr != NULL) { #ifdef DEBUG_VOL_ELEMENT_FROM if ((zi >= DEBUG_VOL_ELEMENT_FROM) && (zi <= DEBUG_VOL_ELEMENT_TO)) m_IF.printf("@< %d: Updating TempPred %.10G with true %.10G: %.10G\n", zi,m_faTempPred[zi],ofr->m_faBin[zi],ofr->m_faBin[zi]-m_faTempPred[zi]); #endif m_faTempPred[zi] = ofr->m_faBin[zi] - m_faTempPred[zi]; } #ifdef DEBUG_VOL_ELEMENT_FROM if ((zi >= DEBUG_VOL_ELEMENT_FROM) && (zi <= DEBUG_VOL_ELEMENT_TO)) m_IF.printf("@< %d: Pred=%.22f, expo=%d, predmantis=%d, resi=%d, mantis=%d, result=%.10f\n", zi,tf3,ex,(int)floor(tf3*pow10(-ex)+0.5),tresi[zi],ofr->m_iaMantis[zi],ofr->m_faBin[zi]); #endif zi++; } } } if (m_IF.IsPL(BQB_PL_VERBOSE)) m_IF.printf("All done.\n"); return true; } void CBQBEngine::ExportCubeHeader(CBQBBitSet *bs, int order) { const CBQBCubeFrame *cfr; int i; if (m_IF.IsPL(BQB_PL_VERBOSE)) m_IF.printf("Writing cube header...\n"); if (order != 0) { if (m_IF.IsPL(BQB_PL_VERBOSE)) m_IF.printf("Cube header already written before.\n"); bs->WriteBit(0); return; } else bs->WriteBit(1); i = bs->GetLength(); cfr = m_pReadCacheCube->GetFrameHistory(0); bs->WriteBits(cfr->m_iRes[0],10); bs->WriteBits(cfr->m_iRes[1],10); bs->WriteBits(cfr->m_iRes[2],10); bs->WriteSignedBits(cfr->m_iCenter[0],32); bs->WriteSignedBits(cfr->m_iCenter[1],32); bs->WriteSignedBits(cfr->m_iCenter[2],32); bs->WriteSignedBits(cfr->m_iStrideA[0],32); bs->WriteSignedBits(cfr->m_iStrideA[1],32); bs->WriteSignedBits(cfr->m_iStrideA[2],32); bs->WriteSignedBits(cfr->m_iStrideB[0],32); bs->WriteSignedBits(cfr->m_iStrideB[1],32); bs->WriteSignedBits(cfr->m_iStrideB[2],32); bs->WriteSignedBits(cfr->m_iStrideC[0],32); bs->WriteSignedBits(cfr->m_iStrideC[1],32); bs->WriteSignedBits(cfr->m_iStrideC[2],32); if (m_IF.IsPL(BQB_PL_VERBOSE)) m_IF.printf("%d bytes written.\n",(bs->GetLength()-i)/8); } void CBQBEngine::ImportCubeHeader(CBQBBitSet *bs, bool second) { CBQBCubeFrame *ofr, *ofr2; int z, i; if (second) ofr = GetOutput2CubeFrame(0); else ofr = GetOutputCubeFrame(0); if (m_IF.IsPL(BQB_PL_VERBOSE)) m_IF.printf("Reading cube header...\n"); i = bs->GetReadPos(); if (!bs->ReadBit()) { // Header already found in previous frame if (second) ofr2 = GetOutput2CubeFrame(1); else ofr2 = GetOutputCubeFrame(1); if (ofr2 == NULL) { m_IF.printf("CEngine::ImportCubeHeader(): Error: First frame does not contain header.\n"); return; } if (m_IF.IsPL(BQB_PL_VERBOSE)) m_IF.printf("Cube header already read before.\n"); for (z=0;z<3;z++) { ofr->m_iRes[z] = ofr2->m_iRes[z]; ofr->m_iCenter[z] = ofr2->m_iCenter[z]; ofr->m_iStrideA[z] = ofr2->m_iStrideA[z]; ofr->m_iStrideB[z] = ofr2->m_iStrideB[z]; ofr->m_iStrideC[z] = ofr2->m_iStrideC[z]; ofr->m_fCenter[z] = ofr2->m_fCenter[z]; ofr->m_fStrideA[z] = ofr2->m_fStrideA[z]; ofr->m_fStrideB[z] = ofr2->m_fStrideB[z]; ofr->m_fStrideC[z] = ofr2->m_fStrideC[z]; } } else { // Header here for (z=0;z<3;z++) ofr->m_iRes[z] = bs->ReadBitsInteger(10); for (z=0;z<3;z++) { ofr->m_iCenter[z] = bs->ReadBitsSignedInteger(32); ofr->m_fCenter[z] = FixedToFloat(ofr->m_iCenter[z],6); } for (z=0;z<3;z++) { ofr->m_iStrideA[z] = bs->ReadBitsSignedInteger(32); ofr->m_fStrideA[z] = FixedToFloat(ofr->m_iStrideA[z],6); } for (z=0;z<3;z++) { ofr->m_iStrideB[z] = bs->ReadBitsSignedInteger(32); ofr->m_fStrideB[z] = FixedToFloat(ofr->m_iStrideB[z],6); } for (z=0;z<3;z++) { ofr->m_iStrideC[z] = bs->ReadBitsSignedInteger(32); ofr->m_fStrideC[z] = FixedToFloat(ofr->m_iStrideC[z],6); } } ofr->m_fMinVal[0] = ofr->m_fCenter[0]; ofr->m_fMaxVal[0] = ofr->m_fCenter[0] + ofr->m_fStrideA[0] * ofr->m_iRes[0]; ofr->m_fMinVal[1] = ofr->m_fCenter[1]; ofr->m_fMaxVal[1] = ofr->m_fCenter[1] + ofr->m_fStrideB[1] * ofr->m_iRes[1]; ofr->m_fMinVal[2] = ofr->m_fCenter[2]; ofr->m_fMaxVal[2] = ofr->m_fCenter[2] + ofr->m_fStrideC[2] * ofr->m_iRes[2]; if (m_IF.IsPL(BQB_PL_VERBOSE)) { m_IF.printf("Resolution: %d x %d x %d\n",ofr->m_iRes[0],ofr->m_iRes[1],ofr->m_iRes[2]); m_IF.printf("Center: %f | %f | %f\n",ofr->m_fCenter[0],ofr->m_fCenter[1],ofr->m_fCenter[2]); m_IF.printf("Stride A: %f | %f | %f\n",ofr->m_fStrideA[0],ofr->m_fStrideA[1],ofr->m_fStrideA[2]); m_IF.printf("Stride B: %f | %f | %f\n",ofr->m_fStrideB[0],ofr->m_fStrideB[1],ofr->m_fStrideB[2]); m_IF.printf("Stride C: %f | %f | %f\n",ofr->m_fStrideC[0],ofr->m_fStrideC[1],ofr->m_fStrideC[2]); m_IF.printf("Range: X %f - %f, Y %f - %f, Z %f - %f\n", ofr->m_fMinVal[0],ofr->m_fMaxVal[0],ofr->m_fMinVal[1],ofr->m_fMaxVal[1],ofr->m_fMinVal[2],ofr->m_fMaxVal[2]); m_IF.printf("%d bytes read.\n",(bs->GetReadPos()-i)/8); } ofr->m_iResXY = ofr->m_iRes[0] * ofr->m_iRes[1]; ofr->m_iResYZ = ofr->m_iRes[1] * ofr->m_iRes[2]; ofr->m_iResXYZ = ofr->m_iRes[0] * ofr->m_iRes[1] * ofr->m_iRes[2]; ofr->m_faBin.resize(ofr->m_iResXYZ); ofr->m_iaExpo.resize(ofr->m_iResXYZ); ofr->m_iaMantis.resize(ofr->m_iResXYZ); } //#define DEBUG_POS_ELEMENT 0 void CBQBEngine::AtomsToIntegerArray( std::vector &outp, int order, CBQBParameterSet_Position *parm, int &histused, bool skipcomp, double *resi ) { int z, z2, i, zc, zi; long mantis, ti, res; int split; double tf; const CBQBAtomSet *cfr; std::vector tpred; double compred; if (parm == NULL) { m_IF.eprintf("CBQBEngine::AtomsToIntegerArray(): Error: parm == NULL.\n"); abort(); } if (m_IF.IsPL(BQB_PL_VERBOSE)) m_IF.printf("\n*** AtomsToIntegerArray order=%d, signi=%d, esplit=%d, split=%lu ***\n", order,parm->GetPrecision(),parm->GetSplit(),((unsigned long)1)<GetSplit()); i = (int)outp.size(); if (m_pReadCacheCube != NULL) cfr = m_pReadCacheCube->GetFrameHistory(0)->m_pAtoms; else cfr = m_pReadCacheXYZ->GetFrameHistory(0); if (m_IF.IsPL(BQB_PL_VERBOSE)) m_IF.printf("Processing %lu atoms...\n",cfr->m_oaAtoms.size()); split = ((unsigned long)1)<GetSplit(); tpred.resize(cfr->m_oaAtoms.size()); if (m_pExtrapolatorXYZ != NULL) { if (order+1 < m_pExtrapolatorXYZ->m_iCubeFrameVisibleCount) m_pExtrapolatorXYZ->m_iCubeFrameVisibleCount = order+1; histused = MIN( m_pExtrapolatorXYZ->m_iTRange, m_pExtrapolatorXYZ->m_iCubeFrameVisibleCount ) - 1; } else histused = order; if (m_IF.IsPL(BQB_PL_VERBOSE)) m_IF.printf(">> histused %d\n",histused); for (zc=0;zc<3;zc++) { if (m_IF.IsPL(BQB_PL_VERBOSE)) m_IF.printf("*** Now coordinate %d/3...\n",zc+1); if (m_pExtrapolatorXYZ != NULL) { if (m_IF.IsPL(BQB_PL_VERBOSE)) m_IF.printf("Extrapolator...\n"); for (z=0;z<(int)cfr->m_oaAtoms.size();z++) tpred[z] = m_pExtrapolatorXYZ->ExtrapolateXYZ(m_iaAtomSort[z],zc); compred = m_pExtrapolatorXYZ->ExtrapolateXYZ((int)cfr->m_oaAtoms.size(),zc); } else { if (m_IF.IsPL(BQB_PL_VERBOSE)) m_IF.printf("Polynomial extrapolation...\n"); for (z=0;z<(int)cfr->m_oaAtoms.size();z++) tpred[z] = 0; compred = 0; for (z=1;zGetFrameHistory(z)->m_pAtoms; else cfr = m_pReadCacheXYZ->GetFrameHistory(z); tf = 1.0; for (z2=1;z2<=order;z2++) { if (z2 == z) continue; tf *= z2 / ((double)z2 - z); } for (z2=0;z2<(int)cfr->m_oaAtoms.size();z2++) tpred[z2] += tf * cfr->m_oaAtoms[m_iaAtomSort[z2]]->m_fRelCoord[zc]; compred += tf * cfr->m_faCOM[zc]; } } if (m_pReadCacheCube != NULL) cfr = m_pReadCacheCube->GetFrameHistory(0)->m_pAtoms; else cfr = m_pReadCacheXYZ->GetFrameHistory(0); if (m_IF.IsPL(BQB_PL_VERBOSE)) m_IF.printf("Discretizing and serializing symbols...\n"); // COM component mantis = cfr->m_iaCOM[zc]; if (floor(compred*pow10(parm->GetPrecision())+0.5+AR_EPS) != floor(compred*pow10(parm->GetPrecision())+0.5-AR_EPS)) { ti = (int)floor(compred*pow10(parm->GetPrecision())); // m_IF.printf("1A) Sanitized rounding of %f.\n",compred*pow10(asigni)); } else ti = (int)floor(compred*pow10(parm->GetPrecision())+0.5); res = mantis - ti; #ifdef DEBUG_POS_ELEMENT m_IF.printf("@> CoM zc=%d, true %.6f, pred %.6f, mantis %ld, ti %ld, res %ld.\n", zc,cfr->m_faCOM[zc],compred,mantis,ti,res); #endif if (resi != NULL) *resi += bqbpow2((double)res); if (!skipcomp) { if (bqbabs(res) >= split) { outp.push_back(C_SPLIT); outp.push_back(res/split); if (res < 0) outp.push_back(-(bqbabs(res)%split)); else outp.push_back(res%split); } else { outp.push_back(res); } } for (zi=0;zi<(int)cfr->m_oaAtoms.size();zi++) { mantis = cfr->m_oaAtoms[m_iaAtomSort[zi]]->m_iRelCoord[zc]; if (floor(tpred[zi]*pow10(parm->GetPrecision())+0.5+AR_EPS) != floor(tpred[zi]*pow10(parm->GetPrecision())+0.5-AR_EPS)) { ti = (int)floor(tpred[zi]*pow10(parm->GetPrecision())); // m_IF.printf("1B) %3d Sanitized rounding of %f.\n",zi,tpred[zi]*pow10(asigni)); } else ti = (int)floor(tpred[zi]*pow10(parm->GetPrecision())+0.5); res = mantis - ti; #ifdef DEBUG_POS_ELEMENT if (m_iaAtomSort[zi] == DEBUG_POS_ELEMENT) m_IF.printf("@> A%d zc=%d, true %.6f, pred %.6f, mantis %ld, ti %ld, res %ld.\n", m_iaAtomSort[zi],zc,cfr->m_oaAtoms[m_iaAtomSort[zi]]->m_fRelCoord[zc],tpred[zi],mantis,ti,res); #endif if (resi != NULL) *resi += bqbpow2((double)res); if (skipcomp) continue; if (bqbabs(res) >= split) { outp.push_back(C_SPLIT); outp.push_back(res/split); if (res < 0) { outp.push_back(-(bqbabs(res)%split)); #ifdef DEBUG_POS_ELEMENT if (m_iaAtomSort[zi] == DEBUG_POS_ELEMENT) m_IF.printf("@> A%d zc=%d, Negative Split(%d): %ld | %ld = %ld.\n", m_iaAtomSort[zi],zc,split,res/split,-(abs(res)%split),res); #endif } else { outp.push_back(res%split); #ifdef DEBUG_POS_ELEMENT if (m_iaAtomSort[zi] == DEBUG_POS_ELEMENT) m_IF.printf("@> A%d zc=%d, Positive Split(%d): %ld | %ld = %ld.\n", m_iaAtomSort[zi],zc,split,res/split,res%split,res); #endif } } else { outp.push_back(res); #ifdef DEBUG_POS_ELEMENT if (m_iaAtomSort[zi] == DEBUG_POS_ELEMENT) m_IF.printf("@> A%d zc=%d, No Split: %ld.\n", m_iaAtomSort[zi],zc,res); #endif } } } if (m_IF.IsPL(BQB_PL_VERBOSE)) { if ((int)outp.size()-i > 20) { m_IF.printf("First 20 symbols (from %lu):\n",outp.size()); for (z=0;z<20;z++) m_IF.printf("%2d: %12d\n",z,outp[z+i]); m_IF.printf("\n"); } } if (m_IF.IsPL(BQB_PL_VERBOSE)) m_IF.printf("*** AtomsToIntegerArray finished, %lu symbols written ***\n\n",outp.size()-i); } void CBQBEngine::IntegerArrayToAtoms( const std::vector &inp, int order, CBQBParameterSet_Position *parm, int ver, bool second ) { int z, z2, i=0, zc, zi, ii; std::vector tpred; double compred; long ti; int split; double tf; CBQBAtomSet *ofr, *ofr0; ii = 0; if (m_IF.IsPL(BQB_PL_VERBOSE)) m_IF.printf("\n*** IntegerArrayToAtoms ***\n"); i = ii; if (ver >= 1) split = ((unsigned long)1)<GetSplit(); else split = parm->GetSplit(); // Backward compatibility with bug if (m_IF.IsPL(BQB_PL_VERBOSE)) m_IF.printf("Order=%d, asigni=%d, esplit=%d, split=%d\n", order,parm->GetPrecision(),parm->GetSplit(),split); if (second) ofr0 = GetOutput2AtomFrame(0); else ofr0 = GetOutputAtomFrame(0); tpred.resize(ofr0->m_oaAtoms.size()); if (m_IF.IsPL(BQB_PL_VERBOSE)) { m_IF.printf("First 20 symbols:\n"); for (z=0;z<20;z++) m_IF.printf("%2d: %12d\n",z,inp[z]); m_IF.printf("\n"); } if (m_IF.IsPL(BQB_PL_VERBOSE)) if (m_pExtrapolatorXYZ != NULL) m_IF.printf("<< histused %d, visco %d, trange %d\n", order,m_pExtrapolatorXYZ->m_iCubeFrameVisibleCount,parm->GetExtraTRange()); for (zc=0;zc<3;zc++) { if (m_IF.IsPL(BQB_PL_VERBOSE)) m_IF.printf("*** Now coordinate %d/3...\n",zc+1); if (m_pExtrapolatorXYZ != NULL) { if (m_IF.IsPL(BQB_PL_VERBOSE)) m_IF.printf("Extrapolator...\n"); if (order+1 > m_pExtrapolatorXYZ->m_iCubeFrameVisibleCount) { m_IF.eprintf("CBQBEngine::IntegerArrayToAtoms(): Error: Frame is of temporal order %d, step history is too short (%d).\n", order,m_pExtrapolatorXYZ->m_iCubeFrameVisibleCount); abort(); } m_pExtrapolatorXYZ->m_iCubeFrameVisibleCount = order+1; for (z=0;z<(int)ofr0->m_oaAtoms.size();z++) tpred[z] = m_pExtrapolatorXYZ->ExtrapolateXYZ(m_iaAtomSort[z],zc); compred = m_pExtrapolatorXYZ->ExtrapolateXYZ((int)ofr0->m_oaAtoms.size(),zc); } else { if (m_IF.IsPL(BQB_PL_VERBOSE)) m_IF.printf("Polynomial extrapolation...\n"); for (z=0;z<(int)ofr0->m_oaAtoms.size();z++) tpred[z] = 0; compred = 0; for (z=1;zm_oaAtoms.size();z2++) tpred[z2] += tf * ofr->m_oaAtoms[m_iaAtomSort[z2]]->m_fRelCoord[zc]; compred += tf * ofr->m_faCOM[zc]; } } if (second) ofr = GetOutput2AtomFrame(0); else ofr = GetOutputAtomFrame(0); if (m_IF.IsPL(BQB_PL_VERBOSE)) m_IF.printf("Decoding symbols...\n"); // COM component if (floor(compred*pow10(parm->GetPrecision())+0.5+AR_EPS) != floor(compred*pow10(parm->GetPrecision())+0.5-AR_EPS)) { ti = (int)floor(compred*pow10(parm->GetPrecision())); // m_IF.printf("2A) Sanitized rounding of %f.\n",compred*pow10(asigni)); } else ti = (int)floor(compred*pow10(parm->GetPrecision())+0.5); if (inp[ii] == C_SPLIT) { ii++; ofr0->m_iaCOM[zc] = ti + inp[ii++] * split; ofr0->m_iaCOM[zc] += inp[ii++]; } else ofr0->m_iaCOM[zc] = ti + inp[ii++]; ofr0->m_faCOM[zc] = FixedToFloat(ofr0->m_iaCOM[zc],parm->GetPrecision()); #ifdef DEBUG_POS_ELEMENT m_IF.printf("@< CoM zc=%d, pred %.6f, mantis %d, ti %ld, true %.6f.\n", zc,compred,ofr0->m_iaCOM[zc],ti,ofr0->m_faCOM[zc]); #endif for (zi=0;zi<(int)ofr0->m_oaAtoms.size();zi++) { if (floor(tpred[zi]*pow10(parm->GetPrecision())+0.5+AR_EPS) != floor(tpred[zi]*pow10(parm->GetPrecision())+0.5-AR_EPS)) { ti = (int)floor(tpred[zi]*pow10(parm->GetPrecision())); // m_IF.printf("2B) %3d Sanitized rounding of %f.\n",zi,tpred[zi]*pow10(asigni)); } else ti = (int)floor(tpred[zi]*pow10(parm->GetPrecision())+0.5); if (inp[ii] == C_SPLIT) { ii++; ofr0->m_oaAtoms[m_iaAtomSort[zi]]->m_iRelCoord[zc] = ti + inp[ii++] * split; ofr0->m_oaAtoms[m_iaAtomSort[zi]]->m_iRelCoord[zc] += inp[ii++]; #ifdef DEBUG_POS_ELEMENT if (m_iaAtomSort[zi] == DEBUG_POS_ELEMENT) m_IF.printf("@< A%d ii=%d Split(%d): %ld + %d*%d + %d = %ld.\n", m_iaAtomSort[zi],ii-3,split,ti,inp[ii-2],split,inp[ii-1], ofr0->m_oaAtoms[m_iaAtomSort[zi]]->m_iRelCoord[zc]); #endif } else { ofr0->m_oaAtoms[m_iaAtomSort[zi]]->m_iRelCoord[zc] = ti + inp[ii++]; #ifdef DEBUG_POS_ELEMENT if (m_iaAtomSort[zi] == DEBUG_POS_ELEMENT) m_IF.printf("@< A%d ii=%d No Split: %ld + %d = %ld.\n", m_iaAtomSort[zi],ii-3,ti,inp[ii-1],ofr0->m_oaAtoms[m_iaAtomSort[zi]]->m_iRelCoord[zc]); #endif } ofr0->m_oaAtoms[m_iaAtomSort[zi]]->m_iCoord[zc] = ofr0->m_oaAtoms[m_iaAtomSort[zi]]->m_iRelCoord[zc] + ofr0->m_iaCOM[zc]; ofr0->m_oaAtoms[m_iaAtomSort[zi]]->m_fRelCoord[zc] = FixedToFloat(ofr0->m_oaAtoms[m_iaAtomSort[zi]]->m_iRelCoord[zc],parm->GetPrecision()); ofr0->m_oaAtoms[m_iaAtomSort[zi]]->m_fCoord[zc] = FixedToFloat(ofr0->m_oaAtoms[m_iaAtomSort[zi]]->m_iCoord[zc],parm->GetPrecision()); #ifdef DEBUG_POS_ELEMENT if (m_iaAtomSort[zi] == DEBUG_POS_ELEMENT) m_IF.printf("@< A%d zc=%d, pred %.6f, mantis %ld, ti %ld, true %.6f.\n", m_iaAtomSort[zi],zc,tpred[zi],ofr0->m_oaAtoms[m_iaAtomSort[zi]]->m_iRelCoord[zc], ti,ofr0->m_oaAtoms[m_iaAtomSort[zi]]->m_fRelCoord[zc]); #endif } } if (m_IF.IsPL(BQB_PL_VERBOSE)) m_IF.printf("*** IntegerArrayToAtoms finished, %d symbols read ***\n\n",ii-i); } void CBQBEngine::CompressString(const char *s, CBQBBitSet *bs, CBQBStatistics *stat) { CBQBIntegerEngine ie(m_IF); std::vector ia; int z, mi, ma, bits, co; CBQBBitSet bs2(m_IF); unsigned long tpos; tpos = bs->GetLength(); if (m_IF.IsPL(BQB_PL_VERBOSE)) m_IF.printf(">>> CompressString >>>\n"); for (z=0;z<(int)strlen(s);z++) ia.push_back(s[z]); mi = 255; ma = 0; for (z=0;z<(int)ia.size();z++) { if (ia[z] > ma) ma = ia[z]; if (ia[z] < mi) mi = ia[z]; } if (ia.size() == 0) { mi = 0; ma = 0; } bits = (int)ceil(mylog2(ma-mi+1)); co = (int)ceil((bits*ia.size()+4.0)/8.0)+2; if (m_IF.IsPL(BQB_PL_VERBOSE)) m_IF.printf("CompressString: Trying conventional storage, length %lu (%lu), range %d - %d, %d bits.\n", strlen(s),ia.size(),mi,ma,bits); if (stat != NULL) stat->PushStatistics(); if (ia.size() > 1) ie.CompressSingle( ia, &bs2, true, true, true, 50, 1, false, true, 10, stat ); if (m_IF.IsPL(BQB_PL_VERBOSE)) m_IF.printf("CompressString: Source %lu Bytes, IntegerEngine %d Bytes, Conventional %d Bytes.\n", ia.size(),bs2.GetByteLength(),co); if ((ia.size() <= 1) || ((co <= bs2.GetByteLength()) && (ia.size() < 256))) { if (m_IF.IsPL(BQB_PL_VERBOSE)) m_IF.printf("--> Using conventional storage.\n"); bs->WriteBit(0); bs->WriteBits((unsigned long)strlen(s),8); bs->WriteBits(mi,8); bs->WriteBits(bits,4); for (z=0;z<(int)ia.size();z++) bs->WriteBits(ia[z]-mi,bits); } else { if (m_IF.IsPL(BQB_PL_VERBOSE)) m_IF.printf("--> Using IntegerEngine storage.\n"); bs->WriteBit(1); bs->WriteBits(&bs2); } if (stat != NULL) { stat->PopStatistics(); stat->m_oStat.m_lOverhead += bs->GetLength() - tpos; } if (m_IF.IsPL(BQB_PL_VERBOSE)) m_IF.printf("<<< CompressString <<<\n"); } void CBQBEngine::DecompressString(CBQBBitSet *bs, char **s) { CBQBIntegerEngine ie(m_IF); std::vector ia; int z, mi, c, bits; if (m_IF.IsPL(BQB_PL_VERBOSE)) m_IF.printf(">>> DecompressString >>>\n"); if (!bs->ReadBit()) { if (m_IF.IsPL(BQB_PL_VERBOSE)) m_IF.printf("Classical storage.\n"); c = bs->ReadBitsInteger(8); mi = bs->ReadBitsInteger(8); bits = bs->ReadBitsInteger(4); for (z=0;zReadBitsInteger(bits)); } else { if (m_IF.IsPL(BQB_PL_VERBOSE)) m_IF.printf("IntegerEngine was used.\n"); ie.DecompressSingle( bs, ia, NULL ); } *s = new char[ia.size()+1]; for (z=0;z<(int)ia.size();z++) (*s)[z] = (char)ia[z]; (*s)[z] = 0; if (m_IF.IsPL(BQB_PL_VERBOSE)) m_IF.printf("<<< DecompressString <<<\n"); } bool CBQBEngine::CompressCubeFrame( CBQBBitSet *bs, int corder, CBQBParameterSet_Volumetric *parm, int &histused, bool staticinfo, CBQBStatistics *stat, bool skipcomp, double *resi, std::vector > *tciaa ) { CBQBIntegerEngine ie(m_IF); const CBQBCubeFrame *cfr; unsigned long tpos; histused = 0; if (parm == NULL) { m_IF.eprintf("CBQBEngine::CompressCubeFrame(): Error: parm == NULL.\n"); return false; } if (resi != NULL) *resi = 0.0; m_iaTempCompressCube.clear(); cfr = m_pReadCacheCube->GetFrameHistory(0); if (parm->GetHilbert() && ((int)m_iaHilbertIdx.size() != cfr->m_iResXYZ)) BuildHilbertIdx(cfr->m_iRes[0],cfr->m_iRes[1],cfr->m_iRes[2]/*,verbose*/); if (tciaa != NULL) { tciaa->push_back(std::vector()); CubeToIntegerArray( tciaa->back(), corder, parm, histused, skipcomp, resi ); } else CubeToIntegerArray( m_iaTempCompressCube, corder, parm, histused, skipcomp, resi ); if (skipcomp || (tciaa != NULL)) return true; tpos = bs->GetLength(); // Current Version 2 // History Frames Used bs->WriteBits(histused,4); if (staticinfo) { bs->WriteBit(1); // Compression Settings Version Info bs->WriteBits(0,3); // Compression Settings parm->ExportBits(bs); ExportCubeHeader(bs,corder/*,verbose*/); // Reserved for future use, must be 0 bs->WriteBit(0); } else bs->WriteBit(0); // Reserved for future use, must be 0 bs->WriteBit(0); /* // Legacy Version 0 and 1 bs->WriteBits(corder,4); bs->WriteBits(parm->GetSigni(),4); bs->WriteBits(parm->GetEps(),6); bs->WriteBits(parm->GetSplit(),6); bs->WriteBit(parm->GetHilbert()?1:0); // Additional fields in version 1 if (m_pExtrapolator != NULL) { bs->WriteBit(1); ExportExtrapolatorSettings(bs,true,verbose); } else { bs->WriteBit(0); bs->WriteBits((unsigned long)floor(parm->GetNbhFac()*1000.0+0.5),11); } bs->WriteBit(0); // Reserved for future use, must be 0 // End Additional fields */ if (stat != NULL) stat->m_oStat.m_lOverhead += bs->GetLength() - tpos; ie.Compress( m_iaTempCompressCube, bs, parm->GetCompressorParameterSet(), false, stat ); return true; } bool CBQBEngine::DecompressCubeFrame( CBQBBitSet *bs, int ver, CBQBParameterSet_Volumetric *parm, int *histused, bool second, bool check ) { CBQBIntegerEngine ie(m_IF); int tco, csver; CBQBCubeFrame *cfr; bool statinfo; statinfo = false; if (ver > BQB_FRAMETYPE_COMPCUBE_VERSION) { m_IF.eprintf("CBQBEngine::DecompressCubeFrame(): Unknown Cube Frame Version: %d.\n",ver); m_IF.printf("Either the BQB file is damaged, or was written with a more recent software version.\n\n"); return false; } m_iaTempCompressCube.clear(); if (second) cfr = GetOutput2CubeFrame(0); else cfr = GetOutputCubeFrame(0); if (ver >= 2) { // Current Version 2 // History Frames Used tco = bs->ReadBitsInteger(4); if (histused != NULL) *histused = tco; if (bs->ReadBit()) { // Static info present statinfo = true; if (!check) m_IF.printf(" Reading volumetric trajectory static information and compression settings...\n"); // Compression Settings Version Info csver = bs->ReadBitsInteger(3); // Compression Settings parm->ImportBits(bs,csver); ImportCubeHeader(bs,second); // Reserved for future use, must be 0 if (bs->ReadBit()) { m_IF.eprintf("CBQBEngine::DecompressCubeFrame(): Reserved bit A expected to be 0, but was 1.\n"); m_IF.printf("Either the BQB file is damaged, or was written with a more recent software version.\n\n"); return false; } } else { if (second) cfr->CopyHeader( GetOutput2CubeFrame(1) ); else cfr->CopyHeader( GetOutputCubeFrame(1) ); } // Reserved for future use, must be 0 if (bs->ReadBit()) { m_IF.eprintf("CBQBEngine::DecompressCubeFrame(): Reserved bit B expected to be 0, but was 1.\n"); m_IF.printf("Either the BQB file is damaged, or was written with a more recent software version.\n\n"); return false; } } else { // Legacy Versions 0 and 1 tco = bs->ReadBitsInteger(4); parm->SetSigni(bs->ReadBitsInteger(4)); parm->SetEps(bs->ReadBitsInteger(6)); parm->SetSplit(bs->ReadBitsInteger(6)); parm->SetHilbert(bs->ReadBit()); if (histused != NULL) *histused = tco; // Additional fields in version 1 if (ver == 1) { if (bs->ReadBit()) { ImportExtrapolatorSettings(bs,true); } else { parm->SetNbhFac(bs->ReadBitsInteger(11) / 1000.0); parm->SetUseExtra(false); } if (bs->ReadBit()) { m_IF.eprintf("CBQBEngine::DecompressCubeFrame(): Reserved bit expected to be 0, but was 1.\n"); m_IF.printf("Either the BQB file is damaged, or was written with a more recent software version.\n\n"); return false; } } else { parm->SetNbhFac(1.075); parm->SetUseExtra(false); } // End Additional fields if (m_pExtrapolator != NULL) if (tco > m_pExtrapolator->m_iTRange-1) tco = m_pExtrapolator->m_iTRange-1; } cfr->m_iEps = parm->GetEps(); cfr->m_iSigni = parm->GetSigni(); if (ver < 2) ImportCubeHeader(bs,second); if (!check && parm->GetUseExtra() && (ver >= 2) && statinfo) { if (parm->GetExtraPredCorr()) { if (m_IF.IsPL(BQB_PL_STANDARD)) m_IF.printf(" Initializing Volumetric Predictor Extrapolator (%d/%d)...\n", parm->GetExtraTRange(),parm->GetExtraTOrder()); if (m_pExtrapolator != NULL) delete m_pExtrapolator; m_pExtrapolator = new CBQBExtrapolator(m_IF); m_pExtrapolator->Initialize( cfr->m_iRes[0], // resx, cfr->m_iRes[1], // resy, cfr->m_iRes[2], // resz, 1, // srangex, 1, // srangey, 1, // srangez, parm->GetExtraTRange(), // trange, 0, // sorder, parm->GetExtraTOrder(), // torder, 0, // offsetx, 0, // offsety, 0, // offsetz, false, // crosss, false, // crosst, false, // wrap, false, // crossranges, false, // crossranget 0, // distexpo parm->GetExtraTimeExpo(), // timeexpo false ); if (m_IF.IsPL(BQB_PL_STANDARD)) { if (parm->IsExtraSRangeXYZEqual()) m_IF.printf(" Initializing Volumetric Corrector Extrapolator (%d/%d)...\n", parm->GetExtraSRangeX(),parm->GetExtraSOrder()); else m_IF.printf(" Initializing Volumetric Corrector Extrapolator (%d|%d|%d/%d)...\n", parm->GetExtraSRangeX(),parm->GetExtraSRangeY(),parm->GetExtraSRangeZ(),parm->GetExtraSOrder()); } if (m_pExtrapolatorCorr != NULL) delete m_pExtrapolatorCorr; m_pExtrapolatorCorr = new CBQBExtrapolator(m_IF); m_pExtrapolatorCorr->Initialize( cfr->m_iRes[0], // resx, cfr->m_iRes[1], // resy, cfr->m_iRes[2], // resz, parm->GetExtraSRangeX(), // srangex, parm->GetExtraSRangeY(), // srangey, parm->GetExtraSRangeZ(), // srangez, 1, // trange, parm->GetExtraSOrder(), // sorder, 0, // torder, parm->GetExtraOffsetX(), // offsetx, parm->GetExtraOffsetY(), // offsety, parm->GetExtraOffsetZ(), // offsetz, parm->GetExtraCrossS(), // crosss, false, // crosst, parm->GetExtraWrap(), // wrap, parm->GetExtraCrossRangeS(), // crossranges, false, // crossranget parm->GetExtraDistExpo(), // distexpo 0, // timeexpo false ); } else { if (m_IF.IsPL(BQB_PL_STANDARD)) { if (parm->IsExtraSRangeXYZEqual()) m_IF.printf(" Initializing Volumetric Extrapolator (%d/%d;%d/%d)...\n", parm->GetExtraSRangeX(), parm->GetExtraSOrder(), parm->GetExtraTRange(), parm->GetExtraTOrder() ); else m_IF.printf(" Initializing Volumetric Extrapolator (%d|%d|%d/%d;%d|%d)...\n", parm->GetExtraSRangeX(), parm->GetExtraSRangeY(), parm->GetExtraSRangeZ(), parm->GetExtraSOrder(), parm->GetExtraTRange(), parm->GetExtraTOrder() ); } if (m_pExtrapolator != NULL) delete m_pExtrapolator; m_pExtrapolator = new CBQBExtrapolator(m_IF); m_pExtrapolator->Initialize( cfr->m_iRes[0], // resx, cfr->m_iRes[1], // resy, cfr->m_iRes[2], // resz, parm->GetExtraSRangeX(), // srangex, parm->GetExtraSRangeY(), // srangey, parm->GetExtraSRangeZ(), // srangez, parm->GetExtraTRange(), // trange, parm->GetExtraSOrder(), // sorder, parm->GetExtraTOrder(), // torder, parm->GetExtraOffsetX(), // offsetx, parm->GetExtraOffsetY(), // offsety, parm->GetExtraOffsetZ(), // offsetz, parm->GetExtraCrossS(), // crosss, parm->GetExtraCrossT(), // crosst, parm->GetExtraWrap(), // wrap, parm->GetExtraCrossRangeS(), // crossranges, parm->GetExtraCrossRangeT(), // crossranget parm->GetExtraDistExpo(), // distexpo parm->GetExtraTimeExpo(), // timeexpo false ); } } if (parm->GetHilbert() && ((int)m_iaHilbertIdx.size() != cfr->m_iResXYZ)) BuildHilbertIdx(cfr->m_iRes[0],cfr->m_iRes[1],cfr->m_iRes[2]); if (!check && (m_pExtrapolator != NULL)) m_pExtrapolator->PushCubeFrame(cfr); ie.Decompress( bs, m_iaTempCompressCube, parm->GetCompressorParameterSet() ); IntegerArrayToCube( m_iaTempCompressCube, tco, parm, ver, second ); return true; } void CBQBEngine::ExportAtomLabels(const CBQBAtomSet *as, CBQBBitSet *bs, CBQBStatistics *stat) { std::vector ia; char tch[5001]; std::string tst; int z, z2, zt, rem; if ((as->m_oaAtoms.size()%5000) == 0) zt = (int)as->m_oaAtoms.size()/5000; else zt = (int)as->m_oaAtoms.size()/5000 + 1; if (zt > 255) { m_IF.eprintf("CBQBEngine::ExportAtomLabels(): Error: More than 1'275'000 atoms are not supported (%d).\n", zt*5000); abort(); } bs->WriteBits(zt,8); for (z=0;zm_oaAtoms.size() - z*5000; if (rem > 5000) rem = 5000; tst = ""; for (z2=0;z2m_oaAtoms[z*5000+z2]->m_sLabel.length(); tst += as->m_oaAtoms[z*5000+z2]->m_sLabel; if (as->m_oaAtoms[z*5000+z2]->m_sLabel.length() > 127) { m_IF.eprintf("CBQBEngine::ExportAtomLabels(): Error: Labels longer than 127 characters are not supported (%ld).\n", as->m_oaAtoms[z*5000+z2]->m_sLabel.length()); abort(); } } tch[rem] = 0; CompressString(tch,bs,stat); CompressString(tst.c_str(),bs,stat); } } void CBQBEngine::ImportAtomLabels(CBQBAtomSet *as, CBQBBitSet *bs) { int z, z2, zt, i; char *tch, *tch2, *p, buf[128]; unsigned char tuc; zt = bs->ReadBitsInteger(8); i = 0; for (z=0;zm_oaAtoms[i]->m_sLabel = buf; p += tuc; z2++; i++; } delete[] tch; delete[] tch2; } if (i != (int)as->m_oaAtoms.size()) { m_IF.eprintf("CBQBEngine::ImportAtomLabels(): Error: Expected %lu atom labels, but found %d (%d).\n", as->m_oaAtoms.size(),i,zt); abort(); } } bool CBQBEngine::CompressAtomFrame( CBQBBitSet *bs, int order, CBQBParameterSet_Position *parm, int &histused, bool staticinfo, bool comment, CBQBStatistics *stat, bool skipcomp, double *resi, std::vector > *tciaa ) { CBQBIntegerEngine ie(m_IF); std::string ts; int bits, z; const CBQBAtomSet *as; unsigned long tpos; histused = 0; if (parm == NULL) { m_IF.eprintf("CBQBEngine::CompressAtomFrame(): Error: parm == NULL.\n"); return false; } if (resi != NULL) *resi = 0.0; m_iaTempCompressXYZ.clear(); if (skipcomp) { AtomsToIntegerArray( m_iaTempCompressXYZ, order, parm, histused, skipcomp, resi ); return true; } if (m_pReadCacheCube != NULL) as = m_pReadCacheCube->GetFrameHistory(0)->m_pAtoms; else as = m_pReadCacheXYZ->GetFrameHistory(0); if (parm->GetSortAtom()) BuildAtomSort(as); else BuildIdentityAtomSort(as); if (tciaa != NULL) { tciaa->push_back(std::vector()); AtomsToIntegerArray( tciaa->back(), order, parm, histused, skipcomp, resi ); } else AtomsToIntegerArray( m_iaTempCompressXYZ, order, parm, histused, skipcomp, resi ); tpos = bs->GetLength(); if (stat != NULL) stat->PushStatistics(); // New in Version 2: Atom Count always written bits = (int)ceil(mylog2((double)as->m_oaAtoms.size()+1)); bs->WriteBits(bits,5); bs->WriteBits((unsigned long)as->m_oaAtoms.size(),bits); if (staticinfo) { // Compression settings stored bs->WriteBit(1); // 3 Bits Compression Setting Version Info (Currently Version 0) bs->WriteBits(0,3); // Compression Settings parm->ExportBits(bs); } else bs->WriteBit(0); // No compression settings stored if (staticinfo) { bs->WriteBit(1); // Static trajectory information present if (as->m_bOrd) { bs->WriteBit(1); // Ord numbers for (z=0;z<(int)as->m_oaAtoms.size();z++) bs->WriteBits(as->m_oaAtoms[z]->m_iOrd,8); } else bs->WriteBit(0); // No Ord numbers if (as->m_bLabels) { bs->WriteBit(1); // Atom label strings ExportAtomLabels(as,bs,stat); } else bs->WriteBit(0); // No Atom label strings // Additional fields since version 1 if (parm->GetSortAtom()) bs->WriteBit(1); else bs->WriteBit(0); // End Additional fields since version 1 // Additional Fields in version 2 // Trajectory Comment bs->WriteBit(0); // Static Cell Info bs->WriteBit(0); // Static Topology bs->WriteBit(0); // Integrator Properties bs->WriteBit(0); // Atom Masses bs->WriteBit(0); // Fixed atomic partial charges bs->WriteBit(0); // Atom Radii bs->WriteBit(0); // Additional per-atom Datasets: Header bs->WriteBit(0); // Reserved for future use, must be 0 bs->WriteBit(0); // End Additional Fields in version 2 } else bs->WriteBit(0); // No static trajectory information present // Comment if ((as->m_sComment != NULL) && comment) { bs->WriteBit(1); CompressString(as->m_sComment,bs,stat); } else bs->WriteBit(0); // Additional Fields in version 2 // History Frames Used bs->WriteBits(histused,4); // Simulation Time bs->WriteBit(0); // Thermodynamic Properties bs->WriteBit(0); // Dynamic Cell Info bs->WriteBit(0); // Dynamic Topology bs->WriteBit(0); // Voronoi Tessellation bs->WriteBit(0); // Additional per-atom Datasets: Data bs->WriteBit(0); // Reserved for future use, must be 0 bs->WriteBit(0); // End Additional Fields in version 2 /* // Legacy Version 0 / 1 bs->WriteBits(order,4); bs->WriteBits(parm->GetPrecision(),4); bs->WriteBits(parm->GetSplit(),6); // Additional fields in version 1 if (m_pExtrapolatorXYZ != NULL) { bs->WriteBit(1); ExportExtrapolatorSettings(bs,false,verbose); } else bs->WriteBit(0); bs->WriteBit(0); // Reserved for future use, must be 0 // End Additional fields */ if (stat != NULL) { stat->PopStatistics(); stat->m_oStat.m_lOverhead += bs->GetLength() - tpos; } if (m_IF.IsPL(BQB_PL_VERBOSE)) m_IF.printf("CBQBEngine::CompressAtomFrame(): Will compress %lu symbols.\n",m_iaTempCompressXYZ.size()); if (tciaa == NULL) ie.Compress( m_iaTempCompressXYZ, bs, parm->GetCompressorParameterSet(), false, stat ); return true; } bool CBQBEngine::DecompressAtomStep( const std::vector *inp, int ver, CBQBParameterSet_Position *parm, int *histused, bool second, bool check ) { CBQBBitSet bs(m_IF); CBQBAtomSet *afr; bool b; if (m_IF.IsPL(BQB_PL_VERBOSE)) m_IF.printf(">>> CBQBEngine::DecompressAtomStep() >>>\n"); afr = new CBQBAtomSet(); PushOutputAtomFrame(afr); bs.m_iaData.assign(inp->begin(),inp->end()); b = DecompressAtomFrame( &bs, ver, parm, histused, second, check ); if (m_IF.IsPL(BQB_PL_VERBOSE)) m_IF.printf("<<< CBQBEngine::DecompressAtomStep() <<<\n"); return b; } bool CBQBEngine::DecompressAtomFrame( CBQBBitSet *bs, int ver, CBQBParameterSet_Position *parm, int *histused, bool second, bool check ) { CBQBIntegerEngine ie(m_IF); int z, bits, atc, csver; int tao; CBQBAtom *at; CBQBAtomSet *as, *as2; char *tch, *p, *q; atc = 0; if (ver > BQB_FRAMETYPE_COMPTRAJ_VERSION) { m_IF.eprintf("CBQBEngine::DecompressAtomFrame(): Unknown Atom Frame Version: %d.\n",ver); m_IF.printf("Either the BQB file is damaged, or was written with a more recent software version.\n\n"); return false; } m_iaTempCompressXYZ.clear(); if (second) as = GetOutput2AtomFrame(0); else as = GetOutputAtomFrame(0); // New in Version 2: Atom count is always written if (ver >= 2) { bits = bs->ReadBitsInteger(5); atc = bs->ReadBitsInteger(bits); } if (ver >= 2) { if (bs->ReadBit()) { // Compression settings stored //m_IF.printf("Reading compression settings...\n"); if (!check) m_IF.printf(" Reading position trajectory compression settings...\n"); // Compression Settings Version Info csver = bs->ReadBitsInteger(3); // Compression Settings parm->ImportBits(bs,csver); //m_IF.printf("%s",parm->ToString(4).c_str()); if (!check && parm->GetUseExtra()) { m_IF.printf(" Initializing Extrapolator (%d/%d)...\n", parm->GetExtraTRange(), parm->GetExtraTOrder() ); if (m_pExtrapolatorXYZ != NULL) delete m_pExtrapolatorXYZ; m_pExtrapolatorXYZ = new CBQBExtrapolator(m_IF); m_pExtrapolatorXYZ->InitializeXYZ(parm,false); } } } if (bs->ReadBit()) { // Static trajectory information stored if (!check) m_IF.printf(" Reading position trajectory static information...\n"); if (ver < 2) { bits = bs->ReadBitsInteger(5); atc = bs->ReadBitsInteger(bits); } if (m_IF.IsPL(BQB_PL_VERBOSE)) m_IF.printf("Will read %d atoms.\n",atc); for (z=0;zm_oaAtoms.push_back(at); } if (bs->ReadBit()) { // Read Ord Numbers as->m_bOrd = true; for (z=0;zm_oaAtoms[z]->m_iOrd = bs->ReadBitsInteger(8); } if (bs->ReadBit()) { // Read Atom label strings as->m_bLabels = true; if (ver >= 1) { // New method ImportAtomLabels(as,bs); if (!as->m_bOrd) for (z=0;zm_oaAtoms[z]->m_iOrd = GetAtomOrd(as->m_oaAtoms[z]->m_sLabel.c_str()); } else { // Old method DecompressString(bs,&tch); if (m_IF.IsPL(BQB_PL_VERBOSE)) m_IF.printf("Decompressed string to %lu characters.\n",strlen(tch)); p = tch; for (z=0;zm_oaAtoms[z]->m_sLabel = p; if (!as->m_bOrd) as->m_oaAtoms[z]->m_iOrd = GetAtomOrd(p); p = q+1; } delete[] tch; } } // Additional fields since version 1 if (ver >= 1) { if (bs->ReadBit()) // Use Atom Sorting BuildAtomSort(as); else BuildIdentityAtomSort(as); } else BuildAtomSort(as); // End Additional fields since version 1 if (ver >= 2) { // Additional fields in version 2 // Trajectory Comment if (bs->ReadBit()) { m_IF.eprintf("CBQBEngine::DecompressAtomFrame(): Trajectory comment found in BQB file, but not yet implemented.\n"); m_IF.printf("Either the BQB file is damaged, or was written with a more recent software version.\n\n"); return false; } // Static Cell Info if (bs->ReadBit()) { m_IF.eprintf("CBQBEngine::DecompressAtomFrame(): Static cell info found in BQB file, but not yet implemented.\n"); m_IF.printf("Either the BQB file is damaged, or was written with a more recent software version.\n\n"); return false; } // Static Topology if (bs->ReadBit()) { m_IF.eprintf("CBQBEngine::DecompressAtomFrame(): Static topology found in BQB file, but not yet implemented.\n"); m_IF.printf("Either the BQB file is damaged, or was written with a more recent software version.\n\n"); return false; } // Integrator Properties if (bs->ReadBit()) { m_IF.eprintf("CBQBEngine::DecompressAtomFrame(): Integrator properties found in BQB file, but not yet implemented.\n"); m_IF.printf("Either the BQB file is damaged, or was written with a more recent software version.\n\n"); return false; } // Atom Masses if (bs->ReadBit()) { m_IF.eprintf("CBQBEngine::DecompressAtomFrame(): Atom masses found in BQB file, but not yet implemented.\n"); m_IF.printf("Either the BQB file is damaged, or was written with a more recent software version.\n\n"); return false; } // Fixed atomic partial charges if (bs->ReadBit()) { m_IF.eprintf("CBQBEngine::DecompressAtomFrame(): Fixed atomic partial charges found in BQB file, but not yet implemented.\n"); m_IF.printf("Either the BQB file is damaged, or was written with a more recent software version.\n\n"); return false; } // Atom Radii if (bs->ReadBit()) { m_IF.eprintf("CBQBEngine::DecompressAtomFrame(): Atom radii found in BQB file, but not yet implemented.\n"); m_IF.printf("Either the BQB file is damaged, or was written with a more recent software version.\n\n"); return false; } // Additional per-atom Datasets: Header if (bs->ReadBit()) { m_IF.eprintf("CBQBEngine::DecompressAtomFrame(): Additional per-atom dataset header found in BQB file, but not yet implemented.\n"); m_IF.printf("Either the BQB file is damaged, or was written with a more recent software version.\n\n"); return false; } // Reserved for future use, must be 0 if (bs->ReadBit()) { m_IF.eprintf("CBQBEngine::DecompressAtomFrame(): Reserved bit A expected to be 0, but was 1.\n"); m_IF.printf("Either the BQB file is damaged, or was written with a more recent software version.\n\n"); return false; } } // End additional fields in version 2 } else { // No static trajectory information stored if (m_IF.IsPL(BQB_PL_VERBOSE)) m_IF.printf("Atom type information already read before.\n"); if (second) as2 = GetOutput2AtomFrame(1); else as2 = GetOutputAtomFrame(1); if (as2 == NULL) { m_IF.printf("CEngine::DecompressAtomFrame(): Error: First frame does not contain atom type information.\n"); return false; } for (z=0;z<(int)as2->m_oaAtoms.size();z++) { at = new CBQBAtom(); at->m_iOrd = as2->m_oaAtoms[z]->m_iOrd; at->m_sLabel = as2->m_oaAtoms[z]->m_sLabel; as->m_oaAtoms.push_back(at); } as->m_bLabels = as2->m_bLabels; as->m_bOrd = as2->m_bOrd; } if (bs->ReadBit()) // Comment was stored DecompressString( bs, &as->m_sComment ); else as->m_sComment = NULL; if (ver == 2) { // Current Version 2 // History Frames Used tao = bs->ReadBitsInteger(4); if (histused != NULL) *histused = tao; // Simulation Time if (bs->ReadBit()) { m_IF.eprintf("CBQBEngine::DecompressAtomFrame(): Simulation time found in BQB file, but not yet implemented.\n"); m_IF.printf("Either the BQB file is damaged, or was written with a more recent software version.\n\n"); return false; } // Thermodynamic Properties if (bs->ReadBit()) { m_IF.eprintf("CBQBEngine::DecompressAtomFrame(): Thermodynamic properties found in BQB file, but not yet implemented.\n"); m_IF.printf("Either the BQB file is damaged, or was written with a more recent software version.\n\n"); return false; } // Dynamic Cell Info if (bs->ReadBit()) { m_IF.eprintf("CBQBEngine::DecompressAtomFrame(): Dynamic cell info found in BQB file, but not yet implemented.\n"); m_IF.printf("Either the BQB file is damaged, or was written with a more recent software version.\n\n"); return false; } // Dynamic Topology if (bs->ReadBit()) { m_IF.eprintf("CBQBEngine::DecompressAtomFrame(): Dynamic topology found in BQB file, but not yet implemented.\n"); m_IF.printf("Either the BQB file is damaged, or was written with a more recent software version.\n\n"); return false; } // Voronoi Tessellation if (bs->ReadBit()) { m_IF.eprintf("CBQBEngine::DecompressAtomFrame(): Voronoi tessellation found in BQB file, but not yet implemented.\n"); m_IF.printf("Either the BQB file is damaged, or was written with a more recent software version.\n\n"); return false; } // Additional per-atom Datasets: Data if (bs->ReadBit()) { m_IF.eprintf("CBQBEngine::DecompressAtomFrame(): Additional per-atom dataset data found in BQB file, but not yet implemented.\n"); m_IF.printf("Either the BQB file is damaged, or was written with a more recent software version.\n\n"); return false; } // Reserved for future use, must be 0 if (bs->ReadBit()) { m_IF.eprintf("CBQBEngine::DecompressAtomFrame(): Reserved bit B expected to be 0, but was 1.\n"); m_IF.printf("Either the BQB file is damaged, or was written with a more recent software version.\n\n"); return false; } } else { // Legacy versions 0 and 1 tao = bs->ReadBitsInteger(4); parm->SetPrecision(bs->ReadBitsInteger(4)); parm->SetSplit(bs->ReadBitsInteger(6)); if (histused != NULL) *histused = tao; // Additional fields in version 1 if (ver == 1) { if (bs->ReadBit()) ImportExtrapolatorSettings(bs,false); else parm->SetUseExtra(false); if (bs->ReadBit()) { m_IF.eprintf("CBQBEngine::DecompressAtomFrame(): Reserved bit expected to be 0, but was 1.\n"); m_IF.printf("Either the BQB file is damaged, or was written with a more recent software version.\n\n"); return false; } } else parm->SetUseExtra(false); // End Additional fields if (m_pExtrapolatorXYZ != NULL) if (tao > m_pExtrapolatorXYZ->m_iTRange-1) tao = m_pExtrapolatorXYZ->m_iTRange-1; } as->m_iSigni = parm->GetPrecision(); if (!check && (m_pExtrapolatorXYZ != NULL)) m_pExtrapolatorXYZ->PushAtomFrame(as); ie.Decompress( bs, m_iaTempCompressXYZ, parm->GetCompressorParameterSet() ); if (m_IF.IsPL(BQB_PL_VERBOSE)) m_IF.printf("CBQBEngine::DecompressAtomFrame(): Decompressed %lu symbols.\n",m_iaTempCompressXYZ.size()); IntegerArrayToAtoms( m_iaTempCompressXYZ, tao, parm, ver, second ); return true; } bool CBQBEngine::PrepareDecompressCube() { int z; if (m_IF.IsPL(BQB_PL_VERBOSE)) m_IF.printf(">>> CBQBEngine::PrepareDecompressCube() >>>\n"); for (z=0;z<(int)m_oaOutputCubeBuf.size();z++) if (m_oaOutputCubeBuf[z] != NULL) delete m_oaOutputCubeBuf[z]; for (z=0;z<(int)m_oaOutputAtomBuf.size();z++) if (m_oaOutputAtomBuf[z] != NULL) delete m_oaOutputAtomBuf[z]; m_oaOutputCubeBuf.resize(10); for (z=0;z<10;z++) m_oaOutputCubeBuf[z] = NULL; m_iOutputCubeBufPos = 0; m_oaOutputAtomBuf.resize(10); for (z=0;z<10;z++) m_oaOutputAtomBuf[z] = NULL; m_iOutputAtomBufPos = 0; if (m_IF.IsPL(BQB_PL_VERBOSE)) m_IF.printf("<<< CBQBEngine::PrepareDecompressCube() <<<\n"); return true; } bool CBQBEngine::DecompressCubeStep( const std::vector *inp, int ver, CBQBParameterSet_PosAndVol *parm, int *ahistused, int *chistused, bool skipvol ) { CBQBCubeFrame *cfr; int al, cl, ahi, chi; CBQBBitSet bsat(m_IF), bscu(m_IF), bshe(m_IF); if (m_IF.IsPL(BQB_PL_VERBOSE)) m_IF.printf(">>> CBQBEngine::DecompressCubeStep() >>>\n"); bshe.Clear(); bshe.m_iaData.assign(inp->begin(),inp->begin()+8); al = bshe.ReadBitsInteger(32); cl = bshe.ReadBitsInteger(32); cfr = new CBQBCubeFrame(m_IF); PushOutputCubeFrame(cfr); cfr->m_pAtoms = new CBQBAtomSet(); PushOutputAtomFrame(cfr->m_pAtoms); bsat.Clear(); bsat.m_iaData.assign(inp->begin()+8,inp->begin()+8+al); bscu.Clear(); bscu.m_iaData.assign(inp->begin()+8+al,inp->begin()+8+al+cl); ahi = 0; if (!DecompressAtomFrame( &bsat, ver, parm->GetPositionParameterSet(), &ahi, false, false )) return false; if (ahistused != NULL) *ahistused = ahi; if (!skipvol) { chi = 0; if (!DecompressCubeFrame( &bscu, ver, parm->GetVolumetricParameterSet(), &chi, false, false )) return false; if (chistused != NULL) *chistused = chi; } if (m_IF.IsPL(BQB_PL_VERBOSE)) m_IF.printf("<<< CBQBEngine::DecompressCubeStep() <<<\n"); return true; } void CBQBEngine::PushOutputCubeFrame(CBQBCubeFrame *cfr) { m_iOutputCubeBufPos++; if (m_iOutputCubeBufPos == (int)m_oaOutputCubeBuf.size()) m_iOutputCubeBufPos = 0; if (m_oaOutputCubeBuf[m_iOutputCubeBufPos] != NULL) delete m_oaOutputCubeBuf[m_iOutputCubeBufPos]; m_oaOutputCubeBuf[m_iOutputCubeBufPos] = cfr; } void CBQBEngine::PushOutput2CubeFrame(CBQBCubeFrame *cfr) { m_iOutput2CubeBufPos++; if (m_iOutput2CubeBufPos == (int)m_oaOutput2CubeBuf.size()) m_iOutput2CubeBufPos = 0; if (m_oaOutput2CubeBuf[m_iOutput2CubeBufPos] != NULL) delete m_oaOutput2CubeBuf[m_iOutput2CubeBufPos]; m_oaOutput2CubeBuf[m_iOutput2CubeBufPos] = cfr; } CBQBCubeFrame* CBQBEngine::GetOutputCubeFrame(int depth) { int ti; if (depth >= (int)m_oaOutputCubeBuf.size()) { m_IF.eprintf("CBQBEngine::GetOutputCubeFrame(): Out of bounds (%d/%d).\n", depth,(int)m_oaOutputCubeBuf.size()); abort(); } ti = m_iOutputCubeBufPos - depth; if (ti < 0) ti += (int)m_oaOutputCubeBuf.size(); return m_oaOutputCubeBuf[ti]; } CBQBCubeFrame* CBQBEngine::GetOutput2CubeFrame(int depth) { int ti; if (depth >= (int)m_oaOutput2CubeBuf.size()) { m_IF.eprintf("CBQBEngine::GetOutput2CubeFrame(): Out of bounds (%d/%d).\n", depth,(int)m_oaOutput2CubeBuf.size()); abort(); } ti = m_iOutput2CubeBufPos - depth; if (ti < 0) ti += (int)m_oaOutput2CubeBuf.size(); return m_oaOutput2CubeBuf[ti]; } void CBQBEngine::PushOutputAtomFrame(CBQBAtomSet *cfr) { m_iOutputAtomBufPos++; if (m_iOutputAtomBufPos == (int)m_oaOutputAtomBuf.size()) m_iOutputAtomBufPos = 0; if (m_oaOutputAtomBuf[m_iOutputAtomBufPos] != NULL) delete m_oaOutputAtomBuf[m_iOutputAtomBufPos]; m_oaOutputAtomBuf[m_iOutputAtomBufPos] = cfr; } void CBQBEngine::PushOutput2AtomFrame(CBQBAtomSet *cfr) { m_iOutput2AtomBufPos++; if (m_iOutput2AtomBufPos == (int)m_oaOutput2AtomBuf.size()) m_iOutput2AtomBufPos = 0; if (m_oaOutput2AtomBuf[m_iOutput2AtomBufPos] != NULL) delete m_oaOutput2AtomBuf[m_iOutput2AtomBufPos]; m_oaOutput2AtomBuf[m_iOutput2AtomBufPos] = cfr; } CBQBAtomSet* CBQBEngine::GetOutputAtomFrame(int depth) { int ti; if (depth >= (int)m_oaOutputAtomBuf.size()) { m_IF.eprintf("CBQBEngine::GetOutputAtomFrame(): Out of bounds (%d/%d).\n", depth,(int)m_oaOutputAtomBuf.size()); abort(); } ti = m_iOutputAtomBufPos - depth; if (ti < 0) ti += (int)m_oaOutputAtomBuf.size(); return m_oaOutputAtomBuf[ti]; } CBQBAtomSet* CBQBEngine::GetOutput2AtomFrame(int depth) { int ti; if (depth >= (int)m_oaOutput2AtomBuf.size()) { m_IF.eprintf("CBQBEngine::GetOutput2AtomFrame(): Out of bounds (%d/%d).\n", depth,(int)m_oaOutput2AtomBuf.size()); abort(); } ti = m_iOutput2AtomBufPos - depth; if (ti < 0) ti += (int)m_oaOutput2AtomBuf.size(); return m_oaOutput2AtomBuf[ti]; } void CBQBEngine::BuildAtomSort(const CBQBAtomSet *as) { int z; if (m_IF.IsPL(BQB_PL_VERBOSE)) m_IF.printf("CBQBEngine::BuildAtomSort() running...\n"); m_iaAtomSort.resize(as->m_oaAtoms.size()); m_iaAtomOrd.resize(as->m_oaAtoms.size()); for (z=0;z<(int)m_iaAtomSort.size();z++) { m_iaAtomSort[z] = z; m_iaAtomOrd[z] = as->m_oaAtoms[z]->m_iOrd; } std::stable_sort( m_iaAtomSort.begin(), m_iaAtomSort.end(), SSortAtomOrd(*this) ); } void CBQBEngine::BuildIdentityAtomSort(const CBQBAtomSet *as) { int z; if (m_IF.IsPL(BQB_PL_VERBOSE)) m_IF.printf("CBQBEngine::BuildIdentityAtomSort() running...\n"); m_iaAtomSort.resize(as->m_oaAtoms.size()); m_iaAtomOrd.resize(as->m_oaAtoms.size()); for (z=0;z<(int)m_iaAtomSort.size();z++) { m_iaAtomSort[z] = z; m_iaAtomOrd[z] = as->m_oaAtoms[z]->m_iOrd; } } void CBQBEngine::ExportExtrapolatorSettings(CBQBBitSet *bs, bool volumetric) { if (volumetric) { // Use Volumetric Extrapolator? if (m_pExtrapolator == NULL) { bs->WriteBit(0); return; } bs->WriteBit(1); // ResX if ((m_pExtrapolator->m_iRes[0] < 1) || (m_pExtrapolator->m_iRes[0] > 1023)) { m_IF.eprintf("CBQBEngine::ExportExtrapolatorSettings(): Error: m_pExtrapolator.ResX out of range (%d, allowed 1..1023).\n", m_pExtrapolator->m_iRes[0]); abort(); } bs->WriteBits(m_pExtrapolator->m_iRes[0],10); // ResY if ((m_pExtrapolator->m_iRes[1] < 1) || (m_pExtrapolator->m_iRes[1] > 1023)) { m_IF.eprintf("CBQBEngine::ExportExtrapolatorSettings(): Error: m_pExtrapolator.ResY out of range (%d, allowed 1..1023).\n", m_pExtrapolator->m_iRes[1]); abort(); } bs->WriteBits(m_pExtrapolator->m_iRes[1],10); // ResZ if ((m_pExtrapolator->m_iRes[2] < 1) || (m_pExtrapolator->m_iRes[2] > 1023)) { m_IF.eprintf("CBQBEngine::ExportExtrapolatorSettings(): Error: m_pExtrapolator.ResZ out of range (%d, allowed 1..1023).\n", m_pExtrapolator->m_iRes[2]); abort(); } bs->WriteBits(m_pExtrapolator->m_iRes[2],10); // PredCorr if (m_pExtrapolatorCorr != NULL) bs->WriteBit(1); else bs->WriteBit(0); if (m_pExtrapolatorCorr != NULL) { // SRangeX if ((m_pExtrapolatorCorr->m_iSRange[0] < 1) || (m_pExtrapolatorCorr->m_iSRange[0] > 15)) { m_IF.eprintf("CBQBEngine::ExportExtrapolatorSettings(): Error: m_pExtrapolatorCorr.SRangeX out of range (%d, allowed 1..15).\n", m_pExtrapolatorCorr->m_iSRange[0]); abort(); } bs->WriteBits(m_pExtrapolatorCorr->m_iSRange[0],4); // SRangeY if ((m_pExtrapolatorCorr->m_iSRange[1] < 1) || (m_pExtrapolatorCorr->m_iSRange[1] > 15)) { m_IF.eprintf("CBQBEngine::ExportExtrapolatorSettings(): Error: m_pExtrapolatorCorr.SRangeY out of range (%d, allowed 1..15).\n", m_pExtrapolatorCorr->m_iSRange[1]); abort(); } bs->WriteBits(m_pExtrapolatorCorr->m_iSRange[1],4); // SRangeZ if ((m_pExtrapolatorCorr->m_iSRange[2] < 1) || (m_pExtrapolatorCorr->m_iSRange[2] > 15)) { m_IF.eprintf("CBQBEngine::ExportExtrapolatorSettings(): Error: m_pExtrapolatorCorr.SRangeZ out of range (%d, allowed 1..15).\n", m_pExtrapolatorCorr->m_iSRange[2]); abort(); } bs->WriteBits(m_pExtrapolatorCorr->m_iSRange[2],4); // SOrder if ((m_pExtrapolatorCorr->m_iSOrder < 0) || (m_pExtrapolatorCorr->m_iSOrder > 15)) { m_IF.eprintf("CBQBEngine::ExportExtrapolatorSettings(): Error: m_pExtrapolatorCorr.SOrder out of range (%d, allowed 0..15).\n", m_pExtrapolatorCorr->m_iSOrder); abort(); } bs->WriteBits(m_pExtrapolatorCorr->m_iSOrder,4); // OffsetX if ((m_pExtrapolatorCorr->m_iSOffset[0] < 0) || (m_pExtrapolatorCorr->m_iSOffset[0] > 15)) { m_IF.eprintf("CBQBEngine::ExportExtrapolatorSettings(): Error: m_pExtrapolatorCorr.SOffsetX out of range (%d, allowed 0..15).\n", m_pExtrapolatorCorr->m_iSOffset[0]); abort(); } if (m_pExtrapolatorCorr->m_iSOffset[0] >= m_pExtrapolatorCorr->m_iSRange[0]) { m_IF.eprintf("CBQBEngine::ExportExtrapolatorSettings(): Error: m_pExtrapolatorCorr.SOffsetX (%d) >= SRangeX (%d.\n", m_pExtrapolatorCorr->m_iSOffset[0],m_pExtrapolatorCorr->m_iSRange[0]); abort(); } bs->WriteBits(m_pExtrapolatorCorr->m_iSOffset[0],4); // OffsetY if ((m_pExtrapolatorCorr->m_iSOffset[1] < 0) || (m_pExtrapolatorCorr->m_iSOffset[1] > 15)) { m_IF.eprintf("CBQBEngine::ExportExtrapolatorSettings(): Error: m_pExtrapolatorCorr.SOffsetY out of range (%d, allowed 0..15).\n", m_pExtrapolatorCorr->m_iSOffset[1]); abort(); } if (m_pExtrapolatorCorr->m_iSOffset[1] >= m_pExtrapolatorCorr->m_iSRange[1]) { m_IF.eprintf("CBQBEngine::ExportExtrapolatorSettings(): Error: m_pExtrapolatorCorr.SOffsetY (%d) >= SRangeY (%d.\n", m_pExtrapolatorCorr->m_iSOffset[1],m_pExtrapolatorCorr->m_iSRange[1]); abort(); } bs->WriteBits(m_pExtrapolatorCorr->m_iSOffset[1],4); // OffsetZ if ((m_pExtrapolatorCorr->m_iSOffset[2] < 0) || (m_pExtrapolatorCorr->m_iSOffset[2] > 15)) { m_IF.eprintf("CBQBEngine::ExportExtrapolatorSettings(): Error: m_pExtrapolatorCorr.SOffsetZ out of range (%d, allowed 0..15).\n", m_pExtrapolatorCorr->m_iSOffset[2]); abort(); } if (m_pExtrapolatorCorr->m_iSOffset[2] >= m_pExtrapolatorCorr->m_iSRange[2]) { m_IF.eprintf("CBQBEngine::ExportExtrapolatorSettings(): Error: m_pExtrapolatorCorr.SOffsetZ (%d) >= SRangeZ (%d.\n", m_pExtrapolatorCorr->m_iSOffset[2],m_pExtrapolatorCorr->m_iSRange[2]); abort(); } bs->WriteBits(m_pExtrapolatorCorr->m_iSOffset[2],4); // CrossS if (m_pExtrapolatorCorr->m_bCrossS) bs->WriteBit(1); else bs->WriteBit(0); // CrossRangeS if (m_pExtrapolatorCorr->m_bCrossRangeS) bs->WriteBit(1); else bs->WriteBit(0); // Wrap if (m_pExtrapolatorCorr->m_bWrap) bs->WriteBit(1); else bs->WriteBit(0); // DistExpo if ((m_pExtrapolatorCorr->m_fDistExpo < 0) || (m_pExtrapolatorCorr->m_fDistExpo > 16.0)) { m_IF.eprintf("CBQBEngine::ExportExtrapolatorSettings(): Error: m_pExtrapolatorCorr.DistExpo out of range (%.3f, allowed 0..16).\n", m_pExtrapolatorCorr->m_fDistExpo); abort(); } bs->WriteBits((unsigned int)floor(m_pExtrapolatorCorr->m_fDistExpo*1000.0+0.5),14); // CorrFactor bs->WriteBits(0,11); } else { // SRangeX if ((m_pExtrapolator->m_iSRange[0] < 1) || (m_pExtrapolator->m_iSRange[0] > 15)) { m_IF.eprintf("CBQBEngine::ExportExtrapolatorSettings(): Error: m_pExtrapolator.SRangeX out of range (%d, allowed 1..15).\n", m_pExtrapolator->m_iSRange[0]); abort(); } bs->WriteBits(m_pExtrapolator->m_iSRange[0],4); // SRangeY if ((m_pExtrapolator->m_iSRange[1] < 1) || (m_pExtrapolator->m_iSRange[1] > 15)) { m_IF.eprintf("CBQBEngine::ExportExtrapolatorSettings(): Error: m_pExtrapolator.SRangeY out of range (%d, allowed 1..15).\n", m_pExtrapolator->m_iSRange[1]); abort(); } bs->WriteBits(m_pExtrapolator->m_iSRange[1],4); // SRangeZ if ((m_pExtrapolator->m_iSRange[2] < 1) || (m_pExtrapolator->m_iSRange[2] > 15)) { m_IF.eprintf("CBQBEngine::ExportExtrapolatorSettings(): Error: m_pExtrapolator.SRangeZ out of range (%d, allowed 1..15).\n", m_pExtrapolator->m_iSRange[2]); abort(); } bs->WriteBits(m_pExtrapolator->m_iSRange[2],4); // SOrder if ((m_pExtrapolator->m_iSOrder < 0) || (m_pExtrapolator->m_iSOrder > 15)) { m_IF.eprintf("CBQBEngine::ExportExtrapolatorSettings(): Error: m_pExtrapolator.SOrder out of range (%d, allowed 0..15).\n", m_pExtrapolator->m_iSOrder); abort(); } bs->WriteBits(m_pExtrapolator->m_iSOrder,4); // OffsetX if ((m_pExtrapolator->m_iSOffset[0] < 0) || (m_pExtrapolator->m_iSOffset[0] > 15)) { m_IF.eprintf("CBQBEngine::ExportExtrapolatorSettings(): Error: m_pExtrapolator.SOffsetX out of range (%d, allowed 0..15).\n", m_pExtrapolator->m_iSOffset[0]); abort(); } if (m_pExtrapolator->m_iSOffset[0] >= m_pExtrapolator->m_iSRange[0]) { m_IF.eprintf("CBQBEngine::ExportExtrapolatorSettings(): Error: m_pExtrapolator.SOffsetX (%d) >= SRangeX (%d.\n", m_pExtrapolator->m_iSOffset[0],m_pExtrapolator->m_iSRange[0]); abort(); } bs->WriteBits(m_pExtrapolator->m_iSOffset[0],4); // OffsetY if ((m_pExtrapolator->m_iSOffset[1] < 0) || (m_pExtrapolator->m_iSOffset[1] > 15)) { m_IF.eprintf("CBQBEngine::ExportExtrapolatorSettings(): Error: m_pExtrapolator.SOffsetY out of range (%d, allowed 0..15).\n", m_pExtrapolator->m_iSOffset[1]); abort(); } if (m_pExtrapolator->m_iSOffset[1] >= m_pExtrapolator->m_iSRange[1]) { m_IF.eprintf("CBQBEngine::ExportExtrapolatorSettings(): Error: m_pExtrapolator.SOffsetY (%d) >= SRangeY (%d.\n", m_pExtrapolator->m_iSOffset[1],m_pExtrapolator->m_iSRange[1]); abort(); } bs->WriteBits(m_pExtrapolator->m_iSOffset[1],4); // OffsetZ if ((m_pExtrapolator->m_iSOffset[2] < 0) || (m_pExtrapolator->m_iSOffset[2] > 15)) { m_IF.eprintf("CBQBEngine::ExportExtrapolatorSettings(): Error: m_pExtrapolator.SOffsetZ out of range (%d, allowed 0..15).\n", m_pExtrapolator->m_iSOffset[2]); abort(); } if (m_pExtrapolator->m_iSOffset[2] >= m_pExtrapolator->m_iSRange[2]) { m_IF.eprintf("CBQBEngine::ExportExtrapolatorSettings(): Error: m_pExtrapolator.SOffsetZ (%d) >= SRangeZ (%d.\n", m_pExtrapolator->m_iSOffset[2],m_pExtrapolator->m_iSRange[2]); abort(); } bs->WriteBits(m_pExtrapolator->m_iSOffset[2],4); // CrossS if (m_pExtrapolator->m_bCrossS) bs->WriteBit(1); else bs->WriteBit(0); // CrossRangeS if (m_pExtrapolator->m_bCrossRangeS) bs->WriteBit(1); else bs->WriteBit(0); // Wrap if (m_pExtrapolator->m_bWrap) bs->WriteBit(1); else bs->WriteBit(0); // DistExpo if ((m_pExtrapolator->m_fDistExpo < 0) || (m_pExtrapolator->m_fDistExpo > 16.0)) { m_IF.eprintf("CBQBEngine::ExportExtrapolatorSettings(): Error: m_pExtrapolator.DistExpo out of range (%.3f, allowed 0..16).\n", m_pExtrapolator->m_fDistExpo); abort(); } bs->WriteBits((unsigned int)floor(m_pExtrapolator->m_fDistExpo*1000.0+0.5),14); // CorrFactor bs->WriteBits(0,11); } // TRange if ((m_pExtrapolator->m_iTRange < 0) || (m_pExtrapolator->m_iTRange > 15)) { m_IF.eprintf("CBQBEngine::ExportExtrapolatorSettings(): Error: m_pExtrapolator.TRange out of range (%d, allowed 0..15).\n", m_pExtrapolator->m_iTRange); abort(); } bs->WriteBits(m_pExtrapolator->m_iTRange,4); // TOrder if ((m_pExtrapolator->m_iTOrder < 0) || (m_pExtrapolator->m_iTOrder > 15)) { m_IF.eprintf("CBQBEngine::ExportExtrapolatorSettings(): Error: m_pExtrapolator.TOrder out of range (%d, allowed 0..15).\n", m_pExtrapolator->m_iTOrder); abort(); } bs->WriteBits(m_pExtrapolator->m_iTOrder,4); // CrossT if (m_pExtrapolator->m_bCrossT) bs->WriteBit(1); else bs->WriteBit(0); // CrossRangeT if (m_pExtrapolator->m_bCrossRangeT) bs->WriteBit(1); else bs->WriteBit(0); // TimeExpo if ((m_pExtrapolator->m_fTimeExpo < 0) || (m_pExtrapolator->m_fTimeExpo > 16.0)) { m_IF.eprintf("CBQBEngine::ExportExtrapolatorSettings(): Error: m_pExtrapolator.TimeExpo out of range (%.3f, allowed 0..16).\n", m_pExtrapolator->m_fTimeExpo); abort(); } bs->WriteBits((unsigned int)floor(m_pExtrapolator->m_fTimeExpo*1000.0+0.5),14); // Reserved bs->WriteBit(0); } else { // Position // Use Position Extrapolator? if (m_pExtrapolatorXYZ == NULL) { bs->WriteBit(0); return; } bs->WriteBit(1); // TRange if ((m_pExtrapolatorXYZ->m_iTRange < 0) || (m_pExtrapolatorXYZ->m_iTRange > 15)) { m_IF.eprintf("CBQBEngine::ExportExtrapolatorSettings(): Error: m_pExtrapolatorXYZ.TRange out of range (%d, allowed 0..15).\n", m_pExtrapolatorXYZ->m_iTRange); abort(); } bs->WriteBits(m_pExtrapolatorXYZ->m_iTRange,4); // TOrder if ((m_pExtrapolatorXYZ->m_iTOrder < 0) || (m_pExtrapolatorXYZ->m_iTOrder > 15)) { m_IF.eprintf("CBQBEngine::ExportExtrapolatorSettings(): Error: m_pExtrapolatorXYZ.TOrder out of range (%d, allowed 0..15).\n", m_pExtrapolatorXYZ->m_iTOrder); abort(); } bs->WriteBits(m_pExtrapolatorXYZ->m_iTOrder,4); // TimeExpo if ((m_pExtrapolatorXYZ->m_fTimeExpo < 0) || (m_pExtrapolatorXYZ->m_fTimeExpo > 16.0)) { m_IF.eprintf("CBQBEngine::ExportExtrapolatorSettings(): Error: m_pExtrapolatorXYZ.TimeExpo out of range (%.3f, allowed 0..16).\n", m_pExtrapolatorXYZ->m_fTimeExpo); abort(); } bs->WriteBits((unsigned int)floor(m_pExtrapolatorXYZ->m_fTimeExpo*1000.0+0.5),14); // Reserved bs->WriteBit(0); } } void CBQBEngine::ImportExtrapolatorSettings(CBQBBitSet *bs, bool volumetric) { int srangex, srangey, srangez, trange, sorder, torder, offsetx, offsety, offsetz, postrange, postorder, resx, resy, resz; bool crosss, crosst, wrap, crossranges, crossranget; double distexpo, timeexpo, postimeexpo; bool predcorr; if (volumetric) { if (!bs->ReadBit()) { if (m_pExtrapolator != NULL) { m_IF.eprintf("CBQBEngine::ImportExtrapolatorSettings(): Warning: No volumetric extrapolator specified in input frame, but m_pExtrapolator != NULL.\n"); delete m_pExtrapolator; m_pExtrapolator = NULL; } if (m_pExtrapolatorCorr != NULL) { m_IF.eprintf("CBQBEngine::ImportExtrapolatorSettings(): Warning: No volumetric extrapolator specified in input frame, but m_pExtrapolatorCorr != NULL.\n"); delete m_pExtrapolatorCorr; m_pExtrapolatorCorr = NULL; } return; } // ResX resx = bs->ReadBitsInteger(10); // ResY resy = bs->ReadBitsInteger(10); // ResZ resz = bs->ReadBitsInteger(10); // PredCorr predcorr = bs->ReadBit(); // SRangeX srangex = bs->ReadBitsInteger(4); // SRangeY srangey = bs->ReadBitsInteger(4); // SRangeZ srangez = bs->ReadBitsInteger(4); // SOrder sorder = ((int)bs->ReadBitsInteger(4)); // OffsetX offsetx = bs->ReadBitsInteger(4); // OffsetY offsety = bs->ReadBitsInteger(4); // OffsetZ offsetz = bs->ReadBitsInteger(4); // CrossS crosss = bs->ReadBit(); // CrossRangeS crossranges = bs->ReadBit(); // Wrap wrap = bs->ReadBit(); // DistExpo distexpo = bs->ReadBitsInteger(14) / 1000.0; // CorrFactor bs->ReadBitsInteger(11); // TRange trange = bs->ReadBitsInteger(4); // TOrder torder = ((int)bs->ReadBitsInteger(4)); // CrossT crosst = bs->ReadBit(); // CrossRangeT crossranget = bs->ReadBit(); // TimeExpo timeexpo = bs->ReadBitsInteger(14) / 1000.0; // Reserved if (bs->ReadBit()) { m_IF.eprintf("CBQBEngine::ImportExtrapolatorSettings(): Error: Reserved bit after volumetric extrapolator is 1.\n"); m_IF.printf("Either the BQB file is damaged, or was written with a more recent software version.\n\n"); abort(); } if (m_pExtrapolator != NULL) { if (predcorr) { if (m_pExtrapolatorCorr == NULL) goto _volcheckfail; // SRangeX if (m_pExtrapolatorCorr->m_iSRange[0] != srangex) goto _volcheckfail; // SRangeY if (m_pExtrapolatorCorr->m_iSRange[1] != srangey) goto _volcheckfail; // SRangeZ if (m_pExtrapolatorCorr->m_iSRange[2] != srangez) goto _volcheckfail; // SOrder if (m_pExtrapolatorCorr->m_iSOrder != sorder) goto _volcheckfail; // OffsetX if (m_pExtrapolatorCorr->m_iSOffset[0] != offsetx) goto _volcheckfail; // OffsetY if (m_pExtrapolatorCorr->m_iSOffset[1] != offsety) goto _volcheckfail; // OffsetZ if (m_pExtrapolatorCorr->m_iSOffset[2] != offsetz) goto _volcheckfail; // CrossS if (m_pExtrapolatorCorr->m_bCrossS != crosss) goto _volcheckfail; // CrossRangeS if (m_pExtrapolatorCorr->m_bCrossRangeS != crossranges) goto _volcheckfail; // Wrap if (m_pExtrapolatorCorr->m_bWrap != wrap) goto _volcheckfail; // DistExpo if (fabs(m_pExtrapolatorCorr->m_fDistExpo-distexpo) > 1.0e-6) goto _volcheckfail; } else { if (m_pExtrapolatorCorr != NULL) goto _volcheckfail; // SRangeX if (m_pExtrapolator->m_iSRange[0] != srangex) goto _volcheckfail; // SRangeY if (m_pExtrapolator->m_iSRange[1] != srangey) goto _volcheckfail; // SRangeZ if (m_pExtrapolator->m_iSRange[2] != srangez) goto _volcheckfail; // SOrder if (m_pExtrapolator->m_iSOrder != sorder) goto _volcheckfail; // OffsetX if (m_pExtrapolator->m_iSOffset[0] != offsetx) goto _volcheckfail; // OffsetY if (m_pExtrapolator->m_iSOffset[1] != offsety) goto _volcheckfail; // OffsetZ if (m_pExtrapolator->m_iSOffset[2] != offsetz) goto _volcheckfail; // CrossS if (m_pExtrapolator->m_bCrossS != crosss) goto _volcheckfail; // CrossRangeS if (m_pExtrapolator->m_bCrossRangeS != crossranges) goto _volcheckfail; // Wrap if (m_pExtrapolator->m_bWrap != wrap) goto _volcheckfail; // DistExpo if (fabs(m_pExtrapolator->m_fDistExpo-distexpo) > 1.0e-6) goto _volcheckfail; } // ResX if (m_pExtrapolator->m_iRes[0] != resx) goto _volcheckfail; // ResY if (m_pExtrapolator->m_iRes[1] != resy) goto _volcheckfail; // ResZ if (m_pExtrapolator->m_iRes[2] != resz) goto _volcheckfail; // TRange if (m_pExtrapolator->m_iTRange != trange) goto _volcheckfail; // TOrder if (m_pExtrapolator->m_iTOrder != torder) goto _volcheckfail; // CrossT if (m_pExtrapolator->m_bCrossT != crosst) goto _volcheckfail; // CrossRangeT if (m_pExtrapolator->m_bCrossRangeT != crossranget) goto _volcheckfail; // TimeExpo if (fabs(m_pExtrapolator->m_fTimeExpo-timeexpo) > 1.0e-6) goto _volcheckfail; return; _volcheckfail: m_IF.eprintf("CBQBEngine::ImportExtrapolatorSettings(): Warning: Reloading volumetric extrapolator with different settings.\n"); delete m_pExtrapolator; m_pExtrapolator = NULL; } if (m_pExtrapolatorCorr != NULL) { delete m_pExtrapolatorCorr; m_pExtrapolatorCorr = NULL; } if (predcorr) { if (m_IF.IsPL(BQB_PL_STANDARD)) m_IF.printf(" Initializing Volumetric Predictor Extrapolator (%d|%d)...\n",trange,torder); m_pExtrapolator = new CBQBExtrapolator(m_IF); m_pExtrapolator->Initialize( resx, // resx, resy, // resy, resz, // resz, 1, // srangex, 1, // srangey, 1, // srangez, trange, // trange, 0, // sorder, torder, // torder, 0, // offsetx, 0, // offsety, 0, // offsetz, false, // crosss, false, // crosst, false, // wrap, false, // crossranges, false, // crossranget 0, // distexpo timeexpo, // timeexpo false ); if (m_IF.IsPL(BQB_PL_STANDARD)) { if ((srangex == srangey) && (srangex == srangez)) m_IF.printf(" Initializing Volumetric Corrector Extrapolator (%d/%d)...\n",srangex,sorder); else m_IF.printf(" Initializing Volumetric Corrector Extrapolator (%d|%d|%d/%d)...\n", srangex,srangey,srangez,sorder); } m_pExtrapolatorCorr = new CBQBExtrapolator(m_IF); m_pExtrapolatorCorr->Initialize( resx, // resx, resy, // resy, resz, // resz, srangex, // srangex, srangey, // srangey, srangez, // srangez, 1, // trange, sorder, // sorder, 0, // torder, offsetx, // offsetx, offsety, // offsety, offsetz, // offsetz, crosss, // crosss, false, // crosst, wrap, // wrap, crossranges, // crossranges, false, // crossranget distexpo, // distexpo 0, // timeexpo false ); } else { if (m_IF.IsPL(BQB_PL_STANDARD)) { if ((srangex == srangey) && (srangex == srangez)) m_IF.printf(" Initializing Volumetric Extrapolator (%d/%d;%d/%d)...\n", srangex,sorder,trange,torder); else m_IF.printf(" Initializing Volumetric Extrapolator (%d|%d|%d/%d;%d/%d)...\n", srangex,srangey,srangez,sorder,trange,torder); } m_pExtrapolator = new CBQBExtrapolator(m_IF); m_pExtrapolator->Initialize( resx, // resx, resy, // resy, resz, // resz, srangex, // srangex, srangey, // srangey, srangez, // srangez, trange, // trange, sorder, // sorder, torder, // torder, offsetx, // offsetx, offsety, // offsety, offsetz, // offsetz, crosss, // crosss, crosst, // crosst, wrap, // wrap, crossranges, // crossranges, crossranget, // crossranget distexpo, // distexpo timeexpo, // timeexpo false ); } } else { // Use Position Extrapolator? if (!bs->ReadBit()) { if (m_pExtrapolatorXYZ != NULL) { m_IF.eprintf("CBQBEngine::ImportExtrapolatorSettings(): Warning: No position extrapolator specified in input frame, but m_pExtrapolatorXYZ != NULL.\n"); delete m_pExtrapolatorXYZ; m_pExtrapolatorXYZ = NULL; } return; } // TRange postrange = bs->ReadBitsInteger(4); // TOrder postorder = ((int)bs->ReadBitsInteger(4)); // TimeExpo postimeexpo = bs->ReadBitsInteger(14) / 1000.0; // Reserved if (bs->ReadBit()) { m_IF.eprintf("CBQBEngine::ImportExtrapolatorSettings(): Error: Reserved bit after position extrapolator is 1.\n"); m_IF.printf("Either the BQB file is damaged, or was written with a more recent software version.\n\n"); abort(); } if (m_pExtrapolatorXYZ != NULL) { // TRange if (m_pExtrapolatorXYZ->m_iTRange != postrange) goto _poscheckfail; // TOrder if (m_pExtrapolatorXYZ->m_iTOrder != postorder) goto _poscheckfail; // TimeExpo if (fabs(m_pExtrapolatorXYZ->m_fTimeExpo-postimeexpo) > 1.0e-6) goto _poscheckfail; return; _poscheckfail: m_IF.eprintf("CBQBEngine::ImportExtrapolatorSettings(): Warning: Reloading position extrapolator with different settings.\n"); delete m_pExtrapolatorXYZ; m_pExtrapolatorXYZ = NULL; } if (m_IF.IsPL(BQB_PL_STANDARD)) m_IF.printf(" Initializing Extrapolator (%d|%d)...\n",postrange,postorder); m_pExtrapolatorXYZ = new CBQBExtrapolator(m_IF); m_pExtrapolatorXYZ->InitializeXYZ(postrange,postorder,postimeexpo,false); } } // Renders an image of a 3D Hilbert Curve in POVRay with Ambient Occlusion through Radiosity void CBQBEngine::ExportPOVRayScene(int degree, const char *s) { FILE *a; unsigned long z, res, crd[3], oldcrd[3]; double dres; CBQBTools bqbtools(m_IF); crd[0] = 0; crd[1] = 0; crd[2] = 0; if (m_IF.IsPL(BQB_PL_STANDARD)) m_IF.printf("Exporting POVRay scene of 3D Hilbert curve to \"%s\"...\n",s); a = bqbtools.BQBOpenFileWrite(s,true); res = pow2i(degree); dres = (double)res; if (m_IF.IsPL(BQB_PL_STANDARD)) { m_IF.printf(" Resolution is %lu x %lu x %lu.\n",res,res,res); m_IF.printf(" Render with POVRay using \"+W1280 +H960 +J +A0.1 +AM2\" for high quality.\n"); } fprintf(a,"global_settings {\n"); fprintf(a," assumed_gamma 2.2\n"); fprintf(a," adc_bailout 1/255\n"); fprintf(a," charset utf8\n"); fprintf(a," // 1 unit in coordinate system = 1 cm\n"); fprintf(a," // To calculate SSLT for different materials\n"); fprintf(a," mm_per_unit 10\n"); fprintf(a," // Only with +q9 or higher\n"); fprintf(a," subsurface {\n"); fprintf(a," // Number of sample rays for diffuse (first value) and single\n"); fprintf(a," // (second value) scattering\n"); fprintf(a," // Lower values -> better performance\n"); fprintf(a," samples 50, 50\n"); fprintf(a," // Use subsurface scattering on radiosity photons\n"); fprintf(a," radiosity on\n"); fprintf(a," }\n"); fprintf(a,"\n"); fprintf(a," radiosity {\n"); fprintf(a," gray_threshold 0.0\n"); fprintf(a," brightness 1\n"); fprintf(a," // not smaller than 0.0039\n"); fprintf(a," adc_bailout 0.005\n"); fprintf(a," // not lower than 2 for isosurfaces, not bigger than 3\n"); fprintf(a," recursion_limit 3\n"); fprintf(a," // lowers error bound during pretrace, removes blotches (default 0.5)\n"); fprintf(a," low_error_factor 0.5\n"); fprintf(a," // Fraction of screen to follow bounced rays (default 0.015)\n"); fprintf(a," // Too small ? rendering gets slow; too high ? no natural darkening\n"); fprintf(a," // of crevices as rays get reused\n"); fprintf(a," minimum_reuse 0.015\n"); fprintf(a," maximum_reuse 0.2\n"); fprintf(a," // Min and maxsize of block in mosaic preview during pretrace\n"); fprintf(a," // default 0.08\n"); fprintf(a," pretrace_start 0.08\n"); fprintf(a," // not smaller than 0.02 (default 0.04)\n"); fprintf(a," pretrace_end 0.003 // Use 0.04 for testing\n"); fprintf(a," count 1200 // Use 100 or even 20 for testing\n"); fprintf(a," // Max number of radiosity values to be blended together (default\n"); fprintf(a," // 4, max 20)\n"); fprintf(a," // Smaller than 4 ? patchiness\n"); fprintf(a," nearest_count 20\n"); fprintf(a," // lower error bound ? more artifacts (requires higher count), but\n"); fprintf(a," // also higher quality\n"); fprintf(a," error_bound 0.2 // Use 0.4 for testing\n"); fprintf(a," }\n"); fprintf(a,"}\n"); fprintf(a,"\n"); fprintf(a,"#declare rad = 0.23;\n"); fprintf(a,"\n"); fprintf(a,"#declare rot_angle = 0.5;\n"); fprintf(a,"#declare camera_dist = 800.0;\n"); fprintf(a,"#declare camera_x = 10.0 * camera_dist / 1566.0 * sin(rot_angle);\n"); fprintf(a,"#declare camera_y = 4.0 * camera_dist / 1566.0;\n"); fprintf(a,"#declare camera_z = 10.0 * camera_dist /1566.0 * cos(rot_angle);\n"); fprintf(a,"\n"); fprintf(a,"#macro Hilbert_Sphere( pos )\n"); fprintf(a," sphere {\n"); fprintf(a," pos, rad / 16.0\n"); fprintf(a," pigment { rgb < 0.8, 0.8, 0.8 > }\n"); fprintf(a," finish {\n"); fprintf(a," reflection 0\n"); fprintf(a," specular 0.0\n"); fprintf(a," ambient 0.0\n"); fprintf(a," diffuse 0.6\n"); fprintf(a," roughness 0.12\n"); fprintf(a," }\n"); fprintf(a," no_shadow\n"); fprintf(a," }\n"); fprintf(a,"#end\n"); fprintf(a,"\n"); fprintf(a,"#macro Hilbert_Cylinder( pos1, pos2 )\n"); fprintf(a," cylinder {\n"); fprintf(a," pos1, pos2, rad / 16.0\n"); fprintf(a," open\n"); fprintf(a," pigment { rgb < 0.8, 0.8, 0.8 > }\n"); fprintf(a," finish {\n"); fprintf(a," reflection 0\n"); fprintf(a," specular 0.0\n"); fprintf(a," ambient 0.0\n"); fprintf(a," diffuse 0.6\n"); fprintf(a," roughness 0.12\n"); fprintf(a," }\n"); fprintf(a," no_shadow\n"); fprintf(a," }\n"); fprintf(a,"#end\n"); fprintf(a,"\n"); fprintf(a,"camera {\n"); fprintf(a," location < camera_x, camera_y, camera_z >\n"); fprintf(a," sky y\n"); fprintf(a," right -0.3*x*image_width/image_height\n"); fprintf(a," up 0.3*y\n"); fprintf(a," look_at < 0.5, 0.42, 0.5 >\n"); fprintf(a,"}\n"); fprintf(a,"\n"); fprintf(a,"// Solid colored Background\n"); fprintf(a,"background { rgb < 1.0, 1.0, 1.0 > }\n"); fprintf(a,"\n"); fprintf(a,"/***** Color Gradient Background ****/ \n"); fprintf(a,"/*\n"); fprintf(a,"sky_sphere {\n"); fprintf(a," pigment {\n"); fprintf(a," gradient y\n"); fprintf(a," color_map {\n"); fprintf(a," [ 0 color rgb < 0.9, 0.9, 0.9 > ]\n"); fprintf(a," [ 1 color rgb < 0.85, 0.75, 1.0 > ]\n"); fprintf(a," }\n"); fprintf(a," scale 1\n"); fprintf(a," translate -0.05\n"); fprintf(a," }\n"); fprintf(a,"}\n"); fprintf(a,"\n"); fprintf(a,"// Two light sources\n"); fprintf(a,"light_source { < 21.54*sin(rot_angle-0.7297), 20, 21.54*cos(rot_angle-0.7297) > color rgb 0.8 }\n"); fprintf(a,"light_source { < 32.02*sin(rot_angle+0.547), 12, 32.02*cos(rot_angle+0.547) > color rgb 0.5 } */\n"); fprintf(a,"\n"); fprintf(a,"// Weak highlight within the sky sphere\n"); fprintf(a,"light_source {\n"); fprintf(a," 500\n"); fprintf(a," // Light intensity depends on color brightness\n"); fprintf(a," rgb .5\n"); fprintf(a," // Cylindrical and spot lights can be area lights as well\n"); fprintf(a," area_light 100*x, 100*y, 100, 100\n"); fprintf(a," // Automatically adapt number of light sources\n"); fprintf(a," adaptive 1\n"); fprintf(a," // Add random positional noise to light source positions\n"); fprintf(a," jitter\n"); fprintf(a," // Use circular area light\n"); fprintf(a," circular\n"); fprintf(a," // Always normalize the light area with regard to the ray\n"); fprintf(a," orient\n"); fprintf(a,"}\n"); fprintf(a,"// invisible pseudo-sky sphere\n"); fprintf(a,"sphere {\n"); fprintf(a," 0, 1\n"); fprintf(a," pigment {\n"); fprintf(a," color rgb 1\n"); fprintf(a," }\n"); fprintf(a," finish {\n"); fprintf(a," emission .5\n"); fprintf(a," }\n"); fprintf(a," // make sure the sphere is big enough to cover the entire scene\n"); fprintf(a," scale 1000\n"); fprintf(a," hollow\n"); fprintf(a," // make sphere invisible for direct rays\n"); fprintf(a," no_image\n"); fprintf(a,"}\n"); fprintf(a,"// Here the actual Hilbert curve data follows\n\n"); for (z=0;z )\n",crd[0]/dres,crd[1]/dres,crd[2]/dres); if (z > 0) { fprintf(a,"Hilbert_Cylinder( < %f, %f, %f >, < %f, %f, %f > )\n", oldcrd[0]/dres,oldcrd[1]/dres,oldcrd[2]/dres,crd[0]/dres,crd[1]/dres,crd[2]/dres); } } fprintf(a,"\n"); if (m_IF.IsPL(BQB_PL_STANDARD)) m_IF.printf("Done.\n"); fclose(a); } void CBQBEngine::ExportXYZScene(int degree, const char *s) { unsigned long z, res, crd[3]; FILE *a; CBQBTools bqbtools(m_IF); res = pow2i(degree); if (m_IF.IsPL(BQB_PL_STANDARD)) m_IF.printf("Exporting XYZ scene of 3D Hilbert curve to \"%s\"...\n",s); a = bqbtools.BQBOpenFileWrite(s,true); res = pow2i(degree); if (m_IF.IsPL(BQB_PL_STANDARD)) m_IF.printf(" Resolution is %lu x %lu x %lu.\n",res,res,res); fprintf(a,"%lu\nHilbert Scene\n",res*res*res); for (z=0;z. ***********************************************************************************/ #ifndef BQB_ENGINE_H #define BQB_ENGINE_H // This must always be the first include directive #include "bqb_config.h" #include "bqb_tools.h" #include #include "bqb_cubeframe.h" #include "bqb_hufftree.h" #include "bqb_extrapolator.h" #include "bqb_parmset.h" #include "bqb_interface.h" class CBQBInterface; class CBQBCellInfo { public: CBQBCellInfo() : m_mCell(0) { } void SetCellInfo(double x, double y, double z) { m_mCell.Unity(); m_mCell(0,0) = x; m_mCell(1,1) = y; m_mCell(2,2) = z; } void SetCellInfo(double ax, double ay, double az, double bx, double by, double bz, double cx, double cy, double cz) { m_mCell(0,0) = ax; m_mCell(0,1) = ay; m_mCell(0,2) = az; m_mCell(1,0) = bx; m_mCell(1,1) = by; m_mCell(1,2) = bz; m_mCell(2,0) = cx; m_mCell(2,1) = cy; m_mCell(2,2) = cz; } bool IsCubic() const { if ((m_mCell(0,0) == m_mCell(1,1)) && (m_mCell(0,0) == m_mCell(2,2)) && (m_mCell(0,1) == 0) && (m_mCell(0,2) == 0) && (m_mCell(1,0) == 0) && (m_mCell(1,2) == 0) && (m_mCell(2,0) == 0) && (m_mCell(2,1) == 0)) return true; else return false; } bool IsOrthorhombic() const { if ((m_mCell(0,1) == 0) && (m_mCell(0,2) == 0) && (m_mCell(1,0) == 0) && (m_mCell(1,2) == 0) && (m_mCell(2,0) == 0) && (m_mCell(2,1) == 0)) return true; else return false; } CBQBDMatrix3 m_mCell; }; template class CBQBReadCache { public: CBQBReadCache(CBQBInterface &i) : m_IF(i), m_iHistoryDepth(0), m_iCachePos(0), m_iReadPos(0), m_fRef(NULL), m_fInput(NULL), m_bStartLock(false) { } virtual ~CBQBReadCache() { if (m_fInput != NULL) CloseFile(); for (int z=0;z<(int)m_oaFrames.size();z++) if (m_oaFrames[z] != NULL) delete m_oaFrames[z]; m_oaFrames.clear(); } void SetStartLock() { if (m_bStartLock) { m_IF.eprintf("CCCReadCache::SetStartLock(): Error: Start lock already set.\n"); abort(); } m_bStartLock = true; } void LiftStartLock() { if (!m_bStartLock) { m_IF.eprintf("CCCReadCache::LiftStartLock(): Error: Start lock not in place.\n"); abort(); } m_bStartLock = false; } void SetHistoryDepth(int i) { m_oaFrames.resize(i,NULL); } int GetCachedSteps() const { if (m_iCachePos >= m_iReadPos) return m_iCachePos - m_iReadPos; else return m_iCachePos - m_iReadPos + (int)m_oaFrames.size(); } const FT* GetFrameHistory(int i) const { if (i > m_iHistoryDepth) { m_IF.eprintf("CCCReadCache::GetFrameHistory(): Error: Index out of range (%d/%d).\n",i,m_iHistoryDepth); abort(); } int t = m_iReadPos - i; if (t < 0) t += (int)m_oaFrames.size(); return m_oaFrames[t]; } const FT* GetNextFrame() { if (m_iReadPos == m_iCachePos) { m_iCachePos++; if (m_iCachePos >= (int)m_oaFrames.size()) { if (m_bStartLock) { m_IF.eprintf("CCCReadCache::GetNextFrame(): Error: Violation of start lock.\n"); abort(); } m_iCachePos = 0; } if (!CacheOneStep()) return NULL; } m_iReadPos++; if (m_iReadPos >= (int)m_oaFrames.size()) m_iReadPos = 0; if (m_iHistoryDepth+1 < (int)m_oaFrames.size()) m_iHistoryDepth++; return m_oaFrames[m_iReadPos]; } bool CacheSteps(int i, bool progress) { if (progress) { m_IF.printf(" Caching %d frames...\n",i); m_IF.printf(" ["); } double tfs = i / 60.0; int k=0; for (int z=0;z= (int)m_oaFrames.size()) { if (m_bStartLock) { m_IF.eprintf("CCCReadCache::CacheSteps(): Error: Violation of start lock.\n"); abort(); } m_iCachePos = 0; } if (!CacheOneStep()) { m_iCachePos--; if (m_iCachePos < 0) m_iCachePos = (int)m_oaFrames.size()-1; m_IF.printf("] Only %d frames read.\n",k); return false; } k++; if (progress && (fmod(z,tfs) < 1.0)) m_IF.printf("#"); } if (progress) m_IF.printf("] Done.\n"); return true; } void RewindReadPos() { if (!m_bStartLock) { m_IF.eprintf("CCCReadCache::RewindReadPos(): Error: Requires start lock.\n"); abort(); } m_iReadPos = -1; } bool FileOpenRead(const char *inp, const char *ref = NULL) { m_iCachePos = -1; m_iReadPos = -1; m_fInput = fopen(inp,"rb"); if (m_fInput == NULL) { m_IF.eprintf("CCCReadCache::FileOpenRead(): Error: Could not open input file for reading.\n"); return false; } if (ref != NULL) { m_fRef = fopen(inp,"wb"); if (m_fRef == NULL) { m_IF.eprintf("CCCReadCache::FileOpenRead(): Error: Could not open reference file for writing.\n"); fclose(m_fInput); m_fInput = NULL; return false; } } return true; } void CloseFile() { fclose(m_fInput); m_fInput = NULL; if (m_fRef != NULL) { fclose(m_fRef); m_fRef = NULL; } } long ftell() { if (m_fInput == NULL) return 0; return ::ftell(m_fInput); } virtual bool SkipOneStep() = 0; protected: CBQBInterface &m_IF; virtual bool CacheOneStep() = 0; int m_iHistoryDepth; int m_iCachePos; // Frame which has been cached last int m_iReadPos; // Frame which was read last std::vector m_oaFrames; FILE *m_fRef; FILE *m_fInput; bool m_bStartLock; }; class CBQBReadXYZCache : public CBQBReadCache { public: CBQBReadXYZCache(CBQBInterface &i) : CBQBReadCache(i), m_iSigni(-1) { } ~CBQBReadXYZCache() { } void SetReadParameters(int signi) { m_iSigni = signi; } bool SkipOneStep() { return CBQBAtomSet().SkipXYZ(m_fInput); } private: bool CacheOneStep() { if ((m_iCachePos < 0) || (m_iCachePos >= (int)m_oaFrames.size())) { m_IF.eprintf("CBQBReadXYZCache::CacheOneStep(): Error: m_iCachePos out of range (%d/%lu).\n",m_iCachePos,m_oaFrames.size()); abort(); } if (m_iSigni < 0) { m_IF.eprintf("CBQBReadXYZCache::CacheOneStep(): Error: m_iSigni out of range (%d).\n",m_iSigni); abort(); } if (m_oaFrames[m_iCachePos] != NULL) delete m_oaFrames[m_iCachePos]; m_oaFrames[m_iCachePos] = new CBQBAtomSet(); if (m_fInput == NULL) { m_IF.eprintf("CBQBReadXYZCache::CacheOneStep(): Error: m_fInput == NULL.\n"); abort(); } if (!m_oaFrames[m_iCachePos]->ReadXYZ(m_fInput,m_iSigni,m_fRef)) return false; return true; } int m_iSigni; }; class CBQBReadCubeCache : public CBQBReadCache { public: CBQBReadCubeCache(CBQBInterface &i) : CBQBReadCache(i), m_iEps(-1), m_iCSigni(-1), m_iASigni(-1) { } ~CBQBReadCubeCache() { } void SetReadParameters(int eps, int csigni, int asigni) { m_iEps = eps; m_iCSigni = csigni; m_iASigni = asigni; } bool SkipOneStep() { return CBQBCubeFrame(m_IF).SkipFrame(m_fInput); } private: bool CacheOneStep() { if ((m_iCachePos < 0) || (m_iCachePos >= (int)m_oaFrames.size())) { m_IF.eprintf("CBQBReadCubeCache::CacheOneStep(): Error: m_iCachePos out of range (%d/%lu).\n",m_iCachePos,m_oaFrames.size()); abort(); } if (m_oaFrames[m_iCachePos] != NULL) delete m_oaFrames[m_iCachePos]; m_oaFrames[m_iCachePos] = new CBQBCubeFrame(m_IF); if (m_fInput == NULL) { m_IF.eprintf("CBQBReadCubeCache::CacheOneStep(): Error: m_fInput == NULL.\n"); abort(); } if (!m_oaFrames[m_iCachePos]->ReadFrame(m_fInput,m_iEps,m_iCSigni,m_iASigni,false)) return false; if (m_fRef != NULL) m_oaFrames[m_iCachePos]->WriteFrame(m_fRef,false); return true; } int m_iEps; int m_iCSigni; int m_iASigni; }; class CBQBEngine { public: CBQBEngine(CBQBInterface &i); ~CBQBEngine(); void Reset(); void CompressString( const char *s, CBQBBitSet *bs, CBQBStatistics *stat ); void DecompressString( CBQBBitSet *bs, char **s ); void ExportCellInfo(CBQBCellInfo *ci, CBQBBitSet *bs); bool ImportCellInfo(CBQBCellInfo *ci, CBQBBitSet *bs); bool CubeToIntegerArray( std::vector &outp, int order, CBQBParameterSet_Volumetric *parm, int &histused, bool skipcomp=false, double *resi=NULL ); bool IntegerArrayToCube( std::vector &inp, int order, CBQBParameterSet_Volumetric *parm, int ver, bool second ); bool CompressCubeFrame( CBQBBitSet *bs, int corder, CBQBParameterSet_Volumetric *parm, int &histused, bool staticinfo, CBQBStatistics *stat, bool skipcomp=false, double *resi=NULL, std::vector > *tciaa=NULL ); bool DecompressCubeFrame( CBQBBitSet *bs, int ver, CBQBParameterSet_Volumetric *parm, int *histused, bool second, bool check ); bool CompressAtomFrame( CBQBBitSet *bs, int order, CBQBParameterSet_Position *parm, int &histused, bool staticinfo, bool comment, CBQBStatistics *stat, bool skipcomp=false, double *resi=NULL, std::vector > *tciaa=NULL ); bool DecompressAtomStep( const std::vector *inp, int ver, CBQBParameterSet_Position *parm, int *histused, bool second, bool check ); bool DecompressAtomFrame( CBQBBitSet *bs, int ver, CBQBParameterSet_Position *parm, int *histused, bool second, bool check ); bool PrepareDecompressCube(); bool DecompressCubeStep( const std::vector *inp, int ver, CBQBParameterSet_PosAndVol *parm, int *ahistused, int *chistused, bool skipvol=false ); void ExportCubeHeader( CBQBBitSet *bs, int order ); void ImportCubeHeader( CBQBBitSet *bs, bool second ); void ExportAtomLabels( const CBQBAtomSet *as, CBQBBitSet *bs, CBQBStatistics *stat ); void ImportAtomLabels( CBQBAtomSet *as, CBQBBitSet *bs ); void AtomsToIntegerArray( std::vector &outp, int order, CBQBParameterSet_Position *parm, int &histused, bool skipcomp=false, double *resi=NULL ); void IntegerArrayToAtoms( const std::vector &inp, int order, CBQBParameterSet_Position *parm, int ver, bool second ); void ExportPOVRayScene(int degree, const char *s); void ExportXYZScene(int degree, const char *s); // This struct is a hack to enable the comparison function for std::sort // to access class members of CBQBEngine. // Can't use global variables here, because multiple CBQBEngines // might be running in different threads... struct SSortAtomOrd { SSortAtomOrd(const CBQBEngine &e) : m_E(e) { } const CBQBEngine &m_E; bool operator()( const int & i1, const int & i2 ) { return m_E.m_iaAtomOrd[i1] > m_E.m_iaAtomOrd[i2]; } }; void ExportExtrapolatorSettings( CBQBBitSet *bs, bool volumetric ); void ImportExtrapolatorSettings( CBQBBitSet *bs, bool volumetric ); void PushOutputCubeFrame(CBQBCubeFrame *cfr); CBQBCubeFrame* GetOutputCubeFrame(int depth); void PushOutput2CubeFrame(CBQBCubeFrame *cfr); CBQBCubeFrame* GetOutput2CubeFrame(int depth); void PushOutputAtomFrame(CBQBAtomSet *cfr); CBQBAtomSet* GetOutputAtomFrame(int depth); void PushOutput2AtomFrame(CBQBAtomSet *cfr); CBQBAtomSet* GetOutput2AtomFrame(int depth); void PushInputAtomFrame_NoDelete(CBQBAtomSet *cfr); void PushInputCubeFrame_NoDelete(CBQBCubeFrame *cfr); void BuildHilbertIdx( int resx, int resy, int resz ); void BuildAtomSort(const CBQBAtomSet *as); void BuildIdentityAtomSort(const CBQBAtomSet *as); int m_iOutputCubeBufPos; std::vector m_oaOutputCubeBuf; int m_iOutput2CubeBufPos; std::vector m_oaOutput2CubeBuf; int m_iOutputAtomBufPos; std::vector m_oaOutputAtomBuf; int m_iOutput2AtomBufPos; std::vector m_oaOutput2AtomBuf; std::vector m_iaHilbertIdx; std::vector m_faTempPred; std::vector m_faTempPred2; std::vector m_iaAtomSort; std::vector m_iaTempCompressCube; std::vector m_iaTempCompressXYZ; CBQBExtrapolator *m_pExtrapolator; CBQBExtrapolator *m_pExtrapolatorCorr; CBQBExtrapolator *m_pExtrapolatorXYZ; CBQBReadXYZCache *m_pReadCacheXYZ; CBQBReadCubeCache *m_pReadCacheCube; std::vector m_iaAtomOrd; private: CBQBInterface &m_IF; }; #endif travis-src-190101/src/bqb_extrapolator.cpp0100777000000000000000000005166513412725617015532 0ustar00/*********************************************************************************** LibBQB - File Format and Compression Algorithms for Trajectories of Volumetric Data and Atom Positions https://brehm-research.de/bqb Free software, licensed under GNU LGPL v3 Copyright (c) Martin Brehm and Martin Thomas, Martin Luther University Halle-Wittenberg, Germany, 2016 - 2019. Please cite: M. Brehm, M. Thomas: "An Efficient Lossless Compression Algorithm for Trajectories of Atom Positions and Volumetric Data", J. Chem. Inf. Model. 2018, 58 (10), pp 2092-2107. -------------------------------------------------------------------------------- LibBQB is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program. If not, see . ***********************************************************************************/ // This must always be the first include directive #include "bqb_config.h" #include "bqb_extrapolator.h" #include "bqb_math.h" #include "bqb_linalg.h" #include "bqb_interface.h" #include const char *GetRevisionInfo_bqb_extrapolator(unsigned int len) { static char buf[256]; GET_REVISION_INFO( buf, len ); return buf; } const char *GetSourceVersion_bqb_extrapolator() { static char buf[256]; GET_SOURCE_VERSION( buf ); return buf; } void CBQBExtrapolator::Reset() { int z; m_iCubeFramePos = 0; m_iCubeFrameCount = 0; m_iCubeFrameVisibleCount = 0; for (z=0;z<(int)m_oaCubeFrames.size();z++) m_oaCubeFrames[z] = NULL; for (z=0;z<(int)m_oaAtomFrames.size();z++) m_oaAtomFrames[z] = NULL; } void CBQBExtrapolator::InitializeXYZ(CBQBParameterSet_Position *p, bool silent) { InitializeXYZ( p->GetExtraTRange(), p->GetExtraTOrder(), p->GetExtraTimeExpo(), silent ); } const CBQBCubeFrame* CBQBExtrapolator::GetCubeFrame(int depth) const { int i; if (depth >= m_iCubeFrameVisibleCount) { m_IF.eprintf("CBQBExtrapolator::GetCubeFrame(): Error: %d >= %d (%d).\n", depth,m_iCubeFrameVisibleCount,m_iCubeFrameCount); abort(); } i = m_iCubeFramePos - depth; if (i < 0) i += m_iTRange; return m_oaCubeFrames[i]; } const CBQBAtomSet* CBQBExtrapolator::GetAtomFrame(int depth) const { int i; if (depth >= m_iCubeFrameVisibleCount) { m_IF.eprintf("CBQBExtrapolator::GetAtomFrame(): Error: %d >= %d (%d).\n", depth,m_iCubeFrameVisibleCount,m_iCubeFrameCount); abort(); } i = m_iCubeFramePos - depth; if (i < 0) i += m_iTRange; /* if (((void*)m_oaAtomFrames[i]) < (void*)0xFFFF) { m_IF.printf("@ GetAtomFrame(%d): %d, %08X\n",depth,i,m_oaAtomFrames[i]); m_IF.printf("Pos %d, Count %d, VisCo %d.\n",m_iCubeFramePos,m_iCubeFrameCount,m_iCubeFrameVisibleCount); }*/ return m_oaAtomFrames[i]; } double CBQBExtrapolator::ExtrapolateKnown(int pattern, int index) const { double tf; unsigned int z; const CBQBExtraPattern &p = m_oaPatterns[pattern]; tf = 0; for (z=0;z= m_iRes012/*m_iRes[0]*m_iRes[1]*m_iRes[2]*/) m_IF.eprintf("CBQBExtrapolator::ExtrapolateKnown(): Pattern %d, Term %u/%lu: Fail2 %d + %d = %d\n", pattern,z,p.m_iaSpatialIndex.size(),index,p.m_iaSpatialIndex[z],ti); if ((p.m_iaSpatialIndex[z] >= 0) && (p.m_iaTemporalIndex[z] == 0)) m_IF.eprintf("CBQBExtrapolator::ExtrapolateKnown(): Pattern %d, Term %u/%lu: Fail3.\n", pattern,z,p.m_iaSpatialIndex.size()); #endif const CBQBCubeFrame *cfr = GetCubeFrame(p.m_iaTemporalIndex[z]); // tf += p.m_faCoeff[z] * cfr->m_faBin[index+p.m_iaSpatialIndex[z]]; // tf += p.m_faCoeff[z] * cfr->m_iaMantis[ti] * pow10(cfr->m_iaExpo[ti]); tf += p.m_faCoeff[z] * cfr->m_faBin[ti]; } return tf; } double CBQBExtrapolator::ExtrapolateKnownCorr(const std::vector &fa, int pattern, int index) const { double tf; unsigned int z; const CBQBExtraPattern &p = m_oaPatterns[pattern]; tf = 0; for (z=0;z= m_iRes012) m_IF.eprintf("CBQBExtrapolator::ExtrapolateKnownCorr(): Pattern %d, Term %u/%lu: Fail2 %d + %d = %d\n", pattern,z,p.m_iaSpatialIndex.size(),index,p.m_iaSpatialIndex[z],ti); if (p.m_iaSpatialIndex[z] >= 0) m_IF.eprintf("CBQBExtrapolator::ExtrapolateKnownCorr(): Pattern %d, Term %u/%lu: Fail3.\n", pattern,z,p.m_iaSpatialIndex.size()); #endif tf += p.m_faCoeff[z] * fa[ti]; } return tf; } void CBQBExtrapolator::Initialize( int resx, int resy, int resz, int srangex, int srangey, int srangez, int trange, int sorder, int torder, int offsetx, int offsety, int offsetz, bool crosss, bool crosst, bool wrap, bool crossranges, bool crossranget, double distexpo, double timeexpo, bool silent ) { int ix, iy, iz, it, rx, ry, rz, rt, dp, i, j2, morder; int jx, jy, jz, jt, kx, ky, kz, kt; int dx, dy, dz, dt; int maxdp, maxcoeff; double tf; CBQBDMatrixMN minp, mout; std::vector iax, iay, iaz, iat, iaind; std::set setx, sety, setz, sett; std::set::iterator setit; CBQBLinAlg la(m_IF); CBQBMath bqbmath(m_IF); if ((offsetx < 0) || (offsetx >= srangex)) { m_IF.eprintf("CBQBExtrapolator::Initialize(): Error: Invalid value for offsetx (found %d, allowed 0 .. %d).\n", offsetx,srangex-1); abort(); } if ((offsety < 0) || (offsety >= srangey)) { m_IF.eprintf("CBQBExtrapolator::Initialize(): Error: Invalid value for offsety (found %d, allowed 0 .. %d).\n", offsety,srangey-1); abort(); } if ((offsetz < 0) || (offsetz >= srangez)) { m_IF.eprintf("CBQBExtrapolator::Initialize(): Error: Invalid value for offsetz (found %d, allowed 0 .. %d).\n", offsetz,srangez-1); abort(); } m_fDistExpoAdd = 1.0; m_fTimeExpoAdd = 1.0; if (sorder < 0) { // Order -1 means no extrapolation, which is less than order 0 (constant extrapolation) sorder = 0; srangex = 1; srangey = 1; srangez = 1; } if (torder < 0) { torder = 0; trange = 1; } m_iSRange[0] = srangex; m_iSRange[1] = srangey; m_iSRange[2] = srangez; m_iTRange = trange; m_iSOffset[0] = offsetx; m_iSOffset[1] = offsety; m_iSOffset[2] = offsetz; m_iSOrder = sorder; m_iTOrder = torder; m_bCrossS = crosss; m_bCrossRangeS = crossranges; m_bWrap = wrap; m_bCrossT = crosst; m_bCrossRangeT = crossranget; m_fDistExpo = distexpo; m_fTimeExpo = timeexpo; m_iRes[0] = resx; m_iRes[1] = resy; m_iRes[2] = resz; m_iSRange01 = m_iSRange[0] * m_iSRange[1]; m_iSRange012 = m_iSRange[0] * m_iSRange[1] * m_iSRange[2]; m_iTempVal[0] = m_iRes[0] - m_iSRange[0] + m_iSOffset[0]; m_iTempVal[1] = m_iRes[1] - m_iSRange[1] + m_iSOffset[1]; m_iTempVal[2] = m_iRes[2] - m_iSRange[2] + m_iSOffset[2]; m_iRes012 = m_iRes[0] * m_iRes[1] * m_iRes[2]; m_iRes12 = m_iRes[1] * m_iRes[2]; maxdp = 0; maxcoeff = 0; m_oaCubeFrames.resize(m_iTRange); m_oaAtomFrames.resize(m_iTRange); m_iCubeFramePos = 0; m_iCubeFrameCount = 0; m_iCubeFrameVisibleCount = 0; for (ix=0;ix m_iSOffset[0]) { if (jx >= m_iSRange[0]-ix) continue; } else if (ix <= m_iSOffset[0]) { if (jx < -m_iSOffset[0]+ix) continue; } } if ((ix <= m_iSOffset[0]) && (jx < -m_iSOffset[0]+ix) && wrap) kx = jx+resx; else if ((ix > m_iSOffset[0]) && (jx > m_iSRange[0]-1-ix) && wrap) kx = jx-resx; else kx = jx; for (jy=-m_iSOffset[1];jy m_iSOffset[1]) { if (jy >= m_iSRange[1]-iy) continue; } else if (iy <= m_iSOffset[1]) { if (jy < -m_iSOffset[1]+iy) continue; } } if ((iy <= m_iSOffset[1]) && (jy < -m_iSOffset[1]+iy) && wrap) ky = jy+resy; else if ((iy > m_iSOffset[1]) && (jy > m_iSRange[1]-1-iy) && wrap) ky = jy-resy; else ky = jy; for (jz=-m_iSOffset[2];jz m_iSOffset[2]) { if (jz >= m_iSRange[2]-iz) continue; } else if (iz <= m_iSOffset[2]) { if (jz < -m_iSOffset[2]+iz) continue; } } if ((iz <= m_iSOffset[2]) && (jz < -m_iSOffset[2]+iz) && wrap) kz = jz+resz; else if ((iz > m_iSOffset[2]) && (jz > m_iSRange[2]-1-iz) && wrap) kz = jz-resz; else kz = jz; if (!crossranges && (((jx != 0) && (jy != 0)) || ((jx != 0) && (jz != 0)) || ((jy != 0) && (jz != 0)))) continue; if (!crossranget && (jt != 0) && ((jx != 0) || (jy != 0) || (jz != 0))) continue; if ((jt == 0) && ((long)kx*resy*resz+(long)ky*resz+(long)kz >= 0)) continue; if (m_IF.IsPL(BQB_PL_VERBOSE)) { m_IF.printf("%3d: ( ",dp+1); m_IF.printf("%2d",jt); m_IF.printf(" | "); m_IF.printf("%2d:%4d",jx,kx); m_IF.printf(" | "); m_IF.printf("%2d:%4d",jy,ky); m_IF.printf(" | "); m_IF.printf("%2d:%4d",jz,kz); m_IF.printf(" ) "); m_IF.printf("DIdx %10ld",(long)kx*resy*resz+(long)ky*resz+(long)kz); m_IF.printf("\n"); } iax.push_back(jx); iay.push_back(jy); iaz.push_back(jz); iat.push_back(jt); setx.insert(jx); sety.insert(jy); setz.insert(jz); sett.insert(jt); iaind.push_back((long)kx*resy*resz+(long)ky*resz+(long)kz); dp++; } } } } if (dp == 0) { if (m_IF.IsPL(BQB_PL_VERBOSE)) m_IF.printf(" Skipping.\n"); continue; } rx = (int)setx.size(); ry = (int)sety.size(); rz = (int)setz.size(); rt = (int)sett.size(); if (m_IF.IsPL(BQB_PL_VERBOSE)) { m_IF.printf(" %lu different X values:",setx.size()); for (setit=setx.begin();setit!=setx.end();++setit) m_IF.printf(" %d",*setit); m_IF.printf("\n"); m_IF.printf(" %lu different Y values:",sety.size()); for (setit=sety.begin();setit!=sety.end();++setit) m_IF.printf(" %d",*setit); m_IF.printf("\n"); m_IF.printf(" %lu different Z values:",setz.size()); for (setit=setz.begin();setit!=setz.end();++setit) m_IF.printf(" %d",*setit); m_IF.printf("\n"); m_IF.printf(" %lu different T values:",sett.size()); for (setit=sett.begin();setit!=sett.end();++setit) m_IF.printf(" %d",*setit); m_IF.printf("\n"); } morder = MIN(sorder,MAX3(rx-1,ry-1,rz-1)); _norder: if (rx-1 < morder) dx = rx-1; else dx = morder; if (ry-1 < morder) dy = ry-1; else dy = morder; if (rz-1 < morder) dz = rz-1; else dz = morder; if (rt-1 < torder) dt = rt-1; else dt = torder; if (m_IF.IsPL(BQB_PL_VERBOSE)) m_IF.printf(" Using MaxOrder=%d, degree X=%d, Y=%d, Z=%d, T=%d\n",morder,dx,dy,dz,dt); i = 0; for (jx=0;jx<=dx;jx++) { for (jy=0;jy<=dy;jy++) { if (jx+jy > morder) break; for (jz=0;jz<=dz;jz++) { if (jx+jy+jz > morder) break; if (!crosss && (((jx != 0) && (jy != 0)) || ((jx != 0) && (jz != 0)) || ((jy != 0) && (jz != 0)))) continue; for (jt=0;jt<=dt;jt++) { if (!crosst && (jt != 0) && ((jx != 0) || (jy != 0) || (jz != 0))) break; i++; } } } } if (i > dp) { morder--; goto _norder; } if (m_IF.IsPL(BQB_PL_VERBOSE)) { m_IF.printf(" These are %d coefficients.\n",i); m_IF.printf(" Constructing %dx%d matrix...\n",dp,i); } if (i > maxcoeff) maxcoeff = i; minp = CBQBDMatrixMN(dp,i); if (m_IF.IsPL(BQB_PL_VERBOSE)) m_IF.printf(" "); i = 0; for (jt=0;jt<=dt;jt++) { for (jx=0;jx<=dx;jx++) { for (jy=0;jy<=dy;jy++) { if (jx+jy > morder) break; for (jz=0;jz<=dz;jz++) { if (jx+jy+jz > morder) break; if (!crosss && (((jx != 0) && (jy != 0)) || ((jx != 0) && (jz != 0)) || ((jy != 0) && (jz != 0)))) continue; if (!crosst && (jt != 0) && ((jx != 0) || (jy != 0) || (jz != 0))) break; if (m_IF.IsPL(BQB_PL_VERBOSE)) { if ((jx==0) && (jy==0) && (jz==0) && (jt==0)) m_IF.printf(" 1"); if (jx > 1) m_IF.printf(" x^%d",jx); else if (jx == 1) m_IF.printf(" x"); if (jy > 1) m_IF.printf(" y^%d",jy); else if (jy == 1) m_IF.printf(" y"); if (jz > 1) m_IF.printf(" z^%d",jz); else if (jz == 1) m_IF.printf(" z"); if (jt > 1) m_IF.printf(" t^%d",jt); else if (jt == 1) m_IF.printf(" t"); } for (kt=0;kt 1.0E-13) j2++; if (m_IF.IsPL(BQB_PL_VERBOSE)) m_IF.printf(" Have %d zero coefficients, %d data points remain.\n",dp-j2,j2); if (j2 > maxdp) maxdp = j2; m_oaPatterns.back().m_iaSpatialIndex.resize(j2); m_oaPatterns.back().m_iaTemporalIndex.resize(j2); m_oaPatterns.back().m_faCoeff.resize(j2); if (m_IF.IsPL(BQB_PL_VERBOSE)) { m_IF.printf(" Matrix:\n"); m_IF.printf(" "); } i = 0; for (kt=0;kt= m_iTRange) m_iCubeFramePos -= m_iTRange; m_oaCubeFrames[m_iCubeFramePos] = frame; } void CBQBExtrapolator::PushAtomFrame(const CBQBAtomSet *frame) { //m_IF.printf("PushAtomFrame before: count %d, visco %d, pos %d\n",m_iCubeFrameCount,m_iCubeFrameVisibleCount,m_iCubeFramePos); if (m_iCubeFrameCount < m_iTRange) m_iCubeFrameCount++; m_iCubeFrameVisibleCount = m_iCubeFrameCount; m_iCubeFramePos++; if (m_iCubeFramePos >= m_iTRange) m_iCubeFramePos -= m_iTRange; m_oaAtomFrames[m_iCubeFramePos] = frame; //m_IF.printf("PushAtomFrame after: count %d, visco %d, pos %d\n",m_iCubeFrameCount,m_iCubeFrameVisibleCount,m_iCubeFramePos); } /* #include "df.h" // Momentan beste Settings: // travis compress cube -check no -cextra -cextrange 4 -cextorder 3 -cexsrange 5 -cexoffset 2 -cexsorder 1 // -cexscross -cexdistexpo 2.5 -cexscrossrange -cexpredcorr -cexcorrfac 0.97 -cexwrap /home/brehm/cubefill/first10.cube new.bqb void TestExtrapolator() { CBQBExtrapolator extra, extra2; CBQBCubeFrame cfr; int ix, iy, iz; double tf, tf2; FILE *a; CDF dfabs, dfrel; extra.Initialize( 160, // resx, 160, // resy, 160, // resz, 3, // srangex, 3, // srangey, 3, // srangez, 5, // trange, 1, // sorder, 4, // torder, 1, // offsetx, 1, // offsety, 1, // offsetz, false, // crosss, false, // crosst, false, // wrap, false, // crossranges, true, // crossranget 0.0, // distexpo 0.0, // timeexpo 1.0, // corrfactor true, // verbose false ); return; extra.Initialize( 160, // resx, 160, // resy, 160, // resz, 5, // srangex, 5, // srangey, 5, // srangez, 1, // trange, 2, // sorder, 0, // torder, 2, // offsetx, 2, // offsety, 2, // offsetz, true, // crosss, false, // crosst, true, // wrap, true, // crossranges, false, // crossranget 6.0, // distexpo 0.0, // timeexpo 1.0, // corrfactor true, // verbose false ); a = fopen("first10.cube","rt"); if (!cfr.ReadFrame(a,12,5,6,true)) { m_IF.printf("Error reading cube frame.\n"); return; } fclose(a); extra.PushCubeFrame(&cfr); dfabs.m_iResolution = 100; dfabs.m_fMinVal = 0; dfabs.m_fMaxVal = 1.0; dfabs.Create(); dfabs.SetLabelX("Absolute Deviation"); dfabs.SetLabelY("Occurrence"); dfrel.m_iResolution = 100; dfrel.m_fMinVal = 1.0; dfrel.m_fMaxVal = 2.0; dfrel.Create(); dfrel.SetLabelX("Relative Deviation"); dfrel.SetLabelY("Occurrence"); m_IF.printf("Extrapolating:"); std::vector tda; tda.resize(160*160*160); for (ix=0;ix<160;ix++) { if ((ix%2) == 0) m_IF.printf("."); for (iy=0;iy<160;iy++) { for (iz=0;iz<160;iz++) { // m_IF.printf("%d|%d|%d --> %d/%lu\n",ix,iy,iz,extra.FindPattern(0,ix,iy,iz),extra.m_oaPatterns.size()); tf = extra.Extrapolate(ix,iy,iz); tf2 = cfr.m_faBin[ix*160*160+iy*160+iz]; dfabs.AddToBin(fabs(tf - tf2)); if (tf != 0) { if (tf > tf2) dfrel.AddToBin(tf/tf2); else dfrel.AddToBin(tf2/tf); } } } } m_IF.printf("Done.\n"); dfabs.NormBinIntegral(1000.0); dfabs.Write("","absf.csv","",false); dfrel.NormBinIntegral(1000.0); dfrel.Write("","relf.csv","",false); } */ travis-src-190101/src/bqb_extrapolator.h0100777000000000000000000001560013412725656015167 0ustar00/*********************************************************************************** LibBQB - File Format and Compression Algorithms for Trajectories of Volumetric Data and Atom Positions https://brehm-research.de/bqb Free software, licensed under GNU LGPL v3 Copyright (c) Martin Brehm and Martin Thomas, Martin Luther University Halle-Wittenberg, Germany, 2016 - 2019. Please cite: M. Brehm, M. Thomas: "An Efficient Lossless Compression Algorithm for Trajectories of Atom Positions and Volumetric Data", J. Chem. Inf. Model. 2018, 58 (10), pp 2092-2107. -------------------------------------------------------------------------------- LibBQB is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program. If not, see . ***********************************************************************************/ #ifndef BQB_EXTRAPOLATOR_H #define BQB_EXTRAPOLATOR_H // This must always be the first include directive #include "bqb_config.h" #include "bqb_cubeframe.h" #include "bqb_bitset.h" #include #include "bqb_parmset.h" class CBQBInterface; //#define CHECK_EXTRAPOLATOR void TestExtrapolator(); class CBQBExtraPattern { public: std::vector m_iaSpatialIndex; std::vector m_iaTemporalIndex; std::vector m_faCoeff; }; class CBQBExtrapolator { public: CBQBExtrapolator(CBQBInterface &i) : m_IF(i) { } ~CBQBExtrapolator() { } void Reset(); void Initialize( int resx, int resy, int resz, int srangex, int srangey, int srangez, int trange, int sorder, int torder, int offsetx, int offsety, int offsetz, bool crosss, bool crosst, bool wrap, bool crossranges, bool crossranget, double distexpo, double timeexpo, bool silent ); void PushCubeFrame(const CBQBCubeFrame *frame); void PushAtomFrame(const CBQBAtomSet *frame); void InitializeXYZ(int trange, int torder, double timeexpo, bool silent) { Initialize( 0, 0, 0, 1, 1, 1, trange, 0, torder, 0, 0, 0, false, false, false, false, false, 0.0, timeexpo, //verbose, silent ); } void InitializeXYZ(CBQBParameterSet_Position *p, bool silent); const CBQBCubeFrame* GetCubeFrame(int depth) const; const CBQBAtomSet* GetAtomFrame(int depth) const; double Extrapolate(int x, int y, int z) const { return ExtrapolateKnown( FindPattern(m_iTRange-m_iCubeFrameVisibleCount,x,y,z), x*m_iRes12 + y*m_iRes[2] + z ); } double Extrapolate(int x, int y, int z, int index) const { return ExtrapolateKnown( FindPattern(m_iTRange-m_iCubeFrameVisibleCount,x,y,z), index ); } double ExtrapolatePred(int index) const { return ExtrapolateKnownPred( m_iTRange-m_iCubeFrameVisibleCount, index ); } double ExtrapolateCorr(const std::vector &fa, int x, int y, int z, int index) const { return ExtrapolateKnownCorr( fa, FindPatternCorr(x,y,z), index ); } double ExtrapolateXYZ(int index, int index2) const { return ExtrapolateKnownXYZ( m_iTRange-m_iCubeFrameVisibleCount, index, index2 ); } double ExtrapolateKnown(int pattern, int index) const; double ExtrapolateKnownCorr(const std::vector &fa, int pattern, int index) const; double ExtrapolateKnownPred(int pattern, int index) const { double tf; unsigned int z; const CBQBExtraPattern &p = m_oaPatterns[pattern]; tf = 0; for (z=0;zm_faBin[index]; return tf; } double ExtrapolateKnownXYZ(int pattern, int index, int index2) const { double tf; unsigned int z; const CBQBExtraPattern &p = m_oaPatterns[pattern]; tf = 0; for (z=0;zm_oaAtoms.size()) tf += p.m_faCoeff[z] * afr->m_oaAtoms[index]->m_fRelCoord[index2]; else tf += p.m_faCoeff[z] * afr->m_faCOM[index2]; } return tf; } int FindPattern(int t, int x, int y, int z) const { int ix, iy, iz; if (x < m_iSOffset[0]) ix = m_iSOffset[0] - x; else if (x > m_iTempVal[0]/*m_iRes[0]-m_iSRange[0]+m_iSOffset[0]*/) ix = m_iSOffset[0] + x - m_iTempVal[0]/*m_iRes[0]+m_iSRange[0]-m_iSOffset[0]*/; else ix = 0; if (y < m_iSOffset[1]) iy = m_iSOffset[1] - y; else if (y > m_iTempVal[1]/*m_iRes[1]-m_iSRange[1]+m_iSOffset[1]*/) iy = m_iSOffset[1] + y - m_iTempVal[1]/*m_iRes[1]+m_iSRange[1]-m_iSOffset[1]*/; else iy = 0; if (z < m_iSOffset[2]) iz = m_iSOffset[2] - z; else if (z > m_iTempVal[2]/*m_iRes[2]-m_iSRange[2]+m_iSOffset[2]*/) iz = m_iSOffset[2] + z - m_iTempVal[2]/*m_iRes[2]+m_iSRange[2]-m_iSOffset[2]*/; else iz = 0; return t * m_iSRange012/*m_iSRange[0]*m_iSRange[1]*m_iSRange[2]*/ + iz * m_iSRange01/*m_iSRange[0]*m_iSRange[1]*/ + iy * m_iSRange[0] + ix; } int FindPatternCorr(int x, int y, int z) const { int ix, iy, iz; if (x < m_iSOffset[0]) ix = m_iSOffset[0] - x; else if (x > m_iTempVal[0]/*m_iRes[0]-m_iSRange[0]+m_iSOffset[0]*/) ix = m_iSOffset[0] + x - m_iTempVal[0]/*m_iRes[0]+m_iSRange[0]-m_iSOffset[0]*/; else ix = 0; if (y < m_iSOffset[1]) iy = m_iSOffset[1] - y; else if (y > m_iTempVal[1]/*m_iRes[1]-m_iSRange[1]+m_iSOffset[1]*/) iy = m_iSOffset[1] + y - m_iTempVal[1]/*m_iRes[1]+m_iSRange[1]-m_iSOffset[1]*/; else iy = 0; if (z < m_iSOffset[2]) iz = m_iSOffset[2] - z; else if (z > m_iTempVal[2]/*m_iRes[2]-m_iSRange[2]+m_iSOffset[2]*/) iz = m_iSOffset[2] + z - m_iTempVal[2]/*m_iRes[2]+m_iSRange[2]-m_iSOffset[2]*/; else iz = 0; return iz * m_iSRange01/*m_iSRange[0]*m_iSRange[1]*/ + iy * m_iSRange[0] + ix; } int m_iRes[3]; int m_iSOffset[3]; int m_iTempVal[3]; int m_iSRange[3]; int m_iSOrder; int m_iTRange; int m_iTOrder; bool m_bCrossS; bool m_bCrossRangeS; bool m_bWrap; bool m_bCrossT; bool m_bCrossRangeT; double m_fDistExpo; double m_fTimeExpo; double m_fDistExpoAdd; double m_fTimeExpoAdd; int m_iCubeFramePos; int m_iCubeFrameCount; int m_iCubeFrameVisibleCount; private: int m_iSRange01; int m_iSRange012; int m_iRes012; int m_iRes12; std::vector m_oaCubeFrames; std::vector m_oaAtomFrames; std::vector m_oaPatterns; CBQBInterface &m_IF; }; #endif travis-src-190101/src/bqb_fastatof.h0100777000000000000000000000735513412725660014255 0ustar00/*********************************************************************************** LibBQB - File Format and Compression Algorithms for Trajectories of Volumetric Data and Atom Positions https://brehm-research.de/bqb Free software, licensed under GNU LGPL v3 Copyright (c) Martin Brehm and Martin Thomas, Martin Luther University Halle-Wittenberg, Germany, 2016 - 2019. Please cite: M. Brehm, M. Thomas: "An Efficient Lossless Compression Algorithm for Trajectories of Atom Positions and Volumetric Data", J. Chem. Inf. Model. 2018, 58 (10), pp 2092-2107. -------------------------------------------------------------------------------- LibBQB is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program. If not, see . ***********************************************************************************/ #ifndef BQB_FASTATOF_H #define BQB_FASTATOF_H // This must always be the first include directive #include "bqb_config.h" // // Simple and fast atof (ascii to float) function. // // - Executes about 5x faster than standard MSCRT library atof(). // - An attractive alternative if the number of calls is in the millions. // - Assumes input is a proper integer, fraction, or scientific format. // - Matches library atof() to 15 digits (except at extreme exponents). // - Follows atof() precedent of essentially no error checking. // // 09-May-2009 Tom Van Baak (tvb) www.LeapSecond.com // #define white_space(c) ((c) == ' ' || (c) == '\t') #define valid_digit(c) ((c) >= '0' && (c) <= '9') inline double bqb_fast_atof (const char *p) { int frac; double sign, value, scale; // Skip leading white space, if any. while (white_space(*p) ) { p += 1; } // Get sign, if any. sign = 1.0; if (*p == '-') { sign = -1.0; p += 1; } else if (*p == '+') { p += 1; } // Get digits before decimal point or exponent, if any. for (value = 0.0; valid_digit(*p); p += 1) { value = value * 10.0 + (*p - '0'); } // Get digits after decimal point, if any. if (*p == '.') { double pow10 = 10.0; p += 1; while (valid_digit(*p)) { value += (*p - '0') / pow10; pow10 *= 10.0; p += 1; } } // Handle exponent, if any. frac = 0; scale = 1.0; if ((*p == 'e') || (*p == 'E')) { unsigned int expon; // Get sign of exponent, if any. p += 1; if (*p == '-') { frac = 1; p += 1; } else if (*p == '+') { p += 1; } // Get digits of exponent, if any. for (expon = 0; valid_digit(*p); p += 1) { expon = expon * 10 + (*p - '0'); } if (expon > 308) expon = 308; // Calculate scaling factor. while (expon >= 50) { scale *= 1E50; expon -= 50; } while (expon >= 8) { scale *= 1E8; expon -= 8; } while (expon > 0) { scale *= 10.0; expon -= 1; } } // Return signed and scaled floating point result. return sign * (frac ? (value / scale) : (value * scale)); } #endif travis-src-190101/src/bqb_format.cpp0100777000000000000000000015553513412725621014272 0ustar00/*********************************************************************************** LibBQB - File Format and Compression Algorithms for Trajectories of Volumetric Data and Atom Positions https://brehm-research.de/bqb Free software, licensed under GNU LGPL v3 Copyright (c) Martin Brehm and Martin Thomas, Martin Luther University Halle-Wittenberg, Germany, 2016 - 2019. Please cite: M. Brehm, M. Thomas: "An Efficient Lossless Compression Algorithm for Trajectories of Atom Positions and Volumetric Data", J. Chem. Inf. Model. 2018, 58 (10), pp 2092-2107. -------------------------------------------------------------------------------- LibBQB is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program. If not, see . ***********************************************************************************/ // This must always be the first include directive #include "bqb_config.h" #include "bqb_format.h" #include "bqb_crc.h" #include "bqb_integerengine.h" #include "bqb_engine.h" #ifdef _WIN32 #include #endif const char *GetRevisionInfo_bqb_format(unsigned int len) { static char buf[256]; GET_REVISION_INFO( buf, len ); return buf; } const char *GetSourceVersion_bqb_format() { static char buf[256]; GET_SOURCE_VERSION( buf ); return buf; } CBQBListEntry::~CBQBListEntry() { if (m_pIndex != NULL) { delete m_pIndex; m_pIndex = NULL; } if (m_pFile != NULL) { delete m_pFile; m_pFile = NULL; } } CBQBFile::~CBQBFile() { int z; for (z=0;z<(int)m_oaBQBList.size();z++) delete m_oaBQBList[z]; if (m_pShortFrame != NULL) { if (!m_bListFile) // Otherwise it is deleted elsewhere delete m_pShortFrame; m_pShortFrame = NULL; } if (m_pIndex != NULL) { delete m_pIndex; m_pIndex = NULL; } if (m_pEngine != NULL) { delete m_pEngine; m_pEngine = NULL; } } bool WriteArrayToFile(FILE *a, const std::vector &ia) { unsigned int i; i = 0; while (i < ia.size()) i += (unsigned int)fwrite(&ia[i],1,(i+4096<=ia.size())?4096:(ia.size()-i),a); return true; } bool ReadArrayFromFile(FILE *a, std::vector &ia, int length) { unsigned int i, k; int z; static unsigned char buf[4096]; i = (unsigned int)ia.size(); ia.resize(ia.size()+length); while (i < ia.size()) { k = (unsigned int)fread(buf,1,(i+4096<=ia.size())?4096:(ia.size()-i),a); for (z=0;z<(int)k;z++) ia[i+z] = buf[z]; i += k; if (feof(a)) return false; } return true; } void ReadArrayFromFile(FILE *a, std::vector &ia) { unsigned int k; int z; static unsigned char buf[4096]; while (!feof(a)) { k = (unsigned int)fread(buf,1,4096,a); for (z=0;z<(int)k;z++) ia.push_back(buf[z]); } } bool CBQBIndex::ImportFromArray(bool compressed, const std::vector &ia, int ver) { CBQBIntegerEngine ie(m_IF); CBQBBitSet bs(m_IF); std::vector diff; int z; if (m_IF.IsPL(BQB_PL_VERBOSE)) m_IF.printf(">>> CBQBIndex::ImportFromArray >>>\n"); if (compressed) { if (m_IF.IsPL(BQB_PL_VERBOSE)) m_IF.printf(" Importing compressed index frame...\n"); m_iaFrameTypes.clear(); m_iaFrameLengths.clear(); bs.m_iaData.assign( ia.begin(), ia.end() ); ie.DecompressSingle( &bs, m_iaFrameTypes, NULL ); if (m_IF.IsPL(BQB_PL_VERBOSE)) m_IF.printf(" Decompressed %lu frame types.\n",m_iaFrameTypes.size()); // for (z=0;z<(int)m_iaFrameTypes.size();z++) // m_IF.printf("@@@ %d\n",m_iaFrameTypes[z]); ie.DecompressSingle( &bs, m_iaFrameLengths, NULL ); if (m_IF.IsPL(BQB_PL_VERBOSE)) m_IF.printf(" Decompressed %lu frame lengths.\n",m_iaFrameLengths.size()); if (ver >= 1) { ie.DecompressSingle( &bs, diff, NULL ); // Reconstruct values from differences m_iaFrameIDs.resize(diff.size()); m_iaFrameIDs[0] = diff[0]; for (z=1;z<(int)diff.size();z++) m_iaFrameIDs[z] = m_iaFrameIDs[z-1] + diff[z]; if (m_IF.IsPL(BQB_PL_VERBOSE)) m_IF.printf(" Decompressed %lu frame IDs.\n",m_iaFrameIDs.size()); } else { m_iaFrameIDs.resize(m_iaFrameLengths.size()); for (z=0;z<(int)m_iaFrameIDs.size();z++) m_iaFrameIDs[z] = 0; } for (z=0;z<(int)m_iaFrameTypes.size();z++) if ((m_iaFrameTypes[z] == 2) || (m_iaFrameTypes[z] == 3)) m_IF.eprintf("CBQBIndex::ImportFromArray(): Warning: Index frame is on the index (%d/%lu).\n",z+1,m_iaFrameTypes.size()); } else { m_IF.eprintf("CBQBIndex::ImportFromArray(): Uncompressed index not yet implemented.\n"); abort(); } if (m_IF.IsPL(BQB_PL_VERBOSE)) m_IF.printf("<<< CBQBIndex::ImportFromArray <<<\n\n"); return true; } bool CBQBIndex::ExportToArray(bool compressed, std::vector &ia, CBQBStatistics *stat) { CBQBIntegerEngine ie(m_IF); CBQBBitSet bs(m_IF); std::vector diff; int i, z; if (m_IF.IsPL(BQB_PL_VERBOSE)) m_IF.printf(">>> CBQBIndex::ExportToArray >>>\n"); if (stat != NULL) stat->PushStatistics(); if (compressed) { // for (i=0;i<(int)m_iaFrameTypes.size();i++) // m_IF.printf("@@@ %d\n",m_iaFrameTypes[i]); ie.CompressSingle( m_iaFrameTypes, &bs, false, true, true, 50, 1, false, false, 10, stat ); i = bs.GetByteLength(); if (m_IF.IsPL(BQB_PL_VERBOSE)) m_IF.printf(" Compressed %lu frame types to %d bytes.\n",m_iaFrameTypes.size(),i); ie.CompressSingle( m_iaFrameLengths, &bs, false, false, true, 50, 1, false, false, 10, stat ); if (m_IF.IsPL(BQB_PL_VERBOSE)) m_IF.printf(" Compressed %lu frame lengths to %d bytes.\n",m_iaFrameLengths.size(),bs.GetByteLength()-i); i = bs.GetByteLength(); // Store differences instead of values diff.resize(m_iaFrameIDs.size()); diff[0] = m_iaFrameIDs[0]; for (z=1;z<(int)m_iaFrameIDs.size();z++) diff[z] = m_iaFrameIDs[z] - m_iaFrameIDs[z-1]; ie.CompressSingle( diff, &bs, false, true, true, 50, 1, false, false, 10, stat ); if (m_IF.IsPL(BQB_PL_VERBOSE)) m_IF.printf(" Compressed %lu frame IDs to %d bytes.\n",m_iaFrameIDs.size(),bs.GetByteLength()-i); ia.insert(ia.end(),bs.m_iaData.begin(),bs.m_iaData.end()); } else { m_IF.eprintf("CBQBIndex::ExportToArray(): Uncompressed index not yet implemented.\n"); abort(); } if (stat != NULL) stat->PopStatistics(); if (m_IF.IsPL(BQB_PL_VERBOSE)) m_IF.printf("<<< CBQBIndex::ExportToArray <<<\n\n"); return true; } void CBQBIndex::Dump() { int z; unsigned long u; m_IF.printf("\n"); m_IF.printf(" Offset Length Type Ver ID\n"); m_IF.printf("---------------------------------------------------\n"); u = 0; for (z=0;z<(int)m_iaFrameTypes.size();z++) { m_IF.printf("%10lu %8d %3d %3d %10d\n", u, m_iaFrameLengths[z], m_iaFrameTypes[z]>>3, m_iaFrameTypes[z]%7, m_iaFrameIDs[z] ); u += m_iaFrameLengths[z]; } m_IF.printf("\n"); } bool CBQBFile::OpenRead(std::string s) { long ip; unsigned char uc[5]; CBQBTools bqbtools(m_IF); CBQBBitSet bs(m_IF); unsigned long fohi, folo, rohi, rolo; std::vector tuca; std::string::size_type sp1, sp2; if (m_IF.IsPL(BQB_PL_VERBOSE)) m_IF.printf(">>> CBQBFile::OpenRead >>>\n"); if (m_bOpenRead || m_bOpenWrite) { m_IF.eprintf("CBQBFile::OpenRead(): Error: A file is already open.\n"); return false; } m_pFile = fopen(s.c_str(),"rb"); if (m_pFile == NULL) { m_IF.eprintf("CBQBFile::OpenRead(): Error: Could not open \"%s\" for reading.\n",s.c_str()); return false; } m_sFileName = s; m_bOpenRead = true; m_bEOF = false; m_iFrameCounter = 0; // Extract directory part sp1 = m_sFileName.rfind('\\'); sp2 = m_sFileName.rfind('/'); if ((sp1 != std::string::npos) || (sp2 != std::string::npos)) { if (sp2 == std::string::npos) m_sDirectory = m_sFileName.substr(0,sp1+1); else if (sp1 == std::string::npos) m_sDirectory = m_sFileName.substr(0,sp2+1); else if (sp1 > sp2) m_sDirectory = m_sFileName.substr(0,sp1+1); else m_sDirectory = m_sFileName.substr(0,sp2+1); if (m_IF.IsPL(BQB_PL_VERBOSE)) m_IF.printf(" Directory is \"%s\".\n",m_sDirectory.c_str()); } else m_sDirectory = ""; memset(uc,0,5); (void)fread(uc,5,1,m_pFile); if (memcmp(uc,"BQ",2) == 0) { if (m_IF.IsPL(BQB_PL_VERBOSE)) m_IF.printf(" File header is \"BQ\" --> Single File.\n"); m_bListFile = false; } else if (memcmp(uc,"BLIST",5) == 0) { if (m_IF.IsPL(BQB_PL_VERBOSE)) m_IF.printf(" File header is \"BLIST\" --> List File.\n"); m_bListFile = true; if (!OpenListFile(m_pFile)) { m_IF.eprintf("CBQBFile::OpenRead(): Error: Failed to open list file.\n"); return false; } goto _end; } else { m_IF.eprintf("CBQBFile::OpenRead(): Error: File does not start with \"BQ\" or \"BLIST\".\n"); return false; } if (m_pEngine == NULL) { m_pEngine = m_IF.CreateEngine(0); m_pEngine->PrepareDecompressCube(); } else m_pEngine->Reset(); ip = bqbtools.FindIndexPosition(m_pFile); if (ip != 0) { m_pIndex = new CBQBIndex(m_IF); if (m_IF.IsPL(BQB_PL_VERBOSE)) m_IF.printf(" Found index frame at offset %ld, reading...\n",ip); fseek(m_pFile,ip,SEEK_SET); GetFileOffset(fohi,folo); if (!ReadFrame()) { m_IF.eprintf("CBQBFile::OpenRead(): Error: Could not read index frame.\n"); return false; } if (m_pShortFrame->m_iFrameType == BQB_FRAMETYPE_COMPIDX) { if (m_pShortFrame->m_iFrameTypeVersion > 1) { m_IF.eprintf("CBQBFile::OpenRead(): Error: Unexpected frame version %d of compressed index frame.\n", m_pShortFrame->m_iFrameTypeVersion); return false; } if (m_pShortFrame->m_iFrameTypeVersion >= 1) { bs.m_iaData.assign( m_pShortFrame->m_iaPayload.begin(), m_pShortFrame->m_iaPayload.begin()+8 ); bs.m_iExcessBits = 0; bs.m_iReadPosBytes = 0; bs.m_iReadPosExcess = 0; rohi = bs.ReadBitsInteger(32); rolo = bs.ReadBitsInteger(32); if ((rohi != fohi) || (rolo != folo)) { m_IF.eprintf("CBQBFile::OpenRead(): Warning: Index frame found at wrong offset; ignoring (found at %02lX:%08lX, expected at %02lX:%08lX).\n", fohi, folo, rohi, rolo ); delete m_pIndex; m_pIndex = NULL; goto _noindex; } tuca.assign( m_pShortFrame->m_iaPayload.begin()+8, m_pShortFrame->m_iaPayload.end() ); } else tuca.assign( m_pShortFrame->m_iaPayload.begin(), m_pShortFrame->m_iaPayload.end() ); m_pIndex->ImportFromArray( true, tuca, m_pShortFrame->m_iFrameTypeVersion ); } else if (m_pShortFrame->m_iFrameType == BQB_FRAMETYPE_IDX) { if (m_pShortFrame->m_iFrameTypeVersion > 1) { m_IF.eprintf("CBQBFile::OpenRead(): Error: Unexpected frame version %d of uncompressed index frame.\n", m_pShortFrame->m_iFrameTypeVersion); return false; } m_pIndex->ImportFromArray( false, m_pShortFrame->m_iaPayload, m_pShortFrame->m_iFrameTypeVersion ); } else { m_IF.eprintf("CBQBFile::OpenRead(): Error: Unexpected frame type %d of index frame.\n", m_pShortFrame->m_iFrameType); return false; } m_iTotalFrameCount = (int)m_pIndex->m_iaFrameLengths.size(); if (m_IF.IsPL(BQB_PL_VERBOSE)) m_IF.printf(" Positioning file pointer to start of file.\n"); } else if (m_IF.IsPL(BQB_PL_VERBOSE)) m_IF.printf(" Found no index frame.\n"); _noindex: fseek(m_pFile,0,SEEK_SET); if (m_pShortFrame != NULL) { delete m_pShortFrame; m_pShortFrame = NULL; } _end: if (m_IF.IsPL(BQB_PL_VERBOSE)) m_IF.printf("<<< CBQBFile::OpenRead <<<\n\n"); return true; } bool CBQBFile::ReadFrame() { unsigned char uc; unsigned char uci[2]; unsigned int id, len, crc; int ty, ve; CBQBCRC32 ecrc; if (m_IF.IsPL(BQB_PL_VERBOSE)) m_IF.printf(">>> CBQBFile::ReadFrame >>>\n"); if (!m_bOpenRead) { m_IF.eprintf("CBQBFile::ReadFrame(): Error: File not open for reading.\n"); abort(); } if (m_bListFile) { if (m_oaBQBList.size() == 0) { if (m_IF.IsPL(BQB_PL_VERBOSE)) m_IF.printf(" LIST: Error: No entrys in list.\n"); m_bEOF = true; return false; } if (m_iListIndex == -1) { if (m_IF.IsPL(BQB_PL_VERBOSE)) m_IF.printf(" LIST: Opening first entry from list...\n"); m_iListIndex = 0; if (!m_oaBQBList[m_iListIndex]->m_pFile->OpenRead(m_oaBQBList[m_iListIndex]->m_sFileName)) { if (m_IF.IsPL(BQB_PL_VERBOSE)) m_IF.printf(" LIST: Failed.\n"); return false; } if (m_oaBQBList[m_iListIndex]->m_iFrameStart > 0) { if (m_IF.IsPL(BQB_PL_VERBOSE)) m_IF.printf(" LIST: Skipping first %d entries...\n",m_oaBQBList[m_iListIndex]->m_iFrameStart); if (!m_oaBQBList[m_iListIndex]->m_pFile->SeekFrame(m_oaBQBList[m_iListIndex]->m_iFrameStart)) return false; } } _again: if (m_IF.IsPL(BQB_PL_VERBOSE)) m_IF.printf(" LIST: Reading frame from list entry %d...\n",m_iListIndex+1); if (!m_oaBQBList[m_iListIndex]->m_pFile->ReadFrame()) { if (m_IF.IsPL(BQB_PL_VERBOSE)) m_IF.printf(" LIST: Could not read further frame from list entry %d. Closing entry.\n",m_iListIndex+1); if (!m_oaBQBList[m_iListIndex]->m_pFile->Close()) { if (m_IF.IsPL(BQB_PL_VERBOSE)) m_IF.printf(" LIST: Failed to close entry.\n"); return false; } if (m_iListIndex+1 == (int)m_oaBQBList.size()) { if (m_IF.IsPL(BQB_PL_VERBOSE)) m_IF.printf(" LIST: No more list entries; leaving.\n"); m_bEOF = true; m_iListIndex = -1; return false; } m_iListIndex++; if (!m_oaBQBList[m_iListIndex]->m_pFile->OpenRead(m_oaBQBList[m_iListIndex]->m_sFileName)) { if (m_IF.IsPL(BQB_PL_VERBOSE)) m_IF.printf(" LIST: Error: Could not open list entry %d; leaving.\n",m_iListIndex+1); return false; } if (m_IF.IsPL(BQB_PL_VERBOSE)) m_IF.printf(" LIST: Opened list entry %d. Trying to read frame...\n",m_iListIndex+1); goto _again; } if ((m_oaBQBList[m_iListIndex]->m_pFile->m_pShortFrame->m_iFrameType == 2) || (m_oaBQBList[m_iListIndex]->m_pFile->m_pShortFrame->m_iFrameType == 3)) { if (m_IF.IsPL(BQB_PL_VERBOSE)) m_IF.printf(" LIST: Is an index frame, skipping.\n"); goto _again; } m_pShortFrame = m_oaBQBList[m_iListIndex]->m_pFile->m_pShortFrame; if (m_IF.IsPL(BQB_PL_VERBOSE)) m_IF.printf(" LIST: Frame successfully read.\n"); } else { if (m_pFile == NULL) { m_IF.eprintf("CBQBFile::ReadFrame(): Error: File pointer is NULL.\n"); abort(); } (void)fread(uci,2,1,m_pFile); if (m_IF.IsPL(BQB_PL_VERBOSE)) m_IF.printf(" Offset is now %ld.\n",ftell(m_pFile)); if (feof(m_pFile)) { m_bEOF = true; if (m_IF.IsPL(BQB_PL_VERBOSE)) { m_IF.printf(" Found EOF while reading frame header.\n"); m_IF.printf("<<< CBQBFile::ReadFrame <<<\n\n"); } return false; } if (memcmp(uci,"BQ",2) != 0) { m_IF.eprintf("CBQBFile::ReadFrame(): Error: Frame does not start with \"BQ\".\n"); abort(); } (void)fread(&uc,1,1,m_pFile); ty = uc >> 3; ve = uc & 7; if (m_IF.IsPL(BQB_PL_VERBOSE)) m_IF.printf(" Found frame type %d, version %d.\n",ty,ve); if ((ty < 2) || (ty > 13)) { m_IF.eprintf("CBQBFile::ReadFrame(): Error: Frame type %d is not a valid short frame.\n",ty); abort(); } if (m_pShortFrame != NULL) delete m_pShortFrame; m_pShortFrame = new CBQBShortFrame(); m_pShortFrame->m_iFrameType = ty; m_pShortFrame->m_iFrameTypeVersion = ve; (void)fread(&id,4,1,m_pFile); (void)fread(&len,4,1,m_pFile); (void)fread(&crc,4,1,m_pFile); m_pShortFrame->m_iID = id; if (m_IF.IsPL(BQB_PL_VERBOSE)) m_IF.printf(" Found id %u, payload length %u, crc32 %u.\n",id,len,crc); if (!ReadArrayFromFile(m_pFile,m_pShortFrame->m_iaPayload,len)) { m_IF.eprintf("CBQBFile::ReadFrame(): Error: Unexpected end of file while reading frame payload (%u bytes).\n",len); abort(); } if (m_IF.IsPL(BQB_PL_VERBOSE)) m_IF.printf(" %u bytes of payload read.\n",len); if (m_IF.IsPL(BQB_PL_VERBOSE)) m_IF.printf(" Finished reading payload, CRC check...\n"); m_pShortFrame->m_iCRC32 = ecrc.ComputeCRC32(m_pShortFrame->m_iaPayload); if (crc != m_pShortFrame->m_iCRC32) { m_IF.eprintf("CBQBFile::ReadFrame(): Error: CRC check failed for frame payload (computed %08lX, read %08X).\n",m_pShortFrame->m_iCRC32,crc); abort(); } if (m_IF.IsPL(BQB_PL_VERBOSE)) m_IF.printf(" CRC matches. All done.\n"); } m_iFrameCounter++; if (m_IF.IsPL(BQB_PL_VERBOSE)) m_IF.printf("<<< CBQBFile::ReadFrame <<<\n\n"); return true; } bool CBQBFile::OpenWriteAppend(std::string s) { long ip; CBQBTools bqbtools(m_IF); CBQBBitSet bs(m_IF); unsigned long fohi, folo, rohi, rolo; std::vector tuca; if (m_IF.IsPL(BQB_PL_VERBOSE)) m_IF.printf(">>> CBQBFile::OpenWriteAppend >>>\n"); if (m_bOpenRead || m_bOpenWrite) { m_IF.eprintf("CBQBFile::OpenWriteAppend(): Error: A file is already open.\n"); abort(); } m_pIndex = new CBQBIndex(m_IF); m_pFile = fopen(s.c_str(),"r+b"); if (m_pFile != NULL) { // File exists if (m_IF.IsPL(BQB_PL_VERBOSE)) m_IF.printf(" File already exists, looking for index frame...\n"); ip = bqbtools.FindIndexPosition(m_pFile); if (ip != 0) { if (m_IF.IsPL(BQB_PL_VERBOSE)) m_IF.printf(" Found index frame at offset %ld, reading...\n",ip); fseek(m_pFile,ip,SEEK_SET); GetFileOffset(fohi,folo); m_bOpenRead = true; ReadFrame(); m_bOpenRead = false; if (m_pShortFrame->m_iFrameType == BQB_FRAMETYPE_COMPIDX) { if (m_pShortFrame->m_iFrameTypeVersion > 1) { m_IF.eprintf("CBQBFile::OpenWriteAppend(): Error: Unexpected frame version %d of compressed index frame.\n", m_pShortFrame->m_iFrameTypeVersion); abort(); } if (m_pShortFrame->m_iFrameTypeVersion >= 1) { bs.m_iaData.assign( m_pShortFrame->m_iaPayload.begin(), m_pShortFrame->m_iaPayload.begin()+8 ); bs.m_iExcessBits = 0; bs.m_iReadPosBytes = 0; bs.m_iReadPosExcess = 0; rohi = bs.ReadBitsInteger(32); rolo = bs.ReadBitsInteger(32); if ((rohi != fohi) || (rolo != folo)) { m_IF.eprintf("CBQBFile::OpenWriteAppend(): Warning: Index frame found at wrong offset; ignoring (found at %02lX:%08lX, expected at %02lX:%08lX).\n", fohi, folo, rohi, rolo ); goto _noindex; } tuca.assign( m_pShortFrame->m_iaPayload.begin()+8, m_pShortFrame->m_iaPayload.end() ); } else tuca.assign( m_pShortFrame->m_iaPayload.begin(), m_pShortFrame->m_iaPayload.end() ); m_pIndex->ImportFromArray( true, tuca, m_pShortFrame->m_iFrameTypeVersion ); } else if (m_pShortFrame->m_iFrameType == BQB_FRAMETYPE_IDX) { if (m_pShortFrame->m_iFrameTypeVersion > 1) { m_IF.eprintf("CBQBFile::OpenWriteAppend(): Error: Unexpected frame version %d of uncompressed index frame.\n", m_pShortFrame->m_iFrameTypeVersion); abort(); } m_pIndex->ImportFromArray( false, m_pShortFrame->m_iaPayload, m_pShortFrame->m_iFrameTypeVersion ); } else { m_IF.eprintf("CBQBFile::OpenWriteAppend(): Error: Unexpected frame type %d of index frame.\n", m_pShortFrame->m_iFrameType); abort(); } if (m_IF.IsPL(BQB_PL_VERBOSE)) m_IF.printf(" Positioning file pointer to start of old index frame.\n"); fseek(m_pFile,ip,SEEK_SET); } else if (m_IF.IsPL(BQB_PL_VERBOSE)) m_IF.printf(" Found no index frame.\n"); _noindex:; } else { // File does not exist if (m_IF.IsPL(BQB_PL_VERBOSE)) m_IF.printf(" File does not exist, creating...\n"); m_pFile = fopen(s.c_str(),"wb"); if (m_pFile == NULL) { m_IF.eprintf("CBQBFile::OpenWriteAppend(): Error: Could not create \"%s\" for writing.\n", s.c_str()); abort(); } } m_sFileName = s; m_bOpenWrite = true; if (m_pShortFrame != NULL) { delete m_pShortFrame; m_pShortFrame = NULL; } if (m_IF.IsPL(BQB_PL_VERBOSE)) m_IF.printf("<<< CBQBFile::OpenWriteAppend <<<\n\n"); return true; } bool CBQBFile::OpenWriteReplace(std::string s) { if (m_IF.IsPL(BQB_PL_VERBOSE)) m_IF.printf(">>> CBQBFile::OpenWriteReplace >>>\n"); if (m_bOpenRead || m_bOpenWrite) { m_IF.eprintf("CBQBFile::OpenWriteReplace(): Error: A file is already open.\n"); abort(); } m_pIndex = new CBQBIndex(m_IF); if (m_IF.IsPL(BQB_PL_VERBOSE)) m_IF.printf(" Creating file...\n"); m_pFile = fopen(s.c_str(),"wb"); if (m_pFile == NULL) { m_IF.eprintf("CBQBFile::OpenWriteReplace(): Error: Could not create \"%s\" for writing.\n",s.c_str()); abort(); } m_sFileName = s; m_bOpenWrite = true; if (m_pShortFrame != NULL) { delete m_pShortFrame; m_pShortFrame = NULL; } if (m_IF.IsPL(BQB_PL_VERBOSE)) m_IF.printf("<<< CBQBFile::OpenWriteReplace <<<\n\n"); return true; } bool CBQBFile::Rewind() { if (m_IF.IsPL(BQB_PL_VERBOSE)) m_IF.printf(">>> CBQBFile::Rewind() >>>\n"); if (!m_bOpenRead && !m_bOpenWrite) { m_IF.eprintf("CBQBFile::Rewind(): Error: No file is open.\n"); abort(); } if (m_bListFile) { if (m_IF.IsPL(BQB_PL_VERBOSE)) m_IF.printf(" LIST: Rewinding list file...\n"); if (m_iListIndex != -1) m_oaBQBList[m_iListIndex]->m_pFile->Close(); m_iListIndex = -1; } else { if (m_IF.IsPL(BQB_PL_VERBOSE)) m_IF.printf(" Rewinding bqb file...\n"); if (m_pFile == NULL) { m_IF.eprintf("CBQBFile::Rewind(): Error: File pointer is NULL.\n"); abort(); } rewind(m_pFile); if (m_pEngine == NULL) { //m_pEngine = new CBQBEngine(); m_pEngine = m_IF.CreateEngine(0); m_pEngine->PrepareDecompressCube(); } else m_pEngine->Reset(); } m_bEOF = false; m_iFrameCounter = 0; if (m_IF.IsPL(BQB_PL_VERBOSE)) m_IF.printf("<<< CBQBFile::Rewind <<<\n\n"); return true; } void CBQBFile::GetFileOffset(unsigned long &high, unsigned long &low) { if (m_IF.IsPL(BQB_PL_VERBOSE)) m_IF.printf(">>> CBQBFile::GetFileOffset >>>\n"); if (!m_bOpenRead && !m_bOpenWrite) { m_IF.eprintf("CBQBFile::GetFileOffset(): Error: No file is open.\n"); abort(); } // It is not so easy to get the 64 bit file offset // in a platform-independent portable way... #ifdef __CYGWIN__ low = ftell(m_pFile) & 0xFFFFFFFF; high = ftell(m_pFile) >> 32; #elif defined (_WIN32) low = _telli64(_fileno(m_pFile)) & 0xFFFFFFFF; high = _telli64(_fileno(m_pFile)) >> 32; #else low = ftello(m_pFile) & 0xFFFFFFFF; high = ftello(m_pFile) >> 32; #endif if (m_IF.IsPL(BQB_PL_VERBOSE)) m_IF.printf("<<< CBQBFile::GetFileOffset <<<\n"); } CBQBEngine* CBQBFile::GetEngine() { if (!m_bOpenRead && !m_bOpenWrite) { m_IF.eprintf("CBQBFile::GetEngine(): Error: No file is open.\n"); abort(); } if (m_bListFile) { if (m_oaBQBList.size() == 0) { m_IF.eprintf("CBQBFile::GetEngine(): Error: No entrys in list.\n"); abort(); } if (m_iListIndex == -1) { m_IF.eprintf("CBQBFile::GetEngine(): Error: No entry from list file is open.\n"); abort(); } if (m_oaBQBList[m_iListIndex]->m_pFile == NULL) { m_IF.eprintf("CBQBFile::GetEngine(): Error: m_pFile == NULL in current list entry.\n"); abort(); } if (m_oaBQBList[m_iListIndex]->m_pFile->m_pEngine == NULL) { m_IF.eprintf("CBQBFile::GetEngine(): Error: m_pFile->m_pEngine == NULL in current list entry.\n"); abort(); } return m_oaBQBList[m_iListIndex]->m_pFile->m_pEngine; } if (m_pEngine == NULL) { m_IF.eprintf("CBQBFile::GetEngine(): Error: m_pEngine == NULL.\n"); abort(); } return m_pEngine; } bool CBQBFile::Close() { int z; if (m_IF.IsPL(BQB_PL_VERBOSE)) m_IF.printf(">>> CBQBFile::Close >>>\n"); if (!m_bOpenRead && !m_bOpenWrite) { m_IF.eprintf("CBQBFile::Close(): Error: No file is open.\n"); abort(); } if (m_bListFile) { if (m_IF.IsPL(BQB_PL_VERBOSE)) m_IF.printf(" LIST: Closing list file...\n"); if (m_iListIndex != -1) m_oaBQBList[m_iListIndex]->m_pFile->Close(); m_iListIndex = -1; for (z=0;z<(int)m_oaBQBList.size();z++) delete m_oaBQBList[z]; m_oaBQBList.clear(); m_pShortFrame = NULL; // Managed/deleted by subsequent instances } else { if (m_IF.IsPL(BQB_PL_VERBOSE)) m_IF.printf(" Closing BQB file...\n"); if (m_pFile == NULL) { m_IF.eprintf("CBQBFile::Close(): Error: File pointer is NULL.\n"); abort(); } fclose(m_pFile); m_pFile = NULL; } m_sFileName = ""; if (m_pIndex != NULL) { delete m_pIndex; m_pIndex = NULL; } if (m_pShortFrame != NULL) { delete m_pShortFrame; m_pShortFrame = NULL; } m_bOpenRead = false; m_bOpenWrite = false; m_iTotalFrameCount = -1; m_bListFile = false; if (m_IF.IsPL(BQB_PL_VERBOSE)) m_IF.printf("<<< CBQBFile::Close <<<\n\n"); return true; } bool CBQBFile::CreateGeneralFrame() { if (m_IF.IsPL(BQB_PL_VERBOSE)) m_IF.printf(">>> CBQBFile::CreateGeneralFrame >>>\n"); m_IF.eprintf("CBQBFile::CreateGeneralFrame(): Not yet implemented.\n"); abort(); return true; } bool CBQBFile::CreateShortFrame(int type, int version, int id) { if (m_IF.IsPL(BQB_PL_VERBOSE)) m_IF.printf(">>> CBQBFile::CreateShortFrame >>>\n"); if (!m_bOpenWrite) { m_IF.eprintf("CBQBFile::CreateShortFrame(): Error: No file is open for writing.\n"); abort(); } if ((type < 2) || (type > 13)) { m_IF.eprintf("CBQBFile::CreateShortFrame(): Error: Short frame type must be in range 2 .. 9 (specified: %d).\n",type); abort(); } if ((version < 0) || (version > 7)) { m_IF.eprintf("CBQBFile::CreateShortFrame(): Error: Frame type version must be in range 0 .. 7 (specified: %d).\n",version); abort(); } m_bShortFrame = true; if (m_pShortFrame != NULL) delete m_pShortFrame; m_pShortFrame = new CBQBShortFrame(); m_pShortFrame->m_iFrameType = type; m_pShortFrame->m_iFrameTypeVersion = version; m_pShortFrame->m_iID = id; if (m_IF.IsPL(BQB_PL_VERBOSE)) m_IF.printf("<<< CBQBFile::CreateShortFrame <<<\n\n"); return true; } bool CBQBFile::PushPayload(const std::vector &ia) { if (m_IF.IsPL(BQB_PL_VERBOSE)) m_IF.printf(">>> CBQBFile::PushPayload >>>\n"); if (!m_bOpenWrite) { m_IF.eprintf("CBQBFile::PushPayload(): Error: No file is open for writing.\n"); abort(); } if (!m_bShortFrame) { m_IF.eprintf("CBQBFile::PushPayload(): Error: Only applicable to short frames.\n"); abort(); } if (m_pShortFrame == NULL) { m_IF.eprintf("CBQBFile::PushPayload(): Error: No frame has been created before.\n"); abort(); } m_pShortFrame->m_iaPayload.insert( m_pShortFrame->m_iaPayload.end(), ia.begin(), ia.end() ); if (m_IF.IsPL(BQB_PL_VERBOSE)) m_IF.printf("<<< CBQBFile::PushPayload <<<\n\n"); return true; } bool CBQBFile::FinalizeFrame(CBQBStatistics *stat) { unsigned char uc, tv; unsigned int ui; CBQBCRC32 crc; if (m_IF.IsPL(BQB_PL_VERBOSE)) m_IF.printf(">>> CBQBFile::FinalizeFrame >>>\n"); if (!m_bOpenWrite) { m_IF.eprintf("CBQBFile::FinalizeFrame(): Error: No file is open for writing.\n"); abort(); } if (m_bShortFrame) { if (m_pShortFrame == NULL) { m_IF.eprintf("CBQBFile::FinalizeFrame(): Error: No frame has been created before.\n"); abort(); } if (m_pShortFrame->m_iaPayload.size() == 0) { m_IF.eprintf("CBQBFile::FinalizeFrame(): Error: Payload is empty.\n"); abort(); } uc = 'B'; fwrite(&uc,1,1,m_pFile); uc = 'Q'; fwrite(&uc,1,1,m_pFile); if (m_IF.IsPL(BQB_PL_VERBOSE)) m_IF.printf(" Offset %ld, writing frame type %d.\n",ftell(m_pFile),m_pShortFrame->m_iFrameType); tv = (unsigned char)((m_pShortFrame->m_iFrameType << 3) + m_pShortFrame->m_iFrameTypeVersion); fwrite(&tv,1,1,m_pFile); ui = m_pShortFrame->m_iID; fwrite(&ui,4,1,m_pFile); ui = (unsigned int)m_pShortFrame->m_iaPayload.size(); fwrite(&ui,4,1,m_pFile); m_pShortFrame->m_iCRC32 = crc.ComputeCRC32(m_pShortFrame->m_iaPayload); ui = m_pShortFrame->m_iCRC32; fwrite(&ui,4,1,m_pFile); if (stat != NULL) stat->m_oStat.m_lOverhead += 15 * 8; WriteArrayToFile(m_pFile,m_pShortFrame->m_iaPayload); fflush(m_pFile); if (m_IF.IsPL(BQB_PL_VERBOSE)) m_IF.printf(" %lu bytes of payload written, CRC32 is %08lX.\n",m_pShortFrame->m_iaPayload.size(),m_pShortFrame->m_iCRC32); m_pIndex->m_iaFrameLengths.push_back((int)m_pShortFrame->m_iaPayload.size()+15); m_pIndex->m_iaFrameTypes.push_back(tv); m_pIndex->m_iaFrameIDs.push_back(m_pShortFrame->m_iID); delete m_pShortFrame; m_pShortFrame = NULL; } else { m_IF.eprintf("CBQBFile::FinalizeFrame(): Error: Not yet implemented for general frames.\n"); abort(); } if (m_IF.IsPL(BQB_PL_VERBOSE)) m_IF.printf("<<< CBQBFile::FinalizeFrame <<<\n\n"); return true; } bool CBQBFile::WriteIndexFrame(bool compressed, CBQBStatistics *stat) { std::vector uca; unsigned long ul, fohi, folo; CBQBBitSet bs(m_IF); if (m_IF.IsPL(BQB_PL_VERBOSE)) m_IF.printf(">>> CBQBFile::WriteIndexFrame >>>\n"); if (!m_bOpenWrite) { m_IF.eprintf("CBQBFile::WriteIndexFrame(): Error: No file is open for writing.\n"); abort(); } if (m_pIndex->m_iaFrameTypes.size() == 0) { m_IF.eprintf("CBQBFile::WriteIndexFrame(): Warning: Will not write index for empty file.\n"); goto _ende; } if (compressed) { GetFileOffset(fohi,folo); // Compressed Index Frame Version 1 CreateShortFrame(BQB_FRAMETYPE_COMPIDX,1,0); bs.WriteBits(fohi,32); bs.WriteBits(folo,32); PushPayload(bs.m_iaData); m_pIndex->ExportToArray(compressed,uca,stat); PushPayload(uca); if (stat != NULL) stat->m_oStat.m_lOverhead += (int)((8+uca.size())*8); ul = (unsigned long)(8 + uca.size() + 22); uca.clear(); uca.push_back((ul>>24)&0xFF); uca.push_back((ul>>16)&0xFF); uca.push_back((ul>>8)&0xFF); uca.push_back(ul&0xFF); uca.push_back('I'); uca.push_back('D'); uca.push_back('X'); PushPayload(uca); if (stat != NULL) stat->m_oStat.m_lOverhead += (int)(uca.size()*8); FinalizeFrame(stat); } else { m_IF.eprintf("CBQBFile::WriteIndexFrame(): Non-compressed index frames not yet implemented.\n"); abort(); } _ende: if (m_IF.IsPL(BQB_PL_VERBOSE)) m_IF.printf("<<< CBQBFile::WriteIndexFrame <<<\n\n"); return true; } void CBQBFile::DumpIndex() { m_pIndex->Dump(); } bool CBQBFile::CheckIntegrity(std::string s, bool verbose) { UNUSED(verbose); int i; unsigned long crc; CBQBCRC32 ecrc; bool b; m_IF.printf("##########################################\n"); m_IF.printf("### Barbecube File Integrity Check ###\n"); m_IF.printf("##########################################\n"); m_IF.printf("Trying to open %s ...\n",s.c_str()); if (!OpenRead(s)) { m_IF.eprintf("CBQBFile::CheckIntegrity(): Error: Failed to open %s\n",s.c_str()); return false; } if (m_pIndex->m_iaFrameLengths.size() != 0) { m_IF.printf("File contains an index with %lu/%lu entries.\n",m_pIndex->m_iaFrameTypes.size(),m_pIndex->m_iaFrameLengths.size()); i = 0; b = false; while (ReadFrame()) { m_IF.printf(" Frame %6d, type %2d v%d (%s), ID %6d, payload size %8lu bytes.\n", i+1, m_pShortFrame->m_iFrameType, m_pShortFrame->m_iFrameTypeVersion, GetFrameTypeString(m_pShortFrame->m_iFrameType), m_pShortFrame->m_iID, m_pShortFrame->m_iaPayload.size() ); if (b) { m_IF.eprintf("CBQBFile::CheckIntegrity(): Error: Frame %d not on the index, but was not the last frame.\n",i); Close(); return false; } crc = ecrc.ComputeCRC32(m_pShortFrame->m_iaPayload); if (crc != m_pShortFrame->m_iCRC32) { m_IF.eprintf("CBQBFile::CheckIntegrity(): Error in frame %d: CRC mismatch (computed %08lX, read %08lX).\n",i+1,crc,m_pShortFrame->m_iCRC32); Close(); return false; } if ((int)m_pIndex->m_iaFrameTypes.size() > i) { if ((m_pShortFrame->m_iFrameType != (int)(m_pIndex->m_iaFrameTypes[i]>>3)) || (m_pShortFrame->m_iFrameTypeVersion != (int)(m_pIndex->m_iaFrameTypes[i]&7)) || ((int)m_pShortFrame->m_iaPayload.size()+15 != m_pIndex->m_iaFrameLengths[i])) { m_IF.eprintf("CBQBFile::CheckIntegrity(): Error in frame %d: Mismatch between frame header and index: Type %d<-->%d, Version %d<-->%d, Length %lu<-->%d.\n",i+1,m_pShortFrame->m_iFrameType,m_pIndex->m_iaFrameTypes[i]>>3,m_pShortFrame->m_iFrameTypeVersion,m_pIndex->m_iaFrameTypes[i]&7,m_pShortFrame->m_iaPayload.size()+15,m_pIndex->m_iaFrameLengths[i]); Close(); return false; } } else { b = true; m_IF.printf(" This frame is not on the index...\n"); } i++; } } else { m_IF.printf("File does not contain an index.\n"); i = 0; while (ReadFrame()) { m_IF.printf(" Frame %6d, type %2d v%d (%s), ID %6d, payload size %8lu bytes.\n", i+1, m_pShortFrame->m_iFrameType, m_pShortFrame->m_iFrameTypeVersion, GetFrameTypeString(m_pShortFrame->m_iFrameType), m_pShortFrame->m_iID, m_pShortFrame->m_iaPayload.size() ); crc = ecrc.ComputeCRC32(m_pShortFrame->m_iaPayload); if (crc != m_pShortFrame->m_iCRC32) { m_IF.eprintf("CBQBFile::CheckIntegrity(): Error in frame %d: CRC mismatch (computed %08lX, read %08lX).\n",i+1,crc,m_pShortFrame->m_iCRC32); Close(); return false; } i++; } } Close(); m_IF.printf("Integrity check passed.\n\n"); return true; } int CBQBFile::GetFrameID() const { if (m_IF.IsPL(BQB_PL_VERBOSE)) m_IF.printf(">>> CBQBFile::GetFrameID >>>\n"); if (!m_bOpenRead) { m_IF.eprintf("CBQBFile::GetFrameID(): Error: File not open for reading.\n"); abort(); } if (m_pShortFrame == NULL) { m_IF.eprintf("CBQBFile::GetFrameID(): Error: No current frame.\n"); abort(); } if (m_IF.IsPL(BQB_PL_VERBOSE)) m_IF.printf("<<< CBQBFile::GetFrameID <<<\n\n"); return m_pShortFrame->m_iID; } int CBQBFile::GetFrameType() const { if (m_IF.IsPL(BQB_PL_VERBOSE)) m_IF.printf(">>> GetFrameType::GetFrameIndex >>>\n"); if (!m_bOpenRead) { m_IF.eprintf("CBQBFile::GetFrameType(): Error: File not open for reading.\n"); abort(); } if (m_pShortFrame == NULL) { m_IF.eprintf("CBQBFile::GetFrameType(): Error: No current frame.\n"); abort(); } if (m_IF.IsPL(BQB_PL_VERBOSE)) m_IF.printf("<<< CBQBFile::GetFrameType <<<\n\n"); return m_pShortFrame->m_iFrameType; } int CBQBFile::GetFrameTypeVersion() const { if (m_IF.IsPL(BQB_PL_VERBOSE)) m_IF.printf(">>> CBQBFile::GetFrameTypeVersion >>>\n"); if (!m_bOpenRead) { m_IF.eprintf("CBQBFile::GetFrameTypeVersion(): Error: File not open for reading.\n"); abort(); } if (m_pShortFrame == NULL) { m_IF.eprintf("CBQBFile::GetFrameTypeVersion(): Error: No current frame.\n"); abort(); } if (m_IF.IsPL(BQB_PL_VERBOSE)) m_IF.printf("<<< CBQBFile::GetFrameTypeVersion <<<\n\n"); return m_pShortFrame->m_iFrameTypeVersion; } const std::vector* CBQBFile::GetFramePayload() const { if (m_IF.IsPL(BQB_PL_VERBOSE)) m_IF.printf(">>> CBQBFile::GetFramePayload >>>\n"); if (!m_bOpenRead) { m_IF.eprintf("CBQBFile::GetFramePayload(): Error: File not open for reading.\n"); abort(); } if (m_pShortFrame == NULL) { m_IF.eprintf("CBQBFile::GetFramePayload(): Error: No current frame.\n"); abort(); } if (m_IF.IsPL(BQB_PL_VERBOSE)) m_IF.printf("<<< CBQBFile::GetFramePayload <<<\n\n"); return &m_pShortFrame->m_iaPayload; } const char *GetFrameTypeString(int type) { const char* names[] = { "RESERVED ", "GENERAL ", "IDX ", "COMPIDX ", "TRAJ ", "COMPTRAJSTART", "COMPTRAJ ", "CUBE ", "COMPCUBESTART", "COMPCUBE ", "FILE ", "COMPFILE " "COMPTRAJKEY ", "COMPCUBEKEY " }; if ((type >= 0) && (type < 14)) return names[type]; else return "UNKNOWN "; } bool CBQBFile::OpenListFile(FILE *a) { char buf[1024], buf2[32], bstart[16], bend[16], *p, *q, *r; CBQBListEntry *le; bool b; int z, ti; if (m_IF.IsPL(BQB_PL_VERBOSE)) m_IF.printf(">>> CBQBFile::OpenListFile >>>\n"); fseek(a,0,SEEK_SET); (void)fgets(buf,1024,a); while ((buf[strlen(buf)-1] == '\r') || (buf[strlen(buf)-1] == '\n')) buf[strlen(buf)-1] = 0; if (strcmp(buf,"BLIST") != 0) { m_IF.eprintf("CBQBFile::OpenListFile(): Error: File header mismatch (\"%s\" != \"BLIST\").\n", buf); return false; } b = false; m_iTotalFrameCount = 0; m_iListIndex = -1; while (!feof(a)) { if (fgets(buf,1024,a) == NULL) { if (!feof(a)) { m_IF.eprintf("CBQBFile::OpenListFile(): Error while reading line %lu from BQB list file.\n", m_oaBQBList.size()+1); return false; } else break; } while ((buf[strlen(buf)-1] == '\r') || (buf[strlen(buf)-1] == '\n')) buf[strlen(buf)-1] = 0; if (strlen(buf) == 0) continue; if (m_IF.IsPL(BQB_PL_VERBOSE)) m_IF.printf(" LIST: Checking list entry %3d: \"%s\"...\n", (int)m_oaBQBList.size()+1,buf); le = new CBQBListEntry(); p = buf; while (*p == ' ') p++; if (*p == '[') { q = p+1; while ((*q != ']') && (*q != 0)) q++; if (*q == 0) { m_IF.eprintf("CBQBFile::OpenListFile(): Missing \"]\" in line %lu: \"%s\".\n", m_oaBQBList.size()+1,buf); return false; } r = p+1; while ((r < q) && (*r != '-')) r++; if (r == q) { m_IF.eprintf("CBQBFile::OpenListFile(): Missing \"-\" in line %lu: \"%s\".\n", m_oaBQBList.size()+1,buf); return false; } if (p+1 < r) memcpy(buf2,p+1,r-p-1); buf2[r-p-1] = 0; le->m_iFrameStart = atoi(buf2)-1; if (r+1 < q) memcpy(buf2,r+1,q-r-1); buf2[q-r-1] = 0; le->m_iFrameEnd = atoi(buf2)-1; le->m_sFileName = q+1; } else le->m_sFileName = buf; if (le->m_sFileName[0] == '/') goto _abs; // Absolute path (Unix) if (le->m_sFileName.length() > 2) if (le->m_sFileName[1] == ':') goto _abs; // Absolute path (Windows) // Prepend directory of list file to relative path of entry if (m_sDirectory.length() > 0) { le->m_sFileName = m_sDirectory + le->m_sFileName; if (m_IF.IsPL(BQB_PL_VERBOSE)) m_IF.printf(" LIST: Reconstructed path: \"%s\"\n", le->m_sFileName.c_str() ); } _abs: le->m_pFile = new CBQBFile(m_IF); if (!le->m_pFile->OpenRead(le->m_sFileName)) { m_IF.eprintf("CBQBFile::OpenListFile(): Error while opening entry %d: \"%s\".\n", (int)m_oaBQBList.size()+1,buf); return false; } if (le->m_pFile->m_pIndex != NULL) { le->m_pIndex = new CBQBIndex(*le->m_pFile->m_pIndex); ti = 0; for (z=0;z<(int)le->m_pIndex->m_iaFrameLengths.size();z++) if ((le->m_pIndex->m_iaFrameTypes[z] != 2) && (le->m_pIndex->m_iaFrameTypes[z] != 3)) ti++; le->m_iFullFrameCount = ti/*le->m_pIndex->m_iaFrameLengths.size()*/; if (m_IF.IsPL(BQB_PL_VERBOSE)) m_IF.printf(" LIST: Found index frame: %d frames, %d payload frames.\n", (int)le->m_pIndex->m_iaFrameLengths.size(),le->m_iFullFrameCount); } else if (m_IF.IsPL(BQB_PL_VERBOSE)) { b = true; if (m_IF.IsPL(BQB_PL_VERBOSE)) m_IF.printf(" LIST: Found no index.\n"); } if ((le->m_iFrameStart != -1) && (le->m_iFrameEnd != -1)) { le->m_iFrameCount = le->m_iFrameEnd - le->m_iFrameStart + 1; if ((le->m_iFullFrameCount != -1) && (le->m_iFrameCount > le->m_iFullFrameCount)) { m_IF.eprintf("CBQBFile::OpenListFile(): Error in entry %d: Frame range %d - %d is more than total frame count (%d).\n", (int)m_oaBQBList.size()+1,le->m_iFrameStart+1,le->m_iFrameEnd+1,le->m_iFullFrameCount); return false; } } else if ((le->m_iFrameStart != -1) && (le->m_iFullFrameCount != -1)) { le->m_iFrameCount = le->m_iFullFrameCount - le->m_iFrameStart; if (le->m_iFrameStart+1 > le->m_iFullFrameCount) { m_IF.eprintf("CBQBFile::OpenListFile(): Error in entry %d: Starting frame number %d is larger than total frame count (%d).\n", (int)m_oaBQBList.size()+1,le->m_iFrameStart+1,le->m_iFullFrameCount); return false; } } else if ((le->m_iFrameEnd != -1) && (le->m_iFullFrameCount != -1)) { le->m_iFrameCount = le->m_iFrameEnd + 1; if (le->m_iFrameEnd+1 > le->m_iFullFrameCount) { m_IF.eprintf("CBQBFile::OpenListFile(): Error in entry %d: Ending frame number %d is larger than total frame count (%d).\n", (int)m_oaBQBList.size()+1,le->m_iFrameEnd+1,le->m_iFullFrameCount); return false; } } else le->m_iFrameCount = le->m_iFullFrameCount; if (le->m_iFrameCount != -1) m_iTotalFrameCount += le->m_iFrameCount; le->m_pFile->Close(); m_oaBQBList.push_back(le); } if (!b) { if (m_IF.IsPL(BQB_PL_VERBOSE)) m_IF.printf("LIST: Building overall index...\n"); m_pIndex = new CBQBIndex(m_IF); for (z=0;z<(int)m_oaBQBList.size();z++) { m_pIndex->m_iaFrameLengths.insert(m_pIndex->m_iaFrameLengths.end(),m_oaBQBList[z]->m_pIndex->m_iaFrameLengths.begin(),m_oaBQBList[z]->m_pIndex->m_iaFrameLengths.end()); m_pIndex->m_iaFrameTypes.insert(m_pIndex->m_iaFrameTypes.end(),m_oaBQBList[z]->m_pIndex->m_iaFrameTypes.begin(),m_oaBQBList[z]->m_pIndex->m_iaFrameTypes.end()); } } else { if (m_IF.IsPL(BQB_PL_VERBOSE)) m_IF.printf("LIST: Some list entries have no index; not building overall index.\n"); m_iTotalFrameCount = -1; } if (m_IF.IsPL(BQB_PL_VERBOSE)) m_IF.printf("LIST: Added %lu entrys to list.\n",m_oaBQBList.size()); if (m_IF.IsPL(BQB_PL_VERBOSE)) { if (m_iTotalFrameCount != -1) m_IF.printf("LIST: Found %d frames in total.\n",m_iTotalFrameCount); else m_IF.printf("LIST: Total frame count is unknown.\n"); } fclose(a); m_IF.printf("\n"); m_IF.printf(" Contents of BQB list file %s:\n",m_sFileName.c_str()); for (z=0;z<(int)m_oaBQBList.size();z++) { if (m_oaBQBList[z]->m_iFrameStart != -1) sprintf(bstart,"%5d",m_oaBQBList[z]->m_iFrameStart+1); else sprintf(bstart,"start"); if (m_oaBQBList[z]->m_iFrameEnd != -1) sprintf(bend,"%5d",m_oaBQBList[z]->m_iFrameEnd+1); else sprintf(bend," end"); if (m_oaBQBList[z]->m_pIndex != NULL) m_IF.printf(" %3d.) %5d payload frames, using %5d (%5s - %5s), %s\n", z+1,m_oaBQBList[z]->m_iFullFrameCount,m_oaBQBList[z]->m_iFrameCount,bstart, bend,m_oaBQBList[z]->m_sFileName.c_str()); else if (m_oaBQBList[z]->m_iFrameCount != -1) m_IF.printf(" %3d.) (no index), using %5d (%5s - %5s), %s\n", z+1,m_oaBQBList[z]->m_iFrameCount,bstart,bend,m_oaBQBList[z]->m_sFileName.c_str()); else m_IF.printf(" %3d.) (no index), (%5s - %5s), %s\n", z+1,bstart,bend,m_oaBQBList[z]->m_sFileName.c_str()); } m_IF.printf("\n"); if (m_IF.IsPL(BQB_PL_VERBOSE)) m_IF.printf("<<< CBQBFile::OpenListFile <<<\n"); return true; } bool CBQBFile::IsEOF() { return m_bEOF; } bool CBQBFile::CompareCoords(std::string infile, std::string reffile, bool verbose) { UNUSED(infile); UNUSED(reffile); UNUSED(verbose); /* FILE *a; int i, z, z2, ty, ver; CTimeStep ts; CxDVec3Array da; double cv[3], m, t1, t2, tv[3]; bool wrap; CCubeFrame *cfr; CAtomSet *afr; bool fail; m_IF.printf("\n"); m_IF.printf(WHITE," *********************************\n"); m_IF.printf(WHITE," *** Coordinate Comparison ***\n"); m_IF.printf(WHITE," *********************************\n\n"); m_IF.printf(" Will compare the coordinates in BQB file %s\n",infile.c_str()); m_IF.printf(" to the reference coordinates in XYZ file %s.\n",reffile.c_str()); m_IF.printf("\n"); SetBarbecubeVerbose(verbose); m_IF.printf(" Opening BQB file...\n"); if (!OpenRead(infile)) return false; m_IF.printf("\n"); m_IF.printf(" Opening XYZ file...\n"); a = fopen(reffile.c_str(),"rb"); if (a == NULL) { m_IF.eprintf("Error: Could not open file for reading.\n"); return false; } g_pCCEngine = new CCCEngine(); g_pCCEngine->PrepareDecompressCube(false); m_IF.printf("\n"); if (AskYesNo(" Allow wrapping (y) or compare absolute coordinates (n)? [yes] ",true)) { wrap = true; m_IF.printf("\n"); m_IF.printf(" Reading first frame...\n"); if (!ReadFrame()) { fclose(a); return false; } ty = GetFrameType(); ver = GetFrameTypeVersion(); m_IF.printf(" First frame is of type %d v%d.\n",ty,ver); if ((ty != 8) || (ver > 1)) { m_IF.eprintf("Error: Frame type not yet supported.\n"); fclose(a); return false; } if (!g_pCCEngine->DecompressCubeStep(GetFramePayload(),ver,false)) { fclose(a); return false; } cfr = g_pCCEngine->GetOutputCubeFrame(0); m_IF.printf("\n *** Input of cell vector (in pm) ***\n\n"); cv[0] = AskFloat(" Enter X component: [%11.4f] ",cfr->m_fStrideA[0]*cfr->m_iRes[0]*LEN_AU2PM,cfr->m_fStrideA[0]*cfr->m_iRes[0]*LEN_AU2PM); cv[1] = AskFloat(" Enter Y component: [%11.4f] ",cfr->m_fStrideB[1]*cfr->m_iRes[1]*LEN_AU2PM,cfr->m_fStrideB[1]*cfr->m_iRes[1]*LEN_AU2PM); cv[2] = AskFloat(" Enter Z component: [%11.4f] ",cfr->m_fStrideC[2]*cfr->m_iRes[2]*LEN_AU2PM,cfr->m_fStrideC[2]*cfr->m_iRes[2]*LEN_AU2PM); m_IF.printf("\n"); m_IF.printf(" Rewinding BQB file...\n"); if (!Rewind()) { fclose(a); return false; } } else wrap = false; i = 0; fail = false; m_IF.printf("\n"); m_IF.printf("Starting comparison process.\n"); while (true) { if (!ReadFrame()) break; m_IF.printf(" Frame %4d ... ",i+1); m_IF.printf("Type %2dv%1d, ",GetFrameType(),GetFrameTypeVersion()); if ((GetFrameType() == 2) || (GetFrameType() == 3)) { m_IF.printf("Skipping index frame.\n"); continue; } else if (((GetFrameType() != 8) && (GetFrameType() != 9)) || (GetFrameTypeVersion() != 0)) { m_IF.eprintf("\nError: Frame type %d v%d not yet supported.\n",GetFrameType(),GetFrameTypeVersion()); fclose(a); return false; } if (!g_pCCEngine->DecompressCubeStep(GetFramePayload(),verbose,false)) return false; afr = g_pCCEngine->GetOutputAtomFrame(0); if (!ts.ReadXYZ(a,true,&da)) { m_IF.eprintf("\nError: Could not read frame %d from XYZ trajectory.\n",i+1); fclose(a); return false; } m = 0; for (z=0;z<(int)afr->m_oaAtoms.size();z++) { // m_IF.printf("@ %10.4f %10.4f %10.4f vs %10.4f %10.4f %10.4f\n",afr->m_oaAtoms[z]->m_fCoord[0]*LEN_AU2PM,afr->m_oaAtoms[z]->m_fCoord[1]*LEN_AU2PM,afr->m_oaAtoms[z]->m_fCoord[2]*LEN_AU2PM,da[z][0],da[z][1],da[z][2]); for (z2=0;z2<3;z2++) { t1 = da[z][z2]; t2 = afr->m_oaAtoms[z]->m_fCoord[z2]*LEN_AU2PM; if (wrap) { while (t1 < 0) t1 += cv[z2]; while (t1 >= cv[z2]) t1 -= cv[z2]; while (t2 < 0) t2 += cv[z2]; while (t2 >= cv[z2]) t2 -= cv[z2]; } tv[z2] = t2 - t1; } t1 = sqrt(tv[0]*tv[0] + tv[1]*tv[1] + tv[2]*tv[2]); if (t1 > m) m = t1; } m_IF.printf("Max. dev. %11.5f pm --> ",m); if (m >= 0.001) { fail = true; m_IF.printf(RED,"fail\n"); } else m_IF.printf(GREEN,"match\n"); i++; } m_IF.printf("Compared %d frames.\n",i); m_IF.printf("Result: "); if (fail) m_IF.printf(RED,"Fail.\n"); else m_IF.printf(GREEN,"Success.\n"); fclose(a); Close(); delete g_pCCEngine; return (!fail);*/ return false; } bool CBQBTrajectoryFrameColumn::ReadColumn(int ac, CBQBBitSet *bs) { unsigned char uc; int z, z2; m_iType = (unsigned char)bs->ReadBitsInteger(8); uc = (unsigned char)bs->ReadBitsInteger(8); m_sLabel.resize(uc); for (z=0;z<(int)uc;z++) m_sLabel[z] = (char)bs->ReadBitsInteger(8); switch(m_iType) { case BQB_TYPE_STRING: m_aString.resize(ac); for (z=0;zReadBitsInteger(8); m_aString[z].resize(uc+1); //m_aString[z].SetBufSize(uc+1); for (z2=0;z2<(int)uc;z2++) m_aString[z][z2] = (char)bs->ReadBitsInteger(8); //m_aString[z](z2) = (char)bs->ReadBitsInteger(8); m_aString[z][uc] = 0; //m_aString[z](uc) = 0; } break; case BQB_TYPE_FLOAT: m_aReal.resize(ac); for (z=0;zReadBitsFloat(); break; case BQB_TYPE_DOUBLE: m_aReal.resize(ac); for (z=0;zReadBitsDouble(); break; case BQB_TYPE_UINT8: m_aUnsignedInt.resize(ac); for (z=0;zReadBitsInteger(8); break; case BQB_TYPE_UINT16: for (z=0;zReadBitsInteger(16); break; case BQB_TYPE_UINT32: for (z=0;zReadBitsInteger(32); break; default: m_IF.eprintf("CBQBTrajectoryFrameColumn::ReadColumn(): Error: Type %u not yet implemented.\n",m_iType); abort(); } return true; } void CBQBTrajectoryFrameColumn::WriteColumn(int ac, CBQBBitSet *bs) { unsigned char uc; int z, z2; bs->WriteBits(m_iType,8); uc = (unsigned char)m_sLabel.length(); bs->WriteBits(uc,8); for (z=0;z<(int)m_sLabel.length();z++) { uc = m_sLabel[z]; bs->WriteBits(uc,8); } switch(m_iType) { case BQB_TYPE_STRING: for (z=0;zWriteBits(uc,8); for (z2=0;z2<(int)m_aString[z].length();z2++) { //for (z2=0;z2<(int)m_aString[z].GetLength();z2++) { uc = m_aString[z][z2]; bs->WriteBits(uc,8); } } break; case BQB_TYPE_FLOAT: for (z=0;zWriteBitsFloat((float)m_aReal[z]); break; case BQB_TYPE_DOUBLE: for (z=0;zWriteBitsDouble(m_aReal[z]); break; case BQB_TYPE_UINT8: for (z=0;zWriteBits(m_aUnsignedInt[z],8); break; case BQB_TYPE_UINT16: for (z=0;zWriteBits(m_aUnsignedInt[z],16); break; case BQB_TYPE_UINT32: for (z=0;zWriteBits(m_aUnsignedInt[z],32); break; default: m_IF.eprintf("CBQBTrajectoryFrameColumn::WriteColumn(): Error: Type %u not yet implemented.\n",m_iType); abort(); } } bool CBQBTrajectoryFrame::ReadFrame(const std::vector *data) { CBQBBitSet bs(m_IF); int i, z; CBQBTrajectoryFrameColumn *col; bs.m_iaData.assign(data->begin(),data->end()); m_iAtomCount = bs.ReadBitsInteger(32); if (bs.ReadBitsInteger(8) != 0) { if (m_pCellMatrix == NULL) m_pCellMatrix = new CBQBDMatrix3(); for (z=0;z<9;z++) m_pCellMatrix->GetAt(z) = bs.ReadBitsDouble(); } else { if (m_pCellMatrix != NULL) { delete m_pCellMatrix; m_pCellMatrix = NULL; } } i = bs.ReadBitsInteger(32); for (z=0;z<(int)m_oaColumns.size();z++) if (m_oaColumns[z] != NULL) delete m_oaColumns[z]; m_oaColumns.resize(i); for (z=0;zReadColumn(m_iAtomCount,&bs); } return true; } void CBQBTrajectoryFrame::WriteFrame(std::vector *data) { CBQBBitSet bs(m_IF); unsigned long ul; int z; bs.WriteBits(m_iAtomCount,32); if (m_pCellMatrix != NULL) { bs.WriteBits(1,8); for (z=0;z<9;z++) bs.WriteBitsDouble(m_pCellMatrix->GetAt(z)); } else bs.WriteBits(0,8); ul = (unsigned long)m_oaColumns.size(); bs.WriteBits(ul,32); for (z=0;z<(int)m_oaColumns.size();z++) m_oaColumns[z]->WriteColumn(m_iAtomCount,&bs); data->insert(data->end(),bs.m_iaData.begin(),bs.m_iaData.end()); } CBQBTrajectoryFrameColumn* CBQBTrajectoryFrame::GetColumn(std::string label) { int z; for (z=0;z<(int)m_oaColumns.size();z++) if (bqb_strcmp_nocase(label.c_str(),m_oaColumns[z]->m_sLabel.c_str()) == 0) return m_oaColumns[z]; return NULL; } CBQBTrajectoryFrameColumn* CBQBTrajectoryFrame::AddColumn(int type, std::string label) { CBQBTrajectoryFrameColumn *col; col = new CBQBTrajectoryFrameColumn(m_IF,(unsigned char)type,label); m_oaColumns.push_back(col); return col; } bool CBQBFile::SeekFrame(int i) { int z, k; unsigned long ul; CBQBListEntry *le; if (m_IF.IsPL(BQB_PL_VERBOSE)) m_IF.printf(">>> CBQBFile::SeekFrame() i=%d >>>\n",i); if (!m_bOpenRead) { m_IF.eprintf("CBQBFile::SeekFrame(): Error: File not open for reading.\n"); abort(); } if (m_bListFile) { if (m_IF.IsPL(BQB_PL_VERBOSE)) m_IF.printf(" Is a list file.\n"); if (m_oaBQBList.size() == 0) { if (m_IF.IsPL(BQB_PL_VERBOSE)) m_IF.eprintf("CBQBFile::SeekFrame(): Error: No entrys in list.\n"); return false; } if (m_iListIndex != -1) { if (m_IF.IsPL(BQB_PL_VERBOSE)) m_IF.printf(" List entry %d is currently open; closing.\n",m_iListIndex+1); if (!m_oaBQBList[m_iListIndex]->m_pFile->Close()) { m_IF.eprintf("CBQBFile::SeekFrame(): Error: Failed to close list entry %d.\n", m_iListIndex+1); return false; } } else if (m_IF.IsPL(BQB_PL_VERBOSE)) m_IF.printf(" No list entry is currently open.\n"); m_pShortFrame = NULL; // Deleted inside of the corresponding list entry k = 0; for (z=0;z<(int)m_oaBQBList.size();z++) { if (m_IF.IsPL(BQB_PL_VERBOSE)) m_IF.printf(" Processing list entry %d...\n",z+1); le = m_oaBQBList[z]; if (le->m_pIndex == NULL) { m_IF.eprintf("CBQBFile::SeekFrame(): Error: List entry %d does not contain an index.\n", z+1); return false; } if (i >= (int)le->m_pIndex->m_iaFrameLengths.size()+k) { k += (int)le->m_pIndex->m_iaFrameLengths.size(); if (m_IF.IsPL(BQB_PL_VERBOSE)) m_IF.printf(" Entry has %lu frames, so end of entry is frame %d, which is < %d.\n", le->m_pIndex->m_iaFrameLengths.size(),k,i); continue; } else { if (m_IF.IsPL(BQB_PL_VERBOSE)) m_IF.printf(" Entry has %lu frames, so end of entry is frame %d, which is >= %d --> Found.\n", le->m_pIndex->m_iaFrameLengths.size(),(int)le->m_pIndex->m_iaFrameLengths.size()+k,i); m_iListIndex = z; if (!m_oaBQBList[m_iListIndex]->m_pFile->OpenRead(m_oaBQBList[m_iListIndex]->m_sFileName)) { m_IF.eprintf("CBQBFile::SeekFrame(): Error: Could not open list entry %d for reading.\n", m_iListIndex+1); return false; } if (i-k != 0) { if (m_IF.IsPL(BQB_PL_VERBOSE)) m_IF.printf(" Seeking to frame %d of list entry %d...\n", i-k+1,m_iListIndex+1); if (!m_oaBQBList[m_iListIndex]->m_pFile->SeekFrame(i-k)) { m_IF.eprintf("CBQBFile::SeekFrame(): Error: Could not seek to frame %d within list entry %d.\n", i-k,m_iListIndex+1); return false; } } else if (m_IF.IsPL(BQB_PL_VERBOSE)) m_IF.printf(" Required frame is first frame of list entry %d, not seeking.\n", m_iListIndex+1); break; } } } else { if (m_IF.IsPL(BQB_PL_VERBOSE)) m_IF.printf(" Is a simple file.\n"); if (m_pFile == NULL) { m_IF.eprintf("CBQBFile::SeekFrame(): Error: File pointer is NULL.\n"); abort(); } if (m_pIndex == NULL) { m_IF.eprintf("CBQBFile::SeekFrame(): Error: File does not contain an index.\n"); abort(); } if (i >= (int)m_pIndex->m_iaFrameLengths.size()) { m_IF.eprintf("CBQBFile::SeekFrame(): Error: Tried to seek frame beyond index (%d/%lu).\n", i,m_pIndex->m_iaFrameLengths.size()); abort(); } ul = 0; for (z=0;zm_iaFrameLengths[z]; if (m_IF.IsPL(BQB_PL_VERBOSE)) m_IF.printf(" Offset of frame %d is %lu.\n",i,ul); fseek(m_pFile,ul,SEEK_SET); } if (m_IF.IsPL(BQB_PL_VERBOSE)) m_IF.printf("<<< CBQBFile::SeekFrame() i=%d <<<\n",i); return true; } bool CBQBFile::SkipFrames(int i) { int z; if (m_IF.IsPL(BQB_PL_VERBOSE)) m_IF.printf(">>> CBQBFile::SkipFrames() i=%d >>>\n",i); if (!m_bOpenRead) { m_IF.eprintf("CBQBFile::SkipFrames(): Error: File not open for reading.\n"); abort(); } for (z=0;z. ***********************************************************************************/ #ifndef BQB_FORMAT_H #define BQB_FORMAT_H // This must always be the first include directive #include "bqb_config.h" #include "bqb_math.h" #include "bqb_parmset.h" #include #include class CBQBInterface; /* Frame Types: 0 - Reserved 1 - General Container Frame 2 - Index Frame 3 - Compressed Index Frame 4 - Trajectory Frame 5 - Compressed Trajectory Frame 6 - Volumetric Data Frame 7 - Compressed Volumetric Data Frame */ #define BQB_FRAMETYPE_GENERAL (1) #define BQB_FRAMETYPE_IDX (2) #define BQB_FRAMETYPE_COMPIDX (3) #define BQB_FRAMETYPE_TRAJ (4) #define BQB_FRAMETYPE_COMPTRAJSTART (5) #define BQB_FRAMETYPE_COMPTRAJ (6) #define BQB_FRAMETYPE_CUBE (7) #define BQB_FRAMETYPE_COMPCUBESTART (8) #define BQB_FRAMETYPE_COMPCUBE (9) #define BQB_FRAMETYPE_FILE (10) #define BQB_FRAMETYPE_COMPFILE (11) #define BQB_FRAMETYPE_COMPTRAJKEY (12) #define BQB_FRAMETYPE_COMPCUBEKEY (13) #define BQB_TYPE_STRING (1) #define BQB_TYPE_FLOAT (2) #define BQB_TYPE_DOUBLE (3) #define BQB_TYPE_INT8 (4) #define BQB_TYPE_INT16 (5) #define BQB_TYPE_INT32 (6) #define BQB_TYPE_UINT8 (7) #define BQB_TYPE_UINT16 (8) #define BQB_TYPE_UINT32 (9) #define BQB_FRAMETYPE_COMPCUBE_VERSION (2) // Currently Version 2 #define BQB_FRAMETYPE_COMPTRAJ_VERSION (2) // Currently Version 2 #define BQB_FRAMETYPE_COMPFILE_VERSION (0) // Currently Version 0 #define BQB_FRAMETYPE_COMPIDX_VERSION (1) // Currently Version 1 //extern bool g_bBQBVerbose; class CBQBEngine; //void SetBQBVerbose(bool v); bool WriteArrayToFile(FILE *a, const std::vector &ia); bool ReadArrayFromFile(FILE *a, std::vector &ia, int length); void ReadArrayFromFile(FILE *a, std::vector &ia); class CBQBFile; class CBQBListEntry; class CBQBBitSet; const char *GetFrameTypeString(int type); class CBQBIndex { public: CBQBIndex(CBQBInterface &i) : m_IF(i) { } CBQBIndex(const CBQBIndex &bi) : m_iaFrameLengths(bi.m_iaFrameLengths), m_iaFrameTypes(bi.m_iaFrameTypes), m_IF(bi.m_IF) { } ~CBQBIndex() { } bool ImportFromArray(bool compressed, const std::vector &ia, int ver); bool ExportToArray(bool compressed, std::vector &ia, CBQBStatistics *stat); void Dump(); std::vector m_iaFrameLengths; std::vector m_iaFrameTypes; std::vector m_iaFrameIDs; private: CBQBInterface &m_IF; }; class CBQBShortFrame { public: CBQBShortFrame() : m_iFrameType(0), m_iFrameTypeVersion(0), m_iID(0), m_iCRC32(0) { } ~CBQBShortFrame() { } int m_iFrameType; int m_iFrameTypeVersion; int m_iID; unsigned long m_iCRC32; std::vector m_iaPayload; }; class CBQBListEntry { public: CBQBListEntry() : m_iFrameCount(-1), m_iFullFrameCount(-1), m_pIndex(NULL), m_pFile(NULL), m_iFrameStart(-1), m_iFrameEnd(-1) { } ~CBQBListEntry(); std::string m_sFileName; int m_iFrameCount; int m_iFullFrameCount; CBQBIndex *m_pIndex; CBQBFile *m_pFile; int m_iFrameStart; int m_iFrameEnd; }; class CBQBFile { public: CBQBFile(CBQBInterface &i) : m_oParmSetCube(i), m_oParmSetPos(i), m_pEngine(NULL), m_IF(i), m_bEOF(false), m_bShortFrame(false), m_bListFile(false), m_pFile(NULL), m_bOpenRead(false), m_bOpenWrite(false), m_pShortFrame(NULL), m_pIndex(NULL), m_iTotalFrameCount(-1) { } ~CBQBFile(); bool OpenRead(std::string s); bool OpenWriteAppend(std::string s); bool OpenWriteReplace(std::string s); bool Close(); bool Rewind(); bool SeekFrame(int i); bool SkipFrames(int i); bool IsEOF(); bool OpenListFile(FILE *a); // General Frame Functions bool CreateGeneralFrame(); // Short Frame Functions bool CreateShortFrame(int type, int version, int id); bool PushPayload(const std::vector &ia); bool FinalizeFrame(CBQBStatistics *stat); bool WriteIndexFrame(bool compressed, CBQBStatistics *stat); int GetFrameID() const; int GetFrameType() const; int GetFrameTypeVersion() const; const std::vector* GetFramePayload() const; void GetFileOffset(unsigned long &high, unsigned long &low); bool ReadFrame(); void DumpIndex(); bool CheckIntegrity(std::string s, bool verbose); bool CompareCoords(std::string infile, std::string reffile, bool verbose); int GetTotalFrameCount() const { return m_iTotalFrameCount; } CBQBEngine* GetEngine(); CBQBParameterSet_PosAndVol m_oParmSetCube; CBQBParameterSet_Position m_oParmSetPos; private: CBQBEngine *m_pEngine; CBQBInterface &m_IF; int m_iFrameCounter; bool m_bEOF; int m_iListIndex; std::vector m_oaBQBList; bool m_bShortFrame; bool m_bListFile; std::string m_sFileName; std::string m_sDirectory; FILE *m_pFile; bool m_bOpenRead; bool m_bOpenWrite; CBQBShortFrame *m_pShortFrame; CBQBIndex *m_pIndex; int m_iTotalFrameCount; }; class CBQBTrajectoryFrameColumn { public: CBQBTrajectoryFrameColumn(CBQBInterface &i) : m_iType(255), m_IF(i) { } CBQBTrajectoryFrameColumn(CBQBInterface &i, unsigned char type, std::string label) : m_iType(type), m_sLabel(label), m_IF(i) { } ~CBQBTrajectoryFrameColumn() { } bool ReadColumn(int ac, CBQBBitSet *bs); void WriteColumn(int ac, CBQBBitSet *bs); unsigned char m_iType; std::string m_sLabel; std::vector m_aString; std::vector m_aReal; std::vector m_aSignedInt; std::vector m_aUnsignedInt; private: CBQBInterface &m_IF; }; class CBQBTrajectoryFrame { public: CBQBTrajectoryFrame(CBQBInterface &i) : m_iAtomCount(0), m_pCellMatrix(NULL), m_IF(i) { } ~CBQBTrajectoryFrame() { int z; for (z=0;z<(int)m_oaColumns.size();z++) delete m_oaColumns[z]; if (m_pCellMatrix != NULL) { delete m_pCellMatrix; m_pCellMatrix = NULL; } } bool ReadFrame(const std::vector *data); void WriteFrame(std::vector *data); CBQBTrajectoryFrameColumn* GetColumn(std::string label); CBQBTrajectoryFrameColumn* AddColumn(int type, std::string label); unsigned long m_iAtomCount; std::vector m_oaColumns; CBQBDMatrix3 *m_pCellMatrix; private: CBQBInterface &m_IF; }; #endif travis-src-190101/src/bqb_hilbert.cpp0100777000000000000000000015142713412725630014427 0ustar00/*********************************************************************************** LibBQB - File Format and Compression Algorithms for Trajectories of Volumetric Data and Atom Positions https://brehm-research.de/bqb Free software, licensed under GNU LGPL v3 Copyright (c) Martin Brehm and Martin Thomas, Martin Luther University Halle-Wittenberg, Germany, 2016 - 2019. Please cite: M. Brehm, M. Thomas: "An Efficient Lossless Compression Algorithm for Trajectories of Atom Positions and Volumetric Data", J. Chem. Inf. Model. 2018, 58 (10), pp 2092-2107. -------------------------------------------------------------------------------- LibBQB is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program. If not, see . ***********************************************************************************/ // This must always be the first include directive #include "bqb_config.h" #include "bqb_hilbert.h" const char *GetRevisionInfo_bqb_hilbert(unsigned int len) { static char buf[256]; GET_REVISION_INFO( buf, len ); return buf; } const char *GetSourceVersion_bqb_hilbert() { static char buf[256]; GET_SOURCE_VERSION( buf ); return buf; } /* See LICENSE below for information on rights to use, modify and distribute this code. */ /* * hilbert.c - Computes Hilbert space-filling curve coordinates, without * recursion, from integer index, and vice versa, and other Hilbert-related * calculations. Also known as Pi-order or Peano scan. * * Author: Doug Moore * Dept. of Computational and Applied Math * Rice University * http://www.caam.rice.edu/~dougm * Date: Sun Feb 20 2000 * Copyright (c) 1998-2000, Rice University * * Acknowledgement: * This implementation is based on the work of A. R. Butz ("Alternative * Algorithm for Hilbert's Space-Filling Curve", IEEE Trans. Comp., April, * 1971, pp 424-426) and its interpretation by Spencer W. Thomas, University * of Michigan (http://www-personal.umich.edu/~spencer/Home.html) in his widely * available C software. While the implementation here differs considerably * from his, the first two interfaces and the style of some comments are very * much derived from his work. */ // MB 28.12.2017 #define HILBERT_CONFORMING /* implementation of the hilbert functions */ #ifdef HILBERT_CONFORMING #define adjust_rotation(rotation,nDims,bits) \ do { \ /* rotation = (rotation + 1 + ffs(bits)) % nDims; */ \ bits &= ((unsigned long)(-((signed long)bits))) & nd1Ones; \ while (bits) \ bits >>= 1, ++rotation; \ if ( ++rotation >= nDims ) \ rotation -= nDims; \ } while (0) #else #define adjust_rotation(rotation,nDims,bits) \ do { \ /* rotation = (rotation + 1 + ffs(bits)) % nDims; */ \ bits &= -bits & nd1Ones; \ while (bits) \ bits >>= 1, ++rotation; \ if ( ++rotation >= nDims ) \ rotation -= nDims; \ } while (0) #endif #define ones(T,k) ((((T)2) << (k-1)) - 1) #define rdbit(w,k) (((w) >> (k)) & 1) #define rotateRight(arg, nRots, nDims) \ ((((arg) >> (nRots)) | ((arg) << ((nDims)-(nRots)))) & ones(bitmask_t,nDims)) #define rotateLeft(arg, nRots, nDims) \ ((((arg) << (nRots)) | ((arg) >> ((nDims)-(nRots)))) & ones(bitmask_t,nDims)) #define DLOGB_BIT_TRANSPOSE static bitmask_t bitTranspose(unsigned nDims, unsigned nBits, bitmask_t inCoords) #if defined(DLOGB_BIT_TRANSPOSE) { unsigned const nDims1 = nDims-1; unsigned inB = nBits; unsigned utB; bitmask_t inFieldEnds = 1; bitmask_t inMask = ones(bitmask_t,inB); bitmask_t coords = 0; while ((utB = inB / 2)) { unsigned const shiftAmt = nDims1 * utB; bitmask_t const utFieldEnds = inFieldEnds | (inFieldEnds << (shiftAmt+utB)); bitmask_t const utMask = (utFieldEnds << utB) - utFieldEnds; bitmask_t utCoords = 0; unsigned d; if (inB & 1) { bitmask_t const inFieldStarts = inFieldEnds << (inB-1); unsigned oddShift = 2*shiftAmt; for (d = 0; d < nDims; ++d) { bitmask_t in = inCoords & inMask; inCoords >>= inB; coords |= (in & inFieldStarts) << oddShift++; in &= ~inFieldStarts; in = (in | (in << shiftAmt)) & utMask; utCoords |= in << (d*utB); } } else { for (d = 0; d < nDims; ++d) { bitmask_t in = inCoords & inMask; inCoords >>= inB; in = (in | (in << shiftAmt)) & utMask; utCoords |= in << (d*utB); } } inCoords = utCoords; inB = utB; inFieldEnds = utFieldEnds; inMask = utMask; } coords |= inCoords; return coords; } #else { bitmask_t coords = 0; unsigned d; for (d = 0; d < nDims; ++d) { unsigned b; bitmask_t in = inCoords & ones(bitmask_t,nBits); bitmask_t out = 0; inCoords >>= nBits; for (b = nBits; b--;) { out <<= nDims; out |= rdbit(in, b); } coords |= out << d; } return coords; } #endif /***************************************************************** * hilbert_i2c * * Convert an index into a Hilbert curve to a set of coordinates. * Inputs: * nDims: Number of coordinate axes. * nBits: Number of bits per axis. * index: The index, contains nDims*nBits bits * (so nDims*nBits must be <= 8*sizeof(bitmask_t)). * Outputs: * coord: The list of nDims coordinates, each with nBits bits. * Assumptions: * nDims*nBits <= (sizeof index) * (bits_per_byte) */ void hilbert_i2c(unsigned nDims, unsigned nBits, bitmask_t index, bitmask_t coord[]) { if (nDims > 1) { bitmask_t coords; halfmask_t const nbOnes = ones(halfmask_t,nBits); unsigned d; if (nBits > 1) { unsigned const nDimsBits = nDims*nBits; halfmask_t const ndOnes = ones(halfmask_t,nDims); halfmask_t const nd1Ones= ndOnes >> 1; /* for adjust_rotation */ unsigned b = nDimsBits; unsigned rotation = 0; halfmask_t flipBit = 0; bitmask_t const nthbits = ones(bitmask_t,nDimsBits) / ndOnes; index ^= (index ^ nthbits) >> 1; coords = 0; do { halfmask_t bits = (index >> (b-=nDims)) & ndOnes; coords <<= nDims; coords |= rotateLeft(bits, rotation, nDims) ^ flipBit; flipBit = (halfmask_t)1 << rotation; adjust_rotation(rotation,nDims,bits); } while (b); for (b = nDims; b < nDimsBits; b *= 2) coords ^= coords >> b; coords = bitTranspose(nBits, nDims, coords); } else coords = index ^ (index >> 1); for (d = 0; d < nDims; ++d) { coord[d] = coords & nbOnes; coords >>= nBits; } } else coord[0] = index; } /***************************************************************** * hilbert_c2i * * Convert coordinates of a point on a Hilbert curve to its index. * Inputs: * nDims: Number of coordinates. * nBits: Number of bits/coordinate. * coord: Array of n nBits-bit coordinates. * Outputs: * index: Output index value. nDims*nBits bits. * Assumptions: * nDims*nBits <= (sizeof bitmask_t) * (bits_per_byte) */ bitmask_t hilbert_c2i(unsigned nDims, unsigned nBits, bitmask_t const coord[]) { if (nDims > 1) { unsigned const nDimsBits = nDims*nBits; bitmask_t index; unsigned d; bitmask_t coords = 0; for (d = nDims; d--; ) { coords <<= nBits; coords |= coord[d]; } if (nBits > 1) { halfmask_t const ndOnes = ones(halfmask_t,nDims); halfmask_t const nd1Ones= ndOnes >> 1; /* for adjust_rotation */ unsigned b = nDimsBits; unsigned rotation = 0; halfmask_t flipBit = 0; bitmask_t const nthbits = ones(bitmask_t,nDimsBits) / ndOnes; coords = bitTranspose(nDims, nBits, coords); coords ^= coords >> nDims; index = 0; do { halfmask_t bits = (coords >> (b-=nDims)) & ndOnes; bits = rotateRight(flipBit ^ bits, rotation, nDims); index <<= nDims; index |= bits; flipBit = (halfmask_t)1 << rotation; adjust_rotation(rotation,nDims,bits); } while (b); index ^= nthbits >> 1; } else index = coords; for (d = 1; d < nDimsBits; d *= 2) index ^= index >> d; return index; } else return coord[0]; } /***************************************************************** * Readers and writers of bits */ typedef bitmask_t (*BitReader) (unsigned nDims, unsigned nBytes, char const* c, unsigned y); typedef void (*BitWriter) (unsigned d, unsigned nBytes, char* c, unsigned y, int fold); #if defined(sparc) #define __BIG_ENDIAN__ #endif #if defined(__BIG_ENDIAN__) #define whichByte(nBytes,y) (nBytes-1-y/8) #define setBytes(dst,pos,nBytes,val) \ memset(&dst[pos+1],val,nBytes-pos-1) #else #define whichByte(nBytes,y) (y/8) #define setBytes(dst,pos,nBytes,val) \ memset(&dst[0],val,pos) #endif static bitmask_t getIntBits(unsigned nDims, unsigned nBytes, char const* c, unsigned y) { unsigned const bit = y%8; unsigned const offs = whichByte(nBytes,y); unsigned d; bitmask_t bits = 0; c += offs; for (d = 0; d < nDims; ++d) { bits |= rdbit(*c, bit) << d; c += nBytes; } return bits; } #include static void propogateIntBits(unsigned d, unsigned nBytes, char* c, unsigned y, int fold) { unsigned const byteId = whichByte(nBytes,y); unsigned const b = y%8; char const bthbit = 1 << b; char* const target = &c[d*nBytes]; target[byteId] ^= bthbit; if (!fold) { char notbit = ((target[byteId] >> b) & 1) - 1; if (notbit) target[byteId] |= bthbit-1; else target[byteId] &= -bthbit; setBytes(target,byteId,nBytes,notbit); } } /* An IEEE double is treated as a 2100 bit number. In particular, 0 is treated as a 1 followed by 2099 zeroes, and negative 0 as a 0 followed by 2099 ones. Only 53 bits differ between a number and a zero of the same sign, with the position of the 53 determined by the exponent, and the values of the 53 by the significand (with implicit leading 1 bit). Although IEEE 754 uses the maximum exponent for NaN's and infinities, this implementation ignores that decision, so that infinities and NaN's are treated as very large numbers. Note that we do not explicitly construct a 2100 bit bitmask in the IEEE routines below. */ enum { IEEEexpBits = 11 }; enum { IEEEsigBits = 52 }; enum { IEEErepBits = (1 << IEEEexpBits) + IEEEsigBits }; typedef union ieee754_double { double d; /* This is the IEEE 754 double-precision format. */ struct { #if defined(__BIG_ENDIAN__) unsigned int negative:1; unsigned int exponent:11; /* Together these comprise the mantissa. */ unsigned int mantissa0:20; unsigned int mantissa1:32; #else /* Big endian. */ /* Together these comprise the mantissa. */ unsigned int mantissa1:32; unsigned int mantissa0:20; unsigned int exponent:11; unsigned int negative:1; #endif /* Little endian. */ } ieee; } ieee754_double; static bitmask_t getIEEESignBits(unsigned nDims, double const* c) { unsigned d; ieee754_double x; bitmask_t bits = 0; for (d = 0; d < nDims; ++d) { x.d = c[d]; bits |= x.ieee.negative << d; } return bits; } static bitmask_t getIEEEBits(unsigned nDims, unsigned ignoreMe, /* ignored */ char const* cP, unsigned y) /* retrieve bits y of elements of double array c, where an expanded IEEE double has 2100 bits. */ { UNUSED(ignoreMe); unsigned d; double const* c = (double const*) cP; ieee754_double x; bitmask_t bits = 0; for (x.d = c[d=0]; d < nDims; x.d = c[++d]) { bitmask_t bit = x.ieee.negative; unsigned normalized = (x.ieee.exponent != 0); unsigned diff = y - (x.ieee.exponent - normalized); if (diff <= 52) bit ^= 1 & ((diff < 32)? x.ieee.mantissa1 >> diff: (diff < 52)? x.ieee.mantissa0 >> (diff - 32): /* else */ normalized); else bit ^= (y == IEEErepBits-1); bits |= bit << d; } return bits; } static void propogateIEEEBits(unsigned d, unsigned nBytes, char* cP, unsigned y, int fold) { UNUSED(nBytes); UNUSED(fold); ieee754_double* x = d + (ieee754_double*) cP; unsigned normalized = (x->ieee.exponent != 0); unsigned diff = y - (x->ieee.exponent - normalized); if (diff < 32) { unsigned b = 1 << diff; unsigned bit = x->ieee.mantissa1 & b; x->ieee.mantissa1 &= ~(b-1); x->ieee.mantissa1 |= b; if (bit) --x->ieee.mantissa1; } else if (diff < 52) { unsigned b = 1 << (diff - 32); unsigned bit = x->ieee.mantissa0 & b; x->ieee.mantissa0 &= ~(b-1); x->ieee.mantissa0 |= b; if (bit) --x->ieee.mantissa0; x->ieee.mantissa1 = bit?-1: 0; } else if (diff == 52) /* "flip" the implicit 1 bit */ { if (normalized) --x->ieee.exponent; else x->ieee.exponent = 1; #ifdef HILBERT_CONFORMING x->ieee.mantissa0 = (unsigned)(-((signed)normalized)); x->ieee.mantissa1 = (unsigned)(-((signed)normalized)); #else x->ieee.mantissa0 = -normalized; x->ieee.mantissa1 = -normalized; #endif } else if (diff < IEEErepBits) { if (y == IEEErepBits-1) { x->ieee.negative ^= 1; x->ieee.exponent = 0; } else x->ieee.exponent = y - 51; x->ieee.mantissa0 = 0; x->ieee.mantissa1 = 0; } } static unsigned getIEEEexptMax(unsigned nDims, double const* c) { unsigned max = 0; unsigned d; for (d = 0; d < nDims; ++d) { ieee754_double x; x.d = c[d]; if (max < x.ieee.exponent) max = x.ieee.exponent; } if (max) --max; return max; } static void getIEEEinitValues(double const* c1, unsigned y, unsigned nDims, unsigned* rotation, bitmask_t* bits, bitmask_t* index) { bitmask_t const one = 1; unsigned d; bitmask_t signBits = getIEEESignBits(nDims, c1); unsigned signParity, leastZeroBit, strayBit; /* compute the odd/evenness of the number of sign bits */ { bitmask_t signPar = signBits; for (d = 1; d < nDims; d *= 2) signPar ^= signPar >> d; signParity = signPar & 1; } /* find the position of the least-order 0 bit in among signBits and adjust it if necessary */ for (leastZeroBit = 0; leastZeroBit < nDims; ++leastZeroBit) if (rdbit(signBits, leastZeroBit) == 0) break; strayBit = 0; if (leastZeroBit == nDims-2) strayBit = 1; else if (leastZeroBit == nDims) leastZeroBit = nDims-1; if (y % 2 == 1) { *rotation = (IEEErepBits - y + 1 + leastZeroBit) % nDims; if (y < IEEErepBits-1) { *bits = signBits ^ (one << ((*rotation + strayBit) % nDims)); *index = signParity; } else /* y == IEEErepBits-1 */ { *bits = signBits ^ (ones(bitmask_t,nDims) &~ 1); *index = signParity ^ (nDims&1); } } else /* y % 2 == 0 */ if (y < IEEErepBits) { unsigned shift_amt = (IEEErepBits - y + leastZeroBit) % nDims; *rotation = (shift_amt + 2 + strayBit) % nDims; *bits = signBits ^ (one << shift_amt); *index = signParity ^ 1; } else /* y == IEEErepBits */ { *rotation = 0; *bits = one << (nDims-1); *index = 1; } } /***************************************************************** * hilbert_cmp, hilbert_ieee_cmp * * Determine which of two points lies further along the Hilbert curve * Inputs: * nDims: Number of coordinates. * nBytes: Number of bytes of storage/coordinate (hilbert_cmp only) * nBits: Number of bits/coordinate. (hilbert_cmp only) * coord1: Array of nDims nBytes-byte coordinates (or doubles for ieee_cmp). * coord2: Array of nDims nBytes-byte coordinates (or doubles for ieee_cmp). * Return value: * -1, 0, or 1 according to whether coord1coord2 * Assumptions: * nBits <= (sizeof bitmask_t) * (bits_per_byte) */ static int hilbert_cmp_work(unsigned nDims, unsigned nBytes, unsigned nBits, unsigned max, unsigned y, char const* c1, char const* c2, unsigned rotation, bitmask_t bits, bitmask_t index, BitReader getBits) { bitmask_t const one = 1; bitmask_t const nd1Ones = ones(bitmask_t,nDims) >> 1; /* used in adjust_rotation macro */ while (y-- > max) { bitmask_t reflection = getBits(nDims, nBytes, c1, y); bitmask_t diff = reflection ^ getBits(nDims, nBytes, c2, y); bits ^= reflection; bits = rotateRight(bits, rotation, nDims); if (diff) { unsigned d; diff = rotateRight(diff, rotation, nDims); for (d = 1; d < nDims; d *= 2) { index ^= index >> d; bits ^= bits >> d; diff ^= diff >> d; } return (((index ^ y ^ nBits) & 1) == (bits < (bits^diff)))? -1: 1; } index ^= bits; reflection ^= one << rotation; adjust_rotation(rotation,nDims,bits); bits = reflection; } return 0; } int hilbert_cmp(unsigned nDims, unsigned nBytes, unsigned nBits, void const* c1, void const* c2) { bitmask_t const one = 1; bitmask_t bits = one << (nDims-1); return hilbert_cmp_work(nDims, nBytes, nBits, 0, nBits, (char const*)c1, (char const*)c2, 0, bits, bits, getIntBits); } int hilbert_ieee_cmp(unsigned nDims, double const* c1, double const* c2) { unsigned rotation, max; bitmask_t bits, index; if (getIEEESignBits(nDims, c1) != getIEEESignBits(nDims, c2)) max = 2047; else { unsigned max1 = getIEEEexptMax(nDims, c1); unsigned max2 = getIEEEexptMax(nDims, c2); max = (max1 > max2)? max1: max2; } getIEEEinitValues(c1, max+53, nDims, &rotation, &bits, &index); return hilbert_cmp_work(nDims, 8, 64, max, max+53, (char const*)c1, (char const*)c2, rotation, bits, index, getIEEEBits); } /***************************************************************** * hilbert_box_vtx * * Determine the first or last vertex of a box to lie on a Hilbert curve * Inputs: * nDims: Number of coordinates. * nBytes: Number of bytes/coordinate. * nBits: Number of bits/coordinate. * findMin: Is it the least vertex sought? * coord1: Array of nDims nBytes-byte coordinates - one corner of box * coord2: Array of nDims nBytes-byte coordinates - opposite corner * Output: * c1 and c2 modified to refer to selected corner * value returned is log2 of size of largest power-of-two-aligned box that * contains the selected corner and no other corners * Assumptions: * nBits <= (sizeof bitmask_t) * (bits_per_byte) */ static unsigned hilbert_box_vtx_work(unsigned nDims, unsigned nBytes, unsigned nBits, int findMin, unsigned max, unsigned y, char* c1, char* c2, unsigned rotation, bitmask_t bits, bitmask_t index, BitReader getBits) { UNUSED(nBits); UNUSED(max); bitmask_t const one = 1; bitmask_t const ndOnes = ones(bitmask_t,nDims); bitmask_t const nd1Ones= ndOnes >> 1; bitmask_t bitsFolded = 0; while (y--) { bitmask_t reflection = getBits(nDims, nBytes, c1, y); bitmask_t diff = reflection ^ getBits(nDims, nBytes, c2, y); if (diff) { unsigned d; bitmask_t smear = rotateRight(diff, rotation, nDims) >> 1; bitmask_t digit = rotateRight(bits ^ reflection, rotation, nDims); for (d = 1; d < nDims; d *= 2) { index ^= index >> d; digit ^= (digit >> d) &~ smear; smear |= smear >> d; } index &= 1; if ((index ^ y ^ findMin) & 1) digit ^= smear+1; digit = rotateLeft(digit, rotation, nDims) & diff; reflection ^= digit; for (d = 0; d < nDims; ++d) if (rdbit(diff, d)) { int way = rdbit(digit, d); char* target = d*nBytes + (way? c1: c2); char* const source = 2*d*nBytes + c1 - target + c2; memcpy(target, source, nBytes); } bitsFolded |= diff; if (bitsFolded == ndOnes) return y; } bits ^= reflection; bits = rotateRight(bits, rotation, nDims); index ^= bits; reflection ^= one << rotation; adjust_rotation(rotation,nDims,bits); bits = reflection; } return y; } unsigned hilbert_box_vtx(unsigned nDims, unsigned nBytes, unsigned nBits, int findMin, void* c1, void* c2) { bitmask_t const one = 1; bitmask_t bits = one << (nDims-1); return hilbert_box_vtx_work(nDims, nBytes, nBits, findMin, 0, nBits, (char*)c1, (char*)c2, 0, bits, bits, getIntBits); } unsigned hilbert_ieee_box_vtx(unsigned nDims, int findMin, double* c1, double* c2) { unsigned rotation, max; bitmask_t bits, index; if (getIEEESignBits(nDims, c1) != getIEEESignBits(nDims, c2)) max = 2047; else { unsigned max1 = getIEEEexptMax(nDims, c1); unsigned max2 = getIEEEexptMax(nDims, c2); max = (max1 > max2)? max1: max2; } getIEEEinitValues(c1, max+53, nDims, &rotation, &bits, &index); return hilbert_box_vtx_work(nDims, 8, 64, findMin, max, max+53, (char *)c1, (char *)c2, rotation, bits, index, getIEEEBits); } /***************************************************************** * hilbert_box_pt * * Determine the first or last point of a box to lie on a Hilbert curve * Inputs: * nDims: Number of coordinates. * nBytes: Number of bytes/coordinate. * nBits: Number of bits/coordinate. * findMin: Is it the least vertex sought? * coord1: Array of nDims nBytes-byte coordinates - one corner of box * coord2: Array of nDims nBytes-byte coordinates - opposite corner * Output: * c1 and c2 modified to refer to least point * Assumptions: * nBits <= (sizeof bitmask_t) * (bits_per_byte) */ unsigned hilbert_box_pt_work(unsigned nDims, unsigned nBytes, unsigned nBits, int findMin, unsigned max, unsigned y, char* c1, char* c2, unsigned rotation, bitmask_t bits, bitmask_t index, BitReader getBits, BitWriter propogateBits) { UNUSED(nBits); bitmask_t const one = 1; bitmask_t const nd1Ones = ones(bitmask_t,nDims) >> 1; bitmask_t fold1 = 0, fold2 = 0; unsigned smearSum = 0; while (y-- > max) { bitmask_t reflection = getBits(nDims, nBytes, c1, y); bitmask_t diff = reflection ^ getBits(nDims, nBytes, c2, y); if (diff) { bitmask_t smear = rotateRight(diff, rotation, nDims) >> 1; bitmask_t digit = rotateRight(bits ^ reflection, rotation, nDims); unsigned d; for (d = 1; d < nDims; d *= 2) { index ^= index >> d; digit ^= (digit >> d) &~ smear; smear |= smear >> d; } smearSum += smear; index &= 1; if ((index ^ y ^ findMin) & 1) digit ^= smear+1; digit = rotateLeft(digit, rotation, nDims) & diff; reflection ^= digit; for (d = 0; d < nDims; ++d) if (rdbit(diff, d)) { int way = rdbit(digit, d); char* c = way? c1: c2; bitmask_t fold = way? fold1: fold2; propogateBits(d, nBytes, c, y, rdbit(fold, d)); } diff ^= digit; fold1 |= digit; fold2 |= diff; } bits ^= reflection; bits = rotateRight(bits, rotation, nDims); index ^= bits; reflection ^= one << rotation; adjust_rotation(rotation,nDims,bits); bits = reflection; } return smearSum; } unsigned hilbert_box_pt(unsigned nDims, unsigned nBytes, unsigned nBits, int findMin, void* c1, void* c2) { bitmask_t const one = 1; bitmask_t bits = one << (nDims-1); return hilbert_box_pt_work(nDims, nBytes, nBits, findMin, 0, nBits, (char*)c1, (char*)c2, 0, bits, bits, getIntBits, propogateIntBits); } unsigned hilbert_ieee_box_pt(unsigned nDims, int findMin, double* c1, double* c2) { unsigned rotation, max; bitmask_t bits, index; bitmask_t c1Signs = getIEEESignBits(nDims, c1); bitmask_t c2Signs = getIEEESignBits(nDims, c2); if (c1Signs != c2Signs) { rotation = 0; bits = (bitmask_t)1 << (nDims-1); index = 1; hilbert_box_pt_work(nDims, 8, 64, findMin, IEEErepBits-1, IEEErepBits, (char *)c1, (char *)c2, rotation, bits, index, getIEEEBits, propogateIEEEBits); } /* having put everything in the same orthant, start */ { unsigned max1 = getIEEEexptMax(nDims, c1); unsigned max2 = getIEEEexptMax(nDims, c2); max = (max1 > max2)? max1: max2; } getIEEEinitValues(c1, max+53, nDims, &rotation, &bits, &index); return hilbert_box_pt_work(nDims, 8, 64, findMin, max, max+53, (char *)c1, (char *)c2, rotation, bits, index, getIEEEBits, propogateIEEEBits); } /***************************************************************** * hilbert_nextinbox * * Determine the first point of a box after or before a given point to lie on * a Hilbert curve * Inputs: * nDims: Number of coordinates. * nBytes: Number of bytes/coordinate. * nBits: Number of bits/coordinate. * findPrev: Is it a previous point that you want? * coord1: Array of nDims nBytes-byte coordinates - one corner of box * coord2: Array of nDims nBytes-byte coordinates - opposite corner * point: Array of nDims nBytes-byte coordinates - lower bound on point returned * * Output: if returns 1: * c1 and c2 modified to refer to least point after "point" in box else returns 0: arguments unchanged; "point" is beyond the last point of the box * Assumptions: * nBits <= (sizeof bitmask_t) * (bits_per_byte) */ int hilbert_nextinbox(unsigned nDims, unsigned nBytes, unsigned nBits, int findPrev, void* c1V, void* c2V, void const* ptV) { bitmask_t const one = 1; unsigned y = nBits; bitmask_t const ndOnes = ones(bitmask_t,nDims); bitmask_t const nd1Ones = ndOnes >> 1; unsigned rotation = 0; bitmask_t bits = 0; bitmask_t index = 0; bitmask_t fold1 = 0, fold2 = 0; bitmask_t valu1 = 0, valu2 = 0; unsigned p_y = 0; bitmask_t p_separator = 0, p_firstSeparator = 0; bitmask_t p_cornerdiff = 0, p_reflection = 0; bitmask_t p_fold1 = 0, p_fold2 = 0, p_valu1 = 0, p_valu2 = 0; char* c1 = (char*)c1V; char* c2 = (char*)c2V; char const* pt = (const char*)ptV; while (y-- > 0) { bitmask_t reflection = getIntBits(nDims, nBytes, pt, y); bitmask_t diff = reflection ^ /* planes that separate box and point */ ((getIntBits(nDims, nBytes, c1, y) &~ fold1) | valu1); if (diff) /* some coordinate planes separate point from box or dividing box or both; smear the bits of diff to reflect that after the first diff dimension, they might as well all be diffing; adjust the diff to reflect the fact that diffed dimensions don't matter. */ { /* compute (the complement of) a "digit" in the integer index of this point */ bitmask_t cornerdiff = (diff ^ reflection) ^ /* separate box crnrs */ ((getIntBits(nDims, nBytes, c2, y) &~ fold2) | valu2); bitmask_t separator = diff & ~cornerdiff; /* eventually, the most significant separating cutting plane */ bitmask_t firstSeparator; /* bits less significant than the msb of separator are irrelevant; for convenience, call them all separators too */ bitmask_t rotSep = rotateRight(separator, rotation, nDims); /* compute the (complement of the) digit of the hilbert code assoc with point */ bitmask_t digit = rotateRight(bits ^ reflection, rotation, nDims); unsigned d; for (d = 1; d < nDims; d *= 2) { index ^= index >> d; digit ^= digit >> d; rotSep |= rotSep >> d; } index &= 1; digit &= rotSep; if ((index ^ y ^ findPrev) & 1) digit ^= rotSep; separator = rotateLeft(rotSep, rotation, nDims); rotSep -= rotSep >> 1; firstSeparator = rotateLeft(rotSep, rotation, nDims); /* forget about all the planes that split the box, except those that are more significant than the most significant separator. */ cornerdiff &= ~separator; if (cornerdiff && digit) /* some coordinate planes divide the box. Call the part of the box in the same orthant as the point "here" and the part of the box in the next (or previous) orthant "there". Remember what the "there" orthant of the box looks like in case it turns out that the curve doesn't reenter the box "here" after (before) passing thru point. Continue working with the "here" part. If there is no "there" there, skip it */ { #ifdef HILBERT_CONFORMING p_firstSeparator = digit & ((unsigned long)(-((signed long)digit))); #else p_firstSeparator = digit & -digit; #endif p_separator = 2*p_firstSeparator-1; p_separator = rotateLeft(p_separator, rotation, nDims); p_firstSeparator = rotateLeft(p_firstSeparator, rotation, nDims); p_cornerdiff = cornerdiff &~ (p_separator ^ p_firstSeparator); p_y = y; p_reflection = reflection ^ p_firstSeparator; p_fold1 = fold1; p_fold2 = fold2; p_valu1 = valu1; p_valu2 = valu2; } if (digit < rotSep) /* use next box */ { if (!p_separator) return 0; /* no next point */ separator = p_separator; firstSeparator = p_firstSeparator; y = p_y; cornerdiff = p_cornerdiff; reflection = p_reflection; fold1 = p_fold1; fold2 = p_fold2; valu1 = p_valu1; valu2 = p_valu2; } if (cornerdiff) { /* reduce currbox */ bitmask_t corner = diff & cornerdiff; cornerdiff ^= corner; fold1 |= corner; fold2 |= cornerdiff; valu1 |= ~reflection & corner; valu2 |= ~reflection & cornerdiff; } separator ^= firstSeparator; if (firstSeparator) /* we have completely separated the point from a part of the box ahead of it on the curve; almost done */ { unsigned byteId = whichByte(nBytes,y); bitmask_t bthbit = one << y%8; for (d = 0; d < nDims; ++d) { char lo1, lo2; char* cc1 = &c1[d*nBytes]; char* cc2 = &c2[d*nBytes]; char const* pnt = &pt[d*nBytes]; #ifdef HILBERT_CONFORMING char hibits = -((char)bthbit); #else char hibits = -bthbit; #endif char hipart = pnt[byteId] & hibits; memcpy(cc1, pnt, byteId); memcpy(cc2, pnt, byteId); if (rdbit(separator, d)) hibits ^= bthbit; if (rdbit(firstSeparator, d)) hipart ^= bthbit; if (rdbit(fold1, d)) { #ifdef HILBERT_CONFORMING lo1 = -((char)rdbit(valu1, d)); #else lo1 = -rdbit(valu1, d); #endif setBytes(cc1,byteId,nBytes,lo1); } else lo1 = cc1[byteId]; cc1[byteId] = hipart | (lo1 &~ hibits); if (rdbit(fold2, d)) { #ifdef HILBERT_CONFORMING lo2 = -((char)rdbit(valu2, d)); #else lo2 = -rdbit(valu2, d); #endif setBytes(cc2,byteId,nBytes,lo2); } else lo2 = cc2[byteId]; cc2[byteId] = hipart | (lo2 &~ hibits); } hilbert_box_pt(nDims, nBytes, nBits, !findPrev, c1V, c2V); return 1; } } bits ^= reflection; bits = rotateRight(bits, rotation, nDims); index ^= bits; reflection ^= one << rotation; adjust_rotation(rotation,nDims,bits); bits = reflection; } /* point is in box */ { unsigned d; for (d = 0; d < nDims; ++d) ((char*)c1)[d] = ((char*)c2)[d] = ((char*)pt)[d]; } return 1; } /***************************************************************** * hilbert_incr * * Advance from one point to its successor on a Hilbert curve * Inputs: * nDims: Number of coordinates. * nBits: Number of bits/coordinate. * coord: Array of nDims nBits-bit coordinates. * Output: * coord: Next point on Hilbert curve * Assumptions: * nBits <= (sizeof bitmask_t) * (bits_per_byte) */ void hilbert_incr(unsigned nDims, unsigned nBits, bitmask_t coord[]) { bitmask_t const one = 1; bitmask_t const ndOnes = ones(bitmask_t,nDims); bitmask_t const nd1Ones= ndOnes >> 1; unsigned b, d; unsigned rotation = 0; bitmask_t reflection = 0; bitmask_t index = 0; unsigned rb = nBits-1; bitmask_t rd = ndOnes; for (b = nBits; b--;) { bitmask_t bits = reflection; reflection = 0; for (d = 0; d < nDims; ++d) reflection |= rdbit(coord[d], b) << d; bits ^= reflection; bits = rotateRight(bits, rotation, nDims); index ^= bits; for (d = 1; d < nDims; d *= 2) index ^= index >> d; if (index++ != ndOnes) { rb = b; #ifdef HILBERT_CONFORMING rd = index & ((unsigned long)(-((signed long)index))); #else rd = index & -index; #endif rd = rotateLeft(rd, rotation, nDims); } index &= 1; index <<= nDims-1; reflection ^= one << rotation; adjust_rotation(rotation,nDims,bits); } for (d = 0; !rdbit(rd, d); ++d) {} coord[d] ^= (2 << rb) - 1; } /* LICENSE * * This software is copyrighted by Rice University. It may be freely copied, * modified, and redistributed, provided that the copyright notice is * preserved on all copies. * * There is no warranty or other guarantee of fitness for this software, * it is provided solely "as is". Bug reports or fixes may be sent * to the author, who may or may not act on them as he desires. * * You may include this software in a program or other software product, * but must display the notice: * * Hilbert Curve implementation copyright 1998, Rice University * * in any place where the end-user would see your own copyright. * * If you modify this software, you should include a notice giving the * name of the person performing the modification, the date of modification, * and the reason for such modification. */ /* Revision history: July 1998: Initial release Sept 1998: Second release Dec 1998: Fixed bug in hilbert_c2i that allowed a shift by number of bits in bitmask to vaporize index, in last bit of the function. Implemented hilbert_incr. August 1999: Added argument to hilbert_nextinbox so that you can, optionally, find the previous point along the curve to intersect the box, rather than the next point. Nov 1999: Defined fast bit-transpose function (fast, at least, if the number of bits is large), and reimplemented i2c and c2i in terms of it. Collapsed loops in hilbert_cmp, with the intention of reusing the cmp code to compare more general bitstreams. Feb 2000: Implemented almost all the floating point versions of cmp, etc, so that coordinates expressed in terms of double-precision IEEE floating point can be ordered. Still have to do next-in-box, though. Oct 2001: Learned that some arbitrary coding choices caused some routines to fail in one dimension, and changed those choices. version 2001-10-20-05:34 */ /* What remains is test code that won't be compiled unless you define the TEST_HILBERT preprocessor symbol */ #ifdef TEST_HILBERT #include #define abs(x) (((x)>=0)?(x):(-(x))) int main() { #define maxDim (8*sizeof(bitmask_t)) bitmask_t coord[maxDim], coordPrev[maxDim]; unsigned nDims, nBits, nPrints, orderCheck, i; bitmask_t r, r1; for (;;) { m_IF.printf( "Enter nDims, nBits, nPrints, orderCheck: " ); scanf( "%d", &nDims); if ( nDims == 0 ) break; scanf( "%d%d%d", &nBits, &nPrints, &orderCheck); while ( (i = getchar()) != '\n' && i != EOF ) ; if ( i == EOF ) break; if (nDims*nBits > 8*sizeof(r)) { m_IF.printf("Product of nDims and nBits not exceed %d.\n", 8*sizeof(r)); break; } if (nBits == 0) { m_IF.printf("nBits must be positive.\n"); break; } if (nPrints > (1ULL << (nDims*nBits))) nPrints = 1ULL << (nDims*nBits); for (r = 0; r < nPrints; ++r) { bitmask_t coord1[maxDim]; int miscount = 0; hilbert_i2c( nDims, nBits, r, coord ); m_IF.printf("%d: ", (unsigned)r); for (i = 0; i < nDims; ++i) { int diff = (int)(coord[i] - coordPrev[i]); miscount += abs(diff); coordPrev[i] = coord[i]; m_IF.printf(" %d", (unsigned)coord[i]); } if (r > 0 && miscount != 1) m_IF.printf(".....error"); m_IF.printf("\n"); r1 = hilbert_c2i( nDims, nBits, coord ); if ( r != r1 ) m_IF.printf( "r = 0x%x; r1 = 0x%x\n", (unsigned)r, (unsigned)r1); for (i = 0; i < nDims; ++i) coord[i] = coordPrev[i]; if (! orderCheck) continue; for (r1 = 0; r1 < r; ++r1 ) { unsigned ans; hilbert_i2c( nDims, nBits, r1, coord1 ); ans = hilbert_cmp( nDims, sizeof(coord[0]), nBits, coord, coord1); if (ans != 1) { int width = (nDims*nBits + 3) / 4; m_IF.printf( "cmp r = 0x%0*x; r1 = 0x%0*x, ans = %2d\n", width, (unsigned)r, width, (unsigned)r1, ans ); } } hilbert_i2c( nDims, nBits, r1, coord1 ); if (hilbert_cmp( nDims, sizeof(coord[0]), nBits, coord, coord1) != 0) m_IF.printf( "cmp r = 0x%0*x; r1 = 0x%0*x\n", (nDims*nBits+3)/4, (unsigned)r, (nDims*nBits+3)/4, (unsigned)r1 ); } } return 0; } #endif #ifdef TEST_IEEE #include #include #include int cmp(const void* xv, const void* yv) { double const* x = xv; double const* y = yv; /* return hilbert_cmp(2, 8, 64, x, y); */ return hilbert_ieee_cmp(2, x, y); } int main() { double *a; unsigned i; unsigned n; m_IF.printf("How many points? "); scanf("%d", &n); a = (double*) malloc(2*n*sizeof(double)); for (i = 0; i < n; ++i) a[2*i] = drand48()-0.5, a[2*i+1] = drand48()-0.5; qsort(a, n, 2*sizeof(double), cmp); for (i = 0; i < n; ++i) m_IF.printf("%8g %8g\n", a[2*i], a[2*i+1]); free(a); return 0; } #endif #ifdef TEST_CMP #include #define maxDim (8*sizeof(bitmask_t)) int main() { double coord[maxDim]; unsigned nDims, i, k; m_IF.printf( "Enter nDims: " ); scanf( "%d", &nDims); if ( nDims == 0 ) return 0; while ( (i = getchar()) != '\n' && i != EOF ) ; if ( i == EOF ) return 0; for (k = 0; k < (1<>i)&1)? -1.: 1.; hilbert_ieee_cmp( nDims, coord, coord); } return 0; } #endif #ifdef TEST_VTX #include #include #define maxDim (8*sizeof(bitmask_t)) unsigned g_nDims; int cmp(void const* c1p, void const* c2p) { return hilbert_cmp(g_nDims, sizeof(unsigned), 8*sizeof(unsigned), c1p, c2p); } int main() { unsigned corner0[maxDim], corner1[maxDim]; unsigned cornerlo[maxDim], cornerhi[maxDim], work[maxDim]; typedef unsigned array_t[maxDim]; array_t* array; unsigned nDims, i, k; m_IF.printf( "Enter nDims: " ); scanf( "%d", &nDims); if ( nDims == 0 ) return 0; while ( (i = getchar()) != '\n' && i != EOF ) ; if ( i == EOF ) return 0; m_IF.printf("Enter one corner (%d coordinates): ", nDims); for (k = 0; k < nDims; ++k) scanf("%d", &corner0[k]); m_IF.printf("Enter other corner (%d coordinates): ", nDims); for (k = 0; k < nDims; ++k) scanf("%d", &corner1[k]); /* find first corner */ for (k = 0; k < nDims; ++k) { cornerlo[k] = corner0[k]; work[k] = corner1[k]; } hilbert_box_vtx(nDims, sizeof(unsigned), 8*sizeof(unsigned), 1, cornerlo, work); m_IF.printf("Predicted lo corner: "); for (k = 0; k < nDims; ++k) m_IF.printf("%4u", cornerlo[k]); m_IF.printf("\n"); /* find last corner */ for (k = 0; k < nDims; ++k) { work[k] = corner0[k]; cornerhi[k] = corner1[k]; } hilbert_box_vtx(nDims, sizeof(unsigned), 8*sizeof(unsigned), 0, work, cornerhi); m_IF.printf("Predicted hi corner: "); for (k = 0; k < nDims; ++k) m_IF.printf("%4u", cornerhi[k]); m_IF.printf("\n"); array = (array_t*) malloc(maxDim*sizeof(unsigned) << nDims); for (k = 0; k < (1<>j)&1)? corner1: corner0; eltk[j] = src[j]; } } g_nDims = nDims; qsort(array, (1< #include #include #define maxDim (8*sizeof(bitmask_t)) typedef double key_t; unsigned g_nDims; int cmp(void const* c1p, void const* c2p) { return hilbert_ieee_cmp(g_nDims, c1p, c2p); } int main() { key_t corner0[maxDim], corner1[maxDim]; key_t cornerlo[maxDim], cornerhi[maxDim], work[maxDim]; typedef key_t array_t[maxDim]; array_t* array; unsigned nDims, i, k; m_IF.printf( "Enter nDims: " ); scanf( "%d", &nDims); if ( nDims == 0 ) return 0; for (i = 0; i < 10000; ++i) { for (k = 0; k < nDims; ++k) { corner0[k] = 2.*drand48() - 1.; corner1[k] = 2.*drand48() - 1.; } /* find first corner */ for (k = 0; k < nDims; ++k) { cornerlo[k] = corner0[k]; work[k] = corner1[k]; } hilbert_ieee_box_vtx(nDims, 1, cornerlo, work); /* find last corner */ for (k = 0; k < nDims; ++k) { work[k] = corner0[k]; cornerhi[k] = corner1[k]; } hilbert_ieee_box_vtx(nDims, 0, work, cornerhi); array = (array_t*) malloc(maxDim*sizeof(key_t) << nDims); for (k = 0; k < (1<>j)&1)? corner1: corner0; eltk[j] = src[j]; } } g_nDims = nDims; qsort(array, (1< #include #define maxDim (8*sizeof(bitmask_t)) unsigned g_nDims; int cmp(void const* c1p, void const* c2p) { return hilbert_cmp(g_nDims, sizeof(unsigned), 8*sizeof(unsigned), c1p, c2p); } int main() { unsigned point0[maxDim], point1[maxDim]; unsigned pointlo[maxDim], pointhi[maxDim], work[maxDim]; typedef unsigned array_t[maxDim]; array_t* array; unsigned nDims, i, k, outvolume = 1, involume = 1; unsigned nextItem; m_IF.printf( "Enter nDims: " ); scanf( "%d", &nDims); if ( nDims == 0 ) return 0; while ( (i = getchar()) != '\n' && i != EOF ) ; if ( i == EOF ) return 0; m_IF.printf("Enter one point (%d coordinates): ", nDims); for (k = 0; k < nDims; ++k) scanf("%d", &point0[k]); m_IF.printf("Enter other point (%d coordinates, strictly greater): ", nDims); for (k = 0; k < nDims; ++k) { unsigned diff; scanf("%d", &point1[k]); diff = point1[k] - point0[k]; outvolume *= diff + 1; involume *= diff - 1; } /* find first point */ for (k = 0; k < nDims; ++k) { pointlo[k] = point0[k]; work[k] = point1[k]; } hilbert_box_pt(nDims, sizeof(unsigned), 8*sizeof(unsigned), 1, pointlo, work); m_IF.printf("Predicted lo point: "); for (k = 0; k < nDims; ++k) m_IF.printf("%4u", pointlo[k]); m_IF.printf("\n"); /* find last point */ for (k = 0; k < nDims; ++k) { work[k] = point0[k]; pointhi[k] = point1[k]; } hilbert_box_pt(nDims, sizeof(unsigned), 8*sizeof(unsigned), 0, work, pointhi); m_IF.printf("Predicted hi point: "); for (k = 0; k < nDims; ++k) m_IF.printf("%4u", pointhi[k]); m_IF.printf("\n"); array = (array_t*) malloc(maxDim*sizeof(unsigned) * (outvolume-involume)); if (array == 0) { fm_IF.printf(stderr, "Out of memory.\n"); exit(-1); } nextItem = 0; for (k = 0; k < outvolume; ++k) { unsigned kk = k; unsigned j; unsigned* eltk = &array[nextItem][0]; int boundary = 0; for (j = 0; j < nDims; ++j) { unsigned diff1 = point1[j] - point0[j] + 1; unsigned pos = point0[j] + (kk % diff1); boundary |= (point0[j] == pos || pos == point1[j]); eltk[j] = pos; kk /= diff1; } if (boundary) ++nextItem; } g_nDims = nDims; qsort(array, outvolume-involume, maxDim*sizeof(unsigned), cmp); m_IF.printf("Result of sort\n"); for (k = 0; k < outvolume-involume; k += outvolume-involume-1) { unsigned j; unsigned* eltk = &array[k][0]; for (j = 0; j < nDims; ++j) m_IF.printf("%4u", eltk[j]); m_IF.printf("\n"); } free((char*)array); return 0; } #endif #ifdef TEST_IEEE_PT #include #include #define maxDim (8*sizeof(bitmask_t)) int main() { double point0[maxDim], point1[maxDim]; double pointlo[maxDim], pointhi[maxDim], work[maxDim]; unsigned nDims, k, i; m_IF.printf( "Enter nDims: " ); scanf( "%d", &nDims); if ( nDims == 0 ) return 0; while ( (i = getchar()) != '\n' && i != EOF ) ; if ( i == EOF ) return 0; m_IF.printf("Enter one point (%d coordinates): ", nDims); for (k = 0; k < nDims; ++k) scanf("%lf", &point0[k]); m_IF.printf("Enter other point (%d coordinates, strictly greater): ", nDims); for (k = 0; k < nDims; ++k) scanf("%lf", &point1[k]); /* find last point */ for (k = 0; k < nDims; ++k) { work[k] = point0[k]; pointhi[k] = point1[k]; } hilbert_ieee_box_pt(nDims, 0, work, pointhi); m_IF.printf("Predicted hi point: "); for (k = 0; k < nDims; ++k) m_IF.printf("%10lg", pointhi[k]); m_IF.printf("\n"); /* find first point */ for (k = 0; k < nDims; ++k) { pointlo[k] = point0[k]; work[k] = point1[k]; } hilbert_ieee_box_pt(nDims, 1, pointlo, work); m_IF.printf("Predicted lo point: "); for (k = 0; k < nDims; ++k) m_IF.printf("%10lg", pointlo[k]); m_IF.printf("\n"); /* validate by sorting random boundary points */ #define nPts 1000000 assert(hilbert_ieee_cmp(nDims, pointlo, pointhi) < 0); for (i = 0; i < nPts; ++i) { double pt1[maxDim], pt2[maxDim]; for (k = 0; k < nDims; ++k) { if (i % nDims == k) pt1[k] = point0[k]; else pt1[k] = point0[k] + drand48()*(point1[k]-point0[k]); } for (k = 0; k < nDims; ++k) { if (i % nDims == k) pt2[k] = point1[k]; else pt2[k] = point0[k] + drand48()*(point1[k]-point0[k]); } if (hilbert_ieee_cmp(nDims, pt1, pt2) < 0) { if (hilbert_ieee_cmp(nDims, pt1, pointlo) < 0) memcpy(pointlo, pt1, maxDim*sizeof(double)); if (hilbert_ieee_cmp(nDims, pointhi, pt2) < 0) memcpy(pointhi, pt2, maxDim*sizeof(double)); } else { if (hilbert_ieee_cmp(nDims, pt2, pointlo) < 0) memcpy(pointlo, pt2, maxDim*sizeof(double)); if (hilbert_ieee_cmp(nDims, pointhi, pt1) < 0) memcpy(pointhi, pt1, maxDim*sizeof(double)); } } m_IF.printf("Sorted hi and lo:\n"); for (k = 0; k < nDims; ++k) m_IF.printf("%10lg", pointhi[k]); m_IF.printf("\n"); for (k = 0; k < nDims; ++k) m_IF.printf("%10lg", pointlo[k]); m_IF.printf("\n"); return 0; } #endif #ifdef TEST_NEXT #include int main() { unsigned i; unsigned c1[100], c2[100], pt[100]; unsigned nDims, nBytes = 4; int stat, findPrev; m_IF.printf("Enter nDims: " ); scanf("%u", &nDims); m_IF.printf("Enter 1st box corner: "); for (i = 0; i < nDims; ++i) scanf("%u", &c1[i]); m_IF.printf("Enter 2nd box corner: "); for (i = 0; i < nDims; ++i) scanf("%u", &c2[i]); m_IF.printf("Enter point: "); for (i = 0; i < nDims; ++i) scanf("%u", &pt[i]); m_IF.printf("Find prev?: "); scanf("%d", &findPrev); stat = hilbert_nextinbox(nDims, nBytes, 8*nBytes, findPrev, c1, c2, pt); if (stat) for (i = 0; i < nDims; ++i) m_IF.printf("%u ", c1[i]); else m_IF.printf("No such point"); m_IF.printf("\n"); return 0; } #endif /************************************************************************************************ *** The following code is taken from the website *** http://and-what-happened.blogspot.de/2011/08/fast-2d-and-3d-hilbert-curves-and.html ************************************************************************************************/ unsigned long MortonToHilbert3D( const unsigned long morton, const unsigned long bits ) { unsigned long hilbert = morton; if( bits > 1 ) { unsigned long block = ( ( bits * 3 ) - 3 ); unsigned long hcode = ( ( hilbert >> block ) & 7 ); unsigned long mcode, shift, signs; shift = signs = 0; while( block ) { block -= 3; hcode <<= 2; mcode = ( ( 0x20212021 >> hcode ) & 3 ); shift = ( ( 0x48 >> ( 7 - shift - mcode ) ) & 3 ); signs = ( ( signs | ( signs << 3 ) ) >> mcode ); signs = ( ( signs ^ ( 0x53560300 >> hcode ) ) & 7 ); mcode = ( ( hilbert >> block ) & 7 ); hcode = mcode; hcode = ( ( ( hcode | ( hcode << 3 ) ) >> shift ) & 7 ); hcode ^= signs; hilbert ^= ( ( mcode ^ hcode ) << block ); } } hilbert ^= ( ( hilbert >> 1 ) & 0x92492492 ); hilbert ^= ( ( hilbert & 0x92492492 ) >> 1 ); return( hilbert ); } unsigned long HilbertToMorton3D( const unsigned long hilbert, const unsigned long bits ) { unsigned long morton = hilbert; morton ^= ( ( morton & 0x92492492 ) >> 1 ); morton ^= ( ( morton >> 1 ) & 0x92492492 ); if( bits > 1 ) { unsigned long block = ( ( bits * 3 ) - 3 ); unsigned long hcode = ( ( morton >> block ) & 7 ); unsigned long mcode, shift, signs; shift = signs = 0; while( block ) { block -= 3; hcode <<= 2; mcode = ( ( 0x20212021 >> hcode ) & 3 ); shift = ( ( 0x48 >> ( 4 - shift + mcode ) ) & 3 ); signs = ( ( signs | ( signs << 3 ) ) >> mcode ); signs = ( ( signs ^ ( 0x53560300 >> hcode ) ) & 7 ); hcode = ( ( morton >> block ) & 7 ); mcode = hcode; mcode ^= signs; mcode = ( ( ( mcode | ( mcode << 3 ) ) >> shift ) & 7 ); morton ^= ( ( hcode ^ mcode ) << block ); } } return( morton ); } unsigned long Morton_3D_Encode_10bit( unsigned long index1, unsigned long index2, unsigned long index3 ) { // pack 3 10-bit indices into a 30-bit Morton code index1 &= 0x000003ff; index2 &= 0x000003ff; index3 &= 0x000003ff; index1 |= ( index1 << 16 ); index2 |= ( index2 << 16 ); index3 |= ( index3 << 16 ); index1 &= 0x030000ff; index2 &= 0x030000ff; index3 &= 0x030000ff; index1 |= ( index1 << 8 ); index2 |= ( index2 << 8 ); index3 |= ( index3 << 8 ); index1 &= 0x0300f00f; index2 &= 0x0300f00f; index3 &= 0x0300f00f; index1 |= ( index1 << 4 ); index2 |= ( index2 << 4 ); index3 |= ( index3 << 4 ); index1 &= 0x030c30c3; index2 &= 0x030c30c3; index3 &= 0x030c30c3; index1 |= ( index1 << 2 ); index2 |= ( index2 << 2 ); index3 |= ( index3 << 2 ); index1 &= 0x09249249; index2 &= 0x09249249; index3 &= 0x09249249; return( index1 | ( index2 << 1 ) | ( index3 << 2 ) ); } void Morton_3D_Decode_10bit( const unsigned long morton, unsigned long &index1, unsigned long &index2, unsigned long &index3 ) { // unpack 3 10-bit indices from a 30-bit Morton code unsigned long value1 = morton; unsigned long value2 = ( value1 >> 1 ); unsigned long value3 = ( value1 >> 2 ); value1 &= 0x09249249; value2 &= 0x09249249; value3 &= 0x09249249; value1 |= ( value1 >> 2 ); value2 |= ( value2 >> 2 ); value3 |= ( value3 >> 2 ); value1 &= 0x030c30c3; value2 &= 0x030c30c3; value3 &= 0x030c30c3; value1 |= ( value1 >> 4 ); value2 |= ( value2 >> 4 ); value3 |= ( value3 >> 4 ); value1 &= 0x0300f00f; value2 &= 0x0300f00f; value3 &= 0x0300f00f; value1 |= ( value1 >> 8 ); value2 |= ( value2 >> 8 ); value3 |= ( value3 >> 8 ); value1 &= 0x030000ff; value2 &= 0x030000ff; value3 &= 0x030000ff; value1 |= ( value1 >> 16 ); value2 |= ( value2 >> 16 ); value3 |= ( value3 >> 16 ); value1 &= 0x000003ff; value2 &= 0x000003ff; value3 &= 0x000003ff; index1 = value1; index2 = value2; index3 = value3; } void hilbert2_3d_i2c(unsigned long index, unsigned long &ix, unsigned long &iy, unsigned long &iz) { UNUSED(index); UNUSED(ix); UNUSED(iy); UNUSED(iz); } unsigned long hilbert2_3d__c2i(unsigned long ix, unsigned long iy, unsigned long iz) { UNUSED(ix); UNUSED(iy); UNUSED(iz); return 0; } travis-src-190101/src/bqb_hilbert.h0100777000000000000000000001645513412725650014077 0ustar00/*********************************************************************************** LibBQB - File Format and Compression Algorithms for Trajectories of Volumetric Data and Atom Positions https://brehm-research.de/bqb Free software, licensed under GNU LGPL v3 Copyright (c) Martin Brehm and Martin Thomas, Martin Luther University Halle-Wittenberg, Germany, 2016 - 2019. Please cite: M. Brehm, M. Thomas: "An Efficient Lossless Compression Algorithm for Trajectories of Atom Positions and Volumetric Data", J. Chem. Inf. Model. 2018, 58 (10), pp 2092-2107. -------------------------------------------------------------------------------- LibBQB is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program. If not, see . ***********************************************************************************/ #ifndef BQB_HILBERT_H #define BQB_HILBERT_H // This must always be the first include directive #include "bqb_config.h" #include "bqb_tools.h" //void ExportPOVRayScene(int degree, const char *s); //void ExportXYZScene(int degree, const char *s); /* C header file for Hilbert curve functions */ #ifdef __cplusplus extern "C" { #endif /* define the bitmask_t type as an integer of sufficient size */ typedef unsigned long bitmask_t; /* define the halfmask_t type as an integer of 1/2 the size of bitmask_t */ typedef unsigned long halfmask_t; /***************************************************************** * hilbert_i2c * * Convert an index into a Hilbert curve to a set of coordinates. * Inputs: * nDims: Number of coordinate axes. * nBits: Number of bits per axis. * index: The index, contains nDims*nBits bits (so nDims*nBits must be <= 8*sizeof(bitmask_t)). * Outputs: * coord: The list of nDims coordinates, each with nBits bits. * Assumptions: * nDims*nBits <= (sizeof index) * (bits_per_byte) */ void hilbert_i2c(unsigned nDims, unsigned nBits, bitmask_t index, bitmask_t coord[]); /***************************************************************** * hilbert_c2i * * Convert coordinates of a point on a Hilbert curve to its index. * Inputs: * nDims: Number of coordinates. * nBits: Number of bits/coordinate. * coord: Array of n nBits-bit coordinates. * Outputs: * index: Output index value. nDims*nBits bits. * Assumptions: * nDims*nBits <= (sizeof bitmask_t) * (bits_per_byte) */ bitmask_t hilbert_c2i(unsigned nDims, unsigned nBits, bitmask_t const coord[]); /***************************************************************** * hilbert_cmp, hilbert_ieee_cmp * * Determine which of two points lies further along the Hilbert curve * Inputs: * nDims: Number of coordinates. * nBytes: Number of bytes of storage/coordinate (hilbert_cmp only) * nBits: Number of bits/coordinate. (hilbert_cmp only) * coord1: Array of nDims nBytes-byte coordinates (or doubles for ieee_cmp). * coord2: Array of nDims nBytes-byte coordinates (or doubles for ieee_cmp). * Return value: * -1, 0, or 1 according to whether coord1coord2 * Assumptions: * nBits <= (sizeof bitmask_t) * (bits_per_byte) */ int hilbert_cmp(unsigned nDims, unsigned nBytes, unsigned nBits, void const* coord1, void const* coord2); int hilbert_ieee_cmp(unsigned nDims, double const* coord1, double const* coord2); /***************************************************************** * hilbert_box_vtx * * Determine the first or last vertex of a box to lie on a Hilbert curve * Inputs: * nDims: Number of coordinates. * nBytes: Number of bytes/coordinate. * nBits: Number of bits/coordinate. (hilbert_cmp only) * findMin: Is it the least vertex sought? * coord1: Array of nDims nBytes-byte coordinates - one corner of box * coord2: Array of nDims nBytes-byte coordinates - opposite corner * Output: * c1 and c2 modified to refer to selected corner * value returned is log2 of size of largest power-of-two-aligned box that * contains the selected corner and no other corners * Assumptions: * nBits <= (sizeof bitmask_t) * (bits_per_byte) */ unsigned hilbert_box_vtx(unsigned nDims, unsigned nBytes, unsigned nBits, int findMin, void* c1, void* c2); unsigned hilbert_ieee_box_vtx(unsigned nDims, int findMin, double* c1, double* c2); /***************************************************************** * hilbert_box_pt * * Determine the first or last point of a box to lie on a Hilbert curve * Inputs: * nDims: Number of coordinates. * nBytes: Number of bytes/coordinate. * nBits: Number of bits/coordinate. * findMin: Is it the least vertex sought? * coord1: Array of nDims nBytes-byte coordinates - one corner of box * coord2: Array of nDims nBytes-byte coordinates - opposite corner * Output: * c1 and c2 modified to refer to least point * Assumptions: * nBits <= (sizeof bitmask_t) * (bits_per_byte) */ unsigned hilbert_box_pt(unsigned nDims, unsigned nBytes, unsigned nBits, int findMin, void* coord1, void* coord2); unsigned hilbert_ieee_box_pt(unsigned nDims, int findMin, double* c1, double* c2); /***************************************************************** * hilbert_nextinbox * * Determine the first point of a box after a given point to lie on a Hilbert curve * Inputs: * nDims: Number of coordinates. * nBytes: Number of bytes/coordinate. * nBits: Number of bits/coordinate. * findPrev: Is the previous point sought? * coord1: Array of nDims nBytes-byte coordinates - one corner of box * coord2: Array of nDims nBytes-byte coordinates - opposite corner * point: Array of nDims nBytes-byte coordinates - lower bound on point returned * * Output: if returns 1: * c1 and c2 modified to refer to least point after "point" in box else returns 0: arguments unchanged; "point" is beyond the last point of the box * Assumptions: * nBits <= (sizeof bitmask_t) * (bits_per_byte) */ int hilbert_nextinbox(unsigned nDims, unsigned nBytes, unsigned nBits, int findPrev, void* coord1, void* coord2, void const* point); /***************************************************************** * hilbert_incr * * Advance from one point to its successor on a Hilbert curve * Inputs: * nDims: Number of coordinates. * nBits: Number of bits/coordinate. * coord: Array of nDims nBits-bit coordinates. * Output: * coord: Next point on Hilbert curve * Assumptions: * nBits <= (sizeof bitmask_t) * (bits_per_byte) */ void hilbert_incr(unsigned nDims, unsigned nBits, bitmask_t coord[]); #ifdef __cplusplus } #endif #endif travis-src-190101/src/bqb_hufftree.cpp0100777000000000000000000010300713412725633014600 0ustar00/*********************************************************************************** LibBQB - File Format and Compression Algorithms for Trajectories of Volumetric Data and Atom Positions https://brehm-research.de/bqb Free software, licensed under GNU LGPL v3 Copyright (c) Martin Brehm and Martin Thomas, Martin Luther University Halle-Wittenberg, Germany, 2016 - 2019. Please cite: M. Brehm, M. Thomas: "An Efficient Lossless Compression Algorithm for Trajectories of Atom Positions and Volumetric Data", J. Chem. Inf. Model. 2018, 58 (10), pp 2092-2107. -------------------------------------------------------------------------------- LibBQB is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program. If not, see . ***********************************************************************************/ // This must always be the first include directive #include "bqb_config.h" #include "bqb_tools.h" #include "bqb_hufftree.h" #include #include #include "bqb_integerengine.h" #include "bqb_interface.h" const char *GetRevisionInfo_bqb_hufftree(unsigned int len) { static char buf[256]; GET_REVISION_INFO( buf, len ); return buf; } const char *GetSourceVersion_bqb_hufftree() { static char buf[256]; GET_SOURCE_VERSION( buf ); return buf; } void CBQBHuffmanTree::Init(int alphasize) { int z; m_iaLengths.resize(alphasize); m_oaBitStrings.resize(alphasize); m_iaFrequencies.resize(alphasize); for (z=0;z<(int)m_iaFrequencies.size();z++) m_iaFrequencies[z] = 0; } bool SORT_SymbolsAsc(CBQBHuffmanSymbol *s1, CBQBHuffmanSymbol *s2) { return (s1->m_iFrequency < s2->m_iFrequency); } bool SORT_SymbolsDesc(CBQBHuffmanSymbol *s1, CBQBHuffmanSymbol *s2) { return (s1->m_iFrequency > s2->m_iFrequency); } bool SORT_SymbolsAlpha(CBQBHuffmanSymbol *s1, CBQBHuffmanSymbol *s2) { return (s1->m_iSymbol < s2->m_iSymbol); } bool SORT_SymbolsCanonical(CBQBHuffmanSymbol *s1, CBQBHuffmanSymbol *s2) { if (s1->m_pBitString->GetLength() < s2->m_pBitString->GetLength()) return true; else if (s1->m_pBitString->GetLength() > s2->m_pBitString->GetLength()) return false; else return (s1->m_iSymbol < s2->m_iSymbol); } void CBQBHuffmanEstimator::Init(int alphasize) { m_iAlphaSize = alphasize; m_iaLength.resize(alphasize); m_iaTempHeap.resize(alphasize+2); m_iaTempFrequencies.resize(alphasize*2); m_iaTempParent.resize(alphasize*2); } // These macros are adapted from the BZIP2 source code #define WEIGHTOF(zz0) ((zz0) & 0xffffff00) #define DEPTHOF(zz1) ((zz1) & 0x000000ff) #define MYMAX(zz2,zz3) ((zz2) > (zz3) ? (zz2) : (zz3)) #define ADDWEIGHTS(zw1,zw2) \ (WEIGHTOF(zw1)+WEIGHTOF(zw2)) | \ (1 + MYMAX(DEPTHOF(zw1),DEPTHOF(zw2))) #define UPHEAP(z) \ { \ unsigned int zz, tmp; \ zz = z; tmp = m_iaTempHeap[zz]; \ while (m_iaTempFrequencies[tmp] < m_iaTempFrequencies[m_iaTempHeap[zz >> 1]]) { \ m_iaTempHeap[zz] = m_iaTempHeap[zz >> 1]; \ zz >>= 1; \ } \ m_iaTempHeap[zz] = tmp; \ } #define DOWNHEAP(z) \ { \ unsigned int zz, yy, tmp; \ zz = z; tmp = m_iaTempHeap[zz]; \ while (true) { \ yy = zz << 1; \ if (yy > nHeap) break; \ if (yy < nHeap && \ m_iaTempFrequencies[m_iaTempHeap[yy+1]] < m_iaTempFrequencies[m_iaTempHeap[yy]]) \ yy++; \ if (m_iaTempFrequencies[tmp] < m_iaTempFrequencies[m_iaTempHeap[yy]]) break; \ m_iaTempHeap[zz] = m_iaTempHeap[yy]; \ zz = yy; \ } \ m_iaTempHeap[zz] = tmp; \ } void CBQBHuffmanEstimator::BuildBitLengthTable(const std::vector &ia) { unsigned int nNodes, nHeap, n1, n2, i, j, k; for (i = 0; i < (unsigned int)m_iAlphaSize; i++) m_iaTempFrequencies[i+1] = ia[i] << 8; // m_iaTempFrequencies[i+1] = (ia[i] == 0 ? 1 : ia[i]) << 8; nNodes = m_iAlphaSize; nHeap = 0; m_iaTempHeap[0] = 0; m_iaTempFrequencies[0] = 0; m_iaTempParent[0] = -2; for (i = 1; i <= (unsigned int)m_iAlphaSize; i++) { m_iaTempParent[i] = -1; nHeap++; m_iaTempHeap[nHeap] = i; UPHEAP(nHeap); } while (nHeap > 1) { n1 = m_iaTempHeap[1]; m_iaTempHeap[1] = m_iaTempHeap[nHeap]; nHeap--; DOWNHEAP(1); n2 = m_iaTempHeap[1]; m_iaTempHeap[1] = m_iaTempHeap[nHeap]; nHeap--; DOWNHEAP(1); nNodes++; m_iaTempParent[n1] = m_iaTempParent[n2] = nNodes; m_iaTempFrequencies[nNodes] = ADDWEIGHTS(m_iaTempFrequencies[n1], m_iaTempFrequencies[n2]); m_iaTempParent[nNodes] = -1; nHeap++; m_iaTempHeap[nHeap] = nNodes; UPHEAP(nHeap); } for (i = 1; i <= (unsigned int)m_iAlphaSize; i++) { j = 0; k = i; while (m_iaTempParent[k] >= 0) { k = m_iaTempParent[k]; j++; } m_iaLength[i-1] = j; } } unsigned int CBQBHuffmanEstimator::EstimateBitLength(const std::vector &ia) { unsigned int nNodes, nHeap, n1, n2, i, j, k, ret; for (i = 0; i < (unsigned int)m_iAlphaSize; i++) m_iaTempFrequencies[i+1] = ia[i] << 8; // m_iaTempFrequencies[i+1] = (ia[i] == 0 ? 1 : ia[i]) << 8; nNodes = m_iAlphaSize; nHeap = 0; m_iaTempHeap[0] = 0; m_iaTempFrequencies[0] = 0; m_iaTempParent[0] = -2; for (i = 1; i <= (unsigned int)m_iAlphaSize; i++) { m_iaTempParent[i] = -1; nHeap++; m_iaTempHeap[nHeap] = i; UPHEAP(nHeap); } while (nHeap > 1) { n1 = m_iaTempHeap[1]; m_iaTempHeap[1] = m_iaTempHeap[nHeap]; nHeap--; DOWNHEAP(1); n2 = m_iaTempHeap[1]; m_iaTempHeap[1] = m_iaTempHeap[nHeap]; nHeap--; DOWNHEAP(1); nNodes++; m_iaTempParent[n1] = m_iaTempParent[n2] = nNodes; m_iaTempFrequencies[nNodes] = ADDWEIGHTS( m_iaTempFrequencies[n1], m_iaTempFrequencies[n2] ); m_iaTempParent[nNodes] = -1; nHeap++; m_iaTempHeap[nHeap] = nNodes; UPHEAP(nHeap); } ret = 0; for (i = 0; i < (unsigned int)m_iAlphaSize; i++) { if (ia[i] == 0) continue; j = 0; k = i+1; while (m_iaTempParent[k] >= 0) { k = m_iaTempParent[k]; j++; } ret += j * ia[i]; } return ret; } unsigned int CBQBHuffmanEstimator::EstimateBitLength(const std::vector &ia, int i2) { std::vector tia; tia.assign(ia.begin(),ia.end()); tia[i2]++; return EstimateBitLength(tia); } unsigned int CBQBHuffmanEstimator::EstimateBitLength(const std::vector &ia, const std::vector &ia2) { std::vector tia; int z; tia.assign(ia.begin(),ia.end()); for (z=0;z<(int)tia.size();z++) tia[z] += ia2[z]; return EstimateBitLength(tia); } unsigned int CBQBHuffmanEstimator::EstimateBitLength(const std::vector &ia, const std::vector &ia2, const std::vector &ia3) { std::vector tia; int z; tia.assign(ia.begin(),ia.end()); for (z=0;z<(int)tia.size();z++) tia[z] += ia2[z] + ia3[z]; return EstimateBitLength(tia); } void CBQBHuffmanTree::BuildTree(bool canonical, bool showsymbols) { int z, ti, c; CBQBHuffmanSymbol *sym; unsigned long l; m_bCanonical = canonical; m_oaSymbols.clear(); if (m_pTree != NULL) delete m_pTree; m_pTree = NULL; for (z=0;z<(int)m_iaFrequencies.size();z++) { if (m_iaFrequencies[z] != 0) { sym = new CBQBHuffmanSymbol(); sym->m_iSymbol = z; sym->m_iFrequency = m_iaFrequencies[z]; // sym->m_iFrequency = (m_iaFrequencies[z]==0)?1:m_iaFrequencies[z]; sym->m_bVirtual = false; sym->m_iDepth = 0; m_oaSymbols.push_back(sym); } } if (m_oaSymbols.size() == 0) return; std::sort(m_oaSymbols.begin(),m_oaSymbols.end(),SORT_SymbolsAsc); m_oaTempSymbols.assign(m_oaSymbols.begin(),m_oaSymbols.end()); while (m_oaTempSymbols.size() > 1) { sym = new CBQBHuffmanSymbol(); sym->m_iSymbol = 0; sym->m_bVirtual = true; sym->m_iFrequency = m_oaTempSymbols[0]->m_iFrequency + m_oaTempSymbols[1]->m_iFrequency; sym->m_oaChildren.push_back(m_oaTempSymbols[0]); sym->m_oaChildren.push_back(m_oaTempSymbols[1]); sym->m_iDepth = MAX( m_oaTempSymbols[0]->m_iDepth, m_oaTempSymbols[1]->m_iDepth ) + 1; m_oaTempSymbols.erase(m_oaTempSymbols.begin(),m_oaTempSymbols.begin()+2); for (z=0;z<(int)m_oaTempSymbols.size();z++) { if (m_oaTempSymbols[z]->m_iFrequency > sym->m_iFrequency) break; if ((m_oaTempSymbols[z]->m_iFrequency == sym->m_iFrequency) && (m_oaTempSymbols[z]->m_iDepth > sym->m_iDepth)) break; } m_oaTempSymbols.insert(m_oaTempSymbols.begin()+z,sym); } m_pTree = m_oaTempSymbols[0]; m_oaTempSymbols.clear(); m_pTree->m_pBitString = new CBQBBitSet(m_IF); m_pTree->REC_BuildBitstrings(0); if (m_bCanonical) { if (m_pTree->m_oaChildren.size() == 0) // Hack 02.04.2017 m_pTree->m_pBitString->WriteBits(0,1); std::sort(m_oaSymbols.begin(),m_oaSymbols.end(),SORT_SymbolsCanonical); ti = 0; l = 0; for (z=0;z<(int)m_oaSymbols.size();z++) { if (m_oaSymbols[z]->m_pBitString->GetLength() > ti) { l <<= m_oaSymbols[z]->m_pBitString->GetLength() - ti; ti = m_oaSymbols[z]->m_pBitString->GetLength(); } m_oaSymbols[z]->m_pBitString->Clear(); m_oaSymbols[z]->m_pBitString->WriteBits(reverse_bit_order(l,ti),ti); l++; } std::sort(m_oaSymbols.begin(),m_oaSymbols.end(),SORT_SymbolsAlpha); } for (z=0;z<(int)m_iaLengths.size();z++) m_iaLengths[z] = 0; m_iMaxBitLength = 0; for (z=0;z<(int)m_oaSymbols.size();z++) { m_iaLengths[m_oaSymbols[z]->m_iSymbol] = m_oaSymbols[z]->m_pBitString->GetLength(); if (m_iMaxBitLength < m_iaLengths[m_oaSymbols[z]->m_iSymbol]) m_iMaxBitLength = m_iaLengths[m_oaSymbols[z]->m_iSymbol]; m_oaBitStrings[m_oaSymbols[z]->m_iSymbol] = m_oaSymbols[z]->m_pBitString; } if (showsymbols) { std::sort(m_oaSymbols.begin(),m_oaSymbols.end(),SORT_SymbolsDesc); m_IF.printf("*** Output of Huffman Table ***\n"); ti = 0; c = 0; for (z=0;z<(int)m_oaSymbols.size();z++) { m_IF.printf(" %6d (%9d): ",m_oaSymbols[z]->m_iSymbol,m_oaSymbols[z]->m_iFrequency); m_oaSymbols[z]->m_pBitString->DumpPlain(); m_IF.printf(" (%d)\n",m_oaSymbols[z]->m_pBitString->GetLength()); ti += m_oaSymbols[z]->m_iFrequency * m_oaSymbols[z]->m_pBitString->GetLength(); c += m_oaSymbols[z]->m_iFrequency; } m_IF.printf(" %lu symbol types, %d symbols, %.4f bits per entry, %.4f MiB per frame.\n",m_oaSymbols.size(),c,((double)ti)/m_pTree->m_iFrequency,ti/8.0/1024.0/1024.0); m_IF.printf("\n\n"); } } void CBQBHuffmanTree::BuildPrelimTree() { int z; CBQBHuffmanSymbol *sym; m_oaSymbols.clear(); if (m_pTree != NULL) delete m_pTree; m_pTree = NULL; for (z=0;z<(int)m_iaFrequencies.size();z++) { sym = new CBQBHuffmanSymbol(); sym->m_iSymbol = z; sym->m_iFrequency = m_iaFrequencies[z]; // sym->m_iFrequency = (m_iaFrequencies[z]==0)?1:m_iaFrequencies[z]; sym->m_bVirtual = false; sym->m_iDepth = 0; m_oaSymbols.push_back(sym); } std::sort(m_oaSymbols.begin(),m_oaSymbols.end(),SORT_SymbolsAsc); m_oaTempSymbols.assign(m_oaSymbols.begin(),m_oaSymbols.end()); while (m_oaTempSymbols.size() > 1) { sym = new CBQBHuffmanSymbol(); sym->m_iSymbol = 0; sym->m_bVirtual = true; sym->m_iFrequency = m_oaTempSymbols[0]->m_iFrequency + m_oaTempSymbols[1]->m_iFrequency; sym->m_iDepth = MAX( m_oaTempSymbols[0]->m_iDepth, m_oaTempSymbols[1]->m_iDepth ) + 1; sym->m_oaChildren.push_back(m_oaTempSymbols[0]); sym->m_oaChildren.push_back(m_oaTempSymbols[1]); m_oaTempSymbols.erase(m_oaTempSymbols.begin(),m_oaTempSymbols.begin()+2); for (z=0;z<(int)m_oaTempSymbols.size();z++) { if (m_oaTempSymbols[z]->m_iFrequency > sym->m_iFrequency) break; if ((m_oaTempSymbols[z]->m_iFrequency == sym->m_iFrequency) && (m_oaTempSymbols[z]->m_iDepth > sym->m_iDepth)) break; } m_oaTempSymbols.insert(m_oaTempSymbols.begin()+z,sym); } m_pTree = m_oaTempSymbols[0]; m_oaTempSymbols.clear(); REC_BuildBitstringLengths(0,m_pTree); } void CBQBHuffmanSymbol::REC_BuildBitstrings(int depth) { if (m_oaChildren.size() == 2) { m_oaChildren[0]->m_pBitString = new CBQBBitSet(m_pBitString); m_oaChildren[0]->m_pBitString->WriteBit(0); m_oaChildren[0]->REC_BuildBitstrings(depth+1); m_oaChildren[1]->m_pBitString = new CBQBBitSet(m_pBitString); m_oaChildren[1]->m_pBitString->WriteBit(1); m_oaChildren[1]->REC_BuildBitstrings(depth+1); } } void CBQBHuffmanTree::REC_BuildBitstringLengths(int depth, CBQBHuffmanSymbol *sym) { if (sym->m_oaChildren.size() == 2) { REC_BuildBitstringLengths(depth+1,sym->m_oaChildren[0]); REC_BuildBitstringLengths(depth+1,sym->m_oaChildren[1]); } else // if (sym->m_iFrequency == 0) // m_iaLengths[sym->m_iSymbol] = depth+5; // else m_iaLengths[sym->m_iSymbol] = depth; } int CBQBHuffmanTree::ExportTree(CBQBBitSet *bs, bool chr) { int b2, b2a, b2s, i, z, z2, z0, nz, orig, alt, alt2, alt20; int alt3, method, bborder, iborder, si, tc; std::vector mtf, ia, ia2, border; CBQBHuffmanTree ht(m_IF); CBQBBitSet bs2(m_IF); si = 0; if (m_bCanonical) { // Canonical if (m_IF.IsPL(BQB_PL_DEBUG)) m_IF.printf(">>> ExportTree Canonical Version >>>\n"); si++; if (bs != NULL) bs->WriteBit(1); i = 0; nz = 0; for (z=0;z<(int)m_iaFrequencies.size();z++) { if (m_iaFrequencies[z] != 0) { i = z; nz++; } } i++; if (m_IF.IsPL(BQB_PL_DEBUG)) m_IF.printf("Symbol type count is %d (%d non-zero symbols).\n",i,nz); b2 = (int)ceil(mylog2(m_iMaxBitLength+1)); b2a = (int)ceil(mylog2(m_iMaxBitLength+2)); if (m_IF.IsPL(BQB_PL_DEBUG)) m_IF.printf("Max bit length is %d, using %d bits per length token.\n",m_iMaxBitLength,b2); ia.resize(i); for (z=0;zm_iSymbol == z) break; if (z2 == (int)m_oaSymbols.size()) { m_IF.eprintf("CBQBHuffmanTree::ExportTree(): Internal error.\n"); abort(); } ia[z] = m_oaSymbols[z2]->m_pBitString->GetLength(); } else ia[z] = 0; } mtf.resize(m_iMaxBitLength+1); for (z=0;z<=m_iMaxBitLength;z++) mtf[z] = z; ia2.clear(); tc = 0; for (z=0;z 10) { alt3 = 0; ht.Init(m_iMaxBitLength+2); for (z=0;z<(int)ia2.size();z++) ht.m_iaFrequencies[ia2[z]]++; ht.BuildTree(true); alt3 = ht.ExportTree(NULL,chr); for (z=0;z<(int)ia2.size();z++) alt3 += ht.m_iaLengths[ia2[z]]; } else { alt3 = 1000000000; if (m_IF.IsPL(BQB_PL_DEBUG)) m_IF.printf("Low symbol type count, not trying alt3.\n"); } b2s = (int)ceil(mylog2(i+1)); if (chr) { if (i < 64) { orig = b2*i + 13; alt = b2*nz + i + 13; alt3 += 7; if (iborder == 0) alt2 += 14; else alt2 += 17; } else { orig = b2*i + 16; alt = b2*nz + i + 16; alt3 += 10; if (iborder == 0) alt2 += 17; else alt2 += 20; } } else { if (i < 64) { orig = b2*i + 13; alt = b2*nz + i + 13; alt3 += 7; if (iborder == 0) alt2 += 14; else alt2 += 19; } else { orig = b2*i + b2s + 13; alt = b2*nz + i + b2s + 13; alt3 += 7+b2s; if (iborder == 0) alt2 += b2s + 14; else alt2 += b2s + 19; } } if (m_IF.IsPL(BQB_PL_DEBUG)) { m_IF.printf("Original method (0): %5d bits.\n",orig); m_IF.printf("Alternative method (1): %5d bits.\n",alt); m_IF.printf("Alternative method (2): %5d bits (border %d).\n",alt2,iborder); if (alt3 < 1e9) m_IF.printf("Alternative method (3): %5d bits.\n",alt3); } if ((orig <= alt) && (orig <= alt2) && (orig <= alt3)) method = 0; else if ((alt <= orig) && (alt <= alt2) && (alt <= alt3)) method = 1; else if ((alt2 <= orig) && (alt2 <= alt) && (alt2 <= alt3)) method = 2; else method = 3; if (m_IF.IsPL(BQB_PL_DEBUG)) m_IF.printf("--> Using method %d.\n",method); si += 2; if (bs != NULL) bs->WriteBits(method,2); nz = si; if ((method == 0) || (method == 1)) { if (i < 64) { if (m_IF.IsPL(BQB_PL_DEBUG)) m_IF.printf("Symbol type count is %d (%d non-zero symbols), using short storage.\n",i,nz); si += 7; if (bs != NULL) { bs->WriteBit(0); bs->WriteBits(i,6); } } else { if (chr) { if (m_IF.IsPL(BQB_PL_DEBUG)) m_IF.printf("Symbol type count is %d (%d non-zero symbols), using 9 bits (char).\n",i,nz); si += 10; if (bs != NULL) { bs->WriteBit(1); bs->WriteBits(i,9); } } else { if (m_IF.IsPL(BQB_PL_DEBUG)) m_IF.printf("Symbol type count is %d (%d non-zero symbols), using %d bits.\n",i,nz,b2s); si += 7 + b2s; if (bs != NULL) { bs->WriteBit(1); bs->WriteBits(b2s,6); bs->WriteBits(i,b2s); } } } // if (!chr) { si += 6; if (bs != NULL) bs->WriteBits(b2,6); // } else { // si += 4; // if (bs != NULL) // bs->WriteBits(b2,4); // } for (z=0;zWriteBit(1); bs->WriteBits(ia[z],b2); } } else { si++; if (bs != NULL) bs->WriteBit(0); } } else { si += b2; if (bs != NULL) bs->WriteBits(ia[z],b2); } /* if (m_iaFrequencies[z] != 0) { if (method == 1) { si++; if (bs != NULL) bs->WriteBit(1); } si += b2; if (bs != NULL) bs->WriteBits(ia[z],b2); } else { if (method == 1) { si ++; if (bs != NULL) bs->WriteBit(0); } else { si += b2; if (bs != NULL) bs->WriteBits(0,b2); } }*/ } } else if (method == 2) { b2s = (int)ceil(mylog2((double)ia2.size()+1)); if (ia2.size() < 64) { if (m_IF.IsPL(BQB_PL_DEBUG)) m_IF.printf("Symbol type count is %lu, using short storage.\n",ia2.size()); si += 7; if (bs != NULL) { bs->WriteBit(0); bs->WriteBits((unsigned long)ia2.size(),6); } } else { if (!chr) { if (m_IF.IsPL(BQB_PL_DEBUG)) m_IF.printf("Transmission symbol type count is %lu, using %d bits.\n",ia2.size(),b2s); si += 7 + b2s; if (bs != NULL) { bs->WriteBit(1); bs->WriteBits(b2s,6); bs->WriteBits((unsigned long)ia2.size(),b2s); } } else { if (m_IF.IsPL(BQB_PL_DEBUG)) m_IF.printf("Transmission symbol type count is %lu, using 9 bits (char).\n",ia2.size()); si += 10; if (bs != NULL) { bs->WriteBit(1); bs->WriteBits((unsigned long)ia2.size(),9); } } } // if (!chr) { si += 6; if (bs != NULL) bs->WriteBits(b2a,6); // } else { // si += 4; // if (bs != NULL) // bs->WriteBits(b2a,4); // } if (iborder != 0) { si++; if (bs != NULL) bs->WriteBit(1); if (chr) { if (bs != NULL) bs->WriteBits(iborder,3); si += 3; } else { if (bs != NULL) bs->WriteBits(iborder,5); si += 5; } } else { si++; if (bs != NULL) bs->WriteBit(0); } for (z=0;z<(int)ia2.size();z++) { if (ia2[z] != 0) { si++; if (bs != NULL) bs->WriteBit(1); if ((int)ceil(mylog2(ia2[z]+1)) <= iborder) { if (iborder != 0) { si++; if (bs != NULL) bs->WriteBit(0); } si += iborder; if (bs != NULL) bs->WriteBits(ia2[z],iborder); } else { if (iborder != 0) { si++; if (bs != NULL) bs->WriteBit(1); } si += b2a; if (bs != NULL) bs->WriteBits(ia2[z],b2a); } } else { si++; if (bs != NULL) bs->WriteBit(0); } } } else { // Method 3 b2s = (int)ceil(mylog2((double)ia2.size()+1)); if (ia2.size() < 64) { if (m_IF.IsPL(BQB_PL_DEBUG)) m_IF.printf("Symbol type count is %lu, using short storage.\n",ia2.size()); // si += 7; if (bs != NULL) { bs->WriteBit(0); bs->WriteBits((unsigned long)ia2.size(),6); } } else { if (!chr) { if (m_IF.IsPL(BQB_PL_DEBUG)) m_IF.printf("Transmission symbol type count is %lu, using %d bits.\n",ia2.size(),b2s); // si += 7 + b2s; if (bs != NULL) { bs->WriteBit(1); bs->WriteBits(b2s,6); bs->WriteBits((unsigned long)ia2.size(),b2s); } } else { if (m_IF.IsPL(BQB_PL_DEBUG)) m_IF.printf("Transmission symbol type count is %lu, using 9 bits (char).\n",ia2.size()); // si += 9; if (bs != NULL) { bs->WriteBit(1); bs->WriteBits((unsigned long)ia2.size(),9); } } } si += alt3; if (bs != NULL) ht.ExportTree(bs,chr); for (z=0;z<(int)ia2.size();z++) { // si += ht.m_oaBitStrings[ia2[z]]->GetLength(); if (bs != NULL) bs->WriteBits(ht.m_oaBitStrings[ia2[z]]); } } if (m_IF.IsPL(BQB_PL_DEBUG)) m_IF.printf("%d Bits written.\n",si-nz); if (m_IF.IsPL(BQB_PL_DEBUG)) m_IF.printf("<<< ExportTree Canonical Version <<<\n"); } else { // Classical if (m_IF.IsPL(BQB_PL_DEBUG)) m_IF.printf("ExportTree Normal Version.\n"); si++; if (bs != NULL) bs->WriteBit(0); b2 = (int)ceil(mylog2((double)m_iaFrequencies.size()+1)); if (m_IF.IsPL(BQB_PL_DEBUG)) m_IF.printf("Using %d bits.\n",b2); si+=6; if (bs != NULL) bs->WriteBits(b2,6); if (m_pTree == NULL) { if (m_IF.IsPL(BQB_PL_DEBUG)) m_IF.printf("m_pTree==NULL.\n"); si+=b2+1; if (bs != NULL) { bs->WriteBit(1); bs->WriteBits(0,b2); } } else { if (m_IF.IsPL(BQB_PL_DEBUG)) m_IF.printf("Starting REC_ExportTree() (si=%d).\n",si); si += REC_ExportTree(bs,m_pTree,b2); if (m_IF.IsPL(BQB_PL_DEBUG)) m_IF.printf("Returned from REC_ExportTree() (si=%d).\n",si); } } return si; } int CBQBHuffmanTree::REC_ExportTree(CBQBBitSet *bs, CBQBHuffmanSymbol *sym, int bits) { int t; if (sym->m_oaChildren.size() == 2) { if (bs != NULL) bs->WriteBit(0); t = REC_ExportTree(bs,sym->m_oaChildren[0],bits); t += REC_ExportTree(bs,sym->m_oaChildren[1],bits); } else { t = bits+1; if (bs != NULL) { bs->WriteBit(1); bs->WriteBits(sym->m_iSymbol,bits); } } return t; } void CBQBHuffmanTree::ImportTree(CBQBBitSet *bs, bool chr) { int z, z2, b2, i, ti, /*ti2,*/ method, border, tia, tib, ts; unsigned long l; CBQBHuffmanSymbol *hs; CBQBHuffmanTree ht(m_IF); std::vector mtf; if (bs->ReadBit()) { // Canonical if (m_IF.IsPL(BQB_PL_DEBUG)) m_IF.printf(">>> ImportTree Canonical Version >>>\n"); method = bs->ReadBitsInteger(2); if (m_IF.IsPL(BQB_PL_DEBUG)) m_IF.printf("Using method %d.\n",method); if (bs->ReadBit()) { if (chr) { if (m_IF.IsPL(BQB_PL_DEBUG)) m_IF.printf("Reading 9 bits of symbol type count (char, long storage)...\n"); i = bs->ReadBitsInteger(9); } else { b2 = bs->ReadBitsInteger(6); if (m_IF.IsPL(BQB_PL_DEBUG)) m_IF.printf("Reading %d bits of symbol type count (long storage)...\n",b2); i = bs->ReadBitsInteger(b2); } } else { if (m_IF.IsPL(BQB_PL_DEBUG)) m_IF.printf("Reading symbol type count (short storage)...\n"); i = bs->ReadBitsInteger(6); } if (m_IF.IsPL(BQB_PL_DEBUG)) m_IF.printf("Symbol type count is %d.\n",i); m_oaSymbols.clear(); if ((method == 0) || (method == 1)) { // if (chr) // b2 = bs->ReadBitsInteger(4); // else b2 = bs->ReadBitsInteger(6); if (m_IF.IsPL(BQB_PL_DEBUG)) m_IF.printf("Reading %d bits per length token...\n",b2); for (z=0;zReadBit()) continue; ti = bs->ReadBitsInteger(b2); if (ti == 0) continue; hs = new CBQBHuffmanSymbol(); hs->m_iSymbol = z; hs->m_pBitString = new CBQBBitSet(m_IF); hs->m_pBitString->WriteBits(0,ti); m_oaSymbols.push_back(hs); } } else if (method == 2) { // if (chr) // b2 = bs->ReadBitsInteger(4); // else b2 = bs->ReadBitsInteger(6); if (m_IF.IsPL(BQB_PL_DEBUG)) m_IF.printf("Reading %d bits per length token...\n",b2); if (bs->ReadBit()) { if (chr) border = bs->ReadBitsInteger(3); else border = bs->ReadBitsInteger(5); } else border = 0; if (m_IF.IsPL(BQB_PL_DEBUG)) m_IF.printf("Border = %d\n",border); mtf.resize(pow2i(b2)); for (z=0;z<(int)mtf.size();z++) mtf[z] = z; tia = 1; tib = 0; ts = 0; for (z=0;zReadBit()) { if (border != 0) { if (bs->ReadBit()) ti = bs->ReadBitsInteger(b2); else ti = bs->ReadBitsInteger(border); } else ti = bs->ReadBitsInteger(b2); } else ti = 0; // m_IF.printf("K %3d: %3d\n",z,ti); if (ti == 0) { tib += tia; tia *= 2; } else if (ti == 1) { tib += 2*tia; tia *= 2; } else { ti--; if (mtf[0] != 0) { for (z2=0;z2m_iSymbol = ts++; hs->m_pBitString = new CBQBBitSet(m_IF); hs->m_pBitString->WriteBits(0,mtf[0]); m_oaSymbols.push_back(hs); } } else ts += tib; tia = 1; tib = 0; // ti2 = mtf[ti]; MoveToFrontIndex(mtf,ti); //std::iter_swap(mtf.begin(),mtf.begin()+ti); // mtf.insert(mtf.begin(),ti2); // mtf.erase(mtf.begin()+ti+1); if (mtf[0] != 0) { hs = new CBQBHuffmanSymbol(); // m_IF.printf("%3lu: %6d (%3d)\n",m_oaSymbols.size(),ts,mtf[0]); hs->m_iSymbol = ts++; hs->m_pBitString = new CBQBBitSet(m_IF); hs->m_pBitString->WriteBits(0,mtf[0]); m_oaSymbols.push_back(hs); } else ts++; } /* ti2 = mtf[ti]; mtf.insert(mtf.begin(),ti2); mtf.erase(mtf.begin()+ti+1); hs = new CBQBHuffmanSymbol(); hs->m_iSymbol = ts++; hs->m_pBitString = new CBitSet(); hs->m_pBitString->WriteBits(0,mtf[0]); m_oaSymbols.push_back(hs);*/ } if (mtf[0] != 0) { for (z2=0;z2m_iSymbol = ts++; hs->m_pBitString = new CBQBBitSet(m_IF); hs->m_pBitString->WriteBits(0,mtf[0]); m_oaSymbols.push_back(hs); } } } else { // Method 3 ht.ImportTree(bs,chr); z2 = 0; for (z=0;z<(int)ht.m_oaSymbols.size();z++) { // m_IF.printf("I %3d: %6d\n",z,ht.m_oaSymbols[z]->m_iSymbol); if (ht.m_oaSymbols[z]->m_iSymbol > z2) z2 = ht.m_oaSymbols[z]->m_iSymbol; } if (m_IF.IsPL(BQB_PL_DEBUG)) m_IF.printf("Found largest symbol %d in tree.\n",z2); mtf.resize(z2+1); for (z=0;z<(int)mtf.size();z++) mtf[z] = z; tia = 1; tib = 0; ts = 0; for (z=0;zm_iSymbol = ts++; hs->m_pBitString = new CBQBBitSet(m_IF); hs->m_pBitString->WriteBits(0,mtf[0]); m_oaSymbols.push_back(hs); } } else ts += tib; tia = 1; tib = 0; // ti2 = mtf[ti]; MoveToFrontIndex(mtf,ti); //std::iter_swap(mtf.begin(),mtf.begin()+ti); // mtf.insert(mtf.begin(),ti2); // mtf.erase(mtf.begin()+ti+1); if (mtf[0] != 0) { hs = new CBQBHuffmanSymbol(); hs->m_iSymbol = ts++; hs->m_pBitString = new CBQBBitSet(m_IF); hs->m_pBitString->WriteBits(0,mtf[0]); m_oaSymbols.push_back(hs); } else ts++; } /* ti2 = mtf[ti]; mtf.insert(mtf.begin(),ti2); mtf.erase(mtf.begin()+ti+1); hs = new CBQBHuffmanSymbol(); hs->m_iSymbol = ts++; hs->m_pBitString = new CBitSet(); hs->m_pBitString->WriteBits(0,mtf[0]); m_oaSymbols.push_back(hs);*/ } if (mtf[0] != 0) { for (z2=0;z2m_iSymbol = ts++; hs->m_pBitString = new CBQBBitSet(m_IF); hs->m_pBitString->WriteBits(0,mtf[0]); m_oaSymbols.push_back(hs); } } } if (m_IF.IsPL(BQB_PL_DEBUG)) m_IF.printf("Sorting symbols in canonical order...\n"); std::sort(m_oaSymbols.begin(),m_oaSymbols.end(),SORT_SymbolsCanonical); // m_IF.printf("Have %lu symbols:\n",m_oaSymbols.size()); // for (z=0;z<(int)m_oaSymbols.size();z++) // m_IF.printf("@%d: %d (Len %d)\n",z+1,m_oaSymbols[z]->m_iSymbol,m_oaSymbols[z]->m_pBitString->GetLength()); // if (m_oaSymbols.size() < 50) // for (z=0;z<(int)m_oaSymbols.size();z++) // m_IF.printf("A %3d: %6d (%3d)\n",z,m_oaSymbols[z]->m_iSymbol,m_oaSymbols[z]->m_pBitString->GetLength()); if (m_IF.IsPL(BQB_PL_DEBUG)) m_IF.printf("Re-creating bit strings and tree...\n"); ti = 0; l = 0; if (m_pTree != NULL) delete m_pTree; m_pTree = new CBQBHuffmanSymbol(); for (z=0;z<(int)m_oaSymbols.size();z++) { if (m_oaSymbols[z]->m_pBitString->GetLength() > ti) { l <<= m_oaSymbols[z]->m_pBitString->GetLength() - ti; ti = m_oaSymbols[z]->m_pBitString->GetLength(); } // if (m_oaSymbols.size() < 50) // for (z2=0;z2<(int)m_oaSymbols.size();z2++) // m_IF.printf("#%d# %3d: %6d\n",z,z2,m_oaSymbols[z2]->m_iSymbol); m_oaSymbols[z]->m_pBitString->Clear(); // m_IF.printf("%3d (%2d) >>> ",z,ti); REC_PushCanonicalSymbol(m_pTree,m_oaSymbols[z],reverse_bit_order(l,ti),ti); // m_IF.printf("\n"); l++; } // if (m_oaSymbols.size() < 50) // for (z=0;z<(int)m_oaSymbols.size();z++) // m_IF.printf("B %3d: %6d\n",z,m_oaSymbols[z]->m_iSymbol); if (m_IF.IsPL(BQB_PL_DEBUG)) m_IF.printf("<<< ImportTree Canonical Version <<<\n"); } else { // Classical if (m_IF.IsPL(BQB_PL_DEBUG)) m_IF.printf("ImportTree Normal Version.\n"); b2 = bs->ReadBitsInteger(6); if (m_IF.IsPL(BQB_PL_DEBUG)) m_IF.printf("Using %d bits.\n",b2); m_pTree = new CBQBHuffmanSymbol(); z = REC_ImportTree(bs,m_pTree,b2); if (m_IF.IsPL(BQB_PL_DEBUG)) m_IF.printf("REC_ImportTree(): Imported %d symbols.\n",z); } } void CBQBHuffmanTree::REC_PushCanonicalSymbol(CBQBHuffmanSymbol *sym, CBQBHuffmanSymbol *ts, unsigned long b, int depth) { // m_IF.printf("%d",b&1); if (depth > 1) { if (sym->m_oaChildren.size() == 0) { sym->m_oaChildren.push_back(new CBQBHuffmanSymbol()); sym->m_oaChildren.push_back(new CBQBHuffmanSymbol()); } REC_PushCanonicalSymbol(sym->m_oaChildren[b&1],ts,b>>1,depth-1); } else { if (sym->m_oaChildren.size() == 0) { if ((b&1) == 0) { sym->m_oaChildren.push_back(ts); sym->m_oaChildren.push_back(new CBQBHuffmanSymbol()); } else { sym->m_oaChildren.push_back(new CBQBHuffmanSymbol()); sym->m_oaChildren.push_back(ts); } } else { delete sym->m_oaChildren[b&1]; sym->m_oaChildren[b&1] = ts; } } } int CBQBHuffmanTree::REC_ImportTree(CBQBBitSet *bs, CBQBHuffmanSymbol *sym, int bits) { int i; i = 0; if (!bs->ReadBit()) { sym->m_oaChildren.push_back(new CBQBHuffmanSymbol()); sym->m_oaChildren.push_back(new CBQBHuffmanSymbol()); i += REC_ImportTree(bs,sym->m_oaChildren[0],bits); i += REC_ImportTree(bs,sym->m_oaChildren[1],bits); } else { sym->m_iSymbol = bs->ReadBitsInteger(bits); i++; } return i; } travis-src-190101/src/bqb_hufftree.h0100777000000000000000000001007213412725657014252 0ustar00/*********************************************************************************** LibBQB - File Format and Compression Algorithms for Trajectories of Volumetric Data and Atom Positions https://brehm-research.de/bqb Free software, licensed under GNU LGPL v3 Copyright (c) Martin Brehm and Martin Thomas, Martin Luther University Halle-Wittenberg, Germany, 2016 - 2019. Please cite: M. Brehm, M. Thomas: "An Efficient Lossless Compression Algorithm for Trajectories of Atom Positions and Volumetric Data", J. Chem. Inf. Model. 2018, 58 (10), pp 2092-2107. -------------------------------------------------------------------------------- LibBQB is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program. If not, see . ***********************************************************************************/ #ifndef BQB_HUFFTREE_H #define BQB_HUFFTREE_H // This must always be the first include directive #include "bqb_config.h" #include "bqb_tools.h" #include #include "bqb_bitset.h" class CBQBInterface; class CBQBHuffmanSymbol { public: CBQBHuffmanSymbol() : m_iSymbol(0), m_pBitString(NULL) { } ~CBQBHuffmanSymbol() { for (int z=0;z<(int)m_oaChildren.size();z++) delete m_oaChildren[z]; if (m_pBitString != NULL) delete m_pBitString; } void REC_BuildBitstrings(int depth); int m_iSymbol; int m_iDepth; int m_iFrequency; bool m_bVirtual; std::vector m_oaChildren; CBQBBitSet *m_pBitString; }; class CBQBHuffmanEstimator { public: void Init(int alphasize); unsigned int EstimateBitLength(const std::vector &ia); unsigned int EstimateBitLength(const std::vector &ia, int i2); unsigned int EstimateBitLength(const std::vector &ia, const std::vector &ia2); unsigned int EstimateBitLength(const std::vector &ia, const std::vector &ia2, const std::vector &ia3); void BuildBitLengthTable(const std::vector &ia); std::vector m_iaLength; private: std::vector m_iaTempFrequencies; std::vector m_iaTempHeap; std::vector m_iaTempParent; int m_iAlphaSize; }; class CBQBHuffmanTree { public: CBQBHuffmanTree(CBQBInterface &i) : m_pTree(NULL), m_iMaxBitLength(0), m_IF(i) { } ~CBQBHuffmanTree() { if (m_pTree != NULL) delete m_pTree; } int DecodeSymbol(CBQBBitSet *bs) const { CBQBHuffmanSymbol *hs = m_pTree; // printf("********\n"); while (hs->m_oaChildren.size() == 2) if (bs->ReadBit()) { // printf("A\n"); hs = hs->m_oaChildren[1]; } else { // printf("B\n"); hs = hs->m_oaChildren[0]; } return hs->m_iSymbol; } void Init(int alphasize); void BuildTree(bool canonical=false, bool showsymbols=false); void BuildPrelimTree(); void REC_BuildBitstringLengths(int depth, CBQBHuffmanSymbol *sym); int ExportTree(CBQBBitSet *bs, bool chr); int REC_ExportTree(CBQBBitSet *bs, CBQBHuffmanSymbol *sym, int bits); void ImportTree(CBQBBitSet *bs, bool chr); int REC_ImportTree(CBQBBitSet *bs, CBQBHuffmanSymbol *sym, int bits); void REC_PushCanonicalSymbol(CBQBHuffmanSymbol *sym, CBQBHuffmanSymbol *ts, unsigned long b, int depth); bool m_bCanonical; CBQBHuffmanSymbol *m_pTree; int m_iMaxBitLength; std::vector m_iaFrequencies; std::vector m_iaLengths; std::vector m_oaBitStrings; std::vector m_oaSymbols; std::vector m_oaTempSymbols; private: CBQBInterface &m_IF; }; #endif travis-src-190101/src/bqb_integerengine.cpp0100777000000000000000000015155613412725626015631 0ustar00/*********************************************************************************** LibBQB - File Format and Compression Algorithms for Trajectories of Volumetric Data and Atom Positions https://brehm-research.de/bqb Free software, licensed under GNU LGPL v3 Copyright (c) Martin Brehm and Martin Thomas, Martin Luther University Halle-Wittenberg, Germany, 2016 - 2019. Please cite: M. Brehm, M. Thomas: "An Efficient Lossless Compression Algorithm for Trajectories of Atom Positions and Volumetric Data", J. Chem. Inf. Model. 2018, 58 (10), pp 2092-2107. -------------------------------------------------------------------------------- LibBQB is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program. If not, see . ***********************************************************************************/ // This must always be the first include directive #include "bqb_config.h" #include "bqb_tools.h" #include #include "bqb_integerengine.h" #include "bqb_bitset.h" #include "bqb_parmset.h" #include "bqb_hufftree.h" #include "bqb_alphabet.h" #include "bqb_interface.h" const char *GetRevisionInfo_bqb_integerengine(unsigned int len) { static char buf[256]; GET_REVISION_INFO( buf, len ); return buf; } const char *GetSourceVersion_bqb_integerengine() { static char buf[256]; GET_SOURCE_VERSION( buf ); return buf; } bool SORT_InverseBW(const CBQBBWPair &p1, const CBQBBWPair &p2) { return p1.m_iSymbol < p2.m_iSymbol; } bool CBQBIntegerEngine::Compress( std::vector &inp, CBQBBitSet *outp, bool bw, bool mtf, bool coderun, int blocklength, int tables, bool opttables, bool chr, int maxiter, int maxchunk, CBQBStatistics *stat ) { CBQBParameterSet_Compressor parm(m_IF); parm.SetBW(bw); parm.SetMTF(mtf); parm.SetRLE(coderun); parm.SetBlockLength(blocklength); parm.SetTableCount(tables); parm.SetOptTables(opttables); parm.SetMaxIter(maxiter); parm.SetMaxChunk(maxchunk); return Compress( inp, outp, &parm, chr, stat ); } bool CBQBIntegerEngine::Compress( std::vector &inp, CBQBBitSet *outp, const CBQBParameterSet_Compressor *parm, bool chr, CBQBStatistics *stat ) { int i, z; std::vector tia; bool b; unsigned long tpos; int maxchunk; if (parm == NULL) { m_IF.eprintf("CBQBIntegerEngine::Compress(): Error: parm == NULL.\n"); abort(); } maxchunk = parm->GetMaxChunk(); if (m_IF.IsPL(BQB_PL_DEBUG)) { m_IF.printf("################################################\n"); m_IF.printf("### Entering CBQBIntegerEngine::Compress ###\n"); m_IF.printf("################################################\n"); m_IF.printf("Data size %lu, chunk size %d.\n",inp.size(),maxchunk); } if (inp.size() == 0) { m_IF.eprintf("CBQBIntegerEngine::Compress(): Error: Input array is empty.\n"); abort(); } tpos = outp->GetLength(); if (inp.size() > 1000) // Reserves 2 bits per integer in the beginning outp->m_iaData.reserve(outp->m_iaData.size()+inp.size()/4); // Magic number :-) outp->WriteBits(42,8); b = true; if ((maxchunk > 0) && ((int)inp.size() > maxchunk)) { i = (int)ceil((double)inp.size()/maxchunk); if (i > 256) { m_IF.eprintf("CBQBIntegerEngine::Compress(): More than 256 chunks not supported. Increase chunk size. (%d * %d = %lu)\n",i,maxchunk,inp.size()); return false; } if (m_IF.IsPL(BQB_PL_DEBUG)) m_IF.printf("Will write %d chunks.\n",i); outp->WriteBit(1); outp->WriteBits(i-1,8); i = 0; z = 0; while (i < (int)inp.size()) { if (m_IF.IsPL(BQB_PL_DEBUG)) m_IF.printf("### Chunk %d ###\n",z+1); if (i+maxchunk >= (int)inp.size()) tia.assign(inp.begin()+i,inp.end()); else tia.assign(inp.begin()+i,inp.begin()+i+maxchunk); if (stat != NULL) stat->m_oStat.m_lOverhead += outp->GetLength()-tpos; tpos = outp->GetLength(); if (!CompressSingle( tia, outp, parm, chr, stat )) { m_IF.eprintf("CBQBIntegerEngine::Compress(): CompressSingle returned an error in chunk %d.\n",z+1); b = false; goto _end; } i += maxchunk; z++; } } else { if (m_IF.IsPL(BQB_PL_DEBUG)) m_IF.printf("Will write one chunk.\n"); outp->WriteBit(0); // Only one chunk if (stat != NULL) stat->m_oStat.m_lOverhead += outp->GetLength()-tpos; tpos = outp->GetLength(); b = CompressSingle( inp, outp, parm, chr, stat ); } _end: if (m_IF.IsPL(BQB_PL_DEBUG)) { m_IF.printf("###############################################\n"); m_IF.printf("### Leaving CBQBIntegerEngine::Compress ###\n"); m_IF.printf("###############################################\n"); } return b; } bool CBQBIntegerEngine::Decompress( CBQBBitSet *inp, std::vector &outp, CBQBParameterSet_Compressor *parm ) { unsigned char uc; int i, z; bool b; b = true; if (m_IF.IsPL(BQB_PL_DEBUG)) { m_IF.printf("##################################################\n"); m_IF.printf("### Entering CBQBIntegerEngine::Decompress ###\n"); m_IF.printf("##################################################\n"); } uc = (unsigned char)inp->ReadBitsInteger(8); if (uc != 42) { m_IF.eprintf("CBQBIntegerEngine::Decompress(): Error in block begin marker: %d != 42.\n",uc); b = false; goto _end; } if (inp->ReadBit()) { i = inp->ReadBitsInteger(8)+1; if (m_IF.IsPL(BQB_PL_DEBUG)) m_IF.printf("Will read %d chunks.\n",i); for (z=0;z &inp, CBQBBitSet *outp, bool bw, bool mtf, bool coderun, int blocklength, int tables, bool opttables, bool chr, int maxiter, CBQBStatistics *stat ) { CBQBParameterSet_Compressor parm(m_IF); parm.SetBW(bw); parm.SetMTF(mtf); parm.SetRLE(coderun); parm.SetBlockLength(blocklength); parm.SetTableCount(tables); parm.SetOptTables(opttables); parm.SetMaxIter(maxiter); return CompressSingle( inp, outp, &parm, chr, stat ); } bool CBQBIntegerEngine::CompressSingle( std::vector &inp, CBQBBitSet *outp, const CBQBParameterSet_Compressor *parm, bool chr, CBQBStatistics *stat ) { CBQBAlphabet *alp; std::vector iasub, gu, asi, iasi, galp, tia, tia2, tiatrans, tfra; std::vector bestgu, bestasi, bestiasi; std::vector > lastfreq, bestfreq; int ibestfreq; int z, z2, i, k, ti, ti2, ti3, tio, nr, iter, beg, end, sw; int runtc, itables, stables, ttables, utables, ztables; int iruna, irunb, bits, bwindex; unsigned long tpos; double tf, tf2, tfx, fbestfreq; bool b, change; CBQBHuffmanTree *ht; std::vector hta; if (parm == NULL) { m_IF.eprintf("CBQBIntegerEngine::CompressSingle(): Error: parm == NULL.\n"); abort(); } bool bw = parm->GetBW(); bool mtf = parm->GetMTF(); bool coderun = parm->GetRLE(); int blocklength = parm->GetBlockLength(); int tables = parm->GetTableCount(); bool opttables = parm->GetOptTables(); int maxiter = parm->GetMaxIter(); if (m_IF.IsPL(BQB_PL_DEBUG)) { m_IF.printf("\n>>>>>>>>>>>>>>>>>>>>>>>>>>\n"); m_IF.printf(">>> CompressSingle >>>\n"); m_IF.printf(">>>>>>>>>>>>>>>>>>>>>>>>>>\n\n"); } if (inp.size() == 0) { m_IF.eprintf("CBQBIntegerEngine::CompressSingle(): Error: Input array is empty.\n"); abort(); } tpos = outp->GetLength(); tpos = outp->GetLength(); // Magic number :-) outp->WriteBits(23,6); if (chr) { if (m_IF.IsPL(BQB_PL_DEBUG)) m_IF.printf("Char flag was set.\n"); outp->WriteBit(1); } else { if (m_IF.IsPL(BQB_PL_DEBUG)) m_IF.printf("No char flag set.\n"); outp->WriteBit(0); } /* if (prerle) { if (verbose) m_IF.printf("Performing Pre-RLE transformation...\n"); outp->WriteBit(1); ti = 0; ti2 = 0; tiatrans.clear(); for (z=0;z<(int)inp.size();z++) { if ((inp[z] != ti) || (ti2 >= 255)) { if (ti2 >= 4) { for (z2=0;z2<4;z2++) tiatrans.push_back(ti); tiatrans.push_back(ti2-4); } else { for (z2=0;z2= 4) { for (z2=0;z2<4;z2++) tiatrans.push_back(ti); tiatrans.push_back(ti2-4); } else { for (z2=0;z2WriteBit(0); tiatrans.assign(inp.begin(),inp.end()); }*/ tiatrans.assign(inp.begin(),inp.end()); alp = new CBQBAlphabet(m_IF); alp->BuildAlphabet(tiatrans); if (bw) { if (IsAllIdentical(alp->m_iaIndices)) { if (m_IF.IsPL(BQB_PL_DEBUG)) m_IF.printf("!!! Array is \"all identical\" - skipping BW step !!!\n"); bw = false; } } if (bw) { if (m_IF.IsPL(BQB_PL_DEBUG)) m_IF.printf("*** Burrows-Wheeler Transformation ***\n"); outp->WriteBit(1); if (m_IF.IsPL(BQB_PL_DEBUG)) m_IF.printf("Preparing index buffer...\n"); //g_iaBW = &alp->m_iaIndices; m_iaBW = &alp->m_iaIndices; tia.resize(alp->m_iaIndices.size()); for (z=0;z<(int)tia.size();z++) tia[z] = z; if (m_IF.IsPL(BQB_PL_DEBUG)) m_IF.printf("Building run table...\n"); //BuildRunTable(*g_iaBW,g_iaBWRunTable); BuildRunTable(*m_iaBW,m_iaBWRunTable); if (m_IF.IsPL(BQB_PL_DEBUG)) m_IF.printf("Sorting...\n"); std::sort( tia.begin(), tia.end(), SSortBWRuntable(*this) ); //std::sort(tia.begin(),tia.end(),SORT_BW_Runtable); // std::sort(tia.begin(),tia.end(),SORT_BW); // std::stable_sort(tia.begin(),tia.end(),SORT_BW); if (m_IF.IsPL(BQB_PL_DEBUG)) m_IF.printf("Sorting done.\n"); if (m_IF.IsPL(BQB_PL_DEBUG)) m_IF.printf("BW Step...\n"); tiatrans.resize(tia.size()); bwindex = -1; for (z=0;z<(int)tia.size();z++) { if (tia[z] == 0) { bwindex = z; tiatrans[z] = alp->m_iaIndices[tia.size()-1]; } else tiatrans[z] = alp->m_iaIndices[tia[z]-1]; } /* FILE *tfi; unsigned char tuc; tfi = fopen("E:\\bwout.txt","wb"); for (z=0;z<(int)tia.size();z++) { tuc = alp->m_oaAlphabet[tiatrans[z]]->m_iSymbol; fwrite(&tuc,1,1,tfi); } fclose(tfi);*/ if (bwindex < 256) { if (m_IF.IsPL(BQB_PL_DEBUG)) m_IF.printf("BW Index is %d, using short storage.\n",bwindex); outp->WriteBit(0); outp->WriteBits(bwindex,8); } else { bits = (int)ceil(mylog2(bwindex+1)); if (m_IF.IsPL(BQB_PL_DEBUG)) m_IF.printf("BW Index is %d, storing with %d bits.\n",bwindex,bits); outp->WriteBit(1); outp->WriteBits(bits,6); outp->WriteBits(bwindex,bits); } tia.clear(); if (m_IF.IsPL(BQB_PL_DEBUG)) m_IF.printf("*** Burrows-Wheeler Finished ***\n"); } else { outp->WriteBit(0); tiatrans.assign(alp->m_iaIndices.begin(),alp->m_iaIndices.end()); } if (mtf) { if (m_IF.IsPL(BQB_PL_DEBUG)) m_IF.printf("Move-To-Front Transformation...\n"); outp->WriteBit(1); galp.resize(alp->m_oaAlphabet.size()); tia.resize(tiatrans.size()); for (z=0;z<(int)galp.size();z++) galp[z] = z; for (z=0;z<(int)tiatrans.size();z++) { for (z2=0;z2<(int)galp.size();z2++) if (tiatrans[z] == galp[z2]) break; // if ((z >= 4040534-10) && (z <= 4040534+10)) // m_IF.printf("%9d: %4d --> %9d\n",z,tiatrans[z],z2); tia[z] = z2; if (z2 != 0) MoveToFrontIndex(galp,z2); /* if (tiatrans[z] == galp[0]) tia[z] = 0; else tia[z] = MoveToFront(galp,tiatrans[z]);*/ /* for (z2=0;z2<(int)galp.size();z2++) if (tiatrans[z] == galp[z2]) break; tia[z] = z2; if (z2 != 0) std::iter_swap(galp.begin(),galp.begin()+z2);*/ } tiatrans.assign(tia.begin(),tia.end()); tia.clear(); } else outp->WriteBit(0); if (coderun) { outp->WriteBit(1); iruna = alp->FindIndex(C_RUNA); irunb = alp->FindIndex(C_RUNB); if (m_IF.IsPL(BQB_PL_DEBUG)) m_IF.printf("Encoding code runs (RUNA=%d, RUNB=%d)...\n",iruna,irunb); runtc = 0; ti = (int)alp->m_oaAlphabet.size()+100; for (i=0;i<(int)tiatrans.size();i++) { if (i != 0) { if (tiatrans[i] != ti) { // if (runtc != 0) { //if (/*(runtc+1 >= 5) && */(ti == 0)) if (ti == 0) PushNumeration(tia,runtc+1,iruna,irunb); else for (z=0;z= 5) && */(ti == 0)) if (ti == 0) PushNumeration(tia,runtc+1,iruna,irunb); else for (z=0;zRecalcFrequencies(tia); if (m_IF.IsPL(BQB_PL_DEBUG)) m_IF.printf("Done. Compressed %lu to %lu symbols.\n",tiatrans.size(),tia.size()); // for (z=0;z<(int)tia.size();z++) // m_IF.printf("@ %2d: %d\n",z+1,tia[z]); tiatrans.assign(tia.begin(),tia.end()); tia.clear(); } else outp->WriteBit(0); if (stat != NULL) stat->m_oStat.m_lOverhead += outp->GetLength()-tpos; tpos = outp->GetLength(); tia.assign(tiatrans.begin(),tiatrans.end()); if (m_IF.IsPL(BQB_PL_DEBUG)) m_IF.printf("Writing alphabet...\n"); i = outp->GetLength(); alp->Export(outp,true,chr); if (m_IF.IsPL(BQB_PL_DEBUG)) m_IF.printf("%d Bytes written.\n",(outp->GetLength()-i)/8); if (stat != NULL) stat->m_oStat.m_lAlphabet += outp->GetLength()-tpos; tpos = outp->GetLength(); if (tables == 1) { _onetab: outp->WriteBit(0); outp->WriteBits(0,3); if (m_IF.IsPL(BQB_PL_DEBUG)) m_IF.printf("Creating Huffman tree...\n"); ht = new CBQBHuffmanTree(m_IF); ht->Init((int)alp->m_oaAlphabet.size()); for (z=0;z<(int)tia.size();z++) ht->m_iaFrequencies[tia[z]]++; ht->BuildTree(true); if (stat != NULL) stat->m_oStat.m_lOverhead += outp->GetLength()-tpos; tpos = outp->GetLength(); i = outp->GetLength(); ht->ExportTree(outp,chr); if (stat != NULL) stat->m_oStat.m_lHuffmanTables += outp->GetLength()-tpos; tpos = outp->GetLength(); if (m_IF.IsPL(BQB_PL_DEBUG)) { m_IF.printf("%d Bytes (%d Bits) written.\n",(outp->GetLength()-i)/8,outp->GetLength()-i); m_IF.printf("Writing Huffman-encoded data...\n"); } bits = (int)ceil(mylog2((double)tia.size()+1)); if (m_IF.IsPL(BQB_PL_DEBUG)) m_IF.printf("%lu symbols to be written, using %d bits for symbol count.\n",tia.size(),bits); outp->WriteBits(bits,6); outp->WriteBits((unsigned long)tia.size(),bits); if (stat != NULL) stat->m_oStat.m_lOverhead += outp->GetLength()-tpos; tpos = outp->GetLength(); k = outp->GetLength(); for (z=0;z<(int)tia.size();z++) outp->WriteBits(ht->m_oaBitStrings[tia[z]]); if (m_IF.IsPL(BQB_PL_DEBUG)) m_IF.printf("%d Bytes (%d Bits) written.\n",(outp->GetLength()-k)/8,outp->GetLength()-k); if (stat != NULL) stat->m_oStat.m_lHuffmanData += outp->GetLength()-tpos; tpos = outp->GetLength(); delete ht; } else { // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! /* if (preopt) { // Alternative multi-table optimization // if (true) { // Alternative multi-table optimization MultiHuffmanOptimize(tables,hta,alp,tia,asi,iasi,blocklength,verbose); // itables = tables; itables = (int)hta.size(); for (z=0;zBuildPrelimTree(); } else { // Classical multi-table optimization*/ if (opttables) { stables = 1000000000; itables = 1; for (ztables=1;ztables<=tables;ztables++) { ttables = ztables; utables = 0; if (ttables == 1) { utables += 4; if (m_IF.IsPL(BQB_PL_DEBUG)) m_IF.printf("$1 Creating Huffman tree...\n"); ht = new CBQBHuffmanTree(m_IF); ht->Init((int)alp->m_oaAlphabet.size()); for (z=0;z<(int)tia.size();z++) ht->m_iaFrequencies[tia[z]]++; ht->BuildTree(true); utables += ht->ExportTree(NULL,chr); if (m_IF.IsPL(BQB_PL_DEBUG)) m_IF.printf("$1 Writing Huffman-encoded data...\n"); bits = (int)ceil(mylog2((double)tia.size()+1)); if (m_IF.IsPL(BQB_PL_DEBUG)) m_IF.printf("$1 %lu symbols to be written, using %d bits for symbol count.\n",tia.size(),bits); utables += 5+bits; for (z=0;z<(int)tia.size();z++) utables += ht->m_oaBitStrings[tia[z]]->GetLength(); delete ht; } else { ti = 0; tio = 0; nr = (int)tia.size(); hta.clear(); if (m_IF.IsPL(BQB_PL_DEBUG)) m_IF.printf("$%d Initializing table populations...\n",ttables); for (i=0;iInit((int)alp->m_oaAlphabetSortFreq.size()); hta.push_back(ht); ti2 = 0; while ((ti2 < nr/(ttables-i)) && (ti < (int)alp->m_oaAlphabetSortFreq.size())) ti2 += alp->m_oaAlphabetSortFreq[ti++]->m_iFrequency; if ((i != 0) && (i != ttables) && ((i%2) == 1) && (ti < (int)alp->m_oaAlphabetSortFreq.size()) && (ti > tio+1)) { ti--; ti2 -= alp->m_oaAlphabetSortFreq[ti]->m_iFrequency; } if (m_IF.IsPL(BQB_PL_DEBUG)) m_IF.printf("$%d Group %2d: Symbols %5d .. %5d / %lu, Count %8d (%7.3f%%)\n",ttables,i+1,tio+1,ti,alp->m_oaAlphabetSortFreq.size(),ti2,(double)ti2/alp->m_iaIndices.size()*100.0); for (z=0;z<(int)alp->m_oaAlphabetSortFreq.size();z++) if ((z >= tio) && (z < ti)) ht->m_iaLengths[alp->m_oaAlphabetSortFreq[z]->m_iIndex] = 0; else ht->m_iaLengths[alp->m_oaAlphabetSortFreq[z]->m_iIndex] = 20; tio = ti; nr -= ti2; } if (m_IF.IsPL(BQB_PL_DEBUG)) m_IF.printf("$%d Starting optimization...\n",ttables); iasub.resize(blocklength); asi.resize(tia.size()/blocklength+1); iasi.resize(tia.size()/blocklength+1); gu.resize(ttables); galp.resize(ttables); tf2 = -3456.0; iter = 0; while (true) { i = 0; for (z=0;zm_oaAlphabet.size();z++) hta[k]->m_iaFrequencies[z] = 0; tf = 0; tfx = 0; sw = 0; beg = 0; for (z=0;z= (int)tia.size()) end = ((int)tia.size())-1; ti = 5000000; ti2 = -1; ti3 = -1; for (k=0;km_iaLengths[tia[z]]; for (z=0;z 1) tio += z+1; if (tio < ti) { ti = tio; ti2 = k; ti3 = z; } } asi[i] = ti2; iasi[i] = ti3; tfx += ti3+1; gu[ti2]++; if (ti3 != 0) { MoveToFrontIndex(galp,ti3); //std::iter_swap(galp.begin(),galp.begin()+ti3); sw++; } for (z=beg;z<=end;z++) hta[ti2]->m_iaFrequencies[tia[z]]++; tf += ti/8.0; beg = end+1; i++; if (beg == (int)tia.size()) break; } if (m_IF.IsPL(BQB_PL_DEBUG)) m_IF.printf("$%d Iteration %2d, Total size: %8.3f KiB\n",ttables,iter+1,tf/1024.0); for (z=0;zBuildPrelimTree(); if (tf2 == tf) break; tf2 = tf; iter++; if (iter > 40) { if (m_IF.IsPL(BQB_PL_DEBUG)) m_IF.printf("$%d Warning: Multi-Huffman optimization did not converge after 40 iterations.\n",ttables); break; } } if (m_IF.IsPL(BQB_PL_DEBUG)) m_IF.printf("$%d Group statistics:\n",ttables); tf2 = tfx/8.0; b = false; for (z=0;zBuildTree(true); if (m_IF.IsPL(BQB_PL_DEBUG)) m_IF.printf("$%d %d: %5.2f%%, %6d blocks, %5lu/%5lu symbols, maxlen %d bits\n",ttables,z+1,(double)gu[z]/tia.size()*blocklength*100.0,gu[z],hta[z]->m_oaSymbols.size(),alp->m_oaAlphabet.size(),hta[z]->m_iMaxBitLength); if (hta[z]->m_pTree == NULL) { if (m_IF.IsPL(BQB_PL_DEBUG)) m_IF.printf("$%d Warning: Empty Huffman tree (%d/%d).\n",ttables,z+1,ttables); b = true; } tf2 += tf; } if (m_IF.IsPL(BQB_PL_DEBUG)) m_IF.printf("$%d Exporting Huffman trees...\n",ttables); if (b) { if (m_IF.IsPL(BQB_PL_DEBUG)) m_IF.printf("$%d Removing empty trees and reorganizing structures...\n",ttables); tia2.clear(); z2 = 0; for (z=0;zm_pTree != NULL) z2++; } ttables = z2; if (m_IF.IsPL(BQB_PL_DEBUG)) m_IF.printf("$%d Now only %d tables left.\n",ttables,ttables); for (z=0;z<(int)hta.size();z++) { if (hta[z]->m_pTree == NULL) { delete hta[z]; hta.erase(hta.begin()+z); z--; } } galp.resize(ttables); for (z=0;zExportTree(NULL,chr); } bits = (int)ceil(mylog2((double)tia.size()+1)); if (m_IF.IsPL(BQB_PL_DEBUG)) { m_IF.printf("$%d Writing Huffman-encoded data...\n",ttables); m_IF.printf("$%d %lu symbols to be written, using %d bits for symbol count.\n",ttables,tia.size(),bits); } utables += 5+bits; beg = 0; i = 0; while (true) { end = beg+blocklength-1; if (end >= (int)tia.size()) end = ((int)tia.size())-1; utables += iasi[i]+1; for (z=beg;z<=end;z++) utables += hta[asi[i]]->m_oaBitStrings[tia[z]]->GetLength(); beg = end+1; i++; if (beg == (int)tia.size()) break; } for (i=0;iInit((int)alp->m_oaAlphabetSortFreq.size()); hta.push_back(ht); ti2 = 0; while ((ti2 < nr/(itables-i)) && (ti < (int)alp->m_oaAlphabetSortFreq.size())) ti2 += alp->m_oaAlphabetSortFreq[ti++]->m_iFrequency; if ((i != 0) && (i != itables) && ((i%2) == 1) && (ti < (int)alp->m_oaAlphabetSortFreq.size()) && (ti > tio+1)) { ti--; ti2 -= alp->m_oaAlphabetSortFreq[ti]->m_iFrequency; } if (m_IF.IsPL(BQB_PL_DEBUG)) m_IF.printf(" Group %2d: Symbols %5d .. %5d / %lu, Count %8d (%7.3f%%)\n",i+1,tio+1,ti,alp->m_oaAlphabetSortFreq.size(),ti2,(double)ti2/tia.size()*100.0); for (z=0;z<(int)alp->m_oaAlphabetSortFreq.size();z++) if ((z >= tio) && (z < ti)) ht->m_iaLengths[alp->m_oaAlphabetSortFreq[z]->m_iIndex] = 0; else ht->m_iaLengths[alp->m_oaAlphabetSortFreq[z]->m_iIndex] = 20; tio = ti; nr -= ti2; } for (k=0;km_oaAlphabet.size();z++) hta[k]->m_iaFrequencies[z] = 0; // } // End if preopt if (m_IF.IsPL(BQB_PL_DEBUG)) m_IF.printf("Starting optimization...\n"); iasub.resize(blocklength); asi.resize(tia.size()/blocklength+1); iasi.resize(tia.size()/blocklength+1); gu.resize(itables); galp.resize(itables); // lastfreq.resize(itables); bestfreq.resize(itables); /* CHuffmanEstimator he; std::vector > tmatrix; m_IF.printf("Building tmatrix...\n"); he.Init(alp->m_oaAlphabet.size()); tmatrix.resize(tia.size()/blocklength+1); for (z=0;zm_oaAlphabet.size()); for (z2=0;z2m_oaAlphabet.size();z2++) tmatrix[z][z2] = 0; } for (z=0;z<(int)tia.size();z++) tmatrix[z/blocklength][tia[z]]++; m_IF.printf("Done.\n");*/ tf2 = -3456.0; iter = 0; fbestfreq = 1.0e20; ibestfreq = -10; while (true) { i = 0; for (z=0;zm_oaAlphabet.size();z++) hta[k]->m_iaFrequencies[z] /= 2; // hta[k]->m_iaFrequencies[z] = 0; for (z=0;z= (int)tia.size()) end = ((int)tia.size())-1; ti = 5000000; ti2 = -1; ti3 = -1; for (k=0;km_iaFrequencies.begin(),hta[k]->m_iaFrequencies.end()); tio = 0; for (z=beg;z<=end;z++) { tio += hta[k]->m_iaLengths[tia[z]]; if (tfra[tia[z]] == 0) { tfra[tia[z]]++; tio += 1; // tio += 1+(gu[k]*5)/(i+1); } } for (z=0;z 1) tio += z+1; if (tio < ti) { ti = tio; ti2 = k; ti3 = z; } } if (asi[i] != ti2) change = true; asi[i] = ti2; iasi[i] = ti3; tfx += ti3+1; gu[ti2]++; if (ti3 != 0) { MoveToFrontIndex(galp,ti3); //std::iter_swap(galp.begin(),galp.begin()+ti3); sw++; } for (z=beg;z<=end;z++) hta[ti2]->m_iaFrequencies[tia[z]]++; tf += ti/8.0; beg = end+1; i++; if (beg == (int)tia.size()) break; } /* for (i=0;im_iaFrequencies.begin(),hta[k]->m_iaFrequencies.end()); tio = he.EstimateBitLength(hta[k]->m_iaFrequencies,tmatrix[i]); // printf("C%d\n",k); for (z=0;z 1) tio += z+1; if (tio < ti) { ti = tio; ti2 = k; ti3 = z; } } asi[i] = ti2; iasi[i] = ti3; tfx += ti3+1; gu[ti2]++; if (ti3 != 0) { std::iter_swap(galp.begin(),galp.begin()+ti3); sw++; } // for (z=beg;z<=end;z++) // hta[ti2]->m_iaFrequencies[tia[z]]++; for (z=0;z<(int)alp->m_oaAlphabet.size();z++) hta[ti2]->m_iaFrequencies[z] += tmatrix[i][z]; tf += ti/8.0; }*/ if (m_IF.IsPL(BQB_PL_DEBUG)) m_IF.printf(" Iteration %2d, Total size: %8.3f KiB\n",iter+1,tf/1024.0); // m_IF.printf("$ %d\n",hta[1]->m_iaFrequencies[1492]); if (tf < fbestfreq) { fbestfreq = tf; for (z=0;zm_iaFrequencies.begin(),hta[z]->m_iaFrequencies.end()); // bestfreq[z].assign(lastfreq[z].begin(),lastfreq[z].end()); // bestgu.assign(gu.begin(),gu.end()); bestasi.assign(asi.begin(),asi.end()); bestiasi.assign(iasi.begin(),iasi.end()); ibestfreq = iter; } for (z=0;zBuildPrelimTree(); if (!change) break; tf2 = tf; iter++; // if (alp->m_oaAlphabet.size() > 500) // break; // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! if (iter >= maxiter) { if (m_IF.IsPL(BQB_PL_DEBUG)) m_IF.printf("Multi-Huffman optimization did not converge.\n"); break; } } if (m_IF.IsPL(BQB_PL_DEBUG)) m_IF.printf("Best result in iteration %d.\n",ibestfreq+1); if (iter != 1) { // gu.assign(bestgu.begin(),bestgu.end()); asi.assign(bestasi.begin(),bestasi.end()); iasi.assign(bestiasi.begin(),bestiasi.end()); for (z=0;zm_iaFrequencies.assign(bestfreq[z].begin(),bestfreq[z].end()); hta[z]->BuildPrelimTree(); } } // } for (k=0;km_oaAlphabet.size();z++) hta[k]->m_iaFrequencies[z] = 0; beg = 0; i = 0; while (true) { end = beg+blocklength-1; if (end >= (int)tia.size()) end = ((int)tia.size())-1; for (z=beg;z<=end;z++) hta[asi[i]]->m_iaFrequencies[tia[z]]++; beg = end+1; if (beg == (int)tia.size()) break; i++; } // m_IF.printf("$$ %d\n",hta[1]->m_iaFrequencies[1492]); gu.resize(itables); for (z=0;zBuildTree(true); tf = 0; for (z2=0;z2<(int)alp->m_oaAlphabet.size();z2++) tf += hta[z]->m_iaLengths[z2] * hta[z]->m_iaFrequencies[z2]; if (m_IF.IsPL(BQB_PL_DEBUG) && (hta[z]->m_pTree != NULL)) m_IF.printf(" %2d: %5.2f%%, %6d blocks, %5lu/%5lu symbols, %6.3f bits/symbol, maxlen %d bits\n",z+1,(double)gu[z]/tia.size()*blocklength*100.0,gu[z],hta[z]->m_oaSymbols.size(),alp->m_oaAlphabet.size(),tf/gu[z]/blocklength,hta[z]->m_iMaxBitLength); if (hta[z]->m_pTree == NULL) { // if (verbose) // m_IF.printf("Warning: Empty Huffman tree (%d/%d).\n",z+1,itables); b = true; } tf2 += tf; } if (m_IF.IsPL(BQB_PL_DEBUG)) m_IF.printf("Exporting Huffman trees...\n"); if (b) { if (m_IF.IsPL(BQB_PL_DEBUG)) m_IF.printf("Removing empty trees and reorganizing structures...\n"); tia2.clear(); z2 = 0; for (z=0;zm_pTree != NULL) z2++; } itables = z2; if (m_IF.IsPL(BQB_PL_DEBUG)) m_IF.printf("Now only %d tables left.\n",itables); for (z=0;z<(int)hta.size();z++) { if (hta[z]->m_pTree == NULL) { delete hta[z]; hta.erase(hta.begin()+z); z--; } } galp.resize(itables); for (z=0;zWriteBit(0); outp->WriteBits(itables-1,3); } else { if (m_IF.IsPL(BQB_PL_DEBUG)) m_IF.printf("Have %d > 8 Huffman trees, using long storage.\n",itables); if (itables >= 1024) { m_IF.eprintf("CBQBIntegerEngine::CompressSingle(): Error: More than 1023 Huffman trees not supported (have %d).\n",itables); abort(); } outp->WriteBit(1); outp->WriteBits(itables-1,10); } outp->WriteBits(blocklength,8); if (stat != NULL) stat->m_oStat.m_lOverhead += outp->GetLength()-tpos; tpos = outp->GetLength(); i = outp->GetLength(); for (z=0;zExportTree(outp,chr); } if (stat != NULL) stat->m_oStat.m_lHuffmanTables += outp->GetLength()-tpos; tpos = outp->GetLength(); bits = (int)ceil(mylog2((double)tia.size()+1)); if (m_IF.IsPL(BQB_PL_DEBUG)) { m_IF.printf("%d Bytes written.\n",(outp->GetLength()-i)/8); m_IF.printf("Writing Huffman-encoded data...\n"); m_IF.printf("%lu symbols to be written, using %d bits for symbol count.\n",tia.size(),bits); } outp->WriteBits(bits,6); outp->WriteBits((unsigned long)tia.size(),bits); /* std::vector blu, blu2; blu.resize(alp->m_oaAlphabet.size()); blu2.resize(alp->m_oaAlphabet.size()); for (z=0;z<(int)alp->m_oaAlphabet.size();z++) blu[z] = 0;*/ if (stat != NULL) stat->m_oStat.m_lOverhead += outp->GetLength()-tpos; tpos = outp->GetLength(); k = outp->GetLength(); beg = 0; i = 0; ti = 0; while (true) { // m_IF.printf("*** Block %d ***\n",i+1); end = beg+blocklength-1; if (end >= (int)tia.size()) end = ((int)tia.size())-1; /* for (z=0;z<(int)alp->m_oaAlphabet.size();z++) blu2[z] = 0; for (z=beg;z<=end;z++) blu2[tia[z]]++; ti = 0; for (z=0;z<(int)alp->m_oaAlphabet.size();z++) if (blu2[z] != 0) ti++; blu[ti]++; */ for (z=0;zWriteBit(1); outp->WriteBit(0); ti += iasi[i]+1; if (stat != NULL) stat->m_oStat.m_lTableSwitch += outp->GetLength()-tpos; tpos = outp->GetLength(); // m_IF.printf("A %d\n",asi[i]); for (z=beg;z<=end;z++) { /* if (i == 5804) { m_IF.printf(" %3d / %3lu\n",tia[z],hta[asi[i]]->m_oaBitStrings.size()); m_IF.printf(" @ %08X %d\n",hta[asi[i]]->m_oaBitStrings[tia[z]],hta[asi[i]]->m_iaFrequencies[tia[z]]); m_IF.printf(" @ %d\n",hta[asi[i]]->m_oaBitStrings[tia[z]]->GetLength()); }*/ outp->WriteBits(hta[asi[i]]->m_oaBitStrings[tia[z]]); } if (stat != NULL) stat->m_oStat.m_lHuffmanData += outp->GetLength()-tpos; tpos = outp->GetLength(); beg = end+1; i++; if (beg == (int)tia.size()) break; } if (m_IF.IsPL(BQB_PL_DEBUG)) m_IF.printf("%d Bytes written (including %d Bytes Switching penalty).\n",(outp->GetLength()-k)/8,ti/8); ti = i; for (i=0;im_oaAlphabet.size() < 10000) { m_IF.printf("Block statistics (%d blocks in total):\n",ti); for (z=0;z<(int)alp->m_oaAlphabet.size();z++) if (blu[z] != 0) m_IF.printf(" %6d/%6lu symbols: %6d (%5.2f%%)\n",z,alp->m_oaAlphabet.size(),blu[z],blu[z]*100.0/ti); }*/ /* if (alp->m_oaAlphabet.size() == 130) { FILE *tta; tta = fopen("matrix.nb","wt"); fprintf(tta,"{ \n"); beg = 0; while (true) { end = beg+blocklength-1; if (end >= (int)tia.size()) end = ((int)tia.size())-1; for (z=0;z<(int)alp->m_oaAlphabet.size();z++) blu2[z] = 0; for (z=beg;z<=end;z++) blu2[tia[z]]++; fprintf(tta,"{ "); for (z=0;z<(int)alp->m_oaAlphabet.size();z++) { fprintf(tta,"%d",blu2[z]); if (z+1 < alp->m_oaAlphabet.size()) fprintf(tta,","); } fprintf(tta,"}"); beg = end+1; if (beg == (int)tia.size()) break; fprintf(tta,",\n"); } fprintf(tta," }\n"); fclose(tta); abort(); }*/ } delete alp; if (m_IF.IsPL(BQB_PL_DEBUG)) { m_IF.printf("\n<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n"); m_IF.printf("<<< CompressSingle Done <<<\n"); m_IF.printf("<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n\n"); } return true; } bool CBQBIntegerEngine::DecompressSingle( CBQBBitSet *inp, std::vector &outp, CBQBParameterSet_Compressor *parm ) { CBQBAlphabet *alp; int i, k, z, z2, c, dc, ti, ti2, bits; int blocklength, tables, iruna, irunb, bwindex; std::vector hta; CBQBHuffmanTree *ht; std::vector galp, tia, tiatrans; std::vector tbwpairs; bool bw, mtf, coderun, chr; if (m_IF.IsPL(BQB_PL_DEBUG)) { m_IF.printf("\n>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n"); m_IF.printf(">>> DecompressSingle >>>\n"); m_IF.printf(">>>>>>>>>>>>>>>>>>>>>>>>>>>>\n\n"); } if (m_IF.IsPL(BQB_PL_DEBUG)) m_IF.printf("Checking block begin magic number (6 bits)...\n"); i = inp->ReadBitsInteger(6); if (m_IF.IsPL(BQB_PL_DEBUG)) m_IF.printf("Found %d.\n",i); if (i != 23) { m_IF.eprintf("CBQBIntegerEngine::Decompress(): Error in block begin: %d != 23.\n",i); return false; } chr = inp->ReadBit(); if (m_IF.IsPL(BQB_PL_DEBUG)) { if (chr) m_IF.printf("Found char flag.\n"); else m_IF.printf("No char flag found.\n"); } bwindex = -1; if (inp->ReadBit()) { bw = true; if (m_IF.IsPL(BQB_PL_DEBUG)) m_IF.printf("Burrows-Wheeler transform was applied.\n"); if (inp->ReadBit()) { bits = inp->ReadBitsInteger(6); bwindex = inp->ReadBitsInteger(bits); } else bwindex = inp->ReadBitsInteger(8); if (m_IF.IsPL(BQB_PL_DEBUG)) m_IF.printf("Burrows-Wheeler index is %d.\n",bwindex); } else { bw = false; if (m_IF.IsPL(BQB_PL_DEBUG)) m_IF.printf("No Burrows-Wheeler transform.\n"); } if (parm != NULL) parm->SetBW(bw); if (inp->ReadBit()) { mtf = true; if (m_IF.IsPL(BQB_PL_DEBUG)) m_IF.printf("Move-to-Front was applied.\n"); } else { mtf = false; if (m_IF.IsPL(BQB_PL_DEBUG)) m_IF.printf("No Move-to-Front.\n"); } if (parm != NULL) parm->SetMTF(mtf); if (inp->ReadBit()) { coderun = true; if (m_IF.IsPL(BQB_PL_DEBUG)) m_IF.printf("CodeRun was applied.\n"); } else { coderun = false; if (m_IF.IsPL(BQB_PL_DEBUG)) m_IF.printf("No CodeRun.\n"); } if (parm != NULL) parm->SetRLE(coderun); alp = new CBQBAlphabet(m_IF); if (m_IF.IsPL(BQB_PL_DEBUG)) m_IF.printf("Reading alphabet...\n"); i = inp->GetReadPos(); alp->Import(inp,chr); if (m_IF.IsPL(BQB_PL_DEBUG)) m_IF.printf("%d Bytes read, %lu symbol types.\n",(inp->GetReadPos()-i)/8,alp->m_oaAlphabet.size()); if (inp->ReadBit()) { tables = inp->ReadBitsInteger(10)+1; if (m_IF.IsPL(BQB_PL_DEBUG)) m_IF.printf("Using %d Huffman tables (long storage).\n",tables); } else { tables = inp->ReadBitsInteger(3)+1; if (m_IF.IsPL(BQB_PL_DEBUG)) m_IF.printf("Using %d Huffman tables (short storage).\n",tables); } if (parm != NULL) parm->SetTableCount(tables); if (tables > 1) { blocklength = inp->ReadBitsInteger(8); if (m_IF.IsPL(BQB_PL_DEBUG)) m_IF.printf("Using a block length of %d.\n",blocklength); if (parm != NULL) parm->SetBlockLength(blocklength); if (m_IF.IsPL(BQB_PL_DEBUG)) m_IF.printf("Importing Huffman trees...\n"); i = inp->GetReadPos(); hta.resize(tables); for (z=0;zImportTree(inp,chr); } if (m_IF.IsPL(BQB_PL_DEBUG)) { m_IF.printf("%d Bytes read.\n",(inp->GetReadPos()-i)/8); m_IF.printf("Importing and decoding data stream...\n"); } bits = inp->ReadBitsInteger(6); if (m_IF.IsPL(BQB_PL_DEBUG)) m_IF.printf("Symbol count stored with %d bits.\n",bits); dc = inp->ReadBitsInteger(bits); if (m_IF.IsPL(BQB_PL_DEBUG)) m_IF.printf("Expecting %d symbols.\n",dc); k = inp->GetReadPos(); galp.resize(tables); for (z=0;zReadBit()) z++; ti = galp[z]; if (z != 0) MoveToFrontIndex(galp,z); //std::iter_swap(galp.begin(),galp.begin()+z); if ((i+1)*blocklength < dc) c = blocklength; else c = dc-(i*blocklength); for (z=0;zDecodeSymbol(inp)); i++; if (i*blocklength >= dc) break; } if (m_IF.IsPL(BQB_PL_DEBUG)) m_IF.printf("%d Bytes read.\n",(inp->GetReadPos()-k)/8); for (z=0;zGetReadPos(); ht = new CBQBHuffmanTree(m_IF); ht->ImportTree(inp,chr); if (m_IF.IsPL(BQB_PL_DEBUG)) { m_IF.printf("%d Bytes read.\n",(inp->GetReadPos()-i)/8); m_IF.printf("Importing and decoding data stream...\n"); } bits = inp->ReadBitsInteger(6); if (m_IF.IsPL(BQB_PL_DEBUG)) m_IF.printf("Symbol count stored with %d bits.\n",bits); dc = inp->ReadBitsInteger(bits); if (m_IF.IsPL(BQB_PL_DEBUG)) m_IF.printf("Expecting %d symbols.\n",dc); k = inp->GetReadPos(); tia.clear(); for (z=0;zDecodeSymbol(inp)); // if (dc < 5) // m_IF.printf("@@@ %d\n",(int)tia[tia.size()-1]); } if (m_IF.IsPL(BQB_PL_DEBUG)) m_IF.printf("%d Bytes (%d bits) read.\n",(inp->GetReadPos()-k)/8,inp->GetReadPos()-k); delete ht; } tiatrans.assign(tia.begin(),tia.end()); if (coderun) { tia.clear(); iruna = alp->FindIndex(C_RUNA); irunb = alp->FindIndex(C_RUNB); if (m_IF.IsPL(BQB_PL_DEBUG)) m_IF.printf("Decoding code runs (RUNA=%d, RUNB=%d)...\n",iruna,irunb); ti = 1; ti2 = 0; for (z=0;z<(int)tiatrans.size();z++) { if (tiatrans[z] == iruna) { ti2 += ti; ti *= 2; } else if (tiatrans[z] == irunb) { ti2 += 2*ti; ti *= 2; } else { ti = 1; for (z2=0;z2m_oaAlphabet.size()); for (z=0;z<(int)alp->m_oaAlphabet.size();z++) galp[z] = z; for (z=0;z<(int)tia.size();z++) { // if ((z >= 4040534-10) && (z <= 4040534+10)) // m_IF.printf("%9d: %4d --> %9d\n",z,tia[z],galp[tia[z]]); if (tia[z] != 0) MoveToFrontIndex(galp,tia[z]); //std::iter_swap(galp.begin(),galp.begin()+tia[z]); tiatrans[z] = galp[0]; } } if (bw) { if (m_IF.IsPL(BQB_PL_DEBUG)) m_IF.printf("Performing inverse Burrows-Wheeler transform...\n"); tia.assign(tiatrans.begin(),tiatrans.end()); tbwpairs.clear(); for (z=0;z<(int)tia.size();z++) tbwpairs.push_back(CBQBBWPair(tia[z],z)); std::stable_sort(tbwpairs.begin(),tbwpairs.end(),SORT_InverseBW); ti = bwindex; for (z=0;z<(int)tia.size();z++) { tiatrans[z] = tbwpairs[ti].m_iSymbol; ti = tbwpairs[ti].m_iIndex; } } if (m_IF.IsPL(BQB_PL_DEBUG)) m_IF.printf("Converting indices to original alphabet symbols...\n"); outp.reserve(outp.size()+tiatrans.size()); for (z=0;z<(int)tiatrans.size();z++) outp.push_back(alp->m_oaAlphabet[tiatrans[z]]->m_iSymbol); delete alp; if (m_IF.IsPL(BQB_PL_DEBUG)) { m_IF.printf("\n<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n"); m_IF.printf("<<< DecompressSingle Done <<<\n"); m_IF.printf("<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n\n"); } return true; } /* void CBQBIntegerEngine::MultiHuffmanOptimize(int tables, std::vector &hta, CBQBAlphabet *alp, std::vector &tia, std::vector &asi, std::vector &iasi, int blocklength, bool verbose) { UNUSED(tables); UNUSED(asi); UNUSED(iasi); //std::vector > tmatrix; std::vector galp; int z, z2, z0, ti, ti2, tii, zi; int sc, payload, trees, blockendsum; CBQBHuffmanTree ht(m_IF), *pht; CBQBHuffmanEstimator he; double nsizeold, nsizenew, nsize, minval; std::vector tfra, tsize, tpop, imintfra; std::vector > told; int lasttree, treemalus, symbmalus, ii, switchmalussum, iminval, lookahead, lastpos, imintii, iminsc, iskip; int blc, iminti, iminti2, ti4; //int z3, za, tibest, ti3; //int mic, mac, mam, last; //int blockcount, tblockcount; //bool b; m_IF.eprintf("CBQBIntegerEngine::MultiHuffmanOptimize(): Internal error: This code is not functional.\n\n"); abort(); bool switchrl = true; iminti = 0; // Avoid uninitialized variable compiler warning // blocklength = 50; treemalus = 60; symbmalus = 3; lookahead = 100000; if (verbose) { m_IF.printf("\n>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n"); m_IF.printf(">>> MultiHuffmanOptimize >>>\n"); m_IF.printf(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n\n"); } if (blocklength != 0) { hta.clear(); he.Init((int)alp->m_oaAlphabet.size()); tfra.resize(alp->m_oaAlphabet.size()); for (zi=0;zi<1;zi++) { if (verbose) m_IF.printf("*** Iteration %d ***\n",zi+1); lastpos = 0; blc = 0; lasttree = -1; switchmalussum = 0; nsizeold = 0; for (z=0;z<(int)hta.size();z++) { for (z2=0;z2<(int)alp->m_oaAlphabet.size();z2++) hta[z]->m_iaFrequencies[z2] = 0; tsize[z] = he.EstimateBitLength(told[z]); tpop[z] = 0; galp[z] = z; } while (true) { if (lastpos+blocklength < (int)tia.size()) sc = blocklength; else sc = (int)tia.size()-lastpos; for (z=0;z<(int)alp->m_oaAlphabet.size();z++) tfra[z] = 0; for (z0=lastpos;z0 ii) ti2 = he.EstimateBitLength(hta[ii]->m_iaFrequencies,tfra,told[ii]); else ti2 = he.EstimateBitLength(hta[ii]->m_iaFrequencies,tfra); if (ti2 - tsize[ii] < ti) { ti = ti2 - tsize[ii]; tii = z; } } if (galp.size() != 0) { // if (switchrl) { nsizeold = (double)(ti + tii + 1) / sc; } ti2 = he.EstimateBitLength(tfra); // if (switchrl) nsizenew = (double)(ti2 + treemalus + hta.size() + 1) / sc; // else // nsizenew = (double)(ti2 + treemalus + 8) / sc; // m_IF.printf("Block %5d: New %.2f, old %.2f (%d)\n",blc,nsizenew,nsizeold,tii); if ((nsizeold < nsizenew) && (galp.size() != 0)) { nsize = nsizeold; } else { nsize = nsizenew; tii = -1; } blc++; if (verbose) if ((blc % 100) == 0) m_IF.printf("%7.3f%% (%lu tables)...\n",(double)lastpos/tia.size()*100.0,hta.size()); if (tii == -1) { pht = new CBQBHuffmanTree(m_IF); pht->Init((int)alp->m_oaAlphabet.size()); pht->m_iaFrequencies.assign(tfra.begin(),tfra.end()); lasttree = (int)hta.size(); hta.push_back(pht); tsize.push_back(ti2); tpop.push_back(sc); galp.insert(galp.begin(),lasttree); // if (switchrl) { switchmalussum += lasttree+1; } else { for (z=0;z<(int)alp->m_oaAlphabet.size();z++) hta[galp[tii]]->m_iaFrequencies[z] += tfra[z]; tsize[galp[tii]] += ti; tpop[galp[tii]] += sc; lasttree = tii; if (lasttree != 0) { MoveToFrontIndex(galp,lasttree); // if (switchrl) switchmalussum += lasttree+1; // else // switchmalussum += 8; } else switchmalussum++; } lastpos += sc; if (lastpos >= (int)tia.size()) break; } told.resize(hta.size()); for (z=0;z<(int)hta.size();z++) { told[z].resize(alp->m_oaAlphabet.size()); for (z2=0;z2<(int)alp->m_oaAlphabet.size();z2++) told[z][z2] = hta[z]->m_iaFrequencies[z2]; } payload = 0; trees = 0; blockendsum = 0; for (z=0;z<(int)hta.size();z++) hta[z]->BuildTree(true); if (verbose) { // ti3 = 0; for (z=0;z<(int)hta.size();z++) { ti = 0; ti2 = 0; for (z2=0;z2<(int)alp->m_oaAlphabet.size();z2++) { ti += hta[z]->m_iaFrequencies[z2]; ti2 += hta[z]->m_iaFrequencies[z2] * hta[z]->m_iaLengths[z2]; } payload += ti2; ti4 = hta[z]->ExportTree(NULL,false,false); trees += ti4; m_IF.printf(" * Tree %3d: %4lu/%lu symbols, %7d payload = %8.3f KiB, %4d ends = %7.3f KiB, tree = %6.3f KiB\n",z,hta[z]->m_oaSymbols.size(),alp->m_oaAlphabet.size()+1,ti,ti2/8.0/1024.0,0,0.0,ti4/8.0/1024.0); } m_IF.printf("\n"); m_IF.printf("Total switching malus: %7.0f Bytes (%7.3f%%).\n",switchmalussum/8.0,(double)switchmalussum/(payload+trees+switchmalussum+blockendsum)*100.0); m_IF.printf("Total block end label: %7.0f Bytes (%7.3f%%).\n",blockendsum/8.0,(double)blockendsum/(payload+trees+switchmalussum+blockendsum)*100.0); m_IF.printf("Total Payload: %7.0f Bytes (%7.3f%%).\n",payload/8.0,(double)payload/(payload+trees+switchmalussum+blockendsum)*100.0); m_IF.printf("Total Trees: %7.0f Bytes (%7.3f%%).\n",trees/8.0,(double)trees/(payload+trees+switchmalussum+blockendsum)*100.0); m_IF.printf("\n"); m_IF.printf("Total size: %7.0f Bytes.\n",(payload+trees+switchmalussum+blockendsum)/8.0); } } } else { hta.clear(); he.Init((int)alp->m_oaAlphabet.size()+1); tfra.resize(alp->m_oaAlphabet.size()+1); for (z=0;z<(int)alp->m_oaAlphabet.size()+1;z++) tfra[z] = 0; tfra[0] = 1; sc = 0; minval = 1.0e20; lasttree = -1; switchmalussum = 0; iskip = 0; blc = 0; lastpos = 0; nsizeold = 0; iminval = 0; imintii = -1; iminsc = 0; for (z0=0;z0<(int)tia.size();z0++) { tfra[tia[z0]+1]++; // tfra[tia[z0]]++; sc++; ti = 1000000000; tii = -1; for (z=0;z<(int)galp.size();z++) { ii = galp[z]; ti2 = he.EstimateBitLength(hta[ii]->m_iaFrequencies,tfra); for (z2=0;z2<(int)alp->m_oaAlphabet.size()+1;z2++) // for (z2=0;z2<(int)alp->m_oaAlphabet.size();z2++) // if ((hta[ii]->m_iaFrequencies[z2] != 0) || (tfra[z2] != 0)) if ((hta[ii]->m_iaFrequencies[z2] == 0) && (tfra[z2] != 0)) ti2 += symbmalus; if (ti2 - tsize[ii] < ti) { ti = ti2 - tsize[ii]; tii = z; } } if (galp.size() != 0) { if (switchrl) { nsizeold = (double)(ti + tii + 1) / sc; } else { if (tii == 0) nsizeold = (double)(ti + 1) / sc; else nsizeold = (double)(ti + 8) / sc; } } ti2 = he.EstimateBitLength(tfra); for (z=0;z<(int)alp->m_oaAlphabet.size()+1;z++) // for (z=0;z<(int)alp->m_oaAlphabet.size();z++) if (tfra[z] != 0) ti2 += symbmalus; if (switchrl) nsizenew = (double)(ti2 + treemalus + hta.size() + 1) / sc; else nsizenew = (double)(ti2 + treemalus + 8) / sc; if ((nsizeold < nsizenew) && (galp.size() != 0)) { nsize = nsizeold; } else { nsize = nsizenew; tii = -1; } if (nsize < minval) { iskip = 0; minval = nsize; iminval = z0; imintii = tii; iminsc = sc; iminti = ti; iminti2 = ti2; imintfra.assign(tfra.begin(),tfra.end()); } else iskip++; if ((z0-lastpos == lookahead) || (iskip == 500) || (z0+1 == (int)tia.size())) { blc++; if (imintii == -1) { pht = new CBQBHuffmanTree(m_IF); pht->Init((int)alp->m_oaAlphabet.size()+1); // pht->Init(alp->m_oaAlphabet.size()); pht->m_iaFrequencies.assign(imintfra.begin(),imintfra.end()); lasttree = (int)hta.size(); hta.push_back(pht); tsize.push_back(iminti2); tpop.push_back(iminsc); galp.insert(galp.begin(),lasttree); if (switchrl) { switchmalussum += lasttree+1; } else { if (lasttree != 0) switchmalussum += 8; else switchmalussum++; } } else { for (z=0;z<(int)alp->m_oaAlphabet.size()+1;z++) // for (z=0;z<(int)alp->m_oaAlphabet.size();z++) hta[galp[imintii]]->m_iaFrequencies[z] += imintfra[z]; tsize[galp[imintii]] += iminti ; tpop[galp[imintii]] += iminsc; lasttree = imintii; if (lasttree != 0) { MoveToFrontIndex(galp,lasttree); //std::iter_swap(galp.begin(),galp.begin()+lasttree); if (switchrl) switchmalussum += 8; else switchmalussum += lasttree+1; } else switchmalussum++; } if ((blc % 10) == 0) { if (imintii == -1) m_IF.printf("*** Block %d (pos %.3f%%, len %d) new tree ***\n",blc,(double)iminval/tia.size()*100.0,iminval-lastpos+1); else m_IF.printf("*** Block %d (pos %.3f%%, len %d) using tree %d (%d) ***\n",blc,(double)iminval/tia.size()*100.0,iminval-lastpos+1,imintii,galp[0]); for (z=0;z<(int)hta.size();z++) m_IF.printf(" * Tree %3d: %7d symbols, %8d bits, %6.3f b/s.\n",z,tpop[z],tsize[z],(double)tsize[z]/tpop[z]); m_IF.printf(" Total switching malus: %d bits.\n\n",switchmalussum); } // if (iminval-lastpos+1 == 1) // abort(); for (z=1;z<(int)alp->m_oaAlphabet.size()+1;z++) // for (z=0;z<(int)alp->m_oaAlphabet.size();z++) tfra[z] = 0; tfra[0] = 1; sc = 0; z0 = iminval; lastpos = iminval+1; minval = 1.0e20; } } } for (z=0;z<(int)hta.size();z++) hta[z]->BuildTree(true); if (verbose) { m_IF.printf("\n*** Loop finished ***\n\n"); payload = 0; trees = 0; blockendsum = 0; m_IF.printf("\n<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n"); m_IF.printf("<<< MultiHuffmanOptimize <<<\n"); m_IF.printf("<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n\n"); } // abort(); } */ travis-src-190101/src/bqb_integerengine.h0100777000000000000000000001135213412725652015262 0ustar00/*********************************************************************************** LibBQB - File Format and Compression Algorithms for Trajectories of Volumetric Data and Atom Positions https://brehm-research.de/bqb Free software, licensed under GNU LGPL v3 Copyright (c) Martin Brehm and Martin Thomas, Martin Luther University Halle-Wittenberg, Germany, 2016 - 2019. Please cite: M. Brehm, M. Thomas: "An Efficient Lossless Compression Algorithm for Trajectories of Atom Positions and Volumetric Data", J. Chem. Inf. Model. 2018, 58 (10), pp 2092-2107. -------------------------------------------------------------------------------- LibBQB is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program. If not, see . ***********************************************************************************/ #ifndef BQB_INTEGERENGINE_H #define BQB_INTEGERENGINE_H // This must always be the first include directive #include "bqb_config.h" #include "bqb_tools.h" #include #include "bqb_bitset.h" #include "bqb_hufftree.h" #include "bqb_alphabet.h" #include "bqb_parmset.h" class CBQBInterface; class CBQBBWPair { public: CBQBBWPair(int symbol, int index) : m_iSymbol(symbol), m_iIndex(index) { } int m_iSymbol; int m_iIndex; }; class CBQBIntegerEngine { public: CBQBIntegerEngine(CBQBInterface &i) : m_IF(i) { } bool Compress( std::vector &inp, CBQBBitSet *outp, bool bw, bool mtf, bool coderun, int blocklength, int tables, bool opttables, bool chr, int maxiter, int maxchunk, CBQBStatistics *stat ); bool Compress( std::vector &inp, CBQBBitSet *outp, const CBQBParameterSet_Compressor *parm, bool chr, CBQBStatistics *stat ); bool Decompress( CBQBBitSet *inp, std::vector &outp, CBQBParameterSet_Compressor *parm ); bool CompressSingle( std::vector &inp, CBQBBitSet *outp, bool bw, bool mtf, bool coderun, int blocklength, int tables, bool opttables, bool chr, int maxiter, CBQBStatistics *stat ); bool CompressSingle( std::vector &inp, CBQBBitSet *outp, const CBQBParameterSet_Compressor *parm, bool chr, CBQBStatistics *stat ); bool DecompressSingle( CBQBBitSet *inp, std::vector &outp, CBQBParameterSet_Compressor *parm ); std::vector *m_iaBW; std::vector m_iaBWRunTable; // These structs are a hack to enable the comparison function for std::sort // to access class members of CBQBIntegerEngine. // Can't use global variables here, because multiple CBQBIntegerEngines // might be running in different threads... struct SSortBW { SSortBW( const CBQBIntegerEngine& ie ) : m_IE(ie) { } const CBQBIntegerEngine &m_IE; bool operator()( const int & i1, const int & i2 ) { int k1, k2, i; if (i1 == i2) return false; k1 = i1; k2 = i2; i = 0; while ((*m_IE.m_iaBW)[k1] == (*m_IE.m_iaBW)[k2]) { k1++; k2++; i++; if (k1 >= (int)m_IE.m_iaBW->size()) k1 = 0; if (k2 >= (int)m_IE.m_iaBW->size()) k2 = 0; if (i >= (int)m_IE.m_iaBW->size()) return false; } return ((*m_IE.m_iaBW)[k1] < (*m_IE.m_iaBW)[k2]); } }; struct SSortBWRuntable { SSortBWRuntable( const CBQBIntegerEngine& ie ) : m_IE(ie) { } const CBQBIntegerEngine &m_IE; bool operator()( const int & i1, const int & i2 ) { int k1, k2, i, j; if (i1 == i2) return false; k1 = i1; k2 = i2; i = 0; while ((*m_IE.m_iaBW)[k1] == (*m_IE.m_iaBW)[k2]) { j = MIN( m_IE.m_iaBWRunTable[k1] , m_IE.m_iaBWRunTable[k2] ); i += j; k1 += j; k2 += j; if (k1 >= (int)m_IE.m_iaBW->size()) k1 -= (int)m_IE.m_iaBW->size(); if (k2 >= (int)m_IE.m_iaBW->size()) k2 -= (int)m_IE.m_iaBW->size(); if (i >= (int)m_IE.m_iaBW->size()) return false; } return ((*m_IE.m_iaBW)[k1] < (*m_IE.m_iaBW)[k2]); } }; private: CBQBInterface &m_IF; //void MultiHuffmanOptimize(int tables, std::vector &hta, CBQBAlphabet *alp, std::vector &tia, std::vector &asi, std::vector &iasi, int blocklength, bool verbose); }; #endif travis-src-190101/src/bqb_interface.cpp0100777000000000000000000001371213412725617014735 0ustar00/*********************************************************************************** LibBQB - File Format and Compression Algorithms for Trajectories of Volumetric Data and Atom Positions https://brehm-research.de/bqb Free software, licensed under GNU LGPL v3 Copyright (c) Martin Brehm and Martin Thomas, Martin Luther University Halle-Wittenberg, Germany, 2016 - 2019. Please cite: M. Brehm, M. Thomas: "An Efficient Lossless Compression Algorithm for Trajectories of Atom Positions and Volumetric Data", J. Chem. Inf. Model. 2018, 58 (10), pp 2092-2107. -------------------------------------------------------------------------------- LibBQB is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program. If not, see . ***********************************************************************************/ // This must always be the first include directive #include "bqb_config.h" #include "bqb_interface.h" #include "bqb_driver.h" #include const char *GetRevisionInfo_bqb_interface(unsigned int len) { static char buf[256]; GET_REVISION_INFO( buf, len ); return buf; } const char *GetSourceVersion_bqb_interface() { static char buf[256]; GET_SOURCE_VERSION( buf ); return buf; } #define BQB_BUF_LEN 16384 CBQBInterface* BQBCreateInterface(unsigned long flags) { UNUSED(flags); CBQBInterface *p; p = new CBQBInterface(); return p; } bool BQBDestroyInterface(CBQBInterface *i) { delete i; return true; } CBQBInterface::CBQBInterface() { m_pPrintCallback = NULL; m_pPrintCallbackVar = NULL; m_pEPrintCallback = NULL; m_pEPrintCallbackVar = NULL; m_pBPrintCallback = NULL; m_pBPrintCallbackVar = NULL; m_iPrintLevel = BQB_PL_STANDARD; } CBQBInterface::~CBQBInterface() { } CBQBDriver* CBQBInterface::CreateDriver(unsigned long flags) { UNUSED(flags); CBQBDriver *p; p = new CBQBDriver(*this); return p; } bool CBQBInterface::DestroyDriver(CBQBDriver *d) { delete d; return true; } CBQBEngine* CBQBInterface::CreateEngine(unsigned long flags) { UNUSED(flags); CBQBEngine *p; p = new CBQBEngine(*this); return p; } bool CBQBInterface::DestroyEngine(CBQBEngine *e) { delete e; return true; } void CBQBInterface::printf(const char *s, ...) const { va_list args; static char buffer[BQB_BUF_LEN]; if (strlen(s) >= BQB_BUF_LEN) { eprintf("CBQBInterface::printf(): Internal error: Buffer overflow (A).\n"); abort(); } buffer[BQB_BUF_LEN-1] = 0; va_start(args,s); vsprintf(buffer,s,args); va_end(args); if (buffer[BQB_BUF_LEN-1] != 0) { eprintf("CBQBInterface::printf(): Internal error: Buffer overflow (B).\n"); abort(); } if (m_pPrintCallbackVar != NULL) m_pPrintCallbackVar("%s",buffer); else if (m_pPrintCallback != NULL) m_pPrintCallback(buffer); else ::printf("%s",buffer); } void CBQBInterface::bprintf(const char *s, ...) const { va_list args; static char buffer[BQB_BUF_LEN]; if (strlen(s) >= BQB_BUF_LEN) { eprintf("CBQBInterface::bprintf(): Internal error: Buffer overflow (A).\n"); abort(); } buffer[BQB_BUF_LEN-1] = 0; va_start(args,s); vsprintf(buffer,s,args); va_end(args); if (buffer[BQB_BUF_LEN-1] != 0) { eprintf("CBQBInterface::bprintf(): Internal error: Buffer overflow (B).\n"); abort(); } if (m_pBPrintCallbackVar != NULL) m_pBPrintCallbackVar("%s",buffer); else if (m_pBPrintCallback != NULL) m_pBPrintCallback(buffer); else ::printf("%s",buffer); } void CBQBInterface::eprintf(const char *s, ...) const { va_list args; static char buffer[BQB_BUF_LEN]; if (strlen(s) >= BQB_BUF_LEN) { eprintf("CBQBInterface::eprintf(): Internal error: Buffer overflow (A).\n"); abort(); } buffer[BQB_BUF_LEN-1] = 0; va_start(args,s); vsprintf(buffer,s,args); va_end(args); if (buffer[BQB_BUF_LEN-1] != 0) { eprintf("CBQBInterface::eprintf(): Internal error: Buffer overflow (B).\n"); abort(); } if (m_pEPrintCallbackVar != NULL) m_pEPrintCallbackVar("%s",buffer); else if (m_pEPrintCallback != NULL) m_pEPrintCallback(buffer); else ::printf("%s",buffer); } void CBQBInterface::FlushLog() const { } void CBQBInterface::SetPrintCallback( void (*fp)(const char *) ) { m_pPrintCallback = fp; m_pEPrintCallback = fp; m_pBPrintCallback = fp; } void CBQBInterface::SetPrintCallback( void (*fp)(const char *, ...) ) { m_pPrintCallbackVar = fp; m_pEPrintCallbackVar = fp; m_pBPrintCallbackVar = fp; } void CBQBInterface::ResetPrintCallback() { m_pPrintCallback = NULL; m_pEPrintCallback = NULL; m_pBPrintCallback = NULL; m_pPrintCallbackVar = NULL; m_pEPrintCallbackVar = NULL; m_pBPrintCallbackVar = NULL; } void CBQBInterface::SetEPrintCallback( void (*fp)(const char *) ) { m_pEPrintCallback = fp; } void CBQBInterface::SetEPrintCallback( void (*fp)(const char *, ...) ) { m_pEPrintCallbackVar = fp; } void CBQBInterface::ResetEPrintCallback() { m_pEPrintCallback = NULL; m_pEPrintCallbackVar = NULL; } void CBQBInterface::SetBPrintCallback( void (*fp)(const char *) ) { m_pBPrintCallback = fp; } void CBQBInterface::SetBPrintCallback( void (*fp)(const char *, ...) ) { m_pBPrintCallbackVar = fp; } void CBQBInterface::ResetBPrintCallback() { m_pBPrintCallback = NULL; m_pBPrintCallbackVar = NULL; } void CBQBInterface::SetPrintLevel(int i) { m_iPrintLevel = i; } int CBQBInterface::GetPrintLevel() const { return m_iPrintLevel; } travis-src-190101/src/bqb_interface.h0100777000000000000000000000741013412725654014401 0ustar00/*********************************************************************************** LibBQB - File Format and Compression Algorithms for Trajectories of Volumetric Data and Atom Positions https://brehm-research.de/bqb Free software, licensed under GNU LGPL v3 Copyright (c) Martin Brehm and Martin Thomas, Martin Luther University Halle-Wittenberg, Germany, 2016 - 2019. Please cite: M. Brehm, M. Thomas: "An Efficient Lossless Compression Algorithm for Trajectories of Atom Positions and Volumetric Data", J. Chem. Inf. Model. 2018, 58 (10), pp 2092-2107. -------------------------------------------------------------------------------- LibBQB is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program. If not, see . ***********************************************************************************/ #ifndef BQB_INTERFACE_H #define BQB_INTERFACE_H // This must always be the first include directive #include "bqb_config.h" #define BQB_PL_SILENT 0 // Do not print anything on the screen #define BQB_PL_QUIET 1 #define BQB_PL_STANDARD 2 // As in TRAVIS / bqbtool #define BQB_PL_VERBOSE 3 // Print all information from Front-Ends #define BQB_PL_DEBUG 4 // Also print all information from Compressor class CBQBDriver; class CBQBInterface; class CBQBEngine; CBQBInterface* BQBCreateInterface(unsigned long flags); bool BQBDestroyInterface(CBQBInterface *i); class CBQBInterface { public: CBQBDriver* CreateDriver(unsigned long flags); bool DestroyDriver(CBQBDriver *d); CBQBEngine* CreateEngine(unsigned long flags); bool DestroyEngine(CBQBEngine *e); void SetPrintCallback( void (*fp)(const char *) ); void SetPrintCallback( void (*fp)(const char *, ...) ); void ResetPrintCallback(); void SetEPrintCallback( void (*fp)(const char *) ); void SetEPrintCallback( void (*fp)(const char *, ...) ); void ResetEPrintCallback(); void SetBPrintCallback( void (*fp)(const char *) ); void SetBPrintCallback( void (*fp)(const char *, ...) ); void ResetBPrintCallback(); #ifdef __GNUG__ // Variadic Argument Type Checking of GCC // Note the implicit first "this" argument! void printf(const char *s, ...) const __attribute__ ((format (printf, 2, 3))); void bprintf(const char *s, ...) const __attribute__ ((format (printf, 2, 3))); void eprintf(const char *s, ...) const __attribute__ ((format (printf, 2, 3))); #else void printf(const char *s, ...) const; void bprintf(const char *s, ...) const; void eprintf(const char *s, ...) const; #endif void FlushLog() const; void SetPrintLevel(int i); int GetPrintLevel() const; bool IsPL(int i) const { return (m_iPrintLevel >= i); } private: CBQBInterface(); ~CBQBInterface(); int m_iPrintLevel; void (*m_pPrintCallback)(const char *); void (*m_pEPrintCallback)(const char *); void (*m_pBPrintCallback)(const char *); void (*m_pPrintCallbackVar)(const char *, ...); void (*m_pEPrintCallbackVar)(const char *, ...); void (*m_pBPrintCallbackVar)(const char *, ...); friend CBQBInterface* BQBCreateInterface(unsigned long flags); friend bool BQBDestroyInterface(CBQBInterface *i); }; #endif travis-src-190101/src/bqb_largeinteger.cpp0100777000000000000000000043554713412725623015460 0ustar00/*********************************************************************************** LibBQB - File Format and Compression Algorithms for Trajectories of Volumetric Data and Atom Positions https://brehm-research.de/bqb Free software, licensed under GNU LGPL v3 Copyright (c) Martin Brehm and Martin Thomas, Martin Luther University Halle-Wittenberg, Germany, 2016 - 2019. Please cite: M. Brehm, M. Thomas: "An Efficient Lossless Compression Algorithm for Trajectories of Atom Positions and Volumetric Data", J. Chem. Inf. Model. 2018, 58 (10), pp 2092-2107. -------------------------------------------------------------------------------- LibBQB is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program. If not, see . ***********************************************************************************/ //======================================================================= // Copyright (C) 1998-2013 William Hallahan // // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without restriction, // including without limitation the rights to use, copy, modify, merge, // publish, distribute, sublicense, and/or sell copies of the Software, // and to permit persons to whom the Software is furnished to do so, // subject to the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES // OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, // WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR // OTHER DEALINGS IN THE SOFTWARE. //======================================================================= //********************************************************************** // Class Implementation File: BQBLargeInteger.cpp // Author: Bill Hallahan // Date: March 11, 1998 // // Abstract: // // This file contains the implementation for class BQBLargeInteger. // An instance of BQBLargeInteger can be used to store and calculate // integer values with a huge number of digits. The internal data // format is a both a boolean value named m_negative_flag that that // stores the sign of the number, and an array of integers that // contains a positive binary value. The maximum number of integers // that can be contained in the internal array is limited to the // maximum signed value which can be stored in an integer, The // maximum number of digits that can be used for octal and hexadecimal // input, and output, is equal to the the maximum value that can be // stored in a signed integer. The input and output conversion // methods for decimal numbers supports up to 19,346,699 digits or // almost 20 million decimal digits. This implementation only works // on little-endian machines. // //********************************************************************** // This must always be the first include directive #include "bqb_config.h" #include "bqb_tools.h" #if defined __GNUC__ #include #include #endif #include "bqb_largeinteger.h" const char *GetRevisionInfo_bqb_largeinteger(unsigned int len) { static char buf[256]; GET_REVISION_INFO( buf, len ); return buf; } const char *GetSourceVersion_bqb_largeinteger() { static char buf[256]; GET_SOURCE_VERSION( buf ); return buf; } #define INT_BIT_LENGTH_IS_POWER_OF_TWO std::string g_sBQBLIString; std::string g_sBQBLIString2; std::string g_sBQBLIString3; //====================================================================== // Constants. //====================================================================== namespace { const unsigned int INTEGER_LOW_HALF_MASK = 0xFFFF; const unsigned int INTEGER_BIT_COUNT = 32; const unsigned int INTEGER_HALF_BIT_COUNT = 16; const int INTEGER_MAXIMUM_BASE = 90; const double D_MAX_UNSIGNED_VALUE = 4294967296.0; const char DIGIT_ARRAY[INTEGER_MAXIMUM_BASE] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'w', 'x', 'y', 'z', '.', ',', '?', '/', '\\', '|', '<', '>', ':', ';', '"', '\'', '{', '}', '[', ']', '`', '~', '!', '@', '#', '$', '%', '^', '&', '*', '(', ')', '-', '_', '+', '=' }; const unsigned int BIT_MASK_ARRAY[5] = { 0xAAAAAAAA, 0xCCCCCCCC, 0xF0F0F0F0, 0xFF00FF00, 0xFFFF0000 }; const unsigned int BIT_MASK_TABLE_LENGTH = sizeof(BIT_MASK_ARRAY) / sizeof(unsigned int); #ifdef LARGE_INT_ALTERNATE_POP_COUNT const unsigned int MASK_1 = 011111111111; const unsigned int MASK_3 = 033333333333; const unsigned int MASK_7 = 030707070707; #endif } //====================================================================== // istream operator for input. //====================================================================== std::istream & operator >>(std::istream & is, BQBLargeInteger & value) { //------------------------------------------------------------------ // Get the input string. //------------------------------------------------------------------ const unsigned int max_string_length = 2048; char * number_ptr = new char [max_string_length]; if (number_ptr != 0) { is.get(number_ptr, max_string_length - 1); int length = (int)is.gcount(); number_ptr[length] = '\0'; unsigned int base; switch (is.flags() & std::ios_base::basefield) { case std::ios_base::oct: base = 8; break; case std::ios_base::dec: base = 10; break; case std::ios_base::hex: base = 16; break; default: base = 10; break; } value.SetValue(number_ptr, base); delete [] number_ptr; } return is; } //====================================================================== // ostream operator for output. //====================================================================== std::ostream & operator <<(std::ostream & os, const BQBLargeInteger & value) { unsigned int base; switch (os.flags() & std::ios_base::basefield) { case std::ios_base::oct: base = 8; break; case std::ios_base::dec: base = 10; break; case std::ios_base::hex: base = 16; break; default: base = 10; break; } std::string number_string; value.GetNumberString(number_string, base); os << number_string.c_str(); return os; } //====================================================================== // Constructor: BQBLargeInteger::BQBLargeInteger //====================================================================== BQBLargeInteger::BQBLargeInteger() : m_array_length(0) , m_integer_length(0) , m_default_base(10) , m_array_ptr(0) , m_negative_flag(false) { SetIntegerLength(1); m_array_ptr[0] = 0; } //====================================================================== // Copy constructor //====================================================================== BQBLargeInteger::BQBLargeInteger(const BQBLargeInteger & value) : m_array_length(0) , m_integer_length(0) , m_default_base(10) , m_array_ptr(0) , m_negative_flag(false) { Copy(value); } //====================================================================== // Conversion constructor for signed long. //====================================================================== BQBLargeInteger::BQBLargeInteger(long value) : m_array_length(0) , m_integer_length(0) , m_default_base(10) , m_array_ptr(0) , m_negative_flag(false) { SetIntegerLength(1); m_negative_flag = value < 0; m_array_ptr[0] = m_negative_flag ? (unsigned int)(-value) : (unsigned int)(value); } //====================================================================== // Conversion constructor for unsigned long. //====================================================================== BQBLargeInteger::BQBLargeInteger(unsigned long value) : m_array_length(0) , m_integer_length(0) , m_default_base(10) , m_array_ptr(0) , m_negative_flag(false) { SetIntegerLength(1); m_array_ptr[0] = value; } //====================================================================== // Conversion constructor for signed int. //====================================================================== BQBLargeInteger::BQBLargeInteger(int value) : m_array_length(0) , m_integer_length(0) , m_default_base(10) , m_array_ptr(0) , m_negative_flag(false) { SetIntegerLength(1); m_negative_flag = value < 0; m_array_ptr[0] = m_negative_flag ? (unsigned int)(-value) : (unsigned int)(value); } //====================================================================== // Conversion constructor for unsigned int. //====================================================================== BQBLargeInteger::BQBLargeInteger(unsigned int value) : m_array_length(0) , m_integer_length(0) , m_default_base(10) , m_array_ptr(0) , m_negative_flag(false) { SetIntegerLength(1); m_array_ptr[0] = value; } //====================================================================== // Constructor: BQBLargeInteger::BQBLargeInteger // // The number is interpreted using the default base that is set // using the SetDefaultBase method. //====================================================================== BQBLargeInteger::BQBLargeInteger(const char * psznumber_ptr) : m_array_length(0) , m_integer_length(0) , m_default_base(10) , m_array_ptr(0) , m_negative_flag(false) { SetValue(psznumber_ptr, m_default_base); } //====================================================================== // Special constructor to allow initializing using an array of // binary data. //====================================================================== BQBLargeInteger::BQBLargeInteger(const char * binary_data_ptr, unsigned int length) : m_array_length(0) , m_integer_length(0) , m_default_base(10) , m_array_ptr(0) , m_negative_flag(false) { SetBinaryValue(binary_data_ptr, length); } //====================================================================== // Destructor //====================================================================== BQBLargeInteger::~BQBLargeInteger() { delete [] m_array_ptr; } //====================================================================== // Method: BQBLargeInteger::SetDefaultBase // // The default base is the value used for the constructor and operator // equals methods that take only a string pointer for a number. //====================================================================== void BQBLargeInteger::SetDefaultBase(unsigned int default_base) { if ((default_base == 0) || (default_base > ((unsigned int)INTEGER_MAXIMUM_BASE))) { //throw BQBLargeIntegerException("Illegal base"); printf("BQBLargeInteger::SetDefaultBase(): Error: Illegal base %u.\n",default_base); abort(); } m_default_base = default_base; } //====================================================================== // This method allows getting this large integer's binary value. // The binary value is a positive number in little endian format. // The buffer that is passed must be large enough to contain the // number. This method can be called passing a null pointer for // the buffer to just obtain the buffer length in bytes. //====================================================================== unsigned int BQBLargeInteger::GetBinaryValue(unsigned char * binary_data_ptr) const { //------------------------------------------------------------------ // Get the length of the output binary array. //------------------------------------------------------------------ unsigned int length = sizeof(unsigned int) * m_integer_length; //------------------------------------------------------------------ // Discard leading zero bytes. //------------------------------------------------------------------ char * source_ptr = reinterpret_cast(&m_array_ptr[0]); unsigned int leading_zero_count = 0; for (int i = length - 1; i >= 0; --i) { if (source_ptr[i] == 0) { ++leading_zero_count; } else { break; } } length -= leading_zero_count; //------------------------------------------------------------------ // If the passed array pointer is not zero then copy the data // to the output array. //------------------------------------------------------------------ if (binary_data_ptr != 0) { for (unsigned int j = 0; j < length; ++j) { binary_data_ptr[j] = source_ptr[j]; } } return length; } //====================================================================== // This method allows setting this large integer's binary value. // The binary value is a positive number in little endian format. // The buffer that is passed must be large enough to contain the // number. This method can be called passing a null pointer for // the buffer to just obtain the buffer length in bytes. //====================================================================== void BQBLargeInteger::SetBinaryValue(const char * binary_data_ptr, unsigned int length) { //------------------------------------------------------------------ // Set the sign for a positive number. //------------------------------------------------------------------ m_negative_flag = false; //------------------------------------------------------------------ // Set the length of internal array of unsigned integers // that will store the byte array. //------------------------------------------------------------------ unsigned int array_length = (length + 3) >> 2; SetIntegerLength(array_length); //------------------------------------------------------------------ // Copy the bytes to the internal unsigned integer array. //------------------------------------------------------------------ char * destination_ptr = reinterpret_cast(m_array_ptr); unsigned int i = 0; for (i = 0; i < length; ++i) { destination_ptr[i] = binary_data_ptr[i]; } //------------------------------------------------------------------ // Determine if there are any extra bytes in the array that // need to be zero padded. //------------------------------------------------------------------ unsigned int index_one_past_final_byte = m_integer_length << 2; if (length < index_one_past_final_byte) { for (i = length; i < index_one_past_final_byte; ++i) { destination_ptr[i] = 0; } } //------------------------------------------------------------------ // Normalize the result. //------------------------------------------------------------------ Normalize(); return; } //================================================================== // Get this large integer value represented in an stl string. //================================================================== void BQBLargeInteger::GetNumberString(std::string & number_string, unsigned int base) const { //------------------------------------------------------------------ // Convert this large integer to a character string representation // in the desired base. //------------------------------------------------------------------ number_string.erase(); //------------------------------------------------------------------ // Use special code for bases 8, 10, and 16. //------------------------------------------------------------------ switch (base) { case 8: GetBase8NumberString(number_string); break; case 10: GetBase10NumberString(number_string); break; case 16: GetBase16NumberString(number_string); break; default: //------------------------------------------------------------------ // Generic code for converting to any base up to base 90. //------------------------------------------------------------------ BQBLargeInteger x_temp = *this; //-------------------------------------------------------------- // The characters are converted in reverse order from the // order they are displayed. //-------------------------------------------------------------- do { BQBLargeInteger x_mult = x_temp / base; BQBLargeInteger x_part = x_mult * base; unsigned int digit_index = (unsigned int)(x_temp - x_part); number_string += DIGIT_ARRAY[digit_index]; x_temp = x_mult; } while(!x_temp.IsZero()); //------------------------------------------------------------------ // Reverse the order of the digits so the number can be // properly displayed. //------------------------------------------------------------------ char * number_ptr = const_cast(number_string.data()); unsigned int length = (unsigned int)number_string.length(); for (unsigned int i = 0; i < (length >> 1); ++i) { char temp = number_ptr[i]; number_ptr[i] = number_ptr[(length - i) - 1]; number_ptr[(length - i) - 1] = temp; } break; } //------------------------------------------------------------------ // If the number is negative then make the first character a // minus sign. //------------------------------------------------------------------ if (IsNegative()) { number_string.insert(0, "-"); } return; } //================================================================== // Set this large integer value using the number in a character // string. //================================================================== bool BQBLargeInteger::SetValue(const char * number_ptr, unsigned int base) { //------------------------------------------------------------------ // Set this instance to the value zero. //------------------------------------------------------------------ SetToZero(); //------------------------------------------------------------------ // If the passed string pointer is equal to zero then exit. //------------------------------------------------------------------ bool success_flag = number_ptr != 0; if (success_flag) { size_t length = ::strlen(number_ptr); if (length > 0) { //---------------------------------------------------------- // Skip any leading white space. //---------------------------------------------------------- size_t index = 0; for (index = 0; index < length; ++index) { if (!::isspace((int)(number_ptr[index]))) { break; } } //---------------------------------------------------------- // Test for + or - character. //---------------------------------------------------------- m_negative_flag = number_ptr[index] == '-'; if (m_negative_flag) { ++index; } if (number_ptr[index] == '+') { ++index; } //---------------------------------------------------------- // Skip white space. //---------------------------------------------------------- for (;index < length; ++index) { if (!::isspace((int)(number_ptr[index]))) { break; } } //---------------------------------------------------------- // Use special code for bases 8, 10, and 16. //---------------------------------------------------------- switch (base) { case 8: success_flag = SetValueWithBase8String(number_ptr + index); break; case 10: success_flag = SetValueWithBase10String(number_ptr + index); break; case 16: success_flag = SetValueWithBase16String(number_ptr + index); break; default: { //-------------------------------------------------- // Loop and add each digit to the value. //-------------------------------------------------- success_flag = true; for (size_t i = index; i < length; ++i) { //---------------------------------------------- // Get the numeric value of a digit. //---------------------------------------------- int digit = ::tolower((int)(number_ptr[i])); if (::isxdigit(digit)) { if ((digit >= 'a') && (digit <= 'f')) { digit = digit + 10 - (int)('a'); } else { digit = digit - (int)('0'); } if ((unsigned int)(digit) < base) { operator *=(base); operator +=(digit); } else { success_flag = false; break; } } else { break; } } } break; } } } //------------------------------------------------------------------ // Normalize the result. //------------------------------------------------------------------ Normalize(); return success_flag; } //====================================================================== // This method returns the position of the leading bit in this // large integer. If the value of this large integer is zero then // this function will return the value zero. //====================================================================== unsigned int BQBLargeInteger::LeadingBitPosition() const { unsigned int leading_bit_position = 0; //------------------------------------------------------------------ // The number has been normalized, so there must be a bit set // in either the most significant term or the next-to most // significant term. //------------------------------------------------------------------ int leading_value_index = m_integer_length - 1; if (m_array_ptr[m_integer_length - 1] == 0) { leading_value_index--; } if (leading_value_index > 0) { unsigned int leading_value = m_array_ptr[leading_value_index]; //------------------------------------------------------------------ // Find the position of the leading bit in the leading value. //------------------------------------------------------------------ unsigned int bit_position_addend = INTEGER_HALF_BIT_COUNT; for (unsigned int i = BIT_MASK_TABLE_LENGTH - 1; int(i) >= 0; --i) { unsigned int bit_mask = BIT_MASK_ARRAY[i]; if ((leading_value & bit_mask) != 0) { leading_bit_position += bit_position_addend; leading_value = leading_value & bit_mask; bit_position_addend = bit_position_addend >> 1; } } leading_bit_position = (INTEGER_BIT_COUNT * leading_value_index) + leading_bit_position; } return leading_bit_position; } //====================================================================== // Return the count of the number of bits set in this large // integer value. //====================================================================== unsigned int BQBLargeInteger::PopulationCount() const { unsigned int bit_count = 0; for (unsigned int i = 0; i < m_integer_length; ++i) { bit_count += PopulationCount32Bit(m_array_ptr[i]); } return bit_count; } //====================================================================== // operator = for integral types. //====================================================================== BQBLargeInteger BQBLargeInteger::operator =(const BQBLargeInteger & value) { Copy(value); return *this; } BQBLargeInteger BQBLargeInteger::operator =(long value) { Copy(BQBLargeInteger(value)); return *this; } BQBLargeInteger BQBLargeInteger::operator =(unsigned long value) { Copy(BQBLargeInteger(value)); return *this; } BQBLargeInteger BQBLargeInteger::operator =(int value) { Copy(BQBLargeInteger(value)); return *this; } BQBLargeInteger BQBLargeInteger::operator =(unsigned int value) { Copy(BQBLargeInteger(value)); return *this; } BQBLargeInteger BQBLargeInteger::operator =(const char * psznumber_ptr) { SetValue(psznumber_ptr, m_default_base); return *this; } //====================================================================== // Unary operator + for integral types. //====================================================================== BQBLargeInteger BQBLargeInteger::operator +=(const BQBLargeInteger & addend) { //------------------------------------------------------------------ // If the signs of this large integer and the sign of the addend // are the same then add the positive array values. If the signs // are NOT the same then subtract the positive array for the // addend from the positive array for this large integer. //------------------------------------------------------------------ bool negative_flag_0 = IsNegative(); bool negative_flag_1 = addend.IsNegative(); if (negative_flag_0 ^ negative_flag_1) { m_negative_flag = negative_flag_0 ^ SubtractPositiveArray(addend); } else { AddPositiveArray(addend); } //------------------------------------------------------------------ // Normalize the result. //------------------------------------------------------------------ Normalize(); return *this; } BQBLargeInteger BQBLargeInteger::operator +=(long addend) { return operator +=(BQBLargeInteger(addend)); } BQBLargeInteger BQBLargeInteger::operator +=(unsigned long addend) { return operator +=(BQBLargeInteger(addend)); } BQBLargeInteger BQBLargeInteger::operator +=(int addend) { return operator +=(BQBLargeInteger(addend)); } BQBLargeInteger BQBLargeInteger::operator +=(unsigned int addend) { return operator +=(BQBLargeInteger(addend)); } //====================================================================== // Unary operator - for integral types. //====================================================================== BQBLargeInteger BQBLargeInteger::operator -=(const BQBLargeInteger & subtrahend) { //------------------------------------------------------------------ // If the signs of this large integer and the sign of the // subtrahend are the same then subtract the positive array // values of the subtrahend from the positive array values // for this large integer. If the signs are NOT the same // then add the positive array values. //------------------------------------------------------------------ bool negative_flag_0 = IsNegative(); bool negative_flag_1 = subtrahend.IsNegative(); if (negative_flag_0 ^ negative_flag_1) { AddPositiveArray(subtrahend); } else { m_negative_flag = negative_flag_0 ^ SubtractPositiveArray(subtrahend); } //------------------------------------------------------------------ // Normalize the result. //------------------------------------------------------------------ Normalize(); return *this; } BQBLargeInteger BQBLargeInteger::operator -=(long subtrahend) { return operator -=(BQBLargeInteger(subtrahend)); } BQBLargeInteger BQBLargeInteger::operator -=(unsigned long subtrahend) { return operator -=(BQBLargeInteger(subtrahend)); } BQBLargeInteger BQBLargeInteger::operator -=(int subtrahend) { return operator -=(BQBLargeInteger(subtrahend)); } BQBLargeInteger BQBLargeInteger::operator -=(unsigned int subtrahend) { return operator -=(BQBLargeInteger(subtrahend)); } //====================================================================== // Unary operator * for integral types. //====================================================================== BQBLargeInteger BQBLargeInteger::operator *=(const BQBLargeInteger & x_multiplier) { //------------------------------------------------------------------ // Create a temporary variable to contain the product and set // the sign of the product. //------------------------------------------------------------------ BQBLargeInteger product = BQBLargeInteger(0); //------------------------------------------------------------------ // Multiply using base 65536 digits. //------------------------------------------------------------------ product.SetIntegerLength(m_integer_length + x_multiplier.m_integer_length); for (unsigned int i = 0; i < m_integer_length; ++i) { //-------------------------------------------------------------- // Get the base 65536 digits for the first multiplier. //-------------------------------------------------------------- unsigned int a0 = m_array_ptr[i] & INTEGER_LOW_HALF_MASK; unsigned int a1 = m_array_ptr[i] >> INTEGER_HALF_BIT_COUNT; for (unsigned int j = 0; j < x_multiplier.m_integer_length; ++j) { //---------------------------------------------------------- // Get the base 65536 digits for the second multiplier. //---------------------------------------------------------- unsigned int b0 = x_multiplier.m_array_ptr[j] & INTEGER_LOW_HALF_MASK; unsigned int b1 = x_multiplier.m_array_ptr[j] >> INTEGER_HALF_BIT_COUNT; //---------------------------------------------------------- // Calculate the product as shown. All multiplier // variables contain INTEGER_HALF_BIT_COUNT // bit quantities. The partial products are the // length of an unsigned integer. // // // // b1 b0 // X a1 a0 // ------------------------- // a0b0H a0b0L // a0b1H a0b1L // a1b0H a1b0L // a1b1H a1b1L // ------------------------- // p1H p1L p0H p0L // //---------------------------------------------------------- //------------------------------------------------------------------ // Calculate the 64-bit partial products. //------------------------------------------------------------------ unsigned int a0b0 = a0 * b0; unsigned int a0b1 = a0 * b1; unsigned int a1b0 = a1 * b0; unsigned int a1b1 = a1 * b1; //------------------------------------------------------------------ // Add the partial products to obtain the low dword. //------------------------------------------------------------------ unsigned int a0b1L = a0b1 << INTEGER_HALF_BIT_COUNT; unsigned int p0 = a0b0 + a0b1L; unsigned int low_dword_carry = (p0 < a0b1L) ? 1 : 0; unsigned int a1b0L = a1b0 << INTEGER_HALF_BIT_COUNT; unsigned int temp = p0 + a1b0L; low_dword_carry += (temp < p0) ? 1 : 0; p0 = temp; //------------------------------------------------------------------ // Add the partial products to obtain the high dword. // The high dword cannot carry because the largest 32-bit // product is: // // 0xFFFFFFFE00000001 = 0xFFFFFFFF * 0xFFFFFFFF //------------------------------------------------------------------ unsigned int a0b1H = a0b1 >> INTEGER_HALF_BIT_COUNT; unsigned int p1 = a1b1 + a0b1H; unsigned int a1b0H = a1b0 >> INTEGER_HALF_BIT_COUNT; p1 = p1 + a1b0H + low_dword_carry; //---------------------------------------------------------- // The 64 bit partial product has been calculated. // Accumulate the product into the appropriate // locations in the output integer array. //---------------------------------------------------------- //---------------------------------------------------------- // Accumulate the the low 32 bit sum. //---------------------------------------------------------- unsigned int index = i + j; AccumulateWithCarry(product, index, p0); //---------------------------------------------------------- // Accumulate the the high 32 bit sum. //---------------------------------------------------------- AccumulateWithCarry(product, index + 1, p1); } } //------------------------------------------------------------------ // Normalize the result. //------------------------------------------------------------------ product.Normalize(); //------------------------------------------------------------------ // Set the sign of the product. //------------------------------------------------------------------ product.m_negative_flag = IsNegative() ^ x_multiplier.IsNegative(); //------------------------------------------------------------------ // Copy the final product to this integer. //------------------------------------------------------------------ Copy(product); return *this; } //====================================================================== // Method BQBLargeInteger::AccumulateWithCarry() // This protected method is called from the // unary operator *(const BQBLargeInteger &) method. //====================================================================== void BQBLargeInteger::AccumulateWithCarry(BQBLargeInteger &product, int index, unsigned int value) { bool sum_overflows = true; while ((sum_overflows) && (index < (int)(product.m_integer_length))) { unsigned int temp = product.m_array_ptr[index]; temp = temp + value; sum_overflows = temp < value; value = 1; product.m_array_ptr[index] = temp; ++index; } } BQBLargeInteger BQBLargeInteger::operator *=(long multiplier) { return operator *=(BQBLargeInteger(multiplier)); } BQBLargeInteger BQBLargeInteger::operator *=(unsigned long multiplier) { return operator *=(BQBLargeInteger(multiplier)); } BQBLargeInteger BQBLargeInteger::operator *=(int multiplier) { return operator *=(BQBLargeInteger(multiplier)); } BQBLargeInteger BQBLargeInteger::operator *=(unsigned int multiplier) { return operator *=(BQBLargeInteger(multiplier)); } //====================================================================== // Unary operator / for integral types. //====================================================================== BQBLargeInteger BQBLargeInteger::operator /=(const BQBLargeInteger & divisor) { printf("BQBLargeInteger::operator /=: Warning: Division seems to yield wrong results!\n"); abort(); //------------------------------------------------------------------ // If the divisor is equal to zero then cause a divide by zero // exception. //------------------------------------------------------------------ if (divisor.IsZero()) { //throw BQBLargeIntegerException("Divide by zero"); // Comment out the line above and uncomment the line below // to cause a regular integer divide by zero exception. //unsigned int temp = 1 / divisor.m_array_ptr[0]; printf("BQBLargeInteger::operator /=: Error: Divide by zero.\n"); abort(); } //-------------------------------------------------------------- // Determine the sign of the quotient. //-------------------------------------------------------------- bool quotient_sign = IsNegative() ^ divisor.IsNegative(); //------------------------------------------------------------------ // Set the numerator variable to this object's value so that // this object can return the quotient. //------------------------------------------------------------------ BQBLargeInteger numerator = *this; // Make this numerator positive. numerator.m_negative_flag = false; //------------------------------------------------------------------ // Set the initial value of the quotient to zero. //------------------------------------------------------------------ SetToZero(); //------------------------------------------------------------------ // If the numerator is zero or the the denominator is greater than // the numerator then the quotient is zero. //------------------------------------------------------------------ if (!numerator.IsZero()) { //-------------------------------------------------------------- // Shift the denominator to the left until it becomes the // greatest shifted value that is less than or equal to the // numerator. //-------------------------------------------------------------- int scale_shift = 0; BQBLargeInteger denom = divisor; while (denom < numerator) { denom.ShiftLeft(1); ++scale_shift; } //-------------------------------------------------------------- // Perform long division. //-------------------------------------------------------------- while (numerator >= denom) { BQBLargeInteger difference = numerator - denom; denom.ShiftRight(1); ShiftLeft(1); if (!difference.IsNegative()) { ++m_array_ptr[0]; numerator = difference; } } //-------------------------------------------------------------- // Adjust the numerator for the denominator scaling. //-------------------------------------------------------------- *this <<= scale_shift; //-------------------------------------------------------------- // Normalize the result. //-------------------------------------------------------------- Normalize(); m_negative_flag = quotient_sign; } return *this; } BQBLargeInteger BQBLargeInteger::operator /=(long divisor) { return operator /=(BQBLargeInteger(divisor)); } BQBLargeInteger BQBLargeInteger::operator /=(unsigned long divisor) { return operator /=(BQBLargeInteger(divisor)); } BQBLargeInteger BQBLargeInteger::operator /=(int divisor) { return operator /=(BQBLargeInteger(divisor)); } BQBLargeInteger BQBLargeInteger::operator /=(unsigned int divisor) { return operator /=(BQBLargeInteger(divisor)); } //====================================================================== // operator <<= for integral types. //====================================================================== BQBLargeInteger BQBLargeInteger::operator <<=(const BQBLargeInteger & shift_count) { if (shift_count.FitsIn32Bits()) { if (shift_count.IsNegative()) { ShiftRight(shift_count.m_array_ptr[0]); } else { ShiftLeft(shift_count.m_array_ptr[0]); } } else { SetToZero(); } return *this; } BQBLargeInteger BQBLargeInteger::operator <<=(long shift_count) { return operator <<=(BQBLargeInteger(shift_count)); } BQBLargeInteger BQBLargeInteger::operator <<=(unsigned long shift_count) { return operator <<=(BQBLargeInteger(shift_count)); } BQBLargeInteger BQBLargeInteger::operator <<=(int shift_count) { return operator <<=(BQBLargeInteger(shift_count)); } BQBLargeInteger BQBLargeInteger::operator <<=(unsigned int shift_count) { return operator <<=(BQBLargeInteger(shift_count)); } //====================================================================== // operator >>= for integral types. //====================================================================== BQBLargeInteger BQBLargeInteger::operator >>=(const BQBLargeInteger & shift_count) { if (shift_count.FitsIn32Bits()) { if (shift_count.IsNegative()) { ShiftLeft(shift_count.m_array_ptr[0]); } else { ShiftRight(shift_count.m_array_ptr[0]); } } else { SetToZero(); } return *this; } BQBLargeInteger BQBLargeInteger::operator >>=(long shift_count) { return operator >>=(BQBLargeInteger(shift_count)); } BQBLargeInteger BQBLargeInteger::operator >>=(unsigned long shift_count) { return operator >>=(BQBLargeInteger(shift_count)); } BQBLargeInteger BQBLargeInteger::operator >>=(int shift_count) { return operator >>=(BQBLargeInteger(shift_count)); } BQBLargeInteger BQBLargeInteger::operator >>=(unsigned int shift_count) { return operator >>=(BQBLargeInteger(shift_count)); } //====================================================================== // Unary operator %= for integral types. //====================================================================== BQBLargeInteger BQBLargeInteger::operator %=(const BQBLargeInteger & divisor) { BQBLargeInteger x_temp(*this); operator /=(divisor); operator *=(divisor); return operator -=(x_temp); } BQBLargeInteger BQBLargeInteger::operator %=(long divisor) { return operator %=(BQBLargeInteger(divisor)); } BQBLargeInteger BQBLargeInteger::operator %=(unsigned long divisor) { return operator %=(BQBLargeInteger(divisor)); } BQBLargeInteger BQBLargeInteger::operator %=(int divisor) { return operator %=(BQBLargeInteger(divisor)); } BQBLargeInteger BQBLargeInteger::operator %=(unsigned int divisor) { return operator %=(BQBLargeInteger(divisor)); } //====================================================================== // operator ^= for integral types. //====================================================================== BQBLargeInteger BQBLargeInteger::operator ^=(const BQBLargeInteger & value) { unsigned int largest_integer_length = m_integer_length < value.m_integer_length ? value.m_integer_length : m_integer_length; SetIntegerLength(largest_integer_length); for (unsigned int i = 0; i < m_integer_length; ++i) { m_array_ptr[i] ^= value.GetSafeArrayValue(i); } //------------------------------------------------------------------ // Normalize the result. //------------------------------------------------------------------ Normalize(); return *this; } BQBLargeInteger BQBLargeInteger::operator ^=(long value) { return operator %=(BQBLargeInteger(value)); } BQBLargeInteger BQBLargeInteger::operator ^=(unsigned long value) { return operator %=(BQBLargeInteger(value)); } BQBLargeInteger BQBLargeInteger::operator ^=(int value) { return operator %=(BQBLargeInteger(value)); } BQBLargeInteger BQBLargeInteger::operator ^=(unsigned int value) { return operator %=(BQBLargeInteger(value)); } //====================================================================== // operator &= for integral types. //====================================================================== BQBLargeInteger BQBLargeInteger::operator &=(const BQBLargeInteger & value) { unsigned int largest_integer_length = m_integer_length < value.m_integer_length ? value.m_integer_length : m_integer_length; SetIntegerLength(largest_integer_length); for (unsigned int i = 0; i < m_integer_length; ++i) { m_array_ptr[i] &= value.GetSafeArrayValue(i); } //------------------------------------------------------------------ // Normalize the result. //------------------------------------------------------------------ Normalize(); return *this; } BQBLargeInteger BQBLargeInteger::operator &=(unsigned long value) { return operator &=(BQBLargeInteger(value)); } BQBLargeInteger BQBLargeInteger::operator &=(int value) { return operator &=(BQBLargeInteger(value)); } BQBLargeInteger BQBLargeInteger::operator &=(unsigned int value) { return operator &=(BQBLargeInteger(value)); } //====================================================================== // operator |= for integral types. //====================================================================== BQBLargeInteger BQBLargeInteger::operator |=(const BQBLargeInteger & value) { unsigned int largest_integer_length = m_integer_length < value.m_integer_length ? value.m_integer_length : m_integer_length; SetIntegerLength(largest_integer_length); for (unsigned int i = 0; i < m_integer_length; ++i) { m_array_ptr[i] |= value.GetSafeArrayValue(i); } //------------------------------------------------------------------ // Normalize the result. //------------------------------------------------------------------ Normalize(); return *this; } BQBLargeInteger BQBLargeInteger::operator |=(long value) { return operator |=(BQBLargeInteger(value)); } BQBLargeInteger BQBLargeInteger::operator |=(unsigned long value) { return operator |=(BQBLargeInteger(value)); } BQBLargeInteger BQBLargeInteger::operator |=(int value) { return operator |=(BQBLargeInteger(value)); } BQBLargeInteger BQBLargeInteger::operator |=(unsigned int value) { return operator |=(BQBLargeInteger(value)); } //====================================================================== // operators with no arguments. The * operator and the & operator // with no arguments do not need to be overloaded. //====================================================================== BQBLargeInteger BQBLargeInteger::operator !() { if (IsZero()) { m_array_ptr[0] = (unsigned int)(-1); m_integer_length = 1; } else { SetToZero(); } return *this; } BQBLargeInteger BQBLargeInteger::operator ~() { for (unsigned int i = 0; i < m_integer_length; ++i) { m_array_ptr[i] = ~m_array_ptr[i]; } //------------------------------------------------------------------ // Normalize the result. //------------------------------------------------------------------ Normalize(); return *this; } BQBLargeInteger BQBLargeInteger::operator +() { return *this; } BQBLargeInteger BQBLargeInteger::operator -() { m_negative_flag = ! m_negative_flag; return *this; } //====================================================================== // The prefix form of the increment and decrement operators. //====================================================================== const BQBLargeInteger BQBLargeInteger::operator ++() { operator +=(1); return *this; } const BQBLargeInteger BQBLargeInteger::operator --() { operator -=(1); return *this; } //====================================================================== // The postfix form of the increment and decrement operators. //====================================================================== const BQBLargeInteger BQBLargeInteger::operator ++(int) { BQBLargeInteger x_temp = *this; operator +=(1); return x_temp; } const BQBLargeInteger BQBLargeInteger::operator --(int) { BQBLargeInteger x_temp = *this; operator -=(1); return x_temp; } //====================================================================== // Unary operator == for integral types. //====================================================================== bool BQBLargeInteger::operator ==(const BQBLargeInteger & value) const { unsigned int largest_integer_length = m_integer_length < value.m_integer_length ? value.m_integer_length : m_integer_length; bool bEqual = true; for (unsigned int i = largest_integer_length - 1; (int)(i) >= 0; --i) { if (GetSafeArrayValue(i) != value.GetSafeArrayValue(i)) { bEqual = false; break; } } return bEqual; } bool BQBLargeInteger::operator ==(long value) const { return operator ==(BQBLargeInteger(value)); } bool BQBLargeInteger::operator ==(unsigned long value) const { return operator ==(BQBLargeInteger(value)); } bool BQBLargeInteger::operator ==(int value) const { return operator ==(BQBLargeInteger(value)); } bool BQBLargeInteger::operator ==(unsigned int value) const { return operator ==(BQBLargeInteger(value)); } //====================================================================== // Unary operator != for integral types. //====================================================================== bool BQBLargeInteger::operator !=(const BQBLargeInteger & value) const { return ! operator ==(value); } bool BQBLargeInteger::operator !=(long value) const { return operator !=(BQBLargeInteger(value)); } bool BQBLargeInteger::operator !=(unsigned long value) const { return operator !=(BQBLargeInteger(value)); } bool BQBLargeInteger::operator !=(int value) const { return operator !=(BQBLargeInteger(value)); } bool BQBLargeInteger::operator !=(unsigned int value) const { return operator !=(BQBLargeInteger(value)); } //====================================================================== // Unary operator < for integral types. //====================================================================== bool BQBLargeInteger::operator <(const BQBLargeInteger & value) const { //------------------------------------------------------------------ // If this value is negative and value is positive then // return true. //------------------------------------------------------------------ bool is_less_than_flag = false; if (IsNegative()) { if (!value.IsNegative()) { is_less_than_flag = true; } else { is_less_than_flag = LessThanPositiveArrayCompare(value, *this); } } else { is_less_than_flag = LessThanPositiveArrayCompare(*this, value); } return is_less_than_flag; } bool BQBLargeInteger::operator <(long value) const { return operator <(BQBLargeInteger(value)); } bool BQBLargeInteger::operator <(unsigned long value) const { return operator <(BQBLargeInteger(value)); } bool BQBLargeInteger::operator <(int value) const { return operator <(BQBLargeInteger(value)); } bool BQBLargeInteger::operator <(unsigned int value) const { return operator <(BQBLargeInteger(value)); } //====================================================================== // Unary operator > for integral types. //====================================================================== bool BQBLargeInteger::operator >(const BQBLargeInteger & value) const { return ((!operator <(value)) && (!operator ==(value))); } bool BQBLargeInteger::operator >(long value) const { return operator >(BQBLargeInteger(value)); } bool BQBLargeInteger::operator >(unsigned long value) const { return operator >(BQBLargeInteger(value)); } bool BQBLargeInteger::operator >(int value) const { return operator >(BQBLargeInteger(value)); } bool BQBLargeInteger::operator >(unsigned int value) const { return operator >(BQBLargeInteger(value)); } //====================================================================== // Unary operator <= for integral types. //====================================================================== bool BQBLargeInteger::operator <=(const BQBLargeInteger & value) const { return ! operator >(value); } bool BQBLargeInteger::operator <=(long value) const { return operator <=(BQBLargeInteger(value)); } bool BQBLargeInteger::operator <=(unsigned long value) const { return operator <=(BQBLargeInteger(value)); } bool BQBLargeInteger::operator <=(int value) const { return operator <=(BQBLargeInteger(value)); } bool BQBLargeInteger::operator <=(unsigned int value) const { return operator <=(BQBLargeInteger(value)); } //====================================================================== // Unary operator >= for integral types. //====================================================================== bool BQBLargeInteger::operator >=(const BQBLargeInteger & value) const { return ! operator <(value); } bool BQBLargeInteger::operator >=(long value) const { return operator <(BQBLargeInteger(value)); } bool BQBLargeInteger::operator >=(unsigned long value) const { return operator <(BQBLargeInteger(value)); } bool BQBLargeInteger::operator >=(int value) const { return operator <(BQBLargeInteger(value)); } bool BQBLargeInteger::operator >=(unsigned int value) const { return operator <(BQBLargeInteger(value)); } //====================================================================== // Cast conversion operators. //====================================================================== BQBLargeInteger::operator long() const { return (long)(m_array_ptr[0]); } BQBLargeInteger::operator unsigned long() const { return (unsigned long)(m_array_ptr[0]); } BQBLargeInteger::operator int() const { return (int)(m_array_ptr[0]); } BQBLargeInteger::operator unsigned int() const { return (m_array_ptr[0]); } BQBLargeInteger::operator short() const { return (short)(m_array_ptr[0]); } BQBLargeInteger::operator unsigned short() const { return (unsigned short)(m_array_ptr[0]); } BQBLargeInteger::operator char() const { return (char)(m_array_ptr[0]); } BQBLargeInteger::operator unsigned char() const { return (unsigned char)(m_array_ptr[0]); } BQBLargeInteger::operator bool() const { unsigned int temp = 0; for (unsigned int i = 0; i < m_integer_length; ++i) { temp = temp | m_array_ptr[i]; } return temp != 0; } BQBLargeInteger::operator float() const { #if defined __GNUC__ double Temp = double(*this); return float(Temp); #else long double Temp = long double(*this); return float(Temp); #endif } BQBLargeInteger::operator double() const { double temp = 0; for (int i = m_integer_length - 1; i >= 0; i--) { temp = D_MAX_UNSIGNED_VALUE * temp; temp = temp + m_array_ptr[i]; } return temp; /* #if defined __GNUC__ double Temp = double(*this); return Temp; #else long double Temp = long double(*this); return double(Temp); #endif */ } BQBLargeInteger::operator long double() const { //------------------------------------------------------------------ // If this value is negative then calculate the absolute value. //------------------------------------------------------------------ BQBLargeInteger x_temp; //------------------------------------------------------------------ // Calculate the value as a long double. //------------------------------------------------------------------ long double temp = 0; // for (unsigned int i = m_integer_length - 1; (int)(i) >= 0; ++i) for (int i = m_integer_length - 1; i >= 0; i--) { temp = D_MAX_UNSIGNED_VALUE * temp; temp = temp + m_array_ptr[i]; } return temp; } #ifdef _DEBUG //====================================================================== // Dump the internal format of this large integer. //====================================================================== void BQBLargeInteger::DebugDump(const char * pszText) { if (pszText != 0) { std::cout << pszText << std::endl; } std::cout << "Length = " << m_integer_length << std::endl; for (unsigned int i = 0; i < m_integer_length; ++i) { std::cout << i << " " << m_array_ptr[i] << std::endl; } return; } #endif //====================================================================== // Function to copy an instance of a large integer. //====================================================================== void BQBLargeInteger::Copy(const BQBLargeInteger & that) { SetIntegerLength(that.m_integer_length); m_negative_flag = that.m_negative_flag; for (unsigned int i = 0; i < m_integer_length; ++i) { m_array_ptr[i] = that.m_array_ptr[i]; } return; } //====================================================================== // Add to this large integer. //====================================================================== void BQBLargeInteger::AddPositiveArray(const BQBLargeInteger & addend) { //------------------------------------------------------------------ // Make sure this large integer's array is as least as large // as the addends array. //------------------------------------------------------------------ if (m_integer_length < addend.m_integer_length) { SetIntegerLength(addend.m_integer_length, true); } //------------------------------------------------------------------ // Add the addend to this large integer. //------------------------------------------------------------------ unsigned int carry = 0; for (unsigned int i = 0; i < m_integer_length; ++i) { unsigned int addend_array_value = addend.GetSafeArrayValue(i); m_array_ptr[i] = m_array_ptr[i] + addend_array_value + carry; carry = (m_array_ptr[i] < addend_array_value) ? 1 : 0; } //------------------------------------------------------------------ // If a carry occurred in the most significant word then increase // the size of this large integer. //------------------------------------------------------------------ if (carry == 1) { SetIntegerLength(m_integer_length + 1, true); m_array_ptr[m_integer_length - 1] = 1; } return; } //====================================================================== // Subtract from this large integer. //====================================================================== bool BQBLargeInteger::SubtractPositiveArray(const BQBLargeInteger & subtrahend) { //------------------------------------------------------------------ // Make sure this large integer's array is the same size // as the subtrahend's array. //------------------------------------------------------------------ if (m_integer_length < subtrahend.m_integer_length) { SetIntegerLength(subtrahend.m_integer_length, true); } //------------------------------------------------------------------ // Save the most significant array value. If this increases // after the subtraction then the minuend is less than the // subtrahend. //------------------------------------------------------------------ unsigned int most_significant_array_value = m_array_ptr[m_integer_length - 1]; //------------------------------------------------------------------ // Subtract the subtrahend from this large integer. //------------------------------------------------------------------ bool borrow = false; for (unsigned int i = 0; i < m_integer_length; ++i) { unsigned int minuend_array_value = m_array_ptr[i]; unsigned int subtrahend_array_value = subtrahend.GetSafeArrayValue(i); unsigned int difference = minuend_array_value - subtrahend_array_value; m_array_ptr[i] = difference - (borrow ? 1 : 0); borrow = borrow & (difference == 0); if (!borrow) { borrow = minuend_array_value < subtrahend_array_value; } } //------------------------------------------------------------------ // If the result taken as a two's complement integer is negative // then the magnitude of the minuend was less than the magnitude // of the subtrahend. In this case, take the two's complement of // the result to get a positive result and return the value true // from this method to signal the the sign of the result should // be toggled. //------------------------------------------------------------------ bool reverse_sign = m_array_ptr[m_integer_length - 1] > most_significant_array_value; if (reverse_sign) { //------------------------------------------------------------- // Add one to the one's complement of the result to obtain // the two's complement value. //------------------------------------------------------------- operator ~(); BQBLargeInteger xOne(1); AddPositiveArray(xOne); } return reverse_sign; } //====================================================================== // Function to shift this large integer to the left. //====================================================================== void BQBLargeInteger::ShiftLeft(unsigned int shift_count) { if (shift_count != 0) { //-------------------------------------------------------------- // The array could grow as a result of this shift. Determine // the new size of the array. Find the first non-zero value // in the array starting at the most significant array value. //-------------------------------------------------------------- bool bNonZero = false; unsigned int nonzero_array_index = 0; for (nonzero_array_index = m_integer_length - 1; (int)(nonzero_array_index) >= 0; --nonzero_array_index) { if (m_array_ptr[nonzero_array_index] != 0) { bNonZero = true; break; } } //-------------------------------------------------------------- // If the value is zero then it is not necessary to shift // this value. //-------------------------------------------------------------- if (bNonZero) { //---------------------------------------------------------- // Determine the position of the bit in the most // significant word. //---------------------------------------------------------- unsigned int most_significant_value = m_array_ptr[nonzero_array_index]; unsigned int bit_position = 0; for (bit_position = 0; bit_position < INTEGER_BIT_COUNT; ++bit_position) { //------------------------------------------------------ // Test the most significant bit. //------------------------------------------------------ if ((int)(most_significant_value) < 0) { break; } most_significant_value <<= 1; } bit_position = INTEGER_BIT_COUNT - 1 - bit_position; //---------------------------------------------------------- // Calculate the position of the most significant bit // in the integer array. //---------------------------------------------------------- unsigned int array_bit_position = INTEGER_BIT_COUNT * nonzero_array_index + bit_position; //---------------------------------------------------------- // Calculate the position of the most significant bit // after shifting this number to the left. //---------------------------------------------------------- unsigned int final_shift_position = array_bit_position + shift_count; //---------------------------------------------------------- // Make the number array large enough for the left shift. //---------------------------------------------------------- unsigned int integer_length = (final_shift_position + INTEGER_BIT_COUNT) / INTEGER_BIT_COUNT; SetIntegerLength(integer_length, true); //---------------------------------------------------------- // Do all shifts that are a multiple of 32. //---------------------------------------------------------- unsigned int array_shift_value = shift_count / INTEGER_BIT_COUNT; if (array_shift_value != 0) { for (unsigned int i = m_integer_length - 1; (int)(i) >= 0; --i) { m_array_ptr[i] = GetSafeArrayValue(i - array_shift_value); } } //---------------------------------------------------------- // Do the remaining shifts. //---------------------------------------------------------- unsigned int remaining_shift_count = shift_count - (array_shift_value * INTEGER_BIT_COUNT); for (unsigned int i = m_integer_length - 1; (int)(i) >= 0; --i) { m_array_ptr[i] = (m_array_ptr[i] << remaining_shift_count) | (GetSafeArrayValue(i - 1) >> (INTEGER_BIT_COUNT - remaining_shift_count)); } //---------------------------------------------------------- // Normalize the result. //---------------------------------------------------------- Normalize(); } } return; } //====================================================================== // Function to shift this large integer to the right. //====================================================================== void BQBLargeInteger::ShiftRight(unsigned int shift_count) { if (shift_count != 0) { //-------------------------------------------------------------- // Do all shifts that are a multiple of 32. //-------------------------------------------------------------- if (shift_count < m_integer_length * INTEGER_BIT_COUNT) { unsigned int array_shift_value = shift_count / INTEGER_BIT_COUNT; if (array_shift_value != 0) { for (unsigned int i = 0; i < m_integer_length - array_shift_value; ++i) { m_array_ptr[i] = m_array_ptr[i + array_shift_value]; } } //---------------------------------------------------------- // Do the remaining shifts. //---------------------------------------------------------- unsigned int remaining_shift_count = shift_count - (array_shift_value * INTEGER_BIT_COUNT); for (unsigned int i = 0; i < m_integer_length; ++i) { m_array_ptr[i] = (m_array_ptr[i] >> remaining_shift_count) | (GetSafeArrayValue(i + 1) << (INTEGER_BIT_COUNT - remaining_shift_count)); } //---------------------------------------------------------- // Normalize the result. //---------------------------------------------------------- Normalize(); } else { SetToZero(); } } return; } //====================================================================== // Function to test for this large integer equal to zero. //====================================================================== bool BQBLargeInteger::IsZero() const { unsigned int temp = 0; for (unsigned int i = 0; i < m_integer_length; ++i) { temp |= m_array_ptr[i]; } return temp == 0; } //====================================================================== // Function to test for this large integer equal to zero. //====================================================================== bool BQBLargeInteger::IsNegative() const { return m_negative_flag; } //====================================================================== // Function to test if the value fits in 32 bits. //====================================================================== bool BQBLargeInteger::FitsIn32Bits() const { return m_integer_length == 1; } //====================================================================== // Member Function: BQBLargeInteger::SetIntegerLength // Author: Bill Hallahan // Date: March 30, 1998 // // Abstract: // // This function is called to set the large integer length. // If the new integer length is greater than the current array // length OR the new buffer length is less than one fourth the // current array length then the array is reallocated. If the // buffer is resized to a be smaller array OR if the passed // boolean value 'copy_data_flag' is the value true then the // data in the old array is copied to the newly allocated // array before the old array memory is freed. // // // Input: // // integer_length The new integer length. // // copy_data_flag If this flag is true then the // data in the array before the length // is modified is copied into the new // buffer. The value is sign extended // if necessary.. // // // Output: // // This function has no return value. // //====================================================================== void BQBLargeInteger::SetIntegerLength(unsigned int integer_length, bool copy_data_flag) { //------------------------------------------------------------------ // If the new data length is greater than the current buffer // length then allocate a larger buffer for the data. // Also if the new data length is less than one fourth the // current buffer length then allocate a new array. //------------------------------------------------------------------ bool reallocate_array_memory = integer_length > m_array_length; //------------------------------------------------------------------ // Also if the new data length is less than one fourth the // current buffer length then allocate a new array. //------------------------------------------------------------------ if (!reallocate_array_memory) { reallocate_array_memory = integer_length < (m_array_length >> 2); copy_data_flag = true; } //------------------------------------------------------------------ // Conditionally reallocate the large integer array. //------------------------------------------------------------------ if (reallocate_array_memory) { //-------------------------------------------------------------- // Allocate a new buffer. //-------------------------------------------------------------- unsigned int * array_ptr = new unsigned int [integer_length]; bool memory_allocated = array_ptr != 0; if (memory_allocated) { if (copy_data_flag) { //------------------------------------------------------ // Copy the data from the old buffer to the new one. //------------------------------------------------------ unsigned int copy_length = integer_length; if (m_integer_length < integer_length) { copy_length = m_integer_length; } for (unsigned int i = 0; i < copy_length; ++i) { array_ptr[i] = m_array_ptr[i]; } //------------------------------------------------------ // If the copied data is shorter than the new array // length then zero-fill the rest of the array. //------------------------------------------------------ if (copy_length < integer_length) { for (unsigned int j = copy_length; j < integer_length; ++j) { array_ptr[j] = 0; } } } else { //------------------------------------------------------ // Fill the array with zeros. //------------------------------------------------------ for (unsigned int i = 0; i < integer_length; ++i) { array_ptr[i] = 0; } } //---------------------------------------------------------- // Delete the old buffer. //---------------------------------------------------------- delete [] m_array_ptr; //---------------------------------------------------------- // Save the new buffer pointer. //---------------------------------------------------------- m_array_ptr = array_ptr; //---------------------------------------------------------- // Set the buffer length and the integer length. //---------------------------------------------------------- m_array_length = integer_length; } else { //---------------------------------------------------------- // Memory allocation failed. Throw an exception. //---------------------------------------------------------- //throw BQBLargeIntegerException("Memory allocation failed"); printf("BQBLargeInteger::SetIntegerLength(): Error: Memory allocation failed.\n"); abort(); } } //------------------------------------------------------------------ // Set the length of the integer. //------------------------------------------------------------------ m_integer_length = integer_length; return; } //====================================================================== // Set this large integer value to zero. //====================================================================== void BQBLargeInteger::SetToZero() { SetIntegerLength(1); m_array_ptr[0] = 0; return; } //====================================================================== // Get the array value. If the index is out of range then return // the value zero. //====================================================================== unsigned int BQBLargeInteger::GetSafeArrayValue(unsigned int index) const { unsigned int array_value; if (index < m_integer_length) { array_value = m_array_ptr[index]; } else { array_value = 0; } return array_value; } //====================================================================== // Set the integer length to the smallest length for this value. //====================================================================== void BQBLargeInteger::Normalize() { //------------------------------------------------------------------ // Discard all leading zeros. //------------------------------------------------------------------ unsigned int integer_length = 1; for (unsigned int i = m_integer_length - 1; i > 0; --i) { if (m_array_ptr[i] != 0) { integer_length = i + 1; break; } } m_integer_length = integer_length; return; } //====================================================================== // Private Method to compare the positive arrays of two large integers. //====================================================================== bool BQBLargeInteger::LessThanPositiveArrayCompare(const BQBLargeInteger & value_0, const BQBLargeInteger & value_1) const { unsigned int largest_integer_length = value_0.m_integer_length > value_1.m_integer_length ? value_0.m_integer_length : value_1.m_integer_length; bool is_less_than_flag = false; for (unsigned int i = largest_integer_length - 1; (int)(i) >= 0; --i) { unsigned int array_value_0 = value_0.GetSafeArrayValue(i); unsigned int array_value_1 = value_1.GetSafeArrayValue(i); if (array_value_0 < array_value_1) { is_less_than_flag = true; } else if (array_value_0 > array_value_1) { break; } } return is_less_than_flag; } //====================================================================== // Calculate the population count for a 32 bit integer. //====================================================================== unsigned int BQBLargeInteger::PopulationCount32Bit(unsigned int value) const { #ifndef LARGE_INT_ALTERNATE_POP_COUNT unsigned int shift_value = 1; for (unsigned int i = 0; i < BIT_MASK_TABLE_LENGTH; ++i) { unsigned int bit_mask = BIT_MASK_ARRAY[i]; value = ((value & bit_mask) >> shift_value) + (value & ~bit_mask); shift_value = shift_value << 1; } return value; #else unsigned int temp = value - ((value >> 1) & MASK_3) - ((value >> 2) & MASK_1); temp = (temp + (temp >> 3)) & MASK_7; return temp % 63; #endif } //====================================================================== // Get this large integer value in an stl string in base 8. //====================================================================== void BQBLargeInteger::GetBase8NumberString(std::string & number_string) const { //-------------------------------------------------------------- // Get the base 8 digits. //-------------------------------------------------------------- std::string base8_digits_string; GetBase8Digits(base8_digits_string); //-------------------------------------------------------------- // Convert the base 8 digits to ascii characters. //-------------------------------------------------------------- number_string.erase(); for (unsigned int i = 0; i < base8_digits_string.length(); ++i) { number_string += base8_digits_string[i] + '0'; } return; } //====================================================================== // Get the base 8 digits in an STL string. //====================================================================== void BQBLargeInteger::GetBase8Digits(std::string & base8_digits_string) const { base8_digits_string.erase(); //-------------------------------------------------------------- // Calculate the base 8 digits. Convert 3 bits at a time // to an octal digit starting at the most significant bits. //-------------------------------------------------------------- unsigned int current_bit_position_plus_one = INTEGER_BIT_COUNT * m_integer_length; unsigned int extra_bits = current_bit_position_plus_one % 3; unsigned int index = m_integer_length - 1; while (current_bit_position_plus_one != 0) { char base8_digit; switch (extra_bits) { case 0: base8_digits_string += (char)((m_array_ptr[index] >> 29) & 7); base8_digits_string += (char)((m_array_ptr[index] >> 26) & 7); base8_digits_string += (char)((m_array_ptr[index] >> 23) & 7); base8_digits_string += (char)((m_array_ptr[index] >> 20) & 7); base8_digits_string += (char)((m_array_ptr[index] >> 17) & 7); base8_digits_string += (char)((m_array_ptr[index] >> 14) & 7); base8_digits_string += (char)((m_array_ptr[index] >> 11) & 7); base8_digits_string += (char)((m_array_ptr[index] >> 8) & 7); base8_digits_string += (char)((m_array_ptr[index] >> 5) & 7); base8_digits_string += (char)((m_array_ptr[index] >> 2) & 7); break; case 1: base8_digit = (char)(((GetSafeArrayValue(index + 1) & 3) << 1) | ((m_array_ptr[index] >> 31) & 1)); base8_digits_string += base8_digit; base8_digits_string += (char)((m_array_ptr[index] >> 28) & 7); base8_digits_string += (char)((m_array_ptr[index] >> 25) & 7); base8_digits_string += (char)((m_array_ptr[index] >> 22) & 7); base8_digits_string += (char)((m_array_ptr[index] >> 19) & 7); base8_digits_string += (char)((m_array_ptr[index] >> 16) & 7); base8_digits_string += (char)((m_array_ptr[index] >> 13) & 7); base8_digits_string += (char)((m_array_ptr[index] >> 10) & 7); base8_digits_string += (char)((m_array_ptr[index] >> 7) & 7); base8_digits_string += (char)((m_array_ptr[index] >> 4) & 7); base8_digits_string += (char)((m_array_ptr[index] >> 1) & 7); break; case 2: base8_digit = (char)(((GetSafeArrayValue(index + 1) & 1) << 2) | ((m_array_ptr[index] >> 30) & 3)); base8_digits_string += base8_digit; base8_digits_string += (char)((m_array_ptr[index] >> 27) & 7); base8_digits_string += (char)((m_array_ptr[index] >> 24) & 7); base8_digits_string += (char)((m_array_ptr[index] >> 21) & 7); base8_digits_string += (char)((m_array_ptr[index] >> 18) & 7); base8_digits_string += (char)((m_array_ptr[index] >> 15) & 7); base8_digits_string += (char)((m_array_ptr[index] >> 12) & 7); base8_digits_string += (char)((m_array_ptr[index] >> 9) & 7); base8_digits_string += (char)((m_array_ptr[index] >> 6) & 7); base8_digits_string += (char)((m_array_ptr[index] >> 3) & 7); base8_digits_string += (char)(m_array_ptr[index] & 7); break; default: break; } --index; extra_bits = (extra_bits + 1) % 3; current_bit_position_plus_one -= INTEGER_BIT_COUNT; } //------------------------------------------------------------------ // Strip any extra sign extension characters. //------------------------------------------------------------------ StripLeadingZeroDigits(base8_digits_string, 0); return; } //====================================================================== // Get this large integer value in an stl string in base 10. //====================================================================== void BQBLargeInteger::GetBase10NumberString(std::string & number_string) const { //------------------------------------------------------------------ // Determine whether the product is a negative value. //------------------------------------------------------------------ BQBLargeInteger x_temp = *this; //------------------------------------------------------------------ // Get the base 8 digits. //------------------------------------------------------------------ std::string digits_string; x_temp.GetBase8Digits(digits_string); //------------------------------------------------------------------ // Convert the base 8 string to a base 10 string using the // algorithm from "Semi-Numerical Methods", by Knuth. // Double the K leading octal digits using decimal arithmetic // and subtract them from the K + 1 leading digits using // decimal arithmetic. //------------------------------------------------------------------ char * digit_array_ptr = const_cast(digits_string.data()); unsigned int digit_length = (unsigned int)(digits_string.length()); char * subtrahend_ptr = new char [digit_length]; if (subtrahend_ptr == 0) { //throw BQBLargeIntegerException("Memory allocation failed"); printf("BQBLargeInteger::GetBase10NumberString(): Error: Memory allocation failed.\n"); abort(); } for (unsigned int k = 0; k < digit_length - 1; ++k) { //-------------------------------------------------------------- // Double the K leading octal digits using base 10 arithmetic // and copy these digits into the K + 1'st location in the // subtrahend array. //-------------------------------------------------------------- unsigned int j = 0; for (j = k + 1; (int)(j) >= 0; --j) { subtrahend_ptr[j] = 0; } for (j = k; (int)(j) >= 0; --j) { char doubled_digit = digit_array_ptr[j] << 1; if (doubled_digit > 9) { subtrahend_ptr[j + 1] += doubled_digit - 10; subtrahend_ptr[j] += 1; } else { subtrahend_ptr[j + 1] += doubled_digit; } } //-------------------------------------------------------------- // Subtract the doubled digits from the original number // using decimal arithmetic. //-------------------------------------------------------------- for (unsigned int m = k + 1; (int)(m) >= 0; --m) { char difference = digit_array_ptr[m] - subtrahend_ptr[m]; if (difference < 0) { digit_array_ptr[m] = difference + 10; if ((int)(m - 1) >= 0) { digit_array_ptr[m - 1] -= 1; } } else { digit_array_ptr[m] = difference; } } } delete [] subtrahend_ptr; //------------------------------------------------------------------ // Convert the digits to characters. First skip all leading zeros. //------------------------------------------------------------------ unsigned int first_nonzero_position = 0; for (first_nonzero_position = 0; first_nonzero_position < digits_string.length(); ++first_nonzero_position) { if (digits_string[first_nonzero_position] != 0) { break; } } number_string.erase(); for (unsigned int j = first_nonzero_position; j < digits_string.length(); ++j) { number_string += digits_string[j] + '0'; } return; } //====================================================================== // Get this large integer value in an stl string in base 16. //====================================================================== void BQBLargeInteger::GetBase16NumberString(std::string & number_string) const { number_string.erase(); //------------------------------------------------------------------ // Convert the digits. //------------------------------------------------------------------ for (unsigned int i = m_integer_length - 1; (int)(i) >= 0; --i) { unsigned int hex_digits = m_array_ptr[i]; for (int iShift = 28; iShift >= 0; iShift -= 4) { number_string += DIGIT_ARRAY[((hex_digits >> iShift) & 0x0F)]; } } //------------------------------------------------------------------ // Strip any extra sign extension characters. //------------------------------------------------------------------ StripLeadingZeroDigits(number_string, '0'); return; } //====================================================================== // Strip any extra zero digits. //====================================================================== void BQBLargeInteger::StripLeadingZeroDigits(std::string & number_string, char zero_digit) const { //------------------------------------------------------------------ // Find the position past any extra zero digit characters. //------------------------------------------------------------------ int start_position = 0; int digit_length = (int)number_string.length(); for (int index = 0; index < digit_length - 1; ++index) { if (number_string[index] == zero_digit) { ++start_position; } else { break; } } //------------------------------------------------------------------ // If necessary then strip leading zero digit characters. //------------------------------------------------------------------ if (start_position != 0) { if (start_position > 0) { number_string = number_string.substr(start_position); } else { number_string = number_string.substr(digit_length - 1); } } return; } //====================================================================== // Set the value of this large integer value using a base 8 string. // Leading sign characters and space characters must be removed // before calling this method. //====================================================================== bool BQBLargeInteger::SetValueWithBase8String(const char * base8_digits_ptr) { //------------------------------------------------------------------ // Get the length of the input string. //------------------------------------------------------------------ size_t digit_length = ::strlen(base8_digits_ptr); //------------------------------------------------------------------ // Convert the octal digit characters to octal values. //------------------------------------------------------------------ std::string digits_string = base8_digits_ptr; char * digit_array_ptr = const_cast(digits_string.data()); digit_length = (unsigned int)(digits_string.length()); //------------------------------------------------------------------ // Convert the digit characters to digit values. //------------------------------------------------------------------ bool success_flag = false; for (int i = 0; i < (int)(digit_length); ++i) { char digit = digit_array_ptr[i]; success_flag = ((digit >= '0') && (digit < '8')); if (success_flag) { digit_array_ptr[i] = digit - '0'; } else { break; } } if (success_flag) { //-------------------------------------------------------------- // Strip any extra sign extension characters. //-------------------------------------------------------------- StripLeadingZeroDigits(digits_string, 0); //-------------------------------------------------------------- // Set the value of this large integer using the base 8 // digit values. //-------------------------------------------------------------- SetValueWithBase8DigitValues(digits_string); } return success_flag; } //====================================================================== // Set the value of this large integer using the base 8 digit values. //====================================================================== void BQBLargeInteger::SetValueWithBase8DigitValues(const std::string & base8_digit_string) { //------------------------------------------------------------------ // Set the length of the array. //------------------------------------------------------------------ unsigned int number_of_digits = (unsigned int)base8_digit_string.length(); unsigned int current_bit_position_plus_one = 3 * number_of_digits; unsigned int integer_length = (current_bit_position_plus_one + (INTEGER_BIT_COUNT - 1)) / INTEGER_BIT_COUNT; SetIntegerLength(integer_length); //------------------------------------------------------------------ // Add each digit to the array. //------------------------------------------------------------------ current_bit_position_plus_one -= 3; unsigned int array_index = integer_length - 1; for (unsigned int octal_digit_index = 0; octal_digit_index < number_of_digits; ++octal_digit_index) { // The bit length is currently 32-bits. #ifdef INT_BIT_LENGTH_IS_POWER_OF_TWO unsigned int shift_value = current_bit_position_plus_one & (INTEGER_BIT_COUNT - 1); #else unsigned int shift_value = current_bit_position_plus_one % INTEGER_BIT_COUNT; #endif current_bit_position_plus_one -= 3; unsigned int octal_digit = 0; switch (shift_value) { case 0: case 1: case 2: { octal_digit = (unsigned int)(base8_digit_string[octal_digit_index]); m_array_ptr[array_index] |= octal_digit << shift_value; } --array_index; break; case 3: case 4: case 5: case 6: case 7: case 8: case 9: case 10: case 11: case 12: case 13: case 14: case 15: case 16: case 17: case 18: case 19: case 20: case 21: case 22: case 23: case 24: case 25: case 26: case 27: case 28: case 29: { octal_digit = (unsigned int)(base8_digit_string[octal_digit_index]); m_array_ptr[array_index] |= octal_digit << shift_value; } break; case 30: { octal_digit = (unsigned int)(base8_digit_string[octal_digit_index]); m_array_ptr[array_index] |= (octal_digit & 3) << 30; if (array_index + 1 < integer_length) { m_array_ptr[array_index + 1] |= (octal_digit & 4) >> 2; } } break; case 31: { octal_digit = (unsigned int)(base8_digit_string[octal_digit_index]); m_array_ptr[array_index] |= (octal_digit & 1) << 31; if (array_index + 1 < integer_length) { m_array_ptr[array_index + 1] |= ((octal_digit & 6) >> 1); } } break; default: break; } } return; } //====================================================================== // Set the value of this large integer value using a base 10 string. // Leading sign characters and space characters must be removed // before calling this method. //====================================================================== bool BQBLargeInteger::SetValueWithBase10String(const char * digits_ptr) { //------------------------------------------------------------------ // Convert the decimal string to octal digit values. //------------------------------------------------------------------ std::string base8_digit_string; bool success_flag = ConvertDecimalStringToOctalDigits(digits_ptr, base8_digit_string); //------------------------------------------------------------------ // Set the value of this large integer using the base 8 // digit values. //------------------------------------------------------------------ if (success_flag) { SetValueWithBase8DigitValues(base8_digit_string); } return success_flag; } //====================================================================== // Convert a base 10 string of characters to base 8 values. // The passed string contains decimal character digits representing // a positive value in base 10. Leading sign characters and space // characters must be removed before calling this method. //====================================================================== bool BQBLargeInteger::ConvertDecimalStringToOctalDigits(const char * decimal_digits_ptr, std::string & digits_string) const { unsigned int i; //------------------------------------------------------------------ // Get the length of the input string. //------------------------------------------------------------------ size_t digit_length = ::strlen(decimal_digits_ptr); //-------------------------------------------------------------- // Convert the decimal digit characters to decimal values. //-------------------------------------------------------------- digits_string = decimal_digits_ptr; //-------------------------------------------------------------- // Insert leading zeros to allow for number growth. // // The algorithm used to calculate the number of digits // of growth is not exact, but it provides a conservative // value that guarantees that there will be enough extra // digits for growth. //-------------------------------------------------------------- unsigned int padding = (unsigned int)(((200 * digit_length) / 1000) + 1); char * padding_ptr = new char [padding]; if (padding_ptr == 0) { //throw BQBLargeIntegerException("Memory allocation failed"); printf("BQBLargeInteger::ConvertDecimalStringToOctalDigits(): Error: Memory allocation failed.\n"); abort(); } for (i = 0; i < padding; ++i) { padding_ptr[i] = 0; } digits_string.insert(0, padding_ptr, padding); delete [] padding_ptr; //-------------------------------------------------------------- // Get the new digit length and the buffer pointer. //-------------------------------------------------------------- digit_length = (unsigned int)(digits_string.length()); char * digit_array_ptr = const_cast(digits_string.data()); //-------------------------------------------------------------- // Convert the digit characters to digit values. //-------------------------------------------------------------- bool success_flag = false; for (i = padding; i < digit_length; ++i) { char digit = digit_array_ptr[i]; success_flag = ::isdigit(digit) != 0; if (success_flag) { digit_array_ptr[i] = digit - '0'; } else { break; } } //-------------------------------------------------------------- // Convert the base 10 digits to base 8 digits. //-------------------------------------------------------------- if (success_flag) { //---------------------------------------------------------- // Convert the base 8 string to base 10 digits using the // algorithm from "Semi-Numerical Methods", by Knuth. // Double the K leading octal digits using octal arithmetic // and add them from the K + 1 leading digits using octal // arithmetic. //---------------------------------------------------------- char * addend_ptr = new char [digit_length + 1]; if (addend_ptr == 0) { //throw BQBLargeIntegerException("Memory allocation failed"); printf("BQBLargeInteger::ConvertDecimalStringToOctalDigits(): Error: Memory allocation failed.\n"); abort(); } for (unsigned int k = 0; k < digit_length - 1; ++k) { //------------------------------------------------------ // Double the K leading decimal digits using base 8 // arithmetic and copy these digits into the K + 1'st // location in the addend array. //------------------------------------------------------ unsigned int j = 0; for (j = k + 1; (int)(j) >= 0; --j) { addend_ptr[j] = 0; } for (j = k; (int)(j) >= 0; --j) { char doubled_digit = digit_array_ptr[j] << 1; if (doubled_digit > 7) { addend_ptr[j + 1] += doubled_digit - 8; addend_ptr[j] += 1; } else { addend_ptr[j + 1] += doubled_digit; } } //---------------------------------------------------------- // Add the doubled digits from the original number // using octal arithmetic. //---------------------------------------------------------- for (unsigned int m = k + 1; (int)(m) >= 0; --m) { char sum = digit_array_ptr[m] + addend_ptr[m]; if (sum > 7) { digit_array_ptr[m] = sum - 8; if ((int)(m - 1) >= 0) { digit_array_ptr[m - 1] += 1; } } else { digit_array_ptr[m] = sum; } } } delete [] addend_ptr; //-------------------------------------------------------------- // Remove all leading zeros. //-------------------------------------------------------------- unsigned int start_position = 0; for (i = 0; i < digits_string.length(); ++i) { if ((digits_string[i] != 0) || (i == digits_string.length() - 1)) { start_position = i; break; } } if (start_position != 0) { digits_string = digits_string.substr(start_position); } } return success_flag; } //====================================================================== // Set the value of this large integer value using a base 16 string. // Leading sign characters and space characters must be removed // before calling this method. //====================================================================== bool BQBLargeInteger::SetValueWithBase16String(const char * digits_ptr) { //------------------------------------------------------------------ // Convert the hexadecimal string to hexadecimal digit values. //------------------------------------------------------------------ bool success_flag = true; std::string hex_number_string = digits_ptr; unsigned int number_of_digits = (unsigned int)(hex_number_string.length()); char * hex_digits_ptr = const_cast(hex_number_string.data()); for (unsigned int i = 0; i < number_of_digits; ++i) { int digit = (int)(hex_digits_ptr[i]); success_flag = ::isxdigit(digit) != 0; if (success_flag) { if (::isdigit(digit)) { hex_digits_ptr[i] = (char)(digit - '0'); } else { hex_digits_ptr[i] = (char)(::toupper(digit)) + 10 - 'A'; } } else { break; } } //------------------------------------------------------------------ // Set the value of this large integer using the base 8 // digit values. //------------------------------------------------------------------ if (success_flag) { //-------------------------------------------------------------- // Strip any extra sign extension characters. //-------------------------------------------------------------- StripLeadingZeroDigits(hex_number_string, 0); //-------------------------------------------------------------- // Set the value of this large integer using the base 16 // digit values. //-------------------------------------------------------------- SetValueWithBase16DigitValues(hex_number_string); } return success_flag; } //====================================================================== // Set the value of this large integer value using a base 16 string. // Leading space characters must be removed before calling this method. //====================================================================== void BQBLargeInteger::SetValueWithBase16DigitValues(const std::string & base16_digit_values_string) { //------------------------------------------------------------------ // Set the length of the array. //------------------------------------------------------------------ unsigned int number_of_digits = (unsigned int)base16_digit_values_string.length(); unsigned int integer_length = (number_of_digits + 7) >> 3; SetIntegerLength(integer_length); //------------------------------------------------------------------ // Add each digit to the array. // Handle extra digits that do not fill a complete word. //------------------------------------------------------------------ unsigned int array_index = integer_length - 1; unsigned int current_digit_index = 0; unsigned int extra_digits = number_of_digits - ((integer_length - 1) << 3); unsigned int hex_digit; switch (extra_digits) { case 7: { hex_digit = base16_digit_values_string[current_digit_index++]; m_array_ptr[array_index] |= hex_digit << 24; hex_digit = base16_digit_values_string[current_digit_index++]; m_array_ptr[array_index] |= hex_digit << 20; hex_digit = base16_digit_values_string[current_digit_index++]; m_array_ptr[array_index] |= hex_digit << 16; hex_digit = base16_digit_values_string[current_digit_index++]; m_array_ptr[array_index] |= hex_digit << 12; hex_digit = base16_digit_values_string[current_digit_index++]; m_array_ptr[array_index] |= hex_digit << 8; hex_digit = base16_digit_values_string[current_digit_index++]; m_array_ptr[array_index] |= hex_digit << 4; hex_digit = base16_digit_values_string[current_digit_index++]; m_array_ptr[array_index--] |= hex_digit; } break; case 6: { hex_digit = base16_digit_values_string[current_digit_index++]; m_array_ptr[array_index] |= hex_digit << 20; hex_digit = base16_digit_values_string[current_digit_index++]; m_array_ptr[array_index] |= hex_digit << 16; hex_digit = base16_digit_values_string[current_digit_index++]; m_array_ptr[array_index] |= hex_digit << 12; hex_digit = base16_digit_values_string[current_digit_index++]; m_array_ptr[array_index] |= hex_digit << 8; hex_digit = base16_digit_values_string[current_digit_index++]; m_array_ptr[array_index] |= hex_digit << 4; hex_digit = base16_digit_values_string[current_digit_index++]; m_array_ptr[array_index--] |= hex_digit; } break; case 5: { hex_digit = base16_digit_values_string[current_digit_index++]; m_array_ptr[array_index] |= hex_digit << 16; hex_digit = base16_digit_values_string[current_digit_index++]; m_array_ptr[array_index] |= hex_digit << 12; hex_digit = base16_digit_values_string[current_digit_index++]; m_array_ptr[array_index] |= hex_digit << 8; hex_digit = base16_digit_values_string[current_digit_index++]; m_array_ptr[array_index] |= hex_digit << 4; hex_digit = base16_digit_values_string[current_digit_index++]; m_array_ptr[array_index--] |= hex_digit; } break; case 4: { hex_digit = base16_digit_values_string[current_digit_index++]; m_array_ptr[array_index] |= hex_digit << 12; hex_digit = base16_digit_values_string[current_digit_index++]; m_array_ptr[array_index] |= hex_digit << 8; hex_digit = base16_digit_values_string[current_digit_index++]; m_array_ptr[array_index] |= hex_digit << 4; hex_digit = base16_digit_values_string[current_digit_index++]; m_array_ptr[array_index--] |= hex_digit; } break; case 3: { hex_digit = base16_digit_values_string[current_digit_index++]; m_array_ptr[array_index] |= hex_digit << 8; hex_digit = base16_digit_values_string[current_digit_index++]; m_array_ptr[array_index] |= hex_digit << 4; hex_digit = base16_digit_values_string[current_digit_index++]; m_array_ptr[array_index--] |= hex_digit; } break; case 2: { hex_digit = base16_digit_values_string[current_digit_index++]; m_array_ptr[array_index] |= hex_digit << 4; hex_digit = base16_digit_values_string[current_digit_index++]; m_array_ptr[array_index--] |= hex_digit; } break; case 1: { hex_digit = base16_digit_values_string[current_digit_index++]; m_array_ptr[array_index--] |= hex_digit; } break; case 0: default: break; } if (number_of_digits > 7) { //------------------------------------------------------------- // The number of digits remaining is a multiple of 8. // Copy these digits into the term array. //------------------------------------------------------------- for (unsigned int hex_digitIndex = current_digit_index; hex_digitIndex < number_of_digits; hex_digitIndex += 8) { unsigned int hex_digit_0 = base16_digit_values_string[hex_digitIndex]; unsigned int hex_digit_1 = base16_digit_values_string[hex_digitIndex + 1]; unsigned int hex_digit_2 = base16_digit_values_string[hex_digitIndex + 2]; unsigned int hex_digit_3 = base16_digit_values_string[hex_digitIndex + 3]; unsigned int hex_digit_4 = base16_digit_values_string[hex_digitIndex + 4]; unsigned int hex_digit_5 = base16_digit_values_string[hex_digitIndex + 5]; unsigned int hex_digit_6 = base16_digit_values_string[hex_digitIndex + 6]; unsigned int hex_digit_7 = base16_digit_values_string[hex_digitIndex + 7]; m_array_ptr[array_index--] = (hex_digit_0 << 28) | (hex_digit_1 << 24) | (hex_digit_2 << 20) | (hex_digit_3 << 16) | (hex_digit_4 << 12) | (hex_digit_5 << 8) | (hex_digit_6 << 4) | hex_digit_7; } } return; } //====================================================================== // Global function declarations. //====================================================================== //====================================================================== // operator + for integral types. //====================================================================== //====================================================================== // Addition of two instances of this class. //====================================================================== BQBLargeInteger operator +(const BQBLargeInteger & addend_a, const BQBLargeInteger & addend_b) { return BQBLargeInteger(addend_a) += addend_b; } //====================================================================== // Addition of an instance of the BQBLargeInteger class and a signed integer. //====================================================================== BQBLargeInteger operator +(const BQBLargeInteger & x_addend, int addend) { return x_addend + BQBLargeInteger(addend); } BQBLargeInteger operator +(int addend, const BQBLargeInteger & x_addend) { return x_addend + addend; } //====================================================================== // Addition of an instance of the BQBLargeInteger class and an unsigned integer. //====================================================================== BQBLargeInteger operator +(const BQBLargeInteger & x_addend, unsigned int addend) { return x_addend + BQBLargeInteger(addend); } BQBLargeInteger operator +(unsigned int addend, const BQBLargeInteger & x_addend) { return x_addend + addend; } //====================================================================== // operator - for integral types. //====================================================================== //====================================================================== // Subtraction of two instances of this class. //====================================================================== BQBLargeInteger operator -(const BQBLargeInteger & minuend, const BQBLargeInteger & subtrahend) { return BQBLargeInteger(minuend) -= subtrahend; } //====================================================================== // Subtraction with an instance of the BQBLargeInteger class and a signed integer. //====================================================================== BQBLargeInteger operator -(const BQBLargeInteger & minuend, int subtrahend) { return minuend - BQBLargeInteger(subtrahend); } BQBLargeInteger operator -(int minuend, const BQBLargeInteger & subtrahend) { return BQBLargeInteger(minuend) - subtrahend; } //====================================================================== // Subtraction with an instance of the BQBLargeInteger class and an unsigned integer. //====================================================================== BQBLargeInteger operator -(const BQBLargeInteger & minuend, unsigned int subtrahend) { return minuend - BQBLargeInteger(subtrahend); } BQBLargeInteger operator -(unsigned int minuend, const BQBLargeInteger & subtrahend) { return BQBLargeInteger(minuend) - subtrahend; } //====================================================================== // operator * for integral types. //====================================================================== //====================================================================== // Multiplication of two instances of this class. //====================================================================== BQBLargeInteger operator *(const BQBLargeInteger & multiplier_a, const BQBLargeInteger & multiplier_b) { return BQBLargeInteger(multiplier_a) *= multiplier_b; } //====================================================================== // Multiplication of an instance of the BQBLargeInteger class and a signed integer. //====================================================================== BQBLargeInteger operator *(const BQBLargeInteger & x_multiplier, int multiplier) { return x_multiplier * BQBLargeInteger(multiplier); } BQBLargeInteger operator *(int multiplier, const BQBLargeInteger & x_multiplier) { return x_multiplier * multiplier; } //====================================================================== // Multiplication of an instance of the BQBLargeInteger class and an unsigned integer. //====================================================================== BQBLargeInteger operator *(const BQBLargeInteger & x_multiplier, unsigned int multiplier) { return x_multiplier * BQBLargeInteger(multiplier); } BQBLargeInteger operator *(unsigned int multiplier, const BQBLargeInteger & x_multiplier) { return x_multiplier * multiplier; } //====================================================================== // operator / for integral types. //====================================================================== //====================================================================== // Division of two instances of this class. //====================================================================== BQBLargeInteger operator /(const BQBLargeInteger & x_dividend, const BQBLargeInteger & x_denominator) { return BQBLargeInteger(x_dividend) /= x_denominator; } //====================================================================== // Division with an instance of the BQBLargeInteger class and a signed integer. //====================================================================== BQBLargeInteger operator /(const BQBLargeInteger & x_dividend, int divisor) { return x_dividend / BQBLargeInteger(divisor); } BQBLargeInteger operator /(int dividend, const BQBLargeInteger & x_denominator) { return BQBLargeInteger(dividend) / x_denominator; } //====================================================================== // Division with an instance of the BQBLargeInteger class and an unsigned integer. //====================================================================== BQBLargeInteger operator /(const BQBLargeInteger & x_dividend, unsigned int divisor) { return x_dividend / BQBLargeInteger(divisor); } BQBLargeInteger operator /(unsigned int dividend, const BQBLargeInteger & x_denominator) { return BQBLargeInteger(dividend) / x_denominator; } //====================================================================== // operator << for integral types. //====================================================================== //====================================================================== // Left shift of two instances of this class. //====================================================================== BQBLargeInteger operator <<(const BQBLargeInteger & value, const BQBLargeInteger & x_shift_count) { return BQBLargeInteger(value) <<= x_shift_count; } //====================================================================== // Left shift with an instance of the BQBLargeInteger class and a signed integer. //====================================================================== BQBLargeInteger operator <<(const BQBLargeInteger & value, int shift_count) { return value << BQBLargeInteger(shift_count); } BQBLargeInteger operator <<(int value, const BQBLargeInteger & x_shift_count) { return BQBLargeInteger(value) << x_shift_count; } //====================================================================== // Left shift with an instance of the BQBLargeInteger class and an unsigned integer. //====================================================================== BQBLargeInteger operator <<(const BQBLargeInteger & value, unsigned int shift_count) { return value << BQBLargeInteger(shift_count); } BQBLargeInteger operator <<(unsigned int value, const BQBLargeInteger & x_shift_count) { return BQBLargeInteger(value) << x_shift_count; } //====================================================================== // operator >> for integral types. //====================================================================== //====================================================================== // Right shift of two instances of this class. //====================================================================== BQBLargeInteger operator >>(const BQBLargeInteger & value, const BQBLargeInteger & x_shift_count) { return BQBLargeInteger(value) >>= x_shift_count; } //====================================================================== // Right shift with an instance of the BQBLargeInteger class and a signed integer. //====================================================================== BQBLargeInteger operator >>(const BQBLargeInteger & value, int shift_count) { return value >> BQBLargeInteger(shift_count); } BQBLargeInteger operator >>(int value, const BQBLargeInteger & x_shift_count) { return BQBLargeInteger(value) >> x_shift_count; } //====================================================================== // Right shift with an instance of the BQBLargeInteger class and an unsigned integer. //====================================================================== BQBLargeInteger operator >>(const BQBLargeInteger & value, unsigned int shift_count) { return value >> BQBLargeInteger(shift_count); } BQBLargeInteger operator >>(unsigned int value, const BQBLargeInteger & x_shift_count) { return BQBLargeInteger(value) >> x_shift_count; } //====================================================================== // operator % for integral types. //====================================================================== //====================================================================== // Modulus operator with two instances of this class. //====================================================================== BQBLargeInteger operator %(const BQBLargeInteger & x_dividend, const BQBLargeInteger & x_denominator) { return BQBLargeInteger(x_dividend) %= x_denominator; } //====================================================================== // Modulus operator with an instance of the BQBLargeInteger class and a signed integer. //====================================================================== BQBLargeInteger operator %(const BQBLargeInteger & x_dividend, int divisor) { return x_dividend % BQBLargeInteger(divisor); } BQBLargeInteger operator %(int dividend, const BQBLargeInteger & x_denominator) { return BQBLargeInteger(dividend) % x_denominator; } //====================================================================== // Modulus operator with an instance of the BQBLargeInteger class and an unsigned integer. //====================================================================== BQBLargeInteger operator %(const BQBLargeInteger & x_dividend, unsigned int divisor) { return x_dividend % BQBLargeInteger(divisor); } BQBLargeInteger operator %(unsigned int dividend, const BQBLargeInteger & x_denominator) { return BQBLargeInteger(dividend) % x_denominator; } //====================================================================== // operator ^ for integral types. //====================================================================== //====================================================================== // Bitwise Exclusive OR of two instances of this class. //====================================================================== BQBLargeInteger operator ^(const BQBLargeInteger & value_a, const BQBLargeInteger & value_b) { return BQBLargeInteger(value_a) ^= value_b; } //====================================================================== // Bitwise Exclusive OR of an instance of the BQBLargeInteger class and a signed integer. //====================================================================== BQBLargeInteger operator ^(const BQBLargeInteger & x_value, int value) { return x_value % BQBLargeInteger(value); } BQBLargeInteger operator ^(int value, const BQBLargeInteger & x_value) { return x_value % value; } //====================================================================== // Bitwise Exclusive OR of an instance of the BQBLargeInteger class and an unsigned integer. //====================================================================== BQBLargeInteger operator ^(const BQBLargeInteger & x_value, unsigned int value) { return x_value % BQBLargeInteger(value); } BQBLargeInteger operator ^(unsigned int value, const BQBLargeInteger & x_value) { return x_value % value; } //====================================================================== // operator & for integral types. //====================================================================== //====================================================================== // Bitwise AND of two instances of this class. //====================================================================== BQBLargeInteger operator &(const BQBLargeInteger & value_a, const BQBLargeInteger & value_b) { return BQBLargeInteger(value_a) &= value_b; } //====================================================================== // Bitwise AND of an instance of the BQBLargeInteger class and a signed integer. //====================================================================== BQBLargeInteger operator &(const BQBLargeInteger & x_value, int value) { return x_value & BQBLargeInteger(value); } BQBLargeInteger operator &(int value, const BQBLargeInteger & x_value) { return x_value & value; } //====================================================================== // Bitwise AND of an instance of the BQBLargeInteger class and an unsigned integer. //====================================================================== BQBLargeInteger operator &(const BQBLargeInteger & x_value, unsigned int value) { return x_value & BQBLargeInteger(value); } BQBLargeInteger operator &(unsigned int value, const BQBLargeInteger & x_value) { return x_value & value; } //====================================================================== // operator | for integral types. //====================================================================== //====================================================================== // Bitwise OR of two instances of this class. //====================================================================== BQBLargeInteger operator |(const BQBLargeInteger & value_a, const BQBLargeInteger & value_b) { return BQBLargeInteger(value_a) |= value_b; } //====================================================================== // Bitwise OR of an instance of the BQBLargeInteger class and a signed integer. //====================================================================== BQBLargeInteger operator |(const BQBLargeInteger & x_value, int value) { return x_value | BQBLargeInteger(value); } BQBLargeInteger operator |(int value, const BQBLargeInteger & x_value) { return x_value | value; } //====================================================================== // Bitwise OR of an instance of the BQBLargeInteger class and an unsigned integer. //====================================================================== BQBLargeInteger operator |(const BQBLargeInteger & x_value, unsigned int value) { return x_value | BQBLargeInteger(value); } BQBLargeInteger operator |(unsigned int value, const BQBLargeInteger & x_value) { return x_value | value; } void BQBLargeInteger::SelfTest() { // This hex number contains 1024 'f' digits. const char * pszNumber = "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"; BQBLargeInteger xMultiplier0; xMultiplier0.SetDefaultBase(16); xMultiplier0 = pszNumber; // Another way to set the value is: //xMultiplier0.SetValue(pszNumber, 16); BQBLargeInteger xMultiplier1 = xMultiplier0; // Time raising the 1024 digit hex number to the 11th power // by doing ten multiplications. This is not an efficient way // to raise a number to a power, but this is to time the // multiplication code. //DWORD dwStartTime = GetTickCount(); BQBLargeInteger xProduct; BQBLargeInteger xBitTest; int i = 0; for (i = 0; i < 10; ++i) { xProduct = xMultiplier0 * xMultiplier1; } //DWORD dwStopTime = GetTickCount(); //DWORD dwElapsedTime = dwStopTime - dwStartTime; //std::cout << "Time = " << dwElapsedTime << " milliseconds. " << std::endl; std::cout << "Product = " << std::hex << xProduct << std::endl; //------------------------------------------------------------------ // Test the large unsigned integer. //------------------------------------------------------------------ xMultiplier0 = 0xFFFFFFFF; xMultiplier1 = 0xFFFFFFFF; xProduct = xMultiplier0 * xMultiplier1; std::cout << "Product = " << std::hex << xProduct << std::endl; // Negative number tests xMultiplier0 = -2; xMultiplier1 = 2; xProduct = xMultiplier0 * xMultiplier1; std::cout << "Product = " << std::hex << xProduct << std::endl; BQBLargeInteger xDividend = BQBLargeInteger(-16); BQBLargeInteger xDivisor = BQBLargeInteger(4); BQBLargeInteger xQuotient = xDividend / xDivisor; std::cout << "Quotient = " << std::hex << xQuotient << std::endl; xQuotient <<= 1; std::cout << "Quotient <<= 1 = " << std::hex << xQuotient << std::endl; xQuotient <<= 1; std::cout << "Quotient <<= 1 = " << std::hex << xQuotient << std::endl; xQuotient <<= 1; std::cout << "Quotient <<= 1 = " << std::hex << xQuotient << std::endl; xQuotient <<= 2; std::cout << "Quotient <<= 2 = " << std::hex << xQuotient << std::endl; xQuotient >>= 1; std::cout << "Quotient >>= 1 = " << std::hex << xQuotient << std::endl; xQuotient >>= 1; std::cout << "Quotient >>= 1 = " << std::hex << xQuotient << std::endl; xQuotient >>= 1; std::cout << "Quotient >>= 1 = " << std::hex << xQuotient << std::endl; xQuotient >>= 1; std::cout << "Quotient >>= 1 = " << std::hex << xQuotient << std::endl; xQuotient >>= 1; std::cout << "Quotient >>= 1 = " << std::hex << xQuotient << std::endl; xQuotient >>= 1; std::cout << "Quotient >>= 1 " << std::hex << xQuotient << std::endl; // A trivial comparison test. BQBLargeInteger xA = BQBLargeInteger(6); BQBLargeInteger xB = BQBLargeInteger(10); if (xA <= xB) { std::cout << "xA <= xB " << std::dec << xA << " <= " << xB << std::endl; } // Shift tests BQBLargeInteger x_value = BQBLargeInteger(1); for (i = 0; i < 256; i++) { x_value <<= 1; std::cout << std::dec << x_value << std::endl; std::cout << std::hex << x_value << std::endl; } for (i = 0; i < 256; i++) { x_value >>= 1; std::cout << std::dec << x_value << std::endl; std::cout << std::hex << x_value << std::endl; } // Another comparison test. if (x_value == 0) { std::cout << x_value << " == 0 Failure" << std::endl; } else { std::cout << x_value << " != 0 Success" << std::endl; } // More number tests. xBitTest.SetValue("FFFFFFFF", 16); unsigned int uiLeadingBitPosition = xBitTest.LeadingBitPosition(); std::cout << "Leading Bit Position = " << uiLeadingBitPosition << std::endl; xBitTest.SetValue("FFFFFFFF", 16); std::cout << "Population Count = " << xBitTest.PopulationCount() << std::endl; xBitTest.SetValue("FFFFFFEF", 16); std::cout << "Population Count = " << xBitTest.PopulationCount() << std::endl; xBitTest.SetValue("FFFFFFCF", 16); std::cout << "Population Count = " << xBitTest.PopulationCount() << std::endl; xBitTest.SetValue("FFFFFF8F", 16); std::cout << "Population Count = " << xBitTest.PopulationCount() << std::endl; xBitTest.SetValue("0FFFFFFF", 16); std::cout << "Population Count = " << xBitTest.PopulationCount() << std::endl; xBitTest.SetValue("F0EFFFFF", 16); std::cout << "Population Count = " << xBitTest.PopulationCount() << std::endl; xBitTest.SetValue("1", 16); std::cout << "Population Count = " << xBitTest.PopulationCount() << std::endl; xBitTest.SetValue("49249249", 8); std::cout << "Octal Value = " << std::oct << xBitTest << std::endl; xBitTest.SetValue("49249249", 16); std::cout << "Hex Value = " << std::hex << xBitTest << std::endl; xBitTest.SetValue("24924924", 8); std::cout << "Octal Value = " << std::oct << xBitTest << std::endl; xBitTest.SetValue("24924924", 16); std::cout << "Hex Value = " << std::hex << xBitTest << std::endl; xBitTest.SetValue("1234567012", 8); std::cout << "Octal Value = " << std::oct << xBitTest << std::endl; xBitTest.SetValue("77777777777777777777777777777777", 8); std::cout << "Octal Value = " << std::oct << xBitTest << std::endl; xBitTest.SetValue("200", 8); xBitTest.SetValue("4294967296", 10); xBitTest.SetValue("777777777777777777777777777777", 8); xBitTest.SetValue("77", 8); xBitTest.SetValue("1234567890123456789", 10); xBitTest.SetValue("12345678901234567890123456789012345678901234567890123456789012345678901234567890987654321", 10); std::cout << "Decimal Value = " << std::dec << xBitTest << std::endl; xBitTest.SetValue("7", 8); std::cout << "Octal Value = " << std::oct << xBitTest << std::endl; xBitTest.SetValue("77", 8); std::cout << "Octal Value = " << std::oct << xBitTest << std::endl; xBitTest.SetValue("777", 8); std::cout << "Octal Value = " << std::oct << xBitTest << std::endl; xBitTest.SetValue("7777", 8); std::cout << "Octal Value = " << std::oct << xBitTest << std::endl; xBitTest.SetValue("77777", 8); std::cout << "Octal Value = " << std::oct << xBitTest << std::endl; xBitTest.SetValue("777777", 8); std::cout << "Octal Value = " << std::oct << xBitTest << std::endl; xBitTest.SetValue("7777777", 8); std::cout << "Octal Value = " << std::oct << xBitTest << std::endl; xBitTest.SetValue("77777777", 8); std::cout << "Octal Value = " << std::oct << xBitTest << std::endl; xBitTest.SetValue("777777777", 8); std::cout << "Octal Value = " << std::oct << xBitTest << std::endl; xBitTest.SetValue("7777777777", 8); std::cout << "Octal Value = " << std::oct << xBitTest << std::endl; xBitTest.SetValue("77777777777", 8); std::cout << "Octal Value = " << std::oct << xBitTest << std::endl; xBitTest.SetValue("777777777777", 8); std::cout << "Octal Value = " << std::oct << xBitTest << std::endl; xBitTest.SetValue("7777777777777", 8); std::cout << "Octal Value = " << std::oct << xBitTest << std::endl; xBitTest.SetValue("77777777777777", 8); std::cout << "Octal Value = " << std::oct << xBitTest << std::endl; xBitTest.SetValue("777777777777777", 8); std::cout << "Octal Value = " << std::oct << xBitTest << std::endl; xBitTest.SetValue("7777777777777777", 8); std::cout << "Octal Value = " << std::oct << xBitTest << std::endl; xBitTest.SetValue("77777777777777777", 8); std::cout << "Octal Value = " << std::oct << xBitTest << std::endl; xBitTest.SetValue("777777777777777777", 8); std::cout << "Octal Value = " << std::oct << xBitTest << std::endl; xBitTest.SetValue("7777777777777777777", 8); std::cout << "Octal Value = " << std::oct << xBitTest << std::endl; xBitTest.SetValue("77777777777777777777", 8); std::cout << "Octal Value = " << std::oct << xBitTest << std::endl; xBitTest.SetValue("777777777777777777777", 8); std::cout << "Octal Value = " << std::oct << xBitTest << std::endl; xBitTest.SetValue("12345670123456701234567654321", 8); std::cout << "Octal Value = " << std::oct << xBitTest << std::endl; xBitTest.SetValue("F", 16); std::cout << "Hex Value = " << std::hex << xBitTest << std::endl; xBitTest.SetValue("FF", 16); std::cout << "Hex Value = " << std::hex << xBitTest << std::endl; xBitTest.SetValue("FFF", 16); std::cout << "Hex Value = " << std::hex << xBitTest << std::endl; xBitTest.SetValue("FFFF", 16); std::cout << "Hex Value = " << std::hex << xBitTest << std::endl; xBitTest.SetValue("FFFFF", 16); std::cout << "Hex Value = " << std::hex << xBitTest << std::endl; xBitTest.SetValue("FFFFFF", 16); std::cout << "Hex Value = " << std::hex << xBitTest << std::endl; xBitTest.SetValue("FFFFFFF", 16); std::cout << "Hex Value = " << std::hex << xBitTest << std::endl; xBitTest.SetValue("FFFFFFFF", 16); std::cout << "Hex Value = " << std::hex << xBitTest << std::endl; xBitTest.SetValue("FFFFFFFFF", 16); std::cout << "Hex Value = " << std::hex << xBitTest << std::endl; xBitTest.SetValue("FFFFFFFFFF", 16); std::cout << "Hex Value = " << std::hex << xBitTest << std::endl; xBitTest.SetValue("FFFFFFFFFFF", 16); std::cout << "Hex Value = " << std::hex << xBitTest << std::endl; xBitTest.SetValue("FFFFFFFFFFFF", 16); std::cout << "Hex Value = " << std::hex << xBitTest << std::endl; xBitTest.SetValue("FFFFFFFFFFFFF", 16); std::cout << "Hex Value = " << std::hex << xBitTest << std::endl; xBitTest.SetValue("FFFFFFFFFFFFFF", 16); std::cout << "Hex Value = " << std::hex << xBitTest << std::endl; xBitTest.SetValue("FFFFFFFFFFFFFFF", 16); std::cout << "Hex Value = " << std::hex << xBitTest << std::endl; xBitTest.SetValue("FFFFFFFFFFFFFFFF", 16); std::cout << "Hex Value = " << std::hex << xBitTest << std::endl; xBitTest.SetValue("FFFFFFFFFFFFFFFFF", 16); std::cout << "Hex Value = " << std::hex << xBitTest << std::endl; xBitTest.SetValue("FFFFFFFFFFFFFFFFFF", 16); std::cout << "Hex Value = " << std::hex << xBitTest << std::endl; xBitTest.SetValue("FFFFFFFFFFFFFFFFFFF", 16); std::cout << "Hex Value = " << std::hex << xBitTest << std::endl; xBitTest.SetValue("FFFFFFFFFFFFFFFFFFFF", 16); std::cout << "Hex Value = " << std::hex << xBitTest << std::endl; xBitTest.SetValue("FFFFFFFFFFFFFFFFFFFFF", 16); std::cout << "Hex Value = " << std::hex << xBitTest << std::endl; xBitTest.SetValue("123456789ABCDEF0123456789abcdef0123456789abcdefedcba987654321", 16); std::cout << "Hex Value = " << std::hex << xBitTest << std::endl; std::cout << "Decimal Value = " << std::dec << xBitTest << std::endl; xBitTest.SetValue("1", 10); xBitTest = xBitTest << 65535; xBitTest--; std::cout << "((1 << 65536) - 1) in base 10 = " << std::dec << xBitTest << std::endl; std::cout << "((1 << 65536) - 1) in base 8 = " << std::oct << xBitTest << std::endl; std::cout << "((1 << 65536) - 1) in base 16 = " << std::hex << xBitTest << std::endl; BQBLargeInteger x_value_0; BQBLargeInteger x_value_1; x_value_0.SetValue("1", 10); x_value_1.SetValue("1", 10); BQBLargeInteger x_result = x_value_0 + x_value_1; std::cout << x_value_0 << " + " << x_value_1 << " = " << x_result << std::endl; x_value_0.SetValue("1", 10); x_value_1.SetValue("-2", 10); x_result = x_value_0 + x_value_1; std::cout << x_value_0 << " + " << x_value_1 << " = " << x_result << std::endl; x_value_0.SetValue("-2", 10); x_value_1.SetValue("1", 10); x_result = x_value_0 + x_value_1; std::cout << x_value_0 << " + " << x_value_1 << " = " << x_result << std::endl; x_value_0.SetValue("-2", 10); x_value_1.SetValue("-1", 10); x_result = x_value_0 + x_value_1; std::cout << x_value_0 << " + " << x_value_1 << " = " << x_result << std::endl; x_value_0.SetValue("-2", 10); x_value_1.SetValue("-1", 10); x_result = x_value_0 + x_value_1; std::cout << x_value_0 << " + " << x_value_1 << " = " << x_result << std::endl; x_value_0.SetValue("1", 10); x_value_1.SetValue("2", 10); x_result = x_value_0 - x_value_1; std::cout << x_value_0 << " - " << x_value_1 << " = " << x_result << std::endl; x_value_0.SetValue("1", 10); x_value_1.SetValue("-2", 10); x_result = x_value_0 - x_value_1; std::cout << x_value_0 << " - " << x_value_1 << " = " << x_result << std::endl; x_value_0.SetValue("-1", 10); x_value_1.SetValue("2", 10); x_result = x_value_0 - x_value_1; std::cout << x_value_0 << " - " << x_value_1 << " = " << x_result << std::endl; x_value_0.SetValue("-1", 10); x_value_1.SetValue("-2", 10); x_result = x_value_0 - x_value_1; std::cout << x_value_0 << " - " << x_value_1 << " = " << x_result << std::endl; x_value_0.SetValue("10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", 10); x_result = x_value_0 + 1; std::cout << x_value_0 << " + 1 = " << x_result << std::endl; x_result = x_value_0 - 1; std::cout << x_value_0 << " - 1 = " << x_result << std::endl; x_value_1 = x_value_0 - x_result; std::cout << x_value_0 << " - " << x_result << " = " << x_value_1 << std::endl; x_value_0.SetValue("10", 10); x_value_1 = x_value_0; x_result = x_value_0 * x_value_1; std::cout << x_result << " = " << x_value_0 << " * " << x_value_1 << std::endl; x_value_0.SetValue("1000000000000000", 10); std::cout << "x_value_0 = " << x_value_0 << std::endl; x_value_1 = x_value_0; x_result = x_value_0 * x_value_1; std::cout << x_result << " = " << x_value_0 << " * " << x_value_1 << std::endl; x_value_0.SetValue("1000000", 10); std::cout << x_value_0 << " = " << x_value_0 << std::endl; x_value_0.SetValue("100000000000000000000000", 10); x_value_1 = x_value_0; x_result = x_value_0 * x_value_1; std::cout << x_result << " = " << x_value_0 << " * " << x_value_1 << std::endl; xDividend.SetValue("1048576", 10); xDivisor.SetValue("1024", 10); xQuotient = xDividend / xDivisor; std::cout << xDividend << " / " << xDivisor << " = " << xQuotient << std::endl; } void BQBLargeInteger::mprintf(unsigned int base) { std::string s; GetNumberString(s,base); ::printf("%s",s.c_str()); } void BQBLargeInteger::mfprintf(FILE *a, unsigned int base) { std::string s; GetNumberString(s,base); ::fprintf(a,"%s",s.c_str()); } const char* BQBLargeInteger::string() const { if (*this != 0) GetNumberString(g_sBQBLIString,10); else g_sBQBLIString = "0"; return g_sBQBLIString.c_str(); } const char* BQBLargeInteger::string2() const { if (*this != 0) GetNumberString(g_sBQBLIString2,10); else g_sBQBLIString2 = "0"; return g_sBQBLIString2.c_str(); } const char* BQBLargeInteger::string3() const { if (*this != 0) GetNumberString(g_sBQBLIString3,10); else g_sBQBLIString3 = "0"; return g_sBQBLIString3.c_str(); } travis-src-190101/src/bqb_largeinteger.h0100777000000000000000000011221013412725664015105 0ustar00/*********************************************************************************** LibBQB - File Format and Compression Algorithms for Trajectories of Volumetric Data and Atom Positions https://brehm-research.de/bqb Free software, licensed under GNU LGPL v3 Copyright (c) Martin Brehm and Martin Thomas, Martin Luther University Halle-Wittenberg, Germany, 2016 - 2019. Please cite: M. Brehm, M. Thomas: "An Efficient Lossless Compression Algorithm for Trajectories of Atom Positions and Volumetric Data", J. Chem. Inf. Model. 2018, 58 (10), pp 2092-2107. -------------------------------------------------------------------------------- LibBQB is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program. If not, see . ***********************************************************************************/ //======================================================================= // Copyright (C) 1998-2013 William Hallahan // // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without restriction, // including without limitation the rights to use, copy, modify, merge, // publish, distribute, sublicense, and/or sell copies of the Software, // and to permit persons to whom the Software is furnished to do so, // subject to the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES // OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, // WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR // OTHER DEALINGS IN THE SOFTWARE. //======================================================================= //====================================================================== // Class Definition File: BQBLargeInteger.h // Author: Bill Hallahan // Date: March 11, 1998 // // Abstract: // // This file contains the definition for class BQBLargeInteger. // An instance of BQBLargeInteger can be used to store and calculate // integer values with a huge number of digits. The internal data // format is a both a boolean value named m_negative_flag that that // stores the sign of the number, and an array of integers that // contains a positive binary value. The maximum number of integers // that can be contained in the internal array is limited to the // maximum signed value which can be stored in an integer, The // maximum number of digits that can be used for octal and hexadecimal // input, and output, is equal to the the maximum value that can be // stored in a signed integer. The input and output conversion // methods for decimal numbers supports up to 19,346,699 digits or // almost 20 million decimal digits. This implementation only works // on little-endian machines. // // How To Use This Class // // Except for the the caveats given below, 'BQBLargeInteger' can be // used as if were a built-in data type. // // There are certain unavoidable differences which are documented // here: // // - This module should be compiled with overflow checking disabled. // This class grows the array that stores the binary number so // that overflows cannot occur. // // - The compiler will not allow large integer types to be the // integer argument in a 'switch' statement. The large integer // must be cast to an built-in type. // // - Instances of this class cannot be used to index simple arrays. // If an instance of this class must be used as an index for an // array then it should be cast to a built-in type. // // - Shift values for the left and right shift operators are limited // to the maximum value that fits in an unsigned integer. If the // shift value is larger than this then the shifted large integer // is set to the value zero. Note that the internal format does // not use two's complement arithmetic so that shifted values // maintain the same sign as the original value. // // - Literals with unlimited bit-length are not supported by any // compiler. To initialize a large integer use a constructor, // an equals operator, SetBinaryValue() method, or one of the // overloaded SetValue() methods. // //====================================================================== #ifndef BQB_LARGEINTEGER_H #define BQB_LARGEINTEGER_H //====================================================================== // Include files. //====================================================================== // This must always be the first include directive #include "bqb_config.h" #include #include //#include extern std::string g_sBQBLIString; extern std::string g_sBQBLIString2; extern std::string g_sBQBLIString3; //====================================================================== // BQBLargeIntegerException class for errors. //====================================================================== /* class BQBLargeIntegerException : public std::exception { public: BQBLargeIntegerException(const char * exception_text) : std::exception(exception_text) { } ~BQBLargeIntegerException() throw() { } };*/ //====================================================================== // Class definition for class BQBLargeInteger. //====================================================================== class BQBLargeInteger { private: //================================================================== // Data members. //================================================================== unsigned int m_array_length; unsigned int m_integer_length; unsigned int m_default_base; unsigned int * m_array_ptr; bool m_negative_flag; public: static void SelfTest(); void mprintf(unsigned int base); void mfprintf(FILE *a, unsigned int base); //================================================================== // istream operator for input. //================================================================== friend std::istream & operator >>(std::istream & is, BQBLargeInteger & value); //================================================================== // ostream operator for output. //================================================================== friend std::ostream & operator <<(std::ostream & os, const BQBLargeInteger & value); //================================================================== // Constructors //================================================================== BQBLargeInteger(); //================================================================== // Copy constructor //================================================================== BQBLargeInteger(const BQBLargeInteger & value); //================================================================== // Conversion constructors. //================================================================== explicit BQBLargeInteger(long value); explicit BQBLargeInteger(unsigned long value); explicit BQBLargeInteger(int value); explicit BQBLargeInteger(unsigned int value); explicit BQBLargeInteger(const char * psznumber_ptr); //================================================================== // Special constructor to allow initializing using a binary array. //================================================================== BQBLargeInteger(const char * binary_data_ptr, unsigned int length); //================================================================== // Destructor //================================================================== virtual ~BQBLargeInteger(); //====================================================================== // Method: BQBLargeInteger::SetDefaultBase // // The default base is the value used for the constructor and operator // equals methods that take only a string pointer for a number. //====================================================================== void SetDefaultBase(unsigned int default_base); //================================================================== // This method allows getting this large integer's binary value. // The binary value is a positive number in little endian format. // The buffer that is passed must be large enough to contain the // number. This method can be called passing a null pointer for // the buffer to just obtain the buffer length in bytes. //================================================================== unsigned int GetBinaryValue(unsigned char * binary_data_ptr = 0) const; //================================================================== // This method allows setting this large integer's binary value. // The binary value is a positive number in little endian format. // The buffer that is passed must be large enough to contain the // number. This method can be called passing a null pointer for // the buffer to just obtain the buffer length in bytes. //================================================================== void SetBinaryValue(const char * binary_data_ptr, unsigned int length); //================================================================== // Get this large integer value represented in an stl string. //================================================================== void GetNumberString(std::string & number_string, unsigned int base) const; //================================================================== // Set this large integer value using the number in a character // string. //================================================================== bool SetValue(const char * number_ptr, unsigned int base); //================================================================== // This method returns the position of the leading bit in this // large integer. //================================================================== unsigned int LeadingBitPosition() const; //================================================================== // Return the count of the number of bits set in this large // integer. //================================================================== unsigned int PopulationCount() const; //================================================================== // operator = for integral types. //================================================================== BQBLargeInteger operator =(const BQBLargeInteger & value); BQBLargeInteger operator =(long value); BQBLargeInteger operator =(unsigned long value); BQBLargeInteger operator =(int value); BQBLargeInteger operator =(unsigned int value); BQBLargeInteger operator =(const char * psznumber_ptr); //================================================================== // Unary operator + for integral types. //================================================================== BQBLargeInteger operator +=(const BQBLargeInteger & addend); BQBLargeInteger operator +=(long addend); BQBLargeInteger operator +=(unsigned long addend); BQBLargeInteger operator +=(int addend); BQBLargeInteger operator +=(unsigned int addend); //================================================================== // Unary operator - for integral types. //================================================================== BQBLargeInteger operator -=(const BQBLargeInteger & subtrahend); BQBLargeInteger operator -=(long subtrahend); BQBLargeInteger operator -=(unsigned long subtrahend); BQBLargeInteger operator -=(int subtrahend); BQBLargeInteger operator -=(unsigned int subtrahend); //================================================================== // Unary operator * for integral types. //================================================================== BQBLargeInteger operator *=(const BQBLargeInteger & multiplier); protected: void AccumulateWithCarry(BQBLargeInteger & product, int index, unsigned int value); public: BQBLargeInteger operator *=(long multiplier); BQBLargeInteger operator *=(unsigned long multiplier); BQBLargeInteger operator *=(int multiplier); BQBLargeInteger operator *=(unsigned int multiplier); //================================================================== // Unary operator / for integral types. //================================================================== BQBLargeInteger operator /=(const BQBLargeInteger & divisor); BQBLargeInteger operator /=(long divisor); BQBLargeInteger operator /=(unsigned long divisor); BQBLargeInteger operator /=(int divisor); BQBLargeInteger operator /=(unsigned int divisor); //================================================================== // operator <<= for integral types. //================================================================== BQBLargeInteger operator <<=(const BQBLargeInteger & shift_count); BQBLargeInteger operator <<=(long shift_count); BQBLargeInteger operator <<=(unsigned long shift_count); BQBLargeInteger operator <<=(int shift_count); BQBLargeInteger operator <<=(unsigned int shift_count); //================================================================== // operator >>= for integral types. //================================================================== BQBLargeInteger operator >>=(const BQBLargeInteger & shift_count); BQBLargeInteger operator >>=(long shift_count); BQBLargeInteger operator >>=(unsigned long shift_count); BQBLargeInteger operator >>=(int shift_count); BQBLargeInteger operator >>=(unsigned int shift_count); //================================================================== // Unary operator %= for integral types. //================================================================== BQBLargeInteger operator %=(const BQBLargeInteger & divisor); BQBLargeInteger operator %=(long divisor); BQBLargeInteger operator %=(unsigned long divisor); BQBLargeInteger operator %=(int divisor); BQBLargeInteger operator %=(unsigned int divisor); //================================================================== // operator ^= for integral types. //================================================================== BQBLargeInteger operator ^=(const BQBLargeInteger & value); BQBLargeInteger operator ^=(long value); BQBLargeInteger operator ^=(unsigned long value); BQBLargeInteger operator ^=(int value); BQBLargeInteger operator ^=(unsigned int value); //================================================================== // operator &= for integral types. //================================================================== BQBLargeInteger operator &=(const BQBLargeInteger & value); BQBLargeInteger operator &=(unsigned long value); BQBLargeInteger operator &=(int value); BQBLargeInteger operator &=(unsigned int value); //================================================================== // operator |= for integral types. //================================================================== BQBLargeInteger operator |=(const BQBLargeInteger & value); BQBLargeInteger operator |=(long value); BQBLargeInteger operator |=(unsigned long value); BQBLargeInteger operator |=(int value); BQBLargeInteger operator |=(unsigned int value); //================================================================== // Unary operators. The unary * operator and the unary & operator // do not need to be overloaded. //================================================================== BQBLargeInteger operator !(); BQBLargeInteger operator ~(); BQBLargeInteger operator +(); BQBLargeInteger operator -(); //================================================================== // The prefix form of the increment and decrement operators. //================================================================== const BQBLargeInteger operator ++(); const BQBLargeInteger operator --(); //================================================================== // The postfix form of the increment and decrement operators. //================================================================== const BQBLargeInteger operator ++(int); const BQBLargeInteger operator --(int); //================================================================== // Unary operator == for integral types. //================================================================== bool operator ==(const BQBLargeInteger & value) const; bool operator ==(long value) const; bool operator ==(unsigned long value) const; bool operator ==(int value) const; bool operator ==(unsigned int value) const; //================================================================== // Unary operator != for integral types. //================================================================== bool operator !=(const BQBLargeInteger & value) const; bool operator !=(long value) const; bool operator !=(unsigned long value) const; bool operator !=(int value) const; bool operator !=(unsigned int value) const; //================================================================== // Unary operator < for integral types. //================================================================== bool operator <(const BQBLargeInteger & value) const; bool operator <(long value) const; bool operator <(unsigned long value) const; bool operator <(int value) const; bool operator <(unsigned int value) const; //================================================================== // Unary operator > for integral types. //================================================================== bool operator >(const BQBLargeInteger & value) const; bool operator >(long value) const; bool operator >(unsigned long value) const; bool operator >(int value) const; bool operator >(unsigned int value) const; //================================================================== // Unary operator <= for integral types. //================================================================== bool operator <=(const BQBLargeInteger & value) const; bool operator <=(long value) const; bool operator <=(unsigned long value) const; bool operator <=(int value) const; bool operator <=(unsigned int value) const; //================================================================== // Unary operator >= for integral types. //================================================================== bool operator >=(const BQBLargeInteger & value) const; bool operator >=(long value) const; bool operator >=(unsigned long value) const; bool operator >=(int value) const; bool operator >=(unsigned int value) const; //================================================================== // Cast conversion operators. //================================================================== operator long() const; operator unsigned long() const; operator int() const; operator unsigned int() const; operator short() const; operator unsigned short() const; operator char() const; operator unsigned char() const; operator bool() const; operator float() const; operator double() const; operator long double() const; #ifdef _DEBUG void DebugDump(const char * pszText = 0); #endif const char* string() const; const char* string2() const; const char* string3() const; private: //================================================================== // The following operators are not declared. The default // behavior of these operators is the desired behavior. // // operator () // operator [] // operator new // operator new[] // operator delete // operator delete[] // operator , // operator ->*() const; // operator &&() // operator ||() // // The following unary operators are not declared. The default // behavior of these operators is the desired behavior. // // operator *() // operator &() // //================================================================== //================================================================== // Private member functions. //================================================================== void Copy(const BQBLargeInteger & that); void AddPositiveArray(const BQBLargeInteger & addend); bool SubtractPositiveArray(const BQBLargeInteger & subtrahend); void ShiftLeft(unsigned int shift_count); void ShiftRight(unsigned int shift_count); bool IsZero() const; bool IsNegative() const; bool FitsIn32Bits() const; void SetIntegerLength(unsigned int integer_length, bool copy_data_flag = false); void SetToZero(); unsigned int GetSafeArrayValue(unsigned int iIndex) const; void Normalize(); bool LessThanPositiveArrayCompare(const BQBLargeInteger & value_0, const BQBLargeInteger & value_1) const; unsigned int PopulationCount32Bit(unsigned int value) const; void GetBase8NumberString(std::string & number_string) const; void GetBase8Digits(std::string & base8_digits_string) const; void GetBase10NumberString(std::string & number_string) const; void GetBase16NumberString(std::string & number_string) const; void StripLeadingZeroDigits(std::string & number_string, char zero_digit) const; bool SetValueWithBase8String(const char * digits_ptr); void SetValueWithBase8DigitValues(const std::string & base8_digit_string); bool SetValueWithBase10String(const char * digits_ptr); bool ConvertDecimalStringToOctalDigits(const char * decimal_digits_ptr, std::string & digits_string) const; bool SetValueWithBase16String(const char * digits_ptr); void SetValueWithBase16DigitValues(const std::string & base16_digit_values_string); }; //====================================================================== // Global function declarations. //====================================================================== //====================================================================== // operator + for integral types. //====================================================================== //====================================================================== // Addition of two instances of this class. //====================================================================== BQBLargeInteger operator +(const BQBLargeInteger & addend_a, const BQBLargeInteger & addend_b); //====================================================================== // Addition of an instance of the BQBLargeInteger class and a signed integer. //====================================================================== BQBLargeInteger operator +(const BQBLargeInteger & x_addend, int addend); BQBLargeInteger operator +(int addend, const BQBLargeInteger & x_addend); //====================================================================== // Addition of an instance of the BQBLargeInteger class and an unsigned integer. //====================================================================== BQBLargeInteger operator +(const BQBLargeInteger & x_addend, unsigned int addend); BQBLargeInteger operator +(unsigned int addend, const BQBLargeInteger & x_addend); //====================================================================== // operator - for integral types. //====================================================================== //====================================================================== // Subtraction of two instances of this class. //====================================================================== BQBLargeInteger operator -(const BQBLargeInteger & minuend, const BQBLargeInteger & subtrahend); //====================================================================== // Subtraction with an instance of the BQBLargeInteger class and a signed integer. //====================================================================== BQBLargeInteger operator -(const BQBLargeInteger & minuend, int subtrahend); BQBLargeInteger operator -(int minuend, const BQBLargeInteger & subtrahend); //====================================================================== // Subtraction with an instance of the BQBLargeInteger class and an unsigned integer. //====================================================================== BQBLargeInteger operator -(const BQBLargeInteger & minuend, unsigned int subtrahend); BQBLargeInteger operator -(unsigned int minuend, const BQBLargeInteger & subtrahend); //====================================================================== // operator * for integral types. //====================================================================== //====================================================================== // Multiplication of two instances of this class. //====================================================================== BQBLargeInteger operator *(const BQBLargeInteger & multiplier_a, const BQBLargeInteger & multiplier_b); //====================================================================== // Multiplication of an instance of the BQBLargeInteger class and a signed integer. //====================================================================== BQBLargeInteger operator *(const BQBLargeInteger & x_multiplier, int multiplier); BQBLargeInteger operator *(int multiplier, const BQBLargeInteger & x_multiplier); //====================================================================== // Multiplication of an instance of the BQBLargeInteger class and an unsigned integer. //====================================================================== BQBLargeInteger operator *(const BQBLargeInteger & x_multiplier, unsigned int multiplier); BQBLargeInteger operator *(unsigned int multiplier, const BQBLargeInteger & x_multiplier); //====================================================================== // operator / for integral types. //====================================================================== //====================================================================== // Division of two instances of this class. //====================================================================== BQBLargeInteger operator /(const BQBLargeInteger & x_dividend, const BQBLargeInteger & x_denominator); //====================================================================== // Division with an instance of the BQBLargeInteger class and a signed integer. //====================================================================== BQBLargeInteger operator /(const BQBLargeInteger & x_dividend, int divisor); BQBLargeInteger operator /(int dividend, const BQBLargeInteger & x_denominator); //====================================================================== // Division with an instance of the BQBLargeInteger class and an unsigned integer. //====================================================================== BQBLargeInteger operator /(const BQBLargeInteger & x_dividend, unsigned int divisor); BQBLargeInteger operator /(unsigned int dividend, const BQBLargeInteger & x_denominator); //====================================================================== // operator << for integral types. //====================================================================== //====================================================================== // Left shift of two instances of this class. //====================================================================== BQBLargeInteger operator <<(const BQBLargeInteger & value, const BQBLargeInteger & x_shift_count); //====================================================================== // Left shift with an instance of the BQBLargeInteger class and a signed integer. //====================================================================== BQBLargeInteger operator <<(const BQBLargeInteger & value, int shift_count); BQBLargeInteger operator <<(int value, const BQBLargeInteger & x_shift_count); //====================================================================== // Left shift with an instance of the BQBLargeInteger class and an unsigned integer. //====================================================================== BQBLargeInteger operator <<(const BQBLargeInteger & value, unsigned int shift_count); BQBLargeInteger operator <<(unsigned int value, const BQBLargeInteger & x_shift_count); //====================================================================== // operator >> for integral types. //====================================================================== //====================================================================== // Right shift of two instances of this class. //====================================================================== BQBLargeInteger operator >>(const BQBLargeInteger & value, const BQBLargeInteger & x_shift_count); //====================================================================== // Right shift with an instance of the BQBLargeInteger class and a signed integer. //====================================================================== BQBLargeInteger operator >>(const BQBLargeInteger & value, int shift_count); BQBLargeInteger operator >>(int value, const BQBLargeInteger & x_shift_count); //====================================================================== // Right shift with an instance of the BQBLargeInteger class and an unsigned integer. //====================================================================== BQBLargeInteger operator >>(const BQBLargeInteger & value, unsigned int shift_count); BQBLargeInteger operator >>(unsigned int value, const BQBLargeInteger & x_shift_count); //====================================================================== // operator % for integral types. //====================================================================== //====================================================================== // Modulus operator with two instances of this class. //====================================================================== BQBLargeInteger operator %(const BQBLargeInteger & x_dividend, const BQBLargeInteger & x_denominator); //====================================================================== // Modulus operator with an instance of the BQBLargeInteger class and a signed integer. //====================================================================== BQBLargeInteger operator %(const BQBLargeInteger & x_dividend, int divisor); BQBLargeInteger operator %(int dividend, const BQBLargeInteger & x_denominator); //====================================================================== // Modulus operator with an instance of the BQBLargeInteger class and an unsigned integer. //====================================================================== BQBLargeInteger operator %(const BQBLargeInteger & x_dividend, unsigned int divisor); BQBLargeInteger operator %(unsigned int dividend, const BQBLargeInteger & x_denominator); //====================================================================== // operator ^ for integral types. //====================================================================== //====================================================================== // Bitwise Exclusive OR of two instances of this class. //====================================================================== BQBLargeInteger operator ^(const BQBLargeInteger & value_a, const BQBLargeInteger & value_b); //====================================================================== // Bitwise Exclusive OR of an instance of the BQBLargeInteger class and a signed integer. //====================================================================== BQBLargeInteger operator ^(const BQBLargeInteger & x_value, int value); BQBLargeInteger operator ^(int value, const BQBLargeInteger & x_value); //====================================================================== // Bitwise Exclusive OR of an instance of the BQBLargeInteger class and an unsigned integer. //====================================================================== BQBLargeInteger operator ^(const BQBLargeInteger & x_value, unsigned int value); BQBLargeInteger operator ^(unsigned int value, const BQBLargeInteger & x_value); //====================================================================== // operator & for integral types. //====================================================================== //====================================================================== // Bitwise AND of two instances of this class. //====================================================================== BQBLargeInteger operator &(const BQBLargeInteger & value_a, const BQBLargeInteger & value_b); //====================================================================== // Bitwise AND of an instance of the BQBLargeInteger class and a signed integer. //====================================================================== BQBLargeInteger operator &(const BQBLargeInteger & x_value, int value); BQBLargeInteger operator &(int value, const BQBLargeInteger & x_value); //====================================================================== // Bitwise AND of an instance of the BQBLargeInteger class and an unsigned integer. //====================================================================== BQBLargeInteger operator &(const BQBLargeInteger & x_value, unsigned int value); BQBLargeInteger operator &(unsigned int value, const BQBLargeInteger & x_value); //====================================================================== // operator | for integral types. //====================================================================== //====================================================================== // Bitwise OR of two instances of this class. //====================================================================== BQBLargeInteger operator |(const BQBLargeInteger & value_a, const BQBLargeInteger & value_b); //====================================================================== // Bitwise OR of an instance of the BQBLargeInteger class and a signed integer. //====================================================================== BQBLargeInteger operator |(const BQBLargeInteger & x_value, int value); BQBLargeInteger operator |(int value, const BQBLargeInteger & x_value); //====================================================================== // Bitwise OR of an instance of the BQBLargeInteger class and an unsigned integer. //====================================================================== BQBLargeInteger operator |(const BQBLargeInteger & x_value, unsigned int value); BQBLargeInteger operator |(unsigned int value, const BQBLargeInteger & x_value); #endif travis-src-190101/src/bqb_linalg.cpp0100777000000000000000000004110513412725623014235 0ustar00/*********************************************************************************** LibBQB - File Format and Compression Algorithms for Trajectories of Volumetric Data and Atom Positions https://brehm-research.de/bqb Free software, licensed under GNU LGPL v3 Copyright (c) Martin Brehm and Martin Thomas, Martin Luther University Halle-Wittenberg, Germany, 2016 - 2019. Please cite: M. Brehm, M. Thomas: "An Efficient Lossless Compression Algorithm for Trajectories of Atom Positions and Volumetric Data", J. Chem. Inf. Model. 2018, 58 (10), pp 2092-2107. -------------------------------------------------------------------------------- LibBQB is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program. If not, see . ***********************************************************************************/ // This must always be the first include directive #include "bqb_config.h" #include #include #include #include "bqb_interface.h" #include "bqb_linalg.h" #include "bqb_tools.h" const char *GetRevisionInfo_bqb_linalg(unsigned int len) { static char buf[256]; GET_REVISION_INFO( buf, len ); return buf; } const char *GetSourceVersion_bqb_linalg() { static char buf[256]; GET_SOURCE_VERSION( buf ); return buf; } //#define MIN(x,y) ( (x) < (y) ? (x) : (y) ) //#define MAX(x,y) ((x)>(y)?(x):(y)) #define SIGN(a, b) ((b) >= 0.0 ? fabs(a) : -fabs(a)) #define SIGNF(a, b) ((b) >= 0.0 ? fabsf(a) : -fabsf(a)) //#define SQR(x) ((x)*(x)) /* * svdcomp - SVD decomposition routine. * Takes an mxn matrix a and decomposes it into udv, where u,v are * left and right orthogonal transformation matrices, and d is a * diagonal matrix of singular values. * * This routine is adapted from svdecomp.c in XLISP-STAT 2.1 which is * code from Numerical Recipes adapted by Luke Tierney and David Betz. * * Input to dsvd is as follows: * a = mxn matrix to be decomposed, gets overwritten with u * m = row dimension of a * n = column dimension of a * w = returns the vector of singular values of a * v = returns the right orthogonal transformation matrix */ static double PYTHAG(double a, double b) { double at = fabs(a), bt = fabs(b), ct, result; if (at > bt) { ct = bt / at; result = at * sqrt(1.0 + ct * ct); } else if (bt > 0.0) { ct = at / bt; result = bt * sqrt(1.0 + ct * ct); } else result = 0.0; return(result); } /* m - rows, n - cols a[zm][zn] = a[zm*n + zn]; */ int CBQBLinAlg::BQB_ComputeSVD_Flat(double *a, int m, int n, double *w, double *v) { int flag, i, its, j, jj, k, l = 0, nm = 0; double c, f, h, s, x, y, z; double anorm = 0.0, g = 0.0, scale = 0.0; double *rv1; if (m < n) { m_IF.eprintf("ComputeSVD(): #rows must be > #cols \n"); return(0); } rv1 = (double *)malloc((unsigned int) n*sizeof(double)); /* Householder reduction to bidiagonal form */ for (i = 0; i < n; i++) { /* left-hand reduction */ l = i + 1; rv1[i] = scale * g; g = s = scale = 0.0; if (i < m) { for (k = i; k < m; k++) scale += fabs(a[k*n+i]); if (scale) { for (k = i; k < m; k++) { a[k*n+i] = a[k*n+i]/scale; s += a[k*n+i] * a[k*n+i]; } f = a[i*n+i]; g = -SIGN(sqrt(s), f); h = f * g - s; a[i*n+i] = f - g; if (i != n - 1) { for (j = l; j < n; j++) { for (s = 0.0, k = i; k < m; k++) s += a[k*n+i] * a[k*n+j]; f = s / h; for (k = i; k < m; k++) a[k*n+j] += f * a[k*n+i]; } } for (k = i; k < m; k++) a[k*n+i] = a[k*n+i]*scale; } } w[i] = scale * g; /* right-hand reduction */ g = s = scale = 0.0; if (i < m && i != n - 1) { for (k = l; k < n; k++) scale += fabs(a[i*n+k]); if (scale) { for (k = l; k < n; k++) { a[i*n+k] = a[i*n+k]/scale; s += a[i*n+k] * a[i*n+k]; } f = a[i*n+l]; g = -SIGN(sqrt(s), f); h = f * g - s; a[i*n+l] = f - g; for (k = l; k < n; k++) rv1[k] = a[i*n+k] / h; if (i != m - 1) { for (j = l; j < m; j++) { for (s = 0.0, k = l; k < n; k++) s += a[j*n+k] * a[i*n+k]; for (k = l; k < n; k++) a[j*n+k] += s * rv1[k]; } } for (k = l; k < n; k++) a[i*n+k] = a[i*n+k]*scale; } } anorm = MAX(anorm, (fabs(w[i]) + fabs(rv1[i]))); } /* accumulate the right-hand transformation */ for (i = n - 1; i >= 0; i--) { if (i < n - 1) { if (g) { for (j = l; j < n; j++) v[j*n+i] = (a[i*n+j] / a[i*n+l]) / g; /* double division to avoid underflow */ for (j = l; j < n; j++) { for (s = 0.0, k = l; k < n; k++) s += a[i*n+k] * v[k*n+j]; for (k = l; k < n; k++) v[k*n+j] += s * v[k*n+i]; } } for (j = l; j < n; j++) v[i*n+j] = v[j*n+i] = 0.0; } v[i*n+i] = 1.0; g = rv1[i]; l = i; } /* accumulate the left-hand transformation */ for (i = n - 1; i >= 0; i--) { l = i + 1; g = w[i]; if (i < n - 1) for (j = l; j < n; j++) a[i*n+j] = 0.0; if (g) { g = 1.0 / g; if (i != n - 1) { for (j = l; j < n; j++) { for (s = 0.0, k = l; k < m; k++) s += a[k*n+i] * a[k*n+j]; f = (s / a[i*n+i]) * g; for (k = i; k < m; k++) a[k*n+j] += f * a[k*n+i]; } } for (j = i; j < m; j++) a[j*n+i] = a[j*n+i]*g; } else { for (j = i; j < m; j++) a[j*n+i] = 0.0; } ++a[i*n+i]; } /* diagonalize the bidiagonal form */ for (k = n - 1; k >= 0; k--) { /* loop over singular values */ for (its = 0; its < 30; its++) { /* loop over allowed iterations */ flag = 1; for (l = k; l >= 0; l--) { /* test for splitting */ nm = l - 1; if (fabs(rv1[l]) + anorm == anorm) { flag = 0; break; } if (fabs(w[nm]) + anorm == anorm) break; } if (flag) { c = 0.0; s = 1.0; for (i = l; i <= k; i++) { f = s * rv1[i]; if (fabs(f) + anorm != anorm) { g = w[i]; h = PYTHAG(f, g); w[i] = h; h = 1.0 / h; c = g * h; s = (- f * h); for (j = 0; j < m; j++) { y = a[j*n+nm]; z = a[j*n+i]; a[j*n+nm] = y * c + z * s; a[j*n+i] = z * c - y * s; } } } } z = w[k]; if (l == k) { /* convergence */ if (z < 0.0) { /* make singular value nonnegative */ w[k] = -z; for (j = 0; j < n; j++) v[j*n+k] = (-v[j*n+k]); } break; } if (its >= 30) { free((void*) rv1); m_IF.eprintf("ComputeSVD(): No convergence after 30,000! iterations \n"); return(0); } /* shift from bottom 2 x 2 minor */ x = w[l]; nm = k - 1; y = w[nm]; g = rv1[nm]; h = rv1[k]; f = ((y - z) * (y + z) + (g - h) * (g + h)) / (2.0 * h * y); g = PYTHAG(f, 1.0); f = ((x - z) * (x + z) + h * ((y / (f + SIGN(g, f))) - h)) / x; /* next QR transformation */ c = s = 1.0; for (j = l; j <= nm; j++) { i = j + 1; g = rv1[i]; y = w[i]; h = s * g; g = c * g; z = PYTHAG(f, h); rv1[j] = z; c = f / z; s = h / z; f = x * c + g * s; g = g * c - x * s; h = y * s; y = y * c; for (jj = 0; jj < n; jj++) { x = v[jj*n+j]; z = v[jj*n+i]; v[jj*n+j] = x * c + z * s; v[jj*n+i] = z * c - x * s; } z = PYTHAG(f, h); w[j] = z; if (z) { z = 1.0 / z; c = f * z; s = h * z; } f = (c * g) + (s * y); x = (c * y) - (s * g); for (jj = 0; jj < m; jj++) { y = a[jj*n+j]; z = a[jj*n+i]; a[jj*n+j] = y * c + z * s; a[jj*n+i] = z * c - y * s; } } rv1[l] = 0.0; rv1[k] = f; w[k] = x; } } free((void*) rv1); return(1); } void CBQBLinAlg::BQB_ComputePseudoInverse(int m, double *m_in, double *m_out) { double *mat_a, *mat_b, *mat_c, tf; int z1, z2, z3; // int z; mat_a = new double[m*m]; mat_b = new double[m]; mat_c = new double[m*m]; memcpy(mat_a,m_in,m*m*sizeof(double)); BQB_ComputeSVD_Flat(mat_a,m,m,mat_b,mat_c); /* m_IF.printf("*** U Matrix:\n"); m_IF.printf("{ "); for (z=0;z 1.0E-13) mat_b[z1] = 1.0 / mat_b[z1]; else mat_b[z1] = 0; } } // m_IF.printf(" @@@\n"); mout = CBQBDMatrixMN(n,m); for (z1=0;z1. ***********************************************************************************/ #ifndef BQB_LINALG_H #define BQB_LINALG_H // This must always be the first include directive #include "bqb_config.h" #include "bqb_math.h" class CBQBInterface; class CBQBLinAlg { public: CBQBLinAlg(CBQBInterface &i) : m_IF(i) { } int BQB_ComputeSVD_Flat(double *a, int m, int n, double *w, double *v); void BQB_TestSVD(); void BQB_ComputePseudoInverse(int m, double *m_in, double *m_out); CBQBDMatrixMN BQB_ComputePseudoInverse(CBQBDMatrixMN input); void BQB_TestPseudoInverse(); private: CBQBInterface &m_IF; }; #endif travis-src-190101/src/bqb_math.cpp0100777000000000000000000001531213412725635013724 0ustar00/*********************************************************************************** LibBQB - File Format and Compression Algorithms for Trajectories of Volumetric Data and Atom Positions https://brehm-research.de/bqb Free software, licensed under GNU LGPL v3 Copyright (c) Martin Brehm and Martin Thomas, Martin Luther University Halle-Wittenberg, Germany, 2016 - 2019. Please cite: M. Brehm, M. Thomas: "An Efficient Lossless Compression Algorithm for Trajectories of Atom Positions and Volumetric Data", J. Chem. Inf. Model. 2018, 58 (10), pp 2092-2107. -------------------------------------------------------------------------------- LibBQB is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program. If not, see . ***********************************************************************************/ // This must always be the first include directive #include "bqb_config.h" #include "bqb_math.h" #include "bqb_interface.h" const char *GetRevisionInfo_bqb_math(unsigned int len) { static char buf[256]; GET_REVISION_INFO( buf, len ); return buf; } const char *GetSourceVersion_bqb_math() { static char buf[256]; GET_SOURCE_VERSION( buf ); return buf; } void CBQBMath::DumpMatrix(const CBQBDMatrix3 &m) const { int z/*, z2*/; for (z=0;z<3;z++) { /* for (z2=0;z2<3;z2++) if ((GetAt(z2,z) < 0) && (GetAt(z2,z) > -0.000000001)) GetAt(z2,z) = 0;*/ m_IF.printf("( %6.3f %6.3f %6.3f )\n",m.GetAt(0,z),m.GetAt(1,z),m.GetAt(2,z)); } } void CBQBMath::DumpMatrixSmall(const CBQBDMatrix3 &m) const { int z/*, z2*/; for (z=0;z<3;z++) { /* for (z2=0;z2<3;z2++) if ((GetAt(z2,z) < 0) && (GetAt(z2,z) > -0.000000001)) GetAt(z2,z) = 0;*/ m_IF.printf("( %12.9f %12.9f %12.9f )\n",m.GetAt(0,z),m.GetAt(1,z),m.GetAt(2,z)); } } void CBQBMath::DumpMatrix(const CBQBDMatrixMN &m) const { int z, z2; for (z=0;z 1.0) t = 1.0; if (t < -1.0) t = -1.0; return acos(t); } double CBQBMath::Angle_Deg(const CBQBDVector3 &vec1, const CBQBDVector3 &vec2) const { double t; if ((vec1.GetLength() == 0) || (vec2.GetLength() == 0)) { m_IF.eprintf("CBQBMath::Angle_Deg(): Warning: Indeterminate angle between ( %f | %f | %f ) and ( %f | %f | %f ).\n",vec1[0],vec1[1],vec1[2],vec2[0],vec2[1],vec2[2]); return 0; } t = ::DotP(vec1,vec2) / vec1.GetLength() / vec2.GetLength(); if (t > 1.0) t = 1.0; if (t < -1.0) t = -1.0; t = acos(t); return fabs(t*180.0 / Pi); } double CBQBMath::DotP(const CBQBDVectorN &vec1, const CBQBDVectorN &vec2) const { if (vec1.GetDim() != vec2.GetDim()) { m_IF.eprintf("double CBQBMath::DotP(const CBQBDVectorN &, const CBQBDVectorN &): Dimension mismatch (%d vs %d).\n",vec1.GetDim(),vec2.GetDim()); abort(); } int z; double f=0; for (z=0;z 1.0) t = 1.0; if (t < -1.0) t = -1.0; return acos(t); } double CBQBMath::Angle_Deg(const CBQBDVectorN &vec1, const CBQBDVectorN &vec2) const { double t; if ((vec1.GetLength() == 0) || (vec2.GetLength() == 0)) { m_IF.eprintf("CBQBMath::Angle_Deg(): Warning: Indeterminate angle.\n"); return 0; } t = DotP(vec1,vec2) / vec1.GetLength() / vec2.GetLength(); if (t > 1.0) t = 1.0; if (t < -1.0) t = -1.0; t = acos(t); return fabs(t*180.0 / Pi); } #ifndef BQB_INSIDE_TRAVIS void CBQBDMatrixMN::Dump(FILE *a) const { int z, z2; for (z=0;z. ***********************************************************************************/ #ifndef BQB_MATH_H #define BQB_MATH_H // This must always be the first include directive #include "bqb_config.h" #include "bqb_tools.h" class CBQBInterface; #ifdef BQB_INSIDE_TRAVIS #include "xdvector3.h" #include "xdvectorn.h" #include "xdmatrix3.h" #include "xdmatrixmn.h" #define bqbpow2 pow2 #define bqbpow3 pow3 #define bqbpow4 pow4 #define bqbpow5 pow5 #define CBQBDVector3 CxDVector3 #define CBQBDVectorN CxDVectorN #define CBQBDMatrix3 CxDMatrix3 #define CBQBDMatrixMN CxDMatrixMN #else class CBQBDMatrix3; class CBQBDVector3; class CBQBDMatrixMN; class CBQBDVectorN; inline double bqbpow2(double x) { return x*x; } inline double bqbpow3(double x) { return x*x*x; } inline double bqbpow4(double x) { return (x*x)*(x*x); } inline double bqbpow5(double x) { return (x*x*x)*(x*x); } #endif class CBQBMath { // Encapsulates everything that may print to log public: CBQBMath(CBQBInterface &i) : m_IF(i) { } void DumpMatrix(const CBQBDMatrix3 &m) const; void DumpMatrixSmall(const CBQBDMatrix3 &m) const; void DumpMatrix(const CBQBDMatrixMN &m) const; void DumpMatrixSmall(const CBQBDMatrixMN &m) const; void InvertMatrix(CBQBDMatrix3 &m); double Angle(const CBQBDVector3 &vec1, const CBQBDVector3 &vec2) const; double Angle_Deg(const CBQBDVector3 &vec1, const CBQBDVector3 &vec2) const; double DotP(const CBQBDVectorN &vec1, const CBQBDVectorN &vec2) const; double Angle(const CBQBDVectorN &vec1, const CBQBDVectorN &vec2) const; double Angle_Deg(const CBQBDVectorN &vec1, const CBQBDVectorN &vec2) const; private: CBQBInterface &m_IF; }; #ifndef BQB_INSIDE_TRAVIS //double Dihedral(const CBQBDVector3 &vec1, const CBQBDVector3 &vec2, const CBQBDVector3 &norm, bool absolute); class CBQBDVector3 { public: CBQBDVector3() { } ~CBQBDVector3() { } CBQBDVector3(const CBQBDVector3 &v) { m_pData[0] = v.m_pData[0]; m_pData[1] = v.m_pData[1]; m_pData[2] = v.m_pData[2]; } explicit CBQBDVector3(double f) { m_pData[0] = f; m_pData[1] = f; m_pData[2] = f; } CBQBDVector3(double x, double y, double z) { m_pData[0] = x; m_pData[1] = y; m_pData[2] = z; } double &GetAt(int i) { #ifdef DEBUG_CDVECTOR3 printf("@ CBQBDVector3::GetAt(int): %d...",i); #endif return m_pData[i]; } double &operator [] (int i) { #ifdef DEBUG_CDVECTOR3 printf("@ CBQBDVector3::operator [] (int): %d\n",i); #endif return GetAt(i); } double GetAt(int i) const { #ifdef DEBUG_CDVECTOR3 printf("@ CBQBDVector3::GetAt(int): %d...",i); #endif #ifdef DEBUG_ARRAYS if (i > 2) { printf("CBQBDVector3::GetAt(int): Boundary Error (%d/3)...",i); abort(); } #endif return m_pData[i]; } double operator [] (int i) const { #ifdef DEBUG_CDVECTOR3 printf("@ CBQBDVector3::operator [] (int): %d\n",i); #endif return GetAt(i); } CBQBDVector3 operator + (const CBQBDVector3 &v) const { #ifdef DEBUG_CDVECTOR3 printf("@ CBQBDVector3::operator + (CBQBDVector3&)\n"); #endif return CBQBDVector3(m_pData[0]+v.m_pData[0],m_pData[1]+v.m_pData[1],m_pData[2]+v.m_pData[2]); } CBQBDVector3 operator - (const CBQBDVector3 &v) const { #ifdef DEBUG_CDVECTOR3 printf("@ CBQBDVector3::operator - (CBQBDVector3&)\n"); #endif return CBQBDVector3(m_pData[0]-v.m_pData[0],m_pData[1]-v.m_pData[1],m_pData[2]-v.m_pData[2]); } CBQBDVector3 operator * (double f) const { #ifdef DEBUG_CDVECTOR3 printf("@ CBQBDVector3::operator * (double)\n"); #endif return CBQBDVector3(m_pData[0]*f,m_pData[1]*f,m_pData[2]*f); } CBQBDVector3 operator / (double f) const { #ifdef DEBUG_CDVECTOR3 printf("@ CBQBDVector3::operator / (double)\n"); #endif return CBQBDVector3(m_pData[0]/f,m_pData[1]/f,m_pData[2]/f); } void operator += (const CBQBDVector3 &v) { #ifdef DEBUG_CDVECTOR3 printf("@ CBQBDVector3::operator += (CBQBDVector3&)\n"); #endif m_pData[0] += v.m_pData[0]; m_pData[1] += v.m_pData[1]; m_pData[2] += v.m_pData[2]; } void operator -= (const CBQBDVector3 &v) { #ifdef DEBUG_CDVECTOR3 printf("@ CBQBDVector3::operator -= (CBQBDVector3&)\n"); #endif m_pData[0] -= v.m_pData[0]; m_pData[1] -= v.m_pData[1]; m_pData[2] -= v.m_pData[2]; } void operator *= (double f) { #ifdef DEBUG_CDVECTOR3 printf("@ CBQBDVector3::operator *= (double)\n"); #endif m_pData[0] *= f; m_pData[1] *= f; m_pData[2] *= f; } void operator /= (double f) { #ifdef DEBUG_CDVECTOR3 printf("@ CBQBDVector3::operator /= (double)\n"); #endif m_pData[0] /= f; m_pData[1] /= f; m_pData[2] /= f; } double GetLength() const { return sqrt(m_pData[0]*m_pData[0]+m_pData[1]*m_pData[1]+m_pData[2]*m_pData[2]); } double GetLengthSqr() const { return m_pData[0]*m_pData[0]+m_pData[1]*m_pData[1]+m_pData[2]*m_pData[2]; } void Normalize() { double l; l = GetLength(); m_pData[0] /= l; m_pData[1] /= l; m_pData[2] /= l; } void Chop(double d) { if ((m_pData[0] != 0) && (fabs(m_pData[0]) < d)) m_pData[0] = 0; if ((m_pData[1] != 0) && (fabs(m_pData[1]) < d)) m_pData[1] = 0; if ((m_pData[2] != 0) && (fabs(m_pData[2]) < d)) m_pData[2] = 0; } void PointRoot(const CBQBDVector3 &vec1, const CBQBDVector3 &vec2, const CBQBDVector3 &point); private: double m_pData[3]; }; inline void Swap(CBQBDVector3 &vec1, CBQBDVector3 &vec2) { CBQBDVector3 t; t = vec1; vec1 = vec2; vec2 = t; } inline CBQBDVector3 operator * (double f, const CBQBDVector3 &v) { return v*f; } inline CBQBDVector3 CrossP(const CBQBDVector3 &vec1, const CBQBDVector3 &vec2) { return CBQBDVector3(vec1[1]*vec2[2] - vec1[2]*vec2[1], vec1[2]*vec2[0] - vec1[0]*vec2[2], vec1[0]*vec2[1] - vec1[1]*vec2[0]); } inline double DotP(const CBQBDVector3 &vec1, const CBQBDVector3 &vec2) { return vec1[0]*vec2[0]+vec1[1]*vec2[1]+vec1[2]*vec2[2]; } inline double VecDist(const CBQBDVector3 &vec1, const CBQBDVector3 &vec2) { return sqrt((vec1[0]-vec2[0])*(vec1[0]-vec2[0]) + (vec1[1]-vec2[1])*(vec1[1]-vec2[1]) + (vec1[2]-vec2[2])*(vec1[2]-vec2[2])); } inline CBQBDVector3 Normalize(const CBQBDVector3 &vec) { double tf; tf = vec.GetLength(); return CBQBDVector3(vec[0]/tf,vec[1]/tf,vec[2]/tf); } class CBQBDMatrix3 { public: CBQBDMatrix3() { } ~CBQBDMatrix3() { } CBQBDMatrix3(const CBQBDMatrix3 &m) { m_pData[0] = m.m_pData[0]; m_pData[1] = m.m_pData[1]; m_pData[2] = m.m_pData[2]; m_pData[3] = m.m_pData[3]; m_pData[4] = m.m_pData[4]; m_pData[5] = m.m_pData[5]; m_pData[6] = m.m_pData[6]; m_pData[7] = m.m_pData[7]; m_pData[8] = m.m_pData[8]; } explicit CBQBDMatrix3(double f) { m_pData[0] = f; m_pData[1] = f; m_pData[2] = f; m_pData[3] = f; m_pData[4] = f; m_pData[5] = f; m_pData[6] = f; m_pData[7] = f; m_pData[8] = f; } CBQBDMatrix3(double a, double b, double c, double d, double e, double f, double g, double h, double i) { m_pData[0] = a; m_pData[1] = b; m_pData[2] = c; m_pData[3] = d; m_pData[4] = e; m_pData[5] = f; m_pData[6] = g; m_pData[7] = h; m_pData[8] = i; } double &GetAt(int i) { #ifdef DEBUG_CMATRIX3 printf("@ CBQBDMatrix3::GetAt(int): %d...",i); #endif return m_pData[i]; } double &GetAt(int i, int j) { #ifdef DEBUG_CMATRIX3 printf("@ CBQBDMatrix3::GetAt(int, int): %d, %d...",i,j); #endif return m_pData[i*3+j]; } double &operator [] (int i) { #ifdef DEBUG_CMATRIX3 printf("@ CBQBDMatrix3::operator [] (int): %d\n",i); #endif return GetAt(i); } double GetAt(int i) const { #ifdef DEBUG_CMATRIX3 printf("@ CBQBDMatrix3::GetAt(int): %d...",i); #endif return m_pData[i]; } double GetAt(int i, int j) const { #ifdef DEBUG_CMATRIX3 printf("@ CBQBDMatrix3::GetAt(int, int): %d, %d...",i,j); #endif return m_pData[i*3+j]; } double operator [] (int i) const { #ifdef DEBUG_CMATRIX3 printf("@ CBQBDMatrix3::operator [] (int): %d\n",i); #endif return GetAt(i); } double &operator () (int i, int j) { #ifdef DEBUG_CMATRIX3 printf("@ CBQBDMatrix3::operator () (int, int): %d, %d\n",i,j); #endif return GetAt(i,j); } double operator () (int i, int j) const { #ifdef DEBUG_CMATRIX3 printf("@ CBQBDMatrix3::operator () (int, int): %d, %d\n",i,j); #endif return GetAt(i,j); } void operator *= (double f) { #ifdef DEBUG_CMATRIX3 printf("@ CBQBDMatrix3::operator *= (double)\n"); #endif m_pData[0] *= f; m_pData[1] *= f; m_pData[2] *= f; m_pData[3] *= f; m_pData[4] *= f; m_pData[5] *= f; m_pData[6] *= f; m_pData[7] *= f; m_pData[8] *= f; } CBQBDMatrix3 operator * (const CBQBDMatrix3 &m) const { #ifdef DEBUG_CMATRIX3 printf("@ CBQBDMatrix3::operator * (CBQBDMatrix3)\n"); #endif return CBQBDMatrix3( GetAt(0,0)*m.GetAt(0,0) + GetAt(1,0)*m.GetAt(0,1) + GetAt(2,0)*m.GetAt(0,2), GetAt(0,1)*m.GetAt(0,0) + GetAt(1,1)*m.GetAt(0,1) + GetAt(2,1)*m.GetAt(0,2), GetAt(0,2)*m.GetAt(0,0) + GetAt(1,2)*m.GetAt(0,1) + GetAt(2,2)*m.GetAt(0,2), GetAt(0,0)*m.GetAt(1,0) + GetAt(1,0)*m.GetAt(1,1) + GetAt(2,0)*m.GetAt(1,2), GetAt(0,1)*m.GetAt(1,0) + GetAt(1,1)*m.GetAt(1,1) + GetAt(2,1)*m.GetAt(1,2), GetAt(0,2)*m.GetAt(1,0) + GetAt(1,2)*m.GetAt(1,1) + GetAt(2,2)*m.GetAt(1,2), GetAt(0,0)*m.GetAt(2,0) + GetAt(1,0)*m.GetAt(2,1) + GetAt(2,0)*m.GetAt(2,2), GetAt(0,1)*m.GetAt(2,0) + GetAt(1,1)*m.GetAt(2,1) + GetAt(2,1)*m.GetAt(2,2), GetAt(0,2)*m.GetAt(2,0) + GetAt(1,2)*m.GetAt(2,1) + GetAt(2,2)*m.GetAt(2,2) ); } CBQBDVector3 operator * (const CBQBDVector3 &v) const { #ifdef DEBUG_CMATRIX3 printf("@ CBQBDMatrix3::operator * (CBQBDVector3)\n"); #endif return CBQBDVector3( GetAt(0,0)*v[0] + GetAt(1,0)*v[1] + GetAt(2,0)*v[2], GetAt(0,1)*v[0] + GetAt(1,1)*v[1] + GetAt(2,1)*v[2], GetAt(0,2)*v[0] + GetAt(1,2)*v[1] + GetAt(2,2)*v[2]); } CBQBDMatrix3 operator * (double f) const { #ifdef DEBUG_CMATRIX3 printf("@ CBQBDMatrix3::operator * (double)\n"); #endif return CBQBDMatrix3(m_pData[0]*f,m_pData[1]*f,m_pData[2]*f,m_pData[3]*f,m_pData[4]*f,m_pData[5]*f,m_pData[6]*f,m_pData[7]*f,m_pData[8]*f); } void RotMat(const CBQBDVector3 &vec, double a) { double ca, sa; ca = cos(a); sa = sin(a); GetAt(0,0) = (vec[0]*vec[0]*(1.0-ca) + ca); GetAt(1,0) = (vec[0]*vec[1]*(1.0-ca) - vec[2]*sa); GetAt(2,0) = (vec[0]*vec[2]*(1.0-ca) + vec[1]*sa); GetAt(0,1) = (vec[1]*vec[0]*(1.0-ca) + vec[2]*sa); GetAt(1,1) = (vec[1]*vec[1]*(1.0-ca) + ca); GetAt(2,1) = (vec[1]*vec[2]*(1.0-ca) - vec[0]*sa); GetAt(0,2) = (vec[2]*vec[0]*(1.0-ca) - vec[1]*sa); GetAt(1,2) = (vec[2]*vec[1]*(1.0-ca) + vec[0]*sa); GetAt(2,2) = (vec[2]*vec[2]*(1.0-ca) + ca); } void Unity() { GetAt(0,0) = 1; GetAt(1,0) = 0; GetAt(2,0) = 0; GetAt(0,1) = 0; GetAt(1,1) = 1; GetAt(2,1) = 0; GetAt(0,2) = 0; GetAt(1,2) = 0; GetAt(2,2) = 1; } CBQBDMatrix3 Transpose() { return CBQBDMatrix3( GetAt(0,0), GetAt(1,0), GetAt(2,0), GetAt(0,1), GetAt(1,1), GetAt(2,1), GetAt(0,2), GetAt(1,2), GetAt(2,2)); } double Det() { #define _deta11 GetAt(0,0) #define _deta12 GetAt(0,1) #define _deta13 GetAt(0,2) #define _deta21 GetAt(1,0) #define _deta22 GetAt(1,1) #define _deta23 GetAt(1,2) #define _deta31 GetAt(2,0) #define _deta32 GetAt(2,1) #define _deta33 GetAt(2,2) return _deta11 * (_deta33*_deta22 - _deta32*_deta23) - _deta21 * (_deta33*_deta12 - _deta32*_deta13) + _deta31 * (_deta23*_deta12 - _deta22*_deta13); } private: double m_pData[9]; }; class CBQBDVectorN { public: CBQBDVectorN() { m_iDim = 0; m_pData = NULL; } ~CBQBDVectorN() { if (m_pData != NULL) { delete[] m_pData; m_pData = NULL; } } CBQBDVectorN(const CBQBDVectorN &v) { m_iDim = v.m_iDim; m_pData = new double[m_iDim]; memcpy(m_pData,v.m_pData,sizeof(double)*m_iDim); } CBQBDVectorN & operator = (const CBQBDVectorN &v) { #ifdef DEBUG_CDVECTORN printf("@ CBQBDVectorN::operator = (const CBQBDVectorN &)\n"); #endif if (m_pData != NULL) delete[] m_pData; m_iDim = v.m_iDim; m_pData = new double[m_iDim]; memcpy(m_pData,v.m_pData,sizeof(double)*m_iDim); return *this; } CBQBDVectorN(int i, double f) { int z; m_iDim = i; m_pData = new double[m_iDim]; for (z=0;z= m_iDim) { printf("& CBQBDVectorN::GetAt(int): Boundary Error (%d/%d).\n",i,m_iDim); abort(); } #endif return m_pData[i]; } double &operator [] (int i) { #ifdef DEBUG_CDVECTORN printf("@ CBQBDVectorN::operator [] (int): %d\n",i); #endif #ifdef DEBUG_ARRAYS if ((i < 0) || (i >= m_iDim)) { printf("& CBQBDVectorN::operator [] (int): Boundary Error (%d/%d).\n",i,m_iDim); abort(); } #endif return m_pData[i]; } double GetAt(int i) const { #ifdef DEBUG_CDVECTORN printf("@ CBQBDVectorN::GetAt(int): %d...",i); #endif #ifdef DEBUG_ARRAYS if (i >= m_iDim) { printf("CBQBDVectorN::GetAt(int): Boundary Error (%d/%d).\n",i,m_iDim); abort(); } #endif return m_pData[i]; } double operator [] (int i) const { #ifdef DEBUG_CDVECTORN printf("@ CBQBDVectorN::operator [] (int): %d\n",i); #endif #ifdef DEBUG_ARRAYS if ((i < 0) || (i >= m_iDim)) { printf("CBQBDVectorN::operator [] (int): Boundary Error (%d/%d).\n",i,m_iDim); abort(); } #endif return m_pData[i]; } CBQBDVectorN operator + (const CBQBDVectorN &v) const { #ifdef DEBUG_CDVECTORN printf("@ CBQBDVectorN::operator + (CBQBDVectorN&)\n"); #endif if (m_iDim != v.m_iDim) { printf("CBQBDVectorN::operator + (CBQBDVectorN&): Dimension mismatch (%d vs %d).\n",m_iDim,v.m_iDim); abort(); } CBQBDVectorN r(m_iDim); int z; for (z=0;z= m_iRows*m_iCols)) { printf("& CBQBDMatrixMN::GetAt(int): Boundary Error (%d/%d).\n",i,m_iRows*m_iCols); abort(); } #endif return m_pData[i]; } double &GetAt(int i, int j) { #ifdef DEBUG_CDMATRIXMN printf("@ CBQBDMatrixMN::GetAt(int, int): %d, %d.\n",i,j); #endif #ifdef BOUND_MATVEC if ((i < 0) || (i >= m_iRows) || (j < 0) || (j >= m_iCols)) { printf("& CBQBDMatrixMN::GetAt(int,int): Boundary Error (%d|%d / %d|%d).\n",i,j,m_iRows,m_iCols); abort(); } #endif return m_pData[i*m_iCols+j]; } double &operator [] (int i) { #ifdef DEBUG_CDMATRIXMN printf("@ CBQBDMatrixMN::operator [] (int): %d.\n",i); #endif return GetAt(i); } double &operator () (int i, int j) { #ifdef DEBUG_CDMATRIXMN printf("@ CBQBDMatrixMN::operator () (int,int): %d, %d.\n",i,j); #endif #ifdef BOUND_MATVEC if ((i < 0) || (i >= m_iRows) || (j < 0) || (j >= m_iCols)) { printf("& CBQBDMatrixMN::operator () (int,int): Boundary Error (%d|%d / %d|%d).\n",i,j,m_iRows,m_iCols); abort(); } #endif return m_pData[i*m_iCols+j]; } double GetAt(int i) const { #ifdef DEBUG_CDMATRIXMN printf("@ CBQBDMatrixMN::GetAt(int): %d.\n",i); #endif #ifdef BOUND_MATVEC if ((i < 0) || (i >= m_iRows*m_iCols)) { printf("CBQBDMatrixMN::GetAt(int): Boundary Error (%d/%d).\n",i,m_iRows*m_iCols); abort(); } #endif return m_pData[i]; } double GetAt(int i, int j) const { #ifdef DEBUG_CDMATRIXMN printf("@ CBQBDMatrixMN::GetAt(int,int): %d, %d.\n",i,j); #endif #ifdef BOUND_MATVEC if ((i < 0) || (i >= m_iRows) || (j < 0) || (j >= m_iCols)) { printf("CBQBDMatrixMN::GetAt(int,int): Boundary Error (%d|%d / %d|%d).\n",i,j,m_iRows,m_iCols); abort(); } #endif return m_pData[i*m_iCols+j]; } double operator [] (int i) const { #ifdef DEBUG_CDMATRIXMN printf("@ CBQBDMatrixMN::operator [] (int): %d.\n",i); #endif #ifdef BOUND_MATVEC if ((i < 0) || (i >= m_iRows*m_iCols)) { printf("CBQBDMatrixMN::operator [] (int): Boundary Error (%d/%d).\n",i,m_iRows*m_iCols); abort(); } #endif return m_pData[i]; } double operator () (int i, int j) const { #ifdef DEBUG_CDMATRIXMN printf("@ CBQBDMatrixMN::operator () (int,int): %d, %d.\n",i,j); #endif #ifdef BOUND_MATVEC if ((i < 0) || (i >= m_iRows) || (j < 0) || (j >= m_iCols)) { printf("CBQBDMatrixMN::operator () (int,int): Boundary Error (%d|%d / %d|%d).\n",i,j,m_iRows,m_iCols); abort(); } #endif return m_pData[i*m_iCols+j]; } void operator *= (double f) { #ifdef DEBUG_CDMATRIXMN printf("@ CBQBDMatrixMN::operator *= (double)\n"); #endif int z; for (z=0;z. ***********************************************************************************/ // This must always be the first include directive #include "bqb_config.h" #include #include #include "bqb_parmset.h" #include "bqb_tools.h" #include "bqb_interface.h" const char *GetRevisionInfo_bqb_parmset(unsigned int len) { static char buf[256]; GET_REVISION_INFO( buf, len ); return buf; } const char *GetSourceVersion_bqb_parmset() { static char buf[256]; GET_SOURCE_VERSION( buf ); return buf; } void BQBChkRngInt(CBQBInterface &in, int &i, int mi, int ma, const char *s) { if ((i < mi) || (i > ma)) { in.eprintf("%s: Warning: Allowed range is %d .. %d, found %d. Clipping.\n",s,mi,ma,i); if (i < mi) i = mi; if (i > ma) i = ma; } } void BQBChkRngFlt(CBQBInterface &in, double &f, double mi, double ma, const char *s) { if ((f < mi) || (f > ma)) { in.eprintf("%s: Warning: Allowed range is %.3f .. %.3f, found %.3f. Clipping.\n",s,mi,ma,f); if (f < mi) f = mi; if (f > ma) f = ma; } } void CBQBParameterSet_Compressor::ExportBits(CBQBBitSet *bs) const { bs->WriteBit(m_bOptTables); bs->WriteBit(m_bRLE); bs->WriteBit(m_bBW); bs->WriteBit(m_bMTF); bs->WriteBits(m_iTableCount,6); if (m_iTableCount != 0) { bs->WriteBits(m_iBlock,7); bs->WriteBits(m_iMaxIter,6); } bs->WriteBits(m_iMaxChunk,4); } bool CBQBParameterSet_Compressor::ImportBits(CBQBBitSet *bs, int version) { if (version > 0) { m_IF.eprintf("CBQBParameterSet_Compressor::ImportBits(): Invalid parameter set version: %d (allowed: 0).\n",version); m_IF.eprintf("Probably the LibBQB version is too old for this parameter set.\n"); return false; } m_bOptTables = bs->ReadBit(); m_bRLE = bs->ReadBit(); m_bBW = bs->ReadBit(); m_bMTF = bs->ReadBit(); m_iTableCount = bs->ReadBitsInteger(6); if (m_iTableCount != 0) { m_iBlock = bs->ReadBitsInteger(7); m_iMaxIter = bs->ReadBitsInteger(6); } else { m_iBlock = 1; m_iMaxIter = 0; } m_iMaxChunk = bs->ReadBitsInteger(4); return true; } std::string CBQBParameterSet_Compressor::ToString(int indent) const { std::string i; int z; std::ostringstream o; for (z=0;z 0) { m_IF.eprintf("CBQBParameterSet_Compressor::FromKey(): Invalid parameter set version: %d (allowed: 0).\n",ver); m_IF.eprintf("Probably the LibBQB version is too old for this key.\n"); return false; } bp = bs.ReadBit(); bv = bs.ReadBit(); if (bp || bv) { m_IF.eprintf("CBQBParameterSet_Compressor::FromKey(): Error: This key is not for compressor data.\n"); return false; } if (!ImportBits(&bs,ver)) { m_IF.eprintf("CBQBParameterSet_Compressor::FromKey(): Error importing compressor parameters from key.\n"); return false; } return true; } /*******************************************************************************************************************/ void CBQBParameterSet_Position::ExportBits(CBQBBitSet *bs) const { m_oCompressor.ExportBits(bs); bs->WriteBits(m_iPrec,3); bs->WriteBits(m_iSplit,5); bs->WriteBit(m_bSortAtom); bs->WriteBit(m_bUseExtra); if (m_bUseExtra) { bs->WriteBits(m_iExtraTRange,4); bs->WriteBits(m_iExtraTOrder,4); bs->WriteBits(m_iExtraTimeExpo,14); } else { bs->WriteBit(m_bOptOrder); bs->WriteBits(m_iOrder,4); } } bool CBQBParameterSet_Position::ImportBits(CBQBBitSet *bs, int version) { if (version > 0) { m_IF.eprintf("CBQBParameterSet_Position::ImportBits(): Invalid parameter set version: %d (allowed: 0).\n",version); m_IF.eprintf("Probably the LibBQB version is too old for this parameter set.\n"); return false; } if (!m_oCompressor.ImportBits(bs,version)) { m_IF.eprintf("CBQBParameterSet_Position::ImportBits(): Error reading compressor parameters.\n"); return false; } m_iPrec = bs->ReadBitsInteger(3); m_iSplit = bs->ReadBitsInteger(5); m_bSortAtom = bs->ReadBit(); m_bUseExtra = bs->ReadBit(); if (m_bUseExtra) { m_iExtraTRange = bs->ReadBitsInteger(4); m_iExtraTOrder = bs->ReadBitsInteger(4); m_iExtraTimeExpo = bs->ReadBitsInteger(14); } else { m_bOptOrder = bs->ReadBit(); m_iOrder = bs->ReadBitsInteger(4); } return true; } std::string CBQBParameterSet_Position::ToString(int indent) const { std::string i; int z; std::ostringstream o; for (z=0;z 0) { m_IF.eprintf("CBQBParameterSet_Position::FromKey(): Invalid parameter set version: %d (allowed: 0).\n",ver); m_IF.eprintf("Probably the LibBQB version is too old for this key.\n"); return false; } bp = bs.ReadBit(); bv = bs.ReadBit(); if (!bp || bv) { m_IF.eprintf("CBQBParameterSet_Position::FromKey(): Error: This key is not for position data.\n"); return false; } if (!ImportBits(&bs,ver)) { m_IF.eprintf("CBQBParameterSet_Position::FromKey(): Error importing position parameters from key.\n"); return false; } return true; } /*******************************************************************************************************************/ void CBQBParameterSet_Volumetric::ExportBits(CBQBBitSet *bs) const { m_oCompressor.ExportBits(bs); bs->WriteBits(m_iSigni,4); bs->WriteBits(m_iEps,6); bs->WriteBits(m_iSplit,5); bs->WriteBit(m_bHilbert); bs->WriteBit(m_bUseExtra); if (m_bUseExtra) { if ((m_iExtraSRangeX == m_iExtraSRangeY) && (m_iExtraSRangeX == m_iExtraSRangeZ)) { bs->WriteBit(0); bs->WriteBits(m_iExtraSRangeX,4); } else { bs->WriteBit(1); bs->WriteBits(m_iExtraSRangeX,4); bs->WriteBits(m_iExtraSRangeY,4); bs->WriteBits(m_iExtraSRangeZ,4); } bs->WriteBits(m_iExtraTRange,4); bs->WriteBits(m_iExtraSOrder,4); bs->WriteBits(m_iExtraTOrder,4); if ((m_iExtraOffsetX == m_iExtraOffsetY) && (m_iExtraOffsetX == m_iExtraOffsetZ)) { bs->WriteBit(0); bs->WriteBits(m_iExtraOffsetX,4); } else { bs->WriteBit(1); bs->WriteBits(m_iExtraOffsetX,4); bs->WriteBits(m_iExtraOffsetY,4); bs->WriteBits(m_iExtraOffsetZ,4); } bs->WriteBit(m_bExtraCrossS); bs->WriteBit(m_bExtraCrossT); bs->WriteBit(m_bExtraWrap); bs->WriteBit(m_bExtraCrossRangeS); bs->WriteBit(m_bExtraCrossRangeT); bs->WriteBits(m_iExtraDistExpo,14); bs->WriteBits(m_iExtraTimeExpo,14); bs->WriteBit(m_bExtraPredCorr); } else { bs->WriteBits(m_iOrder,4); bs->WriteBit(m_bOptOrder); bs->WriteBits(m_iNbhFac,12); } } bool CBQBParameterSet_Volumetric::ImportBits(CBQBBitSet *bs, int version) { if (version > 0) { m_IF.eprintf("CBQBParameterSet_Volumetric::ImportBits(): Invalid parameter set version: %d (allowed: 0).\n",version); m_IF.eprintf("Probably the LibBQB version is too old for this parameter set.\n"); return false; } if (!m_oCompressor.ImportBits(bs,version)) { m_IF.eprintf("CBQBParameterSet_Volumetric::ImportBits(): Error reading compressor parameters.\n"); return false; } m_iSigni = bs->ReadBitsInteger(4); m_iEps = bs->ReadBitsInteger(6); m_iSplit = bs->ReadBitsInteger(5); m_bHilbert = bs->ReadBit(); m_bUseExtra = bs->ReadBit(); if (m_bUseExtra) { if (bs->ReadBit()) { m_iExtraSRangeX = bs->ReadBitsInteger(4); m_iExtraSRangeY = bs->ReadBitsInteger(4); m_iExtraSRangeZ = bs->ReadBitsInteger(4); } else { m_iExtraSRangeX = bs->ReadBitsInteger(4); m_iExtraSRangeY = m_iExtraSRangeX; m_iExtraSRangeZ = m_iExtraSRangeX; } m_iExtraTRange = bs->ReadBitsInteger(4); m_iExtraSOrder = bs->ReadBitsInteger(4); m_iExtraTOrder = bs->ReadBitsInteger(4); if (bs->ReadBit()) { m_iExtraOffsetX = bs->ReadBitsInteger(4); m_iExtraOffsetY = bs->ReadBitsInteger(4); m_iExtraOffsetZ = bs->ReadBitsInteger(4); } else { m_iExtraOffsetX = bs->ReadBitsInteger(4); m_iExtraOffsetY = m_iExtraOffsetX; m_iExtraOffsetZ = m_iExtraOffsetX; } m_bExtraCrossS = bs->ReadBit(); m_bExtraCrossT = bs->ReadBit(); m_bExtraWrap = bs->ReadBit(); m_bExtraCrossRangeS = bs->ReadBit(); m_bExtraCrossRangeT = bs->ReadBit(); m_iExtraDistExpo = bs->ReadBitsInteger(14); m_iExtraTimeExpo = bs->ReadBitsInteger(14); m_bExtraPredCorr = bs->ReadBit(); } else { m_iOrder = bs->ReadBitsInteger(4); m_bOptOrder = bs->ReadBit(); m_iNbhFac = bs->ReadBitsInteger(12); } return true; } std::string CBQBParameterSet_Volumetric::ToString(int indent) const { std::string i; int z; std::ostringstream o; for (z=0;z 0) { m_IF.eprintf("CBQBParameterSet_Volumetric::FromKey(): Invalid parameter set version: %d (allowed: 0).\n",ver); m_IF.eprintf("Probably the LibBQB version is too old for this key.\n"); return false; } bp = bs.ReadBit(); bv = bs.ReadBit(); if (bp || !bv) { m_IF.eprintf("CBQBParameterSet_Volumetric::FromKey(): Error: This key is not for volumetric data.\n"); return false; } if (!ImportBits(&bs,ver)) { m_IF.eprintf("CBQBParameterSet_Volumetric::FromKey(): Error importing parameters from key.\n"); return false; } return true; } /*******************************************************************************************************************/ void CBQBParameterSet_PosAndVol::ExportBits(CBQBBitSet *bs) const { m_oPosition.ExportBits(bs); m_oVolumetric.ExportBits(bs); } bool CBQBParameterSet_PosAndVol::ImportBits(CBQBBitSet *bs, int version) { if (version > 0) { m_IF.eprintf("CBQBParameterSet_PosAndVol::ImportBits(): Invalid parameter set version: %d (allowed: 0).\n",version); m_IF.eprintf("Probably the LibBQB version is too old for this parameter set.\n"); return false; } if (!m_oPosition.ImportBits(bs,version)) { m_IF.eprintf("CBQBParameterSet_PosAndVol::ImportBits(): Error reading position parameters.\n"); return false; } if (!m_oVolumetric.ImportBits(bs,version)) { m_IF.eprintf("CBQBParameterSet_PosAndVol::ImportBits(): Error reading volumetric parameters.\n"); return false; } return true; } std::string CBQBParameterSet_PosAndVol::ToString(int indent) const { std::string i; int z; std::ostringstream o; for (z=0;z 0) { m_IF.eprintf("CBQBParameterSet_PosAndVol::FromKey(): Invalid parameter set version: %d (allowed: 0).\n",ver); m_IF.eprintf("Probably the LibBQB version is too old for this key.\n"); return false; } bp = bs.ReadBit(); bv = bs.ReadBit(); if (!bp || !bv) { m_IF.eprintf("CBQBParameterSet_PosAndVol::FromKey(): Error: This key is not for position & volumetric data.\n"); return false; } if (!ImportBits(&bs,ver)) { m_IF.eprintf("CBQBParameterSet_PosAndVol::FromKey(): Error importing parameters from key.\n"); return false; } return true; } travis-src-190101/src/bqb_parmset.h0100777000000000000000000006757713412725653014137 0ustar00/*********************************************************************************** LibBQB - File Format and Compression Algorithms for Trajectories of Volumetric Data and Atom Positions https://brehm-research.de/bqb Free software, licensed under GNU LGPL v3 Copyright (c) Martin Brehm and Martin Thomas, Martin Luther University Halle-Wittenberg, Germany, 2016 - 2019. Please cite: M. Brehm, M. Thomas: "An Efficient Lossless Compression Algorithm for Trajectories of Atom Positions and Volumetric Data", J. Chem. Inf. Model. 2018, 58 (10), pp 2092-2107. -------------------------------------------------------------------------------- LibBQB is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program. If not, see . ***********************************************************************************/ #ifndef BQB_PARMSET_H #define BQB_PARMSET_H // This must always be the first include directive #include "bqb_config.h" #include #include "bqb_bitset.h" class CBQBInterface; void BQBChkRngInt(CBQBInterface &in, int &i, int mi, int ma, const char *s); void BQBChkRngFlt(CBQBInterface &in, double &f, double mi, double ma, const char *s); // Current Version: 0 class CBQBParameterSet_Compressor { friend class CBQBParameterSet_Position; friend class CBQBParameterSet_Volumetric; friend class CBQBParameterSet_PosAndVol; public: // No pointers as members --> standard copy constructor and assignment operator will work CBQBParameterSet_Compressor(CBQBInterface &i) : m_IF(i) { // Default values for file compression SetOptTables(false); SetRLE(true); SetBW(true); SetMTF(true); SetTableCount(6); SetBlockLength(50); SetMaxIter(10); SetMaxChunk(4194304); m_iVersion = 0; } void ExportBits(CBQBBitSet *bs) const; bool ImportBits(CBQBBitSet *bs, int version); std::string ToString(int indent) const; std::string ToKey() const; bool FromKey(std::string key); void SetOptTables(bool b) { m_bOptTables = b; } bool GetOptTables() const { return m_bOptTables; } void SetRLE(bool b) { m_bRLE = b; } bool GetRLE() const { return m_bRLE; } void SetBW(bool b) { m_bBW = b; } bool GetBW() const { return m_bBW; } void SetMTF(bool b) { m_bMTF = b; } bool GetMTF() const { return m_bMTF; } void SetTableCount(int i) { BQBChkRngInt(m_IF,i,1,64,"CBQBParameterSet_Compressor::SetTableCount()"); m_iTableCount = i-1; } int GetTableCount() const { return m_iTableCount+1; } void SetBlockLength(int i) { BQBChkRngInt(m_IF,i,1,128,"CBQBParameterSet_Compressor::SetBlockLength()"); m_iBlock = i-1; } int GetBlockLength() const { return m_iBlock+1; } void SetMaxIter(int i) { BQBChkRngInt(m_IF,i,0,126,"CBQBParameterSet_Compressor::SetMaxIter()"); m_iMaxIter = i/2; } int GetMaxIter() const { return m_iMaxIter*2; } void SetMaxChunk(int i) { BQBChkRngInt(m_IF,i,0,16777216,"CBQBParameterSet_Compressor::SetMaxChunk()"); if (i == 0) m_iMaxChunk = 0; else m_iMaxChunk = log2i(i/1024)+1; } int GetMaxChunk() const { if (m_iMaxChunk == 0) return 0; else return pow2i(m_iMaxChunk-1)*1024; } int GetVersion() const { return m_iVersion; } private: CBQBInterface &m_IF; bool m_bOptTables; // 1 Bit bool m_bRLE; // 1 Bit bool m_bBW; // 1 Bit bool m_bMTF; // 1 Bit int m_iTableCount; // 6 Bits, 1 .. 64, +1 int m_iBlock; // 7 Bits, 1 .. 128, + 1 int m_iMaxIter; // 6 Bits, 0 .. 126, * 2 int m_iMaxChunk; // 4 Bits, 1 kiSymbol .. 16384 kiSymbol, 2^(i-1), disable: i=0 int m_iVersion; // 4 Bits, 0 .. 15 }; // Current Version: 0 class CBQBParameterSet_Position { friend class CBQBParameterSet_PosAndVol; public: // No pointers as members --> standard copy constructor and assignment operator will work CBQBParameterSet_Position(CBQBInterface &i) : m_IF(i), m_oCompressor(i) { SetPrecision(5); SetOrder(8); SetOptOrder(true); SetSplit(14); SetTableCount(1); SetOptTables(false); SetBlockLength(40); SetBW(false); SetMTF(false); SetRLE(true); SetMaxIter(10); SetSortAtom(true); SetMaxChunk(0); SetUseExtra(true); SetExtraTRange(9); SetExtraTOrder(6); SetExtraTimeExpo(4.0); } void ExportBits(CBQBBitSet *bs) const; bool ImportBits(CBQBBitSet *bs, int version); std::string ToString(int indent) const; std::string ToKey() const; bool FromKey(std::string key); void SetOptTables(bool b) { m_oCompressor.m_bOptTables = b; } bool GetOptTables() const { return m_oCompressor.m_bOptTables; } void SetRLE(bool b) { m_oCompressor.m_bRLE = b; } bool GetRLE() const { return m_oCompressor.m_bRLE; } void SetBW(bool b) { m_oCompressor.m_bBW = b; } bool GetBW() const { return m_oCompressor.m_bBW; } void SetMTF(bool b) { m_oCompressor.m_bMTF = b; } bool GetMTF() const { return m_oCompressor.m_bMTF; } void SetTableCount(int i) { BQBChkRngInt(m_IF,i,1,64,"CBQBParameterSet_Position::SetTableCount()"); m_oCompressor.m_iTableCount = i-1; } int GetTableCount() const { return m_oCompressor.m_iTableCount+1; } void SetBlockLength(int i) { BQBChkRngInt(m_IF,i,1,128,"CBQBParameterSet_Position::SetBlockLength()"); m_oCompressor.m_iBlock = i-1; } int GetBlockLength() const { return m_oCompressor.m_iBlock+1; } void SetMaxIter(int i) { BQBChkRngInt(m_IF,i,0,126,"CBQBParameterSet_Position::SetMaxIter()"); m_oCompressor.m_iMaxIter = i/2; } int GetMaxIter() const { return m_oCompressor.m_iMaxIter*2; } void SetMaxChunk(int i) { BQBChkRngInt(m_IF,i,0,16777216,"CBQBParameterSet_Position::SetMaxChunk()"); if (i == 0) m_oCompressor.m_iMaxChunk = 0; else m_oCompressor.m_iMaxChunk = log2i(i/1024)+1; } int GetMaxChunk() const { if (m_oCompressor.m_iMaxChunk == 0) return 0; else return pow2i(m_oCompressor.m_iMaxChunk-1)*1024; } void SetOptOrder(bool b) { m_bOptOrder = b; } bool GetOptOrder() const { return m_bOptOrder; } void SetSortAtom(bool b) { m_bSortAtom = b; } bool GetSortAtom() const { return m_bSortAtom; } void SetUseExtra(bool b) { m_bUseExtra = b; } bool GetUseExtra() const { return m_bUseExtra; } void SetPrecision(int i) { BQBChkRngInt(m_IF,i,0,7,"CBQBParameterSet_Position::SetPrecision()"); m_iPrec = i; } int GetPrecision() const { return m_iPrec; } void SetOrder(int i) { BQBChkRngInt(m_IF,i,0,15,"CBQBParameterSet_Position::SetOrder()"); m_iOrder = i; } int GetOrder() const { return m_iOrder; } void SetSplit(int i) { BQBChkRngInt(m_IF,i,1,31,"CBQBParameterSet_Position::SetSplit()"); m_iSplit = i; } int GetSplit() const { return m_iSplit; } void SetExtraTRange(int i) { BQBChkRngInt(m_IF,i,0,15,"CBQBParameterSet_Position::SetExtraTRange()"); m_iExtraTRange = i; } int GetExtraTRange() const { return m_iExtraTRange; } void SetExtraTOrder(int i) { BQBChkRngInt(m_IF,i,0,15,"CBQBParameterSet_Position::SetExtraTOrder()"); m_iExtraTOrder = i; } int GetExtraTOrder() const { return m_iExtraTOrder; } void SetExtraTimeExpo(double f) { BQBChkRngFlt(m_IF,f,0,16.0,"CBQBParameterSet_Position::SetExtraTimeExpo()"); m_iExtraTimeExpo = (int)(f*1000.0+0.5); } double GetExtraTimeExpo() const { return m_iExtraTimeExpo/1000.0; } int GetVersion() const { return m_iVersion; } CBQBParameterSet_Compressor* GetCompressorParameterSet() { return &m_oCompressor; } private: CBQBInterface &m_IF; CBQBParameterSet_Compressor m_oCompressor; int m_iPrec; // 3 Bits, 0 .. 7 int m_iOrder; // 4 Bits, 0 .. 15 bool m_bOptOrder; // 1 Bit int m_iSplit; // 5 Bits, 1 .. 31 bool m_bSortAtom; // 1 Bit bool m_bUseExtra; // 1 Bit int m_iExtraTRange; // 4 Bits, 0 .. 15 int m_iExtraTOrder; // 4 Bits, 0 .. 15 int m_iExtraTimeExpo; // 14 Bits, 0.000 .. 16.000, / 1000.0 int m_iVersion; // 4 Bits, 0 .. 15 }; // Current Version: 0 class CBQBParameterSet_Volumetric { friend class CBQBParameterSet_PosAndVol; public: // No pointers as members --> standard copy constructor and assignment operator will work CBQBParameterSet_Volumetric(CBQBInterface &i) : m_IF(i), m_oCompressor(i) { SetSigni(5); SetEps(12); SetOrder(8); SetOptOrder(true); SetHilbert(true); SetNbhFac(1.075); SetSplit(10); SetTableCount(6); SetOptTables(false); SetBlockLength(20); SetBW(false); SetMTF(false); SetMaxIter(10); SetRLE(true); SetMaxChunk(0); SetUseExtra(true); SetExtraSRange(7); SetExtraTRange(6); SetExtraSOrder(3); SetExtraTOrder(2); SetExtraOffset(3); SetExtraCrossS(true); SetExtraCrossT(false); SetExtraWrap(true); SetExtraCrossRangeS(true); SetExtraCrossRangeT(false); SetExtraDistExpo(3.0); SetExtraTimeExpo(1.0); SetExtraPredCorr(true); } void ExportBits(CBQBBitSet *bs) const; bool ImportBits(CBQBBitSet *bs, int version); std::string ToString(int indent) const; std::string ToKey() const; bool FromKey(std::string key); void SetOptTables(bool b) { m_oCompressor.m_bOptTables = b; } bool GetOptTables() const { return m_oCompressor.m_bOptTables; } void SetRLE(bool b) { m_oCompressor.m_bRLE = b; } bool GetRLE() const { return m_oCompressor.m_bRLE; } void SetBW(bool b) { m_oCompressor.m_bBW = b; } bool GetBW() const { return m_oCompressor.m_bBW; } void SetMTF(bool b) { m_oCompressor.m_bMTF = b; } bool GetMTF() const { return m_oCompressor.m_bMTF; } void SetTableCount(int i) { BQBChkRngInt(m_IF,i,1,64,"CBQBParameterSet_Volumetric::SetTableCount()"); m_oCompressor.m_iTableCount = i-1; } int GetTableCount() const { return m_oCompressor.m_iTableCount+1; } void SetBlockLength(int i) { BQBChkRngInt(m_IF,i,1,128,"CBQBParameterSet_Volumetric::SetBlockLength()"); m_oCompressor.m_iBlock = i-1; } int GetBlockLength() const { return m_oCompressor.m_iBlock+1; } void SetMaxIter(int i) { BQBChkRngInt(m_IF,i,0,126,"CBQBParameterSet_Volumetric::SetMaxIter()"); m_oCompressor.m_iMaxIter = i/2; } int GetMaxIter() const { return m_oCompressor.m_iMaxIter*2; } void SetMaxChunk(int i) { BQBChkRngInt(m_IF,i,0,16777216,"CBQBParameterSet_Volumetric::SetMaxChunk()"); if (i == 0) m_oCompressor.m_iMaxChunk = 0; else m_oCompressor.m_iMaxChunk = log2i(i/1024)+1; } int GetMaxChunk() const { if (m_oCompressor.m_iMaxChunk == 0) return 0; else return pow2i(m_oCompressor.m_iMaxChunk-1)*1024; } void SetOptOrder(bool b) { m_bOptOrder = b; } bool GetOptOrder() const { return m_bOptOrder; } void SetHilbert(bool b) { m_bHilbert = b; } bool GetHilbert() const { return m_bHilbert; } void SetUseExtra(bool b) { m_bUseExtra = b; } bool GetUseExtra() const { return m_bUseExtra; } void SetExtraCrossS(bool b) { m_bExtraCrossS = b; } bool GetExtraCrossS() const { return m_bExtraCrossS; } void SetExtraCrossT(bool b) { m_bExtraCrossT = b; } bool GetExtraCrossT() const { return m_bExtraCrossT; } void SetExtraWrap(bool b) { m_bExtraWrap = b; } bool GetExtraWrap() const { return m_bExtraWrap; } void SetExtraCrossRangeS(bool b) { m_bExtraCrossRangeS = b; } bool GetExtraCrossRangeS() const { return m_bExtraCrossRangeS; } void SetExtraCrossRangeT(bool b) { m_bExtraCrossRangeT = b; } bool GetExtraCrossRangeT() const { return m_bExtraCrossRangeT; } void SetExtraPredCorr(bool b) { m_bExtraPredCorr = b; } bool GetExtraPredCorr() const { return m_bExtraPredCorr; } void SetSigni(int i) { BQBChkRngInt(m_IF,i,1,9,"CBQBParameterSet_Volumetric::SetSigni()"); m_iSigni = i; } int GetSigni() const { return m_iSigni; } void SetOrder(int i) { BQBChkRngInt(m_IF,i,0,15,"CBQBParameterSet_Volumetric::SetOrder()"); m_iOrder = i; } int GetOrder() const { return m_iOrder; } void SetEps(int i) { BQBChkRngInt(m_IF,i,0,63,"CBQBParameterSet_Volumetric::SetEps()"); m_iEps = i; } int GetEps() const { return m_iEps; } void SetSplit(int i) { BQBChkRngInt(m_IF,i,1,31,"CBQBParameterSet_Volumetric::SetSplit()"); m_iSplit = i; } int GetSplit() const { return m_iSplit; } void SetExtraSRangeX(int i) { BQBChkRngInt(m_IF,i,0,15,"CBQBParameterSet_Volumetric::SetExtraSRangeX()"); m_iExtraSRangeX = i; } int GetExtraSRangeX() const { return m_iExtraSRangeX; } void SetExtraSRangeY(int i) { BQBChkRngInt(m_IF,i,0,15,"CBQBParameterSet_Volumetric::SetExtraSRangeY()"); m_iExtraSRangeY = i; } int GetExtraSRangeY() const { return m_iExtraSRangeY; } void SetExtraSRangeZ(int i) { BQBChkRngInt(m_IF,i,0,15,"CBQBParameterSet_Volumetric::SetExtraSRangeZ()"); m_iExtraSRangeZ = i; } int GetExtraSRangeZ() const { return m_iExtraSRangeZ; } void SetExtraSRange(int i) { BQBChkRngInt(m_IF,i,0,15,"CBQBParameterSet_Volumetric::SetExtraSRange()"); m_iExtraSRangeX = i; m_iExtraSRangeY = i; m_iExtraSRangeZ = i; } bool IsExtraSRangeXYZEqual() const { if ((m_iExtraSRangeX == m_iExtraSRangeY) && (m_iExtraSRangeX == m_iExtraSRangeZ)) return true; else return false; } void SetExtraTRange(int i) { BQBChkRngInt(m_IF,i,0,15,"CBQBParameterSet_Volumetric::SetExtraTRange()"); m_iExtraTRange = i; } int GetExtraTRange() const { return m_iExtraTRange; } void SetExtraSOrder(int i) { BQBChkRngInt(m_IF,i,0,15,"CBQBParameterSet_Volumetric::SetExtraSOrder()"); m_iExtraSOrder = i; } int GetExtraSOrder() const { return m_iExtraSOrder; } void SetExtraTOrder(int i) { BQBChkRngInt(m_IF,i,0,15,"CBQBParameterSet_Volumetric::SetExtraTOrder()"); m_iExtraTOrder = i; } int GetExtraTOrder() const { return m_iExtraTOrder; } void SetExtraOffsetX(int i) { BQBChkRngInt(m_IF,i,0,15,"CBQBParameterSet_Volumetric::SetExtraOffsetX()"); m_iExtraOffsetX = i; } int GetExtraOffsetX() const { return m_iExtraOffsetX; } void SetExtraOffsetY(int i) { BQBChkRngInt(m_IF,i,0,15,"CBQBParameterSet_Volumetric::SetExtraOffsetY()"); m_iExtraOffsetY = i; } int GetExtraOffsetY() const { return m_iExtraOffsetY; } void SetExtraOffsetZ(int i) { BQBChkRngInt(m_IF,i,0,15,"CBQBParameterSet_Volumetric::SetExtraOffsetZ()"); m_iExtraOffsetZ = i; } int GetExtraOffsetZ() const { return m_iExtraOffsetZ; } void SetExtraOffset(int i) { BQBChkRngInt(m_IF,i,0,15,"CBQBParameterSet_Volumetric::SetExtraOffset()"); m_iExtraOffsetX = i; m_iExtraOffsetY = i; m_iExtraOffsetZ = i; } bool IsExtraOffsetXYZEqual() const { if ((m_iExtraOffsetX == m_iExtraOffsetY) && (m_iExtraOffsetX == m_iExtraOffsetZ)) return true; else return false; } void SetNbhFac(double f) { BQBChkRngFlt(m_IF,f,0,4.0,"CBQBParameterSet_Volumetric::SetNbhFac()"); m_iNbhFac = (int)(f*1000.0+0.5); } double GetNbhFac() const { return m_iNbhFac/1000.0; } void SetExtraDistExpo(double f) { BQBChkRngFlt(m_IF,f,0,16.0,"CBQBParameterSet_Volumetric::SetExtraDistExpo()"); m_iExtraDistExpo = (int)(f*1000.0+0.5); } double GetExtraDistExpo() const { return m_iExtraDistExpo/1000.0; } void SetExtraTimeExpo(double f) { BQBChkRngFlt(m_IF,f,0,16.0,"CBQBParameterSet_Volumetric::SetExtraTimeExpo()"); m_iExtraTimeExpo = (int)(f*1000.0+0.5); } double GetExtraTimeExpo() const { return m_iExtraTimeExpo/1000.0; } int GetVersion() const { return m_iVersion; } CBQBParameterSet_Compressor* GetCompressorParameterSet() { return &m_oCompressor; } private: CBQBInterface &m_IF; CBQBParameterSet_Compressor m_oCompressor; int m_iSigni; // 4 Bits, 1 .. 9 int m_iOrder; // 4 Bits, 0 .. 15 bool m_bOptOrder; // 1 Bit int m_iEps; // 6 Bits, 0 .. 63 int m_iSplit; // 5 Bits, 1 .. 31 bool m_bHilbert; // 1 Bit int m_iNbhFac; // 12 Bits, 0.000 .. 4.000, / 1000.0 bool m_bUseExtra; // 1 Bit int m_iExtraSRangeX; // 4 Bits, 0 .. 15 int m_iExtraSRangeY; // 4 Bits, 0 .. 15 int m_iExtraSRangeZ; // 4 Bits, 0 .. 15 int m_iExtraTRange; // 4 Bits, 0 .. 15 int m_iExtraSOrder; // 4 Bits, 0 .. 15 int m_iExtraTOrder; // 4 Bits, 0 .. 15 int m_iExtraOffsetX; // 4 Bits, 0 .. 15 int m_iExtraOffsetY; // 4 Bits, 0 .. 15 int m_iExtraOffsetZ; // 4 Bits, 0 .. 15 bool m_bExtraCrossS; // 1 Bit bool m_bExtraCrossT; // 1 Bit bool m_bExtraWrap; // 1 Bit bool m_bExtraCrossRangeS; // 1 Bit bool m_bExtraCrossRangeT; // 1 Bit int m_iExtraDistExpo; // 14 Bits, 0.000 .. 16.000, / 1000.0 int m_iExtraTimeExpo; // 14 Bits, 0.000 .. 16.000, / 1000.0 bool m_bExtraPredCorr; // 1 Bit int m_iVersion; // 4 Bits, 0 .. 15 }; // Current Version: 0 class CBQBParameterSet_PosAndVol { public: // No pointers as members --> standard copy constructor and assignment operator will work CBQBParameterSet_PosAndVol(CBQBInterface &i) : m_IF(i), m_oPosition(i), m_oVolumetric(i) { } void ExportBits(CBQBBitSet *bs) const; bool ImportBits(CBQBBitSet *bs, int version); std::string ToString(int indent) const; std::string ToKey() const; bool FromKey(std::string key); void SetVolOptTables(bool b) { m_oVolumetric.m_oCompressor.m_bOptTables = b; } bool GetVolOptTables() const { return m_oVolumetric.m_oCompressor.m_bOptTables; } void SetVolRLE(bool b) { m_oVolumetric.m_oCompressor.m_bRLE = b; } bool GetVolRLE() const { return m_oVolumetric.m_oCompressor.m_bRLE; } void SetVolBW(bool b) { m_oVolumetric.m_oCompressor.m_bBW = b; } bool GetVolBW() const { return m_oVolumetric.m_oCompressor.m_bBW; } void SetVolMTF(bool b) { m_oVolumetric.m_oCompressor.m_bMTF = b; } bool GetVolMTF() const { return m_oVolumetric.m_oCompressor.m_bMTF; } void SetVolTableCount(int i) { BQBChkRngInt(m_IF,i,1,64,"CBQBParameterSet_PosAndVol::SetVolTableCount()"); m_oVolumetric.m_oCompressor.m_iTableCount = i-1; } int GetVolTableCount() const { return m_oVolumetric.m_oCompressor.m_iTableCount+1; } void SetVolBlockLength(int i) { BQBChkRngInt(m_IF,i,1,128,"CBQBParameterSet_PosAndVol::SetVolBlockLength()"); m_oVolumetric.m_oCompressor.m_iBlock = i-1; } int GetVolBlockLength() const { return m_oVolumetric.m_oCompressor.m_iBlock+1; } void SetVolMaxIter(int i) { BQBChkRngInt(m_IF,i,0,126,"CBQBParameterSet_PosAndVol::SetVolMaxIter()"); m_oVolumetric.m_oCompressor.m_iMaxIter = i/2; } int GetVolMaxIter() const { return m_oVolumetric.m_oCompressor.m_iMaxIter*2; } void SetVolMaxChunk(int i) { BQBChkRngInt(m_IF,i,0,16777216,"CBQBParameterSet_PosAndVol::SetVolMaxChunk()"); if (i == 0) m_oVolumetric.m_oCompressor.m_iMaxChunk = 0; else m_oVolumetric.m_oCompressor.m_iMaxChunk = log2i(i/1024)+1; } int GetVolMaxChunk() const { if (m_oVolumetric.m_oCompressor.m_iMaxChunk == 0) return 0; else return pow2i(m_oVolumetric.m_oCompressor.m_iMaxChunk-1)*1024; } void SetVolOptOrder(bool b) { m_oVolumetric.m_bOptOrder = b; } bool GetVolOptOrder() const { return m_oVolumetric.m_bOptOrder; } void SetVolHilbert(bool b) { m_oVolumetric.m_bHilbert = b; } bool GetVolHilbert() const { return m_oVolumetric.m_bHilbert; } void SetVolUseExtra(bool b) { m_oVolumetric.m_bUseExtra = b; } bool GetVolUseExtra() const { return m_oVolumetric.m_bUseExtra; } void SetVolExtraCrossS(bool b) { m_oVolumetric.m_bExtraCrossS = b; } bool GetVolExtraCrossS() const { return m_oVolumetric.m_bExtraCrossS; } void SetVolExtraCrossT(bool b) { m_oVolumetric.m_bExtraCrossT = b; } bool GetVolExtraCrossT() const { return m_oVolumetric.m_bExtraCrossT; } void SetVolExtraWrap(bool b) { m_oVolumetric.m_bExtraWrap = b; } bool GetVolExtraWrap() const { return m_oVolumetric.m_bExtraWrap; } void SetVolExtraCrossRangeS(bool b) { m_oVolumetric.m_bExtraCrossRangeS = b; } bool GetVolExtraCrossRangeS() const { return m_oVolumetric.m_bExtraCrossRangeS; } void SetVolExtraCrossRangeT(bool b) { m_oVolumetric.m_bExtraCrossRangeT = b; } bool GetVolExtraCrossRangeT() const { return m_oVolumetric.m_bExtraCrossRangeT; } void SetVolExtraPredCorr(bool b) { m_oVolumetric.m_bExtraPredCorr = b; } bool GetVolExtraPredCorr() const { return m_oVolumetric.m_bExtraPredCorr; } void SetVolSigni(int i) { BQBChkRngInt(m_IF,i,1,9,"CBQBParameterSet_PosAndVol::SetVolSigni()"); m_oVolumetric.m_iSigni = i; } int GetVolSigni() const { return m_oVolumetric.m_iSigni; } void SetVolOrder(int i) { BQBChkRngInt(m_IF,i,0,15,"CBQBParameterSet_PosAndVol::SetVolOrder()"); m_oVolumetric.m_iOrder = i; } int GetVolOrder() const { return m_oVolumetric.m_iOrder; } void SetVolEps(int i) { BQBChkRngInt(m_IF,i,0,63,"CBQBParameterSet_PosAndVol::SetVolEps()"); m_oVolumetric.m_iEps = i; } int GetVolEps() const { return m_oVolumetric.m_iEps; } void SetVolSplit(int i) { BQBChkRngInt(m_IF,i,1,31,"CBQBParameterSet_PosAndVol::SetVolSplit()"); m_oVolumetric.m_iSplit = i; } int GetVolSplit() const { return m_oVolumetric.m_iSplit; } void SetVolExtraSRangeX(int i) { BQBChkRngInt(m_IF,i,0,15,"CBQBParameterSet_PosAndVol::SetVolExtraSRangeX()"); m_oVolumetric.m_iExtraSRangeX = i; } int GetVolExtraSRangeX() const { return m_oVolumetric.m_iExtraSRangeX; } void SetVolExtraSRangeY(int i) { BQBChkRngInt(m_IF,i,0,15,"CBQBParameterSet_PosAndVol::SetVolExtraSRangeY()"); m_oVolumetric.m_iExtraSRangeY = i; } int GetVolExtraSRangeY() const { return m_oVolumetric.m_iExtraSRangeY; } void SetVolExtraSRangeZ(int i) { BQBChkRngInt(m_IF,i,0,15,"CBQBParameterSet_PosAndVol::SetVolExtraSRangeZ()"); m_oVolumetric.m_iExtraSRangeZ = i; } int GetVolExtraSRangeZ() const { return m_oVolumetric.m_iExtraSRangeZ; } void SetVolExtraSRange(int i) { BQBChkRngInt(m_IF,i,0,15,"CBQBParameterSet_PosAndVol::SetVolExtraSRange()"); m_oVolumetric.m_iExtraSRangeX = i; m_oVolumetric.m_iExtraSRangeY = i; m_oVolumetric.m_iExtraSRangeZ = i; } bool IsVolExtraSRangeXYZEqual() const { if ((m_oVolumetric.m_iExtraSRangeX == m_oVolumetric.m_iExtraSRangeY) && (m_oVolumetric.m_iExtraSRangeX == m_oVolumetric.m_iExtraSRangeZ)) return true; else return false; } void SetVolExtraTRange(int i) { BQBChkRngInt(m_IF,i,0,15,"CBQBParameterSet_PosAndVol::SetVolExtraTRange()"); m_oVolumetric.m_iExtraTRange = i; } int GetVolExtraTRange() const { return m_oVolumetric.m_iExtraTRange; } void SetVolExtraSOrder(int i) { BQBChkRngInt(m_IF,i,0,15,"CBQBParameterSet_PosAndVol::SetVolExtraSOrder()"); m_oVolumetric.m_iExtraSOrder = i; } int GetVolExtraSOrder() const { return m_oVolumetric.m_iExtraSOrder; } void SetVolExtraTOrder(int i) { BQBChkRngInt(m_IF,i,0,15,"CBQBParameterSet_PosAndVol::SetVolExtraTOrder()"); m_oVolumetric.m_iExtraTOrder = i; } int GetVolExtraTOrder() const { return m_oVolumetric.m_iExtraTOrder; } void SetVolExtraOffsetX(int i) { BQBChkRngInt(m_IF,i,0,15,"CBQBParameterSet_PosAndVol::SetVolExtraOffsetX()"); m_oVolumetric.m_iExtraOffsetX = i; } int GetVolExtraOffsetX() const { return m_oVolumetric.m_iExtraOffsetX; } void SetVolExtraOffsetY(int i) { BQBChkRngInt(m_IF,i,0,15,"CBQBParameterSet_PosAndVol::SetVolExtraOffsetY()"); m_oVolumetric.m_iExtraOffsetY = i; } int GetVolExtraOffsetY() const { return m_oVolumetric.m_iExtraOffsetY; } void SetVolExtraOffsetZ(int i) { BQBChkRngInt(m_IF,i,0,15,"CBQBParameterSet_PosAndVol::SetVolExtraOffsetZ()"); m_oVolumetric.m_iExtraOffsetZ = i; } int GetVolExtraOffsetZ() const { return m_oVolumetric.m_iExtraOffsetZ; } void SetVolExtraOffset(int i) { BQBChkRngInt(m_IF,i,0,15,"CBQBParameterSet_PosAndVol::SetVolExtraOffset()"); m_oVolumetric.m_iExtraOffsetX = i; m_oVolumetric.m_iExtraOffsetY = i; m_oVolumetric.m_iExtraOffsetZ = i; } bool IsVolExtraOffsetXYZEqual() const { if ((m_oVolumetric.m_iExtraOffsetX == m_oVolumetric.m_iExtraOffsetY) && (m_oVolumetric.m_iExtraOffsetX == m_oVolumetric.m_iExtraOffsetZ)) return true; else return false; } void SetVolNbhFac(double f) { BQBChkRngFlt(m_IF,f,0,4.0,"CBQBParameterSet_PosAndVol::SetVolNbhFac()"); m_oVolumetric.m_iNbhFac = (int)(f*1000.0+0.5); } double GetVolNbhFac() const { return m_oVolumetric.m_iNbhFac/1000.0; } void SetVolExtraDistExpo(double f) { BQBChkRngFlt(m_IF,f,0,16.0,"CBQBParameterSet_PosAndVol::SetVolExtraDistExpo()"); m_oVolumetric.m_iExtraDistExpo = (int)(f*1000.0+0.5); } double GetVolExtraDistExpo() const { return m_oVolumetric.m_iExtraDistExpo/1000.0; } void SetVolExtraTimeExpo(double f) { BQBChkRngFlt(m_IF,f,0,16.0,"CBQBParameterSet_PosAndVol::SetVolExtraTimeExpo()"); m_oVolumetric.m_iExtraTimeExpo = (int)(f*1000.0+0.5); } double GetVolExtraTimeExpo() const { return m_oVolumetric.m_iExtraTimeExpo/1000.0; } void SetPosOptTables(bool b) { m_oPosition.m_oCompressor.m_bOptTables = b; } bool GetPosOptTables() const { return m_oPosition.m_oCompressor.m_bOptTables; } void SetPosRLE(bool b) { m_oPosition.m_oCompressor.m_bRLE = b; } bool GetPosRLE() const { return m_oPosition.m_oCompressor.m_bRLE; } void SetPosBW(bool b) { m_oPosition.m_oCompressor.m_bBW = b; } bool GetPosBW() const { return m_oPosition.m_oCompressor.m_bBW; } void SetPosMTF(bool b) { m_oPosition.m_oCompressor.m_bMTF = b; } bool GetPosMTF() const { return m_oPosition.m_oCompressor.m_bMTF; } void SetPosTableCount(int i) { BQBChkRngInt(m_IF,i,1,64,"CBQBParameterSet_PosAndVol::SetPosTableCount()"); m_oPosition.m_oCompressor.m_iTableCount = i-1; } int GetPosTableCount() const { return m_oPosition.m_oCompressor.m_iTableCount+1; } void SetPosBlockLength(int i) { BQBChkRngInt(m_IF,i,1,128,"CBQBParameterSet_PosAndVol::SetPosBlockLength()"); m_oPosition.m_oCompressor.m_iBlock = i-1; } int GetPosBlockLength() const { return m_oPosition.m_oCompressor.m_iBlock+1; } void SetPosMaxIter(int i) { BQBChkRngInt(m_IF,i,0,126,"CBQBParameterSet_PosAndVol::SetPosMaxIter()"); m_oPosition.m_oCompressor.m_iMaxIter = i/2; } int GetPosMaxIter() const { return m_oPosition.m_oCompressor.m_iMaxIter*2; } void SetPosMaxChunk(int i) { BQBChkRngInt(m_IF,i,0,16777216,"CBQBParameterSet_PosAndVol::SetPosMaxChunk()"); if (i == 0) m_oPosition.m_oCompressor.m_iMaxChunk = 0; else m_oPosition.m_oCompressor.m_iMaxChunk = log2i(i/1024)+1; } int GetPosMaxChunk() const { if (m_oPosition.m_oCompressor.m_iMaxChunk == 0) return 0; else return pow2i(m_oPosition.m_oCompressor.m_iMaxChunk-1)*1024; } void SetPosOptOrder(bool b) { m_oPosition.m_bOptOrder = b; } bool GetPosOptOrder() const { return m_oPosition.m_bOptOrder; } void SetPosSortAtom(bool b) { m_oPosition.m_bSortAtom = b; } bool GetPosSortAtom() const { return m_oPosition.m_bSortAtom; } void SetPosUseExtra(bool b) { m_oPosition.m_bUseExtra = b; } bool GetPosUseExtra() const { return m_oPosition.m_bUseExtra; } void SetPosPrecision(int i) { BQBChkRngInt(m_IF,i,0,7,"CBQBParameterSet_PosAndVol::SetPosPrecision()"); m_oPosition.m_iPrec = i; } int GetPosPrecision() const { return m_oPosition.m_iPrec; } void SetPosOrder(int i) { BQBChkRngInt(m_IF,i,0,15,"CBQBParameterSet_PosAndVol::SetPosOrder()"); m_oPosition.m_iOrder = i; } int GetPosOrder() const { return m_oPosition.m_iOrder; } void SetPosSplit(int i) { BQBChkRngInt(m_IF,i,1,31,"CBQBParameterSet_PosAndVol::SetPosSplit()"); m_oPosition.m_iSplit = i; } int GetPosSplit() const { return m_oPosition.m_iSplit; } void SetPosExtraTRange(int i) { BQBChkRngInt(m_IF,i,0,15,"CBQBParameterSet_PosAndVol::SetPosExtraTRange()"); m_oPosition.m_iExtraTRange = i; } int GetPosExtraTRange() const { return m_oPosition.m_iExtraTRange; } void SetPosExtraTOrder(int i) { BQBChkRngInt(m_IF,i,0,15,"CBQBParameterSet_PosAndVol::SetPosExtraTOrder()"); m_oPosition.m_iExtraTOrder = i; } int GetPosExtraTOrder() const { return m_oPosition.m_iExtraTOrder; } void SetPosExtraTimeExpo(double f) { BQBChkRngFlt(m_IF,f,0,16.0,"CBQBParameterSet_PosAndVol::SetPosExtraTimeExpo()"); m_oPosition.m_iExtraTimeExpo = (int)(f*1000.0+0.5); } double GetPosExtraTimeExpo() const { return m_oPosition.m_iExtraTimeExpo/1000.0; } int GetVersion() const { return m_iVersion; } CBQBParameterSet_Position* GetPositionParameterSet() { return &m_oPosition; } CBQBParameterSet_Volumetric* GetVolumetricParameterSet() { return &m_oVolumetric; } CBQBParameterSet_Compressor* GetVolumetricCompressorParameterSet() { return &m_oVolumetric.m_oCompressor; } CBQBParameterSet_Compressor* GetPositionCompressorParameterSet() { return &m_oPosition.m_oCompressor; } private: CBQBInterface &m_IF; CBQBParameterSet_Position m_oPosition; CBQBParameterSet_Volumetric m_oVolumetric; int m_iVersion; // 4 Bits, 0 .. 15 }; #endif travis-src-190101/src/bqb_tools.cpp0100777000000000000000000003075013412725616014135 0ustar00/*********************************************************************************** LibBQB - File Format and Compression Algorithms for Trajectories of Volumetric Data and Atom Positions https://brehm-research.de/bqb Free software, licensed under GNU LGPL v3 Copyright (c) Martin Brehm and Martin Thomas, Martin Luther University Halle-Wittenberg, Germany, 2016 - 2019. Please cite: M. Brehm, M. Thomas: "An Efficient Lossless Compression Algorithm for Trajectories of Atom Positions and Volumetric Data", J. Chem. Inf. Model. 2018, 58 (10), pp 2092-2107. -------------------------------------------------------------------------------- LibBQB is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program. If not, see . ***********************************************************************************/ // This must always be the first include directive #include "bqb_config.h" #include "bqb_tools.h" #include #include "bqb_interface.h" #include "bqb_format.h" const char *GetRevisionInfo_bqb_tools(unsigned int len) { static char buf[256]; GET_REVISION_INFO( buf, len ); return buf; } const char *GetSourceVersion_bqb_tools() { static char buf[256]; GET_SOURCE_VERSION( buf ); return buf; } int bqb_strcmp_nocase(const char *s1, const char *s2) { char *buf, *buf2; unsigned long z; int i; buf = new char[strlen(s1)+1]; buf2 = new char[strlen(s2)+1]; for (z=0;z &ia, int n, int s1, int s2) { /* int t, i, z, a; // printf("Push %d ...\n",n); t = (int)(floor(mylog2(n+1))+0.5); // printf("t=%d\n",t); i = n; for (z=0;z>> FindIndexPosition >>>\n"); if (a == NULL) { if (m_IF.IsPL(BQB_PL_DEBUG)) { m_IF.printf(" File pointer == NULL.\n"); m_IF.printf("<<< FindIndexPosition <<<\n\n"); } return 0; } fseek(a,-3,SEEK_END); (void)fread(buf,3,1,a); // if (memcmp(buf,"IDX",3) != 0) { if ((buf[0] != 'I') || (buf[1] != 'D') || (buf[2] != 'X')) { // To prevent Valgrind "uninitialized value" warning if (m_IF.IsPL(BQB_PL_DEBUG)) { m_IF.printf(" Last three characters differ from \"IDX\".\n"); m_IF.printf("<<< FindIndexPosition <<<\n\n"); } return 0; } else if (m_IF.IsPL(BQB_PL_DEBUG)) m_IF.printf(" Found \"IDX\".\n"); fseek(a,-7,SEEK_END); (void)fread(&uc,1,1,a); i = ((unsigned int)uc) << 24; (void)fread(&uc,1,1,a); i += ((unsigned int)uc) << 16; (void)fread(&uc,1,1,a); i += ((unsigned int)uc) << 8; (void)fread(&uc,1,1,a); i += uc; if (m_IF.IsPL(BQB_PL_DEBUG)) m_IF.printf(" Found index frame length %u.\n",i); fseek(a,-((int)i),SEEK_END); l = ftell(a); if (m_IF.IsPL(BQB_PL_DEBUG)) { m_IF.printf(" Found index frame offset %ld.\n",l); m_IF.printf("<<< FindIndexPosition <<<\n\n"); } return l; } void BQBFormatTime(unsigned long eta, char *buf) { char tbuf[256], tbuf2[256]; if (buf == NULL) return; if ((eta/60) > 0) sprintf(tbuf,"%02lus",eta%60); else sprintf(tbuf,"%2lus",eta%60); eta /= 60; if (eta > 0) { strcpy(tbuf2,tbuf); if ((eta/60) > 0) sprintf(tbuf,"%02lum",eta%60); else sprintf(tbuf,"%2lum",eta%60); strcat(tbuf,tbuf2); eta /= 60; if (eta > 0) { strcpy(tbuf2,tbuf); if ((eta/60) > 0) sprintf(tbuf,"%02luh",eta%24); else sprintf(tbuf,"%2luh",eta%24); strcat(tbuf,tbuf2); eta /= 24; } if (eta > 0) { strcpy(tbuf2,tbuf); if ((eta/60) > 0) sprintf(tbuf,"%02lud",eta); else sprintf(tbuf,"%2lud",eta); strcat(tbuf,tbuf2); } } strcpy(buf,tbuf); } bool bqbisinteger(const char *s) { int z; z = 0; if (strlen(s) > 0) if (s[0] == '-') z++; for (;z<(int)strlen(s);z++) if ((s[z] < 0) || (s[z] > 9)) return false; return true; } void CBQBStatistics::PushStatistics() { m_oaStatStack.push_back(m_oStat); } void CBQBStatistics::PopStatistics() { if (m_oaStatStack.size() == 0) { m_IF.eprintf("CBQBStatistics::PopStatistics(): Error: Statistics stack is empty.\n"); abort(); } m_oStat.m_lSize = m_oaStatStack.back().m_lSize; m_oStat.m_lOverhead = m_oaStatStack.back().m_lOverhead; m_oStat.m_lAlphabet = m_oaStatStack.back().m_lAlphabet; m_oStat.m_lHuffmanTables = m_oaStatStack.back().m_lHuffmanTables; m_oStat.m_lTableSwitch = m_oaStatStack.back().m_lTableSwitch; m_oStat.m_lHuffmanData = m_oaStatStack.back().m_lHuffmanData; m_oaStatStack.pop_back(); } void CBQBStatistics::PopDiffStatistics() { if (m_oaStatStack.size() < 2) { m_IF.eprintf("CBQBStatistics::PopDiffStatistics(): Error: Statistics stack has size of %lu < 2.\n",m_oaStatStack.size()); abort(); } m_oStat.m_lSize += m_oaStatStack[m_oaStatStack.size()-2].m_lSize - m_oaStatStack.back().m_lSize; m_oStat.m_lOverhead += m_oaStatStack[m_oaStatStack.size()-2].m_lOverhead - m_oaStatStack.back().m_lOverhead; m_oStat.m_lAlphabet += m_oaStatStack[m_oaStatStack.size()-2].m_lAlphabet - m_oaStatStack.back().m_lAlphabet; m_oStat.m_lHuffmanTables += m_oaStatStack[m_oaStatStack.size()-2].m_lHuffmanTables - m_oaStatStack.back().m_lHuffmanTables; m_oStat.m_lTableSwitch += m_oaStatStack[m_oaStatStack.size()-2].m_lTableSwitch - m_oaStatStack.back().m_lTableSwitch; m_oStat.m_lHuffmanData += m_oaStatStack[m_oaStatStack.size()-2].m_lHuffmanData - m_oaStatStack.back().m_lHuffmanData; m_oaStatStack.pop_back(); } void CBQBStatistics::PopIgnoreStatistics() { if (m_oaStatStack.size() == 0) { m_IF.eprintf("CBQBStatistics::PopStatistics(): Error: Statistics stack is empty.\n"); abort(); } m_oaStatStack.pop_back(); } travis-src-190101/src/bqb_tools.h0100777000000000000000000002262413412725667013611 0ustar00/*********************************************************************************** LibBQB - File Format and Compression Algorithms for Trajectories of Volumetric Data and Atom Positions https://brehm-research.de/bqb Free software, licensed under GNU LGPL v3 Copyright (c) Martin Brehm and Martin Thomas, Martin Luther University Halle-Wittenberg, Germany, 2016 - 2019. Please cite: M. Brehm, M. Thomas: "An Efficient Lossless Compression Algorithm for Trajectories of Atom Positions and Volumetric Data", J. Chem. Inf. Model. 2018, 58 (10), pp 2092-2107. -------------------------------------------------------------------------------- LibBQB is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program. If not, see . ***********************************************************************************/ #ifndef BQB_TOOLS_H #define BQB_TOOLS_H // This must always be the first include directive #include "bqb_config.h" #include #include #include #include #include #include #include #include "bqb_largeinteger.h" #include "bqb_math.h" class CBQBInterface; #ifndef M_LOG2E #define M_LOG2E (1.44269504088896340736) // log2(e) #endif #define C_RUNA (0x7FFFFFFF) #define C_RUNB (0x7FFFFFFE) #define C_FULLNUMBER (0x7FFFFFFD) #define C_SPLIT (0x7FFFFFFC) #define C_OVERFLOW (0x7FFFFFFB) #define C_UNDERFLOW (0x7FFFFFFA) #define C_MIN_RESERVED (0x7FFFFFFA) #define C_MAX_RESERVED (0x7FFFFFFF) int GetAtomOrd(const char *s); #define UNUSED(a) (void)a #define Pi (3.1415926535897932385) #ifndef M_PI #define M_PI (3.1415926535897932385) #endif #define MIN(a,b) (((a)<=(b)) ? (a) : (b)) #define MAX(a,b) (((a)>=(b)) ? (a) : (b)) #define MIN3(a,b,c) MIN(MIN(a,b),c) #define MAX3(a,b,c) MAX(MAX(a,b),c) #define MIN4(a,b,c,d) MIN(MIN(a,b),MIN(c,d)) #define MAX4(a,b,c,d) MAX(MAX(a,b),MAX(c,d)) #define SQR(x) (x)*(x) #ifdef _MSC_VER // Visual Studio (at least old versions) do not have std::abs #define bqbabs(a) abs(a) #else #define bqbabs(a) std::abs(a) #endif class CBQBStatisticsSample { public: CBQBStatisticsSample() : m_lSize(0), m_lOverhead(0), m_lAlphabet(0), m_lHuffmanTables(0), m_lTableSwitch(0), m_lHuffmanData(0) { } void reset() { m_lSize = 0; m_lOverhead = 0; m_lAlphabet = 0; m_lHuffmanTables = 0; m_lTableSwitch = 0; m_lHuffmanData = 0; } BQBLargeInteger m_lSize; BQBLargeInteger m_lOverhead; BQBLargeInteger m_lAlphabet; BQBLargeInteger m_lHuffmanTables; BQBLargeInteger m_lTableSwitch; BQBLargeInteger m_lHuffmanData; }; class CBQBStatistics { public: CBQBStatistics(CBQBInterface &i) : m_IF(i) { } void PushStatistics(); void PopStatistics(); void PopDiffStatistics(); void PopIgnoreStatistics(); void ResetStatistics(); CBQBStatisticsSample m_oStat; std::vector m_oaStatStack; private: CBQBInterface &m_IF; }; // This helper class encapsulates all functions // which need to print to the screen (via CBQBInterface) class CBQBTools { public: CBQBTools(CBQBInterface &i) : m_IF(i) { } FILE* BQBOpenFileWrite(const char *buf, bool text); long FindIndexPosition(FILE *a); private: CBQBInterface &m_IF; }; int bqb_strcmp_nocase(const char *s1, const char *s2); bool BQBFileExist(const char *s); void BQBFormatTime(unsigned long eta, char *buf); inline int MoveToFrontValue(std::vector &ia, int val) { int rtmp, rll_i, rtmp2; int* ryy_j; rtmp = ia[1]; ia[1] = ia[0]; ryy_j = &(ia[1]); rll_i = val; while (rll_i != rtmp) { ryy_j++; rtmp2 = rtmp; rtmp = *ryy_j; *ryy_j = rtmp2; } ia[0] = rtmp; return (int)(ryy_j - &(ia[0])); } inline void MoveToFrontIndex(std::vector &ia, int idx) { /* int ti = ia[idx]; ia.insert(ia.begin(),ti); ia.erase(ia.begin()+idx+1);*/ int z, t; t = ia[idx]; for (z=idx-1;z>=0;z--) ia[z+1] = ia[z]; ia[0] = t; } inline bool IsAllIdentical(const std::vector &ia) { unsigned int z; if (ia.size() < 2) return true; for (z=1;z &ia, std::vector &runtable) { int i, v, j, z; bool b; runtable.resize(ia.size()); i = 0; j = 0; v = ia[0]; b = false; while (true) { i++; if (i >= (int)ia.size()) { i = 0; b = true; } if (ia[i] != v) { if (b) { for (z=j;z<(int)ia.size();z++) runtable[z] = (int)(i-z+ia.size()); for (z=0;z= 0) ? result : (result + b); } */ inline unsigned long reverse_bit_order(unsigned long u, int l) { unsigned long r; int z; r = 0; for (z=0;z exp2) mantis1 *= pow10i(exp1-exp2); else if (exp2 > exp1) mantis2 *= pow10i(exp2-exp1); // printf("@ %d vs %d\n",mantis1,mantis2); return (mantis1 == mantis2); } inline void fprintf_expo(FILE *a, long mantis, int signi, int expo) { fprintf( a, " %c0.%0*luE%c%02d", (mantis>=0)?' ':'-', signi, (unsigned long)bqbabs(mantis), ((expo+signi)>=0)?'+':'-', bqbabs(expo+signi) ); } inline long FloatToFixed(double f, int digits) { return (long)floor(f*pow10i(digits)+0.5); } inline double FixedToFloat(long l, int digits) { return (double)l*pow10(-digits); } /* inline void DumpFixed(long f, int digits) { m_IF.printf("%ld",f/pow10i(digits)); m_IF.printf("."); m_IF.printf("%0*ld",digits,f%pow10i(digits)); } */ inline int RoundCenter(double f) { if (f >= 0) return (int)floor(f); else return (int)ceil(f); } void PushNumeration(std::vector &ia, int n, int s1, int s2); bool bqbisinteger(const char *s); #endif travis-src-190101/src/chiral.cpp0100777000000000000000000004044313412725632013411 0ustar00/***************************************************************************** TRAVIS - Trajectory Analyzer and Visualizer http://www.travis-analyzer.de/ Copyright (c) 2009-2019 Martin Brehm 2012-2019 Martin Thomas 2016-2019 Sascha Gehrke This file was written by Martin Thomas. --------------------------------------------------------------------------- This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . *****************************************************************************/ // This must always be the first include directive #include "config.h" #include "chiral.h" #include "globalvar.h" #include "maintools.h" #include "xobarray.h" const char *GetRevisionInfo_chiral(unsigned int len) { static char buf[256]; GET_REVISION_INFO( buf, len ); return buf; } const char *GetSourceVersion_chiral() { static char buf[256]; GET_SOURCE_VERSION( buf ); return buf; } //#define BUF_SIZE 4096 static CxObArray g_chiralObserv; static bool g_fixTraj; static FILE *g_fixedTrajFile; CChiralObservation::CChiralObservation() { int i, j; // char buf[BUF_SIZE], buf2[BUF_SIZE]; // size_t remaining = BUF_SIZE; CxString buf, buf2; if(g_oaMolecules.GetSize() > 1) { /*#ifdef TARGET_LINUX remaining -= snprintf(buf, remaining, " Take atoms from which molecule ("); #else remaining -= sprintf(buf, " Take atoms from which molecule ("); #endif*/ buf.sprintf(" Take atoms from which molecule ("); for(i = 0; i < g_oaMolecules.GetSize(); i++) { /* if(remaining < 1) break; #ifdef TARGET_LINUX size_t length = snprintf(buf2, remaining, "%s=%d", ((CMolecule *)g_oaMolecules[i])->m_sName, i+1); #else size_t length = sprintf(buf2, "%s=%d", ((CMolecule *)g_oaMolecules[i])->m_sName, i+1); #endif strncat(buf, buf2, remaining - 1); remaining -= length;*/ buf2.sprintf("%s=%d", ((CMolecule *)g_oaMolecules[i])->m_sName, i+1); buf.strcat(buf2); if(i < g_oaMolecules.GetSize() - 1) { /*#ifdef TARGET_LINUX length = snprintf(buf2, remaining, ", "); #else length = sprintf(buf2, ", "); #endif strncat(buf, buf2, remaining - 1); remaining -= length;*/ buf2.sprintf(", "); buf.strcat(buf2); } } // strncat(buf, ")? ", remaining - 1); buf.strcat(")? "); m_iShowMol = AskRangeInteger_ND("%s", 1, g_oaMolecules.GetSize(), (const char*)buf) - 1; } else { m_iShowMol = 0; } m_iShowMolCount = ((CMolecule *)g_oaMolecules[m_iShowMol])->m_laSingleMolIndex.GetSize(); while(true) { // char buf[BUF_SIZE]; do { mprintf(" Which atom to take from molecule %s? ", ((CMolecule *)g_oaMolecules[m_iShowMol])->m_sName); inpprintf("! Which atom to take from molecule %s? ", ((CMolecule *)g_oaMolecules[m_iShowMol])->m_sName); myget(&buf); if(strlen(buf) == 0) { eprintf("There is no default. Please enter a character string.\n"); continue; } } while(!ParseAtom(buf, m_iShowMol, _ty, _rty, _atom)); CMolAtom *ma = NULL; CSingleMolecule *sm = (CSingleMolecule *)g_oaSingleMolecules[((CMolecule *)g_oaMolecules[m_iShowMol])->m_laSingleMolIndex[0]]; for(i = 0; i < sm->m_oaMolAtoms.GetSize(); i++) { ma = (CMolAtom *)sm->m_oaMolAtoms[i]; if((ma->m_iType == _ty) && (ma->m_iNumber == _atom)) break; ma = NULL; } if(ma == NULL) { eprintf("CChiralObservation::CChiralObservation(): Internal error.\n"); abort(); } mprintf(" This atom has %d bonds.\n", ma->m_oaBonds.GetSize()); if(ma->m_oaBonds.GetSize() == 4) { mprintf(" The connected atoms are "); for(i = 0; i < 4; i++) { if(i > 0) mprintf(", "); mprintf("%s%d", (const char*)((CAtom *)g_oaAtoms[sm->m_baAtomIndex[((CMolAtom *)ma->m_oaBonds[i])->m_iType]])->m_sName, ((CMolAtom *)ma->m_oaBonds[i])->m_iNumber+1); } mprintf(".\n"); break; } mprintf(RED, "Please choose an atom with 4 bonds\n"); } _molAtoms.SetMaxSize(m_iShowMolCount); _orderArrays.SetMaxSize(m_iShowMolCount); for(i = 0; i < m_iShowMolCount; i++) { CMolAtom *ma = NULL; CSingleMolecule *sm = (CSingleMolecule *)g_oaSingleMolecules[((CMolecule *)g_oaMolecules[m_iShowMol])->m_laSingleMolIndex[i]]; for(j = 0; j < sm->m_oaMolAtoms.GetSize(); j++) { ma = (CMolAtom *)sm->m_oaMolAtoms[j]; if((ma->m_iType == _ty) && (ma->m_iNumber == _atom)) break; ma = NULL; } if(ma == NULL) { eprintf("CChiralObservation::CChiralObservation(): Internal error.\n"); abort(); } _molAtoms.Add(ma); CxIntArray *a; try { a = new CxIntArray(); } catch(...) { a = NULL; } if(a == NULL) NewException((double)sizeof(CxIntArray), __FILE__, __LINE__, __PRETTY_FUNCTION__); a->SetSize(4); _orderArrays.Add(a); for(j = 0; j < 4; j++) a->GetAt(j) = -1; double ac; int index = 0; do { ac = 0.0; for(j = 0; j < 4; j++) if((a->GetAt(j) == -1) && (((CMolAtom *)ma->m_oaBonds[j])->m_fAtomCode > ac)) ac = ((CMolAtom *)ma->m_oaBonds[j])->m_fAtomCode; int minNum = sm->m_oaMolAtoms.GetSize(); int minIndex; while(true) { minIndex = 5; for(j = 0; j < 4; j++) { if((a->GetAt(j) == -1) && (((CMolAtom *)ma->m_oaBonds[j])->m_fAtomCode == ac) && (((CMolAtom *)ma->m_oaBonds[j])->m_iNumber < minNum)) { minNum = ((CMolAtom *)ma->m_oaBonds[j])->m_iNumber; minIndex = j; } } if(minIndex == 5) break; a->GetAt(minIndex) = index++; } } while(ac > 0.0); } mprintf(" The priority of the connected atoms is "); for(i = 0; i < 4; i++) { int a = ((CxIntArray *)_orderArrays[0])->GetPosition(i); if(i > 0) mprintf(" > "); mprintf("%s%d", (const char*)((CAtom *)g_oaAtoms[((CSingleMolecule *)g_oaSingleMolecules[((CMolecule *)g_oaMolecules[m_iShowMol])->m_laSingleMolIndex[0]])->m_baAtomIndex[((CMolAtom *)((CMolAtom *)_molAtoms[0])->m_oaBonds[a])->m_iType]])->m_sName, ((CMolAtom *)((CMolAtom *)_molAtoms[0])->m_oaBonds[a])->m_iNumber+1); } mprintf(".\n"); if(g_fixTraj) { _fixTraj = AskYesNo("\n Adjust chirality for this atom (y/n)? [yes] ", true); if(_fixTraj) { // char buf[BUF_SIZE], buf2[BUF_SIZE]; // buf[0] = 0; // size_t remaining = BUF_SIZE; buf = ""; for(i = 0; i < 4; i++) { int a = ((CxIntArray *)_orderArrays[0])->GetPosition(i); /*#ifdef TARGET_LINUX size_t length = snprintf(buf2, BUF_SIZE, "%s%d=%d", ((CAtom *)g_oaAtoms[((CSingleMolecule *)g_oaSingleMolecules[((CMolecule *)g_oaMolecules[m_iShowMol])->m_laSingleMolIndex[0]])->m_baAtomIndex[((CMolAtom *)((CMolAtom *)_molAtoms[0])->m_oaBonds[a])->m_iType]])->m_sName, ((CMolAtom *)((CMolAtom *)_molAtoms[0])->m_oaBonds[a])->m_iNumber+1, i+1); #else size_t length = sprintf(buf2, "%s%d=%d", ((CAtom *)g_oaAtoms[((CSingleMolecule *)g_oaSingleMolecules[((CMolecule *)g_oaMolecules[m_iShowMol])->m_laSingleMolIndex[0]])->m_baAtomIndex[((CMolAtom *)((CMolAtom *)_molAtoms[0])->m_oaBonds[a])->m_iType]])->m_sName, ((CMolAtom *)((CMolAtom *)_molAtoms[0])->m_oaBonds[a])->m_iNumber+1, i+1); #endif strncat(buf, buf2, remaining - 1); remaining -= length;*/ buf2.sprintf("%s%d=%d", (const char*)((CAtom *)g_oaAtoms[((CSingleMolecule *)g_oaSingleMolecules[((CMolecule *)g_oaMolecules[m_iShowMol])->m_laSingleMolIndex[0]])->m_baAtomIndex[((CMolAtom *)((CMolAtom *)_molAtoms[0])->m_oaBonds[a])->m_iType]])->m_sName, ((CMolAtom *)((CMolAtom *)_molAtoms[0])->m_oaBonds[a])->m_iNumber+1, i+1); buf.strcat(buf2); if(i < 3) { /*#ifdef TARGET_LINUX length = snprintf(buf2, BUF_SIZE, ", "); #else length = sprintf(buf2, ", "); #endif strncat(buf, buf2, remaining - 1); remaining -= length;*/ buf2.sprintf(", "); buf.strcat(buf2); } } mprintf(" Please enter the atoms to swap: (%s)\n", (const char*)buf); int a1 = AskRangeInteger_ND(" 1st atom: ", 1, 4); int a2 = AskRangeInteger_ND(" 2nd atom: ", 1, 4); if(((CMolAtom *)((CMolAtom *)_molAtoms[i])->m_oaBonds[((CxIntArray *)_orderArrays[i])->GetPosition(a1-1)])->m_fAtomCode != ((CMolAtom *)((CMolAtom *)_molAtoms[i])->m_oaBonds[((CxIntArray *)_orderArrays[i])->GetPosition(a2-1)])->m_fAtomCode) eprintf("Warning: These atoms are not equivalent!"); _swapOffsets[0].SetMaxSize(m_iShowMolCount); _swapOffsets[1].SetMaxSize(m_iShowMolCount); for(i = 0; i < m_iShowMolCount; i++) { _swapOffsets[0].Add(((CMolAtom *)((CMolAtom *)_molAtoms[i])->m_oaBonds[((CxIntArray *)_orderArrays[i])->GetPosition(a1-1)])->m_iOffset); _swapOffsets[1].Add(((CMolAtom *)((CMolAtom *)_molAtoms[i])->m_oaBonds[((CxIntArray *)_orderArrays[i])->GetPosition(a2-1)])->m_iOffset); } _fixToR = AskYesNo(" Adjust chirality to R (y) or S (n)? [yes] ", true); } } else { _fixTraj = false; } } CChiralObservation::~CChiralObservation() { int i; for(i = 0; i < m_iShowMolCount; i++) { delete (CxIntArray *)_orderArrays[i]; delete (CxDoubleArray *)_timedev[i]; } } void CChiralObservation::initialize() { int i; int n; if(g_iTrajSteps != -1) n = (int)(1.1 * g_iTrajSteps / g_iStride); else n = 10000; mprintf(" Absolute configuration time development: Trying to allocate %s of memory...\n", FormatBytes((double)m_iShowMolCount * n * sizeof(double))); for(i = 0; i < m_iShowMolCount; i++) { CxDoubleArray *a; try { a = new CxDoubleArray(); } catch(...) { a = NULL; } if(a == NULL) NewException((double)sizeof(CxDoubleArray), __FILE__, __LINE__, __PRETTY_FUNCTION__); a->SetMaxSize(n); a->SetGrow((int)(0.1 * n)); _timedev.Add(a); } } void CChiralObservation::process(CTimeStep *ts) { int i; for(i = 0; i < m_iShowMolCount; i++) { CMolAtom *ma = (CMolAtom *)_molAtoms[i]; CxIntArray *a = (CxIntArray *)_orderArrays[i]; CxDVector3 vec1, vec2, vec3; vec1 = FoldVector(ts->m_vaCoords[((CMolAtom *)ma->m_oaBonds[a->GetPosition(0)])->m_iOffset] - ts->m_vaCoords[((CMolAtom *)ma->m_oaBonds[a->GetPosition(1)])->m_iOffset]); vec2 = FoldVector(ts->m_vaCoords[ma->m_iOffset] - ts->m_vaCoords[((CMolAtom *)ma->m_oaBonds[a->GetPosition(2)])->m_iOffset]); vec3 = FoldVector(ts->m_vaCoords[((CMolAtom *)ma->m_oaBonds[a->GetPosition(2)])->m_iOffset] - ts->m_vaCoords[((CMolAtom *)ma->m_oaBonds[a->GetPosition(1)])->m_iOffset]); double dih = Dihedral(vec1, vec2, vec3, false); ((CxDoubleArray *)_timedev[i])->Add(dih); } } void CChiralObservation::finalize() { int i, j; // char name[BUF_SIZE]; CxString name; /*#ifdef TARGET_LINUX snprintf(name, BUF_SIZE, "chiral_%s_%s%d.dat", ((CMolecule *)g_oaMolecules[m_iShowMol])->m_sName, ((CAtom *)g_oaAtoms[((CSingleMolecule *)g_oaSingleMolecules[((CMolecule *)g_oaMolecules[m_iShowMol])->m_laSingleMolIndex[0]])->m_baAtomIndex[((CMolAtom *)_molAtoms[0])->m_iType]])->m_sName, ((CMolAtom *)_molAtoms[0])->m_iNumber+1); #else sprintf(name, "chiral_%s_%s%d.dat", ((CMolecule *)g_oaMolecules[m_iShowMol])->m_sName, ((CAtom *)g_oaAtoms[((CSingleMolecule *)g_oaSingleMolecules[((CMolecule *)g_oaMolecules[m_iShowMol])->m_laSingleMolIndex[0]])->m_baAtomIndex[((CMolAtom *)_molAtoms[0])->m_iType]])->m_sName, ((CMolAtom *)_molAtoms[0])->m_iNumber+1); #endif*/ name.sprintf("chiral_%s_%s%d.dat", ((CMolecule *)g_oaMolecules[m_iShowMol])->m_sName, (const char*)((CAtom *)g_oaAtoms[((CSingleMolecule *)g_oaSingleMolecules[((CMolecule *)g_oaMolecules[m_iShowMol])->m_laSingleMolIndex[0]])->m_baAtomIndex[((CMolAtom *)_molAtoms[0])->m_iType]])->m_sName, ((CMolAtom *)_molAtoms[0])->m_iNumber+1); mprintf(" Writing chirality data to %s...\n", (const char*)name); FILE *chiralFile = OpenFileWrite(name, false); for(i = 0; i < ((CxDoubleArray *)_timedev[0])->GetSize(); i++) { fprintf(chiralFile, "%d", i+1); for(j = 0; j < m_iShowMolCount; j++) { if(i > 0) { if((((CxDoubleArray *)_timedev[j])->GetAt(i)) > 0.0 && (((CxDoubleArray *)_timedev[j])->GetAt(i-1) <= 0.0)) mprintf(RED, "Warning: Molecule %d changed configuration from S to R in step %d.\n", j+1, i+1); if((((CxDoubleArray *)_timedev[j])->GetAt(i)) <= 0.0 && (((CxDoubleArray *)_timedev[j])->GetAt(i-1) > 0.0)) mprintf(RED, "Warning: Molecule %d changed configuration from R to S in step %d.\n", j+1, i+1); } fprintf(chiralFile, " %s", ((CxDoubleArray *)_timedev[j])->GetAt(i) > 0.0 ? "R" : "S"); } fprintf(chiralFile, "\n"); } fclose(chiralFile); } int CChiralObservation::swapAtom(int offset) { if(!_fixTraj) return offset; int a = _swapOffsets[0].GetPosition(offset); if(a != -1) { bool lastStepR = ((CxDoubleArray *)_timedev[a])->GetAt(((CxDoubleArray *)_timedev[a])->GetSize()-1) > 0.0; if(lastStepR != _fixToR) return _swapOffsets[1].GetAt(a); else return offset; } else { a = _swapOffsets[1].GetPosition(offset); if(a != -1) { bool lastStepR = ((CxDoubleArray *)_timedev[a])->GetAt(((CxDoubleArray *)_timedev[a])->GetSize()-1) > 0.0; if(lastStepR != _fixToR) return _swapOffsets[0].GetAt(a); else return offset; } } return offset; } bool gatherChiral() { g_fixTraj = AskYesNo(" Swap equivalent atoms to have same chirality in all molecules (y/n)? [no] ", false); if(g_fixTraj) g_bKeepOriginalCoords = true; mprintf("\n"); while(true) { mprintf(YELLOW, ">>> Chirality Observation %d >>>\n\n", g_chiralObserv.GetSize() + 1); CChiralObservation *obs; try { obs = new CChiralObservation(); } catch(...) { obs = NULL; } if(obs == NULL) NewException((double)sizeof(CChiralObservation), __FILE__, __LINE__, __PRETTY_FUNCTION__); g_chiralObserv.Add(obs); mprintf(YELLOW, "\n<<< End of Chirality Observation %d <<<\n\n", g_chiralObserv.GetSize()); if(!AskYesNo(" Add another observation (y/n)? [no] ", false)) break; mprintf("\n"); } mprintf("\n"); return true; } bool initializeChiral() { int i; CxString filename, buf; if(g_fixTraj) { // char filename[BUF_SIZE]; #ifdef TARGET_LINUX // char buf[BUF_SIZE]; // strncpy(buf, g_sInputTraj, BUF_SIZE); // buf[BUF_SIZE-1] = 0; buf.strcpy(g_sInputTraj); char *p = strrchr(buf.GetWritePointer(), '/'); if (p == NULL) p = buf.GetWritePointer(); else p++; size_t s = strcspn(p, "."); if ((int)s > buf.GetLength() - 8) s = (size_t)buf.GetLength() - 8; // strncpy(filename, p, s); filename.strcpy(p); filename(s) = 0; // strcat(filename, "_out.xyz"); filename.strcat("_out.xyz"); #else // sprintf(filename, "out.xyz"); filename.sprintf("out.xyz"); #endif mprintf(" Saving processed trajectory as %s\n\n", (const char*)filename); g_fixedTrajFile = OpenFileWrite(filename, false); } for(i = 0; i < g_chiralObserv.GetSize(); i++) { mprintf(" Initializing Chirality Observation %d...\n", i+1); ((CChiralObservation *)g_chiralObserv[i])->initialize(); } return true; } void processChiral(CTimeStep *ts) { int i, j; for(i = 0; i < g_chiralObserv.GetSize(); i++) { ((CChiralObservation *)g_chiralObserv[i])->process(ts); } if(g_fixTraj) { CxIntArray fixedOrder; fixedOrder.SetMaxSize(g_iGesAtomCount); for(i = 0; i < g_iGesAtomCount; i++) { int si = i; for(j = 0; j < g_chiralObserv.GetSize(); j++) { si = ((CChiralObservation *)g_chiralObserv[j])->swapAtom(i); if(si != i) break; } fixedOrder.Add(si); } fprintf(g_fixedTrajFile, "%d\n", fixedOrder.GetSize()); if(ts->m_pComment != NULL) fprintf(g_fixedTrajFile, "%s\n", ts->m_pComment); else fprintf(g_fixedTrajFile, "\n"); for(i = 0; i < fixedOrder.GetSize(); i++) { fprintf(g_fixedTrajFile, "%4s %14.10f %14.10f %14.10f\n", (const char*)((CAtom *)g_oaAtoms[g_waAtomRealElement[fixedOrder[i]]])->m_sName, ts->m_vaCoords_Original[fixedOrder[i]][0] / 100.0, ts->m_vaCoords_Original[fixedOrder[i]][1] / 100.0, ts->m_vaCoords_Original[fixedOrder[i]][2] / 100.0); } } } void finalizeChiral() { int i; if(g_fixTraj) { fclose(g_fixedTrajFile); } for(i = 0; i < g_chiralObserv.GetSize(); i++) { mprintf(YELLOW, ">>> Chirality Observation %d >>>\n\n", i+1); ((CChiralObservation *)g_chiralObserv[i])->finalize(); mprintf(YELLOW, "\n<<< End of Chirality Observation %d <<<\n\n", i+1); } for(i = 0; i < g_chiralObserv.GetSize(); i++) delete (CChiralObservation *)g_chiralObserv[i]; } travis-src-190101/src/chiral.h0100777000000000000000000000341513412725647013062 0ustar00/***************************************************************************** TRAVIS - Trajectory Analyzer and Visualizer http://www.travis-analyzer.de/ Copyright (c) 2009-2019 Martin Brehm 2012-2019 Martin Thomas 2016-2019 Sascha Gehrke This file was written by Martin Thomas. --------------------------------------------------------------------------- This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . *****************************************************************************/ #ifndef CHIRAL_H #define CHIRAL_H // This must always be the first include directive #include "config.h" #include "moltools.h" #include "xobarray.h" class CTimeStep; class CChiralObservation: public CObservation { public: CChiralObservation(); ~CChiralObservation(); void initialize(); void process(CTimeStep *ts); void finalize(); int swapAtom(int offset); private: int _ty, _rty, _atom; CxObArray _molAtoms; CxObArray _orderArrays; CxObArray _timedev; bool _fixTraj; CxIntArray _swapOffsets[2]; bool _fixToR; }; bool gatherChiral(); bool initializeChiral(); void processChiral(CTimeStep *ts); void finalizeChiral(); #endif travis-src-190101/src/config.h0100777000000000000000000003443213412725657013071 0ustar00/***************************************************************************** TRAVIS - Trajectory Analyzer and Visualizer http://www.travis-analyzer.de/ Copyright (c) 2009-2019 Martin Brehm 2012-2019 Martin Thomas 2016-2019 Sascha Gehrke This file was written by Martin Brehm. --------------------------------------------------------------------------- This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . *****************************************************************************/ // This file is always included before any other include file. #ifndef CONFIG_H #define CONFIG_H // Last change to this version of the source code #define SOURCE_VERSION "Jan 01 2019" /* Please uncomment / comment out the flags you want to use / not to use. */ // You have to change this according to your target operating system. // For a generic platform-independent build, comment out both lines. //#define TARGET_WINDOWS // Tested with Microsoft Visual Studio #define TARGET_LINUX // Tested with GNU C++ compiler on GNU/Linux // Uncomment the following line for an official release //#define RELEASE_VERSION "1.14.0" // Use color for screen output? #define USE_COLOR // Maximum number of bonds any atom may form #define MAX_BONDS 8 // Activate if you have OpenBabel in the system search path //#define USE_OPENBABEL // Use the FFTW library? Otherwise, the built-in KISS-FFT routine is used (default) //#define USE_FFTW // Bound checking in dynamic arrays? #define DEBUG_ARRAYS // Handle volumetric data in single or double precision? Active=double, inactive=single #define VORI_DOUBLE // Use faster hard-coded string to floating point conversion (atof). // This speeds up reading CUBE files by a factor of > 2, and also other file formats. // Seems to give identical results to system atof(), but comment out if problems occur. #define FAST_ATOF #ifdef VORI_DOUBLE #define VORI_FLOAT double #else #define VORI_FLOAT float #endif /***************************************************************************/ // Some "hardcore" debug flags // Warning: They may drastically decrease performance /***************************************************************************/ // Activate debug backtrace? //#define DEBUG_BACKTRACE //#define DEBUG_EXTENDED_BACKTRACE //#define DEBUG_DATABASE //#define DEBUG_CSTRING //#define DEBUG_MATULTRA //#define DEBUG_CVECTOR3 //#define DEBUG_CDVECTOR3 //#define DEBUG_COBARRAY //#define DEBUG_CPTRARRAY //#define DEBUG_CWORDARRAY //#define DEBUG_CLONGARRAY //#define DEBUG_CINTARRAY //#define DEBUG_CFLOATARRAY //#define DEBUG_CDOUBLEARRAY //#define DEBUG_CVEC3ARRAY //#define DEBUG_CDVEC3ARRAY #define _FILE_OFFSET_BITS 64 #ifdef TARGET_WINDOWS #pragma warning(disable:4786) // Warning "Debug Info truncated to 255 characters" #pragma warning(disable:4702) // Warning "Unreachable Code" #define _CRT_SECURE_NO_WARNINGS #define _CRT_SECURE_NO_DEPRECATE #endif // Revision Information #include #define GET_REVISION_INFO(X,LEN) { if (LEN == 0) sprintf( X, "%s", "\"" __FILE__ "\"" ); else sprintf( X, "File %-*s compiled at %s %s, source version %s.", LEN, "\"" __FILE__ "\"", __DATE__, __TIME__, SOURCE_VERSION ); } #define GET_SOURCE_VERSION(X) sprintf( X, "%s", SOURCE_VERSION ) const char *GetRevisionInfo_2df(unsigned int len); const char *GetSourceVersion_2df(); const char *GetRevisionInfo_acf(unsigned int len); const char *GetSourceVersion_acf(); const char *GetRevisionInfo_analysisgroup(unsigned int len); const char *GetSourceVersion_analysisgroup(); const char *GetRevisionInfo_asciiart(unsigned int len); const char *GetSourceVersion_asciiart(); const char *GetRevisionInfo_atomgroup(unsigned int len); const char *GetSourceVersion_atomgroup(); const char *GetRevisionInfo_backtrace(unsigned int len); const char *GetSourceVersion_backtrace(); const char *GetRevisionInfo_base64(unsigned int len); const char *GetSourceVersion_base64(); const char *GetRevisionInfo_bicgstab(unsigned int len); const char *GetSourceVersion_bicgstab(); const char *GetRevisionInfo_bintools(unsigned int len); const char *GetSourceVersion_bintools(); const char *GetRevisionInfo_bintree(unsigned int len); const char *GetSourceVersion_bintree(); const char *GetRevisionInfo_bqb_alphabet(unsigned int len); const char *GetSourceVersion_bqb_alphabet(); const char *GetRevisionInfo_bqb_bitset(unsigned int len); const char *GetSourceVersion_bqb_bitset(); const char *GetRevisionInfo_bqb_crc(unsigned int len); const char *GetSourceVersion_bqb_crc(); const char *GetRevisionInfo_bqb_cubeframe(unsigned int len); const char *GetSourceVersion_bqb_cubeframe(); const char *GetRevisionInfo_bqb_driver(unsigned int len); const char *GetSourceVersion_bqb_driver(); const char *GetRevisionInfo_bqb_engine(unsigned int len); const char *GetSourceVersion_bqb_engine(); const char *GetRevisionInfo_bqb_extrapolator(unsigned int len); const char *GetSourceVersion_bqb_extrapolator(); const char *GetRevisionInfo_bqb_format(unsigned int len); const char *GetSourceVersion_bqb_format(); const char *GetRevisionInfo_bqb_hilbert(unsigned int len); const char *GetSourceVersion_bqb_hilbert(); const char *GetRevisionInfo_bqb_hufftree(unsigned int len); const char *GetSourceVersion_bqb_hufftree(); const char *GetRevisionInfo_bqb_integerengine(unsigned int len); const char *GetSourceVersion_bqb_integerengine(); const char *GetRevisionInfo_bqb_interface(unsigned int len); const char *GetSourceVersion_bqb_interface(); const char *GetRevisionInfo_bqb_largeinteger(unsigned int len); const char *GetSourceVersion_bqb_largeinteger(); const char *GetRevisionInfo_bqb_linalg(unsigned int len); const char *GetSourceVersion_bqb_linalg(); const char *GetRevisionInfo_bqb_math(unsigned int len); const char *GetSourceVersion_bqb_math(); const char *GetRevisionInfo_bqb_parmset(unsigned int len); const char *GetSourceVersion_bqb_parmset(); const char *GetRevisionInfo_bqb_tools(unsigned int len); const char *GetSourceVersion_bqb_tools(); const char *GetRevisionInfo_bqbtool(unsigned int len); const char *GetSourceVersion_bqbtool(); const char *GetRevisionInfo_chiral(unsigned int len); const char *GetSourceVersion_chiral(); const char *GetRevisionInfo_dacf(unsigned int len); const char *GetSourceVersion_dacf(); const char *GetRevisionInfo_database(unsigned int len); const char *GetSourceVersion_database(); const char *GetRevisionInfo_df(unsigned int len); const char *GetSourceVersion_df(); const char *GetRevisionInfo_diagonal(unsigned int len); const char *GetSourceVersion_diagonal(); const char *GetRevisionInfo_domain(unsigned int len); const char *GetSourceVersion_domain(); const char *GetRevisionInfo_elementdata(unsigned int len); const char *GetSourceVersion_elementdata(); const char *GetRevisionInfo_fdf(unsigned int len); const char *GetSourceVersion_fdf(); const char *GetRevisionInfo_fft(unsigned int len); const char *GetSourceVersion_fft(); const char *GetRevisionInfo_fixplproj(unsigned int len); const char *GetSourceVersion_fixplproj(); const char *GetRevisionInfo_gather(unsigned int len); const char *GetSourceVersion_gather(); const char *GetRevisionInfo_globalvar(unsigned int len); const char *GetSourceVersion_globalvar(); const char *GetRevisionInfo_grace(unsigned int len); const char *GetSourceVersion_grace(); const char *GetRevisionInfo_hbond(unsigned int len); const char *GetSourceVersion_hbond(); const char *GetRevisionInfo_interface(unsigned int len); const char *GetSourceVersion_interface(); const char *GetRevisionInfo_internalcoord(unsigned int len); const char *GetSourceVersion_internalcoord(); const char *GetRevisionInfo_ionpair(unsigned int len); const char *GetSourceVersion_ionpair(); const char *GetRevisionInfo_ir(unsigned int len); const char *GetSourceVersion_ir(); const char *GetRevisionInfo_kiss_fft(unsigned int len); const char *GetSourceVersion_kiss_fft(); const char *GetRevisionInfo_largeinteger(unsigned int len); const char *GetSourceVersion_largeinteger(); const char *GetRevisionInfo_linalg(unsigned int len); const char *GetSourceVersion_linalg(); const char *GetRevisionInfo_lmmin(unsigned int len); const char *GetSourceVersion_lmmin(); const char *GetRevisionInfo_lmwrapper(unsigned int len); const char *GetSourceVersion_lmwrapper(); const char *GetRevisionInfo_lu_decomp(unsigned int len); const char *GetSourceVersion_lu_decomp(); const char *GetRevisionInfo_luzar(unsigned int len); const char *GetSourceVersion_luzar(); const char *GetRevisionInfo_maintools(unsigned int len); const char *GetSourceVersion_maintools(); const char *GetRevisionInfo_moltools(unsigned int len); const char *GetSourceVersion_moltools(); const char *GetRevisionInfo_nbexchange(unsigned int len); const char *GetSourceVersion_nbexchange(); const char *GetRevisionInfo_nbsearch(unsigned int len); const char *GetSourceVersion_nbsearch(); const char *GetRevisionInfo_normalcoordinate(unsigned int len); const char *GetSourceVersion_normalcoordinate(); const char *GetRevisionInfo_normalmode(unsigned int len); const char *GetSourceVersion_normalmode(); const char *GetRevisionInfo_order(unsigned int len); const char *GetSourceVersion_order(); const char *GetRevisionInfo_order_chain(unsigned int len); const char *GetSourceVersion_order_chain(); const char *GetRevisionInfo_order_vector(unsigned int len); const char *GetSourceVersion_order_vector(); const char *GetRevisionInfo_pdf(unsigned int len); const char *GetSourceVersion_pdf(); const char *GetRevisionInfo_plproj(unsigned int len); const char *GetSourceVersion_plproj(); const char *GetRevisionInfo_posdomain(unsigned int len); const char *GetSourceVersion_posdomain(); const char *GetRevisionInfo_qr_fact(unsigned int len); const char *GetSourceVersion_qr_fact(); const char *GetRevisionInfo_raman(unsigned int len); const char *GetSourceVersion_raman(); const char *GetRevisionInfo_random(unsigned int len); const char *GetSourceVersion_random(); const char *GetRevisionInfo_reflux(unsigned int len); const char *GetSourceVersion_reflux(); const char *GetRevisionInfo_region(unsigned int len); const char *GetSourceVersion_region(); const char *GetRevisionInfo_reordyn(unsigned int len); const char *GetSourceVersion_reordyn(); const char *GetRevisionInfo_revsdf(unsigned int len); const char *GetSourceVersion_revsdf(); const char *GetRevisionInfo_roa(unsigned int len); const char *GetSourceVersion_roa(); const char *GetRevisionInfo_sdfmap(unsigned int len); const char *GetSourceVersion_sdfmap(); const char *GetRevisionInfo_spectrum(unsigned int len); const char *GetSourceVersion_spectrum(); const char *GetRevisionInfo_statistics(unsigned int len); const char *GetSourceVersion_statistics(); const char *GetRevisionInfo_structurefactor(unsigned int len); const char *GetSourceVersion_structurefactor(); const char *GetRevisionInfo_tensor(unsigned int len); const char *GetSourceVersion_tensor(); const char *GetRevisionInfo_tetrapak(unsigned int len); const char *GetSourceVersion_tetrapak(); const char *GetRevisionInfo_timestep(unsigned int len); const char *GetSourceVersion_timestep(); const char *GetRevisionInfo_tools(unsigned int len); const char *GetSourceVersion_tools(); const char *GetRevisionInfo_travis(unsigned int len); const char *GetSourceVersion_travis(); const char *GetRevisionInfo_v_base(unsigned int len); const char *GetSourceVersion_v_base(); const char *GetRevisionInfo_v_base_wl(unsigned int len); const char *GetSourceVersion_v_base_wl(); const char *GetRevisionInfo_v_cell(unsigned int len); const char *GetSourceVersion_v_cell(); const char *GetRevisionInfo_v_common(unsigned int len); const char *GetSourceVersion_v_common(); const char *GetRevisionInfo_v_compute(unsigned int len); const char *GetSourceVersion_v_compute(); const char *GetRevisionInfo_v_container(unsigned int len); const char *GetSourceVersion_v_container(); const char *GetRevisionInfo_v_container_prd(unsigned int len); const char *GetSourceVersion_v_container_prd(); const char *GetRevisionInfo_v_pre_container(unsigned int len); const char *GetSourceVersion_v_pre_container(); const char *GetRevisionInfo_v_unitcell(unsigned int len); const char *GetSourceVersion_v_unitcell(); const char *GetRevisionInfo_v_wall(unsigned int len); const char *GetSourceVersion_v_wall(); const char *GetRevisionInfo_vorowrapper(unsigned int len); const char *GetSourceVersion_vorowrapper(); const char *GetRevisionInfo_xbytearray(unsigned int len); const char *GetSourceVersion_xbytearray(); const char *GetRevisionInfo_xdf(unsigned int len); const char *GetSourceVersion_xdf(); const char *GetRevisionInfo_xdmatrix3(unsigned int len); const char *GetSourceVersion_xdmatrix3(); const char *GetRevisionInfo_xdmatrixmn(unsigned int len); const char *GetSourceVersion_xdmatrixmn(); const char *GetRevisionInfo_xdoublearray(unsigned int len); const char *GetSourceVersion_xdoublearray(); const char *GetRevisionInfo_xdvec3array(unsigned int len); const char *GetSourceVersion_xdvec3array(); const char *GetRevisionInfo_xdvector3(unsigned int len); const char *GetSourceVersion_xdvector3(); const char *GetRevisionInfo_xdvectorn(unsigned int len); const char *GetSourceVersion_xdvectorn(); const char *GetRevisionInfo_xintarray(unsigned int len); const char *GetSourceVersion_xintarray(); const char *GetRevisionInfo_xlongarray(unsigned int len); const char *GetSourceVersion_xlongarray(); const char *GetRevisionInfo_xmemfile(unsigned int len); const char *GetSourceVersion_xmemfile(); const char *GetRevisionInfo_xobarray(unsigned int len); const char *GetSourceVersion_xobarray(); const char *GetRevisionInfo_xptrarray(unsigned int len); const char *GetSourceVersion_xptrarray(); const char *GetRevisionInfo_string(unsigned int len); const char *GetSourceVersion_string(); const char *GetRevisionInfo_xwordarray(unsigned int len); const char *GetSourceVersion_xwordarray(); const char *GetRevisionInfo_ziggurat(unsigned int len); const char *GetSourceVersion_ziggurat(); #endif travis-src-190101/src/conversion.h0100777000000000000000000000661313412725660014003 0ustar00/***************************************************************************** TRAVIS - Trajectory Analyzer and Visualizer http://www.travis-analyzer.de/ Copyright (c) 2009-2019 Martin Brehm 2012-2019 Martin Thomas 2016-2019 Sascha Gehrke This file was written by Martin Brehm and Martin Thomas. --------------------------------------------------------------------------- This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . *****************************************************************************/ #ifndef CONVERSION_H #define CONVERSION_H // This must always be the first include directive #include "config.h" // Physical constants #define CONST_ATOMIC_MASS_UNIT (1.660538921E-27) // CODATA 2010, Atomic mass unit in kg #define CONST_BOHR_MAGNETON (927.400968E-26) // CODATA 2010, Bohr magneton in A*m^2 #define CONST_BOHR_RADIUS (0.52917721092E-10) // CODATA 2010, Bohr radius in m #define CONST_ELEMENTARY_CHARGE (1.602176565E-19) // CODATA 2010, Elementary charge in C #define CONST_SPEED_OF_LIGHT (299792458.0) // CODATA 2010, Vacuum speed of light in m/s #define CONST_AVOGADRO (6.02214085774E23) // Avogadro's number in 1/mol #define CONST_EPSILON0 (8.8541878176E-12) // Vacuum permittivity in F/m #define CONST_PLANCK (6.626070040E-34) // Planck constant #define CONST_BOLTZMANN (1.38064852E-23) // Boltzmann Constant // Length conversion #define LEN_AU2PM (52.917721092) // Atomic units to pm: CONST_BOHR_RADIUS*1E12 // Time conversion #define TIME_AU2FS (0.02418884326505) // Atomic units to fs // Energy conversion (greetings to the Max Planck Institute :-D ) #define ENER_HARTREE2KJMOL (2625.4995) // Dipole moment conversion #define DIP_DEBYE2CM (3.335640952E-30) // Debye to C*m: 1E-21/CONST_SPEED_OF_LIGHT #define DIP_EPM2DEBYE (0.04803204506) // Elementary charge*pm to Debye: CONST_ELEMENTARY_CHARGE*CONST_SPEED_OF_LIGHT*1E9 // Electric field strength conversion #define EFIELD_AU2VPM (0.514220652) // Atomic unit of electric field "Eh / (e * a0)" to "V/pm" // Total current conversion #define CURR_AUFS2MBPM (9.142057808E-4) // Atomic unit of dipole moment/fs to Bohr magneton/pm: CONST_ELEMENTARY_CHARGE*CONST_BOHR_RADIUS*1E3/CONST_BOHR_MAGNETON #define CURR_EMS2MBPM (1.727598547E-8) // Elementary charge*m/s to Bohr magneton/pm: CONST_ELEMENTARY_CHARGE*1E-12/CONST_BOHR_MAGNETON #define CURR_MBPM2CMS (9.27400968114E-12) // Bohr magneton/pm to Coulomb*m/s: CONST_BOHR_MAGNETON/CONST_ELEMENTARY_CHARGE/1E-12*CONST_ELEMENTARY_CHARGE // Magnetic moment conversion #define MAG_AUPMFS2MB (9.142057808E-4) // Atomic unit of dipole moment*pm/fs to Bohr magneton: CONST_ELEMENTARY_CHARGE*CONST_BOHR_RADIUS*1E3/CONST_BOHR_MAGNETON #define MAG_EPMMS2MB (1.727598547E-8) // Elementary charge*pm*m/s to Bohr magneton: CONST_ELEMENTARY_CHARGE*1E-12/CONST_BOHR_MAGNETON #endif travis-src-190101/src/dacf.cpp0100777000000000000000000012604013412725620013037 0ustar00/***************************************************************************** TRAVIS - Trajectory Analyzer and Visualizer http://www.travis-analyzer.de/ Copyright (c) 2009-2019 Martin Brehm 2012-2019 Martin Thomas 2016-2019 Sascha Gehrke This file was written by Martin Brehm. --------------------------------------------------------------------------- This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . *****************************************************************************/ // This must always be the first include directive #include "config.h" #include "dacf.h" #include "globalvar.h" const char *GetRevisionInfo_dacf(unsigned int len) { static char buf[256]; GET_REVISION_INFO( buf, len ); return buf; } const char *GetSourceVersion_dacf() { static char buf[256]; GET_SOURCE_VERSION( buf ); return buf; } CDACFSub::CDACFSub() { m_bDistTrace = false; m_bNewMode = false; m_fEqCounter = 0; } CDACFSub::~CDACFSub() { } CDACF::CDACF() { m_bLifetimeSpectrum = false; m_oaSubDACFs.SetName("CDACF::m_oaSubDACFs"); m_faWeight1.SetName("CDACF::m_faWeight1"); m_faWeight2.SetName("CDACF::m_faWeight2"); m_oaLTSpectra.SetName("CDACF::m_oaLTSpectra"); } CDACF::~CDACF() { } void CDACF::Parse() { int z, z2, ti; double tf, tf2; CDACFSub *ds; CxDoubleArray fa; CxIntArray wa; // char buf[256], buf2[256]; CxString buf, buf2; if (g_oaMolecules.GetSize() > 1) { // sprintf(buf," Enter first molecule for aggregation ("); buf.sprintf(" Enter first molecule for aggregation ("); for (z=0;zm_sName,z+1); // strcat(buf,buf2); // if (z < g_oaMolecules.GetSize()-1) // strcat(buf,", "); buf2.sprintf("%s=%d",((CMolecule*)g_oaMolecules[z])->m_sName,z+1); buf.strcat(buf2); if (z < g_oaMolecules.GetSize()-1) buf.strcat(", "); } // strcat(buf,"): "); buf.strcat("): "); m_iFirstMol = AskRangeInteger_ND("%s",1,g_oaMolecules.GetSize(),(const char*)buf) - 1; // sprintf(buf," Enter second molecule for aggregation ("); buf.sprintf(" Enter second molecule for aggregation ("); for (z=0;zm_sName,z+1); // strcat(buf,buf2); // if (z < g_oaMolecules.GetSize()-1) // strcat(buf,", "); buf2.sprintf("%s=%d",((CMolecule*)g_oaMolecules[z])->m_sName,z+1); buf.strcat(buf2); if (z < g_oaMolecules.GetSize()-1) buf.strcat(", "); } // strcat(buf,"): "); buf.strcat("): "); m_iSecondMol = AskRangeInteger_ND("%s",1,g_oaMolecules.GetSize(),(const char*)buf) - 1; } else { m_iFirstMol = 0; m_iSecondMol = 0; } mprintf(" Observing aggregates between %s and %s.\n\n",((CMolecule*)g_oaMolecules[m_iFirstMol])->m_sName,((CMolecule*)g_oaMolecules[m_iSecondMol])->m_sName); // sprintf(buf,"%s_%s",((CMolecule*)g_oaMolecules[m_iFirstMol])->m_sName,((CMolecule*)g_oaMolecules[m_iSecondMol])->m_sName); buf.sprintf("%s_%s",((CMolecule*)g_oaMolecules[m_iFirstMol])->m_sName,((CMolecule*)g_oaMolecules[m_iSecondMol])->m_sName); try { m_sName = new char[strlen(buf)+1]; } catch(...) { m_sName = NULL; } if (m_sName == NULL) NewException((double)(strlen(buf)+1)*sizeof(char),__FILE__,__LINE__,__PRETTY_FUNCTION__); strcpy(m_sName,buf); if (g_bDACF) { if (g_iTrajSteps != -1) m_iDACFRes = AskUnsignedInteger(" Enter the depth (resolution) of the DACF in time steps: [%d] ",int(g_iTrajSteps*0.75),int(g_iTrajSteps*0.75)); else m_iDACFRes = AskUnsignedInteger(" Enter the depth (resolution) of the DACF in time steps: [5000] ",5000); m_bFitDACF = AskYesNo(" Fit poly-exponential functions to DACF and integrate over [0,infinity) (y/n)? [yes] ",true); if (m_bFitDACF) { mprintf("\n TRAVIS will fit functions with different count of exponential terms to your data.\n"); mprintf(" This enables you to see how many different processes contribute to your decay.\n\n"); m_iFitDegreeMin = AskUnsignedInteger(" How many exponential terms to use at least: [1] ",1); m_iFitDegreeMax = AskUnsignedInteger(" How many exponential terms to use at most: [3] ",3); mprintf("\n"); } m_bLifetimeSpectrum = false; } if (g_bNbExchange) { if (g_iTrajSteps != -1) m_pNbExchange->m_iTimeDepth = AskUnsignedInteger(" Enter the depth (resolution) of the neighborhood exchange functions in time steps: [%d] ",int(g_iTrajSteps*0.75),int(g_iTrajSteps*0.75)); else m_pNbExchange->m_iTimeDepth = AskUnsignedInteger(" Enter the depth (resolution) of the neighborhood exchange functions in time steps: [5000] ",5000); } if (g_bDDisp) { g_bKeepUnfoldedCoords = true; try { m_pCenterAtoms1 = new CAtomGroup(); } catch(...) { m_pCenterAtoms1 = NULL; } if (m_pCenterAtoms1 == NULL) NewException((double)sizeof(CAtomGroup),__FILE__,__LINE__,__PRETTY_FUNCTION__); try { m_pCenterAtoms2 = new CAtomGroup(); } catch(...) { m_pCenterAtoms2 = NULL; } if (m_pCenterAtoms2 == NULL) NewException((double)sizeof(CAtomGroup),__FILE__,__LINE__,__PRETTY_FUNCTION__); mprintf(YELLOW,"\n*** Dimer Displacement\n\n"); mprintf(" The \"dimer center\" is the weightened average of 2 atoms from the monomers.\n\n"); _ca1: mprintf(" Enter atoms from 1st molecule [center of mass]: "); inpprintf("! Enter atoms from 1st molecule [center of mass]:\n"); myget(&buf); if (strlen(buf)!=0) { if (!m_pCenterAtoms1->ParseAtoms((CMolecule*)g_oaMolecules[m_iFirstMol],buf)) { eprintf("Invalid input.\n"); inpprintf("! Invalid input.\n"); goto _ca1; } } else { if (!m_pCenterAtoms1->ParseAtoms((CMolecule*)g_oaMolecules[m_iFirstMol],"#2")) { eprintf("CDACF::Parse(): Internal error.\n"); inpprintf("! CDACF::Parse(): Internal error.\n"); abort(); } } if (m_pCenterAtoms1->m_iAtomGes > 1) { _wm1again: ti = AskRangeInteger(" Weight Atoms in 1st mol. uniform (1), by mass (2) or manually (3)? [2]",1,3,2); switch(ti) { case 1: for (z=0;zm_iAtomGes;z++) m_faWeight1.Add(1.0); break; case 2: for (z=0;zm_baAtomType.GetSize();z++) for (z2=0;z2<((CxIntArray*)m_pCenterAtoms1->m_oaAtoms[z])->GetSize();z2++) m_faWeight1.Add(((CAtom*)g_oaAtoms[m_pCenterAtoms1->m_baRealAtomType[z]])->m_pElement->m_fMass); break; case 3: for (z=0;zm_baAtomType.GetSize();z++) for (z2=0;z2<((CxIntArray*)m_pCenterAtoms1->m_oaAtoms[z])->GetSize();z2++) { tf = AskFloat(" Enter weight for %s%d: [1.0] ",1.0,(const char*)((CAtom*)g_oaAtoms[m_pCenterAtoms1->m_baRealAtomType[z]])->m_sName,((CxIntArray*)m_pCenterAtoms1->m_oaAtoms[z])->GetAt(z2)+1); m_faWeight1.Add(tf); } break; default: goto _wm1again; } tf = 0; for (z=0;zParseAtoms((CMolecule*)g_oaMolecules[m_iSecondMol],buf)) { eprintf("Invalid input.\n"); inpprintf("! Invalid input.\n"); goto _ca2; } } else { if (!m_pCenterAtoms2->ParseAtoms((CMolecule*)g_oaMolecules[m_iSecondMol],"#2")) { eprintf("CDACF::Parse(): Internal error.\n"); inpprintf("! CDACF::Parse(): Internal error.\n"); abort(); } } if (m_pCenterAtoms2->m_iAtomGes > 1) { _wm2again: ti = AskRangeInteger(" Weight atoms in 2nd mol. uniform (1), by mass (2) or manually (3)? [2]",1,3,2); switch(ti) { case 1: for (z=0;zm_iAtomGes;z++) m_faWeight2.Add(1.0); break; case 2: for (z=0;zm_baAtomType.GetSize();z++) for (z2=0;z2<((CxIntArray*)m_pCenterAtoms2->m_oaAtoms[z])->GetSize();z2++) m_faWeight2.Add(((CAtom*)g_oaAtoms[m_pCenterAtoms2->m_baRealAtomType[z]])->m_pElement->m_fMass); break; case 3: for (z=0;zm_baAtomType.GetSize();z++) for (z2=0;z2<((CxIntArray*)m_pCenterAtoms2->m_oaAtoms[z])->GetSize();z2++) { tf = AskFloat(" Enter weight for %s%d: [1.0] ",1.0,(const char*)((CAtom*)g_oaAtoms[m_pCenterAtoms2->m_baRealAtomType[z]])->m_sName,((CxIntArray*)m_pCenterAtoms2->m_oaAtoms[z])->GetAt(z2)+1); m_faWeight2.Add(tf); } break; default: goto _wm2again; } tf = 0; for (z=0;zm_fMass; tf2 = ((CMolecule*)g_oaMolecules[m_iSecondMol])->m_fMass; m_fWeightMol1 = tf / (tf+tf2); break; case 3: tf = AskFloat(" Enter weight for 1st molecule: [1.0] ",1.0); tf2 = AskFloat(" Enter weight for 2nd molecule: [1.0] ",1.0); m_fWeightMol1 = tf / (tf+tf2); break; default: goto _mwagain; } mprintf(" Weight Mol.1 : Mol.2 is %.3f : %.3f.\n\n",m_fWeightMol1,1.0-m_fWeightMol1); m_fLargestDisplacement = AskFloat(" Enter largest displacement in pm [1000.0]: ",1000.0); m_iDisplacementRes = AskUnsignedInteger(" Enter displacement resolution [100]: ",100); m_fMaxVel = AskFloat(" Enter maximum dimer center velocity in pm/ps (0 means no max. vel.): [10000.0] ",10000.0); if (m_fMaxVel != 0) m_bRemoveMaxVel = AskYesNo(" If Velocity is above max. value: Remove value (y) or only warn (n)? [no] ",false); } else m_fMaxVel = 0.0; if (g_bDLDF) { if (g_bDACF) { m_fLargestLifetime = AskFloat(" Enter largest lifetime in ps [%.3f]: ",m_iDACFRes*g_fTimestepLength/1000.0,m_iDACFRes*g_fTimestepLength/1000.0); m_iLifetimeRes = AskUnsignedInteger(" Enter lifetime binning resolution [100]: ",100); } else { if (g_iTrajSteps != -1) m_fLargestLifetime = AskFloat(" Enter largest lifetime in ps [%.3f]: ",g_iTrajSteps*0.75*g_fTimestepLength/1000.0,g_iTrajSteps*0.75*g_fTimestepLength/1000.0); else m_fLargestLifetime = AskFloat(" Enter largest lifetime in ps [5.0]: ",5.0); m_iLifetimeRes = AskUnsignedInteger(" Enter lifetime binning resolution [%d]: ",int(m_fLargestLifetime*1000.0/g_fTimestepLength),int(m_fLargestLifetime*1000.0/g_fTimestepLength)); } if (m_fLargestLifetime * 1000.0 / g_fTimestepLength < m_iLifetimeRes) { mprintf(WHITE,"\nWARNING: Largest lifetime of %.3f ps is %d timesteps - less than lifetime resolution %d!\n",m_fLargestLifetime,(int)(m_fLargestLifetime * 1000.0 / g_fTimestepLength),m_iLifetimeRes); mprintf(WHITE," Changing lifetime resolution down to %d.\n",(int)(m_fLargestLifetime * 1000.0 / g_fTimestepLength)); m_iLifetimeRes = (int)(m_fLargestLifetime * 1000.0 / g_fTimestepLength); } } /* if (g_bDDisp && g_bDLDF) g_bDLDisp = AskYesNo("\n Create an combined Dimer Lifetime/Displacement-Function (y/n)? [yes] ",true); else g_bDLDisp = false;*/ mprintf("\n"); m_bDACFGrid = false; { mprintf("\nNow you have to enter the condition(s) for aggregation.\n\n"); try { m_pCondition = new CConditionGroup(); } catch(...) { m_pCondition = NULL; } if (m_pCondition == NULL) NewException((double)sizeof(CConditionGroup),__FILE__,__LINE__,__PRETTY_FUNCTION__); m_pCondition->Parse(m_iFirstMol,m_iSecondMol); try { ds = new CDACFSub(); } catch(...) { ds = NULL; } if (ds == NULL) NewException((double)sizeof(CDACFSub),__FILE__,__LINE__,__PRETTY_FUNCTION__); ds->m_iRefMol = m_iFirstMol; ds->m_iShowMol = m_iSecondMol; ds->Create(m_pCondition); ds->Parse(); ds->BuildName(m_sName); m_oaSubDACFs.Add(ds); mprintf("\n"); while (AskYesNo(" Add another aggregation function with different criterion values (y/n)? [no] ",false)) { try { ds = new CDACFSub(); } catch(...) { ds = NULL; } if (ds == NULL) NewException((double)sizeof(CDACFSub),__FILE__,__LINE__,__PRETTY_FUNCTION__); ds->m_iRefMol = m_iFirstMol; ds->m_iShowMol = m_iSecondMol; ds->Create(m_pCondition); mprintf("\n"); ds->m_pCondition->Parse_OnlyValues(); ds->Parse(); ds->BuildName(m_sName); m_oaSubDACFs.Add(ds); mprintf("\n"); } } // END IF NOT GRID mprintf(WHITE,"\n<<< End of Aggregation Functions <<<\n"); } void CDACFSub::BuildName(const char *n) { int z, z2, z3; // char buf[256], buf2[256]; CxString buf, buf2; CConditionSubGroup *sg; CNbSearch *nb; // strcpy(buf,n); buf.strcpy(n); for (z=0;zm_oaConditionSubGroups.GetSize();z++) { sg = (CConditionSubGroup*)m_pCondition->m_oaConditionSubGroups[z]; for (z2=0;z2m_oaConditions.GetSize();z2++) { nb = (CNbSearch*)sg->m_oaConditions[z2]; if (nb->m_pRDF != NULL) { if (nb->m_iNbCountMin == -1) { // strcat(buf,"_r"); buf.strcat("_r"); for (z3=0;z3m_pRDF->m_faMinMaxDist.GetSize()/2;z3++) { if (z3 < (nb->m_pRDF->m_faMinMaxDist.GetSize()/2)-1) // sprintf(buf2,"%.0f-%.0f,",nb->m_pRDF->m_faMinMaxDist[z3*2],nb->m_pRDF->m_faMinMaxDist[z3*2+1]); buf2.sprintf("%.0f-%.0f,",nb->m_pRDF->m_faMinMaxDist[z3*2],nb->m_pRDF->m_faMinMaxDist[z3*2+1]); else // sprintf(buf2,"%.0f-%.0f",nb->m_pRDF->m_faMinMaxDist[z3*2],nb->m_pRDF->m_faMinMaxDist[z3*2+1]); buf2.sprintf("%.0f-%.0f",nb->m_pRDF->m_faMinMaxDist[z3*2],nb->m_pRDF->m_faMinMaxDist[z3*2+1]); } // strcat(buf,buf2); buf.strcat(buf2); } else { // sprintf(buf2,"_n%d-%d",nb->m_iNbCountMin+1,nb->m_iNbCountMax+1); // strcat(buf,buf2); buf2.sprintf("_n%d-%d",nb->m_iNbCountMin+1,nb->m_iNbCountMax+1); buf.strcat(buf2); } } if (nb->m_pADF != NULL) { // strcat(buf,"_a"); buf.strcat("_a"); for (z3=0;z3m_pADF->m_faMinMaxAngle.GetSize()/2;z3++) { if (z3 < (nb->m_pADF->m_faMinMaxAngle.GetSize()/2)-1) // sprintf(buf2,"%.0f-%.0f,",nb->m_pADF->m_faMinMaxAngle[z3*2],nb->m_pADF->m_faMinMaxAngle[z3*2+1]); buf2.sprintf("%.0f-%.0f,",nb->m_pADF->m_faMinMaxAngle[z3*2],nb->m_pADF->m_faMinMaxAngle[z3*2+1]); else // sprintf(buf2,"%.0f-%.0f",nb->m_pADF->m_faMinMaxAngle[z3*2],nb->m_pADF->m_faMinMaxAngle[z3*2+1]); buf2.sprintf("%.0f-%.0f",nb->m_pADF->m_faMinMaxAngle[z3*2],nb->m_pADF->m_faMinMaxAngle[z3*2+1]); } // strcat(buf,buf2); buf.strcat(buf2); } } } if (m_bIntermittend) { // if (m_fIntGap != 0) // sprintf(buf2,"_int%.3f",m_fIntGap); // buf2.sprintf("_int%.3f",m_fIntGap); // else // sprintf(buf2,"_int"); // buf2.sprintf("_int"); // strcat(buf,buf2); buf.strcat("_int"); // if (!m_bIntTravisStyle) // strcat(buf,"_mpstyle"); // buf.strcat("_mpstyle"); } else buf.strcat("_cont"); if (m_bDistTrace) { // strcat(buf,"_trace"); buf.strcat("_trace"); } if (m_bCorrectEq) { // strcat(buf,"_correq"); buf.strcat("_correq"); } /* if (m_bNewMode) { // strcat(buf,"_new"); buf.strcat("_new"); } if (m_bBorderMode) { // strcat(buf,"_border"); buf.strcat("_border"); }*/ try { m_sName = new char[strlen(buf)+1]; } catch(...) { m_sName = NULL; } if (m_sName == NULL) NewException((double)(strlen(buf)+1)*sizeof(char),__FILE__,__LINE__,__PRETTY_FUNCTION__); strcpy(m_sName,buf); } void CDACFSub::Parse() { mprintf("\n"); if (g_bDLDisp) m_bDistTrace = AskYesNo(" Add values to lifetime/displacement plot at cleavage (n) or full trace (y)? [yes] ",true); m_bIntermittend = (AskRangeInteger(" Calculate this function as continuous (0) or intermittent (1) type? [1] ",0,1,1) == 1); if (m_bIntermittend) { m_bNewMode = true; /* if (!g_bInterWarning) { g_bInterWarning = true; mprintf("\n"); mprintf(RED,"Warning: "); mprintf("The TRAVIS implementation of intermittent ACFs was flawed; this bug was fixed\n"); mprintf(" in 08/2016. Results are not comparable to those obtained before that date.\n"); mprintf(" Please be aware and possibly redo your older intermittent ACFs.\n\n"); }*/ m_bCorrectEq = AskYesNo(" Perform finite-size ensemble equilibrium correction (y/n)? [yes] ",true); } else { m_bNewMode = false; m_bCorrectEq = false; } /* { m_bNewMode = false; m_bBorderMode = false; m_bCorrectEq = false; } if (m_bIntermittend) { if (g_bAdvanced2 && (!m_bNewMode)) m_bIntTravisStyle = AskYesNo(" Use \"bridged style\" (y) or \"true ACF style\" (n) for intermittent function? [yes] ",true); else m_bIntTravisStyle = true; if (!m_bNewMode) m_fIntGap = AskFloat(" Enter maximum allowed gap for intermittent function in ps (0=infinite)? [0] ",0); else m_fIntGap = 0; }*/ } CxDVector3 CDACF::CalcCenter(CxDVec3Array *v, int i1, int i2) { CxDVector3 v1, v2; int z, z2, c; CSingleMolecule *s1, *s2; s1 = (CSingleMolecule*)g_oaSingleMolecules[((CMolecule*)g_oaMolecules[m_iFirstMol])->m_laSingleMolIndex[i1]]; s2 = (CSingleMolecule*)g_oaSingleMolecules[((CMolecule*)g_oaMolecules[m_iSecondMol])->m_laSingleMolIndex[i2]]; c = 0; v1 = CxDVector3(0,0,0); for (z=0;zm_baAtomType.GetSize();z++) { for (z2=0;z2<((CxIntArray*)m_pCenterAtoms1->m_oaAtoms[z])->GetSize();z2++) { v1 += v->GetAt(((CxIntArray*)s1->m_oaAtomOffset[z])->GetAt(z2)) * m_faWeight1[c]; c++; } } c = 0; v2 = CxDVector3(0,0,0); for (z=0;zm_baAtomType.GetSize();z++) { for (z2=0;z2<((CxIntArray*)m_pCenterAtoms2->m_oaAtoms[z])->GetSize();z2++) { v2 += v->GetAt(((CxIntArray*)s2->m_oaAtomOffset[z])->GetAt(z2)) * m_faWeight2[c]; c++; } } v1 = v1 * m_fWeightMol1 + v2 * (1.0 - m_fWeightMol1); return v1; } void CDACF::FinishDACFSub(CTimeStep *t, CDACFSub *dacfsub) { int z2, z4, z5/*, z6, z7, z8*/, ti, j; // CSingleMolecule *smfix; double tfs, tf, tf2; CAggregate *ag; ti = 0; for (z2=0;z2<((CMolecule*)g_oaMolecules[m_iFirstMol])->m_laSingleMolIndex.GetSize();z2++) ti += dacfsub->m_oaAggregates[z2].GetSize(); mprintf(" Finishing functions... (%d pairs pending)\n",ti); mprintf(WHITE," ["); tfs = ((CMolecule*)g_oaMolecules[m_iFirstMol])->m_laSingleMolIndex.GetSize() / 60.0; for (z2=0;z2<((CMolecule*)g_oaMolecules[m_iFirstMol])->m_laSingleMolIndex.GetSize();z2++) { if (fmod(z2,tfs) < 1.0) mprintf(WHITE,"#"); // smfix = (CSingleMolecule*)g_oaSingleMolecules[((CMolecule*)g_oaMolecules[m_iFirstMol])->m_laSingleMolIndex[z2]]; if (dacfsub->m_bIntermittend) { j = 0; for (z4=0;z4m_oaAggregates[z2].GetSize();z4++) { ag = (CAggregate*)dacfsub->m_oaAggregates[z2][z4]; if (ag->m_iEnd == -1) ag->m_iEnd = g_iSteps; // if ((!dacfsub->m_bIntTravisStyle) && (*/ag->m_iEnd == (long)g_iSteps)) if (ag->m_iEnd == (long)g_iSteps) { ag->m_iEnd = g_iSteps; ag->m_laLifeIntervals.Add(ag->m_iStart); ag->m_laLifeIntervals.Add(ag->m_iEnd); } if (g_bDDisp || g_bPairMSD) { if (ag->m_iEnd == (long)g_iSteps) ag->m_vEnd = CalcCenter(&t->m_vaCoords_Unfolded,z2,ag->m_iSingleMol2); tf = (ag->m_vEnd-ag->m_vFirstStart).GetLength(); if (g_bDDisp) dacfsub->m_pDDisp->AddToBin(tf); if (g_bDLDisp) dacfsub->m_pDLDisp->AddToBin((ag->m_iEnd - ag->m_iFirstStart+1)*g_fTimestepLength/1000.0,tf); if (g_bPairMSD) dacfsub->m_pPairMSD->AddToBin_Index(ag->m_iEnd - ag->m_iFirstStart + 1,tf*tf); if (g_bVerbose) mprintf("\n## %lu: (Int) Aggregate %d.%d lived from %lu to %ld, end at ( %.2f | %.2f | %.2f ), traveled %.2f pm.",g_iSteps,z2,j,ag->m_iFirstStart,ag->m_iEnd,ag->m_vEnd[0],ag->m_vEnd[1],ag->m_vEnd[2],(ag->m_vEnd-ag->m_vFirstStart).GetLength()); } if (g_bDLDF) dacfsub->m_pDLDF->AddToBin((ag->m_iEnd - ag->m_iFirstStart + 1)*g_fTimestepLength/1000.0); if (g_bDACF) { /* if (!dacfsub->m_bIntTravisStyle) { for (z5=0;z5m_laLifeIntervals.GetSize()/2;z5++) { for (z6=ag->m_laLifeIntervals[z5*2];z6<=ag->m_laLifeIntervals[z5*2+1];z6++) { for (z7=z5;z7m_laLifeIntervals.GetSize()/2;z7++) { dacfsub->m_fEqCounter += ag->m_laLifeIntervals[z7*2+1] - ag->m_laLifeIntervals[z7*2] + 1; for (z8=ag->m_laLifeIntervals[z7*2];z8<=ag->m_laLifeIntervals[z7*2+1];z8++) { if (z8 < z6) continue; dacfsub->m_pDACF->AddToBin_Int(z8-z6); } } } } } else {*/ dacfsub->m_fEqCounter += ag->m_iEnd - ag->m_iFirstStart + 1; // if (dacfsub->m_bNewMode) // { dacfsub->m_piaIntervals[z2*((CMolecule*)g_oaMolecules[m_iSecondMol])->m_laSingleMolIndex.GetSize()+ag->m_iSingleMol2].Add(ag->m_iFirstStart); dacfsub->m_piaIntervals[z2*((CMolecule*)g_oaMolecules[m_iSecondMol])->m_laSingleMolIndex.GetSize()+ag->m_iSingleMol2].Add(ag->m_iEnd); /* } else { if (m_iDACFRes < (int)(ag->m_iEnd-ag->m_iFirstStart+1)) { ti = m_iDACFRes; for (z5=0;z5m_pDACF->AddToBin_Count(z5,(int)(ag->m_iEnd-ag->m_iFirstStart+1)-m_iDACFRes); } else ti = (int)(ag->m_iEnd-ag->m_iFirstStart+1); for (z5=0;z5m_pDACF->AddToBin_Count(z5,ti-z5); }*/ // } } delete ag; dacfsub->m_oaAggregates[z2].RemoveAt_NoShrink(z4,1); z4--; j++; } // END FOR Z4 } else // IF NOT INTERMITTENT { for (z4=0;z4m_oaAggregates[z2].GetSize();z4++) { ag = (CAggregate*)dacfsub->m_oaAggregates[z2][z4]; if (ag->m_iEnd == -1) { ag->m_iEnd = g_iSteps; if (g_bDDisp || g_bPairMSD) { ag->m_vEnd = CalcCenter(&t->m_vaCoords_Unfolded,z2,ag->m_iSingleMol2); tf = (ag->m_vEnd-ag->m_vStart).GetLength(); tf2 = (ag->m_iEnd-ag->m_iStart+1)*g_fTimestepLength/1000.0; if (m_fMaxVel != 0) { if (tf/tf2 > m_fMaxVel) { mprintf("\n Dimer %d - %d lived from Step %lu to %lu and moved %.2f pm (%.1f pm/ps) - too fast.",z2+1,ag->m_iSingleMol2+1,ag->m_iStart,g_iSteps,tf,tf/tf2*1000.0); if (m_bRemoveMaxVel) goto _maxvel2; } } if (g_bDDisp) dacfsub->m_pDDisp->AddToBin(tf); if (g_bDLDisp) dacfsub->m_pDLDisp->AddToBin(tf2,tf); if (g_bPairMSD) dacfsub->m_pPairMSD->AddToBin_Index(ag->m_iEnd-ag->m_iStart+1,tf*tf); } _maxvel2: if (g_bDLDF) dacfsub->m_pDLDF->AddToBin((ag->m_iEnd - ag->m_iStart+1)*g_fTimestepLength/1000.0); if (g_bDACF) { dacfsub->m_fEqCounter += g_iSteps - ag->m_iStart + 1; /* if (dacfsub->m_bNewMode) { dacfsub->m_piaIntervals[z2*((CMolecule*)g_oaMolecules[m_iSecondMol])->m_laSingleMolIndex.GetSize()+ag->m_iSingleMol2].Add(ag->m_iStart); dacfsub->m_piaIntervals[z2*((CMolecule*)g_oaMolecules[m_iSecondMol])->m_laSingleMolIndex.GetSize()+ag->m_iSingleMol2].Add(ag->m_iEnd); } else {*/ if (m_iDACFRes < (int)(g_iSteps-ag->m_iStart+1)) { ti = m_iDACFRes; for (z5=0;z5m_pDACF->AddToBin_Count(z5,(int)(g_iSteps-ag->m_iStart+1)-m_iDACFRes); } else ti = (int)(g_iSteps-ag->m_iStart+1); for (z5=0;z5m_pDACF->AddToBin_Count(z5,ti-z5); // } } delete ag; dacfsub->m_oaAggregates[z2].RemoveAt_NoShrink(z4,1); z4--; continue; } } // END FOR Z4 } // END IF NOT INTERMITTEND } // END FOR Z2 mprintf(WHITE,"]\n\n"); } void CDACF::UpdateDACFSub(int rm, CTimeStep *t, CDACFSub *dacfsub) { int z3, z4, z5/*, z6, z7, z8*/, ti; double tf, tf2; CAggregate *ag; CxDVector3 tv; for (z4=0;z4m_oaAggregates[rm].GetSize();z4++) ((CAggregate*)dacfsub->m_oaAggregates[rm][z4])->m_bStillAlive = false; ti = 0; for (z3=0;z3<((CMolecule*)g_oaMolecules[m_iSecondMol])->m_laSingleMolIndex.GetSize();z3++) // Alle anderen Molekuele durchgehen { if ((m_iFirstMol == m_iSecondMol) && (z3 == rm)) // Wir wollen nicht das Referenzmolekuel mitzaehlen continue; if (dacfsub->m_pCondition->Contains(z3)) { ti++; for (z4=0;z4m_oaAggregates[rm].GetSize();z4++) { ag = (CAggregate*)dacfsub->m_oaAggregates[rm][z4]; if (ag->m_iSingleMol2 == z3) { if (dacfsub->m_bIntermittend && (ag->m_iEnd != -1)) { ag->m_iEnd = -1; ag->m_iStart = g_iSteps; if (g_bDDisp) ag->m_vStart = CalcCenter(&t->m_vaCoords_Unfolded,rm,z3); } ag->m_bStillAlive = true; goto _found; } } try { ag = new CAggregate(); } catch(...) { ag = NULL; } if (ag == NULL) NewException((double)sizeof(CAggregate),__FILE__,__LINE__,__PRETTY_FUNCTION__); dacfsub->m_oaAggregates[rm].Add(ag); ag->m_iSingleMol2 = z3; ag->m_bStillAlive = true; ag->m_iStart = g_iSteps; ag->m_iFirstStart = g_iSteps; ag->m_iEnd = -1; if (g_bDDisp || g_bPairMSD) { ag->m_vFirstStart = CalcCenter(&t->m_vaCoords_Unfolded,rm,z3); ag->m_vStart = ag->m_vFirstStart; if (g_bVerbose) mprintf("\n## %lu: Aggregate %d.%d spawned at ( %.2f | %.2f | %.2f ).",g_iSteps,rm,dacfsub->m_oaAggregates[rm].GetSize()-1,ag->m_vFirstStart[0],ag->m_vFirstStart[1],ag->m_vFirstStart[2]); } _found:; } } // END FOR Z3 dacfsub->m_pNDF->AddToBin_Int(ti); /* if (dacfsub->m_bIntermittend && !dacfsub->m_bNewMode) { for (z4=0;z4m_oaAggregates[rm].GetSize();z4++) { ag = (CAggregate*)dacfsub->m_oaAggregates[rm][z4]; if ((!ag->m_bStillAlive) && (ag->m_iEnd == -1)) { ag->m_iEnd = g_iSteps; // Neu 27.08. if (g_bDDisp || g_bPairMSD) ag->m_vEnd = CalcCenter(&t->m_vaCoords_Unfolded,rm,ag->m_iSingleMol2); if (g_bDACF && (!dacfsub->m_bIntTravisStyle)) { ag->m_laLifeIntervals.Add(ag->m_iStart); ag->m_laLifeIntervals.Add(g_iSteps); } } if ((dacfsub->m_fIntGap != 0) && (ag->m_iEnd != -1) && (ag->m_iEnd <= g_iSteps-(dacfsub->m_fIntGap/(g_fTimestepLength/1000.0)))) { if (g_bDDisp || g_bPairMSD) { tf = (ag->m_vEnd-ag->m_vFirstStart).GetLength(); if (g_bDDisp) { // Weg 27.08. // ag->m_vEnd = CalcCenter(&t->m_vaCoords_Unfolded,rm,ag->m_iSingleMol2); dacfsub->m_pDDisp->AddToBin(tf); if (g_bDLDisp) // dacfsub->m_pDLDisp->AddToBin((g_iSteps - ag->m_iFirstStart)*g_fTimestepLength/1000.0,(ag->m_vEnd-ag->m_vFirstStart).GetLength()); dacfsub->m_pDLDisp->AddToBin((ag->m_iEnd - ag->m_iFirstStart + 1)*g_fTimestepLength/1000.0,tf); } if (g_bPairMSD) dacfsub->m_pPairMSD->AddToBin_Index(ag->m_iEnd - ag->m_iFirstStart + 1,tf*tf); } if (g_bDLDF) { // dacfsub->m_pDLDF->AddToBin((g_iSteps - ag->m_iFirstStart)*g_fTimestepLength/1000.0); dacfsub->m_pDLDF->AddToBin((ag->m_iEnd - ag->m_iFirstStart + 1)*g_fTimestepLength/1000.0); } if (g_bDACF) { if (!dacfsub->m_bIntTravisStyle) { for (z5=0;z5m_laLifeIntervals.GetSize()/2;z5++) { for (z6=ag->m_laLifeIntervals[z5*2];z6<=ag->m_laLifeIntervals[z5*2+1];z6++) { for (z7=z5;z7m_laLifeIntervals.GetSize()/2;z7++) { for (z8=ag->m_laLifeIntervals[z7*2];z8<=ag->m_laLifeIntervals[z7*2+1];z8++) { if (z8 < z6) continue; dacfsub->m_pDACF->AddToBin(z8-z6); } dacfsub->m_fEqCounter += ag->m_laLifeIntervals[z7*2+1] - ag->m_laLifeIntervals[z7*2] + 1; } } } } else { dacfsub->m_fEqCounter += ag->m_iEnd-ag->m_iFirstStart+1; if (dacfsub->m_bNewMode) { dacfsub->m_piaIntervals[rm*((CMolecule*)g_oaMolecules[m_iSecondMol])->m_laSingleMolIndex.GetSize()+ag->m_iSingleMol2].Add(ag->m_iFirstStart); dacfsub->m_piaIntervals[rm*((CMolecule*)g_oaMolecules[m_iSecondMol])->m_laSingleMolIndex.GetSize()+ag->m_iSingleMol2].Add(ag->m_iEnd); } else { if (m_iDACFRes < (int)(ag->m_iEnd-ag->m_iFirstStart+1)) { ti = m_iDACFRes; for (z5=0;z5m_pDACF->AddToBin_Count(z5,(int)(ag->m_iEnd-ag->m_iFirstStart+1)-m_iDACFRes); } else ti = (int)(ag->m_iEnd-ag->m_iFirstStart+1); for (z5=0;z5m_pDACF->AddToBin_Count(z5,ti-z5); } // if (m_iDACFRes < (int)(g_iSteps-ag->m_iFirstStart)) // { // ti = m_iDACFRes; // for (z5=0;z5m_pDACF->AddToBin_Count(z5,(int)(g_iSteps-ag->m_iFirstStart)-m_iDACFRes); // } else ti = (int)(g_iSteps-ag->m_iFirstStart); // for (z5=0;z5m_pDACF->AddToBin_Count(z5,ti-z5); } } // mprintf("Int: RM=%d, OM=%d, t=%d, FirstStart=%d, End=%d, MaxGap ueberschritten.\n",rm+1,ag->m_iSingleMol2+1,g_iSteps,ag->m_iFirstStart,ag->m_iEnd); delete ag; dacfsub->m_oaAggregates[rm].RemoveAt_NoShrink(z4,1); z4--; continue; } else if (ag->m_iEnd != -1) // END IF finally dead { // broken, but still within gap if ((g_bDDisp && dacfsub->m_bDistTrace) || g_bPairMSD) { tv = CalcCenter(&t->m_vaCoords_Unfolded,rm,ag->m_iSingleMol2); ag->m_faTempTrace.Add(g_iSteps - ag->m_iFirstStart + 1); ag->m_faTempTrace.Add((tv-ag->m_vFirstStart).GetLength()); } } else // END IF broken, but still within gap { // Currently together if ((g_bDDisp && dacfsub->m_bDistTrace) || g_bPairMSD) { tv = CalcCenter(&t->m_vaCoords_Unfolded,rm,ag->m_iSingleMol2); tf = (tv-ag->m_vFirstStart).GetLength(); if (g_bDDisp && dacfsub->m_bDistTrace) { dacfsub->m_pDDisp->AddToBin(tf); if (g_bDLDisp) { dacfsub->m_pDLDisp->AddToBin((g_iSteps - ag->m_iFirstStart + 1)*g_fTimestepLength/1000.0,tf); for (z5=0;z5m_faTempTrace.GetSize();z5+=2) dacfsub->m_pDLDisp->AddToBin(ag->m_faTempTrace[z5]*g_fTimestepLength/1000.0,ag->m_faTempTrace[z5+1]); } } if (g_bPairMSD) { dacfsub->m_pPairMSD->AddToBin_Index(g_iSteps - ag->m_iFirstStart + 1,tf*tf); for (z5=0;z5m_faTempTrace.GetSize();z5+=2) dacfsub->m_pPairMSD->AddToBin_Index((int)ag->m_faTempTrace[z5],ag->m_faTempTrace[z5+1]*ag->m_faTempTrace[z5+1]); } ag->m_faTempTrace.RemoveAll_KeepSize(); } if (g_bVerbose) { tv = CalcCenter(&t->m_vaCoords_Unfolded,rm,ag->m_iSingleMol2); tf = (tv-ag->m_vFirstStart).GetLength(); mprintf("\n## %lu: (Int) Aggregate %d.%d lives since %lu at ( %.2f | %.2f | %.2f ), traveled %.2f pm.",g_iSteps,rm,z4,ag->m_iFirstStart,tv[0],tv[1],tv[2],tf); } } } // END FOR Z4 } else // IF NOT INTERMITTENT {*/ for (z4=0;z4m_oaAggregates[rm].GetSize();z4++) { ag = (CAggregate*)dacfsub->m_oaAggregates[rm][z4]; if ((!ag->m_bStillAlive) && (ag->m_iEnd == -1)) { ag->m_iEnd = g_iSteps-1; if (g_bDDisp || g_bPairMSD) { ag->m_vEnd = CalcCenter(&t->m_vaCoords_Unfolded,rm,ag->m_iSingleMol2); tf = (ag->m_vEnd-ag->m_vStart).GetLength(); tf2 = (ag->m_iEnd-ag->m_iStart+1)*g_fTimestepLength/1000.0; if (g_bVerbose) mprintf("\n## %lu: Aggregate %d.%d died at ( %.2f | %.2f | %.2f ), traveled %.2f pm.",g_iSteps,rm,z4,ag->m_vEnd[0],ag->m_vEnd[1],ag->m_vEnd[2],tf); if (m_fMaxVel != 0) { if (tf/tf2 > m_fMaxVel) { mprintf("\nDimer %d - %d lived from Step %lu to %lu and moved %.2f pm (%.1f pm/ps) - too fast.",rm+1,ag->m_iSingleMol2+1,ag->m_iStart,g_iSteps,tf,tf/tf2*1000.0); if (m_bRemoveMaxVel) goto _maxvel; } } if (g_bDDisp) dacfsub->m_pDDisp->AddToBin(tf); if (g_bDLDisp) dacfsub->m_pDLDisp->AddToBin(tf2,tf); if (g_bPairMSD) dacfsub->m_pPairMSD->AddToBin_Index(ag->m_iEnd-ag->m_iStart+1,tf*tf); } _maxvel: if (g_bDLDF) dacfsub->m_pDLDF->AddToBin((g_iSteps - ag->m_iStart + 1)*g_fTimestepLength/1000.0); if (g_bDACF) { dacfsub->m_fEqCounter += ag->m_iEnd-ag->m_iStart+1; if (dacfsub->m_bIntermittend) { // mprintf("%d*%d+%d=%d\n",rm,((CMolecule*)g_oaMolecules[m_iSecondMol])->m_laSingleMolIndex.GetSize(),ag->m_iSingleMol2,rm*((CMolecule*)g_oaMolecules[m_iSecondMol])->m_laSingleMolIndex.GetSize()+ag->m_iSingleMol2); dacfsub->m_piaIntervals[rm*((CMolecule*)g_oaMolecules[m_iSecondMol])->m_laSingleMolIndex.GetSize()+ag->m_iSingleMol2].Add(ag->m_iStart); dacfsub->m_piaIntervals[rm*((CMolecule*)g_oaMolecules[m_iSecondMol])->m_laSingleMolIndex.GetSize()+ag->m_iSingleMol2].Add(ag->m_iEnd); } else { if (m_iDACFRes < (int)(ag->m_iEnd-ag->m_iStart+1)) { ti = m_iDACFRes; for (z5=0;z5m_pDACF->AddToBin_Count(z5,(int)(ag->m_iEnd-ag->m_iStart+1)-m_iDACFRes); } else ti = (int)(ag->m_iEnd-ag->m_iStart+1); for (z5=0;z5m_pDACF->AddToBin_Count(z5,ti-z5); } } // mprintf("Con: RM=%d, OM=%d, t=%d, FirstStart=%d, End=%d.\n",rm+1,ag->m_iSingleMol2+1,g_iSteps,ag->m_iFirstStart,ag->m_iEnd); delete ag; dacfsub->m_oaAggregates[rm].RemoveAt_NoShrink(z4,1); z4--; continue; } else { if ((g_bDDisp && dacfsub->m_bDistTrace) || g_bPairMSD) { tv = CalcCenter(&t->m_vaCoords_Unfolded,rm,ag->m_iSingleMol2); tf = (tv-ag->m_vStart).GetLength(); if (g_bDDisp && dacfsub->m_bDistTrace) dacfsub->m_pDDisp->AddToBin(tf); if (g_bDLDisp && dacfsub->m_bDistTrace) dacfsub->m_pDLDisp->AddToBin((g_iSteps - ag->m_iStart+1)*g_fTimestepLength/1000.0,tf); if (g_bPairMSD) dacfsub->m_pPairMSD->AddToBin_Index(g_iSteps - ag->m_iStart + 1,tf*tf); } if (g_bVerbose) { tv = CalcCenter(&t->m_vaCoords_Unfolded,rm,ag->m_iSingleMol2); tf = (tv-ag->m_vStart).GetLength(); mprintf("\n## %lu: Aggregate %d.%d lives at ( %.2f | %.2f | %.2f ), traveled %.2f pm.",g_iSteps,rm,z4,ag->m_vEnd[0],ag->m_vEnd[1],ag->m_vEnd[2],tf); } } } // END FOR Z4 // } // END IF NOT INTERMITTEND } void CDACF::UpdateNbEx(int rm, CDACFSub *dacfsub) { int z, z2, ti, ti2; CNbExchangePair *nx; // CNbPair *np; // CNbSearch *ns; // ns = (CNbSearch*)((CConditionSubGroup*)dacfsub->m_pCondition->m_oaConditionSubGroups[0])->m_oaConditions[0]; for (z2=0;z2m_oaNbExPairs[rm].GetSize();z2++) ((CNbExchangePair*)dacfsub->m_oaNbExPairs[rm][z2])->m_iStillAlive = 0; ti = 0; for (z=0;z<((CMolecule*)g_oaMolecules[m_iSecondMol])->m_laSingleMolIndex.GetSize();z++) // Alle anderen Molekuele durchgehen { if ((m_iFirstMol == m_iSecondMol) && (z == rm)) // Wir wollen nicht das Referenzmolekuel mitzaehlen continue; if (dacfsub->m_pCondition->Contains(z)) { ti++; for (z2=0;z2m_oaNbExPairs[rm].GetSize();z2++) { nx = (CNbExchangePair*)dacfsub->m_oaNbExPairs[rm][z2]; if ((int)(nx->m_iShowMol) == z) { if (nx->m_iEnd == -1) // Zuletzt noch am leben { nx->m_iStillAlive = 1; goto _found; } } } try { nx = new CNbExchangePair(); } catch(...) { nx = NULL; } if (nx == NULL) NewException((double)sizeof(CNbExchangePair),__FILE__,__LINE__,__PRETTY_FUNCTION__); dacfsub->m_oaNbExPairs[rm].Add(nx); nx->m_iShowMol = z; nx->m_iStart = g_iSteps; nx->m_iEnd = -1; nx->m_iStillAlive = 1; _found:; } } // END FOR Z if (!g_bAggregation) dacfsub->m_pNDF->AddToBin_Int(ti); for (z=0;zm_oaAggregates[rm].GetSize();z++) { nx = (CNbExchangePair*)dacfsub->m_oaNbExPairs[rm][z]; if ((nx->m_iEnd == -1) && (nx->m_iStillAlive == 0)) nx->m_iEnd = g_iSteps; // Noch am leben? Nicht mehr am leben. if (nx->m_iEnd != -1) { if (nx->m_iEnd < (long)g_iSteps-m_pNbExchange->m_iTimeDepth) { dacfsub->m_oaAggregates[rm].RemoveAt(z,1); z--; continue; } } // np = (CNbPair*)ns->m_oaNbPairs[z]; if (nx->m_iStart < (long)g_iSteps-m_pNbExchange->m_iTimeDepth) ti = g_iSteps-m_pNbExchange->m_iTimeDepth; else ti = nx->m_iStart; if (nx->m_iEnd == -1) ti2 = g_iSteps; else ti2 = nx->m_iEnd-1; // Weil es bei m_iEnd bereits erstmalig tot ist. for (z2=ti;z2<=ti2;z2++) { // AddToBin Tau=g_iSteps-z2; Pos=np->m_fMinDist; Nb=np->m_iNbPosition } } // END FOR Z } void CDACFSub::Create(CConditionGroup *c) { try { m_pCondition = new CConditionGroup(); } catch(...) { m_pCondition = NULL; } if (m_pCondition == NULL) NewException((double)sizeof(CConditionGroup),__FILE__,__LINE__,__PRETTY_FUNCTION__); m_pCondition->CopyFrom(c); if (g_bAggregation) { try { m_oaAggregates = new CxObArray[((CMolecule*)g_oaMolecules[m_iRefMol])->m_laSingleMolIndex.GetSize()]; } catch(...) { m_oaAggregates = NULL; } if (m_oaAggregates == NULL) NewException((double)((CMolecule*)g_oaMolecules[m_iRefMol])->m_laSingleMolIndex.GetSize()*sizeof(CxObArray),__FILE__,__LINE__,__PRETTY_FUNCTION__); } } void CDACF::CalcGridFitParms() { int z, z2; CDACFSub *dacfsub; try { m_pFitRMin = new double[m_iFitDegreeMax+1]; } catch(...) { m_pFitRMin = NULL; } if (m_pFitRMin == NULL) NewException((double)(m_iFitDegreeMax+1)*sizeof(double),__FILE__,__LINE__,__PRETTY_FUNCTION__); try { m_pFitRAvg = new double[m_iFitDegreeMax+1]; } catch(...) { m_pFitRAvg = NULL; } if (m_pFitRAvg == NULL) NewException((double)(m_iFitDegreeMax+1)*sizeof(double),__FILE__,__LINE__,__PRETTY_FUNCTION__); try { m_pFitRMax = new double[m_iFitDegreeMax+1]; } catch(...) { m_pFitRMax = NULL; } if (m_pFitRMax == NULL) NewException((double)(m_iFitDegreeMax+1)*sizeof(double),__FILE__,__LINE__,__PRETTY_FUNCTION__); for (z=0;z<=m_iFitDegreeMax;z++) { m_pFitRMin[z] = 1; m_pFitRAvg[z] = 0; m_pFitRMax[z] = 0; } for (z=0;z dacfsub->m_pDACF->m_pCorrCoeff[z2]) m_pFitRMin[z2] = dacfsub->m_pDACF->m_pCorrCoeff[z2]; if (m_pFitRMax[z2] < dacfsub->m_pDACF->m_pCorrCoeff[z2]) m_pFitRMax[z2] = dacfsub->m_pDACF->m_pCorrCoeff[z2]; m_pFitRAvg[z2] += dacfsub->m_pDACF->m_pCorrCoeff[z2]; } } for (z=m_iFitDegreeMin;z<=m_iFitDegreeMax;z++) m_pFitRAvg[z] /= m_oaSubDACFs.GetSize(); } void CDACF::CreateGridFit2DF(C2DF *df, int degree, bool intermittend) { int x, y, z; switch(m_iGridMode) { case 3: df->m_iRes[0] = m_iGridX; df->m_iRes[1] = m_iGridY; df->m_fMinVal[0] = m_fGridXMin; df->m_fMaxVal[0] = m_fGridXMax; df->m_fMinVal[1] = m_fGridYMin; df->m_fMaxVal[1] = m_fGridYMax; df->Create(); df->SetLabelX("Distance [pm]"); df->SetLabelY("Angle [degree]"); for (x=0;xm_pBin[y*m_iGridX+x] = ((CDACFSub*)m_oaSubDACFs[(x*m_iGridY+y)*2+1])->m_pDACF->m_pFitIntegral[degree]; else df->m_pBin[y*m_iGridX+x] = ((CDACFSub*)m_oaSubDACFs[(x*m_iGridY+y)*2])->m_pDACF->m_pFitIntegral[degree]; } else df->m_pBin[y*m_iGridX+x] = ((CDACFSub*)m_oaSubDACFs[x*m_iGridY+y])->m_pDACF->m_pFitIntegral[degree]; } } df->CalcMaxEntry(); break; case 5: df->m_iRes[0] = m_iGridY-m_iGridX+1; df->m_iRes[1] = m_iGridY-m_iGridX+1; df->m_fMinVal[0] = m_iGridX; df->m_fMaxVal[0] = m_iGridY; df->m_fMinVal[1] = m_iGridX; df->m_fMaxVal[1] = m_iGridY; df->Create(); df->SetLabelX("From n-th neighbor"); df->SetLabelY("To n-th neighbor"); z = 0; for (x=0;xm_pBin[y*(m_iGridY-m_iGridX+1)+x] = ((CDACFSub*)m_oaSubDACFs[z*2+1])->m_pDACF->m_pFitIntegral[degree]; else df->m_pBin[y*(m_iGridY-m_iGridX+1)+x] = ((CDACFSub*)m_oaSubDACFs[z*2])->m_pDACF->m_pFitIntegral[degree]; } else df->m_pBin[y*(m_iGridY-m_iGridX+1)+x] = ((CDACFSub*)m_oaSubDACFs[z])->m_pDACF->m_pFitIntegral[degree]; z++; } } df->CalcMaxEntry(); break; } } /*void CDACF::CreateGridFitDF(CDF *df, int degree, bool intermittend) { int x, y, z; switch(m_iGridMode) { } }*/ void CDACF::CreateSubDACFStack(char *s) { // CGrace *g; int z, z2; FILE *a; // char buf[256]; CxString buf; // sprintf(buf,"%s.csv",s); buf.sprintf("%s.csv",s); mprintf(" Writing DACF grid CSV file \"%s\"...\n",(const char*)buf); a = OpenFileWrite(buf,true); mfprintf(a,"# Tau [ps]"); for (z=0;zm_sName); mfprintf(a,"\n"); for (z=0;zm_pDACF->m_pBin[z]); } fclose(a); /* sprintf(buf,"%s.agr",s); mprintf(" Writing DACF grid AGR file \"%s\"...\n",buf); g = new CGrace(); g->AddDataset(); g->SetLabelX("Tau [ps]"); g->SetLabelY("DACF"); g->SetTitle("DACF Grid"); g->SetRangeX(0,m_iDACFRes*g_fTimestepLength/1000.0); g->SetRangeY(0,1.0); g->MakeTicks(); g->CurrentGraph()->CurrentDataset()->m_faValues.SetMaxSize(m_iDACFRes); mprintf(" Preparing set 1: ["); tfs = m_iResolution / 50.0; for (z=0;zAddXYTupel(0,x,m_pBin[z]); if (fmod(z,tfs) < 1) mprintf(WHITE,"#"); } mprintf("]\n"); zi = 0; for (z0=0;z0AddDataset(); g->CurrentGraph()->CurrentDataset()->m_faValues.SetMaxSize(m_iResolution*2); if (m_pAdditionalSetLabels[z0] != NULL) g->SetDatasetName(m_pAdditionalSetLabels[z0]); for (z=0;zAddXYTupel(zi+1,x,m_pAdditionalSets[z0][z]); if (fmod(z,tfs) < 1) mprintf(WHITE,"#"); } mprintf("]\n"); zi++; } g->WriteAgr(buf);*/ } void CDACFSub::ProcessPair(const CxIntArray &intervals) { int z, z2, z3, i; for (z=0;z0;z2--) m_pDACF->m_pBin[i++] += z2; } for (z=0;z= (intervals[z2+1]-intervals[z2])) { for (z3=1;z3<=intervals[z2+1]-intervals[z2]+1;z3++) m_pDACF->m_pBin[i++] += z3; for (z3=0;z3<(intervals[z+1]-intervals[z])-(intervals[z2+1]-intervals[z2]);z3++) m_pDACF->m_pBin[i++] += intervals[z2+1]-intervals[z2]+1; for (z3=intervals[z2+1]-intervals[z2];z3>0;z3--) m_pDACF->m_pBin[i++] += z3; } else { for (z3=1;z3<=intervals[z+1]-intervals[z]+1;z3++) m_pDACF->m_pBin[i++] += z3; for (z3=0;z3<(intervals[z2+1]-intervals[z2])-(intervals[z+1]-intervals[z]);z3++) m_pDACF->m_pBin[i++] += intervals[z+1]-intervals[z]+1; for (z3=intervals[z+1]-intervals[z];z3>0;z3--) m_pDACF->m_pBin[i++] += z3; } } } } travis-src-190101/src/dacf.h0100777000000000000000000000660313412725657012520 0ustar00/***************************************************************************** TRAVIS - Trajectory Analyzer and Visualizer http://www.travis-analyzer.de/ Copyright (c) 2009-2019 Martin Brehm 2012-2019 Martin Thomas 2016-2019 Sascha Gehrke This file was written by Martin Brehm. --------------------------------------------------------------------------- This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . *****************************************************************************/ #ifndef DACF_H #define DACF_H // This must always be the first include directive #include "config.h" #include "xobject.h" #include "xobarray.h" #include "xdoublearray.h" #include "nbsearch.h" #include "moltools.h" #include "nbexchange.h" class CDACFSub : public CxObject { public: void ProcessPair(const CxIntArray &intervals); void Create(CConditionGroup *c); void Parse(); CDACFSub(); ~CDACFSub(); bool m_bNewMode; bool m_bBorderMode; bool m_bDistTrace; bool m_bIntermittend; double m_fIntGap; // bool m_bIntTravisStyle; bool m_bCorrectEq; double m_fEqCounter; int m_iRefMol; int m_iShowMol; char *m_sName; void BuildName(const char *n); CConditionGroup *m_pCondition; CxObArray *m_oaAggregates; CxObArray *m_oaNbExPairs; C2DF *m_pDLDisp; CDF *m_pDACF; CDF *m_pDLDF; CDF *m_pNDF; CDF *m_pDDisp; CAF *m_pPairMSD; CDF **m_pNbExDF; CConditionGroup **m_pNbExConditions; CxIntArray *m_piaIntervals; }; class CDACF : public CxObject { public: void CreateSubDACFStack(char *s); void CreateGridFit2DF(C2DF *df, int degree, bool intermittend); // void CreateGridFitDF(CDF *df, int degree, bool intermittend); void CalcGridFitParms(); void UpdateNbEx(int rm, CDACFSub *dacfsub); void UpdateDACFSub(int rm, CTimeStep *t, CDACFSub *dacfsub); void FinishDACFSub(CTimeStep *t, CDACFSub *dacfsub); bool m_bRemoveMaxVel; double m_fMaxVel; CDACF(); ~CDACF(); void Parse(); CxDVector3 CalcCenter(CxDVec3Array *v, int i1, int i2); CxObArray m_oaSubDACFs; CConditionGroup *m_pCondition; int m_iFirstMol; int m_iSecondMol; char *m_sName; CAtomGroup *m_pCenterAtoms1; CAtomGroup *m_pCenterAtoms2; CxDoubleArray m_faWeight1; CxDoubleArray m_faWeight2; double m_fWeightMol1; int m_iLifetimeRes; int m_iDACFRes; int m_iDisplacementRes; double m_fLargestDisplacement; double m_fLargestLifetime; bool m_bDACFGrid; int m_iGridMode; bool m_bGridCon; bool m_bGridInt; bool m_bGridIntTravisStyle; double m_fGridIntGap; CNbExchange *m_pNbExchange; bool m_bFitDACF; int m_iFitDegreeMin; int m_iFitDegreeMax; double *m_pFitRMin; double *m_pFitRAvg; double *m_pFitRMax; int m_iGridX; int m_iGridY; double m_fGridXMin; double m_fGridXMax; double m_fGridYMin; double m_fGridYMax; bool m_bLifetimeSpectrum; CxObArray m_oaLTSpectra; }; #endif travis-src-190101/src/database.cpp0100777000000000000000000021457113412725627013724 0ustar00/***************************************************************************** TRAVIS - Trajectory Analyzer and Visualizer http://www.travis-analyzer.de/ Copyright (c) 2009-2019 Martin Brehm 2012-2019 Martin Thomas 2016-2019 Sascha Gehrke This file was written by Martin Brehm. --------------------------------------------------------------------------- This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . *****************************************************************************/ // This must always be the first include directive #include "config.h" #include "database.h" const char *GetRevisionInfo_database(unsigned int len) { static char buf[256]; GET_REVISION_INFO( buf, len ); return buf; } const char *GetSourceVersion_database() { static char buf[256]; GET_SOURCE_VERSION( buf ); return buf; } int treecolor=RED, namecolor=GREEN, valuecolor=YELLOW, typecolor=BLUE, symbolcolor=PINK, nodecolor=CYAN; CDatabaseTable::CDatabaseTable() { BTIN; m_iWidth = 0; m_iHeight = 0; m_pValues.SetName("CDatabaseTable::m_pValues"); BTOUT; } CDatabaseTable::~CDatabaseTable() { BTIN; int x, y; for (y=0;yGetAt(x) != NULL) delete (CDatabaseValue*)((CxObArray*)m_pValues.GetAt(y))->GetAt(x); delete (CxObArray*)m_pValues.GetAt(y); } m_pValues.RemoveAll(); BTOUT; } void CDatabaseTable::DumpTable() { BTIN; int x, y; unsigned char *t, tw=0, ttw=0; // char buf[256]; CxString buf; CDatabaseValue *v; try { t = new unsigned char[m_iWidth]; } catch(...) { t = NULL; } if (t == NULL) NewException((double)m_iWidth*sizeof(unsigned char),__FILE__,__LINE__,__PRETTY_FUNCTION__); for (x=0;xGetAt(x); if (v == NULL) continue; switch(v->m_iType) { case 1: ttw = (unsigned char)((int)log10((double)((signed long)v->m_pValue)))+1; if ((signed long)v->m_pValue < 0) ttw++; break; case 2: ttw = (unsigned char)((int)log10(*((double*)v->m_pValue)))+1; if (*((double*)v->m_pValue) < 0) ttw++; ttw+=5; break; case 3: ttw = (unsigned char)strlen((char*)v->m_pValue)+2; break; case 4: ttw = 5; break; } if (ttw > tw) tw = ttw; } t[x] = tw; } for (y=0;yGetAt(x); if (v == NULL) { ttw = (t[x]-1)/2; tw = (t[x]-1)-ttw; // sprintf(buf," [%c%ds-%c%ds] ",'%',tw,'%',ttw); buf.sprintf(" [%c%ds-%c%ds] ",'%',tw,'%',ttw); mprintf(buf,"",""); continue; } switch(v->m_iType) { case 1: tw = (unsigned char)((int)log10((double)((signed long)v->m_pValue)))+1; if ((signed long)v->m_pValue < 0) tw++; ttw = t[x]-tw; // sprintf(buf," [%c%ds%cd] ",'%',ttw,'%'); buf.sprintf(" [%c%ds%cd] ",'%',ttw,'%'); mprintf(buf,"",(signed long)v->m_pValue); break; case 2: tw = (unsigned char)((int)log10(*((double*)v->m_pValue)))+1; if (*((double*)v->m_pValue) < 0) tw++; tw+=5; ttw = t[x]-tw; // sprintf(buf," [%c%ds%c.4f] ",'%',ttw,'%'); buf.sprintf(" [%c%ds%c.4f] ",'%',ttw,'%'); mprintf(buf,"",*((double*)v->m_pValue)); break; case 3: tw = (unsigned char)strlen((char*)v->m_pValue)+2; ttw = t[x]-tw; // sprintf(buf," [\"%cs\"%c%ds] ",'%','%',ttw); buf.sprintf(" [\"%cs\"%c%ds] ",'%','%',ttw); mprintf(buf,(char*)v->m_pValue,""); break; case 4: ttw = (t[x]-5)/2; tw = (t[x]-5)-ttw; if (v->m_pValue == 0) // sprintf(buf," [%c%dsFALSE%c%ds] ",'%',tw,'%',ttw); buf.sprintf(" [%c%dsFALSE%c%ds] ",'%',tw,'%',ttw); else // sprintf(buf," [%c%dsTRUE %c%ds] ",'%',tw,'%',ttw); buf.sprintf(" [%c%dsTRUE %c%ds] ",'%',tw,'%',ttw); mprintf(buf,"",""); break; } } mprintf("\n"); } delete[] t; BTOUT; } void CDatabaseTable::DumpTreeTable(int depth, unsigned long bitmask, bool last) { BTIN; int x, y, z2; unsigned char *t, tw=0, ttw=0; // char buf[256]; CxString buf; CDatabaseValue *v; try { t = new unsigned char[m_iWidth]; } catch(...) { t = NULL; } if (t == NULL) NewException((double)m_iWidth*sizeof(unsigned char),__FILE__,__LINE__,__PRETTY_FUNCTION__); for (x=0;xGetAt(x); if (v == NULL) continue; switch(v->m_iType) { case 1: ttw = (unsigned char)((int)log10((double)((signed long)v->m_pValue)))+1; if ((signed long)v->m_pValue < 0) ttw++; break; case 2: ttw = (unsigned char)((int)log10(*((double*)v->m_pValue)))+1; if (*((double*)v->m_pValue) < 0) ttw++; ttw+=5; break; case 3: ttw = (unsigned char)strlen((char*)v->m_pValue)+2; break; case 4: ttw = 5; break; } if (ttw > tw) tw = ttw; } t[x] = tw; } for (y=0;yGetAt(x); if (v == NULL) { ttw = (t[x]-1)/2; tw = (t[x]-1)-ttw; // sprintf(buf,"%c%ds-%c%ds",'%',tw,'%',ttw); buf.sprintf("%c%ds-%c%ds",'%',tw,'%',ttw); TextColor(symbolcolor); mprintf(" ["); TextColor(valuecolor); mprintf(buf,"",""); TextColor(symbolcolor); mprintf("] "); continue; } switch(v->m_iType) { case 1: tw = (unsigned char)((int)log10((double)((signed long)v->m_pValue)))+1; if ((signed long)v->m_pValue < 0) tw++; ttw = t[x]-tw; // sprintf(buf,"%c%ds%cd",'%',ttw,'%'); buf.sprintf("%c%ds%cd",'%',ttw,'%'); TextColor(symbolcolor); mprintf(" ["); TextColor(valuecolor); mprintf(buf,"",(signed long)v->m_pValue); TextColor(symbolcolor); mprintf("] "); break; case 2: tw = (unsigned char)((int)log10(*((double*)v->m_pValue)))+1; if (*((double*)v->m_pValue) < 0) tw++; tw+=5; ttw = t[x]-tw; // sprintf(buf,"%c%ds%c.4f",'%',ttw,'%'); buf.sprintf("%c%ds%c.4f",'%',ttw,'%'); TextColor(symbolcolor); mprintf(" ["); TextColor(valuecolor); mprintf(buf,"",*((double*)v->m_pValue)); TextColor(symbolcolor); mprintf("] "); break; case 3: tw = (unsigned char)strlen((char*)v->m_pValue)+2; ttw = t[x]-tw; // sprintf(buf,"\"%cs\"%c%ds",'%','%',ttw); buf.sprintf("\"%cs\"%c%ds",'%','%',ttw); TextColor(symbolcolor); mprintf(" ["); TextColor(valuecolor); mprintf(buf,(char*)v->m_pValue,""); TextColor(symbolcolor); mprintf("] "); break; case 4: ttw = (t[x]-5)/2; tw = (t[x]-5)-ttw; if (v->m_pValue == 0) // sprintf(buf,"%c%dsFALSE%c%ds",'%',tw,'%',ttw); buf.sprintf("%c%dsFALSE%c%ds",'%',tw,'%',ttw); else // sprintf(buf,"%c%dsTRUE %c%ds",'%',tw,'%',ttw); buf.sprintf("%c%dsTRUE %c%ds",'%',tw,'%',ttw); TextColor(symbolcolor); mprintf(" ["); TextColor(valuecolor); mprintf(buf,"",""); TextColor(symbolcolor); mprintf("] "); break; } } mprintf("\n"); } delete[] t; BTOUT; } void CDatabaseTable::DumpOutputFile(FILE *a, int depth) { BTIN; int x, y; unsigned char *t, tw=0, ttw=0; // char buf[256]; CxString buf; CDatabaseValue *v; try { t = new unsigned char[m_iWidth]; } catch(...) { t = NULL; } if (t == NULL) NewException((double)m_iWidth*sizeof(unsigned char),__FILE__,__LINE__,__PRETTY_FUNCTION__); for (x=0;xGetAt(x); if (v == NULL) continue; switch(v->m_iType) { case 1: ttw = (unsigned char)((int)log10((double)((signed long)v->m_pValue)))+1; if ((signed long)v->m_pValue < 0) ttw++; break; case 2: ttw = (unsigned char)((int)log10(*((double*)v->m_pValue)))+1; if (*((double*)v->m_pValue) < 0) ttw++; ttw+=5; break; case 3: ttw = (unsigned char)strlen((char*)v->m_pValue)+2; break; case 4: ttw = 5; break; } if (ttw > tw) tw = ttw; } t[x] = tw; } for (y=0;yGetAt(x); if (v == NULL) { ttw = (t[x]-1)/2; tw = (t[x]-1)-ttw; // sprintf(buf," %c%ds-%c%ds ",'%',tw,'%',ttw); buf.sprintf(" %c%ds-%c%ds ",'%',tw,'%',ttw); mfprintf(a,buf,"",""); continue; } switch(v->m_iType) { case 1: tw = (unsigned char)((int)log10((double)((signed long)v->m_pValue)))+1; if ((signed long)v->m_pValue < 0) tw++; ttw = t[x]-tw; // sprintf(buf," %c%ds%cd ",'%',ttw,'%'); buf.sprintf(" %c%ds%cd ",'%',ttw,'%'); mfprintf(a,buf,"",(signed long)v->m_pValue); break; case 2: tw = (unsigned char)((int)log10(*((double*)v->m_pValue)))+1; if (*((double*)v->m_pValue) < 0) tw++; tw+=5; ttw = t[x]-tw; // sprintf(buf," %c%ds%c.4f ",'%',ttw,'%'); buf.sprintf(" %c%ds%c.4f ",'%',ttw,'%'); mfprintf(a,buf,"",*((double*)v->m_pValue)); break; case 3: tw = (unsigned char)strlen((char*)v->m_pValue)+2; ttw = t[x]-tw; // sprintf(buf," \"%cs\"%c%ds ",'%','%',ttw); buf.sprintf(" \"%cs\"%c%ds ",'%','%',ttw); mfprintf(a,buf,(char*)v->m_pValue,""); break; case 4: ttw = (t[x]-5)/2; tw = (t[x]-5)-ttw; if (v->m_pValue == 0) // sprintf(buf," %c%dsFALSE%c%ds ",'%',tw,'%',ttw); buf.sprintf(" %c%dsFALSE%c%ds ",'%',tw,'%',ttw); else // sprintf(buf," %c%dsTRUE %c%ds ",'%',tw,'%',ttw); buf.sprintf(" %c%dsTRUE %c%ds ",'%',tw,'%',ttw); mfprintf(a,buf,"",""); break; } } if (y+1 < m_iHeight) mfprintf(a,"\n"); } delete[] t; BTOUT; } void CDatabaseTable::AddInt(int x, int y, signed long val) { BTIN; CDatabaseValue *v; CxObArray *o; int z, z2; if (y >= m_iHeight) { for (z=m_iHeight;z<=y;z++) { try { o = new CxObArray("CDatabaseTable::AddInt():o"); } catch(...) { o = NULL; } if (o == NULL) NewException((double)sizeof(CxObArray),__FILE__,__LINE__,__PRETTY_FUNCTION__); m_pValues.SetAt(z,(CxObject*)o); for (z2=0;z2SetAt(z2,NULL); } m_iHeight = (unsigned short)y+1; } if (x >= m_iWidth) { for (z=m_iWidth;z<=x;z++) for (z2=0;z2SetAt(z,(CxObject*)NULL); m_iWidth = (unsigned char)x+1; } try { v = new CDatabaseValue(); } catch(...) { v = NULL; } if (v == NULL) NewException((double)sizeof(CDatabaseValue),__FILE__,__LINE__,__PRETTY_FUNCTION__); v->m_iType = 1; v->m_pValue = (void*)val; ((CxObArray*)m_pValues.GetAt(y))->SetAt(x,(CxObject*)v); BTOUT; } void CDatabaseTable::AddDouble(int x, int y, double val) { BTIN; CDatabaseValue *v; CxObArray *o; int z, z2; if (y >= m_iHeight) { for (z=m_iHeight;z<=y;z++) { try { o = new CxObArray("CDatabaseTable::AddDouble():o"); } catch(...) { o = NULL; } if (o == NULL) NewException((double)sizeof(CxObArray),__FILE__,__LINE__,__PRETTY_FUNCTION__); m_pValues.SetAt(z,(CxObject*)o); for (z2=0;z2SetAt(z2,NULL); } m_iHeight = (unsigned short)y+1; } if (x >= m_iWidth) { for (z=m_iWidth;z<=x;z++) for (z2=0;z2SetAt(z,(CxObject*)NULL); m_iWidth = (unsigned char)x+1; } try { v = new CDatabaseValue(); } catch(...) { v = NULL; } if (v == NULL) NewException((double)sizeof(CDatabaseValue),__FILE__,__LINE__,__PRETTY_FUNCTION__); v->m_iType = 2; double *t; try { t = new double; } catch(...) { t = NULL; } if (t == NULL) NewException((double)sizeof(double),__FILE__,__LINE__,__PRETTY_FUNCTION__); *t = val; v->m_pValue = (void*)t; ((CxObArray*)m_pValues.GetAt(y))->SetAt(x,(CxObject*)v); BTOUT; } void CDatabaseTable::AddString(int x, int y, CxString val) { BTIN; CDatabaseValue *v; CxObArray *o; int z, z2; if (y >= m_iHeight) { for (z=m_iHeight;z<=y;z++) { try { o = new CxObArray("CDatabaseTable::AddString():o"); } catch(...) { o = NULL; } if (o == NULL) NewException((double)sizeof(CxObArray),__FILE__,__LINE__,__PRETTY_FUNCTION__); m_pValues.SetAt(z,(CxObject*)o); for (z2=0;z2SetAt(z2,NULL); } m_iHeight = (unsigned short)y+1; } if (x >= m_iWidth) { for (z=m_iWidth;z<=x;z++) for (z2=0;z2SetAt(z,(CxObject*)NULL); m_iWidth = (unsigned char)x+1; } try { v = new CDatabaseValue(); } catch(...) { v = NULL; } if (v == NULL) NewException((double)sizeof(CDatabaseValue),__FILE__,__LINE__,__PRETTY_FUNCTION__); v->m_iType = 3; char *buf; try { buf = new char[val.GetLength()+1]; } catch(...) { buf = NULL; } if (buf == NULL) NewException((double)(val.GetLength()+1)*sizeof(char),__FILE__,__LINE__,__PRETTY_FUNCTION__); strcpy(buf,(const char*)val); v->m_pValue = (void*)buf; ((CxObArray*)m_pValues.GetAt(y))->SetAt(x,(CxObject*)v); BTOUT; } void CDatabaseTable::AddBool(int x, int y, bool val) { BTIN; CDatabaseValue *v; CxObArray *o; int z, z2; if (y >= m_iHeight) { for (z=m_iHeight;z<=y;z++) { try { o = new CxObArray("CDatabaseTable::AddBool():o"); } catch(...) { o = NULL; } if (o == NULL) NewException((double)sizeof(CxObArray),__FILE__,__LINE__,__PRETTY_FUNCTION__); m_pValues.SetAt(z,(CxObject*)o); for (z2=0;z2SetAt(z2,NULL); } m_iHeight = (unsigned short)y+1; } if (x >= m_iWidth) { for (z=m_iWidth;z<=x;z++) for (z2=0;z2SetAt(z,(CxObject*)NULL); m_iWidth = (unsigned char)x+1; } try { v = new CDatabaseValue(); } catch(...) { v = NULL; } if (v == NULL) NewException((double)sizeof(CDatabaseValue),__FILE__,__LINE__,__PRETTY_FUNCTION__); v->m_iType = 4; v->m_pValue = (void*)((unsigned long)(val?1:0)); ((CxObArray*)m_pValues.GetAt(y))->SetAt(x,(CxObject*)v); BTOUT; } CDatabaseValue::CDatabaseValue() { BTIN; m_pValue = NULL; BTOUT; } CDatabaseValue::~CDatabaseValue() { } void CDatabaseValue::DumpOutputFile(FILE *a) { BTIN; int z; switch(m_iType) { case 0: mfprintf(a,""); break; case 1: mfprintf(a,"%ld",(long)m_pValue); break; case 2: mfprintf(a,"%g",*(double*)m_pValue); break; case 3: mfprintf(a,"\"%s\"",(char*)m_pValue); break; case 4: if (m_pValue == 0) mfprintf(a,"FALSE"); else mfprintf(a,"TRUE"); break; case 5: mfprintf(a,"{ "); for (z=0;z<((CxObArray*)m_pValue)->GetSize();z++) { ((CDatabaseValue*)((CxObArray*)m_pValue)->GetAt(z))->DumpOutputFile(a); if (z < ((CxObArray*)m_pValue)->GetSize()-1) mfprintf(a,","); mfprintf(a," "); } mfprintf(a,"}"); break; case 6: break; } BTOUT; } void CDatabaseValue::DumpValue() { BTIN; int z; switch(m_iType) { case 0: mprintf(""); break; case 1: TextColor(valuecolor); mprintf("%ld",(long)m_pValue); TextColor(symbolcolor); break; case 2: TextColor(valuecolor); mprintf("%g",*(double*)m_pValue); TextColor(symbolcolor); break; case 3: TextColor(symbolcolor); mprintf("\""); TextColor(valuecolor); mprintf("%s",(const char*)m_pValue); TextColor(symbolcolor); mprintf("\""); break; case 4: TextColor(valuecolor); if (m_pValue == 0) mprintf("FALSE"); else mprintf("TRUE"); TextColor(symbolcolor); break; case 5: TextColor(symbolcolor); mprintf("{ "); for (z=0;z<((CxObArray*)m_pValue)->GetSize();z++) { TextColor(valuecolor); ((CDatabaseValue*)((CxObArray*)m_pValue)->GetAt(z))->DumpValue(); TextColor(symbolcolor); if (z < ((CxObArray*)m_pValue)->GetSize()-1) mprintf(","); mprintf(" "); } mprintf("}"); break; case 6: TextColor(valuecolor); mprintf("$...$"); TextColor(symbolcolor); break; } BTOUT; } void CDatabaseValue::DumpType() { BTIN; switch(m_iType) { case 0: mprintf(""); break; case 1: mprintf("INT"); break; case 2: mprintf("FLOAT"); break; case 3: mprintf("STRING"); break; case 4: mprintf("BOOL"); break; case 5: mprintf("ARRAY"); break; case 6: mprintf("TABLE"); break; } BTOUT; } CDatabaseNode::CDatabaseNode() { /*mprintf("CDatabaseNode::CDatabaseNode()\n");*/ m_oaChildren.SetName("CDatabaseNode::m_oaChildren"); m_oaValues.SetName("CDatabaseNode::m_oaValues"); } CDatabaseNode::~CDatabaseNode() { /*mprintf("CDatabaseNode::~CDatabaseNode()\n");*/ } CDatabaseNode::CDatabaseNode(const char *s) { BTIN; m_sName.Format("%s",s); BTOUT; } CDatabaseNode* CDatabaseNode::REC_FindNode(CxString s) { BTIN; int i, z; #ifdef DEBUG_DATABASE mprintf("CDatabaseNode::FindNode(CxString): Searching for \"%s\" in \"%s\".\n",(const char*)s,(const char*)m_sName); #endif i = s.FindFirst('/'); if (i == -1) i = s.GetLength(); CxString t = s.Left(i); for (z=0;zm_sName == t) { #ifdef DEBUG_DATABASE mprintf(" Node \"%s\" found.\n",(const char*)t); #endif if (i != s.GetLength()) { BTOUT; return ((CDatabaseNode*)m_oaChildren[z])->REC_FindNode(s.Mid(i+1)); } else { BTOUT; return (CDatabaseNode*)m_oaChildren[z]; } } } #ifdef DEBUG_DATABASE mprintf(" Node \"%s\" not found in \"%s\".\n",(const char*)t,(const char*)m_sName); #endif if (i != s.GetLength()) { BTOUT; return NULL; } BTOUT; return NULL; } CDatabaseNode* CDatabaseNode::REC_FindAddNode(CxString s) { BTIN; int i, z; #ifdef DEBUG_DATABASE mprintf("CDatabaseNode::FindAddNode(CxString): Searching for \"%s\" in \"%s\".\n",(const char*)s,(const char*)m_sName); #endif i = s.FindFirst('/'); if (i == -1) i = s.GetLength(); CxString t = s.Left(i); for (z=0;zm_sName == t) { #ifdef DEBUG_DATABASE mprintf(" Node \"%s\" found.\n",(const char*)t); #endif if (i != s.GetLength()) { BTOUT; return ((CDatabaseNode*)m_oaChildren[z])->REC_FindAddNode(s.Mid(i+1)); } else { BTOUT; return (CDatabaseNode*)m_oaChildren[z]; } } #ifdef DEBUG_DATABASE mprintf(" Adding Node \"%s\" to \"%s\".\n",(const char*)t,(const char*)m_sName); #endif CDatabaseNode *p; try { p = new CDatabaseNode(t); } catch(...) { p = NULL; } if (p == NULL) NewException((double)sizeof(CDatabaseNode),__FILE__,__LINE__,__PRETTY_FUNCTION__); p->m_pParent = this; m_oaChildren.Add(p); if (i != s.GetLength()) { BTOUT; return p->REC_FindAddNode(s.Mid(i+1)); } else { BTOUT; return p; } } CDatabaseValue* CDatabaseNode::FindValue(CxString s) { BTIN; int z; for (z=0;zm_sName) { BTOUT; return (CDatabaseValue*)m_oaValues[z]; } BTOUT; return NULL; } void CDatabaseNode::REC_DumpTree(int depth, unsigned long bitmask, bool last) { BTIN; int z, z2; TextColor(treecolor); mprintf(" "); for (z=0;zm_sName); // if (((CDatabaseValue*)m_oaValues[z])->m_iType != 4) { TextColor(symbolcolor); mprintf(" = "); ((CDatabaseValue*)m_oaValues[z])->DumpValue(); } TextColor(symbolcolor); mprintf(" ("); TextColor(typecolor); ((CDatabaseValue*)m_oaValues[z])->DumpType(); TextColor(symbolcolor); mprintf(")\n"); if (((CDatabaseValue*)m_oaValues[z])->m_iType == 6) { ((CDatabaseTable*)((CDatabaseValue*)m_oaValues[z])->m_pValue)->DumpTreeTable(depth,bitmask,(z+1 == m_oaValues.GetSize()) && (m_oaChildren.GetSize() == 0)); if (z+1 < m_oaValues.GetSize()) { TextColor(treecolor); mprintf(" "); for (z2=0;z2REC_DumpTree(depth+1,bitmask,z+1==m_oaChildren.GetSize()); } if ((m_oaChildren.GetSize() == 0) && last) { TextColor(treecolor); mprintf(" "); for (z2=0;z2m_sName); // if (((CDatabaseValue*)m_oaValues[z])->m_iType != 4) { mfprintf(a," = "); if (((CDatabaseValue*)m_oaValues[z])->m_iType == 6) { mfprintf(a,"$\n"); ((CDatabaseTable*)((CDatabaseValue*)m_oaValues[z])->m_pValue)->DumpOutputFile(a,depth+1); mfprintf(a,"$"); } else ((CDatabaseValue*)m_oaValues[z])->DumpOutputFile(a); } mfprintf(a,"\n"); } for (z=0;zREC_WriteOutputFile(a,depth+1); if (m_oaChildren.GetSize() != 0) mfprintf(a,"\n"); for (z=0;zREC_FindAddNode(s.Mid(1)); BTOUT; } void CDatabase::DumpTree() { BTIN; m_pRoot->REC_DumpTree(0,0xFFFFFFFF,false); BTOUT; } int CDatabase::GetElementType(CxString s) { BTIN; if (s[0] != '/') { mprintf("CDatabase::GetElementType(CxString): Invalid format.\n"); BTOUT; return 0; } CDatabaseNode *n; n = m_pRoot->REC_FindNode((s.Mid(1)).Left(s.FindLast('/')-1)); if (n == NULL) { BTOUT; return 0; } BTOUT; return n->FindValue(s.Mid(s.FindLast('/')+1))->m_iType; } unsigned long CDatabase::GetInt(CxString s) { BTIN; if (s[0] != '/') { eprintf("CDatabase::GetInt(CxString): Invalid format.\n"); BTOUT; return 0; } CDatabaseNode *n; CDatabaseValue *v; n = m_pRoot->REC_FindNode((s.Mid(1)).Left(s.FindLast('/')-1)); if (n == NULL) { eprintf("CDatabase::GetInt(CxString): Node \"%s\" not found.\n",(const char*)s); BTOUT; return 0; } v = n->FindValue(s.Mid(s.FindLast('/')+1)); if (v == NULL) { eprintf("CDatabase::GetInt(CxString): Value \"%s\" not found.\n",(const char*)s.Mid(s.FindLast('/')+1)); BTOUT; return 0; } if (v->m_iType != 1) { eprintf("CDatabase::GetInt(CxString): Value \"%s\" is not an integer value.\n",(const char*)s.Mid(s.FindLast('/')+1)); BTOUT; return 0; } BTOUT; return (unsigned long)v->m_pValue; } double CDatabase::GetFloat(CxString s) { BTIN; if (s[0] != '/') { eprintf("CDatabase::GetFloat(CxString): Invalid format.\n"); BTOUT; return 0; } CDatabaseNode *n; CDatabaseValue *v; n = m_pRoot->REC_FindNode((s.Mid(1)).Left(s.FindLast('/')-1)); if (n == NULL) { eprintf("CDatabase::GetFloat(CxString): Node \"%s\" not found.\n",(const char*)s); BTOUT; return 0; } v = n->FindValue(s.Mid(s.FindLast('/')+1)); if (v == NULL) { eprintf("CDatabase::GetFloat(CxString): Value \"%s\" not found.\n",(const char*)s.Mid(s.FindLast('/')+1)); BTOUT; return 0; } if (v->m_iType != 2) { eprintf("CDatabase::GetFloat(CxString): Value \"%s\" ist not a float value.\n",(const char*)s.Mid(s.FindLast('/')+1)); BTOUT; return 0; } BTOUT; return *(double*)v->m_pValue; } int CDatabase::GetArraySize(CxString s) { BTIN; if (s[0] != '/') { eprintf("CDatabase::GetArraySize(CxString): Invalid format.\n"); BTOUT; return 0; } CDatabaseNode *n; CDatabaseValue *v; n = m_pRoot->REC_FindNode((s.Mid(1)).Left(s.FindLast('/')-1)); if (n == NULL) { eprintf("CDatabase::GetArraySize(CxString): Node \"%s\" not found.\n",(const char*)s); BTOUT; return 0; } v = n->FindValue(s.Mid(s.FindLast('/')+1)); if (v == NULL) { eprintf("CDatabase::GetArraySize(CxString): Value \"%s\" not found.\n",(const char*)s.Mid(s.FindLast('/')+1)); BTOUT; return 0; } if (v->m_iType != 5) { eprintf("CDatabase::GetArraySize(CxString): Value \"%s\" ist not an array.\n",(const char*)s.Mid(s.FindLast('/')+1)); BTOUT; return 0; } BTOUT; return ((CxObArray*)v->m_pValue)->GetSize(); } int CDatabase::GetArrayElementType(CxString s, int i) { BTIN; if (s[0] != '/') { eprintf("CDatabase::GetArrayElementType(CxString,int): Invalid Format.\n"); BTOUT; return 0; } CDatabaseNode *n; CDatabaseValue *v; n = m_pRoot->REC_FindNode((s.Mid(1)).Left(s.FindLast('/')-1)); if (n == NULL) { eprintf("CDatabase::GetArrayElementType(CxString,int): Node \"%s\" not found.\n",(const char*)s); BTOUT; return 0; } v = n->FindValue(s.Mid(s.FindLast('/')+1)); if (v == NULL) { eprintf("CDatabase::GetArrayElementType(CxString,int): Value \"%s\" not found.\n",(const char*)s.Mid(s.FindLast('/')+1)); BTOUT; return 0; } if (v->m_iType != 5) { eprintf("CDatabase::GetArrayElementType(CxString,int): Value \"%s\" is not an array.\n",(const char*)s.Mid(s.FindLast('/')+1)); BTOUT; return 0; } BTOUT; return ((CDatabaseValue*)((CxObArray*)v->m_pValue)->GetAt(i))->m_iType; } int CDatabase::GetArrayInt(CxString s, int i) { BTIN; if (s[0] != '/') { eprintf("CDatabase::GetArrayInt(CxString,int): Invalid format.\n"); BTOUT; return 0; } CDatabaseNode *n; CDatabaseValue *v, *v2; n = m_pRoot->REC_FindNode((s.Mid(1)).Left(s.FindLast('/')-1)); if (n == NULL) { eprintf("CDatabase::GetArrayInt(CxString,int): Node \"%s\" not found.\n",(const char*)s); BTOUT; return 0; } v = n->FindValue(s.Mid(s.FindLast('/')+1)); if (v == NULL) { eprintf("CDatabase::GetArrayInt(CxString,int): Value \"%s\" not found.\n",(const char*)s.Mid(s.FindLast('/')+1)); BTOUT; return 0; } if (v->m_iType != 5) { eprintf("CDatabase::GetArrayInt(CxString,int): Value \"%s\" is not an array.\n",(const char*)s.Mid(s.FindLast('/')+1)); BTOUT; return 0; } v2 = (CDatabaseValue*)((CxObArray*)v->m_pValue)->GetAt(i); if (v2->m_iType != 1) { eprintf("CDatabase::GetArrayInt(CxString,int): Value \"%s\"(%d) is not an integer value.\n",(const char*)s.Mid(s.FindLast('/')+1),i); BTOUT; return 0; } BTOUT; return (long)v2->m_pValue; } double CDatabase::GetArrayFloat(CxString s, int i) { BTIN; if (s[0] != '/') { eprintf("CDatabase::GetArrayFloat(CxString,int): Invalid format.\n"); BTOUT; return 0; } CDatabaseNode *n; CDatabaseValue *v, *v2; n = m_pRoot->REC_FindNode((s.Mid(1)).Left(s.FindLast('/')-1)); if (n == NULL) { eprintf("CDatabase::GetArrayFloat(CxString,int): Node \"%s\" not found.\n",(const char*)s); BTOUT; return 0; } v = n->FindValue(s.Mid(s.FindLast('/')+1)); if (v == NULL) { eprintf("CDatabase::GetArrayFloat(CxString,int): Value \"%s\" not found.\n",(const char*)s.Mid(s.FindLast('/')+1)); BTOUT; return 0; } if (v->m_iType != 5) { eprintf("CDatabase::GetArrayFloat(CxString,int): Value \"%s\" is not an array.\n",(const char*)s.Mid(s.FindLast('/')+1)); BTOUT; return 0; } v2 = (CDatabaseValue*)((CxObArray*)v->m_pValue)->GetAt(i); if (v2->m_iType != 2) { eprintf("CDatabase::GetArrayFloat(CxString,int): Value \"%s\"(%d) is not a floating point value.\n",(const char*)s.Mid(s.FindLast('/')+1),i); BTOUT; return 0; } BTOUT; return *(double*)v2->m_pValue; } bool CDatabase::GetArrayBool(CxString s, int i) { BTIN; if (s[0] != '/') { eprintf("CDatabase::GetArrayBool(CxString,int): Invalid format.\n"); BTOUT; return 0; } CDatabaseNode *n; CDatabaseValue *v, *v2; n = m_pRoot->REC_FindNode((s.Mid(1)).Left(s.FindLast('/')-1)); if (n == NULL) { eprintf("CDatabase::GetArrayBool(CxString,int): Node \"%s\" not found.\n",(const char*)s); BTOUT; return 0; } v = n->FindValue(s.Mid(s.FindLast('/')+1)); if (v == NULL) { eprintf("CDatabase::GetArrayBool(CxString,int): Value \"%s\" not found.\n",(const char*)s.Mid(s.FindLast('/')+1)); BTOUT; return 0; } if (v->m_iType != 5) { eprintf("CDatabase::GetArrayBool(CxString,int): Value \"%s\" is not an array.\n",(const char*)s.Mid(s.FindLast('/')+1)); BTOUT; return 0; } v2 = (CDatabaseValue*)((CxObArray*)v->m_pValue)->GetAt(i); if (v2->m_iType != 4) { eprintf("CDatabase::GetArrayBool(CxString,int): Value \"%s\"(%d) is not a boolean value.\n",(const char*)s.Mid(s.FindLast('/')+1),i); BTOUT; return 0; } BTOUT; return (v2->m_pValue!=NULL); } const char* CDatabase::GetArrayString(CxString s, int i) { BTIN; if (s[0] != '/') { eprintf("CDatabase::GetArrayString(CxString,int): Invalid format.\n"); BTOUT; return 0; } CDatabaseNode *n; CDatabaseValue *v, *v2; n = m_pRoot->REC_FindNode((s.Mid(1)).Left(s.FindLast('/')-1)); if (n == NULL) { eprintf("CDatabase::GetArrayString(CxString,int): Node \"%s\" not found.\n",(const char*)s); BTOUT; return 0; } v = n->FindValue(s.Mid(s.FindLast('/')+1)); if (v == NULL) { eprintf("CDatabase::GetArrayString(CxString,int): Value \"%s\" not found.\n",(const char*)s.Mid(s.FindLast('/')+1)); BTOUT; return 0; } if (v->m_iType != 5) { eprintf("CDatabase::GetArrayString(CxString,int): Value \"%s\" is not an array.\n",(const char*)s.Mid(s.FindLast('/')+1)); BTOUT; return 0; } v2 = (CDatabaseValue*)((CxObArray*)v->m_pValue)->GetAt(i); if (v2->m_iType != 3) { eprintf("CDatabase::GetArrayString(CxString,int): Value \"%s\"(%d) is not a character string.\n",(const char*)s.Mid(s.FindLast('/')+1),i); BTOUT; return 0; } BTOUT; return (char*)v2->m_pValue; } void CDatabase::SetArrayInt(CxString s, int i, int i2) { BTIN; if (s[0] != '/') { eprintf("CDatabase::SetArrayInt(CxString,int,int): Invalid format.\n"); BTOUT; return; } CDatabaseNode *n; CDatabaseValue *v, *v2; n = m_pRoot->REC_FindNode((s.Mid(1)).Left(s.FindLast('/')-1)); if (n == NULL) { eprintf("CDatabase::SetArrayInt(CxString,int,int): Node \"%s\" not found.\n",(const char*)s); BTOUT; return; } v = n->FindValue(s.Mid(s.FindLast('/')+1)); if (v == NULL) { eprintf("CDatabase::SetArrayInt(CxString,int,int): Value \"%s\" not found.\n",(const char*)s.Mid(s.FindLast('/')+1)); BTOUT; return; } if (v->m_iType != 5) { eprintf("CDatabase::SetArrayInt(CxString,int,int): Value \"%s\" is not an array.\n",(const char*)s.Mid(s.FindLast('/')+1)); BTOUT; return; } v2 = (CDatabaseValue*)((CxObArray*)v->m_pValue)->GetAt(i); if (v2->m_iType != 1) { eprintf("CDatabase::SetArrayInt(CxString,int,int): Value \"%s\"(%d) is not an integer value.\n",(const char*)s.Mid(s.FindLast('/')+1),i); BTOUT; return; } v2->m_pValue = (void*)((unsigned long)i2); BTOUT; } void CDatabase::SetArrayFloat(CxString s, int i, double d) { BTIN; if (s[0] != '/') { eprintf("CDatabase::SetArrayFloat(CxString,int,double): Invalid format.\n"); BTOUT; return; } CDatabaseNode *n; CDatabaseValue *v, *v2; n = m_pRoot->REC_FindNode((s.Mid(1)).Left(s.FindLast('/')-1)); if (n == NULL) { eprintf("CDatabase::SetArrayFloat(CxString,int,double): Node \"%s\" not found.\n",(const char*)s); BTOUT; return; } v = n->FindValue(s.Mid(s.FindLast('/')+1)); if (v == NULL) { eprintf("CDatabase::SetArrayFloat(CxString,int,double): Value \"%s\" not found.\n",(const char*)s.Mid(s.FindLast('/')+1)); BTOUT; return; } if (v->m_iType != 5) { eprintf("CDatabase::SetArrayFloat(CxString,int,double): Value \"%s\" is not an array.\n",(const char*)s.Mid(s.FindLast('/')+1)); BTOUT; return; } v2 = (CDatabaseValue*)((CxObArray*)v->m_pValue)->GetAt(i); if (v2->m_iType != 2) { eprintf("CDatabase::SetArrayFloat(CxString,int,double): Value \"%s\"(%d) is not a floating point value.\n",(const char*)s.Mid(s.FindLast('/')+1),i); BTOUT; return; } *(double*)v2->m_pValue = d; BTOUT; } void CDatabase::SetArrayBool(CxString s, int i, bool b) { BTIN; if (s[0] != '/') { eprintf("CDatabase::GetArrayBool(CxString,int,bool): Invalid format.\n"); BTOUT; return; } CDatabaseNode *n; CDatabaseValue *v, *v2; n = m_pRoot->REC_FindNode((s.Mid(1)).Left(s.FindLast('/')-1)); if (n == NULL) { eprintf("CDatabase::GetArrayBool(CxString,int,bool): Node \"%s\" not found.\n",(const char*)s); BTOUT; return; } v = n->FindValue(s.Mid(s.FindLast('/')+1)); if (v == NULL) { eprintf("CDatabase::GetArrayBool(CxString,int,bool): Value \"%s\" not found.\n",(const char*)s.Mid(s.FindLast('/')+1)); BTOUT; return; } if (v->m_iType != 5) { eprintf("CDatabase::GetArrayBool(CxString,int,bool): Value \"%s\" is not an array.\n",(const char*)s.Mid(s.FindLast('/')+1)); BTOUT; return; } v2 = (CDatabaseValue*)((CxObArray*)v->m_pValue)->GetAt(i); if (v2->m_iType != 4) { eprintf("CDatabase::GetArrayBool(CxString,int,bool): Value \"%s\"(%d) is not a boolean value.\n",(const char*)s.Mid(s.FindLast('/')+1),i); BTOUT; return; } v2->m_pValue = (void*)((unsigned long)(b?1:0)); BTOUT; } void CDatabase::SetArrayString(CxString s, int i, CxString s2) { BTIN; if (s[0] != '/') { eprintf("CDatabase::SetArrayString(CxString,int,CxString): Invalid format.\n"); BTOUT; return; } CDatabaseNode *n; CDatabaseValue *v, *v2; n = m_pRoot->REC_FindNode((s.Mid(1)).Left(s.FindLast('/')-1)); if (n == NULL) { eprintf("CDatabase::SetArrayString(CxString,int,CxString): Node \"%s\" not found.\n",(const char*)s); BTOUT; return; } v = n->FindValue(s.Mid(s.FindLast('/')+1)); if (v == NULL) { eprintf("CDatabase::SetArrayString(CxString,int,CxString): Value \"%s\" not found.\n",(const char*)s.Mid(s.FindLast('/')+1)); BTOUT; return; } if (v->m_iType != 5) { eprintf("CDatabase::SetArrayString(CxString,int,CxString): Value \"%s\" is not an array.\n",(const char*)s.Mid(s.FindLast('/')+1)); BTOUT; return; } v2 = (CDatabaseValue*)((CxObArray*)v->m_pValue)->GetAt(i); if (v2->m_iType != 3) { eprintf("CDatabase::SetArrayString(CxString,int,CxString): Value \"%s\"(%d) is not a character string.\n",(const char*)s.Mid(s.FindLast('/')+1),i); BTOUT; return; } delete (char*)v2->m_pValue; char *buf; try { buf = new char[s2.GetLength()+1]; } catch(...) { buf = NULL; } if (buf == NULL) NewException((double)(s2.GetLength()+1)*sizeof(char),__FILE__,__LINE__,__PRETTY_FUNCTION__); strcpy(buf,(const char*)s2); v2->m_pValue = (void*)buf; BTOUT; } const char* CDatabase::GetString(CxString s) { BTIN; if (s[0] != '/') { eprintf("CDatabase::GetString(CxString): Invalid format.\n"); BTOUT; return NULL; } CDatabaseNode *n; CDatabaseValue *v; n = m_pRoot->REC_FindNode((s.Mid(1)).Left(s.FindLast('/')-1)); if (n == NULL) { eprintf("CDatabase::GetString(CxString): Node \"%s\" not found.\n",(const char*)s); BTOUT; return NULL; } v = n->FindValue(s.Mid(s.FindLast('/')+1)); if (v == NULL) { eprintf("CDatabase::GetString(CxString): Value \"%s\" not found.\n",(const char*)s.Mid(s.FindLast('/')+1)); BTOUT; return 0; } if (v->m_iType != 3) { eprintf("CDatabase::GetString(CxString): Value \"%s\" is not a character string.\n",(const char*)s.Mid(s.FindLast('/')+1)); BTOUT; return NULL; } BTOUT; return (char*)v->m_pValue; } bool CDatabase::GetBool(CxString s) { BTIN; if (s[0] != '/') { eprintf("CDatabase::GetBool(CxString): Invalid format.\n"); BTOUT; return false; } CDatabaseNode *n; CDatabaseValue *v; n = m_pRoot->REC_FindNode((s.Mid(1)).Left(s.FindLast('/')-1)); if (n == NULL) { eprintf("CDatabase::GetBool(CxString): Node \"%s\" not found.\n",(const char*)s); BTOUT; return false; } v = n->FindValue(s.Mid(s.FindLast('/')+1)); if (v == NULL) { eprintf("CDatabase::GetBool(CxString): Value \"%s\" not found.\n",(const char*)s.Mid(s.FindLast('/')+1)); BTOUT; return false; } if (v->m_iType != 4) { eprintf("CDatabase::GetBool(CxString): Value \"%s\" is not a boolean value.\n",(const char*)s.Mid(s.FindLast('/')+1)); BTOUT; return false; } BTOUT; return (v->m_pValue != NULL); } void CDatabase::AddArray(CxString s) { BTIN; if (s[0] != '/') { eprintf("CDatabase::AddArray(CxString): Invalid format.\n"); BTOUT; return; } CDatabaseNode *n; n = m_pRoot->REC_FindAddNode((s.Mid(1)).Left(s.FindLast('/')-1)); CDatabaseValue *v; try { v = new CDatabaseValue(); } catch(...) { v = NULL; } if (v == NULL) NewException((double)sizeof(CDatabaseValue),__FILE__,__LINE__,__PRETTY_FUNCTION__); v->m_sName.Format("%s",(const char*)s.Mid(s.FindLast('/')+1)); v->m_iType = 5; try { v->m_pValue = (void*)new CxObArray("CDatabase::AddArray():v->m_pValue"); } catch(...) { v->m_pValue = NULL; } if (v->m_pValue == NULL) NewException((double)sizeof(CxObArray),__FILE__,__LINE__,__PRETTY_FUNCTION__); n->m_oaValues.Add(v); BTOUT; } void CDatabase::AddArrayBool(CxString s, bool b) { BTIN; if (s[0] != '/') { eprintf("CDatabase::AddArrayBool(CxString,bool): Invalid format.\n"); BTOUT; return; } CDatabaseNode *n; CDatabaseValue *v, *v2; n = m_pRoot->REC_FindNode((s.Mid(1)).Left(s.FindLast('/')-1)); if (n == NULL) { eprintf("CDatabase::AddArrayBool(CxString,bool): Node \"%s\" not found.\n",(const char*)s); BTOUT; return; } v = n->FindValue(s.Mid(s.FindLast('/')+1)); if (v == NULL) { eprintf("CDatabase::AddArrayBool(CxString,bool): Value \"%s\" not found.\n",(const char*)s); BTOUT; return; } if (v->m_iType != 5) { eprintf("CDatabase::AddArrayBool(CxString,bool): Value \"%s\" is not an array.\n",(const char*)s); BTOUT; return; } try { v2 = new CDatabaseValue(); } catch(...) { v2 = NULL; } if (v2 == NULL) NewException((double)sizeof(CDatabaseValue),__FILE__,__LINE__,__PRETTY_FUNCTION__); v2->m_iType = 4; v2->m_pValue = (void*)((unsigned long)(b?1:0)); v2->m_sName = ""; ((CxObArray*)v->m_pValue)->Add(v2); BTOUT; } void CDatabase::AddArrayFloat(CxString s, double d) { BTIN; if (s[0] != '/') { eprintf("CDatabase::AddArrayFloat(CxString,double): Invalid format.\n"); BTOUT; return; } CDatabaseNode *n; CDatabaseValue *v, *v2; n = m_pRoot->REC_FindNode((s.Mid(1)).Left(s.FindLast('/')-1)); if (n == NULL) { eprintf("CDatabase::AddArrayFloat(CxString,double): Node \"%s\" not found.\n",(const char*)s); BTOUT; return; } v = n->FindValue(s.Mid(s.FindLast('/')+1)); if (v == NULL) { eprintf("CDatabase::AddArrayFloat(CxString,double): Value \"%s\" not found.\n",(const char*)s); BTOUT; return; } if (v->m_iType != 5) { eprintf("CDatabase::AddArrayFloat(CxString,double): Value \"%s\" is not an array.\n",(const char*)s); BTOUT; return; } try { v2 = new CDatabaseValue(); } catch(...) { v2 = NULL; } if (v2 == NULL) NewException((double)sizeof(CDatabaseValue),__FILE__,__LINE__,__PRETTY_FUNCTION__); v2->m_iType = 2; double *t; try { t = new double; } catch(...) { t = NULL; } if (t == NULL) NewException((double)sizeof(double),__FILE__,__LINE__,__PRETTY_FUNCTION__); *t = d; v2->m_pValue = (void*)t; v2->m_sName = ""; ((CxObArray*)v->m_pValue)->Add(v2); BTOUT; } void CDatabase::AddArrayInt(CxString s, int i) { BTIN; if (s[0] != '/') { eprintf("CDatabase::AddArrayInt(CxString,int): Invalid format.\n"); BTOUT; return; } CDatabaseNode *n; CDatabaseValue *v, *v2; n = m_pRoot->REC_FindNode((s.Mid(1)).Left(s.FindLast('/')-1)); if (n == NULL) { eprintf("CDatabase::AddArrayInt(CxString,int): Node \"%s\" not found.\n",(const char*)s); BTOUT; return; } v = n->FindValue(s.Mid(s.FindLast('/')+1)); if (v == NULL) { eprintf("CDatabase::AddArrayInt(CxString,int): Value \"%s\" not found.\n",(const char*)s); BTOUT; return; } if (v->m_iType != 5) { eprintf("CDatabase::AddArrayInt(CxString,int): Value \"%s\" is not an array.\n",(const char*)s); BTOUT; return; } try { v2 = new CDatabaseValue(); } catch(...) { v2 = NULL; } if (v2 == NULL) NewException((double)sizeof(CDatabaseValue),__FILE__,__LINE__,__PRETTY_FUNCTION__); v2->m_iType = 1; v2->m_pValue = (void*)((unsigned long)i); v2->m_sName = ""; ((CxObArray*)v->m_pValue)->Add(v2); BTOUT; } void CDatabase::AddArrayString(CxString s, CxString s2) { BTIN; if (s[0] != '/') { eprintf("CDatabase::AddArrayString(CxString,CxString): Invalid format.\n"); BTOUT; return; } CDatabaseNode *n; CDatabaseValue *v, *v2; n = m_pRoot->REC_FindNode((s.Mid(1)).Left(s.FindLast('/')-1)); if (n == NULL) { eprintf("CDatabase::AddArrayString(CxString,CxString): Node \"%s\" not found.\n",(const char*)s); BTOUT; return; } v = n->FindValue(s.Mid(s.FindLast('/')+1)); if (v == NULL) { eprintf("CDatabase::AddArrayString(CxString,CxString): Value \"%s\" not found.\n",(const char*)s); BTOUT; return; } if (v->m_iType != 5) { eprintf("CDatabase::AddArrayString(CxString,CxString): Value \"%s\" is not an array.\n",(const char*)s); BTOUT; return; } try { v2 = new CDatabaseValue(); } catch(...) { v2 = NULL; } if (v2 == NULL) NewException((double)sizeof(CDatabaseValue),__FILE__,__LINE__,__PRETTY_FUNCTION__); v2->m_iType = 3; char *buf; try { buf = new char[s2.GetLength()+1]; } catch(...) { buf = NULL; } if (buf == NULL) NewException((double)(s2.GetLength()+1)*sizeof(char),__FILE__,__LINE__,__PRETTY_FUNCTION__); strcpy(buf,(const char*)s2); v2->m_pValue = (void*)buf; v2->m_sName = ""; ((CxObArray*)v->m_pValue)->Add(v2); BTOUT; } void CDatabase::AddInt(CxString s, int i) { BTIN; if (s[0] != '/') { eprintf("CDatabase::AddInt(CxString,int): Invalid format.\n"); BTOUT; return; } CDatabaseNode *n; n = m_pRoot->REC_FindAddNode((s.Mid(1)).Left(s.FindLast('/')-1)); CDatabaseValue *v; try { v = new CDatabaseValue(); } catch(...) { v = NULL; } if (v == NULL) NewException((double)sizeof(CDatabaseValue),__FILE__,__LINE__,__PRETTY_FUNCTION__); v->m_sName.Format("%s",(const char*)s.Mid(s.FindLast('/')+1)); v->m_iType = 1; v->m_pValue = (void*)((unsigned long)i); n->m_oaValues.Add(v); BTOUT; } void CDatabase::AddFloat(CxString s, double d) { BTIN; if (s[0] != '/') { eprintf("CDatabase::AddFloat(CxString,double): Invalid format.\n"); BTOUT; return; } CDatabaseNode *n; n = m_pRoot->REC_FindAddNode((s.Mid(1)).Left(s.FindLast('/')-1)); CDatabaseValue *v; try { v = new CDatabaseValue(); } catch(...) { v = NULL; } if (v == NULL) NewException((double)sizeof(CDatabaseValue),__FILE__,__LINE__,__PRETTY_FUNCTION__); v->m_sName.Format("%s",(const char*)s.Mid(s.FindLast('/')+1)); v->m_iType = 2; double *t; try { t = new double; } catch(...) { t = NULL; } if (t == NULL) NewException((double)sizeof(double),__FILE__,__LINE__,__PRETTY_FUNCTION__); *t = d; v->m_pValue = (void*)t; n->m_oaValues.Add(v); BTOUT; } void CDatabase::AddString(CxString s, CxString s2) { BTIN; if (s[0] != '/') { eprintf("CDatabase::AddString(CxString,CxString): Invalid format.\n"); BTOUT; return; } CDatabaseNode *n; n = m_pRoot->REC_FindAddNode((s.Mid(1)).Left(s.FindLast('/')-1)); CDatabaseValue *v; try { v = new CDatabaseValue(); } catch(...) { v = NULL; } if (v == NULL) NewException((double)sizeof(CDatabaseValue),__FILE__,__LINE__,__PRETTY_FUNCTION__); v->m_sName.Format("%s",(const char*)s.Mid(s.FindLast('/')+1)); v->m_iType = 3; char *buf; try { buf = new char[s2.GetLength()+1]; } catch(...) { buf = NULL; } if (buf == NULL) NewException((double)(s2.GetLength()+1)*sizeof(char),__FILE__,__LINE__,__PRETTY_FUNCTION__); strcpy(buf,(const char*)s2); v->m_pValue = (void*)buf; n->m_oaValues.Add(v); BTOUT; } void CDatabase::AddBool(CxString s, bool val) { BTIN; if (s[0] != '/') { eprintf("CDatabase::AddBool(CxString): Invalid format.\n"); BTOUT; return; } CDatabaseNode *n; n = m_pRoot->REC_FindAddNode((s.Mid(1)).Left(s.FindLast('/')-1)); CDatabaseValue *v; try { v = new CDatabaseValue(); } catch(...) { v = NULL; } if (v == NULL) NewException((double)sizeof(CDatabaseValue),__FILE__,__LINE__,__PRETTY_FUNCTION__); v->m_sName.Format("%s",(const char*)s.Mid(s.FindLast('/')+1)); v->m_iType = 4; v->m_pValue = (void*)((unsigned long)(val?1:0)); n->m_oaValues.Add(v); BTOUT; } void CDatabase::SetInt(CxString s, int i) { BTIN; if (s[0] != '/') { eprintf("CDatabase::SetInt(CxString,int): Invalid format.\n"); BTOUT; return; } CDatabaseNode *n; CDatabaseValue *v; n = m_pRoot->REC_FindNode((s.Mid(1)).Left(s.FindLast('/')-1)); if (n == NULL) { eprintf("CDatabase::SetInt(CxString,int): Node \"%s\" not found.\n",(const char*)(s.Mid(1)).Left(s.FindLast('/')-1)); BTOUT; return; } v = n->FindValue(s.Mid(s.FindLast('/')+1)); if (v == NULL) { eprintf("CDatabase::SetInt(CxString,int): Value \"%s\" not found.\n",(const char*)s.Mid(s.FindLast('/')+1)); BTOUT; return; } if (v->m_iType != 1) { eprintf("CDatabase::SetInt(CxString,int): Value \"%s\" is not an integer value.\n",(const char*)s.Mid(s.FindLast('/')+1)); BTOUT; return; } v->m_pValue = (void*)((unsigned long)i); BTOUT; } void CDatabase::SetFloat(CxString s, double d) { BTIN; if (s[0] != '/') { eprintf("CDatabase::SetFloat(CxString,double): Invalid format.\n"); BTOUT; return; } CDatabaseNode *n; CDatabaseValue *v; n = m_pRoot->REC_FindNode((s.Mid(1)).Left(s.FindLast('/')-1)); if (n == NULL) { eprintf("CDatabase::SetFloat(CxString,double): Node \"%s\" not found.\n",(const char*)(s.Mid(1)).Left(s.FindLast('/')-1)); BTOUT; return; } v = n->FindValue(s.Mid(s.FindLast('/')+1)); if (v == NULL) { eprintf("CDatabase::SetFloat(CxString,double): Value \"%s\" not found.\n",(const char*)s.Mid(s.FindLast('/')+1)); BTOUT; return; } if (v->m_iType != 2) { eprintf("CDatabase::SetFloat(CxString,double): Value \"%s\" is not a floating point value.\n",(const char*)s.Mid(s.FindLast('/')+1)); BTOUT; return; } *(double*)v->m_pValue = d; BTOUT; } void CDatabase::SetString(CxString s, CxString s2) { BTIN; if (s[0] != '/') { eprintf("CDatabase::SetString(CxString,CxString): Invalid format.\n"); BTOUT; return; } CDatabaseNode *n; CDatabaseValue *v; n = m_pRoot->REC_FindNode((s.Mid(1)).Left(s.FindLast('/')-1)); if (n == NULL) { eprintf("CDatabase::SetString(CxString,CxString): Node \"%s\" not found.\n",(const char*)(s.Mid(1)).Left(s.FindLast('/')-1)); BTOUT; return; } v = n->FindValue(s.Mid(s.FindLast('/')+1)); if (v == NULL) { eprintf("CDatabase::SetString(CxString,CxString): Value \"%s\" not found.\n",(const char*)s.Mid(s.FindLast('/')+1)); BTOUT; return; } if (v->m_iType != 3) { eprintf("CDatabase::SetString(CxString,CxString): Value \"%s\" is not a character string.\n",(const char*)s.Mid(s.FindLast('/')+1)); BTOUT; return; } delete[] (char*)v->m_pValue; char *buf; try { buf = new char[s2.GetLength()+1]; } catch(...) { buf = NULL; } if (buf == NULL) NewException((double)(s2.GetLength()+1)*sizeof(char),__FILE__,__LINE__,__PRETTY_FUNCTION__); strcpy(buf,(const char*)s2); v->m_pValue = (void*)buf; BTOUT; } void CDatabase::SetBool(CxString s, bool b) { BTIN; if (s[0] != '/') { eprintf("CDatabase::SetBool(CxString,bool): Invalid format.\n"); BTOUT; return; } CDatabaseNode *n; CDatabaseValue *v; n = m_pRoot->REC_FindNode((s.Mid(1)).Left(s.FindLast('/')-1)); if (n == NULL) { eprintf("CDatabase::SetBool(CxString,bool): Node \"%s\" not found.\n",(const char*)(s.Mid(1)).Left(s.FindLast('/')-1)); BTOUT; return; } v = n->FindValue(s.Mid(s.FindLast('/')+1)); if (v == NULL) { eprintf("CDatabase::SetBool(CxString,bool): Value \"%s\" not found.\n",(const char*)s.Mid(s.FindLast('/')+1)); BTOUT; return; } if (v->m_iType != 4) { eprintf("CDatabase::SetBool(CxString,bool): Value \"%s\" is not a boolean value.\n",(const char*)s.Mid(s.FindLast('/')+1)); BTOUT; return; } v->m_pValue = (void*)((unsigned long)(b?1:0)); BTOUT; } bool CDatabase::WriteOutputFile(CxString s) { BTIN; FILE *a; //a = OpenFileWrite((const char*)s,true); a = fopen((const char*)s,"wt"); if (a == NULL) { eprintf("CDatabase::WriteOutputFile(): Error: Could not open File \"%s\" for writing.\nBe sure to have writing permission for this directory.\n",(const char*)s); abort(); } m_pRoot->REC_WriteOutputFile(a,0); mfprintf(a,"\n"); fclose(a); BTOUT; return true; } void CDatabase::ParseInputFile(const char *s) { BTIN; FILE *a; char *p, *q=NULL, *tc; char buf[1024], tbuf[1024], t2buf[1024], buf2[1024]; // CxString buf, tbuf, t2buf, buf2; CDatabaseNode *cnode, *tnode; CDatabaseValue *val=NULL, *val2; double *td; int tabx=0, taby=0; bool tstring, section, endsection, name, value, namegiven, eq, tdouble, tint, valuegiven, array, table, linevalue; cnode = m_pRoot; a = fopen(s,"rt"); if (a == NULL) { eprintf("CDatabase::ParseInputFile(char*): Could not open file \"%s\".\n",s); BTOUT; return; } table = false; while (!feof(a)) { if (!fgets(buf,256,a)) continue; buf[strlen(buf)-1] = 0; #ifdef DEBUG_DATABASE mprintf("*** \"%s\" ***\n",buf); #endif p = buf; tstring = false; section = false; endsection = false; name = false; value = false; namegiven = false; eq = false; tdouble = false; tint = false; valuegiven = false; array = false; linevalue = false; while (true) { if (*p == '\\') { if (p > buf) { if (*(p-1) == '\\') goto _nolincont; } else if (*p != 0) if (*(p+1) == '\\') goto _nolincont; #ifdef DEBUG_DATABASE mprintf("Zeilenumbruch!\np=\"%s\"\nq=\"%s\"\n",p,q); #endif *p = 0; (void)fgets(buf2,256,a); buf2[strlen(buf2)-1] = 0; #ifdef DEBUG_DATABASE mprintf("buf=\"%s\"\nbuf2=\"%s\"\n",buf,buf2); #endif strcat(buf,buf2); #ifdef DEBUG_DATABASE mprintf("Neuer buf=\"%s\"\n",buf); #endif } _nolincont: if (array) { if ((!tstring) && (*p == '{')) { #ifdef DEBUG_DATABASE mprintf("ARRAY ERROR: Nested Arrays not allowed.\n"); #endif array = false; goto _linedone; } if ((!tstring) && ((*p == ',') || (*p == '}') || (*p == ' ') || (*p == '\t'))) { if ((*p == ',') || (*p == ' ') ||(*p == '\t')) { if (value) { #ifdef DEBUG_DATABASE mprintf("ARRAY NEXT ELEMENT\n"); #endif } else { q = p+1; goto _chardone; } } else if (*p == '}') { array = false; #ifdef DEBUG_DATABASE mprintf("ARRAY DONE\n"); #endif if (!value) goto _linedone; } if (valuegiven) { valuegiven = false; q = p+1; value = false; goto _chardone; } if (tint) { memcpy(tbuf,q,p-q); tbuf[p-q] = 0; try { val2 = new CDatabaseValue(); } catch(...) { val2 = NULL; } if (val2 == NULL) NewException((double)sizeof(CDatabaseValue),__FILE__,__LINE__,__PRETTY_FUNCTION__); val2->m_sName.Format("%s",t2buf); val2->m_iType = 1; val2->m_pValue = (void*)((unsigned long)atoi(tbuf)); ((CxObArray*)val->m_pValue)->Add(val2); #ifdef DEBUG_DATABASE mprintf("ARRAY INT \"%s\" = %d\n",tbuf,val2->m_pValue); #endif } else if (tdouble) { memcpy(tbuf,q,p-q); tbuf[p-q] = 0; try { val2 = new CDatabaseValue(); } catch(...) { val2 = NULL; } if (val2 == NULL) NewException((double)sizeof(CDatabaseValue),__FILE__,__LINE__,__PRETTY_FUNCTION__); val2->m_sName.Format("%s",t2buf); val2->m_iType = 2; try { td = new double; } catch(...) { td = NULL; } if (td == NULL) NewException((double)sizeof(double),__FILE__,__LINE__,__PRETTY_FUNCTION__); *td = atof(tbuf); val2->m_pValue = (void*)td; ((CxObArray*)val->m_pValue)->Add(val2); #ifdef DEBUG_DATABASE mprintf("ARRAY DOUBLE \"%s\" = %f\n",tbuf,*td); #endif } else { memcpy(tbuf,q,p-q); tbuf[p-q] = 0; if (mystricmp(tbuf,"true")==0) { try { val2 = new CDatabaseValue(); } catch(...) { val2 = NULL; } if (val2 == NULL) NewException((double)sizeof(CDatabaseValue),__FILE__,__LINE__,__PRETTY_FUNCTION__); val2->m_sName.Format("%s",t2buf); val2->m_iType = 4; val2->m_pValue = (void*)1; ((CxObArray*)val->m_pValue)->Add(val2); #ifdef DEBUG_DATABASE mprintf("ARRAY BOOL \"%s\" = TRUE\n",tbuf); #endif } else if (mystricmp(tbuf,"false")==0) { try { val2 = new CDatabaseValue(); } catch(...) { val2 = NULL; } if (val2 == NULL) NewException((double)sizeof(CDatabaseValue),__FILE__,__LINE__,__PRETTY_FUNCTION__); val2->m_sName.Format("%s",t2buf); val2->m_iType = 4; val2->m_pValue = (void*)0; ((CxObArray*)val->m_pValue)->Add(val2); #ifdef DEBUG_DATABASE mprintf("ARRAY BOOL \"%s\" = FALSE\n",tbuf); #endif } else eprintf("CDatabase::ParseInputFile(char*): Unrecognized array element \"%s\".\n",tbuf); } tint = false; tdouble = false; value = false; q = p+1; if (!array) goto _linedone; else goto _chardone; } if ((!tstring) && (*p == '"')) { tstring = true; q = p+1; #ifdef DEBUG_DATABASE mprintf("ARRAY STRING ANFANG\n"); #endif goto _chardone; } if (tstring && (*p == '"')) { tstring = false; valuegiven = true; value = true; memcpy(tbuf,q,p-q); tbuf[p-q] = 0; #ifdef DEBUG_DATABASE mprintf("ARRAY STRING ENDE: \"%s\".\n",tbuf); #endif try { val2 = new CDatabaseValue(); } catch(...) { val2 = NULL; } if (val2 == NULL) NewException((double)sizeof(CDatabaseValue),__FILE__,__LINE__,__PRETTY_FUNCTION__); val2->m_sName.Format("%s",t2buf); val2->m_iType = 3; try { tc = new char[strlen(tbuf)+1]; } catch(...) { tc = NULL; } if (tc == NULL) NewException((double)(strlen(tbuf)+1)*sizeof(char),__FILE__,__LINE__,__PRETTY_FUNCTION__); strcpy(tc,tbuf); RemoveDoubleBackslash(tc); val2->m_pValue = (void*)tc; ((CxObArray*)val->m_pValue)->Add(val2); goto _chardone; } if ((!tstring) && (*p >= '0') && (*p <= '9') && (!tdouble)) { #ifdef DEBUG_DATABASE mprintf("ARRAY INT ANFANG\n"); #endif tint = true; value = true; goto _chardone; } if ((!tstring) && (*p == '.')) { #ifdef DEBUG_DATABASE mprintf("ARRAY DOUBLE ANFANG\n"); #endif tint = false; tdouble = true; value = true; goto _chardone; } if (!value) { #ifdef DEBUG_DATABASE mprintf("ARRAY BOOL ANFANG\n"); #endif value = true; } goto _chardone; } // ARRAY ENDE if (table) { if ((!tstring) && (*p == '$')) { if (!value) { #ifdef DEBUG_DATABASE mprintf("TABLE ENDE\n"); #endif table = false; #ifdef DEBUG_DATABASE mprintf("\nHier die Tabelle:\n"); ((CDatabaseTable*)val->m_pValue)->DumpTable(); mprintf("**ENDE**\n"); #endif goto _linedone; } } if ((*p == '\r') || (*p == '\n') || (*p == 0)) { if (!linevalue) { #ifdef DEBUG_DATABASE mprintf("TABLE EMPTY LINE\n"); #endif goto _linedone; } else { #ifdef DEBUG_DATABASE mprintf("TABLE LINE END\n"); #endif if (!value) { tabx = 0; taby++; goto _linedone; } } } if ((!tstring) && ((*p == ',') || (*p == ' ') || (*p == '\t') || (*p == 0) || (*p == '\r') || (*p == '\n') || (*p == '$'))) { if ((*p == ',') || (*p == ' ') || (*p == '\t')) { if (value) { #ifdef DEBUG_DATABASE mprintf("TABLE NEXT ELEMENT\n"); #endif } else { q = p+1; goto _chardone; } } if (valuegiven) { valuegiven = false; q = p+1; value = false; goto _chardone; } if (tint) { memcpy(tbuf,q,p-q); tbuf[p-q] = 0; ((CDatabaseTable*)val->m_pValue)->AddInt(tabx,taby,atoi(tbuf)); #ifdef DEBUG_DATABASE mprintf("TABLE INT \"%s\" = %d\n",tbuf,atoi(tbuf)); #endif tabx++; } else if (tdouble) { memcpy(tbuf,q,p-q); tbuf[p-q] = 0; ((CDatabaseTable*)val->m_pValue)->AddDouble(tabx,taby,atof(tbuf)); #ifdef DEBUG_DATABASE mprintf("TABLE DOUBLE \"%s\" = %f\n",tbuf,atof(tbuf)); #endif tabx++; } else { memcpy(tbuf,q,p-q); tbuf[p-q] = 0; if (mystricmp(tbuf,"true")==0) { ((CDatabaseTable*)val->m_pValue)->AddBool(tabx,taby,true); #ifdef DEBUG_DATABASE mprintf("TABLE BOOL \"%s\" = TRUE\n",tbuf); #endif tabx++; } else if (mystricmp(tbuf,"false")==0) { ((CDatabaseTable*)val->m_pValue)->AddBool(tabx,taby,false); #ifdef DEBUG_DATABASE mprintf("TABLE BOOL \"%s\" = FALSE\n",tbuf); #endif tabx++; } else if (strcmp(tbuf,"-")==0) { #ifdef DEBUG_DATABASE mprintf("TABLE PLACEHOLDER\n"); #endif tabx++; } else eprintf("CDatabase::ParseInputFile(char*): Unrecognized table element \"%s\".\n",tbuf); } if (*p == '$') { #ifdef DEBUG_DATABASE mprintf("TABLE END\n"); #endif table = false; } tint = false; tdouble = false; value = false; q = p+1; if (!table) goto _linedone; else goto _chardone; } if ((!tstring) && (*p == '"')) { tstring = true; linevalue = true; q = p+1; #ifdef DEBUG_DATABASE mprintf("TABLE STRING ANFANG\n"); #endif goto _chardone; } if (tstring && (*p == '"')) { tstring = false; valuegiven = true; value = true; memcpy(tbuf,q,p-q); tbuf[p-q] = 0; #ifdef DEBUG_DATABASE mprintf("TABLE STRING ENDE: \"%s\".\n",tbuf); #endif try { tc = new char[strlen(tbuf)+1]; } catch(...) { tc = NULL; } if (tc == NULL) NewException((double)(strlen(tbuf)+1)*sizeof(char),__FILE__,__LINE__,__PRETTY_FUNCTION__); strcpy(tc,tbuf); RemoveDoubleBackslash(tc); ((CDatabaseTable*)val->m_pValue)->AddString(tabx,taby,tc); delete[] tc; tabx++; goto _chardone; } if ((!tstring) && (*p >= '0') && (*p <= '9') && (!tdouble)) { #ifdef DEBUG_DATABASE mprintf("TABLE INT ANFANG\n"); #endif tint = true; value = true; linevalue = true; goto _chardone; } if ((!tstring) && (*p == '.')) { #ifdef DEBUG_DATABASE mprintf("TABLE DOUBLE ANFANG\n"); #endif tint = false; tdouble = true; value = true; linevalue = true; goto _chardone; } if (!value) { #ifdef DEBUG_DATABASE mprintf("TABLE BOOL ANFANG\n"); #endif value = true; linevalue = true; } goto _chardone; } // TABLE ENDE if ((tstring && (*p != '"')) || (*p == ' ') || (*p == '\t') || (*p == '#') || ((p > buf) && (*p == '/') && (*(p-1) == '/')) || (*p == '\r') || (*p == '\n') || (*p == 0)) { // mprintf("CHARDONE.\n",*p); if (endsection) { memcpy(tbuf,q,p-q); tbuf[p-q] = 0; #ifdef DEBUG_DATABASE mprintf("ENDSECTION \"%s\"\n",tbuf); #endif cnode = cnode->m_pParent; } else if (section) { memcpy(tbuf,q,p-q); tbuf[p-q] = 0; #ifdef DEBUG_DATABASE mprintf("SECTION \"%s\"\n",tbuf); #endif if ((tnode=cnode->REC_FindNode(tbuf)) != NULL) { #ifdef DEBUG_DATABASE mprintf("SECTION already exists.\n",tbuf); #endif } else { try { tnode = new CDatabaseNode(); } catch(...) { tnode = NULL; } if (tnode == NULL) NewException((double)sizeof(CDatabaseNode),__FILE__,__LINE__,__PRETTY_FUNCTION__); #ifdef DEBUG_DATABASE mprintf("SECTION created.\n",tbuf); #endif tnode->m_pParent = cnode; tnode->m_sName.Format("%s",tbuf); cnode->m_oaChildren.Add(tnode); } cnode = tnode; } else if (name) { name = false; namegiven = true; memcpy(tbuf,q,p-q); tbuf[p-q] = 0; strcpy(t2buf,tbuf); #ifdef DEBUG_DATABASE mprintf("NAME \"%s\".\n",tbuf); #endif } else if (value) { value = false; valuegiven = true; memcpy(tbuf,q,p-q); tbuf[p-q] = 0; #ifdef DEBUG_DATABASE mprintf("VALUE: "); #endif if (tint) { if ((val=cnode->FindValue(t2buf))!=NULL) { #ifdef DEBUG_DATABASE mprintf("VALUE already exists.\n"); #endif if (val->m_iType != 1) { eprintf("CDatabase::ParseInputFile(char*): Error: Redefinition of %s with different type.\n",t2buf); abort(); } } else { try { val = new CDatabaseValue(); } catch(...) { val = NULL; } if (val == NULL) NewException((double)sizeof(CDatabaseValue),__FILE__,__LINE__,__PRETTY_FUNCTION__); #ifdef DEBUG_DATABASE mprintf("VALUE created.\n"); #endif val->m_sName.Format("%s",t2buf); val->m_iType = 1; cnode->m_oaValues.Add(val); } val->m_pValue = (void*)((unsigned long)atoi(tbuf)); #ifdef DEBUG_DATABASE mprintf("INT\n"); #endif } else if (tdouble) { if ((val=cnode->FindValue(t2buf))!=NULL) { #ifdef DEBUG_DATABASE mprintf("VALUE already existent.\n"); #endif if (val->m_iType != 2) { eprintf("CDatabase::ParseInputFile(char*): Error: Redefinition of %s with different type.\n",t2buf); abort(); } } else { try { val = new CDatabaseValue(); } catch(...) { val = NULL; } if (val == NULL) NewException((double)sizeof(CDatabaseValue),__FILE__,__LINE__,__PRETTY_FUNCTION__); #ifdef DEBUG_DATABASE mprintf("VALUE created.\n"); #endif val->m_sName.Format("%s",t2buf); val->m_iType = 2; cnode->m_oaValues.Add(val); } try { td = new double; } catch(...) { td = NULL; } if (td == NULL) NewException((double)sizeof(double),__FILE__,__LINE__,__PRETTY_FUNCTION__); *td = atof(tbuf); val->m_pValue = (void*)td; #ifdef DEBUG_DATABASE mprintf("DOUBLE\n"); #endif } else { if ((val=cnode->FindValue(t2buf))!=NULL) { #ifdef DEBUG_DATABASE mprintf("VALUE already existent.\n"); #endif if (val->m_iType != 4) { eprintf("CDatabase::ParseInputFile(char*): Error: Redefinition of %s with different type.\n",t2buf); abort(); } } else { try { val = new CDatabaseValue(); } catch(...) { val = NULL; } if (val == NULL) NewException((double)sizeof(CDatabaseValue),__FILE__,__LINE__,__PRETTY_FUNCTION__); #ifdef DEBUG_DATABASE mprintf("VALUE created.\n"); #endif val->m_sName.Format("%s",t2buf); val->m_iType = 4; cnode->m_oaValues.Add(val); } if (mystricmp(tbuf,"true")==0) val->m_pValue = (void*)1; else if (mystricmp(tbuf,"false")==0) val->m_pValue = (void*)0; else { eprintf("CDatabase::ParseInputFile(char*): Unrecognized bool value \"%s\".\n",buf); goto _chardone; } #ifdef DEBUG_DATABASE mprintf("BOOL\n"); #endif } #ifdef DEBUG_DATABASE mprintf(" \"%s\".\n",tbuf); #endif } goto _chardone; } if (tstring && (*p == '"')) { tstring = false; valuegiven = true; memcpy(tbuf,q,p-q); tbuf[p-q] = 0; #ifdef DEBUG_DATABASE mprintf("VALUE: STRING \"%s\".\n",tbuf); #endif if ((val=cnode->FindValue(t2buf))!=NULL) { #ifdef DEBUG_DATABASE mprintf("VALUE already existent.\n"); #endif if (val->m_iType != 3) { eprintf("CDatabase::ParseInputFile(char*): Error: Redefinition of %s with different type.\n",t2buf); abort(); } } else { try { val = new CDatabaseValue(); } catch(...) { val = NULL; } if (val == NULL) NewException((double)sizeof(CDatabaseValue),__FILE__,__LINE__,__PRETTY_FUNCTION__); #ifdef DEBUG_DATABASE mprintf("VALUE created.\n"); #endif val->m_sName.Format("%s",t2buf); val->m_iType = 3; cnode->m_oaValues.Add(val); } try { tc = new char[strlen(tbuf)+1]; } catch(...) { tc = NULL; } if (tc == NULL) NewException((double)(strlen(tbuf)+1)*sizeof(char),__FILE__,__LINE__,__PRETTY_FUNCTION__); strcpy(tc,tbuf); RemoveDoubleBackslash(tc); val->m_pValue = (void*)tc; goto _chardone; } if (namegiven && (!tstring) && (*p == '"')) { tstring = true; q = p+1; // mprintf("STRING\n"); goto _chardone; } if (namegiven && (!tstring) && (*p == '{')) { array = true; q = p+1; #ifdef DEBUG_DATABASE mprintf("ARRAY START\n"); #endif try { val = new CDatabaseValue(); } catch(...) { val = NULL; } if (val == NULL) NewException((double)sizeof(CDatabaseValue),__FILE__,__LINE__,__PRETTY_FUNCTION__); val->m_sName.Format("%s",t2buf); val->m_iType = 5; try { val->m_pValue = new CxObArray("CDatabase::ParseInputFile():val->m_pValue"); } catch(...) { val->m_pValue = NULL; } if (val->m_pValue == NULL) NewException((double)sizeof(CxObArray),__FILE__,__LINE__,__PRETTY_FUNCTION__); cnode->m_oaValues.Add(val); goto _chardone; } if (namegiven && (!tstring) && (*p == '$')) { table = true; tabx = 0; taby = 0; q = p+1; #ifdef DEBUG_DATABASE mprintf("TABLE START\n"); #endif try { val = new CDatabaseValue(); } catch(...) { val = NULL; } if (val == NULL) NewException((double)sizeof(CDatabaseValue),__FILE__,__LINE__,__PRETTY_FUNCTION__); val->m_sName.Format("%s",t2buf); try { val->m_pValue = (void*) new CDatabaseTable(); } catch(...) { val->m_pValue = NULL; } if (val->m_pValue == NULL) NewException((double)sizeof(CDatabaseTable),__FILE__,__LINE__,__PRETTY_FUNCTION__); val->m_iType = 6; cnode->m_oaValues.Add(val); goto _chardone; } if (*p == '&') { #ifdef DEBUG_DATABASE mprintf("SECTION.\n"); #endif section = true; q = p+1; goto _chardone; } if ((*p == '/') && section) { #ifdef DEBUG_DATABASE mprintf("ENDSECTION.\n"); #endif endsection = true; q++; goto _chardone; } if (*p == '=') { if (name) { name = false; namegiven = true; memcpy(tbuf,q,p-q); tbuf[p-q] = 0; strcpy(t2buf,tbuf); #ifdef DEBUG_DATABASE mprintf("NAME \"%s\".\n",tbuf); #endif } if (!namegiven) { eprintf("CDatabase::ParseInputFile(char*): Error: \"=\" without variable name.\n (\"%s\")\n",buf); goto _linedone; } eq = true; goto _chardone; } if ((isalpha(*p) || (*p == '_')) && (!name) && (!namegiven) && (!section)) { // mprintf("NAME\n"); name = true; q = p; goto _chardone; } if (namegiven && eq && (!value)) { // mprintf("VALUE\n"); value = true; q = p; } if (namegiven && (!eq) && (!value) && (!name)) { #ifdef DEBUG_DATABASE mprintf("(1)STATEMENT \"%s\"\n",t2buf); #endif try { val = new CDatabaseValue(); } catch(...) { val = NULL; } if (val == NULL) NewException((double)sizeof(CDatabaseValue),__FILE__,__LINE__,__PRETTY_FUNCTION__); val->m_sName.Format("%s",t2buf); val->m_pValue = (void*)1; val->m_iType = 4; cnode->m_oaValues.Add(val); q = p; name = true; } if (value && (*p >= '0') && (*p <= '9') && (!tdouble)) { // mprintf("INT. double=%d\n",tdouble); tint = true; goto _chardone; } if (value && (*p == '.')) { // mprintf("DOUBLE\n"); tint = false; tdouble = true; goto _chardone; } _chardone: if ((*p == '#') || ((p > buf) && (*p == '/') && (*(p-1) == '/')) || (*p == '\r') || (*p == '\n') || (*p == 0)) { // mprintf("LINEDONE.\n",*p); if (namegiven && (!valuegiven)) { #ifdef DEBUG_DATABASE mprintf("(2)STATEMENT \"%s\"\n",t2buf); #endif try { val = new CDatabaseValue(); } catch(...) { val = NULL; } if (val == NULL) NewException((double)sizeof(CDatabaseValue),__FILE__,__LINE__,__PRETTY_FUNCTION__); val->m_sName.Format("%s",t2buf); val->m_pValue = (void*)1; val->m_iType = 4; cnode->m_oaValues.Add(val); } goto _linedone; } p++; } _linedone:; } fclose(a); BTOUT; } bool CDatabase::ExistNode(CxString s) { BTIN; if (s[0] != '/') { eprintf("CDatabase::ExistNode(CxString): Invalid Format.\n"); BTOUT; return 0; } CDatabaseNode *n; n = m_pRoot->REC_FindNode(s.Mid(1)); if (n == NULL) { BTOUT; return false; } BTOUT; return true; } travis-src-190101/src/database.h0100777000000000000000000001124513412725651013357 0ustar00/***************************************************************************** TRAVIS - Trajectory Analyzer and Visualizer http://www.travis-analyzer.de/ Copyright (c) 2009-2019 Martin Brehm 2012-2019 Martin Thomas 2016-2019 Sascha Gehrke This file was written by Martin Brehm. --------------------------------------------------------------------------- This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . *****************************************************************************/ #ifndef DATABASE_H #define DATABASE_H // This must always be the first include directive #include "config.h" #include "tools.h" #include "xobject.h" #include "xstring.h" #include "xobarray.h" #include "backtrace.h" class CDatabaseTable : public CxObject { public: CDatabaseTable(); ~CDatabaseTable(); void DumpTable(); void DumpTreeTable(int depth, unsigned long bitmask, bool last); void DumpOutputFile(FILE *a, int depth); void AddInt(int x, int y, signed long val); void AddDouble(int x, int y, double val); void AddString(int x, int y, CxString val); void AddBool(int x, int y, bool val); //private: unsigned char m_iWidth; unsigned short m_iHeight; CxObArray m_pValues; }; class CDatabaseValue : public CxObject { public: CDatabaseValue(); ~CDatabaseValue(); void DumpValue(); void DumpType(); void DumpOutputFile(FILE *a); //private: CxString m_sName; void *m_pValue; unsigned char m_iType; /* 0 - nichts, 1 - int, 2 - double, 3 - string, 4 - bool, 5 - array, 6 - table */ }; class CDatabaseNode : public CxObject { public: CDatabaseNode(); ~CDatabaseNode(); explicit CDatabaseNode(const char *s); CDatabaseNode* REC_FindNode(CxString s); CDatabaseNode* REC_FindAddNode(CxString s); CDatabaseValue* FindValue(CxString s); void REC_DumpTree(int depth, unsigned long bitmask, bool last); void REC_WriteOutputFile(FILE *a, int depth); CxString m_sName; //private: CxObArray m_oaChildren; CxObArray m_oaValues; CDatabaseNode *m_pParent; }; class CDatabase : public CxObject { public: CDatabase(); ~CDatabase(); void AddNode(CxString s); void DumpTree(); bool WriteOutputFile(CxString s); int GetElementType(CxString s); unsigned long GetInt(CxString s); double GetFloat(CxString s); const char* GetString(CxString s); bool GetBool(CxString s); /*******************************************/ void AddArray(CxString s); void AddArrayInt(CxString s, int i); void AddArrayFloat(CxString s, double d); void AddArrayString(CxString s, CxString st); void AddArrayBool(CxString s, bool b); int GetArraySize(CxString s); int GetArrayElementType(CxString s, int i); int GetArrayInt(CxString s, int i); double GetArrayFloat(CxString s, int i); const char* GetArrayString(CxString s, int i); bool GetArrayBool(CxString s, int i); void SetArrayInt(CxString s, int p, int i); void SetArrayFloat(CxString s, int p, double d); void SetArrayString(CxString s, int p, CxString st); void SetArrayBool(CxString s, int p, bool b); /********* Noch zu implementieren *************/ bool ExistNode(CxString s); int GetTableWidth(CxString s); int GetTableHeight(CxString s); int GetTableElementType(CxString s, int x, int y); unsigned long GetTableInt(CxString s, int x, int y); double GetTableFloat(CxString s, int x, int y); const char* GetTableString(CxString s, int x, int y); bool GetTableBool(CxString s, int x, int y); void SetTableInt(CxString s, int x, int y, int i); void SetTableFloat(CxString s, int x, int y, double d); void SetTableString(CxString s, int x, int y, CxString st); void SetTableBool(CxString s, int x, int y, bool b); void AddTable(CxString s); /************************************************/ void AddInt(CxString s, int i); void AddFloat(CxString s, double d); void AddString(CxString s, CxString s2); void AddBool(CxString s, bool val); void SetInt(CxString s, int i); void SetFloat(CxString s, double d); void SetString(CxString s, CxString s2); void SetBool(CxString s, bool val); void ParseInputFile(const char *s); private: CDatabaseNode *m_pRoot; }; #endif travis-src-190101/src/df.cpp0100777000000000000000000013175313412725631012544 0ustar00/***************************************************************************** TRAVIS - Trajectory Analyzer and Visualizer http://www.travis-analyzer.de/ Copyright (c) 2009-2019 Martin Brehm 2012-2019 Martin Thomas 2016-2019 Sascha Gehrke This file was written by Martin Brehm. --------------------------------------------------------------------------- This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . *****************************************************************************/ // This must always be the first include directive #include "config.h" #include "df.h" #include "travis.h" const char *GetRevisionInfo_df(unsigned int len) { static char buf[256]; GET_REVISION_INFO( buf, len ); return buf; } const char *GetSourceVersion_df() { static char buf[256]; GET_SOURCE_VERSION( buf ); return buf; } CDF::CDF() { m_pHistogram = NULL; m_fBinEntries = 0; m_fSkipEntries = 0; m_fSum = 0; m_fSqSum = 0; m_fMean = 0; m_fSD = 0; m_fMinInput = 1e50; m_fMaxInput = -1e50; m_iMultiCount = 0; m_iHistogramRes = 0; m_pIntegral = NULL; m_pBin = 0; m_pIntegral = 0; m_iResolution = 0; m_bLeft = false; m_pAdditionalSets = NULL; m_pAdditionalSetLabels = NULL; m_iAdditionalSets = 0; m_sLabelX = NULL; m_sLabelY = NULL; m_sLabelMulti = NULL; m_oaTimeDiffBuf.SetName("CDF::m_oaTimeDiffBuf"); } CDF::~CDF() { } void CDF::ZeroBin() { int z; for (z=0;z m_fMaxInput) m_fMaxInput = d; if ((i < 0) || (i >= m_iResolution)) { m_fSkipEntries++; BXOUT; return; } m_fBinEntries++; m_pBin[i]++; BXOUT; } void CDF::AddToBin(double d) { BXIN; double p; int ip; m_fSum += d; m_fSqSum += d*d; if (d < m_fMinInput) m_fMinInput = d; if (d > m_fMaxInput) m_fMaxInput = d; if ((d < m_fMinVal) || (d > m_fMaxVal)) { m_fSkipEntries++; BXOUT; return; } m_fBinEntries++; p = (d-m_fMinVal)*m_fFac - 0.5; ip = (int)floor(p); if (ip < 0) { ip = 0; p = 0; } else if (ip > m_iResolution-2) { ip = m_iResolution-2; p = 1.0; } else p -= ip; m_pBin[ip ] += (1.0-p); m_pBin[ip + 1] += p ; /* if (ip < 0) { m_pBin[0]++; } else if (ip > m_iResolution-2) { m_pBin[m_iResolution-1]++; } else { p -= ip; m_pBin[ip] += (1-p); m_pBin[ip+1] += p; }*/ /* ip = floor((d-m_fMinVal)*m_fFac); if (ip >= m_iResolution) ip = m_iResolution -1; m_pBin[ip]++;*/ BXOUT; } void CDF::AddToBin(double d, double v) { BXIN; double p; int ip; m_fSum += d; m_fSqSum += d*d; if (d < m_fMinInput) m_fMinInput = d; if (d > m_fMaxInput) m_fMaxInput = d; if ((d < m_fMinVal) || (d > m_fMaxVal)) { m_fSkipEntries++; BXOUT; return; } m_fBinEntries++; p = (d-m_fMinVal)*m_fFac - 0.5; ip = (int)floor(p); if (ip < 0) { ip = 0; p = 0; } else if (ip > m_iResolution-2) { ip = m_iResolution-2; p = 1.0; } else p -= ip; m_pBin[ip ] += (1.0-p) * v; m_pBin[ip + 1] += p * v; BXOUT; } void CDF::AddToBin_Multi(int i, double d) { BXIN; double p; int ip; if (i >= m_iMultiCount) { eprintf("CDF::AddToBin_Multi(): Error: %d >= %d.\n",i,m_iMultiCount); abort(); } m_fSum += d; m_fSqSum += d*d; if (d < m_fMinInput) m_fMinInput = d; if (d > m_fMaxInput) m_fMaxInput = d; if ((d < m_fMinVal) || (d > m_fMaxVal)) { m_fSkipEntries++; BXOUT; return; } m_fBinEntries++; p = (d-m_fMinVal)*m_fFac - 0.5; ip = (int)floor(p); if (ip < 0) { ip = 0; p = 0; } else if (ip > m_iResolution-2) { ip = m_iResolution-2; p = 1.0; } else p -= ip; m_pBin[ip ] += (1.0-p); m_pBin[ip + 1] += p ; m_pMultiBin[i][ip ] += (1.0-p); m_pMultiBin[i][ip + 1] += p ; BXOUT; } void CDF::AddToBin_Multi_Int(int i, int n, double f) { BXIN; double d; if (i >= m_iMultiCount) { eprintf("CDF::AddToBin_Multi(): Error: %d >= %d.\n",i,m_iMultiCount); abort(); } d = ((double)n)/m_iResolution*(m_fMaxVal-m_fMinVal)-m_fMinVal; m_fSum += d; m_fSqSum += d*d; if (d < m_fMinInput) m_fMinInput = d; if (d > m_fMaxInput) m_fMaxInput = d; m_fBinEntries++; m_pBin[n] += f; m_pMultiBin[i][n] += f; BXOUT; } void CDF::SetAdditionalDatasetLabel(int z, const char *s) { if (m_pAdditionalSetLabels[z] != NULL) delete[] m_pAdditionalSetLabels[z]; try { m_pAdditionalSetLabels[z] = new char[strlen(s)+1]; } catch(...) { m_pAdditionalSetLabels[z] = NULL; } if (m_pAdditionalSetLabels[z] == NULL) NewException((double)(strlen(s)+1)*sizeof(char),__FILE__,__LINE__,__PRETTY_FUNCTION__); strcpy(m_pAdditionalSetLabels[z],s); } void CDF::SetLabelX(const char *s) { if (m_sLabelX != NULL) delete[] m_sLabelX; try { m_sLabelX = new char[strlen(s)+1]; } catch(...) { m_sLabelX = NULL; } if (m_sLabelX == NULL) NewException((double)(strlen(s)+1)*sizeof(char),__FILE__,__LINE__,__PRETTY_FUNCTION__); strcpy(m_sLabelX,s); } void CDF::SetLabelY(const char *s) { if (m_sLabelY != NULL) delete[] m_sLabelY; try { m_sLabelY = new char[strlen(s)+1]; } catch(...) { m_sLabelY = NULL; } if (m_sLabelY == NULL) NewException((double)(strlen(s)+1)*sizeof(char),__FILE__,__LINE__,__PRETTY_FUNCTION__); strcpy(m_sLabelY,s); } void CDF::AddToBin_Int(int i, double j) { double d; BXIN; d = ((double)i)/m_iResolution*(m_fMaxVal-m_fMinVal)-m_fMinVal; m_fSum += d; m_fSqSum += d*d; if (d < m_fMinInput) m_fMinInput = d; if (d > m_fMaxInput) m_fMaxInput = d; if ((i < 0) || (i >= m_iResolution)) { m_fSkipEntries++; // mprintf("CDF: %.3f out of Range (%.3f-%.3f).\n",d,m_fMinVal,m_fMaxVal); BXOUT; return; } m_fBinEntries++; m_pBin[i]+=j; BXOUT; } void CDF::AddToBin_Count(int i, int count) { double d; BXIN; d = ((double)i)/m_iResolution*(m_fMaxVal-m_fMinVal)-m_fMinVal; m_fSum += d*count; m_fSqSum += d*d*count; if (d < m_fMinInput) m_fMinInput = d; if (d > m_fMaxInput) m_fMaxInput = d; if ((i < 0) || (i >= m_iResolution)) { m_fSkipEntries+=count; // mprintf("CDF: %.3f out of Range (%.3f-%.3f).\n",d,m_fMinVal,m_fMaxVal); BXOUT; return; } m_fBinEntries+=count; m_pBin[i]+=count; BXOUT; } void CDF::AngleCorrect() { BTIN; int z; for (z=0;z tma) tma = m_pBin[z]; } if (tma-tmi < 1E-20) tma += 0.00001; d = ma - mi; td = tma - tmi; for (z=0;z= 1.0) return m_fMaxVal; s = 0; for (z=0;z= l) return m_fMinVal+z*(m_fMaxVal-m_fMinVal)/(double)m_iResolution; } BTOUT; return m_fMaxVal; } void CDF::Create() { BTIN; int z; // m_bRDF = rdf; try { m_pBin = new double[m_iResolution]; } catch(...) { m_pBin = NULL; } if (m_pBin == NULL) NewException((double)m_iResolution*sizeof(double),__FILE__,__LINE__,__PRETTY_FUNCTION__); for (z=0;zCurrentGraph()->m_bLegend = true; g->AddDataset(); CalcMinMax(); if (m_sLabelX != NULL) g->SetLabelX(m_sLabelX); if (m_sLabelY != NULL) g->SetLabelY(m_sLabelY); g->SetTitle(title); g->SetRangeX(m_fMinVal,m_fMaxVal); g->SetRangeY((m_fMinEntry<0.0)?m_fMinEntry:0.0,m_fMaxEntry+(m_fMaxEntry-((m_fMinEntry<0.0)?m_fMinEntry:0.0))*0.1); g->MakeTicks(); g->CurrentGraph()->CurrentDataset()->m_faValues.SetMaxSize(m_iResolution*2); g->SetDatasetName("Total"); if (rdf) g->AddLine(m_fMinVal,1.0,m_fMaxVal,1.0,1,1,0,0,0); if (m_iResolution > 2000) { mprintf(" Preparing set 1: ["); tfs = m_iResolution / 50.0; } for (z=0;zAddXYTupel(0,x,m_pBin[z]); if (m_iResolution > 2000) if (fmod(z,tfs) < 1) mprintf(WHITE,"#"); } if (m_iResolution > 2000) mprintf("]\n"); for (z0=0;z0 2000) mprintf(" Preparing set %2d: [",z0+2); g->AddDataset(); g->CurrentGraph()->CurrentDataset()->m_faValues.SetMaxSize(m_iResolution*2); if (m_sLabelMulti != NULL) if (m_sLabelMulti[z0] != NULL) g->SetDatasetName(m_sLabelMulti[z0]); for (z=0;zAddXYTupel(z0+1,x,m_pMultiBin[z0][z]); if (m_iResolution > 2000) if (fmod(z,tfs) < 1) mprintf(WHITE,"#"); } if (m_iResolution > 2000) mprintf("]\n"); } g->WriteAgr(buf,false); delete g; } void CDF::WriteMultiAgr_Cumulative(const char *prefix, const char *name, const char *suffix, const char *title, bool rdf) { CGrace *g; int z0, z; // char buf[32768]; CxString buf; double x, tfs; double *td; // strcpy(buf,prefix); // strcat(buf,name); // strcat(buf,suffix); buf.strcpy(prefix); buf.strcat(name); buf.strcat(suffix); try { g = new CGrace(); } catch(...) { g = NULL; } if (g == NULL) NewException((double)sizeof(CGrace),__FILE__,__LINE__,__PRETTY_FUNCTION__); g->CurrentGraph()->m_bLegend = true; g->CurrentGraph()->m_bInvert = true; // g->AddDataset(); CalcMinMax(); if (m_sLabelX != NULL) g->SetLabelX(m_sLabelX); if (m_sLabelY != NULL) g->SetLabelY(m_sLabelY); g->SetTitle(title); g->SetRangeX(m_fMinVal,m_fMaxVal); g->SetRangeY((m_fMinEntry<0.0)?m_fMinEntry:0.0,m_fMaxEntry+(m_fMaxEntry-((m_fMinEntry<0.0)?m_fMinEntry:0.0))*0.1); g->MakeTicks(); if (rdf) g->AddLine(m_fMinVal,1.0,m_fMaxVal,1.0,1,1,0,0,0); /* g->CurrentGraph()->CurrentDataset()->m_faValues.SetMaxSize(m_iResolution*2); g->SetDatasetName("Total"); mprintf(" Preparing set 1: ["); for (z=0;zAddXYTupel(0,x,m_pBin[z]); if (fmod(z,tfs) < 1) mprintf(WHITE,"#"); } mprintf("]\n");*/ tfs = m_iResolution / 50.0; try { td = new double[m_iResolution]; } catch(...) { td = NULL; } if (td == NULL) NewException((double)m_iResolution*sizeof(double),__FILE__,__LINE__,__PRETTY_FUNCTION__); for (z=0;zAddDataset(); g->CurrentGraph()->CurrentDataset()->m_bFill = true; // g->CurrentGraph()->CurrentDataset()->m_fLineWidth = 0; g->CurrentGraph()->CurrentDataset()->m_faValues.SetMaxSize(m_iResolution*2); } for (z0=0;z0 2000) mprintf(" Preparing set %2d: [",z0+1); if (m_sLabelMulti != NULL) if (m_sLabelMulti[z0] != NULL) g->SetDatasetName(m_iMultiCount-z0-1,m_sLabelMulti[z0]); for (z=0;zAddXYTupel(m_iMultiCount-z0-1,x,td[z]); if (m_iResolution > 2000) if (fmod(z,tfs) < 1) mprintf(WHITE,"#"); } if (m_iResolution > 2000) mprintf("]\n"); } g->WriteAgr(buf,false); delete g; delete[] td; } void CDF::Write_Int(const char *prefix, const char *name, const char *suffix) { BTIN; FILE *a; int z; // char buf[32768]; CxString buf; double d; // strcpy(buf,prefix); // strcat(buf,name); // strcat(buf,suffix); buf.strcpy(prefix); buf.strcat(name); buf.strcat(suffix); a = OpenFileWrite(buf,true); if (m_sLabelX != NULL) mfprintf(a,"# %s; ",m_sLabelX); else mfprintf(a,"# (no label); "); if (m_sLabelY != NULL) mfprintf(a,"%s",m_sLabelY); else mfprintf(a,"(no label)"); mfprintf(a,"; Cumulative Sum\n"); d = 0; for (z=0;zAddDataset(); CalcMinMax(); if (m_sLabelX != NULL) g->SetLabelX(m_sLabelX); if (m_sLabelY != NULL) g->SetLabelY(m_sLabelY); g->SetTitle(title); g->SetRangeX(m_fMinVal,m_fMaxVal); g->SetRangeY((m_fMinEntry<0.0)?m_fMinEntry:0.0,m_fMaxEntry+(m_fMaxEntry-((m_fMinEntry<0.0)?m_fMinEntry:0.0))*0.1); g->MakeTicks(); g->CurrentGraph()->CurrentDataset()->m_faValues.SetMaxSize(m_iResolution*2); if (rdf) g->AddLine(m_fMinVal,1.0,m_fMaxVal,1.0,1,1,0,0,0); if (m_iResolution > 2000) { mprintf(" Preparing set 1: ["); tfs = m_iResolution / 50.0; } for (z=0;zAddXYTupel(0,x,m_pBin[z]); if (m_iResolution > 2000) if (fmod(z,tfs) < 1) mprintf(WHITE,"#"); } if (m_iResolution > 2000) mprintf("]\n"); zi = 0; for (z0=0;z0 2000) mprintf(" Preparing set %2d: [",zi+2); g->AddDataset(); g->CurrentGraph()->CurrentDataset()->m_faValues.SetMaxSize(m_iResolution*2); if (m_pAdditionalSetLabels[z0] != NULL) g->SetDatasetName(m_pAdditionalSetLabels[z0]); for (z=0;zAddXYTupel(zi+1,x,m_pAdditionalSets[z0][z]); if (m_iResolution > 2000) if (fmod(z,tfs) < 1) mprintf(WHITE,"#"); } if (m_iResolution > 2000) mprintf("]\n"); zi++; } g->WriteAgr(buf,false); delete g; } void CDF::WriteHenry(const char *prefix, const char *name, const char *suffix) { BTIN; FILE *a; int z; // char buf[32768]; CxString buf; double d; // strcpy(buf,prefix); // strcat(buf,name); // strcat(buf,suffix); buf.strcpy(prefix); buf.strcat(name); buf.strcat(suffix); a = OpenFileWrite(buf,true); d = 0; for (z=0;zm_pParent = NULL; m_pBinTree->m_pValue = NULL; REC_FillBinTree(0,0,m_pBinTree); REC_FuseTree(m_pBinTree); } unsigned long CDF::REC_FillBinTree(int pos, int depth, CBinTree *p) { CBinTree *t; double *d; if (depth < 16) { try { t = new CBinTree(); } catch(...) { t = NULL; } if (t == NULL) NewException((double)sizeof(CBinTree),__FILE__,__LINE__,__PRETTY_FUNCTION__); t->m_pValue = NULL; t->m_pParent = p; p->m_pChildren[0] = t; pos = REC_FillBinTree(pos,depth+1,t); try { t = new CBinTree(); } catch(...) { t = NULL; } if (t == NULL) NewException((double)sizeof(CBinTree),__FILE__,__LINE__,__PRETTY_FUNCTION__); t->m_pValue = NULL; t->m_pParent = p; p->m_pChildren[1] = t; pos = REC_FillBinTree(pos,depth+1,t); return pos; } else { try { d = new double; } catch(...) { d = NULL; } if (d == NULL) NewException((double)sizeof(double),__FILE__,__LINE__,__PRETTY_FUNCTION__); *d = m_pBin[pos]; p->m_pValue = (void*)d; // mprintf("FillTree: Pos=%d\n",pos); return pos+1; } } void CDF::REC_FuseTree(CBinTree *p) { double *d, *d1, *d2; if (p->m_pChildren[0]->m_pValue == NULL) REC_FuseTree(p->m_pChildren[0]); if (p->m_pChildren[1]->m_pValue == NULL) REC_FuseTree(p->m_pChildren[1]); d1 = (double*)p->m_pChildren[0]->m_pValue; d2 = (double*)p->m_pChildren[1]->m_pValue; try { d = new double; } catch(...) { d = NULL; } if (d == NULL) NewException((double)sizeof(double),__FILE__,__LINE__,__PRETTY_FUNCTION__); *d = *d1 + *d2; p->m_pValue = (void*)d; } void CDF::REC_SaveTree(FILE *a, double xmin, double xmax, int depth, int mindepth, int maxdepth, double thres, CBinTree *p, bool rdf) { // int z; double /*thr,*/ d1, d2, v; if (depth == maxdepth) { v = *(double*)p->m_pValue; mfprintf(a,"%9.4f; %f\n",(xmax+xmin)/2.0,v); return; } d1 = *((double*)p->m_pChildren[0]->m_pValue); d2 = *((double*)p->m_pChildren[1]->m_pValue); if ((sqrt(pow2(thres)-pow2(d1-d2)) < (xmax-xmin)) && (depth >= mindepth)) { v = *(double*)p->m_pValue; mfprintf(a,"%9.4f; %f\n",(xmax+xmin)/2.0,v); } else { REC_SaveTree(a,xmin,xmin+(xmax-xmin)/2.0,depth+1,mindepth,maxdepth,thres,p->m_pChildren[0],rdf); REC_SaveTree(a,xmin+(xmax-xmin)/2.0,xmax,depth+1,mindepth,maxdepth,thres,p->m_pChildren[1],rdf); } } void CDF::WriteAdapted(const char *prefix, const char *name, const char *suffix, int mindepth, int maxdepth, double thres, bool rdf) { BTIN; FILE *a; // char buf[32768]; CxString buf; // strcpy(buf,prefix); // strcat(buf,name); // strcat(buf,suffix); buf.strcpy(prefix); buf.strcat(name); buf.strcat(suffix); a = OpenFileWrite(buf,true); REC_SaveTree(a,m_fMinVal,m_fMaxVal,0,mindepth,maxdepth,thres,m_pBinTree,rdf); fclose(a); BTOUT; } void CDF::BinTree_RadialDist() { REC_BinTreeRadialDist(m_fMinVal,m_fMaxVal,0,m_pBinTree); } void CDF::REC_BinTreeRadialDist(double xmin, double xmax, int depth, CBinTree *p) { *(double*)p->m_pValue /= pow3(xmax)-pow3(xmin); if (depth == 16) return; REC_BinTreeRadialDist(xmin,xmin+(xmax-xmin)/2.0,depth+1,p->m_pChildren[0]); REC_BinTreeRadialDist(xmin+(xmax-xmin)/2.0,xmax,depth+1,p->m_pChildren[1]); } void CDF::BinTree_MultiplyBin(double f) { REC_BinTreeMultiplyBin(m_fMinVal,m_fMaxVal,0,m_pBinTree,f); } void CDF::REC_BinTreeMultiplyBin(double xmin, double xmax, int depth, CBinTree *p, double fac) { *(double*)p->m_pValue *= fac; if (depth == 16) return; REC_BinTreeMultiplyBin(xmin,xmin+(xmax-xmin)/2.0,depth+1,p->m_pChildren[0],fac); REC_BinTreeMultiplyBin(xmin+(xmax-xmin)/2.0,xmax,depth+1,p->m_pChildren[1],fac); } void CDF::CreateCombinedPlot(bool rdf) { double x, x2, imax, tmx, px; int z/*, tpx*/, mi, ma; // char buf[64]; CxString buf; m_pCombinedPlot->FindMinMaxVal(); x = m_pCombinedPlot->CurrentGraph()->m_fMaxValX; x2 = 0.25*x; m_pCombinedPlot->SetRangeX(0,x+x2+0.025*x); m_pCombinedPlot->SetRangeY(m_fMinVal,m_fMaxVal); CreateTicks(m_fMinVal,m_fMaxVal,ma,mi); m_pCombinedPlot->CurrentGraph()->m_fTickMajorY = (m_fMaxVal-m_fMinVal)/(ma-1); m_pCombinedPlot->CurrentGraph()->m_iTickMinorY = mi; m_pCombinedPlot->CurrentGraph()->m_iTickPrecY = (int)MAX(0,1-int(ceil(log10(m_pCombinedPlot->CurrentGraph()->m_fTickMajorY)))); m_pCombinedPlot->AddDataset(); m_pCombinedPlot->CurrentGraph()->CurrentDataset()->m_iLineColorIndex = 1; // mprintf("A\n"); imax = 0; for (z=0;z imax) imax = m_pBin[z]; // Die Trennlinie zwischen TD und Histogramm m_pCombinedPlot->AddLine(x,m_fMinVal,x,m_fMaxVal,2,1); // Die Nulllinie // m_pCombinedPlot->AddLine(x+x2+0.025*x,m_fMinVal,x+x2+0.025*x,m_fMaxVal,2,1); // Die "Eins"-Linie if (rdf) m_pCombinedPlot->AddLine(x+x2+0.025*x-(1.0/imax*x2),m_fMinVal,x+x2+0.025*x-(1.0/imax*x2),m_fMaxVal,1,1); m_pCombinedPlot->CurrentGraph()->m_bTicksBothSidesY = true; m_pCombinedPlot->CurrentGraph()->m_bTickLabelsBothSidesY = true; x += 0.025*x; m_pCombinedPlot->CurrentGraph()->CurrentDataset()->m_faValues.SetMaxSize(m_iResolution*2); for (z=0;zAddXYTupel(m_pCombinedPlot->CurrentGraph()->m_oaDatasets.GetSize()-1,x+x2-(m_pBin[z]/imax*x2),m_fMinVal+(z+0.5)*(m_fMaxVal-m_fMinVal)/m_iResolution); tmx = majorticks(0,x); // tpx = (int)max(0,1-int(ceil(log10(tmx)))); // mprintf("B\n"); // mprintf("x=%f, tmx=%f, tpx=%f.\n",x,tmx,tpx); px = 0; z = 0; do { if ((z%2)==0) { // sprintf(buf,"%.1f ps",px); buf.sprintf("%.1f ps",px); m_pCombinedPlot->AddCustomLabelX(true,px,buf); } else m_pCombinedPlot->AddCustomLabelX(false,px,""); z++; px += tmx/2.0; } while (px+tmx/2.0 < x); // mprintf("C\n"); m_pCombinedPlot->AddCustomLabelX(true,x+x2,"0"); if (rdf) m_pCombinedPlot->AddCustomLabelX(true,x+x2-(1.0/imax*x2),"1"); /* sprintf(buf,"%.1f",imax); m_pCombinedPlot->AddCustomLabelX(true,x,buf);*/ for (z=2;zAddCustomLabelX(false,x+x2-((double)z/imax*x2),""); // sprintf(buf,"%.0f",floor(imax)); buf.sprintf("%.0f",floor(imax)); m_pCombinedPlot->AddCustomLabelX(true,x+x2-(floor(imax)/imax*x2),buf); } void CDF::ScaleXRange(double fac) { m_fMinVal *= fac; m_fMaxVal *= fac; } void CDF::CalcMinMax() { int z, z2; double a; m_fMinEntry = 9E99; m_fMaxEntry = -9E99; for (z=0;z m_fMaxEntry) m_fMaxEntry = m_pBin[z]; if (m_pBin[z] < m_fMinEntry) m_fMinEntry = m_pBin[z]; } if (m_iMultiCount != 0) { for (z2=0;z2 m_fMaxEntry) m_fMaxEntry = m_pMultiBin[z2][z]; if (m_pMultiBin[z2][z] < m_fMinEntry) m_fMinEntry = m_pMultiBin[z2][z]; } } } if (fabs(m_fMinEntry) > m_fMaxEntry) a = fabs(m_fMinEntry); else a = m_fMaxEntry; m_fEps = nextafter(a,2.0*a) - a; } void CDF::CalcHistogram() { int z, z2, t; CalcMinMax(); try { m_pHistogram = new double[m_iHistogramRes]; } catch(...) { m_pHistogram = NULL; } if (m_pHistogram == NULL) NewException((double)m_iHistogramRes*sizeof(double),__FILE__,__LINE__,__PRETTY_FUNCTION__); for (z=0;zm_bCombinedPlot; m_bSaveDist = p->m_bSaveDist; m_fBinEntries = p->m_fBinEntries; m_fFac = p->m_fFac; m_fMaxEntry = p->m_fMaxEntry; m_fMaxP = p->m_fMaxP; m_fMaxVal = p->m_fMaxVal; m_fMinEntry = p->m_fMinEntry; m_fMinVal = p->m_fMinVal; m_fSkipEntries = p->m_fSkipEntries; m_iHistogramRes = p->m_iHistogramRes; m_iResolution = p->m_iResolution; m_fSum = p->m_fSum; m_fSqSum = p->m_fSqSum; m_fMean = p->m_fMean; m_fSD = p->m_fSD; m_fMinInput = p->m_fMinInput; m_fMaxInput = p->m_fMaxInput; if (p->m_pBin != NULL) { try { m_pBin = new double[m_iResolution]; } catch(...) { m_pBin = NULL; } if (m_pBin == NULL) NewException((double)m_iResolution*sizeof(double),__FILE__,__LINE__,__PRETTY_FUNCTION__); memcpy(m_pBin,p->m_pBin,sizeof(double)*m_iResolution); } m_pBinTree = NULL; m_pCombinedPlot = NULL; if (p->m_pHistogram != NULL) { try { m_pHistogram = new double[m_iHistogramRes]; } catch(...) { m_pHistogram = NULL; } if (m_pHistogram == NULL) NewException((double)m_iHistogramRes*sizeof(double),__FILE__,__LINE__,__PRETTY_FUNCTION__); memcpy(m_pHistogram,p->m_pHistogram,sizeof(double)*m_iHistogramRes); } if (p->m_pIntegral != NULL) { try { m_pIntegral = new double[m_iResolution]; } catch(...) { m_pIntegral = NULL; } if (m_pIntegral == NULL) NewException((double)m_iResolution*sizeof(double),__FILE__,__LINE__,__PRETTY_FUNCTION__); memcpy(m_pIntegral,p->m_pIntegral,sizeof(double)*m_iResolution); } } void CDF::Fit_PolyExp(int degree, int maxcall) { double *x, *y; int z; // char buf[256]; CxString buf; try { m_pAdditionalSets[degree] = new double[m_iResolution]; } catch(...) { m_pAdditionalSets[degree] = NULL; } if (m_pAdditionalSets[degree] == NULL) NewException((double)m_iResolution*sizeof(double),__FILE__,__LINE__,__PRETTY_FUNCTION__); // sprintf(buf,"%d-exp fit",degree); buf.sprintf("%d-exp fit",degree); try { m_pAdditionalSetLabels[degree] = new char[strlen(buf)+1]; } catch(...) { m_pAdditionalSetLabels[degree] = NULL; } if (m_pAdditionalSetLabels[degree] == NULL) NewException((double)(strlen(buf)+1)*sizeof(char),__FILE__,__LINE__,__PRETTY_FUNCTION__); strcpy(m_pAdditionalSetLabels[degree],buf); try { m_pLMWrapper = new CLMWrapper(); } catch(...) { m_pLMWrapper = NULL; } if (m_pLMWrapper == NULL) NewException((double)sizeof(CLMWrapper),__FILE__,__LINE__,__PRETTY_FUNCTION__); try { x = new double[m_iResolution]; } catch(...) { x = NULL; } if (x == NULL) NewException((double)m_iResolution*sizeof(double),__FILE__,__LINE__,__PRETTY_FUNCTION__); try { y = new double[m_iResolution]; } catch(...) { y = NULL; } if (y == NULL) NewException((double)m_iResolution*sizeof(double),__FILE__,__LINE__,__PRETTY_FUNCTION__); try { m_pParameters[degree] = new double[degree*2]; } catch(...) { m_pParameters[degree] = NULL; } if (m_pParameters[degree] == NULL) NewException((double)degree*2*sizeof(double),__FILE__,__LINE__,__PRETTY_FUNCTION__); for (z=0;zFit_PolyExp(degree,m_iResolution,x,y,m_pParameters[degree],m_pCorrCoeff[degree],m_pFitIntegral[degree],m_pAdditionalSets[degree],maxcall); delete[] x; delete[] y; delete m_pLMWrapper; m_pLMWrapper = NULL; } void CDF::Fit_ExpSpectrum(int res, double mi, double ma, const char *name, int dpoints, int maxcall, bool lindata, double zeroweight, bool evolve) { double *x, *y; int z; // char buf[256]; CxString buf; int *dpmapping; double *val, *valx; try { dpmapping = new int[dpoints]; } catch(...) { dpmapping = NULL; } if (dpmapping == NULL) NewException((double)dpoints*sizeof(int),__FILE__,__LINE__,__PRETTY_FUNCTION__); try { val = new double[m_iResolution]; } catch(...) { val = NULL; } if (val == NULL) NewException((double)m_iResolution*sizeof(double),__FILE__,__LINE__,__PRETTY_FUNCTION__); try { valx = new double[m_iResolution]; } catch(...) { valx = NULL; } if (valx == NULL) NewException((double)m_iResolution*sizeof(double),__FILE__,__LINE__,__PRETTY_FUNCTION__); try { m_pAdditionalSets = new double*; } catch(...) { m_pAdditionalSets = NULL; } if (m_pAdditionalSets == NULL) NewException((double)sizeof(double*),__FILE__,__LINE__,__PRETTY_FUNCTION__); try { m_pAdditionalSetLabels = new char*; } catch(...) { m_pAdditionalSetLabels = NULL; } if (m_pAdditionalSetLabels == NULL) NewException((double)sizeof(char*),__FILE__,__LINE__,__PRETTY_FUNCTION__); m_iAdditionalSets = 1; try { m_pAdditionalSets[0] = new double[m_iResolution]; } catch(...) { m_pAdditionalSets[0] = NULL; } if (m_pAdditionalSets[0] == NULL) NewException((double)m_iResolution*sizeof(double),__FILE__,__LINE__,__PRETTY_FUNCTION__); // sprintf(buf,"Lifetime spectrum fit"); buf.sprintf("Lifetime spectrum fit"); try { m_pAdditionalSetLabels[0] = new char[strlen(buf)+1]; } catch(...) { m_pAdditionalSetLabels[0] = NULL; } if (m_pAdditionalSetLabels[0] == NULL) NewException((double)(strlen(buf)+1)*sizeof(char),__FILE__,__LINE__,__PRETTY_FUNCTION__); strcpy(m_pAdditionalSetLabels[0],buf); try { m_pLMWrapper = new CLMWrapper(); } catch(...) { m_pLMWrapper = NULL; } if (m_pLMWrapper == NULL) NewException((double)sizeof(CLMWrapper),__FILE__,__LINE__,__PRETTY_FUNCTION__); try { x = new double[dpoints]; } catch(...) { x = NULL; } if (x == NULL) NewException((double)m_iResolution*sizeof(double),__FILE__,__LINE__,__PRETTY_FUNCTION__); try { y = new double[dpoints]; } catch(...) { y = NULL; } if (y == NULL) NewException((double)m_iResolution*sizeof(double),__FILE__,__LINE__,__PRETTY_FUNCTION__); try { m_pParameters = new double*; } catch(...) { m_pParameters = NULL; } if (m_pParameters == NULL) NewException((double)sizeof(double*),__FILE__,__LINE__,__PRETTY_FUNCTION__); try { m_pParameters[0] = new double[res]; } catch(...) { m_pParameters[0] = NULL; } if (m_pParameters[0] == NULL) NewException((double)res*sizeof(double),__FILE__,__LINE__,__PRETTY_FUNCTION__); if (lindata) mprintf(" Reducing %d data points to %d fit points linearly.\n\n",m_iResolution,dpoints); else mprintf(" Reducing %d data points to %d fit points logarithmically.\n\n",m_iResolution,dpoints); mprintf(" Using the following data points:"); for (z=0;zFit_ExpSpectrum(res,mi,ma,dpoints,x,y,m_pParameters[0],m_iResolution,valx,val,name,maxcall,zeroweight,evolve); for (z=0;zm_iResolution) { eprintf("CDF::AddFrom(): Error: %d != %d.\n",m_iResolution,t->m_iResolution); abort(); } for (z=0;zm_pBin[z]; if (t->m_fMinEntry < m_fMinEntry) m_fMinEntry = t->m_fMinEntry; if (t->m_fMaxEntry > m_fMaxEntry) m_fMaxEntry = t->m_fMaxEntry; m_fBinEntries += t->m_fBinEntries; m_fSkipEntries += t->m_fSkipEntries; m_fSum += t->m_fSum; m_fSqSum += t->m_fSqSum; } void CDF::SetLabelMulti(int n, const char *s) { if (n >= m_iMultiCount) { eprintf("CDF::SetLabelMulti(): Error: %d >= %d.\n",n,m_iMultiCount); abort(); } if (m_sLabelMulti[n] != NULL) delete[] m_sLabelMulti[n]; try { m_sLabelMulti[n] = new char[strlen(s)+1]; } catch(...) { m_sLabelMulti[n] = NULL; } if (m_sLabelMulti[n] == NULL) NewException((double)(strlen(s)+1)*sizeof(char),__FILE__,__LINE__,__PRETTY_FUNCTION__); strcpy(m_sLabelMulti[n],s); } void CDF::Mirror(double plane) { // int z, i, j; // float p, f; if ((plane <= m_fMinVal) || (plane >= m_fMaxVal)) return; int i, t; double *tbin, p; try { tbin = new double[m_iResolution]; } catch(...) { tbin = NULL; } if (tbin == NULL) NewException((double)m_iResolution * sizeof(double), __FILE__, __LINE__, __PRETTY_FUNCTION__); p = (plane - m_fMinVal) * m_fFac; for (i = 0; i < m_iResolution; i++) { tbin[i] = m_pBin[i]; t = (int)(2.0 * p - i - 1); if ((t >= 0) && (t < m_iResolution)) { tbin[i] += m_pBin[t]; tbin[i] /= 2.0; } } delete[] m_pBin; m_pBin = tbin; // // Array index of mirror plane // i = (plane-m_fMinVal)*m_fFac; // mprintf(GREEN, "i: %d %f\n", i, m_fFac); // // // Traverse array until mirror plane // for (z=0;z= m_iResolution)) // continue; // // // Average of both points // f = (m_pBin[z]+m_pBin[j]) / 2.0f; // // // Write average into both array positions // m_pBin[z] = f; // m_pBin[j] = f; // } } travis-src-190101/src/df.h0100777000000000000000000001432713412725663012213 0ustar00/***************************************************************************** TRAVIS - Trajectory Analyzer and Visualizer http://www.travis-analyzer.de/ Copyright (c) 2009-2019 Martin Brehm 2012-2019 Martin Thomas 2016-2019 Sascha Gehrke This file was written by Martin Brehm. --------------------------------------------------------------------------- This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . *****************************************************************************/ #ifndef DF_H #define DF_H // This must always be the first include directive #include "config.h" #include #include #include "xdvector3.h" #include "xdoublearray.h" #include "backtrace.h" #include "bintree.h" #include "grace.h" #include "lmwrapper.h" class C2DF; template class C3DF; class CObservation; class CDF : public CxObject { public: void AddFrom(CDF *t); int m_iMultiCount; void CalcMeanSD(); void SetAdditionalDatasetLabel(int z, const char *s); void SetLabelX(const char *s); void SetLabelY(const char *s); bool m_bLeft; void Fit_PolyExp(int degree, int maxcall); void Fit_ExpSpectrum(int res, double mi, double ma, const char *name, int dpoints, int maxcall, bool lindata, double zeroweight, bool evolve); void CopyFrom(CDF *p); void WriteHistogram(const char *prefix, const char *name, const char *suffix); void CalcHistogram(); // bool m_bRDF; void Mirror(double plane); void CalcMinMax(); void ScaleXRange(double fac); void CreateCombinedPlot(bool rdf); void REC_BinTreeMultiplyBin(double xmin, double xmax, int depth, CBinTree *p, double fac); void BinTree_MultiplyBin(double f); void REC_BinTreeRadialDist(double xmin, double xmax, int depth, CBinTree *p); void BinTree_RadialDist(); void WriteAdapted(const char *prefix, const char *name, const char *suffix, int mindepth, int maxdepth, double thres, bool rdf); void REC_SaveTree(FILE *a, double xmin, double xmax, int depth, int mindepth, int maxdepth, double thres, CBinTree *p, bool rdf); void REC_FuseTree(CBinTree *p); unsigned long REC_FillBinTree(int pos, int depth, CBinTree *p); void PrepareAdapt(); CDF(); ~CDF(); // void AddToBin(const CxVector3 &vec); void AddToBin(double d); void AddToBin(double d, double v); void AddToBin_Multi(int i, double d); void AddToBin_Multi_Int(int i, int n, double f); void AddToBin_Int(int i); void AddToBin_Int(int i, double j); void AddToBin_Count(int i, int count); double NormalizeBin(double mi, double ma); void Write(const char *prefix, const char *name, const char *suffix, bool integral); void WriteMultiAgr(const char *prefix, const char *name, const char *suffix, const char *title, bool rdf); void WriteMultiAgr_Cumulative(const char *prefix, const char *name, const char *suffix, const char *title, bool rdf); void WriteMulti(const char *prefix, const char *name, const char *suffix); void WriteMulti_Cumulative(const char *prefix, const char *name, const char *suffix); void Write_Int(const char *prefix, const char *name, const char *suffix); void WriteHenry(const char *prefix, const char *name, const char *suffix); // void WriteLog(const char *prefix, const char *name, const char *suffix); void Create(); void CreateMulti(int n); void SetLabelMulti(int n, const char *s); // void CalcHistogram(); double NormBinIntegral(); void NormBinIntegral(double val); void NormBinSum(double val); void NormAllBin(double); // neu void MultiplyBin(double f); void SubtractBin(double f); void MultiplyIntegral(double f); // void WriteHistogram(const char *prefix, const char *name, const char *suffix); void AngleCorrect(); void ZeroBin(); void Integrate(bool correctradial, double fac); void CorrectRadialDist(); void CorrectRadialDistLong(); void CorrectLiRadialDist(); void WriteAgr(const char *prefix, const char *name, const char *suffix, const char *title, bool rdf); double GetPercentageRange(double perc); double m_fMaxP; double m_fFac; // double m_fMaxDP; // double *m_pHistogram; // double *m_pDHistogram; // double *m_pDBin[3]; double m_fSum; double m_fSqSum; double m_fMean; double m_fSD; double m_fMinInput; double m_fMaxInput; double m_fMinVal, m_fMaxVal; double m_fMinEntry, m_fMaxEntry; int m_iResolution; double *m_pBin; double **m_pMultiBin; double *m_pIntegral; double m_fBinEntries; double m_fSkipEntries; CBinTree *m_pBinTree; double m_fEps; bool m_bSaveDist; bool m_bCombinedPlot; CGrace *m_pCombinedPlot; int m_iHistogramRes; double *m_pHistogram; CLMWrapper *m_pLMWrapper; double *m_pCorrCoeff; double *m_pFitIntegral; double **m_pParameters; double **m_pAdditionalSets; int m_iAdditionalSets; char **m_pAdditionalSetLabels; CxObArray m_oaTimeDiffBuf; CDF *m_pTimeDiff; CDF *m_pTimeDiffAbs; CDF *m_pTimeDiffSqr; C2DF *m_p3DTimeDiff; C2DF *m_p3DTimeDiffAbs; C2DF *m_p3DTimeDiffSqr; C2DF *m_p3DTimeDiffT; C2DF **m_pTimeDiffDistPairs; C3DF *m_pTimeDiffDist3DF; char *m_sLabelX; char *m_sLabelY; char **m_sLabelMulti; void AddToBin_Fast(double d) { double p; int ip; if (d > m_fMaxVal) return; p = d*m_fFac - 0.5; ip = (int)floor(p); if (ip < 0) { ip = 0; p = 0; } else if (ip > m_iResolution-2) { ip = m_iResolution-2; p = 1.0; } else p -= ip; m_pBin[ip ] += (1.0-p); m_pBin[ip + 1] += p ; } void AddToBinInt_Fast(int i) { // if (i >= m_iResolution) // abort(); m_pBin[i] += 1.0; } void AddToBinInt_Fast(int i, double d) { // if (i >= m_iResolution) // abort(); m_pBin[i] += d; } void AddToBin_Multi_Int_Fast(int i, int n, double f) { m_pBin[n] += f; m_pMultiBin[i][n] += f; } // double m_fIntegralNorm; }; #endif travis-src-190101/src/diagonal.cpp0100777000000000000000000002562113412725624013727 0ustar00/***************************************************************************** TRAVIS - Trajectory Analyzer and Visualizer http://www.travis-analyzer.de/ Copyright (c) 2009-2019 Martin Brehm 2012-2019 Martin Thomas 2016-2019 Sascha Gehrke This file was written by Martin Brehm. --------------------------------------------------------------------------- This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . *****************************************************************************/ // This must always be the first include directive #include "config.h" #include "diagonal.h" #include const char *GetRevisionInfo_diagonal(unsigned int len) { static char buf[256]; GET_REVISION_INFO( buf, len ); return buf; } const char *GetSourceVersion_diagonal() { static char buf[256]; GET_SOURCE_VERSION( buf ); return buf; } bool Diagonalize(const CxDMatrixMN &inmat, CxDMatrixMN *evec, CxDoubleArray *eval, bool verbose) { UNUSED(verbose); int n, z, z2; double **a, *d, *e; if (inmat.GetRows() != inmat.GetCols()) { eprintf("Diagonalize(): Error: rows != cols (%d, %d).\n",inmat.GetRows(),inmat.GetCols()); return false; } n = inmat.GetRows(); d = new double[n+1]; e = new double[n+1]; a = new double*[n+1]; for (z=0;zSetSize(n); for (z=0;z= 0.0 ? fabs(a) : -fabs(a)) double pythag(double a, double b) // Computes (a^2 + b^2)^1/2 without destructive underflow or overflow. { double absa,absb; absa=fabs(a); absb=fabs(b); if (absa > absb) return absa*sqrt(1.0+NRSQR(absb/absa)); else return (absb == 0.0 ? 0.0 : absb*sqrt(1.0+NRSQR(absa/absb))); } void tred2(double **a, int n, double d[], double e[], bool verbose) /* Householder reduction of a real, symmetric matrix a[1..n][1..n]. On output, a is replaced by the orthogonal matrix Q effecting the transformation. d[1..n] returns the diagonal elements of the tridiagonal matrix, and e[1..n] the off-diagonal elements, with e[1]=0. Several statements, as noted in comments, can be omitted if only eigenvalues are to be found, in which case a contains no useful information on output. Otherwise they are to be included. */ { int l,k,j,i; double scale,hh,h,g,f; double tfs; if (verbose) { mprintf(" Householder "); mprintf(WHITE,"["); } tfs = n/60.0; for (i=n;i>=2;i--) { if (verbose) if (fmod(i,tfs) < 1.0) mprintf(WHITE,"#"); l=i-1; h=scale=0.0; if (l > 1) { for (k=1;k<=l;k++) scale += fabs(a[i][k]); if (scale == 0.0) // Skip transformation. e[i]=a[i][l]; else { for (k=1;k<=l;k++) { a[i][k] /= scale; // Use scaled as for transformation. h += a[i][k]*a[i][k]; // Form sigma in h. } f=a[i][l]; g=(f >= 0.0 ? -sqrt(h) : sqrt(h)); e[i]=scale*g; h -= f*g; // Now h is equation (11.2.4). a[i][l]=f-g; // Store u in the ith row of a. f=0.0; for (j=1;j<=l;j++) { /* Next statement can be omitted if eigenvectors not wanted */ a[j][i]=a[i][j]/h; // Store u/H in ith column of a. g=0.0; // Form an element of A u in g. for (k=1;k<=j;k++) g += a[j][k]*a[i][k]; for (k=j+1;k<=l;k++) g += a[k][j]*a[i][k]; e[j]=g/h; //Form element of p in temporarily unused element of e. f += e[j]*a[i][j]; } hh=f/(h+h); // Form K, equation (11.2.11). for (j=1;j<=l;j++) { // Form q and store in e overwriting p. f=a[i][j]; e[j]=g=e[j]-hh*f; for (k=1;k<=j;k++) // Reduce a, equation (11.2.13). a[j][k] -= (f*e[k]+g*a[i][k]); } } } else e[i]=a[i][l]; d[i]=h; } if (verbose) mprintf(WHITE,"]\n"); /* Next statement can be omitted if eigenvectors not wanted */ d[1]=0.0; e[1]=0.0; if (verbose) { mprintf(" Eigenvectors "); mprintf(WHITE,"["); } /* Contents of this loop can be omitted if eigenvectors not wanted except for statement d[i]=a[i][i]; */ for (i=1;i<=n;i++) { // Begin accumulation of transformation matrices. if (verbose) if (fmod(i,tfs) < 1.0) mprintf(WHITE,"#"); l=i-1; if (d[i]) { // This block skipped when i=1. for (j=1;j<=l;j++) { g=0.0; for (k=1;k<=l;k++) // Use u and u/H stored in a to form PQ. g += a[i][k]*a[k][j]; for (k=1;k<=l;k++) a[k][j] -= g*a[k][i]; } } d[i]=a[i][i]; // This statement remains. a[i][i]=1.0; // Reset row and column of a to identity matrix for next iteration. for (j=1;j<=l;j++) a[j][i]=a[i][j]=0.0; } if (verbose) mprintf(WHITE,"]\n"); } void tqli(double d[], double e[], int n, double **z, bool verbose) /* QL algorithm with implicit shifts, to determine the eigenvalues and eigenvectors of a real, symmetric, tridiagonal matrix, or of a real, symmetric matrix previously reduced by tred2 11.2. On input, d[1..n] contains the diagonal elements of the tridiagonal matrix. On output, it returns the eigenvalues. The vector e[1..n] inputs the subdiagonal elements of the tridiagonal matrix, with e[1] arbitrary. On output e is destroyed. When finding only the eigenvalues, several lines may be omitted, as noted in the comments. If the eigenvectors of a tridiagonal matrix are desired, the matrix z[1..n][1..n] is input as the identity matrix. If the eigenvectors of a matrix that has been reduced by tred2 are required, then z is input as the matrix output by tred2. In either case, the kth column of z returns the normalized eigenvector corresponding to d[k]. */ { double pythag(double a, double b); int m,l,iter,i,k; double s,r,p,g,f,dd,c,b; double tfs; if (verbose) { mprintf(" QL "); mprintf(WHITE,"["); } tfs = n/60.0; for (i=2;i<=n;i++) e[i-1]=e[i]; // Convenient to renumber the elements of e. e[n]=0.0; for (l=1;l<=n;l++) { if (verbose) if (fmod(l,tfs) < 1.0) mprintf(WHITE,"#"); iter=0; do { for (m=l;m<=n-1;m++) { // Look for a single small subdiagonal element to split the matrix. dd=fabs(d[m])+fabs(d[m+1]); if ((double)(fabs(e[m])+dd) == dd) break; } if (m != l) { if (iter++ == 30) eprintf("\nError: Too many iterations in tqli.\n"); g=(d[l+1]-d[l])/(2.0*e[l]); // Form shift. r=pythag(g,1.0); g=d[m]-d[l]+e[l]/(g+SIGN(r,g)); // This is dm - ks. s=c=1.0; p=0.0; for (i=m-1;i>=l;i--) { // A plane rotation as in the original QL, followed by Givens rotations to restore tridiagonal form. f=s*e[i]; b=c*e[i]; e[i+1]=(r=pythag(f,g)); if (r == 0.0) { // Recover from underflow. d[i+1] -= p; e[m]=0.0; break; } s=f/r; c=g/r; g=d[i+1]-p; r=(d[i]-g)*s+2.0*c*b; d[i+1]=g+(p=s*r); g=c*r-b; /* Next loop can be omitted if eigenvectors not wanted */ for (k=1;k<=n;k++) { // Form eigenvectors. f=z[k][i+1]; z[k][i+1]=s*z[k][i]+c*f; z[k][i]=c*z[k][i]-s*f; } } if (r == 0.0 && i >= l) continue; d[l] -= p; e[l]=g; e[m]=0.0; } } while (m != l); } if (verbose) mprintf(WHITE,"]\n"); } void TestDiagonalization() { CxDMatrixMN inmat, evec; CxDoubleArray eval; int n = 6, z; inmat = CxDMatrixMN(n,n); /* Mathematica {{302.700231596574, 170.443219393374, -139.038947072181, -46.245819859365, -103.181902861864, 29.010383308527}, {170.443219393374, 260.815132417353, -12.935985300894, 44.502937022346, -94.698662374553, -43.419516133519}, {-139.038947072181, -12.935985300894, 217.193731596619, 128.387185615870, 43.079225195861, -69.443726271268}, {-46.245819859365, 44.502937022346, 128.387185615870, 209.996615121875, 74.217503978145, -96.339813050717}, {-103.181902861864, -94.698662374553, 43.079225195861, 74.217503978145, 208.245347398560, -102.388238316016}, {29.010383308527, -43.419516133519, -69.443726271268, -96.339813050717, -102.388238316016, 138.236759834129}} */ inmat(0,0) = 302.700231596574; inmat(0,1) = 170.443219393374; inmat(0,2) = -139.038947072181; inmat(0,3) = -46.245819859365; inmat(0,4) = -103.181902861864; inmat(0,5) = 29.010383308527; inmat(1,0) = 170.443219393374; inmat(1,1) = 260.815132417353; inmat(1,2) = -12.935985300894; inmat(1,3) = 44.502937022346; inmat(1,4) = -94.698662374553; inmat(1,5) = -43.419516133519; inmat(2,0) = -139.038947072181; inmat(2,1) = -12.935985300894; inmat(2,2) = 217.193731596619; inmat(2,3) = 128.387185615870; inmat(2,4) = 43.079225195861; inmat(2,5) = -69.443726271268; inmat(3,0) = -46.245819859365; inmat(3,1) = 44.502937022346; inmat(3,2) = 128.387185615870; inmat(3,3) = 209.996615121875; inmat(3,4) = 74.217503978145; inmat(3,5) = -96.339813050717; inmat(4,0) = -103.181902861864; inmat(4,1) = -94.698662374553; inmat(4,2) = 43.079225195861; inmat(4,3) = 74.217503978145; inmat(4,4) = 208.245347398560; inmat(4,5) = -102.388238316016; inmat(5,0) = 29.010383308527; inmat(5,1) = -43.419516133519; inmat(5,2) = -69.443726271268; inmat(5,3) = -96.339813050717; inmat(5,4) = -102.388238316016; inmat(5,5) = 138.236759834129; mprintf("Input Matrix:\n"); inmat.Dump(); mprintf("\nDiagonalizing...\n"); Diagonalize(inmat,&evec,&eval,true); mprintf("Eigenvalues:\n"); for (z=0;z. *****************************************************************************/ #ifndef DIAGONAL_H #define DIAGONAL_H // This must always be the first include directive #include "config.h" #include "tools.h" #include "xdmatrixmn.h" #include "xdoublearray.h" void tred2(double **a, int n, double d[], double e[], bool verbose); void tqli(double d[], double e[], int n, double **z, bool verbose); bool Diagonalize(const CxDMatrixMN &inmat, CxDMatrixMN *evec, CxDoubleArray *eval, bool verbose); void TestDiagonalization(); #endif travis-src-190101/src/domain.cpp0100777000000000000000000005450313412725630013416 0ustar00/***************************************************************************** TRAVIS - Trajectory Analyzer and Visualizer http://www.travis-analyzer.de/ Copyright (c) 2009-2019 Martin Brehm 2012-2019 Martin Thomas 2016-2019 Sascha Gehrke This file was written by Martin Brehm. --------------------------------------------------------------------------- This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . *****************************************************************************/ // This must always be the first include directive #include "config.h" #include "domain.h" #include "tools.h" #include "timestep.h" #include "vorowrapper.h" #include "globalvar.h" const char *GetRevisionInfo_domain(unsigned int len) { static char buf[256]; GET_REVISION_INFO( buf, len ); return buf; } const char *GetSourceVersion_domain() { static char buf[256]; GET_SOURCE_VERSION( buf ); return buf; } CDomain::CDomain() { Reset(); } CDomain::~CDomain() { } void CDomain::Reset() { m_iaCells.RemoveAll_KeepSize(); m_iaNeighbors.RemoveAll_KeepSize(); m_bActive = true; m_iFaces = 0; m_fSurfaceArea = 0; m_fVolume = 0; m_fAVRatio = 0; } void CDomain::Assimilate(CDomain *dom) { int z; for (z=0;zm_iaCells.GetSize();z++) m_iaCells.Add(dom->m_iaCells[z]); dom->m_bActive = false; m_fVolume += dom->m_fVolume; m_fSurfaceArea += dom->m_fSurfaceArea; m_iFaces += dom->m_iFaces; m_fAVRatio = 10.6347231054330961*m_fVolume/mypow(m_fSurfaceArea,1.5); } CDomainAnalysis::CDomainAnalysis() { } CDomainAnalysis::~CDomainAnalysis() { } void CDomainAnalysis::Parse(int i) { int z, z2, z3, z4; CAtomGroup *ag; CMolecule *m; CSingleMolecule *sm; // char buf[256]; CxString buf; mprintf(YELLOW," >>> Domain Analysis #%d >>>\n\n",i+1); mprintf(" First, you have to specify the base population (i.e., all atoms\n"); mprintf(" that will have a Voronoi cell in the analysis).\n\n"); for (z=0;zm_sName)) { try { ag = new CAtomGroup(); } catch(...) { ag = NULL; } if (ag == NULL) NewException((double)sizeof(CAtomGroup),__FILE__,__LINE__,__PRETTY_FUNCTION__); AskString(" Which atoms to include (e.g. C1,C5-7, *=all)? [all] ",&buf,"*"); if (!ag->ParseAtoms(m,buf)) goto _ag; m_oaBasePopulation.Add(ag); } else m_oaBasePopulation.Add(NULL); } mprintf("\n Processing selection...\n"); for (z=0;zm_pMolecule; for (z2=0;z2m_laSingleMolIndex.GetSize();z2++) { sm = (CSingleMolecule*)g_oaSingleMolecules[m->m_laSingleMolIndex[z2]]; for (z3=0;z3m_oaAtoms.GetSize();z3++) { for (z4=0;z4<((CxIntArray*)ag->m_oaAtoms[z3])->GetSize();z4++) m_iaBasePopulation.Add(((CxIntArray*)sm->m_oaAtomOffset[ag->m_baAtomType[z3]])->GetAt(((CxIntArray*)ag->m_oaAtoms[z3])->GetAt(z4))); } } } mprintf(" Added %d atoms to base population.\n\n",m_iaBasePopulation.GetSize()); mprintf(" Now you have to specify which atoms from the base population\n"); mprintf(" belong to your domain of interest.\n\n"); for (z=0;zm_sName)) { try { ag = new CAtomGroup(); } catch(...) { ag = NULL; } if (ag == NULL) NewException((double)sizeof(CAtomGroup),__FILE__,__LINE__,__PRETTY_FUNCTION__); AskString(" Which atoms to include (e.g. C1,C5-7, *=all)? [all] ",&buf,"*"); if (!ag->ParseAtoms(m,buf)) goto _ag2; m_oaDomainSet.Add(ag); } else m_oaDomainSet.Add(NULL); } mprintf("\n Processing selection...\n"); for (z=0;zm_pMolecule; for (z2=0;z2m_laSingleMolIndex.GetSize();z2++) { sm = (CSingleMolecule*)g_oaSingleMolecules[m->m_laSingleMolIndex[z2]]; for (z3=0;z3m_oaAtoms.GetSize();z3++) { for (z4=0;z4<((CxIntArray*)ag->m_oaAtoms[z3])->GetSize();z4++) { m_iaDomainSet.Add(((CxIntArray*)sm->m_oaAtomOffset[ag->m_baAtomType[z3]])->GetAt(((CxIntArray*)ag->m_oaAtoms[z3])->GetAt(z4))); } } } } mprintf(" Added %d atoms to domain.\n\n",m_iaDomainSet.GetSize()); mprintf(" Checking if domain is a subset of base population...\n"); for (z=0;zm_fMinVal = 0; m_pHistoSurface->m_fMaxVal = AskFloat(" Enter max. domain surface area value [A^2]: [10000.0] ",10000); m_pHistoSurface->m_iResolution = AskUnsignedInteger(" Enter histogram resolution: [100] ",100); m_pHistoSurface->SetLabelX("Domain Surface Area"); m_pHistoSurface->SetLabelY("Occurrence"); m_pHistoSurface->Create(); mprintf("\n"); mprintf(WHITE," Domain Volume Histogram\n"); m_pHistoVolume = new CDF(); m_pHistoVolume->m_fMinVal = 0; m_pHistoVolume->m_fMaxVal = AskFloat(" Enter max. domain volume value [A^3]: [10000.0] ",10000); m_pHistoVolume->m_iResolution = AskUnsignedInteger(" Enter histogram resolution: [100] ",100); m_pHistoVolume->SetLabelX("Domain Volume"); m_pHistoVolume->SetLabelY("Occurrence"); m_pHistoVolume->Create(); mprintf("\n"); mprintf(WHITE," Domain Isoperimetric Quotient Histogram\n"); m_pHistoAVRatio = new CDF(); m_pHistoAVRatio->m_fMinVal = 0; m_pHistoAVRatio->m_fMaxVal = AskFloat(" Enter max. domain isoperimetric quotient value: [1.0] ",1); m_pHistoAVRatio->m_iResolution = AskUnsignedInteger(" Enter histogram resolution: [100] ",100); m_pHistoAVRatio->SetLabelX("Domain Isoperimetric Quotient"); m_pHistoAVRatio->SetLabelY("Occurrence"); m_pHistoAVRatio->Create(); mprintf("\n"); mprintf(WHITE," Domain Face Count Histogram\n"); m_pHistoFaceCount = new CDF(); m_pHistoFaceCount->m_fMinVal = 0; m_pHistoFaceCount->m_fMaxVal = AskUnsignedInteger(" Enter max. domain face count: [10000] ",10000); m_pHistoFaceCount->m_iResolution = AskUnsignedInteger(" Enter histogram resolution: [100] ",100); m_pHistoFaceCount->SetLabelX("Domain Face Count"); m_pHistoFaceCount->SetLabelY("Occurrence"); m_pHistoFaceCount->Create(); mprintf("\n"); mprintf(WHITE," Domain Cell Count Histogram\n"); m_pHistoCellCount = new CDF(); m_pHistoCellCount->m_fMinVal = 0; m_pHistoCellCount->m_fMaxVal = AskUnsignedInteger(" Enter max. domain cell count: [%d] ",m_iaDomainSet.GetSize(),m_iaDomainSet.GetSize()); m_pHistoCellCount->m_iResolution = AskUnsignedInteger(" Enter histogram resolution: [100] ",100); m_pHistoCellCount->SetLabelX("Domain Cell Count"); m_pHistoCellCount->SetLabelY("Occurrence"); m_pHistoCellCount->Create(); mprintf("\n"); mprintf(WHITE," Domain Count Histogram\n"); m_pHistoDomainCount = new CDF(); m_pHistoDomainCount->m_fMinVal = 0; m_pHistoDomainCount->m_fMaxVal = AskUnsignedInteger(" Enter max. domain count: [%d] ",m_iaDomainSet.GetSize(),m_iaDomainSet.GetSize()); m_pHistoDomainCount->m_iResolution = AskUnsignedInteger(" Enter histogram resolution: [100] ",100); m_pHistoDomainCount->SetLabelX("Domain Count"); m_pHistoDomainCount->SetLabelY("Occurrence"); m_pHistoDomainCount->Create(); } mprintf(YELLOW,"\n <<< End of Domain Analysis #%d <<<\n\n",i+1); } void CDomainAnalysis::ProcessStep(CTimeStep *ts) { voronoicell_neighbor c; container_periodic_poly *con; int ijk, q, z, z2, faces, id; double tf; vector nb/*, fo*/; vector fa; CDomain *domain; CxIntArray stack; double sumvol, sqvol, sumsurf, sqsurf, sumav, sqav, sumcell, sqcell, sumface, sqface; double minvol, maxvol, minsurf, maxsurf, minav, maxav, mincell, maxcell, minface, maxface; try { con = new container_periodic_poly(g_fBoxX/1000.0,0,g_fBoxY/1000.0,0,0,g_fBoxZ/1000.0,g_pVoroWrapper->m_iBlocksX,g_pVoroWrapper->m_iBlocksY,g_pVoroWrapper->m_iBlocksZ,g_iVoroMemory); } catch(...) { con = NULL; } if (con == NULL) NewException((double)sizeof(container_periodic_poly),__FILE__,__LINE__,__PRETTY_FUNCTION__); for (z=0;zput(z,ts->m_vaCoords[m_iaBasePopulation[z]][0]/1000.0,ts->m_vaCoords[m_iaBasePopulation[z]][1]/1000.0,ts->m_vaCoords[m_iaBasePopulation[z]][2]/1000.0,g_faVoronoiRadii[m_iaBasePopulation[z]]/1000.0); c_loop_all_periodic vl(*con); for (z=0;zReset(); if (vl.start()) { do { if (con->compute_cell(c,vl)) { ijk=vl.ijk; q=vl.q; id = con->id[ijk][q]; if (!m_iaBaseInDomain[id]) continue; c.neighbors(nb); // c.face_vertices(fv); c.face_areas(fa); // c.face_orders(fo); faces = c.number_of_faces(); domain = (CDomain*)m_oaDomains[id]; if (domain == NULL) mprintf("Error.\n"); domain->m_iaCells.Add(id); domain->m_fSurfaceArea = 0; domain->m_iFaces = 0; for (z=0;zm_iaNeighbors.Add(nb[z]); } else { // Face leads out of domain --> outer surface domain->m_fSurfaceArea += fa[z]*100.0; domain->m_iFaces++; } } domain->m_fVolume = c.volume()*1000.0; domain->m_fAVRatio = 10.6347231054330961*domain->m_fVolume/mypow(domain->m_fSurfaceArea,1.5); } } while (vl.inc()); } delete con; for (z=0;zm_bActive) continue; // mprintf("Starting Recursion for %d (%d)...\n",z,((CDomain*)m_oaDomains[z])->m_iaNeighbors.GetSize()); stack.RemoveAll_KeepSize(); REC_FuseDomain(z,z,&stack); } z2 = 0; sumvol = 0; sqvol = 0; minvol = 1.0e30; maxvol = -1.0e30; sumsurf = 0; sqsurf = 0; minsurf = 1.0e30; maxsurf = -1.0e30; sumav = 0; sqav = 0; minav = 1.0e30; maxav = -1.0e30; sumface = 0; sqface = 0; minface = 1.0e30; maxface = -1.0e30; sumcell = 0; sqcell = 0; mincell = 1.0e30; maxcell = -1.0e30; for (z=0;zm_bActive) continue; tf = domain->m_fVolume; sumvol += tf; sqvol += tf*tf; if (tf < minvol) minvol = tf; if (tf > maxvol) maxvol = tf; tf = domain->m_fSurfaceArea; sumsurf += tf; sqsurf += tf*tf; if (tf < minsurf) minsurf = tf; if (tf > maxsurf) maxsurf = tf; tf = domain->m_fAVRatio; sumav += tf; sqav += tf*tf; if (tf < minav) minav = tf; if (tf > maxav) maxav = tf; tf = domain->m_iFaces; sumface += tf; sqface += tf*tf; if (tf < minface) minface = tf; if (tf > maxface) maxface = tf; tf = domain->m_iaCells.GetSize(); sumcell += tf; sqcell += tf*tf; if (tf < mincell) mincell = tf; if (tf > maxcell) maxcell = tf; if (m_bWriteHistograms) { m_pHistoVolume->AddToBin(domain->m_fVolume); m_pHistoSurface->AddToBin(domain->m_fSurfaceArea); m_pHistoAVRatio->AddToBin(domain->m_fAVRatio); m_pHistoFaceCount->AddToBin(domain->m_iFaces); m_pHistoCellCount->AddToBin(domain->m_iaCells.GetSize()); } z2++; } if (m_bWriteHistograms) m_pHistoDomainCount->AddToBin(z2); // mprintf("%d domains active.\n",z2); sumvol /= z2; m_faVolumeAv.Add(sumvol); m_faVolumeSD.Add(sqrt(sqvol/z2 - sumvol*sumvol)); m_faVolumeMin.Add(minvol); m_faVolumeMax.Add(maxvol); sumsurf /= z2; m_faSurfaceAv.Add(sumsurf); m_faSurfaceSD.Add(sqrt(sqsurf/z2 - sumsurf*sumsurf)); m_faSurfaceMin.Add(minsurf); m_faSurfaceMax.Add(maxsurf); sumav /= z2; m_faAVRatioAv.Add(sumav); m_faAVRatioSD.Add(sqrt(sqav/z2 - sumav*sumav)); m_faAVRatioMin.Add(minav); m_faAVRatioMax.Add(maxav); sumface /= z2; m_faFaceCountAv.Add(sumface); m_faFaceCountSD.Add(sqrt(sqface/z2 - sumface*sumface)); m_faFaceCountMin.Add(minface); m_faFaceCountMax.Add(maxface); sumcell /= z2; m_faCellCountAv.Add(sumcell); m_faCellCountSD.Add(sqrt(sqcell/z2 - sumcell*sumcell)); m_faCellCountMin.Add(mincell); m_faCellCountMax.Add(maxcell); m_iaDomainCount.Add(z2); m_iaStep.Add(g_iSteps); } void CDomainAnalysis::REC_FuseDomain(int basedom, int dom, CxIntArray *stack) { int i, z, z2; CDomain *pdom; stack->Add(dom); pdom = (CDomain*)m_oaDomains[dom]; if (dom != basedom) { // mprintf(" Assimilating %d into %d.\n",dom,basedom); ((CDomain*)m_oaDomains[basedom])->Assimilate(pdom); } for (z=0;zm_iaNeighbors.GetSize();z++) { i = pdom->m_iaNeighbors[z]; if (((CDomain*)m_oaDomains[i])->m_bActive) { for (z2=0;z2GetSize();z2++) if (stack->GetAt(z2) == i) goto _next; REC_FuseDomain(basedom,i,stack); } _next:; } stack->Pop_KeepSize(); } void CDomainAnalysis::Finish(int i) { // char buf[1024]; CxString buf, buf2; double tf; int z; FILE *a; // sprintf(buf,"domain"); buf.sprintf("domain"); for (z=0;zm_pMolecule->m_sName); // strcat(buf,"_"); // strcat(buf,((CAtomGroup*)m_oaDomainSet[z])->m_sName); buf.strcat("_"); buf.strcat(((CAtomGroup*)m_oaDomainSet[z])->m_pMolecule->m_sName); buf.strcat("_"); buf.strcat(((CAtomGroup*)m_oaDomainSet[z])->m_sName); } // strcat(buf,".csv"); buf2 = buf; buf2.strcat("_statistics.csv"); mprintf(" Analysis %d: Writing results to %s ...\n",i+1,(const char*)buf); a = OpenFileWrite(buf2,true); fprintf(a,"#Step; Domain_count; Volume_(A^3)_Avg; Min; Max; SD; Surface_Area_(A^2)_Avg; Min; Max; SD; Isoperimetric_Quotient_Avg; Min; Max; SD; Face_Count_Avg; Min; Max; SD; Cell_Count_Avg; Min; Max; SD\n"); fprintf(a,"#Simulation_Average; "); tf = 0; for (z=0;zm_fBinEntries,m_pHistoSurface->m_fSkipEntries); m_pHistoSurface->NormBinSum(100.0); m_pHistoSurface->Write("",buf,"_histo_surface.csv",true); mprintf(" Saving Domain Volume Histogram as %s_histo_volume.csv.\n",(const char*)buf); mprintf(" (%.0f bin entries, %.0f skipped)\n\n",m_pHistoVolume->m_fBinEntries,m_pHistoVolume->m_fSkipEntries); m_pHistoVolume->NormBinSum(100.0); m_pHistoVolume->Write("",buf,"_histo_volume.csv",true); mprintf(" Saving Domain Isoperimetric Quotient Histogram as %s_histo_avratio.csv.\n",(const char*)buf); mprintf(" (%.0f bin entries, %.0f skipped)\n\n",m_pHistoAVRatio->m_fBinEntries,m_pHistoAVRatio->m_fSkipEntries); m_pHistoAVRatio->NormBinSum(100.0); m_pHistoAVRatio->Write("",buf,"_histo_avratio.csv",true); mprintf(" Saving Domain Face Count Histogram as %s_histo_faces.csv.\n",(const char*)buf); mprintf(" (%.0f bin entries, %.0f skipped)\n\n",m_pHistoFaceCount->m_fBinEntries,m_pHistoFaceCount->m_fSkipEntries); m_pHistoFaceCount->NormBinSum(100.0); m_pHistoFaceCount->Write("",buf,"_histo_faces.csv",true); mprintf(" Saving Domain Cell Count Histogram as %s_histo_cells.csv.\n",(const char*)buf); mprintf(" (%.0f bin entries, %.0f skipped)\n\n",m_pHistoCellCount->m_fBinEntries,m_pHistoCellCount->m_fSkipEntries); m_pHistoCellCount->NormBinSum(100.0); m_pHistoCellCount->Write("",buf,"_histo_cells.csv",true); mprintf(" Saving Domain Count Histogram as %s_histo_domaincount.csv.\n",(const char*)buf); mprintf(" (%.0f bin entries, %.0f skipped)\n\n",m_pHistoDomainCount->m_fBinEntries,m_pHistoDomainCount->m_fSkipEntries); m_pHistoDomainCount->NormBinSum(100.0); m_pHistoDomainCount->Write("",buf,"_histo_domaincount.csv",true); } } CDomainEngine::CDomainEngine() { } CDomainEngine::~CDomainEngine() { } void CDomainEngine::Parse() { CTimeStep *ts; CDomainAnalysis *tempdoma; try { g_pVoroWrapper = new CVoroWrapper(); } catch(...) { g_pVoroWrapper = NULL; } if (g_pVoroWrapper == NULL) NewException((double)sizeof(CVoroWrapper),__FILE__,__LINE__,__PRETTY_FUNCTION__); mprintf(" Initializing Voronoi tesselation...\n"); g_pVoroWrapper->Init(); mprintf("\n"); mprintf("*** Voro: Box density is %f particles / Angstrom^3.\n",g_pVoroWrapper->m_fBoxDens); mprintf("*** Voro: Using %d x %d x %d blocks.\n",g_pVoroWrapper->m_iBlocksX,g_pVoroWrapper->m_iBlocksY,g_pVoroWrapper->m_iBlocksZ); try { ts = new CTimeStep(); } catch(...) { ts = NULL; } if (ts == NULL) NewException((double)sizeof(CTimeStep),__FILE__,__LINE__,__PRETTY_FUNCTION__); ts->CopyFrom(&g_TimeStep); ts->FoldAtomsPositive(); g_pVoroWrapper->Dump("voro.txt",ts); mprintf("\n"); mprintf(" Voro++: Using cell memory for %d particles.\n\n",g_iVoroMemory); do { try { tempdoma = new CDomainAnalysis(); } catch(...) { tempdoma = NULL; } if (tempdoma == NULL) NewException(sizeof(CDomainAnalysis),__FILE__,__LINE__,__PRETTY_FUNCTION__); tempdoma->Parse(m_oaAnalyses.GetSize()); m_oaAnalyses.Add(tempdoma); } while (AskYesNo(" Add another domain analysis (y/n)? [no] ",false)); } void CDomainEngine::ProcessStep(CTimeStep *ts) { int z; for (z=0;zProcessStep(ts); } void CDomainEngine::Finish() { int z; mprintf(YELLOW," >>> Finishing Domain Analysis >>>\n"); for (z=0;zFinish(z); mprintf(YELLOW," <<< Finishing Domain Analysis done <<<\n"); } travis-src-190101/src/domain.h0100777000000000000000000000605213412725663013065 0ustar00/***************************************************************************** TRAVIS - Trajectory Analyzer and Visualizer http://www.travis-analyzer.de/ Copyright (c) 2009-2019 Martin Brehm 2012-2019 Martin Thomas 2016-2019 Sascha Gehrke This file was written by Martin Brehm. --------------------------------------------------------------------------- This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . *****************************************************************************/ // This must always be the first include directive #include "config.h" #ifndef DOMAIN_H #define DOMAIN_H #include "xobject.h" #include "xobarray.h" #include "xintarray.h" #include "timestep.h" class CDomain : public CxObject { public: CDomain(); ~CDomain(); void Reset(); void Assimilate(CDomain *dom); bool m_bActive; CxIntArray m_iaCells; CxIntArray m_iaNeighbors; double m_fSurfaceArea; double m_fVolume; double m_fAVRatio; int m_iFaces; }; class CDomainAnalysis : public CxObject { public: CDomainAnalysis(); ~CDomainAnalysis(); void Parse(int i); void ProcessStep(CTimeStep *ts); void Finish(int i); void REC_FuseDomain(int basedom, int dom, CxIntArray *stack); bool m_bWriteHistograms; CDF *m_pHistoSurface; CDF *m_pHistoVolume; CDF *m_pHistoAVRatio; CDF *m_pHistoFaceCount; CDF *m_pHistoCellCount; CDF *m_pHistoDomainCount; CxObArray m_oaBasePopulation; // Both contain one CAtomGroup object per CMolecule CxObArray m_oaDomainSet; CxIntArray m_iaBasePopulation; CxIntArray m_iaDomainSet; CxIntArray m_iaBaseInDomain; CxObArray m_oaDomains; CxDoubleArray m_faSurfaceAv; CxDoubleArray m_faSurfaceMin; CxDoubleArray m_faSurfaceMax; CxDoubleArray m_faSurfaceSD; CxDoubleArray m_faVolumeAv; CxDoubleArray m_faVolumeMin; CxDoubleArray m_faVolumeMax; CxDoubleArray m_faVolumeSD; CxDoubleArray m_faAVRatioAv; CxDoubleArray m_faAVRatioMin; CxDoubleArray m_faAVRatioMax; CxDoubleArray m_faAVRatioSD; CxDoubleArray m_faFaceCountAv; CxDoubleArray m_faFaceCountMin; CxDoubleArray m_faFaceCountMax; CxDoubleArray m_faFaceCountSD; CxDoubleArray m_faCellCountAv; CxDoubleArray m_faCellCountMin; CxDoubleArray m_faCellCountMax; CxDoubleArray m_faCellCountSD; CxIntArray m_iaDomainCount; CxIntArray m_iaStep; }; class CDomainEngine : public CxObject { public: CDomainEngine(); ~CDomainEngine(); void Parse(); void ProcessStep(CTimeStep *ts); void Finish(); CxObArray m_oaAnalyses; }; #endif travis-src-190101/src/element.h0100777000000000000000000000520313412725660013241 0ustar00/***************************************************************************** TRAVIS - Trajectory Analyzer and Visualizer http://www.travis-analyzer.de/ Copyright (c) 2009-2019 Martin Brehm 2012-2019 Martin Thomas 2016-2019 Sascha Gehrke This file was written by Martin Brehm. --------------------------------------------------------------------------- This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . *****************************************************************************/ #ifndef ELEMENT_H #define ELEMENT_H // This must always be the first include directive #include "config.h" #include "xobject.h" class CElement : public CxObject { public: CElement() { m_sLabel = NULL; m_iColorR = 0; m_iColorG = 255; m_iColorB = 255; m_iColorBleachedR = 170; m_iColorBleachedG = 170; m_iColorBleachedB = 170; m_fMass = 0; m_fRadius = 0; m_iOrd = 0; m_fVdWRadius = 0; } virtual ~CElement() { if (m_sLabel != NULL) { delete[] m_sLabel; m_sLabel = NULL; } } void CopyData(CElement *e) { m_fMass = e->m_fMass; m_iOrd = e->m_iOrd; m_fRadius = e->m_fRadius; m_iColorR = e->m_iColorR; m_iColorG = e->m_iColorG; m_iColorB = e->m_iColorB; m_iColorBleachedR = e->m_iColorBleachedR; m_iColorBleachedG = e->m_iColorBleachedG; m_iColorBleachedB = e->m_iColorBleachedB; } char *m_sLabel; double m_fMass; double m_fRadius; double m_fVdWRadius; int m_iOrd; double m_fCoherentNCS; unsigned char m_iColorR; unsigned char m_iColorG; unsigned char m_iColorB; unsigned char m_iColorBleachedR; unsigned char m_iColorBleachedG; unsigned char m_iColorBleachedB; unsigned char ColorR(double bleached) { return (unsigned char)(((double)m_iColorBleachedR-m_iColorR)*bleached+m_iColorR); } unsigned char ColorG(double bleached) { return (unsigned char)(((double)m_iColorBleachedG-m_iColorG)*bleached+m_iColorG); } unsigned char ColorB(double bleached) { return (unsigned char)(((double)m_iColorBleachedB-m_iColorB)*bleached+m_iColorB); } }; #endif travis-src-190101/src/elementdata.cpp0100777000000000000000000002051413412725625014431 0ustar00/***************************************************************************** TRAVIS - Trajectory Analyzer and Visualizer http://www.travis-analyzer.de/ Copyright (c) 2009-2019 Martin Brehm 2012-2019 Martin Thomas 2016-2019 Sascha Gehrke This file was written by Martin Brehm and Philipp di Dio. --------------------------------------------------------------------------- This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . *****************************************************************************/ /**************************************************************************** Sources of Van-der-Waals radii: 1) R. Scott Rowland, Robin Taylor: Intermolecular Nonbonded Contact Distances in Organic Crystal Structures: Comparison with Distances Expected from van der Waals Radii. In: J. Phys. Chem. 1996, 100, S. 7384-7391, doi:10.1021/jp953141+. 2) A. Bondi: van der Waals Volumes and Radii. In: J. Phys. Chem. 1964, 68, S. 441-451, doi:10.1021/j100785a001. 3) Manjeera Mantina, Adam C. Chamberlin, Rosendo Valero, Christopher J. Cramer, Donald G. Truhlar: Consistent van der Waals Radii for the Whole Main Group. In: J. Phys. Chem. A. 2009, 113, S. 5806-5812, doi:10.1021/jp8111556. Coherent Neutron Scattering Cross Sections: Published in "Neutron News, Vol. 3, No. 3, 1992, pp. 29-37". Taken from "http://www.ncnr.nist.gov/resources/n-lengths/". Source of atomic masses: https://physics.nist.gov/cgi-bin/Compositions/stand_alone.pl The middle of the "standard atomic weight" intervals was chosen. *****************************************************************************/ // This must always be the first include directive #include "config.h" #include "travis.h" const char *GetRevisionInfo_elementdata(unsigned int len) { static char buf[256]; GET_REVISION_INFO( buf, len ); return buf; } const char *GetSourceVersion_elementdata() { static char buf[256]; GET_SOURCE_VERSION( buf ); return buf; } void AddElementData() { // Element, Ord. Number, Mass, Covalent Radius [pm], VdW Radius [pm], ( Coherent Neutron Scattering Cross Section [barn] ) // Lone Pair (for force field simulations) AddElement("LP", 254, 3.00000, 1.0, 1.0); // 1st Period AddElement("H", 1, 1.00798, 37.0, 110.0, 1.7568); AddElement("D", 1, 2.01410, 37.0, 110.0); AddElement("He", 2, 4.00260, 32.0, 140.0); // 2nd Period AddElement("Li", 3, 6.9675, 134.0, 182.0); AddElement("Be", 4, 9.01218, 90.0, 153.0); AddElement("B", 5, 10.8135, 90.0, 192.0); AddElement("C", 6, 12.0106, 82.0, 170.0, 5.551); AddElement("N", 7, 14.0069, 77.0, 155.0, 11.01); AddElement("O", 8, 15.9994, 75.0, 152.0, 4.232); AddElement("F", 9, 18.99840, 73.0, 147.0, 4.017); AddElement("Ne", 10, 20.17976, 69.0, 154.0); // 3rd Period AddElement("Na", 11, 22.98977, 71.0, 227.0); AddElement("Mg", 12, 24.3055, 130.0, 173.0); AddElement("Al", 13, 26.98154, 154.0, 184.0); AddElement("Si", 14, 28.085, 118.0, 210.0); AddElement("P", 15, 30.97376, 111.0, 180.0, 3.307); AddElement("S", 16, 32.0675, 106.0, 180.0, 1.0186); AddElement("Cl", 17, 35.4515, 102.0, 175.0, 11.5257); AddElement("Ar", 18, 39.9481, 97.0, 188.0); // 4th Period AddElement("K", 19, 39.09831, 196.0, 275.0); AddElement("Ca", 20, 40.0784, 174.0, 231.0); AddElement("Sc", 21, 44.95591, 144.0, 0.0); AddElement("Ti", 22, 47.8671, 136.0, 187.0); AddElement("V", 23, 50.94151, 125.0, 0.0); AddElement("Cr", 24, 51.99616, 127.0, 0.0); AddElement("Mn", 25, 54.93804, 139.0, 0.0); AddElement("Fe", 26, 55.8452, 125.0, 0.0); AddElement("Co", 27, 58.93319, 126.0, 0.0); AddElement("Ni", 28, 58.69344, 121.0, 163.0); AddElement("Cu", 29, 63.5463, 138.0, 140.0); AddElement("Zn", 30, 65.382, 131.0, 139.0); AddElement("Ga", 31, 69.7231, 126.0, 187.0); AddElement("Ge", 32, 72.6308, 122.0, 211.0); AddElement("As", 33, 74.92160, 121.0, 185.0); AddElement("Se", 34, 78.9718, 116.0, 190.0); AddElement("Br", 35, 79.904, 114.0, 185.0); AddElement("Kr", 36, 83.7982, 110.0, 202.0); // 5th Period AddElement("Rb", 37, 85.46783, 211.0, 303.0); AddElement("Sr", 38, 87.621, 192.0, 249.0); AddElement("Y", 39, 88.90584, 162.0, 0.0); AddElement("Zr", 40, 91.2242, 148.0, 0.0); AddElement("Nb", 41, 92.90637, 137.0, 0.0); AddElement("Mo", 42, 95.951, 145.0, 0.0); AddElement("Tc", 43, 98.00, 131.0, 0.0); AddElement("Ru", 44, 101.072, 126.0, 0.0); AddElement("Rh", 45, 102.90550, 135.0, 0.0); AddElement("Pd", 46, 106.421, 131.0, 163.0); AddElement("Ag", 47, 107.86822, 153.0, 172.0); AddElement("Cd", 48, 112.4144, 148.0, 158.0); AddElement("In", 49, 114.8181, 144.0, 193.0); AddElement("Sn", 50, 118.7107, 141.0, 217.0); AddElement("Sb", 51, 121.7601, 138.0, 206.0); AddElement("Te", 52, 127.603, 135.0, 206.0); AddElement("I", 53, 126.90447, 133.0, 198.0); AddElement("Xe", 54, 131.2936, 130.0, 216.0); // 6th Period AddElement("Cs", 55, 132.90545, 225.0, 343.0); AddElement("Ba", 56, 137.3277, 198.0, 268.0); AddElement("La", 57, 138.90548, 169.0, 0.0); AddElement("Ce", 58, 140.1161, 204.0, 0.0); AddElement("Pr", 59, 140.90766, 203.0, 0.0); AddElement("Nd", 60, 144.2423, 201.0, 0.0); AddElement("Pm", 61, 145.00, 199.0, 0.0); AddElement("Sm", 62, 150.362, 198.0, 0.0); AddElement("Eu", 63, 151.9641, 198.0, 0.0); AddElement("Gd", 64, 157.253, 196.0, 0.0); AddElement("Tb", 65, 158.92535, 194.0, 0.0); AddElement("Dy", 66, 162.5001, 192.0, 0.0); AddElement("Ho", 67, 164.93033, 192.0, 0.0); AddElement("Er", 68, 167.2593, 189.0, 0.0); AddElement("Tm", 69, 168.93422, 190.0, 0.0); AddElement("Yb", 70, 173.0545, 187.0, 0.0); AddElement("Lu", 71, 174.96681, 187.0, 0.0); AddElement("Hf", 72, 178.492, 150.0, 0.0); AddElement("Ta", 73, 180.94788, 138.0, 0.0); AddElement("W", 74, 183.841, 146.0, 0.0); AddElement("Re", 75, 186.2071, 159.0, 0.0); AddElement("Os", 76, 190.233, 128.0, 0.0); AddElement("Ir", 77, 192.2173, 137.0, 0.0); AddElement("Pt", 78, 195.0849, 138.0, 0.0); AddElement("Au", 79, 196.96657, 144.0, 0.0); AddElement("Hg", 80, 200.5923, 149.0, 0.0); AddElement("Tl", 81, 204.384, 148.0, 0.0); AddElement("Pb", 82, 207.21, 146.0, 0.0); AddElement("Bi", 83, 208.98040, 146.0, 0.0); AddElement("Po", 84, 209.00, 140.0, 0.0); AddElement("At", 85, 210.00, 145.0, 0.0); AddElement("Rn", 86, 222.00, 145.0, 0.0); /* 7th period */ AddElement("Fr", 87, 223.00, 260.0, 0.0); AddElement("Ra", 88, 226.00, 221.0, 0.0); AddElement("Ac", 89, 227.00, 215.0, 0.0); AddElement("Th", 90, 232.03774, 206.0, 0.0); AddElement("Pa", 91, 231.03588, 200.0, 0.0); AddElement("U", 92, 238.02891, 196.0, 0.0); AddElement("Np", 93, 237.00, 190.0, 0.0); AddElement("Pu", 94, 244.10, 187.0, 0.0); AddElement("Am", 95, 243.10, 180.0, 0.0); AddElement("Cm", 96, 247.10, 169.0, 0.0); AddElement("Bk", 97, 247.10, 160.0, 0.0); AddElement("Cf", 98, 251.10, 160.0, 0.0); AddElement("Es", 99, 254.10, 160.0, 0.0); AddElement("Fm", 100, 257.10, 160.0, 0.0); AddElement("Md", 101, 258.00, 160.0, 0.0); AddElement("No", 102, 259.00, 160.0, 0.0); AddElement("Lr", 103, 260.00, 160.0, 0.0); // Virtual Atom AddElement("#", 0, 0.00, 0.0, 0.0); // Colors for some common atoms. Other atoms have standard color. SetElementColor("H", 255, 255, 255, 150, 150, 150 ); SetElementColor("C", 228, 113, 0, 180, 180, 180 ); SetElementColor("N", 0, 0, 255, 140, 140, 140 ); SetElementColor("O", 255, 0, 0, 160, 160, 160 ); SetElementColor("S", 255, 255, 0, 200, 200, 200 ); } travis-src-190101/src/fastatof.h0100777000000000000000000000651013412725667013430 0ustar00/***************************************************************************** TRAVIS - Trajectory Analyzer and Visualizer http://www.travis-analyzer.de/ Copyright (c) 2009-2019 Martin Brehm 2012-2019 Martin Thomas 2016-2019 Sascha Gehrke --------------------------------------------------------------------------- This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . *****************************************************************************/ #ifndef FASTATOF_H #define FASTATOF_H // This must always be the first include directive #include "config.h" // // Simple and fast atof (ascii to float) function. // // - Executes about 5x faster than standard MSCRT library atof(). // - An attractive alternative if the number of calls is in the millions. // - Assumes input is a proper integer, fraction, or scientific format. // - Matches library atof() to 15 digits (except at extreme exponents). // - Follows atof() precedent of essentially no error checking. // // 09-May-2009 Tom Van Baak (tvb) www.LeapSecond.com // #define white_space(c) ((c) == ' ' || (c) == '\t') #define valid_digit(c) ((c) >= '0' && (c) <= '9') inline double fast_atof (const char *p) { int frac; double sign, value, scale; // Skip leading white space, if any. while (white_space(*p) ) { p += 1; } // Get sign, if any. sign = 1.0; if (*p == '-') { sign = -1.0; p += 1; } else if (*p == '+') { p += 1; } // Get digits before decimal point or exponent, if any. for (value = 0.0; valid_digit(*p); p += 1) { value = value * 10.0 + (*p - '0'); } // Get digits after decimal point, if any. if (*p == '.') { double pow10 = 10.0; p += 1; while (valid_digit(*p)) { value += (*p - '0') / pow10; pow10 *= 10.0; p += 1; } } // Handle exponent, if any. frac = 0; scale = 1.0; if ((*p == 'e') || (*p == 'E')) { unsigned int expon; // Get sign of exponent, if any. p += 1; if (*p == '-') { frac = 1; p += 1; } else if (*p == '+') { p += 1; } // Get digits of exponent, if any. for (expon = 0; valid_digit(*p); p += 1) { expon = expon * 10 + (*p - '0'); } if (expon > 308) expon = 308; // Calculate scaling factor. while (expon >= 50) { scale *= 1E50; expon -= 50; } while (expon >= 8) { scale *= 1E8; expon -= 8; } while (expon > 0) { scale *= 10.0; expon -= 1; } } // Return signed and scaled floating point result. return sign * (frac ? (value / scale) : (value * scale)); } #endif travis-src-190101/src/fdf.cpp0100777000000000000000000001623113412725622012703 0ustar00/***************************************************************************** TRAVIS - Trajectory Analyzer and Visualizer http://www.travis-analyzer.de/ Copyright (c) 2009-2019 Martin Brehm 2012-2019 Martin Thomas 2016-2019 Sascha Gehrke This file was written by Martin Thomas. --------------------------------------------------------------------------- This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . *****************************************************************************/ // This must always be the first include directive #include "config.h" #include "fdf.h" #include "conversion.h" #include "globalvar.h" const char *GetRevisionInfo_fdf(unsigned int len) { static char buf[256]; GET_REVISION_INFO( buf, len ); return buf; } const char *GetSourceVersion_fdf() { static char buf[256]; GET_SOURCE_VERSION( buf ); return buf; } static CxObArray g_fdfObserv; CFDFObservation::CFDFObservation() : CObservation() { m_pConditions = NULL; m_bTimeDev = false; m_bSelf = true; m_bOthers = false; m_iShowMol2 = -1; m_bSecondShowMol = false; m_bObsCertain = false; m_bDecompDist = false; m_bDecompType = false; CxString buf, buf2; if (g_oaMolecules.GetSize() > 1) { buf.sprintf(" Which molecule should be observed ("); int i; for(i = 0; i < g_oaMolecules.GetSize(); i++) { buf2.sprintf("%s=%d", ((CMolecule *)g_oaMolecules[i])->m_sName, i+1); buf.strcat(buf2); if(i < g_oaMolecules.GetSize() - 1) buf.strcat(", "); } buf.strcat(")? "); m_iShowMol = AskRangeInteger_ND("%s", 1, g_oaMolecules.GetSize(), (const char*)buf) - 1; } else { m_iShowMol = 0; mprintf(" Observing molecule %s.\n\n", ((CMolecule *)g_oaMolecules[m_iShowMol])->m_sName); } m_iShowMolCount = ((CMolecule *)g_oaMolecules[m_iShowMol])->m_laSingleMolIndex.GetSize(); while(true) { AskString(" Which atom(s) to observe (e.g. \"C1,C3-5,H\", \"*\"=all)? [#2] ", &buf, "#2"); if (m_atoms.ParseAtoms((CMolecule *)g_oaMolecules[m_iShowMol], buf)) break; } mprintf("\n Observing %d atoms of molecule %s.\n\n", m_atoms.m_iAtomGes, ((CMolecule *)g_oaMolecules[m_iShowMol])->m_sName); m_name.sprintf("[%s_%s]", ((CMolecule *)g_oaMolecules[m_iShowMol])->m_sName, m_atoms.m_sName); m_massWeighting = AskYesNo(" Use forces (y) or omit mass weighting and use accelerations (n)? [yes] ", true); mprintf("\n"); if (m_massWeighting) { m_fdf.m_fMinVal = AskFloat(" Please enter the minimal force in pN: [0.0] ", 0.0); m_fdf.m_fMaxVal = AskFloat(" Please enter the maximal force in pN: [10000.0] ", 10000.0); m_fdf.m_iResolution = AskInteger(" Please enter the binning resolution: [100] ", 100); } else { m_fdf.m_fMinVal = AskFloat(" Please enter the minimal acceleration in pm/ps^2: [0.0] ", 0.0); m_fdf.m_fMaxVal = AskFloat(" Please enter the maximal acceleration in pm/ps^2: [100000.0] ", 100000.0); m_fdf.m_iResolution = AskInteger(" Please enter the binning resolution: [100] ", 100); } } void CFDFObservation::initialize() { if (m_massWeighting) m_fdf.SetLabelX("Force / pN"); else m_fdf.SetLabelX("Acceleration / pm*ps^-2"); m_fdf.SetLabelY("Occurrence"); m_fdf.Create(); m_masses.SetSize(m_atoms.m_iAtomGes); if (m_massWeighting) { int n = 0; int i; for(i = 0; i < m_atoms.m_baRealAtomType.GetSize(); i++) { CxIntArray *a = (CxIntArray *)m_atoms.m_oaAtoms[i]; int j; for(j = 0; j < a->GetSize(); j++) { if (m_atoms.m_baRealAtomType[i] == g_iVirtAtomType) m_masses[n] = m_atoms.m_pMolecule->m_fMass; else m_masses[n] = ((CAtom *)g_oaAtoms[m_atoms.m_baRealAtomType[i]])->m_pElement->m_fMass; m_masses[n] *= (double)(1.0E24 * CONST_ATOMIC_MASS_UNIT); // Conversion to obtain final forces in pN n++; } } } else { int i; for (i = 0; i < m_masses.GetSize(); i++) { m_masses[i] = 1.0; } } } void CFDFObservation::process(CTimeStep *ts) { int i, j, k; for (i = 0; i < m_iShowMolCount; i++) { CSingleMolecule *sm = (CSingleMolecule *)g_oaSingleMolecules[((CMolecule *)g_oaMolecules[m_iShowMol])->m_laSingleMolIndex[i]]; int n = 0; for (j = 0; j < m_atoms.m_baAtomType.GetSize(); j++) { CxIntArray *a = (CxIntArray *)m_atoms.m_oaAtoms[j]; for (k = 0; k < a->GetSize(); k++) { m_fdf.AddToBin(ts->m_vaForces[((CxIntArray *)sm->m_oaAtomOffset[m_atoms.m_baAtomType[j]])->GetAt(a->GetAt(k))].GetLength() * m_masses[n]); n++; } } } } void CFDFObservation::finalize() { mprintf(" %.0f bin entries, %.0f out of bin range (%.2f percent).\n", m_fdf.m_fBinEntries, m_fdf.m_fSkipEntries, ZeroDivide(m_fdf.m_fSkipEntries, m_fdf.m_fBinEntries + m_fdf.m_fSkipEntries) * 100.0); m_fdf.CalcMeanSD(); CxString unit; if (m_massWeighting) unit.sprintf("pN"); else unit.sprintf("pm/ps^2"); mprintf(" Mean value: %10G %s Standard deviation: %10G %s\n", m_fdf.m_fMean, (const char *)unit, m_fdf.m_fSD, (const char *)unit); mprintf(" Min. value: %10G %s Max.value: %10G %s\n", m_fdf.m_fMinInput, (const char *)unit, m_fdf.m_fMaxInput, (const char *)unit); m_fdf.MultiplyBin(1.0 / g_iSteps); m_fdf.Integrate(false, 1.0); CxString filename; filename.sprintf("fdf_%s.csv", (const char *)m_name); mprintf(" Saving FDF as \"%s\"...\n", (const char *)filename); m_fdf.Write("", filename, "", true); filename.sprintf("fdf_%s.agr", (const char *)m_name); mprintf(" Saving FDF AGR as \"%s\"...\n", (const char *)filename); m_fdf.WriteAgr("", filename, "", m_name, true); } bool gatherFDF() { g_bUseForces = true; while (true) { mprintf(YELLOW, "\n>>> FDF Observation %d >>>\n\n", g_fdfObserv.GetSize() + 1); CFDFObservation *obs; try { obs = new CFDFObservation(); } catch(...) { obs = NULL; } if (obs == NULL) NewException((double)sizeof(CFDFObservation), __FILE__, __LINE__, __PRETTY_FUNCTION__); g_fdfObserv.Add(obs); mprintf(YELLOW, "\n<<< End of FDF Observation %d <<<\n\n", g_fdfObserv.GetSize()); if (!AskYesNo(" Add another observation (y/n)? [no] ", false)) break; mprintf("\n"); } return true; } bool initializeFDF() { int i; for (i = 0; i < g_fdfObserv.GetSize(); i++) { ((CFDFObservation *)g_fdfObserv[i])->initialize(); } return true; } void processFDF(CTimeStep *ts) { int i; for (i = 0; i < g_fdfObserv.GetSize(); i++) { ((CFDFObservation *)g_fdfObserv[i])->process(ts); } } void finalizeFDF() { int i; for (i = 0; i < g_fdfObserv.GetSize(); i++) { mprintf(YELLOW, "\n>>> FDF Observation %d >>>\n\n", i + 1); ((CFDFObservation *)g_fdfObserv[i])->finalize(); delete (CFDFObservation *)g_fdfObserv[i]; mprintf(YELLOW, "\n<<< End of FDF Observation %d <<<\n\n", i + 1); } } travis-src-190101/src/fdf.h0100777000000000000000000000316413412725670012354 0ustar00/***************************************************************************** TRAVIS - Trajectory Analyzer and Visualizer http://www.travis-analyzer.de/ Copyright (c) 2009-2019 Martin Brehm 2012-2019 Martin Thomas 2016-2019 Sascha Gehrke This file was written by Martin Thomas. --------------------------------------------------------------------------- This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . *****************************************************************************/ #ifndef FDF_H #define FDF_H // This must always be the first include directive #include "config.h" #include "moltools.h" class CTimeStep; class CFDFObservation: public CObservation { public: CFDFObservation(); void initialize(); void process(CTimeStep *ts); void finalize(); private: CAtomGroup m_atoms; CxString m_name; CDF m_fdf; bool m_massWeighting; CxDoubleArray m_masses; }; bool gatherFDF(); bool initializeFDF(); void processFDF(CTimeStep *ts); void finalizeFDF(); #endif travis-src-190101/src/fft.cpp0100777000000000000000000001257213412725623012730 0ustar00/***************************************************************************** TRAVIS - Trajectory Analyzer and Visualizer http://www.travis-analyzer.de/ Copyright (c) 2009-2019 Martin Brehm 2012-2019 Martin Thomas 2016-2019 Sascha Gehrke This file was written by Martin Brehm. --------------------------------------------------------------------------- This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . *****************************************************************************/ // This must always be the first include directive #include "config.h" #include "fft.h" #include "tools.h" const char *GetRevisionInfo_fft(unsigned int len) { static char buf[256]; GET_REVISION_INFO( buf, len ); return buf; } const char *GetSourceVersion_fft() { static char buf[256]; GET_SOURCE_VERSION( buf ); return buf; } #ifdef USE_FFTW /************************************************************************* ************ FFTW ******************************************************** *************************************************************************/ CFFT::CFFT() { BTIN; m_pPlan = NULL; BTOUT; } CFFT::~CFFT() { BTIN; if (m_pPlan != NULL) { fftwf_destroy_plan(m_pPlan); fftwf_free(m_pInput); fftwf_free(m_pOutput); } BTOUT; } /*void CFFT::PrepareFFT_R2C(int n) { BTIN; int z; // m_bInputComplex = false; // m_bOutputComplex = true; m_iSize = n; m_pInput = (float*)fftwf_malloc(sizeof(float) * n); for (z=0;z. *****************************************************************************/ #ifndef FFT_H #define FFT_H // This must always be the first include directive #include "config.h" #include "xobject.h" #include "backtrace.h" #include "tools.h" #include "kiss_fft.h" #ifdef USE_FFTW #include "fftw3.h" #endif class CFFT : public CxObject { public: CFFT(); ~CFFT(); int NextFastSize(int i); // void PrepareFFT_R2C(int n); void PrepareFFT_C2C(int n); void PrepareInverseFFT_C2C(int n); void DoFFT(); int m_iSize; double *m_pInput; double *m_pOutput; #ifdef USE_FFTW fftwf_plan m_pPlan; #else kiss_fft_cfg m_pKISSCfg; void KISS_FFT(); #endif }; #endif travis-src-190101/src/fixplproj.cpp0100777000000000000000000003151513412725617014167 0ustar00/***************************************************************************** TRAVIS - Trajectory Analyzer and Visualizer http://www.travis-analyzer.de/ Copyright (c) 2009-2019 Martin Brehm 2012-2019 Martin Thomas 2016-2019 Sascha Gehrke This file was written by Martin Brehm. --------------------------------------------------------------------------- This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . *****************************************************************************/ // This must always be the first include directive #include "config.h" #include "fixplproj.h" #include "globalvar.h" const char *GetRevisionInfo_fixplproj(unsigned int len) { static char buf[256]; GET_REVISION_INFO( buf, len ); return buf; } const char *GetSourceVersion_fixplproj() { static char buf[256]; GET_SOURCE_VERSION( buf ); return buf; } bool CFixedPlProjObservation::Parse(int i) { int z, z2, z3, z4, ti; std::vector tia; CxString buf; CMolecule *m; CSingleMolecule *sm; CAtomGroup ag, ag2; mprintf(WHITE,"\n >>> Observation %d >>>\n\n",i+1); try { m_p2DF = new C2DF(); } catch(...) { m_p2DF = NULL; } if (m_p2DF == NULL) NewException((double)sizeof(C2DF),__FILE__,__LINE__,__PRETTY_FUNCTION__); m_vPlaneBase[0] = AskFloat(" Enter X coordinate of base point (in pm): [0] ",0); m_vPlaneBase[1] = AskFloat(" Enter Y coordinate of base point (in pm): [0] ",0); m_vPlaneBase[2] = AskFloat(" Enter Z coordinate of base point (in pm): [0] ",0); mprintf("\n"); _nvagain: m_vPlaneVec1[0] = AskFloat(" Enter X coordinate of first spanning vector: [1.0] ",1.0); m_vPlaneVec1[1] = AskFloat(" Enter Y coordinate of first spanning vector: [0] ",0); m_vPlaneVec1[2] = AskFloat(" Enter Z coordinate of first spanning vector: [0] ",0); if (m_vPlaneVec1.GetLength() == 0) { eprintf("\n Error: The length of the spanning vector is zero.\n\n"); goto _nvagain; } mprintf("\n"); _nvagain2: m_vPlaneVec2[0] = AskFloat(" Enter X coordinate of second spanning vector: [0] ",0); m_vPlaneVec2[1] = AskFloat(" Enter Y coordinate of second spanning vector: [1.0] ",1.0); m_vPlaneVec2[2] = AskFloat(" Enter Z coordinate of second spanning vector: [0] ",0); if (m_vPlaneVec2.GetLength() == 0) { eprintf("\n Error: The length of the spanning vector is zero.\n\n"); goto _nvagain2; } mprintf("\n Normalizing spanning vectors...\n"); m_vPlaneVec1.Normalize(); m_vPlaneVec2.Normalize(); m_vPlaneNormal = CrossP(m_vPlaneVec1,m_vPlaneVec2); m_vPlaneNormal.Normalize(); mprintf(" Vector 1: ( %9.6f | %9.6f | %9.6f )\n",m_vPlaneVec1[0],m_vPlaneVec1[1],m_vPlaneVec1[2]); mprintf(" Vector 2: ( %9.6f | %9.6f | %9.6f )\n",m_vPlaneVec2[0],m_vPlaneVec2[1],m_vPlaneVec2[2]); mprintf(" Plane Normal: ( %9.6f | %9.6f | %9.6f )\n\n",m_vPlaneNormal[0],m_vPlaneNormal[1],m_vPlaneNormal[2]); if (m_vPlaneNormal.GetLength() == 0) { eprintf(" Error: Both spanning vectors are linear. No plane defined.\n\n"); return false; } m_bDifference = AskYesNo(" Observe absolute atom position (n) or difference between 2 atoms in a molecule (y)? [yes] ",true); for (z=0;zm_sName)) { tia.clear(); if (AskYesNo(" Take into account all %s molecules (y) or only some of them (n)? [yes] ",true,m->m_sName)) { for (z2=0;z2m_laSingleMolIndex.GetSize();z2++) tia.push_back(z2); } else { mprintf("\n"); _smagain: AskString_ND(" Which of the %d %s molecules to take into account (e.g. 3-7,9): ",&buf,m->m_laSingleMolIndex.GetSize(),m->m_sName); if (!ParseIntList((const char*)buf,tia)) { eprintf("\n Invalid input.\n\n"); goto _smagain; } mprintf(" Observing %lu molecules of %s.\n\n",tia.size(),m->m_sName); } ti = (int)m_iaAtomList.size(); if (m_bDifference) { mprintf(" You can now enter several pairs of atoms between which the distance vector is processed.\n"); while (true) { mprintf("\n"); _atagain2: AskString(" Enter first atom of pair from %s (e.g. C3): [done] ",&buf,"",m->m_sName); if (buf.GetLength() == 0) break; ag.Reset(); if (!ag.ParseAtoms(m,(const char*)buf)) { eprintf("\n Invalid input.\n\n"); goto _atagain2; } if (ag.m_iAtomGes != 1) { eprintf("\n Please enter only one atom at a time.\n\n"); goto _atagain2; } _atagain3: AskString(" Enter second atom of pair from %s (e.g. C3): [done] ",&buf,"",m->m_sName); if (buf.GetLength() == 0) break; ag2.Reset(); if (!ag2.ParseAtoms(m,(const char*)buf)) { eprintf("\n Invalid input.\n\n"); goto _atagain3; } if (ag2.m_iAtomGes != 1) { eprintf("\n Please enter only one atom at a time.\n\n"); goto _atagain3; } for (z2=0;z2<(int)tia.size();z2++) { sm = (CSingleMolecule*)g_oaSingleMolecules[m->m_laSingleMolIndex[tia[z2]]]; m_iaAtomList.push_back(((CxIntArray*)sm->m_oaAtomOffset[ag.m_baAtomType[0]])->GetAt(((CxIntArray*)ag.m_oaAtoms[0])->GetAt(0))); m_iaAtomList.push_back(((CxIntArray*)sm->m_oaAtomOffset[ag2.m_baAtomType[0]])->GetAt(((CxIntArray*)ag2.m_oaAtoms[0])->GetAt(0))); } } mprintf("\n Added %d pairs of atoms for molecule %s.\n",((int)m_iaAtomList.size()-ti)/2,m->m_sName); } else { _atagain: AskString(" Which atoms in %s to observe (e.g. C3)? [#2] ",&buf,"#2",m->m_sName); ag.Reset(); if (!ag.ParseAtoms(m,(const char*)buf)) { eprintf("\n Invalid input.\n\n"); goto _atagain; } for (z2=0;z2<(int)tia.size();z2++) { sm = (CSingleMolecule*)g_oaSingleMolecules[m->m_laSingleMolIndex[tia[z2]]]; for (z3=0;z3GetSize();z4++) m_iaAtomList.push_back(((CxIntArray*)sm->m_oaAtomOffset[ag.m_baAtomType[z3]])->GetAt(((CxIntArray*)ag.m_oaAtoms[z3])->GetAt(z4))); } } mprintf("\n Added %d atoms for molecule %s.\n",(int)m_iaAtomList.size()-ti,m->m_sName); } } } mprintf("\n"); mprintf(" You can choose to take into account only atoms within a certain maximum distance\n"); mprintf(" from the plane. For atom pairs, the center is used to compute the plane distance.\n\n"); m_fLayerWidth = AskFloat(" Enter maximum distance from plane for atoms to take into account (in pm): [infinite] ",0); mprintf("\n"); m_p2DF->m_fMinVal[0] = AskFloat(" Enter minimum value in X direction (in pm): [-1000.0] ",-1000.0); m_p2DF->m_fMaxVal[0] = AskFloat(" Enter maximum value in X direction (in pm): [ 1000.0] ",1000.0); m_p2DF->m_fMinVal[1] = AskFloat(" Enter minimum value in Y direction (in pm): [-1000.0] ",-1000.0); m_p2DF->m_fMaxVal[1] = AskFloat(" Enter maximum value in Y direction (in pm): [ 1000.0] ",1000.0); mprintf("\n"); m_p2DF->m_iRes[0] = AskUnsignedInteger(" Enter resolution in X direction: [100] ",100); m_p2DF->m_iRes[1] = AskUnsignedInteger(" Enter resolution in Y direction: [100] ",100); m_p2DF->Create(); m_p2DF->SetLabelX("Plane Vector 1 [pm]"); m_p2DF->SetLabelY("Plane Vector 2 [pm]"); m_p2DF->SetLabelZ("Occurrence"); m_sName.sprintf("fixplproj_obs%d",i+1); if (m_bDifference) m_sName.strcat("_diff"); else m_sName.strcat("_abs"); if (m_fLayerWidth > 0) { m_pPointPlaneDF = new CDF(); m_pPointPlaneDF->m_fMinVal = -MAX3(g_fBoxX,g_fBoxY,g_fBoxZ); m_pPointPlaneDF->m_fMaxVal = MAX3(g_fBoxX,g_fBoxY,g_fBoxZ); m_pPointPlaneDF->m_iResolution = 300; m_pPointPlaneDF->Create(); m_pPointPlaneDF->SetLabelX("Distance from plane [pm]"); m_pPointPlaneDF->SetLabelY("Occurrence"); } mprintf(WHITE,"\n <<< Observation %d <<<\n\n",i+1); return true; } bool CFixedPlProj::Parse() { CFixedPlProjObservation *obs; mprintf(WHITE,"\n>>> Fixed Plane Projection Function >>>\n\n"); mprintf(" The plane will be fixed in terms of simulation cell coordinates.\n"); mprintf(" The plane will be defined via a base point and two spanning vectors.\n\n"); do { obs = new CFixedPlProjObservation(); if (!obs->Parse((int)m_oaObservations.size())) return false; m_oaObservations.push_back(obs); } while (AskYesNo(" Add another observation (y/n)? [no] ",false)); mprintf("\n Added %lu observations.\n",m_oaObservations.size()); mprintf(WHITE,"\n<<< Fixed Plane Projection Function <<<\n\n"); return true; } void CFixedPlProj::Process(CTimeStep *ts) { int z, z2; double dist, ca, cb; CFixedPlProjObservation *obs; CxDVector3 avg, diff; CTimeStep t2; t2.CopyFrom(ts); t2.FoldMolecules(); for (z=0;z<(int)m_oaObservations.size();z++) { obs = m_oaObservations[z]; if (obs->m_bDifference) { for (z2=0;z2<(int)obs->m_iaAtomList.size()/2;z2++) { if (obs->m_fLayerWidth > 0) { avg = (t2.m_vaCoords[obs->m_iaAtomList[z2*2+1]] + t2.m_vaCoords[obs->m_iaAtomList[z2*2]]) / 2.0; dist = DotP(obs->m_vPlaneNormal,avg-obs->m_vPlaneBase); obs->m_pPointPlaneDF->AddToBin(dist); if (fabs(dist) > obs->m_fLayerWidth) continue; } diff = t2.m_vaCoords[obs->m_iaAtomList[z2*2+1]] - t2.m_vaCoords[obs->m_iaAtomList[z2*2]]; PointRootCoefficients(obs->m_vPlaneVec1,obs->m_vPlaneVec2,diff,ca,cb); obs->m_p2DF->AddToBin(ca,cb); } } else { for (z2=0;z2<(int)obs->m_iaAtomList.size();z2++) { if (obs->m_fLayerWidth > 0) { dist = DotP(obs->m_vPlaneNormal,t2.m_vaCoords[obs->m_iaAtomList[z2]]-obs->m_vPlaneBase); obs->m_pPointPlaneDF->AddToBin(dist); if (fabs(dist) > obs->m_fLayerWidth) continue; } PointRootCoefficients(obs->m_vPlaneVec1,obs->m_vPlaneVec2,t2.m_vaCoords[obs->m_iaAtomList[z2]],ca,cb); obs->m_p2DF->AddToBin(ca,cb); } } } } void CFixedPlProj::Finish() { int z; CFixedPlProjObservation *obs; mprintf(WHITE,"\n >>> Finishing Fixed Plane Projection Function >>>\n"); for (z=0;z<(int)m_oaObservations.size();z++) { obs = m_oaObservations[z]; mprintf(WHITE,"\n *** Observation %d ***\n",z+1); mprintf(" %.0f bin entries, %.0f out of bin range (%.2f percent).\n",obs->m_p2DF->m_fBinEntries,obs->m_p2DF->m_fSkipEntries,ZeroDivide(obs->m_p2DF->m_fSkipEntries,obs->m_p2DF->m_fBinEntries+obs->m_p2DF->m_fSkipEntries)*100.0); if (obs->m_p2DF->m_fBinEntries == 0) { eprintf(" There were no bin entries. Check your function definition. Skipping this observation.\n\n"); goto _skip; } obs->m_p2DF->CalcMaxEntry(); mprintf(" Raw data range from %.0f to %.0f hits.\n",obs->m_p2DF->m_fMinEntry,obs->m_p2DF->m_fMaxEntry); mprintf(" Max. bin entry: %.6E --> EPS: %.6E\n",obs->m_p2DF->m_fMaxEntry,obs->m_p2DF->m_fEps); if (obs->m_p2DF->m_fEps > 1.0E-4) { eprintf("\n Warning: Very large bin entries - probably loss of accuracy occured.\n"); mprintf(" Please reduce the bin counts (e.g. by analyzing only every 10th step).\n\n"); } mprintf(" Normalizing integral value to %.2f.\n",1000000.0); obs->m_p2DF->NormalizeBinIntegral(1000000.0); obs->m_p2DF->CalcMaxEntry(); mprintf(" Resulting data range from %.6f to %.6f.\n",obs->m_p2DF->m_fMinEntry,obs->m_p2DF->m_fMaxEntry); mprintf(" Saving Plane Projection DF triples as \"%s_triples.csv\"...\n",(const char*)obs->m_sName); obs->m_p2DF->Write((const char*)obs->m_sName,"","_triples.csv"); mprintf(" Saving Plane Projection DF matrix as \"%s_matrix.csv\"...\n",(const char*)obs->m_sName); obs->m_p2DF->WriteCSV((const char*)obs->m_sName,"","_matrix.csv"); mprintf(" Saving Plane Projection DF Mathematica Notebook as \"%s.nb\"...\n",(const char*)obs->m_sName); obs->m_p2DF->WriteMathematicaNb((const char*)obs->m_sName,"",".nb",false); mprintf(" Saving Plane Projection DF Gnuplot Input as \"%s.gp\"...\n",(const char*)obs->m_sName); obs->m_p2DF->WriteGnuplotInput((const char*)obs->m_sName,"","",false); if (obs->m_fLayerWidth > 0) { mprintf(" Saving plane distance distribution as \"%s_planedistance.csv\"...\n",(const char*)obs->m_sName); obs->m_pPointPlaneDF->Write((const char*)obs->m_sName,"","_planedistance.csv",true); } _skip:; } mprintf(WHITE,"\n <<< Finishing Fixed Plane Projection Function done <<<\n\n"); } travis-src-190101/src/fixplproj.h0100777000000000000000000000425713412725647013642 0ustar00/***************************************************************************** TRAVIS - Trajectory Analyzer and Visualizer http://www.travis-analyzer.de/ Copyright (c) 2009-2019 Martin Brehm 2012-2019 Martin Thomas 2016-2019 Sascha Gehrke This file was written by Martin Brehm. --------------------------------------------------------------------------- This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . *****************************************************************************/ #ifndef FIXPLPROJ_H #define FIXPLPROJ_H // This must always be the first include directive #include "config.h" #include "tools.h" #include "timestep.h" #include "2df.h" #include class CFixedPlProjObservation { public: CFixedPlProjObservation() : m_p2DF(NULL), m_pPointPlaneDF(NULL) { } ~CFixedPlProjObservation() { if (m_p2DF != NULL) { delete m_p2DF; m_p2DF = NULL; } if (m_pPointPlaneDF != NULL) { delete m_pPointPlaneDF; m_pPointPlaneDF = NULL; } } bool Parse(int i); bool m_bDifference; double m_fLayerWidth; std::vector m_iaAtomList; C2DF *m_p2DF; CDF *m_pPointPlaneDF; CxString m_sName; CxDVector3 m_vPlaneBase; CxDVector3 m_vPlaneVec1; CxDVector3 m_vPlaneVec2; CxDVector3 m_vPlaneNormal; }; class CFixedPlProj { public: ~CFixedPlProj() { int z; for (z=0;z<(int)m_oaObservations.size();z++) delete m_oaObservations[z]; m_oaObservations.clear(); } bool Parse(); void Process(CTimeStep *ts); void Finish(); std::vector m_oaObservations; }; #endif travis-src-190101/src/gather.cpp0100777000000000000000000065106213412725616013430 0ustar00/***************************************************************************** TRAVIS - Trajectory Analyzer and Visualizer http://www.travis-analyzer.de/ Copyright (c) 2009-2019 Martin Brehm 2012-2019 Martin Thomas 2016-2019 Sascha Gehrke This file was written by Martin Brehm and Martin Thomas. --------------------------------------------------------------------------- This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . *****************************************************************************/ // This must always be the first include directive #include "config.h" #include "travis.h" #include "tools.h" #include "database.h" #include "statistics.h" #include "maintools.h" #include "dacf.h" #include "interface.h" #include "plproj.h" #include "sdfmap.h" #include "domain.h" #include "conversion.h" #include "reactive.h" const char *GetRevisionInfo_gather(unsigned int len) { static char buf[256]; GET_REVISION_INFO( buf, len ); return buf; } const char *GetSourceVersion_gather() { static char buf[256]; GET_SOURCE_VERSION( buf ); return buf; } bool GatherInfos() { BTIN; // char buf[32768], buf2[32768]; CxString buf, buf2; double tf, tf2; FILE *a; bool tb=false, tb2, b, tbnew; int z, z0, z2, z3, z4, z5, z6, z7; int ti, ti2, ti3; int ty, rty, atom; int ty2, rty2, atom2; CVirtualAtom *va; CObservation *o; CMolecule *mol; CSingleMolecule *sm, *sm2; CAtomGroup *ag, *ag2; CxWordArray tempwa; CMolecule *m, *m2; CAtom *at; CElement *el; CxIntArray *pia, ia; CxDVector3 veca(0.0, 0.0, 0.0), vecb(0.0, 0.0, 0.0), vecc(0.0, 0.0, 0.0); g_bKeepUnfoldedCoords = false; g_iDoubleBoxFactor = 1; g_bBondACF = false; g_bCombined = false; g_bRefEnvFix = false; g_bTimeDiff = false; g_bRemoveCOM = false; g_bSaveCoordsUnchanged = false; g_bSDFUniform = false; a = NULL; ti2 = -1; //mprintf(YELLOW,"\n*** Interactive query of settings ***\n\n"); mprintf("\n"); // SAVEPOS; ti = 0; tbnew = false; if (g_bUnknownElements) { tb2 = false; _unkstart: tb = false; mprintf(WHITE," Unrecognized atom types: "); for (z=0;zm_pMergedTo != NULL) { // mprintf("%s merged to %s\n",at->m_sName,at->m_pMergedTo->m_sName); at = at->m_pMergedTo; } if (at->m_pElement->m_fRadius != 0) continue; if (tb) mprintf(", "); tb = true; mprintf("%s",(const char*)at->m_sName); ti++; ti2 = z; } mprintf("\n\n"); if ((ti == 1) && (mystricmp("X",((CAtom*)g_oaAtoms[ti2])->m_sName) == 0)) { // Only Wannier centers unrecognized. mprintf(" Possibly, atom type \"X\" represents Wannier centers. If so, do not assign data to them.\n\n"); tb2 = false; } else tb2 = true; tb = false; if (AskYesNo(" Do you want to assign atom data to them (y/n)? [%s] ",tb2,tb2?"yes":"no")) { if (tb2) { if (tbnew) goto _manu; if (AskYesNo(" Automatically rename all atoms to corresponding elements (recommended) (y/n)? [yes] ",true)) { tbnew = true; mprintf("\n"); tb2 = true; tb = false; for (z=0;zm_pElement->m_fRadius != 0) continue; buf2.SetBufSize(3); buf2(0) = at->m_sName[0]; buf2(1) = at->m_sName[1]; buf2(2) = 0; el = FindElement(buf2,true); if (el != NULL) { if (el->m_fRadius == 0) goto _unkX2; } else { _unkX2: buf2(1) = 0; el = FindElement(buf2,true); if (el != NULL) { if (el->m_fRadius == 0) goto _unkX3; } else { _unkX3: // strcpy(buf2,at->m_sName); buf2.strcpy(at->m_sName); } } if (el == NULL) { mprintf(" - Skipping %s... (have no guess for atom type)\n",(const char*)at->m_sName); tb = true; continue; } xAddAtom(buf2,false); mprintf(" - Renaming %s to %s...\n",(const char*)at->m_sName,(const char*)buf2); for (z2=0;z2m_pElement == el) { at = (CAtom*)g_oaAtoms[z2]; el = at->m_pElement; goto _unkX1; } } eprintf(" Internal error.\n"); abort(); _unkX1:; at->m_iCount--; // Remove one from xAddAtom for (z2=0;z2<(int)g_TimeStep.m_iGesAtomCount;z2++) { // strcpy(buf,(char*)g_TimeStep.m_paLabels[z2]); buf.strcpy((char*)g_TimeStep.m_paLabels[z2]); ReplaceDigits(&buf); if (mystricmp(buf,((CAtom*)g_oaAtoms[z])->m_sName) == 0) { at->m_iCount++; ((CAtom*)g_oaAtoms[z])->m_iCount--; } } // mprintf("\nmerging %s to %s.\n",((CAtom*)g_oaAtoms[z])->m_sName,at->m_sName); ((CAtom*)g_oaAtoms[z])->m_pMergedTo = at; } if (tb) { mprintf("\n"); goto _unkstart; } tb = false; goto _unkdone; } } _manu: ti = g_oaAtoms.GetSize(); for (z=0;zm_pMergedTo != NULL) { // mprintf("%s merged to %s\n",at->m_sName,at->m_pMergedTo->m_sName); at = at->m_pMergedTo; } if (at->m_pElement->m_fRadius != 0) continue; mprintf(WHITE,"\n * Element %s\n\n",(const char*)at->m_sName); buf2.SetBufSize(3); buf2(0) = at->m_sName[0]; buf2(1) = at->m_sName[1]; buf2(2) = 0; el = FindElement(buf2,true); if (el != NULL) { if (el->m_fRadius == 0) goto _unk2; } else { _unk2: buf2(1) = 0; el = FindElement(buf2,true); if (el != NULL) { if (el->m_fRadius == 0) goto _unk3; } else { _unk3: // strcpy(buf2,at->m_sName); buf2.strcpy(at->m_sName); } } if (AskYesNo(" Do you want to rename this element (y/n)? [yes] ",true)) { _unk5: AskString(" Enter new name for \"%s\": [%s] ",&buf,(const char*)buf2,(const char*)at->m_sName,(const char*)buf2); // if (strlen(buf) > 7) // { // eprintf("Atom labels may have maximum length of 7 characters.\n"); // goto _unk5; // } if (ContainsDigitOrSpecial(buf)) { eprintf("Digits or special characters in element labels not allowed.\n"); goto _unk5; } el = FindElement(buf,true); if (el != NULL) { xAddAtom(buf,false); if (AskYesNo(" Element %s is known. Merge %s atoms into %s (y/n)? [yes] ",true,(const char*)buf,(const char*)at->m_sName,(const char*)buf)) { for (z2=0;z2m_pElement == el) { at = (CAtom*)g_oaAtoms[z2]; el = at->m_pElement; goto _unk1; } } eprintf(" Internal error.\n"); abort(); _unk1:; } } else { mprintf(" Adding element %s...",(const char*)buf); try { at = new CAtom(); } catch(...) { at = NULL; } if (at == NULL) NewException((double)sizeof(CAtom),__FILE__,__LINE__,__PRETTY_FUNCTION__); at->m_iIndex = g_oaAtoms.GetSize(); g_oaAtoms.Add(at); try { at->m_pElement = new CElement(); } catch(...) { at->m_pElement = NULL; } if (at->m_pElement == NULL) NewException((double)sizeof(CElement),__FILE__,__LINE__,__PRETTY_FUNCTION__); el = at->m_pElement; // sprintf(at->m_sName,"%s",(const char*)buf); at->m_sName = (const char*)buf; } for (z2=0;z2<(int)g_TimeStep.m_iGesAtomCount;z2++) { // strcpy(buf,(char*)g_TimeStep.m_paLabels[z2]); buf.strcpy((char*)g_TimeStep.m_paLabels[z2]); ReplaceDigits(&buf); if (mystricmp(buf,((CAtom*)g_oaAtoms[z])->m_sName) == 0) { at->m_iCount++; ((CAtom*)g_oaAtoms[z])->m_iCount--; } } ((CAtom*)g_oaAtoms[z])->m_pMergedTo = at; if (el->m_fRadius != 0) continue; } // END IF RENAME if (AskYesNo(" Do you want to copy the atom parameters from another element (y/n)? [yes] ",true)) { _unk4: AskString(" Copy atom parameters from which element? [%s] ",&buf,buf2,(const char*)buf2); el = FindElement(buf,true); if (el == NULL) { eprintf("This element is not defined.\n"); goto _unk4; } if (el->m_fRadius == 0) { if (!AskYesNo(" This element has a radius of 0 (will form no bonds). Use it anyway (y/n)? [yes] ",true)) goto _unk4; } mprintf(WHITE,"\n A covalent radius of 0 pm hinders atoms of this kind from forming any bonds.\n\n"); at->m_pElement->m_fRadius = AskFloat(" Please enter covalent radius in pm: [%.2f] ",el->m_fRadius,el->m_fRadius); at->m_pElement->m_fMass = AskFloat(" Please enter atom mass in u: [%.2f] ",el->m_fMass,el->m_fMass); if (!tb && (fabs(at->m_pElement->m_fMass-el->m_fMass) < 0.01)) { tb = true; mprintf(RED,"\n Warning: "); mprintf("Elements %s and %s keep their different labels, but will have\n",(const char*)at->m_sName,(const char*)buf); mprintf(" the same mass and therefore also the same atom codes. They will not\n"); mprintf(" be distinguished in the molecule recognition!\n"); } // mprintf(" Using mass=%.2fu, radius=%.2fpm, ord. number=%d.\n",at->m_pElement->m_fMass,el->m_fRadius,el->m_iOrd); // at->m_pElement->CopyData(el); } else { el = FindElement(buf2,true); mprintf(WHITE,"\n A covalent radius of 0 pm hinders atoms of this kind from forming any bonds.\n\n"); if (el != NULL) { mprintf(" (default values are for %s)\n\n",(const char*)buf2); at->m_pElement->m_fRadius = AskFloat(" Please enter covalent radius in pm: [%.2f] ",el->m_fRadius,el->m_fRadius); at->m_pElement->m_fMass = AskFloat(" Please enter atom mass in u: [%.2f] ",el->m_fMass,el->m_fMass); } else { at->m_pElement->m_fRadius = AskFloat(" Please enter covalent radius in pm: [100] ",100); at->m_pElement->m_fMass = AskFloat_ND(" Please enter atom mass in u: "); } } } _unkdone: mprintf("\n"); mprintf(WHITE," %d atoms in the system: ",g_iGesAtomCount); b = false; for (z=0;zm_pMergedTo != NULL) continue; if (b) mprintf(", "); b = true; mprintf("%dx %s",((CAtom*)g_oaAtoms[z])->m_iCount,(const char*)((CAtom*)g_oaAtoms[z])->m_sName); //if (((CAtom*)g_oaAtoms[z])->m_pMergedTo != NULL) // mprintf(" (merged to %s)",(const char*)((CAtom*)g_oaAtoms[z])->m_pMergedTo->m_sName); } mprintf("\n"); } else { // END IF CHANGE UNKNOWN tb = false; for (z=0;zm_pElement->m_fRadius != 0) continue; if (at->m_pMergedTo != NULL) continue; if (!tb) { tb = true; mprintf("\n"); } if (AskYesNo(" Do you want to hide atom type \"%s\" (y/n)? [yes] ",true,(const char*)((CAtom*)g_oaAtoms[z])->m_sName)) ((CAtom*)g_oaAtoms[z])->m_bExclude = true; } } mprintf("\n"); } // END IF UNKNOWN b = false; tb = false; if (g_bUnknownElements) { for (z=0;zm_pMergedTo != NULL) continue; if (((CAtom*)g_oaAtoms[z])->m_bExclude) continue; if (strlen(((CAtom*)g_oaAtoms[z])->m_sName) < 2) continue; buf.sprintf("%c",((CAtom*)g_oaAtoms[z])->m_sName[0]); for (z2=0;z2m_sLabel) == 0) goto _ef; } continue; _ef: if (!tb) { tb = true; mprintf(" It frequently happens that force field molecular dynamics software uses atom labels\n"); mprintf(" such as \"CR\" for carbon, which is then erroneously considered as chromium by TRAVIS.\n\n"); } if (!AskYesNo(" Does your system really contain the chemical element \"%s\" (y), or are these \"%s\" atoms (n)? [no] ",false,(const char*)((CAtom*)g_oaAtoms[z])->m_sName,(const char*)buf)) { b = true; mprintf("\n Renaming %d \"%s\" atoms to \"%s\"...\n\n",((CAtom*)g_oaAtoms[z])->m_iCount,(const char*)((CAtom*)g_oaAtoms[z])->m_sName,(const char*)buf); xAddAtom(buf,false); for (z2=0;z2m_pElement == el) { at = (CAtom*)g_oaAtoms[z2]; el = at->m_pElement; goto _unkX1F; } } eprintf(" Internal error.\n"); abort(); _unkX1F: at->m_iCount--; // Remove one from xAddAtom for (z2=0;z2<(int)g_TimeStep.m_iGesAtomCount;z2++) { buf.strcpy((char*)g_TimeStep.m_paLabels[z2]); ReplaceDigits(&buf); if (mystricmp(buf,((CAtom*)g_oaAtoms[z])->m_sName) == 0) { at->m_iCount++; ((CAtom*)g_oaAtoms[z])->m_iCount--; } } ((CAtom*)g_oaAtoms[z])->m_pMergedTo = at; } } if (b) { mprintf(WHITE," %d atoms in the system: ",g_iGesAtomCount); b = false; for (z=0;zm_pMergedTo != NULL) continue; if (((CAtom*)g_oaAtoms[z])->m_bExclude) continue; if (b) mprintf(", "); b = true; mprintf("%dx %s",((CAtom*)g_oaAtoms[z])->m_iCount,(const char*)((CAtom*)g_oaAtoms[z])->m_sName); //if (((CAtom*)g_oaAtoms[z])->m_pMergedTo != NULL) // mprintf(" (merged to %s)",(const char*)((CAtom*)g_oaAtoms[z])->m_pMergedTo->m_sName); } mprintf("\n\n"); } } ia.RemoveAll(); tb2 = false; for (z=0;zm_pMergedTo != NULL) continue; if (((CAtom*)g_oaAtoms[z])->m_bExclude) continue; if (z == g_iVirtAtomType) continue; for (z2=z+1;z2m_pMergedTo != NULL) continue; if (((CAtom*)g_oaAtoms[z2])->m_bExclude) continue; if (z2 == g_iVirtAtomType) continue; if (fabs(((CAtom*)g_oaAtoms[z])->m_pElement->m_fMass - ((CAtom*)g_oaAtoms[z2])->m_pElement->m_fMass) < 0.01) { if (!tb) { tb = true; tb2 = true; mprintf(RED,"\n Warning: "); mprintf("The following atoms have the same mass and will therefore not be\n"); mprintf(" distinguished in the molecule recognition:\n\n"); mprintf(WHITE," Mass=%.2f: %s, %s",((CAtom*)g_oaAtoms[z])->m_pElement->m_fMass,(const char*)((CAtom*)g_oaAtoms[z])->m_sName,(const char*)((CAtom*)g_oaAtoms[z2])->m_sName); ia.Add(z); ia.Add(z2); } else { mprintf(WHITE,", %s",(const char*)((CAtom*)g_oaAtoms[z2])->m_sName); } } } if (tb) mprintf("\n"); _next:; } if (tb2) mprintf("\n"); if (((g_iTrajFormat == 5) || (g_iTrajFormat == 7)) && (g_TimeStep.m_pVolumetricData != NULL)) { mprintf(" First frame from volumetric data trajectory contains these cell vectors:\n"); mprintf(" A = ( %10.4f | %10.4f | %10.4f ) pm\n",g_fCubeXVector[0]*g_iCubeRes[0]*LEN_AU2PM,g_fCubeXVector[1]*g_iCubeRes[0]*LEN_AU2PM,g_fCubeXVector[2]*g_iCubeRes[0]*LEN_AU2PM); mprintf(" B = ( %10.4f | %10.4f | %10.4f ) pm\n",g_fCubeYVector[0]*g_iCubeRes[1]*LEN_AU2PM,g_fCubeYVector[1]*g_iCubeRes[1]*LEN_AU2PM,g_fCubeYVector[2]*g_iCubeRes[1]*LEN_AU2PM); mprintf(" C = ( %10.4f | %10.4f | %10.4f ) pm\n",g_fCubeZVector[0]*g_iCubeRes[2]*LEN_AU2PM,g_fCubeZVector[1]*g_iCubeRes[2]*LEN_AU2PM,g_fCubeZVector[2]*g_iCubeRes[2]*LEN_AU2PM); mprintf("\n"); tb = false; if (g_fCubeXVector[0] < 0) { if (!tb) { tb = true; mprintf(" Some diagonal elements of the cell matrix have negative values.\n"); mprintf(" This is quite uncommon and can cause problems, e.g. in Voronoi integration.\n"); mprintf(" TRAVIS offers to mirror the cell such that the diagonal becomes positive.\n\n"); } g_bFlipCellVectorX = AskYesNo(" Mirror at Y-Z plane such that AX becomes positive (y/n)? [yes] ",true); } if (g_fCubeYVector[1] < 0) { if (!tb) { tb = true; mprintf(" Some diagonal elements of the cell matrix have negative values.\n"); mprintf(" This is quite uncommon and can cause problems, e.g. in Voronoi integration.\n"); mprintf(" TRAVIS offers to flip the corresponding vectors such that the diagonal becomes positive.\n\n"); } g_bFlipCellVectorY = AskYesNo(" Mirror at X-Z plane such that BY becomes positive (y/n)? [yes] ",true); } if (g_fCubeZVector[2] < 0) { if (!tb) { tb = true; mprintf(" Some diagonal elements of the cell matrix have negative values.\n"); mprintf(" This is quite uncommon and might cause problems, e.g. in Voronoi integration.\n"); mprintf(" TRAVIS offers to flip the corresponding vectors (i.e. multiply them with -1)\n"); mprintf(" such that the diagonal becomes positive.\n\n"); } g_bFlipCellVectorZ = AskYesNo(" Mirror at X-Y plane such that CZ becomes positive (y/n)? [yes] ",true); } if (tb) { mprintf("\n"); mprintf(" Flipping vectors...\n\n"); if (g_bFlipCellVectorX) { if (g_fCubeXVector[0] != 0) g_fCubeXVector[0] *= -1.0; if (g_fCubeYVector[0] != 0) g_fCubeYVector[0] *= -1.0; if (g_fCubeZVector[0] != 0) g_fCubeZVector[0] *= -1.0; if (g_mCubeCell(0,0) != 0) g_mCubeCell(0,0) *= -1.0; if (g_mCubeCell(1,0) != 0) g_mCubeCell(1,0) *= -1.0; if (g_mCubeCell(2,0) != 0) g_mCubeCell(2,0) *= -1.0; } if (g_bFlipCellVectorY) { if (g_fCubeXVector[1] != 0) g_fCubeXVector[1] *= -1.0; if (g_fCubeYVector[1] != 0) g_fCubeYVector[1] *= -1.0; if (g_fCubeZVector[1] != 0) g_fCubeZVector[1] *= -1.0; if (g_mCubeCell(0,1) != 0) g_mCubeCell(0,1) *= -1.0; if (g_mCubeCell(1,1) != 0) g_mCubeCell(1,1) *= -1.0; if (g_mCubeCell(2,1) != 0) g_mCubeCell(2,1) *= -1.0; } if (g_bFlipCellVectorZ) { if (g_fCubeXVector[2] != 0) g_fCubeXVector[2] *= -1.0; if (g_fCubeYVector[2] != 0) g_fCubeYVector[2] *= -1.0; if (g_fCubeZVector[2] != 0) g_fCubeZVector[2] *= -1.0; if (g_mCubeCell(0,2) != 0) g_mCubeCell(0,2) *= -1.0; if (g_mCubeCell(1,2) != 0) g_mCubeCell(1,2) *= -1.0; if (g_mCubeCell(2,2) != 0) g_mCubeCell(2,2) *= -1.0; } mprintf(" First frame from volumetric data trajectory contains these cell vectors:\n"); mprintf(" A = ( %10.4f | %10.4f | %10.4f ) pm\n",g_fCubeXVector[0]*g_iCubeRes[0]*LEN_AU2PM,g_fCubeXVector[1]*g_iCubeRes[0]*LEN_AU2PM,g_fCubeXVector[2]*g_iCubeRes[0]*LEN_AU2PM); mprintf(" B = ( %10.4f | %10.4f | %10.4f ) pm\n",g_fCubeYVector[0]*g_iCubeRes[1]*LEN_AU2PM,g_fCubeYVector[1]*g_iCubeRes[1]*LEN_AU2PM,g_fCubeYVector[2]*g_iCubeRes[1]*LEN_AU2PM); mprintf(" C = ( %10.4f | %10.4f | %10.4f ) pm\n",g_fCubeZVector[0]*g_iCubeRes[2]*LEN_AU2PM,g_fCubeZVector[1]*g_iCubeRes[2]*LEN_AU2PM,g_fCubeZVector[2]*g_iCubeRes[2]*LEN_AU2PM); mprintf("\n"); /* mprintf(" A = ( %.10e | %.10e | %.10e ) pm\n",g_fCubeXVector[0]*g_iCubeRes[0]*LEN_AU2PM,g_fCubeXVector[1]*g_iCubeRes[0]*LEN_AU2PM,g_fCubeXVector[2]*g_iCubeRes[0]*LEN_AU2PM); mprintf(" B = ( %.10e | %.10e | %.10e ) pm\n",g_fCubeYVector[0]*g_iCubeRes[1]*LEN_AU2PM,g_fCubeYVector[1]*g_iCubeRes[1]*LEN_AU2PM,g_fCubeYVector[2]*g_iCubeRes[1]*LEN_AU2PM); mprintf(" C = ( %.10e | %.10e | %.10e ) pm\n",g_fCubeZVector[0]*g_iCubeRes[2]*LEN_AU2PM,g_fCubeZVector[1]*g_iCubeRes[2]*LEN_AU2PM,g_fCubeZVector[2]*g_iCubeRes[2]*LEN_AU2PM); mprintf("\n"); */ } } /* mprintf(" The advanced mode includes many additional options which are quite powerful, yet possibly\n"); mprintf(" weird or seldomly required. This includes support for non-orthorhombic simulation cells,\n"); mprintf(" NPT ensemble, non-periodic systems, user-definded virtual atoms, pseudomolecules, ...\n\n");*/ mprintf(" The \"advanced mode\" offers seldomly required features, including support for non-orthorhombic\n"); mprintf(" simulation cells, NPT ensemble, non-periodic systems, user-definded virtual atoms, pseudomolecules, ...\n\n"); g_bAdvanced1 = AskYesNo(" Use the advanced mode until the analysis selection menu (y/n)? [no] ",false); mprintf("\n"); if ((g_iTrajFormat == 5) || (g_iTrajFormat == 7)) { if (!g_bAdvanced1 && ((g_fCubeXVector[1] != 0) || (g_fCubeXVector[2] != 0) || (g_fCubeYVector[0] != 0) || (g_fCubeYVector[2] != 0) || (g_fCubeZVector[0] != 0) || (g_fCubeZVector[1] != 0))) { mprintf(WHITE," Warning:"); mprintf(" Cell seems to be non-orthorhombic. Activating advanced mode.\n\n"); g_bAdvanced1 = true; } } if (g_bXYZComment6Numbers) { mprintf(" TRAVIS can read cell vectors / angles from the comment line of the XYZ file.\n"); mprintf(" The format needs to be \"a b c alpha beta gamma\" (space separated). Lengths in Angstrom, angles in degree.\n\n"); mprintf(" The current comment line is \"%s\".\n\n",g_TimeStep.m_pComment); if (AskYesNo(" Are the six numbers in the trajectory's comment line cell geometry data in this format (y/n)? [yes] ",true)) { g_bFoundNonOrtho = true; mprintf("\n Extracting cell geometry...\n"); ExtractXYZCellGeometry(g_TimeStep.m_pComment); mprintf("\n"); } else g_bXYZComment6Numbers = false; } if (g_bXYZComment3Numbers) { mprintf(" TRAVIS can read orthorhombic cell edge lengths from the comment line of the XYZ file.\n"); mprintf(" The format needs to be \"x y z\" (space separated). Lengths in Angstrom.\n\n"); mprintf(" The current comment line is \"%s\".\n\n",g_TimeStep.m_pComment); if (AskYesNo(" Are the three numbers in the trajectory's comment line cell geometry data in this format (y/n)? [yes] ",true)) { mprintf("\n Extracting cell geometry...\n"); ExtractXYZCellGeometry3(g_TimeStep.m_pComment); mprintf("\n"); } else g_bXYZComment3Numbers = false; } if ((g_fBoxX != 0) || g_bFoundNonOrtho) { mprintf(" Found cell geometry data in trajectory file:\n\n"); if (g_bFoundNonOrtho) { DumpNonOrthoCellData(); } else { mprintf(" X = %.2f pm, Y = %.2f pm, Z = %.2f pm\n\n",g_fBoxX,g_fBoxY,g_fBoxZ); tf = GuessBoxSize(); mprintf(" The overall box density is %.6f g/cm^3.\n\n",tf*tf*tf/g_fBoxX/g_fBoxY/g_fBoxZ); } mprintf(" Assuming a 3D-periodic cell.\n\n"); if (AskYesNo(" Use these values (y) or enter different values (n)? [yes] ",true)) { if (g_bFoundNonOrtho) g_bBoxNonOrtho = true; else g_bBoxNonOrtho = false; if (!g_bBoxNonOrtho) { g_mBoxFromOrtho(0,0) = g_fBoxX; g_mBoxFromOrtho(0,1) = 0; g_mBoxFromOrtho(0,2) = 0; g_mBoxFromOrtho(1,0) = 0; g_mBoxFromOrtho(1,1) = g_fBoxY; g_mBoxFromOrtho(1,2) = 0; g_mBoxFromOrtho(2,0) = 0; g_mBoxFromOrtho(2,1) = 0; g_mBoxFromOrtho(2,2) = g_fBoxZ; g_fBoxAngleA = 90.0; g_fBoxAngleB = 90.0; g_fBoxAngleC = 90.0; } g_bPeriodic = true; g_bPeriodicX = true; g_bPeriodicY = true; g_bPeriodicZ = true; if (AskYesNo(" Update cell geometry in every time step (i.e., NPT ensemble) (y) or use fixed cell (n)? [yes] ",true)) g_bNPT = true; else g_bNPT = false; goto _celldefined; } else g_bXYZComment6Numbers = false; } if (g_bAdvanced1) { do { mprintf(" Use periodic boundary conditions (0=no, x, y, z, xy, xz, xyz)? [xyz] "); inpprintf("! Use periodic boundary conditions (0=no, x, y, z, xy, xz, xyz)? [xyz]\n"); myget(&buf); } while (!ParsePeriodic(buf)); // if (!g_bPeriodic) // { /* if (AskYesNo(" Enter Box Size anyways (e.g. fo RDFs) (yes/no)? [yes] ",true)) { goto _askbox; } else { g_fBoxX = GuessBoxSize(); g_fBoxY = GuessBoxSize(); g_fBoxZ = GuessBoxSize(); mprintf("\nGuessed box size (for density 1.0 g/cm^3) is %.2f x %.2f x %.2f pm.\n\n",g_fBoxX,g_fBoxX,g_fBoxX); }*/ // g_fBoxX = (g_TimeStep.m_vMax[0]-g_TimeStep.m_vMin[0])*10.0; // g_fBoxY = (g_TimeStep.m_vMax[1]-g_TimeStep.m_vMin[1])*10.0; // g_fBoxZ = (g_TimeStep.m_vMax[2]-g_TimeStep.m_vMin[2])*10.0; // mprintf("\n Using cell vector of %.2f x %.2f x %.2f pm to \"fake\" non-periodic box.\n\n",g_fBoxX,g_fBoxY,g_fBoxZ); // } } else ParsePeriodic("xyz"); if (g_bPeriodic) { tf = GuessBoxSize(); mprintf(" A cell vector of %.2f pm would result in a density of 1.0 g/cm^3.\n\n",tf); if (g_bAdvanced1) { g_bNPT = AskYesNo(" Use time-dependent cell vector (NPT ensemble) (y/n)? [no] ",false); mprintf("\n"); } else g_bNPT = false; if (g_bAdvanced1) { if ((g_fCubeXVector[1] != 0) || (g_fCubeXVector[2] != 0) || (g_fCubeYVector[0] != 0) || (g_fCubeYVector[2] != 0) || (g_fCubeZVector[0] != 0) || (g_fCubeZVector[1] != 0)) g_bBoxNonOrtho = AskYesNo(" Is the simulation cell non-orthorhombic (cell angles other than 90 deg) (y/n)? [yes] ",true); else g_bBoxNonOrtho = AskYesNo(" Is the simulation cell non-orthorhombic (cell angles other than 90 deg) (y/n)? [no] ",false); mprintf("\n"); } else g_bBoxNonOrtho = false; if (g_bNPT) { if (g_fBoxX != 0) { mprintf(" Your PDB file contains cell vector information.\n\n"); } else { mprintf(" The trajectory does not contain cell vector information.\n"); mprintf(" (supported: PDB file with \"CRYST1\" section, like written by GROMACS trjconv)\n"); mprintf(" You have to supply a plain text file which contains the cell vectors for each step.\n"); mprintf(" It should contain three space-separated real numbers (X, Y, Z vector) per line.\n"); mprintf(" These numbers need to be IN ANGSTROM! (1 angstrom = 100 pm)\n\n"); _nptfileagain: AskString_ND(" Please enter cell vector text file name: ",&g_sNPTFile); if (!FileExist(g_sNPTFile)) { eprintf("Could not open file \"%s\" for reading.\n",(const char*)g_sNPTFile); goto _nptfileagain; } g_fNPTFile = fopen(g_sNPTFile,"rt"); g_TimeStep.ReadCellVector(g_fNPTFile); fclose(g_fNPTFile); mprintf("\n"); } mprintf(" The initial cell vector is ( %.2f pm | %.2f pm | %.2f pm ).\n",g_fBoxX,g_fBoxY,g_fBoxZ); mprintf(" The initial box density is %.6f g/cm^3.\n\n",tf*tf*tf/g_fBoxX/g_fBoxY/g_fBoxZ); } else if (!g_bBoxNonOrtho) { if (g_fBoxX != 0) { mprintf(" Cell vector found in trajectory file:\n"); mprintf(" X = %.2f pm, Y = %.2f pm, Z = %.2f pm\n\n",g_fBoxX,g_fBoxY,g_fBoxZ); if (AskYesNo(" Use these values (y/n)? [yes] ",true)) goto _celldone; } _askbox: if (!AskYesNo(" Are the 3 cell vectors of the same size (yes/no)? [yes] ",true)) { if (g_bPeriodicX) g_fBoxX = AskFloat_ND(" Enter length of X cell vector in pm: "); if (g_bPeriodicY) g_fBoxY = AskFloat_ND(" Enter length of Y cell vector in pm: "); if (g_bPeriodicZ) g_fBoxZ = AskFloat_ND(" Enter length of Z cell vector in pm: "); } else { g_fBoxX = AskFloat_ND(" Enter length of cell vector in pm: "); g_fBoxY = g_fBoxX; g_fBoxZ = g_fBoxX; } if ((g_fBoxX <= 0) || (g_fBoxY <= 0) || (g_fBoxZ <= 0)) { eprintf("Cell vector of length <= 0 is not allowed.\n"); goto _askbox; } _celldone: g_mBoxFromOrtho(0,0) = g_fBoxX; g_mBoxFromOrtho(0,1) = 0; g_mBoxFromOrtho(0,2) = 0; g_mBoxFromOrtho(1,0) = 0; g_mBoxFromOrtho(1,1) = g_fBoxY; g_mBoxFromOrtho(1,2) = 0; g_mBoxFromOrtho(2,0) = 0; g_mBoxFromOrtho(2,1) = 0; g_mBoxFromOrtho(2,2) = g_fBoxZ; g_fBoxAngleA = 90.0; g_fBoxAngleB = 90.0; g_fBoxAngleC = 90.0; g_mBoxToOrtho = CxDMatrix3(g_mBoxFromOrtho); if (!g_mBoxToOrtho.Invert()) { eprintf("Error: Encountered singular cell matrix (cell volume is zero).\n"); abort(); } if (g_bPeriodicX && g_bPeriodicY && g_bPeriodicZ) { mprintf("\n The box size is %.2f x %.2f x %.2f pm.\n",g_fBoxX,g_fBoxY,g_fBoxZ); mprintf(" The overall box density is %.6f g/cm^3.\n",tf*tf*tf/g_fBoxX/g_fBoxY/g_fBoxZ); if (tf*tf*tf/g_fBoxX/g_fBoxY/g_fBoxZ > 15.0) { mprintf("\n"); if (!AskYesNo(" The density of your box seems to be very high. Continue (y) or change input (n)? [n] ",false)) { mprintf("\n"); goto _askbox; } mprintf("\n"); } } } else // Non-orthorhombic cell definition { if (AskYesNo(" Enter three cell vectors (y) or three edge lengths and angles (n)? [%s] ",((g_iTrajFormat == 5) || (g_iTrajFormat == 7)),((g_iTrajFormat == 5) || (g_iTrajFormat == 7))?"yes":"no")) { mprintf("\n"); _cellagain: g_mBoxFromOrtho(0,0) = AskFloat_ND(" Enter X component of cell vector A in pm: "); if (g_bFlipCellVectorX && (g_mBoxFromOrtho(0,0) < 0)) { eprintf("You decided to mirror at the Y-Z plane. Please enter the X components with inverse signs.\n\n"); goto _cellagain; } g_mBoxFromOrtho(0,1) = AskFloat_ND(" Enter Y component of cell vector A in pm: "); g_mBoxFromOrtho(0,2) = AskFloat_ND(" Enter Z component of cell vector A in pm: "); mprintf("\n"); g_mBoxFromOrtho(1,0) = AskFloat_ND(" Enter X component of cell vector B in pm: "); g_mBoxFromOrtho(1,1) = AskFloat_ND(" Enter Y component of cell vector B in pm: "); if (g_bFlipCellVectorY && (g_mBoxFromOrtho(1,1) < 0)) { eprintf("You decided to mirror at the X-Z plane. Please enter the Y components with inverse signs.\n\n"); goto _cellagain; } g_mBoxFromOrtho(1,2) = AskFloat_ND(" Enter Z component of cell vector B in pm: "); mprintf("\n"); g_mBoxFromOrtho(2,0) = AskFloat_ND(" Enter X component of cell vector C in pm: "); g_mBoxFromOrtho(2,1) = AskFloat_ND(" Enter Y component of cell vector C in pm: "); g_mBoxFromOrtho(2,2) = AskFloat_ND(" Enter Z component of cell vector C in pm: "); if (g_bFlipCellVectorZ && (g_mBoxFromOrtho(2,2) < 0)) { eprintf("You decided to mirror at the X-Y plane. Please enter the Z components with inverse signs.\n\n"); goto _cellagain; } veca = CxDVector3(g_mBoxFromOrtho(0,0),g_mBoxFromOrtho(0,1),g_mBoxFromOrtho(0,2)); vecb = CxDVector3(g_mBoxFromOrtho(1,0),g_mBoxFromOrtho(1,1),g_mBoxFromOrtho(1,2)); vecc = CxDVector3(g_mBoxFromOrtho(2,0),g_mBoxFromOrtho(2,1),g_mBoxFromOrtho(2,2)); g_fBoxAngleA = acos(DotP(vecb,vecc) / vecb.GetLength() / vecc.GetLength()) * 180.0 / Pi; g_fBoxAngleB = acos(DotP(veca,vecc) / veca.GetLength() / vecc.GetLength()) * 180.0 / Pi; g_fBoxAngleC = acos(DotP(veca,vecb) / veca.GetLength() / vecb.GetLength()) * 180.0 / Pi; } else { mprintf("\n Convention: \"Vector A\" is located on the X axis, \"vector B\" in the XY plane.\n\n"); g_fBoxX = AskFloat_ND(" Enter length of cell vector A in pm: "); g_fBoxY = AskFloat_ND(" Enter length of cell vector B in pm: "); g_fBoxZ = AskFloat_ND(" Enter length of cell vector C in pm: "); mprintf("\n"); g_fBoxAngleA = AskFloat(" Enter angle Alpha (between B and C) in deg: [90.0] ",90.0); g_fBoxAngleB = AskFloat(" Enter angle Beta (between A and C) in deg: [90.0] ",90.0); g_fBoxAngleC = AskFloat(" Enter angle Gamma (between A and B) in deg: [90.0] ",90.0); mprintf("\n"); mprintf(" Computing vectors...\n"); g_mBoxFromOrtho(0,0) = g_fBoxX; g_mBoxFromOrtho(0,1) = 0; g_mBoxFromOrtho(0,2) = 0; g_mBoxFromOrtho(1,0) = g_fBoxY*cos(g_fBoxAngleC*Pi/180.0); g_mBoxFromOrtho(1,1) = g_fBoxY*sin(g_fBoxAngleC*Pi/180.0); g_mBoxFromOrtho(1,2) = 0; g_mBoxFromOrtho(2,0) = g_fBoxZ*cos(g_fBoxAngleB*Pi/180.0); g_mBoxFromOrtho(2,1) = (-(g_mBoxFromOrtho(1,0)*g_fBoxZ*cos(g_fBoxAngleB*Pi/180.0)) + g_fBoxY*g_fBoxZ*cos(g_fBoxAngleA*Pi/180.0))/g_mBoxFromOrtho(1,1); g_mBoxFromOrtho(2,2) = sqrt(-((pow2(g_fBoxZ)*(pow2(g_mBoxFromOrtho(1,1))*(-1 + pow2(cos(g_fBoxAngleB*Pi/180.0))) + pow2(g_mBoxFromOrtho(1,0)*cos(g_fBoxAngleB*Pi/180.0) - g_fBoxY*cos(g_fBoxAngleA*Pi/180.0))))/pow2(g_mBoxFromOrtho(1,1)))); mprintf(" Recalculating angles from vectors...\n"); veca = CxDVector3(g_mBoxFromOrtho(0,0),g_mBoxFromOrtho(0,1),g_mBoxFromOrtho(0,2)); vecb = CxDVector3(g_mBoxFromOrtho(1,0),g_mBoxFromOrtho(1,1),g_mBoxFromOrtho(1,2)); vecc = CxDVector3(g_mBoxFromOrtho(2,0),g_mBoxFromOrtho(2,1),g_mBoxFromOrtho(2,2)); g_fBoxAngleA = acos(DotP(vecb,vecc) / vecb.GetLength() / vecc.GetLength()) * 180.0 / Pi; g_fBoxAngleB = acos(DotP(veca,vecc) / veca.GetLength() / vecc.GetLength()) * 180.0 / Pi; g_fBoxAngleC = acos(DotP(veca,vecb) / veca.GetLength() / vecb.GetLength()) * 180.0 / Pi; } mprintf(" Computing inverse of transformation matrix...\n\n"); g_mBoxToOrtho = CxDMatrix3(g_mBoxFromOrtho); if (!g_mBoxToOrtho.Invert()) { eprintf("Error: Encountered singular cell matrix (cell volume is zero).\n"); abort(); } // Orthogonal bounding box g_fBoxX = fabs(g_mBoxFromOrtho(0,0)) + fabs(g_mBoxFromOrtho(1,0)) + fabs(g_mBoxFromOrtho(2,0)); g_fBoxY = fabs(g_mBoxFromOrtho(0,1)) + fabs(g_mBoxFromOrtho(1,1)) + fabs(g_mBoxFromOrtho(2,1)); g_fBoxZ = fabs(g_mBoxFromOrtho(0,2)) + fabs(g_mBoxFromOrtho(1,2)) + fabs(g_mBoxFromOrtho(2,2)); veca = CxDVector3(g_mBoxFromOrtho(0,0),g_mBoxFromOrtho(0,1),g_mBoxFromOrtho(0,2)); vecb = CxDVector3(g_mBoxFromOrtho(1,0),g_mBoxFromOrtho(1,1),g_mBoxFromOrtho(1,2)); vecc = CxDVector3(g_mBoxFromOrtho(2,0),g_mBoxFromOrtho(2,1),g_mBoxFromOrtho(2,2)); // Minimal diameters g_fBoxMinDiamA = fabs(DotP(veca,Normalize(CrossP(vecb,vecc)))); g_fBoxMinDiamB = fabs(DotP(vecb,Normalize(CrossP(veca,vecc)))); g_fBoxMinDiamC = fabs(DotP(vecc,Normalize(CrossP(veca,vecb)))); g_fBoxMinDiam = MIN3(g_fBoxMinDiamA,g_fBoxMinDiamB,g_fBoxMinDiamC); DumpNonOrthoCellData(); } if ((g_iTrajFormat == 5) || ((g_iTrajFormat == 7) && (g_TimeStep.m_pVolumetricData != NULL))) { mprintf("\n Cube file has a resolution of %d x %d x %d.\n",g_TimeStep.m_pVolumetricData->m_iRes[0],g_TimeStep.m_pVolumetricData->m_iRes[1],g_TimeStep.m_pVolumetricData->m_iRes[2]); if (g_bBoxNonOrtho) { double ang = Angle_Deg(CxDVector3(g_mCubeCell(0, 0), g_mCubeCell(0, 1), g_mCubeCell(0, 2)), veca); if (ang > 1.0) { eprintf("The direction of cell vector A does not match the grid data in the cube file (the angle is %.2f deg).\nPlease check the cell vectors.\n", ang); abort(); } ang = Angle_Deg(CxDVector3(g_mCubeCell(1, 0), g_mCubeCell(1, 1), g_mCubeCell(1, 2)), vecb); if (ang > 1.0) { eprintf("The direction of cell vector B does not match the grid data in the cube file (the angle is %.2f deg).\nPlease check the cell vectors.\n", ang); abort(); } ang = Angle_Deg(CxDVector3(g_mCubeCell(2, 0), g_mCubeCell(2, 1), g_mCubeCell(2, 2)), vecc); if (ang > 1.0) { eprintf("The direction of cell vector C does not match the grid data in the cube file (the angle is %.2f deg).\nPlease check the cell vectors.\n", ang); abort(); } } mprintf("\n"); double diff; if (g_bBoxNonOrtho) { CxDVector3 diffvec = CxDVector3(g_fCubeXVector[0], g_fCubeXVector[1], g_fCubeXVector[2]) * (double)LEN_AU2PM * g_TimeStep.m_pVolumetricData->m_iRes[0]; diff = diffvec.GetLength() - veca.GetLength(); } else { diff = g_fBoxX - g_fCubeXStep * LEN_AU2PM * g_TimeStep.m_pVolumetricData->m_iRes[0]; } if (fabs(diff) > 0.1) { mprintf(" The X cell vector does not match the grid data in the cube file (the difference is %.3f pm).\n", diff); mprintf(" This is possibly connected to the stride of the cube file.\n\n"); g_iCubeXStride = AskInteger(" Which X stride was used to write the cube file? [2] ", 2); int i; for (i = 1; i < g_iCubeXStride; i++) { if (g_bBoxNonOrtho) { CxDVector3 diffvec = CxDVector3(g_fCubeXVector[0], g_fCubeXVector[1], g_fCubeXVector[2]) * (double)LEN_AU2PM * (g_TimeStep.m_pVolumetricData->m_iRes[0] * g_iCubeXStride - i) / g_iCubeXStride; diff = CxDVector3(g_fCubeXVector[0], g_fCubeXVector[1], g_fCubeXVector[2]).GetLength() - veca.GetLength(); } else { diff = g_fBoxX - g_fCubeXStep * LEN_AU2PM * (g_TimeStep.m_pVolumetricData->m_iRes[0] * g_iCubeXStride - i) / g_iCubeXStride; } if (fabs(diff) < 0.1) { mprintf("\n Assuming that the original grid had %d points, the data would match (the difference is %.3f pm).\n\n", g_TimeStep.m_pVolumetricData->m_iRes[0] * g_iCubeXStride - i, diff); if (AskYesNo(" Take this value (y/n)? [yes] ", true)) { g_iCubeXMismatch = i; break; } } } if (g_iCubeXMismatch == 0) { mprintf("\n"); mprintf(" The original number of grid points could not be determined.\n"); g_iCubeXMismatch = g_TimeStep.m_pVolumetricData->m_iRes[0] * g_iCubeXStride - AskRangeInteger_ND(" Please enter the original number of grid points: ", (g_TimeStep.m_pVolumetricData->m_iRes[0] - 1) * g_iCubeXStride + 1, g_TimeStep.m_pVolumetricData->m_iRes[0] * g_iCubeXStride); } // if (g_bBoxNonOrtho) { g_fCubeXVector[0] /= g_iCubeXStride; g_fCubeXVector[1] /= g_iCubeXStride; g_fCubeXVector[2] /= g_iCubeXStride; // } else { g_fCubeXStep /= g_iCubeXStride; // } mprintf("\n"); } else { mprintf(" X cell vector matches grid data in cube file (difference is %.3f pm).\n", diff); } if (g_bBoxNonOrtho) { CxDVector3 diffvec = CxDVector3(g_fCubeYVector[0], g_fCubeYVector[1], g_fCubeYVector[2]) * (double)LEN_AU2PM * g_TimeStep.m_pVolumetricData->m_iRes[1]; diff = diffvec.GetLength() - vecb.GetLength(); } else { diff = g_fBoxY - g_fCubeYStep * LEN_AU2PM * g_TimeStep.m_pVolumetricData->m_iRes[1]; } if (fabs(diff) > 0.1) { mprintf("\n The Y cell vector does not match the grid data in the cube file (the difference is %.3f pm).\n", diff); mprintf(" This is possibly connected to the stride of the cube file.\n\n"); g_iCubeYStride = AskInteger(" Which Y stride was used to write the cube file? [2] ", 2); int i; for (i = 1; i < g_iCubeYStride; i++) { if (g_bBoxNonOrtho) { CxDVector3 diffvec = CxDVector3(g_fCubeYVector[0], g_fCubeYVector[1], g_fCubeYVector[2]) * (double)LEN_AU2PM * (g_TimeStep.m_pVolumetricData->m_iRes[1] * g_iCubeYStride - i) / g_iCubeXStride; diff = CxDVector3(g_fCubeYVector[0], g_fCubeYVector[1], g_fCubeYVector[2]).GetLength() - vecb.GetLength(); } else { diff = g_fBoxY - g_fCubeYStep * LEN_AU2PM * (g_TimeStep.m_pVolumetricData->m_iRes[1] * g_iCubeYStride - i) / g_iCubeYStride; } if (fabs(diff) < 0.1) { mprintf("\n Assuming that the original grid had %d points, the data would match (the difference is %.3f pm).\n", g_TimeStep.m_pVolumetricData->m_iRes[1] * g_iCubeYStride - i, diff); if (AskYesNo(" Take this value (y/n)? [yes] ", true)) { g_iCubeYMismatch = i; break; } } } if (g_iCubeYMismatch == 0) { mprintf("\n"); mprintf(" The original number of grid points could not be determined.\n"); g_iCubeYMismatch = g_TimeStep.m_pVolumetricData->m_iRes[1] * g_iCubeYStride - AskRangeInteger_ND(" Please enter the original number of grid points: ", (g_TimeStep.m_pVolumetricData->m_iRes[1] - 1) * g_iCubeYStride + 1, g_TimeStep.m_pVolumetricData->m_iRes[1] * g_iCubeYStride); } // if (g_bBoxNonOrtho) { g_fCubeYVector[0] /= g_iCubeYStride; g_fCubeYVector[1] /= g_iCubeYStride; g_fCubeYVector[2] /= g_iCubeYStride; // } else { g_fCubeYStep /= g_iCubeYStride; // } mprintf("\n"); } else { mprintf(" Y cell vector matches grid data in cube file (difference is %.3f pm).\n", diff); } if (g_bBoxNonOrtho) { CxDVector3 diffvec = CxDVector3(g_fCubeZVector[0], g_fCubeZVector[1], g_fCubeZVector[2]) * (double)LEN_AU2PM * g_TimeStep.m_pVolumetricData->m_iRes[2]; diff = diffvec.GetLength() - vecc.GetLength(); } else { diff = g_fBoxZ - g_fCubeZStep * LEN_AU2PM * g_TimeStep.m_pVolumetricData->m_iRes[2]; } if (fabs(diff) > 0.1) { mprintf("\n The Z cell vector does not match the grid data in the cube file (the difference is %.3f pm).\n", diff); mprintf(" This is possibly connected to the stride of the cube file.\n\n"); g_iCubeZStride = AskInteger(" Which Z stride was used to write the cube file? [2] ", 2); int i; for (i = 1; i < g_iCubeZStride; i++) { if (g_bBoxNonOrtho) { CxDVector3 diffvec = CxDVector3(g_fCubeZVector[0], g_fCubeZVector[1], g_fCubeZVector[2]) * (double)LEN_AU2PM * (g_TimeStep.m_pVolumetricData->m_iRes[2] * g_iCubeZStride - i) / g_iCubeZStride; diff = CxDVector3(g_fCubeZVector[0], g_fCubeZVector[1], g_fCubeZVector[2]).GetLength() - vecc.GetLength(); } else { diff = g_fBoxZ - g_fCubeZStep * LEN_AU2PM * (g_TimeStep.m_pVolumetricData->m_iRes[2] * g_iCubeZStride - i) / g_iCubeZStride; } if (fabs(diff) < 0.1) { mprintf("\n Assuming that the original grid had %d points, the data would match (the difference is %.3f pm).\n", g_TimeStep.m_pVolumetricData->m_iRes[2] * g_iCubeZStride - i, diff); if (AskYesNo(" Take this value (y/n)? [yes] ", true)) { g_iCubeZMismatch = i; break; } } } if (g_iCubeZMismatch == 0) { mprintf("\n"); mprintf(" The original number of grid points could not be determined.\n"); g_iCubeZMismatch = g_TimeStep.m_pVolumetricData->m_iRes[2] * g_iCubeZStride - AskRangeInteger_ND(" Please enter the original number of grid points: ", (g_TimeStep.m_pVolumetricData->m_iRes[2] - 1) * g_iCubeZStride + 1, g_TimeStep.m_pVolumetricData->m_iRes[2] * g_iCubeZStride); } // if (g_bBoxNonOrtho) { g_fCubeZVector[0] /= g_iCubeZStride; g_fCubeZVector[1] /= g_iCubeZStride; g_fCubeZVector[2] /= g_iCubeZStride; // } else { g_fCubeZStep /= g_iCubeZStride; // } mprintf("\n"); } else { mprintf(" Z cell vector matches grid data in cube file (difference is %.3f pm).\n", diff); } if (g_bAdvanced1) { mprintf("\n You may enter a cube interpolation factor along each axis (1 means no interpolation)\n"); int factor = 0; while (true) { factor = AskInteger(" X axis: [1] ", 1); if (factor >= 1) break; mprintf(RED, "The factor has to be positive.\n"); } if (factor > 1) { g_iCubeXStride *= factor; g_iCubeXMismatch *= factor; if (g_bBoxNonOrtho) { g_fCubeXVector[0] /= g_iCubeXStride; g_fCubeXVector[1] /= g_iCubeXStride; g_fCubeXVector[2] /= g_iCubeXStride; } else { g_fCubeXStep /= factor; } } while (true) { factor = AskInteger(" Y axis: [1] ", 1); if (factor >= 1) break; mprintf(RED, "The factor has to be positive.\n"); } if (factor > 1) { g_iCubeYStride *= factor; g_iCubeYMismatch *= factor; if (g_bBoxNonOrtho) { g_fCubeYVector[0] /= g_iCubeYStride; g_fCubeYVector[1] /= g_iCubeYStride; g_fCubeYVector[2] /= g_iCubeYStride; } else { g_fCubeYStep /= factor; } } while (true) { factor = AskInteger(" Z axis: [1] ", 1); if (factor >= 1) break; mprintf(RED, "The factor has to be positive.\n"); } if (factor > 1) { g_iCubeZStride *= factor; g_iCubeZMismatch *= factor; if (g_bBoxNonOrtho) { g_fCubeZVector[0] /= g_iCubeZStride; g_fCubeZVector[1] /= g_iCubeZStride; g_fCubeZVector[2] /= g_iCubeZStride; } else { g_fCubeZStep /= factor; } } } if (g_bBoxNonOrtho) { g_fCubeXVector[0] = g_mBoxFromOrtho(0, 0) / (g_TimeStep.m_pVolumetricData->m_iRes[0] * g_iCubeXStride - g_iCubeXMismatch) / LEN_AU2PM; g_fCubeXVector[1] = g_mBoxFromOrtho(0, 1) / (g_TimeStep.m_pVolumetricData->m_iRes[0] * g_iCubeXStride - g_iCubeXMismatch) / LEN_AU2PM; g_fCubeXVector[2] = g_mBoxFromOrtho(0, 2) / (g_TimeStep.m_pVolumetricData->m_iRes[0] * g_iCubeXStride - g_iCubeXMismatch) / LEN_AU2PM; g_fCubeYVector[0] = g_mBoxFromOrtho(1, 0) / (g_TimeStep.m_pVolumetricData->m_iRes[1] * g_iCubeYStride - g_iCubeYMismatch) / LEN_AU2PM; g_fCubeYVector[1] = g_mBoxFromOrtho(1, 1) / (g_TimeStep.m_pVolumetricData->m_iRes[1] * g_iCubeYStride - g_iCubeYMismatch) / LEN_AU2PM; g_fCubeYVector[2] = g_mBoxFromOrtho(1, 2) / (g_TimeStep.m_pVolumetricData->m_iRes[1] * g_iCubeYStride - g_iCubeYMismatch) / LEN_AU2PM; g_fCubeZVector[0] = g_mBoxFromOrtho(2, 0) / (g_TimeStep.m_pVolumetricData->m_iRes[2] * g_iCubeZStride - g_iCubeZMismatch) / LEN_AU2PM; g_fCubeZVector[1] = g_mBoxFromOrtho(2, 1) / (g_TimeStep.m_pVolumetricData->m_iRes[2] * g_iCubeZStride - g_iCubeZMismatch) / LEN_AU2PM; g_fCubeZVector[2] = g_mBoxFromOrtho(2, 2) / (g_TimeStep.m_pVolumetricData->m_iRes[2] * g_iCubeZStride - g_iCubeZMismatch) / LEN_AU2PM; int k, l; for (k = 0; k < 3; k++) { for (l = 0; l < 3; l++) { g_mCubeCell(k, l) = g_mBoxFromOrtho(k, l); } } g_TimeStep.m_pVolumetricData->m_fMaxVal[0] = sqrt(g_mCubeCell(0, 0) * g_mCubeCell(0, 0) + g_mCubeCell(0, 1) * g_mCubeCell(0, 1) + g_mCubeCell(0, 2) * g_mCubeCell(0, 2)); g_TimeStep.m_pVolumetricData->m_fMaxVal[1] = sqrt(g_mCubeCell(1, 0) * g_mCubeCell(1, 0) + g_mCubeCell(1, 1) * g_mCubeCell(1, 1) + g_mCubeCell(1, 2) * g_mCubeCell(1, 2)); g_TimeStep.m_pVolumetricData->m_fMaxVal[2] = sqrt(g_mCubeCell(2, 0) * g_mCubeCell(2, 0) + g_mCubeCell(2, 1) * g_mCubeCell(2, 1) + g_mCubeCell(2, 2) * g_mCubeCell(2, 2)); } else { if (fabs(g_fCubeXStep - g_fBoxX / (g_TimeStep.m_pVolumetricData->m_iRes[0] * g_iCubeXStride - g_iCubeXMismatch) / LEN_AU2PM) > 0.1 || fabs(g_fCubeYStep - g_fBoxY / (g_TimeStep.m_pVolumetricData->m_iRes[1] * g_iCubeYStride - g_iCubeYMismatch) / LEN_AU2PM) > 0.1 || fabs(g_fCubeZStep - g_fBoxZ / (g_TimeStep.m_pVolumetricData->m_iRes[2] * g_iCubeZStride - g_iCubeZMismatch) / LEN_AU2PM) > 0.1) { eprintf("Error while adapting cube grid step to cell size.\n"); return false; } g_fCubeXStep = g_fBoxX / (g_TimeStep.m_pVolumetricData->m_iRes[0] * g_iCubeXStride - g_iCubeXMismatch) / LEN_AU2PM; g_fCubeYStep = g_fBoxY / (g_TimeStep.m_pVolumetricData->m_iRes[1] * g_iCubeYStride - g_iCubeYMismatch) / LEN_AU2PM; g_fCubeZStep = g_fBoxZ / (g_TimeStep.m_pVolumetricData->m_iRes[2] * g_iCubeZStride - g_iCubeZMismatch) / LEN_AU2PM; g_mCubeCell.Unity(); g_mCubeCell(0, 0) = g_fBoxX; g_mCubeCell(1, 1) = g_fBoxY; g_mCubeCell(2, 2) = g_fBoxZ; g_TimeStep.m_pVolumetricData->m_fMaxVal[0] = g_fCubeXStep * LEN_AU2PM * (g_TimeStep.m_pVolumetricData->m_iRes[0] * g_iCubeXStride - g_iCubeXMismatch); g_TimeStep.m_pVolumetricData->m_fMaxVal[1] = g_fCubeYStep * LEN_AU2PM * (g_TimeStep.m_pVolumetricData->m_iRes[1] * g_iCubeYStride - g_iCubeYMismatch); g_TimeStep.m_pVolumetricData->m_fMaxVal[2] = g_fCubeZStep * LEN_AU2PM * (g_TimeStep.m_pVolumetricData->m_iRes[2] * g_iCubeZStride - g_iCubeZMismatch); } } _celldefined: if (g_bAdvanced1 && g_bPeriodic) { mprintf("\n"); if (AskYesNo(" Should the periodic box be multiplied (y/n)? [no] ",false)) { mprintf("\n"); g_bDoubleBox = true; if (g_bPeriodicX) g_iDoubleBoxX = AskUnsignedInteger(" Replicate the box n times in X direction: [2] ",2); else g_iDoubleBoxX = 1; if (g_bPeriodicY) g_iDoubleBoxY = AskUnsignedInteger(" Replicate the box n times in Y direction: [2] ",2); else g_iDoubleBoxY = 1; if (g_bPeriodicZ) g_iDoubleBoxZ = AskUnsignedInteger(" Replicate the box n times in Z direction: [2] ",2); else g_iDoubleBoxZ = 1; g_iDoubleBoxFactor = g_iDoubleBoxX * g_iDoubleBoxY * g_iDoubleBoxZ; g_iGesAtomCount *= g_iDoubleBoxFactor; g_iGesVirtAtomCount *= g_iDoubleBoxFactor; if (g_bBoxNonOrtho) { g_mBoxFromOrtho(0,0) *= g_iDoubleBoxX; g_mBoxFromOrtho(1,0) *= g_iDoubleBoxX; g_mBoxFromOrtho(2,0) *= g_iDoubleBoxX; g_mBoxFromOrtho(0,1) *= g_iDoubleBoxY; g_mBoxFromOrtho(1,1) *= g_iDoubleBoxY; g_mBoxFromOrtho(2,1) *= g_iDoubleBoxY; g_mBoxFromOrtho(0,2) *= g_iDoubleBoxZ; g_mBoxFromOrtho(1,2) *= g_iDoubleBoxZ; g_mBoxFromOrtho(2,2) *= g_iDoubleBoxZ; g_mBoxToOrtho = CxDMatrix3(g_mBoxFromOrtho); if (!g_mBoxToOrtho.Invert()) { eprintf("Error: Encountered singular cell matrix (cell volume is zero).\n"); abort(); } } else { g_fBoxX *= g_iDoubleBoxX; g_fBoxY *= g_iDoubleBoxY; g_fBoxZ *= g_iDoubleBoxZ; g_mBoxFromOrtho(0,0) = g_fBoxX; g_mBoxFromOrtho(0,1) = 0; g_mBoxFromOrtho(0,2) = 0; g_mBoxFromOrtho(1,0) = 0; g_mBoxFromOrtho(1,1) = g_fBoxY; g_mBoxFromOrtho(1,2) = 0; g_mBoxFromOrtho(2,0) = 0; g_mBoxFromOrtho(2,1) = 0; g_mBoxFromOrtho(2,2) = g_fBoxZ; g_mBoxToOrtho = CxDMatrix3(g_mBoxFromOrtho); if (!g_mBoxToOrtho.Invert()) { eprintf("Error: Encountered singular cell matrix (cell volume is zero).\n"); abort(); } } } else g_bDoubleBox = false; } else g_bDoubleBox = false; } else g_bDoubleBox = false; try { g_pUniteTemp = new bool[g_iGesAtomCount]; } catch(...) { g_pUniteTemp = NULL; } if (g_pUniteTemp == NULL) NewException((double)g_iGesAtomCount*sizeof(bool),__FILE__,__LINE__,__PRETTY_FUNCTION__); if (!g_bPeriodic) g_bNPT = false; if (g_bPeriodic) { g_fMinPeriodic = 1e30; if (g_bPeriodicX) if (g_fMinPeriodic > g_fBoxX) g_fMinPeriodic = g_fBoxX; if (g_bPeriodicY) if (g_fMinPeriodic > g_fBoxY) g_fMinPeriodic = g_fBoxY; if (g_bPeriodicZ) if (g_fMinPeriodic > g_fBoxZ) g_fMinPeriodic = g_fBoxZ; } static bool firstmetal = true; if (firstmetal) { firstmetal = false; tb = false; for (z=0;zm_pMergedTo != NULL) continue; if (IsElementMetal((const char*)((CAtom*)g_oaAtoms[z])->m_pElement->m_sLabel)) tb = true; } if (tb) { mprintf("\n"); mprintf(" The trajectory contains some metal atoms.\n"); mprintf(" In many cases, these are ions, and should not form any covalent bonds.\n\n"); for (z=0;zm_pMergedTo != NULL) continue; for (z2=0;z2m_pElement == ((CAtom*)g_oaAtoms[z2])->m_pElement) goto _nextmetal; if (IsElementMetal((const char*)((CAtom*)g_oaAtoms[z])->m_pElement->m_sLabel)) { if (AskYesNo(" Exclude %s atoms from bond recognition (y/n)? [yes] ",true,(const char*)((CAtom*)g_oaAtoms[z])->m_pElement->m_sLabel)) ((CAtom*)g_oaAtoms[z])->m_pElement->m_fRadius = 0; } _nextmetal:; } } tb = false; for (z=0;zm_pMergedTo != NULL) continue; if (IsElementNobleGas((const char*)((CAtom*)g_oaAtoms[z])->m_pElement->m_sLabel)) tb = true; } if (tb) { mprintf("\n"); mprintf(" The trajectory contains some noble gas atoms.\n"); mprintf(" They probably should not form any covalent bonds.\n\n"); for (z=0;zm_pMergedTo != NULL) continue; for (z2=0;z2m_pElement == ((CAtom*)g_oaAtoms[z2])->m_pElement) goto _nextnoble; if (IsElementNobleGas((const char*)((CAtom*)g_oaAtoms[z])->m_pElement->m_sLabel)) { if (AskYesNo(" Exclude %s atoms from bond recognition (y/n)? [yes] ",true,(const char*)((CAtom*)g_oaAtoms[z])->m_pElement->m_sLabel)) ((CAtom*)g_oaAtoms[z])->m_pElement->m_fRadius = 0; } _nextnoble:; } } } // SAVEPOS; _molbegin: g_iCloseAtomCounter = 0; if (g_bReactive) { if (g_pReactEngine == NULL) g_pReactEngine = new CReactiveEngine(); g_pReactEngine->Parse(); goto _reactivedone; } if (!g_bStreamInput) { if (g_bAdvanced1) { mprintf("\n"); g_iScanMolStep = AskInteger(" Execute molecule recognition for which time step (-1 = disable)? [0] ",0); } else g_iScanMolStep = 0; // a = fopen(g_sInputTraj,"rb"); if (!OpenInputTrajectory()) return false; if ((g_bNPT) && (g_sNPTFile[0] != 0)) g_fNPTFile = fopen(g_sNPTFile,"rt"); if (g_iScanMolStep > 0) { mprintf(" Fast-forwarding to step %d...\n",g_iScanMolStep); if (g_iTrajFormat == 7) { mprintf("Warning: Index-based seeking for bqb files not yet implemented.\n"); /* if (!SeekInputTrajectory(g_iScanMolStep)) return false;*/ } mprintf(WHITE," ["); for (z=0;zm_laSingleMolIndex[0]]; buf.sprintf("mol%d.pdb",z+1); mprintf(" Writing PDB file to \"%s\"...\n",(const char*)buf); g_TimeStep.ExportSingleMolecule_PDB(sm,(const char*)buf); buf.sprintf("obabel -ipdb mol%d.pdb -ocan -Omol%d_smiles.txt",z+1,z+1); mprintf(" Executing OpenBabel (\"%s\")...\n",(const char*)buf); (void)system((const char*)buf); buf.sprintf("mol%d_smiles.txt",z+1); mprintf(" Reading output file...\n"); if (!FileExist((const char*)buf)) { eprintf(" Output file not present. OpenBabel run did not work.\n"); continue; } a = fopen((const char*)buf,"rt"); (void)buf.fgets(1024,a); fclose(a); if (buf.FindFirst(' ') != -1) buf.GetWritePointer()[buf.FindFirst(' ')] = 0; if (buf.FindFirst('\t') != -1) buf.GetWritePointer()[buf.FindFirst('\t')] = 0; m->m_sSMILES = buf; mprintf(" Read %d characters from SMILES string.\n",m->m_sSMILES.GetLength()); /* buf.sprintf("mol%d.pdb",z+1); remove(buf); buf.sprintf("mol%d_smiles.txt",z+1); remove(buf);*/ } } #endif /* if (g_bVerbose) { mprintf(WHITE,">>> Output of the molecule tree >>>\n"); g_TimeStep.PrintMegaTree(); mprintf(WHITE,"<<< Output of the molecule tree <<<\n\n"); }*/ _matrixagain: if (g_bAdvanced1) { mprintf("\n"); g_bMegaMat = !AskYesNo(" Show bond matrices only for first representant of each molecule type (y/n)? [yes] ",true); g_bMatOnlyBind = AskYesNo(" Show only bonds in the bond matrices (y/n)? [yes] ",true); } else { g_bMegaMat = false; g_bMatOnlyBind = true; } mprintf(WHITE,"\nOutput of bond matrices:\n"); g_TimeStep.PrintMatrix(!g_bMegaMat,g_bMatOnlyBind); mprintf(YELLOW,"\n\n*** The following %d kind%s of molecules ha%s been recognized:\n",g_oaMolecules.GetSize(),(g_oaMolecules.GetSize()>1)?"s":"",(g_oaMolecules.GetSize()>1)?"ve":"s"); mprintf(" (ordered by molecular mass)\n\n"); for (z=0;zm_sName); mprintf("(%d piece%s, %.2f g/mol)\n",m->m_laSingleMolIndex.GetSize(),(m->m_laSingleMolIndex.GetSize()>1)?"s":"",m->m_fMass); sm = (CSingleMolecule*)g_oaSingleMolecules[((CMolecule*)g_oaMolecules[z])->m_laSingleMolIndex[0]]; mprintf(" (%d noneq. atom%s, %d noneq. bond%s, %d noneq. angle%s)\n",sm->m_iAtomClasses,(sm->m_iAtomClasses==1)?"":"s",sm->m_oaBondGroups.GetSize(),(sm->m_oaBondGroups.GetSize()==1)?"":"s",sm->m_oaAngleGroups.GetSize(),(sm->m_oaAngleGroups.GetSize()==1)?"":"s"); if (m->m_sSMILES.GetLength() != 0) mprintf(" Canonical SMILES: %s\n",(const char*)m->m_sSMILES); if (((CMolecule*)g_oaMolecules[z])->m_oaRingAtoms.GetSize() != 0) { if (((CMolecule*)g_oaMolecules[z])->m_oaRingAtoms.GetSize() == 1) mprintf(WHITE," Detected %d ring:\n",m->m_oaRingAtoms.GetSize()); else mprintf(WHITE," Detected %d rings:\n",m->m_oaRingAtoms.GetSize()); for (z2=0;z2m_oaRingAtoms.GetSize();z2++) { mprintf(WHITE," %2d.) %2d-ring: ",z2+1,((CxIntArray*)m->m_oaRingAtoms[z2])->GetSize()); if (((CxIntArray*)m->m_oaRingAtoms[z2])->GetSize() > 16) { for (z3=0;z3<5;z3++) { mprintf("%s%d",(const char*)((CAtom*)g_oaAtoms[m->m_baAtomIndex[((CxIntArray*)m->m_oaRingAtomTypes[z2])->GetAt(z3)]])->m_sName,((CxIntArray*)m->m_oaRingAtoms[z2])->GetAt(z3)+1); if (z3+1 < ((CxIntArray*)m->m_oaRingAtoms[z2])->GetSize()) mprintf(" - "); } mprintf(RED,"..."); mprintf(" - "); for (z3=((CxIntArray*)m->m_oaRingAtoms[z2])->GetSize()-5;z3<((CxIntArray*)m->m_oaRingAtoms[z2])->GetSize();z3++) { mprintf("%s%d",(const char*)((CAtom*)g_oaAtoms[m->m_baAtomIndex[((CxIntArray*)m->m_oaRingAtomTypes[z2])->GetAt(z3)]])->m_sName,((CxIntArray*)m->m_oaRingAtoms[z2])->GetAt(z3)+1); if (z3+1 < ((CxIntArray*)m->m_oaRingAtoms[z2])->GetSize()) mprintf(" - "); } } else { for (z3=0;z3<((CxIntArray*)m->m_oaRingAtoms[z2])->GetSize();z3++) { mprintf("%s%d",(const char*)((CAtom*)g_oaAtoms[m->m_baAtomIndex[((CxIntArray*)m->m_oaRingAtomTypes[z2])->GetAt(z3)]])->m_sName,((CxIntArray*)m->m_oaRingAtoms[z2])->GetAt(z3)+1); if (z3+1 < ((CxIntArray*)m->m_oaRingAtoms[z2])->GetSize()) mprintf(" - "); } } mprintf("\n"); if (z2 >= 9) { mprintf(RED,"\n Showing only the first 10 rings.\n"); break; } } } mprintf("\n"); } #ifndef USE_OPENBABEL mprintf("\n If you switch on \"USE_OPENBABEL\" in config.h, TRAVIS can print SMILES strings of your molecules.\n"); #endif mprintf("\n"); mprintf(" You can create images of the structural formulas with the atom labels for easier\n"); mprintf(" identification of the atoms (requires installed GraphViz package - see www.graphviz.org).\n\n"); if (AskYesNo(" Create images of the structural formulas (y/n)? [no] ",false)) { if (g_bAdvanced1) ti = AskUnsignedInteger(" How many iterations to perform for formula optimization? [10] ",10); else ti = 10; RenderStructFormulas(ti); } mprintf("\n"); if (!AskYesNo(" Accept these molecules (y) or change something (n)? [yes] ",true)) { tb = false; mprintf("\n"); mprintf(" If you want some atom types to form no bonds at all, assign covalent radius 0 to them.\n"); _modagain: mprintf(YELLOW,"\n *** Modify Molecules ***\n\n"); mprintf(" Your choices:\n\n"); mprintf(" 1.) Change covalent atom radii used for bond recognition\n"); mprintf(" 2.) Break specific bonds\n"); mprintf(" 3.) Rename elements\n"); mprintf("\n"); switch(AskRangeInteger(" Please select: [done] ",1,3,0)) { case 1: // Change radii mprintf("\n A covalent radius of 0 means that the element can't form any bonds.\n\n"); mprintf(" These values have been used (covalent radii from literature multiplied with %.2f):\n\n",g_fBondFactor); for (z=0;zm_sName,((CAtom*)g_oaAtoms[z])->m_pElement->m_fRadius*g_fBondFactor); mprintf("\n"); _arnew: AskString(" Which radius do you want to change (RETURN=done)? ",&buf,""); if (strlen(buf) == 0) goto _ardone; for (z=0;zm_sName) == 0) { ((CAtom*)g_oaAtoms[z])->m_pElement->m_fRadius = AskFloat(" Please enter new bond radius for %s in pm: [%.1f] ",((CAtom*)g_oaAtoms[z])->m_pElement->m_fRadius*g_fBondFactor,(const char*)((CAtom*)g_oaAtoms[z])->m_sName,((CAtom*)g_oaAtoms[z])->m_pElement->m_fRadius*g_fBondFactor) / g_fBondFactor; if (((CAtom*)g_oaAtoms[z])->m_pElement->m_fRadius == 0) { mprintf("\n Atom %s will form no bonds now.\n\n",(const char*)((CAtom*)g_oaAtoms[z])->m_sName); ((CAtom*)g_oaAtoms[z])->m_bExclude = AskYesNo(" Also remove this atom type from the system (y/n)? [no] ",false); } mprintf("\n"); tb = true; goto _arnew; } } eprintf(" Atom \"%s\" is not in the system.\n\n",(const char*)buf); goto _arnew; _ardone: mprintf("\n"); break; case 2: // Break bonds _breakagain: mprintf("\n"); if (g_oaMolecules.GetSize() > 1) { _breakmol: ti = AskUnsignedInteger_ND(" Break bonds in which molecule (1-%d)? ",g_oaMolecules.GetSize())-1; if ((ti < 0) || (ti >= (int)g_oaMolecules.GetSize())) { eprintf("Invalid Input.\n\n"); goto _breakmol; } } else ti = 0; mol = (CMolecule*)g_oaMolecules[ti]; tb = true; if (AskYesNo(" Break all bonds within this molecule (y/n)? [no] ",false)) { for (z=0;zm_laSingleMolIndex.GetSize();z++) { sm = (CSingleMolecule*)g_oaSingleMolecules[mol->m_laSingleMolIndex[z]]; g_laBondBlackList.Append(&sm->m_laBonds); } } else { _breaka1: AskString_ND(" Enter 1st atom of the bond to break (e.g. O2): ",&buf); if (!ParseAtom(buf,ti,ty,rty,atom)) goto _breaka1; _breaka2: AskString_ND(" Enter 2nd atom of the bond to break (e.g. O2): ",&buf); if (!ParseAtom(buf,ti,ty2,rty2,atom2)) goto _breaka2; for (z=0;zm_laSingleMolIndex.GetSize();z++) { sm = (CSingleMolecule*)g_oaSingleMolecules[mol->m_laSingleMolIndex[z]]; g_laBondBlackList.Add(((CxIntArray*)sm->m_oaAtomOffset[ty])->GetAt(atom)); g_laBondBlackList.Add(((CxIntArray*)sm->m_oaAtomOffset[ty2])->GetAt(atom2)); } } if (AskYesNo("\n Break another bond (y/n)? [no] ",false)) goto _breakagain; mprintf("\n"); break; case 3: // Rename elements /*********************************************************************************************************************/ _rennew: mprintf("\n The system contains the following atoms:\n\n "); tb2 = false; for (z=0;zm_pMergedTo != NULL) continue; if (tb2) mprintf(", "); tb2 = true; mprintf("%dx %s",((CAtom*)g_oaAtoms[z])->m_iCount,(const char*)((CAtom*)g_oaAtoms[z])->m_sName); } mprintf("\n\n"); _renerr: AskString(" Which element to rename: [done] ",&buf,""); if (strlen(buf) == 0) goto _rendone; for (z=0;zm_sName) == 0) goto _renfound; eprintf("\n Atom \"%s\" not in the system.\n\n",(const char*)buf); goto _renerr; _renfound: tb = true; at = (CAtom*)g_oaAtoms[z]; AskString_ND(" Enter new name for \"%s\": ",&buf2,(const char*)buf); // if (strlen(buf2) > 7) // { // eprintf("\n Atom labels may have a maximum length of 7 characters.\n\n"); // goto _renfound; // } if (ContainsDigitOrSpecial(buf2)) { eprintf("\n Digits or special characters in element labels are not allowed.\n\n"); goto _renfound; } /* el = FindElement(buf,true); if (el != NULL) { xAddAtom(buf); if (AskYesNo(" Element %s is known. Merge %s atoms into %s (y/n)? [yes] ",true,(const char*)buf,at->m_sName,(const char*)buf)) { for (z2=0;z2m_pElement == el) { at = (CAtom*)g_oaAtoms[z2]; el = at->m_pElement; goto _unk1; } } eprintf(" Strange error ^^\n"); _unk1:; } } else*/ el = FindElement(buf2,true); if (el != NULL) { xAddAtom(buf2,false); if (AskYesNo(" Element %s is known. Merge %s atoms into %s (y/n)? [yes] ",true,(const char*)buf2,(const char*)buf,(const char*)buf2)) { for (z2=0;z2m_pElement == el) { at = (CAtom*)g_oaAtoms[z2]; at->m_iCount--; el = at->m_pElement; goto _ren1; } } eprintf("\n Strange error ^^\n"); //_ren1:; } } else { mprintf("\n Adding element %s...\n\n",(const char*)buf2); try { at = new CAtom(); } catch(...) { at = NULL; } if (at == NULL) NewException((double)sizeof(CAtom),__FILE__,__LINE__,__PRETTY_FUNCTION__); at->m_iIndex = g_oaAtoms.GetSize(); g_oaAtoms.Add(at); at->m_iCount = 0; try { at->m_pElement = new CElement(); } catch(...) { at->m_pElement = NULL; } if (at->m_pElement == NULL) NewException((double)sizeof(CElement),__FILE__,__LINE__,__PRETTY_FUNCTION__); at->m_pElement->m_fRadius = AskFloat(" Please enter covalent radius in pm: [100.0] ",100.0); at->m_pElement->m_fMass = AskFloat(" Please enter atom mass in u: [0] ",0); // sprintf(at->m_sName,"%s",(const char*)buf2); at->m_sName = (const char*)buf2; at->m_pElement->m_sLabel = new char[buf2.GetLength()+1]; strcpy(at->m_pElement->m_sLabel,(const char*)buf2); g_oaElements.Add(at->m_pElement); } /* for (z2=0;z2m_sName) == 0) { mprintf(" Element %s is known. Merging all %s atoms into %s ...\n",(const char*)buf2,(const char*)buf,(const char*)buf2); at = (CAtom*)g_oaAtoms[z2]; goto _ren1; } } mprintf("\n Adding element %s ...\n\n",(const char*)buf2); try { at = new CAtom(); } catch(...) { at = NULL; } if (at == NULL) NewException((double)sizeof(CAtom),__FILE__,__LINE__,__PRETTY_FUNCTION__); at->m_iIndex = g_oaAtoms.GetSize(); g_oaAtoms.Add(at); at->m_iCount = 0; try { at->m_pElement = new CElement(); } catch(...) { at->m_pElement = NULL; } if (at->m_pElement == NULL) NewException((double)sizeof(CElement),__FILE__,__LINE__,__PRETTY_FUNCTION__); at->m_pElement->m_fRadius = AskFloat(" Please enter covalent radius in pm: [100.0] ",100.0); at->m_pElement->m_fMass = AskFloat(" Please enter atom mass in u: [0] ",0); sprintf(at->m_sName,"%s",(const char*)buf2);*/ _ren1: for (z2=0;z2<(int)g_TimeStep.m_iGesAtomCount;z2++) { // strcpy(buf,(char*)g_TimeStep.m_paLabels[z2]); buf.strcpy((char*)g_TimeStep.m_paLabels[z2]); ReplaceDigits(&buf); if (mystricmp(buf,((CAtom*)g_oaAtoms[z])->m_sName) == 0) { at->m_iCount++; ((CAtom*)g_oaAtoms[z])->m_iCount--; } } ((CAtom*)g_oaAtoms[z])->m_pMergedTo = at; mprintf("\n"); goto _rennew; _rendone:; mprintf("\n The system contains the following atoms:\n\n "); tb2 = false; for (z=0;zm_pMergedTo != NULL) continue; if (tb2) mprintf(", "); tb2 = true; mprintf("%dx %s",((CAtom*)g_oaAtoms[z])->m_iCount,(const char*)((CAtom*)g_oaAtoms[z])->m_sName); } mprintf("\n"); /*********************************************************************************************************************/ break; default: goto _fin; } goto _modagain; _fin: if (tb) { mprintf(WHITE,"\n Going back to molecule recognition with changed settings.\n\n"); goto _molbegin; } else mprintf(WHITE,"\n Nothing was changed, not repeating molecule recognition.\n\n"); } if (g_bPeriodic) { tb = false; for (z=0;zm_oaRingAtoms.GetSize() != 0) { if ((((CMolecule*)g_oaMolecules[z])->m_oaRingAtoms.GetSize() > 5) || (((CxIntArray*)((CMolecule*)g_oaMolecules[z])->m_oaRingAtoms[0])->GetSize() > 12)) { if (!tb) { tb = true; mprintf("\n Some of your molecules are polycyclic. Probably some of them are periodic across the\n"); mprintf(" cell boundary, i.e., are polymers of infinite extent (like, e.g., a periodic solid lattice).\n"); mprintf(" Those need to be handled differently (wrapped atom-wise, etc.).\n\n"); } ((CMolecule*)g_oaMolecules[z])->m_bPolymer = AskYesNo(" Molecule %d (%s): Is this an infinite polymer/lattice (y/n)? [yes] ",true,z+1,((CMolecule*)g_oaMolecules[z])->m_sName); } } } mprintf("\n Uniting molecules which have been broken by wrapping...\n"); g_TimeStep.UniteMolecules(true); } mprintf(WHITE,"\n The atoms are currently ordered by topological priority.\n"); if (g_bAdvanced1) { mprintf("\n"); // This block written @ Ballmer peak ;-P Try it out yourself. if (AskYesNo(" Change the atom ordering in some molecule (y/n)? [no] ",false)) { if (AskYesNo(" Order atoms like in the input file instead (y/n)? [no] ",false)) { ReorderLikeInput(); // Crazy shit!! (Ballmer Peak) } else { _reordernext: // sprintf(buf," Change atom ordering in which of the molecules ("); buf.sprintf(" Change atom ordering in which of the molecules ("); for (z=0;zm_sName,z+1); // strcat(buf,buf2); // if (z < g_oaMolecules.GetSize()-1) // strcat(buf,", "); buf2.sprintf("%s=%d",((CMolecule*)g_oaMolecules[z])->m_sName,z+1); buf.strcat(buf2); if (z < g_oaMolecules.GetSize()-1) buf.strcat(", "); } // strcat(buf,")? "); buf.strcat(")? "); ti = AskRangeInteger_ND("%s",1,g_oaMolecules.GetSize(),(const char*)buf)-1; mol = (CMolecule*)g_oaMolecules[ti]; mol->m_oaNewNumbers.SetSize(mol->m_baAtomIndex.GetSize()); for (z=0;zm_baAtomIndex.GetSize();z++) { mprintf("* Atom type %s\n",(const char*)((CAtom*)g_oaAtoms[mol->m_baAtomIndex[z]])->m_sName); if (mol->m_oaNewNumbers[z] != NULL) delete mol->m_oaNewNumbers[z]; try { mol->m_oaNewNumbers[z] = new CxIntArray("gather():mol->m_oaNewNumbers[z]"); } catch(...) { mol->m_oaNewNumbers[z] = NULL; } if (mol->m_oaNewNumbers[z] == NULL) NewException((double)sizeof(CxIntArray),__FILE__,__LINE__,__PRETTY_FUNCTION__); for (z2=0;z2m_waAtomCount[z];z2++) { _renumberagain: ti2 = AskRangeInteger(" Which number should %s%d bear? [%d] ",1,mol->m_waAtomCount[z],z2+1,(const char*)((CAtom*)g_oaAtoms[mol->m_baAtomIndex[z]])->m_sName,z2+1,z2+1); for (z3=0;z3m_oaNewNumbers[z])->GetAt(z3) == ti2-1) { eprintf("This number already was chosen for %s%d!\n",(const char*)((CAtom*)g_oaAtoms[mol->m_baAtomIndex[z]])->m_sName,z3+1); goto _renumberagain; } (*((CxIntArray*)mol->m_oaNewNumbers[z])).Add(ti2-1); } } mprintf("\n Reordering atoms..."); ReorderAtoms(ti); mprintf("Done.\n\n"); if (AskYesNo(" Change atom ordering of another molecule (y/n)? [no] ",false)) goto _reordernext; goto _matrixagain; } // End "this block" mprintf(WHITE,"\n Going back to molecule recognition with changed settings.\n\n"); goto _molbegin; } // END IF REORDER } // END IF ADVANCED mprintf(WHITE,"\n Defining virtual atom #1 as molecular Center of Geometry:\n"); for (z0=0;z0m_sName); va = AddVirtualAtom(z0); va->m_iMode = 0; va->m_oCenterAtoms.AddAllAtoms((CMolecule*)g_oaMolecules[va->m_iMolecule],false); va->m_faWeight.SetSize(va->m_oCenterAtoms.m_iAtomGes); for (z=0;zm_oCenterAtoms.m_iAtomGes;z++) va->m_faWeight[z] = 1.0; va->m_fGesWeight = (double)va->m_oCenterAtoms.m_iAtomGes; } mprintf(WHITE,"\n Defining virtual atom #2 as molecular Center of Mass:\n"); for (z0=0;z0m_sName); va = AddVirtualAtom(z0); va->m_iMode = 0; va->m_oCenterAtoms.AddAllAtoms((CMolecule*)g_oaMolecules[va->m_iMolecule],false); va->m_faWeight.SetSize(va->m_oCenterAtoms.m_iAtomGes); z3 = 0; tf2 = 0; for (z=0;zm_oCenterAtoms.m_baAtomType.GetSize();z++) { tf = ((CAtom*)g_oaAtoms[va->m_oCenterAtoms.m_baRealAtomType[z]])->m_pElement->m_fMass; for (z2=0;z2<((CxIntArray*)va->m_oCenterAtoms.m_oaAtoms[z])->GetSize();z2++) { va->m_faWeight[z3] = tf; tf2 += tf; z3++; } } va->m_fGesWeight = tf2; if (va->m_fGesWeight == 0) { eprintf(" Molecule %s has total mass of zero. Defining #2 as Center of Geometry.\n",((CMolecule*)g_oaMolecules[z0])->m_sName); for (z=0;zm_oCenterAtoms.m_iAtomGes;z++) va->m_faWeight[z] = 1.0; va->m_fGesWeight = (double)va->m_oCenterAtoms.m_iAtomGes; } } for (z0=0;z0m_oaRingAtoms.GetSize() != 0) { if (m->m_bPolymer) { mprintf(WHITE,"\n Skipping ring centers of %s: Is an infinite polymer/lattice.\n",m->m_sName); } else { mprintf(WHITE,"\n Defining ring centers in %s:\n",m->m_sName); for (z=0;zm_oaRingAtoms.GetSize();z++) { mprintf(" - Defining #%d as Center of Ring %d: ",z+3,z+1); for (z3=0;z3<((CxIntArray*)m->m_oaRingAtoms[z])->GetSize();z3++) { mprintf("%s%d",(const char*)((CAtom*)g_oaAtoms[m->m_baAtomIndex[((CxIntArray*)m->m_oaRingAtomTypes[z])->GetAt(z3)]])->m_sName,((CxIntArray*)m->m_oaRingAtoms[z])->GetAt(z3)+1); if (z3+1 < ((CxIntArray*)m->m_oaRingAtoms[z])->GetSize()) mprintf(" - "); } mprintf("\n"); va = AddVirtualAtom(z0); va->m_iMode = 0; va->m_oCenterAtoms.m_pMolecule = m; for (z3=0;z3<((CxIntArray*)m->m_oaRingAtoms[z])->GetSize();z3++) va->m_oCenterAtoms.AddAtom(((CxIntArray*)m->m_oaRingAtomTypes[z])->GetAt(z3),((CxIntArray*)m->m_oaRingAtoms[z])->GetAt(z3),false); va->m_faWeight.SetSize(va->m_oCenterAtoms.m_iAtomGes); for (z3=0;z3m_oCenterAtoms.m_iAtomGes;z3++) va->m_faWeight[z3] = 1.0; va->m_fGesWeight = (double)va->m_oCenterAtoms.m_iAtomGes; } } } } if (g_bAdvanced1) { mprintf("\n"); if (AskYesNo("\n Define additional virtual atoms (y/n)? [no] ",false)) { _vabeg: // sprintf(buf," To which molecule shall the virtual atom belong ("); buf.sprintf(" To which molecule shall the virtual atom belong ("); for (z=0;zm_sName,z+1); // strcat(buf,buf2); // if (z < g_oaMolecules.GetSize()-1) // strcat(buf,", "); buf2.sprintf("%s=%d",((CMolecule*)g_oaMolecules[z])->m_sName,z+1); buf.strcat(buf2); if (z < g_oaMolecules.GetSize()-1) buf.strcat(", "); } // strcat(buf,")? "); buf.strcat(")? "); z = AskRangeInteger_ND("%s",1,g_oaMolecules.GetSize(),(const char*)buf); va = AddVirtualAtom(z-1); mprintf(WHITE,"\n*** Defining virtual atom #%d in %s\n",va->m_iMolVirtAtom+1,((CMolecule*)g_oaMolecules[va->m_iMolecule])->m_sName); va->m_iMode = (unsigned char)AskRangeInteger(" Define v.a. as center (0) or through distance/angle/dihedral (1)? [center] ",0,1,0); if (va->m_iMode == 0) { _vaatoms: mprintf(" Which atoms to use for center (e.g. \"C1,C3-5,H\")? [all] "); inpprintf("! Which atoms to use for center (e.g. \"C1,C3-5,H\")? [all]\n"); myget(&buf); if (strlen(buf)==0) va->m_oCenterAtoms.AddAllAtoms((CMolecule*)g_oaMolecules[va->m_iMolecule],false); else if (!va->m_oCenterAtoms.ParseAtoms((CMolecule*)g_oaMolecules[va->m_iMolecule],buf)) goto _vaatoms; va->m_faWeight.SetSize(va->m_oCenterAtoms.m_iAtomGes); _vaweight: mprintf(" How shall these atoms be weightened (RETURN=equal, *=mass, #=manually)? [equal] "); inpprintf("! How shall these atoms be weightened (RETURN=equal, *=mass, #=manually)? [equal]\n"); myget(&buf); if (strlen(buf)==0) { for (z=0;zm_oCenterAtoms.m_iAtomGes;z++) va->m_faWeight[z] = 1.0; va->m_fGesWeight = (double)va->m_oCenterAtoms.m_iAtomGes; } else if (buf[0] == '*') { z3 = 0; tf2 = 0; for (z=0;zm_oCenterAtoms.m_baAtomType.GetSize();z++) { tf = ((CAtom*)g_oaAtoms[va->m_oCenterAtoms.m_baRealAtomType[z]])->m_pElement->m_fMass; for (z2=0;z2<((CxIntArray*)va->m_oCenterAtoms.m_oaAtoms[z])->GetSize();z2++) { va->m_faWeight[z3] = tf; tf2 += tf; z3++; } } va->m_fGesWeight = tf2; if (va->m_fGesWeight == 0) { eprintf("\n Molecule has total mass of zero. Weighting atoms equally.\n\n"); for (z=0;zm_oCenterAtoms.m_iAtomGes;z++) va->m_faWeight[z] = 1.0; va->m_fGesWeight = (double)va->m_oCenterAtoms.m_iAtomGes; } } else if (buf[0] == '#') { _vawagain: z3 = 0; tf2 = 0; mprintf("\n"); for (z=0;zm_oCenterAtoms.m_baAtomType.GetSize();z++) { for (z2=0;z2<((CxIntArray*)va->m_oCenterAtoms.m_oaAtoms[z])->GetSize();z2++) { tf = AskFloat(" Enter the weight for %s%d: [1] ",1.0,((CAtom*)g_oaAtoms[va->m_oCenterAtoms.m_baRealAtomType[z]])->m_pElement->m_sLabel, ((CxIntArray *)va->m_oCenterAtoms.m_oaAtoms[z])->GetAt(z2)+1); va->m_faWeight[z3] = tf; tf2 += tf; z3++; } } mprintf(" The sum of weights is %.4f.\n\n",tf2); va->m_fGesWeight = tf2; if (va->m_fGesWeight == 0) { eprintf("Sum of weights may not be zero. Enter the weights again.\n\n"); goto _vawagain; } } else { eprintf("Invalid input.\n"); inpprintf("! Invalid input.\n"); goto _vaweight; } } else { _vabond: mprintf(" Enter 2nd atom for distance #%d- (e.g. C2): ",va->m_iMolVirtAtom+1); inpprintf("! Enter 2nd atom for distance #%d- (e.g. C2):\n",va->m_iMolVirtAtom+1); myget(&buf); if (!ParseAtom(buf,va->m_iMolecule,va->m_iAtomType[0],va->m_iRealAtomType[0],va->m_iAtom[0])) goto _vabond; if ((va->m_iRealAtomType[0] == g_iVirtAtomType) && (va->m_iAtom[0] == va->m_iMolVirtAtom)) { eprintf("This atom was already chosen.\n"); goto _vabond; } _vaangle: mprintf(" Enter 3rd atom for angle #%d-%s%d- (e.g. C2)? ",va->m_iMolVirtAtom+1,(const char*)((CAtom*)g_oaAtoms[va->m_iRealAtomType[0]])->m_sName,va->m_iAtom[0]+1); inpprintf("! Enter 3rd atom for angle #%d-%s%d- (e.g. C2)?\n",va->m_iMolVirtAtom+1,(const char*)((CAtom*)g_oaAtoms[va->m_iRealAtomType[0]])->m_sName,va->m_iAtom[0]+1); myget(&buf); if (!ParseAtom(buf,va->m_iMolecule,va->m_iAtomType[1],va->m_iRealAtomType[1],va->m_iAtom[1])) goto _vaangle; if (((va->m_iRealAtomType[1] == g_iVirtAtomType) && (va->m_iAtom[1] == va->m_iMolVirtAtom)) || ((va->m_iRealAtomType[1] == va->m_iRealAtomType[0]) && (va->m_iAtom[1] == va->m_iAtom[0]))) { eprintf("This atom was already chosen.\n"); goto _vaangle; } _vadihedral: mprintf(" Enter 4th atom for dihedral #%d-%s%d-%s%d- (e.g. C2)? ",va->m_iMolVirtAtom+1,(const char*)((CAtom*)g_oaAtoms[va->m_iRealAtomType[0]])->m_sName,va->m_iAtom[0]+1,(const char*)((CAtom*)g_oaAtoms[va->m_iRealAtomType[1]])->m_sName,va->m_iAtom[1]+1); inpprintf("! Enter 4th atom for dihedral #%d-%s%d-%s%d- (e.g. C2)?\n",va->m_iMolVirtAtom+1,(const char*)((CAtom*)g_oaAtoms[va->m_iRealAtomType[0]])->m_sName,va->m_iAtom[0]+1,(const char*)((CAtom*)g_oaAtoms[va->m_iRealAtomType[1]])->m_sName,va->m_iAtom[1]+1); myget(&buf); if (!ParseAtom(buf,va->m_iMolecule,va->m_iAtomType[2],va->m_iRealAtomType[2],va->m_iAtom[2])) goto _vadihedral; if (((va->m_iRealAtomType[2] == g_iVirtAtomType) && (va->m_iAtom[2] == va->m_iMolVirtAtom)) || ((va->m_iRealAtomType[2] == va->m_iRealAtomType[0]) && (va->m_iAtom[2] == va->m_iAtom[0])) || ((va->m_iRealAtomType[2] == va->m_iRealAtomType[1]) && (va->m_iAtom[2] == va->m_iAtom[1]))) { eprintf("This atom was already chosen.\n"); goto _vadihedral; } va->m_fValues[0] = AskFloat_ND(" Enter distance #%d-%s%d in pm: ",va->m_iMolVirtAtom+1,(const char*)((CAtom*)g_oaAtoms[va->m_iRealAtomType[0]])->m_sName,va->m_iAtom[0]+1); va->m_fValues[1] = AskFloat_ND(" Enter angle #%d-%s%d-%s%d in degree: ",va->m_iMolVirtAtom+1,(const char*)((CAtom*)g_oaAtoms[va->m_iRealAtomType[0]])->m_sName,va->m_iAtom[0]+1,(const char*)((CAtom*)g_oaAtoms[va->m_iRealAtomType[1]])->m_sName,va->m_iAtom[1]+1) * (double)Pi / 180.0; va->m_fValues[2] = AskFloat_ND(" Enter dihedral #%d-%s%d-%s%d-%s%d in degree: ",va->m_iMolVirtAtom+1,(const char*)((CAtom*)g_oaAtoms[va->m_iRealAtomType[0]])->m_sName,va->m_iAtom[0]+1,(const char*)((CAtom*)g_oaAtoms[va->m_iRealAtomType[1]])->m_sName,va->m_iAtom[1]+1,(const char*)((CAtom*)g_oaAtoms[va->m_iRealAtomType[2]])->m_sName,va->m_iAtom[2]+1) * (double)Pi / 180.0; } if (AskYesNo("\n Define further virtual atoms (y/n)? [no] ",false)) goto _vabeg; } mprintf("\n"); mprintf(" Pseudo-molecules are a tool to group together certain atoms from certain different\n"); mprintf(" molecules in a system. This group can then be used lika a normal molecule in analyses\n"); mprintf(" (e.g., center of mass of all solvent molecules, etc.).\n"); mprintf("\n"); if (AskYesNo(" Do you want to define pseudo-molecules (y/n)? [no] ",false)) { tb2 = false; ti = 0; mprintf("\n If you need the center of mass or center of geometry of the whole system, you should\n"); mprintf(" define a pseudo-molecule over the whole system, and use its atoms #1 and #2.\n\n"); if (AskYesNo(" Define a pseudo-molecule over the whole system (y/n)? [yes] ",true)) { ti++; /************************************************************************/ mprintf("\n"); try { m2 = new CMolecule(); } catch(...) { m2 = NULL; } if (m2 == NULL) NewException((double)sizeof(CMolecule),__FILE__,__LINE__,__PRETTY_FUNCTION__); try { sm2 = new CSingleMolecule(); } catch(...) { sm2 = NULL; } if (sm2 == NULL) NewException((double)sizeof(CSingleMolecule),__FILE__,__LINE__,__PRETTY_FUNCTION__); m2->m_bPseudo = true; sm2->m_bPseudo = true; m2->m_iIndex = g_oaMolecules.GetSize(); sm2->m_iMolType = g_oaMolecules.GetSize(); sm2->m_iMolSMIndex = 0; m2->m_laSingleMolIndex.Add(g_oaSingleMolecules.GetSize()); g_oaMolecules.Add(m2); g_oaSingleMolecules.Add(sm2); mprintf(WHITE," >>> Pseudo-molecule %d (= molecule %d) >>>\n\n",ti,g_oaMolecules.GetSize()); mprintf(" Adding all atoms from all molecules...\n"); for (z=0;zm_bPseudo) continue; try { ag = new CAtomGroup(); } catch(...) { ag = NULL; } if (ag == NULL) NewException((double)sizeof(CAtomGroup),__FILE__,__LINE__,__PRETTY_FUNCTION__); ag->AddAllAtoms(m,false); ia.RemoveAll(); for (z2=0;z2m_laSingleMolIndex.GetSize();z2++) ia.Add(z2); for (z2=0;z2m_baAtomType.GetSize();z2++) { m2->m_iAtomGes += ((CxIntArray*)ag->m_oaAtoms[z2])->GetSize() * ia.GetSize(); for (z4=0;z4m_baAtomIndex.GetSize();z4++) { if (m2->m_baAtomIndex[z4] == ag->m_baRealAtomType[z2]) { m2->m_waAtomCount[z4] += (unsigned short)(((CxIntArray*)ag->m_oaAtoms[z2])->GetSize() * ia.GetSize()); pia = (CxIntArray*)sm2->m_oaAtomOffset[z4]; goto _pmafound; } } m2->m_baAtomIndex.Add(ag->m_baRealAtomType[z2]); sm2->m_baAtomIndex.Add(ag->m_baRealAtomType[z2]); m2->m_waAtomCount.Add((unsigned short)(((CxIntArray*)ag->m_oaAtoms[z2])->GetSize() * ia.GetSize())); try { pia = new CxIntArray("gather():pia"); } catch(...) { pia = NULL; } if (pia == NULL) NewException((double)sizeof(CxIntArray),__FILE__,__LINE__,__PRETTY_FUNCTION__); sm2->m_oaAtomOffset.Add(pia); _pmafound: for (z4=0;z4<((CxIntArray*)ag->m_oaAtoms[z2])->GetSize();z4++) { for (z5=0;z5m_laSingleMolIndex[ia[z5]]]; for (z6=0;z6m_oaAtomOffset.GetSize();z6++) { for (z7=0;z7<((CxIntArray*)sm2->m_oaAtomOffset[z6])->GetSize();z7++) { if (((CxIntArray*)sm2->m_oaAtomOffset[z6])->GetAt(z7) == ((CxIntArray*)sm->m_oaAtomOffset[ag->m_baAtomType[z2]])->GetAt(((CxIntArray*)ag->m_oaAtoms[z2])->GetAt(z4))) { eprintf("Internal error: Atom %s%d from %s[%d] is already in the pseudo-molecule; skipping.\n",(const char*)((CAtom*)g_oaAtoms[ag->m_baRealAtomType[z2]])->m_sName,((CxIntArray*)ag->m_oaAtoms[z2])->GetAt(z4)+1,m->m_sName,ia[z5]+1); m2->m_waAtomCount[m2->m_waAtomCount.GetSize()-1]--; abort(); } } } pia->Add(((CxIntArray*)sm->m_oaAtomOffset[ag->m_baAtomType[z2]])->GetAt(((CxIntArray*)ag->m_oaAtoms[z2])->GetAt(z4))); } } } delete ag; } mprintf("\n"); /********************************************************************************/ goto _nopseudomol; } _pseudomolnext: ti++; if (!tb2) { tb2 = true; mprintf("\n You may define custom element labels. This enables keeping apart\n atoms of the same type from different molecules/positions.\n\n"); tb = AskYesNo(" Keep the standard element labels (y) or define custom labels (n)? [yes] ",true); mprintf("\n"); } try { m2 = new CMolecule(); } catch(...) { m2 = NULL; } if (m2 == NULL) NewException((double)sizeof(CMolecule),__FILE__,__LINE__,__PRETTY_FUNCTION__); try { sm2 = new CSingleMolecule(); } catch(...) { sm2 = NULL; } if (sm2 == NULL) NewException((double)sizeof(CSingleMolecule),__FILE__,__LINE__,__PRETTY_FUNCTION__); m2->m_bPseudo = true; sm2->m_bPseudo = true; m2->m_iIndex = g_oaMolecules.GetSize(); sm2->m_iMolType = g_oaMolecules.GetSize(); sm2->m_iMolSMIndex = 0; m2->m_laSingleMolIndex.Add(g_oaSingleMolecules.GetSize()); g_oaMolecules.Add(m2); g_oaSingleMolecules.Add(sm2); mprintf(WHITE," >>> Pseudo-molecule %d (= molecule %d) >>>\n\n",ti,g_oaMolecules.GetSize()); /* if (ti == 1) mprintf(WHITE," You may define custom element labels. This enables keeping apart\n atoms of the same type from different molecules/positions.\n\n"); tb = AskYesNo(" Keep the standard element labels (y) or define custom labels (n)? [yes] ",true); mprintf("\n"); */ for (z=0;zm_bPseudo) continue; if (AskYesNo(" Use atoms from molecule %d (%s) (y/n)? [no] ",false,z+1,m->m_sName)) { mprintf("\n"); try { ag = new CAtomGroup(); } catch(...) { ag = NULL; } if (ag == NULL) NewException((double)sizeof(CAtomGroup),__FILE__,__LINE__,__PRETTY_FUNCTION__); if (AskYesNo(" Use all atoms (y) from %s or only certain atoms (n)? [yes] ",true,m->m_sName)) { ag->AddAllAtoms(m,false); } else { _pseudomolp1: AskString_ND(" Please enter atoms from %s to use (e.g. C1-3,H,O4): ",&buf,m->m_sName); if (!ag->ParseAtoms(m,buf)) goto _pseudomolp1; } ia.RemoveAll(); if (m->m_laSingleMolIndex.GetSize() > 1) { if (!AskYesNo(" Add selected atoms from all %s molecules (y), or only from certain molecules (n)? [yes] ",true,m->m_sName)) { _pseudomolil: AskString_ND(" Enter the %s molecules to use (range 1-%d, e.g. 1,3-6,8): ",&buf,m->m_sName,m->m_laSingleMolIndex.GetSize()); ia.RemoveAll(); if (!ParseIntList(buf,&ia)) goto _pseudomolil; for (z2=0;z2 m->m_laSingleMolIndex.GetSize())) { eprintf("Invalid number: %d (should be between 1 and %d).\n",ia[z2],m->m_laSingleMolIndex.GetSize()); goto _pseudomolil; } ia[z2]--; } } else { for (z2=0;z2m_laSingleMolIndex.GetSize();z2++) ia.Add(z2); } } else ia.Add(0); if (!tb) // Custom Labels { for (z2=0;z2m_baAtomType.GetSize();z2++) { _pmlagain: AskString(" How should %s from %s be labeled? [%s] ",&buf,(const char*)((CAtom*)g_oaAtoms[ag->m_baRealAtomType[z2]])->m_sName,(const char*)((CAtom*)g_oaAtoms[ag->m_baRealAtomType[z2]])->m_sName,m->m_sName,(const char*)((CAtom*)g_oaAtoms[ag->m_baRealAtomType[z2]])->m_sName); if (ContainsDigitOrSpecial(buf)) { eprintf("Digits and special characters in element labels not allowed.\n"); goto _pmlagain; } for (z3=0;z3m_sName) == 0) { ti2 = z3; goto _pseudomold1; } } // if (strlen(buf) > 7) // { // mprintf(" Element labels may only have up to 7 characters; truncating.\n"); // buf(7) = 0; // } mprintf(" Adding new element label \"%s\"...\n",(const char*)buf); try { at = new CAtom(); } catch(...) { at = NULL; } if (at == NULL) NewException((double)sizeof(CAtom),__FILE__,__LINE__,__PRETTY_FUNCTION__); at->m_iIndex = g_oaAtoms.GetSize(); at->m_pElement = ((CAtom*)g_oaAtoms[ag->m_baRealAtomType[z2]])->m_pElement; // memcpy(at->m_sName,buf,8); at->m_sName = (const char*)buf; at->m_iCount = ((CxIntArray*)ag->m_oaAtoms[z2])->GetSize() * ia.GetSize(); ti2 = g_oaAtoms.GetSize(); g_oaAtoms.Add(at); _pseudomold1: m2->m_iAtomGes += ((CxIntArray*)ag->m_oaAtoms[z2])->GetSize() * ia.GetSize(); for (z3=0;z3m_baAtomIndex.GetSize();z3++) { if (m2->m_baAtomIndex[z3] == ti2) { m2->m_waAtomCount[z3] += (unsigned short)(((CxIntArray*)ag->m_oaAtoms[z2])->GetSize() * ia.GetSize()); for (z4=0;z4<((CxIntArray*)ag->m_oaAtoms[z2])->GetSize();z4++) { for (z5=0;z5m_laSingleMolIndex[ia[z5]]]; for (z6=0;z6m_oaAtomOffset.GetSize();z6++) { for (z7=0;z7<((CxIntArray*)sm2->m_oaAtomOffset[z6])->GetSize();z7++) { if (((CxIntArray*)sm2->m_oaAtomOffset[z6])->GetAt(z7) == ((CxIntArray*)sm->m_oaAtomOffset[ag->m_baAtomType[z2]])->GetAt(((CxIntArray*)ag->m_oaAtoms[z2])->GetAt(z4))) { eprintf("Atom %s%d from %s[%d] is already in the pseudo-molecule; skipping.\n",(const char*)((CAtom*)g_oaAtoms[ag->m_baRealAtomType[z2]])->m_sName,((CxIntArray*)ag->m_oaAtoms[z2])->GetAt(z4)+1,m->m_sName,ia[z5]+1); m2->m_waAtomCount[z3]--; goto _pseudomolsk1; } } } // mprintf("Molecule %d, SM %d, Type %d, Atom %d: Line %d.\n",z,ia[z5],((CxIntArray*)sm->m_oaAtomOffset[z2])->GetAt(((CxIntArray*)ag->m_oaAtoms[z2])->GetAt(z4))); ((CxIntArray*)sm2->m_oaAtomOffset[z3])->Add(((CxIntArray*)sm->m_oaAtomOffset[ag->m_baAtomType[z2]])->GetAt(((CxIntArray*)ag->m_oaAtoms[z2])->GetAt(z4))); _pseudomolsk1:; } } goto _pseudomold2; } } m2->m_baAtomIndex.Add((unsigned char)ti2); sm2->m_baAtomIndex.Add((unsigned char)ti2); m2->m_waAtomCount.Add((unsigned short)(((CxIntArray*)ag->m_oaAtoms[z2])->GetSize() * ia.GetSize())); try { pia = new CxIntArray("gather():pia"); } catch(...) { pia = NULL; } if (pia == NULL) NewException((double)sizeof(CxIntArray),__FILE__,__LINE__,__PRETTY_FUNCTION__); sm2->m_oaAtomOffset.Add(pia); for (z4=0;z4<((CxIntArray*)ag->m_oaAtoms[z2])->GetSize();z4++) { for (z5=0;z5m_laSingleMolIndex[ia[z5]]]; for (z6=0;z6m_oaAtomOffset.GetSize();z6++) { for (z7=0;z7<((CxIntArray*)sm2->m_oaAtomOffset[z6])->GetSize();z7++) { if (((CxIntArray*)sm2->m_oaAtomOffset[z6])->GetAt(z7) == ((CxIntArray*)sm->m_oaAtomOffset[ag->m_baAtomType[z2]])->GetAt(((CxIntArray*)ag->m_oaAtoms[z2])->GetAt(z4))) { eprintf("Atom %s%d from %s[%d] is already in the pseudo-molecule; skipping.\n",(const char*)((CAtom*)g_oaAtoms[ag->m_baRealAtomType[z2]])->m_sName,((CxIntArray*)ag->m_oaAtoms[z2])->GetAt(z4)+1,m->m_sName,ia[z5]+1); m2->m_waAtomCount[m2->m_waAtomCount.GetSize()-1]--; goto _pseudomolsk2; } } } pia->Add(((CxIntArray*)sm->m_oaAtomOffset[ag->m_baAtomType[z2]])->GetAt(((CxIntArray*)ag->m_oaAtoms[z2])->GetAt(z4))); _pseudomolsk2:; } } _pseudomold2:; } } else // If not custom labels { for (z2=0;z2m_baAtomType.GetSize();z2++) { for (z4=0;z4m_baAtomIndex.GetSize();z4++) { if (m2->m_baAtomIndex[z4] == ag->m_baRealAtomType[z2]) { m2->m_waAtomCount[z4] += (unsigned short)(((CxIntArray*)ag->m_oaAtoms[z2])->GetSize() * ia.GetSize()); pia = (CxIntArray*)sm2->m_oaAtomOffset[z4]; goto _pmafound2; } } m2->m_iAtomGes += ((CxIntArray*)ag->m_oaAtoms[z2])->GetSize() * ia.GetSize(); m2->m_baAtomIndex.Add(ag->m_baRealAtomType[z2]); sm2->m_baAtomIndex.Add(ag->m_baRealAtomType[z2]); m2->m_waAtomCount.Add((unsigned short)(((CxIntArray*)ag->m_oaAtoms[z2])->GetSize() * ia.GetSize())); try { pia = new CxIntArray("gather():pia"); } catch(...) { pia = NULL; } if (pia == NULL) NewException((double)sizeof(CxIntArray),__FILE__,__LINE__,__PRETTY_FUNCTION__); sm2->m_oaAtomOffset.Add(pia); _pmafound2: for (z4=0;z4<((CxIntArray*)ag->m_oaAtoms[z2])->GetSize();z4++) { for (z5=0;z5m_laSingleMolIndex[ia[z5]]]; for (z6=0;z6m_oaAtomOffset.GetSize();z6++) { for (z7=0;z7<((CxIntArray*)sm2->m_oaAtomOffset[z6])->GetSize();z7++) { if (((CxIntArray*)sm2->m_oaAtomOffset[z6])->GetAt(z7) == ((CxIntArray*)sm->m_oaAtomOffset[ag->m_baAtomType[z2]])->GetAt(((CxIntArray*)ag->m_oaAtoms[z2])->GetAt(z4))) { eprintf("Atom %s%d from %s[%d] is already in the pseudo-molecule; skipping.\n",(const char*)((CAtom*)g_oaAtoms[ag->m_baRealAtomType[z2]])->m_sName,((CxIntArray*)ag->m_oaAtoms[z2])->GetAt(z4)+1,m->m_sName,ia[z5]+1); m2->m_waAtomCount[m2->m_waAtomCount.GetSize()-1]--; goto _pseudomolsk3; } } } pia->Add(((CxIntArray*)sm->m_oaAtomOffset[ag->m_baAtomType[z2]])->GetAt(((CxIntArray*)ag->m_oaAtoms[z2])->GetAt(z4))); _pseudomolsk3:; } } } } delete ag; if (AskYesNo(" Use another set of atoms from %s (y/n)? [no] ",false,m->m_sName)) { try { ag = new CAtomGroup(); } catch(...) { ag = NULL; } if (ag == NULL) NewException((double)sizeof(CAtomGroup),__FILE__,__LINE__,__PRETTY_FUNCTION__); goto _pseudomolp1; } } mprintf("\n"); } _nopseudomol: m2->BuildName(); mprintf(WHITE," <<< Pseudo-molecule %d (= molecule %d) defined as %s <<<\n\n",ti,g_oaMolecules.GetSize(),m2->m_sName); if (AskYesNo(" Define another pseudo-molecule (y/n)? [no] ",false)) goto _pseudomolnext; mprintf(WHITE,"\n The following pseudo-molecules have been defined:\n"); mprintf(" (note: pseudo-molecules start with a $ sign)\n\n"); ti = 0; for (z=0;zm_bPseudo) { ti++; mprintf(" %d.) Molecule %d - %s\n",ti,z+1,m->m_sName); } } mprintf(WHITE,"\n Defining virtual atom #1 as molecular Center of Geometry:\n"); for (z0=0;z0m_bPseudo) continue; mprintf(" - %s...\n",m->m_sName); va = AddVirtualAtom(z0); va->m_iMode = 0; va->m_oCenterAtoms.AddAllAtoms((CMolecule*)g_oaMolecules[va->m_iMolecule],false); va->m_faWeight.SetSize(va->m_oCenterAtoms.m_iAtomGes); for (z=0;zm_oCenterAtoms.m_iAtomGes;z++) va->m_faWeight[z] = 1.0; va->m_fGesWeight = (double)va->m_oCenterAtoms.m_iAtomGes; } mprintf(WHITE,"\n Defining virtual atom #2 as molecular Center of Mass:\n"); for (z0=0;z0m_bPseudo) continue; mprintf(" - %s...\n",m->m_sName); va = AddVirtualAtom(z0); va->m_iMode = 0; va->m_oCenterAtoms.AddAllAtoms((CMolecule*)g_oaMolecules[va->m_iMolecule],false); va->m_faWeight.SetSize(va->m_oCenterAtoms.m_iAtomGes); z3 = 0; tf2 = 0; for (z=0;zm_oCenterAtoms.m_baAtomType.GetSize();z++) { tf = ((CAtom*)g_oaAtoms[va->m_oCenterAtoms.m_baRealAtomType[z]])->m_pElement->m_fMass; for (z2=0;z2<((CxIntArray*)va->m_oCenterAtoms.m_oaAtoms[z])->GetSize();z2++) { va->m_faWeight[z3] = tf; tf2 += tf; z3++; } } va->m_fGesWeight = tf2; if (va->m_fGesWeight == 0) { eprintf(" Molecule %s has total mass of zero. Defining #2 as Center of Geometry.\n",m->m_sName); for (z=0;zm_oCenterAtoms.m_iAtomGes;z++) va->m_faWeight[z] = 1.0; va->m_fGesWeight = (double)va->m_oCenterAtoms.m_iAtomGes; } } } } mprintf(WHITE,"\n Defining molecular dipole vectors:\n\n"); mprintf(" The last virtual atom of each molecule is defined as the tip of the dipole vector\n"); mprintf(" starting in center of mass (#2). 1 Debye corresponds to 100pm of vector length.\n"); mprintf(" Only useful if dipole/charge data is provided. Otherwise vector has always length of zero.\n\n"); for (z0=0;z0 #%d in %s ...\n",m->m_laVirtualAtoms.GetSize()+1,m->m_sName); va = AddVirtualAtom(z0); va->m_iMode = 2; } mprintf(GREEN,"\n>>> %d virtual atoms have been defined: >>>\n",g_oaVirtualAtoms.GetSize()); for (z0=0;z0m_laVirtualAtoms.GetSize();z++) { va = (CVirtualAtom*)g_oaVirtualAtoms[((CMolecule*)g_oaMolecules[z0])->m_laVirtualAtoms[z]]; if (va->m_iMolVirtAtom < 2) { mprintf(WHITE,"\n #%d in %s: %s.",va->m_iMolVirtAtom+1,((CMolecule*)g_oaMolecules[va->m_iMolecule])->m_sName,(va->m_iMolVirtAtom==0)?"Center of Geometry":"Center of Mass"); if (va->m_iMolVirtAtom == 1) mprintf("\n"); continue; } if (va->m_iMode < 2) { mprintf(WHITE,"\n #%d in %s - defined through %s\n",va->m_iMolVirtAtom+1,((CMolecule*)g_oaMolecules[va->m_iMolecule])->m_sName,(va->m_iMode==0)?"center:":"distance/angle/dihedral:"); if (va->m_iMode == 0) { if (!((CMolecule*)g_oaMolecules[z0])->m_bPseudo || (z > 1)) { z4 = 0; for (z2=0;z2m_oCenterAtoms.m_baAtomType.GetSize();z2++) { for (z3=0;z3<((CxIntArray*)va->m_oCenterAtoms.m_oaAtoms[z2])->GetSize();z3++) { mprintf(" - %2s%-3d Weight %.2f%c\n",(const char*)((CAtom*)g_oaAtoms[va->m_oCenterAtoms.m_baRealAtomType[z2]])->m_sName,((CxIntArray*)va->m_oCenterAtoms.m_oaAtoms[z2])->GetAt(z3)+1,va->m_faWeight[z4]/va->m_fGesWeight*100.0,'%'); z4++; } } } else mprintf(" (pseudo-molecule, skipping atoms)\n"); } else { mprintf(" - Distance #%d-%s%d = %.2f pm\n",z+1,(const char*)((CAtom*)g_oaAtoms[va->m_iRealAtomType[0]])->m_sName,va->m_iAtom[0]+1,va->m_fValues[0]); mprintf(" - Angle #%d-%s%d-%s%d = %.2f degree\n",z+1,(const char*)((CAtom*)g_oaAtoms[va->m_iRealAtomType[0]])->m_sName,va->m_iAtom[0]+1,(const char*)((CAtom*)g_oaAtoms[va->m_iRealAtomType[1]])->m_sName,va->m_iAtom[1]+1,va->m_fValues[1]*180.0/Pi); mprintf(" - Dihedral #%d-%s%d-%s%d-%s%d = %.2f degree\n",z+1,(const char*)((CAtom*)g_oaAtoms[va->m_iRealAtomType[0]])->m_sName,va->m_iAtom[0]+1,(const char*)((CAtom*)g_oaAtoms[va->m_iRealAtomType[1]])->m_sName,va->m_iAtom[1]+1,(const char*)((CAtom*)g_oaAtoms[va->m_iRealAtomType[2]])->m_sName,va->m_iAtom[2]+1,va->m_fValues[2]*180.0/Pi); } } else if (va->m_iMode == 2) { mprintf(WHITE,"\n #%d in %s - tip of molecular dipole vector starting in #2.\n",va->m_iMolVirtAtom+1,((CMolecule*)g_oaMolecules[va->m_iMolecule])->m_sName); } } } mprintf(GREEN,"\n<<< End of virtual atoms <<<\n\n"); if (g_bPeriodic) g_TimeStep.UniteMolecules(false); g_TimeStep.CalcCenters(); g_bFoldAtomwise = false; if (g_bPeriodic) g_TimeStep.FoldMolecules(); BuildAtomIndices(); // g_TimeStep.WritePOV("step.pov"); mprintf(WHITE,"\n>>> List of functions <<<\n\n"); DumpAnalyses(); mprintf(" (You may specify multiple analyses at once, but\n"); mprintf(" the safe way is to perform only one kind of analysis at a time.)\n"); _fncinput: inpprintf("! Which functions to compute (comma separated)?\n"); mprintf("\n Which functions to compute (comma separated)? "); myget(&buf); mprintf("\n"); if (!ParseFunctions(buf)) { eprintf("Invalid input.\n"); inpprintf("! Invalid input.\n"); goto _fncinput; } mprintf("\n"); if (g_bRegionAnalysis) { if (!(g_bRDF || g_bSDF || g_bADF || g_bDDF || g_bCDF || g_bRevSDF || g_bDens)) { eprintf(" Region-specific analysis needs to be applied to some static analysis (e.g., RDF).\n\n"); return false; } g_iaSMRegion.SetSize(g_oaSingleMolecules.GetSize()); for (z=0;zParse(); } if (g_bVoro) { try { g_pVoroWrapper = new CVoroWrapper(); } catch(...) { g_pVoroWrapper = NULL; } if (g_pVoroWrapper == NULL) NewException((double)sizeof(CVoroWrapper),__FILE__,__LINE__,__PRETTY_FUNCTION__); g_pVoroWrapper->Parse(); } if (g_bTegri && (g_pTetraPak == NULL)) { try { g_pVoroWrapper = new CVoroWrapper(); } catch(...) { g_pVoroWrapper = NULL; } if (g_pVoroWrapper == NULL) NewException((double)sizeof(CVoroWrapper),__FILE__,__LINE__,__PRETTY_FUNCTION__); try { g_pTetraPak = new CTetraPak(); } catch(...) { g_pTetraPak = NULL; } if (g_pTetraPak == NULL) NewException((double)sizeof(CTetraPak),__FILE__,__LINE__,__PRETTY_FUNCTION__); g_pTetraPak->Parse(); } /* if (g_bSFac) { try { g_pSFac = new CStructureFactor(); } catch(...) { g_pSFac = NULL; } if (g_pSFac == NULL) NewException((double)sizeof(CStructureFactor),__FILE__,__LINE__,__PRETTY_FUNCTION__); g_pSFac->Parse(); }*/ if (g_bROA) { try { g_pROAEngine = new CROAEngine(); } catch(...) { g_pROAEngine = NULL; } if (g_pROAEngine == NULL) NewException((double)sizeof(CROAEngine),__FILE__,__LINE__,__PRETTY_FUNCTION__); if (!g_pROAEngine->Parse()) return false; } if (g_bFixedPlProj) { try { g_pFixedPlProj = new CFixedPlProj(); } catch(...) { g_pFixedPlProj = NULL; } if (g_pFixedPlProj == NULL) NewException((double)sizeof(CFixedPlProj),__FILE__,__LINE__,__PRETTY_FUNCTION__); if (!g_pFixedPlProj->Parse()) return false; } if (g_bOrder) { g_pOrderEngine = new COrderEngine(); if (!g_pOrderEngine->Parse(&g_TimeStep)) return false; } if (g_bAggregation) { mprintf(WHITE,">>> Selection of Aggregation Functions >>>\n\n"); g_bDACF = AskYesNo(" Compute Dimer Existence Autocorrelation Functions (DACFs) (y/n)? [yes] ",true); g_bDLDF = AskYesNo(" Compute Dimer Lifetime Distribution Functions (DLDFs) (y/n)? [no] ",false); g_bDDisp = AskYesNo(" Compute Dimer Displacement Functions / Pair Diffusion (y/n)? [no] ",false); if (g_bDDisp) { g_bPairMSD = AskYesNo(" Compute Pair Mean Square Displacement (Pair Diffusion) (y/n)? [yes] ",true); g_bDLDisp = AskYesNo(" Compute combined Dimer Lifetime/Displacement Function (DLDisp) (y/n)? [yes] ",true); } else { g_bDLDisp = false; g_bPairMSD = false; } mprintf(WHITE,"\n<<< Selection of Aggregation Functions <<<\n\n"); } if (g_bNbExchange) { mprintf(WHITE,">>> Selection of Neighborhood Exchange Functions >>>\n\n"); mprintf(WHITE,"\n<<< Selection of Neighborhood Exchange Functions <<<\n\n"); } if (g_bAdvanced2) { if (g_bRDyn || g_bIRSpec) g_bRDynCacheMode = AskYesNo(" Use RDyn cached mode (do this unless there are problems) (y/n)? [yes] ",true); if (g_bMSD) g_bMSDCacheMode = AskYesNo(" Use MSD cached mode (do this unless there are problems) (y/n)? [yes] ",true); } else { g_bRDynCacheMode = true; g_bMSDCacheMode = true; } if (g_bACF) { // mprintf(YELLOW,">>> Select Autocorrelation Functions >>>\n\n"); if (!g_bPowerSpec) g_bVACF = AskYesNo(" Calculate velocity autocorrelation function / power spectra (y/n)? [yes] ",true); else g_bVACF = true; if (g_bVACF) g_bUseVelocities = true; /* if (g_bBetaFeatures) g_bBondACF = AskYesNo(" Calculate bond vibration spectra (y/n)? [no] ",false); else*/ g_bBondACF = false; /* g_bDipACF = AskYesNo(" Calculate dipole autocorrelation function / IR spectra (y/n)? [no] ",false); if (g_bDipACF) g_bDipole = true;*/ // mprintf(YELLOW,"\n<<< End of Select Autocorrelation Functions <<<\n\n"); } if (g_bBondACF) { mprintf(WHITE,">>> Bond vibration spectra >>>\n\n"); if (g_iTrajSteps != -1) g_iBondACFDepth = AskUnsignedInteger(" Enter bond ACF depth in time steps: [%d] ",g_iTrajSteps/2,g_iTrajSteps/2); else g_iBondACFDepth = AskUnsignedInteger(" Enter bond ACF depth in time steps: [%d] ",4096,4096); ti = CalcFFTSize(g_iBondACFDepth,false); if (g_iBondACFDepth != ti) { mprintf(WHITE,"\n The next \"fast\" size for FFT is %d. Using this instead of %d as size.\n",ti,g_iBondACFDepth); g_iBondACFDepth = ti; } g_bBondACFNormalize = AskYesNo(" Normalize all bond ACFs (removes intensity info for the peaks) (y/n)? [no] ",false); g_bBondACFSymmetrize = AskYesNo(" Symmetrize all bond ACFs (y/n)? [no] ",false); g_bBondACFWindow = AskYesNo(" Apply window function to bond ACFs (y/n)? [yes] ",true); g_bBondACFDebug = AskYesNo(" Write out bond ACF debug data (y/n)? [no] ",false); mprintf(WHITE,"\n<<< End of Bond vibration spectra <<<\n\n"); } if (g_bRDyn || g_bIRSpec || g_bBondACF || g_bVACF) { if (g_bAdvanced2) g_bACFFFT = AskYesNo(" Use fourier transform for autocorrelation (much faster) (y/n)? [yes] ",true); else g_bACFFFT = true; } else g_bACFFFT = true; if (g_bCDF || g_bPlProj || g_bDipDF || g_bRDF || g_bVHDF || g_bSDF || g_bPlDF || g_bLiDF || g_bRevSDF || g_bADF || g_bDDF || g_bSaveRefEnv || g_bCutCluster || g_bCond || g_bNbAnalysis) { if (g_oaMolecules.GetSize() > 1) { // sprintf(buf,"\n Which of the molecules should be the reference molecule ("); buf.sprintf("\n Which of the molecules should be the reference molecule ("); for (z=0;zm_sName,z+1); // strcat(buf,buf2); // if (z < g_oaMolecules.GetSize()-1) // strcat(buf,", "); buf2.sprintf("%s=%d",((CMolecule*)g_oaMolecules[z])->m_sName,z+1); buf.strcat(buf2); if (z < g_oaMolecules.GetSize()-1) buf.strcat(", "); } // strcat(buf,")? "); buf.strcat(")? "); g_iFixMol = (char)AskRangeInteger_ND("%s",1,g_oaMolecules.GetSize(),(const char*)buf) - 1; } else g_iFixMol = 0; mprintf(WHITE,"\n %s is the reference molecule.\n\n",((CMolecule*)g_oaMolecules[g_iFixMol])->m_sName); } else g_iFixMol = -1; if (g_bSaveRefEnv) { mprintf(YELLOW,">>> Save environment of the reference molecule >>>\n\n"); g_bSaveRefWithEnv = AskYesNo(" Save the reference molecule itself (y/n)? [yes] ",true); g_bRefEnvCenter = AskYesNo(" Center the reference molecule in the box (y/n)? [yes] ",true); if (g_bRefEnvCenter) { mprintf("\n The first reference atom will be put into the middle of the box.\n\n"); g_bRefEnvFix = AskYesNo(" Fix rotational freedom of the reference molecule (y/n)? [no] ",false); if (g_bRefEnvFix) { mprintf("\n The 2nd reference atom will be put onto the positive X axis,\n"); mprintf(" and the 3rd reference atom into the X-Y plane with positive Y values.\n\n"); } mprintf(WHITE," You will be asked for the reference atom(s) lateron.\n\n"); } if (((CMolecule*)g_oaMolecules[g_iFixMol])->m_laSingleMolIndex.GetSize() > 1) g_iSaveRefMol = (unsigned char)AskRangeInteger(" Which representative of the reference molecules to use (1-%d)? [1] ",1,((CMolecule*)g_oaMolecules[g_iFixMol])->m_laSingleMolIndex.GetSize(),1,((CMolecule*)g_oaMolecules[g_iFixMol])->m_laSingleMolIndex.GetSize()) - 1; else g_iSaveRefMol = 0; mprintf(WHITE,"\nPlease choose mode for neighborhood detection:\n\n"); inpprintf("! Please choose mode for neighborhood detection:\n"); mprintf(" 1.) Search neighbors once in the beginning and always show those.\n"); mprintf(" 2.) Search neighbors in every step and show the current neighbors.\n"); mprintf(" (Warning: Neighbor count differs from step to step - be aware.\n"); mprintf(" 3.) Find the frequentiest neighbors over all steps and always show those.\n\n"); mprintf(WHITE," Please note: "); mprintf("Programs such as VMD cannot handle variable atom count \n"); mprintf(" along a trajectory and will therefore not work properly with mode 2!\n\n"); g_iNbhMode = AskRangeInteger(" Choice (1-3): [3] ",1,3,3); mprintf(YELLOW,"\n<<< End of Save environment of the reference molecule <<<\n\n"); } if (g_bCutCluster) { mprintf(WHITE,">>> Cut clusters >>>\n\n"); g_bSaveRefWithEnv = AskYesNo(" Show reference molecule itself (y/n)? [yes] ",true); g_bRefEnvCenter = AskYesNo(" Center reference molecule in the box (y/n)? [yes] ",true); if (g_bRefEnvCenter) g_bRefEnvFix = AskYesNo(" Fix rotational freedom of the reference molecule (y/n)? [no] ",false); _clustercount: g_iClusterCount = AskUnsignedInteger(" How many clusters to create? [100] ",100); g_iClusterSteps = AskUnsignedInteger(" How many time steps to use for cluster creation? [%d] ",g_iTrajSteps,g_iTrajSteps); mprintf("\nCreating cluster distribution..."); for (z=0;z 500) { eprintf("Error: Too few molecules / time steps for requested cluster count.\n"); goto _clustercount; } ti = ((((unsigned long)rand()%16384)+rand()*16384) % g_iClusterSteps) + 1; ti2 = rand()%((CMolecule*)g_oaMolecules[g_iFixMol])->m_laSingleMolIndex.GetSize(); for (z2=0;z2m_sName); mprintf(" The first reference atom will be put into the center.\n"); mprintf(" The 2nd reference atom will be put onto the positive X axis.\n"); mprintf(" The 3rd reference atom will be put into the X-Y plane with positive Y values.\n\n"); mprintf(" Please enter three comma-separated reference atoms (e.g. \"C1,H2,O1\"): "); inpprintf("! Please enter three comma-separated reference atoms (e.g. \"C1,H2,O1\"):\n"); myget(&buf); if (!ParseRefSystem(g_iFixMol,buf,3)) goto _ref3again; for (z=1;z<3;z++) { for (z2=0;z2m_sName,g_iFixAtom[0]+1,(const char*)((CAtom*)g_oaAtoms[g_iFixRealAtomType[0]])->m_sName,g_iFixAtom[1]+1,(const char*)((CAtom*)g_oaAtoms[g_iFixRealAtomType[1]])->m_sName,g_iFixAtom[2]+1,(const char*)((CAtom*)g_oaAtoms[g_iFixRealAtomType[2]])->m_sName); mprintf("\n"); if ((((CMolecule*)g_oaMolecules[g_iFixMol])->m_laSingleMolIndex.GetSize() > 1) && g_bAdvanced2) { g_iRefMolNum = AskRangeInteger(" Which representative of the reference molecule to use (1-%d)? [1] ",1,((CMolecule*)g_oaMolecules[g_iFixMol])->m_laSingleMolIndex.GetSize(),1,((CMolecule*)g_oaMolecules[g_iFixMol])->m_laSingleMolIndex.GetSize()) - 1; mprintf("\n"); } else g_iRefMolNum = 0; } else if (g_bRevSDF) { g_iRefSystemDim = 2; _ref2again: mprintf(" Please enter two reference atoms (e.g. C1,H3): "); inpprintf("! Please enter two reference atoms (e.g. C1,H3):\n"); myget(&buf); if (!ParseRefSystem(g_iFixMol,buf,2)) goto _ref2again; if ((g_iFixAtomType[0] == g_iFixAtomType[1]) && (g_iFixAtom[0] == g_iFixAtom[1])) { eprintf("Please enter two different atoms.\n\n"); inpprintf("! Please enter two different atoms.\n"); goto _ref2again; } mprintf("\n"); mprintf(WHITE,"Reference axis: Fixing in %s the %d. %s and the %d. %s atom.\n",((CMolecule*)g_oaMolecules[g_iFixMol])->m_sName,g_iFixAtom[0]+1,(const char*)((CAtom*)g_oaAtoms[g_iFixRealAtomType[0]])->m_sName,g_iFixAtom[1]+1,(const char*)((CAtom*)g_oaAtoms[g_iFixRealAtomType[1]])->m_sName); mprintf("\n"); } else if (g_bVHDF || g_bRDF || g_bADF || g_bPlDF || g_bLiDF || g_bDDF || g_bSaveRefEnv || g_bCutCluster) // Fuer Verteilungsfunktion: Welches Atom im Ursprung { g_iRefSystemDim = 1; if (g_bAdvanced2) { _ref1again: mprintf(" Please enter the atom to put into the box center (e.g. C3): [center of mass] "); inpprintf("! Please enter the atom to put into the box center (e.g. C3): [center of mass]\n"); myget(&buf); if (strlen(buf)==0) { if (!ParseRefSystem(g_iFixMol,"#2",1)) { eprintf("Internal error.\n"); inpprintf("! Internal error.\n"); abort(); } } else if (!ParseRefSystem(g_iFixMol,buf,1)) goto _ref1again; mprintf("\n"); mprintf(WHITE,"Reference atom: Fixing in %s the %d. %s atom.\n",((CMolecule*)g_oaMolecules[g_iFixMol])->m_sName,g_iFixAtom[0]+1,(const char*)((CAtom*)g_oaAtoms[g_iFixRealAtomType[0]])->m_sName); mprintf("\n"); } else { if (!ParseRefSystem(g_iFixMol,"#2",1)) { eprintf("Internal error.\n"); inpprintf("! Internal error.\n"); abort(); } } } else if (g_iFixMol != -1) { g_iRefSystemDim = 1; if (!ParseRefSystem(g_iFixMol,"#2",1)) { eprintf("Internal error.\n"); abort(); } mprintf(" Reference atom: Fixing in %s the %d. %s atom.\n\n",((CMolecule*)g_oaMolecules[g_iFixMol])->m_sName,g_iFixAtom[0]+1,(const char*)((CAtom*)g_oaAtoms[g_iFixRealAtomType[0]])->m_sName); } if (g_bSaveRefEnv || g_bCutCluster) { mprintf(WHITE,">>> Neighborhood Definition >>>\n\n"); try { g_pNbSet = new CNbSet(); } catch(...) { g_pNbSet = NULL; } if (g_pNbSet == NULL) NewException((double)sizeof(CNbSet),__FILE__,__LINE__,__PRETTY_FUNCTION__); g_pNbSet->Parse(g_iFixMol); mprintf(WHITE,"\n<<< End of Neighborhood Definition <<<\n\n"); if (g_bSaveRefEnv) { if (AskYesNo(" Create a temporal development overlay (TDO) plot (y/n)? [no] ",false)) { g_bTDO = true; g_laTDOSteps.RemoveAll(); if (AskYesNo(" Use equidistant intervals (y) or specify each point (n) (y/n)? [yes] ",true)) { g_bTDOEqui = true; g_iTDOCount = AskUnsignedInteger(" Enter the overlay count: [5] ",5); g_iTDOStart = AskUnsignedInteger(" Enter the starting timestep: [0] ",0); g_iTDOStride = AskUnsignedInteger(" Enter the overlay distance in steps: [1000] ",1000); for (z=0;z>> Observation %d >>>\n\n",g_oaObserv.GetSize()+1); try { o = new CObservation(); } catch(...) { o = NULL; } if (o == NULL) NewException((double)sizeof(CObservation),__FILE__,__LINE__,__PRETTY_FUNCTION__); o->m_pConditions = NULL; g_oaObserv.Add(o); o->m_bTimeDev = false; if (g_bAggregation || g_bNbExchange) { o->m_bSelf = false; o->m_bOthers = false; } else if (g_bNbAnalysis) { o->m_bSelf = false; o->m_bOthers = true; mprintf(" Performing this observation intermolecular.\n\n"); } else if (g_iFixMol != -1) { if (AskRangeInteger(" Perform this observation intramolecular (within the reference molecule) (0) or intermolecular (1)? [1] ",0,1,1) == 1) { o->m_bSelf = false; o->m_bOthers = true; } else { o->m_bSelf = true; o->m_bOthers = false; } mprintf("\n"); } else { o->m_bSelf = false; o->m_bOthers = true; } if (o->m_bOthers) { if (g_bCDF) { mprintf(WHITE," Please note: "); mprintf("Although you specified this observation to be intermolecular, you may of course\n"); mprintf(" choose atoms from RM only (or OM only), which will yield an intramolecular quantity.\n\n"); } if (g_bCDF) o->m_bSecondShowMol = AskYesNo(" CDF: Perform a three-body analysis (y) or observe one molecule at a time (n)? [no] ",false); else o->m_bSecondShowMol = false; if (o->m_bSecondShowMol) { mprintf(WHITE,"\n You have to select two observed molecules (OMs):\n"); mprintf(" The first CDF channel observes the 1st OM, the second channel observes the 2nd OM.\n\n"); } if (g_oaMolecules.GetSize() > 1) { _obsmolagain: if (o->m_bSecondShowMol) // sprintf(buf," Which 1st molecule should be observed ("); buf.sprintf(" Which 1st molecule should be observed ("); else // sprintf(buf," Which molecule should be observed ("); buf.sprintf(" Which molecule should be observed ("); for (z=0;zm_sName,z+1); // strcat(buf,buf2); // if (z < g_oaMolecules.GetSize()-1) // strcat(buf,", "); buf2.sprintf("%s=%d",((CMolecule*)g_oaMolecules[z])->m_sName,z+1); buf.strcat(buf2); if (z < g_oaMolecules.GetSize()-1) buf.strcat(", "); } // strcat(buf,")? "); buf.strcat(")? "); o->m_iShowMol = AskRangeInteger_ND("%s",1,g_oaMolecules.GetSize(),(const char*)buf) - 1; if ((((CMolecule*)g_oaMolecules[o->m_iShowMol])->m_laSingleMolIndex.GetSize() == 1) && (o->m_iShowMol == g_iFixMol)) { eprintf("Error: There is only 1 molecule of %s.\n--> Intermolecular observation between %s and %s not possible.\n\n",((CMolecule*)g_oaMolecules[o->m_iShowMol])->m_sName,((CMolecule*)g_oaMolecules[o->m_iShowMol])->m_sName,((CMolecule*)g_oaMolecules[o->m_iShowMol])->m_sName); goto _obsmolagain; } } else { mprintf(" Only one molecule type, choosing %s as observed molecule (OM).\n",((CMolecule*)g_oaMolecules[0])->m_sName); o->m_iShowMol = 0; } o->m_iShowMolCount = ((CMolecule*)g_oaMolecules[o->m_iShowMol])->m_laSingleMolIndex.GetSize(); if (o->m_bSecondShowMol) { if (g_oaMolecules.GetSize() > 1) { _obsmol2again: // sprintf(buf," Which 2nd molecule should be observed ("); buf.sprintf(" Which 2nd molecule should be observed ("); for (z=0;zm_sName,z+1); // strcat(buf,buf2); // if (z < g_oaMolecules.GetSize()-1) // strcat(buf,", "); buf2.sprintf("%s=%d",((CMolecule*)g_oaMolecules[z])->m_sName,z+1); buf.strcat(buf2); if (z < g_oaMolecules.GetSize()-1) buf.strcat(", "); } // strcat(buf,")? "); buf.strcat(")? "); o->m_iShowMol2 = AskRangeInteger_ND("%s",1,g_oaMolecules.GetSize(),(const char*)buf) - 1; if ((((CMolecule*)g_oaMolecules[o->m_iShowMol2])->m_laSingleMolIndex.GetSize() == 1) && (o->m_iShowMol2 == g_iFixMol)) { eprintf("Error: There is only 1 molecule of %s.\n --> Intermolecular observation between %s and %s not possible.\n\n",((CMolecule*)g_oaMolecules[o->m_iShowMol2])->m_sName,((CMolecule*)g_oaMolecules[o->m_iShowMol2])->m_sName,((CMolecule*)g_oaMolecules[o->m_iShowMol2])->m_sName); goto _obsmol2again; } } else o->m_iShowMol2 = 0; o->m_iShowMol2Count = ((CMolecule*)g_oaMolecules[o->m_iShowMol2])->m_laSingleMolIndex.GetSize(); if (o->m_iShowMol == o->m_iShowMol2) o->m_bExclude1eq2 = AskYesNo(" Exclude the case \"1st OM = 2nd OM\" (y/n)? [yes] ",true); else o->m_bExclude1eq2 = false; } } else { o->m_iShowMol = -1; o->m_iShowMol2 = -1; o->m_bSecondShowMol = false; o->m_iShowMolCount = 1; } // buf[0] = 0; buf = ""; if ((o->m_bSecondShowMol) && (o->m_iShowMol != o->m_iShowMol2)) // sprintf(buf," of %s / %s / %s",((CMolecule*)g_oaMolecules[g_iFixMol])->m_sName,((CMolecule*)g_oaMolecules[o->m_iShowMol])->m_sName,((CMolecule*)g_oaMolecules[o->m_iShowMol2])->m_sName); buf.sprintf(" of %s / %s / %s",((CMolecule*)g_oaMolecules[g_iFixMol])->m_sName,((CMolecule*)g_oaMolecules[o->m_iShowMol])->m_sName,((CMolecule*)g_oaMolecules[o->m_iShowMol2])->m_sName); else if ((o->m_iShowMol != -1) && (g_iFixMol != -1)) // sprintf(buf," of %s / %s",((CMolecule*)g_oaMolecules[g_iFixMol])->m_sName,((CMolecule*)g_oaMolecules[o->m_iShowMol])->m_sName); buf.sprintf(" of %s / %s",((CMolecule*)g_oaMolecules[g_iFixMol])->m_sName,((CMolecule*)g_oaMolecules[o->m_iShowMol])->m_sName); else if (g_iFixMol != -1) // sprintf(buf," of %s",((CMolecule*)g_oaMolecules[g_iFixMol])->m_sName); buf.sprintf(" of %s",((CMolecule*)g_oaMolecules[g_iFixMol])->m_sName); if (g_iFixMol != -1) { if (g_bAdvanced2) { if (AskYesNo(" Observe only certain molecules%s (y/n)? [no] ",false,(const char*)buf)) { o->m_bObsCertain = true; if (!g_bCDF && (g_bRDF || g_bADF || g_bDDF || g_bDipDF)) o->m_bDecompDist = AskYesNo(" Decompose distribution functions into contributions from molecules (y/n)? [yes] ",true); if (((CMolecule*)g_oaMolecules[g_iFixMol])->m_laSingleMolIndex.GetSize() > 1) { mprintf(" Which %s molecules (RM) to take into account (e.g. 1,3-7)? [all] ",((CMolecule*)g_oaMolecules[g_iFixMol])->m_sName); inpprintf("! Which %s molecules (RM) to take into account (e.g. 1,3-7)? [all]\n",((CMolecule*)g_oaMolecules[g_iFixMol])->m_sName); myget(&buf); if (strlen(buf)==0) { for (z=0;z<((CMolecule*)g_oaMolecules[o->m_iShowMol])->m_laSingleMolIndex.GetSize();z++) o->m_waObsRefList.Add((unsigned short)z); } else { ParseIntList(buf,&o->m_waObsRefList); for (z=0;zm_waObsRefList.GetSize();z++) o->m_waObsRefList[z]--; } } else o->m_waObsRefList.Add(0); // mprintf("RefList[0] = %d\n",o->m_waObsRefList[0]); if (o->m_iShowMol != -1) { if (((CMolecule*)g_oaMolecules[o->m_iShowMol])->m_laSingleMolIndex.GetSize() > 1) { mprintf(" Which %s molecules (OM) to take into account (e.g. 1,3-7)? [all] ",((CMolecule*)g_oaMolecules[o->m_iShowMol])->m_sName); inpprintf("! Which %s molecules (OM) to take into account (e.g. 1,3-7)? [all]\n",((CMolecule*)g_oaMolecules[o->m_iShowMol])->m_sName); myget(&buf); if (strlen(buf)==0) { for (z=0;z<((CMolecule*)g_oaMolecules[o->m_iShowMol])->m_laSingleMolIndex.GetSize();z++) o->m_waObsShowList.Add((unsigned short)z); } else { ParseIntList(buf,&o->m_waObsShowList); for (z=0;zm_waObsShowList.GetSize();z++) o->m_waObsShowList[z]--; } } else o->m_waObsShowList.Add(0); } else o->m_waObsShowList.Add(0); // Dummy if (o->m_bSecondShowMol) { if (o->m_iShowMol2 != -1) { if (((CMolecule*)g_oaMolecules[o->m_iShowMol2])->m_laSingleMolIndex.GetSize() > 1) { mprintf(" Which %s molecules (2nd OM) to take into account (e.g. 1,3-7)? [all] ",((CMolecule*)g_oaMolecules[o->m_iShowMol2])->m_sName); inpprintf("! Which %s molecules (2nd OM) to take into account (e.g. 1,3-7)? [all]\n",((CMolecule*)g_oaMolecules[o->m_iShowMol2])->m_sName); myget(&buf); if (strlen(buf)==0) { for (z=0;z<((CMolecule*)g_oaMolecules[o->m_iShowMol2])->m_laSingleMolIndex.GetSize();z++) o->m_waObsShow2List.Add((unsigned short)z); } else { ParseIntList(buf,&o->m_waObsShow2List); for (z=0;zm_waObsShow2List.GetSize();z++) o->m_waObsShow2List[z]--; } } else o->m_waObsShow2List.Add(0); } else o->m_waObsShow2List.Add(0); // Dummy } } else // if not onlysome { o->m_bObsCertain = false; o->m_bDecompDist = false; } } else // if not advanced { o->m_bObsCertain = false; o->m_bDecompDist = false; } } else { o->m_bObsCertain = false; o->m_bDecompDist = false; } o->m_bDecompType = false; if ((!o->m_bObsCertain) && (!g_bCDF) && g_bAdvanced2 && (g_bRDF || g_bADF || g_bDDF || g_bDipDF)) { if (AskYesNo(" Decompose this observation into contributions from different elements (y/n)? [no] ",false)) { o->m_bDecompType = true; } } if (g_bRegionAnalysis) { AskString(" Take reference molecules from which regions? [all] ",&buf,"0"); ParseIntList(buf,&o->m_iaRMRegions); // for (z6=0;z6m_iaRMRegions.GetSize();z6++) // if (o->m_iaRMRegions[z6] != 0) // o->m_iaRMRegions[z6]--; if (o->m_bOthers) { if (o->m_bSecondShowMol) { AskString(" Take 1st observed molecules from which regions? [all] ",&buf,"0"); ParseIntList(buf,&o->m_iaOM1Regions); // for (z6=0;z6m_iaOM1Regions.GetSize();z6++) // if (o->m_iaOM1Regions[z6] != 0) // o->m_iaOM1Regions[z6]--; AskString(" Take 2nd observed molecules from which regions? [all] ",&buf,"0"); ParseIntList(buf,&o->m_iaOM2Regions); // for (z6=0;z6m_iaOM2Regions.GetSize();z6++) // if (o->m_iaOM2Regions[z6] != 0) // o->m_iaOM2Regions[z6]--; } else { AskString(" Take observed molecules from which regions? [all] ",&buf,"0"); ParseIntList(buf,&o->m_iaOM1Regions); // for (z6=0;z6m_iaOM1Regions.GetSize();z6++) // if (o->m_iaOM1Regions[z6] != 0) // o->m_iaOM1Regions[z6]--; } } } if (g_bAggregation || g_bNbExchange) { try { o->m_pDACF = new CDACF(); } catch(...) { o->m_pDACF = NULL; } if (o->m_pDACF == NULL) NewException((double)sizeof(CDACF),__FILE__,__LINE__,__PRETTY_FUNCTION__); o->m_pDACF->Parse(); } if (g_bRDyn) { try { o->m_pRDyn = new CReorDyn(); } catch(...) { o->m_pRDyn = NULL; } if (o->m_pRDyn == NULL) NewException((double)sizeof(CReorDyn),__FILE__,__LINE__,__PRETTY_FUNCTION__); o->m_pRDyn->m_iShowMol = o->m_iShowMol; o->m_pRDyn->Parse(); } if (g_bIRSpec) { try { o->m_pIRSpec = new CReorDyn(); } catch(...) { o->m_pIRSpec = NULL; } if (o->m_pIRSpec == NULL) NewException((double)sizeof(CReorDyn),__FILE__,__LINE__,__PRETTY_FUNCTION__); o->m_pIRSpec->m_iShowMol = o->m_iShowMol; o->m_pIRSpec->ParseSpec(); } if (g_bDens) { try { o->m_pDensityDF = new CDensDF(); } catch(...) { o->m_pDensityDF = NULL; } if (o->m_pDensityDF == NULL) NewException((double)sizeof(CDensDF),__FILE__,__LINE__,__PRETTY_FUNCTION__); o->m_pDensityDF->m_iShowMol = o->m_iShowMol; o->m_pDensityDF->Parse(); } if (g_bSDF) { try { o->m_pSDF = new CSDF(); } catch(...) { o->m_pSDF = NULL; } if (o->m_pSDF == NULL) NewException((double)sizeof(CSDF),__FILE__,__LINE__,__PRETTY_FUNCTION__); o->m_pSDF->m_bIntra = o->m_bSelf; o->m_pSDF->m_iShowMol = o->m_iShowMol; o->m_pSDF->Parse(false); } if (g_bPlProj) { try { o->m_pPlProj = new CPlProj(); } catch(...) { o->m_pPlProj = NULL; } if (o->m_pPlProj == NULL) NewException((double)sizeof(CPlProj),__FILE__,__LINE__,__PRETTY_FUNCTION__); o->m_pPlProj->m_bIntra = o->m_bSelf; o->m_pPlProj->m_iShowMol = o->m_iShowMol; o->m_pPlProj->Parse(); } if (g_bRevSDF) { try { o->m_pRevSDF = new CRevSDF(); } catch(...) { o->m_pRevSDF = NULL; } if (o->m_pRevSDF == NULL) NewException((double)sizeof(CRevSDF),__FILE__,__LINE__,__PRETTY_FUNCTION__); o->m_pRevSDF->m_bIntra = o->m_bSelf; o->m_pRevSDF->m_iShowMol = o->m_iShowMol; o->m_pRevSDF->Parse(); } if (g_bNbAnalysis) { try { o->m_pNbAnalysis = new CNbAnalysis(); } catch(...) { o->m_pNbAnalysis = NULL; } if (o->m_pNbAnalysis == NULL) NewException((double)sizeof(CNbAnalysis),__FILE__,__LINE__,__PRETTY_FUNCTION__); o->m_pNbAnalysis->m_iShowMol = o->m_iShowMol; o->m_pNbAnalysis->Parse(); } try { o->m_pRDF = new CRDF*[g_iCDFChannels]; } catch(...) { o->m_pRDF = NULL; } if (o->m_pRDF == NULL) NewException((double)g_iCDFChannels*sizeof(CRDF*),__FILE__,__LINE__,__PRETTY_FUNCTION__); try { o->m_pADF = new CADF*[g_iCDFChannels]; } catch(...) { o->m_pADF = NULL; } if (o->m_pADF == NULL) NewException((double)g_iCDFChannels*sizeof(CADF*),__FILE__,__LINE__,__PRETTY_FUNCTION__); try { o->m_pDDF = new CDDF*[g_iCDFChannels]; } catch(...) { o->m_pDDF = NULL; } if (o->m_pDDF == NULL) NewException((double)g_iCDFChannels*sizeof(CDDF*),__FILE__,__LINE__,__PRETTY_FUNCTION__); try { o->m_pDipDF = new CDipDF*[g_iCDFChannels]; } catch(...) { o->m_pDipDF = NULL; } if (o->m_pDipDF == NULL) NewException((double)g_iCDFChannels*sizeof(CDipDF*),__FILE__,__LINE__,__PRETTY_FUNCTION__); try { o->m_pVDF = new CVDF*[g_iCDFChannels]; } catch(...) { o->m_pVDF = NULL; } if (o->m_pVDF == NULL) NewException((double)g_iCDFChannels*sizeof(CVDF*),__FILE__,__LINE__,__PRETTY_FUNCTION__); try { o->m_pPlDF = new CPlDF*[g_iCDFChannels]; } catch(...) { o->m_pPlDF = NULL; } if (o->m_pPlDF == NULL) NewException((double)g_iCDFChannels*sizeof(CVDF*),__FILE__,__LINE__,__PRETTY_FUNCTION__); try { o->m_pLiDF = new CLiDF*[g_iCDFChannels]; } catch(...) { o->m_pLiDF = NULL; } if (o->m_pLiDF == NULL) NewException((double)g_iCDFChannels*sizeof(CVDF*),__FILE__,__LINE__,__PRETTY_FUNCTION__); for (z=0;zm_pRDF[z] = NULL; o->m_pADF[z] = NULL; o->m_pDDF[z] = NULL; o->m_pDipDF[z] = NULL; o->m_pVDF[z] = NULL; o->m_pPlDF[z] = NULL; o->m_pLiDF[z] = NULL; } if (g_bCDF) { try { o->m_pCDF = new CCDF(); } catch(...) { o->m_pCDF = NULL; } if (o->m_pCDF == NULL) NewException((double)sizeof(CCDF),__FILE__,__LINE__,__PRETTY_FUNCTION__); try { o->m_pCDF->m_iCombinations = new int[g_iCDFChannels]; } catch(...) { o->m_pCDF->m_iCombinations = NULL; } if (o->m_pCDF->m_iCombinations == NULL) NewException((double)g_iCDFChannels*sizeof(int),__FILE__,__LINE__,__PRETTY_FUNCTION__); mprintf(BLUE,"\n>>> Combined Distribution Function >>>\n"); // o->m_pCDF->m_bChannelAll = new bool[g_iCDFChannels]; o->m_pCDF->m_iCombinationProd = 1; for (z=0;zm_pRDF[z] = new CRDF(); } catch(...) { o->m_pRDF[z] = NULL; } if (o->m_pRDF[z] == NULL) NewException((double)sizeof(CRDF),__FILE__,__LINE__,__PRETTY_FUNCTION__); if (o->m_bSecondShowMol && (z == 1)) o->m_pRDF[z]->m_iShowMol = o->m_iShowMol2; else o->m_pRDF[z]->m_iShowMol = o->m_iShowMol; o->m_pRDF[z]->Parse(); o->m_pCDF->m_iCombinations[z] = o->m_pRDF[z]->m_iCombinations; o->m_pCDF->m_iCombinationProd *= o->m_pRDF[z]->m_iCombinations; /* if (o->m_pRDF[z]->m_bSaveDist) o->m_bTimeDev = true;*/ break; case 1: try { o->m_pADF[z] = new CADF(); } catch(...) { o->m_pADF[z] = NULL; } if (o->m_pADF[z] == NULL) NewException((double)sizeof(CADF),__FILE__,__LINE__,__PRETTY_FUNCTION__); if (o->m_bSecondShowMol && (z == 1)) o->m_pADF[z]->m_iShowMol = o->m_iShowMol2; else o->m_pADF[z]->m_iShowMol = o->m_iShowMol; o->m_pADF[z]->Parse(); o->m_pCDF->m_iCombinations[z] = o->m_pADF[z]->m_iCombinations; o->m_pCDF->m_iCombinationProd *= o->m_pADF[z]->m_iCombinations; /* if (o->m_pADF[z]->m_bSaveAngle) o->m_bTimeDev = true;*/ break; case 2: try { o->m_pDDF[z] = new CDDF(); } catch(...) { o->m_pDDF[z] = NULL; } if (o->m_pDDF[z] == NULL) NewException((double)sizeof(CDDF),__FILE__,__LINE__,__PRETTY_FUNCTION__); if (o->m_bSecondShowMol && (z == 1)) o->m_pDDF[z]->m_iShowMol = o->m_iShowMol2; else o->m_pDDF[z]->m_iShowMol = o->m_iShowMol; o->m_pDDF[z]->Parse(); o->m_pCDF->m_iCombinations[z] = o->m_pDDF[z]->m_iCombinations; o->m_pCDF->m_iCombinationProd *= o->m_pDDF[z]->m_iCombinations; /* if (o->m_pDDF[z]->m_bSaveAngle) o->m_bTimeDev = true;*/ break; case 3: try { o->m_pDipDF[z] = new CDipDF(); } catch(...) { o->m_pDipDF[z] = NULL; } if (o->m_pDipDF[z] == NULL) NewException((double)sizeof(CDipDF),__FILE__,__LINE__,__PRETTY_FUNCTION__); if (o->m_bSecondShowMol && (z == 1)) o->m_pDipDF[z]->m_iShowMol = o->m_iShowMol2; else o->m_pDipDF[z]->m_iShowMol = o->m_iShowMol; o->m_pDipDF[z]->m_iCombinations = 1; o->m_pDipDF[z]->Parse(); o->m_pCDF->m_iCombinations[z] = 1; /* if (o->m_pDipDF[z]->m_bSaveDipole) o->m_bTimeDev = true;*/ break; case 4: try { o->m_pVDF[z] = new CVDF(); } catch(...) { o->m_pVDF[z] = NULL; } if (o->m_pVDF[z] == NULL) NewException((double)sizeof(CVDF),__FILE__,__LINE__,__PRETTY_FUNCTION__); if (o->m_bSecondShowMol && (z == 1)) o->m_pVDF[z]->m_iShowMol = o->m_iShowMol2; else o->m_pVDF[z]->m_iShowMol = o->m_iShowMol; o->m_pVDF[z]->Parse(); o->m_pCDF->m_iCombinations[z] = o->m_pVDF[z]->m_iCombinations; o->m_pCDF->m_iCombinationProd *= o->m_pVDF[z]->m_iCombinations; g_bUseVelocities = true; /* if (o->m_pVDF[z]->m_bSaveSpeed) o->m_bTimeDev = true;*/ break; case 5: try { o->m_pPlDF[z] = new CPlDF(); } catch(...) { o->m_pPlDF[z] = NULL; } if (o->m_pPlDF[z] == NULL) NewException((double)sizeof(CPlDF),__FILE__,__LINE__,__PRETTY_FUNCTION__); if (o->m_bSecondShowMol && (z == 1)) o->m_pPlDF[z]->m_iShowMol = o->m_iShowMol2; else o->m_pPlDF[z]->m_iShowMol = o->m_iShowMol; o->m_pPlDF[z]->Parse(); o->m_pCDF->m_iCombinations[z] = o->m_pPlDF[z]->m_iCombinations; o->m_pCDF->m_iCombinationProd *= o->m_pPlDF[z]->m_iCombinations; break; case 6: try { o->m_pLiDF[z] = new CLiDF(); } catch(...) { o->m_pLiDF[z] = NULL; } if (o->m_pLiDF[z] == NULL) NewException((double)sizeof(CLiDF),__FILE__,__LINE__,__PRETTY_FUNCTION__); if (o->m_bSecondShowMol && (z == 1)) o->m_pLiDF[z]->m_iShowMol = o->m_iShowMol2; else o->m_pLiDF[z]->m_iShowMol = o->m_iShowMol; o->m_pLiDF[z]->Parse(); o->m_pCDF->m_iCombinations[z] = o->m_pLiDF[z]->m_iCombinations; o->m_pCDF->m_iCombinationProd *= o->m_pLiDF[z]->m_iCombinations; break; } /* if (z != 0) o->m_pCDF->m_bChannelAll[z] = AskYesNo(" Should this CDF Channel observe all OMs (y) or only the current one (n)? [no] ",false); else o->m_pCDF->m_bChannelAll[z] = false;*/ } /* mprintf(" Write out temporal development for this CDF (1=yes,0=no)? [no] "); myget(buf); o->m_pCDF->m_bTimeDev = (atoi(buf)!=0); if (o->m_pCDF->m_bTimeDev) o->m_bTimeDev = true;*/ mprintf("\n"); try { o->m_pCDF->m_iResolution = new int[g_iCDFChannels]; } catch(...) { o->m_pCDF->m_iResolution = NULL; } if (o->m_pCDF->m_iResolution == NULL) NewException((double)g_iCDFChannels*sizeof(int),__FILE__,__LINE__,__PRETTY_FUNCTION__); for (z=0;zm_pCDF->m_iResolution[z] = AskUnsignedInteger(" Please enter the resolution (bin count) for CDF channel %d (%s): [100] ",100,z+1,(const char*)buf); } if (g_bAdvanced2) o->m_pCDF->m_iHistogramRes = AskUnsignedInteger(" Please enter CDF histogram resolution (0=no histogram): [0] ",0); else o->m_pCDF->m_iHistogramRes = 0; if (g_iCDFChannels == 2) { try { o->m_pCDF->m_pCombineList = new char[o->m_pCDF->m_iCombinationProd]; } catch(...) { o->m_pCDF->m_pCombineList = NULL; } if (o->m_pCDF->m_pCombineList == NULL) NewException((double)o->m_pCDF->m_iCombinationProd*sizeof(char),__FILE__,__LINE__,__PRETTY_FUNCTION__); if ((o->m_pCDF->m_iCombinations[0] > 1) && (o->m_pCDF->m_iCombinations[1] > 1)) { mprintf("\n"); for (z=0;zm_pCDF->m_iCombinations[z]); o->ListCDFObservations(z); mprintf("\n"); } if (o->m_pCDF->m_iCombinations[0] == o->m_pCDF->m_iCombinations[1]) { if (AskYesNo(" Combine n-th with n-th observation? (y/n) [yes] ",true)) { for (z=0;zm_pCDF->m_iCombinations[0];z++) for (z2=0;z2m_pCDF->m_iCombinations[1];z2++) o->m_pCDF->m_pCombineList[z*o->m_pCDF->m_iCombinations[1]+z2] = (z==z2)?1:0; goto _combdone; } goto _askcomball; } else { _askcomball: if (!AskYesNo(" Combine each with each observation (y), or use only some combinations (n)? [yes] ",true)) { for (z=0;zm_pCDF->m_iCombinations[0];z++) for (z2=0;z2m_pCDF->m_iCombinations[1];z2++) o->m_pCDF->m_pCombineList[z*o->m_pCDF->m_iCombinations[1]+z2] = 0; mprintf("\n Please enter all the combinations you want to observe.\n"); mprintf(" Enter each combination as a comma-separated %d-tuple (e.g. ",g_iCDFChannels); for (z=0;z o->m_pCDF->m_iCombinations[z])) { eprintf(" Invalid input, channel %d has only %d observations (%d requested).\n",z+1,o->m_pCDF->m_iCombinations[z],tempwa[z]); goto _nextcomb; } tempwa[z]--; } if (o->m_pCDF->m_pCombineList[tempwa[0]*o->m_pCDF->m_iCombinations[1]+tempwa[1]] == 1) { eprintf(" This combination has already been added.\n"); goto _nextcomb; } o->m_pCDF->m_pCombineList[tempwa[0]*o->m_pCDF->m_iCombinations[1]+tempwa[1]] = 1; goto _nextcomb; } else goto _combineall; _combdone:; } } else { _combineall: for (z=0;zm_pCDF->m_iCombinationProd;z++) o->m_pCDF->m_pCombineList[z] = 1; } o->m_pCDF->m_iCombinationsEnabled = 0; for (z=0;zm_pCDF->m_iCombinationProd;z++) if (o->m_pCDF->m_pCombineList[z] != 0) o->m_pCDF->m_iCombinationsEnabled++; if (o->m_pCDF->m_iCombinationsEnabled == 1) { mprintf(WHITE,"\n Using 1 combination for each RM-OM pair.\n\n"); } else { mprintf(WHITE,"\n Using %d combinations for each RM-OM pair:\n\n",o->m_pCDF->m_iCombinationsEnabled); z3 = 0; for (z=0;zm_pCDF->m_iCombinations[0];z++) { for (z2=0;z2m_pCDF->m_iCombinations[1];z2++) { if (o->m_pCDF->m_pCombineList[z*o->m_pCDF->m_iCombinations[1]+z2] == 1) { mprintf(" %2d.) %2d - %2d\n",z3+1,z+1,z2+1); z3++; } } } mprintf("\n"); } if (g_bAdvanced2) { o->m_pCDF->m_bAxisDivide = AskYesNo(" Write out +/- correlation plot for this CDF (y/n)? [no] ",false); if (o->m_pCDF->m_bAxisDivide) o->m_pCDF->m_bAxisDivideAll = AskYesNo(" Also write tensor product and axis projection quotients (y/n)? [no] ",false); } else { o->m_pCDF->m_bAxisDivide = false; o->m_pCDF->m_bAxisDivideAll = false; } if (g_bAdvanced2) { o->m_pCDF->m_bGraceBunch = AskYesNo(" Write out grace stack (multiple 2D plots) for this CDF (y/n)? [no] ",false); if (o->m_pCDF->m_bGraceBunch) { o->m_pCDF->m_iGraceBunchC1 = AskUnsignedInteger(" How many graphs do you want do draw in the channel 1 grace stack (0=disable)? [10] ",10); o->m_pCDF->m_iGraceBunchC2 = AskUnsignedInteger(" How many graphs do you want do draw in the channel 2 grace stack (0=disable)? [10] ",10); } } else o->m_pCDF->m_bGraceBunch = false; } if (g_iCDFChannels == 3) { mprintf("\n"); try { o->m_pCDF->m_pCombineList = new char[o->m_pCDF->m_iCombinationProd]; } catch(...) { o->m_pCDF->m_pCombineList = NULL; } if (o->m_pCDF->m_pCombineList == NULL) NewException((double)o->m_pCDF->m_iCombinationProd*sizeof(char),__FILE__,__LINE__,__PRETTY_FUNCTION__); if ((o->m_pCDF->m_iCombinations[0] > 1) || (o->m_pCDF->m_iCombinations[1] > 1) || (o->m_pCDF->m_iCombinations[2] > 1)) { for (z=0;zm_pCDF->m_iCombinations[z]); o->ListCDFObservations(z); mprintf("\n"); } if (!AskYesNo(" Combine each with each observation (y), or use only some combinations (n)? [yes] ",true)) { for (z=0;zm_pCDF->m_iCombinations[0];z++) for (z2=0;z2m_pCDF->m_iCombinations[1];z2++) for (z3=0;z3m_pCDF->m_iCombinations[2];z3++) o->m_pCDF->m_pCombineList[z*o->m_pCDF->m_iCombinations[1]*o->m_pCDF->m_iCombinations[2]+z2*o->m_pCDF->m_iCombinations[2]+z3] = 0; mprintf("\n Please enter all the combinations you want to observe.\n"); mprintf(" Enter each combination as a comma-separated %d-tuple (e.g. ",g_iCDFChannels); for (z=0;z o->m_pCDF->m_iCombinations[z])) { eprintf(" Invalid input, channel %d has only %d observations (%d requested).\n",z+1,o->m_pCDF->m_iCombinations[z],tempwa[z]); goto _3nextcomb; } tempwa[z]--; } if (o->m_pCDF->m_pCombineList[tempwa[0]*o->m_pCDF->m_iCombinations[1]*o->m_pCDF->m_iCombinations[2]+tempwa[1]*o->m_pCDF->m_iCombinations[2]+tempwa[2]] == 1) { eprintf(" This combination has already been added.\n"); goto _3nextcomb; } o->m_pCDF->m_pCombineList[tempwa[0]*o->m_pCDF->m_iCombinations[1]*o->m_pCDF->m_iCombinations[2]+tempwa[1]*o->m_pCDF->m_iCombinations[2]+tempwa[2]] = 1; goto _3nextcomb; } else goto _3combineall; } else { _3combineall: for (z=0;zm_pCDF->m_iCombinationProd;z++) o->m_pCDF->m_pCombineList[z] = 1; } _3combdone: o->m_pCDF->m_iCombinationsEnabled = 0; for (z=0;zm_pCDF->m_iCombinationProd;z++) if (o->m_pCDF->m_pCombineList[z] != 0) o->m_pCDF->m_iCombinationsEnabled++; if (o->m_pCDF->m_iCombinationsEnabled == 1) { mprintf(WHITE,"\n Using 1 combination for each RM-OM pair.\n\n"); } else { mprintf(WHITE,"\n Using %d combinations for each RM-OM pair:\n\n",o->m_pCDF->m_iCombinationsEnabled); z4 = 0; for (z=0;zm_pCDF->m_iCombinations[0];z++) for (z2=0;z2m_pCDF->m_iCombinations[1];z2++) for (z3=0;z3m_pCDF->m_iCombinations[2];z3++) if (o->m_pCDF->m_pCombineList[z*o->m_pCDF->m_iCombinations[1]*o->m_pCDF->m_iCombinations[2]+z2*o->m_pCDF->m_iCombinations[2]+z3] == 1) { mprintf(" %2d.) %2d - %2d - %2d\n",z4+1,z+1,z2+1,z3+1); z4++; } mprintf("\n"); } if (g_bAdvanced2) { o->m_pCDF->m_b3DSlices = AskYesNo(" Write out 2D slices for this CDF (y/n)? [no] ",false); if (o->m_pCDF->m_b3DSlices) for (z=0;z<3;z++) o->m_pCDF->m_i3DSliceIntervals[z] = AskUnsignedInteger(" How many slice intervals to create along channel %d axis (0=skip)? [0] ",0,z+1); } else o->m_pCDF->m_b3DSlices = false; } // end if channels == 3 if (g_bAdvanced2) { o->m_pCDF->m_bDumpDat = AskYesNo(" Write out input tuples (very large!) for this CDF (y/n)? [no] ",false); if ((g_iCDFChannels == 2) && (g_iObsChannel[0] == 0) && (g_iObsChannel[1] == 1)) o->m_pCDF->m_iNormalize = (char)AskRangeInteger(" Normalize uniformly (3), data range (2), integral (1), or do not normalize (0)? [1] ",0,3,1); else o->m_pCDF->m_iNormalize = (char)AskRangeInteger(" Normalize data range (2), integral (1), or do not normalize (0)? [1] ",0,2,1); if (o->m_pCDF->m_iNormalize == 1) o->m_pCDF->m_fNormValue = AskFloat(" Set CDF integral to which value? [1000000] ",1000000.0); if (o->m_pCDF->m_iNormalize == 2) o->m_pCDF->m_fNormValue = AskFloat(" Set maximum entry to which value? [100] ",100.0); } else { o->m_pCDF->m_bDumpDat = false; o->m_pCDF->m_iNormalize = 1; o->m_pCDF->m_fNormValue = 1000000.0; } mprintf(BLUE,"\n<<< End of Combined Distribution Function <<<\n\n"); } else { if (g_bRDF) { try { o->m_pRDF[0] = new CRDF(); } catch(...) { o->m_pRDF[0] = NULL; } if (o->m_pRDF[0] == NULL) NewException((double)sizeof(CRDF),__FILE__,__LINE__,__PRETTY_FUNCTION__); o->m_pRDF[0]->m_iShowMol = o->m_iShowMol; o->m_pRDF[0]->Parse(); o->m_pRDF[0]->m_bSelf = o->m_bSelf; } if (g_bPlDF) { try { o->m_pPlDF[0] = new CPlDF(); } catch(...) { o->m_pPlDF[0] = NULL; } if (o->m_pPlDF[0] == NULL) NewException((double)sizeof(CPlDF),__FILE__,__LINE__,__PRETTY_FUNCTION__); o->m_pPlDF[0]->m_iShowMol = o->m_iShowMol; o->m_pPlDF[0]->Parse(); o->m_pPlDF[0]->m_bSelf = o->m_bSelf; } if (g_bLiDF) { try { o->m_pLiDF[0] = new CLiDF(); } catch(...) { o->m_pLiDF[0] = NULL; } if (o->m_pLiDF[0] == NULL) NewException((double)sizeof(CLiDF),__FILE__,__LINE__,__PRETTY_FUNCTION__); o->m_pLiDF[0]->m_iShowMol = o->m_iShowMol; o->m_pLiDF[0]->Parse(); o->m_pLiDF[0]->m_bSelf = o->m_bSelf; } if (g_bVHDF) { try { o->m_pVHDF = new CVHDF(); } catch(...) { o->m_pVHDF = NULL; } if (o->m_pVHDF == NULL) NewException((double)sizeof(CVHDF),__FILE__,__LINE__,__PRETTY_FUNCTION__); o->m_pVHDF->m_iShowMol = o->m_iShowMol; o->m_pVHDF->m_bSelf = o->m_bSelf; o->m_pVHDF->Parse(); } if (g_bADF) { try { o->m_pADF[0] = new CADF(); } catch(...) { o->m_pADF[0] = NULL; } if (o->m_pADF[0] == NULL) NewException((double)sizeof(CADF),__FILE__,__LINE__,__PRETTY_FUNCTION__); o->m_pADF[0]->m_iShowMol = o->m_iShowMol; o->m_pADF[0]->m_bSelf = o->m_bSelf; o->m_pADF[0]->Parse(); } if (g_bDDF) { try { o->m_pDDF[0] = new CDDF(); } catch(...) { o->m_pDDF[0] = NULL; } if (o->m_pDDF[0] == NULL) NewException((double)sizeof(CDDF),__FILE__,__LINE__,__PRETTY_FUNCTION__); o->m_pDDF[0]->m_iShowMol = o->m_iShowMol; o->m_pDDF[0]->m_bSelf = o->m_bSelf; o->m_pDDF[0]->Parse(); } if (g_bDipDF) { try { o->m_pDipDF[0] = new CDipDF(); } catch(...) { o->m_pDipDF[0] = NULL; } if (o->m_pDipDF[0] == NULL) NewException((double)sizeof(CDipDF),__FILE__,__LINE__,__PRETTY_FUNCTION__); o->m_pDipDF[0]->m_iShowMol = o->m_iShowMol; o->m_pDipDF[0]->m_bSelf = o->m_bSelf; o->m_pDipDF[0]->Parse(); } if (g_bVDF) { try { o->m_pVDF[0] = new CVDF(); } catch(...) { o->m_pVDF[0] = NULL; } if (o->m_pVDF[0] == NULL) NewException((double)sizeof(CVDF),__FILE__,__LINE__,__PRETTY_FUNCTION__); o->m_pVDF[0]->m_iShowMol = o->m_iShowMol; o->m_pVDF[0]->m_bSelf = true; o->m_pVDF[0]->Parse(); g_bUseVelocities = true; } if (g_bMSD) { try { o->m_pMSD = new CMSD(); } catch(...) { o->m_pMSD = NULL; } if (o->m_pMSD == NULL) NewException((double)sizeof(CMSD),__FILE__,__LINE__,__PRETTY_FUNCTION__); o->m_pMSD->m_iShowMol = o->m_iShowMol; o->m_pMSD->Parse(); } } if ((g_bCDF && (g_iCDFChannels == 2)) || g_bRDF || g_bADF || g_bVDF || g_bDDF || g_bDipDF) { if (!o->m_bSecondShowMol) { if (AskYesNo(" Save temporal development for this observation (y/n)? [no] ",false)) { mprintf(WHITE,"\n>>> Save temporal development >>>\n\n"); o->m_bTimeDev = true; if (g_fTimestepLength == 0) { g_fTimestepLength = AskFloat(" Enter the length of one trajectory time step in fs: [0.5] ",0.5); mprintf("\n"); } if (g_bDDF && (!g_bCDF)) { if ((o->m_pDDF[0]->m_iDeriv == 0) && (!o->m_pDDF[0]->m_bCosine) && (!o->m_pDDF[0]->m_bAbs) && (!o->m_pDDF[0]->m_bPositive)) { mprintf("\n You can include full rotations into the DDF's temporal development.\n"); mprintf(" This means, if a dihedral makes a full rotation, the value will be 360 deg insteat of 0 deg.\n"); mprintf(" You may count the number of full rotations during simulation in this way.\n\n"); o->m_pDDF[0]->m_bRotate = AskYesNo(" Include full rotations into the DDF's temporal development (y/n)? [no] ",false); } else o->m_pDDF[0]->m_bRotate = false; if (o->m_pDDF[0]->m_bRotate) { mprintf(WHITE,"\n Warning: "); mprintf("This only works if your trajectory time step is small enough to ensure\n"); mprintf(" that the dihedral is never changing more than 180 deg within one step!\n\n"); } } if (g_bRDF || g_bADF || g_bVDF || g_bDDF || g_bDipDF) { if (AskYesNo(" Create combined development/histogram-plots for 2D analyses (y/n)? [yes] ",true)) { g_bCombined = true; o->m_bCombinedPlot = true; if (AskYesNo(" Use grey tones for combined plot (y) or standard colors (n)? [no] ",false)) { o->m_bCombinedGreyMode = true; o->m_iCombinedGreyMin = AskRangeInteger(" Darkest shade of grey to use (0=black, 255=white)? [128] ",0,255,128); o->m_iCombinedGreyMax = AskRangeInteger(" Lightest shade of grey to use (0=black, 255=white)? [224] ",o->m_iCombinedGreyMin,255,224); o->m_iCombinedGreyShades = AskUnsignedInteger(" How many different shades of grey to use? [4] ",4); } else o->m_bCombinedGreyMode = false; } else o->m_bCombinedPlot = false; } else o->m_bCombinedPlot = false; if (!g_bVDF && ((CMolecule*)g_oaMolecules[g_iFixMol])->m_laSingleMolIndex.GetSize() > 1) { mprintf(" Save development for which rep. of the reference molecule (e.g. 1,3-7)? [1] "); inpprintf("! Save development for which rep. of the reference molecule (e.g. 1,3-7)? [1]\n"); myget(&buf); if (strlen(buf)==0) o->m_waSaveRefList.Add(0); else { ParseIntList(buf,&o->m_waSaveRefList); for (z=0;zm_waSaveRefList.GetSize();z++) o->m_waSaveRefList[z]--; } } else o->m_waSaveRefList.Add(0); if (o->m_iShowMol != -1) { if (((CMolecule*)g_oaMolecules[o->m_iShowMol])->m_laSingleMolIndex.GetSize() > 1) { mprintf(" Save development for which rep. of the observed molecule (e.g. 1,3-7)? [all] "); inpprintf("! Save development for which rep. of the observed molecule (e.g. 1,3-7)? [all]\n"); myget(&buf); if (strlen(buf)==0) { for (z=0;z<((CMolecule*)g_oaMolecules[o->m_iShowMol])->m_laSingleMolIndex.GetSize();z++) o->m_waSaveShowList.Add((unsigned short)z); } else { ParseIntList(buf,&o->m_waSaveShowList); for (z=0;zm_waSaveShowList.GetSize();z++) o->m_waSaveShowList[z]--; } } else o->m_waSaveShowList.Add(0); } else o->m_waSaveShowList.Add(0); // Dummy if ((o->m_waSaveRefList.GetSize() > 1) && (o->m_bOthers)) o->m_bSaveSeparateFiles = AskYesNo(" Developments for different ref. molecules to same (n) or different (y) files? [yes] ",true); else o->m_bSaveSeparateFiles = false; if ((g_bCDF) && (g_iCDFChannels == 2)) { if (AskYesNo(" Generate time development animation (TDO) for CDF (y/n)? [no] ",false)) { o->m_pCDF->m_bTDAnimation = true; o->m_pCDF->m_iTDASteps = AskUnsignedInteger(" How many steps should the animation have? [1000] ",1000); o->m_pCDF->m_iTDAStride = AskUnsignedInteger(" Enter distance between the frames in timesteps: [100] ",50); o->m_pCDF->m_iTDATail = AskUnsignedInteger(" Enter length of the tail in timesteps: [100] ",100); o->m_pCDF->m_bTDATrace = AskYesNo(" Show trace (y/n)? [yes] ",true); o->m_pCDF->m_iTDAResX = AskUnsignedInteger(" Enter width (in pixel) of the TDA images: [640] ",640); o->m_pCDF->m_iTDAResY = AskUnsignedInteger(" Enter height (in pixel) of the TDA images: [480] ",480); } else o->m_pCDF->m_bTDAnimation = false; } mprintf("\n Saving temporal development for reference molecules "); for (z=0;zm_waSaveRefList.GetSize();z++) { if (z < (int)o->m_waSaveRefList.GetSize()-1) { mprintf("%d, ",o->m_waSaveRefList[z]+1); if (((z+1) % 16) == 0) mprintf("\n "); } else mprintf("%d",o->m_waSaveRefList[z]+1); } if (o->m_bOthers) { mprintf("\n and for observed molecules "); for (z=0;zm_waSaveShowList.GetSize();z++) { if (z < (int)o->m_waSaveShowList.GetSize()-1) { mprintf("%d, ",o->m_waSaveShowList[z]+1); if (((z+1) % 16) == 0) mprintf("\n "); } else mprintf("%d",o->m_waSaveShowList[z]+1); } } mprintf(".\n"); mprintf(WHITE,"\n<<< End of Save temporal development <<<\n\n"); } else o->m_bTimeDev = false; if (g_bAdvanced2) { if (AskYesNo(" Create a temporal difference plot for this observation (y/n)? [no] ",false)) { o->m_bTimeDiff = true; g_bTimeDiff = true; o->m_iTimeDiffDepth = AskUnsignedInteger(" Enter temporal depth of this plot in time steps: [1000] ",1000); o->m_b3DTimeDiff = AskYesNo(" Create also 3D temporal difference plots (y/n)? [yes] ",true); if (o->m_b3DTimeDiff) { tf = 0; tf2 = 0; if (g_bRDF) { tf = o->m_pRDF[0]->m_fMinDist; tf2 = o->m_pRDF[0]->m_fMaxDist; } if (g_bADF) { tf = o->m_pADF[0]->m_fMinAngle; tf2 = o->m_pADF[0]->m_fMaxAngle; } if (g_bDDF) { tf = o->m_pDDF[0]->m_fMinAngle; tf2 = o->m_pDDF[0]->m_fMaxAngle; } if (g_bVDF) { tf = o->m_pVDF[0]->m_fMinSpeed; tf2 = o->m_pVDF[0]->m_fMaxSpeed; } if (g_bDipDF) { tf = o->m_pDipDF[0]->m_fDipoleMin; tf2 = o->m_pDipDF[0]->m_fDipoleMax; } o->m_iTimeDiffStride3D = AskUnsignedInteger(" Take every n-th time step for the tau axis: [%d] ",o->m_iTimeDiffDepth/100,o->m_iTimeDiffDepth/100); o->m_fTimeDiffMinVal3D = AskFloat(" Enter min. value for the starting point: [%.2f] ",tf,tf); o->m_fTimeDiffMaxVal3D = AskFloat(" Enter max. value for the starting point: [%.2f] ",tf2,tf2); o->m_iTimeDiffRes3D = AskUnsignedInteger(" Enter binning resolution for the starting value: [100] ",100); mprintf("\n Temporal before/after 3D plot:\n"); o->m_iTimeDiffDistSteps= AskUnsignedInteger(" Every how many time steps create a 2D slice (0 to disable): [0] ",0); o->m_fTimeDiffDistMinValX = AskFloat(" Enter min. value for the starting point: [%.2f] ",tf,tf); o->m_fTimeDiffDistMaxValX = AskFloat(" Enter max. value for the starting point: [%.2f] ",tf2,tf2); o->m_iTimeDiffDistResX = AskUnsignedInteger(" Enter binning resolution for the X axis: [100] ",100); o->m_fTimeDiffDistMinValY = AskFloat(" Enter min. value for the end point: [%.2f] ",tf,tf); o->m_fTimeDiffDistMaxValY = AskFloat(" Enter max. value for the end point: [%.2f] ",tf2,tf2); o->m_iTimeDiffDistResY = AskUnsignedInteger(" Enter binning resolution for the Y axis: [100] ",100); } mprintf("\n"); } else o->m_bTimeDiff = false; } else o->m_bTimeDiff = false; } else { o->m_bTimeDev = false; o->m_bTimeDiff = false; } } else { o->m_bTimeDev = false; o->m_bTimeDiff = false; } if ((g_iFixMol != -1) && (o->m_iShowMol != -1) && (g_bRDyn || g_bDipDF || g_bMSD || g_bADF || g_bPlDF || g_bLiDF || g_bDDF || g_bVACF || g_bDipACF ||g_bRevSDF || g_bSDF || g_bPlProj || g_bVHDF || g_bRDF || g_bVDF || /*g_bFDF ||*/ g_bCond)) { if (g_bCond) goto _askcond; if (AskYesNo(" Add a condition to this observation (y/n)? [no] ",false)) { _askcond: mprintf(GREEN,"\n>>> Condition input >>>\n\n"); // mprintf("You may enter several sets of conditions. They are connected with \"or\",\nonly one of them needs to apply to take a configuration into account.\n\n"); // mprintf("In each set of conditions, you may enter several conditions. They are connected\nwith \"and\", all of them have to apply to make this set of conditions apply.\n"); if (o->m_bSecondShowMol) { if (!AskYesNo(" Add a condition between RM and 1st OM (y/n)? [yes] ",true)) goto _no1stcond; mprintf(WHITE,"\n *** Input of Condition between RM and 1st OM ***\n\n"); } try { o->m_pConditions = new CConditionGroup(); } catch(...) { o->m_pConditions = NULL; } if (o->m_pConditions == NULL) NewException((double)sizeof(CConditionGroup),__FILE__,__LINE__,__PRETTY_FUNCTION__); o->m_pConditions->m_iShowMol = o->m_iShowMol; o->m_pConditions->Parse(g_iFixMol,o->m_iShowMol); _no1stcond: if (o->m_bSecondShowMol) { mprintf("\n"); if (!AskYesNo(" Add a condition between RM and 2nd OM (y/n)? [yes] ",true)) goto _no2ndcond; mprintf(WHITE,"\n *** Input of Condition between RM and 2nd OM ***\n\n"); try { o->m_pConditionsOM2 = new CConditionGroup(); } catch(...) { o->m_pConditionsOM2 = NULL; } if (o->m_pConditionsOM2 == NULL) NewException((double)sizeof(CConditionGroup),__FILE__,__LINE__,__PRETTY_FUNCTION__); o->m_pConditionsOM2->m_iShowMol = o->m_iShowMol2; o->m_pConditionsOM2->Parse(g_iFixMol,o->m_iShowMol2); _no2ndcond:; } if (o->m_pConditions != NULL) { if (o->m_pConditions->m_bInvertCondition) { o->m_bBinOnlyNotPassedAtoms = false; o->m_bBinOnlyPassedAtoms = false; goto _nobinonly; } } if (o->m_pConditionsOM2 != NULL) { if (o->m_pConditionsOM2->m_bInvertCondition) { o->m_bBinOnlyNotPassedAtoms = false; o->m_bBinOnlyPassedAtoms = false; goto _nobinonly; } } mprintf("\n Normally, TRAVIS evaluates the condition for each RM-OM pair. If the condition\n"); mprintf(" is fulfilled, all atoms from this pair are evaluated. The following question\n"); mprintf(" enables to take into account only exactly the atoms which fulfilled the condition.\n\n"); mprintf(" If you have a distance condition with \"nearest neighbor mode\", only the atom\n"); mprintf(" from the OM that is closest to the RM will be taken into account.\n\n"); o->m_bBinOnlyPassedAtoms = AskYesNo(" Add only atoms to the bin that passed the condition(s) (y/n)? [no] ",false); /* if (!o->m_bBinOnlyPassedAtoms) o->m_bBinOnlyNotPassedAtoms = AskYesNo(" Add only atoms to the bin that did NOT pass the condition(s) (y/n)? [no] ",false); else*/ o->m_bBinOnlyNotPassedAtoms = false; _nobinonly: g_bSaveCondSnapshot = AskYesNo(" Save a snapshot every time the conditions are fulfilled (y/n)? [no] ",false); if (g_bSaveCondSnapshot) g_bNeedMoleculeWrap = true; if (g_bSaveCondSnapshot) { g_bSaveCondWholeBox = AskYesNo(" Save the whole box (y) or only the RM/OM pair (n)? [no] ",false); if (g_bSaveCondWholeBox) mprintf("\n The RM that fulfills the condition will be centered (coordinates 0|0|0).\n"); } mprintf("\n"); if (g_bCond) o->m_bCondDevelopment = AskYesNo(" Save temporal development of this condition (y/n)? [yes] ",true); else o->m_bCondDevelopment = AskYesNo(" Save temporal development of this condition (y/n)? [no] ",false); if (o->m_bCondDevelopment) o->m_iCondDevelopmentMax = AskUnsignedInteger(" Record development up to how many OMs per RM? [6] ",6); mprintf(GREEN,"\n<<< End of Condition input <<<\n\n"); } } if (g_bVACF) { mprintf(WHITE,"\n>>> Velocity autocorrelation function >>>\n\n"); try { o->m_pVACF = new CACF(); } catch(...) { o->m_pVACF = NULL; } if (o->m_pVACF == NULL) NewException((double)sizeof(CACF),__FILE__,__LINE__,__PRETTY_FUNCTION__); o->m_pVACF->m_iShowMol = o->m_iShowMol; o->m_pVACF->Parse(); mprintf(WHITE,"\n<< End of Velocity autocorrelation function <<<\n\n"); } /* if (g_bDipACF) { mprintf(WHITE,"\n>>> Dipole moment autocorrelation function >>>\n\n"); try { o->m_pDipACF = new CACF(); } catch(...) { o->m_pDipACF = NULL; } if (o->m_pDipACF == NULL) NewException((double)sizeof(CACF),__FILE__,__LINE__,__PRETTY_FUNCTION__); o->m_pDipACF->Parse(); mprintf(WHITE,"\n<<< End of Dipole moment autocorrelation function <<<\n\n"); }*/ if (g_bUseVelocities) { if (g_iFixMol != -1) o->m_bVelocityRelToRef = (AskRangeInteger(" Use absolute velocities (0) or relative to the reference molecule (1)? [0] ",0,1,0) != 0); else o->m_bVelocityRelToRef = false; } mprintf(YELLOW,"\n<<< End of Observation %d <<<\n",g_oaObserv.GetSize()); if (AskYesNo("\n Add another observation (y/n)? [no] ",false)) goto _nextsdf; mprintf("\n"); mprintf(WHITE,">>> Observation List >>>\n\n"); for (z2=0;z2m_sName,((CMolecule*)g_oaMolecules[o->m_iShowMol])->m_sName); if (g_bAggregation) { mprintf(" - Aggregation functions - %d value sets:\n",o->m_pDACF->m_oaSubDACFs.GetSize()); for (z3=0;z3m_pDACF->m_oaSubDACFs.GetSize();z3++) mprintf(" > %s\n",((CDACFSub*)o->m_pDACF->m_oaSubDACFs[z3])->m_sName); } if (g_bNbExchange) { mprintf(" - Neighborhood exchange functions:\n"); for (z3=0;z3m_pDACF->m_oaSubDACFs.GetSize();z3++) mprintf(" > %s\n",((CDACFSub*)o->m_pDACF->m_oaSubDACFs[z3])->m_sName); } if (g_bRDyn) mprintf(" - Reorientation Dynamics: %s\n",o->m_pRDyn->m_sName); if (g_bIRSpec) mprintf(" - IR Spectrum: %s\n",o->m_pIRSpec->m_sName); if (g_bDens) mprintf(" - Density DF: %s\n",o->m_pDensityDF->m_sName); if (g_bSDF) mprintf(" - SDF: %s\n",o->m_pSDF->m_sName); if (g_bPlProj) mprintf(" - Plane Projection DF: %s\n",o->m_pPlProj->m_sName); if (g_bRevSDF) mprintf(" - Pseudo SDF: %s\n",o->m_pRevSDF->m_sName); if (g_bNbAnalysis) mprintf(" - Neighborhood Analysis: %s\n",o->m_pNbAnalysis->m_sName); if (g_bVACF) mprintf(" - VACF: %s\n",o->m_pVACF->m_sName); if (g_bMSD) mprintf(" - MSD: %s\n",o->m_pMSD->m_sName); if (g_bVHDF) mprintf(" - VHDF: %s\n",o->m_pVHDF->m_sName); if (g_bCDF) { mprintf(" - Combined Distribution Function:\n"); for (z3=0;z3m_pRDF[z3] != NULL) mprintf(" - Channel %d: RDF: %s\n",z3+1,o->m_pRDF[z3]->m_sName); if (o->m_pADF[z3] != NULL) mprintf(" - Channel %d: ADF: %s\n",z3+1,o->m_pADF[z3]->m_sName); if (o->m_pDDF[z3] != NULL) mprintf(" - Channel %d: DDF: %s\n",z3+1,o->m_pDDF[z3]->m_sName); if (o->m_pDipDF[z3] != NULL) mprintf(" - Channel %d: DipDF: %s\n",z3+1,o->m_pDipDF[z3]->m_sName); if (o->m_pVDF[z3] != NULL) mprintf(" - Channel %d: VDF: %s\n",z3+1,o->m_pVDF[z3]->m_sName); if (o->m_pPlDF[z3] != NULL) mprintf(" - Channel %d: PlDF: %s\n",z3+1,o->m_pPlDF[z3]->m_sName); if (o->m_pLiDF[z3] != NULL) mprintf(" - Channel %d: LiDF: %s\n",z3+1,o->m_pLiDF[z3]->m_sName); } } else { if (g_bRDF) mprintf(" - RDF: %s\n",o->m_pRDF[0]->m_sName); if (g_bDipDF) mprintf(" - DipDF: %s\n",o->m_pDipDF[0]->m_sName); if (g_bADF) mprintf(" - ADF: %s\n",o->m_pADF[0]->m_sName); if (g_bDDF) mprintf(" - DDF: %s\n",o->m_pDDF[0]->m_sName); if (g_bVDF) mprintf(" - VDF: %s\n",o->m_pVDF[0]->m_sName); if (g_bPlDF) mprintf(" - PlDF: %s\n",o->m_pPlDF[0]->m_sName); if (g_bLiDF) mprintf(" - LiDF: %s\n",o->m_pLiDF[0]->m_sName); } } mprintf(WHITE,"\n<<< End of Observation List <<<\n\n"); } _endobs: if (!Interface_BeforeAnalysis2()) return false; if (g_bVACF && g_bGlobalVACF) { try { g_pGlobalVACF = new CACF(); } catch(...) { g_pGlobalVACF = NULL; } if (g_pGlobalVACF == NULL) NewException((double)sizeof(CACF),__FILE__,__LINE__,__PRETTY_FUNCTION__); mprintf(WHITE,"\n>>> Global velocity autocorrelation function >>>\n\n"); g_pGlobalVACF->Parse(); mprintf(WHITE,"\n<<< End of global velocity autocorrelation function <<<\n\n"); } if (g_bIRSpec && g_bGlobalIR) { try { g_pGlobalIR = new CReorDyn(); } catch(...) { g_pGlobalIR = NULL; } if (g_pGlobalIR == NULL) NewException((double)sizeof(CReorDyn),__FILE__,__LINE__,__PRETTY_FUNCTION__); mprintf(WHITE,"\n*** Definition of system-wide IR spectrum ***\n\n"); g_pGlobalIR->ParseSpec(); } if (g_bSDF) { g_bSDFMap = AskYesNo(" Map a quantity to the surface of the SDF (y/n)? [no] ",false); if (g_bSDFMap) { _sdfmapnext: CSDFMap *sma; sma = new CSDFMap(); g_oaSDFMaps.Add(sma); sma->Parse(); if (AskYesNo(" Map another quantity to the surface of the SDF (y/n)? [no] ",false)) goto _sdfmapnext; mprintf("\n"); } } if (g_bSDF || g_bCreateRevSDF) { g_iSDFSmoothGrade = AskInteger(" Up to which degree should the SDFs be smoothened (0=not at all)? [2] ",2); if (g_bSDFMap) g_iSDFMapSmoothGrade = AskInteger(" Up to which degree should the SDF surface maps be smoothened (0=not at all)? [2] ",2); if (g_bSDF) { _sdf_norm_again: g_bSDFUniform = AskYesNo(" Calculate SDF values in nm^-3 (n) or relative to uniform density (y)? [no] ",false); if (g_bSDFUniform && ((!g_bPeriodicX) || (!g_bPeriodicY) || (!g_bPeriodicZ))) { eprintf("\n Error: Uniform particle density is only defined for XYZ-periodic systems.\n\n"); goto _sdf_norm_again; } } // g_iSDFScale = AskRangeInteger(" SDF values in ppm (1), pm^-3 (2), nm^-3 (3) or rel. to uniform density (4)? [4] ",1,4,4) - 1; // g_iSDFScale = 2; // nm^-3 } else if (g_bCDF && (g_iCDFChannels == 3)) g_iSDFSmoothGrade = AskInteger(" Up to which degree should the 3D CDFs be smoothened (0=not at all)? [2] ",2); // if (g_bVDF || g_bSVDF) // g_bSaveVelForce = AskYesNo(" Save maximum/averaged velocity time development (y/n)? [yes] ",true); // if (g_bVDF || g_bFDF) // { // g_fVelPercentage = AskFloat(" Which percentage of all velocities/forces to take into account? [95] ",95.0f); // g_fForcePercentage = g_fVelPercentage; // } g_bSaveVelForce = false; if ((g_bSDF && g_bAdvanced2) || g_bSaveRefEnv || g_bCutCluster || g_bSaveJustTraj) { mprintf(WHITE,"\n>>> Coordinate output options >>>\n\n"); if ((g_bSDF && g_bAdvanced2) || g_bSaveRefEnv || g_bCutCluster) { if (g_bAdvanced2) g_bWriteAtomwise = (AskRangeInteger(" Sort output coordinates by molecules (0) or by element types (1)? [molecules] ",0,1,0)!=0); else g_bWriteAtomwise = false; } g_bSaveVirtAtoms = AskYesNo(" Write also virtual atoms (center of mass, ...) (y/n)? [no] ",false); if (g_bSaveVirtAtoms) { if (AskYesNo(" Ref.Env.: Use alias names (instead of #) for virtual atoms (y/n)? [no] ",false)) { for (z2=0;z2m_baAtomIndex.GetSize();z++) { if (m->m_baAtomIndex[z] != g_iVirtAtomType) continue; for (z3=0;z3m_waAtomCount[z];z3++) { mprintf(" How to name atom #%d in %s? [#%d] ",z3+1,m->m_sName,z3+1); inpprintf("! How to name atom #%d in %s? [#%d]\n",z3+1,m->m_sName,z3+1); myget(&buf); if (strlen(buf) != 0) strcpy(((CVirtualAtom*)g_oaVirtualAtoms[m->m_laVirtualAtoms[z3]])->m_sLabel,buf); } } } } } if (g_bSaveRefEnv || g_bCutCluster) g_bEnvWriteDetailedInfo = AskYesNo(" Write detailed (long) comment lines into output xyz file (y/n)? [yes] ",true); else g_bEnvWriteDetailedInfo = false; if ((g_bSaveRefEnv || g_bCutCluster) && !g_bEnvDisableSortNb) g_bEnvSortNb = AskYesNo(" Sort molecules according to distance from reference molecule (y/n)? [yes] ",true); else g_bEnvSortNb = false; mprintf(WHITE,"\n<<< End of Coordinate output options <<<\n\n"); } else { g_bWriteAtomwise = false; g_bSaveVirtAtoms = false; } if (g_bSaveRefEnv || g_bCutCluster) g_bCenterZero = AskYesNo(" Put the center of the system to (0|0|0) (y) or to (x/2|y/2|z/2) (n)? [yes] ",true); g_bMiddleAvg = false; g_iSwapAtoms = 0; if (g_bSaveJustTraj) { mprintf(WHITE,"\n>>> Process Trajectory >>>\n\n"); if (g_bAdvanced2) g_bSaveTrajNoRot = AskYesNo(" Remove angular momentum from trajectory (y/n)? [no] ",false); else g_bSaveTrajNoRot = false; if (g_bSaveTrajNoRot) { mprintf("\n This centers the mass center of the system. All atoms of the system are saved.\n\n"); g_bSaveCoordsUnchanged = false; g_bSaveJustCenter = false; if(AskYesNo(" Put the center of the system to (0|0|0) (y) or to (x/2|y/2|z/2) (n)? [yes] ",true)) g_bCenterZero = true; else g_bCenterZero = false; goto _norot; } else { switch(AskRangeInteger(" Put the center of the system to (0|0|0) (0), to (x/2|y/2|z/2) (1), or leave coords unchanged (2)? [1] ",0,2,1)) { case 0: g_bCenterZero = true; g_bSaveCoordsUnchanged = false; break; case 1: g_bCenterZero = false; g_bSaveCoordsUnchanged = false; break; case 2: g_bSaveCoordsUnchanged = true; break; } if (!g_bSaveCoordsUnchanged) g_bSaveJustCenter = AskYesNo("\n Put a specific atom into the box center (y/n)? [no] ",false); else g_bSaveJustCenter = false; } if (g_bSaveJustCenter) { if (g_oaMolecules.GetSize() > 1) { // sprintf(buf," Choose center atom from which of the molecules ("); buf.sprintf(" Choose center atom from which of the molecules ("); for (z=0;zm_sName,z+1); // strcat(buf,buf2); // if (z < g_oaMolecules.GetSize()-1) // strcat(buf,", "); buf2.sprintf("%s=%d",((CMolecule*)g_oaMolecules[z])->m_sName,z+1); buf.strcat(buf2); if (z < g_oaMolecules.GetSize()-1) buf.strcat(", "); } // strcat(buf,")? "); buf.strcat(")? "); g_iSaveJustMol = AskRangeInteger_ND("%s",1,g_oaMolecules.GetSize(),(const char*)buf) - 1; } else { g_iSaveJustMol = 0; mprintf(" Choosing center atom from %s.\n",((CMolecule*)g_oaMolecules[0])->m_sName); } if (((CMolecule*)g_oaMolecules[g_iSaveJustMol])->m_laSingleMolIndex.GetSize() > 1) g_iSaveJustSM = AskRangeInteger(" Take which representant from %s (1-%d)? [1] ",1,((CMolecule*)g_oaMolecules[g_iSaveJustMol])->m_laSingleMolIndex.GetSize(),1,((CMolecule*)g_oaMolecules[g_iSaveJustMol])->m_sName,((CMolecule*)g_oaMolecules[g_iSaveJustMol])->m_laSingleMolIndex.GetSize()) - 1; else g_iSaveJustSM = 0; _proccenter: AskString(" Which atom from %s %d to put into the box center? [#2] ",&buf,"#2",((CMolecule*)g_oaMolecules[g_iSaveJustMol])->m_sName,g_iSaveJustSM+1); if (!ParseAtom(buf,g_iSaveJustMol,g_iSaveJustAtomType,g_iSaveJustRealAtomType,g_iSaveJustAtom)) goto _proccenter; } g_iSaveGesAtoms = 0; if (!AskYesNo(" Save all atoms in the system (y/n)? [yes] ",true)) { mprintf("\n"); for (z=0;zm_sName)) { try { ag = new CAtomGroup(); } catch(...) { ag = NULL; } if (ag == NULL) NewException((double)sizeof(CAtomGroup),__FILE__,__LINE__,__PRETTY_FUNCTION__); g_oaSaveMolecules.Add(ag); _savejust1: mprintf(" Which atoms to save from %s (e.g. \"C1,C3-5,H\")? [all] ",((CMolecule*)g_oaMolecules[z])->m_sName); inpprintf("! Which atoms to save from %s (e.g. \"C1,C3-5,H\")? [all]\n",((CMolecule*)g_oaMolecules[z])->m_sName); myget(&buf); if (strlen(buf)==0) ag->AddAllAtoms((CMolecule*)g_oaMolecules[z],g_bSaveVirtAtoms); else if (!ag->ParseAtoms((CMolecule*)g_oaMolecules[z],buf)) goto _savejust1; g_iSaveGesAtoms += ag->m_iAtomGes * ((CMolecule*)g_oaMolecules[z])->m_laSingleMolIndex.GetSize(); } } } else { _norot: for (z=0;zAddAllAtoms((CMolecule*)g_oaMolecules[z],g_bSaveVirtAtoms); g_iSaveGesAtoms += ag->m_iAtomGes * ((CMolecule*)g_oaMolecules[z])->m_laSingleMolIndex.GetSize(); } } if (g_bUnknownElements) { g_bUnwrapWannier = AskYesNo(" Write out Wannier centers together with trajectory (y/n)? [no] ",false); if (g_bUnwrapWannier) ParseDipole(); } else g_bUnwrapWannier = false; if ((!g_bSaveCoordsUnchanged) && (!g_bSaveTrajNoRot)) g_bUnwrap = AskYesNo(" Try to unwrap the trajectory (y/n)? [no] ",false); else g_bUnwrap = false; if (g_bUnwrap && g_bNPT) { mprintf("\n"); mprintf(RED," Warning: "); mprintf("Unwrapping does *not* work with variable cell vector (NpT ensemble)!\n"); mprintf(" The output trajectory will be only valid if the cell vector is constant in all frames.\n\n"); if (!AskYesNo(" Acknowledged (y/n): [yes] ",true)) return false; } if (g_bBoxNonOrtho) { mprintf("\n"); g_bWriteOrtho = AskYesNo(" Write \"orthonormalized\" coordinates (y/n)? [no] ",false); if (g_bWriteOrtho) { g_fWriteOrthoFac = AskFloat(" Enter scaling factor (x,y,z coordinates will range from 0 to this value) in pm: [%.4f] ",mypow(g_fBoxVolume,1.0/3.0)*100.0,mypow(g_fBoxVolume,1.0/3.0)*100.0); mprintf("\n"); } } if (g_bUnwrap) mprintf("\n Attention! This feature only works if the time step\n in the trajectory is quite small. One particle may never\n move further than half of the box length in one time step!\n"); mprintf(WHITE,"\n Saving %lu atoms per step:\n",g_iSaveGesAtoms); for (z2=0;z2m_pMolecule->m_sName); for (z=0;zm_baAtomType.GetSize();z++) { for (z3=0;z3<((CxIntArray*)ag->m_oaAtoms[z])->GetSize();z3++) { mprintf("%s%d",(const char*)((CAtom*)g_oaAtoms[ag->m_baRealAtomType[z]])->m_sName,((CxIntArray*)ag->m_oaAtoms[z])->GetAt(z3)+1); if (z3 < ((CxIntArray*)ag->m_oaAtoms[z])->GetSize()-1) mprintf(", "); } if (z+1 < ag->m_baAtomType.GetSize()) mprintf(", "); } mprintf("\n"); } // g_bTrajAtomwise = (AskRangeInteger("\n Save trajectory ordered molecule-wise (0) or atom-wise (1)? [0] ",0,1,0)!=0); mprintf("\n"); if (g_bAdvanced2) { if ((int)g_iSaveGesAtoms == g_iGesAtomCount) { switch(AskRangeInteger(" Sort output coordinates by molecules (0), element types (1), or input file order (2)? [0] ",0,2,0)) { case 0: g_bWriteAtomwise = false; g_bWriteInputOrder = false; break; case 1: g_bWriteAtomwise = true; g_bWriteInputOrder = false; break; case 2: g_bWriteAtomwise = false; g_bWriteInputOrder = true; break; default: eprintf("Internal error.\n"); abort(); } } else { g_bWriteAtomwise = (AskRangeInteger(" Sort output coordinates by molecules (0) or by element types (1)? [0] ",0,1,0)!=0); g_bWriteInputOrder = false; } } else { g_bWriteAtomwise = false; g_bWriteInputOrder = false; } g_bProcAlternativeLabels = AskYesNo(" Change atom labels of some atoms in output trajectory (y/n)? [no] ",false); if (g_bProcAlternativeLabels) { try { ag2 = new CAtomGroup(); } catch(...) { ag2 = NULL; } if (ag2 == NULL) NewException((double)sizeof(CAtomGroup),__FILE__,__LINE__,__PRETTY_FUNCTION__); for (z=0;zm_pMolecule->m_sName)) continue; while (true) { mprintf("\n Which atoms to relabel in %s (e.g. \"C1,C3-5\")? [done] ",(const char*)ag->m_pMolecule->m_sName); inpprintf("! Which atoms to relabel in %s (e.g. \"C1,C3-5,H\")? [done]\n",(const char*)ag->m_pMolecule->m_sName); myget(&buf); if (buf.GetLength() == 0) break; if (!ag2->ParseAtoms(ag->m_pMolecule,buf)) continue; AskString_ND(" Enter output element label for these atoms: ",&buf); for (z=0;zm_baAtomType.GetSize();z++) for (z3=0;z3<((CxIntArray*)ag2->m_oaAtoms[z])->GetSize();z3++) for (z4=0;z4m_pMolecule->m_laSingleMolIndex.GetSize();z4++) *((CxString*)g_oaProcAlternativeLabels[((CxIntArray*)((CSingleMolecule*)g_oaSingleMolecules[ag2->m_pMolecule->m_laSingleMolIndex[z4]])->m_oaAtomOffset[ag2->m_baAtomType[z]])->GetAt(((CxIntArray*)ag2->m_oaAtoms[z])->GetAt(z3))]) = buf; } } delete ag2; mprintf(WHITE,"\n Relabeled the following atoms in output trajectory:\n\n"); for (z2=0;z2m_baAtomType.GetSize();z++) { for (z3=0;z3<((CxIntArray*)ag->m_oaAtoms[z])->GetSize();z3++) { ti = ((CxIntArray*)((CSingleMolecule*)g_oaSingleMolecules[ag->m_pMolecule->m_laSingleMolIndex[0]])->m_oaAtomOffset[ag->m_baAtomType[z]])->GetAt(((CxIntArray*)ag->m_oaAtoms[z])->GetAt(z3)); if (((CxString*)g_oaProcAlternativeLabels[ti])->GetLength() != 0) { if (!tb) { mprintf(" - In %s:\n",ag->m_pMolecule->m_sName); tb = true; } mprintf(" %2s%-3d ---> %6s\n",(const char*)((CAtom*)g_oaAtoms[ag->m_baRealAtomType[z]])->m_sName,((CxIntArray*)ag->m_oaAtoms[z])->GetAt(z3)+1,(const char*)*((CxString*)g_oaProcAlternativeLabels[ti])); } } } if (tb) mprintf("\n"); } } if (g_bAdvanced2) { g_bProcWriteComments = AskYesNo(" Write comments (atom label and molecule) behind each line in output trajectory (y/n)? [no] ",false); g_bProcDumpAwkScript = AskYesNo(" Create a shell script for resorting other XYZ files (e.g., velocity/force trajectories) (y/n)? [no] ",false); g_bProcCellComment = AskYesNo(" Write the cell geometry to the XYZ comment line (y/n)? [no] ",false); if (g_bProcCellComment) { if (g_bBoxNonOrtho) g_bProcCellCommentAngles = AskYesNo(" Write cell edge lengths and angles (y) or only edge lengths (n)? [yes] ",true); else g_bProcCellCommentAngles = AskYesNo(" Write cell edge lengths and angles (y) or only edge lengths (n)? [no] ",false); } } else { g_bProcWriteComments = false; g_bProcDumpAwkScript = false; g_bProcCellComment = false; } if (g_bAdvanced2) { g_bProcSplit = AskYesNo(" Split the trajectory into parts (y/n)? [no] ",false); if (g_bProcSplit) g_iProcSplitLength = AskUnsignedInteger(" Enter the number of time steps in each part: [1000] ",1000); } else { g_bProcSplit = false; g_iProcSplitLength = -1; } if (g_bAdvanced2) { mprintf("\n"); g_bProcAddMesh = AskYesNo(" Add a mesh of atoms to the saved trajectory (y/n)? [no] ",false); if (g_bProcAddMesh) { mprintf("\n"); if (!g_bPeriodicX || !g_bPeriodicY || !g_bPeriodicZ) { eprintf("Error: This only works with a XYZ-periodic cell.\n\n"); abort(); } mprintf(" The meshes will be periodic with respect to the unit cell entered above.\n\n"); AskString(" Which atom label to use for the mesh atoms? [Ne] ",&g_sProcAddMeshLabel,"Ne"); mprintf("\n"); g_bProcAddMeshZ = AskYesNo(" Add a mesh in the X-Y plane (y/n)? [yes] ",true); if (g_bProcAddMeshZ) { if (g_bCenterZero) tf = -g_fBoxZ/2.0; else tf = 0; g_fProcAddMeshZPos = AskFloat(" At which Z position to add the mesh in the X-Y plane? [%.3f] ",tf,tf); mprintf("\n"); } g_bProcAddMeshY = AskYesNo(" Add a mesh in the X-Z plane (y/n)? [yes] ",true); if (g_bProcAddMeshY) { if (g_bCenterZero) tf = -g_fBoxY/2.0; else tf = 0; g_fProcAddMeshYPos = AskFloat(" At which Y position to add the mesh in the X-Z plane? [%.3f] ",tf,tf); mprintf("\n"); } g_bProcAddMeshX = AskYesNo(" Add a mesh in the Y-Z plane (y/n)? [yes] ",true); if (g_bProcAddMeshX) { if (g_bCenterZero) tf = -g_fBoxX/2.0; else tf = 0; g_fProcAddMeshXPos = AskFloat(" At which X position to add the mesh in the Y-Z plane? [%.3f] ",tf,tf); mprintf("\n"); } g_iProcAddMeshGrid = AskUnsignedInteger(" Enter grid resolution for mesh: [8] ",8); g_bProcAddMeshJitter = AskYesNo(" Add random jitter to mesh atoms (e.g. to avoid Voronoi degeneracies, y/n)? [yes] ",true); if (g_bProcAddMeshJitter) g_fProcAddMeshJitter = AskFloat(" Enter the amount of random jitter on mesh atom coordinates (in pm): [1.0] ",1.0); } } else g_bProcAddMesh = false; mprintf(WHITE,"\n<<<< End of Process Trajectory <<<\n\n"); } else g_bUnwrap = false; if (g_bUnwrap) { g_vaUnwrapArray.SetSize(g_oaSingleMolecules.GetSize()); for (z=0;z 1) ti = AskRangeInteger_ND(" Take atom from which molecule type (1-%d)? ",1,g_oaMolecules.GetSize(),g_oaMolecules.GetSize()) - 1; else ti = 0; if (((CMolecule*)g_oaMolecules[ti])->m_laSingleMolIndex.GetSize() > 1) ti2 = AskRangeInteger_ND(" Take atom from which molecule of %s (1-%d)? ",1,((CMolecule*)g_oaMolecules[ti])->m_laSingleMolIndex.GetSize(),((CMolecule*)g_oaMolecules[ti])->m_sName,((CMolecule*)g_oaMolecules[ti])->m_laSingleMolIndex.GetSize()) - 1; else ti2 = 0; AskString(" Which atom to take from %s %d? [#2] ",&buf,"#2",((CMolecule*)g_oaMolecules[ti])->m_sName,ti2+1); ParseAtom((const char*)buf,ti,ty,rty,atom); g_iRemoveCOMFixAtom = ((CxIntArray*)((CSingleMolecule*)g_oaSingleMolecules[((CMolecule*)g_oaMolecules[ti])->m_laSingleMolIndex[ti2]])->m_oaAtomOffset[ty])->GetAt(atom); mprintf(" The atom has offset %d.\n\n",g_iRemoveCOMFixAtom); } else g_iRemoveCOMFixAtom = -1; } if (g_bUseVelocities && (g_fTimestepLength > 1.0) && !g_bROA) { mprintf(RED," Warning: "); mprintf("Atom velocities are obtained from positions by numerical differentiation.\n"); mprintf(" This is only reliable for trajectory timestep distances <= approx. 1 fs.\n"); mprintf(" Your timestep distance is %.2f fs, which is larger than 1 fs.\n\n",g_fTimestepLength); if (!AskYesNo(" Proceed anyway (y/n)? [yes] ",true)) return false; } if (g_TimeStep.GetCommentNumberCount() > 0) { g_bSkipDoubleSteps = AskYesNo(" Skip repeated time steps (y/n)? [no] ",false); if (g_bSkipDoubleSteps) { mprintf("\n"); mprintf(" The comment line is \"%s\".\n",g_TimeStep.m_pComment); if (g_TimeStep.GetCommentNumberCount() > 1) { if (!AskYesNo(" Does this line contain the time step number (y/n)? [yes] ",true)) g_bSkipDoubleSteps = false; if (g_bSkipDoubleSteps) { // sprintf(buf," Choose the time step number: "); buf.sprintf(" Choose the time step number: "); for (z=0;z= 1.\n"); goto _intervalagain; } if (ti != -1) { g_laMultiIntervalStart.Add(ti-1); g_laMultiIntervalEnd.Add(AskUnsignedInteger_ND(" Enter ending time step of %d. interval: ",g_laMultiIntervalStart.GetSize())-1); goto _intervalagain; } } mprintf(WHITE,"\n* %d Intervals have been defined:\n",g_laMultiIntervalStart.GetSize()); for (z=0;z= 0) { if (g_bMSD) { for (z=0;zm_pMSD->m_iResolution > ti) { eprintf("\n MSD resolution of %d requires at least %d time steps, but using only %d steps.\n This will lead to erroneous results!\n\n",o->m_pMSD->m_iResolution,o->m_pMSD->m_iResolution,ti); if (!AskYesNo(" Continue anyway (y/n)? [yes] ",true)) return false; goto _lessstepdone; } } } if (g_bRDyn) { for (z=0;zm_pRDyn->m_iDepth*o->m_pRDyn->m_iStride > ti) { eprintf("\n Reorientation dynamics resolution of %d requires at least %d time steps, but using only %d steps.\n This will lead to erroneous results!\n\n",o->m_pRDyn->m_iDepth*o->m_pRDyn->m_iStride,o->m_pRDyn->m_iDepth*o->m_pRDyn->m_iStride,ti); if (!AskYesNo(" Continue anyway (y/n)? [yes] ",true)) return false; goto _lessstepdone; } } } if (g_bIRSpec) { for (z=0;zm_pIRSpec->m_iDepth*o->m_pIRSpec->m_iStride > ti) { eprintf("\n IR spectrum resolution of %d requires at least %d time steps, but using only %d steps.\n This will lead to erroneous results!\n\n",o->m_pIRSpec->m_iDepth*o->m_pIRSpec->m_iStride,o->m_pIRSpec->m_iDepth*o->m_pIRSpec->m_iStride,ti); if (!AskYesNo(" Continue anyway (y/n)? [yes] ",true)) return false; goto _lessstepdone; } } } } _lessstepdone: if (g_bScanVelocities) { mprintf(WHITE,"\n>>> Velocity Pre-Analysis >>>\n\n"); g_iScanVelStart = AskUnsignedInteger(" Start in which time step for velocity pre-analysis? [0] ",0); g_iScanVelSteps = AskUnsignedInteger(" Use how many time steps from this point on for vel. pre-analysis? [all] ",0); g_iScanVelStride = AskUnsignedInteger(" Use every n-th step for velocity pre-analysis? [10] ",10); mprintf(WHITE,"\n<<< End of Velocity Pre-Analysis <<<\n"); } if (g_bSaveRefEnv && (g_iNbhMode == 3)) { mprintf(WHITE,"\n>>> Neighborhood Pre-Analysis >>>\n\n"); g_iScanNbhStart = AskUnsignedInteger(" Start in which time step for neighborhood analysis? [0] ",0); g_iScanNbhSteps = AskUnsignedInteger(" Use how many time steps from this point on for nbh analysis? [all] ",0); g_iScanNbhStride = AskUnsignedInteger(" Use every n-th step for the neighborhood analysis? [10] ",10); mprintf(WHITE,"\n<<< End of Neighborhood Pre-Analysis <<<\n"); } mprintf(WHITE,"\n########## All information collected ##########\n\n"); BTOUT; return true; } /* a = fopen("struct.xyz","wt"); mfprintf(a,"%d\n\n",g_iGesAtomCount*20); FILE *b; for (z=0;z<20;z++) { g_pTempTimestep = new CTimeStep(); g_pTempTimestep->CopyFrom(&g_TimeStep); g_pTempTimestep->CenterCOM(); CxDMatrix3 ma; CxVector3 vec1; vec1[0] = ((rand()%20001)-10000)/10000.0; vec1[1] = ((rand()%20001)-10000)/10000.0; vec1[2] = ((rand()%20001)-10000)/10000.0; vec1.Normalize(); tf = (rand()%10000)/10000.0*2.0*Pi; ma.RotMat(vec1,tf); g_pTempTimestep->Transform(ma); vec1[0] = (rand()%20000)/10.0; vec1[1] = (rand()%20000)/10.0; vec1[2] = (rand()%20000)/10.0; for (z2=0;z2m_vaCoords[z2] += vec1; sprintf(buf,"coord_%02d.xyz",z+1); b = fopen(buf,"wt"); // mfprintf(b,"%d\n\n",g_iGesAtomCount); for (z2=0;z2m_sName,g_pTempTimestep->m_vaCoords[z2][0]/100.0,g_pTempTimestep->m_vaCoords[z2][1]/100.0,g_pTempTimestep->m_vaCoords[z2][2]/100.0); mfprintf(b,"%s %f %f %f\n",((CAtom*)g_oaAtoms[g_waAtomRealElement[z2]])->m_sName,g_pTempTimestep->m_vaCoords[z2][0]/100.0,g_pTempTimestep->m_vaCoords[z2][1]/100.0,g_pTempTimestep->m_vaCoords[z2][2]/100.0); } fclose(b); } fclose(a);*/ travis-src-190101/src/globalvar.cpp0100777000000000000000000003513413412725632014121 0ustar00/***************************************************************************** TRAVIS - Trajectory Analyzer and Visualizer http://www.travis-analyzer.de/ Copyright (c) 2009-2019 Martin Brehm 2012-2019 Martin Thomas 2016-2019 Sascha Gehrke This file was written by Martin Brehm and Martin Thomas. --------------------------------------------------------------------------- This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . *****************************************************************************/ // This must always be the first include directive #include "config.h" #include "travis.h" #include "tools.h" #include "database.h" #include "statistics.h" #include "maintools.h" #include "vorowrapper.h" #include "globalvar.h" #include "reactive.h" const char *GetRevisionInfo_globalvar(unsigned int len) { static char buf[256]; GET_REVISION_INFO( buf, len ); return buf; } const char *GetSourceVersion_globalvar() { static char buf[256]; GET_SOURCE_VERSION( buf ); return buf; } CxObArray g_oaAtoms; // Die Atomsorten der Simulation CxObArray g_oaMolecules; // Die Molekuelsorten der Simulation CxObArray g_oaSingleMolecules; CxObArray g_oaObserv; CxObArray g_oaVirtualAtoms; CTimeStep g_TimeStep; char g_iFixMol; // Welches Molekuel fixieren wir? int g_iFixAtomType[3]; // Welches Element fixieren wir? (3 mal wegen den 3 Fixpunkten) int g_iFixRealAtomType[3]; // Wie Eben, nur Index auf g_pAtoms int g_iFixAtom[3]; // Welche Atome in in dem Molekuel fixieren? int g_iCurrentTimeStep, g_iLastTimeStep, g_iNextTimeStep; unsigned long g_iSteps; // Zaehler fuer die schon verarbeiteten Zeitschritte unsigned char g_iBinning; bool g_bFold; bool g_bWarnUnsteady; double g_fUnsteadyLimit = 10000000.0; // Unit is pm/ps FILE *g_fSaveJustTraj; unsigned char g_iVirtAtomType; double g_fVelLimit, g_fForceLimit; double g_fMSVDFLevel, g_fMSFDFLevel; bool g_bCalcVel, g_bCalcForces; bool g_bManSVDFLevel, g_bManSFDFLevel; bool g_bManSMeanVDFLevel, g_bManSMeanFDFLevel; bool g_bManSMaxVDFLevel, g_bManSMaxFDFLevel; double g_fSVDFLevel[16]; double g_fSMeanVDFLevel[16]; double g_fSMaxVDFLevel[16]; double g_fSFDFLevel[16]; double g_fSMeanFDFLevel[16]; double g_fSMaxFDFLevel[16]; //char g_sRefEnv[256]; CxString g_sRefEnv; bool g_bUseVelocities; bool g_bUseForces; double g_fBoxX, g_fBoxY, g_fBoxZ; CxDVec3Array g_pRefMol; // Die Koordinaten des Referenzmolekueles (zum akkumulieren) bool g_bAvg; // Gemitteltes Referenzmolekuel ausgeben bool g_bMiddleAvg; // Soll das Referenzmolekuel wirklich gemittelt werden (true), oder soll einfach das erstbeste Molekuel genommen werden (false)? int g_iGesAtomCount; // Gesamtzahl der Atome pro Zeitschritt - also in der Simulation int g_iGesVirtAtomCount; int g_iMaxStep; // Bis zu welchem Zeitschritt geht die Analyse? -1 fuer alle unsigned char g_iSwapAtoms; // Sollen Atome, die sich frei drehen oder sich vertauschen, zurueckgetauscht werden? unsigned char g_iNormSDF; // 0 - jede SDF einzeln auf 100, 1 - gar nicht normieren unsigned char g_iSVDFLevel, g_iSFDFLevel; //char g_pAtomMassLabels[][3] = { "H", "He", "Li", "B", "C", "N", "O", "F", "Na", "Al", "Si", "P", "S", "Cl", "Ru", "Pt", "Br", "Fe", "U" }; //unsigned char g_iAtomMassCount = 19; //double g_fAtomMass[] = { 1.f, 4.f, 7.f, 11.f, 12.f, 14.f, 16.f, 19.f, 23.f, 27.f, 28.f, 31.f, 32.f, 35.45f, 101.07f, 195.1f, 79.9f, 55.8f, 238.0f }; //double g_fAtomRadius[] = { 0.37f, 0.32f, 1.34f, 0.9f, 0.82f, 0.77f, 0.75f, 0.73f, 0.71f, 1.54f, 1.18f, 1.11f, 1.06f, 1.02f, 0.99f, 1.3f, 1.f, 1.52f, 1.0f }; //double g_fAtomVDWRadius[] = { 1.20f, 1.22f, 0.f, 2.08f, 1.85f, 1.54f, 1.40f, 1.35f, 2.31f, 2.05f, 2.f, 1.9f, 1.85f, 1.81f, 1.46f, 10.f, 2.0f, 1.52f, 1.42f }; bool g_bMegaMat; bool g_bMatOnlyBind; bool g_bVFHisto; unsigned short g_iHistogramRes = 256; FILE *g_fRefTrajec, *g_fRefEnv, *g_fVRDF[32]; CTimeStep *g_pTempTimestep; bool g_bFoldAtomwise; double g_fBondFactor; bool g_bSaveJustTraj; //bool g_bRefEnvVirt; bool g_bSaveVirtAtoms; FILE *g_fVFCorr[64]; unsigned short g_iVFCorrCount; //bool g_bDynamicNeighbor; bool g_bSaveRefWithEnv; bool g_bRefEnvCenter; //bool g_bScanNeighbors; bool g_bPeriodicX, g_bPeriodicY, g_bPeriodicZ; bool g_bPeriodic; int g_iStride; CAsciiArt g_oAsciiArt; CTimeStep *g_pT2Timestep; //CNbSearch *g_pNbAll; int g_iClusterPos; CxByteArray g_baAtomIndex; //bool g_bRefEnvAtomwise; bool g_bScanMolecules; CACF *g_pGlobalVACF; CACF *g_pGlobalDipACF; int g_iRefSystemDim; //bool g_bSaveTrajVirt; FILE *g_fPos, *g_fVel, *g_fForce; double g_fTimestepLength; CFFT *g_pFFT; long g_iHighestStepNumber; int g_iDotCounter; bool g_bStepSkipped; bool g_bAbortAnalysis; //int g_iMSDDepth; CxIntArray g_laBondBlackList; int g_iBondBlackListUsed; int g_iFirstStepSkipped; bool g_bGlobalPsycho; int g_iWannierAtomType; double g_fWannierCharge; bool g_bCombinedDF; bool g_bSDF, g_bRDF; bool g_bVDF, g_bFDF, g_bADF; bool g_bDipole; CxObArray g_oaAnalysisGroups; CxObArray g_oaAnalyses; int g_iStepHistory; CxObArray g_oaTimeSteps; double g_fMaxVel, g_fMaxForce; double g_fLMaxVel, g_fLMaxForce; double g_fLMidVel, g_fLMidForce; bool g_bAsciiArt; //char g_sInputVel[256]; //char g_sInputForce[256]; //char g_sInputCtrl[256]; CxString g_sInputVel; CxString g_sInputForce; CxString g_sInputCtrl; CDatabase *g_pDatabase; CxIntArray g_laAtomSMIndex; // Enthaelt fuer jedes Atom, in welchem SingleMolecule es sich befindet, oder -1 wenn gar nicht CxIntArray g_laAtomSMLocalIndex; //CxWordArray g_waAtomMolElem; // Enthaelt fuer jedes Atom den Index im m_oaMolAtoms-Array des SingleMolecules CxWordArray g_waAtomElement; CxWordArray g_waAtomMolNumber; CxWordArray g_waAtomMolIndex; CxWordArray g_waAtomMolUID; CxWordArray g_waAtomRealElement; CxDoubleArray g_faAtomCode; std::vector g_liAtomCode; CxDoubleArray g_faVdWRadius; CxObArray g_oaMolAtoms; CxByteArray g_baAtomPassedCondition; int g_iCDFChannels; bool g_bWannier; int g_iScanMolStep; char *g_sInputTraj; bool g_bCDF; int *g_iObsChannel; // 1 - RDF, 2 - ADF, 3 - DDF, 4 - DipDF, 5 - VDF, 6 - FDF bool g_bDDF; bool g_bRevSDF; bool g_bMSD; bool g_bCutCluster; bool g_bSaveRefEnv; unsigned char g_iSaveRefMol; bool g_bRefEnvFix; //int g_iNbStride; //bool g_bKeepNbCount; int g_iClusterSteps, g_iClusterCount; CxIntArray g_iaClusterSteps, g_iaClusterMol; bool g_bNbAnalysis; bool g_bVHDF; //CxObArray g_oaNbSearches; CNbSet *g_pNbSet; bool g_bVACF; bool g_bVFDF; bool g_bGlobalVACF; bool g_bGlobalDipACF; int g_iSDFSmoothGrade; bool g_bACFWindowFunction; //int g_iMSDStride; //int g_iVHDFDepth; //int g_iVHDFStride; //int g_iVHDFMinDepth; bool g_bSaveVelForce; double g_fVelPercentage, g_fForcePercentage; //bool g_bRefNoVirt; unsigned long g_iSaveGesAtoms; bool g_bUnwrap; CxObArray g_oaSaveMolecules; //bool g_bTrajAtomwise; CxDVec3Array g_vaUnwrapArray; int g_iBeginStep; bool g_bSkipDoubleSteps; //bool g_bUseMassCenters; int g_iNumberPos; // Die wievielte Nummer in der XYZ-Kommentarzeile ist die Schrittzahl? FILE *g_fInput; bool g_bDipACF; //int g_iMaxACFDepth; bool g_bACF; bool g_bDipDF; bool g_bInputRedirected; //int g_iSDFScale; // 0 = ppm, 1 = pm^-3, 2 = nm^-3, 3 = Rel. to Uniform Density bool g_bSDFUniform; bool g_bDDisp; bool g_bDLDF; bool g_bDLDisp; bool g_bDACF; bool g_bAggregation; //CAggregation *g_pAggregation; bool g_bKeepUnfoldedCoords; CxObArray g_oaElements; bool g_bTDO; bool g_bTDOEqui; int g_iTDOCount; int g_iTDOStride; int g_iTDOStart; CxIntArray g_laTDOSteps; double g_fTDOBleaching; bool g_bMultiInterval; int g_iMultiIntervalBegin; int g_iMultiIntervalStride; int g_iMultiIntervalLength; CxIntArray g_laMultiIntervalStart; CxIntArray g_laMultiIntervalEnd; bool g_bDoubleBox; int g_iDoubleBoxX; int g_iDoubleBoxY; int g_iDoubleBoxZ; int g_iDoubleBoxFactor; int g_iTrajSteps; bool g_bRDyn; bool g_bBondACF; int g_iBondACFDepth; bool g_bBondACFDebug; bool g_bBondACFNormalize; bool g_bBondACFSymmetrize; bool g_bBondACFWindow; bool g_bACFFFT = true; bool g_bMSDCacheMode; bool g_bRDynCacheMode; bool g_bVACFCacheMode; char *g_sInputFile; FILE *g_fInputFile; char *g_sControlFile; bool g_bControlRun; CDatabase *g_pControlDB; int g_iControlRT; bool g_bReactive; CReactiveEngine *g_pReactEngine; bool g_bSaveCondSnapshot; bool g_bSaveCondWholeBox; FILE *g_fSaveCondFile; int g_iSaveCondCount; bool g_bCond; //CConditionGroup *g_pCondition; bool g_bCombined; unsigned long g_iFastForwardPos; int g_iNbhMode; bool g_bWriteAtomwise; time_t g_iStartTime, g_iEndTime; int g_iTrajFormat; bool g_bScanVelocities; int g_iScanNbhStart; int g_iScanNbhSteps; int g_iScanNbhStride; int g_iScanVelStart; int g_iScanVelSteps; int g_iScanVelStride; bool g_bSilentProgress; char *g_sHomeDir; char *g_sSettingsFile; char *g_sHostName; char *g_sWorkingDir; bool g_bSMode; bool g_bCreateRevSDF; bool g_bNoColor; int g_iColorIntensity; bool g_bNPT; //char g_sNPTFile[256]; CxString g_sNPTFile; FILE *g_fNPTFile; bool g_bNbExchange; bool g_bVerbose; bool *g_pUniteTemp; bool g_bCenterZero; bool g_bSaveJustCenter; int g_iSaveJustMol; int g_iSaveJustSM; int g_iSaveJustAtomType; int g_iSaveJustRealAtomType; int g_iSaveJustAtom; bool g_bTimeDiff; bool g_bDeriv; int g_iDerivLast; int g_iDerivCurr; int g_iDerivNext; int g_iCloseAtomCounter; bool g_bRemoveCOM; bool g_bVoro; int g_iVoroMemory; CVoroWrapper *g_pVoroWrapper; bool g_bSaxonize; bool g_bUnknownElements; bool g_bNeedMoleculeWrap; bool g_bAdvanced1; bool g_bAdvanced2; bool g_bVoid; bool g_bDipoleDefined; bool g_bDipolGrimme; bool g_bVoidSDF; bool g_bSaveCoordsUnchanged; bool g_bDens; bool g_bSaveTrajNoRot; bool g_bCheckWrite; bool g_bRaman; bool g_bIRSpec; bool g_bPowerSpec; bool g_bKeepOriginalCoords; bool g_bShowConf; bool g_bWriteConf; char *g_sConfFile; bool g_bPDF; int g_iStrideDetect; double g_fMinPeriodic; bool g_bRegionAnalysis; CxIntArray g_iaSMRegion; bool g_bDumpDipoleVector; bool g_bDumpDipoleAbs; bool g_bDumpDipoleXYZ; CxObArray g_oaDumpDipoleVector; // Contains CxIntAtrrays FILE *g_fDumpDipole; FILE *g_fDumpDipoleXYZ; FILE *g_fDumpDipolePURE; int g_iDumpDipoleSMCount; int g_iDumpDipoleXYZAtoms; double g_fDumpDipoleScale; bool g_bPlDF; bool g_bLiDF; bool g_bStreamInput; bool g_bGlobalIR; CReorDyn *g_pGlobalIR; bool g_bLMFitSilent; int g_iFitDegree; double *g_pExpSpecExpo; bool g_bLMFitSmooth; int g_iLMMaxIter; bool g_bUnwrapWannier; bool g_bDipoleRefFixed; double *g_fLSpecEvolveBuf; bool g_bXYZ4thCol; bool g_bXYZComment6Numbers; bool g_bXYZComment3Numbers; bool g_bReadChargesFrom4thXYZ; bool g_bProcSplit; int g_iProcSplitLength; bool g_bPDFFixAtom; int g_iPDFFixAtom; int g_iRemoveCOMFixAtom; bool g_bPairMSD; bool g_bSFac; //CStructureFactor *g_pSFac; bool g_bEnvWriteDetailedInfo; bool g_bEnvSortNb; bool g_bEnvDisableSortNb; bool g_bShowCredits; bool g_bWriteInputOrder; bool g_bPlProj; bool g_bNormalCoordinate = false; bool g_bChiral = false; bool g_bSortWannier = false; bool g_bVCD = false; bool g_bEckartTransform = false; bool g_bPower = false; bool g_bIR = false; CTetraPak *g_pTetraPak; bool g_bTegri; bool g_bDomA; CDomainEngine *g_pDomainEngine; CxDoubleArray g_faVoronoiRadii; bool g_bBoxNonOrtho; bool g_bFoundNonOrtho; double g_fBoxAngleA; double g_fBoxAngleB; double g_fBoxAngleC; CxDMatrix3 g_mBoxToOrtho; CxDMatrix3 g_mBoxFromOrtho; double g_fBoxMinDiamA; double g_fBoxMinDiamB; double g_fBoxMinDiamC; double g_fBoxMinDiam; double g_fBoxVolume; bool g_bWriteOrtho; double g_fWriteOrthoFac; bool g_bSDFVoro; bool g_bSDFMap; CxObArray g_oaSDFMaps; int g_iSDFMapSmoothGrade; bool g_bCHDF = false; int g_iCubeRes[3] = { -1, -1, -1 }; double g_fCubeXStep = 0.0; double g_fCubeYStep = 0.0; double g_fCubeZStep = 0.0; double g_fCubeXVector[3] = { 0.0, 0.0, 0.0 }; double g_fCubeYVector[3] = { 0.0, 0.0, 0.0 }; double g_fCubeZVector[3] = { 0.0, 0.0, 0.0 }; CxDMatrix3 g_mCubeCell = CxDMatrix3(0.0); int g_iCubeXStride = 1; int g_iCubeYStride = 1; int g_iCubeZStride = 1; int g_iCubeXMismatch = 0; int g_iCubeYMismatch = 0; int g_iCubeZMismatch = 0; bool g_bCubeTimeDev = false; FILE *g_fPDESolverInfoFile = NULL; double g_fBackgroundDensity = 1.0e-6; double g_fPDEConvThresh = 0.05; int g_iPDEMaxIter = 30; bool g_bVoroSilent; int g_iVoroPrintLevel; bool g_bVoronoiMoments; bool g_bVoroIntEquitable; bool g_bVoroIntegrateCharge = false; bool g_bVoroIntegrateDipoleMoment = false; bool g_bVoroIntegrateQuadrupoleMoment = false; bool g_bQuadrupoleKeepTrace = false; bool g_bVoroIntegrateTotalCurrent = false; bool g_bVoroIntegrateMagneticMoment = false; //char g_sAmberParmFile[1024]; CxString g_sAmberParmFile; bool g_bCubeStream = false; CxMemFile *g_fCubeMemFile = NULL; int g_iCubeMemFileLines = 0; int g_iCubeMemFileSteps = 0; bool g_bDipoleRestart = false; bool g_bLoadDipoleRestart = false; FILE *g_fDipoleRestartFile = NULL; bool g_bMagneticDipoleRestart = false; bool g_bLoadMagneticDipoleRestart = false; FILE *g_fMagneticDipoleRestartFile = NULL; bool g_bSetUpPolarizabilityCalc = false; bool g_bPolarizabilityDefined = false; int g_iPolarizabilityMode = 0; int g_iPolarizabilityConf[3] = { 0, 0, 0 }; FILE *g_fPolarizabilityFile[6] = { NULL, NULL, NULL, NULL, NULL, NULL }; double g_fPolarizabilityFieldStrength = 0.0; bool g_bLAMMPSCharge; bool g_bReadLAMMPSCharges; bool g_bLAMMPSForce; bool g_bHBond = false; bool g_bIonPair = false; int g_iRefMolNum; bool g_bProcAlternativeLabels; CxObArray g_oaProcAlternativeLabels; bool g_bProcDumpAwkScript; bool g_bProcWriteComments; bool g_bProcCellComment; bool g_bProcCellCommentAngles; bool g_bInterWarning; CBQBFile *g_pBQBFile = NULL; //CBQBEngine *g_pBQBEngine = NULL; bool g_bFlipCellVectorX; bool g_bFlipCellVectorY; bool g_bFlipCellVectorZ; bool g_bOrder; COrderEngine *g_pOrderEngine; bool g_bROA; CROAEngine *g_pROAEngine; FILE *g_fMolIntegralFile; bool g_bVolumetricData; bool g_bElMagProperties; bool g_bReadVelocity; bool g_bVACFNew; double g_fVelocityConversion; bool g_bStrideParsed; bool g_bFixedPlProj; CFixedPlProj *g_pFixedPlProj; bool g_bProcAddMesh; bool g_bProcAddMeshZ; double g_fProcAddMeshZPos; bool g_bProcAddMeshY; double g_fProcAddMeshYPos; bool g_bProcAddMeshX; double g_fProcAddMeshXPos; int g_iProcAddMeshGrid; CxString g_sProcAddMeshLabel; bool g_bProcAddMeshJitter; double g_fProcAddMeshJitter; CBQBInterface *g_pBQBInterface; bool g_bUseBQB; travis-src-190101/src/globalvar.h0100777000000000000000000003775213412725661013600 0ustar00/***************************************************************************** TRAVIS - Trajectory Analyzer and Visualizer http://www.travis-analyzer.de/ Copyright (c) 2009-2019 Martin Brehm 2012-2019 Martin Thomas 2016-2019 Sascha Gehrke This file was written by Martin Brehm and Martin Thomas. --------------------------------------------------------------------------- This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . *****************************************************************************/ #ifndef GLOBALVAR_H #define GLOBALVAR_H // This must always be the first include directive #include "config.h" #include "asciiart.h" #include "database.h" #include "timestep.h" #include "domain.h" #include "vorowrapper.h" #include "tetrapak.h" #include "roa.h" #include "bqb.h" #include "fixplproj.h" #include "order.h" class CxString; class CReactiveEngine; extern CxObArray g_oaAtoms; // Die Atomsorten der Simulation extern CxObArray g_oaMolecules; // Die Molekuelsorten der Simulation extern CxObArray g_oaSingleMolecules; extern CxObArray g_oaObserv; extern CxObArray g_oaVirtualAtoms; extern CTimeStep g_TimeStep; extern char g_iFixMol; // Welches Molekuel fixieren wir? extern int g_iFixAtomType[3]; // Welches Element fixieren wir? (3 mal wegen den 3 Fixpunkten) extern int g_iFixRealAtomType[3]; // Wie Eben, nur Index auf g_pAtoms extern int g_iFixAtom[3]; // Welche Atome in in dem Molekuel fixieren? extern int g_iCurrentTimeStep, g_iLastTimeStep, g_iNextTimeStep; extern unsigned long g_iSteps; // Zaehler fuer die schon verarbeiteten Zeitschritte extern unsigned char g_iBinning; extern bool g_bFold; extern bool g_bWarnUnsteady; extern double g_fUnsteadyLimit; extern FILE *g_fSaveJustTraj; extern unsigned char g_iVirtAtomType; extern double g_fVelLimit, g_fForceLimit; extern double g_fMSVDFLevel, g_fMSFDFLevel; extern bool g_bCalcVel, g_bCalcForces; extern bool g_bManSVDFLevel, g_bManSFDFLevel; extern bool g_bManSMeanVDFLevel, g_bManSMeanFDFLevel; extern bool g_bManSMaxVDFLevel, g_bManSMaxFDFLevel; extern double g_fSVDFLevel[16]; extern double g_fSMeanVDFLevel[16]; extern double g_fSMaxVDFLevel[16]; extern double g_fSFDFLevel[16]; extern double g_fSMeanFDFLevel[16]; extern double g_fSMaxFDFLevel[16]; //extern char g_sRefEnv[256]; extern CxString g_sRefEnv; extern bool g_bUseVelocities; extern bool g_bUseForces; extern double g_fBoxX, g_fBoxY, g_fBoxZ; extern CxDVec3Array g_pRefMol; // Die Koordinaten des Referenzmolekueles (zum akkumulieren) extern bool g_bAvg; // Gemitteltes Referenzmolekuel ausgeben extern bool g_bMiddleAvg; // Soll das Referenzmolekuel wirklich gemittelt werden (true), oder soll einfach das erstbeste Molekuel genommen werden (false)? extern int g_iGesAtomCount; // Gesamtzahl der Atome pro Zeitschritt - also in der Simulation extern int g_iGesVirtAtomCount; extern int g_iMaxStep; // Bis zu welchem Zeitschritt geht die Analyse? -1 fuer alle extern unsigned char g_iSwapAtoms; // Sollen Atome, die sich frei drehen oder sich vertauschen, zurueckgetauscht werden? extern unsigned char g_iNormSDF; // 0 - jede SDF einzeln auf 100, 1 - gar nicht normieren extern unsigned char g_iSVDFLevel, g_iSFDFLevel; extern bool g_bMegaMat; extern bool g_bMatOnlyBind; extern bool g_bVFHisto; extern unsigned short g_iHistogramRes; extern FILE *g_fRefTrajec, *g_fRefEnv, *g_fVRDF[32]; extern CTimeStep *g_pTempTimestep; extern bool g_bFoldAtomwise; extern double g_fBondFactor; extern bool g_bSaveJustTraj; extern bool g_bSaveVirtAtoms; extern FILE *g_fVFCorr[64]; extern unsigned short g_iVFCorrCount; extern bool g_bSaveRefWithEnv; extern bool g_bRefEnvCenter; extern bool g_bPeriodicX, g_bPeriodicY, g_bPeriodicZ; extern bool g_bPeriodic; extern int g_iStride; extern CAsciiArt g_oAsciiArt; extern CTimeStep *g_pT2Timestep; //extern CNbSearch *g_pNbAll; extern int g_iClusterPos; extern CxByteArray g_baAtomIndex; extern bool g_bScanMolecules; extern CACF *g_pGlobalVACF; extern CACF *g_pGlobalDipACF; extern int g_iRefSystemDim; //extern bool g_bSaveTrajVirt; extern FILE *g_fPos, *g_fVel, *g_fForce; extern double g_fTimestepLength; extern CFFT *g_pFFT; extern long g_iHighestStepNumber; extern int g_iDotCounter; extern bool g_bStepSkipped; extern bool g_bAbortAnalysis; extern CxIntArray g_laBondBlackList; extern int g_iBondBlackListUsed; extern int g_iFirstStepSkipped; extern bool g_bGlobalPsycho; extern int g_iWannierAtomType; extern double g_fWannierCharge; extern bool g_bCombinedDF; extern bool g_bSDF, g_bRDF; extern bool g_bVDF, g_bFDF, g_bADF; extern bool g_bDipole; extern CxObArray g_oaAnalysisGroups; extern CxObArray g_oaAnalyses; extern int g_iStepHistory; extern CxObArray g_oaTimeSteps; extern double g_fMaxVel, g_fMaxForce; extern double g_fLMaxVel, g_fLMaxForce; extern double g_fLMidVel, g_fLMidForce; extern bool g_bAsciiArt; //extern char g_sInputVel[256]; //extern char g_sInputForce[256]; //extern char g_sInputCtrl[256]; extern CxString g_sInputVel; extern CxString g_sInputForce; extern CxString g_sInputCtrl; extern CDatabase *g_pDatabase; extern CxIntArray g_laAtomSMIndex; // Enthaelt fuer jedes Atom, in welchem SingleMolecule es sich befindet, oder -1 wenn gar nicht extern CxIntArray g_laAtomSMLocalIndex; extern CxWordArray g_waAtomElement; extern CxWordArray g_waAtomMolNumber; extern CxWordArray g_waAtomMolIndex; extern CxWordArray g_waAtomRealElement; extern CxDoubleArray g_faAtomCode; extern std::vector g_liAtomCode; extern CxDoubleArray g_faVdWRadius; extern CxWordArray g_waAtomMolUID; extern CxObArray g_oaMolAtoms; extern CxByteArray g_baAtomPassedCondition; extern int g_iCDFChannels; extern bool g_bWannier; extern int g_iScanMolStep; extern char *g_sInputTraj; extern bool g_bCDF; extern int *g_iObsChannel; // 1 - RDF, 2 - ADF, 3 - DDF, 4 - DipDF, 5 - VDF, 6 - FDF extern bool g_bDDF; extern bool g_bRevSDF; extern bool g_bMSD; extern bool g_bCutCluster; extern bool g_bSaveRefEnv; extern unsigned char g_iSaveRefMol; extern bool g_bRefEnvFix; extern int g_iClusterSteps, g_iClusterCount; extern CxIntArray g_iaClusterSteps, g_iaClusterMol; extern bool g_bNbAnalysis; extern bool g_bVHDF; //extern CxObArray g_oaNbSearches; extern CNbSet *g_pNbSet; extern bool g_bVACF; extern bool g_bVFDF; extern bool g_bGlobalVACF; extern bool g_bGlobalDipACF; extern int g_iSDFSmoothGrade; extern bool g_bACFWindowFunction; extern bool g_bSaveVelForce; extern double g_fVelPercentage, g_fForcePercentage; //extern bool g_bRefNoVirt; extern unsigned long g_iSaveGesAtoms; extern bool g_bUnwrap; extern CxObArray g_oaSaveMolecules; extern CxDVec3Array g_vaUnwrapArray; extern int g_iBeginStep; extern bool g_bSkipDoubleSteps; extern int g_iNumberPos; // Die wievielte Nummer in der XYZ-Kommentarzeile ist die Schrittzahl? extern FILE *g_fInput; extern bool g_bDipACF; extern bool g_bACF; extern bool g_bDipDF; extern bool g_bInputRedirected; //extern int g_iSDFScale; // 0 = ppm, 1 = pm^-3, 2 = nm^-3, 3 = Rel. to Uniform Density extern bool g_bSDFUniform; extern bool g_bDDisp; extern bool g_bDLDF; extern bool g_bDLDisp; extern bool g_bDACF; extern bool g_bAggregation; //extern CAggregation *g_pAggregation; extern bool g_bKeepUnfoldedCoords; extern CxObArray g_oaElements; extern bool g_bTDO; extern bool g_bTDOEqui; extern int g_iTDOCount; extern int g_iTDOStride; extern int g_iTDOStart; extern CxIntArray g_laTDOSteps; extern double g_fTDOBleaching; extern bool g_bMultiInterval; extern int g_iMultiIntervalBegin; extern int g_iMultiIntervalStride; extern int g_iMultiIntervalLength; extern CxIntArray g_laMultiIntervalStart; extern CxIntArray g_laMultiIntervalEnd; extern bool g_bDoubleBox; extern int g_iDoubleBoxX; extern int g_iDoubleBoxY; extern int g_iDoubleBoxZ; extern int g_iDoubleBoxFactor; extern int g_iTrajSteps; extern bool g_bRDyn; extern bool g_bBondACF; extern int g_iBondACFDepth; extern bool g_bBondACFDebug; extern bool g_bBondACFNormalize; extern bool g_bBondACFSymmetrize; extern bool g_bBondACFWindow; extern bool g_bACFFFT; extern bool g_bMSDCacheMode; extern bool g_bRDynCacheMode; extern bool g_bVACFCacheMode; extern char *g_sInputFile; extern FILE *g_fInputFile; extern char *g_sControlFile; extern bool g_bControlRun; extern CDatabase *g_pControlDB; extern int g_iControlRT; extern bool g_bReactive; extern CReactiveEngine *g_pReactEngine; extern bool g_bSaveCondSnapshot; extern bool g_bSaveCondWholeBox; extern FILE *g_fSaveCondFile; extern int g_iSaveCondCount; extern bool g_bCond; //extern CConditionGroup *g_pCondition; extern bool g_bCombined; extern unsigned long g_iFastForwardPos; extern int g_iNbhMode; extern bool g_bWriteAtomwise; extern time_t g_iStartTime, g_iEndTime; extern int g_iTrajFormat; extern bool g_bScanVelocities; extern int g_iScanNbhStart; extern int g_iScanNbhSteps; extern int g_iScanNbhStride; extern int g_iScanVelStart; extern int g_iScanVelSteps; extern int g_iScanVelStride; extern bool g_bSilentProgress; extern char *g_sHomeDir; extern char *g_sSettingsFile; extern char *g_sHostName; extern char *g_sWorkingDir; extern bool g_bSMode; extern bool g_bCreateRevSDF; extern bool g_bNoColor; extern int g_iColorIntensity; extern bool g_bNPT; //extern char g_sNPTFile[256]; extern CxString g_sNPTFile; extern FILE *g_fNPTFile; extern bool g_bNbExchange; extern bool g_bVerbose; extern bool *g_pUniteTemp; extern bool g_bCenterZero; extern bool g_bSaveJustCenter; extern int g_iSaveJustMol; extern int g_iSaveJustSM; extern int g_iSaveJustAtomType; extern int g_iSaveJustRealAtomType; extern int g_iSaveJustAtom; extern bool g_bTimeDiff; extern bool g_bDeriv; extern int g_iDerivLast; extern int g_iDerivCurr; extern int g_iDerivNext; extern int g_iCloseAtomCounter; extern bool g_bVoro; extern CVoroWrapper *g_pVoroWrapper; extern bool g_bRemoveCOM; extern int g_iVoroMemory; extern bool g_bSaxonize; extern bool g_bUnknownElements; extern bool g_bNeedMoleculeWrap; extern bool g_bAdvanced1; extern bool g_bAdvanced2; extern bool g_bVoid; extern bool g_bDipoleDefined; extern bool g_bDipolGrimme; extern bool g_bSaveCoordsUnchanged; extern bool g_bDens; extern bool g_bSaveTrajNoRot; extern bool g_bCheckWrite; extern bool g_bRaman; extern bool g_bIRSpec; extern bool g_bPowerSpec; extern bool g_bKeepOriginalCoords; extern bool g_bShowConf; extern bool g_bWriteConf; extern char *g_sConfFile; extern bool g_bPDF; extern int g_iStrideDetect; extern double g_fMinPeriodic; extern bool g_bRegionAnalysis; extern CxIntArray g_iaSMRegion; extern bool g_bDumpDipoleVector; extern bool g_bDumpDipoleAbs; extern bool g_bDumpDipoleXYZ; extern CxObArray g_oaDumpDipoleVector; // Contains CxIntAtrrays extern FILE *g_fDumpDipole; extern FILE *g_fDumpDipoleXYZ; extern FILE *g_fDumpDipolePURE; extern int g_iDumpDipoleSMCount; extern int g_iDumpDipoleXYZAtoms; extern double g_fDumpDipoleScale; extern bool g_bPlDF; extern bool g_bLiDF; extern bool g_bStreamInput; extern bool g_bGlobalIR; extern CReorDyn *g_pGlobalIR; extern bool g_bLMFitSilent; extern int g_iFitDegree; extern double *g_pExpSpecExpo; extern bool g_bLMFitSmooth; typedef struct { const double *x; const double *y; } lmcurve_data_struct; extern int g_iLMMaxIter; extern bool g_bUnwrapWannier; extern bool g_bDipoleRefFixed; extern double *g_fLSpecEvolveBuf; extern bool g_bXYZ4thCol; extern bool g_bXYZComment6Numbers; extern bool g_bXYZComment3Numbers; extern bool g_bReadChargesFrom4thXYZ; extern bool g_bProcSplit; extern int g_iProcSplitLength; extern bool g_bPDFFixAtom; extern int g_iPDFFixAtom; extern int g_iRemoveCOMFixAtom; extern bool g_bPairMSD; extern bool g_bSFac; //extern CStructureFactor *g_pSFac; extern bool g_bEnvWriteDetailedInfo; extern bool g_bEnvSortNb; extern bool g_bEnvDisableSortNb; extern bool g_bShowCredits; extern bool g_bWriteInputOrder; extern bool g_bPlProj; extern bool g_bNormalCoordinate; extern bool g_bChiral; extern bool g_bSortWannier; extern bool g_bVCD; extern bool g_bEckartTransform; extern bool g_bPower; extern bool g_bIR; extern CTetraPak *g_pTetraPak; extern bool g_bTegri; extern CxDoubleArray g_faVoronoiRadii; extern bool g_bBoxNonOrtho; extern bool g_bFoundNonOrtho; extern double g_fBoxAngleA; extern double g_fBoxAngleB; extern double g_fBoxAngleC; extern CxDMatrix3 g_mBoxToOrtho; extern CxDMatrix3 g_mBoxFromOrtho; extern double g_fBoxMinDiamA; extern double g_fBoxMinDiamB; extern double g_fBoxMinDiamC; extern double g_fBoxMinDiam; extern double g_fBoxVolume; extern bool g_bWriteOrtho; extern double g_fWriteOrthoFac; extern bool g_bSDFVoro; extern int g_iVoroPrintLevel; extern bool g_bSDFMap; extern CxObArray g_oaSDFMaps; extern int g_iSDFMapSmoothGrade; extern bool g_bCHDF; extern int g_iCubeRes[3]; extern double g_fCubeXStep; extern double g_fCubeYStep; extern double g_fCubeZStep; extern double g_fCubeXVector[3]; extern double g_fCubeYVector[3]; extern double g_fCubeZVector[3]; extern CxDMatrix3 g_mCubeCell; extern int g_iCubeXStride; extern int g_iCubeYStride; extern int g_iCubeZStride; extern int g_iCubeXMismatch; extern int g_iCubeYMismatch; extern int g_iCubeZMismatch; extern bool g_bCubeTimeDev; extern FILE *g_fPDESolverInfoFile; extern double g_fBackgroundDensity; extern double g_fPDEConvThresh; extern int g_iPDEMaxIter; extern bool g_bVoronoiMoments; extern bool g_bVoroIntEquitable; extern bool g_bVoroIntegrateCharge; extern bool g_bVoroIntegrateDipoleMoment; extern bool g_bVoroIntegrateQuadrupoleMoment; extern bool g_bQuadrupoleKeepTrace; extern bool g_bVoroIntegrateTotalCurrent; extern bool g_bVoroIntegrateMagneticMoment; extern bool g_bVoroSilent; extern bool g_bDomA; extern CDomainEngine *g_pDomainEngine; extern CxString g_sAmberParmFile; extern bool g_bCubeStream; extern CxMemFile *g_fCubeMemFile; extern int g_iCubeMemFileLines; extern int g_iCubeMemFileSteps; extern bool g_bDipoleRestart; extern bool g_bLoadDipoleRestart; extern FILE *g_fDipoleRestartFile; extern bool g_bMagneticDipoleRestart; extern bool g_bLoadMagneticDipoleRestart; extern FILE *g_fMagneticDipoleRestartFile; extern bool g_bSetUpPolarizabilityCalc; extern bool g_bPolarizabilityDefined; extern int g_iPolarizabilityMode; extern int g_iPolarizabilityConf[3]; extern FILE *g_fPolarizabilityFile[6]; extern double g_fPolarizabilityFieldStrength; extern bool g_bLAMMPSCharge; extern bool g_bReadLAMMPSCharges; extern bool g_bLAMMPSForce; extern bool g_bHBond; extern bool g_bIonPair; extern int g_iRefMolNum; extern bool g_bProcAlternativeLabels; extern CxObArray g_oaProcAlternativeLabels; extern bool g_bProcDumpAwkScript; extern bool g_bProcWriteComments; extern bool g_bProcCellComment; extern bool g_bProcCellCommentAngles; extern bool g_bInterWarning; extern CBQBFile *g_pBQBFile; //extern CBQBEngine *g_pBQBEngine; extern bool g_bFlipCellVectorX; extern bool g_bFlipCellVectorY; extern bool g_bFlipCellVectorZ; extern bool g_bVACFNew; extern bool g_bOrder; extern COrderEngine *g_pOrderEngine; extern bool g_bROA; extern CROAEngine *g_pROAEngine; extern FILE *g_fMolIntegralFile; extern bool g_bVolumetricData; extern bool g_bElMagProperties; extern bool g_bReadVelocity; extern double g_fVelocityConversion; extern bool g_bStrideParsed; extern bool g_bFixedPlProj; extern CFixedPlProj *g_pFixedPlProj; extern bool g_bProcAddMesh; extern bool g_bProcAddMeshZ; extern double g_fProcAddMeshZPos; extern bool g_bProcAddMeshY; extern double g_fProcAddMeshYPos; extern bool g_bProcAddMeshX; extern double g_fProcAddMeshXPos; extern int g_iProcAddMeshGrid; extern CxString g_sProcAddMeshLabel; extern bool g_bProcAddMeshJitter; extern double g_fProcAddMeshJitter; extern CBQBInterface *g_pBQBInterface; extern bool g_bUseBQB; #endif travis-src-190101/src/grace.cpp0100777000000000000000000011240413412725634013227 0ustar00/***************************************************************************** TRAVIS - Trajectory Analyzer and Visualizer http://www.travis-analyzer.de/ Copyright (c) 2009-2019 Martin Brehm 2012-2019 Martin Thomas 2016-2019 Sascha Gehrke This file was written by Martin Brehm. --------------------------------------------------------------------------- This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . *****************************************************************************/ // This must always be the first include directive #include "config.h" #include "grace.h" #include #include #include "tools.h" #include "maintools.h" const char *GetRevisionInfo_grace(unsigned int len) { static char buf[256]; GET_REVISION_INFO( buf, len ); return buf; } const char *GetSourceVersion_grace() { static char buf[256]; GET_SOURCE_VERSION( buf ); return buf; } CGrace::CGrace() { m_iBGColor = 0xFFFFFF; AddGraph(); AddColor(255,255,255,"white"); AddColor( 0, 0, 0,"black"); AddColor(255, 0, 0,"red"); AddColor( 0,255, 0,"green"); AddColor( 0, 0,255,"blue"); AddColor(255,255, 0,"yellow"); AddColor(188,143,143,"brown"); AddColor(220,220,220,"grey"); AddColor(148, 0,211,"violet"); AddColor( 0,255,255,"cyan"); AddColor(255, 0,255,"magenta"); AddColor(255,165, 0,"orange"); AddColor(114, 33,188,"indigo"); AddColor(103, 7, 72,"maroon"); AddColor( 64,224,208,"turquoise"); AddColor( 0,139, 0,"green4"); m_oaGraceGraphs.SetName("CGrace::m_oaGraceGraphs"); m_oaGraceColors.SetName("CGrace::m_oaGraceColors"); } CGrace::~CGrace() { } CGraceGraph::CGraceGraph() { try { m_sLabelX = new char[1]; } catch(...) { m_sLabelX = NULL; } if (m_sLabelX == NULL) NewException((double)sizeof(char),__FILE__,__LINE__,__PRETTY_FUNCTION__); *m_sLabelX = 0; try { m_sLabelY = new char[1]; } catch(...) { m_sLabelY = NULL; } if (m_sLabelY == NULL) NewException((double)sizeof(char),__FILE__,__LINE__,__PRETTY_FUNCTION__); *m_sLabelY = 0; try { m_sTitle = new char[1]; } catch(...) { m_sTitle = NULL; } if (m_sTitle == NULL) NewException((double)sizeof(char),__FILE__,__LINE__,__PRETTY_FUNCTION__); *m_sTitle = 0; try { m_sSubTitle = new char[1]; } catch(...) { m_sSubTitle = NULL; } if (m_sSubTitle == NULL) NewException((double)sizeof(char),__FILE__,__LINE__,__PRETTY_FUNCTION__); m_fYAxisBarWidth = 1.0; *m_sSubTitle = 0; m_bShowFrame = true; m_bShowXAxis = true; m_bTicksBothSidesX = false; m_bTicksBothSidesY = false; m_bTickLabelsBothSidesX = false; m_bTickLabelsBothSidesY = false; m_bLegend = false; m_bTickInX = true; m_bTickInY = true; m_bTickLabels = true; m_bInvertXAxis = false; m_bInvertYAxis = false; m_bTicks = true; m_fFrameWidth = 2.0; m_fViewportX1 = 0.15; m_fViewportY1 = 0.15; m_fViewportX2 = 1.15; m_fViewportY2 = 0.85; m_bInvert = false; m_iTickMinorX = 1; m_iTickMinorY = 1; m_oaDatasets.SetName("CGraceGraph::m_oaDatasets"); m_oaCustomLabelsX.SetName("CGraceGraph::m_oaCustomLabelsX"); m_oaCustomLabelsY.SetName("CGraceGraph::m_oaCustomLabelsY"); m_oaLines.SetName("CGraceGraph::m_oaLines"); } CGraceGraph::~CGraceGraph() { } CGraceDataset::CGraceDataset() { try { m_sName = new char[1]; } catch(...) { m_sName = NULL; } if (m_sName == NULL) NewException((double)sizeof(char),__FILE__,__LINE__,__PRETTY_FUNCTION__); *m_sName = 0; m_iLineColorIndex = 0; m_iLineStyle = 0; m_fLineWidth = 2.0; m_iSymbColorIndex = 0; m_iBegin = 0; m_iEnd = 0; m_bFill = false; m_bSymbol = false; m_faValues.SetName("CGraceDataset::m_faValues"); } CGraceDataset::~CGraceDataset() { } CGraceColor::CGraceColor() { try { m_sName = new char[1]; } catch(...) { m_sName = NULL; } if (m_sName == NULL) NewException((double)sizeof(char),__FILE__,__LINE__,__PRETTY_FUNCTION__); *m_sName = 0; } CGraceColor::~CGraceColor() { } void CGrace::MakeTicks() { // double d1, d2; CGraceGraph *g; g = CurrentGraph(); /* d1 = dec(m_fMinValX,2); d2 = dec(m_fMaxValX,2); m_fMinRangeX = minbound(m_fMinValX,d1); m_fMaxRangeX = maxbound(m_fMaxValX,d2);*/ g->m_fTickMajorX = majorticks(g->m_fMinRangeX,g->m_fMaxRangeX); g->m_iTickPrecX = (int)MAX(0,1-int(ceil(log10(g->m_fTickMajorX)))); /* d1 = dec(m_fMinValY,2); d2 = dec(m_fMaxValY,2); m_fMinRangeY = minbound(m_fMinValY,d1); m_fMaxRangeY = maxbound(m_fMaxValY,d2);*/ g->m_fTickMajorY = majorticks(g->m_fMinRangeY,g->m_fMaxRangeY); g->m_iTickPrecY = (int)MAX(0,1-int(ceil(log10(g->m_fTickMajorY)))); } void CGrace::WriteAgr(const char *s, bool silent) { int z, z2/*, i*/; FILE *a; // CGraceGraph *g; if ((!silent) && (CurrentGraph()->m_oaDatasets.GetSize() > 2)) mprintf(" Writing file...\n"); a = OpenFileWrite(s,true); mfprintf(a,"# Grace project file\n"); mfprintf(a,"# Written by TRAVIS, the Trajectory Analyser and Visualizer\n"); mfprintf(a,"# See http://www.travis-analyzer.de\n"); mfprintf(a,"@version 50119\n"); mfprintf(a,"@page size 792, 612\n"); mfprintf(a,"@page scroll 5%c\n",'%'); mfprintf(a,"@page inout 5%c\n",'%'); mfprintf(a,"@link page off\n"); mfprintf(a,"@map font 0 to \"Times-Roman\", \"Times-Roman\"\n"); mfprintf(a,"@map font 1 to \"Times-Italic\", \"Times-Italic\"\n"); mfprintf(a,"@map font 2 to \"Times-Bold\", \"Times-Bold\"\n"); mfprintf(a,"@map font 3 to \"Times-BoldItalic\", \"Times-BoldItalic\"\n"); mfprintf(a,"@map font 4 to \"Helvetica\", \"Helvetica\"\n"); mfprintf(a,"@map font 5 to \"Helvetica-Oblique\", \"Helvetica-Oblique\"\n"); mfprintf(a,"@map font 6 to \"Helvetica-Bold\", \"Helvetica-Bold\"\n"); mfprintf(a,"@map font 7 to \"Helvetica-BoldOblique\", \"Helvetica-BoldOblique\"\n"); mfprintf(a,"@map font 8 to \"Courier\", \"Courier\"\n"); mfprintf(a,"@map font 9 to \"Courier-Oblique\", \"Courier-Oblique\"\n"); mfprintf(a,"@map font 10 to \"Courier-Bold\", \"Courier-Bold\"\n"); mfprintf(a,"@map font 11 to \"Courier-BoldOblique\", \"Courier-BoldOblique\"\n"); mfprintf(a,"@map font 12 to \"Symbol\", \"Symbol\"\n"); mfprintf(a,"@map font 13 to \"ZapfDingbats\", \"ZapfDingbats\"\n"); for (z=0;zm_iColorRed,((CGraceColor*)m_oaGraceColors[z])->m_iColorGreen,((CGraceColor*)m_oaGraceColors[z])->m_iColorBlue,((CGraceColor*)m_oaGraceColors[z])->m_sName); mfprintf(a,"@map color %d to (%lu, %lu, %lu), \"color_bg\"\n",m_oaGraceColors.GetSize(),m_iBGColor % 256,(m_iBGColor >> 8) % 256,(m_iBGColor >> 16) % 256); /* mfprintf(a,"@map color 1 to (0, 0, 0), \"black\"\n"); mfprintf(a,"@map color 2 to (255, 0, 0), \"red\"\n"); mfprintf(a,"@map color 3 to (0, 255, 0), \"green\"\n"); mfprintf(a,"@map color 4 to (0, 0, 255), \"blue\"\n"); mfprintf(a,"@map color 5 to (255, 255, 0), \"yellow\"\n"); mfprintf(a,"@map color 6 to (188, 143, 143), \"brown\"\n"); mfprintf(a,"@map color 7 to (220, 220, 220), \"grey\"\n"); mfprintf(a,"@map color 8 to (148, 0, 211), \"violet\"\n"); mfprintf(a,"@map color 9 to (0, 255, 255), \"cyan\"\n"); mfprintf(a,"@map color 10 to (255, 0, 255), \"magenta\"\n"); mfprintf(a,"@map color 11 to (255, 165, 0), \"orange\"\n"); mfprintf(a,"@map color 12 to (114, 33, 188), \"indigo\"\n"); mfprintf(a,"@map color 13 to (103, 7, 72), \"maroon\"\n"); mfprintf(a,"@map color 14 to (64, 224, 208), \"turquoise\"\n"); mfprintf(a,"@map color 15 to (0, 139, 0), \"green4\"\n"); i = 16; for (z=0;zm_iColorIndex = i; for (z2=0;z2m_oaDatasets.GetSize();z2++) { mfprintf(a,"@map color %d to (%lu, %lu, %lu), \"color_line%d_%d\"\n",z2*2+g->m_iColorIndex,((CGraceDataset*)g->m_oaDatasets[z2])->m_iLineColor % 256,(((CGraceDataset*)g->m_oaDatasets[z2])->m_iLineColor >> 8) % 256,(((CGraceDataset*)g->m_oaDatasets[z2])->m_iLineColor >> 16) % 256,z+1,z2+1); mfprintf(a,"@map color %d to (%lu, %lu, %lu), \"color_symb%d_%d\"\n",z2*2+g->m_iColorIndex+1,((CGraceDataset*)g->m_oaDatasets[z2])->m_iSymbColor % 256,(((CGraceDataset*)g->m_oaDatasets[z2])->m_iSymbColor >> 8) % 256,(((CGraceDataset*)g->m_oaDatasets[z2])->m_iSymbColor >> 16) % 256,z+1,z2+1); i+=2; } } mfprintf(a,"@map color %d to (%lu, %lu, %lu), \"color_bg\"\n",i,m_iBGColor % 256,(m_iBGColor >> 8) % 256,(m_iBGColor >> 16) % 256); */ mfprintf(a,"@reference date 0\n"); mfprintf(a,"@date wrap off\n"); mfprintf(a,"@date wrap year 1950\n"); mfprintf(a,"@default linewidth 1.0\n"); mfprintf(a,"@default linestyle 1\n"); mfprintf(a,"@default color 1\n"); mfprintf(a,"@default pattern 1\n"); mfprintf(a,"@default font 0\n"); mfprintf(a,"@default char size 1.000000\n"); mfprintf(a,"@default symbol size 1.000000\n"); mfprintf(a,"@default sformat \"%c.8g\"\n",'%'); mfprintf(a,"@background color %d\n",m_oaGraceColors.GetSize()); mfprintf(a,"@page background fill on\n"); mfprintf(a,"@timestamp off\n"); mfprintf(a,"@timestamp 0.03, 0.03\n"); mfprintf(a,"@timestamp color 1\n"); mfprintf(a,"@timestamp rot 0\n"); mfprintf(a,"@timestamp font 0\n"); mfprintf(a,"@timestamp char size 1.000000\n"); mfprintf(a,"@timestamp def \"xx\"\n"); for (z=0;zm_oaLines.GetSize();z2++) ((CGraceLine*)((CGraceGraph*)m_oaGraceGraphs[z])->m_oaLines[z2])->WriteLine(a,((CGraceGraph*)m_oaGraceGraphs[z])->m_iNumber); mfprintf(a,"@r0 off\n"); mfprintf(a,"@link r0 to g0\n"); mfprintf(a,"@r0 type above\n"); mfprintf(a,"@r0 linestyle 1\n"); mfprintf(a,"@r0 linewidth 1.0\n"); mfprintf(a,"@r0 color 1\n"); mfprintf(a,"@r0 line 0, 0, 0, 0\n"); mfprintf(a,"@r1 off\n"); mfprintf(a,"@link r1 to g0\n"); mfprintf(a,"@r1 type above\n"); mfprintf(a,"@r1 linestyle 1\n"); mfprintf(a,"@r1 linewidth 1.0\n"); mfprintf(a,"@r1 color 1\n"); mfprintf(a,"@r1 line 0, 0, 0, 0\n"); mfprintf(a,"@r2 off\n"); mfprintf(a,"@link r2 to g0\n"); mfprintf(a,"@r2 type above\n"); mfprintf(a,"@r2 linestyle 1\n"); mfprintf(a,"@r2 linewidth 1.0\n"); mfprintf(a,"@r2 color 1\n"); mfprintf(a,"@r2 line 0, 0, 0, 0\n"); mfprintf(a,"@r3 off\n"); mfprintf(a,"@link r3 to g0\n"); mfprintf(a,"@r3 type above\n"); mfprintf(a,"@r3 linestyle 1\n"); mfprintf(a,"@r3 linewidth 1.0\n"); mfprintf(a,"@r3 color 1\n"); mfprintf(a,"@r3 line 0, 0, 0, 0\n"); mfprintf(a,"@r4 off\n"); mfprintf(a,"@link r4 to g0\n"); mfprintf(a,"@r4 type above\n"); mfprintf(a,"@r4 linestyle 1\n"); mfprintf(a,"@r4 linewidth 1.0\n"); mfprintf(a,"@r4 color 1\n"); mfprintf(a,"@r4 line 0, 0, 0, 0\n"); for (z=0;zWrite(a); for (z=0;zWriteData(a,silent); fclose(a); } void CGraceGraph::WriteData(FILE *a, bool silent) { int z; if ((!silent) && (m_oaDatasets.GetSize() > 2)) mprintf(WHITE," ["); for (z=0;zm_iNumber); ((CGraceDataset*)m_oaDatasets[z])->WriteSet(a); if ((!silent) && (m_oaDatasets.GetSize() > 2)) if ((z % MAX(1,(m_oaDatasets.GetSize()/40))) == 0) mprintf(WHITE,"#"); } if ((!silent) && (m_oaDatasets.GetSize() > 2)) mprintf(WHITE,"]\n"); } CGraceDataset* CGraceGraph::CurrentDataset() { return (CGraceDataset*)m_oaDatasets[m_oaDatasets.GetSize()-1]; } CGraceDataset* CGraceGraph::Dataset(int i) { if ((i >= m_oaDatasets.GetSize()) || (i < 0)) { eprintf("CGraceGraph::Dataset(): Error: %d/%d.\n",i,m_oaDatasets.GetSize()); abort(); } return (CGraceDataset*)m_oaDatasets[m_oaDatasets.GetSize()-1]; } void CGraceGraph::Write(FILE *a) { int z; mfprintf(a,"@g%d on\n",m_iNumber); mfprintf(a,"@g%d hidden false\n",m_iNumber); mfprintf(a,"@g%d type XY\n",m_iNumber); mfprintf(a,"@g%d stacked false\n",m_iNumber); mfprintf(a,"@g%d bar hgap 0.000000\n",m_iNumber); mfprintf(a,"@g%d fixedpoint off\n",m_iNumber); mfprintf(a,"@g%d fixedpoint type 0\n",m_iNumber); mfprintf(a,"@g%d fixedpoint xy 0.000000, 0.000000\n",m_iNumber); mfprintf(a,"@g%d fixedpoint format general general\n",m_iNumber); mfprintf(a,"@g%d fixedpoint prec 6, 6\n",m_iNumber); mfprintf(a,"@with g%d\n",m_iNumber); mfprintf(a,"@ world %f, %f, %f, %f\n",m_fMinRangeX,m_fMinRangeY,m_fMaxRangeX,m_fMaxRangeY); mfprintf(a,"@ stack world 0, 0, 0, 0\n"); mfprintf(a,"@ znorm 1\n"); mfprintf(a,"@ view %f, %f, %f, %f\n",m_fViewportX1,m_fViewportY1,m_fViewportX2,m_fViewportY2); mfprintf(a,"@ title \"%s\"\n",m_sTitle); mfprintf(a,"@ title font 0\n"); mfprintf(a,"@ title size 1.500000\n"); mfprintf(a,"@ title color 1\n"); mfprintf(a,"@ subtitle \"%s\"\n",m_sSubTitle); mfprintf(a,"@ subtitle font 0\n"); mfprintf(a,"@ subtitle size 1.000000\n"); mfprintf(a,"@ subtitle color 1\n"); mfprintf(a,"@ xaxes scale Normal\n"); mfprintf(a,"@ yaxes scale Normal\n"); if (m_bInvertXAxis) mfprintf(a,"@ xaxes invert on\n"); else mfprintf(a,"@ xaxes invert off\n"); if (m_bInvertYAxis) mfprintf(a,"@ yaxes invert on\n"); else mfprintf(a,"@ yaxes invert off\n"); mfprintf(a,"@ xaxis on\n"); mfprintf(a,"@ xaxis type zero false\n"); mfprintf(a,"@ xaxis offset 0.000000 , 0.000000\n"); mfprintf(a,"@ xaxis bar %s\n",m_bShowXAxis?"on":"off"); mfprintf(a,"@ xaxis bar color 1\n"); mfprintf(a,"@ xaxis bar linestyle 1\n"); mfprintf(a,"@ xaxis bar linewidth 1.0\n"); mfprintf(a,"@ xaxis label \"%s\"\n",m_bShowXAxis?m_sLabelX:""); mfprintf(a,"@ xaxis label layout para\n"); mfprintf(a,"@ xaxis label place auto\n"); mfprintf(a,"@ xaxis label char size 1.000000\n"); mfprintf(a,"@ xaxis label font 4\n"); mfprintf(a,"@ xaxis label color 1\n"); mfprintf(a,"@ xaxis label place normal\n"); if (m_bTicks) mfprintf(a,"@ xaxis tick %s\n",m_bShowXAxis?"on":"off"); else mfprintf(a,"@ xaxis tick off\n"); mfprintf(a,"@ xaxis tick major %f\n",m_fTickMajorX); mfprintf(a,"@ xaxis tick minor ticks %d\n",m_iTickMinorX); mfprintf(a,"@ xaxis tick default 6\n"); mfprintf(a,"@ xaxis tick place rounded true\n"); if (m_bTickInX) mfprintf(a,"@ xaxis tick in\n"); else mfprintf(a,"@ xaxis tick out\n"); mfprintf(a,"@ xaxis tick major size 1.000000\n"); mfprintf(a,"@ xaxis tick major color 1\n"); mfprintf(a,"@ xaxis tick major linewidth 2.0\n"); mfprintf(a,"@ xaxis tick major linestyle 1\n"); mfprintf(a,"@ xaxis tick major grid off\n"); mfprintf(a,"@ xaxis tick minor color 1\n"); mfprintf(a,"@ xaxis tick minor linewidth 2.0\n"); mfprintf(a,"@ xaxis tick minor linestyle 1\n"); mfprintf(a,"@ xaxis tick minor grid off\n"); mfprintf(a,"@ xaxis tick minor size 0.500000\n"); if (m_bTickLabels) mfprintf(a,"@ xaxis ticklabel %s\n",m_bShowXAxis?"on":"off"); else mfprintf(a,"@ xaxis ticklabel off\n"); mfprintf(a,"@ xaxis ticklabel format decimal\n"); mfprintf(a,"@ xaxis ticklabel prec %d\n",m_iTickPrecX); mfprintf(a,"@ xaxis ticklabel formula \"\"\n"); mfprintf(a,"@ xaxis ticklabel append \"\"\n"); mfprintf(a,"@ xaxis ticklabel prepend \"\"\n"); mfprintf(a,"@ xaxis ticklabel angle 0\n"); mfprintf(a,"@ xaxis ticklabel skip 0\n"); mfprintf(a,"@ xaxis ticklabel stagger 0\n"); if (m_bTickLabelsBothSidesX) mfprintf(a,"@ xaxis ticklabel place both\n"); else mfprintf(a,"@ xaxis ticklabel place normal\n"); mfprintf(a,"@ xaxis ticklabel offset auto\n"); mfprintf(a,"@ xaxis ticklabel offset 0.000000 , 0.010000\n"); mfprintf(a,"@ xaxis ticklabel start type auto\n"); mfprintf(a,"@ xaxis ticklabel start 0.000000\n"); mfprintf(a,"@ xaxis ticklabel stop type auto\n"); mfprintf(a,"@ xaxis ticklabel stop 0.000000\n"); mfprintf(a,"@ xaxis ticklabel char size 1.000000\n"); mfprintf(a,"@ xaxis ticklabel font 4\n"); mfprintf(a,"@ xaxis ticklabel color 1\n"); if (m_bTicksBothSidesX) mfprintf(a,"@ xaxis tick place both\n"); else mfprintf(a,"@ xaxis tick place normal\n"); if (m_oaCustomLabelsX.GetSize() > 0) { mfprintf(a,"@ xaxis tick spec type both\n"); mfprintf(a,"@ xaxis tick spec %d\n",m_oaCustomLabelsX.GetSize()); for (z=0;zWrite(a); } else { mfprintf(a,"@ xaxis tick spec type none\n"); } mfprintf(a,"@ yaxis on\n"); mfprintf(a,"@ yaxis type zero false\n"); mfprintf(a,"@ yaxis offset 0.000000 , 0.000000\n"); mfprintf(a,"@ yaxis bar on\n"); mfprintf(a,"@ yaxis bar color 1\n"); mfprintf(a,"@ yaxis bar linestyle 1\n"); mfprintf(a,"@ yaxis bar linewidth %.1f\n",m_fYAxisBarWidth); mfprintf(a,"@ yaxis label \"%s\"\n",m_sLabelY); mfprintf(a,"@ yaxis label layout para\n"); mfprintf(a,"@ yaxis label place auto\n"); mfprintf(a,"@ yaxis label char size 1.000000\n"); mfprintf(a,"@ yaxis label font 4\n"); mfprintf(a,"@ yaxis label color 1\n"); mfprintf(a,"@ yaxis label place normal\n"); if (m_bTicks) mfprintf(a,"@ yaxis tick on\n"); else mfprintf(a,"@ yaxis tick off\n"); mfprintf(a,"@ yaxis tick major %f\n",m_fTickMajorY); mfprintf(a,"@ yaxis tick minor ticks %d\n",m_iTickMinorY); mfprintf(a,"@ yaxis tick default 6\n"); mfprintf(a,"@ yaxis tick place rounded true\n"); if (m_bTickInY) mfprintf(a,"@ yaxis tick in\n"); else mfprintf(a,"@ yaxis tick out\n"); mfprintf(a,"@ yaxis tick major size 1.000000\n"); mfprintf(a,"@ yaxis tick major color 1\n"); mfprintf(a,"@ yaxis tick major linewidth 2.0\n"); mfprintf(a,"@ yaxis tick major linestyle 1\n"); mfprintf(a,"@ yaxis tick major grid off\n"); mfprintf(a,"@ yaxis tick minor color 1\n"); mfprintf(a,"@ yaxis tick minor linewidth 2.0\n"); mfprintf(a,"@ yaxis tick minor linestyle 1\n"); mfprintf(a,"@ yaxis tick minor grid off\n"); mfprintf(a,"@ yaxis tick minor size 0.500000\n"); if (m_bTickLabels) mfprintf(a,"@ yaxis ticklabel on\n"); else mfprintf(a,"@ yaxis ticklabel off\n"); mfprintf(a,"@ yaxis ticklabel format decimal\n"); mfprintf(a,"@ yaxis ticklabel prec %d\n",m_iTickPrecY); mfprintf(a,"@ yaxis ticklabel formula \"\"\n"); mfprintf(a,"@ yaxis ticklabel append \"\"\n"); mfprintf(a,"@ yaxis ticklabel prepend \"\"\n"); mfprintf(a,"@ yaxis ticklabel angle 0\n"); mfprintf(a,"@ yaxis ticklabel skip 0\n"); mfprintf(a,"@ yaxis ticklabel stagger 0\n"); if (m_bTickLabelsBothSidesY) mfprintf(a,"@ yaxis ticklabel place both\n"); else mfprintf(a,"@ yaxis ticklabel place normal\n"); mfprintf(a,"@ yaxis ticklabel offset auto\n"); mfprintf(a,"@ yaxis ticklabel offset 0.000000 , 0.010000\n"); mfprintf(a,"@ yaxis ticklabel start type auto\n"); mfprintf(a,"@ yaxis ticklabel start 0.000000\n"); mfprintf(a,"@ yaxis ticklabel stop type auto\n"); mfprintf(a,"@ yaxis ticklabel stop 0.000000\n"); mfprintf(a,"@ yaxis ticklabel char size 1.000000\n"); mfprintf(a,"@ yaxis ticklabel font 4\n"); mfprintf(a,"@ yaxis ticklabel color 1\n"); if (m_bTicksBothSidesY) mfprintf(a,"@ yaxis tick place both\n"); else mfprintf(a,"@ yaxis tick place normal\n"); if (m_oaCustomLabelsY.GetSize() > 0) { mfprintf(a,"@ yaxis tick spec type both\n"); mfprintf(a,"@ yaxis tick spec %d\n",m_oaCustomLabelsY.GetSize()); for (z=0;zWrite(a); } else { mfprintf(a,"@ yaxis tick spec type none\n"); } mfprintf(a,"@ altxaxis off\n"); mfprintf(a,"@ altyaxis off\n"); if (m_bLegend) mfprintf(a,"@ legend on\n"); else mfprintf(a,"@ legend off\n"); mfprintf(a,"@ legend loctype view\n"); mfprintf(a,"@ legend 0.9, 0.84\n"); mfprintf(a,"@ legend box color 1\n"); mfprintf(a,"@ legend box pattern 1\n"); mfprintf(a,"@ legend box linewidth 2.0\n"); mfprintf(a,"@ legend box linestyle 1\n"); mfprintf(a,"@ legend box fill color 0\n"); mfprintf(a,"@ legend box fill pattern 1\n"); mfprintf(a,"@ legend font 4\n"); mfprintf(a,"@ legend char size 1.000000\n"); mfprintf(a,"@ legend color 1\n"); mfprintf(a,"@ legend length 4\n"); mfprintf(a,"@ legend vgap 1\n"); mfprintf(a,"@ legend hgap 1\n"); if (m_bInvert) mfprintf(a,"@ legend invert true\n"); else mfprintf(a,"@ legend invert false\n"); mfprintf(a,"@ frame type 0\n"); mfprintf(a,"@ frame linestyle 1\n"); mfprintf(a,"@ frame linewidth %f\n",m_fFrameWidth); mfprintf(a,"@ frame color 1\n"); mfprintf(a,"@ frame pattern %d\n",m_bShowFrame?1:0); mfprintf(a,"@ frame background color 0\n"); mfprintf(a,"@ frame background pattern 0\n"); for (z=0;zWriteHeader(a); } void CGraceDataset::WriteHeader(FILE *a) { // CGraceGraph *g; // g = m_pGraph; mfprintf(a,"@ s%d hidden false\n",m_iNumber); mfprintf(a,"@ s%d type xy\n",m_iNumber); if ( m_bSymbol ) { mfprintf(a,"@ s%d symbol 1\n",m_iNumber); mfprintf(a,"@ s%d symbol size 0.500000\n",m_iNumber); mfprintf(a,"@ s%d symbol color %d\n",m_iNumber,m_iLineColorIndex); mfprintf(a,"@ s%d symbol pattern 1\n",m_iNumber); mfprintf(a,"@ s%d symbol fill color %d\n",m_iNumber,m_iLineColorIndex); mfprintf(a,"@ s%d symbol fill pattern 1\n",m_iNumber); mfprintf(a,"@ s%d symbol linewidth 1.0\n",m_iNumber); mfprintf(a,"@ s%d symbol linestyle 1\n",m_iNumber); mfprintf(a,"@ s%d symbol char 65\n",m_iNumber); mfprintf(a,"@ s%d symbol char font 0\n",m_iNumber); mfprintf(a,"@ s%d symbol skip 0\n",m_iNumber); mfprintf(a,"@ s%d line type 1\n",m_iNumber); mfprintf(a,"@ s%d line linestyle 0\n",m_iNumber); mfprintf(a,"@ s%d line linewidth %.1f\n",m_iNumber,m_fLineWidth); mfprintf(a,"@ s%d line color %d\n",m_iNumber,m_iLineColorIndex); mfprintf(a,"@ s%d line pattern 1\n",m_iNumber); } else { mfprintf(a,"@ s%d symbol 0\n",m_iNumber); mfprintf(a,"@ s%d symbol size 1.000000\n",m_iNumber); mfprintf(a,"@ s%d symbol color %d\n",m_iNumber,m_iSymbColorIndex); mfprintf(a,"@ s%d symbol pattern 1\n",m_iNumber); mfprintf(a,"@ s%d symbol fill color %d\n",m_iNumber,m_iSymbColorIndex); mfprintf(a,"@ s%d symbol fill pattern 0\n",m_iNumber); mfprintf(a,"@ s%d symbol linewidth 1.0\n",m_iNumber); mfprintf(a,"@ s%d symbol linestyle 1\n",m_iNumber); mfprintf(a,"@ s%d symbol char 65\n",m_iNumber); mfprintf(a,"@ s%d symbol char font 0\n",m_iNumber); mfprintf(a,"@ s%d symbol skip 0\n",m_iNumber); mfprintf(a,"@ s%d line type 1\n",m_iNumber); mfprintf(a,"@ s%d line linestyle 1\n",m_iNumber); mfprintf(a,"@ s%d line linewidth %.1f\n",m_iNumber,m_fLineWidth); mfprintf(a,"@ s%d line color %d\n",m_iNumber,m_iLineColorIndex); mfprintf(a,"@ s%d line pattern 1\n",m_iNumber); } mfprintf(a,"@ s%d baseline type 0\n",m_iNumber); mfprintf(a,"@ s%d baseline off\n",m_iNumber); mfprintf(a,"@ s%d dropline off\n",m_iNumber); if (m_bFill) mfprintf(a,"@ s%d fill type 2\n",m_iNumber); else mfprintf(a,"@ s%d fill type 0\n",m_iNumber); mfprintf(a,"@ s%d fill rule 0\n",m_iNumber); mfprintf(a,"@ s%d fill color %d\n",m_iNumber,m_iLineColorIndex); mfprintf(a,"@ s%d fill pattern 1\n",m_iNumber); mfprintf(a,"@ s%d avalue off\n",m_iNumber); mfprintf(a,"@ s%d avalue type 2\n",m_iNumber); mfprintf(a,"@ s%d avalue char size 1.000000\n",m_iNumber); mfprintf(a,"@ s%d avalue font 0\n",m_iNumber); mfprintf(a,"@ s%d avalue color 1\n",m_iNumber); mfprintf(a,"@ s%d avalue rot 0\n",m_iNumber); mfprintf(a,"@ s%d avalue format general\n",m_iNumber); mfprintf(a,"@ s%d avalue prec 3\n",m_iNumber); mfprintf(a,"@ s%d avalue prepend \"\"\n",m_iNumber); mfprintf(a,"@ s%d avalue append \"\"\n",m_iNumber); mfprintf(a,"@ s%d avalue offset 0.000000 , 0.000000\n",m_iNumber); mfprintf(a,"@ s%d errorbar on\n",m_iNumber); mfprintf(a,"@ s%d errorbar place both\n",m_iNumber); mfprintf(a,"@ s%d errorbar color 4\n",m_iNumber); mfprintf(a,"@ s%d errorbar pattern 1\n",m_iNumber); mfprintf(a,"@ s%d errorbar size 1.000000\n",m_iNumber); mfprintf(a,"@ s%d errorbar linewidth 1.0\n",m_iNumber); mfprintf(a,"@ s%d errorbar linestyle 1\n",m_iNumber); mfprintf(a,"@ s%d errorbar riser linewidth 1.0\n",m_iNumber); mfprintf(a,"@ s%d errorbar riser linestyle 1\n",m_iNumber); mfprintf(a,"@ s%d errorbar riser clip off\n",m_iNumber); mfprintf(a,"@ s%d errorbar riser clip length 0.100000\n",m_iNumber); mfprintf(a,"@ s%d comment \"%s\"\n",m_iNumber,m_sName); mfprintf(a,"@ s%d legend \"%s\"\n",m_iNumber,m_sName); } void CGraceDataset::WriteSet(FILE *a) { int z; mfprintf(a,"@type xy\n"); for (z=m_iBegin;z<(((m_faValues.GetSize()/2)m_pGraph = g; gd->m_iNumber = g->m_oaDatasets.GetSize(); gd->m_iLineColorIndex = (gd->m_iNumber % 15) + 1; // alles ausser weiss g->m_oaDatasets.Add(gd); } void CGrace::AddGraph() { CGraceGraph *g; try { g = new CGraceGraph(); } catch(...) { g = NULL; } if (g == NULL) NewException((double)sizeof(CGraceGraph),__FILE__,__LINE__,__PRETTY_FUNCTION__); g->m_iNumber = m_oaGraceGraphs.GetSize(); m_oaGraceGraphs.Add(g); } void CGrace::AddXYTupel(int set, double x, double y) { CGraceGraph *g; g = CurrentGraph(); /* if (set >= g->m_oaDatasets.GetSize()) { eprintf("CGrace::AddXYTupel(): Set %d >= %d.\n",set,g->m_oaDatasets.GetSize()); return; }*/ ((CGraceDataset*)g->m_oaDatasets[set])->m_faValues.Add(x); ((CGraceDataset*)g->m_oaDatasets[set])->m_faValues.Add(y); ((CGraceDataset*)g->m_oaDatasets[set])->m_iEnd = ((CGraceDataset*)g->m_oaDatasets[set])->m_faValues.GetSize()/2; } void CGrace::AddXYTupel(double x, double y) { AddXYTupel(CurrentGraph()->m_oaDatasets.GetSize()-1,x,y); } void CGrace::FindMinMaxVal() { CGraceDataset *gd; int z, z2; CGraceGraph *g; g = CurrentGraph(); g->m_fMinValX = (double)9E20; g->m_fMinValY = (double)9E20; g->m_fMaxValX = (double)-9E20; g->m_fMaxValY = (double)-9E20; for (z=0;zm_oaDatasets.GetSize();z++) { gd = (CGraceDataset*)g->m_oaDatasets[z]; for (z2=0;z2m_faValues.GetSize()/2;z2++) { if (gd->m_faValues[z2*2] > g->m_fMaxValX) g->m_fMaxValX = (double)gd->m_faValues[z2*2]; if (gd->m_faValues[z2*2] < g->m_fMinValX) g->m_fMinValX = (double)gd->m_faValues[z2*2]; if (gd->m_faValues[z2*2+1] > g->m_fMaxValY) g->m_fMaxValY = (double)gd->m_faValues[z2*2+1]; if (gd->m_faValues[z2*2+1] < g->m_fMinValY) g->m_fMinValY = (double)gd->m_faValues[z2*2+1]; } // mprintf("Dataset %d: X %f - %f, Y %f - %f.\n",z+1,g->m_fMinValX,g->m_fMaxValX,g->m_fMinValY,g->m_fMaxValY); } } void CGrace::SetTitle(const char *s) { CGraceGraph *g; g = CurrentGraph(); if (g->m_sTitle != NULL) delete[] g->m_sTitle; try { g->m_sTitle = new char[strlen(s)+1]; } catch(...) { g->m_sTitle = NULL; } if (g->m_sTitle == NULL) NewException((double)(strlen(s)+1)*sizeof(char),__FILE__,__LINE__,__PRETTY_FUNCTION__); strcpy(g->m_sTitle,s); } void CGrace::SetSubTitle(const char *s) { CGraceGraph *g; g = CurrentGraph(); if (g->m_sSubTitle != NULL) delete[] g->m_sSubTitle; try { g->m_sSubTitle = new char[strlen(s)+1]; } catch(...) { g->m_sSubTitle = NULL; } if (g->m_sSubTitle == NULL) NewException((double)(strlen(s)+1)*sizeof(char),__FILE__,__LINE__,__PRETTY_FUNCTION__); strcpy(g->m_sSubTitle,s); } void CGrace::SetLabelX(const char *s) { CGraceGraph *g; g = CurrentGraph(); if (g->m_sLabelX != NULL) delete[] g->m_sLabelX; try { g->m_sLabelX = new char[strlen(s)+1]; } catch(...) { g->m_sLabelX = NULL; } if (g->m_sLabelX == NULL) NewException((double)(strlen(s)+1)*sizeof(char),__FILE__,__LINE__,__PRETTY_FUNCTION__); strcpy(g->m_sLabelX,s); } void CGrace::SetLabelY(const char *s) { CGraceGraph *g; g = CurrentGraph(); if (g->m_sLabelY != NULL) delete[] g->m_sLabelY; try { g->m_sLabelY = new char[strlen(s)+1]; } catch(...) { g->m_sLabelY = NULL; } if (g->m_sLabelY == NULL) NewException((double)(strlen(s)+1)*sizeof(char),__FILE__,__LINE__,__PRETTY_FUNCTION__); strcpy(g->m_sLabelY,s); } void CGrace::SetRangeX(double mi, double ma) { CGraceGraph *g; g = CurrentGraph(); g->m_fMinRangeX = (double)mi; g->m_fMaxRangeX = (double)ma; g->m_fTickMajorX = majorticks(g->m_fMinRangeX,g->m_fMaxRangeX); g->m_iTickPrecX = (int)MAX(0,1-int(ceil(log10(g->m_fTickMajorX)))); } void CGrace::SetRangeY(double mi, double ma) { CGraceGraph *g; g = CurrentGraph(); g->m_fMinRangeY = (double)mi; g->m_fMaxRangeY = (double)ma; g->m_fTickMajorY = majorticks(g->m_fMinRangeY,g->m_fMaxRangeY); g->m_iTickPrecY = (int)MAX(0,1-int(ceil(log10(g->m_fTickMajorY)))); } void CGrace::DuplicateSet(int set) { CGraceDataset* gd; CGraceGraph *g; g = CurrentGraph(); try { gd = new CGraceDataset(); } catch(...) { gd = NULL; } if (gd == NULL) NewException((double)sizeof(CGraceDataset),__FILE__,__LINE__,__PRETTY_FUNCTION__); gd->CopyFrom((CGraceDataset*)g->m_oaDatasets[set]); gd->m_iNumber = g->m_oaDatasets.GetSize(); g->m_oaDatasets.Add(gd); } void CGraceDataset::CopyFrom(CGraceDataset *d) { m_faValues.CopyFrom(&d->m_faValues); m_iLineColorIndex = d->m_iLineColorIndex; m_fLineWidth = d->m_fLineWidth; m_bFill = d->m_bFill; m_iSymbColorIndex = d->m_iSymbColorIndex; m_pGraph = d->m_pGraph; } void CGrace::SetSetRange(int set, int start, int end) { CGraceDataset* gd; CGraceGraph *g; g = CurrentGraph(); gd = (CGraceDataset*)g->m_oaDatasets[set]; gd->m_iBegin = start; if (end == -1) gd->m_iEnd = gd->m_faValues.GetSize()/2; else gd->m_iEnd = end; } void CGrace::SetSetLineColor(int set, unsigned char r, unsigned char g, unsigned char b) { int z; CGraceColor *gc; // char buf[64]; CxString buf; for (z=0;zm_iColorRed == r) && (gc->m_iColorGreen == g) && (gc->m_iColorBlue == b)) goto _done; } if (m_oaGraceColors.GetSize() < 254) { // sprintf(buf,"set%d",set+1); buf.sprintf("set%d",set+1); z = AddColor(r,g,b,buf); } else z = 1; _done: ((CGraceDataset*)CurrentGraph()->m_oaDatasets[set])->m_iLineColorIndex = z; ((CGraceDataset*)CurrentGraph()->m_oaDatasets[set])->m_iSymbColorIndex = z; } void CGrace::SetSetLineColor(unsigned char r, unsigned char g, unsigned char b) { SetSetLineColor(CurrentGraph()->m_oaDatasets.GetSize()-1,r,g,b); } void CGrace::SetSetLineColorLong(int set, unsigned long col) { SetSetLineColor(set,(unsigned char)(col & 0x100), (unsigned char)((col >> 8) & 0x100), (unsigned char)(col >> 16)); } void CGrace::SetSetLineWidth(int set, double width) { CGraceDataset* gd; CGraceGraph *g; g = CurrentGraph(); gd = (CGraceDataset*)g->m_oaDatasets[set]; gd->m_fLineWidth = width; } void CGraceLine::WriteLine(FILE *a, int graph) { mfprintf(a,"@with line\n"); mfprintf(a,"@ line on\n"); mfprintf(a,"@ line loctype world\n"); mfprintf(a,"@ line g%d\n",graph); mfprintf(a,"@ line %f, %f, %f, %f\n",m_fX1,m_fY1,m_fX2,m_fY2); mfprintf(a,"@ line linewidth %.1f\n",m_fLineWidth); mfprintf(a,"@ line linestyle %d\n",m_iLineStyle); mfprintf(a,"@ line color %d\n",m_iLineColorIndex); mfprintf(a,"@ line arrow 0\n"); mfprintf(a,"@ line arrow type 0\n"); mfprintf(a,"@ line arrow length 1.000000\n"); mfprintf(a,"@ line arrow layout 1.000000, 1.000000\n"); mfprintf(a,"@line def\n"); } void CGrace::AddCustomLabelX(bool major, double val, const char *s) { CGraceCustomLabel *cl; CGraceGraph *g; g = CurrentGraph(); try { cl = new CGraceCustomLabel(); } catch(...) { cl = NULL; } if (cl == NULL) NewException((double)sizeof(CGraceCustomLabel),__FILE__,__LINE__,__PRETTY_FUNCTION__); cl->m_bMajor = major; cl->m_fValue = val; try { cl->m_sText = new char[strlen(s)+1]; } catch(...) { cl->m_sText = NULL; } if (cl->m_sText == NULL) NewException((double)(strlen(s)+1)*sizeof(char),__FILE__,__LINE__,__PRETTY_FUNCTION__); cl->m_bX = true; strcpy(cl->m_sText,s); cl->m_iNumber = g->m_oaCustomLabelsX.GetSize(); g->m_oaCustomLabelsX.Add(cl); } void CGrace::AddCustomLabelY(bool major, double val, const char *s) { CGraceCustomLabel *cl; CGraceGraph *g; g = CurrentGraph(); try { cl = new CGraceCustomLabel(); } catch(...) { cl = NULL; } if (cl == NULL) NewException((double)sizeof(CGraceCustomLabel),__FILE__,__LINE__,__PRETTY_FUNCTION__); cl->m_bMajor = major; cl->m_fValue = val; try { cl->m_sText = new char[strlen(s)+1]; } catch(...) { cl->m_sText = NULL; } if (cl->m_sText == NULL) NewException((double)(strlen(s)+1)*sizeof(char),__FILE__,__LINE__,__PRETTY_FUNCTION__); cl->m_bX = false; strcpy(cl->m_sText,s); cl->m_iNumber = g->m_oaCustomLabelsY.GetSize(); g->m_oaCustomLabelsY.Add(cl); } void CGrace::AddLine(double x1, double y1, double x2, double y2, double width, int style) { CGraceLine *gl; CGraceGraph *g; g = CurrentGraph(); try { gl = new CGraceLine(); } catch(...) { gl = NULL; } if (gl == NULL) NewException((double)sizeof(CGraceLine),__FILE__,__LINE__,__PRETTY_FUNCTION__); gl->m_fX1 = x1; gl->m_fY1 = y1; gl->m_fX2 = x2; gl->m_fY2 = y2; gl->m_fLineWidth = width; gl->m_iLineStyle = style; gl->m_iLineColorIndex = 1; g->m_oaLines.Add(gl); } void CGrace::AddLine(double x1, double y1, double x2, double y2, double width, int style, unsigned char r, unsigned char g, unsigned char b) { CGraceLine *gl; CGraceGraph *gg; CGraceColor *gc; int z; // char buf[64]; CxString buf; gg = CurrentGraph(); try { gl = new CGraceLine(); } catch(...) { gl = NULL; } if (gl == NULL) NewException((double)sizeof(CGraceLine),__FILE__,__LINE__,__PRETTY_FUNCTION__); gl->m_fX1 = x1; gl->m_fY1 = y1; gl->m_fX2 = x2; gl->m_fY2 = y2; gl->m_fLineWidth = width; gl->m_iLineStyle = style; for (z=0;zm_iColorRed == r) && (gc->m_iColorGreen == g) && (gc->m_iColorBlue == b)) goto _done; } if (m_oaGraceColors.GetSize() < 254) { // sprintf(buf,"line%d",gg->m_oaLines.GetSize()+1); buf.sprintf("line%d",gg->m_oaLines.GetSize()+1); z = AddColor(r,g,b,buf); } else z = 1; _done: gl->m_iLineColorIndex = z; gg->m_oaLines.Add(gl); } void CGraceCustomLabel::Write(FILE *a) { if (m_bMajor) mfprintf(a,"@ %caxis tick major %d, %f\n",m_bX?'x':'y',m_iNumber,m_fValue); else mfprintf(a,"@ %caxis tick minor %d, %f\n",m_bX?'x':'y',m_iNumber,m_fValue); if (strlen(m_sText) != 0) mfprintf(a,"@ %caxis ticklabel %d, \"%s\"\n",m_bX?'x':'y',m_iNumber,m_sText); } void CGrace::SetViewport(double x1, double y1, double x2, double y2) { CGraceGraph *g; g = CurrentGraph(); g->m_fViewportX1 = x1; g->m_fViewportY1 = y1; g->m_fViewportX2 = x2; g->m_fViewportY2 = y2; } CGraceGraph* CGrace::CurrentGraph() { return (CGraceGraph*)m_oaGraceGraphs[m_oaGraceGraphs.GetSize()-1]; } CGraceDataset* CGrace::LastDataset() { return (CGraceDataset*)CurrentGraph()->m_oaDatasets[CurrentGraph()->m_oaDatasets.GetSize()-1]; } void CGrace::SetDatasetName(int set, const char *s) { CGraceGraph *g; CGraceDataset *ds; g = CurrentGraph(); ds = (CGraceDataset*)g->m_oaDatasets[set]; if (ds->m_sName != NULL) delete[] ds->m_sName; try { ds->m_sName = new char[strlen(s)+1]; } catch(...) { ds->m_sName = NULL; } if (ds->m_sName == NULL) NewException((double)(strlen(s)+1)*sizeof(char),__FILE__,__LINE__,__PRETTY_FUNCTION__); strcpy(ds->m_sName,s); } void CGrace::SetDatasetName(const char *s) { SetDatasetName(CurrentGraph()->m_oaDatasets.GetSize()-1,s); } void CGrace::WriteCSV(const char *s) { int z, z2; FILE *a; CGraceGraph *g; g = CurrentGraph(); a = OpenFileWrite(s,true); for (z=0;z<((CGraceDataset*)g->m_oaDatasets[0])->m_faValues.GetSize()/2;z++) { mfprintf(a,"%G; ",((CGraceDataset*)g->m_oaDatasets[0])->m_faValues[z*2]); for (z2=0;z2m_oaDatasets.GetSize();z2++) { mfprintf(a,"%G",((CGraceDataset*)g->m_oaDatasets[z2])->m_faValues[z*2+1]); if (z2 < g->m_oaDatasets.GetSize()-1) mfprintf(a,"; "); } mfprintf(a,"\n"); } fclose(a); } int CGrace::AddColor(unsigned char r, unsigned char g, unsigned char b, const char *name) { CGraceColor *gc; try { gc = new CGraceColor(); } catch(...) { gc = NULL; } if (gc == NULL) NewException((double)sizeof(CGraceColor),__FILE__,__LINE__,__PRETTY_FUNCTION__); gc->m_iColorRed = r; gc->m_iColorGreen = g; gc->m_iColorBlue = b; gc->SetName(name); m_oaGraceColors.Add(gc); return m_oaGraceColors.GetSize()-1; } void CGraceColor::SetName(const char *s) { if (m_sName != NULL) delete[] m_sName; try { m_sName = new char[strlen(s)+1]; } catch(...) { m_sName = NULL; } if (m_sName == NULL) NewException((double)(strlen(s)+1)*sizeof(char),__FILE__,__LINE__,__PRETTY_FUNCTION__); strcpy(m_sName,s); } travis-src-190101/src/grace.h0100777000000000000000000001222513412725663012676 0ustar00/***************************************************************************** TRAVIS - Trajectory Analyzer and Visualizer http://www.travis-analyzer.de/ Copyright (c) 2009-2019 Martin Brehm 2012-2019 Martin Thomas 2016-2019 Sascha Gehrke This file was written by Martin Brehm. --------------------------------------------------------------------------- This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . *****************************************************************************/ #ifndef GRACE_H #define GRACE_H // This must always be the first include directive #include "config.h" #include "xobject.h" #include "xobarray.h" #include "xdoublearray.h" class CGraceDataset; class CGraceGraph : public CxObject { public: CGraceGraph(); ~CGraceGraph(); void WriteData(FILE *a, bool silent); void Write(FILE *a); CGraceDataset* CurrentDataset(); CGraceDataset* Dataset(int i); CxObArray m_oaDatasets; CxObArray m_oaCustomLabelsX; CxObArray m_oaCustomLabelsY; CxObArray m_oaLines; double m_fYAxisBarWidth; bool m_bShowFrame; bool m_bShowXAxis; double m_fMinRangeX; double m_fMaxRangeX; double m_fMinRangeY; double m_fMaxRangeY; double m_fTickMajorX; int m_iTickPrecX; double m_fTickMajorY; int m_iTickPrecY; int m_iTickMinorX; int m_iTickMinorY; double m_fMinValX; double m_fMaxValX; double m_fMinValY; double m_fMaxValY; char *m_sTitle; char *m_sLabelX; char *m_sLabelY; char *m_sSubTitle; bool m_bTicksBothSidesX; bool m_bTicksBothSidesY; bool m_bTickLabelsBothSidesX; bool m_bTickLabelsBothSidesY; bool m_bInvertXAxis; bool m_bInvertYAxis; bool m_bInvert; int m_iColorIndex; int m_iNumber; double m_fViewportX1; double m_fViewportY1; double m_fViewportX2; double m_fViewportY2; bool m_bTicks; bool m_bTickLabels; bool m_bTickInX; bool m_bTickInY; bool m_bLegend; double m_fFrameWidth; }; class CGraceColor : public CxObject { public: void SetName(const char *s); CGraceColor(); ~CGraceColor(); unsigned char m_iColorRed; unsigned char m_iColorGreen; unsigned char m_iColorBlue; char *m_sName; }; class CGraceDataset : public CxObject { public: void CopyFrom(CGraceDataset *d); int m_iNumber; void WriteSet(FILE *a); void WriteHeader(FILE *a); CGraceDataset(); ~CGraceDataset(); CxDoubleArray m_faValues; // unsigned long m_iLineColor; // unsigned long m_iSymbColor; int m_iLineColorIndex; int m_iSymbColorIndex; char *m_sName; double m_fLineWidth; unsigned char m_iLineStyle; int m_iBegin; int m_iEnd; bool m_bFill; bool m_bSymbol; CGraceGraph *m_pGraph; }; class CGraceLine : public CxObject { public: CGraceLine() { } ~CGraceLine() { } void WriteLine(FILE *a, int graph); double m_fX1; double m_fY1; double m_fX2; double m_fY2; double m_fLineWidth; int m_iLineStyle; int m_iLineColorIndex; }; class CGraceCustomLabel : public CxObject { public: void Write(FILE *a); CGraceCustomLabel() { } ~CGraceCustomLabel() { } bool m_bX; int m_iNumber; bool m_bMajor; char *m_sText; double m_fValue; }; class CGrace : public CxObject { public: int AddColor(unsigned char r, unsigned char g, unsigned char b, const char *name); void WriteCSV(const char *s); void SetDatasetName(const char *s); void SetDatasetName(int set, const char *s); CGraceDataset* LastDataset(); void SetViewport(double x1, double y1, double x2, double y2); void AddGraph(); CGraceGraph* CurrentGraph(); void AddLine(double x1, double y1, double x2, double y2, double width, int style); void AddLine(double x1, double y1, double x2, double y2, double width, int style, unsigned char r, unsigned char g, unsigned char b); void AddCustomLabelY(bool major, double val, const char *s); void AddCustomLabelX(bool major, double val, const char *s); void SetSetLineWidth(int set, double width); void SetSetLineColorLong(int set, unsigned long col); void SetSetLineColor(int set, unsigned char r, unsigned char g, unsigned char b); void SetSetLineColor(unsigned char r, unsigned char g, unsigned char b); void SetSetRange(int set, int start, int end); void DuplicateSet(int set); void SetRangeY(double mi, double ma); void SetRangeX(double mi, double ma); void SetLabelY(const char *s); void SetLabelX(const char *s); void SetSubTitle(const char *s); void SetTitle(const char *s); void FindMinMaxVal(); void AddXYTupel(int set, double x, double y); void AddXYTupel(double x, double y); void AddDataset(); void WriteAgr(const char *s, bool silent); CxObArray m_oaGraceGraphs; CxObArray m_oaGraceColors; void MakeTicks(); unsigned long m_iBGColor; CGrace(); ~CGrace(); }; #endif travis-src-190101/src/hbond.cpp0100777000000000000000000010257413412725632013245 0ustar00/***************************************************************************** TRAVIS - Trajectory Analyzer and Visualizer http://www.travis-analyzer.de/ Copyright (c) 2009-2019 Martin Brehm 2012-2019 Martin Thomas 2016-2019 Sascha Gehrke This file was written by Sascha Gehrke. --------------------------------------------------------------------------- This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . *****************************************************************************/ // This must always be the first include directive #include "config.h" #include "hbond.h" #include "luzar.h" #include #include "globalvar.h" #include "maintools.h" const char *GetRevisionInfo_hbond(unsigned int len) { static char buf[256]; GET_REVISION_INFO( buf, len ); return buf; } const char *GetSourceVersion_hbond() { static char buf[256]; GET_SOURCE_VERSION( buf ); return buf; } static CxObArray g_HBondObserv; bool gatherHBond() { CHBondObservation *o; try { o = new CHBondObservation(); } catch(...) { o = NULL; } if (o == NULL) NewException((double)sizeof(CHBondObservation),__FILE__,__LINE__,__PRETTY_FUNCTION__); g_HBondObserv.Add(o); return true; } bool initializeHBond() { int i; for(i = 0; i < g_HBondObserv.GetSize(); i++) { ((CHBondObservation *)g_HBondObserv[i])->initialize(); } return true; } bool processHBond(CTimeStep* ts) { int i; for(i = 0; i < g_HBondObserv.GetSize(); i++) { ((CHBondObservation *)g_HBondObserv[i])->process(ts); } return true; } bool finalizeHBond() { int i; for(i = 0; i < g_HBondObserv.GetSize(); i++) { ((CHBondObservation *)g_HBondObserv[i])->finalize(); } return true; } CHBondObservation::CHBondObservation() { int z, z2; CxString buf, buf2; try { m_laAccep = new CxIntArray(); } catch(...) { m_laAccep = NULL; } if (m_laAccep == NULL) NewException((double)sizeof(CxIntArray),__FILE__,__LINE__,__PRETTY_FUNCTION__); try { m_laHydro = new CxIntArray(); } catch(...) { m_laHydro = NULL; } if (m_laHydro == NULL) NewException((double)sizeof(CxIntArray),__FILE__,__LINE__,__PRETTY_FUNCTION__); try { m_laDonor = new CxIntArray(); } catch(...) { m_laDonor = NULL; } if (m_laDonor == NULL) NewException((double)sizeof(CxIntArray),__FILE__,__LINE__,__PRETTY_FUNCTION__); if (g_oaMolecules.GetSize() > 1) { buf.sprintf("\n Which of the molecules should be the donor molecule ("); for (z=0;zm_sName,z+1); buf.strcat(buf2); if (z < g_oaMolecules.GetSize()-1) buf.strcat(", "); } buf.strcat(")? "); m_iShowMol = AskRangeInteger_ND("%s",1,g_oaMolecules.GetSize(),(const char*)buf) - 1; mprintf(WHITE,"\n %s is the donor molecule.\n\n",((CMolecule*)g_oaMolecules[m_iShowMol])->m_sName); buf.sprintf("\n Which of the molecules should be the acceptor molecule ("); for (z=0;zm_sName,z+1); buf.strcat(buf2); if (z < g_oaMolecules.GetSize()-1) buf.strcat(", "); } buf.strcat(")? "); m_iShowMol2 = AskRangeInteger_ND("%s",1,g_oaMolecules.GetSize(),(const char*)buf) - 1; mprintf(WHITE,"\n %s is the acceptor molecule.\n\n",((CMolecule*)g_oaMolecules[m_iShowMol2])->m_sName); } else { m_iShowMol = 0; m_iShowMol2 = 0; } mprintf(WHITE," Please note:"); mprintf(" You have to enter the hydrogen bond donor atoms below.\n"); mprintf(" In this analysis, the donors are not the hydrogen atoms themselves,\n"); mprintf(" but the atoms they are bound to (e.g., O, N, C). Enter those as donors.\n"); mprintf(" The relevant hydrogen atoms will then be automatically detected.\n\n"); mprintf(" Which atom(s) from %s are involved as hydrogen bond donor (e.g. \"C1,O3-5,N\")? ",((CMolecule*)g_oaMolecules[m_iShowMol])->m_sName); inpprintf("! Which atom(s) from %s are involved as hydrogen bond donor (e.g. \"C1,O3-5,N\")? \n",((CMolecule*)g_oaMolecules[m_iShowMol])->m_sName); myget(&buf); while ((strlen(buf) == 0) || (!checkAtomChoice((CMolecule*)g_oaMolecules[m_iShowMol],buf,((CxIntArray*)m_laDonor)))) { mprintf(" Please enter donating atom! "); myget(&buf); } mprintf("\n Added %d donor atoms in %d %s molecules:",m_laDonor->GetSize(),((CMolecule*)g_oaMolecules[m_iShowMol])->m_laSingleMolIndex.GetSize(),((CMolecule*)g_oaMolecules[m_iShowMol])->m_sName); for (z=0;zGetSize();z++) { if (g_waAtomMolIndex[m_laDonor->GetAt(z)] != m_iShowMol) { eprintf("\nError: Donor atom %s[%d] %s%d is not from donor molecule %s!\n",((CMolecule*)g_oaMolecules[g_waAtomMolIndex[m_laDonor->GetAt(z)]])->m_sName,g_laAtomSMLocalIndex[m_laDonor->GetAt(z)]+1,(const char*)((CAtom*)g_oaAtoms[g_waAtomRealElement[m_laDonor->GetAt(z)]])->m_sName,g_waAtomMolNumber[m_laDonor->GetAt(z)]+1,((CMolecule*)g_oaMolecules[m_iShowMol])->m_sName); abort(); } if (g_laAtomSMLocalIndex[m_laDonor->GetAt(z)] == 0) mprintf(" %s%d",(const char*)((CAtom*)g_oaAtoms[g_waAtomRealElement[m_laDonor->GetAt(z)]])->m_sName,g_waAtomMolNumber[m_laDonor->GetAt(z)]+1); } for (z=0;zGetSize();z++) { for (z2=z+1;z2GetSize();z2++) { if (m_laDonor->GetAt(z) == m_laDonor->GetAt(z2)) { eprintf("\nError: Donor atom %s[%d] %s%d is listed more than one time!\n",((CMolecule*)g_oaMolecules[g_waAtomMolIndex[m_laDonor->GetAt(z)]])->m_sName,g_laAtomSMLocalIndex[m_laDonor->GetAt(z)]+1,(const char*)((CAtom*)g_oaAtoms[g_waAtomRealElement[m_laDonor->GetAt(z)]])->m_sName,g_waAtomMolNumber[m_laDonor->GetAt(z)]+1); abort(); } } } mprintf("\n\n"); mprintf(" Which atom(s) from %s are involved as hydrogen bond acceptor (e.g. \"C1,O3-5,N\")? ",((CMolecule*)g_oaMolecules[m_iShowMol2])->m_sName); inpprintf("! Which atom(s) from %s are involved as hydrogen bond acceptor (e.g. \"C1,O3-5,N\")? \n",((CMolecule*)g_oaMolecules[m_iShowMol2])->m_sName); myget(&buf); while ((strlen(buf) == 0) || (!checkAtomChoice((CMolecule*)g_oaMolecules[m_iShowMol2],buf,((CxIntArray*)m_laAccep)))) { mprintf(" Please enter accepting atom! "); myget(&buf); } mprintf("\n Added %d acceptor atoms in %d %s molecules:",m_laAccep->GetSize(),((CMolecule*)g_oaMolecules[m_iShowMol2])->m_laSingleMolIndex.GetSize(),((CMolecule*)g_oaMolecules[m_iShowMol2])->m_sName); for (z=0;zGetSize();z++) { if (g_waAtomMolIndex[m_laAccep->GetAt(z)] != m_iShowMol2) { eprintf("\nError: Acceptor atom %s[%d] %s%d is not from acceptor molecule %s!\n",((CMolecule*)g_oaMolecules[g_waAtomMolIndex[m_laAccep->GetAt(z)]])->m_sName,g_laAtomSMLocalIndex[m_laAccep->GetAt(z)]+1,(const char*)((CAtom*)g_oaAtoms[g_waAtomRealElement[m_laAccep->GetAt(z)]])->m_sName,g_waAtomMolNumber[m_laAccep->GetAt(z)]+1,((CMolecule*)g_oaMolecules[m_iShowMol2])->m_sName); abort(); } if (g_laAtomSMLocalIndex[m_laAccep->GetAt(z)] == 0) mprintf(" %s%d",(const char*)((CAtom*)g_oaAtoms[g_waAtomRealElement[m_laAccep->GetAt(z)]])->m_sName,g_waAtomMolNumber[m_laAccep->GetAt(z)]+1); } for (z=0;zGetSize();z++) { for (z2=z+1;z2GetSize();z2++) { if (m_laAccep->GetAt(z) == m_laAccep->GetAt(z2)) { eprintf("\nError: Acceptor atom %s[%d] %s%d is listed more than one time!\n",((CMolecule*)g_oaMolecules[g_waAtomMolIndex[m_laAccep->GetAt(z)]])->m_sName,g_laAtomSMLocalIndex[m_laAccep->GetAt(z)]+1,(const char*)((CAtom*)g_oaAtoms[g_waAtomRealElement[m_laAccep->GetAt(z)]])->m_sName,g_waAtomMolNumber[m_laAccep->GetAt(z)]+1); abort(); } } } mprintf("\n\n"); BuildHydroArray(); m_bLuzar = AskYesNo(" Analyse bond per donor-acceptor pair (y) or bond per hydrogen atom (n)? [no] ",false); if ( !m_bLuzar ) { BuildDonorArray(); if ( m_laHydro->GetSize() != m_laDonor->GetSize() ) { eprintf("Number of hydrogens is not equal number of donor atoms. Something is wrong. Aborting ...\n"); abort(); } } else { eprintf("Sorry! The \"donor-acceptor pair\" mode is currently not working properly. Aborting ...\n"); abort(); } m_frAD = 0; m_frAH = 0; m_fwinkel = 0; m_bHysteresis = AskYesNo(" Use hysteresis for the hydrogen bond criterion (y/n)? [no]", false); while(m_frAD == 0 || m_frAH == 0) { m_frAH = AskFloat(" Maximum distance between hydrogen atom and accepting atom for bond formation in pm? [245] ",245.0); if ( m_bHysteresis ) { m_frAH_out = AskFloat(" Maximum distance between hydrogen atom and accepting atom for bond breaking in pm? [%f] ",m_frAH,m_frAH); } else { m_frAH_out = m_frAH; } m_frAD = AskFloat(" Maximum distance between donating atom and accepting atom for bond formation in pm? [%d] ",int(m_frAH + 105),int(m_frAH + 105)); if ( m_bHysteresis ) { m_frAD_out = AskFloat(" Maximum distance between donating atom and accepting atom for bond formation in pm? [%f] ",m_frAD,m_frAD); } else { m_frAD_out = m_frAD; } if(m_frAD < m_frAH) { if(!AskYesNo(" The distance between acceptor and donor is smaller than the distance between acceptor and hydrogen. This is very unusual. Keep the values anyway (y/n)? [yes] ",true)) { m_frAD = 0; m_frAH = 0; } } } while( m_fwinkel == 0 ) { m_fwinkel = cos((M_PI/180)*AskRangeFloat(" Maximum angle between donor-acceptor and donor-hydrogen for bond formation? [30] ", 0.0, 180.0, 30.0)); if ( m_bHysteresis ) { m_fwinkel_out = cos((M_PI/180)*AskRangeFloat(" Maximum angle between donor-acceptor and donor-hydrogen for bond breaking? [%f] ", 0.0, 180.0, acos(m_fwinkel) * 180 / M_PI, acos(m_fwinkel) * 180 / M_PI)); } else { m_fwinkel_out = m_fwinkel; } } g_fTimestepLength = AskFloat(" Enter the length of one trajectory time step in fs: [0.5] ",0.5f); } CHBondObservation::~CHBondObservation() { } void CHBondObservation::initialize() { int n,m,m_start = 0; try { m_laLastNeigh = new CxIntArray(); } catch(...) { m_laLastNeigh = NULL; } if (m_laLastNeigh == NULL) NewException((double)sizeof(CxIntArray),__FILE__,__LINE__,__PRETTY_FUNCTION__); try { m_laLastBond = new CxIntArray(); } catch(...) { m_laLastBond = NULL; } if (m_laLastBond == NULL) NewException((double)sizeof(CxIntArray),__FILE__,__LINE__,__PRETTY_FUNCTION__); try { m_oaNeigh = new CxObArray(); } catch(...) { m_oaNeigh = NULL; } if (m_oaNeigh == NULL) NewException((double)sizeof(CxObArray),__FILE__,__LINE__,__PRETTY_FUNCTION__); try { m_oaBond = new CxObArray(); } catch(...) { m_oaBond = NULL; } if (m_oaBond == NULL) NewException((double)sizeof(CxObArray),__FILE__,__LINE__,__PRETTY_FUNCTION__); try { m_oaPartners = new CxObArray(); } catch(...) { m_oaPartners = NULL; } if (m_oaPartners == NULL) NewException((double)sizeof(CxObArray),__FILE__,__LINE__,__PRETTY_FUNCTION__); if ( g_iMaxStep != -1 ) m_iDepth = g_iMaxStep * 3 / 4 / g_iStride; else m_iDepth = g_iTrajSteps * 3 / 4 / g_iStride; m_iDepth = AskUnsignedInteger(" Enter the resolution (=depth) of the ACF (in time steps): [%d] ", m_iDepth, m_iDepth); if ( m_iDepth > g_iTrajSteps ) { mprintf(" Correlation Depth is exceeding number of total timesteps. Truncating ....\n"); m_iDepth = g_iTrajSteps; } m_iTrunc = m_iDepth; while ( m_iTrunc > (int)(m_iDepth/10) ) { m_iTrunc = (int)(50000/(g_fTimestepLength*g_iStride)); if ( m_iTrunc > m_iDepth/10 ) m_iTrunc = (int)(m_iDepth/10); m_iTrunc = AskUnsignedInteger(" Enter the truncation for the fitting procedure (in time steps): [%d] ", m_iTrunc, m_iTrunc); if ( m_iTrunc > m_iDepth/10 ) mprintf(" Truncation must be at least 10 times smaller than correlation depth!\n"); } if ( !m_bLuzar ) // dynamics of hydrogen bonds { for ( n=0; n < m_laAccep->GetSize(); n++) { for (m=0; m < m_laDonor->GetSize(); m++) { if ( m_laDonor->GetAt(m) != m_laAccep->GetAt(n) ) // Donor could be Accep ... processing would not make any sense ... { CxIntArray* IncludeME; CxIntArray* IncludeME2; try { IncludeME = new CxIntArray(); } catch(...) { IncludeME = NULL; } if (IncludeME == NULL) NewException((double)sizeof(CxIntArray),__FILE__,__LINE__,__PRETTY_FUNCTION__); try { IncludeME2 = new CxIntArray(); } catch(...) { IncludeME2 = NULL; } if (IncludeME2 == NULL) NewException((double)sizeof(CxIntArray),__FILE__,__LINE__,__PRETTY_FUNCTION__); m_laLastNeigh->Add(0); m_laLastBond->Add(0); m_oaNeigh->Add(IncludeME); m_oaBond->Add(IncludeME2); } } } } else // dynamics of hydrogen bonded molecules { if ( m_laAccep->Contains(m_laDonor->GetAt(0)) ) // Donor and Acceptor same atomtype? { m_bSameAtom = true; } else { m_bSameAtom = false; } for ( n=0; n < m_laAccep->GetSize(); n++ ) { if ( m_bSameAtom ) { m_start = n + 1; // If same atomtype: No doubles! } for ( m = m_start; m < m_laDonor->GetSize(); m++ ) { CxIntArray* IncludeME; CxIntArray* IncludeME2; CxIntArray* IncludeME3; try { IncludeME = new CxIntArray(); } catch(...) { IncludeME = NULL; } if (IncludeME == NULL) NewException((double)sizeof(CxIntArray),__FILE__,__LINE__,__PRETTY_FUNCTION__); try { IncludeME2 = new CxIntArray(); } catch(...) { IncludeME2 = NULL; } if (IncludeME2 == NULL) NewException((double)sizeof(CxIntArray),__FILE__,__LINE__,__PRETTY_FUNCTION__); try { IncludeME3 = new CxIntArray(); } catch(...) { IncludeME3 = NULL; } if (IncludeME3 == NULL) NewException((double)sizeof(CxIntArray),__FILE__,__LINE__,__PRETTY_FUNCTION__); m_laLastNeigh->Add(0); m_laLastBond->Add(0); m_oaNeigh->Add(IncludeME); m_oaBond->Add(IncludeME2); FindHydro(IncludeME3,m_laAccep->GetAt(n)); FindHydro(IncludeME3,m_laDonor->GetAt(m)); m_oaPartners->Add(IncludeME3); } } } } void CHBondObservation::FindHydro(CxIntArray* IncludeME3, int donor) { int m,i,j; for (m=0; m < ((CMolecule*)g_oaMolecules[m_iShowMol])->m_laSingleMolIndex.GetSize(); m++) // Walk over all SingleMolecules { for (i=0; i < ((CSingleMolecule*)g_oaSingleMolecules[((CMolecule*)g_oaMolecules[m_iShowMol])->m_laSingleMolIndex.GetAt(m)])->m_oaMolAtoms.GetSize(); i++) // Walk over all Atoms in Molecule { if ( ((CMolAtom*)((CSingleMolecule*)g_oaSingleMolecules[((CMolecule*)g_oaMolecules[m_iShowMol])->m_laSingleMolIndex.GetAt(m)])->m_oaMolAtoms[i])->m_iOffset == donor ) // Search Atom { for (j=0; j < ((CMolAtom*)((CSingleMolecule*)g_oaSingleMolecules[((CMolecule*)g_oaMolecules[m_iShowMol])->m_laSingleMolIndex.GetAt(m)])->m_oaMolAtoms[i])->m_oaBonds.GetSize(); j++) // Walk over all bondpartners { if ( ((CAtom*)g_oaAtoms[((CMolAtom*)((CMolAtom*)((CSingleMolecule*)g_oaSingleMolecules[((CMolecule*)g_oaMolecules[m_iShowMol])->m_laSingleMolIndex.GetAt(m)])->m_oaMolAtoms[i])->m_oaBonds[j])->m_iType])->m_pElement->m_iOrd == 1 ) { IncludeME3->Add(((CMolAtom*)((CMolAtom*)((CSingleMolecule*)g_oaSingleMolecules[((CMolecule*)g_oaMolecules[m_iShowMol])->m_laSingleMolIndex.GetAt(m)])->m_oaMolAtoms[i])->m_oaBonds[j])->m_iOffset); } } m = ((CMolecule*)g_oaMolecules[m_iShowMol])->m_laSingleMolIndex.GetSize(); break; } } } } void CHBondObservation::process(CTimeStep* ts) { int n,m,k,i=0,m_start=0; if ( !m_bLuzar ) // Dynamics of hydrogen bonds: Check for all combinations if conditions are fulfilled { for (n=0; n < m_laAccep->GetSize(); n++) { for (m=0; m < m_laDonor->GetSize(); m++) { if ( m_laDonor->GetAt(m) != m_laAccep->GetAt(n) ) // Donor could be Accep ... processing would not make any sense ... { if ( checkCOND(ts->m_vaCoords[m_laAccep->GetAt(n)], ts->m_vaCoords[m_laHydro->GetAt(m)], ts->m_vaCoords[m_laDonor->GetAt(m)], i) ) { mprintf(RED,"Something is wrong ... aborting ..."); abort(); } i++; } } } } else // Dynamics of hydrogen bonded molecules: Check every pair only once { for ( n=0; n < m_laAccep->GetSize(); n++ ) { if ( m_bSameAtom ) { m_start = n + 1; // If same atomtype: No doubles! } for ( m = m_start; m < m_laDonor->GetSize(); m++ ) { for ( k=0; k < ((CxIntArray*)m_oaPartners->GetAt(i))->GetSize(); k++ ) // Check condition for every possible hydrogenatom { if ( checkCOND(ts->m_vaCoords[m_laAccep->GetAt(n)], ts->m_vaCoords[((CxIntArray*)m_oaPartners->GetAt(i))->GetAt(k)], ts->m_vaCoords[m_laDonor->GetAt(m)], i) ) { if ( k == (((CxIntArray*)m_oaPartners->GetAt(i))->GetSize()-1) ) { m_laLastBond->SetAt(i,0); // Kein H-Bond ((CxIntArray*)m_oaBond->GetAt(i))->Add(g_iSteps); } continue; } if ( m_laLastNeigh->GetAt(i) == 0 || m_laLastBond->GetAt(i) == 1 ) // No Neighbor or hbond fulfilled { break; } } i++; } } } } void CHBondObservation::finalize() // reconstruct functions -> autocorrelate -> sum results -> normalize -> fit { long n,i,interval; double BondCor, DiffCor; CxString buf,buf2; unsigned long t0,eta; CxDoubleArray* NeighFunction; // Input CxDoubleArray* BondFunction; CxDoubleArray* temp1Function; // Temp CxDoubleArray* temp2Function; CLuzarCorrelation* luzar; try { BondFunction = new CxDoubleArray(); } catch(...) { BondFunction = NULL; } if (BondFunction == NULL) NewException((double)sizeof(CxDoubleArray),__FILE__,__LINE__,__PRETTY_FUNCTION__); try { NeighFunction = new CxDoubleArray(); } catch(...) { NeighFunction = NULL; } if (NeighFunction == NULL) NewException((double)sizeof(CxDoubleArray),__FILE__,__LINE__,__PRETTY_FUNCTION__); try { BondDynamic = new CxDoubleArray(); } catch(...) { BondDynamic = NULL; } if (BondDynamic == NULL) NewException((double)sizeof(CxDoubleArray),__FILE__,__LINE__,__PRETTY_FUNCTION__); try { DiffusionDynamic = new CxDoubleArray(); } catch(...) { DiffusionDynamic = NULL; } if (DiffusionDynamic == NULL) NewException((double)sizeof(CxDoubleArray),__FILE__,__LINE__,__PRETTY_FUNCTION__); try { k_t = new CxDoubleArray(); } catch(...) { k_t = NULL; } if (k_t == NULL) NewException((double)sizeof(CxDoubleArray),__FILE__,__LINE__,__PRETTY_FUNCTION__); try { a = new CxDoubleArray(); } catch(...) { a = NULL; } if (a == NULL) NewException((double)sizeof(CxDoubleArray),__FILE__,__LINE__,__PRETTY_FUNCTION__); try { b = new CxDoubleArray(); } catch(...) { b = NULL; } if (b == NULL) NewException((double)sizeof(CxDoubleArray),__FILE__,__LINE__,__PRETTY_FUNCTION__); try { temp1Function = new CxDoubleArray(); } catch(...) { temp1Function = NULL; } if (temp1Function == NULL) NewException((double)sizeof(CxDoubleArray),__FILE__,__LINE__,__PRETTY_FUNCTION__); try { temp2Function = new CxDoubleArray(); } catch(...) { temp2Function = NULL; } if (temp2Function == NULL) NewException((double)sizeof(CxDoubleArray),__FILE__,__LINE__,__PRETTY_FUNCTION__); for ( i=0; i < m_iDepth; i++ ) { BondDynamic->Add(0.0); DiffusionDynamic->Add(0.0); } try { luzar = new CLuzarCorrelation(); } catch(...) { luzar = NULL; } if (luzar == NULL) NewException((double)sizeof(CLuzarCorrelation),__FILE__,__LINE__,__PRETTY_FUNCTION__); NeighFunction->SetSize(g_iSteps / g_iStride); BondFunction->SetSize(g_iSteps / g_iStride); luzar->Init(g_iSteps / g_iStride,m_iDepth); // Inititalize Luzar-Correlation mprintf(" Finishing %6i Functions ... \nFunc %6li ",m_laLastNeigh->GetSize(),(long)0); g_iDotCounter = 0; t0 = (unsigned long)time(NULL); interval = 2; for ( n=0; n < m_laLastNeigh->GetSize(); n++) // Walk over all pairs { if ( n % interval == 0 ) { if ( g_iDotCounter >= 50 ) { if ( interval == 2 && n > 100 ) { interval = 20; } else if ( interval == 20 && n > 2000 ) { interval = 200; } g_iDotCounter = 0; if ((time(NULL) - t0) > 5) { eta = (unsigned long)(((double)time(NULL) - t0) / n * ((double)MAX((long)0,(long)m_laLastNeigh->GetSize() - (long)n))); FormatTime(eta,&buf); mprintf(" ETA %s",(const char*)buf); } mprintf("\nFunc %6li ",n); } g_iDotCounter++; mprintf("."); } if ( ((CxIntArray*)m_oaNeigh->GetAt(n))->GetSize() > 0 ) { RestoreFunction(((CxIntArray*)m_oaNeigh->GetAt(n)),((CxDoubleArray*)NeighFunction)); // Restore function of pair n as NeighFunction and BondFunction RestoreFunction(((CxIntArray*)m_oaBond->GetAt(n)),((CxDoubleArray*)BondFunction)); luzar->Correlate(BondFunction,NeighFunction,temp1Function,temp2Function); for ( i=0; i < m_iDepth; i++ ) // Sum results to Output-array { (*BondDynamic)[i] += (*temp1Function)[i]; (*DiffusionDynamic)[i] += (*temp2Function)[i]; } } } mprintf("\n\n"); if ( (*BondDynamic)[0] == 0 || (*DiffusionDynamic)[0] == 0 ) { eprintf("First correlation value is zero ... something is wrong ...\n"); abort(); } BondCor = (double)(*BondDynamic)[0]; DiffCor = (double)(*DiffusionDynamic)[0]; for ( i=0; i < m_iDepth; i++ ) // Normalize { (*BondDynamic)[i] /= BondCor; (*DiffusionDynamic)[i] /= DiffCor; (*DiffusionDynamic)[i] -= (*BondDynamic)[i]; } luzar->Fit(BondDynamic, DiffusionDynamic, k_t, a, b, m_iTrunc); WriteOutput(); } void CHBondObservation::RestoreFunction(CxIntArray* input, CxDoubleArray* output) { unsigned int n; bool eins = false; for ( n=0; n < (g_iSteps / g_iStride); n++ ) // Walk over all processed steps { if ( input->Contains((n+1)*g_iStride) ) { eins = !eins; } if (!eins) { output->SetAt(n,0.0); } else { output->SetAt(n,1.0); } } } bool CHBondObservation::includeAtom(int atom, int number, int mol, CxIntArray* target) // atom: element number, number: atomsort number, mol m_iShowMol, target: in which array to include { CxIntArray includeME; for ( int n = 0; n < ((CMolecule*)g_oaMolecules[mol])->m_laSingleMolIndex.GetSize(); n++) { includeME.CopyFrom((CxIntArray*)(((CSingleMolecule*)g_oaSingleMolecules[((CMolecule*)g_oaMolecules[mol])->m_laSingleMolIndex[n]])->m_oaAtomOffset[atom])); if (number >= includeME.GetSize()) { eprintf("CHBondObservation::includeAtom(): Internal error (%d/%d).\n",number,includeME.GetSize()); abort(); } target->Add(includeME[number]); } return true; } bool CHBondObservation::checkAtomChoice(CMolecule *mol, const char *s, CxIntArray* m_laInclude) { const char *p, *q; char buf[32]; const char *allowed = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890,-#_ "; int inclu, la = -1, i = -1, i2 = -1, atom = -1; bool m = false, fin = false; p = s; while (*p != 0) { fin = false; while (*p == ' ') p++; if (strchr(allowed,*p) == NULL) { eprintf("Error: Character \"%c\" not allowed.\n",*p); return false; } q = p; if (*q == '#' || *q == '*') { eprintf("No virtual atoms allowed!"); return false; } if (isalpha(*q)) { if (m) { eprintf("Error: Only digit allowed after \"-\".\n"); return false; } while (isalpha(*q)) q++; if (q-p >= 32) { eprintf("Internal Error (%ld >= 32).\n",q-p); return false; } memcpy(buf,p,q-p); buf[q-p] = 0; atom = mol->FindAtomInMol(buf); // atom holds number of element if (atom == -1) { eprintf("Error: Atom \"%s\" not in the molecule.\n",buf); return false; } } else if (isdigit(*q)) { if (atom == -1) atom = la; if (atom == -1) { eprintf("Error: Number in the beginning not possible.\n"); return false; } while (isdigit(*q)) q++; if ((*q != '-') && (*q != ',') && (*q != ' ') && (*q != 0)) { eprintf("Error: Only \",\" or \"-\" may follow after a number.\n"); return false; } if (q-p >= 32) { eprintf("Internal Error (%ld >= 32).\n",q-p); return false; } memcpy(buf,p,q-p); buf[q-p] = 0; if (atoi(buf)-1 >= mol->m_waAtomCount[atom]) { eprintf("Error: Only %d %s atoms in the molecule (requested: %d)\n",mol->m_waAtomCount[atom],(const char*)((CAtom*)g_oaAtoms[mol->m_baAtomIndex[atom]])->m_sName,atoi(buf)); return false; } if (m) // Range: Include all atoms from i to i2 case: X1-3 A { i2 = atoi(buf)-1; if (i2 < i) // If range from high to low -> wrong input { eprintf("Error: Invalid atom range, %d < %d.\n",i2+1,i+1); return false; } else { //>>>MB170422 //for (inclu = i; inclu < i2; inclu++) for (inclu = i; inclu <= i2; inclu++) //<<m_iIndex, m_laInclude); //hier } fin = true; } } else { i = atoi(buf)-1; } } else if (*q == '-') { if (i == -1) { eprintf("Error: \"-\" without preceding number.\n"); return false; } m = true; q++; } else if (*q == ',') { if (atom == -1) { eprintf("Error: Comma without atom.\n"); return false; } if ( i == -1 ) // include all atoms of kind case: X, C { for (inclu = 0; inclu < mol->m_waAtomCount[atom]; inclu++ ) { includeAtom(atom, inclu, mol->m_iIndex, m_laInclude); //hier } } else if (!m) // include single atom case: X1, B { includeAtom(atom, i, mol->m_iIndex, m_laInclude); // hier } la = atom; m = false; i = -1; i2 = -1; atom = -1; q++; fin = true; } p = q; } if ( !fin ) { if ( i == -1 ) // case: X { for (inclu = 0; inclu < mol->m_waAtomCount[atom]; inclu++ ) { includeAtom(atom, inclu, mol->m_iIndex, m_laInclude); //hier } } else // case: X1 { includeAtom(atom, i, mol->m_iIndex, m_laInclude); // hier } } return true; } void CHBondObservation::BuildDonorArray() { int n,m,i; m_laDonor->RemoveAll(); for (n=0; n < m_laHydro->GetSize();n++) // Walk over all hydrogens { for (m=0; m < ((CMolecule*)g_oaMolecules[m_iShowMol])->m_laSingleMolIndex.GetSize(); m++) // Walk over all SingleMolecules { for (i=0; i < ((CSingleMolecule*)g_oaSingleMolecules[((CMolecule*)g_oaMolecules[m_iShowMol])->m_laSingleMolIndex.GetAt(m)])->m_oaMolAtoms.GetSize(); i++) // Walk over all Atoms in Molecule { if ( ((CMolAtom*)((CSingleMolecule*)g_oaSingleMolecules[((CMolecule*)g_oaMolecules[m_iShowMol])->m_laSingleMolIndex.GetAt(m)])->m_oaMolAtoms[i])->m_iOffset == m_laHydro->GetAt(n) ) // Search Atom { if ( ((CMolAtom*)((CSingleMolecule*)g_oaSingleMolecules[((CMolecule*)g_oaMolecules[m_iShowMol])->m_laSingleMolIndex.GetAt(m)])->m_oaMolAtoms[i])->m_oaBonds.GetSize() > 1 ) { eprintf("Something is wrong: Hydrogen has more than one bond! Aborting ...\n"); abort(); } m_laDonor->Add(((CMolAtom*)((CMolAtom*)((CSingleMolecule*)g_oaSingleMolecules[((CMolecule*)g_oaMolecules[m_iShowMol])->m_laSingleMolIndex.GetAt(m)])->m_oaMolAtoms[i])->m_oaBonds[0])->m_iOffset); m = ((CMolecule*)g_oaMolecules[m_iShowMol])->m_laSingleMolIndex.GetSize(); break; } } } } } void CHBondObservation::BuildHydroArray() { int n,m,i,j; bool tb; CMolecule *mol; CSingleMolecule *sm; CMolAtom *ma; mol = (CMolecule*)g_oaMolecules[m_iShowMol]; for (n=0; n < m_laDonor->GetSize();n++) // Walk over all donors { tb = false; for (m=0; m < mol->m_laSingleMolIndex.GetSize(); m++) // Walk over all SingleMolecules { sm = (CSingleMolecule*)g_oaSingleMolecules[mol->m_laSingleMolIndex[m]]; for (i=0; i < sm->m_oaMolAtoms.GetSize(); i++) // Walk over all Atoms in Molecule { ma = (CMolAtom*)sm->m_oaMolAtoms[i]; if ( ma->m_iOffset == m_laDonor->GetAt(n) ) // Search Atom { for (j=0; j < ma->m_oaBonds.GetSize(); j++) // Walk over all bondpartners { if ( ((CAtom*)g_oaAtoms[mol->m_baAtomIndex[((CMolAtom*)ma->m_oaBonds[j])->m_iType]])->m_pElement->m_iOrd == 1 ) { m_laHydro->Add(((CMolAtom*)ma->m_oaBonds[j])->m_iOffset); tb = true; } } if (!tb) { mprintf("Warning: Did not find hydrogen atoms on donor atom %s%d[%d].\n",(const char*)((CAtom*)g_oaAtoms[mol->m_baAtomIndex[ma->m_iType]])->m_sName,g_waAtomMolNumber[((CMolAtom*)((CSingleMolecule*)g_oaSingleMolecules[m])->m_oaMolAtoms[i])->m_iOffset]+1,m+1); } m = ((CMolecule*)g_oaMolecules[m_iShowMol])->m_laSingleMolIndex.GetSize(); break; } } } } mprintf(" BuildHydroArray(): Found %d hydrogen atoms on %d donor atoms.\n\n",m_laHydro->GetSize(),m_laDonor->GetSize()); if ((m_laHydro->GetSize() == 0) && (m_laDonor->GetSize() != 0)) { mprintf("\n"); mprintf(" Probably you entered the hydrogen atoms as donor atoms. Instead, you have to\n"); mprintf(" enter the bond partners of the hydrogen atoms as donor atoms (see note above).\n"); mprintf(" Aborting execution.\n\n"); abort(); } } bool CHBondObservation::checkCOND(CxDVector3 m_vAccep, CxDVector3 m_vHydro, CxDVector3 m_vDonor, int i) { CxDVector3 m_vrAD, m_vrAH, m_vrHD; double rAD, rAH, rHD, winkel; double rAD_crit, rAH_crit, winkel_crit; m_vrAD = m_vAccep - m_vDonor; m_vrAD = FoldVector(m_vrAD); rAD = m_vrAD.GetLength(); if ( m_bHysteresis && m_laLastNeigh->GetAt(i) == 1 ) // pair is neighbor -> out_crit if hysteresis { rAD_crit = m_frAD_out; } else { rAD_crit = m_frAD; } if ( m_bHysteresis && m_laLastBond->GetAt(i) == 1 ) // pair is hbonded -> out_crit if hysteresis { rAH_crit = m_frAH_out; winkel_crit = m_fwinkel_out; } else { rAH_crit = m_frAH; winkel_crit = m_fwinkel; } if ( rAD < rAD_crit ) // distance acceptor-donor smaller reference? { if ( m_laLastNeigh->GetAt(i) == 0 ) { m_laLastNeigh->SetAt(i,1); // Nachbar ((CxIntArray*)m_oaNeigh->GetAt(i))->Add(g_iSteps); } m_vrHD = m_vDonor - m_vHydro; m_vrHD = FoldVector(m_vrHD); rHD = m_vrHD.GetLength(); m_vrAH = m_vAccep - m_vHydro; m_vrAH = FoldVector(m_vrAH); rAH = m_vrAH.GetLength(); if ( rAH < rHD ) // "acceptor" is in actually donor { winkel = (rAD*rAD + rAH*rAH - rHD*rHD) / (2 * rAD * rAH); } else // "donor" is de facto donor { winkel = (rAD*rAD + rHD*rHD - rAH*rAH) / (2 * rAD * rHD); } if ( rAH < rAH_crit && rHD < rAH_crit ) // distance acceptor-hydrogen smaller reference? Additional: distance donor-hydrogen smaller (for LUZAR) { if ( winkel > winkel_crit ) // cos(winkel) bigger than reference (or in other words: angle smaller?) { if ( m_laLastBond->GetAt(i) == 0 ) { m_laLastBond->SetAt(i,1); // H-Bond ((CxIntArray*)m_oaBond->GetAt(i))->Add(g_iSteps); } return false; } } if ( m_laLastBond->GetAt(i) == 1 ) { if ( m_bLuzar ) { return true; } m_laLastBond->SetAt(i,0); // Kein H-Bond ((CxIntArray*)m_oaBond->GetAt(i))->Add(g_iSteps); } return false; } else { if ( m_laLastNeigh->GetAt(i) == 1 ) { m_laLastNeigh->SetAt(i,0); // Kein Nachbar ((CxIntArray*)m_oaNeigh->GetAt(i))->Add(g_iSteps); } if ( m_laLastBond->GetAt(i) == 1 ) { m_laLastBond->SetAt(i,0); // Kein H-Bond ... geht nicht, wenn kein Nachbar ... echt nicht .... geht gar nicht ... ((CxIntArray*)m_oaBond->GetAt(i))->Add(g_iSteps); } return false; } return true; // This point should never be reached ... it's not a nice point ... } void CHBondObservation::WriteOutput() { CGrace* gc; int n,m; mprintf(" Writing \"Correlations.agr\"...\n"); try { gc = new CGrace(); } catch(...) { gc = NULL; } if (gc == NULL) NewException((double)sizeof(CGrace),__FILE__,__LINE__,__PRETTY_FUNCTION__); gc->SetRangeX(0,m_iDepth*g_iStride*g_fTimestepLength/1000); gc->SetRangeY(0,1); gc->MakeTicks(); gc->SetLabelX("tau [ps]"); gc->SetLabelY("f(tau)"); gc->CurrentGraph()->m_bInvertXAxis = false; gc->CurrentGraph()->m_bLegend = true; gc->AddDataset(); gc->SetDatasetName(0, "c(t)"); gc->AddDataset(); gc->SetDatasetName(1, "n(t)"); for ( n = 0; n < BondDynamic->GetSize(); n++) { gc->AddXYTupel(0,n*g_fTimestepLength*g_iStride/1000,BondDynamic->GetAt(n)); gc->AddXYTupel(1,n*g_fTimestepLength*g_iStride/1000,DiffusionDynamic->GetAt(n)); } gc->WriteAgr("Correlations.agr",false); gc->WriteCSV("Correlations.csv"); delete gc; mprintf(" Writing \"Fitted.agr\"...\n"); CalcMinMax(); try { gc = new CGrace(); } catch(...) { gc = NULL; } if (gc == NULL) NewException((double)sizeof(CGrace),__FILE__,__LINE__,__PRETTY_FUNCTION__); gc->SetRangeX(0,m_dGraceMax); gc->SetRangeY(0,m_dGraceMax); gc->MakeTicks(); gc->SetLabelX("kf c(t) - kb n(t) [1/ps]"); gc->SetLabelY("-dc/dt [1/ps]"); gc->CurrentGraph()->m_bInvertXAxis = false; gc->CurrentGraph()->m_bLegend = true; gc->AddDataset(); gc->SetDatasetName(0, "Data"); for ( m=0; m < k_t->GetSize(); m++) gc->AddXYTupel(0,(*a)[0] * (*BondDynamic)[m] - (*b)[0] * (*DiffusionDynamic)[m], -(*k_t)[m]); gc->WriteCSV("Fitted.csv"); gc->AddDataset(); gc->SetDatasetName(1, "Unity"); gc->AddXYTupel(1,0,0); gc->AddXYTupel(1,m_dGraceMax,m_dGraceMax); gc->WriteAgr("Fitted.agr",false); delete gc; } void CHBondObservation::CalcMinMax() { double temp; int n; m_dGraceMin = 1E20; m_dGraceMax = -1E20; for ( n = m_iTrunc / 5; n < BondDynamic->GetSize(); n++) { temp = ((*a)[0] * (*BondDynamic)[n] - (*b)[0] * (*DiffusionDynamic)[n]); if ( m_dGraceMin >= temp ) m_dGraceMin = temp; if ( m_dGraceMax <= temp ) m_dGraceMax = temp; } for ( n = m_iTrunc / 5; n < k_t->GetSize(); n++) { temp = -k_t->GetAt(n); if ( m_dGraceMin >= temp ) m_dGraceMin = temp; if ( m_dGraceMax <= temp ) m_dGraceMax = temp; } } travis-src-190101/src/hbond.h0100777000000000000000000000534213412725670012707 0ustar00/***************************************************************************** TRAVIS - Trajectory Analyzer and Visualizer http://www.travis-analyzer.de/ Copyright (c) 2009-2019 Martin Brehm 2012-2019 Martin Thomas 2016-2019 Sascha Gehrke This file was written by Sascha Gehrke. --------------------------------------------------------------------------- This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . *****************************************************************************/ #ifndef HBOND_H #define HBOND_H // This must always be the first include directive #include "config.h" #include "moltools.h" bool gatherHBond(); bool initializeHBond(); bool processHBond(CTimeStep* ts); bool finalizeHBond(); class CHBondObservation: public CObservation { public: CHBondObservation(); ~CHBondObservation(); CxIntArray *m_laAccep; // Enthaelt m_iOffset fuer jedes Acceptoratom CxIntArray *m_laHydro; // " Wasserstoffatom CxIntArray *m_laDonor; // " Donoratom CxObArray *m_oaNeigh; CxObArray *m_oaBond; CxObArray *m_oaPartners; // Contains relevant hydrogens for each pair CxIntArray *m_laLastNeigh; // Contains the last states CxIntArray *m_laLastBond; // Contains the last states CxDoubleArray* BondDynamic; // Final Datasets after processing CxDoubleArray* DiffusionDynamic; CxDoubleArray* k_t; // Numerical derivation of BondDynamic CxDoubleArray* a; CxDoubleArray* b; bool m_bSameAtom; bool m_bLuzar; bool m_bHysteresis; int m_iDepth, m_iTrunc; double m_frAD, m_frAH, m_fwinkel; double m_frAD_out, m_frAH_out, m_fwinkel_out; double m_dGraceMin, m_dGraceMax; void initialize(); void process(CTimeStep* ts); void finalize(); bool checkCOND(CxDVector3,CxDVector3,CxDVector3,int); bool checkAtomChoice(CMolecule*, const char*, CxIntArray*); bool includeAtom(int, int, int, CxIntArray*); void BuildDonorArray(); void BuildHydroArray(); void FindHydro(CxIntArray*, int); void RestoreFunction(CxIntArray*, CxDoubleArray*); // void CheckBoundary(CxDVector3*); void CalcMinMax(); void WriteOutput(); private: }; #endif travis-src-190101/src/interface.cpp0100777000000000000000000001677613412725617014126 0ustar00/***************************************************************************** TRAVIS - Trajectory Analyzer and Visualizer http://www.travis-analyzer.de/ Copyright (c) 2009-2019 Martin Brehm 2012-2019 Martin Thomas 2016-2019 Sascha Gehrke This file was written by Martin Brehm and Martin Thomas. --------------------------------------------------------------------------- This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . *****************************************************************************/ // This must always be the first include directive #include "config.h" #include "interface.h" #include "chiral.h" #include "fdf.h" #include "ir.h" #include "normalcoordinate.h" #include "normalmode.h" #include "pdf.h" #include "raman.h" #include "region.h" #include "structurefactor.h" #include "hbond.h" #include "ionpair.h" const char *GetRevisionInfo_interface(unsigned int len) { static char buf[256]; GET_REVISION_INFO( buf, len ); return buf; } const char *GetSourceVersion_interface() { static char buf[256]; GET_SOURCE_VERSION( buf ); return buf; } void Interface_DefaultConf() { /* g_pDatabase->AddString("/BLA/BLUBB/PLOEPP/STRING1","String 1 Content"); g_pDatabase->AddInt("/BLA/BLUBB/PLOEPP/INT1",123456); g_pDatabase->AddFloat("/BLA/BLUBB/PLOEPP/FLOAT1",1.23456); g_pDatabase->AddBool("/BLA/BLUBB/PLOEPP/BOOL1",true);*/ } bool Interface_BeforeAnalysis() { if(g_bRegionAnalysis) if(!gatherRegionAnalysis()) return false; if(g_bRaman) if(!gatherRaman()) return false; if(g_bPDF) if(!gatherPDF()) return false; if(g_bNormalCoordinate) if(!gatherNormalCoordinate()) return false; if(g_bSFac) if(!gatherStructureFactor()) return false; if(g_bChiral) if(!gatherChiral()) return false; if(g_bSortWannier) if(!gatherSortWannier()) return false; if(g_bEckartTransform) if(!gatherEckartTransform()) return false; if(g_bPower || g_bVACFNew) if(!gatherPowerSpectrum()) return false; if(g_bIR) if(!gatherIR()) return false; if(g_bVCD) if(!gatherVCD()) return false; if (g_bDipoleRestart) if (!gatherDipoleRestart()) return false; if (g_bMagneticDipoleRestart) if (!gatherMagneticDipoleRestart()) return false; if (g_bSetUpPolarizabilityCalc) if (!gatherPolarizabilityCalc()) return false; if (g_bFDF) if (!gatherFDF()) return false; if (g_bHBond) if (!gatherHBond()) return false; if (g_bIonPair) if (!gatherIonPair()) return false; return true; } bool Interface_BeforeAnalysis2() { return true; } bool Interface_Initialization() { if(g_bRaman) if(!initializeRaman()) return false; if(g_bPDF) if(!initializePDF()) return false; if(g_bNormalCoordinate) if(!initializeNormalCoordinate()) return false; if(g_bSFac) if(!initializeStructureFactor()) return false; if(g_bChiral) if(!initializeChiral()) return false; if(g_bSortWannier) if(!initializeSortWannier()) return false; if(g_bEckartTransform) if(!initializeEckartTransform()) return false; if(g_bPower || g_bVACFNew) if(!initializePowerSpectrum()) return false; if(g_bIR) if(!initializeIR()) return false; if(g_bVCD) if(!initializeVCD()) return false; if (g_bDipoleRestart) if (!initializeDipoleRestart()) return false; if (g_bMagneticDipoleRestart) if (!initializeMagneticDipoleRestart()) return false; if (g_bSetUpPolarizabilityCalc) if (!initializePolarizabilityCalc()) return false; if (g_bCubeTimeDev) g_fPDESolverInfoFile = OpenFileWrite("pdesolver_info", false); if (g_bFDF) if (!initializeFDF()) return false; if (g_bHBond) if (!initializeHBond()) return false; if (g_bIonPair) if (!initializeIonPair()) return false; return true; } void Interface_ProcessStep(CTimeStep *ts) { if(g_bRegionAnalysis) processRegionAnalysis(ts); if(g_bRaman) processRaman(ts); if(g_bPDF) processPDF(ts); if(g_bNormalCoordinate) processNormalCoordinate(ts); if(g_bSFac) processStructureFactor(ts); if(g_bChiral) processChiral(ts); if(g_bSortWannier) processSortWannier(ts); if(g_bEckartTransform) processEckartTransform(ts); if(g_bPower || g_bVACFNew) processPowerSpectrum(ts); if(g_bIR) processIR(ts); if(g_bVCD) processVCD(ts); if (g_bDipoleRestart) processDipoleRestart(ts); if (g_bMagneticDipoleRestart) processMagneticDipoleRestart(ts); if (g_bSetUpPolarizabilityCalc) processPolarizabilityCalc(ts); if (g_bFDF) processFDF(ts); if (g_bHBond) processHBond(ts); if (g_bIonPair) processIonPair(ts); } void Interface_AfterAnalysis() { if(g_bRegionAnalysis) finalizeRegionAnalysis(); if(g_bRaman) finalizeRaman(); if(g_bPDF) finalizePDF(); if(g_bNormalCoordinate) finalizeNormalCoordinate(); if(g_bSFac) finalizeStructureFactor(); if(g_bChiral) finalizeChiral(); if(g_bSortWannier) finalizeSortWannier(); if(g_bEckartTransform) finalizeEckartTransform(); if(g_bPower || g_bVACFNew) finalizePowerSpectrum(); if(g_bIR) finalizeIR(); if(g_bVCD) finalizeVCD(); if (g_bDipoleRestart) finalizeDipoleRestart(); if (g_bMagneticDipoleRestart) finalizeMagneticDipoleRestart(); if (g_bSetUpPolarizabilityCalc) finalizePolarizabilityCalc(); if (g_bCubeTimeDev) fclose(g_fPDESolverInfoFile); if (g_bFDF) finalizeFDF(); if (g_bHBond) finalizeHBond(); if (g_bIonPair) finalizeIonPair(); } void Interface_DecomposeModes(int n, CxObArray *ccr_matrix) { normalModeAnalysis(n, ccr_matrix); } /************************************************ Output: mprintf( [Color,] ... ) #define GREY 8 #define BLUE 9 #define GREEN 10 #define CYAN 11 #define RED 12 #define PINK 13 #define YELLOW 14 #define WHITE 15 A list of useful global variables: g_bAdvanced2 g_fTimestepLength g_iTrajSteps // -1 means no information g_fBoxX, g_fBoxY, g_fBoxZ - The cell vector in pm g_oaMolecules - Array of all molecule kinds (members of type CMolecule) g_oaSingleMolecules - Array of all molecules (members of type CSingleMolecule) for (z=0;zm_bPseudo) continue; for (z2=0;z2m_laSingleMolIndex.GetSize();z2++) { sm = (CSingleMolecule*)g_oaSingleMolecules[m->m_laSingleMolIndex[z2]]; for (z3=0;z3m_baAtomIndex.GetSize();z3++) { if ((!g_bSaveVirtAtoms) && (m->m_baAtomIndex[z3] == g_iVirtAtomType)) continue; for (z4=0;z4<((CxIntArray*)sm->m_oaAtomOffset[z3])->GetSize();z4++) mfprintf(a," %s %8.5f %8.5f %8.5f\n",((CAtom*)g_oaAtoms[m->m_baAtomIndex[z3]])->m_sName,m_vaCoords[((CxIntArray*)sm->m_oaAtomOffset[z3])->GetAt(z4)][0]/100.0f,m_vaCoords[((CxIntArray*)sm->m_oaAtomOffset[z3])->GetAt(z4)][1]/100.0f,m_vaCoords[((CxIntArray*)sm->m_oaAtomOffset[z3])->GetAt(z4)][2]/100.0f); } } } *************************************************/ travis-src-190101/src/interface.h0100777000000000000000000000370213412725664013556 0ustar00/***************************************************************************** TRAVIS - Trajectory Analyzer and Visualizer http://www.travis-analyzer.de/ Copyright (c) 2009-2019 Martin Brehm 2012-2019 Martin Thomas 2016-2019 Sascha Gehrke This file was written by Martin Brehm and Martin Thomas. --------------------------------------------------------------------------- This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . *****************************************************************************/ #ifndef INTERFACE_H #define INTERFACE_H // This must always be the first include directive #include "config.h" #include #include #include #include #include "bintools.h" #include "moltools.h" #include "xobject.h" #include "xobarray.h" #include "asciiart.h" #include "backtrace.h" #include "grace.h" #include "acf.h" #include "fft.h" #include "spectrum.h" #include "analysis.h" #include "analysisgroup.h" #include "timestep.h" #include "database.h" #include "xintarray.h" #include "globalvar.h" void Interface_DefaultConf(); bool Interface_BeforeAnalysis(); bool Interface_BeforeAnalysis2(); bool Interface_Initialization(); void Interface_ProcessStep(CTimeStep *ts); void Interface_AfterAnalysis(); void Interface_DecomposeModes(int n, CxObArray *ccr_matrix); #endif travis-src-190101/src/internalcoord.cpp0100777000000000000000000000363513412725620015011 0ustar00/***************************************************************************** TRAVIS - Trajectory Analyzer and Visualizer http://www.travis-analyzer.de/ Copyright (c) 2009-2019 Martin Brehm 2012-2019 Martin Thomas 2016-2019 Sascha Gehrke This file was written by Martin Brehm. --------------------------------------------------------------------------- This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . *****************************************************************************/ // This must always be the first include directive #include "config.h" #include "internalcoord.h" const char *GetRevisionInfo_internalcoord(unsigned int len) { static char buf[256]; GET_REVISION_INFO( buf, len ); return buf; } const char *GetSourceVersion_internalcoord() { static char buf[256]; GET_SOURCE_VERSION( buf ); return buf; } CMolAngle::CMolAngle() { m_faData.SetName("CMolAngle::m_faData"); } CMolAngle::~CMolAngle() { } CMolAngleGroup::CMolAngleGroup() { m_oaAngles.SetName("CMolAngleGroup::m_oaAngles"); } CMolAngleGroup::~CMolAngleGroup() { } CMolBond::CMolBond() { m_faData.SetName("CMolBond::m_faData"); } CMolBond::~CMolBond() { } CMolBondGroup::CMolBondGroup() { m_oaBonds.SetName("CMolBondGroup::m_oaBonds"); } CMolBondGroup::~CMolBondGroup() { } travis-src-190101/src/internalcoord.h0100777000000000000000000000363113412725646014462 0ustar00/***************************************************************************** TRAVIS - Trajectory Analyzer and Visualizer http://www.travis-analyzer.de/ Copyright (c) 2009-2019 Martin Brehm 2012-2019 Martin Thomas 2016-2019 Sascha Gehrke This file was written by Martin Brehm. --------------------------------------------------------------------------- This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . *****************************************************************************/ #ifndef INTERNALCOORD_H #define INTERNALCOORD_H // This must always be the first include directive #include "config.h" #include "xobject.h" #include "xobarray.h" #include "xdoublearray.h" class CMolBond : public CxObject { public: CMolBond(); ~CMolBond(); int m_iAtomType[2]; int m_iAtom[2]; int m_iMolAtom[2]; int m_iAtomOffset[2]; CxDoubleArray m_faData; }; class CMolBondGroup : public CxObject { public: CMolBondGroup(); ~CMolBondGroup(); CxObArray m_oaBonds; }; class CMolAngle : public CxObject { public: CMolAngle(); ~CMolAngle(); int m_iAtomType[3]; int m_iAtom[3]; int m_iMolAtom[3]; int m_iAtomOffset[3]; CxDoubleArray m_faData; }; class CMolAngleGroup : public CxObject { public: CMolAngleGroup(); ~CMolAngleGroup(); CxObArray m_oaAngles; }; #endif travis-src-190101/src/ionpair.cpp0100777000000000000000000007212713412725622013613 0ustar00/***************************************************************************** TRAVIS - Trajectory Analyzer and Visualizer http://www.travis-analyzer.de/ Copyright (c) 2009-2019 Martin Brehm 2012-2019 Martin Thomas 2016-2019 Sascha Gehrke This file was written by Sascha Gehrke. --------------------------------------------------------------------------- This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . *****************************************************************************/ // This must always be the first include directive #include "config.h" #include "ionpair.h" #include "luzar.h" #include #include "globalvar.h" #include "maintools.h" const char *GetRevisionInfo_ionpair(unsigned int len) { static char buf[256]; GET_REVISION_INFO( buf, len ); return buf; } const char *GetSourceVersion_ionpair() { static char buf[256]; GET_SOURCE_VERSION( buf ); return buf; } static CxObArray g_IonPairObserv; bool gatherIonPair() { CIonPairObservation *o; try { o = new CIonPairObservation(); } catch(...) { o = NULL; } if (o == NULL) NewException((double)sizeof(CIonPairObservation),__FILE__,__LINE__,__PRETTY_FUNCTION__); g_IonPairObserv.Add(o); return true; } bool initializeIonPair() { int i; for(i = 0; i < g_IonPairObserv.GetSize(); i++) { ((CIonPairObservation *)g_IonPairObserv[i])->initialize(); } return true; } bool processIonPair(CTimeStep* ts) { int i; for(i = 0; i < g_IonPairObserv.GetSize(); i++) { ((CIonPairObservation *)g_IonPairObserv[i])->process(ts); } return true; } bool finalizeIonPair() { int i; for(i = 0; i < g_IonPairObserv.GetSize(); i++) { ((CIonPairObservation *)g_IonPairObserv[i])->finalize(); } return true; } CIonPairObservation::CIonPairObservation() { int z,n; double d_temp; CxString buf, buf2; CxObArray* oa_temp; try { m_oaAnion = new CxObArray(); } catch(...) { m_oaAnion = NULL; } if (m_oaAnion == NULL) NewException((double)sizeof(CxObArray),__FILE__,__LINE__,__PRETTY_FUNCTION__); try { m_oaCation = new CxObArray(); } catch(...) { m_oaCation = NULL; } if (m_oaCation == NULL) NewException((double)sizeof(CxObArray),__FILE__,__LINE__,__PRETTY_FUNCTION__); mprintf("\n First TRAVIS will gather which molecules are to be handled as cations and anions. \n"); if (g_oaMolecules.GetSize() > 1) { buf.sprintf("\n Which of the molecules are cations ("); for (z=0;zm_sName,z+1); buf.strcat(buf2); if (z < g_oaMolecules.GetSize()-1) buf.strcat(", "); } buf.strcat(")? [enter if finished]"); z = -1; while ( z != 0 ) { z = AskRangeInteger("%s",0,g_oaMolecules.GetSize(),0,(const char*)buf); if ( ia_cation.Contains(z-1) ) { mprintf(WHITE,"\n %s is already chosen as cation.\n\n",((CMolecule*)g_oaMolecules[z-1])->m_sName); } else if ( z != 0 ) { ia_cation.Add(z-1); mprintf(WHITE,"\n Adding %s to the cations.\n\n",((CMolecule*)g_oaMolecules[z-1])->m_sName); } else if ( ia_cation.GetSize() == 0 ) { mprintf(WHITE,"\n Need at least one cation for analysis!\n\n"); z = -1; } } buf.sprintf("\n Which of the molecules are anions ("); for (z=0;zm_sName,z+1); buf.strcat(buf2); if (z < g_oaMolecules.GetSize()-1) buf.strcat(", "); } buf.strcat(")? [enter if finished]"); z = -1; while ( z != 0 ) { z = AskRangeInteger("%s",0,g_oaMolecules.GetSize(),0,(const char*)buf); if ( ia_cation.Contains(z-1) ) { mprintf(WHITE,"\n %s is already chosen as cation.\n",((CMolecule*)g_oaMolecules[z-1])->m_sName); if ( !AskYesNo(" Choose as anion as well (This may cause some weird effects!) ? [yes]", true) ) { continue; } } if ( ia_anion.Contains(z-1) ) { mprintf(WHITE,"\n %s is already chosen as anion.\n\n",((CMolecule*)g_oaMolecules[z-1])->m_sName); } else if ( z != 0 ) { ia_anion.Add(z-1); mprintf(WHITE,"\n Adding %s to the anions.\n\n",((CMolecule*)g_oaMolecules[z-1])->m_sName); } else if ( ia_anion.GetSize() == 0 ) { mprintf(WHITE,"\n Need at least one anion for analysis!\n\n"); z = -1; } } } else { mprintf("\n There is only one molecule, which is handled as cation AND as anion. \n"); ia_anion.Add(0); ia_cation.Add(0); } mprintf("\n Now TRAVIS needs to know which (virtual) atom is the center of the respective ions. "); mprintf("\n If the analysis is performed with more than one cation/anion it may be necessary to "); mprintf("\n correct the size of the smaller ions.\n"); for ( z=0; z < ia_cation.GetSize(); z++ ) { try { oa_temp = new CxObArray(); } catch(...) { oa_temp = NULL; } if (oa_temp == NULL) NewException((double)sizeof(CxObArray),__FILE__,__LINE__,__PRETTY_FUNCTION__); while ( oa_temp->GetSize() == 0 ) { mprintf(" Which atom from %s is the cationic center? [#2] ",((CMolecule*)g_oaMolecules[ia_cation[z]])->m_sName); inpprintf("! Which atom from %s is the cationic center? [#2] \n",((CMolecule*)g_oaMolecules[ia_cation[z]])->m_sName); myget(&buf); if (buf.GetLength() == 0) { buf.sprintf("#2"); } checkAtomChoice((CMolecule*)g_oaMolecules[ia_cation[z]],buf,oa_temp); } if ( ia_cation.GetSize() > 1 ) { d_temp = AskFloat(" Please enter size correction in pm! [0.0]",0.0 ); if ( d_temp != 0.0 ) { for ( n=0; n < oa_temp->GetSize(); n++ ) { ((CIon*)(*oa_temp)[n])->m_dCorr = d_temp; } } } m_oaCation->Add(oa_temp); } for ( z=0; z < ia_anion.GetSize(); z++ ) { try { oa_temp = new CxObArray(); } catch(...) { oa_temp = NULL; } if (oa_temp == NULL) NewException((double)sizeof(CxObArray),__FILE__,__LINE__,__PRETTY_FUNCTION__); while ( oa_temp->GetSize() == 0 ) { mprintf(" Which atom from %s is the anionic center? [#2] ",((CMolecule*)g_oaMolecules[ia_anion[z]])->m_sName); inpprintf("! Which atom from %s is the anionic center? [#2] \n",((CMolecule*)g_oaMolecules[ia_anion[z]])->m_sName); myget(&buf); if (buf.GetLength() == 0) { buf.sprintf("#2"); } checkAtomChoice((CMolecule*)g_oaMolecules[ia_anion[z]],buf,oa_temp); } if ( ia_anion.GetSize() > 1 ) { d_temp = AskFloat(" Please enter size correction in pm! [0.0]",0.0 ); if ( d_temp != 0.0 ) { for ( n=0; n < oa_temp->GetSize(); n++ ) { ((CIon*)oa_temp->GetAt(n))->m_dCorr = d_temp; } } } m_oaAnion->Add(oa_temp); } m_fDist = AskFloat(" Maximum distance between cation and anion in pm (for this distance no corrections are applied!)? [350] ",350.0); g_fTimestepLength = AskFloat(" Enter the length of one trajectory time step in fs: [0.5] ",0.5f); } CIonPairObservation::~CIonPairObservation() { } void CIonPairObservation::initialize() { int n_c, n_a, m_c, m_a; try { m_oaLastNeigh = new CxObArray(); } catch(...) { m_oaLastNeigh = NULL; } if (m_oaLastNeigh == NULL) NewException((double)sizeof(CxObArray),__FILE__,__LINE__,__PRETTY_FUNCTION__); try { m_laLastPair = new CxIntArray(); } catch(...) { m_laLastPair = NULL; } if (m_laLastPair == NULL) NewException((double)sizeof(CxIntArray),__FILE__,__LINE__,__PRETTY_FUNCTION__); try { m_oaNeigh = new CxObArray(); } catch(...) { m_oaNeigh = NULL; } if (m_oaNeigh == NULL) NewException((double)sizeof(CxObArray),__FILE__,__LINE__,__PRETTY_FUNCTION__); try { m_oaPair = new CxObArray(); } catch(...) { m_oaPair = NULL; } if (m_oaPair == NULL) NewException((double)sizeof(CxObArray),__FILE__,__LINE__,__PRETTY_FUNCTION__); if ( g_iMaxStep != -1 ) { m_iDepth = g_iMaxStep * 3 / 4 / g_iStride; } else { m_iDepth = g_iTrajSteps * 3 / 4 / g_iStride; } m_iDepth = AskUnsignedInteger(" Enter the resolution (=depth) of the ACF (in time steps): [%d] ", m_iDepth, m_iDepth); if ( m_iDepth > g_iTrajSteps ) { mprintf(" Correlation Depth is exceeding number of total timesteps. Truncating ....\n"); m_iDepth = g_iTrajSteps; } m_iTotalCats = 0; m_iTotalAns = 0; for ( n_c=0; n_c < m_oaCation->GetSize(); n_c++) // Walks over all Cation Types { for ( m_c=0; m_c < ((CxObArray*)(*m_oaCation)[n_c])->GetSize(); m_c++ ) // Walks over all cations of type { m_iTotalCats++; m_laLastPair->Add(-1); CxIntArray* IncludeME3; try { IncludeME3 = new CxIntArray(); } catch(...) { IncludeME3 = NULL; } if (IncludeME3 == NULL) NewException((double)sizeof(CxIntArray),__FILE__,__LINE__,__PRETTY_FUNCTION__); for ( n_a=0; n_a < m_oaAnion->GetSize(); n_a++) // Walks over all Anion Types { for ( m_a=0; m_a < ((CxObArray*)(*m_oaAnion)[n_a])->GetSize(); m_a++ ) // Walks over all anions of type { if ( m_iTotalCats == 1 ) { m_iTotalAns++; } CxIntArray* IncludeME; CxIntArray* IncludeME2; try { IncludeME = new CxIntArray(); } catch(...) { IncludeME = NULL; } if (IncludeME == NULL) NewException((double)sizeof(CxIntArray),__FILE__,__LINE__,__PRETTY_FUNCTION__); try { IncludeME2 = new CxIntArray(); } catch(...) { IncludeME2 = NULL; } if (IncludeME2 == NULL) NewException((double)sizeof(CxIntArray),__FILE__,__LINE__,__PRETTY_FUNCTION__); m_oaNeigh->Add(IncludeME); m_oaPair->Add(IncludeME2); IncludeME3->Add(0); } } m_oaLastNeigh->Add(IncludeME3); } } for ( n_a=0; n_a < m_oaAnion->GetSize(); n_a++) // Walks over all Anion Types { for ( m_a=0; m_a < ((CxObArray*)(*m_oaAnion)[n_a])->GetSize(); m_a++ ) // Walks over all anions of type { m_laLastPair->Add(-1); CxIntArray* IncludeME3; try { IncludeME3 = new CxIntArray(); } catch(...) { IncludeME3 = NULL; } if (IncludeME3 == NULL) NewException((double)sizeof(CxIntArray),__FILE__,__LINE__,__PRETTY_FUNCTION__); for ( n_c=0; n_c < m_oaCation->GetSize(); n_c++) // Walks over all Cation Types { for ( m_c=0; m_c < ((CxObArray*)(*m_oaCation)[n_c])->GetSize(); m_c++ ) // Walks over all cations of type { CxIntArray* IncludeME; CxIntArray* IncludeME2; try { IncludeME = new CxIntArray(); } catch(...) { IncludeME = NULL; } if (IncludeME == NULL) NewException((double)sizeof(CxIntArray),__FILE__,__LINE__,__PRETTY_FUNCTION__); try { IncludeME2 = new CxIntArray(); } catch(...) { IncludeME2 = NULL; } if (IncludeME2 == NULL) NewException((double)sizeof(CxIntArray),__FILE__,__LINE__,__PRETTY_FUNCTION__); m_oaNeigh->Add(IncludeME); m_oaPair->Add(IncludeME2); IncludeME3->Add(0); } } m_oaLastNeigh->Add(IncludeME3); } } mprintf(" Found in total %d cations and %d anions!\n",m_iTotalCats, m_iTotalAns); m_iTrunc = m_iDepth; while ( m_iTrunc > (int)(m_iDepth/10) ) { m_iTrunc = (int)(50000/(g_fTimestepLength*g_iStride)); if ( m_iTrunc > m_iDepth/10 ) m_iTrunc = (int)(m_iDepth/10); m_iTrunc = AskUnsignedInteger(" Enter the truncation for the fitting procedure (in time steps): [%d] ", m_iTrunc, m_iTrunc); if ( m_iTrunc > m_iDepth/10 ) mprintf(" Truncation must be at least 10 times smaller than correlation depth!\n"); } } void CIonPairObservation::process(CTimeStep* ts) { int Cur_Pair = -1; double Min_Pair; int n_c, n_a, m_c, m_a; int m, n = -1; CxDVector3 Vec; CIon *cat, *an; for ( n_c=0; n_c < m_oaCation->GetSize(); n_c++) // Walks over all Cation Types { for ( m_c=0; m_c < ((CxObArray*)(*m_oaCation)[n_c])->GetSize(); m_c++ ) // Walks over all cations of type { n++; cat = ((CIon*)(*(CxObArray*)(*m_oaCation)[n_c])[m_c]); Min_Pair = 2 * g_fBoxX; m = -1; for ( n_a=0; n_a < m_oaAnion->GetSize(); n_a++) // Walks over all Anion Types { for ( m_a=0; m_a < ((CxObArray*)(*m_oaAnion)[n_a])->GetSize(); m_a++ ) // Walks over all anions of type { m++; an = ((CIon*)(*(CxObArray*)(*m_oaAnion)[n_a])[m_a]); if ( cat->m_iOffset == an->m_iOffset ) { continue; } Vec = ts->m_vaCoords[cat->m_iOffset] - ts->m_vaCoords[an->m_iOffset]; Vec = FoldVector(Vec); if ( Vec.GetLength() <= m_fDist ) // In cutoff range -> Neighbor { if ( Vec.GetLength() < Min_Pair ) { Min_Pair = Vec.GetLength(); Cur_Pair = m; } if ( (*(CxIntArray*)(*m_oaLastNeigh)[n])[m] == 0 ) // Was not a neighbor ... hmmmm .... { ((CxIntArray*)(*m_oaNeigh)[n*m_iTotalAns+m])->Add(g_iSteps); (*(CxIntArray*)(*m_oaLastNeigh)[n])[m] = 1; } } if ( Vec.GetLength() > m_fDist ) // Out of cutoff range -> No Neighbor { if ( (*(CxIntArray*)(*m_oaLastNeigh)[n])[m] == 1 ) // Was a neighbor ... hmmmm .... { ((CxIntArray*)(*m_oaNeigh)[n*m_iTotalAns+m])->Add(g_iSteps); (*(CxIntArray*)(*m_oaLastNeigh)[n])[m] = 0; } } } // m_a end } // n_a end if ( Cur_Pair == -1 ) { eprintf("\n Failure! There was no next counterion found for at least one of the cations.\n"); eprintf(" This is mostly caused by a to large maximum distance.\n"); abort(); } if ( Cur_Pair != (*m_laLastPair)[n] ) { if ( (*m_laLastPair)[n] != -1 ) { ((CxIntArray*)(*m_oaPair)[ ( n * m_iTotalAns ) + (*m_laLastPair)[n] ])->Add(g_iSteps); } ((CxIntArray*)(*m_oaPair)[ ( n * m_iTotalAns ) + Cur_Pair ])->Add(g_iSteps); (*m_laLastPair)[n] = Cur_Pair; } } // m_c end } // n_c end m = -1; for ( n_a=0; n_a < m_oaAnion->GetSize(); n_a++) // Walks over all Anion Types { for ( m_a=0; m_a < ((CxObArray*)(*m_oaAnion)[n_a])->GetSize(); m_a++ ) // Walks over all anions of type { m++; an = ((CIon*)(*(CxObArray*)(*m_oaAnion)[n_a])[m_a]); Min_Pair = 2 * g_fBoxX; n = -1; for ( n_c=0; n_c < m_oaCation->GetSize(); n_c++) // Walks over all Cation Types { for ( m_c=0; m_c < ((CxObArray*)(*m_oaCation)[n_c])->GetSize(); m_c++ ) // Walks over all cations of type { n++; cat = ((CIon*)(*(CxObArray*)(*m_oaCation)[n_c])[m_c]); if ( cat->m_iOffset == an->m_iOffset ) { continue; } Vec = ts->m_vaCoords[cat->m_iOffset] - ts->m_vaCoords[an->m_iOffset]; Vec = FoldVector(Vec); if ( Vec.GetLength() <= m_fDist ) // In cutoff range -> Neighbor { if ( Vec.GetLength() < Min_Pair ) { Min_Pair = Vec.GetLength(); Cur_Pair = n; } if ( (*(CxIntArray*)(*m_oaLastNeigh)[m+m_iTotalCats])[n] == 0 ) // Was not a neighbor ... hmmmm .... { ((CxIntArray*)(*m_oaNeigh)[m_iTotalCats*m_iTotalAns+m*m_iTotalCats+n])->Add(g_iSteps); (*(CxIntArray*)(*m_oaLastNeigh)[m+m_iTotalCats])[n] = 1; } } if ( Vec.GetLength() > m_fDist ) // Out of cutoff range -> No Neighbor { if ( (*(CxIntArray*)(*m_oaLastNeigh)[m+m_iTotalCats])[n] == 1 ) // Was a neighbor ... hmmmm .... { ((CxIntArray*)(*m_oaNeigh)[m_iTotalCats*m_iTotalAns+m*m_iTotalCats+n])->Add(g_iSteps); (*(CxIntArray*)(*m_oaLastNeigh)[m+m_iTotalCats])[n] = 0; } } } // m_a end } // n_a end if ( Cur_Pair == -1 ) { eprintf("\n Failure! There was no next counterion found for at least one of the anions.\n"); eprintf(" This is mostly caused by a to small maximum distance.\n"); abort(); } if ( Cur_Pair != (*m_laLastPair)[m+m_iTotalCats] ) { if ( (*m_laLastPair)[m+m_iTotalCats] != -1 ) { ((CxIntArray*)(*m_oaPair)[ m_iTotalCats * m_iTotalAns + m * m_iTotalCats + (*m_laLastPair)[m+m_iTotalCats] ])->Add(g_iSteps); } ((CxIntArray*)(*m_oaPair)[ m_iTotalCats * m_iTotalAns + m * m_iTotalCats + Cur_Pair ])->Add(g_iSteps); (*m_laLastPair)[m+m_iTotalCats] = Cur_Pair; } } // m_a end } // n_a end } void CIonPairObservation::finalize() // reconstruct functions -> autocorrelate -> sum results -> normalize -> fit { long n,m,i,interval, count, z; double PairCor, DiffCor; CxString buf,buf2; unsigned long t0,eta; CxDoubleArray* NeighFunction; // Input CxDoubleArray* PairFunction; CxDoubleArray* temp1Function; // Temp CxDoubleArray* temp2Function; CxDoubleArray* temp3Function; CLuzarCorrelation* luzar; try { PairFunction = new CxDoubleArray(); } catch(...) { PairFunction = NULL; } if (PairFunction == NULL) NewException((double)sizeof(CxDoubleArray),__FILE__,__LINE__,__PRETTY_FUNCTION__); try { NeighFunction = new CxDoubleArray(); } catch(...) { NeighFunction = NULL; } if (NeighFunction == NULL) NewException((double)sizeof(CxDoubleArray),__FILE__,__LINE__,__PRETTY_FUNCTION__); try { PairDynamic = new CxObArray(); } catch(...) { PairDynamic = NULL; } if (PairDynamic == NULL) NewException((double)sizeof(CxObArray),__FILE__,__LINE__,__PRETTY_FUNCTION__); try { DiffusionDynamic = new CxObArray(); } catch(...) { DiffusionDynamic = NULL; } if (DiffusionDynamic == NULL) NewException((double)sizeof(CxObArray),__FILE__,__LINE__,__PRETTY_FUNCTION__); try { k_t = new CxObArray(); } catch(...) { k_t = NULL; } if (k_t == NULL) NewException((double)sizeof(CxObArray),__FILE__,__LINE__,__PRETTY_FUNCTION__); try { a = new CxObArray(); } catch(...) { a = NULL; } if (a == NULL) NewException((double)sizeof(CxObArray),__FILE__,__LINE__,__PRETTY_FUNCTION__); try { b = new CxObArray(); } catch(...) { b = NULL; } if (b == NULL) NewException((double)sizeof(CxObArray),__FILE__,__LINE__,__PRETTY_FUNCTION__); for ( n=0; n < (m_oaCation->GetSize()+m_oaAnion->GetSize()); n++) // Walks over all Cation Types { try { temp1Function = new CxDoubleArray(); } catch(...) { temp1Function = NULL; } if (temp1Function == NULL) NewException((double)sizeof(CxDoubleArray),__FILE__,__LINE__,__PRETTY_FUNCTION__); try { temp2Function = new CxDoubleArray(); } catch(...) { temp2Function = NULL; } if (temp2Function == NULL) NewException((double)sizeof(CxDoubleArray),__FILE__,__LINE__,__PRETTY_FUNCTION__); for ( i=0; i < m_iDepth; i++ ) { temp1Function->Add(0.0); temp2Function->Add(0.0); } PairDynamic->Add(temp1Function); DiffusionDynamic->Add(temp2Function); try { temp1Function = new CxDoubleArray(); } catch(...) { temp1Function = NULL; } if (temp1Function == NULL) NewException((double)sizeof(CxDoubleArray),__FILE__,__LINE__,__PRETTY_FUNCTION__); try { temp2Function = new CxDoubleArray(); } catch(...) { temp2Function = NULL; } if (temp2Function == NULL) NewException((double)sizeof(CxDoubleArray),__FILE__,__LINE__,__PRETTY_FUNCTION__); try { temp3Function = new CxDoubleArray(); } catch(...) { temp3Function = NULL; } if (temp3Function == NULL) NewException((double)sizeof(CxDoubleArray),__FILE__,__LINE__,__PRETTY_FUNCTION__); k_t->Add(temp1Function); a->Add(temp2Function); b->Add(temp3Function); } try { temp1Function = new CxDoubleArray(); } catch(...) { temp1Function = NULL; } if (temp1Function == NULL) NewException((double)sizeof(CxDoubleArray),__FILE__,__LINE__,__PRETTY_FUNCTION__); try { temp2Function = new CxDoubleArray(); } catch(...) { temp2Function = NULL; } if (temp2Function == NULL) NewException((double)sizeof(CxDoubleArray),__FILE__,__LINE__,__PRETTY_FUNCTION__); try { luzar = new CLuzarCorrelation(); } catch(...) { luzar = NULL; } if (luzar == NULL) NewException((double)sizeof(CLuzarCorrelation),__FILE__,__LINE__,__PRETTY_FUNCTION__); NeighFunction->SetSize(g_iSteps / g_iStride); PairFunction->SetSize(g_iSteps / g_iStride); for ( i=0; i < (int)(g_iSteps/g_iStride); i++ ) { (*NeighFunction)[i] = 0; (*PairFunction)[i] = 0; } luzar->Init(g_iSteps / g_iStride,m_iDepth); // Inititalize Luzar-Correlation mprintf(" Finishing %6i Functions ... \nFunc %6li ",m_oaNeigh->GetSize(),(long)0); g_iDotCounter = 0; t0 = (unsigned long)time(NULL); interval = 2; count = -1; for ( n=0; n < (m_oaCation->GetSize() + m_oaAnion->GetSize()); n++) // Walks over all ion Types { if ( n < m_oaCation->GetSize() ) z = (((CxObArray*)(*m_oaCation)[n])->GetSize() * m_iTotalAns) ; else z = (((CxObArray*)(*m_oaAnion)[n-m_oaCation->GetSize()])->GetSize() * m_iTotalCats); for ( m=0; m < z; m++ ) // Walks over all ions of type { count++; if ( count % interval == 0 ) { if ( g_iDotCounter >= 50 ) { if ( interval == 2 && count > 100 ) { interval = 20; } else if ( interval == 20 && count > 2000 ) { interval = 200; } g_iDotCounter = 0; if ((time(NULL) - t0) > 5) { eta = (unsigned long)(((double)time(NULL) - t0) / count * ((double)MAX((long)0,(long)m_oaNeigh->GetSize() - (long)count))); FormatTime(eta,&buf); mprintf(" ETA %s",(const char*)buf); } mprintf("\nFunc %6li ",count); } g_iDotCounter++; mprintf("."); } if ( ((CxIntArray*)(*m_oaPair)[count])->GetSize() > 0 ) { RestoreFunction(((CxIntArray*)(*m_oaNeigh)[count]),((CxDoubleArray*)NeighFunction)); // Restore function of pair n as NeighFunction and BondFunction RestoreFunction(((CxIntArray*)(*m_oaPair)[count]),((CxDoubleArray*)PairFunction)); luzar->Correlate(PairFunction,NeighFunction,temp1Function,temp2Function); for ( i=0; i < m_iDepth; i++ ) // Sum results to Output-array { (*(CxDoubleArray*)(*PairDynamic)[n])[i] += (*temp1Function)[i]; (*(CxDoubleArray*)(*DiffusionDynamic)[n])[i] += (*temp2Function)[i]; } } } // end of individuals if ( (*(CxDoubleArray*)(*PairDynamic)[n])[0] == 0 || (*(CxDoubleArray*)(*DiffusionDynamic)[n])[0] == 0 ) { eprintf("\n First correlation value is zero ... something is wrong ...\n"); abort(); } PairCor = (double)(*(CxDoubleArray*)(*PairDynamic)[n])[0]; DiffCor = (double)(*(CxDoubleArray*)(*DiffusionDynamic)[n])[0]; for ( i=0; i < m_iDepth; i++ ) // Normalize { (*(CxDoubleArray*)(*PairDynamic)[n])[i] /= PairCor; (*(CxDoubleArray*)(*DiffusionDynamic)[n])[i] /= DiffCor; (*(CxDoubleArray*)(*DiffusionDynamic)[n])[i] -= (*(CxDoubleArray*)(*PairDynamic)[n])[i]; } } // end of types mprintf("\n\n"); for ( n=0; n < (m_oaCation->GetSize() + m_oaAnion->GetSize()); n++) // Walks over all Cation Types { if ( n < m_oaCation->GetSize() ) z = ia_cation[n]; else z = ia_anion[n-m_oaCation->GetSize()]; mprintf("Fitting %s ...\n",((CMolecule*)g_oaMolecules[z])->m_sName); luzar->Fit(((CxDoubleArray*)(*PairDynamic)[n]), ((CxDoubleArray*)(*DiffusionDynamic)[n]), ((CxDoubleArray*)(*k_t)[n]), ((CxDoubleArray*)(*a)[n]), ((CxDoubleArray*)(*b)[n]), m_iTrunc); WriteOutput(((CxDoubleArray*)(*PairDynamic)[n]), ((CxDoubleArray*)(*DiffusionDynamic)[n]), ((CxDoubleArray*)(*a)[n]), ((CxDoubleArray*)(*b)[n]), ((CxDoubleArray*)(*k_t)[n]), ((CMolecule*)g_oaMolecules[z])->m_sName); } } void CIonPairObservation::RestoreFunction(CxIntArray* input, CxDoubleArray* output) { unsigned int n; bool eins = false; for ( n=0; n < (g_iSteps / g_iStride); n++ ) // Walk over all processed steps { if ( input->Contains((n+1)*g_iStride) ) eins = !eins; if (!eins) output->SetAt(n,0.0); else output->SetAt(n,1.0); } } bool CIonPairObservation::includeAtom(int atom, int number, int mol, CxObArray* target) // atom: element number, number: atomsort number, mol m_iShowMol, target: in which array to include { int n; CIon* ion; for ( n=0; n < ((CMolecule*)g_oaMolecules[mol])->m_laSingleMolIndex.GetSize(); n++) { try { ion = new CIon(); } catch(...) { ion = NULL; } if (ion == NULL) NewException((double)sizeof(CIon),__FILE__,__LINE__,__PRETTY_FUNCTION__); ion->m_iOffset = ((CxIntArray*)(((CSingleMolecule*)g_oaSingleMolecules[((CMolecule*)g_oaMolecules[mol])->m_laSingleMolIndex[n]])->m_oaAtomOffset[atom]))->GetAt(number); target->Add(ion); } return true; } bool CIonPairObservation::checkAtomChoice(CMolecule *mol, const char *s, CxObArray* m_oaInclude) { const char *p, *q; char buf[32]; const char *allowed = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890,# "; int i = -1, atom = -1; p = s; while (*p == ' ') p++; if (strchr(allowed,*p) == NULL) { eprintf("Error: Character \"%c\" not allowed.\n",*p); return false; } q = p; if (isalpha(*q) || (*q == '#')) { while (isalpha(*q) || (*q == '#')) q++; if (q-p >= 32) { eprintf("Internal Error (%ld >= 32).\n",q-p); return false; } memcpy(buf,p,q-p); buf[q-p] = 0; atom = mol->FindAtomInMol(buf); // atom holds number of element if (atom == -1) { eprintf("Error: Atom \"%s\" not in the molecule.\n",buf); return false; } } p = q; if (isdigit(*q)) { if (atom == -1) { eprintf("Error: Number in the beginning not possible.\n"); return false; } while (isdigit(*q)) q++; if (*q != 0) { eprintf("Error: Please type only one atom.\n"); return false; } if (q-p >= 32) { eprintf("Internal Error (%ld >= 32).\n",q-p); return false; } memcpy(buf,p,q-p); buf[q-p] = 0; if (atoi(buf)-1 >= mol->m_waAtomCount[atom]) { eprintf("Error: Only %d %s atoms in the molecule (requested: %d)\n",mol->m_waAtomCount[atom],(const char*)((CAtom*)g_oaAtoms[mol->m_baAtomIndex[atom]])->m_sName,atoi(buf)); return false; } } i = atoi(buf)-1; if ( i == -1 ) { eprintf("Error: Please type only one atom.\n"); return false; } else includeAtom(atom, i, mol->m_iIndex, m_oaInclude); // hier return true; } void CIonPairObservation::WriteOutput(CxDoubleArray* pairs, CxDoubleArray* diffs, CxDoubleArray* as, CxDoubleArray* bs, CxDoubleArray* k_ts, std::string name) { CGrace* gc; int n,m; char buf[256]; mprintf(" Writing \"%s_Correlations.agr\"...\n", name.c_str()); try { gc = new CGrace(); } catch(...) { gc = NULL; } if (gc == NULL) NewException((double)sizeof(CGrace),__FILE__,__LINE__,__PRETTY_FUNCTION__); gc->SetRangeX(0,m_iDepth*g_fTimestepLength/1000*g_iStride); gc->SetRangeY(0,1); gc->MakeTicks(); gc->SetLabelX("tau [ps]"); gc->SetLabelY("f(tau)"); gc->CurrentGraph()->m_bInvertXAxis = false; gc->CurrentGraph()->m_bLegend = true; gc->AddDataset(); gc->SetDatasetName(0, "c(t)"); gc->AddDataset(); gc->SetDatasetName(1, "n(t)"); for ( n = 0; n < pairs->GetSize(); n++) { gc->AddXYTupel(0,n*g_fTimestepLength/1000*g_iStride,(*pairs)[n]); gc->AddXYTupel(1,n*g_fTimestepLength/1000*g_iStride,(*diffs)[n]); } sprintf(buf,"%s_Correlations.agr",name.c_str()); gc->WriteAgr(buf,false); sprintf(buf,"%s_Correlations.csv",name.c_str()); gc->WriteCSV(buf); delete gc; mprintf(" Writing \"%s_Fitted.agr\"...\n", name.c_str()); CalcMinMax(pairs, diffs, as, bs, k_ts); try { gc = new CGrace(); } catch(...) { gc = NULL; } if (gc == NULL) NewException((double)sizeof(CGrace),__FILE__,__LINE__,__PRETTY_FUNCTION__); gc->SetRangeX(0,m_dGraceMax); gc->SetRangeY(0,m_dGraceMax); gc->MakeTicks(); gc->SetLabelX("kf c(t) - kb n(t) [1/ps]"); gc->SetLabelY("-dc/dt [1/ps]"); gc->CurrentGraph()->m_bInvertXAxis = false; gc->CurrentGraph()->m_bLegend = true; gc->AddDataset(); gc->SetDatasetName(0, "Data"); for ( m=0; m < k_ts->GetSize(); m++) gc->AddXYTupel(0,(*as)[0] * (*pairs)[m] - (*bs)[0] * (*diffs)[m], -(*k_ts)[m]); sprintf(buf,"%s_Fitted.csv",name.c_str()); gc->WriteCSV(buf); gc->AddDataset(); gc->SetDatasetName(1, "Unity"); gc->AddXYTupel(1,m_dGraceMin,m_dGraceMin); gc->AddXYTupel(1,m_dGraceMax,m_dGraceMax); sprintf(buf,"%s_Fitted.agr",name.c_str()); gc->WriteAgr(buf,false); delete gc; } void CIonPairObservation::CalcMinMax(CxDoubleArray* pairs, CxDoubleArray* diffs, CxDoubleArray* as, CxDoubleArray* bs, CxDoubleArray* k_ts) { double temp; int n; m_dGraceMin = 1E10; m_dGraceMax = -1E10; for ( n = m_iTrunc; n < PairDynamic->GetSize(); n++) { temp = ((*as)[0] * (*pairs)[n] - (*bs)[0] * (*diffs)[n]); if ( m_dGraceMin >= temp ) m_dGraceMin = temp; if ( m_dGraceMax <= temp ) m_dGraceMax = temp; } for ( n = m_iTrunc; n < k_ts->GetSize(); n++) { temp = -k_ts->GetAt(n); if ( m_dGraceMin >= temp ) m_dGraceMin = temp; if ( m_dGraceMax <= temp ) m_dGraceMax = temp; } } void CIonPairObservation::Initiate_Offsets(int mol, CxObArray* array) { int n; for ( n=0; n<((CMolecule*)g_oaMolecules[mol])->m_laSingleMolIndex.GetSize(); n++ ) { CxIntArray* temp; try { temp = new CxIntArray(); } catch(...) { temp = NULL; } if (temp == NULL) NewException((double)sizeof(CxIntArray),__FILE__,__LINE__,__PRETTY_FUNCTION__); array->Add(temp); } } CIon::CIon() { m_iOffset = -1; m_dCorr = -1.0; } CIon::~CIon() { } travis-src-190101/src/ionpair.h0100777000000000000000000000564613412725655013270 0ustar00/***************************************************************************** TRAVIS - Trajectory Analyzer and Visualizer http://www.travis-analyzer.de/ Copyright (c) 2009-2019 Martin Brehm 2012-2019 Martin Thomas 2016-2019 Sascha Gehrke This file was written by Sascha Gehrke. --------------------------------------------------------------------------- This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . *****************************************************************************/ #ifndef IONPAIR_H #define IONPAIR_H // This must always be the first include directive #include "config.h" #include "moltools.h" bool gatherIonPair(); bool initializeIonPair(); bool processIonPair(CTimeStep* ts); bool finalizeIonPair(); class CIonPairObservation: public CObservation { public: CIonPairObservation(); ~CIonPairObservation(); CxIntArray ia_anion, ia_cation; // Contains the type numbers of the ion types CxObArray *m_oaAnion; // Contains an ObArray for each anion. This array contains the CIons CxObArray *m_oaCation; // CxObArray *m_oaNeigh; // Arrays are two dimensional: First, all cations, second all anions CxObArray *m_oaPair; // The ions are thereby sorted in an "A1,A2,A3,B1,B2,C1..." style CxObArray *m_oaLastNeigh; // Contains the last neighborstates CxIntArray *m_laLastPair; // Contains the last pair partner (there must be one in every step) CxObArray* PairDynamic; // Final Datasets after processing CxObArray* DiffusionDynamic; CxObArray* k_t; // Numerical derivation of BondDynamic CxObArray* a; CxObArray* b; double m_fDist; // Distance for the caging int m_iDepth, m_iTrunc; int m_iTotalCats, m_iTotalAns; double m_dGraceMin, m_dGraceMax; void initialize(); void process(CTimeStep* ts); void finalize(); void Initiate_Offsets(int, CxObArray*); bool checkAtomChoice(CMolecule*, const char*, CxObArray*); bool includeAtom(int, int, int, CxObArray*); void RestoreFunction(CxIntArray*, CxDoubleArray*); void CalcMinMax(CxDoubleArray*, CxDoubleArray*, CxDoubleArray*, CxDoubleArray*, CxDoubleArray*); void WriteOutput(CxDoubleArray*, CxDoubleArray*, CxDoubleArray*, CxDoubleArray*, CxDoubleArray*,std::string); private: }; class CIon: public CxObject { public: CIon(); ~CIon(); int m_iOffset; double m_dCorr; private: }; #endif travis-src-190101/src/ir.cpp0100777000000000000000000023470013412725636012566 0ustar00/***************************************************************************** TRAVIS - Trajectory Analyzer and Visualizer http://www.travis-analyzer.de/ Copyright (c) 2009-2019 Martin Brehm 2012-2019 Martin Thomas 2016-2019 Sascha Gehrke This file was written by Martin Thomas. --------------------------------------------------------------------------- This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . *****************************************************************************/ // This must always be the first include directive #include "config.h" #include "ir.h" #include "globalvar.h" #include "maintools.h" #include "timestep.h" #include "xstring.h" #include "linalg.h" #include const char *GetRevisionInfo_ir(unsigned int len) { static char buf[256]; GET_REVISION_INFO( buf, len ); return buf; } const char *GetSourceVersion_ir() { static char buf[256]; GET_SOURCE_VERSION( buf ); return buf; } #define BUF_SIZE 4096 static CxObArray g_PowerObserv; // static CxFloatArray g_TemperatureCache; CPowerObservation::CPowerObservation(bool global) { int i, size; CxString buf, buf2; try { _atoms = new CAtomGroup(); } catch(...) { _atoms = NULL; } if (_atoms == NULL) NewException((double)sizeof(CAtomGroup), __FILE__, __LINE__, __PRETTY_FUNCTION__); if (global) { m_iShowMol = -1; m_iShowMolCount = g_oaSingleMolecules.GetSize(); _name = new char[7]; sprintf(_name, "global"); } else { // char buf[BUF_SIZE]; // char buf2[BUF_SIZE]; // size_t remaining = BUF_SIZE; if (g_oaMolecules.GetSize() > 1) { /*#ifdef TARGET_LINUX remaining -= snprintf(buf, remaining, " Which molecule should be observed ("); #else remaining -= sprintf(buf, " Which molecule should be observed ("); #endif*/ buf.sprintf( " Which molecule should be observed ("); for (i = 0; i < g_oaMolecules.GetSize(); i++) { /* if(remaining < 1) break; #ifdef TARGET_LINUX size_t length = snprintf(buf2, remaining, "%s=%d", ((CMolecule *)g_oaMolecules[i])->m_sName, i+1); #else size_t length = sprintf(buf2, "%s=%d", ((CMolecule *)g_oaMolecules[i])->m_sName, i+1); #endif strncat(buf, buf2, remaining - 1); remaining -= length;*/ buf2.sprintf("%s=%d", ((CMolecule *)g_oaMolecules[i])->m_sName, i+1); buf.strcat(buf2); if (i < g_oaMolecules.GetSize() - 1) { /*#ifdef TARGET_LINUX length = snprintf(buf2, remaining, ", "); #else length = sprintf(buf2, ", "); #endif strncat(buf, buf2, remaining - 1); remaining -= length;*/ buf2.sprintf(", "); buf.strcat(buf2); } } // strncat(buf, ")? ", remaining - 1); buf.strcat(")? "); m_iShowMol = AskRangeInteger_ND("%s", 1, g_oaMolecules.GetSize(),(const char*)buf) - 1; } else { m_iShowMol = 0; mprintf(" Observing molecule %s.\n", ((CMolecule *)g_oaMolecules[m_iShowMol])->m_sName); } while(true) { mprintf(" Which atom(s) to observe (e.g. \"C1,C3-5,H\", \"*\"=all)? [*] "); inpprintf("! Which atom(s) to observe (e.g. \"C1,C3-5,H\", \"*\"=all)? [*]\n"); // char buf[BUF_SIZE]; myget(&buf); if(strlen(buf) == 0) { if(!_atoms->ParseAtoms((CMolecule *)g_oaMolecules[m_iShowMol], "*")) { eprintf("CPowerObservation::CPowerObservation(): Internal error 1.\n"); continue; } } else if(!_atoms->ParseAtoms((CMolecule *)g_oaMolecules[m_iShowMol], buf)) { continue; } break; } mprintf("\n Observing %d atoms of molecule %s.\n", _atoms->m_iAtomGes, ((CMolecule *)g_oaMolecules[m_iShowMol])->m_sName); m_iShowMolCount = ((CMolecule *)g_oaMolecules[m_iShowMol])->m_laSingleMolIndex.GetSize(); _name = new char[strlen(((CMolecule *)g_oaMolecules[m_iShowMol])->m_sName) + strlen(_atoms->m_sName) + 4]; sprintf(_name, "[%s_%s]", ((CMolecule *)g_oaMolecules[m_iShowMol])->m_sName, _atoms->m_sName); mprintf("\n"); } if(g_iTrajSteps != -1) { _correlationDepth = (int)(0.75 * g_iTrajSteps); if (g_bPower) { if (_correlationDepth > 4096) _correlationDepth = 4096; if ((g_fTimestepLength > 1.0) && (_correlationDepth > 2048)) _correlationDepth = 2048; if ((g_fTimestepLength > 2.0) && (_correlationDepth > 1024)) _correlationDepth = 1024; } _correlationDepth = AskUnsignedInteger(" Enter the resolution (=depth) of the ACF (in time steps): [%d] ", _correlationDepth, _correlationDepth); } else { _correlationDepth = AskUnsignedInteger(" Enter the resolution (=depth) of the ACF (in time steps): [256] ", 256); } size = CalcFFTSize(_correlationDepth, false); if (_correlationDepth != size) { mprintf(WHITE, " The next \"fast\" size for FFT is %d. Using this instead of %d as depth.\n\n", size, _correlationDepth); _correlationDepth = size; } m_iFinalDepth = _correlationDepth; if (g_bPower) { if (g_bAdvanced2) { m_bSplitCart = AskYesNo(" Write cartesian contributions (x, y, z, xy, xz, yz) of this power spectrum (y/n)? [no] ",false); mprintf("\n"); } else m_bSplitCart = false; } else { m_bSplitCart = AskYesNo(" Write cartesian contributions (x, y, z, xy, xz, yz) of this autocorrelation (y/n)? [no] ",false); mprintf("\n"); } if(g_bAdvanced2) { if (g_bPower) _windowFunction = AskRangeInteger(" Window function: None (0), cos^2(a*t) (1), exp(-t/a) (2), exp(-(t/a)^2) (3) [1] ", 0, 3, 1); else _windowFunction = AskRangeInteger(" Window function: None (0), cos^2(a*t) (1), exp(-t/a) (2), exp(-(t/a)^2) (3) [0] ", 0, 3, 0); if(_windowFunction == 1) { mprintf(" The parameter \"a\" is chosen according to the correlation depth.\n"); _windowFunctionParameter = 0; } else if(_windowFunction == 2) { _windowFunctionParameter = AskUnsignedInteger(" Parameter \"a\" (in time steps): [%d] ", m_iFinalDepth / 4, m_iFinalDepth / 4); } else if(_windowFunction == 3) { _windowFunctionParameter = AskUnsignedInteger(" Parameter \"a\" (in time steps): [%d] ", m_iFinalDepth / 2, m_iFinalDepth / 2); } else if (_windowFunction != 0) { eprintf("CPowerObservation::CPowerObservation(): Internal error 2.\n"); abort(); } mprintf("\n"); } else { if (g_bPower) _windowFunction = 1; else _windowFunction = 0; _windowFunctionParameter = 0; } if (g_bPower) _massWeighting = AskYesNo(" Weight autocorrelation functions by atomic mass (y/n)? [yes] ", true); else _massWeighting = AskYesNo(" Weight autocorrelation functions by atomic mass (y/n)? [no] ", false); mprintf("\n"); if (g_bPower) { if(g_bAdvanced2) { _zeroPadding = AskUnsignedInteger(" Zero Padding: How many zeros to insert? [%d] ", m_iFinalDepth * 3, m_iFinalDepth * 3); size = CalcFFTSize(m_iFinalDepth + _zeroPadding, false); if(m_iFinalDepth + _zeroPadding != size) { mprintf(WHITE, " The next \"fast\" size for FFT is %d. Using %d zeros for zero padding.\n", size, size-m_iFinalDepth); _zeroPadding = size - m_iFinalDepth; } } else { _zeroPadding = m_iFinalDepth * 3; size = CalcFFTSize(m_iFinalDepth + _zeroPadding, false); mprintf(" Using cos^2 window function; inserting %d zeros for zero padding.\n",_zeroPadding); if(m_iFinalDepth + _zeroPadding != size) { mprintf(WHITE, " The next \"fast\" size for FFT is %d. Using %d zeros for zero padding.\n", size, size-m_iFinalDepth); _zeroPadding = size - m_iFinalDepth; } } double possibleRange = 33356.41 / g_fTimestepLength / 2.0; _specResolution = possibleRange / (m_iFinalDepth + _zeroPadding); mprintf(" This results in a spectral resolution of %.2f cm^-1.\n", _specResolution); mprintf("\n A time step length of %.2f fs allows a spectral range up to %.2f cm^-1.\n", g_fTimestepLength, possibleRange); double specLimit = AskRangeFloat("\n Calculate spectrum up to which wave number (cm^-1)? [%.2f cm^-1] ", 0, possibleRange, (possibleRange < 5000.0) ? possibleRange : 5000.0, (possibleRange < 5000.0) ? possibleRange : 5000.0); _specSize = (int)(specLimit / _specResolution); mprintf("\n"); if(g_bAdvanced2) { _saveACF = AskYesNo(" Save autocorrelation function (y/n)? [no] ", false); mprintf("\n"); } else _saveACF = false; } else { _saveACF = true; } } CPowerObservation::~CPowerObservation() { delete[] _name; delete _atoms; } void CPowerObservation::initialize() { int i, j, k; int n; if(g_iTrajSteps != -1) n = (int)(1.1 * g_iTrajSteps / g_iStride); else n = 10000; if(m_iShowMol == -1) { mprintf(" Velocity cache: Trying to allocate %s of memory...\n", FormatBytes((double)g_iGesAtomCount * n * sizeof(CxDVector3))); for(i = 0; i < g_iGesAtomCount; i++) { CxDVec3Array *a; try { a = new CxDVec3Array(); } catch(...) { a = NULL; } if(a == NULL) NewException((double)sizeof(CxDVec3Array), __FILE__, __LINE__, __PRETTY_FUNCTION__); a->SetMaxSize(n); a->SetGrow(n / 10); _velocityCache.Add(a); } } else { mprintf(" Velocity cache: Trying to allocate %s of memory...\n", FormatBytes((double)m_iShowMolCount * _atoms->m_iAtomGes * n * sizeof(CxDVector3))); for(i = 0; i < m_iShowMolCount * _atoms->m_iAtomGes; i++) { CxDVec3Array *a; try { a = new CxDVec3Array(); } catch(...) { a = NULL; } if(a == NULL) NewException((double)sizeof(CxDVec3Array), __FILE__, __LINE__, __PRETTY_FUNCTION__); a->SetMaxSize(n); a->SetGrow(n / 10); _velocityCache.Add(a); } } if(m_iShowMol == -1) { _masses.SetSize(g_iGesAtomCount); if(_massWeighting) { for(i = 0; i < g_iGesAtomCount; i++) { _masses[i] = ((CAtom *)g_oaAtoms[g_waAtomRealElement[i]])->m_pElement->m_fMass; if (_masses[i] == 0) { eprintf("\nWarning: Zero mass for element %s, using 1 for mass weighting.",(const char*)((CAtom *)g_oaAtoms[g_waAtomRealElement[i]])->m_sName); _masses[i] = 1.0; } } } else { for(i = 0; i < g_iGesAtomCount; i++) { _masses[i] = 1.0; } } } else { _masses.SetSize(m_iShowMolCount * _atoms->m_iAtomGes); if(_massWeighting) { for(i = 0; i < m_iShowMolCount; i++) { n = 0; for(j = 0; j < _atoms->m_baRealAtomType.GetSize(); j++) { if ((i == 0) && (((CAtom *)g_oaAtoms[_atoms->m_baRealAtomType[j]])->m_pElement->m_fMass == 0)) eprintf("\nWarning: Zero mass for element %s, using 1 for mass weighting.",(const char*)((CAtom *)g_oaAtoms[_atoms->m_baRealAtomType[j]])->m_sName); CxIntArray *a = (CxIntArray *)_atoms->m_oaAtoms[j]; for(k = 0; k < a->GetSize(); k++) { _masses[i * _atoms->m_iAtomGes + n] = ((CAtom *)g_oaAtoms[_atoms->m_baRealAtomType[j]])->m_pElement->m_fMass; if (_masses[i * _atoms->m_iAtomGes + n] == 0) _masses[i * _atoms->m_iAtomGes + n] = 1.0; n++; } } } } else { for(i = 0; i < m_iShowMolCount * _atoms->m_iAtomGes; i++) { _masses[i] = 1.0; } } } } void CPowerObservation::process(CTimeStep *ts) { int i, j, k; if(m_iShowMol == -1) { for(i = 0; i < g_iGesAtomCount; i++) { ((CxDVec3Array *)_velocityCache[i])->Add(ts->m_vaVelocities[i]); } } else { for(i = 0; i < m_iShowMolCount; i++) { CSingleMolecule *sm = (CSingleMolecule *)g_oaSingleMolecules[((CMolecule *)g_oaMolecules[m_iShowMol])->m_laSingleMolIndex[i]]; int n = 0; for(j = 0; j < _atoms->m_baAtomType.GetSize(); j++) { CxIntArray *a = (CxIntArray *)_atoms->m_oaAtoms[j]; for(k = 0; k < a->GetSize(); k++) { ((CxDVec3Array *)_velocityCache[i * _atoms->m_iAtomGes + n])->Add(ts->m_vaVelocities[((CxIntArray *)sm->m_oaAtomOffset[_atoms->m_baAtomType[j]])->GetAt(a->GetAt(k))]); n++; } } } } } void CPowerObservation::finalize() { int i, j, k, l, n, oldSize, split, cc=0; double step, possibleRange, integral; CFFT *fft; CxDoubleArray *acf, *temp, *temp2, *spectrum; CAutoCorrelation *ac; FILE *specFile, *acfFile; char filename[BUF_SIZE]; const char *contrib=NULL; split = 0; n = ((CxDVec3Array *)_velocityCache[0])->GetSize(); if (n < _correlationDepth) { eprintf("\nError: Autocorrelation depth is %d, but only %d timesteps evaluated.\n",_correlationDepth,n); eprintf(" Reduce depth or increase trajectory length.\n\n"); abort(); } if ((g_iStride != 1) && g_bPower) { mprintf("\n A trajectory stride of %d was entered, correcting spectral resolution...\n",g_iStride); possibleRange = 33356.41 / g_fTimestepLength / g_iStride / 2.0; _specResolution = possibleRange / (_correlationDepth + _zeroPadding); mprintf(" New spectral resolution is %.2f cm^-1.\n\n", _specResolution); _specSize *= g_iStride; if (_specSize > _correlationDepth+_zeroPadding) _specSize = _correlationDepth+_zeroPadding; } if(m_iShowMol == -1) step = (double)g_iGesAtomCount / 50.0; else step = (double)m_iShowMolCount * _atoms->m_iAtomGes / 50.0; _beginsplit: switch(split) { case 0: cc = 3; contrib = ""; if (m_bSplitCart) mprintf(WHITE," *** All Contributions ***\n"); break; case 1: cc = 1; contrib = "_x"; if (m_bSplitCart) mprintf(WHITE,"\n *** X Projection ***\n"); break; case 2: cc = 1; contrib = "_y"; if (m_bSplitCart) mprintf(WHITE,"\n *** Y Projection ***\n"); break; case 3: cc = 1; contrib = "_z"; if (m_bSplitCart) mprintf(WHITE,"\n *** Z Projection ***\n"); break; case 4: cc = 2; contrib = "_xy"; if (m_bSplitCart) mprintf(WHITE,"\n *** XY Projection ***\n"); break; case 5: cc = 2; contrib = "_xz"; if (m_bSplitCart) mprintf(WHITE,"\n *** XZ Projection ***\n"); break; case 6: cc = 2; contrib = "_yz"; if (m_bSplitCart) mprintf(WHITE,"\n *** YZ Projection ***\n"); break; } mprintf(" Calculating autocorrelation...\n"); try { acf = new CxDoubleArray(); } catch(...) { acf = NULL; } if(acf == NULL) NewException((double)sizeof(CxDoubleArray), __FILE__, __LINE__, __PRETTY_FUNCTION__); acf->SetSize(_correlationDepth); for(i = 0; i < _correlationDepth; i++) acf->GetAt(i) = 0.0; try { ac = new CAutoCorrelation(); } catch(...) { ac = NULL; } if(ac == NULL) NewException((double)sizeof(CAutoCorrelation), __FILE__, __LINE__, __PRETTY_FUNCTION__); ac->Init(n, _correlationDepth, g_bACFFFT); try { temp = new CxDoubleArray(); } catch(...) { temp = NULL; } if(temp == NULL) NewException((double)sizeof(CxDoubleArray), __FILE__, __LINE__, __PRETTY_FUNCTION__); temp->SetSize(n); try { temp2 = new CxDoubleArray(); } catch(...) { temp2 = NULL; } if(temp2 == NULL) NewException((double)sizeof(CxDoubleArray), __FILE__, __LINE__, __PRETTY_FUNCTION__); temp2->SetSize(_correlationDepth); mprintf(WHITE, " ["); if (m_iShowMol == -1) { for (i = 0; i < g_iGesAtomCount; i++) { if (fmod(i, step) < 1.0) mprintf(WHITE, "#"); for (j = 0; j < 3; j++) { switch(split) { case 0: break; case 1: if (j != 0) continue; break; case 2: if (j != 1) continue; break; case 3: if (j != 2) continue; break; case 4: if (j == 2) continue; break; case 5: if (j == 1) continue; break; case 6: if (j == 0) continue; break; } for(k = 0; k < n; k++) temp->GetAt(k) = ((CxDVec3Array *)_velocityCache[i])->GetAt(k)[j]; ac->AutoCorrelate(temp, temp2); for(k = 0; k < _correlationDepth; k++) acf->GetAt(k) += temp2->GetAt(k) * _masses[i]; } } } else { for(i = 0; i < m_iShowMolCount; i++) { for(j = 0; j < _atoms->m_iAtomGes; j++) { if(fmod(i * _atoms->m_iAtomGes + j, step) < 1.0) mprintf(WHITE, "#"); for(k = 0; k < 3; k++) { switch(split) { case 0: break; case 1: if (k != 0) continue; break; case 2: if (k != 1) continue; break; case 3: if (k != 2) continue; break; case 4: if (k == 2) continue; break; case 5: if (k == 1) continue; break; case 6: if (k == 0) continue; break; } for(l = 0; l < n; l++) temp->GetAt(l) = ((CxDVec3Array *)_velocityCache[i * _atoms->m_iAtomGes + j])->GetAt(l)[k]; ac->AutoCorrelate(temp, temp2); for(l = 0; l < _correlationDepth; l++) acf->GetAt(l) += temp2->GetAt(l) * _masses[i * _atoms->m_iAtomGes + j]; } } } } mprintf(WHITE, "]\n"); if (m_iShowMol != -1) for (i = 0; i < _correlationDepth; i++) acf->GetAt(i) /= (double)m_iShowMolCount; delete ac; delete temp2; if (_saveACF) { if (g_bPower) { #ifdef TARGET_LINUX snprintf(filename, BUF_SIZE, "power_acf%s_%s.csv", contrib, _name); #else sprintf(filename, "power_acf%s_%s.csv", contrib, _name); #endif } else { #ifdef TARGET_LINUX snprintf(filename, BUF_SIZE, "vacf%s_%s.csv", contrib, _name); #else sprintf(filename, "vacf%s_%s.csv", contrib, _name); #endif } mprintf(" Saving autocorrelation function as \"%s\"...\n", filename); acfFile = OpenFileWrite(filename, false); integral = 0; fprintf(acfFile, "#Correlation Depth [fs]; Velocity ACF [pm^2/ps^2]; Integral [pm^2/ps]\n"); for(i = 0; i < _correlationDepth; i++) { integral += acf->GetAt(i) * g_fTimestepLength / 1000.0; fprintf(acfFile, "%.2f; %.8G; %.8G\n", i * g_fTimestepLength, acf->GetAt(i), integral); } fclose(acfFile); } temp->CopyFrom(acf); if (_windowFunction == 1) { for(i = 0; i < temp->GetSize(); i++) temp->GetAt(i) *= pow2(cos((double)i / (temp->GetSize() - 1) / 2.0 * Pi)); } else if(_windowFunction == 2) { for(i = 0; i < temp->GetSize(); i++) temp->GetAt(i) *= exp(-(double)i / _windowFunctionParameter); } else if(_windowFunction == 3) { for(i = 0; i < temp->GetSize(); i++) temp->GetAt(i) *= exp(-(double)i * i / _windowFunctionParameter / _windowFunctionParameter); } else if(_windowFunction != 0) { eprintf("Unknown window function.\n"); abort(); } if (_saveACF && (_windowFunction != 0)) { if (g_bPower) { #ifdef TARGET_LINUX snprintf(filename, BUF_SIZE, "power_acf%s_windowed_%s.csv", contrib, _name); #else sprintf(filename, "power_acf%s_windowed_%s.csv", contrib, _name); #endif } else { #ifdef TARGET_LINUX snprintf(filename, BUF_SIZE, "vacf%s_windowed_%s.csv", contrib, _name); #else sprintf(filename, "vacf%s_windowed_%s.csv", contrib, _name); #endif } mprintf(" Saving windowed autocorrelation function as \"%s\"...\n", filename); acfFile = OpenFileWrite(filename, false); fprintf(acfFile, "#Correlation Depth [fs]; Windowed Velocity ACF [pm^2/ps^2]\n"); for(i = 0; i < m_iFinalDepth; i++) fprintf(acfFile, "%.2f; %.8G\n", i * g_fTimestepLength * g_iStride, temp->GetAt(i)); fclose(acfFile); } if (g_bPower) { if (_zeroPadding > 0) for(i = 0; i < _zeroPadding; i++) temp->Add(0.0); oldSize = temp->GetSize(); temp->SetSize(2 * oldSize); for (i = 1; i < oldSize; i++) temp->GetAt(oldSize + i) = temp->GetAt(oldSize - i); temp->GetAt(oldSize) = 0.0; mprintf(" Fourier transforming autocorrelation function...\n"); try { fft = new CFFT(); } catch(...) { fft = NULL; } if (fft == NULL) NewException((double)sizeof(CFFT), __FILE__, __LINE__, __PRETTY_FUNCTION__); fft->PrepareFFT_C2C(temp->GetSize()); for (i = 0; i < temp->GetSize(); i++) { fft->m_pInput[2*i] = temp->GetAt(i); fft->m_pInput[2*i+1] = 0.0; } fft->DoFFT(); try { spectrum = new CxDoubleArray(); } catch(...) { spectrum = NULL; } if (spectrum == NULL) NewException((double)sizeof(CxDoubleArray), __FILE__, __LINE__, __PRETTY_FUNCTION__); spectrum->SetSize(_specSize); for (i = 0; i < _specSize; i++) spectrum->GetAt(i) = 7.211349e-9 * fft->m_pOutput[2*i] * g_fTimestepLength * g_iStride; // Output in K*cm #ifdef TARGET_LINUX snprintf(filename, BUF_SIZE, "power_spectrum%s_%s.csv", contrib, _name); #else sprintf(filename, "power_spectrum%s_%s.csv", contrib, _name); #endif mprintf(" Saving spectrum as \"%s\"...\n", filename); specFile = OpenFileWrite(filename, false); fprintf(specFile, "#Wavenumber (cm^-1); Spectrum (K*cm); Integral (K)\n"); integral = 0.0; for(i = 0; i < _specSize; i++) { integral += (double)spectrum->GetAt(i) * _specResolution; fprintf(specFile, "%.2f; %.8G; %.14G\n", _specResolution * i, spectrum->GetAt(i), integral); } fclose(specFile); mprintf("\n"); if(m_iShowMol == -1) mprintf(" Assuming %dn = %d degrees of freedom, the average temperature is %.3f K.\n", cc, cc * g_iGesAtomCount, integral / (double(cc) * g_iGesAtomCount)); else mprintf(" Assuming %dn = %d degrees of freedom, the average temperature is %.3f K.\n", cc, cc * _atoms->m_iAtomGes, integral / (double(cc) * _atoms->m_iAtomGes)); delete fft; delete spectrum; } delete acf; delete temp; if (m_bSplitCart && (split < 6)) { split++; goto _beginsplit; } for(i = 0; i < _velocityCache.GetSize(); i++) delete (CxDVec3Array *)_velocityCache[i]; } bool gatherPowerSpectrum() { bool tb; CPowerObservation *obs; const char *fname, *fnameu; if (g_bPower) { fname = "power spectrum"; fnameu = "Power Spectrum"; } else { fname = "velocity autocorrelation"; fnameu = "Velocity Autocorrelation"; } g_bUseVelocities = true; if (AskYesNo("\n Compute global %s of whole system (y/n) [yes] ", true, fname)) { mprintf(YELLOW, "\n>>> Global %s >>>\n\n",fnameu); try { obs = new CPowerObservation(true); } catch(...) { obs = NULL; } if(obs == NULL) NewException((double)sizeof(CPowerObservation), __FILE__, __LINE__, __PRETTY_FUNCTION__); g_PowerObserv.Add(obs); mprintf(YELLOW, "<<< End of Global %s <<<\n\n",fnameu); tb = true; } else tb = false; if (tb) if (!AskYesNo(" Compute %s of certain atoms/molecules (y/n)? [no] ",false, fname)) return true; while(true) { mprintf(YELLOW, "\n>>> %s %d >>>\n\n", fnameu, g_PowerObserv.GetSize() + 1); try { obs = new CPowerObservation(); } catch(...) { obs = NULL; } if(obs == NULL) NewException((double)sizeof(CPowerObservation), __FILE__, __LINE__, __PRETTY_FUNCTION__); g_PowerObserv.Add(obs); mprintf(YELLOW, "<<< End of %s %d <<<\n\n", fnameu, g_PowerObserv.GetSize()); if(!AskYesNo(" Add another %s observation (y/n)? [no] ", false, fname)) break; mprintf("\n"); } return true; } bool initializePowerSpectrum() { int i; for(i = 0; i < g_PowerObserv.GetSize(); i++) { ((CPowerObservation *)g_PowerObserv[i])->initialize(); } // int n; // if(g_iTrajSteps != -1) // n = (int)(1.1 * g_iTrajSteps / g_iStride); // else // n = 10000; // // mprintf(" Temperature cache: Trying to allocate %s of memory...\n", FormatBytes((double)g_iGesAtomCount * n * sizeof(double))); // g_TemperatureCache.SetMaxSize(n); // g_TemperatureCache.SetGrow(n / 10); return true; } void processPowerSpectrum(CTimeStep* ts) { int i; for(i = 0; i < g_PowerObserv.GetSize(); i++) { ((CPowerObservation *)g_PowerObserv[i])->process(ts); } // double temperature = 0.0f; // for (i = 0; i < g_iGesAtomCount; i++) { // temperature += ts->m_vaVelocities[i].GetLengthSqr() * ((CAtom *)g_oaAtoms[g_waAtomRealElement[i]])->m_pElement->m_fMass; // } // temperature /= (3.0f * g_iGesAtomCount * 8314.4621f); // g_TemperatureCache.Add(temperature); } void finalizePowerSpectrum() { int i; const char *fnameu; if (g_bPower) fnameu = "Power Spectrum"; else fnameu = "Velocity Autocorrelation"; for(i = 0; i < g_PowerObserv.GetSize(); i++) { mprintf(YELLOW, "\n>>> %s %d >>>\n\n", fnameu, i+1); ((CPowerObservation *)g_PowerObserv[i])->finalize(); delete (CPowerObservation *)g_PowerObserv[i]; mprintf(YELLOW, "\n<<< End of %s %d <<<\n\n", fnameu, i+1); } // CxString filename; // filename.sprintf("temperature.csv"); // mprintf(" Saving temperature as %s...\n", (const char *)filename); // FILE *tempFile = OpenFileWrite(filename, false); // fprintf(tempFile, "#Time (fs); Temperature (K)\n"); // double average = 0.0; // for(i = 0; i < g_TemperatureCache.GetSize(); i++) { // average += (double)g_TemperatureCache[i]; // fprintf(tempFile, "%.2f; %.8G\n", g_fTimestepLength * i, g_TemperatureCache[i]); // } // fclose(tempFile); // average /= g_TemperatureCache.GetSize(); // // mprintf("\n The average temperature is %.2f K\n", average); } static CxObArray g_IRObserv; CIRObservation::CIRObservation(bool global) { int i; if(global) { m_iShowMol = -1; m_iShowMolCount = g_oaSingleMolecules.GetSize(); _name = new char[7]; sprintf(_name, "global"); } else { char buf[BUF_SIZE]; char buf2[BUF_SIZE]; size_t remaining = BUF_SIZE; if(g_oaMolecules.GetSize() > 1) { #ifdef TARGET_LINUX remaining -= snprintf(buf, remaining, " Which molecule should be observed ("); #else remaining -= sprintf(buf, " Which molecule should be observed ("); #endif for(i = 0; i < g_oaMolecules.GetSize(); i++) { if(remaining < 1) break; #ifdef TARGET_LINUX size_t length = snprintf(buf2, remaining, "%s=%d", ((CMolecule *)g_oaMolecules[i])->m_sName, i+1); #else size_t length = sprintf(buf2, "%s=%d", ((CMolecule *)g_oaMolecules[i])->m_sName, i+1); #endif strncat(buf, buf2, remaining - 1); remaining -= length; if(i < g_oaMolecules.GetSize() - 1) { #ifdef TARGET_LINUX length = snprintf(buf2, remaining, ", "); #else length = sprintf(buf2, ", "); #endif strncat(buf, buf2, remaining - 1); remaining -= length; } } strncat(buf, ")? ", remaining - 1); m_iShowMol = AskRangeInteger_ND("%s", 1, g_oaMolecules.GetSize(),(const char*)buf) - 1; } else { m_iShowMol = 0; mprintf(" Observing molecule %s.\n", ((CMolecule *)g_oaMolecules[m_iShowMol])->m_sName); } m_iShowMolCount = ((CMolecule *)g_oaMolecules[m_iShowMol])->m_laSingleMolIndex.GetSize(); _name = new char[strlen(((CMolecule *)g_oaMolecules[m_iShowMol])->m_sName) + 1]; strcpy(_name, ((CMolecule *)g_oaMolecules[m_iShowMol])->m_sName); mprintf("\n"); } if(g_iTrajSteps != -1) { _correlationDepth = (int)(0.75 * g_iTrajSteps); if(_correlationDepth > 4096) _correlationDepth = 4096; if(g_fTimestepLength > 1.0) _correlationDepth = 2048; if(g_fTimestepLength > 2.0) _correlationDepth = 1024; _correlationDepth = AskUnsignedInteger(" Enter the resolution (=depth) of the ACF (in time steps): [%d] ", _correlationDepth, _correlationDepth); } else { _correlationDepth = AskUnsignedInteger(" Enter the resolution (=depth) of the ACF (in time steps): [256] ", 256); } int size = CalcFFTSize(_correlationDepth, false); if(_correlationDepth != size) { mprintf(WHITE, " The next \"fast\" size for FFT is %d. Using this instead of %d as depth.\n", size, _correlationDepth); _correlationDepth = size; } if(g_bAdvanced2) { _windowFunction = AskRangeInteger(" Window function: cos^2(a*t) (1), exp(-t/a) (2), exp(-(t/a)^2) (3) [1] ", 1, 3, 1); if(_windowFunction == 1) { mprintf(" The parameter \"a\" is chosen according to the correlation depth.\n"); _windowFunctionParameter = 0; } else if(_windowFunction == 2) { _windowFunctionParameter = AskUnsignedInteger(" Parameter \"a\" (in time steps): [%d] ", _correlationDepth / 4, _correlationDepth / 4); } else if(_windowFunction == 3) { _windowFunctionParameter = AskUnsignedInteger(" Parameter \"a\" (in time steps): [%d] ", _correlationDepth / 2, _correlationDepth / 2); } else { eprintf("This is impossible.\n"); abort(); } } else { _windowFunction = 1; _windowFunctionParameter = 0; mprintf(" Using cos^2 window function.\n"); } if(g_bAdvanced2) { _zeroPadding = AskUnsignedInteger(" Zero Padding: How many zeros to insert? [%d] ", _correlationDepth * 3, _correlationDepth * 3); size = CalcFFTSize(_correlationDepth + _zeroPadding, false); if(_correlationDepth + _zeroPadding != size) { mprintf(WHITE, " The next \"fast\" size for FFT is %d. Using %d zeros for zero padding.\n", size, size-_correlationDepth); _zeroPadding = size-_correlationDepth; } } else { _zeroPadding = _correlationDepth * 3; size = CalcFFTSize(_correlationDepth + _zeroPadding, false); if(_correlationDepth + _zeroPadding != size) { mprintf(WHITE, " The next \"fast\" size for FFT is %d. Using %d zeros for zero padding.\n", size, size-_correlationDepth); _zeroPadding = size-_correlationDepth; } mprintf(" Inserting %d zeros for zero padding.\n",_zeroPadding); } double possibleRange = 33356.41 / g_fTimestepLength / 2.0; _specResolution = possibleRange / (_correlationDepth + _zeroPadding); mprintf(" This results in a spectral resolution of %.2f cm^-1.\n", _specResolution); mprintf("\n A time step length of %.2f fs allows a spectral range up to %.2f cm^-1.\n", g_fTimestepLength, possibleRange); double specLimit = AskRangeFloat("\n Calculate spectrum up to which wave number (cm^-1)? [%.2f cm^-1] ", 0, possibleRange, (possibleRange < 5000.0) ? possibleRange : 5000.0, (possibleRange < 5000.0) ? possibleRange : 5000.0); _specSize = (int)(specLimit / _specResolution); mprintf("\n"); if(g_bAdvanced2) { _finiteDifferenceCorrection = AskYesNo(" Apply finite difference correction (y/n)? [yes] ", true); mprintf("\n"); } else { _finiteDifferenceCorrection = true; } if(g_bAdvanced2) { _saveACF = AskYesNo(" Save autocorrelation function (y/n)? [no] ", false); mprintf("\n"); } else { _saveACF = false; } if(g_bAdvanced2 && m_iShowMol == -1) { _includeCross = AskYesNo(" Include also cross-correlations (y/n)? [no] ", false); mprintf("\n"); } else { _includeCross = false; } } CIRObservation::~CIRObservation() { delete[] _name; } void CIRObservation::initialize() { int n; if(g_iTrajSteps != -1) n = (int)(1.1 * g_iTrajSteps / g_iStride); else n = 10000; mprintf(" Moment cache: Trying to allocate %s of memory...\n", FormatBytes((double)m_iShowMolCount * n * sizeof(CxDVector3))); int i; for(i = 0; i < m_iShowMolCount; i++) { CxDVec3Array *a; try { a = new CxDVec3Array(); } catch(...) { a = NULL; } if(a == NULL) NewException((double)sizeof(CxDVec3Array), __FILE__, __LINE__, __PRETTY_FUNCTION__); a->SetMaxSize(n); a->SetGrow(n / 10); _dipoleCache.Add(a); } } void CIRObservation::process() { int i; if(m_iShowMol == -1) { for(i = 0; i < m_iShowMolCount; i++) { CSingleMolecule *sm = (CSingleMolecule *)g_oaSingleMolecules[i]; ((CxDVec3Array *)_dipoleCache[i])->Add(sm->m_vDipole); } } else { for(i = 0; i < m_iShowMolCount; i++) { CSingleMolecule *sm = (CSingleMolecule *)g_oaSingleMolecules[((CMolecule *)g_oaMolecules[m_iShowMol])->m_laSingleMolIndex[i]]; ((CxDVec3Array *)_dipoleCache[i])->Add(sm->m_vDipole); } } } void CIRObservation::finalize() { int n = ((CxDVec3Array *)_dipoleCache[0])->GetSize() - 2; double step = (double)m_iShowMolCount / 20.0; if (n < _correlationDepth) { eprintf("\nError: Autocorrelation depth is %d, but only %d timesteps evaluated.\n",_correlationDepth,n); eprintf(" Reduce depth or increase trajectory length.\n\n"); abort(); } mprintf(" Deriving dipole moments...\n"); mprintf(WHITE, " ["); int i, j, k, l; for(i = 0; i < m_iShowMolCount; i++) { if(fmod(i, step) < 1.0) mprintf(WHITE, "#"); for(j = 0; j < n; j++) { ((CxDVec3Array *)_dipoleCache[i])->GetAt(j) = 0.5 * (((CxDVec3Array *)_dipoleCache[i])->GetAt(j+2) - ((CxDVec3Array *)_dipoleCache[i])->GetAt(j)) / g_fTimestepLength; } } mprintf(WHITE, "]\n"); mprintf(" Calculating autocorrelation...\n"); CxDoubleArray *acf; try { acf = new CxDoubleArray(); } catch(...) { acf = NULL; } if(acf == NULL) NewException((double)sizeof(CxDoubleArray), __FILE__, __LINE__, __PRETTY_FUNCTION__); acf->SetSize(_correlationDepth); for(i = 0; i < _correlationDepth; i++) { acf->GetAt(i) = 0.0; } CAutoCorrelation *ac; try { ac = new CAutoCorrelation(); } catch(...) { ac = NULL; } if(ac == NULL) NewException((double)sizeof(CAutoCorrelation), __FILE__, __LINE__, __PRETTY_FUNCTION__); ac->Init(n, _correlationDepth, g_bACFFFT); CxDoubleArray *temp; try { temp = new CxDoubleArray(); } catch(...) { temp = NULL; } if(temp == NULL) NewException((double)sizeof(CxDoubleArray), __FILE__, __LINE__, __PRETTY_FUNCTION__); temp->SetSize(n); CxDoubleArray *temp2; try { temp2 = new CxDoubleArray(); } catch(...) { temp2 = NULL; } if(temp2 == NULL) NewException((double)sizeof(CxDoubleArray), __FILE__, __LINE__, __PRETTY_FUNCTION__); temp2->SetSize(n); mprintf(WHITE, " ["); for(i = 0; i < m_iShowMolCount; i++) { if(fmod(i, step) < 1.0) mprintf(WHITE, "#"); for(j = 0; j < 3; j++) { for(k = 0; k < n; k++) { temp->GetAt(k) = ((CxDVec3Array *)_dipoleCache[i])->GetAt(k)[j]; } ac->AutoCorrelate(temp, temp2); for(k = 0; k < _correlationDepth; k++) { acf->GetAt(k) += temp2->GetAt(k); } } } mprintf(WHITE, "]\n"); // if(m_iShowMol == -1) { // for(i = 0; i < _correlationDepth; i++) { // acf->GetAt(i) /= 3.0f; // } // } else { // for(i = 0; i < _correlationDepth; i++) { // acf->GetAt(i) /= 3.0f * m_iShowMolCount; // } // } // The 3.0f is included in the final normalization if(m_iShowMol != -1) { for(i = 0; i < _correlationDepth; i++) { acf->GetAt(i) /= (double)m_iShowMolCount; } } delete ac; CxDoubleArray *ccf = NULL; if(_includeCross) { mprintf(" Calculating cross-correlation...\n"); try { ccf = new CxDoubleArray(); } catch(...) { ccf = NULL; } if(ccf == NULL) NewException((double)sizeof(CxDoubleArray), __FILE__, __LINE__, __PRETTY_FUNCTION__); ccf->SetSize(_correlationDepth); for(i = 0; i < _correlationDepth; i++) { ccf->GetAt(i) = 0.0; } CCrossCorrelation *cc; try { cc = new CCrossCorrelation(); } catch(...) { cc = NULL; } if(cc == NULL) NewException((double)sizeof(CCrossCorrelation), __FILE__, __LINE__, __PRETTY_FUNCTION__); cc->Init(n, _correlationDepth, g_bACFFFT); CxDoubleArray *temp3; try { temp3 = new CxDoubleArray(); } catch(...) { temp3 = NULL; } if(temp3 == NULL) NewException((double)sizeof(CxDoubleArray), __FILE__, __LINE__, __PRETTY_FUNCTION__); temp3->SetSize(n); temp->SetSize(n); temp2->SetSize(n); mprintf(WHITE, " ["); step = (double)m_iShowMolCount * (m_iShowMolCount - 1) / 20.0; int c = 0; for(i = 0; i < m_iShowMolCount; i++) { for(j = 0; j < m_iShowMolCount; j++) { if (i == j) continue; if(fmod((double)c++, step) < 1.0) mprintf(WHITE, "#"); for(k = 0; k < 3; k++) { for(l = 0; l < n; l++) { temp->GetAt(l) = ((CxDVec3Array *)_dipoleCache[i])->GetAt(l)[k]; temp2->GetAt(l) = ((CxDVec3Array *)_dipoleCache[j])->GetAt(l)[k]; } cc->CrossCorrelate(temp, temp2, temp3); for(l = 0; l < _correlationDepth; l++) { ccf->GetAt(l) += temp3->GetAt(l); } } } } mprintf(WHITE, "]\n"); // for(i = 0; i < _correlationDepth; i++) { // ccf->GetAt(i) /= 3.0f; // } delete cc; delete temp3; } delete temp2; if(_saveACF) { char filename[BUF_SIZE]; #ifdef TARGET_LINUX snprintf(filename, BUF_SIZE, "ir_acf_%s.csv", _name); #else sprintf(filename, "ir_acf_%s.csv", _name); #endif mprintf(" Saving autocorrelation function as %s...\n", filename); FILE *acfFile = OpenFileWrite(filename, false); for(i = 0; i < _correlationDepth; i++) { fprintf(acfFile, "%.2f; %.10G\n", i * g_fTimestepLength, acf->GetAt(i)); } fclose(acfFile); } temp->CopyFrom(acf); if(_windowFunction == 1) { for(i = 0; i < temp->GetSize(); i++) { temp->GetAt(i) *= pow2(cos((double)i / (temp->GetSize() - 1) / 2.0 * Pi)); } } else if(_windowFunction == 2) { for(i = 0; i < temp->GetSize(); i++) { temp->GetAt(i) *= exp(-(double)i / _windowFunctionParameter); } } else if(_windowFunction == 3) { for(i = 0; i < temp->GetSize(); i++) { temp->GetAt(i) *= exp(-(double)i * i / _windowFunctionParameter / _windowFunctionParameter); } } else if(_windowFunction != 0) { eprintf("Unknown window function.\n"); abort(); } if(_saveACF) { char filename[BUF_SIZE]; #ifdef TARGET_LINUX snprintf(filename, BUF_SIZE, "ir_acf_windowed_%s.csv", _name); #else sprintf(filename, "ir_acf_windowed_%s.csv", _name); #endif mprintf(" Saving windowed autocorrelation function as %s...\n", filename); FILE *acfFile = OpenFileWrite(filename, false); for(i = 0; i < _correlationDepth; i++) { fprintf(acfFile, "%.2f; %.10G\n", i * g_fTimestepLength, temp->GetAt(i)); } fclose(acfFile); } if(_zeroPadding > 0) { for(i = 0; i < _zeroPadding; i++) { temp->Add(0.0); } } int oldSize = temp->GetSize(); temp->SetSize(2 * oldSize); for(i = 1; i < oldSize; i++) { temp->GetAt(oldSize + i) = temp->GetAt(oldSize - i); } temp->GetAt(oldSize) = 0.0; mprintf(" Fourier transforming autocorrelation function...\n"); CFFT *fft; try { fft = new CFFT(); } catch(...) { fft = NULL; } if(fft == NULL) NewException((double)sizeof(CFFT), __FILE__, __LINE__, __PRETTY_FUNCTION__); fft->PrepareFFT_C2C(temp->GetSize()); for(i = 0; i < temp->GetSize(); i++) { fft->m_pInput[2*i] = temp->GetAt(i); fft->m_pInput[2*i+1] = 0.0; } fft->DoFFT(); CxDoubleArray *spectrum; try { spectrum = new CxDoubleArray(); } catch(...) { spectrum = NULL; } if(spectrum == NULL) NewException((double)sizeof(CxDoubleArray), __FILE__, __LINE__, __PRETTY_FUNCTION__); spectrum->SetSize(_specSize); for(i = 0; i < _specSize; i++) { spectrum->GetAt(i) = 3047.2310 * fft->m_pOutput[2*i] * g_fTimestepLength; // Output in K*cm*km/mol } if(_finiteDifferenceCorrection) { double f = _specResolution * g_fTimestepLength * 1.883652e-4; for(i = 1; i < _specSize; i++) { spectrum->GetAt(i) *= pow2(f * i / sin(f * i)); // Divide by sinc function to correct finite difference derivation } } if(_includeCross) { char filename[BUF_SIZE]; #ifdef TARGET_LINUX snprintf(filename, BUF_SIZE, "ir_spectrum_auto_%s.csv", _name); #else sprintf(filename, "ir_spectrum_auto_%s.csv", _name); #endif mprintf(" Saving autocorrelation spectrum as %s...\n", filename); FILE *specFile = OpenFileWrite(filename, false); fprintf(specFile, "#Wavenumber (cm^-1); Spectrum (K*cm*km*mol^-1); Integral (K*km*mol^-1)\n"); double integral = 0.0; for(i = 0; i < _specSize; i++) { integral += (double)spectrum->GetAt(i) * _specResolution; fprintf(specFile, "%.2f; %.8G; %.14G\n", _specResolution * i, spectrum->GetAt(i), integral); } fclose(specFile); if(_saveACF) { //char filename[BUF_SIZE]; #ifdef TARGET_LINUX snprintf(filename, BUF_SIZE, "ir_ccf_%s.csv", _name); #else sprintf(filename, "ir_ccf_%s.csv", _name); #endif mprintf(" Saving cross-correlation function as %s...\n", filename); FILE *ccfFile = OpenFileWrite(filename, false); for(i = 0; i < _correlationDepth; i++) { fprintf(ccfFile, "%.2f; %.10G\n", i * g_fTimestepLength, ccf->GetAt(i)); } fclose(ccfFile); } temp->CopyFrom(ccf); if(_windowFunction == 1) { for(i = 0; i < temp->GetSize(); i++) { temp->GetAt(i) *= pow2(cos((double)i / temp->GetSize() / 2.0 * Pi)); } } else if(_windowFunction == 2) { for(i = 0; i < temp->GetSize(); i++) { temp->GetAt(i) *= exp(-(double)i / _windowFunctionParameter); } } else if(_windowFunction == 3) { for(i = 0; i < temp->GetSize(); i++) { temp->GetAt(i) *= exp(-(double)i * i / _windowFunctionParameter / _windowFunctionParameter); } } else if(_windowFunction != 0) { eprintf("Unknown window function.\n"); abort(); } if(_saveACF) { //char filename[BUF_SIZE]; #ifdef TARGET_LINUX snprintf(filename, BUF_SIZE, "ir_ccf_windowed_%s.csv", _name); #else sprintf(filename, "ir_ccf_windowed_%s.csv", _name); #endif mprintf(" Saving windowed cross-correlation function as %s...\n", filename); FILE *ccfFile = OpenFileWrite(filename, false); for(i = 0; i < _correlationDepth; i++) { fprintf(ccfFile, "%.2f; %.10G\n", i * g_fTimestepLength, ccf->GetAt(i)); } fclose(ccfFile); } if(_zeroPadding > 0) { for(i = 0; i < _zeroPadding; i++) { temp->Add(0.0); } } //int oldSize = temp->GetSize(); oldSize = temp->GetSize(); temp->SetSize(2 * oldSize); for(i = 1; i < oldSize; i++) { temp->GetAt(oldSize + i) = temp->GetAt(oldSize - i); } temp->GetAt(oldSize) = 0.0; mprintf(" Fourier transforming cross-correlation function...\n"); fft->PrepareFFT_C2C(temp->GetSize()); for(i = 0; i < temp->GetSize(); i++) { fft->m_pInput[2*i] = temp->GetAt(i); fft->m_pInput[2*i+1] = 0.0; } fft->DoFFT(); CxDoubleArray *ccSpectrum; try { ccSpectrum = new CxDoubleArray(); } catch(...) { ccSpectrum = NULL; } if(ccSpectrum == NULL) NewException((double)sizeof(CxDoubleArray), __FILE__, __LINE__, __PRETTY_FUNCTION__); ccSpectrum->SetSize(_specSize); for(i = 0; i < _specSize; i++) { ccSpectrum->GetAt(i) = 3047.2310 * fft->m_pOutput[2*i] * g_fTimestepLength; } #ifdef TARGET_LINUX snprintf(filename, BUF_SIZE, "ir_spectrum_cross_%s.csv", _name); #else sprintf(filename, "ir_spectrum_cross_%s.csv", _name); #endif mprintf(" Saving cross-correlation spectrum as %s...\n", filename); specFile = OpenFileWrite(filename, false); fprintf(specFile, "#Wavenumber (cm^-1); Spectrum (K*cm*km*mol^-1); Integral (K*km*mol^-1)\n"); integral = 0.0; for(i = 0; i < _specSize; i++) { integral += ccSpectrum->GetAt(i) * _specResolution; fprintf(specFile, "%.2f; %.8G; %.14G\n", _specResolution * i, ccSpectrum->GetAt(i), integral); } fclose(specFile); for(i = 0; i < _specSize; i++) { spectrum->GetAt(i) += ccSpectrum->GetAt(i); } delete ccSpectrum; } char filename[BUF_SIZE]; #ifdef TARGET_LINUX snprintf(filename, BUF_SIZE, "ir_spectrum_%s.csv", _name); #else sprintf(filename, "ir_spectrum_%s.csv", _name); #endif mprintf(" Saving spectrum as %s...\n", filename); FILE *specFile = OpenFileWrite(filename, false); fprintf(specFile, "#Wavenumber (cm^-1); Spectrum (K*cm*km*mol^-1); Integral (K*km*mol^-1)\n"); double integral = 0.0; for(i = 0; i < _specSize; i++) { integral += spectrum->GetAt(i) * _specResolution; fprintf(specFile, "%.2f; %.8G; %.14G\n", _specResolution * i, spectrum->GetAt(i), integral); } fclose(specFile); delete acf; if(_includeCross) { delete ccf; } delete temp; delete fft; delete spectrum; for(i = 0; i < _dipoleCache.GetSize(); i++) delete (CxDVec3Array *)_dipoleCache[i]; } bool gatherIR() { g_bDipole = true; ParseDipole(); while(true) { mprintf(YELLOW, "\n>>> IR Observation %d >>>\n\n", g_IRObserv.GetSize() + 1); CIRObservation *obs; try { obs = new CIRObservation(); } catch(...) { obs = NULL; } if(obs == NULL) NewException((double)sizeof(CIRObservation), __FILE__, __LINE__, __PRETTY_FUNCTION__); g_IRObserv.Add(obs); mprintf(YELLOW, "<<< End of IR Observation %d <<<\n\n", g_IRObserv.GetSize()); if(!AskYesNo(" Add another observation (y/n)? [no] ", false)) break; mprintf("\n"); } if(AskYesNo("\n Compute IR spectrum of whole system (y/n) [no] ", false)) { mprintf(YELLOW, "\n>>> Global IR Observation >>>\n\n"); CIRObservation *obs; try { obs = new CIRObservation(true); } catch(...) { obs = NULL; } if(obs == NULL) NewException((double)sizeof(CIRObservation), __FILE__, __LINE__, __PRETTY_FUNCTION__); g_IRObserv.Add(obs); mprintf(YELLOW, "<<< End of Global IR Observation <<<\n\n"); } return true; } bool initializeIR() { int i; for(i = 0; i < g_IRObserv.GetSize(); i++) { ((CIRObservation *)g_IRObserv[i])->initialize(); } return true; } void processIR(CTimeStep* ts) { UNUSED(ts); int i; for(i = 0; i < g_IRObserv.GetSize(); i++) { ((CIRObservation *)g_IRObserv[i])->process(); } } void finalizeIR() { int i; for(i = 0; i < g_IRObserv.GetSize(); i++) { mprintf(YELLOW, "\n>>> IR Observation %d >>>\n\n", i+1); ((CIRObservation *)g_IRObserv[i])->finalize(); delete (CIRObservation *)g_IRObserv[i]; mprintf(YELLOW, "\n<<< End of IR Observation %d <<<\n\n", i+1); } } static FILE *g_dipoleRestartFile = NULL; bool gatherDipoleRestart() { g_bDipole = true; ParseDipole(); mprintf(YELLOW, "\n>>> Dipole Restart File >>>\n\n"); CxString filename; AskString(" Enter name of dipole restart file to write: [dipole.restart] ", &filename, "dipole.restart"); g_dipoleRestartFile = OpenFileWrite((const char *)filename, false); int numMolecules = g_oaSingleMolecules.GetSize(); fwrite(&numMolecules, sizeof(int), 1, g_dipoleRestartFile); mprintf(YELLOW, "\n<<< End of Dipole Restart File <<<\n\n"); return true; } bool initializeDipoleRestart() { return true; } void processDipoleRestart(CTimeStep *ts) { UNUSED(ts); int i; for (i = 0; i < g_oaSingleMolecules.GetSize(); i++) { CSingleMolecule *sm = (CSingleMolecule *)g_oaSingleMolecules[i]; int j; for (j = 0; j < 3; j++) { double val = sm->m_vDipole[j]; fwrite(&val, sizeof(double), 1, g_dipoleRestartFile); } } fflush(g_dipoleRestartFile); } void finalizeDipoleRestart() { if (g_dipoleRestartFile != NULL) fclose(g_dipoleRestartFile); } static CxObArray g_VCDObserv; CVCDObservation::CVCDObservation(bool global) { int i; if(global) { m_iShowMol = -1; m_iShowMolCount = g_oaSingleMolecules.GetSize(); _name = new char[7]; sprintf(_name, "global"); } else { char buf[BUF_SIZE]; char buf2[BUF_SIZE]; size_t remaining = BUF_SIZE; if(g_oaMolecules.GetSize() > 1) { #ifdef TARGET_LINUX remaining -= snprintf(buf, remaining, " Which molecule should be observed ("); #else remaining -= sprintf(buf, " Which molecule should be observed ("); #endif for(i = 0; i < g_oaMolecules.GetSize(); i++) { if(remaining < 1) break; #ifdef TARGET_LINUX size_t length = snprintf(buf2, remaining, "%s=%d", ((CMolecule *)g_oaMolecules[i])->m_sName, i+1); #else size_t length = sprintf(buf2, "%s=%d", ((CMolecule *)g_oaMolecules[i])->m_sName, i+1); #endif strncat(buf, buf2, remaining - 1); remaining -= length; if(i < g_oaMolecules.GetSize() - 1) { #ifdef TARGET_LINUX length = snprintf(buf2, remaining, ", "); #else length = sprintf(buf2, ", "); #endif strncat(buf, buf2, remaining - 1); remaining -= length; } } strncat(buf, ")? ", remaining - 1); m_iShowMol = AskRangeInteger_ND("%s", 1, g_oaMolecules.GetSize(),(const char*)buf) - 1; } else { m_iShowMol = 0; } m_iShowMolCount = ((CMolecule *)g_oaMolecules[m_iShowMol])->m_laSingleMolIndex.GetSize(); _name = new char[strlen(((CMolecule *)g_oaMolecules[m_iShowMol])->m_sName) + 1]; strcpy(_name, ((CMolecule *)g_oaMolecules[m_iShowMol])->m_sName); mprintf("\n"); } if(g_iTrajSteps != -1) { _correlationDepth = (int)(0.75 * g_iTrajSteps); if(_correlationDepth > 4096) _correlationDepth = 4096; if(g_fTimestepLength > 1.0) _correlationDepth = 2048; if(g_fTimestepLength > 2.0) _correlationDepth = 1024; _correlationDepth = AskUnsignedInteger(" Enter the resolution (=depth) of the ACF (in time steps): [%d] ", _correlationDepth, _correlationDepth); } else { _correlationDepth = AskUnsignedInteger(" Enter the resolution (=depth) of the ACF (in time steps): [256] ", 256); } int size = CalcFFTSize(_correlationDepth, false); if(_correlationDepth != size) { mprintf(WHITE, " The next \"fast\" size for FFT is %d. Using this instead of %d as depth.\n", size, _correlationDepth); _correlationDepth = size; } if(g_bAdvanced2) { _windowFunction = AskRangeInteger(" Window function: cos^2(a*t) (1), exp(-t/a) (2), exp(-(t/a)^2) (3) [1] ", 1, 3, 1); if(_windowFunction == 1) { mprintf(" The parameter \"a\" is chosen according to the correlation depth.\n"); _windowFunctionParameter = 0; } else if(_windowFunction == 2) { _windowFunctionParameter = AskUnsignedInteger(" Parameter \"a\" (in time steps): [%d] ", _correlationDepth / 4, _correlationDepth / 4); } else if(_windowFunction == 3) { _windowFunctionParameter = AskUnsignedInteger(" Parameter \"a\" (in time steps): [%d] ", _correlationDepth / 2, _correlationDepth / 2); } else { eprintf("This is impossible.\n"); abort(); } } else { _windowFunction = 1; _windowFunctionParameter = 0; mprintf(" Using cos^2 window function.\n"); } if(g_bAdvanced2) { _zeroPadding = AskUnsignedInteger(" Zero Padding: How many zeros to insert? [%d] ", _correlationDepth * 3, _correlationDepth * 3); size = CalcFFTSize(_correlationDepth + _zeroPadding, false); if(_correlationDepth + _zeroPadding != size) { mprintf(WHITE, " The next \"fast\" size for FFT is %d. Using %d zeros for zero padding.\n", size, size-_correlationDepth); _zeroPadding = size-_correlationDepth; } } else { _zeroPadding = _correlationDepth * 3; size = CalcFFTSize(_correlationDepth + _zeroPadding, false); if(_correlationDepth + _zeroPadding != size) { mprintf(WHITE, " The next \"fast\" size for FFT is %d. Using %d zeros for zero padding.\n", size, size-_correlationDepth); _zeroPadding = size-_correlationDepth; } mprintf(" Inserting %d zeros for zero padding.\n",_zeroPadding); } double possibleRange = 33356.41 / g_fTimestepLength / 2.0; _specResolution = possibleRange / (_correlationDepth + _zeroPadding); mprintf(" This results in a spectral resolution of %.2f cm^-1.\n", _specResolution); mprintf("\n A time step length of %.2f fs allows a spectral range up to %.2f cm^-1.\n", g_fTimestepLength, possibleRange); double specLimit = AskRangeFloat("\n Calculate spectrum up to which wave number (cm^-1)? [%.2f cm^-1] ", 0, possibleRange, (possibleRange < 5000.0) ? possibleRange : 5000.0, (possibleRange < 5000.0) ? possibleRange : 5000.0); _specSize = (int)(specLimit / _specResolution); mprintf("\n"); if(g_bAdvanced2) { _smoothWidth = AskUnsignedInteger(" Window width of median filter to smooth magnetic dipole moments: [0] ", 0); mprintf("\n"); } else { _smoothWidth = 0; } if(g_bAdvanced2) { _saveMoments = AskYesNo(" Save electric and magnetic moments (y/n)? [no] ", false); } else { _saveMoments = false; } if(g_bAdvanced2) { _saveACF = AskYesNo(" Save cross-correlation function (y/n)? [no] ", false); mprintf("\n"); } else { _saveACF = false; } } CVCDObservation::~CVCDObservation() { delete[] _name; } void CVCDObservation::initialize() { int n; if(g_iTrajSteps != -1) n = (int)(1.1 * g_iTrajSteps / g_iStride); else n = 10000; mprintf(" Moment cache: Trying to allocate %s of memory...\n", FormatBytes((double)m_iShowMolCount * 2.0 * n * sizeof(CxDVector3))); int i; for(i = 0; i < m_iShowMolCount; i++) { CxDVec3Array *a, *b; try { a = new CxDVec3Array(); } catch(...) { a = NULL; } if(a == NULL) NewException((double)sizeof(CxDVec3Array), __FILE__, __LINE__, __PRETTY_FUNCTION__); try { b = new CxDVec3Array(); } catch(...) { b = NULL; } if(b == NULL) NewException((double)sizeof(CxDVec3Array), __FILE__, __LINE__, __PRETTY_FUNCTION__); a->SetMaxSize(n); a->SetGrow(n / 10); b->SetMaxSize(n); b->SetGrow(n / 10); _electricDipoleCache.Add(a); _magneticDipoleCache.Add(b); } } void CVCDObservation::process() { int i; for(i = 0; i < m_iShowMolCount; i++) { CSingleMolecule *sm = (CSingleMolecule *)g_oaSingleMolecules[((CMolecule *)g_oaMolecules[m_iShowMol])->m_laSingleMolIndex[i]]; ((CxDVec3Array *)_electricDipoleCache[i])->Add(sm->m_vDipole); ((CxDVec3Array *)_magneticDipoleCache[i])->Add(sm->m_vMagneticDipole); } } static int compare_double(const void *f1, const void *f2) { if(*(double *)f1 < *(double *)f2) return -1; if(*(double *)f1 > *(double *)f2) return 1; return 0; } void CVCDObservation::finalize() { int i, j, k, l; if(_smoothWidth > 0) { mprintf(" Smoothing magnetic dipole moments...\n"); CxDVec3Array *tempMoments; try { tempMoments = new CxDVec3Array(); } catch(...) { tempMoments = NULL; } if(tempMoments == NULL) NewException((double)sizeof(CxDVec3Array), __FILE__, __LINE__, __PRETTY_FUNCTION__); double *sortArray; try { sortArray = new double[2*_smoothWidth+1]; } catch(...) { sortArray = NULL; } if(sortArray == NULL) NewException((double)_smoothWidth * sizeof(double), __FILE__, __LINE__, __PRETTY_FUNCTION__); for(i = 0; i < m_iShowMolCount; i++) { tempMoments->SetSize(((CxDVec3Array *)_magneticDipoleCache[i])->GetSize()); for(j = 0; j < tempMoments->GetSize(); j++) { for(k = 0; k < 3; k++) { int index = 0; for(l = j - _smoothWidth; l <= j + _smoothWidth; l++) { if(l < 0) continue; if(l >= tempMoments->GetSize()) break; sortArray[index] = ((CxDVec3Array *)_magneticDipoleCache[i])->GetAt(l)[k]; index++; } qsort(sortArray, index, sizeof(double), compare_double); if(index % 2 == 0) { tempMoments->GetAt(j)[k] = (sortArray[index / 2] + sortArray[index / 2 - 1]) / 2.0; } else { tempMoments->GetAt(j)[k] = sortArray[index / 2]; } } } // for(j = 0; j < 9; j++) { // tempMoments->GetAt(j) = ((CxDVec3Array *)_magneticDipoleCache[i])->GetAt(j); // } // for(j = 9; j < tempMoments->GetSize() - 9; j++) { // int k; // for(k = 0; k < 3; k++) { // double array[19]; // int l; // for(l = j - 9; l <= j + 9; l++) { // array[l - j + 9] = ((CxDVec3Array *)_magneticDipoleCache[i])->GetAt(l)[k]; // } // qsort(array, 19, sizeof(double), compare_double); // tempMoments->GetAt(j)[k] = array[9]; // } // } // for(j = tempMoments->GetSize() - 9; j < tempMoments->GetSize(); j++) { // tempMoments->GetAt(j) = ((CxDVec3Array *)_magneticDipoleCache[i])->GetAt(j); // } // for(j = 0; j < tempMoments->GetSize(); j++) { // tempMoments->GetAt(j) = CxDVector3(0.0f, 0.0f, 0.0f); // int k; // int count = 0; // for(k = j - 10; k <= j + 10; k++) { // if(k < 0) // continue; // if(k >= tempMoments->GetSize()) // break; // tempMoments->GetAt(j) += ((CxDVec3Array *)_magneticDipoleCache[i])->GetAt(k); // count++; // } // tempMoments->GetAt(j) /= (double)count; // } // for(j = 0; j < 12; j++) { // tempMoments->GetAt(j) = ((CxDVec3Array *)_magneticDipoleCache[i])->GetAt(j); // } // for(j = 12; j < tempMoments->GetSize() - 12; j++) { // // tempMoments->GetAt(j) = (-3.0f * ((CxDVec3Array *)_magneticDipoleCache[i])->GetAt(j-2) + 12.0f * ((CxDVec3Array *)_magneticDipoleCache[i])->GetAt(j-1) + 17.0f * ((CxDVec3Array *)_magneticDipoleCache[i])->GetAt(j) + 12.0f * ((CxDVec3Array *)_magneticDipoleCache[i])->GetAt(j+1) - 3.0f * ((CxDVec3Array *)_magneticDipoleCache[i])->GetAt(j+2)) / 35.0f; // // tempMoments->GetAt(j) = (-21.0f * ((CxDVec3Array *)_magneticDipoleCache[i])->GetAt(j-4) + 14.0f * ((CxDVec3Array *)_magneticDipoleCache[i])->GetAt(j-3) + 39.0f * ((CxDVec3Array *)_magneticDipoleCache[i])->GetAt(j-2) + 54.0f * ((CxDVec3Array *)_magneticDipoleCache[i])->GetAt(j-1) + 59.0f * ((CxDVec3Array *)_magneticDipoleCache[i])->GetAt(j) + 54.0f * ((CxDVec3Array *)_magneticDipoleCache[i])->GetAt(j+1) + 39.0f * ((CxDVec3Array *)_magneticDipoleCache[i])->GetAt(j+2) + 14.0f * ((CxDVec3Array *)_magneticDipoleCache[i])->GetAt(j+3) - 21.0f * ((CxDVec3Array *)_magneticDipoleCache[i])->GetAt(j+4)) / 231.0f; // tempMoments->GetAt(j) = (-253.0f * ((CxDVec3Array *)_magneticDipoleCache[i])->GetAt(j-12) - 138.0f * ((CxDVec3Array *)_magneticDipoleCache[i])->GetAt(j-11) - 33.0f * ((CxDVec3Array *)_magneticDipoleCache[i])->GetAt(j-10) + 62.0f * ((CxDVec3Array *)_magneticDipoleCache[i])->GetAt(j-9) + 147.0f * ((CxDVec3Array *)_magneticDipoleCache[i])->GetAt(j-8) + 222.0f * ((CxDVec3Array *)_magneticDipoleCache[i])->GetAt(j-7) + 287.0f * ((CxDVec3Array *)_magneticDipoleCache[i])->GetAt(j-6) + 322.0f * ((CxDVec3Array *)_magneticDipoleCache[i])->GetAt(j-5) + 387.0f * ((CxDVec3Array *)_magneticDipoleCache[i])->GetAt(j-4) + 422.0f * ((CxDVec3Array *)_magneticDipoleCache[i])->GetAt(j-3) + 447.0f * ((CxDVec3Array *)_magneticDipoleCache[i])->GetAt(j-2) + 462.0f * ((CxDVec3Array *)_magneticDipoleCache[i])->GetAt(j-1) + 467.0f * ((CxDVec3Array *)_magneticDipoleCache[i])->GetAt(j) + 462.0f * ((CxDVec3Array *)_magneticDipoleCache[i])->GetAt(j+1) + 447.0f * ((CxDVec3Array *)_magneticDipoleCache[i])->GetAt(j+2) + // 422.0f * ((CxDVec3Array *)_magneticDipoleCache[i])->GetAt(j+3) + 387.0f * ((CxDVec3Array *)_magneticDipoleCache[i])->GetAt(j+4) + 322.0f * ((CxDVec3Array *)_magneticDipoleCache[i])->GetAt(j+5) + 287.0f * ((CxDVec3Array *)_magneticDipoleCache[i])->GetAt(j+6) + 222.0f * ((CxDVec3Array *)_magneticDipoleCache[i])->GetAt(j+7) + 147.0f * ((CxDVec3Array *)_magneticDipoleCache[i])->GetAt(j+8) + 62.0f * ((CxDVec3Array *)_magneticDipoleCache[i])->GetAt(j+9) - 33.0f * ((CxDVec3Array *)_magneticDipoleCache[i])->GetAt(j+10) - 138.0f * ((CxDVec3Array *)_magneticDipoleCache[i])->GetAt(j+11) - 253.0f * ((CxDVec3Array *)_magneticDipoleCache[i])->GetAt(j+12)) / 5175.0f; // } // for(j = tempMoments->GetSize() - 12; j < tempMoments->GetSize(); j++) { // tempMoments->GetAt(j) = ((CxDVec3Array *)_magneticDipoleCache[i])->GetAt(j); // } ((CxDVec3Array *)_magneticDipoleCache[i])->CopyFrom(tempMoments); } delete tempMoments; delete[] sortArray; } if(_saveMoments) { mprintf(" Saving electric and magnetic dipole moments...\n"); char filename[BUF_SIZE]; #ifdef TARGET_LINUX snprintf(filename, BUF_SIZE, "vcd_moments_%s.csv", _name); #else sprintf(filename, "vcd_moments_%s.csv", _name); #endif FILE *momentsFile = OpenFileWrite(filename, false); for(i = 0; i < ((CxDVec3Array *)_magneticDipoleCache[0])->GetSize(); i++) { fprintf(momentsFile, "%.2f;", g_fTimestepLength * (i + 1)); for(j = 0; j < m_iShowMolCount; j++) { fprintf(momentsFile, " %.10G; %.10G; %.10G; %.10G; %.10G; %.10G;", ((CxDVec3Array *)_electricDipoleCache[j])->GetAt(i)[0], ((CxDVec3Array *)_electricDipoleCache[j])->GetAt(i)[1], ((CxDVec3Array *)_electricDipoleCache[j])->GetAt(i)[2], ((CxDVec3Array *)_magneticDipoleCache[j])->GetAt(i)[0], ((CxDVec3Array *)_magneticDipoleCache[j])->GetAt(i)[1], ((CxDVec3Array *)_magneticDipoleCache[j])->GetAt(i)[2]); } fprintf(momentsFile, "\n"); } fclose(momentsFile); } mprintf(" Deriving electric dipole moments...\n"); int n = ((CxDVec3Array *)_electricDipoleCache[0])->GetSize() - 2; double step = (double)m_iShowMolCount / 20.0; mprintf(WHITE, " ["); for(i = 0; i < m_iShowMolCount; i++) { if(fmod(i, step) < 1.0) mprintf(WHITE, "#"); for(j = 0; j < n; j++) { ((CxDVec3Array *)_electricDipoleCache[i])->GetAt(j) = 0.5 * (((CxDVec3Array *)_electricDipoleCache[i])->GetAt(j+2) - ((CxDVec3Array *)_electricDipoleCache[i])->GetAt(j)) / g_fTimestepLength; } } mprintf(WHITE, "]\n"); mprintf(" Deriving magnetic dipole moments...\n"); mprintf(WHITE, " ["); for(i = 0; i < m_iShowMolCount; i++) { if(fmod(i, step) < 1.0) mprintf(WHITE, "#"); for(j = 0; j < n; j++) { ((CxDVec3Array *)_magneticDipoleCache[i])->GetAt(j) = 0.5 * (((CxDVec3Array *)_magneticDipoleCache[i])->GetAt(j+2) - ((CxDVec3Array *)_magneticDipoleCache[i])->GetAt(j)) / g_fTimestepLength; } } mprintf(WHITE, "]\n"); if(_saveMoments) { mprintf(" Saving electric and magnetic dipole moment derivatives...\n"); char filename[BUF_SIZE]; #ifdef TARGET_LINUX snprintf(filename, BUF_SIZE, "vcd_moments_deriv_%s.csv", _name); #else sprintf(filename, "vcd_moments_deriv_%s.csv", _name); #endif FILE *momentsFile = OpenFileWrite(filename, false); for(i = 0; i < n; i++) { fprintf(momentsFile, "%.2f;", g_fTimestepLength * (i + 2)); for(j = 0; j < m_iShowMolCount; j++) { fprintf(momentsFile, " %.10G; %.10G; %.10G; %.10G; %.10G; %.10G;", ((CxDVec3Array *)_electricDipoleCache[j])->GetAt(i)[0], ((CxDVec3Array *)_electricDipoleCache[j])->GetAt(i)[1], ((CxDVec3Array *)_electricDipoleCache[j])->GetAt(i)[2], ((CxDVec3Array *)_magneticDipoleCache[j])->GetAt(i)[0], ((CxDVec3Array *)_magneticDipoleCache[j])->GetAt(i)[1], ((CxDVec3Array *)_magneticDipoleCache[j])->GetAt(i)[2]); } fprintf(momentsFile, "\n"); } fclose(momentsFile); } mprintf(" Calculating cross-correlation...\n"); if ((n < 2) || (_correlationDepth < 2)) { mprintf("Less than 2 steps, skipping correlation.\n"); for(i = 0; i < _electricDipoleCache.GetSize(); i++) { delete (CxDVec3Array *)_electricDipoleCache[i]; delete (CxDVec3Array *)_magneticDipoleCache[i]; } return; } CxDoubleArray *ccf; try { ccf = new CxDoubleArray(); } catch(...) { ccf = NULL; } if(ccf == NULL) NewException((double)sizeof(CxDoubleArray), __FILE__, __LINE__, __PRETTY_FUNCTION__); ccf->SetSize(_correlationDepth); for(i = 0; i < _correlationDepth; i++) { ccf->GetAt(i) = 0.0; } CCrossCorrelation *cc; try { cc = new CCrossCorrelation(); } catch(...) { cc = NULL; } if(cc == NULL) NewException((double)sizeof(CCrossCorrelation), __FILE__, __LINE__, __PRETTY_FUNCTION__); cc->Init(n, _correlationDepth, g_bACFFFT); CxDoubleArray *temp; try { temp = new CxDoubleArray(); } catch(...) { temp = NULL; } if(temp == NULL) NewException((double)sizeof(CxDoubleArray), __FILE__, __LINE__, __PRETTY_FUNCTION__); temp->SetSize(n); CxDoubleArray *temp2; try { temp2 = new CxDoubleArray(); } catch(...) { temp2 = NULL; } if(temp2 == NULL) NewException((double)sizeof(CxDoubleArray), __FILE__, __LINE__, __PRETTY_FUNCTION__); temp2->SetSize(n); CxDoubleArray *temp3; try { temp3 = new CxDoubleArray(); } catch(...) { temp3 = NULL; } if(temp3 == NULL) NewException((double)sizeof(CxDoubleArray), __FILE__, __LINE__, __PRETTY_FUNCTION__); temp3->SetSize(n); mprintf(WHITE, " ["); for(i = 0; i < m_iShowMolCount; i++) { if(fmod(i, step) < 1.0) mprintf(WHITE, "#"); for(j = 0; j < 3; j++) { for(k = 0; k < n; k++) { temp->GetAt(k) = ((CxDVec3Array *)_electricDipoleCache[i])->GetAt(k)[j]; temp2->GetAt(k) = ((CxDVec3Array *)_magneticDipoleCache[i])->GetAt(k)[j]; } cc->CrossCorrelate(temp, temp2, temp3); for(k = 0; k < _correlationDepth; k++) { ccf->GetAt(k) += temp3->GetAt(k); } cc->CrossCorrelate(temp2, temp, temp3); for(k = 0; k < _correlationDepth; k++) { ccf->GetAt(k) -= temp3->GetAt(k); } } } mprintf(WHITE, "]\n"); // The 3.0f is included in the final normalization // for(i = 0; i < _correlationDepth; i++) { // ccf->GetAt(i) /= 3.0f * g_iSteps * m_iShowMolCount; // } if(m_iShowMol != -1) { for(i = 0; i < _correlationDepth; i++) { ccf->GetAt(i) /= (double)m_iShowMolCount; } } delete cc; delete temp2; delete temp3; if(_saveACF) { char filename[BUF_SIZE]; #ifdef TARGET_LINUX snprintf(filename, BUF_SIZE, "vcd_ccf_%s.csv", _name); #else sprintf(filename, "vcd_ccf_%s.csv", _name); #endif mprintf(" Saving cross-correlation function as %s...\n", filename); FILE *ccfFile = OpenFileWrite(filename, false); for(i = 0; i < _correlationDepth; i++) { fprintf(ccfFile, "%.2f; %.10G\n", i * g_fTimestepLength, ccf->GetAt(i)); } fclose(ccfFile); } temp->CopyFrom(ccf); if(_windowFunction == 1) { for(i = 0; i < temp->GetSize(); i++) { temp->GetAt(i) *= pow2(cos((double)i / (temp->GetSize() - 1) / 2.0 * Pi)); } } else if(_windowFunction == 2) { for(i = 0; i < temp->GetSize(); i++) { temp->GetAt(i) *= exp(-(double)i / _windowFunctionParameter); } } else if(_windowFunction == 3) { for(i = 0; i < temp->GetSize(); i++) { temp->GetAt(i) *= exp(-(double)i * i / _windowFunctionParameter / _windowFunctionParameter); } } else if(_windowFunction != 0) { eprintf("Unknown window function.\n"); abort(); } if(_saveACF) { char filename[BUF_SIZE]; #ifdef TARGET_LINUX snprintf(filename, BUF_SIZE, "vcd_ccf_windowed_%s.csv", _name); #else sprintf(filename, "vcd_ccf_windowed_%s.csv", _name); #endif mprintf(" Saving windowed cross-correlation function as %s...\n", filename); FILE *ccfFile = OpenFileWrite(filename, false); for(i = 0; i < _correlationDepth; i++) { fprintf(ccfFile, "%.2f; %.10G\n", i * g_fTimestepLength, temp->GetAt(i)); } fclose(ccfFile); } if(_zeroPadding > 0) { for(i = 0; i < _zeroPadding; i++) { temp->Add(0.0); } } int oldSize = temp->GetSize(); temp->SetSize(2 * oldSize); for(i = 1; i < oldSize; i++) { temp->GetAt(oldSize + i) = -temp->GetAt(oldSize - i); } temp->GetAt(oldSize) = 0.0; mprintf(" Fourier transforming cross-correlation function...\n"); CFFT *fft; try { fft = new CFFT(); } catch(...) { fft = NULL; } if(fft == NULL) NewException((double)sizeof(CFFT), __FILE__, __LINE__, __PRETTY_FUNCTION__); fft->PrepareFFT_C2C(temp->GetSize()); for(i = 0; i < temp->GetSize(); i++) { fft->m_pInput[2*i] = temp->GetAt(i); fft->m_pInput[2*i+1] = 0.0; } fft->DoFFT(); CxDoubleArray *spectrum; try { spectrum = new CxDoubleArray(); } catch(...) { spectrum = NULL; } if(spectrum == NULL) NewException((double)sizeof(CxDoubleArray), __FILE__, __LINE__, __PRETTY_FUNCTION__); spectrum->SetSize(_specSize); for(i = 0; i < _specSize; i++) { spectrum->GetAt(i) = 28.260058 * fft->m_pOutput[2*i+1] * g_fTimestepLength; // Output in K*cm*km/mol } if(_finiteDifferenceCorrection) { double f = _specResolution * g_fTimestepLength * 1.883652e-4; for(i = 1; i < _specSize; i++) { spectrum->GetAt(i) *= pow2(f * i / sin(f * i)); // Divide by sinc function to correct finite difference derivation } } char filename[BUF_SIZE]; #ifdef TARGET_LINUX snprintf(filename, BUF_SIZE, "vcd_spectrum_%s.csv", _name); #else sprintf(filename, "vcd_spectrum_%s.csv", _name); #endif mprintf(" Saving spectrum as %s...\n", filename); FILE *specFile = OpenFileWrite(filename, false); fprintf(specFile, "#Wavenumber (cm^-1); Spectrum (K*cm*km*mol^-1); Integral (K*km*mol^-1)\n"); double integral = 0.0; for(i = 0; i < _specSize; i++) { integral += spectrum->GetAt(i) * _specResolution; fprintf(specFile, "%.2f; %.8G; %.14G\n", _specResolution * i, spectrum->GetAt(i), integral); } fclose(specFile); delete ccf; delete temp; delete fft; delete spectrum; for(i = 0; i < _electricDipoleCache.GetSize(); i++) { delete (CxDVec3Array *)_electricDipoleCache[i]; delete (CxDVec3Array *)_magneticDipoleCache[i]; } } bool gatherVCD() { parseMagneticDipole(); ParseDipole(); while(true) { mprintf(YELLOW, "\n>>> VCD Observation %d >>>\n\n", g_VCDObserv.GetSize() + 1); CVCDObservation *obs; try { obs = new CVCDObservation(); } catch(...) { obs = NULL; } if(obs == NULL) NewException((double)sizeof(CVCDObservation), __FILE__, __LINE__, __PRETTY_FUNCTION__); g_VCDObserv.Add(obs); mprintf(YELLOW, "<<< End of VCD Observation %d <<<\n\n", g_VCDObserv.GetSize()); if(!AskYesNo(" Add another observation (y/n)? [no] ", false)) break; mprintf("\n"); } if(AskYesNo(" Compute VCD spectrum of whole system (y/n) [no] ", false)) { mprintf(YELLOW, "\n>>> Global VCD Observation >>>\n\n"); CVCDObservation *obs; try { obs = new CVCDObservation(true); } catch(...) { obs = NULL; } if(obs == NULL) NewException((double)sizeof(CVCDObservation), __FILE__, __LINE__, __PRETTY_FUNCTION__); g_VCDObserv.Add(obs); mprintf(YELLOW, "<<< End of Global VCD Observation <<<\n\n"); } return true; } bool initializeVCD() { int i; for(i = 0; i < g_VCDObserv.GetSize(); i++) { ((CVCDObservation *)g_VCDObserv[i])->initialize(); } return true; } void processVCD(CTimeStep *ts) { UNUSED(ts); // ts->CalcMagneticDipoles(); int i; for(i = 0; i < g_VCDObserv.GetSize(); i++) { ((CVCDObservation *)g_VCDObserv[i])->process(); } } void finalizeVCD() { int i; for(i = 0; i < g_VCDObserv.GetSize(); i++) { ((CVCDObservation *)g_VCDObserv[i])->finalize(); } } static FILE *g_magneticDipoleRestartFile = NULL; bool gatherMagneticDipoleRestart() { parseMagneticDipole(); ParseDipole(); mprintf(YELLOW, "\n>>> Magnetic Moment Restart File >>>\n\n"); CxString filename; AskString(" Enter name of magnetic moment restart file to write: [magnetic.restart] ", &filename, "magnetic.restart"); g_magneticDipoleRestartFile = OpenFileWrite((const char *)filename, false); int numMolecules = g_oaSingleMolecules.GetSize(); fwrite(&numMolecules, sizeof(int), 1, g_magneticDipoleRestartFile); mprintf(YELLOW, "\n<<< End of Magnetic Moment Restart File <<<\n\n"); return true; } bool initializeMagneticDipoleRestart() { return true; } void processMagneticDipoleRestart(CTimeStep *ts) { UNUSED(ts); int i; for (i = 0; i < g_oaSingleMolecules.GetSize(); i++) { CSingleMolecule *sm = (CSingleMolecule *)g_oaSingleMolecules[i]; int j; for (j = 0; j < 3; j++) { double val = sm->m_vMagneticDipole[j]; fwrite(&val, sizeof(double), 1, g_magneticDipoleRestartFile); } } fflush(g_magneticDipoleRestartFile); } void finalizeMagneticDipoleRestart() { if (g_magneticDipoleRestartFile != NULL) fclose(g_magneticDipoleRestartFile); } static FILE *g_sortWannierTrajFile; static int g_sortWannierCount; static CxDVec3Array g_sortWannierHistory; static CxIntArray g_sortWannierHistoryIndex; static CxDoubleArray g_sortWannierDistanceMatrix; static CxIntArray g_sortWannierKMStarCol; static CxIntArray g_sortWannierKMPrimeRow; static CxDoubleArray g_sortWannierKMMinCol; static CxDoubleArray g_sortWannierKMMinRow; bool gatherSortWannier() { g_bKeepOriginalCoords = true; g_bWannier = true; int watom = -1; int i; for(i = 0; i < g_oaAtoms.GetSize() - 1; i++) { if(((CAtom *)g_oaAtoms[i])->m_bExclude) { watom = i; break; } } if(watom == -1) eprintf(" Atom label of Wannier centers not found.\n\n"); else mprintf(" Atom type %s is excluded from the system, probably these are the Wannier centers.\n\n", (const char*)((CAtom *)g_oaAtoms[watom])->m_sName); bool ok = false; char buf[BUF_SIZE]; char buf2[BUF_SIZE]; size_t remaining = BUF_SIZE; while(!ok) { #ifdef TARGET_LINUX remaining -= snprintf(buf, remaining, " Which atom label do the wannier centers have ("); #else remaining -= sprintf(buf, " Which atom label do the wannier centers have ("); #endif for(i = 0; i < g_oaAtoms.GetSize() - 1; i++) { if(remaining < 1) break; #ifdef TARGET_LINUX size_t length = snprintf(buf2, remaining, "%s", (const char*)((CAtom *)g_oaAtoms[i])->m_sName); #else size_t length = sprintf(buf2, "%s", (const char*)((CAtom *)g_oaAtoms[i])->m_sName); #endif strncat(buf, buf2, remaining - 1); remaining -= length; if(i < g_oaAtoms.GetSize() - 2) { #ifdef TARGET_LINUX length = snprintf(buf2, remaining, ", "); #else length = sprintf(buf2, ", "); #endif strncat(buf, buf2, remaining - 1); remaining -= length; } } #ifdef TARGET_LINUX size_t length = snprintf(buf2, remaining, ")? "); #else size_t length = sprintf(buf2, ")? "); #endif strncat(buf, buf2, remaining - 1); remaining -= length; if(watom != -1) { #ifdef TARGET_LINUX snprintf(buf2, remaining, "[%s] ", (const char*)((CAtom *)g_oaAtoms[watom])->m_sName); #else sprintf(buf2, "[%s] ", (const char*)((CAtom *)g_oaAtoms[watom])->m_sName); #endif strncat(buf, buf2, remaining - 1); } CxString buf3; if(watom == -1) AskString_ND("%s", &buf3, (const char*)buf); else AskString("%s", &buf3, ((CAtom *)g_oaAtoms[watom])->m_sName, (const char*)buf); for(i = 0; i < g_oaAtoms.GetSize() - 1; i++) { if(mystricmp((const char *)buf3, ((CAtom *)g_oaAtoms[i])->m_sName) == 0) { g_iWannierAtomType = i; ok = true; break; } } if(!ok) { eprintf(" Invalid input.\n"); inpprintf("! Invalid input.\n"); } } g_sortWannierCount = 0; for(i = 0; i < g_iGesAtomCount; i++) { if(g_baAtomIndex[i] == g_iWannierAtomType) g_sortWannierCount++; } mprintf("\n There are %d Wannier centers in the first step.\n", g_sortWannierCount); return true; } bool initializeSortWannier() { char filename[BUF_SIZE]; #ifdef TARGET_LINUX char buf[BUF_SIZE]; strncpy(buf, g_sInputTraj, BUF_SIZE); buf[BUF_SIZE-1] = 0; char *p = strrchr(buf, '/'); if(p == NULL) p = buf; else p++; size_t s = strcspn(p, "."); if(s > BUF_SIZE - 8) s = BUF_SIZE - 8; strncpy(filename, p, s); filename[s] = 0; strcat(filename, "_out.xyz"); #else sprintf(filename, "out.xyz"); #endif mprintf(" Saving processed trajectory as %s\n\n", filename); g_sortWannierTrajFile = OpenFileWrite(filename, false); mprintf(" Coordinate history: Trying to allocate %s of memory...\n", FormatBytes((double)(g_sortWannierCount * sizeof(int) + g_sortWannierCount * sizeof(CxDVector3)))); g_sortWannierHistory.SetSize(g_sortWannierCount); g_sortWannierHistoryIndex.SetSize(g_sortWannierCount); mprintf(" Hungarian algorithm: Trying to allocate %s of memory...\n", FormatBytes((double)(g_sortWannierCount * g_sortWannierCount * sizeof(double) + 2 * g_sortWannierCount * sizeof(double) + 2 * g_sortWannierCount * sizeof(int)))); g_sortWannierDistanceMatrix.SetSize(g_sortWannierCount * g_sortWannierCount); g_sortWannierKMStarCol.SetSize(g_sortWannierCount); g_sortWannierKMPrimeRow.SetSize(g_sortWannierCount); g_sortWannierKMMinCol.SetSize(g_sortWannierCount); g_sortWannierKMMinRow.SetSize(g_sortWannierCount); return true; } void processSortWannier(CTimeStep *ts) { static bool first = true; if(first) { first = false; fprintf(g_sortWannierTrajFile, "%d\n", g_iGesAtomCount); if(ts->m_pComment != NULL) fprintf(g_sortWannierTrajFile, "%s\n", ts->m_pComment); else fprintf(g_sortWannierTrajFile, "\n"); int i; int pos = 0; for(i = 0; i < g_iGesAtomCount; i++) { if(g_baAtomIndex[i] == g_iWannierAtomType) { g_sortWannierHistory[pos] = ts->m_vaCoords[i]; g_sortWannierHistoryIndex[pos] = i; pos++; fprintf(g_sortWannierTrajFile, "%4s %14.10f %14.10f %14.10f\n", (const char*)((CAtom *)g_oaAtoms[g_iWannierAtomType])->m_sName, ts->m_vaCoords_Original[i][0] / 100.0f, ts->m_vaCoords_Original[i][1] / 100.0f, ts->m_vaCoords_Original[i][2] / 100.0f); } else { fprintf(g_sortWannierTrajFile, "%4s %14.10f %14.10f %14.10f\n", (const char*)((CAtom *)g_oaAtoms[g_waAtomRealElement[i]])->m_sName, ts->m_vaCoords_Original[i][0] / 100.0f, ts->m_vaCoords_Original[i][1] / 100.0f, ts->m_vaCoords_Original[i][2] / 100.0f); } } } else { CxIntArray sortIndex; sortIndex.SetSize(g_sortWannierHistory.GetSize()); // Hungarian algorithm as described on http://de.wikipedia.org/wiki/Ungarische_Methode, 07.02.14 const double thresh = 1.0e-5; int i, j; for(i = 0; i < g_sortWannierCount; i++) { for(j = 0; j < g_sortWannierCount; j++) { CxDVector3 dist = g_sortWannierHistory[i] - ts->m_vaCoords[g_sortWannierHistoryIndex[j]]; if(g_bPeriodicX) { while(dist[0] > g_fBoxX / 2.0) dist[0] -= g_fBoxX; while(dist[0] < -g_fBoxX / 2.0) dist[0] += g_fBoxX; } if(g_bPeriodicY) { while(dist[1] > g_fBoxY / 2.0) dist[1] -= g_fBoxY; while(dist[1] < -g_fBoxY / 2.0) dist[1] += g_fBoxY; } if(g_bPeriodicZ) { while(dist[2] > g_fBoxZ / 2.0) dist[2] -= g_fBoxZ; while(dist[2] < -g_fBoxZ / 2.0) dist[2] += g_fBoxZ; } g_sortWannierDistanceMatrix[i*g_sortWannierCount+j] = dist.GetLengthSqr(); } } for(i = 0; i < g_sortWannierCount; i++) { g_sortWannierKMStarCol[i] = -1; } for(j = 0; j < g_sortWannierCount; j++) { g_sortWannierKMMinCol[j] = g_sortWannierDistanceMatrix[j]; for(i = 0; i < g_sortWannierCount; i++) { if(g_sortWannierDistanceMatrix[i*g_sortWannierCount+j] < g_sortWannierKMMinCol[j]) { g_sortWannierKMMinCol[j] = g_sortWannierDistanceMatrix[i*g_sortWannierCount+j]; } } } for(i = 0; i < g_sortWannierCount; i++) { g_sortWannierKMMinRow[i] = g_sortWannierDistanceMatrix[i*g_sortWannierCount] - g_sortWannierKMMinCol[0]; for(j = 0; j < g_sortWannierCount; j++) { if(g_sortWannierDistanceMatrix[i*g_sortWannierCount+j] - g_sortWannierKMMinCol[j] < g_sortWannierKMMinRow[i]) { g_sortWannierKMMinRow[i] = g_sortWannierDistanceMatrix[i*g_sortWannierCount+j] - g_sortWannierKMMinCol[j]; } } } while(true) { for(i = 0; i < g_sortWannierCount; i++) { g_sortWannierKMPrimeRow[i] = -1; } int count = 0; for(i = 0; i < g_sortWannierCount; i++) { bool star = false; for(j = 0; j < g_sortWannierCount; j++) { if(g_sortWannierKMStarCol[j] == i) { star = true; count++; break; } } if(star) { continue; } for(j = 0; j < g_sortWannierCount; j++) { if(g_sortWannierKMStarCol[j] == -1 && g_sortWannierDistanceMatrix[i*g_sortWannierCount+j] - g_sortWannierKMMinRow[i] - g_sortWannierKMMinCol[j] < thresh) { g_sortWannierKMStarCol[j] = i; count++; break; } } } if(count == g_sortWannierCount) { break; } int row; while(true) { double min = 1.0e5; for(i = 0; i < g_sortWannierCount; i++) { if(g_sortWannierKMPrimeRow[i] != -1) { continue; } for(j = 0; j < g_sortWannierCount; j++) { if((g_sortWannierKMStarCol[j] == -1 || g_sortWannierKMPrimeRow[g_sortWannierKMStarCol[j]] != -1) && g_sortWannierDistanceMatrix[i*g_sortWannierCount+j] - g_sortWannierKMMinRow[i] - g_sortWannierKMMinCol[j] < min) { min = g_sortWannierDistanceMatrix[i*g_sortWannierCount+j] - g_sortWannierKMMinRow[i] - g_sortWannierKMMinCol[j]; } } } for(i = 0; i < g_sortWannierCount; i++) { if(g_sortWannierKMStarCol[i] == -1 || g_sortWannierKMPrimeRow[g_sortWannierKMStarCol[i]] != -1) { g_sortWannierKMMinCol[i] += min; } if(g_sortWannierKMPrimeRow[i] != -1) { g_sortWannierKMMinRow[i] -= min; } } row = -1; for(i = 0; i < g_sortWannierCount; i++) { if(g_sortWannierKMPrimeRow[i] != -1) { continue; } bool found = false; for(j = 0; j < g_sortWannierCount; j++) { if((g_sortWannierKMStarCol[j] == -1 || g_sortWannierKMPrimeRow[g_sortWannierKMStarCol[j]] != -1) && g_sortWannierDistanceMatrix[i*g_sortWannierCount+j] - g_sortWannierKMMinRow[i] - g_sortWannierKMMinCol[j] < thresh) { g_sortWannierKMPrimeRow[i] = j; row = i; found = true; break; } } if(found) { break; } } bool star = false; for(j = 0; j < g_sortWannierCount; j++) { if(g_sortWannierKMStarCol[j] == row) { star = true; break; } } if(!star) { break; } } while(true) { if(g_sortWannierKMStarCol[g_sortWannierKMPrimeRow[row]] == -1) { break; } int tmp = g_sortWannierKMStarCol[g_sortWannierKMPrimeRow[row]]; g_sortWannierKMStarCol[g_sortWannierKMPrimeRow[row]] = row; row = tmp; } g_sortWannierKMStarCol[g_sortWannierKMPrimeRow[row]] = row; } for(i = 0; i < g_sortWannierHistoryIndex.GetSize(); i++) sortIndex[g_sortWannierKMStarCol[i]] = g_sortWannierHistoryIndex[i]; fprintf(g_sortWannierTrajFile, "%d\n", g_iGesAtomCount); if(ts->m_pComment != NULL) fprintf(g_sortWannierTrajFile, "%s\n", ts->m_pComment); else fprintf(g_sortWannierTrajFile, "\n"); int pos = 0; for(i = 0; i < g_iGesAtomCount; i++) { if(g_baAtomIndex[i] == g_iWannierAtomType) { g_sortWannierHistory[pos] = ts->m_vaCoords[sortIndex[pos]]; fprintf(g_sortWannierTrajFile, "%4s %14.10f %14.10f %14.10f\n", (const char*)((CAtom *)g_oaAtoms[g_iWannierAtomType])->m_sName, ts->m_vaCoords_Original[sortIndex[pos]][0] / 100.0f, ts->m_vaCoords_Original[sortIndex[pos]][1] / 100.0f, ts->m_vaCoords_Original[sortIndex[pos]][2] / 100.0f); pos++; } else { fprintf(g_sortWannierTrajFile, "%4s %14.10f %14.10f %14.10f\n", (const char*)((CAtom *)g_oaAtoms[g_waAtomRealElement[i]])->m_sName, ts->m_vaCoords_Original[i][0] / 100.0f, ts->m_vaCoords_Original[i][1] / 100.0f, ts->m_vaCoords_Original[i][2] / 100.0f); } } } } void finalizeSortWannier() { fclose(g_sortWannierTrajFile); } travis-src-190101/src/ir.h0100777000000000000000000000665613412725653012241 0ustar00/***************************************************************************** TRAVIS - Trajectory Analyzer and Visualizer http://www.travis-analyzer.de/ Copyright (c) 2009-2019 Martin Brehm 2012-2019 Martin Thomas 2016-2019 Sascha Gehrke This file was written by Martin Thomas. --------------------------------------------------------------------------- This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . *****************************************************************************/ #ifndef IR_H #define IR_H // This must always be the first include directive #include "config.h" #include "moltools.h" class CTimeStep; class CPowerObservation: public CObservation { public: explicit CPowerObservation(bool global = false); ~CPowerObservation(); void initialize(); void process(CTimeStep *ts); void finalize(); private: char *_name; CAtomGroup *_atoms; int _correlationDepth; int _windowFunction; int _windowFunctionParameter; int _zeroPadding; int _specSize; double _specResolution; bool _saveACF; bool _massWeighting; bool m_bSplitCart; int m_iFinalDepth; CxObArray _velocityCache; CxDoubleArray _masses; }; bool gatherPowerSpectrum(); bool initializePowerSpectrum(); void processPowerSpectrum(CTimeStep *ts); void finalizePowerSpectrum(); class CIRObservation: public CObservation { public: explicit CIRObservation(bool global = false); ~CIRObservation(); void initialize(); void process(); void finalize(); private: char *_name; int _correlationDepth; int _windowFunction; int _windowFunctionParameter; int _zeroPadding; int _specSize; double _specResolution; bool _saveACF; bool _includeCross; bool _finiteDifferenceCorrection; CxObArray _dipoleCache; }; bool gatherIR(); bool initializeIR(); void processIR(CTimeStep *ts); void finalizeIR(); bool gatherDipoleRestart(); bool initializeDipoleRestart(); void processDipoleRestart(CTimeStep *ts); void finalizeDipoleRestart(); class CVCDObservation: public CObservation { public: explicit CVCDObservation(bool global = false); ~CVCDObservation(); void initialize(); void process(); void finalize(); private: char *_name; int _correlationDepth; int _windowFunction; int _windowFunctionParameter; int _zeroPadding; int _specSize; double _specResolution; bool _saveMoments; bool _saveACF; bool _finiteDifferenceCorrection; int _smoothWidth; CxObArray _electricDipoleCache; CxObArray _magneticDipoleCache; }; bool gatherVCD(); bool initializeVCD(); void processVCD(CTimeStep *ts); void finalizeVCD(); bool gatherMagneticDipoleRestart(); bool initializeMagneticDipoleRestart(); void processMagneticDipoleRestart(CTimeStep *ts); void finalizeMagneticDipoleRestart(); bool gatherSortWannier(); bool initializeSortWannier(); void processSortWannier(CTimeStep *ts); void finalizeSortWannier(); #endif travis-src-190101/src/kiss_fft.cpp0100777000000000000000000003202613412725630013753 0ustar00/***************************************************************************** TRAVIS - Trajectory Analyzer and Visualizer http://www.travis-analyzer.de/ Copyright (c) 2009-2019 Martin Brehm 2012-2019 Martin Thomas 2016-2019 Sascha Gehrke --------------------------------------------------------------------------- This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . *****************************************************************************/ /* Copyright (c) 2003-2010, Mark Borgerding All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * 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. * Neither the author nor the names of any contributors may be used to endorse or promote products derived from this software without specific prior written permission. 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. */ // This must always be the first include directive #include "config.h" #include "kiss_fft_guts.h" /* The guts header contains all the multiplication and addition macros that are defined for fixed or floating point complex numbers. It also delares the kf_ internal functions. */ const char *GetRevisionInfo_kiss_fft(unsigned int len) { static char buf[256]; GET_REVISION_INFO( buf, len ); return buf; } const char *GetSourceVersion_kiss_fft() { static char buf[256]; GET_SOURCE_VERSION( buf ); return buf; } static void kf_bfly2( kiss_fft_cpx * Fout, const size_t fstride, const kiss_fft_cfg st, int m ) { kiss_fft_cpx * Fout2; kiss_fft_cpx * tw1 = st->twiddles; kiss_fft_cpx t; Fout2 = Fout + m; do { C_FIXDIV(*Fout,2); C_FIXDIV(*Fout2,2); C_MUL (t, *Fout2 , *tw1); tw1 += fstride; C_SUB( *Fout2 , *Fout , t ); C_ADDTO( *Fout , t ); ++Fout2; ++Fout; } while (--m); } static void kf_bfly4( kiss_fft_cpx * Fout, const size_t fstride, const kiss_fft_cfg st, const size_t m ) { kiss_fft_cpx *tw1,*tw2,*tw3; kiss_fft_cpx scratch[6]; size_t k=m; const size_t m2=2*m; const size_t m3=3*m; tw3 = tw2 = tw1 = st->twiddles; do { C_FIXDIV(*Fout,4); C_FIXDIV(Fout[m],4); C_FIXDIV(Fout[m2],4); C_FIXDIV(Fout[m3],4); C_MUL(scratch[0],Fout[m] , *tw1 ); C_MUL(scratch[1],Fout[m2] , *tw2 ); C_MUL(scratch[2],Fout[m3] , *tw3 ); C_SUB( scratch[5] , *Fout, scratch[1] ); C_ADDTO(*Fout, scratch[1]); C_ADD( scratch[3] , scratch[0] , scratch[2] ); C_SUB( scratch[4] , scratch[0] , scratch[2] ); C_SUB( Fout[m2], *Fout, scratch[3] ); tw1 += fstride; tw2 += fstride*2; tw3 += fstride*3; C_ADDTO( *Fout , scratch[3] ); if(st->inverse) { Fout[m].r = scratch[5].r - scratch[4].i; Fout[m].i = scratch[5].i + scratch[4].r; Fout[m3].r = scratch[5].r + scratch[4].i; Fout[m3].i = scratch[5].i - scratch[4].r; }else{ Fout[m].r = scratch[5].r + scratch[4].i; Fout[m].i = scratch[5].i - scratch[4].r; Fout[m3].r = scratch[5].r - scratch[4].i; Fout[m3].i = scratch[5].i + scratch[4].r; } ++Fout; }while(--k); } static void kf_bfly3( kiss_fft_cpx * Fout, const size_t fstride, const kiss_fft_cfg st, size_t m ) { size_t k=m; const size_t m2 = 2*m; kiss_fft_cpx *tw1,*tw2; kiss_fft_cpx scratch[5]; kiss_fft_cpx epi3; epi3 = st->twiddles[fstride*m]; tw1=tw2=st->twiddles; do{ C_FIXDIV(*Fout,3); C_FIXDIV(Fout[m],3); C_FIXDIV(Fout[m2],3); C_MUL(scratch[1],Fout[m] , *tw1); C_MUL(scratch[2],Fout[m2] , *tw2); C_ADD(scratch[3],scratch[1],scratch[2]); C_SUB(scratch[0],scratch[1],scratch[2]); tw1 += fstride; tw2 += fstride*2; Fout[m].r = Fout->r - HALF_OF(scratch[3].r); Fout[m].i = Fout->i - HALF_OF(scratch[3].i); C_MULBYSCALAR( scratch[0] , epi3.i ); C_ADDTO(*Fout,scratch[3]); Fout[m2].r = Fout[m].r + scratch[0].i; Fout[m2].i = Fout[m].i - scratch[0].r; Fout[m].r -= scratch[0].i; Fout[m].i += scratch[0].r; ++Fout; }while(--k); } static void kf_bfly5( kiss_fft_cpx * Fout, const size_t fstride, const kiss_fft_cfg st, int m ) { kiss_fft_cpx *Fout0,*Fout1,*Fout2,*Fout3,*Fout4; int u; kiss_fft_cpx scratch[13]; kiss_fft_cpx * twiddles = st->twiddles; kiss_fft_cpx *tw; kiss_fft_cpx ya,yb; ya = twiddles[fstride*m]; yb = twiddles[fstride*2*m]; Fout0=Fout; Fout1=Fout0+m; Fout2=Fout0+2*m; Fout3=Fout0+3*m; Fout4=Fout0+4*m; tw=st->twiddles; for ( u=0; ur += scratch[7].r + scratch[8].r; Fout0->i += scratch[7].i + scratch[8].i; scratch[5].r = scratch[0].r + S_MUL(scratch[7].r,ya.r) + S_MUL(scratch[8].r,yb.r); scratch[5].i = scratch[0].i + S_MUL(scratch[7].i,ya.r) + S_MUL(scratch[8].i,yb.r); scratch[6].r = S_MUL(scratch[10].i,ya.i) + S_MUL(scratch[9].i,yb.i); scratch[6].i = -S_MUL(scratch[10].r,ya.i) - S_MUL(scratch[9].r,yb.i); C_SUB(*Fout1,scratch[5],scratch[6]); C_ADD(*Fout4,scratch[5],scratch[6]); scratch[11].r = scratch[0].r + S_MUL(scratch[7].r,yb.r) + S_MUL(scratch[8].r,ya.r); scratch[11].i = scratch[0].i + S_MUL(scratch[7].i,yb.r) + S_MUL(scratch[8].i,ya.r); scratch[12].r = - S_MUL(scratch[10].i,yb.i) + S_MUL(scratch[9].i,ya.i); scratch[12].i = S_MUL(scratch[10].r,yb.i) - S_MUL(scratch[9].r,ya.i); C_ADD(*Fout2,scratch[11],scratch[12]); C_SUB(*Fout3,scratch[11],scratch[12]); ++Fout0;++Fout1;++Fout2;++Fout3;++Fout4; } } /* perform the butterfly for one stage of a mixed radix FFT */ static void kf_bfly_generic( kiss_fft_cpx * Fout, const size_t fstride, const kiss_fft_cfg st, int m, int p ) { int u,k,q1,q; kiss_fft_cpx * twiddles = st->twiddles; kiss_fft_cpx t; int Norig = st->nfft; kiss_fft_cpx * scratch = (kiss_fft_cpx*)KISS_FFT_TMP_ALLOC(sizeof(kiss_fft_cpx)*p); for ( u=0; u=Norig) twidx-=Norig; C_MUL(t,scratch[q] , twiddles[twidx] ); C_ADDTO( Fout[ k ] ,t); } k += m; } } KISS_FFT_TMP_FREE(scratch); } static void kf_work( kiss_fft_cpx * Fout, const kiss_fft_cpx * f, const size_t fstride, int in_stride, int * factors, const kiss_fft_cfg st ) { kiss_fft_cpx * Fout_beg=Fout; const int p=*factors++; /* the radix */ const int m=*factors++; /* stage's fft length/p */ const kiss_fft_cpx * Fout_end = Fout + p*m; if (m==1) { do{ *Fout = *f; f += fstride*in_stride; }while(++Fout != Fout_end ); }else{ do{ // recursive call: // DFT of size m*p performed by doing // p instances of smaller DFTs of size m, // each one takes a decimated version of the input kf_work( Fout , f, fstride*p, in_stride, factors,st); f += fstride*in_stride; }while( (Fout += m) != Fout_end ); } Fout=Fout_beg; // recombine the p smaller DFTs switch (p) { case 2: kf_bfly2(Fout,fstride,st,m); break; case 3: kf_bfly3(Fout,fstride,st,m); break; case 4: kf_bfly4(Fout,fstride,st,m); break; case 5: kf_bfly5(Fout,fstride,st,m); break; default: kf_bfly_generic(Fout,fstride,st,m,p); break; } } /* facbuf is populated by p1,m1,p2,m2, ... where p[i] * m[i] = m[i-1] m0 = n */ static void kf_factor(int n,int * facbuf) { int p=4; double floor_sqrt; floor_sqrt = floor( sqrt((double)n) ); /*factor out powers of 4, powers of 2, then any remaining primes */ do { while (n % p) { switch (p) { case 4: p = 2; break; case 2: p = 3; break; default: p += 2; break; } if (p > floor_sqrt) p = n; /* no more factors, skip to end */ } n /= p; *facbuf++ = p; *facbuf++ = n; } while (n > 1); } /* * * User-callable function to allocate all necessary storage space for the fft. * * The return value is a contiguous block of memory, allocated with malloc. As such, * It can be freed with free(), rather than a kiss_fft-specific function. * */ kiss_fft_cfg kiss_fft_alloc(int nfft,int inverse_fft,void * mem,size_t * lenmem ) { kiss_fft_cfg st=NULL; size_t memneeded = sizeof(struct kiss_fft_state) + sizeof(kiss_fft_cpx)*(nfft-1); /* twiddle factors*/ if ( lenmem==NULL ) { st = ( kiss_fft_cfg)KISS_FFT_MALLOC( memneeded ); }else{ if (mem != NULL && *lenmem >= memneeded) st = (kiss_fft_cfg)mem; *lenmem = memneeded; } if (st) { int i; st->nfft=nfft; st->inverse = inverse_fft; for (i=0;iinverse) phase *= -1; kf_cexp(st->twiddles+i, phase ); } kf_factor(nfft,st->factors); } return st; } void kiss_fft_stride(kiss_fft_cfg st,const kiss_fft_cpx *fin,kiss_fft_cpx *fout,int in_stride) { if (fin == fout) { //NOTE: this is not really an in-place FFT algorithm. //It just performs an out-of-place FFT into a temp buffer kiss_fft_cpx * tmpbuf = (kiss_fft_cpx*)KISS_FFT_TMP_ALLOC( sizeof(kiss_fft_cpx)*st->nfft); kf_work(tmpbuf,fin,1,in_stride, st->factors,st); memcpy(fout,tmpbuf,sizeof(kiss_fft_cpx)*st->nfft); KISS_FFT_TMP_FREE(tmpbuf); }else{ kf_work( fout, fin, 1,in_stride, st->factors,st ); } } void kiss_fft(kiss_fft_cfg cfg,const kiss_fft_cpx *fin,kiss_fft_cpx *fout) { kiss_fft_stride(cfg,fin,fout,1); } void kiss_fft_cleanup(void) { // nothing needed any more } int kiss_fft_next_fast_size(int n) { while(1) { int m=n; while ( (m%2) == 0 ) m/=2; while ( (m%3) == 0 ) m/=3; while ( (m%5) == 0 ) m/=5; if (m<=1) break; /* n is completely factorable by twos, threes, and fives */ n++; } return n; } travis-src-190101/src/kiss_fft.h0100777000000000000000000001215513412725657013432 0ustar00/***************************************************************************** TRAVIS - Trajectory Analyzer and Visualizer http://www.travis-analyzer.de/ Copyright (c) 2009-2019 Martin Brehm 2012-2019 Martin Thomas 2016-2019 Sascha Gehrke --------------------------------------------------------------------------- This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . *****************************************************************************/ /* Copyright (c) 2003-2010, Mark Borgerding All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * 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. * Neither the author nor the names of any contributors may be used to endorse or promote products derived from this software without specific prior written permission. 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. */ #ifndef KISS_FFT_H #define KISS_FFT_H // This must always be the first include directive #include "config.h" #include #include #include #include //#include //#ifdef __cplusplus //extern "C" { //#endif #define KISS_FFT_MALLOC malloc #define KISS_FFT_FREE free #define kiss_fft_scalar double typedef struct { kiss_fft_scalar r; kiss_fft_scalar i; } kiss_fft_cpx; typedef struct kiss_fft_state *kiss_fft_cfg; /* * kiss_fft_alloc * * Initialize a FFT (or IFFT) algorithm's cfg/state buffer. * * typical usage: kiss_fft_cfg mycfg=kiss_fft_alloc(1024,0,NULL,NULL); * * The return value from fft_alloc is a cfg buffer used internally * by the fft routine or NULL. * * If lenmem is NULL, then kiss_fft_alloc will allocate a cfg buffer using malloc. * The returned value should be free()d when done to avoid memory leaks. * * The state can be placed in a user supplied buffer 'mem': * If lenmem is not NULL and mem is not NULL and *lenmem is large enough, * then the function places the cfg in mem and the size used in *lenmem * and returns mem. * * If lenmem is not NULL and ( mem is NULL or *lenmem is not large enough), * then the function returns NULL and places the minimum cfg * buffer size in *lenmem. * */ kiss_fft_cfg kiss_fft_alloc(int nfft, int inverse_fft, void * mem,size_t *lenmem); /* * kiss_fft(cfg,in_out_buf) * * Perform an FFT on a complex input buffer. * for a forward FFT, * fin should be f[0] , f[1] , ... ,f[nfft-1] * fout will be F[0] , F[1] , ... ,F[nfft-1] * Note that each element is complex and can be accessed like f[k].r and f[k].i * */ void kiss_fft(kiss_fft_cfg cfg, const kiss_fft_cpx *fin, kiss_fft_cpx *fout); /* A more generic version of the above function. It reads its input from every Nth sample. * */ void kiss_fft_stride(kiss_fft_cfg cfg, const kiss_fft_cpx *fin, kiss_fft_cpx *fout, int fin_stride); /* If kiss_fft_alloc allocated a buffer, it is one contiguous buffer and can be simply free()d when no longer needed*/ #define kiss_fft_free free /* Cleans up some memory that gets managed internally. Not necessary to call, but it might clean up your compiler output to call this before you exit. */ void kiss_fft_cleanup(void); /* * Returns the smallest integer k, such that k>=n and k has only "fast" factors (2,3,5) */ int kiss_fft_next_fast_size(int n); /* for real ffts, we need an even size */ #define kiss_fftr_next_fast_size_real(n) \ (kiss_fft_next_fast_size( ((n)+1)>>1)<<1) //#ifdef __cplusplus //} //#endif #endif travis-src-190101/src/kiss_fft_guts.h0100777000000000000000000001242313412725647014471 0ustar00/***************************************************************************** TRAVIS - Trajectory Analyzer and Visualizer http://www.travis-analyzer.de/ Copyright (c) 2009-2019 Martin Brehm 2012-2019 Martin Thomas 2016-2019 Sascha Gehrke --------------------------------------------------------------------------- This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . *****************************************************************************/ /* Copyright (c) 2003-2010, Mark Borgerding All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * 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. * Neither the author nor the names of any contributors may be used to endorse or promote products derived from this software without specific prior written permission. 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. */ /* kiss_fft.h defines kiss_fft_scalar as either short or a float type and defines typedef struct { kiss_fft_scalar r; kiss_fft_scalar i; }kiss_fft_cpx; */ // This must always be the first include directive #include "config.h" #include "kiss_fft.h" #include #define MAXFACTORS 32 /* e.g. an fft of length 128 has 4 factors as far as kissfft is concerned 4*4*4*2 */ struct kiss_fft_state { int nfft; int inverse; int factors[2*MAXFACTORS]; kiss_fft_cpx twiddles[1]; }; /* Explanation of macros dealing with complex math: C_MUL(m,a,b) : m = a*b C_FIXDIV( c , div ) : if a fixed point impl., c /= div. noop otherwise C_SUB( res, a,b) : res = a - b C_SUBFROM( res , a) : res -= a C_ADDTO( res , a) : res += a * */ # define S_MUL(a,b) ( (a)*(b) ) #define C_MUL(m,a,b) \ do{ (m).r = (a).r*(b).r - (a).i*(b).i;\ (m).i = (a).r*(b).i + (a).i*(b).r; }while(0) # define C_FIXDIV(c,div) /* NOOP */ # define C_MULBYSCALAR( c, s ) \ do{ (c).r *= (s);\ (c).i *= (s); }while(0) #ifndef CHECK_OVERFLOW_OP # define CHECK_OVERFLOW_OP(a,op,b) /* noop */ #endif #define C_ADD( res, a,b)\ do { \ CHECK_OVERFLOW_OP((a).r,+,(b).r)\ CHECK_OVERFLOW_OP((a).i,+,(b).i)\ (res).r=(a).r+(b).r; (res).i=(a).i+(b).i; \ }while(0) #define C_SUB( res, a,b)\ do { \ CHECK_OVERFLOW_OP((a).r,-,(b).r)\ CHECK_OVERFLOW_OP((a).i,-,(b).i)\ (res).r=(a).r-(b).r; (res).i=(a).i-(b).i; \ }while(0) #define C_ADDTO( res , a)\ do { \ CHECK_OVERFLOW_OP((res).r,+,(a).r)\ CHECK_OVERFLOW_OP((res).i,+,(a).i)\ (res).r += (a).r; (res).i += (a).i;\ }while(0) #define C_SUBFROM( res , a)\ do {\ CHECK_OVERFLOW_OP((res).r,-,(a).r)\ CHECK_OVERFLOW_OP((res).i,-,(a).i)\ (res).r -= (a).r; (res).i -= (a).i; \ }while(0) # define KISS_FFT_COS(phase) (kiss_fft_scalar) cos(phase) # define KISS_FFT_SIN(phase) (kiss_fft_scalar) sin(phase) # define HALF_OF(x) ((x)*((kiss_fft_scalar).5)) #define kf_cexp(x,phase) \ do{ \ (x)->r = KISS_FFT_COS(phase);\ (x)->i = KISS_FFT_SIN(phase);\ }while(0) /* a debugging function */ #define pcpx(c)\ fprintf(stderr,"%g + %gi\n",(double)((c)->r),(double)((c)->i) ) #ifdef KISS_FFT_USE_ALLOCA // define this to allow use of alloca instead of malloc for temporary buffers // Temporary buffers are used in two case: // 1. FFT sizes that have "bad" factors. i.e. not 2,3 and 5 // 2. "in-place" FFTs. Notice the quotes, since kissfft does not really do an in-place transform. #include #define KISS_FFT_TMP_ALLOC(nbytes) alloca(nbytes) #define KISS_FFT_TMP_FREE(ptr) #else #define KISS_FFT_TMP_ALLOC(nbytes) KISS_FFT_MALLOC(nbytes) #define KISS_FFT_TMP_FREE(ptr) KISS_FFT_FREE(ptr) #endif travis-src-190101/src/largeinteger.cpp0100777000000000000000000043146513412725634014631 0ustar00/***************************************************************************** TRAVIS - Trajectory Analyzer and Visualizer http://www.travis-analyzer.de/ Copyright (c) 2009-2019 Martin Brehm 2012-2019 Martin Thomas 2016-2019 Sascha Gehrke --------------------------------------------------------------------------- This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . *****************************************************************************/ //======================================================================= // Copyright (C) 1998-2013 William Hallahan // // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without restriction, // including without limitation the rights to use, copy, modify, merge, // publish, distribute, sublicense, and/or sell copies of the Software, // and to permit persons to whom the Software is furnished to do so, // subject to the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES // OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, // WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR // OTHER DEALINGS IN THE SOFTWARE. //======================================================================= //********************************************************************** // Class Implementation File: LargeInteger.cpp // Author: Bill Hallahan // Date: March 11, 1998 // // Abstract: // // This file contains the implementation for class LargeInteger. // An instance of LargeInteger can be used to store and calculate // integer values with a huge number of digits. The internal data // format is a both a boolean value named m_negative_flag that that // stores the sign of the number, and an array of integers that // contains a positive binary value. The maximum number of integers // that can be contained in the internal array is limited to the // maximum signed value which can be stored in an integer, The // maximum number of digits that can be used for octal and hexadecimal // input, and output, is equal to the the maximum value that can be // stored in a signed integer. The input and output conversion // methods for decimal numbers supports up to 19,346,699 digits or // almost 20 million decimal digits. This implementation only works // on little-endian machines. // //********************************************************************** // This must always be the first include directive #include "config.h" #include "tools.h" #if defined __GNUC__ #include #include #endif #include "largeinteger.h" const char *GetRevisionInfo_largeinteger(unsigned int len) { static char buf[256]; GET_REVISION_INFO( buf, len ); return buf; } const char *GetSourceVersion_largeinteger() { static char buf[256]; GET_SOURCE_VERSION( buf ); return buf; } #define INT_BIT_LENGTH_IS_POWER_OF_TWO std::string g_sLIString; std::string g_sLIString2; std::string g_sLIString3; //====================================================================== // Constants. //====================================================================== namespace { const unsigned int INTEGER_LOW_HALF_MASK = 0xFFFF; const unsigned int INTEGER_BIT_COUNT = 32; const unsigned int INTEGER_HALF_BIT_COUNT = 16; const int INTEGER_MAXIMUM_BASE = 90; const double D_MAX_UNSIGNED_VALUE = 4294967296.0; const char DIGIT_ARRAY[INTEGER_MAXIMUM_BASE] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'w', 'x', 'y', 'z', '.', ',', '?', '/', '\\', '|', '<', '>', ':', ';', '"', '\'', '{', '}', '[', ']', '`', '~', '!', '@', '#', '$', '%', '^', '&', '*', '(', ')', '-', '_', '+', '=' }; const unsigned int BIT_MASK_ARRAY[5] = { 0xAAAAAAAA, 0xCCCCCCCC, 0xF0F0F0F0, 0xFF00FF00, 0xFFFF0000 }; const unsigned int BIT_MASK_TABLE_LENGTH = sizeof(BIT_MASK_ARRAY) / sizeof(unsigned int); #ifdef LARGE_INT_ALTERNATE_POP_COUNT const unsigned int MASK_1 = 011111111111; const unsigned int MASK_3 = 033333333333; const unsigned int MASK_7 = 030707070707; #endif } //====================================================================== // istream operator for input. //====================================================================== std::istream & operator >>(std::istream & is, LargeInteger & value) { //------------------------------------------------------------------ // Get the input string. //------------------------------------------------------------------ const unsigned int max_string_length = 2048; char * number_ptr = new char [max_string_length]; if (number_ptr != 0) { is.get(number_ptr, max_string_length - 1); int length = (int)is.gcount(); number_ptr[length] = '\0'; unsigned int base; switch (is.flags() & std::ios_base::basefield) { case std::ios_base::oct: base = 8; break; case std::ios_base::dec: base = 10; break; case std::ios_base::hex: base = 16; break; default: base = 10; break; } value.SetValue(number_ptr, base); delete [] number_ptr; } return is; } //====================================================================== // ostream operator for output. //====================================================================== std::ostream & operator <<(std::ostream & os, const LargeInteger & value) { unsigned int base; switch (os.flags() & std::ios_base::basefield) { case std::ios_base::oct: base = 8; break; case std::ios_base::dec: base = 10; break; case std::ios_base::hex: base = 16; break; default: base = 10; break; } std::string number_string; value.GetNumberString(number_string, base); os << number_string.c_str(); return os; } //====================================================================== // Constructor: LargeInteger::LargeInteger //====================================================================== LargeInteger::LargeInteger() : m_array_length(0) , m_integer_length(0) , m_default_base(10) , m_array_ptr(0) , m_negative_flag(false) { SetIntegerLength(1); m_array_ptr[0] = 0; } //====================================================================== // Copy constructor //====================================================================== LargeInteger::LargeInteger(const LargeInteger & value) : m_array_length(0) , m_integer_length(0) , m_default_base(10) , m_array_ptr(0) , m_negative_flag(false) { Copy(value); } //====================================================================== // Conversion constructor for signed long. //====================================================================== LargeInteger::LargeInteger(long value) : m_array_length(0) , m_integer_length(0) , m_default_base(10) , m_array_ptr(0) , m_negative_flag(false) { SetIntegerLength(1); m_negative_flag = value < 0; m_array_ptr[0] = m_negative_flag ? (unsigned int)(-value) : (unsigned int)(value); } //====================================================================== // Conversion constructor for unsigned long. //====================================================================== LargeInteger::LargeInteger(unsigned long value) : m_array_length(0) , m_integer_length(0) , m_default_base(10) , m_array_ptr(0) , m_negative_flag(false) { SetIntegerLength(1); m_array_ptr[0] = value; } //====================================================================== // Conversion constructor for signed int. //====================================================================== LargeInteger::LargeInteger(int value) : m_array_length(0) , m_integer_length(0) , m_default_base(10) , m_array_ptr(0) , m_negative_flag(false) { SetIntegerLength(1); m_negative_flag = value < 0; m_array_ptr[0] = m_negative_flag ? (unsigned int)(-value) : (unsigned int)(value); } //====================================================================== // Conversion constructor for unsigned int. //====================================================================== LargeInteger::LargeInteger(unsigned int value) : m_array_length(0) , m_integer_length(0) , m_default_base(10) , m_array_ptr(0) , m_negative_flag(false) { SetIntegerLength(1); m_array_ptr[0] = value; } //====================================================================== // Constructor: LargeInteger::LargeInteger // // The number is interpreted using the default base that is set // using the SetDefaultBase method. //====================================================================== LargeInteger::LargeInteger(const char * psznumber_ptr) : m_array_length(0) , m_integer_length(0) , m_default_base(10) , m_array_ptr(0) , m_negative_flag(false) { SetValue(psznumber_ptr, m_default_base); } //====================================================================== // Special constructor to allow initializing using an array of // binary data. //====================================================================== LargeInteger::LargeInteger(const char * binary_data_ptr, unsigned int length) : m_array_length(0) , m_integer_length(0) , m_default_base(10) , m_array_ptr(0) , m_negative_flag(false) { SetBinaryValue(binary_data_ptr, length); } //====================================================================== // Destructor //====================================================================== LargeInteger::~LargeInteger() { delete [] m_array_ptr; } //====================================================================== // Method: LargeInteger::SetDefaultBase // // The default base is the value used for the constructor and operator // equals methods that take only a string pointer for a number. //====================================================================== void LargeInteger::SetDefaultBase(unsigned int default_base) { if ((default_base == 0) || (default_base > ((unsigned int)INTEGER_MAXIMUM_BASE))) { //throw LargeIntegerException("Illegal base"); eprintf("LargeInteger::SetDefaultBase(): Error: Illegal base %u.\n",default_base); abort(); } m_default_base = default_base; } //====================================================================== // This method allows getting this large integer's binary value. // The binary value is a positive number in little endian format. // The buffer that is passed must be large enough to contain the // number. This method can be called passing a null pointer for // the buffer to just obtain the buffer length in bytes. //====================================================================== unsigned int LargeInteger::GetBinaryValue(unsigned char * binary_data_ptr) const { //------------------------------------------------------------------ // Get the length of the output binary array. //------------------------------------------------------------------ unsigned int length = sizeof(unsigned int) * m_integer_length; //------------------------------------------------------------------ // Discard leading zero bytes. //------------------------------------------------------------------ char * source_ptr = reinterpret_cast(&m_array_ptr[0]); unsigned int leading_zero_count = 0; for (int i = length - 1; i >= 0; --i) { if (source_ptr[i] == 0) { ++leading_zero_count; } else { break; } } length -= leading_zero_count; //------------------------------------------------------------------ // If the passed array pointer is not zero then copy the data // to the output array. //------------------------------------------------------------------ if (binary_data_ptr != 0) { for (unsigned int j = 0; j < length; ++j) { binary_data_ptr[j] = source_ptr[j]; } } return length; } //====================================================================== // This method allows setting this large integer's binary value. // The binary value is a positive number in little endian format. // The buffer that is passed must be large enough to contain the // number. This method can be called passing a null pointer for // the buffer to just obtain the buffer length in bytes. //====================================================================== void LargeInteger::SetBinaryValue(const char * binary_data_ptr, unsigned int length) { //------------------------------------------------------------------ // Set the sign for a positive number. //------------------------------------------------------------------ m_negative_flag = false; //------------------------------------------------------------------ // Set the length of internal array of unsigned integers // that will store the byte array. //------------------------------------------------------------------ unsigned int array_length = (length + 3) >> 2; SetIntegerLength(array_length); //------------------------------------------------------------------ // Copy the bytes to the internal unsigned integer array. //------------------------------------------------------------------ char * destination_ptr = reinterpret_cast(m_array_ptr); unsigned int i = 0; for (i = 0; i < length; ++i) { destination_ptr[i] = binary_data_ptr[i]; } //------------------------------------------------------------------ // Determine if there are any extra bytes in the array that // need to be zero padded. //------------------------------------------------------------------ unsigned int index_one_past_final_byte = m_integer_length << 2; if (length < index_one_past_final_byte) { for (i = length; i < index_one_past_final_byte; ++i) { destination_ptr[i] = 0; } } //------------------------------------------------------------------ // Normalize the result. //------------------------------------------------------------------ Normalize(); return; } //================================================================== // Get this large integer value represented in an stl string. //================================================================== void LargeInteger::GetNumberString(std::string & number_string, unsigned int base) const { //------------------------------------------------------------------ // Convert this large integer to a character string representation // in the desired base. //------------------------------------------------------------------ number_string.erase(); //------------------------------------------------------------------ // Use special code for bases 8, 10, and 16. //------------------------------------------------------------------ switch (base) { case 8: GetBase8NumberString(number_string); break; case 10: GetBase10NumberString(number_string); break; case 16: GetBase16NumberString(number_string); break; default: //------------------------------------------------------------------ // Generic code for converting to any base up to base 90. //------------------------------------------------------------------ LargeInteger x_temp = *this; //-------------------------------------------------------------- // The characters are converted in reverse order from the // order they are displayed. //-------------------------------------------------------------- do { LargeInteger x_mult = x_temp / base; LargeInteger x_part = x_mult * base; unsigned int digit_index = (unsigned int)(x_temp - x_part); number_string += DIGIT_ARRAY[digit_index]; x_temp = x_mult; } while(!x_temp.IsZero()); //------------------------------------------------------------------ // Reverse the order of the digits so the number can be // properly displayed. //------------------------------------------------------------------ char * number_ptr = const_cast(number_string.data()); unsigned int length = (unsigned int)number_string.length(); for (unsigned int i = 0; i < (length >> 1); ++i) { char temp = number_ptr[i]; number_ptr[i] = number_ptr[(length - i) - 1]; number_ptr[(length - i) - 1] = temp; } break; } //------------------------------------------------------------------ // If the number is negative then make the first character a // minus sign. //------------------------------------------------------------------ if (IsNegative()) { number_string.insert(0, "-"); } return; } //================================================================== // Set this large integer value using the number in a character // string. //================================================================== bool LargeInteger::SetValue(const char * number_ptr, unsigned int base) { //------------------------------------------------------------------ // Set this instance to the value zero. //------------------------------------------------------------------ SetToZero(); //------------------------------------------------------------------ // If the passed string pointer is equal to zero then exit. //------------------------------------------------------------------ bool success_flag = number_ptr != 0; if (success_flag) { size_t length = ::strlen(number_ptr); if (length > 0) { //---------------------------------------------------------- // Skip any leading white space. //---------------------------------------------------------- size_t index = 0; for (index = 0; index < length; ++index) { if (!::isspace((int)(number_ptr[index]))) { break; } } //---------------------------------------------------------- // Test for + or - character. //---------------------------------------------------------- m_negative_flag = number_ptr[index] == '-'; if (m_negative_flag) { ++index; } if (number_ptr[index] == '+') { ++index; } //---------------------------------------------------------- // Skip white space. //---------------------------------------------------------- for (;index < length; ++index) { if (!::isspace((int)(number_ptr[index]))) { break; } } //---------------------------------------------------------- // Use special code for bases 8, 10, and 16. //---------------------------------------------------------- switch (base) { case 8: success_flag = SetValueWithBase8String(number_ptr + index); break; case 10: success_flag = SetValueWithBase10String(number_ptr + index); break; case 16: success_flag = SetValueWithBase16String(number_ptr + index); break; default: { //-------------------------------------------------- // Loop and add each digit to the value. //-------------------------------------------------- success_flag = true; for (size_t i = index; i < length; ++i) { //---------------------------------------------- // Get the numeric value of a digit. //---------------------------------------------- int digit = ::tolower((int)(number_ptr[i])); if (::isxdigit(digit)) { if ((digit >= 'a') && (digit <= 'f')) { digit = digit + 10 - (int)('a'); } else { digit = digit - (int)('0'); } if ((unsigned int)(digit) < base) { operator *=(base); operator +=(digit); } else { success_flag = false; break; } } else { break; } } } break; } } } //------------------------------------------------------------------ // Normalize the result. //------------------------------------------------------------------ Normalize(); return success_flag; } //====================================================================== // This method returns the position of the leading bit in this // large integer. If the value of this large integer is zero then // this function will return the value zero. //====================================================================== unsigned int LargeInteger::LeadingBitPosition() const { unsigned int leading_bit_position = 0; //------------------------------------------------------------------ // The number has been normalized, so there must be a bit set // in either the most significant term or the next-to most // significant term. //------------------------------------------------------------------ int leading_value_index = m_integer_length - 1; if (m_array_ptr[m_integer_length - 1] == 0) { leading_value_index--; } if (leading_value_index > 0) { unsigned int leading_value = m_array_ptr[leading_value_index]; //------------------------------------------------------------------ // Find the position of the leading bit in the leading value. //------------------------------------------------------------------ unsigned int bit_position_addend = INTEGER_HALF_BIT_COUNT; for (unsigned int i = BIT_MASK_TABLE_LENGTH - 1; int(i) >= 0; --i) { unsigned int bit_mask = BIT_MASK_ARRAY[i]; if ((leading_value & bit_mask) != 0) { leading_bit_position += bit_position_addend; leading_value = leading_value & bit_mask; bit_position_addend = bit_position_addend >> 1; } } leading_bit_position = (INTEGER_BIT_COUNT * leading_value_index) + leading_bit_position; } return leading_bit_position; } //====================================================================== // Return the count of the number of bits set in this large // integer value. //====================================================================== unsigned int LargeInteger::PopulationCount() const { unsigned int bit_count = 0; for (unsigned int i = 0; i < m_integer_length; ++i) { bit_count += PopulationCount32Bit(m_array_ptr[i]); } return bit_count; } //====================================================================== // operator = for integral types. //====================================================================== LargeInteger LargeInteger::operator =(const LargeInteger & value) { Copy(value); return *this; } LargeInteger LargeInteger::operator =(long value) { Copy(LargeInteger(value)); return *this; } LargeInteger LargeInteger::operator =(unsigned long value) { Copy(LargeInteger(value)); return *this; } LargeInteger LargeInteger::operator =(int value) { Copy(LargeInteger(value)); return *this; } LargeInteger LargeInteger::operator =(unsigned int value) { Copy(LargeInteger(value)); return *this; } LargeInteger LargeInteger::operator =(const char * psznumber_ptr) { SetValue(psznumber_ptr, m_default_base); return *this; } //====================================================================== // Unary operator + for integral types. //====================================================================== LargeInteger LargeInteger::operator +=(const LargeInteger & addend) { //------------------------------------------------------------------ // If the signs of this large integer and the sign of the addend // are the same then add the positive array values. If the signs // are NOT the same then subtract the positive array for the // addend from the positive array for this large integer. //------------------------------------------------------------------ bool negative_flag_0 = IsNegative(); bool negative_flag_1 = addend.IsNegative(); if (negative_flag_0 ^ negative_flag_1) { m_negative_flag = negative_flag_0 ^ SubtractPositiveArray(addend); } else { AddPositiveArray(addend); } //------------------------------------------------------------------ // Normalize the result. //------------------------------------------------------------------ Normalize(); return *this; } LargeInteger LargeInteger::operator +=(long addend) { return operator +=(LargeInteger(addend)); } LargeInteger LargeInteger::operator +=(unsigned long addend) { return operator +=(LargeInteger(addend)); } LargeInteger LargeInteger::operator +=(int addend) { return operator +=(LargeInteger(addend)); } LargeInteger LargeInteger::operator +=(unsigned int addend) { return operator +=(LargeInteger(addend)); } //====================================================================== // Unary operator - for integral types. //====================================================================== LargeInteger LargeInteger::operator -=(const LargeInteger & subtrahend) { //------------------------------------------------------------------ // If the signs of this large integer and the sign of the // subtrahend are the same then subtract the positive array // values of the subtrahend from the positive array values // for this large integer. If the signs are NOT the same // then add the positive array values. //------------------------------------------------------------------ bool negative_flag_0 = IsNegative(); bool negative_flag_1 = subtrahend.IsNegative(); if (negative_flag_0 ^ negative_flag_1) { AddPositiveArray(subtrahend); } else { m_negative_flag = negative_flag_0 ^ SubtractPositiveArray(subtrahend); } //------------------------------------------------------------------ // Normalize the result. //------------------------------------------------------------------ Normalize(); return *this; } LargeInteger LargeInteger::operator -=(long subtrahend) { return operator -=(LargeInteger(subtrahend)); } LargeInteger LargeInteger::operator -=(unsigned long subtrahend) { return operator -=(LargeInteger(subtrahend)); } LargeInteger LargeInteger::operator -=(int subtrahend) { return operator -=(LargeInteger(subtrahend)); } LargeInteger LargeInteger::operator -=(unsigned int subtrahend) { return operator -=(LargeInteger(subtrahend)); } //====================================================================== // Unary operator * for integral types. //====================================================================== LargeInteger LargeInteger::operator *=(const LargeInteger & x_multiplier) { //------------------------------------------------------------------ // Create a temporary variable to contain the product and set // the sign of the product. //------------------------------------------------------------------ LargeInteger product = LargeInteger(0); //------------------------------------------------------------------ // Multiply using base 65536 digits. //------------------------------------------------------------------ product.SetIntegerLength(m_integer_length + x_multiplier.m_integer_length); for (unsigned int i = 0; i < m_integer_length; ++i) { //-------------------------------------------------------------- // Get the base 65536 digits for the first multiplier. //-------------------------------------------------------------- unsigned int a0 = m_array_ptr[i] & INTEGER_LOW_HALF_MASK; unsigned int a1 = m_array_ptr[i] >> INTEGER_HALF_BIT_COUNT; for (unsigned int j = 0; j < x_multiplier.m_integer_length; ++j) { //---------------------------------------------------------- // Get the base 65536 digits for the second multiplier. //---------------------------------------------------------- unsigned int b0 = x_multiplier.m_array_ptr[j] & INTEGER_LOW_HALF_MASK; unsigned int b1 = x_multiplier.m_array_ptr[j] >> INTEGER_HALF_BIT_COUNT; //---------------------------------------------------------- // Calculate the product as shown. All multiplier // variables contain INTEGER_HALF_BIT_COUNT // bit quantities. The partial products are the // length of an unsigned integer. // // // // b1 b0 // X a1 a0 // ------------------------- // a0b0H a0b0L // a0b1H a0b1L // a1b0H a1b0L // a1b1H a1b1L // ------------------------- // p1H p1L p0H p0L // //---------------------------------------------------------- //------------------------------------------------------------------ // Calculate the 64-bit partial products. //------------------------------------------------------------------ unsigned int a0b0 = a0 * b0; unsigned int a0b1 = a0 * b1; unsigned int a1b0 = a1 * b0; unsigned int a1b1 = a1 * b1; //------------------------------------------------------------------ // Add the partial products to obtain the low dword. //------------------------------------------------------------------ unsigned int a0b1L = a0b1 << INTEGER_HALF_BIT_COUNT; unsigned int p0 = a0b0 + a0b1L; unsigned int low_dword_carry = (p0 < a0b1L) ? 1 : 0; unsigned int a1b0L = a1b0 << INTEGER_HALF_BIT_COUNT; unsigned int temp = p0 + a1b0L; low_dword_carry += (temp < p0) ? 1 : 0; p0 = temp; //------------------------------------------------------------------ // Add the partial products to obtain the high dword. // The high dword cannot carry because the largest 32-bit // product is: // // 0xFFFFFFFE00000001 = 0xFFFFFFFF * 0xFFFFFFFF //------------------------------------------------------------------ unsigned int a0b1H = a0b1 >> INTEGER_HALF_BIT_COUNT; unsigned int p1 = a1b1 + a0b1H; unsigned int a1b0H = a1b0 >> INTEGER_HALF_BIT_COUNT; p1 = p1 + a1b0H + low_dword_carry; //---------------------------------------------------------- // The 64 bit partial product has been calculated. // Accumulate the product into the appropriate // locations in the output integer array. //---------------------------------------------------------- //---------------------------------------------------------- // Accumulate the the low 32 bit sum. //---------------------------------------------------------- unsigned int index = i + j; AccumulateWithCarry(product, index, p0); //---------------------------------------------------------- // Accumulate the the high 32 bit sum. //---------------------------------------------------------- AccumulateWithCarry(product, index + 1, p1); } } //------------------------------------------------------------------ // Normalize the result. //------------------------------------------------------------------ product.Normalize(); //------------------------------------------------------------------ // Set the sign of the product. //------------------------------------------------------------------ product.m_negative_flag = IsNegative() ^ x_multiplier.IsNegative(); //------------------------------------------------------------------ // Copy the final product to this integer. //------------------------------------------------------------------ Copy(product); return *this; } //====================================================================== // Method LargeInteger::AccumulateWithCarry() // This protected method is called from the // unary operator *(const LargeInteger &) method. //====================================================================== void LargeInteger::AccumulateWithCarry(LargeInteger &product, int index, unsigned int value) { bool sum_overflows = true; while ((sum_overflows) && (index < (int)(product.m_integer_length))) { unsigned int temp = product.m_array_ptr[index]; temp = temp + value; sum_overflows = temp < value; value = 1; product.m_array_ptr[index] = temp; ++index; } } LargeInteger LargeInteger::operator *=(long multiplier) { return operator *=(LargeInteger(multiplier)); } LargeInteger LargeInteger::operator *=(unsigned long multiplier) { return operator *=(LargeInteger(multiplier)); } LargeInteger LargeInteger::operator *=(int multiplier) { return operator *=(LargeInteger(multiplier)); } LargeInteger LargeInteger::operator *=(unsigned int multiplier) { return operator *=(LargeInteger(multiplier)); } //====================================================================== // Unary operator / for integral types. //====================================================================== LargeInteger LargeInteger::operator /=(const LargeInteger & divisor) { eprintf("LargeInteger::operator /=: Warning: Division seems to yield wrong results!\n"); //------------------------------------------------------------------ // If the divisor is equal to zero then cause a divide by zero // exception. //------------------------------------------------------------------ if (divisor.IsZero()) { //throw LargeIntegerException("Divide by zero"); // Comment out the line above and uncomment the line below // to cause a regular integer divide by zero exception. //unsigned int temp = 1 / divisor.m_array_ptr[0]; eprintf("LargeInteger::operator /=: Error: Divide by zero.\n"); abort(); } //-------------------------------------------------------------- // Determine the sign of the quotient. //-------------------------------------------------------------- bool quotient_sign = IsNegative() ^ divisor.IsNegative(); //------------------------------------------------------------------ // Set the numerator variable to this object's value so that // this object can return the quotient. //------------------------------------------------------------------ LargeInteger numerator = *this; // Make this numerator positive. numerator.m_negative_flag = false; //------------------------------------------------------------------ // Set the initial value of the quotient to zero. //------------------------------------------------------------------ SetToZero(); //------------------------------------------------------------------ // If the numerator is zero or the the denominator is greater than // the numerator then the quotient is zero. //------------------------------------------------------------------ if (!numerator.IsZero()) { //-------------------------------------------------------------- // Shift the denominator to the left until it becomes the // greatest shifted value that is less than or equal to the // numerator. //-------------------------------------------------------------- int scale_shift = 0; LargeInteger denom = divisor; while (denom < numerator) { denom.ShiftLeft(1); ++scale_shift; } //-------------------------------------------------------------- // Perform long division. //-------------------------------------------------------------- while (numerator >= denom) { LargeInteger difference = numerator - denom; denom.ShiftRight(1); ShiftLeft(1); if (!difference.IsNegative()) { ++m_array_ptr[0]; numerator = difference; } } //-------------------------------------------------------------- // Adjust the numerator for the denominator scaling. //-------------------------------------------------------------- *this <<= scale_shift; //-------------------------------------------------------------- // Normalize the result. //-------------------------------------------------------------- Normalize(); m_negative_flag = quotient_sign; } return *this; } LargeInteger LargeInteger::operator /=(long divisor) { return operator /=(LargeInteger(divisor)); } LargeInteger LargeInteger::operator /=(unsigned long divisor) { return operator /=(LargeInteger(divisor)); } LargeInteger LargeInteger::operator /=(int divisor) { return operator /=(LargeInteger(divisor)); } LargeInteger LargeInteger::operator /=(unsigned int divisor) { return operator /=(LargeInteger(divisor)); } //====================================================================== // operator <<= for integral types. //====================================================================== LargeInteger LargeInteger::operator <<=(const LargeInteger & shift_count) { if (shift_count.FitsIn32Bits()) { if (shift_count.IsNegative()) { ShiftRight(shift_count.m_array_ptr[0]); } else { ShiftLeft(shift_count.m_array_ptr[0]); } } else { SetToZero(); } return *this; } LargeInteger LargeInteger::operator <<=(long shift_count) { return operator <<=(LargeInteger(shift_count)); } LargeInteger LargeInteger::operator <<=(unsigned long shift_count) { return operator <<=(LargeInteger(shift_count)); } LargeInteger LargeInteger::operator <<=(int shift_count) { return operator <<=(LargeInteger(shift_count)); } LargeInteger LargeInteger::operator <<=(unsigned int shift_count) { return operator <<=(LargeInteger(shift_count)); } //====================================================================== // operator >>= for integral types. //====================================================================== LargeInteger LargeInteger::operator >>=(const LargeInteger & shift_count) { if (shift_count.FitsIn32Bits()) { if (shift_count.IsNegative()) { ShiftLeft(shift_count.m_array_ptr[0]); } else { ShiftRight(shift_count.m_array_ptr[0]); } } else { SetToZero(); } return *this; } LargeInteger LargeInteger::operator >>=(long shift_count) { return operator >>=(LargeInteger(shift_count)); } LargeInteger LargeInteger::operator >>=(unsigned long shift_count) { return operator >>=(LargeInteger(shift_count)); } LargeInteger LargeInteger::operator >>=(int shift_count) { return operator >>=(LargeInteger(shift_count)); } LargeInteger LargeInteger::operator >>=(unsigned int shift_count) { return operator >>=(LargeInteger(shift_count)); } //====================================================================== // Unary operator %= for integral types. //====================================================================== LargeInteger LargeInteger::operator %=(const LargeInteger & divisor) { LargeInteger x_temp(*this); operator /=(divisor); operator *=(divisor); return operator -=(x_temp); } LargeInteger LargeInteger::operator %=(long divisor) { return operator %=(LargeInteger(divisor)); } LargeInteger LargeInteger::operator %=(unsigned long divisor) { return operator %=(LargeInteger(divisor)); } LargeInteger LargeInteger::operator %=(int divisor) { return operator %=(LargeInteger(divisor)); } LargeInteger LargeInteger::operator %=(unsigned int divisor) { return operator %=(LargeInteger(divisor)); } //====================================================================== // operator ^= for integral types. //====================================================================== LargeInteger LargeInteger::operator ^=(const LargeInteger & value) { unsigned int largest_integer_length = m_integer_length < value.m_integer_length ? value.m_integer_length : m_integer_length; SetIntegerLength(largest_integer_length); for (unsigned int i = 0; i < m_integer_length; ++i) { m_array_ptr[i] ^= value.GetSafeArrayValue(i); } //------------------------------------------------------------------ // Normalize the result. //------------------------------------------------------------------ Normalize(); return *this; } LargeInteger LargeInteger::operator ^=(long value) { return operator %=(LargeInteger(value)); } LargeInteger LargeInteger::operator ^=(unsigned long value) { return operator %=(LargeInteger(value)); } LargeInteger LargeInteger::operator ^=(int value) { return operator %=(LargeInteger(value)); } LargeInteger LargeInteger::operator ^=(unsigned int value) { return operator %=(LargeInteger(value)); } //====================================================================== // operator &= for integral types. //====================================================================== LargeInteger LargeInteger::operator &=(const LargeInteger & value) { unsigned int largest_integer_length = m_integer_length < value.m_integer_length ? value.m_integer_length : m_integer_length; SetIntegerLength(largest_integer_length); for (unsigned int i = 0; i < m_integer_length; ++i) { m_array_ptr[i] &= value.GetSafeArrayValue(i); } //------------------------------------------------------------------ // Normalize the result. //------------------------------------------------------------------ Normalize(); return *this; } LargeInteger LargeInteger::operator &=(unsigned long value) { return operator &=(LargeInteger(value)); } LargeInteger LargeInteger::operator &=(int value) { return operator &=(LargeInteger(value)); } LargeInteger LargeInteger::operator &=(unsigned int value) { return operator &=(LargeInteger(value)); } //====================================================================== // operator |= for integral types. //====================================================================== LargeInteger LargeInteger::operator |=(const LargeInteger & value) { unsigned int largest_integer_length = m_integer_length < value.m_integer_length ? value.m_integer_length : m_integer_length; SetIntegerLength(largest_integer_length); for (unsigned int i = 0; i < m_integer_length; ++i) { m_array_ptr[i] |= value.GetSafeArrayValue(i); } //------------------------------------------------------------------ // Normalize the result. //------------------------------------------------------------------ Normalize(); return *this; } LargeInteger LargeInteger::operator |=(long value) { return operator |=(LargeInteger(value)); } LargeInteger LargeInteger::operator |=(unsigned long value) { return operator |=(LargeInteger(value)); } LargeInteger LargeInteger::operator |=(int value) { return operator |=(LargeInteger(value)); } LargeInteger LargeInteger::operator |=(unsigned int value) { return operator |=(LargeInteger(value)); } //====================================================================== // operators with no arguments. The * operator and the & operator // with no arguments do not need to be overloaded. //====================================================================== LargeInteger LargeInteger::operator !() { if (IsZero()) { m_array_ptr[0] = (unsigned int)(-1); m_integer_length = 1; } else { SetToZero(); } return *this; } LargeInteger LargeInteger::operator ~() { for (unsigned int i = 0; i < m_integer_length; ++i) { m_array_ptr[i] = ~m_array_ptr[i]; } //------------------------------------------------------------------ // Normalize the result. //------------------------------------------------------------------ Normalize(); return *this; } LargeInteger LargeInteger::operator +() { return *this; } LargeInteger LargeInteger::operator -() { m_negative_flag = ! m_negative_flag; return *this; } //====================================================================== // The prefix form of the increment and decrement operators. //====================================================================== const LargeInteger LargeInteger::operator ++() { operator +=(1); return *this; } const LargeInteger LargeInteger::operator --() { operator -=(1); return *this; } //====================================================================== // The postfix form of the increment and decrement operators. //====================================================================== const LargeInteger LargeInteger::operator ++(int) { LargeInteger x_temp = *this; operator +=(1); return x_temp; } const LargeInteger LargeInteger::operator --(int) { LargeInteger x_temp = *this; operator -=(1); return x_temp; } //====================================================================== // Unary operator == for integral types. //====================================================================== bool LargeInteger::operator ==(const LargeInteger & value) const { unsigned int largest_integer_length = m_integer_length < value.m_integer_length ? value.m_integer_length : m_integer_length; bool bEqual = true; for (unsigned int i = largest_integer_length - 1; (int)(i) >= 0; --i) { if (GetSafeArrayValue(i) != value.GetSafeArrayValue(i)) { bEqual = false; break; } } return bEqual; } bool LargeInteger::operator ==(long value) const { return operator ==(LargeInteger(value)); } bool LargeInteger::operator ==(unsigned long value) const { return operator ==(LargeInteger(value)); } bool LargeInteger::operator ==(int value) const { return operator ==(LargeInteger(value)); } bool LargeInteger::operator ==(unsigned int value) const { return operator ==(LargeInteger(value)); } //====================================================================== // Unary operator != for integral types. //====================================================================== bool LargeInteger::operator !=(const LargeInteger & value) const { return ! operator ==(value); } bool LargeInteger::operator !=(long value) const { return operator !=(LargeInteger(value)); } bool LargeInteger::operator !=(unsigned long value) const { return operator !=(LargeInteger(value)); } bool LargeInteger::operator !=(int value) const { return operator !=(LargeInteger(value)); } bool LargeInteger::operator !=(unsigned int value) const { return operator !=(LargeInteger(value)); } //====================================================================== // Unary operator < for integral types. //====================================================================== bool LargeInteger::operator <(const LargeInteger & value) const { //------------------------------------------------------------------ // If this value is negative and value is positive then // return true. //------------------------------------------------------------------ bool is_less_than_flag = false; if (IsNegative()) { if (!value.IsNegative()) { is_less_than_flag = true; } else { is_less_than_flag = LessThanPositiveArrayCompare(value, *this); } } else { is_less_than_flag = LessThanPositiveArrayCompare(*this, value); } return is_less_than_flag; } bool LargeInteger::operator <(long value) const { return operator <(LargeInteger(value)); } bool LargeInteger::operator <(unsigned long value) const { return operator <(LargeInteger(value)); } bool LargeInteger::operator <(int value) const { return operator <(LargeInteger(value)); } bool LargeInteger::operator <(unsigned int value) const { return operator <(LargeInteger(value)); } //====================================================================== // Unary operator > for integral types. //====================================================================== bool LargeInteger::operator >(const LargeInteger & value) const { return ((!operator <(value)) && (!operator ==(value))); } bool LargeInteger::operator >(long value) const { return operator >(LargeInteger(value)); } bool LargeInteger::operator >(unsigned long value) const { return operator >(LargeInteger(value)); } bool LargeInteger::operator >(int value) const { return operator >(LargeInteger(value)); } bool LargeInteger::operator >(unsigned int value) const { return operator >(LargeInteger(value)); } //====================================================================== // Unary operator <= for integral types. //====================================================================== bool LargeInteger::operator <=(const LargeInteger & value) const { return ! operator >(value); } bool LargeInteger::operator <=(long value) const { return operator <=(LargeInteger(value)); } bool LargeInteger::operator <=(unsigned long value) const { return operator <=(LargeInteger(value)); } bool LargeInteger::operator <=(int value) const { return operator <=(LargeInteger(value)); } bool LargeInteger::operator <=(unsigned int value) const { return operator <=(LargeInteger(value)); } //====================================================================== // Unary operator >= for integral types. //====================================================================== bool LargeInteger::operator >=(const LargeInteger & value) const { return ! operator <(value); } bool LargeInteger::operator >=(long value) const { return operator <(LargeInteger(value)); } bool LargeInteger::operator >=(unsigned long value) const { return operator <(LargeInteger(value)); } bool LargeInteger::operator >=(int value) const { return operator <(LargeInteger(value)); } bool LargeInteger::operator >=(unsigned int value) const { return operator <(LargeInteger(value)); } //====================================================================== // Cast conversion operators. //====================================================================== LargeInteger::operator long() const { return (long)(m_array_ptr[0]); } LargeInteger::operator unsigned long() const { return (unsigned long)(m_array_ptr[0]); } LargeInteger::operator int() const { return (int)(m_array_ptr[0]); } LargeInteger::operator unsigned int() const { return (m_array_ptr[0]); } LargeInteger::operator short() const { return (short)(m_array_ptr[0]); } LargeInteger::operator unsigned short() const { return (unsigned short)(m_array_ptr[0]); } LargeInteger::operator char() const { return (char)(m_array_ptr[0]); } LargeInteger::operator unsigned char() const { return (unsigned char)(m_array_ptr[0]); } LargeInteger::operator bool() const { unsigned int temp = 0; for (unsigned int i = 0; i < m_integer_length; ++i) { temp = temp | m_array_ptr[i]; } return temp != 0; } LargeInteger::operator float() const { #if defined __GNUC__ double Temp = double(*this); return float(Temp); #else long double Temp = long double(*this); return float(Temp); #endif } LargeInteger::operator double() const { double temp = 0; for (int i = m_integer_length - 1; i >= 0; i--) { temp = D_MAX_UNSIGNED_VALUE * temp; temp = temp + m_array_ptr[i]; } return temp; /* #if defined __GNUC__ double Temp = double(*this); return Temp; #else long double Temp = long double(*this); return double(Temp); #endif */ } LargeInteger::operator long double() const { //------------------------------------------------------------------ // If this value is negative then calculate the absolute value. //------------------------------------------------------------------ LargeInteger x_temp; //------------------------------------------------------------------ // Calculate the value as a long double. //------------------------------------------------------------------ long double temp = 0; // for (unsigned int i = m_integer_length - 1; (int)(i) >= 0; ++i) for (int i = m_integer_length - 1; i >= 0; i--) { temp = D_MAX_UNSIGNED_VALUE * temp; temp = temp + m_array_ptr[i]; } return temp; } #ifdef _DEBUG //====================================================================== // Dump the internal format of this large integer. //====================================================================== void LargeInteger::DebugDump(const char * pszText) { if (pszText != 0) { std::cout << pszText << std::endl; } std::cout << "Length = " << m_integer_length << std::endl; for (unsigned int i = 0; i < m_integer_length; ++i) { std::cout << i << " " << m_array_ptr[i] << std::endl; } return; } #endif //====================================================================== // Function to copy an instance of a large integer. //====================================================================== void LargeInteger::Copy(const LargeInteger & that) { SetIntegerLength(that.m_integer_length); m_negative_flag = that.m_negative_flag; for (unsigned int i = 0; i < m_integer_length; ++i) { m_array_ptr[i] = that.m_array_ptr[i]; } return; } //====================================================================== // Add to this large integer. //====================================================================== void LargeInteger::AddPositiveArray(const LargeInteger & addend) { //------------------------------------------------------------------ // Make sure this large integer's array is as least as large // as the addends array. //------------------------------------------------------------------ if (m_integer_length < addend.m_integer_length) { SetIntegerLength(addend.m_integer_length, true); } //------------------------------------------------------------------ // Add the addend to this large integer. //------------------------------------------------------------------ unsigned int carry = 0; for (unsigned int i = 0; i < m_integer_length; ++i) { unsigned int addend_array_value = addend.GetSafeArrayValue(i); m_array_ptr[i] = m_array_ptr[i] + addend_array_value + carry; carry = (m_array_ptr[i] < addend_array_value) ? 1 : 0; } //------------------------------------------------------------------ // If a carry occurred in the most significant word then increase // the size of this large integer. //------------------------------------------------------------------ if (carry == 1) { SetIntegerLength(m_integer_length + 1, true); m_array_ptr[m_integer_length - 1] = 1; } return; } //====================================================================== // Subtract from this large integer. //====================================================================== bool LargeInteger::SubtractPositiveArray(const LargeInteger & subtrahend) { //------------------------------------------------------------------ // Make sure this large integer's array is the same size // as the subtrahend's array. //------------------------------------------------------------------ if (m_integer_length < subtrahend.m_integer_length) { SetIntegerLength(subtrahend.m_integer_length, true); } //------------------------------------------------------------------ // Save the most significant array value. If this increases // after the subtraction then the minuend is less than the // subtrahend. //------------------------------------------------------------------ unsigned int most_significant_array_value = m_array_ptr[m_integer_length - 1]; //------------------------------------------------------------------ // Subtract the subtrahend from this large integer. //------------------------------------------------------------------ bool borrow = false; for (unsigned int i = 0; i < m_integer_length; ++i) { unsigned int minuend_array_value = m_array_ptr[i]; unsigned int subtrahend_array_value = subtrahend.GetSafeArrayValue(i); unsigned int difference = minuend_array_value - subtrahend_array_value; m_array_ptr[i] = difference - (borrow ? 1 : 0); borrow = borrow & (difference == 0); if (!borrow) { borrow = minuend_array_value < subtrahend_array_value; } } //------------------------------------------------------------------ // If the result taken as a two's complement integer is negative // then the magnitude of the minuend was less than the magnitude // of the subtrahend. In this case, take the two's complement of // the result to get a positive result and return the value true // from this method to signal the the sign of the result should // be toggled. //------------------------------------------------------------------ bool reverse_sign = m_array_ptr[m_integer_length - 1] > most_significant_array_value; if (reverse_sign) { //------------------------------------------------------------- // Add one to the one's complement of the result to obtain // the two's complement value. //------------------------------------------------------------- operator ~(); LargeInteger xOne(1); AddPositiveArray(xOne); } return reverse_sign; } //====================================================================== // Function to shift this large integer to the left. //====================================================================== void LargeInteger::ShiftLeft(unsigned int shift_count) { if (shift_count != 0) { //-------------------------------------------------------------- // The array could grow as a result of this shift. Determine // the new size of the array. Find the first non-zero value // in the array starting at the most significant array value. //-------------------------------------------------------------- bool bNonZero = false; unsigned int nonzero_array_index = 0; for (nonzero_array_index = m_integer_length - 1; (int)(nonzero_array_index) >= 0; --nonzero_array_index) { if (m_array_ptr[nonzero_array_index] != 0) { bNonZero = true; break; } } //-------------------------------------------------------------- // If the value is zero then it is not necessary to shift // this value. //-------------------------------------------------------------- if (bNonZero) { //---------------------------------------------------------- // Determine the position of the bit in the most // significant word. //---------------------------------------------------------- unsigned int most_significant_value = m_array_ptr[nonzero_array_index]; unsigned int bit_position = 0; for (bit_position = 0; bit_position < INTEGER_BIT_COUNT; ++bit_position) { //------------------------------------------------------ // Test the most significant bit. //------------------------------------------------------ if ((int)(most_significant_value) < 0) { break; } most_significant_value <<= 1; } bit_position = INTEGER_BIT_COUNT - 1 - bit_position; //---------------------------------------------------------- // Calculate the position of the most significant bit // in the integer array. //---------------------------------------------------------- unsigned int array_bit_position = INTEGER_BIT_COUNT * nonzero_array_index + bit_position; //---------------------------------------------------------- // Calculate the position of the most significant bit // after shifting this number to the left. //---------------------------------------------------------- unsigned int final_shift_position = array_bit_position + shift_count; //---------------------------------------------------------- // Make the number array large enough for the left shift. //---------------------------------------------------------- unsigned int integer_length = (final_shift_position + INTEGER_BIT_COUNT) / INTEGER_BIT_COUNT; SetIntegerLength(integer_length, true); //---------------------------------------------------------- // Do all shifts that are a multiple of 32. //---------------------------------------------------------- unsigned int array_shift_value = shift_count / INTEGER_BIT_COUNT; if (array_shift_value != 0) { for (unsigned int i = m_integer_length - 1; (int)(i) >= 0; --i) { m_array_ptr[i] = GetSafeArrayValue(i - array_shift_value); } } //---------------------------------------------------------- // Do the remaining shifts. //---------------------------------------------------------- unsigned int remaining_shift_count = shift_count - (array_shift_value * INTEGER_BIT_COUNT); for (unsigned int i = m_integer_length - 1; (int)(i) >= 0; --i) { m_array_ptr[i] = (m_array_ptr[i] << remaining_shift_count) | (GetSafeArrayValue(i - 1) >> (INTEGER_BIT_COUNT - remaining_shift_count)); } //---------------------------------------------------------- // Normalize the result. //---------------------------------------------------------- Normalize(); } } return; } //====================================================================== // Function to shift this large integer to the right. //====================================================================== void LargeInteger::ShiftRight(unsigned int shift_count) { if (shift_count != 0) { //-------------------------------------------------------------- // Do all shifts that are a multiple of 32. //-------------------------------------------------------------- if (shift_count < m_integer_length * INTEGER_BIT_COUNT) { unsigned int array_shift_value = shift_count / INTEGER_BIT_COUNT; if (array_shift_value != 0) { for (unsigned int i = 0; i < m_integer_length - array_shift_value; ++i) { m_array_ptr[i] = m_array_ptr[i + array_shift_value]; } } //---------------------------------------------------------- // Do the remaining shifts. //---------------------------------------------------------- unsigned int remaining_shift_count = shift_count - (array_shift_value * INTEGER_BIT_COUNT); for (unsigned int i = 0; i < m_integer_length; ++i) { m_array_ptr[i] = (m_array_ptr[i] >> remaining_shift_count) | (GetSafeArrayValue(i + 1) << (INTEGER_BIT_COUNT - remaining_shift_count)); } //---------------------------------------------------------- // Normalize the result. //---------------------------------------------------------- Normalize(); } else { SetToZero(); } } return; } //====================================================================== // Function to test for this large integer equal to zero. //====================================================================== bool LargeInteger::IsZero() const { unsigned int temp = 0; for (unsigned int i = 0; i < m_integer_length; ++i) { temp |= m_array_ptr[i]; } return temp == 0; } //====================================================================== // Function to test for this large integer equal to zero. //====================================================================== bool LargeInteger::IsNegative() const { return m_negative_flag; } //====================================================================== // Function to test if the value fits in 32 bits. //====================================================================== bool LargeInteger::FitsIn32Bits() const { return m_integer_length == 1; } //====================================================================== // Member Function: LargeInteger::SetIntegerLength // Author: Bill Hallahan // Date: March 30, 1998 // // Abstract: // // This function is called to set the large integer length. // If the new integer length is greater than the current array // length OR the new buffer length is less than one fourth the // current array length then the array is reallocated. If the // buffer is resized to a be smaller array OR if the passed // boolean value 'copy_data_flag' is the value true then the // data in the old array is copied to the newly allocated // array before the old array memory is freed. // // // Input: // // integer_length The new integer length. // // copy_data_flag If this flag is true then the // data in the array before the length // is modified is copied into the new // buffer. The value is sign extended // if necessary.. // // // Output: // // This function has no return value. // //====================================================================== void LargeInteger::SetIntegerLength(unsigned int integer_length, bool copy_data_flag) { //------------------------------------------------------------------ // If the new data length is greater than the current buffer // length then allocate a larger buffer for the data. // Also if the new data length is less than one fourth the // current buffer length then allocate a new array. //------------------------------------------------------------------ bool reallocate_array_memory = integer_length > m_array_length; //------------------------------------------------------------------ // Also if the new data length is less than one fourth the // current buffer length then allocate a new array. //------------------------------------------------------------------ if (!reallocate_array_memory) { reallocate_array_memory = integer_length < (m_array_length >> 2); copy_data_flag = true; } //------------------------------------------------------------------ // Conditionally reallocate the large integer array. //------------------------------------------------------------------ if (reallocate_array_memory) { //-------------------------------------------------------------- // Allocate a new buffer. //-------------------------------------------------------------- unsigned int * array_ptr = new unsigned int [integer_length]; bool memory_allocated = array_ptr != 0; if (memory_allocated) { if (copy_data_flag) { //------------------------------------------------------ // Copy the data from the old buffer to the new one. //------------------------------------------------------ unsigned int copy_length = integer_length; if (m_integer_length < integer_length) { copy_length = m_integer_length; } for (unsigned int i = 0; i < copy_length; ++i) { array_ptr[i] = m_array_ptr[i]; } //------------------------------------------------------ // If the copied data is shorter than the new array // length then zero-fill the rest of the array. //------------------------------------------------------ if (copy_length < integer_length) { for (unsigned int j = copy_length; j < integer_length; ++j) { array_ptr[j] = 0; } } } else { //------------------------------------------------------ // Fill the array with zeros. //------------------------------------------------------ for (unsigned int i = 0; i < integer_length; ++i) { array_ptr[i] = 0; } } //---------------------------------------------------------- // Delete the old buffer. //---------------------------------------------------------- delete [] m_array_ptr; //---------------------------------------------------------- // Save the new buffer pointer. //---------------------------------------------------------- m_array_ptr = array_ptr; //---------------------------------------------------------- // Set the buffer length and the integer length. //---------------------------------------------------------- m_array_length = integer_length; } else { //---------------------------------------------------------- // Memory allocation failed. Throw an exception. //---------------------------------------------------------- //throw LargeIntegerException("Memory allocation failed"); eprintf("LargeInteger::SetIntegerLength(): Error: Memory allocation failed.\n"); abort(); } } //------------------------------------------------------------------ // Set the length of the integer. //------------------------------------------------------------------ m_integer_length = integer_length; return; } //====================================================================== // Set this large integer value to zero. //====================================================================== void LargeInteger::SetToZero() { SetIntegerLength(1); m_array_ptr[0] = 0; return; } //====================================================================== // Get the array value. If the index is out of range then return // the value zero. //====================================================================== unsigned int LargeInteger::GetSafeArrayValue(unsigned int index) const { unsigned int array_value; if (index < m_integer_length) { array_value = m_array_ptr[index]; } else { array_value = 0; } return array_value; } //====================================================================== // Set the integer length to the smallest length for this value. //====================================================================== void LargeInteger::Normalize() { //------------------------------------------------------------------ // Discard all leading zeros. //------------------------------------------------------------------ unsigned int integer_length = 1; for (unsigned int i = m_integer_length - 1; i > 0; --i) { if (m_array_ptr[i] != 0) { integer_length = i + 1; break; } } m_integer_length = integer_length; return; } //====================================================================== // Private Method to compare the positive arrays of two large integers. //====================================================================== bool LargeInteger::LessThanPositiveArrayCompare(const LargeInteger & value_0, const LargeInteger & value_1) const { unsigned int largest_integer_length = value_0.m_integer_length > value_1.m_integer_length ? value_0.m_integer_length : value_1.m_integer_length; bool is_less_than_flag = false; for (unsigned int i = largest_integer_length - 1; (int)(i) >= 0; --i) { unsigned int array_value_0 = value_0.GetSafeArrayValue(i); unsigned int array_value_1 = value_1.GetSafeArrayValue(i); if (array_value_0 < array_value_1) { is_less_than_flag = true; } else if (array_value_0 > array_value_1) { break; } } return is_less_than_flag; } //====================================================================== // Calculate the population count for a 32 bit integer. //====================================================================== unsigned int LargeInteger::PopulationCount32Bit(unsigned int value) const { #ifndef LARGE_INT_ALTERNATE_POP_COUNT unsigned int shift_value = 1; for (unsigned int i = 0; i < BIT_MASK_TABLE_LENGTH; ++i) { unsigned int bit_mask = BIT_MASK_ARRAY[i]; value = ((value & bit_mask) >> shift_value) + (value & ~bit_mask); shift_value = shift_value << 1; } return value; #else unsigned int temp = value - ((value >> 1) & MASK_3) - ((value >> 2) & MASK_1); temp = (temp + (temp >> 3)) & MASK_7; return temp % 63; #endif } //====================================================================== // Get this large integer value in an stl string in base 8. //====================================================================== void LargeInteger::GetBase8NumberString(std::string & number_string) const { //-------------------------------------------------------------- // Get the base 8 digits. //-------------------------------------------------------------- std::string base8_digits_string; GetBase8Digits(base8_digits_string); //-------------------------------------------------------------- // Convert the base 8 digits to ascii characters. //-------------------------------------------------------------- number_string.erase(); for (unsigned int i = 0; i < base8_digits_string.length(); ++i) { number_string += base8_digits_string[i] + '0'; } return; } //====================================================================== // Get the base 8 digits in an STL string. //====================================================================== void LargeInteger::GetBase8Digits(std::string & base8_digits_string) const { base8_digits_string.erase(); //-------------------------------------------------------------- // Calculate the base 8 digits. Convert 3 bits at a time // to an octal digit starting at the most significant bits. //-------------------------------------------------------------- unsigned int current_bit_position_plus_one = INTEGER_BIT_COUNT * m_integer_length; unsigned int extra_bits = current_bit_position_plus_one % 3; unsigned int index = m_integer_length - 1; while (current_bit_position_plus_one != 0) { char base8_digit; switch (extra_bits) { case 0: base8_digits_string += (char)((m_array_ptr[index] >> 29) & 7); base8_digits_string += (char)((m_array_ptr[index] >> 26) & 7); base8_digits_string += (char)((m_array_ptr[index] >> 23) & 7); base8_digits_string += (char)((m_array_ptr[index] >> 20) & 7); base8_digits_string += (char)((m_array_ptr[index] >> 17) & 7); base8_digits_string += (char)((m_array_ptr[index] >> 14) & 7); base8_digits_string += (char)((m_array_ptr[index] >> 11) & 7); base8_digits_string += (char)((m_array_ptr[index] >> 8) & 7); base8_digits_string += (char)((m_array_ptr[index] >> 5) & 7); base8_digits_string += (char)((m_array_ptr[index] >> 2) & 7); break; case 1: base8_digit = (char)(((GetSafeArrayValue(index + 1) & 3) << 1) | ((m_array_ptr[index] >> 31) & 1)); base8_digits_string += base8_digit; base8_digits_string += (char)((m_array_ptr[index] >> 28) & 7); base8_digits_string += (char)((m_array_ptr[index] >> 25) & 7); base8_digits_string += (char)((m_array_ptr[index] >> 22) & 7); base8_digits_string += (char)((m_array_ptr[index] >> 19) & 7); base8_digits_string += (char)((m_array_ptr[index] >> 16) & 7); base8_digits_string += (char)((m_array_ptr[index] >> 13) & 7); base8_digits_string += (char)((m_array_ptr[index] >> 10) & 7); base8_digits_string += (char)((m_array_ptr[index] >> 7) & 7); base8_digits_string += (char)((m_array_ptr[index] >> 4) & 7); base8_digits_string += (char)((m_array_ptr[index] >> 1) & 7); break; case 2: base8_digit = (char)(((GetSafeArrayValue(index + 1) & 1) << 2) | ((m_array_ptr[index] >> 30) & 3)); base8_digits_string += base8_digit; base8_digits_string += (char)((m_array_ptr[index] >> 27) & 7); base8_digits_string += (char)((m_array_ptr[index] >> 24) & 7); base8_digits_string += (char)((m_array_ptr[index] >> 21) & 7); base8_digits_string += (char)((m_array_ptr[index] >> 18) & 7); base8_digits_string += (char)((m_array_ptr[index] >> 15) & 7); base8_digits_string += (char)((m_array_ptr[index] >> 12) & 7); base8_digits_string += (char)((m_array_ptr[index] >> 9) & 7); base8_digits_string += (char)((m_array_ptr[index] >> 6) & 7); base8_digits_string += (char)((m_array_ptr[index] >> 3) & 7); base8_digits_string += (char)(m_array_ptr[index] & 7); break; default: break; } --index; extra_bits = (extra_bits + 1) % 3; current_bit_position_plus_one -= INTEGER_BIT_COUNT; } //------------------------------------------------------------------ // Strip any extra sign extension characters. //------------------------------------------------------------------ StripLeadingZeroDigits(base8_digits_string, 0); return; } //====================================================================== // Get this large integer value in an stl string in base 10. //====================================================================== void LargeInteger::GetBase10NumberString(std::string & number_string) const { //------------------------------------------------------------------ // Determine whether the product is a negative value. //------------------------------------------------------------------ LargeInteger x_temp = *this; //------------------------------------------------------------------ // Get the base 8 digits. //------------------------------------------------------------------ std::string digits_string; x_temp.GetBase8Digits(digits_string); //------------------------------------------------------------------ // Convert the base 8 string to a base 10 string using the // algorithm from "Semi-Numerical Methods", by Knuth. // Double the K leading octal digits using decimal arithmetic // and subtract them from the K + 1 leading digits using // decimal arithmetic. //------------------------------------------------------------------ char * digit_array_ptr = const_cast(digits_string.data()); unsigned int digit_length = (unsigned int)(digits_string.length()); char * subtrahend_ptr = new char [digit_length]; if (subtrahend_ptr == 0) { //throw LargeIntegerException("Memory allocation failed"); eprintf("LargeInteger::GetBase10NumberString(): Error: Memory allocation failed.\n"); abort(); } for (unsigned int k = 0; k < digit_length - 1; ++k) { //-------------------------------------------------------------- // Double the K leading octal digits using base 10 arithmetic // and copy these digits into the K + 1'st location in the // subtrahend array. //-------------------------------------------------------------- unsigned int j = 0; for (j = k + 1; (int)(j) >= 0; --j) { subtrahend_ptr[j] = 0; } for (j = k; (int)(j) >= 0; --j) { char doubled_digit = digit_array_ptr[j] << 1; if (doubled_digit > 9) { subtrahend_ptr[j + 1] += doubled_digit - 10; subtrahend_ptr[j] += 1; } else { subtrahend_ptr[j + 1] += doubled_digit; } } //-------------------------------------------------------------- // Subtract the doubled digits from the original number // using decimal arithmetic. //-------------------------------------------------------------- for (unsigned int m = k + 1; (int)(m) >= 0; --m) { char difference = digit_array_ptr[m] - subtrahend_ptr[m]; if (difference < 0) { digit_array_ptr[m] = difference + 10; if ((int)(m - 1) >= 0) { digit_array_ptr[m - 1] -= 1; } } else { digit_array_ptr[m] = difference; } } } delete [] subtrahend_ptr; //------------------------------------------------------------------ // Convert the digits to characters. First skip all leading zeros. //------------------------------------------------------------------ unsigned int first_nonzero_position = 0; for (first_nonzero_position = 0; first_nonzero_position < digits_string.length(); ++first_nonzero_position) { if (digits_string[first_nonzero_position] != 0) { break; } } number_string.erase(); for (unsigned int j = first_nonzero_position; j < digits_string.length(); ++j) { number_string += digits_string[j] + '0'; } return; } //====================================================================== // Get this large integer value in an stl string in base 16. //====================================================================== void LargeInteger::GetBase16NumberString(std::string & number_string) const { number_string.erase(); //------------------------------------------------------------------ // Convert the digits. //------------------------------------------------------------------ for (unsigned int i = m_integer_length - 1; (int)(i) >= 0; --i) { unsigned int hex_digits = m_array_ptr[i]; for (int iShift = 28; iShift >= 0; iShift -= 4) { number_string += DIGIT_ARRAY[((hex_digits >> iShift) & 0x0F)]; } } //------------------------------------------------------------------ // Strip any extra sign extension characters. //------------------------------------------------------------------ StripLeadingZeroDigits(number_string, '0'); return; } //====================================================================== // Strip any extra zero digits. //====================================================================== void LargeInteger::StripLeadingZeroDigits(std::string & number_string, char zero_digit) const { //------------------------------------------------------------------ // Find the position past any extra zero digit characters. //------------------------------------------------------------------ int start_position = 0; int digit_length = (int)number_string.length(); for (int index = 0; index < digit_length - 1; ++index) { if (number_string[index] == zero_digit) { ++start_position; } else { break; } } //------------------------------------------------------------------ // If necessary then strip leading zero digit characters. //------------------------------------------------------------------ if (start_position != 0) { if (start_position > 0) { number_string = number_string.substr(start_position); } else { number_string = number_string.substr(digit_length - 1); } } return; } //====================================================================== // Set the value of this large integer value using a base 8 string. // Leading sign characters and space characters must be removed // before calling this method. //====================================================================== bool LargeInteger::SetValueWithBase8String(const char * base8_digits_ptr) { //------------------------------------------------------------------ // Get the length of the input string. //------------------------------------------------------------------ size_t digit_length = ::strlen(base8_digits_ptr); //------------------------------------------------------------------ // Convert the octal digit characters to octal values. //------------------------------------------------------------------ std::string digits_string = base8_digits_ptr; char * digit_array_ptr = const_cast(digits_string.data()); digit_length = (unsigned int)(digits_string.length()); //------------------------------------------------------------------ // Convert the digit characters to digit values. //------------------------------------------------------------------ bool success_flag = false; for (int i = 0; i < (int)(digit_length); ++i) { char digit = digit_array_ptr[i]; success_flag = ((digit >= '0') && (digit < '8')); if (success_flag) { digit_array_ptr[i] = digit - '0'; } else { break; } } if (success_flag) { //-------------------------------------------------------------- // Strip any extra sign extension characters. //-------------------------------------------------------------- StripLeadingZeroDigits(digits_string, 0); //-------------------------------------------------------------- // Set the value of this large integer using the base 8 // digit values. //-------------------------------------------------------------- SetValueWithBase8DigitValues(digits_string); } return success_flag; } //====================================================================== // Set the value of this large integer using the base 8 digit values. //====================================================================== void LargeInteger::SetValueWithBase8DigitValues(const std::string & base8_digit_string) { //------------------------------------------------------------------ // Set the length of the array. //------------------------------------------------------------------ unsigned int number_of_digits = (unsigned int)base8_digit_string.length(); unsigned int current_bit_position_plus_one = 3 * number_of_digits; unsigned int integer_length = (current_bit_position_plus_one + (INTEGER_BIT_COUNT - 1)) / INTEGER_BIT_COUNT; SetIntegerLength(integer_length); //------------------------------------------------------------------ // Add each digit to the array. //------------------------------------------------------------------ current_bit_position_plus_one -= 3; unsigned int array_index = integer_length - 1; for (unsigned int octal_digit_index = 0; octal_digit_index < number_of_digits; ++octal_digit_index) { // The bit length is currently 32-bits. #ifdef INT_BIT_LENGTH_IS_POWER_OF_TWO unsigned int shift_value = current_bit_position_plus_one & (INTEGER_BIT_COUNT - 1); #else unsigned int shift_value = current_bit_position_plus_one % INTEGER_BIT_COUNT; #endif current_bit_position_plus_one -= 3; unsigned int octal_digit = 0; switch (shift_value) { case 0: case 1: case 2: { octal_digit = (unsigned int)(base8_digit_string[octal_digit_index]); m_array_ptr[array_index] |= octal_digit << shift_value; } --array_index; break; case 3: case 4: case 5: case 6: case 7: case 8: case 9: case 10: case 11: case 12: case 13: case 14: case 15: case 16: case 17: case 18: case 19: case 20: case 21: case 22: case 23: case 24: case 25: case 26: case 27: case 28: case 29: { octal_digit = (unsigned int)(base8_digit_string[octal_digit_index]); m_array_ptr[array_index] |= octal_digit << shift_value; } break; case 30: { octal_digit = (unsigned int)(base8_digit_string[octal_digit_index]); m_array_ptr[array_index] |= (octal_digit & 3) << 30; if (array_index + 1 < integer_length) { m_array_ptr[array_index + 1] |= (octal_digit & 4) >> 2; } } break; case 31: { octal_digit = (unsigned int)(base8_digit_string[octal_digit_index]); m_array_ptr[array_index] |= (octal_digit & 1) << 31; if (array_index + 1 < integer_length) { m_array_ptr[array_index + 1] |= ((octal_digit & 6) >> 1); } } break; default: break; } } return; } //====================================================================== // Set the value of this large integer value using a base 10 string. // Leading sign characters and space characters must be removed // before calling this method. //====================================================================== bool LargeInteger::SetValueWithBase10String(const char * digits_ptr) { //------------------------------------------------------------------ // Convert the decimal string to octal digit values. //------------------------------------------------------------------ std::string base8_digit_string; bool success_flag = ConvertDecimalStringToOctalDigits(digits_ptr, base8_digit_string); //------------------------------------------------------------------ // Set the value of this large integer using the base 8 // digit values. //------------------------------------------------------------------ if (success_flag) { SetValueWithBase8DigitValues(base8_digit_string); } return success_flag; } //====================================================================== // Convert a base 10 string of characters to base 8 values. // The passed string contains decimal character digits representing // a positive value in base 10. Leading sign characters and space // characters must be removed before calling this method. //====================================================================== bool LargeInteger::ConvertDecimalStringToOctalDigits(const char * decimal_digits_ptr, std::string & digits_string) const { unsigned int i; //------------------------------------------------------------------ // Get the length of the input string. //------------------------------------------------------------------ size_t digit_length = ::strlen(decimal_digits_ptr); //-------------------------------------------------------------- // Convert the decimal digit characters to decimal values. //-------------------------------------------------------------- digits_string = decimal_digits_ptr; //-------------------------------------------------------------- // Insert leading zeros to allow for number growth. // // The algorithm used to calculate the number of digits // of growth is not exact, but it provides a conservative // value that guarantees that there will be enough extra // digits for growth. //-------------------------------------------------------------- unsigned int padding = (unsigned int)(((200 * digit_length) / 1000) + 1); char * padding_ptr = new char [padding]; if (padding_ptr == 0) { //throw LargeIntegerException("Memory allocation failed"); eprintf("LargeInteger::ConvertDecimalStringToOctalDigits(): Error: Memory allocation failed.\n"); abort(); } for (i = 0; i < padding; ++i) { padding_ptr[i] = 0; } digits_string.insert(0, padding_ptr, padding); delete [] padding_ptr; //-------------------------------------------------------------- // Get the new digit length and the buffer pointer. //-------------------------------------------------------------- digit_length = (unsigned int)(digits_string.length()); char * digit_array_ptr = const_cast(digits_string.data()); //-------------------------------------------------------------- // Convert the digit characters to digit values. //-------------------------------------------------------------- bool success_flag = false; for (i = padding; i < digit_length; ++i) { char digit = digit_array_ptr[i]; success_flag = ::isdigit(digit) != 0; if (success_flag) { digit_array_ptr[i] = digit - '0'; } else { break; } } //-------------------------------------------------------------- // Convert the base 10 digits to base 8 digits. //-------------------------------------------------------------- if (success_flag) { //---------------------------------------------------------- // Convert the base 8 string to base 10 digits using the // algorithm from "Semi-Numerical Methods", by Knuth. // Double the K leading octal digits using octal arithmetic // and add them from the K + 1 leading digits using octal // arithmetic. //---------------------------------------------------------- char * addend_ptr = new char [digit_length + 1]; if (addend_ptr == 0) { //throw LargeIntegerException("Memory allocation failed"); eprintf("LargeInteger::ConvertDecimalStringToOctalDigits(): Error: Memory allocation failed.\n"); abort(); } for (unsigned int k = 0; k < digit_length - 1; ++k) { //------------------------------------------------------ // Double the K leading decimal digits using base 8 // arithmetic and copy these digits into the K + 1'st // location in the addend array. //------------------------------------------------------ unsigned int j = 0; for (j = k + 1; (int)(j) >= 0; --j) { addend_ptr[j] = 0; } for (j = k; (int)(j) >= 0; --j) { char doubled_digit = digit_array_ptr[j] << 1; if (doubled_digit > 7) { addend_ptr[j + 1] += doubled_digit - 8; addend_ptr[j] += 1; } else { addend_ptr[j + 1] += doubled_digit; } } //---------------------------------------------------------- // Add the doubled digits from the original number // using octal arithmetic. //---------------------------------------------------------- for (unsigned int m = k + 1; (int)(m) >= 0; --m) { char sum = digit_array_ptr[m] + addend_ptr[m]; if (sum > 7) { digit_array_ptr[m] = sum - 8; if ((int)(m - 1) >= 0) { digit_array_ptr[m - 1] += 1; } } else { digit_array_ptr[m] = sum; } } } delete [] addend_ptr; //-------------------------------------------------------------- // Remove all leading zeros. //-------------------------------------------------------------- unsigned int start_position = 0; for (i = 0; i < digits_string.length(); ++i) { if ((digits_string[i] != 0) || (i == digits_string.length() - 1)) { start_position = i; break; } } if (start_position != 0) { digits_string = digits_string.substr(start_position); } } return success_flag; } //====================================================================== // Set the value of this large integer value using a base 16 string. // Leading sign characters and space characters must be removed // before calling this method. //====================================================================== bool LargeInteger::SetValueWithBase16String(const char * digits_ptr) { //------------------------------------------------------------------ // Convert the hexadecimal string to hexadecimal digit values. //------------------------------------------------------------------ bool success_flag = true; std::string hex_number_string = digits_ptr; unsigned int number_of_digits = (unsigned int)(hex_number_string.length()); char * hex_digits_ptr = const_cast(hex_number_string.data()); for (unsigned int i = 0; i < number_of_digits; ++i) { int digit = (int)(hex_digits_ptr[i]); success_flag = ::isxdigit(digit) != 0; if (success_flag) { if (::isdigit(digit)) { hex_digits_ptr[i] = (char)(digit - '0'); } else { hex_digits_ptr[i] = (char)(::toupper(digit)) + 10 - 'A'; } } else { break; } } //------------------------------------------------------------------ // Set the value of this large integer using the base 8 // digit values. //------------------------------------------------------------------ if (success_flag) { //-------------------------------------------------------------- // Strip any extra sign extension characters. //-------------------------------------------------------------- StripLeadingZeroDigits(hex_number_string, 0); //-------------------------------------------------------------- // Set the value of this large integer using the base 16 // digit values. //-------------------------------------------------------------- SetValueWithBase16DigitValues(hex_number_string); } return success_flag; } //====================================================================== // Set the value of this large integer value using a base 16 string. // Leading space characters must be removed before calling this method. //====================================================================== void LargeInteger::SetValueWithBase16DigitValues(const std::string & base16_digit_values_string) { //------------------------------------------------------------------ // Set the length of the array. //------------------------------------------------------------------ unsigned int number_of_digits = (unsigned int)base16_digit_values_string.length(); unsigned int integer_length = (number_of_digits + 7) >> 3; SetIntegerLength(integer_length); //------------------------------------------------------------------ // Add each digit to the array. // Handle extra digits that do not fill a complete word. //------------------------------------------------------------------ unsigned int array_index = integer_length - 1; unsigned int current_digit_index = 0; unsigned int extra_digits = number_of_digits - ((integer_length - 1) << 3); unsigned int hex_digit; switch (extra_digits) { case 7: { hex_digit = base16_digit_values_string[current_digit_index++]; m_array_ptr[array_index] |= hex_digit << 24; hex_digit = base16_digit_values_string[current_digit_index++]; m_array_ptr[array_index] |= hex_digit << 20; hex_digit = base16_digit_values_string[current_digit_index++]; m_array_ptr[array_index] |= hex_digit << 16; hex_digit = base16_digit_values_string[current_digit_index++]; m_array_ptr[array_index] |= hex_digit << 12; hex_digit = base16_digit_values_string[current_digit_index++]; m_array_ptr[array_index] |= hex_digit << 8; hex_digit = base16_digit_values_string[current_digit_index++]; m_array_ptr[array_index] |= hex_digit << 4; hex_digit = base16_digit_values_string[current_digit_index++]; m_array_ptr[array_index--] |= hex_digit; } break; case 6: { hex_digit = base16_digit_values_string[current_digit_index++]; m_array_ptr[array_index] |= hex_digit << 20; hex_digit = base16_digit_values_string[current_digit_index++]; m_array_ptr[array_index] |= hex_digit << 16; hex_digit = base16_digit_values_string[current_digit_index++]; m_array_ptr[array_index] |= hex_digit << 12; hex_digit = base16_digit_values_string[current_digit_index++]; m_array_ptr[array_index] |= hex_digit << 8; hex_digit = base16_digit_values_string[current_digit_index++]; m_array_ptr[array_index] |= hex_digit << 4; hex_digit = base16_digit_values_string[current_digit_index++]; m_array_ptr[array_index--] |= hex_digit; } break; case 5: { hex_digit = base16_digit_values_string[current_digit_index++]; m_array_ptr[array_index] |= hex_digit << 16; hex_digit = base16_digit_values_string[current_digit_index++]; m_array_ptr[array_index] |= hex_digit << 12; hex_digit = base16_digit_values_string[current_digit_index++]; m_array_ptr[array_index] |= hex_digit << 8; hex_digit = base16_digit_values_string[current_digit_index++]; m_array_ptr[array_index] |= hex_digit << 4; hex_digit = base16_digit_values_string[current_digit_index++]; m_array_ptr[array_index--] |= hex_digit; } break; case 4: { hex_digit = base16_digit_values_string[current_digit_index++]; m_array_ptr[array_index] |= hex_digit << 12; hex_digit = base16_digit_values_string[current_digit_index++]; m_array_ptr[array_index] |= hex_digit << 8; hex_digit = base16_digit_values_string[current_digit_index++]; m_array_ptr[array_index] |= hex_digit << 4; hex_digit = base16_digit_values_string[current_digit_index++]; m_array_ptr[array_index--] |= hex_digit; } break; case 3: { hex_digit = base16_digit_values_string[current_digit_index++]; m_array_ptr[array_index] |= hex_digit << 8; hex_digit = base16_digit_values_string[current_digit_index++]; m_array_ptr[array_index] |= hex_digit << 4; hex_digit = base16_digit_values_string[current_digit_index++]; m_array_ptr[array_index--] |= hex_digit; } break; case 2: { hex_digit = base16_digit_values_string[current_digit_index++]; m_array_ptr[array_index] |= hex_digit << 4; hex_digit = base16_digit_values_string[current_digit_index++]; m_array_ptr[array_index--] |= hex_digit; } break; case 1: { hex_digit = base16_digit_values_string[current_digit_index++]; m_array_ptr[array_index--] |= hex_digit; } break; case 0: default: break; } if (number_of_digits > 7) { //------------------------------------------------------------- // The number of digits remaining is a multiple of 8. // Copy these digits into the term array. //------------------------------------------------------------- for (unsigned int hex_digitIndex = current_digit_index; hex_digitIndex < number_of_digits; hex_digitIndex += 8) { unsigned int hex_digit_0 = base16_digit_values_string[hex_digitIndex]; unsigned int hex_digit_1 = base16_digit_values_string[hex_digitIndex + 1]; unsigned int hex_digit_2 = base16_digit_values_string[hex_digitIndex + 2]; unsigned int hex_digit_3 = base16_digit_values_string[hex_digitIndex + 3]; unsigned int hex_digit_4 = base16_digit_values_string[hex_digitIndex + 4]; unsigned int hex_digit_5 = base16_digit_values_string[hex_digitIndex + 5]; unsigned int hex_digit_6 = base16_digit_values_string[hex_digitIndex + 6]; unsigned int hex_digit_7 = base16_digit_values_string[hex_digitIndex + 7]; m_array_ptr[array_index--] = (hex_digit_0 << 28) | (hex_digit_1 << 24) | (hex_digit_2 << 20) | (hex_digit_3 << 16) | (hex_digit_4 << 12) | (hex_digit_5 << 8) | (hex_digit_6 << 4) | hex_digit_7; } } return; } //====================================================================== // Global function declarations. //====================================================================== //====================================================================== // operator + for integral types. //====================================================================== //====================================================================== // Addition of two instances of this class. //====================================================================== LargeInteger operator +(const LargeInteger & addend_a, const LargeInteger & addend_b) { return LargeInteger(addend_a) += addend_b; } //====================================================================== // Addition of an instance of the LargeInteger class and a signed integer. //====================================================================== LargeInteger operator +(const LargeInteger & x_addend, int addend) { return x_addend + LargeInteger(addend); } LargeInteger operator +(int addend, const LargeInteger & x_addend) { return x_addend + addend; } //====================================================================== // Addition of an instance of the LargeInteger class and an unsigned integer. //====================================================================== LargeInteger operator +(const LargeInteger & x_addend, unsigned int addend) { return x_addend + LargeInteger(addend); } LargeInteger operator +(unsigned int addend, const LargeInteger & x_addend) { return x_addend + addend; } //====================================================================== // operator - for integral types. //====================================================================== //====================================================================== // Subtraction of two instances of this class. //====================================================================== LargeInteger operator -(const LargeInteger & minuend, const LargeInteger & subtrahend) { return LargeInteger(minuend) -= subtrahend; } //====================================================================== // Subtraction with an instance of the LargeInteger class and a signed integer. //====================================================================== LargeInteger operator -(const LargeInteger & minuend, int subtrahend) { return minuend - LargeInteger(subtrahend); } LargeInteger operator -(int minuend, const LargeInteger & subtrahend) { return LargeInteger(minuend) - subtrahend; } //====================================================================== // Subtraction with an instance of the LargeInteger class and an unsigned integer. //====================================================================== LargeInteger operator -(const LargeInteger & minuend, unsigned int subtrahend) { return minuend - LargeInteger(subtrahend); } LargeInteger operator -(unsigned int minuend, const LargeInteger & subtrahend) { return LargeInteger(minuend) - subtrahend; } //====================================================================== // operator * for integral types. //====================================================================== //====================================================================== // Multiplication of two instances of this class. //====================================================================== LargeInteger operator *(const LargeInteger & multiplier_a, const LargeInteger & multiplier_b) { return LargeInteger(multiplier_a) *= multiplier_b; } //====================================================================== // Multiplication of an instance of the LargeInteger class and a signed integer. //====================================================================== LargeInteger operator *(const LargeInteger & x_multiplier, int multiplier) { return x_multiplier * LargeInteger(multiplier); } LargeInteger operator *(int multiplier, const LargeInteger & x_multiplier) { return x_multiplier * multiplier; } //====================================================================== // Multiplication of an instance of the LargeInteger class and an unsigned integer. //====================================================================== LargeInteger operator *(const LargeInteger & x_multiplier, unsigned int multiplier) { return x_multiplier * LargeInteger(multiplier); } LargeInteger operator *(unsigned int multiplier, const LargeInteger & x_multiplier) { return x_multiplier * multiplier; } //====================================================================== // operator / for integral types. //====================================================================== //====================================================================== // Division of two instances of this class. //====================================================================== LargeInteger operator /(const LargeInteger & x_dividend, const LargeInteger & x_denominator) { return LargeInteger(x_dividend) /= x_denominator; } //====================================================================== // Division with an instance of the LargeInteger class and a signed integer. //====================================================================== LargeInteger operator /(const LargeInteger & x_dividend, int divisor) { return x_dividend / LargeInteger(divisor); } LargeInteger operator /(int dividend, const LargeInteger & x_denominator) { return LargeInteger(dividend) / x_denominator; } //====================================================================== // Division with an instance of the LargeInteger class and an unsigned integer. //====================================================================== LargeInteger operator /(const LargeInteger & x_dividend, unsigned int divisor) { return x_dividend / LargeInteger(divisor); } LargeInteger operator /(unsigned int dividend, const LargeInteger & x_denominator) { return LargeInteger(dividend) / x_denominator; } //====================================================================== // operator << for integral types. //====================================================================== //====================================================================== // Left shift of two instances of this class. //====================================================================== LargeInteger operator <<(const LargeInteger & value, const LargeInteger & x_shift_count) { return LargeInteger(value) <<= x_shift_count; } //====================================================================== // Left shift with an instance of the LargeInteger class and a signed integer. //====================================================================== LargeInteger operator <<(const LargeInteger & value, int shift_count) { return value << LargeInteger(shift_count); } LargeInteger operator <<(int value, const LargeInteger & x_shift_count) { return LargeInteger(value) << x_shift_count; } //====================================================================== // Left shift with an instance of the LargeInteger class and an unsigned integer. //====================================================================== LargeInteger operator <<(const LargeInteger & value, unsigned int shift_count) { return value << LargeInteger(shift_count); } LargeInteger operator <<(unsigned int value, const LargeInteger & x_shift_count) { return LargeInteger(value) << x_shift_count; } //====================================================================== // operator >> for integral types. //====================================================================== //====================================================================== // Right shift of two instances of this class. //====================================================================== LargeInteger operator >>(const LargeInteger & value, const LargeInteger & x_shift_count) { return LargeInteger(value) >>= x_shift_count; } //====================================================================== // Right shift with an instance of the LargeInteger class and a signed integer. //====================================================================== LargeInteger operator >>(const LargeInteger & value, int shift_count) { return value >> LargeInteger(shift_count); } LargeInteger operator >>(int value, const LargeInteger & x_shift_count) { return LargeInteger(value) >> x_shift_count; } //====================================================================== // Right shift with an instance of the LargeInteger class and an unsigned integer. //====================================================================== LargeInteger operator >>(const LargeInteger & value, unsigned int shift_count) { return value >> LargeInteger(shift_count); } LargeInteger operator >>(unsigned int value, const LargeInteger & x_shift_count) { return LargeInteger(value) >> x_shift_count; } //====================================================================== // operator % for integral types. //====================================================================== //====================================================================== // Modulus operator with two instances of this class. //====================================================================== LargeInteger operator %(const LargeInteger & x_dividend, const LargeInteger & x_denominator) { return LargeInteger(x_dividend) %= x_denominator; } //====================================================================== // Modulus operator with an instance of the LargeInteger class and a signed integer. //====================================================================== LargeInteger operator %(const LargeInteger & x_dividend, int divisor) { return x_dividend % LargeInteger(divisor); } LargeInteger operator %(int dividend, const LargeInteger & x_denominator) { return LargeInteger(dividend) % x_denominator; } //====================================================================== // Modulus operator with an instance of the LargeInteger class and an unsigned integer. //====================================================================== LargeInteger operator %(const LargeInteger & x_dividend, unsigned int divisor) { return x_dividend % LargeInteger(divisor); } LargeInteger operator %(unsigned int dividend, const LargeInteger & x_denominator) { return LargeInteger(dividend) % x_denominator; } //====================================================================== // operator ^ for integral types. //====================================================================== //====================================================================== // Bitwise Exclusive OR of two instances of this class. //====================================================================== LargeInteger operator ^(const LargeInteger & value_a, const LargeInteger & value_b) { return LargeInteger(value_a) ^= value_b; } //====================================================================== // Bitwise Exclusive OR of an instance of the LargeInteger class and a signed integer. //====================================================================== LargeInteger operator ^(const LargeInteger & x_value, int value) { return x_value % LargeInteger(value); } LargeInteger operator ^(int value, const LargeInteger & x_value) { return x_value % value; } //====================================================================== // Bitwise Exclusive OR of an instance of the LargeInteger class and an unsigned integer. //====================================================================== LargeInteger operator ^(const LargeInteger & x_value, unsigned int value) { return x_value % LargeInteger(value); } LargeInteger operator ^(unsigned int value, const LargeInteger & x_value) { return x_value % value; } //====================================================================== // operator & for integral types. //====================================================================== //====================================================================== // Bitwise AND of two instances of this class. //====================================================================== LargeInteger operator &(const LargeInteger & value_a, const LargeInteger & value_b) { return LargeInteger(value_a) &= value_b; } //====================================================================== // Bitwise AND of an instance of the LargeInteger class and a signed integer. //====================================================================== LargeInteger operator &(const LargeInteger & x_value, int value) { return x_value & LargeInteger(value); } LargeInteger operator &(int value, const LargeInteger & x_value) { return x_value & value; } //====================================================================== // Bitwise AND of an instance of the LargeInteger class and an unsigned integer. //====================================================================== LargeInteger operator &(const LargeInteger & x_value, unsigned int value) { return x_value & LargeInteger(value); } LargeInteger operator &(unsigned int value, const LargeInteger & x_value) { return x_value & value; } //====================================================================== // operator | for integral types. //====================================================================== //====================================================================== // Bitwise OR of two instances of this class. //====================================================================== LargeInteger operator |(const LargeInteger & value_a, const LargeInteger & value_b) { return LargeInteger(value_a) |= value_b; } //====================================================================== // Bitwise OR of an instance of the LargeInteger class and a signed integer. //====================================================================== LargeInteger operator |(const LargeInteger & x_value, int value) { return x_value | LargeInteger(value); } LargeInteger operator |(int value, const LargeInteger & x_value) { return x_value | value; } //====================================================================== // Bitwise OR of an instance of the LargeInteger class and an unsigned integer. //====================================================================== LargeInteger operator |(const LargeInteger & x_value, unsigned int value) { return x_value | LargeInteger(value); } LargeInteger operator |(unsigned int value, const LargeInteger & x_value) { return x_value | value; } void LargeInteger::SelfTest() { // This hex number contains 1024 'f' digits. const char * pszNumber = "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"; LargeInteger xMultiplier0; xMultiplier0.SetDefaultBase(16); xMultiplier0 = pszNumber; // Another way to set the value is: //xMultiplier0.SetValue(pszNumber, 16); LargeInteger xMultiplier1 = xMultiplier0; // Time raising the 1024 digit hex number to the 11th power // by doing ten multiplications. This is not an efficient way // to raise a number to a power, but this is to time the // multiplication code. //DWORD dwStartTime = GetTickCount(); LargeInteger xProduct; LargeInteger xBitTest; int i = 0; for (i = 0; i < 10; ++i) { xProduct = xMultiplier0 * xMultiplier1; } //DWORD dwStopTime = GetTickCount(); //DWORD dwElapsedTime = dwStopTime - dwStartTime; //std::cout << "Time = " << dwElapsedTime << " milliseconds. " << std::endl; std::cout << "Product = " << std::hex << xProduct << std::endl; //------------------------------------------------------------------ // Test the large unsigned integer. //------------------------------------------------------------------ xMultiplier0 = 0xFFFFFFFF; xMultiplier1 = 0xFFFFFFFF; xProduct = xMultiplier0 * xMultiplier1; std::cout << "Product = " << std::hex << xProduct << std::endl; // Negative number tests xMultiplier0 = -2; xMultiplier1 = 2; xProduct = xMultiplier0 * xMultiplier1; std::cout << "Product = " << std::hex << xProduct << std::endl; LargeInteger xDividend = LargeInteger(-16); LargeInteger xDivisor = LargeInteger(4); LargeInteger xQuotient = xDividend / xDivisor; std::cout << "Quotient = " << std::hex << xQuotient << std::endl; xQuotient <<= 1; std::cout << "Quotient <<= 1 = " << std::hex << xQuotient << std::endl; xQuotient <<= 1; std::cout << "Quotient <<= 1 = " << std::hex << xQuotient << std::endl; xQuotient <<= 1; std::cout << "Quotient <<= 1 = " << std::hex << xQuotient << std::endl; xQuotient <<= 2; std::cout << "Quotient <<= 2 = " << std::hex << xQuotient << std::endl; xQuotient >>= 1; std::cout << "Quotient >>= 1 = " << std::hex << xQuotient << std::endl; xQuotient >>= 1; std::cout << "Quotient >>= 1 = " << std::hex << xQuotient << std::endl; xQuotient >>= 1; std::cout << "Quotient >>= 1 = " << std::hex << xQuotient << std::endl; xQuotient >>= 1; std::cout << "Quotient >>= 1 = " << std::hex << xQuotient << std::endl; xQuotient >>= 1; std::cout << "Quotient >>= 1 = " << std::hex << xQuotient << std::endl; xQuotient >>= 1; std::cout << "Quotient >>= 1 " << std::hex << xQuotient << std::endl; // A trivial comparison test. LargeInteger xA = LargeInteger(6); LargeInteger xB = LargeInteger(10); if (xA <= xB) { std::cout << "xA <= xB " << std::dec << xA << " <= " << xB << std::endl; } // Shift tests LargeInteger x_value = LargeInteger(1); for (i = 0; i < 256; i++) { x_value <<= 1; std::cout << std::dec << x_value << std::endl; std::cout << std::hex << x_value << std::endl; } for (i = 0; i < 256; i++) { x_value >>= 1; std::cout << std::dec << x_value << std::endl; std::cout << std::hex << x_value << std::endl; } // Another comparison test. if (x_value == 0) { std::cout << x_value << " == 0 Failure" << std::endl; } else { std::cout << x_value << " != 0 Success" << std::endl; } // More number tests. xBitTest.SetValue("FFFFFFFF", 16); unsigned int uiLeadingBitPosition = xBitTest.LeadingBitPosition(); std::cout << "Leading Bit Position = " << uiLeadingBitPosition << std::endl; xBitTest.SetValue("FFFFFFFF", 16); std::cout << "Population Count = " << xBitTest.PopulationCount() << std::endl; xBitTest.SetValue("FFFFFFEF", 16); std::cout << "Population Count = " << xBitTest.PopulationCount() << std::endl; xBitTest.SetValue("FFFFFFCF", 16); std::cout << "Population Count = " << xBitTest.PopulationCount() << std::endl; xBitTest.SetValue("FFFFFF8F", 16); std::cout << "Population Count = " << xBitTest.PopulationCount() << std::endl; xBitTest.SetValue("0FFFFFFF", 16); std::cout << "Population Count = " << xBitTest.PopulationCount() << std::endl; xBitTest.SetValue("F0EFFFFF", 16); std::cout << "Population Count = " << xBitTest.PopulationCount() << std::endl; xBitTest.SetValue("1", 16); std::cout << "Population Count = " << xBitTest.PopulationCount() << std::endl; xBitTest.SetValue("49249249", 8); std::cout << "Octal Value = " << std::oct << xBitTest << std::endl; xBitTest.SetValue("49249249", 16); std::cout << "Hex Value = " << std::hex << xBitTest << std::endl; xBitTest.SetValue("24924924", 8); std::cout << "Octal Value = " << std::oct << xBitTest << std::endl; xBitTest.SetValue("24924924", 16); std::cout << "Hex Value = " << std::hex << xBitTest << std::endl; xBitTest.SetValue("1234567012", 8); std::cout << "Octal Value = " << std::oct << xBitTest << std::endl; xBitTest.SetValue("77777777777777777777777777777777", 8); std::cout << "Octal Value = " << std::oct << xBitTest << std::endl; xBitTest.SetValue("200", 8); xBitTest.SetValue("4294967296", 10); xBitTest.SetValue("777777777777777777777777777777", 8); xBitTest.SetValue("77", 8); xBitTest.SetValue("1234567890123456789", 10); xBitTest.SetValue("12345678901234567890123456789012345678901234567890123456789012345678901234567890987654321", 10); std::cout << "Decimal Value = " << std::dec << xBitTest << std::endl; xBitTest.SetValue("7", 8); std::cout << "Octal Value = " << std::oct << xBitTest << std::endl; xBitTest.SetValue("77", 8); std::cout << "Octal Value = " << std::oct << xBitTest << std::endl; xBitTest.SetValue("777", 8); std::cout << "Octal Value = " << std::oct << xBitTest << std::endl; xBitTest.SetValue("7777", 8); std::cout << "Octal Value = " << std::oct << xBitTest << std::endl; xBitTest.SetValue("77777", 8); std::cout << "Octal Value = " << std::oct << xBitTest << std::endl; xBitTest.SetValue("777777", 8); std::cout << "Octal Value = " << std::oct << xBitTest << std::endl; xBitTest.SetValue("7777777", 8); std::cout << "Octal Value = " << std::oct << xBitTest << std::endl; xBitTest.SetValue("77777777", 8); std::cout << "Octal Value = " << std::oct << xBitTest << std::endl; xBitTest.SetValue("777777777", 8); std::cout << "Octal Value = " << std::oct << xBitTest << std::endl; xBitTest.SetValue("7777777777", 8); std::cout << "Octal Value = " << std::oct << xBitTest << std::endl; xBitTest.SetValue("77777777777", 8); std::cout << "Octal Value = " << std::oct << xBitTest << std::endl; xBitTest.SetValue("777777777777", 8); std::cout << "Octal Value = " << std::oct << xBitTest << std::endl; xBitTest.SetValue("7777777777777", 8); std::cout << "Octal Value = " << std::oct << xBitTest << std::endl; xBitTest.SetValue("77777777777777", 8); std::cout << "Octal Value = " << std::oct << xBitTest << std::endl; xBitTest.SetValue("777777777777777", 8); std::cout << "Octal Value = " << std::oct << xBitTest << std::endl; xBitTest.SetValue("7777777777777777", 8); std::cout << "Octal Value = " << std::oct << xBitTest << std::endl; xBitTest.SetValue("77777777777777777", 8); std::cout << "Octal Value = " << std::oct << xBitTest << std::endl; xBitTest.SetValue("777777777777777777", 8); std::cout << "Octal Value = " << std::oct << xBitTest << std::endl; xBitTest.SetValue("7777777777777777777", 8); std::cout << "Octal Value = " << std::oct << xBitTest << std::endl; xBitTest.SetValue("77777777777777777777", 8); std::cout << "Octal Value = " << std::oct << xBitTest << std::endl; xBitTest.SetValue("777777777777777777777", 8); std::cout << "Octal Value = " << std::oct << xBitTest << std::endl; xBitTest.SetValue("12345670123456701234567654321", 8); std::cout << "Octal Value = " << std::oct << xBitTest << std::endl; xBitTest.SetValue("F", 16); std::cout << "Hex Value = " << std::hex << xBitTest << std::endl; xBitTest.SetValue("FF", 16); std::cout << "Hex Value = " << std::hex << xBitTest << std::endl; xBitTest.SetValue("FFF", 16); std::cout << "Hex Value = " << std::hex << xBitTest << std::endl; xBitTest.SetValue("FFFF", 16); std::cout << "Hex Value = " << std::hex << xBitTest << std::endl; xBitTest.SetValue("FFFFF", 16); std::cout << "Hex Value = " << std::hex << xBitTest << std::endl; xBitTest.SetValue("FFFFFF", 16); std::cout << "Hex Value = " << std::hex << xBitTest << std::endl; xBitTest.SetValue("FFFFFFF", 16); std::cout << "Hex Value = " << std::hex << xBitTest << std::endl; xBitTest.SetValue("FFFFFFFF", 16); std::cout << "Hex Value = " << std::hex << xBitTest << std::endl; xBitTest.SetValue("FFFFFFFFF", 16); std::cout << "Hex Value = " << std::hex << xBitTest << std::endl; xBitTest.SetValue("FFFFFFFFFF", 16); std::cout << "Hex Value = " << std::hex << xBitTest << std::endl; xBitTest.SetValue("FFFFFFFFFFF", 16); std::cout << "Hex Value = " << std::hex << xBitTest << std::endl; xBitTest.SetValue("FFFFFFFFFFFF", 16); std::cout << "Hex Value = " << std::hex << xBitTest << std::endl; xBitTest.SetValue("FFFFFFFFFFFFF", 16); std::cout << "Hex Value = " << std::hex << xBitTest << std::endl; xBitTest.SetValue("FFFFFFFFFFFFFF", 16); std::cout << "Hex Value = " << std::hex << xBitTest << std::endl; xBitTest.SetValue("FFFFFFFFFFFFFFF", 16); std::cout << "Hex Value = " << std::hex << xBitTest << std::endl; xBitTest.SetValue("FFFFFFFFFFFFFFFF", 16); std::cout << "Hex Value = " << std::hex << xBitTest << std::endl; xBitTest.SetValue("FFFFFFFFFFFFFFFFF", 16); std::cout << "Hex Value = " << std::hex << xBitTest << std::endl; xBitTest.SetValue("FFFFFFFFFFFFFFFFFF", 16); std::cout << "Hex Value = " << std::hex << xBitTest << std::endl; xBitTest.SetValue("FFFFFFFFFFFFFFFFFFF", 16); std::cout << "Hex Value = " << std::hex << xBitTest << std::endl; xBitTest.SetValue("FFFFFFFFFFFFFFFFFFFF", 16); std::cout << "Hex Value = " << std::hex << xBitTest << std::endl; xBitTest.SetValue("FFFFFFFFFFFFFFFFFFFFF", 16); std::cout << "Hex Value = " << std::hex << xBitTest << std::endl; xBitTest.SetValue("123456789ABCDEF0123456789abcdef0123456789abcdefedcba987654321", 16); std::cout << "Hex Value = " << std::hex << xBitTest << std::endl; std::cout << "Decimal Value = " << std::dec << xBitTest << std::endl; xBitTest.SetValue("1", 10); xBitTest = xBitTest << 65535; xBitTest--; std::cout << "((1 << 65536) - 1) in base 10 = " << std::dec << xBitTest << std::endl; std::cout << "((1 << 65536) - 1) in base 8 = " << std::oct << xBitTest << std::endl; std::cout << "((1 << 65536) - 1) in base 16 = " << std::hex << xBitTest << std::endl; LargeInteger x_value_0; LargeInteger x_value_1; x_value_0.SetValue("1", 10); x_value_1.SetValue("1", 10); LargeInteger x_result = x_value_0 + x_value_1; std::cout << x_value_0 << " + " << x_value_1 << " = " << x_result << std::endl; x_value_0.SetValue("1", 10); x_value_1.SetValue("-2", 10); x_result = x_value_0 + x_value_1; std::cout << x_value_0 << " + " << x_value_1 << " = " << x_result << std::endl; x_value_0.SetValue("-2", 10); x_value_1.SetValue("1", 10); x_result = x_value_0 + x_value_1; std::cout << x_value_0 << " + " << x_value_1 << " = " << x_result << std::endl; x_value_0.SetValue("-2", 10); x_value_1.SetValue("-1", 10); x_result = x_value_0 + x_value_1; std::cout << x_value_0 << " + " << x_value_1 << " = " << x_result << std::endl; x_value_0.SetValue("-2", 10); x_value_1.SetValue("-1", 10); x_result = x_value_0 + x_value_1; std::cout << x_value_0 << " + " << x_value_1 << " = " << x_result << std::endl; x_value_0.SetValue("1", 10); x_value_1.SetValue("2", 10); x_result = x_value_0 - x_value_1; std::cout << x_value_0 << " - " << x_value_1 << " = " << x_result << std::endl; x_value_0.SetValue("1", 10); x_value_1.SetValue("-2", 10); x_result = x_value_0 - x_value_1; std::cout << x_value_0 << " - " << x_value_1 << " = " << x_result << std::endl; x_value_0.SetValue("-1", 10); x_value_1.SetValue("2", 10); x_result = x_value_0 - x_value_1; std::cout << x_value_0 << " - " << x_value_1 << " = " << x_result << std::endl; x_value_0.SetValue("-1", 10); x_value_1.SetValue("-2", 10); x_result = x_value_0 - x_value_1; std::cout << x_value_0 << " - " << x_value_1 << " = " << x_result << std::endl; x_value_0.SetValue("10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", 10); x_result = x_value_0 + 1; std::cout << x_value_0 << " + 1 = " << x_result << std::endl; x_result = x_value_0 - 1; std::cout << x_value_0 << " - 1 = " << x_result << std::endl; x_value_1 = x_value_0 - x_result; std::cout << x_value_0 << " - " << x_result << " = " << x_value_1 << std::endl; x_value_0.SetValue("10", 10); x_value_1 = x_value_0; x_result = x_value_0 * x_value_1; std::cout << x_result << " = " << x_value_0 << " * " << x_value_1 << std::endl; x_value_0.SetValue("1000000000000000", 10); std::cout << "x_value_0 = " << x_value_0 << std::endl; x_value_1 = x_value_0; x_result = x_value_0 * x_value_1; std::cout << x_result << " = " << x_value_0 << " * " << x_value_1 << std::endl; x_value_0.SetValue("1000000", 10); std::cout << x_value_0 << " = " << x_value_0 << std::endl; x_value_0.SetValue("100000000000000000000000", 10); x_value_1 = x_value_0; x_result = x_value_0 * x_value_1; std::cout << x_result << " = " << x_value_0 << " * " << x_value_1 << std::endl; xDividend.SetValue("1048576", 10); xDivisor.SetValue("1024", 10); xQuotient = xDividend / xDivisor; std::cout << xDividend << " / " << xDivisor << " = " << xQuotient << std::endl; } void LargeInteger::mprintf(unsigned int base) { std::string s; GetNumberString(s,base); ::mprintf("%s",s.c_str()); } void LargeInteger::mfprintf(FILE *a, unsigned int base) { std::string s; GetNumberString(s,base); ::mfprintf(a,"%s",s.c_str()); } const char* LargeInteger::string() const { if (*this != 0) GetNumberString(g_sLIString,10); else g_sLIString = "0"; return g_sLIString.c_str(); } const char* LargeInteger::string2() const { if (*this != 0) GetNumberString(g_sLIString2,10); else g_sLIString2 = "0"; return g_sLIString2.c_str(); } const char* LargeInteger::string3() const { if (*this != 0) GetNumberString(g_sLIString3,10); else g_sLIString3 = "0"; return g_sLIString3.c_str(); } travis-src-190101/src/largeinteger.h0100777000000000000000000011002013412725662014254 0ustar00/***************************************************************************** TRAVIS - Trajectory Analyzer and Visualizer http://www.travis-analyzer.de/ Copyright (c) 2009-2019 Martin Brehm 2012-2019 Martin Thomas 2016-2019 Sascha Gehrke --------------------------------------------------------------------------- This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . *****************************************************************************/ //======================================================================= // Copyright (C) 1998-2013 William Hallahan // // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without restriction, // including without limitation the rights to use, copy, modify, merge, // publish, distribute, sublicense, and/or sell copies of the Software, // and to permit persons to whom the Software is furnished to do so, // subject to the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES // OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, // WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR // OTHER DEALINGS IN THE SOFTWARE. //======================================================================= //====================================================================== // Class Definition File: LargeInteger.h // Author: Bill Hallahan // Date: March 11, 1998 // // Abstract: // // This file contains the definition for class LargeInteger. // An instance of LargeInteger can be used to store and calculate // integer values with a huge number of digits. The internal data // format is a both a boolean value named m_negative_flag that that // stores the sign of the number, and an array of integers that // contains a positive binary value. The maximum number of integers // that can be contained in the internal array is limited to the // maximum signed value which can be stored in an integer, The // maximum number of digits that can be used for octal and hexadecimal // input, and output, is equal to the the maximum value that can be // stored in a signed integer. The input and output conversion // methods for decimal numbers supports up to 19,346,699 digits or // almost 20 million decimal digits. This implementation only works // on little-endian machines. // // How To Use This Class // // Except for the the caveats given below, 'LargeInteger' can be // used as if were a built-in data type. // // There are certain unavoidable differences which are documented // here: // // - This module should be compiled with overflow checking disabled. // This class grows the array that stores the binary number so // that overflows cannot occur. // // - The compiler will not allow large integer types to be the // integer argument in a 'switch' statement. The large integer // must be cast to an built-in type. // // - Instances of this class cannot be used to index simple arrays. // If an instance of this class must be used as an index for an // array then it should be cast to a built-in type. // // - Shift values for the left and right shift operators are limited // to the maximum value that fits in an unsigned integer. If the // shift value is larger than this then the shifted large integer // is set to the value zero. Note that the internal format does // not use two's complement arithmetic so that shifted values // maintain the same sign as the original value. // // - Literals with unlimited bit-length are not supported by any // compiler. To initialize a large integer use a constructor, // an equals operator, SetBinaryValue() method, or one of the // overloaded SetValue() methods. // //====================================================================== #ifndef LARGEINTEGER_H #define LARGEINTEGER_H //====================================================================== // Include files. //====================================================================== // This must always be the first include directive #include "config.h" #include #include //#include extern std::string g_sLIString; extern std::string g_sLIString2; extern std::string g_sLIString3; //====================================================================== // LargeIntegerException class for errors. //====================================================================== /* class LargeIntegerException : public std::exception { public: LargeIntegerException(const char * exception_text) : std::exception(exception_text) { } ~LargeIntegerException() throw() { } };*/ //====================================================================== // Class definition for class LargeInteger. //====================================================================== class LargeInteger { private: //================================================================== // Data members. //================================================================== unsigned int m_array_length; unsigned int m_integer_length; unsigned int m_default_base; unsigned int * m_array_ptr; bool m_negative_flag; public: static void SelfTest(); void mprintf(unsigned int base); void mfprintf(FILE *a, unsigned int base); //================================================================== // istream operator for input. //================================================================== friend std::istream & operator >>(std::istream & is, LargeInteger & value); //================================================================== // ostream operator for output. //================================================================== friend std::ostream & operator <<(std::ostream & os, const LargeInteger & value); //================================================================== // Constructors //================================================================== LargeInteger(); //================================================================== // Copy constructor //================================================================== LargeInteger(const LargeInteger & value); //================================================================== // Conversion constructors. //================================================================== explicit LargeInteger(long value); explicit LargeInteger(unsigned long value); explicit LargeInteger(int value); explicit LargeInteger(unsigned int value); explicit LargeInteger(const char * psznumber_ptr); //================================================================== // Special constructor to allow initializing using a binary array. //================================================================== LargeInteger(const char * binary_data_ptr, unsigned int length); //================================================================== // Destructor //================================================================== virtual ~LargeInteger(); //====================================================================== // Method: LargeInteger::SetDefaultBase // // The default base is the value used for the constructor and operator // equals methods that take only a string pointer for a number. //====================================================================== void SetDefaultBase(unsigned int default_base); //================================================================== // This method allows getting this large integer's binary value. // The binary value is a positive number in little endian format. // The buffer that is passed must be large enough to contain the // number. This method can be called passing a null pointer for // the buffer to just obtain the buffer length in bytes. //================================================================== unsigned int GetBinaryValue(unsigned char * binary_data_ptr = 0) const; //================================================================== // This method allows setting this large integer's binary value. // The binary value is a positive number in little endian format. // The buffer that is passed must be large enough to contain the // number. This method can be called passing a null pointer for // the buffer to just obtain the buffer length in bytes. //================================================================== void SetBinaryValue(const char * binary_data_ptr, unsigned int length); //================================================================== // Get this large integer value represented in an stl string. //================================================================== void GetNumberString(std::string & number_string, unsigned int base) const; //================================================================== // Set this large integer value using the number in a character // string. //================================================================== bool SetValue(const char * number_ptr, unsigned int base); //================================================================== // This method returns the position of the leading bit in this // large integer. //================================================================== unsigned int LeadingBitPosition() const; //================================================================== // Return the count of the number of bits set in this large // integer. //================================================================== unsigned int PopulationCount() const; //================================================================== // operator = for integral types. //================================================================== LargeInteger operator =(const LargeInteger & value); LargeInteger operator =(long value); LargeInteger operator =(unsigned long value); LargeInteger operator =(int value); LargeInteger operator =(unsigned int value); LargeInteger operator =(const char * psznumber_ptr); //================================================================== // Unary operator + for integral types. //================================================================== LargeInteger operator +=(const LargeInteger & addend); LargeInteger operator +=(long addend); LargeInteger operator +=(unsigned long addend); LargeInteger operator +=(int addend); LargeInteger operator +=(unsigned int addend); //================================================================== // Unary operator - for integral types. //================================================================== LargeInteger operator -=(const LargeInteger & subtrahend); LargeInteger operator -=(long subtrahend); LargeInteger operator -=(unsigned long subtrahend); LargeInteger operator -=(int subtrahend); LargeInteger operator -=(unsigned int subtrahend); //================================================================== // Unary operator * for integral types. //================================================================== LargeInteger operator *=(const LargeInteger & multiplier); protected: void AccumulateWithCarry(LargeInteger & product, int index, unsigned int value); public: LargeInteger operator *=(long multiplier); LargeInteger operator *=(unsigned long multiplier); LargeInteger operator *=(int multiplier); LargeInteger operator *=(unsigned int multiplier); //================================================================== // Unary operator / for integral types. //================================================================== LargeInteger operator /=(const LargeInteger & divisor); LargeInteger operator /=(long divisor); LargeInteger operator /=(unsigned long divisor); LargeInteger operator /=(int divisor); LargeInteger operator /=(unsigned int divisor); //================================================================== // operator <<= for integral types. //================================================================== LargeInteger operator <<=(const LargeInteger & shift_count); LargeInteger operator <<=(long shift_count); LargeInteger operator <<=(unsigned long shift_count); LargeInteger operator <<=(int shift_count); LargeInteger operator <<=(unsigned int shift_count); //================================================================== // operator >>= for integral types. //================================================================== LargeInteger operator >>=(const LargeInteger & shift_count); LargeInteger operator >>=(long shift_count); LargeInteger operator >>=(unsigned long shift_count); LargeInteger operator >>=(int shift_count); LargeInteger operator >>=(unsigned int shift_count); //================================================================== // Unary operator %= for integral types. //================================================================== LargeInteger operator %=(const LargeInteger & divisor); LargeInteger operator %=(long divisor); LargeInteger operator %=(unsigned long divisor); LargeInteger operator %=(int divisor); LargeInteger operator %=(unsigned int divisor); //================================================================== // operator ^= for integral types. //================================================================== LargeInteger operator ^=(const LargeInteger & value); LargeInteger operator ^=(long value); LargeInteger operator ^=(unsigned long value); LargeInteger operator ^=(int value); LargeInteger operator ^=(unsigned int value); //================================================================== // operator &= for integral types. //================================================================== LargeInteger operator &=(const LargeInteger & value); LargeInteger operator &=(unsigned long value); LargeInteger operator &=(int value); LargeInteger operator &=(unsigned int value); //================================================================== // operator |= for integral types. //================================================================== LargeInteger operator |=(const LargeInteger & value); LargeInteger operator |=(long value); LargeInteger operator |=(unsigned long value); LargeInteger operator |=(int value); LargeInteger operator |=(unsigned int value); //================================================================== // Unary operators. The unary * operator and the unary & operator // do not need to be overloaded. //================================================================== LargeInteger operator !(); LargeInteger operator ~(); LargeInteger operator +(); LargeInteger operator -(); //================================================================== // The prefix form of the increment and decrement operators. //================================================================== const LargeInteger operator ++(); const LargeInteger operator --(); //================================================================== // The postfix form of the increment and decrement operators. //================================================================== const LargeInteger operator ++(int); const LargeInteger operator --(int); //================================================================== // Unary operator == for integral types. //================================================================== bool operator ==(const LargeInteger & value) const; bool operator ==(long value) const; bool operator ==(unsigned long value) const; bool operator ==(int value) const; bool operator ==(unsigned int value) const; //================================================================== // Unary operator != for integral types. //================================================================== bool operator !=(const LargeInteger & value) const; bool operator !=(long value) const; bool operator !=(unsigned long value) const; bool operator !=(int value) const; bool operator !=(unsigned int value) const; //================================================================== // Unary operator < for integral types. //================================================================== bool operator <(const LargeInteger & value) const; bool operator <(long value) const; bool operator <(unsigned long value) const; bool operator <(int value) const; bool operator <(unsigned int value) const; //================================================================== // Unary operator > for integral types. //================================================================== bool operator >(const LargeInteger & value) const; bool operator >(long value) const; bool operator >(unsigned long value) const; bool operator >(int value) const; bool operator >(unsigned int value) const; //================================================================== // Unary operator <= for integral types. //================================================================== bool operator <=(const LargeInteger & value) const; bool operator <=(long value) const; bool operator <=(unsigned long value) const; bool operator <=(int value) const; bool operator <=(unsigned int value) const; //================================================================== // Unary operator >= for integral types. //================================================================== bool operator >=(const LargeInteger & value) const; bool operator >=(long value) const; bool operator >=(unsigned long value) const; bool operator >=(int value) const; bool operator >=(unsigned int value) const; //================================================================== // Cast conversion operators. //================================================================== operator long() const; operator unsigned long() const; operator int() const; operator unsigned int() const; operator short() const; operator unsigned short() const; operator char() const; operator unsigned char() const; operator bool() const; operator float() const; operator double() const; operator long double() const; #ifdef _DEBUG void DebugDump(const char * pszText = 0); #endif const char* string() const; const char* string2() const; const char* string3() const; private: //================================================================== // The following operators are not declared. The default // behavior of these operators is the desired behavior. // // operator () // operator [] // operator new // operator new[] // operator delete // operator delete[] // operator , // operator ->*() const; // operator &&() // operator ||() // // The following unary operators are not declared. The default // behavior of these operators is the desired behavior. // // operator *() // operator &() // //================================================================== //================================================================== // Private member functions. //================================================================== void Copy(const LargeInteger & that); void AddPositiveArray(const LargeInteger & addend); bool SubtractPositiveArray(const LargeInteger & subtrahend); void ShiftLeft(unsigned int shift_count); void ShiftRight(unsigned int shift_count); bool IsZero() const; bool IsNegative() const; bool FitsIn32Bits() const; void SetIntegerLength(unsigned int integer_length, bool copy_data_flag = false); void SetToZero(); unsigned int GetSafeArrayValue(unsigned int iIndex) const; void Normalize(); bool LessThanPositiveArrayCompare(const LargeInteger & value_0, const LargeInteger & value_1) const; unsigned int PopulationCount32Bit(unsigned int value) const; void GetBase8NumberString(std::string & number_string) const; void GetBase8Digits(std::string & base8_digits_string) const; void GetBase10NumberString(std::string & number_string) const; void GetBase16NumberString(std::string & number_string) const; void StripLeadingZeroDigits(std::string & number_string, char zero_digit) const; bool SetValueWithBase8String(const char * digits_ptr); void SetValueWithBase8DigitValues(const std::string & base8_digit_string); bool SetValueWithBase10String(const char * digits_ptr); bool ConvertDecimalStringToOctalDigits(const char * decimal_digits_ptr, std::string & digits_string) const; bool SetValueWithBase16String(const char * digits_ptr); void SetValueWithBase16DigitValues(const std::string & base16_digit_values_string); }; //====================================================================== // Global function declarations. //====================================================================== //====================================================================== // operator + for integral types. //====================================================================== //====================================================================== // Addition of two instances of this class. //====================================================================== LargeInteger operator +(const LargeInteger & addend_a, const LargeInteger & addend_b); //====================================================================== // Addition of an instance of the LargeInteger class and a signed integer. //====================================================================== LargeInteger operator +(const LargeInteger & x_addend, int addend); LargeInteger operator +(int addend, const LargeInteger & x_addend); //====================================================================== // Addition of an instance of the LargeInteger class and an unsigned integer. //====================================================================== LargeInteger operator +(const LargeInteger & x_addend, unsigned int addend); LargeInteger operator +(unsigned int addend, const LargeInteger & x_addend); //====================================================================== // operator - for integral types. //====================================================================== //====================================================================== // Subtraction of two instances of this class. //====================================================================== LargeInteger operator -(const LargeInteger & minuend, const LargeInteger & subtrahend); //====================================================================== // Subtraction with an instance of the LargeInteger class and a signed integer. //====================================================================== LargeInteger operator -(const LargeInteger & minuend, int subtrahend); LargeInteger operator -(int minuend, const LargeInteger & subtrahend); //====================================================================== // Subtraction with an instance of the LargeInteger class and an unsigned integer. //====================================================================== LargeInteger operator -(const LargeInteger & minuend, unsigned int subtrahend); LargeInteger operator -(unsigned int minuend, const LargeInteger & subtrahend); //====================================================================== // operator * for integral types. //====================================================================== //====================================================================== // Multiplication of two instances of this class. //====================================================================== LargeInteger operator *(const LargeInteger & multiplier_a, const LargeInteger & multiplier_b); //====================================================================== // Multiplication of an instance of the LargeInteger class and a signed integer. //====================================================================== LargeInteger operator *(const LargeInteger & x_multiplier, int multiplier); LargeInteger operator *(int multiplier, const LargeInteger & x_multiplier); //====================================================================== // Multiplication of an instance of the LargeInteger class and an unsigned integer. //====================================================================== LargeInteger operator *(const LargeInteger & x_multiplier, unsigned int multiplier); LargeInteger operator *(unsigned int multiplier, const LargeInteger & x_multiplier); //====================================================================== // operator / for integral types. //====================================================================== //====================================================================== // Division of two instances of this class. //====================================================================== LargeInteger operator /(const LargeInteger & x_dividend, const LargeInteger & x_denominator); //====================================================================== // Division with an instance of the LargeInteger class and a signed integer. //====================================================================== LargeInteger operator /(const LargeInteger & x_dividend, int divisor); LargeInteger operator /(int dividend, const LargeInteger & x_denominator); //====================================================================== // Division with an instance of the LargeInteger class and an unsigned integer. //====================================================================== LargeInteger operator /(const LargeInteger & x_dividend, unsigned int divisor); LargeInteger operator /(unsigned int dividend, const LargeInteger & x_denominator); //====================================================================== // operator << for integral types. //====================================================================== //====================================================================== // Left shift of two instances of this class. //====================================================================== LargeInteger operator <<(const LargeInteger & value, const LargeInteger & x_shift_count); //====================================================================== // Left shift with an instance of the LargeInteger class and a signed integer. //====================================================================== LargeInteger operator <<(const LargeInteger & value, int shift_count); LargeInteger operator <<(int value, const LargeInteger & x_shift_count); //====================================================================== // Left shift with an instance of the LargeInteger class and an unsigned integer. //====================================================================== LargeInteger operator <<(const LargeInteger & value, unsigned int shift_count); LargeInteger operator <<(unsigned int value, const LargeInteger & x_shift_count); //====================================================================== // operator >> for integral types. //====================================================================== //====================================================================== // Right shift of two instances of this class. //====================================================================== LargeInteger operator >>(const LargeInteger & value, const LargeInteger & x_shift_count); //====================================================================== // Right shift with an instance of the LargeInteger class and a signed integer. //====================================================================== LargeInteger operator >>(const LargeInteger & value, int shift_count); LargeInteger operator >>(int value, const LargeInteger & x_shift_count); //====================================================================== // Right shift with an instance of the LargeInteger class and an unsigned integer. //====================================================================== LargeInteger operator >>(const LargeInteger & value, unsigned int shift_count); LargeInteger operator >>(unsigned int value, const LargeInteger & x_shift_count); //====================================================================== // operator % for integral types. //====================================================================== //====================================================================== // Modulus operator with two instances of this class. //====================================================================== LargeInteger operator %(const LargeInteger & x_dividend, const LargeInteger & x_denominator); //====================================================================== // Modulus operator with an instance of the LargeInteger class and a signed integer. //====================================================================== LargeInteger operator %(const LargeInteger & x_dividend, int divisor); LargeInteger operator %(int dividend, const LargeInteger & x_denominator); //====================================================================== // Modulus operator with an instance of the LargeInteger class and an unsigned integer. //====================================================================== LargeInteger operator %(const LargeInteger & x_dividend, unsigned int divisor); LargeInteger operator %(unsigned int dividend, const LargeInteger & x_denominator); //====================================================================== // operator ^ for integral types. //====================================================================== //====================================================================== // Bitwise Exclusive OR of two instances of this class. //====================================================================== LargeInteger operator ^(const LargeInteger & value_a, const LargeInteger & value_b); //====================================================================== // Bitwise Exclusive OR of an instance of the LargeInteger class and a signed integer. //====================================================================== LargeInteger operator ^(const LargeInteger & x_value, int value); LargeInteger operator ^(int value, const LargeInteger & x_value); //====================================================================== // Bitwise Exclusive OR of an instance of the LargeInteger class and an unsigned integer. //====================================================================== LargeInteger operator ^(const LargeInteger & x_value, unsigned int value); LargeInteger operator ^(unsigned int value, const LargeInteger & x_value); //====================================================================== // operator & for integral types. //====================================================================== //====================================================================== // Bitwise AND of two instances of this class. //====================================================================== LargeInteger operator &(const LargeInteger & value_a, const LargeInteger & value_b); //====================================================================== // Bitwise AND of an instance of the LargeInteger class and a signed integer. //====================================================================== LargeInteger operator &(const LargeInteger & x_value, int value); LargeInteger operator &(int value, const LargeInteger & x_value); //====================================================================== // Bitwise AND of an instance of the LargeInteger class and an unsigned integer. //====================================================================== LargeInteger operator &(const LargeInteger & x_value, unsigned int value); LargeInteger operator &(unsigned int value, const LargeInteger & x_value); //====================================================================== // operator | for integral types. //====================================================================== //====================================================================== // Bitwise OR of two instances of this class. //====================================================================== LargeInteger operator |(const LargeInteger & value_a, const LargeInteger & value_b); //====================================================================== // Bitwise OR of an instance of the LargeInteger class and a signed integer. //====================================================================== LargeInteger operator |(const LargeInteger & x_value, int value); LargeInteger operator |(int value, const LargeInteger & x_value); //====================================================================== // Bitwise OR of an instance of the LargeInteger class and an unsigned integer. //====================================================================== LargeInteger operator |(const LargeInteger & x_value, unsigned int value); LargeInteger operator |(unsigned int value, const LargeInteger & x_value); #endif travis-src-190101/src/linalg.cpp0100777000000000000000000006650313412725627013426 0ustar00/***************************************************************************** TRAVIS - Trajectory Analyzer and Visualizer http://www.travis-analyzer.de/ Copyright (c) 2009-2019 Martin Brehm 2012-2019 Martin Thomas 2016-2019 Sascha Gehrke This file was written by Martin Brehm. --------------------------------------------------------------------------- This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . *****************************************************************************/ // This must always be the first include directive #include "config.h" #include "linalg.h" #include #include #include #include "tools.h" #include "qr_fact.h" #include "lu_decomp.h" //#include "defs_and_types.h" const char *GetRevisionInfo_linalg(unsigned int len) { static char buf[256]; GET_REVISION_INFO( buf, len ); return buf; } const char *GetSourceVersion_linalg() { static char buf[256]; GET_SOURCE_VERSION( buf ); return buf; } //#define MIN(x,y) ( (x) < (y) ? (x) : (y) ) //#define MAX(x,y) ((x)>(y)?(x):(y)) #define SIGN(a, b) ((b) >= 0.0 ? fabs(a) : -fabs(a)) #define SIGNF(a, b) ((b) >= 0.0 ? fabsf(a) : -fabsf(a)) //#define SQR(x) ((x)*(x)) /* * svdcomp - SVD decomposition routine. * Takes an mxn matrix a and decomposes it into udv, where u,v are * left and right orthogonal transformation matrices, and d is a * diagonal matrix of singular values. * * This routine is adapted from svdecomp.c in XLISP-STAT 2.1 which is * code from Numerical Recipes adapted by Luke Tierney and David Betz. * * Input to dsvd is as follows: * a = mxn matrix to be decomposed, gets overwritten with u * m = row dimension of a * n = column dimension of a * w = returns the vector of singular values of a * v = returns the right orthogonal transformation matrix */ static double PYTHAG(double a, double b) { double at = fabs(a), bt = fabs(b), ct, result; if (at > bt) { ct = bt / at; result = at * sqrt(1.0 + ct * ct); } else if (bt > 0.0) { ct = at / bt; result = bt * sqrt(1.0 + ct * ct); } else result = 0.0; return(result); } int ComputeSVD(double **a, int m, int n, double *w, double **v) { int flag, i, its, j, jj, k, l = 0, nm = 0; double c, f, h, s, x, y, z; double anorm = 0.0, g = 0.0, scale = 0.0; double *rv1; if (m < n) { eprintf("ComputeSVD(): #rows must be > #cols \n"); return(0); } rv1 = (double *)malloc((unsigned int) n*sizeof(double)); /* Householder reduction to bidiagonal form */ for (i = 0; i < n; i++) { /* left-hand reduction */ l = i + 1; rv1[i] = scale * g; g = s = scale = 0.0; if (i < m) { for (k = i; k < m; k++) scale += fabs(a[k][i]); if (scale) { for (k = i; k < m; k++) { a[k][i] = a[k][i]/scale; s += a[k][i] * a[k][i]; } f = a[i][i]; g = -SIGN(sqrt(s), f); h = f * g - s; a[i][i] = f - g; if (i != n - 1) { for (j = l; j < n; j++) { for (s = 0.0, k = i; k < m; k++) s += a[k][i] * a[k][j]; f = s / h; for (k = i; k < m; k++) a[k][j] += f * a[k][i]; } } for (k = i; k < m; k++) a[k][i] = a[k][i]*scale; } } w[i] = scale * g; /* right-hand reduction */ g = s = scale = 0.0; if (i < m && i != n - 1) { for (k = l; k < n; k++) scale += fabs(a[i][k]); if (scale) { for (k = l; k < n; k++) { a[i][k] = a[i][k]/scale; s += a[i][k] * a[i][k]; } f = a[i][l]; g = -SIGN(sqrt(s), f); h = f * g - s; a[i][l] = f - g; for (k = l; k < n; k++) rv1[k] = a[i][k] / h; if (i != m - 1) { for (j = l; j < m; j++) { for (s = 0.0, k = l; k < n; k++) s += a[j][k] * a[i][k]; for (k = l; k < n; k++) a[j][k] += s * rv1[k]; } } for (k = l; k < n; k++) a[i][k] = a[i][k]*scale; } } anorm = MAX(anorm, (fabs(w[i]) + fabs(rv1[i]))); } /* accumulate the right-hand transformation */ for (i = n - 1; i >= 0; i--) { if (i < n - 1) { if (g) { for (j = l; j < n; j++) v[j][i] = (a[i][j] / a[i][l]) / g; /* double division to avoid underflow */ for (j = l; j < n; j++) { for (s = 0.0, k = l; k < n; k++) s += a[i][k] * v[k][j]; for (k = l; k < n; k++) v[k][j] += s * v[k][i]; } } for (j = l; j < n; j++) v[i][j] = v[j][i] = 0.0; } v[i][i] = 1.0; g = rv1[i]; l = i; } /* accumulate the left-hand transformation */ for (i = n - 1; i >= 0; i--) { l = i + 1; g = w[i]; if (i < n - 1) for (j = l; j < n; j++) a[i][j] = 0.0; if (g) { g = 1.0 / g; if (i != n - 1) { for (j = l; j < n; j++) { for (s = 0.0, k = l; k < m; k++) s += a[k][i] * a[k][j]; f = (s / a[i][i]) * g; for (k = i; k < m; k++) a[k][j] += f * a[k][i]; } } for (j = i; j < m; j++) a[j][i] = a[j][i]*g; } else { for (j = i; j < m; j++) a[j][i] = 0.0; } ++a[i][i]; } /* diagonalize the bidiagonal form */ for (k = n - 1; k >= 0; k--) { /* loop over singular values */ for (its = 0; its < 30; its++) { /* loop over allowed iterations */ flag = 1; for (l = k; l >= 0; l--) { /* test for splitting */ nm = l - 1; if (fabs(rv1[l]) + anorm == anorm) { flag = 0; break; } if (fabs(w[nm]) + anorm == anorm) break; } if (flag) { c = 0.0; s = 1.0; for (i = l; i <= k; i++) { f = s * rv1[i]; if (fabs(f) + anorm != anorm) { g = w[i]; h = PYTHAG(f, g); w[i] = h; h = 1.0 / h; c = g * h; s = (- f * h); for (j = 0; j < m; j++) { y = a[j][nm]; z = a[j][i]; a[j][nm] = y * c + z * s; a[j][i] = z * c - y * s; } } } } z = w[k]; if (l == k) { /* convergence */ if (z < 0.0) { /* make singular value nonnegative */ w[k] = -z; for (j = 0; j < n; j++) v[j][k] = (-v[j][k]); } break; } if (its >= 30) { free((void*) rv1); eprintf("ComputeSVD(): No convergence after 30,000! iterations \n"); return(0); } /* shift from bottom 2 x 2 minor */ x = w[l]; nm = k - 1; y = w[nm]; g = rv1[nm]; h = rv1[k]; f = ((y - z) * (y + z) + (g - h) * (g + h)) / (2.0 * h * y); g = PYTHAG(f, 1.0); f = ((x - z) * (x + z) + h * ((y / (f + SIGN(g, f))) - h)) / x; /* next QR transformation */ c = s = 1.0; for (j = l; j <= nm; j++) { i = j + 1; g = rv1[i]; y = w[i]; h = s * g; g = c * g; z = PYTHAG(f, h); rv1[j] = z; c = f / z; s = h / z; f = x * c + g * s; g = g * c - x * s; h = y * s; y = y * c; for (jj = 0; jj < n; jj++) { x = v[jj][j]; z = v[jj][i]; v[jj][j] = x * c + z * s; v[jj][i] = z * c - x * s; } z = PYTHAG(f, h); w[j] = z; if (z) { z = 1.0 / z; c = f * z; s = h * z; } f = (c * g) + (s * y); x = (c * y) - (s * g); for (jj = 0; jj < m; jj++) { y = a[jj][j]; z = a[jj][i]; a[jj][j] = y * c + z * s; a[jj][i] = z * c - y * s; } } rv1[l] = 0.0; rv1[k] = f; w[k] = x; } } free((void*) rv1); return(1); } /* m - rows, n - cols a[zm][zn] = a[zm*n + zn]; */ int ComputeSVD_Flat(double *a, int m, int n, double *w, double *v) { int flag, i, its, j, jj, k, l = 0, nm = 0; double c, f, h, s, x, y, z; double anorm = 0.0, g = 0.0, scale = 0.0; double *rv1; if (m < n) { eprintf("ComputeSVD(): #rows must be > #cols \n"); return(0); } rv1 = (double *)malloc((unsigned int) n*sizeof(double)); /* Householder reduction to bidiagonal form */ for (i = 0; i < n; i++) { /* left-hand reduction */ l = i + 1; rv1[i] = scale * g; g = s = scale = 0.0; if (i < m) { for (k = i; k < m; k++) scale += fabs(a[k*n+i]); if (scale) { for (k = i; k < m; k++) { a[k*n+i] = a[k*n+i]/scale; s += a[k*n+i] * a[k*n+i]; } f = a[i*n+i]; g = -SIGN(sqrt(s), f); h = f * g - s; a[i*n+i] = f - g; if (i != n - 1) { for (j = l; j < n; j++) { for (s = 0.0, k = i; k < m; k++) s += a[k*n+i] * a[k*n+j]; f = s / h; for (k = i; k < m; k++) a[k*n+j] += f * a[k*n+i]; } } for (k = i; k < m; k++) a[k*n+i] = a[k*n+i]*scale; } } w[i] = scale * g; /* right-hand reduction */ g = s = scale = 0.0; if (i < m && i != n - 1) { for (k = l; k < n; k++) scale += fabs(a[i*n+k]); if (scale) { for (k = l; k < n; k++) { a[i*n+k] = a[i*n+k]/scale; s += a[i*n+k] * a[i*n+k]; } f = a[i*n+l]; g = -SIGN(sqrt(s), f); h = f * g - s; a[i*n+l] = f - g; for (k = l; k < n; k++) rv1[k] = a[i*n+k] / h; if (i != m - 1) { for (j = l; j < m; j++) { for (s = 0.0, k = l; k < n; k++) s += a[j*n+k] * a[i*n+k]; for (k = l; k < n; k++) a[j*n+k] += s * rv1[k]; } } for (k = l; k < n; k++) a[i*n+k] = a[i*n+k]*scale; } } anorm = MAX(anorm, (fabs(w[i]) + fabs(rv1[i]))); } /* accumulate the right-hand transformation */ for (i = n - 1; i >= 0; i--) { if (i < n - 1) { if (g) { for (j = l; j < n; j++) v[j*n+i] = (a[i*n+j] / a[i*n+l]) / g; /* double division to avoid underflow */ for (j = l; j < n; j++) { for (s = 0.0, k = l; k < n; k++) s += a[i*n+k] * v[k*n+j]; for (k = l; k < n; k++) v[k*n+j] += s * v[k*n+i]; } } for (j = l; j < n; j++) v[i*n+j] = v[j*n+i] = 0.0; } v[i*n+i] = 1.0; g = rv1[i]; l = i; } /* accumulate the left-hand transformation */ for (i = n - 1; i >= 0; i--) { l = i + 1; g = w[i]; if (i < n - 1) for (j = l; j < n; j++) a[i*n+j] = 0.0; if (g) { g = 1.0 / g; if (i != n - 1) { for (j = l; j < n; j++) { for (s = 0.0, k = l; k < m; k++) s += a[k*n+i] * a[k*n+j]; f = (s / a[i*n+i]) * g; for (k = i; k < m; k++) a[k*n+j] += f * a[k*n+i]; } } for (j = i; j < m; j++) a[j*n+i] = a[j*n+i]*g; } else { for (j = i; j < m; j++) a[j*n+i] = 0.0; } ++a[i*n+i]; } /* diagonalize the bidiagonal form */ for (k = n - 1; k >= 0; k--) { /* loop over singular values */ for (its = 0; its < 30; its++) { /* loop over allowed iterations */ flag = 1; for (l = k; l >= 0; l--) { /* test for splitting */ nm = l - 1; if (fabs(rv1[l]) + anorm == anorm) { flag = 0; break; } if (fabs(w[nm]) + anorm == anorm) break; } if (flag) { c = 0.0; s = 1.0; for (i = l; i <= k; i++) { f = s * rv1[i]; if (fabs(f) + anorm != anorm) { g = w[i]; h = PYTHAG(f, g); w[i] = h; h = 1.0 / h; c = g * h; s = (- f * h); for (j = 0; j < m; j++) { y = a[j*n+nm]; z = a[j*n+i]; a[j*n+nm] = y * c + z * s; a[j*n+i] = z * c - y * s; } } } } z = w[k]; if (l == k) { /* convergence */ if (z < 0.0) { /* make singular value nonnegative */ w[k] = -z; for (j = 0; j < n; j++) v[j*n+k] = (-v[j*n+k]); } break; } if (its >= 30) { free((void*) rv1); eprintf("ComputeSVD(): No convergence after 30,000! iterations \n"); return(0); } /* shift from bottom 2 x 2 minor */ x = w[l]; nm = k - 1; y = w[nm]; g = rv1[nm]; h = rv1[k]; f = ((y - z) * (y + z) + (g - h) * (g + h)) / (2.0 * h * y); g = PYTHAG(f, 1.0); f = ((x - z) * (x + z) + h * ((y / (f + SIGN(g, f))) - h)) / x; /* next QR transformation */ c = s = 1.0; for (j = l; j <= nm; j++) { i = j + 1; g = rv1[i]; y = w[i]; h = s * g; g = c * g; z = PYTHAG(f, h); rv1[j] = z; c = f / z; s = h / z; f = x * c + g * s; g = g * c - x * s; h = y * s; y = y * c; for (jj = 0; jj < n; jj++) { x = v[jj*n+j]; z = v[jj*n+i]; v[jj*n+j] = x * c + z * s; v[jj*n+i] = z * c - x * s; } z = PYTHAG(f, h); w[j] = z; if (z) { z = 1.0 / z; c = f * z; s = h * z; } f = (c * g) + (s * y); x = (c * y) - (s * g); for (jj = 0; jj < m; jj++) { y = a[jj*n+j]; z = a[jj*n+i]; a[jj*n+j] = y * c + z * s; a[jj*n+i] = z * c - y * s; } } rv1[l] = 0.0; rv1[k] = f; w[k] = x; } } free((void*) rv1); return(1); } void ComputePseudoInverse(int m, double *m_in, double *m_out) { double *mat_a, *mat_b, *mat_c, tf; int z1, z2, z3; // int z; mat_a = new double[m*m]; mat_b = new double[m]; mat_c = new double[m*m]; memcpy(mat_a,m_in,m*m*sizeof(double)); ComputeSVD_Flat(mat_a,m,m,mat_b,mat_c); /* mprintf("*** U Matrix:\n"); mprintf("{ "); for (z=0;z 1.0E-13) mat_b[z1] = 1.0 / mat_b[z1]; else mat_b[z1] = 0; for (z1=0;z1 1.0E-13) mat_b[z1] = 1.0 / mat_b[z1]; else mat_b[z1] = 0; // } } // mprintf(" @@@\n"); mout = CxDMatrixMN(n,m); for (z1=0;z1 (M-N)/2) && (z-(M-N)/2 <= N)) mprintf("| x%d |",(z-(M-N)/2)); else mprintf(" "); if (z == M/2) mprintf(" = "); else mprintf(" "); mprintf("| %7.3f |\n",b[z]); } mprintf("\n"); mprintf("Solving...\n"); Solve_LeastSquares_QR(A,b,x,M,N); mprintf("\nResult:\n\n"); for (z=0;zGetCols() != b->GetDim()) || (a->GetRows() != b->GetDim())) { eprintf("SolveLinearLU(): Error: Dimension mismatch (matrix %d x %d, vector %d).\n",a->GetCols(),a->GetRows(),b->GetDim()); abort(); } n = a->GetCols(); ta = new double*[n+1]; tb = new double[n+1]; tx = new double[n+1]; indx = new int[n+1]; for (z=0;zGetDim() != n) *x = CxDVectorN(n); for (z=0;z. *****************************************************************************/ #ifndef LINALG_H #define LINALG_H // This must always be the first include directive #include "config.h" #include "xdmatrixmn.h" #include "xdvectorn.h" int ComputeSVD(double **a, int m, int n, double *w, double **v); int ComputeSVD_Flat(double *a, int m, int n, double *w, double *v); void TestSVD(); void ComputePseudoInverse(int m, double *m_in, double *m_out); CxDMatrixMN ComputePseudoInverse(CxDMatrixMN input); void TestPseudoInverse(); /************************/ void Solve_LeastSquares_QR(double *a, double *b, double *x, int m, int n); void TestLeastSquaresQR(); /************************/ void SolveLinearLU(CxDMatrixMN *a, CxDVectorN *b, CxDVectorN *x); void TestLinearLU(); #endif travis-src-190101/src/lmmin.cpp0100777000000000000000000012754713412725625013300 0ustar00/***************************************************************************** TRAVIS - Trajectory Analyzer and Visualizer http://www.travis-analyzer.de/ Copyright (c) 2009-2019 Martin Brehm 2012-2019 Martin Thomas 2016-2019 Sascha Gehrke --------------------------------------------------------------------------- This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . *****************************************************************************/ /* * Project: LevenbergMarquardtLeastSquaresFitting * * File: lmmin.c * * Contents: Levenberg-Marquardt core implementation, * and simplified user interface. * * Author: Joachim Wuttke * * Homepage: www.messen-und-deuten.de/lmfit */ /* * lmfit is released under the LMFIT-BEER-WARE licence: * * In writing this software, I borrowed heavily from the public domain, * especially from work by Burton S. Garbow, Kenneth E. Hillstrom, * Jorge J. Moré, Steve Moshier, and the authors of lapack. To avoid * unneccessary complications, I put my additions and amendments also * into the public domain. Please retain this notice. Otherwise feel * free to do whatever you want with this stuff. If we meet some day, * and you think this work is worth it, you can buy me a beer in return. */ // This must always be the first include directive #include "config.h" #include #include #include #include #include "lmmin.h" #include "tools.h" #include "globalvar.h" const char *GetRevisionInfo_lmmin(unsigned int len) { static char buf[256]; GET_REVISION_INFO( buf, len ); return buf; } const char *GetSourceVersion_lmmin() { static char buf[256]; GET_SOURCE_VERSION( buf ); return buf; } //#define LMFIT_DEBUG_MESSAGES //#define LMFIT_MYDEBUG /*****************************************************************************/ /* set message texts (indexed by status.info) */ /*****************************************************************************/ const char *lm_infmsg[] = { "success (sum of squares below underflow limit)", "success (the relative error in the sum of squares is at most tol)", "success (the relative error between x and the solution is at most tol)", "success (both errors are at most tol)", "trapped by degeneracy (fvec is orthogonal to the columns of the jacobian)", "timeout (number of calls to fcn has reached maxcall*(n+1))", "failure (ftoly[z2]; ya /= m_dat; t2 = 0; sse = 0; sst = 0; for (z2=0;z2x[z2]); t2 += pow( fabs(((lmcurve_data_struct*)data)->y[z2] - t), 2); sse += (((lmcurve_data_struct*)data)->y[z2]-t)*(((lmcurve_data_struct*)data)->y[z2]-t); sst += (((lmcurve_data_struct*)data)->y[z2]-ya)*(((lmcurve_data_struct*)data)->y[z2]-ya); } r = sqrt(1.0 - sse/sst); mprintf(" %4d: Fit RMS Error = %15.8f; R = %10.8f; sse=%G; sst=%G; sse/sst=%G.\n",g_iLMPrintTmp,t2,r,sse,sst,sse/sst); for (z2=0;z2 norm: %18.11g\n", lm_enorm(m_dat, fvec)); } if( printflags & 3 ) mprintf( "\n" ); if ( (printflags & 8) || ((printflags & 4) && iflag == -1) ) { mprintf(" residuals:\n"); for (i = 0; i < m_dat; ++i) mprintf(" fvec[%2d]=%12g\n", i, fvec[i] ); } } /*****************************************************************************/ /* lm_minimize (intermediate-level interface) */ /*****************************************************************************/ void lmmin( int n_par, double *par, int m_dat, const void *data, void (*evaluate) (const double *par, int m_dat, const void *data, double *fvec, int *info), const lm_control_struct *control, lm_status_struct *status, void (*printout) (int n_par, const double *par, int m_dat, const void *data, const double *fvec, int printflags, int iflag, int iter, int nfev) ) { /*** allocate work space. ***/ g_iLMPrintTmp = 0; if (!g_bLMFitSilent) { mprintf(" Fitting "); mprintf(WHITE,"["); } double *fvec, *diag, *fjac, *qtf, *wa1, *wa2, *wa3, *wa4; int *ipvt; int n = n_par; int m = m_dat; if ( (fvec = (double *) malloc(m * sizeof(double))) == NULL || (diag = (double *) malloc(n * sizeof(double))) == NULL || (qtf = (double *) malloc(n * sizeof(double))) == NULL || (fjac = (double *) malloc(n*m*sizeof(double))) == NULL || (wa1 = (double *) malloc(n * sizeof(double))) == NULL || (wa2 = (double *) malloc(n * sizeof(double))) == NULL || (wa3 = (double *) malloc(n * sizeof(double))) == NULL || (wa4 = (double *) malloc(m * sizeof(double))) == NULL || (ipvt = (int *) malloc(n * sizeof(int) )) == NULL ) { status->info = 9; return; } int j; if( ! control->scale_diag ) for( j=0; jinfo = 0; /* this goes through the modified legacy interface: */ lm_lmdif( m, n, par, fvec, control->ftol, control->xtol, control->gtol, control->maxcall * (n + 1), control->epsilon, diag, ( control->scale_diag ? 1 : 2 ), control->stepbound, &(status->info), &(status->nfev), fjac, ipvt, qtf, wa1, wa2, wa3, wa4, evaluate, printout, control->printflags, data ); if ( printout ) (*printout)( n, par, m, data, fvec, control->printflags, -1, 0, status->nfev ); status->fnorm = lm_enorm(m, fvec); if ( status->info < 0 ) status->info = 11; /*** clean up. ***/ free(fvec); free(diag); free(qtf); free(fjac); free(wa1); free(wa2); free(wa3); free(wa4); free(ipvt); if (!g_bLMFitSilent) mprintf(WHITE,"]\n"); } /*** lm_minimize. ***/ /*****************************************************************************/ /* lm_lmdif (low-level, modified legacy interface for full control) */ /*****************************************************************************/ void lm_lmpar( int n, double *r, int ldr, int *ipvt, double *diag, double *qtb, double delta, double *par, double *x, double *sdiag, double *aux, double *xdi ); void lm_qrfac( int m, int n, double *a, int pivot, int *ipvt, double *rdiag, double *acnorm, double *wa ); void lm_qrsolv( int n, double *r, int ldr, int *ipvt, double *diag, double *qtb, double *x, double *sdiag, double *wa ); //#define MIN(a,b) (((a)<=(b)) ? (a) : (b)) //#define MAX(a,b) (((a)>=(b)) ? (a) : (b)) //#define SQR(x) (x)*(x) void lm_lmdif( int m, int n, double *x, double *fvec, double ftol, double xtol, double gtol, int maxfev, double epsfcn, double *diag, int mode, double factor, int *info, int *nfev, double *fjac, int *ipvt, double *qtf, double *wa1, double *wa2, double *wa3, double *wa4, void (*evaluate) (const double *par, int m_dat, const void *data, double *fvec, int *info), void (*printout) (int n_par, const double *par, int m_dat, const void *data, const double *fvec, int printflags, int iflag, int iter, int nfev), int printflags, const void *data ) { /* * The purpose of lmdif is to minimize the sum of the squares of * m nonlinear functions in n variables by a modification of * the levenberg-marquardt algorithm. The user must provide a * subroutine evaluate which calculates the functions. The jacobian * is then calculated by a forward-difference approximation. * * The multi-parameter interface lm_lmdif is for users who want * full control and flexibility. Most users will be better off using * the simpler interface lmmin provided above. * * Parameters: * * m is a positive integer input variable set to the number * of functions. * * n is a positive integer input variable set to the number * of variables; n must not exceed m. * * x is an array of length n. On input x must contain an initial * estimate of the solution vector. On OUTPUT x contains the * final estimate of the solution vector. * * fvec is an OUTPUT array of length m which contains * the functions evaluated at the output x. * * ftol is a nonnegative input variable. Termination occurs when * both the actual and predicted relative reductions in the sum * of squares are at most ftol. Therefore, ftol measures the * relative error desired in the sum of squares. * * xtol is a nonnegative input variable. Termination occurs when * the relative error between two consecutive iterates is at * most xtol. Therefore, xtol measures the relative error desired * in the approximate solution. * * gtol is a nonnegative input variable. Termination occurs when * the cosine of the angle between fvec and any column of the * jacobian is at most gtol in absolute value. Therefore, gtol * measures the orthogonality desired between the function vector * and the columns of the jacobian. * * maxfev is a positive integer input variable. Termination * occurs when the number of calls to lm_fcn is at least * maxfev by the end of an iteration. * * epsfcn is an input variable used in choosing a step length for * the forward-difference approximation. The relative errors in * the functions are assumed to be of the order of epsfcn. * * diag is an array of length n. If mode = 1 (see below), diag is * internally set. If mode = 2, diag must contain positive entries * that serve as multiplicative scale factors for the variables. * * mode is an integer input variable. If mode = 1, the * variables will be scaled internally. If mode = 2, * the scaling is specified by the input diag. * * factor is a positive input variable used in determining the * initial step bound. This bound is set to the product of * factor and the euclidean norm of diag*x if nonzero, or else * to factor itself. In most cases factor should lie in the * interval (0.1,100.0). Generally, the value 100.0 is recommended. * * info is an integer OUTPUT variable that indicates the termination * status of lm_lmdif as follows: * * info < 0 termination requested by user-supplied routine *evaluate; * * info = 0 fnorm almost vanishing; * * info = 1 both actual and predicted relative reductions * in the sum of squares are at most ftol; * * info = 2 relative error between two consecutive iterates * is at most xtol; * * info = 3 conditions for info = 1 and info = 2 both hold; * * info = 4 the cosine of the angle between fvec and any * column of the jacobian is at most gtol in * absolute value; * * info = 5 number of calls to lm_fcn has reached or * exceeded maxfev; * * info = 6 ftol is too small: no further reduction in * the sum of squares is possible; * * info = 7 xtol is too small: no further improvement in * the approximate solution x is possible; * * info = 8 gtol is too small: fvec is orthogonal to the * columns of the jacobian to machine precision; * * info =10 improper input parameters; * * nfev is an OUTPUT variable set to the number of calls to the * user-supplied routine *evaluate. * * fjac is an OUTPUT m by n array. The upper n by n submatrix * of fjac contains an upper triangular matrix r with * diagonal elements of nonincreasing magnitude such that * * pT*(jacT*jac)*p = rT*r * * (NOTE: T stands for matrix transposition), * * where p is a permutation matrix and jac is the final * calculated jacobian. Column j of p is column ipvt(j) * (see below) of the identity matrix. The lower trapezoidal * part of fjac contains information generated during * the computation of r. * * ipvt is an integer OUTPUT array of length n. It defines a * permutation matrix p such that jac*p = q*r, where jac is * the final calculated jacobian, q is orthogonal (not stored), * and r is upper triangular with diagonal elements of * nonincreasing magnitude. Column j of p is column ipvt(j) * of the identity matrix. * * qtf is an OUTPUT array of length n which contains * the first n elements of the vector (q transpose)*fvec. * * wa1, wa2, and wa3 are work arrays of length n. * * wa4 is a work array of length m, used among others to hold * residuals from evaluate. * * evaluate points to the subroutine which calculates the * m nonlinear functions. Implementations should be written as follows: * * void evaluate( double* par, int m_dat, void *data, * double* fvec, int *info ) * { * // for ( i=0; i= 0.) temp = 0.5; else temp = 0.5 * dirder / (dirder + 0.55 * actred); if (p1 * fnorm1 >= fnorm || temp < p1) temp = p1; delta = temp * MIN(delta, pnorm / p1); par /= temp; } else if (par == 0. || ratio >= 0.75) { delta = pnorm / 0.5; par *= 0.5; } /*** inner: test for successful iteration. ***/ if (ratio >= p0001) { /* yes, success: update x, fvec, and their norms. */ for (j = 0; j < n; j++) { x[j] = wa2[j]; wa2[j] = diag[j] * x[j]; } for (i = 0; i < m; i++) fvec[i] = wa4[i]; xnorm = lm_enorm(n, wa2); fnorm = fnorm1; iter++; } #ifdef LMFIT_DEBUG_MESSAGES else { mprintf("ATTN: iteration considered unsuccessful\n"); } #endif /*** inner: test for convergence. ***/ if( fnorm<=LM_DWARF ){ *info = 0; return; } *info = 0; if (fabs(actred) <= ftol && prered <= ftol && 0.5 * ratio <= 1) *info = 1; if (delta <= xtol * xnorm) *info += 2; if (*info != 0) return; /*** inner: tests for termination and stringent tolerances. ***/ if (*nfev >= maxfev){ *info = 5; return; } if (fabs(actred) <= LM_MACHEP && prered <= LM_MACHEP && 0.5 * ratio <= 1){ *info = 6; return; } if (delta <= LM_MACHEP * xnorm){ *info = 7; return; } if (gnorm <= LM_MACHEP){ *info = 8; return; } /*** inner: end of the loop. repeat if iteration unsuccessful. ***/ } while (ratio < p0001); /*** outer: end of the loop. ***/ } while (1); } /*** lm_lmdif. ***/ /*****************************************************************************/ /* lm_lmpar (determine Levenberg-Marquardt parameter) */ /*****************************************************************************/ void lm_lmpar(int n, double *r, int ldr, int *ipvt, double *diag, double *qtb, double delta, double *par, double *x, double *sdiag, double *aux, double *xdi) { /* Given an m by n matrix a, an n by n nonsingular diagonal * matrix d, an m-vector b, and a positive number delta, * the problem is to determine a value for the parameter * par such that if x solves the system * * a*x = b and sqrt(par)*d*x = 0 * * in the least squares sense, and dxnorm is the euclidean * norm of d*x, then either par=0 and (dxnorm-delta) < 0.1*delta, * or par>0 and abs(dxnorm-delta) < 0.1*delta. * * Using lm_qrsolv, this subroutine completes the solution of the problem * if it is provided with the necessary information from the * qr factorization, with column pivoting, of a. That is, if * a*p = q*r, where p is a permutation matrix, q has orthogonal * columns, and r is an upper triangular matrix with diagonal * elements of nonincreasing magnitude, then lmpar expects * the full upper triangle of r, the permutation matrix p, * and the first n components of qT*b. On output * lmpar also provides an upper triangular matrix s such that * * pT*(aT*a + par*d*d)*p = sT*s. * * s is employed within lmpar and may be of separate interest. * * Only a few iterations are generally needed for convergence * of the algorithm. If, however, the limit of 10 iterations * is reached, then the output par will contain the best * value obtained so far. * * parameters: * * n is a positive integer input variable set to the order of r. * * r is an n by n array. on input the full upper triangle * must contain the full upper triangle of the matrix r. * on OUTPUT the full upper triangle is unaltered, and the * strict lower triangle contains the strict upper triangle * (transposed) of the upper triangular matrix s. * * ldr is a positive integer input variable not less than n * which specifies the leading dimension of the array r. * * ipvt is an integer input array of length n which defines the * permutation matrix p such that a*p = q*r. column j of p * is column ipvt(j) of the identity matrix. * * diag is an input array of length n which must contain the * diagonal elements of the matrix d. * * qtb is an input array of length n which must contain the first * n elements of the vector (q transpose)*b. * * delta is a positive input variable which specifies an upper * bound on the euclidean norm of d*x. * * par is a nonnegative variable. on input par contains an * initial estimate of the levenberg-marquardt parameter. * on OUTPUT par contains the final estimate. * * x is an OUTPUT array of length n which contains the least * squares solution of the system a*x = b, sqrt(par)*d*x = 0, * for the output par. * * sdiag is an array of length n which contains the * diagonal elements of the upper triangular matrix s. * * aux is a multi-purpose work array of length n. * * xdi is a work array of length n. On OUTPUT: diag[j] * x[j]. * */ int i, iter, j, nsing; double dxnorm, fp, fp_old, gnorm, parc, parl, paru; double sum, temp; static double p1 = 0.1; #ifdef LMFIT_DEBUG_MESSAGES mprintf("lmpar\n"); #endif /*** lmpar: compute and store in x the gauss-newton direction. if the jacobian is rank-deficient, obtain a least squares solution. ***/ nsing = n; for (j = 0; j < n; j++) { aux[j] = qtb[j]; if (r[j * ldr + j] == 0 && nsing == n) // if ((fabs(r[j * ldr + j]) < 1e-100) && (nsing == n)) nsing = j; if (nsing < n) aux[j] = 0; } //#ifdef LMFIT_DEBUG_MESSAGES #ifdef LMFIT_MYDEBUG mprintf("\n$ nsing %d ", nsing); #endif for (j = nsing - 1; j >= 0; j--) { #ifdef LMFIT_MYDEBUG mprintf("\n$ A aux[%d]=%G, r[%d + %d*%d]=%G.",j,aux[j],j,ldr,j,r[j + ldr * j]); #endif aux[j] = aux[j] / r[j + ldr * j]; #ifdef LMFIT_MYDEBUG mprintf("\n$ B aux[%d]=%G.",j,aux[j]); #endif temp = aux[j]; for (i = 0; i < j; i++) aux[i] -= r[j * ldr + i] * temp; #ifdef LMFIT_MYDEBUG mprintf("\n$ C aux[%d]=%G.",j,aux[j]); #endif } for (j = 0; j < n; j++) x[ipvt[j]] = aux[j]; /*** lmpar: initialize the iteration counter, evaluate the function at the origin, and test for acceptance of the gauss-newton direction. ***/ iter = 0; for (j = 0; j < n; j++) { // mprintf("\n$ diag[%d]=%G, x[%d]=%G.",j,diag[j],j,x[j]); xdi[j] = diag[j] * x[j]; } dxnorm = lm_enorm(n, xdi); #ifdef LMFIT_MYDEBUG mprintf("\n$ dxnorm=%G, delta=%G.",dxnorm,delta); #endif fp = dxnorm - delta; if (fp <= p1 * delta) { #ifdef LMFIT_DEBUG_MESSAGES mprintf("lmpar/ terminate (fp= n) { for (j = 0; j < n; j++) aux[j] = diag[ipvt[j]] * xdi[ipvt[j]] / dxnorm; for (j = 0; j < n; j++) { sum = 0.; for (i = 0; i < j; i++) sum += r[j * ldr + i] * aux[i]; aux[j] = (aux[j] - sum) / r[j + ldr * j]; } temp = lm_enorm(n, aux); #ifdef LMFIT_MYDEBUG mprintf("\n$ fp=%G, delta=%G, temp=%G, sum=%G, dxnorm=%G.",fp,delta,temp,sum,dxnorm); #endif parl = fp / delta / temp / temp; } #ifdef LMFIT_MYDEBUG mprintf("\n$ parl = %G.",parl); #endif /*** lmpar: calculate an upper bound, paru, for the 0. of the function. ***/ for (j = 0; j < n; j++) { sum = 0; for (i = 0; i <= j; i++) sum += r[j * ldr + i] * qtb[i]; aux[j] = sum / diag[ipvt[j]]; } gnorm = lm_enorm(n, aux); paru = gnorm / delta; if (paru == 0.) paru = LM_DWARF / MIN(delta, p1); /*** lmpar: if the input par lies outside of the interval (parl,paru), set par to the closer endpoint. ***/ *par = MAX(*par, parl); *par = MIN(*par, paru); if (*par == 0.) *par = gnorm / dxnorm; #ifdef LMFIT_DEBUG_MESSAGES mprintf("lmpar/ parl %.4e par %.4e paru %.4e\n", parl, *par, paru); #endif /*** lmpar: iterate. ***/ for (;; iter++) { /** evaluate the function at the current value of par. **/ if (*par == 0.) *par = MAX(LM_DWARF, 0.001 * paru); temp = sqrt(*par); for (j = 0; j < n; j++) aux[j] = temp * diag[j]; lm_qrsolv( n, r, ldr, ipvt, aux, qtb, x, sdiag, xdi ); /* return values are r, x, sdiag */ #ifdef LMFIT_MYDEBUG for (j=0;j<10;j++) mprintf("\n$ iter=%d, j=%d, x=%G.",iter,j,x[j]); #endif for (j = 0; j < n; j++) xdi[j] = diag[j] * x[j]; /* used as output */ dxnorm = lm_enorm(n, xdi); fp_old = fp; fp = dxnorm - delta; /** if the function is small enough, accept the current value of par. Also test for the exceptional cases where parl is zero or the number of iterations has reached 10. **/ if (fabs(fp) <= p1 * delta || (parl == 0. && fp <= fp_old && fp_old < 0.) || iter == 10) break; /* the only exit from the iteration. */ /** compute the Newton correction. **/ for (j = 0; j < n; j++) aux[j] = diag[ipvt[j]] * xdi[ipvt[j]] / dxnorm; for (j = 0; j < n; j++) { aux[j] = aux[j] / sdiag[j]; for (i = j + 1; i < n; i++) aux[i] -= r[j * ldr + i] * aux[j]; } temp = lm_enorm(n, aux); parc = fp / delta / temp / temp; /** depending on the sign of the function, update parl or paru. **/ if (fp > 0) parl = MAX(parl, *par); else if (fp < 0) paru = MIN(paru, *par); /* the case fp==0 is precluded by the break condition */ /** compute an improved estimate for par. **/ #ifdef LMFIT_MYDEBUG mprintf("\n$ %G = MAX( %G, %G + %G ).",MAX(parl, *par + parc),parl,*par,parc); #endif *par = MAX(parl, *par + parc); } } /*** lm_lmpar. ***/ /*****************************************************************************/ /* lm_qrfac (QR factorisation, from lapack) */ /*****************************************************************************/ void lm_qrfac(int m, int n, double *a, int pivot, int *ipvt, double *rdiag, double *acnorm, double *wa) { /* * This subroutine uses householder transformations with column * pivoting (optional) to compute a qr factorization of the * m by n matrix a. That is, qrfac determines an orthogonal * matrix q, a permutation matrix p, and an upper trapezoidal * matrix r with diagonal elements of nonincreasing magnitude, * such that a*p = q*r. The householder transformation for * column k, k = 1,2,...,min(m,n), is of the form * * i - (1/u(k))*u*uT * * where u has zeroes in the first k-1 positions. The form of * this transformation and the method of pivoting first * appeared in the corresponding linpack subroutine. * * Parameters: * * m is a positive integer input variable set to the number * of rows of a. * * n is a positive integer input variable set to the number * of columns of a. * * a is an m by n array. On input a contains the matrix for * which the qr factorization is to be computed. On OUTPUT * the strict upper trapezoidal part of a contains the strict * upper trapezoidal part of r, and the lower trapezoidal * part of a contains a factored form of q (the non-trivial * elements of the u vectors described above). * * pivot is a logical input variable. If pivot is set true, * then column pivoting is enforced. If pivot is set false, * then no column pivoting is done. * * ipvt is an integer OUTPUT array of length lipvt. This array * defines the permutation matrix p such that a*p = q*r. * Column j of p is column ipvt(j) of the identity matrix. * If pivot is false, ipvt is not referenced. * * rdiag is an OUTPUT array of length n which contains the * diagonal elements of r. * * acnorm is an OUTPUT array of length n which contains the * norms of the corresponding columns of the input matrix a. * If this information is not needed, then acnorm can coincide * with rdiag. * * wa is a work array of length n. If pivot is false, then wa * can coincide with rdiag. * */ int i, j, k, kmax, minmn; double ajnorm, sum, temp; /*** qrfac: compute initial column norms and initialize several arrays. ***/ for (j = 0; j < n; j++) { acnorm[j] = lm_enorm(m, &a[j*m]); rdiag[j] = acnorm[j]; wa[j] = rdiag[j]; if (pivot) ipvt[j] = j; } #ifdef LMFIT_DEBUG_MESSAGES mprintf("qrfac\n"); #endif /*** qrfac: reduce a to r with householder transformations. ***/ minmn = MIN(m, n); for (j = 0; j < minmn; j++) { if (!pivot) goto pivot_ok; /** bring the column of largest norm into the pivot position. **/ kmax = j; for (k = j + 1; k < n; k++) if (rdiag[k] > rdiag[kmax]) kmax = k; if (kmax == j) goto pivot_ok; for (i = 0; i < m; i++) { temp = a[j*m+i]; a[j*m+i] = a[kmax*m+i]; a[kmax*m+i] = temp; } rdiag[kmax] = rdiag[j]; wa[kmax] = wa[j]; k = ipvt[j]; ipvt[j] = ipvt[kmax]; ipvt[kmax] = k; pivot_ok: /** compute the Householder transformation to reduce the j-th column of a to a multiple of the j-th unit vector. **/ ajnorm = lm_enorm(m-j, &a[j*m+j]); // Change by M. Brehm, July 3rd, 2013 if (fabs(ajnorm) < 1e-200) { rdiag[j] = 0; continue; } if (a[j*m+j] < 0.) ajnorm = -ajnorm; for (i = j; i < m; i++) a[j*m+i] /= ajnorm; a[j*m+j] += 1; /** apply the transformation to the remaining columns and update the norms. **/ for (k = j + 1; k < n; k++) { sum = 0; for (i = j; i < m; i++) sum += a[j*m+i] * a[k*m+i]; temp = sum / a[j + m * j]; for (i = j; i < m; i++) a[k*m+i] -= temp * a[j*m+i]; if (pivot && rdiag[k] != 0.) { temp = a[m * k + j] / rdiag[k]; temp = MAX(0., 1 - temp * temp); rdiag[k] *= sqrt(temp); temp = rdiag[k] / wa[k]; if ( 0.05 * SQR(temp) <= LM_MACHEP ) { rdiag[k] = lm_enorm(m-j-1, &a[m*k+j+1]); wa[k] = rdiag[k]; } } } rdiag[j] = -ajnorm; } } /*****************************************************************************/ /* lm_qrsolv (linear least-squares) */ /*****************************************************************************/ void lm_qrsolv(int n, double *r, int ldr, int *ipvt, double *diag, double *qtb, double *x, double *sdiag, double *wa) { /* * Given an m by n matrix a, an n by n diagonal matrix d, * and an m-vector b, the problem is to determine an x which * solves the system * * a*x = b and d*x = 0 * * in the least squares sense. * * This subroutine completes the solution of the problem * if it is provided with the necessary information from the * qr factorization, with column pivoting, of a. That is, if * a*p = q*r, where p is a permutation matrix, q has orthogonal * columns, and r is an upper triangular matrix with diagonal * elements of nonincreasing magnitude, then qrsolv expects * the full upper triangle of r, the permutation matrix p, * and the first n components of (q transpose)*b. The system * a*x = b, d*x = 0, is then equivalent to * * r*z = qT*b, pT*d*p*z = 0, * * where x = p*z. If this system does not have full rank, * then a least squares solution is obtained. On output qrsolv * also provides an upper triangular matrix s such that * * pT *(aT *a + d*d)*p = sT *s. * * s is computed within qrsolv and may be of separate interest. * * Parameters * * n is a positive integer input variable set to the order of r. * * r is an n by n array. On input the full upper triangle * must contain the full upper triangle of the matrix r. * On OUTPUT the full upper triangle is unaltered, and the * strict lower triangle contains the strict upper triangle * (transposed) of the upper triangular matrix s. * * ldr is a positive integer input variable not less than n * which specifies the leading dimension of the array r. * * ipvt is an integer input array of length n which defines the * permutation matrix p such that a*p = q*r. Column j of p * is column ipvt(j) of the identity matrix. * * diag is an input array of length n which must contain the * diagonal elements of the matrix d. * * qtb is an input array of length n which must contain the first * n elements of the vector (q transpose)*b. * * x is an OUTPUT array of length n which contains the least * squares solution of the system a*x = b, d*x = 0. * * sdiag is an OUTPUT array of length n which contains the * diagonal elements of the upper triangular matrix s. * * wa is a work array of length n. * */ int i, kk, j, k, nsing; double qtbpj, sum, temp; double _sin, _cos, _tan, _cot; /* local variables, not functions */ /*** qrsolv: copy r and (q transpose)*b to preserve input and initialize s. in particular, save the diagonal elements of r in x. ***/ for (j = 0; j < n; j++) { for (i = j; i < n; i++) r[j * ldr + i] = r[i * ldr + j]; x[j] = r[j * ldr + j]; wa[j] = qtb[j]; } #ifdef LMFIT_DEBUG_MESSAGES mprintf("qrsolv\n"); #endif /*** qrsolv: eliminate the diagonal matrix d using a Givens rotation. ***/ for (j = 0; j < n; j++) { /*** qrsolv: prepare the row of d to be eliminated, locating the diagonal element using p from the qr factorization. ***/ if (diag[ipvt[j]] == 0.) goto L90; for (k = j; k < n; k++) sdiag[k] = 0.; sdiag[j] = diag[ipvt[j]]; /*** qrsolv: the transformations to eliminate the row of d modify only a single element of qT*b beyond the first n, which is initially 0. ***/ qtbpj = 0.; for (k = j; k < n; k++) { /** determine a Givens rotation which eliminates the appropriate element in the current row of d. **/ if (sdiag[k] == 0.) continue; kk = k + ldr * k; if (fabs(r[kk]) < fabs(sdiag[k])) { _cot = r[kk] / sdiag[k]; _sin = 1 / sqrt(1 + SQR(_cot)); _cos = _sin * _cot; } else { _tan = sdiag[k] / r[kk]; _cos = 1 / sqrt(1 + SQR(_tan)); _sin = _cos * _tan; } /** compute the modified diagonal element of r and the modified element of ((q transpose)*b,0). **/ r[kk] = _cos * r[kk] + _sin * sdiag[k]; temp = _cos * wa[k] + _sin * qtbpj; qtbpj = -_sin * wa[k] + _cos * qtbpj; wa[k] = temp; /** accumulate the tranformation in the row of s. **/ for (i = k + 1; i < n; i++) { temp = _cos * r[k * ldr + i] + _sin * sdiag[i]; sdiag[i] = -_sin * r[k * ldr + i] + _cos * sdiag[i]; r[k * ldr + i] = temp; } } L90: /** store the diagonal element of s and restore the corresponding diagonal element of r. **/ sdiag[j] = r[j * ldr + j]; r[j * ldr + j] = x[j]; } /*** qrsolv: solve the triangular system for z. if the system is singular, then obtain a least squares solution. ***/ nsing = n; for (j = 0; j < n; j++) { if (sdiag[j] == 0. && nsing == n) nsing = j; if (nsing < n) wa[j] = 0; } for (j = nsing - 1; j >= 0; j--) { sum = 0; for (i = j + 1; i < nsing; i++) sum += r[j * ldr + i] * wa[i]; wa[j] = (wa[j] - sum) / sdiag[j]; } /*** qrsolv: permute the components of z back to components of x. ***/ for (j = 0; j < n; j++) x[ipvt[j]] = wa[j]; } /*** lm_qrsolv. ***/ /*****************************************************************************/ /* lm_enorm (Euclidean norm) */ /*****************************************************************************/ double lm_enorm(int n, const double *x) { /* Given an n-vector x, this function calculates the * euclidean norm of x. * * The euclidean norm is computed by accumulating the sum of * squares in three different sums. The sums of squares for the * small and large components are scaled so that no overflows * occur. Non-destructive underflows are permitted. Underflows * and overflows do not occur in the computation of the unscaled * sum of squares for the intermediate components. * The definitions of small, intermediate and large components * depend on two constants, LM_SQRT_DWARF and LM_SQRT_GIANT. The main * restrictions on these constants are that LM_SQRT_DWARF**2 not * underflow and LM_SQRT_GIANT**2 not overflow. * * Parameters * * n is a positive integer input variable. * * x is an input array of length n. */ int i; double agiant, s1, s2, s3, xabs, x1max, x3max, temp; s1 = 0; s2 = 0; s3 = 0; x1max = 0; x3max = 0; agiant = LM_SQRT_GIANT / n; /** sum squares. **/ for (i = 0; i < n; i++) { xabs = fabs(x[i]); if (xabs > LM_SQRT_DWARF) { if ( xabs < agiant ) { s2 += xabs * xabs; } else if ( xabs > x1max ) { temp = x1max / xabs; s1 = 1 + s1 * SQR(temp); x1max = xabs; } else { temp = xabs / x1max; s1 += SQR(temp); } } else if ( xabs > x3max ) { temp = x3max / xabs; s3 = 1 + s3 * SQR(temp); x3max = xabs; } else if (xabs != 0.) { temp = xabs / x3max; s3 += SQR(temp); } } /** calculation of norm. **/ if (s1 != 0) return x1max * sqrt(s1 + (s2 / x1max) / x1max); else if (s2 != 0) if (s2 >= x3max) return sqrt(s2 * (1 + (x3max / s2) * (x3max * s3))); else return sqrt(x3max * ((s2 / x3max) + (x3max * s3))); else return x3max * sqrt(s3); } /*** lm_enorm. ***/ travis-src-190101/src/lmmin.h0100777000000000000000000001321713412725657012736 0ustar00/***************************************************************************** TRAVIS - Trajectory Analyzer and Visualizer http://www.travis-analyzer.de/ Copyright (c) 2009-2019 Martin Brehm 2012-2019 Martin Thomas 2016-2019 Sascha Gehrke --------------------------------------------------------------------------- This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . *****************************************************************************/ /* * Project: LevenbergMarquardtLeastSquaresFitting * * File: lmmin.h * * Contents: Public interface to the Levenberg-Marquardt core implementation. * * Author: Joachim Wuttke 2004-2010 * * Homepage: www.messen-und-deuten.de/lmfit */ #ifndef LMMIN_H #define LMMIN_H //#ifdef __cplusplus //extern "C" { //#endif // This must always be the first include directive #include "config.h" #include /** Compact high-level interface. **/ /* Collection of control (input) parameters. */ typedef struct { double ftol; /* relative error desired in the sum of squares. */ double xtol; /* relative error between last two approximations. */ double gtol; /* orthogonality desired between fvec and its derivs. */ double epsilon; /* step used to calculate the jacobian. */ double stepbound; /* initial bound to steps in the outer loop. */ int maxcall; /* maximum number of iterations. */ int scale_diag; /* UNDOCUMENTED, TESTWISE automatical diag rescaling? */ int printflags; /* OR'ed to produce more noise */ } lm_control_struct; /* Collection of status (output) parameters. */ typedef struct { double fnorm; /* norm of the residue vector fvec. */ int nfev; /* actual number of iterations. */ int info; /* status of minimization. */ } lm_status_struct; /* Recommended control parameter settings. */ extern const lm_control_struct lm_control_double; extern const lm_control_struct lm_control_float; /* Standard monitoring routine. */ void lm_printout_std( int n_par, const double *par, int m_dat, const void *data, const double *fvec, int printflags, int iflag, int iter, int nfev); /* Refined calculation of Eucledian norm, typically used in printout routine. */ double lm_enorm( int, const double * ); /* The actual minimization. */ void lmmin( int n_par, double *par, int m_dat, const void *data, void (*evaluate) (const double *par, int m_dat, const void *data, double *fvec, int *info), const lm_control_struct *control, lm_status_struct *status, void (*printout) (int n_par, const double *par, int m_dat, const void *data, const double *fvec, int printflags, int iflag, int iter, int nfev) ); /** Legacy low-level interface. **/ /* Alternative to lm_minimize, allowing full control, and read-out of auxiliary arrays. For usage, see implementation of lm_minimize. */ void lm_lmdif( int m, int n, double *x, double *fvec, double ftol, double xtol, double gtol, int maxfev, double epsfcn, double *diag, int mode, double factor, int *info, int *nfev, double *fjac, int *ipvt, double *qtf, double *wa1, double *wa2, double *wa3, double *wa4, void (*evaluate) (const double *par, int m_dat, const void *data, double *fvec, int *info), void (*printout) (int n_par, const double *par, int m_dat, const void *data, const double *fvec, int printflags, int iflag, int iter, int nfev), int printflags, const void *data ); extern const char *lm_infmsg[]; extern const char *lm_shortmsg[]; /*****************************************************************************/ /* set numeric constants */ /*****************************************************************************/ /* machine-dependent constants from float.h */ #define LM_MACHEP DBL_EPSILON /* resolution of arithmetic */ #define LM_DWARF DBL_MIN /* smallest nonzero number */ #define LM_SQRT_DWARF sqrt(DBL_MIN) /* square should not underflow */ #define LM_SQRT_GIANT sqrt(DBL_MAX) /* square should not overflow */ #define LM_USERTOL 30*LM_MACHEP /* users are recommended to require this */ /* If the above values do not work, the following seem good for an x86: LM_MACHEP .555e-16 LM_DWARF 9.9e-324 LM_SQRT_DWARF 1.e-160 LM_SQRT_GIANT 1.e150 LM_USERTOL 1.e-14*/ /* The following values should work on any machine: #define LM_MACHEP 1.2e-16 #define LM_DWARF 1.0e-38 #define LM_SQRT_DWARF 3.834e-20 #define LM_SQRT_GIANT 1.304e19 #define LM_USERTOL 1.e-14*/ /*const lm_control_struct lm_control_double = { LM_USERTOL, LM_USERTOL, LM_USERTOL, LM_USERTOL, 1.0, 2000, 1, 0 }; const lm_control_struct lm_control_float = { 1.e-7, 1.e-7, 1.e-7, 1.e-7, 1.0, 100, 0, 0 };*/ //#ifdef __cplusplus //} //#endif #endif /* LMMIN_H */ travis-src-190101/src/lmwrapper.cpp0100777000000000000000000002727513412725617014173 0ustar00/***************************************************************************** TRAVIS - Trajectory Analyzer and Visualizer http://www.travis-analyzer.de/ Copyright (c) 2009-2019 Martin Brehm 2012-2019 Martin Thomas 2016-2019 Sascha Gehrke This file was written by Martin Brehm. --------------------------------------------------------------------------- This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . *****************************************************************************/ // This must always be the first include directive #include "config.h" #include "lmwrapper.h" #include #include "tools.h" #include "globalvar.h" const char *GetRevisionInfo_lmwrapper(unsigned int len) { static char buf[256]; GET_REVISION_INFO( buf, len ); return buf; } const char *GetSourceVersion_lmwrapper() { static char buf[256]; GET_SOURCE_VERSION( buf ); return buf; } double g_fZeroWeight; CLMWrapper::CLMWrapper() { } CLMWrapper::~CLMWrapper() { } void lmcurve_evaluate(const double *par, int m_dat, const void *data, double *fvec, int *info) { int z, z2; double t; // const double eps = 0.001; UNUSED(info); // Suppress "unused parameter" warning for (z2=0;z2x[z2]); /* if (par[z*2+1] > -eps) fvec[z2] += (par[z*2+1]+eps) * 1000.0; if (par[z*2] < 0) fvec[z2] += fabs(par[z*2]) * 1000.0;*/ } fvec[z2] = ((lmcurve_data_struct*)data)->y[z2] - t; if (z2 == 0) fvec[z2] *= 100.0; for (z=0;zy,m_dat*sizeof(double)); // mprintf("\n#### EVAL"); for (z=0;zx[z2]); } fvec[0] *= g_fZeroWeight; // mprintf("\nEval: %G; %G; %G; ...",fvec[0],fvec[1],fvec[2]); /* for (z2=0;z2x[z2]); fvec[z2] = ((lmcurve_data_struct*)data)->y[z2] - t; if (z2 == 0) fvec[z2] *= g_fZeroWeight; }*/ } void lmcurve_evaluate_sd(const double *par, int m_dat, const void *data, double *fvec, int *info) { int z; UNUSED(info); // Suppress "unused parameter" warning for (z=0;zy[z] - par[0] * (1.0 - exp(par[1] * mypow( ((lmcurve_data_struct*)data)->x[z],par[2]) )); } double f_PolyExp(double t, const double *p) { double r; int z; r = 0; for (z=0;z t) { t = -par[z2*2]/par[z2*2+1]; i = z2; } } if ((i != -1) && (i != z)) { t = par[z*2]; par[z*2] = par[i*2]; par[i*2] = t; t = par[z*2+1]; par[z*2+1] = par[i*2+1]; par[i*2+1] = t; } } mprintf(" Status: %s (%d cycles).\n",lm_infmsg[status.info],status.nfev); for (z=0;z= 0)) mprintf(" tau(%d) = %.8G ps",z+1,-par[z*2]/par[z*2+1]); mprintf("\n"); } mprintf(" R = % 13.9f",r); mprintf(" Chi^2 = % 12.8f\n",status.fnorm); integral = 0; for (z=0;z 0) { mprintf(" Curve integral is infinite (not all exponents <= 0)!\n"); integral = -1; goto _noint; } integral -= par[z*2]/par[z*2+1]; } mprintf(" Curve integral: tau(total) = %.8G ps.\n",integral); _noint: mprintf(" Fitting done.\n\n"); } void CLMWrapper::Fit_ExpSpectrum(int degree, double mi, double ma, int n, double *x, double *y, double *par, int fitcurvepoints, double *fitcurvex, double *fitcurve, const char *name, int maxcall, double zeroweight, bool evolve) { lm_status_struct status; lm_control_struct control; int z, z2, i; double ya, sse, sst, r; // char buf[256]; CxString buf; FILE *a; mprintf(" Performing Lifetime Spectrum fit (max. %d iterations)...\n",maxcall); if (evolve) { mprintf("\n Allocating %s of memory for evolution buffer...\n",FormatBytes((double)degree*maxcall*2*sizeof(double))); try { g_fLSpecEvolveBuf = new double[degree*maxcall*2]; } catch(...) { g_fLSpecEvolveBuf = NULL; } if (g_fLSpecEvolveBuf == NULL) NewException((double)degree*maxcall*2*sizeof(double),__FILE__,__LINE__,__PRETTY_FUNCTION__); for (z=0;z. *****************************************************************************/ #ifndef LMWRAPPER_H #define LMWRAPPER_H // This must always be the first include directive #include "config.h" #include "xobject.h" #include "lmmin.h" class CLMWrapper : public CxObject { public: void Fit_PolyExp(int degree, int n, double *x, double *y, double *par, double &r, double &integral, double *fitcurve, int maxcall); void Fit_ExpSpectrum(int degree, double mi, double ma, int n, double *x, double *y, double *par, int fitcurvepoints, double *fitcurvex, double *fitcurve, const char *name, int maxcall, double zeroweight, bool evolve); void Fit_SD(int n, double *x, double *y, double *par, double *fitcurve, double *r, int maxcall); CLMWrapper(); ~CLMWrapper(); }; #endif travis-src-190101/src/luzar.cpp0100777000000000000000000001706413412725621013305 0ustar00/***************************************************************************** TRAVIS - Trajectory Analyzer and Visualizer http://www.travis-analyzer.de/ Copyright (c) 2009-2019 Martin Brehm 2012-2019 Martin Thomas 2016-2019 Sascha Gehrke This file was written by Sascha Gehrke. --------------------------------------------------------------------------- This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . *****************************************************************************/ // This must always be the first include directive #include "config.h" #include "luzar.h" #include "globalvar.h" #include "maintools.h" const char *GetRevisionInfo_luzar(unsigned int len) { static char buf[256]; GET_REVISION_INFO( buf, len ); return buf; } const char *GetSourceVersion_luzar() { static char buf[256]; GET_SOURCE_VERSION( buf ); return buf; } CLuzarCorrelation::CLuzarCorrelation() { m_iInput = 0; m_iDepth = 0; m_pFFT = NULL; m_pFFT2 = NULL; } void CLuzarCorrelation::Init(int input, int depth) { m_iInput = input; m_iDepth = depth; m_iFFTSize = CalcSize(input); try { m_pFFT = new CFFT(); } catch(...) { m_pFFT = NULL; } if (m_pFFT == NULL) NewException((double)sizeof(CFFT),__FILE__,__LINE__,__PRETTY_FUNCTION__); m_pFFT->PrepareFFT_C2C(2*m_iFFTSize); try { m_pFFT2 = new CFFT(); } catch(...) { m_pFFT2 = NULL; } if (m_pFFT2 == NULL) NewException((double)sizeof(CFFT),__FILE__,__LINE__,__PRETTY_FUNCTION__); m_pFFT2->PrepareFFT_C2C(2*m_iFFTSize); try { m_pFFTback = new CFFT(); } catch(...) { m_pFFTback = NULL; } if (m_pFFTback == NULL) NewException((double)sizeof(CFFT),__FILE__,__LINE__,__PRETTY_FUNCTION__); m_pFFTback->PrepareInverseFFT_C2C(2*m_iFFTSize); } int CLuzarCorrelation::CalcSize(int n) // Calculate the next bigger number which is factorable by twos, threes, and fives { int m; while( n > 0 ) // Should be endless ... if not, you have a no-step trajectorie { m = n; while ( (m%2) == 0 ) m/=2; while ( (m%3) == 0 ) m/=3; while ( (m%5) == 0 ) m/=5; if ( m == 1 ) break; n++; } return n; } void CLuzarCorrelation::Correlate(CxDoubleArray* input1, CxDoubleArray* input2, CxDoubleArray* output1, CxDoubleArray* output2) { int i; output1->SetSize(m_iDepth); output2->SetSize(m_iDepth); for ( i=0; i < m_iInput; i++ ) // Fill Input-Strings with values and zeros { m_pFFT->m_pInput[i*2] = (*input1)[i]; m_pFFT->m_pInput[i*2+1] = 0; m_pFFT2->m_pInput[i*2] = (*input2)[i]; m_pFFT2->m_pInput[i*2+1] = 0; } for ( i=m_iInput; i < 2*m_iFFTSize; i++ ) // Fill with zeros { m_pFFT->m_pInput[i*2] = 0; m_pFFT->m_pInput[i*2+1] = 0; m_pFFT2->m_pInput[i*2] = 0; m_pFFT2->m_pInput[i*2+1] = 0; } m_pFFT->DoFFT(); // Move into Fourier-space m_pFFT2->DoFFT(); for ( i=0; i < 2*m_iFFTSize; i++ ) // Autocorrelate input1 { m_pFFTback->m_pInput[i*2] = (double)((m_pFFT->m_pOutput[i*2]*m_pFFT->m_pOutput[i*2] + m_pFFT->m_pOutput[i*2+1]*m_pFFT->m_pOutput[i*2+1])); m_pFFTback->m_pInput[i*2+1] = 0; } m_pFFTback->DoFFT(); // Leaving Fourier-space for ( i=0; i < m_iDepth; i++ ) // Fill autocorrelated function in output1 { (*output1)[i] = (double)((double)m_pFFTback->m_pOutput[2*i] / ((double)m_iInput - i)); } for ( i=0; i < 2*m_iFFTSize; i++ ) // Crosscorrelate input1 and input2 { m_pFFTback->m_pInput[i*2] = (double)((m_pFFT->m_pOutput[i*2]*m_pFFT2->m_pOutput[i*2] + m_pFFT->m_pOutput[i*2+1]*m_pFFT2->m_pOutput[i*2+1])); m_pFFTback->m_pInput[i*2+1] = (double)((m_pFFT->m_pOutput[i*2]*m_pFFT2->m_pOutput[i*2+1] - m_pFFT->m_pOutput[i*2+1]*m_pFFT2->m_pOutput[i*2])); } m_pFFTback->DoFFT(); // Leaving Fourier-space for ( i=0; i < m_iDepth; i++ ) // Fill crosscorrelated function in output2 { (*output2)[i] = (double)((double)m_pFFTback->m_pOutput[2*i] / ((double)m_iInput - i)); } } CLuzarCorrelation::~CLuzarCorrelation() { } void CLuzarCorrelation::Fit(CxDoubleArray* c, CxDoubleArray* n, CxDoubleArray* k, CxDoubleArray* a, CxDoubleArray* b, int trunc) { double RMS_alt = 1e25, conv = 1e-25, a_alt = 0.3, b_alt = 0.7, RMSa, RMSb, RMS; int i, j = 0; double multiplier, count, count_start = 1e7; bool repeat = true; double ps_corr = 1000 / (g_fTimestepLength * g_iStride); for ( i=1; iGetSize(); i++ ) k->Add( c->GetAt(i) - c->GetAt(i-1) ); while ( repeat ) { repeat = false; mprintf(" k_f[1/ps] k_b[1/ps] tau_f[ps] tau_b[ps]\n"); mprintf(" ---------------------------------------------------------\n"); a->Add(0.3); b->Add(0.7); RMS = GetRMS((*a)[0], (*b)[0], c, n, k, trunc); multiplier = 0.5; count = count_start; while ( multiplier > 0.000000000000009 ) { while ( RMS_alt - RMS > conv ) { a_alt = (*a)[j]; b_alt = (*b)[j]; RMS_alt = RMS; RMSa = GetRMS((*a)[j]*0.999999, (*b)[j], c, n, k, trunc); RMSb = GetRMS((*a)[j],(*b)[j]*0.999999, c, n, k, trunc); if ( RMS > RMSa ) (*a)[j] *= (1 - multiplier); else if ( RMS < RMSa ) (*a)[j] *= (1 + multiplier); if ( RMS > RMSb ) (*b)[j] *= (1 - multiplier); else if ( RMS < RMSb ) (*b)[j] *= (1 + multiplier); RMS = GetRMS((*a)[j], (*b)[j], c, n, k, trunc); if ( count == 0 ) { multiplier = 0; break; } count--; } RMS_alt = 1e25; (*a)[j] = a_alt; (*b)[j] = b_alt; multiplier /= 5; } mprintf("%15.10f %15.10f %15.5f %15.5f ", (*a)[j]*ps_corr,(*b)[j]*ps_corr,1/(*a)[j]/ps_corr,1/(*b)[j]/ps_corr); if ( count > 0 ) mprintf("\n"); else { mprintf("not converged!!!\n"); repeat = true; } mprintf("\n\n"); if ( repeat ) { count_start *= 100; repeat = AskYesNo(" Fitting is not converged. Retry with more steps (y/n)? [yes] ",true); mprintf("\n\n"); } } } double CLuzarCorrelation::GetRMS(double a, double b, CxDoubleArray* c, CxDoubleArray* n, CxDoubleArray* k, int trunc) { double RMS = 0.0; int i; for ( i=trunc; iGetSize(); i++ ) { RMS += pow2((a * c->GetAt(i) - b * n->GetAt(i) + k->GetAt(i))); } return sqrt( RMS / (k->GetSize()-trunc) ); } travis-src-190101/src/luzar.h0100777000000000000000000000340313412725651012745 0ustar00/***************************************************************************** TRAVIS - Trajectory Analyzer and Visualizer http://www.travis-analyzer.de/ Copyright (c) 2009-2019 Martin Brehm 2012-2019 Martin Thomas 2016-2019 Sascha Gehrke This file was written by Sascha Gehrke. --------------------------------------------------------------------------- This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . *****************************************************************************/ #ifndef LUZAR_H #define LUZAR_H // This must always be the first include directive #include "config.h" #include "moltools.h" class CLuzarCorrelation : public CxObject { public: CLuzarCorrelation(); ~CLuzarCorrelation(); void Init(int, int); void Correlate(CxDoubleArray*, CxDoubleArray*, CxDoubleArray*, CxDoubleArray*); int CalcSize(int); double GetRMS(double, double, CxDoubleArray*, CxDoubleArray*, CxDoubleArray*, int); void Fit(CxDoubleArray*, CxDoubleArray*, CxDoubleArray*, CxDoubleArray*, CxDoubleArray*, int); int m_iInput; int m_iDepth; int m_iFFTSize; CFFT *m_pFFT; CFFT *m_pFFT2; CFFT *m_pFFTback; }; #endif travis-src-190101/src/lu_decomp.cpp0100777000000000000000000001230713412725621014112 0ustar00/***************************************************************************** TRAVIS - Trajectory Analyzer and Visualizer http://www.travis-analyzer.de/ Copyright (c) 2009-2019 Martin Brehm 2012-2019 Martin Thomas 2016-2019 Sascha Gehrke This file was written by Martin Brehm. --------------------------------------------------------------------------- This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . *****************************************************************************/ #include "config.h" #include "lu_decomp.h" #include #include "tools.h" const char *GetRevisionInfo_lu_decomp(unsigned int len) { static char buf[256]; GET_REVISION_INFO( buf, len ); return buf; } const char *GetSourceVersion_lu_decomp() { static char buf[256]; GET_SOURCE_VERSION( buf ); return buf; } #define TINY 1.0e-20 // A small number. void ludcmp(double **a, int n, int *indx, double *d) /* Given a matrix a[1..n][1..n], this routine replaces it by the LU decomposition of a rowwise permutation of itself. a and n are input. a is output, arranged as in equation (2.3.14) above; indx[1..n] is an output vector that records the row permutation effected by the partial pivoting; d is output as 1 depending on whether the number of row interchanges was even or odd, respectively. This routine is used in combination with lubksb to solve linear equations or invert a matrix. */ { int i,imax,j,k; double big,dum,sum,temp; double *vv; // vv stores the implicit scaling of each row. imax = -1; // Avoid compiler warning vv=new double[n+1]; *d=1.0; // No row interchanges yet. for (i=1;i<=n;i++) { // Loop over rows to get the implicit scaling information. big=0.0; for (j=1;j<=n;j++) if ((temp=fabs(a[i][j])) > big) big=temp; if (big == 0.0) { eprintf("Singular matrix in routine ludcmp."); abort(); } // No nonzero largest element. vv[i]=1.0/big; // Save the scaling. } for (j=1;j<=n;j++) { // This is the loop over columns of Crouts method. for (i=1;i= big) { // Is the figure of merit for the pivot better than the best so far? big=dum; imax=i; } } if (j != imax) { // Do we need to interchange rows? for (k=1;k<=n;k++) { // Yes, do so... dum=a[imax][k]; a[imax][k]=a[j][k]; a[j][k]=dum; } *d = -(*d); // ...and change the parity of d. vv[imax]=vv[j]; // Also interchange the scale factor. } indx[j]=imax; if (a[j][j] == 0.0) a[j][j]=TINY; // If the pivot element is zero the matrix is singular (at least to the precision of the // algorithm). For some applications on singular matrices, it is desirable to substitute // TINY for zero. if (j != n) { // Now, finally, divide by the pivot element. dum=1.0/(a[j][j]); for (i=j+1;i<=n;i++) a[i][j] *= dum; } } // Go back for the next column in the reduction. delete[] vv; } void lubksb(double **a, int n, int *indx, double b[]) /* Solves the set of n linear equations AX = B. Here a[1..n][1..n] is input, not as the matrix A but rather as its LU decomposition, determined by the routine ludcmp. indx[1..n] is input as the permutation vector returned by ludcmp. b[1..n] is input as the right-hand side vector B, and returns with the solution vector X. a, n, and indx are not modified by this routine and can be left in place for successive calls with different right-hand sides b. This routine takes into account the possibility that b will begin with many zero elements, so it is efficient for use in matrix inversion. */ { int i,ii=0,ip,j; double sum; for (i=1;i<=n;i++) { // When ii is set to a positive value, it will become the // index of the first nonvanishing element of b. We now // do the forward substitution, equation (2.3.6). The // only new wrinkle is to unscramble the permutation // as we go. ip=indx[i]; sum=b[ip]; b[ip]=b[i]; if (ii) for (j=ii;j<=i-1;j++) sum -= a[i][j]*b[j]; else if (sum) ii=i; // A nonzero element was encountered, so from now on we will have to do the sums in the loop above. b[i]=sum; } for (i=n;i>=1;i--) { // Now we do the backsubstitution, equation (2.3.7). sum=b[i]; for (j=i+1;j<=n;j++) sum -= a[i][j]*b[j]; b[i]=sum/a[i][i]; // Store a component of the solution vector X. } // All done! } travis-src-190101/src/lu_decomp.h0100777000000000000000000000255213412725653013565 0ustar00/***************************************************************************** TRAVIS - Trajectory Analyzer and Visualizer http://www.travis-analyzer.de/ Copyright (c) 2009-2019 Martin Brehm 2012-2019 Martin Thomas 2016-2019 Sascha Gehrke This file was written by Martin Brehm. --------------------------------------------------------------------------- This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . *****************************************************************************/ #ifndef LU_DECOMP_H #define LU_DECOMP_H // This must always be the first include directive #include "config.h" void ludcmp(double **a, int n, int *indx, double *d); void lubksb(double **a, int n, int *indx, double b[]); #endif travis-src-190101/src/maintools.cpp0100777000000000000000000072306513412725633014165 0ustar00/***************************************************************************** TRAVIS - Trajectory Analyzer and Visualizer http://www.travis-analyzer.de/ Copyright (c) 2009-2019 Martin Brehm 2012-2019 Martin Thomas 2016-2019 Sascha Gehrke This file was written by Martin Brehm and Martin Thomas. --------------------------------------------------------------------------- This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . *****************************************************************************/ // This must always be the first include directive #include "config.h" #include "maintools.h" #include "conversion.h" #include "globalvar.h" #include "interface.h" #include "bicgstab.h" #ifdef TARGET_LINUX #include #endif #ifdef TARGET_WINDOWS #include #endif const char *GetRevisionInfo_maintools(unsigned int len) { static char buf[256]; GET_REVISION_INFO( buf, len ); return buf; } const char *GetSourceVersion_maintools() { static char buf[256]; GET_SOURCE_VERSION( buf ); return buf; } bool OpenInputTrajectory() { if (g_bVerbose) mprintf(">>> OpenInputTrajectory() >>>\n"); if (g_iTrajFormat == 7) { if (g_pBQBFile == NULL) { g_pBQBFile = new CBQBFile(*g_pBQBInterface); //g_pBQBEngine = new CBQBEngine(); //g_pBQBEngine->PrepareDecompressCube(false); if (g_bVerbose) { mprintf("\nSwitching on BQB verbosity.\n\n"); g_pBQBInterface->SetPrintLevel(BQB_PL_DEBUG); } //SetBQBVerbose(g_bVerbose); if (!g_pBQBFile->OpenRead(g_sInputTraj)) { eprintf("Error: Could not open BQB file \"%s\".\n",g_sInputTraj); return false; } } else { if (!g_pBQBFile->Rewind()) return false; } } else { g_fPos = fopen(g_sInputTraj,"rb"); if (g_fPos == NULL) { eprintf("\nError: Could not open position trajectory \"%s\" for reading.\n",g_sInputTraj); return false; } } if (g_bVerbose) mprintf("<<< OpenInputTrajectory() <<<\n"); return true; } bool CloseInputTrajectory() { if (g_bVerbose) mprintf(">>> CloseInputTrajectory() >>>\n"); if (g_iTrajFormat == 7) { } else { if (g_fPos == NULL) { eprintf("\nCloseInputTrajectory(): Error: File pointer is NULL.\n"); return false; } fclose(g_fPos); g_fPos = NULL; } if (g_bVerbose) mprintf("<<< CloseInputTrajectory() <<<\n"); return true; } bool InputTrajectoryEOF() { if (g_iTrajFormat == 7) return g_pBQBFile->IsEOF(); if (g_fPos == NULL) { eprintf("\nInputTrajectoryEOF(): Error: File pointer is NULL.\n"); return true; } return (feof(g_fPos) != 0); } bool SeekInputTrajectory(int step) { if (g_bVerbose) mprintf(">>> SeekInputTrajectory() >>>\n"); if (g_iTrajFormat == 7) { eprintf("Error: SeekInputTrajectory() not yet implemented for BQB files.\n"); abort(); } else { if (g_fPos == NULL) { eprintf("\nSeekInputTrajectory(): Error: File pointer is NULL.\n"); return false; } if (step == g_iBeginStep) fseek(g_fPos,g_iFastForwardPos,SEEK_SET); else { eprintf("\nSeekInputTrajectory(): Error: Seek only supported for g_iBeginStep.\n"); return false; } } if (g_bVerbose) mprintf("<<< SeekInputTrajectory() <<<\n"); return true; } CAnalysisGroup* AddAnalysisGroup(const char *name) { BTIN; CAnalysisGroup *g; try { g = new CAnalysisGroup(); } catch(...) { g = NULL; } if (g == NULL) NewException((double)sizeof(CAnalysisGroup),__FILE__,__LINE__,__PRETTY_FUNCTION__); try { g->m_sGroupName = new char[strlen(name)+1]; } catch(...) { g->m_sGroupName = NULL; } if (g->m_sGroupName == NULL) NewException((double)(strlen(name)+1)*sizeof(char),__FILE__,__LINE__,__PRETTY_FUNCTION__); strcpy(g->m_sGroupName,name); g_oaAnalysisGroups.Add(g); BTOUT; return g; } void AddAnalysis(CAnalysisGroup* g, const char *name, const char *abbrev) { BTIN; CAnalysis *a; try { a = new CAnalysis(); } catch(...) { a = NULL; } if (a == NULL) NewException((double)sizeof(CAnalysis),__FILE__,__LINE__,__PRETTY_FUNCTION__); try { a->m_sName = new char[strlen(name)+1]; } catch(...) { a->m_sName = NULL; } if (a->m_sName == NULL) NewException((double)(strlen(name)+1)*sizeof(char),__FILE__,__LINE__,__PRETTY_FUNCTION__); try { a->m_sAbbrev = new char[strlen(abbrev)+1]; } catch(...) { a->m_sAbbrev = NULL; } if (a->m_sAbbrev == NULL) NewException((double)(strlen(abbrev)+1)*sizeof(char),__FILE__,__LINE__,__PRETTY_FUNCTION__); strcpy(a->m_sName,name); strcpy(a->m_sAbbrev,abbrev); g_oaAnalyses.Add(a); g->m_oaAnalyses.Add(a); BTOUT; } void InitAnalyses() { BTIN; CAnalysisGroup *g; /**********************************************************************/ g = AddAnalysisGroup("Static (time independent) Functions"); AddAnalysis(g,"Combined Distribution Function","cdf"); AddAnalysis(g,"Radial Distribution Function","rdf"); AddAnalysis(g,"Angular Distribution Function","adf"); AddAnalysis(g,"Dihedral Distribution Function","ddf"); AddAnalysis(g,"Point-Plane Distance Distribution","pldf"); AddAnalysis(g,"Point-Line Distance Distribution","lidf"); AddAnalysis(g,"Plane Projection Distribution","plproj"); AddAnalysis(g,"Fixed Plane Density Profile","dprof"); AddAnalysis(g,"Fixed Plane Projection","fpp"); AddAnalysis(g,"Density Distribution Function","dens"); AddAnalysis(g,"Spatial Distribution Function","sdf"); AddAnalysis(g,"Pseudo SDF (only 2 ref. atoms)","psdf"); AddAnalysis(g,"Dipole Distribution Function","dip"); AddAnalysis(g,"Evaluate Structural Condition","cond"); AddAnalysis(g,"Compute Structure Factor","sfac"); /**********************************************************************/ g = AddAnalysisGroup("Dynamic (time dependent) Functions"); AddAnalysis(g,"Velocity Distribution Function","vdf"); AddAnalysis(g,"Force Distribution Function","fdf"); AddAnalysis(g,"Mean Square Displacement / Diffusion Coefficients","msd"); AddAnalysis(g,"Velocity Autocorrelation Functions","acf"); AddAnalysis(g,"Vector Reorientation Dynamics","rdyn"); AddAnalysis(g,"Van Hove Correlation Function","vhcf"); AddAnalysis(g,"Aggregation Functions (DACF, DLDF, DDisp)","aggr"); AddAnalysis(g,"Hydrogen Bond Dynamics", "hbond"); AddAnalysis(g,"Diffusion Corrected Ion Pair Dynamics", "ionpair"); /**********************************************************************/ g = AddAnalysisGroup("Spectroscopic Functions"); AddAnalysis(g, "New Spectroscopy Module (IR, Raman, VCD, ROA)", "spec"); AddAnalysis(g,"Calculate Power Spectrum","power"); AddAnalysis(g, "Normal Coordinate Analysis", "nc"); AddAnalysis(g,"(old) Calculate IR Spectrum","ir"); AddAnalysis(g,"(old) Calculate Raman Spectrum","raman"); AddAnalysis(g, "(old) Calculate VCD Spectrum", "vcd"); AddAnalysis(g, "Save Dipole Restart File", "drst"); AddAnalysis(g, "Save Magnetic Moment Restart File", "mrst"); AddAnalysis(g, "Set up Polarizability Calculation", "pol"); /**********************************************************************/ g = AddAnalysisGroup("Miscellaneous Functions"); AddAnalysis(g,"Save Trajectory of RM Environment / TDO Plot","env"); AddAnalysis(g,"Save Processed Trajectory","proc"); AddAnalysis(g,"Cut Clusters","cut"); AddAnalysis(g,"Region-specific Analysis","reg"); AddAnalysis(g,"Chirality Analysis", "chi"); AddAnalysis(g,"Transform to Eckart Frame", "eck"); AddAnalysis(g,"Sort Wannier Centers", "swan"); AddAnalysis(g,"Basic Voronoi Analysis","voro"); AddAnalysis(g,"Domain Analysis","doma"); AddAnalysis(g,"Voronoi Integration Functions","vori"); AddAnalysis(g,"Order Parameters","order"); /**********************************************************************/ BTOUT; } void DumpAnalyses() { BTIN; int z, z2; CAnalysis *a; CAnalysisGroup *g; for (z=0;zm_sGroupName); for (z2=0;z2m_oaAnalyses.GetSize();z2++) { a = (CAnalysis*)g->m_oaAnalyses[z2]; mprintf(WHITE," %-8s",a->m_sAbbrev); mprintf("- %s\n",a->m_sName); } mprintf("\n"); } BTOUT; } /*void UniteNb() { BTIN; int z, z2, z3, z4; CNbSearch *nb; CxIntArray *w, *w2; if (g_pNbAll != NULL) delete g_pNbAll; g_pNbAll = new CNbSearch(); g_pNbAll->Create(); for (z=0;zm_oaScanNeighbors[z]; for (z2=0;z2m_oaScanNeighbors[z]; for (z3=0;z3m_waScanNeighborCount[z];z3++) { if (!g_bKeepNbCount) for (z4=0;z4m_waScanNeighborCount[z];z4++) { if (w->GetAt(z3) == w2->GetAt(z4)) goto _unb_found; } w2->Add(w->GetAt(z3)); g_pNbAll->m_waScanNeighborCount[z]++; _unb_found:; } } } BTOUT; }*/ bool ParseAtom(const char *s, int refmol, int &ty, int &rty, int &atom) { BTIN; CMolecule *mol; char buf[64]; const char *r, *t; int a, b; mol = (CMolecule*)g_oaMolecules[refmol]; t = s; while ((*t == ' ') && (*t != 0)) t++; r = t; while ((!isdigit(*r)) && (*r != 0)) r++; if (r-t == 0) { eprintf("ParseAtom(): Missing Atom Label for Atom.\n"); BTOUT; return false; } if (r-t >= 64) { eprintf("Internal Error in ParseAtom(): A, %ld >= 64.\n",r-t); return false; } memcpy(buf,t,r-t); buf[r-t] = 0; // printf("Label \"%s\"\n",buf); a = mol->FindAtomInMol(buf); if (a == -1) { eprintf("ParseAtom(): Atom Type \"%s\" not found in Molecule.\n",buf); BTOUT; return false; } b = atoi(r); if (b != 0) b--; if (b >= ((CMolecule*)g_oaMolecules[refmol])->m_waAtomCount[a]) { eprintf("ParseAtom(): The Molecule only has %d %s-Atoms.\n",((CMolecule*)g_oaMolecules[refmol])->m_waAtomCount[a],buf); BTOUT; return false; } // printf("ParseRefSystem: Atom 1 ist in Molekuel %d Typ %d Nummer %d.\n",refmol,a,b); ty = a; rty = ((CMolecule*)g_oaMolecules[refmol])->m_baAtomIndex[a]; atom = b; BTOUT; return true; } bool ParseRefSystem(int refmol, const char *s, int points) { BTIN; char buf[256]; char *p, *q; if (points == 1) { BTOUT; return ParseAtom(s,refmol,g_iFixAtomType[0],g_iFixRealAtomType[0],g_iFixAtom[0]); } strcpy(buf,s); if (points == 2) { p = strchr(buf,','); if (p == NULL) { eprintf("ParseRefSystem(): No comma found.\n"); BTOUT; return false; } *p = 0; p++; if (!ParseAtom(buf,refmol,g_iFixAtomType[0],g_iFixRealAtomType[0],g_iFixAtom[0])) { BTOUT; return false; } BTOUT; return ParseAtom(p,refmol,g_iFixAtomType[1],g_iFixRealAtomType[1],g_iFixAtom[1]); } if (points == 3) { p = strchr(buf,','); if (p == NULL) { eprintf("ParseRefSystem(): No comma found.\n"); BTOUT; return false; } *p = 0; p++; q = strchr(p,','); if (q == NULL) { eprintf("ParseRefSystem(): No second comma found.\n"); BTOUT; return false; } *q = 0; q++; if (!ParseAtom(buf,refmol,g_iFixAtomType[0],g_iFixRealAtomType[0],g_iFixAtom[0])) { BTOUT; return false; } if (!ParseAtom(p,refmol,g_iFixAtomType[1],g_iFixRealAtomType[1],g_iFixAtom[1])) { BTOUT; return false; } BTOUT; return ParseAtom(q,refmol,g_iFixAtomType[2],g_iFixRealAtomType[2],g_iFixAtom[2]); } BTOUT; return false; } CTimeStep* GetTimeStep(int i) { BTIN; if (g_iCurrentTimeStep != -1) { if (g_bUseVelocities || g_bUseForces) i++; if (i >= g_iStepHistory) { eprintf("GetTimeStep(): Error! Requested depth (%d) >= step history (%d).\n",i,g_iStepHistory); BTOUT; return NULL; } if (g_iCurrentTimeStep-i+g_iStepHistory < 0) { eprintf("GetTimeStep(): Error! i=%d, g_iCurrentTimeStep=%d, g_iStepHistory=%d.\n",i,g_iCurrentTimeStep,g_iStepHistory); BTOUT; return NULL; } if (g_iCurrentTimeStep-i >= 0) { BTOUT; return (CTimeStep*)g_oaTimeSteps[g_iCurrentTimeStep-i]; } else { BTOUT; return (CTimeStep*)g_oaTimeSteps[g_iCurrentTimeStep-i+g_iStepHistory]; } } else { BTOUT; return NULL; } } CTimeStep** GetTimeStepAddress(int i) { BTIN; if (g_iCurrentTimeStep != -1) { if (g_bUseVelocities || g_bUseForces) i++; if (g_iCurrentTimeStep-i >= 0) { BTOUT; return (CTimeStep**)&g_oaTimeSteps[g_iCurrentTimeStep-i]; } else { BTOUT; return (CTimeStep**)&g_oaTimeSteps[g_iCurrentTimeStep-i+g_iStepHistory]; } } else { BTOUT; return NULL; } } void CalcVelocities() { BTIN; int z, z2; unsigned long index; double v, imv, ilmv; CxDVector3 dist; CMolecule *m; CSingleMolecule *sm; CVirtualAtom *vi; g_fLMidVel = 0; imv = g_fMaxVel; ilmv = g_fLMaxVel; GetTimeStep(0)->m_vaVelocities.SetSize(g_iGesVirtAtomCount); // for (z=0;zm_vaCoords[z][0],GetTimeStep(-1)->m_vaCoords[z][0],g_fTimestepLength,(GetTimeStep(1)->m_vaCoords[z][0] - GetTimeStep(-1)->m_vaCoords[z][0]) / (2.0f*g_fTimestepLength) * 1000.0f); dist = GetTimeStep(-1)->m_vaCoords[z] - GetTimeStep(1)->m_vaCoords[z]; // mprintf(RED, "d: %d ( %12G | %12G | %12G )\n", g_waAtomElement[z], dist[0], dist[1], dist[2]); if(g_bPeriodicX) { while(dist[0] > g_fBoxX / 2.0) dist[0] -= g_fBoxX; while(dist[0] < -g_fBoxX / 2.0) dist[0] += g_fBoxX; } if(g_bPeriodicY) { while(dist[1] > g_fBoxY / 2.0) dist[1] -= g_fBoxY; while(dist[1] < -g_fBoxY / 2.0) dist[1] += g_fBoxY; } if(g_bPeriodicZ) { while(dist[2] > g_fBoxZ / 2.0) dist[2] -= g_fBoxZ; while(dist[2] < -g_fBoxZ / 2.0) dist[2] += g_fBoxZ; } GetTimeStep(0)->m_vaVelocities[z] = dist * 1000.0 / 2.0 / g_fTimestepLength / g_iStride; // mprintf(RED, "v: ( %12G | %12G | %12G )\n", GetTimeStep(0)->m_vaVelocities[z][0], GetTimeStep(0)->m_vaVelocities[z][1], GetTimeStep(0)->m_vaVelocities[z][2]); // GetTimeStep(0)->m_vaVelocities[z] = (GetTimeStep(1)->m_vaCoords[z] - GetTimeStep(-1)->m_vaCoords[z]) / (2.0f*g_fTimestepLength) * 1000.0f; v = GetTimeStep(0)->m_vaVelocities[z].GetLength(); g_fLMidVel += v; if (v > imv) imv = v; if (v > ilmv) ilmv = v; } for (z = 0; z < g_oaVirtualAtoms.GetSize(); z++) { vi = (CVirtualAtom*)g_oaVirtualAtoms[z]; m = (CMolecule*)g_oaMolecules[vi->m_iMolecule]; for (z2=0;z2m_laSingleMolIndex.GetSize();z2++) { sm = (CSingleMolecule*)g_oaSingleMolecules[m->m_laSingleMolIndex[z2]]; index = ((CxIntArray*)sm->m_oaAtomOffset[sm->m_baAtomIndex.GetSize()-1])->GetAt(vi->m_iMolVirtAtom); if (((CVirtualAtom *)g_oaVirtualAtoms[z])->m_iMode == 2) { dist = CxDVector3(0.0, 0.0, 0.0); } else { dist = GetTimeStep(-1)->m_vaCoords[index] - GetTimeStep(1)->m_vaCoords[index]; // mprintf(RED, "d: %d ( %12G | %12G | %12G )\n", g_waAtomElement[index], dist[0], dist[1], dist[2]); if(g_bPeriodicX) { while(dist[0] > g_fBoxX / 2.0) dist[0] -= g_fBoxX; while(dist[0] < -g_fBoxX / 2.0) dist[0] += g_fBoxX; } if(g_bPeriodicY) { while(dist[1] > g_fBoxY / 2.0) dist[1] -= g_fBoxY; while(dist[1] < -g_fBoxY / 2.0) dist[1] += g_fBoxY; } if(g_bPeriodicZ) { while(dist[2] > g_fBoxZ / 2.0) dist[2] -= g_fBoxZ; while(dist[2] < -g_fBoxZ / 2.0) dist[2] += g_fBoxZ; } } GetTimeStep(0)->m_vaVelocities[index] = dist * 1000.0 / 2.0 / g_fTimestepLength / g_iStride; // mprintf("\nVA[%lu/%d]: (%10g|%10g|%10g)",index,g_oaVirtualAtoms.GetSize(),GetTimeStep(0)->m_vaVelocities[index][0],GetTimeStep(0)->m_vaVelocities[index][1],GetTimeStep(0)->m_vaVelocities[index][2]); // mprintf(RED, "v: ( %12G | %12G | %12G )\n", GetTimeStep(0)->m_vaVelocities[index][0], GetTimeStep(0)->m_vaVelocities[index][1], GetTimeStep(0)->m_vaVelocities[index][2]); v = GetTimeStep(0)->m_vaVelocities[index].GetLength(); g_fLMidVel += v; if (v > imv) imv = v; if (v > ilmv) ilmv = v; } } g_fLMidVel /= g_iGesVirtAtomCount; g_fLMaxVel = ilmv; if (imv < g_fUnsteadyLimit) { g_fMaxVel = imv; } else if (!g_bWarnUnsteady) { g_bWarnUnsteady = true; mprintf("Warning: Discontinuity in time step %d (maximum velocity = %f > %f pm/ps).\n",(int)g_iSteps,imv,g_fUnsteadyLimit); } BTOUT; } void CalcVolumetricDataTimeDev() { if (GetTimeStep(0)->m_pVolumetricDataTimeDev == NULL) return; if (GetTimeStep(0)->m_pVolumetricDataTimeDev->m_pBin == NULL) { GetTimeStep(0)->m_pVolumetricDataTimeDev->m_iRes[0] = GetTimeStep(0)->m_pVolumetricData->m_iRes[0]; GetTimeStep(0)->m_pVolumetricDataTimeDev->m_iRes[1] = GetTimeStep(0)->m_pVolumetricData->m_iRes[1]; GetTimeStep(0)->m_pVolumetricDataTimeDev->m_iRes[2] = GetTimeStep(0)->m_pVolumetricData->m_iRes[2]; GetTimeStep(0)->m_pVolumetricDataTimeDev->m_fMinVal[0] = GetTimeStep(0)->m_pVolumetricData->m_fMinVal[0]; GetTimeStep(0)->m_pVolumetricDataTimeDev->m_fMaxVal[0] = GetTimeStep(0)->m_pVolumetricData->m_fMaxVal[0]; GetTimeStep(0)->m_pVolumetricDataTimeDev->m_fMinVal[1] = GetTimeStep(0)->m_pVolumetricData->m_fMinVal[1]; GetTimeStep(0)->m_pVolumetricDataTimeDev->m_fMaxVal[1] = GetTimeStep(0)->m_pVolumetricData->m_fMaxVal[1]; GetTimeStep(0)->m_pVolumetricDataTimeDev->m_fMinVal[2] = GetTimeStep(0)->m_pVolumetricData->m_fMinVal[2]; GetTimeStep(0)->m_pVolumetricDataTimeDev->m_fMaxVal[2] = GetTimeStep(0)->m_pVolumetricData->m_fMaxVal[2]; GetTimeStep(0)->m_pVolumetricDataTimeDev->Create(); } int i; double integral = 0.0; int timedevSize = 0; for (i = 0; i < GetTimeStep(0)->m_pVolumetricData->m_iRes[0] * GetTimeStep(0)->m_pVolumetricData->m_iRes[1] * GetTimeStep(0)->m_pVolumetricData->m_iRes[2]; i++) { if (fabs(GetTimeStep(0)->m_pVolumetricData->m_pBin[i]) > -1.0e-20) { GetTimeStep(0)->m_pVolumetricDataTimeDev->m_pBin[i] = (GetTimeStep(-1)->m_pVolumetricData->m_pBin[i] - GetTimeStep(1)->m_pVolumetricData->m_pBin[i]) / (2.0 * g_fTimestepLength); integral += GetTimeStep(0)->m_pVolumetricDataTimeDev->m_pBin[i]; timedevSize++; } else { GetTimeStep(0)->m_pVolumetricDataTimeDev->m_pBin[i] = 0.0; } } // mprintf(GREEN, "%g %g\n", integral, integral / timedevSize); for (i = 0; i < GetTimeStep(0)->m_pVolumetricDataTimeDev->m_iRes[0] * GetTimeStep(0)->m_pVolumetricDataTimeDev->m_iRes[1] * GetTimeStep(0)->m_pVolumetricDataTimeDev->m_iRes[2]; i++) { if (fabs(GetTimeStep(0)->m_pVolumetricData->m_pBin[i]) > -1.0e-20) { GetTimeStep(0)->m_pVolumetricDataTimeDev->m_pBin[i] -= integral / timedevSize; } } // integral = 0.0; // for (i = 0; i < GetTimeStep(0)->m_pVolumetricDataTimeDev->m_iRes[0] * GetTimeStep(0)->m_pVolumetricDataTimeDev->m_iRes[1] * GetTimeStep(0)->m_pVolumetricDataTimeDev->m_iRes[2]; i++) { // integral += GetTimeStep(0)->m_pVolumetricDataTimeDev->m_pBin[i]; // } // mprintf(GREEN, "%g\n", integral); // mprintf(GREEN, "%#20.10g %#20.10g %#20.10g %#20.10g\n", GetTimeStep(-1)->m_pVolumetricData->m_pBin[10], GetTimeStep(0)->m_pVolumetricData->m_pBin[10], GetTimeStep(1)->m_pVolumetricData->m_pBin[10], GetTimeStep(0)->m_pVolumetricDataTimeDev->m_pBin[10]); // FILE *cubeFile = fopen("test.cube", "w"); // if (cubeFile == NULL) { // printf("Could not open output file!\n"); // abort(); // } // // fprintf(cubeFile, "\n\n"); // fprintf(cubeFile, "%5lu %12.6f %12.6f %12.6f\n", GetTimeStep(0)->m_iGesAtomCount, 0.0f, 0.0f, 0.0f); // fprintf(cubeFile, "%5d %12.6f %12.6f %12.6f\n", GetTimeStep(0)->m_pVolumetricDataTimeDev->m_iRes[0], g_fCubeXStep, 0.0f, 0.0f); // fprintf(cubeFile, "%5d %12.6f %12.6f %12.6f\n", GetTimeStep(0)->m_pVolumetricDataTimeDev->m_iRes[1], 0.0f, g_fCubeYStep, 0.0f); // fprintf(cubeFile, "%5d %12.6f %12.6f %12.6f\n", GetTimeStep(0)->m_pVolumetricDataTimeDev->m_iRes[2], 0.0f, 0.0f, g_fCubeZStep); // for (int i = 0; i < (int)GetTimeStep(0)->m_iGesAtomCount; i++) { // fprintf(cubeFile, "%5d %12.6f %12.6f %12.6f %12.6f\n", 1, 0.0f, GetTimeStep(0)->m_vaCoords[i][0] / 0.529177249f / 100.0f, GetTimeStep(0)->m_vaCoords[i][1] / 0.529177249f / 100.0f, GetTimeStep(0)->m_vaCoords[i][2] / 0.529177249f / 100.0f); // } // for (int i = 0; i < GetTimeStep(0)->m_pVolumetricDataTimeDev->m_iRes[0]; i++) { // for (int j = 0; j < GetTimeStep(0)->m_pVolumetricDataTimeDev->m_iRes[1]; j++) { // for (int k = 0; k < GetTimeStep(0)->m_pVolumetricDataTimeDev->m_iRes[2] / 6; k++) { // for (int l = 0; l < 6; l++) { // fprintf(cubeFile, "%13.5E", GetTimeStep(0)->m_pVolumetricDataTimeDev->m_pBin[i + j * GetTimeStep(0)->m_pVolumetricDataTimeDev->m_iRes[0] + (k * 6 + l) * GetTimeStep(0)->m_pVolumetricDataTimeDev->m_iRes[0] * GetTimeStep(0)->m_pVolumetricDataTimeDev->m_iRes[1]]); // } // fprintf(cubeFile, "\n"); // } // if (GetTimeStep(0)->m_pVolumetricDataTimeDev->m_iRes[2] % 6 != 0) { // for (int l = 0; l < GetTimeStep(0)->m_pVolumetricDataTimeDev->m_iRes[2] % 6; l++) { // fprintf(cubeFile, "%13.5E", GetTimeStep(0)->m_pVolumetricDataTimeDev->m_pBin[i + j * GetTimeStep(0)->m_pVolumetricDataTimeDev->m_iRes[0] + ((GetTimeStep(0)->m_pVolumetricDataTimeDev->m_iRes[2] / 6) * 6 + l) * GetTimeStep(0)->m_pVolumetricDataTimeDev->m_iRes[0] * GetTimeStep(0)->m_pVolumetricDataTimeDev->m_iRes[1]]); // } // fprintf(cubeFile, "\n"); // } // } // } // // fclose(cubeFile); } void CalcCurrentDensity() { int res[3]; res[0] = GetTimeStep(0)->m_pVolumetricDataTimeDev->m_iRes[0]; res[1] = GetTimeStep(0)->m_pVolumetricDataTimeDev->m_iRes[1]; res[2] = GetTimeStep(0)->m_pVolumetricDataTimeDev->m_iRes[2]; C3DF density; density.CopyFrom(GetTimeStep(0)->m_pVolumetricData); C3DF densityGradient[3]; int i; for (i = 0; i < 3; i++) { densityGradient[i].m_iRes[0] = density.m_iRes[0]; densityGradient[i].m_iRes[1] = density.m_iRes[1]; densityGradient[i].m_iRes[2] = density.m_iRes[2]; densityGradient[i].m_fMinVal[0] = density.m_fMinVal[0]; densityGradient[i].m_fMaxVal[0] = density.m_fMaxVal[0]; densityGradient[i].m_fMinVal[1] = density.m_fMinVal[1]; densityGradient[i].m_fMaxVal[1] = density.m_fMaxVal[1]; densityGradient[i].m_fMinVal[2] = density.m_fMinVal[2]; densityGradient[i].m_fMaxVal[2] = density.m_fMaxVal[2]; densityGradient[i].Create(); } for (i = 0; i < res[2]; i++) { int j; for (j = 0; j < res[1]; j++) { int k; for (k = 1; k < res[0] - 1; k++) { densityGradient[0].m_pBin[i * res[0] * res[1] + j * res[0] + k] = (density.m_pBin[i * res[0] * res[1] + j * res[0] + k + 1] - density.m_pBin[i * res[0] * res[1] + j * res[0] + k - 1]) / (2.0 * g_fCubeXStep); } densityGradient[0].m_pBin[i * res[0] * res[1] + j * res[0]] = (density.m_pBin[i * res[0] * res[1] + j * res[0] + 1] - density.m_pBin[i * res[0] * res[1] + j * res[0] + res[0] - 1]) / (2.0 * g_fCubeXStep); densityGradient[0].m_pBin[i * res[0] * res[1] + j * res[0] + res[0] - 1] = (density.m_pBin[i * res[0] * res[1] + j * res[0]] - density.m_pBin[i * res[0] * res[1] + j * res[0] + res[0] - 2]) / (2.0 * g_fCubeXStep); } } for (i = 0; i < res[2]; i++) { int j; for (j = 1; j < res[1] - 1; j++) { int k; for (k = 0; k < res[0]; k++) { densityGradient[1].m_pBin[i * res[0] * res[1] + j * res[0] + k] = (density.m_pBin[i * res[0] * res[1] + (j + 1) * res[0] + k] - density.m_pBin[i * res[0] * res[1] + (j - 1) * res[0] + k]) / (2.0 * g_fCubeYStep); } } int k; for (k = 0; k < res[0]; k++) { densityGradient[1].m_pBin[i * res[0] * res[1] + k] = (density.m_pBin[i * res[0] * res[1] + res[0] + k] - density.m_pBin[i * res[0] * res[1] + (res[1] - 1) * res[0] + k]) / (2.0 * g_fCubeYStep); densityGradient[1].m_pBin[i * res[0] * res[1] + (res[1] - 1) * res[0] + k] = (density.m_pBin[i * res[0] * res[1] + k] - density.m_pBin[i * res[0] * res[1] + (res[1] - 2) * res[0] + k]) / (2.0 * g_fCubeYStep); } } for (i = 1; i < res[2] - 1; i++) { int j; for (j = 0; j < res[1]; j++) { int k; for (k = 0; k < res[0]; k++) { densityGradient[2].m_pBin[i * res[0] * res[1] + j * res[0] + k] = (density.m_pBin[(i + 1) * res[0] * res[1] + j * res[0] + k] - density.m_pBin[(i - 1) * res[0] * res[1] + j * res[0] + k]) / (2.0 * g_fCubeZStep); } } } int j; for (j = 0; j < res[1]; j++) { int k; for (k = 0; k < res[0]; k++) { densityGradient[2].m_pBin[j * res[0] + k] = (density.m_pBin[res[0] * res[1] + j * res[0] + k] - density.m_pBin[(res[2] - 1) * res[0] * res[1] + j * res[0] + k]) / (2.0 * g_fCubeZStep); densityGradient[2].m_pBin[(res[2] - 1) * res[0] * res[1] + j * res[0] + k] = (density.m_pBin[j * res[0] + k] - density.m_pBin[(res[2] - 2) * res[0] * res[1] + j * res[0] + k]) / (2.0 * g_fCubeZStep); } } // mprintf(GREEN, "%#.10g %#.10g %#.10g %#.10g\n", density.m_pBin[1942857], densityGradient[0].m_pBin[1942857], densityGradient[1].m_pBin[1942857], densityGradient[2].m_pBin[1942857]); // FILE *cubeFile2 = fopen("test2.cube", "w"); // if (cubeFile2 == NULL) { // printf("Could not open output file!\n"); // abort(); // } // // fprintf(cubeFile2, "\n\n"); // fprintf(cubeFile2, "%5lu %12.6f %12.6f %12.6f\n", GetTimeStep(0)->m_iGesAtomCount, 0.0f, 0.0f, 0.0f); // fprintf(cubeFile2, "%5d %12.6f %12.6f %12.6f\n", GetTimeStep(0)->m_pVolumetricDataTimeDev->m_iRes[0], g_fCubeXStep, 0.0f, 0.0f); // fprintf(cubeFile2, "%5d %12.6f %12.6f %12.6f\n", GetTimeStep(0)->m_pVolumetricDataTimeDev->m_iRes[1], 0.0f, g_fCubeYStep, 0.0f); // fprintf(cubeFile2, "%5d %12.6f %12.6f %12.6f\n", GetTimeStep(0)->m_pVolumetricDataTimeDev->m_iRes[2], 0.0f, 0.0f, g_fCubeZStep); // for (int i = 0; i < (int)GetTimeStep(0)->m_iGesAtomCount; i++) { // fprintf(cubeFile2, "%5d %12.6f %12.6f %12.6f %12.6f\n", 1, 0.0f, GetTimeStep(0)->m_vaCoords[i][0] / 0.529177249f / 100.0f, GetTimeStep(0)->m_vaCoords[i][1] / 0.529177249f / 100.0f, GetTimeStep(0)->m_vaCoords[i][2] / 0.529177249f / 100.0f); // } // for (int i = 0; i < GetTimeStep(0)->m_pVolumetricDataTimeDev->m_iRes[0]; i++) { // for (int j = 0; j < GetTimeStep(0)->m_pVolumetricDataTimeDev->m_iRes[1]; j++) { // for (int k = 0; k < GetTimeStep(0)->m_pVolumetricDataTimeDev->m_iRes[2] / 6; k++) { // for (int l = 0; l < 6; l++) { // fprintf(cubeFile2, "%13.5E", densityGradient[2].m_pBin[i + j * GetTimeStep(0)->m_pVolumetricDataTimeDev->m_iRes[0] + (k * 6 + l) * GetTimeStep(0)->m_pVolumetricDataTimeDev->m_iRes[0] * GetTimeStep(0)->m_pVolumetricDataTimeDev->m_iRes[1]]); // } // fprintf(cubeFile2, "\n"); // } // if (GetTimeStep(0)->m_pVolumetricDataTimeDev->m_iRes[2] % 6 != 0) { // for (int l = 0; l < GetTimeStep(0)->m_pVolumetricDataTimeDev->m_iRes[2] % 6; l++) { // fprintf(cubeFile2, "%13.5E", densityGradient[2].m_pBin[i + j * GetTimeStep(0)->m_pVolumetricDataTimeDev->m_iRes[0] + ((GetTimeStep(0)->m_pVolumetricDataTimeDev->m_iRes[2] / 6) * 6 + l) * GetTimeStep(0)->m_pVolumetricDataTimeDev->m_iRes[0] * GetTimeStep(0)->m_pVolumetricDataTimeDev->m_iRes[1]]); // } // fprintf(cubeFile2, "\n"); // } // } // } // // fclose(cubeFile2); // CSparseMatrix testMatrix; // testMatrix.setTest(); // double solution[9]; // for (int i = 0; i < 9; i++) // solution[i] = 0.0; // double rhs[9]; // rhs[0] = 1.0; // rhs[1] = 2.0; // rhs[2] = 1.0; // rhs[3] = 2.0; // rhs[4] = 1.0; // rhs[5] = 2.0; // rhs[6] = 1.0; // rhs[7] = 2.0; // rhs[8] = 1.0; // // CCurrentPDESolver::bicgstabl(4, &testMatrix, solution, rhs, 100, 1e-10, stdout); // // return; for (i = 0; i < res[0] * res[1] * res[2]; i++) { density.m_pBin[i] += g_fBackgroundDensity; } CSparseMatrix pdeMatrix; CCurrentPDEDiscretizer::discretize(&pdeMatrix, density, densityGradient[0], densityGradient[1], densityGradient[2]); static double *pdeSolution = NULL; if (pdeSolution == NULL) { try { pdeSolution = new double[res[0] * res[1] * res[2]]; } catch(...) { pdeSolution = NULL; } if (pdeSolution == NULL) NewException((double)res[0] * res[1] * res[2] * sizeof(double), __FILE__, __LINE__, __PRETTY_FUNCTION__); memset(pdeSolution, 0, res[0] * res[1] * res[2] * sizeof(double)); } static bool first = true; static double thresh; if (first) { memset(pdeSolution, 0, res[0] * res[1] * res[2] * sizeof(double)); thresh = g_fPDEConvThresh * CCurrentPDESolver::calcResidual(&pdeMatrix, pdeSolution, GetTimeStep(0)->m_pVolumetricDataTimeDev->m_pBin); first = false; } if (g_fPDESolverInfoFile != NULL) { fprintf(g_fPDESolverInfoFile, "Step %lu\n", g_iSteps - 1); } double thresh2 = thresh; if (!CCurrentPDESolver::bicgstabl(4, &pdeMatrix, pdeSolution, GetTimeStep(0)->m_pVolumetricDataTimeDev->m_pBin, g_iPDEMaxIter, &thresh2, g_fPDESolverInfoFile)) { memset(pdeSolution, 0, res[0] * res[1] * res[2] * sizeof(double)); if (g_fPDESolverInfoFile != NULL) { fprintf(g_fPDESolverInfoFile, "Resetting solution guess\n"); } thresh2 = thresh; if (!CCurrentPDESolver::bicgstabl(4, &pdeMatrix, pdeSolution, GetTimeStep(0)->m_pVolumetricDataTimeDev->m_pBin, g_iPDEMaxIter, &thresh2, g_fPDESolverInfoFile)) { memset(pdeSolution, 0, res[0] * res[1] * res[2] * sizeof(double)); if (g_fPDESolverInfoFile != NULL) { fprintf(g_fPDESolverInfoFile, "Trying different threshold\n"); } thresh2 *= 1.05; if (!CCurrentPDESolver::bicgstabl(4, &pdeMatrix, pdeSolution, GetTimeStep(0)->m_pVolumetricDataTimeDev->m_pBin, g_iPDEMaxIter, &thresh2, g_fPDESolverInfoFile)) { memset(pdeSolution, 0, res[0] * res[1] * res[2] * sizeof(double)); if (g_fPDESolverInfoFile != NULL) { fprintf(g_fPDESolverInfoFile, "Severe convergence problem! Resetting solution guess\n"); } } } } if (g_fPDESolverInfoFile != NULL) { fprintf(g_fPDESolverInfoFile, "\n"); } GetTimeStep(0)->m_pCurrentDensity->SetSize(3 * res[0] * res[1] * res[2]); // fftwf_complex *fft_data; // fft_data = fftwf_alloc_complex(res[0] * res[1] * res[2]); // fftwf_plan plan1, plan2; // plan1 = fftwf_plan_dft_3d(res[2], res[1], res[0], fft_data, fft_data, FFTW_FORWARD, FFTW_MEASURE); // plan2 = fftwf_plan_dft_3d(res[2], res[1], res[0], fft_data, fft_data, FFTW_BACKWARD, FFTW_MEASURE); // // int i; // for (i = 0; i < res[0] * res[1] * res[2]; i++) { // fft_data[i][0] = GetTimeStep(0)->m_pVolumetricDataTimeDev->m_pBin[i]; // fft_data[i][1] = 0.0f; // } // fftwf_execute(plan1); // for (i = 0; i < res[2]; i++) { // int j; // for (j = 0; j < res[1]; j++) { // int k; // for (k = 0; k < res[0]; k++) { // if (i == 0 && j == 0 && k == 0) { // fft_data[i * res[1] * res[0] + j * res[0] + k][0] = 0.0f; // fft_data[i * res[1] * res[0] + j * res[0] + k][1] = 0.0f; // continue; // } // double f = (2.0f * cos(2.0f * (double)Pi / res[2] * i) - 2.0) / g_fCubeXStep / g_fCubeXStep + (2.0f * cos(2.0f * (double)Pi / res[1] * j) - 2.0f) / g_fCubeYStep / g_fCubeYStep + (2.0f * cos(2.0f * (double)Pi / res[0] * k) - 2.0f) / g_fCubeZStep / g_fCubeZStep; // fft_data[i * res[1] * res[0] + j * res[0] + k][0] /= f; // fft_data[i * res[1] * res[0] + j * res[0] + k][1] /= f; // } // } // } // fftwf_execute(plan2); // for (i = 0; i < res[0] * res[1] * res[2]; i++) { // fft_data[i][0] /= res[0] * res[1] * res[2]; // fft_data[i][1] /= res[0] * res[1] * res[2]; // } // FILE *cubeFile2 = fopen("test2.cube", "w"); // if (cubeFile2 == NULL) { // printf("Could not open output file!\n"); // abort(); // } // // fprintf(cubeFile2, "\n\n"); // fprintf(cubeFile2, "%5lu %12.6f %12.6f %12.6f\n", GetTimeStep(0)->m_iGesAtomCount, 0.0f, 0.0f, 0.0f); // fprintf(cubeFile2, "%5d %12.6f %12.6f %12.6f\n", GetTimeStep(0)->m_pVolumetricDataTimeDev->m_iRes[0], g_fCubeXStep, 0.0f, 0.0f); // fprintf(cubeFile2, "%5d %12.6f %12.6f %12.6f\n", GetTimeStep(0)->m_pVolumetricDataTimeDev->m_iRes[1], 0.0f, g_fCubeYStep, 0.0f); // fprintf(cubeFile2, "%5d %12.6f %12.6f %12.6f\n", GetTimeStep(0)->m_pVolumetricDataTimeDev->m_iRes[2], 0.0f, 0.0f, g_fCubeZStep); // for (int i = 0; i < (int)GetTimeStep(0)->m_iGesAtomCount; i++) { // fprintf(cubeFile2, "%5d %12.6f %12.6f %12.6f %12.6f\n", 1, 0.0f, GetTimeStep(0)->m_vaCoords[i][0] / 0.529177249f / 100.0f, GetTimeStep(0)->m_vaCoords[i][1] / 0.529177249f / 100.0f, GetTimeStep(0)->m_vaCoords[i][2] / 0.529177249f / 100.0f); // } // for (int i = 0; i < GetTimeStep(0)->m_pVolumetricDataTimeDev->m_iRes[0]; i++) { // for (int j = 0; j < GetTimeStep(0)->m_pVolumetricDataTimeDev->m_iRes[1]; j++) { // for (int k = 0; k < GetTimeStep(0)->m_pVolumetricDataTimeDev->m_iRes[2] / 6; k++) { // for (int l = 0; l < 6; l++) { // fprintf(cubeFile2, "%13.5E", fft_data[i + j * GetTimeStep(0)->m_pVolumetricDataTimeDev->m_iRes[0] + (k * 6 + l) * GetTimeStep(0)->m_pVolumetricDataTimeDev->m_iRes[0] * GetTimeStep(0)->m_pVolumetricDataTimeDev->m_iRes[1]][0]); // } // fprintf(cubeFile2, "\n"); // } // if (GetTimeStep(0)->m_pVolumetricDataTimeDev->m_iRes[2] % 6 != 0) { // for (int l = 0; l < GetTimeStep(0)->m_pVolumetricDataTimeDev->m_iRes[2] % 6; l++) { // fprintf(cubeFile2, "%13.5E", fft_data[i + j * GetTimeStep(0)->m_pVolumetricDataTimeDev->m_iRes[0] + ((GetTimeStep(0)->m_pVolumetricDataTimeDev->m_iRes[2] / 6) * 6 + l) * GetTimeStep(0)->m_pVolumetricDataTimeDev->m_iRes[0] * GetTimeStep(0)->m_pVolumetricDataTimeDev->m_iRes[1]][0]); // } // fprintf(cubeFile2, "\n"); // } // } // } // // fclose(cubeFile2); // // FILE *testFile2 = fopen("test2.dat", "w"); // if (testFile2 == NULL) { // printf("Could not open output file!\n"); // abort(); // } // // for (int i = 0; i < GetTimeStep(0)->m_pVolumetricDataTimeDev->m_iRes[0]; i++) { // for (int j = 0; j < GetTimeStep(0)->m_pVolumetricDataTimeDev->m_iRes[1]; j++) { // fprintf(testFile2, "%.6f %.6f %.14f\n", i * g_fCubeXStep, j * g_fCubeYStep, fft_data[i + j * GetTimeStep(0)->m_pVolumetricDataTimeDev->m_iRes[0] + GetTimeStep(0)->m_pVolumetricDataTimeDev->m_iRes[2] / 2 * GetTimeStep(0)->m_pVolumetricDataTimeDev->m_iRes[1] * GetTimeStep(0)->m_pVolumetricDataTimeDev->m_iRes[0]][0]); // } // fprintf(testFile2, "\n"); // } // // fclose(testFile2); // for (i = 0; i < res[2]; i++) { // int j; // for (j = 0; j < res[1]; j++) { // int k; // for (k = 1; k < res[0] - 1; k++) { // GetTimeStep(0)->m_pCurrentDensity->GetAt(i * res[1] * res[0] * 3 + j * res[0] * 3 + k * 3) = (fft_data[i * res[1] * res[0] + j * res[0] + k + 1][0] - fft_data[i * res[1] * res[0] + j * res[0] + k - 1][0]) / g_fCubeXStep; // } // GetTimeStep(0)->m_pCurrentDensity->GetAt(i * res[1] * res[0] * 3 + j * res[0] * 3) = (fft_data[i * res[1] * res[0] + j * res[0] + 1][0] - fft_data[i * res[1] * res[0] + j * res[0] + res[0] - 1][0]) / g_fCubeXStep; // GetTimeStep(0)->m_pCurrentDensity->GetAt(i * res[1] * res[0] * 3 + j * res[0] * 3 + (res[0] - 1) * 3) = (fft_data[i * res[1] * res[0] + j * res[0]][0] - fft_data[i * res[1] * res[0] + j * res[0] + res[0] - 2][0]) / g_fCubeXStep; // } // } // for (i = 0; i < res[2]; i++) { // int j; // for (j = 1; j < res[1] - 1; j++) { // int k; // for (k = 0; k < res[0]; k++) { // GetTimeStep(0)->m_pCurrentDensity->GetAt(i * res[1] * res[0] * 3 + j * res[0] * 3 + k * 3 + 1) = (fft_data[i * res[1] * res[0] + (j + 1) * res[0] + k][0] - fft_data[i * res[1] * res[0] + (j - 1) * res[0] + k][0]) / g_fCubeYStep; // } // } // int k; // for (k = 0; k < res[0]; k++) { // GetTimeStep(0)->m_pCurrentDensity->GetAt(i * res[1] * res[0] * 3 + k * 3 + 1) = (fft_data[i * res[1] * res[0] + res[0] + k][0] - fft_data[i * res[1] * res[0] + (res[1] - 1) * res[0] + k][0]) / g_fCubeYStep; // GetTimeStep(0)->m_pCurrentDensity->GetAt(i * res[1] * res[0] * 3 + (res[1] - 1) * res[0] * 3 + k * 3 + 1) = (fft_data[i * res[1] * res[0] + k][0] - fft_data[i * res[1] * res[0] + (res[1] - 2) * res[0] + k][0]) / g_fCubeYStep; // } // } // for (i = 1; i < res[2] - 1; i++) { // int j; // for (j = 0; j < res[1]; j++) { // int k; // for (k = 0; k < res[0]; k++) { // GetTimeStep(0)->m_pCurrentDensity->GetAt(i * res[1] * res[0] * 3 + j * res[0] * 3 + k * 3 + 2) = (fft_data[(i + 1) * res[1] * res[0] + j * res[0] + k][0] - fft_data[(i - 1) * res[1] * res[0] + j * res[0] + k][0]) / g_fCubeZStep; // } // } // } // int j; // for (j = 0; j < res[1]; j++) { // int k; // for (k = 0; k < res[0]; k++) { // GetTimeStep(0)->m_pCurrentDensity->GetAt(j * res[0] * 3 + k * 3 + 2) = (fft_data[res[1] * res[0] + j * res[0] + k][0] - fft_data[(res[2] - 1) * res[1] * res[0] + j * res[0] + k][0]) / g_fCubeZStep; // GetTimeStep(0)->m_pCurrentDensity->GetAt((res[2] - 1) * res[1] * res[0] * 3 + j * res[0] * 3 + k * 3 + 2) = (fft_data[j * res[0] + k][0] - fft_data[(res[2] - 2) * res[1] * res[0] + j * res[0] + k][0]) / g_fCubeZStep; // } // } // // fftwf_destroy_plan(plan1); // fftwf_destroy_plan(plan2); // fftwf_free(fft_data); for (i = 0; i < res[2]; i++) { for (j = 0; j < res[1]; j++) { int k; for (k = 1; k < res[0] - 1; k++) { GetTimeStep(0)->m_pCurrentDensity->GetAt(i * res[1] * res[0] * 3 + j * res[0] * 3 + k * 3) = (pdeSolution[i * res[1] * res[0] + j * res[0] + k + 1] - pdeSolution[i * res[1] * res[0] + j * res[0] + k - 1]) / (2.0 * g_fCubeXStep) * GetTimeStep(0)->m_pVolumetricData->m_pBin[i * res[1] * res[0] + j * res[0] + k]; } GetTimeStep(0)->m_pCurrentDensity->GetAt(i * res[1] * res[0] * 3 + j * res[0] * 3) = (pdeSolution[i * res[1] * res[0] + j * res[0] + 1] - pdeSolution[i * res[1] * res[0] + j * res[0] + res[0] - 1]) / (2.0 * g_fCubeXStep) * GetTimeStep(0)->m_pVolumetricData->m_pBin[i * res[1] * res[0] + j * res[0]]; GetTimeStep(0)->m_pCurrentDensity->GetAt(i * res[1] * res[0] * 3 + j * res[0] * 3 + (res[0] - 1) * 3) = (pdeSolution[i * res[1] * res[0] + j * res[0]] - pdeSolution[i * res[1] * res[0] + j * res[0] + res[0] - 2]) / (2.0 * g_fCubeXStep) * GetTimeStep(0)->m_pVolumetricData->m_pBin[i * res[1] * res[0] + j * res[0] + res[0] - 1]; } } for (i = 0; i < res[2]; i++) { for (j = 1; j < res[1] - 1; j++) { int k; for (k = 0; k < res[0]; k++) { GetTimeStep(0)->m_pCurrentDensity->GetAt(i * res[1] * res[0] * 3 + j * res[0] * 3 + k * 3 + 1) = (pdeSolution[i * res[1] * res[0] + (j + 1) * res[0] + k] - pdeSolution[i * res[1] * res[0] + (j - 1) * res[0] + k]) / (2.0 * g_fCubeYStep) * GetTimeStep(0)->m_pVolumetricData->m_pBin[i * res[1] * res[0] + j * res[0] + k]; } } int k; for (k = 0; k < res[0]; k++) { GetTimeStep(0)->m_pCurrentDensity->GetAt(i * res[1] * res[0] * 3 + k * 3 + 1) = (pdeSolution[i * res[1] * res[0] + res[0] + k] - pdeSolution[i * res[1] * res[0] + (res[1] - 1) * res[0] + k]) / (2.0 * g_fCubeYStep) * GetTimeStep(0)->m_pVolumetricData->m_pBin[i * res[1] * res[0] + k]; GetTimeStep(0)->m_pCurrentDensity->GetAt(i * res[1] * res[0] * 3 + (res[1] - 1) * res[0] * 3 + k * 3 + 1) = (pdeSolution[i * res[1] * res[0] + k] - pdeSolution[i * res[1] * res[0] + (res[1] - 2) * res[0] + k]) / (2.0 * g_fCubeYStep) * GetTimeStep(0)->m_pVolumetricData->m_pBin[i * res[1] * res[0] + (res[1] - 1) * res[0] + k]; } } for (i = 1; i < res[2] - 1; i++) { for (j = 0; j < res[1]; j++) { int k; for (k = 0; k < res[0]; k++) { GetTimeStep(0)->m_pCurrentDensity->GetAt(i * res[1] * res[0] * 3 + j * res[0] * 3 + k * 3 + 2) = (pdeSolution[(i + 1) * res[1] * res[0] + j * res[0] + k] - pdeSolution[(i - 1) * res[1] * res[0] + j * res[0] + k]) / (2.0 * g_fCubeZStep) * GetTimeStep(0)->m_pVolumetricData->m_pBin[i * res[1] * res[0] + j * res[0] + k]; } } } for (j = 0; j < res[1]; j++) { int k; for (k = 0; k < res[0]; k++) { GetTimeStep(0)->m_pCurrentDensity->GetAt(j * res[0] * 3 + k * 3 + 2) = (pdeSolution[res[1] * res[0] + j * res[0] + k] - pdeSolution[(res[2] - 1) * res[1] * res[0] + j * res[0] + k]) / (2.0 * g_fCubeZStep) * GetTimeStep(0)->m_pVolumetricData->m_pBin[j * res[0] + k]; GetTimeStep(0)->m_pCurrentDensity->GetAt((res[2] - 1) * res[1] * res[0] * 3 + j * res[0] * 3 + k * 3 + 2) = (pdeSolution[j * res[0] + k] - pdeSolution[(res[2] - 2) * res[1] * res[0] + j * res[0] + k]) / (2.0 * g_fCubeZStep) * GetTimeStep(0)->m_pVolumetricData->m_pBin[(res[2] - 1) * res[1] * res[0] + j * res[0] + k]; } } // mprintf(GREEN, "%#.10g\n", GetTimeStep(0)->m_pCurrentDensity->GetAt(0)); // FILE *cubeFile = fopen("test.cube", "w"); // if (cubeFile == NULL) { // printf("Could not open output file!\n"); // abort(); // } // // fprintf(cubeFile, "\n\n"); // fprintf(cubeFile, "%5lu %12.6f %12.6f %12.6f\n", GetTimeStep(0)->m_iGesAtomCount, 0.0f, 0.0f, 0.0f); // fprintf(cubeFile, "%5d %12.6f %12.6f %12.6f\n", GetTimeStep(0)->m_pVolumetricDataTimeDev->m_iRes[0], g_fCubeXStep, 0.0f, 0.0f); // fprintf(cubeFile, "%5d %12.6f %12.6f %12.6f\n", GetTimeStep(0)->m_pVolumetricDataTimeDev->m_iRes[1], 0.0f, g_fCubeYStep, 0.0f); // fprintf(cubeFile, "%5d %12.6f %12.6f %12.6f\n", GetTimeStep(0)->m_pVolumetricDataTimeDev->m_iRes[2], 0.0f, 0.0f, g_fCubeZStep); // for (int i = 0; i < (int)GetTimeStep(0)->m_iGesAtomCount; i++) { // fprintf(cubeFile, "%5d %12.6f %12.6f %12.6f %12.6f\n", 1, 0.0f, GetTimeStep(0)->m_vaCoords[i][0] / 0.529177249f / 100.0f, GetTimeStep(0)->m_vaCoords[i][1] / 0.529177249f / 100.0f, GetTimeStep(0)->m_vaCoords[i][2] / 0.529177249f / 100.0f); // } // double sum = 0.0; // for (int i = 0; i < GetTimeStep(0)->m_pVolumetricDataTimeDev->m_iRes[0]; i++) { // for (int j = 0; j < GetTimeStep(0)->m_pVolumetricDataTimeDev->m_iRes[1]; j++) { // for (int k = 0; k < GetTimeStep(0)->m_pVolumetricDataTimeDev->m_iRes[2] / 6; k++) { // for (int l = 0; l < 6; l++) { // fprintf(cubeFile, "%13.5E", GetTimeStep(0)->m_pCurrentDensity->GetAt(i * 3 + j * GetTimeStep(0)->m_pVolumetricDataTimeDev->m_iRes[0] * 3 + (k * 6 + l) * GetTimeStep(0)->m_pVolumetricDataTimeDev->m_iRes[0] * GetTimeStep(0)->m_pVolumetricDataTimeDev->m_iRes[1] * 3)); // sum += GetTimeStep(0)->m_pCurrentDensity->GetAt(i * 3 + j * GetTimeStep(0)->m_pVolumetricDataTimeDev->m_iRes[0] * 3 + (k * 6 + l) * GetTimeStep(0)->m_pVolumetricDataTimeDev->m_iRes[0] * GetTimeStep(0)->m_pVolumetricDataTimeDev->m_iRes[1] * 3); // } // fprintf(cubeFile, "\n"); // } // if (GetTimeStep(0)->m_pVolumetricDataTimeDev->m_iRes[2] % 6 != 0) { // for (int l = 0; l < GetTimeStep(0)->m_pVolumetricDataTimeDev->m_iRes[2] % 6; l++) { // fprintf(cubeFile, "%13.5E", GetTimeStep(0)->m_pCurrentDensity->GetAt(i * 3 + j * GetTimeStep(0)->m_pVolumetricDataTimeDev->m_iRes[0] * 3 + ((GetTimeStep(0)->m_pVolumetricDataTimeDev->m_iRes[2] / 6) * 6 + l) * GetTimeStep(0)->m_pVolumetricDataTimeDev->m_iRes[0] * GetTimeStep(0)->m_pVolumetricDataTimeDev->m_iRes[1] * 3)); // sum += GetTimeStep(0)->m_pCurrentDensity->GetAt(i * 3 + j * GetTimeStep(0)->m_pVolumetricDataTimeDev->m_iRes[0] * 3 + ((GetTimeStep(0)->m_pVolumetricDataTimeDev->m_iRes[2] / 6) * 6 + l) * GetTimeStep(0)->m_pVolumetricDataTimeDev->m_iRes[0] * GetTimeStep(0)->m_pVolumetricDataTimeDev->m_iRes[1] * 3); // } // fprintf(cubeFile, "\n"); // } // } // } // mprintf(GREEN, "%g\n", sum); // // fclose(cubeFile); // // FILE *testFile = fopen("test.dat", "w"); // if (testFile == NULL) { // printf("Could not open output file!\n"); // abort(); // } // // for (int i = 0; i < GetTimeStep(0)->m_pVolumetricDataTimeDev->m_iRes[0]; i++) { // for (int j = 0; j < GetTimeStep(0)->m_pVolumetricDataTimeDev->m_iRes[1]; j++) { // fprintf(testFile, "%.6f %.6f %.14f %.14f\n", i * g_fCubeXStep, j * g_fCubeYStep, GetTimeStep(0)->m_pCurrentDensity->GetAt(i * 3 + j * GetTimeStep(0)->m_pVolumetricDataTimeDev->m_iRes[0] * 3 + GetTimeStep(0)->m_pVolumetricDataTimeDev->m_iRes[2] / 2 * GetTimeStep(0)->m_pVolumetricDataTimeDev->m_iRes[1] * GetTimeStep(0)->m_pVolumetricDataTimeDev->m_iRes[0] * 3), GetTimeStep(0)->m_pCurrentDensity->GetAt(i * 3 + j * GetTimeStep(0)->m_pVolumetricDataTimeDev->m_iRes[0] * 3 + GetTimeStep(0)->m_pVolumetricDataTimeDev->m_iRes[2] / 2 * GetTimeStep(0)->m_pVolumetricDataTimeDev->m_iRes[1] * GetTimeStep(0)->m_pVolumetricDataTimeDev->m_iRes[0] * 3 + 1)); // } // fprintf(testFile, "\n"); // } // // fclose(testFile); } void CalcForces() { BTIN; int z; double f, imf, ilmf; g_fLMidForce = 0; imf = g_fMaxForce; ilmf = g_fLMaxForce; GetTimeStep(0)->m_vaForces.SetSize(g_iGesVirtAtomCount); for (z=0;zm_vaForces[z] = (GetTimeStep(-1)->m_vaCoords[z] - 2*GetTimeStep(0)->m_vaCoords[z] + GetTimeStep(1)->m_vaCoords[z])/(double)pow2(g_fTimestepLength/1000.0); f = GetTimeStep(0)->m_vaForces[z].GetLength(); // mprintf(GREEN, "%g\n", f); g_fLMidForce += f; if (f > imf) imf = f; if (f > ilmf) ilmf = f; } g_fLMidForce /= g_iGesVirtAtomCount; g_fLMaxForce = ilmf; if (imf < g_fUnsteadyLimit) { g_fMaxForce = imf; } else if (!g_bWarnUnsteady) { g_bWarnUnsteady = true; mprintf("Warning: Discontinuity in time step %d (maximum acceleration = %f > %f pm/ps^2).\n",(int)g_iSteps,imf,g_fUnsteadyLimit); } BTOUT; } /*double AtomMass(char *s) { BTIN; int z; for (z=0;zm_sLabel)==0) { BTOUT; return ((CElement*)g_oaElements[z])->m_fMass; } eprintf("Atom \"%s\" not found.\n",s); BTOUT; return -1.0f; } int AtomOrd(char *s) { BTIN; int z; for (z=0;zm_sLabel)==0) { BTOUT; return ((CElement*)g_oaElements[z])->m_iOrd; } eprintf("Atom \"%s\" not found.\n",s); BTOUT; return -1; } double AtomRadius(char *s) { BTIN; int z; for (z=0;zm_sLabel)==0) { BTOUT; return ((CElement*)g_oaElements[z])->m_fRadius; } mprintf("No Atom Radius found for Atom \"%s\".\n",s); BTOUT; return 0; }*/ CElement* FindElement(const char *s, bool quiet) { BTIN; int z; for (z=0;zm_sLabel)==0) { BTOUT; return (CElement*)g_oaElements[z]; } } if (!quiet) eprintf(" No element data found for atom \"%s\".\n",s); g_bUnknownElements = true; BTOUT; return NULL; } double GuessBoxSize() { BTIN; int z; double m, gm; gm = 0; for (z=0;zm_pElement->m_fMass; /* if (m < 0) // Dieses Atom ist nicht in der Liste { if (z != g_iVirtAtomType) mprintf("Atom \"%s\" nicht in der Liste.\n",((CAtom*)g_oaAtoms[z])->m_sName); continue; }*/ gm += m * ((CAtom*)g_oaAtoms[z])->m_iCount; } m = (double)mypow(gm/6.02214086*10,0.33333333) * 100.0; // In pm BTOUT; return m; } void strtolower(char *s) { BTIN; char *p; p = s; while (*p != 0) { if ((*p >= 'A') && (*p <= 'Z')) *p += 32; p++; } BTOUT; } void SortAtoms() { BTIN; int z, z2; int i; CAtom *a; for (z=0;zm_sName,((CAtom*)g_oaAtoms[z2])->m_sName) > 0) i = z2; if (i != z) { a = (CAtom*)g_oaAtoms[z]; g_oaAtoms[z] = g_oaAtoms[i]; g_oaAtoms[i] = a; } } for (z=0;zm_iIndex = z; BTOUT; } void SortElementsLabel() { BTIN; int z, z2; int i; CElement *e; for (z=0;zm_sLabel,((CElement*)g_oaElements[z2])->m_sLabel) > 0) i = z2; if (i != z) { e = (CElement*)g_oaElements[z]; g_oaElements[z] = g_oaElements[i]; g_oaElements[i] = e; } } BTOUT; } void SortElementsMass() { BTIN; int z, z2; int i; CElement *e; for (z=0;zm_fMass > ((CElement*)g_oaElements[z2])->m_fMass) i = z2; if (i != z) { e = (CElement*)g_oaElements[z]; g_oaElements[z] = g_oaElements[i]; g_oaElements[i] = e; } } BTOUT; } bool SetAnalysis(const char *s) { BTIN; if (mystricmp(s, "fpp") == 0) { g_bFixedPlProj = true; return true; } if (mystricmp(s, "chdf") == 0) { g_bCHDF = true; return true; } if(mystricmp(s, "chi") == 0) { g_bChiral = true; return true; } if(mystricmp(s, "eck") == 0) { g_bEckartTransform = true; return true; } if (mystricmp(s, "pol") == 0) { g_bSetUpPolarizabilityCalc = true; return true; } if(mystricmp(s, "swan") == 0) { g_bSortWannier = true; return true; } if (mystricmp(s, "order") == 0) { g_bOrder = true; return true; } if(mystricmp(s, "vcd") == 0) { g_bVCD = true; return true; } if (mystricmp(s, "spec") == 0) { g_bROA = true; return true; } if (mystricmp(s, "drst") == 0) { g_bDipoleRestart = true; return true; } if (mystricmp(s, "mrst") == 0) { g_bMagneticDipoleRestart = true; return true; } if(mystricmp(s, "nc") == 0) { g_bNormalCoordinate = true; return true; } if (mystricmp(s,"dprof")==0) { /* if ((!g_bPeriodicX) || (!g_bPeriodicY) || (!g_bPeriodicZ)) { eprintf("\n Error: Requires XYZ-periodic box!\n\n"); BTOUT; return false; }*/ g_bPDF = true; return true; } if (mystricmp(s,"vori")==0) { g_bTegri = true; BTOUT; return true; } if (mystricmp(s,"doma")==0) { g_bDomA = true; BTOUT; return true; } if (mystricmp(s,"plproj")==0) { g_bPlProj = true; BTOUT; return true; } if (mystricmp(s,"pldf")==0) { g_bPlDF = true; BTOUT; return true; } if (mystricmp(s,"lidf")==0) { g_bLiDF = true; BTOUT; return true; } if (mystricmp(s,"power")==0) { // g_bACF = true; // g_bPowerSpec = true; g_bPower = true; BTOUT; return true; } if (mystricmp(s,"ir")==0) { // g_bRDyn = true; // g_bIRSpec = true; g_bIR = true; BTOUT; return true; } if (mystricmp(s,"reg")==0) { g_bRegionAnalysis = true; BTOUT; return true; } if (mystricmp(s,"raman")==0) { g_bRaman = true; BTOUT; return true; } if (mystricmp(s,"sfac")==0) { g_bSFac = true; BTOUT; return true; } if (mystricmp(s,"dens")==0) { if ((!g_bPeriodicX) || (!g_bPeriodicY) || (!g_bPeriodicZ)) { eprintf("\n Error: Requires XYZ-periodic box!\n\n"); BTOUT; return false; } g_bDens = true; BTOUT; return true; } if (mystricmp(s,"cond")==0) { g_bCond = true; BTOUT; return true; } if (mystricmp(s,"sdf")==0) { g_bSDF = true; BTOUT; return true; } if (mystricmp(s,"psdf")==0) { g_bRevSDF = true; BTOUT; return true; } if (mystricmp(s,"rdf")==0) { g_bRDF = true; BTOUT; return true; } if (mystricmp(s,"vdf")==0) { g_bVDF = true; BTOUT; return true; } if (mystricmp(s,"fdf")==0) { g_bFDF = true; BTOUT; return true; } if (mystricmp(s,"adf")==0) { g_bADF = true; BTOUT; return true; } if (mystricmp(s,"ddf")==0) { g_bDDF = true; BTOUT; return true; } if (mystricmp(s,"cdf")==0) { g_bCDF = true; BTOUT; return true; } if (mystricmp(s,"msd")==0) { g_bMSD = true; BTOUT; return true; } if (mystricmp(s,"aggr")==0) { g_bAggregation = true; BTOUT; return true; } if (mystricmp(s,"hbond") == 0) { g_bHBond = true; return true; } if (mystricmp(s,"ionpair") == 0) { g_bIonPair = true; return true; } if (mystricmp(s,"nbex")==0) { g_bNbExchange = true; BTOUT; return true; } /* if (mystricmp(s,"ddisp")==0) { g_bDDisp = true; g_bAggregation = true; BTOUT; return true; }*/ if (mystricmp(s,"acf")==0) { //g_bACF = true; g_bVACFNew = true; BTOUT; return true; } if (mystricmp(s,"nbx")==0) { g_bNbExchange = true; BTOUT; return true; } if (mystricmp(s,"rdyn")==0) { g_bRDyn = true; BTOUT; return true; } if (mystricmp(s,"cut")==0) { g_bCutCluster = true; BTOUT; return true; } if (mystricmp(s,"avg")==0) { g_bAvg = true; BTOUT; return true; } if (mystricmp(s,"env")==0) { g_bSaveRefEnv = true; BTOUT; return true; } if (mystricmp(s,"proc")==0) { g_bSaveJustTraj = true; BTOUT; return true; } if (mystricmp(s,"vhcf")==0) { g_bVHDF = true; BTOUT; return true; } if (mystricmp(s,"nbh")==0) { g_bNbAnalysis = true; BTOUT; return true; } /* if (mystricmp(s,"vfd")==0) { g_bSaveVelForce = true; BTOUT; return true; }*/ if (mystricmp(s,"dip")==0) { g_bDipDF = true; g_bDipole = true; BTOUT; return true; } if (mystricmp(s,"voro")==0) { if ((!g_bPeriodicX) || (!g_bPeriodicY) || (!g_bPeriodicZ)) { eprintf("\n Error: Basic Voronoi Analysis currently requires XYZ-periodic box.\n\n"); BTOUT; return false; } g_bVoro = true; BTOUT; return true; } BTOUT; return false; } bool ParseFunctions(const char *s) { BTIN; const char *cp; char *p, *q; char buf[256]; int z; CAnalysis *a; g_bOrder = false; g_bFixedPlProj = false; g_bROA = false; g_bSFac = false; g_bVoid = false; g_bTegri = false; g_bVoro = false; g_bDomA = false; g_bPlProj = false; g_bPlDF = false; g_bLiDF = false; g_bDens = false; g_bCond = false; g_bSDF = false; g_bRDF = false; g_bVDF = false; g_bFDF = false; g_bADF = false; g_bAvg = false; g_bSaveVelForce = false; g_bSaveRefEnv = false; g_bRefEnvCenter = false; g_bSaveJustTraj = false; g_bVHDF = false; g_bCutCluster = false; g_bNbAnalysis = false; g_bVACF = false; g_bDipACF = false; g_bDDF = false; g_bMSD = false; g_bDipole = false; g_bDipDF = false; g_bCDF = false; g_bAggregation = false; g_bDDisp = false; g_bDACF = false; g_bDLDF = false; g_bRDyn = false; g_bNbExchange = false; g_bRaman = false; g_bIRSpec = false; g_bPowerSpec = false; g_bRegionAnalysis = false; g_bVACFNew = false; cp = s; q = buf; while (*cp != 0) { if (*cp == ' ') cp++; else { *q = *cp; cp++; q++; } } *q = 0; p = buf; while (true) { q = strchr(p,','); if (q != NULL) *q = 0; for (z=0;zm_sAbbrev)==0) { mprintf(WHITE," %-7s",a->m_sAbbrev); mprintf("- %s\n",a->m_sName); if (!SetAnalysis(p)) { eprintf("Function cannot be applied to this system: \"%s\"\n",p); return false; } goto _done; } } eprintf("Unknown Function: \"%s\"\n",p); return false; _done: if ((q == NULL) || (*(q+1) == 0)) { BTOUT; return true; } p = q+1; } } bool ParsePeriodic(const char *s) { const char *p; BTIN; if (strlen(s) == 0) { g_bPeriodicX = true; g_bPeriodicY = true; g_bPeriodicZ = true; g_bPeriodic = true; BTOUT; return true; } g_bPeriodicX = false; g_bPeriodicY = false; g_bPeriodicZ = false; p = s; while (*p != 0) { if ((*p == 'x') || (*p == 'X')) g_bPeriodicX = true; else if ((*p == 'y') || (*p == 'Y')) g_bPeriodicY = true; else if ((*p == 'z') || (*p == 'Z')) g_bPeriodicZ = true; else if (*p != '0') { eprintf("Invalid input.\n"); BTOUT; return false; } p++; } g_bPeriodic = g_bPeriodicX || g_bPeriodicY || g_bPeriodicZ; BTOUT; return true; } void WriteHeader() { struct tm *today; time_t ltime; char buf[64]; unsigned long l, *lp; unsigned char *ca, *cb, *cc, *cd; bool b; BTIN; mprintf("\n"); /* http://patorjk.com/software/taag/ "Big Money-SW" */ /* mprintf(" ________ ______ __ __ __ \n"); mprintf("/ | / \\ / | / |/ | \n"); mprintf("########/______ /###### |## | ## |##/ _______ \n"); mprintf(" ## | / \\ ## |__## |## | ## |/ | / |\n"); mprintf(" ## |/###### |## ## |## \\ /##/ ## |/#######/ \n"); mprintf(" ## |## | ##/ ######## | ## /##/ ## |## \\ \n"); mprintf(" ## |## | ## | ## | ## ##/ ## | ###### |\n"); mprintf(" ## |## | ## | ## | ###/ ## |/ ##/ \n"); mprintf(" ##/ ##/ ##/ ##/ #/ ##/ #######/ \n");*/ /* mprintf(" ________ __\n"); mprintf(" / | / |\n"); mprintf(" ########/______ ______ __ __ ##/ _______\n"); mprintf(" ## | / \\ / \\ / \\ / |/ | / |\n"); mprintf(" ## |/###### |###### |## \\ /##/ ## |/#######/\n"); mprintf(" ## |## | ##/ / ## | ## /##/ ## |## \\\n"); mprintf(" ## |## | /####### | ## ##/ ## | ###### |\n"); mprintf(" ## |## | ## ## | ###/ ## |/ ##/\n"); mprintf(" ##/ ##/ #######/ #/ ##/ #######/\n");*/ mprintf(YELLOW," ________ __\n"); mprintf(YELLOW," / | / |\n"); mprintf(YELLOW," ########/ ______ ______ __ __ ##/ _______\n"); mprintf(YELLOW," ## | / \\ / \\ / \\ / | / | / |\n"); mprintf(YELLOW," ## | /###### | ###### | ## \\ /##/ ## | /#######/\n"); mprintf(YELLOW," ## | ## | ##/ / ## | ## /##/ ## | ## \\\n"); mprintf(YELLOW," ## | ## | /####### | ## ##/ ## | ###### |\n"); mprintf(YELLOW," ## | ## | ## ## | ###/ ## | / ##/\n"); mprintf(YELLOW," ##/ ##/ #######/ #/ ##/ #######/\n"); mprintf(WHITE,"\n TRajectory Analyzer and VISualizer - Open-source freeware under GNU GPL v3\n\n"); // mprintf(""); mprintf(" Copyright (c) Martin Brehm (2009-2019), University of Halle (Saale)\n"); mprintf(" Martin Thomas (2012-2019)\n"); mprintf(" Sascha Gehrke (2016-2019), University of Bonn\n"); mprintf(" Barbara Kirchner (2009-2019), University of Bonn\n"); mprintf("\n"); mprintf(YELLOW," http://www.travis-analyzer.de\n\n"); // mprintf(" Open-source freeware; Licensed under the GNU General Public License v3.\n\n"); mprintf(" Please cite: "); mprintf(WHITE,"M. Brehm, B. Kirchner: J. Chem. Inf. Model. 2011, 51 (8), pp 2007-2023.\n\n"); mprintf(" There is absolutely no warranty on any results obtained from TRAVIS.\n\n"); time(<ime); today = localtime(<ime); strcpy(buf,asctime(today)); buf[strlen(buf)-1] = 0; mprintf(WHITE," # "); if (g_sHostName != NULL) mprintf("Running on %s at %s",g_sHostName,buf); else mprintf("Running at %s",buf); #ifdef TARGET_LINUX mprintf(" (PID %d)\n",getpid()); #elif defined(TARGET_WINDOWS) mprintf(" (PID %d)\n",GetCurrentProcessId()); #else mprintf("\n"); #endif if (g_sWorkingDir != NULL) { mprintf(WHITE," # "); mprintf("Running in %s\n",g_sWorkingDir); } /* mprintf(WHITE," # "); mprintf("Source code version: "); mprintf("%s.\n",SOURCE_VERSION); #ifdef RELEASE_VERSION mprintf(WHITE," # "); mprintf("Release version: "); mprintf("%s.\n",RELEASE_VERSION); #endif mprintf(WHITE," # "); mprintf("Compiled at "); mprintf("%s %s.\n",__DATE__,__TIME__);*/ mprintf(WHITE," # "); mprintf("Code version: "); mprintf("%s",SOURCE_VERSION); #ifdef RELEASE_VERSION mprintf(", Release "); mprintf("%s",RELEASE_VERSION); #endif mprintf(", Compiled at "); mprintf("%s, %s",__DATE__,__TIME__); #if defined(__VERSION) || defined(__GNUC__) || defined(_MSC_VER) || defined(__clang__) || defined(__llvm__) mprintf(", Compiler"); b = false; #ifdef __VERSION__ mprintf(" \"%s\"",__VERSION__); b = true; #endif #ifdef __llvm__ if (b) mprintf(","); mprintf(" LLVM"); b = true; #endif #ifdef __clang__ if (b) mprintf(","); #if defined(__clang_major__) && defined(__clang_minor__) && defined(__clang_patchlevel__) mprintf(" CLANG %d.%d.%d",__clang_major__,__clang_minor__,__clang_patchlevel__); #elif defined(__clang_version__) mprintf(" CLANG \"%s\"",__clang_version__); #else mprintf(" CLANG"); #endif b = true; #endif #ifdef __GNUC__ if (b) mprintf(","); #ifdef __MINGW32__ mprintf(" MinGW GCC %d.%d.%d",__GNUC__,__GNUC_MINOR__,__GNUC_PATCHLEVEL__); #else mprintf(" GCC %d.%d.%d",__GNUC__,__GNUC_MINOR__,__GNUC_PATCHLEVEL__); #endif b = true; #endif #ifdef _MSC_VER if (b) mprintf(","); mprintf(" MSVC++ "); switch(_MSC_VER) { case 1916: mprintf("15.9, VS 2017"); break; case 1915: mprintf("15.8, VS 2017"); break; case 1914: mprintf("15.7, VS 2017"); break; case 1913: mprintf("15.6, VS 2017"); break; case 1912: mprintf("15.5, VS 2017"); break; case 1911: mprintf("15.3, VS 2017"); break; case 1910: mprintf("15.1, VS 2017"); break; case 1900: mprintf("14.0, VS 2015"); break; case 1800: mprintf("12.0, VS 2013"); break; case 1700: mprintf("11.0, VS 2012"); break; case 1600: mprintf("10.0, VS 2010"); break; case 1500: mprintf("9.0, VS 2008"); break; case 1400: mprintf("8.0, VS 2005"); break; case 1310: mprintf("7.1, VS 2003"); break; case 1300: mprintf("7.0"); break; case 1200: mprintf("6.0"); break; case 1100: mprintf("5.0"); break; default: mprintf("%d",_MSC_VER); break; } b = true; #endif #endif mprintf("\n"); #ifdef TARGET_WINDOWS mprintf(WHITE," # "); mprintf("Target platform: Windows"); #elif defined(TARGET_LINUX) mprintf(WHITE," # "); mprintf("Target platform: Linux"); #else mprintf(WHITE," # "); mprintf("Target platform: Generic"); #endif mprintf(", Compile flags: "); #ifdef DEBUG_BACKTRACE mprintf("DEBUG_BACKTRACE "); #endif #ifdef DEBUG_EXTENDED_BACKTRACE mprintf("DEBUG_EXTENDED_BACKTRACE "); #endif #ifdef USE_FFTW mprintf("USE_FFTW "); #endif #ifdef DEBUG_ARRAYS mprintf("DEBUG_ARRAYS "); #endif #ifdef DEBUG_COBARRAY mprintf("DEBUG_COBARRAY "); #endif #ifdef DEBUG_CSTRING mprintf("DEBUG_CSTRING "); #endif #ifdef DEBUG_CVEC3ARRAY mprintf("DEBUG_CVEC3ARRAY "); #endif #ifdef DEBUG_DATABASE mprintf("DEBUG_DATABASE "); #endif mprintf("\n"); l = 0xA0B0C0D0; lp = &l; ca = (unsigned char*)lp; cb = ca+1; cc = ca+2; cd = ca+3; mprintf(WHITE," # "); mprintf("Machine: int=%lub, long=%lub, addr=%lub, 0xA0B0C0D0=%02X,%02X,%02X,%02X.\n",sizeof(int),sizeof(long),sizeof(void*),*ca,*cb,*cc,*cd); mprintf(WHITE," # "); if (g_sHomeDir != NULL) mprintf("Home: %s, ",g_sHomeDir); mprintf("Executable: %s\n",g_sExeName); mprintf(WHITE," # "); if ((!IsTTY(stdin)) || (g_sInputFile != NULL)) { if (g_sInputFile != NULL) mprintf("Input from %s, ",g_sInputFile); else mprintf("Input is redirected, "); } else mprintf("Input from terminal, "); if (IsTTY(stdout)) mprintf("Output to terminal\n"); else mprintf("Output is redirected\n"); if (g_bStreamInput) { mprintf(WHITE," # "); mprintf("Input trajectory treated as stream\n"); } mprintf("\n"); mprintf(" >>> Please use a color scheme with dark background or specify \"-nocolor\"! <<<\n\n"); // mprintf("\nSome general hints:\n - If you don't Enter something and just press RETURN,\n the Value in [Square Brackets] will be used as default.\n"); // mprintf(" - If your input was wrong and you want to jump back,\n please enter \"$\".\n\n"); BTOUT; } void CommandLineHelp() { BTIN; mprintf(WHITE," List of supported command line options:\n\n"); mprintf(" -p Load position data from specified trajectory file.\n"); mprintf(" File format may be *.xyz, *.pdb, *.lmp (LAMMPS), HISTORY (DLPOLY), or *.prmtop/*.mdcrd (Amber).\n"); mprintf(" BQB format (*.bqb, *.btr, *.emp, *.blist) is also supported.\n"); mprintf(" -vel Read atom velocities from a file in addition to the position trajectory.\n"); mprintf(" Currently, only .xyz format is supported for velocity data.\n"); mprintf(" -i Read input from specified text file.\n"); mprintf(" -c Read and execute control file (experimental).\n"); mprintf(" -config Load the specified configuration file.\n"); mprintf(" -stream Treat input trajectory as a stream (e.g. named pipe): No fseek, etc.\n"); mprintf(" -showconf Show a tree structure of the configuration file.\n"); mprintf(" -writeconf Write the default configuration file, including all defines values.\n\n"); mprintf(" -verbose Show detailed information about what's going on.\n"); mprintf(" -nocolor Execute TRAVIS in monochrome mode (suitable for white background).\n"); mprintf(" -dimcolor Use dim instead of bright colors.\n\n"); mprintf(" -credits Display a list of persons who contributed to TRAVIS.\n"); mprintf(" -help, -? Shows this help.\n"); mprintf("\n"); mprintf(" If only one argument is specified, it is assumed to be the name of a trajectory file.\n"); mprintf(" If argument is specified at all, TRAVIS asks for the trajectory file to open.\n"); BTOUT; } bool ParseArgs(int argc, const char *argv[]) { BTIN; const char *p; char SModeFlag[64]; int z; // bool namegiven; UnBase64((unsigned char *)SModeFlag,(const unsigned char *)"LXNjaGlzcw==",12); g_bAsciiArt = false; z = 1; // g_sInputTraj[0] = 0; // g_sInputVel[0] = 0; g_sInputVel = ""; // g_sInputForce[0] = 0; g_sInputForce = ""; // g_sInputCtrl[0] = 0; g_sInputCtrl = ""; // namegiven = false; while (z < argc) { if ((memcmp(argv[z],"-?",2)==0) || (memcmp(argv[z],"--?",3)==0) || (memcmp(argv[z],"-help",5)==0) || (memcmp(argv[z],"--help",6)==0)) { CommandLineHelp(); BTOUT; return false; } if (mystricmp(argv[z],"-p")==0) { // mprintf("Dateiname: \"%s\"\n",argv[z+1]); z++; try { g_sInputTraj = new char[strlen(argv[z])+1]; } catch(...) { g_sInputTraj = NULL; } if (g_sInputTraj == NULL) NewException((double)(strlen(argv[z])+1)*sizeof(char),__FILE__,__LINE__,__PRETTY_FUNCTION__); strcpy(g_sInputTraj,argv[z]); goto _argend; } if (mystricmp(argv[z],"-vel")==0) { z++; g_sInputVel.strcpy(argv[z]); goto _argend; } if (mystricmp(argv[z],"-conf")==0) { // mprintf("Dateiname: \"%s\"\n",argv[z+1]); z++; try { g_sConfFile = new char[strlen(argv[z])+1]; } catch(...) { g_sConfFile = NULL; } if (g_sConfFile == NULL) NewException((double)(strlen(argv[z])+1)*sizeof(char),__FILE__,__LINE__,__PRETTY_FUNCTION__); strcpy(g_sConfFile,argv[z]); goto _argend; } if (mystricmp(argv[z],"-i")==0) { // mprintf("Dateiname: \"%s\"\n",argv[z+1]); z++; /* try { g_sInputFile = new char[strlen(argv[z])+1]; } catch(...) { g_sInputFile = NULL; } if (g_sInputFile == NULL) NewException((double)(strlen(argv[z])+1)*sizeof(char),__FILE__,__LINE__,__PRETTY_FUNCTION__); strcpy(g_sInputFile,argv[z]);*/ goto _argend; } if (mystricmp(argv[z],"-c")==0) { z++; goto _argend; } if (mystricmp(argv[z],"-react")==0) { goto _argend; } if (mystricmp(argv[z],"-verbose")==0) { goto _argend; } if (mystricmp(argv[z],"-credits")==0) { goto _argend; } if (mystricmp(argv[z],"-showconf")==0) { goto _argend; } if (mystricmp(argv[z],"-stream")==0) { goto _argend; } if (mystricmp(argv[z],"-writeconf")==0) { goto _argend; } /* if (mystricmp(argv[z],"-f")==0) { z++; strcpy(g_sInputForce,argv[z]); goto _argend; }*/ if ((mystricmp(argv[z],"-nocolor")==0) || (mystricmp(argv[z],"--nocolor")==0)) { goto _argend; } if ((mystricmp(argv[z],"-dimcolor")==0) || (mystricmp(argv[z],"--dimcolor")==0)) { goto _argend; } if (mystricmp(argv[z],"-a")==0) { // mprintf("AA ist an.\n"); g_bAsciiArt = true; goto _argend; } if (mystricmp(argv[z],"-lsd")==0) { goto _argend; } if (mystricmp(argv[z],"-readdipole")==0) { goto _argend; } if (mystricmp(argv[z],"-sax")==0) { goto _argend; } if (mystricmp(argv[z],SModeFlag)==0) { g_bSMode = true; goto _argend; } if ((argc > 2) || (argv[z][0] == '-')) { eprintf("Unknown parameter: \"%s\".\n\n",argv[z]); CommandLineHelp(); BTOUT; return false; } p = strrchr(argv[z],'.'); if (p != NULL) { p++; if ((mystricmp(p,"xyz")==0) || (mystricmp(p,"cube")==0) || (mystricmp(p,"pdb")==0) || (mystricmp(p,"mol2")==0) || (mystricmp(p,"lmp")==0) || (mystricmp(p,"HISTORY")==0) || (mystricmp(p,"prmtop")==0) || (mystricmp(p,"mdcrd")==0) || (mystricmp(p,"bqb")==0) || (mystricmp(p,"bbq")==0) || (mystricmp(p,"btr")==0) || (mystricmp(p,"blist")==0) || (mystricmp(p,"emp")==0)) { try { g_sInputTraj = new char[strlen(argv[z])+1]; } catch(...) { g_sInputTraj = NULL; } if (g_sInputTraj == NULL) NewException((double)(strlen(argv[z])+1)*sizeof(char),__FILE__,__LINE__,__PRETTY_FUNCTION__); strcpy(g_sInputTraj,argv[z]); } else { eprintf("Unknown parameter: \"%s\".\n\n",argv[z]); CommandLineHelp(); BTOUT; return false; } // try { g_sInputTraj = new char[strlen(argv[z])+1]; } catch(...) { g_sInputTraj = NULL; } // if (g_sInputTraj == NULL) NewException((double)(strlen(argv[z])+1)*sizeof(char),__FILE__,__LINE__,__PRETTY_FUNCTION__); // strcpy(g_sInputTraj,argv[z]); } else { if (mystricmp(&argv[z][strlen(argv[z])-7],"HISTORY")==0) { try { g_sInputTraj = new char[strlen(argv[z])+1]; } catch(...) { g_sInputTraj = NULL; } if (g_sInputTraj == NULL) NewException((double)(strlen(argv[z])+1)*sizeof(char),__FILE__,__LINE__,__PRETTY_FUNCTION__); strcpy(g_sInputTraj,argv[z]); } else { eprintf("Unknown parameter: \"%s\".\n\n",argv[z]); CommandLineHelp(); BTOUT; return false; } } BTOUT; return true; _argend: z++; } BTOUT; return true; } void ParsePassiveArgs(int argc, const char *argv[]) { BTIN; int z; g_bGlobalPsycho = false; z = 1; while (z < argc) { if (mystricmp(argv[z],"-credits")==0) g_bShowCredits = true; if (mystricmp(argv[z],"-lsd")==0) g_bGlobalPsycho = true; if (mystricmp(argv[z],"-readdipole")==0) g_bDipolGrimme = true; if (mystricmp(argv[z],"-sax")==0) g_bSaxonize = true; if (mystricmp(argv[z],"-verbose")==0) g_bVerbose = true; if (mystricmp(argv[z],"-showconf")==0) g_bShowConf = true; if (mystricmp(argv[z],"-stream")==0) g_bStreamInput = true; if (mystricmp(argv[z],"-vel")==0) g_bReadVelocity = true; if (mystricmp(argv[z],"-writeconf")==0) g_bWriteConf = true; if ((mystricmp(argv[z],"-nocolor")==0) || (mystricmp(argv[z],"--nocolor")==0)) g_bNoColor = true; if ((mystricmp(argv[z],"-dimcolor")==0) || (mystricmp(argv[z],"--dimcolor")==0)) g_iColorIntensity = 2; if (mystricmp(argv[z],"-i")==0) { z++; try { g_sInputFile = new char[strlen(argv[z])+1]; } catch(...) { g_sInputFile = NULL; } if (g_sInputFile == NULL) NewException((double)(strlen(argv[z])+1)*sizeof(char),__FILE__,__LINE__,__PRETTY_FUNCTION__); strcpy(g_sInputFile,argv[z]); } if (mystricmp(argv[z],"-c")==0) { z++; try { g_sControlFile = new char[strlen(argv[z])+1]; } catch(...) { g_sControlFile = NULL; } if (g_sControlFile == NULL) NewException((double)(strlen(argv[z])+1)*sizeof(char),__FILE__,__LINE__,__PRETTY_FUNCTION__); strcpy(g_sControlFile,argv[z]); g_bControlRun = true; } z++; } BTOUT; } void CreateDatabaseDefaults() { g_pDatabase->AddString("/GLOBAL/TRAVIS_VERSION",SOURCE_VERSION); g_pDatabase->AddBool("/GLOBAL/SHOWCREDITS",false); g_pDatabase->AddBool("/PLOT2D/FORMATS/WRITE_MATHEMATICA",true); g_pDatabase->AddBool("/PLOT2D/FORMATS/WRITE_GNUPLOT",true); g_pDatabase->AddBool("/PLOT2D/FORMATS/WRITE_TRIPLES",true); g_pDatabase->AddBool("/PLOT2D/FORMATS/WRITE_MATRIX",true); g_pDatabase->AddInt("/PLOT2D/DEFAULTS/BIN_RES",100); g_pDatabase->AddInt("/PLOT2D/DEFAULTS/IMAGE_RES",1000); g_pDatabase->AddFloat("/PLOT2D/DEFAULTS/PLOT_EXP",0.5); g_pDatabase->AddInt("/PLOT2D/DEFAULTS/CONTOUR_LINES",30); g_pDatabase->AddBool("/PLOT3D/FORMATS/WRITE_CUBE",true); g_pDatabase->AddBool("/PLOT3D/FORMATS/WRITE_PLT",true); g_pDatabase->AddInt("/PLOT3D/DEFAULTS/BIN_RES",100); /* g_pDatabase->AddString("/BLA/BLUBB/PLOEPP/STRING1","String 1 Content"); g_pDatabase->AddInt("/BLA/BLUBB/PLOEPP/INT1",123456); g_pDatabase->AddFloat("/BLA/BLUBB/PLOEPP/FLOAT1",1.23456); g_pDatabase->AddBool("/BLA/BLUBB/PLOEPP/BOOL1",true);*/ //g_pDatabase->AddInt("/BLA/BLUBB/PLOEPP/STRING1",17); } void LoadSettings() { // char buf[256]; CxString buf; char sep; FILE *a; #ifdef TARGET_WINDOWS sep = '\\'; #else sep = '/'; #endif if (g_sConfFile != NULL) { mprintf(WHITE," Custom configuration file specified: %s\n",g_sConfFile); if (FileExist(g_sConfFile)) { mprintf(" Loading configuration from %s ...\n",g_sConfFile); g_pDatabase->ParseInputFile(g_sConfFile); return; } else { eprintf("LoadSettings(): Error: File does not exist or cannot be read.\n"); abort(); } } // sprintf(buf,"%s%ctravis.conf",g_sWorkingDir,sep); buf.sprintf("%s%ctravis.conf",g_sWorkingDir,sep); if (FileExist(buf)) { mprintf(" Loading configuration from %s ...\n",(const char*)buf); g_pDatabase->ParseInputFile(buf); return; } // sprintf(buf,"%s%c.travis.conf",g_sWorkingDir,sep); buf.sprintf("%s%c.travis.conf",g_sWorkingDir,sep); if (FileExist(buf)) { mprintf(" Loading configuration from %s ...\n",(const char*)buf); g_pDatabase->ParseInputFile(buf); return; } // sprintf(buf,"%s%ctravis.conf",g_sHomeDir,sep); buf.sprintf("%s%ctravis.conf",g_sHomeDir,sep); if (FileExist(buf)) { mprintf(" Loading configuration from %s ...\n",(const char*)buf); g_pDatabase->ParseInputFile(buf); return; } // sprintf(buf,"%s%c.travis.conf",g_sHomeDir,sep); buf.sprintf("%s%c.travis.conf",g_sHomeDir,sep); if (FileExist(buf)) { mprintf(" Loading configuration from %s ...\n",(const char*)buf); g_pDatabase->ParseInputFile(buf); return; } mprintf(WHITE," No configuration file found.\n"); if (g_sHomeDir == NULL) { eprintf("\n Could not detect user home directory, writing config file to current directory.\n\n"); // sprintf(buf,".travis.conf"); buf.sprintf(".travis.conf"); } else // sprintf(buf,"%s%c.travis.conf",g_sHomeDir,sep); buf.sprintf("%s%c.travis.conf",g_sHomeDir,sep); mprintf(" Writing default configuration to %s ...\n",(const char*)buf); a = fopen(buf,"wt"); if (a == NULL) { eprintf(" Cannot open %s for writing.\n",(const char*)buf); return; } fclose(a); g_pDatabase->WriteOutputFile(buf); } void InitDatabase() { // char buf[256]; CxString buf; char sep; FILE *a; #ifdef TARGET_WINDOWS sep = '\\'; #else sep = '/'; #endif try { g_pDatabase = new CDatabase(); } catch(...) { g_pDatabase = NULL; } if (g_pDatabase == NULL) NewException((double)sizeof(CDatabase),__FILE__,__LINE__,__PRETTY_FUNCTION__); CreateDatabaseDefaults(); /******* Interface *********/ Interface_DefaultConf(); LoadSettings(); // mprintf("\"%s\" vs \"%s\"\n",g_pDatabase->GetString("/GLOBAL/TRAVIS_VERSION"),SOURCE_VERSION); if (strcmp(g_pDatabase->GetString("/GLOBAL/TRAVIS_VERSION"),SOURCE_VERSION) != 0) { g_pDatabase->SetString("/GLOBAL/TRAVIS_VERSION",SOURCE_VERSION); // sprintf(buf,"%s%c.travis.conf",g_sHomeDir,sep); buf.sprintf("%s%c.travis.conf",g_sHomeDir,sep); mprintf(WHITE," TRAVIS version has changed."); if (!g_bWriteConf) mprintf(" You should write a new configuration file (specify \"-writeconf\").\n"); } if (g_bWriteConf) { if (g_sHomeDir == NULL) { eprintf("\n Could not detect user's home directory, writing config file to current directory.\n\n"); // sprintf(buf,".travis.conf"); buf.sprintf(".travis.conf"); } else // sprintf(buf,"%s%c.travis.conf",g_sHomeDir,sep); buf.sprintf("%s%c.travis.conf",g_sHomeDir,sep); mprintf(" Writing new default configuration to %s ...\n",(const char*)buf); a = fopen(buf,"wt"); if (a == NULL) { eprintf(" Error: Cannot open %s for writing.\n",(const char*)buf); goto _writeend; } fclose(a); g_pDatabase->WriteOutputFile(buf); } _writeend: if (g_bShowConf) { mprintf(WHITE,"\n Output of Database Tree:\n\n"); g_pDatabase->DumpTree(); } if (g_pDatabase->GetBool("/GLOBAL/SHOWCREDITS")) g_bShowCredits = true; mprintf("\n"); } void RECURSION_BuildCDF(CObservation *o, int channel, int om, CxDoubleArray **data, double *result) { BXIN; int z/*, z2*/; if (channel == g_iCDFChannels) { o->m_pCDF->AddToBin(result); BXOUT; return; } /* if (o->m_pCDF->m_bChannelAll[channel]) { for (z=0;zm_iShowMolCount;z++) for (z2=0;z2m_iIndex = g_iGesVirtAtomCount; va->m_iMolecule = (unsigned short)mol; va->m_iMolVirtAtom = (unsigned char)m->m_laVirtualAtoms.GetSize(); sprintf(va->m_sLabel,"#%d",va->m_iMolVirtAtom+1); if (m->m_laVirtualAtoms.GetSize()==0) { m->m_baAtomIndex.Add(g_iVirtAtomType); m->m_waAtomCount.Add(1); for (z2=0;z2m_laSingleMolIndex.GetSize();z2++) { sm = (CSingleMolecule*)g_oaSingleMolecules[m->m_laSingleMolIndex[z2]]; sm->m_baAtomIndex.Add(g_iVirtAtomType); try { la = new CxIntArray("AddVirtualAtom():sm->m_oaAtomOffset[]"); } catch(...) { la = NULL; } if (la == NULL) NewException((double)sizeof(CxIntArray),__FILE__,__LINE__,__PRETTY_FUNCTION__); sm->m_oaAtomOffset.Add(la); } } else { m->m_waAtomCount[m->m_baAtomIndex.GetSize()-1]++; // for (z2=0;z2m_laSingleMolIndex.GetSize();z2++) // { // sm = (CSingleMolecule*)g_oaSingleMolecules[m->m_laSingleMolIndex[z2]]; // sm->m_iAtomCount[sm->m_iElements-1]++; // } } for (z2=0;z2m_laSingleMolIndex.GetSize();z2++) { sm = (CSingleMolecule*)g_oaSingleMolecules[m->m_laSingleMolIndex[z2]]; ((CxIntArray*)sm->m_oaAtomOffset[sm->m_baAtomIndex.GetSize()-1])->Add(g_iGesVirtAtomCount); g_iGesVirtAtomCount++; } m->m_iAtomGes++; m->m_laVirtualAtoms.Add((unsigned short)g_oaVirtualAtoms.GetSize()-1); BTOUT; return va; } void AddElement(const char *s, int ord, double mass, double radius, double vdw) { BTIN; CElement *e; try { e = new CElement(); } catch(...) { e = NULL; } if (e == NULL) NewException((double)sizeof(CElement),__FILE__,__LINE__,__PRETTY_FUNCTION__); try { e->m_sLabel = new char[strlen(s)+1]; } catch(...) { e->m_sLabel = NULL; } if (e->m_sLabel == NULL) NewException((double)(strlen(s)+1)*sizeof(char),__FILE__,__LINE__,__PRETTY_FUNCTION__); strcpy(e->m_sLabel,s); e->m_iOrd = ord; e->m_fMass = mass; e->m_fRadius = radius; e->m_fVdWRadius = vdw; e->m_fCoherentNCS = 0; g_oaElements.Add(e); BTOUT; } void AddElement(const char *s, int ord, double mass, double radius, double vdw, double ncs) { BTIN; CElement *e; try { e = new CElement(); } catch(...) { e = NULL; } if (e == NULL) NewException((double)sizeof(CElement),__FILE__,__LINE__,__PRETTY_FUNCTION__); try { e->m_sLabel = new char[strlen(s)+1]; } catch(...) { e->m_sLabel = NULL; } if (e->m_sLabel == NULL) NewException((double)(strlen(s)+1)*sizeof(char),__FILE__,__LINE__,__PRETTY_FUNCTION__); strcpy(e->m_sLabel,s); e->m_iOrd = ord; e->m_fMass = mass; e->m_fRadius = radius; e->m_fVdWRadius = vdw; e->m_fCoherentNCS = ncs; g_oaElements.Add(e); BTOUT; } void SetElementColor(const char *s, unsigned char r, unsigned char g, unsigned char b, unsigned char br, unsigned char bb, unsigned char bg) { BTIN; CElement *e; e = FindElement(s,true); if (e == NULL) { eprintf("SetElementColor(): Element \"%s\" not found.\n",s); return; } e->m_iColorR = r; e->m_iColorG = g; e->m_iColorB = b; e->m_iColorBleachedR = br; e->m_iColorBleachedG = bg; e->m_iColorBleachedB = bb; BTOUT; } void RemoveAllElements() { BTIN; int z; for (z=0;zm_laSingleMolIndex.GetSize();z++) { sm = (CSingleMolecule*)g_oaSingleMolecules[mol->m_laSingleMolIndex[z]]; // sm->m_oaTempAtomOffset.SetSize(mol->m_baAtomIndex.GetSize()); for (z2=0;z2m_baAtomIndex.GetSize();z2++) { /* if (sm->m_oaTempAtomOffset[z2] != NULL) delete sm->m_oaTempAtomOffset[z2]; sm->m_oaTempAtomOffset[z2] = new CxIntArray();*/ if (twa != NULL) delete twa; try { twa = new CxIntArray("ReorderAtoms():twa"); } catch(...) { twa = NULL; } if (twa == NULL) NewException((double)sizeof(CxIntArray),__FILE__,__LINE__,__PRETTY_FUNCTION__); twa->SetSize(((CxIntArray*)mol->m_oaNewNumbers[z2])->GetSize()); for (z3=0;z3<((CxIntArray*)mol->m_oaNewNumbers[z2])->GetSize();z3++) { // ti = ((CxIntArray*)sm->m_oaAtomOffset[z2])->GetAt(z3); // (*((CxIntArray*)sm->m_oaAtomOffset[z2]))[z3] = ((CxIntArray*)sm->m_oaAtomOffset[z2])->GetAt(((CxIntArray*)mol->m_oaNewNumbers[z2])->GetAt(z3)); (*twa)[z3] = ((CxIntArray*)sm->m_oaAtomOffset[z2])->GetAt(((CxIntArray*)mol->m_oaNewNumbers[z2])->GetAt(z3)); // mprintf(" (%s%d wird zu %s%d; %d -> %d)\n",((CAtom*)g_oaAtoms[mol->m_baAtomIndex[z2]])->m_sName,z3+1,((CAtom*)g_oaAtoms[mol->m_baAtomIndex[z2]])->m_sName,((CxIntArray*)mol->m_oaNewNumbers[z2])->GetAt(z3)+1,((CxIntArray*)sm->m_oaAtomOffset[z2])->GetAt(z3),((CxIntArray*)sm->m_oaAtomOffset[z2])->GetAt(((CxIntArray*)mol->m_oaNewNumbers[z2])->GetAt(z3))); } for (z3=0;z3<((CxIntArray*)mol->m_oaNewNumbers[z2])->GetSize();z3++) (*((CxIntArray*)sm->m_oaAtomOffset[z2]))[z3] = (*twa)[z3]; } } delete twa; } void ReorderLikeInput() { // Written @ Ballmer Peak int z, z2, z3, z4, z5, ti, tl; CMolecule *mol; CSingleMolecule *sm; mprintf("\n"); for (z=0;zm_sName); mol->m_oaNewNumbers.SetSize(mol->m_baAtomIndex.GetSize()); sm = (CSingleMolecule*)g_oaSingleMolecules[mol->m_laSingleMolIndex[0]]; for (z2=0;z2m_baAtomIndex.GetSize();z2++) { if (mol->m_oaNewNumbers[z2] != NULL) delete mol->m_oaNewNumbers[z2]; try { mol->m_oaNewNumbers[z2] = new CxIntArray("ReorderLikeInput():mol->m_oaNewNumbers[z2]"); } catch(...) { mol->m_oaNewNumbers[z2] = NULL; } if (mol->m_oaNewNumbers[z2] == NULL) NewException((double)sizeof(CxIntArray),__FILE__,__LINE__,__PRETTY_FUNCTION__); // F***ing Stack sort is incompatible with Ballmer Peak ^^ for (z3=0;z3m_waAtomCount[z2];z3++) { // Sortiere nach kleinstem Offset tl = 9999999; ti = -1; for (z4=0;z4m_waAtomCount[z2];z4++) { for (z5=0;z5m_oaNewNumbers[z2])->GetAt(z5) == z4) goto _nextreord; // Der ist schon einsortiert. Keyswapping hier offensichtlich nicht moeglich if (((CxIntArray*)sm->m_oaAtomOffset[z2])->GetAt(z4) < tl) { tl = ((CxIntArray*)sm->m_oaAtomOffset[z2])->GetAt(z4); ti = z4; } _nextreord:; } ((CxIntArray*)mol->m_oaNewNumbers[z2])->Add(ti); } } ReorderAtoms(z); mprintf("Done.\n"); } mprintf("\n"); } unsigned long GraceColor(int z, double bleach) { int r, g, b; z = z % 14; switch(z) { case 0: r = 0; g = 0; b = 0; break; case 1: r = 0; g = 0; b = 255; break; case 2: r = 255; g = 0; b = 0; break; case 3: r = 0; g = 255; b = 0; break; case 4: r = 255; g = 0; b = 255; break; case 5: r = 0; g = 255; b = 255; break; case 6: r = 255; g = 255; b = 0; break; case 7: r = 128; g = 128; b = 128; break; case 8: r = 0; g = 0; b = 128; break; case 9: r = 128; g = 0; b = 0; break; case 10: r = 0; g = 128; b = 0; break; case 11: r = 128; g = 0; b = 128; break; case 12: r = 0; g = 128; b = 128; break; case 13: r = 128; g = 255; b = 0; break; default: r = 0; g = 0; b = 0; } r = (int)((1.0-bleach)*r + bleach*255.0); g = (int)((1.0-bleach)*g + bleach*255.0); b = (int)((1.0-bleach)*b + bleach*255.0); if (r > 255) r = 255; if (g > 255) g = 255; if (b > 255) b = 255; return r + g*0x100 + b*0x10000; } unsigned long CalcFFTSize(unsigned long i, bool silent) { unsigned long t, r, r2, r3, r5, t2, t3, t5; int i2, i3, i5, m2, m3, m5; bool b=false; // mprintf("*** CalcFFTSize %d ***\n",i); m2 = (int)ceil(log((double)i) / log(2.0)); m3 = (int)ceil(log((double)i) / log(3.0)); m5 = (int)ceil(log((double)i) / log(5.0)); r = 2147483647; r2 = m2; r3 = m3; r5 = m5; // mprintf("m2=%d, m3=%d, m5=%d, r=%d.\n",m2,m3,m5,r); t2 = 1; for (i2=0;i2<=m2;i2++) { t3 = 1; for (i3=0;i3<=m3;i3++) { t5 = 1; for (i5=0;i5<=m5;i5++) { t = t2 * t3 * t5; // mprintf("%d * %d * %d = %d\n",t2,t3,t5,t); if ((t >= i) && (t < r)) { r = t; r2 = i2; r3 = i3; r5 = i5; // mprintf("2^%d + 3^%d +5^%d = %d.\n",r2,r3,r5,r); } t5 *= 5; } t3 *= 3; } t2 *= 2; } if (!silent) { mprintf("\n CalcFFTSize(): %lu = ",i); if (r2 != 0) { mprintf("2^%lu",r2); b = true; } if (r3 != 0) { if (b) mprintf(" *"); mprintf(" 3^%lu",r3); b = true; } if (r5 != 0) { if (b) mprintf(" *"); mprintf(" 5^%lu",r5); } if ((i - r) == 0) mprintf(". All prime factors within 2, 3, 5. Fine.\n\n"); else mprintf(" - %lu. Prime factors other than 2, 3, 5 not allowed.\n",r-i); } // mprintf("*** CalcFFTSize done ***\n"); return r; } void BuildAtomIndices() { int z, z2, z3, z4, z5, ti, ti2; CMolecule *m; CSingleMolecule *sm; g_waAtomMolIndex.SetSize(g_iGesVirtAtomCount); g_waAtomMolUID.SetSize(g_iGesVirtAtomCount); g_laAtomSMLocalIndex.SetSize(g_iGesVirtAtomCount); g_waAtomMolNumber.SetSize(g_iGesVirtAtomCount); g_waAtomElement.SetSize(g_iGesVirtAtomCount); g_waAtomRealElement.SetSize(g_iGesVirtAtomCount); g_faAtomCode.SetSize(g_iGesAtomCount); g_liAtomCode.resize(g_iGesAtomCount); g_faVdWRadius.SetSize(g_iGesAtomCount); for (z=0;zm_bPseudo) continue; for (z2=0;z2m_laSingleMolIndex.GetSize();z2++) { sm = (CSingleMolecule*)g_oaSingleMolecules[m->m_laSingleMolIndex[z2]]; for (z3=0;z3m_baAtomIndex.GetSize();z3++) { for (z4=0;z4<((CxIntArray*)sm->m_oaAtomOffset[z3])->GetSize();z4++) { ti = ((CxIntArray*)sm->m_oaAtomOffset[z3])->GetAt(z4); if (g_waAtomMolIndex[ti] != 60000) eprintf("BuildAtomIndices(): Atom in more than one molecule! z=%d, z2=%d, z3=%d, z4=%d.\n",z,z2,z3,z4); g_waAtomMolIndex[ti] = (unsigned short)z; g_waAtomMolUID[ti] = (unsigned short)ti2; g_laAtomSMLocalIndex[ti] = z2; g_waAtomElement[ti] = (unsigned short)z3; g_waAtomMolNumber[ti] = (unsigned short)z4; g_waAtomRealElement[ti] = sm->m_baAtomIndex[z3]; if (sm->m_baAtomIndex[z3] == g_iVirtAtomType) continue; g_faVdWRadius[ti] = ((CAtom*)g_oaAtoms[sm->m_baAtomIndex[z3]])->m_pElement->m_fVdWRadius; for (z5=0;z5m_oaMolAtoms.GetSize();z5++) { if (((CMolAtom*)sm->m_oaMolAtoms[z5])->m_iOffset == ti) { g_faAtomCode[ti] = ((CMolAtom*)sm->m_oaMolAtoms[z5])->m_fAtomCode; g_liAtomCode[ti] = ((CMolAtom*)sm->m_oaMolAtoms[z5])->m_liAtomCode; goto _found; } } eprintf("BuildAtomIndices(): Atom Code not found (z=%d, z2=%d, z3=%d, z4=%d).\n",z,z2,z3,z4); _found:; } } ti2++; } } g_baAtomPassedCondition.SetSize(g_iGesVirtAtomCount); for (z=0;z= 7) { if (mystricmp(&g_sInputTraj[strlen(g_sInputTraj)-7],"HISTORY") == 0) { g_iTrajFormat = 4; return true; } } goto _unk; } p++; if (mystricmp(p,"xyz")==0) { g_iTrajFormat = 0; return true; } if (mystricmp(p,"pdb")==0) { g_iTrajFormat = 1; return true; } if (mystricmp(p,"mol2")==0) { g_iTrajFormat = 2; return true; } if (mystricmp(p,"lmp")==0) { g_iTrajFormat = 3; return true; } if (mystricmp(p,"cube")==0) { g_iTrajFormat = 5; g_bVolumetricData = true; return true; } if ((mystricmp(p,"prmtop")==0) || (mystricmp(p,"mdcrd")==0)) { g_iTrajFormat = 6; *p = 0; // Delete file extension return true; } if ((mystricmp(p,"bqb")==0) || (mystricmp(p,"bbq")==0) || (mystricmp(p,"btr")==0) || (mystricmp(p,"emp")==0) || (mystricmp(p,"blist")==0)) { g_iTrajFormat = 7; return true; } _unk: eprintf("Could not determine trajectory file format (%s).\n\n",p); mprintf(WHITE,"The following formats are supported:\n"); mprintf(" - XYZ trajectories (extension .xyz)\n"); mprintf(" - PDB trajectories (extension .pdb)\n"); mprintf(" - LAMMPS trajectories \"dump custom element xu yu zu\" (extension .lmp)\n"); mprintf(" - DLPOLY trajectories (file name \"HISTORY\", no extension)\n"); mprintf(" - Amber trajectories (extension .prmtop / .mdcrd)\n"); mprintf(" - Cube file trajectories (extension .cube)\n"); mprintf(" - BQB format (extensions .bqb, .btr, .emp, and .blist)\n"); mprintf("\n"); return false; } const char* GetFileExtension(const char *s) { const char *p; if (s == NULL) return NULL; p = strrchr(s,'.'); if (p == NULL) return NULL; return p+1; } void PrintSMode() { const char *stext[16]; char buf[256]; int z; stext[0] = "ICAgU1NTU1NTU1NTU1NTU1NTICAgICAgICAgICAgICAgICAgaGhoaGhoICAgICAgICAgICAgICAgaWlpICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgISEh"; stext[1] = "IFNTOjo6Ojo6Ojo6Ojo6Ojo6UyAgICAgICAgICAgICAgICAgaDo6OjpoICAgICAgICAgICAgICBpOjo6aSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAhITohIQ=="; stext[2] = "Uzo6Ojo6U1NTU1NTOjo6Ojo6UyAgICAgICAgICAgICAgICAgaDo6OjpoICAgICAgICAgICAgICAgaWlpICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAhOjo6IQ=="; stext[3] = "Uzo6Ojo6UyAgICAgU1NTU1NTUyAgICAgICAgICAgICAgICAgIGg6OjpoICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAhOjo6IQ=="; stext[4] = "Uzo6Ojo6UyAgICAgICAgICAgICAgICAgY2NjY2NjY2NjY2NjIGg6OjpoIGhoaGhoICAgICAgIGlpaWlpaSAgICAgIHNzc3Nzc3NzICAgICAgICBzc3Nzc3NzcyAgICAhOjo6IQ=="; stext[5] = "Uzo6Ojo6UyAgICAgICAgICAgICAgIGNjOjo6Ojo6Ojo6OjpjIGg6OjpoaDo6Ojo6aGggICAgIGk6Ojo6aSAgICBzczo6Ojo6Ojo6cyAgICAgc3M6Ojo6Ojo6OnMgICAhOjo6IQ=="; stext[6] = "IFM6Ojo6U1NTUyAgICAgICAgICAgYzo6Ojo6Ojo6Ojo6OjpjIGg6Ojo6Ojo6Ojo6OjpoaCAgICBpOjo6aSAgc3M6Ojo6Ojo6Ojo6OnMgIHNzOjo6Ojo6Ojo6OjpzICAhOjo6IQ=="; stext[7] = "ICBTUzo6Ojo6OlNTU1NTICAgICBjOjo6OjpjY2NjY2M6OjpjIGg6Ojo6OjpoaGg6Ojo6OmggICBpOjo6aSAgczo6Ojo6c3Nzczo6OjpzIHM6Ojo6OnNzc3M6Ojo6cyAhOjo6IQ=="; stext[8] = "ICAgIFNTUzo6Ojo6Ojo6U1MgICBjOjo6OmMgICAgIGNjY2NjIGg6Ojo6OmggICBoOjo6OjpoICBpOjo6aSAgIHM6Ojo6cyAgIHNzc3MgICBzOjo6OnMgICBzc3NzICAhOjo6IQ=="; stext[9] = "ICAgICAgIFNTU1NTUzo6OjpTICBjOjo6YyAgICAgICAgICAgIGg6Ojo6aCAgICAgaDo6OjpoICBpOjo6aSAgICAgczo6Ojo6cyAgICAgICAgIHM6Ojo6OnMgICAgICAhOjo6IQ=="; stext[10] = "ICAgICAgICAgICAgUzo6Ojo6UyBjOjo6YyAgICAgICAgICAgIGg6Ojo6aCAgICAgaDo6OjpoICBpOjo6aSAgICAgICBzOjo6OjpzICAgICAgICAgczo6Ojo6cyAgICAhITohIQ=="; stext[11] = "ICAgICAgICAgICAgUzo6Ojo6UyBjOjo6OmMgICAgIGNjY2NjIGg6Ojo6aCAgICAgaDo6OjpoICBpOjo6aSAgc3NzcyAgICBzOjo6OnMgIHNzc3MgICAgczo6OjpzICAgISEh"; stext[12] = "U1NTU1NTUyAgICAgUzo6Ojo6UyBjOjo6OjpjY2NjY2M6OjpjIGg6Ojo6aCAgICAgaDo6OjpoIGk6Ojo6Omkgczo6Ojpzc3NzOjo6OjpzIHM6Ojo6c3Nzczo6Ojo6cw=="; stext[13] = "Uzo6Ojo6OlNTU1NTUzo6Ojo6UyAgYzo6Ojo6Ojo6Ojo6OjpjIGg6Ojo6aCAgICAgaDo6OjpoIGk6Ojo6Omkgczo6Ojo6Ojo6Ojo6OnMgIHM6Ojo6Ojo6Ojo6OjpzICAgISEh"; stext[14] = "Uzo6Ojo6Ojo6Ojo6Ojo6OlNTICAgIGNjOjo6Ojo6Ojo6OjpjIGg6Ojo6aCAgICAgaDo6OjpoIGk6Ojo6OmkgIHM6Ojo6Ojo6OjpzcyAgICBzOjo6Ojo6Ojo6c3MgICAhITohIQ=="; stext[15] = "IFNTU1NTU1NTU1NTU1NTUyAgICAgICAgY2NjY2NjY2NjY2NjIGhoaGhoaCAgICAgaGhoaGhoIGlpaWlpaWkgICBzc3Nzc3Nzc3MgICAgICAgc3Nzc3Nzc3NzICAgICAgISEh"; for (z=0;z<16;z++) { UnBase64((unsigned char*)buf,(const unsigned char*)stext[z],(int)strlen(stext[z])); mprintf(YELLOW,"%s\n",buf); } mprintf("\n"); } void PrintBMode() { const char *stext[15]; char buf[256]; int z; stext[0] = "ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIF8sIC4u"; stext[1] = "ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdfKF8wbylvKCku"; stext[2] = "ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAsbyhfXyksXyksKF9fKW8="; stext[3] = "ICAgICAgICAgXy4oLSkuXyAgICAgICAgICAgICAgICAgICAgbyhfLC1vKF8gKSgoXylvTylf"; stext[4] = "ICAgICAgLicgICAgICAgICAnLiAgICAgICAgICAgICAgICAgLk8oX18pbyxfXylvKF8pT29fKQ=="; stext[5] = "ICAgICAvICAgICAgICAgICAgIFwgICAgICAgICAgICAuLS0tLXwgICB8ICAgfCAgIHxfKTA="; stext[6] = "ICAgICB8Jy0uLi5fX18uLi4tJ3wgICAgICAgICAgIC8gIC4tLXwgICB8ICAgfCAgIHwsXyk="; stext[7] = "ICAgICAgXCAgICAnPScgICAgLyAgICAgICAgICAgfCAgLyAgIHwgICB8ICAgfCAgIHxvKF8p"; stext[8] = "ICAgICAgIGAnLl9fX19fLidgICAgICAgICAgICAgfCAgfCAgIHwgICB8ICAgfCAgIHxfL2Ap"; stext[9] = "ICAgICAgICAvICAgfCAgIFwgICAgICAgICAgICAgfCAgfCAgIHwgICB8ICAgfCAgIHxPXyk="; stext[10] = "ICAgICAgIC8uLS0nfCctLS5cICAgICAgICAgICAgfCAgXCAgIHwgICB8ICAgfCAgIHw="; stext[11] = "ICAgIFtdLyctLl9ffF9fLi0nXFtdICAgICAgICAgIFwgICctLXwgICB8ICAgfCAgIHw="; stext[12] = "ICAgICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAnLS0tLXwgICB8ICAgfCAgIHw="; stext[13] = "ICAgICAgICAgICBbXSAgICAgICAgICAgICAgICAgICAgICAgIFwgICBcICAgLyAgIC8="; stext[14] = "ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBgIiIiIiIiIiIiYA=="; mprintf("\n"); for (z=0;z<15;z++) { UnBase64((unsigned char*)buf,(const unsigned char*)stext[z],(int)strlen(stext[z])); mprintf(YELLOW," %s\n",buf); } // mprintf("\n"); } void WriteCredits() { mprintf("\n"); if (g_bShowCredits) { WriteCredits_Long(); } else { mprintf(YELLOW," Note:"); mprintf(" To show a list of all persons who contributed to TRAVIS,\n"); mprintf(" please add \""); mprintf(WHITE,"-credits"); mprintf("\" to your command line arguments, or set the\n"); mprintf(" variable \"SHOWCREDITS\" to \"TRUE\" in your travis.conf file.\n"); } mprintf("\n"); mprintf(" Source code from other projects used in TRAVIS:\n"); mprintf(" - lmfit from "); mprintf(WHITE,"Joachim Wuttke\n"); mprintf(" - kiss_fft from "); mprintf(WHITE,"Mark Borgerding\n"); mprintf(" - voro++ from "); mprintf(WHITE,"Chris Rycroft\n"); mprintf("\n"); mprintf(WHITE," http://www.travis-analyzer.de\n\n"); mprintf(YELLOW," Please cite the following articles:\n\n"); mprintf(RED," * "); mprintf("\"TRAVIS - A Free Analyzer and Visualizer for Monte Carlo and Molecular Dynamics Trajectories\",\n M. Brehm, B. Kirchner; J. Chem. Inf. Model. 2011, 51 (8), pp 2007-2023.\n\n"); if (g_bUseBQB) { mprintf(RED," * "); mprintf("\"An Efficient Lossless Compression Algorithm for Trajectories of Atom Positions and Volumetric Data\",\n M. Brehm, M. Thomas; J. Chem. Inf. Model. 2018, 58 (10), pp 2092-2107.\n\n"); } if (g_bIRSpec || g_bPowerSpec || g_bRaman || g_bPower || g_bIR || g_bROA) { mprintf(RED," * "); mprintf("\"Computing vibrational spectra from ab initio molecular dynamics\",\n M. Thomas, M. Brehm, R. Fligg, P. Voehringer, B. Kirchner; Phys. Chem. Chem. Phys. 2013, 15, pp 6608-6622.\n\n"); } if (g_bNormalCoordinate || g_bEckartTransform) { mprintf(RED," * "); mprintf("\"Simulating the vibrational spectra of ionic liquid systems:\n 1-Ethyl-3-methylimidazolium acetate and its mixtures\",\n M. Thomas, M. Brehm, O. Holloczki, Z. Kelemen, L. Nyulaszi, T. Pasinszki, B. Kirchner;\n J. Chem. Phys. 2014, 141, 024510.\n\n"); } if (g_bVoro || g_bDomA) { mprintf(RED," * "); mprintf("\"Domain Analysis in Nanostructured Liquids: A Post-Molecular Dynamics Study at the Example of Ionic Liquids\",\n M. Brehm, H. Weber, M. Thomas, O. Holloczki, B. Kirchner; ChemPhysChem 2015, 16, pp 3271-3277.\n\n"); } if (g_bSFac) { mprintf(RED," * "); mprintf("\"Triphilic Ionic-Liquid Mixtures: Fluorinated and Non-fluorinated Aprotic Ionic-Liquid Mixtures\",\n O. Holloczki, M. Macchiagodena, H. Weber, M. Thomas, M. Brehm, A. Stark, O. Russina, A. Triolo, B. Kirchner; ChemPhysChem 2015, 16, pp 3325-3333.\n\n"); } if (g_bTegri || g_bROA) { mprintf(RED," * "); mprintf("\"Voronoi dipole moments for the simulation of bulk phase vibrational spectra\",\n M. Thomas, M. Brehm, B. Kirchner; Phys. Chem. Chem. Phys. 2015, 17, pp 3207-3213.\n\n"); } if (g_bVCD || g_bCubeTimeDev) { mprintf(RED," * "); mprintf("\"Classical Magnetic Dipole Moments for the Simulation of Vibrational Circular Dichroism by Ab Initio Molecular Dynamics\",\n M. Thomas, B. Kirchner; J. Phys. Chem. Lett. 2016, 7, pp 509-513.\n\n"); } else if (g_bROA) { if (g_pROAEngine->m_bVCD || g_pROAEngine->m_bROA || g_pROAEngine->m_bMagMom) { mprintf(RED," * "); mprintf("\"Classical Magnetic Dipole Moments for the Simulation of Vibrational Circular Dichroism by Ab Initio Molecular Dynamics\",\n M. Thomas, B. Kirchner; J. Phys. Chem. Lett. 2016, 7, pp 509-513.\n\n"); } } if (g_bROA) { if (g_pROAEngine->m_bROA) { mprintf(RED," * "); mprintf("\"Computing Bulk Phase Raman Optical Activity Spectra from ab initio Molecular Dynamics Simulations\",\n M. Brehm, M. Thomas; J. Phys. Chem. Lett. 2017, 8 (14), pp 3409-3414.\n\n"); } } if (g_bHBond || g_bIonPair) { mprintf(RED," * "); mprintf("\"Structure and lifetimes in ionic liquids and their mixtures\",\n S. Gehrke, M. von Domaros, R. Clark, O. Holloczki, M. Brehm, T. Welton, A. Luzar, B. Kirchner;\n Faraday discuss. 2018, 206, pp 219-245.\n\n"); } if (g_bOrder) { mprintf(RED," * "); mprintf("\"Influence of Small Fluorophilic and Lipophilic Organic Molecules on Dipalmitoylphosphatidylcholine Bilayers\",\n M. Brehm, G. Saddiq, T. Watermann, D. Sebastiani;\n J. Phys. Chem. B 2017, 121 (35), 8311-8321.\n"); mprintf(" (for the order parameters in TRAVIS)\n\n"); } } void WriteCredits_Long() { mprintf(YELLOW," >>> Credits <<<\n"); mprintf(YELLOW,"\n"); mprintf(YELLOW," > "); mprintf(WHITE,"Martin Brehm "); mprintf("Main Developer (2009 - now)\n"); mprintf(YELLOW," > "); mprintf(WHITE,"Martin Thomas "); mprintf("Developer (2012 - now)\n"); mprintf(YELLOW," > "); mprintf(WHITE,"Sascha Gehrke "); mprintf("Developer (2016 - now)\n"); mprintf(YELLOW," > "); mprintf(WHITE,"Barbara Kirchner "); mprintf("Group Leader and idea\n\n"); mprintf(YELLOW," > "); mprintf(WHITE,"Marc Bruessel "); mprintf("Testing and Debugging\n"); mprintf(YELLOW," > "); mprintf(WHITE,"Philipp di Dio "); mprintf("Atom Parameters and Math Support\n"); mprintf(YELLOW," > "); mprintf(WHITE,"Christian Dressler "); mprintf("Bug Finding and Discussion\n"); mprintf(YELLOW," > "); mprintf(WHITE,"Michael von Domaros "); mprintf("New Ideas and Linux Repository updating\n"); mprintf(YELLOW," > "); mprintf(WHITE,"Dzmitry Firaha "); mprintf("Testing and new Ideas\n"); mprintf(YELLOW," > "); mprintf(WHITE,"Dorothea Golze "); mprintf("Testing and Debugging\n"); mprintf(YELLOW," > "); mprintf(WHITE,"Oldamur Holloczki "); mprintf("Testing and Debugging\n"); mprintf(YELLOW," > "); mprintf(WHITE,"Daniela Kerle "); mprintf("Name Finding\n"); mprintf(YELLOW," > "); mprintf(WHITE,"Miriam Kohagen "); mprintf("Testing and Debugging\n"); mprintf(YELLOW," > "); mprintf(WHITE,"Marina Macchiagodena "); mprintf("Testing and new Ideas\n"); mprintf(YELLOW," > "); mprintf(WHITE,"Friedrich \"Fred\" Malberg "); mprintf("Leading Bug Finder :-)\n"); mprintf(YELLOW," > "); mprintf(WHITE,"Matthias Schoeppke "); mprintf("Testing and new Ideas\n"); mprintf(YELLOW," > "); mprintf(WHITE,"Daniele Tedesco "); mprintf("Testing and new Ideas\n"); mprintf(YELLOW," > "); mprintf(WHITE,"Jens Thar "); mprintf("Fruitful Discussion and Scientific Input\n"); mprintf(YELLOW," > "); mprintf(WHITE,"Henry Weber "); mprintf("Testing, Debugging and creative Ideas\n"); mprintf(YELLOW," > "); mprintf(WHITE,"Stefan Zahn "); mprintf("Testing and Debugging\n"); /* mprintf(YELLOW," >>> Credits <<<\n"); mprintf(YELLOW,"\n"); mprintf(YELLOW," > "); mprintf(WHITE,"Martin Brehm "); mprintf("("); mprintf(RED,"*"); mprintf(") "); mprintf("Main Developer (2009 - now)\n"); mprintf(YELLOW," > "); mprintf(WHITE,"Martin Thomas "); mprintf("("); mprintf(RED,"*"); mprintf(") "); mprintf("Main Developer (2012 - now)\n"); mprintf(YELLOW," > "); mprintf(WHITE,"Barbara Kirchner "); mprintf("Group Leader\n\n"); mprintf(YELLOW," > "); mprintf(WHITE,"Marc Bruessel "); mprintf("Testing and Debugging\n"); mprintf(YELLOW," > "); mprintf(WHITE,"Philipp di Dio "); mprintf("("); mprintf(RED,"*"); mprintf(") "); mprintf("Atom Parameters and Math Support\n"); mprintf(YELLOW," > "); mprintf(WHITE,"Dorothea Golze "); mprintf("Testing and Debugging\n"); mprintf(YELLOW," > "); mprintf(WHITE,"Daniela Kerle "); mprintf("Name Finding\n"); mprintf(YELLOW," > "); mprintf(WHITE,"Miriam Kohagen "); mprintf("Testing and Debugging\n"); mprintf(YELLOW," > "); mprintf(WHITE,"Fred Malberg "); mprintf("Leading Bug Finder :-)\n"); mprintf(YELLOW," > "); mprintf(WHITE,"Matthias Schoeppke "); mprintf("Testing and new Ideas\n"); mprintf(YELLOW," > "); mprintf(WHITE,"Jens Thar "); mprintf("("); mprintf(RED,"*"); mprintf(") Fruitful Discussion and Scientific Input\n"); mprintf(YELLOW," > "); mprintf(WHITE,"Henry Weber "); mprintf("("); mprintf(RED,"*"); mprintf(") ");mprintf("Testing, Debugging and creative Ideas\n"); mprintf("\n"); mprintf(" ("); mprintf(RED,"*"); mprintf(")"); mprintf(" Office 42 - \"answer to all questions\".\n");*/ } CAutoCorrelation::CAutoCorrelation() { m_iInput = 0; m_iDepth = 0; m_pFFT = NULL; m_pFFT2 = NULL; } CAutoCorrelation::~CAutoCorrelation() { } void CAutoCorrelation::Init(int input, int depth, bool fft) { m_iInput = input; m_iDepth = depth; if (fft) { m_bFFT = true; m_iFFTSize = CalcFFTSize(input,true); try { m_pFFT = new CFFT(); } catch(...) { m_pFFT = NULL; } if (m_pFFT == NULL) NewException((double)sizeof(CFFT),__FILE__,__LINE__,__PRETTY_FUNCTION__); m_pFFT->PrepareFFT_C2C(2*m_iFFTSize); try { m_pFFT2 = new CFFT(); } catch(...) { m_pFFT2 = NULL; } if (m_pFFT2 == NULL) NewException((double)sizeof(CFFT),__FILE__,__LINE__,__PRETTY_FUNCTION__); m_pFFT2->PrepareInverseFFT_C2C(2*m_iFFTSize); } else { m_bFFT = false; } } void CAutoCorrelation::AutoCorrelate(CxDoubleArray *inp, CxDoubleArray *outp) { int z, z2; double tf; outp->SetSize(m_iDepth); if (m_bFFT) { for (z=0;zm_pInput[z*2] = (*inp)[z]; m_pFFT->m_pInput[z*2+1] = 0; } for (z=m_iInput;z<2*m_iFFTSize;z++) { m_pFFT->m_pInput[z*2] = 0; m_pFFT->m_pInput[z*2+1] = 0; } m_pFFT->DoFFT(); for (z=0;zm_pInput[z*2] = m_pFFT->m_pOutput[z*2]*m_pFFT->m_pOutput[z*2] + m_pFFT->m_pOutput[z*2+1]*m_pFFT->m_pOutput[z*2+1]; m_pFFT2->m_pInput[z*2+1] = 0; } m_pFFT2->DoFFT(); for (z=0;zm_pOutput[2*z] / m_iFFTSize / 2.0 / ((double)m_iInput - z); } else { for (z=0;z &inp, std::vector &outp) { int z, z2; double tf; outp.resize(m_iDepth); if (m_bFFT) { for (z=0;zm_pInput[z*2] = inp[z]; m_pFFT->m_pInput[z*2+1] = 0; } for (z=m_iInput;z<2*m_iFFTSize;z++) { m_pFFT->m_pInput[z*2] = 0; m_pFFT->m_pInput[z*2+1] = 0; } m_pFFT->DoFFT(); for (z=0;zm_pInput[z*2] = m_pFFT->m_pOutput[z*2]*m_pFFT->m_pOutput[z*2] + m_pFFT->m_pOutput[z*2+1]*m_pFFT->m_pOutput[z*2+1]; m_pFFT2->m_pInput[z*2+1] = 0; } m_pFFT2->DoFFT(); for (z=0;zm_pOutput[2*z] / m_iFFTSize / 2.0 / ((double)m_iInput - z); } else { for (z=0;zSetSize(m_iDepth); if (m_bFFT) { for (z=0;zm_pInput[z*2] = (*inp)[z]; m_pFFT->m_pInput[z*2+1] = 0; } for (z=m_iInput;z<2*m_iFFTSize;z++) { m_pFFT->m_pInput[z*2] = 0; m_pFFT->m_pInput[z*2+1] = 0; } m_pFFT->DoFFT(); for (z=0;zm_pInput[z*2] = sqrt(m_pFFT->m_pOutput[z*2]*m_pFFT->m_pOutput[z*2] + m_pFFT->m_pOutput[z*2+1]*m_pFFT->m_pOutput[z*2+1]); // m_pFFT2->m_pInput[z*2] = fabs(m_pFFT->m_pOutput[z*2]*m_pFFT->m_pOutput[z*2] + m_pFFT->m_pOutput[z*2+1]*m_pFFT->m_pOutput[z*2+1]); m_pFFT2->m_pInput[z*2+1] = 0; } m_pFFT2->DoFFT(); for (z=0;zm_pOutput[2*z]; // / m_iFFTSize / 2.0 / ((double)m_iInput - z); } else { eprintf("CAutoCorrelation::AutoCorrelateSqrt(): Error: Only implemented for FFT.\n"); abort(); } } /* void FormatTime(unsigned long eta, char *buf) { char tbuf[256], tbuf2[256]; if ((eta/60) > 0) sprintf(tbuf,"%02lus",eta%60); else sprintf(tbuf,"%2lus",eta%60); eta /= 60; if (eta > 0) { strcpy(tbuf2,tbuf); if ((eta/60) > 0) sprintf(tbuf,"%02lum",eta%60); else sprintf(tbuf,"%2lum",eta%60); strcat(tbuf,tbuf2); eta /= 60; if (eta > 0) { strcpy(tbuf2,tbuf); if ((eta/60) > 0) sprintf(tbuf,"%02luh",eta%24); else sprintf(tbuf,"%2luh",eta%24); strcat(tbuf,tbuf2); eta /= 24; } if (eta > 0) { strcpy(tbuf2,tbuf); if ((eta/60) > 0) sprintf(tbuf,"%02lud",eta); else sprintf(tbuf,"%2lud",eta); strcat(tbuf,tbuf2); } } strcpy(buf,tbuf); } */ void FormatTime(unsigned long eta, CxString *buf) { // char tbuf[256], tbuf2[256]; CxString tbuf, tbuf2; if (buf == NULL) return; if ((eta/60) > 0) // sprintf(tbuf,"%02lus",eta%60); tbuf.sprintf("%02lus",eta%60); else // sprintf(tbuf,"%2lus",eta%60); tbuf.sprintf("%2lus",eta%60); eta /= 60; if (eta > 0) { // strcpy(tbuf2,tbuf); tbuf2.strcpy(tbuf); if ((eta/60) > 0) // sprintf(tbuf,"%02lum",eta%60); tbuf.sprintf("%02lum",eta%60); else // sprintf(tbuf,"%2lum",eta%60); tbuf.sprintf("%2lum",eta%60); // strcat(tbuf,tbuf2); tbuf.strcat(tbuf2); eta /= 60; if (eta > 0) { // strcpy(tbuf2,tbuf); tbuf2.strcpy(tbuf); if ((eta/60) > 0) // sprintf(tbuf,"%02luh",eta%24); tbuf.sprintf("%02luh",eta%24); else // sprintf(tbuf,"%2luh",eta%24); tbuf.sprintf("%2luh",eta%24); // strcat(tbuf,tbuf2); tbuf.strcat(tbuf2); eta /= 24; } if (eta > 0) { // strcpy(tbuf2,tbuf); tbuf2.strcpy(tbuf); if ((eta/60) > 0) // sprintf(tbuf,"%02lud",eta); tbuf.sprintf("%02lud",eta); else // sprintf(tbuf,"%2lud",eta); tbuf.sprintf("%2lud",eta); // strcat(tbuf,tbuf2); tbuf.strcat(tbuf2); } } // strcpy(buf,tbuf); buf->strcpy(tbuf); } void RenderStructFormulas(int tries) { int z, z2, z3, ti; bool nohyd, hex; double tf; FILE *a; // char buf[256]; CxString buf; CMolecule *m; CSingleMolecule *sm; CMolAtom *ma1, *ma2; mprintf("\n"); hex = false; for (z=0;zm_iAtomGesNoVirt > 150) || (m->m_bPolymer)) { mprintf("\n"); mprintf(YELLOW," Warning: "); mprintf("Molecule %d (%s) is rather large. Rendering of structural formula may take a lot of time.\n\n",z+1,(const char*)m->m_sName); if (!AskYesNo(" Render this structural formula anyways (y/n)? [no] ",false)) continue; mprintf("\n"); } if (m->m_iAtomGesNoVirt == 1) { mprintf(WHITE," * Molecule %d: %s - skipping (only one atom).\n",z+1,m->m_sName); continue; } sm = (CSingleMolecule*)g_oaSingleMolecules[m->m_laSingleMolIndex[0]]; nohyd = false; _again: if (nohyd) { // sprintf(buf,"mol%d_%s_no_H.dot",z+1,m->m_sName); buf.sprintf("mol%d_%s_no_H.dot",z+1,m->m_sName); mprintf(WHITE," * Molecule %d: %s (without hydrogen atoms)\n",z+1,m->m_sName); } else { // sprintf(buf,"mol%d_%s.dot",z+1,m->m_sName); buf.sprintf("mol%d_%s.dot",z+1,m->m_sName); mprintf(WHITE," * Molecule %d: %s\n",z+1,m->m_sName); } mprintf(" Writing dot file %s...\n",(const char*)buf); a = OpenFileWrite(buf,true); mfprintf(a,"graph molecule {\n"); mfprintf(a," graph [pack=true,splines=true,overlap=false];\n"); mfprintf(a," node [shape=none,fontsize=16,fontname=\"Arial\",margin=0,fixedsize=true,height=0.28];\n"); mfprintf(a," edge [style=bold,len=0.70];\n"); for (z2=0;z2m_oaMolAtoms.GetSize();z2++) { ma1 = (CMolAtom*)sm->m_oaMolAtoms[z2]; if (mystricmp(((CAtom*)g_oaAtoms[m->m_baAtomIndex[ma1->m_iType]])->m_sName,"H")==0) { if (nohyd) continue; else hex = true; } mfprintf(a," %s%d [label=\"%s%d\",width=%.2f];\n",(const char*)((CAtom*)g_oaAtoms[m->m_baAtomIndex[ma1->m_iType]])->m_sName,ma1->m_iNumber+1,(const char*)((CAtom*)g_oaAtoms[m->m_baAtomIndex[ma1->m_iType]])->m_sName,ma1->m_iNumber+1,(strlen((const char*)((CAtom*)g_oaAtoms[m->m_baAtomIndex[ma1->m_iType]])->m_sName)+(((ma1->m_iNumber+1)>9)?2:1))*0.17); } for (z2=0;z2m_oaMolAtoms.GetSize();z2++) { ma1 = (CMolAtom*)sm->m_oaMolAtoms[z2]; if (nohyd && (mystricmp(((CAtom*)g_oaAtoms[m->m_baAtomIndex[ma1->m_iType]])->m_sName,"H")==0)) continue; for (z3=0;z3m_oaBonds.GetSize();z3++) { ma2 = (CMolAtom*)ma1->m_oaBonds[z3]; if (ma2->m_iMolAtomNumber < ma1->m_iMolAtomNumber) continue; if (nohyd && (mystricmp(((CAtom*)g_oaAtoms[m->m_baAtomIndex[ma2->m_iType]])->m_sName,"H")==0)) continue; // Calculate edge weight: C-C is most important if ((mystricmp(((CAtom*)g_oaAtoms[m->m_baAtomIndex[ma1->m_iType]])->m_sName,"C")==0) && (mystricmp(((CAtom*)g_oaAtoms[m->m_baAtomIndex[ma2->m_iType]])->m_sName,"C")==0)) { ti = 10000; tf = 2.0; } else { ti = ((CAtom*)g_oaAtoms[m->m_baAtomIndex[ma1->m_iType]])->m_pElement->m_iOrd * ((CAtom*)g_oaAtoms[m->m_baAtomIndex[ma2->m_iType]])->m_pElement->m_iOrd; tf = 1.0; } if (nohyd) ti = 40; tf = 0.5 + (((ti>80)?80:ti)/80.0*2.0); mfprintf(a," %s%d -- %s%d [weight=%d, penwidth=%f];\n",(const char*)((CAtom*)g_oaAtoms[m->m_baAtomIndex[ma1->m_iType]])->m_sName,ma1->m_iNumber+1,(const char*)((CAtom*)g_oaAtoms[m->m_baAtomIndex[ma2->m_iType]])->m_sName,ma2->m_iNumber+1,ti,tf); } } mfprintf(a,"}\n"); fclose(a); // if (nohyd) // sprintf(buf,"dot mol%d_%s_no_H.dot -Tpng -omol%d_%s_no_H.png -Kneato -Gepsilon=0.000001 -Gnslimit=5000 -Gmclimit=5000",z+1,m->m_sName,z+1,m->m_sName); // else sprintf(buf,"dot mol%d_%s.dot -Tpng -omol%d_%s.png -Kneato -Gepsilon=0.000001 -Gnslimit=5000 -Gmclimit=5000",z+1,m->m_sName,z+1,m->m_sName); if (nohyd) // sprintf(buf,"mol%d_%s_no_H",z+1,m->m_sName); buf.sprintf("mol%d_%s_no_H",z+1,m->m_sName); else // sprintf(buf,"mol%d_%s",z+1,m->m_sName); buf.sprintf("mol%d_%s",z+1,m->m_sName); RenderFormula(buf,tries); mprintf("\n"); if ((!nohyd) && (m->m_iAtomGes > 30) && hex) { nohyd = true; goto _again; } } mprintf(" If the command above worked, you can now view the PNG files that have been created.\n\n"); } void RenderFormula(const char *s, int tries) { int z, zm; char buf[256], buf2[256], *p, *q; double tf, mi, ma, av; FILE *a; // mprintf("%d Tries:\n",tries); zm = -1; av = 0; ma = 0; mi = 1e30; mprintf(" Command: dot %s.dot -Tpng -o%s.png -Kneato -Gepsilon=0.000001 -Gnslimit=5000 -Gmclimit=5000 -v -Gstart=%d\n",s,s,rand()); mprintf(" Optimizing (%d tries): ",tries); mprintf(WHITE,"["); for (z=0;z dot%d.log 2>&1",s,s,z,rand(),z); // mprintf(" (%s)\n",buf); (void)system(buf); sprintf(buf,"dot%d.log",z); a = fopen(buf,"rt"); if (a == NULL) { eprintf("\nRenderFormula(): Error opening %s for reading.\n",buf); eprintf("It seems that GraphViz is not installed or in system path (try command \"dot\" in command line).\n\n"); return; } while (!feof(a)) { (void)fgets(buf,256,a); if (strstr(buf,"final") != NULL) { p = buf; // mprintf(" buf=\"%s\".\n",buf); while (((*p < '0') || (*p > '9')) && (*p != 0)) p++; // mprintf(" p=\"%s\".\n",p); if (*p == 0) continue; q = p; // mprintf(" *p = %d.\n",*p); while (((*p >= '0') && (*p <= '9')) || (*p == '.')) { // mprintf(" *p = %d --> p++;\n",*p); p++; } // mprintf(" p2=\"%s\".\n",p); *p = 0; // mprintf(" q=\"%s\".\n",q); tf = atof(q); // mprintf(" tf = %g.\n",tf); if (tf > ma) ma = tf; if (tf < mi) { mi = tf; zm = z; } av += tf; goto _done; } } eprintf("\nError: Unexpected GraphViz output. See dot%d.log.\n",z); eprintf("It seems that GraphViz is not working properly (try command \"dot\" in command line).\n\n"); return; _done: fclose(a); sprintf(buf,"dot%d.log",z); remove(buf); } mprintf(WHITE,"]\n"); av /= tries; mprintf(" Quality statistics: Min %g, Max %g, Avg %g.\n",mi,ma,av); mprintf(" Using best result to produce output file.\n"); for (z=0;z Core Charge Definition >\n\n"); mprintf(" Please mind pseudopotentials while entering core charges.\n\n"); int i; for (i = 0; i < g_oaAtoms.GetSize(); i++) { if (i == g_iWannierAtomType) continue; if (i == g_iVirtAtomType) continue; double def = 0.0; if (mystricmp(((CAtom *)g_oaAtoms[i])->m_sName, "B") == 0) def = 3.0; else if (mystricmp(((CAtom *)g_oaAtoms[i])->m_sName, "C") == 0) def = 4.0; else if (mystricmp(((CAtom *)g_oaAtoms[i])->m_sName, "N") == 0) def = 5.0; else if (mystricmp(((CAtom *)g_oaAtoms[i])->m_sName, "O") == 0) def = 6.0; else if (mystricmp(((CAtom *)g_oaAtoms[i])->m_sName, "F") == 0) def = 7.0; else if (mystricmp(((CAtom *)g_oaAtoms[i])->m_sName, "Na") == 0) def = 9.0; else if (mystricmp(((CAtom *)g_oaAtoms[i])->m_sName, "Si") == 0) def = 4.0; else if (mystricmp(((CAtom *)g_oaAtoms[i])->m_sName, "P") == 0) def = 5.0; else if (mystricmp(((CAtom *)g_oaAtoms[i])->m_sName, "S") == 0) def = 6.0; else if (mystricmp(((CAtom *)g_oaAtoms[i])->m_sName, "Cl") == 0) def = 7.0; else if (mystricmp(((CAtom *)g_oaAtoms[i])->m_sName, "Br") == 0) def = 7.0; else if (mystricmp(((CAtom *)g_oaAtoms[i])->m_sName, "I") == 0) def = 7.0; else def = (double)((CAtom *)g_oaAtoms[i])->m_pElement->m_iOrd; ((CAtom *)g_oaAtoms[i])->m_fCharge = AskFloat(" Enter core charge for atom type %s: [%.1f] ", def, (const char*)((CAtom*)g_oaAtoms[i])->m_sName, def); } mprintf(WHITE, "\n < End Core Charge Definition <\n"); coreChargesDefined = true; } bool setupWannier() { if(!g_bWannier) { mprintf(WHITE, "\n > Wannier Centers >\n\n"); g_bWannier = true; int watom = -1; int i; for(i = 0; i < g_oaAtoms.GetSize() - 1; i++) { if(((CAtom *)g_oaAtoms[i])->m_bExclude) { watom = i; break; } } if(watom == -1) eprintf(" Atom label of Wannier centers not found.\n\n"); else mprintf(" Atom type %s is excluded from the system, probably these are the Wannier centers.\n\n", (const char*)((CAtom *)g_oaAtoms[watom])->m_sName); bool ok = false; while(!ok) { CxString buf, buf2; buf.sprintf(" Which atom label do the wannier centers have ("); for(i = 0; i < g_oaAtoms.GetSize() - 1; i++) { buf2.sprintf("%s", (const char*)((CAtom *)g_oaAtoms[i])->m_sName); buf.strcat(buf2); if(i < g_oaAtoms.GetSize() - 2) { buf2.sprintf(", "); buf.strcat(buf2); } } buf2.sprintf(")? "); buf.strcat(buf2); if(watom != -1) { buf2.sprintf("[%s] ", (const char*)((CAtom *)g_oaAtoms[watom])->m_sName); buf.strcat(buf2); } if(watom == -1) AskString_ND("%s", &buf2, (const char*)buf); else AskString("%s", &buf2, ((CAtom *)g_oaAtoms[watom])->m_sName, (const char*)buf); for(i = 0; i < g_oaAtoms.GetSize() - 1; i++) { if(mystricmp(buf2, ((CAtom *)g_oaAtoms[i])->m_sName) == 0) { g_iWannierAtomType = i; ok = true; break; } } if(!ok) { eprintf(" Invalid input.\n"); inpprintf("! Invalid input.\n"); } } g_fWannierCharge = fabs(AskFloat("\n Enter the negative charge of the Wannier centers (without sign): [2.0] ", 2.0)); parseCoreCharges(); mprintf("\n"); if(!g_TimeStep.ScanWannier(true)) { eprintf("\n Setup of Wannier centers failed.\n"); return false; } mprintf(WHITE, "\n < End Wannier Centers <\n"); } return true; } static void setupFluctuatingCharges() { if ((!g_bReadChargesFrom4thXYZ) && (!g_bReadLAMMPSCharges)) { if (g_bXYZ4thCol) g_bReadChargesFrom4thXYZ = true; if (g_bLAMMPSCharge) g_bReadLAMMPSCharges = true; mprintf(WHITE, "\n > Fluctuating Atomic Partial Charges >\n"); FILE *a; int z, z2, z3, z4; double tf; CMolecule *m; CSingleMolecule *sm; mprintf("\n Trying to read charges from first time step...\n"); a = fopen(g_sInputTraj,"rb"); if (a == NULL) { eprintf("setupFluctuatingCharges(): Error: Could not open \"%s\" for reading.\n",g_sInputTraj); abort(); } if (!g_TimeStep.ReadTimestep(a,true)) { eprintf("setupFluctuatingCharges(): Error: Could not read first time step of \"%s\".\n",g_sInputTraj); abort(); } fclose(a); mprintf("\n Uniting molecules which have been broken by wrapping...\n"); g_TimeStep.UniteMolecules(true); g_TimeStep.CalcCenters(); mprintf("\n Found the following atomic charges:\n\n"); for (z=0;zm_bChargesAssigned = true; for (z2=0;z2m_baAtomIndex.GetSize();z2++) { if (m->m_baAtomIndex[z2] == g_iVirtAtomType) continue; for (z3=0;z3m_waAtomCount[z2];z3++) { for (z4=0;z4m_laSingleMolIndex.GetSize();z4++) { sm = (CSingleMolecule*)g_oaSingleMolecules[m->m_laSingleMolIndex[z4]]; mprintf(" %s[%d] %s%d: %8.6f\n",m->m_sName,z4+1,(const char*)((CAtom*)g_oaAtoms[m->m_baAtomIndex[z2]])->m_sName,z3+1,g_TimeStep.m_faCharge[((CxIntArray*)sm->m_oaAtomOffset[z2])->GetAt(z3)]); } } } } mprintf("\n Total charges of the molecules:\n\n"); for (z=0;zm_laSingleMolIndex.GetSize();z4++) { sm = (CSingleMolecule*)g_oaSingleMolecules[m->m_laSingleMolIndex[z4]]; tf = 0; for (z2=0;z2m_baAtomIndex.GetSize();z2++) { if (m->m_baAtomIndex[z2] == g_iVirtAtomType) continue; for (z3=0;z3m_waAtomCount[z2];z3++) tf += g_TimeStep.m_faCharge[((CxIntArray*)sm->m_oaAtomOffset[z2])->GetAt(z3)]; } mprintf(" %s[%d]: Total charge is %8.6f.\n",m->m_sName,z4+1,tf); if (z4 == 0) m->m_fCharge = tf; } } mprintf(WHITE, "\n < End Fluctuating Atomic Partial Charges <\n"); } } static void setupDipoleRestartFile() { if (!g_bLoadDipoleRestart) { mprintf(WHITE, "\n > Dipole Restart File >\n\n"); g_bLoadDipoleRestart = true; while (true) { CxString filename; AskString(" Enter name of dipole restart file: [dipole.restart] ", &filename, "dipole.restart"); g_fDipoleRestartFile = fopen((const char *)filename, "r"); if (g_fDipoleRestartFile == NULL) { eprintf(" Could not open \"%s\": %s.\n\n", (const char *)filename, strerror(errno)); continue; } int numMolecules; (void)fread(&numMolecules, sizeof(int), 1, g_fDipoleRestartFile); if (numMolecules != g_oaSingleMolecules.GetSize()) { eprintf(" This dipole restart file was written for a different number of molecules.\n\n"); continue; } break; } mprintf(WHITE, "\n < End Dipole Restart File <\n"); } } static void setupMagneticDipoleRestartFile() { if (!g_bLoadMagneticDipoleRestart) { mprintf(WHITE, "\n > Magnetic Moment Restart File >\n\n"); g_bLoadMagneticDipoleRestart = true; while (true) { CxString filename; AskString(" Enter name of magnetic moment restart file: [magnetic.restart] ", &filename, "magnetic.restart"); g_fMagneticDipoleRestartFile = fopen((const char *)filename, "r"); if (g_fMagneticDipoleRestartFile == NULL) { eprintf(" Could not open \"%s\": %s.\n\n", (const char *)filename, strerror(errno)); continue; } int numMolecules; (void)fread(&numMolecules, sizeof(int), 1, g_fMagneticDipoleRestartFile); if (numMolecules != g_oaSingleMolecules.GetSize()) { eprintf(" This magnetic moment restart file was written for a different number of molecules.\n\n"); continue; } break; } mprintf(WHITE, "\n < End Magnetic Moment Restart File <\n"); } } void ParseDipole() { if (g_bDipoleDefined) return; g_bDipole = true; if (g_bTegri && (g_pTetraPak == NULL)) { try { g_pVoroWrapper = new CVoroWrapper(); } catch(...) { g_pVoroWrapper = NULL; } if (g_pVoroWrapper == NULL) NewException((double)sizeof(CVoroWrapper),__FILE__,__LINE__,__PRETTY_FUNCTION__); try { g_pTetraPak = new CTetraPak(); } catch(...) { g_pTetraPak = NULL; } if (g_pTetraPak == NULL) NewException((double)sizeof(CTetraPak),__FILE__,__LINE__,__PRETTY_FUNCTION__); g_pTetraPak->Parse(); } mprintf(WHITE, "\n>>> Dipole Definition >>>\n\n"); if(g_bAdvanced2) { g_bDipoleRefFixed = AskYesNo(" Use a box-fixed reference point for dipole calculation (y/n)? [no] ", false); mprintf("\n\n"); } else { g_bDipoleRefFixed = false; } mprintf(" There are the following possibilities to provide dipole moments:\n"); mprintf(" (1) Calculate dipole moments from Wannier centers\n (These need to be atoms in the trajectory)\n"); mprintf(" (2) Read dipole moments from an external file\n (This file is expected to contain one line per timestep\n with the three dipole vector components separated by spaces)\n"); mprintf(" (3) Read dipole moments from the trajectory file\n (These need to be specified in the comment line)\n"); mprintf(" (4) Calculate dipole moments from fixed atomic partial charges\n"); mprintf(" (5) Calculate dipole moments from fluctuating atomic partial charges\n (These need to be in the fourth column of the trajectory)\n"); mprintf(" (6) Calculate dipole moments from Voronoi partial charges\n (This requires volumetric electron density data)\n"); mprintf(" (7) Calculate Voronoi dipole moments\n (This requires volumetric electron density data)\n"); mprintf(" (8) Load a dipole restart file\n"); mprintf("\n"); mprintf(" The following dipole modes can be set for all molecules at once: 1, 5, 6, 7, 8\n"); while (true) { int globalMode = AskRangeInteger(" Which dipole mode to set for all molecules at once? [none] ", 0, 8, 0); if (globalMode == 0) { int i; for (i = 0; i < g_oaMolecules.GetSize(); i++) ((CMolecule *)g_oaMolecules[i])->m_iDipoleMode = 0; break; } else if (globalMode == 1) { if (setupWannier()) { int i; for (i = 0; i < g_oaMolecules.GetSize(); i++) ((CMolecule *)g_oaMolecules[i])->m_iDipoleMode = 1; break; } continue; } else if (globalMode == 2) { eprintf("\n This mode cannot be set for all molecules at once.\n\n"); continue; } else if (globalMode == 3) { eprintf("\n This mode cannot be set for all molecules at once.\n\n"); continue; } else if (globalMode == 4) { eprintf("\n This mode cannot be set for all molecules at once.\n\n"); continue; } else if (globalMode == 5) { if (g_bXYZ4thCol || g_bLAMMPSCharge) { setupFluctuatingCharges(); int i; for (i = 0; i < g_oaMolecules.GetSize(); i++) ((CMolecule *)g_oaMolecules[i])->m_iDipoleMode = 5; break; } eprintf("\n The trajectory does not have a fourth column.\n\n"); continue; } else if (globalMode == 6) { if (!g_bVolumetricData) { eprintf("\n This requires volumetric electron density data in each step of the trajectory (.cube or .bqb).\n\n"); continue; } if (g_bTegri) { g_bVoroIntegrateCharge = true; parseCoreCharges(); int i; for (i = 0; i < g_oaMolecules.GetSize(); i++) { int rty; ParseAtom("#2", i, ((CMolecule *)g_oaMolecules[i])->m_iDipoleCenterType, rty, ((CMolecule *)g_oaMolecules[i])->m_iDipoleCenterIndex); ((CMolecule *)g_oaMolecules[i])->m_iDipoleMode = 6; } break; } eprintf("\n Voronoi integration needs to be active. Use \"vori\" in the main menu.\n\n"); continue; } else if (globalMode == 7) { if (!g_bVolumetricData) { eprintf("\n This requires volumetric electron density data in each step of the trajectory (.cube or .bqb).\n\n"); continue; } if (g_bTegri) { if (!g_pTetraPak->m_bVoronoiCharges) { eprintf("\n Error: You need to activate \"Voronoi integration\" (question above).\n\n"); continue; } g_bVoroIntegrateCharge = true; g_bVoroIntegrateDipoleMoment = true; mprintf("\n"); g_bVoroIntegrateQuadrupoleMoment = AskYesNo(" Also activate quadrupole integration (y/n)? [no] ",false); parseCoreCharges(); int i; for (i = 0; i < g_oaMolecules.GetSize(); i++) { int rty; ParseAtom("#2", i, ((CMolecule *)g_oaMolecules[i])->m_iDipoleCenterType, rty, ((CMolecule *)g_oaMolecules[i])->m_iDipoleCenterIndex); ((CMolecule *)g_oaMolecules[i])->m_iDipoleMode = 7; } break; } eprintf("\n Voronoi integration needs to be active. Use \"vori\" in the main menu.\n\n"); continue; } else if (globalMode == 8) { setupDipoleRestartFile(); int i; for (i = 0; i < g_oaMolecules.GetSize(); i++) ((CMolecule *)g_oaMolecules[i])->m_iDipoleMode = 8; break; } eprintf("\n Error: Invalid input.\n\n"); } while (true) { mprintf("\n The following dipole modes are set up:\n\n"); int longest = 0; int i; for (i = 0; i < g_oaMolecules.GetSize(); i++) { int length = (int)strlen(((CMolecule *)g_oaMolecules[i])->m_sName); if (length > longest) longest = length; } CxString buf; buf.sprintf(" %%%ds - %%d", longest); for (i = 0; i < g_oaMolecules.GetSize(); i++) { mprintf(buf, ((CMolecule *)g_oaMolecules[i])->m_sName, ((CMolecule *)g_oaMolecules[i])->m_iDipoleMode); if (((CMolecule *)g_oaMolecules[i])->m_iDipoleMode == 0) mprintf(" (none)\n"); else if (((CMolecule *)g_oaMolecules[i])->m_iDipoleMode == 1) mprintf(" (Wannier centers)\n"); else if (((CMolecule *)g_oaMolecules[i])->m_iDipoleMode == 2) mprintf(" (external file)\n"); else if (((CMolecule *)g_oaMolecules[i])->m_iDipoleMode == 3) mprintf(" (trajectory comment line)\n"); else if (((CMolecule *)g_oaMolecules[i])->m_iDipoleMode == 4) mprintf(" (fixed atomic partial charges)\n"); else if (((CMolecule *)g_oaMolecules[i])->m_iDipoleMode == 5) mprintf(" (fluctuating atomic partial charges)\n"); else if (((CMolecule *)g_oaMolecules[i])->m_iDipoleMode == 6) mprintf(" (Voronoi partial charges)\n"); else if (((CMolecule *)g_oaMolecules[i])->m_iDipoleMode == 7) mprintf(" (Voronoi dipole moments)\n"); else if (((CMolecule *)g_oaMolecules[i])->m_iDipoleMode == 8) mprintf(" (restart file)\n"); else mprintf("\n"); } mprintf("\n"); if (!AskYesNo(" Change dipole mode for a molecule (y/n)? [no] ", false)) break; int mol; if (g_oaMolecules.GetSize() > 1) { buf.sprintf(" Change dipole mode for which molecule ("); for (i = 0; i < g_oaMolecules.GetSize(); i++) { CxString buf2; buf2.sprintf("%s=%d", ((CMolecule *)g_oaMolecules[i])->m_sName, i + 1); buf.strcat(buf2); if(i < g_oaMolecules.GetSize() - 1) { buf.strcat(", "); } } buf.strcat(")? "); mol = AskRangeInteger_ND("%s", 1, g_oaMolecules.GetSize(), (const char*)buf) - 1; } else { mol = 0; } int mode = AskRangeInteger_ND(" Which dipole mode to set for molecule %s? ", 1, 8, ((CMolecule *)g_oaMolecules[mol])->m_sName); if (mode == 0) { ((CMolecule *)g_oaMolecules[mol])->m_iDipoleMode = 0; } else if (mode == 1) { if (setupWannier()) { ((CMolecule *)g_oaMolecules[mol])->m_iDipoleMode = 1; } } else if (mode == 2) { FILE *dipoleFile = NULL; while (true) { if(dipoleFile != NULL) { fclose(dipoleFile); dipoleFile = NULL; } AskString_ND(" Name of file for dipole moments: ", &buf); mprintf("\n Trying to read first line...\n\n"); dipoleFile = fopen(buf, "r"); if(dipoleFile == NULL) { eprintf(" Could not open \"%s\".\n\n", (const char*)buf); continue; } if (buf.fgets(1024, dipoleFile) == NULL) { eprintf(" Could not read first line.\n\n"); continue; } double dipole[3]; if(sscanf((const char *)buf, "%lf %lf %lf", &dipole[0], &dipole[1], &dipole[2]) < 3) { eprintf(" Could not find three real numbers in first line.\n\n"); continue; } mprintf(" Found the following dipole moment in the first line:\n"); mprintf(" ( %8G | %8G | %8G ) Debye\n", dipole[0], dipole[1], dipole[2]); rewind(dipoleFile); break; } ((CMolecule *)g_oaMolecules[mol])->m_iDipoleMode = 2; ((CMolecule *)g_oaMolecules[mol])->m_pDipoleFile = dipoleFile; if(((CMolecule *)g_oaMolecules[mol])->m_laSingleMolIndex.GetSize() > 1) eprintf("\n Warning: There are several molecules %s. The same dipole moment will be used for all of them.\n", ((CMolecule *)g_oaMolecules[mol])->m_sName); } else if (mode == 3) { CxString comment; comment.strcpy(g_TimeStep.m_pComment); mprintf(" The comment line is \"%s\".\n", (const char *)comment); buf = ""; const char delim[] = "\t "; char *tok = strtok(comment.GetWritePointer(), delim); int num = 0; while(tok != NULL) { double f; if(sscanf(tok, "%lf", &f) == 1) { CxString buf2; num++; if(num > 1) { buf2.sprintf(", %s (%d)", tok, num); } else { buf2.sprintf("%s (%d)", tok, num); } buf.strcat(buf2); } tok = strtok(NULL, delim); } ((CMolecule *)g_oaMolecules[mol])->m_iDipoleCommentIndex[0] = AskRangeInteger(" Choose the X dipole component: %s [1] ", 1, num, 1, (const char *)buf) - 1; ((CMolecule *)g_oaMolecules[mol])->m_iDipoleCommentIndex[1] = AskRangeInteger(" Choose the Y dipole component: %s [1] ", 1, num, 1, (const char *)buf) - 1; ((CMolecule *)g_oaMolecules[mol])->m_iDipoleCommentIndex[2] = AskRangeInteger(" Choose the Z dipole component: %s [1] ", 1, num, 1, (const char *)buf) - 1; ((CMolecule *)g_oaMolecules[mol])->m_iDipoleMode = 3; if(((CMolecule *)g_oaMolecules[mol])->m_laSingleMolIndex.GetSize() > 1) eprintf("\n Warning: There are several molecules %s. The same dipole moment will be used for all of them.\n", ((CMolecule *)g_oaMolecules[mol])->m_sName); } else if (mode == 4) { CMolecule *m = (CMolecule*)g_oaMolecules[mol]; CSingleMolecule *sm = (CSingleMolecule*)g_oaSingleMolecules[m->m_laSingleMolIndex[0]]; m->m_bChargesAssigned = true; int z2, z3, ti; CMolAtom *ma; CxDoubleArray *tfa; bool b; double tf; double td; CxString buf2; for (z2=0;z2m_baAtomIndex.GetSize();z2++) { mprintf("\n"); ma = NULL; td = 1.0e50; try { tfa = new CxDoubleArray("ParseDipole():tfa"); } catch(...) { tfa = NULL; } if (tfa == NULL) NewException((double)sizeof(CxDoubleArray),__FILE__,__LINE__,__PRETTY_FUNCTION__); m->m_oaCharges.Add(tfa); _cnm: buf = ""; buf2 = ""; b = false; ti = 0; for (z3=0;z3m_oaMolAtoms.GetSize();z3++) { if (((CMolAtom*)sm->m_oaMolAtoms[z3])->m_iType != z2) continue; ma = (CMolAtom*)sm->m_oaMolAtoms[z3]; if (ma->m_fAtomCode > td) { continue; } if (b) { if (ma->m_fAtomCode < td) { continue; } ti++; buf2.sprintf(", %s%d",(const char*)((CAtom*)g_oaAtoms[m->m_baAtomIndex[z2]])->m_sName,ma->m_iNumber+1); buf.strcat(buf2); } else { if (ma->m_fAtomCode < td) { td = ma->m_fAtomCode; } buf.sprintf(" Enter partial atomic charge on %s%d",(const char*)((CAtom*)g_oaAtoms[m->m_baAtomIndex[z2]])->m_sName,ma->m_iNumber+1); b = true; ti++; } } if (b) { buf.strcat(": [0.0] "); tf = AskFloat("%s",0, (const char*)buf); for (z3=0;z3Add(tf); td -= 1.0; goto _cnm; } } tf = 0; for (z2=0;z2m_baAtomIndex.GetSize();z2++) { for (z3=0;z3<((CxDoubleArray*)m->m_oaCharges[z2])->GetSize();z3++) { mprintf(" %s%d: %7.4f\n",(const char*)((CAtom*)g_oaAtoms[m->m_baAtomIndex[z2]])->m_sName,z3+1,((CxDoubleArray*)m->m_oaCharges[z2])->GetAt(z3)); tf += ((CxDoubleArray*)m->m_oaCharges[z2])->GetAt(z3); } } m->m_fCharge = tf; mprintf(WHITE,"\n Molecule %s: Total charge is %.4f.\n\n",m->m_sName,m->m_fCharge); ((CMolecule *)g_oaMolecules[mol])->m_iDipoleMode = 4; } else if (mode == 5) { if (g_bXYZ4thCol || g_bLAMMPSCharge) { setupFluctuatingCharges(); ((CMolecule *)g_oaMolecules[mol])->m_iDipoleMode = 5; } eprintf(" The trajectory does not have a fourth column.\n"); } else if (mode == 6) { if (g_bTegri) { g_bVoroIntegrateCharge = true; parseCoreCharges(); int rty; ParseAtom("#2", mol, ((CMolecule *)g_oaMolecules[mol])->m_iDipoleCenterType, rty, ((CMolecule *)g_oaMolecules[mol])->m_iDipoleCenterIndex); ((CMolecule *)g_oaMolecules[mol])->m_iDipoleMode = 6; } else { eprintf(" Voronoi integration needs to be active. Use \"vori\" in the main menu.\n"); } } else if (mode == 7) { if (g_bTegri) { g_bVoroIntegrateCharge = true; g_bVoroIntegrateDipoleMoment = true; parseCoreCharges(); int rty; ParseAtom("#2", mol, ((CMolecule *)g_oaMolecules[mol])->m_iDipoleCenterType, rty, ((CMolecule *)g_oaMolecules[mol])->m_iDipoleCenterIndex); ((CMolecule *)g_oaMolecules[mol])->m_iDipoleMode = 7; } else { eprintf(" Voronoi integration needs to be active. Use \"vori\" in the main menu.\n"); } } else if (mode == 8) { setupDipoleRestartFile(); ((CMolecule *)g_oaMolecules[mol])->m_iDipoleMode = 8; } else { eprintf(" This is impossible.\n"); } } if (!g_bDipoleRefFixed) { int i; for (i = 0; i < g_oaMolecules.GetSize(); i++) { if (fabs(((CMolecule *)g_oaMolecules[i])->m_fCharge) > 0.001) { mprintf("\n"); mprintf(" Molecule %s is charged (%.4f). Input of a dipole reference point is required.\n",((CMolecule *)g_oaMolecules[i])->m_sName, ((CMolecule *)g_oaMolecules[i])->m_fCharge); int rty; CxString buf; do { AskString(" Please enter dipole reference point: [#2] ", &buf, "#2"); } while (!ParseAtom(buf, i, ((CMolecule *)g_oaMolecules[i])->m_iDipoleCenterType, rty, ((CMolecule *)g_oaMolecules[i])->m_iDipoleCenterIndex)); } } } mprintf("\n"); // CxString buf, buf2, comment; // // // const int BUF_SIZE = 1024; // // if (g_bDipoleDefined) // return; // // // if(g_bAdvanced2) { // g_bDipoleRefFixed = AskYesNo(" Use a box-fixed reference point for dipole calculation (y/n)? [no] ", false); // mprintf("\n"); // } else { // g_bDipoleRefFixed = false; // } // // mprintf(WHITE, "\n>>> Dipole Definition >>>\n\n"); // mprintf(" There are different ways to provide dipole moments in TRAVIS:\n"); // mprintf(" (1) Calculate dipole moments from Wannier centers\n (These need to be atoms in the trajectory)\n"); // mprintf(" (2) Read dipole moments from an external file\n (This file is expected to contain one line per timestep\n with the three dipole vector components separated by spaces)\n"); // mprintf(" (3) Read dipole moments from the trajectory file\n (These need to be specified in the comment line)\n"); // mprintf(" (4) Calculate dipole moments from fixed atomic partial charges\n"); // mprintf(" (5) Calculate dipole moments from fluctuating atomic partial charges\n (These need to be in the fourth column of the trajectory)\n"); // mprintf(" (8) Load dipole moments from a dipole restart file\n"); // mprintf("\n"); // // while(true) { // // char buf[BUF_SIZE]; // // char buf2[BUF_SIZE]; // // size_t remaining = BUF_SIZE; // int mol; // if(g_oaMolecules.GetSize() > 1) { // /*#ifdef TARGET_LINUX // remaining -= snprintf(buf, remaining, " Add dipole information for which molecule ("); // #else // remaining -= sprintf(buf, " Add dipole information for which molecule ("); // #endif*/ // // buf.sprintf(" Add dipole information for which molecule ("); // // int i; // for(i = 0; i < g_oaMolecules.GetSize(); i++) { // // /* if(remaining < 1) // break; // #ifdef TARGET_LINUX // size_t length = snprintf(buf2, remaining, "%s=%d", ((CMolecule *)g_oaMolecules[i])->m_sName, i+1); // #else // size_t length = sprintf(buf2, "%s=%d", ((CMolecule *)g_oaMolecules[i])->m_sName, i+1); // #endif // strncat(buf, buf2, remaining - 1); // remaining -= length;*/ // // buf2.sprintf("%s=%d", ((CMolecule *)g_oaMolecules[i])->m_sName, i+1); // buf.strcat(buf2); // // if(i < g_oaMolecules.GetSize() - 1) { // /*#ifdef TARGET_LINUX // length = snprintf(buf2, remaining, ", "); // #else // length = sprintf(buf2, ", "); // #endif // strncat(buf, buf2, remaining - 1); // remaining -= length;*/ // // buf2.sprintf(", "); // buf.strcat(buf2); // } // } // // strncat(buf, ")? ", remaining - 1); // buf.strcat(")? "); // // mol = AskRangeInteger_ND(buf, 1, g_oaMolecules.GetSize()) - 1; // } else { // mol = 0; // } // // int mode; // // { // if(g_bXYZ4thCol) // mode = AskRangeInteger("\n Use Wannier centers (1), external file (2), comment line (3), fixed charges (4), or fluctuating charges (5) for molecule %s? [1] ", 1, 5, 1, ((CMolecule *)g_oaMolecules[mol])->m_sName); // else // mode = AskRangeInteger("\n Use Wannier centers (1), external file (2), comment line (3), or fixed charges (4) for molecule %s? [1] ", 1, 4, 1, ((CMolecule *)g_oaMolecules[mol])->m_sName); // } // mprintf("\n"); // // if(mode == 1) { // if(!g_bWannier) { // mprintf(WHITE, " > Wannier Centers >\n\n"); // g_bWannier = true; // int watom = -1; // int i; // for(i = 0; i < g_oaAtoms.GetSize() - 1; i++) { // if(((CAtom *)g_oaAtoms[i])->m_bExclude) { // watom = i; // break; // } // } // if(watom == -1) // eprintf(" Atom label of Wannier centers not found.\n\n"); // else // mprintf(" Atom type %s is excluded from the system, probably these are the Wannier centers.\n\n", ((CAtom *)g_oaAtoms[watom])->m_sName); // // bool ok = false; // while(!ok) { // /* remaining = BUF_SIZE; // #ifdef TARGET_LINUX // remaining -= snprintf(buf, remaining, " Which atom label do the wannier centers have ("); // #else // remaining -= sprintf(buf, " Which atom label do the wannier centers have ("); // #endif*/ // // buf.sprintf(" Which atom label do the wannier centers have ("); // // for(i = 0; i < g_oaAtoms.GetSize() - 1; i++) { // // /* if(remaining < 1) // break; // #ifdef TARGET_LINUX // size_t length = snprintf(buf2, remaining, "%s", ((CAtom *)g_oaAtoms[i])->m_sName); // #else // size_t length = sprintf(buf2, "%s", ((CAtom *)g_oaAtoms[i])->m_sName); // #endif // strncat(buf, buf2, remaining - 1); // remaining -= length;*/ // // buf2.sprintf("%s", ((CAtom *)g_oaAtoms[i])->m_sName); // buf.strcat(buf2); // // if(i < g_oaAtoms.GetSize() - 2) { // /*#ifdef TARGET_LINUX // length = snprintf(buf2, remaining, ", "); // #else // length = sprintf(buf2, ", "); // #endif // strncat(buf, buf2, remaining - 1); // remaining -= length;*/ // // buf2.sprintf(", "); // buf.strcat(buf2); // } // } // // /*#ifdef TARGET_LINUX // size_t length = snprintf(buf2, remaining, ")? "); // #else // size_t length = sprintf(buf2, ")? "); // #endif // strncat(buf, buf2, remaining - 1); // remaining -= length;*/ // // buf2.sprintf(")? "); // buf.strcat(buf2); // // if(watom != -1) { // /*#ifdef TARGET_LINUX // snprintf(buf2, remaining, "[%s] ", ((CAtom *)g_oaAtoms[watom])->m_sName); // #else // sprintf(buf2, "[%s] ", ((CAtom *)g_oaAtoms[watom])->m_sName); // #endif // strncat(buf, buf2, remaining - 1);*/ // // buf2.sprintf("[%s] ", ((CAtom *)g_oaAtoms[watom])->m_sName); // buf.strcat(buf2); // } // // if(watom == -1) // AskString_ND(buf, &buf2); // else // AskString(buf, &buf2, ((CAtom *)g_oaAtoms[watom])->m_sName); // // for(i = 0; i < g_oaAtoms.GetSize() - 1; i++) { // if(mystricmp(buf2, ((CAtom *)g_oaAtoms[i])->m_sName) == 0) { // g_iWannierAtomType = i; // ok = true; // break; // } // } // if(!ok) { // eprintf(" Wrong input.\n"); // inpprintf("! Wrong input.\n"); // } // } // // g_fWannierCharge = fabs(AskFloat("\n Enter the negative charge of the Wannier centers (without sign): [2.0] ", 2.0f)); // for(i = 0; i < g_oaAtoms.GetSize() - 1; i++) { // if(i == g_iWannierAtomType) // continue; // if(i == g_iVirtAtomType) // continue; // double def; // if(mystricmp(((CAtom *)g_oaAtoms[i])->m_sName, "B") == 0) def = 3.0f; // else if(mystricmp(((CAtom *)g_oaAtoms[i])->m_sName, "C") == 0) def = 4.0f; // else if(mystricmp(((CAtom *)g_oaAtoms[i])->m_sName, "N") == 0) def = 5.0f; // else if(mystricmp(((CAtom *)g_oaAtoms[i])->m_sName, "O") == 0) def = 6.0f; // else if(mystricmp(((CAtom *)g_oaAtoms[i])->m_sName, "F") == 0) def = 7.0f; // else if(mystricmp(((CAtom *)g_oaAtoms[i])->m_sName, "Si") == 0) def = 4.0f; // else if(mystricmp(((CAtom *)g_oaAtoms[i])->m_sName, "P") == 0) def = 5.0f; // else if(mystricmp(((CAtom *)g_oaAtoms[i])->m_sName, "S") == 0) def = 6.0f; // else if(mystricmp(((CAtom *)g_oaAtoms[i])->m_sName, "Cl") == 0) def = 7.0f; // else if(mystricmp(((CAtom *)g_oaAtoms[i])->m_sName, "Br") == 0) def = 7.0f; // else if(mystricmp(((CAtom *)g_oaAtoms[i])->m_sName, "I") == 0) def = 7.0f; // else def = (double)((CAtom *)g_oaAtoms[i])->m_pElement->m_iOrd; // ((CAtom *)g_oaAtoms[i])->m_fCharge = AskFloat(" Enter core charge (mind pseudopotentials!) for atom type %s: [%.1f] ", def, ((CAtom*)g_oaAtoms[i])->m_sName, def); // } // mprintf("\n"); // if(!g_TimeStep.ScanWannier(true)) { // eprintf("\n No dipole information for molecule %s added.\n", ((CMolecule *)g_oaMolecules[mol])->m_sName); // } // mprintf(WHITE, "\n < End Wannier Centers <\n\n"); // } // ((CMolecule *)g_oaMolecules[mol])->m_iDipoleMode = 1; // mprintf(" Set dipole information for %s to Wannier centers.\n", ((CMolecule *)g_oaMolecules[mol])->m_sName); // } else if(mode == 2) { // FILE *dipoleFile = NULL; // while(true) { // if(dipoleFile != NULL) { // fclose(dipoleFile); // dipoleFile = NULL; // } // AskString_ND(" Name of file for dipole moments: ", &buf); // mprintf("\n Trying to read first line...\n\n"); // dipoleFile = fopen(buf, "r"); // if(dipoleFile == NULL) { // eprintf(" Could not open \"%s\".\n\n", (const char*)buf); // continue; // } // // if(fgets(buf, BUF_SIZE, dipoleFile) == NULL) { // if (buf.fgets(1024, dipoleFile) == NULL) { // eprintf(" Could not read first line.\n\n"); // continue; // } // double dipole[3]; // if(sscanf(buf, "%f %f %f", &dipole[0], &dipole[1], &dipole[2]) < 3) { // eprintf(" Could not find three real numbers in first line.\n\n"); // continue; // } // mprintf(" Found the following dipole moment in the first line:\n"); // mprintf(" ( %8G | %8G | %8G ) Debye\n", dipole[0], dipole[1], dipole[2]); // rewind(dipoleFile); // break; // } // ((CMolecule *)g_oaMolecules[mol])->m_iDipoleMode = 2; // mprintf("\n Set dipole information for %s to external file.\n", ((CMolecule *)g_oaMolecules[mol])->m_sName); // ((CMolecule *)g_oaMolecules[mol])->m_pDipoleFile = dipoleFile; // if(((CMolecule *)g_oaMolecules[mol])->m_laSingleMolIndex.GetSize() > 1) // eprintf("\n Warning: There are several molecules %s. The same dipole moment will be used for all of them.\n", ((CMolecule *)g_oaMolecules[mol])->m_sName); // } else if(mode == 3) { // // char comment[BUF_SIZE]; // // strncpy(comment, g_TimeStep.m_pComment, BUF_SIZE); // // comment[BUF_SIZE-1] = '\0'; // comment.strcpy(g_TimeStep.m_pComment); // mprintf(" The comment line is \"%s\".\n", (const char*)comment); // // char buf[BUF_SIZE]; // // buf[0] = '\0'; // // size_t remaining = BUF_SIZE; // buf.sprintf(""); // const char delim[] = "\t "; // char *tok = strtok(comment.GetWritePointer(), delim); // int num = 0; // while(tok != NULL) { // double f; // if(sscanf(tok, "%f", &f) == 1) { // num++; // // char buf2[BUF_SIZE]; // // size_t length; // if(num > 1) { // /*#ifdef TARGET_LINUX // length = snprintf(buf2, BUF_SIZE, ", %s (%d)", tok, num); // #else // length = sprintf(buf2, ", %s (%d)", tok, num); // #endif*/ // buf2.sprintf(", %s (%d)", tok, num); // } else { // /*#ifdef TARGET_LINUX // length = snprintf(buf2, BUF_SIZE, "%s (%d)", tok, num); // #else // length = sprintf(buf2, "%s (%d)", tok, num); // #endif*/ // buf2.sprintf("%s (%d)", tok, num); // } // // strncat(buf, buf2, remaining - 1); // buf.strcat(buf2); // /* remaining -= length; // if(remaining < 1) // break;*/ // } // tok = strtok(NULL, delim); // } // ((CMolecule *)g_oaMolecules[mol])->m_iDipoleCommentIndex[0] = AskRangeInteger(" Choose the X dipole component: %s [1] ", 1, num, 1, (const char*)buf) - 1; // ((CMolecule *)g_oaMolecules[mol])->m_iDipoleCommentIndex[1] = AskRangeInteger(" Choose the Y dipole component: %s [1] ", 1, num, 1, (const char*)buf) - 1; // ((CMolecule *)g_oaMolecules[mol])->m_iDipoleCommentIndex[2] = AskRangeInteger(" Choose the Z dipole component: %s [1] ", 1, num, 1, (const char*)buf) - 1; // ((CMolecule *)g_oaMolecules[mol])->m_iDipoleMode = 3; // mprintf("\n Set dipole information for %s to comment line.\n", ((CMolecule *)g_oaMolecules[mol])->m_sName); // if(((CMolecule *)g_oaMolecules[mol])->m_laSingleMolIndex.GetSize() > 1) // eprintf("\n Warning: There are several molecules %s. The same dipole moment will be used for all of them.\n", ((CMolecule *)g_oaMolecules[mol])->m_sName); // } else if(mode == 4) { // CMolecule *m = (CMolecule*)g_oaMolecules[mol]; // CSingleMolecule *sm = (CSingleMolecule*)g_oaSingleMolecules[m->m_laSingleMolIndex[0]]; // m->m_bChargesAssigned = true; // int z2, z3, ti; // CMolAtom *ma; // CxFloatArray *tfa; // bool b; // double tf; // double td; // for (z2=0;z2m_baAtomIndex.GetSize();z2++) // { // mprintf("\n"); // // mprintf("%s Anfang.\n",((CAtom*)g_oaAtoms[m->m_baAtomIndex[z2]])->m_sName); // ma = NULL; // td = 1.0e50; // // try { tfa = new CxFloatArray("ParseDipole():tfa"); } catch(...) { tfa = NULL; } // if (tfa == NULL) NewException((double)sizeof(CxFloatArray),__FILE__,__LINE__,__PRETTY_FUNCTION__); // // m->m_oaCharges.Add(tfa); // _cnm: // // buf[0] = 0; // // buf2[0] = 0; // buf.sprintf(""); // buf2.sprintf(""); // b = false; // ti = 0; // // mprintf("D.\n"); // for (z3=0;z3m_oaMolAtoms.GetSize();z3++) // { // // mprintf("z3=%d.\n",z3); // if (((CMolAtom*)sm->m_oaMolAtoms[z3])->m_iType != z2) // continue; // // ma = (CMolAtom*)sm->m_oaMolAtoms[z3]; // // // mprintf("AtomType %s, z3=%d, td=%f, ac=%f.\n",((CAtom*)g_oaAtoms[m->m_baAtomIndex[z2]])->m_sName,z3,td,ma->m_fAtomCode); // // if (ma->m_fAtomCode > td) // { // // mprintf(" AtomCode = %f > %f = td. Skip.\n",ma->m_fAtomCode,td); // continue; // } // if (b) // { // if (ma->m_fAtomCode < td) // { // // mprintf(" AtomCode = %f < %f = td. Skip.\n",ma->m_fAtomCode,td); // continue; // } // ti++; // // mprintf(" Taking %s%d into account.\n",((CAtom*)g_oaAtoms[m->m_baAtomIndex[z2]])->m_sName,ma->m_iNumber+1); // // // sprintf(buf2,", %s%d",((CAtom*)g_oaAtoms[m->m_baAtomIndex[z2]])->m_sName,ma->m_iNumber+1); // // strcat(buf,buf2); // // buf2.sprintf(", %s%d",((CAtom*)g_oaAtoms[m->m_baAtomIndex[z2]])->m_sName,ma->m_iNumber+1); // buf.strcat(buf2); // // } else // { // if (ma->m_fAtomCode < td) // { // // mprintf(" Changing td from %f to %f.\n",td,ma->m_fAtomCode); // // mprintf(" Taking %s%d into account.\n",((CAtom*)g_oaAtoms[m->m_baAtomIndex[z2]])->m_sName,ma->m_iNumber+1); // td = ma->m_fAtomCode; // } // // // sprintf(buf," Enter partial atomic charge on %s%d",((CAtom*)g_oaAtoms[m->m_baAtomIndex[z2]])->m_sName,ma->m_iNumber+1); // buf.sprintf(" Enter partial atomic charge on %s%d",((CAtom*)g_oaAtoms[m->m_baAtomIndex[z2]])->m_sName,ma->m_iNumber+1); // b = true; // ti++; // } // } // // mprintf("%s Mitte.\n",((CAtom*)g_oaAtoms[m->m_baAtomIndex[z2]])->m_sName); // if (b) // { // // strcat(buf,": [0.0] "); // buf.strcat(": [0.0] "); // tf = AskFloat(buf,0); // for (z3=0;z3Add(tf); // td -= 1.0; // goto _cnm; // } // // mprintf("%s Ende.\n",((CAtom*)g_oaAtoms[m->m_baAtomIndex[z2]])->m_sName); // } // // // mprintf("\n"); // tf = 0; // for (z2=0;z2m_baAtomIndex.GetSize();z2++) // { // for (z3=0;z3<((CxFloatArray*)m->m_oaCharges[z2])->GetSize();z3++) // { // mprintf(" %s%d: %7.4f\n",((CAtom*)g_oaAtoms[m->m_baAtomIndex[z2]])->m_sName,z3+1,((CxFloatArray*)m->m_oaCharges[z2])->GetAt(z3)); // tf += ((CxFloatArray*)m->m_oaCharges[z2])->GetAt(z3); // } // } // m->m_fCharge = tf; // mprintf(WHITE,"\n Molecule %s: Total charge is %.4f.\n\n",m->m_sName,m->m_fCharge); // // ((CMolecule *)g_oaMolecules[mol])->m_iDipoleMode = 4; // mprintf("\n Set dipole information for %s to fixed atomic partial charges.\n", ((CMolecule *)g_oaMolecules[mol])->m_sName); // } else if(mode == 5) { // if(!g_bReadChargesFrom4thXYZ) { // mprintf(WHITE, " > Fluctuating Atomic Partial Charges >\n"); // g_bReadChargesFrom4thXYZ = true; // // FILE *a; // int z, z2, z3, z4; // double tf; // CMolecule *m; // CSingleMolecule *sm; // mprintf("\n Trying to read charges from first time step...\n"); // a = fopen(g_sInputTraj,"rb"); // if (a == NULL) // { // eprintf(" Could not open \"%s\" for reading.\n",g_sInputTraj); // abort(); // } // // if (!g_TimeStep.ReadTimestep(a,true)) // { // eprintf(" Could not read first time step of \"%s\".\n",g_sInputTraj); // abort(); // } // // fclose(a); // // mprintf("\n Uniting molecules which have been broken by wrapping...\n"); // g_TimeStep.UniteMolecules(true); // // mprintf("\n Found the following atomic charges:\n\n"); // // for (z=0;zm_bChargesAssigned = true; // for (z2=0;z2m_baAtomIndex.GetSize();z2++) // { // if (m->m_baAtomIndex[z2] == g_iVirtAtomType) // continue; // for (z3=0;z3m_waAtomCount[z2];z3++) // { // for (z4=0;z4m_laSingleMolIndex.GetSize();z4++) // { // sm = (CSingleMolecule*)g_oaSingleMolecules[m->m_laSingleMolIndex[z4]]; // mprintf(" %s[%d] %s%d: %8.6f\n",m->m_sName,z4+1,((CAtom*)g_oaAtoms[m->m_baAtomIndex[z2]])->m_sName,z3+1,g_TimeStep.m_faCharge[((CxIntArray*)sm->m_oaAtomOffset[z2])->GetAt(z3)]); // } // } // } // } // mprintf("\n Total charges of the molecules:\n\n"); // // for (z=0;zm_laSingleMolIndex.GetSize();z4++) // { // sm = (CSingleMolecule*)g_oaSingleMolecules[m->m_laSingleMolIndex[z4]]; // tf = 0; // for (z2=0;z2m_baAtomIndex.GetSize();z2++) // { // if (m->m_baAtomIndex[z2] == g_iVirtAtomType) // continue; // // for (z3=0;z3m_waAtomCount[z2];z3++) // tf += g_TimeStep.m_faCharge[((CxIntArray*)sm->m_oaAtomOffset[z2])->GetAt(z3)]; // } // mprintf(" %s[%d]: Total charge is %8.6f.\n",m->m_sName,z4+1,tf); // if (z4 == 0) // m->m_fCharge = tf; // } // } // mprintf(WHITE, "\n < End Fluctuating Atomic Partial Charges <\n\n"); // } // ((CMolecule *)g_oaMolecules[mol])->m_iDipoleMode = 5; // mprintf(" Set dipole information for %s to fluctuating atomic partial charges.\n", ((CMolecule *)g_oaMolecules[mol])->m_sName); // } else if(mode == 6) { // ((CMolecule *)g_oaMolecules[mol])->m_iDipoleMode = 6; // mprintf(" Set dipole information for %s to Voronoi partial charges.\n", ((CMolecule *)g_oaMolecules[mol])->m_sName); // unsigned char rty; // ParseAtom("#2", mol, ((CMolecule *)g_oaMolecules[mol])->m_iDipoleCenterType, rty, ((CMolecule *)g_oaMolecules[mol])->m_iDipoleCenterIndex); // } else if (mode == 7) { // ((CMolecule *)g_oaMolecules[mol])->m_iDipoleMode = 7; // mprintf(" Set dipole information for %s to Voronoi dipole moments.\n", ((CMolecule *)g_oaMolecules[mol])->m_sName); // unsigned char rty; // ParseAtom("#2", mol, ((CMolecule *)g_oaMolecules[mol])->m_iDipoleCenterType, rty, ((CMolecule *)g_oaMolecules[mol])->m_iDipoleCenterIndex); // } else if (mode == 8) { // ((CMolecule *)g_oaMolecules[mol])->m_iDipoleMode = 8; // // g_bDipoleRestartFile = fopen("dipole.restart", "r"); // mprintf(" Using dipole restart file.\n"); // } else { // eprintf("Internal error.\n"); // abort(); // } // // if(!g_bDipoleRefFixed) { // if(fabs(((CMolecule *)g_oaMolecules[mol])->m_fCharge) > 0.001f) { // mprintf("\n"); // mprintf(" The molecule is charged (%.4f). Input of a dipole reference point is required.\n", ((CMolecule *)g_oaMolecules[mol])->m_fCharge); // unsigned char rty; // do { // AskString(" Please enter dipole reference point: [#2] ", &buf, "#2"); // } while(!ParseAtom(buf, mol, ((CMolecule *)g_oaMolecules[mol])->m_iDipoleCenterType, rty, ((CMolecule *)g_oaMolecules[mol])->m_iDipoleCenterIndex)); // } // } // // if(!(g_oaMolecules.GetSize() > 1) || !AskYesNo("\n Add dipole information for another molecule (y/n)? [yes] ", true)) // break; // mprintf("\n"); // } // mprintf("\n"); size_t nameLength = 0; int i; for(i = 0; i < g_oaMolecules.GetSize(); i++) { CMolecule *m = (CMolecule *)g_oaMolecules[i]; if(m->m_iDipoleMode == 1 || m->m_iDipoleMode == 4 || m->m_iDipoleMode == 5) if(strlen(m->m_sName) > nameLength) nameLength = strlen(m->m_sName); } if(!g_bDipoleRefFixed) { for(i = 0; i < g_oaMolecules.GetSize(); i++) { CMolecule *m = (CMolecule *)g_oaMolecules[i]; if(m->m_iDipoleMode == 1 || m->m_iDipoleMode == 4 || m->m_iDipoleMode == 5) { mprintf(WHITE, " - %s:", m->m_sName); size_t j; for(j = strlen(m->m_sName); j <= nameLength; j++) mprintf(" "); mprintf(" Dipole reference point is %s%d.\n", (const char*)((CAtom*)g_oaAtoms[m->m_baAtomIndex[m->m_iDipoleCenterType]])->m_sName, m->m_iDipoleCenterIndex + 1); } } } mprintf("\n Calculating dipole moments from first time step...\n\n"); if (g_bTegri) { g_pTetraPak->ProcessStep(&g_TimeStep, true); mprintf("\n"); } // for (i=0;i<50;i++) // mprintf("@ %f %f %f\n",g_TimeStep.m_vaCoords[i][0],g_TimeStep.m_vaCoords[i][1],g_TimeStep.m_vaCoords[i][2]); g_TimeStep.CalcDipoles(true); for(i = 0; i < g_oaMolecules.GetSize(); i++) if(((CMolecule *)g_oaMolecules[i])->m_iDipoleMode == 2) rewind(((CMolecule *)g_oaMolecules[i])->m_pDipoleFile); if (g_bLoadDipoleRestart) { fseek(g_fDipoleRestartFile, sizeof(int), SEEK_SET); } for(i = 0; i < g_oaMolecules.GetSize(); i++) { CMolecule *m = (CMolecule *)g_oaMolecules[i]; if(m->m_iDipoleMode != 0) { double min = 1.0e6, max = 0.0, ave = 0.0; int j; for(j = 0; j < m->m_laSingleMolIndex.GetSize(); j++) { double val = ((CSingleMolecule *)g_oaSingleMolecules[m->m_laSingleMolIndex[j]])->m_vDipole.GetLength(); if(val > max) max = val; if(val < min) min = val; ave += val; } ave /= (double)m->m_laSingleMolIndex.GetSize(); mprintf(WHITE, " - %s:", m->m_sName); size_t k; for(k = strlen(m->m_sName); k <= nameLength; k++) mprintf(" "); mprintf(" Min. %12G, Max. %12G, Avg. %12G Debye.\n", min, max, ave); mprintf(" Cartesian dipole vector of first molecule is ( %8G | %8G | %8G ) Debye.\n\n", ((CSingleMolecule *)g_oaSingleMolecules[m->m_laSingleMolIndex[0]])->m_vDipole[0], ((CSingleMolecule *)g_oaSingleMolecules[m->m_laSingleMolIndex[0]])->m_vDipole[1], ((CSingleMolecule *)g_oaSingleMolecules[m->m_laSingleMolIndex[0]])->m_vDipole[2]); } } mprintf("\n"); if (g_bAdvanced2) { int z, z2, ti; CxIntArray *tia; // char buf[256]; CxString buf; if (AskYesNo(" Write out cartesian dipole vectors of molecules in each step (y/n)? [no] ",false)) { g_bDumpDipoleVector = true; mprintf("\n"); ti = 0; for (z=0;zm_sName)) { try { tia = new CxIntArray("ParseDipole():tia"); } catch(...) { tia = NULL; } if (tia == NULL) NewException((double)sizeof(CxIntArray),__FILE__,__LINE__,__PRETTY_FUNCTION__); g_oaDumpDipoleVector.Add(tia); AskString(" Which representants to consider (e.g. 1,3-6,8)? [all] ",&buf,"*"); if (buf[0] == '*') { for (z2=0;z2<((CMolecule*)g_oaMolecules[z])->m_laSingleMolIndex.GetSize();z2++) tia->Add(z2+1); } else ParseIntList(buf,tia); for (z2=0;z2GetSize();z2++) tia->GetAt(z2)--; ti += tia->GetSize(); mprintf("\n"); } else g_oaDumpDipoleVector.Add(NULL); } g_iDumpDipoleSMCount = ti; g_bDumpDipoleAbs = AskYesNo(" Write out absolute value as 4th column per molecule (y/n)? [yes] ",true); g_bDumpDipoleXYZ = AskYesNo(" Write out XYZ trajectory to visualize dipole vectors (y/n)? [no] ",false); if (g_bDumpDipoleXYZ) { g_fDumpDipoleScale = AskFloat(" Please enter dipole scale in trajectory (unit: Angstrom/Debye): [1.0] ",1.0); g_iDumpDipoleXYZAtoms = 0; for (z=0;zm_iAtomGesNoVirt * ((CxIntArray*)g_oaDumpDipoleVector[z])->GetSize(); } g_iDumpDipoleXYZAtoms += g_iDumpDipoleSMCount*2; } } else g_bDumpDipoleVector = false; mprintf("\n"); } if (g_bTegri && (g_iTrajFormat != 5) && (g_iTrajFormat != 7)) { mprintf(" Rewinding density cube file to beginning...\n\n"); fseek(g_pTetraPak->m_fCubePipe,0,SEEK_SET); } mprintf(WHITE, "<<< End of Dipole Definition <<<\n\n\n"); g_bDipoleDefined = true; //----------------- OLD ----------------------- // // int z, z2, z3, z4, ti; // bool b; // char buf[256], buf2[256]; // double td, td2, td3; // double tf; // unsigned char rty; // CMolecule *m; // CSingleMolecule *sm; // CMolAtom *ma; // CxFloatArray *tfa; // CxIntArray *tia; // FILE *a; // // if (g_bDipoleDefined) // return; // // _dipbeg: // mprintf(WHITE,"\n>>> Dipole definition >>>\n\n"); // mprintf(" TRAVIS can calculate dipole moments either from wannier centers (you need\n"); // mprintf(" to have those in the trajectory then) or from fixed atomic partial charges.\n\n"); // g_bWannier = AskYesNo(" Obtain dipole vectors from wannier centers (y/n)? [yes] ",true); // mprintf("\n"); // if (g_bWannier) // { // _wantype: // ti = -1; // for (z=0;zm_bExclude) // { // ti = z; // break; // } // } // // if (ti == -1) // eprintf(" Atom label of wannier centers not found.\n\n"); // else mprintf(" Atom type %s is excluded from system, probably the wannier centers.\n\n",((CAtom*)g_oaAtoms[ti])->m_sName); // // sprintf(buf," Which atom label do the wannier centers have ("); // // for (z=0;zm_sName); // strcat(buf,buf2); // } else // { // if (ti == -1) // sprintf(buf2,"%s)? ",((CAtom*)g_oaAtoms[z])->m_sName); // else sprintf(buf2,"%s)? [%s] ",((CAtom*)g_oaAtoms[z])->m_sName,((CAtom*)g_oaAtoms[ti])->m_sName); // strcat(buf,buf2); // } // } // // if (ti == -1) // AskString_ND(buf,buf2); // else AskString(buf,buf2,((CAtom*)g_oaAtoms[ti])->m_sName); // // for (z=0;zm_sName)==0) // { // g_iWannierAtomType = z; // goto _wandone; // } // } // eprintf(" Wrong input.\n"); // inpprintf("! Wrong input.\n"); // goto _wantype; // _wandone: // g_fWannierCharge = (double)fabs(AskFloat(" Enter the negative charge of the wannier centers (without sign): [2.0] ",2.0f)); // mprintf("\n"); // for (z=0;zm_sName,"C") == 0) // z2 = 4; // else if (mystricmp(((CAtom*)g_oaAtoms[z])->m_sName,"N") == 0) // z2 = 5; // else if (mystricmp(((CAtom*)g_oaAtoms[z])->m_sName,"O") == 0) // z2 = 6; // else if (mystricmp(((CAtom*)g_oaAtoms[z])->m_sName,"F") == 0) // z2 = 7; // else if (mystricmp(((CAtom*)g_oaAtoms[z])->m_sName,"P") == 0) // z2 = 5; // else if (mystricmp(((CAtom*)g_oaAtoms[z])->m_sName,"S") == 0) // z2 = 6; // else if (mystricmp(((CAtom*)g_oaAtoms[z])->m_sName,"Cl") == 0) // z2 = 7; // else if (mystricmp(((CAtom*)g_oaAtoms[z])->m_sName,"B") == 0) // z2 = 3; // else if (mystricmp(((CAtom*)g_oaAtoms[z])->m_sName,"Br") == 0) // z2 = 7; // else if (mystricmp(((CAtom*)g_oaAtoms[z])->m_sName,"I") == 0) // z2 = 7; // else z2 = ((CAtom*)g_oaAtoms[z])->m_pElement->m_iOrd; // // ((CAtom*)g_oaAtoms[z])->m_fCharge = AskFloat(" Enter core charge (mind pseudopotentials!) for atom type %s: [%d.0] ",(double)z2,((CAtom*)g_oaAtoms[z])->m_sName,z2); // } // mprintf("\n"); // if (!g_TimeStep.ScanWannier(true)) // goto _dipbeg; // /* if (g_bAdvanced2) // { // g_bUnwrapWannier = AskYesNo(" Write out trajectory with unwrapped molecules and wannier centers (y/n)? [no] ",false); // } else g_bUnwrapWannier = false;*/ // } else // NOT WANNIER // { // if (g_bBetaFeatures && g_bXYZ4thCol) // { // if (AskYesNo(" Read atomic charges from 4th numeric column of XYZ file (y/n)? [yes] ",true)) // { // g_bReadChargesFrom4thXYZ = true; // // mprintf("\n Trying to read charges from first time step...\n"); // a = fopen(g_sInputTraj,"rb"); // if (a == NULL) // { // eprintf(" Could not open \"%s\" for reading.\n",g_sInputTraj); // abort(); // } // // if (!g_TimeStep.ReadTimestep(a,true)) // { // eprintf(" Could not read first time step of \"%s\".\n",g_sInputTraj); // abort(); // } // // fclose(a); // // mprintf("\n Uniting molecules which have been broken by wrapping...\n"); // g_TimeStep.UniteMolecules(true); // // mprintf("\n Found the following atomic charges:\n\n"); // // for (z=0;zm_bChargesAssigned = true; // for (z2=0;z2m_baAtomIndex.GetSize();z2++) // { // if (m->m_baAtomIndex[z2] == g_iVirtAtomType) // continue; // for (z3=0;z3m_waAtomCount[z2];z3++) // { // for (z4=0;z4m_laSingleMolIndex.GetSize();z4++) // { // sm = (CSingleMolecule*)g_oaSingleMolecules[m->m_laSingleMolIndex[z4]]; // mprintf(" %s[%d] %s%d: %8.6f\n",m->m_sName,z4+1,((CAtom*)g_oaAtoms[m->m_baAtomIndex[z2]])->m_sName,z3+1,g_TimeStep.m_faCharge[((CxIntArray*)sm->m_oaAtomOffset[z2])->GetAt(z3)]); // } // } // } // } // mprintf("\n Total charges of the molecules:\n\n"); // // for (z=0;zm_laSingleMolIndex.GetSize();z4++) // { // sm = (CSingleMolecule*)g_oaSingleMolecules[m->m_laSingleMolIndex[z4]]; // tf = 0; // for (z2=0;z2m_baAtomIndex.GetSize();z2++) // { // if (m->m_baAtomIndex[z2] == g_iVirtAtomType) // continue; // // for (z3=0;z3m_waAtomCount[z2];z3++) // tf += g_TimeStep.m_faCharge[((CxIntArray*)sm->m_oaAtomOffset[z2])->GetAt(z3)]; // } // mprintf(" %s[%d]: Total charge is %8.6f.\n",m->m_sName,z4+1,tf); // if (z4 == 0) // m->m_fCharge = tf; // } // } // mprintf("\n"); // // goto _chargedone; // } // } // for (z=0;zm_laSingleMolIndex[0]]; // mprintf(YELLOW,"\n * Molecule %s\n\n",m->m_sName); // // m->m_bChargesAssigned = AskYesNo(" Enter partial atomic charges for this molecule (y/n)? [yes] ",true); // // if (!m->m_bChargesAssigned) // { // mprintf("\n Dipole moment will be always zero for this molecule.\n"); // goto _nocharge; // } // // for (z2=0;z2m_baAtomIndex.GetSize();z2++) // { // mprintf("\n"); // // mprintf("%s Anfang.\n",((CAtom*)g_oaAtoms[m->m_baAtomIndex[z2]])->m_sName); // ma = NULL; // td = 1.0e50; // // try { tfa = new CxFloatArray("ParseDipole():tfa"); } catch(...) { tfa = NULL; } // if (tfa == NULL) NewException((double)sizeof(CxFloatArray),__FILE__,__LINE__,__PRETTY_FUNCTION__); // // m->m_oaCharges.Add(tfa); // _cnm: // buf[0] = 0; // buf2[0] = 0; // b = false; // ti = 0; // // mprintf("D.\n"); // for (z3=0;z3m_oaMolAtoms.GetSize();z3++) // { // // mprintf("z3=%d.\n",z3); // if (((CMolAtom*)sm->m_oaMolAtoms[z3])->m_iType != z2) // continue; // // ma = (CMolAtom*)sm->m_oaMolAtoms[z3]; // // // mprintf("AtomType %s, z3=%d, td=%f, ac=%f.\n",((CAtom*)g_oaAtoms[m->m_baAtomIndex[z2]])->m_sName,z3,td,ma->m_fAtomCode); // // if (ma->m_fAtomCode > td) // { // // mprintf(" AtomCode = %f > %f = td. Skip.\n",ma->m_fAtomCode,td); // continue; // } // if (b) // { // if (ma->m_fAtomCode < td) // { // // mprintf(" AtomCode = %f < %f = td. Skip.\n",ma->m_fAtomCode,td); // continue; // } // ti++; // // mprintf(" Taking %s%d into account.\n",((CAtom*)g_oaAtoms[m->m_baAtomIndex[z2]])->m_sName,ma->m_iNumber+1); // sprintf(buf2,", %s%d",((CAtom*)g_oaAtoms[m->m_baAtomIndex[z2]])->m_sName,ma->m_iNumber+1); // strcat(buf,buf2); // } else // { // if (ma->m_fAtomCode < td) // { // // mprintf(" Changing td from %f to %f.\n",td,ma->m_fAtomCode); // // mprintf(" Taking %s%d into account.\n",((CAtom*)g_oaAtoms[m->m_baAtomIndex[z2]])->m_sName,ma->m_iNumber+1); // td = ma->m_fAtomCode; // } // sprintf(buf," Enter partial atomic charge on %s%d",((CAtom*)g_oaAtoms[m->m_baAtomIndex[z2]])->m_sName,ma->m_iNumber+1); // b = true; // ti++; // } // } // // mprintf("%s Mitte.\n",((CAtom*)g_oaAtoms[m->m_baAtomIndex[z2]])->m_sName); // if (b) // { // strcat(buf,": [0.0] "); // tf = AskFloat(buf,0); // for (z3=0;z3Add(tf); // td -= 1.0; // goto _cnm; // } // // mprintf("%s Ende.\n",((CAtom*)g_oaAtoms[m->m_baAtomIndex[z2]])->m_sName); // } // // // mprintf("\n"); // tf = 0; // for (z2=0;z2m_baAtomIndex.GetSize();z2++) // { // for (z3=0;z3<((CxFloatArray*)m->m_oaCharges[z2])->GetSize();z3++) // { // mprintf(" %s%d: %7.4f\n",((CAtom*)g_oaAtoms[m->m_baAtomIndex[z2]])->m_sName,z3+1,((CxFloatArray*)m->m_oaCharges[z2])->GetAt(z3)); // tf += ((CxFloatArray*)m->m_oaCharges[z2])->GetAt(z3); // } // } // m->m_fCharge = tf; // mprintf(WHITE,"\n Molecule %s: Total charge is %.4f.\n\n",m->m_sName,m->m_fCharge); // _nocharge:; // } // } // _chargedone: // if (g_bAdvanced2) // { // mprintf("\n"); // g_bDipoleRefFixed = AskYesNo(" Use a box-fixed reference point for dipole calculation (y/n)? [no] ",false); // if (g_bDipoleRefFixed) // mprintf("\n Warning: Absolute dipole moments of charged molecules will be erroneous.\n Only the derivatives will be useful.\n\n"); // } else g_bDipoleRefFixed = false; // // if (!g_bDipoleRefFixed) // { // for (z=0;zm_bChargesAssigned)) // continue; // // if (fabs(m->m_fCharge) > 0.001) // { // mprintf("\n"); // mprintf(" Molecule %s is charged (%.4f). Input of a dipole reference point is required.\n",m->m_sName,m->m_fCharge); // _diprefagain: // AskString(" Please enter dipole reference point for %s: [#1] ",buf,"#1",m->m_sName); // if (!ParseAtom(buf,z,m->m_iDipoleCenterType,rty,m->m_iDipoleCenterIndex)) // goto _diprefagain; // } // } // mprintf("\n"); // } // // ti = 0; // for (z=0;zm_bChargesAssigned)) // continue; // if (((int)strlen(m->m_sName)) > ti) // ti = strlen(m->m_sName); // } // // if (!g_bDipoleRefFixed) // { // for (z=0;zm_bChargesAssigned)) // continue; // mprintf(WHITE," - %s:",m->m_sName); // for (z2=strlen(m->m_sName);z2<=ti;z2++) // mprintf(" "); // mprintf(" Dipole reference point is %s%d.\n",((CAtom*)g_oaAtoms[m->m_baAtomIndex[m->m_iDipoleCenterType]])->m_sName,m->m_iDipoleCenterIndex+1); // } // mprintf("\n"); // } // // mprintf(" Calculating dipole moments from first time step...\n\n"); // g_TimeStep.CalcDipoles(); // // sm = NULL; // for (z=0;zm_bChargesAssigned)) // continue; // td = 0; // td2 = 1.0e10; // td3 = 0; // for (z2=0;z2m_laSingleMolIndex.GetSize();z2++) // { // sm = (CSingleMolecule*)g_oaSingleMolecules[m->m_laSingleMolIndex[z2]]; // tf = sm->m_vDipole.GetLength(); // if (tf > td) // td = tf; // if (tf < td2) // td2 = tf; // td3 += tf; // } // td3 /= (double)m->m_laSingleMolIndex.GetSize(); // mprintf(WHITE," - %s:",m->m_sName); // for (z2=strlen(m->m_sName);z2<=ti;z2++) // mprintf(" "); // mprintf(" Min. %12G, Max. %12G, Avg. %12G Debye.\n",td2,td,td3); // if (m->m_laSingleMolIndex.GetSize() == 1) // { // for (z2=strlen(m->m_sName);z2<=ti;z2++) // mprintf(" "); // mprintf(" Cartesian dipole vector is ( %8G | %8G | %8G ).\n\n",sm->m_vDipole[0],sm->m_vDipole[1],sm->m_vDipole[2]); // } // } // // mprintf("\n"); // if (g_bAdvanced2) // { // if (AskYesNo(" Write out cartesian dipole vectors of molecules in each step (y/n)? [no] ",false)) // { // g_bDumpDipoleVector = true; // mprintf("\n"); // ti = 0; // for (z=0;zm_sName)) // { // try { tia = new CxIntArray("ParseDipole():tia"); } catch(...) { tia = NULL; } // if (tia == NULL) NewException((double)sizeof(CxIntArray),__FILE__,__LINE__,__PRETTY_FUNCTION__); // // g_oaDumpDipoleVector.Add(tia); // AskString(" Which representants to consider (e.g. 1,3-6,8)? [all] ",buf,"*"); // if (buf[0] == '*') // { // for (z2=0;z2<((CMolecule*)g_oaMolecules[z])->m_laSingleMolIndex.GetSize();z2++) // tia->Add(z2+1); // } else ParseIntList(buf,tia); // for (z2=0;z2GetSize();z2++) // tia->GetAt(z2)--; // ti += tia->GetSize(); // mprintf("\n"); // } else g_oaDumpDipoleVector.Add(NULL); // } // g_iDumpDipoleSMCount = ti; // g_bDumpDipoleAbs = AskYesNo(" Write out absolute value as 4th column per molecule (y/n)? [yes] ",true); // g_bDumpDipoleXYZ = AskYesNo(" Write out XYZ trajectory to visualize dipole vectors (y/n)? [no] ",false); // // if (g_bDumpDipoleXYZ) // { // g_fDumpDipoleScale = AskFloat(" Please enter dipole scale in trajectory (unit: Angstrom/Debye): [1.0] ",1.0f); // g_iDumpDipoleXYZAtoms = 0; // for (z=0;zm_iAtomGesNoVirt * ((CxIntArray*)g_oaDumpDipoleVector[z])->GetSize(); // } // g_iDumpDipoleXYZAtoms += g_iDumpDipoleSMCount*2; // } // } else g_bDumpDipoleVector = false; // } // // mprintf(WHITE,"\n<<< End of Dipole definition <<<\n\n"); // // g_bDipoleDefined = true; } void parseMagneticDipole() { static bool magneticDipoleDefined = false; if (magneticDipoleDefined) return; g_bUseVelocities = true; if (g_bTegri && (g_pTetraPak == NULL)) { try { g_pVoroWrapper = new CVoroWrapper(); } catch(...) { g_pVoroWrapper = NULL; } if (g_pVoroWrapper == NULL) NewException((double)sizeof(CVoroWrapper),__FILE__,__LINE__,__PRETTY_FUNCTION__); try { g_pTetraPak = new CTetraPak(); } catch(...) { g_pTetraPak = NULL; } if (g_pTetraPak == NULL) NewException((double)sizeof(CTetraPak),__FILE__,__LINE__,__PRETTY_FUNCTION__); g_pTetraPak->Parse(); } mprintf(WHITE, "\n>>> Magnetic Moment Definition >>>\n\n"); mprintf(" There are the following possibilities to provide magnetic moments:\n"); mprintf(" (1) Calculate magnetic moments from Wannier centers\n (These need to be atoms in the trajectory and have to be sorted, use \"swan\" in the main menu)\n"); mprintf(" (2) Read magnetic moments from an external file\n (This file is expected to contain one line per timestep\n with the three vector components separated by spaces)\n"); mprintf(" (3) Read magnetic moments from the trajectory file\n (These need to be specified in the comment line)\n"); mprintf(" (4) Calculate magnetic moments from fixed atomic partial charges\n"); mprintf(" (5) Calculate magnetic moments from fluctuating atomic partial charges\n (These need to be in the fourth column of the trajectory)\n"); mprintf(" (6) Calculate magnetic moments from Voronoi partial charges\n (This needs electron density data)\n"); mprintf(" (7) Calculate Voronoi magnetic moments\n (This needs electron density data)\n"); mprintf(" (8) Load a magnetic moment restart file\n"); mprintf("\n"); mprintf(" The following magnetic moment modes can be set for all molecules at once: 1, 5, 6, 7, 8\n"); while (true) { int globalMode = AskRangeInteger(" Which magnetic moment mode to set for all molecules at once? [none] ", 0, 8, 0); if (globalMode == 0) { int i; for (i = 0; i < g_oaMolecules.GetSize(); i++) ((CMolecule *)g_oaMolecules[i])->m_iMagneticDipoleMode = 0; break; } else if (globalMode == 1) { if (setupWannier()) { int i; for (i = 0; i < g_oaMolecules.GetSize(); i++) ((CMolecule *)g_oaMolecules[i])->m_iMagneticDipoleMode = 1; break; } continue; } else if (globalMode == 2) { eprintf(" This mode cannot be set for all molecules at once.\n"); continue; } else if (globalMode == 3) { eprintf(" This mode cannot be set for all molecules at once.\n"); continue; } else if (globalMode == 4) { eprintf(" This mode cannot be set for all molecules at once.\n"); continue; } else if (globalMode == 5) { if (g_bXYZ4thCol || g_bLAMMPSCharge) { setupFluctuatingCharges(); int i; for (i = 0; i < g_oaMolecules.GetSize(); i++) ((CMolecule *)g_oaMolecules[i])->m_iMagneticDipoleMode = 5; break; } eprintf(" The trajectory does not have a fourth column.\n"); continue; } else if (globalMode == 6) { if (g_bTegri) { g_bVoroIntegrateCharge = true; parseCoreCharges(); int i; for (i = 0; i < g_oaMolecules.GetSize(); i++) ((CMolecule *)g_oaMolecules[i])->m_iMagneticDipoleMode = 6; break; } eprintf(" Voronoi integration needs to be active. Use \"vori\" in the main menu.\n"); continue; } else if (globalMode == 7) { if (g_bTegri) { g_bVoroIntegrateCharge = true; g_bVoroIntegrateDipoleMoment = true; g_bVoroIntegrateTotalCurrent = true; g_bVoroIntegrateMagneticMoment = true; g_bCubeTimeDev = true; parseCoreCharges(); int i; for (i = 0; i < g_oaMolecules.GetSize(); i++) ((CMolecule *)g_oaMolecules[i])->m_iMagneticDipoleMode = 7; break; } eprintf(" Voronoi integration needs to be active. Use \"vori\" in the main menu.\n"); continue; } else if (globalMode == 8) { setupMagneticDipoleRestartFile(); int i; for (i = 0; i < g_oaMolecules.GetSize(); i++) ((CMolecule *)g_oaMolecules[i])->m_iMagneticDipoleMode = 8; break; } eprintf(" This is impossible.\n"); } int i; for (i = 0; i < g_oaMolecules.GetSize(); i++) { int rty; ParseAtom("#2", i, ((CMolecule *)g_oaMolecules[i])->m_iMagneticDipoleCenterType, rty, ((CMolecule *)g_oaMolecules[i])->m_iMagneticDipoleCenterIndex); } while (true) { mprintf("\n The following magnetic moment modes are set up:\n\n"); int longest = 0; for (i = 0; i < g_oaMolecules.GetSize(); i++) { int length = (int)strlen(((CMolecule *)g_oaMolecules[i])->m_sName); if (length > longest) longest = length; } CxString buf; buf.sprintf(" %%%ds - %%d", longest); for (i = 0; i < g_oaMolecules.GetSize(); i++) { mprintf(buf, ((CMolecule *)g_oaMolecules[i])->m_sName, ((CMolecule *)g_oaMolecules[i])->m_iMagneticDipoleMode); if (((CMolecule *)g_oaMolecules[i])->m_iMagneticDipoleMode == 0) mprintf(" (none)\n"); else if (((CMolecule *)g_oaMolecules[i])->m_iMagneticDipoleMode == 1) mprintf(" (Wannier centers)\n"); else if (((CMolecule *)g_oaMolecules[i])->m_iMagneticDipoleMode == 2) mprintf(" (external file)\n"); else if (((CMolecule *)g_oaMolecules[i])->m_iMagneticDipoleMode == 3) mprintf(" (trajectory comment line)\n"); else if (((CMolecule *)g_oaMolecules[i])->m_iMagneticDipoleMode == 4) mprintf(" (fixed atomic partial charges)\n"); else if (((CMolecule *)g_oaMolecules[i])->m_iMagneticDipoleMode == 5) mprintf(" (fluctuating atomic partial charges)\n"); else if (((CMolecule *)g_oaMolecules[i])->m_iMagneticDipoleMode == 6) mprintf(" (Voronoi partial charges)\n"); else if (((CMolecule *)g_oaMolecules[i])->m_iMagneticDipoleMode == 7) mprintf(" (Voronoi magnetic moments)\n"); else if (((CMolecule *)g_oaMolecules[i])->m_iMagneticDipoleMode == 8) mprintf(" (restart file)\n"); else mprintf("\n"); } mprintf("\n"); if (!AskYesNo(" Change magnetic moment mode for a molecule (y/n)? [no] ", false)) break; int mol; if (g_oaMolecules.GetSize() > 1) { buf.sprintf(" Change dipole mode for which molecule ("); for (i = 0; i < g_oaMolecules.GetSize(); i++) { CxString buf2; buf2.sprintf("%s=%d", ((CMolecule *)g_oaMolecules[i])->m_sName, i + 1); buf.strcat(buf2); if(i < g_oaMolecules.GetSize() - 1) { buf.strcat(", "); } } buf.strcat(")? "); mol = AskRangeInteger_ND("%s", 1, g_oaMolecules.GetSize(), (const char*)buf) - 1; } else { mol = 0; } int mode = AskRangeInteger_ND(" Which magnetic moment mode to set for molecule %s? ", 1, 8, ((CMolecule *)g_oaMolecules[mol])->m_sName); if (mode == 0) { ((CMolecule *)g_oaMolecules[mol])->m_iMagneticDipoleMode = 0; } else if (mode == 1) { if (setupWannier()) { ((CMolecule *)g_oaMolecules[mol])->m_iMagneticDipoleMode = 1; } } else if (mode == 2) { FILE *dipoleFile = NULL; while (true) { if(dipoleFile != NULL) { fclose(dipoleFile); dipoleFile = NULL; } AskString_ND(" Name of file for magnetic moments: ", &buf); mprintf("\n Trying to read first line...\n\n"); dipoleFile = fopen(buf, "r"); if(dipoleFile == NULL) { eprintf(" Could not open \"%s\".\n\n", (const char*)buf); continue; } if (buf.fgets(1024, dipoleFile) == NULL) { eprintf(" Could not read first line.\n\n"); continue; } double dipole[3]; if(sscanf((const char *)buf, "%lf %lf %lf", &dipole[0], &dipole[1], &dipole[2]) < 3) { eprintf(" Could not find three real numbers in first line.\n\n"); continue; } mprintf(" Found the following magnetic moment in the first line:\n"); mprintf(" ( %8G | %8G | %8G ) Bohr magneton.\n", dipole[0], dipole[1], dipole[2]); rewind(dipoleFile); break; } ((CMolecule *)g_oaMolecules[mol])->m_iMagneticDipoleMode = 2; ((CMolecule *)g_oaMolecules[mol])->m_pMagneticDipoleFile = dipoleFile; if(((CMolecule *)g_oaMolecules[mol])->m_laSingleMolIndex.GetSize() > 1) eprintf("\n Warning: There are several molecules %s. The same magnetic moment will be used for all of them.\n", ((CMolecule *)g_oaMolecules[mol])->m_sName); } else if (mode == 3) { CxString comment; comment.strcpy(g_TimeStep.m_pComment); mprintf(" The comment line is \"%s\".\n", (const char *)comment); buf = ""; const char delim[] = "\t "; char *tok = strtok(comment.GetWritePointer(), delim); int num = 0; while(tok != NULL) { double f; if(sscanf(tok, "%lf", &f) == 1) { CxString buf2; num++; if(num > 1) { buf2.sprintf(", %s (%d)", tok, num); } else { buf2.sprintf("%s (%d)", tok, num); } buf.strcat(buf2); } tok = strtok(NULL, delim); } ((CMolecule *)g_oaMolecules[mol])->m_iMagneticDipoleCommentIndex[0] = AskRangeInteger(" Choose the X magnetic moment component: %s [1] ", 1, num, 1, (const char *)buf) - 1; ((CMolecule *)g_oaMolecules[mol])->m_iMagneticDipoleCommentIndex[1] = AskRangeInteger(" Choose the Y magnetic moment component: %s [1] ", 1, num, 1, (const char *)buf) - 1; ((CMolecule *)g_oaMolecules[mol])->m_iMagneticDipoleCommentIndex[2] = AskRangeInteger(" Choose the Z magnetic moment component: %s [1] ", 1, num, 1, (const char *)buf) - 1; ((CMolecule *)g_oaMolecules[mol])->m_iMagneticDipoleMode = 3; if(((CMolecule *)g_oaMolecules[mol])->m_laSingleMolIndex.GetSize() > 1) eprintf("\n Warning: There are several molecules %s. The same dipole moment will be used for all of them.\n", ((CMolecule *)g_oaMolecules[mol])->m_sName); } else if (mode == 4) { CMolecule *m = (CMolecule*)g_oaMolecules[mol]; CSingleMolecule *sm = (CSingleMolecule*)g_oaSingleMolecules[m->m_laSingleMolIndex[0]]; m->m_bChargesAssigned = true; int z2, z3, ti; CMolAtom *ma; CxDoubleArray *tfa; bool b; double tf; double td; CxString buf2; for (z2=0;z2m_baAtomIndex.GetSize();z2++) { mprintf("\n"); ma = NULL; td = 1.0e50; try { tfa = new CxDoubleArray("ParseDipole():tfa"); } catch(...) { tfa = NULL; } if (tfa == NULL) NewException((double)sizeof(CxDoubleArray),__FILE__,__LINE__,__PRETTY_FUNCTION__); m->m_oaCharges.Add(tfa); _cnm: buf = ""; buf2 = ""; b = false; ti = 0; for (z3=0;z3m_oaMolAtoms.GetSize();z3++) { if (((CMolAtom*)sm->m_oaMolAtoms[z3])->m_iType != z2) continue; ma = (CMolAtom*)sm->m_oaMolAtoms[z3]; if (ma->m_fAtomCode > td) { continue; } if (b) { if (ma->m_fAtomCode < td) { continue; } ti++; buf2.sprintf(", %s%d",(const char*)((CAtom*)g_oaAtoms[m->m_baAtomIndex[z2]])->m_sName,ma->m_iNumber+1); buf.strcat(buf2); } else { if (ma->m_fAtomCode < td) { td = ma->m_fAtomCode; } buf.sprintf(" Enter partial atomic charge on %s%d",(const char*)((CAtom*)g_oaAtoms[m->m_baAtomIndex[z2]])->m_sName,ma->m_iNumber+1); b = true; ti++; } } if (b) { buf.strcat(": [0.0] "); tf = AskFloat("%s",0, (const char*)buf); for (z3=0;z3Add(tf); td -= 1.0; goto _cnm; } } tf = 0; for (z2=0;z2m_baAtomIndex.GetSize();z2++) { for (z3=0;z3<((CxDoubleArray*)m->m_oaCharges[z2])->GetSize();z3++) { mprintf(" %s%d: %7.4f\n",(const char*)((CAtom*)g_oaAtoms[m->m_baAtomIndex[z2]])->m_sName,z3+1,((CxDoubleArray*)m->m_oaCharges[z2])->GetAt(z3)); tf += ((CxDoubleArray*)m->m_oaCharges[z2])->GetAt(z3); } } m->m_fCharge = tf; mprintf(WHITE,"\n Molecule %s: Total charge is %.4f.\n\n",m->m_sName,m->m_fCharge); ((CMolecule *)g_oaMolecules[mol])->m_iMagneticDipoleMode = 4; } else if (mode == 5) { if (g_bXYZ4thCol || g_bLAMMPSCharge) { setupFluctuatingCharges(); ((CMolecule *)g_oaMolecules[mol])->m_iMagneticDipoleMode = 5; } eprintf(" The trajectory does not have a fourth column.\n"); } else if (mode == 6) { if (g_bTegri) { g_bVoroIntegrateCharge = true; parseCoreCharges(); ((CMolecule *)g_oaMolecules[mol])->m_iMagneticDipoleMode = 6; } else { eprintf(" Voronoi integration needs to be active. Use \"vori\" in the main menu.\n"); } } else if (mode == 7) { if (g_bTegri) { g_bVoroIntegrateCharge = true; g_bVoroIntegrateDipoleMoment = true; g_bVoroIntegrateTotalCurrent = true; g_bVoroIntegrateMagneticMoment = true; g_bCubeTimeDev = true; parseCoreCharges(); ((CMolecule *)g_oaMolecules[mol])->m_iMagneticDipoleMode = 7; } else { eprintf(" Voronoi integration needs to be active. Use \"vori\" in the main menu.\n"); } } else if (mode == 8) { setupMagneticDipoleRestartFile(); ((CMolecule *)g_oaMolecules[mol])->m_iMagneticDipoleMode = 8; } else { eprintf(" This is impossible.\n"); } } mprintf("\n"); if (g_bCubeTimeDev) { g_fBackgroundDensity = AskFloat(" Background density to improve PDE solver convergence in atomic units [1e-6] ", 1.0e-6); g_fPDEConvThresh = AskFloat(" Relative convergence threshold for PDE solver [1e-2] ", 0.01); g_iPDEMaxIter = AskInteger(" Maximum number of iterations in PDE solver [20] ", 20); mprintf("\n"); } mprintf(WHITE, "<<< End of Magnetic Moment Definition <<<\n\n"); magneticDipoleDefined = true; } void DipolGrimme(const char *s) { FILE *a; char buf[256], *p, *q; const char *sep = " ,;\t"; int i, ti, z, z3; CxDoubleArray *fa, *ptfa2, *ptfa3; double fx, fy, fz, tf; CFFT tfft; CAutoCorrelation *ac; CReorDyn *m_pRDyn; mprintf("\n This analysis reads dipole vectors from a text file\n"); mprintf(" and calculates the dipole vector ACF / IR spectrum.\n\n"); mprintf(" The text file needs to contain the three cartesian components\n"); mprintf(" of the dipole vector (three numbers per line); one line equals one time step.\n\n"); if (s == NULL) { eprintf("Please specify dipole text file as first command line parameter.\n\n"); return; } mprintf(" If you are not sure what to enter, use the default values (just press return).\n\n"); g_fTimestepLength = AskFloat(" Enter the length of one trajectory time step in fs: [0.5] ",0.5); mprintf("\n"); try { m_pRDyn = new CReorDyn(); } catch(...) { m_pRDyn = NULL; } if (m_pRDyn == NULL) NewException((double)sizeof(CReorDyn),__FILE__,__LINE__,__PRETTY_FUNCTION__); // m_pRDyn->m_sName = "dipole"; try { m_pRDyn->m_pRDyn = new CDF(); } catch(...) { m_pRDyn->m_pRDyn = NULL; } if (m_pRDyn->m_pRDyn == NULL) NewException((double)sizeof(CDF),__FILE__,__LINE__,__PRETTY_FUNCTION__); m_pRDyn->m_pRDyn->m_bLeft = true; mprintf(WHITE,"\n*** Vector Reorientation Dynamics ***\n\n"); m_pRDyn->m_iDepth = AskUnsignedInteger(" Enter the resolution (=depth) of the vector ACF (in time steps): [4096] ",4096); mprintf("\n This corresponds to a spectral resolution of %.4f cm^-1.\n",33356.41/g_fTimestepLength/2.0/m_pRDyn->m_iDepth); ti = CalcFFTSize(m_pRDyn->m_iDepth,false); if (m_pRDyn->m_iDepth != ti) { mprintf(WHITE,"\n The next \"fast\" size for FFT is %d. Using this instead of %d as depth.\n",tfft.NextFastSize(m_pRDyn->m_iDepth),m_pRDyn->m_iDepth); m_pRDyn->m_iDepth = tfft.NextFastSize(m_pRDyn->m_iDepth); } try { m_pRDyn->m_pACF = new CACF(); } catch(...) { m_pRDyn->m_pACF = NULL; } if (m_pRDyn->m_pACF == NULL) NewException((double)sizeof(CACF),__FILE__,__LINE__,__PRETTY_FUNCTION__); m_pRDyn->m_pACF->m_iSize = m_pRDyn->m_iDepth; m_pRDyn->m_pACF->m_bSpectrum = true; m_pRDyn->m_pACF->m_bWindowFunction = AskYesNo(" Apply window function (Cos^2) to Autocorrelation function (y/n)? [yes] ",true); tf = 33356.41 / g_fTimestepLength / 2.0; mprintf("\n A time step length of %.1f fs allows a spectral range up to %.1f cm^-1.\n\n",g_fTimestepLength,tf); m_pRDyn->m_pACF->m_fSpecWaveNumber = AskRangeFloat(" Calculate spectrum up to which wave number (cm^-1)? [%.1f cm^-1] ",0,tf,(tf<5000.0)?tf:5000.0,(tf<5000.0)?tf:5000.0); m_pRDyn->m_pACF->m_iMirror = AskUnsignedInteger(" No mirroring (0), short-time enhancing (1) or long-time enhancing (2)? [1] ",1); m_pRDyn->m_pACF->m_iZeroPadding = AskUnsignedInteger(" Zero Padding: How many zeros to insert? [%d] ",m_pRDyn->m_iDepth*3,m_pRDyn->m_iDepth*3); m_pRDyn->m_pACF->m_iZeroPadding0 = m_pRDyn->m_pACF->m_iZeroPadding; ti = CalcFFTSize(m_pRDyn->m_iDepth+m_pRDyn->m_pACF->m_iZeroPadding,false); if (m_pRDyn->m_iDepth+m_pRDyn->m_pACF->m_iZeroPadding != ti) { mprintf(WHITE,"\n The next \"fast\" size for FFT is %d. Using %d zeros for zero padding.\n",ti,ti-m_pRDyn->m_iDepth); m_pRDyn->m_pACF->m_iZeroPadding = ti-m_pRDyn->m_iDepth; } mprintf(" Zero padding increases the spectral resolution to %.4f cm^-1.\n\n",33356.41/g_fTimestepLength/2.0/(m_pRDyn->m_iDepth+m_pRDyn->m_pACF->m_iZeroPadding)); m_pRDyn->m_pACF->m_bACF_DB = AskYesNo(" Convert intensity axis of spectrum to decibel (y/n)? [no] ",false); m_pRDyn->m_pACF->Create(); m_pRDyn->m_pRDyn->m_fMinVal = 0; m_pRDyn->m_pRDyn->m_fMaxVal = m_pRDyn->m_iDepth * g_fTimestepLength / 1000.0; m_pRDyn->m_pRDyn->m_iResolution = m_pRDyn->m_iDepth; m_pRDyn->m_pRDyn->SetLabelX("Tau [ps]"); m_pRDyn->m_pRDyn->SetLabelY("Vector autocorrelation"); m_pRDyn->m_pRDyn->Create(); mprintf(" Trying to open dipole file \"%s\"...\n",s); a = fopen(s,"rt"); if (a == NULL) { eprintf("Error: Could not open file for reading.\n\n"); return; } mprintf("\nReading dipole data:\n"); try { fa = new CxDoubleArray("DipolGrimme():fa"); } catch(...) { fa = NULL; } if (fa == NULL) NewException((double)sizeof(CxDoubleArray),__FILE__,__LINE__,__PRETTY_FUNCTION__); i = 0; while (!feof(a)) { (void)fgets(buf,256,a); if (feof(a)) { mprintf("\n\nEnd of dipole file reached."); break; } buf[strlen(buf)-1] = 0; p = buf; while (strchr(sep,*p) != NULL) p++; q = p; while ((strchr(sep,*p) == NULL) && (*p != 0)) p++; *p = 0; p++; fx = atof(q); while (strchr(sep,*p) != NULL) p++; q = p; while ((strchr(sep,*p) == NULL) && (*p != 0)) p++; *p = 0; p++; fy = atof(q); while (strchr(sep,*p) != NULL) p++; q = p; while ((strchr(sep,*p) == NULL) && (*p != 0)) p++; *p = 0; fz = atof(q); // mprintf("\n( %f | %f | %f)",fx,fy,fz); fa->Add(fx); fa->Add(fy); fa->Add(fz); if ((i % 50) == 0) mprintf("\n%6d ",i); mprintf("."); i++; } mprintf("\n\n%d time steps read.\n\n",i); fclose(a); mprintf(" Autocorrelating cached vectors via FFT...\n"); try { ptfa2 = new CxDoubleArray("DipolGrimme():ptfa2"); } catch(...) { ptfa2 = NULL; } if (ptfa2 == NULL) NewException((double)sizeof(CxDoubleArray),__FILE__,__LINE__,__PRETTY_FUNCTION__); ptfa2->SetSize(i); try { ptfa3 = new CxDoubleArray("DipolGrimme():ptfa3"); } catch(...) { ptfa3 = NULL; } if (ptfa3 == NULL) NewException((double)sizeof(CxDoubleArray),__FILE__,__LINE__,__PRETTY_FUNCTION__); ptfa3->SetSize(i); try { ac = new CAutoCorrelation(); } catch(...) { ac = NULL; } if (ac == NULL) NewException((double)sizeof(CAutoCorrelation),__FILE__,__LINE__,__PRETTY_FUNCTION__); ac->Init(i,m_pRDyn->m_iDepth,true); /* X */ for (z3=0;z3<(int)i;z3++) (*ptfa2)[z3] = (*fa)[z3*3]; ac->AutoCorrelate(ptfa2,ptfa3); for (z3=0;z3<(int)m_pRDyn->m_iDepth;z3++) m_pRDyn->m_pRDyn->AddToBin_Int(z3,(*ptfa3)[z3]); /* Y */ for (z3=0;z3<(int)i;z3++) (*ptfa2)[z3] = (*fa)[z3*3+1]; ac->AutoCorrelate(ptfa2,ptfa3); for (z3=0;z3<(int)m_pRDyn->m_iDepth;z3++) m_pRDyn->m_pRDyn->AddToBin_Int(z3,(*ptfa3)[z3]); /* Z */ for (z3=0;z3<(int)i;z3++) (*ptfa2)[z3] = (*fa)[z3*3+2]; ac->AutoCorrelate(ptfa2,ptfa3); for (z3=0;z3<(int)m_pRDyn->m_iDepth;z3++) { m_pRDyn->m_pRDyn->AddToBin_Int(z3,(*ptfa3)[z3]); m_pRDyn->m_pRDyn->m_fBinEntries += (double)(i-z3) - 3.0; } delete ac; delete ptfa2; delete ptfa3; mprintf(" Finished.\n\n"); mprintf(" %.0f bin entries.\n",m_pRDyn->m_pRDyn->m_fBinEntries); mprintf(" Starting value is %f.\n",m_pRDyn->m_pRDyn->m_pBin[0]); m_pRDyn->m_pRDyn->MultiplyBin(1.0/m_pRDyn->m_pRDyn->m_pBin[0]); sprintf(buf,"rdyn_dipole.csv"); mprintf(" Saving result as %s ...\n",buf); m_pRDyn->m_pRDyn->Write("",buf,"",false); mprintf("\n Creating reorientation spectrum:\n"); for (z=0;zm_iDepth;z++) m_pRDyn->m_pACF->m_pData[z] = m_pRDyn->m_pRDyn->m_pBin[z]; if (m_pRDyn->m_pACF->m_iMirror != 0) { mprintf(" Mirroring ACF...\n"); m_pRDyn->m_pACF->Mirror(m_pRDyn->m_pACF->m_iMirror); sprintf(buf,"rdyn_dipole.mirrored.csv"); mprintf(" Saving mirrored ACF as %s ...\n",buf); m_pRDyn->m_pACF->WriteACF("",buf,""); } if (m_pRDyn->m_pACF->m_bWindowFunction) { mprintf(" Applying window function to ACF...\n"); m_pRDyn->m_pACF->Window(); sprintf(buf,"rdyn_dipole.windowed.csv"); mprintf(" Saving windowed ACF as %s ...\n",buf); m_pRDyn->m_pACF->WriteACF("",buf,""); } mprintf(" Performing Fourier transformation...\n"); try { g_pFFT = new CFFT(); } catch(...) { g_pFFT = NULL; } if (g_pFFT == NULL) NewException((double)sizeof(CFFT),__FILE__,__LINE__,__PRETTY_FUNCTION__); g_pFFT->PrepareFFT_C2C(m_pRDyn->m_pACF->m_iSize+m_pRDyn->m_pACF->m_iZeroPadding); m_pRDyn->m_pACF->Transform(g_pFFT); delete g_pFFT; m_pRDyn->m_pACF->m_pSpectrum->SetMaxRWL(1E7/299.792/g_fTimestepLength); if (m_pRDyn->m_pACF->m_bACF_DB) { mprintf(" Normalizing spectrum to decibel...\n"); m_pRDyn->m_pACF->m_pSpectrum->MakeDB(); } sprintf(buf,"spectrum_dipole.csv"); mprintf(" Saving spectrum as %s ...\n",buf); m_pRDyn->m_pACF->m_pSpectrum->Write("",buf,""); mprintf("\n\n*** Finished ***\n\n"); WriteCredits(); } void InitGlobalVars() { g_bUseBQB = false; g_bFlipCellVectorX = false; g_bFlipCellVectorY = false; g_bFlipCellVectorZ = false; g_iRemoveCOMFixAtom = -1; g_bReadLAMMPSCharges = false; g_bLAMMPSCharge = false; g_bLAMMPSForce = false; g_iVoroPrintLevel = 0; g_bSDFVoro = false; g_bDoubleBox = false; g_bWriteOrtho = false; g_bBoxNonOrtho = false; g_bFoundNonOrtho = false; g_bWriteInputOrder = false; g_bShowCredits = false; g_bPairMSD = false; g_bStreamInput = false; g_bReactive = false; g_sConfFile = NULL; g_bShowConf = false; g_bWriteConf = false; g_bCheckWrite = true; g_bSaxonize = false; g_bUnknownElements = false; g_iStartTime = 0; g_bSMode = false; g_bNoColor = false; g_iColorIntensity = 1; g_bNPT = true; // Nur anfaenglich // g_sNPTFile[0] = 0; g_sNPTFile = ""; g_fNPTFile = NULL; g_fBoxX = 0; g_fBoxY = 0; g_fBoxZ = 0; g_bVerbose = false; g_bNeedMoleculeWrap = false; g_bDipoleDefined = false; g_bDipolGrimme = false; g_fTimestepLength = 0; g_sInputTraj = NULL; g_sInputFile = NULL; g_bKeepOriginalCoords = false; g_bAbortAnalysis = true; g_bMiddleAvg = true; g_bVFHisto = false; g_bUseVelocities = false; g_bUseForces = false; g_bWriteAtomwise = false; g_fBondFactor = 1.15; g_fVelPercentage = 0.95; g_fForcePercentage = 0.95; g_fPos = NULL; g_fVel = NULL; g_fForce = NULL; g_iRefSystemDim = 0; g_iFixMol = -1; g_fInputFile = NULL; g_fInput = NULL; g_fSaveCondFile = NULL; g_bSaveCondSnapshot = false; g_bScanVelocities = false; g_bSilentProgress = false; g_bCreateRevSDF = false; g_bDeriv = false; g_iStrideDetect = -1; g_bGlobalIR = false; g_pGlobalIR = NULL; g_bLMFitSilent = false; g_iLMMaxIter = 200; g_bXYZ4thCol = false; g_bXYZComment6Numbers = false; g_bReadChargesFrom4thXYZ = false; g_bEnvWriteDetailedInfo = false; g_bEnvSortNb = false; g_bEnvDisableSortNb = false; g_bSDFMap = false; g_iSDFMapSmoothGrade = 0; g_bVoroSilent = false; g_pOrderEngine = NULL; g_bQuadrupoleKeepTrace = false; g_bVoronoiMoments = true; g_iWannierAtomType = -1; g_iRefMolNum = 0; g_bProcAlternativeLabels = false; g_bProcDumpAwkScript = false; g_bProcWriteComments = false; g_bProcCellComment = false; g_bInterWarning = false; g_fMolIntegralFile = NULL; g_bVolumetricData = false; g_bElMagProperties = false; g_bReadVelocity = false; g_fVelocityConversion = 0; g_bStrideParsed = false; g_pFixedPlProj = NULL; g_sControlFile = NULL; g_bControlRun = false; g_pControlDB = NULL; g_iControlRT = -1; g_pReactEngine = NULL; g_pBQBInterface = NULL; g_bOrder = false; g_bFixedPlProj = false; g_bROA = false; g_bSFac = false; g_bVoid = false; g_bTegri = false; g_bVoro = false; g_bDomA = false; g_bPlProj = false; g_bPlDF = false; g_bLiDF = false; g_bDens = false; g_bCond = false; g_bSDF = false; g_bRDF = false; g_bVDF = false; g_bFDF = false; g_bADF = false; g_bAvg = false; g_bSaveVelForce = false; g_bSaveRefEnv = false; g_bRefEnvCenter = false; g_bSaveJustTraj = false; g_bVHDF = false; g_bCutCluster = false; g_bNbAnalysis = false; g_bVACF = false; g_bDipACF = false; g_bDDF = false; g_bMSD = false; g_bDipole = false; g_bDipDF = false; g_bCDF = false; g_bAggregation = false; g_bDDisp = false; g_bDACF = false; g_bDLDF = false; g_bRDyn = false; g_bNbExchange = false; g_bRaman = false; g_bIRSpec = false; g_bPowerSpec = false; g_bRegionAnalysis = false; g_bVACFNew = false; } CCrossCorrelation::CCrossCorrelation() { m_iInput = 0; m_iDepth = 0; m_pFFT = NULL; m_pFFT2 = NULL; } CCrossCorrelation::~CCrossCorrelation() { } void CCrossCorrelation::Init(int input, int depth, bool fft) { m_iInput = input; m_iDepth = depth; if (fft) { m_bFFT = true; m_iFFTSize = CalcFFTSize(input,true); try { m_pFFT = new CFFT(); } catch(...) { m_pFFT = NULL; } if (m_pFFT == NULL) NewException((double)sizeof(CFFT),__FILE__,__LINE__,__PRETTY_FUNCTION__); m_pFFT->PrepareFFT_C2C(2*m_iFFTSize); try { m_pFFT2 = new CFFT(); } catch(...) { m_pFFT2 = NULL; } if (m_pFFT2 == NULL) NewException((double)sizeof(CFFT),__FILE__,__LINE__,__PRETTY_FUNCTION__); m_pFFT2->PrepareFFT_C2C(2*m_iFFTSize); try { m_pFFTback = new CFFT(); } catch(...) { m_pFFTback = NULL; } if (m_pFFTback == NULL) NewException((double)sizeof(CFFT),__FILE__,__LINE__,__PRETTY_FUNCTION__); m_pFFTback->PrepareInverseFFT_C2C(2*m_iFFTSize); } else { m_bFFT = false; } } void CCrossCorrelation::CrossCorrelate(CxDoubleArray *inp1, CxDoubleArray *inp2, CxDoubleArray *outp) { int z, z2; double tf; outp->SetSize(m_iDepth); if (m_bFFT) { for (z=0;zm_pInput[z*2] = (*inp1)[z]; m_pFFT->m_pInput[z*2+1] = 0; } for (z=m_iInput;z<2*m_iFFTSize;z++) { m_pFFT->m_pInput[z*2] = 0; m_pFFT->m_pInput[z*2+1] = 0; } m_pFFT->DoFFT(); for (z=0;zm_pInput[z*2] = (*inp2)[z]; m_pFFT2->m_pInput[z*2+1] = 0; } for (z=m_iInput;z<2*m_iFFTSize;z++) { m_pFFT2->m_pInput[z*2] = 0; m_pFFT2->m_pInput[z*2+1] = 0; } m_pFFT2->DoFFT(); for (z=0;zm_pInput[z*2] = (m_pFFT->m_pOutput[z*2]*m_pFFT2->m_pOutput[z*2] + m_pFFT->m_pOutput[z*2+1]*m_pFFT2->m_pOutput[z*2+1]); // a2*b1 - a1*b2 m_pFFTback->m_pInput[z*2+1] = (-m_pFFT2->m_pOutput[z*2]*m_pFFT->m_pOutput[z*2+1] + m_pFFT->m_pOutput[z*2]*m_pFFT2->m_pOutput[z*2+1]); } m_pFFTback->DoFFT(); for (z=0;zm_pOutput[2*z] / m_iFFTSize / 2.0 / ((double)m_iInput - z); } else { for (z=0;z &inp1, std::vector &inp2, std::vector &outp) { int z, z2; double tf; outp.resize(m_iDepth); if (m_bFFT) { for (z=0;zm_pInput[z*2] = inp1[z]; m_pFFT->m_pInput[z*2+1] = 0; } for (z=m_iInput;z<2*m_iFFTSize;z++) { m_pFFT->m_pInput[z*2] = 0; m_pFFT->m_pInput[z*2+1] = 0; } m_pFFT->DoFFT(); for (z=0;zm_pInput[z*2] = inp2[z]; m_pFFT2->m_pInput[z*2+1] = 0; } for (z=m_iInput;z<2*m_iFFTSize;z++) { m_pFFT2->m_pInput[z*2] = 0; m_pFFT2->m_pInput[z*2+1] = 0; } m_pFFT2->DoFFT(); for (z=0;zm_pInput[z*2] = (m_pFFT->m_pOutput[z*2]*m_pFFT2->m_pOutput[z*2] + m_pFFT->m_pOutput[z*2+1]*m_pFFT2->m_pOutput[z*2+1]); // a2*b1 - a1*b2 m_pFFTback->m_pInput[z*2+1] = (-m_pFFT2->m_pOutput[z*2]*m_pFFT->m_pOutput[z*2+1] + m_pFFT->m_pOutput[z*2]*m_pFFT2->m_pOutput[z*2+1]); } m_pFFTback->DoFFT(); for (z=0;zm_pOutput[2*z] / m_iFFTSize / 2.0 / ((double)m_iInput - z); } else { for (z=0;zSetSize(m_iDepth); if (m_bFFT) { for (z=0;zm_pInput[z*2] = (*inp1)[z]; m_pFFT->m_pInput[z*2+1] = 0; } for (z=m_iInput;z<2*m_iFFTSize;z++) { m_pFFT->m_pInput[z*2] = 0; m_pFFT->m_pInput[z*2+1] = 0; } m_pFFT->DoFFT(); for (z=0;zm_pInput[z*2] = (*inp2)[z]; m_pFFT2->m_pInput[z*2+1] = 0; } for (z=m_iInput;z<2*m_iFFTSize;z++) { m_pFFT2->m_pInput[z*2] = 0; m_pFFT2->m_pInput[z*2+1] = 0; } m_pFFT2->DoFFT(); for (z=0;zm_pInput[z*2] = (m_pFFT->m_pOutput[z*2]*m_pFFT2->m_pOutput[z*2] + m_pFFT->m_pOutput[z*2+1]*m_pFFT2->m_pOutput[z*2+1]); // a2*b1 - a1*b2 m_pFFTback->m_pInput[z*2+1] = (-m_pFFT2->m_pOutput[z*2]*m_pFFT->m_pOutput[z*2+1] + m_pFFT->m_pOutput[z*2]*m_pFFT2->m_pOutput[z*2+1]); } m_pFFTback->DoFFT(); for (z=0;zm_pOutput[2*z] / m_iFFTSize / 2.0 / ((double)m_iInput - z); for (z=0;zm_pInput[z*2] = (m_pFFT2->m_pOutput[z*2]*m_pFFT->m_pOutput[z*2] + m_pFFT2->m_pOutput[z*2+1]*m_pFFT->m_pOutput[z*2+1]); // a1*b2 - a2*b1 m_pFFTback->m_pInput[z*2+1] = (-m_pFFT->m_pOutput[z*2]*m_pFFT2->m_pOutput[z*2+1] + m_pFFT2->m_pOutput[z*2]*m_pFFT->m_pOutput[z*2+1]); } m_pFFTback->DoFFT(); for (z=0;zm_pOutput[2*z] / m_iFFTSize / 2.0 / ((double)m_iInput - z); } else { for (z=0;zm_sName,((CAtom*)g_oaAtoms[z])->m_pElement->m_fRadius); if (((CAtom*)g_oaAtoms[z])->m_pElement->m_fRadius < 1.0) mprintf(RED, "Warning: The radius of %s is very small.\n", (const char*)((CAtom*)g_oaAtoms[z])->m_sName); } g_faVoronoiRadii.SetSize(g_iGesAtomCount); for (z=0;zm_pElement->m_fRadius; } if (i == 2) { mprintf("\n Using the following atom radii:\n"); for (z=0;zm_sName,((CAtom*)g_oaAtoms[z])->m_pElement->m_fVdWRadius); if (((CAtom*)g_oaAtoms[z])->m_pElement->m_fVdWRadius < 1.0) mprintf(RED, "Warning: The radius of %s is very small.\n", (const char*)((CAtom*)g_oaAtoms[z])->m_sName); } g_faVoronoiRadii.SetSize(g_iGesAtomCount); for (z=0;zm_pElement->m_fVdWRadius; } if (i == 3) { mprintf(" Enter 0 as radius to exclude atoms from the Voronoi decomposition.\n\n"); g_faVoronoiRadii.SetSize(g_iGesAtomCount); if (AskYesNo(" Assign atom radii per element type (y) or per atom (n)? [yes] ",true)) { mprintf("\n"); f = new double[g_oaAtoms.GetSize()]; for (z=0;zm_sName); } for (z=0;zm_sName); for (z2=0;z2m_baAtomIndex.GetSize();z2++) { if (m->m_baAtomIndex[z2] == g_iVirtAtomType) continue; for (z3=0;z3m_waAtomCount[z2];z3++) { tf = AskFloat_ND(" Radius for %2s%-2d (in pm): ",(const char*)((CAtom*)g_oaAtoms[m->m_baAtomIndex[z2]])->m_sName,z3+1); for (z4=0;z4m_laSingleMolIndex.GetSize();z4++) g_faVoronoiRadii[((CxIntArray*)((CSingleMolecule*)g_oaSingleMolecules[m->m_laSingleMolIndex[z4]])->m_oaAtomOffset[z2])->GetAt(z3)] = tf; } } mprintf("\n"); } } } if (i == 0) mprintf("\n Not using Voronoi radii.\n\n"); else mprintf("\n Voronoi radii defined.\n\n"); } void DumpNonOrthoCellData() { double tf; CxDVector3 veca, vecb, vecc; veca = CxDVector3(g_mBoxFromOrtho(0,0),g_mBoxFromOrtho(0,1),g_mBoxFromOrtho(0,2)); vecb = CxDVector3(g_mBoxFromOrtho(1,0),g_mBoxFromOrtho(1,1),g_mBoxFromOrtho(1,2)); vecc = CxDVector3(g_mBoxFromOrtho(2,0),g_mBoxFromOrtho(2,1),g_mBoxFromOrtho(2,2)); mprintf(WHITE," *** Non-orthorhombic cell geometry ***\n"); mprintf(WHITE," *\n"); mprintf(WHITE," *"); mprintf(" Cell vector A: ( %10.4f | %10.4f | %10.4f ), Length %10.3f pm.\n",g_mBoxFromOrtho(0,0),g_mBoxFromOrtho(0,1),g_mBoxFromOrtho(0,2),veca.GetLength()); mprintf(WHITE," *"); mprintf(" Cell vector B: ( %10.4f | %10.4f | %10.4f ), Length %10.3f pm.\n",g_mBoxFromOrtho(1,0),g_mBoxFromOrtho(1,1),g_mBoxFromOrtho(1,2),vecb.GetLength()); mprintf(WHITE," *"); mprintf(" Cell vector C: ( %10.4f | %10.4f | %10.4f ), Length %10.3f pm.\n",g_mBoxFromOrtho(2,0),g_mBoxFromOrtho(2,1),g_mBoxFromOrtho(2,2),vecc.GetLength()); mprintf(WHITE," *\n"); mprintf(WHITE," *"); mprintf(" Cell angle Alpha (between B and C): %8.3f degree.\n",g_fBoxAngleA); mprintf(WHITE," *"); mprintf(" Cell angle Beta (between A and C): %8.3f degree.\n",g_fBoxAngleB); mprintf(WHITE," *"); mprintf(" Cell angle Gamma (between A and B): %8.3f degree.\n",g_fBoxAngleC); mprintf(WHITE," *\n"); tf = DotP(CrossP(veca,vecb),vecc)/1000000.0; mprintf(WHITE," *"); mprintf(" Cell volume: %.3f Angstrom^3 = %.6f nm^3.\n",tf,tf/1000.0); g_fBoxVolume = tf; mprintf(WHITE," *"); mprintf(" Cell density: %.6f g/cm^3.\n",pow3(GuessBoxSize())/tf/1000000.0); mprintf(WHITE," *\n"); mprintf(WHITE," *"); mprintf(" Orthogonal bounding box of the cell:\n"); mprintf(WHITE," *"); mprintf(" dX = %10.4f pm, dY = %10.4f pm, dZ = %10.4f pm.\n",g_fBoxX,g_fBoxY,g_fBoxZ); mprintf(WHITE," *\n"); mprintf(WHITE," *"); mprintf(" Minimal periodic diameter (smallest distance between atom and its periodic image):\n"); mprintf(WHITE," *"); mprintf(" Min. Diam. = %10.4f pm.\n",g_fBoxMinDiam); mprintf(WHITE," *"); mprintf(" ( dA = %10.4f pm, dB = %10.4f pm, dC = %10.4f pm )\n",g_fBoxMinDiamA,g_fBoxMinDiamB,g_fBoxMinDiamC); mprintf(WHITE," *\n"); mprintf(WHITE," *"); mprintf(" Determinant of the forward transformation matrix is %12G.\n",g_mBoxFromOrtho.Det()); mprintf(WHITE," *"); mprintf(" Determinant of the backward transformation matrix is %12G.\n",g_mBoxToOrtho.Det()); mprintf(WHITE," *\n"); mprintf(WHITE," *** End of non-orthorhombic cell geometry ***\n\n"); } void ExtractXYZCellGeometry(const char *s) { int z; char buf[64]; const char *p, *q; double data[6]; CxDVector3 veca, vecb, vecc; z = 0; p = s; while (*p != 0) { // mprintf("# (A) z=%d \"%s\".\n",z,p); while (strchr("0123456789+-.Ee",*p) == NULL) p++; q = p; // mprintf("# (B) z=%d \"%s\".\n",z,p); while ((strchr("0123456789+-.Ee",*q) != NULL) && (*q != 0)) q++; if (*(q-1) == 0) q--; // mprintf("# (C) z=%d q=\"%s\" p=\"%s\".\n",z,q,p); if (q > p) { // mprintf("# q>p, q-p = %d\n",q-p); // mprintf("# p=\"%s\".\n",p); memcpy(buf,p,q-p); buf[q-p] = 0; // mprintf("# buf = \"%s\".\n",buf); if (atof(buf) != 0) { data[z] = atof(buf); z++; } }// else mprintf("# q <= p\n"); // mprintf("# z=%d.\n",z); if (*q == 0) break; // mprintf("# X.\n"); if (z == 6) break; // mprintf("# Y.\n"); p = q; } if (z < 6) { eprintf("\nError: ExtractXYZCellGeometry(): Comment line of XYZ trajectory does not contain 6 numbers.\n"); eprintf(" (Comment line is \"%s\"). ",s); return; } g_fBoxX = data[0] * 100.0; // Angstrom --> pm g_fBoxY = data[1] * 100.0; g_fBoxZ = data[2] * 100.0; g_fBoxAngleA = data[3]; g_fBoxAngleB = data[4]; g_fBoxAngleC = data[5]; // mprintf(" Computing vectors...\n"); g_mBoxFromOrtho(0,0) = g_fBoxX; g_mBoxFromOrtho(0,1) = 0; g_mBoxFromOrtho(0,2) = 0; g_mBoxFromOrtho(1,0) = g_fBoxY*cos(g_fBoxAngleC*Pi/180.0); g_mBoxFromOrtho(1,1) = g_fBoxY*sin(g_fBoxAngleC*Pi/180.0); g_mBoxFromOrtho(1,2) = 0; g_mBoxFromOrtho(2,0) = g_fBoxZ*cos(g_fBoxAngleB*Pi/180.0); g_mBoxFromOrtho(2,1) = (-(g_mBoxFromOrtho(1,0)*g_fBoxZ*cos(g_fBoxAngleB*Pi/180.0)) + g_fBoxY*g_fBoxZ*cos(g_fBoxAngleA*Pi/180.0))/g_mBoxFromOrtho(1,1); g_mBoxFromOrtho(2,2) = sqrt(-((pow2(g_fBoxZ)*(pow2(g_mBoxFromOrtho(1,1))*(-1 + pow2(cos(g_fBoxAngleB*Pi/180.0))) + pow2(g_mBoxFromOrtho(1,0)*cos(g_fBoxAngleB*Pi/180.0) - g_fBoxY*cos(g_fBoxAngleA*Pi/180.0))))/pow2(g_mBoxFromOrtho(1,1)))); if (g_bDoubleBox) { g_mBoxFromOrtho(0,0) *= g_iDoubleBoxX; g_mBoxFromOrtho(1,0) *= g_iDoubleBoxX; g_mBoxFromOrtho(2,0) *= g_iDoubleBoxX; g_mBoxFromOrtho(0,1) *= g_iDoubleBoxY; g_mBoxFromOrtho(1,1) *= g_iDoubleBoxY; g_mBoxFromOrtho(2,1) *= g_iDoubleBoxY; g_mBoxFromOrtho(0,2) *= g_iDoubleBoxZ; g_mBoxFromOrtho(1,2) *= g_iDoubleBoxZ; g_mBoxFromOrtho(2,2) *= g_iDoubleBoxZ; } // mprintf(" Recalculating angles from vectors...\n"); veca = CxDVector3(g_mBoxFromOrtho(0,0),g_mBoxFromOrtho(0,1),g_mBoxFromOrtho(0,2)); vecb = CxDVector3(g_mBoxFromOrtho(1,0),g_mBoxFromOrtho(1,1),g_mBoxFromOrtho(1,2)); vecc = CxDVector3(g_mBoxFromOrtho(2,0),g_mBoxFromOrtho(2,1),g_mBoxFromOrtho(2,2)); g_fBoxAngleA = acos(DotP(vecb,vecc) / vecb.GetLength() / vecc.GetLength()) * 180.0 / Pi; g_fBoxAngleB = acos(DotP(veca,vecc) / veca.GetLength() / vecc.GetLength()) * 180.0 / Pi; g_fBoxAngleC = acos(DotP(veca,vecb) / veca.GetLength() / vecb.GetLength()) * 180.0 / Pi; // mprintf(" Computing inverse of transformation matrix...\n\n"); g_mBoxToOrtho = CxDMatrix3(g_mBoxFromOrtho); if (!g_mBoxToOrtho.Invert()) { eprintf("ExtractXYZCellGeometry(): Error: Encountered singular cell matrix (cell volume is zero).\n"); abort(); } // Orthogonal bounding box g_fBoxX = fabs(g_mBoxFromOrtho(0,0)) + fabs(g_mBoxFromOrtho(1,0)) + fabs(g_mBoxFromOrtho(2,0)); g_fBoxY = fabs(g_mBoxFromOrtho(0,1)) + fabs(g_mBoxFromOrtho(1,1)) + fabs(g_mBoxFromOrtho(2,1)); g_fBoxZ = fabs(g_mBoxFromOrtho(0,2)) + fabs(g_mBoxFromOrtho(1,2)) + fabs(g_mBoxFromOrtho(2,2)); veca = CxDVector3(g_mBoxFromOrtho(0,0),g_mBoxFromOrtho(0,1),g_mBoxFromOrtho(0,2)); vecb = CxDVector3(g_mBoxFromOrtho(1,0),g_mBoxFromOrtho(1,1),g_mBoxFromOrtho(1,2)); vecc = CxDVector3(g_mBoxFromOrtho(2,0),g_mBoxFromOrtho(2,1),g_mBoxFromOrtho(2,2)); // Minimal diameters g_fBoxMinDiamA = fabs(DotP(veca,Normalize(CrossP(vecb,vecc)))); g_fBoxMinDiamB = fabs(DotP(vecb,Normalize(CrossP(veca,vecc)))); g_fBoxMinDiamC = fabs(DotP(vecc,Normalize(CrossP(veca,vecb)))); g_fBoxMinDiam = MIN3(g_fBoxMinDiamA,g_fBoxMinDiamB,g_fBoxMinDiamC); } void ExtractXYZCellGeometry3(const char *s) { int z; char buf[64]; const char *p, *q; double data[6]; CxDVector3 veca, vecb, vecc; if (strspn(s,"0123456789+-.Ee \r\n\t") != strlen(s)){ eprintf("\nError: ExtractXYZCellGeometry3(): Comment line of XYZ trajectory contains non-numeric characters.\n"); eprintf(" (Comment line is \"%s\"). ",s); return; } z = 0; p = s; while (*p != 0) { // mprintf("# (A) z=%d \"%s\".\n",z,p); while (strchr("0123456789+-.Ee",*p) == NULL) p++; q = p; // mprintf("# (B) z=%d \"%s\".\n",z,p); while ((strchr("0123456789+-.Ee",*q) != NULL) && (*q != 0)) q++; if (*(q-1) == 0) q--; // mprintf("# (C) z=%d q=\"%s\" p=\"%s\".\n",z,q,p); if (q > p) { // mprintf("# q>p, q-p = %d\n",q-p); // mprintf("# p=\"%s\".\n",p); memcpy(buf,p,q-p); buf[q-p] = 0; // mprintf("# buf = \"%s\".\n",buf); if (atof(buf) != 0) { data[z] = atof(buf); z++; } }// else mprintf("# q <= p\n"); // mprintf("# z=%d.\n",z); if (*q == 0) break; // mprintf("# X.\n"); if (z == 3) break; // mprintf("# Y.\n"); p = q; } if (z < 3) { eprintf("\nError: ExtractXYZCellGeometry3(): Comment line of XYZ trajectory does not contain 3 numbers.\n"); eprintf(" (Comment line is \"%s\"). ",s); return; } if (g_bDoubleBox) { g_fBoxX *= g_iDoubleBoxX; g_fBoxY *= g_iDoubleBoxY; g_fBoxZ *= g_iDoubleBoxZ; } g_fBoxX = data[0] * 100.0; // Angstrom --> pm g_fBoxY = data[1] * 100.0; g_fBoxZ = data[2] * 100.0; g_mBoxFromOrtho(0,0) = g_fBoxX; g_mBoxFromOrtho(0,1) = 0; g_mBoxFromOrtho(0,2) = 0; g_mBoxFromOrtho(1,0) = 0; g_mBoxFromOrtho(1,1) = g_fBoxY; g_mBoxFromOrtho(1,2) = 0; g_mBoxFromOrtho(2,0) = 0; g_mBoxFromOrtho(2,1) = 0; g_mBoxFromOrtho(2,2) = g_fBoxZ; g_fBoxAngleA = 90.0; g_fBoxAngleB = 90.0; g_fBoxAngleC = 90.0; /* if (g_bDoubleBox) { g_mBoxFromOrtho(0,0) *= g_iDoubleBoxX; g_mBoxFromOrtho(1,0) *= g_iDoubleBoxX; g_mBoxFromOrtho(2,0) *= g_iDoubleBoxX; g_mBoxFromOrtho(0,1) *= g_iDoubleBoxY; g_mBoxFromOrtho(1,1) *= g_iDoubleBoxY; g_mBoxFromOrtho(2,1) *= g_iDoubleBoxY; g_mBoxFromOrtho(0,2) *= g_iDoubleBoxZ; g_mBoxFromOrtho(1,2) *= g_iDoubleBoxZ; g_mBoxFromOrtho(2,2) *= g_iDoubleBoxZ; }*/ } bool IsElementMetal(const char *s) { // 2nd Period if (mystricmp(s,"Li") == 0) return true; // 3rd Period if (mystricmp(s,"Na") == 0) return true; if (mystricmp(s,"Mg") == 0) return true; if (mystricmp(s,"Al") == 0) return true; // 4th Period if (mystricmp(s, "K") == 0) return true; if (mystricmp(s,"Ca") == 0) return true; if (mystricmp(s,"Sc") == 0) return true; if (mystricmp(s,"Ti") == 0) return true; if (mystricmp(s, "V") == 0) return true; if (mystricmp(s,"Cr") == 0) return true; if (mystricmp(s,"Mn") == 0) return true; if (mystricmp(s,"Fe") == 0) return true; if (mystricmp(s,"Co") == 0) return true; if (mystricmp(s,"Ni") == 0) return true; if (mystricmp(s,"Cu") == 0) return true; if (mystricmp(s,"Zn") == 0) return true; if (mystricmp(s,"Ga") == 0) return true; if (mystricmp(s,"Ge") == 0) return true; // 5th Period if (mystricmp(s,"Rb") == 0) return true; if (mystricmp(s,"Sr") == 0) return true; if (mystricmp(s, "Y") == 0) return true; if (mystricmp(s,"Zr") == 0) return true; if (mystricmp(s,"Nb") == 0) return true; if (mystricmp(s,"Mo") == 0) return true; if (mystricmp(s,"Tc") == 0) return true; if (mystricmp(s,"Ru") == 0) return true; if (mystricmp(s,"Rh") == 0) return true; if (mystricmp(s,"Pd") == 0) return true; if (mystricmp(s,"Ag") == 0) return true; if (mystricmp(s,"Cd") == 0) return true; if (mystricmp(s,"In") == 0) return true; if (mystricmp(s,"Sn") == 0) return true; if (mystricmp(s,"Sb") == 0) return true; // 6th Period if (mystricmp(s,"Cs") == 0) return true; if (mystricmp(s,"Ba") == 0) return true; if (mystricmp(s,"La") == 0) return true; if (mystricmp(s,"Ce") == 0) return true; if (mystricmp(s,"Pr") == 0) return true; if (mystricmp(s,"Nd") == 0) return true; if (mystricmp(s,"Pm") == 0) return true; if (mystricmp(s,"Sm") == 0) return true; if (mystricmp(s,"Eu") == 0) return true; if (mystricmp(s,"Gd") == 0) return true; if (mystricmp(s,"Tb") == 0) return true; if (mystricmp(s,"Dy") == 0) return true; if (mystricmp(s,"Ho") == 0) return true; if (mystricmp(s,"Er") == 0) return true; if (mystricmp(s,"Tm") == 0) return true; if (mystricmp(s,"Yb") == 0) return true; if (mystricmp(s,"Lu") == 0) return true; if (mystricmp(s,"Hf") == 0) return true; if (mystricmp(s,"Ta") == 0) return true; if (mystricmp(s, "W") == 0) return true; if (mystricmp(s,"Re") == 0) return true; if (mystricmp(s,"Os") == 0) return true; if (mystricmp(s,"Ir") == 0) return true; if (mystricmp(s,"Pt") == 0) return true; if (mystricmp(s,"Au") == 0) return true; if (mystricmp(s,"Hg") == 0) return true; if (mystricmp(s,"Tl") == 0) return true; if (mystricmp(s,"Pb") == 0) return true; if (mystricmp(s,"Bi") == 0) return true; // 7th Period if (mystricmp(s,"Fr") == 0) return true; if (mystricmp(s,"Ra") == 0) return true; if (mystricmp(s,"Ac") == 0) return true; if (mystricmp(s,"Th") == 0) return true; if (mystricmp(s,"Pa") == 0) return true; if (mystricmp(s, "U") == 0) return true; if (mystricmp(s,"Np") == 0) return true; if (mystricmp(s,"Pu") == 0) return true; if (mystricmp(s,"Am") == 0) return true; if (mystricmp(s,"Cm") == 0) return true; if (mystricmp(s,"Bk") == 0) return true; if (mystricmp(s,"Cf") == 0) return true; if (mystricmp(s,"Es") == 0) return true; if (mystricmp(s,"Fm") == 0) return true; if (mystricmp(s,"Md") == 0) return true; if (mystricmp(s,"No") == 0) return true; if (mystricmp(s,"Lr") == 0) return true; return false; } bool IsElementNobleGas(const char *s) { if (mystricmp(s,"He") == 0) return true; if (mystricmp(s,"Ne") == 0) return true; if (mystricmp(s,"Ar") == 0) return true; if (mystricmp(s,"Kr") == 0) return true; if (mystricmp(s,"Xe") == 0) return true; if (mystricmp(s,"Rn") == 0) return true; return false; } void WriteRevisionInfo() { std::vector sa; unsigned int z, len; mprintf("Revision information of the source code files:\n\n"); len = 0; _begin: sa.push_back( GetRevisionInfo_2df( len ) ); sa.push_back( GetRevisionInfo_acf( len ) ); sa.push_back( GetRevisionInfo_analysisgroup( len ) ); sa.push_back( GetRevisionInfo_asciiart( len ) ); sa.push_back( GetRevisionInfo_atomgroup( len ) ); sa.push_back( GetRevisionInfo_backtrace( len ) ); sa.push_back( GetRevisionInfo_base64( len ) ); sa.push_back( GetRevisionInfo_bicgstab( len ) ); sa.push_back( GetRevisionInfo_bintools( len ) ); sa.push_back( GetRevisionInfo_bintree( len ) ); sa.push_back( GetRevisionInfo_bqb_alphabet( len ) ); sa.push_back( GetRevisionInfo_bqb_bitset( len ) ); sa.push_back( GetRevisionInfo_bqb_crc( len ) ); sa.push_back( GetRevisionInfo_bqb_cubeframe( len ) ); sa.push_back( GetRevisionInfo_bqb_driver( len ) ); sa.push_back( GetRevisionInfo_bqb_engine( len ) ); sa.push_back( GetRevisionInfo_bqb_extrapolator( len ) ); sa.push_back( GetRevisionInfo_bqb_format( len ) ); sa.push_back( GetRevisionInfo_bqb_hilbert( len ) ); sa.push_back( GetRevisionInfo_bqb_hufftree( len ) ); sa.push_back( GetRevisionInfo_bqb_integerengine( len ) ); sa.push_back( GetRevisionInfo_bqb_interface( len ) ); sa.push_back( GetRevisionInfo_bqb_largeinteger( len ) ); sa.push_back( GetRevisionInfo_bqb_linalg( len ) ); sa.push_back( GetRevisionInfo_bqb_math( len ) ); sa.push_back( GetRevisionInfo_bqb_parmset( len ) ); sa.push_back( GetRevisionInfo_bqb_tools( len ) ); sa.push_back( GetRevisionInfo_bqbtool( len ) ); sa.push_back( GetRevisionInfo_chiral( len ) ); sa.push_back( GetRevisionInfo_dacf( len ) ); sa.push_back( GetRevisionInfo_database( len ) ); sa.push_back( GetRevisionInfo_df( len ) ); sa.push_back( GetRevisionInfo_diagonal( len ) ); sa.push_back( GetRevisionInfo_domain( len ) ); sa.push_back( GetRevisionInfo_elementdata( len ) ); sa.push_back( GetRevisionInfo_fdf( len ) ); sa.push_back( GetRevisionInfo_fft( len ) ); sa.push_back( GetRevisionInfo_fixplproj( len ) ); sa.push_back( GetRevisionInfo_gather( len ) ); sa.push_back( GetRevisionInfo_globalvar( len ) ); sa.push_back( GetRevisionInfo_grace( len ) ); sa.push_back( GetRevisionInfo_hbond( len ) ); sa.push_back( GetRevisionInfo_interface( len ) ); sa.push_back( GetRevisionInfo_internalcoord( len ) ); sa.push_back( GetRevisionInfo_ionpair( len ) ); sa.push_back( GetRevisionInfo_ir( len ) ); sa.push_back( GetRevisionInfo_kiss_fft( len ) ); sa.push_back( GetRevisionInfo_largeinteger( len ) ); sa.push_back( GetRevisionInfo_linalg( len ) ); sa.push_back( GetRevisionInfo_lmmin( len ) ); sa.push_back( GetRevisionInfo_lmwrapper( len ) ); sa.push_back( GetRevisionInfo_lu_decomp( len ) ); sa.push_back( GetRevisionInfo_luzar( len ) ); sa.push_back( GetRevisionInfo_maintools( len ) ); sa.push_back( GetRevisionInfo_moltools( len ) ); sa.push_back( GetRevisionInfo_nbexchange( len ) ); sa.push_back( GetRevisionInfo_nbsearch( len ) ); sa.push_back( GetRevisionInfo_normalcoordinate( len ) ); sa.push_back( GetRevisionInfo_normalmode( len ) ); sa.push_back( GetRevisionInfo_order( len ) ); sa.push_back( GetRevisionInfo_order_chain( len ) ); sa.push_back( GetRevisionInfo_order_vector( len ) ); sa.push_back( GetRevisionInfo_pdf( len ) ); sa.push_back( GetRevisionInfo_plproj( len ) ); sa.push_back( GetRevisionInfo_posdomain( len ) ); sa.push_back( GetRevisionInfo_qr_fact( len ) ); sa.push_back( GetRevisionInfo_raman( len ) ); sa.push_back( GetRevisionInfo_random( len ) ); sa.push_back( GetRevisionInfo_reflux( len ) ); sa.push_back( GetRevisionInfo_region( len ) ); sa.push_back( GetRevisionInfo_reordyn( len ) ); sa.push_back( GetRevisionInfo_revsdf( len ) ); sa.push_back( GetRevisionInfo_roa( len ) ); sa.push_back( GetRevisionInfo_sdfmap( len ) ); sa.push_back( GetRevisionInfo_spectrum( len ) ); sa.push_back( GetRevisionInfo_statistics( len ) ); sa.push_back( GetRevisionInfo_structurefactor( len ) ); sa.push_back( GetRevisionInfo_tensor( len ) ); sa.push_back( GetRevisionInfo_tetrapak( len ) ); sa.push_back( GetRevisionInfo_timestep( len ) ); sa.push_back( GetRevisionInfo_tools( len ) ); sa.push_back( GetRevisionInfo_travis( len ) ); sa.push_back( GetRevisionInfo_v_base( len ) ); sa.push_back( GetRevisionInfo_v_base_wl( len ) ); sa.push_back( GetRevisionInfo_v_cell( len ) ); sa.push_back( GetRevisionInfo_v_common( len ) ); sa.push_back( GetRevisionInfo_v_compute( len ) ); sa.push_back( GetRevisionInfo_v_container( len ) ); sa.push_back( GetRevisionInfo_v_container_prd( len ) ); sa.push_back( GetRevisionInfo_v_pre_container( len ) ); sa.push_back( GetRevisionInfo_v_unitcell( len ) ); sa.push_back( GetRevisionInfo_v_wall( len ) ); sa.push_back( GetRevisionInfo_vorowrapper( len ) ); sa.push_back( GetRevisionInfo_xbytearray( len ) ); sa.push_back( GetRevisionInfo_xdf( len ) ); sa.push_back( GetRevisionInfo_xdmatrix3( len ) ); sa.push_back( GetRevisionInfo_xdmatrixmn( len ) ); sa.push_back( GetRevisionInfo_xdoublearray( len ) ); sa.push_back( GetRevisionInfo_xdvec3array( len ) ); sa.push_back( GetRevisionInfo_xdvector3( len ) ); sa.push_back( GetRevisionInfo_xdvectorn( len ) ); sa.push_back( GetRevisionInfo_xintarray( len ) ); sa.push_back( GetRevisionInfo_xlongarray( len ) ); sa.push_back( GetRevisionInfo_xmemfile( len ) ); sa.push_back( GetRevisionInfo_xobarray( len ) ); sa.push_back( GetRevisionInfo_xptrarray( len ) ); sa.push_back( GetRevisionInfo_string( len ) ); sa.push_back( GetRevisionInfo_xwordarray( len ) ); sa.push_back( GetRevisionInfo_ziggurat( len ) ); if (len == 0) { for (z=0;z len) len = strlen(sa[z]); sa.clear(); goto _begin; } for (z=0;z. *****************************************************************************/ #ifndef MAINTOOLS_H #define MAINTOOLS_H // This must always be the first include directive #include "config.h" #include "travis.h" #include "tools.h" #include "database.h" #include "statistics.h" #include "element.h" #include "base64.h" bool OpenInputTrajectory(); bool CloseInputTrajectory(); bool InputTrajectoryEOF(); bool SeekInputTrajectory(int step); void WriteRevisionInfo(); void CheckSourceVersion(); int bqbtool_main(int argc, const char *argv[]); class CAutoCorrelation : public CxObject { public: CAutoCorrelation(); ~CAutoCorrelation(); void Init(int input, int depth, bool fft); void AutoCorrelate(CxDoubleArray *inp, CxDoubleArray *outp); void AutoCorrelate(std::vector &inp, std::vector &outp); void AutoCorrelateSqrt(CxDoubleArray *inp, CxDoubleArray *outp); int m_iInput; int m_iDepth; int m_iFFTSize; bool m_bFFT; CFFT *m_pFFT; CFFT *m_pFFT2; }; class CCrossCorrelation : public CxObject { public: CCrossCorrelation(); ~CCrossCorrelation(); void Init(int input, int depth, bool fft); void CrossCorrelate(CxDoubleArray *inp1, CxDoubleArray *inp2, CxDoubleArray *outp); void CrossCorrelate(std::vector &inp1, std::vector &inp2, std::vector &outp); void CrossCorrelateSymmetric(CxDoubleArray *inp1, CxDoubleArray *inp2, CxDoubleArray *outp); int m_iInput; int m_iDepth; int m_iFFTSize; bool m_bFFT; CFFT *m_pFFT; CFFT *m_pFFT2; CFFT *m_pFFTback; }; /*void AutoCorrelate(CxFloatArray *inp, CxFloatArray *outp, int depth); void AutoCorrelate(CxFloatArray *inp, CxFloatArray *outp, int depth, CFFT *fft, CFFT *fft2);*/ CAnalysisGroup* AddAnalysisGroup(const char *name); void AddAnalysis(CAnalysisGroup* g, const char *name, const char *abbrev); void InitAnalyses(); void DumpAnalyses(); //void UniteNb(); bool ParseAtom(const char *s, int refmol, int &ty, int &rty, int &atom); bool ParseRefSystem(int refmol, const char *s, int points); CTimeStep* GetTimeStep(int i); CTimeStep** GetTimeStepAddress(int i); void CalcVelocities(); void CalcVolumetricDataTimeDev(); void CalcCurrentDensity(); void CalcForces(); /*double AtomMass(char *s); int AtomOrd(char *s); double AtomRadius(char *s);*/ CElement* FindElement(const char *s, bool quiet); double GuessBoxSize(); void strtolower(char *s); void SortAtoms(); void SortElementsLabel(); void SortElementsMass(); bool SetAnalysis(const char *s); bool ParseFunctions(const char *s); bool ParsePeriodic(const char *s); void WriteHeader(); void CommandLineHelp(); bool ParseArgs(int argc, const char *argv[]); void ParsePassiveArgs(int argc, const char *argv[]); //void VariablesToDatabase(); //void DatabaseToVariables(); //void WriteDefaultSettings(const char *s); void CreateDatabaseDefaults(); void LoadSettings(); void InitDatabase(); void RECURSION_BuildCDF(CObservation *o, int channel, int om, CxDoubleArray **data, double *result); CVirtualAtom* AddVirtualAtom(int mol); void RemoveAllElements(); void RemoveAllAtoms(); void RemoveAllAnalyses(); void RemoveAllMolecules(); void RemoveAllObservations(); void GetTravisPath(); void ReorderAtoms(int molecule); void ReorderLikeInput(); void DoubleBoxHelper(unsigned char tpx, unsigned char tpy, unsigned char tpz); unsigned long GraceColor(int z, double bleach); void parseCoreCharges(); bool setupWannier(); void ParseDipole(); void parseMagneticDipole(); void DipolGrimme(const char *s); inline CxDVector3 FoldVector(CxDVector3 v) { if (g_bBoxNonOrtho) { CxDVector3 w; w = g_mBoxToOrtho * v; while (w[0] > 0.5) w[0] -= 1.0; while (w[0] <= -0.5) w[0] += 1.0; while (w[1] > 0.5) w[1] -= 1.0; while (w[1] <= -0.5) w[1] += 1.0; while (w[2] > 0.5) w[2] -= 1.0; while (w[2] <= -0.5) w[2] += 1.0; return g_mBoxFromOrtho * w; } else { if (g_bPeriodicX) { while (v[0] > g_fBoxX/2) v[0] -= g_fBoxX; while (v[0] <= -g_fBoxX/2) v[0] += g_fBoxX; } if (g_bPeriodicY) { while (v[1] > g_fBoxY/2) v[1] -= g_fBoxY; while (v[1] <= -g_fBoxY/2) v[1] += g_fBoxY; } if (g_bPeriodicZ) { while (v[2] > g_fBoxZ/2) v[2] -= g_fBoxZ; while (v[2] <= -g_fBoxZ/2) v[2] += g_fBoxZ; } } return v; } inline CxDVector3 FoldVectorPositive(CxDVector3 v) { if (g_bBoxNonOrtho) { CxDVector3 w; w = g_mBoxToOrtho * v; while (w[0] >= 1.0) w[0] -= 1.0; while (w[0] < 0) w[0] += 1.0; while (w[1] >= 1.0) w[1] -= 1.0; while (w[1] < 0) w[1] += 1.0; while (w[2] >= 1.0) w[2] -= 1.0; while (w[2] < 0) w[2] += 1.0; return g_mBoxFromOrtho * w; } else { if (g_bPeriodicX) { while (v[0] >= g_fBoxX) v[0] -= g_fBoxX; while (v[0] < 0) v[0] += g_fBoxX; } if (g_bPeriodicY) { while (v[1] >= g_fBoxY) v[1] -= g_fBoxY; while (v[1] < 0) v[1] += g_fBoxY; } if (g_bPeriodicZ) { while (v[2] >= g_fBoxZ) v[2] -= g_fBoxZ; while (v[2] < 0) v[2] += g_fBoxZ; } } return v; } inline double FoldedLength(CxDVector3 v) { if (g_bBoxNonOrtho) { CxDVector3 w; w = g_mBoxToOrtho * v; while (w[0] > 0.5) w[0] -= 1.0; while (w[0] <= -0.5) w[0] += 1.0; while (w[1] > 0.5) w[1] -= 1.0; while (w[1] <= -0.5) w[1] += 1.0; while (w[2] > 0.5) w[2] -= 1.0; while (w[2] <= -0.5) w[2] += 1.0; return (g_mBoxFromOrtho * w).GetLength(); } else { if (g_bPeriodicX) { while (v[0] > g_fBoxX/2) v[0] -= g_fBoxX; while (v[0] <= -g_fBoxX/2) v[0] += g_fBoxX; } if (g_bPeriodicY) { while (v[1] > g_fBoxY/2) v[1] -= g_fBoxY; while (v[1] <= -g_fBoxY/2) v[1] += g_fBoxY; } if (g_bPeriodicZ) { while (v[2] > g_fBoxZ/2) v[2] -= g_fBoxZ; while (v[2] <= -g_fBoxZ/2) v[2] += g_fBoxZ; } return v.GetLength(); } } /*inline CxDVector3 FoldVector1(CxDVector3 v) { while (v[0] >= 0.5) v[0] -= 1.0; while (v[0] < -0.5) v[0] += 1.0; while (v[1] >= 0.5) v[1] -= 1.0; while (v[1] < -0.5) v[1] += 1.0; while (v[2] >= 0.5) v[2] -= 1.0; while (v[2] < -0.5) v[2] += 1.0; return v; }*/ inline double MeshRandom() { if (g_bProcAddMeshJitter) return ((rand()%20001)-10000)/2000000.0*g_fProcAddMeshJitter; else return 0; } void BuildAtomIndices(); bool DetermineTrajFormat(); void PrintSMode(); void PrintBMode(); void WriteCredits(); void WriteCredits_Long(); unsigned long CalcFFTSize(unsigned long i, bool silent); //void FormatTime(unsigned long eta, char *buf); void FormatTime(unsigned long eta, CxString *buf); void RenderStructFormulas(int tries); void RenderFormula(const char *s, int tries); void InitGlobalVars(); void ParseVoronoiRadii(); void DumpNonOrthoCellData(); void ExtractXYZCellGeometry(const char *s); void ExtractXYZCellGeometry3(const char *s); const char* GetFileExtension(const char *s); bool IsElementMetal(const char *s); bool IsElementNobleGas(const char *s); #endif travis-src-190101/src/moltools.cpp0100777000000000000000000101462513412725620014020 0ustar00/***************************************************************************** TRAVIS - Trajectory Analyzer and Visualizer http://www.travis-analyzer.de/ Copyright (c) 2009-2019 Martin Brehm 2012-2019 Martin Thomas 2016-2019 Sascha Gehrke This file was written by Martin Brehm. --------------------------------------------------------------------------- This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . *****************************************************************************/ // This must always be the first include directive #include "config.h" #include "moltools.h" #include "travis.h" #include "maintools.h" #include "plproj.h" #include const char *GetRevisionInfo_moltools(unsigned int len) { static char buf[256]; GET_REVISION_INFO( buf, len ); return buf; } const char *GetSourceVersion_moltools() { static char buf[256]; GET_SOURCE_VERSION( buf ); return buf; } CAtom::CAtom() { m_pElement = NULL; m_bExclude = false; m_pMergedTo = NULL; m_iIndex = -1; } CAtom::~CAtom() { } CVirtualAtom::CVirtualAtom() { m_faWeight.SetName("CVirtualAtom::m_faWeight"); } CVirtualAtom::~CVirtualAtom() { } CMolecule::CMolecule() { m_iWannierCount = 0; m_sName = NULL; m_fCharge = 0; m_bPseudo = false; m_bChargesAssigned = false; m_bPolymer = false; m_baAtomIndex.SetName("CMolecule::m_baAtomIndex"); m_waAtomCount.SetName("CMolecule::m_waAtomCount"); m_laSingleMolIndex.SetName("CMolecule::m_laSingleMolIndex"); m_laVirtualAtoms.SetName("CMolecule::m_laVirtualAtoms"); m_oaNewNumbers.SetName("CMolecule::m_oaNewNumbers"); m_oaRingAtomTypes.SetName("CMolecule::m_oaRingAtomTypes"); m_oaRingAtoms.SetName("CMolecule::m_oaRingAtoms"); m_oaCharges.SetName("CMolecule::m_oaCharges"); m_iDipoleMode = 0; m_pDipoleFile = NULL; } CMolecule::~CMolecule() { if (m_sName != NULL) { delete[] m_sName; m_sName = NULL; } if(m_pDipoleFile != NULL) fclose(m_pDipoleFile); } CMolAtom::CMolAtom() { m_oaBonds.SetName("CMolAtom::m_oaBonds"); } CMolAtom::~CMolAtom() { } CSingleMolecule::CSingleMolecule() { m_bPseudo = false; m_oaBondGroups.SetName("CSingleMolecule::m_oaBondGroups"); m_oaBonds.SetName("CSingleMolecule::m_oaBonds"); m_oaAngleGroups.SetName("CSingleMolecule::m_oaAngleGroups"); m_oaAngles.SetName("CSingleMolecule::m_oaAngles"); m_oaRings.SetName("CSingleMolecule::m_oaRings"); m_laBonds.SetName("CSingleMolecule::m_laBonds"); m_laWannier.SetName("CSingleMolecule::m_laWannier"); m_oaAtomOffset.SetName("CSingleMolecule::m_oaAtomOffset"); m_oaMolAtoms.SetName("CSingleMolecule::m_oaMolAtoms"); m_baAtomIndex.SetName("CSingleMolecule::m_baAtomIndex"); } CSingleMolecule::~CSingleMolecule() { } CADF::CADF() { m_pADF = NULL; m_oaVectors.SetName("CADF::m_oaVectors"); m_faACF.SetName("CADF::m_faACF"); m_faMinMaxAngle.SetName("CADF::m_faMinMaxAngle"); } CADF::~CADF() { } CDDF::CDDF() { m_bRotate = false; m_oaVectors.SetName("CDDF::m_oaVectors"); m_faLastData.SetName("CDDF::m_faLastData"); m_laRotation.SetName("CDDF::m_laRotation"); m_faACF.SetName("CDDF::m_faACF"); } CDDF::~CDDF() { } CMSD::CMSD() { m_oaCache.SetName("CMSD::m_oaCache"); } CMSD::~CMSD() { } CVHDF::CVHDF() { m_sName = NULL; m_sShortName = NULL; m_pVHDF = NULL; m_oaVectors.SetName("CVHDF::m_oaVectors"); } CVHDF::~CVHDF() { if (m_sName != NULL) { delete[] m_sName; m_sName = NULL; } if (m_sShortName != NULL) { delete[] m_sShortName; m_sShortName = NULL; } if (m_pVHDF != NULL) { delete m_pVHDF; m_pVHDF = NULL; } } CRDF::CRDF() { m_fDist = NULL; m_pRDF = NULL; m_bProbDens = false; m_bLine = false; m_faMinMaxDist.SetName("CRDF::m_faMinMaxDist"); m_oaVectors.SetName("CRDF::m_oaVectors"); m_faACF.SetName("CRDF::m_faACF"); } CPlDF::CPlDF() { m_pPlDF = NULL; m_oaVectors.SetName("CPlDF::m_oaVectors"); m_faACF.SetName("CPlDF::m_faACF"); } CLiDF::CLiDF() { m_pLiDF = NULL; m_oaVectors.SetName("CLiDF::m_oaVectors"); m_faACF.SetName("CLiDF::m_faACF"); } CRDF::~CRDF() { if (m_sName != NULL) { delete[] m_sName; m_sName = NULL; } if (m_sShortName != NULL) { delete[] m_sShortName; m_sShortName = NULL; } if (m_fDist != NULL) { delete[] m_fDist; m_fDist = NULL; } if (m_pRDF != NULL) { delete m_pRDF; m_pRDF = NULL; } if (m_faData != NULL) { delete[] m_faData; m_faData = NULL; } } CDensDF::CDensDF() { m_pDensDF = NULL; } CDensDF::~CDensDF() { if (m_sName != NULL) { delete[] m_sName; m_sName = NULL; } if (m_sShortName != NULL) { delete[] m_sShortName; m_sShortName = NULL; } if (m_pDensDF != NULL) { delete m_pDensDF; m_pDensDF = NULL; } } CVDF::CVDF() { m_faACF.SetName("CVDF::m_faACF"); m_bSplitCart = false; } CVDF::~CVDF() { } CDipDF::CDipDF() { m_faACF.SetName("CDipDF::m_faACF"); } CDipDF::~CDipDF() { } CSDF::CSDF() { m_pCutPlane = NULL; m_fPosCounter = 0; m_fAtom2PosX = 0; m_fAtom3PosX = 0; m_fAtom3PosY = 0; } CSDF::~CSDF() { } CCDF::CCDF() { m_bAxisDivide = false; } CCDF::~CCDF() { } CConditionSubGroup::CConditionSubGroup() { m_fPassed = 0; m_fTotal = 0; m_oaConditions.SetName("CConditionSubGroup::m_oaConditions"); } CConditionSubGroup::~CConditionSubGroup() { } CConditionGroup::CConditionGroup() { m_pTable = NULL; m_bInactive = false; m_fPassed = 0; m_fTotal = 0; m_iPassCounter = NULL; m_bAlwaysTrue = NULL; m_oaConditionSubGroups.SetName("CConditionGroup::m_oaConditionSubGroups"); } CConditionGroup::~CConditionGroup() { } bool ContainsDigit(const char *s) { if (strcspn(s,"0123456789") != strlen(s)) return true; return false; } bool ContainsDigitOrSpecial(const char *s) { if (strspn(s,"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ") != strlen(s)) return true; return false; } /* void ReplaceDigits(char *s) { char uf[32]; char *p, *q; bool b; p = s; q = buf; b = false; while (*p != 0) { if (b) { switch(*p) { case '1': *q = 'a'; break; case '2': *q = 'b'; break; case '3': *q = 'c'; break; case '4': *q = 'd'; break; case '5': *q = 'e'; break; case '6': *q = 'f'; break; case '7': *q = 'g'; break; case '8': *q = 'h'; break; case '9': *q = 'i'; break; case '0': *q = 'z'; break; default: *q = *p; } } else { switch(*p) { case '1': b = true; *q = '_'; q++; *q = 'a'; break; case '2': b = true; *q = '_'; q++; *q = 'b'; break; case '3': b = true; *q = '_'; q++; *q = 'c'; break; case '4': b = true; *q = '_'; q++; *q = 'd'; break; case '5': b = true; *q = '_'; q++; *q = 'e'; break; case '6': b = true; *q = '_'; q++; *q = 'f'; break; case '7': b = true; *q = '_'; q++; *q = 'g'; break; case '8': b = true; *q = '_'; q++; *q = 'h'; break; case '9': b = true; *q = '_'; q++; *q = 'i'; break; case '0': b = true; *q = '_'; q++; *q = 'z'; break; default: *q = *p; } } p++; q++; } *q = 0; strcpy(s,buf); } */ void ReplaceDigits(CxString *s) { int z; char buf[256], *p; p = buf; for (z=0;zGetLength();z++) if (strchr("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ",(*s)[z]) != 0) *(p++) = (*s)[z]; if (p == buf) *(p++) = 'X'; *p = 0; s->strcpy(buf); /* char buf[256]; char *p, *q; bool b; p = s->GetWritePointer(); q = buf; b = false; while (*p != 0) { if (b) { switch(*p) { case '1': q--; break; case '2': q--; break; case '3': q--; break; case '4': q--; break; case '5': q--; break; case '6': q--; break; case '7': q--; break; case '8': q--; break; case '9': q--; break; case '0': q--; break; case '"': *q = '_'; break; case '\'': *q = '_'; break; case '-': *q = '_'; break; case '+': *q = '_'; break; case '.': *q = '_'; break; case ',': *q = '_'; break; case ':': *q = '_'; break; case ';': *q = '_'; break; case '#': *q = '_'; break; case '^': *q = '_'; break; case '!': *q = '_'; break; case '$': *q = '_'; break; case '%': *q = '_'; break; case '&': *q = '_'; break; case '*': *q = '_'; break; case '~': *q = '_'; break; case '/': *q = '_'; break; case '\\': *q = '_'; break; case '(': *q = '_'; break; case ')': *q = '_'; break; case '[': *q = '_'; break; case ']': *q = '_'; break; case '{': *q = '_'; break; case '}': *q = '_'; break; case '?': *q = '_'; break; case '=': *q = '_'; break; case '>': *q = '_'; break; case '<': *q = '_'; break; case '|': *q = '_'; break; default: *q = *p; } } else { switch(*p) { case '1': q--; break; case '2': q--; break; case '3': q--; break; case '4': q--; break; case '5': q--; break; case '6': q--; break; case '7': q--; break; case '8': q--; break; case '9': q--; break; case '0': q--; break; case '"': b = true; *q = '_'; break; case '\'': b = true; *q = '_'; break; case '-': b = true; *q = '_'; break; case '+': b = true; *q = '_'; break; case '.': b = true; *q = '_'; break; case ',': b = true; *q = '_'; break; case ':': b = true; *q = '_'; break; case ';': b = true; *q = '_'; break; case '#': b = true; *q = '_'; break; case '^': b = true; *q = '_'; break; case '!': b = true; *q = '_'; break; case '$': b = true; *q = '_'; break; case '%': b = true; *q = '_'; break; case '&': b = true; *q = '_'; break; case '*': b = true; *q = '_'; break; case '~': b = true; *q = '_'; break; case '/': b = true; *q = '_'; break; case '\\': b = true; *q = '_'; break; case '(': b = true; *q = '_'; break; case ')': b = true; *q = '_'; break; case '[': b = true; *q = '_'; break; case ']': b = true; *q = '_'; break; case '{': b = true; *q = '_'; break; case '}': b = true; *q = '_'; break; case '?': b = true; *q = '_'; break; case '=': b = true; *q = '_'; break; case '>': b = true; *q = '_'; break; case '<': b = true; *q = '_'; break; case '|': b = true; *q = '_'; break; default: *q = *p; } } p++; q++; } *q = 0; s->strcpy(buf);*/ } void xAddAtom(const char *s, bool virt) { BTIN; int z; CAtom *a; // char buf[64]; CxString buf; if (g_oaAtoms.GetSize() >= 254) { eprintf("Error: More than 254 different atom types not supported.\n"); return; } // strcpy(buf,s); buf.strcpy(s); static bool first = true; if (!virt) { ReplaceDigits(&buf); if (ContainsDigitOrSpecial(s)) { if (first) { first = false; eprintf(" Digits or special characters in element labels not allowed.\n"); eprintf(" Removing those characters from all atom labels.\n\n"); } } } // printf("AddAtom: \"%s\".\n",s); for (z=0;zm_sName)==0) { ((CAtom*)g_oaAtoms[z])->m_iCount++; BTOUT; return; } } try { a = new CAtom(); } catch(...) { a = NULL; } if (a == NULL) NewException((double)sizeof(CAtom),__FILE__,__LINE__,__PRETTY_FUNCTION__); a->m_iIndex = g_oaAtoms.GetSize(); //strcpy(a->m_sName,buf); a->m_sName = (const char*)buf; if (islower(a->m_sName(0))) a->m_sName(0) = (char)toupper(a->m_sName(0)); if (strlen(a->m_sName) > 1) if (isupper(a->m_sName(1))) a->m_sName(1) = (char)tolower(a->m_sName(1)); a->m_iCount = 1; /* if (s[0] != '#') {*/ a->m_pElement = FindElement(buf,false); if (a->m_pElement == NULL) { try { a->m_pElement = new CElement(); } catch(...) { a->m_pElement = NULL; } if (a->m_pElement == NULL) NewException((double)sizeof(CElement),__FILE__,__LINE__,__PRETTY_FUNCTION__); try { a->m_pElement->m_sLabel = new char[strlen(a->m_sName)+1]; } catch(...) { a->m_pElement->m_sLabel = NULL; } if (a->m_pElement->m_sLabel == NULL) NewException((double)(strlen(a->m_sName)+1)*sizeof(char),__FILE__,__LINE__,__PRETTY_FUNCTION__); strcpy(a->m_pElement->m_sLabel,a->m_sName); } /* a->m_fMass = AtomMass(s); a->m_fRadius = AtomRadius(s); a->m_iOrd = AtomOrd(s);*/ // a->m_fVDWRadius = AtomVDWRadius(s); /* } else { a->m_fMass = 0.0f; a->m_fRadius = 0.0f; a->m_iOrd = 0; // a->m_fVDWRadius = 0.0f; }*/ g_oaAtoms.Add(a); // g_pAtoms[g_iElementCount].Offset = offset; // printf("Fuege Atom %s an Stelle %d neu hinzu. Der Offset ist %d.\n",s,g_iAtomCount,offset); // g_iElementCount++; BTOUT; } void CSingleMolecule::Dump() { BTIN; int z, z2; mprintf("### Single Molecule Dump ###\n"); mprintf("%d Elemente.\n",m_baAtomIndex.GetSize()); for (z=0;zm_sName,((CxIntArray*)m_oaAtomOffset[z])->GetSize()); for (z2=0;z2<((CxIntArray*)m_oaAtomOffset[z])->GetSize();z2++) { mprintf("%d",((CxIntArray*)m_oaAtomOffset[z])->GetAt(z2)); if (z2 < ((CxIntArray*)m_oaAtomOffset[z])->GetSize()-1) mprintf(", "); } mprintf("\n"); } BTOUT; } void CMolecule::Dump() { BTIN; int z; mprintf("### Molecule Type Dump ###\n"); mprintf("%d Elemente.\n",m_baAtomIndex.GetSize()); for (z=0;zm_sName,m_waAtomCount[z]); BTOUT; } void CADF::BuildName() { BTIN; int z, z2; // char tmp[32768]; CxString tmp; CAtomGroup *ag; // tmp[0] = 0; tmp = ""; if (m_iDeriv != 0) // sprintf(tmp,"deriv%d_",m_iDeriv); tmp.sprintf("deriv%d_",m_iDeriv); for (z2=0;z2m_sName); tmp.strcat(ag->m_sName); if (m_iRefOrSec[z][0]) // strcat(tmp,"o_"); tmp.strcat("o_"); else // strcat(tmp,"r_"); tmp.strcat("r_"); tmp.strcat(((CAtomGroup*)m_oaVectors[z2*6+z*3+1])->m_sName); if (m_iRefOrSec[z][1]) // strcat(tmp,"o_"); tmp.strcat("o_"); else // strcat(tmp,"r_"); tmp.strcat("r_"); // strcat(tmp,((CAtomGroup*)m_oaVectors[z2*6+z*3+2])->m_sName); tmp.strcat(((CAtomGroup*)m_oaVectors[z2*6+z*3+2])->m_sName); if (m_iRefOrSec[z][2]) // strcat(tmp,"o"); tmp.strcat("o"); else // strcat(tmp,"r"); tmp.strcat("r"); } else { /* if (m_bSameFoot && (z == 1)) ag = (CAtomGroup*)m_oaVectors[z2*6]; else */ag = (CAtomGroup*)m_oaVectors[z2*6+z*3]; // strcat(tmp,ag->m_sName); tmp.strcat(ag->m_sName); if (m_iRefOrSec[z][0]) // strcat(tmp,"o_"); tmp.strcat("o_"); else // strcat(tmp,"r_"); tmp.strcat("r_"); // strcat(tmp,((CAtomGroup*)m_oaVectors[z2*6+z*3+1])->m_sName); tmp.strcat(((CAtomGroup*)m_oaVectors[z2*6+z*3+1])->m_sName); if (m_iRefOrSec[z][1]) // strcat(tmp,"o"); tmp.strcat("o"); else // strcat(tmp,"r"); tmp.strcat("r"); } } else if (m_iVecType[z] == 1) // Dipol { // strcat(tmp,"dip_"); // strcat(tmp,(m_iRefOrSec[z][0]!=0)?((CMolecule*)g_oaMolecules[m_iShowMol])->m_sName:((CMolecule*)g_oaMolecules[g_iFixMol])->m_sName); tmp.strcat("dip_"); tmp.strcat((m_iRefOrSec[z][0]!=0)?((CMolecule*)g_oaMolecules[m_iShowMol])->m_sName:((CMolecule*)g_oaMolecules[g_iFixMol])->m_sName); } else if (m_iVecType[z] == 2) // Geschwindigkeit { // strcat(tmp,"vel_"); // strcat(tmp,((CAtomGroup*)m_oaVectors[z*3])->m_sName); tmp.strcat("vel_"); tmp.strcat(((CAtomGroup*)m_oaVectors[z*3])->m_sName); } else if (m_iVecType[z] == 3) // Kraft { // strcat(tmp,"frc_"); // strcat(tmp,((CAtomGroup*)m_oaVectors[z*3])->m_sName); tmp.strcat("frc_"); tmp.strcat(((CAtomGroup*)m_oaVectors[z*3])->m_sName); } if (z == 0) // strcat(tmp,"]-"); tmp.strcat("]-"); else // strcat(tmp,"]"); tmp.strcat("]"); } if (z2<(m_oaVectors.GetSize()/6)-1) // strcat(tmp,"_"); tmp.strcat("_"); } try { m_sShortName = new char[strlen(tmp)+1]; } catch(...) { m_sShortName = NULL; } if (m_sShortName == NULL) NewException((double)(strlen(tmp)+1)*sizeof(char),__FILE__,__LINE__,__PRETTY_FUNCTION__); strcpy(m_sShortName,tmp); if (m_iShowMol != -1) // sprintf(tmp,"%s_%s%d_%s_",((CMolecule*)g_oaMolecules[g_iFixMol])->m_sName,((CAtom*)g_oaAtoms[g_iFixRealAtomType[0]])->m_sName,g_iFixAtom[0]+1,((CMolecule*)g_oaMolecules[m_iShowMol])->m_sName); tmp.sprintf("%s_%s%d_%s_",((CMolecule*)g_oaMolecules[g_iFixMol])->m_sName,(const char*)((CAtom*)g_oaAtoms[g_iFixRealAtomType[0]])->m_sName,g_iFixAtom[0]+1,((CMolecule*)g_oaMolecules[m_iShowMol])->m_sName); else // sprintf(tmp,"%s_%s%d_",((CMolecule*)g_oaMolecules[g_iFixMol])->m_sName,((CAtom*)g_oaAtoms[g_iFixRealAtomType[0]])->m_sName,g_iFixAtom[0]+1); tmp.sprintf("%s_%s%d_",((CMolecule*)g_oaMolecules[g_iFixMol])->m_sName,(const char*)((CAtom*)g_oaAtoms[g_iFixRealAtomType[0]])->m_sName,g_iFixAtom[0]+1); // strcat(tmp,m_sShortName); tmp.strcat(m_sShortName); try { m_sName = new char[strlen(tmp)+1]; } catch(...) { m_sName = NULL; } if (m_sName == NULL) NewException((double)(strlen(tmp)+1)*sizeof(char),__FILE__,__LINE__,__PRETTY_FUNCTION__); strcpy(m_sName,tmp); tmp = ""; if (m_iDeriv != 0) tmp.sprintf("deriv%d_",m_iDeriv); for (z=0;z<2;z++) { tmp.strcat("["); if (m_iVecType[z] == 0) // Position { if (m_bOrtho[z]) { ag = (CAtomGroup*)m_oaVectors[z*3]; tmp.strcat(ag->m_sName); if (m_iRefOrSec[z][0]) tmp.strcat("o_"); else tmp.strcat("r_"); tmp.strcat(((CAtomGroup*)m_oaVectors[z*3+1])->m_sName); if (m_iRefOrSec[z][1]) tmp.strcat("o_"); else tmp.strcat("r_"); tmp.strcat(((CAtomGroup*)m_oaVectors[z*3+2])->m_sName); if (m_iRefOrSec[z][2]) tmp.strcat("o"); else tmp.strcat("r"); } else { ag = (CAtomGroup*)m_oaVectors[z*3]; tmp.strcat(ag->m_sName); if (m_iRefOrSec[z][0]) tmp.strcat("o_"); else tmp.strcat("r_"); tmp.strcat(((CAtomGroup*)m_oaVectors[z*3+1])->m_sName); if (m_iRefOrSec[z][1]) tmp.strcat("o"); else tmp.strcat("r"); } } else if (m_iVecType[z] == 1) // Dipol { tmp.strcat("dip_"); tmp.strcat((m_iRefOrSec[z][0]!=0)?((CMolecule*)g_oaMolecules[m_iShowMol])->m_sName:((CMolecule*)g_oaMolecules[g_iFixMol])->m_sName); } else if (m_iVecType[z] == 2) // Geschwindigkeit { tmp.strcat("vel_"); tmp.strcat(((CAtomGroup*)m_oaVectors[z*3])->m_sName); } else if (m_iVecType[z] == 3) // Kraft { tmp.strcat("frc_"); tmp.strcat(((CAtomGroup*)m_oaVectors[z*3])->m_sName); } if (z == 0) tmp.strcat("]-"); else tmp.strcat("]"); } if (m_oaVectors.GetSize() > 6) tmp.strcat(",(...)"); try { m_sLabelName = new char[strlen(tmp)+1]; } catch(...) { m_sLabelName = NULL; } if (m_sLabelName == NULL) NewException((double)(strlen(tmp)+1)*sizeof(char),__FILE__,__LINE__,__PRETTY_FUNCTION__); strcpy(m_sLabelName,tmp); BTOUT; } void CPlDF::BuildName() { BTIN; // char tmp[32768]; CxString tmp; CAtomGroup *ag; // tmp[0] = 0; tmp = ""; // strcat(tmp,"["); tmp.strcat("["); if (m_bNormal) { ag = (CAtomGroup*)m_oaVectors[0]; // strcat(tmp,ag->m_sName); tmp.strcat(ag->m_sName); if (m_iRefOrSec[0]) // strcat(tmp,"o_"); tmp.strcat("o_"); else // strcat(tmp,"r_"); tmp.strcat("r_"); // strcat(tmp,((CAtomGroup*)m_oaVectors[1])->m_sName); tmp.strcat(((CAtomGroup*)m_oaVectors[1])->m_sName); if (m_iRefOrSec[1]) // strcat(tmp,"o"); tmp.strcat("o"); else // strcat(tmp,"r"); tmp.strcat("r"); } else { ag = (CAtomGroup*)m_oaVectors[0]; // strcat(tmp,ag->m_sName); tmp.strcat(ag->m_sName); if (m_iRefOrSec[0]) // strcat(tmp,"o_"); tmp.strcat("o_"); else // strcat(tmp,"r_"); tmp.strcat("r_"); // strcat(tmp,((CAtomGroup*)m_oaVectors[1])->m_sName); tmp.strcat(((CAtomGroup*)m_oaVectors[1])->m_sName); if (m_iRefOrSec[1]) // strcat(tmp,"o_"); tmp.strcat("o_"); else // strcat(tmp,"r_"); tmp.strcat("r_"); // strcat(tmp,((CAtomGroup*)m_oaVectors[2])->m_sName); tmp.strcat(((CAtomGroup*)m_oaVectors[2])->m_sName); if (m_iRefOrSec[2]) // strcat(tmp,"o"); tmp.strcat("o"); else // strcat(tmp,"r"); tmp.strcat("r"); } // strcat(tmp,"]_"); // strcat(tmp,((CAtomGroup*)m_oaVectors[3])->m_sName); tmp.strcat("]_"); tmp.strcat(((CAtomGroup*)m_oaVectors[3])->m_sName); if (m_iRefOrSec[3]) // strcat(tmp,"o"); tmp.strcat("o"); else // strcat(tmp,"r"); tmp.strcat("r"); try { m_sShortName = new char[strlen(tmp)+1]; } catch(...) { m_sShortName = NULL; } if (m_sShortName == NULL) NewException((double)(strlen(tmp)+1)*sizeof(char),__FILE__,__LINE__,__PRETTY_FUNCTION__); strcpy(m_sShortName,tmp); if (m_iShowMol != -1) // sprintf(tmp,"%s_%s%d_%s_",((CMolecule*)g_oaMolecules[g_iFixMol])->m_sName,((CAtom*)g_oaAtoms[g_iFixRealAtomType[0]])->m_sName,g_iFixAtom[0]+1,((CMolecule*)g_oaMolecules[m_iShowMol])->m_sName); tmp.sprintf("%s_%s%d_%s_",((CMolecule*)g_oaMolecules[g_iFixMol])->m_sName,(const char*)((CAtom*)g_oaAtoms[g_iFixRealAtomType[0]])->m_sName,g_iFixAtom[0]+1,((CMolecule*)g_oaMolecules[m_iShowMol])->m_sName); else // sprintf(tmp,"%s_%s%d_",((CMolecule*)g_oaMolecules[g_iFixMol])->m_sName,((CAtom*)g_oaAtoms[g_iFixRealAtomType[0]])->m_sName,g_iFixAtom[0]+1); tmp.sprintf("%s_%s%d_",((CMolecule*)g_oaMolecules[g_iFixMol])->m_sName,(const char*)((CAtom*)g_oaAtoms[g_iFixRealAtomType[0]])->m_sName,g_iFixAtom[0]+1); // strcat(tmp,m_sShortName); tmp.strcat(m_sShortName); try { m_sName = new char[strlen(tmp)+1]; } catch(...) { m_sName = NULL; } if (m_sName == NULL) NewException((double)(strlen(tmp)+1)*sizeof(char),__FILE__,__LINE__,__PRETTY_FUNCTION__); strcpy(m_sName,tmp); tmp.sprintf("["); if (m_bNormal) { ag = (CAtomGroup*)m_oaVectors[0]; tmp.strcat(ag->m_sName); if (m_iRefOrSec[0]) tmp.strcat("o_"); else tmp.strcat("r_"); tmp.strcat(((CAtomGroup*)m_oaVectors[1])->m_sName); if (m_iRefOrSec[1]) tmp.strcat("o"); else tmp.strcat("r"); } else { ag = (CAtomGroup*)m_oaVectors[0]; tmp.strcat(ag->m_sName); if (m_iRefOrSec[0]) tmp.strcat("o_"); else tmp.strcat("r_"); tmp.strcat(((CAtomGroup*)m_oaVectors[1])->m_sName); if (m_iRefOrSec[1]) tmp.strcat("o_"); else tmp.strcat("r_"); tmp.strcat(((CAtomGroup*)m_oaVectors[2])->m_sName); if (m_iRefOrSec[2]) tmp.strcat("o"); else tmp.strcat("r"); } tmp.strcat("]_"); tmp.strcat(((CAtomGroup*)m_oaVectors[3])->m_sName); if (m_iRefOrSec[3]) tmp.strcat("o"); else tmp.strcat("r"); if (m_oaVectors.GetSize() > 4) tmp.strcat(",(...)"); try { m_sLabelName = new char[strlen(tmp)+1]; } catch(...) { m_sLabelName = NULL; } if (m_sLabelName == NULL) NewException((double)(strlen(tmp)+1)*sizeof(char),__FILE__,__LINE__,__PRETTY_FUNCTION__); strcpy(m_sLabelName,tmp); BTOUT; } void CLiDF::BuildName() { BTIN; // char tmp[32768]; CxString tmp; CAtomGroup *ag; // tmp[0] = 0; tmp = ""; // strcat(tmp,"["); tmp.strcat("["); if (m_bNormal) { ag = (CAtomGroup*)m_oaVectors[0]; // strcat(tmp,ag->m_sName); tmp.strcat(ag->m_sName); if (m_iRefOrSec[0]) // strcat(tmp,"o_"); tmp.strcat("o_"); else // strcat(tmp,"r_"); tmp.strcat("r_"); // strcat(tmp,((CAtomGroup*)m_oaVectors[1])->m_sName); tmp.strcat(((CAtomGroup*)m_oaVectors[1])->m_sName); if (m_iRefOrSec[1]) // strcat(tmp,"o_"); tmp.strcat("o_"); else // strcat(tmp,"r_"); tmp.strcat("r_"); // strcat(tmp,((CAtomGroup*)m_oaVectors[2])->m_sName); tmp.strcat(((CAtomGroup*)m_oaVectors[2])->m_sName); if (m_iRefOrSec[2]) // strcat(tmp,"o"); tmp.strcat("o"); else // strcat(tmp,"r"); tmp.strcat("r"); } else { ag = (CAtomGroup*)m_oaVectors[0]; // strcat(tmp,ag->m_sName); tmp.strcat(ag->m_sName); if (m_iRefOrSec[0]) // strcat(tmp,"o_"); tmp.strcat("o_"); else // strcat(tmp,"r_"); tmp.strcat("r_"); // strcat(tmp,((CAtomGroup*)m_oaVectors[1])->m_sName); tmp.strcat(((CAtomGroup*)m_oaVectors[1])->m_sName); if (m_iRefOrSec[1]) // strcat(tmp,"o"); tmp.strcat("o"); else // strcat(tmp,"r"); tmp.strcat("r"); } // strcat(tmp,"]_"); // strcat(tmp,((CAtomGroup*)m_oaVectors[3])->m_sName); tmp.strcat("]_"); tmp.strcat(((CAtomGroup*)m_oaVectors[3])->m_sName); if (m_iRefOrSec[3]) // strcat(tmp,"o"); tmp.strcat("o"); else // strcat(tmp,"r"); tmp.strcat("r"); try { m_sShortName = new char[strlen(tmp)+1]; } catch(...) { m_sShortName = NULL; } if (m_sShortName == NULL) NewException((double)(strlen(tmp)+1)*sizeof(char),__FILE__,__LINE__,__PRETTY_FUNCTION__); strcpy(m_sShortName,tmp); if (m_iShowMol != -1) // sprintf(tmp,"%s_%s%d_%s_",((CMolecule*)g_oaMolecules[g_iFixMol])->m_sName,((CAtom*)g_oaAtoms[g_iFixRealAtomType[0]])->m_sName,g_iFixAtom[0]+1,((CMolecule*)g_oaMolecules[m_iShowMol])->m_sName); tmp.sprintf("%s_%s%d_%s_",((CMolecule*)g_oaMolecules[g_iFixMol])->m_sName,(const char*)((CAtom*)g_oaAtoms[g_iFixRealAtomType[0]])->m_sName,g_iFixAtom[0]+1,((CMolecule*)g_oaMolecules[m_iShowMol])->m_sName); else // sprintf(tmp,"%s_%s%d_",((CMolecule*)g_oaMolecules[g_iFixMol])->m_sName,((CAtom*)g_oaAtoms[g_iFixRealAtomType[0]])->m_sName,g_iFixAtom[0]+1); tmp.sprintf("%s_%s%d_",((CMolecule*)g_oaMolecules[g_iFixMol])->m_sName,(const char*)((CAtom*)g_oaAtoms[g_iFixRealAtomType[0]])->m_sName,g_iFixAtom[0]+1); // strcat(tmp,m_sShortName); tmp.strcat(m_sShortName); try { m_sName = new char[strlen(tmp)+1]; } catch(...) { m_sName = NULL; } if (m_sName == NULL) NewException((double)(strlen(tmp)+1)*sizeof(char),__FILE__,__LINE__,__PRETTY_FUNCTION__); strcpy(m_sName,tmp); tmp.sprintf("["); if (m_bNormal) { ag = (CAtomGroup*)m_oaVectors[0]; tmp.strcat(ag->m_sName); if (m_iRefOrSec[0]) tmp.strcat("o_"); else tmp.strcat("r_"); tmp.strcat(((CAtomGroup*)m_oaVectors[1])->m_sName); if (m_iRefOrSec[1]) tmp.strcat("o_"); else tmp.strcat("r_"); tmp.strcat(((CAtomGroup*)m_oaVectors[2])->m_sName); if (m_iRefOrSec[2]) tmp.strcat("o"); else tmp.strcat("r"); } else { ag = (CAtomGroup*)m_oaVectors[0]; tmp.strcat(ag->m_sName); if (m_iRefOrSec[0]) tmp.strcat("o_"); else tmp.strcat("r_"); tmp.strcat(((CAtomGroup*)m_oaVectors[1])->m_sName); if (m_iRefOrSec[1]) tmp.strcat("o"); else tmp.strcat("r"); } tmp.strcat("]_"); tmp.strcat(((CAtomGroup*)m_oaVectors[3])->m_sName); if (m_iRefOrSec[3]) tmp.strcat("o"); else tmp.strcat("r"); if (m_oaVectors.GetSize() > 4) tmp.strcat(",(...)"); try { m_sLabelName = new char[strlen(tmp)+1]; } catch(...) { m_sLabelName = NULL; } if (m_sLabelName == NULL) NewException((double)(strlen(tmp)+1)*sizeof(char),__FILE__,__LINE__,__PRETTY_FUNCTION__); strcpy(m_sLabelName,tmp); BTOUT; } void CDDF::BuildName() { BTIN; int z; // char tmp[32768]; CxString tmp; CAtomGroup *ag; // tmp[0] = 0; tmp = ""; if (m_iDeriv != 0) // sprintf(tmp,"deriv%d_",m_iDeriv); tmp.sprintf("deriv%d_",m_iDeriv); for (z=0;z<3;z++) { // strcat(tmp,"["); tmp.strcat("["); if (m_bOrtho[z]) { ag = (CAtomGroup*)m_oaVectors[z*3]; // strcat(tmp,ag->m_sName); tmp.strcat(ag->m_sName); if (m_iRefOrSec[z][0]) // strcat(tmp,"o_"); tmp.strcat("o_"); else // strcat(tmp,"r_"); tmp.strcat("r_"); // strcat(tmp,((CAtomGroup*)m_oaVectors[z*3+1])->m_sName); tmp.strcat(((CAtomGroup*)m_oaVectors[z*3+1])->m_sName); if (m_iRefOrSec[z][1]) // strcat(tmp,"o_"); tmp.strcat("o_"); else // strcat(tmp,"r_"); tmp.strcat("r_"); // strcat(tmp,((CAtomGroup*)m_oaVectors[z*3+2])->m_sName); tmp.strcat(((CAtomGroup*)m_oaVectors[z*3+2])->m_sName); if (m_iRefOrSec[z][2]) // strcat(tmp,"o"); tmp.strcat("o"); else // strcat(tmp,"r"); tmp.strcat("r"); } else { ag = (CAtomGroup*)m_oaVectors[z*3]; // strcat(tmp,ag->m_sName); tmp.strcat(ag->m_sName); if (m_iRefOrSec[z][0]) // strcat(tmp,"o_"); tmp.strcat("o_"); else // strcat(tmp,"r_"); tmp.strcat("r_"); // strcat(tmp,((CAtomGroup*)m_oaVectors[z*3+1])->m_sName); tmp.strcat(((CAtomGroup*)m_oaVectors[z*3+1])->m_sName); if (m_iRefOrSec[z][1]) // strcat(tmp,"o"); tmp.strcat("o"); else // strcat(tmp,"r"); tmp.strcat("r"); } if (z < 2) // strcat(tmp,"]-"); tmp.strcat("]-"); else // strcat(tmp,"]"); tmp.strcat("]"); } try { m_sShortName = new char[strlen(tmp)+1]; } catch(...) { m_sShortName = NULL; } if (m_sShortName == NULL) NewException((double)(strlen(tmp)+1)*sizeof(char),__FILE__,__LINE__,__PRETTY_FUNCTION__); strcpy(m_sShortName,tmp); if (m_iShowMol != -1) // sprintf(tmp,"%s_%s%d_%s_",((CMolecule*)g_oaMolecules[g_iFixMol])->m_sName,((CAtom*)g_oaAtoms[g_iFixRealAtomType[0]])->m_sName,g_iFixAtom[0]+1,((CMolecule*)g_oaMolecules[m_iShowMol])->m_sName); tmp.sprintf("%s_%s%d_%s_",((CMolecule*)g_oaMolecules[g_iFixMol])->m_sName,(const char*)((CAtom*)g_oaAtoms[g_iFixRealAtomType[0]])->m_sName,g_iFixAtom[0]+1,((CMolecule*)g_oaMolecules[m_iShowMol])->m_sName); else // sprintf(tmp,"%s_%s%d_",((CMolecule*)g_oaMolecules[g_iFixMol])->m_sName,((CAtom*)g_oaAtoms[g_iFixRealAtomType[0]])->m_sName,g_iFixAtom[0]+1); tmp.sprintf("%s_%s%d_",((CMolecule*)g_oaMolecules[g_iFixMol])->m_sName,(const char*)((CAtom*)g_oaAtoms[g_iFixRealAtomType[0]])->m_sName,g_iFixAtom[0]+1); // strcat(tmp,m_sShortName); tmp.strcat(m_sShortName); try { m_sName = new char[strlen(tmp)+1]; } catch(...) { m_sName = NULL; } if (m_sName == NULL) NewException((double)(strlen(tmp)+1)*sizeof(char),__FILE__,__LINE__,__PRETTY_FUNCTION__); strcpy(m_sName,tmp); tmp = ""; if (m_iDeriv != 0) tmp.sprintf("deriv%d_",m_iDeriv); for (z=0;z<3;z++) { tmp.strcat("["); if (m_bOrtho[z]) { ag = (CAtomGroup*)m_oaVectors[z*3]; tmp.strcat(ag->m_sName); if (m_iRefOrSec[z][0]) tmp.strcat("o_"); else tmp.strcat("r_"); tmp.strcat(((CAtomGroup*)m_oaVectors[z*3+1])->m_sName); if (m_iRefOrSec[z][1]) tmp.strcat("o_"); else tmp.strcat("r_"); tmp.strcat(((CAtomGroup*)m_oaVectors[z*3+2])->m_sName); if (m_iRefOrSec[z][2]) tmp.strcat("o"); else tmp.strcat("r"); } else { ag = (CAtomGroup*)m_oaVectors[z*3]; tmp.strcat(ag->m_sName); if (m_iRefOrSec[z][0]) tmp.strcat("o_"); else tmp.strcat("r_"); tmp.strcat(((CAtomGroup*)m_oaVectors[z*3+1])->m_sName); if (m_iRefOrSec[z][1]) tmp.strcat("o"); else tmp.strcat("r"); } if (z < 2) tmp.strcat("]-"); else tmp.strcat("]"); } if (m_oaVectors.GetSize() > 9) tmp.strcat(",(...)"); try { m_sLabelName = new char[strlen(tmp)+1]; } catch(...) { m_sLabelName = NULL; } if (m_sLabelName == NULL) NewException((double)(strlen(tmp)+1)*sizeof(char),__FILE__,__LINE__,__PRETTY_FUNCTION__); strcpy(m_sLabelName,tmp); BTOUT; } void CDipDF::BuildName() { BTIN; // char tmp[32768]; CxString tmp; // tmp[0] = 0; tmp = ""; if (m_iDeriv != 0) // sprintf(tmp,"deriv%d_",m_iDeriv); tmp.sprintf("deriv%d_",m_iDeriv); if (m_iRefOrSec) // sprintf(tmp,"%s",((CMolecule*)g_oaMolecules[m_iShowMol])->m_sName); tmp.sprintf("%s",((CMolecule*)g_oaMolecules[m_iShowMol])->m_sName); else // sprintf(tmp,"%s",((CMolecule*)g_oaMolecules[g_iFixMol])->m_sName); tmp.sprintf("%s",((CMolecule*)g_oaMolecules[g_iFixMol])->m_sName); try { m_sName = new char[strlen(tmp)+1]; } catch(...) { m_sName = NULL; } if (m_sName == NULL) NewException((double)(strlen(tmp)+1)*sizeof(char),__FILE__,__LINE__,__PRETTY_FUNCTION__); strcpy(m_sName,tmp); try { m_sShortName = new char[strlen(tmp)+1]; } catch(...) { m_sShortName = NULL; } if (m_sShortName == NULL) NewException((double)(strlen(tmp)+1)*sizeof(char),__FILE__,__LINE__,__PRETTY_FUNCTION__); strcpy(m_sShortName,tmp); try { m_sLabelName = new char[strlen(tmp)+1]; } catch(...) { m_sLabelName = NULL; } if (m_sLabelName == NULL) NewException((double)(strlen(tmp)+1)*sizeof(char),__FILE__,__LINE__,__PRETTY_FUNCTION__); strcpy(m_sLabelName,tmp); BTOUT; } void CADF::BuildAtomList(CSingleMolecule *ref, CSingleMolecule *obs, CxIntArray *vec) { BXIN; int z, z1t, z1a, z2t, z2a, z3t, z3a, z4t, z4a, z5t, z5a, z6t, z6a; CAtomGroup *g1, *g2, *g3, *g4, *g5, *g6; CxIntArray *a1, *a2, *a3, *a4, *a5, *a6; // mprintf("Vec: %X\n",vec); vec->RemoveAll_KeepSize(); for (z=0;zm_baAtomType.GetSize();z1t++) { a1 = (CxIntArray*)g1->m_oaAtoms[z1t]; for (z1a=0;z1aGetSize();z1a++) { for (z2t=0;z2tm_baAtomType.GetSize();z2t++) { a2 = (CxIntArray*)g2->m_oaAtoms[z2t]; for (z2a=0;z2aGetSize();z2a++) { for (z3t=0;z3tm_baAtomType.GetSize();z3t++) { a3 = (CxIntArray*)g3->m_oaAtoms[z3t]; for (z3a=0;z3aGetSize();z3a++) { if (m_bOrtho[1]) { g4 = (CAtomGroup*)m_oaVectors[z*6+3]; g5 = (CAtomGroup*)m_oaVectors[z*6+4]; g6 = (CAtomGroup*)m_oaVectors[z*6+5]; for (z4t=0;z4tm_baAtomType.GetSize();z4t++) { a4 = (CxIntArray*)g4->m_oaAtoms[z4t]; for (z4a=0;z4aGetSize();z4a++) { for (z5t=0;z5tm_baAtomType.GetSize();z5t++) { a5 = (CxIntArray*)g5->m_oaAtoms[z5t]; for (z5a=0;z5aGetSize();z5a++) { for (z6t=0;z6tm_baAtomType.GetSize();z6t++) { a6 = (CxIntArray*)g6->m_oaAtoms[z6t]; for (z6a=0;z6aGetSize();z6a++) { if ((!m_iRefOrSec[0][0]) || (obs == NULL)) vec->Add(((CxIntArray*)ref->m_oaAtomOffset[g1->m_baAtomType[z1t]])->GetAt(a1->GetAt(z1a))); else vec->Add(((CxIntArray*)obs->m_oaAtomOffset[g1->m_baAtomType[z1t]])->GetAt(a1->GetAt(z1a))); if ((!m_iRefOrSec[0][1]) || (obs == NULL)) vec->Add(((CxIntArray*)ref->m_oaAtomOffset[g2->m_baAtomType[z2t]])->GetAt(a2->GetAt(z2a))); else vec->Add(((CxIntArray*)obs->m_oaAtomOffset[g2->m_baAtomType[z2t]])->GetAt(a2->GetAt(z2a))); if ((!m_iRefOrSec[0][2]) || (obs == NULL)) vec->Add(((CxIntArray*)ref->m_oaAtomOffset[g3->m_baAtomType[z3t]])->GetAt(a3->GetAt(z3a))); else vec->Add(((CxIntArray*)obs->m_oaAtomOffset[g3->m_baAtomType[z3t]])->GetAt(a3->GetAt(z3a))); if ((!m_iRefOrSec[1][0]) || (obs == NULL)) vec->Add(((CxIntArray*)ref->m_oaAtomOffset[g4->m_baAtomType[z4t]])->GetAt(a4->GetAt(z4a))); else vec->Add(((CxIntArray*)obs->m_oaAtomOffset[g4->m_baAtomType[z4t]])->GetAt(a4->GetAt(z4a))); if ((!m_iRefOrSec[1][1]) || (obs == NULL)) vec->Add(((CxIntArray*)ref->m_oaAtomOffset[g5->m_baAtomType[z5t]])->GetAt(a5->GetAt(z5a))); else vec->Add(((CxIntArray*)obs->m_oaAtomOffset[g5->m_baAtomType[z5t]])->GetAt(a5->GetAt(z5a))); if ((!m_iRefOrSec[1][2]) || (obs == NULL)) vec->Add(((CxIntArray*)ref->m_oaAtomOffset[g6->m_baAtomType[z6t]])->GetAt(a6->GetAt(z6a))); else vec->Add(((CxIntArray*)obs->m_oaAtomOffset[g6->m_baAtomType[z6t]])->GetAt(a6->GetAt(z6a))); } } } } } } } else { g4 = (CAtomGroup*)m_oaVectors[z*6+3]; g5 = (CAtomGroup*)m_oaVectors[z*6+4]; for (z4t=0;z4tm_baAtomType.GetSize();z4t++) { a4 = (CxIntArray*)g4->m_oaAtoms[z4t]; for (z4a=0;z4aGetSize();z4a++) { for (z5t=0;z5tm_baAtomType.GetSize();z5t++) { a5 = (CxIntArray*)g5->m_oaAtoms[z5t]; for (z5a=0;z5aGetSize();z5a++) { if ((!m_iRefOrSec[0][0]) || (obs == NULL)) vec->Add(((CxIntArray*)ref->m_oaAtomOffset[g1->m_baAtomType[z1t]])->GetAt(a1->GetAt(z1a))); else vec->Add(((CxIntArray*)obs->m_oaAtomOffset[g1->m_baAtomType[z1t]])->GetAt(a1->GetAt(z1a))); if ((!m_iRefOrSec[0][1]) || (obs == NULL)) vec->Add(((CxIntArray*)ref->m_oaAtomOffset[g2->m_baAtomType[z2t]])->GetAt(a2->GetAt(z2a))); else vec->Add(((CxIntArray*)obs->m_oaAtomOffset[g2->m_baAtomType[z2t]])->GetAt(a2->GetAt(z2a))); if ((!m_iRefOrSec[0][2]) || (obs == NULL)) vec->Add(((CxIntArray*)ref->m_oaAtomOffset[g3->m_baAtomType[z3t]])->GetAt(a3->GetAt(z3a))); else vec->Add(((CxIntArray*)obs->m_oaAtomOffset[g3->m_baAtomType[z3t]])->GetAt(a3->GetAt(z3a))); if ((!m_iRefOrSec[1][0]) || (obs == NULL)) vec->Add(((CxIntArray*)ref->m_oaAtomOffset[g4->m_baAtomType[z4t]])->GetAt(a4->GetAt(z4a))); else vec->Add(((CxIntArray*)obs->m_oaAtomOffset[g4->m_baAtomType[z4t]])->GetAt(a4->GetAt(z4a))); if ((!m_iRefOrSec[1][1]) || (obs == NULL)) vec->Add(((CxIntArray*)ref->m_oaAtomOffset[g5->m_baAtomType[z5t]])->GetAt(a5->GetAt(z5a))); else vec->Add(((CxIntArray*)obs->m_oaAtomOffset[g5->m_baAtomType[z5t]])->GetAt(a5->GetAt(z5a))); vec->Add(0); } } } } } // END IF NOT ORTHO[1] } } } } } } } else { g1 = (CAtomGroup*)m_oaVectors[z*6]; g2 = (CAtomGroup*)m_oaVectors[z*6+1]; for (z1t=0;z1tm_baAtomType.GetSize();z1t++) { a1 = (CxIntArray*)g1->m_oaAtoms[z1t]; for (z1a=0;z1aGetSize();z1a++) { for (z2t=0;z2tm_baAtomType.GetSize();z2t++) { a2 = (CxIntArray*)g2->m_oaAtoms[z2t]; for (z2a=0;z2aGetSize();z2a++) { if (m_bOrtho[1]) { g4 = (CAtomGroup*)m_oaVectors[z*6+3]; g5 = (CAtomGroup*)m_oaVectors[z*6+4]; g6 = (CAtomGroup*)m_oaVectors[z*6+5]; for (z4t=0;z4tm_baAtomType.GetSize();z4t++) { a4 = (CxIntArray*)g4->m_oaAtoms[z4t]; for (z4a=0;z4aGetSize();z4a++) { for (z5t=0;z5tm_baAtomType.GetSize();z5t++) { a5 = (CxIntArray*)g5->m_oaAtoms[z5t]; for (z5a=0;z5aGetSize();z5a++) { for (z6t=0;z6tm_baAtomType.GetSize();z6t++) { a6 = (CxIntArray*)g6->m_oaAtoms[z6t]; for (z6a=0;z6aGetSize();z6a++) { if ((!m_iRefOrSec[0][0]) || (obs == NULL)) vec->Add(((CxIntArray*)ref->m_oaAtomOffset[g1->m_baAtomType[z1t]])->GetAt(a1->GetAt(z1a))); else vec->Add(((CxIntArray*)obs->m_oaAtomOffset[g1->m_baAtomType[z1t]])->GetAt(a1->GetAt(z1a))); if ((!m_iRefOrSec[0][1]) || (obs == NULL)) vec->Add(((CxIntArray*)ref->m_oaAtomOffset[g2->m_baAtomType[z2t]])->GetAt(a2->GetAt(z2a))); else vec->Add(((CxIntArray*)obs->m_oaAtomOffset[g2->m_baAtomType[z2t]])->GetAt(a2->GetAt(z2a))); vec->Add(0); if ((!m_iRefOrSec[1][0]) || (obs == NULL)) vec->Add(((CxIntArray*)ref->m_oaAtomOffset[g4->m_baAtomType[z4t]])->GetAt(a4->GetAt(z4a))); else vec->Add(((CxIntArray*)obs->m_oaAtomOffset[g4->m_baAtomType[z4t]])->GetAt(a4->GetAt(z4a))); if ((!m_iRefOrSec[1][1]) || (obs == NULL)) vec->Add(((CxIntArray*)ref->m_oaAtomOffset[g5->m_baAtomType[z5t]])->GetAt(a5->GetAt(z5a))); else vec->Add(((CxIntArray*)obs->m_oaAtomOffset[g5->m_baAtomType[z5t]])->GetAt(a5->GetAt(z5a))); if ((!m_iRefOrSec[1][2]) || (obs == NULL)) vec->Add(((CxIntArray*)ref->m_oaAtomOffset[g6->m_baAtomType[z6t]])->GetAt(a6->GetAt(z6a))); else vec->Add(((CxIntArray*)obs->m_oaAtomOffset[g6->m_baAtomType[z6t]])->GetAt(a6->GetAt(z6a))); } } } } } } } else { g4 = (CAtomGroup*)m_oaVectors[z*6+3]; g5 = (CAtomGroup*)m_oaVectors[z*6+4]; for (z4t=0;z4tm_baAtomType.GetSize();z4t++) { a4 = (CxIntArray*)g4->m_oaAtoms[z4t]; for (z4a=0;z4aGetSize();z4a++) { for (z5t=0;z5tm_baAtomType.GetSize();z5t++) { a5 = (CxIntArray*)g5->m_oaAtoms[z5t]; for (z5a=0;z5aGetSize();z5a++) { // mprintf("### BuildAtomList\n"); // mprintf(" z1a=%d, z1t=%d, z2a=%d, z2t=%d, z4a=%d, z4t=%d, z5a=%d, z5t=%d.\n",z1a,z1t,z2a,z2t,z4a,z4t,z5a,z5t); // mprintf(" g1=\"%s\", g2=\"%s\", g4=\"%s\", g5=\"%s\".\n",g1->m_sName,g2->m_sName,g4->m_sName,g5->m_sName); if ((!m_iRefOrSec[0][0]) || (obs == NULL)) vec->Add(((CxIntArray*)ref->m_oaAtomOffset[g1->m_baAtomType[z1t]])->GetAt(a1->GetAt(z1a))); else vec->Add(((CxIntArray*)obs->m_oaAtomOffset[g1->m_baAtomType[z1t]])->GetAt(a1->GetAt(z1a))); if ((!m_iRefOrSec[0][1]) || (obs == NULL)) vec->Add(((CxIntArray*)ref->m_oaAtomOffset[g2->m_baAtomType[z2t]])->GetAt(a2->GetAt(z2a))); else vec->Add(((CxIntArray*)obs->m_oaAtomOffset[g2->m_baAtomType[z2t]])->GetAt(a2->GetAt(z2a))); vec->Add(0); if ((!m_iRefOrSec[1][0]) || (obs == NULL)) vec->Add(((CxIntArray*)ref->m_oaAtomOffset[g4->m_baAtomType[z4t]])->GetAt(a4->GetAt(z4a))); else vec->Add(((CxIntArray*)obs->m_oaAtomOffset[g4->m_baAtomType[z4t]])->GetAt(a4->GetAt(z4a))); if ((!m_iRefOrSec[1][1]) || (obs == NULL)) vec->Add(((CxIntArray*)ref->m_oaAtomOffset[g5->m_baAtomType[z5t]])->GetAt(a5->GetAt(z5a))); else vec->Add(((CxIntArray*)obs->m_oaAtomOffset[g5->m_baAtomType[z5t]])->GetAt(a5->GetAt(z5a))); vec->Add(0); } } } } } // END IF NOT ORTHO[1] } } } } } } BXOUT; } /* Mega abartig !!!! */ void CDDF::BuildAtomList(CSingleMolecule *ref, CSingleMolecule *obs, CxIntArray *vec) { BXIN; int z, z1t, z1a, z2t, z2a, z3t, z3a, z4t, z4a, z5t, z5a, z6t, z6a, z7t, z7a, z8t, z8a, z9t, z9a; CAtomGroup *g1, *g2, *g3, *g4, *g5, *g6, *g7, *g8, *g9; CxIntArray *a1, *a2, *a3, *a4, *a5, *a6, *a7, *a8, *a9; vec->RemoveAll_KeepSize(); for (z=0;zm_baAtomType.GetSize();z1t++) { a1 = (CxIntArray*)g1->m_oaAtoms[z1t]; for (z1a=0;z1aGetSize();z1a++) { for (z2t=0;z2tm_baAtomType.GetSize();z2t++) { a2 = (CxIntArray*)g2->m_oaAtoms[z2t]; for (z2a=0;z2aGetSize();z2a++) { for (z3t=0;z3tm_baAtomType.GetSize();z3t++) { a3 = (CxIntArray*)g3->m_oaAtoms[z3t]; for (z3a=0;z3aGetSize();z3a++) { if (m_bOrtho[1]) { g4 = (CAtomGroup*)m_oaVectors[z*9+3]; g5 = (CAtomGroup*)m_oaVectors[z*9+4]; g6 = (CAtomGroup*)m_oaVectors[z*9+5]; for (z4t=0;z4tm_baAtomType.GetSize();z4t++) { a4 = (CxIntArray*)g4->m_oaAtoms[z4t]; for (z4a=0;z4aGetSize();z4a++) { for (z5t=0;z5tm_baAtomType.GetSize();z5t++) { a5 = (CxIntArray*)g5->m_oaAtoms[z5t]; for (z5a=0;z5aGetSize();z5a++) { for (z6t=0;z6tm_baAtomType.GetSize();z6t++) { a6 = (CxIntArray*)g6->m_oaAtoms[z6t]; for (z6a=0;z6aGetSize();z6a++) { if (m_bOrtho[2]) { g7 = (CAtomGroup*)m_oaVectors[z*9+6]; g8 = (CAtomGroup*)m_oaVectors[z*9+7]; g9 = (CAtomGroup*)m_oaVectors[z*9+8]; for (z7t=0;z7tm_baAtomType.GetSize();z7t++) { a7 = (CxIntArray*)g7->m_oaAtoms[z7t]; for (z7a=0;z7aGetSize();z7a++) { for (z8t=0;z8tm_baAtomType.GetSize();z8t++) { a8 = (CxIntArray*)g8->m_oaAtoms[z8t]; for (z8a=0;z8aGetSize();z8a++) { for (z9t=0;z9tm_baAtomType.GetSize();z9t++) { a9 = (CxIntArray*)g9->m_oaAtoms[z9t]; for (z9a=0;z9aGetSize();z9a++) { if ((!m_iRefOrSec[0][0]) || (obs == NULL)) vec->Add(((CxIntArray*)ref->m_oaAtomOffset[g1->m_baAtomType[z1t]])->GetAt(a1->GetAt(z1a))); else vec->Add(((CxIntArray*)obs->m_oaAtomOffset[g1->m_baAtomType[z1t]])->GetAt(a1->GetAt(z1a))); if ((!m_iRefOrSec[0][1]) || (obs == NULL)) vec->Add(((CxIntArray*)ref->m_oaAtomOffset[g2->m_baAtomType[z2t]])->GetAt(a2->GetAt(z2a))); else vec->Add(((CxIntArray*)obs->m_oaAtomOffset[g2->m_baAtomType[z2t]])->GetAt(a2->GetAt(z2a))); if ((!m_iRefOrSec[0][2]) || (obs == NULL)) vec->Add(((CxIntArray*)ref->m_oaAtomOffset[g3->m_baAtomType[z3t]])->GetAt(a3->GetAt(z3a))); else vec->Add(((CxIntArray*)obs->m_oaAtomOffset[g3->m_baAtomType[z3t]])->GetAt(a3->GetAt(z3a))); if ((!m_iRefOrSec[1][0]) || (obs == NULL)) vec->Add(((CxIntArray*)ref->m_oaAtomOffset[g4->m_baAtomType[z4t]])->GetAt(a4->GetAt(z4a))); else vec->Add(((CxIntArray*)obs->m_oaAtomOffset[g4->m_baAtomType[z4t]])->GetAt(a4->GetAt(z4a))); if ((!m_iRefOrSec[1][1]) || (obs == NULL)) vec->Add(((CxIntArray*)ref->m_oaAtomOffset[g5->m_baAtomType[z5t]])->GetAt(a5->GetAt(z5a))); else vec->Add(((CxIntArray*)obs->m_oaAtomOffset[g5->m_baAtomType[z5t]])->GetAt(a5->GetAt(z5a))); if ((!m_iRefOrSec[1][2]) || (obs == NULL)) vec->Add(((CxIntArray*)ref->m_oaAtomOffset[g6->m_baAtomType[z6t]])->GetAt(a6->GetAt(z6a))); else vec->Add(((CxIntArray*)obs->m_oaAtomOffset[g6->m_baAtomType[z6t]])->GetAt(a6->GetAt(z6a))); if ((!m_iRefOrSec[2][0]) || (obs == NULL)) vec->Add(((CxIntArray*)ref->m_oaAtomOffset[g7->m_baAtomType[z7t]])->GetAt(a7->GetAt(z7a))); else vec->Add(((CxIntArray*)obs->m_oaAtomOffset[g7->m_baAtomType[z7t]])->GetAt(a7->GetAt(z7a))); if ((!m_iRefOrSec[2][1]) || (obs == NULL)) vec->Add(((CxIntArray*)ref->m_oaAtomOffset[g8->m_baAtomType[z8t]])->GetAt(a8->GetAt(z8a))); else vec->Add(((CxIntArray*)obs->m_oaAtomOffset[g8->m_baAtomType[z8t]])->GetAt(a8->GetAt(z8a))); if ((!m_iRefOrSec[2][2]) || (obs == NULL)) vec->Add(((CxIntArray*)ref->m_oaAtomOffset[g9->m_baAtomType[z9t]])->GetAt(a9->GetAt(z9a))); else vec->Add(((CxIntArray*)obs->m_oaAtomOffset[g9->m_baAtomType[z9t]])->GetAt(a9->GetAt(z9a))); } } } } } } } else // IF NOT ORTHO[2] { g7 = (CAtomGroup*)m_oaVectors[z*9+6]; g8 = (CAtomGroup*)m_oaVectors[z*9+7]; for (z7t=0;z7tm_baAtomType.GetSize();z7t++) { a7 = (CxIntArray*)g7->m_oaAtoms[z7t]; for (z7a=0;z7aGetSize();z7a++) { for (z8t=0;z8tm_baAtomType.GetSize();z8t++) { a8 = (CxIntArray*)g8->m_oaAtoms[z8t]; for (z8a=0;z8aGetSize();z8a++) { if ((!m_iRefOrSec[0][0]) || (obs == NULL)) vec->Add(((CxIntArray*)ref->m_oaAtomOffset[g1->m_baAtomType[z1t]])->GetAt(a1->GetAt(z1a))); else vec->Add(((CxIntArray*)obs->m_oaAtomOffset[g1->m_baAtomType[z1t]])->GetAt(a1->GetAt(z1a))); if ((!m_iRefOrSec[0][1]) || (obs == NULL)) vec->Add(((CxIntArray*)ref->m_oaAtomOffset[g2->m_baAtomType[z2t]])->GetAt(a2->GetAt(z2a))); else vec->Add(((CxIntArray*)obs->m_oaAtomOffset[g2->m_baAtomType[z2t]])->GetAt(a2->GetAt(z2a))); if ((!m_iRefOrSec[0][2]) || (obs == NULL)) vec->Add(((CxIntArray*)ref->m_oaAtomOffset[g3->m_baAtomType[z3t]])->GetAt(a3->GetAt(z3a))); else vec->Add(((CxIntArray*)obs->m_oaAtomOffset[g3->m_baAtomType[z3t]])->GetAt(a3->GetAt(z3a))); if ((!m_iRefOrSec[1][0]) || (obs == NULL)) vec->Add(((CxIntArray*)ref->m_oaAtomOffset[g4->m_baAtomType[z4t]])->GetAt(a4->GetAt(z4a))); else vec->Add(((CxIntArray*)obs->m_oaAtomOffset[g4->m_baAtomType[z4t]])->GetAt(a4->GetAt(z4a))); if ((!m_iRefOrSec[1][1]) || (obs == NULL)) vec->Add(((CxIntArray*)ref->m_oaAtomOffset[g5->m_baAtomType[z5t]])->GetAt(a5->GetAt(z5a))); else vec->Add(((CxIntArray*)obs->m_oaAtomOffset[g5->m_baAtomType[z5t]])->GetAt(a5->GetAt(z5a))); if ((!m_iRefOrSec[1][2]) || (obs == NULL)) vec->Add(((CxIntArray*)ref->m_oaAtomOffset[g6->m_baAtomType[z6t]])->GetAt(a6->GetAt(z6a))); else vec->Add(((CxIntArray*)obs->m_oaAtomOffset[g6->m_baAtomType[z6t]])->GetAt(a6->GetAt(z6a))); if ((!m_iRefOrSec[2][0]) || (obs == NULL)) vec->Add(((CxIntArray*)ref->m_oaAtomOffset[g7->m_baAtomType[z7t]])->GetAt(a7->GetAt(z7a))); else vec->Add(((CxIntArray*)obs->m_oaAtomOffset[g7->m_baAtomType[z7t]])->GetAt(a7->GetAt(z7a))); if ((!m_iRefOrSec[2][1]) || (obs == NULL)) vec->Add(((CxIntArray*)ref->m_oaAtomOffset[g8->m_baAtomType[z8t]])->GetAt(a8->GetAt(z8a))); else vec->Add(((CxIntArray*)obs->m_oaAtomOffset[g8->m_baAtomType[z8t]])->GetAt(a8->GetAt(z8a))); vec->Add(0); } } } } } // END IF NOT ORTHO[2] } } } } } } } else // IF NOT ORTHO[1] { g4 = (CAtomGroup*)m_oaVectors[z*9+3]; g5 = (CAtomGroup*)m_oaVectors[z*9+4]; for (z4t=0;z4tm_baAtomType.GetSize();z4t++) { a4 = (CxIntArray*)g4->m_oaAtoms[z4t]; for (z4a=0;z4aGetSize();z4a++) { for (z5t=0;z5tm_baAtomType.GetSize();z5t++) { a5 = (CxIntArray*)g5->m_oaAtoms[z5t]; for (z5a=0;z5aGetSize();z5a++) { if (m_bOrtho[2]) { g7 = (CAtomGroup*)m_oaVectors[z*9+6]; g8 = (CAtomGroup*)m_oaVectors[z*9+7]; g9 = (CAtomGroup*)m_oaVectors[z*9+8]; for (z7t=0;z7tm_baAtomType.GetSize();z7t++) { a7 = (CxIntArray*)g7->m_oaAtoms[z7t]; for (z7a=0;z7aGetSize();z7a++) { for (z8t=0;z8tm_baAtomType.GetSize();z8t++) { a8 = (CxIntArray*)g8->m_oaAtoms[z8t]; for (z8a=0;z8aGetSize();z8a++) { for (z9t=0;z9tm_baAtomType.GetSize();z9t++) { a9 = (CxIntArray*)g9->m_oaAtoms[z9t]; for (z9a=0;z9aGetSize();z9a++) { if ((!m_iRefOrSec[0][0]) || (obs == NULL)) vec->Add(((CxIntArray*)ref->m_oaAtomOffset[g1->m_baAtomType[z1t]])->GetAt(a1->GetAt(z1a))); else vec->Add(((CxIntArray*)obs->m_oaAtomOffset[g1->m_baAtomType[z1t]])->GetAt(a1->GetAt(z1a))); if ((!m_iRefOrSec[0][1]) || (obs == NULL)) vec->Add(((CxIntArray*)ref->m_oaAtomOffset[g2->m_baAtomType[z2t]])->GetAt(a2->GetAt(z2a))); else vec->Add(((CxIntArray*)obs->m_oaAtomOffset[g2->m_baAtomType[z2t]])->GetAt(a2->GetAt(z2a))); if ((!m_iRefOrSec[0][2]) || (obs == NULL)) vec->Add(((CxIntArray*)ref->m_oaAtomOffset[g3->m_baAtomType[z3t]])->GetAt(a3->GetAt(z3a))); else vec->Add(((CxIntArray*)obs->m_oaAtomOffset[g3->m_baAtomType[z3t]])->GetAt(a3->GetAt(z3a))); if ((!m_iRefOrSec[1][0]) || (obs == NULL)) vec->Add(((CxIntArray*)ref->m_oaAtomOffset[g4->m_baAtomType[z4t]])->GetAt(a4->GetAt(z4a))); else vec->Add(((CxIntArray*)obs->m_oaAtomOffset[g4->m_baAtomType[z4t]])->GetAt(a4->GetAt(z4a))); if ((!m_iRefOrSec[1][1]) || (obs == NULL)) vec->Add(((CxIntArray*)ref->m_oaAtomOffset[g5->m_baAtomType[z5t]])->GetAt(a5->GetAt(z5a))); else vec->Add(((CxIntArray*)obs->m_oaAtomOffset[g5->m_baAtomType[z5t]])->GetAt(a5->GetAt(z5a))); vec->Add(0); if ((!m_iRefOrSec[2][0]) || (obs == NULL)) vec->Add(((CxIntArray*)ref->m_oaAtomOffset[g7->m_baAtomType[z7t]])->GetAt(a7->GetAt(z7a))); else vec->Add(((CxIntArray*)obs->m_oaAtomOffset[g7->m_baAtomType[z7t]])->GetAt(a7->GetAt(z7a))); if ((!m_iRefOrSec[2][1]) || (obs == NULL)) vec->Add(((CxIntArray*)ref->m_oaAtomOffset[g8->m_baAtomType[z8t]])->GetAt(a8->GetAt(z8a))); else vec->Add(((CxIntArray*)obs->m_oaAtomOffset[g8->m_baAtomType[z8t]])->GetAt(a8->GetAt(z8a))); if ((!m_iRefOrSec[2][2]) || (obs == NULL)) vec->Add(((CxIntArray*)ref->m_oaAtomOffset[g9->m_baAtomType[z9t]])->GetAt(a9->GetAt(z9a))); else vec->Add(((CxIntArray*)obs->m_oaAtomOffset[g9->m_baAtomType[z9t]])->GetAt(a9->GetAt(z9a))); } } } } } } } else // IF NOT ORTHO[2] { g7 = (CAtomGroup*)m_oaVectors[z*9+6]; g8 = (CAtomGroup*)m_oaVectors[z*9+7]; for (z7t=0;z7tm_baAtomType.GetSize();z7t++) { a7 = (CxIntArray*)g7->m_oaAtoms[z7t]; for (z7a=0;z7aGetSize();z7a++) { for (z8t=0;z8tm_baAtomType.GetSize();z8t++) { a8 = (CxIntArray*)g8->m_oaAtoms[z8t]; for (z8a=0;z8aGetSize();z8a++) { if ((!m_iRefOrSec[0][0]) || (obs == NULL)) vec->Add(((CxIntArray*)ref->m_oaAtomOffset[g1->m_baAtomType[z1t]])->GetAt(a1->GetAt(z1a))); else vec->Add(((CxIntArray*)obs->m_oaAtomOffset[g1->m_baAtomType[z1t]])->GetAt(a1->GetAt(z1a))); if ((!m_iRefOrSec[0][1]) || (obs == NULL)) vec->Add(((CxIntArray*)ref->m_oaAtomOffset[g2->m_baAtomType[z2t]])->GetAt(a2->GetAt(z2a))); else vec->Add(((CxIntArray*)obs->m_oaAtomOffset[g2->m_baAtomType[z2t]])->GetAt(a2->GetAt(z2a))); if ((!m_iRefOrSec[0][2]) || (obs == NULL)) vec->Add(((CxIntArray*)ref->m_oaAtomOffset[g3->m_baAtomType[z3t]])->GetAt(a3->GetAt(z3a))); else vec->Add(((CxIntArray*)obs->m_oaAtomOffset[g3->m_baAtomType[z3t]])->GetAt(a3->GetAt(z3a))); if ((!m_iRefOrSec[1][0]) || (obs == NULL)) vec->Add(((CxIntArray*)ref->m_oaAtomOffset[g4->m_baAtomType[z4t]])->GetAt(a4->GetAt(z4a))); else vec->Add(((CxIntArray*)obs->m_oaAtomOffset[g4->m_baAtomType[z4t]])->GetAt(a4->GetAt(z4a))); if ((!m_iRefOrSec[1][1]) || (obs == NULL)) vec->Add(((CxIntArray*)ref->m_oaAtomOffset[g5->m_baAtomType[z5t]])->GetAt(a5->GetAt(z5a))); else vec->Add(((CxIntArray*)obs->m_oaAtomOffset[g5->m_baAtomType[z5t]])->GetAt(a5->GetAt(z5a))); vec->Add(0); if ((!m_iRefOrSec[2][0]) || (obs == NULL)) vec->Add(((CxIntArray*)ref->m_oaAtomOffset[g7->m_baAtomType[z7t]])->GetAt(a7->GetAt(z7a))); else vec->Add(((CxIntArray*)obs->m_oaAtomOffset[g7->m_baAtomType[z7t]])->GetAt(a7->GetAt(z7a))); if ((!m_iRefOrSec[2][1]) || (obs == NULL)) vec->Add(((CxIntArray*)ref->m_oaAtomOffset[g8->m_baAtomType[z8t]])->GetAt(a8->GetAt(z8a))); else vec->Add(((CxIntArray*)obs->m_oaAtomOffset[g8->m_baAtomType[z8t]])->GetAt(a8->GetAt(z8a))); vec->Add(0); } } } } } // END IF NOT ORTHO[2] } } } } } // END IF NOT ORTHO[1] } } } } } } } else // IF NOT ORTHO[0] { g1 = (CAtomGroup*)m_oaVectors[z*9]; g2 = (CAtomGroup*)m_oaVectors[z*9+1]; for (z1t=0;z1tm_baAtomType.GetSize();z1t++) { a1 = (CxIntArray*)g1->m_oaAtoms[z1t]; for (z1a=0;z1aGetSize();z1a++) { for (z2t=0;z2tm_baAtomType.GetSize();z2t++) { a2 = (CxIntArray*)g2->m_oaAtoms[z2t]; for (z2a=0;z2aGetSize();z2a++) { if (m_bOrtho[1]) { g4 = (CAtomGroup*)m_oaVectors[z*9+3]; g5 = (CAtomGroup*)m_oaVectors[z*9+4]; g6 = (CAtomGroup*)m_oaVectors[z*9+5]; for (z4t=0;z4tm_baAtomType.GetSize();z4t++) { a4 = (CxIntArray*)g4->m_oaAtoms[z4t]; for (z4a=0;z4aGetSize();z4a++) { for (z5t=0;z5tm_baAtomType.GetSize();z5t++) { a5 = (CxIntArray*)g5->m_oaAtoms[z5t]; for (z5a=0;z5aGetSize();z5a++) { for (z6t=0;z6tm_baAtomType.GetSize();z6t++) { a6 = (CxIntArray*)g6->m_oaAtoms[z6t]; for (z6a=0;z6aGetSize();z6a++) { if (m_bOrtho[2]) { g7 = (CAtomGroup*)m_oaVectors[z*9+6]; g8 = (CAtomGroup*)m_oaVectors[z*9+7]; g9 = (CAtomGroup*)m_oaVectors[z*9+8]; for (z7t=0;z7tm_baAtomType.GetSize();z7t++) { a7 = (CxIntArray*)g7->m_oaAtoms[z7t]; for (z7a=0;z7aGetSize();z7a++) { for (z8t=0;z8tm_baAtomType.GetSize();z8t++) { a8 = (CxIntArray*)g8->m_oaAtoms[z8t]; for (z8a=0;z8aGetSize();z8a++) { for (z9t=0;z9tm_baAtomType.GetSize();z9t++) { a9 = (CxIntArray*)g9->m_oaAtoms[z9t]; for (z9a=0;z9aGetSize();z9a++) { if ((!m_iRefOrSec[0][0]) || (obs == NULL)) vec->Add(((CxIntArray*)ref->m_oaAtomOffset[g1->m_baAtomType[z1t]])->GetAt(a1->GetAt(z1a))); else vec->Add(((CxIntArray*)obs->m_oaAtomOffset[g1->m_baAtomType[z1t]])->GetAt(a1->GetAt(z1a))); if ((!m_iRefOrSec[0][1]) || (obs == NULL)) vec->Add(((CxIntArray*)ref->m_oaAtomOffset[g2->m_baAtomType[z2t]])->GetAt(a2->GetAt(z2a))); else vec->Add(((CxIntArray*)obs->m_oaAtomOffset[g2->m_baAtomType[z2t]])->GetAt(a2->GetAt(z2a))); vec->Add(0); if ((!m_iRefOrSec[1][0]) || (obs == NULL)) vec->Add(((CxIntArray*)ref->m_oaAtomOffset[g4->m_baAtomType[z4t]])->GetAt(a4->GetAt(z4a))); else vec->Add(((CxIntArray*)obs->m_oaAtomOffset[g4->m_baAtomType[z4t]])->GetAt(a4->GetAt(z4a))); if ((!m_iRefOrSec[1][1]) || (obs == NULL)) vec->Add(((CxIntArray*)ref->m_oaAtomOffset[g5->m_baAtomType[z5t]])->GetAt(a5->GetAt(z5a))); else vec->Add(((CxIntArray*)obs->m_oaAtomOffset[g5->m_baAtomType[z5t]])->GetAt(a5->GetAt(z5a))); if ((!m_iRefOrSec[1][2]) || (obs == NULL)) vec->Add(((CxIntArray*)ref->m_oaAtomOffset[g6->m_baAtomType[z6t]])->GetAt(a6->GetAt(z6a))); else vec->Add(((CxIntArray*)obs->m_oaAtomOffset[g6->m_baAtomType[z6t]])->GetAt(a6->GetAt(z6a))); if ((!m_iRefOrSec[2][0]) || (obs == NULL)) vec->Add(((CxIntArray*)ref->m_oaAtomOffset[g7->m_baAtomType[z7t]])->GetAt(a7->GetAt(z7a))); else vec->Add(((CxIntArray*)obs->m_oaAtomOffset[g7->m_baAtomType[z7t]])->GetAt(a7->GetAt(z7a))); if ((!m_iRefOrSec[2][1]) || (obs == NULL)) vec->Add(((CxIntArray*)ref->m_oaAtomOffset[g8->m_baAtomType[z8t]])->GetAt(a8->GetAt(z8a))); else vec->Add(((CxIntArray*)obs->m_oaAtomOffset[g8->m_baAtomType[z8t]])->GetAt(a8->GetAt(z8a))); if ((!m_iRefOrSec[2][2]) || (obs == NULL)) vec->Add(((CxIntArray*)ref->m_oaAtomOffset[g9->m_baAtomType[z9t]])->GetAt(a9->GetAt(z9a))); else vec->Add(((CxIntArray*)obs->m_oaAtomOffset[g9->m_baAtomType[z9t]])->GetAt(a9->GetAt(z9a))); } } } } } } } else // IF NOT ORTHO[2] { g7 = (CAtomGroup*)m_oaVectors[z*9+6]; g8 = (CAtomGroup*)m_oaVectors[z*9+7]; for (z7t=0;z7tm_baAtomType.GetSize();z7t++) { a7 = (CxIntArray*)g7->m_oaAtoms[z7t]; for (z7a=0;z7aGetSize();z7a++) { for (z8t=0;z8tm_baAtomType.GetSize();z8t++) { a8 = (CxIntArray*)g8->m_oaAtoms[z8t]; for (z8a=0;z8aGetSize();z8a++) { if ((!m_iRefOrSec[0][0]) || (obs == NULL)) vec->Add(((CxIntArray*)ref->m_oaAtomOffset[g1->m_baAtomType[z1t]])->GetAt(a1->GetAt(z1a))); else vec->Add(((CxIntArray*)obs->m_oaAtomOffset[g1->m_baAtomType[z1t]])->GetAt(a1->GetAt(z1a))); if ((!m_iRefOrSec[0][1]) || (obs == NULL)) vec->Add(((CxIntArray*)ref->m_oaAtomOffset[g2->m_baAtomType[z2t]])->GetAt(a2->GetAt(z2a))); else vec->Add(((CxIntArray*)obs->m_oaAtomOffset[g2->m_baAtomType[z2t]])->GetAt(a2->GetAt(z2a))); vec->Add(0); if ((!m_iRefOrSec[1][0]) || (obs == NULL)) vec->Add(((CxIntArray*)ref->m_oaAtomOffset[g4->m_baAtomType[z4t]])->GetAt(a4->GetAt(z4a))); else vec->Add(((CxIntArray*)obs->m_oaAtomOffset[g4->m_baAtomType[z4t]])->GetAt(a4->GetAt(z4a))); if ((!m_iRefOrSec[1][1]) || (obs == NULL)) vec->Add(((CxIntArray*)ref->m_oaAtomOffset[g5->m_baAtomType[z5t]])->GetAt(a5->GetAt(z5a))); else vec->Add(((CxIntArray*)obs->m_oaAtomOffset[g5->m_baAtomType[z5t]])->GetAt(a5->GetAt(z5a))); if ((!m_iRefOrSec[1][2]) || (obs == NULL)) vec->Add(((CxIntArray*)ref->m_oaAtomOffset[g6->m_baAtomType[z6t]])->GetAt(a6->GetAt(z6a))); else vec->Add(((CxIntArray*)obs->m_oaAtomOffset[g6->m_baAtomType[z6t]])->GetAt(a6->GetAt(z6a))); if ((!m_iRefOrSec[2][0]) || (obs == NULL)) vec->Add(((CxIntArray*)ref->m_oaAtomOffset[g7->m_baAtomType[z7t]])->GetAt(a7->GetAt(z7a))); else vec->Add(((CxIntArray*)obs->m_oaAtomOffset[g7->m_baAtomType[z7t]])->GetAt(a7->GetAt(z7a))); if ((!m_iRefOrSec[2][1]) || (obs == NULL)) vec->Add(((CxIntArray*)ref->m_oaAtomOffset[g8->m_baAtomType[z8t]])->GetAt(a8->GetAt(z8a))); else vec->Add(((CxIntArray*)obs->m_oaAtomOffset[g8->m_baAtomType[z8t]])->GetAt(a8->GetAt(z8a))); vec->Add(0); } } } } } // END IF NOT ORTHO[2] } } } } } } } else // IF NOT ORTHO[1] { g4 = (CAtomGroup*)m_oaVectors[z*9+3]; g5 = (CAtomGroup*)m_oaVectors[z*9+4]; for (z4t=0;z4tm_baAtomType.GetSize();z4t++) { a4 = (CxIntArray*)g4->m_oaAtoms[z4t]; for (z4a=0;z4aGetSize();z4a++) { for (z5t=0;z5tm_baAtomType.GetSize();z5t++) { a5 = (CxIntArray*)g5->m_oaAtoms[z5t]; for (z5a=0;z5aGetSize();z5a++) { if (m_bOrtho[2]) { g7 = (CAtomGroup*)m_oaVectors[z*9+6]; g8 = (CAtomGroup*)m_oaVectors[z*9+7]; g9 = (CAtomGroup*)m_oaVectors[z*9+8]; for (z7t=0;z7tm_baAtomType.GetSize();z7t++) { a7 = (CxIntArray*)g7->m_oaAtoms[z7t]; for (z7a=0;z7aGetSize();z7a++) { for (z8t=0;z8tm_baAtomType.GetSize();z8t++) { a8 = (CxIntArray*)g8->m_oaAtoms[z8t]; for (z8a=0;z8aGetSize();z8a++) { for (z9t=0;z9tm_baAtomType.GetSize();z9t++) { a9 = (CxIntArray*)g9->m_oaAtoms[z9t]; for (z9a=0;z9aGetSize();z9a++) { if ((!m_iRefOrSec[0][0]) || (obs == NULL)) vec->Add(((CxIntArray*)ref->m_oaAtomOffset[g1->m_baAtomType[z1t]])->GetAt(a1->GetAt(z1a))); else vec->Add(((CxIntArray*)obs->m_oaAtomOffset[g1->m_baAtomType[z1t]])->GetAt(a1->GetAt(z1a))); if ((!m_iRefOrSec[0][1]) || (obs == NULL)) vec->Add(((CxIntArray*)ref->m_oaAtomOffset[g2->m_baAtomType[z2t]])->GetAt(a2->GetAt(z2a))); else vec->Add(((CxIntArray*)obs->m_oaAtomOffset[g2->m_baAtomType[z2t]])->GetAt(a2->GetAt(z2a))); vec->Add(0); if ((!m_iRefOrSec[1][0]) || (obs == NULL)) vec->Add(((CxIntArray*)ref->m_oaAtomOffset[g4->m_baAtomType[z4t]])->GetAt(a4->GetAt(z4a))); else vec->Add(((CxIntArray*)obs->m_oaAtomOffset[g4->m_baAtomType[z4t]])->GetAt(a4->GetAt(z4a))); if ((!m_iRefOrSec[1][1]) || (obs == NULL)) vec->Add(((CxIntArray*)ref->m_oaAtomOffset[g5->m_baAtomType[z5t]])->GetAt(a5->GetAt(z5a))); else vec->Add(((CxIntArray*)obs->m_oaAtomOffset[g5->m_baAtomType[z5t]])->GetAt(a5->GetAt(z5a))); vec->Add(0); if ((!m_iRefOrSec[2][0]) || (obs == NULL)) vec->Add(((CxIntArray*)ref->m_oaAtomOffset[g7->m_baAtomType[z7t]])->GetAt(a7->GetAt(z7a))); else vec->Add(((CxIntArray*)obs->m_oaAtomOffset[g7->m_baAtomType[z7t]])->GetAt(a7->GetAt(z7a))); if ((!m_iRefOrSec[2][1]) || (obs == NULL)) vec->Add(((CxIntArray*)ref->m_oaAtomOffset[g8->m_baAtomType[z8t]])->GetAt(a8->GetAt(z8a))); else vec->Add(((CxIntArray*)obs->m_oaAtomOffset[g8->m_baAtomType[z8t]])->GetAt(a8->GetAt(z8a))); if ((!m_iRefOrSec[2][2]) || (obs == NULL)) vec->Add(((CxIntArray*)ref->m_oaAtomOffset[g9->m_baAtomType[z9t]])->GetAt(a9->GetAt(z9a))); else vec->Add(((CxIntArray*)obs->m_oaAtomOffset[g9->m_baAtomType[z9t]])->GetAt(a9->GetAt(z9a))); } } } } } } } else // IF NOT ORTHO[2] { g7 = (CAtomGroup*)m_oaVectors[z*9+6]; g8 = (CAtomGroup*)m_oaVectors[z*9+7]; for (z7t=0;z7tm_baAtomType.GetSize();z7t++) { a7 = (CxIntArray*)g7->m_oaAtoms[z7t]; for (z7a=0;z7aGetSize();z7a++) { for (z8t=0;z8tm_baAtomType.GetSize();z8t++) { a8 = (CxIntArray*)g8->m_oaAtoms[z8t]; for (z8a=0;z8aGetSize();z8a++) { if ((!m_iRefOrSec[0][0]) || (obs == NULL)) vec->Add(((CxIntArray*)ref->m_oaAtomOffset[g1->m_baAtomType[z1t]])->GetAt(a1->GetAt(z1a))); else vec->Add(((CxIntArray*)obs->m_oaAtomOffset[g1->m_baAtomType[z1t]])->GetAt(a1->GetAt(z1a))); if ((!m_iRefOrSec[0][1]) || (obs == NULL)) vec->Add(((CxIntArray*)ref->m_oaAtomOffset[g2->m_baAtomType[z2t]])->GetAt(a2->GetAt(z2a))); else vec->Add(((CxIntArray*)obs->m_oaAtomOffset[g2->m_baAtomType[z2t]])->GetAt(a2->GetAt(z2a))); vec->Add(0); if ((!m_iRefOrSec[1][0]) || (obs == NULL)) vec->Add(((CxIntArray*)ref->m_oaAtomOffset[g4->m_baAtomType[z4t]])->GetAt(a4->GetAt(z4a))); else vec->Add(((CxIntArray*)obs->m_oaAtomOffset[g4->m_baAtomType[z4t]])->GetAt(a4->GetAt(z4a))); if ((!m_iRefOrSec[1][1]) || (obs == NULL)) vec->Add(((CxIntArray*)ref->m_oaAtomOffset[g5->m_baAtomType[z5t]])->GetAt(a5->GetAt(z5a))); else vec->Add(((CxIntArray*)obs->m_oaAtomOffset[g5->m_baAtomType[z5t]])->GetAt(a5->GetAt(z5a))); vec->Add(0); if ((!m_iRefOrSec[2][0]) || (obs == NULL)) vec->Add(((CxIntArray*)ref->m_oaAtomOffset[g7->m_baAtomType[z7t]])->GetAt(a7->GetAt(z7a))); else vec->Add(((CxIntArray*)obs->m_oaAtomOffset[g7->m_baAtomType[z7t]])->GetAt(a7->GetAt(z7a))); if ((!m_iRefOrSec[2][1]) || (obs == NULL)) vec->Add(((CxIntArray*)ref->m_oaAtomOffset[g8->m_baAtomType[z8t]])->GetAt(a8->GetAt(z8a))); else vec->Add(((CxIntArray*)obs->m_oaAtomOffset[g8->m_baAtomType[z8t]])->GetAt(a8->GetAt(z8a))); vec->Add(0); } } } } } // END IF NOT ORTHO[2] } } } } } // END IF NOT ORTHO[1] } } } } } // END IF NOT ORTHO[0] } // END FOR ALL SETS BXOUT; } void CPlDF::BuildAtomList(CSingleMolecule *ref, CSingleMolecule *obs, CxIntArray *vec) { BXIN; int z, z1t, z1a, z2t, z2a, z3t, z3a, z4t, z4a; CAtomGroup *g1, *g2, *g3, *g4; CxIntArray *a1, *a2, *a3, *a4; vec->RemoveAll_KeepSize(); for (z=0;zm_baAtomType.GetSize();z1t++) { a1 = (CxIntArray*)g1->m_oaAtoms[z1t]; for (z1a=0;z1aGetSize();z1a++) { for (z2t=0;z2tm_baAtomType.GetSize();z2t++) { a2 = (CxIntArray*)g2->m_oaAtoms[z2t]; for (z2a=0;z2aGetSize();z2a++) { for (z4t=0;z4tm_baAtomType.GetSize();z4t++) { a4 = (CxIntArray*)g4->m_oaAtoms[z4t]; for (z4a=0;z4aGetSize();z4a++) { if ((!m_iRefOrSec[0]) || (obs == NULL)) vec->Add(((CxIntArray*)ref->m_oaAtomOffset[g1->m_baAtomType[z1t]])->GetAt(a1->GetAt(z1a))); else vec->Add(((CxIntArray*)obs->m_oaAtomOffset[g1->m_baAtomType[z1t]])->GetAt(a1->GetAt(z1a))); if ((!m_iRefOrSec[1]) || (obs == NULL)) vec->Add(((CxIntArray*)ref->m_oaAtomOffset[g2->m_baAtomType[z2t]])->GetAt(a2->GetAt(z2a))); else vec->Add(((CxIntArray*)obs->m_oaAtomOffset[g2->m_baAtomType[z2t]])->GetAt(a2->GetAt(z2a))); vec->Add(0); if ((!m_iRefOrSec[3]) || (obs == NULL)) vec->Add(((CxIntArray*)ref->m_oaAtomOffset[g4->m_baAtomType[z4t]])->GetAt(a4->GetAt(z4a))); else vec->Add(((CxIntArray*)obs->m_oaAtomOffset[g4->m_baAtomType[z4t]])->GetAt(a4->GetAt(z4a))); } } } } } } } else // IF NOT NORMAL { g1 = (CAtomGroup*)m_oaVectors[z*4]; g2 = (CAtomGroup*)m_oaVectors[z*4+1]; g3 = (CAtomGroup*)m_oaVectors[z*4+2]; g4 = (CAtomGroup*)m_oaVectors[z*4+3]; for (z1t=0;z1tm_baAtomType.GetSize();z1t++) { a1 = (CxIntArray*)g1->m_oaAtoms[z1t]; for (z1a=0;z1aGetSize();z1a++) { for (z2t=0;z2tm_baAtomType.GetSize();z2t++) { a2 = (CxIntArray*)g2->m_oaAtoms[z2t]; for (z2a=0;z2aGetSize();z2a++) { for (z3t=0;z3tm_baAtomType.GetSize();z3t++) { a3 = (CxIntArray*)g3->m_oaAtoms[z3t]; for (z3a=0;z3aGetSize();z3a++) { for (z4t=0;z4tm_baAtomType.GetSize();z4t++) { a4 = (CxIntArray*)g4->m_oaAtoms[z4t]; for (z4a=0;z4aGetSize();z4a++) { if ((!m_iRefOrSec[0]) || (obs == NULL)) vec->Add(((CxIntArray*)ref->m_oaAtomOffset[g1->m_baAtomType[z1t]])->GetAt(a1->GetAt(z1a))); else vec->Add(((CxIntArray*)obs->m_oaAtomOffset[g1->m_baAtomType[z1t]])->GetAt(a1->GetAt(z1a))); if ((!m_iRefOrSec[1]) || (obs == NULL)) vec->Add(((CxIntArray*)ref->m_oaAtomOffset[g2->m_baAtomType[z2t]])->GetAt(a2->GetAt(z2a))); else vec->Add(((CxIntArray*)obs->m_oaAtomOffset[g2->m_baAtomType[z2t]])->GetAt(a2->GetAt(z2a))); if ((!m_iRefOrSec[2]) || (obs == NULL)) vec->Add(((CxIntArray*)ref->m_oaAtomOffset[g3->m_baAtomType[z3t]])->GetAt(a3->GetAt(z3a))); else vec->Add(((CxIntArray*)obs->m_oaAtomOffset[g3->m_baAtomType[z3t]])->GetAt(a3->GetAt(z3a))); if ((!m_iRefOrSec[3]) || (obs == NULL)) vec->Add(((CxIntArray*)ref->m_oaAtomOffset[g4->m_baAtomType[z4t]])->GetAt(a4->GetAt(z4a))); else vec->Add(((CxIntArray*)obs->m_oaAtomOffset[g4->m_baAtomType[z4t]])->GetAt(a4->GetAt(z4a))); } } } } } } } } } } // END FOR ALL SETS BXOUT; } void CLiDF::BuildAtomList(CSingleMolecule *ref, CSingleMolecule *obs, CxIntArray *vec) { BXIN; int z, z1t, z1a, z2t, z2a, z3t, z3a, z4t, z4a; CAtomGroup *g1, *g2, *g3, *g4; CxIntArray *a1, *a2, *a3, *a4; vec->RemoveAll_KeepSize(); for (z=0;zm_baAtomType.GetSize();z1t++) { a1 = (CxIntArray*)g1->m_oaAtoms[z1t]; for (z1a=0;z1aGetSize();z1a++) { for (z2t=0;z2tm_baAtomType.GetSize();z2t++) { a2 = (CxIntArray*)g2->m_oaAtoms[z2t]; for (z2a=0;z2aGetSize();z2a++) { for (z3t=0;z3tm_baAtomType.GetSize();z3t++) { a3 = (CxIntArray*)g3->m_oaAtoms[z3t]; for (z3a=0;z3aGetSize();z3a++) { for (z4t=0;z4tm_baAtomType.GetSize();z4t++) { a4 = (CxIntArray*)g4->m_oaAtoms[z4t]; for (z4a=0;z4aGetSize();z4a++) { if ((!m_iRefOrSec[0]) || (obs == NULL)) vec->Add(((CxIntArray*)ref->m_oaAtomOffset[g1->m_baAtomType[z1t]])->GetAt(a1->GetAt(z1a))); else vec->Add(((CxIntArray*)obs->m_oaAtomOffset[g1->m_baAtomType[z1t]])->GetAt(a1->GetAt(z1a))); if ((!m_iRefOrSec[1]) || (obs == NULL)) vec->Add(((CxIntArray*)ref->m_oaAtomOffset[g2->m_baAtomType[z2t]])->GetAt(a2->GetAt(z2a))); else vec->Add(((CxIntArray*)obs->m_oaAtomOffset[g2->m_baAtomType[z2t]])->GetAt(a2->GetAt(z2a))); if ((!m_iRefOrSec[2]) || (obs == NULL)) vec->Add(((CxIntArray*)ref->m_oaAtomOffset[g3->m_baAtomType[z3t]])->GetAt(a3->GetAt(z3a))); else vec->Add(((CxIntArray*)obs->m_oaAtomOffset[g3->m_baAtomType[z3t]])->GetAt(a3->GetAt(z3a))); if ((!m_iRefOrSec[3]) || (obs == NULL)) vec->Add(((CxIntArray*)ref->m_oaAtomOffset[g4->m_baAtomType[z4t]])->GetAt(a4->GetAt(z4a))); else vec->Add(((CxIntArray*)obs->m_oaAtomOffset[g4->m_baAtomType[z4t]])->GetAt(a4->GetAt(z4a))); } } } } } } } } } else // If not Normal { g1 = (CAtomGroup*)m_oaVectors[z*4]; g2 = (CAtomGroup*)m_oaVectors[z*4+1]; g4 = (CAtomGroup*)m_oaVectors[z*4+3]; for (z1t=0;z1tm_baAtomType.GetSize();z1t++) { a1 = (CxIntArray*)g1->m_oaAtoms[z1t]; for (z1a=0;z1aGetSize();z1a++) { for (z2t=0;z2tm_baAtomType.GetSize();z2t++) { a2 = (CxIntArray*)g2->m_oaAtoms[z2t]; for (z2a=0;z2aGetSize();z2a++) { for (z4t=0;z4tm_baAtomType.GetSize();z4t++) { a4 = (CxIntArray*)g4->m_oaAtoms[z4t]; for (z4a=0;z4aGetSize();z4a++) { if ((!m_iRefOrSec[0]) || (obs == NULL)) vec->Add(((CxIntArray*)ref->m_oaAtomOffset[g1->m_baAtomType[z1t]])->GetAt(a1->GetAt(z1a))); else vec->Add(((CxIntArray*)obs->m_oaAtomOffset[g1->m_baAtomType[z1t]])->GetAt(a1->GetAt(z1a))); if ((!m_iRefOrSec[1]) || (obs == NULL)) vec->Add(((CxIntArray*)ref->m_oaAtomOffset[g2->m_baAtomType[z2t]])->GetAt(a2->GetAt(z2a))); else vec->Add(((CxIntArray*)obs->m_oaAtomOffset[g2->m_baAtomType[z2t]])->GetAt(a2->GetAt(z2a))); vec->Add(0); if ((!m_iRefOrSec[3]) || (obs == NULL)) vec->Add(((CxIntArray*)ref->m_oaAtomOffset[g4->m_baAtomType[z4t]])->GetAt(a4->GetAt(z4a))); else vec->Add(((CxIntArray*)obs->m_oaAtomOffset[g4->m_baAtomType[z4t]])->GetAt(a4->GetAt(z4a))); } } } } } } } } // END FOR ALL SETS BXOUT; } void CRDF::BuildName() { BTIN; int z; // char tmp[32768]; CxString tmp; // tmp[0] = 0; tmp = ""; if (m_iDeriv != 0) // sprintf(tmp,"deriv%d_",m_iDeriv); tmp.sprintf("deriv%d_",m_iDeriv); for (z=0;zm_sName); tmp.strcat("["); tmp.strcat(((CAtomGroup*)m_oaVectors[z*2])->m_sName); if (m_iRefOrSec[0]) // strcat(tmp,"o_"); tmp.strcat("o_"); else // strcat(tmp,"r_"); tmp.strcat("r_"); // strcat(tmp,((CAtomGroup*)m_oaVectors[z*2+1])->m_sName); tmp.strcat(((CAtomGroup*)m_oaVectors[z*2+1])->m_sName); if (m_iRefOrSec[1]) // strcat(tmp,"o"); tmp.strcat("o"); else // strcat(tmp,"r"); tmp.strcat("r"); if (z < (m_oaVectors.GetSize()/2)-1) // strcat(tmp,"],"); tmp.strcat("],"); else // strcat(tmp,"]"); tmp.strcat("]"); } try { m_sShortName = new char[strlen(tmp)+1]; } catch(...) { m_sShortName = NULL; } if (m_sShortName == NULL) NewException((double)(strlen(tmp)+1)*sizeof(char),__FILE__,__LINE__,__PRETTY_FUNCTION__); strcpy(m_sShortName,(const char*)tmp); if (m_iShowMol != -1) // sprintf(tmp,"%s_%s%d_%s_",((CMolecule*)g_oaMolecules[g_iFixMol])->m_sName,((CAtom*)g_oaAtoms[g_iFixRealAtomType[0]])->m_sName,g_iFixAtom[0]+1,((CMolecule*)g_oaMolecules[m_iShowMol])->m_sName); tmp.sprintf("%s_%s%d_%s_",((CMolecule*)g_oaMolecules[g_iFixMol])->m_sName,(const char*)((CAtom*)g_oaAtoms[g_iFixRealAtomType[0]])->m_sName,g_iFixAtom[0]+1,((CMolecule*)g_oaMolecules[m_iShowMol])->m_sName); else // sprintf(tmp,"%s_%s%d_",((CMolecule*)g_oaMolecules[g_iFixMol])->m_sName,((CAtom*)g_oaAtoms[g_iFixRealAtomType[0]])->m_sName,g_iFixAtom[0]+1); tmp.sprintf("%s_%s%d_",((CMolecule*)g_oaMolecules[g_iFixMol])->m_sName,(const char*)((CAtom*)g_oaAtoms[g_iFixRealAtomType[0]])->m_sName,g_iFixAtom[0]+1); // strcat(tmp,m_sShortName); tmp.strcat(m_sShortName); try { m_sName = new char[strlen(tmp)+1]; } catch(...) { m_sName = NULL; } if (m_sName == NULL) NewException((double)(strlen(tmp)+1)*sizeof(char),__FILE__,__LINE__,__PRETTY_FUNCTION__); strcpy(m_sName,tmp); tmp = ""; if (m_iDeriv != 0) tmp.sprintf("deriv%d_",m_iDeriv); tmp.strcat("["); tmp.strcat(((CAtomGroup*)m_oaVectors[0])->m_sName); if (m_iRefOrSec[0]) tmp.strcat("o_"); else tmp.strcat("r_"); tmp.strcat(((CAtomGroup*)m_oaVectors[1])->m_sName); if (m_iRefOrSec[1]) tmp.strcat("o"); else tmp.strcat("r"); tmp.strcat("]"); if (m_oaVectors.GetSize() > 2) tmp.strcat(",(...)"); try { m_sLabelName = new char[strlen(tmp)+1]; } catch(...) { m_sLabelName = NULL; } if (m_sLabelName == NULL) NewException((double)(strlen(tmp)+1)*sizeof(char),__FILE__,__LINE__,__PRETTY_FUNCTION__); strcpy(m_sLabelName,tmp); BTOUT; } void CDensDF::BuildName() { BTIN; // char tmp[32768]; CxString tmp; int z; // sprintf(tmp,"%s_%s%d_%s",((CMolecule*)g_oaMolecules[m_iShowMol])->m_sName,((CAtom*)g_oaAtoms[m_iCenterAtomRealType])->m_sName,m_iCenterAtom+1,(m_bDensityMass?"mass":"particle")); tmp.sprintf("%s_%s%d_%s",((CMolecule*)g_oaMolecules[m_iShowMol])->m_sName,(const char*)((CAtom*)g_oaAtoms[m_iCenterAtomRealType])->m_sName,m_iCenterAtom+1,(m_bDensityMass?"mass":"particle")); for (z=0;zm_sName); tmp.strcat("_"); tmp.strcat(((CMolecule*)g_oaMolecules[z])->m_sName); if (!m_pDensityMolAG[z]->m_bAllAtoms) { // strcat(tmp,"_"); // strcat(tmp,m_pDensityMolAG[z]->m_sName); tmp.strcat("_"); tmp.strcat(m_pDensityMolAG[z]->m_sName); } } try { m_sName = new char[strlen(tmp)+1]; } catch(...) { m_sName = NULL; } if (m_sName == NULL) NewException((double)(strlen(tmp)+1)*sizeof(char),__FILE__,__LINE__,__PRETTY_FUNCTION__); strcpy(m_sName,tmp); BTOUT; } void CVHDF::BuildName() { BTIN; int z; // char tmp[32768]; CxString tmp; // tmp[0] = 0; tmp = ""; for (z=0;zm_sName); tmp.strcat("["); tmp.strcat(((CAtomGroup*)m_oaVectors[z*2])->m_sName); if (m_iRefOrSec[0]) // strcat(tmp,"o_"); tmp.strcat("o_"); else // strcat(tmp,"r_"); tmp.strcat("r_"); // strcat(tmp,((CAtomGroup*)m_oaVectors[z*2+1])->m_sName); tmp.strcat(((CAtomGroup*)m_oaVectors[z*2+1])->m_sName); if (m_iRefOrSec[1]) // strcat(tmp,"o"); tmp.strcat("o"); else // strcat(tmp,"r"); tmp.strcat("r"); if (z < (m_oaVectors.GetSize()/2)-1) // strcat(tmp,"],"); tmp.strcat("],"); else // strcat(tmp,"]"); tmp.strcat("]"); } try { m_sShortName = new char[strlen(tmp)+1]; } catch(...) { m_sShortName = NULL; } if (m_sShortName == NULL) NewException((double)(strlen(tmp)+1)*sizeof(char),__FILE__,__LINE__,__PRETTY_FUNCTION__); strcpy(m_sShortName,tmp); if (m_iShowMol != -1) // sprintf(tmp,"%s_%s%d_%s_",((CMolecule*)g_oaMolecules[g_iFixMol])->m_sName,((CAtom*)g_oaAtoms[g_iFixRealAtomType[0]])->m_sName,g_iFixAtom[0]+1,((CMolecule*)g_oaMolecules[m_iShowMol])->m_sName); tmp.sprintf("%s_%s%d_%s_",((CMolecule*)g_oaMolecules[g_iFixMol])->m_sName,(const char*)((CAtom*)g_oaAtoms[g_iFixRealAtomType[0]])->m_sName,g_iFixAtom[0]+1,((CMolecule*)g_oaMolecules[m_iShowMol])->m_sName); else // sprintf(tmp,"%s_%s%d_",((CMolecule*)g_oaMolecules[g_iFixMol])->m_sName,((CAtom*)g_oaAtoms[g_iFixRealAtomType[0]])->m_sName,g_iFixAtom[0]+1); tmp.sprintf("%s_%s%d_",((CMolecule*)g_oaMolecules[g_iFixMol])->m_sName,(const char*)((CAtom*)g_oaAtoms[g_iFixRealAtomType[0]])->m_sName,g_iFixAtom[0]+1); // strcat(tmp,m_sShortName); tmp.strcat(m_sShortName); try { m_sName = new char[strlen(tmp)+1]; } catch(...) { m_sName = NULL; } if (m_sName == NULL) NewException((double)(strlen(tmp)+1)*sizeof(char),__FILE__,__LINE__,__PRETTY_FUNCTION__); strcpy(m_sName,tmp); BTOUT; } void CRDF::Parse() { BTIN; // char buf[1024]; CxString buf; int ti; CAtomGroup *ag; try { m_pRDF = new CDF(); } catch(...) { m_pRDF = NULL; } if (m_pRDF == NULL) NewException((double)sizeof(CDF),__FILE__,__LINE__,__PRETTY_FUNCTION__); m_iShowAtomGes = 0; m_iRefAtomGes = 0; m_iCombinations = 0; mprintf(WHITE,"\n>>> Radial Distribution Function >>>\n\n"); /* if (m_bSelf) { m_iRefOrSec[0] = 0; m_iRefOrSec[1] = 0; } else { m_iRefOrSec[0] = 0; m_iRefOrSec[1] = 1; }*/ if (m_iShowMol != -1) m_iRefOrSec[0] = AskRangeInteger(" Take reference atom(s) from RM %s (0) or from OM %s (1)? [0] ",0,1,0,((CMolecule*)g_oaMolecules[g_iFixMol])->m_sName,((CMolecule*)g_oaMolecules[m_iShowMol])->m_sName); else m_iRefOrSec[0] = 0; // Kein OM: Nimm alles aus RM if (m_iShowMol != -1) m_iRefOrSec[1] = AskRangeInteger(" Take observed atom(s) from RM %s (0) or from OM %s (1)? [1] ",0,1,1,((CMolecule*)g_oaMolecules[g_iFixMol])->m_sName,((CMolecule*)g_oaMolecules[m_iShowMol])->m_sName); else m_iRefOrSec[1] = 0; // Kein OM: Nimm alles aus RM _rdfnewset: mprintf("\n"); try { ag = new CAtomGroup(); } catch(...) { ag = NULL; } if (ag == NULL) NewException((double)sizeof(CAtomGroup),__FILE__,__LINE__,__PRETTY_FUNCTION__); _rdfatom1: // 1 reales + 2 virtuelle = 3 gesamt if (((CMolecule*)g_oaMolecules[(m_iRefOrSec[0])?m_iShowMol:g_iFixMol])->m_iAtomGesNoVirt == 1) { mprintf(" %s is only one atom, there is no choice.\n",((CMolecule*)g_oaMolecules[(m_iRefOrSec[0])?m_iShowMol:g_iFixMol])->m_sName); ag->Reset(); ag->m_pMolecule = (CMolecule*)g_oaMolecules[(m_iRefOrSec[0])?m_iShowMol:g_iFixMol]; ag->AddAtom(0,0,false); ag->SortAtoms(); ag->BuildName(); } else { if (m_iRefOrSec[0]) { mprintf(" Which atom(s) to take from OM %s (e.g. \"C1,C3-5,H\", \"*\"=all)? [#2] ",((CMolecule*)g_oaMolecules[m_iShowMol])->m_sName); inpprintf("! Which atom(s) to take from OM %s (e.g. \"C1,C3-5,H\", \"*\"=all)? [#2]\n",((CMolecule*)g_oaMolecules[m_iShowMol])->m_sName); } else { mprintf(" Which atom(s) to take from RM %s (e.g. \"C1,C3-5,H\", \"*\"=all)? [#2] ",((CMolecule*)g_oaMolecules[g_iFixMol])->m_sName); inpprintf("! Which atom(s) to take from RM %s (e.g. \"C1,C3-5,H\", \"*\"=all)? [#2]\n",((CMolecule*)g_oaMolecules[g_iFixMol])->m_sName); } myget(&buf); if (strlen(buf) == 0) { if (!ag->ParseAtoms((CMolecule*)g_oaMolecules[(m_iRefOrSec[0])?m_iShowMol:g_iFixMol],"#2")) { eprintf("CRDF::Parse(): Internal error.\n"); goto _rdfatom1; } } else if (!ag->ParseAtoms((CMolecule*)g_oaMolecules[(m_iRefOrSec[0])?m_iShowMol:g_iFixMol],buf)) goto _rdfatom1; } m_oaVectors.Add(ag); m_iRefAtomGes += ag->m_iAtomGes; ti = ag->m_iAtomGes; try { ag = new CAtomGroup(); } catch(...) { ag = NULL; } if (ag == NULL) NewException((double)sizeof(CAtomGroup),__FILE__,__LINE__,__PRETTY_FUNCTION__); _rdfatom2: if (((CMolecule*)g_oaMolecules[(m_iRefOrSec[1])?m_iShowMol:g_iFixMol])->m_iAtomGesNoVirt == 1) { mprintf(" %s is only one atom, there is no choice.\n",((CMolecule*)g_oaMolecules[(m_iRefOrSec[1])?m_iShowMol:g_iFixMol])->m_sName); ag->Reset(); ag->m_pMolecule = (CMolecule*)g_oaMolecules[(m_iRefOrSec[1])?m_iShowMol:g_iFixMol]; ag->AddAtom(0,0,false); ag->SortAtoms(); ag->BuildName(); } else { if (m_iRefOrSec[1]) { mprintf(" Which atom(s) to take from OM %s (e.g. \"C1,C3-5,H\", \"*\"=all)? [#2] ",((CMolecule*)g_oaMolecules[m_iShowMol])->m_sName); inpprintf("! Which atom(s) to take from OM %s (e.g. \"C1,C3-5,H\", \"*\"=all)? [#2]\n",((CMolecule*)g_oaMolecules[m_iShowMol])->m_sName); } else { mprintf(" Which atom(s) to take from RM %s (e.g. \"C1,C3-5,H\", \"*\"=all)? [#2] ",((CMolecule*)g_oaMolecules[g_iFixMol])->m_sName); inpprintf("! Which atom(s) to take from RM %s (e.g. \"C1,C3-5,H\", \"*\"=all)? [#2]\n",((CMolecule*)g_oaMolecules[g_iFixMol])->m_sName); } myget(&buf); try { ag = new CAtomGroup(); } catch(...) { ag = NULL; } if (ag == NULL) NewException((double)sizeof(CAtomGroup),__FILE__,__LINE__,__PRETTY_FUNCTION__); if (strlen(buf) == 0) { if (!ag->ParseAtoms((CMolecule*)g_oaMolecules[(m_iRefOrSec[1])?m_iShowMol:g_iFixMol],"#2")) { eprintf("CRDF::Parse(): Internal error.\n"); goto _rdfatom2; } } else if (!ag->ParseAtoms((CMolecule*)g_oaMolecules[(m_iRefOrSec[1])?m_iShowMol:g_iFixMol],buf)) goto _rdfatom2; } m_oaVectors.Add(ag); m_iShowAtomGes += ag->m_iAtomGes; m_iCombinations += ti * ag->m_iAtomGes; if (g_bAdvanced2) if (AskYesNo(" Add another set of atoms to this (!) RDF (y/n)? [no] ",false)) goto _rdfnewset; mprintf(" This yields in %d combinations.\n\n",m_iCombinations); ParseDeriv(); switch(m_iDeriv) { case 0: m_fMinDist = AskFloat(" Enter the minimal radius of this RDF in pm: [0] ",0.0); m_fMaxDist = AskFloat(" Enter the maximal radius of this RDF in pm: [%d.0] ",(double)HalfBox(),HalfBox()); break; case 1: if (m_bDerivAbs) m_fMinDist = AskFloat(" Enter the minimal value of this d1-RDF in pm/ps: [0] ",0.0); else m_fMinDist = AskFloat(" Enter the minimal value of this d1-RDF in pm/ps: [-10.0] ",-10.0); m_fMaxDist = AskFloat(" Enter the maximal value of this d1-RDF in pm/ps: [10.0] ",10.0); break; case 2: if (m_bDerivAbs) m_fMinDist = AskFloat(" Enter the minimal value of this d2-RDF in pm/ps^2: [0] ",0.0); else m_fMinDist = AskFloat(" Enter the minimal value of this d2-RDF in pm/ps^2: [-10.0] ",-10.0); m_fMaxDist = AskFloat(" Enter the maximal value of this d2-RDF in pm/ps^2: [10.0] ",10.0); break; } if (g_bPeriodic && (m_iDeriv == 0) && (m_fMaxDist > HalfBox_Exact()+1.0)) { eprintf("\nWarning: "); mprintf("The specified max. radius is larger than half of the smallest periodic cell vector.\n"); mprintf(" TRAVIS counts every atom only once (central periodic image).\n"); mprintf(" Expect the analysis to decay to zero for large radii.\n\n"); AskYesNo(" Acknowledged [yes] ",true); mprintf("\n"); } m_bAdaptive = false/*AskYesNo(" Enter binning resolution (n) or use adaptive binnig (y)? [no] ",false)*/; if (!m_bAdaptive) m_iResolution = AskUnsignedInteger(" Enter the resolution (bin count) for this RDF: [300] ",/*(int)((m_fMaxDist-m_fMinDist)/10.0f),(int)((m_fMaxDist-m_fMinDist)/10.0f)*/300); else m_iResolution = 65536; if (g_bAdvanced2) { m_iHistogramRes = AskUnsignedInteger(" Please enter histogram resolution (0=no histogram): [0] ",0); m_bLine = AskYesNo(" Draw a line in the agr file at g(r) = 1 (y/n)? [no] ",false); } else { m_iHistogramRes = 0; m_bLine = false; } if (m_iDeriv == 0) { // if (m_iShowMol != -1) m_bRadialCorrect = AskYesNo(" Correct radial distribution for this RDF (y/n)? [yes] ",true); // else m_bRadialCorrect = AskYesNo(" Correct radial distribution for this RDF (y/n)? [no] ",false); } else m_bRadialCorrect = false; if (g_bAdvanced2 && m_bRadialCorrect) m_bProbDens = AskYesNo(" Compute occurrence in nm^(-3) (y) or rel. to uniform density (n)? [no] ",false); else m_bProbDens = false; m_bLongMode = false; BuildName(); mprintf(WHITE,"\n<<< End of Radial Distribution Function <<<\n\n"); BTOUT; } void CDensDF::Parse() { BTIN; // char buf[1024]; CxString buf; int z; CMolecule *m; try { m_pDensDF = new CDF(); } catch(...) { m_pDensDF = NULL; } if (m_pDensDF == NULL) NewException((double)sizeof(CDF),__FILE__,__LINE__,__PRETTY_FUNCTION__); mprintf(WHITE,"\n>>> Density Distribution Function >>>\n\n"); m_bDensityMass = AskYesNo(" Observe mass density (y) or particle density (n)? [yes] ",true); mprintf("\n Choose a reference atom around which the density will be analyzed.\n\n"); // 1 reales + 2 virtuelle = 3 gesamt if (((CMolecule*)g_oaMolecules[m_iShowMol])->m_iAtomGesNoVirt == 1) { mprintf(" %s is only one atom, there is no choice.\n",((CMolecule*)g_oaMolecules[m_iShowMol])->m_sName); if (!ParseAtom("#2",m_iShowMol,m_iCenterAtomType,m_iCenterAtomRealType,m_iCenterAtom)) { eprintf("CDensDF::Parse(): Internal error.\n"); abort(); } } else { _densatom1: mprintf(" Which atom to take from OM %s (e.g. C1)? [#2] ",((CMolecule*)g_oaMolecules[m_iShowMol])->m_sName); inpprintf("! Which atom to take from OM %s (e.g. C1)? [#2]\n",((CMolecule*)g_oaMolecules[m_iShowMol])->m_sName); myget(&buf); if (strlen(buf) == 0) { if (!ParseAtom("#2",m_iShowMol,m_iCenterAtomType,m_iCenterAtomRealType,m_iCenterAtom)) { eprintf("CDensDF::Parse(): Internal error.\n"); abort(); } } else if (!ParseAtom(buf,m_iShowMol,m_iCenterAtomType,m_iCenterAtomRealType,m_iCenterAtom)) goto _densatom1; } try { m_pDensityMolSelect = new bool[g_oaMolecules.GetSize()]; } catch(...) { m_pDensityMolSelect = NULL; } if (m_pDensityMolSelect == NULL) NewException((double)g_oaMolecules.GetSize()*sizeof(bool),__FILE__,__LINE__,__PRETTY_FUNCTION__); try { m_pDensityMolAG = new CAtomGroup*[g_oaMolecules.GetSize()]; } catch(...) { m_pDensityMolAG = NULL; } if (m_pDensityMolAG == NULL) NewException((double)g_oaMolecules.GetSize()*sizeof(CAtomGroup*),__FILE__,__LINE__,__PRETTY_FUNCTION__); mprintf("\n Please choose the atoms to observe:\n\n"); for (z=0;zm_bPseudo,((CMolecule*)g_oaMolecules[z])->m_sName,m->m_bPseudo?"no":"yes"); if (m_pDensityMolSelect[z]) { try { m_pDensityMolAG[z] = new CAtomGroup(); } catch(...) { m_pDensityMolAG[z] = NULL; } if (m_pDensityMolAG[z] == NULL) NewException((double)sizeof(CAtomGroup),__FILE__,__LINE__,__PRETTY_FUNCTION__); _densatom2: AskString(" Which atoms from %s to observe (e.g. C1-3,C6,N)? [all] ",&buf,"",m->m_sName); if (strlen(buf) == 0) { m_pDensityMolAG[z]->AddAllAtoms(m,false); } else if (!m_pDensityMolAG[z]->ParseAtoms(m,buf)) goto _densatom2; } } mprintf("\n"); m_fMinDist = AskFloat(" Enter the minimal radius of this Density DF in pm: [0] ",0.0); m_fMaxDist = AskFloat(" Enter the maximal radius of this Density DF in pm: [%d.0] ",(double)HalfBox(),HalfBox()); m_iResolution = AskUnsignedInteger(" Enter the resolution (bin count) for this Density DF: [300] ",300); if (g_bAdvanced2) m_iHistogramRes = AskUnsignedInteger(" Please enter histogram resolution (0=no histogram): [0] ",0); else m_iHistogramRes = 0; BuildName(); mprintf(WHITE,"\n<<< End of Density Distribution Function <<<\n\n"); BTOUT; } void CRDF::ParseCondition(int rm, CNbSearch *n, bool nbana) { BTIN; // char buf[1024]; CxString buf; int ti; CAtomGroup *ag; try { m_pRDF = new CDF(); } catch(...) { m_pRDF = NULL; } if (m_pRDF == NULL) NewException((double)sizeof(CDF),__FILE__,__LINE__,__PRETTY_FUNCTION__); m_iShowAtomGes = 0; m_iRefAtomGes = 0; m_iCombinations = 0; m_iRefOrSec[0] = 0; m_iRefOrSec[1] = 1; mprintf(WHITE,"\n>>> Distance Condition >>>\n"); _rdfnewset: mprintf("\n"); try { ag = new CAtomGroup(); } catch(...) { ag = NULL; } if (ag == NULL) NewException((double)sizeof(CAtomGroup),__FILE__,__LINE__,__PRETTY_FUNCTION__); _rdfatom1: if (((CMolecule*)g_oaMolecules[rm])->m_iAtomGesNoVirt == 1) { mprintf(" %s is only one atom, there is no choice.\n",((CMolecule*)g_oaMolecules[rm])->m_sName); ag->Reset(); ag->m_pMolecule = (CMolecule*)g_oaMolecules[rm]; ag->AddAtom(0,0,false); ag->SortAtoms(); ag->BuildName(); } else { mprintf(" Which atom(s) to take from RM %s (e.g. \"C1,C3-5,H\", \"*\"=all)? [#2] ",((CMolecule*)g_oaMolecules[rm])->m_sName); inpprintf("! Which atom(s) to take from RM %s (e.g. \"C1,C3-5,H\", \"*\"=all)? [#2]\n",((CMolecule*)g_oaMolecules[rm])->m_sName); myget(&buf); if (strlen(buf) == 0) { if (!ag->ParseAtoms((CMolecule*)g_oaMolecules[rm],"#2")) { eprintf("CRDF::ParseCondition(): Internal error.\n"); goto _rdfatom1; } } else if (!ag->ParseAtoms((CMolecule*)g_oaMolecules[rm],buf)) goto _rdfatom1; } m_oaVectors.Add(ag); m_iRefAtomGes += ag->m_iAtomGes; ti = ag->m_iAtomGes; try { ag = new CAtomGroup(); } catch(...) { ag = NULL; } if (ag == NULL) NewException((double)sizeof(CAtomGroup),__FILE__,__LINE__,__PRETTY_FUNCTION__); _rdfatom2: if (((CMolecule*)g_oaMolecules[m_iShowMol])->m_iAtomGesNoVirt == 1) { mprintf(" %s is only one atom, there is no choice.\n",((CMolecule*)g_oaMolecules[m_iShowMol])->m_sName); ag->Reset(); ag->m_pMolecule = (CMolecule*)g_oaMolecules[m_iShowMol]; ag->AddAtom(0,0,false); ag->SortAtoms(); ag->BuildName(); } else { mprintf(" Which atom(s) to take from OM %s (e.g. \"C1,C3-5,H\", \"*\"=all)? [#2] ",((CMolecule*)g_oaMolecules[m_iShowMol])->m_sName); inpprintf("! Which atom(s) to take from OM %s (e.g. \"C1,C3-5,H\", \"*\"=all)? [#2]\n",((CMolecule*)g_oaMolecules[m_iShowMol])->m_sName); myget(&buf); try { ag = new CAtomGroup(); } catch(...) { ag = NULL; } if (ag == NULL) NewException((double)sizeof(CAtomGroup),__FILE__,__LINE__,__PRETTY_FUNCTION__); if (strlen(buf) == 0) { if (!ag->ParseAtoms((CMolecule*)g_oaMolecules[m_iShowMol],"#2")) { eprintf("CRDF::ParseCondition(): Internal error.\n"); goto _rdfatom2; } } else if (!ag->ParseAtoms((CMolecule*)g_oaMolecules[m_iShowMol],buf)) goto _rdfatom2; } m_oaVectors.Add(ag); m_iShowAtomGes += ag->m_iAtomGes; m_iCombinations += ti * ag->m_iAtomGes; if (AskYesNo(" Enter another set of atoms for this condition (y/n)? [no] ",false)) goto _rdfnewset; if (!nbana) { if (AskUnsignedInteger("\n Enter min./max. distance (0) or min./max. nearest neighbor count (1)? [0] ",0)==0) { g_bEnvDisableSortNb = true; do { m_faMinMaxDist.Add(AskFloat(" Enter the minimal distance in pm: [0] ",0.0)); m_faMinMaxDist.Add(AskFloat(" Enter the maximal distance in pm: [400] ",400.0)); } while (AskYesNo(" Enter another distance interval (y/n)? [no] ",false)); n->m_iNbCountMin = -1; n->m_iNbCountMax = -1; } else { n->m_iNbCountMin = AskRangeInteger(" Use next neighbors from the n-th on? [1] ",0,((CMolecule*)g_oaMolecules[m_iShowMol])->m_laSingleMolIndex.GetSize(),1)-1; n->m_iNbCountMax = AskRangeInteger(" Use next neighbors up to the n-th? [%d] ",n->m_iNbCountMin+1,((CMolecule*)g_oaMolecules[m_iShowMol])->m_laSingleMolIndex.GetSize(),n->m_iNbCountMin+1,n->m_iNbCountMin+1)-1; // m_faMinMaxDist.Add(0); // m_faMinMaxDist.Add(9E20f); } } else { m_faMinMaxDist.Add(0); m_faMinMaxDist.Add(1.0e30); n->m_iNbCountMin = -2; n->m_iNbCountMax = -2; } mprintf(WHITE,"\n<<< End of Distance Condition <<<\n\n"); BTOUT; } void CRDF::ParseConditionGrid(int rm, CNbSearch *n, int gridmode) { BTIN; // char buf[1024]; CxString buf; int ti; CAtomGroup *ag; try { m_pRDF = new CDF(); } catch(...) { m_pRDF = NULL; } if (m_pRDF == NULL) NewException((double)sizeof(CDF),__FILE__,__LINE__,__PRETTY_FUNCTION__); m_iShowAtomGes = 0; m_iRefAtomGes = 0; m_iCombinations = 0; m_iRefOrSec[0] = 0; m_iRefOrSec[1] = 1; mprintf(WHITE,"\n>>> Distance Condition >>>\n"); _rdfnewset: mprintf("\n"); try { ag = new CAtomGroup(); } catch(...) { ag = NULL; } if (ag == NULL) NewException((double)sizeof(CAtomGroup),__FILE__,__LINE__,__PRETTY_FUNCTION__); _rdfatom1: if (((CMolecule*)g_oaMolecules[rm])->m_iAtomGesNoVirt == 1) { mprintf(" %s is only one atom, there is no choice.\n",((CMolecule*)g_oaMolecules[rm])->m_sName); ag->Reset(); ag->m_pMolecule = (CMolecule*)g_oaMolecules[rm]; ag->AddAtom(0,0,false); ag->SortAtoms(); ag->BuildName(); } else { mprintf(" Which atom(s) to take from RM %s (e.g. \"C1,C3-5,H\", \"*\"=all)? [#2] ",((CMolecule*)g_oaMolecules[rm])->m_sName); inpprintf("! Which atom(s) to take from RM %s (e.g. \"C1,C3-5,H\", \"*\"=all)? [#2]\n",((CMolecule*)g_oaMolecules[rm])->m_sName); myget(&buf); if (strlen(buf) == 0) { if (!ag->ParseAtoms((CMolecule*)g_oaMolecules[rm],"#2")) { eprintf("CRDF::ParseConditionGrid(): Internal error.\n"); goto _rdfatom1; } } else if (!ag->ParseAtoms((CMolecule*)g_oaMolecules[rm],buf)) goto _rdfatom1; } m_oaVectors.Add(ag); m_iRefAtomGes += ag->m_iAtomGes; ti = ag->m_iAtomGes; try { ag = new CAtomGroup(); } catch(...) { ag = NULL; } if (ag == NULL) NewException((double)sizeof(CAtomGroup),__FILE__,__LINE__,__PRETTY_FUNCTION__); _rdfatom2: if (((CMolecule*)g_oaMolecules[m_iShowMol])->m_iAtomGesNoVirt == 1) { mprintf(" %s is only one atom, there is no choice.\n",((CMolecule*)g_oaMolecules[m_iShowMol])->m_sName); ag->Reset(); ag->m_pMolecule = (CMolecule*)g_oaMolecules[m_iShowMol]; ag->AddAtom(0,0,false); ag->SortAtoms(); ag->BuildName(); } else { mprintf(" Which atom(s) to take from OM %s (e.g. \"C1,C3-5,H\", \"*\"=all)? [#2] ",((CMolecule*)g_oaMolecules[m_iShowMol])->m_sName); inpprintf("! Which atom(s) to take from OM %s (e.g. \"C1,C3-5,H\", \"*\"=all)? [#2]\n",((CMolecule*)g_oaMolecules[m_iShowMol])->m_sName); myget(&buf); try { ag = new CAtomGroup(); } catch(...) { ag = NULL; } if (ag == NULL) NewException((double)sizeof(CAtomGroup),__FILE__,__LINE__,__PRETTY_FUNCTION__); if (strlen(buf) == 0) { if (!ag->ParseAtoms((CMolecule*)g_oaMolecules[m_iShowMol],"#2")) { eprintf("CRDF::ParseConditionGrid(): Internal error.\n"); goto _rdfatom2; } } else if (!ag->ParseAtoms((CMolecule*)g_oaMolecules[m_iShowMol],buf)) goto _rdfatom2; } m_oaVectors.Add(ag); m_iShowAtomGes += ag->m_iAtomGes; m_iCombinations += ti * ag->m_iAtomGes; if (AskYesNo(" Enter another set of atoms (y/n)? [no] ",false)) goto _rdfnewset; if (gridmode == 6) { if (AskUnsignedInteger("\n Enter min./max. distance (0) or min./max. nearest neighbor count (1)? [0] ",0)==0) { m_faMinMaxDist.Add(AskFloat(" Enter the minimal distance in pm: [0] ",0.0)); m_faMinMaxDist.Add(AskFloat(" Enter the maximal distance in pm: [400] ",400.0)); n->m_iNbCountMin = -1; n->m_iNbCountMax = -1; } else { n->m_iNbCountMin = AskRangeInteger(" Use next neighbors from the n-th on? [1] ",0,((CMolecule*)g_oaMolecules[m_iShowMol])->m_laSingleMolIndex.GetSize(),1)-1; n->m_iNbCountMax = AskRangeInteger(" Use next neighbors up to the n-th? [%d] ",n->m_iNbCountMin+1,((CMolecule*)g_oaMolecules[m_iShowMol])->m_laSingleMolIndex.GetSize(),n->m_iNbCountMin+1,n->m_iNbCountMin+1)-1; // m_faMinMaxDist.Add(0); // m_faMinMaxDist.Add(9E20f); } } else if ((gridmode == 4) || (gridmode == 5)) { n->m_iNbCountMin = 0; n->m_iNbCountMax = 0; // m_faMinMaxDist.Add(0); // m_faMinMaxDist.Add(9E20f); } else if (gridmode == 2) { m_faMinMaxDist.Add(AskFloat(" Enter the minimal distance in pm: [0] ",0.0)); m_faMinMaxDist.Add(AskFloat(" Enter the maximal distance in pm: [400] ",400.0)); n->m_iNbCountMin = -1; n->m_iNbCountMax = -1; } else { m_faMinMaxDist.Add(0.0); m_faMinMaxDist.Add(400.0); n->m_iNbCountMin = -1; n->m_iNbCountMax = -1; } mprintf(WHITE,"\n<<< End of Distance Condition <<<\n\n"); BTOUT; } void CRDF::ParseCondition_OnlyValues(CNbSearch *n) { BTIN; int z; mprintf(" Distance condition between "); for (z=0;zm_sName,((CAtomGroup*)m_oaVectors[z*2+1])->m_sName); if (z < (m_oaVectors.GetSize()/2)-1) mprintf(", "); } mprintf("\n"); if (n->m_iNbCountMin == -1) { for (z=0;zm_iNbCountMin = AskRangeInteger(" Use next neighbors from the n-th on? [1] ",0,((CMolecule*)g_oaMolecules[m_iShowMol])->m_laSingleMolIndex.GetSize(),1)-1; n->m_iNbCountMax = AskRangeInteger(" Use next neighbors up to the n-th? [%d] ",n->m_iNbCountMin+1,((CMolecule*)g_oaMolecules[m_iShowMol])->m_laSingleMolIndex.GetSize(),n->m_iNbCountMin+1,n->m_iNbCountMin+1)-1; } BTOUT; } void CVHDF::Parse() { BTIN; // char buf[1024]; CxString buf; int ti; CAtomGroup *ag; try { m_pVHDF = new C2DF(); } catch(...) { m_pVHDF = NULL; } if (m_pVHDF == NULL) NewException((double)sizeof(C2DF),__FILE__,__LINE__,__PRETTY_FUNCTION__); m_iShowAtomGes = 0; m_iRefAtomGes = 0; m_iCombinations = 0; mprintf(WHITE,"\n>>> Van Hove Correlation Function >>>\n\n"); if (m_iShowMol != -1) { m_iRefOrSec[0] = AskRangeInteger(" Take (fixed) reference atom(s) from RM %s (0) or from OM %s (1)? [0] ",0,1,0,((CMolecule*)g_oaMolecules[g_iFixMol])->m_sName,((CMolecule*)g_oaMolecules[m_iShowMol])->m_sName); m_iRefOrSec[1] = AskRangeInteger(" Take (moving) observed atom(s) from RM %s (0) or from OM %s (1)? [1] ",0,1,1,((CMolecule*)g_oaMolecules[g_iFixMol])->m_sName,((CMolecule*)g_oaMolecules[m_iShowMol])->m_sName); } else // Kein OM: Nimm alles aus RM { m_iRefOrSec[0] = 0; m_iRefOrSec[1] = 0; } _rdfnewset: mprintf("\n"); try { ag = new CAtomGroup(); } catch(...) { ag = NULL; } if (ag == NULL) NewException((double)sizeof(CAtomGroup),__FILE__,__LINE__,__PRETTY_FUNCTION__); _rdfatom1: if (m_iRefOrSec[0]) { mprintf(" Which (fixed) reference atom(s) to take from OM %s (e.g. \"C1,C3-5,H\", \"*\"=all)? [#2] ",((CMolecule*)g_oaMolecules[m_iShowMol])->m_sName); inpprintf("! Which (fixed) reference atom(s) to take from OM %s (e.g. \"C1,C3-5,H\", \"*\"=all)? [#2]\n",((CMolecule*)g_oaMolecules[m_iShowMol])->m_sName); } else { mprintf(" Which (fixed) reference atom(s) to take from RM %s (e.g. \"C1,C3-5,H\", \"*\"=all)? [#2] ",((CMolecule*)g_oaMolecules[g_iFixMol])->m_sName); inpprintf("! Which (fixed) reference atom(s) to take from RM %s (e.g. \"C1,C3-5,H\", \"*\"=all)? [#2]\n",((CMolecule*)g_oaMolecules[g_iFixMol])->m_sName); } myget(&buf); if (strlen(buf) == 0) { if (!ag->ParseAtoms((CMolecule*)g_oaMolecules[(m_iRefOrSec[0])?m_iShowMol:g_iFixMol],"#2")) goto _rdfatom1; } else if (!ag->ParseAtoms((CMolecule*)g_oaMolecules[(m_iRefOrSec[0])?m_iShowMol:g_iFixMol],buf)) goto _rdfatom1; m_oaVectors.Add(ag); m_iRefAtomGes += ag->m_iAtomGes; ti = ag->m_iAtomGes; try { ag = new CAtomGroup(); } catch(...) { ag = NULL; } if (ag == NULL) NewException((double)sizeof(CAtomGroup),__FILE__,__LINE__,__PRETTY_FUNCTION__); _rdfatom2: if (m_iRefOrSec[1]) { mprintf(" Which (moving) observed atom(s) to take from OM %s (e.g. \"C1,C3-5,H\", \"*\"=all)? [#2] ",((CMolecule*)g_oaMolecules[m_iShowMol])->m_sName); inpprintf("! Which (moving) observed atom(s) to take from OM %s (e.g. \"C1,C3-5,H\", \"*\"=all)? [#2]\n",((CMolecule*)g_oaMolecules[m_iShowMol])->m_sName); } else { mprintf(" Which (moving) observed atom(s) to take from RM %s (e.g. \"C1,C3-5,H\", \"*\"=all)? [#2] ",((CMolecule*)g_oaMolecules[g_iFixMol])->m_sName); inpprintf("! Which (moving) observed atom(s) to take from RM %s (e.g. \"C1,C3-5,H\", \"*\"=all)? [#2]\n",((CMolecule*)g_oaMolecules[g_iFixMol])->m_sName); } myget(&buf); try { ag = new CAtomGroup(); } catch(...) { ag = NULL; } if (ag == NULL) NewException((double)sizeof(CAtomGroup),__FILE__,__LINE__,__PRETTY_FUNCTION__); if (strlen(buf) == 0) { if (!ag->ParseAtoms((CMolecule*)g_oaMolecules[(m_iRefOrSec[1])?m_iShowMol:g_iFixMol],"#2")) goto _rdfatom2; } else if (!ag->ParseAtoms((CMolecule*)g_oaMolecules[(m_iRefOrSec[1])?m_iShowMol:g_iFixMol],buf)) goto _rdfatom2; m_oaVectors.Add(ag); m_iShowAtomGes += ag->m_iAtomGes; m_iCombinations += ti * ag->m_iAtomGes; if (g_bAdvanced2) if (AskYesNo(" Enter another set of atoms (y/n)? [no] ",false)) goto _rdfnewset; m_fMinDist = 0; //AskFloat(" Enter the minimal radius of this VHCF in pm: [0] ",0.0f); m_fMaxDist = AskFloat(" Enter the radius of this VHCF in pm: [%d.0] ",(double)HalfBox(),HalfBox()); m_iResolution = AskUnsignedInteger(" Enter the radial resolution of this VHCF: [100] ",100); m_bRadialCorrect = AskYesNo(" Correct radial distribution for this VHCF (y/n)? [%s] ",!m_bSelf,m_bSelf?"no":"yes"); _depth: if (g_iTrajSteps != -1) m_iDepth = AskUnsignedInteger(" Enter the temporal resolution (time depth) of this VHCF (in time steps): [%d] ",int(g_iTrajSteps*0.75),int(g_iTrajSteps*0.75)); else m_iDepth = AskUnsignedInteger(" Enter the temporal resolution (time depth) of this VHCF (in time steps): [0] ",0); mprintf("\n This will occupy %s of RAM.\n",FormatBytes((double)m_iDepth*g_iGesVirtAtomCount*3.0*sizeof(double))); if (m_iDepth*g_iGesVirtAtomCount*3.0*sizeof(double)/1024.0/1024.0 >= 1000.0) if (!AskYesNo(" Make sure that enough free RAM is available. Continue (y/n)? [yes] ",true)) goto _depth; mprintf("\n"); _resagain: m_iStride = AskUnsignedInteger(" Take each n-th time step for the temporal axis? [%d] ",MAX(1,m_iDepth/100),MAX(1,m_iDepth/100)); mprintf("\n This results in a plot resolution of %d on the temporal axis.\n",m_iDepth/m_iStride); if (m_iDepth/m_iStride > 200) { mprintf("\n"); if (!AskYesNo(" The resolution seems quite high, the plot will take much time to render. Contiune (y/n)? [yes] ",true)) goto _resagain; } if (g_bAdvanced2) { mprintf("\n"); m_bSwapAxes = AskYesNo(" Put distance on X axis and time on Y axis (y) or swap axes (n)? [yes] ",true); m_iGraceBunchTime = AskUnsignedInteger(" How many time graphs do you want do draw in the distance grace stack (0=disable)? [10] ",10); m_iGraceBunchDist = AskUnsignedInteger(" How many distance graphs do you want do draw in the time grace stack (0=disable)? [10] ",10); } else { m_bSwapAxes = true; m_iGraceBunchTime = 0; m_iGraceBunchDist = 0; } BuildName(); mprintf(WHITE,"\n<<< End of Van Hove Correlation Function <<<\n\n"); BTOUT; } void CADF::Parse() { BTIN; // char buf[1024]; CxString buf; int z, z2, ti; CAtomGroup *ag; double tf; bool dip; try { m_pADF = new CDF(); } catch(...) { m_pADF = NULL; } if (m_pADF == NULL) NewException((double)sizeof(CDF),__FILE__,__LINE__,__PRETTY_FUNCTION__); mprintf(WHITE,"\n>>> Angular Distribution Function >>>\n\n"); dip = false; for (z=0;z<2;z++) { m_iVecType[z] = AskRangeInteger(" Should the %d. vector depict position (1), dipole (2), velocity (3) or force (4)? [1] ",1,4,1,z+1) - 1; if (m_iVecType[z] == 1) { g_bDipole = true; ParseDipole(); } if (!dip) { dip = true; mprintf(YELLOW,"\n Please note: "); mprintf("The last virtual atom (e.g., #3) of each molecule is defined as the tip of the\n"); mprintf(" molecular dipole vector starting from molecular center of mass (i.e., #2). So you can involve the\n"); mprintf(" dipole vector in any analysis. 1 Debye corresponds to 100 pm length of the vector.\n\n"); } } z2 = 0; m_iCombinations = 0; do { ti = 1; if (z2 != 0) mprintf("\n %d. set of vectors\n\n",z2+1); for (z=0;z<2;z++) { if (m_iVecType[z] == 0) // Position { /* if (z2 == 0) if ((z == 1) && (m_iVecType[0] == 0) && (m_iVecType[1] == 0)) m_bSameFoot = AskYesNo(" Should the base points of the 1st and 2nd vectors always be equal (y/n)? [no] ",false); else m_bSameFoot = false;*/ if (z2 == 0) { mprintf("\n"); m_bOrtho[z] = (AskRangeInteger(" Should the %d. vector connect 2 points (0) or stand perpendicular to 3 points (1)? [0] ",0,1,0,z+1) != 0); mprintf("\n"); } if (m_bOrtho[z]) { _ax1: if (z2 == 0) { if (m_iShowMol != -1) m_iRefOrSec[z][0] = AskRangeInteger(" Take atom(s) at the base point from RM %s (0) or from OM %s (1)? [%d] ",0,1,z,((CMolecule*)g_oaMolecules[g_iFixMol])->m_sName,((CMolecule*)g_oaMolecules[m_iShowMol])->m_sName,z); else m_iRefOrSec[z][0] = 0; } try { ag = new CAtomGroup(); } catch(...) { ag = NULL; } if (ag == NULL) NewException((double)sizeof(CAtomGroup),__FILE__,__LINE__,__PRETTY_FUNCTION__); if (((CMolecule*)g_oaMolecules[(m_iRefOrSec[z][0])?m_iShowMol:g_iFixMol])->m_iAtomGesNoVirt == 1) { mprintf(" %s is only one atom, there is no choice.\n",((CMolecule*)g_oaMolecules[(m_iRefOrSec[z][0])?m_iShowMol:g_iFixMol])->m_sName); ag->Reset(); ag->m_pMolecule = (CMolecule*)g_oaMolecules[(m_iRefOrSec[z][0])?m_iShowMol:g_iFixMol]; ag->AddAtom(0,0,false); ag->SortAtoms(); ag->BuildName(); } else { mprintf(" Please enter the atom(s) at the base point (e.g. C7): "); inpprintf("! Please enter the atom(s) at the base point (e.g. C7):\n"); myget(&buf); if (!ag->ParseAtoms((!m_iRefOrSec[z][0])?(CMolecule*)g_oaMolecules[g_iFixMol]:(CMolecule*)g_oaMolecules[m_iShowMol],buf)) { eprintf("Invalid input.\n"); inpprintf("! Invalid input.\n"); delete ag; goto _ax1; } } m_oaVectors.Add(ag); ti *= ag->m_iAtomGes; _ax2: if (z2 == 0) { if (m_iShowMol != -1) m_iRefOrSec[z][1] = AskRangeInteger(" Take 2nd atom(s) of normal plane from RM %s (0) or from OM %s (1)? [%d] ",0,1,z,((CMolecule*)g_oaMolecules[g_iFixMol])->m_sName,((CMolecule*)g_oaMolecules[m_iShowMol])->m_sName,z); else m_iRefOrSec[z][1] = 0; } try { ag = new CAtomGroup(); } catch(...) { ag = NULL; } if (ag == NULL) NewException((double)sizeof(CAtomGroup),__FILE__,__LINE__,__PRETTY_FUNCTION__); if (((CMolecule*)g_oaMolecules[(m_iRefOrSec[z][1])?m_iShowMol:g_iFixMol])->m_iAtomGesNoVirt == 1) { mprintf(" %s is only one atom, there is no choice.\n",((CMolecule*)g_oaMolecules[(m_iRefOrSec[z][1])?m_iShowMol:g_iFixMol])->m_sName); ag->Reset(); ag->m_pMolecule = (CMolecule*)g_oaMolecules[(m_iRefOrSec[z][1])?m_iShowMol:g_iFixMol]; ag->AddAtom(0,0,false); ag->SortAtoms(); ag->BuildName(); } else { mprintf(" Please enter the 2nd atom(s) of the normal plane (e.g. C7): "); inpprintf("! Please enter the 2nd atom(s) of the normal plane (e.g. C7):\n"); myget(&buf); if (!ag->ParseAtoms((!m_iRefOrSec[z][1])?(CMolecule*)g_oaMolecules[g_iFixMol]:(CMolecule*)g_oaMolecules[m_iShowMol],buf)) { eprintf("Invalid input.\n"); inpprintf("! Invalid input.\n"); delete ag; goto _ax2; } } m_oaVectors.Add(ag); ti *= ag->m_iAtomGes; _ax3: if (z2 == 0) { if (m_iShowMol != -1) m_iRefOrSec[z][2] = AskRangeInteger(" Take 3rd atom(s) of normal plane from RM %s (0) or from OM %s (1)? [%d] ",0,1,z,((CMolecule*)g_oaMolecules[g_iFixMol])->m_sName,((CMolecule*)g_oaMolecules[m_iShowMol])->m_sName,z); else m_iRefOrSec[z][2] = 0; } try { ag = new CAtomGroup(); } catch(...) { ag = NULL; } if (ag == NULL) NewException((double)sizeof(CAtomGroup),__FILE__,__LINE__,__PRETTY_FUNCTION__); if (((CMolecule*)g_oaMolecules[(m_iRefOrSec[z][2])?m_iShowMol:g_iFixMol])->m_iAtomGesNoVirt == 1) { mprintf(" %s is only one atom, there is no choice.\n",((CMolecule*)g_oaMolecules[(m_iRefOrSec[z][2])?m_iShowMol:g_iFixMol])->m_sName); ag->Reset(); ag->m_pMolecule = (CMolecule*)g_oaMolecules[(m_iRefOrSec[z][2])?m_iShowMol:g_iFixMol]; ag->AddAtom(0,0,false); ag->SortAtoms(); ag->BuildName(); } else { mprintf(" Please enter the 3rd atom(s) of the normal plane (e.g. C7): "); inpprintf("! Please enter the 3rd atom(s) of the normal plane (e.g. C7):\n"); myget(&buf); if (!ag->ParseAtoms((!m_iRefOrSec[z][2])?(CMolecule*)g_oaMolecules[g_iFixMol]:(CMolecule*)g_oaMolecules[m_iShowMol],buf)) { eprintf("Invalid input.\n"); inpprintf("! Invalid input.\n"); delete ag; goto _ax3; } } m_oaVectors.Add(ag); ti *= ag->m_iAtomGes; } else // IF ORTHO { _ax4: if (z2 == 0) { if (m_iShowMol != -1) m_iRefOrSec[z][0] = AskRangeInteger(" Take atom(s) at the base point from RM %s (0) or from OM %s (1)? [%d] ",0,1,z,((CMolecule*)g_oaMolecules[g_iFixMol])->m_sName,((CMolecule*)g_oaMolecules[m_iShowMol])->m_sName,z); else m_iRefOrSec[z][0] = 0; } try { ag = new CAtomGroup(); } catch(...) { ag = NULL; } if (ag == NULL) NewException((double)sizeof(CAtomGroup),__FILE__,__LINE__,__PRETTY_FUNCTION__); if (((CMolecule*)g_oaMolecules[(m_iRefOrSec[z][0])?m_iShowMol:g_iFixMol])->m_iAtomGesNoVirt == 1) { mprintf(" %s is only one atom, there is no choice.\n",((CMolecule*)g_oaMolecules[(m_iRefOrSec[z][0])?m_iShowMol:g_iFixMol])->m_sName); ag->Reset(); ag->m_pMolecule = (CMolecule*)g_oaMolecules[(m_iRefOrSec[z][0])?m_iShowMol:g_iFixMol]; ag->AddAtom(0,0,false); ag->SortAtoms(); ag->BuildName(); } else { mprintf(" Please enter the atom(s) at the base point (e.g. C7): "); inpprintf("! Please enter the atom(s) at the base point (e.g. C7):\n"); myget(&buf); if (!ag->ParseAtoms((!m_iRefOrSec[z][0])?(CMolecule*)g_oaMolecules[g_iFixMol]:(CMolecule*)g_oaMolecules[m_iShowMol],buf)) { eprintf("Invalid input.\n"); inpprintf("! Invalid input.\n"); delete ag; goto _ax4; } } // mprintf("## ParseAtoms: \"%s\" --> \"%s\".\n",(const char*)buf,ag->m_sName); m_oaVectors.Add(ag); ti *= ag->m_iAtomGes; _ax5: if (z2 == 0) { if (m_iShowMol != -1) m_iRefOrSec[z][1] = AskRangeInteger(" Take atom(s) at the tip point from RM %s (0) or from OM %s (1)? [%d] ",0,1,z,((CMolecule*)g_oaMolecules[g_iFixMol])->m_sName,((CMolecule*)g_oaMolecules[m_iShowMol])->m_sName,z); else m_iRefOrSec[z][1] = 0; } try { ag = new CAtomGroup(); } catch(...) { ag = NULL; } if (ag == NULL) NewException((double)sizeof(CAtomGroup),__FILE__,__LINE__,__PRETTY_FUNCTION__); if (((CMolecule*)g_oaMolecules[(m_iRefOrSec[z][1])?m_iShowMol:g_iFixMol])->m_iAtomGesNoVirt == 1) { mprintf(" %s is only one atom, there is no choice.\n",((CMolecule*)g_oaMolecules[(m_iRefOrSec[z][1])?m_iShowMol:g_iFixMol])->m_sName); ag->Reset(); ag->m_pMolecule = (CMolecule*)g_oaMolecules[(m_iRefOrSec[z][1])?m_iShowMol:g_iFixMol]; ag->AddAtom(0,0,false); ag->SortAtoms(); ag->BuildName(); } else { mprintf(" Please enter the atom(s) at the tip point (e.g. C7): "); inpprintf("! Please enter the atom(s) at the tip point (e.g. C7):\n"); myget(&buf); if (!ag->ParseAtoms((!m_iRefOrSec[z][1])?(CMolecule*)g_oaMolecules[g_iFixMol]:(CMolecule*)g_oaMolecules[m_iShowMol],buf)) { eprintf("Invalid input.\n"); inpprintf("! Invalid input.\n"); delete ag; goto _ax5; } } // mprintf("## ParseAtoms: \"%s\" --> \"%s\".\n",(const char*)buf,ag->m_sName); m_oaVectors.Add(ag); ti *= ag->m_iAtomGes; m_oaVectors.Add(NULL); } // END IF NOT ORTHO } else if (m_iVecType[z] == 1) // Dipol { mprintf("\n"); if (m_iShowMol != -1) m_iRefOrSec[z][0] = AskRangeInteger(" Take dipole vector from RM %s (0) or from OM %s (1)? [%d] ",0,1,z,((CMolecule*)g_oaMolecules[g_iFixMol])->m_sName,((CMolecule*)g_oaMolecules[m_iShowMol])->m_sName,z); else m_iRefOrSec[z][0] = 0; m_bOrtho[z] = false; try { ag = new CAtomGroup(); } catch(...) { ag = NULL; } if (ag == NULL) NewException((double)sizeof(CAtomGroup),__FILE__,__LINE__,__PRETTY_FUNCTION__); if (!ag->ParseAtoms((!m_iRefOrSec[z][0])?(CMolecule*)g_oaMolecules[g_iFixMol]:(CMolecule*)g_oaMolecules[m_iShowMol],"#2")) { eprintf("CADF::Parse(): Internal error. \"#2\" not found.\n"); abort(); } m_oaVectors.Add(ag); ti *= ag->m_iAtomGes; try { ag = new CAtomGroup(); } catch(...) { ag = NULL; } if (ag == NULL) NewException((double)sizeof(CAtomGroup),__FILE__,__LINE__,__PRETTY_FUNCTION__); buf.Format("#%d",((CMolecule*)((!m_iRefOrSec[z][0])?g_oaMolecules[g_iFixMol]:g_oaMolecules[m_iShowMol]))->m_laVirtualAtoms.GetSize()); if (!ag->ParseAtoms((!m_iRefOrSec[z][0])?(CMolecule*)g_oaMolecules[g_iFixMol]:(CMolecule*)g_oaMolecules[m_iShowMol],buf)) { eprintf("CADF::Parse(): Internal error. \"%s\" not found.\n",(const char*)buf); abort(); } m_oaVectors.Add(ag); ti *= ag->m_iAtomGes; m_oaVectors.Add(NULL); } else if (m_iVecType[z] == 2) // Geschwindigkeit { _ax6: if (m_iShowMol != -1) m_iRefOrSec[z][0] = AskRangeInteger(" Take velocity vector from RM %s (0) or from OM %s (1)? [%d] ",0,1,z,((CMolecule*)g_oaMolecules[g_iFixMol])->m_sName,((CMolecule*)g_oaMolecules[m_iShowMol])->m_sName,z); else m_iRefOrSec[z][0] = 0; mprintf(" Velocity vector of which atoms to use (e.g. C7)? [#2] "); inpprintf("! Velocity vector of which atoms to use (e.g. C7)? [#2]\n"); myget(&buf); try { ag = new CAtomGroup(); } catch(...) { ag = NULL; } if (ag == NULL) NewException((double)sizeof(CAtomGroup),__FILE__,__LINE__,__PRETTY_FUNCTION__); if (strlen(buf)==0) { if (!ag->ParseAtoms((!m_iRefOrSec[z][0])?(CMolecule*)g_oaMolecules[g_iFixMol]:(CMolecule*)g_oaMolecules[m_iShowMol],"#2")) { eprintf("CADF::Parse(): Internal error.\n"); inpprintf("! CADF::Parse(): Internal error.\n"); abort(); } } else if (!ag->ParseAtoms((!m_iRefOrSec[z][0])?(CMolecule*)g_oaMolecules[g_iFixMol]:(CMolecule*)g_oaMolecules[m_iShowMol],buf)) { eprintf("Invalid input.\n"); inpprintf("! Invalid input.\n"); delete ag; goto _ax6; } m_oaVectors.Add(ag); ti *= ag->m_iAtomGes; } else if (m_iVecType[z] == 3) // Kraft { _ax7: if (m_iShowMol != -1) m_iRefOrSec[z][0] = AskRangeInteger(" Take force vector from RM %s (0) or from OM %s (1)? [%d] ",0,1,z,((CMolecule*)g_oaMolecules[g_iFixMol])->m_sName,((CMolecule*)g_oaMolecules[m_iShowMol])->m_sName,z); else m_iRefOrSec[z][0] = 0; mprintf(" Force vector of which atoms to use (e.g. C7)? [#2] "); inpprintf("! Force vector of which atoms to use (e.g. C7)? [#2]\n"); myget(&buf); try { ag = new CAtomGroup(); } catch(...) { ag = NULL; } if (ag == NULL) NewException((double)sizeof(CAtomGroup),__FILE__,__LINE__,__PRETTY_FUNCTION__); if (strlen(buf)==0) { if (!ag->ParseAtoms((!m_iRefOrSec[z][0])?(CMolecule*)g_oaMolecules[g_iFixMol]:(CMolecule*)g_oaMolecules[m_iShowMol],"#2")) { eprintf("CADF::Parse(): Internal Error.\n"); inpprintf("! CADF::Parse(): Internal Error.\n"); abort(); } } else if (!ag->ParseAtoms((!m_iRefOrSec[z][0])?(CMolecule*)g_oaMolecules[g_iFixMol]:(CMolecule*)g_oaMolecules[m_iShowMol],buf)) { eprintf("Invalid input.\n"); inpprintf("! Invalid input.\n"); delete ag; goto _ax7; } m_oaVectors.Add(ag); ti *= ag->m_iAtomGes; } } // END FOR 0..1 z2++; m_iCombinations += ti; // mprintf("RefOrSec: %d %d %d %d.\n",m_iRefOrSec[0][0],m_iRefOrSec[0][1],m_iRefOrSec[1][0],m_iRefOrSec[1][1]); } while (g_bAdvanced2?AskYesNo("\n Add another set of vectors to this (!) ADF (y/n)? [no] ",false):false); ParseDeriv(); switch(m_iDeriv) { case 0: mprintf("\n"); _anglowag: m_fMinAngle = AskFloat(" Enter minimal angle between the vectors: [0 deg] ",0.0); if (m_fMinAngle < 0) { eprintf(" Angles < 0 degree are not defined.\n"); goto _anglowag; } m_fMaxAngle = AskFloat(" Enter maximal angle between the vectors: [180 deg] ",180.0); break; case 1: if (m_bDerivAbs) m_fMinAngle = AskFloat(" Enter the minimal value of this d1-ADF in deg/ps: [0] ",0.0); else m_fMinAngle = AskFloat(" Enter the minimal value of this d1-ADF in deg/ps: [-10.0] ",-10.0); m_fMaxAngle = AskFloat(" Enter the maximal value of this d1-ADF in deg/ps: [10.0] ",10.0); break; case 2: if (m_bDerivAbs) m_fMinAngle = AskFloat(" Enter the minimal value of this d2-ADF in deg/ps^2: [0] ",0.0); else m_fMinAngle = AskFloat(" Enter the minimal value of this d2-ADF in deg/ps^2: [-10.0] ",-10.0); m_fMaxAngle = AskFloat(" Enter the maximal value of this d2-ADF in deg/ps^2: [10.0] ",10.0); break; } /* if (m_fMaxAngle <= 90.0f) m_bFoldAngle = AskYesNo(" Should angles > 90 deg be \"mirrored\" (180 deg = 0 deg) (y/n)? [yes] ",true); else*/ m_bFoldAngle = false; m_bCosine = (AskRangeInteger(" Plot ADF against angle (0) or against cosine (1)? [0] ",0,1,0)!=0); if (m_bCosine) { m_fMinAngle = (double)cos(m_fMinAngle/180.0*Pi); m_fMaxAngle = (double)cos(m_fMaxAngle/180.0*Pi); if (m_fMinAngle > m_fMaxAngle) { tf = m_fMinAngle; m_fMinAngle = m_fMaxAngle; m_fMaxAngle = tf; } mprintf(" The data range is %.2f to %.2f.\n",m_fMinAngle,m_fMaxAngle); } if (!m_bCosine) m_bMirror = AskYesNo(" Force this ADF to be mirror-symmetric to the 90 deg line (y/n)? [no] ",false); else m_bMirror = false; m_iResolution = AskUnsignedInteger(" Please enter the resolution (bin count) for this ADF: [100] ",100); if (g_bAdvanced2) m_iHistogramRes = AskUnsignedInteger(" Please enter histogram resolution (0=no histogram): [0] ",0); else m_iHistogramRes = 0; if (m_iShowMol != -1) m_bStat = AskYesNo(" Apply cone correction (y/n)? [%c] ",!m_bCosine,(!m_bCosine)?'y':'n'); else m_bStat = 0; /* mprintf("\n Save temporal development of this ADF (0=nein, 1=ja)? [0] "); myget(buf); m_bSaveAngle = (atoi(buf)!=0);*/ BuildName(); mprintf(WHITE,"\n<<< End of Angular Distribution Function <<<\n\n"); BTOUT; } void CDDF::Parse() { BTIN; // char buf[1024]; CxString buf; CAtomGroup *ag; int z0, z, z2, i; double tf; try { m_pDDF = new CDF(); } catch(...) { m_pDDF = NULL; } if (m_pDDF == NULL) NewException((double)sizeof(CDF),__FILE__,__LINE__,__PRETTY_FUNCTION__); mprintf(WHITE,"\n>>> Dihedral Distribution Function >>>\n\n"); m_bClassical = AskYesNo(" Use \"simple\" (y) (4 atoms) or \"generalized\" (n) (3 vectors) Dihedrals? [yes] ",true); m_iCombinations = 1; if (m_bClassical) { m_bOrtho[0] = false; m_bOrtho[1] = false; m_bOrtho[2] = false; z0 = m_oaVectors.GetSize(); for (z=0;z<3;z++) { try { ag = new CAtomGroup(); } catch(...) { ag = NULL; } if (ag == NULL) NewException((double)sizeof(CAtomGroup),__FILE__,__LINE__,__PRETTY_FUNCTION__); m_oaVectors.Add(ag); try { ag = new CAtomGroup(); } catch(...) { ag = NULL; } if (ag == NULL) NewException((double)sizeof(CAtomGroup),__FILE__,__LINE__,__PRETTY_FUNCTION__); m_oaVectors.Add(ag); m_oaVectors.Add(NULL); } for (z=0;z<4;z++) { _bx: if (m_iShowMol != -1) i = AskRangeInteger(" Take the %d. atom from RM %s (0) or from OM %s (1)? [0] ",0,1,0,z+1,((CMolecule*)g_oaMolecules[g_iFixMol])->m_sName,((CMolecule*)g_oaMolecules[m_iShowMol])->m_sName); else i = 0; switch(z) { case 0: m_iRefOrSec[0][1] = i; break; case 1: m_iRefOrSec[0][0] = i; m_iRefOrSec[2][0] = i; break; case 2: m_iRefOrSec[2][1] = i; m_iRefOrSec[1][0] = i; break; case 3: m_iRefOrSec[1][1] = i; break; } mprintf(" Enter the %d. atom(s) (e.g. C7): ",z+1); inpprintf("! Enter the %d. atom(s) (e.g. C7):\n",z+1); myget(&buf); switch(z) { case 0: if (!((CAtomGroup*)m_oaVectors[z0+0*3+1])->ParseAtoms((!m_iRefOrSec[0][1])?(CMolecule*)g_oaMolecules[g_iFixMol]:(CMolecule*)g_oaMolecules[m_iShowMol],buf)) { eprintf("Invalid input.\n"); inpprintf("! Invalid input.\n"); goto _bx; } m_iCombinations *= ((CAtomGroup*)m_oaVectors[z0+0*3+1])->m_iAtomGes; break; case 1: if (!((CAtomGroup*)m_oaVectors[z0+0*3+0])->ParseAtoms((!m_iRefOrSec[0][0])?(CMolecule*)g_oaMolecules[g_iFixMol]:(CMolecule*)g_oaMolecules[m_iShowMol],buf)) { eprintf("Invalid input.\n"); inpprintf("! Invalid input.\n"); goto _bx; } if (!((CAtomGroup*)m_oaVectors[z0+2*3+0])->ParseAtoms((!m_iRefOrSec[2][0])?(CMolecule*)g_oaMolecules[g_iFixMol]:(CMolecule*)g_oaMolecules[m_iShowMol],buf)) { eprintf("Invalid input.\n"); inpprintf("! Invalid input.\n"); goto _bx; } m_iCombinations *= ((CAtomGroup*)m_oaVectors[z0+0*3+0])->m_iAtomGes; m_iCombinations *= ((CAtomGroup*)m_oaVectors[z0+0*3+0])->m_iAtomGes; break; case 2: if (!((CAtomGroup*)m_oaVectors[z0+2*3+1])->ParseAtoms((!m_iRefOrSec[2][1])?(CMolecule*)g_oaMolecules[g_iFixMol]:(CMolecule*)g_oaMolecules[m_iShowMol],buf)) { eprintf("Invalid input.\n"); inpprintf("! Invalid input.\n"); goto _bx; } if (!((CAtomGroup*)m_oaVectors[z0+1*3+0])->ParseAtoms((!m_iRefOrSec[1][0])?(CMolecule*)g_oaMolecules[g_iFixMol]:(CMolecule*)g_oaMolecules[m_iShowMol],buf)) { eprintf("Invalid input.\n"); inpprintf("! Invalid input.\n"); goto _bx; } m_iCombinations *= ((CAtomGroup*)m_oaVectors[z0+2*3+1])->m_iAtomGes; m_iCombinations *= ((CAtomGroup*)m_oaVectors[z0+2*3+1])->m_iAtomGes; break; case 3: if (!((CAtomGroup*)m_oaVectors[z0+1*3+1])->ParseAtoms((!m_iRefOrSec[1][1])?(CMolecule*)g_oaMolecules[g_iFixMol]:(CMolecule*)g_oaMolecules[m_iShowMol],buf)) { eprintf("Invalid input.\n"); inpprintf("! Invalid input.\n"); goto _bx; } m_iCombinations *= ((CAtomGroup*)m_oaVectors[z0+1*3+1])->m_iAtomGes; break; } } } else // NONCLASSIC { mprintf("\nYou now have to define 3 vectors:\n"); mprintf("The 1st and 2nd vector are projected onto the normal plane of the 3rd vector.\n"); mprintf("The angle between the two projected vectors in the plane is evaluated.\n"); for (z=0;z<3;z++) { mprintf(WHITE,"\n * Vector %d\n",z+1); m_bOrtho[z] = (AskRangeInteger(" Shall the %d. vector connect 2 points (0) or be orthogonal to a plane (1)? [0] ",0,1,0,z+1) != 0); if (m_bOrtho[z]) { for (z2=0;z2<3;z2++) { try { ag = new CAtomGroup(); } catch(...) { ag = NULL; } if (ag == NULL) NewException((double)sizeof(CAtomGroup),__FILE__,__LINE__,__PRETTY_FUNCTION__); _by: if (m_iShowMol != -1) m_iRefOrSec[z][z2] = AskRangeInteger(" Take the %d. atom(s) of the plane from RM %s (0) or from OM %s (1)? [0] ",0,1,0,z2+1,((CMolecule*)g_oaMolecules[g_iFixMol])->m_sName,((CMolecule*)g_oaMolecules[m_iShowMol])->m_sName); else m_iRefOrSec[z][z2] = 0; mprintf(" Please enter the %d. atom(s) (e.g. C7): ",z2+1); inpprintf("! Please enter the %d. atom(s) (e.g. C7):\n",z2+1); myget(&buf); if (!ag->ParseAtoms((!m_iRefOrSec[z][z2])?(CMolecule*)g_oaMolecules[g_iFixMol]:(CMolecule*)g_oaMolecules[m_iShowMol],buf)) { eprintf("Invalid input.\n"); inpprintf("! Invalid input.\n"); goto _by; } m_iCombinations *= ag->m_iAtomGes; m_oaVectors.Add(ag); } } else // Ortho { for (z2=0;z2<2;z2++) { try { ag = new CAtomGroup(); } catch(...) { ag = NULL; } if (ag == NULL) NewException((double)sizeof(CAtomGroup),__FILE__,__LINE__,__PRETTY_FUNCTION__); _bz: if (m_iShowMol != -1) m_iRefOrSec[z][z2] = AskRangeInteger(" Take the %d. atom(s) of the vector from RM %s (0) or from OM %s (1)? [0] ",0,1,0,z2+1,((CMolecule*)g_oaMolecules[g_iFixMol])->m_sName,((CMolecule*)g_oaMolecules[m_iShowMol])->m_sName); else m_iRefOrSec[z][z2] = 0; mprintf(" Please enter the %d. atom(s) (e.g. C7): ",z2+1); inpprintf("! Please enter the %d. atom(s) (e.g. C7):\n",z2+1); myget(&buf); if (!ag->ParseAtoms((!m_iRefOrSec[z][z2])?(CMolecule*)g_oaMolecules[g_iFixMol]:(CMolecule*)g_oaMolecules[m_iShowMol],buf)) { eprintf("Invalid input.\n"); inpprintf("! Invalid input.\n"); goto _bz; } m_iCombinations *= ag->m_iAtomGes; m_oaVectors.Add(ag); } m_oaVectors.Add(NULL); } // ENDIF ORTHO } // END FOR } // END IF NONCLASSIC /* mprintf("\n"); mprintf(" The \"classical\" dihedral angle is defined for a range of 0 ... 180 deg.\n\n"); m_bAbs = !AskYesNo(" Do you want to extend the range to -180 ... +180 deg (y/n)? [no] ",false);*/ mprintf("\n"); mprintf(" Per default, the dihedral angle is defined in a range of -180 ... 180 deg.\n\n"); m_bPositive = AskYesNo(" Use range of 0 ... 360 deg instead (e.g. -90 deg becomes 270 deg, ...) (y/n)? [no] ",false); m_bAbs = false; mprintf("\n"); ParseDeriv(); switch(m_iDeriv) { case 0: if (m_bPositive) { m_fMinAngle = AskFloat("\n Enter minimal dihedral angle to observe: [0 deg] ",0); m_fMaxAngle = AskFloat(" Enter maximal dihedral angle to observe: [360 deg] ",360.0); } else { m_fMinAngle = AskFloat("\n Enter minimal dihedral angle to observe: [-180 deg] ",-180.0); m_fMaxAngle = AskFloat(" Enter maximal dihedral angle to observe: [180 deg] ",180.0); } break; case 1: if (m_bDerivAbs) m_fMinAngle = AskFloat(" Enter the minimal value of this d1-DDF in deg/ps: [0] ",0.0); else m_fMinAngle = AskFloat(" Enter the minimal value of this d1-DDF in deg/ps: [-10.0] ",-10.0); m_fMaxAngle = AskFloat(" Enter the maximal value of this d1-DDF in deg/ps: [10.0] ",10.0); break; case 2: if (m_bDerivAbs) m_fMinAngle = AskFloat(" Enter the minimal value of this d2-DDF in deg/ps^2: [0] ",0.0); else m_fMinAngle = AskFloat(" Enter the minimal value of this d2-DDF in deg/ps^2: [-10.0] ",-10.0); m_fMaxAngle = AskFloat(" Enter the maximal value of this d2-DDF in deg/ps^2: [10.0] ",10.0); break; } if (m_iDeriv == 0) { m_bCosine = (AskRangeInteger(" Plot DDF against angle (0) or against cosine (1)? [0] ",0,1,0) != 0); if (m_bCosine) { if ((m_fMinAngle <= 0) && (m_fMaxAngle >= 0)) { if (fabs(m_fMinAngle) > fabs(m_fMaxAngle)) m_fMinAngle = cos(fabs(m_fMinAngle)); else m_fMinAngle = cos(fabs(m_fMaxAngle)); m_fMaxAngle = 1.0; } else { m_fMinAngle = cos(m_fMinAngle/180.0*Pi); m_fMaxAngle = cos(m_fMaxAngle/180.0*Pi); } if (m_fMinAngle > m_fMaxAngle) { tf = m_fMinAngle; m_fMinAngle = m_fMaxAngle; m_fMaxAngle = tf; } m_bAbs = false; m_bSymm = false; mprintf("\n The data range is %.2f to %.2f.\n\n",m_fMinAngle,m_fMaxAngle); } else { /* m_bAbs = AskYesNo(" Use absolute angle values (y) or signed values (n)? [yes] ",true); if (!m_bAbs) { m_fMinAngle = -m_fMaxAngle; mprintf("\n The data range is %.2f to %.2f.\n\n",m_fMinAngle,m_fMaxAngle); m_bSymm = AskYesNo(" Force this DDF to be symmetrical to the 0 degree line (y/n)? [no] ",false); } else m_bSymm = false;*/ // if (!m_bAbs) // { // m_fMinAngle = -m_fMaxAngle; mprintf("\n The data range is %.2f to %.2f.\n\n",m_fMinAngle,m_fMaxAngle); if (!m_bPositive) m_bSymm = AskYesNo(" Add also bin entries for inverse angles (force symmetry) (y/n)? [no] ",false); else m_bSymm = false; // } else m_bSymm = false; } } else { m_bCosine = false; m_bAbs = false; m_bSymm = false; } m_iResolution = AskUnsignedInteger(" Please enter binning resolution for this DDF: [100] ",100); if (g_bAdvanced2) m_iHistogramRes = AskUnsignedInteger(" Please enter histogram resolution (0=no histogram): [0] ",0); else m_iHistogramRes = 0; /* mprintf("\n Save temporal Development of Dihedrals (0=no, 1=yes)? [0] "); myget(buf); m_bSaveAngle = atoi(buf)!=0;*/ BuildName(); mprintf(WHITE,"\n<<< End of Dihedral Distribution Function <<<\n\n"); BTOUT; } void CPlDF::Parse() { BTIN; // char buf[1024]; CxString buf; CAtomGroup *ag; int z; try { m_pPlDF = new CDF(); } catch(...) { m_pPlDF = NULL; } if (m_pPlDF == NULL) NewException((double)sizeof(CDF),__FILE__,__LINE__,__PRETTY_FUNCTION__); mprintf(WHITE,"\n>>> Plane Distance Distribution Function >>>\n\n"); m_bNormal = !AskYesNo(" Define plane via 3 atoms (y) or as normal plane of a vector (n) (y/n)? [yes] ",true); m_iCombinations = 1; m_iRefAtomGes = 1; if (m_bNormal) { try { ag = new CAtomGroup(); } catch(...) { ag = NULL; } if (ag == NULL) NewException((double)sizeof(CAtomGroup),__FILE__,__LINE__,__PRETTY_FUNCTION__); _b2: if (m_iShowMol != -1) m_iRefOrSec[0] = AskRangeInteger(" Take the base atom of the vector/plane from RM %s (0) or from OM %s (1)? [0] ",0,1,0,((CMolecule*)g_oaMolecules[g_iFixMol])->m_sName,((CMolecule*)g_oaMolecules[m_iShowMol])->m_sName); else m_iRefOrSec[0] = 0; if (((CMolecule*)g_oaMolecules[(m_iRefOrSec[0])?m_iShowMol:g_iFixMol])->m_iAtomGesNoVirt == 1) { mprintf(" %s is only one atom, there is no choice.\n",((CMolecule*)g_oaMolecules[(m_iRefOrSec[0])?m_iShowMol:g_iFixMol])->m_sName); ag->Reset(); ag->m_pMolecule = (CMolecule*)g_oaMolecules[(m_iRefOrSec[0])?m_iShowMol:g_iFixMol]; ag->AddAtom(0,0,false); ag->SortAtoms(); ag->BuildName(); } else { mprintf(" Please enter the base atom (e.g. C7): "); inpprintf("! Please enter the base atom (e.g. C7):\n"); myget(&buf); if (!ag->ParseAtoms((!m_iRefOrSec[0])?(CMolecule*)g_oaMolecules[g_iFixMol]:(CMolecule*)g_oaMolecules[m_iShowMol],buf)) { eprintf("Invalid input.\n"); inpprintf("! Invalid input.\n"); goto _b2; } } m_iCombinations *= ag->m_iAtomGes; m_oaVectors.Add(ag); try { ag = new CAtomGroup(); } catch(...) { ag = NULL; } if (ag == NULL) NewException((double)sizeof(CAtomGroup),__FILE__,__LINE__,__PRETTY_FUNCTION__); _b3: if (m_iShowMol != -1) m_iRefOrSec[1] = AskRangeInteger(" Take the atom at the tip of the vector from RM %s (0) or from OM %s (1)? [0] ",0,1,0,((CMolecule*)g_oaMolecules[g_iFixMol])->m_sName,((CMolecule*)g_oaMolecules[m_iShowMol])->m_sName); else m_iRefOrSec[1] = 0; if (((CMolecule*)g_oaMolecules[(m_iRefOrSec[1])?m_iShowMol:g_iFixMol])->m_iAtomGesNoVirt == 1) { mprintf(" %s is only one atom, there is no choice.\n",((CMolecule*)g_oaMolecules[(m_iRefOrSec[1])?m_iShowMol:g_iFixMol])->m_sName); ag->Reset(); ag->m_pMolecule = (CMolecule*)g_oaMolecules[(m_iRefOrSec[1])?m_iShowMol:g_iFixMol]; ag->AddAtom(0,0,false); ag->SortAtoms(); ag->BuildName(); } else { mprintf(" Please enter the tip atom (e.g. C7): "); inpprintf("! Please enter the tip atom (e.g. C7):\n"); myget(&buf); if (!ag->ParseAtoms((!m_iRefOrSec[1])?(CMolecule*)g_oaMolecules[g_iFixMol]:(CMolecule*)g_oaMolecules[m_iShowMol],buf)) { eprintf("Invalid input.\n"); inpprintf("! Invalid input.\n"); goto _b3; } } m_iCombinations *= ag->m_iAtomGes; m_oaVectors.Add(ag); m_oaVectors.Add(NULL); // Dummy placeholder } else { for (z=0;z<3;z++) { try { ag = new CAtomGroup(); } catch(...) { ag = NULL; } if (ag == NULL) NewException((double)sizeof(CAtomGroup),__FILE__,__LINE__,__PRETTY_FUNCTION__); _b1: if (m_iShowMol != -1) m_iRefOrSec[z] = AskRangeInteger(" Take the %d. atom(s) of the plane from RM %s (0) or from OM %s (1)? [0] ",0,1,0,z+1,((CMolecule*)g_oaMolecules[g_iFixMol])->m_sName,((CMolecule*)g_oaMolecules[m_iShowMol])->m_sName); else m_iRefOrSec[z] = 0; if (((CMolecule*)g_oaMolecules[(m_iRefOrSec[z])?m_iShowMol:g_iFixMol])->m_iAtomGesNoVirt == 1) { mprintf(" %s is only one atom, there is no choice.\n",((CMolecule*)g_oaMolecules[(m_iRefOrSec[z])?m_iShowMol:g_iFixMol])->m_sName); ag->Reset(); ag->m_pMolecule = (CMolecule*)g_oaMolecules[(m_iRefOrSec[z])?m_iShowMol:g_iFixMol]; ag->AddAtom(0,0,false); ag->SortAtoms(); ag->BuildName(); } else { mprintf(" Please enter the %d. atom (e.g. C7): ",z+1); inpprintf("! Please enter the %d. atom (e.g. C7):\n",z+1); myget(&buf); if (!ag->ParseAtoms((!m_iRefOrSec[z])?(CMolecule*)g_oaMolecules[g_iFixMol]:(CMolecule*)g_oaMolecules[m_iShowMol],buf)) { eprintf("Invalid input.\n"); inpprintf("! Invalid input.\n"); goto _b1; } } m_iCombinations *= ag->m_iAtomGes; m_oaVectors.Add(ag); } } mprintf(" Plane defined.\n\n"); try { ag = new CAtomGroup(); } catch(...) { ag = NULL; } if (ag == NULL) NewException((double)sizeof(CAtomGroup),__FILE__,__LINE__,__PRETTY_FUNCTION__); _b4: if (m_iShowMol != -1) m_iRefOrSec[3] = AskRangeInteger(" Take the atom(s) to observe from RM %s (0) or from OM %s (1)? [1] ",0,1,1,((CMolecule*)g_oaMolecules[g_iFixMol])->m_sName,((CMolecule*)g_oaMolecules[m_iShowMol])->m_sName); else m_iRefOrSec[3] = 0; if (((CMolecule*)g_oaMolecules[(m_iRefOrSec[3])?m_iShowMol:g_iFixMol])->m_iAtomGesNoVirt == 1) { mprintf(" %s is only one atom, there is no choice.\n",((CMolecule*)g_oaMolecules[(m_iRefOrSec[3])?m_iShowMol:g_iFixMol])->m_sName); ag->Reset(); ag->m_pMolecule = (CMolecule*)g_oaMolecules[(m_iRefOrSec[3])?m_iShowMol:g_iFixMol]; ag->AddAtom(0,0,false); ag->SortAtoms(); ag->BuildName(); } else { mprintf(" Please enter the atom(s) to observe (e.g. C7): "); inpprintf("! Please enter the atom(s) to observe (e.g. C7):\n"); myget(&buf); if (!ag->ParseAtoms((!m_iRefOrSec[3])?(CMolecule*)g_oaMolecules[g_iFixMol]:(CMolecule*)g_oaMolecules[m_iShowMol],buf)) { eprintf("Invalid input.\n"); inpprintf("! Invalid input.\n"); goto _b4; } } m_iCombinations *= ag->m_iAtomGes; m_iShowAtomGes = ag->m_iAtomGes; m_oaVectors.Add(ag); m_fMinDist = AskFloat(" Enter the minimal distance to observe (in pm): [-%d.0] ",(double)-HalfBox(),HalfBox()); m_fMaxDist = AskFloat(" Enter the maximal distance to observe (in pm): [%d.0] ",(double)HalfBox(),HalfBox()); m_iResolution = AskUnsignedInteger(" Please enter binning resolution for this PlDF: [100] ",100); if (g_bAdvanced2) m_iHistogramRes = AskUnsignedInteger(" Please enter histogram resolution (0=no histogram): [0] ",0); else m_iHistogramRes = 0; BuildName(); mprintf(WHITE,"\n<<< End of Plane Distance Distribution Function <<<\n\n"); BTOUT; } void CLiDF::Parse() { BTIN; // char buf[1024]; CxString buf; CAtomGroup *ag; int z; try { m_pLiDF = new CDF(); } catch(...) { m_pLiDF = NULL; } if (m_pLiDF == NULL) NewException((double)sizeof(CDF),__FILE__,__LINE__,__PRETTY_FUNCTION__); mprintf(WHITE,"\n>>> Line Distance Distribution Function >>>\n\n"); m_bNormal = !AskYesNo(" Define line via 2 atoms (y) or as normal vector of a plane (n) (y/n)? [yes] ",true); m_iCombinations = 1; m_iRefAtomGes = 1; if (m_bNormal) { mprintf("\n The line will pass through the 1st point of the plane.\n\n"); for (z=0;z<3;z++) { try { ag = new CAtomGroup(); } catch(...) { ag = NULL; } if (ag == NULL) NewException((double)sizeof(CAtomGroup),__FILE__,__LINE__,__PRETTY_FUNCTION__); _b3: if (m_iShowMol != -1) m_iRefOrSec[z] = AskRangeInteger(" Take the %d. atom(s) of the plane from RM %s (0) or from OM %s (1)? [0] ",0,1,0,z+1,((CMolecule*)g_oaMolecules[g_iFixMol])->m_sName,((CMolecule*)g_oaMolecules[m_iShowMol])->m_sName); else m_iRefOrSec[z] = 0; if (((CMolecule*)g_oaMolecules[(m_iRefOrSec[z])?m_iShowMol:g_iFixMol])->m_iAtomGesNoVirt == 1) { mprintf(" %s is only one atom, there is no choice.\n",((CMolecule*)g_oaMolecules[(m_iRefOrSec[z])?m_iShowMol:g_iFixMol])->m_sName); ag->Reset(); ag->m_pMolecule = (CMolecule*)g_oaMolecules[(m_iRefOrSec[z])?m_iShowMol:g_iFixMol]; ag->AddAtom(0,0,false); ag->SortAtoms(); ag->BuildName(); } else { mprintf(" Please enter the %d. atom (e.g. C7): ",z+1); inpprintf("! Please enter the %d. atom (e.g. C7):\n",z+1); myget(&buf); if (!ag->ParseAtoms((!m_iRefOrSec[z])?(CMolecule*)g_oaMolecules[g_iFixMol]:(CMolecule*)g_oaMolecules[m_iShowMol],buf)) { eprintf("Invalid input.\n"); inpprintf("! Invalid input.\n"); goto _b3; } } m_iCombinations *= ag->m_iAtomGes; m_oaVectors.Add(ag); } } else { for (z=0;z<2;z++) { try { ag = new CAtomGroup(); } catch(...) { ag = NULL; } if (ag == NULL) NewException((double)sizeof(CAtomGroup),__FILE__,__LINE__,__PRETTY_FUNCTION__); _b1: if (m_iShowMol != -1) m_iRefOrSec[z] = AskRangeInteger(" Take the %d. atom(s) of the line from RM %s (0) or from OM %s (1)? [0] ",0,1,0,z+1,((CMolecule*)g_oaMolecules[g_iFixMol])->m_sName,((CMolecule*)g_oaMolecules[m_iShowMol])->m_sName); else m_iRefOrSec[z] = 0; if (((CMolecule*)g_oaMolecules[(m_iRefOrSec[z])?m_iShowMol:g_iFixMol])->m_iAtomGesNoVirt == 1) { mprintf(" %s is only one atom, there is no choice.\n",((CMolecule*)g_oaMolecules[(m_iRefOrSec[z])?m_iShowMol:g_iFixMol])->m_sName); ag->Reset(); ag->m_pMolecule = (CMolecule*)g_oaMolecules[(m_iRefOrSec[z])?m_iShowMol:g_iFixMol]; ag->AddAtom(0,0,false); ag->SortAtoms(); ag->BuildName(); } else { mprintf(" Please enter the %d. atom (e.g. C7): ",z+1); inpprintf("! Please enter the %d. atom (e.g. C7):\n",z+1); myget(&buf); if (!ag->ParseAtoms((!m_iRefOrSec[z])?(CMolecule*)g_oaMolecules[g_iFixMol]:(CMolecule*)g_oaMolecules[m_iShowMol],buf)) { eprintf("Invalid input.\n"); inpprintf("! Invalid input.\n"); goto _b1; } } m_iCombinations *= ag->m_iAtomGes; m_oaVectors.Add(ag); } m_oaVectors.Add(NULL); } mprintf(" Line defined.\n\n"); try { ag = new CAtomGroup(); } catch(...) { ag = NULL; } if (ag == NULL) NewException((double)sizeof(CAtomGroup),__FILE__,__LINE__,__PRETTY_FUNCTION__); _b2: if (m_iShowMol != -1) m_iRefOrSec[3] = AskRangeInteger(" Take the atom(s) to observe from RM %s (0) or from OM %s (1)? [1] ",0,1,1,((CMolecule*)g_oaMolecules[g_iFixMol])->m_sName,((CMolecule*)g_oaMolecules[m_iShowMol])->m_sName); else m_iRefOrSec[3] = 0; if (((CMolecule*)g_oaMolecules[(m_iRefOrSec[3])?m_iShowMol:g_iFixMol])->m_iAtomGesNoVirt == 1) { mprintf(" %s is only one atom, there is no choice.\n",((CMolecule*)g_oaMolecules[(m_iRefOrSec[3])?m_iShowMol:g_iFixMol])->m_sName); ag->Reset(); ag->m_pMolecule = (CMolecule*)g_oaMolecules[(m_iRefOrSec[3])?m_iShowMol:g_iFixMol]; ag->AddAtom(0,0,false); ag->SortAtoms(); ag->BuildName(); } else { mprintf(" Please enter the atom(s) to observe (e.g. C7): "); inpprintf("! Please enter the atom(s) to observe (e.g. C7):\n"); myget(&buf); if (!ag->ParseAtoms((!m_iRefOrSec[3])?(CMolecule*)g_oaMolecules[g_iFixMol]:(CMolecule*)g_oaMolecules[m_iShowMol],buf)) { eprintf("Invalid input.\n"); inpprintf("! Invalid input.\n"); goto _b2; } } m_iShowAtomGes = ag->m_iAtomGes; m_iCombinations *= ag->m_iAtomGes; m_oaVectors.Add(ag); m_fMinDist = AskFloat(" Enter the minimal distance to observe (in pm): [0] ",0.0); m_fMaxDist = AskFloat(" Enter the maximal distance to observe (in pm): [%d.0] ",(double)HalfBox(),HalfBox()); m_iResolution = AskUnsignedInteger(" Please enter binning resolution for this LiDF: [100] ",100); if (g_bAdvanced2) m_iHistogramRes = AskUnsignedInteger(" Please enter histogram resolution (0=no histogram): [0] ",0); else m_iHistogramRes = 0; if (m_iShowMol != -1) m_bRadialCorrect = AskYesNo(" Correct radial distribution for this LiDF (y/n)? [yes] ",true); else m_bRadialCorrect = AskYesNo(" Correct radial distribution for this LiDF (y/n)? [no] ",false); BuildName(); mprintf(WHITE,"\n<<< End of Line Distance Distribution Function <<<\n\n"); BTOUT; } void CDipDF::Parse() { BTIN; double tf; double td, td2, td3; CMolecule *m; CSingleMolecule *sm; int z; g_bDipole = true; try { m_pDipoleDF = new CDF(); } catch(...) { m_pDipoleDF = NULL; } if (m_pDipoleDF == NULL) NewException((double)sizeof(CDF),__FILE__,__LINE__,__PRETTY_FUNCTION__); mprintf(WHITE,"\n>>> Dipole Distribution Function >>>\n\n"); if (m_iShowMol != -1) m_iRefOrSec = AskRangeInteger(" Observe dipole moment from RM %s (0) or from OM %s (1)? [0] ",0,1,0,((CMolecule*)g_oaMolecules[g_iFixMol])->m_sName,((CMolecule*)g_oaMolecules[m_iShowMol])->m_sName); else m_iRefOrSec = 0; ParseDeriv(); if (m_iRefOrSec != 0) m = (CMolecule*)g_oaMolecules[m_iShowMol]; else m = (CMolecule*)g_oaMolecules[g_iFixMol]; td = 0; td2 = 1.0e10; td3 = 0; for (z=0;zm_laSingleMolIndex.GetSize();z++) { sm = (CSingleMolecule*)g_oaSingleMolecules[m->m_laSingleMolIndex[z]]; tf = sm->m_vDipole.GetLength(); if (tf > td) td = tf; if (tf < td2) td2 = tf; td3 += tf; } td3 /= (double)m->m_laSingleMolIndex.GetSize(); mprintf("\n Dipole moment of %s (1st step): Min. %.3f, Max. %.3f, Avg. %.3f Debye.\n\n",m->m_sName,td2,td,td3); switch(m_iDeriv) { case 0: m_fDipoleMin = AskFloat(" Enter the lower bound for dipole values (in Debye): [0] ",0.0); m_fDipoleMax = AskFloat(" Enter the upper bound for dipole values (in Debye): [%d] ",double(int(td*2.0)),int(td*2.0)); break; case 1: if (m_bDerivAbs) m_fDipoleMin = AskFloat(" Enter the minimal value of this d1-DDF in Debye/ps: [0] ",0.0); else m_fDipoleMin = AskFloat(" Enter the minimal value of this d1-DDF in Debye/ps: [-10.0] ",-10.0); m_fDipoleMax = AskFloat(" Enter the maximal value of this d1-DDF in Debye/ps: [10.0] ",10.0); break; case 2: if (m_bDerivAbs) m_fDipoleMin = AskFloat(" Enter the minimal value of this d2-DDF in Debye/ps^2: [0] ",0.0); else m_fDipoleMin = AskFloat(" Enter the minimal value of this d2-DDF in Debye/ps^2: [-10.0] ",-10.0); m_fDipoleMax = AskFloat(" Enter the maximal value of this d2-DDF in Debye/ps^2: [10.0] ",10.0); break; } m_iResolution = AskUnsignedInteger(" Enter binning resolution for the Dipole DF: [%d] ",int((m_fDipoleMax-m_fDipoleMin)*10.0),int((m_fDipoleMax-m_fDipoleMin)*10.0)); if (g_bAdvanced2) m_iHistogramRes = AskUnsignedInteger(" Please enter histogram resolution (0=no histogram): [0] ",0); else m_iHistogramRes = 0; BuildName(); mprintf(WHITE,"\n<<< End of Dipole Distribution Function <<<\n\n"); BTOUT; } void CSDF::Parse(bool voro) { BTIN; int ti; // char buf[1024]; CxString buf; m_iShowAtomGes = 0; try { m_pSDF = new C3DF(); } catch(...) { m_pSDF = NULL; } if (m_pSDF == NULL) NewException((double)sizeof(C3DF),__FILE__,__LINE__,__PRETTY_FUNCTION__); mprintf(WHITE,"\n>>> Spatial Distribution Function >>>\n\n"); _sdfatoms: if (!voro) { if (m_bIntra) { mprintf(" Observing atoms in reference molecule %s.\n",((CMolecule*)g_oaMolecules[g_iFixMol])->m_sName); m_iRefOrSec = 0; } else { mprintf(" Observing atoms in observed molecule %s.\n",((CMolecule*)g_oaMolecules[m_iShowMol])->m_sName); m_iRefOrSec = 1; } /* if (m_iShowMol != -1) m_iRefOrSec = AskRangeInteger(" Observe atoms in RM %s (0) or in OM %s (1)? [1] ",0,1,1,((CMolecule*)g_oaMolecules[g_iFixMol])->m_sName,((CMolecule*)g_oaMolecules[m_iShowMol])->m_sName); else m_iRefOrSec = 0;*/ if (((CMolecule*)g_oaMolecules[(m_iRefOrSec)?m_iShowMol:g_iFixMol])->m_iAtomGesNoVirt == 1) { mprintf(" %s is only one atom, there is no choice.\n",((CMolecule*)g_oaMolecules[(m_iRefOrSec)?m_iShowMol:g_iFixMol])->m_sName); m_oAtoms.Reset(); m_oAtoms.m_pMolecule = (CMolecule*)g_oaMolecules[(m_iRefOrSec)?m_iShowMol:g_iFixMol]; m_oAtoms.AddAtom(0,0,false); m_oAtoms.SortAtoms(); m_oAtoms.BuildName(); } else { mprintf(" Which atoms to observe (e.g. \"C1,C3-5,H\", \"*\"=all)? [#2] "); inpprintf("! Which atoms to observe (e.g. \"C1,C3-5,H\", \"*\"=all)? [#2]\n"); myget(&buf); if (strlen(buf) == 0) { if (!m_oAtoms.ParseAtoms((CMolecule*)g_oaMolecules[(m_iRefOrSec==0)?g_iFixMol:m_iShowMol],"#2")) { eprintf("Strange error ^^\n"); inpprintf("! Strange error ^\n"); goto _sdfatoms; } } else { if (!m_oAtoms.ParseAtoms((CMolecule*)g_oaMolecules[(m_iRefOrSec==0)?g_iFixMol:m_iShowMol],buf)) { eprintf("Invalid input.\n"); inpprintf("! Invalid input.\n"); goto _sdfatoms; } } } m_iShowAtomGes += m_oAtoms.m_iAtomGes; m_fParticleDensity = m_oAtoms.m_iAtomGes * ((CMolecule*)g_oaMolecules[(m_iRefOrSec==0)?g_iFixMol:m_iShowMol])->m_laSingleMolIndex.GetSize() / g_fBoxX / g_fBoxY / g_fBoxZ * 1E9; } m_fRadius = AskFloat(" Please enter radius of this SDF in pm: [%d.0] ",(double)HalfBox(),HalfBox()); if (g_bPeriodic && (m_fRadius > HalfBox_Exact()+1.0)) { eprintf("\nWarning: "); mprintf("The specified max. radius is larger than half of the smallest periodic cell vector.\n"); mprintf(" TRAVIS counts every atom only once (central periodic image).\n"); mprintf(" Expect the analysis to decay to zero for large radii.\n\n"); AskYesNo(" Acknowledged [yes] ",true); mprintf("\n"); } _sdfresagain: ti = g_pDatabase->GetInt("/PLOT3D/DEFAULTS/BIN_RES"); m_iResolution = AskUnsignedInteger(" Please enter binning resolution of this SDF per dimension: [%d] ",ti,ti); if (m_iResolution > 300) { eprintf("\nWarning: "); mprintf("This large resolution will consume much RAM (%s)\n",FormatBytes(pow3((double)m_iResolution)*sizeof(double))); mprintf(" and result in very large SDF output files.\n\n"); if (!AskYesNo(" Use this resolution (y/n)? [no] ",false)) goto _sdfresagain; } if (g_bAdvanced2) { m_bVdWSpheres = false; //AskYesNo(" Process atoms as VdW spheres rather than points (y/n)? [no] ",false); m_iHistogramRes = AskUnsignedInteger(" Please enter histogram resolution (0=no histogram): [0] ",0); m_bClipPlane = AskYesNo(" Use a clipping plane for this SDF (y/n)? [no] ",false); if (m_bClipPlane) { _cut: mprintf(" Should the clipping plane stand perpendicular to the X, Y or Z axis (x/y/z)? [x] "); inpprintf("! Should the clipping plane stand perpendicular to the X, Y or Z axis (x/y/z)? [x]\n"); myget(&buf); switch(tolower(buf[0])) { case 0: case 'x': m_iClipDirection = 0; break; case 'y': m_iClipDirection = 1; break; case 'z': m_iClipDirection = 2; break; default: eprintf(" Invalid input! Please enter 'x', 'y' or 'z'.\n"); inpprintf("! Invalid input! Please enter 'x', 'y' or 'z'.\n"); goto _cut; } m_fClipValue = AskFloat(" Please enter distance of clipping plane from origin (in pm): [0] ",0.0); } m_bInvert = AskYesNo(" Should this SDF be inverted (y/n)? [no] ",false); m_bSDFMirrorXY = AskYesNo(" Force this SDF to be symmetrical to the XY plane (y/n)? [no] ",false); m_bSDFMirrorBisect = AskYesNo(" Force this SDF to be symmetrical to the angle bisector (y/n)? [no] ",false); m_bCutPlane = AskYesNo(" Add a particle density cut plane to this SDF (y/n)? [no] ",false); if (m_bCutPlane) { m_iCutPlaneResolution = AskUnsignedInteger(" Enter the binning resolution for the cut plane per dimension: [100] ",100); m_bCutPlaneShowAtoms = AskYesNo(" Show reference atoms in Pseudo SDF plot (y/n)? [yes] ",true); } } else { m_bVdWSpheres = false; m_bClipPlane = false; m_bInvert = false; m_bSDFMirrorXY = false; m_bSDFMirrorBisect = false; m_bCutPlane = false; m_iHistogramRes = 0; } if (!voro) BuildName(); mprintf(WHITE,"\n<<< End of Spatial Distribution Function <<<\n\n"); BTOUT; } void CVDF::Parse() { BTIN; // char buf[1024]; CxString buf; m_iShowAtomGes = 0; try { m_pVDF = new CDF(); } catch(...) { m_pVDF = NULL; } if (m_pVDF == NULL) NewException((double)sizeof(CDF),__FILE__,__LINE__,__PRETTY_FUNCTION__); mprintf(WHITE,"\n>>> Velocity Distribution Function >>>\n\n"); _atoms: if (g_iFixMol == -1) { mprintf(" Observing atoms from OM %s.\n",((CMolecule*)g_oaMolecules[m_iShowMol])->m_sName); m_iRefOrSec = 1; } else if (m_iShowMol == -1) { mprintf(" Observing atoms from RM %s.\n",((CMolecule*)g_oaMolecules[g_iFixMol])->m_sName); m_iRefOrSec = 0; } else m_iRefOrSec = AskRangeInteger(" Observe atoms in RM %s (0) or in OM %s (1)? [1]",0,1,1,((CMolecule*)g_oaMolecules[g_iFixMol])->m_sName,((CMolecule*)g_oaMolecules[m_iShowMol])->m_sName); mprintf(" Which atoms to observe (e.g. \"C1,C3-5,H\", \"*\"=all)? [#2] "); inpprintf("! Which atoms to observe (e.g. \"C1,C3-5,H\", \"*\"=all)? [#2]\n"); myget(&buf); if (strlen(buf) == 0) { m_oAtoms.AddAllAtoms((CMolecule*)g_oaMolecules[m_iRefOrSec?m_iShowMol:g_iFixMol],false); if (!m_oAtoms.ParseAtoms((CMolecule*)g_oaMolecules[m_iRefOrSec?m_iShowMol:g_iFixMol],"#2")) { eprintf("CVDF::Parse(): Internal error.\n"); abort(); } } else { if (!m_oAtoms.ParseAtoms((CMolecule*)g_oaMolecules[m_iRefOrSec?m_iShowMol:g_iFixMol],buf)) { eprintf("Invalid input.\n"); inpprintf("! Invalid input.\n"); goto _atoms; } } m_iCombinations = m_oAtoms.m_iAtomGes; m_iShowAtomGes += m_oAtoms.m_iAtomGes; // m_fParticleDensity = m_oAtoms.m_iAtomGes * ((CMolecule*)g_oaMolecules[m_iShowMol])->m_laSingleMolIndex.GetSize() / g_fBoxX / g_fBoxY / g_fBoxZ; ParseDeriv(); switch(m_iDeriv) { case 0: /* if (AskYesNo(" Scan for velocity range (y) or enter range manually (n)? [no] ",false)) { m_bScanRange = true; g_bScanVelocities = true; } else*/ { m_bScanRange = false; m_fMinSpeed = 0; //AskFloat(" Please enter the minimal velocity: [0.0 pm/fs] ",0.0f); m_fMaxSpeed = AskFloat(" Please enter the maximal velocity: [10000.0 pm/ps] ",10000.0); } break; case 1: if (m_bDerivAbs) m_fMinSpeed = AskFloat(" Enter the minimal value of this d1-VDF in pm/ps^2: [0] ",0.0); else m_fMinSpeed = AskFloat(" Enter the minimal value of this d1-VDF in pm/ps^2: [-10.0] ",-10.0); m_fMaxSpeed = AskFloat(" Enter the maximal value of this d1-VDF in pm/ps^2: [10.0] ",10.0); break; case 2: if (m_bDerivAbs) m_fMinSpeed = AskFloat(" Enter the minimal value of this d2-VDF in pm/ps^3: [0] ",0.0); else m_fMinSpeed = AskFloat(" Enter the minimal value of this d2-VDF in pm/ps^3: [-10.0] ",-10.0); m_fMaxSpeed = AskFloat(" Enter the maximal value of this d2-VDF in pm/ps^3: [10.0] ",10.0); break; } m_iResolution = AskInteger(" Please enter the binning resolution for this VDF: [300] ",300); if (g_bAdvanced2) { m_bSplitCart = AskYesNo(" Write cartesian contributions (x, y, z, xy, xz, yz) of this VDF (y/n)? [no] ",false); m_iHistogramRes = AskUnsignedInteger(" Please enter histogram resolution (0=no histogram): [0] ",0); } else { m_bSplitCart = false; m_iHistogramRes = 0; } if (m_bSplitCart && (g_iFixMol != -1)) { mprintf("\n"); mprintf(RED," Error:"); mprintf(" Writing cartesian contributions only works for pure VDFs (i.e., not part of a CDF).\n\n"); AskYesNo(" Acknowledged [yes] ",true); mprintf("\n"); m_bSplitCart = false; } /* mprintf(" Save temporal Development of Velocity (0=no, 1=yes)? [0] "); myget(buf); m_bSaveSpeed = atoi(buf)!=0;*/ BuildName(); mprintf(WHITE,"\n<<< End of Velocity Distribution Function <<<\n\n"); BTOUT; } void CSDF::BuildName() { BTIN; // char tmp[32768]; CxString tmp; // tmp[0] = 0; tmp = ""; if (m_iRefOrSec) // sprintf(tmp,"%s_%s%d%s%d%s%d_%s_%s",((CMolecule*)g_oaMolecules[g_iFixMol])->m_sName,((CAtom*)g_oaAtoms[g_iFixRealAtomType[0]])->m_sName,g_iFixAtom[0]+1,((CAtom*)g_oaAtoms[g_iFixRealAtomType[1]])->m_sName,g_iFixAtom[1]+1,((CAtom*)g_oaAtoms[g_iFixRealAtomType[2]])->m_sName,g_iFixAtom[2]+1,((CMolecule*)g_oaMolecules[m_iShowMol])->m_sName,m_oAtoms.m_sName); tmp.sprintf("%s_%s%d%s%d%s%d_%s_%s",((CMolecule*)g_oaMolecules[g_iFixMol])->m_sName,(const char*)((CAtom*)g_oaAtoms[g_iFixRealAtomType[0]])->m_sName,g_iFixAtom[0]+1,(const char*)((CAtom*)g_oaAtoms[g_iFixRealAtomType[1]])->m_sName,g_iFixAtom[1]+1,(const char*)((CAtom*)g_oaAtoms[g_iFixRealAtomType[2]])->m_sName,g_iFixAtom[2]+1,((CMolecule*)g_oaMolecules[m_iShowMol])->m_sName,m_oAtoms.m_sName); else // sprintf(tmp,"%s_%s%d%s%d%s%d_%s",((CMolecule*)g_oaMolecules[g_iFixMol])->m_sName,((CAtom*)g_oaAtoms[g_iFixRealAtomType[0]])->m_sName,g_iFixAtom[0]+1,((CAtom*)g_oaAtoms[g_iFixRealAtomType[1]])->m_sName,g_iFixAtom[1]+1,((CAtom*)g_oaAtoms[g_iFixRealAtomType[2]])->m_sName,g_iFixAtom[2]+1,m_oAtoms.m_sName); tmp.sprintf("%s_%s%d%s%d%s%d_%s",((CMolecule*)g_oaMolecules[g_iFixMol])->m_sName,(const char*)((CAtom*)g_oaAtoms[g_iFixRealAtomType[0]])->m_sName,g_iFixAtom[0]+1,(const char*)((CAtom*)g_oaAtoms[g_iFixRealAtomType[1]])->m_sName,g_iFixAtom[1]+1,(const char*)((CAtom*)g_oaAtoms[g_iFixRealAtomType[2]])->m_sName,g_iFixAtom[2]+1,m_oAtoms.m_sName); try { m_sName = new char[strlen(tmp)+1]; } catch(...) { m_sName = NULL; } if (m_sName == NULL) NewException((double)(strlen(tmp)+1)*sizeof(char),__FILE__,__LINE__,__PRETTY_FUNCTION__); strcpy(m_sName,tmp); BTOUT; } void CVDF::BuildName() { BTIN; // char tmp[32768]; CxString tmp; if (m_iDeriv != 0) // sprintf(tmp,"deriv%d_%s",m_iDeriv,m_oAtoms.m_sName); tmp.sprintf("deriv%d_%s",m_iDeriv,m_oAtoms.m_sName); else // sprintf(tmp,"%s",m_oAtoms.m_sName); tmp.sprintf("%s",m_oAtoms.m_sName); try { m_sShortName = new char[strlen(tmp)+1]; } catch(...) { m_sShortName = NULL; } if (m_sShortName == NULL) NewException((double)(strlen(tmp)+1)*sizeof(char),__FILE__,__LINE__,__PRETTY_FUNCTION__); strcpy(m_sShortName,m_oAtoms.m_sName); if (g_iFixMol == -1) { // sprintf(tmp,"%s_",((CMolecule*)g_oaMolecules[m_iShowMol])->m_sName); tmp.sprintf("%s_",((CMolecule*)g_oaMolecules[m_iShowMol])->m_sName); } else if (m_iRefOrSec) // sprintf(tmp,"%s_%s%d_%s_",((CMolecule*)g_oaMolecules[g_iFixMol])->m_sName,((CAtom*)g_oaAtoms[g_iFixRealAtomType[0]])->m_sName,g_iFixAtom[0]+1,((CMolecule*)g_oaMolecules[m_iShowMol])->m_sName); tmp.sprintf("%s_%s%d_%s_",((CMolecule*)g_oaMolecules[g_iFixMol])->m_sName,(const char*)((CAtom*)g_oaAtoms[g_iFixRealAtomType[0]])->m_sName,g_iFixAtom[0]+1,((CMolecule*)g_oaMolecules[m_iShowMol])->m_sName); else // sprintf(tmp,"%s_%s%d_",((CMolecule*)g_oaMolecules[g_iFixMol])->m_sName,((CAtom*)g_oaAtoms[g_iFixRealAtomType[0]])->m_sName,g_iFixAtom[0]+1); tmp.sprintf("%s_%s%d_",((CMolecule*)g_oaMolecules[g_iFixMol])->m_sName,(const char*)((CAtom*)g_oaAtoms[g_iFixRealAtomType[0]])->m_sName,g_iFixAtom[0]+1); // strcat(tmp,m_sShortName); tmp.strcat(m_sShortName); try { m_sName = new char[strlen(tmp)+1]; } catch(...) { m_sName = NULL; } if (m_sName == NULL) NewException((double)(strlen(tmp)+1)*sizeof(char),__FILE__,__LINE__,__PRETTY_FUNCTION__); strcpy(m_sName,tmp); try { m_sLabelName = new char[strlen(tmp)+1]; } catch(...) { m_sLabelName = NULL; } if (m_sLabelName == NULL) NewException((double)(strlen(m_sShortName)+1)*sizeof(char),__FILE__,__LINE__,__PRETTY_FUNCTION__); strcpy(m_sLabelName,m_sShortName); BTOUT; } void CSDF::BuildAtomList(CSingleMolecule *ref, CSingleMolecule *obs, CxIntArray *vec) { BXIN; int z1t, z1a; CxIntArray *a1; vec->RemoveAll_KeepSize(); for (z1t=0;z1tGetSize()); for (z1a=0;z1aGetSize();z1a++) if (m_iRefOrSec) { // mprintf("(c) BuildAtomList z1t=%d, z1a=%d, Type=%d, WA=%X\n",z1t,z1a,m_oAtoms.m_baAtomType[z1t],obs->m_oaAtomOffset[m_oAtoms.m_baAtomType[z1t]]); vec->Add(((CxIntArray*)obs->m_oaAtomOffset[m_oAtoms.m_baAtomType[z1t]])->GetAt(a1->GetAt(z1a))); } else vec->Add(((CxIntArray*)ref->m_oaAtomOffset[m_oAtoms.m_baAtomType[z1t]])->GetAt(a1->GetAt(z1a))); } BXOUT; } void CVDF::BuildAtomList(CSingleMolecule *ref, CSingleMolecule *obs, CxIntArray *vec) { BXIN; int z1t, z1a; CxIntArray *a1; vec->RemoveAll_KeepSize(); for (z1t=0;z1tGetSize();z1a++) if (m_iRefOrSec) vec->Add(((CxIntArray*)obs->m_oaAtomOffset[m_oAtoms.m_baAtomType[z1t]])->GetAt(a1->GetAt(z1a))); else vec->Add(((CxIntArray*)ref->m_oaAtomOffset[m_oAtoms.m_baAtomType[z1t]])->GetAt(a1->GetAt(z1a))); } BXOUT; } void CRDF::BuildAtomList(CSingleMolecule *ref, CSingleMolecule *obs, CxIntArray *vec) { BXIN; int z, z1t, z1a, z2t, z2a; CAtomGroup *g1, *g2; CxIntArray *a1, *a2; vec->RemoveAll_KeepSize(); for (z=0;zm_baAtomType.GetSize();z1t++) { a1 = (CxIntArray*)g1->m_oaAtoms[z1t]; for (z1a=0;z1aGetSize();z1a++) { g2 = (CAtomGroup*)m_oaVectors[z*2+1]; for (z2t=0;z2tm_baAtomType.GetSize();z2t++) { a2 = (CxIntArray*)g2->m_oaAtoms[z2t]; for (z2a=0;z2aGetSize();z2a++) { if (m_iRefOrSec[0]) vec->Add(((CxIntArray*)obs->m_oaAtomOffset[g1->m_baAtomType[z1t]])->GetAt(a1->GetAt(z1a))); else vec->Add(((CxIntArray*)ref->m_oaAtomOffset[g1->m_baAtomType[z1t]])->GetAt(a1->GetAt(z1a))); if (m_iRefOrSec[1]) vec->Add(((CxIntArray*)obs->m_oaAtomOffset[g2->m_baAtomType[z2t]])->GetAt(a2->GetAt(z2a))); else vec->Add(((CxIntArray*)ref->m_oaAtomOffset[g2->m_baAtomType[z2t]])->GetAt(a2->GetAt(z2a))); // mprintf("Vector z=%d, z1t=%d, z1a=%d, z2t=%d, z2a=%d.\n",z,z1t,z1a,z2t,z2a); } } } } } BXOUT; } void CVHDF::BuildAtomList(CSingleMolecule *ref, CSingleMolecule *obs, CxIntArray *vec) { BXIN; int z, z1t, z1a, z2t, z2a; CAtomGroup *g1, *g2; CxIntArray *a1, *a2; vec->RemoveAll_KeepSize(); for (z=0;zm_baAtomType.GetSize();z1t++) { a1 = (CxIntArray*)g1->m_oaAtoms[z1t]; for (z1a=0;z1aGetSize();z1a++) { g2 = (CAtomGroup*)m_oaVectors[z*2+1]; for (z2t=0;z2tm_baAtomType.GetSize();z2t++) { a2 = (CxIntArray*)g2->m_oaAtoms[z2t]; for (z2a=0;z2aGetSize();z2a++) { if (m_iRefOrSec[0]) vec->Add(((CxIntArray*)obs->m_oaAtomOffset[g1->m_baAtomType[z1t]])->GetAt(a1->GetAt(z1a))); else vec->Add(((CxIntArray*)ref->m_oaAtomOffset[g1->m_baAtomType[z1t]])->GetAt(a1->GetAt(z1a))); if (m_iRefOrSec[1]) vec->Add(((CxIntArray*)obs->m_oaAtomOffset[g2->m_baAtomType[z2t]])->GetAt(a2->GetAt(z2a))); else vec->Add(((CxIntArray*)ref->m_oaAtomOffset[g2->m_baAtomType[z2t]])->GetAt(a2->GetAt(z2a))); } } } } } BXOUT; } /*int FindAtom(char *s) { BTIN; int z; for (z=0;zm_sName)==0) { BTOUT; return z; } BTOUT; return -1; }*/ int CMolecule::FindAtomInMol(const char *s) { BTIN; int z; for (z=0;zm_sName)==0) { BTOUT; return z; } BTOUT; return -1; } void CMolecule::BuildName() { BTIN; int z, z2; // char buf[64], buf2[1024]; CxString buf, buf2; if (m_bPseudo) { // buf2[0] = '$'; // buf2[1] = 0; buf2.sprintf("$"); } else // buf2[0] = 0; buf2 = ""; for (z=0;z 1) // sprintf(buf,"%s%d",((CAtom*)g_oaAtoms[z])->m_sName,m_waAtomCount[z2]); buf.sprintf("%s%d",(const char*)((CAtom*)g_oaAtoms[z])->m_sName,m_waAtomCount[z2]); else // sprintf(buf,"%s",((CAtom*)g_oaAtoms[z])->m_sName); buf.sprintf("%s",(const char*)((CAtom*)g_oaAtoms[z])->m_sName); // strcat(buf2,buf); buf2.strcat(buf); } } try { m_sName = new char[strlen(buf2)+1]; } catch(...) { m_sName = NULL; } if (m_sName == NULL) NewException((double)(strlen(buf2)+1)*sizeof(char),__FILE__,__LINE__,__PRETTY_FUNCTION__); strcpy(m_sName,buf2); BTOUT; } bool CConditionGroup::Contains(int mol) { BXIN; int z; if (m_bInactive) return m_bAlwaysTrue[mol]; if (m_bInvertCondition) { if (m_bAlwaysTrue[mol]) { BXOUT; return false; } for (z=0;zContains(mol)) { BXOUT; return false; } } BXOUT; return true; } else { if (m_bAlwaysTrue[mol]) { BXOUT; return true; } for (z=0;zContains(mol)) { BXOUT; return true; } } BXOUT; return false; } } void CConditionGroup::MarkPassedAtoms(int om, bool passed) { BXIN; int z; // int ti; // mprintf("######## OM %d ##########\n",om+1); for (z=0;zMarkPassedAtoms(om); // for (z=0;z Wird genommen.",z+1); } else // Condition bestanden { // mprintf("Atom %s%d nicht bestanden (%d).\n",((CAtom*)g_oaAtoms[g_waAtomRealElement[z]])->m_sName,g_waAtomMolNumber[z]+1,g_baAtomPassedCondition[z]); // mprintf("\n%d erfuellt --> durchgefallen",z+1); g_baAtomPassedCondition[z] = 0; } } } else { for (z=0;z= 100) // Entweder Condition bestanden oder Atom kam gar nicht darin vor { // ti++; g_baAtomPassedCondition[z] = 1; } else // Condition nicht bestanden { // mprintf("Atom %s%d nicht bestanden (%d).\n",((CAtom*)g_oaAtoms[g_waAtomRealElement[z]])->m_sName,g_waAtomMolNumber[z]+1,g_baAtomPassedCondition[z]); g_baAtomPassedCondition[z] = 0; } } else { if (g_baAtomPassedCondition[z] == 100) // Condition bestanden { // ti++; // mprintf("### Atom %s[%d] %s%d bestanden (%d).\n",((CMolecule*)g_oaMolecules[g_waAtomMolIndex[z]])->m_sName,g_laAtomSMLocalIndex[z]+1,((CAtom*)g_oaAtoms[g_waAtomRealElement[z]])->m_sName,g_waAtomMolNumber[z]+1,g_baAtomPassedCondition[z]); g_baAtomPassedCondition[z] = 0; } else // Entweder Condition nicht bestanden oder Atom kam gar nicht darin vor { // mprintf("--- Atom %s[%d] %s%d nicht bestanden (%d).\n",((CMolecule*)g_oaMolecules[g_waAtomMolIndex[z]])->m_sName,g_laAtomSMLocalIndex[z]+1,((CAtom*)g_oaAtoms[g_waAtomRealElement[z]])->m_sName,g_waAtomMolNumber[z]+1,g_baAtomPassedCondition[z]); g_baAtomPassedCondition[z] = 1; } } } } // mprintf("\nMarked %d / %d atoms as enabled.",ti,g_iGesVirtAtomCount); BXOUT; } void CConditionGroup::ScanNeighborhoodAllOM(CTimeStep *t, CSingleMolecule *rm) { BXIN; int z, z2, t1, t2, i; if (m_bInactive) return; for (z=0;zScanNeighborhoodAllOM(t,rm); if (m_oaConditionSubGroups.GetSize() == 2) { for (z=0;z<((CMolecule*)g_oaMolecules[m_iShowMol])->m_laSingleMolIndex.GetSize();z++) { t1 = 0; t2 = 0; for (z2=0;z2<((CConditionSubGroup*)m_oaConditionSubGroups[0])->m_oaConditions.GetSize();z2++) t1 += ((CNbSearch*)((CConditionSubGroup*)m_oaConditionSubGroups[0])->m_oaConditions[z2])->m_iCombPassCount[z]; for (z2=0;z2<((CConditionSubGroup*)m_oaConditionSubGroups[1])->m_oaConditions.GetSize();z2++) t2 += ((CNbSearch*)((CConditionSubGroup*)m_oaConditionSubGroups[1])->m_oaConditions[z2])->m_iCombPassCount[z]; m_pTable[t1*(((CConditionSubGroup*)m_oaConditionSubGroups[1])->m_iCombinations+1)+t2]++; m_fTableGes++; } } i = 0; for (z=0;z<((CMolecule*)g_oaMolecules[m_iShowMol])->m_laSingleMolIndex.GetSize();z++) { m_fTotal++; if (m_bInvertCondition) { for (z2=0;z2Contains(z)) goto _nopass; m_fPassed++; m_iPassCounter[z]++; m_bAnyPassed = true; m_iTempPassed++; } else { for (z2=0;z2Contains(z)) { // mprintf("passed[%d]++\n",z); m_fPassed++; m_iPassCounter[z]++; m_bAnyPassed = true; m_iTempPassed++; i++; goto _nopass; } } } _nopass:; } m_pHistogram[i]++; m_iHistoGes++; BXOUT; } void CConditionGroup::PreScanNeighborhoodAllOM(CTimeStep *t, CSingleMolecule *rm) { BXIN; int z; if (m_bInactive) return; for (z=0;zPreScanNeighborhoodAllOM(t,rm); BXOUT; } void CConditionGroup::Parse(int rm, int sm) { BTIN; CConditionSubGroup *sg; int z; m_iShowMol = sm; m_iRefMol = rm; try { m_bAlwaysTrue = new bool[((CMolecule*)g_oaMolecules[sm])->m_laSingleMolIndex.GetSize()]; } catch(...) { m_bAlwaysTrue = NULL; } if (m_bAlwaysTrue == NULL) NewException((double)((CMolecule*)g_oaMolecules[sm])->m_laSingleMolIndex.GetSize()*sizeof(bool),__FILE__,__LINE__,__PRETTY_FUNCTION__); try { m_iPassCounter = new long[((CMolecule*)g_oaMolecules[sm])->m_laSingleMolIndex.GetSize()]; } catch(...) { m_iPassCounter = NULL; } if (m_iPassCounter == NULL) NewException((double)((CMolecule*)g_oaMolecules[sm])->m_laSingleMolIndex.GetSize()*sizeof(long),__FILE__,__LINE__,__PRETTY_FUNCTION__); try { m_iOMPassCounter = new long[((CMolecule*)g_oaMolecules[sm])->m_laSingleMolIndex.GetSize()]; } catch(...) { m_iOMPassCounter = NULL; } if (m_iOMPassCounter == NULL) NewException((double)((CMolecule*)g_oaMolecules[sm])->m_laSingleMolIndex.GetSize()*sizeof(long),__FILE__,__LINE__,__PRETTY_FUNCTION__); for (z=0;z<((CMolecule*)g_oaMolecules[sm])->m_laSingleMolIndex.GetSize();z++) { m_bAlwaysTrue[z] = false; m_iPassCounter[z] = 0; m_iOMPassCounter[z] = 0; } try { m_iRMPassCounter = new long[((CMolecule*)g_oaMolecules[rm])->m_laSingleMolIndex.GetSize()]; } catch(...) { m_iRMPassCounter = NULL; } if (m_iRMPassCounter == NULL) NewException((double)((CMolecule*)g_oaMolecules[rm])->m_laSingleMolIndex.GetSize()*sizeof(long),__FILE__,__LINE__,__PRETTY_FUNCTION__); for (z=0;z<((CMolecule*)g_oaMolecules[rm])->m_laSingleMolIndex.GetSize();z++) m_iRMPassCounter[z] = 0; mprintf("Different sets of conditions are connected with OR (at least one of them has to be fulfilled).\n"); mprintf("Different conditions within one set are connected with AND (have to be fulfilled at the same time).\n"); mprintf("If you create 1 or 2 sets of conditions, a table with subcondition count populations will be printed.\n\n"); _newset: mprintf(YELLOW,">>> %d. set of conditions >>>\n",m_oaConditionSubGroups.GetSize()+1); try { sg = new CConditionSubGroup(); } catch(...) { sg = NULL; } if (sg == NULL) NewException((double)sizeof(CConditionSubGroup),__FILE__,__LINE__,__PRETTY_FUNCTION__); sg->m_iShowMol = m_iShowMol; sg->m_iNumber = m_oaConditionSubGroups.GetSize(); m_oaConditionSubGroups.Add(sg); sg->Parse(rm,sm); mprintf(YELLOW,"\n<<< End of %d. set of conditions <<<\n\n",m_oaConditionSubGroups.GetSize()); if (AskYesNo(" Enter an additional set of conditions (y/n)? [no] ",false)) goto _newset; m_bInvertCondition = AskYesNo(" Invert this condition (only add bin entries if failed) (y/n)? [no] ",false); if (m_oaConditionSubGroups.GetSize() == 2) { m_fTableGes = 0; try { m_pTable = new double[(((CConditionSubGroup*)m_oaConditionSubGroups[0])->m_iCombinations+1) * (((CConditionSubGroup*)m_oaConditionSubGroups[1])->m_iCombinations+1)]; } catch(...) { m_pTable = NULL; } if (m_pTable == NULL) NewException((double)(((CConditionSubGroup*)m_oaConditionSubGroups[0])->m_iCombinations+1) * (((CConditionSubGroup*)m_oaConditionSubGroups[1])->m_iCombinations+1)*sizeof(double),__FILE__,__LINE__,__PRETTY_FUNCTION__); for (z=0;z<(((CConditionSubGroup*)m_oaConditionSubGroups[0])->m_iCombinations+1) * (((CConditionSubGroup*)m_oaConditionSubGroups[1])->m_iCombinations+1);z++) m_pTable[z] = 0; } /* m_bNeedNbCountMode = false; for (z=0;zm_oaConditions.GetSize();z2++) if (((CNbSearch*)sg->m_oaConditions[z2])->m_iNbCountMin != -1) m_bNeedNbCountMode = true; }*/ m_iHistoGes = 0; try {m_pHistogram = new unsigned long[((CMolecule*)g_oaMolecules[sm])->m_laSingleMolIndex.GetSize()+1]; } catch(...) { m_pHistogram = NULL; } if (m_pHistogram == NULL) NewException((double)((CMolecule*)g_oaMolecules[sm])->m_laSingleMolIndex.GetSize()+1*sizeof(unsigned long),__FILE__,__LINE__,__PRETTY_FUNCTION__); for (z=0;z<((CMolecule*)g_oaMolecules[sm])->m_laSingleMolIndex.GetSize()+1;z++) m_pHistogram[z] = 0; BTOUT; } void CConditionGroup::PrintData() { int z; mprintf(GREEN,"\n>>> Condition Data >>>\n\n"); mprintf(" %.0f of %.0f molecules passed the conditions (%.2f percent).\n",m_fPassed,m_fTotal,ZeroDivide(m_fPassed,m_fTotal)*100.0); if (m_fPassed == 0) { mprintf(YELLOW,"\n No molecules at all passed the condition.\n"); mprintf(" This is probably not what you wanted.\n"); } else { mprintf(YELLOW,"\nList of reference molecules (%s) that passed the conditions:\n\n",((CMolecule*)g_oaMolecules[m_iRefMol])->m_sName); for (z=0;z<((CMolecule*)g_oaMolecules[m_iRefMol])->m_laSingleMolIndex.GetSize();z++) if (m_iRMPassCounter[z] > 0) mprintf(" - %2d: %10.4f percent of the time (%ld hits)\n",z+1,((double)m_iRMPassCounter[z])/g_iSteps*100.0,m_iRMPassCounter[z]); mprintf(YELLOW,"\nList of observed molecules (%s) that passed the conditions:\n\n",((CMolecule*)g_oaMolecules[m_iShowMol])->m_sName); for (z=0;z<((CMolecule*)g_oaMolecules[m_iShowMol])->m_laSingleMolIndex.GetSize();z++) if (m_iOMPassCounter[z] > 0) mprintf(" - %2d: %10.4f percent of the time (%ld hits)\n",z+1,((double)m_iOMPassCounter[z])/g_iSteps*100.0,m_iOMPassCounter[z]); } mprintf(YELLOW,"\nNeighbor count histogram:\n\n"); for (z=0;z<((CMolecule*)g_oaMolecules[m_iShowMol])->m_laSingleMolIndex.GetSize()+1;z++) if (m_pHistogram[z] != 0) mprintf(" - %d Neighbors: %8.4f percent of the time (%lu hits).\n",z,((double)m_pHistogram[z])/m_iHistoGes*100.0,m_pHistogram[z]); mprintf(YELLOW,"\nListing for all sets of conditions:\n"); for (z=0;zPrintData(); mprintf(GREEN,"\n<<< End of Condition Data <<<\n\n"); } void CConditionGroup::PrintData(const char *s) { int z; FILE *a; mprintf(GREEN,"\n>>> Condition Data >>>\n\n"); mprintf(" %.0f of %.0f molecules passed the conditions (%.2f percent).\n",m_fPassed,m_fTotal,ZeroDivide(m_fPassed,m_fTotal)*100.0); if (m_fPassed == 0) { mprintf("\n No molecules at all passed the condition.\n"); mprintf(" This is probably not what you wanted.\n"); } mprintf("\nNeighbor count histogram:\n\n"); for (z=0;z<((CMolecule*)g_oaMolecules[m_iShowMol])->m_laSingleMolIndex.GetSize()+1;z++) if (m_pHistogram[z] != 0) mprintf(" - %d Neighbors: %8.4f percent of the time (%lu hits).\n",z,((double)m_pHistogram[z])/m_iHistoGes*100.0,m_pHistogram[z]); mprintf("\n Saving detailed condition data as \"%s\"...\n",s); a = OpenFileWrite(s,true); mfprintf(a,"\n>>> Condition Data >>>\n\n"); mfprintf(a," %.0f of %.0f molecules passed the conditions (%.2f percent).\n",m_fPassed,m_fTotal,ZeroDivide(m_fPassed,m_fTotal)*100.0); if (m_fPassed == 0) { mfprintf(a,"\n No molecules at all passed the condition.\n"); mfprintf(a," This is probably not what you wanted.\n"); } else { mfprintf(a,"\nList of reference molecules (%s) that passed the conditions:\n\n",((CMolecule*)g_oaMolecules[m_iRefMol])->m_sName); for (z=0;z<((CMolecule*)g_oaMolecules[m_iRefMol])->m_laSingleMolIndex.GetSize();z++) if (m_iRMPassCounter[z] > 0) mfprintf(a," - %2d: %10.4f percent of the time (%lu hits)\n",z+1,((double)m_iRMPassCounter[z])/g_iSteps*100.0,m_iRMPassCounter[z]); mfprintf(a,"\nList of observed molecules (%s) that passed the conditions:\n\n",((CMolecule*)g_oaMolecules[m_iShowMol])->m_sName); for (z=0;z<((CMolecule*)g_oaMolecules[m_iShowMol])->m_laSingleMolIndex.GetSize();z++) if (m_iOMPassCounter[z] > 0) mfprintf(a," - %2d: %10.4f percent of the time (%lu hits)\n",z+1,((double)m_iOMPassCounter[z])/g_iSteps*100.0,m_iOMPassCounter[z]); } mfprintf(a,"\nNeighbor count histogram:\n\n"); for (z=0;z<((CMolecule*)g_oaMolecules[m_iShowMol])->m_laSingleMolIndex.GetSize()+1;z++) if (m_pHistogram[z] != 0) mfprintf(a," - %d Neighbors: %8.4f percent of the time (%lu hits).\n",z,((double)m_pHistogram[z])/m_iHistoGes*100.0,m_pHistogram[z]); mfprintf(a,"\nListing for all sets of conditions:\n"); for (z=0;zPrintData(a); mfprintf(a,"\n<<< End of Condition Data <<<\n\n"); fclose(a); mprintf(GREEN,"\n<<< End of Condition Data <<<\n\n"); } bool CConditionSubGroup::Contains(int mol) { BXIN; int z; for (z=0;zm_bPassed[mol]) { BXOUT; return false; } } BXOUT; return true; } void CConditionSubGroup::MarkPassedAtoms(int om) { int z, z2; for (z=0;zMarkPassedAtoms(om); for (z2=0;z2ScanAllOM(rm,t); for (z=0;z<((CMolecule*)g_oaMolecules[m_iShowMol])->m_laSingleMolIndex.GetSize();z++) { m_fTotal++; for (z2=0;z2m_bPassed[z]) goto _nopass; m_fPassed++; _nopass:; } } void CConditionSubGroup::PreScanNeighborhoodAllOM(CTimeStep *t, CSingleMolecule *rm) { int z; // mprintf("@@ Subgroup %08X\n",this); for (z=0;zPreScanAllOM(rm,t); } } void CConditionSubGroup::Parse(int rm, int sm) { BTIN; CNbSearch *n; m_iCombinations = 0; do { try { n = new CNbSearch(); } catch(...) { n = NULL; } if (n == NULL) NewException((double)sizeof(CNbSearch),__FILE__,__LINE__,__PRETTY_FUNCTION__); n->m_iNumber = m_oaConditions.GetSize(); m_oaConditions.Add(n); n->Parse(rm,sm,false); m_iCombinations += n->m_iCombinationsEnabled; } while (AskYesNo(" Add another condition to this set of conditions (y/n)? [no] ",false)); try { m_bTempPassed = new bool[g_iGesVirtAtomCount]; } catch(...) { m_bTempPassed = NULL; } if (m_bTempPassed == NULL) NewException((double)g_iGesVirtAtomCount*sizeof(bool),__FILE__,__LINE__,__PRETTY_FUNCTION__); BTOUT; } void CADF::ParseCondition(int rm, bool nocrit) { BTIN; // char buf[1024]; CxString buf; int z, z2, ti; CAtomGroup *ag; mprintf(WHITE,"\n>>> Angular Condition >>>\n"); for (z=0;z<2;z++) m_iVecType[z] = 0; z2 = 0; m_iCombinations = 0; do { ti = 1; if (z2 != 0) mprintf("\n %d. set of vectors\n\n",z2+1); for (z=0;z<2;z++) { /* if (z == 1) m_bSameFoot = AskYesNo(" Should the base points of the 1st and 2nd vectors always be equal (y/n)? [no] ",false); else m_bSameFoot = false;*/ m_bOrtho[z] = (AskRangeInteger("\n Should the %d. vector connect two points (0) or stand perpendicular on 3 points (1)? [0] ",0,1,0,z+1) != 0); mprintf("\n"); if (m_bOrtho[z]) { /* if (m_bSameFoot && (z == 1)) { m_iRefOrSec[1][0] = m_iRefOrSec[0][0]; m_oaVectors.Add(NULL); } else*/ { _ax1: if (m_iShowMol != -1) m_iRefOrSec[z][0] = AskRangeInteger(" Take atom(s) in base point from 1st mol. %s (0) or from 2nd mol. %s (1)? [%d] ",0,1,z,((CMolecule*)g_oaMolecules[rm])->m_sName,((CMolecule*)g_oaMolecules[m_iShowMol])->m_sName,z); else m_iRefOrSec[z][0] = 0; mprintf(" Enter atom(s) in the base point (e.g. C7): "); inpprintf("! Enter atom(s) in the base point (e.g. C7):\n"); myget(&buf); try { ag = new CAtomGroup(); } catch(...) { ag = NULL; } if (ag == NULL) NewException((double)sizeof(CAtomGroup),__FILE__,__LINE__,__PRETTY_FUNCTION__); if (!ag->ParseAtoms((!m_iRefOrSec[z][0])?(CMolecule*)g_oaMolecules[rm]:(CMolecule*)g_oaMolecules[m_iShowMol],buf)) { eprintf("Invalid input.\n"); inpprintf("! Invalid input.\n"); delete ag; goto _ax1; } m_oaVectors.Add(ag); ti *= ag->m_iAtomGes; } _ax2: if (m_iShowMol != -1) m_iRefOrSec[z][1] = AskRangeInteger(" Take 2nd atom(s) of normal plane from 1st mol. %s (0) or from 2nd mol. %s (1)? [%d] ",0,1,z,((CMolecule*)g_oaMolecules[rm])->m_sName,((CMolecule*)g_oaMolecules[m_iShowMol])->m_sName,z); else m_iRefOrSec[z][1] = 0; mprintf(" Enter 2nd atom(s) of normal plane (e.g. C7): "); inpprintf("! Enter 2nd atom(s) of normal plane (e.g. C7):\n"); myget(&buf); try { ag = new CAtomGroup(); } catch(...) { ag = NULL; } if (ag == NULL) NewException((double)sizeof(CAtomGroup),__FILE__,__LINE__,__PRETTY_FUNCTION__); if (!ag->ParseAtoms((!m_iRefOrSec[z][1])?(CMolecule*)g_oaMolecules[rm]:(CMolecule*)g_oaMolecules[m_iShowMol],buf)) { eprintf("Invalid input.\n"); inpprintf("! Invalid input.\n"); delete ag; goto _ax2; } m_oaVectors.Add(ag); ti *= ag->m_iAtomGes; _ax3: if (m_iShowMol != -1) m_iRefOrSec[z][2] = AskRangeInteger(" Take 3rd atom(s) of normal plane from 1st mol. %s (0) or from 2nd mol. %s (1)? [%d] ",0,1,z,((CMolecule*)g_oaMolecules[rm])->m_sName,((CMolecule*)g_oaMolecules[m_iShowMol])->m_sName,z); else m_iRefOrSec[z][2] = 0; mprintf(" Enter 3rd atom(s) of normal plane (e.g. C7): "); inpprintf("! Enter 3rd atom(s) of normal plane (e.g. C7):\n"); myget(&buf); try { ag = new CAtomGroup(); } catch(...) { ag = NULL; } if (ag == NULL) NewException((double)sizeof(CAtomGroup),__FILE__,__LINE__,__PRETTY_FUNCTION__); if (!ag->ParseAtoms((!m_iRefOrSec[z][2])?(CMolecule*)g_oaMolecules[rm]:(CMolecule*)g_oaMolecules[m_iShowMol],buf)) { eprintf("Invalid input.\n"); inpprintf("! Invalid input.\n"); delete ag; goto _ax3; } m_oaVectors.Add(ag); ti *= ag->m_iAtomGes; } else // IF NOT ORTHO { /* if (m_bSameFoot && (z == 1)) { m_iRefOrSec[1][0] = m_iRefOrSec[0][0]; m_oaVectors.Add(NULL); } else*/ { _ax4: if (m_iShowMol != -1) m_iRefOrSec[z][0] = AskRangeInteger(" Take atom(s) in base point from 1st mol. %s (0) or from 2nd mol. %s (1)? [%d] ",0,1,z,((CMolecule*)g_oaMolecules[rm])->m_sName,((CMolecule*)g_oaMolecules[m_iShowMol])->m_sName,z); else m_iRefOrSec[z][0] = 0; mprintf(" Enter atom(s) in the base point (e.g. C7): "); inpprintf("! Enter atom(s) in the base point (e.g. C7):\n"); myget(&buf); try { ag = new CAtomGroup(); } catch(...) { ag = NULL; } if (ag == NULL) NewException((double)sizeof(CAtomGroup),__FILE__,__LINE__,__PRETTY_FUNCTION__); if (!ag->ParseAtoms((!m_iRefOrSec[z][0])?(CMolecule*)g_oaMolecules[rm]:(CMolecule*)g_oaMolecules[m_iShowMol],buf)) { eprintf("Invalid input.\n"); inpprintf("! Invalid input.\n"); delete ag; goto _ax4; } m_oaVectors.Add(ag); ti *= ag->m_iAtomGes; } // END IF NOT SAMEFOOT _ax5: if (m_iShowMol != -1) m_iRefOrSec[z][1] = AskRangeInteger(" Take atom(s) in tip point from 1st mol. %s (0) or from 2nd mol. %s (1)? [%d] ",0,1,z,((CMolecule*)g_oaMolecules[rm])->m_sName,((CMolecule*)g_oaMolecules[m_iShowMol])->m_sName,z); else m_iRefOrSec[z][1] = 0; mprintf(" Enter atom(s) in the tip point (e.g. C7): "); inpprintf("! Enter atom(s) in the tip point (e.g. C7):\n"); myget(&buf); try { ag = new CAtomGroup(); } catch(...) { ag = NULL; } if (ag == NULL) NewException((double)sizeof(CAtomGroup),__FILE__,__LINE__,__PRETTY_FUNCTION__); if (!ag->ParseAtoms((!m_iRefOrSec[z][1])?(CMolecule*)g_oaMolecules[rm]:(CMolecule*)g_oaMolecules[m_iShowMol],buf)) { eprintf("Invalid input.\n"); inpprintf("! Invalid input.\n"); delete ag; goto _ax5; } m_oaVectors.Add(ag); ti *= ag->m_iAtomGes; m_oaVectors.Add(NULL); } // END IF NOT ORTHO } // END FOR 0..1 m_iCombinations += ti; z2++; } while (AskYesNo("\n Enter another set of vectors (y/n)? [no] ",false)); if (!nocrit) { do { m_faMinMaxAngle.Add(AskFloat(" Enter minimal angle between the vectors in degree: [0.0] ",0.0)); m_faMinMaxAngle.Add(AskFloat(" Enter maximal angle between the vectors in degree: [180.0] ",180.0)); } while (AskYesNo(" Enter another angle interval (y/n)? [no] ",false)); } else { m_faMinMaxAngle.Add(0.0); m_faMinMaxAngle.Add(180.0); } mprintf(WHITE,"\n<<< End of Angular Condition <<<\n\n"); BTOUT; } void CADF::ParseConditionGrid(int rm, int gridmode) { BTIN; // char buf[1024]; CxString buf; int z, z2, ti; CAtomGroup *ag; mprintf(WHITE,"\n>>> Angular Condition >>>\n"); for (z=0;z<2;z++) m_iVecType[z] = 0; z2 = 0; m_iCombinations = 0; do { ti = 1; if (z2 != 0) mprintf("\n %d. set of vectors\n\n",z2+1); for (z=0;z<2;z++) { /* if (z == 1) m_bSameFoot = AskYesNo(" Should the base points of the 1st and 2nd vectors always be equal (y/n)? [no] ",false); else m_bSameFoot = false;*/ m_bOrtho[z] = (AskRangeInteger("\n Should the %d. vector connect two points (0) or stand perpendicular on 3 points (1)? [0] ",0,1,0,z+1) != 0); mprintf("\n"); if (m_bOrtho[z]) { /* if (m_bSameFoot && (z == 1)) { m_iRefOrSec[1][0] = m_iRefOrSec[0][0]; m_oaVectors.Add(NULL); } else*/ { _ax1: if (m_iShowMol != -1) m_iRefOrSec[z][0] = AskRangeInteger(" Take atom(s) in base point from 1st mol. %s (0) or from 2nd mol. %s (1)? [%d] ",0,1,z,((CMolecule*)g_oaMolecules[rm])->m_sName,((CMolecule*)g_oaMolecules[m_iShowMol])->m_sName,z); else m_iRefOrSec[z][0] = 0; mprintf(" Enter atom(s) in the base point (e.g. C7): "); inpprintf("! Enter atom(s) in the base point (e.g. C7):\n"); myget(&buf); try { ag = new CAtomGroup(); } catch(...) { ag = NULL; } if (ag == NULL) NewException((double)sizeof(CAtomGroup),__FILE__,__LINE__,__PRETTY_FUNCTION__); m_oaVectors.Add(ag); if (!ag->ParseAtoms((!m_iRefOrSec[z][0])?(CMolecule*)g_oaMolecules[rm]:(CMolecule*)g_oaMolecules[m_iShowMol],buf)) { eprintf("Invalid input.\n"); inpprintf("! Invalid input.\n"); goto _ax1; } ti *= ag->m_iAtomGes; } _ax2: if (m_iShowMol != -1) m_iRefOrSec[z][1] = AskRangeInteger(" Take 2nd atom(s) of normal plane from 1st mol. %s (0) or from 2nd mol. %s (1)? [%d] ",0,1,z,((CMolecule*)g_oaMolecules[rm])->m_sName,((CMolecule*)g_oaMolecules[m_iShowMol])->m_sName,z); else m_iRefOrSec[z][1] = 0; mprintf(" Enter 2nd atom(s) of normal plane (e.g. C7): "); inpprintf("! Enter 2nd atom(s) of normal plane (e.g. C7):\n"); myget(&buf); try { ag = new CAtomGroup(); } catch(...) { ag = NULL; } if (ag == NULL) NewException((double)sizeof(CAtomGroup),__FILE__,__LINE__,__PRETTY_FUNCTION__); m_oaVectors.Add(ag); if (!ag->ParseAtoms((!m_iRefOrSec[z][1])?(CMolecule*)g_oaMolecules[rm]:(CMolecule*)g_oaMolecules[m_iShowMol],buf)) { eprintf("Invalid input.\n"); inpprintf("! Invalid input.\n"); goto _ax2; } ti *= ag->m_iAtomGes; _ax3: if (m_iShowMol != -1) m_iRefOrSec[z][2] = AskRangeInteger(" Take 3rd atom(s) of normal plane from 1st mol. %s (0) or from 2nd mol. %s (1)? [%d] ",0,1,z,((CMolecule*)g_oaMolecules[rm])->m_sName,((CMolecule*)g_oaMolecules[m_iShowMol])->m_sName,z); else m_iRefOrSec[z][2] = 0; mprintf(" Enter 3rd atom(s) of normal plane (e.g. C7): "); inpprintf("! Enter 3rd atom(s) of normal plane (e.g. C7):\n"); myget(&buf); try { ag = new CAtomGroup(); } catch(...) { ag = NULL; } if (ag == NULL) NewException((double)sizeof(CAtomGroup),__FILE__,__LINE__,__PRETTY_FUNCTION__); m_oaVectors.Add(ag); if (!ag->ParseAtoms((!m_iRefOrSec[z][2])?(CMolecule*)g_oaMolecules[rm]:(CMolecule*)g_oaMolecules[m_iShowMol],buf)) { eprintf("Invalid input.\n"); inpprintf("! Invalid input.\n"); goto _ax3; } ti *= ag->m_iAtomGes; } else // IF NOT ORTHO { /* if (m_bSameFoot && (z == 1)) { m_iRefOrSec[1][0] = m_iRefOrSec[0][0]; m_oaVectors.Add(NULL); } else*/ { _ax4: if (m_iShowMol != -1) m_iRefOrSec[z][0] = AskRangeInteger(" Take atom(s) in base point from 1st mol. %s (0) or from 2nd mol. %s (1)? [%d] ",0,1,z,((CMolecule*)g_oaMolecules[rm])->m_sName,((CMolecule*)g_oaMolecules[m_iShowMol])->m_sName,z); else m_iRefOrSec[z][0] = 0; mprintf(" Enter atom(s) in the base point (e.g. C7): "); inpprintf("! Enter atom(s) in the base point (e.g. C7):\n"); myget(&buf); try { ag = new CAtomGroup(); } catch(...) { ag = NULL; } if (ag == NULL) NewException((double)sizeof(CAtomGroup),__FILE__,__LINE__,__PRETTY_FUNCTION__); m_oaVectors.Add(ag); if (!ag->ParseAtoms((!m_iRefOrSec[z][0])?(CMolecule*)g_oaMolecules[rm]:(CMolecule*)g_oaMolecules[m_iShowMol],buf)) { eprintf("Invalid input.\n"); inpprintf("! Invalid input.\n"); goto _ax4; } ti *= ag->m_iAtomGes; } // END IF NOT SAMEFOOT _ax5: if (m_iShowMol != -1) m_iRefOrSec[z][1] = AskRangeInteger(" Take atom(s) in tip point from 1st mol. %s (0) or from 2nd mol. %s (1)? [%d] ",0,1,z,((CMolecule*)g_oaMolecules[rm])->m_sName,((CMolecule*)g_oaMolecules[m_iShowMol])->m_sName,z); else m_iRefOrSec[z][1] = 0; mprintf(" Enter atom(s) in the tip point (e.g. C7): "); inpprintf("! Enter atom(s) in the tip point (e.g. C7):\n"); myget(&buf); try { ag = new CAtomGroup(); } catch(...) { ag = NULL; } if (ag == NULL) NewException((double)sizeof(CAtomGroup),__FILE__,__LINE__,__PRETTY_FUNCTION__); m_oaVectors.Add(ag); if (!ag->ParseAtoms((!m_iRefOrSec[z][1])?(CMolecule*)g_oaMolecules[rm]:(CMolecule*)g_oaMolecules[m_iShowMol],buf)) { eprintf("Invalid input.\n"); inpprintf("! Invalid input.\n"); goto _ax5; } ti *= ag->m_iAtomGes; m_oaVectors.Add(NULL); } // END IF NOT ORTHO } // END FOR 0..1 m_iCombinations += ti; z2++; } while (AskYesNo("\n Enter another set of vectors (y/n)? [no] ",false)); if ((gridmode == 1) || (gridmode == 6)) { m_faMinMaxAngle.Add(AskFloat(" Enter minimal angle between the vectors in degree: [0.0] ",0.0)); m_faMinMaxAngle.Add(AskFloat(" Enter maximal angle between the vectors in degree: [180.0] ",180.0)); } else { m_faMinMaxAngle.Add(0.0); m_faMinMaxAngle.Add(180.0); } mprintf(WHITE,"\n<<< End of Angular Condition <<<\n\n"); BTOUT; } void CADF::ParseCondition_OnlyValues() { BTIN; int z; mprintf(" Angular condition between vectors:\n"); for (z=0;zm_sName,((CAtomGroup*)m_oaVectors[z*6+1])->m_sName,((CAtomGroup*)m_oaVectors[z*6+2])->m_sName); else mprintf("(%s --> %s)",((CAtomGroup*)m_oaVectors[z*6])->m_sName,((CAtomGroup*)m_oaVectors[z*6+1])->m_sName); mprintf(" and "); if (m_oaVectors[z*6+5] != NULL) mprintf("normal(%s, %s, %s)",((CAtomGroup*)m_oaVectors[z*6+3])->m_sName,((CAtomGroup*)m_oaVectors[z*6+4])->m_sName,((CAtomGroup*)m_oaVectors[z*6+5])->m_sName); else mprintf("(%s --> %s)",((CAtomGroup*)m_oaVectors[z*6+3])->m_sName,((CAtomGroup*)m_oaVectors[z*6+4])->m_sName); mprintf("\n"); } for (z=0;zm_fAtomCode = 10.0 * ((CAtom*)g_oaAtoms[m_baAtomIndex[ma->m_iType]])->m_pElement->m_fMass; ma->m_liAtomCode = int(((CAtom*)g_oaAtoms[m_baAtomIndex[ma->m_iType]])->m_pElement->m_fMass*10.0); i = 0; for (z2=0;z2m_oaBonds.GetSize();z2++) { // Alle Wasserstoff-Atome ueberspringen if (((CAtom*)g_oaAtoms[m_baAtomIndex[((CMolAtom*)ma->m_oaBonds[z2])->m_iType]])->m_pElement->m_fMass < 4.5) continue; ma->m_fAtomCode++; ma->m_liAtomCode++; i++; } if (g_bVerbose) { mprintf(" Atom %d (%s%d): 10.0 * %.2f + %d = %.2f (",z+1,(const char*)((CAtom*)g_oaAtoms[m_baAtomIndex[ma->m_iType]])->m_sName,ma->m_iOffset+1,((CAtom*)g_oaAtoms[m_baAtomIndex[ma->m_iType]])->m_pElement->m_fMass,i,ma->m_fAtomCode); ma->m_liAtomCode.mprintf(10); mprintf(")\n"); } } i = 0; do { c1 = CountDifferentAtomCodes(); if (g_bVerbose) mprintf(WHITE,"\n Cycle %d: %d different atom codes exist.\n\n",i+1,c1); for (z=0;zm_fTempAtomCode = ma->m_fAtomCode * 5.0; ma->m_liTempAtomCode = ma->m_liAtomCode * 5; for (z2=0;z2m_oaBonds.GetSize();z2++) { ma->m_fTempAtomCode += ((CMolAtom*)ma->m_oaBonds[z2])->m_fAtomCode; ma->m_liTempAtomCode += ((CMolAtom*)ma->m_oaBonds[z2])->m_liAtomCode; } } for (z=0;zm_fAtomCode = ma->m_fTempAtomCode; ma->m_liAtomCode = ma->m_liTempAtomCode; if (g_bVerbose) { mprintf(" Atom %d (%s%d): %.2f (",z+1,(const char*)((CAtom*)g_oaAtoms[m_baAtomIndex[ma->m_iType]])->m_sName,ma->m_iOffset+1,ma->m_fAtomCode); ma->m_liAtomCode.mprintf(10); mprintf(")\n"); } } c2 = CountDifferentAtomCodes(); i++; // mprintf("Iteration %d: %d classes before, %d classes after.\n",i,c1,c2); } while (c1 != c2); if (g_bVerbose) mprintf(WHITE,"\nSorting...\n"); m_iAtomClasses = c2; // mprintf("Finished.\n"); // mprintf("%d Iterations, %d atom classes found.\n",i,c2); // mprintf("Sorting Atom Codes..."); // Sortieren mittels StackSort if (m_oaMolAtoms.GetSize() > 1) { for (z=0;zm_liAtomCode > li) { li = ((CMolAtom*)m_oaMolAtoms[z2])->m_liAtomCode; i = z2; } } if (i != -1) { ma = (CMolAtom*)m_oaMolAtoms[z]; m_oaMolAtoms[z] = m_oaMolAtoms[i]; m_oaMolAtoms[i] = ma; ((CMolAtom*)m_oaMolAtoms[z])->m_iMolAtomNumber = z; } else { eprintf("CSingleMolecule::BuildAtomCodes(): Internal error (%d, %d).\n",z,m_oaMolAtoms.GetSize()); return; } } } if (g_bVerbose) { for (z=0;zm_iType]])->m_sName,ma->m_iOffset+1,ma->m_fAtomCode); ma->m_liAtomCode.mprintf(10); mprintf(")\n"); } mprintf(WHITE,"Finished.\n\n"); } // mprintf("Finished.\n"); } int CSingleMolecule::CountDifferentAtomCodes() { int z, z2, i; //double *d; LargeInteger *li; //try { d = new double[m_oaMolAtoms.GetSize()]; } catch(...) { d = NULL; } //if (d == NULL) NewException((double)m_oaMolAtoms.GetSize()*sizeof(double),__FILE__,__LINE__,__PRETTY_FUNCTION__); try { li = new LargeInteger[m_oaMolAtoms.GetSize()]; } catch(...) { li = NULL; } if (li == NULL) NewException((double)m_oaMolAtoms.GetSize()*sizeof(LargeInteger),__FILE__,__LINE__,__PRETTY_FUNCTION__); i = 0; for (z=0;zm_liAtomCode) goto _next; li[i] = ((CMolAtom*)m_oaMolAtoms[z])->m_liAtomCode; i++; _next:; } //delete[] d; delete[] li; return i; } void CMSD::Parse() { // char buf[1024]; CxString buf; int ti; BTIN; try { m_pMSD = new CAF(); } catch(...) { m_pMSD = NULL; } if (m_pMSD == NULL) NewException((double)sizeof(CAF),__FILE__,__LINE__,__PRETTY_FUNCTION__); mprintf(WHITE,"\n*** Mean Square Displacement\n\n"); try { m_pAtomGroup = new CAtomGroup(); } catch(...) { m_pAtomGroup = NULL; } if (m_pAtomGroup == NULL) NewException((double)sizeof(CAtomGroup),__FILE__,__LINE__,__PRETTY_FUNCTION__); if (((CMolecule*)g_oaMolecules[m_iShowMol])->m_iAtomGesNoVirt == 1) { mprintf(" %s consists only of one atom, no choice.\n",((CMolecule*)g_oaMolecules[m_iShowMol])->m_sName); goto _oneatom; } _rdfatom1: mprintf(" Which atom(s) to take from OM %s (e.g. \"C1,C3-5,H\", \"*\"=all)? [#2] ",((CMolecule*)g_oaMolecules[m_iShowMol])->m_sName); inpprintf("! Which atom(s) to take from OM %s (e.g. \"C1,C3-5,H\", \"*\"=all)? [#2]\n",((CMolecule*)g_oaMolecules[m_iShowMol])->m_sName); myget(&buf); if (strlen(buf) == 0) { _oneatom: if (!m_pAtomGroup->ParseAtoms((CMolecule*)g_oaMolecules[m_iShowMol],"#2")) { eprintf("CMSD::Parse(): Internal error.\n"); inpprintf("! CMSD::Parse(): Internel error.\n"); goto _rdfatom1; } } else if (!m_pAtomGroup->ParseAtoms((CMolecule*)g_oaMolecules[m_iShowMol],buf)) { eprintf("Invalid input.\n"); inpprintf("! Invalid input.\n"); goto _rdfatom1; } //_depth: if (g_iTrajSteps != -1) m_iResolution = AskUnsignedInteger(" Enter the resolution (=depth) for this MSD (in time steps): [%d] ",int(g_iTrajSteps*0.5),int(g_iTrajSteps*0.5)); else m_iResolution = AskUnsignedInteger(" Enter the resolution (=depth) for this MSD (in time steps): [10000] ",10000); m_iShowAtoms = m_pAtomGroup->m_iAtomGes; /* if (g_iTrajSteps != -1) { if (g_bMSDCacheMode) { tf = g_iTrajSteps*m_pAtomGroup->m_iAtomGes*((CMolecule*)g_oaMolecules[m_iShowMol])->m_laSingleMolIndex.GetSize()*3.0f*sizeof(double)/1024.0f/1024.0f; if (tf >= 10.0f) if (!AskYesNo(" This will occupy %.0f MB RAM (once, not for every MSD!). Continue (y/n)? [yes] ",true,tf)) goto _depth; } else { tf = m_iResolution*g_iGesVirtAtomCount*12.0f*sizeof(double)/1024.0f/1024.0f; if (tf >= 10.0f) if (!AskYesNo(" This will occupy %.0f MB RAM (once, not for every MSD!). Continue (y/n)? [yes] ",true,tf)) goto _depth; } }*/ /* if (m_iResolution > g_iMaxMSDDepth) g_iMaxMSDDepth = m_iReolution;*/ ti = m_iResolution / 1000; if (ti < 1) ti = 1; m_iStride = AskUnsignedInteger(" Take every n-th step for the time axis of the MSD: [%d] ",ti,ti); m_iStride2 = AskUnsignedInteger(" Shift correlation window n time steps at once: [%d] ",m_iStride,m_iStride); if (g_bAdvanced2) { m_bSplit = AskYesNo(" Decompose this MSD into contributions from each individual molecule (y/n)? [no] ",false); if (AskYesNo(" Take into account only certain dimensions for displacement (y/n)? [no] ",false)) { m_bTakeX = AskYesNo(" Take into account contributions along X axis (y/n)? [yes] ",true); m_bTakeY = AskYesNo(" Take into account contributions along Y axis (y/n)? [yes] ",true); m_bTakeZ = AskYesNo(" Take into account contributions along Z axis (y/n)? [yes] ",true); } else { m_bTakeX = true; m_bTakeY = true; m_bTakeZ = true; } } else { m_bSplit = false; m_bTakeX = true; m_bTakeY = true; m_bTakeZ = true; } BuildName(); BTOUT; } void CMSD::BuildName() { BTIN; // char tmp[32768]; CxString tmp; // sprintf(tmp,"%s_%s",((CMolecule*)g_oaMolecules[m_iShowMol])->m_sName,m_pAtomGroup->m_sName); tmp.sprintf("%s_%s",((CMolecule*)g_oaMolecules[m_iShowMol])->m_sName,m_pAtomGroup->m_sName); if ((!m_bTakeX) || (!m_bTakeY) || (!m_bTakeZ)) { // strcat(tmp,"_"); tmp.strcat("_"); if (m_bTakeX) // strcat(tmp,"X"); tmp.strcat("X"); if (m_bTakeY) // strcat(tmp,"Y"); tmp.strcat("Y"); if (m_bTakeZ) // strcat(tmp,"Z"); tmp.strcat("Z"); } try { m_sName = new char[strlen(tmp)+1]; } catch(...) { m_sName = NULL; } if (m_sName == NULL) NewException((double)(strlen(tmp)+1)*sizeof(char),__FILE__,__LINE__,__PRETTY_FUNCTION__); strcpy(m_sName,tmp); BTOUT; } void CVHDF::CorrectCount() { int x, y, ti; ti = m_iDepth/m_iStride; for (y=0;ym_pBin[y*ti+x] /= m_pCount[x]; } void CConditionSubGroup::PrintData() { int z; double d; mprintf(GREEN,"\n*** Data for %d. set of conditions ***\n\n",m_iNumber+1); mprintf(" %.0f of %.0f molecules passed this set of conditions (%.4f percent).\n",m_fPassed,m_fTotal,ZeroDivide(m_fPassed,m_fTotal)*100.0); d = 1.0; for (z=0;zm_fMoleculesPassed,((CNbSearch*)m_oaConditions[z])->m_fMoleculesTotal,ZeroDivide(((CNbSearch*)m_oaConditions[z])->m_fMoleculesPassed,((CNbSearch*)m_oaConditions[z])->m_fMoleculesTotal)*100.0); d *= ZeroDivide(((CNbSearch*)m_oaConditions[z])->m_fMoleculesPassed,((CNbSearch*)m_oaConditions[z])->m_fMoleculesTotal); } mprintf("\n"); if (m_oaConditions.GetSize() > 1) { mprintf(" The product of the condition probabilities is %.4f percent.\n",d*100.0); mprintf(" If the conditions would be uncorrelated, this would be also the probability for the set.\n"); mprintf(" Therefore, the conditions are %s correlated for %.4f percent.\n\n",(dPrintTable(); } void CConditionSubGroup::PrintData(FILE *a) { int z; mfprintf(a,"\n*** Data for %d. set of conditions ***\n\n",m_iNumber+1); mfprintf(a," %.0f of %.0f molecules passed this set of conditions (%.4f percent).\n",m_fPassed,m_fTotal,ZeroDivide(m_fPassed,m_fTotal)*100.0); for (z=0;zPrintTable(a); } void CConditionSubGroup::PrintSingle(int om) { int z; for (z=0;zPrintSingle(om); } void CConditionGroup::PrintSingle(int om) { int z; for (z=0;zPrintSingle(om); } void CConditionGroup::PrintTable() { int z, z2; double tf1, tf2, tf3; mprintf(WHITE,"*** Condition Table ***\n\n"); mprintf(" The rows indicate how many subconditions of condition 1 are fulfilled.\n"); mprintf(" The columns indicate how many subconditions of condition 2 are fulfilled.\n\n"); mprintf(" "); for (z=0;z<((CConditionSubGroup*)m_oaConditionSubGroups[1])->m_iCombinations+1;z++) mprintf("| %4d ",z); mprintf("\n"); mprintf("-----"); for (z=0;z<((CConditionSubGroup*)m_oaConditionSubGroups[1])->m_iCombinations+1;z++) mprintf("|---------"); mprintf("\n"); tf1 = 0; tf2 = 0; tf3 = 0; for (z=0;z<((CConditionSubGroup*)m_oaConditionSubGroups[0])->m_iCombinations+1;z++) { mprintf(" %3d ",z); for (z2=0;z2<((CConditionSubGroup*)m_oaConditionSubGroups[1])->m_iCombinations+1;z2++) { if ((z > 0) && (z2 == 0)) tf1 += m_pTable[z*(((CConditionSubGroup*)m_oaConditionSubGroups[1])->m_iCombinations+1)+z2]; if ((z == 0) && (z2 > 0)) tf2 += m_pTable[z*(((CConditionSubGroup*)m_oaConditionSubGroups[1])->m_iCombinations+1)+z2]; if ((z > 0) && (z2 > 0)) tf3 += m_pTable[z*(((CConditionSubGroup*)m_oaConditionSubGroups[1])->m_iCombinations+1)+z2]; mprintf("| %7.3f ",m_pTable[z*(((CConditionSubGroup*)m_oaConditionSubGroups[1])->m_iCombinations+1)+z2]/m_fTableGes*100.0); } mprintf("\n"); } mprintf("\n"); mprintf(" A RM/OM pair fulfills no condition: %7.3f percent of the time.\n",m_pTable[0]/m_fTableGes*100.0); mprintf(" A RM/OM pair fulfills only condition 1: %7.3f percent of the time.\n",tf1/m_fTableGes*100.0); mprintf(" A RM/OM pair fulfills only condition 2: %7.3f percent of the time.\n",tf2/m_fTableGes*100.0); mprintf(" A RM/OM pair fulfills both conditions: %7.3f percent of the time.\n",tf3/m_fTableGes*100.0); mprintf(" Total: %7.3f percent of the time.\n",100.0); mprintf("\n"); mprintf(WHITE,"*** Condition Table End ***\n\n"); } void CObservation::ListCDFObservations(int z) { int z2, ti, ti2, ti3; CxIntArray tempwa; switch(g_iObsChannel[z]) { case 0: // RDF if (m_bOthers) { if (m_bSecondShowMol && (z == 1)) m_pRDF[z]->BuildAtomList((CSingleMolecule*)g_oaSingleMolecules[((CMolecule*)g_oaMolecules[g_iFixMol])->m_laSingleMolIndex[0]],(CSingleMolecule*)g_oaSingleMolecules[((CMolecule*)g_oaMolecules[m_iShowMol2])->m_laSingleMolIndex[0]],&tempwa); else m_pRDF[z]->BuildAtomList((CSingleMolecule*)g_oaSingleMolecules[((CMolecule*)g_oaMolecules[g_iFixMol])->m_laSingleMolIndex[0]],(CSingleMolecule*)g_oaSingleMolecules[((CMolecule*)g_oaMolecules[m_iShowMol])->m_laSingleMolIndex[0]],&tempwa); } else m_pRDF[z]->BuildAtomList((CSingleMolecule*)g_oaSingleMolecules[((CMolecule*)g_oaMolecules[g_iFixMol])->m_laSingleMolIndex[0]],(CSingleMolecule*)g_oaSingleMolecules[((CMolecule*)g_oaMolecules[g_iFixMol])->m_laSingleMolIndex[0]],&tempwa); for (z2=0;z2 %s%d (%s)\n",z2+1,(const char*)((CAtom*)g_oaAtoms[g_waAtomRealElement[ti]])->m_sName,g_waAtomMolNumber[ti]+1,((CMolecule*)g_oaMolecules[g_waAtomMolIndex[ti]])->m_sName,(const char*)((CAtom*)g_oaAtoms[g_waAtomRealElement[ti2]])->m_sName,g_waAtomMolNumber[ti2]+1,((CMolecule*)g_oaMolecules[g_waAtomMolIndex[ti2]])->m_sName); } break; case 1: // ADF if (m_bOthers) { if (m_bSecondShowMol && (z == 1)) m_pADF[z]->BuildAtomList((CSingleMolecule*)g_oaSingleMolecules[((CMolecule*)g_oaMolecules[g_iFixMol])->m_laSingleMolIndex[0]],(CSingleMolecule*)g_oaSingleMolecules[((CMolecule*)g_oaMolecules[m_iShowMol2])->m_laSingleMolIndex[0]],&tempwa); else m_pADF[z]->BuildAtomList((CSingleMolecule*)g_oaSingleMolecules[((CMolecule*)g_oaMolecules[g_iFixMol])->m_laSingleMolIndex[0]],(CSingleMolecule*)g_oaSingleMolecules[((CMolecule*)g_oaMolecules[m_iShowMol])->m_laSingleMolIndex[0]],&tempwa); } else m_pADF[z]->BuildAtomList((CSingleMolecule*)g_oaSingleMolecules[((CMolecule*)g_oaMolecules[g_iFixMol])->m_laSingleMolIndex[0]],(CSingleMolecule*)g_oaSingleMolecules[((CMolecule*)g_oaMolecules[g_iFixMol])->m_laSingleMolIndex[0]],&tempwa); for (z2=0;z2m_bOrtho[0]) { ti = tempwa[z2*6]; ti2 = tempwa[z2*6+1]; ti3 = tempwa[z2*6+2]; mprintf("[%s%d (%s), %s%d (%s), %s%d (%s)] to ",(const char*)((CAtom*)g_oaAtoms[g_waAtomRealElement[ti]])->m_sName,g_waAtomMolNumber[ti]+1,((CMolecule*)g_oaMolecules[g_waAtomMolIndex[ti]])->m_sName,(const char*)((CAtom*)g_oaAtoms[g_waAtomRealElement[ti2]])->m_sName,g_waAtomMolNumber[ti2]+1,((CMolecule*)g_oaMolecules[g_waAtomMolIndex[ti2]])->m_sName,(const char*)((CAtom*)g_oaAtoms[g_waAtomRealElement[ti3]])->m_sName,g_waAtomMolNumber[ti3]+1,((CMolecule*)g_oaMolecules[g_waAtomMolIndex[ti3]])->m_sName); } else { ti = tempwa[z2*6]; ti2 = tempwa[z2*6+1]; mprintf("[%s%d (%s) --> %s%d (%s)] to ",(const char*)((CAtom*)g_oaAtoms[g_waAtomRealElement[ti]])->m_sName,g_waAtomMolNumber[ti]+1,((CMolecule*)g_oaMolecules[g_waAtomMolIndex[ti]])->m_sName,(const char*)((CAtom*)g_oaAtoms[g_waAtomRealElement[ti2]])->m_sName,g_waAtomMolNumber[ti2]+1,((CMolecule*)g_oaMolecules[g_waAtomMolIndex[ti2]])->m_sName); } if (m_pADF[z]->m_bOrtho[1]) { ti = tempwa[z2*6+3]; ti2 = tempwa[z2*6+4]; ti3 = tempwa[z2*6+5]; mprintf("[%s%d (%s), %s%d (%s), %s%d (%s)]\n",(const char*)((CAtom*)g_oaAtoms[g_waAtomRealElement[ti]])->m_sName,g_waAtomMolNumber[ti]+1,((CMolecule*)g_oaMolecules[g_waAtomMolIndex[ti]])->m_sName,(const char*)((CAtom*)g_oaAtoms[g_waAtomRealElement[ti2]])->m_sName,g_waAtomMolNumber[ti2]+1,((CMolecule*)g_oaMolecules[g_waAtomMolIndex[ti2]])->m_sName,(const char*)((CAtom*)g_oaAtoms[g_waAtomRealElement[ti3]])->m_sName,g_waAtomMolNumber[ti3]+1,((CMolecule*)g_oaMolecules[g_waAtomMolIndex[ti3]])->m_sName); } else { ti = tempwa[z2*6+3]; ti2 = tempwa[z2*6+4]; mprintf("[%s%d (%s) --> %s%d (%s)]\n",(const char*)((CAtom*)g_oaAtoms[g_waAtomRealElement[ti]])->m_sName,g_waAtomMolNumber[ti]+1,((CMolecule*)g_oaMolecules[g_waAtomMolIndex[ti]])->m_sName,(const char*)((CAtom*)g_oaAtoms[g_waAtomRealElement[ti2]])->m_sName,g_waAtomMolNumber[ti2]+1,((CMolecule*)g_oaMolecules[g_waAtomMolIndex[ti2]])->m_sName); } } break; case 2: // DDF if (m_bOthers) { if (m_bSecondShowMol && (z == 1)) m_pDDF[z]->BuildAtomList((CSingleMolecule*)g_oaSingleMolecules[((CMolecule*)g_oaMolecules[g_iFixMol])->m_laSingleMolIndex[0]],(CSingleMolecule*)g_oaSingleMolecules[((CMolecule*)g_oaMolecules[m_iShowMol2])->m_laSingleMolIndex[0]],&tempwa); else m_pDDF[z]->BuildAtomList((CSingleMolecule*)g_oaSingleMolecules[((CMolecule*)g_oaMolecules[g_iFixMol])->m_laSingleMolIndex[0]],(CSingleMolecule*)g_oaSingleMolecules[((CMolecule*)g_oaMolecules[m_iShowMol])->m_laSingleMolIndex[0]],&tempwa); } else m_pDDF[z]->BuildAtomList((CSingleMolecule*)g_oaSingleMolecules[((CMolecule*)g_oaMolecules[g_iFixMol])->m_laSingleMolIndex[0]],(CSingleMolecule*)g_oaSingleMolecules[((CMolecule*)g_oaMolecules[g_iFixMol])->m_laSingleMolIndex[0]],&tempwa); for (z2=0;z2m_bOrtho[0]) { ti = tempwa[z2*9]; ti2 = tempwa[z2*9+1]; ti3 = tempwa[z2*9+2]; mprintf("[%s%d (%s), %s%d (%s), %s%d (%s)] - ",(const char*)((CAtom*)g_oaAtoms[g_waAtomRealElement[ti]])->m_sName,g_waAtomMolNumber[ti]+1,((CMolecule*)g_oaMolecules[g_waAtomMolIndex[ti]])->m_sName,(const char*)((CAtom*)g_oaAtoms[g_waAtomRealElement[ti2]])->m_sName,g_waAtomMolNumber[ti2]+1,((CMolecule*)g_oaMolecules[g_waAtomMolIndex[ti2]])->m_sName,(const char*)((CAtom*)g_oaAtoms[g_waAtomRealElement[ti3]])->m_sName,g_waAtomMolNumber[ti3]+1,((CMolecule*)g_oaMolecules[g_waAtomMolIndex[ti3]])->m_sName); } else { ti = tempwa[z2*9]; ti2 = tempwa[z2*9+1]; mprintf("[%s%d (%s) --> %s%d (%s)] - ",(const char*)((CAtom*)g_oaAtoms[g_waAtomRealElement[ti]])->m_sName,g_waAtomMolNumber[ti]+1,((CMolecule*)g_oaMolecules[g_waAtomMolIndex[ti]])->m_sName,(const char*)((CAtom*)g_oaAtoms[g_waAtomRealElement[ti2]])->m_sName,g_waAtomMolNumber[ti2]+1,((CMolecule*)g_oaMolecules[g_waAtomMolIndex[ti2]])->m_sName); } if (m_pDDF[z]->m_bOrtho[1]) { ti = tempwa[z2*9+3]; ti2 = tempwa[z2*9+4]; ti3 = tempwa[z2*9+5]; mprintf("[%s%d (%s), %s%d (%s), %s%d (%s)] - ",(const char*)((CAtom*)g_oaAtoms[g_waAtomRealElement[ti]])->m_sName,g_waAtomMolNumber[ti]+1,((CMolecule*)g_oaMolecules[g_waAtomMolIndex[ti]])->m_sName,(const char*)((CAtom*)g_oaAtoms[g_waAtomRealElement[ti2]])->m_sName,g_waAtomMolNumber[ti2]+1,((CMolecule*)g_oaMolecules[g_waAtomMolIndex[ti2]])->m_sName,(const char*)((CAtom*)g_oaAtoms[g_waAtomRealElement[ti3]])->m_sName,g_waAtomMolNumber[ti3]+1,((CMolecule*)g_oaMolecules[g_waAtomMolIndex[ti3]])->m_sName); } else { ti = tempwa[z2*9+3]; ti2 = tempwa[z2*9+4]; mprintf("[%s%d (%s) --> %s%d (%s)] - ",(const char*)((CAtom*)g_oaAtoms[g_waAtomRealElement[ti]])->m_sName,g_waAtomMolNumber[ti]+1,((CMolecule*)g_oaMolecules[g_waAtomMolIndex[ti]])->m_sName,(const char*)((CAtom*)g_oaAtoms[g_waAtomRealElement[ti2]])->m_sName,g_waAtomMolNumber[ti2]+1,((CMolecule*)g_oaMolecules[g_waAtomMolIndex[ti2]])->m_sName); } if (m_pDDF[z]->m_bOrtho[2]) { ti = tempwa[z2*9+6]; ti2 = tempwa[z2*9+7]; ti3 = tempwa[z2*9+8]; mprintf("[%s%d (%s), %s%d (%s), %s%d (%s)]\n",(const char*)((CAtom*)g_oaAtoms[g_waAtomRealElement[ti]])->m_sName,g_waAtomMolNumber[ti]+1,((CMolecule*)g_oaMolecules[g_waAtomMolIndex[ti]])->m_sName,(const char*)((CAtom*)g_oaAtoms[g_waAtomRealElement[ti2]])->m_sName,g_waAtomMolNumber[ti2]+1,((CMolecule*)g_oaMolecules[g_waAtomMolIndex[ti2]])->m_sName,(const char*)((CAtom*)g_oaAtoms[g_waAtomRealElement[ti3]])->m_sName,g_waAtomMolNumber[ti3]+1,((CMolecule*)g_oaMolecules[g_waAtomMolIndex[ti3]])->m_sName); } else { ti = tempwa[z2*9+6]; ti2 = tempwa[z2*9+7]; mprintf("[%s%d (%s) --> %s%d (%s)]\n",(const char*)((CAtom*)g_oaAtoms[g_waAtomRealElement[ti]])->m_sName,g_waAtomMolNumber[ti]+1,((CMolecule*)g_oaMolecules[g_waAtomMolIndex[ti]])->m_sName,(const char*)((CAtom*)g_oaAtoms[g_waAtomRealElement[ti2]])->m_sName,g_waAtomMolNumber[ti2]+1,((CMolecule*)g_oaMolecules[g_waAtomMolIndex[ti2]])->m_sName); } } break; case 3: eprintf("(not implemented)\n"); break; case 4: eprintf("(not implemented)\n"); break; case 5: // PlDF if (m_bOthers) { if (m_bSecondShowMol && (z == 1)) m_pPlDF[z]->BuildAtomList((CSingleMolecule*)g_oaSingleMolecules[((CMolecule*)g_oaMolecules[g_iFixMol])->m_laSingleMolIndex[0]],(CSingleMolecule*)g_oaSingleMolecules[((CMolecule*)g_oaMolecules[m_iShowMol2])->m_laSingleMolIndex[0]],&tempwa); else m_pPlDF[z]->BuildAtomList((CSingleMolecule*)g_oaSingleMolecules[((CMolecule*)g_oaMolecules[g_iFixMol])->m_laSingleMolIndex[0]],(CSingleMolecule*)g_oaSingleMolecules[((CMolecule*)g_oaMolecules[m_iShowMol])->m_laSingleMolIndex[0]],&tempwa); } else m_pPlDF[z]->BuildAtomList((CSingleMolecule*)g_oaSingleMolecules[((CMolecule*)g_oaMolecules[g_iFixMol])->m_laSingleMolIndex[0]],(CSingleMolecule*)g_oaSingleMolecules[((CMolecule*)g_oaMolecules[g_iFixMol])->m_laSingleMolIndex[0]],&tempwa); for (z2=0;z2m_bNormal) { ti = tempwa[z2*4]; ti2 = tempwa[z2*4+1]; mprintf("[%s%d (%s) --> %s%d (%s)] - ",(const char*)((CAtom*)g_oaAtoms[g_waAtomRealElement[ti]])->m_sName,g_waAtomMolNumber[ti]+1,((CMolecule*)g_oaMolecules[g_waAtomMolIndex[ti]])->m_sName,(const char*)((CAtom*)g_oaAtoms[g_waAtomRealElement[ti2]])->m_sName,g_waAtomMolNumber[ti2]+1,((CMolecule*)g_oaMolecules[g_waAtomMolIndex[ti2]])->m_sName); } else { ti = tempwa[z2*4]; ti2 = tempwa[z2*4+1]; ti3 = tempwa[z2*4+2]; mprintf("[%s%d (%s), %s%d (%s), %s%d (%s)] - ",(const char*)((CAtom*)g_oaAtoms[g_waAtomRealElement[ti]])->m_sName,g_waAtomMolNumber[ti]+1,((CMolecule*)g_oaMolecules[g_waAtomMolIndex[ti]])->m_sName,(const char*)((CAtom*)g_oaAtoms[g_waAtomRealElement[ti2]])->m_sName,g_waAtomMolNumber[ti2]+1,((CMolecule*)g_oaMolecules[g_waAtomMolIndex[ti2]])->m_sName,(const char*)((CAtom*)g_oaAtoms[g_waAtomRealElement[ti3]])->m_sName,g_waAtomMolNumber[ti3]+1,((CMolecule*)g_oaMolecules[g_waAtomMolIndex[ti3]])->m_sName); } ti = tempwa[z2*4+3]; mprintf("%s%d (%s)\n",(const char*)((CAtom*)g_oaAtoms[g_waAtomRealElement[ti]])->m_sName,g_waAtomMolNumber[ti]+1,((CMolecule*)g_oaMolecules[g_waAtomMolIndex[ti]])->m_sName); } break; case 6: // LiDF if (m_bOthers) { if (m_bSecondShowMol && (z == 1)) m_pLiDF[z]->BuildAtomList((CSingleMolecule*)g_oaSingleMolecules[((CMolecule*)g_oaMolecules[g_iFixMol])->m_laSingleMolIndex[0]],(CSingleMolecule*)g_oaSingleMolecules[((CMolecule*)g_oaMolecules[m_iShowMol2])->m_laSingleMolIndex[0]],&tempwa); else m_pLiDF[z]->BuildAtomList((CSingleMolecule*)g_oaSingleMolecules[((CMolecule*)g_oaMolecules[g_iFixMol])->m_laSingleMolIndex[0]],(CSingleMolecule*)g_oaSingleMolecules[((CMolecule*)g_oaMolecules[m_iShowMol])->m_laSingleMolIndex[0]],&tempwa); } else m_pLiDF[z]->BuildAtomList((CSingleMolecule*)g_oaSingleMolecules[((CMolecule*)g_oaMolecules[g_iFixMol])->m_laSingleMolIndex[0]],(CSingleMolecule*)g_oaSingleMolecules[((CMolecule*)g_oaMolecules[g_iFixMol])->m_laSingleMolIndex[0]],&tempwa); for (z2=0;z2m_bNormal) { ti = tempwa[z2*4]; ti2 = tempwa[z2*4+1]; ti3 = tempwa[z2*4+2]; mprintf("[%s%d (%s), %s%d (%s), %s%d (%s)] - ",(const char*)((CAtom*)g_oaAtoms[g_waAtomRealElement[ti]])->m_sName,g_waAtomMolNumber[ti]+1,((CMolecule*)g_oaMolecules[g_waAtomMolIndex[ti]])->m_sName,(const char*)((CAtom*)g_oaAtoms[g_waAtomRealElement[ti2]])->m_sName,g_waAtomMolNumber[ti2]+1,((CMolecule*)g_oaMolecules[g_waAtomMolIndex[ti2]])->m_sName,(const char*)((CAtom*)g_oaAtoms[g_waAtomRealElement[ti3]])->m_sName,g_waAtomMolNumber[ti3]+1,((CMolecule*)g_oaMolecules[g_waAtomMolIndex[ti3]])->m_sName); } else { ti = tempwa[z2*4]; ti2 = tempwa[z2*4+1]; mprintf("[%s%d (%s) --> %s%d (%s)] - ",(const char*)((CAtom*)g_oaAtoms[g_waAtomRealElement[ti]])->m_sName,g_waAtomMolNumber[ti]+1,((CMolecule*)g_oaMolecules[g_waAtomMolIndex[ti]])->m_sName,(const char*)((CAtom*)g_oaAtoms[g_waAtomRealElement[ti2]])->m_sName,g_waAtomMolNumber[ti2]+1,((CMolecule*)g_oaMolecules[g_waAtomMolIndex[ti2]])->m_sName); } ti = tempwa[z2*4+3]; mprintf("%s%d (%s)\n",(const char*)((CAtom*)g_oaAtoms[g_waAtomRealElement[ti]])->m_sName,g_waAtomMolNumber[ti]+1,((CMolecule*)g_oaMolecules[g_waAtomMolIndex[ti]])->m_sName); } break; } } void CSDF::CreateCutPlane() { int x, y; CxDVector3 vec; try { m_pCutPlane = new C2DF(); } catch(...) { m_pCutPlane = NULL; } if (m_pCutPlane == NULL) NewException((double)sizeof(C2DF),__FILE__,__LINE__,__PRETTY_FUNCTION__); m_pCutPlane->m_fMinVal[0] = -m_fRadius; m_pCutPlane->m_fMinVal[1] = -m_fRadius; m_pCutPlane->m_fMaxVal[0] = m_fRadius; m_pCutPlane->m_fMaxVal[1] = m_fRadius; m_pCutPlane->m_iRes[0] = m_iCutPlaneResolution; m_pCutPlane->m_iRes[1] = m_iCutPlaneResolution; m_pCutPlane->SetLabelX("X [pm]"); m_pCutPlane->SetLabelY("Y [pm]"); m_pCutPlane->Create(); vec[2] = 0; for (y=0;ym_iRes[1])*(m_pCutPlane->m_fMaxVal[1]-m_pCutPlane->m_fMinVal[1])+m_pCutPlane->m_fMinVal[1]); for (x=0;xm_iRes[0])*(m_pCutPlane->m_fMaxVal[0]-m_pCutPlane->m_fMinVal[0])+m_pCutPlane->m_fMinVal[0]); m_pCutPlane->AddToBin(x,y,m_pSDF->GetValue(vec)); } } if (m_bCutPlaneShowAtoms) { m_pCutPlane->AddCircle(0,0,((CAtom*)g_oaAtoms[g_iFixRealAtomType[0]])->m_pElement->m_fRadius*0.75,((CAtom*)g_oaAtoms[g_iFixRealAtomType[0]])->m_pElement->m_iColorR/255.0,((CAtom*)g_oaAtoms[g_iFixRealAtomType[0]])->m_pElement->m_iColorG/255.0,((CAtom*)g_oaAtoms[g_iFixRealAtomType[0]])->m_pElement->m_iColorB/255.0); m_pCutPlane->AddCircle(m_fAtom2PosX / m_fPosCounter,0,((CAtom*)g_oaAtoms[g_iFixRealAtomType[1]])->m_pElement->m_fRadius*0.75,((CAtom*)g_oaAtoms[g_iFixRealAtomType[1]])->m_pElement->m_iColorR/255.0,((CAtom*)g_oaAtoms[g_iFixRealAtomType[1]])->m_pElement->m_iColorG/255.0,((CAtom*)g_oaAtoms[g_iFixRealAtomType[1]])->m_pElement->m_iColorB/255.0); m_pCutPlane->AddCircle(m_fAtom3PosX / m_fPosCounter,m_fAtom3PosY / m_fPosCounter,((CAtom*)g_oaAtoms[g_iFixRealAtomType[2]])->m_pElement->m_fRadius*0.75,((CAtom*)g_oaAtoms[g_iFixRealAtomType[2]])->m_pElement->m_iColorR/255.0,((CAtom*)g_oaAtoms[g_iFixRealAtomType[2]])->m_pElement->m_iColorG/255.0,((CAtom*)g_oaAtoms[g_iFixRealAtomType[2]])->m_pElement->m_iColorB/255.0); } } void CConditionGroup::Reset() { int z; for (z=0;zReset(); for (z=0;z<((CMolecule*)g_oaMolecules[m_iShowMol])->m_laSingleMolIndex.GetSize();z++) m_iPassCounter[z] = 0; } void CConditionSubGroup::Reset() { int z; for (z=0;zReset(); } void CRDF::CopyFrom(CRDF *p) { int z; CAtomGroup *ag; m_bAdaptive = p->m_bAdaptive; m_bRadialCorrect = p->m_bRadialCorrect; m_bSelf = p->m_bSelf; m_fMinDist = p->m_fMinDist; m_fMaxDist = p->m_fMaxDist; m_iCombinations = p->m_iCombinations; m_iHistogramRes = p->m_iHistogramRes; m_iRefAtomGes = p->m_iRefAtomGes; m_iRefOrSec[0] = p->m_iRefOrSec[0]; m_iRefOrSec[1] = p->m_iRefOrSec[1]; m_iResolution = p->m_iResolution; m_iShowAtomGes = p->m_iShowAtomGes; m_iShowMol = p->m_iShowMol; if (p->m_sName != NULL) { try { m_sName = new char[strlen(p->m_sName)+1]; } catch(...) { m_sName = NULL; } if (m_sName == NULL) NewException((double)(strlen(p->m_sName)+1)*sizeof(char),__FILE__,__LINE__,__PRETTY_FUNCTION__); strcpy(m_sName,p->m_sName); } else m_sName = NULL; if (p->m_sShortName != NULL) { try { m_sShortName = new char[strlen(p->m_sShortName)+1]; } catch(...) { m_sShortName = NULL; } if (m_sShortName == NULL) NewException((double)(strlen(p->m_sShortName)+1)*sizeof(char),__FILE__,__LINE__,__PRETTY_FUNCTION__); strcpy(m_sShortName,p->m_sShortName); } else m_sShortName = NULL; if (p->m_baDataEnabled != NULL) { try { m_baDataEnabled = new CxByteArray[((CMolecule*)g_oaMolecules[m_iShowMol])->m_laSingleMolIndex.GetSize()]; } catch(...) { m_baDataEnabled = NULL; } if (m_baDataEnabled == NULL) NewException((double)((CMolecule*)g_oaMolecules[m_iShowMol])->m_laSingleMolIndex.GetSize()*sizeof(CxByteArray),__FILE__,__LINE__,__PRETTY_FUNCTION__); for (z=0;z<((CMolecule*)g_oaMolecules[m_iShowMol])->m_laSingleMolIndex.GetSize();z++) m_baDataEnabled[z].CopyFrom(&p->m_baDataEnabled[z]); } if (p->m_faData != NULL) { try { m_faData = new CxDoubleArray[((CMolecule*)g_oaMolecules[m_iShowMol])->m_laSingleMolIndex.GetSize()]; } catch(...) { m_faData = NULL; } if (m_faData == NULL) NewException((double)((CMolecule*)g_oaMolecules[m_iShowMol])->m_laSingleMolIndex.GetSize()*sizeof(CxDoubleArray),__FILE__,__LINE__,__PRETTY_FUNCTION__); for (z=0;z<((CMolecule*)g_oaMolecules[m_iShowMol])->m_laSingleMolIndex.GetSize();z++) m_faData[z].CopyFrom(&p->m_faData[z]); } for (z=0;zm_oaVectors.GetSize();z++) { try { ag = new CAtomGroup(); } catch(...) { ag = NULL; } if (ag == NULL) NewException((double)sizeof(CAtomGroup),__FILE__,__LINE__,__PRETTY_FUNCTION__); ag->CopyFrom((CAtomGroup*)p->m_oaVectors[z]); m_oaVectors.Add(ag); } m_faMinMaxDist.CopyFrom(&p->m_faMinMaxDist); if (p->m_pRDF != NULL) { try { m_pRDF = new CDF(); } catch(...) { m_pRDF = NULL; } if (m_pRDF == NULL) NewException((double)sizeof(CDF),__FILE__,__LINE__,__PRETTY_FUNCTION__); m_pRDF->CopyFrom(p->m_pRDF); } } void CADF::CopyFrom(CADF *p) { int z, z2; CAtomGroup *ag; m_bCosine = p->m_bCosine; m_bFoldAngle = p->m_bFoldAngle; m_bMirror = p->m_bMirror; m_bOrtho[0] = p->m_bOrtho[0]; m_bOrtho[1] = p->m_bOrtho[1]; m_iVecType[0] = p->m_iVecType[0]; m_iVecType[1] = p->m_iVecType[1]; m_bSelf = p->m_bSelf; m_bStat = p->m_bStat; m_fMinAngle = p->m_fMinAngle; m_fMaxAngle = p->m_fMaxAngle; m_iCombinations = p->m_iCombinations; m_iHistogramRes = p->m_iHistogramRes; for (z=0;z<2;z++) for (z2=0;z2<3;z2++) m_iRefOrSec[z][z2] = p->m_iRefOrSec[z][z2]; m_iResolution = p->m_iResolution; m_iShowMol = p->m_iShowMol; if (p->m_sName != NULL) { try { m_sName = new char[strlen(p->m_sName)+1]; } catch(...) { m_sName = NULL; } if (m_sName == NULL) NewException((double)(strlen(p->m_sName)+1)*sizeof(char),__FILE__,__LINE__,__PRETTY_FUNCTION__); strcpy(m_sName,p->m_sName); } else m_sName = NULL; if (p->m_sShortName != NULL) { try { m_sShortName = new char[strlen(p->m_sShortName)+1]; } catch(...) { m_sShortName = NULL; } if (m_sShortName == NULL) NewException((double)(strlen(p->m_sShortName)+1)*sizeof(char),__FILE__,__LINE__,__PRETTY_FUNCTION__); strcpy(m_sShortName,p->m_sShortName); } else m_sShortName = NULL; if (p->m_baDataEnabled != NULL) { try { m_baDataEnabled = new CxByteArray[((CMolecule*)g_oaMolecules[m_iShowMol])->m_laSingleMolIndex.GetSize()]; } catch(...) { m_baDataEnabled = NULL; } if (m_baDataEnabled == NULL) NewException((double)((CMolecule*)g_oaMolecules[m_iShowMol])->m_laSingleMolIndex.GetSize()*sizeof(CxByteArray),__FILE__,__LINE__,__PRETTY_FUNCTION__); for (z=0;z<((CMolecule*)g_oaMolecules[m_iShowMol])->m_laSingleMolIndex.GetSize();z++) m_baDataEnabled[z].CopyFrom(&p->m_baDataEnabled[z]); } if (p->m_faData != NULL) { try { m_faData = new CxDoubleArray[((CMolecule*)g_oaMolecules[m_iShowMol])->m_laSingleMolIndex.GetSize()]; } catch(...) { m_faData = NULL; } if (m_faData == NULL) NewException((double)((CMolecule*)g_oaMolecules[m_iShowMol])->m_laSingleMolIndex.GetSize()*sizeof(CxDoubleArray),__FILE__,__LINE__,__PRETTY_FUNCTION__); for (z=0;z<((CMolecule*)g_oaMolecules[m_iShowMol])->m_laSingleMolIndex.GetSize();z++) m_faData[z].CopyFrom(&p->m_faData[z]); } for (z=0;zm_oaVectors.GetSize();z++) { if (p->m_oaVectors[z] != NULL) { try { ag = new CAtomGroup(); } catch(...) { ag = NULL; } if (ag == NULL) NewException((double)sizeof(CAtomGroup),__FILE__,__LINE__,__PRETTY_FUNCTION__); ag->CopyFrom((CAtomGroup*)p->m_oaVectors[z]); m_oaVectors.Add(ag); } else m_oaVectors.Add(NULL); } m_faMinMaxAngle.CopyFrom(&p->m_faMinMaxAngle); if (p->m_pADF != NULL) { try { m_pADF = new CDF(); } catch(...) { m_pADF = NULL; } if (m_pADF == NULL) NewException((double)sizeof(CDF),__FILE__,__LINE__,__PRETTY_FUNCTION__); m_pADF->CopyFrom(p->m_pADF); } } void CConditionSubGroup::CopyFrom(CConditionSubGroup *p) { int z; CNbSearch *nb; m_fPassed = p->m_fPassed; m_fTotal = p->m_fTotal; m_iCombinations = p->m_iCombinations; m_iNumber = p->m_iNumber; m_iShowMol = p->m_iShowMol; if (p->m_bTempPassed != NULL) { try { m_bTempPassed = new bool[g_iGesVirtAtomCount]; } catch(...) { m_bTempPassed = NULL; } if (m_bTempPassed == NULL) NewException((double)g_iGesVirtAtomCount*sizeof(bool),__FILE__,__LINE__,__PRETTY_FUNCTION__); memcpy(m_bTempPassed,p->m_bTempPassed,sizeof(bool)*g_iGesVirtAtomCount); } for (z=0;zm_oaConditions.GetSize();z++) { try { nb = new CNbSearch(); } catch(...) { nb = NULL; } if (nb == NULL) NewException((double)sizeof(CNbSearch),__FILE__,__LINE__,__PRETTY_FUNCTION__); nb->CopyFrom((CNbSearch*)p->m_oaConditions[z]); m_oaConditions.Add(nb); } } void CConditionGroup::CopyFrom(CConditionGroup *p) { int z; CConditionSubGroup *sg; m_bInactive = p->m_bInactive; m_iShowMol = p->m_iShowMol; m_iRefMol = p->m_iRefMol; m_iHistoGes = p->m_iHistoGes; m_bAnyPassed = p->m_bAnyPassed; m_iTempPassed = p->m_iTempPassed; m_fTableGes = p->m_fTableGes; m_fPassed = p->m_fPassed; m_fTotal = p->m_fTotal; m_bInvertCondition = p->m_bInvertCondition; if (p->m_bAlwaysTrue != NULL) { try { m_bAlwaysTrue = new bool[((CMolecule*)g_oaMolecules[m_iShowMol])->m_laSingleMolIndex.GetSize()]; } catch(...) { m_bAlwaysTrue = NULL; } if (m_bAlwaysTrue == NULL) NewException((double)((CMolecule*)g_oaMolecules[m_iShowMol])->m_laSingleMolIndex.GetSize()*sizeof(bool),__FILE__,__LINE__,__PRETTY_FUNCTION__); memcpy(m_bAlwaysTrue,p->m_bAlwaysTrue,sizeof(bool)*((CMolecule*)g_oaMolecules[m_iShowMol])->m_laSingleMolIndex.GetSize()); } if (p->m_iPassCounter != NULL) { try { m_iPassCounter = new long[((CMolecule*)g_oaMolecules[m_iShowMol])->m_laSingleMolIndex.GetSize()]; } catch(...) { m_iPassCounter = NULL; } if (m_iPassCounter == NULL) NewException((double)((CMolecule*)g_oaMolecules[m_iShowMol])->m_laSingleMolIndex.GetSize()*sizeof(long),__FILE__,__LINE__,__PRETTY_FUNCTION__); memcpy(m_iPassCounter,p->m_iPassCounter,sizeof(long)*((CMolecule*)g_oaMolecules[m_iShowMol])->m_laSingleMolIndex.GetSize()); } if (p->m_iOMPassCounter != NULL) { try { m_iOMPassCounter = new long[((CMolecule*)g_oaMolecules[m_iShowMol])->m_laSingleMolIndex.GetSize()]; } catch(...) { m_iOMPassCounter = NULL; } if (m_iOMPassCounter == NULL) NewException((double)((CMolecule*)g_oaMolecules[m_iShowMol])->m_laSingleMolIndex.GetSize()*sizeof(long),__FILE__,__LINE__,__PRETTY_FUNCTION__); memcpy(m_iOMPassCounter,p->m_iOMPassCounter,sizeof(long)*((CMolecule*)g_oaMolecules[m_iShowMol])->m_laSingleMolIndex.GetSize()); } if (p->m_iRMPassCounter != NULL) { try { m_iRMPassCounter = new long[((CMolecule*)g_oaMolecules[m_iRefMol])->m_laSingleMolIndex.GetSize()]; } catch(...) { m_iRMPassCounter = NULL; } if (m_iRMPassCounter == NULL) NewException((double)((CMolecule*)g_oaMolecules[m_iRefMol])->m_laSingleMolIndex.GetSize()*sizeof(long),__FILE__,__LINE__,__PRETTY_FUNCTION__); memcpy(m_iRMPassCounter,p->m_iRMPassCounter,sizeof(long)*((CMolecule*)g_oaMolecules[m_iRefMol])->m_laSingleMolIndex.GetSize()); } for (z=0;zm_oaConditionSubGroups.GetSize();z++) { try { sg = new CConditionSubGroup(); } catch(...) { sg = NULL; } if (sg == NULL) NewException((double)sizeof(CConditionSubGroup),__FILE__,__LINE__,__PRETTY_FUNCTION__); sg->CopyFrom((CConditionSubGroup*)p->m_oaConditionSubGroups[z]); m_oaConditionSubGroups.Add(sg); } if (p->m_pTable != NULL) { try { m_pTable = new double[(((CConditionSubGroup*)m_oaConditionSubGroups[0])->m_iCombinations+1) * (((CConditionSubGroup*)m_oaConditionSubGroups[1])->m_iCombinations+1)]; } catch(...) { m_pTable = NULL; } if (m_pTable == NULL) NewException((double)(((CConditionSubGroup*)m_oaConditionSubGroups[0])->m_iCombinations+1) * (((CConditionSubGroup*)m_oaConditionSubGroups[1])->m_iCombinations+1)*sizeof(double),__FILE__,__LINE__,__PRETTY_FUNCTION__); memcpy(m_pTable,p->m_pTable,sizeof(double)*(((CConditionSubGroup*)m_oaConditionSubGroups[0])->m_iCombinations+1) * (((CConditionSubGroup*)m_oaConditionSubGroups[1])->m_iCombinations+1)); } if (p->m_pHistogram != NULL) { try { m_pHistogram = new unsigned long[((CMolecule*)g_oaMolecules[m_iShowMol])->m_laSingleMolIndex.GetSize()+1]; } catch(...) { m_pHistogram = NULL; } if (m_pHistogram == NULL) NewException((double)(((CMolecule*)g_oaMolecules[m_iShowMol])->m_laSingleMolIndex.GetSize()+1)*sizeof(unsigned long),__FILE__,__LINE__,__PRETTY_FUNCTION__); memcpy(m_pHistogram,p->m_pHistogram,sizeof(unsigned long)*(((CMolecule*)g_oaMolecules[m_iShowMol])->m_laSingleMolIndex.GetSize()+1)); } } void CConditionGroup::Parse_OnlyValues() { BTIN; int z; for (z=0;z>> %d. set of conditions >>>\n\n",z+1); ((CConditionSubGroup*)m_oaConditionSubGroups[z])->Parse_OnlyValues(); mprintf(YELLOW,"<<< End of %d. set of conditions <<<\n\n",z+1); } } void CConditionSubGroup::Parse_OnlyValues() { BTIN; int z; for (z=0;z>> %d. condition within this set >>>\n\n",z+1); ((CNbSearch*)m_oaConditions[z])->Parse_OnlyValues(); mprintf(YELLOW,"\n <<< End of %d. condition <<<\n\n",z+1); } BTOUT; } void CConditionGroup::CopyResults(CConditionGroup *p) { int z; for (z=0;zCopyResults((CConditionSubGroup*)p->m_oaConditionSubGroups[z]); } void CConditionSubGroup::CopyResults(CConditionSubGroup *p) { int z; for (z=0;zCopyResults((CNbSearch*)p->m_oaConditions[z]); } void CConditionGroup::ReScan(CSingleMolecule *rm) { BXIN; int z, z2, t1, t2, i; if (m_bInactive) return; for (z=0;zReScan(rm); if (m_oaConditionSubGroups.GetSize() == 2) { for (z=0;z<((CMolecule*)g_oaMolecules[m_iShowMol])->m_laSingleMolIndex.GetSize();z++) { t1 = 0; t2 = 0; for (z2=0;z2<((CConditionSubGroup*)m_oaConditionSubGroups[0])->m_oaConditions.GetSize();z2++) t1 += ((CNbSearch*)((CConditionSubGroup*)m_oaConditionSubGroups[0])->m_oaConditions[z2])->m_iCombPassCount[z]; for (z2=0;z2<((CConditionSubGroup*)m_oaConditionSubGroups[1])->m_oaConditions.GetSize();z2++) t2 += ((CNbSearch*)((CConditionSubGroup*)m_oaConditionSubGroups[1])->m_oaConditions[z2])->m_iCombPassCount[z]; m_pTable[t1*(((CConditionSubGroup*)m_oaConditionSubGroups[1])->m_iCombinations+1)+t2]++; m_fTableGes++; } } i = 0; for (z=0;z<((CMolecule*)g_oaMolecules[m_iShowMol])->m_laSingleMolIndex.GetSize();z++) { m_fTotal++; if (m_bInvertCondition) { for (z2=0;z2Contains(z)) goto _nopass; m_fPassed++; m_iPassCounter[z]++; m_bAnyPassed = true; m_iTempPassed++; } else { for (z2=0;z2Contains(z)) { // mprintf("passed[%d]++\n",z); m_fPassed++; m_iPassCounter[z]++; m_bAnyPassed = true; m_iTempPassed++; i++; goto _nopass; } } _nopass:; } m_pHistogram[i]++; m_iHistoGes++; BXOUT; } void CConditionSubGroup::ReScan(CSingleMolecule *rm) { int z, z2; // mprintf("***** ReScan subgroup=%08X, rm=%d ******\n",this,rm->m_iMolSMIndex); for (z=0;zReScan(rm); } for (z=0;z<((CMolecule*)g_oaMolecules[m_iShowMol])->m_laSingleMolIndex.GetSize();z++) { m_fTotal++; for (z2=0;z2m_bPassed[z]) goto _nopass; m_fPassed++; _nopass:; } } CNbSearch* CConditionGroup::AddSingleCondition(int rm, int sm, int gridmode) { BTIN; CConditionSubGroup *sg; int z; m_iShowMol = sm; m_iRefMol = rm; try { m_bAlwaysTrue = new bool[((CMolecule*)g_oaMolecules[sm])->m_laSingleMolIndex.GetSize()]; } catch(...) { m_bAlwaysTrue = NULL; } if (m_bAlwaysTrue == NULL) NewException((double)((CMolecule*)g_oaMolecules[sm])->m_laSingleMolIndex.GetSize()*sizeof(bool),__FILE__,__LINE__,__PRETTY_FUNCTION__); try { m_iPassCounter = new long[((CMolecule*)g_oaMolecules[sm])->m_laSingleMolIndex.GetSize()]; } catch(...) { m_iPassCounter = NULL; } if (m_iPassCounter == NULL) NewException((double)((CMolecule*)g_oaMolecules[sm])->m_laSingleMolIndex.GetSize()*sizeof(long),__FILE__,__LINE__,__PRETTY_FUNCTION__); try { m_iOMPassCounter = new long[((CMolecule*)g_oaMolecules[sm])->m_laSingleMolIndex.GetSize()]; } catch(...) { m_iOMPassCounter = NULL; } if (m_iOMPassCounter == NULL) NewException((double)((CMolecule*)g_oaMolecules[sm])->m_laSingleMolIndex.GetSize()*sizeof(long),__FILE__,__LINE__,__PRETTY_FUNCTION__); for (z=0;z<((CMolecule*)g_oaMolecules[sm])->m_laSingleMolIndex.GetSize();z++) { m_bAlwaysTrue[z] = false; m_iPassCounter[z] = 0; m_iOMPassCounter[z] = 0; } try { m_iRMPassCounter = new long[((CMolecule*)g_oaMolecules[rm])->m_laSingleMolIndex.GetSize()]; } catch(...) { m_iRMPassCounter = NULL; } if (m_iRMPassCounter == NULL) NewException((double)((CMolecule*)g_oaMolecules[rm])->m_laSingleMolIndex.GetSize()*sizeof(long),__FILE__,__LINE__,__PRETTY_FUNCTION__); for (z=0;z<((CMolecule*)g_oaMolecules[rm])->m_laSingleMolIndex.GetSize();z++) m_iRMPassCounter[z] = 0; try { sg = new CConditionSubGroup(); } catch(...) { sg = NULL; } if (sg == NULL) NewException((double)sizeof(CConditionSubGroup),__FILE__,__LINE__,__PRETTY_FUNCTION__); sg->m_iShowMol = m_iShowMol; sg->m_iNumber = m_oaConditionSubGroups.GetSize(); m_oaConditionSubGroups.Add(sg); m_bInvertCondition = false; m_iHistoGes = 0; try { m_pHistogram = new unsigned long[((CMolecule*)g_oaMolecules[sm])->m_laSingleMolIndex.GetSize()+1]; } catch(...) { m_pHistogram = NULL; } if (m_pHistogram == NULL) NewException((double)(((CMolecule*)g_oaMolecules[sm])->m_laSingleMolIndex.GetSize()+1)*sizeof(unsigned long),__FILE__,__LINE__,__PRETTY_FUNCTION__); for (z=0;z<((CMolecule*)g_oaMolecules[sm])->m_laSingleMolIndex.GetSize()+1;z++) m_pHistogram[z] = 0; BTOUT; return sg->AddSingleCondition(rm,sm,gridmode); } CNbSearch* CConditionSubGroup::AddSingleCondition(int rm, int sm, int gridmode) { BTIN; CNbSearch *n; m_iCombinations = 0; try { n = new CNbSearch(); } catch(...) { n = NULL; } if (n == NULL) NewException((double)sizeof(CNbSearch),__FILE__,__LINE__,__PRETTY_FUNCTION__); n->m_iNumber = m_oaConditions.GetSize(); m_oaConditions.Add(n); n->ParseGrid(rm,sm,gridmode); m_iCombinations += n->m_iCombinationsEnabled; try { m_bTempPassed = new bool[g_iGesVirtAtomCount]; } catch(...) { m_bTempPassed = NULL; } if (m_bTempPassed == NULL) NewException((double)g_iGesVirtAtomCount*sizeof(bool),__FILE__,__LINE__,__PRETTY_FUNCTION__); BTOUT; return n; } void CObservation::BuildTimeDiff(CDF *df, bool ddf) { int z, z2, z3, z4, i; CxDoubleArray *ptfa; double tf, tfa, tfsq, tfs, tf0; // char buf[1024]; CxString buf; try { df->m_pTimeDiff = new CDF(); } catch(...) { df->m_pTimeDiff = NULL; } if (df->m_pTimeDiff == NULL) NewException((double)sizeof(CDF),__FILE__,__LINE__,__PRETTY_FUNCTION__); df->m_pTimeDiff->m_iResolution = m_iTimeDiffDepth; df->m_pTimeDiff->m_fMinVal = 0; df->m_pTimeDiff->m_fMaxVal = m_iTimeDiffDepth * g_fTimestepLength / 1000.0; df->m_pTimeDiff->Create(); df->m_pTimeDiff->SetLabelX("Tau [ps]"); // sprintf(buf,"Delta "); // strcat(buf,df->m_sLabelX); buf.sprintf("Delta "); buf.strcat(df->m_sLabelX); df->m_pTimeDiff->SetLabelY(buf); try { df->m_pTimeDiffAbs = new CDF(); } catch(...) { df->m_pTimeDiffAbs = NULL; } if (df->m_pTimeDiffAbs == NULL) NewException((double)sizeof(CDF),__FILE__,__LINE__,__PRETTY_FUNCTION__); df->m_pTimeDiffAbs->m_iResolution = m_iTimeDiffDepth; df->m_pTimeDiffAbs->m_fMinVal = 0; df->m_pTimeDiffAbs->m_fMaxVal = m_iTimeDiffDepth * g_fTimestepLength / 1000.0; df->m_pTimeDiffAbs->Create(); df->m_pTimeDiffAbs->SetLabelX("Tau [ps]"); df->m_pTimeDiffAbs->SetLabelY(buf); // sprintf(buf,"Delta Square "); // strcat(buf,df->m_sLabelX); buf.sprintf("Delta Square "); buf.strcat(df->m_sLabelX); try { df->m_pTimeDiffSqr = new CDF(); } catch(...) { df->m_pTimeDiffSqr = NULL; } if (df->m_pTimeDiffSqr == NULL) NewException((double)sizeof(CDF),__FILE__,__LINE__,__PRETTY_FUNCTION__); df->m_pTimeDiffSqr->m_iResolution = m_iTimeDiffDepth; df->m_pTimeDiffSqr->m_fMinVal = 0; df->m_pTimeDiffSqr->m_fMaxVal = m_iTimeDiffDepth * g_fTimestepLength / 1000.0; df->m_pTimeDiffSqr->Create(); df->m_pTimeDiffSqr->SetLabelX("Tau [ps]"); df->m_pTimeDiffSqr->SetLabelY(buf); if (m_b3DTimeDiff) { // sprintf(buf,"Delta "); // strcat(buf,df->m_sLabelX); buf.sprintf("Delta "); buf.strcat(df->m_sLabelX); try { df->m_p3DTimeDiff = new C2DF(); } catch(...) { df->m_p3DTimeDiff = NULL; } if (df->m_p3DTimeDiff == NULL) NewException((double)sizeof(C2DF),__FILE__,__LINE__,__PRETTY_FUNCTION__); df->m_p3DTimeDiff->m_iRes[0] = m_iTimeDiffDepth/m_iTimeDiffStride3D; df->m_p3DTimeDiff->m_iRes[1] = m_iTimeDiffRes3D; df->m_p3DTimeDiff->m_fMinVal[0] = 0; df->m_p3DTimeDiff->m_fMaxVal[0] = m_iTimeDiffDepth * g_fTimestepLength / 1000.0; df->m_p3DTimeDiff->m_fMinVal[1] = m_fTimeDiffMinVal3D; df->m_p3DTimeDiff->m_fMaxVal[1] = m_fTimeDiffMaxVal3D; df->m_p3DTimeDiff->Create(); df->m_p3DTimeDiff->SetLabelX("Tau [ps]"); df->m_p3DTimeDiff->SetLabelY(df->m_sLabelX); df->m_p3DTimeDiff->SetLabelZ(buf); try { df->m_p3DTimeDiffAbs = new C2DF(); } catch(...) { df->m_p3DTimeDiffAbs = NULL; } if (df->m_p3DTimeDiffAbs == NULL) NewException((double)sizeof(C2DF),__FILE__,__LINE__,__PRETTY_FUNCTION__); df->m_p3DTimeDiffAbs->m_iRes[0] = m_iTimeDiffDepth/m_iTimeDiffStride3D; df->m_p3DTimeDiffAbs->m_iRes[1] = m_iTimeDiffRes3D; df->m_p3DTimeDiffAbs->m_fMinVal[0] = 0; df->m_p3DTimeDiffAbs->m_fMaxVal[0] = m_iTimeDiffDepth * g_fTimestepLength / 1000.0; df->m_p3DTimeDiffAbs->m_fMinVal[1] = m_fTimeDiffMinVal3D; df->m_p3DTimeDiffAbs->m_fMaxVal[1] = m_fTimeDiffMaxVal3D; df->m_p3DTimeDiffAbs->Create(); df->m_p3DTimeDiffAbs->SetLabelX("Tau [ps]"); df->m_p3DTimeDiffAbs->SetLabelY(df->m_sLabelX); df->m_p3DTimeDiffAbs->SetLabelZ(buf); if (m_iTimeDiffDistSteps != 0) { try { df->m_pTimeDiffDistPairs = new C2DF*[m_iTimeDiffDepth/m_iTimeDiffStride3D/m_iTimeDiffDistSteps]; } catch(...) { df->m_pTimeDiffDistPairs = NULL; } if (df->m_pTimeDiffDistPairs == NULL) NewException((double)m_iTimeDiffDepth/m_iTimeDiffStride3D/m_iTimeDiffDistSteps*sizeof(C2DF*),__FILE__,__LINE__,__PRETTY_FUNCTION__); for (z=0;zm_pTimeDiffDistPairs[z] = new C2DF(); } catch(...) { df->m_pTimeDiffDistPairs[z] = NULL; } if (df->m_pTimeDiffDistPairs[z] == NULL) NewException((double)sizeof(C2DF),__FILE__,__LINE__,__PRETTY_FUNCTION__); df->m_pTimeDiffDistPairs[z]->m_iRes[0] = m_iTimeDiffDistResX; df->m_pTimeDiffDistPairs[z]->m_iRes[1] = m_iTimeDiffDistResY; df->m_pTimeDiffDistPairs[z]->m_fMinVal[0] = m_fTimeDiffDistMinValX; df->m_pTimeDiffDistPairs[z]->m_fMaxVal[0] = m_fTimeDiffDistMaxValX; df->m_pTimeDiffDistPairs[z]->m_fMinVal[1] = m_fTimeDiffDistMinValY; df->m_pTimeDiffDistPairs[z]->m_fMaxVal[1] = m_fTimeDiffDistMaxValY; df->m_pTimeDiffDistPairs[z]->Create(); df->m_pTimeDiffDistPairs[z]->SetLabelX(df->m_sLabelX); df->m_pTimeDiffDistPairs[z]->SetLabelY(df->m_sLabelX); } } try { df->m_pTimeDiffDist3DF = new C3DF(); } catch(...) { df->m_pTimeDiffDist3DF = NULL; } if (df->m_pTimeDiffDist3DF == NULL) NewException((double)sizeof(C3DF),__FILE__,__LINE__,__PRETTY_FUNCTION__); df->m_pTimeDiffDist3DF->m_iRes[0] = m_iTimeDiffDistResX; df->m_pTimeDiffDist3DF->m_iRes[1] = m_iTimeDiffDistResY; df->m_pTimeDiffDist3DF->m_iRes[2] = m_iTimeDiffDepth/m_iTimeDiffStride3D; df->m_pTimeDiffDist3DF->m_fMinVal[0] = m_fTimeDiffDistMinValX; df->m_pTimeDiffDist3DF->m_fMaxVal[0] = m_fTimeDiffDistMaxValX; df->m_pTimeDiffDist3DF->m_fMinVal[1] = m_fTimeDiffDistMinValY; df->m_pTimeDiffDist3DF->m_fMaxVal[1] = m_fTimeDiffDistMaxValY; df->m_pTimeDiffDist3DF->m_fMinVal[2] = 0; df->m_pTimeDiffDist3DF->m_fMaxVal[2] = m_iTimeDiffDepth * g_fTimestepLength / 1000.0; df->m_pTimeDiffDist3DF->Create(); df->m_pTimeDiffDist3DF->SetLabelX(df->m_sLabelX); df->m_pTimeDiffDist3DF->SetLabelY(df->m_sLabelX); // sprintf(buf,"Delta Square "); // strcat(buf,df->m_sLabelX); buf.sprintf("Delta Square "); buf.strcat(df->m_sLabelX); try { df->m_p3DTimeDiffSqr = new C2DF(); } catch(...) { df->m_p3DTimeDiffSqr = NULL; } if (df->m_p3DTimeDiffSqr == NULL) NewException((double)sizeof(C2DF),__FILE__,__LINE__,__PRETTY_FUNCTION__); df->m_p3DTimeDiffSqr->m_iRes[0] = m_iTimeDiffDepth/m_iTimeDiffStride3D; df->m_p3DTimeDiffSqr->m_iRes[1] = m_iTimeDiffRes3D; df->m_p3DTimeDiffSqr->m_fMinVal[0] = 0; df->m_p3DTimeDiffSqr->m_fMaxVal[0] = m_iTimeDiffDepth * g_fTimestepLength / 1000.0; df->m_p3DTimeDiffSqr->m_fMinVal[1] = m_fTimeDiffMinVal3D; df->m_p3DTimeDiffSqr->m_fMaxVal[1] = m_fTimeDiffMaxVal3D; df->m_p3DTimeDiffSqr->Create(); df->m_p3DTimeDiffSqr->SetLabelX("Tau [ps]"); df->m_p3DTimeDiffSqr->SetLabelY(df->m_sLabelX); df->m_p3DTimeDiffSqr->SetLabelZ(buf); try { df->m_p3DTimeDiffT = new C2DF(); } catch(...) { df->m_p3DTimeDiffT = NULL; } if (df->m_p3DTimeDiffT == NULL) NewException((double)sizeof(C2DF),__FILE__,__LINE__,__PRETTY_FUNCTION__); df->m_p3DTimeDiffT->m_iRes[0] = m_iTimeDiffDepth/m_iTimeDiffStride3D; df->m_p3DTimeDiffT->m_iRes[1] = m_iTimeDiffRes3D; df->m_p3DTimeDiffT->m_fMinVal[0] = 0; df->m_p3DTimeDiffT->m_fMaxVal[0] = m_iTimeDiffDepth * g_fTimestepLength / 1000.0; df->m_p3DTimeDiffT->m_fMinVal[1] = m_fTimeDiffMinVal3D; df->m_p3DTimeDiffT->m_fMaxVal[1] = m_fTimeDiffMaxVal3D; df->m_p3DTimeDiffT->Create(); } for (z2=0;z2m_oaTimeDiffBuf.GetSize();z2++) { mprintf(" %4d/%d 2D [",z2+1,df->m_oaTimeDiffBuf.GetSize()); ptfa = (CxDoubleArray*)df->m_oaTimeDiffBuf[z2]; tfs = m_iTimeDiffDepth/50.0; for (z3=0;z3GetSize()-z3-1;z4++) // Das ist der Startpunkt { tf0 = (*ptfa)[z3+z4]-(*ptfa)[z4]; if (ddf) { if (tf0 > 180.0) tf0 -= 360.0; if (tf0 <= -180.0) tf0 += 360.0; } tfa += fabs(tf0); tf += tf0; tfsq += tf0 * tf0; } df->m_pTimeDiff->AddToBin_Int(z3,tf/(ptfa->GetSize()-z3-1)); df->m_pTimeDiffAbs->AddToBin_Int(z3,tfa/(ptfa->GetSize()-z3-1)); df->m_pTimeDiffSqr->AddToBin_Int(z3,tfsq/(ptfa->GetSize()-z3-1)); df->m_pTimeDiff->m_fBinEntries += ptfa->GetSize()-z3-2; df->m_pTimeDiffAbs->m_fBinEntries += ptfa->GetSize()-z3-2; df->m_pTimeDiffSqr->m_fBinEntries += ptfa->GetSize()-z3-2; } mprintf("]\n"); if (m_b3DTimeDiff) { mprintf(" %4d/%d 3D [",z2+1,df->m_oaTimeDiffBuf.GetSize()); tfs = m_iTimeDiffDepth/50.0; for (z3=0;z3GetSize()-z3-1;z4++) // Das ist der Startpunkt { tf0 = (*ptfa)[z3+z4]-(*ptfa)[z4]; if (ddf) { if (tf0 > 180.0) tf0 -= 360.0; if (tf0 <= -180.0) tf0 += 360.0; } df->m_p3DTimeDiff->AddToBin_IntX(i,(*ptfa)[z4],tf0); df->m_p3DTimeDiffAbs->AddToBin_IntX(i,(*ptfa)[z4],fabs(tf0)); df->m_p3DTimeDiffSqr->AddToBin_IntX(i,(*ptfa)[z4],tf0*tf0); df->m_p3DTimeDiffT->AddToBin_IntX(i,(*ptfa)[z4],1.0); df->m_pTimeDiffDist3DF->AddToBin_IntZ((*ptfa)[z4],(*ptfa)[z3+z4],i); if (m_iTimeDiffDistSteps != 0) if ((i % m_iTimeDiffDistSteps) == 0) df->m_pTimeDiffDistPairs[i/m_iTimeDiffDistSteps]->AddToBin((*ptfa)[z4],(*ptfa)[z3+z4]); } } mprintf("]\n"); } } for (z3=0;z3m_pTimeDiff->m_pBin[z3] /= df->m_oaTimeDiffBuf.GetSize(); df->m_pTimeDiffAbs->m_pBin[z3] /= df->m_oaTimeDiffBuf.GetSize(); df->m_pTimeDiffSqr->m_pBin[z3] /= df->m_oaTimeDiffBuf.GetSize(); } if (m_b3DTimeDiff) { for (z2=0;z2m_p3DTimeDiff->m_iRes[0]*df->m_p3DTimeDiff->m_iRes[1];z2++) { if (df->m_p3DTimeDiffT->m_pBin[z2] != 0) { df->m_p3DTimeDiff->m_pBin[z2] /= df->m_p3DTimeDiffT->m_pBin[z2]; df->m_p3DTimeDiffAbs->m_pBin[z2] /= df->m_p3DTimeDiffT->m_pBin[z2]; df->m_p3DTimeDiffSqr->m_pBin[z2] /= df->m_p3DTimeDiffT->m_pBin[z2]; } } if (m_iTimeDiffDistSteps != 0) for (z=0;zm_pTimeDiffDistPairs[z]->NormalizeBinIntegral(1000000.0); } } void CObservation::WriteTimeDiff(CDF *df, const char *anaup, const char *analow, const char *name, const char *multibuf, bool ddf) { // char buf[1024]; CxString buf; int z, z2; C3DF *temp3DF; mprintf(" Creating temporal difference plot...\n"); BuildTimeDiff(df,ddf); mprintf(" (%.0f bin entries)\n",df->m_pTimeDiff->m_fBinEntries); // sprintf(buf,"%s_timediff_%s%s.csv",analow,name,multibuf); buf.sprintf("%s_timediff_%s%s.csv",analow,name,multibuf); mprintf(" Saving %s temporal difference plot as \"%s\"...\n",anaup,(const char*)buf); df->m_pTimeDiff->Write("",buf,"",true); // sprintf(buf,"%s_timediff_%s%s.agr",analow,name,multibuf); buf.sprintf("%s_timediff_%s%s.agr",analow,name,multibuf); mprintf(" Saving %s temporal difference plot AGR file as \"%s\"...\n",anaup,(const char*)buf); df->m_pTimeDiff->WriteAgr("",buf,"",name,false); // sprintf(buf,"%s_timediff_%s%s_abs.csv",analow,name,multibuf); buf.sprintf("%s_timediff_%s%s_abs.csv",analow,name,multibuf); mprintf(" Saving %s absolute temporal difference plot as \"%s\"...\n",anaup,(const char*)buf); df->m_pTimeDiffAbs->Write("",buf,"",true); // sprintf(buf,"%s_timediff_%s%s_abs.agr",analow,name,multibuf); buf.sprintf("%s_timediff_%s%s_abs.agr",analow,name,multibuf); mprintf(" Saving %s absolute temporal difference plot AGR file as \"%s\"...\n",anaup,(const char*)buf); df->m_pTimeDiffAbs->WriteAgr("",buf,"",name,false); // sprintf(buf,"%s_timediff_%s%s_sqr.csv",analow,name,multibuf); buf.sprintf("%s_timediff_%s%s_sqr.csv",analow,name,multibuf); mprintf(" Saving %s squared temporal difference plot as \"%s\"...\n",anaup,(const char*)buf); df->m_pTimeDiffSqr->Write("",buf,"",true); // sprintf(buf,"%s_timediff_%s%s_sqr.agr",analow,name,multibuf); buf.sprintf("%s_timediff_%s%s_sqr.agr",analow,name,multibuf); mprintf(" Saving %s squared temporal difference plot AGR file as \"%s\"...\n",anaup,(const char*)buf); df->m_pTimeDiffSqr->WriteAgr("",buf,"",name,false); if (m_b3DTimeDiff) { mprintf(" Writing temporal 3D difference plot...\n"); mprintf(" (%.0f bin entries)\n",df->m_p3DTimeDiff->m_fBinEntries); // sprintf(buf,"%s_timediff_%s%s_triples.csv",analow,name,multibuf); buf.sprintf("%s_timediff_%s%s_triples.csv",analow,name,multibuf); mprintf(" Saving %s temporal difference plot triples as \"%s\"...\n",anaup,(const char*)buf); df->m_p3DTimeDiff->Write("",buf,""); // sprintf(buf,"%s_timediff_%s%s_matrix.csv",analow,name,multibuf); buf.sprintf("%s_timediff_%s%s_matrix.csv",analow,name,multibuf); mprintf(" Saving %s temporal difference plot matrix as \"%s\"...\n",anaup,(const char*)buf); df->m_p3DTimeDiff->WriteCSV("",buf,""); // sprintf(buf,"%s_timediff_%s%s.nb",analow,name,multibuf); buf.sprintf("%s_timediff_%s%s.nb",analow,name,multibuf); mprintf(" Saving %s temporal difference plot Mathematica Notebook as \"%s\"...\n",anaup,(const char*)buf); df->m_p3DTimeDiff->WriteMathematicaNb("",buf,"",false); // sprintf(buf,"%s_timediff_%s%s",analow,name,multibuf); buf.sprintf("%s_timediff_%s%s",analow,name,multibuf); mprintf(" Saving %s temporal difference plot Gnuplot Input as \"%s.gp\"...\n",anaup,(const char*)buf); df->m_p3DTimeDiff->WriteGnuplotInput("",buf,"",false); // sprintf(buf,"%s_timediff_%s%s_triples_abs.csv",analow,name,multibuf); buf.sprintf("%s_timediff_%s%s_triples_abs.csv",analow,name,multibuf); mprintf(" Saving %s absolute temporal difference plot triples as \"%s\"...\n",anaup,(const char*)buf); df->m_p3DTimeDiffAbs->Write("",buf,""); // sprintf(buf,"%s_timediff_%s%s_matrix_abs.csv",analow,name,multibuf); buf.sprintf("%s_timediff_%s%s_matrix_abs.csv",analow,name,multibuf); mprintf(" Saving %s absolute temporal difference plot matrix as \"%s\"...\n",anaup,(const char*)buf); df->m_p3DTimeDiffAbs->WriteCSV("",buf,""); // sprintf(buf,"%s_timediff_%s%s_abs.nb",analow,name,multibuf); buf.sprintf("%s_timediff_%s%s_abs.nb",analow,name,multibuf); mprintf(" Saving %s absolute temporal difference plot Mathematica Notebook as \"%s\"...\n",anaup,(const char*)buf); df->m_p3DTimeDiffAbs->WriteMathematicaNb("",buf,"",false); // sprintf(buf,"%s_timediff_%s%s_abs",analow,name,multibuf); buf.sprintf("%s_timediff_%s%s_abs",analow,name,multibuf); mprintf(" Saving %s absolute temporal difference plot Gnuplot Input as \"%s.gp\"...\n",anaup,(const char*)buf); df->m_p3DTimeDiffAbs->WriteGnuplotInput("",buf,"",false); // sprintf(buf,"%s_timediff_%s%s_triples_sqr.csv",analow,name,multibuf); buf.sprintf("%s_timediff_%s%s_triples_sqr.csv",analow,name,multibuf); mprintf(" Saving %s squared temporal difference plot triples as \"%s\"...\n",anaup,(const char*)buf); df->m_p3DTimeDiffSqr->Write("",buf,""); // sprintf(buf,"%s_timediff_%s%s_matrix_sqr.csv",analow,name,multibuf); buf.sprintf("%s_timediff_%s%s_matrix_sqr.csv",analow,name,multibuf); mprintf(" Saving %s squared temporal difference plot matrix as \"%s\"...\n",anaup,(const char*)buf); df->m_p3DTimeDiffSqr->WriteCSV("",buf,""); // sprintf(buf,"%s_timediff_%s%s_sqr.nb",analow,name,multibuf); buf.sprintf("%s_timediff_%s%s_sqr.nb",analow,name,multibuf); mprintf(" Saving %s squared temporal difference plot Mathematica Notebook as \"%s\"...\n",anaup,(const char*)buf); df->m_p3DTimeDiffSqr->WriteMathematicaNb("",buf,"",false); // sprintf(buf,"%s_timediff_%s%s_sqr",analow,name,multibuf); buf.sprintf("%s_timediff_%s%s_sqr",analow,name,multibuf); mprintf(" Saving %s squared temporal difference plot Gnuplot Input as \"%s.gp\"...\n",anaup,(const char*)buf); df->m_p3DTimeDiffSqr->WriteGnuplotInput("",buf,"",false); if (m_iTimeDiffDistSteps != 0) { for (z=0;zm_pTimeDiffDistPairs[z]->Write("",buf,""); // sprintf(buf,"%s_timediff_beforeafter_%s%s_tau%.3f_matrix.csv",analow,name,multibuf,z*m_iTimeDiffStride3D*m_iTimeDiffDistSteps*g_fTimestepLength/1000.0); buf.sprintf("%s_timediff_beforeafter_%s%s_tau%.3f_matrix.csv",analow,name,multibuf,z*m_iTimeDiffStride3D*m_iTimeDiffDistSteps*g_fTimestepLength/1000.0); mprintf(" Saving %s before/after plot matrix as \"%s\"...\n",anaup,(const char*)buf); df->m_pTimeDiffDistPairs[z]->WriteCSV("",buf,""); // sprintf(buf,"%s_timediff_beforeafter_%s%s_tau%.3f.nb",analow,name,multibuf,z*m_iTimeDiffStride3D*m_iTimeDiffDistSteps*g_fTimestepLength/1000.0); buf.sprintf("%s_timediff_beforeafter_%s%s_tau%.3f.nb",analow,name,multibuf,z*m_iTimeDiffStride3D*m_iTimeDiffDistSteps*g_fTimestepLength/1000.0); mprintf(" Saving %s before/after plot Mathematica Notebook as \"%s\"...\n",anaup,(const char*)buf); df->m_pTimeDiffDistPairs[z]->WriteMathematicaNb("",buf,"",false); // sprintf(buf,"%s_timediff_beforeafter_%s%s_tau%.3f",analow,name,multibuf,z*m_iTimeDiffStride3D*m_iTimeDiffDistSteps*g_fTimestepLength/1000.0); buf.sprintf("%s_timediff_beforeafter_%s%s_tau%.3f",analow,name,multibuf,z*m_iTimeDiffStride3D*m_iTimeDiffDistSteps*g_fTimestepLength/1000.0); mprintf(" Saving %s before/after plot Gnuplot Input as \"%s.gp\"...\n",anaup,(const char*)buf); df->m_pTimeDiffDistPairs[z]->WriteGnuplotInput("",buf,"",false); } } for (z2=0;z2<=3;z2++) { try { temp3DF = new C3DF(); } catch(...) { temp3DF = NULL; } if (temp3DF == NULL) NewException((double)sizeof(C3DF),__FILE__,__LINE__,__PRETTY_FUNCTION__); temp3DF->CopyFrom(df->m_pTimeDiffDist3DF); if (z2 != 0) { temp3DF->Smooth(z2); // sprintf(buf,".s%d%s.plt",z2,multibuf); buf.sprintf(".s%d%s.plt",z2,multibuf); } else // sprintf(buf,"%s.plt",multibuf); buf.sprintf("%s.plt",multibuf); mprintf(" Saving 3D Plot as \"%s%s\"...\n",name,(const char*)buf); temp3DF->WritePLT("",name,buf,false); if (z2 != 0) // sprintf(buf,".s%d%s.cube",z2,multibuf); buf.sprintf(".s%d%s.cube",z2,multibuf); else // sprintf(buf,"%s.cube",multibuf); buf.sprintf("%s.cube",multibuf); mprintf(" Saving 3D Plot as \"%s%s\"...\n",name,(const char*)buf); temp3DF->WriteCube("",name,buf,false); } } } void CObservation::CreateTimeDiff(CDF *df, int comb) { int z2; CxDoubleArray *ptfa; if (m_bSelf) { for (z2=0;z2<((CMolecule*)g_oaMolecules[g_iFixMol])->m_laSingleMolIndex.GetSize()*comb;z2++) { try { ptfa = new CxDoubleArray("CObservation::CreateTimeDiff():ptfa"); } catch(...) { ptfa = NULL; } if (ptfa == NULL) NewException((double)sizeof(CxDoubleArray),__FILE__,__LINE__,__PRETTY_FUNCTION__); if (g_iTrajSteps != -1) { ptfa->SetMaxSize((long)(g_iTrajSteps*1.1)); ptfa->SetGrow((long)(g_iTrajSteps*0.1)); } else ptfa->SetGrow(1000); df->m_oaTimeDiffBuf.Add(ptfa); } } else { for (z2=0;z2<((CMolecule*)g_oaMolecules[g_iFixMol])->m_laSingleMolIndex.GetSize()*((CMolecule*)g_oaMolecules[m_iShowMol])->m_laSingleMolIndex.GetSize()*comb;z2++) { try { ptfa = new CxDoubleArray("CObservation::CreateTimeDiff():ptfa"); } catch(...) { ptfa = NULL; } if (ptfa == NULL) NewException((double)sizeof(CxDoubleArray),__FILE__,__LINE__,__PRETTY_FUNCTION__); if (g_iTrajSteps != -1) { ptfa->SetMaxSize((long)(g_iTrajSteps*1.1)); ptfa->SetGrow((long)(g_iTrajSteps*0.1)); } else ptfa->SetGrow(1000); df->m_oaTimeDiffBuf.Add(ptfa); } } } void CMSD::WriteSplit(const char *s) { FILE *a; int z, z2, z3; CAF *af; a = OpenFileWrite(s,true); mfprintf(a,"# tau [ps]; Total MSD [pm^2]"); for (z=0;zm_oaAtoms.GetSize();z++) for (z2=0;z2<((CxIntArray*)m_pAtomGroup->m_oaAtoms[z])->GetSize();z2++) for (z3=0;z3<((CMolecule*)g_oaMolecules[m_iShowMol])->m_laSingleMolIndex.GetSize();z3++) { if (m_pAtomGroup->m_baRealAtomType[z] == g_iVirtAtomType) mfprintf(a,"; Mol. %d #%d",z3+1,((CxIntArray*)m_pAtomGroup->m_oaAtoms[z])->GetAt(z2)+1); else mfprintf(a,"; Mol. %d %s%d",z3+1,(const char*)((CAtom*)g_oaAtoms[m_pAtomGroup->m_baRealAtomType[z]])->m_sName,((CxIntArray*)m_pAtomGroup->m_oaAtoms[z])->GetAt(z2)+1); } mfprintf(a,"\n"); for (z=0;zm_iResolution;z++) { mfprintf(a,"%f; %f",m_pMSD->m_fMinVal+z*(m_pMSD->m_fMaxVal-m_pMSD->m_fMinVal)/m_pMSD->m_iResolution,m_pMSD->m_pBin[z]); for (z2=0;z2m_iAtomGes;z2++) for (z3=0;z3<((CMolecule*)g_oaMolecules[m_iShowMol])->m_laSingleMolIndex.GetSize();z3++) { af = m_pSplitMSD[z2*((CMolecule*)g_oaMolecules[m_iShowMol])->m_laSingleMolIndex.GetSize()+z3]; mfprintf(a,"; %f",af->m_pBin[z]); } mfprintf(a,"\n"); } fclose(a); } travis-src-190101/src/moltools.h0100777000000000000000000004107113412725657013471 0ustar00/***************************************************************************** TRAVIS - Trajectory Analyzer and Visualizer http://www.travis-analyzer.de/ Copyright (c) 2009-2019 Martin Brehm 2012-2019 Martin Thomas 2016-2019 Sascha Gehrke This file was written by Martin Brehm. --------------------------------------------------------------------------- This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . *****************************************************************************/ #ifndef MOLTOOLS_H #define MOLTOOLS_H // This must always be the first include directive #include "config.h" #include #include #include "bintools.h" #include "xobject.h" #include "xdf.h" #include "xobarray.h" #include "xdvec3array.h" #include "xdoublearray.h" #include "xwordarray.h" #include "xdvector3.h" #include "xdmatrix3.h" #include "nbsearch.h" #include "backtrace.h" #include "statistics.h" #include "xbytearray.h" #include "atomgroup.h" #include "df.h" #include "2df.h" #include "3df.h" //#include "s3df.h" #include "acf.h" #include "aggregate.h" #include "grace.h" #include "element.h" #include "reordyn.h" #include "revsdf.h" #include "nbexchange.h" #include #include #include "largeinteger.h" class CDACF; class CPlProj; class CTimeStep; extern int g_iCDFChannels; //int FindAtom(char *s); class CAtom : public CxObject { public: CAtom(); ~CAtom(); //char m_sName[8]; // Elementsymbol CxString m_sName; int m_iCount; // Wie oft kommt dieses Element in der Simulation vor? bool m_bExclude; // Aus der Molekuelerkennung ausschliessen double m_fCharge; CElement *m_pElement; CAtom *m_pMergedTo; int m_iIndex; }; class CVirtualAtom : public CxObject { public: CVirtualAtom(); ~CVirtualAtom(); int m_iMolVirtAtom; char m_sLabel[8]; CAtomGroup m_oCenterAtoms; //unsigned long m_iIndex; unsigned short m_iMolecule; unsigned char m_iMode; // 0 - Schwerpunkt, 1 - Bond/Angle/Dihedral, 2 - Dipolvektor, 3 - Geschw.-Vektor, 4 - Kraftvektor CxDoubleArray m_faWeight; double m_fGesWeight; int m_iAtomType[3]; int m_iRealAtomType[3]; int m_iAtom[3]; double m_fValues[3]; }; class CMolecule : public CxObject { public: CMolecule(); ~CMolecule(); void BuildName(); int FindAtomInMol(const char *s); void Dump(); CxByteArray m_baAtomIndex; // Welche Atomsorte? -> Verweis auf g_pAtoms CxWordArray m_waAtomCount; // Wie viele von dieser Sorte? CxIntArray m_laSingleMolIndex; // Verweise auf die ganzen konkreten Molekuele dieser Sorte CxIntArray m_laVirtualAtoms; CxObArray m_oaNewNumbers; // Enthaelt CxIntArrays mit den neuen Nummern fuer die Atomsorten CxObArray m_oaRingAtomTypes; // Enthaelt CxWordArray fuer jeden Ring CxObArray m_oaRingAtoms; // Enthaelt CxWordArray fuer jeden Ring int m_iAtomGes; // Gesamtzahl der Atome (inclusive virtueller Atome!) int m_iAtomGesNoVirt; char *m_sName; // Name (String) int m_iWannierCount; double m_fMass; int m_iIndex; int m_iDipoleCenterType; // Atomsorte (fuer Molekuel, nicht global) des Dipolzentrums int m_iDipoleCenterIndex; // Atomnummer des Dipolzentrums double m_fCharge; bool m_bPseudo; bool m_bChargesAssigned; CxObArray m_oaCharges; // std::vector m_saFFLabels; // std::vector m_oaFFAtomTypes; std::vector m_iaFFAtomTypes; std::vector m_faCharges; int m_iDipoleMode; FILE *m_pDipoleFile; int m_iDipoleCommentIndex[3]; int m_iMagneticDipoleMode; FILE *m_pMagneticDipoleFile; int m_iMagneticDipoleCommentIndex[3]; int m_iMagneticDipoleCenterType; int m_iMagneticDipoleCenterIndex; bool m_bPolymer; CxString m_sSMILES; }; class CMolAtom : public CxObject { public: CMolAtom(); ~CMolAtom(); int m_iMolAtomNumber; int m_iType; int m_iNumber; int m_iOffset; double m_fAtomCode; double m_fTempAtomCode; LargeInteger m_liAtomCode; LargeInteger m_liTempAtomCode; CxObArray m_oaBonds; // Pointer auf andere CMolAtoms }; class CSingleMolecule : public CxObject { public: int m_iMolSMIndex; int CountDifferentAtomCodes(); void BuildAtomCodes(); CSingleMolecule(); ~CSingleMolecule(); void Dump(); CxObArray m_oaBondGroups; CxObArray m_oaBonds; CxObArray m_oaAngleGroups; CxObArray m_oaAngles; CxObArray m_oaRings; // Enthaelt ein CxWordArray fuer jeden Ring CxIntArray m_laBonds; CxIntArray m_laWannier; CxObArray m_oaAtomOffset; // Enthaelt ein CxIntArray fuer jede Atomsorte CxObArray m_oaMolAtoms; // Enthaelt ein CMolAtom fuer jedes Atom int m_iAtomClasses; int m_iIndex; CxByteArray m_baAtomIndex; int m_iMolType; double m_polarizability[9]; bool m_bPseudo; double m_fCharge; // Unit: e CxDVector3 m_vDipole; // Unit: Debye CxDMatrix3 m_mQuadrupole; // Unit: Debye*pm CxDVector3 m_vCurrent; // Unit: MB/pm CxDVector3 m_vMagneticDipole; // Unit: MB }; class CADF : public CXDF { public: void CopyFrom(CADF *p); void ParseCondition(int rm, bool nocrit); void ParseConditionGrid(int rm, int gridmode); CADF(); ~CADF(); void BuildAtomList(CSingleMolecule *ref, CSingleMolecule *obs, CxIntArray *vec); void Parse(); void ParseCondition_OnlyValues(); bool m_bOrtho[2]; int m_iRefOrSec[2][3]; // 0 = Ref, 1 = Obs, 2 = Obs2 int m_iVecType[2]; // 0 = Ort, 1 = Dipol, 2 = Geschw., 3 = Kraft bool m_bStat; // bool m_bSameFoot; bool m_bMirror; // bool m_bSaveAngle; FILE **m_fAngle; double m_fMinAngle, m_fMaxAngle; CxDoubleArray m_faMinMaxAngle; bool m_bFoldAngle; CDF *m_pADF; void BuildName(); // bool m_bOthers; bool m_bCosine; CxObArray m_oaVectors; // Enthaelt CAtomGroups, 6 pro Vektor-Satz }; class CDDF : public CXDF { public: CDDF(); ~CDDF(); void BuildAtomList(CSingleMolecule *ref, CSingleMolecule *obs, CxIntArray *vec); void BuildName(); void Parse(); bool m_bOrtho[3]; int m_iRefOrSec[3][3]; CxObArray m_oaVectors; // Enthaelt CAtomGroups, 9 pro Vektor-Satz bool m_bClassical; double m_fMinAngle, m_fMaxAngle; CDF *m_pDDF; // bool m_bSaveAngle; FILE **m_fAngle; // bool m_bOthers; bool m_bCosine; bool m_bAbs; bool m_bPositive; bool m_bSymm; bool m_bRotate; CxDoubleArray m_faLastData; CxIntArray m_laRotation; }; class CMSD : public CxObject { public: void WriteSplit(const char *s); void BuildName(); void Parse(); CMSD(); ~CMSD(); int m_iShowAtoms; int m_iShowMol; int m_iResolution; int m_iStride; int m_iStride2; CAF *m_pMSD; CAF **m_pSplitMSD; char *m_sName; CAtomGroup *m_pAtomGroup; CxObArray m_oaCache; bool m_bSplit; bool m_bTakeX; bool m_bTakeY; bool m_bTakeZ; }; class CRDF : public CXDF { public: bool m_bLongMode; void CopyFrom(CRDF *p); CRDF(); ~CRDF(); void BuildAtomList(CSingleMolecule *ref, CSingleMolecule *obs, CxIntArray *vec); void BuildName(); void Parse(); void ParseCondition(int rm, CNbSearch *n, bool nbana); void ParseConditionGrid(int rm, CNbSearch *n, int gridmode); void ParseCondition_OnlyValues(CNbSearch *n); int m_iRefOrSec[2]; double m_fMinDist, m_fMaxDist; CxDoubleArray m_faMinMaxDist; FILE **m_fDist; // CStatistics *m_pDistStat; CDF *m_pRDF; CxObArray m_oaVectors; // Enthaelt CAtomGroups, 2 pro Vektor-Satz int m_iShowAtomGes; int m_iRefAtomGes; bool m_bAdaptive; bool m_bRadialCorrect; bool m_bProbDens; int m_iSDBlocks; int m_iSDBlockMin; int m_iSDBlockMax; bool m_bSDVerbose; double m_fSDTimesSigma; bool m_bLine; }; class CPlDF : public CXDF { public: // void CopyFrom(CPlDF *p); CPlDF(); ~CPlDF(); void BuildAtomList(CSingleMolecule *ref, CSingleMolecule *obs, CxIntArray *vec); void BuildName(); void Parse(); int m_iRefOrSec[4]; bool m_bNormal; double m_fMinDist, m_fMaxDist; CDF *m_pPlDF; CxObArray m_oaVectors; // Enthaelt CAtomGroups, 4 pro Vektor-Satz int m_iShowAtomGes; int m_iRefAtomGes; }; class CLiDF : public CXDF { public: // void CopyFrom(CLiDF *p); CLiDF(); ~CLiDF(); void BuildAtomList(CSingleMolecule *ref, CSingleMolecule *obs, CxIntArray *vec); void BuildName(); void Parse(); int m_iRefOrSec[4]; double m_fMinDist, m_fMaxDist; CDF *m_pLiDF; CxObArray m_oaVectors; // Enthaelt CAtomGroups, 4 pro Vektor-Satz int m_iShowAtomGes; int m_iRefAtomGes; bool m_bRadialCorrect; bool m_bNormal; }; class CDensDF : public CXDF { public: void CopyFrom(CRDF *p); CDensDF(); ~CDensDF(); void BuildName(); void Parse(); double m_fMinDist, m_fMaxDist; int m_iCenterAtomType; int m_iCenterAtomRealType; int m_iCenterAtom; CDF *m_pDensDF; bool m_bDensityMass; bool *m_pDensityMolSelect; CAtomGroup **m_pDensityMolAG; }; class CVHDF : public CxObject { public: bool m_bSelf; void CorrectCount(); CVHDF(); ~CVHDF(); void BuildAtomList(CSingleMolecule *ref, CSingleMolecule *obs, CxIntArray *vec); void BuildName(); void Parse(); char *m_sName; char *m_sShortName; int m_iRefOrSec[2]; double m_fMinDist, m_fMaxDist; int m_iResolution; int m_iDepth; int m_iStride; C2DF *m_pVHDF; double *m_pCount; CxObArray m_oaVectors; // Enthaelt CAtomGroups, 2 pro Vektor-Satz int m_iShowAtomGes; int m_iRefAtomGes; int m_iShowMol; int m_iCombinations; bool m_bRadialCorrect; bool m_bSwapAxes; int m_iGraceBunchTime; int m_iGraceBunchDist; }; class CVDF : public CXDF { public: bool m_bScanRange; CVDF(); ~CVDF(); void BuildAtomList(CSingleMolecule *ref, CSingleMolecule *obs, CxIntArray *vec); void BuildName(); void Parse(); bool m_bSplitCart; int m_iRefOrSec; double m_fMinSpeed, m_fMaxSpeed; FILE **m_fSpeed; // bool m_bSaveSpeed; CDF *m_pVDF; CDF *m_pVDFSplit[6]; CAtomGroup m_oAtoms; int m_iShowAtomGes; // int m_iRefAtomGes; }; class CDipDF : public CXDF { public: CDipDF(); ~CDipDF(); void BuildName(); void Parse(); int m_iRefOrSec; double m_fDipoleMin, m_fDipoleMax; // bool m_bSaveDipole; FILE **m_fDipole; CDF *m_pDipoleDF; }; class CSDF : public CxObject { public: bool m_bVdWSpheres; bool m_bCutPlane; void CreateCutPlane(); bool m_bIntra; CSDF(); ~CSDF(); void BuildAtomList(CSingleMolecule *ref, CSingleMolecule *obs, CxIntArray *vec); void BuildName(); void Parse(bool voro); int m_iRefOrSec; char *m_sName; double m_fRadius; int m_iResolution; int m_iHistogramRes; bool m_bSDFMirrorXY; bool m_bSDFMirrorBisect; int m_iShowMol; CxDVec3Array *m_vaData; CxDoubleArray *m_faRadius; C3DF *m_pSDF; CAtomGroup m_oAtoms; double m_fParticleDensity; int m_iShowAtomGes; bool m_bClipPlane; int m_iClipDirection; double m_fClipValue; bool m_bInvert; double m_fPosCounter; double m_fAtom2PosX; double m_fAtom3PosX; double m_fAtom3PosY; int m_iCutPlaneResolution; bool m_bCutPlaneShowAtoms; C2DF *m_pCutPlane; CxByteArray *m_baDataEnabled; }; class CCDF : public CxObject { public: double m_fFactor; CCDF(); ~CCDF(); inline void AddToBin(double *d) { int z; if (m_bDumpDat) { for (z=0;zAddToBin(d[0],d[1]); } // bool *m_bChannelAll; // Soll dieser Kanal nur das aktuelle OM oder alle liefern? char *m_sName; char *m_sShortName; FILE **m_fTimeDev; C2DF *m_p2DF; C2DF *m_pTensorProduct; C2DF *m_pDiffFunction; C3DF *m_p3DF; CNDF *m_pNDF; bool m_bDumpDat; // bool m_bTimeDev; FILE *m_fDump; char m_iNormalize; double m_fNormValue; int *m_iCombinations; int m_iCombinationProd; int m_iCombinationsEnabled; char *m_pCombineList; int *m_iResolution; bool m_bGraceBunch; int m_iGraceBunchC1; int m_iGraceBunchC2; bool m_b3DSlices; int m_i3DSliceIntervals[3]; bool m_bAxisDivide; bool m_bAxisDivideAll; bool m_bTDAnimation; int m_iTDASteps; int m_iTDAStride; int m_iTDATail; int m_iTDAResX; int m_iTDAResY; bool m_bTDATrace; CGrace *m_pTDAPlot; int m_iHistogramRes; }; class CConditionSubGroup : public CxObject { public: CNbSearch* AddSingleCondition(int rm, int sm, int gridmode); void ReScan(CSingleMolecule *rm); void CopyResults(CConditionSubGroup *p); void Parse_OnlyValues(); void CopyFrom(CConditionSubGroup *p); void Reset(); int m_iShowMol; int m_iCombinations; void PrintSingle(int om); int m_iNumber; void PrintData(); void PrintData(FILE *a); void Parse(int rm, int sm); // void ScanNeighborhood(CTimeStep *t, int rm, int mol, bool markpassedatoms); void MarkPassedAtoms(int om); // void ScanNeighborhoodSingleOM(CTimeStep *t, CSingleMolecule *rm, int om, bool markpassedatoms, bool fold); void ScanNeighborhoodAllOM(CTimeStep *t, CSingleMolecule *rm); void PreScanNeighborhoodAllOM(CTimeStep *t, CSingleMolecule *rm); // void Clear(); bool Contains(int mol); CConditionSubGroup(); ~CConditionSubGroup(); CxObArray m_oaConditions; double m_fPassed; double m_fTotal; bool *m_bTempPassed; }; class CConditionGroup : public CxObject { public: CNbSearch* AddSingleCondition(int rm, int sm, int gridmode); void ReScan(CSingleMolecule *rm); void CopyResults(CConditionGroup *p); void Parse_OnlyValues(); void CopyFrom(CConditionGroup *p); void Reset(); void PrintTable(); void PrintSingle(int om); void PrintData(); void PrintData(const char *s); CConditionGroup(); ~CConditionGroup(); void Parse(int rm, int sm); // void ScanNeighborhood(CTimeStep *t, int rm, int mol, bool markpassedatoms); void MarkPassedAtoms(int om, bool passed); // void ScanNeighborhoodSingleOM(CTimeStep *t, CSingleMolecule *rm, int om, bool markpassedatoms, bool fold); void ScanNeighborhoodAllOM(CTimeStep *t, CSingleMolecule *rm); void PreScanNeighborhoodAllOM(CTimeStep *t, CSingleMolecule *rm); // void Clear(); bool Contains(int mol); bool m_bInactive; int m_iShowMol; int m_iRefMol; unsigned long m_iHistoGes; bool m_bAnyPassed; int m_iTempPassed; double m_fTableGes; double m_fPassed; double m_fTotal; bool m_bInvertCondition; CxObArray m_oaConditionSubGroups; double *m_pTable; unsigned long *m_pHistogram; bool *m_bAlwaysTrue; long *m_iPassCounter; long *m_iRMPassCounter; long *m_iOMPassCounter; // bool m_bNeedNbCountMode; }; class CObservation : public CxObject { public: void CreateTimeDiff(CDF *df, int comb); void WriteTimeDiff(CDF *df, const char *anaup, const char *analow, const char *name, const char *multibuf, bool ddf); void BuildTimeDiff(CDF *df, bool ddf); void ListCDFObservations(int z); CObservation(); ~CObservation(); int m_iShowMol; // In welchem Molekuel beobachten wir Atome? int m_iShowMolCount; bool m_bSecondShowMol; int m_iShowMol2; int m_iShowMol2Count; bool m_bExclude1eq2; bool m_bSelf; bool m_bOthers; bool m_bTimeDev; bool m_bSaveSeparateFiles; bool m_bVelocityRelToRef; CxWordArray m_waSaveRefList; CxWordArray m_waSaveShowList; CxWordArray m_waObsRefList; CxWordArray m_waObsShowList; CxWordArray m_waObsShow2List; bool m_bObsCertain; bool m_bDecompDist; bool m_bDecompType; CxWordArray m_waDecompTypeRefOffs; CxWordArray m_waDecompTypeObsOffs; CxWordArray m_waDecompTypeRefList; CxWordArray m_waDecompTypeObsList; bool m_bTimeDiff; bool m_b3DTimeDiff; int m_iTimeDiffDepth; int m_iTimeDiffRes3D; int m_iTimeDiffStride3D; double m_fTimeDiffMinVal3D; double m_fTimeDiffMaxVal3D; int m_iTimeDiffDistSteps; int m_iTimeDiffDistResX; int m_iTimeDiffDistResY; double m_fTimeDiffDistMinValX; double m_fTimeDiffDistMaxValX; double m_fTimeDiffDistMinValY; double m_fTimeDiffDistMaxValY; bool m_bCombinedGreyMode; int m_iCombinedGreyMin; int m_iCombinedGreyMax; int m_iCombinedGreyShades; bool m_bCombinedPlot; bool m_bBinOnlyPassedAtoms; bool m_bBinOnlyNotPassedAtoms; CxIntArray m_iaRMRegions; CxIntArray m_iaOM1Regions; CxIntArray m_iaOM2Regions; CConditionGroup *m_pConditions; CConditionGroup *m_pConditionsOM2; CReorDyn *m_pRDyn; CReorDyn *m_pIRSpec; CPlProj *m_pPlProj; CDensDF *m_pDensityDF; CRevSDF *m_pRevSDF; CVHDF *m_pVHDF; CMSD *m_pMSD; CSDF *m_pSDF; CCDF *m_pCDF; CACF *m_pVACF; CACF *m_pDipACF; CADF **m_pADF; CDDF **m_pDDF; CRDF **m_pRDF; CDipDF **m_pDipDF; CVDF **m_pVDF; CPlDF **m_pPlDF; CLiDF **m_pLiDF; CNbAnalysis *m_pNbAnalysis; CNbExchange *m_pNbExchange; CDACF *m_pDACF; bool m_bCondDevelopment; FILE *m_pCondDevelopment; std::vector m_iaCondDevelopmentCounter; int m_iCondDevelopmentMax; int m_iCondDevelopmentAvg; }; #endif travis-src-190101/src/nbexchange.cpp0100777000000000000000000000310313412725627014245 0ustar00/***************************************************************************** TRAVIS - Trajectory Analyzer and Visualizer http://www.travis-analyzer.de/ Copyright (c) 2009-2019 Martin Brehm 2012-2019 Martin Thomas 2016-2019 Sascha Gehrke This file was written by Martin Brehm. --------------------------------------------------------------------------- This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . *****************************************************************************/ // This must always be the first include directive #include "config.h" #include "nbexchange.h" #include "moltools.h" #include "globalvar.h" const char *GetRevisionInfo_nbexchange(unsigned int len) { static char buf[256]; GET_REVISION_INFO( buf, len ); return buf; } const char *GetSourceVersion_nbexchange() { static char buf[256]; GET_SOURCE_VERSION( buf ); return buf; } CNbExchange::CNbExchange() { } CNbExchange::~CNbExchange() { } travis-src-190101/src/nbexchange.h0100777000000000000000000000343213412725660013714 0ustar00/***************************************************************************** TRAVIS - Trajectory Analyzer and Visualizer http://www.travis-analyzer.de/ Copyright (c) 2009-2019 Martin Brehm 2012-2019 Martin Thomas 2016-2019 Sascha Gehrke This file was written by Martin Brehm. --------------------------------------------------------------------------- This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . *****************************************************************************/ #ifndef NBEXCHANGE_H #define NBEXCHANGE_H // This must always be the first include directive #include "config.h" #include "xobject.h" #include "xobarray.h" #include "df.h" #include "nbsearch.h" class CConditionGroup; class CNbExchangePair : public CxObject { public: CNbExchangePair() { } ~CNbExchangePair() { } unsigned int m_iShowMol; unsigned char m_iStillAlive; int m_iStart; int m_iEnd; // double m_fDistance; // unsigned short m_iNeighbor; }; class CNbExchange : public CxObject { public: CNbExchange(); ~CNbExchange(); bool m_bDifferentCrit; CNbSearch *m_pNbSearch; int m_iTimeDepth; CConditionGroup **m_pNbExConditions; }; #endif travis-src-190101/src/nbsearch.cpp0100777000000000000000000021067413412725624013742 0ustar00/***************************************************************************** TRAVIS - Trajectory Analyzer and Visualizer http://www.travis-analyzer.de/ Copyright (c) 2009-2019 Martin Brehm 2012-2019 Martin Thomas 2016-2019 Sascha Gehrke This file was written by Martin Brehm. --------------------------------------------------------------------------- This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . *****************************************************************************/ // This must always be the first include directive #include "config.h" #include "nbsearch.h" #include "travis.h" #include "maintools.h" const char *GetRevisionInfo_nbsearch(unsigned int len) { static char buf[256]; GET_REVISION_INFO( buf, len ); return buf; } const char *GetSourceVersion_nbsearch() { static char buf[256]; GET_SOURCE_VERSION( buf ); return buf; } CNbPair::CNbPair() { m_fDistances = NULL; m_fAngles = NULL; m_bDistPassed = NULL; m_bAnglePassed = NULL; m_bAnyAnglePassed = false; m_bAnyDistPassed = false; m_iMinDistIndex = -1; m_laDistAtomList.SetName("CNbPair::m_laDistAtomList"); m_laAngleAtomList.SetName("CNbPair::m_laAngleAtomList"); } CNbPair::~CNbPair() { } void CNbPair::Check(CNbSearch *parent, CTimeStep *ts, CSingleMolecule *rm, CSingleMolecule *sm) { int z, z2; CxDVector3 vec1, vec2, veca, vecb, vecc; if (parent->m_pRDF != NULL) { m_bAnyDistPassed = false; m_fMinDist = 1E30; m_laDistAtomList.RemoveAll_KeepSize(); parent->m_pRDF->BuildAtomList(rm,sm,&m_laDistAtomList); for (z=0;zm_vaCoords[m_laDistAtomList[z*2]]-ts->m_vaCoords[m_laDistAtomList[z*2+1]]); if (m_fDistances[z] < m_fMinDist) { m_fMinDist = m_fDistances[z]; m_iMinDistIndex = z; } m_bDistPassed[z] = false; for (z2=0;z2m_pRDF->m_faMinMaxDist.GetSize();z2+=2) { if ((m_fDistances[z] >= parent->m_pRDF->m_faMinMaxDist[z2]) && (m_fDistances[z] <= parent->m_pRDF->m_faMinMaxDist[z2+1])) { m_bAnyDistPassed = true; m_bDistPassed[z] = true; break; } } } } else { m_bAnyDistPassed = true; m_bDistPassed[0] = true; } if (parent->m_pADF != NULL) { m_bAnyAnglePassed = false; m_laAngleAtomList.RemoveAll_KeepSize(); parent->m_pADF->BuildAtomList(rm,sm,&m_laAngleAtomList); for (z=0;zm_pADF->m_bOrtho[0]) { veca = ts->m_vaCoords[m_laAngleAtomList[z*6]]; vecb = ts->m_vaCoords[m_laAngleAtomList[z*6+1]]; vecc = ts->m_vaCoords[m_laAngleAtomList[z*6+2]]; vec1 = CrossP(FoldVector(vecb-veca),FoldVector(vecc-veca)); } else { veca = ts->m_vaCoords[m_laAngleAtomList[z*6]]; vecb = ts->m_vaCoords[m_laAngleAtomList[z*6+1]]; vec1 = FoldVector(vecb-veca); } if (parent->m_pADF->m_bOrtho[1]) { veca = ts->m_vaCoords[m_laAngleAtomList[z*6+3]]; vecb = ts->m_vaCoords[m_laAngleAtomList[z*6+4]]; vecc = ts->m_vaCoords[m_laAngleAtomList[z*6+5]]; vec2 = CrossP(FoldVector(vecb-veca),FoldVector(vecc-veca)); } else { veca = ts->m_vaCoords[m_laAngleAtomList[z*6+3]]; vecb = ts->m_vaCoords[m_laAngleAtomList[z*6+4]]; vec2 = FoldVector(vecb-veca); } m_fAngles[z] = Angle_Deg(vec1,vec2); m_bAnglePassed[z] = false; for (z2=0;z2m_pADF->m_faMinMaxAngle.GetSize();z2+=2) { if ((m_fAngles[z] >= parent->m_pADF->m_faMinMaxAngle[z2]) && (m_fAngles[z] <= parent->m_pADF->m_faMinMaxAngle[z2+1])) { m_bAnyAnglePassed = true; m_bAnglePassed[z] = true; break; } } } } else { m_bAnyAnglePassed = true; m_bAnglePassed[0] = true; } // mprintf("Pair: Angle=%f --> %s.\n",m_fAngles[0],m_bAnglePassed[0]?"passed.":"failed."); } void CNbPair::PreCheck(CNbSearch *parent, CTimeStep *ts, CSingleMolecule *rm, CSingleMolecule *sm) { int z, z2; CxDVector3 vec1, vec2, veca, vecb, vecc; if (parent->m_pRDF != NULL) { m_fMinDist = 1E30; m_laDistAtomList.RemoveAll_KeepSize(); parent->m_pRDF->BuildAtomList(rm,sm,&m_laDistAtomList); // mprintf("$$ NbPair %08X PreCheck %d\n",this,m_laDistAtomList.GetSize()/2); for (z=0;zm_vaCoords[m_laDistAtomList[z*2]]-ts->m_vaCoords[m_laDistAtomList[z*2+1]]); // mprintf(" %d: %f\n",z,m_fDistances[z]); if (m_fDistances[z] < m_fMinDist) { m_fMinDist = m_fDistances[z]; m_iMinDistIndex = z; } } } else { m_bAnyDistPassed = true; m_bDistPassed[0] = true; } if (parent->m_pADF != NULL) { m_bAnyAnglePassed = false; m_laAngleAtomList.RemoveAll_KeepSize(); parent->m_pADF->BuildAtomList(rm,sm,&m_laAngleAtomList); for (z=0;zm_pADF->m_bOrtho[0]) { veca = ts->m_vaCoords[m_laAngleAtomList[z*6]]; vecb = ts->m_vaCoords[m_laAngleAtomList[z*6+1]]; vecc = ts->m_vaCoords[m_laAngleAtomList[z*6+2]]; vec1 = CrossP(FoldVector(vecb-veca),FoldVector(vecc-veca)); } else { veca = ts->m_vaCoords[m_laAngleAtomList[z*6]]; vecb = ts->m_vaCoords[m_laAngleAtomList[z*6+1]]; vec1 = FoldVector(vecb-veca); } if (parent->m_pADF->m_bOrtho[1]) { veca = ts->m_vaCoords[m_laAngleAtomList[z*6+3]]; vecb = ts->m_vaCoords[m_laAngleAtomList[z*6+4]]; vecc = ts->m_vaCoords[m_laAngleAtomList[z*6+5]]; vec2 = CrossP(FoldVector(vecb-veca),FoldVector(vecc-veca)); } else { veca = ts->m_vaCoords[m_laAngleAtomList[z*6+3]]; vecb = ts->m_vaCoords[m_laAngleAtomList[z*6+4]]; vec2 = FoldVector(vecb-veca); } m_fAngles[z] = Angle_Deg(vec1,vec2); m_bAnglePassed[z] = false; for (z2=0;z2m_pADF->m_faMinMaxAngle.GetSize();z2+=2) { if ((m_fAngles[z] >= parent->m_pADF->m_faMinMaxAngle[z2]) && (m_fAngles[z] <= parent->m_pADF->m_faMinMaxAngle[z2+1])) { m_bAnyAnglePassed = true; m_bAnglePassed[z] = true; break; } } } } else { m_bAnyAnglePassed = true; m_bAnglePassed[0] = true; } } CExtendedCondition::CExtendedCondition() { } CExtendedCondition::~CExtendedCondition() { } CNbSearch::CNbSearch() { m_pRDF = NULL; m_pADF = NULL; m_iNbCountMin = -1; m_bInactive = false; m_pNbSort = NULL; m_pDistances = NULL; m_pAngles = NULL; m_oaNbPairs.SetName("CNbSearch::m_oaNbPairs"); m_oaExtendedConditions.SetName("CNbSearch::m_oaExtendedConditions"); } CNbSearch::~CNbSearch() { } void CNbSearch::MarkPassedAtoms(int om) { int /*z,*/ z2, z3, z4; CNbPair *n; n = (CNbPair*)m_oaNbPairs[om]; /* mprintf("****A****\n"); for (z=0;zm_laDistAtomList[z4]] == 110) g_baAtomPassedCondition[n->m_laDistAtomList[z4]] = 0; } if (m_pADF != NULL) { for (z3=0;z3m_laAngleAtomList[z3*6]] == 110) g_baAtomPassedCondition[n->m_laAngleAtomList[z3*6]] = 0; if (g_baAtomPassedCondition[n->m_laAngleAtomList[z3*6+1]] == 110) g_baAtomPassedCondition[n->m_laAngleAtomList[z3*6+1]] = 0; if (m_pADF->m_bOrtho[0]) if (g_baAtomPassedCondition[n->m_laAngleAtomList[z3*6+2]] == 110) g_baAtomPassedCondition[n->m_laAngleAtomList[z3*6+2]] = 0; if (g_baAtomPassedCondition[n->m_laAngleAtomList[z3*6+3]] == 110) g_baAtomPassedCondition[n->m_laAngleAtomList[z3*6+3]] = 0; if (g_baAtomPassedCondition[n->m_laAngleAtomList[z3*6+4]] == 110) g_baAtomPassedCondition[n->m_laAngleAtomList[z3*6+4]] = 0; if (m_pADF->m_bOrtho[1]) if (g_baAtomPassedCondition[n->m_laAngleAtomList[z3*6+5]] == 110) g_baAtomPassedCondition[n->m_laAngleAtomList[z3*6+5]] = 0; } } /* mprintf("****B****\n"); for (z=0;zm_bDistPassed[z2] && n->m_bAnglePassed[z3]) { // mprintf("@ Blubb 0\n"); if (m_bCombinationMatrix[z2*m_iAngles+z3]) { // mprintf("@ Blubb\n"); if (m_pRDF) { for (z4=z2*2;z4m_laDistAtomList[z4]] == 0) g_baAtomPassedCondition[n->m_laDistAtomList[z4]] = 1; } if (m_pADF) { if (g_baAtomPassedCondition[n->m_laAngleAtomList[z3*6]] == 0) g_baAtomPassedCondition[n->m_laAngleAtomList[z3*6]] = 1; if (g_baAtomPassedCondition[n->m_laAngleAtomList[z3*6+1]] == 0) g_baAtomPassedCondition[n->m_laAngleAtomList[z3*6+1]] = 1; if (m_pADF->m_bOrtho[0]) if (g_baAtomPassedCondition[n->m_laAngleAtomList[z3*6+2]] == 0) g_baAtomPassedCondition[n->m_laAngleAtomList[z3*6+2]] = 1; if (g_baAtomPassedCondition[n->m_laAngleAtomList[z3*6+3]] == 0) g_baAtomPassedCondition[n->m_laAngleAtomList[z3*6+3]] = 1; if (g_baAtomPassedCondition[n->m_laAngleAtomList[z3*6+4]] == 0) g_baAtomPassedCondition[n->m_laAngleAtomList[z3*6+4]] = 1; if (m_pADF->m_bOrtho[1]) if (g_baAtomPassedCondition[n->m_laAngleAtomList[z3*6+5]] == 0) g_baAtomPassedCondition[n->m_laAngleAtomList[z3*6+5]] = 1; } } } } } /* mprintf("****C****\n"); for (z=0;zm_laSingleMolIndex.GetSize(); m_fCombinationsTotal += ((CMolecule*)g_oaMolecules[m_iObsMol])->m_laSingleMolIndex.GetSize() * m_iDistances * m_iAngles; ti3 = 0; for (z=0;z<((CMolecule*)g_oaMolecules[m_iObsMol])->m_laSingleMolIndex.GetSize();z++) { n = (CNbPair*)m_oaNbPairs[z]; m_bPassed[z] = false; anypassed = false; m_iCombPassCount[z] = 0; if ((rm->m_iMolSMIndex == z) && (rm->m_iMolType == m_iObsMol)) { n->m_fMinDist = 9e20; continue; } n->Check(this,t,rm,(CSingleMolecule*)g_oaSingleMolecules[((CMolecule*)g_oaMolecules[m_iObsMol])->m_laSingleMolIndex[z]]); // mprintf("A\n"); if (m_iNbCountMin <= -1) // Abstands-Modus { // mprintf("B\n"); for (z2=0;z2m_bDistPassed[z2]) { anypassed = true; m_fCombinationsFound[(z2+1)*(m_iAngles+1)] += 1.0; //m_iAngles; } } for (z3=0;z3m_bAnglePassed[z3]) { anypassed = true; m_fCombinationsFound[z3+1] += 1.0; //m_iDistances; } } /* mprintf("$$$ davor\n"); for (z2=0;z2m_bDistPassed[z2]); for (z3=0;z3m_bAnglePassed[z3]);*/ for (z2=0;z2m_bDistPassed[z2] && n->m_bAnglePassed[z3]) { // mprintf("C\n"); m_fCombinationsFound[(z2+1)*(m_iAngles+1)+z3+1]++; if (m_bCombinationMatrix[z2*m_iAngles+z3]) { // mprintf("D\n"); if (m_bExtendedMode) { // mprintf("E\n"); if (CheckExtended(n->m_fDistances[z2],n->m_fAngles[z3])) { // mprintf("%f | %f passed: Dist %d Angle %d\n",n->m_fDistances[z2],n->m_fAngles[z3],n->m_bDistPassed[z2],n->m_bAnglePassed[z3]); if (!m_bPassed[z]) { ti3++; m_bPassed[z] = true; m_iPassCounter[z]++; } m_iCombPassCount[z]++; m_fCombinationsPassed++; } else { n->m_bDistPassed[z2] = false; n->m_bAnglePassed[z3] = false; } } else { if (!m_bPassed[z]) { ti3++; m_bPassed[z] = true; m_iPassCounter[z]++; } m_iCombPassCount[z]++; m_fCombinationsPassed++; } } } } } /* mprintf("$$$ danach\n"); for (z2=0;z2m_bDistPassed[z2]); for (z3=0;z3m_bAnglePassed[z3]);*/ if (anypassed) m_fCombinationsFound[0] += 1.0; //m_iDistances * m_iAngles; if (m_bPassed[z]) m_fMoleculesPassed++; } // Ende Abstandsmodus } if (m_iNbCountMin > -1) // Nachbar-Anzahl-Modus { SortNeighbors(); for (z=0;z<((CMolecule*)g_oaMolecules[m_iObsMol])->m_laSingleMolIndex.GetSize();z++) { ti = m_pNbSort[z].m_iOM; if ((rm->m_iMolSMIndex == ti) && (rm->m_iMolType == m_iObsMol)) continue; n = (CNbPair*)m_oaNbPairs[ti]; if ((z >= m_iNbCountMin) && (z <= m_iNbCountMax)) { n->m_bAnyDistPassed = true; n->m_bDistPassed[n->m_iMinDistIndex] = true; if (n->m_bAnyAnglePassed) { m_bPassed[ti] = true; m_iPassCounter[ti]++; m_fMoleculesPassed++; m_fCombinationsFound[0] += m_iDistances * m_iAngles; } else m_bPassed[ti] = false; } else { n->m_bAnyDistPassed = false; m_bPassed[ti] = false; } } } } void CNbSearch::PreScanAllOM(CSingleMolecule *rm, CTimeStep *t) { int z; CNbPair *n; // mprintf("************* this=%08X, RM = %d ******************\n",this,rm->m_iMolSMIndex); for (z=0;z<((CMolecule*)g_oaMolecules[m_iObsMol])->m_laSingleMolIndex.GetSize();z++) { n = (CNbPair*)m_oaNbPairs[z]; // mprintf("@ PreScanAllOM %d/%d\n",z,((CMolecule*)g_oaMolecules[m_iObsMol])->m_laSingleMolIndex.GetSize()); if ((rm->m_iMolSMIndex == z) && (rm->m_iMolType == m_iObsMol)) { // mprintf("Cont.\n"); continue; } n->PreCheck(this,t,rm,(CSingleMolecule*)g_oaSingleMolecules[((CMolecule*)g_oaMolecules[m_iObsMol])->m_laSingleMolIndex[z]]); // mprintf(" i=%d\n",n->m_iMinDistIndex); } if (m_iNbCountMin > -1) // Nachbar-Anzahl-Modus SortNeighbors(); } void CNbSearch::Create(int obs) { int z; CNbPair *n; try { m_bPassed = new bool[((CMolecule*)g_oaMolecules[obs])->m_laSingleMolIndex.GetSize()]; } catch(...) { m_bPassed = NULL; } if (m_bPassed == NULL) NewException((double)((CMolecule*)g_oaMolecules[obs])->m_laSingleMolIndex.GetSize()*sizeof(bool),__FILE__,__LINE__,__PRETTY_FUNCTION__); try { m_iCombPassCount = new int[((CMolecule*)g_oaMolecules[obs])->m_laSingleMolIndex.GetSize()]; } catch(...) { m_iCombPassCount = NULL; } if (m_iCombPassCount == NULL) NewException((double)((CMolecule*)g_oaMolecules[obs])->m_laSingleMolIndex.GetSize()*sizeof(int),__FILE__,__LINE__,__PRETTY_FUNCTION__); try { m_iPassCounter = new int[((CMolecule*)g_oaMolecules[obs])->m_laSingleMolIndex.GetSize()]; } catch(...) { m_iPassCounter = NULL; } if (m_iPassCounter == NULL) NewException((double)((CMolecule*)g_oaMolecules[obs])->m_laSingleMolIndex.GetSize()*sizeof(int),__FILE__,__LINE__,__PRETTY_FUNCTION__); if (m_pADF != NULL) m_iAngles = m_pADF->m_iCombinations; else m_iAngles = 1; if (m_pRDF != NULL) m_iDistances = m_pRDF->m_iCombinations; else m_iDistances = 1; m_oaNbPairs.RemoveAll(); try { m_pDistances = new double[m_iDistances*((CMolecule*)g_oaMolecules[obs])->m_laSingleMolIndex.GetSize()]; } catch(...) { m_pDistances = NULL; } if (m_pDistances == NULL) NewException((double)m_iDistances*((CMolecule*)g_oaMolecules[obs])->m_laSingleMolIndex.GetSize()*sizeof(double),__FILE__,__LINE__,__PRETTY_FUNCTION__); try { m_pAngles = new double[m_iAngles*((CMolecule*)g_oaMolecules[obs])->m_laSingleMolIndex.GetSize()]; } catch(...) { m_pAngles = NULL; } if (m_pAngles == NULL) NewException((double)m_iAngles*((CMolecule*)g_oaMolecules[obs])->m_laSingleMolIndex.GetSize()*sizeof(double),__FILE__,__LINE__,__PRETTY_FUNCTION__); for (z=0;z<((CMolecule*)g_oaMolecules[obs])->m_laSingleMolIndex.GetSize();z++) { m_iPassCounter[z] = 0; try { n = new CNbPair(); } catch(...) { n = NULL; } if (n == NULL) NewException((double)sizeof(CNbPair),__FILE__,__LINE__,__PRETTY_FUNCTION__); n->m_fDistances = &m_pDistances[z*m_iDistances]; n->m_fAngles = &m_pAngles[z*m_iAngles]; n->Create(this); m_oaNbPairs.Add(n); } try { m_fCombinationsFound = new double[(m_iAngles+1)*(m_iDistances+1)]; } catch(...) { m_fCombinationsFound = NULL; } if (m_fCombinationsFound == NULL) NewException((double)(m_iAngles+1)*(m_iDistances+1)*sizeof(double),__FILE__,__LINE__,__PRETTY_FUNCTION__); for (z=0;z<(m_iAngles+1)*(m_iDistances+1);z++) m_fCombinationsFound[z] = 0; try { m_bCombinationMatrix = new bool[m_iAngles*m_iDistances]; } catch(...) { m_bCombinationMatrix = NULL; } if (m_bCombinationMatrix == NULL) NewException((double)m_iAngles*m_iDistances*sizeof(bool),__FILE__,__LINE__,__PRETTY_FUNCTION__); m_fCombinationsTotal = 0; m_fCombinationsPassed = 0; m_fMoleculesTotal = 0; m_fMoleculesPassed = 0; } void CNbSearch::Parse(int rm, int om, bool nbana) { CxIntArray wa, tempwa; int z, z2, z3, ti, ti2, ti3; CxObArray *oa; CExtendedCondition *ec; // char buf[256]; CxString buf; mprintf(YELLOW,"\n>>> Condition between %s and %s >>>\n\n",((CMolecule*)g_oaMolecules[rm])->m_sName,((CMolecule*)g_oaMolecules[om])->m_sName); m_iRefMol = rm; m_iObsMol = om; if (nbana) goto _rdf; if (g_bAdvanced2) m_bExtendedMode = AskYesNo(" Use set of linear functions as condition (\"extended mode\") (y/n)? [no] ",false); else m_bExtendedMode = false; if (m_bExtendedMode) { g_bEnvDisableSortNb = true; mprintf(WHITE,"\n For the extended mode you have to define a distance and an angle.\n\n"); try { m_pRDF = new CRDF(); } catch(...) { m_pRDF = NULL; } if (m_pRDF == NULL) NewException((double)sizeof(CRDF),__FILE__,__LINE__,__PRETTY_FUNCTION__); m_pRDF->m_iShowMol = om; m_pRDF->ParseCondition(rm,this,true); try {m_pADF = new CADF(); } catch(...) { m_pADF = NULL; } if (m_pADF == NULL) NewException((double)sizeof(CADF),__FILE__,__LINE__,__PRETTY_FUNCTION__); m_pADF->m_iShowMol = om; m_pADF->ParseCondition(rm,true); mprintf("\n You can now define linear functions of distance and angle.\n"); mprintf(" You can create several blocks of these functions.\n"); mprintf(" The functions in each block are connected with \"AND\" (have to be fulfilled at the same time).\n"); mprintf(" The blocks of functions are connected with \"OR\" (at least one of them has to be fulfilled).\n\n"); mprintf(" For each linear function, you have to enter two distance-angle pairs, which define a line.\n"); mprintf(" A third distange-angle pair controls which side of the line is to be included.\n"); z = 0; z2 = 0; while (true) { mprintf(YELLOW,"\n*** %d. block of functions ***\n",z+1); try { oa = new CxObArray("CNbSearch::Parse():oa"); } catch(...) { oa = NULL; } if (oa == NULL) NewException((double)sizeof(CxObArray),__FILE__,__LINE__,__PRETTY_FUNCTION__); m_oaExtendedConditions.Add(oa); while (true) { try { ec = new CExtendedCondition(); } catch(...) { ec = NULL; } if (ec == NULL) NewException((double)sizeof(CExtendedCondition),__FILE__,__LINE__,__PRETTY_FUNCTION__); oa->Add(ec); mprintf(WHITE,"\n * %d. function in %d. block\n\n",z2+1,z+1); _lineagain: ec->m_fD[0] = AskFloat_ND(" Line point 1 - enter distance value in pm: "); ec->m_fA[0] = AskFloat_ND(" Line point 1 - enter angle value in degree: "); ec->m_fD[1] = AskFloat_ND(" Line point 2 - enter distance value in pm: "); ec->m_fA[1] = AskFloat_ND(" Line point 2 - enter angle value in degree: "); if ((ec->m_fD[1] == ec->m_fD[0]) && (ec->m_fA[1] == ec->m_fA[0])) { eprintf("\n The two points need to be different.\n\n"); goto _lineagain; } _sampleagain: ec->m_fD[2] = AskFloat_ND(" Included sample point - enter distance value in pm: "); ec->m_fA[2] = AskFloat_ND(" Included sample point - enter angle value in degree: "); if (!ec->Evaluate()) { eprintf("\n Sample point may not be located on the line!\n\n"); goto _sampleagain; } mprintf("\n (resulting equation: %G * dist + %G * angle %c %G).\n",ec->m_fX,ec->m_fY,ec->m_bLarger?'>':'<',ec->m_fZ); z2++; mprintf("\n"); if (!AskYesNo(" Add another function to this block (y/n)? [no] ",false)) break; } z++; mprintf("\n"); if (!AskYesNo(" Add another block of functions (y/n)? [no] ",false)) break; } mprintf("\n"); } else // END IF EXTENDED MODE { _condagain: if (AskYesNo(" Do you want to define a distance condition (y/n)? [yes] ",true)) { _rdf: try { m_pRDF = new CRDF(); } catch(...) { m_pRDF = NULL; } if (m_pRDF == NULL) NewException((double)sizeof(CRDF),__FILE__,__LINE__,__PRETTY_FUNCTION__); m_pRDF->m_iShowMol = om; m_pRDF->ParseCondition(rm,this,nbana); } if (!nbana) { if (AskYesNo(" Do you want to define an angular condition (y/n)? [%s] ",(m_pRDF == NULL),(m_pRDF == NULL)?"yes":"no")) { g_bEnvDisableSortNb = true; try { m_pADF = new CADF(); } catch(...) { m_pADF = NULL; } if (m_pADF == NULL) NewException((double)sizeof(CADF),__FILE__,__LINE__,__PRETTY_FUNCTION__); m_pADF->m_iShowMol = om; m_pADF->ParseCondition(rm,false); } } if ((m_pRDF == NULL) && (m_pADF == NULL)) { eprintf("Error: You need to specify at least one condition.\n"); goto _condagain; } } Create(om); if ((m_pADF != NULL) && (m_pRDF != NULL)) { mprintf(WHITE,"\n There are %d distance subconditions:\n",m_iDistances); m_pRDF->BuildAtomList((CSingleMolecule*)g_oaSingleMolecules[((CMolecule*)g_oaMolecules[rm])->m_laSingleMolIndex[0]],(CSingleMolecule*)g_oaSingleMolecules[((CMolecule*)g_oaMolecules[om])->m_laSingleMolIndex[0]],&wa); for (z=0;z %s%d (%s)\n",z+1,(const char*)((CAtom*)g_oaAtoms[g_waAtomRealElement[ti]])->m_sName,g_waAtomMolNumber[ti]+1,((CMolecule*)g_oaMolecules[g_waAtomMolIndex[ti]])->m_sName,(const char*)((CAtom*)g_oaAtoms[g_waAtomRealElement[ti2]])->m_sName,g_waAtomMolNumber[ti2]+1,((CMolecule*)g_oaMolecules[g_waAtomMolIndex[ti2]])->m_sName); } mprintf("\n"); mprintf(WHITE," There are %d angular subconditions:\n",m_iAngles); m_pADF->BuildAtomList((CSingleMolecule*)g_oaSingleMolecules[((CMolecule*)g_oaMolecules[rm])->m_laSingleMolIndex[0]],(CSingleMolecule*)g_oaSingleMolecules[((CMolecule*)g_oaMolecules[om])->m_laSingleMolIndex[0]],&wa); for (z=0;zm_bOrtho[0]) { ti = wa[z*6]; ti2 = wa[z*6+1]; ti3 = wa[z*6+2]; mprintf("[%s%d (%s), %s%d (%s), %s%d (%s)] to ",(const char*)((CAtom*)g_oaAtoms[g_waAtomRealElement[ti]])->m_sName,g_waAtomMolNumber[ti]+1,((CMolecule*)g_oaMolecules[g_waAtomMolIndex[ti]])->m_sName,(const char*)((CAtom*)g_oaAtoms[g_waAtomRealElement[ti2]])->m_sName,g_waAtomMolNumber[ti2]+1,((CMolecule*)g_oaMolecules[g_waAtomMolIndex[ti2]])->m_sName,(const char*)((CAtom*)g_oaAtoms[g_waAtomRealElement[ti3]])->m_sName,g_waAtomMolNumber[ti3]+1,((CMolecule*)g_oaMolecules[g_waAtomMolIndex[ti3]])->m_sName); } else { ti = wa[z*6]; ti2 = wa[z*6+1]; mprintf("[%s%d (%s) --> %s%d (%s)] to ",(const char*)((CAtom*)g_oaAtoms[g_waAtomRealElement[ti]])->m_sName,g_waAtomMolNumber[ti]+1,((CMolecule*)g_oaMolecules[g_waAtomMolIndex[ti]])->m_sName,(const char*)((CAtom*)g_oaAtoms[g_waAtomRealElement[ti2]])->m_sName,g_waAtomMolNumber[ti2]+1,((CMolecule*)g_oaMolecules[g_waAtomMolIndex[ti2]])->m_sName); } if (m_pADF->m_bOrtho[1]) { ti = wa[z*6+3]; ti2 = wa[z*6+4]; ti3 = wa[z*6+5]; mprintf("[%s%d (%s), %s%d (%s), %s%d (%s)]\n",(const char*)((CAtom*)g_oaAtoms[g_waAtomRealElement[ti]])->m_sName,g_waAtomMolNumber[ti]+1,((CMolecule*)g_oaMolecules[g_waAtomMolIndex[ti]])->m_sName,(const char*)((CAtom*)g_oaAtoms[g_waAtomRealElement[ti2]])->m_sName,g_waAtomMolNumber[ti2]+1,((CMolecule*)g_oaMolecules[g_waAtomMolIndex[ti2]])->m_sName,(const char*)((CAtom*)g_oaAtoms[g_waAtomRealElement[ti3]])->m_sName,g_waAtomMolNumber[ti3]+1,((CMolecule*)g_oaMolecules[g_waAtomMolIndex[ti3]])->m_sName); } else { ti = wa[z*6+3]; ti2 = wa[z*6+4]; mprintf("[%s%d (%s) --> %s%d (%s)]\n",(const char*)((CAtom*)g_oaAtoms[g_waAtomRealElement[ti]])->m_sName,g_waAtomMolNumber[ti]+1,((CMolecule*)g_oaMolecules[g_waAtomMolIndex[ti]])->m_sName,(const char*)((CAtom*)g_oaAtoms[g_waAtomRealElement[ti2]])->m_sName,g_waAtomMolNumber[ti2]+1,((CMolecule*)g_oaMolecules[g_waAtomMolIndex[ti2]])->m_sName); } } mprintf("\n"); if (m_iNbCountMin > -1) { mprintf(" Min./max. next neighbor count specified, combining each with each subcondition.\n"); for (z=0;z 1) && (m_iAngles > 1)) { if (m_iDistances == m_iAngles) { if (AskYesNo(" Combine n-th distance subcondition with n-th angular subcondition (y/n)? [yes] ",true)) { for (z=0;z m_iDistances)) { eprintf(" Invalid input, only %d distance subconditions (%d requested).\n",m_iDistances,tempwa[0]); goto _nextcomb; } if ((tempwa[1] < 1) || (tempwa[1] > m_iAngles)) { eprintf(" Invalid input, only %d angle subconditions (%d requested).\n",m_iAngles,tempwa[1]); goto _nextcomb; } tempwa[0]--; tempwa[1]--; if (m_bCombinationMatrix[tempwa[0]*m_iAngles+tempwa[1]]) { eprintf(" This combination has already been added.\n"); goto _nextcomb; } m_bCombinationMatrix[tempwa[0]*m_iAngles+tempwa[1]] = true; goto _nextcomb; _combdone:; } } mprintf("\n"); } else { for (z=0;zGetSize();z2++) { ec = (CExtendedCondition*)oa->GetAt(z2); mprintf(" %G * dist + %G * angle %c %G\n",ec->m_fX,ec->m_fY,ec->m_bLarger?'>':'<',ec->m_fZ); if (z2+1 < oa->GetSize()) mprintf(" AND\n"); } if (z+1 < m_oaExtendedConditions.GetSize()) mprintf("\n OR\n\n"); } } mprintf(YELLOW,"\n<<< End of this condition <<<\n\n"); } void CNbSearch::ParseGrid(int rm, int om, int gridmode) { CxIntArray wa, tempwa; CxObArray *oa; CExtendedCondition *ec; int z, z2, ti, ti2, ti3; // char buf[256]; CxString buf; mprintf(YELLOW,"\n>>> Condition between %s and %s >>>\n\n",((CMolecule*)g_oaMolecules[rm])->m_sName,((CMolecule*)g_oaMolecules[om])->m_sName); m_iRefMol = rm; m_iObsMol = om; if (gridmode == 6) { m_bExtendedMode = AskYesNo(" Use set of linear functions as condition (\"extended mode\") (y/n)? [no] ",false); if (m_bExtendedMode) { mprintf(WHITE,"\n For the extended mode you have to define a distance and an angle.\n\n"); try { m_pRDF = new CRDF(); } catch(...) { m_pRDF = NULL; } if (m_pRDF == NULL) NewException((double)sizeof(CRDF),__FILE__,__LINE__,__PRETTY_FUNCTION__); m_pRDF->m_iShowMol = om; m_pRDF->ParseCondition(rm,this,true); try { m_pADF = new CADF(); } catch(...) { m_pADF = NULL; } if (m_pADF == NULL) NewException((double)sizeof(CADF),__FILE__,__LINE__,__PRETTY_FUNCTION__); m_pADF->m_iShowMol = om; m_pADF->ParseCondition(rm,true); mprintf("\n You can now define linear functions of distance and angle.\n"); mprintf(" You can create several blocks of these functions.\n"); mprintf(" The functions in each block are connected with \"AND\" (have to be fulfilled at the same time).\n"); mprintf(" The blocks of functions are connected with \"OR\" (at least one of them has to be fulfilled).\n\n"); mprintf(" For each linear function, you have to enter two distance-angle pairs, which define a line.\n"); mprintf(" A third distange-angle pair controls which side of the line is to be included.\n"); z = 0; z2 = 0; while (true) { mprintf(YELLOW,"\n*** %d. block of functions ***\n",z+1); try { oa = new CxObArray("CNbSearch::ParseGrid():oa"); } catch(...) { oa = NULL; } if (oa == NULL) NewException((double)sizeof(CxObArray),__FILE__,__LINE__,__PRETTY_FUNCTION__); m_oaExtendedConditions.Add(oa); while (true) { try { ec = new CExtendedCondition(); } catch(...) { ec = NULL; } if (ec == NULL) NewException((double)sizeof(CExtendedCondition),__FILE__,__LINE__,__PRETTY_FUNCTION__); oa->Add(ec); mprintf(WHITE,"\n * %d. function in %d. block\n\n",z2+1,z+1); _lineagain: ec->m_fD[0] = AskFloat_ND(" Line point 1 - enter distance value in pm: "); ec->m_fA[0] = AskFloat_ND(" Line point 1 - enter angle value in degree: "); ec->m_fD[1] = AskFloat_ND(" Line point 2 - enter distance value in pm: "); ec->m_fA[1] = AskFloat_ND(" Line point 2 - enter angle value in degree: "); if ((ec->m_fD[1] == ec->m_fD[0]) && (ec->m_fA[1] == ec->m_fA[0])) { eprintf("\n The two points need to be different.\n\n"); goto _lineagain; } _sampleagain: ec->m_fD[2] = AskFloat_ND(" Included sample point - enter distance value in pm: "); ec->m_fA[2] = AskFloat_ND(" Included sample point - enter angle value in degree: "); if (!ec->Evaluate()) { eprintf("\n Sample point may not be located on the line!\n\n"); goto _sampleagain; } mprintf("\n (resulting equation: %G * dist + %G * angle %c %G).\n",ec->m_fX,ec->m_fY,ec->m_bLarger?'>':'<',ec->m_fZ); z2++; mprintf("\n"); if (!AskYesNo(" Add another function to this block (y/n)? [no] ",false)) break; } z++; mprintf("\n"); if (!AskYesNo(" Add another block of functions (y/n)? [no] ",false)) break; } mprintf("\n"); goto _noadf; } } else m_bExtendedMode = false; if ((gridmode == 1) || (gridmode == 3) || (gridmode == 4) || (gridmode == 5) || (gridmode == 6)) { if (gridmode == 6) if (!AskYesNo(" Do you want to define a distance condition (y/n)? [yes] ",true)) goto _nordf; try { m_pRDF = new CRDF(); } catch(...) { m_pRDF = NULL; } if (m_pRDF == NULL) NewException((double)sizeof(CRDF),__FILE__,__LINE__,__PRETTY_FUNCTION__); m_pRDF->m_iShowMol = om; m_pRDF->ParseConditionGrid(rm,this,gridmode); _nordf:; } if ((gridmode == 2) || (gridmode == 3) || (gridmode == 4) || (gridmode == 5) || (gridmode == 6)) { if ((gridmode == 4) || (gridmode == 5) || (gridmode == 6)) if (!AskYesNo(" Do you want to define an angular condition (y/n)? [no] ",false)) goto _noadf; try { m_pADF = new CADF(); } catch(...) { m_pADF = NULL; } if (m_pADF == NULL) NewException((double)sizeof(CADF),__FILE__,__LINE__,__PRETTY_FUNCTION__); m_pADF->m_iShowMol = om; m_pADF->ParseConditionGrid(rm,gridmode); _noadf:; } Create(om); if ((m_pADF != NULL) && (m_pRDF != NULL)) { mprintf(WHITE,"\nThere are %d distance subconditions:\n",m_iDistances); m_pRDF->BuildAtomList((CSingleMolecule*)g_oaSingleMolecules[((CMolecule*)g_oaMolecules[rm])->m_laSingleMolIndex[0]],(CSingleMolecule*)g_oaSingleMolecules[((CMolecule*)g_oaMolecules[om])->m_laSingleMolIndex[0]],&wa); for (z=0;z %s%d (%s)\n",z+1,(const char*)((CAtom*)g_oaAtoms[g_waAtomRealElement[ti]])->m_sName,g_waAtomMolNumber[ti]+1,((CMolecule*)g_oaMolecules[g_waAtomMolIndex[ti]])->m_sName,(const char*)((CAtom*)g_oaAtoms[g_waAtomRealElement[ti2]])->m_sName,g_waAtomMolNumber[ti2]+1,((CMolecule*)g_oaMolecules[g_waAtomMolIndex[ti2]])->m_sName); } mprintf("\n"); mprintf(WHITE,"There are %d angular subconditions:\n",m_iDistances); m_pADF->BuildAtomList((CSingleMolecule*)g_oaSingleMolecules[((CMolecule*)g_oaMolecules[rm])->m_laSingleMolIndex[0]],(CSingleMolecule*)g_oaSingleMolecules[((CMolecule*)g_oaMolecules[om])->m_laSingleMolIndex[0]],&wa); for (z=0;zm_bOrtho[0]) { ti = wa[z*6]; ti2 = wa[z*6+1]; ti3 = wa[z*6+2]; mprintf("[%s%d (%s), %s%d (%s), %s%d (%s)] to ",(const char*)((CAtom*)g_oaAtoms[g_waAtomRealElement[ti]])->m_sName,g_waAtomMolNumber[ti]+1,((CMolecule*)g_oaMolecules[g_waAtomMolIndex[ti]])->m_sName,(const char*)((CAtom*)g_oaAtoms[g_waAtomRealElement[ti2]])->m_sName,g_waAtomMolNumber[ti2]+1,((CMolecule*)g_oaMolecules[g_waAtomMolIndex[ti2]])->m_sName,(const char*)((CAtom*)g_oaAtoms[g_waAtomRealElement[ti3]])->m_sName,g_waAtomMolNumber[ti3]+1,((CMolecule*)g_oaMolecules[g_waAtomMolIndex[ti3]])->m_sName); } else { ti = wa[z*6]; ti2 = wa[z*6+1]; mprintf("[%s%d (%s) --> %s%d (%s)] to ",(const char*)((CAtom*)g_oaAtoms[g_waAtomRealElement[ti]])->m_sName,g_waAtomMolNumber[ti]+1,((CMolecule*)g_oaMolecules[g_waAtomMolIndex[ti]])->m_sName,(const char*)((CAtom*)g_oaAtoms[g_waAtomRealElement[ti2]])->m_sName,g_waAtomMolNumber[ti2]+1,((CMolecule*)g_oaMolecules[g_waAtomMolIndex[ti2]])->m_sName); } if (m_pADF->m_bOrtho[1]) { ti = wa[z*6+3]; ti2 = wa[z*6+4]; ti3 = wa[z*6+5]; mprintf("[%s%d (%s), %s%d (%s), %s%d (%s)]\n",(const char*)((CAtom*)g_oaAtoms[g_waAtomRealElement[ti]])->m_sName,g_waAtomMolNumber[ti]+1,((CMolecule*)g_oaMolecules[g_waAtomMolIndex[ti]])->m_sName,(const char*)((CAtom*)g_oaAtoms[g_waAtomRealElement[ti2]])->m_sName,g_waAtomMolNumber[ti2]+1,((CMolecule*)g_oaMolecules[g_waAtomMolIndex[ti2]])->m_sName,(const char*)((CAtom*)g_oaAtoms[g_waAtomRealElement[ti3]])->m_sName,g_waAtomMolNumber[ti3]+1,((CMolecule*)g_oaMolecules[g_waAtomMolIndex[ti3]])->m_sName); } else { ti = wa[z*6+3]; ti2 = wa[z*6+4]; mprintf("[%s%d (%s) --> %s%d (%s)]\n",(const char*)((CAtom*)g_oaAtoms[g_waAtomRealElement[ti]])->m_sName,g_waAtomMolNumber[ti]+1,((CMolecule*)g_oaMolecules[g_waAtomMolIndex[ti]])->m_sName,(const char*)((CAtom*)g_oaAtoms[g_waAtomRealElement[ti2]])->m_sName,g_waAtomMolNumber[ti2]+1,((CMolecule*)g_oaMolecules[g_waAtomMolIndex[ti2]])->m_sName); } } mprintf("\n"); if (m_iNbCountMin != -1) { mprintf(" Min./max. next neighbor count specified, combining each with each subcondition.\n"); for (z=0;z 1) && (m_iAngles > 1)) { if (m_iDistances == m_iAngles) { if (AskYesNo(" Combine n-th distance subcondition with n-th angular subcondition (y/n)? [yes] ",true)) { for (z=0;z m_iDistances)) { eprintf(" Invalid input, only %d distance subconditions (%d requested).\n",m_iDistances,tempwa[0]); goto _nextcomb; } if ((tempwa[1] < 1) || (tempwa[1] > m_iAngles)) { eprintf(" Invalid input, only %d angle subconditions (%d requested).\n",m_iAngles,tempwa[1]); goto _nextcomb; } tempwa[0]--; tempwa[1]--; if (m_bCombinationMatrix[tempwa[0]*m_iAngles+tempwa[1]]) { eprintf(" This combination has already been added.\n"); goto _nextcomb; } m_bCombinationMatrix[tempwa[0]*m_iAngles+tempwa[1]] = true; goto _nextcomb; _combdone:; } } mprintf("\n"); } else { for (z=0;zGetSize();z2++) { ec = (CExtendedCondition*)oa->GetAt(z2); mprintf(" %G * dist + %G * angle %c %G\n",ec->m_fX,ec->m_fY,ec->m_bLarger?'>':'<',ec->m_fZ); if (z2+1 < oa->GetSize()) mprintf(" AND\n"); } if (z+1 < m_oaExtendedConditions.GetSize()) mprintf("\n OR\n\n"); } } mprintf(YELLOW,"\n<<< End of this condition <<<\n\n"); } void CNbSearch::Parse_OnlyValues() { // mprintf(YELLOW,"\n>>> Condition between %s and %s >>>\n\n",((CMolecule*)g_oaMolecules[rm])->m_sName,((CMolecule*)g_oaMolecules[om])->m_sName); if (m_pRDF != NULL) { m_pRDF->ParseCondition_OnlyValues(this); if (m_pADF != NULL) mprintf("\n"); } if (m_pADF != NULL) m_pADF->ParseCondition_OnlyValues(); } void CNbSearch::PrintTable() { int z, z2; mprintf(WHITE,"\n*** Condition %d ***\n\n",m_iNumber+1); mprintf(" %.0f molecules total, %.0f passed (%.4f percent).\n",m_fMoleculesTotal,m_fMoleculesPassed,m_fMoleculesPassed/m_fMoleculesTotal*100.0); if (m_iNbCountMin == -1) { mprintf(" %.0f subconditions total, %.0f passed (%.4f percent).\n\n",m_fCombinationsTotal,m_fCombinationsPassed,m_fCombinationsPassed/m_fCombinationsTotal*100.0); mprintf(" Frequency table for Neighborhood between %s and %s:\n",((CMolecule*)g_oaMolecules[m_iRefMol])->m_sName,((CMolecule*)g_oaMolecules[m_iObsMol])->m_sName); mprintf(" (enabled pairs of conditions are printed in color)\n\n"); mprintf(" | Dist. |"); for (z=0;zm_sName,((CMolecule*)g_oaMolecules[m_iObsMol])->m_sName); mfprintf(a," | Dist. |"); for (z=0;zm_iDistances]; try { m_bDistPassed = new bool[parent->m_iDistances]; } catch(...) { m_bDistPassed = NULL; } if (m_bDistPassed == NULL) NewException((double)parent->m_iDistances*sizeof(bool),__FILE__,__LINE__,__PRETTY_FUNCTION__); // m_fAngles = new double[parent->m_iAngles]; try { m_bAnglePassed = new bool[parent->m_iAngles]; } catch(...) { m_bAnglePassed = NULL; } if (m_bAnglePassed == NULL) NewException((double)parent->m_iAngles*sizeof(bool),__FILE__,__LINE__,__PRETTY_FUNCTION__); } void CNbSearch::PrintSingle(int om) { int z, z4; CNbPair *n; mprintf("*** Single Condition Dump ***\n"); n = (CNbPair*)m_oaNbPairs[om]; for (z=0;zm_fDistances[z],n->m_bDistPassed[z]?"passed":"failed"); for (z4=z*2;z4m_laDistAtomList[z4]); mprintf("\n"); } for (z=0;zm_fAngles[z],((CNbPair*)m_oaNbPairs[om])->m_bAnglePassed[z]?"passed":"failed"); mprintf("%d, ",n->m_laAngleAtomList[z*6]); mprintf("%d, ",n->m_laAngleAtomList[z*6+1]); if (m_pADF->m_bOrtho[0]) mprintf("%d, ",n->m_laAngleAtomList[z*6+2]); mprintf("%d, ",n->m_laAngleAtomList[z*6+3]); mprintf("%d, ",n->m_laAngleAtomList[z*6+4]); if (m_pADF->m_bOrtho[1]) mprintf("%d, ",n->m_laAngleAtomList[z*6+5]); mprintf("\n"); } } void CNbSet::Parse(int rm) { int z; // CNbSearch *n; CConditionGroup *g; for (z=0;zm_laSingleMolIndex.GetSize() == 1)) { m_oaConditionGroups.Add(NULL); continue; } if (!AskYesNo(" Use neighboring %s molecules (y/n)? [yes] ",true,((CMolecule*)g_oaMolecules[z])->m_sName)) { m_oaConditionGroups.Add(NULL); continue; } mprintf(WHITE,"\n>>> Conditions for neighboring %s molecules >>>\n\n",((CMolecule*)g_oaMolecules[z])->m_sName); try { g = new CConditionGroup(); } catch(...) { g = NULL; } if (g == NULL) NewException((double)sizeof(CConditionGroup),__FILE__,__LINE__,__PRETTY_FUNCTION__); g->Parse(rm,z); m_oaConditionGroups.Add(g); mprintf(WHITE,"\n<<< End of Conditions for neighboring %s molecules <<<\n\n",((CMolecule*)g_oaMolecules[z])->m_sName); /* n = new CNbSearch(); n->Parse(rm,z); m_oaMolecules.Add(n);*/ } } void CNbSet::Scan(CSingleMolecule *rm, CTimeStep *t) { int z; for (z=0;zm_bInactive) ((CConditionGroup*)m_oaConditionGroups[z])->ScanNeighborhoodAllOM(t,rm); } void CNbSearch::Reset() { int z; for (z=0;z<((CMolecule*)g_oaMolecules[m_iObsMol])->m_laSingleMolIndex.GetSize();z++) { m_bPassed[z] = false; m_iPassCounter[z] = 0; ((CNbPair*)m_oaNbPairs[z])->Reset(); } for (z=0;z<(m_iAngles+1)*(m_iDistances+1);z++) m_fCombinationsFound[z] = 0; m_fCombinationsTotal = 0; m_fCombinationsPassed = 0; m_fMoleculesTotal = 0; m_fMoleculesPassed = 0; } void CNbSet::Reset() { int z; for (z=0;zReset(); } } void CNbPair::Reset() { } void CNbSet::Dump() { int z, z2; CConditionGroup *g; CMolecule *m; mprintf(WHITE,"Neighborhood Environment:\n\n"); for (z=0;zm_bInactive) continue;*/ m = (CMolecule*)g_oaMolecules[z]; mprintf(" * Molecule %s: ",m->m_sName); for (z2=0;z2m_laSingleMolIndex.GetSize();z2++) if (g->Contains(z2)) mprintf("%d ",z2+1); mprintf("\n"); } } void CNbSet::AddMolecule(int moltype, int mol) { CConditionGroup *cg; int z; if (m_oaConditionGroups[moltype] == NULL) { try { cg = new CConditionGroup(); } catch(...) { cg = NULL; } if (cg == NULL) NewException((double)sizeof(CConditionGroup),__FILE__,__LINE__,__PRETTY_FUNCTION__); m_oaConditionGroups[moltype] = cg; cg->m_bInactive = true; cg->m_iShowMol = moltype; try { cg->m_bAlwaysTrue = new bool[((CMolecule*)g_oaMolecules[moltype])->m_laSingleMolIndex.GetSize()]; } catch(...) { cg->m_bAlwaysTrue = NULL; } if (cg->m_bAlwaysTrue == NULL) NewException((double)((CMolecule*)g_oaMolecules[moltype])->m_laSingleMolIndex.GetSize()*sizeof(bool),__FILE__,__LINE__,__PRETTY_FUNCTION__); try { cg->m_iPassCounter = new long[((CMolecule*)g_oaMolecules[moltype])->m_laSingleMolIndex.GetSize()]; } catch(...) { cg->m_iPassCounter = NULL; } if (cg->m_iPassCounter == NULL) NewException((double)((CMolecule*)g_oaMolecules[moltype])->m_laSingleMolIndex.GetSize()*sizeof(long),__FILE__,__LINE__,__PRETTY_FUNCTION__); for (z=0;z<((CMolecule*)g_oaMolecules[moltype])->m_laSingleMolIndex.GetSize();z++) { cg->m_bAlwaysTrue[z] = false; cg->m_iPassCounter[z] = 0; } } ((CConditionGroup*)m_oaConditionGroups[moltype])->m_bAlwaysTrue[mol] = true; } CNbAnalysis::CNbAnalysis() { m_oaDF.SetName("CNbAnalysis::m_oaDF"); m_oaNPF.SetName("CNbAnalysis::m_oaNPF"); } CNbAnalysis::~CNbAnalysis() { } void CNbAnalysis::Parse() { int z; mprintf(WHITE,"\n>>> Neighborhood Analysis >>>\n\n"); mprintf(" You now have to define a neighborhood criterion.\n"); m_fBinEntries = 0; try { m_pNbSearch = new CNbSearch(); } catch(...) { m_pNbSearch = NULL; } if (m_pNbSearch == NULL) NewException((double)sizeof(CNbSearch),__FILE__,__LINE__,__PRETTY_FUNCTION__); m_pNbSearch->Parse(g_iFixMol,m_iShowMol,true); if (g_iFixMol == m_iShowMol) m_iNbCount = ((CMolecule*)g_oaMolecules[m_iShowMol])->m_laSingleMolIndex.GetSize()-1; else m_iNbCount = ((CMolecule*)g_oaMolecules[m_iShowMol])->m_laSingleMolIndex.GetSize(); /* m_iMinNbCount = AskUnsignedInteger(" From which neighbor on to analyze? [1] ",1)-1; if (m_iShowMol == g_iFixMol) ti = ((CMolecule*)g_oaMolecules[m_iShowMol])->m_laSingleMolIndex.GetSize()-1; else ti = ((CMolecule*)g_oaMolecules[m_iShowMol])->m_laSingleMolIndex.GetSize(); m_iMaxNbCount = AskRangeInteger(" Up to which neighbor to analyze? [%d] ",m_iMinNbCount+1,ti,ti,ti)-1; */ m_fMinDist = AskFloat(" Enter minimal distance for neighborhood analysis (pm): [0] ",0); m_fMaxDist = AskFloat(" Enter maximal distance for neighborhood analysis (pm): [%d] ",(double)HalfBox()*2.0,HalfBox()*2); m_iResolution = AskUnsignedInteger(" Enter the binning resolution: [200] ",200); BuildName(); try { m_pDist = new double[((CMolecule*)g_oaMolecules[m_iShowMol])->m_laSingleMolIndex.GetSize()]; } catch(...) { m_pDist = NULL; } if (m_pDist == NULL) NewException((double)((CMolecule*)g_oaMolecules[m_iShowMol])->m_laSingleMolIndex.GetSize()*sizeof(double),__FILE__,__LINE__,__PRETTY_FUNCTION__); try { m_pDistMin = new double[((CMolecule*)g_oaMolecules[m_iShowMol])->m_laSingleMolIndex.GetSize()]; } catch(...) { m_pDistMin = NULL; } if (m_pDistMin == NULL) NewException((double)((CMolecule*)g_oaMolecules[m_iShowMol])->m_laSingleMolIndex.GetSize()*sizeof(double),__FILE__,__LINE__,__PRETTY_FUNCTION__); try { m_pDistMax = new double[((CMolecule*)g_oaMolecules[m_iShowMol])->m_laSingleMolIndex.GetSize()]; } catch(...) { m_pDistMax = NULL; } if (m_pDistMax == NULL) NewException((double)((CMolecule*)g_oaMolecules[m_iShowMol])->m_laSingleMolIndex.GetSize()*sizeof(double),__FILE__,__LINE__,__PRETTY_FUNCTION__); try { m_pDistAvg = new double[((CMolecule*)g_oaMolecules[m_iShowMol])->m_laSingleMolIndex.GetSize()]; } catch(...) { m_pDistAvg = NULL; } if (m_pDistAvg == NULL) NewException((double)((CMolecule*)g_oaMolecules[m_iShowMol])->m_laSingleMolIndex.GetSize()*sizeof(double),__FILE__,__LINE__,__PRETTY_FUNCTION__); try { m_pDistCount = new double[((CMolecule*)g_oaMolecules[m_iShowMol])->m_laSingleMolIndex.GetSize()]; } catch(...) { m_pDistCount = NULL; } if (m_pDistCount == NULL) NewException((double)((CMolecule*)g_oaMolecules[m_iShowMol])->m_laSingleMolIndex.GetSize()*sizeof(double),__FILE__,__LINE__,__PRETTY_FUNCTION__); for (z=0;z<((CMolecule*)g_oaMolecules[m_iShowMol])->m_laSingleMolIndex.GetSize();z++) { m_pDistMin[z] = 1e20; m_pDistMax[z] = 0; m_pDistAvg[z] = 0; m_pDistCount[z] = 0; } mprintf(WHITE,"\n<<< End of Neighborhood Analysis <<<\n"); } void CNbAnalysis::BuildName() { BTIN; // char tmp[32768]; CxString tmp; // sprintf(tmp,"%s_%s",((CMolecule*)g_oaMolecules[g_iFixMol])->m_sName,((CMolecule*)g_oaMolecules[m_iShowMol])->m_sName); tmp.sprintf("%s_%s",((CMolecule*)g_oaMolecules[g_iFixMol])->m_sName,((CMolecule*)g_oaMolecules[m_iShowMol])->m_sName); try { m_sName = new char[strlen(tmp)+1]; } catch(...) { m_sName = NULL; } if (m_sName == NULL) NewException((double)(strlen(tmp)+1)*sizeof(char),__FILE__,__LINE__,__PRETTY_FUNCTION__); strcpy(m_sName,tmp); BTOUT; } void CNbAnalysis::AnalyzeStep() { int z, z2; double r; /* for (z=0;z<((CMolecule*)g_oaMolecules[m_iShowMol])->m_laSingleMolIndex.GetSize();z++) m_pDist[z] = ((CNbPair*)m_pNbSearch->m_oaNbPairs[z])->m_fMinDist; qsort(m_pDist,((CMolecule*)g_oaMolecules[m_iShowMol])->m_laSingleMolIndex.GetSize(),sizeof(double),compare_double); */ /* mprintf("Sorted: "); for (z=0;z<((CMolecule*)g_oaMolecules[m_iShowMol])->m_laSingleMolIndex.GetSize();z++) mprintf("%.2f ",m_pDist[z]); mprintf("\n");*/ m_pNbSearch->SortNeighbors(); m_fBinEntries += m_iNbCount; for (z=0;z<((CMolecule*)g_oaMolecules[m_iShowMol])->m_laSingleMolIndex.GetSize();z++) m_pDist[z] = m_pNbSearch->m_pNbSort[z].m_fMinDist; for (z=0;zAddToBin(m_pDist[z]); if (m_pDist[z] < m_pDistMin[z]) m_pDistMin[z] = m_pDist[z]; if (m_pDist[z] > m_pDistMax[z]) m_pDistMax[z] = m_pDist[z]; m_pDistAvg[z] += m_pDist[z]; m_pDistCount[z]++; } z2 = 0; for (z=0;zm_laSingleMolIndex.GetSize())) z2++; // z2--; // mprintf("z=%d, r=%f, z2=%d\n",z,r,z2); ((CDF*)m_oaNPF[z2])->AddToBin_Int(z); m_pNPFCount->AddToBin_Int(z); } } int compare_nbsort(const void *arg1, const void *arg2) { if (((CNbSort*)arg1)->m_bAnyAnglePassed && (!((CNbSort*)arg2)->m_bAnyAnglePassed)) return -1; if ((!((CNbSort*)arg1)->m_bAnyAnglePassed) && ((CNbSort*)arg2)->m_bAnyAnglePassed) return 1; if (((CNbSort*)arg1)->m_fMinDist > ((CNbSort*)arg2)->m_fMinDist) return 1; else if (((CNbSort*)arg1)->m_fMinDist < ((CNbSort*)arg2)->m_fMinDist) return -1; else return 0; } void CNbSearch::SortNeighbors() { int z; CNbPair *n; if (m_pNbSort == NULL) { try { m_pNbSort = new CNbSort[((CMolecule*)g_oaMolecules[m_iObsMol])->m_laSingleMolIndex.GetSize()]; } catch(...) { m_pNbSort = NULL; } if (m_pNbSort == NULL) NewException((double)((CMolecule*)g_oaMolecules[m_iObsMol])->m_laSingleMolIndex.GetSize()*sizeof(CNbSort),__FILE__,__LINE__,__PRETTY_FUNCTION__); } for (z=0;z<((CMolecule*)g_oaMolecules[m_iObsMol])->m_laSingleMolIndex.GetSize();z++) { n = (CNbPair*)m_oaNbPairs[z]; m_pNbSort[z].m_fMinDist = n->m_fMinDist; m_pNbSort[z].m_iOM = z; m_pNbSort[z].m_bAnyAnglePassed = n->m_bAnyAnglePassed; } qsort(m_pNbSort,((CMolecule*)g_oaMolecules[m_iObsMol])->m_laSingleMolIndex.GetSize(),sizeof(CNbSort),compare_nbsort); for (z=0;z<((CMolecule*)g_oaMolecules[m_iObsMol])->m_laSingleMolIndex.GetSize();z++) ((CNbPair*)m_oaNbPairs[m_pNbSort[z].m_iOM])->m_iNbPosition = z; } void CNbSet::ResetAlwaysTrue() { CConditionGroup *cg; int z, z2; for (z=0;zm_laSingleMolIndex.GetSize();z2++) { cg->m_bAlwaysTrue[z2] = false; cg->m_iPassCounter[z2] = 0; } } } void CNbSearch::CopyFrom(CNbSearch *nb) { int z; CNbPair *np; CExtendedCondition *ec; m_iRefMol = nb->m_iRefMol; m_iObsMol = nb->m_iObsMol; m_bInactive = nb->m_bInactive; m_fCombinationsTotal = nb->m_fCombinationsTotal; m_fCombinationsPassed = nb->m_fCombinationsPassed; m_fMoleculesTotal = nb->m_fMoleculesTotal; m_fMoleculesPassed = nb->m_fMoleculesPassed; m_iAngles = nb->m_iAngles; m_iDistances = nb->m_iDistances; m_iCombinationsEnabled = nb->m_iCombinationsEnabled; m_iNbCountMin = nb->m_iNbCountMin; m_iNbCountMax = nb->m_iNbCountMax; m_iNumber = nb->m_iNumber; m_bExtendedMode = nb->m_bExtendedMode; m_oaExtendedConditions.RemoveAll_KeepSize(); for (z=0;zm_oaExtendedConditions.GetSize();z++) { try { ec = new CExtendedCondition(); } catch(...) { ec = NULL; } if (ec == NULL) NewException((double)sizeof(CExtendedCondition),__FILE__,__LINE__,__PRETTY_FUNCTION__); ec->CopyFrom((CExtendedCondition*)nb->m_oaExtendedConditions[z]); m_oaExtendedConditions.Add(ec); } if (nb->m_pRDF != NULL) { try { m_pRDF = new CRDF(); } catch(...) { m_pRDF = NULL; } if (m_pRDF == NULL) NewException((double)sizeof(CRDF),__FILE__,__LINE__,__PRETTY_FUNCTION__); m_pRDF->CopyFrom(nb->m_pRDF); } if (nb->m_pADF != NULL) { try { m_pADF = new CADF(); } catch(...) { m_pADF = NULL; } if (m_pADF == NULL) NewException((double)sizeof(CADF),__FILE__,__LINE__,__PRETTY_FUNCTION__); m_pADF->CopyFrom(nb->m_pADF); } if (nb->m_bPassed != NULL) { try { m_bPassed = new bool[((CMolecule*)g_oaMolecules[m_iObsMol])->m_laSingleMolIndex.GetSize()]; } catch(...) { m_bPassed = NULL; } if (m_bPassed == NULL) NewException((double)((CMolecule*)g_oaMolecules[m_iObsMol])->m_laSingleMolIndex.GetSize()*sizeof(bool),__FILE__,__LINE__,__PRETTY_FUNCTION__); memcpy(m_bPassed,nb->m_bPassed,sizeof(bool)*((CMolecule*)g_oaMolecules[m_iObsMol])->m_laSingleMolIndex.GetSize()); } if (nb->m_iCombPassCount != NULL) { try { m_iCombPassCount = new int[((CMolecule*)g_oaMolecules[m_iObsMol])->m_laSingleMolIndex.GetSize()]; } catch(...) { m_iCombPassCount = NULL; } if (m_iCombPassCount == NULL) NewException((double)((CMolecule*)g_oaMolecules[m_iObsMol])->m_laSingleMolIndex.GetSize()*sizeof(int),__FILE__,__LINE__,__PRETTY_FUNCTION__); memcpy(m_iCombPassCount,nb->m_iCombPassCount,sizeof(int)*((CMolecule*)g_oaMolecules[m_iObsMol])->m_laSingleMolIndex.GetSize()); } if (nb->m_iPassCounter != NULL) { try { m_iPassCounter = new int[((CMolecule*)g_oaMolecules[m_iObsMol])->m_laSingleMolIndex.GetSize()]; } catch(...) { m_iPassCounter = NULL; } if (m_iPassCounter == NULL) NewException((double)((CMolecule*)g_oaMolecules[m_iObsMol])->m_laSingleMolIndex.GetSize()*sizeof(int),__FILE__,__LINE__,__PRETTY_FUNCTION__); memcpy(m_iPassCounter,nb->m_iPassCounter,sizeof(int)*((CMolecule*)g_oaMolecules[m_iObsMol])->m_laSingleMolIndex.GetSize()); } if (nb->m_fCombinationsFound != NULL) { try { m_fCombinationsFound = new double[(m_iAngles+1)*(m_iDistances+1)]; } catch(...) { m_fCombinationsFound = NULL; } if (m_fCombinationsFound == NULL) NewException((double)(m_iAngles+1)*(m_iDistances+1)*sizeof(double),__FILE__,__LINE__,__PRETTY_FUNCTION__); memcpy(m_fCombinationsFound,nb->m_fCombinationsFound,sizeof(double)*(m_iAngles+1)*(m_iDistances+1)); } if (nb->m_bCombinationMatrix != NULL) { try { m_bCombinationMatrix = new bool[m_iAngles*m_iDistances]; } catch(...) { m_bCombinationMatrix = NULL; } if (m_bCombinationMatrix == NULL) NewException((double)m_iAngles*m_iDistances*sizeof(bool),__FILE__,__LINE__,__PRETTY_FUNCTION__); memcpy(m_bCombinationMatrix,nb->m_bCombinationMatrix,sizeof(bool)*m_iAngles*m_iDistances); } if (nb->m_pNbSort != NULL) { try { m_pNbSort = new CNbSort[((CMolecule*)g_oaMolecules[m_iObsMol])->m_laSingleMolIndex.GetSize()]; } catch(...) { m_pNbSort = NULL; } if (m_pNbSort == NULL) NewException((double)((CMolecule*)g_oaMolecules[m_iObsMol])->m_laSingleMolIndex.GetSize()*sizeof(CNbSort),__FILE__,__LINE__,__PRETTY_FUNCTION__); for (z=0;z<((CMolecule*)g_oaMolecules[m_iObsMol])->m_laSingleMolIndex.GetSize();z++) m_pNbSort[z] = nb->m_pNbSort[z]; } if (nb->m_pDistances != NULL) { try { m_pDistances = new double[m_iDistances*((CMolecule*)g_oaMolecules[m_iObsMol])->m_laSingleMolIndex.GetSize()]; } catch(...) { m_pDistances = NULL; } if (m_pDistances == NULL) NewException((double)m_iDistances*((CMolecule*)g_oaMolecules[m_iObsMol])->m_laSingleMolIndex.GetSize()*sizeof(double),__FILE__,__LINE__,__PRETTY_FUNCTION__); memcpy(m_pDistances,nb->m_pDistances,sizeof(double)*m_iDistances*((CMolecule*)g_oaMolecules[m_iObsMol])->m_laSingleMolIndex.GetSize()); } if (nb->m_pAngles != NULL) { try { m_pAngles = new double[m_iAngles*((CMolecule*)g_oaMolecules[m_iObsMol])->m_laSingleMolIndex.GetSize()]; } catch(...) { m_pAngles = NULL; } if (m_pAngles == NULL) NewException((double)m_iAngles*((CMolecule*)g_oaMolecules[m_iObsMol])->m_laSingleMolIndex.GetSize()*sizeof(double),__FILE__,__LINE__,__PRETTY_FUNCTION__); memcpy(m_pAngles,nb->m_pAngles,sizeof(double)*m_iAngles*((CMolecule*)g_oaMolecules[m_iObsMol])->m_laSingleMolIndex.GetSize()); } m_oaNbPairs.RemoveAll_KeepSize(); for (z=0;zm_oaNbPairs.GetSize();z++) { try { np = new CNbPair(); } catch(...) { np = NULL; } if (np == NULL) NewException((double)sizeof(CNbPair),__FILE__,__LINE__,__PRETTY_FUNCTION__); np->m_fDistances = &m_pDistances[z*m_iDistances]; np->m_fAngles = &m_pAngles[z*m_iAngles]; np->CopyFrom((CNbPair*)nb->m_oaNbPairs[z],nb); m_oaNbPairs.Add(np); } } void CNbPair::CopyFrom(CNbPair *p, CNbSearch *parent) { m_iNbPosition = p->m_iNbPosition; m_bAnglePassed = p->m_bAnglePassed; m_iNbPosition = p->m_iNbPosition; m_bAnyDistPassed = p->m_bAnyDistPassed; m_bAnyAnglePassed = p->m_bAnyAnglePassed; m_fMinDist = p->m_fMinDist; m_iMinDistIndex = p->m_iMinDistIndex; /* if (p->m_fDistances != NULL) { m_fDistances = new double[parent->m_iDistances]; memcpy(m_fDistances,p->m_fDistances,sizeof(double)*parent->m_iDistances); }*/ if (p->m_bDistPassed != NULL) { try { m_bDistPassed = new bool[parent->m_iDistances]; } catch(...) { m_bDistPassed = NULL; } if (m_bDistPassed == NULL) NewException((double)parent->m_iDistances*sizeof(bool),__FILE__,__LINE__,__PRETTY_FUNCTION__); memcpy(m_bDistPassed,p->m_bDistPassed,sizeof(bool)*parent->m_iDistances); } /* if (p->m_fAngles != NULL) { m_fAngles = new double[parent->m_iAngles]; memcpy(m_fAngles,p->m_fAngles,sizeof(double)*parent->m_iAngles); }*/ if (p->m_bAnglePassed != NULL) { try {m_bAnglePassed = new bool[parent->m_iAngles]; } catch(...) { m_bAnglePassed = NULL; } if (m_bAnglePassed == NULL) NewException((double)parent->m_iAngles*sizeof(bool),__FILE__,__LINE__,__PRETTY_FUNCTION__); memcpy(m_bAnglePassed,p->m_bAnglePassed,sizeof(bool)*parent->m_iAngles); } m_laDistAtomList.CopyFrom(&p->m_laDistAtomList); m_laAngleAtomList.CopyFrom(&p->m_laAngleAtomList); } void CNbSearch::CopyResults(CNbSearch *p) { int z/*, z2*/; /* for (z=0;zm_fDistances,((CNbPair*)p->m_oaNbPairs[z])->m_fDistances,sizeof(double)*m_iDistances); memcpy(((CNbPair*)m_oaNbPairs[z])->m_fAngles,((CNbPair*)p->m_oaNbPairs[z])->m_fAngles,sizeof(double)*m_iAngles); }*/ if (m_iNbCountMin > -1) { if (m_pNbSort == NULL) { try { m_pNbSort = new CNbSort[((CMolecule*)g_oaMolecules[m_iObsMol])->m_laSingleMolIndex.GetSize()]; } catch(...) { m_pNbSort = NULL; } if (m_pNbSort == NULL) NewException((double)((CMolecule*)g_oaMolecules[m_iObsMol])->m_laSingleMolIndex.GetSize()*sizeof(CNbSort),__FILE__,__LINE__,__PRETTY_FUNCTION__); } for (z=0;z<((CMolecule*)g_oaMolecules[m_iObsMol])->m_laSingleMolIndex.GetSize();z++) m_pNbSort[z] = p->m_pNbSort[z]; //memcpy(m_pNbSort,p->m_pNbSort,sizeof(CNbSort)*((CMolecule*)g_oaMolecules[m_iObsMol])->m_laSingleMolIndex.GetSize()); } //else { memcpy(m_pDistances,p->m_pDistances,sizeof(double)*m_iDistances*((CMolecule*)g_oaMolecules[m_iObsMol])->m_laSingleMolIndex.GetSize()); memcpy(m_pAngles,p->m_pAngles,sizeof(double)*m_iAngles*((CMolecule*)g_oaMolecules[m_iObsMol])->m_laSingleMolIndex.GetSize()); } } void CNbSearch::ReScan(CSingleMolecule *rm) { int z, z2, z3, ti, ti3; CNbPair *n; bool anypassed; m_fMoleculesTotal += ((CMolecule*)g_oaMolecules[m_iObsMol])->m_laSingleMolIndex.GetSize(); m_fCombinationsTotal += ((CMolecule*)g_oaMolecules[m_iObsMol])->m_laSingleMolIndex.GetSize() * m_iDistances * m_iAngles; ti3 = 0; for (z=0;z<((CMolecule*)g_oaMolecules[m_iObsMol])->m_laSingleMolIndex.GetSize();z++) { n = (CNbPair*)m_oaNbPairs[z]; m_bPassed[z] = false; anypassed = false; m_iCombPassCount[z] = 0; if ((rm->m_iMolSMIndex == z) && (rm->m_iMolType == m_iObsMol)) { n->m_fMinDist = 9e20; continue; } n->ReScan(this); if (m_iNbCountMin <= -1) // Abstands-Modus { for (z2=0;z2m_bDistPassed[z2]) { anypassed = true; m_fCombinationsFound[(z2+1)*(m_iAngles+1)] += m_iAngles; } } for (z3=0;z3m_bAnglePassed[z3]) { anypassed = true; m_fCombinationsFound[z3+1] += m_iDistances; } } for (z2=0;z2m_bDistPassed[z2] && n->m_bAnglePassed[z3]) { m_fCombinationsFound[(z2+1)*(m_iAngles+1)+z3+1]++; if (m_bCombinationMatrix[z2*m_iAngles+z3]) { if (m_bExtendedMode) { if (CheckExtended(n->m_fDistances[z2],n->m_fAngles[z3])) { if (!m_bPassed[z]) { ti3++; m_bPassed[z] = true; m_iPassCounter[z]++; } m_iCombPassCount[z]++; m_fCombinationsPassed++; } else { n->m_bDistPassed[z2] = false; n->m_bAnglePassed[z3] = false; } } else { if (!m_bPassed[z]) { ti3++; m_bPassed[z] = true; m_iPassCounter[z]++; } m_iCombPassCount[z]++; m_fCombinationsPassed++; } } } } } if (anypassed) m_fCombinationsFound[0] += m_iDistances * m_iAngles; if (m_bPassed[z]) m_fMoleculesPassed++; } // Ende Abstandsmodus } if (m_iNbCountMin > -1) // Nachbar-Anzahl-Modus { for (z=0;z<((CMolecule*)g_oaMolecules[m_iObsMol])->m_laSingleMolIndex.GetSize();z++) { ti = m_pNbSort[z].m_iOM; if ((rm->m_iMolSMIndex == ti) && (rm->m_iMolType == m_iObsMol)) continue; n = (CNbPair*)m_oaNbPairs[ti]; if ((z >= m_iNbCountMin) && (z <= m_iNbCountMax)) { n->m_bAnyDistPassed = true; if (n->m_iMinDistIndex == -1) { eprintf("CNbSearch::ReScan(): Error: n->m_iMinDistIndex == -1 (z=%d, ti=%d, rm->m_iMolSMIndex=%d).\n",z,ti,rm->m_iMolSMIndex); abort(); } n->m_bDistPassed[n->m_iMinDistIndex] = true; if (n->m_bAnyAnglePassed) { m_bPassed[ti] = true; m_iPassCounter[ti]++; m_fMoleculesPassed++; m_fCombinationsFound[0] += m_iDistances * m_iAngles; } else m_bPassed[ti] = false; } else { n->m_bAnyDistPassed = false; m_bPassed[ti] = false; } } } } void CNbPair::ReScan(CNbSearch *parent) { int z, z2; if (parent->m_pRDF != NULL) { m_bAnyDistPassed = false; m_fMinDist = 1E30; // mprintf("$$ NbPair %08X ReScan %d\n",this,parent->m_iDistances); for (z=0;zm_iDistances;z++) { // mprintf(" %d: %f\n",z,m_fDistances[z]); if (m_fDistances[z] < m_fMinDist) { m_fMinDist = m_fDistances[z]; m_iMinDistIndex = z; } m_bDistPassed[z] = false; for (z2=0;z2m_pRDF->m_faMinMaxDist.GetSize();z2+=2) { if ((m_fDistances[z] >= parent->m_pRDF->m_faMinMaxDist[z2]) && (m_fDistances[z] <= parent->m_pRDF->m_faMinMaxDist[z2+1])) { m_bAnyDistPassed = true; m_bDistPassed[z] = true; break; } } } } else { m_bAnyDistPassed = true; m_bDistPassed[0] = true; } if (parent->m_pADF != NULL) { m_bAnyAnglePassed = false; for (z=0;zm_iAngles;z++) { m_bAnglePassed[z] = false; for (z2=0;z2m_pADF->m_faMinMaxAngle.GetSize();z2+=2) { if ((m_fAngles[z] >= parent->m_pADF->m_faMinMaxAngle[z2]) && (m_fAngles[z] <= parent->m_pADF->m_faMinMaxAngle[z2+1])) { m_bAnyAnglePassed = true; m_bAnglePassed[z] = true; break; } } } } else { m_bAnyAnglePassed = true; m_bAnglePassed[0] = true; } } bool CNbSearch::CheckExtended(double dist, double angle) { CxObArray *oa; CExtendedCondition *ec; int z, z2; // mprintf("\nChecking Dist=%G, Angle=%G...\n",dist,angle); for (z=0;zGetSize();z2++) { ec = (CExtendedCondition*)(*oa)[z2]; // mprintf(" Function %d: %G * %G + %G * %G %c %G? ",z2+1,ec->m_fX,dist,ec->m_fY,angle,ec->m_bLarger?'>':'<',ec->m_fZ); if (ec->m_bLarger) { if (ec->m_fX*dist + ec->m_fY*angle <= ec->m_fZ) goto _fail; // mprintf("Yes!\n"); } else { if (ec->m_fX*dist + ec->m_fY*angle >= ec->m_fZ) goto _fail; // mprintf("Yes!\n"); } } // mprintf("\n"); // mprintf("\nBestanden! dist=%G, angle=%G.\n",dist,angle); return true; _fail:; // mprintf("No!\n"); } // mprintf("\n"); return false; } bool CExtendedCondition::Evaluate() { double t; if ((m_fA[0]*m_fD[1] - m_fA[1]*m_fD[0]) == 0) { // mprintf("A\n"); m_fZ = 0; if (m_fA[1] == m_fA[0]) { // mprintf("X\n"); m_fX = 0; m_fY = 1.0; } else { // mprintf("Y\n"); m_fX = 1.0; m_fY = - (m_fD[1] - m_fD[0]) / (m_fA[1] - m_fA[0]); } } else { // mprintf("B\n"); m_fX = -(m_fA[1] - m_fA[0]) / (m_fA[0]*m_fD[1] - m_fA[1]*m_fD[0]); m_fY = (m_fD[1] - m_fD[0]) / (m_fA[0]*m_fD[1] - m_fA[1]*m_fD[0]); m_fZ = 1.0; } t = m_fX * m_fD[2] + m_fY * m_fA[2]; if (t == m_fZ) return false; if (t > m_fZ) m_bLarger = true; else m_bLarger = false; return true; } void CExtendedCondition::CopyFrom(CExtendedCondition *ec) { int z; m_bLarger = ec->m_bLarger; m_fX = ec->m_fX; m_fY = ec->m_fY; m_fZ = ec->m_fZ; for (z=0;z<3;z++) { m_fA[z] = ec->m_fA[z]; m_fD[z] = ec->m_fD[z]; } } CNbSet::CNbSet() { m_oaConditionGroups.SetName("CNBSet::m_oaConditionGroups"); } CNbSet::~CNbSet() { } travis-src-190101/src/nbsearch.h0100777000000000000000000001112513412725661013376 0ustar00/***************************************************************************** TRAVIS - Trajectory Analyzer and Visualizer http://www.travis-analyzer.de/ Copyright (c) 2009-2019 Martin Brehm 2012-2019 Martin Thomas 2016-2019 Sascha Gehrke This file was written by Martin Brehm. --------------------------------------------------------------------------- This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . *****************************************************************************/ #ifndef NBSEARCH_H #define NBSEARCH_H // This must always be the first include directive #include "config.h" #include "xobject.h" #include "xobarray.h" #include "xwordarray.h" #include "xintarray.h" #include "xdoublearray.h" #include "backtrace.h" #include "df.h" class CNbSearch; class CRDF; class CADF; class CSingleMolecule; class CTimeStep; //#include "moltools.h" class CNbPair : public CxObject { public: void ReScan(CNbSearch *parent); void CopyFrom(CNbPair *p, CNbSearch *parent); void Reset(); void Create(CNbSearch *parent); CNbPair(); ~CNbPair(); void Check(CNbSearch *parent, CTimeStep *ts, CSingleMolecule *rm, CSingleMolecule *sm); void PreCheck(CNbSearch *parent, CTimeStep *ts, CSingleMolecule *rm, CSingleMolecule *sm); int m_iNbPosition; bool m_bAnyDistPassed; bool m_bAnyAnglePassed; bool *m_bDistPassed; bool *m_bAnglePassed; double *m_fDistances; double *m_fAngles; double m_fMinDist; int m_iMinDistIndex; CxIntArray m_laDistAtomList; CxIntArray m_laAngleAtomList; }; class CNbSort : public CxObject { public: //CNbSort() { } //~CNbSort() { } double m_fMinDist; int m_iOM; bool m_bAnyAnglePassed; }; class CExtendedCondition : public CxObject { public: void CopyFrom(CExtendedCondition *ec); bool Evaluate(); double m_fX; double m_fY; double m_fZ; bool m_bLarger; double m_fA[3]; double m_fD[3]; CExtendedCondition(); ~CExtendedCondition(); }; class CNbSearch : public CxObject { public: bool CheckExtended(double dist, double angle); void ReScan(CSingleMolecule *rm); void CopyResults(CNbSearch *p); void CopyFrom(CNbSearch *nb); void SortNeighbors(); void Reset(); void PrintSingle(int om); void PrintTable(); void PrintTable(FILE *a); void Parse_OnlyValues(); void ParseGrid(int rm, int om, int gridmode); void Parse(int rm, int om, bool nbana); void Create(int obs); CNbSearch(); ~CNbSearch(); // void ScanSingleOM(CSingleMolecule *rm, int om, CTimeStep *t, bool markpassedatoms, bool fold); void MarkPassedAtoms(int om); void ScanAllOM(CSingleMolecule *rm, CTimeStep *t); void PreScanAllOM(CSingleMolecule *rm, CTimeStep *t); int m_iRefMol; int m_iObsMol; bool m_bInactive; double m_fCombinationsTotal; double m_fCombinationsPassed; double m_fMoleculesTotal; double m_fMoleculesPassed; int m_iAngles; int m_iDistances; int m_iCombinationsEnabled; int m_iNbCountMin; int m_iNbCountMax; int m_iNumber; bool *m_bPassed; bool *m_bCombinationMatrix; double *m_fCombinationsFound; int *m_iCombPassCount; int *m_iPassCounter; // bool *m_iPassed; CRDF *m_pRDF; CADF *m_pADF; CNbSort *m_pNbSort; double *m_pDistances; double *m_pAngles; CxObArray m_oaNbPairs; bool m_bExtendedMode; CxObArray m_oaExtendedConditions; }; class CNbAnalysis : public CxObject { public: double m_fBinEntries; void AnalyzeStep(); CNbAnalysis(); ~CNbAnalysis(); void Parse(); void BuildName(); double *m_pDist; double *m_pDistMin; double *m_pDistMax; double *m_pDistAvg; double *m_pDistCount; char *m_sName; CNbSearch *m_pNbSearch; CxObArray m_oaDF; CxObArray m_oaNPF; CDF *m_pNPFCount; int m_iResolution; double m_fMinDist; double m_fMaxDist; int m_iNbCount; // int m_iMinNbCount; // int m_iMaxNbCount; int m_iShowMol; }; class CNbSet : public CxObject { public: void ResetAlwaysTrue(); void AddMolecule(int moltype, int mol); void Dump(); void Reset(); void Scan(CSingleMolecule *rm, CTimeStep *t); // CxObArray m_oaMolecules; CxObArray m_oaConditionGroups; void Parse(int rm); CNbSet(); ~CNbSet(); }; #endif travis-src-190101/src/normalcoordinate.cpp0100777000000000000000000041251013412725621015503 0ustar00/***************************************************************************** TRAVIS - Trajectory Analyzer and Visualizer http://www.travis-analyzer.de/ Copyright (c) 2009-2019 Martin Brehm 2012-2019 Martin Thomas 2016-2019 Sascha Gehrke This file was written by Martin Thomas. --------------------------------------------------------------------------- This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . *****************************************************************************/ // This must always be the first include directive #include "config.h" #include "normalcoordinate.h" #include "globalvar.h" #include "linalg.h" #include "maintools.h" #include "moltools.h" #include "timestep.h" #include "tools.h" #include "xbytearray.h" #include "xobarray.h" #include "xstring.h" #include const char *GetRevisionInfo_normalcoordinate(unsigned int len) { static char buf[256]; GET_REVISION_INFO( buf, len ); return buf; } const char *GetSourceVersion_normalcoordinate() { static char buf[256]; GET_SOURCE_VERSION( buf ); return buf; } #define BUF_SIZE 4096 static CxObArray g_normalCoordinateObservations; static void SVD_3x3(double *input_matrix, double *s_values, double *u_matrix, double *v_matrix) { double v[9]; ComputeSVD_Flat(input_matrix, 3, 3, s_values, v); int sortIndex[3]; int i, j; for(i = 0; i < 3; i++) { sortIndex[i] = i; } for(i = 0; i < 2; i++) { for(j = i + 1; j < 3; j++) { if(s_values[j] > s_values[i]) { double tf = s_values[i]; s_values[i] = s_values[j]; s_values[j] = tf; int ti = sortIndex[i]; sortIndex[i] = sortIndex[j]; sortIndex[j] = ti; } } } for(i = 0; i < 3; i++) { for(j = 0; j < 3; j++) { u_matrix[3*i + j] = input_matrix[3*i + sortIndex[j]]; v_matrix[3*i + j] = v[3*i + sortIndex[j]]; } } } CReferenceStructure::CReferenceStructure(int showMol, const char *basename, bool calcIR) { int i, j; CxString buf; _calcIR = calcIR; try { _singleMol = new CSingleMolecule(); } catch(...) { _singleMol = NULL; } if(_singleMol == NULL) NewException((double)sizeof(CSingleMolecule), __FILE__, __LINE__, __PRETTY_FUNCTION__); try { _refTimestep = new CTimeStep(); } catch(...) { _refTimestep = NULL; } if(_refTimestep == NULL) NewException((double)sizeof(CTimeStep), __FILE__, __LINE__, __PRETTY_FUNCTION__); while(true) { // char buf[BUF_SIZE]; AskString_ND(" Filename for reference structure: ", &buf); FILE *refFile = fopen(buf, "r"); if(refFile == NULL) { mprintf(RED, "Could not open reference structure file: %s\n", strerror(errno)); continue; } if(!_refTimestep->ReadTimestep(refFile, true)) { mprintf(RED, "Error reading reference structure file\n"); continue; } strncpy(_filename, buf, 128); _filename[127] = 0; mprintf("\n Starting molecule recoginition...\n"); if(!recognizeMolecule(_refTimestep, showMol, basename)) { mprintf(RED, "Molecule recoginition failed\n\n"); continue; } break; } if(g_bAdvanced2) { _writeTransformedTrajectories = AskYesNo(" Save trajectories after transformation to reference frame for first observed molecule (y/n)? [no] ", false); mprintf("\n"); } else { _writeTransformedTrajectories = false; } _showMolCount = ((CMolecule *)g_oaMolecules[showMol])->m_laSingleMolIndex.GetSize(); if(_permutationCount > 1) { _useInternals = AskYesNo(" Use mass-weighted Cartesians for probabilities (n) or define internal coordinates (y)? [no] ", false); if(_useInternals) { mprintf("\n At the moment, only \"simple\" dihedral angles can be defined.\n"); do { CxIntArray *internal; try { internal = new CxIntArray(); } catch(...) { internal = NULL; } if(internal == NULL) NewException((double)sizeof(CxIntArray), __FILE__, __LINE__, __PRETTY_FUNCTION__); internal->SetSize(4); mprintf("\n"); for(i = 0; i < 4; i++) { // char buf[BUF_SIZE]; int parse[3]; do AskString_ND(" Enter the %d. atom (e.g. C7): ", &buf, i+1); while(!ParseAtom(buf, showMol, parse[0], parse[1], parse[2])); internal->GetAt(i) = -1; for(j = 0; j < _singleMol->m_oaMolAtoms.GetSize(); j++) { CMolAtom *ma = (CMolAtom *)_singleMol->m_oaMolAtoms[j]; if((ma->m_iType == parse[0]) && (ma->m_iNumber == parse[2])) { internal->GetAt(i) = j; break; } } if(internal->GetAt(i) == -1) { eprintf("CReferenceStructure::CReferenceStructure(): Internal error.\n"); abort(); } } _internals.Add(internal); } while(AskYesNo("\n Add another dihedral angle (y/n)? [no] ", false)); _gaussianWidth = AskFloat("\n Gaussian width for probability distribution (deg)? [10.0] ", 10.0); } else { _gaussianWidth = AskFloat(" Gaussian width for probability distribution (pm*sqrt(amu))? [1.0] ", 1.0); } mprintf("\n"); } else { _useInternals = false; _gaussianWidth = 1000.0; } if(g_iTrajSteps != -1) { _correlationDepth = (int)(0.75 * g_iTrajSteps); if(_correlationDepth > 4096) _correlationDepth = 4096; if(g_fTimestepLength > 1.0) _correlationDepth = 2048; if(g_fTimestepLength > 2.0) _correlationDepth = 1024; _correlationDepth = AskUnsignedInteger(" Enter the resolution (=depth) of the ACF (in time steps): [%d] ", _correlationDepth, _correlationDepth); } else { _correlationDepth = AskUnsignedInteger(" Enter the resolution (=depth) of the ACF (in time steps): [256] ", 256); } int size = CalcFFTSize(_correlationDepth, false); if(_correlationDepth != size) { mprintf(WHITE, " The next \"fast\" size for FFT is %d. Using this instead of %d as depth.\n", size, _correlationDepth); _correlationDepth = size; } if(g_bAdvanced2) { _windowFunction = AskRangeInteger(" Window function: cos^2(a*t) (1), exp(-t/a) (2), exp(-(t/a)^2) (3) [1] ", 1, 3, 1); if(_windowFunction == 1) { mprintf(" The parameter \"a\" is chosen according to the correlation depth.\n"); _windowFunctionParameter = 0; } else if(_windowFunction == 2) { _windowFunctionParameter = AskUnsignedInteger(" Parameter \"a\" (in time steps): [%d] ", _correlationDepth / 4, _correlationDepth / 4); } else if(_windowFunction == 3) { _windowFunctionParameter = AskUnsignedInteger(" Parameter \"a\" (in time steps): [%d] ", _correlationDepth / 2, _correlationDepth / 2); } else { eprintf("This is impossible.\n"); abort(); } } else { _windowFunction = 1; _windowFunctionParameter = 0; } if(g_bAdvanced2) { _zeroPadding = AskUnsignedInteger(" Zero Padding: How many zeros to insert? [%d] ", _correlationDepth * 3, _correlationDepth * 3); size = CalcFFTSize(_correlationDepth + _zeroPadding, false); if(_correlationDepth + _zeroPadding != size) { mprintf(WHITE, " The next \"fast\" size for FFT is %d. Using %d zeros for zero padding.\n", size, size-_correlationDepth); _zeroPadding = size-_correlationDepth; } } else { _zeroPadding = _correlationDepth * 3; size = CalcFFTSize(_correlationDepth + _zeroPadding, false); if(_correlationDepth + _zeroPadding != size) { mprintf(WHITE, " The next \"fast\" size for FFT is %d. Using %d zeros for zero padding.\n", size, size-_correlationDepth); _zeroPadding = size-_correlationDepth; } } double possibleRange = 33356.41 / g_fTimestepLength / 2.0; _specResolution = possibleRange / (_correlationDepth + _zeroPadding); mprintf(" This results in a spectral resolution of %.2f cm^-1.\n", _specResolution); mprintf("\n A time step length of %.2f fs allows a spectral range up to %.2f cm^-1.\n", g_fTimestepLength, possibleRange); double specLimit = AskRangeFloat("\n Calculate spectrum up to which wave number (cm^-1)? [%.2f cm^-1] ", 0, possibleRange, (possibleRange < 5000.0) ? possibleRange : 5000.0, (possibleRange < 5000.0) ? possibleRange : 5000.0); _specSize = (int)(specLimit / _specResolution); mprintf("\n"); _convergenceThreshold = AskFloat(" Relative convergence threshold for diagonalization: [1.0e-6] ", 1.0e-6); _maxIterations = AskUnsignedInteger(" Maximum number of iterations for diagonalization: [50] ", 50); mprintf("\n"); } CReferenceStructure::~CReferenceStructure() { delete _singleMol; delete _refTimestep; int i; for(i = 0; i < _centroidCoords.GetSize(); i++) delete (CxDVec3Array *)_centroidCoords[i]; for(i = 0; i < _distanceTimedev.GetSize(); i++) delete (CxDoubleArray *)_distanceTimedev[i]; for(i = 0; i < _coordHistory.GetSize(); i++) delete (CxDVec3Array *)_coordHistory[i]; for(i = 0; i < _velocityCache.GetSize(); i++) delete (CxDVec3Array *)_velocityCache[i]; for(i = 0; i < _dipoleHistory.GetSize(); i++) delete (CxDVec3Array *)_dipoleHistory[i]; for(i = 0; i < _dipoleDerivativeCache.GetSize(); i++) delete (CxDVec3Array *)_dipoleDerivativeCache[i]; } void CReferenceStructure::initialize(const char *basename) { _numSteps = 0; int n; if(g_iTrajSteps != -1) n = (int)(1.1 * g_iTrajSteps / g_iStride); else n = 10000; mprintf(" Distance time development: Trying to allocate %s of memory...\n", FormatBytes((double)_showMolCount * n * _permutationCount * sizeof(double))); int i; for(i = 0; i < _showMolCount * _permutationCount; i++) { CxDoubleArray *a; try { a = new CxDoubleArray(); } catch(...) { a = NULL; } if(a == NULL) NewException((double)sizeof(CxDoubleArray), __FILE__, __LINE__, __PRETTY_FUNCTION__); a->SetMaxSize(n); a->SetGrow((int)(0.1 * n)); _distanceTimedev.Add(a); } mprintf(" Coordinate history: Trying to allocate %s of memory...\n", FormatBytes((double)_showMolCount * _permutationCount * _atomCount * 3 * sizeof(CxDVector3))); for(i = 0; i < _showMolCount * _permutationCount * _atomCount; i++) { CxDVec3Array *a; try { a = new CxDVec3Array(); } catch(...) { a = NULL; } if(a == NULL) NewException((double)sizeof(CxDVec3Array), __FILE__, __LINE__, __PRETTY_FUNCTION__); a->SetSize(3); _coordHistory.Add(a); } _historyIndex = 0; _calcVelocity = false; if(_calcIR) { mprintf(" Dipole history: Trying to allocate %s of memory...\n", FormatBytes((double)_showMolCount * _permutationCount * 3 * sizeof(CxDVector3))); for(i = 0; i < _showMolCount * _permutationCount; i++) { CxDVec3Array *a; try { a = new CxDVec3Array(); } catch(...) { a = NULL; } if(a == NULL) NewException((double)sizeof(CxDVec3Array), __FILE__, __LINE__, __PRETTY_FUNCTION__); a->SetSize(3); _dipoleHistory.Add(a); } } mprintf(" Velocity cache: Trying to allocate %s of memory...\n", FormatBytes((double)_showMolCount * _permutationCount * _atomCount * n * sizeof(CxDVector3))); for(i = 0; i < _showMolCount * _permutationCount * _atomCount; i++) { CxDVec3Array *a; try { a = new CxDVec3Array(); } catch(...) { a = NULL; } if(a == NULL) NewException((double)sizeof(CxDVec3Array), __FILE__, __LINE__, __PRETTY_FUNCTION__); a->SetMaxSize(n); a->SetGrow((int)(0.1 * n)); _velocityCache.Add(a); } if(_calcIR) { mprintf(" Dipole derivative cache: Trying to allocate %s of memory...\n", FormatBytes((double)_showMolCount * _permutationCount * n * sizeof(CxDVector3))); for(i = 0; i < _showMolCount * _permutationCount; i++) { CxDVec3Array *a; try { a = new CxDVec3Array(); } catch(...) { a = NULL; } if(a == NULL) NewException((double)sizeof(CxDVec3Array), __FILE__, __LINE__, __PRETTY_FUNCTION__); a->SetMaxSize(n); a->SetGrow((int)(0.1 * n)); _dipoleDerivativeCache.Add(a); } } if(_writeTransformedTrajectories) { try { _transformedTrajectoryFiles = new FILE *[_permutationCount]; } catch(...) { _transformedTrajectoryFiles = NULL; } if(_transformedTrajectoryFiles == NULL) NewException((double)sizeof(FILE *) * _permutationCount, __FILE__, __LINE__, __PRETTY_FUNCTION__); for(i = 0; i < _permutationCount; i++) { char name[BUF_SIZE]; #ifdef TARGET_LINUX snprintf(name, BUF_SIZE, "%s_p%d_transformed.xyz", basename, i+1); #else sprintf(name, "%s_p%d_transformed.xyz", basename, i+1); #endif _transformedTrajectoryFiles[i] = OpenFileWrite(name, false); } } } void CReferenceStructure::processCoordinates(CxDVec3Array &coord, CxDVector3 &dipole, int showMol) { int i, j, k, l; for(i = 0; i < _permutationCount; i++) { if(_atomCount != coord.GetSize()) { eprintf("CReferenceStructure::processCoordinates(): Wrong number of coordinates from trajectory.\n"); abort(); } CxDVector3 centroid(0.0, 0.0, 0.0); for(j = 0; j < coord.GetSize(); j++) { centroid += coord[j] * _weights[j]; } centroid /= _weightSum; double covarianceMatrix[9] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; for(j = 0; j < _atomCount; j++) { CxDVector3 v1 = coord[j] - centroid; CxDVector3 v2 = ((CxDVec3Array *)_centroidCoords[i])->GetAt(j); for(k = 0; k < 3; k++) { for(l = 0; l < 3; l++) { covarianceMatrix[k*3+l] += v1[k] * v2[l] * _weights[j]; } } } //************** NEW ******************** // double sValues[3]; // double vMatrix[9]; // ComputeSVD_Flat(covarianceMatrix, 3, 3, sValues, vMatrix); // // double rotationMatrix[9]; // for(int j = 0; j < 3; j++) { // for(int k = 0; k < 3; k++) { // rotationMatrix[3*j+k] = 0.0f; // for(int l = 0; l < 3; l++) { // rotationMatrix[3*j+k] += vMatrix[3*j+l] * covarianceMatrix[3*k+l]; // } // } // } // // double determinant = rotationMatrix[0]*rotationMatrix[4]*rotationMatrix[8] + rotationMatrix[1]*rotationMatrix[5]*rotationMatrix[6] + rotationMatrix[2]*rotationMatrix[3]*rotationMatrix[7] - rotationMatrix[2]*rotationMatrix[4]*rotationMatrix[6] - rotationMatrix[1]*rotationMatrix[3]*rotationMatrix[8] - rotationMatrix[0]*rotationMatrix[5]*rotationMatrix[7]; // if(determinant < 0.0f) { // // mprintf(RED, "det < 0"); // for(int j = 0; j < 3; j++) { // for(int k = 0; k < 3; k++) { // rotationMatrix[3*j+k] = 0.0f; // for(int l = 0; l < 3; l++) { // rotationMatrix[3*j+k] += vMatrix[3*j+l] * covarianceMatrix[3*k+l] * (l == 0 ? -1.0f : 1.0f); // } // } // } // } // // mprintf(GREEN, "%f", rotationMatrix[0]*rotationMatrix[4]*rotationMatrix[8] + rotationMatrix[1]*rotationMatrix[5]*rotationMatrix[6] + rotationMatrix[2]*rotationMatrix[3]*rotationMatrix[7] - rotationMatrix[2]*rotationMatrix[4]*rotationMatrix[6] - rotationMatrix[1]*rotationMatrix[3]*rotationMatrix[8] - rotationMatrix[0]*rotationMatrix[5]*rotationMatrix[7]); //*************************************** //************* NEW 2 ******************* double sValues[3]; double uMatrix[9]; double vMatrix[9]; SVD_3x3(covarianceMatrix, sValues, uMatrix, vMatrix); double rotationMatrix[9]; for(j = 0; j < 3; j++) { for(k = 0; k < 3; k++) { rotationMatrix[3*j+k] = 0.0; for(l = 0; l < 3; l++) { rotationMatrix[3*j+k] += vMatrix[3*j+l] * uMatrix[3*k+l]; } } } double determinant = rotationMatrix[0]*rotationMatrix[4]*rotationMatrix[8] + rotationMatrix[1]*rotationMatrix[5]*rotationMatrix[6] + rotationMatrix[2]*rotationMatrix[3]*rotationMatrix[7] - rotationMatrix[2]*rotationMatrix[4]*rotationMatrix[6] - rotationMatrix[1]*rotationMatrix[3]*rotationMatrix[8] - rotationMatrix[0]*rotationMatrix[5]*rotationMatrix[7]; if(determinant < 0.0) { for(j = 0; j < 3; j++) { for(k = 0; k < 3; k++) { rotationMatrix[3*j+k] = 0.0; for(l = 0; l < 3; l++) { rotationMatrix[3*j+k] += vMatrix[3*j+l] * uMatrix[3*k+l] * (l == 2 ? -1.0 : 1.0); } } } } //*************************************** // double sValues[3]; // double uMatrix[9]; // double vtMatrix[9]; // singularValueDecompose_3x3(covarianceMatrix, sValues, uMatrix, vtMatrix); // // if(vtMatrix[0]*vtMatrix[4]*vtMatrix[8] + vtMatrix[1]*vtMatrix[5]*vtMatrix[6] + vtMatrix[2]*vtMatrix[3]*vtMatrix[7] - vtMatrix[2]*vtMatrix[4]*vtMatrix[6] - vtMatrix[1]*vtMatrix[3]*vtMatrix[8] - vtMatrix[0]*vtMatrix[5]*vtMatrix[7] < 0) { // for(int j = 0; j < 3; j++) { // vtMatrix[6+j] *= -1.0f; // } // } // // double rotationMatrix[9]; // for(int j = 0; j < 3; j++) { // for(int k = 0; k < 3; k++) { // rotationMatrix[3*k+j] = 0.0f; // for(int l = 0; l < 3; l++) { // rotationMatrix[3*k+j] += uMatrix[3*j+l] * vtMatrix[3*l+k]; // } // } // } // double det = rotationMatrix[0]*rotationMatrix[4]*rotationMatrix[8] + rotationMatrix[1]*rotationMatrix[5]*rotationMatrix[6] + rotationMatrix[2]*rotationMatrix[3]*rotationMatrix[7] - rotationMatrix[2]*rotationMatrix[4]*rotationMatrix[6] - rotationMatrix[1]*rotationMatrix[3]*rotationMatrix[8] - rotationMatrix[0]*rotationMatrix[5]*rotationMatrix[7]; // if(det < 0) { // mprintf(RED, "det < 0\n"); // } CxDVector3 translation; for(j = 0; j < 3; j++) { translation[j] = _centroid[j]; for(k = 0; k < 3; k++) { translation[j] -= rotationMatrix[3*j+k] * centroid[k]; } } double dist = 0.0; for(j = 0; j < _atomCount; j++) { CxDVector3 newCoord = translation; for(k = 0; k < 3; k++) { for(l = 0; l < 3; l++) { newCoord[k] += rotationMatrix[3*k+l] * coord[j][l]; } } ((CxDVec3Array *)_coordHistory[showMol*_permutationCount*_atomCount + i*_atomCount + ((CxIntArray *)_permutations[i])->GetAt(j)])->GetAt(_historyIndex) = newCoord; // ((CxDVec3Array *)_coordHistory[showMol*_permutationCount*_atomCount + i*_atomCount + ((CxIntArray *)_permutations[i])->GetPosition(j)])->GetAt(_historyIndex) = newCoord; // ((CxDVec3Array *)_coordHistory[showMol*_permutationCount*_atomCount + i*_atomCount + j])->GetAt(_historyIndex) = newCoord; CxDVector3 distVec = newCoord - ((CxDVec3Array *)_centroidCoords[i])->GetAt(j) - _centroid; dist += distVec.GetLengthSqr() * _weights[j]; } if(_useInternals) { double idist = 0.0; for(j = 0; j < _internals.GetSize(); j++) { double d1, d2; CxDVector3 vec1, vec2, vec3; vec1 = FoldVector(((CxDVec3Array *)_centroidCoords[i])->GetAt(((CxIntArray *)_internals[j])->GetAt(0)) - ((CxDVec3Array *)_centroidCoords[i])->GetAt(((CxIntArray *)_internals[j])->GetAt(1))); vec2 = FoldVector(((CxDVec3Array *)_centroidCoords[i])->GetAt(((CxIntArray *)_internals[j])->GetAt(3)) - ((CxDVec3Array *)_centroidCoords[i])->GetAt(((CxIntArray *)_internals[j])->GetAt(2))); vec3 = FoldVector(((CxDVec3Array *)_centroidCoords[i])->GetAt(((CxIntArray *)_internals[j])->GetAt(2)) - ((CxDVec3Array *)_centroidCoords[i])->GetAt(((CxIntArray *)_internals[j])->GetAt(1))); d1 = Dihedral(vec1, vec2, vec3, false); vec1 = FoldVector(((CxDVec3Array *)_coordHistory[showMol*_permutationCount*_atomCount + i*_atomCount + ((CxIntArray *)_permutations[i])->GetAt(((CxIntArray *)_internals[j])->GetAt(0))])->GetAt(_historyIndex) - ((CxDVec3Array *)_coordHistory[showMol*_permutationCount*_atomCount + i*_atomCount + ((CxIntArray *)_permutations[i])->GetAt(((CxIntArray *)_internals[j])->GetAt(1))])->GetAt(_historyIndex)); vec2 = FoldVector(((CxDVec3Array *)_coordHistory[showMol*_permutationCount*_atomCount + i*_atomCount + ((CxIntArray *)_permutations[i])->GetAt(((CxIntArray *)_internals[j])->GetAt(3))])->GetAt(_historyIndex) - ((CxDVec3Array *)_coordHistory[showMol*_permutationCount*_atomCount + i*_atomCount + ((CxIntArray *)_permutations[i])->GetAt(((CxIntArray *)_internals[j])->GetAt(2))])->GetAt(_historyIndex)); vec3 = FoldVector(((CxDVec3Array *)_coordHistory[showMol*_permutationCount*_atomCount + i*_atomCount + ((CxIntArray *)_permutations[i])->GetAt(((CxIntArray *)_internals[j])->GetAt(2))])->GetAt(_historyIndex) - ((CxDVec3Array *)_coordHistory[showMol*_permutationCount*_atomCount + i*_atomCount + ((CxIntArray *)_permutations[i])->GetAt(((CxIntArray *)_internals[j])->GetAt(1))])->GetAt(_historyIndex)); d2 = Dihedral(vec1, vec2, vec3, false); double diff = fabs(d1 - d2); if(diff > 180.0) diff = 360.0 - diff; idist += diff * diff; } ((CxDoubleArray *)_distanceTimedev[showMol*_permutationCount + i])->Add(sqrt(idist)); } else { ((CxDoubleArray *)_distanceTimedev[showMol*_permutationCount + i])->Add(sqrt(dist) / sqrt(_weightSum)); } if(_calcIR) { CxDVector3 newDipole(0.0, 0.0, 0.0); for(j = 0; j < 3; j++) { for(k = 0; k < 3; k++) { newDipole[j] += rotationMatrix[3*j+k] * dipole[k]; } } ((CxDVec3Array *)_dipoleHistory[showMol*_permutationCount + i])->GetAt(_historyIndex) = newDipole; } if(_writeTransformedTrajectories && (showMol == 0)) { fprintf(_transformedTrajectoryFiles[i], "%4d\n\n", _atomCount); for(j = 0; j < _atomCount; j++) { fprintf(_transformedTrajectoryFiles[i], "%4s %12.6f %12.6f %12.6f\n", (const char*)((CAtom *)g_oaAtoms[_singleMol->m_baAtomIndex[((CMolAtom *)_singleMol->m_oaMolAtoms[j])->m_iType]])->m_sName, ((CxDVec3Array *)_coordHistory[i*_atomCount + j])->GetAt(_historyIndex)[0] / 100.0, ((CxDVec3Array *)_coordHistory[i*_atomCount + j])->GetAt(_historyIndex)[1] / 100.0, ((CxDVec3Array *)_coordHistory[i*_atomCount + j])->GetAt(_historyIndex)[2] / 100.0); // fprintf(_transformedTrajectoryFiles[i], "%4s %12.6f %12.6f %12.6f\n", ((CAtom *)g_oaAtoms[_singleMol->m_baAtomIndex[((CMolAtom *)_singleMol->m_oaMolAtoms[j])->m_iType]])->m_sName, ((CxDVec3Array *)_coordHistory[i*_atomCount + ((CxIntArray *)_permutations[i])->GetPosition(j)])->GetAt(_historyIndex)[0] / 100.0f, ((CxDVec3Array *)_coordHistory[i*_atomCount + ((CxIntArray *)_permutations[i])->GetPosition(j)])->GetAt(_historyIndex)[1] / 100.0f, ((CxDVec3Array *)_coordHistory[i*_atomCount + ((CxIntArray *)_permutations[i])->GetPosition(j)])->GetAt(_historyIndex)[2] / 100.0f); } } } } void CReferenceStructure::calcVelocities(int showMol) { int n = (_historyIndex + 1) % 3; int i, j; for(i = 0; i < _permutationCount; i++) { for(j = 0; j < _atomCount; j++) { CxDVector3 velVec; velVec = (((CxDVec3Array *)_coordHistory[showMol*_permutationCount*_atomCount + i*_atomCount + j])->GetAt(_historyIndex) - ((CxDVec3Array *)_coordHistory[showMol*_permutationCount*_atomCount + i*_atomCount + j])->GetAt(n)) / 2.0 / g_fTimestepLength * 1000.0; ((CxDVec3Array *)_velocityCache[showMol*_permutationCount*_atomCount + i*_atomCount + j])->Add(velVec); } if(_calcIR) { CxDVector3 derVec; derVec = (((CxDVec3Array *)_dipoleHistory[showMol*_permutationCount + i])->GetAt(_historyIndex) - ((CxDVec3Array *)_dipoleHistory[showMol*_permutationCount + i])->GetAt(n)) / 2.0 / g_fTimestepLength; ((CxDVec3Array *)_dipoleDerivativeCache[showMol*_permutationCount + i])->Add(derVec); } } } double CReferenceStructure::calcMinimumDistance(int showMol, bool useInternals, CxObArray &internals) { double minDist = 0.0; int i, j; for(i = 0; i < _permutationCount; i++) { if(useInternals) { double idist = 0.0; for(j = 0; j < internals.GetSize(); j++) { double d1, d2; CxDVector3 vec1, vec2, vec3; vec1 = FoldVector(((CxDVec3Array *)_centroidCoords[i])->GetAt(((CxIntArray *)internals[j])->GetAt(0)) - ((CxDVec3Array *)_centroidCoords[i])->GetAt(((CxIntArray *)internals[j])->GetAt(1))); vec2 = FoldVector(((CxDVec3Array *)_centroidCoords[i])->GetAt(((CxIntArray *)internals[j])->GetAt(3)) - ((CxDVec3Array *)_centroidCoords[i])->GetAt(((CxIntArray *)internals[j])->GetAt(2))); vec3 = FoldVector(((CxDVec3Array *)_centroidCoords[i])->GetAt(((CxIntArray *)internals[j])->GetAt(2)) - ((CxDVec3Array *)_centroidCoords[i])->GetAt(((CxIntArray *)internals[j])->GetAt(1))); d1 = Dihedral(vec1, vec2, vec3, false); vec1 = FoldVector(((CxDVec3Array *)_coordHistory[showMol*_permutationCount*_atomCount + i*_atomCount + ((CxIntArray *)_permutations[i])->GetAt(((CxIntArray *)internals[j])->GetAt(0))])->GetAt(_historyIndex) - ((CxDVec3Array *)_coordHistory[showMol*_permutationCount*_atomCount + i*_atomCount + ((CxIntArray *)_permutations[i])->GetAt(((CxIntArray *)internals[j])->GetAt(1))])->GetAt(_historyIndex)); vec2 = FoldVector(((CxDVec3Array *)_coordHistory[showMol*_permutationCount*_atomCount + i*_atomCount + ((CxIntArray *)_permutations[i])->GetAt(((CxIntArray *)internals[j])->GetAt(3))])->GetAt(_historyIndex) - ((CxDVec3Array *)_coordHistory[showMol*_permutationCount*_atomCount + i*_atomCount + ((CxIntArray *)_permutations[i])->GetAt(((CxIntArray *)internals[j])->GetAt(2))])->GetAt(_historyIndex)); vec3 = FoldVector(((CxDVec3Array *)_coordHistory[showMol*_permutationCount*_atomCount + i*_atomCount + ((CxIntArray *)_permutations[i])->GetAt(((CxIntArray *)internals[j])->GetAt(2))])->GetAt(_historyIndex) - ((CxDVec3Array *)_coordHistory[showMol*_permutationCount*_atomCount + i*_atomCount + ((CxIntArray *)_permutations[i])->GetAt(((CxIntArray *)internals[j])->GetAt(1))])->GetAt(_historyIndex)); d2 = Dihedral(vec1, vec2, vec3, false); double diff = fabs(d1 - d2); if(diff > 180.0) diff = 360.0 - diff; idist += diff * diff; } idist = sqrt(idist); if(i == 0) { minDist = idist; } else { if(idist < minDist) { minDist = idist; } } } else { double dist = 0.0; for(j = 0; j < _atomCount; j++) { CxDVector3 distVec = ((CxDVec3Array *)_centroidCoords[i])->GetAt(j) - ((CxDVec3Array *)_coordHistory[showMol*_permutationCount*_atomCount + i*_atomCount + ((CxIntArray *)_permutations[i])->GetAt(j)])->GetAt(_historyIndex); dist += distVec.GetLengthSqr() * _weights[j]; } dist = sqrt(dist) / sqrt(_weightSum); if(i == 0) { minDist = dist; } else { if(dist < minDist) { minDist = dist; } } } } return minDist; } void CReferenceStructure::nextStep() { _historyIndex = (_historyIndex + 1) % 3; _numSteps++; } double CReferenceStructure::getMinimumDistance(int showMol, int step) { if(step > _numSteps) { eprintf("CReferenceStructure::getMinimumDistance(): Error: Illegal step number.\n"); abort(); } double minDist = ((CxDoubleArray *)_distanceTimedev[showMol*_permutationCount])->GetAt(step); int i; for(i = 1; i < _permutationCount; i++) { if(((CxDoubleArray *)_distanceTimedev[showMol*_permutationCount + i])->GetAt(step) < minDist) minDist = ((CxDoubleArray *)_distanceTimedev[showMol*_permutationCount + i])->GetAt(step); } return minDist; } void CReferenceStructure::setGlobalProbability(int showMol, int step, double prob) { if(_globalProb.GetSize() < _showMolCount) { int i; for(i = 0; i < _showMolCount; i++) { CxDoubleArray *a; try { a = new CxDoubleArray(); } catch(...) { a = NULL; } if(a == NULL) NewException((double)sizeof(CxDoubleArray), __FILE__, __LINE__, __PRETTY_FUNCTION__); a->SetSize(_numSteps); _globalProb.Add(a); } } ((CxDoubleArray *)_globalProb[showMol])->GetAt(step) = prob; } void CReferenceStructure::finalize(const char *basename) { int i, j, k, l, m, n, o; if(_writeTransformedTrajectories) { for(i = 0; i < _permutationCount; i++) { fclose(_transformedTrajectoryFiles[i]); } delete[] _transformedTrajectoryFiles; } mprintf(" Saving distance time development...\n"); char name[BUF_SIZE]; #ifdef TARGET_LINUX snprintf(name, BUF_SIZE, "%s_dist_timedev.csv", basename); #else sprintf(name, "%s_dist_timedev.csv", basename); #endif FILE *distanceFile = OpenFileWrite(name, false); fprintf(distanceFile, "#Time (fs);"); for(i = 0; i < _showMolCount; i++) { for(j = 0; j < _permutationCount; j++) { fprintf(distanceFile, " M%d P%d;", i+1, j+1); } } fprintf(distanceFile, "\n"); for(i = 0; i < _numSteps; i++) { fprintf(distanceFile, "%.2f;", i * g_fTimestepLength * g_iStride); for(j = 0; j < _showMolCount; j++) { for(k = 0; k < _permutationCount; k++) { fprintf(distanceFile, " %.8G;", ((CxDoubleArray *)_distanceTimedev[j*_permutationCount + k])->GetAt(i)); } } fprintf(distanceFile, "\n"); } fclose(distanceFile); mprintf(" Saving probability time development...\n"); #ifdef TARGET_LINUX snprintf(name, BUF_SIZE, "%s_prob_timedev.csv", basename); #else sprintf(name, "%s_prob_timedev.csv", basename); #endif FILE *probFile = OpenFileWrite(name, false); fprintf(probFile, "#Time (fs);"); for(i = 0; i < _showMolCount; i++) { for(j = 0; j < _permutationCount; j++) { fprintf(probFile, " M%d P%d;", i+1, j+1); } } fprintf(probFile, "\n"); CxDoubleArray probSum; probSum.SetSize(_showMolCount*_numSteps); for(i = 0; i < _numSteps; i++) { fprintf(probFile, "%.2f;", i * g_fTimestepLength * g_iStride); for(j = 0; j < _showMolCount; j++) { CxDoubleArray probs; probs.SetSize(_permutationCount); probSum[j*_numSteps + i] = 0.0; if(_permutationCount == 1) { probs[0] = 1.0; probSum[j*_numSteps + i] = 1.0; fprintf(probFile, " %.8G;", probs[0] / probSum[j*_numSteps + i]); } else { for(k = 0; k < _permutationCount; k++) { probs[k] = exp(-(double)((CxDoubleArray *)_distanceTimedev[j*_permutationCount + k])->GetAt(i) * (double)((CxDoubleArray *)_distanceTimedev[j*_permutationCount + k])->GetAt(i) / 2.0 / (double)_gaussianWidth / (double)_gaussianWidth); probSum[j*_numSteps + i] += probs[k]; } for(k = 0; k < _permutationCount; k++) { if(isnan(probs[k] / probSum[j*_numSteps + i])) { eprintf("CReferenceStructure::finalize(): Error: Invalid probability for permutation %d of molecule %d in step %d.\nMaybe it helps to increase the distribution width.\nTwo identical reference structures can also cause this error.\n", k+1, j+1, i+1); abort(); } fprintf(probFile, " %.8G;", probs[k] / probSum[j*_numSteps + i]); } } } fprintf(probFile, "\n"); } fclose(probFile); mprintf(" Calculating cross-correlation matrix...\n"); CxObArray ccMatrix; for(i = 0; i < 3 * _atomCount * (3 * _atomCount + 1) / 2; i++) { CxDoubleArray *a; try { a = new CxDoubleArray(); } catch(...) { a = NULL; } if(a == NULL) NewException((double)sizeof(CxDoubleArray), __FILE__, __LINE__, __PRETTY_FUNCTION__); a->SetSize(_correlationDepth); for(j = 0; j < _correlationDepth; j++) { a->GetAt(j) = 0.0; } ccMatrix.Add(a); } CCrossCorrelation *cc; try { cc = new CCrossCorrelation(); } catch(...) { cc = NULL; } if(cc == NULL) NewException((double)sizeof(CCrossCorrelation), __FILE__, __LINE__, __PRETTY_FUNCTION__); cc->Init(_numSteps-2, _correlationDepth, g_bACFFFT); CxDoubleArray *atemp; try { atemp = new CxDoubleArray(); } catch(...) { atemp = NULL; } if(atemp == NULL) NewException((double)sizeof(CxDoubleArray), __FILE__, __LINE__, __PRETTY_FUNCTION__); atemp->SetSize(_numSteps-2); CxDoubleArray *temp2; try { temp2 = new CxDoubleArray(); } catch(...) { temp2 = NULL; } if(temp2 == NULL) NewException((double)sizeof(CxDoubleArray), __FILE__, __LINE__, __PRETTY_FUNCTION__); temp2->SetSize(_numSteps-2); CxDoubleArray *temp3; try { temp3 = new CxDoubleArray(); } catch(...) { temp3 = NULL; } if(temp3 == NULL) NewException((double)sizeof(CxDoubleArray), __FILE__, __LINE__, __PRETTY_FUNCTION__); temp3->SetSize(_correlationDepth); mprintf(WHITE, " ["); double step = (double)(_showMolCount * _permutationCount * 3*_atomCount * (3*_atomCount+1)/2) / 20.0; int ci = 0; for(i = 0; i < _showMolCount; i++) { // for(int i = 1; i < 2; i++) { for(j = 0; j < _permutationCount; j++) { // for(int j = 0; j < 1; j++) { for(k = 0; k < _atomCount; k++) { for(l = 0; l < 3; l++) { for(m = k; m < _atomCount; m++) { for(n = ((m == k) ? l : 0); n < 3; n++) { if(fmod((double)ci++, step) < 1.0) mprintf(WHITE, "#"); for(o = 0; o < _numSteps - 2; o++) { // temp->GetAt(o) = exp(-((CxFloatArray *)_distanceTimedev[i*_permutationCount + j])->GetAt(o+1) * ((CxFloatArray *)_distanceTimedev[i*_permutationCount + j])->GetAt(o+1) / 2.0f / _gaussianWidth / _gaussianWidth) / probSum[i] * ((CxDVec3Array *)_velocityCache[i*_permutationCount*_atomCount + j*_atomCount + k])->GetAt(o)[l] * sqrtf(_weights[k]); // temp->GetAt(o) = ((CxFloatArray *)_globalProb[i])->GetAt(o) * exp(-((CxFloatArray *)_distanceTimedev[i*_permutationCount + j])->GetAt(o+1) * ((CxFloatArray *)_distanceTimedev[i*_permutationCount + j])->GetAt(o+1) / 2.0f / _gaussianWidth / _gaussianWidth) / probSum[i] * ((CxDVec3Array *)_velocityCache[i*_permutationCount*_atomCount + j*_atomCount + k])->GetAt(o)[l] * sqrtf(_weights[k]); // mprintf(RED, "%f %f %f\n", exp(-(double)((CxFloatArray *)_distanceTimedev[i*_permutationCount + j])->GetAt(o+1) * (double)((CxFloatArray *)_distanceTimedev[i*_permutationCount + j])->GetAt(o+1) / 2.0 / (double)_gaussianWidth / (double)_gaussianWidth), probSum[i*_numSteps + o+1], (exp(-(double)((CxFloatArray *)_distanceTimedev[i*_permutationCount + j])->GetAt(o+1) * (double)((CxFloatArray *)_distanceTimedev[i*_permutationCount + j])->GetAt(o+1) / 2.0 / (double)_gaussianWidth / (double)_gaussianWidth) / probSum[i*_numSteps + o+1])); if(_permutationCount == 1) { atemp->GetAt(o) = ((CxDoubleArray *)_globalProb[i])->GetAt(o+1) * ((CxDVec3Array *)_velocityCache[i*_permutationCount*_atomCount + j*_atomCount + k])->GetAt(o)[l] * sqrt(_weights[k]); } else { atemp->GetAt(o) = ((CxDoubleArray *)_globalProb[i])->GetAt(o+1) * (double)(exp(-(double)((CxDoubleArray *)_distanceTimedev[i*_permutationCount + j])->GetAt(o+1) * (double)((CxDoubleArray *)_distanceTimedev[i*_permutationCount + j])->GetAt(o+1) / 2.0 / (double)_gaussianWidth / (double)_gaussianWidth) / probSum[i*_numSteps + o+1]) * ((CxDVec3Array *)_velocityCache[i*_permutationCount*_atomCount + j*_atomCount + k])->GetAt(o)[l] * sqrt(_weights[k]); } temp2->GetAt(o) = ((CxDVec3Array *)_velocityCache[i*_permutationCount*_atomCount + j*_atomCount + m])->GetAt(o)[n] * sqrt(_weights[m]); } cc->CrossCorrelate(atemp, temp2, temp3); for(o = 0; o < _correlationDepth; o++) { ((CxDoubleArray *)ccMatrix[(3*_atomCount-1)*(3*k+l) - (3*k+l)*(3*k+l-1)/2 + (3*m+n)])->GetAt(o) += temp3->GetAt(o); } } } } } } } mprintf(WHITE, "]\n"); for(k = 0; k < _atomCount; k++) { for(l = 0; l < 3; l++) { for(m = k; m < _atomCount; m++) { for(n = ((m == k) ? l : 0); n < 3; n++) { for(o = 0; o < _correlationDepth; o++) { ((CxDoubleArray *)ccMatrix[(3*_atomCount-1)*(3*k+l) - (3*k+l)*(3*k+l-1)/2 + (3*m+n)])->GetAt(o) /= (double)_showMolCount; } } } } } // for(int i = 0; i < 3 * _atomCount; i++) { // for(int j = i; j < 3 * _atomCount; j++) { // char name[BUF_SIZE]; // snprintf(name, BUF_SIZE, "ccf_%d_%d.dat", i, j); // FILE *ccfFile = fopen(name, "w"); // for(int k = 0; k < _correlationDepth; k++) { // fprintf(ccfFile, "%g %g %g\n", g_fTimestepLength * k, ((CxFloatArray *)ccMatrix[(3*_atomCount-1)*i - i*(i-1)/2 + j])->GetAt(k), ((CxDVec3Array *)_velocityCache[i])->GetAt(k)[0]); // } // fclose(ccfFile); // } // } CFFT *fft; try { fft = new CFFT(); } catch(...) { fft = NULL; } if(fft == NULL) NewException((double)sizeof(CFFT), __FILE__, __LINE__, __PRETTY_FUNCTION__); fft->PrepareFFT_C2C(2 * (((CxDoubleArray *)ccMatrix[0])->GetSize() + _zeroPadding)); mprintf(" Fourier transforming cross-correlation matrix...\n"); mprintf(WHITE, " ["); step = (double)(3*_atomCount * (3*_atomCount+1)/2) / 20.0; ci = 0; for(i = 0; i < 3 * _atomCount; i++) { for(j = i; j < 3 * _atomCount; j++) { if(fmod((double)ci++, step) < 1.0) mprintf(WHITE, "#"); atemp->CopyFrom((CxDoubleArray *)ccMatrix[(3*_atomCount-1)*i - i*(i-1)/2 + j]); if(_windowFunction == 1) { for(k = 0; k < atemp->GetSize(); k++) { atemp->GetAt(k) *= pow2(cos((double)k / (atemp->GetSize() - 1) / 2.0 * Pi)); } } else if(_windowFunction == 2) { for(k = 0; k < atemp->GetSize(); k++) { atemp->GetAt(k) *= exp(-(double)k / _windowFunctionParameter); } } else if(_windowFunction == 3) { for(k = 0; k < atemp->GetSize(); k++) { atemp->GetAt(k) *= exp(-(double)k * k / _windowFunctionParameter / _windowFunctionParameter); } } else if(_windowFunction != 0) { eprintf("Unknown window function.\n"); abort(); } if(_zeroPadding > 0) { for(k = 0; k < _zeroPadding; k++) { atemp->Add(0.0); } } int oldSize = atemp->GetSize(); atemp->SetSize(2 * oldSize); for(k = 1; k < oldSize; k++) { atemp->GetAt(oldSize + k) = atemp->GetAt(oldSize - k); } atemp->GetAt(oldSize) = 0.0; // fft->PrepareFFT_C2C(temp->GetSize()); for(k = 0; k < atemp->GetSize(); k++) { fft->m_pInput[2*k] = atemp->GetAt(k); fft->m_pInput[2*k+1] = 0.0; } fft->DoFFT(); ((CxDoubleArray *)ccMatrix[(3*_atomCount-1)*i - i*(i-1)/2 + j])->SetSize(_specSize); for(k = 0; k < _specSize; k++) { ((CxDoubleArray *)ccMatrix[(3*_atomCount-1)*i - i*(i-1)/2 + j])->GetAt(k) = 7.211349e-9 * fft->m_pOutput[2*k] * g_fTimestepLength; // Spectra in K*cm // ((CxFloatArray *)ccMatrix[(3*_atomCount-1)*i - i*(i-1)/2 + j])->GetAt(k) = sqrtf(fft->m_pOutput[2*k]*fft->m_pOutput[2*k]+fft->m_pOutput[2*k+1]*fft->m_pOutput[2*k+1]); } } } mprintf(WHITE, "]\n"); delete fft; mprintf(" Saving power spectrum...\n"); #ifdef TARGET_LINUX snprintf(name, BUF_SIZE, "%s_power.csv", basename); #else sprintf(name, "%s_power.csv", basename); #endif FILE *powerFile = OpenFileWrite(name, false); fprintf(powerFile, "#Wavenumber (cm^-1); Spectrum (K*cm); Integral (K)\n"); double integral = 0.0; for(i = 0; i < _specSize; i++) { double value = 0.0; for(j = 0; j < 3*_atomCount; j++) { value += ((CxDoubleArray *)ccMatrix[(3*_atomCount-1)*j - j*(j-1)/2 + j])->GetAt(i); } integral += (double)value * _specResolution; fprintf(powerFile, "%.2f; %.8G; %.14G\n", _specResolution*i, value, integral); } fclose(powerFile); // mprintf(" Saving inital spectra...\n"); // snprintf(name, BUF_SIZE, "%s_speci.dat", basename); // FILE *speciFile = OpenFileWrite(name, false); // for(int i = 0; i < _specSize; i++) { // fprintf(speciFile, "%10.4f", _specResolution * i); // for(int j = 0; j < 3*_atomCount; j++) { // fprintf(speciFile, " %20.8f", ((CxFloatArray *)ccMatrix[(3*_atomCount-1)*j - j*(j-1)/2 + j])->GetAt(i)); // } // fprintf(speciFile, "\n"); // } // fclose(speciFile); // CxDoubleArray *transMatrix; try { transMatrix = new CxDoubleArray(); } catch(...) { transMatrix = NULL; } if(transMatrix == NULL) NewException((double)sizeof(CxDoubleArray), __FILE__, __LINE__, __PRETTY_FUNCTION__); transMatrix->SetMaxSize(9 * _atomCount * _atomCount); for(i = 0; i < 3 * _atomCount; i++) { for(j = 0; j < 3 * _atomCount; j++) { transMatrix->Add((i == j) ? 1.0 : 0.0); } } // for(int i = 0; i < 3 * _atomCount; i++) { // for(int j = i; j < 3 * _atomCount; j++) { // char name[BUF_SIZE]; // snprintf(name, BUF_SIZE, "speca_%d_%d.dat", i, j); // FILE *specFile = fopen(name, "w"); // for(int k = 0; k < _specSize; k++) { // fprintf(specFile, "%g %g\n", _specResolution * k, ((CxFloatArray *)ccMatrix[(3*_atomCount-1)*i - i*(i-1)/2 + j])->GetAt(k)); // } // fclose(specFile); // } // } // FILE *testFile = fopen("test.out", "w"); // for(int i = 0; i < _specSize; i++) { // fprintf(testFile, "%f", _specResolution * i); // for(int j = 0; j < 3 * _atomCount; j++) { // for(int k = j; k < 3 * _atomCount; k++) { // fprintf(testFile, " %f", ((CxFloatArray *)ccMatrix[(3*_atomCount-1)*j - j*(j-1)/2 + k])->GetAt(i)); // } // } // fprintf(testFile, "\n"); // } // fclose(testFile); mprintf(" Minimizing cross-correlations...\n\n"); mprintf(" ---------------------------------------------------\n"); mprintf(" Iteration Off-diagonal norm Change\n"); mprintf(" ---------------------------------------------------\n"); double norm = offDiagonalNorm(ccMatrix); double change = norm; mprintf(" %9d %20g %20g\n", 1, norm, change); int count = 0; temp2->SetSize(3*_atomCount); while((fabs(change) > _convergenceThreshold * norm) && (count < _maxIterations)) { count++; for(i = 0; i < 3*_atomCount; i++) { for(j = i+1; j < 3*_atomCount; j++) { // mprintf(RED, "i: %d, j: %d\n", i, j); double t = findRotationAngle(ccMatrix, i, j); double c = 1.0 / sqrt(t * t + 1.0); double s = t * c; double temp[3]; // mprintf(RED, "(%d, %d) t: %f\n", i, j, t); for(k = 0; k < _specSize; k++) { // mprintf(RED, "k: %d\n", k); for(l = 0; l < j; l++) { if(l < i) { temp[0] = c * ((CxDoubleArray *)ccMatrix[(3*_atomCount-1)*l - l*(l-1)/2 + i])->GetAt(k) - s * ((CxDoubleArray *)ccMatrix[(3*_atomCount-1)*l - l*(l-1)/2 + j])->GetAt(k); temp[1] = s * ((CxDoubleArray *)ccMatrix[(3*_atomCount-1)*l - l*(l-1)/2 + i])->GetAt(k) + c * ((CxDoubleArray *)ccMatrix[(3*_atomCount-1)*l - l*(l-1)/2 + j])->GetAt(k); ((CxDoubleArray *)ccMatrix[(3*_atomCount-1)*l - l*(l-1)/2 + i])->GetAt(k) = temp[0]; ((CxDoubleArray *)ccMatrix[(3*_atomCount-1)*l - l*(l-1)/2 + j])->GetAt(k) = temp[1]; } else if(l > i) { temp2->GetAt(l) = ((CxDoubleArray *)ccMatrix[(3*_atomCount-1)*l - l*(l-1)/2 + j])->GetAt(k); temp[1] = s * ((CxDoubleArray *)ccMatrix[(3*_atomCount-1)*i - i*(i-1)/2 + l])->GetAt(k) + c * ((CxDoubleArray *)ccMatrix[(3*_atomCount-1)*l - l*(l-1)/2 + j])->GetAt(k); ((CxDoubleArray *)ccMatrix[(3*_atomCount-1)*l - l*(l-1)/2 + j])->GetAt(k) = temp[1]; } } for(l = i+1; l < 3*_atomCount; l++) { if(l < j) { temp[0] = c * ((CxDoubleArray *)ccMatrix[(3*_atomCount-1)*i - i*(i-1)/2 + l])->GetAt(k) - s * temp2->GetAt(l); ((CxDoubleArray *)ccMatrix[(3*_atomCount-1)*i - i*(i-1)/2 + l])->GetAt(k) = temp[0]; } else if(l > j) { temp[0] = c * ((CxDoubleArray *)ccMatrix[(3*_atomCount-1)*i - i*(i-1)/2 + l])->GetAt(k) - s * ((CxDoubleArray *)ccMatrix[(3*_atomCount-1)*j - j*(j-1)/2 + l])->GetAt(k); temp[1] = s * ((CxDoubleArray *)ccMatrix[(3*_atomCount-1)*i - i*(i-1)/2 + l])->GetAt(k) + c * ((CxDoubleArray *)ccMatrix[(3*_atomCount-1)*j - j*(j-1)/2 + l])->GetAt(k); ((CxDoubleArray *)ccMatrix[(3*_atomCount-1)*i - i*(i-1)/2 + l])->GetAt(k) = temp[0]; ((CxDoubleArray *)ccMatrix[(3*_atomCount-1)*j - j*(j-1)/2 + l])->GetAt(k) = temp[1]; } } temp[0] = c * c * ((CxDoubleArray *)ccMatrix[(3*_atomCount-1)*i - i*(i-1)/2 + i])->GetAt(k) + s * s * ((CxDoubleArray *)ccMatrix[(3*_atomCount-1)*j - j*(j-1)/2 + j])->GetAt(k) - 2 * c * s * ((CxDoubleArray *)ccMatrix[(3*_atomCount-1)*i - i*(i-1)/2 + j])->GetAt(k); temp[1] = (c * c - s * s) * ((CxDoubleArray *)ccMatrix[(3*_atomCount-1)*i - i*(i-1)/2 + j])->GetAt(k) + c * s * (((CxDoubleArray *)ccMatrix[(3*_atomCount-1)*i - i*(i-1)/2 + i])->GetAt(k) - ((CxDoubleArray *)ccMatrix[(3*_atomCount-1)*j - j*(j-1)/2 + j])->GetAt(k)); temp[2] = s * s * ((CxDoubleArray *)ccMatrix[(3*_atomCount-1)*i - i*(i-1)/2 + i])->GetAt(k) + c * c * ((CxDoubleArray *)ccMatrix[(3*_atomCount-1)*j - j*(j-1)/2 + j])->GetAt(k) + 2 * c * s * ((CxDoubleArray *)ccMatrix[(3*_atomCount-1)*i - i*(i-1)/2 + j])->GetAt(k); ((CxDoubleArray *)ccMatrix[(3*_atomCount-1)*i - i*(i-1)/2 + i])->GetAt(k) = temp[0]; ((CxDoubleArray *)ccMatrix[(3*_atomCount-1)*i - i*(i-1)/2 + j])->GetAt(k) = temp[1]; ((CxDoubleArray *)ccMatrix[(3*_atomCount-1)*j - j*(j-1)/2 + j])->GetAt(k) = temp[2]; } for(l = 0; l < 3*_atomCount; l++) { temp[0] = c * transMatrix->GetAt(i * 3*_atomCount + l) - s * transMatrix->GetAt(j * 3*_atomCount + l); temp[1] = s * transMatrix->GetAt(i * 3*_atomCount + l) + c * transMatrix->GetAt(j * 3*_atomCount + l); transMatrix->GetAt(i * 3*_atomCount + l) = temp[0]; transMatrix->GetAt(j * 3*_atomCount + l) = temp[1]; } } } double newNorm = offDiagonalNorm(ccMatrix); change = newNorm - norm; norm = newNorm; mprintf(" %9d %20g %20g\n", count+1, norm, change); } mprintf(" ---------------------------------------------------\n"); if(count == _maxIterations) { eprintf("\nMinimization did not converge.\n\n"); mprintf("Maybe it helps to increase the number of iterations or the convergence threshold.\n"); mprintf("Will write unconverged results anyway.\n\n"); } else mprintf(" Convergence reached after %d iterations.\n\n", count+1); delete atemp; delete temp2; delete temp3; // for(int i = 0; i < 3 * _atomCount; i++) { // for(int j = i; j < 3 * _atomCount; j++) { // char name[BUF_SIZE]; // snprintf(name, BUF_SIZE, "specb_%d_%d.dat", i, j); // FILE *specFile = fopen(name, "w"); // for(int k = 0; k < _specSize; k++) { // fprintf(specFile, "%g %g\n", _specResolution * k, ((CxFloatArray *)ccMatrix[(3*_atomCount-1)*i - i*(i-1)/2 + j])->GetAt(k)); // } // fclose(specFile); // } // } // FILE *test2File = fopen("test2.out", "w"); // for(int i = 0; i < _specSize; i++) { // fprintf(test2File, "%f", _specResolution * i); // for(int j = 0; j < 3 * _atomCount; j++) { // for(int k = j; k < 3 * _atomCount; k++) { // fprintf(test2File, " %f", ((CxFloatArray *)ccMatrix[(3*_atomCount-1)*j - j*(j-1)/2 + k])->GetAt(i)); // } // } // fprintf(test2File, "\n"); // } // fclose(test2File); mprintf(" Calculating integrals...\n"); CxDoubleArray *integrals; try { integrals = new CxDoubleArray(); } catch(...) { integrals = NULL; } if(integrals == NULL) NewException((double)sizeof(CxDoubleArray), __FILE__, __LINE__, __PRETTY_FUNCTION__); CxDoubleArray *centers; try { centers = new CxDoubleArray(); } catch(...) { centers = NULL; } if(centers == NULL) NewException((double)sizeof(CxDoubleArray), __FILE__, __LINE__, __PRETTY_FUNCTION__); calcIntegrals(ccMatrix, integrals, centers); mprintf(" Sorting normal coordinates...\n\n"); CxIntArray *sortIndex; try { sortIndex = new CxIntArray(); } catch(...) { sortIndex = NULL; } if(sortIndex == NULL) NewException((double)sizeof(CxIntArray), __FILE__, __LINE__, __PRETTY_FUNCTION__); for(i = 0; i < 6; i++) { int minIndex = 0; while(sortIndex->Contains(minIndex) && (minIndex < 3*_atomCount - 1)) minIndex++; double minIntegral = integrals->GetAt(minIndex); for(j = minIndex+1; j < 3*_atomCount; j++) { if(sortIndex->Contains(j)) continue; if(integrals->GetAt(j) < minIntegral) { minIndex = j; minIntegral = integrals->GetAt(minIndex); } } sortIndex->Add(minIndex); } for(i = 6; i < 3*_atomCount; i++) { int minIndex = 0; while(sortIndex->Contains(minIndex) && (minIndex < 3*_atomCount - 1)) minIndex++; double minCenter = centers->GetAt(minIndex); for(j = minIndex+1; j < 3*_atomCount; j++) { if(sortIndex->Contains(j)) continue; if(centers->GetAt(j) < minCenter) { minIndex = j; minCenter = centers->GetAt(minIndex); } } sortIndex->Add(minIndex); } mprintf(" ----------------------------------------------\n"); mprintf(" Mode Integral (K) Center (cm^-1)\n"); mprintf(" ----------------------------------------------\n"); for(i = 0; i < 3*_atomCount; i++) { mprintf(" %4d %20g %20.2f\n", i+1, integrals->GetAt(sortIndex->GetAt(i)), centers->GetAt(sortIndex->GetAt(i))); if(i == 5) mprintf(" ----------------------------------------------\n"); } mprintf(" ----------------------------------------------\n\n"); mprintf(" Saving normal coordinate spectra...\n"); #ifdef TARGET_LINUX snprintf(name, BUF_SIZE, "%s_spectra.csv", basename); #else sprintf(name, "%s_spectra.csv", basename); #endif FILE *specFile = OpenFileWrite(name, false); fprintf(specFile, "#Wavenumber (cm^-1);"); for(i = 0; i < 3*_atomCount; i++) { fprintf(specFile, " Mode %d (K*cm);", i+1); } fprintf(specFile, " Trace (K*cm)\n"); for(i = 0; i < _specSize; i++) { fprintf(specFile, "%.2f;", _specResolution * i); double value = 0.0; for(j = 0; j < 3*_atomCount; j++) { fprintf(specFile, " %.8G;", ((CxDoubleArray *)ccMatrix[(3*_atomCount-1)*sortIndex->GetAt(j) - sortIndex->GetAt(j)*(sortIndex->GetAt(j)-1)/2 + sortIndex->GetAt(j)])->GetAt(i)); value += ((CxDoubleArray *)ccMatrix[(3*_atomCount-1)*sortIndex->GetAt(j) - sortIndex->GetAt(j)*(sortIndex->GetAt(j)-1)/2 + sortIndex->GetAt(j)])->GetAt(i); } fprintf(specFile, " %.8G\n", value); } fclose(specFile); mprintf(" Creating Molden file...\n"); #ifdef TARGET_LINUX snprintf(name, BUF_SIZE, "%s.molden", basename); #else sprintf(name, "%s.molden", basename); #endif FILE *moldenFile = OpenFileWrite(name, false); fprintf(moldenFile, "[Molden Format]\n"); fprintf(moldenFile, "[FREQ]\n"); for(i = 0; i < 3*_atomCount; i++) { fprintf(moldenFile, "%f\n", i < 6 ? 0.0 : centers->GetAt(sortIndex->GetAt(i))); } fprintf(moldenFile, "[FR-COORD]\n"); for(i = 0; i < _atomCount; i++) { fprintf(moldenFile, "%s %f %f %f\n", (const char*)((CAtom *)g_oaAtoms[_singleMol->m_baAtomIndex[((CMolAtom *)_singleMol->m_oaMolAtoms[i])->m_iType]])->m_sName, ((CxDVec3Array *)_centroidCoords[0])->GetAt(i)[0] / 100.0 * 1.889726, ((CxDVec3Array *)_centroidCoords[0])->GetAt(i)[1] / 100.0 * 1.889726, ((CxDVec3Array *)_centroidCoords[0])->GetAt(i)[2] / 100.0 * 1.889726); } fprintf(moldenFile, "[FR-NORM-COORD]\n"); for(i = 0; i < 3*_atomCount; i++) { fprintf(moldenFile, "vibration %d\n", i+1); for(j = 0; j < 3*_atomCount; j+=3) { double mass = sqrt(((CAtom *)g_oaAtoms[_singleMol->m_baAtomIndex[((CMolAtom *)_singleMol->m_oaMolAtoms[j / 3])->m_iType]])->m_pElement->m_fMass); fprintf(moldenFile, "%f %f %f\n", transMatrix->GetAt(sortIndex->GetAt(i) * 3*_atomCount + j) / mass, transMatrix->GetAt(sortIndex->GetAt(i) * 3*_atomCount + j + 1) / mass, transMatrix->GetAt(sortIndex->GetAt(i) * 3*_atomCount + j + 2) / mass); } } // fprintf(moldenFile, "[INT]\n"); // for(int i = 0; i < 3*_atomCount; i++) { // fprintf(moldenFile, "%f\n", integrals->GetAt(i)); // } fclose(moldenFile); mprintf(" Creating NMD file...\n"); #ifdef TARGET_LINUX snprintf(name, BUF_SIZE, "%s.nmd", basename); #else sprintf(name, "%s.nmd", basename); #endif FILE *nmdFile = OpenFileWrite(name, false); fprintf(nmdFile, "atomnames"); for(i = 0; i < _atomCount; i++) { fprintf(nmdFile, " %s", (const char*)((CAtom *)g_oaAtoms[_singleMol->m_baAtomIndex[((CMolAtom *)_singleMol->m_oaMolAtoms[i])->m_iType]])->m_sName); } fprintf(nmdFile, "\n"); fprintf(nmdFile, "coordinates"); for(i = 0; i < _atomCount; i++) { for(j = 0; j < 3; j++) { fprintf(nmdFile, " %f", ((CxDVec3Array *)_centroidCoords[0])->GetAt(i)[j] / 100.0); } } fprintf(nmdFile, "\n"); for(i = 0; i < 3*_atomCount; i++) { fprintf(nmdFile, "mode %d", i+1); for(j = 0; j < 3*_atomCount; j+=3) { double mass = sqrt(((CAtom *)g_oaAtoms[_singleMol->m_baAtomIndex[((CMolAtom *)_singleMol->m_oaMolAtoms[j / 3])->m_iType]])->m_pElement->m_fMass); for(k = 0; k < 3; k++) { fprintf(nmdFile, " %f", transMatrix->GetAt(sortIndex->GetAt(i) * 3*_atomCount + j + k) / mass); } } fprintf(nmdFile, "\n"); } fclose(nmdFile); // if(_calcIR) { // mprintf(" Calculating dipole auto correlation...\n"); // CxFloatArray *dipoleAC; // try { dipoleAC = new CxFloatArray(); } catch(...) { dipoleAC = NULL; } // if(dipoleAC == NULL) NewException((double)sizeof(CxFloatArray), __FILE__, __LINE__, __PRETTY_FUNCTION__); // dipoleAC->SetSize(_correlationDepth); // for(int i = 0; i < _correlationDepth; i++) // dipoleAC->GetAt(i) = 0.0f; // // CxFloatArray *tmp; // try { tmp = new CxFloatArray(); } catch(...) { tmp = NULL; } // if(tmp == NULL) NewException((double)sizeof(CxFloatArray), __FILE__, __LINE__, __PRETTY_FUNCTION__); // tmp->SetSize(_numSteps-2); // CxFloatArray *tmp2; // try { tmp2 = new CxFloatArray(); } catch(...) { tmp2 = NULL; } // if(tmp2 == NULL) NewException((double)sizeof(CxFloatArray), __FILE__, __LINE__, __PRETTY_FUNCTION__); // tmp2->SetSize(_numSteps-2); // CxFloatArray *tmp3; // try { tmp3 = new CxFloatArray(); } catch(...) { tmp3 = NULL; } // if(tmp3 == NULL) NewException((double)sizeof(CxFloatArray), __FILE__, __LINE__, __PRETTY_FUNCTION__); // tmp3->SetSize(_correlationDepth); // // // FILE *testFile = fopen("test.dat", "w"); // // for(int i = 0; i < _numSteps - 2; i++) { // // fprintf(testFile, "%d %f %f %f\n", i, ((CxDVec3Array *)_dipoleDerivativeCache[0])->GetAt(i)[0], ((CxDVec3Array *)_dipoleDerivativeCache[0])->GetAt(i)[1], ((CxDVec3Array *)_dipoleDerivativeCache[0])->GetAt(i)[2]); // // } // // fclose(testFile); // // mprintf(WHITE, " ["); // double step = (double)(_showMolCount * _permutationCount * 3) / 20.0f; // int c = 0; // for(int i = 0; i < _showMolCount; i++) { // for(int j = 0; j < _permutationCount; j++) { // for(int k = 0; k < 3; k++) { // if(fmod((double)c++, step) < 1.0f) // mprintf(WHITE, "#"); // for(int l = 0; l < _numSteps - 2; l++) { // tmp->GetAt(l) = ((CxFloatArray *)_globalProb[i])->GetAt(l+1) * (double)(exp(-(double)((CxFloatArray *)_distanceTimedev[i*_permutationCount + j])->GetAt(l+1) * (double)((CxFloatArray *)_distanceTimedev[i*_permutationCount + j])->GetAt(l+1) / 2.0 / (double)_gaussianWidth / (double)_gaussianWidth) / probSum[i*_numSteps + l+1]) * ((CxDVec3Array *)_dipoleDerivativeCache[i*_permutationCount + j])->GetAt(l)[k]; // tmp2->GetAt(l) = ((CxDVec3Array *)_dipoleDerivativeCache[i*_permutationCount + j])->GetAt(l)[k]; // } // cc->CrossCorrelate(tmp, tmp2, tmp3); // for(int l = 0; l < _correlationDepth; l++) { // dipoleAC->GetAt(l) += tmp3->GetAt(l); // } // } // } // } // mprintf(WHITE, "]\n"); // for(int i = 0; i < _correlationDepth; i++) { // dipoleAC->GetAt(i) /= _showMolCount; // } // // mprintf(" Fourier transforming dipole auto correlation...\n"); // CFFT *fft; // try { fft = new CFFT(); } catch(...) { fft = NULL; } // if(fft == NULL) NewException((double)sizeof(CFFT), __FILE__, __LINE__, __PRETTY_FUNCTION__); // CxFloatArray *tmp4; // try { tmp4 = new CxFloatArray(); } catch(...) { tmp4 = NULL; } // if(tmp4 == NULL) NewException((double)sizeof(CxFloatArray), __FILE__, __LINE__, __PRETTY_FUNCTION__); // // mprintf(WHITE, " ["); // tmp4->CopyFrom(dipoleAC); // if(_applyWindowFunction) { // for(int i = 0; i < tmp4->GetSize(); i++) { // tmp4->GetAt(i) *= pow(cos((double)i / tmp4->GetSize() / 2.0 * Pi), 2.0); // } // } // if(_zeroPadding > 0) { // for(int i = 0; i < _zeroPadding; i++) { // tmp4->Add(0.0f); // } // } // if(_applyMirroring) { // int oldSize = tmp4->GetSize(); // tmp4->SetSize(2 * oldSize); // for(int i = 1; i < oldSize; i++) { // tmp4->GetAt(oldSize + i) = tmp4->GetAt(oldSize - i); // } // } // fft->PrepareFFT_C2C(tmp4->GetSize()); // for(int i = 0; i < tmp4->GetSize(); i++) { // fft->m_pInput[2*i] = tmp4->GetAt(i); // fft->m_pInput[2*i+1] = 0.0f; // } // fft->DoFFT(); // dipoleAC->SetSize(_specSize); // for(int i = 0; i < _specSize; i++) { // dipoleAC->GetAt(i) = fft->m_pOutput[2*i] * 1523615.0f; // } // mprintf(WHITE, "#]\n"); // // mprintf(" Saving infrared spectrum...\n"); // snprintf(name, BUF_SIZE, "%s_ir.dat", basename); // FILE *irFile = OpenFileWrite(name, false); // for(int i = 0; i < _specSize; i++) { // fprintf(irFile, "%10.4f %20.8f\n", _specResolution*i, dipoleAC->GetAt(i)); // } // fclose(irFile); // // mprintf(" Calculating linear least-squares fit...\n"); // CxFloatArray *diagonalCoefficients; // try { diagonalCoefficients = new CxFloatArray(); } catch(...) { diagonalCoefficients = NULL; } // if(diagonalCoefficients == NULL) NewException((double)sizeof(CxFloatArray), __FILE__, __LINE__, __PRETTY_FUNCTION__); // diagonalCoefficients->SetSize(3*_atomCount); // CxFloatArray *xMatrix; // try { xMatrix = new CxFloatArray(); } catch(...) { xMatrix = NULL; } // if(xMatrix == NULL) NewException((double)sizeof(CxFloatArray), __FILE__, __LINE__, __PRETTY_FUNCTION__); // xMatrix->SetSize(3*_atomCount * _specSize); // CxFloatArray *qtMatrix; // try { qtMatrix = new CxFloatArray(); } catch(...) { qtMatrix = NULL; } // if(qtMatrix == NULL) NewException((double)sizeof(CxFloatArray), __FILE__, __LINE__, __PRETTY_FUNCTION__); // qtMatrix->SetSize(3*_atomCount * _specSize); // CxFloatArray *rMatrix; // try { rMatrix = new CxFloatArray(); } catch(...) { rMatrix = NULL; } // if(rMatrix == NULL) NewException((double)sizeof(CxFloatArray), __FILE__, __LINE__, __PRETTY_FUNCTION__); // rMatrix->SetSize(3*_atomCount * _specSize); // CxFloatArray *qyVector; // try { qyVector = new CxFloatArray(); } catch(...) { qyVector = NULL; } // if(qyVector == NULL) NewException((double)sizeof(CxFloatArray), __FILE__, __LINE__, __PRETTY_FUNCTION__); // qyVector->SetSize(3*_atomCount); // // for(int i = 0; i < 3*_atomCount; i++) { // for(int j = 0; j < _specSize; j++) { // xMatrix->GetAt(j * 3*_atomCount + i) = ((CxFloatArray *)ccMatrix[(3*_atomCount-1)*sortIndex->GetAt(i) - sortIndex->GetAt(i)*(sortIndex->GetAt(i)-1)/2 + sortIndex->GetAt(i)])->GetAt(j); // } // } // // qrDecompose(_specSize, 3*_atomCount, xMatrix, qtMatrix, rMatrix); // // for(int i = 0; i < 3*_atomCount; i++) { // qyVector->GetAt(i) = 0.0f; // for(int j = 0; j < _specSize; j++) { // qyVector->GetAt(i) += qtMatrix->GetAt(i * _specSize + j) * dipoleAC->GetAt(j); // } // } // for(int i = 3*_atomCount - 1; i >= 0; i--) { // diagonalCoefficients->GetAt(i) = qyVector->GetAt(i); // for(int j = i+1; j < 3*_atomCount; j++) { // diagonalCoefficients->GetAt(i) -= diagonalCoefficients->GetAt(j) * rMatrix->GetAt(i * 3*_atomCount + j); // } // diagonalCoefficients->GetAt(i) /= rMatrix->GetAt(i * 3*_atomCount + i); // } // // mprintf("\n -------------------------\n"); // mprintf(" Mode Intensity (km/mol)\n"); // mprintf(" -------------------------\n"); // for(int i = 0; i < 6; i++) { // mprintf(" %4d %20.6g\n", i+1, diagonalCoefficients->GetAt(i) / 1000.0f); // } // mprintf(" -------------------------\n"); // for(int i = 6; i < 3*_atomCount; i++) { // mprintf(" %4d %20.6g\n", i+1, diagonalCoefficients->GetAt(i) / 1000.0f); // } // mprintf(" -------------------------\n\n"); // // mprintf(" Saving reconstructed infrared spectrum...\n"); // CxFloatArray *irSpec; // try { irSpec = new CxFloatArray(); } catch(...) { irSpec = NULL; } // if(irSpec == NULL) NewException((double)sizeof(CxFloatArray), __FILE__, __LINE__, __PRETTY_FUNCTION__); // irSpec->SetSize(_specSize); // for(int i = 0; i < _specSize; i++) // irSpec->GetAt(i) = 0.0f; // for(int i = 0; i < 3*_atomCount; i++) { // for(int j = 0; j < _specSize; j++) { // irSpec->GetAt(j) += diagonalCoefficients->GetAt(i) * ((CxFloatArray *)ccMatrix[(3*_atomCount-1)*sortIndex->GetAt(i) - sortIndex->GetAt(i)*(sortIndex->GetAt(i)-1)/2 + sortIndex->GetAt(i)])->GetAt(j); // } // } // snprintf(name, BUF_SIZE, "%s_ir_fit_diagonal.dat", basename); // irFile = OpenFileWrite(name, false); // for(int i = 0; i < _specSize; i++) { // fprintf(irFile, "%10.4f %20.8f\n", _specResolution*i, irSpec->GetAt(i)); // } // fclose(irFile); // // delete dipoleAC; // // mprintf(" Calculating dipole-velocity cross correlations...\n"); // CxObArray cdMatrix; // for(int i = 0; i < 3 * 3*_atomCount; i++) { // CxFloatArray *a; // try { a = new CxFloatArray(); } catch(...) { a = NULL; } // if(a == NULL) NewException((double)sizeof(CxFloatArray), __FILE__, __LINE__, __PRETTY_FUNCTION__); // a->SetSize(_correlationDepth); // for(int j = 0; j < _correlationDepth; j++) { // a->GetAt(j) = 0.0f; // } // cdMatrix.Add(a); // } // // mprintf(WHITE, " ["); // step = (double)(_showMolCount * _permutationCount * 3 * 3*_atomCount) / 20.0f; // c = 0; // for(int i = 0; i < _showMolCount; i++) { // for(int j = 0; j < _permutationCount; j++) { // for(int k = 0; k < _atomCount; k++) { // for(int l = 0; l < 3; l++) { // for(int m = 0; m < 3; m++) { // if(fmod((double)c++, step) < 1.0f) // mprintf(WHITE, "#"); // for(int n = 0; n < _numSteps - 2; n++) { // tmp->GetAt(n) = ((CxFloatArray *)_globalProb[i])->GetAt(n+1) * (double)(exp(-(double)((CxFloatArray *)_distanceTimedev[i*_permutationCount + j])->GetAt(n+1) * (double)((CxFloatArray *)_distanceTimedev[i*_permutationCount + j])->GetAt(n+1) / 2.0 / (double)_gaussianWidth / (double)_gaussianWidth) / probSum[i*_numSteps + n+1]) * ((CxDVec3Array *)_dipoleDerivativeCache[i*_permutationCount + j])->GetAt(n)[m]; // tmp2->GetAt(n) = ((CxDVec3Array *)_velocityCache[i*_permutationCount*_atomCount + j*_atomCount + k])->GetAt(n)[l] * sqrtf(_weights[k]); // } // cc->CrossCorrelate(tmp, tmp2, tmp3); // for(int n = 0; n < _correlationDepth; n++) { // ((CxFloatArray *)cdMatrix[m * 3*_atomCount + 3 * k + l])->GetAt(n) += tmp3->GetAt(n); // } // } // } // } // } // } // mprintf(WHITE, "]\n"); // for(int i = 0; i < 3*_atomCount; i++) { // for(int j = 0; j < 3; j++) { // for(int k = 0; k < _correlationDepth; k++) { // ((CxFloatArray *)cdMatrix[j * 3*_atomCount + i])->GetAt(k) /= _showMolCount; // } // } // } // // mprintf(" Fourier transforming dipole-velocity cross correlations...\n"); // mprintf(WHITE, " ["); // step = (double)(3 * 3*_atomCount) / 20.0f; // c = 0; // for(int i = 0; i < 3*_atomCount; i++) { // for(int j = 0; j < 3; j++) { // if(fmod((double)c++, step) < 1.0f) // mprintf(WHITE, "#"); // tmp4->CopyFrom((CxFloatArray *)cdMatrix[j * 3*_atomCount + i]); // if(_applyWindowFunction) { // for(int k = 0; k < tmp4->GetSize(); k++) { // tmp4->GetAt(k) *= pow(cos((double)k / tmp4->GetSize() / 2.0 * Pi), 2.0); // } // } // if(_zeroPadding > 0) { // for(int k = 0; k < _zeroPadding; k++) { // tmp4->Add(0.0f); // } // } // if(_applyMirroring) { // int oldSize = tmp4->GetSize(); // tmp4->SetSize(2 * oldSize); // for(int k = 1; k < oldSize; k++) { // tmp4->GetAt(oldSize + k) = tmp4->GetAt(oldSize - k); // } // } // fft->PrepareFFT_C2C(tmp4->GetSize()); // for(int k = 0; k < tmp4->GetSize(); k++) { // fft->m_pInput[2*k] = tmp4->GetAt(k); // fft->m_pInput[2*k+1] = 0.0f; // } // fft->DoFFT(); // ((CxFloatArray *)cdMatrix[j * 3*_atomCount + i])->SetSize(_specSize); // for(int k = 0; k < _specSize; k++) { // ((CxFloatArray *)cdMatrix[j * 3*_atomCount + i])->GetAt(k) = fft->m_pOutput[2*k]; // } // } // } // mprintf(WHITE, "]\n"); // // FILE *testFile = fopen("test.dat", "w"); // for(int i = 0; i < _specSize; i++) { // fprintf(testFile, "%10.4f", _specResolution * i); // for(int j = 0; j < 3*_atomCount; j++) { // fprintf(testFile, " %20.8f", ((CxFloatArray *)cdMatrix[j])->GetAt(i)); // } // fprintf(testFile, "\n"); // } // fclose(testFile); // // delete fft; // // CxObArray cdtMatrix; // for(int i = 0; i < 3 * 3*_atomCount; i++) { // CxFloatArray *a; // try { a = new CxFloatArray(); } catch(...) { a = NULL; } // if(a == NULL) NewException((double)sizeof(CxFloatArray), __FILE__, __LINE__, __PRETTY_FUNCTION__); // a->SetSize(_correlationDepth); // for(int j = 0; j < _correlationDepth; j++) { // a->GetAt(j) = 0.0f; // } // cdtMatrix.Add(a); // } // for(int i = 0; i < 3; i++) { // for(int j = 0; j < 3*_atomCount; j++) { // for(int k = 0; k < 3*_atomCount; k++) { // for(int l = 0; l < _specSize; l++) { // // ((CxFloatArray *)cdtMatrix[i * 3*_atomCount + j])->GetAt(l) += ((CxFloatArray *)cdMatrix[i * 3*_atomCount + k])->GetAt(l) * transMatrix->GetAt(sortIndex->GetAt(j) * 3*_atomCount + k); // ((CxFloatArray *)cdtMatrix[i * 3*_atomCount + j])->GetAt(l) += ((CxFloatArray *)cdMatrix[i * 3*_atomCount + k])->GetAt(l) * transMatrix->GetAt(j * 3*_atomCount + k); // } // } // } // } // // FILE *test2File = fopen("test2.dat", "w"); // for(int i = 0; i < _specSize; i++) { // fprintf(test2File, "%10.4f", _specResolution * i); // for(int j = 0; j < 3*_atomCount; j++) { // fprintf(test2File, " %20.8f", ((CxFloatArray *)cdtMatrix[3*_atomCount + j])->GetAt(i)); // } // fprintf(test2File, "\n"); // } // fclose(test2File); // // mprintf(" Calculating linear least-squares fit...\n"); // CxFloatArray *coefficientMatrix; // try { coefficientMatrix = new CxFloatArray(); } catch(...) { coefficientMatrix = NULL; } // if(coefficientMatrix == NULL) NewException((double)sizeof(CxFloatArray), __FILE__, __LINE__, __PRETTY_FUNCTION__); // coefficientMatrix->SetSize(3 * 3*_atomCount); // xMatrix->SetSize(3*_atomCount * 3*_atomCount * _specSize); // qtMatrix->SetSize(3*_atomCount * 3*_atomCount * _specSize); // rMatrix->SetSize(3*_atomCount * 3*_atomCount * _specSize); // qyVector->SetSize(3*_atomCount); // // for(int i = 0; i < 3*_atomCount; i++) { // for(int j = 0; j < _specSize; j++) { // for(int k = 0; k < 3*_atomCount; k++) { // if(i <= k) // xMatrix->GetAt((i*_specSize + j) * 3*_atomCount + k) = ((CxFloatArray *)ccMatrix[(3*_atomCount-1)*i - i*(i-1)/2 + k])->GetAt(j); // // xMatrix->GetAt((i*_specSize + j) * 3*_atomCount + k) = ((CxFloatArray *)ccMatrix[(3*_atomCount-1)*sortIndex->GetAt(i) - sortIndex->GetAt(i)*(sortIndex->GetAt(i)-1)/2 + sortIndex->GetAt(k)])->GetAt(j); // else // xMatrix->GetAt((i*_specSize + j) * 3*_atomCount + k) = ((CxFloatArray *)ccMatrix[(3*_atomCount-1)*k - k*(k-1)/2 + i])->GetAt(j); // // xMatrix->GetAt((i*_specSize + j) * 3*_atomCount + k) = ((CxFloatArray *)ccMatrix[(3*_atomCount-1)*sortIndex->GetAt(k) - sortIndex->GetAt(k)*(sortIndex->GetAt(k)-1)/2 + sortIndex->GetAt(i)])->GetAt(j); // } // } // } // // qrDecompose(3*_atomCount * _specSize, 3*_atomCount, xMatrix, qtMatrix, rMatrix); // // // FILE *testFile = fopen("test.dat", "w"); // // for(int i = 0; i < 3*_atomCount; i++) { // // for(int j = 0; j < 3*_atomCount; j++) { // // fprintf(testFile, " %f", xMatrix->GetAt(i * 3*_atomCount * _specSize + j)); // // } // // fprintf(testFile, "\n"); // // } // // fclose(testFile); // // for(int i = 0; i < 3; i++) { // for(int j = 0; j < 3*_atomCount; j++) { // qyVector->GetAt(j) = 0.0f; // for(int k = 0; k < 3*_atomCount; k++) { // for(int l = 0; l < _specSize; l++) { // qyVector->GetAt(j) += qtMatrix->GetAt(j * 3*_atomCount * _specSize + k * _specSize + l) * ((CxFloatArray *)cdtMatrix[i * 3*_atomCount + k])->GetAt(l); // } // } // } // for(int j = 3*_atomCount - 1; j >= 0; j--) { // coefficientMatrix->GetAt(i * 3*_atomCount + j) = qyVector->GetAt(j); // for(int k = j+1; k < 3*_atomCount; k++) { // coefficientMatrix->GetAt(i * 3*_atomCount + j) -= coefficientMatrix->GetAt(i * 3*_atomCount + k) * rMatrix->GetAt(j * 3*_atomCount + k); // } // coefficientMatrix->GetAt(i * 3*_atomCount + j) /= rMatrix->GetAt(j * 3*_atomCount + j); // } // } // // delete xMatrix; // delete qtMatrix; // delete rMatrix; // delete qyVector; // // mprintf(" Saving reconstructed infrared spectrum...\n"); // irSpec->SetSize(_specSize); // for(int i = 0; i < _specSize; i++) // irSpec->GetAt(i) = 0.0f; // for(int i = 0; i < 3; i++) { // for(int j = 0; j < 3*_atomCount; j++) { // for(int k = 0; k < 3*_atomCount; k++) { // for(int l = 0; l < _specSize; l++) { // if(j <= k) // irSpec->GetAt(l) += coefficientMatrix->GetAt(i * 3*_atomCount + j) * coefficientMatrix->GetAt(i * 3*_atomCount + k) * ((CxFloatArray *)ccMatrix[(3*_atomCount-1)*j - j*(j-1)/2 + k])->GetAt(l); // // irSpec->GetAt(l) += coefficientMatrix->GetAt(i * 3*_atomCount + j) * coefficientMatrix->GetAt(i * 3*_atomCount + k) * ((CxFloatArray *)ccMatrix[(3*_atomCount-1)*sortIndex->GetAt(j) - sortIndex->GetAt(j)*(sortIndex->GetAt(j)-1)/2 + sortIndex->GetAt(k)])->GetAt(l); // else // irSpec->GetAt(l) += coefficientMatrix->GetAt(i * 3*_atomCount + j) * coefficientMatrix->GetAt(i * 3*_atomCount + k) * ((CxFloatArray *)ccMatrix[(3*_atomCount-1)*j - j*(j-1)/2 + k])->GetAt(l); // // irSpec->GetAt(l) += coefficientMatrix->GetAt(i * 3*_atomCount + j) * coefficientMatrix->GetAt(i * 3*_atomCount + k) * ((CxFloatArray *)ccMatrix[(3*_atomCount-1)*sortIndex->GetAt(j) - sortIndex->GetAt(j)*(sortIndex->GetAt(j)-1)/2 + sortIndex->GetAt(k)])->GetAt(l); // } // } // } // } // snprintf(name, BUF_SIZE, "%s_ir_fit_linear.dat", basename); // irFile = OpenFileWrite(name, false); // for(int i = 0; i < _specSize; i++) { // fprintf(irFile, "%10.4f %20.8f\n", _specResolution*i, irSpec->GetAt(i)); // } // fclose(irFile); // // delete irSpec; // // // delete temp; // // delete temp2; // // delete temp3; // } delete cc; delete integrals; delete centers; delete sortIndex; } bool CReferenceStructure::recognizeMolecule(CTimeStep *ts, int showMol, const char *basename) { int i, j; bool ok = true; unsigned int *stack; try { stack = new unsigned int[ts->m_iGesAtomCount]; } catch(...) { stack = NULL; } if(stack == NULL) NewException((double)ts->m_iGesAtomCount*sizeof(int), __FILE__, __LINE__, __PRETTY_FUNCTION__); bool *used; try { used = new bool[ts->m_iGesAtomCount]; } catch(...) { used = NULL; } if(used == NULL) NewException((double)ts->m_iGesAtomCount*sizeof(int), __FILE__, __LINE__, __PRETTY_FUNCTION__); for(i = 0; (unsigned int)i < ts->m_iGesAtomCount; i++) { used[i] = false; } CxByteArray baAtomIndex; baAtomIndex.SetSize(ts->m_iGesAtomCount); for(i = 0; (unsigned int)i < ts->m_iGesAtomCount; i++) { // char buf[64]; CxString buf; // strncpy(buf, (char *)(ts->m_paLabels[i]), 64); // buf[63] = 0; buf.strcpy((char *)(ts->m_paLabels[i])); ReplaceDigits(&buf); baAtomIndex[i] = 255; for(j = 0; j < g_oaAtoms.GetSize(); j++) { if(mystricmp(buf, ((CAtom *)g_oaAtoms[j])->m_sName) == 0) { CAtom *a = (CAtom *)g_oaAtoms[j]; while(a->m_pMergedTo != NULL) a = a->m_pMergedTo; baAtomIndex[i] = (unsigned char)a->m_iIndex; break; } } if(baAtomIndex[i] == 255) { mprintf(RED, "Atom type \"%s\" not known\n", (const char*)buf); ok = false; } } if(ok) { recognizeMoleculeRecursion(0, used, 0, stack, ts, baAtomIndex); for(i = 0; (unsigned int)i < ts->m_iGesAtomCount; i++) { if(!used[i]) { mprintf(RED, "Some atoms are not connected to the molecule\n"); ok = false; break; } } } if(ok) { mprintf(" Recognized one molecule\n"); mprintf(" Sorting atom types...\n"); for(i = 0; i < _singleMol->m_baAtomIndex.GetSize() - 1; i++) { int a = -1; int b = 999; for(j = i; j < _singleMol->m_baAtomIndex.GetSize(); j++) { if(_singleMol->m_baAtomIndex[j] < b) { b = _singleMol->m_baAtomIndex[j]; a = j; } } if((a != -1) && (a != i)) { b = _singleMol->m_baAtomIndex[a]; _singleMol->m_baAtomIndex[a] = _singleMol->m_baAtomIndex[i]; _singleMol->m_baAtomIndex[i] = (unsigned char)b; for(j = 0; j < _singleMol->m_oaMolAtoms.GetSize(); j++) { if(((CMolAtom *)_singleMol->m_oaMolAtoms[j])->m_iType == i) ((CMolAtom *)_singleMol->m_oaMolAtoms[j])->m_iType = a; else if(((CMolAtom *)_singleMol->m_oaMolAtoms[j])->m_iType == a) ((CMolAtom *)_singleMol->m_oaMolAtoms[j])->m_iType = i; } } } mprintf(" Setting up bond list...\n"); for(i = 0; i < _singleMol->m_laBonds.GetSize() / 2; i++) { int a = _singleMol->m_laBonds[2*i]; int b = _singleMol->m_laBonds[2*i+1]; int c = -1; for(j = 0; j < _singleMol->m_oaMolAtoms.GetSize(); j++) { if(((CMolAtom *)_singleMol->m_oaMolAtoms[j])->m_iOffset == a) { c = j; break; } } if(c == -1) { eprintf("CReferenceStructure::recognizeMolecule(): Internal error.\n"); abort(); } int d = -1; for(j = 0; j < _singleMol->m_oaMolAtoms.GetSize(); j++) { if(((CMolAtom *)_singleMol->m_oaMolAtoms[j])->m_iOffset == b) { d = j; break; } } if(d == -1) { eprintf("CReferenceStructure::recognizeMolecule(): Internal error.\n"); abort(); } ((CMolAtom *)_singleMol->m_oaMolAtoms[c])->m_oaBonds.Add((CMolAtom *)_singleMol->m_oaMolAtoms[d]); ((CMolAtom *)_singleMol->m_oaMolAtoms[d])->m_oaBonds.Add((CMolAtom *)_singleMol->m_oaMolAtoms[c]); } mprintf(" Building atom codes...\n"); _singleMol->BuildAtomCodes(); mprintf(" Creating topological atom order...\n"); for(i = 0; i < _singleMol->m_baAtomIndex.GetSize(); i++) { CxIntArray *a; try { a = new CxIntArray(); } catch(...) { a = NULL; } if(a == NULL) NewException((double)sizeof(CxIntArray), __FILE__, __LINE__, __PRETTY_FUNCTION__); _singleMol->m_oaAtomOffset.Add(a); for(j = 0; j < _singleMol->m_oaMolAtoms.GetSize(); j++) { if(((CMolAtom *)_singleMol->m_oaMolAtoms[j])->m_iType == i) { ((CMolAtom *)_singleMol->m_oaMolAtoms[j])->m_iNumber = a->GetSize(); a->Add(((CMolAtom *)_singleMol->m_oaMolAtoms[j])->m_iOffset); } } } // mprintf(" Creating bond list...\n"); // mprintf(" Creating angle list...\n"); mprintf(" Comparing to global molecule type...\n"); bool diff = false; CSingleMolecule *compMol = (CSingleMolecule *)g_oaSingleMolecules[((CMolecule *)g_oaMolecules[showMol])->m_laSingleMolIndex[0]]; if(_singleMol->m_oaMolAtoms.GetSize() != compMol->m_oaMolAtoms.GetSize()) { diff = true; } else { for(i = 0; i < _singleMol->m_oaMolAtoms.GetSize(); i++) { // mprintf(RED, "%f %f\n", ((CMolAtom *)_singleMol->m_oaMolAtoms[i])->m_fAtomCode, ((CMolAtom *)compMol->m_oaMolAtoms[i])->m_fAtomCode); if(((CMolAtom *)_singleMol->m_oaMolAtoms[i])->m_liAtomCode != ((CMolAtom *)compMol->m_oaMolAtoms[i])->m_liAtomCode) { diff = true; break; } } } if(!diff) { _singleMol->m_iMolType = showMol; mprintf(" The reference structure belongs to molecule type %d (%s)\n", _singleMol->m_iMolType+1, ((CMolecule *)g_oaMolecules[_singleMol->m_iMolType])->m_sName); _atomCount = _singleMol->m_oaMolAtoms.GetSize(); } else { ok = false; mprintf(RED, "The reference structure does not belong to molecule type %d (%s)\n", _singleMol->m_iMolType+1, ((CMolecule *)g_oaMolecules[_singleMol->m_iMolType])->m_sName); } // mprintf(" Refining ring systems...\n"); } mprintf("\n"); if(ok) { mprintf(" Looking for equivalent atoms...\n"); CxIntArray permutationActions; askPermutations(&permutationActions); mprintf("\n Creating permutations of equivalent atoms...\n"); CxIntArray *nullPerm; try { nullPerm = new CxIntArray(); } catch(...) { nullPerm = NULL; } if(nullPerm == NULL) NewException((double)sizeof(CxIntArray), __FILE__, __LINE__, __PRETTY_FUNCTION__); createPermutationsRecursion(0, nullPerm, &permutationActions); _permutationCount = _permutations.GetSize(); for(i = 0; i < _permutationCount; i++) { CxDVec3Array *centroidCoord; try { centroidCoord = new CxDVec3Array(); } catch(...) { centroidCoord = NULL; } if(centroidCoord == NULL) NewException((double)sizeof(CxDVec3Array), __FILE__, __LINE__, __PRETTY_FUNCTION__); for(j = 0; j < _atomCount; j++) { centroidCoord->Add(_refTimestep->m_vaCoords[((CMolAtom *)_singleMol->m_oaMolAtoms[((CxIntArray *)_permutations[i])->GetAt(j)])->m_iOffset]); } _centroidCoords.Add(centroidCoord); } mprintf(" Created %d permutations\n", _permutationCount); for(i = 0; i < _permutationCount; i++) { mprintf(" %d: ", i+1); for(j = 0; j < _atomCount; j++) { mprintf(" %d", ((CxIntArray *)_permutations[i])->GetAt(j)+1); } mprintf("\n"); } mprintf("\n"); if(g_bAdvanced2) { if(AskYesNo(" Save xyz files for all permutations (y/n)? [no] ", false)) { for(i = 0; i < _centroidCoords.GetSize(); i++) { char name[BUF_SIZE]; #ifdef TARGET_LINUX snprintf(name, BUF_SIZE, "%s_p%d_reference.xyz", basename, i+1); #else sprintf(name, "%s_p%d_reference.xyz", basename, i+1); #endif FILE *permutationFile = OpenFileWrite(name, false); fprintf(permutationFile, "%d\n\n", _singleMol->m_oaMolAtoms.GetSize()); for(j = 0; j < _singleMol->m_oaMolAtoms.GetSize(); j++) { fprintf(permutationFile, "%s %f %f %f\n", (const char*)((CAtom *)g_oaAtoms[_singleMol->m_baAtomIndex[((CMolAtom *)_singleMol->m_oaMolAtoms[j])->m_iType]])->m_sName, ((CxDVec3Array *)_centroidCoords[i])->GetAt(j)[0] / 100.0, ((CxDVec3Array *)_centroidCoords[i])->GetAt(j)[1] / 100.0, ((CxDVec3Array *)_centroidCoords[i])->GetAt(j)[2] / 100.0); } fclose(permutationFile); } } mprintf("\n"); } _weightSum = 0.0; _weights.SetSize(_singleMol->m_oaMolAtoms.GetSize()); _centroid = CxDVector3(0.0, 0.0, 0.0); for(i = 0; i < _singleMol->m_oaMolAtoms.GetSize(); i++) { _weights[i] = ((CAtom *)g_oaAtoms[_singleMol->m_baAtomIndex[((CMolAtom *)_singleMol->m_oaMolAtoms[i])->m_iType]])->m_pElement->m_fMass; _centroid += ((CxDVec3Array *)_centroidCoords[0])->GetAt(i) * _weights[i]; _weightSum += _weights[i]; } _centroid /= _weightSum; for(i = 0; i < _centroidCoords.GetSize(); i++) { for(j = 0; j < _singleMol->m_oaMolAtoms.GetSize(); j++) { ((CxDVec3Array *)_centroidCoords[i])->GetAt(j) -= _centroid; } } } delete[] used; delete[] stack; return ok; } void CReferenceStructure::recognizeMoleculeRecursion(unsigned int index, bool *used, int depth, unsigned int *stack, CTimeStep *ts, CxByteArray &baAtomIndex) { int i, j; if(g_bVerbose) { mprintf(" "); for(i = 1; i < depth; i++) mprintf(" "); if(depth > 0) mprintf(WHITE, "\\--"); mprintf(CYAN, "%s", (const char*)((CAtom *)g_oaAtoms[baAtomIndex[index]])->m_sName); mprintf("(%d)", index+1); } stack[depth] = index; used[index] = true; bool found = false; for(i = 0; i < _singleMol->m_baAtomIndex.GetSize(); i++) { if(_singleMol->m_baAtomIndex[i] == baAtomIndex[index]) { CMolAtom *molAtom; try { molAtom = new CMolAtom(); } catch(...) { molAtom = NULL; } if(molAtom == NULL) NewException((double)sizeof(CMolAtom), __FILE__, __LINE__, __PRETTY_FUNCTION__); molAtom->m_iOffset = index; molAtom->m_iType = i; _singleMol->m_oaMolAtoms.Add(molAtom); found = true; break; } } if(!found) { CMolAtom *molAtom; try { molAtom = new CMolAtom(); } catch(...) { molAtom = NULL; } if(molAtom == NULL) NewException((double)sizeof(CMolAtom), __FILE__, __LINE__, __PRETTY_FUNCTION__); molAtom->m_iOffset = index; molAtom->m_iType = _singleMol->m_baAtomIndex.GetSize(); _singleMol->m_oaMolAtoms.Add(molAtom); _singleMol->m_baAtomIndex.Add(baAtomIndex[index]); } int numNeighbors = 0; int neighborList[MAX_BONDS]; for(i = 0; (unsigned int)i < ts->m_iGesAtomCount; i++) { if((unsigned int)i == index) continue; if(((CAtom *)g_oaAtoms[baAtomIndex[index]])->m_bExclude) continue; double distance; if(recognizeMoleculeBondRange(ts, index, i, &distance, baAtomIndex)) { if(used[i]) { if((depth > 0) && ((unsigned int)i != stack[depth-1])) { if(_singleMol->m_oaRings.GetSize() < 100) { if(g_bVerbose) { mprintf(GREEN, " <-- Ring closure: "); mprintf("%s(%d)", (const char*)((CAtom *)g_oaAtoms[baAtomIndex[stack[depth]]])->m_sName, stack[depth]+1); } CxIntArray *ring; try { ring = new CxIntArray(); } catch(...) { ring = NULL; } if(ring == NULL) NewException((double)sizeof(CxIntArray), __FILE__, __LINE__, __PRETTY_FUNCTION__); _singleMol->m_oaRings.Add(ring); ring->Add(stack[depth]); for(j = depth - 1; (stack[j] != (unsigned int)i) && (j >= 0); j--) { ring->Add(stack[j]); if(g_bVerbose) mprintf(" - %s(%d)", (const char*)((CAtom *)g_oaAtoms[baAtomIndex[stack[j]]])->m_sName, stack[j]+1); } ring->Add(i); if(g_bVerbose) mprintf(" - %s(%d)", (const char*)((CAtom *)g_oaAtoms[baAtomIndex[i]])->m_sName, i+1); } else { mprintf(RED, "More than 100 rings\n"); } } continue; } if(distance < 50.0) { mprintf(RED, "Atoms %s(%d) and %s(%d) are very close to each other: %.4f pm\n", (const char*)((CAtom *)g_oaAtoms[baAtomIndex[index]])->m_sName, index + 1, (const char*)((CAtom *)g_oaAtoms[baAtomIndex[i]])->m_sName, i + 1, distance); } neighborList[numNeighbors++] = i; if(numNeighbors >= MAX_BONDS) { mprintf(RED, "Atom %s(%d) has more than %d bonds\n", (const char*)((CAtom *)g_oaAtoms[baAtomIndex[index]])->m_sName, index + 1, MAX_BONDS); break; } } } if(g_bVerbose) mprintf("\n"); for(i = 0; i < numNeighbors; i++) { _singleMol->m_laBonds.Add(index); _singleMol->m_laBonds.Add(neighborList[i]); if(!used[neighborList[i]]) { recognizeMoleculeRecursion(neighborList[i], used, depth+1, stack, ts, baAtomIndex); } } } bool CReferenceStructure::recognizeMoleculeBondRange(CTimeStep *ts, int i1, int i2, double *distance, CxByteArray &baAtomIndex) { /* double x = ts->m_vaCoords[i1][0] - ts->m_vaCoords[i2][0]; double y = ts->m_vaCoords[i1][1] - ts->m_vaCoords[i2][1]; double z = ts->m_vaCoords[i1][2] - ts->m_vaCoords[i2][2]; if(g_bPeriodic) { if(g_bPeriodicX) { while(x < -g_fBoxX/2) x += g_fBoxX; while(x > g_fBoxX/2) x -= g_fBoxX; } if(g_bPeriodicY) { while(y < -g_fBoxY/2) y += g_fBoxY; while(y > g_fBoxY/2) y -= g_fBoxY; } if(g_bPeriodicZ) { while(z < -g_fBoxZ/2) z += g_fBoxZ; while(z > g_fBoxZ/2) z -= g_fBoxZ; } } *distance = sqrt(x*x + y*y + z*z);*/ CxDVector3 v; v = FoldVector( ts->m_vaCoords[i2] - ts->m_vaCoords[i1]); *distance = v.GetLength(); return *distance < (((CAtom *)g_oaAtoms[baAtomIndex[i1]])->m_pElement->m_fRadius + ((CAtom *)g_oaAtoms[baAtomIndex[i2]])->m_pElement->m_fRadius) * g_fBondFactor; } void CReferenceStructure::askPermutations(CxIntArray *actions) { int i; int a1 = 0; while(a1 < _singleMol->m_oaMolAtoms.GetSize()) { int a2 = a1; while((a2 < _singleMol->m_oaMolAtoms.GetSize()) && (((CMolAtom *)_singleMol->m_oaMolAtoms[a2])->m_liAtomCode == ((CMolAtom *)_singleMol->m_oaMolAtoms[a1])->m_liAtomCode)) { a2++; } if((a2 - a1) > 1) { char buf[BUF_SIZE]; char buf2[BUF_SIZE]; size_t remaining = BUF_SIZE; #ifdef TARGET_LINUX remaining -= snprintf(buf, remaining, "Atoms "); #else remaining -= sprintf(buf, "Atoms "); #endif for(i = a1; i < a2; i++) { if(remaining < 1) break; #ifdef TARGET_LINUX size_t length = snprintf(buf2, remaining, "%s%d ", (const char*)((CAtom *)g_oaAtoms[_singleMol->m_baAtomIndex[((CMolAtom *)_singleMol->m_oaMolAtoms[i])->m_iType]])->m_sName, ((CMolAtom *)_singleMol->m_oaMolAtoms[i])->m_iNumber + 1); #else size_t length = sprintf(buf2, "%s%d ", (const char*)((CAtom *)g_oaAtoms[_singleMol->m_baAtomIndex[((CMolAtom *)_singleMol->m_oaMolAtoms[i])->m_iType]])->m_sName, ((CMolAtom *)_singleMol->m_oaMolAtoms[i])->m_iNumber + 1); #endif strncat(buf, buf2, remaining - 1); remaining -= length; if(i < a2-1) { #ifdef TARGET_LINUX length = snprintf(buf2, remaining, ", "); #else length = sprintf(buf2, ", "); #endif strncat(buf, buf2, remaining - 1); remaining -= length; } } strncat(buf, " are equivalent.", remaining - 1); mprintf("\n %s\n", buf); int action = AskRangeInteger(" Create no permutation (1), cyclic permutations (2), all permutations (3), or specify certain permutations (4) ? [1] ", 1, 4, 1); actions->Add(action); } a1 = a2; } } void CReferenceStructure::createPermutationsRecursion(int start, CxIntArray *permutation, CxIntArray *permutationActions) { CxString buf; // mprintf(RED, "createPermutationsRecursion (%d):", start); // for(int i = 0; i < permutation->GetSize(); i++) { // mprintf(RED, " %d", permutation->GetAt(i)); // } // mprintf(RED, "\n"); int i, j; int a1 = start; while(a1 < _singleMol->m_oaMolAtoms.GetSize()) { int a2 = a1; while((a2 < _singleMol->m_oaMolAtoms.GetSize()) && (((CMolAtom *)_singleMol->m_oaMolAtoms[a2])->m_liAtomCode == ((CMolAtom *)_singleMol->m_oaMolAtoms[a1])->m_liAtomCode)) { a2++; } if((a2 - a1) > 1) { CxIntArray newPermutationActions; newPermutationActions.CopyFrom(permutationActions); int action = newPermutationActions[0]; newPermutationActions.RemoveAt(0, 1); if(action == 1) { CxIntArray *newPermutation; try { newPermutation = new CxIntArray(); } catch(...) { newPermutation = NULL; } if(newPermutation == NULL) NewException((double)sizeof(CxIntArray), __FILE__, __LINE__, __PRETTY_FUNCTION__); newPermutation->CopyFrom(permutation); for(i = a1; i < a2; i++) { newPermutation->Add(i); } createPermutationsRecursion(a2, newPermutation, &newPermutationActions); return; // for(int i = a1; i < a2; i++) { // permutation->Add(i); // } // permutationActions->RemoveAt(0, 1); // a1 = a2; } else if(action == 2) { CxIntArray *newPermutation; for(i = 0; i < (a2 - a1); i++) { try { newPermutation = new CxIntArray(); } catch(...) { newPermutation = NULL; } if(newPermutation == NULL) NewException((double)sizeof(CxIntArray), __FILE__, __LINE__, __PRETTY_FUNCTION__); newPermutation->CopyFrom(permutation); for(j = a1+i; j < a2; j++) newPermutation->Add(j); for(j = a1; j < a1+i; j++) newPermutation->Add(j); createPermutationsRecursion(a2, newPermutation, &newPermutationActions); } return; } else if(action == 3) { eprintf("CReferenceStructure::createPermutationsRecursion(): Error: Not implemented.\n"); abort(); } else if(action == 4) { CxIntArray *newPermutation; while(true) { try { newPermutation = new CxIntArray(); } catch(...) { newPermutation = NULL; } if(newPermutation == NULL) NewException((double)sizeof(CxIntArray), __FILE__, __LINE__, __PRETTY_FUNCTION__); newPermutation->CopyFrom(permutation); // char buf[BUF_SIZE]; const char delim[] = ", "; AskString(" Enter permutation: ", &buf, ""); if(strlen(buf) == 0) break; char *tok = strtok(buf.GetWritePointer(), delim); while(tok != NULL) { int n; if(sscanf(tok, "%d", &n) == 1) { newPermutation->Add(a1+n); } tok = strtok(NULL, delim); } createPermutationsRecursion(a2, newPermutation, &newPermutationActions); } return; } else { eprintf("CReferenceStructure::createPermutationsRecursion(): Internal error.\n"); abort(); } } else { permutation->Add(a1); a1 = a2; } } _permutations.Add(permutation); } double CReferenceStructure::offDiagonalNorm(CxObArray &matrix) { double norm = 0.0; int i, j, k; for(i = 0; i < 3 * _atomCount; i++) { for(j = i+1; j < 3 * _atomCount; j++) { double integral = 0.0; for(k = 0; k < ((CxDoubleArray *)matrix[(3*_atomCount-1)*i - i*(i-1)/2 + j])->GetSize(); k++) { integral += ((CxDoubleArray *)matrix[(3*_atomCount-1)*i - i*(i-1)/2 + j])->GetAt(k) * ((CxDoubleArray *)matrix[(3*_atomCount-1)*i - i*(i-1)/2 + j])->GetAt(k); } // mprintf(RED, "Integral (%d, %d): %f\n", i, j, integral); integral *= _specResolution; norm += integral; } } return sqrt(norm); } double CReferenceStructure::findRotationAngle(CxObArray &matrix, int i, int j) { // mprintf(RED, "findRotationAngle (%d, %d)\n", i, j); CxDoubleArray *aii = (CxDoubleArray *)matrix[(3*_atomCount-1)*i - i*(i-1)/2 + i]; CxDoubleArray *aij = (CxDoubleArray *)matrix[(3*_atomCount-1)*i - i*(i-1)/2 + j]; CxDoubleArray *ajj = (CxDoubleArray *)matrix[(3*_atomCount-1)*j - j*(j-1)/2 + j]; double int1 = 0.0, int2 = 0.0, int3 = 0.0; int k, l; for(k = 0; k < aij->GetSize(); k++) { int1 += (double)aij->GetAt(k) * (double)aij->GetAt(k); int2 += (double)aij->GetAt(k) * ((double)aii->GetAt(k) - (double)ajj->GetAt(k)); int3 += ((double)aii->GetAt(k) - (double)ajj->GetAt(k)) * ((double)aii->GetAt(k) - (double)ajj->GetAt(k)); } int1 *= (double)_specResolution; int2 *= (double)_specResolution; int3 *= (double)_specResolution; if(fabs(int2) < 1.0e-6) { double f = 4.0 * int1 - int3; if((fabs(int1) < 1.0) && (fabs(int2) < 1.0) && (fabs(int3) < 1.0)) return 0.0; if(0.5 * f > 0.0) return 1.0; if(-2.0 * f > 0.0) return 0.0; } else { double f = (4.0 * int1 - int3) / int2; double r[2][2]; double s[2][2]; for(k = 0; k < 2; k++) { for(l = 0; l < 2; l++) { r[k][l] = (-f + (k == 0 ? -1.0 : 1.0) * sqrt(16.0 + f * f) + (l == 0 ? -1.0 : 1.0) * sqrt(2.0) * sqrt(16.0 + f * f - (k == 0 ? -1.0 : 1.0) * f * sqrt(16.0 + f * f))) / 4.0; s[k][l] = -2.0 * int2 / pow4(r[k][l] * r[k][l] + 1.0) * (2.0 * r[k][l] * (pow4(r[k][l]) - 14.0 * r[k][l] * r[k][l] + 9.0) + f * (3.0 * pow4(r[k][l]) - 8.0 * r[k][l] * r[k][l] + 1.0)); } } for(k = 0; k < 2; k++) { for(l = 0; l < 2; l++) { if((fabs(r[k][l]) <= 1.0) && (s[k][l] > 0.0)) return r[k][l]; } } } eprintf("CReferenceStructure::findRotationAngle(): No suitable rotation angle found. Aborting.\n"); abort(); } void CReferenceStructure::calcIntegrals(CxObArray &matrix, CxDoubleArray *integrals, CxDoubleArray *centers) { integrals->SetSize(3*_atomCount); centers->SetSize(3*_atomCount); int i, k; for(i = 0; i < 3*_atomCount; i++) { integrals->GetAt(i) = 0.0; centers->GetAt(i) = 0.0; double integral_sqr = 0.0; for(k = 0; k < ((CxDoubleArray *)matrix[(3*_atomCount-1)*i - i*(i-1)/2 + i])->GetSize(); k++) { // integrals->GetAt(i) += ((CxFloatArray *)matrix[(3*_atomCount-1)*i - i*(i-1)/2 + i])->GetAt(k) * ((CxFloatArray *)matrix[(3*_atomCount-1)*i - i*(i-1)/2 + i])->GetAt(k); integrals->GetAt(i) += ((CxDoubleArray *)matrix[(3*_atomCount-1)*i - i*(i-1)/2 + i])->GetAt(k); integral_sqr += ((CxDoubleArray *)matrix[(3*_atomCount-1)*i - i*(i-1)/2 + i])->GetAt(k) * ((CxDoubleArray *)matrix[(3*_atomCount-1)*i - i*(i-1)/2 + i])->GetAt(k); centers->GetAt(i) += ((CxDoubleArray *)matrix[(3*_atomCount-1)*i - i*(i-1)/2 + i])->GetAt(k) * ((CxDoubleArray *)matrix[(3*_atomCount-1)*i - i*(i-1)/2 + i])->GetAt(k) * (double)k; } integrals->GetAt(i) *= _specResolution;// * 3.605675e-9; integral_sqr *= _specResolution; centers->GetAt(i) *= _specResolution * _specResolution / integral_sqr; } } CNormalCoordinateObservation::CNormalCoordinateObservation() { // char buf[BUF_SIZE]; // char buf2[BUF_SIZE]; // size_t remaining = BUF_SIZE; CxString buf, buf2, name; int i, j; if(g_oaMolecules.GetSize() > 1) { /*#ifdef TARGET_LINUX remaining -= snprintf(buf, remaining, " Which molecule should be observed ("); #else remaining -= sprintf(buf, " Which molecule should be observed ("); #endif*/ buf.sprintf(" Which molecule should be observed ("); for(i = 0; i < g_oaMolecules.GetSize(); i++) { /* if(remaining < 1) break; #ifdef TARGET_LINUX size_t length = snprintf(buf2, remaining, "%s=%d", ((CMolecule *)g_oaMolecules[i])->m_sName, i+1); #else size_t length = sprintf(buf2, "%s=%d", ((CMolecule *)g_oaMolecules[i])->m_sName, i+1); #endif strncat(buf, buf2, remaining - 1); remaining -= length;*/ buf2.sprintf("%s=%d", ((CMolecule *)g_oaMolecules[i])->m_sName, i+1); buf.strcat(buf2); if(i < g_oaMolecules.GetSize() - 1) { /*#ifdef TARGET_LINUX length = snprintf(buf2, remaining, ", "); #else length = sprintf(buf2, ", "); #endif strncat(buf, buf2, remaining - 1); remaining -= length;*/ buf2.sprintf(", "); buf.strcat(buf2); } } // strncat(buf, ")? ", remaining - 1); buf.strcat(")? "); m_iShowMol = AskRangeInteger_ND("%s", 1, g_oaMolecules.GetSize(), (const char*)buf) - 1; } else { m_iShowMol = 0; } m_iShowMolCount = ((CMolecule *)g_oaMolecules[m_iShowMol])->m_laSingleMolIndex.GetSize(); // _calcIR = AskYesNo(" Calculate also transformed IR spectrum? [no] ", false); _calcIR = false; if(_calcIR) { g_bDipole = true; ParseDipole(); } mprintf("\n"); _refCount = 0; while(true) { _refCount++; mprintf(YELLOW, ">>> Reference Structure %d >>>\n\n", _refStructures.GetSize()+1); /* char name[BUF_SIZE]; #ifdef TARGET_LINUX snprintf(name, BUF_SIZE, "normalcoordinate_%s_r%d", ((CMolecule *)g_oaMolecules[m_iShowMol])->m_sName, _refCount); #else sprintf(name, "normalcoordinate_%s_r%d", ((CMolecule *)g_oaMolecules[m_iShowMol])->m_sName, _refCount); #endif*/ name.sprintf("normalcoordinate_%s_r%d", ((CMolecule *)g_oaMolecules[m_iShowMol])->m_sName, _refCount); CReferenceStructure *refStruct; try { refStruct = new CReferenceStructure(m_iShowMol, name, _calcIR); } catch(...) { refStruct = NULL; } if(refStruct == NULL) NewException((double)sizeof(CReferenceStructure), __FILE__, __LINE__, __PRETTY_FUNCTION__); _refStructures.Add(refStruct); mprintf(YELLOW, "<<< End of Reference Structure %d <<<\n\n", _refStructures.GetSize()); if(!AskYesNo(" Add another reference structure (y/n)? [no] ", false)) break; mprintf("\n"); } // _refCount = AskUnsignedInteger(" How many reference structures do you wish to enter? [1] ", 1); // for(int i = 0; i < _refCount; i++) { // mprintf(YELLOW, "\n>>> Reference Structure %d >>>\n\n", _refStructures.GetSize()+1); // // CReferenceStructure *refStruct; // try { refStruct = new CReferenceStructure(m_iShowMol, _calcIR); } catch(...) { refStruct = NULL; } // if(refStruct == NULL) NewException((double)sizeof(CReferenceStructure), __FILE__, __LINE__, __PRETTY_FUNCTION__); // _refStructures.Add(refStruct); // // mprintf(YELLOW, "<<< End of Reference Structure %d <<<\n", _refStructures.GetSize()); // } // if(g_bAdvanced2) // _writeTransformedTrajectories = AskYesNo("\n Save trajectories after transformation to reference frame for first observed molecule (y/n)? [no] ", false); // else if(_refCount > 1) { _useInternals = AskYesNo("\n Use mass-weighted Cartesians for probabilities (n) or define internal coordinates (y)? [no] ", false); if(_useInternals) { mprintf("\n At the moment, only \"simple\" dihedral angles can be defined.\n"); do { CxIntArray *internal; try { internal = new CxIntArray(); } catch(...) { internal = NULL; } if(internal == NULL) NewException((double)sizeof(CxIntArray), __FILE__, __LINE__, __PRETTY_FUNCTION__); internal->SetSize(4); mprintf("\n"); for(i = 0; i < 4; i++) { // char buf[BUF_SIZE]; int parse[3]; do AskString_ND(" Enter the %d. atom (e.g. C7): ", &buf, i+1); while(!ParseAtom(buf, m_iShowMol, parse[0], parse[1], parse[2])); internal->GetAt(i) = -1; for(j = 0; j < ((CSingleMolecule *)g_oaSingleMolecules[((CMolecule *)g_oaMolecules[m_iShowMol])->m_laSingleMolIndex[0]])->m_oaMolAtoms.GetSize(); j++) { CMolAtom *ma = (CMolAtom *)((CSingleMolecule *)g_oaSingleMolecules[((CMolecule *)g_oaMolecules[m_iShowMol])->m_laSingleMolIndex[0]])->m_oaMolAtoms[j]; if((ma->m_iType == parse[0]) && (ma->m_iNumber == parse[2])) { internal->GetAt(i) = j; break; } } if(internal->GetAt(i) == -1) { eprintf("CNormalCoordinateObservation::CNormalCoordinateObservation(): Internal error.\n"); abort(); } } _internals.Add(internal); } while(AskYesNo("\n Add another dihedral angle (y/n)? [no] ", false)); _gaussianWidth = AskFloat("\n Gaussian width for probability distribution (deg)? [10.0] ", 10.0); } else { _gaussianWidth = AskFloat(" Gaussian width for probability distribution (pm*sqrt(amu))? [1.0] ", 1.0); } } else { _useInternals = false; _gaussianWidth = 1000.0; } // _gaussianWidth = AskFloat("\n Gaussian width for probability distribution (pm*sqrt(amu))? [1.0] ", 1.0f); // if(g_iTrajSteps != -1) { // _correlationDepth = 0.75 * g_iTrajSteps; // if(_correlationDepth > 4096) // _correlationDepth = 4096; // _correlationDepth = AskUnsignedInteger(" Enter the resolution (=depth) of the ACF (in time steps): [%d] ", _correlationDepth, _correlationDepth); // } else { // _correlationDepth = AskUnsignedInteger(" Enter the resolution (=depth) of the ACF (in time steps): [256] ", 256); // } // int size = CalcFFTSize(_correlationDepth, false); // if(_correlationDepth != size) { // mprintf(WHITE, " The next \"fast\" size for FFT is %d. Using this instead of %d as depth.\n", size, _correlationDepth); // _correlationDepth = size; // } } CNormalCoordinateObservation::~CNormalCoordinateObservation() { int i; for(i = 0; i < _distanceTimedev.GetSize(); i++) delete (CxDoubleArray *)_distanceTimedev[i]; for(i = 0; i < _refStructures.GetSize(); i++) delete (CReferenceStructure *)_refStructures[i]; } void CNormalCoordinateObservation::initialize() { _numSteps = 0; // if(_writeTransformedTrajectories) { // int numPerm = 0; // for(int i = 0; i < _refStructures.GetSize(); i++) { // numPerm += ((CReferenceStructure *)_refStructures[i])->numPermutations(); // } // try { _transformedTrajectoryFiles = new FILE *[numPerm]; } catch(...) { _transformedTrajectoryFiles = NULL; } // if(_transformedTrajectoryFiles == NULL) NewException((double)numPerm * sizeof(FILE *), __FILE__, __LINE__, __PRETTY_FUNCTION__); // int index = 0; // for(int i = 0; i < _refStructures.GetSize(); i++) { // for(int j = 0; j < ((CReferenceStructure *)_refStructures[i])->numPermutations(); j++) { // char name[BUF_SIZE]; // snprintf(name, BUF_SIZE, "reference_%s_%d_%d_transformed.xyz", ((CMolecule *)g_oaMolecules[m_iShowMol])->m_sName, i+1, j+1); // _transformedTrajectoryFiles[index] = OpenFileWrite(name, false); // if(_transformedTrajectoryFiles[index] == NULL) { // mprintf(RED, "Could not open file %s: %s\n", name, strerror(errno)); // } // index++; // } // } // } // for(int i = 0; i < m_iShowMolCount * _refStructures.GetSize(); i++) { // CxObArray *a; // try { a = new CxObArray(); } catch(...) { a = NULL; } // if(a == NULL) NewException((double)sizeof(CxObArray), __FILE__, __LINE__, __PRETTY_FUNCTION__); // _distanceTimedev.Add(a); // } // for(int i = 0; i < m_iShowMolCount; i++) { // for(int j = 0; j < _refStructures.GetSize(); j++) { // for(int k = 0; k < 3; k++) { // CxObArray *a; // try { a = new CxObArray(); } catch(...) { a = NULL; } // if(a == NULL) NewException((double)sizeof(CxObArray), __FILE__, __LINE__, __PRETTY_FUNCTION__); // for(int l = 0; l < ((CReferenceStructure *)_refStructures[j])->numPermutations(); l++) { // CxDVec3Array *b; // try { b = new CxDVec3Array(); } catch(...) { b = NULL; } // if(b == NULL) NewException((double)sizeof(CxDVec3Array), __FILE__, __LINE__, __PRETTY_FUNCTION__); // a->Add(b); // } // _coordHistory.Add(a); // } // } // } // _historyIndex = 0; // _calcVelocity = false; // for(int i = 0; i < m_iShowMolCount * _refStructures.GetSize(); i++) { // CxObArray *a; // try { a = new CxObArray(); } catch(...) { a = NULL; } // if(a == NULL) NewException((double)sizeof(CxObArray), __FILE__, __LINE__, __PRETTY_FUNCTION__); // _velocityCache.Add(a); // } int n; if(g_iTrajSteps != -1) n = (int)(1.1 * g_iTrajSteps / g_iStride); else n = 10000; mprintf(" Global distance time development: Trying to allocate %s of memory...\n", FormatBytes((double)m_iShowMolCount * n * _refCount * sizeof(double))); int i; for(i = 0; i < m_iShowMolCount * _refCount; i++) { CxDoubleArray *a; try { a = new CxDoubleArray(); } catch(...) { a = NULL; } if(a == NULL) NewException((double)sizeof(CxDoubleArray), __FILE__, __LINE__, __PRETTY_FUNCTION__); a->SetMaxSize(n); a->SetGrow((int)(0.1 * n)); _distanceTimedev.Add(a); } for(i = 0; i < _refStructures.GetSize(); i++) { mprintf(" Initializing reference structure %d...\n", i+1); char name[BUF_SIZE]; #ifdef TARGET_LINUX snprintf(name, BUF_SIZE, "normalcoordinate_%s_r%d", ((CMolecule *)g_oaMolecules[m_iShowMol])->m_sName, i+1); #else sprintf(name, "normalcoordinate_%s_r%d", ((CMolecule *)g_oaMolecules[m_iShowMol])->m_sName, i+1); #endif ((CReferenceStructure *)_refStructures[i])->initialize(name); } } void CNormalCoordinateObservation::process(CTimeStep *ts) { int i, j; for(i = 0; i < m_iShowMolCount; i++) { CSingleMolecule *sm = (CSingleMolecule *)g_oaSingleMolecules[((CMolecule *)g_oaMolecules[m_iShowMol])->m_laSingleMolIndex[i]]; CxDVec3Array coord; coord.SetSize(sm->m_oaMolAtoms.GetSize()); for(j = 0; j < sm->m_oaMolAtoms.GetSize(); j++) { coord[j] = ts->m_vaCoords[((CMolAtom *)sm->m_oaMolAtoms[j])->m_iOffset]; } CxDVector3 dipole(0.0, 0.0, 0.0); if(_calcIR) { dipole = sm->m_vDipole; } for(j = 0; j < _refStructures.GetSize(); j++) { ((CReferenceStructure *)_refStructures[j])->processCoordinates(coord, dipole, i); ((CxDoubleArray *)_distanceTimedev[i*_refCount + j])->Add(((CReferenceStructure *)_refStructures[j])->calcMinimumDistance(i, _useInternals, _internals)); if(_numSteps >= 2) ((CReferenceStructure *)_refStructures[j])->calcVelocities(i); } } for(i = 0; i < _refStructures.GetSize(); i++) { ((CReferenceStructure *)_refStructures[i])->nextStep(); } _numSteps++; // for(int i = 0; i < m_iShowMolCount; i++) { // CSingleMolecule *sm = (CSingleMolecule *)g_oaSingleMolecules[((CMolecule *)g_oaMolecules[m_iShowMol])->m_laSingleMolIndex[i]]; // CxDVec3Array coord; // coord.SetSize(sm->m_oaMolAtoms.GetSize()); // for(int j = 0; j < sm->m_oaMolAtoms.GetSize(); j++) { // coord[j] = ts->m_vaCoords[((CMolAtom *)sm->m_oaMolAtoms[j])->m_iOffset]; // } // int index = 0; // for(int j = 0; j < _refStructures.GetSize(); j++) { // CxFloatArray *distances; // try { distances = new CxFloatArray(); } catch(...) { distances = NULL; } // if(distances == NULL) NewException((double)sizeof(CxFloatArray), __FILE__, __LINE__, __PRETTY_FUNCTION__); // distances->SetSize(((CReferenceStructure *)_refStructures[j])->numPermutations()); // // CxObArray newCoords; // // for(int k = 0; k < ((CReferenceStructure *)_refStructures[j])->numPermutations(); k++) { // // CxDVec3Array *a; // // try { a = new CxDVec3Array(); } catch(...) { a = NULL; } // // if(a == NULL) NewException((double)sizeof(CxDVec3Array), __FILE__, __LINE__, __PRETTY_FUNCTION__); // // newCoords.Add(a); // // } // ((CReferenceStructure *)_refStructures[j])->transformCoordinates(coord, *distances, *((CxObArray *)_coordHistory[3*_refStructures.GetSize()*i+3*j+_historyIndex])); // if(_writeTransformedTrajectories && (i == 0)) { // for(int k = 0; k < ((CReferenceStructure *)_refStructures[j])->numPermutations(); k++) { // fprintf(_transformedTrajectoryFiles[index], "%6d\n\n", ((CxDVec3Array *)((CxObArray *)_coordHistory[3*_refStructures.GetSize()*i+3*j+_historyIndex])->GetAt(k))->GetSize()); // for(int l = 0; l < ((CxDVec3Array *)((CxObArray *)_coordHistory[3*_refStructures.GetSize()*i+3*j+_historyIndex])->GetAt(k))->GetSize(); l++) { // fprintf(_transformedTrajectoryFiles[index], "%4s %14.8f %14.8f %14.8f\n", ((CAtom *)g_oaAtoms[sm->m_baAtomIndex[((CMolAtom *)sm->m_oaMolAtoms[l])->m_iType]])->m_sName, ((CxDVec3Array *)((CxObArray *)_coordHistory[3*_refStructures.GetSize()*i+3*j+_historyIndex])->GetAt(k))->GetAt(l)[0] / 100.0f, ((CxDVec3Array *)((CxObArray *)_coordHistory[3*_refStructures.GetSize()*i+3*j+_historyIndex])->GetAt(k))->GetAt(l)[1] / 100.0f, ((CxDVec3Array *)((CxObArray *)_coordHistory[3*_refStructures.GetSize()*i+3*j+_historyIndex])->GetAt(k))->GetAt(l)[2] / 100.0f); // } // index++; // } // } // ((CxObArray *)_distanceTimedev[i*_refStructures.GetSize() + j])->Add(distances); // if(_calcVelocity) { // CxObArray *vel; // try { vel = new CxObArray(); } catch(...) { vel = NULL; } // if(vel == NULL) NewException((double)sizeof(CxObArray), __FILE__, __LINE__, __PRETTY_FUNCTION__); // for(int k = 0; k < ((CReferenceStructure *)_refStructures[j])->numPermutations(); k++) { // CxDVec3Array *vec; // try { vec = new CxDVec3Array(); } catch(...) { vec = NULL; } // if(vec == NULL) NewException((double)sizeof(CxDVec3Array), __FILE__, __LINE__, __PRETTY_FUNCTION__); // vec->SetSize(((CxDVec3Array *)((CxObArray *)_coordHistory[3*_refStructures.GetSize()*i+3*j+_historyIndex])->GetAt(k))->GetSize()); // int n = (_historyIndex + 1) % 3; // for(int l = 0; l < ((CxDVec3Array *)((CxObArray *)_coordHistory[3*_refStructures.GetSize()*i+3*j+_historyIndex])->GetAt(k))->GetSize(); l++) { // vec->GetAt(l) = (((CxDVec3Array *)((CxObArray *)_coordHistory[3*_refStructures.GetSize()*i+3*j+_historyIndex])->GetAt(k))->GetAt(l) - ((CxDVec3Array *)((CxObArray *)_coordHistory[3*_refStructures.GetSize()*i+3*j+n])->GetAt(k))->GetAt(l)) / 2.0f / g_fTimestepLength * 1000.0f; // } // vel->Add(vec); // } // ((CxObArray *)_velocityCache[i*_refStructures.GetSize() + j])->Add(vel); // } // // for(int k = 0; k < newCoords.GetSize(); k++) // // delete (CxDVec3Array *)newCoords[k]; // // newCoords.RemoveAll(); // } // } // _historyIndex = (_historyIndex + 1) % 3; // if(_historyIndex == 2) // _calcVelocity = true; // _numSteps++; } void CNormalCoordinateObservation::finalize() { mprintf(" Saving global distance time development...\n"); char name[BUF_SIZE]; #ifdef TARGET_LINUX snprintf(name, BUF_SIZE, "normalcoordinate_%s_global_dist_timedev.csv", ((CMolecule *)g_oaMolecules[m_iShowMol])->m_sName); #else sprintf(name, "normalcoordinate_%s_global_dist_timedev.csv", ((CMolecule *)g_oaMolecules[m_iShowMol])->m_sName); #endif FILE *distanceFile = OpenFileWrite(name, false); fprintf(distanceFile, "#Time (fs);"); int i, j, k; for(i = 0; i < m_iShowMolCount; i++) { for(j = 0; j < _refCount; j++) { fprintf(distanceFile, " M%d R%d;", i+1, j+1); } } fprintf(distanceFile, "\n"); for(i = 0; i < _numSteps; i++) { fprintf(distanceFile, "%.2f;", i * g_fTimestepLength * g_iStride); for(j = 0; j < m_iShowMolCount; j++) { for(k = 0; k < _refCount; k++) { fprintf(distanceFile, " %.8G;", ((CxDoubleArray *)_distanceTimedev[j*_refCount + k])->GetAt(i)); } } fprintf(distanceFile, "\n"); } fclose(distanceFile); mprintf(" Saving global probability time development...\n"); #ifdef TARGET_LINUX snprintf(name, BUF_SIZE, "normalcoordinate_%s_global_prob_timedev.csv", ((CMolecule *)g_oaMolecules[m_iShowMol])->m_sName); #else sprintf(name, "normalcoordinate_%s_global_prob_timedev.csv", ((CMolecule *)g_oaMolecules[m_iShowMol])->m_sName); #endif FILE *probFile = OpenFileWrite(name, false); fprintf(probFile, "#Time (fs);"); for(i = 0; i < m_iShowMolCount; i++) { for(j = 0; j < _refCount; j++) { fprintf(probFile, " M%d R%d;", i+1, j+1); } } fprintf(probFile, "\n"); CxDoubleArray probSum; probSum.SetSize(m_iShowMolCount*_numSteps); for(i = 0; i < _numSteps; i++) { fprintf(probFile, "%.2f;", i * g_fTimestepLength * g_iStride); for(j = 0; j < m_iShowMolCount; j++) { CxDoubleArray probs; probs.SetSize(_refCount); probSum[j*_numSteps + i] = 0.0; if(_refCount == 1) { probs[0] = 1.0; probSum[j*_numSteps + i] = 1.0; ((CReferenceStructure *)_refStructures[0])->setGlobalProbability(j, i, (double)(probs[0] / probSum[j*_numSteps + i])); fprintf(probFile, " %.8G;", probs[0] / probSum[j*_numSteps + i]); } else { for(k = 0; k < _refCount; k++) { probs[k] = exp(-(double)((CxDoubleArray *)_distanceTimedev[j*_refCount + k])->GetAt(i) * (double)((CxDoubleArray *)_distanceTimedev[j*_refCount + k])->GetAt(i) / 2.0 / (double)_gaussianWidth / (double)_gaussianWidth); probSum[j*_numSteps + i] += probs[k]; } for(k = 0; k < _refCount; k++) { if(isnan(probs[k] / probSum[j*_numSteps + i])) { eprintf("CNormalCoordinateObservation::finalize(): Invalid probability for reference %d of molecule %d in step %d.\nMaybe it helps to increase the distribution width.\nTwo identical reference structures can also cause this error.\n", k+1, j+1, i+1); abort(); } ((CReferenceStructure *)_refStructures[k])->setGlobalProbability(j, i, (double)(probs[k] / probSum[j*_numSteps + i])); fprintf(probFile, " %.8G;", probs[k] / probSum[j*_numSteps + i]); } } } fprintf(probFile, "\n"); } fclose(probFile); // mprintf(" Calculating reference probabilities\n"); // char name[BUF_SIZE]; // snprintf(name, BUF_SIZE, "normalcoordinate_%s_global_prob_timedev.dat", ((CMolecule *)g_oaMolecules[m_iShowMol])->m_sName); // FILE *probFile = OpenFileWrite(name, false); // fprintf(probFile, "# Time "); // for(int i = 0; i < m_iShowMolCount; i++) { // for(int j = 0; j < _refStructures.GetSize(); j++) { // fprintf(probFile, " M. %3d,R. %3d", i+1, j+1); // } // } // fprintf(probFile, "\n"); // for(int i = 0; i < _numSteps; i++) { // fprintf(probFile, "%10.2f", i * g_fTimestepLength * g_iStride); // for(int j = 0; j < m_iShowMolCount; j++) { // CxFloatArray dist; // dist.SetSize(_refStructures.GetSize()); // for(int k = 0; k < _refStructures.GetSize(); k++) { // dist[k] = ((CReferenceStructure *)_refStructures[k])->getMinimumDistance(j, i); // } // // CxFloatArray probs; // CxDoubleArray probs; // probs.SetSize(_refStructures.GetSize()); // // double probSum = 0.0f; // double probSum = 0.0; // for(int k = 0; k < _refStructures.GetSize(); k++) { // // probs[k] = exp(-dist[k] * dist[k] / 2.0f / _gaussianWidth / _gaussianWidth); // probs[k] = exp(-(double)dist[k] * (double)dist[k] / 2.0 / (double)_gaussianWidth / (double)_gaussianWidth); // probSum += probs[k]; // } // for(int k = 0; k < _refStructures.GetSize(); k++) { // ((CReferenceStructure *)_refStructures[k])->setGlobalProbability(j, i, (double)(probs[k] / probSum)); // fprintf(probFile, " %14.8f", probs[k] / probSum); // } // } // fprintf(probFile, "\n"); // } // fclose(probFile); for(i = 0; i < _refStructures.GetSize(); i++) { mprintf(" Finalizing reference structure %d...\n", i+1); //char name[BUF_SIZE]; #ifdef TARGET_LINUX snprintf(name, BUF_SIZE, "normalcoordinate_%s_r%d", ((CMolecule *)g_oaMolecules[m_iShowMol])->m_sName, i+1); #else sprintf(name, "normalcoordinate_%s_r%d", ((CMolecule *)g_oaMolecules[m_iShowMol])->m_sName, i+1); #endif ((CReferenceStructure *)_refStructures[i])->finalize(name); } // mprintf(" Saving distance time development...\n"); // for(int i = 0; i < _refStructures.GetSize(); i++) { // char name[BUF_SIZE]; // snprintf(name, BUF_SIZE, "distance_timedev_reference_%s_%d.dat", ((CMolecule *)g_oaMolecules[m_iShowMol])->m_sName, i+1); // FILE *distanceFile = OpenFileWrite(name, false); // for(int j = 0; j < _numSteps; j++) { // fprintf(distanceFile, "%10.2f", j * g_fTimestepLength * g_iStride); // for(int k = 0; k < m_iShowMolCount; k++) { // for(int l = 0; l < ((CReferenceStructure *)_refStructures[i])->numPermutations(); l++) { // fprintf(distanceFile, " %14.8f", ((CxFloatArray *)((CxObArray *)_distanceTimedev[k*_refStructures.GetSize() + i])->GetAt(j))->GetAt(l)); // } // } // fprintf(distanceFile, "\n"); // } // fclose(distanceFile); // } // // mprintf(" Saving probability time development...\n"); // for(int i = 0; i < _refStructures.GetSize(); i++) { // char name[BUF_SIZE]; // snprintf(name, BUF_SIZE, "probability_timedev_reference_%s_%d.dat", ((CMolecule *)g_oaMolecules[m_iShowMol])->m_sName, i+1); // FILE *probFile = OpenFileWrite(name, false); // for(int j = 0; j < _numSteps; j++) { // fprintf(probFile, "%10.2f", j * g_fTimestepLength * g_iStride); // for(int k = 0; k < m_iShowMolCount; k++) { // CxFloatArray probs; // probs.SetSize(((CReferenceStructure *)_refStructures[i])->numPermutations()); // double probSum = 0.0f; // for(int l = 0; l < ((CReferenceStructure *)_refStructures[i])->numPermutations(); l++) { // probs[l] = exp(-((CxFloatArray *)((CxObArray *)_distanceTimedev[k*_refStructures.GetSize() + i])->GetAt(j))->GetAt(l) * ((CxFloatArray *)((CxObArray *)_distanceTimedev[k*_refStructures.GetSize() + i])->GetAt(j))->GetAt(l) / 2.0f / _gaussianWidth); // probSum += probs[l]; // } // for(int l = 0; l < ((CReferenceStructure *)_refStructures[i])->numPermutations(); l++) { // fprintf(probFile, " %14.8f", probs[l] / probSum); // } // } // fprintf(probFile, "\n"); // } // fclose(probFile); // } // // CCrossCorrelation *cc; // try { cc = new CCrossCorrelation(); } catch(...) { cc = NULL; } // if(cc == NULL) NewException((double)sizeof(CCrossCorrelation), __FILE__, __LINE__, __PRETTY_FUNCTION__); // cc->Init(_numSteps - 2, _correlationDepth, true); // // for(int i = 0; i < _refStructures.GetSize(); i++) { // mprintf(" Calculating cross correlation matrix for reference structure %d...\n", i+1); // CxObArray ccMatrix; // for(int j = 0; j < 3 * m_iGesAtomCount; j++) { // for(int k = 0; k <= j; k++) { // CxFloatArray *a; // try { a = new CxFloatArray(); } catch(...) { a = NULL; } // if(a == NULL) NewException((double)sizeof(CxFloatArray), __FILE__, __LINE__, __PRETTY_FUNCTION__); // for(int l = 0; l < m_iShowMolCount; l++) { // for(int m = 0; m < ((CReferenceStructure *)_refStructures[i])->numPermutations(); m++) { // // } // } // ccMatrix.Add(a); // } // } // } // // delete cc; // // if(_writeTransformedTrajectories) { // int index = 0; // for(int i = 0; i < _refStructures.GetSize(); i++) { // for(int j = 0; j < ((CReferenceStructure *)_refStructures[i])->numPermutations(); j++) { // fclose(_transformedTrajectoryFiles[index++]); // } // } // delete[] _transformedTrajectoryFiles; // } // for(int i = 0; i < _distanceTimedev.GetSize(); i++) { // for(int j = 0; j < ((CxObArray *)_distanceTimedev[i])->GetSize(); j++) { // delete (CxFloatArray *)((CxObArray *)_distanceTimedev[i])->GetAt(j); // } // delete (CxObArray *)_distanceTimedev[i]; // } // for(int i = 0; i < _coordHistory.GetSize(); i++) { // for(int j = 0; j < ((CxObArray *)_coordHistory[i])->GetSize(); j++) { // delete (CxDVec3Array *)((CxObArray *)_coordHistory[i])->GetAt(j); // } // delete (CxObArray *)_coordHistory[i]; // } // for(int i = 0; i < _velocityCache.GetSize(); i++) { // for(int j = 0; j < ((CxObArray *)_velocityCache[i])->GetSize(); j++) { // for(int k = 0; k < ((CxObArray *)((CxObArray *)_velocityCache[i])->GetAt(j))->GetSize(); k++) { // delete (CxDVec3Array *)((CxObArray *)((CxObArray *)_velocityCache[i])->GetAt(j))->GetAt(k); // } // delete (CxObArray *)((CxObArray *)_velocityCache[i])->GetAt(j); // } // delete (CxObArray *)_velocityCache[i]; // } } bool gatherNormalCoordinate() { while(true) { mprintf(YELLOW, ">>> Normal Coordinate Observation %d >>>\n\n", g_normalCoordinateObservations.GetSize()+1); CNormalCoordinateObservation *obs; try { obs = new CNormalCoordinateObservation(); } catch(...) { obs = NULL; } if(obs == NULL) NewException((double)sizeof(CNormalCoordinateObservation), __FILE__, __LINE__, __PRETTY_FUNCTION__); g_normalCoordinateObservations.Add(obs); mprintf(YELLOW, "\n<<< End of Normal Coordinate Observation %d <<<\n\n", g_normalCoordinateObservations.GetSize()); if(!AskYesNo(" Add another observation (y/n)? [no] ", false)) break; mprintf("\n"); } mprintf("\n"); return true; } bool initializeNormalCoordinate() { int i; for(i = 0; i < g_normalCoordinateObservations.GetSize(); i++) { mprintf("Initializing Normal Coordinate Observation %d...\n", i+1); ((CNormalCoordinateObservation *)g_normalCoordinateObservations[i])->initialize(); } return true; } void processNormalCoordinate(CTimeStep *ts) { int i; for(i = 0; i < g_normalCoordinateObservations.GetSize(); i++) ((CNormalCoordinateObservation *)g_normalCoordinateObservations[i])->process(ts); } void finalizeNormalCoordinate() { int i; for(i = 0; i < g_normalCoordinateObservations.GetSize(); i++) { mprintf(YELLOW, ">>> Normal Coordinate Observation %d >>>\n\n", i+1); ((CNormalCoordinateObservation *)g_normalCoordinateObservations[i])->finalize(); mprintf(YELLOW, "\n<<< End of Normal Coordinate Observation %d <<<\n", i+1); } for(i = 0; i < g_normalCoordinateObservations.GetSize(); i++) delete (CNormalCoordinateObservation *)g_normalCoordinateObservations[i]; } CEckartReferenceStructure::CEckartReferenceStructure() { CxString buf; try { _singleMol = new CSingleMolecule(); } catch(...) { _singleMol = NULL; } if(_singleMol == NULL) NewException((double)sizeof(CSingleMolecule), __FILE__, __LINE__, __PRETTY_FUNCTION__); try { _refTimestep = new CTimeStep(); } catch(...) { _refTimestep = NULL; } if(_refTimestep == NULL) NewException((double)sizeof(CTimeStep), __FILE__, __LINE__, __PRETTY_FUNCTION__); try { _mapAtoms = new CAtomGroup(); } catch(...) { _mapAtoms = NULL; } if(_mapAtoms == NULL) NewException((double)sizeof(CAtomGroup), __FILE__, __LINE__, __PRETTY_FUNCTION__); while(true) { // char buf[BUF_SIZE]; AskString_ND(" Filename for reference structure: ", &buf); FILE *refFile = fopen(buf, "r"); if(refFile == NULL) { mprintf(RED, "Could not open reference structure file: %s\n", strerror(errno)); continue; } if(!_refTimestep->ReadTimestep(refFile, true)) { mprintf(RED, "Error reading reference structure file\n"); continue; } strncpy(_filename, buf, 128); _filename[127] = 0; mprintf("\n Starting molecule recoginition...\n"); if(!recognizeMolecule(_refTimestep)) { mprintf(RED, "Molecule recoginition failed\n\n"); continue; } break; } if(((CMolecule *)g_oaMolecules[_singleMol->m_iMolType])->m_laSingleMolIndex.GetSize() > 1) { _singleMolIndex = AskRangeInteger(" Which representant of %s in the trajectory should be mapped to the reference structure (1-%d)? ", 1, ((CMolecule *)g_oaMolecules[_singleMol->m_iMolType])->m_laSingleMolIndex.GetSize(), 1, ((CMolecule *)g_oaMolecules[_singleMol->m_iMolType])->m_sName, ((CMolecule *)g_oaMolecules[_singleMol->m_iMolType])->m_laSingleMolIndex.GetSize()) - 1; } else { _singleMolIndex = 0; mprintf(" Mapping molecule %s in trajectory to reference structure.\n", ((CMolecule *)g_oaMolecules[_singleMol->m_iMolType])->m_sName); } mprintf("\n"); while(true) { mprintf(" Which atom(s) to map (e.g. \"C1,C3-5,H\", \"*\"=all)? [*] "); inpprintf("! Which atom(s) to map (e.g. \"C1,C3-5,H\", \"*\"=all)? [*]\n"); // char buf[BUF_SIZE]; myget(&buf); if(strlen(buf) == 0) { if(!_mapAtoms->ParseAtoms((CMolecule *)g_oaMolecules[_singleMol->m_iMolType], "*")) { eprintf("CEckartReferenceStructure::CEckartReferenceStructure(): Internal error.\n"); continue; } } else if(!_mapAtoms->ParseAtoms((CMolecule *)g_oaMolecules[_singleMol->m_iMolType], buf)) { continue; } break; } mprintf("\n Mapping %d atoms.\n", _mapAtoms->m_iAtomGes); _refCentroidCoord.SetSize(_mapAtoms->m_iAtomGes); _refCentroid = CxDVector3(0.0, 0.0, 0.0); _weightSum = 0.0; _weights.SetSize(_mapAtoms->m_iAtomGes); int i; int k = 0; for(i = 0; i < _mapAtoms->m_baAtomType.GetSize(); i++) { CxIntArray *a = (CxIntArray *)_mapAtoms->m_oaAtoms[i]; int j; for(j = 0; j < a->GetSize(); j++) { _refCentroidCoord[k] = (_refTimestep->m_vaCoords[((CxIntArray *)_singleMol->m_oaAtomOffset[_mapAtoms->m_baAtomType[i]])->GetAt(a->GetAt(j))]); _weights[k] = ((CAtom *)g_oaAtoms[_mapAtoms->m_baRealAtomType[i]])->m_pElement->m_fMass; _weightSum += _weights[k]; _refCentroid += _refCentroidCoord[k] * _weights[k]; k++; } } _refCentroid /= _weightSum; for(i = 0; i < _refCentroidCoord.GetSize(); i++) { _refCentroidCoord[i] -= _refCentroid; } } CEckartReferenceStructure::~CEckartReferenceStructure() { delete _singleMol; delete _refTimestep; delete _mapAtoms; } void CEckartReferenceStructure::process(CTimeStep *ts) { CxDVec3Array coord; coord.SetSize(_mapAtoms->m_iAtomGes); CxDVector3 centroid(0.0, 0.0, 0.0); CSingleMolecule *sm = (CSingleMolecule *)g_oaSingleMolecules[((CMolecule *)g_oaMolecules[_singleMol->m_iMolType])->m_laSingleMolIndex[_singleMolIndex]]; int i, j; int k = 0, l; for(i = 0; i < _mapAtoms->m_baAtomType.GetSize(); i++) { CxIntArray *a = (CxIntArray *)_mapAtoms->m_oaAtoms[i]; for(j = 0; j < a->GetSize(); j++) { coord[k] = (ts->m_vaCoords[((CxIntArray *)sm->m_oaAtomOffset[_mapAtoms->m_baAtomType[i]])->GetAt(a->GetAt(j))]); centroid += coord[k] * _weights[k]; k++; } } centroid /= _weightSum; double covarianceMatrix[9] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; for(i = 0; i < coord.GetSize(); i++) { CxDVector3 v1 = coord[i] - centroid; CxDVector3 v2 = _refCentroidCoord[i]; for(k = 0; k < 3; k++) { for(l = 0; l < 3; l++) { covarianceMatrix[k*3+l] += v1[k] * v2[l] * _weights[i]; } } } //************** NEW ******************** // double sValues[3]; // double vMatrix[9]; // ComputeSVD_Flat(covarianceMatrix, 3, 3, sValues, vMatrix); // // for(int j = 0; j < 3; j++) { // for(int k = 0; k < 3; k++) { // _rotationMatrix[3*j+k] = 0.0f; // for(int l = 0; l < 3; l++) { // _rotationMatrix[3*j+k] += vMatrix[3*j+l] * covarianceMatrix[3*k+l]; // } // } // } // // double determinant = _rotationMatrix[0]*_rotationMatrix[4]*_rotationMatrix[8] + _rotationMatrix[1]*_rotationMatrix[5]*_rotationMatrix[6] + _rotationMatrix[2]*_rotationMatrix[3]*_rotationMatrix[7] - _rotationMatrix[2]*_rotationMatrix[4]*_rotationMatrix[6] - _rotationMatrix[1]*_rotationMatrix[3]*_rotationMatrix[8] - _rotationMatrix[0]*_rotationMatrix[5]*_rotationMatrix[7]; // if(determinant < 0.0f) { // for(int j = 0; j < 3; j++) { // for(int k = 0; k < 3; k++) { // _rotationMatrix[3*j+k] = 0.0f; // for(int l = 0; l < 3; l++) { // _rotationMatrix[3*j+k] += vMatrix[3*j+l] * covarianceMatrix[3*k+l] * (l == 0 ? -1.0f : 1.0f); // } // } // } // } //*************************************** //************* NEW 2 ******************* double sValues[3]; double uMatrix[9]; double vMatrix[9]; SVD_3x3(covarianceMatrix, sValues, uMatrix, vMatrix); for(j = 0; j < 3; j++) { for(k = 0; k < 3; k++) { _rotationMatrix[3*j+k] = 0.0; for(l = 0; l < 3; l++) { _rotationMatrix[3*j+k] += vMatrix[3*j+l] * uMatrix[3*k+l]; } } } double determinant = _rotationMatrix[0]*_rotationMatrix[4]*_rotationMatrix[8] + _rotationMatrix[1]*_rotationMatrix[5]*_rotationMatrix[6] + _rotationMatrix[2]*_rotationMatrix[3]*_rotationMatrix[7] - _rotationMatrix[2]*_rotationMatrix[4]*_rotationMatrix[6] - _rotationMatrix[1]*_rotationMatrix[3]*_rotationMatrix[8] - _rotationMatrix[0]*_rotationMatrix[5]*_rotationMatrix[7]; if(determinant < 0.0) { for(j = 0; j < 3; j++) { for(k = 0; k < 3; k++) { _rotationMatrix[3*j+k] = 0.0; for(l = 0; l < 3; l++) { _rotationMatrix[3*j+k] += vMatrix[3*j+l] * uMatrix[3*k+l] * (l == 2 ? -1.0 : 1.0); } } } } //*************************************** // double sValues[3]; // double uMatrix[9]; // double vtMatrix[9]; // singularValueDecompose_3x3(covarianceMatrix, sValues, uMatrix, vtMatrix); // // if(vtMatrix[0]*vtMatrix[4]*vtMatrix[8] + vtMatrix[1]*vtMatrix[5]*vtMatrix[6] + vtMatrix[2]*vtMatrix[3]*vtMatrix[7] - vtMatrix[2]*vtMatrix[4]*vtMatrix[6] - vtMatrix[1]*vtMatrix[3]*vtMatrix[8] - vtMatrix[0]*vtMatrix[5]*vtMatrix[7] < 0) { // int j; // for(j = 0; j < 3; j++) { // vtMatrix[6+j] *= -1.0f; // } // } // // int j; // for(j = 0; j < 3; j++) { // int k; // for(k = 0; k < 3; k++) { // _rotationMatrix[3*k+j] = 0.0f; // int l; // for(l = 0; l < 3; l++) { // _rotationMatrix[3*k+j] += uMatrix[3*j+l] * vtMatrix[3*l+k]; // } // } // } for(j = 0; j < 3; j++) { _translationVector[j] = _refCentroid[j]; for(k = 0; k < 3; k++) { _translationVector[j] -= _rotationMatrix[3*j+k] * centroid[k]; } } } bool CEckartReferenceStructure::recognizeMolecule(CTimeStep *ts) { bool ok = true; unsigned int *stack; int i, j; try { stack = new unsigned int[ts->m_iGesAtomCount]; } catch(...) { stack = NULL; } if(stack == NULL) NewException((double)ts->m_iGesAtomCount*sizeof(int), __FILE__, __LINE__, __PRETTY_FUNCTION__); bool *used; try { used = new bool[ts->m_iGesAtomCount]; } catch(...) { used = NULL; } if(used == NULL) NewException((double)ts->m_iGesAtomCount*sizeof(int), __FILE__, __LINE__, __PRETTY_FUNCTION__); for(i = 0; (unsigned int)i < ts->m_iGesAtomCount; i++) { used[i] = false; } CxByteArray baAtomIndex; baAtomIndex.SetSize(ts->m_iGesAtomCount); for(i = 0; (unsigned int)i < ts->m_iGesAtomCount; i++) { // char buf[64]; CxString buf; // strncpy(buf, (char *)(ts->m_paLabels[i]), 64); // buf[63] = 0; buf.strcpy((char *)(ts->m_paLabels[i])); ReplaceDigits(&buf); baAtomIndex[i] = 255; for(j = 0; j < g_oaAtoms.GetSize(); j++) { if(mystricmp(buf, ((CAtom *)g_oaAtoms[j])->m_sName) == 0) { CAtom *a = (CAtom *)g_oaAtoms[j]; while(a->m_pMergedTo != NULL) a = a->m_pMergedTo; baAtomIndex[i] = (unsigned char)a->m_iIndex; break; } } if(baAtomIndex[i] == 255) { mprintf(RED, "Atom type \"%s\" not known\n", (const char*)buf); ok = false; } } if(ok) { recognizeMoleculeRecursion(0, used, 0, stack, ts, baAtomIndex); for(i = 0; (unsigned int)i < ts->m_iGesAtomCount; i++) { if(!used[i]) { mprintf(RED, "Some atoms are not connected to the molecule\n"); ok = false; break; } } } if(ok) { mprintf(" Recognized one molecule\n"); mprintf(" Sorting atom types...\n"); for(i = 0; i < _singleMol->m_baAtomIndex.GetSize() - 1; i++) { int a = -1; int b = 999; for(j = i; j < _singleMol->m_baAtomIndex.GetSize(); j++) { if(_singleMol->m_baAtomIndex[j] < b) { b = _singleMol->m_baAtomIndex[j]; a = j; } } if((a != -1) && (a != i)) { b = _singleMol->m_baAtomIndex[a]; _singleMol->m_baAtomIndex[a] = _singleMol->m_baAtomIndex[i]; _singleMol->m_baAtomIndex[i] = (unsigned char)b; for(j = 0; j < _singleMol->m_oaMolAtoms.GetSize(); j++) { if(((CMolAtom *)_singleMol->m_oaMolAtoms[j])->m_iType == i) ((CMolAtom *)_singleMol->m_oaMolAtoms[j])->m_iType = a; else if(((CMolAtom *)_singleMol->m_oaMolAtoms[j])->m_iType == a) ((CMolAtom *)_singleMol->m_oaMolAtoms[j])->m_iType = i; } } } mprintf(" Setting up bond list...\n"); for(i = 0; i < _singleMol->m_laBonds.GetSize() / 2; i++) { int a = _singleMol->m_laBonds[2*i]; int b = _singleMol->m_laBonds[2*i+1]; int c = -1; for(j = 0; j < _singleMol->m_oaMolAtoms.GetSize(); j++) { if(((CMolAtom *)_singleMol->m_oaMolAtoms[j])->m_iOffset == a) { c = j; break; } } if(c == -1) { eprintf("CEckartReferenceStructure::recognizeMolecule(): Internal error (1).\n"); abort(); } int d = -1; for(j = 0; j < _singleMol->m_oaMolAtoms.GetSize(); j++) { if(((CMolAtom *)_singleMol->m_oaMolAtoms[j])->m_iOffset == b) { d = j; break; } } if(d == -1) { eprintf("CEckartReferenceStructure::recognizeMolecule(): Internal error (2).\n"); abort(); } ((CMolAtom *)_singleMol->m_oaMolAtoms[c])->m_oaBonds.Add((CMolAtom *)_singleMol->m_oaMolAtoms[d]); ((CMolAtom *)_singleMol->m_oaMolAtoms[d])->m_oaBonds.Add((CMolAtom *)_singleMol->m_oaMolAtoms[c]); } mprintf(" Building atom codes...\n"); _singleMol->BuildAtomCodes(); mprintf(" Creating topological atom order...\n"); for(i = 0; i < _singleMol->m_baAtomIndex.GetSize(); i++) { CxIntArray *a; try { a = new CxIntArray(); } catch(...) { a = NULL; } if(a == NULL) NewException((double)sizeof(CxIntArray), __FILE__, __LINE__, __PRETTY_FUNCTION__); _singleMol->m_oaAtomOffset.Add(a); for(j = 0; j < _singleMol->m_oaMolAtoms.GetSize(); j++) { if(((CMolAtom *)_singleMol->m_oaMolAtoms[j])->m_iType == i) { ((CMolAtom *)_singleMol->m_oaMolAtoms[j])->m_iNumber = a->GetSize(); a->Add(((CMolAtom *)_singleMol->m_oaMolAtoms[j])->m_iOffset); } } } mprintf(" Comparing to global molecule types...\n"); int molType = -1; for(i = 0; i < g_oaMolecules.GetSize(); i++) { CSingleMolecule *compMol = (CSingleMolecule *)g_oaSingleMolecules[((CMolecule *)g_oaMolecules[i])->m_laSingleMolIndex[0]]; if(_singleMol->m_oaMolAtoms.GetSize() != compMol->m_oaMolAtoms.GetSize()) continue; bool diff = false; for(j = 0; j < _singleMol->m_oaMolAtoms.GetSize(); j++) { if(((CMolAtom *)_singleMol->m_oaMolAtoms[j])->m_liAtomCode != ((CMolAtom *)compMol->m_oaMolAtoms[j])->m_liAtomCode) { diff = true; break; } } if(!diff) { molType = i; break; } } if(molType == -1) { ok = false; mprintf(RED, "The reference structure does not belong to any molecule type\n"); } else { _singleMol->m_iMolType = molType; mprintf(" The reference structure belongs to molecule type %d (%s)\n", _singleMol->m_iMolType+1, ((CMolecule *)g_oaMolecules[_singleMol->m_iMolType])->m_sName); // _atomCount = _singleMol->m_oaMolAtoms.GetSize(); } } mprintf("\n"); delete[] used; delete[] stack; return ok; } void CEckartReferenceStructure::recognizeMoleculeRecursion(unsigned int index, bool *used, int depth, unsigned int *stack, CTimeStep *ts, CxByteArray &baAtomIndex) { int i, j; if(g_bVerbose) { mprintf(" "); for(i = 1; i < depth; i++) mprintf(" "); if(depth > 0) mprintf(WHITE, "\\--"); mprintf(CYAN, "%s", (const char*)((CAtom *)g_oaAtoms[baAtomIndex[index]])->m_sName); mprintf("(%d)", index+1); } stack[depth] = index; used[index] = true; bool found = false; for(i = 0; i < _singleMol->m_baAtomIndex.GetSize(); i++) { if(_singleMol->m_baAtomIndex[i] == baAtomIndex[index]) { CMolAtom *molAtom; try { molAtom = new CMolAtom(); } catch(...) { molAtom = NULL; } if(molAtom == NULL) NewException((double)sizeof(CMolAtom), __FILE__, __LINE__, __PRETTY_FUNCTION__); molAtom->m_iOffset = index; molAtom->m_iType = i; _singleMol->m_oaMolAtoms.Add(molAtom); found = true; break; } } if(!found) { CMolAtom *molAtom; try { molAtom = new CMolAtom(); } catch(...) { molAtom = NULL; } if(molAtom == NULL) NewException((double)sizeof(CMolAtom), __FILE__, __LINE__, __PRETTY_FUNCTION__); molAtom->m_iOffset = index; molAtom->m_iType = _singleMol->m_baAtomIndex.GetSize(); _singleMol->m_oaMolAtoms.Add(molAtom); _singleMol->m_baAtomIndex.Add(baAtomIndex[index]); } int numNeighbors = 0; int neighborList[MAX_BONDS]; for(i = 0; (unsigned int)i < ts->m_iGesAtomCount; i++) { if((unsigned int)i == index) continue; if(((CAtom *)g_oaAtoms[baAtomIndex[index]])->m_bExclude) continue; double distance; if(recognizeMoleculeBondRange(ts, index, i, &distance, baAtomIndex)) { if(used[i]) { if((depth > 0) && ((unsigned int)i != stack[depth-1])) { if(_singleMol->m_oaRings.GetSize() < 100) { if(g_bVerbose) { mprintf(GREEN, " <-- Ring closure: "); mprintf("%s(%d)", (const char*)((CAtom *)g_oaAtoms[baAtomIndex[stack[depth]]])->m_sName, stack[depth]+1); } CxIntArray *ring; try { ring = new CxIntArray(); } catch(...) { ring = NULL; } if(ring == NULL) NewException((double)sizeof(CxIntArray), __FILE__, __LINE__, __PRETTY_FUNCTION__); _singleMol->m_oaRings.Add(ring); ring->Add(stack[depth]); for(j = depth - 1; (stack[j] != (unsigned int)i) && (j >= 0); j--) { ring->Add(stack[j]); if(g_bVerbose) mprintf(" - %s(%d)", (const char*)((CAtom *)g_oaAtoms[baAtomIndex[stack[j]]])->m_sName, stack[j]+1); } ring->Add(i); if(g_bVerbose) mprintf(" - %s(%d)", (const char*)((CAtom *)g_oaAtoms[baAtomIndex[i]])->m_sName, i+1); } else { mprintf(RED, "More than 100 rings\n"); } } continue; } if(distance < 50.0) { mprintf(RED, "Atoms %s(%d) and %s(%d) are very close to each other: %.4f pm\n", (const char*)((CAtom *)g_oaAtoms[baAtomIndex[index]])->m_sName, index + 1, (const char*)((CAtom *)g_oaAtoms[baAtomIndex[i]])->m_sName, i + 1, distance); } neighborList[numNeighbors++] = i; if(numNeighbors >= MAX_BONDS) { mprintf(RED, "Atom %s(%d) has more than %d bonds\n", (const char*)((CAtom *)g_oaAtoms[baAtomIndex[index]])->m_sName, index + 1, MAX_BONDS); break; } } } if(g_bVerbose) mprintf("\n"); for(i = 0; i < numNeighbors; i++) { _singleMol->m_laBonds.Add(index); _singleMol->m_laBonds.Add(neighborList[i]); if(!used[neighborList[i]]) { recognizeMoleculeRecursion(neighborList[i], used, depth+1, stack, ts, baAtomIndex); } } } bool CEckartReferenceStructure::recognizeMoleculeBondRange(CTimeStep *ts, int i1, int i2, double *distance, CxByteArray &baAtomIndex) { double x = ts->m_vaCoords[i1][0] - ts->m_vaCoords[i2][0]; double y = ts->m_vaCoords[i1][1] - ts->m_vaCoords[i2][1]; double z = ts->m_vaCoords[i1][2] - ts->m_vaCoords[i2][2]; if(g_bPeriodic) { if(g_bPeriodicX) { while(x < -g_fBoxX/2) x += g_fBoxX; while(x > g_fBoxX/2) x -= g_fBoxX; } if(g_bPeriodicY) { while(y < -g_fBoxY/2) y += g_fBoxY; while(y > g_fBoxY/2) y -= g_fBoxY; } if(g_bPeriodicZ) { while(z < -g_fBoxZ/2) z += g_fBoxZ; while(z > g_fBoxZ/2) z -= g_fBoxZ; } } *distance = sqrt(x*x + y*y + z*z); return *distance < (((CAtom *)g_oaAtoms[baAtomIndex[i1]])->m_pElement->m_fRadius + ((CAtom *)g_oaAtoms[baAtomIndex[i2]])->m_pElement->m_fRadius) * g_fBondFactor; } static CEckartReferenceStructure *g_eckartReferenceStructure; static FILE *g_eckartTransformFile; bool gatherEckartTransform() { try { g_eckartReferenceStructure = new CEckartReferenceStructure(); } catch(...) { g_eckartReferenceStructure = NULL; } if(g_eckartReferenceStructure == NULL) NewException((double)sizeof(CEckartReferenceStructure), __FILE__, __LINE__, __PRETTY_FUNCTION__); if(g_bXYZ4thCol) g_bReadChargesFrom4thXYZ = true; return true; } bool initializeEckartTransform() { char filename[BUF_SIZE]; #ifdef TARGET_LINUX char buf[BUF_SIZE]; strncpy(buf, g_sInputTraj, BUF_SIZE); buf[BUF_SIZE-1] = 0; char *p = strrchr(buf, '/'); if(p == NULL) p = buf; else p++; size_t s = strcspn(p, "."); if(s > BUF_SIZE - 8) s = BUF_SIZE - 8; strncpy(filename, p, s); filename[s] = 0; strcat(filename, "_out.xyz"); #else sprintf(filename, "out.xyz"); #endif mprintf(" Saving processed trajectory as %s\n\n", filename); g_eckartTransformFile = OpenFileWrite(filename, false); return true; } void processEckartTransform(CTimeStep *ts) { g_eckartReferenceStructure->process(ts); fprintf(g_eckartTransformFile, "%d\n", g_iGesAtomCount); if(ts->m_pComment != NULL) fprintf(g_eckartTransformFile, "%s\n", ts->m_pComment); else fprintf(g_eckartTransformFile, "\n"); int i; for(i = 0; i < g_iGesAtomCount; i++) { CxDVector3 newCoord = g_eckartReferenceStructure->translationVector(); int j; for(j = 0; j < 3; j++) { int k; for(k = 0; k < 3; k++) { newCoord[j] += g_eckartReferenceStructure->rotationMatrix()[3*j+k] * ts->m_vaCoords[i][k]; } } if(g_bReadChargesFrom4thXYZ) { fprintf(g_eckartTransformFile, "%2s %10.5f %10.5f %10.5f %10.5f\n", g_waAtomRealElement[i] == 60000 ? "X" : (const char*)((CAtom *)g_oaAtoms[g_waAtomRealElement[i]])->m_sName, newCoord[0] / 100.0, newCoord[1] / 100.0, newCoord[2] / 100.0, ts->m_faCharge[i]); } else { fprintf(g_eckartTransformFile, "%2s %10.5f %10.5f %10.5f\n", g_waAtomRealElement[i] == 60000 ? "X" : (const char*)((CAtom *)g_oaAtoms[g_waAtomRealElement[i]])->m_sName, newCoord[0] / 100.0, newCoord[1] / 100.0, newCoord[2] / 100.0); } } } void finalizeEckartTransform() { delete g_eckartReferenceStructure; fclose(g_eckartTransformFile); } travis-src-190101/src/normalcoordinate.h0100777000000000000000000001244213412725667015162 0ustar00/***************************************************************************** TRAVIS - Trajectory Analyzer and Visualizer http://www.travis-analyzer.de/ Copyright (c) 2009-2019 Martin Brehm 2012-2019 Martin Thomas 2016-2019 Sascha Gehrke This file was written by Martin Thomas. --------------------------------------------------------------------------- This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . *****************************************************************************/ #ifndef NORMALCOORDINATE_H #define NORMALCOORDINATE_H // This must always be the first include directive #include "config.h" #include "moltools.h" #include "xdoublearray.h" #include "xintarray.h" #include "xobject.h" #include "xobarray.h" #include "xdvector3.h" class CTimeStep; class CxByteArray; class CxDVec3Array; class CNormalCoordinateObservation; class CReferenceStructure: public CxObject { public: CReferenceStructure(int showMol, const char *basename, bool calcIR); ~CReferenceStructure(); void initialize(const char *basename); void processCoordinates(CxDVec3Array &coord, CxDVector3 &dipole, int showMol); void calcVelocities(int showMol); double calcMinimumDistance(int showMol, bool useInternals, CxObArray &internals); void nextStep(); double getMinimumDistance(int showMol, int step); void setGlobalProbability(int showMol, int step, double prob); void finalize(const char *basename); private: CTimeStep *_refTimestep; CSingleMolecule *_singleMol; int _showMolCount; int _atomCount; int _permutationCount; int _numSteps; bool _writeTransformedTrajectories; FILE **_transformedTrajectoryFiles; CxObArray _permutations; CxDVector3 _centroid; CxObArray _centroidCoords; CxDoubleArray _weights; double _weightSum; char _filename[128]; CxObArray _distanceTimedev; CxObArray _coordHistory; int _historyIndex; bool _calcVelocity; CxObArray _velocityCache; CxObArray _globalProb; bool _useInternals; CxObArray _internals; double _gaussianWidth; int _correlationDepth; int _windowFunction; int _windowFunctionParameter; double _specResolution; int _specSize; int _zeroPadding; double _convergenceThreshold; int _maxIterations; bool _calcIR; CxObArray _dipoleHistory; CxObArray _dipoleDerivativeCache; bool recognizeMolecule(CTimeStep *ts, int showMol, const char *basename); void recognizeMoleculeRecursion(unsigned int index, bool *used, int depth, unsigned int *stack, CTimeStep *ts, CxByteArray &baAtomIndex); bool recognizeMoleculeBondRange(CTimeStep *ts, int i1, int i2, double *distance, CxByteArray &baAtomIndex); void askPermutations(CxIntArray *actions); void createPermutationsRecursion(int start, CxIntArray *permutation, CxIntArray *permutationActions); double offDiagonalNorm(CxObArray &matrix); double findRotationAngle(CxObArray &matrix, int i, int j); void calcIntegrals(CxObArray &matrix, CxDoubleArray *integrals, CxDoubleArray *centers); }; class CNormalCoordinateObservation: public CObservation { public: CNormalCoordinateObservation(); ~CNormalCoordinateObservation(); void initialize(); void process(CTimeStep *ts); void finalize(); private: CxObArray _refStructures; int _refCount; int _numSteps; double _gaussianWidth; //int _correlationDepth; CxObArray _distanceTimedev; bool _useInternals; CxObArray _internals; bool _calcIR; // bool _writeTransformedTrajectories; // FILE **_transformedTrajectoryFiles; // CxObArray _distanceTimedev; // CxObArray _coordHistory; // int _historyIndex; // bool _calcVelocity; // CxObArray _velocityCache; }; bool gatherNormalCoordinate(); bool initializeNormalCoordinate(); void processNormalCoordinate(CTimeStep *ts); void finalizeNormalCoordinate(); class CEckartReferenceStructure: public CxObject { public: CEckartReferenceStructure(); ~CEckartReferenceStructure(); void process(CTimeStep *ts); const double *rotationMatrix() { return _rotationMatrix; } const CxDVector3 &translationVector() { return _translationVector; } private: CTimeStep *_refTimestep; CSingleMolecule *_singleMol; char _filename[128]; int _singleMolIndex; CAtomGroup *_mapAtoms; CxDVector3 _refCentroid; CxDVec3Array _refCentroidCoord; CxDoubleArray _weights; double _weightSum; double _rotationMatrix[9]; CxDVector3 _translationVector; bool recognizeMolecule(CTimeStep *ts); void recognizeMoleculeRecursion(unsigned int index, bool *used, int depth, unsigned int *stack, CTimeStep *ts, CxByteArray &baAtomIndex); bool recognizeMoleculeBondRange(CTimeStep *ts, int i1, int i2, double *distance, CxByteArray &baAtomIndex); }; bool gatherEckartTransform(); bool initializeEckartTransform(); void processEckartTransform(CTimeStep *ts); void finalizeEckartTransform(); #endif travis-src-190101/src/normalmode.cpp0100777000000000000000000006332613412725626014314 0ustar00/***************************************************************************** TRAVIS - Trajectory Analyzer and Visualizer http://www.travis-analyzer.de/ Copyright (c) 2009-2019 Martin Brehm 2012-2019 Martin Thomas 2016-2019 Sascha Gehrke This file was written by Martin Thomas. --------------------------------------------------------------------------- This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . *****************************************************************************/ // This must always be the first include directive #include "config.h" #include "normalmode.h" #include "acf.h" #include "globalvar.h" #include "tools.h" #include "xdoublearray.h" #include "xobarray.h" #include const char *GetRevisionInfo_normalmode(unsigned int len) { static char buf[256]; GET_REVISION_INFO( buf, len ); return buf; } const char *GetSourceVersion_normalmode() { static char buf[256]; GET_SOURCE_VERSION( buf ); return buf; } static double g_freqStep; static CxDoubleArray *g_transMatrix; static double findRotationAngle(int n, CxObArray *cc_matrix, int i, int j) { CxDoubleArray *aii = (CxDoubleArray *)cc_matrix->GetAt(i * n + i); CxDoubleArray *aij = (CxDoubleArray *)cc_matrix->GetAt(i * n + j); CxDoubleArray *ajj = (CxDoubleArray *)cc_matrix->GetAt(j * n + j); double int1 = 0.0, int2 = 0.0, int3 = 0.0; int k; for(k = 0; k < aij->GetSize(); k++) { // if(fabs(aij->GetAt(k)) > 1.0e7f) int1 += aij->GetAt(k) * aij->GetAt(k); // if((fabs(aij->GetAt(k)) > 1.0e7f) && (fabs(aii->GetAt(k)-ajj->GetAt(k)) > 1.0e7f)) int2 += aij->GetAt(k) * (aii->GetAt(k) - ajj->GetAt(k)); // if(fabs(aii->GetAt(k)-ajj->GetAt(k)) > 1.0e7f) int3 += (aii->GetAt(k) - ajj->GetAt(k)) * (aii->GetAt(k) - ajj->GetAt(k)); } int1 *= (double)g_freqStep; int2 *= (double)g_freqStep; int3 *= (double)g_freqStep; // mprintf(RED, "---\n(%d, %d) int1 = %30g int2 = %30g int3 = %30g\n", i, j, int1, int2, int3); if(fabs(int2) < 1.0) { // mprintf(RED, "int2 < 1.0\n"); double f = 4.0 * int1 - int3; // mprintf(RED, "f = %30g\n", f); if((fabs(int1) < 1.0) && (fabs(int2) < 1.0) && (fabs(int3) < 1.0)) return 0.0; if(0.5 * f > 0.0) return 1.0; if(-2.0 * f > 0.0) return 0.0; } else { // mprintf(RED, "int2 >= 1.0\n"); double f = (4.0 * int1 - int3) / int2; double r[2][2]; double s[2][2]; for(k = 0; k < 2; k++) { int l; for(l = 0; l < 2; l++) { // double r = (-f + (k == 0 ? -1.0 : 1.0) * sqrt(16.0 + f * f) + (l == 0 ? -1.0 : 1.0) * sqrt(2.0) * sqrt(16.0 + f * f - (k == 0 ? -1.0 : 1.0) * f * sqrt(16.0 + f * f))) / 4.0; // double s = -2.0 * int2 / pow(r * r + 1.0, 4.0) * (2.0 * r * (pow(r, 4.0) - 14.0 * r * r + 9.0) + f * (3.0 * pow(r, 4.0) - 8.0 * r * r + 1.0)); // if((fabs(r) <= 1.0) && (s > 0.0)) // return (double)r; r[k][l] = (-f + (k == 0 ? -1.0 : 1.0) * sqrt(16.0 + f * f) + (l == 0 ? -1.0 : 1.0) * sqrt(2.0) * sqrt(16.0 + f * f - (k == 0 ? -1.0 : 1.0) * f * sqrt(16.0 + f * f))) / 4.0; s[k][l] = -2.0 * int2 / pow4(r[k][l] * r[k][l] + 1.0) * (2.0 * r[k][l] * (pow4(r[k][l]) - 14.0 * r[k][l] * r[k][l] + 9.0) + f * (3.0 * pow4(r[k][l]) - 8.0 * r[k][l] * r[k][l] + 1.0)); // mprintf(RED, "t = %10g, s = %30g\n", r[k][l], s[k][l]); } } for(k = 0; k < 2; k++) { int l; for(l = 0; l < 2; l++) { if((fabs(r[k][l]) <= 1.0) && (s[k][l] > 0.0)) return r[k][l]; } } } // double f = (4.0 * int1 - int3) / int2; // double r[2][2]; // double s[2][2]; // for(k = 0; k < 2; k++) { // int l; // for(l = 0; l < 2; l++) { // double r = (-f + (k == 0 ? -1.0 : 1.0) * sqrt(16.0 + f * f) + (l == 0 ? -1.0 : 1.0) * sqrt(2.0) * sqrt(16.0 + f * f - (k == 0 ? -1.0 : 1.0) * f * sqrt(16.0 + f * f))) / 4.0; // double s = -2.0 * int2 / pow(r * r + 1.0, 4.0) * (2.0 * r * (pow(r, 4.0) - 14.0 * r * r + 9.0) + f * (3.0 * pow(r, 4.0) - 8.0 * r * r + 1.0)); // if((fabs(r) <= 1.0) && (s >= 0.0)) // return (double)r; // r[k][l] = (-f + (k == 0 ? -1.0 : 1.0) * sqrt(16.0 + f * f) + (l == 0 ? -1.0 : 1.0) * sqrt(2.0) * sqrt(16.0 + f * f - (k == 0 ? -1.0 : 1.0) * f * sqrt(16.0 + f * f))) / 4.0; // s[k][l] = -2.0 * int2 / pow(r[k][l] * r[k][l] + 1.0, 4.0) * (2.0 * r[k][l] * (pow(r[k][l], 4.0) - 14.0 * r[k][l] * r[k][l] + 9.0) + f * (3.0 * pow(r[k][l], 4.0) - 8.0 * r[k][l] * r[k][l] + 1.0)); // mprintf(RED, "r = %10.6f, s = %30.2f\n", r[k][l], s[k][l]); // } // } // for(k = 0; k < 2; k++) { // int l; // for(l = 0; l < 2; l++) { // if((fabs(r[k][l]) <= 1.0f) && (s[k][l] >= 0.0f)) // return r[k][l]; // } // } mprintf(RED, "No suitable rotation angle found. Aborting.\n"); return 0.1; // abort(); } static double offDiagonalNorm(int n, CxObArray *cc_matrix) { double norm = 0.0; int i, j, k; // mprintf("@"); for(i = 0; i < n; i++) { for(j = i + 1; j < n; j++) { double integral = 0.0; CxDoubleArray *fa = (CxDoubleArray *)cc_matrix->GetAt(i * n + j); for(k = 0; k < fa->GetSize(); k++) { // if(fabs(fa->GetAt(k)) > 1.0e7f) integral += fa->GetAt(k) * fa->GetAt(k); } integral *= g_freqStep; // mprintf("%14g ", integral); norm += integral; } // mprintf("\n@"); } // mprintf("\n"); return sqrt(norm); } void normalModeAnalysis(int n, CxObArray *cc_matrix) { mprintf(" Fourier transforming cross correlation matrix...\n"); mprintf(WHITE, " ["); int i, j, k; for(i = 0; i < n; i++) { for(j = 0; j < n; j++) { CxDoubleArray *temp; try { temp = new CxDoubleArray("normalModeAnalysis():temp"); } catch(...) { temp = NULL; } if(temp == NULL) NewException((double)sizeof(CxDoubleArray), __FILE__, __LINE__, __PRETTY_FUNCTION__); temp->CopyFrom((CxDoubleArray *)cc_matrix->GetAt(i * n + j)); if(g_pGlobalVACF->m_bWindowFunction) { for(k = 0; k < temp->GetSize(); k++) { temp->GetAt(k) *= pow2(cos(k / temp->GetSize() / 2.0 * Pi)); } } if(g_pGlobalVACF->m_iZeroPadding > 0) { for(k = 0; k < g_pGlobalVACF->m_iZeroPadding; k++) { temp->Add(0.0); } } if(g_pGlobalVACF->m_iMirror != 0) { int oldSize = temp->GetSize(); temp->SetSize(2 * oldSize); for(k = 1; k < oldSize; k++) { temp->GetAt(oldSize + k) = temp->GetAt(oldSize - k); } } CFFT *fft; try { fft = new CFFT(); } catch(...) { fft = NULL; } if(fft == NULL) NewException((double)sizeof(fft), __FILE__, __LINE__, __PRETTY_FUNCTION__); fft->PrepareFFT_C2C(temp->GetSize()); for(k = 0; k < temp->GetSize(); k++) { fft->m_pInput[2 * k] = temp->GetAt(k); fft->m_pInput[2 * k + 1] = 0.0; } fft->DoFFT(); ((CxDoubleArray *)cc_matrix->GetAt(i * n + j))->SetSize(temp->GetSize()); for(k = 0; k < temp->GetSize(); k++) { ((CxDoubleArray *)cc_matrix->GetAt(i * n + j))->GetAt(k) = fft->m_pOutput[2 * k]; } delete fft; delete temp; // CxFloatArray *temp; // try { temp = new CxFloatArray(); } catch(...) { temp = NULL; } // if(temp == NULL) NewException((double)sizeof(CxFloatArray), __FILE__, __LINE__, __PRETTY_FUNCTION__); // temp->CopyFrom((CxFloatArray *)cc_matrix->GetAt(i * n + j)); // if(g_pGlobalVACF->m_bWindowFunction) { // for(k = 0; k < temp->GetSize(); k++) { // temp->GetAt(k) *= pow(cos((double)k / temp->GetSize() / 2.0 * Pi), 2.0); // } // } // if(g_pGlobalVACF->m_iZeroPadding > 0) { // for(k = 0; k < g_pGlobalVACF->m_iZeroPadding; k++) { // temp->Add(0.0f); // } // } // if(g_pGlobalVACF->m_iMirror != 0) { // int oldSize = temp->GetSize(); // temp->SetSize(2 * oldSize); // for(k = 1; k < oldSize; k++) { // temp->GetAt(oldSize + k) = temp->GetAt(oldSize - k); // } // } // CFFT *fft; // try { fft = new CFFT(); } catch(...) { fft = NULL; } // if(fft == NULL) NewException((double)sizeof(fft), __FILE__, __LINE__, __PRETTY_FUNCTION__); // fft->PrepareFFT_C2C(temp->GetSize()); // for(k = 0; k < temp->GetSize(); k++) { // fft->m_pInput[2 * k] = temp->GetAt(k); // fft->m_pInput[2 * k + 1] = 0.0f; // } // fft->DoFFT(); // ((CxFloatArray *)cc_matrix->GetAt(i * n + j))->SetSize(temp->GetSize()); // for(k = 0; k < temp->GetSize(); k++) { // ((CxFloatArray *)cc_matrix->GetAt(i * n + j))->GetAt(k) = fft->m_pOutput[2 * k]; // } // delete fft; // delete temp; // CACF *tempACF; // try { tempACF = new CACF(); } catch(...) { tempACF = NULL; } // if(tempACF == NULL) NewException((double)sizeof(CACF), __FILE__, __LINE__, __PRETTY_FUNCTION__); // tempACF->m_iSize = ((CxFloatArray *)cc_matrix->GetAt(i * n + j))->GetSize(); // tempACF->m_bSpectrum = true; // tempACF->m_bWindowFunction = g_pGlobalVACF->m_bWindowFunction; // tempACF->m_fSpecWaveNumber = g_pGlobalVACF->m_fSpecWaveNumber; // tempACF->m_iMirror = g_pGlobalVACF->m_iMirror; // tempACF->m_iZeroPadding = g_pGlobalVACF->m_iZeroPadding; // tempACF->Create(); // for(k = 0; k < tempACF->m_iSize; k++) { // tempACF->m_pData[k] = ((CxFloatArray *)cc_matrix->GetAt(i * n + j))->GetAt(k); // } // if(tempACF->m_iMirror != 0) // tempACF->Mirror(tempACF->m_iMirror); // if(tempACF->m_bWindowFunction) // tempACF->Window(); // CFFT *fft; // try { fft = new CFFT(); } catch(...) { fft = NULL; } // if(fft == NULL) NewException((double)sizeof(fft), __FILE__, __LINE__, __PRETTY_FUNCTION__); // fft->PrepareFFT_C2C(tempACF->m_iSize + tempACF->m_iZeroPadding); // tempACF->Transform(fft); // delete fft; // ((CxFloatArray *)cc_matrix->GetAt(i * n + j))->SetSize(tempACF->m_pSpectrum->m_iSize); // for(k = 0; k < tempACF->m_pSpectrum->m_iSize; k++) { // ((CxFloatArray *)cc_matrix->GetAt(i * n + j))->GetAt(k) = tempACF->m_pSpectrum->m_pComplex[2*k]; // } // delete tempACF; } mprintf(WHITE, "#"); } mprintf(WHITE, "]\n"); g_freqStep = 1e15 / 299792458.0 / 100.0 / g_fTimestepLength / g_iStride / ((CxDoubleArray *)cc_matrix->GetAt(0))->GetSize(); mprintf(" Allocating transformation matrix...\n"); try { g_transMatrix = new CxDoubleArray("normalModeAnalysis():g_transMatrix"); } catch(...) { g_transMatrix = NULL; } if(g_transMatrix == NULL) NewException((double)sizeof(CxDoubleArray), __FILE__, __LINE__, __PRETTY_FUNCTION__); // g_transMatrix->SetSize(n * n); for(i = 0; i < n; i++) { for(j = 0; j < n; j++) { g_transMatrix->Add((i == j) ? 1.0 : 0.0); } } mprintf(" Saving transformation matrix\n"); FILE *matrixi_file = OpenFileWrite("transformation_matrix_i.dat", false); for(i = 0; i < n; i++) { for(j = 0; j < n; j++) { fprintf(matrixi_file, " %14g", g_transMatrix->GetAt(i * n + j)); } fprintf(matrixi_file, "\n"); } CxDoubleArray *speciSum; try { speciSum = new CxDoubleArray("normalModeAnalysis():speciSum"); } catch(...) { speciSum = NULL; } if(speciSum == NULL) NewException((double)sizeof(CxDoubleArray), __FILE__, __LINE__, __PRETTY_FUNCTION__); for(i = 0; i < ((CxDoubleArray *)cc_matrix->GetAt(0))->GetSize(); i++) speciSum->Add(0.0); for(i = 0; i < n; i++) { for(k = 0; k < ((CxDoubleArray *)cc_matrix->GetAt(i * n + i))->GetSize(); k++) { speciSum->GetAt(k) += ((CxDoubleArray *)cc_matrix->GetAt(i * n + i))->GetAt(k); } } FILE *speci_file = OpenFileWrite("normalmode_sum_initial.dat", false); for(k = 0; k * g_freqStep < g_pGlobalVACF->m_fSpecWaveNumber; k++) { fprintf(speci_file, "%14G %20G\n", k * g_freqStep, speciSum->GetAt(k)); } fclose(speci_file); delete(speciSum); for(i = 0; i < n; i++) { for(j = i; j < n; j++) { char name[128]; #ifdef TARGET_WINDOWS _snprintf(name, 128, "speci_%d_%d.dat", i, j); #elif defined TARGET_LINUX snprintf(name, 128, "speci_%d_%d.dat", i, j); #else sprintf(name, "speci_%d_%d.dat", i, j); #endif //FILE *speci_file = fopen(name, "w"); speci_file = fopen(name, "w"); for(k = 0; k * g_freqStep < g_pGlobalVACF->m_fSpecWaveNumber; k++) { fprintf(speci_file, "%14G %20G\n", k * g_freqStep, ((CxDoubleArray *)cc_matrix->GetAt(i * n + j))->GetAt(k)); } fclose(speci_file); } } mprintf(" Minimizing cross correlations...\n"); double norm = offDiagonalNorm(n, cc_matrix); mprintf(" %4d %20g\n", 0, norm); double change = norm; int count = 0; CxDoubleArray *tempMatrix; try { tempMatrix = new CxDoubleArray("normalModeAnalysis():tempMatrix"); } catch(...) { tempMatrix = NULL; } if(tempMatrix == NULL) NewException((double)sizeof(CxDoubleArray), __FILE__, __LINE__, __PRETTY_FUNCTION__); for(i = 0; i < n; i++) { tempMatrix->Add(0.0); } while(fabs(change) > 1.0e-3 * norm) { count++; for(i = 0; i < n; i++) { for(j = i + 1; j < n; j++) { double t = findRotationAngle(n, cc_matrix, i, j); double c = 1.0 / sqrt(t * t + 1.0); double s = t * c; // mprintf(RED, "(%d, %d) t = %10.6f c = %10.6f s = %10.6f\n", i, j, t, c, s); for(k = 0; k < ((CxDoubleArray *)cc_matrix->GetAt(0))->GetSize(); k++) { double temp[3]; int l; for(l = 0; l < j; l++) { if(l < i) { temp[0] = c * ((CxDoubleArray *)cc_matrix->GetAt(l * n + i))->GetAt(k) - s * ((CxDoubleArray *)cc_matrix->GetAt(l * n + j))->GetAt(k); temp[1] = s * ((CxDoubleArray *)cc_matrix->GetAt(l * n + i))->GetAt(k) + c * ((CxDoubleArray *)cc_matrix->GetAt(l * n + j))->GetAt(k); ((CxDoubleArray *)cc_matrix->GetAt(l * n + i))->GetAt(k) = temp[0]; ((CxDoubleArray *)cc_matrix->GetAt(l * n + j))->GetAt(k) = temp[1]; } else if(l > i) { tempMatrix->GetAt(l) = ((CxDoubleArray *)cc_matrix->GetAt(l * n + j))->GetAt(k); temp[1] = s * ((CxDoubleArray *)cc_matrix->GetAt(i * n + l))->GetAt(k) + c * ((CxDoubleArray *)cc_matrix->GetAt(l * n + j))->GetAt(k); ((CxDoubleArray *)cc_matrix->GetAt(l * n + j))->GetAt(k) = temp[1]; } } for(l = i + 1; l < n; l++) { if(l < j) { temp[0] = c * ((CxDoubleArray *)cc_matrix->GetAt(i * n + l))->GetAt(k) - s * tempMatrix->GetAt(l); ((CxDoubleArray *)cc_matrix->GetAt(i * n + l))->GetAt(k) = temp[0]; } else if(l > j) { temp[0] = c * ((CxDoubleArray *)cc_matrix->GetAt(i * n + l))->GetAt(k) - s * ((CxDoubleArray *)cc_matrix->GetAt(j * n + l))->GetAt(k); temp[1] = s * ((CxDoubleArray *)cc_matrix->GetAt(i * n + l))->GetAt(k) + c * ((CxDoubleArray *)cc_matrix->GetAt(j * n + l))->GetAt(k); ((CxDoubleArray *)cc_matrix->GetAt(i * n + l))->GetAt(k) = temp[0]; ((CxDoubleArray *)cc_matrix->GetAt(j * n + l))->GetAt(k) = temp[1]; } } temp[0] = c * c * ((CxDoubleArray *)cc_matrix->GetAt(i * n + i))->GetAt(k) + s * s * ((CxDoubleArray *)cc_matrix->GetAt(j * n + j))->GetAt(k) - 2 * c * s * ((CxDoubleArray *)cc_matrix->GetAt(i * n + j))->GetAt(k); temp[1] = (c * c - s * s) * ((CxDoubleArray *)cc_matrix->GetAt(i * n + j))->GetAt(k) + c * s * (((CxDoubleArray *)cc_matrix->GetAt(i * n + i))->GetAt(k) - ((CxDoubleArray *)cc_matrix->GetAt(j * n + j))->GetAt(k)); temp[2] = s * s * ((CxDoubleArray *)cc_matrix->GetAt(i * n + i))->GetAt(k) + c * c * ((CxDoubleArray *)cc_matrix->GetAt(j * n + j))->GetAt(k) + 2 * c * s * ((CxDoubleArray *)cc_matrix->GetAt(i * n + j))->GetAt(k); ((CxDoubleArray *)cc_matrix->GetAt(i * n + i))->GetAt(k) = temp[0]; ((CxDoubleArray *)cc_matrix->GetAt(i * n + j))->GetAt(k) = temp[1]; ((CxDoubleArray *)cc_matrix->GetAt(j * n + j))->GetAt(k) = temp[2]; // for(l = 0; l < n; l++) { // if(l < i) { // temp[0] = c * ((CxFloatArray *)cc_matrix->GetAt(l * n + i))->GetAt(k) - s * ((CxFloatArray *)cc_matrix->GetAt(l * n + j))->GetAt(k); // temp[1] = s * ((CxFloatArray *)cc_matrix->GetAt(l * n + i))->GetAt(k) + c * ((CxFloatArray *)cc_matrix->GetAt(l * n + j))->GetAt(k); // ((CxFloatArray *)cc_matrix->GetAt(i * n + l))->GetAt(k) = temp[0]; // ((CxFloatArray *)cc_matrix->GetAt(j * n + l))->GetAt(k) = temp[1]; // } else if(l < j) { // temp[0] = c * ((CxFloatArray *)cc_matrix->GetAt(i * n + l))->GetAt(k) - s * ((CxFloatArray *)cc_matrix->GetAt(l * n + j))->GetAt(k); // temp[1] = s * ((CxFloatArray *)cc_matrix->GetAt(i * n + l))->GetAt(k) + c * ((CxFloatArray *)cc_matrix->GetAt(l * n + j))->GetAt(k); // ((CxFloatArray *)cc_matrix->GetAt(i * n + l))->GetAt(k) = temp[0]; // ((CxFloatArray *)cc_matrix->GetAt(j * n + l))->GetAt(k) = temp[1]; // } else { //// for(l = 0; l < n; l++) { // temp[0] = c * ((CxFloatArray *)cc_matrix->GetAt(i * n + l))->GetAt(k) - s * ((CxFloatArray *)cc_matrix->GetAt(j * n + l))->GetAt(k); // temp[1] = s * ((CxFloatArray *)cc_matrix->GetAt(i * n + l))->GetAt(k) + c * ((CxFloatArray *)cc_matrix->GetAt(j * n + l))->GetAt(k); // ((CxFloatArray *)cc_matrix->GetAt(i * n + l))->GetAt(k) = temp[0]; // ((CxFloatArray *)cc_matrix->GetAt(j * n + l))->GetAt(k) = temp[1]; // } // } // for(l = n - 1; l >= 0; l--) { // if(l > j) { // temp[0] = c * ((CxFloatArray *)cc_matrix->GetAt(i * n + l))->GetAt(k) - s * ((CxFloatArray *)cc_matrix->GetAt(j * n + l))->GetAt(k); // temp[1] = s * ((CxFloatArray *)cc_matrix->GetAt(i * n + l))->GetAt(k) + c * ((CxFloatArray *)cc_matrix->GetAt(j * n + l))->GetAt(k); // ((CxFloatArray *)cc_matrix->GetAt(l * n + i))->GetAt(k) = temp[0]; // ((CxFloatArray *)cc_matrix->GetAt(l * n + j))->GetAt(k) = temp[1]; // } else if(l > i) { // temp[0] = c * ((CxFloatArray *)cc_matrix->GetAt(i * n + l))->GetAt(k) - s * ((CxFloatArray *)cc_matrix->GetAt(l * n + j))->GetAt(k); // temp[1] = s * ((CxFloatArray *)cc_matrix->GetAt(i * n + l))->GetAt(k) + c * ((CxFloatArray *)cc_matrix->GetAt(l * n + j))->GetAt(k); // ((CxFloatArray *)cc_matrix->GetAt(l * n + i))->GetAt(k) = temp[0]; // ((CxFloatArray *)cc_matrix->GetAt(l * n + j))->GetAt(k) = temp[1]; // } else { //// for(l = 0; l < n; l++) { // temp[0] = c * ((CxFloatArray *)cc_matrix->GetAt(l * n + i))->GetAt(k) - s * ((CxFloatArray *)cc_matrix->GetAt(l * n + j))->GetAt(k); // temp[1] = s * ((CxFloatArray *)cc_matrix->GetAt(l * n + i))->GetAt(k) + c * ((CxFloatArray *)cc_matrix->GetAt(l * n + j))->GetAt(k); //// ((CxFloatArray *)cc_matrix->GetAt(l * n + i))->GetAt(k) = temp[0]; // ((CxFloatArray *)cc_matrix->GetAt(l * n + j))->GetAt(k) = temp[1]; // } // } } double temp[2]; int l; for(l = 0; l < n; l++) { temp[0] = c * g_transMatrix->GetAt(i * n + l) - s * g_transMatrix->GetAt(j * n + l); temp[1] = s * g_transMatrix->GetAt(i * n + l) + c * g_transMatrix->GetAt(j * n + l); g_transMatrix->GetAt(i * n + l) = temp[0]; g_transMatrix->GetAt(j * n + l) = temp[1]; } // mprintf("@@ (%d, %d) %20g\n", i, j, offDiagonalNorm(n, cc_matrix)); } } double newNorm = offDiagonalNorm(n, cc_matrix); change = newNorm - norm; norm = newNorm; mprintf(" %4d %20g\n", count, norm); } delete tempMatrix; // double temp[9]; // for(k = 0; k < ((CxFloatArray *)cc_matrix->GetAt(0))->GetSize(); k++) { // temp[0] = -0.0259f * ((CxFloatArray *)cc_matrix->GetAt(0))->GetAt(k) - 0.978f * ((CxFloatArray *)cc_matrix->GetAt(3))->GetAt(k) + 0.209f * ((CxFloatArray *)cc_matrix->GetAt(6))->GetAt(k); // temp[1] = -0.0259f * ((CxFloatArray *)cc_matrix->GetAt(3))->GetAt(k) - 0.978f * ((CxFloatArray *)cc_matrix->GetAt(30))->GetAt(k) + 0.209f * ((CxFloatArray *)cc_matrix->GetAt(33))->GetAt(k); // temp[2] = -0.0259f * ((CxFloatArray *)cc_matrix->GetAt(6))->GetAt(k) - 0.978f * ((CxFloatArray *)cc_matrix->GetAt(33))->GetAt(k) + 0.209f * ((CxFloatArray *)cc_matrix->GetAt(60))->GetAt(k); // temp[3] = 0.986f * ((CxFloatArray *)cc_matrix->GetAt(0))->GetAt(k) + 0.009f * ((CxFloatArray *)cc_matrix->GetAt(3))->GetAt(k) + 0.164f * ((CxFloatArray *)cc_matrix->GetAt(6))->GetAt(k); // temp[4] = 0.986f * ((CxFloatArray *)cc_matrix->GetAt(3))->GetAt(k) + 0.009f * ((CxFloatArray *)cc_matrix->GetAt(30))->GetAt(k) + 0.164f * ((CxFloatArray *)cc_matrix->GetAt(33))->GetAt(k); // temp[5] = 0.986f * ((CxFloatArray *)cc_matrix->GetAt(6))->GetAt(k) + 0.009f * ((CxFloatArray *)cc_matrix->GetAt(33))->GetAt(k) + 0.164f * ((CxFloatArray *)cc_matrix->GetAt(60))->GetAt(k); // temp[6] = -0.163f * ((CxFloatArray *)cc_matrix->GetAt(0))->GetAt(k) + 0.210f * ((CxFloatArray *)cc_matrix->GetAt(3))->GetAt(k) + 0.964f * ((CxFloatArray *)cc_matrix->GetAt(6))->GetAt(k); // temp[7] = -0.163f * ((CxFloatArray *)cc_matrix->GetAt(3))->GetAt(k) + 0.210f * ((CxFloatArray *)cc_matrix->GetAt(30))->GetAt(k) + 0.964f * ((CxFloatArray *)cc_matrix->GetAt(33))->GetAt(k); // temp[8] = -0.163f * ((CxFloatArray *)cc_matrix->GetAt(6))->GetAt(k) + 0.210f * ((CxFloatArray *)cc_matrix->GetAt(33))->GetAt(k) + 0.964f * ((CxFloatArray *)cc_matrix->GetAt(60))->GetAt(k); // ((CxFloatArray *)cc_matrix->GetAt(0))->GetAt(k) = temp[0]; // ((CxFloatArray *)cc_matrix->GetAt(3))->GetAt(k) = temp[1]; // ((CxFloatArray *)cc_matrix->GetAt(6))->GetAt(k) = temp[2]; // ((CxFloatArray *)cc_matrix->GetAt(12))->GetAt(k) = temp[4]; // ((CxFloatArray *)cc_matrix->GetAt(15))->GetAt(k) = temp[5]; // ((CxFloatArray *)cc_matrix->GetAt(24))->GetAt(k) = temp[8]; // } // for(k = 0; k < ((CxFloatArray *)cc_matrix->GetAt(0))->GetSize(); k++) { // temp[0] = -0.0259f * ((CxFloatArray *)cc_matrix->GetAt(0))->GetAt(k) - 0.978f * ((CxFloatArray *)cc_matrix->GetAt(3))->GetAt(k) + 0.209f * ((CxFloatArray *)cc_matrix->GetAt(6))->GetAt(k); // temp[1] = -0.0259f * ((CxFloatArray *)cc_matrix->GetAt(3))->GetAt(k) - 0.978f * ((CxFloatArray *)cc_matrix->GetAt(30))->GetAt(k) + 0.209f * ((CxFloatArray *)cc_matrix->GetAt(33))->GetAt(k); // temp[2] = -0.0259f * ((CxFloatArray *)cc_matrix->GetAt(6))->GetAt(k) - 0.978f * ((CxFloatArray *)cc_matrix->GetAt(33))->GetAt(k) + 0.209f * ((CxFloatArray *)cc_matrix->GetAt(60))->GetAt(k); // temp[3] = 0.986f * ((CxFloatArray *)cc_matrix->GetAt(0))->GetAt(k) + 0.009f * ((CxFloatArray *)cc_matrix->GetAt(3))->GetAt(k) + 0.164f * ((CxFloatArray *)cc_matrix->GetAt(6))->GetAt(k); // temp[4] = 0.986f * ((CxFloatArray *)cc_matrix->GetAt(3))->GetAt(k) + 0.009f * ((CxFloatArray *)cc_matrix->GetAt(30))->GetAt(k) + 0.164f * ((CxFloatArray *)cc_matrix->GetAt(33))->GetAt(k); // temp[5] = 0.986f * ((CxFloatArray *)cc_matrix->GetAt(6))->GetAt(k) + 0.009f * ((CxFloatArray *)cc_matrix->GetAt(33))->GetAt(k) + 0.164f * ((CxFloatArray *)cc_matrix->GetAt(60))->GetAt(k); // temp[6] = -0.163f * ((CxFloatArray *)cc_matrix->GetAt(0))->GetAt(k) + 0.210f * ((CxFloatArray *)cc_matrix->GetAt(3))->GetAt(k) + 0.964f * ((CxFloatArray *)cc_matrix->GetAt(6))->GetAt(k); // temp[7] = -0.163f * ((CxFloatArray *)cc_matrix->GetAt(3))->GetAt(k) + 0.210f * ((CxFloatArray *)cc_matrix->GetAt(30))->GetAt(k) + 0.964f * ((CxFloatArray *)cc_matrix->GetAt(33))->GetAt(k); // temp[8] = -0.163f * ((CxFloatArray *)cc_matrix->GetAt(6))->GetAt(k) + 0.210f * ((CxFloatArray *)cc_matrix->GetAt(33))->GetAt(k) + 0.964f * ((CxFloatArray *)cc_matrix->GetAt(60))->GetAt(k); // ((CxFloatArray *)cc_matrix->GetAt(0))->GetAt(k) = temp[0]; // ((CxFloatArray *)cc_matrix->GetAt(3))->GetAt(k) = temp[1]; // ((CxFloatArray *)cc_matrix->GetAt(6))->GetAt(k) = temp[2]; // ((CxFloatArray *)cc_matrix->GetAt(30))->GetAt(k) = temp[4]; // ((CxFloatArray *)cc_matrix->GetAt(33))->GetAt(k) = temp[5]; // ((CxFloatArray *)cc_matrix->GetAt(60))->GetAt(k) = temp[8]; // } // for(k = 0; k < 4096; k++) { // int l; // for (l=0;l<81;l++) // ((CxFloatArray *)cc_matrix->GetAt(l))->GetAt(k) = 1000.0f; // } // mprintf(RED, "Old: %20g, New: %20g\n", norm, offDiagonalNorm(n, cc_matrix)); CxDoubleArray *specSum; try { specSum = new CxDoubleArray("normalModeAnalysis():specSum"); } catch(...) { specSum = NULL; } if(specSum == NULL) NewException((double)sizeof(CxDoubleArray), __FILE__, __LINE__, __PRETTY_FUNCTION__); for(i = 0; i < ((CxDoubleArray *)cc_matrix->GetAt(0))->GetSize(); i++) specSum->Add(0.0); mprintf(" Saving normal mode spectra...\n"); for(i = 0; i < n; i++) { char name[128]; #ifdef TARGET_WINDOWS _snprintf(name, 128, "normalmode_%d.dat", i); #elif defined TARGET_LINUX snprintf(name, 128, "normalmode_%d.dat", i); #else sprintf(name, "normalmode_%d.dat", i); #endif FILE *spec_file = OpenFileWrite(name, false); for(k = 0; k * g_freqStep < g_pGlobalVACF->m_fSpecWaveNumber; k++) { fprintf(spec_file, "%14G %20G\n", k * g_freqStep, ((CxDoubleArray *)cc_matrix->GetAt(i * n + i))->GetAt(k)); specSum->GetAt(k) += ((CxDoubleArray *)cc_matrix->GetAt(i * n + i))->GetAt(k); } fclose(spec_file); } mprintf(" Saving sum of normal mode spectra...\n"); FILE *spec_file = OpenFileWrite("normalmode_sum.dat", false); for(k = 0; k * g_freqStep < g_pGlobalVACF->m_fSpecWaveNumber; k++) { fprintf(spec_file, "%14G %20G\n", k * g_freqStep, specSum->GetAt(k)); } fclose(spec_file); delete specSum; for(i = 0; i < n; i++) { for(j = i + 1; j < n; j++) { char name[128]; #ifdef TARGET_WINDOWS _snprintf(name, 128, "spec_%d_%d.dat", i, j); #elif defined TARGET_LINUX snprintf(name, 128, "spec_%d_%d.dat", i, j); #else sprintf(name, "spec_%d_%d.dat", i, j); #endif //FILE *spec_file = fopen(name, "w"); spec_file = fopen(name, "w"); for(k = 0; k * g_freqStep < g_pGlobalVACF->m_fSpecWaveNumber; k++) { fprintf(spec_file, "%14G %20G\n", k * g_freqStep, ((CxDoubleArray *)cc_matrix->GetAt(i * n + j))->GetAt(k)); } fclose(spec_file); } } mprintf(" Saving transformation matrix\n"); FILE *matrix_file = OpenFileWrite("transformation_matrix.dat", false); for(i = 0; i < n; i++) { for(j = 0; j < n; j++) { fprintf(matrix_file, " %14g", g_transMatrix->GetAt(i * n + j)); } fprintf(matrix_file, "\n"); } fclose(matrix_file); delete g_transMatrix; } travis-src-190101/src/normalmode.h0100777000000000000000000000250413412725656013753 0ustar00/***************************************************************************** TRAVIS - Trajectory Analyzer and Visualizer http://www.travis-analyzer.de/ Copyright (c) 2009-2019 Martin Brehm 2012-2019 Martin Thomas 2016-2019 Sascha Gehrke This file was written by Martin Thomas. --------------------------------------------------------------------------- This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . *****************************************************************************/ #ifndef NORMALMODE_H #define NORMALMODE_H // This must always be the first include directive #include "config.h" class CxObArray; void normalModeAnalysis(int n, CxObArray *cc_matrix); #endif travis-src-190101/src/order.cpp0100777000000000000000000002466313412725630013266 0ustar00/***************************************************************************** TRAVIS - Trajectory Analyzer and Visualizer http://www.travis-analyzer.de/ Copyright (c) 2009-2019 Martin Brehm 2012-2019 Martin Thomas 2016-2019 Sascha Gehrke This file was written by Martin Brehm. --------------------------------------------------------------------------- This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . *****************************************************************************/ // This must always be the first include directive #include "config.h" #include "order.h" #include "order_chain.h" #include "order_vector.h" #include "globalvar.h" #include "largeinteger.h" const char *GetRevisionInfo_order(unsigned int len) { static char buf[256]; GET_REVISION_INFO( buf, len ); return buf; } const char *GetSourceVersion_order() { static char buf[256]; GET_SOURCE_VERSION( buf ); return buf; } void COrderEngine::REC_DetectChains(int depth, int pos, std::vector &touched) { int z, z2, i, nc, nh; CMolBond *mb; CElement *el; std::vector nbh; el = ((CAtom*)g_oaAtoms[g_waAtomRealElement[pos]])->m_pElement; if (mystricmp(el->m_sLabel,"C") != 0) return; // for (z=0;z>> REC %d >>>\n",pos); nh = 0; nc = 0; for (z=0;zm_oaBonds.GetSize();z++) { mb = (CMolBond*)m_pTempSM->m_oaBonds[z]; if (mb->m_iAtomOffset[0] == pos) i = mb->m_iAtomOffset[1]; else if (mb->m_iAtomOffset[1] == pos) i = mb->m_iAtomOffset[0]; else continue; el = ((CAtom*)g_oaAtoms[g_waAtomRealElement[i]])->m_pElement; if (mystricmp(el->m_sLabel,"C") == 0) { nc++; if (touched[i] == 0) nbh.push_back(i); goto _accept; } else { for (z2=0;z2<(int)m_saChainAllowedSub.size();z2++) { if (mystricmp(el->m_sLabel,m_saChainAllowedSub[z2].c_str()) == 0) { nh++; goto _accept; } } } nc++; _accept:; } // for (z=0;z 2) return; touched[pos] = 2; for (z=0;z<(int)nbh.size();z++) REC_DetectChains(depth+1,nbh[z],touched); // for (z=0;z tia, tlist; COrderChain *oc; LargeInteger li; CxString buf; char *p, *q, cbuf[16]; mprintf(" Detecting alkyl chains...\n\n"); m_iChainsTotal = 0; AskString(" Which elements to allow as carbon bond partners in alkyl chains? [H,D,F] ",&buf,"H,D,F"); p = buf.GetWritePointer(); while (*p != 0) { while (*p == ' ') p++; q = p; while ((*q != 0) && (*q != ',') && (*q != ' ')) q++; memcpy(cbuf,p,q-p); cbuf[q-p] = 0; m_saChainAllowedSub.push_back((const char*)cbuf); while ((*q == ' ') || (*q == ',')) q++; if (*q == 0) break; p = q; } mprintf("\n"); //for (z=0;z<(int)m_saChainAllowedSub.size();z++) // mprintf("\"%s\"\n",m_saChainAllowedSub[z].c_str()); tia.resize(g_iGesAtomCount); m_oaChains.resize(g_oaMolecules.GetSize()); ntot = 0; for (z=0;zm_laSingleMolIndex[0]]; mprintf(WHITE," %s ...\n",m->m_sName); ic = -1; for (z2=0;z2m_baAtomIndex.GetSize()-1;z2++) { if (mystricmp(((CAtom*)g_oaAtoms[m->m_baAtomIndex[z2]])->m_pElement->m_sLabel,"C") == 0) { ic = z2; break; } } if (ic == -1) { mprintf(" Does not contain carbon atoms.\n\n"); continue; } for (z2=0;z2m_laSingleMolIndex[0]) continue; if (tia[z2] != 0) continue; REC_DetectChains(0,z2,tia); n = 0; tlist.clear(); for (z3=0;z3m_oaAtomOffset[ic])->GetSize();z4++) { if (((CxIntArray*)m_pTempSM->m_oaAtomOffset[ic])->GetAt(z4) == z3) { // mprintf("C%d",z4+1); goto _done; } } eprintf("Internal error: Not a carbon atom.\n"); abort(); _done:*/ //b = true; n++; tia[z3] = 1; tlist.push_back(z3); } } // if (b) // mprintf(" (%d)\n",n); if (tlist.size() < 2) // Process further if at least an ethyl group continue; oc = new COrderChain(); m_iChainsTotal++; oc->m_iMolecule = z; oc->m_iCarbonIndex = ic; m_oaChains[z].push_back(oc); ntot++; ti = -1; tn = -1; for (z3=0;z3<(int)tlist.size();z3++) { n = 0; for (z4=0;z4m_oaBonds.GetSize();z4++) { if (((CMolBond*)m_pTempSM->m_oaBonds[z4])->m_iAtomOffset[0] == tlist[z3]) { for (z5=0;z5<(int)tlist.size();z5++) { if (((CMolBond*)m_pTempSM->m_oaBonds[z4])->m_iAtomOffset[1] == tlist[z5]) { n++; goto _bf; } } } else if (((CMolBond*)m_pTempSM->m_oaBonds[z4])->m_iAtomOffset[1] == tlist[z3]) { for (z5=0;z5<(int)tlist.size();z5++) { if (((CMolBond*)m_pTempSM->m_oaBonds[z4])->m_iAtomOffset[0] == tlist[z5]) { n++; goto _bf; } } } _bf:; } if (n == 1) { mai = -1; for (z4=0;z4m_oaMolAtoms.GetSize();z4++) { if (((CMolAtom*)m_pTempSM->m_oaMolAtoms[z4])->m_iOffset == tlist[z3]) { mai = z4; break; } } if (mai == -1) { eprintf("Internal error: CMolAtom not found.\n"); abort(); } if (ti != -1) { if (((CMolAtom*)m_pTempSM->m_oaMolAtoms[mai])->m_liAtomCode > li) { ti = tlist[z3]; li = ((CMolAtom*)m_pTempSM->m_oaMolAtoms[mai])->m_liAtomCode; tn = ((CMolAtom*)m_pTempSM->m_oaMolAtoms[mai])->m_iNumber; } } else { ti = tlist[z3]; li = ((CMolAtom*)m_pTempSM->m_oaMolAtoms[mai])->m_liAtomCode; tn = ((CMolAtom*)m_pTempSM->m_oaMolAtoms[mai])->m_iNumber; } } else if (n != 2) { eprintf("Internal error: Chain atom has > 2 bonds: %d.\n",n); abort(); } } //mprintf("Start is C%d.\n",tn+1); oc->m_iaAtoms.push_back(tn); ti2 = -1; for (z3=0;z3<(int)tlist.size()-1;z3++) { for (z4=0;z4m_oaBonds.GetSize();z4++) { if (((CMolBond*)m_pTempSM->m_oaBonds[z4])->m_iAtomOffset[0] == ti) { for (z5=0;z5<(int)tlist.size();z5++) { if (((CMolBond*)m_pTempSM->m_oaBonds[z4])->m_iAtomOffset[1] == tlist[z5]) { if (tlist[z5] != ti2) { ti2 = ti; ti = tlist[z5]; goto _cd; } } } } else if (((CMolBond*)m_pTempSM->m_oaBonds[z4])->m_iAtomOffset[1] == ti) { for (z5=0;z5<(int)tlist.size();z5++) { if (((CMolBond*)m_pTempSM->m_oaBonds[z4])->m_iAtomOffset[0] == tlist[z5]) { if (tlist[z5] != ti2) { ti2 = ti; ti = tlist[z5]; goto _cd; } } } } } _cd: for (z4=0;z4m_oaMolAtoms.GetSize();z4++) { if (((CMolAtom*)m_pTempSM->m_oaMolAtoms[z4])->m_iOffset == ti) { oc->m_iaAtoms.push_back(((CMolAtom*)m_pTempSM->m_oaMolAtoms[z4])->m_iNumber); goto _cd2; } } eprintf("Internal error: CMolAtom not found (2).\n"); abort(); _cd2:; //mprintf(" C%d",oc->m_iaAtoms[oc->m_iaAtoms.size()-1]+1); } //mprintf("\n"); } // Sort chains descending by length for (z2=0;z2<(int)m_oaChains[z].size()-1;z2++) { ti = -1; ti2 = -1; for (z3=z2;z3<(int)m_oaChains[z].size();z3++) { if ((int)m_oaChains[z][z3]->m_iaAtoms.size() > ti) { ti = (int)m_oaChains[z][z3]->m_iaAtoms.size(); ti2 = z3; } } if (ti2 != z2) { oc = m_oaChains[z][z2]; m_oaChains[z][z2] = m_oaChains[z][ti2]; m_oaChains[z][ti2] = oc; } } for (z2=0;z2<(int)m_oaChains[z].size();z2++) { oc = (COrderChain*)m_oaChains[z][z2]; mprintf(" %2d.) ",z2+1); for (z3=0;z3<(int)oc->m_iaAtoms.size();z3++) { if (z3 != 0) mprintf("-"); mprintf("C%d",oc->m_iaAtoms[z3]+1); } mprintf(" (%lu)\n",oc->m_iaAtoms.size()); } mprintf("\n"); } mprintf(" Chain detection completed. Detected %d alkyl chains.\n\n\n",ntot); } bool COrderEngine::Parse(CTimeStep *ts) { COrderAnalysis *v; CxString buf; mprintf(WHITE,"\n >>> Order Parameters >>>\n\n"); DetectChains(); while (true) { mprintf(WHITE," *** Analysis %lu ***\n\n",m_oaAnalyses.size()+1); mprintf(" Available analyses:\n"); mprintf(" vec - Vector-based Order Parameters\n"); mprintf(" chain - Alkyl Chain Order Parameters\n"); mprintf("\n"); _again: AskString_ND(" Which analysis to perform? ",&buf); if (strchr((const char*)buf,',') != NULL) { eprintf("\n Please enter only one analysis at a time.\n\n"); goto _again; } if (mystricmp((const char*)buf,"vec") == 0) v = new COrderAnalysis_Vector(this); else if (mystricmp((const char*)buf,"chain") == 0) v = new COrderAnalysis_Chain(this); else { eprintf("\n Unknown analysis: \"%s\".\n\n",(const char*)buf); goto _again; } v->m_iNumber = (int)m_oaAnalyses.size(); m_oaAnalyses.push_back(v); if (!v->Parse(ts)) return false; if (!AskYesNo(" Add another order parameter analysis (y/n)? [no] ",false)) break; mprintf("\n"); } mprintf("\n Added %lu analyses.\n",m_oaAnalyses.size()); mprintf(WHITE,"\n <<< Order Parameters <<<\n\n"); return true; } void COrderEngine::ProcessStep(CTimeStep *ts) { int z; for (z=0;z<(int)m_oaAnalyses.size();z++) m_oaAnalyses[z]->ProcessStep(ts); } void COrderEngine::Finish() { int z; mprintf(WHITE,"\n Finishing Order Parameter Analyses...\n"); for (z=0;z<(int)m_oaAnalyses.size();z++) m_oaAnalyses[z]->Finish(); } travis-src-190101/src/order.h0100777000000000000000000000421513412725663012730 0ustar00/***************************************************************************** TRAVIS - Trajectory Analyzer and Visualizer http://www.travis-analyzer.de/ Copyright (c) 2009-2019 Martin Brehm 2012-2019 Martin Thomas 2016-2019 Sascha Gehrke This file was written by Martin Brehm. --------------------------------------------------------------------------- This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . *****************************************************************************/ #ifndef ORDER_H #define ORDER_H // This must always be the first include directive #include "config.h" #include "timestep.h" #include class COrderEngine; class COrderAnalysis { public: COrderAnalysis(COrderEngine *parent) : m_pParent(parent) { } virtual bool Parse(CTimeStep *ts) = 0; virtual void ProcessStep(CTimeStep *ts) = 0; virtual void Finish() = 0; int m_iNumber; COrderEngine *m_pParent; private: COrderAnalysis(); // "delete" the default constructor by making it private }; class COrderChain { public: int m_iMolecule; int m_iCarbonIndex; std::vector m_iaAtoms; }; class COrderEngine { public: bool Parse(CTimeStep *ts); void ProcessStep(CTimeStep *ts); void Finish(); void DetectChains(); void REC_DetectChains(int depth, int pos, std::vector &touched); std::vector m_oaAnalyses; std::vector > m_oaChains; int m_iChainsTotal; CSingleMolecule *m_pTempSM; std::vector m_saChainAllowedSub; }; #endif travis-src-190101/src/order_chain.cpp0100777000000000000000000002063413412725626014427 0ustar00/***************************************************************************** TRAVIS - Trajectory Analyzer and Visualizer http://www.travis-analyzer.de/ Copyright (c) 2009-2019 Martin Brehm 2012-2019 Martin Thomas 2016-2019 Sascha Gehrke This file was written by Martin Brehm. --------------------------------------------------------------------------- This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . *****************************************************************************/ // This must always be the first include directive #include "config.h" #include "order.h" #include "order_chain.h" #include "globalvar.h" #include "maintools.h" const char *GetRevisionInfo_order_chain(unsigned int len) { static char buf[256]; GET_REVISION_INFO( buf, len ); return buf; } const char *GetSourceVersion_order_chain() { static char buf[256]; GET_SOURCE_VERSION( buf ); return buf; } bool COrderAnalysis_Chain::Parse(CTimeStep *ts) { int z; //CMolecule *m; //CSingleMolecule *sm; CxString buf; UNUSED(ts); mprintf(WHITE,"\n >>> Analysis %d: Alkyl Chain Order Parameters >>>\n\n",m_iNumber+1); if (g_oaMolecules.GetSize() == 1) { mprintf(" Using molecule 1.\n"); m_iMolecule = 0; } else m_iMolecule = AskRangeInteger_ND(" Define vectors in which molecule (1-%d)? ",1,g_oaMolecules.GetSize(),g_oaMolecules.GetSize()) - 1; if (m_pParent->m_oaChains[m_iMolecule].size() == 0) { eprintf("\n Error: No alkyl chains have been detected in molecule %d.\n",m_iMolecule+1); abort(); } //m = (CMolecule*)g_oaMolecules[m_iMolecule]; _ilagain: m_iaChains.clear(); AskString_ND(" Which chain(s) to use in molecule %d (comma separated, see list above)? ",&buf,m_iMolecule+1); if (!ParseIntList((const char*)buf,m_iaChains)) { eprintf("\n Invalid input.\n\n"); goto _ilagain; } for (z=0;z<(int)m_iaChains.size();z++) { if ((m_iaChains[z] < 1) || (m_iaChains[z] > (int)m_pParent->m_oaChains[m_iMolecule].size())) { eprintf("\n Chain number %d outside of allowed range (%d .. %lu).\n\n",m_iaChains[z],1,m_pParent->m_oaChains[m_iMolecule].size()); goto _ilagain; } m_iaChains[z]--; if (z > 0) { if (m_pParent->m_oaChains[m_iMolecule][m_iaChains[0]]->m_iaAtoms.size() != m_pParent->m_oaChains[m_iMolecule][m_iaChains[z]]->m_iaAtoms.size()) { eprintf("\n Chains have different lengths (%d: %lu vs. %d: %lu).\n\n",m_iaChains[0]+1,m_pParent->m_oaChains[m_iMolecule][m_iaChains[0]]->m_iaAtoms.size(),m_iaChains[z]+1,m_pParent->m_oaChains[m_iMolecule][m_iaChains[z]]->m_iaAtoms.size()); goto _ilagain; } } else { if (m_pParent->m_oaChains[m_iMolecule][m_iaChains[0]]->m_iaAtoms.size() < 4) { eprintf("\n Chains need to have at least length 4 (found: %lu).\n\n",m_pParent->m_oaChains[m_iMolecule][m_iaChains[0]]->m_iaAtoms.size()); goto _ilagain; } } } mprintf("\n"); m_iDihedrals = (int)m_pParent->m_oaChains[m_iMolecule][m_iaChains[0]]->m_iaAtoms.size()-3; mprintf(" Using %lu chains of length %lu, therefore %d dihedrals.\n\n",m_iaChains.size(),m_pParent->m_oaChains[m_iMolecule][m_iaChains[0]]->m_iaAtoms.size(),m_iDihedrals); m_bSaveHistograms = AskYesNo(" Save histogram for each group of dihedrals (y/n)? [yes] ",true); m_faGauche.resize(m_iDihedrals); m_faTotal.resize(m_iDihedrals); m_faEcliptic1.resize(m_iDihedrals); m_faEcliptic2.resize(m_iDihedrals); for (z=0;zm_fMinVal = 0; m_pGaucheCountHistogram->m_fMaxVal = (double)m_iDihedrals+1.0; m_pGaucheCountHistogram->m_iResolution = (int)m_iDihedrals+1; m_pGaucheCountHistogram->Create(); m_pGaucheCountHistogram->SetLabelX("Number of Gauche Dihedrals in Chain"); m_pGaucheCountHistogram->SetLabelY("Occurrence"); m_pGaucheCountHistogram->m_bLeft = true; if (m_bSaveHistograms) { m_oaHistograms.resize(m_iDihedrals); for (z=0;zm_fMinVal = 0; m_oaHistograms[z]->m_fMaxVal = 180.0; m_oaHistograms[z]->m_iResolution = 100; m_oaHistograms[z]->Create(); m_oaHistograms[z]->SetLabelX("Dihedral Angle"); m_oaHistograms[z]->SetLabelY("Occurrence"); } } mprintf(WHITE,"\n <<< Analysis %d: Alkyl Chain Order Parameters <<<\n\n",m_iNumber+1); return true; } void COrderAnalysis_Chain::ProcessStep(CTimeStep *ts) { int z, z2, z3, i; CMolecule *m; CSingleMolecule *sm; COrderChain *oc; double tf; m = (CMolecule*)g_oaMolecules[m_iMolecule]; for (z=0;zm_laSingleMolIndex.GetSize();z++) { sm = (CSingleMolecule*)g_oaSingleMolecules[m->m_laSingleMolIndex[z]]; for (z2=0;z2<(int)m_iaChains.size();z2++) { oc = m_pParent->m_oaChains[m_iMolecule][m_iaChains[z2]]; i = 0; for (z3=0;z3m_vaCoords[((CxIntArray*)sm->m_oaAtomOffset[oc->m_iCarbonIndex])->GetAt(oc->m_iaAtoms[z3])] - ts->m_vaCoords[((CxIntArray*)sm->m_oaAtomOffset[oc->m_iCarbonIndex])->GetAt(oc->m_iaAtoms[z3+1])]), FoldVector(ts->m_vaCoords[((CxIntArray*)sm->m_oaAtomOffset[oc->m_iCarbonIndex])->GetAt(oc->m_iaAtoms[z3+3])] - ts->m_vaCoords[((CxIntArray*)sm->m_oaAtomOffset[oc->m_iCarbonIndex])->GetAt(oc->m_iaAtoms[z3+2])]), FoldVector(ts->m_vaCoords[((CxIntArray*)sm->m_oaAtomOffset[oc->m_iCarbonIndex])->GetAt(oc->m_iaAtoms[z3+1])] - ts->m_vaCoords[((CxIntArray*)sm->m_oaAtomOffset[oc->m_iCarbonIndex])->GetAt(oc->m_iaAtoms[z3+2])]), true ); if (m_bSaveHistograms) m_oaHistograms[z3]->AddToBin(tf); if (tf < 120.0) { i++; m_faGauche[z3]++; } if (tf < 20.0) m_faEcliptic1[z3]++; if ((tf > 100.0) && (tf < 140.0)) m_faEcliptic2[z3]++; m_faTotal[z3]++; } m_fGaucheCount += (double)i/m_iDihedrals; m_fGaucheSqSum += (double)i*i/m_iDihedrals/m_iDihedrals; m_fCountTotal++; m_pGaucheCountHistogram->AddToBin((double)i); } } } void COrderAnalysis_Chain::Finish() { int z; double mean, sd; CxString buf; FILE *a; mprintf(WHITE,"\n *** Chain Order Parameter Analysis %d ***\n\n",m_iNumber+1); for (z=0;zNormBinSum(100.0); m_oaHistograms[z]->Write((const char*)buf,"","",false); } } mprintf("\n"); buf.sprintf("order_chain%d_results.csv",m_iNumber+1); mprintf(" Saving results to %s ...\n",(const char*)buf); a = OpenFileWrite((const char*)buf,true); mfprintf(a,"# Dihedral; Gauche percentage; Anti percentage; Ecliptic 1 percentage; Ecliptic 2 percentage\n"); for (z=0;zNormBinSum(100.0); m_pGaucheCountHistogram->Write((const char*)buf,"","",false); mprintf("\n"); } travis-src-190101/src/order_chain.h0100777000000000000000000000356613412725653014101 0ustar00/***************************************************************************** TRAVIS - Trajectory Analyzer and Visualizer http://www.travis-analyzer.de/ Copyright (c) 2009-2019 Martin Brehm 2012-2019 Martin Thomas 2016-2019 Sascha Gehrke This file was written by Martin Brehm. --------------------------------------------------------------------------- This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . *****************************************************************************/ #ifndef ORDER_CHAIN_H #define ORDER_CHAIN_H // This must always be the first include directive #include "config.h" #include "order.h" #include "df.h" class COrderAnalysis_Chain : public COrderAnalysis { public: COrderAnalysis_Chain(COrderEngine *parent) : COrderAnalysis(parent) { } bool Parse(CTimeStep *ts); void ProcessStep(CTimeStep *ts); void Finish(); int m_iMolecule; int m_iDihedrals; std::vector m_iaChains; std::vector m_faGauche; std::vector m_faEcliptic1; std::vector m_faEcliptic2; std::vector m_faTotal; std::vector m_oaHistograms; CDF* m_pGaucheCountHistogram; double m_fGaucheCount; double m_fGaucheSqSum; double m_fCountTotal; bool m_bSaveHistograms; }; #endif travis-src-190101/src/order_vector.cpp0100777000000000000000000002767313412725621014654 0ustar00/***************************************************************************** TRAVIS - Trajectory Analyzer and Visualizer http://www.travis-analyzer.de/ Copyright (c) 2009-2019 Martin Brehm 2012-2019 Martin Thomas 2016-2019 Sascha Gehrke This file was written by Martin Brehm. --------------------------------------------------------------------------- This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . *****************************************************************************/ // This must always be the first include directive #include "config.h" #include "order.h" #include "order_vector.h" #include "globalvar.h" #include "maintools.h" const char *GetRevisionInfo_order_vector(unsigned int len) { static char buf[256]; GET_REVISION_INFO( buf, len ); return buf; } const char *GetSourceVersion_order_vector() { static char buf[256]; GET_SOURCE_VERSION( buf ); return buf; } bool COrderAnalysis_Vector::Parse(CTimeStep *ts) { COrderAnalysis_VectorObs *obs; CxString buf; CAtomGroup ag; CMolecule *m; bool chain, b; char *p, *q, cbuf[16]; int z, z2, z3, z4, ti, ia, it; std::vector tia; std::vector tsa; CSingleMolecule *sm; CMolBond *mb; COrderChain *oc; UNUSED(ts); mprintf(WHITE,"\n >>> Analysis %d: Vector-Based Order Parameters >>>\n\n",m_iNumber+1); m_vFixedVector[0] = AskFloat(" Enter X component of fixed vector: [0.0] ",0); m_vFixedVector[1] = AskFloat(" Enter Y component of fixed vector: [0.0] ",0); m_vFixedVector[2] = AskFloat(" Enter Z component of fixed vector: [1.0] ",1.0); mprintf("\n"); if (m_pParent->m_iChainsTotal != 0) { chain = AskYesNo(" Use C-H bonds along an alkyl chain as vectors (y/n)? [no] ",false); mprintf("\n"); } else chain = false; if (chain) { AskString(" Form vectors to which elements as carbon bond partners? [H,D,F] ",&buf,"H,D,F"); p = buf.GetWritePointer(); while (*p != 0) { while (*p == ' ') p++; q = p; while ((*q != 0) && (*q != ',') && (*q != ' ')) q++; memcpy(cbuf,p,q-p); cbuf[q-p] = 0; tsa.push_back((const char*)cbuf); while ((*q == ' ') || (*q == ',')) q++; if (*q == 0) break; p = q; } if (g_oaMolecules.GetSize() == 1) { mprintf(" Using molecule 1.\n"); ti = 0; } else ti = AskRangeInteger_ND(" Define vectors in which molecule (1-%d)? ",1,g_oaMolecules.GetSize(),g_oaMolecules.GetSize()) - 1; if (m_pParent->m_oaChains[ti].size() == 0) { eprintf("\n Error: No alkyl chains have been detected in molecule %d.\n",ti+1); abort(); } m = (CMolecule*)g_oaMolecules[ti]; _ilagain: tia.clear(); AskString_ND(" Which chain(s) to use in molecule %d (comma separated, see list above)? ",&buf,ti+1); if (!ParseIntList((const char*)buf,tia)) { eprintf("\n Invalid input.\n\n"); goto _ilagain; } for (z=0;z<(int)tia.size();z++) { if ((tia[z] < 1) || (tia[z] > (int)m_pParent->m_oaChains[ti].size())) { eprintf("\n Chain number %d outside of allowed range (%d .. %lu).\n\n",tia[z],1,m_pParent->m_oaChains[ti].size()); goto _ilagain; } tia[z]--; if (z > 0) { if (m_pParent->m_oaChains[ti][tia[0]]->m_iaAtoms.size() != m_pParent->m_oaChains[ti][tia[z]]->m_iaAtoms.size()) { eprintf("\n Chains have different lengths (%d: %lu vs. %d: %lu).\n\n",tia[0]+1,m_pParent->m_oaChains[ti][tia[0]]->m_iaAtoms.size(),tia[z]+1,m_pParent->m_oaChains[ti][tia[z]]->m_iaAtoms.size()); goto _ilagain; } } } mprintf("\n"); mprintf(" Using %lu chains of length %lu:\n\n",tia.size(),m_pParent->m_oaChains[ti][tia[0]]->m_iaAtoms.size()); sm = (CSingleMolecule*)g_oaSingleMolecules[m->m_laSingleMolIndex[0]]; for (z=0;z<(int)m_pParent->m_oaChains[ti][tia[0]]->m_iaAtoms.size();z++) { mprintf(" Vector %2d: ",z+1); obs = new COrderAnalysis_VectorObs(); m_oaObservations.push_back(obs); obs->m_sName = m->m_sName; obs->m_iMolecule = ti; b = false; for (z2=0;z2<(int)tia.size();z2++) { oc = m_pParent->m_oaChains[ti][tia[z2]]; for (z3=0;z3m_oaBonds.GetSize();z3++) { mb = (CMolBond*)sm->m_oaBonds[z3]; if ((mb->m_iAtomType[0] == oc->m_iCarbonIndex) && (mb->m_iAtom[0] == oc->m_iaAtoms[z])) { ia = mb->m_iAtom[1]; it = mb->m_iAtomType[1]; } else if ((mb->m_iAtomType[1] == oc->m_iCarbonIndex) && (mb->m_iAtom[1] == oc->m_iaAtoms[z])) { ia = mb->m_iAtom[0]; it = mb->m_iAtomType[0]; } else continue; for (z4=0;z4<(int)tsa.size();z4++) if (mystricmp(tsa[z4].c_str(),((CAtom*)g_oaAtoms[m->m_baAtomIndex[it]])->m_sName) == 0) goto _elok; continue; _elok: obs->m_iaAtomTypes.push_back(oc->m_iCarbonIndex); obs->m_iaAtomTypes.push_back(it); obs->m_iaAtoms.push_back(oc->m_iaAtoms[z]); obs->m_iaAtoms.push_back(ia); buf.sprintf("_C%d-%s%d",oc->m_iaAtoms[z]+1,(const char*)((CAtom*)g_oaAtoms[m->m_baAtomIndex[it]])->m_sName,ia+1); obs->m_sName += buf; if (b) mprintf(", "); b = true; mprintf("C%d --> %s%d",oc->m_iaAtoms[z]+1,(const char*)((CAtom*)g_oaAtoms[m->m_baAtomIndex[it]])->m_sName,ia+1); } } mprintf("\n"); } mprintf("\n"); goto _defdone; } while (true) { mprintf(WHITE," *** Observation %lu ***\n\n",m_oaObservations.size()); obs = new COrderAnalysis_VectorObs(); m_oaObservations.push_back(obs); if (g_oaMolecules.GetSize() == 1) { mprintf(" Defining vector in molecule 1.\n"); obs->m_iMolecule = 0; } else obs->m_iMolecule = AskRangeInteger_ND(" Define vector in which molecule (1-%d)? ",1,g_oaMolecules.GetSize(),g_oaMolecules.GetSize()) - 1; mprintf("\n"); m = (CMolecule*)g_oaMolecules[obs->m_iMolecule]; obs->m_sName = m->m_sName; _again1: AskString_ND(" Which atom to use as vector base point (e.g. C3)? ",&buf); ag.Reset(); if (!ag.ParseAtoms(m,(const char*)buf)) { eprintf("\n Invalid input.\n\n"); goto _again1; } if (ag.m_iAtomGes != 1) { eprintf("\n Please enter only one atom at a time.\n\n"); goto _again1; } obs->m_iaAtomTypes.push_back(ag.m_baAtomType[0]); obs->m_iaAtoms.push_back(((CxIntArray*)ag.m_oaAtoms[0])->GetAt(0)); buf.sprintf("_%s%d-",(const char*)((CAtom*)g_oaAtoms[ag.m_baRealAtomType[0]])->m_sName,((CxIntArray*)ag.m_oaAtoms[0])->GetAt(0)+1); obs->m_sName += buf; _again2: AskString_ND(" Which atom to use as vector tip point (e.g. C3)? ",&buf); ag.Reset(); if (!ag.ParseAtoms(m,(const char*)buf)) { eprintf("\n Invalid input.\n\n"); goto _again2; } if (ag.m_iAtomGes != 1) { eprintf("\n Please enter only one atom at a time.\n\n"); goto _again2; } obs->m_iaAtomTypes.push_back(ag.m_baAtomType[0]); obs->m_iaAtoms.push_back(((CxIntArray*)ag.m_oaAtoms[0])->GetAt(0)); buf.sprintf("%s%d",(const char*)((CAtom*)g_oaAtoms[ag.m_baRealAtomType[0]])->m_sName,((CxIntArray*)ag.m_oaAtoms[0])->GetAt(0)+1); obs->m_sName += buf; mprintf("\n"); if (AskYesNo(" Add another vector to this observation (y/n)? [no] ",false)) goto _again1; if (!AskYesNo(" Add another observation (y/n)? [no] ",false)) break; mprintf("\n"); } mprintf("\n"); _defdone: m_bHistograms = AskYesNo(" Create histograms of each vector order parameter (y) or only average values (n)? [yes] ",true); if (m_bHistograms) { ti = AskUnsignedInteger(" Which resolution to use for the histograms? [100] ",100); for (z=0;z<(int)m_oaObservations.size();z++) { obs = m_oaObservations[z]; obs->m_pHistogram = new CDF(); obs->m_pHistogram->m_fMinVal = 0.0; obs->m_pHistogram->m_fMaxVal = 180.0; obs->m_pHistogram->m_iResolution = ti; obs->m_pHistogram->Create(); obs->m_pHistogram->SetLabelX("Angle"); obs->m_pHistogram->SetLabelY("Occurrence"); } mprintf("\n"); } for (z=0;z<(int)m_oaObservations.size();z++) { obs = m_oaObservations[z]; obs->m_fAverage = 0; obs->m_fAvgCounter = 0; } if (m_oaObservations.size() > 1) m_bCombined = AskYesNo(" Create an overview datafile with the average values of all order parameters (y/n)? [yes] ",true); else m_bCombined = false; mprintf(WHITE,"\n <<< Analysis %d: Vector-Based Order Parameters <<<\n\n",m_iNumber+1); return true; } void COrderAnalysis_Vector::ProcessStep(CTimeStep *ts) { int z, z2, z3; COrderAnalysis_VectorObs *obs; CxDVector3 vec; CMolecule *m; CSingleMolecule *sm; double tf, tf2; for (z=0;z<(int)m_oaObservations.size();z++) { obs = m_oaObservations[z]; m = (CMolecule*)g_oaMolecules[obs->m_iMolecule]; for (z2=0;z2m_laSingleMolIndex.GetSize();z2++) { sm = (CSingleMolecule*)g_oaSingleMolecules[m->m_laSingleMolIndex[z2]]; for (z3=0;z3<(int)obs->m_iaAtoms.size()/2;z3++) { vec = ts->m_vaCoords[((CxIntArray*)sm->m_oaAtomOffset[obs->m_iaAtomTypes[z3*2+1]])->GetAt(obs->m_iaAtoms[z3*2+1])] - ts->m_vaCoords[((CxIntArray*)sm->m_oaAtomOffset[obs->m_iaAtomTypes[z3*2]])->GetAt(obs->m_iaAtoms[z3*2])]; vec = FoldVector(vec); vec.Normalize(); tf = DotP(vec,m_vFixedVector); tf2 = 1.5*tf*tf - 0.5; obs->m_fAverage += tf2; obs->m_fAvgCounter++; if (m_bHistograms) obs->m_pHistogram->AddToBin(acos(tf)*180.0/Pi); } } } } void COrderAnalysis_Vector::Finish() { int z /*, z2*/; //double tf , tf2; //std::vector tfa; COrderAnalysis_VectorObs *obs; FILE *a; CxString buf; mprintf(WHITE,"\n *** Vector Order Parameter Analysis %d ***\n\n",m_iNumber+1); for (z=0;z<(int)m_oaObservations.size();z++) { obs = m_oaObservations[z]; mprintf(" Observation %d:\n",z+1); obs->m_fAverage /= obs->m_fAvgCounter; mprintf(" Average value: %.6f\n",obs->m_fAverage); if (m_bHistograms) { buf.sprintf("order_vector%d_histogram%d_%s.csv",m_iNumber+1,z+1,(const char*)obs->m_sName); mprintf(" Writing histogram to %s ...\n",(const char*)buf); obs->m_pHistogram->AngleCorrect(); obs->m_pHistogram->NormBinSum(100.0); obs->m_pHistogram->Integrate(false,1.0); obs->m_pHistogram->Write((const char*)buf,"","",true); /* tfa.resize(obs->m_pHistogram->m_iResolution); for (z2=0;z2m_pHistogram->m_iResolution;z2++) { tf = -0.5 + 1.5*(z2+0.5)/obs->m_pHistogram->m_iResolution; tf2 = sin(acos(sqrt((tf+0.5)/1.5))); tfa[z2] = obs->m_pHistogram->m_pBin[z2] / tf2 / tf2; } tf = 0; for (z2=0;z2m_pHistogram->m_iResolution;z2++) tf += tfa[z2]; for (z2=0;z2m_pHistogram->m_iResolution;z2++) tfa[z2] *= 100.0 / tf; obs->m_pHistogram->NormBinSum(100.0); obs->m_pHistogram->Integrate(false,1.0); a = OpenFileWrite((const char*)buf,true); mfprintf(a,"# Order Parameter; Occurrence; Integral; Corrected Occurrence; Corrected Integral\n"); tf = 0; tf2 = 0; for (z2=0;z2m_pHistogram->m_iResolution;z2++) { tf += obs->m_pHistogram->m_pBin[z2]; tf2 += tfa[z2]; mfprintf(a,"%f; %f; %f; %f; %f\n", -0.5 + 1.5*(z2+0.5)/obs->m_pHistogram->m_iResolution, obs->m_pHistogram->m_pBin[z2], tf, tfa[z2], tf2); } fclose(a);*/ } mprintf("\n"); } if (m_bCombined) { buf.sprintf("order_vector%d_combined.csv",m_iNumber+1); mprintf(" Creating combined data file %s ...\n",(const char*)buf); a = OpenFileWrite((const char*)buf,true); mfprintf(a,"# Vector Set; Average Order Parameter\n"); for (z=0;z<(int)m_oaObservations.size();z++) mfprintf(a,"%d; %.6f\n",z+1,m_oaObservations[z]->m_fAverage); fclose(a); } } travis-src-190101/src/order_vector.h0100777000000000000000000000353513412725657014321 0ustar00/***************************************************************************** TRAVIS - Trajectory Analyzer and Visualizer http://www.travis-analyzer.de/ Copyright (c) 2009-2019 Martin Brehm 2012-2019 Martin Thomas 2016-2019 Sascha Gehrke This file was written by Martin Brehm. --------------------------------------------------------------------------- This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . *****************************************************************************/ #ifndef ORDER_VECTOR_H #define ORDER_VECTOR_H // This must always be the first include directive #include "config.h" #include "order.h" #include "xdvector3.h" class COrderAnalysis_VectorObs { public: int m_iMolecule; std::vector m_iaAtomTypes; std::vector m_iaAtoms; CxString m_sName; double m_fAverage; double m_fAvgCounter; CDF *m_pHistogram; }; class COrderAnalysis_Vector : public COrderAnalysis { public: COrderAnalysis_Vector(COrderEngine *parent) : COrderAnalysis(parent) { } bool Parse(CTimeStep *ts); void ProcessStep(CTimeStep *ts); void Finish(); CxDVector3 m_vFixedVector; std::vector m_oaObservations; bool m_bHistograms; bool m_bCombined; }; #endif travis-src-190101/src/pdf.cpp0100777000000000000000000003641613412725623012725 0ustar00/***************************************************************************** TRAVIS - Trajectory Analyzer and Visualizer http://www.travis-analyzer.de/ Copyright (c) 2009-2019 Martin Brehm 2012-2019 Martin Thomas 2016-2019 Sascha Gehrke This file was written by Martin Thomas. --------------------------------------------------------------------------- This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . *****************************************************************************/ // This must always be the first include directive #include "config.h" #include "pdf.h" #include "atomgroup.h" #include "df.h" #include "globalvar.h" #include "maintools.h" #include "xobarray.h" #include "xdvector3.h" #include "xstring.h" const char *GetRevisionInfo_pdf(unsigned int len) { static char buf[256]; GET_REVISION_INFO( buf, len ); return buf; } const char *GetSourceVersion_pdf() { static char buf[256]; GET_SOURCE_VERSION( buf ); return buf; } //#define BUF_SIZE 1024 static CxDVector3 g_normalVector; static CxDVector3 g_fixPoint; static CxObArray g_pdfObserv; CPDF::CPDF(int showMol) { // char buf[256]; CxString buf; m_iShowMol = showMol; _showAtomGes = 0; try { _df = new CDF(); } catch(...) { _df = NULL; } if(_df == NULL) NewException((double)sizeof(CDF), __FILE__, __LINE__, __PRETTY_FUNCTION__); mprintf(WHITE, "\n>>> Fixed Plane Density Profile >>>\n\n"); try { _ag = new CAtomGroup(); } catch(...) { _ag = NULL; } if(_ag == NULL) NewException((double)sizeof(CAtomGroup), __FILE__, __LINE__, __PRETTY_FUNCTION__); while(true) { if(((CMolecule *)g_oaMolecules[m_iShowMol])->m_iAtomGesNoVirt == 1) { mprintf(" %s is only one atom, there is no choice.\n", ((CMolecule *)g_oaMolecules[m_iShowMol])->m_sName); _ag->Reset(); _ag->m_pMolecule = (CMolecule *)g_oaMolecules[m_iShowMol]; _ag->AddAtom(0, 0, false); _ag->SortAtoms(); _ag->BuildName(); } else { mprintf(" Which atom(s) to take from OM %s (e.g. \"C1,C3-5,H\", \"*\"=all)? [#2] ",((CMolecule*)g_oaMolecules[m_iShowMol])->m_sName); inpprintf("! Which atom(s) to take from OM %s (e.g. \"C1,C3-5,H\", \"*\"=all)? [#2]\n",((CMolecule*)g_oaMolecules[m_iShowMol])->m_sName); myget(&buf); if(strlen(buf) == 0) { if(!_ag->ParseAtoms((CMolecule *)g_oaMolecules[m_iShowMol], "#2")) { eprintf("CPDF::CPDF(): Internal error.\n"); continue; } } else if(!_ag->ParseAtoms((CMolecule *)g_oaMolecules[m_iShowMol], buf)) { continue; } } break; } _showAtomGes += _ag->m_iAtomGes; ParseDeriv(); switch(m_iDeriv) { case 0: _minDist = AskFloat(" Enter the minimal distance of this density profile in pm: [%d.0] ", -(double)HalfBox(), -HalfBox()); _maxDist = AskFloat(" Enter the maximal distance of this density profile in pm: [%d.0] ", (double)HalfBox(), HalfBox()); break; /* case 1: if(m_bDerivAbs) _minDist = AskFloat(" Enter the minimal value of this d1-PDF in pm/ps: [0] ", 0.0f); else _minDist = AskFloat(" Enter the minimal value of this d1-PDF in pm/ps: [-10.0] ", -10.0f); _maxDist = AskFloat(" Enter the maximal value of this d1-RDF in pm/ps: [10.0] ", 10.0f); break; case 2: if(m_bDerivAbs) _minDist = AskFloat(" Enter the minimal value of this d2-RDF in pm/ps^2: [0] ", 0.0f); else _minDist = AskFloat(" Enter the minimal value of this d2-RDF in pm/ps^2: [-10.0] ", -10.0f); _maxDist = AskFloat(" Enter the maximal value of this d2-RDF in pm/ps^2: [10.0] ",10.0f); break;*/ default: eprintf("Higher derivatives are not implemented.\n"); abort(); break; } m_iResolution = AskUnsignedInteger(" Enter the resolution (bin count) for this density profile: [300] ", 300); m_iHistogramRes = 0; if (!g_bBoxNonOrtho) { _scaleUniform = AskYesNo(" Scale to uniform density (y) or to nm^(-1) (n)? [no] ", false); } else { _scaleUniform = false; } m_bMirror = AskYesNo(" Enforce mirror symmetry of this profile (y/n)? [no] ",false); buildName(); m_bSelf = false; mprintf(WHITE, "\n<<< Enf of Fixed Plane Density Profile <<<\n\n"); } CPDF::~CPDF() { delete _ag; delete _df; delete[] m_faData; delete[] m_sName; delete[] m_sShortName; } void CPDF::initialize(int showMolCount) { mprintf(" Creating Density Profile...\n"); _df->m_fMinVal = _minDist; _df->m_fMaxVal = _maxDist; _df->m_iResolution = m_iResolution; _df->m_iHistogramRes = m_iHistogramRes; _df->SetLabelX("Distance / pm"); if (_scaleUniform) _df->SetLabelY("g(d)"); else _df->SetLabelY("Density / nm^(-1)"); _df->Create(); try { m_faData = new CxDoubleArray[showMolCount]; } catch(...) { m_faData = NULL; } if(m_faData == NULL) NewException((double)showMolCount*sizeof(CxDoubleArray), __FILE__, __LINE__, __PRETTY_FUNCTION__); // Add timedev here } void CPDF::finalize() { CxString filename; mprintf(" %.0f bin entries, %.0f out of bin range (%.2f percent).\n", _df->m_fBinEntries, _df->m_fSkipEntries, ZeroDivide(_df->m_fSkipEntries, _df->m_fBinEntries + _df->m_fSkipEntries) * 100.0); _df->CalcMeanSD(); mprintf(" Mean value: %10G pm Standard deviation: %10G pm\n", _df->m_fMean, _df->m_fSD); mprintf(" Min. value: %10G pm Max.value: %10G pm\n", _df->m_fMinInput, _df->m_fMaxInput); _df->MultiplyBin(1.0 / g_iSteps); _df->Integrate(false, 1.0); if (_scaleUniform && !g_bBoxNonOrtho) { mprintf(" Scaling Density Profile to uniform density...\n"); _df->MultiplyBin((g_normalVector[0] * g_normalVector[0] * g_fBoxX + g_normalVector[1] * g_normalVector[1] * g_fBoxY + g_normalVector[2] * g_normalVector[2] * g_fBoxZ) * m_iResolution / (_maxDist-_minDist) / ((CMolecule *)g_oaMolecules[m_iShowMol])->m_laSingleMolIndex.GetSize() / _showAtomGes); } else { mprintf(" Scaling Density Profile to nm^(-1)...\n"); _df->MultiplyBin(1.0e3 / (_maxDist - _minDist) * m_iResolution); } /* char filename[BUF_SIZE]; #ifdef TARGET_WINDOWS _snprintf(filename, BUF_SIZE, "dprof_%s.csv", m_sName); #elif defined TARGET_LINUX snprintf(filename, BUF_SIZE, "dprof_%s.csv", m_sName); #else sprintf(filename, "dprof_%s.csv", m_sName); #endif*/ filename.sprintf("dprof_%s.csv", m_sName); mprintf(" Saving density profile as \"%s\"...\n", (const char*)filename); _df->Write("", filename, "", true); /*#ifdef TARGET_WINDOWS _snprintf(filename, BUF_SIZE, "dprof_%s.agr", m_sName); #elif defined TARGET_LINUX snprintf(filename, BUF_SIZE, "dprof_%s.agr", m_sName); #else sprintf(filename, "dprof_%s.agr", m_sName); #endif*/ filename.sprintf("dprof_%s.agr", m_sName); mprintf(" Saving density profile AGR as \"%s\"...\n", (const char*)filename); _df->WriteAgr("", filename, "", m_sName, true); } void CPDF::buildAtomList(CSingleMolecule *sm, CxIntArray *array) { int i, j; array->RemoveAll_KeepSize(); for(i = 0; i < _ag->m_baAtomType.GetSize(); i++) { CxIntArray *a = (CxIntArray *)_ag->m_oaAtoms[i]; for(j = 0; j < a->GetSize(); j++) { array->Add(((CxIntArray *)sm->m_oaAtomOffset[_ag->m_baAtomType[i]])->GetAt(a->GetAt(j))); } } } void CPDF::buildName() { // char tmp[BUF_SIZE]; CxString tmp; // Check for overflow is missing!!! /* tmp[0] = 0; if(m_iDeriv != 0) { sprintf(tmp, "deriv%d_", m_iDeriv); } strcat(tmp, "["); strcat(tmp, ((CMolecule *)g_oaMolecules[m_iShowMol])->m_sName); strcat(tmp, "_"); strcat(tmp, _ag->m_sName); strcat(tmp, "]");*/ tmp = ""; if(m_iDeriv != 0) { tmp.sprintf("deriv%d_", m_iDeriv); } tmp.strcat("["); tmp.strcat(((CMolecule *)g_oaMolecules[m_iShowMol])->m_sName); tmp.strcat("_"); tmp.strcat(_ag->m_sName); tmp.strcat("]"); try { m_sShortName = new char[1]; } catch(...) { m_sShortName = NULL; } if(m_sShortName == NULL) NewException((double)sizeof(char), __FILE__, __LINE__, __PRETTY_FUNCTION__); m_sShortName[0] = 0; try { m_sName = new char[strlen(tmp)+1]; } catch(...) { m_sName = NULL; } if(m_sName == NULL) NewException((double)(strlen(tmp)+1)*sizeof(char), __FILE__, __LINE__, __PRETTY_FUNCTION__); strcpy(m_sName, tmp); } CPDFObservation::CPDFObservation() { int i; CxString buf, buf2; m_pConditions = NULL; m_bTimeDev = false; m_bSelf = false; m_bOthers = true; if(g_oaMolecules.GetSize() > 1) { /* char buf[BUF_SIZE], buf2[BUF_SIZE]; size_t remaining = BUF_SIZE; #ifdef TARGET_WINDOWS remaining -= _snprintf(buf, remaining, " Which molecule should be observed ("); #elif defined TARGET_LINUX remaining -= snprintf(buf, remaining, " Which molecule should be observed ("); #else remaining -= sprintf(buf, " Which molecule should be observed ("); #endif*/ buf.sprintf(" Which molecule should be observed ("); for(i = 0; i < g_oaMolecules.GetSize(); i++) { /* if(remaining < 1) break; #ifdef TARGET_WINDOWS size_t length = _snprintf(buf2, remaining, "%s=%d", ((CMolecule *)g_oaMolecules[i])->m_sName, i+1); #elif defined TARGET_LINUX size_t length = snprintf(buf2, remaining, "%s=%d", ((CMolecule *)g_oaMolecules[i])->m_sName, i+1); #else size_t length = sprintf(buf2, "%s=%d", ((CMolecule *)g_oaMolecules[i])->m_sName, i+1); #endif strncat(buf, buf2, remaining - 1); remaining -= length;*/ buf2.sprintf("%s=%d", ((CMolecule *)g_oaMolecules[i])->m_sName, i+1); buf.strcat(buf2); if(i < g_oaMolecules.GetSize() - 1) { /*#ifdef TARGET_WINDOWS length = _snprintf(buf2, remaining, ", "); #elif defined TARGET_LINUX length = snprintf(buf2, remaining, ", "); #else length = sprintf(buf2, ", "); #endif strncat(buf, buf2, remaining - 1); remaining -= length;*/ buf2.sprintf(", "); buf.strcat(buf2); } } // strncat(buf, ")? ", remaining - 1); buf.strcat(")? "); m_iShowMol = AskRangeInteger_ND("%s", 1, g_oaMolecules.GetSize(), (const char*)buf) - 1; } else { m_iShowMol = 0; } m_iShowMolCount = ((CMolecule *)g_oaMolecules[m_iShowMol])->m_laSingleMolIndex.GetSize(); m_bObsCertain = false; m_bDecompDist = false; m_bDecompType = false; try { _pdf = new CPDF(m_iShowMol); } catch(...) { _pdf = NULL; } if(_pdf == NULL) NewException((double)sizeof(CPDF), __FILE__, __LINE__, __PRETTY_FUNCTION__); // Ask for conditions here // Add observation list here } CPDFObservation::~CPDFObservation() { delete _pdf; } void CPDFObservation::initialize() { _pdf->initialize(m_iShowMolCount); } void CPDFObservation::process(CTimeStep *ts) { int i, j; double val; for(i = 0; i < m_iShowMolCount; i++) { _pdf->m_faData[i].RemoveAll_KeepSize(); } if (g_bPDFFixAtom) g_fixPoint = ts->m_vaCoords[g_iPDFFixAtom]; for(i = 0; i < m_iShowMolCount; i++) { CSingleMolecule *sm = (CSingleMolecule *)g_oaSingleMolecules[((CMolecule *)g_oaMolecules[m_iShowMol])->m_laSingleMolIndex[i]]; CxIntArray temp; _pdf->buildAtomList(sm, &temp); for(j = 0; j < temp.GetSize(); j++) { CxDVector3 vec = FoldVector(ts->m_vaCoords[temp[j]] - g_fixPoint); val = DotP(vec, g_normalVector); _pdf->addToDF(val); if (_pdf->m_bMirror) _pdf->addToDF(-val); } } /* for(i = 0; i < m_iShowMolCount; i++) { CSingleMolecule *sm = (CSingleMolecule *)g_oaSingleMolecules[((CMolecule *)g_oaMolecules[m_iShowMol])->m_laSingleMolIndex[i]]; CxIntArray temp; _pdf->buildAtomList(sm, &temp); for(j = 0; j < temp.GetSize(); j++) { CxDVector3 vec = FoldVector(ts->m_vaCoords[temp[j]] - g_fixPoint); val = DotP(vec, g_normalVector); _pdf->m_faData[i].Add(val); if (_pdf->m_bMirror) _pdf->m_faData[i].Add(-val); } } for(i = 0; i < m_iShowMolCount; i++) { for(j = 0; j < _pdf->m_faData[i].GetSize(); j++) { _pdf->addToDF(_pdf->m_faData[i][j]); } }*/ } void CPDFObservation::finalize() { mprintf(WHITE, "* Planar Distribution Function\n"); _pdf->finalize(); } bool gatherPDF() { double x, y, z; int ti, ti2, ty, rty, at; CxString buf; mprintf(YELLOW, "\n>>> Reference Plane >>>\n\n"); mprintf(" Enter normal vector of reference plane:\n"); x = AskFloat(" x component [0.0] ", 0.0); y = AskFloat(" y component [0.0] ", 0.0); z = AskFloat(" z component [1.0] ", 1.0); g_normalVector = CxDVector3(x, y, z); g_normalVector.Normalize(); mprintf("\n Normalized normal vector is\n"); mprintf(" "); g_normalVector.Dump(); mprintf("\n\n"); g_bPDFFixAtom = AskYesNo(" Use a specified atom (y) or absolute coordinates (n) as origin? [no] ",false); if (g_bPDFFixAtom) { if (g_oaMolecules.GetSize() > 1) ti = AskRangeInteger_ND(" Take origin atom from which molecule type (1-%d)? ",1,g_oaMolecules.GetSize(),g_oaMolecules.GetSize()) - 1; else ti = 0; if (((CMolecule*)g_oaMolecules[ti])->m_laSingleMolIndex.GetSize() > 1) ti2 = AskRangeInteger_ND(" Take origin atom from which molecule of %s (1-%d)? ",1,((CMolecule*)g_oaMolecules[ti])->m_laSingleMolIndex.GetSize(),((CMolecule*)g_oaMolecules[ti])->m_sName,((CMolecule*)g_oaMolecules[ti])->m_laSingleMolIndex.GetSize()) - 1; else ti2 = 0; AskString(" Which atom to take from %s %d? [#2] ",&buf,"#2",((CMolecule*)g_oaMolecules[ti])->m_sName,ti2+1); ParseAtom((const char*)buf,ti,ty,rty,at); g_iPDFFixAtom = ((CxIntArray*)((CSingleMolecule*)g_oaSingleMolecules[((CMolecule*)g_oaMolecules[ti])->m_laSingleMolIndex[ti2]])->m_oaAtomOffset[ty])->GetAt(at); mprintf(" The atom has offset %d.\n",g_iPDFFixAtom); } else { mprintf("\n Enter coordinates of fix point in pm:\n"); x = AskFloat(" x component [0.0] ", 0.0); y = AskFloat(" y component [0.0] ", 0.0); z = AskFloat(" z component [0.0] ", 0.0); g_fixPoint = CxDVector3(x, y, z); mprintf("\n Fix point vector is\n"); mprintf(" "); g_fixPoint.Dump(); mprintf("\n"); } mprintf(YELLOW, "\n<<< End of Reference Plane <<<\n\n"); while(true) { mprintf(YELLOW, "\n>>> Density Profile Observation %d >>>\n\n", g_pdfObserv.GetSize() + 1); CPDFObservation *obs; try { obs = new CPDFObservation(); } catch(...) { obs = NULL; } if(obs == NULL) NewException((double)sizeof(CPDFObservation), __FILE__, __LINE__, __PRETTY_FUNCTION__); g_pdfObserv.Add(obs); mprintf(YELLOW, "\n<<< End of Density Profile Observation %d <<<\n\n", g_pdfObserv.GetSize()); if(!AskYesNo(" Add another observation (y/n)? [no] ", false)) break; mprintf("\n"); } return true; } bool initializePDF() { int i; for(i = 0; i < g_pdfObserv.GetSize(); i++) { ((CPDFObservation *)g_pdfObserv[i])->initialize(); } return true; } void processPDF(CTimeStep *ts) { int i; for(i = 0; i < g_pdfObserv.GetSize(); i++) { ((CPDFObservation *)g_pdfObserv[i])->process(ts); } } void finalizePDF() { int i; for(i = 0; i < g_pdfObserv.GetSize(); i++) { mprintf(YELLOW, "\n>>> Density Profile Observation %d >>>\n\n", i+1); ((CPDFObservation *)g_pdfObserv[i])->finalize(); mprintf(YELLOW, "\n<<< End of Density Profile Observation %d <<<\n\n", i+1); } for(i = 0; i < g_pdfObserv.GetSize(); i++) { delete (CPDFObservation *)g_pdfObserv[i]; } } travis-src-190101/src/pdf.h0100777000000000000000000000401513412725665012366 0ustar00/***************************************************************************** TRAVIS - Trajectory Analyzer and Visualizer http://www.travis-analyzer.de/ Copyright (c) 2009-2019 Martin Brehm 2012-2019 Martin Thomas 2016-2019 Sascha Gehrke This file was written by Martin Thomas. --------------------------------------------------------------------------- This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . *****************************************************************************/ #ifndef PDF_H #define PDF_H // This must always be the first include directive #include "config.h" #include "moltools.h" #include "xdf.h" class CDF; class CSingleMolecule; class CTimeStep; class CxIntArray; class CPDF: public CXDF { public: explicit CPDF(int showMol); ~CPDF(); void initialize(int showMolCount); void finalize(); void buildAtomList(CSingleMolecule *mol, CxIntArray *array); void addToDF(double value) { _df->AddToBin(value); } bool m_bMirror; private: CDF *_df; CAtomGroup *_ag; int _showAtomGes; double _minDist, _maxDist; bool _scaleUniform; void buildName(); }; class CPDFObservation: public CObservation { public: CPDFObservation(); ~CPDFObservation(); void initialize(); void process(CTimeStep *ts); void finalize(); private: CPDF *_pdf; }; bool gatherPDF(); bool initializePDF(); void processPDF(CTimeStep *ts); void finalizePDF(); #endif travis-src-190101/src/plproj.cpp0100777000000000000000000002435713412725620013460 0ustar00/***************************************************************************** TRAVIS - Trajectory Analyzer and Visualizer http://www.travis-analyzer.de/ Copyright (c) 2009-2019 Martin Brehm 2012-2019 Martin Thomas 2016-2019 Sascha Gehrke This file was written by Martin Brehm. --------------------------------------------------------------------------- This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . *****************************************************************************/ // This must always be the first include directive #include "config.h" #include "plproj.h" #include "globalvar.h" const char *GetRevisionInfo_plproj(unsigned int len) { static char buf[256]; GET_REVISION_INFO( buf, len ); return buf; } const char *GetSourceVersion_plproj() { static char buf[256]; GET_SOURCE_VERSION( buf ); return buf; } CPlProj::CPlProj() { m_p2DF = NULL; m_iAverageCounter = 0; } CPlProj::~CPlProj() { } void CPlProj::Parse() { int ti, z; // char buf[256], buf2[256]; CxString buf, buf2; double tf; try { m_p2DF = new C2DF(); } catch(...) { m_p2DF = NULL; } if (m_p2DF == NULL) NewException((double)sizeof(C2DF),__FILE__,__LINE__,__PRETTY_FUNCTION__); mprintf(WHITE,"\n>>> Plane Projection Distribution Function >>>\n\n"); _plprojatoms: if (m_bIntra) { mprintf(" Observing atoms in molecules of kind %s.\n",((CMolecule*)g_oaMolecules[g_iFixMol])->m_sName); } else { mprintf(" Observing atoms in reference molecule (%s).\n",((CMolecule*)g_oaMolecules[m_iShowMol])->m_sName); } if (((CMolecule*)g_oaMolecules[(!m_bIntra)?m_iShowMol:g_iFixMol])->m_iAtomGesNoVirt == 1) { mprintf(" %s is only one atom, there is no choice.\n",((CMolecule*)g_oaMolecules[(!m_bIntra)?m_iShowMol:g_iFixMol])->m_sName); m_oAtoms.Reset(); m_oAtoms.m_pMolecule = (CMolecule*)g_oaMolecules[(!m_bIntra)?m_iShowMol:g_iFixMol]; m_oAtoms.AddAtom(0,0,false); m_oAtoms.SortAtoms(); m_oAtoms.BuildName(); } else { mprintf(" Which atoms to observe (e.g. \"C1,C3-5,H\", \"*\"=all)? [#2] "); inpprintf("! Which atoms to observe (e.g. \"C1,C3-5,H\", \"*\"=all)? [#2]\n"); myget(&buf); if (strlen(buf) == 0) { if (!m_oAtoms.ParseAtoms((CMolecule*)g_oaMolecules[m_bIntra?g_iFixMol:m_iShowMol],"#2")) { eprintf("Strange error ^^\n"); inpprintf("! Strange error ^\n"); goto _plprojatoms; } } else { if (!m_oAtoms.ParseAtoms((CMolecule*)g_oaMolecules[m_bIntra?g_iFixMol:m_iShowMol],buf)) { eprintf("Invalid input.\n"); inpprintf("! Invalid input.\n"); goto _plprojatoms; } } } m_iShowAtomGes = m_oAtoms.m_iAtomGes; if (g_bPeriodicX && g_bPeriodicY && g_bPeriodicZ) m_fParticleDensity = m_oAtoms.m_iAtomGes * ((CMolecule*)g_oaMolecules[m_bIntra?g_iFixMol:m_iShowMol])->m_laSingleMolIndex.GetSize() / g_fBoxX / g_fBoxY / g_fBoxZ * 1E9; mprintf("\n"); m_bDrawAtoms = AskYesNo(" Draw atoms of reference molecule in plot (y/n)? [yes] ",true); if (m_bDrawAtoms) { _drawagain: // sprintf(buf," Draw reference atoms (%s%d, %s%d, %s%d) in plot (y/n)? [yes] ",((CAtom*)g_oaAtoms[g_iFixRealAtomType[0]])->m_sName,g_iFixAtom[0]+1,((CAtom*)g_oaAtoms[g_iFixRealAtomType[1]])->m_sName,g_iFixAtom[1]+1,((CAtom*)g_oaAtoms[g_iFixRealAtomType[2]])->m_sName,g_iFixAtom[2]+1); buf.sprintf(" Draw reference atoms (%s%d, %s%d, %s%d) in plot (y/n)? [yes] ",(const char*)((CAtom*)g_oaAtoms[g_iFixRealAtomType[0]])->m_sName,g_iFixAtom[0]+1,(const char*)((CAtom*)g_oaAtoms[g_iFixRealAtomType[1]])->m_sName,g_iFixAtom[1]+1,(const char*)((CAtom*)g_oaAtoms[g_iFixRealAtomType[2]])->m_sName,g_iFixAtom[2]+1); if (AskYesNo("%s",true,(const char*)buf)) { // sprintf(buf,"%s%d,%s%d,%s%d",((CAtom*)g_oaAtoms[g_iFixRealAtomType[0]])->m_sName,g_iFixAtom[0]+1,((CAtom*)g_oaAtoms[g_iFixRealAtomType[1]])->m_sName,g_iFixAtom[1]+1,((CAtom*)g_oaAtoms[g_iFixRealAtomType[2]])->m_sName,g_iFixAtom[2]+1); buf.sprintf("%s%d,%s%d,%s%d",(const char*)((CAtom*)g_oaAtoms[g_iFixRealAtomType[0]])->m_sName,g_iFixAtom[0]+1,(const char*)((CAtom*)g_oaAtoms[g_iFixRealAtomType[1]])->m_sName,g_iFixAtom[1]+1,(const char*)((CAtom*)g_oaAtoms[g_iFixRealAtomType[2]])->m_sName,g_iFixAtom[2]+1); AskString(" Which additional atoms to draw (e.g. \"C1,C3-5,H\")? [none] ",&buf2,""); if (strlen(buf2) != 0) { // strcat(buf,","); // strcat(buf,buf2); buf.strcat(","); buf.strcat(buf2); } } else { AskString(" Which atoms to draw (e.g. \"C1,C3-5,H\", \"*\"=all)? [none] ",&buf,""); } // mprintf("---> \"%s\".\n",buf); if (strlen(buf) != 0) { if (!m_oDrawAtoms.ParseAtoms((CMolecule*)g_oaMolecules[g_iFixMol],buf)) { eprintf("Invalid input (\"%s\").\n",(const char*)buf); goto _drawagain; } } else { m_bDrawAtoms = false; mprintf(" Not drawing any atoms from reference molecule.\n\n"); } } if (m_bDrawAtoms) { mprintf(" Drawing %d atoms from reference molecule.\n",m_oDrawAtoms.m_iAtomGes); m_vaAtomPos.SetSize(m_oDrawAtoms.m_iAtomGes); for (z=0;zm_fAspectRatio = m_fAspectRatio; mprintf("\n"); ti = g_pDatabase->GetInt("/PLOT2D/DEFAULTS/BIN_RES"); m_iResolution[0] = AskUnsignedInteger(" Please enter binning resolution in X direction: [%d] ",ti,ti); m_iResolution[1] = AskUnsignedInteger(" Please enter binning resolution in Y direction: [%d] ",m_iResolution[0],m_iResolution[0]); if (g_bAdvanced2) m_iHistogramRes = AskUnsignedInteger(" Please enter histogram resolution (0=no histogram): [0] ",0); else m_iHistogramRes = 0; BuildName(); mprintf(WHITE,"\n<<< End of Plane Projection Distribution Function <<<\n\n"); } void CPlProj::BuildName() { BTIN; // char tmp[32768]; CxString tmp; // tmp[0] = 0; tmp = ""; if (m_bIntra) // sprintf(tmp,"plproj_%s_%s%d%s%d%s%d_%s",((CMolecule*)g_oaMolecules[g_iFixMol])->m_sName,((CAtom*)g_oaAtoms[g_iFixRealAtomType[0]])->m_sName,g_iFixAtom[0]+1,((CAtom*)g_oaAtoms[g_iFixRealAtomType[1]])->m_sName,g_iFixAtom[1]+1,((CAtom*)g_oaAtoms[g_iFixRealAtomType[2]])->m_sName,g_iFixAtom[2]+1,m_oAtoms.m_sName); tmp.sprintf("plproj_%s_%s%d%s%d%s%d_%s",((CMolecule*)g_oaMolecules[g_iFixMol])->m_sName,(const char*)((CAtom*)g_oaAtoms[g_iFixRealAtomType[0]])->m_sName,g_iFixAtom[0]+1,(const char*)((CAtom*)g_oaAtoms[g_iFixRealAtomType[1]])->m_sName,g_iFixAtom[1]+1,(const char*)((CAtom*)g_oaAtoms[g_iFixRealAtomType[2]])->m_sName,g_iFixAtom[2]+1,m_oAtoms.m_sName); else // sprintf(tmp,"plproj_%s_%s%d%s%d%s%d_%s_%s",((CMolecule*)g_oaMolecules[g_iFixMol])->m_sName,((CAtom*)g_oaAtoms[g_iFixRealAtomType[0]])->m_sName,g_iFixAtom[0]+1,((CAtom*)g_oaAtoms[g_iFixRealAtomType[1]])->m_sName,g_iFixAtom[1]+1,((CAtom*)g_oaAtoms[g_iFixRealAtomType[2]])->m_sName,g_iFixAtom[2]+1,((CMolecule*)g_oaMolecules[m_iShowMol])->m_sName,m_oAtoms.m_sName); tmp.sprintf("plproj_%s_%s%d%s%d%s%d_%s_%s",((CMolecule*)g_oaMolecules[g_iFixMol])->m_sName,(const char*)((CAtom*)g_oaAtoms[g_iFixRealAtomType[0]])->m_sName,g_iFixAtom[0]+1,(const char*)((CAtom*)g_oaAtoms[g_iFixRealAtomType[1]])->m_sName,g_iFixAtom[1]+1,(const char*)((CAtom*)g_oaAtoms[g_iFixRealAtomType[2]])->m_sName,g_iFixAtom[2]+1,((CMolecule*)g_oaMolecules[m_iShowMol])->m_sName,m_oAtoms.m_sName); try { m_sName = new char[strlen(tmp)+1]; } catch(...) { m_sName = NULL; } if (m_sName == NULL) NewException((double)(strlen(tmp)+1)*sizeof(char),__FILE__,__LINE__,__PRETTY_FUNCTION__); strcpy(m_sName,tmp); BTOUT; } void CPlProj::BuildAtomList(CSingleMolecule *ref, CSingleMolecule *obs, CxIntArray *vec) { BXIN; int z1t, z1a; CxIntArray *a1; vec->RemoveAll_KeepSize(); for (z1t=0;z1tGetSize();z1a++) { if (m_bIntra) vec->Add(((CxIntArray*)ref->m_oaAtomOffset[m_oAtoms.m_baAtomType[z1t]])->GetAt(a1->GetAt(z1a))); else vec->Add(((CxIntArray*)obs->m_oaAtomOffset[m_oAtoms.m_baAtomType[z1t]])->GetAt(a1->GetAt(z1a))); } } BXOUT; } travis-src-190101/src/plproj.h0100777000000000000000000000402413412725670013117 0ustar00/***************************************************************************** TRAVIS - Trajectory Analyzer and Visualizer http://www.travis-analyzer.de/ Copyright (c) 2009-2019 Martin Brehm 2012-2019 Martin Thomas 2016-2019 Sascha Gehrke This file was written by Martin Brehm. --------------------------------------------------------------------------- This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . *****************************************************************************/ #ifndef PLPROJ_H #define PLPROJ_H // This must always be the first include directive #include "config.h" #include "tools.h" #include "xobject.h" #include "2df.h" #include "moltools.h" #include "xdvec3array.h" #include "atomgroup.h" #include "xbytearray.h" class CPlProj : public CxObject { public: CPlProj(); ~CPlProj(); void BuildAtomList(CSingleMolecule *ref, CSingleMolecule *obs, CxIntArray *vec); void BuildName(); void Parse(); int m_iHistogramRes; int m_iResolution[2]; bool m_bIntra; int m_iShowMol; double m_fMinVal[2]; double m_fMaxVal[2]; double m_fSliceBorder[2]; double m_fAspectRatio; double m_fParticleDensity; char *m_sName; CxDVec3Array *m_vaData; C2DF *m_p2DF; CAtomGroup m_oAtoms; CAtomGroup m_oDrawAtoms; bool m_bDrawAtoms; bool m_bAverageAtomPos; CxDVec3Array m_vaAtomPos; int m_iAverageCounter; CxByteArray *m_baDataEnabled; int m_iShowAtomGes; }; #endif travis-src-190101/src/posdomain.cpp0100777000000000000000000001467713412725635014155 0ustar00/***************************************************************************** TRAVIS - Trajectory Analyzer and Visualizer http://www.travis-analyzer.de/ Copyright (c) 2009-2019 Martin Brehm 2012-2019 Martin Thomas 2016-2019 Sascha Gehrke This file was written by Martin Brehm. --------------------------------------------------------------------------- This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . *****************************************************************************/ // This must always be the first include directive #include "config.h" #include "posdomain.h" const char *GetRevisionInfo_posdomain(unsigned int len) { static char buf[256]; GET_REVISION_INFO( buf, len ); return buf; } const char *GetSourceVersion_posdomain() { static char buf[256]; GET_SOURCE_VERSION( buf ); return buf; } bool CPosDomainEngine::Create(const CxDVec3Array &atoms, const CxDMatrix3 &cell, double mindist) { return Create(atoms,atoms.GetSize(),cell,mindist); } bool CPosDomainEngine::Create(const CxDVec3Array &atoms, int count, const CxDMatrix3 &cell, double mindist) { CxDVector3 tv; CxDMatrix3 invcell; int z, dx, dy, dz, d, ti; double tf; //mprintf("\n>>> Init >>>\n"); invcell = cell; if (!invcell.Invert()) { eprintf("CPosDomainEngine::Create(): Error: Encountered singular cell matrix (cell volume is zero).\n"); abort(); } tf = sqrt( cell(0,0)*cell(0,0) + cell(0,1)*cell(0,1) + cell(0,2)*cell(0,2) ); z = (int)floor(tf/mindist); if (z < 1) z = 1; if (z > 64) z = 64; //m_iRes[0] = AskUnsignedInteger(" Domain X grid: [%d] ",z,z); m_iRes[0] = z; tf = sqrt( cell(1,0)*cell(1,0) + cell(1,1)*cell(1,1) + cell(1,2)*cell(1,2) ); z = (int)floor(tf/mindist); if (z < 1) z = 1; if (z > 64) z = 64; //m_iRes[1] = AskUnsignedInteger(" Domain Y grid: [%d] ",z,z); m_iRes[1] = z; tf = sqrt( cell(2,0)*cell(2,0) + cell(2,1)*cell(2,1) + cell(2,2)*cell(2,2) ); z = (int)floor(tf/mindist); if (z < 1) z = 1; if (z > 64) z = 64; //m_iRes[2] = AskUnsignedInteger(" Domain Z grid: [%d] ",z,z); m_iRes[2] = z; if ((m_iRes[0] < 3) || (m_iRes[1] < 3) || (m_iRes[2] < 3)) { m_bTrivial = true; m_iaTrivialList.resize(atoms.GetSize()); for (z=0;z (int)m_oaDomains.size()) { ti = (int)m_oaDomains.size(); m_oaDomains.resize(m_iRes[0]*m_iRes[1]*m_iRes[2]); for (z=ti;zm_iaAtoms.clear(); m_iaAtomDomain.resize(count); for (z=0;z= m_iRes[0]) dx = m_iRes[0]-1; if (dy >= m_iRes[1]) dy = m_iRes[1]-1; if (dz >= m_iRes[2]) dz = m_iRes[2]-1; d = dx+dy*m_iRes[0]+dz*m_iRes[0]*m_iRes[1]; m_oaDomains[d]->m_iaAtoms.push_back(z); m_iaAtomDomain[z] = d; } //mprintf("\n>>> Init Done >>>\n"); return true; } bool CPosDomainEngine::CreateTrivial(const CxDVec3Array &atoms) { int z; m_bTrivial = true; m_iaTrivialList.resize(atoms.GetSize()); for (z=0;z &nb) const { int d, d2, ox, oy, oz, rx, ry, rz, nx, ny, nz; //mprintf("\n*** Neighbors of %d ***\n",atom); if (m_bTrivial) { nb.insert( nb.end(), m_iaTrivialList.begin(), m_iaTrivialList.end() ); return; } // Guaranteed resolution >= 3 in all directions d = m_iaAtomDomain[atom]; ox = d % m_iRes[0]; oy = (d / m_iRes[0]) % m_iRes[1]; oz = (d / m_iRes[0] / m_iRes[1]); //mprintf(" is in Domain %d, which is %d %d %d.\n",d,ox,oy,oz); nb.clear(); for (rz=oz-1;rz<=oz+1;rz++) { if (rz < 0) nz = rz+m_iRes[2]; else if (rz >= m_iRes[2]) nz = rz-m_iRes[2]; else nz = rz; for (ry=oy-1;ry<=oy+1;ry++) { //mprintf("@ ry=%d (%d..%d)\n",ry,oy-1,oy+1); if (ry < 0) ny = ry+m_iRes[1]; else if (ry >= m_iRes[1]) ny = ry-m_iRes[1]; else ny = ry; for (rx=ox-1;rx<=ox+1;rx++) { if (rx < 0) nx = rx+m_iRes[0]; else if (rx >= m_iRes[0]) nx = rx-m_iRes[0]; else nx = rx; d2 = nx+ny*m_iRes[0]+nz*m_iRes[0]*m_iRes[1]; //mprintf(" %2d %2d %2d / %4d: %d atoms.\n",nx,ny,nz,d2,(int)m_oaDomains[d2]->m_iaAtoms.size()); nb.insert( nb.end(), m_oaDomains[d2]->m_iaAtoms.begin(), m_oaDomains[d2]->m_iaAtoms.end() ); } } } } void CPosDomainEngine::GetDomainAndNeighbors(int domain, std::vector &dom, std::vector &nbh) const { int d2, ox, oy, oz, rx, ry, rz, nx, ny, nz; if (m_bTrivial) { dom.assign( m_iaTrivialList.begin(), m_iaTrivialList.end() ); nbh.assign( m_iaTrivialList.begin(), m_iaTrivialList.end() ); return; } dom.assign( m_oaDomains[domain]->m_iaAtoms.begin(), m_oaDomains[domain]->m_iaAtoms.end() ); ox = domain % m_iRes[0]; oy = (domain / m_iRes[0]) % m_iRes[1]; oz = (domain / m_iRes[0] / m_iRes[1]); nbh.clear(); for (rz=oz-1;rz<=oz+1;rz++) { if (rz < 0) nz = rz+m_iRes[2]; else if (rz >= m_iRes[2]) nz = rz-m_iRes[2]; else nz = rz; for (ry=oy-1;ry<=oy+1;ry++) { if (ry < 0) ny = ry+m_iRes[1]; else if (ry >= m_iRes[1]) ny = ry-m_iRes[1]; else ny = ry; for (rx=ox-1;rx<=ox+1;rx++) { if (rx < 0) nx = rx+m_iRes[0]; else if (rx >= m_iRes[0]) nx = rx-m_iRes[0]; else nx = rx; d2 = nx+ny*m_iRes[0]+nz*m_iRes[0]*m_iRes[1]; nbh.insert( nbh.end(), m_oaDomains[d2]->m_iaAtoms.begin(), m_oaDomains[d2]->m_iaAtoms.end() ); } } } } travis-src-190101/src/posdomain.h0100777000000000000000000000425413412725650013605 0ustar00/***************************************************************************** TRAVIS - Trajectory Analyzer and Visualizer http://www.travis-analyzer.de/ Copyright (c) 2009-2019 Martin Brehm 2012-2019 Martin Thomas 2016-2019 Sascha Gehrke This file was written by Martin Brehm. --------------------------------------------------------------------------- This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . *****************************************************************************/ #ifndef POSDOMAIN_H #define POSDOMAIN_H // This must always be the first include directive #include "config.h" #include "tools.h" #include "xdvec3array.h" #include "xdmatrix3.h" #include class CPosDomain { public: std::vector m_iaAtoms; }; class CPosDomainEngine { public: CPosDomainEngine() { m_iRes[0] = 0; m_iRes[1] = 0; m_iRes[2] = 0; m_bTrivial = false; } ~CPosDomainEngine() { int z; for (z=0;z<(int)m_oaDomains.size();z++) delete m_oaDomains[z]; m_oaDomains.clear(); } bool Create(const CxDVec3Array &atoms, const CxDMatrix3 &cell, double mindist); bool Create(const CxDVec3Array &atoms, int count, const CxDMatrix3 &cell, double mindist); bool CreateTrivial(const CxDVec3Array &atoms); void FindNeighbors(int atom, std::vector &nb) const; void GetDomainAndNeighbors(int domain, std::vector &dom, std::vector &nbh) const; std::vector m_oaDomains; std::vector m_iaAtomDomain; std::vector m_iaTrivialList; bool m_bTrivial; int m_iRes[3]; }; #endif travis-src-190101/src/qr_fact.cpp0100777000000000000000000002505113412725633013565 0ustar00/***************************************************************************** TRAVIS - Trajectory Analyzer and Visualizer http://www.travis-analyzer.de/ Copyright (c) 2009-2019 Martin Brehm 2012-2019 Martin Thomas 2016-2019 Sascha Gehrke --------------------------------------------------------------------------- This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . *****************************************************************************/ /* QR Least-Squares Solver with Column Pivoting * * Note: This code will overwrite the input matrix! Create a copy if needed. * * Implemented in ANSI C. To compile with gcc: gcc -o qr_fact qr_fact.c -lm * * Author: Michael Mazack, * * Date: April 27th, 2010 * * License: Public Domain. Redistribution and modification without * restriction is granted. If you find this code helpful, please let me know. */ // This must always be the first include directive #include "config.h" #include #include #include #include "qr_fact.h" #include "tools.h" const char *GetRevisionInfo_qr_fact(unsigned int len) { static char buf[256]; GET_REVISION_INFO( buf, len ); return buf; } const char *GetSourceVersion_qr_fact() { static char buf[256]; GET_SOURCE_VERSION( buf ); return buf; } int QR_Test() { int i, j; /* Variables for the matrix, the right hand side, the solution, and copies. */ double **A, **B; double *b, *c, *d; double *x; /* The residual. */ double r; /* Dimensions for our matrix and vectors. */ int M = 6; int N = 3; /* Allocate memory of the matrices and vectors. */ A = (double**)malloc(sizeof(double *)*M); B = (double**)malloc(sizeof(double *)*M); b = (double*)malloc(sizeof(double)*M); c = (double*)malloc(sizeof(double)*M); d = (double*)malloc(sizeof(double)*M); x = (double*)malloc(sizeof(double)*N); /* Use a 2D array for the matrices. */ for(i = 0; i < M; i++) { A[i] = (double*)malloc(sizeof(double)*N); B[i] = (double*)malloc(sizeof(double)*N); } /* Assign the matrix and the right hand side. Notice the format. */ A[0][0] = 1; A[0][1] = 2; A[0][2] = 3; b[0] = 3; A[1][0] = 4; A[1][1] = 5; A[1][2] = 6; b[1] = 9; A[2][0] = 7; A[2][1] = 8; A[2][2] = 9; b[2] = 15; A[3][0] = 10; A[3][1] = 11; A[3][2] = 12; b[3] = 22; A[4][0] = 13; A[4][1] = 14; A[4][2] = 15; b[4] = 27; A[5][0] = 16; A[5][1] = 17; A[5][2] = -5; b[5] = 33; /* Copy the matrix A into B since the QR routine will overwrite A. */ for(i = 0; i < M; i++) for(j = 0; j < N; j++) B[i][j] = A[i][j]; /* Copy the vector b into d since the QR routine will overwrite b. */ for(i = 0; i < M; i++) d[i] = b[i]; mprintf("\n"); mprintf("--------------------------------------------\n"); mprintf("QR Least-Squares Solver with Column-Pivoting\n"); mprintf("--------------------------------------------\n"); mprintf("Matrix A: \n"); QR_display_mat(A, M, N, NULL); mprintf("Right-hand side b: \n"); QR_display_vec(b, M, NULL); /* Solve the least squares problem x = A\b. */ QR_least_squares(A, b, x, M, N); mprintf("Solution x: \n"); QR_display_vec(x, N, NULL); /* Use the copies of the initial matrix and vector to get the right hand side * which corresponds to the least squares solution. */ QR_mat_vec(B, M, N, x, c); mprintf("Matrix-vector product A*x: \n"); QR_display_vec(c, M, NULL); /* Compute the 2-norm of the difference between the original right hand side * and the right hand side computed from the least squares solution. */ r = 0.0; for(i = 0; i < M; i++) r += (c[i] - d[i])*(c[i] - d[i]); r = sqrt(r); mprintf("Least squares residual: r = %f\n", r); mprintf("\n"); /* Collect garbage. */ for(i = 0; i < M; i++) { free(A[i]); free(B[i]); } /* Collect more garbage. */ free(A); free(B); free(b); free(c); free(d); free(x); return 0; } void QR_swap_cols(int *p, int i, int j) { int temp; temp = p[i]; p[i] = p[j]; p[j] = temp; } void QR_back_solve(double **mat, double *rhs, int rows, int cols, double *sol, int *p) { int i, j, bottom; double sum; UNUSED(cols); bottom = 0; /* Fill the solution with zeros initially. */ for(i = 0; i < cols; i++) sol[i] = 0.0; /* Find the first non-zero row from the bottom and start solving from here. */ for(i = rows - 1; i >= 0; i--) if(fabs(mat[i][p[cols - 1]]) > 1e-7) { bottom = i; break; } /* Standard back solving routine starting at the first non-zero diagonal. */ for(i = bottom; i >= 0; i--) { sum = 0.0; for(j = cols - 1; j >= 0; j--) if(j > i) sum += sol[p[j]]*mat[i][p[j]]; if(mat[i][p[i]] > 1e-7) sol[p[i]] = (rhs[i] - sum)/mat[i][p[i]]; else sol[p[i]] = 0.0; } } void QR_householder(double **mat, int rows, int cols, int row_pos, int col_pos, double *result) { int i; double norm; UNUSED(cols); norm = 0; for(i = row_pos; i < rows; i++) norm += mat[i][col_pos]*mat[i][col_pos]; if(norm == 0) return; norm = sqrt(norm); result[0] = (mat[row_pos][col_pos] - norm); for(i = 1; i < (rows - row_pos); i++) result[i] = mat[i+row_pos][col_pos]; norm = 0; for(i = 0; i < (rows - row_pos); i++) norm += result[i]*result[i]; if(norm == 0) return; norm = sqrt(norm); for(i = 0; i < (rows - row_pos); i++) result[i] *= (1.0/norm); } void QR_apply_householder(double **mat, double *rhs, int rows, int cols, double *house, int row_pos, int *p) { int i, j, k, n; double sum; double **hhmat; double **mat_cpy; double *rhs_cpy; // Get the dimensions for the Q matrix. n = rows - row_pos; // Allocate memory. hhmat = (double**)malloc(sizeof(double *)*n); for(i = 0; i < n; i++) hhmat[i] = (double*)malloc(sizeof(double)*n); mat_cpy = (double**)malloc(sizeof(double *)*rows); for(i = 0; i < rows; i++) mat_cpy[i] = (double*)malloc(sizeof(double)*cols); rhs_cpy = (double*)malloc(sizeof(double )*rows); // Copy the matrix. for(i = 0; i < rows; i++) for(j = 0; j < cols; j++) mat_cpy[i][j] = mat[i][j]; // Copy the right hand side. for(i = 0; i < rows; i++) rhs_cpy[i] = rhs[i]; // Build the Q matrix from the Householder transform. for(j = 0; j < n; j++) for(i = 0; i < n; i++) if(i != j) hhmat[i][j] = -2.0*house[j]*house[i]; else hhmat[i][j] = 1.0 - 2.0*house[j]*house[i]; // Multiply by the Q matrix. for(k = 0; k < cols; k++) for(j = 0; j < n; j++) { sum = 0.0; for(i = 0; i < n; i++) sum += hhmat[j][i]*mat_cpy[i + row_pos][p[k]]; mat[j + row_pos][p[k]] = sum; } // Multiply the rhs by the Q matrix. for(j = 0; j < n; j++) { sum = 0.0; for(i = 0; i < n; i++) sum += hhmat[i][j]*rhs_cpy[i + row_pos]; rhs[j + row_pos] = sum; } // Collect garbage. for(i = 0; i < (rows - row_pos); i++) free(hhmat[i]); for(i = 0; i < rows; i++) free(mat_cpy[i]); free(hhmat); free(mat_cpy); free(rhs_cpy); } int QR_get_next_col(double **mat, int rows, int cols, int row_pos, int *p) { int i, j, max_loc; double *col_norms; double max; max_loc = -1; col_norms = (double*)malloc(sizeof(double)*cols); // Compute the norms of the sub columns. for(j = 0; j < cols; j++) { col_norms[j] = 0; for(i = row_pos; i < rows; i++) col_norms[j] += mat[i][p[j]]*mat[i][p[j]]; } // Find the maximum location. max = 1e-7; for(i = 0; i < cols; i++) if(col_norms[i] > max) { max = col_norms[i]; max_loc = i; } // Collect garbge and return. free(col_norms); return max_loc; } /* The star of the show. A QR least-squares solving routine for x = A\b. * * First argument : The row-major matrix (2D array), A. * Second argument: The right-hand side vector, b. * Third argument : The solution vector, x. * Fourth argument: The number of rows in A. * Fifth argument : The number of columns in A. * * WARNING: This routine will overwrite the matrix A and the right-hand side * vector b. In other words, A*x = b is solved using QR least-squares with, * column pivoting, but neither the A nor b are what you started with. However, * the solution x corresponds to the solution of both the modified and original * systems. Please be aware of this. */ void QR_least_squares(double **mat, double *rhs, double *sol, int rows, int cols) { int i, max_loc; int *p; double *v; /* Allocate memory for index vector and Householder transform vector. */ p = (int*)malloc(sizeof(int)*cols); v = (double*)malloc(sizeof(double)*rows); /* Initial permutation vector. */ for(i = 0; i < cols; i++) p[i] = i; /* Apply rotators to make R and Q'*b */ for(i = 0; i < cols; i++) { max_loc = QR_get_next_col(mat, rows, cols, i, p); if(max_loc >= 0) QR_swap_cols(p, i, max_loc); QR_householder(mat, rows, cols, i, p[i], v); QR_apply_householder(mat, rhs, rows, cols, v, i, p); } /* Back solve Rx = Q'*b */ QR_back_solve(mat, rhs, rows, cols, sol, p); /* Collect garbage. */ free(p); free(v); } /* A very simple matrix vector product routine. */ void QR_mat_vec(double **mat, int rows, int cols, double *vec, double *rhs) { int i, j; double sum; for(i = 0; i < rows; i++) { sum = 0.0; for(j = 0; j < cols; j++) sum += mat[i][j]*vec[j]; rhs[i] = sum; } } /* Simple routine for displaying a matrix. */ void QR_display_mat(double **mat, int rows, int cols, int *p) { int i, j; for(i = 0; i < rows; i++) { for(j = 0; j < cols; j++) if(p != NULL) mprintf("\t%-3.5f ", mat[i][p[j]]); else mprintf("\t%-3.5f ", mat[i][j]); mprintf("\n"); } mprintf("\n"); } /* Simple routine for displaying a vector. */ void QR_display_vec(double *vec, int rows, int *p) { int i; for(i = 0; i < rows; i++) if(p != NULL) mprintf("\t%-3.5f\n", vec[p[i]]); else mprintf("\t%-3.5f\n", vec[i]); mprintf("\n"); } travis-src-190101/src/qr_fact.h0100777000000000000000000000562113412725664013237 0ustar00/***************************************************************************** TRAVIS - Trajectory Analyzer and Visualizer http://www.travis-analyzer.de/ Copyright (c) 2009-2019 Martin Brehm 2012-2019 Martin Thomas 2016-2019 Sascha Gehrke --------------------------------------------------------------------------- This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . *****************************************************************************/ /* QR Least-Squares Solver with Column Pivoting * * Note: This code will overwrite the input matrix! Create a copy if needed. * * Implemented in ANSI C. To compile with gcc: gcc -o qr_fact qr_fact.c -lm * * Author: Michael Mazack, * * Date: April 27th, 2010 * * License: Public Domain. Redistribution and modification without * restriction is granted. If you find this code helpful, please let me know. */ #ifndef QR_FACT #define QR_FACT // This must always be the first include directive #include "config.h" /* For updating the permuatation vector in (virtual) column swaps. */ void QR_swap_cols(int *p, int i, int j); /* Backsolving of a trianglular system. */ void QR_back_solve(double **mat, double *rhs, int rows, int cols, double *sol, int *p); /* Apply a Householder transform to the matrix at a given spot. */ void QR_householder(double **mat, int rows, int cols, int row_pos, int col_pos, double *result); /* Routine for applying the Householder transform to the matrix and the * right hand side. */ void QR_apply_householder(double **mat, double *rhs, int rows, int cols, double *house, int row_pos, int *p); /* Get the column with the largest sub-norm starting from i = p[j] = row_pos. */ int QR_get_next_col(double **mat, int rows, int cols, int row_pos, int *p); /* Solve the least squares problem, sol = mat\rhs . */ void QR_least_squares(double **mat, double *rhs, double *sol, int rows, int cols); /* A simple matrix-vector product routine. */ void QR_mat_vec(double **mat, int rows, int cols, double *vec, double *rhs); /* Routine for displaying a matrix. */ void QR_display_mat(double **mat, int rows, int cols, int *p); /* Routine for displaying a vector. */ void QR_display_vec(double *vec, int rows, int *p); int QR_Test(); #endif travis-src-190101/src/raman.cpp0100777000000000000000000037220013412725630013242 0ustar00/***************************************************************************** TRAVIS - Trajectory Analyzer and Visualizer http://www.travis-analyzer.de/ Copyright (c) 2009-2019 Martin Brehm 2012-2019 Martin Thomas 2016-2019 Sascha Gehrke This file was written by Martin Thomas. --------------------------------------------------------------------------- This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . *****************************************************************************/ // This must always be the first include directive #include "config.h" #include "raman.h" #include "acf.h" #include "df.h" #include "globalvar.h" #include "maintools.h" #include "moltools.h" #include "timestep.h" #include "tools.h" #include "xdoublearray.h" #include "xobarray.h" #include #include #include #ifdef TARGET_LINUX #include #include #endif const char *GetRevisionInfo_raman(unsigned int len) { static char buf[256]; GET_REVISION_INFO( buf, len ); return buf; } const char *GetSourceVersion_raman() { static char buf[256]; GET_SOURCE_VERSION( buf ); return buf; } #define BUF_SIZE 4096 static bool g_newRaman; static char *g_ramanDir; static bool g_orientAvg; static double g_fieldStrength; static int g_step = 0; static int g_stride; static char *g_inputTemplate; static char *g_templateFieldPos; static char *g_templatePolPos; static char *g_templateCoordPos; static char *g_templateStepsPos; static CxObArray g_ramObserv; static FILE *g_polFile[3]; static CTimeStep *g_timestep[3]; static FILE *g_reftrajFile; static int g_steps = 0; static bool g_ramanCompat = false; // CRamanDyn::CRamanDyn(int showMol, bool global) { // _global = global; // if(_global) { // m_iShowMol = -1; // m_iMolecules = g_oaSingleMolecules.GetSize(); // } else { // m_iShowMol = showMol; // m_iMolecules = ((CMolecule *)g_oaMolecules[m_iShowMol])->m_laSingleMolIndex.GetSize(); // } // // /*** Set Names of dynamic arrays. By M. Brehm */ // _dipole0.SetName("CRamanDyn::_dipole0"); // char tbuf[256]; // for (int tz1=0;tz1<3;tz1++) // { // for (int tz2=0;tz2<3;tz2++) // { // sprintf(tbuf,"CRamanDyn::_polarizability[%d][%d]",tz1,tz2); // _polarizability[tz1][tz2].SetName(tbuf); // } // } // /* End of set names */ // // mprintf(YELLOW, ">>> Raman Spectrum >>>\n\n"); // // if(_global) // mprintf(" All atoms will be taken.\n\n"); // else // mprintf(" All atoms will be taken from the OM %s.\n\n", ((CMolecule *)g_oaMolecules[m_iShowMol])->m_sName); // // m_iVecType = 1; // m_iCombinations = 1; // g_bDipole = true; // ParseDipole(); // // if(g_iTrajSteps != -1) { // int depth = (int)(g_iTrajSteps / g_stride * 0.75); // if(depth > 4096) // depth = 4096; // m_iDepth = AskUnsignedInteger(" Enter the resolution (=depth) of the ACF (in time steps): [%d] ", depth, depth); // } else { // m_iDepth = AskUnsignedInteger(" Enter the resolution (=depth) of the ACF (in time steps): [2000] ", 2000); // } // // int size = CalcFFTSize(m_iDepth, false); // if(m_iDepth != size) { // mprintf(WHITE," The next \"fast\" size for FFT is %d. Using this instead of %d as depth.\n", size, m_iDepth); // m_iDepth = size; // } // // m_iStride = 1; // m_bSpectrum = true; // // _derivativeOrder = 1; // bool window = true; // bool derive = true; // if(g_bAdvanced2) { // derive = AskYesNo(" Derive the vectors before autocorrelation (y/n)? [yes] ", true); // if(derive) // _derivativeOrder = AskRangeInteger(" Please enter degree of vector derivative (1-2): [1] ", 1, 2, 1); // window = AskYesNo(" Apply window function (Cos^2) to autocorrelation function (y/n)? [yes] ", true); // } // double possibleRange = 33356.41f / g_fTimestepLength / 2.0f / g_stride; // mprintf(" A time step length of %.2f fs with a stride of %d allows a spectral range up to %.2f cm^-1.\n", g_fTimestepLength, g_stride, possibleRange); // double specWaveNumber = AskRangeFloat("\n Calculate spectrum up to which wave number (cm^-1)? [%.2f cm^-1] ", 0, possibleRange, (possibleRange < 5000.0f) ? possibleRange : 5000.0f, (possibleRange < 5000.0f) ? possibleRange : 5000.0f); // int mirror = 1; // int zeroPadding = m_iDepth * 3; // if(g_bAdvanced2) { // mirror = AskRangeInteger(" No mirroring (0) or short-time enhancing (1)? [1] ", 0, 1, 1); // zeroPadding = AskUnsignedInteger(" Zero Padding: How many zeros to insert? [%d] ", m_iDepth * 3, m_iDepth * 3); // } // // size = CalcFFTSize(m_iDepth + zeroPadding, false); // if(m_iDepth + zeroPadding != size) { // mprintf(WHITE, " The next \"fast\" size for FFT is %d. Using %d zeros for zero padding.\n", size, size-m_iDepth); // zeroPadding = size-m_iDepth; // } // // mprintf(" This results in a spectral resolution to %.2f cm^-1.\n\n", 33356.41 / g_fTimestepLength / 2.0f / size); // // try { _isoACF = new CACF(); } catch(...) { _isoACF = NULL; } // if(_isoACF == NULL) NewException((double)sizeof(CACF), __FILE__, __LINE__, __PRETTY_FUNCTION__); // _isoACF->m_iSize = m_iDepth; // _isoACF->m_bSpectrum = true; // _isoACF->m_bDerivative = derive; // _isoACF->m_iDerivative = _derivativeOrder; // _isoACF->m_bWindowFunction = window; // _isoACF->m_fSpecWaveNumber = specWaveNumber; // _isoACF->m_iMirror = mirror; // _isoACF->m_iZeroPadding = zeroPadding; // _isoACF->m_bACF_DB = false; // // try { _anisoACF = new CACF(); } catch(...) { _anisoACF = NULL; } // if(_anisoACF == NULL) NewException((double)sizeof(CACF), __FILE__, __LINE__, __PRETTY_FUNCTION__); // _anisoACF->m_iSize = m_iDepth; // _anisoACF->m_bSpectrum = true; // _anisoACF->m_bDerivative = derive; // _anisoACF->m_iDerivative = _derivativeOrder; // _anisoACF->m_bWindowFunction = window; // _anisoACF->m_fSpecWaveNumber = specWaveNumber; // _anisoACF->m_iMirror = mirror; // _anisoACF->m_iZeroPadding = zeroPadding; // _anisoACF->m_bACF_DB = false; // // BuildName(); // // mprintf(YELLOW, "<<< End of Raman Spectrum <<<\n\n"); // } // // CRamanDyn::~CRamanDyn() { // int i, j, k; // // for(i = 0; i < m_iMolecules; i++) // delete (CxFloatArray *)_dipole0[i]; // for(i = 0; i < m_iMolecules; i++) { // for(j = 0; j < 3; j++) { // for(k = 0; k < (g_orientAvg ? 3 : 1); k++) { // delete (CxFloatArray *)_polarizability[j][k][i]; // } // } // } // delete _isoACF; // delete _anisoACF; // } // // void CRamanDyn::initialize() { // int i, j, k; // // _isoACF->Create(); // _anisoACF->Create(); // // if (g_iTrajSteps != -1) // mprintf(" Raman Cache: Trying to allocate %s of memory...\n", FormatBytes((double)m_iMolecules * g_iTrajSteps / g_iStride / g_stride * (g_orientAvg ? 9.9 : 3.3) * sizeof(double))); // else // mprintf(" Raman Cache: Trying to allocate %s of memory...\n", FormatBytes((double)m_iMolecules * 2000 / g_iStride /g_stride * (g_orientAvg ? 9.9 : 3.3) * sizeof(double))); // for(i = 0; i < m_iMolecules; i++) { // CxDVector3 *dipoleVector; // try { dipoleVector = new CxDVector3(); } catch(...) { dipoleVector = NULL; } // if(dipoleVector == NULL) NewException((double)sizeof(CxDVector3), __FILE__, __LINE__, __PRETTY_FUNCTION__); // _dipole0.Add(dipoleVector); // } // for(i = 0; i < m_iMolecules; i++) { // for(j = 0; j < 3; j++) { // for(k = 0; k < (g_orientAvg ? 3 : 1); k++) { // CxFloatArray *doubleArray; // try { doubleArray = new CxFloatArray("CRamanDyn::initialize():doubleArray"); } catch(...) { doubleArray = NULL; } // if(doubleArray == NULL) NewException((double)sizeof(CxFloatArray), __FILE__, __LINE__, __PRETTY_FUNCTION__); // if(g_iTrajSteps != -1) { // doubleArray->SetMaxSize((long)(g_iTrajSteps / g_iStride / g_stride * 1.1)); // doubleArray->SetGrow((long)(g_iTrajSteps / g_iStride / g_stride * 0.1)); // } else { // doubleArray->SetGrow(10000); // } // _polarizability[j][k].Add(doubleArray); // } // } // } // } // // void CRamanDyn::getDipole0() { // int i; // // for(i = 0; i < m_iMolecules; i++) { // CSingleMolecule *sm; // if(_global) // sm = (CSingleMolecule *)g_oaSingleMolecules[i]; // else // sm = (CSingleMolecule *)g_oaSingleMolecules[((CMolecule *)g_oaMolecules[m_iShowMol])->m_laSingleMolIndex[i]]; // *((CxDVector3 *)_dipole0[i]) = sm->m_vDipole; // } // } // // void CRamanDyn::calcPolarizability(int fieldDirection) { // int i; // // for(i = 0; i < m_iMolecules; i++) { // CSingleMolecule *sm; // if(_global) // sm = (CSingleMolecule *)g_oaSingleMolecules[i]; // else // sm = (CSingleMolecule *)g_oaSingleMolecules[((CMolecule *)g_oaMolecules[m_iShowMol])->m_laSingleMolIndex[i]]; // for(int j = 0; j < 3; j++) { // ((CxFloatArray *)_polarizability[j][fieldDirection][i])->Add(((*((CxDVector3 *)_dipole0[i]))[j] - sm->m_vDipole[j]) / g_fieldStrength * 0.393430f); // 0.393430 - Umrechnung von Debye in a.u. // } // } // } // // void CRamanDyn::finalize() { // int i, j, k, l; // // char filename[BUF_SIZE]; // #ifdef TARGET_LINUX // snprintf(filename, BUF_SIZE, "%s/polarizability_%s.dat", g_ramanDir, m_sName); // #else // sprintf(filename, "%s/polarizability_%s.dat", g_ramanDir, m_sName); // #endif // mprintf(" Writing polarizabilities for first molecule to \"%s\"...\n", filename); // FILE *pol_file; // pol_file = OpenFileWrite(filename, false); // for(i = 0; i < ((CxFloatArray *)_polarizability[0][0][0])->GetSize(); i++) { // fprintf(pol_file, "%10.2f", i * g_fTimestepLength * g_iStride * g_stride); // for(j = 0; j < (g_orientAvg ? 3 : 1); j++) { // for(k = 0; k < 3; k++) { // fprintf(pol_file, " %14.8f", (*((CxFloatArray *)_polarizability[k][j][0]))[i]); // } // } // fprintf(pol_file, "\n"); // } // fclose(pol_file); // // double step; // switch(_derivativeOrder) { // case 0: // mprintf(" Not deriving polarizabilities.\n"); // break; // case 1: // mprintf(" Deriving polarizabilities (1st derivative)...\n"); // mprintf(WHITE, " ["); // step = m_iMolecules / 20.0f; // for(i = 0; i < m_iMolecules; i++) { // if(fmod((double)i, step) < 1.0f) // mprintf(WHITE, "#"); // for(j = 0; j < ((CxFloatArray *)_polarizability[0][0][0])->GetSize() - 1; j++) { // for(k = 0; k < 3; k++) { // for(l = 0; l < (g_orientAvg ? 3 : 1); l++) { // (*((CxFloatArray *)_polarizability[k][l][i]))[j] = 0.5f * ((*((CxFloatArray *)_polarizability[k][l][i]))[j+1] - (*((CxFloatArray *)_polarizability[k][l][i]))[j]); // } // } // } // } // mprintf(WHITE, "]\n"); // break; // case 2: // mprintf(" Deriving polarizabilities (2nd derivative)...\n"); // mprintf(WHITE, " ["); // step = m_iMolecules / 20.0f; // for(i = 0; i < m_iMolecules; i++) { // if(fmod((double)i, step) < 1.0f) // mprintf(WHITE, "#"); // for(j = 0; j < ((CxFloatArray *)_polarizability[0][0][0])->GetSize() - 2; j++) { // for(k = 0; k < 3; k++) { // for(l = 0; l < (g_orientAvg ? 3 : 1); l++) { // (*((CxFloatArray *)_polarizability[k][l][i]))[j] = (*((CxFloatArray *)_polarizability[k][l][i]))[j+2] - 2.0f * (*((CxFloatArray *)_polarizability[k][l][i]))[j+1] + (*((CxFloatArray *)_polarizability[k][l][i]))[j]; // } // } // } // } // mprintf(WHITE, "]\n"); // break; // default: // mprintf(RED, "Higher derivatives not implemented.\n"); // abort(); // break; // } // // mprintf(" Processing polarizability tensor components...\n"); // step = m_iMolecules / 20.0f; // // CAutoCorrelation *autoCorrelation; // try { autoCorrelation = new CAutoCorrelation(); } catch(...) { autoCorrelation = NULL; } // if(autoCorrelation == NULL) NewException((double)sizeof(CAutoCorrelation), __FILE__, __LINE__, __PRETTY_FUNCTION__); // autoCorrelation->Init(((CxFloatArray *)_polarizability[0][0][0])->GetSize() - _derivativeOrder, m_iDepth, g_bACFFFT); // // if(g_orientAvg) { // CxFloatArray *isotropyPol, *isotropyACF; // try { isotropyACF = new CxFloatArray("CRamanDyn::finalize():isotropyACF"); } catch(...) { isotropyACF = NULL; } // if(isotropyACF == NULL) NewException((double)sizeof(CxFloatArray), __FILE__, __LINE__, __PRETTY_FUNCTION__); // isotropyACF->SetSize(m_iDepth); // try { isotropyPol = new CxFloatArray("CRamanDyn::finalize():isotropyPol"); } catch(...) { isotropyPol = NULL; } // if(isotropyPol == NULL) NewException((double)sizeof(CxFloatArray), __FILE__, __LINE__, __PRETTY_FUNCTION__); // isotropyPol->SetSize(((CxFloatArray *)_polarizability[0][0][0])->GetSize() - _derivativeOrder); // // mprintf(" Isotropic part...\n"); // mprintf(WHITE, " ["); // for(i = 0; i < m_iDepth; i++) { // _isoACF->m_pData[i] = 0.0f; // } // for(i = 0; i < m_iMolecules; i++) { // if(fmod((double)i, step) < 1.0f) // mprintf(WHITE, "#"); // for(j = 0; j < ((CxFloatArray *)_polarizability[0][0][0])->GetSize() - _derivativeOrder; j++) { // (*isotropyPol)[j] = 0.0f; // for(k = 0; k < 3; k++) { // (*isotropyPol)[j] += (*((CxFloatArray *)_polarizability[k][k][i]))[j]; // } // (*isotropyPol)[j] /= 3.0f; // } // autoCorrelation->AutoCorrelate(isotropyPol, isotropyACF); // for(j = 0; j < m_iDepth; j++) { // _isoACF->m_pData[j] += (*isotropyACF)[j]; // } // } // for(i = 0; i < m_iDepth; i++) { // if(_global) // _isoACF->m_pData[i] /= g_iSteps / g_stride; // else // _isoACF->m_pData[i] /= g_iSteps / g_stride * m_iMolecules; // } // mprintf(WHITE, "]\n"); // // // #ifdef TARGET_LINUX // // snprintf(filename, BUF_SIZE, "%s/acf_iso_%s.dat", g_ramanDir, m_sName); // // #else // // sprintf(filename, "%s/acf_iso_%s.dat", g_ramanDir, m_sName); // // #endif // // mprintf(" Saving ACF as %s...\n", filename); // // FILE *acf_file = OpenFileWrite(filename, false); // // for(i = 0; i < m_iDepth; i++) // // fprintf(acf_file, "%10.2f %12.8f\n", i * g_fTimestepLength * g_iStride * g_stride, _isoACF->m_pData[i]); // // fclose(acf_file); // // if(_isoACF->m_iMirror != 0) { // mprintf(" Mirroring ACF...\n"); // _isoACF->Mirror(_isoACF->m_iMirror); // } // if(_isoACF->m_bWindowFunction != 0) { // mprintf(" Applying window function to ACF...\n"); // _isoACF->Window(); // } // // // #ifdef TARGET_LINUX // // snprintf(filename, BUF_SIZE, "%s/acf_iso_%s.mw.dat", g_ramanDir, m_sName); // // #else // // sprintf(filename, "%s/acf_iso_%s.mw.dat", g_ramanDir, m_sName); // // #endif // // mprintf(" Saving ACF as %s...\n", filename); // // acf_file = OpenFileWrite(filename, false); // // for(i = 0; i < _isoACF->m_iSize; i++) // // fprintf(acf_file, "%10.2f %12.8f\n", i * g_fTimestepLength * g_iStride * g_stride, _isoACF->m_pData[i]); // // fclose(acf_file); // // mprintf(" Performing Fourier transformation...\n"); // CFFT *fft; // try { fft = new CFFT(); } catch(...) { fft = NULL; } // if(fft == NULL) NewException((double)sizeof(CFFT), __FILE__, __LINE__, __PRETTY_FUNCTION__); // fft->PrepareFFT_C2C(_isoACF->m_iSize + _isoACF->m_iZeroPadding); // _isoACF->Transform(fft); // delete fft; // _isoACF->m_pSpectrum->SetMaxRWL(1e15f/299792458.0f/100.0f/g_fTimestepLength/g_iStride/g_stride); // // // #ifdef TARGET_LINUX // // snprintf(filename, BUF_SIZE, "%s/spectrum_iso_%s.dat", g_ramanDir, m_sName); // // #else // // sprintf(filename, "%s/spectrum_iso_%s.dat", g_ramanDir, m_sName); // // #endif // // mprintf(" Saving spectrum as %s...\n", filename); // // _isoACF->m_pSpectrum->Write("", filename, ""); // // delete isotropyACF; // delete isotropyPol; // // CxFloatArray *anisotropyPol, *anisotropyACF, *anisotropyACFSum; // try { anisotropyPol = new CxFloatArray("CRamanDyn::finalize():anisotropyPol"); } catch(...) { anisotropyPol = NULL; } // if(anisotropyPol == NULL) NewException((double)sizeof(CxFloatArray), __FILE__, __LINE__, __PRETTY_FUNCTION__); // anisotropyPol->SetSize(((CxFloatArray *)_polarizability[0][0][0])->GetSize() - _derivativeOrder); // try { anisotropyACF = new CxFloatArray("CRamanDyn::finalize():anisotropyACF"); } catch(...) { anisotropyACF = NULL; } // if(anisotropyACF == NULL) NewException((double)sizeof(CxFloatArray), __FILE__, __LINE__, __PRETTY_FUNCTION__); // anisotropyACF->SetSize(m_iDepth); // try { anisotropyACFSum = new CxFloatArray("CRamanDyn::finalize():anisotropyACFSum"); } catch(...) { anisotropyACFSum = NULL; } // if(anisotropyACFSum == NULL) NewException((double)sizeof(CxFloatArray), __FILE__, __LINE__, __PRETTY_FUNCTION__); // anisotropyACFSum->SetSize(m_iDepth); // // mprintf(" First anisotropic part...\n"); // mprintf(WHITE, " ["); // for(i = 0; i < m_iDepth; i++) { // _anisoACF->m_pData[i] = 0.0f; // } // for(i = 0; i < m_iMolecules; i++) { // if(fmod((double)i, step) < 1.0f) // mprintf(WHITE, "#"); // for(j = 0; j < ((CxFloatArray *)_polarizability[0][0][0])->GetSize() - _derivativeOrder; j++) { // (*anisotropyPol)[j] = (*((CxFloatArray *)_polarizability[0][0][i]))[j]; // (*anisotropyPol)[j] -= (*((CxFloatArray *)_polarizability[1][1][i]))[j]; // } // autoCorrelation->AutoCorrelate(anisotropyPol, anisotropyACF); // for(int j = 0; j < m_iDepth; j++) { // _anisoACF->m_pData[j] += (*anisotropyACF)[j]; // } // } // for(i = 0; i < m_iDepth; i++) { // (*anisotropyACFSum)[i] = 0.5f * _anisoACF->m_pData[i]; // } // mprintf(WHITE, "]\n"); // // mprintf(" Second anisotropic part...\n"); // mprintf(WHITE, " ["); // for(i = 0; i < m_iDepth; i++) { // _anisoACF->m_pData[i] = 0.0f; // } // for(i = 0; i < m_iMolecules; i++) { // if(fmod((double)i, step) < 1.0f) // mprintf(WHITE, "#"); // for(j = 0; j < ((CxFloatArray *)_polarizability[0][0][0])->GetSize() - _derivativeOrder; j++) { // (*anisotropyPol)[j] = (*((CxFloatArray *)_polarizability[1][1][i]))[j]; // (*anisotropyPol)[j] -= (*((CxFloatArray *)_polarizability[2][2][i]))[j]; // } // autoCorrelation->AutoCorrelate(anisotropyPol, anisotropyACF); // for(j = 0; j < m_iDepth; j++) { // _anisoACF->m_pData[j] += (*anisotropyACF)[j]; // } // } // for(i = 0; i < m_iDepth; i++) { // (*anisotropyACFSum)[i] += 0.5f * _anisoACF->m_pData[i]; // } // mprintf(WHITE, "]\n"); // // mprintf(" Third anisotropic part...\n"); // mprintf(WHITE, " ["); // for(i = 0; i < m_iDepth; i++) { // _anisoACF->m_pData[i] = 0.0f; // } // for(i = 0; i < m_iMolecules; i++) { // if(fmod((double)i, step) < 1.0f) // mprintf(WHITE, "#"); // for(j = 0; j < ((CxFloatArray *)_polarizability[0][0][0])->GetSize() - _derivativeOrder; j++) { // (*anisotropyPol)[j] = (*((CxFloatArray *)_polarizability[2][2][i]))[j]; // (*anisotropyPol)[j] -= (*((CxFloatArray *)_polarizability[0][0][i]))[j]; // } // autoCorrelation->AutoCorrelate(anisotropyPol, anisotropyACF); // for(j = 0; j < m_iDepth; j++) { // _anisoACF->m_pData[j] += (*anisotropyACF)[j]; // } // } // for(i = 0; i < m_iDepth; i++) { // (*anisotropyACFSum)[i] += 0.5f * _anisoACF->m_pData[i]; // } // mprintf(WHITE, "]\n"); // // mprintf(" Fourth anisotropic part...\n"); // mprintf(WHITE, " ["); // for(i = 0; i < m_iDepth; i++) { // _anisoACF->m_pData[i] = 0.0f; // } // for(i = 0; i < m_iMolecules; i++) { // if(fmod((double)i, step) < 1.0f) // mprintf(WHITE, "#"); // for(j = 0; j < ((CxFloatArray *)_polarizability[0][0][0])->GetSize() - _derivativeOrder; j++) { // (*anisotropyPol)[j] = (*((CxFloatArray *)_polarizability[0][1][i]))[j]; // (*anisotropyPol)[j] += (*((CxFloatArray *)_polarizability[1][0][i]))[j]; // (*anisotropyPol)[j] *= 0.5f; // } // autoCorrelation->AutoCorrelate(anisotropyPol, anisotropyACF); // for(j = 0; j < m_iDepth; j++) { // _anisoACF->m_pData[j] += (*anisotropyACF)[j]; // } // } // for(i = 0; i < m_iDepth; i++) { // (*anisotropyACFSum)[i] += 3.0f * _anisoACF->m_pData[i]; // } // mprintf(WHITE, "]\n"); // // mprintf(" Fifth anisotropic part...\n"); // mprintf(WHITE, " ["); // for(i = 0; i < m_iDepth; i++) { // _anisoACF->m_pData[i] = 0.0f; // } // for(i = 0; i < m_iMolecules; i++) { // if(fmod((double)i, step) < 1.0f) // mprintf(WHITE, "#"); // for(j = 0; j < ((CxFloatArray *)_polarizability[0][0][0])->GetSize() - _derivativeOrder; j++) { // (*anisotropyPol)[j] = (*((CxFloatArray *)_polarizability[1][2][i]))[j]; // (*anisotropyPol)[j] += (*((CxFloatArray *)_polarizability[2][1][i]))[j]; // (*anisotropyPol)[j] *= 0.5f; // } // autoCorrelation->AutoCorrelate(anisotropyPol, anisotropyACF); // for(j = 0; j < m_iDepth; j++) { // _anisoACF->m_pData[j] += (*anisotropyACF)[j]; // } // } // for(i = 0; i < m_iDepth; i++) { // (*anisotropyACFSum)[i] += 3.0f * _anisoACF->m_pData[i]; // } // mprintf(WHITE, "]\n"); // // mprintf(" Sixth anisotropic part...\n"); // mprintf(WHITE, " ["); // for(i = 0; i < m_iDepth; i++) { // _anisoACF->m_pData[i] = 0.0f; // } // for(i = 0; i < m_iMolecules; i++) { // if(fmod((double)i, step) < 1.0f) // mprintf(WHITE, "#"); // for(j = 0; j < ((CxFloatArray *)_polarizability[0][0][0])->GetSize() - _derivativeOrder; j++) { // (*anisotropyPol)[j] = (*((CxFloatArray *)_polarizability[2][0][i]))[j]; // (*anisotropyPol)[j] += (*((CxFloatArray *)_polarizability[0][2][i]))[j]; // (*anisotropyPol)[j] *= 0.5f; // } // autoCorrelation->AutoCorrelate(anisotropyPol, anisotropyACF); // for(j = 0; j < m_iDepth; j++) { // _anisoACF->m_pData[j] += (*anisotropyACF)[j]; // } // } // for(i = 0; i < m_iDepth; i++) { // (*anisotropyACFSum)[i] += 3.0f * _anisoACF->m_pData[i]; // } // mprintf(WHITE, "]\n"); // // for(i = 0; i < m_iDepth; i++) { // if(_global) // _anisoACF->m_pData[i] = (*anisotropyACFSum)[i] / g_iSteps * g_stride; // else // _anisoACF->m_pData[i] = (*anisotropyACFSum)[i] / g_iSteps * g_stride / m_iMolecules; // } // // // #ifdef TARGET_LINUX // // snprintf(filename, BUF_SIZE, "%s/acf_aniso_%s.dat", g_ramanDir, m_sName); // // #else // // sprintf(filename, "%s/acf_aniso_%s.dat", g_ramanDirm_sName); // // #endif // // mprintf(" Saving ACF as %s...\n", filename); // // acf_file = OpenFileWrite(filename, false); // // for(i = 0; i < m_iDepth; i++) // // fprintf(acf_file, "%10.2f %12.8f\n", i * g_fTimestepLength * g_iStride * g_stride, _anisoACF->m_pData[i]); // // fclose(acf_file); // // if(_anisoACF->m_iMirror != 0) { // mprintf(" Mirroring ACF...\n"); // _anisoACF->Mirror(_anisoACF->m_iMirror); // } // if(_anisoACF->m_bWindowFunction != 0) { // mprintf(" Applying window function to ACF...\n"); // _anisoACF->Window(); // } // // // #ifdef TARGET_LINUX // // snprintf(filename, BUF_SIZE, "%s/acf_aniso_%s.mw.dat", g_ramanDir, m_sName); // // #else // // sprintf(filename, "%s/acf_aniso_%s.mw.dat", g_ramanDir, m_sName); // // #endif // // mprintf(" Saving ACF as %s...\n", filename); // // acf_file = OpenFileWrite(filename, false); // // for(i = 0; i < _anisoACF->m_iSize; i++) // // fprintf(acf_file, "%10.2f %12.8f\n", i * g_fTimestepLength * g_iStride * g_stride, _anisoACF->m_pData[i]); // // fclose(acf_file); // // mprintf(" Performing Fourier transformation...\n"); // try { fft = new CFFT(); } catch(...) { fft = NULL; } // if(fft == NULL) NewException((double)sizeof(CFFT), __FILE__, __LINE__, __PRETTY_FUNCTION__); // fft->PrepareFFT_C2C(_anisoACF->m_iSize + _anisoACF->m_iZeroPadding); // _anisoACF->Transform(fft); // delete fft; // _anisoACF->m_pSpectrum->SetMaxRWL(1e15f/299792458.0f/100.0f/g_fTimestepLength/g_iStride/g_stride); // // // #ifdef TARGET_LINUX // // snprintf(filename, BUF_SIZE, "%s/spectrum_aniso_%s.dat", g_ramanDir, m_sName); // // #else // // sprintf(filename, "%s/spectrum_aniso_%s.dat", g_ramanDir, m_sName); // // #endif // // mprintf(" Saving spectrum as %s...\n", filename); // // _anisoACF->m_pSpectrum->Write("", filename, ""); // // int specSize = _isoACF->m_pSpectrum->m_iSize; // CSpectrum *paraSpectrum, *orthoSpectrum, *sumSpectrum, *depolSpectrum; // try { paraSpectrum = new CSpectrum(); } catch(...) { paraSpectrum = NULL; } // if(paraSpectrum == NULL) NewException((double)sizeof(CSpectrum), __FILE__, __LINE__, __PRETTY_FUNCTION__); // paraSpectrum->m_fWaveNumber = _isoACF->m_fSpecWaveNumber; // paraSpectrum->Create(specSize); // paraSpectrum->SetMaxRWL(1e15f/299792458.0f/100.0f/g_fTimestepLength/g_iStride/g_stride); // try { orthoSpectrum = new CSpectrum(); } catch(...) { orthoSpectrum = NULL; } // if(orthoSpectrum == NULL) NewException((double)sizeof(CSpectrum), __FILE__, __LINE__, __PRETTY_FUNCTION__); // orthoSpectrum->m_fWaveNumber = _isoACF->m_fSpecWaveNumber; // orthoSpectrum->Create(specSize); // orthoSpectrum->SetMaxRWL(1e15f/299792458.0f/100.0f/g_fTimestepLength/g_iStride/g_stride); // try { sumSpectrum = new CSpectrum(); } catch(...) { sumSpectrum = NULL; } // if(sumSpectrum == NULL) NewException((double)sizeof(CSpectrum), __FILE__, __LINE__, __PRETTY_FUNCTION__); // sumSpectrum->m_fWaveNumber = _isoACF->m_fSpecWaveNumber; // sumSpectrum->Create(specSize); // sumSpectrum->SetMaxRWL(1e15f/299792458.0f/100.0f/g_fTimestepLength/g_iStride/g_stride); // try { depolSpectrum = new CSpectrum(); } catch(...) { depolSpectrum = NULL; } // if(depolSpectrum == NULL) NewException((double)sizeof(CSpectrum), __FILE__, __LINE__, __PRETTY_FUNCTION__); // depolSpectrum->m_fWaveNumber = _isoACF->m_fSpecWaveNumber; // depolSpectrum->Create(specSize); // depolSpectrum->SetMaxRWL(1e15f/299792458.0f/100.0f/g_fTimestepLength/g_iStride/g_stride); // // for(i = 0; i < specSize; i++) { // paraSpectrum->m_pData[i] = _isoACF->m_pSpectrum->m_pData[i] + 4.0f / 45.0f * _anisoACF->m_pSpectrum->m_pData[i]; // } // // // #ifdef TARGET_LINUX // // snprintf(filename, BUF_SIZE, "%s/spectrum_para_%s.dat", g_ramanDir, m_sName); // // #else // // sprintf(filename, "%s/spectrum_para_%s.dat", g_ramanDir, m_sName); // // #endif // // mprintf(" Saving para spectrum as %s...\n", filename); // // paraSpectrum->Write("", filename, ""); // // for(i = 0; i < specSize; i++) { // orthoSpectrum->m_pData[i] = _anisoACF->m_pSpectrum->m_pData[i] / 15.0f; // } // // // #ifdef TARGET_LINUX // // snprintf(filename, BUF_SIZE, "%s/spectrum_ortho_%s.dat", g_ramanDir, m_sName); // // #else // // sprintf(filename, "%s/spectrum_ortho_%s.dat", g_ramanDir, m_sName); // // #endif // // mprintf(" Saving ortho spectrum as %s...\n", filename); // // orthoSpectrum->Write("", filename, ""); // // for(i = 0; i < specSize; i++) { // sumSpectrum->m_pData[i] = paraSpectrum->m_pData[i] + orthoSpectrum->m_pData[i]; // } // // // #ifdef TARGET_LINUX // // snprintf(filename, BUF_SIZE, "%s/spectrum_unpol_%s.dat", g_ramanDir, m_sName); // // #else // // sprintf(filename, "%s/spectrum_unpol_%s.dat", g_ramanDir, m_sName); // // #endif // // mprintf(" Saving unpolarized spectrum as %s...\n", filename); // // sumSpectrum->Write("", filename, ""); // // for(i = 0; i < specSize; i++) { // double freq = i * paraSpectrum->m_fMaxRWL / paraSpectrum->m_iSize; // double crossSecFactor = pow(g_laser - freq, 4) / freq / (1 - exp(-1.438777f * freq / g_temp)); // paraSpectrum->m_pData[i] *= crossSecFactor; // orthoSpectrum->m_pData[i] *= crossSecFactor; // sumSpectrum->m_pData[i] *= crossSecFactor; // } // // for(i = 0; i < specSize; i++) { // depolSpectrum->m_pData[i] = orthoSpectrum->m_pData[i] / paraSpectrum->m_pData[i]; // } // // #ifdef TARGET_LINUX // snprintf(filename, BUF_SIZE, "%s/spectrum_para_%s.csv", g_ramanDir, m_sName); // #else // sprintf(filename, "%s/spectrum_para_%s.csv", g_ramanDir, m_sName); // #endif // mprintf(" Saving parallel spectrum as %s...\n", filename); // paraSpectrum->Write("", filename, ""); // // #ifdef TARGET_LINUX // snprintf(filename, BUF_SIZE, "%s/spectrum_ortho_%s.csv", g_ramanDir, m_sName); // #else // sprintf(filename, "%s/spectrum_ortho_%s.csv", g_ramanDir, m_sName); // #endif // mprintf(" Saving orthogonal spectrum as %s...\n", filename); // orthoSpectrum->Write("", filename, ""); // // #ifdef TARGET_LINUX // snprintf(filename, BUF_SIZE, "%s/spectrum_unpol_%s.csv", g_ramanDir, m_sName); // #else // sprintf(filename, "%s/spectrum_unpol_%s.csv", g_ramanDir, m_sName); // #endif // mprintf(" Saving unpolarized spectrum as %s...\n", filename); // sumSpectrum->Write("", filename, ""); // // #ifdef TARGET_LINUX // snprintf(filename, BUF_SIZE, "%s/depol_ratio_%s.csv", g_ramanDir, m_sName); // #else // sprintf(filename, "%s/depol_ratio_%s.csv", g_ramanDir, m_sName); // #endif // mprintf(" Saving depolarization ratio as %s...\n", filename); // depolSpectrum->Write("", filename, ""); // // delete anisotropyACFSum; // delete anisotropyACF; // delete anisotropyPol; // // delete paraSpectrum; // delete orthoSpectrum; // delete sumSpectrum; // delete depolSpectrum; // } else { // CxFloatArray *ACF; // try { ACF = new CxFloatArray("CRamanDyn::finalize():ACF"); } catch(...) { ACF = NULL; } // if(ACF == NULL) NewException((double)sizeof(CxFloatArray), __FILE__, __LINE__, __PRETTY_FUNCTION__); // ACF->SetSize(m_iDepth); // // mprintf(" Parallel part...\n"); // mprintf(WHITE, " ["); // for(i = 0; i < m_iDepth; i++) { // _isoACF->m_pData[i] = 0.0f; // } // for(i = 0; i < m_iMolecules; i++) { // if(fmod((double)i, step) < 1.0f) // mprintf(WHITE, "#"); // autoCorrelation->AutoCorrelate((CxFloatArray *)_polarizability[0][0][i], ACF); // for(int j = 0; j < m_iDepth; j++) { // _isoACF->m_pData[j] += (*ACF)[j]; // } // } // for(i = 0; i < m_iDepth; i++) { // if(_global) // _isoACF->m_pData[i] /= g_iSteps / g_stride; // else // _isoACF->m_pData[i] /= g_iSteps / g_stride * m_iMolecules; // } // mprintf(WHITE, "]\n"); // // // #ifdef TARGET_LINUX // // snprintf(filename, BUF_SIZE, "%s/acf_para_%s.dat", g_ramanDir, m_sName); // // #else // // sprintf(filename, "%s/acf_para_%s.dat", g_ramanDir, m_sName); // // #endif // // mprintf(" Saving ACF as %s...\n", filename); // // FILE *acf_file = OpenFileWrite(filename, false); // // for(i = 0; i < m_iDepth; i++) // // fprintf(acf_file, "%10.2f %12.8f\n", i * g_fTimestepLength * g_iStride * g_stride, _isoACF->m_pData[i]); // // fclose(acf_file); // // if(_isoACF->m_iMirror != 0) { // mprintf(" Mirroring ACF...\n"); // _isoACF->Mirror(_isoACF->m_iMirror); // } // if(_isoACF->m_bWindowFunction != 0) { // mprintf(" Applying window function to ACF...\n"); // _isoACF->Window(); // } // // // #ifdef TARGET_LINUX // // snprintf(filename, BUF_SIZE, "%s/acf_para_%s.mw.dat", g_ramanDir, m_sName); // // #else // // sprintf(filename, "%s/acf_para_%s.mw.dat", g_ramanDir, m_sName); // // #endif // // mprintf(" Saving ACF as %s...\n", filename); // // acf_file = OpenFileWrite(filename, false); // // for(i = 0; i < _isoACF->m_iSize; i++) // // fprintf(acf_file, "%10.2f %12.8f\n", i * g_fTimestepLength * g_iStride * g_stride, _isoACF->m_pData[i]); // // fclose(acf_file); // // mprintf(" Performing Fourier transformation...\n"); // CFFT *fft; // try { fft = new CFFT(); } catch(...) { fft = NULL; } // if(fft == NULL) NewException((double)sizeof(CFFT), __FILE__, __LINE__, __PRETTY_FUNCTION__); // fft->PrepareFFT_C2C(_isoACF->m_iSize + _isoACF->m_iZeroPadding); // _isoACF->Transform(fft); // delete fft; // _isoACF->m_pSpectrum->SetMaxRWL(1e15f/299792458.0f/100.0f/g_fTimestepLength/g_iStride/g_stride); // // // #ifdef TARGET_LINUX // // snprintf(filename, BUF_SIZE, "%s/spectrum_para_%s.dat", g_ramanDir, m_sName); // // #else // // sprintf(filename, "%s/spectrum_para_%s.dat", g_ramanDir, m_sName); // // #endif // // mprintf(" Saving spectrum as %s...\n", filename); // // _isoACF->m_pSpectrum->Write("", filename, ""); // // mprintf(" Orthogonal part...\n"); // mprintf(WHITE, " ["); // for(i = 0; i < m_iDepth; i++) { // _anisoACF->m_pData[i] = 0.0f; // } // for(i = 0; i < m_iMolecules; i++) { // if(fmod((double)i, step) < 1.0f) // mprintf(WHITE, "#"); // autoCorrelation->AutoCorrelate((CxFloatArray *)_polarizability[1][0][i], ACF); // for(int j = 0; j < m_iDepth; j++) { // _anisoACF->m_pData[j] += (*ACF)[j]; // } // } // for(i = 0; i < m_iDepth; i++) { // if(_global) // _anisoACF->m_pData[i] /= g_iSteps / g_stride; // else // _anisoACF->m_pData[i] /= g_iSteps / g_stride * m_iMolecules; // } // mprintf(WHITE, "]\n"); // // // #ifdef TARGET_LINUX // // snprintf(filename, BUF_SIZE, "%s/acf_ortho_%s.dat", g_ramanDir, m_sName); // // #else // // sprintf(filename, "%s/acf_ortho_%s.dat", g_ramanDir, m_sName); // // #endif // // mprintf(" Saving ACF as %s...\n", filename); // // acf_file = OpenFileWrite(filename, false); // // for(i = 0; i < m_iDepth; i++) // // fprintf(acf_file, "%10.2f %12.8f\n", i * g_fTimestepLength * g_iStride * g_stride, _anisoACF->m_pData[i]); // // fclose(acf_file); // // if(_anisoACF->m_iMirror != 0) { // mprintf(" Mirroring ACF...\n"); // _anisoACF->Mirror(_isoACF->m_iMirror); // } // if(_anisoACF->m_bWindowFunction != 0) { // mprintf(" Applying window function to ACF...\n"); // _anisoACF->Window(); // } // // // #ifdef TARGET_LINUX // // snprintf(filename, BUF_SIZE, "%s/acf_ortho_%s.mw.dat", g_ramanDir, m_sName); // // #else // // sprintf(filename, "%s/acf_ortho_%s.mw.dat", g_ramanDir, m_sName); // // #endif // // mprintf(" Saving ACF as %s...\n", filename); // // acf_file = OpenFileWrite(filename, false); // // for(i = 0; i < _isoACF->m_iSize; i++) // // fprintf(acf_file, "%10.2f %12.8f\n", i * g_fTimestepLength * g_iStride * g_stride, _anisoACF->m_pData[i]); // // fclose(acf_file); // // mprintf(" Performing Fourier transformation...\n"); // try { fft = new CFFT(); } catch(...) { fft = NULL; } // if(fft == NULL) NewException((double)sizeof(CFFT), __FILE__, __LINE__, __PRETTY_FUNCTION__); // fft->PrepareFFT_C2C(_anisoACF->m_iSize + _anisoACF->m_iZeroPadding); // _anisoACF->Transform(fft); // delete fft; // _anisoACF->m_pSpectrum->SetMaxRWL(1e15f/299792458.0f/100.0f/g_fTimestepLength/g_iStride/g_stride); // // // #ifdef TARGET_LINUX // // snprintf(filename, BUF_SIZE, "%s/spectrum_ortho_%s.dat", g_ramanDir, m_sName); // // #else // // sprintf(filename, "%s/spectrum_ortho_%s.dat", g_ramanDir, m_sName); // // #endif // // mprintf(" Saving spectrum as %s...\n", filename); // // _anisoACF->m_pSpectrum->Write("", filename, ""); // // delete ACF; // // int specSize = _isoACF->m_pSpectrum->m_iSize; // CSpectrum *sumSpectrum, *depolSpectrum; // try { sumSpectrum = new CSpectrum(); } catch(...) { sumSpectrum = NULL; } // if(sumSpectrum == NULL) NewException((double)sizeof(CSpectrum), __FILE__, __LINE__, __PRETTY_FUNCTION__); // sumSpectrum->m_fWaveNumber = _isoACF->m_fSpecWaveNumber; // sumSpectrum->Create(specSize); // sumSpectrum->SetMaxRWL(1e15f/299792458.0f/100.0f/g_fTimestepLength/g_iStride/g_stride); // try { depolSpectrum = new CSpectrum(); } catch(...) { depolSpectrum = NULL; } // if(depolSpectrum == NULL) NewException((double)sizeof(CSpectrum), __FILE__, __LINE__, __PRETTY_FUNCTION__); // depolSpectrum->m_fWaveNumber = _isoACF->m_fSpecWaveNumber; // depolSpectrum->Create(specSize); // depolSpectrum->SetMaxRWL(1e15f/299792458.0f/100.0f/g_fTimestepLength/g_iStride/g_stride); // // for(i = 0; i < specSize; i++) { // sumSpectrum->m_pData[i] = _isoACF->m_pSpectrum->m_pData[i] + _anisoACF->m_pSpectrum->m_pData[i]; // } // // // #ifdef TARGET_LINUX // // snprintf(filename, BUF_SIZE, "%s/spectrum_unpol_%s.dat", g_ramanDir, m_sName); // // #else // // sprintf(filename, "%s/spectrum_unpol_%s.dat", g_ramanDir, m_sName); // // #endif // // mprintf(" Saving unpolarized spectrum as %s...\n", filename); // // sumSpectrum->Write("", filename, ""); // // for(i = 0; i < specSize; i++) { // double freq = i * _isoACF->m_pSpectrum->m_fMaxRWL / _isoACF->m_pSpectrum->m_iSize; // double crossSecFactor = pow(g_laser - freq, 4) / freq / (1 - exp(-1.438777f * freq / g_temp)); // _isoACF->m_pSpectrum->m_pData[i] *= crossSecFactor; // _anisoACF->m_pSpectrum->m_pData[i] *= crossSecFactor; // sumSpectrum->m_pData[i] *= crossSecFactor; // } // // for(i = 0; i < specSize; i++) { // depolSpectrum->m_pData[i] = _anisoACF->m_pSpectrum->m_pData[i] / _isoACF->m_pSpectrum->m_pData[i]; // } // // #ifdef TARGET_LINUX // snprintf(filename, BUF_SIZE, "%s/spectrum_para_%s.csv", g_ramanDir, m_sName); // #else // sprintf(filename, "%s/spectrum_para_%s.csv", g_ramanDir, m_sName); // #endif // mprintf(" Saving parallel spectrum as %s...\n", filename); // _isoACF->m_pSpectrum->Write("", filename, ""); // // #ifdef TARGET_LINUX // snprintf(filename, BUF_SIZE, "%s/spectrum_ortho_%s.csv", g_ramanDir, m_sName); // #else // sprintf(filename, "%s/spectrum_ortho_%s.csv", g_ramanDir, m_sName); // #endif // mprintf(" Saving orthogonal spectrum as %s...\n", filename); // _anisoACF->m_pSpectrum->Write("", filename, ""); // // #ifdef TARGET_LINUX // snprintf(filename, BUF_SIZE, "%s/spectrum_unpol_%s.csv", g_ramanDir, m_sName); // #else // sprintf(filename, "%s/spectrum_unpol_%s.csv", g_ramanDir, m_sName); // #endif // mprintf(" Saving unpolarized spectrum as %s...\n", filename); // sumSpectrum->Write("", filename, ""); // // #ifdef TARGET_LINUX // snprintf(filename, BUF_SIZE, "%s/depol_ratio_%s.csv", g_ramanDir, m_sName); // #else // sprintf(filename, "%s/depol_ratio_%s.csv", g_ramanDir, m_sName); // #endif // mprintf(" Saving depolarization ratio as %s...\n", filename); // depolSpectrum->Write("", filename, ""); // // delete sumSpectrum; // delete depolSpectrum; // } // // delete autoCorrelation; // } CRamanObservation::CRamanObservation(bool global) { int i; if(global) { m_iShowMol = -1; m_iShowMolCount = g_oaSingleMolecules.GetSize(); _name = new char[7]; sprintf(_name, "global"); } else { char buf[BUF_SIZE]; char buf2[BUF_SIZE]; size_t remaining = BUF_SIZE; if(g_oaMolecules.GetSize() > 1) { #ifdef TARGET_LINUX remaining -= snprintf(buf, remaining, " Which molecule should be observed ("); #else remaining -= sprintf(buf, " Which molecule should be observed ("); #endif for(i = 0; i < g_oaMolecules.GetSize(); i++) { if(remaining < 1) break; #ifdef TARGET_LINUX size_t length = snprintf(buf2, remaining, "%s=%d", ((CMolecule *)g_oaMolecules[i])->m_sName, i+1); #else size_t length = sprintf(buf2, "%s=%d", ((CMolecule *)g_oaMolecules[i])->m_sName, i+1); #endif strncat(buf, buf2, remaining - 1); remaining -= length; if(i < g_oaMolecules.GetSize() - 1) { #ifdef TARGET_LINUX length = snprintf(buf2, remaining, ", "); #else length = sprintf(buf2, ", "); #endif strncat(buf, buf2, remaining - 1); remaining -= length; } } strncat(buf, ")? ", remaining - 1); m_iShowMol = AskRangeInteger_ND("%s", 1, g_oaMolecules.GetSize(),(const char*)buf) - 1; } else { m_iShowMol = 0; mprintf(" Observing molecule %s.\n", ((CMolecule *)g_oaMolecules[m_iShowMol])->m_sName); } m_iShowMolCount = ((CMolecule *)g_oaMolecules[m_iShowMol])->m_laSingleMolIndex.GetSize(); _name = new char[strlen(((CMolecule *)g_oaMolecules[m_iShowMol])->m_sName) + 1]; strcpy(_name, ((CMolecule *)g_oaMolecules[m_iShowMol])->m_sName); mprintf("\n"); } if (!g_ramanCompat) { mprintf(" If the full polarizability tensor is available, you can do orientational averaging.\n Otherwise, please specify the field polarization used to calculate the polarizability.\n\n"); int def = 0; if (g_iPolarizabilityConf[0] > 0 && g_iPolarizabilityConf[1] > 0 && g_iPolarizabilityConf[2] > 0) { def = 1; } else { if (g_iPolarizabilityConf[0] > 0) def = 2; else if (g_iPolarizabilityConf[1] > 0) def = 3; else if (g_iPolarizabilityConf[2] > 0) def = 4; } if (def > 0) { m_fieldMode = AskRangeInteger(" Use orientational averaging (1), field along x axis (2), field along y axis (3), or field along z axis (4)? [%d] ", 1, 4, def, def); } else { m_fieldMode = AskRangeInteger_ND(" Use orientational averaging (1), field along x axis (2), field along y axis (3), or field along z axis (4)? ", 1, 4); } mprintf("\n The scattering cross sections are calculated for:\n"); if (m_fieldMode == 1 || m_fieldMode == 2) mprintf(" x polarized incident laser beam propagating along the y axis with detection in z direction.\n"); else if (m_fieldMode == 3) mprintf(" y polarized incident laser beam propagating along the z axis with detection in x direction.\n"); else if (m_fieldMode == 4) mprintf(" z polarized incident laser beam propagating along the x axis with detection in y direction.\n"); mprintf("\n"); } else { if (g_orientAvg) m_fieldMode = 1; else m_fieldMode = 2; } if(g_iTrajSteps != -1) { _correlationDepth = (int)(0.75 * g_iTrajSteps); if(_correlationDepth > 4096) _correlationDepth = 4096; if(g_fTimestepLength * g_stride > 1.0) _correlationDepth = 2048; if(g_fTimestepLength * g_stride > 2.0) _correlationDepth = 1024; _correlationDepth = AskUnsignedInteger(" Enter the resolution (=depth) of the ACF (in time steps): [%d] ", _correlationDepth, _correlationDepth); } else { _correlationDepth = AskUnsignedInteger(" Enter the resolution (=depth) of the ACF (in time steps): [256] ", 256); } int size = CalcFFTSize(_correlationDepth, false); if(_correlationDepth != size) { mprintf(WHITE, " The next \"fast\" size for FFT is %d. Using this instead of %d as depth.\n", size, _correlationDepth); _correlationDepth = size; } if(g_bAdvanced2) { _windowFunction = AskRangeInteger(" Window function: cos^2(a*t) (1), exp(-t/a) (2), exp(-(t/a)^2) (3) [1] ", 1, 3, 1); if(_windowFunction == 1) { mprintf(" The parameter \"a\" is chosen according to the correlation depth.\n"); _windowFunctionParameter = 0; } else if(_windowFunction == 2) { _windowFunctionParameter = AskUnsignedInteger(" Parameter \"a\" (in time steps): [%d] ", _correlationDepth / 4, _correlationDepth / 4); } else if(_windowFunction == 3) { _windowFunctionParameter = AskUnsignedInteger(" Parameter \"a\" (in time steps): [%d] ", _correlationDepth / 2, _correlationDepth / 2); } else { eprintf("This is impossible.\n"); abort(); } } else { _windowFunction = 1; _windowFunctionParameter = 0; } if(g_bAdvanced2) { _zeroPadding = AskUnsignedInteger(" Zero Padding: How many zeros to insert? [%d] ", _correlationDepth * 3, _correlationDepth * 3); size = CalcFFTSize(_correlationDepth + _zeroPadding, false); if(_correlationDepth + _zeroPadding != size) { mprintf(WHITE, " The next \"fast\" size for FFT is %d. Using %d zeros for zero padding.\n", size, size-_correlationDepth); _zeroPadding = size-_correlationDepth; } } else { _zeroPadding = _correlationDepth * 3; size = CalcFFTSize(_correlationDepth + _zeroPadding, false); if(_correlationDepth + _zeroPadding != size) { mprintf(WHITE, " The next \"fast\" size for FFT is %d. Using %d zeros for zero padding.\n", size, size-_correlationDepth); _zeroPadding = size-_correlationDepth; } } double possibleRange = 33356.41 / g_fTimestepLength / g_stride / 2.0; _specResolution = possibleRange / (_correlationDepth + _zeroPadding); mprintf(" This results in a spectral resolution of %.2f cm^-1.\n", _specResolution); mprintf("\n A time step length of %.2f fs with a stride of %d allows a spectral range up to %.2f cm^-1.\n", g_fTimestepLength, g_stride, possibleRange); double specLimit = AskRangeFloat("\n Calculate spectrum up to which wave number (cm^-1)? [%.2f cm^-1] ", 0, possibleRange, (possibleRange < 5000.0) ? possibleRange : 5000.0, (possibleRange < 5000.0) ? possibleRange : 5000.0); _specSize = (int)(specLimit / _specResolution); mprintf("\n"); if(g_bAdvanced2) { _finiteDifferenceCorrection = AskYesNo(" Apply finite difference correction (y/n)? [yes] ", true); mprintf("\n"); } else { _finiteDifferenceCorrection = true; } if(g_bAdvanced2) { _saveACF = AskYesNo(" Save autocorrelation functions (y/n)? [no] ", false); mprintf("\n"); } else { _saveACF = false; } if(g_bAdvanced2 && m_iShowMol == -1) { _includeCross = AskYesNo(" Include also cross-correlations (y/n)? [no] ", false); if(_includeCross) { mprintf(RED, " This is not implemented.\n"); } mprintf("\n"); } else { _includeCross = false; } { _quantumCorrection = 1; } _laserFreq = AskFloat(" Calculate scattering cross section for which laser wave number (cm^-1)? [20000.0] ", 20000.0); _temperature = AskFloat(" Calculate scattering cross section for which temperature (K)? [300.0] ", 300.0); mprintf("\n"); // try { _ramanDyn = new CRamanDyn(m_iShowMol, global); } catch(...) { _ramanDyn = NULL; } // if(_ramanDyn == NULL) NewException((double)sizeof(CRamanDyn), __FILE__, __LINE__, __PRETTY_FUNCTION__); } CRamanObservation::~CRamanObservation() { delete[] _name; // delete _ramanDyn; } void CRamanObservation::initialize() { int n; if(g_iTrajSteps != -1) n = (int)(1.1 * g_iTrajSteps / g_iStride); else n = 10000; if (g_ramanCompat) { _dipoleZero.SetSize(m_iShowMolCount); if(g_orientAvg) { mprintf(" Polarizability cache: Trying to allocate %s of memory...\n", FormatBytes((double)m_iShowMolCount * 3.0 * n * sizeof(double))); } else { mprintf(" Polarizability cache: Trying to allocate %s of memory...\n", FormatBytes((double)m_iShowMolCount * 9.0 * n * sizeof(double))); } int i, j, k; for(i = 0; i < m_iShowMolCount; i++) { for(j = 0; j < 3; j++) { for(k = 0; k < (g_orientAvg ? 3 : 1); k++) { CxDoubleArray *a; try { a = new CxDoubleArray(); } catch(...) { a = NULL; } if(a == NULL) NewException((double)sizeof(CxDoubleArray), __FILE__, __LINE__, __PRETTY_FUNCTION__); a->SetMaxSize(n); a->SetGrow(n / 10); _polarizabilityCache.Add(a); } } } } else { mprintf(" Polarizability cache: Trying to allocate %s of memory...\n", FormatBytes((double)m_iShowMolCount * 9.0 * n * sizeof(double))); int i; for (i = 0; i < m_iShowMolCount; i++) { int j; for (j = 0; j < 9; j++) { CxDoubleArray *a; try { a = new CxDoubleArray; } catch (...) { a = NULL; } if (a == NULL) NewException((double)sizeof(CxDoubleArray), __FILE__, __LINE__, __PRETTY_FUNCTION__); a->SetMaxSize(n); a->SetGrow(n / 10); _polarizabilityCache.Add(a); } } } // _ramanDyn->initialize(); } void CRamanObservation::getDipoleZero() { int i; if(m_iShowMol == -1) { for(i = 0; i < m_iShowMolCount; i++) { CSingleMolecule *sm = (CSingleMolecule *)g_oaSingleMolecules[i]; _dipoleZero[i] = sm->m_vDipole; } } else { for(i = 0; i < m_iShowMolCount; i++) { CSingleMolecule *sm = (CSingleMolecule *)g_oaSingleMolecules[((CMolecule *)g_oaMolecules[m_iShowMol])->m_laSingleMolIndex[i]]; _dipoleZero[i] = sm->m_vDipole; } } // _ramanDyn->getDipole0(); } void CRamanObservation::calcPolarizability(int fieldDirection) { int i, j; if(m_iShowMol == -1) { for(i = 0; i < m_iShowMolCount; i++) { CSingleMolecule *sm = (CSingleMolecule *)g_oaSingleMolecules[i]; for(j = 0; j < 3; j++) { ((CxDoubleArray *)_polarizabilityCache[3*m_iShowMolCount * fieldDirection + m_iShowMolCount * j + i])->Add((_dipoleZero[i][j] - sm->m_vDipole[j]) / g_fieldStrength * 0.393430); // Conversion from Debye to a.u. } } } else { for(i = 0; i < m_iShowMolCount; i++) { CSingleMolecule *sm = (CSingleMolecule *)g_oaSingleMolecules[((CMolecule *)g_oaMolecules[m_iShowMol])->m_laSingleMolIndex[i]]; for(j = 0; j < 3; j++) { ((CxDoubleArray *)_polarizabilityCache[3*m_iShowMolCount * fieldDirection + m_iShowMolCount * j + i])->Add((_dipoleZero[i][j] - sm->m_vDipole[j]) / g_fieldStrength * 0.393430); // Conversion from Debye to a.u. } } } // _ramanDyn->calcPolarizability(fieldDirection); } void CRamanObservation::process() { if (m_iShowMol == -1) { int i; for (i = 0; i < m_iShowMolCount; i++) { CSingleMolecule *sm = (CSingleMolecule *)g_oaSingleMolecules[i]; int j; for (j = 0; j < 9; j++) { ((CxDoubleArray *)_polarizabilityCache[m_iShowMolCount * j + i])->Add(sm->m_polarizability[j]); } } } else { int i; for (i = 0; i < m_iShowMolCount; i++) { CSingleMolecule *sm = (CSingleMolecule *)g_oaSingleMolecules[((CMolecule *)g_oaMolecules[m_iShowMol])->m_laSingleMolIndex[i]]; int j; for (j = 0; j < 9; j++) { ((CxDoubleArray *)_polarizabilityCache[m_iShowMolCount * j + i])->Add(sm->m_polarizability[j]); } } } } void CRamanObservation::finalize() { int i, j, k, l; CxString filename; if(_saveACF) { if (g_ramanCompat) filename.sprintf("%s/polarizability_%s.dat", g_ramanDir, _name); else filename.sprintf("polarizability_%s.dat", _name); mprintf(" Saving polarizabilities for first molecule as %s...\n", (const char *)filename); FILE *pol_file; pol_file = OpenFileWrite(filename, false); for(i = 0; i < ((CxDoubleArray *)_polarizabilityCache[0])->GetSize(); i++) { fprintf(pol_file, "%.2f;", i * g_fTimestepLength * g_iStride * g_stride); if (g_ramanCompat) { for(j = 0; j < 3; j++) { for(k = 0; k < (g_orientAvg ? 3 : 1); k++) { fprintf(pol_file, " %.8G;", ((CxDoubleArray *)_polarizabilityCache[3*m_iShowMolCount * k + m_iShowMolCount * j])->GetAt(i)); } } } else { for (j = 0; j < 9; j++) { fprintf(pol_file, " %.8G;", ((CxDoubleArray *)_polarizabilityCache[m_iShowMolCount * j])->GetAt(i)); } } fprintf(pol_file, "\n"); } fclose(pol_file); } int n = ((CxDoubleArray *)_polarizabilityCache[0])->GetSize() - 2; double step = (double)m_iShowMolCount / 20.0; if (n < _correlationDepth) { eprintf("\nError: Autocorrelation depth is %d, but only %d timesteps evaluated.\n",_correlationDepth,n); eprintf(" Reduce depth or increase trajectory length.\n\n"); abort(); } mprintf(" Deriving polarizabilities...\n"); mprintf(WHITE, " ["); for(i = 0; i < m_iShowMolCount; i++) { if(fmod(i, step) < 1.0) mprintf(WHITE, "#"); if (g_ramanCompat) { for(j = 0; j < 3; j++) { for(k = 0; k < (g_orientAvg ? 3 : 1); k++) { for(l = 0; l < n; l++) { ((CxDoubleArray *)_polarizabilityCache[3*m_iShowMolCount * k + m_iShowMolCount * j + i])->GetAt(l) = 0.5 * (((CxDoubleArray *)_polarizabilityCache[3*m_iShowMolCount * k + m_iShowMolCount * j + i])->GetAt(l+2) - ((CxDoubleArray *)_polarizabilityCache[3*m_iShowMolCount * k + m_iShowMolCount * j + i])->GetAt(l)) / g_fTimestepLength / g_stride; } } } } else { for (j = 0; j < 9; j++) { for (k = 0; k < n; k++) { ((CxDoubleArray *)_polarizabilityCache[m_iShowMolCount * j + i])->GetAt(k) = 0.5 * (((CxDoubleArray *)_polarizabilityCache[m_iShowMolCount * j + i])->GetAt(k + 2) - ((CxDoubleArray *)_polarizabilityCache[m_iShowMolCount * j + i])->GetAt(k)) / g_fTimestepLength; } } } } mprintf(WHITE, "]\n"); mprintf(" Processing polarizability tensor components...\n"); CxDoubleArray *acf; try { acf = new CxDoubleArray(); } catch(...) { acf = NULL; } if(acf == NULL) NewException((double)sizeof(CxDoubleArray), __FILE__, __LINE__, __PRETTY_FUNCTION__); acf->SetSize(_correlationDepth); for(i = 0; i < _correlationDepth; i++) { acf->GetAt(i) = 0.0; } CAutoCorrelation *ac; try { ac = new CAutoCorrelation(); } catch(...) { ac = NULL; } if(ac == NULL) NewException((double)sizeof(CAutoCorrelation), __FILE__, __LINE__, __PRETTY_FUNCTION__); ac->Init(n, _correlationDepth, g_bACFFFT); CxDoubleArray *temp; try { temp = new CxDoubleArray(); } catch(...) { temp = NULL; } if(temp == NULL) NewException((double)sizeof(CxDoubleArray), __FILE__, __LINE__, __PRETTY_FUNCTION__); temp->SetSize(_correlationDepth); CxDoubleArray *temp2; try { temp2 = new CxDoubleArray(); } catch(...) { temp2 = NULL; } if(temp2 == NULL) NewException((double)sizeof(CxDoubleArray), __FILE__, __LINE__, __PRETTY_FUNCTION__); temp2->SetSize(n); CxDoubleArray *temp3; try { temp3 = new CxDoubleArray(); } catch(...) { temp3 = NULL; } if(temp3 == NULL) NewException((double)sizeof(CxDoubleArray), __FILE__, __LINE__, __PRETTY_FUNCTION__); temp3->SetSize(_correlationDepth); CFFT *fft; try { fft = new CFFT(); } catch(...) { fft = NULL; } if(fft == NULL) NewException((double)sizeof(CFFT), __FILE__, __LINE__, __PRETTY_FUNCTION__); CxDoubleArray *spectrum1; try { spectrum1 = new CxDoubleArray(); } catch(...) { spectrum1 = NULL; } if(spectrum1 == NULL) NewException((double)sizeof(CxDoubleArray), __FILE__, __LINE__, __PRETTY_FUNCTION__); spectrum1->SetSize(_specSize); CxDoubleArray *spectrum2; try { spectrum2 = new CxDoubleArray(); } catch(...) { spectrum2 = NULL; } if(spectrum2 == NULL) NewException((double)sizeof(CxDoubleArray), __FILE__, __LINE__, __PRETTY_FUNCTION__); spectrum2->SetSize(_specSize); // if(g_orientAvg) { if (m_fieldMode == 1) { mprintf(" Isotropic part...\n"); mprintf(WHITE, " ["); for(i = 0; i < m_iShowMolCount; i++) { if(fmod(i, step) < 1.0) mprintf(WHITE, "#"); for(j = 0; j < n; j++) { temp2->GetAt(j) = 0.0; for(k = 0; k < 3; k++) { temp2->GetAt(j) += ((CxDoubleArray *)_polarizabilityCache[3*m_iShowMolCount * k + m_iShowMolCount * k + i])->GetAt(j); } temp2->GetAt(j) /= 3.0; } ac->AutoCorrelate(temp2, temp); for(j = 0; j < _correlationDepth; j++) { acf->GetAt(j) += temp->GetAt(j); } } mprintf(WHITE, "]\n"); if(m_iShowMol != -1) { for(i = 0; i < _correlationDepth; i++) { acf->GetAt(i) /= (double)m_iShowMolCount; } } if(_saveACF) { if (g_ramanCompat) filename.sprintf("%s/acf_iso_%s.csv", g_ramanDir, _name); else filename.sprintf("raman_acf_iso_%s.csv", _name); mprintf(" Saving autocorrelation function as %s...\n", (const char *)filename); FILE *acf_file = OpenFileWrite(filename, false); for(i = 0; i < _correlationDepth; i++) { fprintf(acf_file, "%.2f; %.10G\n", i * g_fTimestepLength * g_stride, acf->GetAt(i)); } fclose(acf_file); } temp->CopyFrom(acf); if(_windowFunction == 1) { for(i = 0; i < temp->GetSize(); i++) { temp->GetAt(i) *= pow2(cos((double)i / (temp->GetSize() - 1) / 2.0 * Pi)); } } else if(_windowFunction == 2) { for(i = 0; i < temp->GetSize(); i++) { temp->GetAt(i) *= exp(-(double)i / _windowFunctionParameter); } } else if(_windowFunction == 3) { for(i = 0; i < temp->GetSize(); i++) { temp->GetAt(i) *= exp(-(double)i * i / _windowFunctionParameter / _windowFunctionParameter); } } else if(_windowFunction != 0) { eprintf("Unknown window function.\n"); abort(); } if(_saveACF) { if (g_ramanCompat) filename.sprintf("%s/acf_windowed_iso_%s.csv", g_ramanDir, _name); else filename.sprintf("raman_acf_windowed_iso_%s.csv", _name); mprintf(" Saving windowed autocorrelation function as %s...\n", (const char *)filename); FILE *acf_file = OpenFileWrite(filename, false); for(i = 0; i < _correlationDepth; i++) { fprintf(acf_file, "%.2f; %.10G\n", i * g_fTimestepLength * g_stride, acf->GetAt(i)); } fclose(acf_file); } if(_zeroPadding > 0) { for(i = 0; i < _zeroPadding; i++) { temp->Add(0.0); } } int oldSize = temp->GetSize(); temp->SetSize(2 * oldSize); for(i = 1; i < oldSize; i++) { temp->GetAt(oldSize + i) = temp->GetAt(oldSize - i); } temp->GetAt(oldSize) = 0.0; mprintf(" Performing Fourier transformation...\n"); fft->PrepareFFT_C2C(temp->GetSize()); for(i = 0; i < temp->GetSize(); i++) { fft->m_pInput[2*i] = temp->GetAt(i); fft->m_pInput[2*i+1] = 0.0; } fft->DoFFT(); for(i = 0; i < _specSize; i++) { double freq = i * _specResolution; spectrum1->GetAt(i) = 4.160440e-18 * pow4(_laserFreq - freq) / freq / (1 - exp(-1.438777 * freq / _temperature)) * fft->m_pOutput[2*i] * g_fTimestepLength * g_stride; // Output in 1e-30*m^2*cm } spectrum1->GetAt(0) = 0.0; if(_finiteDifferenceCorrection) { double f = _specResolution * g_fTimestepLength * g_stride * 1.883652e-4; for(i = 1; i < _specSize; i++) { spectrum1->GetAt(i) *= pow2(f * i / sin(f * i)); // Divide by sinc function to correct finite difference derivation } } if(_quantumCorrection != 1) { for(i = 0; i < _specSize; i++) { double factor = 1.0; if(_quantumCorrection == 2) { factor = 2.0 / (1.0 + exp(-1.438777 * _specResolution * i / _quantumCorrectionTemperature)) / (1.438777 * _specResolution * i / _quantumCorrectionTemperature) * (1.0 - exp(-1.438777 * _specResolution * i / _quantumCorrectionTemperature)); } else if(_quantumCorrection == 3) { factor = exp(0.719388 * _specResolution * i / _quantumCorrectionTemperature) / (1.438777 * _specResolution * i / _quantumCorrectionTemperature) * (1.0 - exp(-1.438777 * _specResolution * i / _quantumCorrectionTemperature)); } spectrum1->GetAt(i) *= factor; } } mprintf(" First anisotropic part...\n"); for(i = 0; i < _correlationDepth; i++) { temp3->GetAt(i) = 0.0; } mprintf(WHITE, " ["); for(i = 0; i < m_iShowMolCount; i++) { if(fmod(i, step) < 1.0) mprintf(WHITE, "#"); for(j = 0; j < n; j++) { temp2->GetAt(j) = ((CxDoubleArray *)_polarizabilityCache[i])->GetAt(j) - ((CxDoubleArray *)_polarizabilityCache[3*m_iShowMolCount + m_iShowMolCount + i])->GetAt(j); } ac->AutoCorrelate(temp2, temp); for(j = 0; j < _correlationDepth; j++) { temp3->GetAt(j) += temp->GetAt(j); } } mprintf(WHITE, "]\n"); if(m_iShowMol != -1) { for(i = 0; i < _correlationDepth; i++) { temp3->GetAt(i) /= (double)m_iShowMolCount; } } for(i = 0; i < _correlationDepth; i++) { acf->GetAt(i) = 0.5 * temp3->GetAt(i); } mprintf(" Second anisotropic part...\n"); for(i = 0; i < _correlationDepth; i++) { temp3->GetAt(i) = 0.0; } mprintf(WHITE, " ["); for(i = 0; i < m_iShowMolCount; i++) { if(fmod(i, step) < 1.0) mprintf(WHITE, "#"); for(j = 0; j < n; j++) { temp2->GetAt(j) = ((CxDoubleArray *)_polarizabilityCache[3*m_iShowMolCount + m_iShowMolCount + i])->GetAt(j) - ((CxDoubleArray *)_polarizabilityCache[3*m_iShowMolCount * 2 + m_iShowMolCount * 2 + i])->GetAt(j); } ac->AutoCorrelate(temp2, temp); for(j = 0; j < _correlationDepth; j++) { temp3->GetAt(j) += temp->GetAt(j); } } mprintf(WHITE, "]\n"); if(m_iShowMol != -1) { for(i = 0; i < _correlationDepth; i++) { temp3->GetAt(i) /= (double)m_iShowMolCount; } } for(i = 0; i < _correlationDepth; i++) { acf->GetAt(i) += 0.5 * temp3->GetAt(i); } mprintf(" Third anisotropic part...\n"); for(i = 0; i < _correlationDepth; i++) { temp3->GetAt(i) = 0.0; } mprintf(WHITE, " ["); for(i = 0; i < m_iShowMolCount; i++) { if(fmod(i, step) < 1.0) mprintf(WHITE, "#"); for(j = 0; j < n; j++) { temp2->GetAt(j) = ((CxDoubleArray *)_polarizabilityCache[3*m_iShowMolCount * 2 + m_iShowMolCount * 2 + i])->GetAt(j) - ((CxDoubleArray *)_polarizabilityCache[i])->GetAt(j); } ac->AutoCorrelate(temp2, temp); for(j = 0; j < _correlationDepth; j++) { temp3->GetAt(j) += temp->GetAt(j); } } mprintf(WHITE, "]\n"); if(m_iShowMol != -1) { for(i = 0; i < _correlationDepth; i++) { temp3->GetAt(i) /= (double)m_iShowMolCount; } } for(i = 0; i < _correlationDepth; i++) { acf->GetAt(i) += 0.5 * temp3->GetAt(i); } mprintf(" Fourth anisotropic part...\n"); for(i = 0; i < _correlationDepth; i++) { temp3->GetAt(i) = 0.0; } mprintf(WHITE, " ["); for(i = 0; i < m_iShowMolCount; i++) { if(fmod(i, step) < 1.0) mprintf(WHITE, "#"); for(j = 0; j < n; j++) { temp2->GetAt(j) = 0.5 * (((CxDoubleArray *)_polarizabilityCache[m_iShowMolCount + i])->GetAt(j) + ((CxDoubleArray *)_polarizabilityCache[3*m_iShowMolCount + i])->GetAt(j)); } ac->AutoCorrelate(temp2, temp); for(j = 0; j < _correlationDepth; j++) { temp3->GetAt(j) += temp->GetAt(j); } } mprintf(WHITE, "]\n"); if(m_iShowMol != -1) { for(i = 0; i < _correlationDepth; i++) { temp3->GetAt(i) /= (double)m_iShowMolCount; } } for(i = 0; i < _correlationDepth; i++) { acf->GetAt(i) += 3.0 * temp3->GetAt(i); } mprintf(" Fifth anisotropic part...\n"); for(i = 0; i < _correlationDepth; i++) { temp3->GetAt(i) = 0.0; } mprintf(WHITE, " ["); for(i = 0; i < m_iShowMolCount; i++) { if(fmod(i, step) < 1.0) mprintf(WHITE, "#"); for(j = 0; j < n; j++) { temp2->GetAt(j) = 0.5 * (((CxDoubleArray *)_polarizabilityCache[3*m_iShowMolCount + m_iShowMolCount * 2 + i])->GetAt(j) + ((CxDoubleArray *)_polarizabilityCache[3*m_iShowMolCount * 2 + m_iShowMolCount + i])->GetAt(j)); } ac->AutoCorrelate(temp2, temp); for(j = 0; j < _correlationDepth; j++) { temp3->GetAt(j) += temp->GetAt(j); } } mprintf(WHITE, "]\n"); if(m_iShowMol != -1) { for(i = 0; i < _correlationDepth; i++) { temp3->GetAt(i) /= (double)m_iShowMolCount; } } for(i = 0; i < _correlationDepth; i++) { acf->GetAt(i) += 3.0 * temp3->GetAt(i); } mprintf(" Sixth anisotropic part...\n"); for(i = 0; i < _correlationDepth; i++) { temp3->GetAt(i) = 0.0; } mprintf(WHITE, " ["); for(i = 0; i < m_iShowMolCount; i++) { if(fmod(i, step) < 1.0) mprintf(WHITE, "#"); for(j = 0; j < n; j++) { temp2->GetAt(j) = 0.5 * (((CxDoubleArray *)_polarizabilityCache[3*m_iShowMolCount * 2 + i])->GetAt(j) + ((CxDoubleArray *)_polarizabilityCache[m_iShowMolCount * 2 + i])->GetAt(j)); } ac->AutoCorrelate(temp2, temp); for(j = 0; j < _correlationDepth; j++) { temp3->GetAt(j) += temp->GetAt(j); } } mprintf(WHITE, "]\n"); if(m_iShowMol != -1) { for(i = 0; i < _correlationDepth; i++) { temp3->GetAt(i) /= (double)m_iShowMolCount; } } for(i = 0; i < _correlationDepth; i++) { acf->GetAt(i) += 3.0 * temp3->GetAt(i); } if(_saveACF) { if (g_ramanCompat) filename.sprintf("%s/acf_aniso_%s.csv", g_ramanDir, _name); else filename.sprintf("raman_acf_aniso_%s.csv", _name); mprintf(" Saving autocorrelation function as %s...\n", (const char *)filename); FILE *acf_file = OpenFileWrite(filename, false); for(i = 0; i < _correlationDepth; i++) { fprintf(acf_file, "%.2f; %.10G\n", i * g_fTimestepLength * g_stride, acf->GetAt(i)); } fclose(acf_file); } temp->CopyFrom(acf); if(_windowFunction == 1) { for(i = 0; i < temp->GetSize(); i++) { temp->GetAt(i) *= pow2(cos((double)i / (temp->GetSize() - 1) / 2.0 * Pi)); } } else if(_windowFunction == 2) { for(i = 0; i < temp->GetSize(); i++) { temp->GetAt(i) *= exp(-(double)i / _windowFunctionParameter); } } else if(_windowFunction == 3) { for(i = 0; i < temp->GetSize(); i++) { temp->GetAt(i) *= exp(-(double)i * i / _windowFunctionParameter / _windowFunctionParameter); } } else if(_windowFunction != 0) { eprintf("Unknown window function.\n"); abort(); } if(_saveACF) { if (g_ramanCompat) filename.sprintf("%s/acf_windowed_aniso_%s.csv", g_ramanDir, _name); else filename.sprintf("raman_acf_windowed_aniso_%s.csv", _name); mprintf(" Saving windowed autocorrelation function as %s...\n", (const char *)filename); FILE *acf_file = OpenFileWrite(filename, false); for(i = 0; i < _correlationDepth; i++) { fprintf(acf_file, "%.2f; %.10G\n", i * g_fTimestepLength * g_stride, acf->GetAt(i)); } fclose(acf_file); } if(_zeroPadding > 0) { for(i = 0; i < _zeroPadding; i++) { temp->Add(0.0); } } oldSize = temp->GetSize(); temp->SetSize(2 * oldSize); for(i = 1; i < oldSize; i++) { temp->GetAt(oldSize + i) = temp->GetAt(oldSize - i); } temp->GetAt(oldSize) = 0.0; mprintf(" Performing Fourier transformation...\n"); fft->PrepareFFT_C2C(temp->GetSize()); for(i = 0; i < temp->GetSize(); i++) { fft->m_pInput[2*i] = temp->GetAt(i); fft->m_pInput[2*i+1] = 0.0; } fft->DoFFT(); for(i = 0; i < _specSize; i++) { double freq = i * _specResolution; spectrum2->GetAt(i) = 4.160440e-18 * pow4(_laserFreq - freq) / freq / (1 - exp(-1.438777 * freq / _temperature)) * fft->m_pOutput[2*i] * g_fTimestepLength * g_stride; // Output in 1e-30*m^2*cm } spectrum2->GetAt(0) = 0.0; if(_finiteDifferenceCorrection) { double f = _specResolution * g_fTimestepLength * g_stride * 1.883652e-4; for(i = 1; i < _specSize; i++) { spectrum2->GetAt(i) *= pow2(f * i / sin(f * i)); // Divide by sinc function to correct finite difference derivation } } if(_quantumCorrection != 1) { for(i = 0; i < _specSize; i++) { double factor = 1.0; if(_quantumCorrection == 2) { factor = 2.0 / (1.0 + exp(-1.438777 * _specResolution * i / _quantumCorrectionTemperature)) / (1.438777 * _specResolution * i / _quantumCorrectionTemperature) * (1.0 - exp(-1.438777 * _specResolution * i / _quantumCorrectionTemperature)); } else if(_quantumCorrection == 3) { factor = exp(0.719388 * _specResolution * i / _quantumCorrectionTemperature) / (1.438777 * _specResolution * i / _quantumCorrectionTemperature) * (1.0 - exp(-1.438777 * _specResolution * i / _quantumCorrectionTemperature)); } spectrum2->GetAt(i) *= factor; } } if (g_ramanCompat) filename.sprintf("%s/spectrum_para_%s.csv", g_ramanDir, _name); else filename.sprintf("raman_spectrum_para_%s.csv", _name); mprintf(" Saving parallel spectrum as %s...\n", (const char *)filename); FILE *specFile = OpenFileWrite(filename, false); fprintf(specFile, "#Wavenumber (cm^-1); Spectrum (10^-30*K*m^2*cm); Integral (10^-30*K*m^2)\n"); double integral = 0.0; for(i = 0; i < _specSize; i++) { integral += ((double)spectrum1->GetAt(i) + 4.0 / 45.0 * (double)spectrum2->GetAt(i)) * _specResolution; fprintf(specFile, "%.2f; %.8G; %.14G\n", _specResolution * i, spectrum1->GetAt(i) + 4.0 / 45.0 * spectrum2->GetAt(i), integral); } fclose(specFile); if (g_ramanCompat) filename.sprintf("%s/spectrum_ortho_%s.csv", g_ramanDir, _name); else filename.sprintf("raman_spectrum_ortho_%s.csv", _name); mprintf(" Saving orthogonal spectrum as %s...\n", (const char *)filename); specFile = OpenFileWrite(filename, false); fprintf(specFile, "#Wavenumber (cm^-1); Spectrum (10^-30*K*m^2*cm); Integral (10^-30*K*m^2)\n"); integral = 0.0; for(i = 0; i < _specSize; i++) { integral += (double)spectrum2->GetAt(i) / 15.0 * _specResolution; fprintf(specFile, "%.2f; %.8G; %.14G\n", _specResolution * i, spectrum2->GetAt(i) / 15.0, integral); } fclose(specFile); if (g_ramanCompat) filename.sprintf("%s/spectrum_unpol_%s.csv", g_ramanDir, _name); else filename.sprintf("raman_spectrum_unpol_%s.csv", _name); mprintf(" Saving unpolarized spectrum as %s...\n", (const char *)filename); specFile = OpenFileWrite(filename, false); fprintf(specFile, "#Wavenumber (cm^-1); Spectrum (10^-30*K*m^2*cm); Integral (10^-30*K*m^2)\n"); integral = 0.0; for(i = 0; i < _specSize; i++) { integral += ((double)spectrum1->GetAt(i) + 7.0 / 45.0 * (double)spectrum2->GetAt(i)) * _specResolution; fprintf(specFile, "%.2f; %.8G; %.14G\n", _specResolution * i, spectrum1->GetAt(i) + 7.0 / 45.0 * spectrum2->GetAt(i), integral); } fclose(specFile); if (g_ramanCompat) filename.sprintf("%s/depol_ratio_%s.csv", g_ramanDir, _name); else filename.sprintf("raman_depol_ratio_%s.csv", _name); mprintf(" Saving depolarization ratio as %s...\n", (const char *)filename); specFile = OpenFileWrite(filename, false); fprintf(specFile, "#Wavenumber (cm^-1); Depolarization ratio\n"); for(i = 0; i < _specSize; i++) { fprintf(specFile, "%.2f; %.8G\n", _specResolution * i, (spectrum2->GetAt(i) / 15.0) / (spectrum1->GetAt(i) + 4.0 / 45.0 * spectrum2->GetAt(i))); } fclose(specFile); } else { mprintf(" Parallel part...\n"); mprintf(WHITE, " ["); for(i = 0; i < m_iShowMolCount; i++) { if(fmod(i, step) < 1.0) mprintf(WHITE, "#"); if (g_ramanCompat) { ac->AutoCorrelate((CxDoubleArray *)_polarizabilityCache[i], temp); } else { ac->AutoCorrelate((CxDoubleArray *)_polarizabilityCache[3*m_iShowMolCount * (m_fieldMode - 2) + m_iShowMolCount * (m_fieldMode - 2) + i], temp); } for(j = 0; j < _correlationDepth; j++) { acf->GetAt(j) += temp->GetAt(j); } } mprintf(WHITE, "]\n"); if(m_iShowMol != -1) { for(i = 0; i < _correlationDepth; i++) { acf->GetAt(i) /= (double)m_iShowMolCount; } } if(_saveACF) { if (g_ramanCompat) filename.sprintf("%s/acf_para_%s.csv", g_ramanDir, _name); else filename.sprintf("raman_acf_para_%s.csv", _name); mprintf(" Saving autocorrelation function as %s...\n", (const char *)filename); FILE *acf_file = OpenFileWrite(filename, false); for(i = 0; i < _correlationDepth; i++) { fprintf(acf_file, "%.2f; %.10G\n", i * g_fTimestepLength * g_stride, acf->GetAt(i)); } fclose(acf_file); } temp->CopyFrom(acf); if(_windowFunction == 1) { for(i = 0; i < temp->GetSize(); i++) { temp->GetAt(i) *= pow2(cos((double)i / (temp->GetSize() - 1) / 2.0 * Pi)); } } else if(_windowFunction == 2) { for(i = 0; i < temp->GetSize(); i++) { temp->GetAt(i) *= exp(-(double)i / _windowFunctionParameter); } } else if(_windowFunction == 3) { for(i = 0; i < temp->GetSize(); i++) { temp->GetAt(i) *= exp(-(double)i * i / _windowFunctionParameter / _windowFunctionParameter); } } else if(_windowFunction != 0) { eprintf("Unknown window function.\n"); abort(); } if(_saveACF) { if (g_ramanCompat) filename.sprintf("%s/acf_windowed_para_%s.csv", g_ramanDir, _name); else filename.sprintf("raman_acf_windowed_para_%s.csv", _name); mprintf(" Saving windowed autocorrelation function as %s...\n", (const char *)filename); FILE *acf_file = OpenFileWrite(filename, false); for(i = 0; i < _correlationDepth; i++) { fprintf(acf_file, "%.2f; %.10G\n", i * g_fTimestepLength * g_stride, acf->GetAt(i)); } fclose(acf_file); } if(_zeroPadding > 0) { for(i = 0; i < _zeroPadding; i++) { temp->Add(0.0); } } int oldSize = temp->GetSize(); temp->SetSize(2 * oldSize); for(i = 1; i < oldSize; i++) { temp->GetAt(oldSize + i) = temp->GetAt(oldSize - i); } temp->GetAt(oldSize) = 0.0; mprintf(" Performing Fourier transformation...\n"); fft->PrepareFFT_C2C(temp->GetSize()); for(i = 0; i < temp->GetSize(); i++) { fft->m_pInput[2*i] = temp->GetAt(i); fft->m_pInput[2*i+1] = 0.0; } fft->DoFFT(); for(i = 0; i < _specSize; i++) { double freq = i * _specResolution; spectrum1->GetAt(i) = 4.160440e-18 * pow4(_laserFreq - freq) / freq / (1 - exp(-1.438777 * freq / _temperature)) * fft->m_pOutput[2*i] * g_fTimestepLength * g_stride; // Output in 1e-30*m^2*cm } spectrum1->GetAt(0) = 0.0; if(_finiteDifferenceCorrection) { double f = _specResolution * g_fTimestepLength * g_stride * 1.883652e-4; for(i = 1; i < _specSize; i++) { spectrum1->GetAt(i) *= pow2(f * i / sin(f * i)); // Divide by sinc function to correct finite difference derivation } } if(_quantumCorrection != 1) { for(i = 0; i < _specSize; i++) { double factor = 1.0; if(_quantumCorrection == 2) { factor = 2.0 / (1.0 + exp(-1.438777 * _specResolution * i / _quantumCorrectionTemperature)) / (1.438777 * _specResolution * i / _quantumCorrectionTemperature) * (1.0 - exp(-1.438777 * _specResolution * i / _quantumCorrectionTemperature)); } else if(_quantumCorrection == 3) { factor = exp(0.719388 * _specResolution * i / _quantumCorrectionTemperature) / (1.438777 * _specResolution * i / _quantumCorrectionTemperature) * (1.0 - exp(-1.438777 * _specResolution * i / _quantumCorrectionTemperature)); } spectrum1->GetAt(i) *= factor; } } if (g_ramanCompat) filename.sprintf("%s/spectrum_para_%s.csv", g_ramanDir, _name); else filename.sprintf("raman_spectrum_para_%s.csv", _name); mprintf(" Saving parallel spectrum as %s...\n", (const char *)filename); FILE *specFile = OpenFileWrite(filename, false); fprintf(specFile, "#Wavenumber (cm^-1); Spectrum (10^-30*K*m^2*cm); Integral (10^-30*K*m^2)\n"); double integral = 0.0; for(i = 0; i < _specSize; i++) { integral += (double)spectrum1->GetAt(i) * _specResolution; fprintf(specFile, "%.2f; %.8G; %.14G\n", _specResolution * i, spectrum1->GetAt(i), integral); } fclose(specFile); mprintf(" Orthogonal part...\n"); for(i = 0; i < _correlationDepth; i++) { acf->GetAt(i) = 0.0; } mprintf(WHITE, " ["); for(i = 0; i < m_iShowMolCount; i++) { if(fmod(i, step) < 1.0) mprintf(WHITE, "#"); if (g_ramanCompat) { ac->AutoCorrelate((CxDoubleArray *)_polarizabilityCache[m_iShowMolCount + i], temp); } else { ac->AutoCorrelate((CxDoubleArray *)_polarizabilityCache[3*m_iShowMolCount * ((m_fieldMode - 1) % 3) + m_iShowMolCount * (m_fieldMode - 2) + i], temp); } for(j = 0; j < _correlationDepth; j++) { acf->GetAt(j) += temp->GetAt(j); } } mprintf(WHITE, "]\n"); if(m_iShowMol != -1) { for(i = 0; i < _correlationDepth; i++) { acf->GetAt(i) /= (double)m_iShowMolCount; } } if(_saveACF) { if (g_ramanCompat) filename.sprintf("%s/acf_ortho_%s.csv", g_ramanDir, _name); else filename.sprintf("raman_acf_ortho_%s.csv", _name); mprintf(" Saving autocorrelation function as %s...\n", (const char *)filename); FILE *acf_file = OpenFileWrite(filename, false); for(i = 0; i < _correlationDepth; i++) { fprintf(acf_file, "%.2f; %.10G\n", i * g_fTimestepLength * g_stride, acf->GetAt(i)); } fclose(acf_file); } temp->CopyFrom(acf); if(_windowFunction == 1) { for(i = 0; i < temp->GetSize(); i++) { temp->GetAt(i) *= pow2(cos((double)i / (temp->GetSize() - 1) / 2.0 * Pi)); } } else if(_windowFunction == 2) { for(i = 0; i < temp->GetSize(); i++) { temp->GetAt(i) *= exp(-(double)i / _windowFunctionParameter); } } else if(_windowFunction == 3) { for(i = 0; i < temp->GetSize(); i++) { temp->GetAt(i) *= exp(-(double)i * i / _windowFunctionParameter / _windowFunctionParameter); } } else if(_windowFunction != 0) { eprintf("Unknown window function.\n"); abort(); } if(_saveACF) { if (g_ramanCompat) filename.sprintf("%s/acf_windowed_ortho_%s.csv", g_ramanDir, _name); else filename.sprintf("raman_acf_windowed_ortho_%s.csv", _name); mprintf(" Saving windowed autocorrelation function as %s...\n", (const char *)filename); FILE *acf_file = OpenFileWrite(filename, false); for(i = 0; i < _correlationDepth; i++) { fprintf(acf_file, "%.2f; %.10G\n", i * g_fTimestepLength * g_stride, acf->GetAt(i)); } fclose(acf_file); } if(_zeroPadding > 0) { for(i = 0; i < _zeroPadding; i++) { temp->Add(0.0); } } oldSize = temp->GetSize(); temp->SetSize(2 * oldSize); for(i = 1; i < oldSize; i++) { temp->GetAt(oldSize + i) = temp->GetAt(oldSize - i); } temp->GetAt(oldSize) = 0.0; mprintf(" Performing Fourier transformation...\n"); fft->PrepareFFT_C2C(temp->GetSize()); for(i = 0; i < temp->GetSize(); i++) { fft->m_pInput[2*i] = temp->GetAt(i); fft->m_pInput[2*i+1] = 0.0; } fft->DoFFT(); for(i = 0; i < _specSize; i++) { double freq = i * _specResolution; spectrum2->GetAt(i) = 4.160440e-18 * pow4(_laserFreq - freq) / freq / (1 - exp(-1.438777 * freq / _temperature)) * fft->m_pOutput[2*i] * g_fTimestepLength * g_stride; // Output in 1e-30*m^2*cm } spectrum2->GetAt(0) = 0.0; if(_finiteDifferenceCorrection) { double f = _specResolution * g_fTimestepLength * g_stride * 1.883652e-4; for(i = 1; i < _specSize; i++) { spectrum2->GetAt(i) *= pow2(f * i / sin(f * i)); // Divide by sinc function to correct finite difference derivation } } if(_quantumCorrection != 1) { for(i = 0; i < _specSize; i++) { double factor = 1.0; if(_quantumCorrection == 2) { factor = 2.0 / (1.0 + exp(-1.438777 * _specResolution * i / _quantumCorrectionTemperature)) / (1.438777 * _specResolution * i / _quantumCorrectionTemperature) * (1.0 - exp(-1.438777 * _specResolution * i / _quantumCorrectionTemperature)); } else if(_quantumCorrection == 3) { factor = exp(0.719388 * _specResolution * i / _quantumCorrectionTemperature) / (1.438777 * _specResolution * i / _quantumCorrectionTemperature) * (1.0 - exp(-1.438777 * _specResolution * i / _quantumCorrectionTemperature)); } spectrum2->GetAt(i) *= factor; } } if (g_ramanCompat) filename.sprintf("%s/spectrum_ortho_%s.csv", g_ramanDir, _name); else filename.sprintf("raman_spectrum_ortho_%s.csv", _name); mprintf(" Saving orthogonal spectrum as %s...\n", (const char *)filename); specFile = OpenFileWrite(filename, false); fprintf(specFile, "#Wavenumber (cm^-1); Spectrum (10^-30*K*m^2*cm); Integral (10^-30*K*m^2)\n"); integral = 0.0; for(i = 0; i < _specSize; i++) { integral += (double)spectrum2->GetAt(i) * _specResolution; fprintf(specFile, "%.2f; %.8G; %.14G\n", _specResolution * i, spectrum2->GetAt(i), integral); } fclose(specFile); if (g_ramanCompat) filename.sprintf("%s/spectrum_unpol_%s.csv", g_ramanDir, _name); else filename.sprintf("raman_spectrum_unpol_%s.csv", _name); mprintf(" Saving unpolarized spectrum as %s...\n", (const char *)filename); specFile = OpenFileWrite(filename, false); fprintf(specFile, "#Wavenumber (cm^-1); Spectrum (10^-30*K*m^2*cm); Integral (10^-30*K*m^2)\n"); integral = 0.0; for(i = 0; i < _specSize; i++) { integral += ((double)spectrum1->GetAt(i) + (double)spectrum2->GetAt(i)) * _specResolution; fprintf(specFile, "%.2f; %.8G; %.14G\n", _specResolution * i, spectrum1->GetAt(i) + spectrum2->GetAt(i), integral); } fclose(specFile); if (g_ramanCompat) filename.sprintf("%s/depol_ratio_%s.csv", g_ramanDir, _name); else filename.sprintf("raman_depol_ratio_%s.csv", _name); mprintf(" Saving depolarization ratio as %s...\n", (const char *)filename); specFile = OpenFileWrite(filename, false); fprintf(specFile, "#Wavenumber (cm^-1); Depolarization ratio\n"); for(i = 0; i < _specSize; i++) { fprintf(specFile, "%.2f; %.8G\n", _specResolution * i, spectrum2->GetAt(i) / spectrum1->GetAt(i)); } fclose(specFile); } delete ac; delete temp; delete temp2; delete temp3; delete fft; delete spectrum1; delete spectrum2; // _ramanDyn->finalize(); } #ifdef TARGET_LINUX static bool parseSettings(FILE *settingsFile) { char buf[BUF_SIZE]; if(fgets(buf, BUF_SIZE, settingsFile) == NULL) return false; int temp = -1; if(sscanf(buf, "%d", &temp) < 1) return false; if(temp == 0) g_orientAvg = false; else if(temp == 1) g_orientAvg = true; else return false; if(fgets(buf, BUF_SIZE, settingsFile) == NULL) return false; if(sscanf(buf, "%lf", &g_fieldStrength) < 1) return false; if(fgets(buf, BUF_SIZE, settingsFile) == NULL) return false; if(sscanf(buf, "%d", &g_stride) < 1) return false; return true; } #else static bool parseSettings(FILE *settingsFile) { UNUSED(settingsFile); eprintf("parseSettings(): No Windows implementation available.\n"); return false; } #endif bool gatherRaman() { if (g_bAdvanced2) g_ramanCompat = AskYesNo(" Use Raman compatibility mode (y/n)? [no] ", false); else g_ramanCompat = false; if (g_ramanCompat) { mprintf("\n"); mprintf(RED,"Warning: "); mprintf("This is the compatibility mode. It relies on very old and untested\n"); mprintf(" code, and it is highly likely that the spectra will be wrong. Only use\n"); mprintf(" this mode for testing purposes.\n\n"); CxString buf; #ifndef TARGET_LINUX mprintf(RED, "Raman calculations are currently possible only under Linux.\n"); return false; #else mprintf(" To calculate Raman spectra, polarizabilities have to be determined.\n"); mprintf(" TRAVIS creates CP2K input files for numerical polarizabilities\n and will process the resulting data in a second run.\n\n"); g_newRaman = AskYesNo(" Do you wish to create new CP2K input files (y) or process existing results (n)? [y] ", true); // char buf[BUF_SIZE]; if(g_newRaman) { AskString(" Please enter a name for the directory to collect the data: [raman] ", &buf, "raman"); } else { AskString(" Please enter the name of the directory to take the data from: [raman] ", &buf, "raman"); } try { g_ramanDir = new char[strlen(buf)+1]; } catch(...) { g_ramanDir = NULL; } if(g_ramanDir == NULL) NewException((double)(strlen(buf)+1)*sizeof(char), __FILE__, __LINE__, __PRETTY_FUNCTION__); strcpy(g_ramanDir, buf); if(g_newRaman) { g_bKeepOriginalCoords = true; if(FileExist(g_ramanDir)) { mprintf(RED, "A file or a directory \"%s\" already exists. Please remove it first.\n", g_ramanDir); return false; } if(mkdir(g_ramanDir, S_IRWXU) != 0) { mprintf(RED, "Directory \"%s\" could not be created: %s\n", g_ramanDir, strerror(errno)); return false; } char filename[BUF_SIZE]; snprintf(filename, BUF_SIZE, "%s/settings.dat", g_ramanDir); FILE *settingsFile = fopen(filename, "w"); if(settingsFile == NULL) { mprintf(RED, "Could not open settings file \"%s\": %s\n", filename, strerror(errno)); return false; } g_orientAvg = AskYesNo("\n Use orientational averaging? [no] ", false); if(g_orientAvg) fprintf(settingsFile, "%d\n", 1); else fprintf(settingsFile, "%d\n", 0); g_fieldStrength = AskFloat(" Field strength in atomic units [5.0e-4] ", 5.0e-4); fprintf(settingsFile, "%.6E\n", g_fieldStrength); g_stride = AskInteger(" Calculate polarizability for every n-th timestep [1] ", 1); fprintf(settingsFile, "%d\n", g_stride); fclose(settingsFile); snprintf(filename, BUF_SIZE, "%s/1", g_ramanDir); if(mkdir(filename, S_IRWXU) != 0) { mprintf(RED, "Directory \"%s\" could not be created: %s\n", filename, strerror(errno)); return false; } if(g_orientAvg) { snprintf(filename, BUF_SIZE, "%s/2", g_ramanDir); if(mkdir(filename, S_IRWXU) != 0) { mprintf(RED, "Directory \"%s\" could not be created: %s\n", filename, strerror(errno)); return false; } snprintf(filename, BUF_SIZE, "%s/3", g_ramanDir); if(mkdir(filename, S_IRWXU) != 0) { mprintf(RED, "Directory \"%s\" could not be created: %s\n", filename, strerror(errno)); return false; } } FILE* templateFile; snprintf(filename, BUF_SIZE, "%s/template.inp", g_ramanDir); templateFile = fopen(filename, "w"); if(templateFile == NULL) { mprintf(RED, "Could not open template file \"%s\": %s\n", filename, strerror(errno)); return false; } fprintf(templateFile, "&GLOBAL\n"); fprintf(templateFile, " PROJECT_NAME polarizability\n"); fprintf(templateFile, " RUN_TYPE MD\n"); fprintf(templateFile, " PRINT_LEVEL LOW\n"); fprintf(templateFile, "&END\n"); fprintf(templateFile, "&FORCE_EVAL\n"); fprintf(templateFile, " &DFT\n"); fprintf(templateFile, " BASIS_SET_FILE_NAME BASIS_MOLOPT\n"); fprintf(templateFile, " POTENTIAL_FILE_NAME POTENTIAL\n"); fprintf(templateFile, " &MGRID\n"); fprintf(templateFile, " NGRIDS 5\n"); fprintf(templateFile, " CUTOFF 280\n"); fprintf(templateFile, " REL_CUTOFF 40\n"); fprintf(templateFile, " &END\n"); fprintf(templateFile, " &SCF\n"); fprintf(templateFile, " SCF_GUESS ATOMIC\n"); fprintf(templateFile, " MAX_SCF 200\n"); fprintf(templateFile, " EPS_SCF 1.0E-5\n"); fprintf(templateFile, " &OT\n"); fprintf(templateFile, " MINIMIZER DIIS\n"); fprintf(templateFile, " PRECONDITIONER FULL_SINGLE_INVERSE\n"); fprintf(templateFile, " &END\n"); fprintf(templateFile, " &END\n"); fprintf(templateFile, " &XC\n"); fprintf(templateFile, " &XC_FUNCTIONAL BLYP\n"); fprintf(templateFile, " &END\n"); fprintf(templateFile, " &XC_GRID\n"); fprintf(templateFile, " XC_SMOOTH_RHO NN10\n"); fprintf(templateFile, " XC_DERIV NN10_SMOOTH\n"); fprintf(templateFile, " &END\n"); fprintf(templateFile, " &VDW_POTENTIAL\n"); fprintf(templateFile, " POTENTIAL_TYPE PAIR_POTENTIAL\n"); fprintf(templateFile, " &PAIR_POTENTIAL\n"); fprintf(templateFile, " TYPE DFTD3\n"); fprintf(templateFile, " REFERENCE_FUNCTIONAL BLYP\n"); fprintf(templateFile, " PARAMETER_FILE_NAME dftd3.dat\n"); fprintf(templateFile, " &END\n"); fprintf(templateFile, " &END\n"); fprintf(templateFile, " &END\n"); fprintf(templateFile, " &LOCALIZE\n"); fprintf(templateFile, " METHOD CRAZY\n"); fprintf(templateFile, " MAX_ITER 2000\n"); fprintf(templateFile, " &PRINT\n"); fprintf(templateFile, " &WANNIER_CENTERS\n"); fprintf(templateFile, " IONS+CENTERS\n"); fprintf(templateFile, " FILENAME =polarizability_wannier.xyz\n"); fprintf(templateFile, " &END\n"); fprintf(templateFile, " &END\n"); fprintf(templateFile, " &END\n"); fprintf(templateFile, " &PERIODIC_EFIELD\n"); fprintf(templateFile, " INTENSITY ###!field strength will be put here###\n"); fprintf(templateFile, " POLARISATION ###!polarisation vector will be put here###\n"); fprintf(templateFile, " &END\n"); fprintf(templateFile, " &END\n"); fprintf(templateFile, " &SUBSYS\n"); fprintf(templateFile, " &CELL\n"); fprintf(templateFile, " ABC %.6f %.6f %.6f\n", g_fBoxX / 100.0, g_fBoxY / 100.0, g_fBoxZ / 100.0); fprintf(templateFile, " &END\n"); fprintf(templateFile, " &COORD\n"); fprintf(templateFile, "###!coordinates will be put here###\n"); fprintf(templateFile, " &END\n"); fprintf(templateFile, " &KIND H\n"); fprintf(templateFile, " BASIS_SET DZVP-MOLOPT-SR-GTH\n"); fprintf(templateFile, " POTENTIAL GTH-BLYP-q1\n"); fprintf(templateFile, " &END\n"); fprintf(templateFile, " &KIND C\n"); fprintf(templateFile, " BASIS_SET DZVP-MOLOPT-SR-GTH\n"); fprintf(templateFile, " POTENTIAL GTH-BLYP-q4\n"); fprintf(templateFile, " &END\n"); fprintf(templateFile, " &KIND N\n"); fprintf(templateFile, " BASIS_SET DZVP-MOLOPT-SR-GTH\n"); fprintf(templateFile, " POTENTIAL GTH-BLYP-q5\n"); fprintf(templateFile, " &END\n"); fprintf(templateFile, " &KIND O\n"); fprintf(templateFile, " BASIS_SET DZVP-MOLOPT-SR-GTH\n"); fprintf(templateFile, " POTENTIAL GTH-BLYP-q6\n"); fprintf(templateFile, " &END\n"); fprintf(templateFile, " &END\n"); fprintf(templateFile, "&END\n"); fprintf(templateFile, "&MOTION\n"); fprintf(templateFile, " &MD\n"); fprintf(templateFile, " ENSEMBLE REFTRAJ\n"); fprintf(templateFile, " STEPS ###!number of steps will be put here###\n"); fprintf(templateFile, " TIMESTEP %f\n", g_fTimestepLength * g_stride); fprintf(templateFile, " &REFTRAJ\n"); fprintf(templateFile, " EVAL_ENERGY_FORCES\n"); fprintf(templateFile, " TRAJ_FILE_NAME ../polarizability_reftraj.xyz\n"); fprintf(templateFile, " &END\n"); fprintf(templateFile, " &END\n"); fprintf(templateFile, " &PRINT\n"); fprintf(templateFile, " &RESTART\n"); fprintf(templateFile, " &EACH\n"); fprintf(templateFile, " MD 1\n"); fprintf(templateFile, " &END\n"); fprintf(templateFile, " &END\n"); fprintf(templateFile, " &END\n"); fprintf(templateFile, "&END\n"); fclose(templateFile); mprintf("\n An input template for the polarizability calculations has been written to \"%s/template.inp\"\n Please modify it according to your needs.\n Press any key when you are finished.\n", g_ramanDir); getchar(); if(g_orientAvg) { mprintf(" CP2K input files will be created in \"%s/1\", \"%s/2\", and \"%s/3\".\n", g_ramanDir, g_ramanDir, g_ramanDir); mprintf(" After TRAVIS has finished, please run them and make sure that the resulting trajectories \"polarizability_wannier.xyz\"\n are placed in the same directories before you execute TRAVIS for evaluation.\n\n"); } else { mprintf(" A CP2K input file will be created in \"%s/1\".\n", g_ramanDir); mprintf(" After TRAVIS has finished, please run it and make sure that the resulting trajectory \"polarizability_wannier.xyz\"\n is placed in the same directory before you run TRAVIS for evaluation.\n\n"); } } else { if(!FileExist(g_ramanDir)) { mprintf(RED, "The directory \"%s\" was not found.\n", g_ramanDir); return false; } char filename[BUF_SIZE]; snprintf(filename, BUF_SIZE, "%s/settings.dat", g_ramanDir); FILE *settingsFile; settingsFile = fopen(filename, "r"); if(settingsFile == NULL) { mprintf(RED, "Could not open settings file \"%s\": %s\n", filename, strerror(errno)); return false; } if(!parseSettings(settingsFile)) { mprintf(RED, "Could not parse settings file.\n"); return false; } mprintf("\n"); if(g_orientAvg) mprintf(" Using orientational averaging\n"); else mprintf(" Not using orientational averaging\n"); mprintf(" Field strength: %.6e a. u.\n", g_fieldStrength); mprintf(" Using every %d%s timestep\n\n", g_stride, (g_stride == 1) ? "st" : ((g_stride == 2) ? "nd" : ((g_stride == 3) ? "rd" : "th"))); mprintf(" The scattering cross sections are calculated for an\n x polarized incident laser beam along the y axis with detection in z direction.\n"); g_bDipole = true; ParseDipole(); while(true) { mprintf(YELLOW, "\n>>> Raman Observation %d >>>\n\n", g_ramObserv.GetSize() + 1); CRamanObservation *obs; try { obs = new CRamanObservation(); } catch(...) { obs = NULL; } if(obs == NULL) NewException((double)sizeof(CRamanObservation), __FILE__, __LINE__, __PRETTY_FUNCTION__); g_ramObserv.Add(obs); mprintf(YELLOW, "<<< End of Raman Observation %d <<<\n\n", g_ramObserv.GetSize()); if(!AskYesNo(" Add another observation (y/n)? [no] ", false)) break; mprintf("\n"); } if(AskYesNo(" Compute Raman spectrum of whole system (y/n)? [no] ", false)) { mprintf(YELLOW, "\n>>> Global Raman Observation >>>\n\n"); CRamanObservation *obs; try { obs = new CRamanObservation(true); } catch(...) { obs = NULL; } if(obs == NULL) NewException((double)sizeof(CRamanObservation), __FILE__, __LINE__, __PRETTY_FUNCTION__); g_ramObserv.Add(obs); mprintf(YELLOW, "<<< End of Global Raman Observation <<<\n\n"); } } #endif } else { g_stride = 1; parsePolarizability(); while (true) { mprintf(YELLOW, "\n>>> Raman Observation %d >>>\n\n", g_ramObserv.GetSize() + 1); CRamanObservation *obs; try { obs = new CRamanObservation(); } catch(...) { obs = NULL; } if (obs == NULL) NewException((double)sizeof(CRamanObservation), __FILE__, __LINE__, __PRETTY_FUNCTION__); g_ramObserv.Add(obs); mprintf(YELLOW, "<<< End of Raman Observation %d <<<\n\n", g_ramObserv.GetSize()); if (!AskYesNo(" Add another observation (y/n)? [no] ", false)) break; mprintf("\n"); } if (AskYesNo(" Compute Raman spectrum of whole system (y/n)? [no] ", false)) { mprintf(YELLOW, "\n>>> Global Raman Observation >>>\n\n"); CRamanObservation *obs; try { obs = new CRamanObservation(true); } catch(...) { obs = NULL; } if (obs == NULL) NewException((double)sizeof(CRamanObservation), __FILE__, __LINE__, __PRETTY_FUNCTION__); g_ramObserv.Add(obs); mprintf(YELLOW, "<<< End of Global Raman Observation <<<\n\n"); } } return true; } bool initializeRaman() { int i; if (g_ramanCompat) { if(g_newRaman) { char filename[BUF_SIZE]; #ifdef TARGET_LINUX snprintf(filename, BUF_SIZE, "%s/template.inp", g_ramanDir); #else sprintf(filename, "%s/template.inp", g_ramanDir); #endif FILE *templateFile; templateFile = fopen(filename, "r"); if(templateFile == NULL) { mprintf(RED, "Could not open template file \"%s\": %s\n", filename, strerror(errno)); return false; } fseek(templateFile, 0L, SEEK_END); long length = ftell(templateFile); if(length < 0) { mprintf(RED, "Could not determine size of template file: %s\n", strerror(errno)); fclose(templateFile); return false; } try { g_inputTemplate = new char[length + 1]; } catch(...) { g_inputTemplate = NULL; } if(g_inputTemplate == NULL) NewException((double)(length + 1)*sizeof(char), __FILE__, __LINE__, __PRETTY_FUNCTION__); rewind(templateFile); if((long)fread(g_inputTemplate, sizeof(char), length, templateFile) < length) { mprintf(RED, "Could not read template file: %s\n", strerror(errno)); fclose(templateFile); return false; } g_inputTemplate[length] = '\0'; fclose(templateFile); g_templateFieldPos = strstr(g_inputTemplate, "###!field strength will be put here###"); if(g_templateFieldPos == NULL) { mprintf(RED, "Position mark for field strength missing in template.\n"); //fclose(templateFile); return false; } g_templatePolPos = strstr(g_inputTemplate, "###!polarisation vector will be put here###"); if(g_templatePolPos == NULL) { mprintf(RED, "Position mark for polarisation vector missing in template.\n"); //fclose(templateFile); return false; } g_templateCoordPos = strstr(g_inputTemplate, "###!coordinates will be put here###"); if(g_templateCoordPos == NULL) { mprintf(RED, "Position mark for coordinates missing in template.\n"); //fclose(templateFile); return false; } g_templateStepsPos = strstr(g_inputTemplate, "###!number of steps will be put here###"); if(g_templateStepsPos == NULL) { mprintf(RED, "Position mark for number of steps missing in template.\n"); //fclose(templateFile); return false; } g_templateFieldPos[0] = '\0'; g_templatePolPos[0] = '\0'; g_templateCoordPos[0] = '\0'; g_templateStepsPos[0] = '\0'; #ifdef TARGET_LINUX snprintf(filename, BUF_SIZE, "%s/polarizability_reftraj.xyz", g_ramanDir); #else sprintf(filename, "%s/polarizability_reftraj.xyz", g_ramanDir); #endif g_reftrajFile = fopen(filename, "w"); if(g_reftrajFile == NULL) { mprintf(RED, "Could not open reference trajectory \"%s\": %s\n", filename, strerror(errno)); //fclose(templateFile); return false; } } else { for(i = 0; i < g_ramObserv.GetSize(); i++) { mprintf("Initializing Raman Observation %d...\n", i+1); CRamanObservation *obs = (CRamanObservation *)g_ramObserv[i]; obs->initialize(); } char filename[BUF_SIZE]; for(i = 0; i < (g_orientAvg ? 3 : 1); i++) { if ((g_iTrajFormat == 5) || (g_iTrajFormat == 7)) { #ifdef TARGET_LINUX snprintf(filename, BUF_SIZE, "%s/%d/polarizability_density.cube", g_ramanDir, i + 1); #else sprintf(filename, "%s/%d/polarizability_density.cube", g_ramanDir, i + 1); #endif } else { #ifdef TARGET_LINUX snprintf(filename, BUF_SIZE, "%s/%d/polarizability_wannier.xyz", g_ramanDir, i + 1); #else sprintf(filename, "%s/%d/polarizability_wannier.xyz", g_ramanDir, i + 1); #endif } g_polFile[i] = fopen(filename, "r"); if(g_polFile[i] == NULL) { mprintf(RED, "Could not open trajectory \"%s\": %s\n", filename, strerror(errno)); return false; } } for(i = 0; i < (g_orientAvg ? 3 : 1); i++) { try { g_timestep[i] = new CTimeStep(); } catch(...) { g_timestep[i] = NULL; } if(g_timestep[i] == NULL) NewException((double)sizeof(CTimeStep), __FILE__, __LINE__, __PRETTY_FUNCTION__); } } } else { for (i = 0; i < g_ramObserv.GetSize(); i++) { mprintf("Initializing Raman Observation %d...\n", i + 1); CRamanObservation *obs = (CRamanObservation *)g_ramObserv[i]; obs->initialize(); } } return true; } void processRaman(CTimeStep *ts) { int i, j; if (g_ramanCompat) { g_step++; if(g_newRaman) { if(g_step % g_stride == 0) { g_steps++; int numAtoms = 0; for(i = 0; i < g_iGesAtomCount; i++) if(g_waAtomMolIndex[i] != 60000) numAtoms++; fprintf(g_reftrajFile, "%d\nStep %d\n", numAtoms, g_step); for(i = 0; i < g_iGesAtomCount; i++) { if(g_waAtomMolIndex[i] == 60000) continue; fprintf(g_reftrajFile, "%4s %14.10f %14.10f %14.10f\n", (const char*)((CAtom *)g_oaAtoms[g_waAtomRealElement[i]])->m_sName, ts->m_vaCoords_Original[i][0] / 100.0, ts->m_vaCoords_Original[i][1] / 100.0, ts->m_vaCoords_Original[i][2] / 100.0); } } } else { if(g_step % g_stride == 0) { for(i = 0; i < g_ramObserv.GetSize(); i++) ((CRamanObservation *)g_ramObserv[i])->getDipoleZero(); for(i = 0; i < (g_orientAvg ? 3 : 1); i++) { if(!g_timestep[i]->ReadTimestep(g_polFile[i], false)) { eprintf("processRaman(): Error while reading trajectory for polarizabilities.\n"); abort(); } if(!g_bSaveCoordsUnchanged) { g_timestep[i]->UniteMolecules(false); if(g_bRemoveCOM) g_timestep[i]->CenterCOM(); } g_timestep[i]->CalcCenters(); if(g_bWannier) g_timestep[i]->ScanWannier(false); g_timestep[i]->CalcDipoles(false); for(j = 0; j < g_ramObserv.GetSize(); j++) { ((CRamanObservation *)g_ramObserv[j])->calcPolarizability(i); } } } } } else { ts->CalcPolarizabilities(); for (i = 0; i < g_ramObserv.GetSize(); i++) { ((CRamanObservation *)g_ramObserv[i])->process(); } } } void finalizeRaman() { if (g_ramanCompat) { int i, j, k, l; if(g_newRaman) { fclose(g_reftrajFile); char filename[BUF_SIZE]; FILE *inputFile; for(i = 1; i < (g_orientAvg ? 4 : 2); i++) { #ifdef TARGET_LINUX snprintf(filename, BUF_SIZE, "%s/%d/polarizability.inp", g_ramanDir, i); #else sprintf(filename, "%s/%d/polarizability.inp", g_ramanDir, i); #endif inputFile = fopen(filename, "w"); if(inputFile == NULL) { eprintf("finalizeRaman(): Could not open input file \"%s\": %s\n", filename, strerror(errno)); abort(); } fprintf(inputFile, "%s", g_inputTemplate); for(j = 0; j < 4; j++) { char *tempPos = g_inputTemplate; for(k = 0; k <= j; k++) tempPos = strchr(&tempPos[1], '\0'); if(tempPos == g_templateFieldPos) { fprintf(inputFile, "%.6E", g_fieldStrength); fprintf(inputFile, "%s", &g_templateFieldPos[38]); } else if(tempPos == g_templatePolPos) { if(i == 1) fprintf(inputFile, "1.0 0.0 0.0"); if(i == 2) fprintf(inputFile, "0.0 1.0 0.0"); if(i == 3) fprintf(inputFile, "0.0 0.0 1.0"); fprintf(inputFile, "%s", &g_templatePolPos[43]); } else if(tempPos == g_templateCoordPos) { CTimeStep *ts = GetTimeStep(0); for(l = 0; l < g_iGesAtomCount; l++) { if(g_waAtomMolIndex[l] == 60000) continue; fprintf(inputFile, " %s %14.10f %14.10f %14.10f\n", (const char*)((CAtom *)g_oaAtoms[g_waAtomRealElement[l]])->m_sName, ts->m_vaCoords_Original[l][0] / 100.0, ts->m_vaCoords_Original[l][1] / 100.0, ts->m_vaCoords_Original[l][2] / 100.0); } fprintf(inputFile, "%s", &g_templateCoordPos[36]); } else if(tempPos == g_templateStepsPos) { fprintf(inputFile, "%d", g_steps); fprintf(inputFile, "%s", &g_templateStepsPos[39]); } else { mprintf(RED, "Unexpected error while processing the input template.\n"); } } fclose(inputFile); } delete[] g_inputTemplate; } else { for(i = 0; i < g_ramObserv.GetSize(); i++) { mprintf(YELLOW, ">>> Raman Observation %d >>>\n\n", i + 1); ((CRamanObservation *)g_ramObserv[i])->finalize(); mprintf(YELLOW, "\n<<< End of Raman Observation %d <<<\n\n", i + 1); } for(i = 0; i < (g_orientAvg ? 3 : 1); i++) fclose(g_polFile[i]); for(i = 0; i < (g_orientAvg ? 3 : 1); i++) delete g_timestep[i]; } delete[] g_ramanDir; } else { int i; for (i = 0; i < g_ramObserv.GetSize(); i++) { mprintf(YELLOW, ">>> Raman Observation %d >>>\n\n", i + 1); ((CRamanObservation *)g_ramObserv[i])->finalize(); mprintf(YELLOW, "\n<<< End of Raman Observation %d <<<\n\n", i + 1); } } } void parsePolarizability() { if (g_bPolarizabilityDefined) return; g_bDipole = true; ParseDipole(); mprintf(WHITE, "\n>>> Polarizability Definition >>>\n\n"); mprintf(" There are the following possibilities to provide polarizabilities:\n"); mprintf(" (1) Read polarizabilities from an external file\n"); mprintf(" Calculate polarizabilities by finite differences of dipole moments and\n"); mprintf(" (2) get dipole moments from Wannier centers\n"); mprintf(" (3) use Voronoi dipole moments\n"); mprintf(" (4) load dipole restart files\n"); mprintf("\n"); while (true) { g_iPolarizabilityMode = AskRangeInteger(" Which polarizability mode to set? [2] ", 1, 4, 2); if (g_iPolarizabilityMode == 1) { eprintf("This is not implemented yet.\n"); continue; } else if (g_iPolarizabilityMode == 2) { setupWannier(); break; } else if (g_iPolarizabilityMode == 3) { if (g_bTegri) { if (g_pTetraPak == NULL) { try { g_pVoroWrapper = new CVoroWrapper(); } catch(...) { g_pVoroWrapper = NULL; } if (g_pVoroWrapper == NULL) NewException((double)sizeof(CVoroWrapper),__FILE__,__LINE__,__PRETTY_FUNCTION__); try { g_pTetraPak = new CTetraPak(); } catch(...) { g_pTetraPak = NULL; } if (g_pTetraPak == NULL) NewException((double)sizeof(CTetraPak),__FILE__,__LINE__,__PRETTY_FUNCTION__); g_pTetraPak->Parse(); } } else { eprintf(" Voronoi integration needs to be active. Use \"vori\" in the main menu.\n"); continue; } break; } else if (g_iPolarizabilityMode == 4) { break; } else { eprintf("This is impossible.\n"); continue; } } mprintf("\n"); if (g_iPolarizabilityMode == 1) { eprintf("This is not implemented yet.\n"); abort(); } else { if (g_iPolarizabilityMode == 2) { mprintf("\n"); mprintf(" This implementation requires a sub-directory (per default \"polarizability\")\n"); mprintf(" with some of the following files inside of it:\n"); mprintf("\n"); mprintf(" (1) polarizability_xp-wannier.xyz\n"); mprintf(" (2) polarizability_xn-wannier.xyz\n"); mprintf(" (3) polarizability_yp-wannier.xyz\n"); mprintf(" (4) polarizability_yn-wannier.xyz\n"); mprintf(" (5) polarizability_zp-wannier.xyz\n"); mprintf(" (6) polarizability_zn-wannier.xyz\n"); mprintf("\n"); mprintf(" Each file needs to be a trajectory with Wannier centers under the influence of an\n"); mprintf(" external electrical field in the specified direction (X/Y/Z, p=\"positive\", n=\"negative\").\n"); mprintf(" The file names are hard-coded and need to match exactly.\n"); mprintf(" To use forward differences, leave out the \"negative\" files (2,4,6).\n"); mprintf(" To use isotropic averaging, leave out the Y and Z field directions (3-6).\n\n"); } else if (g_iPolarizabilityMode == 3) { mprintf("\n"); mprintf(" This implementation requires a sub-directory (per default \"polarizability\")\n"); mprintf(" with some of the following files inside of it:\n"); mprintf("\n"); mprintf(" (1) polarizability_xp-density.cube\n"); mprintf(" (2) polarizability_xn-density.cube\n"); mprintf(" (3) polarizability_yp-density.cube\n"); mprintf(" (4) polarizability_yn-density.cube\n"); mprintf(" (5) polarizability_zp-density.cube\n"); mprintf(" (6) polarizability_zn-density.cube\n"); mprintf("\n"); mprintf(" Each file needs to be a volumetric electron density trajectory under the influence of an\n"); mprintf(" external electrical field in the specified direction (X/Y/Z, p=\"positive\", n=\"negative\").\n"); mprintf(" The file names are hard-coded and need to match exactly.\n"); mprintf(" To use forward differences, leave out the \"negative\" files (2,4,6).\n"); mprintf(" To use isotropic averaging, leave out the Y and Z field directions (3-6).\n\n"); } CxString dirname; while (true) { AskString(" Enter the name of the polarizability directory: [polarizability] ", &dirname, "polarizability"); if (!FileExist((const char *)dirname)) { eprintf("Could not find directory \"%s\".\n", (const char *)dirname); continue; } break; } mprintf("\n"); CxString nameString; if (g_iPolarizabilityMode == 2) nameString = CxString("polarizability_%c%c-wannier.xyz"); else if (g_iPolarizabilityMode == 3) nameString = CxString("polarizability_%c%c-density.cube"); else if (g_iPolarizabilityMode == 4) nameString = CxString("polarizability_%c%c-dipole.restart"); CxString filename, path; filename.sprintf((const char *)nameString, 'x', 'p'); path.sprintf("%s/%s", (const char *)dirname, (const char *)filename); g_iPolarizabilityConf[0] = 0; if (FileExist((const char *)path)) { g_fPolarizabilityFile[0] = fopen((const char *)path, "r"); if (g_fPolarizabilityFile[0] != NULL) { g_iPolarizabilityConf[0] = 1; filename.sprintf((const char *)nameString, 'x', 'n'); path.sprintf("%s/%s", (const char *)dirname, (const char *)filename); if (FileExist((const char *)path)) { g_fPolarizabilityFile[1] = fopen((const char *)path, "r"); if (g_fPolarizabilityFile[1] != NULL) { g_iPolarizabilityConf[0] = 2; } } } } filename.sprintf((const char *)nameString, 'y', 'p'); path.sprintf("%s/%s", (const char *)dirname, (const char *)filename); g_iPolarizabilityConf[1] = 0; if (FileExist((const char *)path)) { g_fPolarizabilityFile[2] = fopen((const char *)path, "r"); if (g_fPolarizabilityFile[2] != NULL) { g_iPolarizabilityConf[1] = 1; filename.sprintf((const char *)nameString, 'y', 'n'); path.sprintf("%s/%s", (const char *)dirname, (const char *)filename); if (FileExist((const char *)path)) { g_fPolarizabilityFile[3] = fopen((const char *)path, "r"); if (g_fPolarizabilityFile[3] != NULL) { g_iPolarizabilityConf[1] = 2; } } } } filename.sprintf((const char *)nameString, 'z', 'p'); path.sprintf("%s/%s", (const char *)dirname, (const char *)filename); g_iPolarizabilityConf[2] = 0; if (FileExist((const char *)path)) { g_fPolarizabilityFile[4] = fopen((const char *)path, "r"); if (g_fPolarizabilityFile[4] != NULL) { g_iPolarizabilityConf[2] = 1; filename.sprintf((const char *)nameString, 'z', 'n'); path.sprintf("%s/%s", (const char *)dirname, (const char *)filename); if (FileExist((const char *)path)) { g_fPolarizabilityFile[5] = fopen((const char *)path, "r"); if (g_fPolarizabilityFile[5] != NULL) { g_iPolarizabilityConf[2] = 2; } } } } while (true) { mprintf(" The following configuration is set up:\n\n"); char fieldChar[4] = "xyz"; int i; for (i = 0; i < 3; i++) { mprintf(" Electric field along %c axis: ", fieldChar[i]); if (g_iPolarizabilityConf[i] == 0) mprintf("disabled\n"); else if (g_iPolarizabilityConf[i] == 1) mprintf("forward difference\n"); else if (g_iPolarizabilityConf[i] == 2) mprintf("central difference\n"); else mprintf("UNKNOWN\n"); } mprintf("\n"); if (!AskYesNo(" Change this configuration (y/n)? [no] ", false)) break; for (i = 0; i < 3; i++) { g_iPolarizabilityConf[i] = AskRangeInteger(" Electric field along %c axis: (1) disable, (2) use forward difference, (3) use central difference? [1] ", 1, 3, 1, fieldChar[i]) - 1; if (g_iPolarizabilityConf[i] > 0) { while (true) { //CxString filename; FILE *file; if (g_iPolarizabilityMode == 2) { AskString_ND(" Enter file of Wannier centers with field along positive %c axis: ", &filename, fieldChar[i]); } else if (g_iPolarizabilityMode == 3) { AskString_ND(" Enter file of electron density with field along positive %c axis: ", &filename, fieldChar[i]); } else if (g_iPolarizabilityMode == 4) { AskString_ND(" Enter dipole restart file with field along positive %c axis: ", &filename, fieldChar[i]); } file = fopen((const char *)filename, "r"); if (file != NULL) { if (g_fPolarizabilityFile[2 * i] != NULL) fclose(g_fPolarizabilityFile[2 * i]); g_fPolarizabilityFile[2 * i] = file; break; } eprintf("Could not open \"%s\": %s.\n", (const char *)filename, strerror(errno)); } if (g_iPolarizabilityConf[i] > 1) { while (true) { //CxString filename; FILE *file; if (g_iPolarizabilityMode == 2) { AskString_ND(" Enter file of Wannier centers with field along negative %c axis: ", &filename, fieldChar[i]); } else if (g_iPolarizabilityMode == 3) { AskString_ND(" Enter file of electron density with field along negative %c axis: ", &filename, fieldChar[i]); } else if (g_iPolarizabilityMode == 4) { AskString_ND(" Enter dipole restart file with field along negative %c axis: ", &filename, fieldChar[i]); } file = fopen((const char *)filename, "r"); if (file != NULL) { if (g_fPolarizabilityFile[2 * i + 1] != NULL) fclose(g_fPolarizabilityFile[2 * i + 1]); g_fPolarizabilityFile[2 * i + 1] = file; break; } eprintf("Could not open \"%s\": %s.\n", (const char *)filename, strerror(errno)); } } } } } mprintf("\n"); if (g_iPolarizabilityMode == 4) { int i; for (i = 0; i < 3; i++) { if (g_iPolarizabilityConf[i] > 0) { int numAtoms; (void)fread(&numAtoms, sizeof(int), 1, g_fPolarizabilityFile[2 * i]); char fieldChar[4] = "xyz"; if (numAtoms != g_oaSingleMolecules.GetSize()) { eprintf("The dipole restart file with field along positive %c axis was written for a different number of molecules.\n", fieldChar[i]); abort(); } if (g_iPolarizabilityConf[i] > 1) { //int numAtoms; (void)fread(&numAtoms, sizeof(int), 1, g_fPolarizabilityFile[2 * i + 1]); //char fieldChar[4] = "xyz"; if (numAtoms != g_oaSingleMolecules.GetSize()) { eprintf("The dipole restart file with field along negative %c axis was written for a different number of molecules.\n", fieldChar[i]); abort(); } } } } } g_fPolarizabilityFieldStrength = 5.0E-3; filename.sprintf("%s/settings.dat", (const char *)dirname); FILE *settingsFile = fopen((const char *)filename, "r"); if (settingsFile != NULL) { CxString line; (void)line.fgets(1024, settingsFile); if (sscanf((const char *)line, "%lf", &g_fPolarizabilityFieldStrength) < 1) g_fPolarizabilityFieldStrength = 1.0; else mprintf(" Found electric field strentgh in \"%s/settings.dat\": %g a. u.\n", (const char *)dirname, g_fPolarizabilityFieldStrength); fclose(settingsFile); } g_fPolarizabilityFieldStrength = AskFloat(" Electric field strength in atomic units: [%g] ", g_fPolarizabilityFieldStrength, g_fPolarizabilityFieldStrength); } g_bPolarizabilityDefined = true; mprintf(WHITE, "\n<<< End of Polarizability Definition <<<\n\n"); } static CxString g_polarizabilityDir; static double g_polFieldStrength; static char *g_polInputTemplate = NULL; static const char *g_polInputTemplateEnd = NULL; static char *g_polTemplatePosIdent[2] = { NULL, NULL }; static char *g_polTemplatePosField = NULL; static char *g_polTemplatePosPol = NULL; static char *g_polTemplatePosCoord = NULL; static char *g_polTemplatePosSteps = NULL; static FILE *g_polReftrajFile = NULL; static int g_polSteps = 0; bool gatherPolarizabilityCalc() { #ifdef TARGET_LINUX g_bKeepOriginalCoords = true; AskString(" Enter a name for the directory to collect the data: [polarizability] ", &g_polarizabilityDir, "polarizability"); if (FileExist((const char *)g_polarizabilityDir)) { eprintf("A file or a directory \"%s\" already exists. Please remove it first.\n", (const char *)g_polarizabilityDir); return false; } if (mkdir((const char *)g_polarizabilityDir, S_IRWXU) != 0) { eprintf("Directory \"%s\" could not be created: %s\n", (const char *)g_polarizabilityDir, strerror(errno)); return false; } mprintf("\n"); mprintf(" A set of six CP2K input files will be created in the directory \"%s\".\n", (const char *)g_polarizabilityDir); mprintf(" These contain the three independent field directions (x, y, z) with positive and negative sign (p, n).\n"); mprintf(" To get the full polarizability tensor with forward differences, you need to calculate xp, yp, and zp.\n"); mprintf(" To use (more accurate) central differences, you also need to calculate xn, yn, and zn.\n"); mprintf(" For isotropic systems, it is usually sufficient to consider only one field direction.\n"); mprintf(" In this case, you only need xp for forward differences, and also xn for central differences.\n"); mprintf("\n"); CxString filename; filename.sprintf("%s/settings.dat", (const char *)g_polarizabilityDir); FILE *settingsFile = fopen((const char *)filename, "w"); if (settingsFile == NULL) { eprintf("Could not open settings file \"%s\": %s\n", (const char *)filename, strerror(errno)); return false; } g_polFieldStrength = AskFloat(" Electric field strength in atomic units: [5e-4] ", 5.0e-4); fprintf(settingsFile, "%.6E\n", g_polFieldStrength); fclose(settingsFile); int mode = AskRangeInteger_ND(" Prepare input for Wannier centers (1), cube trajectory (2), or cube streaming (3)? ", 1, 3); filename.sprintf("%s/template.inp", (const char *)g_polarizabilityDir); FILE *templateFile = fopen((const char *)filename, "w"); if(templateFile == NULL) { mprintf(RED, "Could not open template file \"%s\": %s\n", (const char *)filename, strerror(errno)); return false; } fprintf(templateFile, "&GLOBAL\n"); fprintf(templateFile, " PROJECT_NAME polarizability_###!identifier will be put here###\n"); fprintf(templateFile, " RUN_TYPE MD\n"); fprintf(templateFile, " PRINT_LEVEL LOW\n"); fprintf(templateFile, " FFTW_PLAN_TYPE PATIENT\n"); fprintf(templateFile, "&END\n"); fprintf(templateFile, "&FORCE_EVAL\n"); fprintf(templateFile, " &DFT\n"); fprintf(templateFile, " BASIS_SET_FILE_NAME BASIS_MOLOPT\n"); fprintf(templateFile, " POTENTIAL_FILE_NAME POTENTIAL\n"); fprintf(templateFile, " &MGRID\n"); fprintf(templateFile, " NGRIDS 5\n"); fprintf(templateFile, " CUTOFF 280\n"); fprintf(templateFile, " REL_CUTOFF 40\n"); fprintf(templateFile, " &END\n"); fprintf(templateFile, " &SCF\n"); fprintf(templateFile, " SCF_GUESS ATOMIC\n"); fprintf(templateFile, " MAX_SCF 200\n"); fprintf(templateFile, " EPS_SCF 1.0E-5\n"); fprintf(templateFile, " &OT\n"); fprintf(templateFile, " MINIMIZER DIIS\n"); fprintf(templateFile, " PRECONDITIONER FULL_SINGLE_INVERSE\n"); fprintf(templateFile, " &END\n"); fprintf(templateFile, " &END\n"); fprintf(templateFile, " &XC\n"); fprintf(templateFile, " &XC_FUNCTIONAL BLYP\n"); fprintf(templateFile, " &END\n"); fprintf(templateFile, " &XC_GRID\n"); fprintf(templateFile, " XC_SMOOTH_RHO NN10\n"); fprintf(templateFile, " XC_DERIV NN10_SMOOTH\n"); fprintf(templateFile, " &END\n"); fprintf(templateFile, " &VDW_POTENTIAL\n"); fprintf(templateFile, " POTENTIAL_TYPE PAIR_POTENTIAL\n"); fprintf(templateFile, " &PAIR_POTENTIAL\n"); fprintf(templateFile, " TYPE DFTD3\n"); fprintf(templateFile, " REFERENCE_FUNCTIONAL BLYP\n"); fprintf(templateFile, " PARAMETER_FILE_NAME dftd3.dat\n"); fprintf(templateFile, " &END\n"); fprintf(templateFile, " &END\n"); fprintf(templateFile, " &END\n"); fprintf(templateFile, " &PERIODIC_EFIELD\n"); fprintf(templateFile, " INTENSITY ###!field strength will be put here###\n"); fprintf(templateFile, " POLARISATION ###!polarisation vector will be put here###\n"); fprintf(templateFile, " &END\n"); if (mode == 1) { fprintf(templateFile, " &LOCALIZE\n"); fprintf(templateFile, " METHOD CRAZY\n"); fprintf(templateFile, " MAX_ITER 2000\n"); fprintf(templateFile, " &PRINT\n"); fprintf(templateFile, " &WANNIER_CENTERS\n"); fprintf(templateFile, " IONS+CENTERS\n"); fprintf(templateFile, " FILENAME =polarizability_###!identifier will be put here###-wannier.xyz\n"); fprintf(templateFile, " &END\n"); fprintf(templateFile, " &END\n"); fprintf(templateFile, " &END\n"); } else if (mode == 2) { fprintf(templateFile, " &PRINT\n"); fprintf(templateFile, " &E_DENSITY_CUBE\n"); fprintf(templateFile, " FILENAME =polarizability_###!identifier will be put here###-density.cube\n"); fprintf(templateFile, " APPEND\n"); fprintf(templateFile, " STRIDE 2 2 2\n"); fprintf(templateFile, " &END\n"); fprintf(templateFile, " &END\n"); } else if (mode == 3) { fprintf(templateFile, " &PRINT\n"); fprintf(templateFile, " &E_DENSITY_CUBE\n"); fprintf(templateFile, " STRIDE 2 2 2\n"); fprintf(templateFile, " &END\n"); fprintf(templateFile, " &END\n"); } fprintf(templateFile, " &END\n"); fprintf(templateFile, " &SUBSYS\n"); fprintf(templateFile, " &CELL\n"); fprintf(templateFile, " ABC %.6f %.6f %.6f\n", g_fBoxX / 100.0, g_fBoxY / 100.0, g_fBoxZ / 100.0); fprintf(templateFile, " &END\n"); fprintf(templateFile, " &COORD\n"); fprintf(templateFile, "###!coordinates will be put here###\n"); fprintf(templateFile, " &END\n"); int i; for (i = 0; i < g_oaAtoms.GetSize(); i++) { if (mystricmp(((CAtom *)g_oaAtoms[i])->m_sName, "H") == 0) { fprintf(templateFile, " &KIND H\n"); fprintf(templateFile, " BASIS_SET DZVP-MOLOPT-SR-GTH\n"); fprintf(templateFile, " POTENTIAL GTH-BLYP-q1\n"); fprintf(templateFile, " &END\n"); } else if (mystricmp(((CAtom *)g_oaAtoms[i])->m_sName, "C") == 0) { fprintf(templateFile, " &KIND C\n"); fprintf(templateFile, " BASIS_SET DZVP-MOLOPT-SR-GTH\n"); fprintf(templateFile, " POTENTIAL GTH-BLYP-q4\n"); fprintf(templateFile, " &END\n"); } else if (mystricmp(((CAtom *)g_oaAtoms[i])->m_sName, "N") == 0) { fprintf(templateFile, " &KIND N\n"); fprintf(templateFile, " BASIS_SET DZVP-MOLOPT-SR-GTH\n"); fprintf(templateFile, " POTENTIAL GTH-BLYP-q5\n"); fprintf(templateFile, " &END\n"); } else if (mystricmp(((CAtom *)g_oaAtoms[i])->m_sName, "O") == 0) { fprintf(templateFile, " &KIND O\n"); fprintf(templateFile, " BASIS_SET DZVP-MOLOPT-SR-GTH\n"); fprintf(templateFile, " POTENTIAL GTH-BLYP-q6\n"); fprintf(templateFile, " &END\n"); } else if (mystricmp(((CAtom *)g_oaAtoms[i])->m_sName, "F") == 0) { fprintf(templateFile, " &KIND F\n"); fprintf(templateFile, " BASIS_SET DZVP-MOLOPT-SR-GTH\n"); fprintf(templateFile, " POTENTIAL GTH-BLYP-q7\n"); fprintf(templateFile, " &END\n"); } else if (mystricmp(((CAtom *)g_oaAtoms[i])->m_sName, "S") == 0) { fprintf(templateFile, " &KIND S\n"); fprintf(templateFile, " BASIS_SET DZVP-MOLOPT-SR-GTH\n"); fprintf(templateFile, " POTENTIAL GTH-BLYP-q6\n"); fprintf(templateFile, " &END\n"); } else if (mystricmp(((CAtom *)g_oaAtoms[i])->m_sName, "Cl") == 0) { fprintf(templateFile, " &KIND Cl\n"); fprintf(templateFile, " BASIS_SET DZVP-MOLOPT-SR-GTH\n"); fprintf(templateFile, " POTENTIAL GTH-BLYP-q7\n"); fprintf(templateFile, " &END\n"); } } fprintf(templateFile, " &END\n"); fprintf(templateFile, "&END\n"); fprintf(templateFile, "&MOTION\n"); fprintf(templateFile, " &MD\n"); fprintf(templateFile, " ENSEMBLE REFTRAJ\n"); fprintf(templateFile, " STEPS ###!number of steps will be put here###\n"); fprintf(templateFile, " TIMESTEP %f\n", g_fTimestepLength); fprintf(templateFile, " &REFTRAJ\n"); fprintf(templateFile, " EVAL_ENERGY_FORCES\n"); fprintf(templateFile, " TRAJ_FILE_NAME polarizability_reftraj.xyz\n"); fprintf(templateFile, " &END\n"); fprintf(templateFile, " &END\n"); fprintf(templateFile, "&END\n"); fclose(templateFile); mprintf("\n An input template for the polarizability calculations has been written to \"%s/template.inp\"\n Modify it according to your needs and press any key when you are finished.\n", (const char *)g_polarizabilityDir); getchar(); #else eprintf("\nRaman calculations are currently only supported with TARGET_LINUX.\n"); abort(); #endif return true; } bool initializePolarizabilityCalc() { CxString filename; filename.sprintf("%s/template.inp", (const char *)g_polarizabilityDir); FILE *templateFile = fopen(filename, "r"); if (templateFile == NULL) { eprintf("Could not open template file \"%s\": %s\n", (const char *)filename, strerror(errno)); return false; } fseek(templateFile, 0L, SEEK_END); long length = ftell(templateFile); if (length < 0) { eprintf("Could not determine size of template file: %s\n", strerror(errno)); fclose(templateFile); return false; } try { g_polInputTemplate = new char[length + 1]; } catch(...) { g_polInputTemplate = NULL; } if (g_polInputTemplate == NULL) NewException((double)(length + 1) * sizeof(char), __FILE__, __LINE__, __PRETTY_FUNCTION__); rewind(templateFile); if ((long)fread(g_polInputTemplate, sizeof(char), length, templateFile) < length) { eprintf("Could not read template file: %s\n", strerror(errno)); fclose(templateFile); return false; } g_polInputTemplate[length] = 0; g_polInputTemplateEnd = &g_polInputTemplate[length]; fclose(templateFile); g_polTemplatePosIdent[0] = strstr(g_polInputTemplate, "###!identifier will be put here###"); g_polTemplatePosIdent[1] = strstr(g_polTemplatePosIdent[0] + 1, "###!identifier will be put here###"); g_polTemplatePosField = strstr(g_polInputTemplate, "###!field strength will be put here###"); if(g_polTemplatePosField == NULL) { eprintf("Position mark for field strength missing in template.\n"); //fclose(templateFile); return false; } g_polTemplatePosPol = strstr(g_polInputTemplate, "###!polarisation vector will be put here###"); if(g_polTemplatePosPol == NULL) { eprintf("Position mark for polarisation vector missing in template.\n"); //fclose(templateFile); return false; } g_polTemplatePosCoord = strstr(g_polInputTemplate, "###!coordinates will be put here###"); if(g_polTemplatePosCoord == NULL) { eprintf("Position mark for coordinates missing in template.\n"); //fclose(templateFile); return false; } g_polTemplatePosSteps = strstr(g_polInputTemplate, "###!number of steps will be put here###"); if(g_polTemplatePosSteps == NULL) { eprintf("Position mark for number of steps missing in template.\n"); //fclose(templateFile); return false; } if (g_polTemplatePosIdent[0] != NULL) g_polTemplatePosIdent[0][0] = 0; if (g_polTemplatePosIdent[1] != NULL) g_polTemplatePosIdent[1][0] = 0; g_polTemplatePosField[0] = 0; g_polTemplatePosPol[0] = 0; g_polTemplatePosCoord[0] = 0; g_polTemplatePosSteps[0] = 0; filename.sprintf("%s/polarizability_reftraj.xyz", (const char *)g_polarizabilityDir); g_polReftrajFile = fopen((const char *)filename, "w"); if(g_polReftrajFile == NULL) { eprintf("Could not open reference trajectory \"%s\": %s\n", (const char *)filename, strerror(errno)); //fclose(templateFile); return false; } return true; } void processPolarizabilityCalc(CTimeStep *ts) { int numAtoms = 0; int i; for (i = 0; i < g_iGesAtomCount; i++) if (g_waAtomMolIndex[i] != 60000) numAtoms++; fprintf(g_polReftrajFile, "%d\n", numAtoms); fprintf(g_polReftrajFile, "Step %lu\n", g_iSteps); for (i = 0; i < g_iGesAtomCount; i++) { if (g_waAtomMolIndex[i] == 60000) continue; fprintf(g_polReftrajFile, "%3s %16.10f %16.10f %16.10f\n", (const char*)((CAtom *)g_oaAtoms[g_waAtomRealElement[i]])->m_sName, ts->m_vaCoords_Original[i][0] / 100.0, ts->m_vaCoords_Original[i][1] / 100.0, ts->m_vaCoords_Original[i][2] / 100.0); } g_polSteps++; } void finalizePolarizabilityCalc() { fclose(g_polReftrajFile); char fieldChar[4] = "xyz"; char dirChar[3] = "pn"; CxString filename; FILE *inputFile; int i; for (i = 0; i < 3; i++) { int j; for (j = 0; j < 2; j++) { filename.sprintf("%s/polarizability_%c%c.inp", (const char *)g_polarizabilityDir, fieldChar[i], dirChar[j]); inputFile = fopen((const char *)filename, "w"); if (inputFile == NULL) { eprintf("Could not open input file \"%s\": %s\n", (const char *)filename, strerror(errno)); abort(); } fprintf(inputFile, "%s", g_polInputTemplate); const char *tempPos = strchr(g_polInputTemplate, 0); while (tempPos != g_polInputTemplateEnd) { if (tempPos == g_polTemplatePosIdent[0] || tempPos == g_polTemplatePosIdent[1]) { fprintf(inputFile, "%c%c", fieldChar[i], dirChar[j]); tempPos = &tempPos[34]; } else if (tempPos == g_polTemplatePosField) { fprintf(inputFile, "%.6E", g_polFieldStrength); tempPos = &tempPos[38]; } else if (tempPos == g_polTemplatePosPol) { if (i == 0) fprintf(inputFile, "%c1.0 0.0 0.0", j == 0 ? '+' : '-'); if (i == 1) fprintf(inputFile, "0.0 %c1.0 0.0", j == 0 ? '+' : '-'); if (i == 2) fprintf(inputFile, "0.0 0.0 %c1.0", j == 0 ? '+' : '-'); tempPos = &tempPos[43]; } else if (tempPos == g_polTemplatePosCoord) { CTimeStep *ts = GetTimeStep(0); int k; for (k = 0; k < g_iGesAtomCount; k++) { if(g_waAtomMolIndex[k] == 60000) continue; fprintf(inputFile, " %s %.10f %.10f %.10f\n", (const char*)((CAtom *)g_oaAtoms[g_waAtomRealElement[k]])->m_sName, ts->m_vaCoords_Original[k][0] / 100.0, ts->m_vaCoords_Original[k][1] / 100.0, ts->m_vaCoords_Original[k][2] / 100.0); } tempPos = &tempPos[36]; } else if (tempPos == g_polTemplatePosSteps) { fprintf(inputFile, "%d", g_polSteps); tempPos = &tempPos[39]; } fprintf(inputFile, "%s", tempPos); tempPos = strchr(tempPos, 0); } fclose(inputFile); } } delete[] g_polInputTemplate; } travis-src-190101/src/raman.h0100777000000000000000000000526513412725650012715 0ustar00/***************************************************************************** TRAVIS - Trajectory Analyzer and Visualizer http://www.travis-analyzer.de/ Copyright (c) 2009-2019 Martin Brehm 2012-2019 Martin Thomas 2016-2019 Sascha Gehrke This file was written by Martin Thomas. --------------------------------------------------------------------------- This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . *****************************************************************************/ #ifndef RAMAN_H #define RAMAN_H // This must always be the first include directive #include "config.h" #include "moltools.h" #include "reordyn.h" class CTimeStep; // class CRamanDyn: public CReorDyn // { // public: // CRamanDyn(int showMol, bool global = false); // ~CRamanDyn(); // // void initialize(); // // void getDipole0(); // void calcPolarizability(int fieldDirection); // // void finalize(); // // private: // CxObArray _dipole0; // CxObArray _polarizability[3][3]; // CACF *_isoACF; // CACF *_anisoACF; // // int _derivativeOrder; // // bool _global; // }; class CRamanObservation: public CObservation { public: CRamanObservation(bool global = false); ~CRamanObservation(); void initialize(); void getDipoleZero(); void calcPolarizability(int fieldDirection); void process(); void finalize(); private: // CRamanDyn *_ramanDyn; char *_name; int _correlationDepth; int _windowFunction; int _windowFunctionParameter; int _zeroPadding; int _specSize; double _specResolution; bool _finiteDifferenceCorrection; bool _saveACF; bool _includeCross; int _quantumCorrection; double _quantumCorrectionTemperature; double _laserFreq; double _temperature; int m_fieldMode; CxDVec3Array _dipoleZero; CxObArray _polarizabilityCache; }; bool gatherRaman(); bool initializeRaman(); void processRaman(CTimeStep *ts); void finalizeRaman(); void parsePolarizability(); bool gatherPolarizabilityCalc(); bool initializePolarizabilityCalc(); void processPolarizabilityCalc(CTimeStep *ts); void finalizePolarizabilityCalc(); #endif travis-src-190101/src/random.cpp0100777000000000000000000000311013412725633013416 0ustar00/***************************************************************************** TRAVIS - Trajectory Analyzer and Visualizer http://www.travis-analyzer.de/ Copyright (c) 2009-2019 Martin Brehm 2012-2019 Martin Thomas 2016-2019 Sascha Gehrke This file was written by Martin Brehm. --------------------------------------------------------------------------- This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . *****************************************************************************/ // This must always be the first include directive #include "config.h" #include "random.h" const char *GetRevisionInfo_random(unsigned int len) { static char buf[256]; GET_REVISION_INFO( buf, len ); return buf; } const char *GetSourceVersion_random() { static char buf[256]; GET_SOURCE_VERSION( buf ); return buf; } CRandom::CRandom() { seed = 123456789; r4_nor_setup ( kn, fn, wn ); r4_exp_setup ( ke, fe, we ); } CRandom::~CRandom() { } travis-src-190101/src/random.h0100777000000000000000000000340613412725664013077 0ustar00/***************************************************************************** TRAVIS - Trajectory Analyzer and Visualizer http://www.travis-analyzer.de/ Copyright (c) 2009-2019 Martin Brehm 2012-2019 Martin Thomas 2016-2019 Sascha Gehrke This file was written by Martin Brehm. --------------------------------------------------------------------------- This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . *****************************************************************************/ #ifndef RANDOM_H #define RANDOM_H // This must always be the first include directive #include "config.h" #include "xobject.h" #include "ziggurat.h" #include class CRandom : public CxObject { public: CRandom(); ~CRandom(); double RandomUniform() { // return r4_uni(&seed); return ((double)(rand()%RAND_MAX)/RAND_MAX/RAND_MAX) + ((double)(rand()%RAND_MAX)/RAND_MAX); } double RandomNormal() { return r4_nor(&seed,kn,fn,wn); } double RandomExp() { return r4_exp(&seed,ke,fe,we); } double fn[128]; int kn[128]; double wn[128]; double fe[256]; int ke[256]; double we[256]; unsigned long int seed; }; #endif travis-src-190101/src/reactive.cpp0100777000000000000000000001230513412725635013750 0ustar00/***************************************************************************** TRAVIS - Trajectory Analyzer and Visualizer http://www.travis-analyzer.de/ Copyright (c) 2009-2019 Martin Brehm 2012-2019 Martin Thomas 2016-2019 Sascha Gehrke This file was written by Martin Brehm. --------------------------------------------------------------------------- This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . *****************************************************************************/ // This must always be the first include directive #include "config.h" #include "reactive.h" #include "tools.h" #include "globalvar.h" #include "maintools.h" #include "timestep.h" #include "posdomain.h" const char *GetRevisionInfo_reactive(unsigned int len) { static char buf[256]; GET_REVISION_INFO( buf, len ); return buf; } const char *GetSourceVersion_reactive() { static char buf[256]; GET_SOURCE_VERSION( buf ); return buf; } CReactiveRingBuffer::CReactiveRingBuffer() { m_iCurrentPos = -1; m_iAtomCount = 0; m_iDepth = 0; } CReactiveRingBuffer::~CReactiveRingBuffer() { } void CReactiveRingBuffer::Init(int depth, int atomcount) { int z; m_iAtomCount = atomcount; m_iDepth = depth; m_vaaCoords.resize(atomcount); for (z=0;z= m_iDepth) m_iCurrentPos = 0; for (z=0;zm_pElement->m_fRadius > maxbond) maxbond = ((CAtom*)g_oaAtoms[z])->m_pElement->m_fRadius; maxbond *= 2 * g_fBondFactor; if (!OpenInputTrajectory()) { eprintf("Error: Could not open position trajectory for reading.\n"); abort(); } if (g_bNPT && (g_sNPTFile[0] != 0)) { g_fNPTFile = fopen((const char*)g_sNPTFile,"rt"); if (g_fNPTFile == NULL) { eprintf("Error: Could not open cell vector file \"%s\" for reading.\n",(const char*)g_sNPTFile); abort(); } } rb.Init(2*m_iBondPersist,g_iGesAtomCount); step = 0; while (true) { if (!ts.ReadTimestep(g_fPos,true)) { if (InputTrajectoryEOF()) mprintf("End of trajectory file reached.\n"); else eprintf("Error while reading trajectory frame.\n"); break; } rb.PushFrame(ts.m_vaCoords); if (g_bNPT) { if (g_sNPTFile[0] != 0) ts.ReadCellVector(g_fNPTFile); if (g_bBoxNonOrtho) rb.PushCellMatrix(g_mBoxFromOrtho); else rb.PushCellVector(g_fBoxX,g_fBoxY,g_fBoxZ); } if (g_bPeriodicX && g_bPeriodicY && g_bPeriodicZ) de.Create( ts.m_vaCoords, g_mBoxFromOrtho, maxbond ); else de.CreateTrivial( ts.m_vaCoords ); step++; } if ((g_bNPT) && (g_sNPTFile[0] != 0)) fclose(g_fNPTFile); CloseInputTrajectory(); mprintf("\n"); mprintf(WHITE," ##############################################\n"); mprintf(WHITE," #### Reactive Molecule Scan Finished ####\n"); mprintf(WHITE," ##############################################\n"); mprintf("\n"); } travis-src-190101/src/reactive.h0100777000000000000000000000410113412725647013413 0ustar00/***************************************************************************** TRAVIS - Trajectory Analyzer and Visualizer http://www.travis-analyzer.de/ Copyright (c) 2009-2019 Martin Brehm 2012-2019 Martin Thomas 2016-2019 Sascha Gehrke This file was written by Martin Brehm. --------------------------------------------------------------------------- This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . *****************************************************************************/ #ifndef REACTIVE_H #define REACTIVE_H // This must always be the first include directive #include "config.h" #include #include "xdvector3.h" #include "xdvec3array.h" #include "xdmatrix3.h" class CReactiveRingBuffer { public: CReactiveRingBuffer(); ~CReactiveRingBuffer(); void Init(int depth, int atomcount); void PushFrame(const CxDVec3Array &va); void PushCellMatrix(const CxDMatrix3 &m); void PushCellVector(double x, double y, double z); const CxDVector3 & Get(int atom, int depth) const { int t = m_iCurrentPos - depth; if (t < 0) t += m_iDepth; return m_vaaCoords[atom][t]; } int m_iCurrentPos; int m_iDepth; int m_iAtomCount; std::vector > m_vaaCoords; std::vector m_maCellMatrix; std::vector m_vaCellVector; }; class CReactiveEngine { public: CReactiveEngine(); ~CReactiveEngine(); void Parse(); bool m_bFirst; int m_iBondPersist; }; #endif travis-src-190101/src/reflux.cpp0100777000000000000000000014540113412725621013452 0ustar00/***************************************************************************** TRAVIS - Trajectory Analyzer and Visualizer http://www.travis-analyzer.de/ Copyright (c) 2009-2019 Martin Brehm 2012-2019 Martin Thomas 2016-2019 Sascha Gehrke This file was written by Sascha Gehrke. --------------------------------------------------------------------------- This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . *****************************************************************************/ // This must always be the first include directive #include "config.h" #include "reflux.h" #include "luzar.h" #include "math.h" #include "globalvar.h" #include "maintools.h" const char *GetRevisionInfo_reflux(unsigned int len) { static char buf[256]; GET_REVISION_INFO( buf, len ); return buf; } const char *GetSourceVersion_reflux() { static char buf[256]; GET_SOURCE_VERSION( buf ); return buf; } static CxObArray g_ReFluxObserv; bool gatherReFlux() { CReFluxObservation *o; try { o = new CReFluxObservation(); } catch(...) { o = NULL; } if (o == NULL) NewException((double)sizeof(CReFluxObservation),__FILE__,__LINE__,__PRETTY_FUNCTION__); g_ReFluxObserv.Add(o); return true; } bool initializeReFlux() { int i; for(i = 0; i < g_ReFluxObserv.GetSize(); i++) { ((CReFluxObservation *)g_ReFluxObserv[i])->initialize(); } return true; } bool processReFlux(CTimeStep* ts) { int i; for(i = 0; i < g_ReFluxObserv.GetSize(); i++) { ((CReFluxObservation *)g_ReFluxObserv[i])->process(ts); } return true; } bool finalizeReFlux() { int i; for(i = 0; i < g_ReFluxObserv.GetSize(); i++) { ((CReFluxObservation *)g_ReFluxObserv[i])->finalize(); } return true; } CReFluxObservation::CReFluxObservation() { int i_temp, mol = 0; bool b_temp; double d_temp; int i,j,z; CxString buf, buf2, buf_temp; CReFluxCond* temp; m_iShowMol3 = -1; mprintf(" The generelized reactive flux analysis is organized as followed:\n"); mprintf(" First two types of molecules are defined: the reference molecule RM\n"); mprintf(" the observed molecule OM\n"); mprintf(" All possible combinations of these molecules are the total number of pairs.\n"); mprintf(" The neighboring of each pair is defined by a single distance criterion \n"); mprintf(" defined by a maximum distance between one atom of RM and one of OM.\n"); mprintf(" For the aggregation a third molecule type may be include: The TM.\n"); if (g_oaMolecules.GetSize() > 1) { buf.sprintf("\n Which of the molecules should be the reference molecule ("); for (z=0;zm_sName,z+1); buf.strcat(buf2); if (z < g_oaMolecules.GetSize()-1) buf.strcat(", "); } buf.strcat(")? "); m_iShowMol = AskRangeInteger_ND("%s",1,g_oaMolecules.GetSize(),(const char*)buf) - 1; buf.sprintf("\n Which of the molecules should be the observed molecule ("); for (z=0;zm_sName,z+1); buf.strcat(buf2); if (z < g_oaMolecules.GetSize()-1) buf.strcat(", "); } buf.strcat(")? "); m_iShowMol2 = AskRangeInteger_ND("%s",1,g_oaMolecules.GetSize(),(const char*)buf) - 1; } else { m_iShowMol = 0; m_iShowMol2 = 0; } mprintf(WHITE,"\n %s is the reference molecule.\n\n",((CMolecule*)g_oaMolecules[m_iShowMol])->m_sName); mprintf(WHITE,"\n %s is the observed molecule.\n\n",((CMolecule*)g_oaMolecules[m_iShowMol2])->m_sName); for ( i=0; i < ((CMolecule*)g_oaMolecules[m_iShowMol])->m_laSingleMolIndex.GetSize(); i++) { for ( j=0; j < ((CMolecule*)g_oaMolecules[m_iShowMol2])->m_laSingleMolIndex.GetSize(); j++) { try { temp = new CReFluxCond(); } catch(...) { temp = NULL; } if (temp == NULL) NewException((double)sizeof(CReFluxCond),__FILE__,__LINE__,__PRETTY_FUNCTION__); m_oaCond.Add(temp); } } mprintf("\n Analyzing %d pairs of molecules!\n", m_oaCond.GetSize()); mprintf(" Which atom from %s defines the neighboring condition (e.g. \"C1,O3,#2\" )?",((CMolecule*)g_oaMolecules[m_iShowMol])->m_sName); inpprintf("! Which atom from %s defines the neighboring condition (e.g. \"C1,O3,#2\" )?\n",((CMolecule*)g_oaMolecules[m_iShowMol])->m_sName); myget(&buf); while ((strlen(buf) == 0) || (!checkAtomChoice(buf,1,1))) { mprintf(" Please enter single atom!\n"); myget(&buf); } mprintf(" Which atom from %s defines the neighboring condition (e.g. \"C1,O3,#2\" )?",((CMolecule*)g_oaMolecules[m_iShowMol2])->m_sName); inpprintf("! Which atom from %s defines the neighboring condition (e.g. \"C1,O3,#2\" )?\n",((CMolecule*)g_oaMolecules[m_iShowMol2])->m_sName); myget(&buf); while ((strlen(buf) == 0) || (!checkAtomChoice(buf,2,2))) { mprintf(" Please enter atom!\n"); myget(&buf); } d_temp = AskFloat(" Enter maximum distance for neighbor criterion [300] ",300.0); for ( i=0; i < m_oaCond.GetSize(); i++ ) ((CReFluxCond*)m_oaCond[i])->m_dNeighDist = d_temp; if ( AskYesNo(" Perform three body analysis? [no]", false) ) { if (g_oaMolecules.GetSize() > 1) { buf.sprintf("\n Which of the molecules should be the third molecule ("); for (z=0;zm_sName,z+1); buf.strcat(buf2); if (z < g_oaMolecules.GetSize()-1) buf.strcat(", "); } buf.strcat(")? "); m_iShowMol3 = AskRangeInteger_ND("%s",1,g_oaMolecules.GetSize(),(const char*)buf) - 1; } else m_iShowMol3 = 0; mprintf(WHITE,"\n %s is the third molecule.\n\n",((CMolecule*)g_oaMolecules[m_iShowMol3])->m_sName); } if ( m_iShowMol3 != -1 ) { mprintf(" For a three body analysis a distance criterion containing at least one atom of the TM is needed!\n"); mprintf(" Add which atom(s) from %s to distance condition (e.g. \"C1,O3-5,#2\" *=all)?",((CMolecule*)g_oaMolecules[m_iShowMol3])->m_sName); inpprintf("! Add which atom(s) from %s to distance condition (e.g. \"C1,O3-5,#2\" *=all)?\n",((CMolecule*)g_oaMolecules[m_iShowMol3])->m_sName); while ((strlen(buf) == 0) || (!checkAtomChoice(buf,3,3))) { mprintf(" Please enter atom(s)!\n"); myget(&buf); } i_temp = AskRangeInteger_ND("\n Take second atom(s) from which molecule (%s(RM)=1, %s(OM)=2, %s(TM)=3 )?", 1, 3, ((CMolecule*)g_oaMolecules[m_iShowMol])->m_sName, ((CMolecule*)g_oaMolecules[m_iShowMol2])->m_sName, ((CMolecule*)g_oaMolecules[m_iShowMol3])->m_sName ); if ( i_temp == 1 ) mol = m_iShowMol; else if ( i_temp == 2 ) mol = m_iShowMol2; else if ( i_temp == 3 ) mol = m_iShowMol3; mprintf(" Add which atom(s) from %s to distance condition (e.g. \"C1,O3-5,#2\" *=all)?",((CMolecule*)g_oaMolecules[mol])->m_sName); inpprintf("! Add which atom(s) from %s to distance condition (e.g. \"C1,O3-5,#2\" *=all)?\n",((CMolecule*)g_oaMolecules[mol])->m_sName); myget(&buf); while ((strlen(buf) == 0) || (!checkAtomChoice(buf,i_temp,4))) { mprintf(" Please enter atom(s)!\n"); myget(&buf); } d_temp = AskFloat(" Enter maximum distance for distance criterion (in pm) [300] ",300.0); for ( i=0; i < m_oaCond.GetSize(); i++ ) for ( z=0; z < ((CReFluxCond*)m_oaCond[i])->m_oaDistConds.GetSize(); z++ ) if ( ((CReFluxSingleCond*)((CReFluxCond*)m_oaCond[i])->m_oaDistConds[z])->m_dAggrMinAngle == -1.0 ) ((CReFluxSingleCond*)((CReFluxCond*)m_oaCond[i])->m_oaDistConds[z])->m_dAggrMinAngle = d_temp; } while ( AskYesNo(" Define a(nother) distance criterion for the aggregation? [no]", false) ) { if ( m_iShowMol3 != -1 ) i_temp = AskRangeInteger_ND("\n Take first atom(s) from which molecule (%s(RM)=1, %s(OM)=2, %s(TM)=3)?", 1, 3, ((CMolecule*)g_oaMolecules[m_iShowMol])->m_sName, ((CMolecule*)g_oaMolecules[m_iShowMol2])->m_sName, ((CMolecule*)g_oaMolecules[m_iShowMol3])->m_sName ); else i_temp = AskRangeInteger_ND("\n Take first atom(s) from which molecule (%s(RM)=1, %s(OM)=2)?", 1, 2, ((CMolecule*)g_oaMolecules[m_iShowMol])->m_sName, ((CMolecule*)g_oaMolecules[m_iShowMol2])->m_sName ); if ( i_temp == 1 ) mol = m_iShowMol; else if ( i_temp == 2 ) mol = m_iShowMol2; else if ( i_temp == 3 ) mol = m_iShowMol3; mprintf(" Add which atom(s) from %s to distance condition (e.g. \"C1,O3-5,#2\" *=all)?",((CMolecule*)g_oaMolecules[mol])->m_sName); inpprintf("! Add which atom(s) from %s to distance condition (e.g. \"C1,O3-5,#2\" *=all)?\n",((CMolecule*)g_oaMolecules[mol])->m_sName); myget(&buf); while ((strlen(buf) == 0) || (!checkAtomChoice(buf,i_temp,3))) { mprintf(" Please enter atom(s)!\n"); myget(&buf); } if ( m_iShowMol3 != -1 ) i_temp = AskRangeInteger_ND("\n Take second atom(s) from which molecule (%s(RM)=1, %s(OM)=2, %s(TM)=3)?", 1, 3, ((CMolecule*)g_oaMolecules[m_iShowMol])->m_sName, ((CMolecule*)g_oaMolecules[m_iShowMol2])->m_sName, ((CMolecule*)g_oaMolecules[m_iShowMol3])->m_sName ); else i_temp = AskRangeInteger_ND("\n Take second atom(s) from which molecule (%s(RM)=1, %s(OM)=2)?", 1, 2, ((CMolecule*)g_oaMolecules[m_iShowMol])->m_sName, ((CMolecule*)g_oaMolecules[m_iShowMol2])->m_sName ); if ( i_temp == 1 ) mol = m_iShowMol; else if ( i_temp == 2 ) mol = m_iShowMol2; else if ( i_temp == 3 ) mol = m_iShowMol3; mprintf(" Add which atom(s) from %s to distance condition (e.g. \"C1,O3-5,#2\" *=all)?",((CMolecule*)g_oaMolecules[mol])->m_sName); inpprintf("! Add which atom(s) from %s to distance condition (e.g. \"C1,O3-5,#2\" *=all)?\n",((CMolecule*)g_oaMolecules[mol])->m_sName); myget(&buf); while ((strlen(buf) == 0) || (!checkAtomChoice(buf,i_temp,4))) { mprintf(" Please enter atom(s)!\n"); myget(&buf); } d_temp = AskFloat(" Enter maximum distance for distance criterion (in pm) [300] ",300.0); for ( i=0; i < m_oaCond.GetSize(); i++ ) for ( z=0; z < ((CReFluxCond*)m_oaCond[i])->m_oaDistConds.GetSize(); z++ ) if ( ((CReFluxSingleCond*)((CReFluxCond*)m_oaCond[i])->m_oaDistConds[z])->m_dAggrMinAngle == -1.0 ) ((CReFluxSingleCond*)((CReFluxCond*)m_oaCond[i])->m_oaDistConds[z])->m_dAggrMinAngle = d_temp; } SortDist(); while ( AskYesNo("\n Define an(other) angle criterion for the aggregation? [no]", false) ) { mprintf(" Two vectors need to be defined.\n"); mprintf(" Each vector can be defined by two points or perpendicular to a plane by three points.\n"); mprintf(" Each point can be an atom from the reference molecule (RM), the observed molecule (OM),\n"); mprintf(" or the third molecule (TM).\n"); for ( z=5; z<11; z++ ) { if ( z == 5 ) mprintf("\n First vector:\n"); else mprintf("\n Second vector:\n"); b_temp = !AskYesNo(" Define vector by two points (y) or perpendicular to a plane (n) ? [yes]", true); if ( m_iShowMol3 != -1 ) i_temp = AskRangeInteger_ND("\n Take base atom(s) from which molecule (%s(RM)=1, %s(OM)=2, %s(TM)=3)?", 1, 3, ((CMolecule*)g_oaMolecules[m_iShowMol])->m_sName, ((CMolecule*)g_oaMolecules[m_iShowMol2])->m_sName, ((CMolecule*)g_oaMolecules[m_iShowMol3])->m_sName ); else i_temp = AskRangeInteger_ND("\n Take base atom(s) from which molecule (%s(RM)=1, %s(OM)=2)?", 1, 2, ((CMolecule*)g_oaMolecules[m_iShowMol])->m_sName, ((CMolecule*)g_oaMolecules[m_iShowMol2])->m_sName ); if ( i_temp == 1 ) mol = m_iShowMol; else if ( i_temp == 2 ) mol = m_iShowMol2; else if ( i_temp == 3 ) mol = m_iShowMol3; mprintf(" Use which atom(s) from %s as base atom(s) (e.g. \"C1,O3-5,#2\" *=all)?",((CMolecule*)g_oaMolecules[mol])->m_sName); inpprintf("! Use which atom(s) from %s as base atom(s) (e.g. \"C1,O3-5,#2\" *=all)?\n",((CMolecule*)g_oaMolecules[mol])->m_sName); myget(&buf); while ((strlen(buf) == 0) || (!checkAtomChoice(buf, i_temp, z++))) { mprintf(" Please enter atom(s)!\n"); myget(&buf); } if ( m_iShowMol3 != -1 ) i_temp = AskRangeInteger_ND("\n Take second atom(s) from which molecule (%s(RM)=1, %s(OM)=2, %s(TM)=3)?", 1, 3, ((CMolecule*)g_oaMolecules[m_iShowMol])->m_sName, ((CMolecule*)g_oaMolecules[m_iShowMol2])->m_sName, ((CMolecule*)g_oaMolecules[m_iShowMol3])->m_sName ); else i_temp = AskRangeInteger_ND("\n Take second atom(s) from which molecule (%s(RM)=1, %s(OM)=2)?", 1, 2, ((CMolecule*)g_oaMolecules[m_iShowMol])->m_sName, ((CMolecule*)g_oaMolecules[m_iShowMol2])->m_sName ); if ( i_temp == 1 ) mol = m_iShowMol; else if ( i_temp == 2 ) mol = m_iShowMol2; else if ( i_temp == 3 ) mol = m_iShowMol3; mprintf(" Use which atom(s) from %s as second atom(s) (e.g. \"C1,O3-5,#2\" *=all)?",((CMolecule*)g_oaMolecules[mol])->m_sName); inpprintf("! Use which atom(s) from %s as second atom(s) (e.g. \"C1,O3-5,#2\" *=all)?\n",((CMolecule*)g_oaMolecules[mol])->m_sName); myget(&buf); while ((strlen(buf) == 0) || (!checkAtomChoice(buf, i_temp, z++))) { mprintf(" Please enter atom(s)!\n"); myget(&buf); } if ( b_temp ) { if ( m_iShowMol3 != -1 ) i_temp = AskRangeInteger_ND("\n Take third atom(s) from which molecule (%s(RM)=1, %s(OM)=2, %s(TM)=3)?", 1, 3, ((CMolecule*)g_oaMolecules[m_iShowMol])->m_sName, ((CMolecule*)g_oaMolecules[m_iShowMol2])->m_sName, ((CMolecule*)g_oaMolecules[m_iShowMol3])->m_sName ); else i_temp = AskRangeInteger_ND("\n Take third atom(s) from which molecule (%s(RM)=1, %s(OM)=2)?", 1, 2, ((CMolecule*)g_oaMolecules[m_iShowMol])->m_sName, ((CMolecule*)g_oaMolecules[m_iShowMol2])->m_sName ); if ( i_temp == 1 ) mol = m_iShowMol; else if ( i_temp == 2 ) mol = m_iShowMol2; else if ( i_temp == 3 ) mol = m_iShowMol3; mprintf(" Use which atom(s) from %s as third atom(s) (e.g. \"C1,O3-5,#2\" *=all)?",((CMolecule*)g_oaMolecules[mol])->m_sName); inpprintf("! Use which atom(s) from %s as third atom(s) (e.g. \"C1,O3-5,#2\" *=all)?\n",((CMolecule*)g_oaMolecules[mol])->m_sName); myget(&buf); while ((strlen(buf) == 0) || (!checkAtomChoice(buf, i_temp, z))) { mprintf(" Please enter atom(s)!\n"); myget(&buf); } } else for ( i=0; i < m_oaCond.GetSize(); i++ ) for ( j=0; j < ((CReFluxCond*)m_oaCond[i])->m_oaAngleConds.GetSize(); j++ ) ((CReFluxSingleCond*)((CReFluxCond*)m_oaCond[i])->m_oaAngleConds[j])->m_iaTypes.Add(-1); } d_temp = cos((M_PI/180)*AskRangeFloat(" Enter minimum angle for aggregation criterion [0] ",0.0,179.0,0.0)); for ( i=0; i < m_oaCond.GetSize(); i++ ) for ( j=0; j < ((CReFluxCond*)m_oaCond[i])->m_oaAngleConds.GetSize(); j++ ) if ( ((CReFluxSingleCond*)((CReFluxCond*)m_oaCond[i])->m_oaAngleConds[j])->m_dAggrMinAngle == -1 ) ((CReFluxSingleCond*)((CReFluxCond*)m_oaCond[i])->m_oaAngleConds[j])->m_dAggrMinAngle = d_temp; d_temp = cos((M_PI/180)*AskRangeFloat(" Enter maximum angle for aggregation criterion [180] ",d_temp,180.0,180.0)); for ( i=0; i < m_oaCond.GetSize(); i++ ) for ( j=0; j < ((CReFluxCond*)m_oaCond[i])->m_oaAngleConds.GetSize(); j++ ) if ( ((CReFluxSingleCond*)((CReFluxCond*)m_oaCond[i])->m_oaAngleConds[j])->m_dAggrMaxAngle == -1 ) ((CReFluxSingleCond*)((CReFluxCond*)m_oaCond[i])->m_oaAngleConds[j])->m_dAggrMaxAngle = d_temp; } SortAngle(); SortFinal(); if ( ((CReFluxCond*)m_oaCond[0])->m_oaAggrConds.GetSize() == 0 ) { eprintf("Error: No aggregation criterion left?\n"); abort(); } z = m_oaCond.GetSize(); j = ((CMolecule*)g_oaMolecules[m_iShowMol])->m_laSingleMolIndex.GetSize(); if ( m_iShowMol == m_iShowMol2 ) for ( i=0; i < j; i++ ) m_oaCond.RemoveAt(z-(i*(j+1))-1,1); mprintf("\n Analysing %d pairs with %d aggregation criteria each ...\n",m_oaCond.GetSize(),((CReFluxCond*)m_oaCond[0])->m_oaAggrConds.GetSize()); g_fTimestepLength = AskFloat(" Enter the length of one trajectory time step in fs: [0.5] ",0.5f); } CReFluxObservation::~CReFluxObservation() { } void CReFluxObservation::initialize() { CxIntArray* temp; int i; for ( i=0; i < m_oaCond.GetSize(); i++ ) { try { temp = new CxIntArray(); } catch(...) { temp = NULL; } if (temp == NULL) NewException((double)sizeof(CxIntArray),__FILE__,__LINE__,__PRETTY_FUNCTION__); m_oaNeigh.Add(temp); try { temp = new CxIntArray(); } catch(...) { temp = NULL; } if (temp == NULL) NewException((double)sizeof(CxIntArray),__FILE__,__LINE__,__PRETTY_FUNCTION__); m_oaAggr.Add(temp); } if ( g_iMaxStep != -1 ) m_iDepth = g_iMaxStep * 3 / 4 / g_iStride; else m_iDepth = g_iTrajSteps * 3 / 4 / g_iStride; m_iDepth = AskUnsignedInteger(" Enter the resolution (=depth) of the ACF (in time steps): [%d] ", m_iDepth, m_iDepth); if ( m_iDepth > g_iTrajSteps ) { mprintf(" Correlation Depth is exceeding number of total timesteps. Truncating ....\n"); m_iDepth = g_iTrajSteps; } m_iTrunc = m_iDepth; while ( m_iTrunc > (int)(m_iDepth/10) ) { m_iTrunc = (int)(50000/(g_fTimestepLength*g_iStride)); if ( m_iTrunc > m_iDepth/10 ) m_iTrunc = (int)(m_iDepth/10); m_iTrunc = AskUnsignedInteger(" Enter the truncation for the fitting procedure (in time steps): [%d] ", m_iTrunc, m_iTrunc); if ( m_iTrunc > m_iDepth/10 ) mprintf(" Truncation must be at least 10 times smaller than correlation depth!\n"); } } void CReFluxObservation::process(CTimeStep* ts) { int i; for ( i=0; i < m_oaCond.GetSize(); i++ ) ((CReFluxCond*)m_oaCond[i])->check(ts,((CxIntArray*)m_oaNeigh[i]),((CxIntArray*)m_oaAggr[i])); } void CReFluxObservation::finalize() // reconstruct functions -> autocorrelate -> sum results -> normalize -> fit { long n,i,interval; double AggrCor, DiffCor; CxString buf,buf2; unsigned long t0,eta; CxDoubleArray NeighFunction; // Input CxDoubleArray AggrFunction; CxDoubleArray temp1Function; // Temp CxDoubleArray temp2Function; CLuzarCorrelation luzar; for ( i=0; i < m_iDepth; i++ ) { AggrDynamic.Add(0.0); DiffusionDynamic.Add(0.0); } NeighFunction.SetSize(g_iSteps / g_iStride); AggrFunction.SetSize(g_iSteps / g_iStride); luzar.Init(g_iSteps / g_iStride,m_iDepth); // Inititalize Luzar-Correlation mprintf(" Finishing %6i Functions ... \nFunc %6li ",m_oaNeigh.GetSize(),(long)0); g_iDotCounter = 0; t0 = (unsigned long)time(NULL); interval = 2; for ( n=0; n < m_oaNeigh.GetSize(); n++) // Walk over all pairs { if ( n % interval == 0 ) { if ( g_iDotCounter >= 50 ) { if ( interval == 2 && n > 100 ) { interval = 20; } else if ( interval == 20 && n > 2000 ) { interval = 200; } g_iDotCounter = 0; if ((time(NULL) - t0) > 5) { eta = (unsigned long)(((double)time(NULL) - t0) / n * ((double)MAX((long)0,(long)m_oaNeigh.GetSize() - (long)n))); FormatTime(eta,&buf); mprintf(" ETA %s",(const char*)buf); } mprintf("\nFunc %6li ",n); } g_iDotCounter++; mprintf("."); } if ( ((CxIntArray*)m_oaNeigh[n])->GetSize() > 0 ) { RestoreFunction(((CxIntArray*)m_oaNeigh[n]),&NeighFunction); // Restore function of pair n as NeighFunction and AggrFunction RestoreFunction(((CxIntArray*)m_oaAggr[n]),&AggrFunction); luzar.Correlate(&AggrFunction,&NeighFunction,&temp1Function,&temp2Function); for ( i=0; i < m_iDepth; i++ ) // Sum results to Output-array { AggrDynamic[i] += temp1Function[i]; DiffusionDynamic[i] += temp2Function[i]; } } } mprintf("\n\n"); if ( AggrDynamic[0] == 0 || DiffusionDynamic[0] == 0 ) { eprintf("First correlation value is zero ... something is wrong ...\n"); abort(); } AggrCor = (double)AggrDynamic[0]; DiffCor = (double)DiffusionDynamic[0]; for ( i=0; i < m_iDepth; i++ ) // Normalize { AggrDynamic[i] /= AggrCor; DiffusionDynamic[i] /= DiffCor; DiffusionDynamic[i] -= AggrDynamic[i]; } luzar.Fit(&AggrDynamic, &DiffusionDynamic, &k_t, &a, &b, m_iTrunc); WriteOutput(); } void CReFluxObservation::RestoreFunction(CxIntArray* input, CxDoubleArray* output) { unsigned int n; bool eins = false; for ( n=0; n < (g_iSteps / g_iStride); n++ ) // Walk over all processed steps { if ( input->Contains((n+1)*g_iStride) ) eins = !eins; if (!eins) output->SetAt(n,0.0); else output->SetAt(n,1.0); } } bool CReFluxObservation::includeAtom(int atom, int number, int moltype, int target) // atom: element number, number: atomsort number, mol m_iShowMol, target: in which array to include { int n, m, i, smol = -1, count = -1, mol; CxIntArray includeME, temp; if ( moltype == 1 ) mol = m_iShowMol; else if ( moltype == 2 ) mol = m_iShowMol2; else if ( moltype == 3 ) mol = m_iShowMol3; else { eprintf("CReFluxObservation::includeAtom Error: Unknown moltype %d!",moltype); abort(); } for ( n=0; n < ((CMolecule*)g_oaMolecules[m_iShowMol])->m_laSingleMolIndex.GetSize(); n++) { for ( m=0; m < ((CMolecule*)g_oaMolecules[m_iShowMol2])->m_laSingleMolIndex.GetSize(); m++) { count++; if ( moltype == 1 ) // Ref smol = n; if ( moltype == 2 ) // Obs smol = m; if ( smol != -1 ) { includeME.CopyFrom((CxIntArray*)(((CSingleMolecule*)g_oaSingleMolecules[((CMolecule*)g_oaMolecules[mol])->m_laSingleMolIndex[smol]])->m_oaAtomOffset[atom])); if (number >= includeME.GetSize()) { eprintf("CReFluxObservation::includeAtom(): Internal error (%d/%d).\n",number,includeME.GetSize()); abort(); } ((CReFluxCond*)m_oaCond[count])->Add(moltype, target,includeME[number]); } else { for ( i=0; i < ((CMolecule*)g_oaMolecules[mol])->m_laSingleMolIndex.GetSize(); i++ ) { temp.CopyFrom((CxIntArray*)(((CSingleMolecule*)g_oaSingleMolecules[((CMolecule*)g_oaMolecules[mol])->m_laSingleMolIndex[smol]])->m_oaAtomOffset[atom])); if (number >= temp.GetSize()) { eprintf("CReFluxObservation::includeAtom(): Internal error (%d/%d).\n",number,temp.GetSize()); abort(); } includeME.Add(temp[number]); } ((CReFluxCond*)m_oaCond[count])->AddArray(moltype, target,&includeME); } } } return true; } bool CReFluxObservation::checkAtomChoice(const char *s, int moltype, int target) { const char *p, *q; char buf[32]; const char *allowed = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890-,#*_ "; int inclu, la = -1, i = -1, i2 = -1, atom = -1, n, mol; bool m = false, fin = false, single = false; if ( moltype == 1 ) mol = m_iShowMol; else if ( moltype == 2 ) mol = m_iShowMol2; else if ( moltype == 3 ) mol = m_iShowMol3; else { eprintf("CReFluxObservation::includeAtom Error: Unknown moltype %d!",moltype); abort(); } if ( target == 1 || target == 2 ) single = true; p = s; while (*p != 0) { fin = false; while (*p == ' ') p++; if ( single && ( *p == ',' || *p == '*' || *p == '-' ) ) { eprintf("Error: Must be single atom!\n"); return false; } if (strchr(allowed,*p) == NULL) { eprintf("Error: Character \"%c\" not allowed.\n",*p); return false; } if ( *p == '*' ) { for ( n=0; n < ((CMolecule*)g_oaMolecules[mol])->m_baAtomIndex.GetSize()-1; n++ ) for (inclu = 0; inclu < ((CMolecule*)g_oaMolecules[mol])->m_waAtomCount[n]; inclu++ ) includeAtom(n, inclu, moltype, target); //hier return true; } q = p; if (isalpha(*q) || *q == '#') { if (m) { eprintf("Error: Only digit allowed after \"-\".\n"); return false; } while ( isalpha(*q) || *q == '#' ) q++; if (q-p >= 32) { eprintf("Internal Error (%ld >= 32).\n",q-p); return false; } memcpy(buf,p,q-p); buf[q-p] = 0; atom = ((CMolecule*)g_oaMolecules[mol])->FindAtomInMol(buf); // atom holds number of element if (atom == -1) { eprintf("Error: Atom \"%s\" not in the molecule.\n",buf); return false; } } else if (isdigit(*q)) { if (atom == -1) atom = la; if (atom == -1) { eprintf("Error: Number in the beginning not possible.\n"); return false; } while (isdigit(*q)) q++; if ((*q != '-') && (*q != ',') && (*q != ' ') && (*q != 0)) { eprintf("Error: Only \",\" or \"-\" may follow after a number.\n"); return false; } if (q-p >= 32) { eprintf("Internal Error (%ld >= 32).\n",q-p); return false; } memcpy(buf,p,q-p); buf[q-p] = 0; if (atoi(buf)-1 >= ((CMolecule*)g_oaMolecules[mol])->m_waAtomCount[atom]) { eprintf("Error: Only %d %s atoms in the molecule (requested: %d)\n",((CMolecule*)g_oaMolecules[mol])->m_waAtomCount[atom],(const char*)((CAtom*)g_oaAtoms[((CMolecule*)g_oaMolecules[mol])->m_baAtomIndex[atom]])->m_sName,atoi(buf)); return false; } if (m) // Range: Include all atoms from i to i2 case: X1-3 A { i2 = atoi(buf)-1; if (i2 < i) // If range from high to low -> wrong input { eprintf("Error: Invalid atom range, %d < %d.\n",i2+1,i+1); return false; } else { for (inclu = i; inclu <= i2; inclu++) { includeAtom(atom, inclu, moltype, target); //hier } fin = true; } } else { i = atoi(buf)-1; } } else if (*q == '-') { if (i == -1) { eprintf("Error: \"-\" without preceding number.\n"); return false; } m = true; q++; } else if (*q == ',') { if (atom == -1) { eprintf("Error: Comma without atom.\n"); return false; } if ( i == -1 ) // include all atoms of kind case: X, C for (inclu = 0; inclu < ((CMolecule*)g_oaMolecules[mol])->m_waAtomCount[atom]; inclu++ ) includeAtom(atom, inclu, moltype, target); //hier else if (!m) // include single atom case: X1, B includeAtom(atom, i, moltype, target); // hier la = atom; m = false; i = -1; i2 = -1; atom = -1; q++; fin = true; } p = q; } if ( !fin ) { if ( i == -1 ) // case: X { for (inclu = 0; inclu < ((CMolecule*)g_oaMolecules[mol])->m_waAtomCount[atom]; inclu++ ) { includeAtom(atom, inclu, moltype, target); //hier } } else // case: X1 { includeAtom(atom, i, moltype, target); // hier } } return true; } void CReFluxObservation::WriteOutput() { CGrace gc, gc2; int n,m; mprintf(" Writing \"Correlations.agr\"...\n"); gc.SetRangeX(0,m_iDepth*g_iStride*g_fTimestepLength/1000); gc.SetRangeY(0,1); gc.MakeTicks(); gc.SetLabelX("t [ps]"); gc.SetLabelY("f(t)"); gc.CurrentGraph()->m_bInvertXAxis = false; gc.CurrentGraph()->m_bLegend = true; gc.AddDataset(); gc.SetDatasetName(0, "c(t)"); gc.AddDataset(); gc.SetDatasetName(1, "n(t)"); for ( n = 0; n < AggrDynamic.GetSize(); n++) { gc.AddXYTupel(0,n*g_fTimestepLength*g_iStride/1000,AggrDynamic[n]); gc.AddXYTupel(1,n*g_fTimestepLength*g_iStride/1000,DiffusionDynamic[n]); } gc.WriteAgr("Correlations.agr",false); gc.WriteCSV("Correlations.csv"); mprintf(" Writing \"Fitted.agr\"...\n"); CalcMinMax(); gc2.SetRangeX(0,m_dGraceMax); gc2.SetRangeY(0,m_dGraceMax); gc2.MakeTicks(); gc2.SetLabelX("kf c(t) - kb n(t) [1/ps]"); gc2.SetLabelY("-dc/dt [1/ps]"); gc2.CurrentGraph()->m_bInvertXAxis = false; gc2.CurrentGraph()->m_bLegend = true; gc2.AddDataset(); gc2.SetDatasetName(0, "Data"); for ( m=0; m < k_t.GetSize(); m++) gc2.AddXYTupel(0,a[0] * AggrDynamic[m] - b[0] * DiffusionDynamic[m], - k_t[m]); gc2.WriteCSV("Fitted.csv"); gc2.AddDataset(); gc2.SetDatasetName(1, "Unity"); gc2.AddXYTupel(1,0,0); gc2.AddXYTupel(1,m_dGraceMax,m_dGraceMax); gc2.WriteAgr("Fitted.agr",false); } void CReFluxObservation::CalcMinMax() { double temp; int n; m_dGraceMin = 1E20; m_dGraceMax = -1E20; for ( n = m_iTrunc / 5; n < AggrDynamic.GetSize(); n++) { temp = (a[0] * AggrDynamic[n] - b[0] * DiffusionDynamic[n]); if ( m_dGraceMin >= temp ) m_dGraceMin = temp; if ( m_dGraceMax <= temp ) m_dGraceMax = temp; } for ( n = m_iTrunc / 5; n < k_t.GetSize(); n++) { temp = -k_t.GetAt(n); if ( m_dGraceMin >= temp ) m_dGraceMin = temp; if ( m_dGraceMax <= temp ) m_dGraceMax = temp; } } CReFluxCond::CReFluxCond() { } CReFluxCond::~CReFluxCond() { } void CReFluxCond::check(CTimeStep* ts, CxIntArray* na, CxIntArray* aa) { int i; CxDVector3 Vec; if ( m_iRefNeigh == m_iObsNeigh ) return; Vec = FoldVector( ts->m_vaCoords[m_iRefNeigh] - ts->m_vaCoords[m_iObsNeigh] ); if ( Vec.GetLength() > m_dNeighDist ) { if ( na->GetSize() % 2 == 1 ) na->Add(g_iSteps); if ( aa->GetSize() % 2 == 1 ) aa->Add(g_iSteps); return; } if ( na->GetSize() % 2 == 0 ) na->Add(g_iSteps); for ( i=0; i < m_oaAggrConds.GetSize(); i++ ) { if ( ((CReFluxSubCond*)m_oaAggrConds[i])->check(ts) ) { if ( aa->GetSize() % 2 == 0 ) aa->Add(g_iSteps); return; } } if ( aa->GetSize() % 2 == 1 ) aa->Add(g_iSteps); } void CReFluxCond::Add(int moltype, int target, int number) { CReFluxSingleCond* sc; int i, i_temp, j; if ( target == 1 ) // Neighbor 1 m_iRefNeigh = number; else if ( target == 2 ) // Neighbor 2 m_iObsNeigh = number; else if ( target == 3 || target == 5 ) // Dist 1 or Angle 1 { try { sc = new CReFluxSingleCond(); } catch(...) { sc = NULL; } if (sc == NULL) NewException((double)sizeof(CReFluxSingleCond),__FILE__,__LINE__,__PRETTY_FUNCTION__); if ( target == 3 ) sc->m_iRefDist = number; if ( target == 5 ) sc->m_iRefVec = number; sc->m_iaTypes.Add(moltype); if ( target == 3 ) m_oaDistConds.Add(sc); if ( target == 5 ) m_oaAngleConds.Add(sc); } else if ( target == 4 || ( target > 5 && target < 11 ) ) // Dist 2 or Angle 2 { j = -1; i_temp = m_oaAngleConds.GetSize(); if ( target == 4 ) i_temp = m_oaDistConds.GetSize(); for ( i=0; i < i_temp; i++ ) { if ( target == 4 ) sc = (CReFluxSingleCond*)m_oaDistConds[i]; else sc = (CReFluxSingleCond*)m_oaAngleConds[i]; if ( sc->m_dAggrMinAngle != -1 ) continue; if ( j == -1 ) j = i; if ( target == 4 && i != j && sc->m_iRefDist == ((CReFluxSingleCond*)m_oaDistConds[j])->m_iRefDist ) break; if ( (target == 4 && sc->m_iObsVec != -1) || (target == 6 && sc->m_iRefVec2 != -1) || (target == 7 && sc->m_iRefVec3 != -1) || (target == 8 && sc->m_iObsVec != -1) || (target == 9 && sc->m_iObsVec2 != -1) || (target == 10 && sc->m_iObsVec3 != -1) ) { try { sc = new CReFluxSingleCond(); } catch(...) { sc = NULL; } if (sc == NULL) NewException((double)sizeof(CReFluxSingleCond),__FILE__,__LINE__,__PRETTY_FUNCTION__); if ( target == 4 ) { sc->Copy( (CReFluxSingleCond*)m_oaDistConds[i] ); m_oaDistConds.Add(sc); } else { sc->Copy( (CReFluxSingleCond*)m_oaAngleConds[i] ); m_oaAngleConds.Add(sc); } sc->m_iaTypes.RemoveAt(sc->m_iaTypes.GetSize()-1,1); } if ( target == 4 || target == 8 ) sc->m_iObsVec = number; else if ( target == 6 ) sc->m_iRefVec2 = number; else if ( target == 7 ) sc->m_iRefVec3 = number; else if ( target == 9 ) sc->m_iObsVec2 = number; else if ( target == 10 ) sc->m_iObsVec3 = number; sc->m_iaTypes.Add(moltype); } } else { eprintf("CReFluxCond::Add(): Internal error (target %d).\n",target); abort(); } } void CReFluxCond::AddArray(int moltype, int target, CxIntArray* addme) { int i; if ( target == 1 || target == 2 ) { eprintf("CReFluxCond::AddArray(): Internal error (target %d).\n",target); abort(); } for ( i=0; i < addme->GetSize(); i++ ) Add(moltype, target, (*addme)[i]); } bool CReFluxObservation::GetArray(const char* s, CxIntArray* temp, int max) { const char *p, *q; char buf[32]; temp->RemoveAll(); p = s; while ( *p != 0 ) { while ( *p == ' ' || *p == ',' ) p++; q = p; while ( isdigit(*q) ) q++; if ( q == p ) { mprintf("\n Please enter comma seperated numbers!\n"); return false; } memcpy(buf,p,q-p); buf[q-p] = 0; if ( atoi(buf) > max ) { mprintf("\n There is no option %d!\n", atoi(buf)); return false; } temp->Add(atoi(buf)-1); p = q; } return true; } bool CReFluxObservation::GetDoubleArray( const char* s, CxIntArray* temp1, CxIntArray* temp2, int max1, int max2 ) { const char *p, *q; char buf[32]; bool minus = false; temp1->RemoveAll(); temp2->RemoveAll(); p = s; while ( *p != 0 ) { while ( *p == ' ' || *p == ',' ) p++; if ( *p == '-' ) { minus = true; p++; } q = p; while ( isdigit(*q) ) q++; if ( q == p ) { mprintf("\n Please enter: x1,x2-y1,y2,y3 !\n"); return false; } memcpy(buf,p,q-p); buf[q-p] = 0; if ( ( atoi(buf) > max1 && !minus ) || ( atoi(buf) > max2 && minus ) ) { if ( !minus ) mprintf("\n There is no option %d for distances!\n", atoi(buf)); else mprintf("\n There is no option %d for distances!\n", atoi(buf)); return false; } if ( !minus ) temp1->Add(atoi(buf)-1); else temp2->Add(atoi(buf)-1); p = q; } return true; } CxString CReFluxObservation::FindType(CReFluxSingleCond* sc, int k) { CxString out; if ( sc->m_iaTypes[k] == 1 ) out = ("RM"); else if ( sc->m_iaTypes[k] == 2 ) out = ("OM"); else if ( sc->m_iaTypes[k] == 3 ) out = ("TM"); return out; } void CReFluxObservation::DumpDist() { int i; int a1, a2; CxString out, temp; for ( i=0; i < ((CReFluxCond*)m_oaCond[0])->m_oaDistConds.GetSize(); i++ ) { a1 = ((CReFluxSingleCond*)((CReFluxCond*)m_oaCond[0])->m_oaDistConds[i])->m_iRefDist; a2 = ((CReFluxSingleCond*)((CReFluxCond*)m_oaCond[0])->m_oaDistConds[i])->m_iObsVec; out.Format("%7d: %s%d (", i+1, (const char*)((CAtom*)g_oaAtoms[g_waAtomRealElement[a1]])->m_sName, g_waAtomMolNumber[a1]+1 ); out += FindType((CReFluxSingleCond*)((CReFluxCond*)m_oaCond[0])->m_oaDistConds[i], 0); temp.Format(") - %s%d (", (const char*)((CAtom*)g_oaAtoms[g_waAtomRealElement[a2]])->m_sName, g_waAtomMolNumber[a2]+1 ); out += temp; out += FindType((CReFluxSingleCond*)((CReFluxCond*)m_oaCond[0])->m_oaDistConds[i], 1); out += (")\n"); out.Dump(); } } void CReFluxObservation::DumpAngle() { int i; int a1, a2, a3, b1, b2, b3; CxString out, temp; for ( i=0; i < ((CReFluxCond*)m_oaCond[0])->m_oaAngleConds.GetSize(); i++ ) { a1 = ((CReFluxSingleCond*)((CReFluxCond*)m_oaCond[0])->m_oaAngleConds[i])->m_iRefVec; a2 = ((CReFluxSingleCond*)((CReFluxCond*)m_oaCond[0])->m_oaAngleConds[i])->m_iRefVec2; a3 = ((CReFluxSingleCond*)((CReFluxCond*)m_oaCond[0])->m_oaAngleConds[i])->m_iRefVec3; b1 = ((CReFluxSingleCond*)((CReFluxCond*)m_oaCond[0])->m_oaAngleConds[i])->m_iObsVec; b2 = ((CReFluxSingleCond*)((CReFluxCond*)m_oaCond[0])->m_oaAngleConds[i])->m_iObsVec2; b3 = ((CReFluxSingleCond*)((CReFluxCond*)m_oaCond[0])->m_oaAngleConds[i])->m_iObsVec3; out.Format("%7d: ", i+1); if ( a3 == -1 ) out += (" vec["); else out += ("plane["); temp.Format("%s%d(", (const char*)((CAtom*)g_oaAtoms[g_waAtomRealElement[a1]])->m_sName, g_waAtomMolNumber[a1]+1 ); out += temp; out += FindType((CReFluxSingleCond*)((CReFluxCond*)m_oaCond[0])->m_oaAngleConds[i], 0); temp.Format(")-%s%d(", (const char*)((CAtom*)g_oaAtoms[g_waAtomRealElement[a2]])->m_sName, g_waAtomMolNumber[a2]+1 ); out += temp; out += FindType((CReFluxSingleCond*)((CReFluxCond*)m_oaCond[0])->m_oaAngleConds[i], 1); if ( a3 != -1 ) { temp.Format(")-%s%d(", (const char*)((CAtom*)g_oaAtoms[g_waAtomRealElement[a3]])->m_sName, g_waAtomMolNumber[a3]+1 ); out += temp; out += FindType((CReFluxSingleCond*)((CReFluxCond*)m_oaCond[0])->m_oaAngleConds[i], 2); } if ( b3 == -1 ) out += (")] - vec["); else out += (")] - plane["); temp.Format("%s%d(", (const char*)((CAtom*)g_oaAtoms[g_waAtomRealElement[b1]])->m_sName, g_waAtomMolNumber[b1]+1 ); out += temp; out += FindType((CReFluxSingleCond*)((CReFluxCond*)m_oaCond[0])->m_oaAngleConds[i], 3); temp.Format(")-%s%d(", (const char*)((CAtom*)g_oaAtoms[g_waAtomRealElement[b2]])->m_sName, g_waAtomMolNumber[b2]+1 ); out += temp; out += FindType((CReFluxSingleCond*)((CReFluxCond*)m_oaCond[0])->m_oaAngleConds[i], 4); if ( b3 != -1 ) { temp.Format(")-%s%d(", (const char*)((CAtom*)g_oaAtoms[g_waAtomRealElement[b3]])->m_sName, g_waAtomMolNumber[b3]+1 ); out += temp; out += FindType((CReFluxSingleCond*)((CReFluxCond*)m_oaCond[0])->m_oaAngleConds[i], 5); } out += (")]\n"); out.Dump(); } } void CReFluxObservation::DumpAll() { int i, j; int a1, a2, a3, b1, b2, b3; int i_temp, j_max, j_temp; CxString out, temp; for ( i=0; i < ((CReFluxCond*)m_oaCond[0])->m_oaAggrConds.GetSize(); i++ ) { j_max = ((CReFluxSubCond*)((CReFluxCond*)m_oaCond[0])->m_oaAggrConds[i])->m_iaDistConds.GetSize(); for ( j=0; j < j_max; j++ ) { i_temp = ((CReFluxSubCond*)((CReFluxCond*)m_oaCond[0])->m_oaAggrConds[i])->m_iaDistConds[j]; a1 = ((CReFluxSingleCond*)((CReFluxCond*)m_oaCond[0])->m_oaDistConds[i_temp])->m_iRefDist; a2 = ((CReFluxSingleCond*)((CReFluxCond*)m_oaCond[0])->m_oaDistConds[i_temp])->m_iObsVec; if ( j == 0 ) out.Format("%7d: ", i+1); else out = (" + "); temp.Format("Distance: %s%d (", (const char*)((CAtom*)g_oaAtoms[g_waAtomRealElement[a1]])->m_sName, g_waAtomMolNumber[a1]+1 ); out += temp; out += FindType((CReFluxSingleCond*)((CReFluxCond*)m_oaCond[0])->m_oaDistConds[i], 0); temp.Format(") - %s%d (", (const char*)((CAtom*)g_oaAtoms[g_waAtomRealElement[a2]])->m_sName, g_waAtomMolNumber[a2]+1 ); out += temp; out += FindType((CReFluxSingleCond*)((CReFluxCond*)m_oaCond[0])->m_oaDistConds[i], 1); temp = (")\n"); out += temp; out.Dump(); } j_temp = j_max; for ( j_max += ((CReFluxSubCond*)((CReFluxCond*)m_oaCond[0])->m_oaAggrConds[i])->m_iaAngleConds.GetSize(); j < j_max; j++ ) { i_temp = ((CReFluxSubCond*)((CReFluxCond*)m_oaCond[0])->m_oaAggrConds[i])->m_iaAngleConds[j-j_temp]; a1 = ((CReFluxSingleCond*)((CReFluxCond*)m_oaCond[0])->m_oaAngleConds[i_temp])->m_iRefVec; a2 = ((CReFluxSingleCond*)((CReFluxCond*)m_oaCond[0])->m_oaAngleConds[i_temp])->m_iRefVec2; a3 = ((CReFluxSingleCond*)((CReFluxCond*)m_oaCond[0])->m_oaAngleConds[i_temp])->m_iRefVec3; b1 = ((CReFluxSingleCond*)((CReFluxCond*)m_oaCond[0])->m_oaAngleConds[i_temp])->m_iObsVec; b2 = ((CReFluxSingleCond*)((CReFluxCond*)m_oaCond[0])->m_oaAngleConds[i_temp])->m_iObsVec2; b3 = ((CReFluxSingleCond*)((CReFluxCond*)m_oaCond[0])->m_oaAngleConds[i_temp])->m_iObsVec3; if ( j == 0 ) out.Format("%7d: ", i+1); else out = (" + "); out += ("Angle: "); if ( a3 == -1 ) out += (" vec["); else out += ("plane["); temp.Format("%s%d(", (const char*)((CAtom*)g_oaAtoms[g_waAtomRealElement[a1]])->m_sName, g_waAtomMolNumber[a1]+1 ); out += temp; out += FindType((CReFluxSingleCond*)((CReFluxCond*)m_oaCond[0])->m_oaAngleConds[i_temp], 0); temp.Format(")-%s%d(", (const char*)((CAtom*)g_oaAtoms[g_waAtomRealElement[a2]])->m_sName, g_waAtomMolNumber[a2]+1 ); out += temp; out += FindType((CReFluxSingleCond*)((CReFluxCond*)m_oaCond[0])->m_oaAngleConds[i_temp], 1); if ( a3 != -1 ) { temp.Format(")-%s%d(", (const char*)((CAtom*)g_oaAtoms[g_waAtomRealElement[a3]])->m_sName, g_waAtomMolNumber[a3]+1 ); out += temp; out += FindType((CReFluxSingleCond*)((CReFluxCond*)m_oaCond[0])->m_oaAngleConds[i_temp], 2); } if ( b3 == -1 ) out += (")] - vec["); else out += (")] - plane["); temp.Format("%s%d(", (const char*)((CAtom*)g_oaAtoms[g_waAtomRealElement[b1]])->m_sName, g_waAtomMolNumber[b1]+1 ); out += temp; out += FindType((CReFluxSingleCond*)((CReFluxCond*)m_oaCond[0])->m_oaAngleConds[i_temp], 3); temp.Format(")-%s%d(", (const char*)((CAtom*)g_oaAtoms[g_waAtomRealElement[b2]])->m_sName, g_waAtomMolNumber[b2]+1 ); out += temp; out += FindType((CReFluxSingleCond*)((CReFluxCond*)m_oaCond[0])->m_oaAngleConds[i_temp], 4); if ( b3 != -1 ) { temp.Format(")-%s%d(", (const char*)((CAtom*)g_oaAtoms[g_waAtomRealElement[b3]])->m_sName, g_waAtomMolNumber[b3]+1 ); out += temp; out += FindType((CReFluxSingleCond*)((CReFluxCond*)m_oaCond[0])->m_oaAngleConds[i_temp], 5); } out += (")]\n"); out.Dump(); } } } void CReFluxObservation::SortDist() { if ( ((CReFluxCond*)m_oaCond[0])->m_oaDistConds.GetSize() == 0 ) return; int i, j; CxString buf; CxIntArray temp; CReFluxSubCond* subcond; mprintf("\n Found the following distance couples:\n"); DumpDist(); while ( true ) { mprintf("\n Which couples should be ignored (comma seperated numbers) [none]?"); inpprintf("! Which couples should be ignored (comma seperated numbers) [none]?\n"); myget(&buf); if ( strlen(buf) != 0 ) if ( !GetArray(buf, &temp, ((CReFluxCond*)m_oaCond[0])->m_oaDistConds.GetSize()) ) continue; break; } if ( temp.GetSize() != 0 ) for ( i=((CReFluxCond*)m_oaCond[0])->m_oaDistConds.GetSize()-1; i != -1; i-- ) if ( temp.Contains(i) ) for ( j=0; j < m_oaCond.GetSize(); j++ ) ((CReFluxCond*)m_oaCond[j])->m_oaDistConds.RemoveAt(i,1); mprintf("\n Left are the following distance couples:\n"); DumpDist(); mprintf("\n It is possible to define groups of criteria which have to be fulfilled simultaneously.\n"); mprintf(" You have now the chance to define one or more groups.\n"); while ( true ) { mprintf("\n Which criteria should be paired (comma seperated numbers) [end]?"); inpprintf("! Which criteria should be paired (comma seperated numbers) [end]?\n"); myget(&buf); if ( strlen(buf) == 0 ) break; if ( !GetArray(buf, &temp, ((CReFluxCond*)m_oaCond[0])->m_oaDistConds.GetSize()) ) continue; for ( i=0; i < m_oaCond.GetSize(); i++ ) { try { subcond = new CReFluxSubCond(); } catch(...) { subcond = NULL; } if (subcond == NULL) NewException((double)sizeof(CReFluxSubCond),__FILE__,__LINE__,__PRETTY_FUNCTION__); subcond->m_iaDistConds.CopyFrom(&temp); subcond->m_oaDistConds = &((CReFluxCond*)m_oaCond[i])->m_oaDistConds; subcond->m_oaAngleConds = &((CReFluxCond*)m_oaCond[i])->m_oaAngleConds; ((CReFluxCond*)m_oaCond[i])->m_oaAggrConds.Add(subcond); } } for ( j=0; j < ((CReFluxCond*)m_oaCond[0])->m_oaDistConds.GetSize(); j++ ) { for ( i=0; i < ((CReFluxCond*)m_oaCond[0])->m_oaAggrConds.GetSize(); i++ ) { if ( ((CReFluxSubCond*)((CReFluxCond*)m_oaCond[0])->m_oaAggrConds[i])->m_iaDistConds.Contains(j) ) { i = -1; break; } } if ( i == -1 ) continue; for ( i=0; i < m_oaCond.GetSize(); i++ ) { try { subcond = new CReFluxSubCond(); } catch(...) { subcond = NULL; } if (subcond == NULL) NewException((double)sizeof(CReFluxSubCond),__FILE__,__LINE__,__PRETTY_FUNCTION__); subcond->m_iaDistConds.Add(j); subcond->m_oaDistConds = &((CReFluxCond*)m_oaCond[i])->m_oaDistConds; subcond->m_oaAngleConds = &((CReFluxCond*)m_oaCond[i])->m_oaAngleConds; ((CReFluxCond*)m_oaCond[i])->m_oaAggrConds.Add(subcond); } } } void CReFluxObservation::SortAngle() { int i, j, n, m; CxString buf; CxIntArray temp, temp2; CReFluxSubCond* subcond; if ( ((CReFluxCond*)m_oaCond[0])->m_oaAngleConds.GetSize() == 0 ) return; mprintf("\n Found the following angle definitions:\n"); DumpAngle(); while ( true ) { mprintf("\n Which definitions should be ignored (comma seperated numbers) [none]?"); inpprintf("! Which definitions should be ignored (comma seperated numbers) [none]?\n"); myget(&buf); if ( strlen(buf) != 0 ) if ( !GetArray(buf, &temp, ((CReFluxCond*)m_oaCond[0])->m_oaAngleConds.GetSize()) ) continue; break; } if ( temp.GetSize() != 0 ) for ( i=((CReFluxCond*)m_oaCond[0])->m_oaAngleConds.GetSize()-1; i != -1; i-- ) if ( temp.Contains(i) ) for ( j=0; j < m_oaCond.GetSize(); j++ ) ((CReFluxCond*)m_oaCond[j])->m_oaAngleConds.RemoveAt(i,1); mprintf("\n Left are the following angle definitions ...\n"); DumpAngle(); if ( ((CReFluxCond*)m_oaCond[0])->m_oaAggrConds.GetSize() > 0 ) { mprintf("\n ... and the following distance criteria:\n"); DumpAll(); } mprintf("\n It is possible to define groups of criteria which have to be fulfilled simultaneously.\n"); mprintf(" You have now the chance to define one or more groups.\n"); if ( ((CReFluxCond*)m_oaCond[0])->m_oaAggrConds.GetSize() > 0 ) { mprintf(" Please define the groups like this: x1,x2-y1,y2,y3 (x=distances, y=angles).\n"); mprintf(" Or, if a group only contains angles: -y1,y2\n"); } else mprintf(" Please define the groups one by one as comma separated numbers.\n"); mprintf(" Just press enter to end.\n"); n = ((CReFluxCond*)m_oaCond[0])->m_oaAggrConds.GetSize(); m = ((CReFluxCond*)m_oaCond[0])->m_oaAngleConds.GetSize(); while ( true ) { inpprintf("! Which criteria should be paired [end]?\n"); myget(&buf); if ( strlen(buf) == 0 ) break; if ( n > 0 ) if ( !GetDoubleArray( buf, &temp, &temp2, n, m ) ) continue; if ( m == 0 ) if ( !GetArray( buf, &temp2, m ) ) continue; for ( i=0; i < m_oaCond.GetSize(); i++ ) { try { subcond = new CReFluxSubCond(); } catch(...) { subcond = NULL; } if (subcond == NULL) NewException((double)sizeof(CReFluxSubCond),__FILE__,__LINE__,__PRETTY_FUNCTION__); for ( j=0; j < temp.GetSize(); j++ ) subcond->m_iaDistConds.Append( &((CReFluxSubCond*)((CReFluxCond*)m_oaCond[i])->m_oaAggrConds[temp[j]])->m_iaDistConds ); subcond->m_iaAngleConds.CopyFrom(&temp2); subcond->m_oaDistConds = &((CReFluxCond*)m_oaCond[i])->m_oaDistConds; subcond->m_oaAngleConds = &((CReFluxCond*)m_oaCond[i])->m_oaAngleConds; ((CReFluxCond*)m_oaCond[i])->m_oaAggrConds.Add(subcond); } } for ( j=0; j < n; j++ ) { for ( i=n; i < ((CReFluxCond*)m_oaCond[0])->m_oaAggrConds.GetSize(); i++ ) { if ( ((CReFluxSubCond*)((CReFluxCond*)m_oaCond[0])->m_oaAggrConds[i])->m_iaDistConds.Contains(((CReFluxSubCond*)((CReFluxCond*)m_oaCond[0])->m_oaAggrConds[j])->m_iaDistConds[0]) ) { i = -1; break; } } if ( i != -1 ) { for ( i=0; i < m_oaCond.GetSize(); i++ ) { try { subcond = new CReFluxSubCond(); } catch(...) { subcond = NULL; } if (subcond == NULL) NewException((double)sizeof(CReFluxSubCond),__FILE__,__LINE__,__PRETTY_FUNCTION__); subcond->m_iaDistConds.CopyFrom( &((CReFluxSubCond*)((CReFluxCond*)m_oaCond[i])->m_oaAggrConds[j])->m_iaDistConds ); subcond->m_oaDistConds = &((CReFluxCond*)m_oaCond[i])->m_oaDistConds; subcond->m_oaAngleConds = &((CReFluxCond*)m_oaCond[i])->m_oaAngleConds; ((CReFluxCond*)m_oaCond[i])->m_oaAggrConds.Add(subcond); } } } for ( j=0; j < m; j++ ) { for ( i=n; i < ((CReFluxCond*)m_oaCond[0])->m_oaAggrConds.GetSize(); i++ ) { if ( ((CReFluxSubCond*)((CReFluxCond*)m_oaCond[0])->m_oaAggrConds[i])->m_iaAngleConds.Contains(j) ) { i = -1; break; } } if ( i != -1 ) { for ( i=0; i < m_oaCond.GetSize(); i++ ) { try { subcond = new CReFluxSubCond(); } catch(...) { subcond = NULL; } if (subcond == NULL) NewException((double)sizeof(CReFluxSubCond),__FILE__,__LINE__,__PRETTY_FUNCTION__); subcond->m_iaAngleConds.Add(j); subcond->m_oaDistConds = &((CReFluxCond*)m_oaCond[i])->m_oaDistConds; subcond->m_oaAngleConds = &((CReFluxCond*)m_oaCond[i])->m_oaAngleConds; ((CReFluxCond*)m_oaCond[i])->m_oaAggrConds.Add(subcond); } } } for ( i=0; i < m_oaCond.GetSize(); i++ ) ((CReFluxCond*)m_oaCond[i])->m_oaAggrConds.RemoveAt(0,n); } void CReFluxObservation::SortFinal() { int i, j; CxString buf; CxIntArray temp; if ( ((CReFluxCond*)m_oaCond[0])->m_oaAggrConds.GetSize() == 0 ) return; mprintf("\n Your choice result in the following aggregation criteria:\n"); DumpAll(); mprintf("\n If some of these criteria are incorrect it is now possible to discard them."); while ( true ) { mprintf("\n Which criteria should be discarded (comma seperated numbers) [none]?"); inpprintf("! Which criteria should be discarded (comma seperated numbers) [none]?\n"); myget(&buf); if ( strlen(buf) != 0 ) if ( !GetArray(buf, &temp, ((CReFluxCond*)m_oaCond[0])->m_oaAggrConds.GetSize()) ) continue; break; } if ( temp.GetSize() != 0 ) for ( i=((CReFluxCond*)m_oaCond[0])->m_oaAggrConds.GetSize()-1; i != -1; i-- ) if ( temp.Contains(i) ) for ( j=0; j < m_oaCond.GetSize(); j++ ) ((CReFluxCond*)m_oaCond[j])->m_oaAggrConds.RemoveAt(i,1); } CReFluxSubCond::CReFluxSubCond() { } bool CReFluxSubCond::check(CTimeStep* ts) { int i, a1, a2, a3; CxDVector3 Vec, Vec2, Vec3; double cos; for ( i=0; i < m_iaDistConds.GetSize(); i++ ) { a1 = ((CReFluxSingleCond*)(*m_oaDistConds)[i])->m_iRefDist; a2 = ((CReFluxSingleCond*)(*m_oaDistConds)[i])->m_iObsVec; Vec = FoldVector( ts->m_vaCoords[a1] - ts->m_vaCoords[a2] ); if ( Vec.GetLength() > ((CReFluxSingleCond*)(*m_oaDistConds)[i])->m_dAggrMinAngle ) return false; } for ( i=0; i < m_iaAngleConds.GetSize(); i++ ) { a1 = ((CReFluxSingleCond*)(*m_oaAngleConds)[i])->m_iRefVec; a2 = ((CReFluxSingleCond*)(*m_oaAngleConds)[i])->m_iRefVec2; a3 = ((CReFluxSingleCond*)(*m_oaAngleConds)[i])->m_iRefVec3; Vec = FoldVector( ts->m_vaCoords[a1] - ts->m_vaCoords[a2] ); if ( a3 != -1 ) { Vec3 = FoldVector( ts->m_vaCoords[a3] - ts->m_vaCoords[a2] ); Vec = CrossP(Vec, Vec3); } Vec.Normalize(); a1 = ((CReFluxSingleCond*)(*m_oaAngleConds)[i])->m_iObsVec; a2 = ((CReFluxSingleCond*)(*m_oaAngleConds)[i])->m_iObsVec2; a3 = ((CReFluxSingleCond*)(*m_oaAngleConds)[i])->m_iObsVec3; Vec2 = FoldVector( ts->m_vaCoords[a1] - ts->m_vaCoords[a2] ); if ( a3 != -1 ) { Vec3 = FoldVector( ts->m_vaCoords[a3] - ts->m_vaCoords[a2] ); Vec2 = CrossP(Vec2, Vec3); } Vec2.Normalize(); cos = DotP( Vec, Vec2 ); if ( ( cos > ((CReFluxSingleCond*)(*m_oaAngleConds)[i])->m_dAggrMinAngle ) || ( cos < ((CReFluxSingleCond*)(*m_oaAngleConds)[i])->m_dAggrMaxAngle ) ) return false; } return true; } CReFluxSubCond::~CReFluxSubCond() { } CReFluxSingleCond::CReFluxSingleCond() { m_iRefDist = -1; // Ref for Dist m_iRefVec = -1; // Reference vectors base for angle crit m_iRefVec2 = -1; // Reference vectors tipp m_iRefVec3 = -1; // only used if Vectors are defined by plane m_iObsVec = -1; // Observed vectors base for angle crit of Obs for Dist m_iObsVec2 = -1; // Observed vectors tipp m_iObsVec3 = -1; // only used if Vectors are defined by plane m_dAggrMinAngle = -1.0; // Angle for AngleCrit of Dist for Dist m_dAggrMaxAngle = -1.0; // Angle for AngleCrit } CReFluxSingleCond::~CReFluxSingleCond() { } void CReFluxSingleCond::Copy(CReFluxSingleCond* sc) { m_iRefDist = sc->m_iRefDist; m_iRefVec = sc->m_iRefVec; m_iRefVec2 = sc->m_iRefVec2; m_iRefVec3 = sc->m_iRefVec3; m_iObsVec = sc->m_iObsVec; m_iObsVec2 = sc->m_iObsVec2; m_iObsVec3 = sc->m_iObsVec3; m_dAggrMinAngle = sc->m_dAggrMinAngle; m_dAggrMaxAngle = sc->m_dAggrMaxAngle; m_iaTypes.CopyFrom(&sc->m_iaTypes); } travis-src-190101/src/reflux.h0100777000000000000000000001061013412725663013116 0ustar00/***************************************************************************** TRAVIS - Trajectory Analyzer and Visualizer http://www.travis-analyzer.de/ Copyright (c) 2009-2019 Martin Brehm 2012-2019 Martin Thomas 2016-2019 Sascha Gehrke This file was written by Sascha Gehrke. --------------------------------------------------------------------------- This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . *****************************************************************************/ #ifndef REFLUX_H #define REFLUX_H // This must always be the first include directive #include "config.h" #include "moltools.h" bool gatherReFlux(); bool initializeReFlux(); bool processReFlux(CTimeStep* ts); bool finalizeReFlux(); class CReFluxSingleCond: public CxObject { public: CReFluxSingleCond(); ~CReFluxSingleCond(); CxIntArray m_iaTypes; // Molecule types int m_iRefDist; // Ref for Dist int m_iRefVec; // Reference vectors base for angle crit int m_iRefVec2; // Reference vectors tipp int m_iRefVec3; // only used if Vectors are defined by plane int m_iObsVec; // Observed vectors base for angle crit of Obs for Dist int m_iObsVec2; // Observed vectors tipp int m_iObsVec3; // only used if Vectors are defined by plane double m_dAggrMinAngle; // Angle for AngleCrit of Dist for Dist double m_dAggrMaxAngle; // Angle for AngleCrit void Copy(CReFluxSingleCond*); }; class CReFluxSubCond: public CxObject { public: CReFluxSubCond(); ~CReFluxSubCond(); CxIntArray m_iaDistConds; // all of these must be fulfilled simultaneously! CxIntArray m_iaAngleConds; // all of these must be fulfilled simultaneously! CxObArray* m_oaDistConds; CxObArray* m_oaAngleConds; bool check(CTimeStep*); // checks fulfillment }; class CReFluxCond: public CxObject // Condition for each pair { public: CReFluxCond(); ~CReFluxCond(); int m_iRefNeigh; // Reference for neighbor criterion int m_iObsNeigh; // Observed for neighbor criterion double m_dNeighDist; // Distance for Neighbor CxObArray m_oaAggrConds; // at least one of these must be fulfilled CxObArray m_oaDistConds; // single conds (the AggrConds link on them) CxObArray m_oaAngleConds; // single conds (the AggrConds link on them) void check(CTimeStep*,CxIntArray*,CxIntArray*); // checks conditions for fulfillment void Add(int, int, int); void AddArray(int, int, CxIntArray*); }; class CReFluxObservation: public CObservation { public: CReFluxObservation(); ~CReFluxObservation(); CxObArray m_oaCond; // Contains the conditions for the possible pairs CxObArray m_oaNeigh; // Contains the switching timesteps CxObArray m_oaAggr; CxDoubleArray AggrDynamic; // Final Datasets after processing CxDoubleArray DiffusionDynamic; CxDoubleArray k_t; // Numerical derivation of BondDynamic CxDoubleArray a; CxDoubleArray b; int m_iShowMol3; bool m_bRefVecPlane; // defined by plane? bool m_bObsVecPlane; // defined by plane? CxIntArray m_iaAngleMols; CxIntArray tempRef, tempObs, tempRef2, tempObs2, tempRef3, tempObs3; int m_iDepth, m_iTrunc; double m_dNeighDist, m_dAggrDist; double m_dGraceMin, m_dGraceMax; void initialize(); void process(CTimeStep* ts); void finalize(); bool checkAtomChoice(const char*i, int, int); bool includeAtom(int, int, int, int); bool GetArray(const char*, CxIntArray*, int); bool GetDoubleArray( const char*, CxIntArray*, CxIntArray*, int, int ); CxString FindType(CReFluxSingleCond*, int); void DumpDist(); // Dumps the Conds void DumpAngle(); // Dumps the Conds void DumpAll(); // Dumps the Conds void SortDist(); // Sorts the Conds void SortAngle(); // Sorts the Conds void SortFinal(); // Sorts the Conds void RestoreFunction(CxIntArray*, CxDoubleArray*); void CalcMinMax(); void WriteOutput(); private: }; #endif travis-src-190101/src/region.cpp0100777000000000000000000001343413412725633013433 0ustar00/***************************************************************************** TRAVIS - Trajectory Analyzer and Visualizer http://www.travis-analyzer.de/ Copyright (c) 2009-2019 Martin Brehm 2012-2019 Martin Thomas 2016-2019 Sascha Gehrke This file was written by Martin Thomas. --------------------------------------------------------------------------- This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . *****************************************************************************/ // This must always be the first include directive #include "config.h" #include "region.h" #include "globalvar.h" #include "maintools.h" #include "tools.h" #include "xobarray.h" #include "xdvector3.h" const char *GetRevisionInfo_region(unsigned int len) { static char buf[256]; GET_REVISION_INFO( buf, len ); return buf; } const char *GetSourceVersion_region() { static char buf[256]; GET_SOURCE_VERSION( buf ); return buf; } static CxObArray g_regions; CRegion::CRegion() { // char buf[256]; CxString buf; mprintf(" You have to define an orthorhombic part of the simulation box\n by entering minimum and maximum values along the x, y, and z axes.\n\n"); _xmin = AskFloat(" Minimum x value in pm [0.0] ", 0.0); _xmax = AskFloat(" Maximum x value in pm [%.1f] ", g_fBoxX, g_fBoxX); _ymin = AskFloat(" Minimum y value in pm [0.0] ", 0.0); _ymax = AskFloat(" Maximum y value in pm [%.1f] ", g_fBoxY, g_fBoxY); _zmin = AskFloat(" Minimum z value in pm [0.0] ", 0.0); _zmax = AskFloat(" Maximum z value in pm [%.1f] ", g_fBoxZ, g_fBoxZ); try { _centerAtomTypes = new int[g_oaMolecules.GetSize()]; } catch(...) { _centerAtomTypes = NULL; } if(_centerAtomTypes == NULL) NewException((double)g_oaMolecules.GetSize()*sizeof(int), __FILE__, __LINE__, __PRETTY_FUNCTION__); try { _centerAtomRealTypes = new int[g_oaMolecules.GetSize()]; } catch(...) { _centerAtomRealTypes = NULL; } if(_centerAtomRealTypes == NULL) NewException((double)g_oaMolecules.GetSize()*sizeof(int), __FILE__, __LINE__, __PRETTY_FUNCTION__); try { _centerAtoms = new int[g_oaMolecules.GetSize()]; } catch(...) { _centerAtoms = NULL; } if(_centerAtoms == NULL) NewException((double)g_oaMolecules.GetSize()*sizeof(int), __FILE__, __LINE__, __PRETTY_FUNCTION__); int i; mprintf("\n By default, the center of mass will be used to decide if a molecule is within the region.\n"); if(AskYesNo(" Change this behavior (y/n)? [no] ", false)) { for(i = 0; i < g_oaMolecules.GetSize(); i++) { while(true) { mprintf(" Which atom to use for %s (e.g. C1)? [#2] ", ((CMolecule*)g_oaMolecules[i])->m_sName); inpprintf("! Which atom to use for %s (e.g. C1)? [#2]\n", ((CMolecule*)g_oaMolecules[i])->m_sName); myget(&buf); if(strlen(buf) == 0) { if(!ParseAtom("#2", i, _centerAtomTypes[i], _centerAtomRealTypes[i], _centerAtoms[i])) { eprintf("CRegion::CRegion(): Internal error (1).\n"); abort(); } } else { if(ParseAtom(buf, i, _centerAtomTypes[i], _centerAtomRealTypes[i], _centerAtoms[i])) break; } } } } else { for(i = 0; i < g_oaMolecules.GetSize(); i++) { if(!ParseAtom("#2", i, _centerAtomTypes[i], _centerAtomRealTypes[i], _centerAtoms[i])) { eprintf("CRegion::CRegion(): Internal error (2).\n"); abort(); } } } } CRegion::~CRegion() { delete[] _centerAtomTypes; delete[] _centerAtomRealTypes; delete[] _centerAtoms; } bool CRegion::isInRegion(const CxDVector3 &vec) { if((vec[0] > _xmin) && (vec[0] < _xmax) && (vec[1] > _ymin) && (vec[1] < _ymax) && (vec[2] > _zmin) && (vec[2] < _zmax)) return true; return false; } bool gatherRegionAnalysis() { mprintf("\n"); mprintf(YELLOW, ">>> Region Definition >>>\n\n"); mprintf(" You can specify as many regions as you want.\n All parts of the simulation box not contained in these regions will be region 1.\n\n"); while(true) { mprintf(YELLOW, ">>> Region %d >>>\n\n", g_regions.GetSize() + 2); CRegion *region; try { region = new CRegion(); } catch(...) { region = NULL; } if(region == NULL) NewException((double)sizeof(CRegion), __FILE__, __LINE__, __PRETTY_FUNCTION__); g_regions.Add(region); mprintf(YELLOW, "\n<<< End Region %d <<<\n\n", g_regions.GetSize() + 1); if(!AskYesNo(" Add another region (y/n)? [no] ", false)) break; mprintf("\n"); } mprintf(YELLOW, "\n<<< End Region Definition <<<\n\n"); return true; } void processRegionAnalysis(CTimeStep *ts) { int i, j; for(i = 0; i < g_iaSMRegion.GetSize(); i++) { g_iaSMRegion[i] = 1; } for(i = 0; i < g_regions.GetSize(); i++) { CRegion *region = (CRegion *)g_regions[i]; for(j = 0; j < g_oaSingleMolecules.GetSize(); j++) { CSingleMolecule *sm = (CSingleMolecule *)g_oaSingleMolecules[j]; CxDVector3 position = ts->m_vaCoords[((CxIntArray *)sm->m_oaAtomOffset[region->centerAtomType(sm->m_iMolType)])->GetAt(region->centerAtom(sm->m_iMolType))]; if(region->isInRegion(position)) g_iaSMRegion[j] = i + 2; } } } void finalizeRegionAnalysis() { int i; for(i = 0; i < g_regions.GetSize(); i++) { delete g_regions[i]; } g_regions.RemoveAll(); } travis-src-190101/src/region.h0100777000000000000000000000367613412725652013110 0ustar00/***************************************************************************** TRAVIS - Trajectory Analyzer and Visualizer http://www.travis-analyzer.de/ Copyright (c) 2009-2019 Martin Brehm 2012-2019 Martin Thomas 2016-2019 Sascha Gehrke This file was written by Martin Thomas. --------------------------------------------------------------------------- This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . *****************************************************************************/ #ifndef REGION_H #define REGION_H // This must always be the first include directive #include "config.h" #include "xobject.h" class CTimeStep; class CxDVector3; class CRegion: public CxObject { public: CRegion(); ~CRegion(); int centerAtomType(int index) const { return _centerAtomTypes[index]; } int centerAtomRealType(int index) const { return _centerAtomRealTypes[index]; } int centerAtom(int index) const { return _centerAtoms[index]; } bool isInRegion(const CxDVector3 &vector); private: double _xmin; double _xmax; double _ymin; double _ymax; double _zmin; double _zmax; int *_centerAtomTypes; int *_centerAtomRealTypes; int *_centerAtoms; }; bool gatherRegionAnalysis(); void processRegionAnalysis(CTimeStep *ts); void finalizeRegionAnalysis(); #endif travis-src-190101/src/reordyn.cpp0100777000000000000000000012226713412725624013637 0ustar00/***************************************************************************** TRAVIS - Trajectory Analyzer and Visualizer http://www.travis-analyzer.de/ Copyright (c) 2009-2019 Martin Brehm 2012-2019 Martin Thomas 2016-2019 Sascha Gehrke This file was written by Martin Brehm. --------------------------------------------------------------------------- This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . *****************************************************************************/ // This must always be the first include directive #include "config.h" #include "reordyn.h" #include "travis.h" #include "maintools.h" const char *GetRevisionInfo_reordyn(unsigned int len) { static char buf[256]; GET_REVISION_INFO( buf, len ); return buf; } const char *GetSourceVersion_reordyn() { static char buf[256]; GET_SOURCE_VERSION( buf ); return buf; } CReorDyn::CReorDyn() { m_iShowMol = -1; m_bLifetimeSpectrum = false; m_bLegendre2 = false; m_oaCache.SetName("CReorDyn::m_oaCache"); m_oaVectors.SetName("CReorDyn::m_oaVectors"); m_oaLTSpectra.SetName("CReorDyn::m_oaLTSpectra"); } CReorDyn::~CReorDyn() { } void CReorDyn::Parse() { BTIN; // char buf[256]; CxString buf; int z2, ti; CAtomGroup *ag; double tf; CFFT tfft; try { m_pRDyn = new CDF(); } catch(...) { m_pRDyn = NULL; } if (m_pRDyn == NULL) NewException((double)sizeof(CDF),__FILE__,__LINE__,__PRETTY_FUNCTION__); m_pRDyn->m_bLeft = true; m_bCrossCor = false; mprintf(YELLOW,"\n>>> Vector Reorientation Dynamics >>>\n\n"); mprintf(" All atoms will be taken from the OM %s.\n\n",((CMolecule*)g_oaMolecules[m_iShowMol])->m_sName); m_iVecType = AskRangeInteger(" Should the vector depict position (1), dipole (2), velocity (3) or force (4)? [1] ",1,4,1) - 1; mprintf("\n"); z2 = 0; m_iCombinations = 0; m_iMolecules = ((CMolecule*)g_oaMolecules[m_iShowMol])->m_laSingleMolIndex.GetSize(); ti = 1; if (m_iVecType == 0) // Position { m_bOrtho = (AskRangeInteger(" Should the vector connect 2 points (0) or stand perpendicular to 3 points (1)? [0] ",0,1,0) != 0); do { ti = 1; if (z2 != 0) mprintf("\n %d. vector\n\n",z2+1); if (m_bOrtho) { _ax1: mprintf(" Please enter the atom(s) at the base point (e.g. C7): "); inpprintf("! Please enter the atom(s) at the base point (e.g. C7):\n"); myget(&buf); try { ag = new CAtomGroup(); } catch(...) { ag = NULL; } if (ag == NULL) NewException((double)sizeof(CAtomGroup),__FILE__,__LINE__,__PRETTY_FUNCTION__); if (!ag->ParseAtoms((CMolecule*)g_oaMolecules[m_iShowMol],buf)) { eprintf("Invalid input.\n"); inpprintf("! Invalid input.\n"); goto _ax1; } m_oaVectors.Add(ag); ti *= ag->m_iAtomGes; _ax2: mprintf(" Please enter the 2nd atom(s) of the normal plane (e.g. C7): "); inpprintf("! Please enter the 2nd atom(s) of the normal plane (e.g. C7):\n"); myget(&buf); try { ag = new CAtomGroup(); } catch(...) { ag = NULL; } if (ag == NULL) NewException((double)sizeof(CAtomGroup),__FILE__,__LINE__,__PRETTY_FUNCTION__); if (!ag->ParseAtoms((CMolecule*)g_oaMolecules[m_iShowMol],buf)) { eprintf("Invalid input.\n"); inpprintf("! Invalid input.\n"); goto _ax2; } m_oaVectors.Add(ag); ti *= ag->m_iAtomGes; _ax3: mprintf(" Please enter the 3rd atom(s) of the normal plane (e.g. C7): "); inpprintf("! Please enter the 3rd atom(s) of the normal plane (e.g. C7):\n"); myget(&buf); try { ag = new CAtomGroup(); } catch(...) { ag = NULL; } if (ag == NULL) NewException((double)sizeof(CAtomGroup),__FILE__,__LINE__,__PRETTY_FUNCTION__); if (!ag->ParseAtoms((CMolecule*)g_oaMolecules[m_iShowMol],buf)) { eprintf("Invalid input.\n"); inpprintf("! Invalid input.\n"); goto _ax3; } m_oaVectors.Add(ag); ti *= ag->m_iAtomGes; } else // IF ORTHO { _ax4: mprintf(" Please enter the atom(s) at the base point (e.g. C7): "); inpprintf("! Please enter the atom(s) at the base point (e.g. C7):\n"); myget(&buf); try { ag = new CAtomGroup(); } catch(...) { ag = NULL; } if (ag == NULL) NewException((double)sizeof(CAtomGroup),__FILE__,__LINE__,__PRETTY_FUNCTION__); if (!ag->ParseAtoms((CMolecule*)g_oaMolecules[m_iShowMol],buf)) { eprintf("Invalid input.\n"); inpprintf("! Invalid input.\n"); goto _ax4; } m_oaVectors.Add(ag); ti *= ag->m_iAtomGes; _ax5: mprintf(" Please enter the atom(s) at the tip point (e.g. C7): "); inpprintf("! Please enter the atom(s) at the tip point (e.g. C7):\n"); myget(&buf); try { ag = new CAtomGroup(); } catch(...) { ag = NULL; } if (ag == NULL) NewException((double)sizeof(CAtomGroup),__FILE__,__LINE__,__PRETTY_FUNCTION__); if (!ag->ParseAtoms((CMolecule*)g_oaMolecules[m_iShowMol],buf)) { eprintf("Invalid input.\n"); inpprintf("! Invalid input.\n"); goto _ax5; } m_oaVectors.Add(ag); ti *= ag->m_iAtomGes; m_oaVectors.Add(NULL); } // END IF NOT ORTHO z2++; m_iCombinations += ti; } while (AskYesNo("\n Enter another set of vectors (y/n)? [no] ",false)); } else if (m_iVecType == 1) // Dipol { mprintf(" Taking dipole vector of OM %s.\n\n",((CMolecule*)g_oaMolecules[m_iShowMol])->m_sName); m_iCombinations = 1; g_bDipole = true; ParseDipole(); } else if (m_iVecType == 2) // Geschwindigkeit { _ax6: mprintf(" Velocity vector of which atoms to use (e.g. C7)? [#2] "); inpprintf("! Velocity vector of which atoms to use (e.g. C7)? [#2]\n"); myget(&buf); try { ag = new CAtomGroup(); } catch(...) { ag = NULL; } if (ag == NULL) NewException((double)sizeof(CAtomGroup),__FILE__,__LINE__,__PRETTY_FUNCTION__); if (strlen(buf)==0) { if (!ag->ParseAtoms((CMolecule*)g_oaMolecules[m_iShowMol],"#2")) { eprintf("CReorDyn::Parse(): Internal error (1).\n"); inpprintf("! CReorDyn::Parse(): Internal error.\n"); abort(); } } else if (!ag->ParseAtoms((CMolecule*)g_oaMolecules[m_iShowMol],buf)) { eprintf("Invalid input.\n"); inpprintf("! Invalid input.\n"); goto _ax6; } m_oaVectors.Add(ag); ti *= ag->m_iAtomGes; } else if (m_iVecType == 3) // Kraft { _ax7: mprintf(" Force vector of which atoms to use (e.g. C7)? [#2] "); inpprintf("! Force vector of which atoms to use (e.g. C7)? [#2]\n"); myget(&buf); try { ag = new CAtomGroup(); } catch(...) { ag = NULL; } if (ag == NULL) NewException((double)sizeof(CAtomGroup),__FILE__,__LINE__,__PRETTY_FUNCTION__); if (strlen(buf)==0) { if (!ag->ParseAtoms((CMolecule*)g_oaMolecules[m_iShowMol],"#2")) { eprintf("CReorDyn::Parse(): Internal Error (2).\n"); inpprintf("! CReorDyn::Parse(): Internal Error.\n"); abort(); } } else if (!ag->ParseAtoms((CMolecule*)g_oaMolecules[m_iShowMol],buf)) { eprintf("Invalid input.\n"); inpprintf("! Invalid input.\n"); goto _ax7; } m_oaVectors.Add(ag); ti *= ag->m_iAtomGes; } mprintf("\n Observing %d vectors per OM.\n\n",m_iCombinations); //_depth: mprintf(WHITE," Hint: "); mprintf("The resolution of the ACF may never be higher than the number of processed steps.\n"); mprintf(" Suggested is up to 75 percent of the processed steps.\n\n"); if (g_iTrajSteps != -1) m_iDepth = AskUnsignedInteger(" Enter the resolution (=depth) of the vector ACF (in time steps): [%d] ",int(g_iTrajSteps*0.75),int(g_iTrajSteps*0.75)); else m_iDepth = AskUnsignedInteger(" Enter the resolution (=depth) of the vector ACF (in time steps): [10000] ",10000); /* if (g_bRDynCacheMode) { tf = g_iTrajSteps*m_iCombinations*((CMolecule*)g_oaMolecules[m_iShowMol])->m_waSingleMolIndex.GetSize()*3.0f*sizeof(double)/1024.0f/1024.0f; // if (tf >= 10.0f) if (!AskYesNo(" This will occupy around %.0f MB RAM (for each R.Dyn.). Continue (y/n)? [yes] ",true,tf)) goto _depth; } else { tf = m_iDepth*g_iGesVirtAtomCount*3.0f*sizeof(double)/1024.0f/1024.0f; // if (tf >= 10.0f) if (!AskYesNo(" This will occupy around %.0f MB RAM (once, not for each R.Dyn.). Continue (y/n)? [yes] ",true,tf)) goto _depth; }*/ if (g_bACFFFT) { ti = CalcFFTSize(m_iDepth,false); if (m_iDepth != ti) { mprintf(WHITE,"\n The next \"fast\" size for FFT is %d. Using this instead of %d as depth.\n",tfft.NextFastSize(m_iDepth),m_iDepth); m_iDepth = tfft.NextFastSize(m_iDepth); } } else mprintf("\n"); m_iStride = AskUnsignedInteger(" Take each n-th time step for temporal axis: [1] ",1); mprintf("\n"); m_bLegendre2 = AskYesNo(" Perform autocorrelation of 2nd Legendre polynomial (y/n)? [no] ",false); mprintf("\n"); if (g_bAdvanced2) { m_bSpectrum = AskYesNo(" Calculate reorientation spectrum (FFT of vector ACF) (y/n)? [no] ",false); } else { mprintf("\n Note: The question for reorientation spectra has been moved to the advanced mode.\n"); m_bSpectrum = false; } if (m_bSpectrum) { try { m_pACF = new CACF(); } catch(...) { m_pACF = NULL; } if (m_pACF == NULL) NewException((double)sizeof(CACF),__FILE__,__LINE__,__PRETTY_FUNCTION__); m_pACF->m_iSize = m_iDepth; m_pACF->m_bSpectrum = true; m_pACF->m_bDerivative = AskYesNo(" Derive the vectors before autocorrelation (y/n)? [yes] ",true); if (m_pACF->m_bDerivative) m_pACF->m_iDerivative = AskRangeInteger(" Please enter degree of vector derivative (1-6): [1] ",1,6,1); else m_pACF->m_iDerivative = 0; m_pACF->m_bWindowFunction = AskYesNo(" Apply window function (Cos^2) to autocorrelation function (y/n)? [yes] ",true); tf = 33356.41 / g_fTimestepLength / 2.0; mprintf("\n A time step length of %.1f fs allows a spectral range up to %.1f cm^-1.\n\n",g_fTimestepLength,tf); m_pACF->m_fSpecWaveNumber = AskRangeFloat(" Calculate spectrum up to which wave number (cm^-1)? [%.1f cm^-1] ",0,tf,(tf<5000.0)?tf:5000.0,(tf<5000.0)?tf:5000.0); m_pACF->m_iMirror = AskUnsignedInteger(" No mirroring (0), short-time enhancing (1) or long-time enhancing (2)? [1] ",1); m_pACF->m_iZeroPadding = AskUnsignedInteger(" Zero Padding: How many zeros to insert? [%d] ",m_iDepth*3,m_iDepth*3); m_pACF->m_iZeroPadding0 = m_pACF->m_iZeroPadding; ti = CalcFFTSize(m_iDepth+m_pACF->m_iZeroPadding,false); if (m_iDepth+m_pACF->m_iZeroPadding != ti) { mprintf(WHITE,"\n The next \"fast\" size for FFT is %d. Using %d zeros for zero padding.\n",ti,ti-m_iDepth); m_pACF->m_iZeroPadding = ti-m_iDepth; } m_pACF->m_bACF_DB = AskYesNo(" Convert intensity axis of spectrum to decibel (y/n)? [no] ",false); m_pACF->Create(); } BuildName(); mprintf(YELLOW,"\n<<< End of Vector Reorientation Dynamics <<<\n\n"); BTOUT; } void CReorDyn::ParseSpec() { BTIN; int ti; double tf; CFFT tfft; try { m_pRDyn = new CDF(); } catch(...) { m_pRDyn = NULL; } if (m_pRDyn == NULL) NewException((double)sizeof(CDF),__FILE__,__LINE__,__PRETTY_FUNCTION__); m_pRDyn->m_bLeft = true; mprintf(YELLOW,"\n>>> Infrared Spectrum >>>\n\n"); m_iVecType = 1; m_iCombinations = 0; ti = 1; if (m_iShowMol != -1) { mprintf(" Taking dipole vector of OM %s.\n\n",((CMolecule*)g_oaMolecules[m_iShowMol])->m_sName); m_iMolecules = ((CMolecule*)g_oaMolecules[m_iShowMol])->m_laSingleMolIndex.GetSize(); } else m_iMolecules = g_oaSingleMolecules.GetSize(); m_iCombinations = 1; g_bDipole = true; ParseDipole(); mprintf(WHITE," Hint: "); mprintf("The resolution of the ACF may never be higher than the number of processed steps.\n"); mprintf(" Suggested is 75 percent of the processed steps, but not more than approx. 16384.\n\n"); if (g_iTrajSteps != -1) ti = (int(g_iTrajSteps*0.75)<5120)?int(g_iTrajSteps*0.75):4096; else ti = 4096; m_iDepth = AskUnsignedInteger(" Enter the resolution (=depth) of the dipole ACF (in time steps): [%d] ",ti,ti); if (g_bACFFFT) { ti = CalcFFTSize(m_iDepth,false); if (m_iDepth != ti) { mprintf(WHITE,"\n The next \"fast\" size for FFT is %d. Using this instead of %d as depth.\n",tfft.NextFastSize(m_iDepth),m_iDepth); m_iDepth = tfft.NextFastSize(m_iDepth); } } else mprintf("\n"); mprintf("\n This corresponds to a spectral resolution of %.4f cm^-1.\n",33356.41/g_fTimestepLength/2.0/m_iDepth); if (g_bAdvanced2) m_iStride = AskUnsignedInteger(" Take each n-th time step for temporal axis: [1] ",1); else m_iStride = 1; m_bSpectrum = true; try { m_pACF = new CACF(); } catch(...) { m_pACF = NULL; } if (m_pACF == NULL) NewException((double)sizeof(CACF),__FILE__,__LINE__,__PRETTY_FUNCTION__); m_pACF->m_iSize = m_iDepth; m_pACF->m_bSpectrum = true; if (g_bAdvanced2) { mprintf("\n"); m_pACF->m_bDerivative = AskYesNo(" Derive the dipole vectors before autocorrelation (y/n)? [yes] ",true); if (m_pACF->m_bDerivative) m_pACF->m_iDerivative = AskRangeInteger(" Please enter degree of vector derivative (1-6): [1] ",1,6,1); else m_pACF->m_iDerivative = 0; m_pACF->m_bWindowFunction = AskYesNo(" Apply window function (Cos^2) to autocorrelation function (y/n)? [yes] ",true); } else { m_pACF->m_bWindowFunction = true; m_pACF->m_bDerivative = true; m_pACF->m_iDerivative = 1; } tf = 33356.41 / g_fTimestepLength / 2.0; mprintf("\n A time step length of %.1f fs allows a spectral range up to %.1f cm^-1.\n\n",g_fTimestepLength,tf); m_pACF->m_fSpecWaveNumber = AskRangeFloat(" Calculate spectrum up to which wave number (cm^-1)? [%.1f cm^-1] ",0,tf,(tf<5000.0)?tf:5000.0,(tf<5000.0)?tf:5000.0); if (g_bAdvanced2) { m_pACF->m_iMirror = AskUnsignedInteger(" No mirroring (0), short-time enhancing (1) or long-time enhancing (2)? [1] ",1); m_pACF->m_iZeroPadding = AskUnsignedInteger(" Zero Padding: How many zeros to insert? [%d] ",m_iDepth*3,m_iDepth*3); } else { m_pACF->m_iMirror = 1; m_pACF->m_iZeroPadding = m_iDepth*3; } ti = CalcFFTSize(m_iDepth+m_pACF->m_iZeroPadding,false); if (m_iDepth+m_pACF->m_iZeroPadding != ti) { mprintf(WHITE," The next \"fast\" size for FFT is %d. Using %d zeros for zero padding.\n",ti,ti-m_iDepth); m_pACF->m_iZeroPadding = ti-m_iDepth; } mprintf(" Zero padding increases the spectral resolution to %.4f cm^-1.\n\n",33356.41/g_fTimestepLength/2.0/(m_iDepth+m_pACF->m_iZeroPadding)); m_pACF->m_iZeroPadding0 = m_pACF->m_iZeroPadding; m_pACF->m_bACF_DB = AskYesNo(" Convert intensity axis of spectrum to decibel (y/n)? [no] ",false); m_pACF->Create(); m_bCrossCor = false; BuildName(); mprintf(YELLOW,"\n<<< End of Infrared Spectrum <<<\n\n"); BTOUT; } void CReorDyn::BuildName() { BTIN; int z2; // char tmp[32768]; CxString tmp; CAtomGroup *ag; // tmp[0] = 0; tmp = ""; // strcat(tmp,"["); tmp.strcat("["); if (m_iVecType == 0) // Position { for (z2=0;z2m_sName); // strcat(tmp,"_"); // strcat(tmp,((CAtomGroup*)m_oaVectors[z2*3+1])->m_sName); // strcat(tmp,"_"); // strcat(tmp,((CAtomGroup*)m_oaVectors[z2*3+2])->m_sName); tmp.strcat(ag->m_sName); tmp.strcat("_"); tmp.strcat(((CAtomGroup*)m_oaVectors[z2*3+1])->m_sName); tmp.strcat("_"); tmp.strcat(((CAtomGroup*)m_oaVectors[z2*3+2])->m_sName); } else { ag = (CAtomGroup*)m_oaVectors[z2*3]; // strcat(tmp,ag->m_sName); // strcat(tmp,"_"); // strcat(tmp,((CAtomGroup*)m_oaVectors[z2*3+1])->m_sName); tmp.strcat(ag->m_sName); tmp.strcat("_"); tmp.strcat(((CAtomGroup*)m_oaVectors[z2*3+1])->m_sName); } if (z2<(m_oaVectors.GetSize()/3)-1) // strcat(tmp,"]_["); tmp.strcat("]_["); } } else if (m_iVecType == 1) // Dipol { // strcat(tmp,"dip_"); tmp.strcat("dip_"); if (m_iShowMol == -1) // strcat(tmp,"global"); tmp.strcat("global"); else // strcat(tmp,((CMolecule*)g_oaMolecules[m_iShowMol])->m_sName); tmp.strcat(((CMolecule*)g_oaMolecules[m_iShowMol])->m_sName); } else if (m_iVecType == 2) // Geschwindigkeit { // strcat(tmp,"vel_"); // strcat(tmp,((CAtomGroup*)m_oaVectors[0])->m_sName); tmp.strcat("vel_"); tmp.strcat(((CAtomGroup*)m_oaVectors[0])->m_sName); } else if (m_iVecType == 3) // Kraft { // strcat(tmp,"frc_"); // strcat(tmp,((CAtomGroup*)m_oaVectors[0])->m_sName); tmp.strcat("frc_"); tmp.strcat(((CAtomGroup*)m_oaVectors[0])->m_sName); } // strcat(tmp,"]"); tmp.strcat("]"); if (m_bLegendre2) // strcat(tmp,"_P2"); tmp.strcat("_P2"); try { m_sShortName = new char[strlen(tmp)+1]; } catch(...) { m_sShortName = NULL; } if (m_sShortName == NULL) NewException((double)(strlen(tmp)+1)*sizeof(char),__FILE__,__LINE__,__PRETTY_FUNCTION__); if (m_iVecType != 1) { strcpy(m_sShortName,tmp); // sprintf(tmp,"%s_",((CMolecule*)g_oaMolecules[m_iShowMol])->m_sName); // strcat(tmp,m_sShortName); tmp.sprintf("%s_",((CMolecule*)g_oaMolecules[m_iShowMol])->m_sName); tmp.strcat(m_sShortName); } try { m_sName = new char[strlen(tmp)+1]; } catch(...) { m_sName = NULL; } if (m_sName == NULL) NewException((double)(strlen(tmp)+1)*sizeof(char),__FILE__,__LINE__,__PRETTY_FUNCTION__); strcpy(m_sName,tmp); BTOUT; } void CReorDyn::BuildAtomList(CSingleMolecule *obs, CxIntArray *vec) { BXIN; int z, z1t, z1a, z2t, z2a, z3t, z3a; CAtomGroup *g1, *g2, *g3; CxIntArray *a1, *a2, *a3; vec->RemoveAll_KeepSize(); for (z=0;zm_baAtomType.GetSize();z1t++) { a1 = (CxIntArray*)g1->m_oaAtoms[z1t]; for (z1a=0;z1aGetSize();z1a++) { for (z2t=0;z2tm_baAtomType.GetSize();z2t++) { a2 = (CxIntArray*)g2->m_oaAtoms[z2t]; for (z2a=0;z2aGetSize();z2a++) { for (z3t=0;z3tm_baAtomType.GetSize();z3t++) { a3 = (CxIntArray*)g3->m_oaAtoms[z3t]; for (z3a=0;z3aGetSize();z3a++) { vec->Add(((CxIntArray*)obs->m_oaAtomOffset[g1->m_baAtomType[z1t]])->GetAt(a1->GetAt(z1a))); vec->Add(((CxIntArray*)obs->m_oaAtomOffset[g2->m_baAtomType[z2t]])->GetAt(a2->GetAt(z2a))); vec->Add(((CxIntArray*)obs->m_oaAtomOffset[g3->m_baAtomType[z3t]])->GetAt(a3->GetAt(z3a))); } } } } } } } else { g1 = (CAtomGroup*)m_oaVectors[z*3]; g2 = (CAtomGroup*)m_oaVectors[z*3+1]; for (z1t=0;z1tm_baAtomType.GetSize();z1t++) { a1 = (CxIntArray*)g1->m_oaAtoms[z1t]; for (z1a=0;z1aGetSize();z1a++) { for (z2t=0;z2tm_baAtomType.GetSize();z2t++) { a2 = (CxIntArray*)g2->m_oaAtoms[z2t]; for (z2a=0;z2aGetSize();z2a++) { vec->Add(((CxIntArray*)obs->m_oaAtomOffset[g1->m_baAtomType[z1t]])->GetAt(a1->GetAt(z1a))); vec->Add(((CxIntArray*)obs->m_oaAtomOffset[g2->m_baAtomType[z2t]])->GetAt(a2->GetAt(z2a))); vec->Add(0); } } } } } } BXOUT; } void CReorDyn::Finish(const char *multibuf) { int z2, z3, z4, z5, z6, ti; double tfs; // char buf[256]; CxString buf; CxDoubleArray *ptfa, *ptfab, *ptfa2, *ptfa2b, *ptfa3; CAutoCorrelation *ac; CCrossCorrelation *ccr; ti = 0; if (g_bRDynCacheMode) { if (m_bSpectrum) { switch(m_pACF->m_iDerivative) { case 0: mprintf(" Not deriving vectors.\n"); ti = 0; break; case 1: ti = 2; mprintf(" Deriving vectors (1st derivative)...\n"); mprintf(WHITE," ["); tfs = (m_iMolecules*m_iCombinations)/60.0; for (z2=0;z2SetSize(g_iSteps/g_iStride-ti); try { ptfa3 = new CxDoubleArray("CReorDyn::Finish():ptfa3"); } catch(...) { ptfa3 = NULL; } if (ptfa3 == NULL) NewException((double)sizeof(CxDoubleArray),__FILE__,__LINE__,__PRETTY_FUNCTION__); ptfa3->SetSize(g_iSteps/g_iStride-ti); try { ac = new CAutoCorrelation(); } catch(...) { ac = NULL; } if (ac == NULL) NewException((double)sizeof(CAutoCorrelation),__FILE__,__LINE__,__PRETTY_FUNCTION__); ac->Init(g_iSteps/g_iStride-ti,m_iDepth,g_bACFFFT); for (z2=0;z2AutoCorrelate(ptfa2,ptfa3); for (z3=0;z3<(int)m_iDepth/m_iStride;z3++) m_pRDyn->AddToBin_Int(z3,1.5*(*ptfa3)[z3*m_iStride]); /* 3/2 Y^2 */ for (z3=0;z3<(int)g_iSteps/g_iStride-ti;z3++) (*ptfa2)[z3] = (*ptfa)[z3*3+1] * (*ptfa)[z3*3+1]; ac->AutoCorrelate(ptfa2,ptfa3); for (z3=0;z3<(int)m_iDepth/m_iStride;z3++) m_pRDyn->AddToBin_Int(z3,1.5*(*ptfa3)[z3*m_iStride]); /* 3/2 Z^2 */ for (z3=0;z3<(int)g_iSteps/g_iStride-ti;z3++) (*ptfa2)[z3] = (*ptfa)[z3*3+2] * (*ptfa)[z3*3+2]; ac->AutoCorrelate(ptfa2,ptfa3); for (z3=0;z3<(int)m_iDepth/m_iStride;z3++) m_pRDyn->AddToBin_Int(z3,1.5*(*ptfa3)[z3*m_iStride]); /* 3 X*Y */ for (z3=0;z3<(int)g_iSteps/g_iStride-ti;z3++) (*ptfa2)[z3] = (*ptfa)[z3*3] * (*ptfa)[z3*3+1]; ac->AutoCorrelate(ptfa2,ptfa3); for (z3=0;z3<(int)m_iDepth/m_iStride;z3++) m_pRDyn->AddToBin_Int(z3,3*(*ptfa3)[z3*m_iStride]); /* 3 X*Z */ for (z3=0;z3<(int)g_iSteps/g_iStride-ti;z3++) (*ptfa2)[z3] = (*ptfa)[z3*3] * (*ptfa)[z3*3+2]; ac->AutoCorrelate(ptfa2,ptfa3); for (z3=0;z3<(int)m_iDepth/m_iStride;z3++) m_pRDyn->AddToBin_Int(z3,3*(*ptfa3)[z3*m_iStride]); /* 3 Y*Z */ for (z3=0;z3<(int)g_iSteps/g_iStride-ti;z3++) (*ptfa2)[z3] = (*ptfa)[z3*3+1] * (*ptfa)[z3*3+2]; ac->AutoCorrelate(ptfa2,ptfa3); for (z3=0;z3<(int)m_iDepth/m_iStride;z3++) m_pRDyn->AddToBin_Int(z3,3*(*ptfa3)[z3*m_iStride]); /* -1/2 */ for (z3=0;z3<(int)m_iDepth/m_iStride;z3++) m_pRDyn->AddToBin_Int(z3,-0.5); for (z3=0;z3<(int)m_iDepth/m_iStride;z3++) m_pRDyn->m_fBinEntries += (double)(g_iSteps-z3*m_iStride) - 3.0; } else // Classical vector autocorrelation { /* X */ for (z3=0;z3<(int)g_iSteps/g_iStride-ti;z3++) (*ptfa2)[z3] = (*ptfa)[z3*3]; // (*ptfa2)[z3] = sqrt((*ptfa)[z3*3]*(*ptfa)[z3*3] + (*ptfa)[z3*3+1]*(*ptfa)[z3*3+1] + (*ptfa)[z3*3+2]*(*ptfa)[z3*3+2]); ac->AutoCorrelate(ptfa2,ptfa3); for (z3=0;z3<(int)m_iDepth/m_iStride;z3++) m_pRDyn->AddToBin_Int(z3,(*ptfa3)[z3*m_iStride]); /* Y */ for (z3=0;z3<(int)g_iSteps/g_iStride-ti;z3++) (*ptfa2)[z3] = (*ptfa)[z3*3+1]; ac->AutoCorrelate(ptfa2,ptfa3); for (z3=0;z3<(int)m_iDepth/m_iStride;z3++) m_pRDyn->AddToBin_Int(z3,(*ptfa3)[z3*m_iStride]); /* Z */ for (z3=0;z3<(int)g_iSteps/g_iStride-ti;z3++) (*ptfa2)[z3] = (*ptfa)[z3*3+2]; ac->AutoCorrelate(ptfa2,ptfa3); for (z3=0;z3<(int)m_iDepth/m_iStride;z3++) { m_pRDyn->AddToBin_Int(z3,(*ptfa3)[z3*m_iStride]); m_pRDyn->m_fBinEntries += (double)(g_iSteps-z3*m_iStride) - 3.0; } } } delete ac; delete ptfa2; delete ptfa3; mprintf(WHITE,"]\n"); } else { for (z2=0;z2m_iResolution;z2++) m_pRDyn->m_pBin[z2] /= m_pCount[z2]; } if (m_iShowMol == -1) // Keine Normalisierung fuer globales Spektrum Finish_Part2("",multibuf,1); else Finish_Part2("",multibuf,m_iMolecules*m_iCombinations); if (m_bSpectrum && m_bCrossCor) { /*************************************************************************/ mprintf(WHITE,"\n * Computing Cross-Correlation \"cross\"\n"); m_pACF->m_iSize = m_iDepth; m_pACF->m_iZeroPadding = m_pACF->m_iZeroPadding0; m_pACF->Create(); mprintf(" Cross-Correlating cached vectors...\n"); mprintf(WHITE," ["); tfs = (m_iMolecules*m_iCombinations)*(m_iMolecules*m_iCombinations)/60.0; m_pRDyn->ZeroBin(); try { ptfa2 = new CxDoubleArray("CReorDyn::Finish():ptfa2"); } catch(...) { ptfa2 = NULL; } if (ptfa2 == NULL) NewException((double)sizeof(CxDoubleArray),__FILE__,__LINE__,__PRETTY_FUNCTION__); ptfa2->SetSize(g_iSteps/g_iStride-ti); try { ptfa2b = new CxDoubleArray("CReorDyn::Finish():ptfa2b"); } catch(...) { ptfa2b = NULL; } if (ptfa2b == NULL) NewException((double)sizeof(CxDoubleArray),__FILE__,__LINE__,__PRETTY_FUNCTION__); ptfa2b->SetSize(g_iSteps/g_iStride-ti); try { ptfa3 = new CxDoubleArray("CReorDyn::Finish():ptfa3"); } catch(...) { ptfa3 = NULL; } if (ptfa3 == NULL) NewException((double)sizeof(CxDoubleArray),__FILE__,__LINE__,__PRETTY_FUNCTION__); ptfa3->SetSize(g_iSteps/g_iStride-ti); try { ccr = new CCrossCorrelation(); } catch(...) { ccr = NULL; } if (ccr == NULL) NewException((double)sizeof(CCrossCorrelation),__FILE__,__LINE__,__PRETTY_FUNCTION__); ccr->Init(g_iSteps/g_iStride-ti,m_iDepth,g_bACFFFT); for (z2=0;z2CrossCorrelate(ptfa2,ptfa2b,ptfa3); for (z3=0;z3<(int)m_iDepth/m_iStride;z3++) m_pRDyn->AddToBin_Int(z3,(*ptfa3)[z3*m_iStride]); /* Y */ for (z3=0;z3<(int)g_iSteps/g_iStride-ti;z3++) { (*ptfa2)[z3] = (*ptfa)[z3*3+1]; (*ptfa2b)[z3] = (*ptfab)[z3*3+1]; } ccr->CrossCorrelate(ptfa2,ptfa2b,ptfa3); for (z3=0;z3<(int)m_iDepth/m_iStride;z3++) m_pRDyn->AddToBin_Int(z3,(*ptfa3)[z3*m_iStride]); /* Z */ for (z3=0;z3<(int)g_iSteps/g_iStride-ti;z3++) { (*ptfa2)[z3] = (*ptfa)[z3*3+2]; (*ptfa2b)[z3] = (*ptfab)[z3*3+2]; } ccr->CrossCorrelate(ptfa2,ptfa2b,ptfa3); for (z3=0;z3<(int)m_iDepth/m_iStride;z3++) { m_pRDyn->AddToBin_Int(z3,(*ptfa3)[z3*m_iStride]); m_pRDyn->m_fBinEntries += (double)(g_iSteps-z3*m_iStride) - 3.0; } } } delete ccr; delete ptfa2; delete ptfa2b; delete ptfa3; mprintf(WHITE,"]\n"); Finish_Part2("cross_",multibuf,1); /*************************************************************************/ mprintf(WHITE,"\n * Computing Cross-Correlation \"both\"\n"); m_pACF->m_iSize = m_iDepth; m_pACF->m_iZeroPadding = m_pACF->m_iZeroPadding0; m_pACF->Create(); mprintf(" Cross-Correlating cached vectors...\n"); mprintf(WHITE," ["); tfs = (m_iMolecules*m_iCombinations)*(m_iMolecules*m_iCombinations)/60.0; m_pRDyn->ZeroBin(); try { ptfa2 = new CxDoubleArray("CReorDyn::Finish():ptfa2"); } catch(...) { ptfa2 = NULL; } if (ptfa2 == NULL) NewException((double)sizeof(CxDoubleArray),__FILE__,__LINE__,__PRETTY_FUNCTION__); ptfa2->SetSize(g_iSteps/g_iStride-ti); try { ptfa2b = new CxDoubleArray("CReorDyn::Finish():ptfa2b"); } catch(...) { ptfa2b = NULL; } if (ptfa2b == NULL) NewException((double)sizeof(CxDoubleArray),__FILE__,__LINE__,__PRETTY_FUNCTION__); ptfa2b->SetSize(g_iSteps/g_iStride-ti); try { ptfa3 = new CxDoubleArray("CReorDyn::Finish():ptfa3"); } catch(...) { ptfa3 = NULL; } if (ptfa3 == NULL) NewException((double)sizeof(CxDoubleArray),__FILE__,__LINE__,__PRETTY_FUNCTION__); ptfa3->SetSize(g_iSteps/g_iStride-ti); try { ccr = new CCrossCorrelation(); } catch(...) { ccr = NULL; } if (ccr == NULL) NewException((double)sizeof(CCrossCorrelation),__FILE__,__LINE__,__PRETTY_FUNCTION__); ccr->Init(g_iSteps/g_iStride-ti,m_iDepth,g_bACFFFT); for (z2=0;z2CrossCorrelate(ptfa2,ptfa2b,ptfa3); for (z3=0;z3<(int)m_iDepth/m_iStride;z3++) m_pRDyn->AddToBin_Int(z3,(*ptfa3)[z3*m_iStride]); /* Y */ for (z3=0;z3<(int)g_iSteps/g_iStride-ti;z3++) { (*ptfa2)[z3] = (*ptfa)[z3*3+1]; (*ptfa2b)[z3] = (*ptfab)[z3*3+1]; } ccr->CrossCorrelate(ptfa2,ptfa2b,ptfa3); for (z3=0;z3<(int)m_iDepth/m_iStride;z3++) m_pRDyn->AddToBin_Int(z3,(*ptfa3)[z3*m_iStride]); /* Z */ for (z3=0;z3<(int)g_iSteps/g_iStride-ti;z3++) { (*ptfa2)[z3] = (*ptfa)[z3*3+2]; (*ptfa2b)[z3] = (*ptfab)[z3*3+2]; } ccr->CrossCorrelate(ptfa2,ptfa2b,ptfa3); for (z3=0;z3<(int)m_iDepth/m_iStride;z3++) { m_pRDyn->AddToBin_Int(z3,(*ptfa3)[z3*m_iStride]); m_pRDyn->m_fBinEntries += (double)(g_iSteps-z3*m_iStride) - 3.0; } } } delete ccr; delete ptfa2; delete ptfa2b; delete ptfa3; mprintf(WHITE,"]\n"); Finish_Part2("both_",multibuf,1); /*************************************************************************/ if (m_iShowMol == -1) { for (z5=0;z5m_sName,((CMolecule*)g_oaMolecules[z6])->m_sName); m_pACF->m_iSize = m_iDepth; m_pACF->m_iZeroPadding = m_pACF->m_iZeroPadding0; m_pACF->Create(); mprintf(" Cross-Correlating cached vectors...\n"); mprintf(WHITE," ["); tfs = (m_iMolecules*m_iCombinations)*(m_iMolecules*m_iCombinations)/60.0; m_pRDyn->ZeroBin(); try { ptfa2 = new CxDoubleArray("CReorDyn::Finish():ptfa2"); } catch(...) { ptfa2 = NULL; } if (ptfa2 == NULL) NewException((double)sizeof(CxDoubleArray),__FILE__,__LINE__,__PRETTY_FUNCTION__); ptfa2->SetSize(g_iSteps/g_iStride-ti); try { ptfa2b = new CxDoubleArray("CReorDyn::Finish():ptfa2b"); } catch(...) { ptfa2b = NULL; } if (ptfa2b == NULL) NewException((double)sizeof(CxDoubleArray),__FILE__,__LINE__,__PRETTY_FUNCTION__); ptfa2b->SetSize(g_iSteps/g_iStride-ti); try { ptfa3 = new CxDoubleArray("CReorDyn::Finish():ptfa3"); } catch(...) { ptfa3 = NULL; } if (ptfa3 == NULL) NewException((double)sizeof(CxDoubleArray),__FILE__,__LINE__,__PRETTY_FUNCTION__); ptfa3->SetSize(g_iSteps/g_iStride-ti); try { ccr = new CCrossCorrelation(); } catch(...) { ccr = NULL; } if (ccr == NULL) NewException((double)sizeof(CCrossCorrelation),__FILE__,__LINE__,__PRETTY_FUNCTION__); ccr->Init(g_iSteps/g_iStride-ti,m_iDepth,g_bACFFFT); for (z2=0;z2m_iMolType != z5) || (((CSingleMolecule*)g_oaSingleMolecules[z4])->m_iMolType != z6)) && ((((CSingleMolecule*)g_oaSingleMolecules[z2])->m_iMolType != z6) || (((CSingleMolecule*)g_oaSingleMolecules[z4])->m_iMolType != z5))) continue; ptfab = (CxDoubleArray*)m_oaCache[z4]; /* X */ for (z3=0;z3<(int)g_iSteps/g_iStride-ti;z3++) { (*ptfa2)[z3] = (*ptfa)[z3*3]; (*ptfa2b)[z3] = (*ptfab)[z3*3]; } ccr->CrossCorrelate(ptfa2,ptfa2b,ptfa3); for (z3=0;z3<(int)m_iDepth/m_iStride;z3++) m_pRDyn->AddToBin_Int(z3,(*ptfa3)[z3*m_iStride]); /* Y */ for (z3=0;z3<(int)g_iSteps/g_iStride-ti;z3++) { (*ptfa2)[z3] = (*ptfa)[z3*3+1]; (*ptfa2b)[z3] = (*ptfab)[z3*3+1]; } ccr->CrossCorrelate(ptfa2,ptfa2b,ptfa3); for (z3=0;z3<(int)m_iDepth/m_iStride;z3++) m_pRDyn->AddToBin_Int(z3,(*ptfa3)[z3*m_iStride]); /* Z */ for (z3=0;z3<(int)g_iSteps/g_iStride-ti;z3++) { (*ptfa2)[z3] = (*ptfa)[z3*3+2]; (*ptfa2b)[z3] = (*ptfab)[z3*3+2]; } ccr->CrossCorrelate(ptfa2,ptfa2b,ptfa3); for (z3=0;z3<(int)m_iDepth/m_iStride;z3++) { m_pRDyn->AddToBin_Int(z3,(*ptfa3)[z3*m_iStride]); m_pRDyn->m_fBinEntries += (double)(g_iSteps-z3*m_iStride) - 3.0; } } } delete ccr; delete ptfa2; delete ptfa2b; delete ptfa3; mprintf(WHITE,"]\n"); // sprintf(buf,"cc_%s_%s_",((CMolecule*)g_oaMolecules[z5])->m_sName,((CMolecule*)g_oaMolecules[z6])->m_sName); buf.sprintf("cc_%s_%s_",((CMolecule*)g_oaMolecules[z5])->m_sName,((CMolecule*)g_oaMolecules[z6])->m_sName); Finish_Part2(buf,multibuf,1); } } } /*************************************************************************/ } // END IF SPECTRUM _irdone:; } void CReorDyn::Finish_Part2(const char *s, const char *multibuf, int nmol) { // char buf[256]; CxString buf; int z2; mprintf(" %.0f bin entries.\n",m_pRDyn->m_fBinEntries); if (m_bSpectrum) m_pRDyn->MultiplyBin(1.0/g_iSteps/nmol); else m_pRDyn->MultiplyBin(1.0/m_pRDyn->m_pBin[0]); // sprintf(buf,"rdyn_%s%s%s.csv",s,m_sName,multibuf); buf.sprintf("rdyn_%s%s%s.csv",s,m_sName,multibuf); mprintf(" Saving result as %s ...\n",(const char*)buf); m_pRDyn->Write("",buf,"",false); if (m_bSpectrum) { mprintf(" Creating reorientation spectrum:\n"); for (z2=0;z2m_pData[z2] = m_pRDyn->m_pBin[z2]; if (m_pACF->m_iDerivative != 0) // sprintf(buf,"acf_%s%s%s.d%d.csv",s,m_sName,multibuf,m_pACF->m_iDerivative); buf.sprintf("acf_%s%s%s.d%d.csv",s,m_sName,multibuf,m_pACF->m_iDerivative); else // sprintf(buf,"acf_%s%s%s.csv",s,m_sName,multibuf); buf.sprintf("acf_%s%s%s.csv",s,m_sName,multibuf); mprintf(" Saving ACF as %s ...\n",(const char*)buf); m_pACF->WriteACF("",buf,""); if (m_pACF->m_iMirror != 0) { mprintf(" Mirroring ACF...\n"); m_pACF->Mirror(m_pACF->m_iMirror); if (m_pACF->m_bDerivative) // sprintf(buf,"acf_%s%s%s.d%d.m.csv",s,m_sName,multibuf,m_pACF->m_iDerivative); buf.sprintf("acf_%s%s%s.d%d.m.csv",s,m_sName,multibuf,m_pACF->m_iDerivative); else // sprintf(buf,"acf_%s%s%s.m.csv",s,m_sName,multibuf); buf.sprintf("acf_%s%s%s.m.csv",s,m_sName,multibuf); mprintf(" Saving mirrored ACF as %s ...\n",(const char*)buf); m_pACF->WriteACF("",buf,""); } if (m_pACF->m_bWindowFunction) { mprintf(" Applying window function to ACF...\n"); m_pACF->Window(); if (m_pACF->m_bDerivative) // sprintf(buf,"acf_%s%s%s.d%d.w.csv",s,m_sName,multibuf,m_pACF->m_iDerivative); buf.sprintf("acf_%s%s%s.d%d.w.csv",s,m_sName,multibuf,m_pACF->m_iDerivative); else // sprintf(buf,"acf_%s%s%s.w.csv",s,m_sName,multibuf); buf.sprintf("acf_%s%s%s.w.csv",s,m_sName,multibuf); mprintf(" Saving windowed ACF as %s ...\n",(const char*)buf); m_pACF->WriteACF("",buf,""); } mprintf(" Performing fourier transformation...\n"); try { g_pFFT = new CFFT(); } catch(...) { g_pFFT = NULL; } if (g_pFFT == NULL) NewException((double)sizeof(CFFT),__FILE__,__LINE__,__PRETTY_FUNCTION__); g_pFFT->PrepareFFT_C2C(m_pACF->m_iSize+m_pACF->m_iZeroPadding); m_pACF->Transform(g_pFFT); delete g_pFFT; m_pACF->m_pSpectrum->SetMaxRWL(1E7/299.792/g_fTimestepLength/g_iStride); if (m_pACF->m_bACF_DB) { mprintf(" Normalising spectrum to decibel...\n"); m_pACF->m_pSpectrum->MakeDB(); } if (m_pACF->m_bDerivative) // sprintf(buf,"spectrum_%s%s%s.d%d.csv",s,m_sName,multibuf,m_pACF->m_iDerivative); buf.sprintf("spectrum_%s%s%s.d%d.csv",s,m_sName,multibuf,m_pACF->m_iDerivative); else // sprintf(buf,"spectrum_%s%s%s.csv",s,m_sName,multibuf); buf.sprintf("spectrum_%s%s%s.csv",s,m_sName,multibuf); mprintf(" Saving spectrum as %s ...\n",(const char*)buf); m_pACF->m_pSpectrum->Write("",buf,""); } } travis-src-190101/src/reordyn.h0100777000000000000000000000410513412725653013274 0ustar00/***************************************************************************** TRAVIS - Trajectory Analyzer and Visualizer http://www.travis-analyzer.de/ Copyright (c) 2009-2019 Martin Brehm 2012-2019 Martin Thomas 2016-2019 Sascha Gehrke This file was written by Martin Brehm. --------------------------------------------------------------------------- This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . *****************************************************************************/ #ifndef REORDYN_H #define REORDYN_H // This must always be the first include directive #include "config.h" #include "xobject.h" #include "df.h" #include "atomgroup.h" #include "acf.h" class CSingleMolecule; class CReorDyn : public CxObject { public: void Finish_Part2(const char *s, const char *multibuf, int nmol); void Finish(const char *multibuf); void BuildAtomList(CSingleMolecule *obs, CxIntArray *vec); void BuildName(); void Parse(); void ParseSpec(); CReorDyn(); ~CReorDyn(); bool m_bOrtho; int m_iVecType; // 0 = Ort, 1 = Dipol, 2 = Geschw., 3 = Kraft int m_iCombinations; int m_iShowMol; char *m_sName; char *m_sShortName; int m_iDepth; int m_iStride; int m_iMolecules; double *m_pCount; bool m_bSpectrum; CACF *m_pACF; bool m_bCrossCor; CxObArray m_oaCache; CxObArray m_oaVectors; // Enthaelt CAtomGroups, 3 pro Vektor CDF *m_pRDyn; bool m_bLifetimeSpectrum; CxObArray m_oaLTSpectra; bool m_bLegendre2; }; #endif travis-src-190101/src/revsdf.cpp0100777000000000000000000002106513412725616013441 0ustar00/***************************************************************************** TRAVIS - Trajectory Analyzer and Visualizer http://www.travis-analyzer.de/ Copyright (c) 2009-2019 Martin Brehm 2012-2019 Martin Thomas 2016-2019 Sascha Gehrke This file was written by Martin Brehm. --------------------------------------------------------------------------- This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . *****************************************************************************/ // This must always be the first include directive #include "config.h" #include "revsdf.h" #include "xwordarray.h" #include "moltools.h" #include "globalvar.h" const char *GetRevisionInfo_revsdf(unsigned int len) { static char buf[256]; GET_REVISION_INFO( buf, len ); return buf; } const char *GetSourceVersion_revsdf() { static char buf[256]; GET_SOURCE_VERSION( buf ); return buf; } CRevSDF::CRevSDF() { m_fSecondAtomPosX = 0; m_fSecondAtomCount = 0; } CRevSDF::~CRevSDF() { } void CRevSDF::BuildAtomList(CSingleMolecule *ref, CSingleMolecule *obs, CxIntArray *vec) { BXIN; int z1t, z1a; CxIntArray *a1; vec->RemoveAll_KeepSize(); for (z1t=0;z1tGetSize()); for (z1a=0;z1aGetSize();z1a++) if (m_iRefOrSec) { // mprintf("(c) BuildAtomList z1t=%d, z1a=%d, Type=%d, WA=%X\n",z1t,z1a,m_oAtoms.m_baAtomType[z1t],obs->m_oaAtomOffset[m_oAtoms.m_baAtomType[z1t]]); vec->Add(((CxIntArray*)obs->m_oaAtomOffset[m_oAtoms.m_baAtomType[z1t]])->GetAt(a1->GetAt(z1a))); } else vec->Add(((CxIntArray*)ref->m_oaAtomOffset[m_oAtoms.m_baAtomType[z1t]])->GetAt(a1->GetAt(z1a))); } BXOUT; } void CRevSDF::BuildName() { BTIN; // char tmp[32768]; CxString tmp; if (m_iRefOrSec) // sprintf(tmp,"%s_%s%d%s%d_%s_%s",((CMolecule*)g_oaMolecules[g_iFixMol])->m_sName,((CAtom*)g_oaAtoms[g_iFixRealAtomType[0]])->m_sName,g_iFixAtom[0]+1,((CAtom*)g_oaAtoms[g_iFixRealAtomType[1]])->m_sName,g_iFixAtom[1]+1,((CMolecule*)g_oaMolecules[m_iShowMol])->m_sName,m_oAtoms.m_sName); tmp.sprintf("%s_%s%d%s%d_%s_%s",((CMolecule*)g_oaMolecules[g_iFixMol])->m_sName,(const char*)((CAtom*)g_oaAtoms[g_iFixRealAtomType[0]])->m_sName,g_iFixAtom[0]+1,(const char*)((CAtom*)g_oaAtoms[g_iFixRealAtomType[1]])->m_sName,g_iFixAtom[1]+1,((CMolecule*)g_oaMolecules[m_iShowMol])->m_sName,m_oAtoms.m_sName); else // sprintf(tmp,"%s_%s%d%s%d_%s",((CMolecule*)g_oaMolecules[g_iFixMol])->m_sName,((CAtom*)g_oaAtoms[g_iFixRealAtomType[0]])->m_sName,g_iFixAtom[0]+1,((CAtom*)g_oaAtoms[g_iFixRealAtomType[1]])->m_sName,g_iFixAtom[1]+1,m_oAtoms.m_sName); tmp.sprintf("%s_%s%d%s%d_%s",((CMolecule*)g_oaMolecules[g_iFixMol])->m_sName,(const char*)((CAtom*)g_oaAtoms[g_iFixRealAtomType[0]])->m_sName,g_iFixAtom[0]+1,(const char*)((CAtom*)g_oaAtoms[g_iFixRealAtomType[1]])->m_sName,g_iFixAtom[1]+1,m_oAtoms.m_sName); try { m_sName = new char[strlen(tmp)+1]; } catch(...) { m_sName = NULL; } if (m_sName == NULL) NewException((double)(strlen(tmp)+1)*sizeof(char),__FILE__,__LINE__,__PRETTY_FUNCTION__); strcpy(m_sName,tmp); BTOUT; } void CRevSDF::Parse() { BTIN; // char buf[256]; CxString buf; m_iShowAtomGes = 0; try { m_p2DF = new C2DF(); } catch(...) { m_p2DF = NULL; } if (m_p2DF == NULL) NewException((double)sizeof(C2DF),__FILE__,__LINE__,__PRETTY_FUNCTION__); mprintf(WHITE,"\n>>> Pseudo SDF >>>\n\n"); _sdfatoms: if (m_bIntra) { mprintf(" Observing Atoms in reference molecule %s.\n",((CMolecule*)g_oaMolecules[g_iFixMol])->m_sName); m_iRefOrSec = 0; } else { mprintf(" Observing Atoms in observed molecule %s.\n",((CMolecule*)g_oaMolecules[m_iShowMol])->m_sName); m_iRefOrSec = 1; } /* if (m_iShowMol != -1) m_iRefOrSec = AskRangeInteger(" Observe atoms in RM %s (0) or in OM %s (1)? [1] ",0,1,1,((CMolecule*)g_oaMolecules[g_iFixMol])->m_sName,((CMolecule*)g_oaMolecules[m_iShowMol])->m_sName); else m_iRefOrSec = 0;*/ if (((CMolecule*)g_oaMolecules[(m_iRefOrSec)?m_iShowMol:g_iFixMol])->m_iAtomGesNoVirt == 1) { mprintf(" %s is only one atom, there is no choice.\n",((CMolecule*)g_oaMolecules[(m_iRefOrSec)?m_iShowMol:g_iFixMol])->m_sName); m_oAtoms.Reset(); m_oAtoms.m_pMolecule = (CMolecule*)g_oaMolecules[(m_iRefOrSec)?m_iShowMol:g_iFixMol]; m_oAtoms.AddAtom(0,0,false); m_oAtoms.SortAtoms(); m_oAtoms.BuildName(); } else { mprintf(" Which atoms to observe (e.g. \"C1,C3-5,H\")? [all] "); inpprintf("! Which atoms to observe (e.g. \"C1,C3-5,H\")? [all]\n"); myget(&buf); if (strlen(buf) == 0) { m_oAtoms.AddAllAtoms((CMolecule*)g_oaMolecules[(m_iRefOrSec==0)?g_iFixMol:m_iShowMol],false); } else if (!m_oAtoms.ParseAtoms((CMolecule*)g_oaMolecules[(m_iRefOrSec==0)?g_iFixMol:m_iShowMol],buf)) { eprintf("Invalid input.\n"); inpprintf("! Invalid input.\n"); goto _sdfatoms; } } m_iShowAtomGes += m_oAtoms.m_iAtomGes; m_fParticleDensity = m_oAtoms.m_iAtomGes * ((CMolecule*)g_oaMolecules[(m_iRefOrSec==0)?g_iFixMol:m_iShowMol])->m_laSingleMolIndex.GetSize() / g_fBoxX / g_fBoxY / g_fBoxZ * 1E9; m_fRadius = AskFloat(" Please enter radius of this Pseudo SDF in pm: [%.0f.0] ",(double)HalfBox(),(double)HalfBox()); if (g_bPeriodic && (m_fRadius > HalfBox_Exact()+1.0)) { eprintf("\nWarning: "); mprintf("The specified max. radius is larger than half of the smallest periodic cell vector.\n"); mprintf(" TRAVIS counts every atom only once (central periodic image).\n"); mprintf(" Expect the analysis to decay to zero for large radii.\n\n"); AskYesNo(" Acknowledged [yes] ",true); mprintf("\n"); } m_iResolution = AskUnsignedInteger(" Please enter binning resolution of this Pseudo SDF per dimension: [100] ",100)+1; m_iHistogramRes = AskUnsignedInteger(" Please enter histogram resolution (0=no histogram): [0] ",0); m_bMirrorY = AskYesNo(" Force this Pseudo SDF to be mirror-symmetrical to the X axis (y/n)? [no] ",false); if (m_bMirrorY) m_bMirrorBond = AskYesNo(" Mirror this Pseudo SDF at middle of bond (y) or ref. atom (n)? [yes] ",true); m_bCorrectRadial = AskYesNo(" Correct radial distribition (y/n)? [yes] ",true); m_bCorrectAngle = AskYesNo(" Apply cone correction (y/n)? [yes] ",true); m_bDrawAtoms = AskYesNo(" Show reference atoms in Pseudo SDF plot (y/n)? [yes] ",true); m_bCreateRevSDF = AskYesNo(" Create a volumetric Revolution SDF (y/n)? [no] ",false); if (m_bCreateRevSDF) { g_bCreateRevSDF = true; m_iRevSDFRes = AskUnsignedInteger(" Enter binning resolution of Revolution SDF per dimension: [100] ",100); } BuildName(); mprintf(WHITE,"\n<<< End of Pseudo SDF <<<\n\n"); BTOUT; } void CRevSDF::CreateRevSDF() { int x, y, z; CxDVector3 v; try { m_pRevSDF = new C3DF(); } catch(...) { m_pRevSDF = NULL; } if (m_pRevSDF == NULL) NewException((double)sizeof(C3DF),__FILE__,__LINE__,__PRETTY_FUNCTION__); m_pRevSDF->m_fMinVal[0] = -m_fRadius; m_pRevSDF->m_fMaxVal[0] = m_fRadius; m_pRevSDF->m_fMinVal[1] = -m_fRadius; m_pRevSDF->m_fMaxVal[1] = m_fRadius; m_pRevSDF->m_fMinVal[2] = -m_fRadius; m_pRevSDF->m_fMaxVal[2] = m_fRadius; m_pRevSDF->m_iRes[0] = m_iRevSDFRes; m_pRevSDF->m_iRes[1] = m_iRevSDFRes; m_pRevSDF->m_iRes[2] = m_iRevSDFRes; m_pRevSDF->Create(); for (z=0;zm_iRes[2];z++) { v[2] = (double)(((double)(z+0.5)/m_pRevSDF->m_iRes[2]*(m_pRevSDF->m_fMaxVal[2]-m_pRevSDF->m_fMinVal[2])) + m_pRevSDF->m_fMinVal[2]); for (y=0;ym_iRes[1];y++) { v[1] = (double)(((double)(y+0.5)/m_pRevSDF->m_iRes[1]*(m_pRevSDF->m_fMaxVal[1]-m_pRevSDF->m_fMinVal[1])) + m_pRevSDF->m_fMinVal[1]); for (x=0;xm_iRes[0];x++) { v[0] = (double)(((double)(x+0.5)/m_pRevSDF->m_iRes[0]*(m_pRevSDF->m_fMaxVal[0]-m_pRevSDF->m_fMinVal[0])) + m_pRevSDF->m_fMinVal[0]); m_pRevSDF->m_pBin[z*m_pRevSDF->m_iResXY + y*m_pRevSDF->m_iRes[0] + x] = m_p2DF->GetValue(sqrt(v[0]*v[0]+v[2]*v[2]),v[1]); } } } } travis-src-190101/src/revsdf.h0100777000000000000000000000407613412725647013115 0ustar00/***************************************************************************** TRAVIS - Trajectory Analyzer and Visualizer http://www.travis-analyzer.de/ Copyright (c) 2009-2019 Martin Brehm 2012-2019 Martin Thomas 2016-2019 Sascha Gehrke This file was written by Martin Brehm. --------------------------------------------------------------------------- This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . *****************************************************************************/ #ifndef REVSDF_H #define REVSDF_H // This must always be the first include directive #include "config.h" #include "xobject.h" #include "2df.h" #include "xdvec3array.h" #include "atomgroup.h" #include "3df.h" class CSingleMolecule; class CRevSDF : public CxObject { public: CRevSDF(); ~CRevSDF(); void BuildAtomList(CSingleMolecule *ref, CSingleMolecule *obs, CxIntArray *vec); void BuildName(); void Parse(); void CreateRevSDF(); bool m_bIntra; int m_iRefOrSec; char *m_sName; double m_fRadius; int m_iResolution; bool m_bMirrorY; bool m_bMirrorBond; int m_iShowMol; CxDVec3Array *m_vaData; C2DF *m_p2DF; C3DF *m_pRevSDF; CAtomGroup m_oAtoms; double m_fParticleDensity; int m_iShowAtomGes; double m_fSecondAtomPosX; double m_fSecondAtomCount; bool m_bCorrectAngle; bool m_bCorrectRadial; bool m_bCreateRevSDF; int m_iRevSDFRes; bool m_bDrawAtoms; int m_iHistogramRes; CxByteArray *m_baDataEnabled; }; #endif travis-src-190101/src/roa.cpp0100777000000000000000000054403213412725630012731 0ustar00/***************************************************************************** TRAVIS - Trajectory Analyzer and Visualizer http://www.travis-analyzer.de/ Copyright (c) 2009-2019 Martin Brehm 2012-2019 Martin Thomas 2016-2019 Sascha Gehrke This file was written by Martin Brehm. --------------------------------------------------------------------------- This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . *****************************************************************************/ // This must always be the first include directive #include "config.h" #include "roa.h" #include "xstring.h" #include "globalvar.h" #include "maintools.h" #include "bicgstab.h" #include "conversion.h" const char *GetRevisionInfo_roa(unsigned int len) { static char buf[256]; GET_REVISION_INFO( buf, len ); return buf; } const char *GetSourceVersion_roa() { static char buf[256]; GET_SOURCE_VERSION( buf ); return buf; } void CSmoothener::Init(int length, double wavenumber) { m_iLength = length; m_fWaveNumber = wavenumber; m_pForward = new CFFT(); // The constant "40" controls the padding between original data set and mirrored data set m_iInternalLength = m_pForward->NextFastSize(m_iLength+40); m_pForward->PrepareFFT_C2C(2*m_iInternalLength); m_pInverse = new CFFT(); m_pInverse->PrepareInverseFFT_C2C(2*m_iInternalLength); } void CSmoothener::Smoothen(const std::vector &inp, std::vector &outp) { int z; for (z=0;zm_pInput[2*z] = inp[z]; m_pForward->m_pInput[2*z+1] = 0.0; } for (z=m_iLength;zm_pInput[2*z] = inp[m_iLength-1]; m_pForward->m_pInput[2*z+1] = 0.0; } // Symmetrize by mirroring for (z=0;zm_pInput[2*(z+m_iInternalLength)] = inp[m_iLength-z-1]; m_pForward->m_pInput[2*(z+m_iInternalLength)+1] = 0.0; } for (z=m_iLength;zm_pInput[2*(z+m_iInternalLength)] = inp[0]; m_pForward->m_pInput[2*(z+m_iInternalLength)+1] = 0.0; } m_pForward->DoFFT(); for (z=0;z<2*m_iInternalLength;z++) { if (z < 2*m_iInternalLength*(m_fWaveNumber / (33356.41 / g_fTimestepLength / g_iStride / 2.0))) { m_pInverse->m_pInput[2*z] = m_pForward->m_pOutput[2*z]; m_pInverse->m_pInput[2*z+1] = m_pForward->m_pOutput[2*z+1]; } else { m_pInverse->m_pInput[2*z] = 0.0; m_pInverse->m_pInput[2*z+1] = 0.0; } } m_pInverse->m_pInput[0] /= 2.0*m_iInternalLength; m_pInverse->m_pInput[1] /= 2.0*m_iInternalLength; for (z=1;zm_pInput[2*z] /= (double)m_iInternalLength; m_pInverse->m_pInput[2*z+1] /= (double)m_iInternalLength; } m_pInverse->DoFFT(); outp.resize(m_iLength); // Borders: Linearly fade to original data, as smoothing might fail on borders for (z=0;zm_pOutput[2*z] + (1.0-(double)z/19.0)*inp[z]; for (z=MIN(20,m_iLength);zm_pOutput[2*z]; for (z=MAX(1,m_iLength-20);zm_pOutput[2*z] + (1.0-(double)(m_iLength-z-1)/19.0)*inp[z]; } void CSmoothener::Smoothen(const std::vector &inp, std::vector &outp) { int z, z2; std::vector tv; tv.resize(m_iLength); for (z=0;z<3;z++) { for (z2=0;z2 &inp, std::vector &outp) { int z, z2; std::vector tv; tv.resize(m_iLength); for (z=0;z<9;z++) { for (z2=0;z2>> Spectroscopy Observation %d >>>\n\n",iobs+1); obs = new CROAObservation(); mprintf(" The following types of spectra can be computed:\n"); mprintf(" IR - Infrared Spectrum\n"); mprintf(" Raman - Raman Spectrum\n"); mprintf(" VCD - Vibrational Circular Dichroism Spectrum\n"); mprintf(" ROA - Raman Optical Activity Spectrum\n"); mprintf("\n"); _again: ir = false; raman = false; vcd = false; sfg = false; roa = false; AskString_ND(" Spectra to compute for this observation (comma separated): ",&buf); p = buf.GetWritePointer(); while (true) { while ((*p == ' ') || (*p == ',')) p++; if (p == 0) break; q = p; while ((*q != ' ') && (*q != ',') && (*q != 0)) q++; memcpy(buf2,p,q-p); buf2[q-p] = 0; if (mystricmp(buf2,"IR") == 0) ir = true; else if (mystricmp(buf2,"Raman") == 0) raman = true; else if (mystricmp(buf2,"VCD") == 0) vcd = true; else if (mystricmp(buf2,"ROA") == 0) roa = true; else { eprintf("Error: Unknown input: \"%s\".\n\n",buf2); goto _again; } if (*q == 0) break; p = q+1; } if (!ir && !raman && !vcd && !sfg && !roa) { eprintf("Error: At least one type of spectrum needs to be selected.\n\n"); goto _again; } mprintf("\n"); if (ir) m_bIR = true; if (raman) m_bRaman = true; if (vcd) m_bVCD = true; if (roa) m_bROA = true; { obs->m_iaMolSelection.resize(g_oaMolecules.GetSize()); for (z=0;zm_sName)) { _again2: AskString(" Which molecules of type %s to observe (e.g. 1,5-7)? [all] ", &buf,"*",((CMolecule*)g_oaMolecules[z])->m_sName); if (mystricmp((const char*)buf,"*") == 0) { for (z2=0;z2<((CMolecule*)g_oaMolecules[z])->m_laSingleMolIndex.GetSize();z2++) obs->m_iaMolSelection[z].push_back(z2); } else { tia.RemoveAll(); if (!ParseIntList((const char*)buf,&tia)) goto _again2; for (z2=0;z2m_iaMolSelection[z].push_back(tia[z2]); } } } mprintf("\n"); } _resagain: if (g_iTrajSteps != -1) { obs->m_iDepth = (int)(0.5 * g_iTrajSteps/g_iStride); if ((int)floor(0.5 + (g_fTimestepLength*g_iStride) / 0.5) >= 1) // MB 181227: Avoid division by zero ti = 4096 / (int)floor(0.5 + (g_fTimestepLength*g_iStride) / 0.5); else ti = 4096; //ti = 4096 / (int)floor(0.5 + (g_fTimestepLength*g_iStride) / 0.5); if (obs->m_iDepth > ti) obs->m_iDepth = ti; obs->m_iDepth = AskUnsignedInteger(" Enter the resolution (=depth) of the correlation functions (in time steps): [%d] ", obs->m_iDepth, obs->m_iDepth); } else obs->m_iDepth = AskUnsignedInteger(" Enter the resolution (=depth) of the correlation functions (in time steps): [512] ", 512); if ((g_iTrajSteps != -1) && (obs->m_iDepth >= (int)(0.6 * g_iTrajSteps/g_iStride))) { mprintf("\n"); mprintf(RED," Warning: "); mprintf("The resolution is larger than half of the processed trajectory step count.\n"); mprintf(" This leads to noisy and inaccurate spectra.\n\n"); if (!AskYesNo(" Use this resolution anyway (y/n)? [no] ",false)) { mprintf("\n"); goto _resagain; } } i = CalcFFTSize(obs->m_iDepth, false); if (obs->m_iDepth != i) { mprintf(WHITE," The next \"fast\" size for FFT is %d. Using this value instead of %d as depth.\n", i, obs->m_iDepth); obs->m_iDepth = i; } if(g_bAdvanced2) { obs->m_iWindowFunction = AskRangeInteger(" Window function: cos^2(a*t) (1), exp(-t/a) (2), exp(-(t/a)^2) (3) [1] ", 1, 3, 1); if (obs->m_iWindowFunction == 1) { mprintf("\n The parameter \"a\" is chosen according to the correlation depth.\n\n"); obs->m_iWindowFunctionParameter = 0; } else if (obs->m_iWindowFunction == 2) { obs->m_iWindowFunctionParameter = AskUnsignedInteger(" Parameter \"a\" (in time steps): [%d] ", obs->m_iDepth / 4, obs->m_iDepth / 4); } else if (obs->m_iWindowFunction == 3) { obs->m_iWindowFunctionParameter = AskUnsignedInteger(" Parameter \"a\" (in time steps): [%d] ", obs->m_iDepth / 2, obs->m_iDepth / 2); } else { eprintf("Unknown input.\n"); abort(); } } else { obs->m_iWindowFunction = 1; obs->m_iWindowFunctionParameter = 0; mprintf(" Using Hann window function (cos^2).\n"); } if (g_bAdvanced2) { obs->m_iZeroPadding = AskUnsignedInteger(" Zero Padding: How many zeros to insert? [%d] ", obs->m_iDepth * 3, obs->m_iDepth * 3); i = CalcFFTSize(obs->m_iDepth + obs->m_iZeroPadding, false); if (obs->m_iDepth + obs->m_iZeroPadding != i) { mprintf(WHITE, " The next \"fast\" size for FFT is %d. Using %d zeros for zero padding.\n", i, i-obs->m_iDepth); obs->m_iZeroPadding = i-obs->m_iDepth; } } else { obs->m_iZeroPadding = obs->m_iDepth * 3; i = CalcFFTSize(obs->m_iDepth + obs->m_iZeroPadding, false); if (obs->m_iDepth + obs->m_iZeroPadding != i) { mprintf(WHITE, " The next \"fast\" size for FFT is %d. Using %d zeros for zero padding.\n", i, i-obs->m_iDepth); obs->m_iZeroPadding = i-obs->m_iDepth; } mprintf(" Inserting %d zeros for zero padding.\n",obs->m_iZeroPadding); } double possibleRange = 33356.41 / g_fTimestepLength / g_iStride / 2.0; obs->m_fSpecResolution = possibleRange / ( (obs->m_iDepth + obs->m_iZeroPadding)); mprintf(" This results in a spectral resolution of %.2f cm^-1 per data point.\n", obs->m_fSpecResolution); mprintf("\n A time step length of %.2f fs at stride %d allows a spectral range up to %.2f cm^-1.\n", g_fTimestepLength, g_iStride, possibleRange); double specLimit = AskRangeFloat("\n Calculate spectrum up to which wave number (cm^-1)? [%.2f cm^-1] ", 0, possibleRange, (possibleRange < 5000.0) ? possibleRange : 5000.0, (possibleRange < 5000.0) ? possibleRange : 5000.0); obs->m_iSpecLength = (int)(specLimit / obs->m_fSpecResolution); mprintf("\n"); if (g_bAdvanced2) { obs->m_bFiniteDifferenceCorrection = AskYesNo(" Apply finite difference correction (y/n)? [yes] ", true); mprintf("\n"); } else obs->m_bFiniteDifferenceCorrection = true; if (g_bAdvanced2) { obs->m_bSaveACF = AskYesNo(" Save also correlation function(s) (y/n)? [no] ", false); if (sfg) obs->m_bSingleACFs = AskYesNo(" Save all SFG correlation component spectra separately (y/n)? [no] ", false); else obs->m_bSingleACFs = false; mprintf("\n"); } else { obs->m_bSaveACF = false; obs->m_bSingleACFs = false; } if (g_bAdvanced2) obs->m_bUseCommutator = AskYesNo(" Use \"commutator trick\" for cross-correlations (y/n)? [yes] ",true); else obs->m_bUseCommutator = true; { if (g_bAdvanced2) obs->m_bCrossCorrelation = AskYesNo(" Include intermolecular cross-correlations (y/n)? [no] ",false); else obs->m_bCrossCorrelation = false; } obs->m_sMolName = ""; for (z=0;z<(int)obs->m_iaMolSelection.size();z++) { if (obs->m_iaMolSelection[z].size() == 0) continue; obs->m_sMolName.strcat("_"); obs->m_sMolName.strcat(((CMolecule*)g_oaMolecules[z])->m_sName); if ((int)obs->m_iaMolSelection[z].size() != ((CMolecule*)g_oaMolecules[z])->m_laSingleMolIndex.GetSize()) { for (z2=0;z2<(int)obs->m_iaMolSelection[z].size();z2++) { buf.sprintf("_%d",obs->m_iaMolSelection[z][z2]); obs->m_sMolName.strcat((const char*)buf); } } } if (raman || roa) { obs->m_fLaserFreq = AskFloat(" Calculate scattering cross section for which laser wave number (cm^-1)? [20000.0] ", 20000.0); obs->m_fTemperature = AskFloat(" Calculate scattering cross section for which temperature (K)? [350.0] ", 350.0); } obs->m_bCorrectTemperature = AskYesNo(" Correct spectrum for a certain simulation temperature (y/n)? [yes] ",true); if (obs->m_bCorrectTemperature) { if (raman || roa) obs->m_fCorrectTemperature = AskFloat(" Enter the simulation temperature (K): [%.1f] ", obs->m_fTemperature,obs->m_fTemperature); else obs->m_fCorrectTemperature = AskFloat(" Enter the simulation temperature (K): [350.0] ",350.0); } mprintf("\n Will compute the following spectra:\n"); if (ir) { mprintf(" - IR\n"); obs2 = new CROAObservation(*obs); obs2->m_iType = ROA_SPECTRUM_IR; obs2->m_sTypeName = "ir"; obs2->m_sName.Format("%s%s",(const char*)obs2->m_sTypeName,(const char*)obs2->m_sMolName); if (obs2->m_bCrossCorrelation) obs2->m_sName.strcat("_cc"); m_oaObservations.push_back(obs2); } if (raman) { mprintf(" - Raman\n"); obs2 = new CROAObservation(*obs); obs2->m_iType = ROA_SPECTRUM_RAMAN; obs2->m_sTypeName = "raman"; obs2->m_sName.Format("%s%s",(const char*)obs2->m_sTypeName,(const char*)obs2->m_sMolName); if (obs2->m_bCrossCorrelation) obs2->m_sName.strcat("_cc"); m_oaObservations.push_back(obs2); } if (vcd) { mprintf(" - VCD\n"); obs2 = new CROAObservation(*obs); obs2->m_iType = ROA_SPECTRUM_VCD; obs2->m_sTypeName = "vcd"; obs2->m_sName.Format("%s%s",(const char*)obs2->m_sTypeName,(const char*)obs2->m_sMolName); if (obs2->m_bCrossCorrelation) obs2->m_sName.strcat("_cc"); m_oaObservations.push_back(obs2); } if (roa) { mprintf(" - ROA\n"); obs2 = new CROAObservation(*obs); obs2->m_iType = ROA_SPECTRUM_ROA; obs2->m_sTypeName = "roa"; obs2->m_sName.Format("%s%s",(const char*)obs2->m_sTypeName,(const char*)obs2->m_sMolName); if (obs2->m_bCrossCorrelation) obs2->m_sName.strcat("_cc"); m_oaObservations.push_back(obs2); } delete obs; mprintf(WHITE,"\n <<< Spectroscopy Observation %d <<<\n\n",iobs+1); iobs++; if (!AskYesNo(" Add another observation (y/n)? [no] ",false)) break; } mprintf("\n Added %lu observations.\n\n",m_oaObservations.size()); } CROATrajectory::CROATrajectory() { m_iTSPos = 0; m_iHistory = 0; m_pFile = NULL; m_bBQB = false; m_pBQB = NULL; } CROATrajectory::~CROATrajectory() { int z; for (z=0;z<(int)m_oaTSHistory.size();z++) if (m_oaTSHistory[z] != NULL) delete m_oaTSHistory[z]; for (z=0;z<(int)m_oaMolecules.size();z++) delete m_oaMolecules[z]; if (m_pFile != NULL) { fclose(m_pFile); m_pFile = NULL; } if (m_pBQB != NULL) { delete m_pBQB; m_pBQB = NULL; } } void CROATrajectory::SetHistory(int i) { int z; m_iHistory = i; for (z=0;z<(int)m_oaTSHistory.size();z++) if (m_oaTSHistory[z] != NULL) delete m_oaTSHistory[z]; m_oaTSHistory.clear(); for (z=0;zOpenRead(m_sFileName)) { eprintf("\n Error: Not a valid BQB file.\n\n"); return false; } mprintf("\n Is a valid BQB file, "); if (m_pBQB->GetTotalFrameCount() != -1) mprintf("%d frames (with index)",m_pBQB->GetTotalFrameCount()); else mprintf("no index"); mprintf(".\n\n"); } else if (mystricmp(GetFileExtension(m_sFileName.c_str()),"cube") == 0) { m_pFile = fopen(m_sFileName.c_str(),"rb"); } else { eprintf("\n Error: Not a valid file extension: \"%s\".\n\n", GetFileExtension(m_sFileName.c_str())); return false; } return true; } bool CROATrajectory::ReadTimeStep() { if (m_iHistory == 0) { eprintf("CROATrajectory::ReadTimeStep(): Error: m_iHistory == 0.\n"); abort(); } m_iTSPos++; if (m_iTSPos >= m_iHistory) m_iTSPos = 0; if (m_bBQB) { if (!m_oaTSHistory[m_iTSPos]->ReadBQB(m_pBQB,true)) return false; } else { if (!m_oaTSHistory[m_iTSPos]->ReadCube(m_pFile,true)) return false; } m_oaTSHistory[m_iTSPos]->UniteMolecules(false); m_oaTSHistory[m_iTSPos]->CalcCenters(); return true; } bool CROATrajectory::SkipTimeStep() { CTimeStep ts; if (m_bBQB) { if (!ts.SkipBQB(m_pBQB)) return false; } else { if (!ts.SkipCube(m_pFile)) return false; } return true; } void CROATrajectory::Rewind() { if (m_bBQB) { if (m_pBQB == NULL) { eprintf("CROATrajectory::Rewind(): Error: BQB trajectory not initialized.\n"); abort(); } if (!m_pBQB->Rewind()) { eprintf("CROATrajectory::Rewind(): Error rewinding BQB trajectory.\n"); abort(); } } else { if (m_pFile != NULL) fclose(m_pFile); m_pFile = fopen(m_sFileName.c_str(),"rb"); if (m_pFile == NULL) { eprintf("CROATrajectory::Rewind(): Error rewinding CUBE trajectory.\n"); abort(); } } } void CROATrajectory::CalcVelocities() { int z, z2; CMolecule *m; CSingleMolecule *sm; CVirtualAtom *vi; unsigned long index; CxDVector3 dist; this->GetTimeStep(0)->m_vaVelocities.SetSize(g_iGesVirtAtomCount); for (z=0;zGetTimeStep(1)->m_vaCoords[z] - this->GetTimeStep(-1)->m_vaCoords[z]; if(g_bPeriodicX) { while(dist[0] > g_fBoxX / 2.0) dist[0] -= g_fBoxX; while(dist[0] < -g_fBoxX / 2.0) dist[0] += g_fBoxX; } if(g_bPeriodicY) { while(dist[1] > g_fBoxY / 2.0) dist[1] -= g_fBoxY; while(dist[1] < -g_fBoxY / 2.0) dist[1] += g_fBoxY; } if(g_bPeriodicZ) { while(dist[2] > g_fBoxZ / 2.0) dist[2] -= g_fBoxZ; while(dist[2] < -g_fBoxZ / 2.0) dist[2] += g_fBoxZ; } this->GetTimeStep(0)->m_vaVelocities[z] = dist * 1000.0 / 2.0 / g_fTimestepLength; } for (z = 0; z < g_oaVirtualAtoms.GetSize(); z++) { vi = (CVirtualAtom*)g_oaVirtualAtoms[z]; m = (CMolecule*)g_oaMolecules[vi->m_iMolecule]; for (z2=0;z2m_laSingleMolIndex.GetSize();z2++) { sm = (CSingleMolecule*)g_oaSingleMolecules[m->m_laSingleMolIndex[z2]]; index = ((CxIntArray*)sm->m_oaAtomOffset[sm->m_baAtomIndex.GetSize()-1])->GetAt(vi->m_iMolVirtAtom); if (((CVirtualAtom *)g_oaVirtualAtoms[z])->m_iMode == 2) { dist = CxDVector3(0.0, 0.0, 0.0); } else { dist = GetTimeStep(-1)->m_vaCoords[index] - GetTimeStep(1)->m_vaCoords[index]; if(g_bPeriodicX) { while(dist[0] > g_fBoxX / 2.0) dist[0] -= g_fBoxX; while(dist[0] < -g_fBoxX / 2.0) dist[0] += g_fBoxX; } if(g_bPeriodicY) { while(dist[1] > g_fBoxY / 2.0) dist[1] -= g_fBoxY; while(dist[1] < -g_fBoxY / 2.0) dist[1] += g_fBoxY; } if(g_bPeriodicZ) { while(dist[2] > g_fBoxZ / 2.0) dist[2] -= g_fBoxZ; while(dist[2] < -g_fBoxZ / 2.0) dist[2] += g_fBoxZ; } } this->GetTimeStep(0)->m_vaVelocities[index] = dist * 1000.0 / 2.0 / g_fTimestepLength; } } } CTimeStep* CROATrajectory::GetTimeStep(int i) { int t; if (m_iHistory == 0) { eprintf("CROATrajectory::GetTimeStep(): Error: m_iHistory == 0.\n"); abort(); } if ((i < -1) || (i > 1)) { eprintf("CROATrajectory::GetTimeStep(): Error: %d.\n",i); abort(); } t = (m_iTSPos+i-1) % m_iHistory; if (t < 0) t += m_iHistory; return m_oaTSHistory[t]; } bool CROAEngine::CheckTrajColumns(CROATrajectory *tr) { CBQBTrajectoryFrame btf(*g_pBQBInterface); bool b; mprintf(" Checking data fields of trajectory...\n"); if (!tr->m_bBQB) { eprintf("Error: Trajectory is not in BQB format.\n"); return false; } if (!tr->m_pBQB->ReadFrame()) { eprintf("Error while reading first BQB frame.\n"); return false; } if ((tr->m_pBQB->GetFrameType() != 4) || (tr->m_pBQB->GetFrameTypeVersion() != 0)) { eprintf("Error: Wrong BQB frame type (expected: 4v0, found: %dv%d).\n", tr->m_pBQB->GetFrameType(),tr->m_pBQB->GetFrameTypeVersion()); return false; } if (!btf.ReadFrame(tr->m_pBQB->GetFramePayload())) { eprintf("Error: Could not read trajectory frame from BQB payload.\n"); return false; } b = false; mprintf(" Contains: "); if (btf.GetColumn("Label") != NULL) { if (b) mprintf(", "); mprintf("Labels"); b=true; } if (btf.GetColumn("PosX") != NULL) { if (b) mprintf(", "); mprintf("Positions"); b=true; } if (btf.GetColumn("VelX") != NULL) { if (b) mprintf(", "); mprintf("Velocities"); b=true; } if (btf.GetColumn("EChg") != NULL) { if (b) mprintf(", "); mprintf("El.Charges"); b=true; } if (btf.GetColumn("EDipX") != NULL) { if (b) mprintf(", "); mprintf("El.Dipoles"); b=true; } if (btf.GetColumn("EQXX") != NULL) { if (b) mprintf(", "); mprintf("El.Quadrupoles"); b=true; } if (btf.GetColumn("ECurX") != NULL) { if (b) mprintf(", "); mprintf("El.Currents"); b=true; } if (btf.GetColumn("MDipX") != NULL) { if (b) mprintf(", "); mprintf("Mag.Dipoles"); } mprintf("\n\n"); if (btf.GetColumn("Label") == NULL) { eprintf("Error: Data file does not contain atom labels.\n"); return false; } if (btf.GetColumn("PosX") == NULL) { eprintf("Error: Data file does not contain atom positions.\n"); return false; } if (btf.GetColumn("EChg") == NULL) { eprintf("Error: Data file does not contain electric charges.\n"); return false; } if (btf.GetColumn("EDipX") == NULL) { eprintf("Error: Data file does not contain electric dipoles.\n"); return false; } if (m_bROA) { if (btf.GetColumn("EQXX") == NULL) { eprintf("Error: Data file does not contain electric quadrupoles required by ROA spectra.\n"); return false; } } if (m_bMagMom) { if (btf.GetColumn("VelX") == NULL) { eprintf("Error: Data file does not contain velocities required by VCD and ROA spectra.\n"); eprintf(" Switch on the magnetic dipole calculation in the gathering run to produce the data file.\n"); return false; } if (btf.GetColumn("MDipX") == NULL) { eprintf("Error: Data file does not contain magnetic dipoles required by VCD and ROA spectra.\n"); eprintf(" Switch on the magnetic dipole calculation in the gathering run to produce the data file.\n"); return false; } } return true; } bool CROAEngine::Parse() { int i, z, z2, steps, ti; CROATrajectory *tr; CxString buf; CxDVec3Array va; int rty; CROAMolecule *rm; mprintf(WHITE,"\n >>> New Spectroscopy Module >>>\n\n"); mprintf(" This module computes vibrational spectra (IR/Raman/VCD/ROA) from trajectories of\n"); mprintf(" volumetric electron density data. To use Wannier centers instead, use one of the\n"); mprintf(" old spectroscopy modules in the main function menu (enter \"ir\", \"raman\", or \"vcd\").\n"); mprintf("\n"); if (g_bTegri) { eprintf("Error: Don't switch on Voronoi integration in the main function menu.\n"); eprintf(" It will be switched on automatically.\n\n"); return false; } mprintf(" There are two different operating modes available:\n\n"); mprintf(YELLOW," (*) One-pass Mode:\n"); mprintf(" Read all volumetric data trajectories, solve the current PDE, integrate the properties\n"); mprintf(" and compute the desired spectra in one single pass. Easy to use, but takes a long time,\n"); mprintf(" because only one single CPU core is utilized for the process.\n"); mprintf("\n"); mprintf(YELLOW," (*) Two-pass Mode:\n"); mprintf(" Solve the current PDE for small parts of each trajectory individually in the first pass\n"); mprintf(" (\"gathering run\"), allowing to parallelize this process on many CPU cores. In the second\n"); mprintf(" pass (\"analyzing run\"), all data files (.emp) obtained in the first-pass runs are used to\n"); mprintf(" yield the desired spectra.\n\n"); if (AskYesNo(" Use two-pass mode (y/n)? [yes] ",true)) { if (AskYesNo(" Is this a gathering run (y) or the analyzing run (n)? [%s] ", !g_bElMagProperties,g_bElMagProperties?"no":"yes")) m_iMode = ROA_MODE_GATHER; else m_iMode = ROA_MODE_ANALYZE; } else m_iMode = ROA_MODE_COMBINED; if ((m_iMode == ROA_MODE_COMBINED) || (m_iMode == ROA_MODE_GATHER)) { if (!g_bVolumetricData) { mprintf("\n"); eprintf(" Error: This requires volumetric electron density data in each step of the trajectory.\n"); eprintf(" The file formats .cube and .bqb are suitable for this.\n\n"); return false; } } if (m_iMode == ROA_MODE_ANALYZE) { mprintf("\n"); mprintf(" Make sure to adapt the time step length if you processed only every n-th frame while gathering.\n"); mprintf(" If you, e.g., processed every 8-th frame from a trajectory with 0.5 fs time step, enter \"4.0\" below.\n"); } mprintf("\n"); g_fTimestepLength = AskFloat(" Enter the length of one trajectory time step in fs: [0.5] ",0.5); if (!g_bStrideParsed) { mprintf("\n"); g_bStrideParsed = true; g_iBeginStep = AskUnsignedInteger(" In which time step to start processing the trajectory? [1] ",1) - 1; if (g_iBeginStep == -1) g_iBeginStep = 0; g_iMaxStep = AskUnsignedInteger(" How many time steps to use (from this position on)? [all] ",0); if (g_iMaxStep == 0) g_iMaxStep = -1; // Alle verwenden if (g_iMaxStep > 0) g_iTrajSteps = g_iMaxStep; if ((m_iMode == ROA_MODE_GATHER) || (m_iMode == ROA_MODE_COMBINED)) { mprintf("\n In most cases, it is sufficient to process steps only every 2 fs or even 4 fs for good spectra.\n\n"); // ti = (int)floor(4.01/g_fTimestepLength); ti = 1; g_iStride = AskUnsignedInteger(" Use every n-th time step from the trajectory? [%d] ",ti,ti); } else g_iStride = AskUnsignedInteger(" Use every n-th time step from the trajectory? [1] ",1); } if ((m_iMode == ROA_MODE_COMBINED) || (m_iMode == ROA_MODE_ANALYZE)) { ParseObservations(); if (m_bVCD || m_bROA) { m_bMagMom = true; mprintf(" Magnetic dipole moments will be required.\n"); } if (m_bRaman || m_bROA || m_bSFG) { m_bPola = true; mprintf(" Polarizabilities will be required.\n"); } if (m_bMagMom || m_bPola) mprintf("\n"); if (m_bPola) { /* m_bAniso = AskYesNo(" Compute polarizability for all three spatial directions (y) or only for one (n)? [yes] ",true); if (!m_bAniso) { eprintf("\nNot yet implemented.\n\n"); return false; }*/ m_bAniso = true; m_bCentral = AskYesNo(" Use central finite differences (y) or one-sided differences (n) for polarizabilities? [no] ",false); m_fFieldStrength = AskFloat(" Enter electric field strength that was used for field trajectories (in a.u.): [5.0E-3] ",5.0E-3); } if (g_bAdvanced2) { m_bDumpMolecularProps = AskYesNo(" Write all molecular electronic/magnetic properties to file (y/n)? [no] ",false); m_bDumpMol1Props = AskYesNo(" Write electronic/magnetic properties of molecule 1 to file (y/n)? [no] ",false); m_bWriteACFs = AskYesNo(" Write autocorrelation functions of all quantities (y/n)? [no] ",false); m_bSmoothData = AskYesNo(" Smoothen properties before computing temporal derivatives (y/n)? [no] ",false); if (m_bSmoothData) m_fSmoothWaveNumber = AskFloat(" Smoothing: Remove all frequencies above which wave number (in cm^-1)? [5000] ",5000.0); m_bReplaceOutliers = AskYesNo(" Replace outliers in time series (y/n)? [no] ",false); g_bQuadrupoleKeepTrace = AskYesNo(" Keep trace of quadrupole tensor (y/n)? [no] ",false); m_bReverseTraj = AskYesNo(" Reverse direction of input trajectory (y/n)? [no] ",false); g_bDipoleRefFixed = AskYesNo(" Use a common box-fixed reference point for electric / magnetic multipoles (y/n)? [no] ", false); } else { m_bDumpMolecularProps = false; m_bDumpMol1Props = false; m_bWriteACFs = false; m_bSmoothData = false; m_bReplaceOutliers = false; g_bQuadrupoleKeepTrace = false; m_bReverseTraj = false; } } if (m_iMode == ROA_MODE_GATHER) { mprintf("\n"); m_bMagMom = AskYesNo(" Compute magnetic moments (time consuming, required for VCD and ROA) (y/n)? [yes] ",true); mprintf("\n"); } parseCoreCharges(); if ((m_iMode == ROA_MODE_COMBINED) || (m_iMode == ROA_MODE_GATHER)) { if (m_bMagMom) { if (g_fTimestepLength > 0.501) { mprintf("\n"); eprintf(" Warning: "); mprintf( "The finite differences approach for the magnetic moments only works accurately\n"); mprintf(" for small time steps <= 0.5 fs. Your trajectory has a time step of %.2f fs.\n\n",g_fTimestepLength); if (!AskYesNo(" Continue anyway (y/n)? [no] ",false)) return false; } if (g_iStride != 1) { mprintf("\n"); eprintf(" Warning: "); mprintf( "You have chosen to process only every %d-",g_iStride); if (g_iStride == 2) mprintf("nd"); else if (g_iStride == 3) mprintf("rd"); else mprintf("th"); mprintf(" step of the input trajectory.\n"); mprintf(" The finite differences approach for the magnetic moments requires a time step\n"); mprintf(" not larger than 0.5 fs. Therefore, TRAVIS will use the following scheme:\n\n"); mprintf(" Read time steps 1 - 3.\n"); mprintf(" Compute magnetic dipole in step 2 by finite differences from step 1 and 3.\n"); if (g_iStride > 4) { mprintf(" Skip time steps 4 - %d.\n",g_iStride); mprintf(" Read time steps %d - %d.\n",g_iStride+1,g_iStride+3); } else if (g_iStride == 4) { mprintf(" Skip time step 4.\n"); mprintf(" Read time steps 5 - 7.\n"); } else if (g_iStride == 3) { mprintf(" Read time steps 4 - 6.\n"); } else if (g_iStride == 2) { mprintf(" Read time steps 4 and 5.\n"); } mprintf(" Compute magnetic dipole in step %d by finite differences from step %d and %d.\n", g_iStride+2,g_iStride+1,g_iStride+3); mprintf(" ...\n\n"); if (!AskYesNo(" Acknowledged (y/n): [yes] ",true)) return false; } } ParseVoronoiRadii(); if (m_bMagMom) { if (g_bAdvanced2) { g_fBackgroundDensity = AskFloat(" Background density to improve PDE solver convergence (in a.u.): [1e-6] ", 1.0e-6); g_iPDEMaxIter = AskInteger(" Maximum number of iterations in PDE solver: [25] ", 25); m_bPDERestart = AskYesNo(" Restart PDE solver from solution of last step (y/n)? [yes] ",true); m_bPDEFastMode = AskYesNo(" Use PDE fast mode (activate unless there are problems) (y/n)? [yes] ",true); if (AskYesNo(" Write verbose info on PDE solving to text file (y/n)? [no] ",false)) m_fPDEInfo = OpenFileWrite("pde_verbose.txt",true); mprintf("\n"); } else { g_fBackgroundDensity = 1.0e-6; g_iPDEMaxIter = 25; m_bPDERestart = true; m_bPDEFastMode = true; mprintf(" Using a background density of %.2e and a maximum iteration count of %d in PDE solver.\n", g_fBackgroundDensity,g_iPDEMaxIter); mprintf(" Restarting PDE solver from solution of last step.\n\n"); } mprintf(" ROA spectra require a threshold of <= 0.001, but for VCD, normally 0.01 is enough (faster).\n\n"); if ((m_iMode == ROA_MODE_COMBINED) && !m_bROA) g_fPDEConvThresh = AskFloat(" Relative convergence threshold for PDE solver: [0.01] ", 0.01); else g_fPDEConvThresh = AskFloat(" Relative convergence threshold for PDE solver: [0.001] ", 0.001); } } for (z=0;zm_iDipoleMode = 7; if (m_bMagMom) ((CMolecule*)g_oaMolecules[z])->m_iMagneticDipoleMode = 7; ParseAtom("#2", z, ((CMolecule *)g_oaMolecules[z])->m_iDipoleCenterType, rty, ((CMolecule *)g_oaMolecules[z])->m_iDipoleCenterIndex); } if (m_iMode == ROA_MODE_GATHER) { mprintf("\n"); m_bGatherWriteCSV = AskYesNo(" Write CSV text file with atomic properties in addition to EMP file (y/n)? [no] ",false); if (g_bAdvanced2) m_bGatherCheck = AskYesNo(" Extract EMP file to CSV file (for checking) at the end of the run (y/n)? [no] ",false); else m_bGatherCheck = false; mprintf("\n Opening input trajectory...\n"); tr = new CROATrajectory; if (m_bMagMom) tr->SetHistory(3); else tr->SetHistory(1); m_iaTrajKinds[0] = (int)m_iaInvTrajKinds.size(); m_iaInvTrajKinds.push_back(0); m_oaTrajectories.push_back(tr); tr->m_sFileName = (const char*)g_sInputTraj; if (!tr->OpenFile()) { eprintf("Error: Could not re-open input trajectory \"%s\".\n",(const char*)g_sInputTraj); abort(); } /* if (g_pBQBEngine != NULL) { if (g_pBQBEngine->m_pExtrapolator != NULL) g_pBQBEngine->m_pExtrapolator->Clear(); if (g_pBQBEngine->m_pExtrapolatorCorr != NULL) g_pBQBEngine->m_pExtrapolatorCorr->Clear(); if (g_pBQBEngine->m_pExtrapolatorXYZ != NULL) g_pBQBEngine->m_pExtrapolatorXYZ->Clear(); }*/ if (tr->m_bBQB) { steps = tr->m_pBQB->GetTotalFrameCount(); mprintf(" Trajectoriy contains %d steps.\n",steps); } else steps = -1; mprintf("\n Reading first time step from trajectory...\n"); for (z=0;z<(int)m_oaTrajectories.size();z++) { mprintf(" %s ...\n",m_oaTrajectories[z]->m_sFileName.c_str()); if (!m_oaTrajectories[z]->ReadTimeStep()) { eprintf("Error: Could not read time step.\n"); abort(); } } mprintf(" Setting up Voronoi integration...\n"); if (!PrepareVori(m_oaTrajectories[0]->GetTimeStep(1),true,true,true)) { eprintf("Error while setting up Voronoi integration.\n"); return false; } mprintf("\n Computing dipole moment of first molecule from first time step of trajectory...\n"); if (m_bMagMom) { PrepareCurrentDensity( m_oaTrajectories[0]->GetTimeStep(1), m_oaTrajectories[0]->GetTimeStep(1), true ); PrepareCurrentDensity( m_oaTrajectories[0]->GetTimeStep(0), m_oaTrajectories[0]->GetTimeStep(1), false ); PrepareCurrentDensity( m_oaTrajectories[0]->GetTimeStep(-1), m_oaTrajectories[0]->GetTimeStep(1), false ); } g_bVoroIntegrateCharge = true; g_bVoroIntegrateDipoleMoment = true; g_bVoroIntegrateQuadrupoleMoment = true; g_bVoroIntegrateTotalCurrent = false; g_bVoroIntegrateMagneticMoment = false; g_bCubeTimeDev = false; g_pTetraPak->ProcessStep(m_oaTrajectories[0]->GetTimeStep(1),true); m_oaTrajectories[0]->GetTimeStep(1)->CalcDipoles(false); mprintf("\n"); if (m_bMagMom) { mprintf(WHITE," Important note:\n"); mprintf(" If you perform multiple gathering runs on different intervals of a volumetric trajectory file,\n"); mprintf(" make sure that the parts have an overlap of exactly 2 frames, because you will lose 2 frames\n"); mprintf(" at the beginning of the trajectory due to the finite differences in the magnetic moment PDE.\n\n"); } } if (m_iMode == ROA_MODE_ANALYZE) { mprintf("\n"); if (m_bPola) { mprintf(" You now need to supply the data files (.emp) which have previously been generated\n"); mprintf(" in gathering runs.\n\n"); mprintf(" Assuming that TRAVIS was started with the field-free trajectory.\n\n"); } tr = new CROATrajectory; tr->SetHistory(1); m_iaTrajKinds[0] = (int)m_iaInvTrajKinds.size(); m_iaInvTrajKinds.push_back(0); m_oaTrajectories.push_back(tr); /* _again0: AskString_ND(" Enter data file name without field: ",&buf); tr->m_sFileName = (const char*)buf;*/ tr->m_sFileName = (const char*)g_sInputTraj; mprintf(" Trying to open data file \"%s\"...\n",(const char*)g_sInputTraj); if ((mystricmp(GetFileExtension((const char*)g_sInputTraj),"bqb") != 0) && (mystricmp(GetFileExtension((const char*)g_sInputTraj),"emp") != 0) && (mystricmp(GetFileExtension((const char*)g_sInputTraj),"blist") != 0)) { eprintf("Error: File extension of data files should be .bqb, .emp, or .blist\n"); if (m_bPola) eprintf("Please start TRAVIS with the field-free data file generated in a gathering run before.\n"); else eprintf("Please start TRAVIS with the data file generated in a gathering run before.\n"); abort(); // goto _again0; } if (!tr->OpenFile()) { eprintf("Error while opening data file.\n"); if (m_bPola) eprintf("Please start TRAVIS with the field-free data file generated in a gathering run before.\n"); else eprintf("Please start TRAVIS with the data file generated in a gathering run before.\n"); abort(); // goto _again0; } if (tr->m_bBQB) steps = tr->m_pBQB->GetTotalFrameCount(); else steps = -1; if (!CheckTrajColumns(tr)) { eprintf("\nSome required properties were missing in the data file. Aborting.\n"); abort(); } if (m_bPola) { mprintf(" Polarizability calculation was requested. You need to supply the previously generated\n"); mprintf(" data files from the trajectories with external electric field.\n\n"); for (z=0;z<(m_bAniso?3:1);z++) { for (z2=0;z2<(m_bCentral?2:1);z2++) { tr = new CROATrajectory; tr->SetHistory(1); i = z*2+z2+1; m_iaTrajKinds[i] = (int)m_iaInvTrajKinds.size(); m_iaInvTrajKinds.push_back(i); m_oaTrajectories.push_back(tr); _again: AskString_ND(" Enter data file name for field %c%s: ", &buf,'X'+z,m_bCentral?((z2==0)?" positive":" negative"):""); tr->m_sFileName = (const char*)buf; if ((mystricmp(GetFileExtension((const char*)buf),"bqb") != 0) && (mystricmp(GetFileExtension((const char*)buf),"emp") != 0) && (mystricmp(GetFileExtension((const char*)buf),"blist") != 0)) { eprintf("Error: File extension of data files is .bqb, .emp, or .blist\n\n"); goto _again; } if (!tr->OpenFile()) goto _again; if (tr->m_bBQB) if ((steps != -1) && (tr->m_pBQB->GetTotalFrameCount() != -1) && (tr->m_pBQB->GetTotalFrameCount() != steps)) eprintf("Warning: Step count (%d) differs from first data file (%d).\n", tr->m_pBQB->GetTotalFrameCount(),steps); if (!CheckTrajColumns(tr)) { eprintf("\nSome required properties were missing in the data file. Aborting.\n"); abort(); } } } } /* if (steps != -1) mprintf("\n First trajectory contains %d steps. Good.\n",steps); else mprintf("\n No index, could not determine step count.\n"); */ mprintf(" Rewinding trajectories...\n"); for (z=0;z<(int)m_oaTrajectories.size();z++) m_oaTrajectories[z]->Rewind(); /* if (g_pBQBEngine != NULL) { if (g_pBQBEngine->m_pExtrapolator != NULL) g_pBQBEngine->m_pExtrapolator->Clear(); if (g_pBQBEngine->m_pExtrapolatorCorr != NULL) g_pBQBEngine->m_pExtrapolatorCorr->Clear(); if (g_pBQBEngine->m_pExtrapolatorXYZ != NULL) g_pBQBEngine->m_pExtrapolatorXYZ->Clear(); }*/ mprintf("\n Reading first time step from %d trajectories...\n",(int)m_oaTrajectories.size()); g_bVoroIntegrateCharge = true; g_bVoroIntegrateDipoleMoment = true; g_bVoroIntegrateQuadrupoleMoment = true; if (m_bMagMom) { g_bVoroIntegrateTotalCurrent = true; g_bVoroIntegrateMagneticMoment = true; g_bCubeTimeDev = true; g_bUseVelocities = true; } else { g_bVoroIntegrateTotalCurrent = false; g_bVoroIntegrateMagneticMoment = false; g_bCubeTimeDev = false; g_bUseVelocities = false; } for (z=0;z<(int)m_oaTrajectories.size();z++) { mprintf(" %s ...\n",m_oaTrajectories[z]->m_sFileName.c_str()); if (!m_oaTrajectories[z]->ReadTimeStep()) { eprintf("Error: Could not read time step.\n"); abort(); } for (z2=0;z2m_oaMolecules.push_back(rm); } } for (z=0;zm_iDipoleMode = 7; if (m_bMagMom) ((CMolecule*)g_oaMolecules[z])->m_iMagneticDipoleMode = 7; } mprintf("\n Computing dipole moment of first molecule from first time step of each trajectory...\n"); mprintf("\n"); for (z=0;z<(int)m_oaTrajectories.size();z++) { mprintf(" Trajectory %d: ",z+1); m_oaTrajectories[z]->GetTimeStep(1)->CalcDipoles(false); CMolecule *m = (CMolecule *)g_oaMolecules[0]; mprintf("( %12.8f | %12.8f | %12.8f ) Debye.\n", ((CSingleMolecule *)g_oaSingleMolecules[m->m_laSingleMolIndex[0]])->m_vDipole[0], ((CSingleMolecule *)g_oaSingleMolecules[m->m_laSingleMolIndex[0]])->m_vDipole[1], ((CSingleMolecule *)g_oaSingleMolecules[m->m_laSingleMolIndex[0]])->m_vDipole[2] ); va.Add(((CSingleMolecule*)g_oaSingleMolecules[m->m_laSingleMolIndex[0]])->m_vDipole); } mprintf("\n"); if (m_bPola && m_bCentral) { mprintf(" Checking symmetry of finite differences (should be all around 0.5)...\n"); for (z=0;z<(m_bAniso?3:1);z++) mprintf(" Field +/- %c: ( %10.8f | %10.8f | %10.8f )\n", 'X'+z, (va[0][0]-va[z*2+2][0])/(va[z*2+1][0]-va[z*2+2][0]), (va[0][1]-va[z*2+2][1])/(va[z*2+1][1]-va[z*2+2][1]), (va[0][2]-va[z*2+2][2])/(va[z*2+1][2]-va[z*2+2][2]) ); mprintf("\n"); } } if (m_iMode == ROA_MODE_COMBINED) { mprintf("\n"); if (m_bPola) mprintf(" Assuming that TRAVIS was started with the field-free trajectory.\n\n"); tr = new CROATrajectory; if (m_bMagMom) tr->SetHistory(3); else tr->SetHistory(1); m_iaTrajKinds[0] = (int)m_iaInvTrajKinds.size(); m_iaInvTrajKinds.push_back(0); m_oaTrajectories.push_back(tr); /* _again0b: AskString_ND(" Enter trajectory file name without field: ",&buf); tr->m_sFileName = (const char*)buf;*/ tr->m_sFileName = (const char*)g_sInputTraj; mprintf(" Trying to open volumetric trajectory file \"%s\"...\n",(const char*)g_sInputTraj); if (!tr->OpenFile()) { eprintf("Error while opening volumetric trajectory file.\n"); if (m_bPola) eprintf("Please start TRAVIS with the field-free volumetric trajectory file.\n"); else eprintf("Please start TRAVIS with the volumetric trajectory file.\n"); abort(); // goto _again0b; } if (tr->m_bBQB) steps = tr->m_pBQB->GetTotalFrameCount(); else steps = -1; if (m_bPola) { mprintf("\n"); mprintf(" Polarizability calculation was requested. You need to supply the\n"); mprintf(" volumetric data trajectories with external electric field.\n\n"); for (z=0;z<(m_bAniso?3:1);z++) { for (z2=0;z2<(m_bCentral?2:1);z2++) { tr = new CROATrajectory; if (m_bMagMom) tr->SetHistory(3); else tr->SetHistory(1); i = z*2+z2+1; m_iaTrajKinds[i] = (int)m_iaInvTrajKinds.size(); m_iaInvTrajKinds.push_back(i); m_oaTrajectories.push_back(tr); _againb: AskString_ND(" Enter trajectory file name for field %c%s: ", &buf,'X'+z,m_bCentral?((z2==0)?" positive":" negative"):""); tr->m_sFileName = (const char*)buf; if (!tr->OpenFile()) goto _againb; if (tr->m_bBQB) if ((steps != -1) && (tr->m_pBQB->GetTotalFrameCount() != -1) && (tr->m_pBQB->GetTotalFrameCount() != steps)) { eprintf("Warning: Step count (%d) differs from first trajectory (%d).\n", tr->m_pBQB->GetTotalFrameCount(),steps); //return false; } } } } /* if (steps != -1) mprintf("\n First trajectory contains %d steps. Good.\n",steps); else mprintf("\n No index, could not determine step count.\n"); */ mprintf("\n Reading first time step from %d trajectories...\n",(int)m_oaTrajectories.size()); for (z=0;z<(int)m_oaTrajectories.size();z++) { mprintf(" %s ... ",m_oaTrajectories[z]->m_sFileName.c_str()); if (!m_oaTrajectories[z]->ReadTimeStep()) { eprintf("Error: Could not read time step.\n"); abort(); } mprintf("%d x %d x %d bins, %9.4f x %9.4f x %9.4f pm.\n", m_oaTrajectories[z]->GetTimeStep(1)->m_pVolumetricData->m_iRes[0], m_oaTrajectories[z]->GetTimeStep(1)->m_pVolumetricData->m_iRes[1], m_oaTrajectories[z]->GetTimeStep(1)->m_pVolumetricData->m_iRes[2], m_oaTrajectories[z]->GetTimeStep(1)->m_pVolumetricData->m_fMaxVal[0], m_oaTrajectories[z]->GetTimeStep(1)->m_pVolumetricData->m_fMaxVal[1], m_oaTrajectories[z]->GetTimeStep(1)->m_pVolumetricData->m_fMaxVal[2]); for (z2=0;z2m_oaMolecules.push_back(rm); } } for (z=0;zm_iDipoleMode = 7; if (m_bMagMom) ((CMolecule*)g_oaMolecules[z])->m_iMagneticDipoleMode = 7; } g_bVoroIntegrateCharge = true; g_bVoroIntegrateDipoleMoment = true; g_bVoroIntegrateQuadrupoleMoment = true; g_bVoroIntegrateTotalCurrent = false; g_bVoroIntegrateMagneticMoment = false; g_bCubeTimeDev = false; mprintf(" Setting up Voronoi integration...\n"); if (!PrepareVori(m_oaTrajectories[0]->GetTimeStep(1),true,true,true)) { eprintf("Error while setting up Voronoi integration.\n"); return false; } mprintf("\n Computing dipole moment of first molecule from first time step of each trajectory...\n"); mprintf("\n"); for (z=0;z<(int)m_oaTrajectories.size();z++) { mprintf(" Trajectory %d: ",z+1); g_pTetraPak->ProcessStep(m_oaTrajectories[z]->GetTimeStep(1),false); m_oaTrajectories[z]->GetTimeStep(1)->CalcDipoles(false); CMolecule *m = (CMolecule *)g_oaMolecules[0]; mprintf("( %12.8f | %12.8f | %12.8f ) Debye.\n", ((CSingleMolecule *)g_oaSingleMolecules[m->m_laSingleMolIndex[0]])->m_vDipole[0], ((CSingleMolecule *)g_oaSingleMolecules[m->m_laSingleMolIndex[0]])->m_vDipole[1], ((CSingleMolecule *)g_oaSingleMolecules[m->m_laSingleMolIndex[0]])->m_vDipole[2] ); va.Add(((CSingleMolecule*)g_oaSingleMolecules[m->m_laSingleMolIndex[0]])->m_vDipole); } mprintf("\n"); if (m_bPola && m_bCentral) { mprintf(" Checking symmetry of finite differences (should be all around 0.5)...\n"); for (z=0;z<(m_bAniso?3:1);z++) mprintf(" Field +/- %c: ( %10.8f | %10.8f | %10.8f )\n", 'X'+z, (va[0][0]-va[z*2+2][0])/(va[z*2+1][0]-va[z*2+2][0]), (va[0][1]-va[z*2+2][1])/(va[z*2+1][1]-va[z*2+2][1]), (va[0][2]-va[z*2+2][2])/(va[z*2+1][2]-va[z*2+2][2]) ); mprintf("\n"); } g_bVoroIntegrateCharge = true; g_bVoroIntegrateDipoleMoment = true; g_bVoroIntegrateQuadrupoleMoment = true; if (m_bMagMom) { g_bVoroIntegrateTotalCurrent = true; g_bVoroIntegrateMagneticMoment = true; g_bCubeTimeDev = true; g_bUseVelocities = true; } else { g_bVoroIntegrateTotalCurrent = false; g_bVoroIntegrateMagneticMoment = false; g_bCubeTimeDev = false; g_bUseVelocities = false; } } mprintf(WHITE,"\n <<< New Spectroscopy Module <<<\n\n"); return true; } void CROAEngine::MainLoop() { if (m_iMode == ROA_MODE_COMBINED) MainLoop_Combined(); else if (m_iMode == ROA_MODE_GATHER) MainLoop_Gather(); else if (m_iMode == ROA_MODE_ANALYZE) MainLoop_Analyze(); } void CROAEngine::MainLoop_Combined() { int z, z2, tsteps; unsigned long eta, t0; double tfs; CROATrajectory *tr; CTimeStep *ts, tts; CxString buf; CROAMolecule *rm; CSingleMolecule *sm; mprintf(WHITE,"\n >>> Processing Trajectories - Combined Mode >>>\n\n"); for (z=0;z<(int)m_oaTrajectories.size();z++) { tr = m_oaTrajectories[z]; mprintf(WHITE,"*** Processing trajectory %d / %d ***\n\n", z+1,(int)m_oaTrajectories.size()); mprintf(" Rewinding trajectory...\n"); tr->Rewind(); /* if (g_pBQBEngine != NULL) { if (g_pBQBEngine->m_pExtrapolator != NULL) g_pBQBEngine->m_pExtrapolator->Clear(); if (g_pBQBEngine->m_pExtrapolatorCorr != NULL) g_pBQBEngine->m_pExtrapolatorCorr->Clear(); if (g_pBQBEngine->m_pExtrapolatorXYZ != NULL) g_pBQBEngine->m_pExtrapolatorXYZ->Clear(); }*/ if (m_bMagMom) tr->m_vaAtomVelocities.resize(g_iGesAtomCount); if (g_iBeginStep != 0) { mprintf(" Fast-forwarding to step %d...\n",g_iBeginStep+1); if (tr->m_bBQB) { if (!tr->m_pBQB->SeekFrame(g_iBeginStep)) { eprintf(" Error while fast-forwarding trajectory (BQB).\n"); return; } } else { mprintf(WHITE," ["); tfs = g_iBeginStep/60.0; for (z2=0;z2m_pFile)) { eprintf(" Error while fast-forwarding trajectory (CUBE).\n"); return; } if (fmod(z2,tfs) < 1) mprintf(WHITE,"#"); } mprintf(WHITE,"]"); mprintf("\n"); } } tsteps = 0; if (m_bMagMom) { mprintf("\n"); mprintf(" Reading first 2 time steps for finite differences...\n"); tsteps += 2; for (z2=0;z2<2;z2++) if (!tr->ReadTimeStep()) return; if (z == 0) PrepareCurrentDensity( tr->GetTimeStep(1), tr->GetTimeStep(1), true ); else PrepareCurrentDensity( tr->GetTimeStep(1), tr->GetTimeStep(1), false ); PrepareCurrentDensity( tr->GetTimeStep(0), tr->GetTimeStep(1), false ); PrepareCurrentDensity( tr->GetTimeStep(-1), tr->GetTimeStep(1), false ); } mprintf("\n"); mprintf(" Starting run...\n\n"); t0 = (unsigned long)time(NULL); g_iSteps = 0; while (true) { mprintf(" Step %5lu",g_iSteps+1); if ((g_iSteps != 0) && (g_iTrajSteps > 0) && ((time(NULL) - t0) > 5)) { eta = (unsigned long)(((double)time(NULL) - t0) / tsteps * ((double)MAX(long(0),g_iTrajSteps - ((long)tsteps)))); FormatTime(eta,&buf); mprintf(": ETA %s",(const char*)buf); } mprintf("\n"); if ((g_iStride != 1) && (g_iSteps != 0)) { tsteps += g_iStride-1; mprintf(" Skipping steps "); mprintf("["); if (g_iStride > 4) { for (z2=0;z2SkipTimeStep()) { mprintf("\n Reached end of file.\n"); goto _end; } mprintf("S"); } for (z2=0;z2<2;z2++) { if (!tr->ReadTimeStep()) { mprintf("\n Reached end of file.\n"); goto _end; } mprintf("R"); } } else if (g_iStride == 4) { if (!tr->SkipTimeStep()) { mprintf("\n Reached end of file.\n"); goto _end; } mprintf("S"); for (z2=0;z2<2;z2++) { if (!tr->ReadTimeStep()) { mprintf("\n Reached end of file.\n"); goto _end; } mprintf("R"); } } else if (g_iStride == 3) { for (z2=0;z2<2;z2++) { if (!tr->ReadTimeStep()) { mprintf("\n Reached end of file.\n"); goto _end; } mprintf("R"); } } else if (g_iStride == 2) { if (!tr->ReadTimeStep()) { mprintf("\n Reached end of file.\n"); goto _end; } mprintf("R"); } mprintf("]\n"); } if ((g_iMaxStep > 0) && (tsteps >= g_iMaxStep)) { mprintf("\nReached step limit.\n"); break; } mprintf(" Reading step...\n"); if (!tr->ReadTimeStep()) { mprintf("\n Reached end of file.\n"); break; } tsteps++; if (m_bMagMom) { tr->CalcVelocities(); mprintf(" Current "); CalculateCurrentDensity(tr->GetTimeStep(-1),tr->GetTimeStep(0),tr->GetTimeStep(1),g_iSteps==0); mprintf("\n"); } ts = tr->GetTimeStep(0); mprintf(" Integrating...\n"); g_pTetraPak->ProcessStep(ts,false); if (m_bMagMom) ts->CalcCenterVelocities(); ts->CalcDipoles(false); if (m_bMagMom) ts->CalcMagneticDipoles(); for (z2=0;z2m_oaMolecules[z2]; sm = (CSingleMolecule*)g_oaSingleMolecules[z2]; rm->m_faCharge.push_back(sm->m_fCharge); // Unit: e rm->m_vaElDip.push_back(sm->m_vDipole); // Unit: Debye rm->m_maElQuad.push_back(sm->m_mQuadrupole); // Unit: Debye*pm if (m_bMagMom) { rm->m_vaElCurr.push_back(sm->m_vCurrent); // Unit: MB/pm rm->m_vaMagDip.push_back(sm->m_vMagneticDipole); // Unit: MB } } if (m_bMagMom) for (z2=0;z2m_vaAtomVelocities[z2].Add(ts->m_vaVelocities[z2]); g_iSteps++; if ((g_iMaxStep > 0) && (tsteps >= g_iMaxStep)) { mprintf("\n Reached step limit.\n"); break; } } _end: if (g_iStride != 1) mprintf("\n Processed %lu steps out of %d input steps.\n\n",g_iSteps,tsteps); else mprintf("\n Processed %lu steps.\n\n",g_iSteps); for (z2=0;z2<(int)tr->m_oaTSHistory.size();z2++) delete tr->m_oaTSHistory[z2]; tr->m_oaTSHistory.clear(); m_iStepsProcessed = (int)tr->m_oaMolecules[0]->m_faCharge.size(); } mprintf(WHITE," Finished processing %d trajectories:\n\n",(int)m_oaTrajectories.size()); for (z=0;z<(int)m_oaTrajectories.size();z++) mprintf(" Trajectory %d: %d steps.\n",z+1,(int)m_oaTrajectories[z]->m_oaMolecules[0]->m_faCharge.size()); for (z=0;z<(int)m_oaTrajectories.size();z++) { if ((int)m_oaTrajectories[z]->m_oaMolecules[0]->m_faCharge.size() != m_iStepsProcessed) { eprintf("\nError: Step count of trajectories does not match.\n"); abort(); } } mprintf(WHITE,"\n <<< Processing Trajectories - Combined Mode <<<\n\n"); Finish(); } void CROAEngine::MainLoop_Analyze() { int z, z2, z3, tsteps; unsigned long eta, t0; CxString buf; CROATrajectory *tr; CTimeStep *ts; CROAMolecule *rm; CSingleMolecule *sm; FILE *a; mprintf(WHITE,"\n >>> Processing Trajectories - Analyze >>>\n\n"); if (m_bDumpMolecularProps) { for (z=0;z<(int)m_oaTrajectories.size();z++) { buf.sprintf("bqb_molecular_integrals_traj%d.csv",z+1); a = OpenFileWrite((const char*)buf, true); mfprintf(a,"#Step; Molecule; SingleMolecule; Charge; ElDipX; ElDipY; ElDipZ; ElQuadXX; ElQuadXY; ElQuadXZ; ElQuadYX; ElQuadYY; ElQuadYZ; ElQuadZX; ElQuadZY; ElQuadZZ"); if (m_bMagMom) mfprintf(a,"; ElCurrX; ElCurrY; ElCurrZ; MagDipX; MagDipY; MagDipZ"); mfprintf(a,"\n"); fflush(a); m_fMolIntegralFiles.push_back(a); } } mprintf(" Rewinding trajectories...\n\n"); for (z=0;z<(int)m_oaTrajectories.size();z++) m_oaTrajectories[z]->Rewind(); /* if (g_pBQBEngine != NULL) { if (g_pBQBEngine->m_pExtrapolator != NULL) g_pBQBEngine->m_pExtrapolator->Clear(); if (g_pBQBEngine->m_pExtrapolatorCorr != NULL) g_pBQBEngine->m_pExtrapolatorCorr->Clear(); if (g_pBQBEngine->m_pExtrapolatorXYZ != NULL) g_pBQBEngine->m_pExtrapolatorXYZ->Clear(); }*/ if (g_iBeginStep != 0) { mprintf(" Fast-forwarding to step %d...\n",g_iBeginStep+1); for (z=0;z<(int)m_oaTrajectories.size();z++) { if (!m_oaTrajectories[z]->m_pBQB->SeekFrame(g_iBeginStep)) { eprintf(" Error while fast-forwarding trajectory %d (BQB).\n",z+1); return; } } } if (m_bMagMom) m_oaTrajectories[0]->m_vaAtomVelocities.resize(g_iGesAtomCount); m_oaTrajectories[0]->m_vaCOMCoord.resize(g_oaSingleMolecules.GetSize()); g_bVoroIntegrateCharge = true; g_bVoroIntegrateDipoleMoment = true; g_bVoroIntegrateQuadrupoleMoment = true; if (m_bMagMom) { g_bVoroIntegrateTotalCurrent = true; g_bVoroIntegrateMagneticMoment = true; g_bCubeTimeDev = true; g_bUseVelocities = true; } else { g_bVoroIntegrateTotalCurrent = false; g_bVoroIntegrateMagneticMoment = false; g_bCubeTimeDev = false; g_bUseVelocities = false; } t0 = (unsigned long)time(NULL); g_iSteps = 0; tsteps = 0; while (true) { if ((g_iSteps % 10) == 0) { if ((g_iSteps % 500) == 0) { if (g_iSteps != 0) { if ((g_iTrajSteps > 0) && ((time(NULL) - t0) > 5)) { eta = (unsigned long)(((double)time(NULL) - t0) / tsteps * ((double)MAX(long(0),g_iTrajSteps - ((long)tsteps)))); FormatTime(eta,&buf); mprintf(" ETA %s\nStep %5lu ",(const char*)buf,g_iSteps); } else mprintf("\nStep %5lu ",g_iSteps); } else mprintf("Step %5d ",1); } else mprintf("."); } if ((g_iStride != 1) && (g_iSteps != 0)) { tsteps += g_iStride-1; for (z=0;zGetTimeStep(1); if (m_bMagMom) ts->CalcCenterVelocities(); ts->CalcDipoles(false); if (m_bMagMom) ts->CalcMagneticDipoles(); if (m_bDumpMolecularProps) { g_fMolIntegralFile = m_fMolIntegralFiles[z]; DumpMolecularProps(); } for (z2=0;z2m_oaMolecules[z2]; sm = (CSingleMolecule*)g_oaSingleMolecules[z2]; rm->m_faCharge.push_back(sm->m_fCharge); // Unit: e rm->m_vaElDip.push_back(sm->m_vDipole); // Unit: Debye rm->m_maElQuad.push_back(sm->m_mQuadrupole); // Unit: Debye*pm if (m_bMagMom) { rm->m_vaElCurr.push_back(sm->m_vCurrent); // Unit: MB/pm rm->m_vaMagDip.push_back(sm->m_vMagneticDipole); // Unit: MB } } } ts = m_oaTrajectories[0]->GetTimeStep(1); for (z2=0;z2m_vaCOMCoord[z2].Add(ts->m_vaCoords[((CxIntArray*)sm->m_oaAtomOffset[sm->m_baAtomIndex.GetSize()-1])->GetAt(1)]); } if (m_bMagMom) for (z2=0;z2m_vaAtomVelocities[z2].Add(ts->m_vaVelocities[z2]); g_iSteps++; if ((g_iMaxStep > 0) && (tsteps >= g_iMaxStep)) { mprintf("\nReached step limit.\n"); break; } } _end: if (g_iStride != 1) mprintf("\nProcessed %lu steps out of %d input steps.\n\n",g_iSteps,tsteps); else mprintf("\nProcessed %lu steps.\n\n",g_iSteps); m_iStepsProcessed = g_iSteps; if (m_bDumpMolecularProps) { mprintf(" Molecular properties have been written to the following files:\n"); for (z=0;z<(int)m_oaTrajectories.size();z++) { mprintf(" bqb_molecular_integrals_traj%d.csv\n",z+1); fclose(m_fMolIntegralFiles[z]); } m_fMolIntegralFiles.clear(); } if (m_bReverseTraj) { mprintf("\n Reversing direction of input trajectory...\n"); for (z=0;z<(int)m_oaTrajectories.size();z++) { tr = m_oaTrajectories[z]; for (z2=0;z2m_oaMolecules[z2]; std::reverse(rm->m_faCharge.begin(),rm->m_faCharge.end()); std::reverse(rm->m_vaElDip.begin(),rm->m_vaElDip.end()); std::reverse(rm->m_maElQuad.begin(),rm->m_maElQuad.end()); if (m_bMagMom) { std::reverse(rm->m_vaElCurr.begin(),rm->m_vaElCurr.end()); std::reverse(rm->m_vaMagDip.begin(),rm->m_vaMagDip.end()); for (z3=0;z3<(int)rm->m_vaElCurr.size();z3++) rm->m_vaElCurr[z3] *= -1.0; for (z3=0;z3<(int)rm->m_vaMagDip.size();z3++) rm->m_vaMagDip[z3] *= -1.0; } } } } mprintf(WHITE,"\n <<< Processing Trajectories - Analyze <<<\n\n"); Finish(); } void CROAEngine::MainLoop_Gather() { int z, z2, z3, tsteps; unsigned long eta, t0; double tfs; CxString buf; FILE *a; CBQBFile *bqwrite; CBQBTrajectoryFrame *btf; CBQBTrajectoryFrameColumn *bco; CTimeStep *ts, tts; std::vector ia; a = NULL; mprintf(WHITE,"\n >>> Processing Trajectory - Gather >>>\n\n"); mprintf(" Rewinding trajectory...\n"); m_oaTrajectories[0]->Rewind(); /* if (g_pBQBEngine != NULL) { if (g_pBQBEngine->m_pExtrapolator != NULL) g_pBQBEngine->m_pExtrapolator->Clear(); if (g_pBQBEngine->m_pExtrapolatorCorr != NULL) g_pBQBEngine->m_pExtrapolatorCorr->Clear(); if (g_pBQBEngine->m_pExtrapolatorXYZ != NULL) g_pBQBEngine->m_pExtrapolatorXYZ->Clear(); }*/ if (g_iBeginStep != 0) { mprintf(" Fast-forwarding to step %d...\n",g_iBeginStep+1); if (m_oaTrajectories[0]->m_bBQB) { if (!m_oaTrajectories[0]->m_pBQB->SeekFrame(g_iBeginStep)) { eprintf(" Error while fast-forwarding trajectory (BQB).\n"); return; } } else { mprintf(WHITE," ["); tfs = g_iBeginStep/60.0; for (z2=0;z2m_pFile)) { eprintf(" Error while fast-forwarding trajectory (CUBE).\n"); return; } if (fmod(z2,tfs) < 1) mprintf(WHITE,"#"); } mprintf(WHITE,"]"); mprintf("\n"); } } tsteps = 0; if (m_bMagMom) { mprintf(" Reading first 2 time steps for finite differences...\n"); tsteps += 2; for (z=0;z<2;z++) if (!ReadStep(true)) return; mprintf("\n"); if (g_iTrajSteps != -1) mprintf(" Starting run (%d remaining steps)...\n\n",g_iTrajSteps-2); else mprintf(" Starting run...\n\n"); } else { if (g_iTrajSteps != -1) mprintf(" Starting run (%d steps)...\n\n",g_iTrajSteps); else mprintf(" Starting run...\n\n"); } bqwrite = new CBQBFile(*g_pBQBInterface); bqwrite->OpenWriteReplace("properties.emp"); btf = new CBQBTrajectoryFrame(*g_pBQBInterface); btf->m_iAtomCount = g_iGesAtomCount; btf->AddColumn(BQB_TYPE_STRING,"Label"); btf->AddColumn(BQB_TYPE_DOUBLE,"PosX"); // Unit: pm btf->AddColumn(BQB_TYPE_DOUBLE,"PosY"); // Unit: pm btf->AddColumn(BQB_TYPE_DOUBLE,"PosZ"); // Unit: pm if (m_bMagMom) { btf->AddColumn(BQB_TYPE_DOUBLE,"VelX"); // Unit: pm/ps btf->AddColumn(BQB_TYPE_DOUBLE,"VelY"); // Unit: pm/ps btf->AddColumn(BQB_TYPE_DOUBLE,"VelZ"); // Unit: pm/ps } btf->AddColumn(BQB_TYPE_DOUBLE,"EChg"); // Unit: e btf->AddColumn(BQB_TYPE_DOUBLE,"EDipX"); // Unit: e*pm btf->AddColumn(BQB_TYPE_DOUBLE,"EDipY"); // Unit: e*pm btf->AddColumn(BQB_TYPE_DOUBLE,"EDipZ"); // Unit: e*pm btf->AddColumn(BQB_TYPE_DOUBLE,"EQXX"); // Unit: e*nm^2 btf->AddColumn(BQB_TYPE_DOUBLE,"EQXY"); // Unit: e*nm^2 btf->AddColumn(BQB_TYPE_DOUBLE,"EQXZ"); // Unit: e*nm^2 btf->AddColumn(BQB_TYPE_DOUBLE,"EQYX"); // Unit: e*nm^2 btf->AddColumn(BQB_TYPE_DOUBLE,"EQYY"); // Unit: e*nm^2 btf->AddColumn(BQB_TYPE_DOUBLE,"EQYZ"); // Unit: e*nm^2 btf->AddColumn(BQB_TYPE_DOUBLE,"EQZX"); // Unit: e*nm^2 btf->AddColumn(BQB_TYPE_DOUBLE,"EQZY"); // Unit: e*nm^2 btf->AddColumn(BQB_TYPE_DOUBLE,"EQZZ"); // Unit: e*nm^2 if (m_bMagMom) { btf->AddColumn(BQB_TYPE_DOUBLE,"ECurX"); // Unit: MB/pm btf->AddColumn(BQB_TYPE_DOUBLE,"ECurY"); // Unit: MB/pm btf->AddColumn(BQB_TYPE_DOUBLE,"ECurZ"); // Unit: MB/pm btf->AddColumn(BQB_TYPE_DOUBLE,"MDipX"); // Unit: MB btf->AddColumn(BQB_TYPE_DOUBLE,"MDipY"); // Unit: MB btf->AddColumn(BQB_TYPE_DOUBLE,"MDipZ"); // Unit: MB } btf->m_oaColumns[0]->m_aString.resize(g_iGesAtomCount); for (z=1;z<(int)btf->m_oaColumns.size();z++) btf->m_oaColumns[z]->m_aReal.resize(g_iGesAtomCount); btf->m_pCellMatrix = new CxDMatrix3(); for (z=0;z<9;z++) (*btf->m_pCellMatrix)[z] = g_mBoxFromOrtho[z]; for (z=0;zm_oaColumns[0]->m_aString[z] = (const char*)m_oaTrajectories[0]->GetTimeStep(1)->m_paLabels[z]; if (m_bGatherWriteCSV) { a = OpenFileWrite("properties.csv",true); mfprintf(a,"#Step"); mfprintf(a,"; AtomID"); mfprintf(a,"; Label"); mfprintf(a,"; PosX; PosY; PosZ"); if (m_bMagMom) mfprintf(a,"; VelX; VelY; VelZ"); mfprintf(a,"; Charge"); mfprintf(a,"; ElDipX; ElDipY; ElDipZ"); mfprintf(a,"; ElQuadXX; ElQuadXY; ElQuadXZ; ElQuadYX; ElQuadYY; ElQuadYZ; ElQuadZX; ElQuadZY; ElQuadZZ"); if (m_bMagMom) { mfprintf(a,"; ElCurrX; ElCurrY; ElCurrZ"); mfprintf(a,"; MagDipX; MagDipY; MagDipZ"); } mfprintf(a,"\n"); } g_bVoroIntegrateCharge = true; g_bVoroIntegrateDipoleMoment = true; g_bVoroIntegrateQuadrupoleMoment = true; if (m_bMagMom) { g_bVoroIntegrateTotalCurrent = true; g_bVoroIntegrateMagneticMoment = true; g_bCubeTimeDev = true; } else { g_bVoroIntegrateTotalCurrent = false; g_bVoroIntegrateMagneticMoment = false; g_bCubeTimeDev = false; } t0 = (unsigned long)time(NULL); g_iSteps = 0; while (true) { mprintf(" Step %5lu",g_iSteps+1); if ((g_iSteps != 0) && (g_iTrajSteps > 0)) { eta = (unsigned long)(((double)time(NULL) - t0) / tsteps * ((double)MAX(long(0),g_iTrajSteps - tsteps))); FormatTime(eta,&buf); mprintf(": ETA %s",(const char*)buf); } mprintf("\n"); if ((g_iStride != 1) && (g_iSteps != 0)) { mprintf(" Skipping steps "); mprintf("["); tsteps += g_iStride-1; if (g_iStride > 4) { for (z2=0;z2 0) && (tsteps >= g_iMaxStep)) { mprintf("\nReached step limit.\n"); break; } if (!ReadStep(true)) { mprintf("\nReached end of file.\n"); break; } tsteps++; if (m_bMagMom) { this->CalcVelocities(); mprintf(" Current "); CalculateCurrentDensity(m_oaTrajectories[0]->GetTimeStep(-1),m_oaTrajectories[0]->GetTimeStep(0),m_oaTrajectories[0]->GetTimeStep(1),false); mprintf("\n"); } ts = m_oaTrajectories[0]->GetTimeStep(0); mprintf(" Integrating...\n"); g_pTetraPak->ProcessStep(ts,false); if (m_bGatherWriteCSV) { for (z=0;zm_paLabels[z]); mfprintf(a,"; %17.10f; %17.10f; %17.10f", ts->m_vaCoords[z][0], ts->m_vaCoords[z][1], ts->m_vaCoords[z][2] ); if (m_bMagMom) mfprintf(a,"; %17.10f; %17.10f; %17.10f", ts->m_vaVelocities[z][0], ts->m_vaVelocities[z][1], ts->m_vaVelocities[z][2] ); mfprintf(a,"; %17.10f",ts->m_faCharge[z]); mfprintf(a,"; %17.10f; %17.10f; %17.10f", ts->m_dipoleMoments[z][0], ts->m_dipoleMoments[z][1], ts->m_dipoleMoments[z][2] ); mfprintf(a,"; %17.10f; %17.10f; %17.10f; %17.10f; %17.10f; %17.10f; %17.10f; %17.10f; %17.10f", ts->m_maQuadTensor[z][0], ts->m_maQuadTensor[z][1], ts->m_maQuadTensor[z][2], ts->m_maQuadTensor[z][3], ts->m_maQuadTensor[z][4], ts->m_maQuadTensor[z][5], ts->m_maQuadTensor[z][6], ts->m_maQuadTensor[z][7], ts->m_maQuadTensor[z][8] ); if (m_bMagMom) { mfprintf(a,"; %17.10f; %17.10f; %17.10f", ts->m_totalCurrents[z][0], ts->m_totalCurrents[z][1], ts->m_totalCurrents[z][2] ); mfprintf(a,"; %17.10f; %17.10f; %17.10f", ts->m_magneticDipoleMoments[z][0], ts->m_magneticDipoleMoments[z][1], ts->m_magneticDipoleMoments[z][2] ); } mfprintf(a,"\n"); } fflush(a); } bco = btf->GetColumn("PosX"); for (z=0;zm_aReal[z] = ts->m_vaCoords[z][0]; bco = btf->GetColumn("PosY"); for (z=0;zm_aReal[z] = ts->m_vaCoords[z][1]; bco = btf->GetColumn("PosZ"); for (z=0;zm_aReal[z] = ts->m_vaCoords[z][2]; if (m_bMagMom) { bco = btf->GetColumn("VelX"); for (z=0;zm_aReal[z] = ts->m_vaVelocities[z][0]; bco = btf->GetColumn("VelY"); for (z=0;zm_aReal[z] = ts->m_vaVelocities[z][1]; bco = btf->GetColumn("VelZ"); for (z=0;zm_aReal[z] = ts->m_vaVelocities[z][2]; } bco = btf->GetColumn("EChg"); for (z=0;zm_aReal[z] = ts->m_faCharge[z]; bco = btf->GetColumn("EDipX"); for (z=0;zm_aReal[z] = ts->m_dipoleMoments[z][0]; bco = btf->GetColumn("EDipY"); for (z=0;zm_aReal[z] = ts->m_dipoleMoments[z][1]; bco = btf->GetColumn("EDipZ"); for (z=0;zm_aReal[z] = ts->m_dipoleMoments[z][2]; bco = btf->GetColumn("EQXX"); for (z=0;zm_aReal[z] = ts->m_maQuadTensor[z][0]; bco = btf->GetColumn("EQXY"); for (z=0;zm_aReal[z] = ts->m_maQuadTensor[z][1]; bco = btf->GetColumn("EQXZ"); for (z=0;zm_aReal[z] = ts->m_maQuadTensor[z][2]; bco = btf->GetColumn("EQYX"); for (z=0;zm_aReal[z] = ts->m_maQuadTensor[z][3]; bco = btf->GetColumn("EQYY"); for (z=0;zm_aReal[z] = ts->m_maQuadTensor[z][4]; bco = btf->GetColumn("EQYZ"); for (z=0;zm_aReal[z] = ts->m_maQuadTensor[z][5]; bco = btf->GetColumn("EQZX"); for (z=0;zm_aReal[z] = ts->m_maQuadTensor[z][6]; bco = btf->GetColumn("EQZY"); for (z=0;zm_aReal[z] = ts->m_maQuadTensor[z][7]; bco = btf->GetColumn("EQZZ"); for (z=0;zm_aReal[z] = ts->m_maQuadTensor[z][8]; if (m_bMagMom) { bco = btf->GetColumn("ECurX"); for (z=0;zm_aReal[z] = ts->m_totalCurrents[z][0]; bco = btf->GetColumn("ECurY"); for (z=0;zm_aReal[z] = ts->m_totalCurrents[z][1]; bco = btf->GetColumn("ECurZ"); for (z=0;zm_aReal[z] = ts->m_totalCurrents[z][2]; bco = btf->GetColumn("MDipX"); for (z=0;zm_aReal[z] = ts->m_magneticDipoleMoments[z][0]; bco = btf->GetColumn("MDipY"); for (z=0;zm_aReal[z] = ts->m_magneticDipoleMoments[z][1]; bco = btf->GetColumn("MDipZ"); for (z=0;zm_aReal[z] = ts->m_magneticDipoleMoments[z][2]; } ia.clear(); btf->WriteFrame(&ia); bqwrite->CreateShortFrame(BQB_FRAMETYPE_TRAJ,0,g_iSteps+1); bqwrite->PushPayload(ia); bqwrite->FinalizeFrame(NULL); g_iSteps++; if ((g_iMaxStep > 0) && (tsteps >= g_iMaxStep)) { mprintf("\nReached step limit.\n"); break; } } _end: if (g_iStride != 1) mprintf("\nProcessed %lu steps out of %d input steps.\n\n",g_iSteps,tsteps); else mprintf("\nProcessed %lu steps.\n\n",g_iSteps); mprintf("Writing BQB index...\n"); bqwrite->WriteIndexFrame(true,NULL); bqwrite->Close(); delete bqwrite; delete btf; mprintf("Finished writing BQB file.\n\n"); if (m_bGatherWriteCSV) fclose(a); if (m_bGatherCheck) { mprintf("Now re-opening BQB file to check.\n"); bqwrite = new CBQBFile(*g_pBQBInterface); bqwrite->OpenRead("properties.emp"); btf = new CBQBTrajectoryFrame(*g_pBQBInterface); a = OpenFileWrite("properties_out.csv",true); z = 0; while (bqwrite->ReadFrame()) { if (bqwrite->GetFrameType() != BQB_FRAMETYPE_TRAJ) continue; mprintf("Frame %d...\n",z+1); btf->ReadFrame(bqwrite->GetFramePayload()); if (z == 0) { mfprintf(a,"#Step; AtomID"); for (z2=0;z2<(int)btf->m_oaColumns.size();z2++) mfprintf(a,"; %s",btf->m_oaColumns[z2]->m_sLabel.c_str()); mfprintf(a,"\n"); } for (z2=0;z2<(int)btf->m_iAtomCount;z2++) { mfprintf(a,"%6d; %4d",z+1,z2+1); mfprintf(a,"; %-3s",(const char*)btf->m_oaColumns[0]->m_aString[z2].c_str()); for (z3=1;z3<(int)btf->m_oaColumns.size();z3++) mfprintf(a,"; %17.10f",btf->m_oaColumns[z3]->m_aReal[z2]); mfprintf(a,"\n"); } fflush(a); z++; } fclose(a); bqwrite->Close(); delete bqwrite; delete btf; } mprintf(WHITE,"\n <<< Processing Trajectory - Gather <<<\n\n"); } CTimeStep* CROAEngine::GetROAStep(int traj, int step) { if (m_iaTrajKinds[traj] == -1) { eprintf("CROAEngine::GetROAStep(): Error: Trajectory %d not present.\n",traj); abort(); } return m_oaTrajectories[m_iaTrajKinds[traj]]->GetTimeStep(step); } bool CROAEngine::ReadStep(bool verbose) { int z; if (verbose) mprintf(" Reading ["); for (z=0;z<(int)m_oaTrajectories.size();z++) { if (!m_oaTrajectories[z]->ReadTimeStep()) { mprintf("\nCROAEngine::ReadStep(): Could not read further time step from trajectory %d (%s).\n", z+1,m_oaTrajectories[z]->m_sFileName.c_str()); return false; } if (verbose) mprintf("#"); } if (verbose) mprintf("]\n"); return true; } bool CROAEngine::SkipStep() { int z; for (z=0;z<(int)m_oaTrajectories.size();z++) { if (!m_oaTrajectories[z]->SkipTimeStep()) { mprintf("\nCROAEngine::SkipStep(): Could not skip further time step in trajectory %d (%s).\n", z+1,m_oaTrajectories[z]->m_sFileName.c_str()); return false; } } return true; } void CROAEngine::CalcVelocities() { int z; for (z=0;z<(int)m_oaTrajectories.size();z++) m_oaTrajectories[z]->CalcVelocities(); } void CROAEngine::Finish() { int z, z2, z3, o, ic; bool b, b2; double f, tfs, cfac; CROATrajectory *tn, *txp, *txn, *typ, *tyn, *tzp, *tzn; CROAMolecule *rn, *rxp, *rxn, *ryp, *ryn, *rzp, *rzn; FILE *a; CSmoothener smo; CAutoCorrelation *ac; CxDoubleArray dain, daout; CxDoubleArray daacf[64]; CxDoubleArray daspec[64]; CxDoubleArray *tda; CxString buf, buf2; CFFT *fft; std::vector temp; mprintf(WHITE,"\n >>> Finishing Analysis >>>\n\n"); if (m_fPDEInfo != NULL) fclose(m_fPDEInfo); b = false; tda = NULL; cfac = 0; ic = 0; a = NULL; tn=NULL; txp=NULL; txn=NULL; typ=NULL; tyn=NULL; tzp=NULL; tzn=NULL; rn=NULL; rxp=NULL; rxn=NULL; ryp=NULL; ryn=NULL; rzp=NULL; rzn=NULL; if (m_bPola) { if (m_bCentral && m_bAniso) { tn = m_oaTrajectories[0]; txp = m_oaTrajectories[1]; txn = m_oaTrajectories[2]; typ = m_oaTrajectories[3]; tyn = m_oaTrajectories[4]; tzp = m_oaTrajectories[5]; tzn = m_oaTrajectories[6]; } else if (!m_bCentral && m_bAniso) { tn = m_oaTrajectories[0]; txp = m_oaTrajectories[1]; typ = m_oaTrajectories[2]; tzp = m_oaTrajectories[3]; } else { eprintf("Error: Not yet implemented.\n"); return; } } else tn = m_oaTrajectories[0]; if (m_bMagMom) { mprintf(" Computing power spectrum of total system...\n"); ac = new CAutoCorrelation(); ac->Init(m_iStepsProcessed-2,m_oaObservations[0]->m_iDepth,g_bACFFFT); dain.SetSize(m_iStepsProcessed-2); daout.SetSize(m_oaObservations[0]->m_iDepth); fft = new CFFT(); fft->PrepareFFT_C2C(2*(m_oaObservations[0]->m_iDepth+m_oaObservations[0]->m_iZeroPadding)); temp.resize(2*(m_oaObservations[0]->m_iDepth+m_oaObservations[0]->m_iZeroPadding)); daacf[0].SetSize(m_oaObservations[0]->m_iDepth); for (z2=0;z2m_iDepth;z2++) daacf[0][z2] = 0; tfs = g_iGesAtomCount / 60.0; mprintf(WHITE," ["); for (z=0;zm_vaAtomVelocities[z][z2][z3]; ac->AutoCorrelate(&dain,&daout); for (z2=0;z2m_iDepth;z2++) daacf[0][z2] += daout[z2] * ((CAtom*)g_oaAtoms[g_waAtomRealElement[z]])->m_pElement->m_fMass; } } mprintf(WHITE,"]\n"); for (z3=0;z3m_iDepth;z3++) daacf[0][z3] /= (double)3*g_iGesAtomCount; for (z3=0;z3m_iDepth;z3++) temp[z3] = daacf[0][z3]; for (z3=m_oaObservations[0]->m_iDepth;z3m_iDepth+m_oaObservations[0]->m_iZeroPadding;z3++) temp[z3] = 0.0; for (z3=0;z3m_iDepth;z3++) temp[z3] *= pow2(cos((double)z3 / (m_oaObservations[0]->m_iDepth - 1) / 2.0 * Pi)); o = m_oaObservations[0]->m_iDepth+m_oaObservations[0]->m_iZeroPadding; for (z3=1;z3m_iDepth+m_oaObservations[0]->m_iZeroPadding);z3++) { fft->m_pInput[2*z3] = temp[z3]; fft->m_pInput[2*z3+1] = 0.0; } fft->DoFFT(); daspec[0].SetSize(m_oaObservations[0]->m_iSpecLength); for (z3=0;z3m_iSpecLength;z3++) daspec[0][z3] = fft->m_pOutput[2*z3]; for(z3 = 0; z3 < m_oaObservations[0]->m_iSpecLength; z3++) daspec[0][z3] *= 7.211349e-9 * g_fTimestepLength * g_iStride; // Output in K*cm delete ac; delete fft; mprintf(" Writing power spectrum to \"power_spectrum.csv\"...\n"); a = OpenFileWrite("power_spectrum.csv",true); mfprintf(a,"#Wavenumber [cm^-1]; Power Spectrum [K*cm]; Integral [K]\n"); f = 0; for (z=0;zm_iSpecLength;z++) { f += daspec[0][z] * m_oaObservations[0]->m_fSpecResolution; mfprintf(a,"%.2f; %.10G; %.10G\n",m_oaObservations[0]->m_fSpecResolution*z,daspec[0][z],f); } fclose(a); if (m_bWriteACFs || m_oaObservations[0]->m_bSaveACF) { mprintf(" Writing velocity autocorrelation function to \"power_vacf.csv\"...\n"); a = OpenFileWrite("power_vacf.csv",true); mfprintf(a,"#Depth [fs]; VACF\n"); for (z=0;zm_iDepth;z++) mfprintf(a,"%.2f; %.10G\n",z*g_fTimestepLength*g_iStride,daacf[0][z]); fclose(a); } mprintf("\n Assuming 3n = %d degrees of freedom, the average system temperature is %.2f K.\n\n", 3 * g_iGesAtomCount, f ); } if (m_bPola) { _again: if (!b && m_bDumpMolecularProps && m_bCentral) { mprintf(" Writing results to \"central.csv\"...\n"); a = OpenFileWrite("central.csv",true); mfprintf(a,"#Step"); for (z=0;z 1) mprintf(WHITE," ["); for (z=0;z 1) if (fmod(z,tfs) < 1.0) mprintf(WHITE,"#"); if (m_bCentral && m_bAniso) { rn = tn->m_oaMolecules[z]; rxp = txp->m_oaMolecules[z]; rxn = txn->m_oaMolecules[z]; ryp = typ->m_oaMolecules[z]; ryn = tyn->m_oaMolecules[z]; rzp = tzp->m_oaMolecules[z]; rzn = tzn->m_oaMolecules[z]; cfac = 2.0; } else if (!m_bCentral && m_bAniso) { rn = tn->m_oaMolecules[z]; rxp = txp->m_oaMolecules[z]; rxn = tn->m_oaMolecules[z]; ryp = typ->m_oaMolecules[z]; ryn = tn->m_oaMolecules[z]; rzp = tzp->m_oaMolecules[z]; rzn = tn->m_oaMolecules[z]; cfac = 1.0; } rn->m_maPolElDip.resize(m_iStepsProcessed); rn->m_taPolElQuad.resize(m_iStepsProcessed,CDTensor3(3,3,3)); if (m_bMagMom) rn->m_maPolMagDip.resize(m_iStepsProcessed); for (z2=0;z2m_maPolElDip[z2](0,0) = (rxp->m_vaElDip[z2][0] - rxn->m_vaElDip[z2][0]) / (cfac * m_fFieldStrength); rn->m_maPolElDip[z2](0,1) = (rxp->m_vaElDip[z2][1] - rxn->m_vaElDip[z2][1]) / (cfac * m_fFieldStrength); rn->m_maPolElDip[z2](0,2) = (rxp->m_vaElDip[z2][2] - rxn->m_vaElDip[z2][2]) / (cfac * m_fFieldStrength); rn->m_maPolElDip[z2](1,0) = (ryp->m_vaElDip[z2][0] - ryn->m_vaElDip[z2][0]) / (cfac * m_fFieldStrength); rn->m_maPolElDip[z2](1,1) = (ryp->m_vaElDip[z2][1] - ryn->m_vaElDip[z2][1]) / (cfac * m_fFieldStrength); rn->m_maPolElDip[z2](1,2) = (ryp->m_vaElDip[z2][2] - ryn->m_vaElDip[z2][2]) / (cfac * m_fFieldStrength); rn->m_maPolElDip[z2](2,0) = (rzp->m_vaElDip[z2][0] - rzn->m_vaElDip[z2][0]) / (cfac * m_fFieldStrength); rn->m_maPolElDip[z2](2,1) = (rzp->m_vaElDip[z2][1] - rzn->m_vaElDip[z2][1]) / (cfac * m_fFieldStrength); rn->m_maPolElDip[z2](2,2) = (rzp->m_vaElDip[z2][2] - rzn->m_vaElDip[z2][2]) / (cfac * m_fFieldStrength); if (!b && m_bDumpMolecularProps && m_bCentral) { tda[z*ic ][z2] = (rn->m_vaElDip[z2][0] - rxn->m_vaElDip[z2][0]) / (rxp->m_vaElDip[z2][0] - rxn->m_vaElDip[z2][0]); tda[z*ic+1][z2] = (rn->m_vaElDip[z2][1] - rxn->m_vaElDip[z2][1]) / (rxp->m_vaElDip[z2][1] - rxn->m_vaElDip[z2][1]); tda[z*ic+2][z2] = (rn->m_vaElDip[z2][2] - rxn->m_vaElDip[z2][2]) / (rxp->m_vaElDip[z2][2] - rxn->m_vaElDip[z2][2]); tda[z*ic+3][z2] = (rn->m_vaElDip[z2][0] - ryn->m_vaElDip[z2][0]) / (ryp->m_vaElDip[z2][0] - ryn->m_vaElDip[z2][0]); tda[z*ic+4][z2] = (rn->m_vaElDip[z2][1] - ryn->m_vaElDip[z2][1]) / (ryp->m_vaElDip[z2][1] - ryn->m_vaElDip[z2][1]); tda[z*ic+5][z2] = (rn->m_vaElDip[z2][2] - ryn->m_vaElDip[z2][2]) / (ryp->m_vaElDip[z2][2] - ryn->m_vaElDip[z2][2]); tda[z*ic+6][z2] = (rn->m_vaElDip[z2][0] - rzn->m_vaElDip[z2][0]) / (rzp->m_vaElDip[z2][0] - rzn->m_vaElDip[z2][0]); tda[z*ic+7][z2] = (rn->m_vaElDip[z2][1] - rzn->m_vaElDip[z2][1]) / (rzp->m_vaElDip[z2][1] - rzn->m_vaElDip[z2][1]); tda[z*ic+8][z2] = (rn->m_vaElDip[z2][2] - rzn->m_vaElDip[z2][2]) / (rzp->m_vaElDip[z2][2] - rzn->m_vaElDip[z2][2]); } for (z3=0;z3<9;z3++) rn->m_maPolElDip[z2][z3] *= 1.0 / DIP_EPM2DEBYE / EFIELD_AU2VPM; // Conversion Debye*e*a0/Eh to e*pm^2/V // Electric Dipole-Electric Quadrupole Polarizability rn->m_taPolElQuad[z2](0,0,0) = (rxp->m_maElQuad[z2](0,0) - rxn->m_maElQuad[z2](0,0)) / (cfac * m_fFieldStrength); rn->m_taPolElQuad[z2](0,0,1) = (rxp->m_maElQuad[z2](0,1) - rxn->m_maElQuad[z2](0,1)) / (cfac * m_fFieldStrength); rn->m_taPolElQuad[z2](0,0,2) = (rxp->m_maElQuad[z2](0,2) - rxn->m_maElQuad[z2](0,2)) / (cfac * m_fFieldStrength); rn->m_taPolElQuad[z2](0,1,0) = (rxp->m_maElQuad[z2](1,0) - rxn->m_maElQuad[z2](1,0)) / (cfac * m_fFieldStrength); rn->m_taPolElQuad[z2](0,1,1) = (rxp->m_maElQuad[z2](1,1) - rxn->m_maElQuad[z2](1,1)) / (cfac * m_fFieldStrength); rn->m_taPolElQuad[z2](0,1,2) = (rxp->m_maElQuad[z2](1,2) - rxn->m_maElQuad[z2](1,2)) / (cfac * m_fFieldStrength); rn->m_taPolElQuad[z2](0,2,0) = (rxp->m_maElQuad[z2](2,0) - rxn->m_maElQuad[z2](2,0)) / (cfac * m_fFieldStrength); rn->m_taPolElQuad[z2](0,2,1) = (rxp->m_maElQuad[z2](2,1) - rxn->m_maElQuad[z2](2,1)) / (cfac * m_fFieldStrength); rn->m_taPolElQuad[z2](0,2,2) = (rxp->m_maElQuad[z2](2,2) - rxn->m_maElQuad[z2](2,2)) / (cfac * m_fFieldStrength); rn->m_taPolElQuad[z2](1,0,0) = (ryp->m_maElQuad[z2](0,0) - ryn->m_maElQuad[z2](0,0)) / (cfac * m_fFieldStrength); rn->m_taPolElQuad[z2](1,0,1) = (ryp->m_maElQuad[z2](0,1) - ryn->m_maElQuad[z2](0,1)) / (cfac * m_fFieldStrength); rn->m_taPolElQuad[z2](1,0,2) = (ryp->m_maElQuad[z2](0,2) - ryn->m_maElQuad[z2](0,2)) / (cfac * m_fFieldStrength); rn->m_taPolElQuad[z2](1,1,0) = (ryp->m_maElQuad[z2](1,0) - ryn->m_maElQuad[z2](1,0)) / (cfac * m_fFieldStrength); rn->m_taPolElQuad[z2](1,1,1) = (ryp->m_maElQuad[z2](1,1) - ryn->m_maElQuad[z2](1,1)) / (cfac * m_fFieldStrength); rn->m_taPolElQuad[z2](1,1,2) = (ryp->m_maElQuad[z2](1,2) - ryn->m_maElQuad[z2](1,2)) / (cfac * m_fFieldStrength); rn->m_taPolElQuad[z2](1,2,0) = (ryp->m_maElQuad[z2](2,0) - ryn->m_maElQuad[z2](2,0)) / (cfac * m_fFieldStrength); rn->m_taPolElQuad[z2](1,2,1) = (ryp->m_maElQuad[z2](2,1) - ryn->m_maElQuad[z2](2,1)) / (cfac * m_fFieldStrength); rn->m_taPolElQuad[z2](1,2,2) = (ryp->m_maElQuad[z2](2,2) - ryn->m_maElQuad[z2](2,2)) / (cfac * m_fFieldStrength); rn->m_taPolElQuad[z2](2,0,0) = (rzp->m_maElQuad[z2](0,0) - rzn->m_maElQuad[z2](0,0)) / (cfac * m_fFieldStrength); rn->m_taPolElQuad[z2](2,0,1) = (rzp->m_maElQuad[z2](0,1) - rzn->m_maElQuad[z2](0,1)) / (cfac * m_fFieldStrength); rn->m_taPolElQuad[z2](2,0,2) = (rzp->m_maElQuad[z2](0,2) - rzn->m_maElQuad[z2](0,2)) / (cfac * m_fFieldStrength); rn->m_taPolElQuad[z2](2,1,0) = (rzp->m_maElQuad[z2](1,0) - rzn->m_maElQuad[z2](1,0)) / (cfac * m_fFieldStrength); rn->m_taPolElQuad[z2](2,1,1) = (rzp->m_maElQuad[z2](1,1) - rzn->m_maElQuad[z2](1,1)) / (cfac * m_fFieldStrength); rn->m_taPolElQuad[z2](2,1,2) = (rzp->m_maElQuad[z2](1,2) - rzn->m_maElQuad[z2](1,2)) / (cfac * m_fFieldStrength); rn->m_taPolElQuad[z2](2,2,0) = (rzp->m_maElQuad[z2](2,0) - rzn->m_maElQuad[z2](2,0)) / (cfac * m_fFieldStrength); rn->m_taPolElQuad[z2](2,2,1) = (rzp->m_maElQuad[z2](2,1) - rzn->m_maElQuad[z2](2,1)) / (cfac * m_fFieldStrength); rn->m_taPolElQuad[z2](2,2,2) = (rzp->m_maElQuad[z2](2,2) - rzn->m_maElQuad[z2](2,2)) / (cfac * m_fFieldStrength); for (z3=0;z3<27;z3++) rn->m_taPolElQuad[z2][z3] *= 1.0 / DIP_EPM2DEBYE / EFIELD_AU2VPM; // Conversion Debye*pm*e*a0/Eh to e*pm^3/V if (m_bMagMom) { // Electric Dipole-Magnetic Dipole Polarizability rn->m_maPolMagDip[z2](0,0) = (rxp->m_vaMagDip[z2][0] - rxn->m_vaMagDip[z2][0]) / (cfac * m_fFieldStrength); rn->m_maPolMagDip[z2](0,1) = (rxp->m_vaMagDip[z2][1] - rxn->m_vaMagDip[z2][1]) / (cfac * m_fFieldStrength); rn->m_maPolMagDip[z2](0,2) = (rxp->m_vaMagDip[z2][2] - rxn->m_vaMagDip[z2][2]) / (cfac * m_fFieldStrength); rn->m_maPolMagDip[z2](1,0) = (ryp->m_vaMagDip[z2][0] - ryn->m_vaMagDip[z2][0]) / (cfac * m_fFieldStrength); rn->m_maPolMagDip[z2](1,1) = (ryp->m_vaMagDip[z2][1] - ryn->m_vaMagDip[z2][1]) / (cfac * m_fFieldStrength); rn->m_maPolMagDip[z2](1,2) = (ryp->m_vaMagDip[z2][2] - ryn->m_vaMagDip[z2][2]) / (cfac * m_fFieldStrength); rn->m_maPolMagDip[z2](2,0) = (rzp->m_vaMagDip[z2][0] - rzn->m_vaMagDip[z2][0]) / (cfac * m_fFieldStrength); rn->m_maPolMagDip[z2](2,1) = (rzp->m_vaMagDip[z2][1] - rzn->m_vaMagDip[z2][1]) / (cfac * m_fFieldStrength); rn->m_maPolMagDip[z2](2,2) = (rzp->m_vaMagDip[z2][2] - rzn->m_vaMagDip[z2][2]) / (cfac * m_fFieldStrength); if (!b && m_bDumpMolecularProps && m_bCentral) { tda[z*ic+ 9][z2] = (rn->m_vaMagDip[z2][0] - rxn->m_vaMagDip[z2][0]) / (rxp->m_vaMagDip[z2][0] - rxn->m_vaMagDip[z2][0]); tda[z*ic+10][z2] = (rn->m_vaMagDip[z2][1] - rxn->m_vaMagDip[z2][1]) / (rxp->m_vaMagDip[z2][1] - rxn->m_vaMagDip[z2][1]); tda[z*ic+11][z2] = (rn->m_vaMagDip[z2][2] - rxn->m_vaMagDip[z2][2]) / (rxp->m_vaMagDip[z2][2] - rxn->m_vaMagDip[z2][2]); tda[z*ic+12][z2] = (rn->m_vaMagDip[z2][0] - ryn->m_vaMagDip[z2][0]) / (ryp->m_vaMagDip[z2][0] - ryn->m_vaMagDip[z2][0]); tda[z*ic+13][z2] = (rn->m_vaMagDip[z2][1] - ryn->m_vaMagDip[z2][1]) / (ryp->m_vaMagDip[z2][1] - ryn->m_vaMagDip[z2][1]); tda[z*ic+14][z2] = (rn->m_vaMagDip[z2][2] - ryn->m_vaMagDip[z2][2]) / (ryp->m_vaMagDip[z2][2] - ryn->m_vaMagDip[z2][2]); tda[z*ic+15][z2] = (rn->m_vaMagDip[z2][0] - rzn->m_vaMagDip[z2][0]) / (rzp->m_vaMagDip[z2][0] - rzn->m_vaMagDip[z2][0]); tda[z*ic+16][z2] = (rn->m_vaMagDip[z2][1] - rzn->m_vaMagDip[z2][1]) / (rzp->m_vaMagDip[z2][1] - rzn->m_vaMagDip[z2][1]); tda[z*ic+17][z2] = (rn->m_vaMagDip[z2][2] - rzn->m_vaMagDip[z2][2]) / (rzp->m_vaMagDip[z2][2] - rzn->m_vaMagDip[z2][2]); } for (z3=0;z3<9;z3++) rn->m_maPolMagDip[z2][z3] *= 0.001 / MAG_EPMMS2MB / EFIELD_AU2VPM; // Conversion MB*e*a0/Eh to e*pm^3/(fs*V) } } } if (g_oaSingleMolecules.GetSize() > 1) mprintf(WHITE,"]\n"); if (!b && m_bDumpMolecularProps && m_bCentral) { for (z=0;z 1) mprintf(WHITE," ["); for (z=0;z 1) if (fmod(z,tfs) < 1.0) mprintf(WHITE,"#"); rn = tn->m_oaMolecules[z]; for (z2=0;z2m_faCharge[z2],rn->m_faCharge[z2+1],rn->m_faCharge[z2+3],rn->m_faCharge[z2+4]); tfma = MAX4(rn->m_faCharge[z2],rn->m_faCharge[z2+1],rn->m_faCharge[z2+3],rn->m_faCharge[z2+4]); if ((rn->m_faCharge[z2+2] < tfmi-tfout*(tfma-tfmi)) || (rn->m_faCharge[z2+2] > tfma+tfout*(tfma-tfmi))) m_iaOutliers[0][z2]++; } for (z2=0;z2m_vaElDip[z2][z3],rn->m_vaElDip[z2+1][z3],rn->m_vaElDip[z2+3][z3],rn->m_vaElDip[z2+4][z3]); tfma = MAX4(rn->m_vaElDip[z2][z3],rn->m_vaElDip[z2+1][z3],rn->m_vaElDip[z2+3][z3],rn->m_vaElDip[z2+4][z3]); if ((rn->m_vaElDip[z2+2][z3] < tfmi-tfout*(tfma-tfmi)) || (rn->m_vaElDip[z2+2][z3] > tfma+tfout*(tfma-tfmi))) tb = true; } if (tb) m_iaOutliers[1][z2]++; } for (z2=0;z2m_maElQuad[z2][z3],rn->m_maElQuad[z2+1][z3],rn->m_maElQuad[z2+3][z3],rn->m_maElQuad[z2+4][z3]); tfma = MAX4(rn->m_maElQuad[z2][z3],rn->m_maElQuad[z2+1][z3],rn->m_maElQuad[z2+3][z3],rn->m_maElQuad[z2+4][z3]); if ((rn->m_maElQuad[z2+2][z3] < tfmi-tfout*(tfma-tfmi)) || (rn->m_maElQuad[z2+2][z3] > tfma+tfout*(tfma-tfmi))) tb = true; } if (tb) m_iaOutliers[2][z2]++; } for (z2=0;z2m_vaElCurr[z2][z3],rn->m_vaElCurr[z2+1][z3],rn->m_vaElCurr[z2+3][z3],rn->m_vaElCurr[z2+4][z3]); tfma = MAX4(rn->m_vaElCurr[z2][z3],rn->m_vaElCurr[z2+1][z3],rn->m_vaElCurr[z2+3][z3],rn->m_vaElCurr[z2+4][z3]); if ((rn->m_vaElCurr[z2+2][z3] < tfmi-2.0*tfout*(tfma-tfmi)) || (rn->m_vaElCurr[z2+2][z3] > tfma+2.0*tfout*(tfma-tfmi))) tb = true; } if (tb) m_iaOutliers[3][z2]++; } for (z2=0;z2m_vaMagDip[z2][z3],rn->m_vaMagDip[z2+1][z3],rn->m_vaMagDip[z2+3][z3],rn->m_vaMagDip[z2+4][z3]); tfma = MAX4(rn->m_vaMagDip[z2][z3],rn->m_vaMagDip[z2+1][z3],rn->m_vaMagDip[z2+3][z3],rn->m_vaMagDip[z2+4][z3]); if ((rn->m_vaMagDip[z2+2][z3] < tfmi-2.0*tfout*(tfma-tfmi)) || (rn->m_vaMagDip[z2+2][z3] > tfma+2.0*tfout*(tfma-tfmi))) tb = true; } if (tb) m_iaOutliers[4][z2]++; } for (z2=0;z2m_maPolElDip[z2][z3],rn->m_maPolElDip[z2+1][z3],rn->m_maPolElDip[z2+3][z3],rn->m_maPolElDip[z2+4][z3]); tfma = MAX4(rn->m_maPolElDip[z2][z3],rn->m_maPolElDip[z2+1][z3],rn->m_maPolElDip[z2+3][z3],rn->m_maPolElDip[z2+4][z3]); if ((rn->m_maPolElDip[z2+2][z3] < tfmi-tfout*(tfma-tfmi)) || (rn->m_maPolElDip[z2+2][z3] > tfma+tfout*(tfma-tfmi))) tb = true; } if (tb) m_iaOutliers[5][z2]++; } for (z2=0;z2m_taPolElQuad[z2][z3],rn->m_taPolElQuad[z2+1][z3],rn->m_taPolElQuad[z2+3][z3],rn->m_taPolElQuad[z2+4][z3]); tfma = MAX4(rn->m_taPolElQuad[z2][z3],rn->m_taPolElQuad[z2+1][z3],rn->m_taPolElQuad[z2+3][z3],rn->m_taPolElQuad[z2+4][z3]); if ((rn->m_taPolElQuad[z2+2][z3] < tfmi-tfout*(tfma-tfmi)) || (rn->m_taPolElQuad[z2+2][z3] > tfma+tfout*(tfma-tfmi))) tb = true; } if (tb) m_iaOutliers[6][z2]++; } for (z2=0;z2m_maPolMagDip[z2][z3],rn->m_maPolMagDip[z2+1][z3],rn->m_maPolMagDip[z2+3][z3],rn->m_maPolMagDip[z2+4][z3]); tfma = MAX4(rn->m_maPolMagDip[z2][z3],rn->m_maPolMagDip[z2+1][z3],rn->m_maPolMagDip[z2+3][z3],rn->m_maPolMagDip[z2+4][z3]); if ((rn->m_maPolMagDip[z2+2][z3] < tfmi-2.0*tfout*(tfma-tfmi)) || (rn->m_maPolMagDip[z2+2][z3] > tfma+2.0*tfout*(tfma-tfmi))) tb = true; } if (tb) m_iaOutliers[7][z2]++; } } if (g_oaSingleMolecules.GetSize() > 1) mprintf(WHITE,"]\n"); /* a = OpenFileWrite("outliers.csv",true); fprintf(a,"#Step; Charge; ElDip; ElQuad; Curr; MagDip; PolElDip; PolElQuad; PolMagDip\n"); for (z=0;zm_oaMolecules[z2]; if (!tb2) { para.Init4(-2.0,rn->m_faCharge[z],-1.0,rn->m_faCharge[z+1],1.0,rn->m_faCharge[z+3],2.0,rn->m_faCharge[z+4]); rn->m_faCharge[z+2] = para.Evaluate(0); for (z3=0;z3<3;z3++) { para.Init4(-2.0,rn->m_vaElDip[z][z3],-1.0,rn->m_vaElDip[z+1][z3],1.0,rn->m_vaElDip[z+3][z3],2.0,rn->m_vaElDip[z+4][z3]); rn->m_vaElDip[z+2][z3] = para.Evaluate(0); } for (z3=0;z3<9;z3++) { para.Init4(-2.0,rn->m_maElQuad[z][z3],-1.0,rn->m_maElQuad[z+1][z3],1.0,rn->m_maElQuad[z+3][z3],2.0,rn->m_maElQuad[z+4][z3]); rn->m_maElQuad[z+2][z3] = para.Evaluate(0); } for (z3=0;z3<9;z3++) { para.Init4(-2.0,rn->m_maPolElDip[z][z3],-1.0,rn->m_maPolElDip[z+1][z3],1.0,rn->m_maPolElDip[z+3][z3],2.0,rn->m_maPolElDip[z+4][z3]); rn->m_maPolElDip[z+2][z3] = para.Evaluate(0); } for (z3=0;z3<27;z3++) { para.Init4(-2.0,rn->m_taPolElQuad[z][z3],-1.0,rn->m_taPolElQuad[z+1][z3],1.0,rn->m_taPolElQuad[z+3][z3],2.0,rn->m_taPolElQuad[z+4][z3]); rn->m_taPolElQuad[z+2][z3] = para.Evaluate(0); } } if ((z > 0) && (z < m_iStepsProcessed-6)) { for (z3=0;z3<3;z3++) { para.Init4(-3.0,rn->m_vaMagDip[z-1][z3],-2.0,rn->m_vaMagDip[z][z3],3.0,rn->m_vaMagDip[z+5][z3],4.0,rn->m_vaMagDip[z+6][z3]); rn->m_vaMagDip[z+1][z3] = para.Evaluate(-1.0); rn->m_vaMagDip[z+2][z3] = para.Evaluate(0); rn->m_vaMagDip[z+3][z3] = para.Evaluate(1.0); rn->m_vaMagDip[z+4][z3] = para.Evaluate(2.0); } for (z3=0;z3<3;z3++) { para.Init4(-3.0,rn->m_vaElCurr[z-1][z3],-2.0,rn->m_vaElCurr[z][z3],3.0,rn->m_vaElCurr[z+5][z3],4.0,rn->m_vaElCurr[z+6][z3]); rn->m_vaElCurr[z+1][z3] = para.Evaluate(-1.0); rn->m_vaElCurr[z+2][z3] = para.Evaluate(0); rn->m_vaElCurr[z+3][z3] = para.Evaluate(1.0); rn->m_vaElCurr[z+4][z3] = para.Evaluate(2.0); } for (z3=0;z3<9;z3++) { para.Init4(-3.0,rn->m_maPolMagDip[z-1][z3],-2.0,rn->m_maPolMagDip[z][z3],3.0,rn->m_maPolMagDip[z+5][z3],4.0,rn->m_maPolMagDip[z+6][z3]); rn->m_maPolMagDip[z+1][z3] = para.Evaluate(-1.0); rn->m_maPolMagDip[z+2][z3] = para.Evaluate(0); rn->m_maPolMagDip[z+3][z3] = para.Evaluate(1.0); rn->m_maPolMagDip[z+4][z3] = para.Evaluate(2.0); } } } z += 2; } if (tb) { mprintf(" Found some outliers, repeating detection.\n"); goto _outagain; } if (!tb2) { mprintf(" Now scanning for magnetic outliers...\n"); tb2 = true; goto _outagain2; } mprintf(" Outlier correction finished.\n"); } } if (m_bDumpMol1Props) { if (b) { mprintf(" Writing results to \"prop_mol1_smooth.csv\"...\n"); a = OpenFileWrite("prop_mol1_smooth.csv",true); } else { mprintf(" Writing results to \"prop_mol1.csv\"...\n"); a = OpenFileWrite("prop_mol1.csv",true); } mfprintf(a,"#Step"); mfprintf(a,"; Charge; ElDipX; ElDipY; ElDipZ; ElQuadXX; ElQuadXY; ElQuadXZ; ElQuadYX; ElQuadYY; ElQuadYZ; ElQuadZX; ElQuadZY; ElQuadZZ"); if (m_bMagMom) mfprintf(a,"; ElCurrX; ElCurrY; ElCurrZ; MagDipX; MagDipY; MagDipZ"); if (m_bPola) { mfprintf(a,"; PolElDipXX; PolElDipXY; PolElDipXZ; PolElDipYX; PolElDipYY; PolElDipYZ; PolElDipZX; PolElDipZY; PolElDipZZ"); mfprintf(a,"; PolElQuadXXX; PolElQuadXXY; PolElQuadXXZ; PolElQuadXYX; PolElQuadXYY; PolElQuadXYZ; PolElQuadXZX; PolElQuadXZY; PolElQuadXZZ; PolElQuadYXX; PolElQuadYXY; PolElQuadYXZ; PolElQuadYYX; PolElQuadYYY; PolElQuadYYZ; PolElQuadYZX; PolElQuadYZY; PolElQuadYZZ; PolElQuadZXX; PolElQuadZXY; PolElQuadZXZ; PolElQuadZYX; PolElQuadZYY; PolElQuadZYZ; PolElQuadZZX; PolElQuadZZY; PolElQuadZZZ"); } if (m_bMagMom && m_bPola) mfprintf(a,"; PolMagDipXX; PolMagDipXY; PolMagDipXZ; PolMagDipYX; PolMagDipYY; PolMagDipYZ; PolMagDipZX; PolMagDipZY; PolMagDipZZ"); mfprintf(a,"\n"); rn = tn->m_oaMolecules[0]; tfs = m_iStepsProcessed / 60.0; mprintf(WHITE," ["); for (z=0;zm_faCharge[z]); mfprintf(a,"; %.10G; %.10G; %.10G", rn->m_vaElDip[z][0], rn->m_vaElDip[z][1], rn->m_vaElDip[z][2] ); mfprintf(a,"; %.10G; %.10G; %.10G; %.10G; %.10G; %.10G; %.10G; %.10G; %.10G", rn->m_maElQuad[z](0,0),rn->m_maElQuad[z](0,1),rn->m_maElQuad[z](0,2), rn->m_maElQuad[z](1,0),rn->m_maElQuad[z](1,1),rn->m_maElQuad[z](1,2), rn->m_maElQuad[z](2,0),rn->m_maElQuad[z](2,1),rn->m_maElQuad[z](2,2) ); if (m_bMagMom) { mfprintf(a,"; %.10G; %.10G; %.10G", rn->m_vaElCurr[z][0], rn->m_vaElCurr[z][1], rn->m_vaElCurr[z][2] ); mfprintf(a,"; %.10G; %.10G; %.10G", rn->m_vaMagDip[z][0], rn->m_vaMagDip[z][1], rn->m_vaMagDip[z][2] ); } if (m_bPola) { mfprintf(a,"; %.10G; %.10G; %.10G; %.10G; %.10G; %.10G; %.10G; %.10G; %.10G", rn->m_maPolElDip[z](0,0), rn->m_maPolElDip[z](0,1), rn->m_maPolElDip[z](0,2), rn->m_maPolElDip[z](1,0), rn->m_maPolElDip[z](1,1), rn->m_maPolElDip[z](1,2), rn->m_maPolElDip[z](2,0), rn->m_maPolElDip[z](2,1), rn->m_maPolElDip[z](2,2) ); mfprintf(a,"; %.10G; %.10G; %.10G; %.10G; %.10G; %.10G; %.10G; %.10G; %.10G; %.10G; %.10G; %.10G; %.10G; %.10G; %.10G; %.10G; %.10G; %.10G; %.10G; %.10G; %.10G; %.10G; %.10G; %.10G; %.10G; %.10G; %.10G", rn->m_taPolElQuad[z](0,0,0), rn->m_taPolElQuad[z](0,0,1), rn->m_taPolElQuad[z](0,0,2), rn->m_taPolElQuad[z](0,1,0), rn->m_taPolElQuad[z](0,1,1), rn->m_taPolElQuad[z](0,1,2), rn->m_taPolElQuad[z](0,2,0), rn->m_taPolElQuad[z](0,2,1), rn->m_taPolElQuad[z](0,2,2), rn->m_taPolElQuad[z](1,0,0), rn->m_taPolElQuad[z](1,0,1), rn->m_taPolElQuad[z](1,0,2), rn->m_taPolElQuad[z](1,1,0), rn->m_taPolElQuad[z](1,1,1), rn->m_taPolElQuad[z](1,1,2), rn->m_taPolElQuad[z](1,2,0), rn->m_taPolElQuad[z](1,2,1), rn->m_taPolElQuad[z](1,2,2), rn->m_taPolElQuad[z](2,0,0), rn->m_taPolElQuad[z](2,0,1), rn->m_taPolElQuad[z](2,0,2), rn->m_taPolElQuad[z](2,1,0), rn->m_taPolElQuad[z](2,1,1), rn->m_taPolElQuad[z](2,1,2), rn->m_taPolElQuad[z](2,2,0), rn->m_taPolElQuad[z](2,2,1), rn->m_taPolElQuad[z](2,2,2) ); } if (m_bMagMom && m_bPola) mfprintf(a,"; %.10G; %.10G; %.10G; %.10G; %.10G; %.10G; %.10G; %.10G; %.10G", rn->m_maPolMagDip[z](0,0), rn->m_maPolMagDip[z](0,1), rn->m_maPolMagDip[z](0,2), rn->m_maPolMagDip[z](1,0), rn->m_maPolMagDip[z](1,1), rn->m_maPolMagDip[z](1,2), rn->m_maPolMagDip[z](2,0), rn->m_maPolMagDip[z](2,1), rn->m_maPolMagDip[z](2,2) ); mfprintf(a,"\n"); //fflush(a); } mprintf(WHITE,"]\n"); fclose(a); } mprintf(" Deriving all properties...\n"); tfs = g_oaSingleMolecules.GetSize() / 60.0; if (g_oaSingleMolecules.GetSize() > 1) mprintf(WHITE," ["); for (z=0;z 1) if (fmod(z,tfs) < 1.0) mprintf(WHITE,"#"); rn = tn->m_oaMolecules[z]; rn->m_faDCharge.resize(m_iStepsProcessed-2); rn->m_vaDElDip.resize(m_iStepsProcessed-2); rn->m_maDElQuad.resize(m_iStepsProcessed-2); if (m_bMagMom) { rn->m_vaDElCurr.resize(m_iStepsProcessed-2); rn->m_vaDMagDip.resize(m_iStepsProcessed-2); } if (m_bPola) { rn->m_maDPolElDip.resize(m_iStepsProcessed-2); rn->m_taDPolElQuad.resize(m_iStepsProcessed-2,CDTensor3(3,3,3)); } if (m_bMagMom && m_bPola) rn->m_maDPolMagDip.resize(m_iStepsProcessed-2); for (z2=0;z2m_faDCharge[z2] = (rn->m_faCharge[z2+2] - rn->m_faCharge[z2]) / (2.0 * g_fTimestepLength * g_iStride); // Unit: Debye/fs for (z3=0;z3<3;z3++) rn->m_vaDElDip[z2][z3] = (rn->m_vaElDip[z2+2][z3] - rn->m_vaElDip[z2][z3]) / (2.0 * g_fTimestepLength * g_iStride); // Unit: Debye*pm/fs for (z3=0;z3<9;z3++) rn->m_maDElQuad[z2][z3] = (rn->m_maElQuad[z2+2][z3] - rn->m_maElQuad[z2][z3]) / (2.0 * g_fTimestepLength * g_iStride); if (m_bMagMom) { // Unit: MB/(pm*fs) for (z3=0;z3<3;z3++) rn->m_vaDElCurr[z2][z3] = (rn->m_vaElCurr[z2+2][z3] - rn->m_vaElCurr[z2][z3]) / (2.0 * g_fTimestepLength * g_iStride); // Unit: MB/fs for (z3=0;z3<3;z3++) rn->m_vaDMagDip[z2][z3] = (rn->m_vaMagDip[z2+2][z3] - rn->m_vaMagDip[z2][z3]) / (2.0 * g_fTimestepLength * g_iStride); } if (m_bPola) { // Unit: e*pm^2/(V*fs) for (z3=0;z3<9;z3++) rn->m_maDPolElDip[z2][z3] = (rn->m_maPolElDip[z2+2][z3] - rn->m_maPolElDip[z2][z3]) / (2.0 * g_fTimestepLength * g_iStride); // Unit: e*pm^3/(V*fs) for (z3=0;z3<27;z3++) rn->m_taDPolElQuad[z2][z3] = (rn->m_taPolElQuad[z2+2][z3] - rn->m_taPolElQuad[z2][z3]) / (2.0 * g_fTimestepLength * g_iStride); } if (m_bMagMom && m_bPola) { // Unit: e*pm^3/(V*fs^2) for (z3=0;z3<9;z3++) rn->m_maDPolMagDip[z2][z3] = (rn->m_maPolMagDip[z2+2][z3] - rn->m_maPolMagDip[z2][z3]) / (2.0 * g_fTimestepLength * g_iStride); } } } if (g_oaSingleMolecules.GetSize() > 1) mprintf(WHITE,"]\n"); if (m_bDumpMol1Props) { if (b) { mprintf(" Writing results to \"prop_mol1_deriv_smooth.csv\"...\n"); a = OpenFileWrite("prop_mol1_deriv_smooth.csv",true); } else { mprintf(" Writing results to \"prop_mol1_deriv.csv\"...\n"); a = OpenFileWrite("prop_mol1_deriv.csv",true); } mfprintf(a,"#Step"); mfprintf(a,"; DCharge; DElDipX; DElDipY; DElDipZ; DElQuadXX; DElQuadXY; DElQuadXZ; DElQuadYX; DElQuadYY; DElQuadYZ; DElQuadZX; DElQuadZY; DElQuadZZ"); if (m_bMagMom) mfprintf(a,"; DElCurrX; DElCurrY; DElCurrZ; DMagDipX; DMagDipY; DMagDipZ"); if (m_bPola) { mfprintf(a,"; DPolElDipXX; DPolElDipXY; DPolElDipXZ; DPolElDipYX; DPolElDipYY; DPolElDipYZ; DPolElDipZX; DPolElDipZY; DPolElDipZZ"); mfprintf(a,"; DPolElQuadXXX; DPolElQuadXXY; DPolElQuadXXZ; DPolElQuadXYX; DPolElQuadXYY; DPolElQuadXYZ; DPolElQuadXZX; DPolElQuadXZY; DPolElQuadXZZ; DPolElQuadYXX; DPolElQuadYXY; DPolElQuadYXZ; DPolElQuadYYX; DPolElQuadYYY; DPolElQuadYYZ; DPolElQuadYZX; DPolElQuadYZY; DPolElQuadYZZ; DPolElQuadZXX; DPolElQuadZXY; DPolElQuadZXZ; DPolElQuadZYX; DPolElQuadZYY; DPolElQuadZYZ; DPolElQuadZZX; DPolElQuadZZY; DPolElQuadZZZ"); } if (m_bMagMom && m_bPola) mfprintf(a,"; DPolMagDipXX; DPolMagDipXY; DPolMagDipXZ; DPolMagDipYX; DPolMagDipYY; DPolMagDipYZ; DPolMagDipZX; DPolMagDipZY; DPolMagDipZZ"); mfprintf(a,"\n"); rn = tn->m_oaMolecules[0]; tfs = (m_iStepsProcessed-2) / 60.0; mprintf(WHITE," ["); for (z=0;zm_faDCharge[z]); mfprintf(a,"; %.10G; %.10G; %.10G", rn->m_vaDElDip[z][0], rn->m_vaDElDip[z][1], rn->m_vaDElDip[z][2] ); mfprintf(a,"; %.10G; %.10G; %.10G; %.10G; %.10G; %.10G; %.10G; %.10G; %.10G", rn->m_maDElQuad[z](0,0), rn->m_maDElQuad[z](0,1), rn->m_maDElQuad[z](0,2), rn->m_maDElQuad[z](1,0), rn->m_maDElQuad[z](1,1), rn->m_maDElQuad[z](1,2), rn->m_maDElQuad[z](2,0), rn->m_maDElQuad[z](2,1), rn->m_maDElQuad[z](2,2) ); if (m_bMagMom) { mfprintf(a,"; %.10G; %.10G; %.10G", rn->m_vaDElCurr[z][0], rn->m_vaDElCurr[z][1], rn->m_vaDElCurr[z][2] ); mfprintf(a,"; %.10G; %.10G; %.10G", rn->m_vaDMagDip[z][0], rn->m_vaDMagDip[z][1], rn->m_vaDMagDip[z][2] ); } if (m_bPola) { mfprintf(a,"; %.10G; %.10G; %.10G; %.10G; %.10G; %.10G; %.10G; %.10G; %.10G", rn->m_maDPolElDip[z](0,0), rn->m_maDPolElDip[z](0,1), rn->m_maDPolElDip[z](0,2), rn->m_maDPolElDip[z](1,0), rn->m_maDPolElDip[z](1,1), rn->m_maDPolElDip[z](1,2), rn->m_maDPolElDip[z](2,0), rn->m_maDPolElDip[z](2,1), rn->m_maDPolElDip[z](2,2) ); mfprintf(a,"; %.10G; %.10G; %.10G; %.10G; %.10G; %.10G; %.10G; %.10G; %.10G; %.10G; %.10G; %.10G; %.10G; %.10G; %.10G; %.10G; %.10G; %.10G; %.10G; %.10G; %.10G; %.10G; %.10G; %.10G; %.10G; %.10G; %.10G", rn->m_taDPolElQuad[z](0,0,0), rn->m_taDPolElQuad[z](0,0,1), rn->m_taDPolElQuad[z](0,0,2), rn->m_taDPolElQuad[z](0,1,0), rn->m_taDPolElQuad[z](0,1,1), rn->m_taDPolElQuad[z](0,1,2), rn->m_taDPolElQuad[z](0,2,0), rn->m_taDPolElQuad[z](0,2,1), rn->m_taDPolElQuad[z](0,2,2), rn->m_taDPolElQuad[z](1,0,0), rn->m_taDPolElQuad[z](1,0,1), rn->m_taDPolElQuad[z](1,0,2), rn->m_taDPolElQuad[z](1,1,0), rn->m_taDPolElQuad[z](1,1,1), rn->m_taDPolElQuad[z](1,1,2), rn->m_taDPolElQuad[z](1,2,0), rn->m_taDPolElQuad[z](1,2,1), rn->m_taDPolElQuad[z](1,2,2), rn->m_taDPolElQuad[z](2,0,0), rn->m_taDPolElQuad[z](2,0,1), rn->m_taDPolElQuad[z](2,0,2), rn->m_taDPolElQuad[z](2,1,0), rn->m_taDPolElQuad[z](2,1,1), rn->m_taDPolElQuad[z](2,1,2), rn->m_taDPolElQuad[z](2,2,0), rn->m_taDPolElQuad[z](2,2,1), rn->m_taDPolElQuad[z](2,2,2) ); } if (m_bMagMom && m_bPola) { mfprintf(a,"; %.10G; %.10G; %.10G; %.10G; %.10G; %.10G; %.10G; %.10G; %.10G", rn->m_maDPolMagDip[z](0,0), rn->m_maDPolMagDip[z](0,1), rn->m_maDPolMagDip[z](0,2), rn->m_maDPolMagDip[z](1,0), rn->m_maDPolMagDip[z](1,1), rn->m_maDPolMagDip[z](1,2), rn->m_maDPolMagDip[z](2,0), rn->m_maDPolMagDip[z](2,1), rn->m_maDPolMagDip[z](2,2) ); } mfprintf(a,"\n"); //fflush(a); } mprintf(WHITE,"]\n"); fclose(a); } if (m_bWriteACFs) { b2 = false; _normalized: buf.sprintf("acfs"); if (b) buf.strcat("_smooth"); if (b2) buf.strcat("_normalized"); buf.strcat(".csv"); mprintf(" Writing autocorrelation functions to \"%s\"...\n",(const char*)buf); a = OpenFileWrite((const char*)buf,true); ac = new CAutoCorrelation(); ac->Init(m_iStepsProcessed-2,m_oaObservations[0]->m_iDepth,g_bACFFFT); dain.SetSize(m_iStepsProcessed-2); daout.SetSize(m_oaObservations[0]->m_iDepth); fft = new CFFT(); fft->PrepareFFT_C2C(2*(m_oaObservations[0]->m_iDepth+m_oaObservations[0]->m_iZeroPadding)); temp.resize(2*(m_oaObservations[0]->m_iDepth+m_oaObservations[0]->m_iZeroPadding)); buf2 = ""; tfs = 64 / 60.0; mprintf(WHITE," ["); for (z=0;z<64;z++) { if (fmod(z,tfs) < 1.0) mprintf(WHITE,"#"); if (!m_bMagMom) if (((z >= 13) && (z <= 18)) || ((z >= 55) && (z <= 63))) continue; if (!m_bPola) if ((z >= 19) && (z <= 63)) continue; daacf[z].SetSize(m_oaObservations[0]->m_iDepth); for (z2=0;z2m_iDepth;z2++) daacf[z][z2] = 0; for (z2=0;z2m_oaMolecules[z2]; switch(z) { case 0: for (z3=0;z3m_faDCharge[z3]; if (z2 == 0) buf2 += "; DCharge"; break; case 1: for (z3=0;z3m_vaDElDip[z3][0]; if (z2 == 0) buf2 += "; DElDipX"; break; case 2: for (z3=0;z3m_vaDElDip[z3][1]; if (z2 == 0) buf2 += "; DElDipY"; break; case 3: for (z3=0;z3m_vaDElDip[z3][2]; if (z2 == 0) buf2 += "; DElDipZ"; break; case 4: for (z3=0;z3m_maDElQuad[z3][0]; if (z2 == 0) buf2 += "; DElQuadXX"; break; case 5: for (z3=0;z3m_maDElQuad[z3][1]; if (z2 == 0) buf2 += "; DElQuadXY"; break; case 6: for (z3=0;z3m_maDElQuad[z3][2]; if (z2 == 0) buf2 += "; DElQuadXZ"; break; case 7: for (z3=0;z3m_maDElQuad[z3][3]; if (z2 == 0) buf2 += "; DElQuadYX"; break; case 8: for (z3=0;z3m_maDElQuad[z3][4]; if (z2 == 0) buf2 += "; DElQuadYY"; break; case 9: for (z3=0;z3m_maDElQuad[z3][5]; if (z2 == 0) buf2 += "; DElQuadYZ"; break; case 10: for (z3=0;z3m_maDElQuad[z3][6]; if (z2 == 0) buf2 += "; DElQuadZX"; break; case 11: for (z3=0;z3m_maDElQuad[z3][7]; if (z2 == 0) buf2 += "; DElQuadZY"; break; case 12: for (z3=0;z3m_maDElQuad[z3][8]; if (z2 == 0) buf2 += "; DElQuadZZ"; break; case 13: for (z3=0;z3m_vaDElCurr[z3][0]; if (z2 == 0) buf2 += "; DElCurrX"; break; case 14: for (z3=0;z3m_vaDElCurr[z3][1]; if (z2 == 0) buf2 += "; DElCurrY"; break; case 15: for (z3=0;z3m_vaDElCurr[z3][2]; if (z2 == 0) buf2 += "; DElCurrZ"; break; case 16: for (z3=0;z3m_vaDMagDip[z3][0]; if (z2 == 0) buf2 += "; DMagDipX"; break; case 17: for (z3=0;z3m_vaDMagDip[z3][1]; if (z2 == 0) buf2 += "; DMagDipY"; break; case 18: for (z3=0;z3m_vaDMagDip[z3][2]; if (z2 == 0) buf2 += "; DMagDipZ"; break; case 19: for (z3=0;z3m_maDPolElDip[z3][0]; if (z2 == 0) buf2 += "; DPolElDipXX"; break; case 20: for (z3=0;z3m_maDPolElDip[z3][1]; if (z2 == 0) buf2 += "; DPolElDipXY"; break; case 21: for (z3=0;z3m_maDPolElDip[z3][2]; if (z2 == 0) buf2 += "; DPolElDipXZ"; break; case 22: for (z3=0;z3m_maDPolElDip[z3][3]; if (z2 == 0) buf2 += "; DPolElDipYX"; break; case 23: for (z3=0;z3m_maDPolElDip[z3][4]; if (z2 == 0) buf2 += "; DPolElDipYY"; break; case 24: for (z3=0;z3m_maDPolElDip[z3][5]; if (z2 == 0) buf2 += "; DPolElDipYZ"; break; case 25: for (z3=0;z3m_maDPolElDip[z3][6]; if (z2 == 0) buf2 += "; DPolElDipZX"; break; case 26: for (z3=0;z3m_maDPolElDip[z3][7]; if (z2 == 0) buf2 += "; DPolElDipZY"; break; case 27: for (z3=0;z3m_maDPolElDip[z3][8]; if (z2 == 0) buf2 += "; DPolElDipZZ"; break; case 28: for (z3=0;z3m_taDPolElQuad[z3][0]; if (z2 == 0) buf2 += "; DPolElQuadXXX"; break; case 29: for (z3=0;z3m_taDPolElQuad[z3][1]; if (z2 == 0) buf2 += "; DPolElQuadXXY"; break; case 30: for (z3=0;z3m_taDPolElQuad[z3][2]; if (z2 == 0) buf2 += "; DPolElQuadXXZ"; break; case 31: for (z3=0;z3m_taDPolElQuad[z3][3]; if (z2 == 0) buf2 += "; DPolElQuadXYX"; break; case 32: for (z3=0;z3m_taDPolElQuad[z3][4]; if (z2 == 0) buf2 += "; DPolElQuadXYY"; break; case 33: for (z3=0;z3m_taDPolElQuad[z3][5]; if (z2 == 0) buf2 += "; DPolElQuadXYZ"; break; case 34: for (z3=0;z3m_taDPolElQuad[z3][6]; if (z2 == 0) buf2 += "; DPolElQuadXZX"; break; case 35: for (z3=0;z3m_taDPolElQuad[z3][7]; if (z2 == 0) buf2 += "; DPolElQuadXZY"; break; case 36: for (z3=0;z3m_taDPolElQuad[z3][8]; if (z2 == 0) buf2 += "; DPolElQuadXZZ"; break; case 37: for (z3=0;z3m_taDPolElQuad[z3][9]; if (z2 == 0) buf2 += "; DPolElQuadYXX"; break; case 38: for (z3=0;z3m_taDPolElQuad[z3][10]; if (z2 == 0) buf2 += "; DPolElQuadYXY"; break; case 39: for (z3=0;z3m_taDPolElQuad[z3][11]; if (z2 == 0) buf2 += "; DPolElQuadYXZ"; break; case 40: for (z3=0;z3m_taDPolElQuad[z3][12]; if (z2 == 0) buf2 += "; DPolElQuadYYX"; break; case 41: for (z3=0;z3m_taDPolElQuad[z3][13]; if (z2 == 0) buf2 += "; DPolElQuadYYY"; break; case 42: for (z3=0;z3m_taDPolElQuad[z3][14]; if (z2 == 0) buf2 += "; DPolElQuadYYZ"; break; case 43: for (z3=0;z3m_taDPolElQuad[z3][15]; if (z2 == 0) buf2 += "; DPolElQuadYZX"; break; case 44: for (z3=0;z3m_taDPolElQuad[z3][16]; if (z2 == 0) buf2 += "; DPolElQuadYZY"; break; case 45: for (z3=0;z3m_taDPolElQuad[z3][17]; if (z2 == 0) buf2 += "; DPolElQuadYZZ"; break; case 46: for (z3=0;z3m_taDPolElQuad[z3][18]; if (z2 == 0) buf2 += "; DPolElQuadZXX"; break; case 47: for (z3=0;z3m_taDPolElQuad[z3][19]; if (z2 == 0) buf2 += "; DPolElQuadZXY"; break; case 48: for (z3=0;z3m_taDPolElQuad[z3][20]; if (z2 == 0) buf2 += "; DPolElQuadZXZ"; break; case 49: for (z3=0;z3m_taDPolElQuad[z3][21]; if (z2 == 0) buf2 += "; DPolElQuadZYX"; break; case 50: for (z3=0;z3m_taDPolElQuad[z3][22]; if (z2 == 0) buf2 += "; DPolElQuadZYY"; break; case 51: for (z3=0;z3m_taDPolElQuad[z3][23]; if (z2 == 0) buf2 += "; DPolElQuadZYZ"; break; case 52: for (z3=0;z3m_taDPolElQuad[z3][24]; if (z2 == 0) buf2 += "; DPolElQuadZZX"; break; case 53: for (z3=0;z3m_taDPolElQuad[z3][25]; if (z2 == 0) buf2 += "; DPolElQuadZZY"; break; case 54: for (z3=0;z3m_taDPolElQuad[z3][26]; if (z2 == 0) buf2 += "; DPolElQuadZZZ"; break; case 55: for (z3=0;z3m_maDPolMagDip[z3][0]; if (z2 == 0) buf2 += "; DPolMagDipXX"; break; case 56: for (z3=0;z3m_maDPolMagDip[z3][1]; if (z2 == 0) buf2 += "; DPolMagDipXY"; break; case 57: for (z3=0;z3m_maDPolMagDip[z3][2]; if (z2 == 0) buf2 += "; DPolMagDipXZ"; break; case 58: for (z3=0;z3m_maDPolMagDip[z3][3]; if (z2 == 0) buf2 += "; DPolMagDipYX"; break; case 59: for (z3=0;z3m_maDPolMagDip[z3][4]; if (z2 == 0) buf2 += "; DPolMagDipYY"; break; case 60: for (z3=0;z3m_maDPolMagDip[z3][5]; if (z2 == 0) buf2 += "; DPolMagDipYZ"; break; case 61: for (z3=0;z3m_maDPolMagDip[z3][6]; if (z2 == 0) buf2 += "; DPolMagDipZX"; break; case 62: for (z3=0;z3m_maDPolMagDip[z3][7]; if (z2 == 0) buf2 += "; DPolMagDipZY"; break; case 63: for (z3=0;z3m_maDPolMagDip[z3][8]; if (z2 == 0) buf2 += "; DPolMagDipZZ"; break; } ac->AutoCorrelate(&dain,&daout); for (z3=0;z3m_iDepth;z3++) daacf[z][z3] += daout[z3]; } for (z3=0;z3m_iDepth;z3++) daacf[z][z3] /= (double)g_oaSingleMolecules.GetSize(); if (b2) { f = daacf[z][0]; for (z3=0;z3m_iDepth;z3++) daacf[z][z3] /= f; } for (z3=0;z3m_iDepth;z3++) temp[z3] = daacf[z][z3]; for (z3=m_oaObservations[0]->m_iDepth;z3m_iDepth+m_oaObservations[0]->m_iZeroPadding;z3++) temp[z3] = 0.0; for (z3=0;z3m_iDepth;z3++) temp[z3] *= pow2(cos((double)z3 / (m_oaObservations[0]->m_iDepth - 1) / 2.0 * Pi)); o = m_oaObservations[0]->m_iDepth+m_oaObservations[0]->m_iZeroPadding; for (z3=1;z3m_iDepth+m_oaObservations[0]->m_iZeroPadding);z3++) { fft->m_pInput[2*z3] = temp[z3]; fft->m_pInput[2*z3+1] = 0.0; } fft->DoFFT(); daspec[z].SetSize(m_oaObservations[0]->m_iSpecLength); for (z3=0;z3m_iSpecLength;z3++) daspec[z][z3] = fft->m_pOutput[2*z3]; f = m_oaObservations[0]->m_fSpecResolution * g_fTimestepLength * g_iStride * 1.883652e-4; for (z3=1;z3m_iSpecLength;z3++) daspec[z][z3] *= pow2(f * z3 / sin(f * z3)); // Divide by sinc function to correct finite difference derivation } delete ac; delete fft; mprintf(WHITE,"]\n"); mfprintf(a,"#Depth[fs]%s\n",(const char*)buf2); for (z=0;zm_iDepth;z++) { mfprintf(a,"%.2f",z*g_fTimestepLength*g_iStride); for (z2=0;z2<64;z2++) { if (!m_bMagMom) if (((z2 >= 13) && (z2 <= 18)) || ((z2 >= 55) && (z2 <= 63))) continue; if (!m_bPola) if ((z2 >= 19) && (z2 <= 63)) continue; mfprintf(a,"; %.10G",daacf[z2][z]); } mfprintf(a,"\n"); } fclose(a); buf.sprintf("acf_spectra"); if (b) buf.strcat("_smooth"); if (b2) buf.strcat("_normalized"); buf.strcat(".csv"); mprintf(" Writing autocorrelation spectra to \"%s\"...\n",(const char*)buf); a = OpenFileWrite((const char*)buf,true); mfprintf(a,"#Wavenumber%s\n",(const char*)buf2); for (z=0;zm_iSpecLength;z++) { mfprintf(a,"%.2f",m_oaObservations[0]->m_fSpecResolution*z); for (z2=0;z2<64;z2++) { if (!m_bMagMom) if (((z2 >= 13) && (z2 <= 18)) || ((z2 >= 55) && (z2 <= 63))) continue; if (!m_bPola) if ((z2 >= 19) && (z2 <= 63)) continue; mfprintf(a,"; %.10G",daspec[z2][z]); } mfprintf(a,"\n"); } fclose(a); if (!b2) { b2 = true; goto _normalized; } } if (m_bSmoothData && !b) { mprintf("\n Smoothing properties...\n\n"); b = true; smo.Init(m_iStepsProcessed,m_fSmoothWaveNumber); for (z=0;z<(int)m_oaTrajectories.size();z++) { for (z2=0;z2m_oaMolecules[z2]->m_faCharge); smo.Smoothen(m_oaTrajectories[z]->m_oaMolecules[z2]->m_vaElDip); smo.Smoothen(m_oaTrajectories[z]->m_oaMolecules[z2]->m_maElQuad); if (m_bMagMom) { smo.Smoothen(m_oaTrajectories[z]->m_oaMolecules[z2]->m_vaElCurr); smo.Smoothen(m_oaTrajectories[z]->m_oaMolecules[z2]->m_vaMagDip); } } } goto _again; } for (z=0;z<(int)m_oaObservations.size();z++) { mprintf(WHITE,"\n * Finishing Observation %d: %s\n", z+1,(const char*)m_oaObservations[z]->m_sName); if (m_iStepsProcessed-2 <= m_oaObservations[z]->m_iDepth) { mprintf(RED," Warning: "); mprintf("The ACF depth (%d) is larger than the number of data points (%d).\n", m_oaObservations[z]->m_iDepth,m_iStepsProcessed-2); mprintf(" The results of this observation will be meaningless.\n"); } mprintf(" Computing ACF...\n"); ComputeACF(m_oaObservations[z]); mprintf(" Computing Spectrum...\n"); ComputeSpectrum(m_oaObservations[z]); } mprintf(WHITE,"\n <<< Finished Analysis <<<\n"); } void CROAEngine::ComputeACFPair(CROAObservation *obs, CROAMolecule *mol1, CROAMolecule *mol2, std::vector *wfn) { int zc, z, zi, zj, zk; //FILE *a; if (wfn != NULL) { for (z=0;zCrossCorrelate(&m_faInput1,&m_faInput2,&m_faOutput); for (z=0;zm_iDepth;z++) obs->m_faWFN[z] += m_faOutput[z]; } /*********************************************************************************************************************/ if (obs->m_iType == ROA_SPECTRUM_IR) { for (zc=0;zc<3;zc++) { if (wfn != NULL) { for (z=0;zm_vaDElDip[z][zc] * (*wfn)[z]; m_faInput2[z] = mol2->m_vaDElDip[z][zc] * (*wfn)[z]; } } else { for (z=0;zm_vaDElDip[z][zc]; m_faInput2[z] = mol2->m_vaDElDip[z][zc]; } } m_pCrossCorr->CrossCorrelate(&m_faInput1,&m_faInput2,&m_faOutput); for (z=0;zm_iDepth;z++) obs->m_faACF[z] += m_faOutput[z]; } /*********************************************************************************************************************/ } else if (obs->m_iType == ROA_SPECTRUM_RAMAN) { // Isotropic Part for (z=0;zm_maDPolElDip[z](0,0) + mol1->m_maDPolElDip[z](1,1) + mol1->m_maDPolElDip[z](2,2)) / 3.0; m_faInput2[z] = (mol2->m_maDPolElDip[z](0,0) + mol2->m_maDPolElDip[z](1,1) + mol2->m_maDPolElDip[z](2,2)) / 3.0; } m_pCrossCorr->CrossCorrelate(&m_faInput1,&m_faInput2,&m_faOutput); for (z=0;zm_iDepth;z++) obs->m_faACF[z] += m_faOutput[z]; if (obs->m_bUseCommutator) { for (z=0;zm_iDepth;z++) { obs->m_faACF_CTP[z] += 0.5 * m_faOutput[z]; obs->m_faACF_CTN[z] += 0.5 * m_faOutput[z]; } m_pCrossCorr->CrossCorrelate(&m_faInput2,&m_faInput1,&m_faOutput); for (z=0;zm_iDepth;z++) { obs->m_faACF_CTP[z] += 0.5 * m_faOutput[z]; obs->m_faACF_CTN[z] -= 0.5 * m_faOutput[z]; } } // First Anisotropic Part for (z=0;zm_maDPolElDip[z](0,0) - mol1->m_maDPolElDip[z](1,1); m_faInput2[z] = mol2->m_maDPolElDip[z](0,0) - mol2->m_maDPolElDip[z](1,1); } m_pCrossCorr->CrossCorrelate(&m_faInput1,&m_faInput2,&m_faOutput); for (z=0;zm_iDepth;z++) obs->m_faACF2[z] += m_faOutput[z] / 2.0; if (obs->m_bUseCommutator) { for (z=0;zm_iDepth;z++) { obs->m_faACF2_CTP[z] += 0.5 * m_faOutput[z]; obs->m_faACF2_CTN[z] += 0.5 * m_faOutput[z]; } m_pCrossCorr->CrossCorrelate(&m_faInput2,&m_faInput1,&m_faOutput); for (z=0;zm_iDepth;z++) { obs->m_faACF2_CTP[z] += 0.5 * m_faOutput[z]; obs->m_faACF2_CTN[z] -= 0.5 * m_faOutput[z]; } } // Second Anisotropic Part for (z=0;zm_maDPolElDip[z](1,1) - mol1->m_maDPolElDip[z](2,2); m_faInput2[z] = mol2->m_maDPolElDip[z](1,1) - mol2->m_maDPolElDip[z](2,2); } m_pCrossCorr->CrossCorrelate(&m_faInput1,&m_faInput2,&m_faOutput); for (z=0;zm_iDepth;z++) obs->m_faACF2[z] += m_faOutput[z] / 2.0; if (obs->m_bUseCommutator) { for (z=0;zm_iDepth;z++) { obs->m_faACF2_CTP[z] += 0.5 * m_faOutput[z]; obs->m_faACF2_CTN[z] += 0.5 * m_faOutput[z]; } m_pCrossCorr->CrossCorrelate(&m_faInput2,&m_faInput1,&m_faOutput); for (z=0;zm_iDepth;z++) { obs->m_faACF2_CTP[z] += 0.5 * m_faOutput[z]; obs->m_faACF2_CTN[z] -= 0.5 * m_faOutput[z]; } } // Third Anisotropic Part for (z=0;zm_maDPolElDip[z](2,2) - mol1->m_maDPolElDip[z](0,0); m_faInput2[z] = mol2->m_maDPolElDip[z](2,2) - mol2->m_maDPolElDip[z](0,0); } m_pCrossCorr->CrossCorrelate(&m_faInput1,&m_faInput2,&m_faOutput); for (z=0;zm_iDepth;z++) obs->m_faACF2[z] += m_faOutput[z] / 2.0; if (obs->m_bUseCommutator) { for (z=0;zm_iDepth;z++) { obs->m_faACF2_CTP[z] += 0.5 * m_faOutput[z]; obs->m_faACF2_CTN[z] += 0.5 * m_faOutput[z]; } m_pCrossCorr->CrossCorrelate(&m_faInput2,&m_faInput1,&m_faOutput); for (z=0;zm_iDepth;z++) { obs->m_faACF2_CTP[z] += 0.5 * m_faOutput[z]; obs->m_faACF2_CTN[z] -= 0.5 * m_faOutput[z]; } } // Fourth Anisotropic Part for (z=0;zm_maDPolElDip[z](0,1); m_faInput2[z] = mol2->m_maDPolElDip[z](0,1); } m_pCrossCorr->CrossCorrelate(&m_faInput1,&m_faInput2,&m_faOutput); for (z=0;zm_iDepth;z++) obs->m_faACF2[z] += m_faOutput[z] * 3.0; if (obs->m_bUseCommutator) { for (z=0;zm_iDepth;z++) { obs->m_faACF2_CTP[z] += 0.5 * m_faOutput[z]; obs->m_faACF2_CTN[z] += 0.5 * m_faOutput[z]; } m_pCrossCorr->CrossCorrelate(&m_faInput2,&m_faInput1,&m_faOutput); for (z=0;zm_iDepth;z++) { obs->m_faACF2_CTP[z] += 0.5 * m_faOutput[z]; obs->m_faACF2_CTN[z] -= 0.5 * m_faOutput[z]; } } // Fifth Anisotropic Part for (z=0;zm_maDPolElDip[z](1,2); m_faInput2[z] = mol2->m_maDPolElDip[z](1,2); } m_pCrossCorr->CrossCorrelate(&m_faInput1,&m_faInput2,&m_faOutput); for (z=0;zm_iDepth;z++) obs->m_faACF2[z] += m_faOutput[z] * 3.0; if (obs->m_bUseCommutator) { for (z=0;zm_iDepth;z++) { obs->m_faACF2_CTP[z] += 0.5 * m_faOutput[z]; obs->m_faACF2_CTN[z] += 0.5 * m_faOutput[z]; } m_pCrossCorr->CrossCorrelate(&m_faInput2,&m_faInput1,&m_faOutput); for (z=0;zm_iDepth;z++) { obs->m_faACF2_CTP[z] += 0.5 * m_faOutput[z]; obs->m_faACF2_CTN[z] -= 0.5 * m_faOutput[z]; } } // Sixth Anisotropic Part for (z=0;zm_maDPolElDip[z](2,0); m_faInput2[z] = mol2->m_maDPolElDip[z](2,0); } m_pCrossCorr->CrossCorrelate(&m_faInput1,&m_faInput2,&m_faOutput); for (z=0;zm_iDepth;z++) obs->m_faACF2[z] += m_faOutput[z] * 3.0; if (obs->m_bUseCommutator) { for (z=0;zm_iDepth;z++) { obs->m_faACF2_CTP[z] += 0.5 * m_faOutput[z]; obs->m_faACF2_CTN[z] += 0.5 * m_faOutput[z]; } m_pCrossCorr->CrossCorrelate(&m_faInput2,&m_faInput1,&m_faOutput); for (z=0;zm_iDepth;z++) { obs->m_faACF2_CTP[z] += 0.5 * m_faOutput[z]; obs->m_faACF2_CTN[z] -= 0.5 * m_faOutput[z]; } } /*********************************************************************************************************************/ } else if (obs->m_iType == ROA_SPECTRUM_VCD) { for (zc=0;zc<3;zc++) { for (z=0;zm_vaDElDip[z][zc]; m_faInput2[z] = mol2->m_vaDMagDip[z][zc]; } m_pCrossCorr->CrossCorrelate(&m_faInput1,&m_faInput2,&m_faOutput); for (z=0;zm_iDepth;z++) obs->m_faACF[z] += m_faOutput[z]; if (obs->m_bUseCommutator) { for (z=0;zm_iDepth;z++) { obs->m_faACF_CTP[z] += 0.5 * m_faOutput[z]; obs->m_faACF_CTN[z] += 0.5 * m_faOutput[z]; } m_pCrossCorr->CrossCorrelate(&m_faInput2,&m_faInput1,&m_faOutput); for (z=0;zm_iDepth;z++) { obs->m_faACF_CTP[z] += 0.5 * m_faOutput[z]; obs->m_faACF_CTN[z] -= 0.5 * m_faOutput[z]; } } } /*********************************************************************************************************************/ } else if (obs->m_iType == ROA_SPECTRUM_SFG) { for (zi=0;zi<3;zi++){ for (zj=0;zj<3;zj++){ for (zk=0;zk<3;zk++){ for (z=0;zm_maDPolElDip[z](zi,zj); m_faInput2[z] = mol2->m_vaDElDip[z][zk]; } m_pCrossCorr->CrossCorrelate(&m_faInput1,&m_faInput2,&m_faOutput); for (z=0;zm_iDepth;z++) obs->m_faACF[z] += m_faOutput[z]; if (obs->m_bSingleACFs) for (z=0;zm_iDepth;z++) obs->m_faaSingleACFs[zi*9+zj*3+zk][z] += m_faOutput[z]; } } } /*********************************************************************************************************************/ } else if (obs->m_iType == ROA_SPECTRUM_ROA) { // aG for (z=0;zm_maDPolElDip[z](0,0) + mol1->m_maDPolElDip[z](1,1) + mol1->m_maDPolElDip[z](2,2)) / 3.0; // Unit: e*pm^3/(V*fs^2) m_faInput2[z] = -(mol2->m_maDPolMagDip[z](0,0) + mol2->m_maDPolMagDip[z](1,1) + mol2->m_maDPolMagDip[z](1,1)) / 3.0; } m_pCrossCorr->CrossCorrelate(&m_faInput1,&m_faInput2,&m_faOutput); for (z=0;zm_iDepth;z++) obs->m_faACF[z] += m_faOutput[z]; // Unit: e^2*pm^5/(V^2*fs^3) if (obs->m_bUseCommutator) { for (z=0;zm_iDepth;z++) { obs->m_faACF_CTP[z] += 0.5 * m_faOutput[z]; obs->m_faACF_CTN[z] += 0.5 * m_faOutput[z]; } m_pCrossCorr->CrossCorrelate(&m_faInput2,&m_faInput1,&m_faOutput); for (z=0;zm_iDepth;z++) { obs->m_faACF_CTP[z] += 0.5 * m_faOutput[z]; obs->m_faACF_CTN[z] -= 0.5 * m_faOutput[z]; } } // GammaG - Part 1 for (z=0;zm_maDPolElDip[z](0,0) - mol1->m_maDPolElDip[z](1,1); // Unit: e*pm^3/(V*fs^2) m_faInput2[z] = -(mol2->m_maDPolMagDip[z](0,0) - mol2->m_maDPolMagDip[z](1,1)); } m_pCrossCorr->CrossCorrelate(&m_faInput1,&m_faInput2,&m_faOutput); for (z=0;zm_iDepth;z++) obs->m_faACF2[z] += m_faOutput[z] / 2.0; // Unit: e^2*pm^5/(V^2*fs^3) if (obs->m_bUseCommutator) { for (z=0;zm_iDepth;z++) { obs->m_faACF2_CTP[z] += 0.5 * m_faOutput[z] / 2.0; obs->m_faACF2_CTN[z] += 0.5 * m_faOutput[z] / 2.0; } m_pCrossCorr->CrossCorrelate(&m_faInput2,&m_faInput1,&m_faOutput); for (z=0;zm_iDepth;z++) { obs->m_faACF2_CTP[z] += 0.5 * m_faOutput[z] / 2.0; obs->m_faACF2_CTN[z] -= 0.5 * m_faOutput[z] / 2.0; } } // GammaG - Part 2 for (z=0;zm_maDPolElDip[z](1,1) - mol1->m_maDPolElDip[z](2,2); m_faInput2[z] = -(mol2->m_maDPolMagDip[z](1,1) - mol2->m_maDPolMagDip[z](2,2)); } m_pCrossCorr->CrossCorrelate(&m_faInput1,&m_faInput2,&m_faOutput); for (z=0;zm_iDepth;z++) obs->m_faACF2[z] += m_faOutput[z] / 2.0; if (obs->m_bUseCommutator) { for (z=0;zm_iDepth;z++) { obs->m_faACF2_CTP[z] += 0.5 * m_faOutput[z] / 2.0; obs->m_faACF2_CTN[z] += 0.5 * m_faOutput[z] / 2.0; } m_pCrossCorr->CrossCorrelate(&m_faInput2,&m_faInput1,&m_faOutput); for (z=0;zm_iDepth;z++) { obs->m_faACF2_CTP[z] += 0.5 * m_faOutput[z] / 2.0; obs->m_faACF2_CTN[z] -= 0.5 * m_faOutput[z] / 2.0; } } // GammaG - Part 3 for (z=0;zm_maDPolElDip[z](2,2) - mol1->m_maDPolElDip[z](0,0); m_faInput2[z] = -(mol2->m_maDPolMagDip[z](2,2) - mol2->m_maDPolMagDip[z](0,0)); } m_pCrossCorr->CrossCorrelate(&m_faInput1,&m_faInput2,&m_faOutput); for (z=0;zm_iDepth;z++) obs->m_faACF2[z] += m_faOutput[z] / 2.0; if (obs->m_bUseCommutator) { for (z=0;zm_iDepth;z++) { obs->m_faACF2_CTP[z] += 0.5 * m_faOutput[z] / 2.0; obs->m_faACF2_CTN[z] += 0.5 * m_faOutput[z] / 2.0; } m_pCrossCorr->CrossCorrelate(&m_faInput2,&m_faInput1,&m_faOutput); for (z=0;zm_iDepth;z++) { obs->m_faACF2_CTP[z] += 0.5 * m_faOutput[z] / 2.0; obs->m_faACF2_CTN[z] -= 0.5 * m_faOutput[z] / 2.0; } } // GammaG - Part 4 for (z=0;zm_maDPolElDip[z](0,1); m_faInput2[z] = -(mol2->m_maDPolMagDip[z](0,1) + mol2->m_maDPolMagDip[z](1,0)); } m_pCrossCorr->CrossCorrelate(&m_faInput1,&m_faInput2,&m_faOutput); for (z=0;zm_iDepth;z++) obs->m_faACF2[z] += m_faOutput[z] * 1.5; if (obs->m_bUseCommutator) { for (z=0;zm_iDepth;z++) { obs->m_faACF2_CTP[z] += 0.5 * m_faOutput[z] * 1.5; obs->m_faACF2_CTN[z] += 0.5 * m_faOutput[z] * 1.5; } m_pCrossCorr->CrossCorrelate(&m_faInput2,&m_faInput1,&m_faOutput); for (z=0;zm_iDepth;z++) { obs->m_faACF2_CTP[z] += 0.5 * m_faOutput[z] * 1.5; obs->m_faACF2_CTN[z] -= 0.5 * m_faOutput[z] * 1.5; } } // GammaG - Part 5 for (z=0;zm_maDPolElDip[z](1,2); m_faInput2[z] = -(mol2->m_maDPolMagDip[z](1,2) + mol2->m_maDPolMagDip[z](2,1)); } m_pCrossCorr->CrossCorrelate(&m_faInput1,&m_faInput2,&m_faOutput); for (z=0;zm_iDepth;z++) obs->m_faACF2[z] += m_faOutput[z] * 1.5; if (obs->m_bUseCommutator) { for (z=0;zm_iDepth;z++) { obs->m_faACF2_CTP[z] += 0.5 * m_faOutput[z] * 1.5; obs->m_faACF2_CTN[z] += 0.5 * m_faOutput[z] * 1.5; } m_pCrossCorr->CrossCorrelate(&m_faInput2,&m_faInput1,&m_faOutput); for (z=0;zm_iDepth;z++) { obs->m_faACF2_CTP[z] += 0.5 * m_faOutput[z] * 1.5; obs->m_faACF2_CTN[z] -= 0.5 * m_faOutput[z] * 1.5; } } // GammaG - Part 6 for (z=0;zm_maDPolElDip[z](2,0); m_faInput2[z] = -(mol2->m_maDPolMagDip[z](2,0) + mol2->m_maDPolMagDip[z](0,2)); } m_pCrossCorr->CrossCorrelate(&m_faInput1,&m_faInput2,&m_faOutput); for (z=0;zm_iDepth;z++) obs->m_faACF2[z] += m_faOutput[z] * 1.5; if (obs->m_bUseCommutator) { for (z=0;zm_iDepth;z++) { obs->m_faACF2_CTP[z] += 0.5 * m_faOutput[z] * 1.5; obs->m_faACF2_CTN[z] += 0.5 * m_faOutput[z] * 1.5; } m_pCrossCorr->CrossCorrelate(&m_faInput2,&m_faInput1,&m_faOutput); for (z=0;zm_iDepth;z++) { obs->m_faACF2_CTP[z] += 0.5 * m_faOutput[z] * 1.5; obs->m_faACF2_CTN[z] -= 0.5 * m_faOutput[z] * 1.5; } } // GammaA - Part 1 for (z=0;zm_maDPolElDip[z](1,1) - mol1->m_maDPolElDip[z](0,0); // Unit: e*pm^3/(V*fs) m_faInput2[z] = mol2->m_taDPolElQuad[z](2,0,1); } m_pCrossCorr->CrossCorrelate(&m_faInput1,&m_faInput2,&m_faOutput); for (z=0;zm_iDepth;z++) // Unit: e^2*pm^5/(V^2*fs^3) obs->m_faACF3[z] += m_faOutput[z] / 2.0 * 1.0E-15 * obs->m_fLaserFreq * 100.0 * CONST_SPEED_OF_LIGHT * 2.0 * Pi; if (obs->m_bUseCommutator) { for (z=0;zm_iDepth;z++) { obs->m_faACF3_CTP[z] += 0.5 * m_faOutput[z] / 2.0 * 1.0E-15 * obs->m_fLaserFreq * 100.0 * CONST_SPEED_OF_LIGHT * 2.0 * Pi; obs->m_faACF3_CTN[z] += 0.5 * m_faOutput[z] / 2.0 * 1.0E-15 * obs->m_fLaserFreq * 100.0 * CONST_SPEED_OF_LIGHT * 2.0 * Pi; } m_pCrossCorr->CrossCorrelate(&m_faInput2,&m_faInput1,&m_faOutput); for (z=0;zm_iDepth;z++) { obs->m_faACF3_CTP[z] += 0.5 * m_faOutput[z] / 2.0 * 1.0E-15 * obs->m_fLaserFreq * 100.0 * CONST_SPEED_OF_LIGHT * 2.0 * Pi; obs->m_faACF3_CTN[z] -= 0.5 * m_faOutput[z] / 2.0 * 1.0E-15 * obs->m_fLaserFreq * 100.0 * CONST_SPEED_OF_LIGHT * 2.0 * Pi; } } // GammaA - Part 2 for (z=0;zm_maDPolElDip[z](0,0) - mol1->m_maDPolElDip[z](2,2); m_faInput2[z] = mol2->m_taDPolElQuad[z](1,2,0); } m_pCrossCorr->CrossCorrelate(&m_faInput1,&m_faInput2,&m_faOutput); for (z=0;zm_iDepth;z++) obs->m_faACF3[z] += m_faOutput[z] / 2.0 * 1.0E-15 * obs->m_fLaserFreq * 100.0 * CONST_SPEED_OF_LIGHT * 2.0 * Pi; if (obs->m_bUseCommutator) { for (z=0;zm_iDepth;z++) { obs->m_faACF3_CTP[z] += 0.5 * m_faOutput[z] / 2.0 * 1.0E-15 * obs->m_fLaserFreq * 100.0 * CONST_SPEED_OF_LIGHT * 2.0 * Pi; obs->m_faACF3_CTN[z] += 0.5 * m_faOutput[z] / 2.0 * 1.0E-15 * obs->m_fLaserFreq * 100.0 * CONST_SPEED_OF_LIGHT * 2.0 * Pi; } m_pCrossCorr->CrossCorrelate(&m_faInput2,&m_faInput1,&m_faOutput); for (z=0;zm_iDepth;z++) { obs->m_faACF3_CTP[z] += 0.5 * m_faOutput[z] / 2.0 * 1.0E-15 * obs->m_fLaserFreq * 100.0 * CONST_SPEED_OF_LIGHT * 2.0 * Pi; obs->m_faACF3_CTN[z] -= 0.5 * m_faOutput[z] / 2.0 * 1.0E-15 * obs->m_fLaserFreq * 100.0 * CONST_SPEED_OF_LIGHT * 2.0 * Pi; } } // GammaA - Part 3 for (z=0;zm_maDPolElDip[z](2,2) - mol1->m_maDPolElDip[z](1,1); m_faInput2[z] = mol2->m_taDPolElQuad[z](0,1,2); } m_pCrossCorr->CrossCorrelate(&m_faInput1,&m_faInput2,&m_faOutput); for (z=0;zm_iDepth;z++) obs->m_faACF3[z] += m_faOutput[z] / 2.0 * 1.0E-15 * obs->m_fLaserFreq * 100.0 * CONST_SPEED_OF_LIGHT * 2.0 * Pi; if (obs->m_bUseCommutator) { for (z=0;zm_iDepth;z++) { obs->m_faACF3_CTP[z] += 0.5 * m_faOutput[z] / 2.0 * 1.0E-15 * obs->m_fLaserFreq * 100.0 * CONST_SPEED_OF_LIGHT * 2.0 * Pi; obs->m_faACF3_CTN[z] += 0.5 * m_faOutput[z] / 2.0 * 1.0E-15 * obs->m_fLaserFreq * 100.0 * CONST_SPEED_OF_LIGHT * 2.0 * Pi; } m_pCrossCorr->CrossCorrelate(&m_faInput2,&m_faInput1,&m_faOutput); for (z=0;zm_iDepth;z++) { obs->m_faACF3_CTP[z] += 0.5 * m_faOutput[z] / 2.0 * 1.0E-15 * obs->m_fLaserFreq * 100.0 * CONST_SPEED_OF_LIGHT * 2.0 * Pi; obs->m_faACF3_CTN[z] -= 0.5 * m_faOutput[z] / 2.0 * 1.0E-15 * obs->m_fLaserFreq * 100.0 * CONST_SPEED_OF_LIGHT * 2.0 * Pi; } } // GammaA - Part 4 for (z=0;zm_maDPolElDip[z](0,1); m_faInput2[z] = mol2->m_taDPolElQuad[z](1,1,2) - mol2->m_taDPolElQuad[z](2,1,1) + mol2->m_taDPolElQuad[z](2,0,0) - mol2->m_taDPolElQuad[z](0,0,2); } m_pCrossCorr->CrossCorrelate(&m_faInput1,&m_faInput2,&m_faOutput); for (z=0;zm_iDepth;z++) obs->m_faACF3[z] += m_faOutput[z] / 2.0 * 1.0E-15 * obs->m_fLaserFreq * 100.0 * CONST_SPEED_OF_LIGHT * 2.0 * Pi; if (obs->m_bUseCommutator) { for (z=0;zm_iDepth;z++) { obs->m_faACF3_CTP[z] += 0.5 * m_faOutput[z] / 2.0 * 1.0E-15 * obs->m_fLaserFreq * 100.0 * CONST_SPEED_OF_LIGHT * 2.0 * Pi; obs->m_faACF3_CTN[z] += 0.5 * m_faOutput[z] / 2.0 * 1.0E-15 * obs->m_fLaserFreq * 100.0 * CONST_SPEED_OF_LIGHT * 2.0 * Pi; } m_pCrossCorr->CrossCorrelate(&m_faInput2,&m_faInput1,&m_faOutput); for (z=0;zm_iDepth;z++) { obs->m_faACF3_CTP[z] += 0.5 * m_faOutput[z] / 2.0 * 1.0E-15 * obs->m_fLaserFreq * 100.0 * CONST_SPEED_OF_LIGHT * 2.0 * Pi; obs->m_faACF3_CTN[z] -= 0.5 * m_faOutput[z] / 2.0 * 1.0E-15 * obs->m_fLaserFreq * 100.0 * CONST_SPEED_OF_LIGHT * 2.0 * Pi; } } // GammaA - Part 5 for (z=0;zm_maDPolElDip[z](1,2); m_faInput2[z] = mol2->m_taDPolElQuad[z](2,2,0) - mol2->m_taDPolElQuad[z](0,2,2) + mol2->m_taDPolElQuad[z](0,1,1) - mol2->m_taDPolElQuad[z](1,1,0); } m_pCrossCorr->CrossCorrelate(&m_faInput1,&m_faInput2,&m_faOutput); for (z=0;zm_iDepth;z++) obs->m_faACF3[z] += m_faOutput[z] / 2.0 * 1.0E-15 * obs->m_fLaserFreq * 100.0 * CONST_SPEED_OF_LIGHT * 2.0 * Pi; if (obs->m_bUseCommutator) { for (z=0;zm_iDepth;z++) { obs->m_faACF3_CTP[z] += 0.5 * m_faOutput[z] / 2.0 * 1.0E-15 * obs->m_fLaserFreq * 100.0 * CONST_SPEED_OF_LIGHT * 2.0 * Pi; obs->m_faACF3_CTN[z] += 0.5 * m_faOutput[z] / 2.0 * 1.0E-15 * obs->m_fLaserFreq * 100.0 * CONST_SPEED_OF_LIGHT * 2.0 * Pi; } m_pCrossCorr->CrossCorrelate(&m_faInput2,&m_faInput1,&m_faOutput); for (z=0;zm_iDepth;z++) { obs->m_faACF3_CTP[z] += 0.5 * m_faOutput[z] / 2.0 * 1.0E-15 * obs->m_fLaserFreq * 100.0 * CONST_SPEED_OF_LIGHT * 2.0 * Pi; obs->m_faACF3_CTN[z] -= 0.5 * m_faOutput[z] / 2.0 * 1.0E-15 * obs->m_fLaserFreq * 100.0 * CONST_SPEED_OF_LIGHT * 2.0 * Pi; } } // GammaA - Part 6 for (z=0;zm_maDPolElDip[z](2,0); m_faInput2[z] = mol2->m_taDPolElQuad[z](1,2,2) - mol2->m_taDPolElQuad[z](2,2,1) + mol2->m_taDPolElQuad[z](0,0,1) - mol2->m_taDPolElQuad[z](1,0,0); } m_pCrossCorr->CrossCorrelate(&m_faInput1,&m_faInput2,&m_faOutput); for (z=0;zm_iDepth;z++) obs->m_faACF3[z] += m_faOutput[z] / 2.0 * 1.0E-15 * obs->m_fLaserFreq * 100.0 * CONST_SPEED_OF_LIGHT * 2.0 * Pi; if (obs->m_bUseCommutator) { for (z=0;zm_iDepth;z++) { obs->m_faACF3_CTP[z] += 0.5 * m_faOutput[z] / 2.0 * 1.0E-15 * obs->m_fLaserFreq * 100.0 * CONST_SPEED_OF_LIGHT * 2.0 * Pi; obs->m_faACF3_CTN[z] += 0.5 * m_faOutput[z] / 2.0 * 1.0E-15 * obs->m_fLaserFreq * 100.0 * CONST_SPEED_OF_LIGHT * 2.0 * Pi; } m_pCrossCorr->CrossCorrelate(&m_faInput2,&m_faInput1,&m_faOutput); for (z=0;zm_iDepth;z++) { obs->m_faACF3_CTP[z] += 0.5 * m_faOutput[z] / 2.0 * 1.0E-15 * obs->m_fLaserFreq * 100.0 * CONST_SPEED_OF_LIGHT * 2.0 * Pi; obs->m_faACF3_CTN[z] -= 0.5 * m_faOutput[z] / 2.0 * 1.0E-15 * obs->m_fLaserFreq * 100.0 * CONST_SPEED_OF_LIGHT * 2.0 * Pi; } } /*********************************************************************************************************************/ } else { eprintf("CROAEngine::ComputeACFPair(): Error: Unknown spectrum type %d.\n",obs->m_iType); abort(); } } //int g_iTC=0; void CROAEngine::ComputeACF(CROAObservation *obs) { int z, z2, z3, z4, imol, imol2, acc; double pc, tfs; CROATrajectory *tr; CxString buf; std::vector wfn; try { m_pCrossCorr = new CCrossCorrelation(); } catch(...) { m_pCrossCorr = NULL; } if (m_pCrossCorr == NULL) NewException((double)sizeof(CCrossCorrelation), __FILE__, __LINE__, __PRETTY_FUNCTION__); m_pCrossCorr->Init(m_iStepsProcessed-2, obs->m_iDepth, g_bACFFFT); m_faInput1.SetSize(m_iStepsProcessed-2); m_faInput2.SetSize(m_iStepsProcessed-2); m_faOutput.SetSize(obs->m_iDepth); obs->m_faACF.resize(obs->m_iDepth); obs->m_faACF2.resize(obs->m_iDepth); obs->m_faACF3.resize(obs->m_iDepth); obs->m_faACF4.resize(obs->m_iDepth); for (z=0;zm_iDepth;z++) { obs->m_faACF[z] = 0; obs->m_faACF2[z] = 0; obs->m_faACF3[z] = 0; obs->m_faACF4[z] = 0; } if (obs->m_bSingleACFs && m_bSFG) { obs->m_faaSingleACFs.resize(27); for (z=0;z<27;z++) { obs->m_faaSingleACFs[z].resize(obs->m_iDepth); for (z2=0;z2m_iDepth;z2++) obs->m_faaSingleACFs[z][z2] = 0; } } if (obs->m_bUseCommutator) { obs->m_faACF_CTP.resize(obs->m_iDepth); obs->m_faACF2_CTP.resize(obs->m_iDepth); obs->m_faACF3_CTP.resize(obs->m_iDepth); obs->m_faACF4_CTP.resize(obs->m_iDepth); obs->m_faACF_CTN.resize(obs->m_iDepth); obs->m_faACF2_CTN.resize(obs->m_iDepth); obs->m_faACF3_CTN.resize(obs->m_iDepth); obs->m_faACF4_CTN.resize(obs->m_iDepth); for (z=0;zm_iDepth;z++) { obs->m_faACF_CTP[z] = 0; obs->m_faACF2_CTP[z] = 0; obs->m_faACF3_CTP[z] = 0; obs->m_faACF4_CTP[z] = 0; obs->m_faACF_CTN[z] = 0; obs->m_faACF2_CTN[z] = 0; obs->m_faACF3_CTN[z] = 0; obs->m_faACF4_CTN[z] = 0; } } tr = m_oaTrajectories[0]; tfs = 0; acc = 0; for (z=0;zm_iaMolSelection[z].size();z2++) { tfs++; acc++; if (obs->m_bCrossCorrelation) { for (z3=0;z3m_iaMolSelection[z3].size();z4++) { if ((z == z3) && (z2 == z4)) continue; tfs++; } } } } } tfs /= 60.0; pc = 0; mprintf(WHITE," ["); for (z=0;zm_iaMolSelection[z].size();z2++) { imol = ((CMolecule*)g_oaMolecules[z])->m_laSingleMolIndex[z2]; ComputeACFPair(obs,tr->m_oaMolecules[imol],tr->m_oaMolecules[imol]); pc++; if (fmod(pc,tfs) < 1.0) mprintf(WHITE,"#"); if (obs->m_bCrossCorrelation) { for (z3=0;z3m_iaMolSelection[z3].size();z4++) { if ((z == z3) && (z2 == z4)) continue; imol2 = ((CMolecule*)g_oaMolecules[z3])->m_laSingleMolIndex[z4]; ComputeACFPair(obs,tr->m_oaMolecules[imol],tr->m_oaMolecules[imol2]); pc++; if (fmod(pc,tfs) < 1.0) mprintf(WHITE,"#"); } } } } } mprintf(WHITE,"]\n"); delete m_pCrossCorr; for (z=0;zm_iDepth;z++) { obs->m_faACF[z] /= pc; obs->m_faACF2[z] /= pc; obs->m_faACF3[z] /= pc; obs->m_faACF4[z] /= pc; } if (obs->m_bUseCommutator) { for (z=0;zm_iDepth;z++) { obs->m_faACF_CTP[z] /= pc; obs->m_faACF2_CTP[z] /= pc; obs->m_faACF3_CTP[z] /= pc; obs->m_faACF4_CTP[z] /= pc; obs->m_faACF_CTN[z] /= pc; obs->m_faACF2_CTN[z] /= pc; obs->m_faACF3_CTN[z] /= pc; obs->m_faACF4_CTN[z] /= pc; } } } void CROAEngine::ComputeSpectrum(CROAObservation *obs, const std::vector &acf, std::vector &spectrum, const char *name, bool im, bool ghack) { int z, o; double f, val; CFFT *fft; std::vector temp; FILE *a; CxString buf, unit; if (obs->m_bSaveACF) { buf.sprintf("acf_%s%s%s",(const char*)obs->m_sTypeName,name,(const char*)obs->m_sMolName); if (obs->m_bCrossCorrelation) buf.strcat("_cc"); if (m_bSmoothData) buf.strcat("_smooth"); buf.strcat(".csv"); mprintf(" Writing ACF to \"%s\"...\n",(const char*)buf); a = OpenFileWrite((const char*)buf,true); mfprintf(a,"#Depth[fs]; ACF\n"); for (z=0;zm_iDepth;z++) mfprintf(a,"%.2f; %.10G\n",(double)z*g_fTimestepLength*g_iStride,acf[z]); fclose(a); } temp.resize( 2* (obs->m_iDepth+obs->m_iZeroPadding) ); for (z=0;zm_iDepth;z++) temp[z] = acf[z]; for (z=obs->m_iDepth;z< (obs->m_iDepth+obs->m_iZeroPadding);z++) temp[z] = 0.0; { if (obs->m_iWindowFunction == 1) { for (z=0;zm_iDepth;z++) temp[z] *= pow2(cos((double)z / (obs->m_iDepth - 1) / 2.0 * Pi)); } else if (obs->m_iWindowFunction == 2) { for (z=0;zm_iDepth;z++) temp[z] *= exp(-(double)z / obs->m_iWindowFunctionParameter); } else if (obs->m_iWindowFunction == 3) { for (z=0;zm_iDepth;z++) temp[z] *= exp(-(double)z * z / obs->m_iWindowFunctionParameter / obs->m_iWindowFunctionParameter); } else if (obs->m_iWindowFunction != 0) { eprintf("CROAEngine::ComputeSpectrum(): Error: Unknown window function: %d.\n",obs->m_iWindowFunction); abort(); } } if (im) { o = obs->m_iDepth+obs->m_iZeroPadding; for (z=1;zm_iDepth+obs->m_iZeroPadding; for (z=1;zm_bSaveACF) { buf.sprintf("acf_%s%s_windowed%s",(const char*)obs->m_sTypeName,name,(const char*)obs->m_sMolName); if (obs->m_bCrossCorrelation) buf.strcat("_cc"); if (m_bSmoothData) buf.strcat("_smooth"); buf.strcat(".csv"); mprintf(" Writing windowed/mirrored ACF to \"%s\"...\n",(const char*)buf); a = OpenFileWrite((const char*)buf,true); mfprintf(a,"#Depth[fs]; ACF\n"); for (z=0;z<2* (obs->m_iDepth+obs->m_iZeroPadding);z++) mfprintf(a,"%.2f; %.10G\n",(double)z*g_fTimestepLength*g_iStride,temp[z]); fclose(a); } try { fft = new CFFT(); } catch(...) { fft = NULL; } if (fft == NULL) NewException((double)sizeof(CFFT), __FILE__, __LINE__, __PRETTY_FUNCTION__); fft->PrepareFFT_C2C(2* (obs->m_iDepth+obs->m_iZeroPadding)); for (z=0;z<2* (obs->m_iDepth+obs->m_iZeroPadding);z++) { fft->m_pInput[2*z] = temp[z]; fft->m_pInput[2*z+1] = 0.0; } fft->DoFFT(); spectrum.resize(obs->m_iSpecLength); unit = ""; switch(obs->m_iType) { case ROA_SPECTRUM_IR: for (z=0;zm_iSpecLength;z++) { if (im) val = fft->m_pOutput[2*z+1]; else val = fft->m_pOutput[2*z]; spectrum[z] = 3047.2310 * val * g_fTimestepLength * g_iStride; } if (obs->m_bCorrectTemperature) unit.sprintf("; Spectrum at %.2f K (cm*km*mol^-1); Integral (km*mol^-1)",obs->m_fCorrectTemperature); else unit.sprintf("; Spectrum (K*cm*km*mol^-1); Integral (K*km*mol^-1)"); break; case ROA_SPECTRUM_RAMAN: for (z=1;zm_iSpecLength;z++) { f = z * obs->m_fSpecResolution; if (im) val = fft->m_pOutput[2*z+1]; else val = fft->m_pOutput[2*z]; spectrum[z] = 1.0E40 * 100.0 * 2.0 * CONST_PLANCK / (8.0 * CONST_BOLTZMANN * CONST_EPSILON0 * CONST_EPSILON0) * 1.0E6 * CONST_ELEMENTARY_CHARGE * CONST_ELEMENTARY_CHARGE * 1.0E-48 / 1.0E-15 * pow4(obs->m_fLaserFreq - f) / f / (1.0 - exp(-1.438777 * f / obs->m_fTemperature)) * val * g_fTimestepLength * g_iStride; // Output in 1e-30*m^2*cm } spectrum[0] = 0.0; if (obs->m_bCorrectTemperature) unit.sprintf("; Spectrum at %.2f K (10^-40*m^2*cm); Integral (10^-40*m^2)",obs->m_fCorrectTemperature); else unit.sprintf("; Spectrum (10^-40*K*m^2*cm); Integral (10^-40*K*m^2)"); break; case ROA_SPECTRUM_ROA: for (z=1;zm_iSpecLength;z++) { f = z * obs->m_fSpecResolution; if (im) val = fft->m_pOutput[2*z+1]; else val = fft->m_pOutput[2*z]; spectrum[z] = 1.0/90.0 * 1.0E40 * 100.0 * 2.0 * CONST_PLANCK / (8.0 * CONST_BOLTZMANN * CONST_EPSILON0 * CONST_EPSILON0) * 1.0E6 * CONST_ELEMENTARY_CHARGE * CONST_ELEMENTARY_CHARGE / CONST_SPEED_OF_LIGHT * 1.0E3 * 1.0E-48 / 1.0E-15 * pow4(obs->m_fLaserFreq - f) / f / (1.0 - exp(-1.438777 * f / obs->m_fTemperature)) * val * g_fTimestepLength * g_iStride; if (ghack) spectrum[z] *= obs->m_fLaserFreq / f; } spectrum[0] = 0.0; if (obs->m_bCorrectTemperature) unit.sprintf("; Spectrum at %.2f K (10^-40*m^2*cm); Integral (10^-40*m^2)",obs->m_fCorrectTemperature); else unit.sprintf("; Spectrum (10^-40*K*m^2*cm); Integral (10^-40*K*m^2)"); break; case ROA_SPECTRUM_VCD: for (z=0;zm_iSpecLength;z++) { if (im) val = fft->m_pOutput[2*z+1]; else val = fft->m_pOutput[2*z]; spectrum[z] = 2.0 * 28.260058 * val * g_fTimestepLength * g_iStride; } if (obs->m_bCorrectTemperature) unit.sprintf("; Spectrum at %.2f K (cm*km*mol^-1); Integral (km*mol^-1)",obs->m_fCorrectTemperature); else unit.sprintf("; Spectrum (K*cm*km*mol^-1); Integral (K*km*mol^-1)"); break; case ROA_SPECTRUM_SFG: for (z=1;zm_iSpecLength;z++) { f = z * obs->m_fSpecResolution; if (im) val = fft->m_pOutput[2*z+1]; else val = fft->m_pOutput[2*z]; spectrum[z] = val / f * g_fTimestepLength * g_iStride; } spectrum[0] = 0.0; if (obs->m_bCorrectTemperature) unit.sprintf("; Spectrum at %.2f K; Integral",obs->m_fCorrectTemperature); else unit.sprintf("; Spectrum; Integral"); break; default: for (z=0;zm_iSpecLength;z++) { if (im) val = fft->m_pOutput[2*z+1]; else val = fft->m_pOutput[2*z]; spectrum[z] = val * g_fTimestepLength * g_iStride; } unit.sprintf("; Spectrum; Integral"); break; } if (obs->m_bFiniteDifferenceCorrection) { f = obs->m_fSpecResolution * g_fTimestepLength * g_iStride * 1.883652e-4; for (z=1;zm_iSpecLength;z++) spectrum[z] *= pow2(f * z / sin(f * z)); // Divide by sinc function to correct finite difference derivation } if (obs->m_bCorrectTemperature) { mprintf(" Correcting spectrum for %.2f K simulation temperature...\n",obs->m_fCorrectTemperature); for (z=0;zm_iSpecLength;z++) spectrum[z] /= obs->m_fCorrectTemperature; } buf.sprintf("spectrum_%s%s%s",(const char*)obs->m_sTypeName,name,(const char*)obs->m_sMolName); if (obs->m_bCrossCorrelation) buf.strcat("_cc"); if (m_bSmoothData) buf.strcat("_smooth"); buf.strcat(".csv"); mprintf(" Writing spectrum to \"%s\"...\n",(const char*)buf); a = OpenFileWrite((const char*)buf,true); mfprintf(a, "#Wavenumber (cm^-1)%s\n",(const char*)unit); f = 0.0; for (z=0;zm_iSpecLength;z++) { f += spectrum[z] * obs->m_fSpecResolution; mfprintf(a, "%.2f; %.8G; %.14G\n", obs->m_fSpecResolution * z, spectrum[z], f); } fclose(a); } void CROAEngine::WriteSpectrum(CROAObservation *obs, const std::vector &spectrum, const char *name) { int z; double f; FILE *a; CxString buf, unit; buf.sprintf("spectrum_%s%s%s",(const char*)obs->m_sTypeName,name,(const char*)obs->m_sMolName); if (obs->m_bCrossCorrelation) buf.strcat("_cc"); if (m_bSmoothData) buf.strcat("_smooth"); buf.strcat(".csv"); mprintf(" Writing spectrum to \"%s\"...\n",(const char*)buf); a = OpenFileWrite((const char*)buf,true); unit = ""; switch(obs->m_iType) { case ROA_SPECTRUM_IR: if (obs->m_bCorrectTemperature) unit.sprintf("; Spectrum at %.2f K (cm*km*mol^-1); Integral (km*mol^-1)",obs->m_fCorrectTemperature); else unit.sprintf("; Spectrum (K*cm*km*mol^-1); Integral (K*km*mol^-1)"); break; case ROA_SPECTRUM_RAMAN: if (obs->m_bCorrectTemperature) unit.sprintf("; Spectrum at %.2f K (10^-40*m^2*cm); Integral (10^-40*m^2)",obs->m_fCorrectTemperature); else unit.sprintf("; Spectrum (10^-40*K*m^2*cm); Integral (10^-40*K*m^2)"); break; case ROA_SPECTRUM_ROA: if (obs->m_bCorrectTemperature) unit.sprintf("; Spectrum at %.2f K (10^-40*m^2*cm); Integral (10^-40*m^2)",obs->m_fCorrectTemperature); else unit.sprintf("; Spectrum (10^-40*K*m^2*cm); Integral (10^-40*K*m^2)"); break; case ROA_SPECTRUM_VCD: if (obs->m_bCorrectTemperature) unit.sprintf("; Spectrum at %.2f K (cm*km*mol^-1); Integral (km*mol^-1)",obs->m_fCorrectTemperature); else unit.sprintf("; Spectrum (K*cm*km*mol^-1); Integral (K*km*mol^-1)"); break; case ROA_SPECTRUM_SFG: if (obs->m_bCorrectTemperature) unit.sprintf("; Spectrum at %.2f K; Integral",obs->m_fCorrectTemperature); else unit.sprintf("; Spectrum; Integral"); break; default: unit.sprintf("; Spectrum; Integral"); break; } mfprintf(a, "#Wavenumber (cm^-1)%s\n",(const char*)unit); f = 0.0; for (z=0;zm_iSpecLength;z++) { f += spectrum[z] * obs->m_fSpecResolution; mfprintf(a, "%.2f; %.8G; %.14G\n", obs->m_fSpecResolution * z, spectrum[z], f); } fclose(a); } void CROAEngine::ComputeSpectrum(CROAObservation *obs) { int z; std::vector spectrum; CxString buf; /*********************************************************************************************************************/ if (obs->m_iType == ROA_SPECTRUM_IR) { ComputeSpectrum(obs,obs->m_faACF,obs->m_faSpectrum,"",false); /*********************************************************************************************************************/ } else if (obs->m_iType == ROA_SPECTRUM_RAMAN) { if (!obs->m_bUseCommutator || g_bAdvanced2) { ComputeSpectrum(obs,obs->m_faACF,obs->m_faSpectrum,"_iso",false); ComputeSpectrum(obs,obs->m_faACF2,obs->m_faSpectrum2,"_aniso",false); spectrum.resize(obs->m_iSpecLength); for (z=0;zm_iSpecLength;z++) spectrum[z] = obs->m_faSpectrum[z] + 4.0 / 45.0 * obs->m_faSpectrum2[z]; WriteSpectrum(obs,spectrum,"_para"); for (z=0;zm_iSpecLength;z++) spectrum[z] = obs->m_faSpectrum2[z] / 15.0; WriteSpectrum(obs,spectrum,"_ortho"); for (z=0;zm_iSpecLength;z++) spectrum[z] = obs->m_faSpectrum[z] + 7.0 / 45.0 * obs->m_faSpectrum2[z]; WriteSpectrum(obs,spectrum,"_unpol"); for (z=0;zm_iSpecLength;z++) spectrum[z] = (obs->m_faSpectrum2[z] / 15.0) / (obs->m_faSpectrum[z] + 4.0 / 45.0 * obs->m_faSpectrum2[z]); WriteSpectrum(obs,spectrum,"_depol_ratio"); } if (obs->m_bUseCommutator) { ComputeSpectrum(obs,obs->m_faACF_CTP,obs->m_faSpectrum,"_iso_ct",false); ComputeSpectrum(obs,obs->m_faACF2_CTP,obs->m_faSpectrum2,"_aniso_ct",false); spectrum.resize(obs->m_iSpecLength); for (z=0;zm_iSpecLength;z++) spectrum[z] = obs->m_faSpectrum[z] + 4.0 / 45.0 * obs->m_faSpectrum2[z]; WriteSpectrum(obs,spectrum,"_para_ct"); for (z=0;zm_iSpecLength;z++) spectrum[z] = obs->m_faSpectrum2[z] / 15.0; WriteSpectrum(obs,spectrum,"_ortho_ct"); for (z=0;zm_iSpecLength;z++) spectrum[z] = obs->m_faSpectrum[z] + 7.0 / 45.0 * obs->m_faSpectrum2[z]; WriteSpectrum(obs,spectrum,"_unpol_ct"); for (z=0;zm_iSpecLength;z++) spectrum[z] = (obs->m_faSpectrum2[z] / 15.0) / (obs->m_faSpectrum[z] + 4.0 / 45.0 * obs->m_faSpectrum2[z]); WriteSpectrum(obs,spectrum,"_depol_ratio_ct"); } /*********************************************************************************************************************/ } else if (obs->m_iType == ROA_SPECTRUM_VCD) { if (!obs->m_bUseCommutator || g_bAdvanced2) ComputeSpectrum(obs,obs->m_faACF,obs->m_faSpectrum,"",true); if (obs->m_bUseCommutator) { // ComputeSpectrum(obs,obs->m_faACF_CTP,obs->m_faSpectrum,"_ct_p",false); // ComputeSpectrum(obs,obs->m_faACF_CTP,obs->m_faSpectrum,"_ct_p_im",true); // ComputeSpectrum(obs,obs->m_faACF_CTN,obs->m_faSpectrum,"_ct_n_re",false); ComputeSpectrum(obs,obs->m_faACF_CTN,obs->m_faSpectrum,"_ct",true); } /*********************************************************************************************************************/ } else if (obs->m_iType == ROA_SPECTRUM_SFG) { ComputeSpectrum(obs,obs->m_faACF,obs->m_faSpectrum,"_re",false); ComputeSpectrum(obs,obs->m_faACF,obs->m_faSpectrum,"_im",true); if (obs->m_bSingleACFs) { for (z=0;z<27;z++) { buf.sprintf("_single_%c%c_%c_re",'x'+(z/9),'x'+((z/3)%3),'x'+(z%3)); ComputeSpectrum(obs,obs->m_faaSingleACFs[z],obs->m_faSpectrum,(const char*)buf,false); buf.sprintf("_single_%c%c_%c_im",'x'+(z/9),'x'+((z/3)%3),'x'+(z%3)); ComputeSpectrum(obs,obs->m_faaSingleACFs[z],obs->m_faSpectrum,(const char*)buf,true); } } /*********************************************************************************************************************/ } else if (obs->m_iType == ROA_SPECTRUM_ROA) { if (!obs->m_bUseCommutator || g_bAdvanced2) { ComputeSpectrum(obs,obs->m_faACF,obs->m_faSpectrum,"_ag",true,true); ComputeSpectrum(obs,obs->m_faACF2,obs->m_faSpectrum2,"_gamma_g",true,true); ComputeSpectrum(obs,obs->m_faACF3,obs->m_faSpectrum3,"_gamma_a",false); spectrum.resize(obs->m_iSpecLength); for (z=0;zm_iSpecLength;z++) spectrum[z] = 180.0 * obs->m_faSpectrum[z] + 28.0 * obs->m_faSpectrum2[z] + 4.0 * obs->m_faSpectrum3[z]; WriteSpectrum(obs,spectrum,"_90deg_ortho"); for (z=0;zm_iSpecLength;z++) spectrum[z] = 24.0 * obs->m_faSpectrum2[z] - 8.0 * obs->m_faSpectrum3[z]; WriteSpectrum(obs,spectrum,"_90deg_para"); for (z=0;zm_iSpecLength;z++) spectrum[z] = 180.0 * obs->m_faSpectrum[z] + 52.0 * obs->m_faSpectrum2[z] - 4.0 * obs->m_faSpectrum3[z]; WriteSpectrum(obs,spectrum,"_90deg_unpol"); for (z=0;zm_iSpecLength;z++) spectrum[z] = 720.0 * obs->m_faSpectrum[z] + 16.0 * obs->m_faSpectrum2[z] - 16.0 * obs->m_faSpectrum3[z]; WriteSpectrum(obs,spectrum,"_forward"); for (z=0;zm_iSpecLength;z++) spectrum[z] = 96.0 * obs->m_faSpectrum2[z] + 32.0 * obs->m_faSpectrum3[z]; WriteSpectrum(obs,spectrum,"_backward"); /* for (z=0;zm_iSpecLength;z++) spectrum[z] = 180.0 * obs->m_faSpectrum[z] + 28.0 * obs->m_faSpectrum2[z]; WriteSpectrum(obs,spectrum,"_90deg_ortho_noa"); for (z=0;zm_iSpecLength;z++) spectrum[z] = 24.0 * obs->m_faSpectrum2[z]; WriteSpectrum(obs,spectrum,"_90deg_para_noa"); for (z=0;zm_iSpecLength;z++) spectrum[z] = 180.0 * obs->m_faSpectrum[z] + 52.0 * obs->m_faSpectrum2[z]; WriteSpectrum(obs,spectrum,"_90deg_unpol_noa"); for (z=0;zm_iSpecLength;z++) spectrum[z] = 720.0 * obs->m_faSpectrum[z] + 16.0 * obs->m_faSpectrum2[z]; WriteSpectrum(obs,spectrum,"_forward_noa"); for (z=0;zm_iSpecLength;z++) spectrum[z] = 96.0 * obs->m_faSpectrum2[z]; WriteSpectrum(obs,spectrum,"_backward_noa"); ComputeSpectrum(obs,obs->m_faACF,obs->m_faSpectrum,"_ag_re",false,true); ComputeSpectrum(obs,obs->m_faACF2,obs->m_faSpectrum2,"_gamma_g_re",false,true); ComputeSpectrum(obs,obs->m_faACF3,obs->m_faSpectrum3,"_gamma_a_im",true);*/ } if (obs->m_bUseCommutator) { ComputeSpectrum(obs,obs->m_faACF_CTN,obs->m_faSpectrum,"_ag_ct",true,true); ComputeSpectrum(obs,obs->m_faACF2_CTN,obs->m_faSpectrum2,"_gamma_g_ct",true,true); ComputeSpectrum(obs,obs->m_faACF3_CTP,obs->m_faSpectrum3,"_gamma_a_ct",false); spectrum.resize(obs->m_iSpecLength); for (z=0;zm_iSpecLength;z++) spectrum[z] = 180.0 * obs->m_faSpectrum[z] + 28.0 * obs->m_faSpectrum2[z] + 4.0 * obs->m_faSpectrum3[z]; WriteSpectrum(obs,spectrum,"_90deg_ortho_ct"); for (z=0;zm_iSpecLength;z++) spectrum[z] = 24.0 * obs->m_faSpectrum2[z] - 8.0 * obs->m_faSpectrum3[z]; WriteSpectrum(obs,spectrum,"_90deg_para_ct"); for (z=0;zm_iSpecLength;z++) spectrum[z] = 180.0 * obs->m_faSpectrum[z] + 52.0 * obs->m_faSpectrum2[z] - 4.0 * obs->m_faSpectrum3[z]; WriteSpectrum(obs,spectrum,"_90deg_unpol_ct"); for (z=0;zm_iSpecLength;z++) spectrum[z] = 720.0 * obs->m_faSpectrum[z] + 16.0 * obs->m_faSpectrum2[z] - 16.0 * obs->m_faSpectrum3[z]; WriteSpectrum(obs,spectrum,"_forward_ct"); for (z=0;zm_iSpecLength;z++) spectrum[z] = 96.0 * obs->m_faSpectrum2[z] + 32.0 * obs->m_faSpectrum3[z]; WriteSpectrum(obs,spectrum,"_backward_ct"); /* for (z=0;zm_iSpecLength;z++) spectrum[z] = 180.0 * obs->m_faSpectrum[z] + 28.0 * obs->m_faSpectrum2[z]; WriteSpectrum(obs,spectrum,"_90deg_ortho_noa_ct"); for (z=0;zm_iSpecLength;z++) spectrum[z] = 24.0 * obs->m_faSpectrum2[z]; WriteSpectrum(obs,spectrum,"_90deg_para_noa_ct"); for (z=0;zm_iSpecLength;z++) spectrum[z] = 180.0 * obs->m_faSpectrum[z] + 52.0 * obs->m_faSpectrum2[z]; WriteSpectrum(obs,spectrum,"_90deg_unpol_noa_ct"); for (z=0;zm_iSpecLength;z++) spectrum[z] = 720.0 * obs->m_faSpectrum[z] + 16.0 * obs->m_faSpectrum2[z]; WriteSpectrum(obs,spectrum,"_forward_noa_ct"); for (z=0;zm_iSpecLength;z++) spectrum[z] = 96.0 * obs->m_faSpectrum2[z]; WriteSpectrum(obs,spectrum,"_backward_noa_ct"); ComputeSpectrum(obs,obs->m_faACF_CTP,obs->m_faSpectrum,"_ag_ct_p",false,true); ComputeSpectrum(obs,obs->m_faACF2_CTP,obs->m_faSpectrum2,"_gamma_g_ct_p",false,true); ComputeSpectrum(obs,obs->m_faACF3_CTN,obs->m_faSpectrum3,"_gamma_a_ct_n",true);*/ } /*********************************************************************************************************************/ } else { eprintf("CROAEngine::ComputeSpectrum(): Error: Unknown spectrum type %d.\n",obs->m_iType); abort(); } } bool CROAEngine::PrepareVori(CTimeStep *ts, bool dipole, bool quadrupole, bool magmom) { try { g_pVoroWrapper = new CVoroWrapper(); } catch(...) { g_pVoroWrapper = NULL; } if (g_pVoroWrapper == NULL) NewException((double)sizeof(CVoroWrapper),__FILE__,__LINE__,__PRETTY_FUNCTION__); try { g_pTetraPak = new CTetraPak(); } catch(...) { g_pTetraPak = NULL; } if (g_pTetraPak == NULL) NewException((double)sizeof(CTetraPak),__FILE__,__LINE__,__PRETTY_FUNCTION__); g_bTegri = true; g_iTrajFormat = 5; // Cube format g_bVoroIntegrateCharge = true; g_bVoroIntegrateDipoleMoment = dipole; g_bVoroIntegrateQuadrupoleMoment = quadrupole; g_bVoroIntegrateTotalCurrent = magmom; g_bVoroIntegrateMagneticMoment = magmom; g_bCubeTimeDev = magmom; g_pTetraPak->ParseSilent(ts); for (int i = 0; i < g_oaMolecules.GetSize(); i++) { int rty; ParseAtom("#2", i, ((CMolecule *)g_oaMolecules[i])->m_iDipoleCenterType, rty, ((CMolecule *)g_oaMolecules[i])->m_iDipoleCenterIndex); ((CMolecule *)g_oaMolecules[i])->m_iDipoleMode = 7; } return true; } bool CROAEngine::PrepareCurrentDensity(CTimeStep *ts, CTimeStep *tsref, bool first) { if (first) { m_pDensity.m_iRes[0] = tsref->m_pVolumetricData->m_iRes[0]; m_pDensity.m_iRes[1] = tsref->m_pVolumetricData->m_iRes[1]; m_pDensity.m_iRes[2] = tsref->m_pVolumetricData->m_iRes[2]; m_pDensity.m_fMinVal[0] = tsref->m_pVolumetricData->m_fMinVal[0]; m_pDensity.m_fMaxVal[0] = tsref->m_pVolumetricData->m_fMaxVal[0]; m_pDensity.m_fMinVal[1] = tsref->m_pVolumetricData->m_fMinVal[1]; m_pDensity.m_fMaxVal[1] = tsref->m_pVolumetricData->m_fMaxVal[1]; m_pDensity.m_fMinVal[2] = tsref->m_pVolumetricData->m_fMinVal[2]; m_pDensity.m_fMaxVal[2] = tsref->m_pVolumetricData->m_fMaxVal[2]; m_pDensity.Create(); m_pDensityGrad[0].m_iRes[0] = tsref->m_pVolumetricData->m_iRes[0]; m_pDensityGrad[0].m_iRes[1] = tsref->m_pVolumetricData->m_iRes[1]; m_pDensityGrad[0].m_iRes[2] = tsref->m_pVolumetricData->m_iRes[2]; m_pDensityGrad[0].m_fMinVal[0] = tsref->m_pVolumetricData->m_fMinVal[0]; m_pDensityGrad[0].m_fMaxVal[0] = tsref->m_pVolumetricData->m_fMaxVal[0]; m_pDensityGrad[0].m_fMinVal[1] = tsref->m_pVolumetricData->m_fMinVal[1]; m_pDensityGrad[0].m_fMaxVal[1] = tsref->m_pVolumetricData->m_fMaxVal[1]; m_pDensityGrad[0].m_fMinVal[2] = tsref->m_pVolumetricData->m_fMinVal[2]; m_pDensityGrad[0].m_fMaxVal[2] = tsref->m_pVolumetricData->m_fMaxVal[2]; m_pDensityGrad[0].Create(); m_pDensityGrad[1].m_iRes[0] = tsref->m_pVolumetricData->m_iRes[0]; m_pDensityGrad[1].m_iRes[1] = tsref->m_pVolumetricData->m_iRes[1]; m_pDensityGrad[1].m_iRes[2] = tsref->m_pVolumetricData->m_iRes[2]; m_pDensityGrad[1].m_fMinVal[0] = tsref->m_pVolumetricData->m_fMinVal[0]; m_pDensityGrad[1].m_fMaxVal[0] = tsref->m_pVolumetricData->m_fMaxVal[0]; m_pDensityGrad[1].m_fMinVal[1] = tsref->m_pVolumetricData->m_fMinVal[1]; m_pDensityGrad[1].m_fMaxVal[1] = tsref->m_pVolumetricData->m_fMaxVal[1]; m_pDensityGrad[1].m_fMinVal[2] = tsref->m_pVolumetricData->m_fMinVal[2]; m_pDensityGrad[1].m_fMaxVal[2] = tsref->m_pVolumetricData->m_fMaxVal[2]; m_pDensityGrad[1].Create(); m_pDensityGrad[2].m_iRes[0] = tsref->m_pVolumetricData->m_iRes[0]; m_pDensityGrad[2].m_iRes[1] = tsref->m_pVolumetricData->m_iRes[1]; m_pDensityGrad[2].m_iRes[2] = tsref->m_pVolumetricData->m_iRes[2]; m_pDensityGrad[2].m_fMinVal[0] = tsref->m_pVolumetricData->m_fMinVal[0]; m_pDensityGrad[2].m_fMaxVal[0] = tsref->m_pVolumetricData->m_fMaxVal[0]; m_pDensityGrad[2].m_fMinVal[1] = tsref->m_pVolumetricData->m_fMinVal[1]; m_pDensityGrad[2].m_fMaxVal[1] = tsref->m_pVolumetricData->m_fMaxVal[1]; m_pDensityGrad[2].m_fMinVal[2] = tsref->m_pVolumetricData->m_fMinVal[2]; m_pDensityGrad[2].m_fMaxVal[2] = tsref->m_pVolumetricData->m_fMaxVal[2]; m_pDensityGrad[2].Create(); } ts->m_pVolumetricDataTimeDev = new C3DF; ts->m_pVolumetricDataTimeDev->m_iRes[0] = tsref->m_pVolumetricData->m_iRes[0]; ts->m_pVolumetricDataTimeDev->m_iRes[1] = tsref->m_pVolumetricData->m_iRes[1]; ts->m_pVolumetricDataTimeDev->m_iRes[2] = tsref->m_pVolumetricData->m_iRes[2]; ts->m_pVolumetricDataTimeDev->m_fMinVal[0] = tsref->m_pVolumetricData->m_fMinVal[0]; ts->m_pVolumetricDataTimeDev->m_fMaxVal[0] = tsref->m_pVolumetricData->m_fMaxVal[0]; ts->m_pVolumetricDataTimeDev->m_fMinVal[1] = tsref->m_pVolumetricData->m_fMinVal[1]; ts->m_pVolumetricDataTimeDev->m_fMaxVal[1] = tsref->m_pVolumetricData->m_fMaxVal[1]; ts->m_pVolumetricDataTimeDev->m_fMinVal[2] = tsref->m_pVolumetricData->m_fMinVal[2]; ts->m_pVolumetricDataTimeDev->m_fMaxVal[2] = tsref->m_pVolumetricData->m_fMaxVal[2]; ts->m_pVolumetricDataTimeDev->Create(); ts->m_pCurrentDensity = new CxDoubleArray(); return true; } bool CROAEngine::CalculateCurrentDensity(CTimeStep *ts1, CTimeStep *ts2, CTimeStep *ts3, bool reset) { int i, j, k; double integral = 0.0; int timedevSize = 0; int res[3]; bool c=true; for (i = 0; i < ts2->m_pVolumetricData->m_iRes[0] * ts2->m_pVolumetricData->m_iRes[1] * ts2->m_pVolumetricData->m_iRes[2]; i++) { if (fabs(ts2->m_pVolumetricData->m_pBin[i]) > -1.0e-20) { ts2->m_pVolumetricDataTimeDev->m_pBin[i] = (ts3->m_pVolumetricData->m_pBin[i] - ts1->m_pVolumetricData->m_pBin[i]) / (2.0 * g_fTimestepLength); integral += ts2->m_pVolumetricDataTimeDev->m_pBin[i]; timedevSize++; } else ts2->m_pVolumetricDataTimeDev->m_pBin[i] = 0.0; } for (i = 0; i < ts2->m_pVolumetricDataTimeDev->m_iRes[0] * ts2->m_pVolumetricDataTimeDev->m_iRes[1] * ts2->m_pVolumetricDataTimeDev->m_iRes[2]; i++) if (fabs(ts2->m_pVolumetricData->m_pBin[i]) > -1.0e-20) ts2->m_pVolumetricDataTimeDev->m_pBin[i] -= integral / timedevSize; res[0] = ts2->m_pVolumetricDataTimeDev->m_iRes[0]; res[1] = ts2->m_pVolumetricDataTimeDev->m_iRes[1]; res[2] = ts2->m_pVolumetricDataTimeDev->m_iRes[2]; m_pDensity.CopyFrom(ts2->m_pVolumetricData); for (i = 0; i < res[2]; i++) { for (j = 0; j < res[1]; j++) { for (k = 1; k < res[0] - 1; k++) m_pDensityGrad[0].m_pBin[i * res[0] * res[1] + j * res[0] + k] = (m_pDensity.m_pBin[i * res[0] * res[1] + j * res[0] + k + 1] - m_pDensity.m_pBin[i * res[0] * res[1] + j * res[0] + k - 1]) / (2.0 * g_fCubeXStep); m_pDensityGrad[0].m_pBin[i * res[0] * res[1] + j * res[0]] = (m_pDensity.m_pBin[i * res[0] * res[1] + j * res[0] + 1] - m_pDensity.m_pBin[i * res[0] * res[1] + j * res[0] + res[0] - 1]) / (2.0 * g_fCubeXStep); m_pDensityGrad[0].m_pBin[i * res[0] * res[1] + j * res[0] + res[0] - 1] = (m_pDensity.m_pBin[i * res[0] * res[1] + j * res[0]] - m_pDensity.m_pBin[i * res[0] * res[1] + j * res[0] + res[0] - 2]) / (2.0 * g_fCubeXStep); } } for (i = 0; i < res[2]; i++) { for (j = 1; j < res[1] - 1; j++) for (k = 0; k < res[0]; k++) m_pDensityGrad[1].m_pBin[i * res[0] * res[1] + j * res[0] + k] = (m_pDensity.m_pBin[i * res[0] * res[1] + (j + 1) * res[0] + k] - m_pDensity.m_pBin[i * res[0] * res[1] + (j - 1) * res[0] + k]) / (2.0 * g_fCubeYStep); for (k = 0; k < res[0]; k++) { m_pDensityGrad[1].m_pBin[i * res[0] * res[1] + k] = (m_pDensity.m_pBin[i * res[0] * res[1] + res[0] + k] - m_pDensity.m_pBin[i * res[0] * res[1] + (res[1] - 1) * res[0] + k]) / (2.0 * g_fCubeYStep); m_pDensityGrad[1].m_pBin[i * res[0] * res[1] + (res[1] - 1) * res[0] + k] = (m_pDensity.m_pBin[i * res[0] * res[1] + k] - m_pDensity.m_pBin[i * res[0] * res[1] + (res[1] - 2) * res[0] + k]) / (2.0 * g_fCubeYStep); } } for (i = 1; i < res[2] - 1; i++) for (j = 0; j < res[1]; j++) for (k = 0; k < res[0]; k++) m_pDensityGrad[2].m_pBin[i * res[0] * res[1] + j * res[0] + k] = (m_pDensity.m_pBin[(i + 1) * res[0] * res[1] + j * res[0] + k] - m_pDensity.m_pBin[(i - 1) * res[0] * res[1] + j * res[0] + k]) / (2.0 * g_fCubeZStep); for (j = 0; j < res[1]; j++) { for (k = 0; k < res[0]; k++) { m_pDensityGrad[2].m_pBin[j * res[0] + k] = (m_pDensity.m_pBin[res[0] * res[1] + j * res[0] + k] - m_pDensity.m_pBin[(res[2] - 1) * res[0] * res[1] + j * res[0] + k]) / (2.0 * g_fCubeZStep); m_pDensityGrad[2].m_pBin[(res[2] - 1) * res[0] * res[1] + j * res[0] + k] = (m_pDensity.m_pBin[j * res[0] + k] - m_pDensity.m_pBin[(res[2] - 2) * res[0] * res[1] + j * res[0] + k]) / (2.0 * g_fCubeZStep); } } for (i = 0; i < res[0] * res[1] * res[2]; i++) m_pDensity.m_pBin[i] += g_fBackgroundDensity; CSparseMatrix pdeMatrix; CCurrentPDEDiscretizer::discretize(&pdeMatrix, m_pDensity, m_pDensityGrad[0], m_pDensityGrad[1], m_pDensityGrad[2]); static double thresh; if (m_pPDESolution == NULL) { try { m_pPDESolution = new double[res[0] * res[1] * res[2]]; } catch(...) { m_pPDESolution = NULL; } if (m_pPDESolution == NULL) NewException((double)res[0] * res[1] * res[2] * sizeof(double), __FILE__, __LINE__, __PRETTY_FUNCTION__); memset(m_pPDESolution, 0, res[0] * res[1] * res[2] * sizeof(double)); thresh = g_fPDEConvThresh * CCurrentPDESolver::calcResidual(&pdeMatrix, m_pPDESolution, ts2->m_pVolumetricDataTimeDev->m_pBin); } else if (reset) { memset(m_pPDESolution, 0, res[0] * res[1] * res[2] * sizeof(double)); thresh = g_fPDEConvThresh * CCurrentPDESolver::calcResidual(&pdeMatrix, m_pPDESolution, ts2->m_pVolumetricDataTimeDev->m_pBin); } //memset(pdeSolution, 0, res[0] * res[1] * res[2] * sizeof(double)); //mprintf("solution: %g\ntimedev: %g\ndensity: %g\ngradx: %g\ngrady: %g\ngradz: %g\n",pdeSolution[0],ts2->m_pVolumetricDataTimeDev->m_pBin[0],m_pDensity.m_pBin[0],m_pDensityGrad[0].m_pBin[0],m_pDensityGrad[1].m_pBin[0],m_pDensityGrad[2].m_pBin[0]); double thresh2 = thresh; mprintf("["); if (!m_bPDERestart) goto _norestart; mprintf("R"); if (m_fPDEInfo != NULL) fprintf(m_fPDEInfo,"Starting PDE solver...\n"); if (!CCurrentPDESolver::bicgstabl(4, &pdeMatrix, m_pPDESolution, ts2->m_pVolumetricDataTimeDev->m_pBin, g_iPDEMaxIter, &thresh2, m_fPDEInfo, m_bPDEFastMode )) { mprintf("|"); _norestart: c = true; memset(m_pPDESolution, 0, res[0] * res[1] * res[2] * sizeof(double)); mprintf("Z"); if (m_fPDEInfo != NULL) fprintf(m_fPDEInfo,"Starting PDE solver with zero initial guess...\n"); thresh2 = thresh; if (!CCurrentPDESolver::bicgstabl(4, &pdeMatrix, m_pPDESolution, ts2->m_pVolumetricDataTimeDev->m_pBin, g_iPDEMaxIter, &thresh2, m_fPDEInfo, m_bPDEFastMode )) { c = false; if (!m_bPDEFastMode) { memset(m_pPDESolution, 0, res[0] * res[1] * res[2] * sizeof(double)); // if (verbose) // mprintf("@PDE Trying different threshold\n"); mprintf("|T"); thresh2 *= 1.05; // mprintf("\nSetting threshold to %f.\n",thresh2); if (m_fPDEInfo != NULL) fprintf(m_fPDEInfo,"Starting PDE solver with reduced threshold (%f)...\n",thresh2); CCurrentPDESolver::bicgstabl(4, &pdeMatrix, m_pPDESolution, ts2->m_pVolumetricDataTimeDev->m_pBin, g_iPDEMaxIter, &thresh2, m_fPDEInfo, m_bPDEFastMode ); } } } mprintf("]"); if (c) mprintf(" Converged."); else mprintf(" Not converged (%.2f).",thresh2/thresh); ts2->m_pCurrentDensity->SetSize(3 * res[0] * res[1] * res[2]); for (i = 0; i < res[2]; i++) { for (j = 0; j < res[1]; j++) { for (k = 1; k < res[0] - 1; k++) ts2->m_pCurrentDensity->GetAt(i * res[1] * res[0] * 3 + j * res[0] * 3 + k * 3) = (m_pPDESolution[i * res[1] * res[0] + j * res[0] + k + 1] - m_pPDESolution[i * res[1] * res[0] + j * res[0] + k - 1]) / (2.0 * g_fCubeXStep) * ts2->m_pVolumetricData->m_pBin[i * res[1] * res[0] + j * res[0] + k]; ts2->m_pCurrentDensity->GetAt(i * res[1] * res[0] * 3 + j * res[0] * 3) = (m_pPDESolution[i * res[1] * res[0] + j * res[0] + 1] - m_pPDESolution[i * res[1] * res[0] + j * res[0] + res[0] - 1]) / (2.0 * g_fCubeXStep) * ts2->m_pVolumetricData->m_pBin[i * res[1] * res[0] + j * res[0]]; ts2->m_pCurrentDensity->GetAt(i * res[1] * res[0] * 3 + j * res[0] * 3 + (res[0] - 1) * 3) = (m_pPDESolution[i * res[1] * res[0] + j * res[0]] - m_pPDESolution[i * res[1] * res[0] + j * res[0] + res[0] - 2]) / (2.0 * g_fCubeXStep) * ts2->m_pVolumetricData->m_pBin[i * res[1] * res[0] + j * res[0] + res[0] - 1]; } } for (i = 0; i < res[2]; i++) { for (j = 1; j < res[1] - 1; j++) for (k = 0; k < res[0]; k++) ts2->m_pCurrentDensity->GetAt(i * res[1] * res[0] * 3 + j * res[0] * 3 + k * 3 + 1) = (m_pPDESolution[i * res[1] * res[0] + (j + 1) * res[0] + k] - m_pPDESolution[i * res[1] * res[0] + (j - 1) * res[0] + k]) / (2.0 * g_fCubeYStep) * ts2->m_pVolumetricData->m_pBin[i * res[1] * res[0] + j * res[0] + k]; for (k = 0; k < res[0]; k++) { ts2->m_pCurrentDensity->GetAt(i * res[1] * res[0] * 3 + k * 3 + 1) = (m_pPDESolution[i * res[1] * res[0] + res[0] + k] - m_pPDESolution[i * res[1] * res[0] + (res[1] - 1) * res[0] + k]) / (2.0 * g_fCubeYStep) * ts2->m_pVolumetricData->m_pBin[i * res[1] * res[0] + k]; ts2->m_pCurrentDensity->GetAt(i * res[1] * res[0] * 3 + (res[1] - 1) * res[0] * 3 + k * 3 + 1) = (m_pPDESolution[i * res[1] * res[0] + k] - m_pPDESolution[i * res[1] * res[0] + (res[1] - 2) * res[0] + k]) / (2.0 * g_fCubeYStep) * ts2->m_pVolumetricData->m_pBin[i * res[1] * res[0] + (res[1] - 1) * res[0] + k]; } } for (i = 1; i < res[2] - 1; i++) for (j = 0; j < res[1]; j++) for (k = 0; k < res[0]; k++) ts2->m_pCurrentDensity->GetAt(i * res[1] * res[0] * 3 + j * res[0] * 3 + k * 3 + 2) = (m_pPDESolution[(i + 1) * res[1] * res[0] + j * res[0] + k] - m_pPDESolution[(i - 1) * res[1] * res[0] + j * res[0] + k]) / (2.0 * g_fCubeZStep) * ts2->m_pVolumetricData->m_pBin[i * res[1] * res[0] + j * res[0] + k]; for (j = 0; j < res[1]; j++) { for (k = 0; k < res[0]; k++) { ts2->m_pCurrentDensity->GetAt(j * res[0] * 3 + k * 3 + 2) = (m_pPDESolution[res[1] * res[0] + j * res[0] + k] - m_pPDESolution[(res[2] - 1) * res[1] * res[0] + j * res[0] + k]) / (2.0 * g_fCubeZStep) * ts2->m_pVolumetricData->m_pBin[j * res[0] + k]; ts2->m_pCurrentDensity->GetAt((res[2] - 1) * res[1] * res[0] * 3 + j * res[0] * 3 + k * 3 + 2) = (m_pPDESolution[j * res[0] + k] - m_pPDESolution[(res[2] - 2) * res[1] * res[0] + j * res[0] + k]) / (2.0 * g_fCubeZStep) * ts2->m_pVolumetricData->m_pBin[(res[2] - 1) * res[1] * res[0] + j * res[0] + k]; } } return true; } void CFitParabola::Init4(double x1, double y1, double x2, double y2, double x3, double y3, double x4, double y4) { CxDMatrix3 a, t; double sx1, sx2, sx3, sx4, sy1, sy2, sy3, d; sx1 = x1 + x2 + x3 + x4; sx2 = x1*x1 + x2*x2 + x3*x3 + x4*x4; sx3 = x1*x1*x1 + x2*x2*x2 + x3*x3*x3 + x4*x4*x4; sx4 = x1*x1*x1*x1 + x2*x2*x2*x2 + x3*x3*x3*x3 + x4*x4*x4*x4; sy1 = y1 + y2 + y3 + y4; sy2 = x1*y1 + x2*y2 + x3*y3 + x4*y4; sy3 = x1*x1*y1 + x2*x2*y2 + x3*x3*y3 + x4*x4*y4; a(0,0) = 4.0; a(0,1) = sx1; a(0,2) = sx2; a(1,0) = sx1; a(1,1) = sx2; a(1,2) = sx3; a(2,0) = sx2; a(2,1) = sx3; a(2,2) = sx4; d = a.Det(); if (d == 0) { eprintf("CParabola::Init4(): Error: Det == 0.\n"); m_fA = 0; m_fB = 0; m_fC = 0; return; } t = a; t(0,0) = sy1; t(1,0) = sy2; t(2,0) = sy3; m_fA = t.Det() / d; t = a; t(0,1) = sy1; t(1,1) = sy2; t(2,1) = sy3; m_fB = t.Det() / d; t = a; t(0,2) = sy1; t(1,2) = sy2; t(2,2) = sy3; m_fC = t.Det() / d; //mprintf("%.10G + %.10G * x + %.10G * x^2\n",m_fA,m_fB,m_fC); } double CFitParabola::Evaluate(double x) { return m_fA + x * m_fB + x * x * m_fC; } travis-src-190101/src/roa.h0100777000000000000000000002163413412725666012405 0ustar00/***************************************************************************** TRAVIS - Trajectory Analyzer and Visualizer http://www.travis-analyzer.de/ Copyright (c) 2009-2019 Martin Brehm 2012-2019 Martin Thomas 2016-2019 Sascha Gehrke This file was written by Martin Brehm. --------------------------------------------------------------------------- This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . *****************************************************************************/ #ifndef ROA_H #define ROA_H // This must always be the first include directive #include "config.h" #include #include "tools.h" #include "timestep.h" #include "tensor.h" #include "bqb.h" class CCrossCorrelation; #define ROA_FIELD_NONE 0 #define ROA_FIELD_EXP 1 #define ROA_FIELD_EXN 2 #define ROA_FIELD_EYP 3 #define ROA_FIELD_EYN 4 #define ROA_FIELD_EZP 5 #define ROA_FIELD_EZN 6 #define ROA_MODE_COMBINED 0 #define ROA_MODE_GATHER 1 #define ROA_MODE_ANALYZE 2 #define ROA_SPECTRUM_IR 1 #define ROA_SPECTRUM_RAMAN 2 #define ROA_SPECTRUM_VCD 3 #define ROA_SPECTRUM_SFG 4 #define ROA_SPECTRUM_ROA 5 class CSmoothener { public: CSmoothener() : m_pForward(NULL), m_pInverse(NULL), m_iLength(-1), m_iInternalLength(-1), m_fWaveNumber(0) { } ~CSmoothener() { if (m_pForward != NULL) { delete m_pForward; m_pForward = NULL; } if (m_pInverse != NULL) { delete m_pInverse; m_pInverse = NULL; } } void Init(int length, double wavenumber); void Smoothen(const std::vector &inp, std::vector &outp); void Smoothen(const std::vector &inp, std::vector &outp); void Smoothen(const std::vector &inp, std::vector &outp); void Smoothen(std::vector &data) { Smoothen(data,data); } void Smoothen(std::vector &data) { Smoothen(data,data); } void Smoothen(std::vector &data) { Smoothen(data,data); } CFFT *m_pForward; CFFT *m_pInverse; int m_iLength; int m_iInternalLength; double m_fWaveNumber; }; class CROAObservation { public: CROAObservation(); CROAObservation(const CROAObservation &t); ~CROAObservation(); CxString m_sName; CxString m_sMolName; CxString m_sTypeName; std::vector > m_iaMolSelection; std::vector m_faACF; std::vector m_faACF2; std::vector m_faACF3; std::vector m_faACF4; std::vector m_faSpectrum; std::vector m_faSpectrum2; std::vector m_faSpectrum3; std::vector m_faACF_CTP; std::vector m_faACF2_CTP; std::vector m_faACF3_CTP; std::vector m_faACF4_CTP; std::vector m_faACF_CTN; std::vector m_faACF2_CTN; std::vector m_faACF3_CTN; std::vector m_faACF4_CTN; bool m_bSingleACFs; std::vector > m_faaSingleACFs; std::vector m_faWFN; int m_iType; int m_iDepth; int m_iWindowFunction; int m_iWindowFunctionParameter; int m_iZeroPadding; double m_fSpecResolution; int m_iSpecLength; bool m_bFiniteDifferenceCorrection; bool m_bSaveACF; int m_iQuantumCorrection; double m_fQuantumCorrectionTemperature; bool m_bCorrectFrequency; bool m_bCrossCorrelation; double m_fLaserFreq; double m_fTemperature; bool m_bCorrectTemperature; double m_fCorrectTemperature; bool m_bUseCommutator; }; class CROAMolecule { public: CROAMolecule() { } ~CROAMolecule() { } std::vector m_faCharge; // Unit: e std::vector m_vaElDip; // Unit: Debye std::vector m_maElQuad; // Unit: Debye*pm std::vector m_vaElCurr; // Unit: MB/pm std::vector m_vaMagDip; // Unit: MB std::vector m_maPolElDip; // Unit: e*pm^2/V std::vector m_taPolElQuad; // Unit: e*pm^3/V std::vector m_maPolMagDip; // Unit: e*pm^3/(fs*V) std::vector m_faDCharge; // Unit: e/fs std::vector m_vaDElDip; // Unit: Debye/fs std::vector m_maDElQuad; // Unit: Debye*pm/fs std::vector m_vaDElCurr; // Unit: MB/(pm*fs) std::vector m_vaDMagDip; // Unit: MB/fs std::vector m_maDPolElDip; // Unit: e*pm^2/(V*fs) std::vector m_taDPolElQuad; // Unit: e*pm^3/(V*fs) std::vector m_maDPolMagDip; // Unit: e*pm^3/(V*fs^2) }; class CROATrajectory { public: CROATrajectory(); ~CROATrajectory(); bool OpenFile(); CTimeStep* GetTimeStep(int i); bool ReadTimeStep(); bool SkipTimeStep(); void CalcVelocities(); void Rewind(); void SetHistory(int i); std::string m_sFileName; std::vector m_oaTSHistory; int m_iTSPos; std::vector m_oaMolecules; std::vector m_vaAtomVelocities; std::vector m_vaCOMCoord; FILE *m_pFile; bool m_bBQB; CBQBFile *m_pBQB; int m_iHistory; }; class CROAAtom { public: std::vector m_vaPos; std::vector m_vaVel; std::vector m_faCharge; // Unit: e std::vector m_vaElDip; // Unit: Debye std::vector m_maElQuad; // Unit: Debye*pm std::vector m_vaElCurr; // Unit: MB/pm std::vector m_vaMagDip; // Unit: MB std::vector m_maPolElDip; // Unit: e*pm^2/V std::vector m_taPolElQuad; // Unit: e*pm^3/V std::vector m_maPolMagDip; // Unit: e*pm^3/(fs*V) std::vector m_faDCharge; // Unit: e/fs std::vector m_vaDElDip; // Unit: Debye/fs std::vector m_maDElQuad; // Unit: Debye*pm/fs std::vector m_vaDElCurr; // Unit: MB/(pm*fs) std::vector m_vaDMagDip; // Unit: MB/fs std::vector m_maDPolElDip; // Unit: e*pm^2/(V*fs) std::vector m_taDPolElQuad; // Unit: e*pm^3/(V*fs) std::vector m_maDPolMagDip; // Unit: e*pm^3/(V*fs^2) }; class CROAEngine { public: CROAEngine(); ~CROAEngine(); bool Parse(); void MainLoop(); void MainLoop_Combined(); void MainLoop_Gather(); void MainLoop_Analyze(); bool ReadStep(bool verbose); bool SkipStep(); void Finish(); void CalcVelocities(); void ParseObservations(); bool CheckTrajColumns(CROATrajectory *tr); void ComputeACF(CROAObservation *obs); void ComputeACFPair(CROAObservation *obs, CROAMolecule *mol1, CROAMolecule *mol2, std::vector *wfn=NULL); void ComputeSpectrum(CROAObservation *obs); void ComputeSpectrum(CROAObservation *obs, const std::vector &acf, std::vector &spectrum, const char *name, bool im, bool ghack=false); void WriteSpectrum(CROAObservation *obs, const std::vector &spectrum, const char *name); CTimeStep* GetROAStep(int traj, int step); bool PrepareVori(CTimeStep *ts, bool dipole, bool quadrupole, bool magmom); bool PrepareCurrentDensity(CTimeStep *ts, CTimeStep *tsref, bool first); bool CalculateCurrentDensity(CTimeStep *ts1, CTimeStep *ts2, CTimeStep *ts3, bool reset); bool m_bAniso; bool m_bCentral; double m_fFieldStrength; // In atomic units: Eh / (e * a0) = 5.14220652E11 V/m bool m_bSmoothData; bool m_bReplaceOutliers; std::vector m_iaOutliers[8]; double m_fSmoothWaveNumber; bool m_bDumpMolecularProps; bool m_bDumpMol1Props; bool m_bWriteACFs; bool m_bGatherWriteCSV; bool m_bGatherCheck; bool m_bReverseTraj; int m_iMode; bool m_bIR; bool m_bRaman; bool m_bVCD; bool m_bROA; bool m_bSFG; bool m_bMagMom; bool m_bPola; int m_iStepsProcessed; std::vector m_oaTrajectories; std::vector m_oaObservations; std::vector m_oaAtoms; std::vector m_iaTrajKinds; std::vector m_iaInvTrajKinds; C3DF m_pDensity; C3DF m_pDensityGrad[3]; double *m_pPDESolution; FILE *m_fPDEInfo; bool m_bPDEFastMode; std::vector m_fMolIntegralFiles; CCrossCorrelation *m_pCrossCorr; CxDoubleArray m_faInput1; CxDoubleArray m_faInput2; CxDoubleArray m_faOutput; bool m_bPDERestart; }; class CFitParabola { public: // Finds a best-fit parabola through four given points void Init4(double x1, double y1, double x2, double y2, double x3, double y3, double x4, double y4); double Evaluate(double x); private: double m_fA; double m_fB; double m_fC; }; #endif travis-src-190101/src/sdfmap.cpp0100777000000000000000000004223213412725620013414 0ustar00/***************************************************************************** TRAVIS - Trajectory Analyzer and Visualizer http://www.travis-analyzer.de/ Copyright (c) 2009-2019 Martin Brehm 2012-2019 Martin Thomas 2016-2019 Sascha Gehrke This file was written by Martin Brehm. --------------------------------------------------------------------------- This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . *****************************************************************************/ // This must always be the first include directive #include "config.h" #include "sdfmap.h" #include "globalvar.h" const char *GetRevisionInfo_sdfmap(unsigned int len) { static char buf[256]; GET_REVISION_INFO( buf, len ); return buf; } const char *GetSourceVersion_sdfmap() { static char buf[256]; GET_SOURCE_VERSION( buf ); return buf; } CSDFMap::CSDFMap() { m_pValueMin = NULL; m_pValueMax = NULL; m_pValueAvg = NULL; m_pCount = NULL; m_sName = NULL; m_sSubName = NULL; } CSDFMap::~CSDFMap() { if (m_pValueMin != NULL) { delete m_pValueMin; m_pValueMin = NULL; } if (m_pValueMax != NULL) { delete m_pValueMax; m_pValueMax = NULL; } if (m_pValueAvg != NULL) { delete m_pValueAvg; m_pValueAvg = NULL; } if (m_pCount != NULL) { delete m_pCount; m_pCount = NULL; } if (m_sName != NULL) { delete[] m_sName; m_sName = NULL; } if (m_sSubName != NULL) { delete[] m_sSubName; m_sSubName = NULL; } } void CSDFMap::Parse() { int ti, z; // char buf[256], buf2[256]; CxString buf, buf2; CAtomGroup *ag; mprintf(WHITE,"\n>>> SDF Surface Map >>>\n\n"); mprintf(" List of scalar quantities which can be mapped to SDF surface:\n"); mprintf(" 1.) Absolute velocity\n"); mprintf(" 2.) Absolute force\n"); mprintf("\n"); _quantityagain: m_iQuantity = AskRangeInteger_ND(" Select quantity to map onto SDF surface (1-2): ",1,2); switch(m_iQuantity) { /********************************************************************************************************/ case 1: g_bUseVelocities = true; if (g_fTimestepLength == 0) { mprintf("\n"); g_fTimestepLength = AskFloat(" Enter the length of one trajectory time step in fs: [0.5] ",0.5); } _vnextmol: mprintf("\n"); // sprintf(buf," Evaluate velocity of atoms from which molecule type ("); buf.sprintf(" Evaluate velocity of atoms from which molecule type ("); for (z=0;zm_sName,z+1); // strcat(buf,buf2); // if (z < g_oaMolecules.GetSize()-1) // strcat(buf,", "); buf2.sprintf("%s=%d",((CMolecule*)g_oaMolecules[z])->m_sName,z+1); buf.strcat(buf2); if (z < g_oaMolecules.GetSize()-1) buf.strcat(", "); } // strcat(buf,")? "); buf.strcat(")? "); ti = AskRangeInteger_ND("%s",1,g_oaMolecules.GetSize(),(const char*)buf) - 1; for (z=0;zm_pMolecule->m_iIndex == ti) { eprintf("This molecule type is already in use.\n"); goto _vnextmol; } } try { ag = new CAtomGroup(); } catch(...) { ag = NULL; } if (ag == NULL) NewException((double)sizeof(CAtomGroup),__FILE__,__LINE__,__PRETTY_FUNCTION__); _vagain: AskString(" Which atoms to take into account from %s (*=all)? [*] ",&buf,"*",((CMolecule*)g_oaMolecules[ti])->m_sName); if (!ag->ParseAtoms((CMolecule*)g_oaMolecules[ti],buf)) goto _vagain; m_oaAtomGroups.Add(ag); mprintf("\n"); if (AskYesNo(" Evaluate velocity of atoms from another molecule type (y/n)? [no] ",false)) goto _vnextmol; // sprintf(buf,"velocity"); buf.sprintf("velocity"); for (z=0;zm_pMolecule->m_sName,((CAtomGroup*)m_oaAtomGroups[z])->m_sName); // strcat(buf,buf2); buf2.sprintf("_%s_%s",((CAtomGroup*)m_oaAtomGroups[z])->m_pMolecule->m_sName,((CAtomGroup*)m_oaAtomGroups[z])->m_sName); buf.strcat(buf2); } try { m_sSubName = new char[strlen(buf)+1]; } catch(...) { m_sSubName = NULL; } if (m_sSubName == NULL) NewException((double)(strlen(buf)+1)*sizeof(char),__FILE__,__LINE__,__PRETTY_FUNCTION__); strcpy(m_sSubName,buf); break; /********************************************************************************************************/ default: eprintf("Not yet implemented.\n"); goto _quantityagain; } mprintf("\n"); m_bModeAvg = AskYesNo(" Create surface map of average values (y/n)? [yes] ",true); m_bModeMin = AskYesNo(" Create surface map of minimal values (y/n)? [no] ",false); m_bModeMax = AskYesNo(" Create surface map of maximal values (y/n)? [no] ",false); mprintf("\n"); m_bSphere = AskYesNo(" Add each value to a sphere of more than one grid points (y/n)? [no] ",false); if (m_bSphere) m_iSphereRadius = AskUnsignedInteger(" Enter the radius of this sphere in grid points: [3] ",3); mprintf("\n"); m_fRadius = AskFloat(" Please enter radius of this SDF surface map in pm: [%d.0] ",(double)HalfBox(),HalfBox()); _sdfresagain: ti = g_pDatabase->GetInt("/PLOT3D/DEFAULTS/BIN_RES"); m_iResolution = AskUnsignedInteger(" Please enter binning resolution of this SDF surface map per dimension: [%d] ",ti,ti); if (m_iResolution > 300) { eprintf("\nWarning: "); mprintf("This large resolution will consume much RAM (%s)\n",FormatBytes(pow3((double)m_iResolution)*sizeof(double))); mprintf(" and result in very large SDF map output files.\n\n"); if (!AskYesNo(" Use this resolution (y/n)? [no] ",false)) goto _sdfresagain; } BuildName(); mprintf(WHITE,"\n<<< End of SDF Surface Map <<<\n\n"); } void CSDFMap::Create() { m_pCount = new C3DF(); m_pCount->m_fMinVal[0] = -m_fRadius; m_pCount->m_fMaxVal[0] = m_fRadius; m_pCount->m_fMinVal[1] = -m_fRadius; m_pCount->m_fMaxVal[1] = m_fRadius; m_pCount->m_fMinVal[2] = -m_fRadius; m_pCount->m_fMaxVal[2] = m_fRadius; m_pCount->m_iRes[0] = m_iResolution; m_pCount->m_iRes[1] = m_iResolution; m_pCount->m_iRes[2] = m_iResolution; m_pCount->m_iHistogramRes = 0; m_pCount->Create(); if (m_bModeAvg) { m_pValueAvg = new C3DF(); m_pValueAvg->m_fMinVal[0] = -m_fRadius; m_pValueAvg->m_fMaxVal[0] = m_fRadius; m_pValueAvg->m_fMinVal[1] = -m_fRadius; m_pValueAvg->m_fMaxVal[1] = m_fRadius; m_pValueAvg->m_fMinVal[2] = -m_fRadius; m_pValueAvg->m_fMaxVal[2] = m_fRadius; m_pValueAvg->m_iRes[0] = m_iResolution; m_pValueAvg->m_iRes[1] = m_iResolution; m_pValueAvg->m_iRes[2] = m_iResolution; m_pValueAvg->m_iHistogramRes = 0; m_pValueAvg->Create(); } if (m_bModeMin) { m_pValueMin = new C3DF(); m_pValueMin->m_fMinVal[0] = -m_fRadius; m_pValueMin->m_fMaxVal[0] = m_fRadius; m_pValueMin->m_fMinVal[1] = -m_fRadius; m_pValueMin->m_fMaxVal[1] = m_fRadius; m_pValueMin->m_fMinVal[2] = -m_fRadius; m_pValueMin->m_fMaxVal[2] = m_fRadius; m_pValueMin->m_iRes[0] = m_iResolution; m_pValueMin->m_iRes[1] = m_iResolution; m_pValueMin->m_iRes[2] = m_iResolution; m_pValueMin->m_iHistogramRes = 0; m_pValueMin->Create(); } if (m_bModeMax) { m_pValueMax = new C3DF(); m_pValueMax->m_fMinVal[0] = -m_fRadius; m_pValueMax->m_fMaxVal[0] = m_fRadius; m_pValueMax->m_fMinVal[1] = -m_fRadius; m_pValueMax->m_fMaxVal[1] = m_fRadius; m_pValueMax->m_fMinVal[2] = -m_fRadius; m_pValueMax->m_fMaxVal[2] = m_fRadius; m_pValueMax->m_iRes[0] = m_iResolution; m_pValueMax->m_iRes[1] = m_iResolution; m_pValueMax->m_iRes[2] = m_iResolution; m_pValueMax->m_iHistogramRes = 0; m_pValueMax->Create(); } } void CSDFMap::Process(int rm, CTimeStep *ts) { int z, z2, z3, z4, ti; double px, py, pz, v; CAtomGroup *ag; CMolecule *m; CSingleMolecule *sm; UNUSED(rm); // Keep this: probably other quantities will require knowledge of current reference molecule switch(m_iQuantity) { case 1: // Absolute Velocity for (z=0;zm_pMolecule->m_iIndex]; for (z2=0;z2m_laSingleMolIndex.GetSize();z2++) { sm = (CSingleMolecule*)g_oaSingleMolecules[m->m_laSingleMolIndex[z2]]; for (z3=0;z3m_baAtomType.GetSize();z3++) { for (z4=0;z4<((CxIntArray*)ag->m_oaAtoms[z3])->GetSize();z4++) { ti = ((CxIntArray*)sm->m_oaAtomOffset[ag->m_baAtomType[z3]])->GetAt(((CxIntArray*)ag->m_oaAtoms[z3])->GetAt(z4)); px = ts->m_vaCoords[ti][0]; py = ts->m_vaCoords[ti][1]; pz = ts->m_vaCoords[ti][2]; v = ts->m_vaVelocities[ti].GetLength(); AddValue(px,py,pz,v); } } } } break; default: return; } } void CSDFMap::BuildName() { // char tmp[32768]; CxString tmp; if (m_bSphere) // sprintf(tmp,"sdfmap_%s_%s%d%s%d%s%d_%s_sph%d",((CMolecule*)g_oaMolecules[g_iFixMol])->m_sName,((CAtom*)g_oaAtoms[g_iFixRealAtomType[0]])->m_sName,g_iFixAtom[0]+1,((CAtom*)g_oaAtoms[g_iFixRealAtomType[1]])->m_sName,g_iFixAtom[1]+1,((CAtom*)g_oaAtoms[g_iFixRealAtomType[2]])->m_sName,g_iFixAtom[2]+1,m_sSubName,m_iSphereRadius); tmp.sprintf("sdfmap_%s_%s%d%s%d%s%d_%s_sph%d",((CMolecule*)g_oaMolecules[g_iFixMol])->m_sName,(const char*)((CAtom*)g_oaAtoms[g_iFixRealAtomType[0]])->m_sName,g_iFixAtom[0]+1,(const char*)((CAtom*)g_oaAtoms[g_iFixRealAtomType[1]])->m_sName,g_iFixAtom[1]+1,(const char*)((CAtom*)g_oaAtoms[g_iFixRealAtomType[2]])->m_sName,g_iFixAtom[2]+1,m_sSubName,m_iSphereRadius); else // sprintf(tmp,"sdfmap_%s_%s%d%s%d%s%d_%s",((CMolecule*)g_oaMolecules[g_iFixMol])->m_sName,((CAtom*)g_oaAtoms[g_iFixRealAtomType[0]])->m_sName,g_iFixAtom[0]+1,((CAtom*)g_oaAtoms[g_iFixRealAtomType[1]])->m_sName,g_iFixAtom[1]+1,((CAtom*)g_oaAtoms[g_iFixRealAtomType[2]])->m_sName,g_iFixAtom[2]+1,m_sSubName); tmp.sprintf("sdfmap_%s_%s%d%s%d%s%d_%s",((CMolecule*)g_oaMolecules[g_iFixMol])->m_sName,(const char*)((CAtom*)g_oaAtoms[g_iFixRealAtomType[0]])->m_sName,g_iFixAtom[0]+1,(const char*)((CAtom*)g_oaAtoms[g_iFixRealAtomType[1]])->m_sName,g_iFixAtom[1]+1,(const char*)((CAtom*)g_oaAtoms[g_iFixRealAtomType[2]])->m_sName,g_iFixAtom[2]+1,m_sSubName); try { m_sName = new char[strlen(tmp)+1]; } catch(...) { m_sName = NULL; } if (m_sName == NULL) NewException((double)(strlen(tmp)+1)*sizeof(char),__FILE__,__LINE__,__PRETTY_FUNCTION__); strcpy(m_sName,tmp); } void CSDFMap::Finish() { int z; double mimi, mima, miavg, mico, mami, mama, maavg, maco, avmi, avma, avavg, avco, toco, ze; C3DF *tempSDF; // char buf[256]; CxString buf; mprintf(YELLOW," * Finishing %s ...\n",m_sName); mprintf(" Calculating statistics...\n"); toco = 0; ze = 0; mimi = 0; mima = 0; miavg = 0; mico = 0; mami = 0; mama = 0; maavg = 0; maco = 0; avmi = 0; avma = 0; avavg = 0; avco = 0; if (m_bModeMin) { mimi = 1.0E30; mima = -1.0E30; miavg = 0; mico = 0; } if (m_bModeMax) { mami = 1.0E30; mama = -1.0E30; maavg = 0; maco = 0; } if (m_bModeAvg) { avmi = 1.0E30; avma = -1.0E30; avavg = 0; avco = 0; } for (z=0;zm_pBin[z] != 0) { toco += m_pCount->m_pBin[z]; if (m_bModeAvg) { m_pValueAvg->m_pBin[z] /= m_pCount->m_pBin[z]; avco++; avavg += m_pValueAvg->m_pBin[z]; if (m_pValueAvg->m_pBin[z] > avma) avma = m_pValueAvg->m_pBin[z]; if (m_pValueAvg->m_pBin[z] < avmi) avmi = m_pValueAvg->m_pBin[z]; } if (m_bModeMin) { mico++; miavg += m_pValueMin->m_pBin[z]; if (m_pValueMin->m_pBin[z] > mima) mima = m_pValueMin->m_pBin[z]; if (m_pValueMin->m_pBin[z] < mimi) mimi = m_pValueMin->m_pBin[z]; } if (m_bModeMax) { maco++; maavg += m_pValueMax->m_pBin[z]; if (m_pValueMax->m_pBin[z] > mama) mama = m_pValueMax->m_pBin[z]; if (m_pValueMax->m_pBin[z] < mami) mami = m_pValueMax->m_pBin[z]; } } else ze++; } mprintf(" %.0f bin entries in total.\n",toco); mprintf(" %.0f bin values are zero (%.3f%c).\n",ze,ze/m_iResolution/m_iResolution/m_iResolution*100.0,'%'); if (m_bModeAvg) { mprintf(WHITE,"\n Average values:\n"); mprintf(" Min. value %10.5f\n",avmi); mprintf(" Max. value %10.5f\n",avma); mprintf(" Avg. value %10.5f (without all zeros %10.5f)\n",avavg/m_iResolution/m_iResolution/m_iResolution,avavg/avco); } if (m_bModeMin) { mprintf(WHITE,"\n Minimal values:\n"); mprintf(" Min. value %10.5f\n",mimi); mprintf(" Max. value %10.5f\n",mima); mprintf(" Avg. value %10.5f (without all zeros %10.5f)\n",miavg/m_iResolution/m_iResolution/m_iResolution,miavg/mico); } if (m_bModeMax) { mprintf(WHITE,"\n Maximal values:\n"); mprintf(" Min. value %10.5f\n",mami); mprintf(" Max. value %10.5f\n",mama); mprintf(" Avg. value %10.5f (without all zeros %10.5f)\n",maavg/m_iResolution/m_iResolution/m_iResolution,maavg/maco); } if (m_bModeAvg) { mprintf(WHITE,"\n Writing average SDF map:\n"); for (z=0;z<=g_iSDFMapSmoothGrade;z++) { try { tempSDF = new C3DF(); } catch(...) { tempSDF = NULL; } if (tempSDF == NULL) NewException((double)sizeof(C3DF),__FILE__,__LINE__,__PRETTY_FUNCTION__); tempSDF->CopyFrom(m_pValueAvg); if (z != 0) tempSDF->Smooth(z); tempSDF->CalcMaxEntry(); mprintf(" Data range from %.6f to %.6f.\n",tempSDF->m_fMinEntry,tempSDF->m_fMaxEntry); if (g_pDatabase->GetBool("/PLOT3D/FORMATS/WRITE_PLT")) { if (z != 0) // sprintf(buf,"_avg.s%d.plt",z); buf.sprintf("_avg.s%d.plt",z); else // sprintf(buf,"_avg.plt"); buf.sprintf("_avg.plt"); mprintf(" Saving SDF map as \"%s%s\"...\n",m_sName,(const char*)buf); tempSDF->WritePLT("",m_sName,buf,true); } if (g_pDatabase->GetBool("/PLOT3D/FORMATS/WRITE_CUBE")) { if (z != 0) // sprintf(buf,"_avg.s%d.cube",z); buf.sprintf("_avg.s%d.cube",z); else // sprintf(buf,"_avg.cube"); buf.sprintf("_avg.cube"); mprintf(" Saving SDF map as \"%s%s\"...\n",m_sName,(const char*)buf); tempSDF->WriteCube("",m_sName,buf,true); } delete tempSDF; } } if (m_bModeMin) { mprintf(WHITE,"\n Writing minimal SDF map:\n"); for (z=0;z<=g_iSDFMapSmoothGrade;z++) { try { tempSDF = new C3DF(); } catch(...) { tempSDF = NULL; } if (tempSDF == NULL) NewException((double)sizeof(C3DF),__FILE__,__LINE__,__PRETTY_FUNCTION__); tempSDF->CopyFrom(m_pValueMin); if (z != 0) tempSDF->Smooth(z); tempSDF->CalcMaxEntry(); mprintf(" Data range from %.6f to %.6f.\n",tempSDF->m_fMinEntry,tempSDF->m_fMaxEntry); if (g_pDatabase->GetBool("/PLOT3D/FORMATS/WRITE_PLT")) { if (z != 0) // sprintf(buf,"_min.s%d.plt",z); buf.sprintf("_min.s%d.plt",z); else // sprintf(buf,"_min.plt"); buf.sprintf("_min.plt"); mprintf(" Saving SDF map as \"%s%s\"...\n",m_sName,(const char*)buf); tempSDF->WritePLT("",m_sName,buf,true); } if (g_pDatabase->GetBool("/PLOT3D/FORMATS/WRITE_CUBE")) { if (z != 0) // sprintf(buf,"_min.s%d.cube",z); buf.sprintf("_min.s%d.cube",z); else // sprintf(buf,"_min.cube"); buf.sprintf("_min.cube"); mprintf(" Saving SDF map as \"%s%s\"...\n",m_sName,(const char*)buf); tempSDF->WriteCube("",m_sName,buf,true); } delete tempSDF; } } if (m_bModeMax) { mprintf(WHITE,"\n Writing maximal SDF map:\n"); for (z=0;z<=g_iSDFMapSmoothGrade;z++) { try { tempSDF = new C3DF(); } catch(...) { tempSDF = NULL; } if (tempSDF == NULL) NewException((double)sizeof(C3DF),__FILE__,__LINE__,__PRETTY_FUNCTION__); tempSDF->CopyFrom(m_pValueMax); if (z != 0) tempSDF->Smooth(z); tempSDF->CalcMaxEntry(); mprintf(" Data range from %.6f to %.6f.\n",tempSDF->m_fMinEntry,tempSDF->m_fMaxEntry); if (g_pDatabase->GetBool("/PLOT3D/FORMATS/WRITE_PLT")) { if (z != 0) // sprintf(buf,"_max.s%d.plt",z); buf.sprintf("_max.s%d.plt",z); else // sprintf(buf,"_max.plt"); buf.sprintf("_max.plt"); mprintf(" Saving SDF map as \"%s%s\"...\n",m_sName,(const char*)buf); tempSDF->WritePLT("",m_sName,buf,true); } if (g_pDatabase->GetBool("/PLOT3D/FORMATS/WRITE_CUBE")) { if (z != 0) // sprintf(buf,"_max.s%d.cube",z); buf.sprintf("_max.s%d.cube",z); else // sprintf(buf,"_max.cube"); buf.sprintf("_max.cube"); mprintf(" Saving SDF map as \"%s%s\"...\n",m_sName,(const char*)buf); tempSDF->WriteCube("",m_sName,buf,true); } delete tempSDF; } } } travis-src-190101/src/sdfmap.h0100777000000000000000000000440213412725653013064 0ustar00/***************************************************************************** TRAVIS - Trajectory Analyzer and Visualizer http://www.travis-analyzer.de/ Copyright (c) 2009-2019 Martin Brehm 2012-2019 Martin Thomas 2016-2019 Sascha Gehrke This file was written by Martin Brehm. --------------------------------------------------------------------------- This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . *****************************************************************************/ #ifndef SDFMAP_H #define SDFMAP_H // This must always be the first include directive #include "config.h" #include "xobject.h" #include "xobarray.h" #include "3df.h" #include "timestep.h" class CSDFMap : public CxObject { public: CSDFMap(); ~CSDFMap(); void Parse(); void Create(); void Process(int rm, CTimeStep *ts); void BuildName(); void Finish(); int m_iQuantity; bool m_bModeMin; bool m_bModeMax; bool m_bModeAvg; CxObArray m_oaAtomGroups; int m_iResolution; double m_fRadius; bool m_bSphere; int m_iSphereRadius; C3DF *m_pValueMin; C3DF *m_pValueMax; C3DF *m_pValueAvg; C3DF *m_pCount; char *m_sName; char *m_sSubName; void AddValue(double x, double y, double z, double v) { if (m_bModeAvg) m_pValueAvg->AddToBin_Single(x,y,z,v); if (m_bModeMax) if (v > m_pValueMax->GetBinValue_Single(x,y,z)) m_pValueMax->SetBinValue_Single(x,y,z,v); if (m_bModeMin) { if ((m_pCount->GetBinValue_Single(x,y,z) == 0) || (v < m_pValueMin->GetBinValue_Single(x,y,z))) m_pValueMin->SetBinValue_Single(x,y,z,v); } m_pCount->AddToBin_Single(x,y,z,1.0); } }; #endif travis-src-190101/src/spectrum.cpp0100777000000000000000000001001513412725616014003 0ustar00/***************************************************************************** TRAVIS - Trajectory Analyzer and Visualizer http://www.travis-analyzer.de/ Copyright (c) 2009-2019 Martin Brehm 2012-2019 Martin Thomas 2016-2019 Sascha Gehrke This file was written by Martin Brehm. --------------------------------------------------------------------------- This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . *****************************************************************************/ // This must always be the first include directive #include "config.h" #include "spectrum.h" #include #include "travis.h" const char *GetRevisionInfo_spectrum(unsigned int len) { static char buf[256]; GET_REVISION_INFO( buf, len ); return buf; } const char *GetSourceVersion_spectrum() { static char buf[256]; GET_SOURCE_VERSION( buf ); return buf; } CSpectrum::CSpectrum() { BTIN; m_pData = NULL; m_pComplex = NULL; BTOUT; } CSpectrum::~CSpectrum() { BTIN; if (m_pData != NULL) { delete[] m_pData; m_pData = NULL; } if (m_pComplex != NULL) { delete[] m_pComplex; m_pComplex = NULL; } BTOUT; } void CSpectrum::Create(int i) { m_iSize = i; try { m_pData = new double[i]; } catch(...) { m_pData = NULL; } if (m_pData == NULL) NewException((double)i*sizeof(double),__FILE__,__LINE__,__PRETTY_FUNCTION__); try { m_pComplex = new double[i*2]; } catch(...) { m_pComplex = NULL; } if (m_pComplex == NULL) NewException((double)i*2*sizeof(double),__FILE__,__LINE__,__PRETTY_FUNCTION__); } void CSpectrum::FromComplex(double *f) { int z; if (m_pComplex != NULL) memcpy(m_pComplex,f,m_iSize*2*sizeof(double)); for (z=0;z m_fWaveNumber) && (m_fWaveNumber > 0)) break; /* mfprintf(a,"%.2f; %.5f; %.5f",z*m_fMaxRWL/m_iSize,m_pData[z],m_pData[z]*m_pData[z]); if (m_pComplex != NULL) mfprintf(a,"; %.5f; %.5f",m_pComplex[z*2],m_pComplex[z*2+1]); mfprintf(a,"\n");*/ mfprintf(a,"%G; %G; %G\n",z*m_fMaxRWL/m_iSize,m_pData[z],m_pData[z]*m_pData[z]); } fclose(a); BTOUT; } void CSpectrum::SetMaxRWL(double f) { m_fMaxRWL = f; } void CSpectrum::MakeDB() { double f; int z; f = 0; for (z=0;z m) m = m_pData[z]; m = f/m; for (z=0;z. *****************************************************************************/ #ifndef SPECTRUM_H #define SPECTRUM_H // This must always be the first include directive #include "config.h" #include "xobject.h" #include "tools.h" #include "backtrace.h" class CSpectrum : public CxObject { public: void SetIntegral(double f); void SetMaxValue(double f); void Multiply(double f); void MakeDB(); void SetMaxRWL(double f); void Write(const char *pre, const char *s, const char *post); void FromComplex(double *f); void Create(int i); double *m_pComplex; double *m_pData; double m_fMaxRWL; long m_iSize; double m_fWaveNumber; CSpectrum(); virtual ~CSpectrum(); }; #endif travis-src-190101/src/statistics.cpp0100777000000000000000000000715613412725616014347 0ustar00/***************************************************************************** TRAVIS - Trajectory Analyzer and Visualizer http://www.travis-analyzer.de/ Copyright (c) 2009-2019 Martin Brehm 2012-2019 Martin Thomas 2016-2019 Sascha Gehrke This file was written by Martin Brehm. --------------------------------------------------------------------------- This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . *****************************************************************************/ // This must always be the first include directive #include "config.h" #include "statistics.h" #include "xstring.h" const char *GetRevisionInfo_statistics(unsigned int len) { static char buf[256]; GET_REVISION_INFO( buf, len ); return buf; } const char *GetSourceVersion_statistics() { static char buf[256]; GET_SOURCE_VERSION( buf ); return buf; } CStatistics::CStatistics() { m_iSizeX = 0; m_iSizeY = 0; m_pMin = NULL; m_pMax = NULL; m_pAvg = NULL; m_pCount = NULL; m_waXValues.SetName("CStatistics::m_waXValues"); m_waYValues.SetName("CStatistics::m_waYValues"); } CStatistics::~CStatistics() { if (m_pMin != NULL) { delete[] m_pMin; m_pMin = NULL; } if (m_pMax != NULL) { delete[] m_pMax; m_pMax = NULL; } if (m_pAvg != NULL) { delete[] m_pAvg; m_pAvg = NULL; } if (m_pCount != NULL) { delete[] m_pCount; m_pCount = NULL; } } void CStatistics::Init(int x, int y) { int z; m_iSizeX = x; m_iSizeY = y; try { m_pMin = new double[x*y]; } catch(...) { m_pMin = NULL; } if (m_pMin == NULL) NewException((double)x*y*sizeof(double),__FILE__,__LINE__,__PRETTY_FUNCTION__); try { m_pMax = new double[x*y]; } catch(...) { m_pMax = NULL; } if (m_pMax == NULL) NewException((double)x*y*sizeof(double),__FILE__,__LINE__,__PRETTY_FUNCTION__); try { m_pAvg = new double[x*y]; } catch(...) { m_pAvg = NULL; } if (m_pAvg == NULL) NewException((double)x*y*sizeof(double),__FILE__,__LINE__,__PRETTY_FUNCTION__); try { m_pCount = new double[x*y]; } catch(...) { m_pCount = NULL; } if (m_pCount == NULL) NewException((double)x*y*sizeof(double),__FILE__,__LINE__,__PRETTY_FUNCTION__); for (z=0;z. *****************************************************************************/ #ifndef STATISTICS_H #define STATISTICS_H // This must always be the first include directive #include "config.h" #include "xobject.h" #include "tools.h" #include "backtrace.h" #include "xwordarray.h" class CStatistics : public CxObject { public: CStatistics(); virtual ~CStatistics(); void Init(int x, int y); void Evaluate(); void Write(const char *pre, const char *s, const char *post); void AddValue(int x, int y, double v) { int z; z = y*m_iSizeX + x; m_pCount[z]++; m_pAvg[z] += v; if (v < m_pMin[z]) m_pMin[z] = v; if (v > m_pMax[z]) m_pMax[z] = v; } double *m_pMin; double *m_pMax; double *m_pAvg; double *m_pCount; CxWordArray m_waXValues; CxWordArray m_waYValues; int m_iSizeX, m_iSizeY; }; #endif travis-src-190101/src/structurefactor.cpp0100777000000000000000000027671513412725636015427 0ustar00/***************************************************************************** TRAVIS - Trajectory Analyzer and Visualizer http://www.travis-analyzer.de/ Copyright (c) 2009-2019 Martin Brehm 2012-2019 Martin Thomas 2016-2019 Sascha Gehrke This file was written by Martin Thomas. --------------------------------------------------------------------------- This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . *****************************************************************************/ // This must always be the first include directive #include "config.h" #include "structurefactor.h" #include "globalvar.h" #include "maintools.h" #include "timestep.h" #include "xobarray.h" const char *GetRevisionInfo_structurefactor(unsigned int len) { static char buf[256]; GET_REVISION_INFO( buf, len ); return buf; } const char *GetSourceVersion_structurefactor() { static char buf[256]; GET_SOURCE_VERSION( buf ); return buf; } #define BUF_SIZE 4096 static CxObArray g_isotopes; static CStructureFactor *g_structureFactor; static CxObArray g_sFacObserv; static void createIsotopeList() { // Neutron factors from http://www.ncnr.nist.gov/resources/n-lengths/ // X-Ray factors from http://www.ruppweb.org/new_comp/scattering_factors.htm CIsotope *isotope; try { isotope = new CIsotope("H", -3.7390, 0.493, 0.323, 0.140, 0.041, 10.511, 26.126, 3.142, 57.800, 0.003f); } catch(...) { isotope = NULL; } if(isotope == NULL) NewException((double)sizeof(CIsotope), __FILE__, __LINE__, __PRETTY_FUNCTION__); g_isotopes.Add(isotope); try { isotope = new CIsotope("1H", -3.7406, 0.493, 0.323, 0.140, 0.041, 10.511, 26.126, 3.142, 57.800, 0.003f); } catch(...) { isotope = NULL; } if(isotope == NULL) NewException((double)sizeof(CIsotope), __FILE__, __LINE__, __PRETTY_FUNCTION__); g_isotopes.Add(isotope); try { isotope = new CIsotope("D", 6.671, 0.493, 0.323, 0.140, 0.041, 10.511, 26.126, 3.142, 57.800, 0.003f); } catch(...) { isotope = NULL; } if(isotope == NULL) NewException((double)sizeof(CIsotope), __FILE__, __LINE__, __PRETTY_FUNCTION__); g_isotopes.Add(isotope); try { isotope = new CIsotope("2H", 6.671, 0.493, 0.323, 0.140, 0.041, 10.511, 26.126, 3.142, 57.800, 0.003f); } catch(...) { isotope = NULL; } if(isotope == NULL) NewException((double)sizeof(CIsotope), __FILE__, __LINE__, __PRETTY_FUNCTION__); g_isotopes.Add(isotope); try { isotope = new CIsotope("3H", 4.792, 0.493, 0.323, 0.140, 0.041, 10.511, 26.126, 3.142, 57.800, 0.003f); } catch(...) { isotope = NULL; } if(isotope == NULL) NewException((double)sizeof(CIsotope), __FILE__, __LINE__, __PRETTY_FUNCTION__); g_isotopes.Add(isotope); try { isotope = new CIsotope("B", 5.30, 2.055, 1.333, 1.098, 0.707, 23.219, 1.021, 60.350, 0.140, -0.193f); } catch(...) { isotope = NULL; } if(isotope == NULL) NewException((double)sizeof(CIsotope), __FILE__, __LINE__, __PRETTY_FUNCTION__); g_isotopes.Add(isotope); try { isotope = new CIsotope("10B", -0.1, 2.055, 1.333, 1.098, 0.707, 23.219, 1.021, 60.350, 0.140, -0.193f); } catch(...) { isotope = NULL; } if(isotope == NULL) NewException((double)sizeof(CIsotope), __FILE__, __LINE__, __PRETTY_FUNCTION__); g_isotopes.Add(isotope); try { isotope = new CIsotope("11B", 6.65, 2.055, 1.333, 1.098, 0.707, 23.219, 1.021, 60.350, 0.140, -0.193f); } catch(...) { isotope = NULL; } if(isotope == NULL) NewException((double)sizeof(CIsotope), __FILE__, __LINE__, __PRETTY_FUNCTION__); g_isotopes.Add(isotope); try { isotope = new CIsotope("C", 6.6460, 2.310, 1.020, 1.589, 0.865, 20.844, 10.208, 0.569, 51.651, 0.216f); } catch(...) { isotope = NULL; } if(isotope == NULL) NewException((double)sizeof(CIsotope), __FILE__, __LINE__, __PRETTY_FUNCTION__); g_isotopes.Add(isotope); try { isotope = new CIsotope("12C", 6.6511, 2.310, 1.020, 1.589, 0.865, 20.844, 10.208, 0.569, 51.651, 0.216f); } catch(...) { isotope = NULL; } if(isotope == NULL) NewException((double)sizeof(CIsotope), __FILE__, __LINE__, __PRETTY_FUNCTION__); g_isotopes.Add(isotope); try { isotope = new CIsotope("13C", 6.19, 2.310, 1.020, 1.589, 0.865, 20.844, 10.208, 0.569, 51.651, 0.216f); } catch(...) { isotope = NULL; } if(isotope == NULL) NewException((double)sizeof(CIsotope), __FILE__, __LINE__, __PRETTY_FUNCTION__); g_isotopes.Add(isotope); try { isotope = new CIsotope("N", 9.36, 12.213, 3.132, 2.013, 1.166, 0.006, 9.893, 28.997, 0.583, -11.529f); } catch(...) { isotope = NULL; } if(isotope == NULL) NewException((double)sizeof(CIsotope), __FILE__, __LINE__, __PRETTY_FUNCTION__); g_isotopes.Add(isotope); try { isotope = new CIsotope("14N", 9.37, 12.213, 3.132, 2.013, 1.166, 0.006, 9.893, 28.997, 0.583, -11.529f); } catch(...) { isotope = NULL; } if(isotope == NULL) NewException((double)sizeof(CIsotope), __FILE__, __LINE__, __PRETTY_FUNCTION__); g_isotopes.Add(isotope); try { isotope = new CIsotope("15N", 6.44, 12.213, 3.132, 2.013, 1.166, 0.006, 9.893, 28.997, 0.583, -11.529f); } catch(...) { isotope = NULL; } if(isotope == NULL) NewException((double)sizeof(CIsotope), __FILE__, __LINE__, __PRETTY_FUNCTION__); g_isotopes.Add(isotope); try { isotope = new CIsotope("O", 5.803, 3.049, 2.287, 1.546, 0.867, 13.277, 5.701, 0.324, 32.909, 0.251f); } catch(...) { isotope = NULL; } if(isotope == NULL) NewException((double)sizeof(CIsotope), __FILE__, __LINE__, __PRETTY_FUNCTION__); g_isotopes.Add(isotope); try { isotope = new CIsotope("16O", 5.803, 3.049, 2.287, 1.546, 0.867, 13.277, 5.701, 0.324, 32.909, 0.251f); } catch(...) { isotope = NULL; } if(isotope == NULL) NewException((double)sizeof(CIsotope), __FILE__, __LINE__, __PRETTY_FUNCTION__); g_isotopes.Add(isotope); try { isotope = new CIsotope("17O", 5.78, 3.049, 2.287, 1.546, 0.867, 13.277, 5.701, 0.324, 32.909, 0.251f); } catch(...) { isotope = NULL; } if(isotope == NULL) NewException((double)sizeof(CIsotope), __FILE__, __LINE__, __PRETTY_FUNCTION__); g_isotopes.Add(isotope); try { isotope = new CIsotope("18O", 5.84, 3.049, 2.287, 1.546, 0.867, 13.277, 5.701, 0.324, 32.909, 0.251f); } catch(...) { isotope = NULL; } if(isotope == NULL) NewException((double)sizeof(CIsotope), __FILE__, __LINE__, __PRETTY_FUNCTION__); g_isotopes.Add(isotope); try { isotope = new CIsotope("F", 5.654, 3.539, 2.641, 1.517, 1.024, 10.283, 4.294, 0.262, 26.148, 0.278f); } catch(...) { isotope = NULL; } if(isotope == NULL) NewException((double)sizeof(CIsotope), __FILE__, __LINE__, __PRETTY_FUNCTION__); g_isotopes.Add(isotope); try { isotope = new CIsotope("P", 5.13, 6.435, 4.179, 1.780, 1.491, 1.907, 27.157, 0.526, 68.164, 1.115); } catch(...) { isotope = NULL; } if(isotope == NULL) NewException((double)sizeof(CIsotope), __FILE__, __LINE__, __PRETTY_FUNCTION__); g_isotopes.Add(isotope); try { isotope = new CIsotope("S", 2.847, 6.905, 5.203, 1.438, 1.586, 1.468, 22.215, 0.254, 56.172, 0.867f); } catch(...) { isotope = NULL; } if(isotope == NULL) NewException((double)sizeof(CIsotope), __FILE__, __LINE__, __PRETTY_FUNCTION__); g_isotopes.Add(isotope); try { isotope = new CIsotope("32S", 2.804, 6.905, 5.203, 1.438, 1.586, 1.468, 22.215, 0.254, 56.172, 0.867f); } catch(...) { isotope = NULL; } if(isotope == NULL) NewException((double)sizeof(CIsotope), __FILE__, __LINE__, __PRETTY_FUNCTION__); g_isotopes.Add(isotope); try { isotope = new CIsotope("33S", 4.74, 6.905, 5.203, 1.438, 1.586, 1.468, 22.215, 0.254, 56.172, 0.867f); } catch(...) { isotope = NULL; } if(isotope == NULL) NewException((double)sizeof(CIsotope), __FILE__, __LINE__, __PRETTY_FUNCTION__); g_isotopes.Add(isotope); try { isotope = new CIsotope("34S", 3.48, 6.905, 5.203, 1.438, 1.586, 1.468, 22.215, 0.254, 56.172, 0.867f); } catch(...) { isotope = NULL; } if(isotope == NULL) NewException((double)sizeof(CIsotope), __FILE__, __LINE__, __PRETTY_FUNCTION__); g_isotopes.Add(isotope); try { isotope = new CIsotope("36S", 3.1, 6.905, 5.203, 1.438, 1.586, 1.468, 22.215, 0.254, 56.172, 0.867f); } catch(...) { isotope = NULL; } if(isotope == NULL) NewException((double)sizeof(CIsotope), __FILE__, __LINE__, __PRETTY_FUNCTION__); g_isotopes.Add(isotope); try { isotope = new CIsotope("Cl", 9.577, 11.460, 7.196, 6.256, 1.645, 0.010, 1.166, 18.519, 47.778, -9.557f); } catch(...) { isotope = NULL; } if(isotope == NULL) NewException((double)sizeof(CIsotope), __FILE__, __LINE__, __PRETTY_FUNCTION__); g_isotopes.Add(isotope); try { isotope = new CIsotope("35Cl", 11.65, 11.460, 7.196, 6.256, 1.645, 0.010, 1.166, 18.519, 47.778, -9.557f); } catch(...) { isotope = NULL; } if(isotope == NULL) NewException((double)sizeof(CIsotope), __FILE__, __LINE__, __PRETTY_FUNCTION__); g_isotopes.Add(isotope); try { isotope = new CIsotope("37Cl", 3.08, 11.460, 7.196, 6.256, 1.645, 0.010, 1.166, 18.519, 47.778, -9.557f); } catch(...) { isotope = NULL; } if(isotope == NULL) NewException((double)sizeof(CIsotope), __FILE__, __LINE__, __PRETTY_FUNCTION__); g_isotopes.Add(isotope); try { isotope = new CIsotope("Br", 6.795, 17.179, 5.236, 5.638, 3.985, 2.172, 16.580, 0.261, 41.433, -2.956f); } catch(...) { isotope = NULL; } if(isotope == NULL) NewException((double)sizeof(CIsotope), __FILE__, __LINE__, __PRETTY_FUNCTION__); g_isotopes.Add(isotope); try { isotope = new CIsotope("79Br", 6.80, 17.179, 5.236, 5.638, 3.985, 2.172, 16.580, 0.261, 41.433, -2.956f); } catch(...) { isotope = NULL; } if(isotope == NULL) NewException((double)sizeof(CIsotope), __FILE__, __LINE__, __PRETTY_FUNCTION__); g_isotopes.Add(isotope); try { isotope = new CIsotope("81Br", 6.79, 17.179, 5.236, 5.638, 3.985, 2.172, 16.580, 0.261, 41.433, -2.956f); } catch(...) { isotope = NULL; } if(isotope == NULL) NewException((double)sizeof(CIsotope), __FILE__, __LINE__, __PRETTY_FUNCTION__); g_isotopes.Add(isotope); } static void deleteIsotopeList() { int i; for(i = 0; i < g_isotopes.GetSize(); i++) delete (CIsotope *)g_isotopes[i]; } struct StructureFactorAtomKind: public CxObject { int atomType; CxObArray isotopeList; }; struct StructureFactorMolecule: public CxObject { int moleculeType; CxObArray atomKinds; }; CIsotope::CIsotope(const char *label, double neutronFactor, double cma1, double cma2, double cma3, double cma4, double cmb1, double cmb2, double cmb3, double cmb4, double cmc) { try { _label = new char[strlen(label) + 1]; } catch(...) { _label = NULL; } if(_label == NULL) NewException((double)sizeof(char) * (strlen(label) + 1), __FILE__, __LINE__, __PRETTY_FUNCTION__); strcpy(_label, label); _neutronFactor = neutronFactor; _cma[0] = cma1; _cma[1] = cma2; _cma[2] = cma3; _cma[3] = cma4; _cmb[0] = cmb1; _cmb[1] = cmb2; _cmb[2] = cmb3; _cmb[3] = cmb4; _cmc = cmc; } CIsotope::~CIsotope() { delete[] _label; } double CIsotope::xrayFactor(double q) { double x = q * 100.0 / 4.0 / Pi; double factor = 0.0; int i; for(i = 0; i < 4; i++) { factor += _cma[i] * exp(-_cmb[i] * x * x); } factor += _cmc; return factor; } CStructureFactorGroup::CStructureFactorGroup(bool global, CxObArray &isotopeAssignList) { int i, j, k, l; if (global) { for (i = 0; i < g_oaMolecules.GetSize(); i++) { CAtomGroup *ag; try { ag = new CAtomGroup(); } catch(...) { ag = NULL; } if (ag == NULL) NewException((double)sizeof(CAtomGroup), __FILE__, __LINE__, __PRETTY_FUNCTION__); if(!ag->ParseAtoms((CMolecule *)g_oaMolecules[i], "*")) { eprintf("CStructureFactorGroup::CStructureFactorGroup(): Internal error.\n"); abort(); } m_atomGroupList.Add(ag); } m_sepInterIntra = false; } else { CxString buf, buf2; while (true) { buf.sprintf(" Take atoms from which molecule ("); for (i = 0; i < g_oaMolecules.GetSize(); i++) { buf2.sprintf("%s=%d", ((CMolecule *)g_oaMolecules[i])->m_sName, i+1); buf.strcat(buf2); if (i < g_oaMolecules.GetSize() - 1) { buf.strcat(", "); } } buf.strcat(")? "); int mol = AskRangeInteger_ND("%s", 1, g_oaMolecules.GetSize(),(const char*)buf) - 1; CAtomGroup *ag; try { ag = new CAtomGroup(); } catch(...) { ag = NULL; } if (ag == NULL) NewException((double)sizeof(CAtomGroup), __FILE__, __LINE__, __PRETTY_FUNCTION__); while (true) { if (((CMolecule *)g_oaMolecules[mol])->m_iAtomGesNoVirt == 1) { mprintf(" %s is only one atom, there is no choice.\n", ((CMolecule *)g_oaMolecules[mol])->m_sName); ag->Reset(); ag->m_pMolecule = (CMolecule *)g_oaMolecules[mol]; ag->AddAtom(0, 0, false); ag->SortAtoms(); ag->BuildName(); } else { AskString(" Which atom(s) to take from molecule %s (e.g. \"C1,C3-5,H\", \"*\"=all)? [*] ", &buf, "*", ((CMolecule*)g_oaMolecules[mol])->m_sName); if(!ag->ParseAtoms((CMolecule *)g_oaMolecules[mol], buf)) { continue; } bool containsVirt = false; for (i = 0; i < ag->m_baAtomType.GetSize(); i++) { if (ag->m_baAtomType[i] == g_iVirtAtomType) { containsVirt = true; break; } } if (containsVirt) { eprintf("The selection must not contain virtual atoms.\n"); continue; } } break; } m_atomGroupList.Add(ag); if (!AskYesNo("\n Add atoms from another molecule (y/n)? [no] ", false)) break; mprintf("\n"); } mprintf("\n"); m_sepInterIntra = AskYesNo(" Separate intramolecular and intermolecular contributions (y/n)? [no] ", false); mprintf("\n"); } if (global) { m_name.sprintf("total"); } else { CxString temp; for (i = 0; i < m_atomGroupList.GetSize(); i++) { if (i > 0) temp.strcat("__"); temp.strcat(((CAtomGroup *)m_atomGroupList[i])->m_pMolecule->m_sName); temp.strcat("_"); temp.strcat(((CAtomGroup *)m_atomGroupList[i])->m_sName); } m_name.sprintf("[%s]", (const char *)temp); } for (i = 0; i < m_atomGroupList.GetSize(); i++) { CAtomGroup *ag = (CAtomGroup *)m_atomGroupList[i]; CMolecule *mol = ag->m_pMolecule; for (j = 0; j < ag->m_baAtomType.GetSize(); j++) { CxIntArray *a = (CxIntArray *)ag->m_oaAtoms[j]; for (k = 0; k < a->GetSize(); k++) { CIsotope *isotope = (CIsotope *)((StructureFactorAtomKind *)((StructureFactorMolecule *)isotopeAssignList.GetAt(mol->m_iIndex))->atomKinds[ag->m_baAtomType[j]])->isotopeList[k]; int isotopeIndex = -1; for (l = 0; l < m_isotopeTypeList.GetSize(); l++) { if((CIsotope *)m_isotopeTypeList[l] == isotope) { isotopeIndex = l; break; } } if (isotopeIndex == -1) { isotopeIndex = m_isotopeTypeList.GetSize(); m_isotopeTypeList.Add(isotope); m_isotopeTypeCount.Add(0); } for (l = 0; l < mol->m_laSingleMolIndex.GetSize(); l++) { CSingleMolecule *sm = (CSingleMolecule *)g_oaSingleMolecules[mol->m_laSingleMolIndex[l]]; m_atomIndexList.Add(((CxIntArray *)sm->m_oaAtomOffset[ag->m_baAtomType[j]])->GetAt(a->GetAt(k))); m_singleMolList.Add(mol->m_laSingleMolIndex[l]); m_isotopeList.Add(isotopeIndex); m_isotopeTypeCount[isotopeIndex]++; } } } } m_isotopeTypeTotalCount.SetSize(m_isotopeTypeCount.GetSize()); for (i = 0; i < m_isotopeTypeTotalCount.GetSize(); i++) m_isotopeTypeTotalCount[i] = 0; for (i = 0; i < isotopeAssignList.GetSize(); i++) { StructureFactorMolecule *smol = (StructureFactorMolecule *)isotopeAssignList[i]; for (j = 0; j < smol->atomKinds.GetSize(); j++) { StructureFactorAtomKind *satom = (StructureFactorAtomKind *)smol->atomKinds[j]; for (k = 0; k < satom->isotopeList.GetSize(); k++) { CIsotope *isotope = (CIsotope *)satom->isotopeList[k]; int isotopeIndex = -1; for (l = 0; l < m_isotopeTypeList.GetSize(); l++) { if ((CIsotope *)m_isotopeTypeList[l] == isotope) { isotopeIndex = l; break; } } if (isotopeIndex != -1) { m_isotopeTypeTotalCount[isotopeIndex] += ((CMolecule *)g_oaMolecules[i])->m_laSingleMolIndex.GetSize(); } } } } m_global = global; } CStructureFactorGroup::~CStructureFactorGroup() { int i; for (i = 0; i < m_atomGroupList.GetSize(); i++) delete (CAtomGroup *)m_atomGroupList[i]; for (i = 0; i < m_rdfList.GetSize(); i++) delete (CDF *)m_rdfList[i]; for (i = 0; i < m_rdfIntraList.GetSize(); i++) delete (CDF *)m_rdfIntraList[i]; for (i = 0; i < m_rdfInterList.GetSize(); i++) delete (CDF *)m_rdfInterList[i]; } void CStructureFactorGroup::initialize(double rdfMax, int rdfRes) { int i; mprintf(" Creating %d RDFs\n", m_isotopeTypeList.GetSize() * (m_isotopeTypeList.GetSize() + 1) / 2); for (i = 0; i < m_isotopeTypeList.GetSize() * (m_isotopeTypeList.GetSize() + 1) / 2; i++) { CDF *df; try { df = new CDF(); } catch(...) { df = NULL; } if (df == NULL) NewException((double)sizeof(CDF), __FILE__, __LINE__, __PRETTY_FUNCTION__); df->m_fMinVal = 0.0; df->m_fMaxVal = rdfMax; df->m_iResolution = rdfRes; df->SetLabelX("Distance / pm"); df->SetLabelY("g(r)"); df->Create(); m_rdfList.Add(df); } if (m_sepInterIntra) { mprintf(" Creating %d intramolecular RDFs\n", m_isotopeTypeList.GetSize() * (m_isotopeTypeList.GetSize() + 1) / 2); for (i = 0; i < m_isotopeTypeList.GetSize() * (m_isotopeTypeList.GetSize() + 1) / 2; i++) { CDF *df; try { df = new CDF(); } catch(...) { df = NULL; } if (df == NULL) NewException((double)sizeof(CDF), __FILE__, __LINE__, __PRETTY_FUNCTION__); df->m_fMinVal = 0.0; df->m_fMaxVal = rdfMax; df->m_iResolution = rdfRes; df->SetLabelX("Distance / pm"); df->SetLabelY("g(r)"); df->Create(); m_rdfIntraList.Add(df); } mprintf(" Creating %d intermolecular RDFs\n", m_isotopeTypeList.GetSize() * (m_isotopeTypeList.GetSize() + 1) / 2); for (i = 0; i < m_isotopeTypeList.GetSize() * (m_isotopeTypeList.GetSize() + 1) / 2; i++) { CDF *df; try { df = new CDF(); } catch(...) { df = NULL; } if (df == NULL) NewException((double)sizeof(CDF), __FILE__, __LINE__, __PRETTY_FUNCTION__); df->m_fMinVal = 0.0; df->m_fMaxVal = rdfMax; df->m_iResolution = rdfRes; df->SetLabelX("Distance / pm"); df->SetLabelY("g(r)"); df->Create(); m_rdfInterList.Add(df); } } } void CStructureFactorGroup::process(CTimeStep *ts) { int i, j; for (i = 0; i < m_atomIndexList.GetSize(); i++) { //if ((i%100) == 0) // mprintf("\n@Group i=%d",i); for (j = i+1; j < m_atomIndexList.GetSize(); j++) { double dist = FoldedLength(ts->m_vaCoords[m_atomIndexList[i]] - ts->m_vaCoords[m_atomIndexList[j]]); int a = m_isotopeList[i]; int b = m_isotopeList[j]; int index; if (a < b) index = (m_isotopeTypeList.GetSize()-1)*a - a*(a-1)/2 + b; else index = (m_isotopeTypeList.GetSize()-1)*b - b*(b-1)/2 + a; ((CDF *)m_rdfList[index])->AddToBin(dist); if (m_sepInterIntra) { if (m_singleMolList[i] == m_singleMolList[j]) ((CDF *)m_rdfIntraList[index])->AddToBin(dist); else ((CDF *)m_rdfInterList[index])->AddToBin(dist); } } } } void CStructureFactorGroup::finalize(CDF *sfac, CDF *xray, CDF *neutron, bool saveIntermediate) { int i, j, k, l; CxString filename; CDF *sfacTemp; try { sfacTemp = new CDF(); } catch(...) { sfacTemp = NULL; } if(sfacTemp == NULL) NewException((double)sizeof(CDF), __FILE__, __LINE__, __PRETTY_FUNCTION__); sfacTemp->m_fMinVal = sfac->m_fMinVal; sfacTemp->m_fMaxVal = sfac->m_fMaxVal; sfacTemp->m_iResolution = sfac->m_iResolution; sfacTemp->SetLabelX("Wave vector modulus / nm^-1"); sfacTemp->SetLabelY("Intensity"); sfacTemp->Create(); for (i = 0; i < m_isotopeTypeList.GetSize(); i++) { for (j = i; j < m_isotopeTypeList.GetSize(); j++) { mprintf(" Processing partial structure factor %s-%s\n", ((CIsotope *)m_isotopeTypeList[i])->label(), ((CIsotope *)m_isotopeTypeList[j])->label()); CDF *df = (CDF *)m_rdfList[(m_isotopeTypeList.GetSize()-1)*i - i*(i-1)/2 + j]; df->MultiplyBin(1.0 / g_iSteps * g_iStride); if(i == j) df->MultiplyBin(2.0); df->CorrectRadialDist(); if (g_bBoxNonOrtho) df->MultiplyBin(g_fBoxVolume * 1000000.0 / (4.0/3.0 * Pi) / ((double)m_isotopeTypeTotalCount[i]) / ((double)m_isotopeTypeTotalCount[j])); else df->MultiplyBin(g_fBoxX * g_fBoxY * g_fBoxZ / (4.0/3.0 * Pi) / ((double)m_isotopeTypeTotalCount[i]) / ((double)m_isotopeTypeTotalCount[j])); if (g_bDoubleBox) df->MultiplyBin(g_iDoubleBoxFactor); if (saveIntermediate) { // df->Integrate(true, (4.0f/3.0f * Pi) * m_isotopeTypeTotalCount[i] * m_isotopeTypeTotalCount[j] / (g_fBoxX * g_fBoxY * g_fBoxZ) / m_isotopeTypeCount[i]); filename.sprintf("sfac_%s%s_rdf_%s_%s.csv", m_global ? "" : "self_", (const char *)m_name, (const char *)(((CIsotope *)m_isotopeTypeList[i])->label()), (const char *)(((CIsotope *)m_isotopeTypeList[j])->label())); mprintf(" Writing RDF to %s...\n", (const char *)filename); df->Write("", filename, "", false); } double shift = ((double)m_isotopeTypeCount[i]) * ((double)m_isotopeTypeCount[j]) / (((double)m_isotopeTypeTotalCount[i]) * ((double)m_isotopeTypeTotalCount[j])); /* mprintf("@ m_isotopeTypeCount[i] = %d\n",m_isotopeTypeCount[i]); mprintf("@ m_isotopeTypeCount[j] = %d\n",m_isotopeTypeCount[j]); mprintf("@ m_isotopeTypeTotalCount[i] = %d\n",m_isotopeTypeTotalCount[i]); mprintf("@ m_isotopeTypeTotalCount[j] = %d\n",m_isotopeTypeTotalCount[j]); mprintf("@ shift = %.10G\n",shift);*/ for (k = 0; k < sfacTemp->m_iResolution; k++) { double q = (sfacTemp->m_fMinVal + (0.5 + k) / sfacTemp->m_fFac) / 1000.0; double f = 0; for (l = 0; l < df->m_iResolution; l++) { double r = (0.5 + l) / df->m_fFac; f += r * (df->m_pBin[l] - shift) / q * sin(r * q); } sfacTemp->m_pBin[k] = f / df->m_fFac; } for (k = 0; k < sfacTemp->m_iResolution; k++) { double q = (sfacTemp->m_fMinVal + (0.5 + k) / sfacTemp->m_fFac) / 1000.0; sfac->m_pBin[k] += sfacTemp->m_pBin[k] * ((i == j) ? 1.0 : 2.0) * ((double)m_isotopeTypeTotalCount[i]) * ((double)m_isotopeTypeTotalCount[j]) / ((double)g_iGesAtomCount) / ((double)g_iGesAtomCount); neutron->m_pBin[k] += sfacTemp->m_pBin[k] * ((i == j) ? 1.0 : 2.0) * ((double)m_isotopeTypeTotalCount[i]) * ((double)m_isotopeTypeTotalCount[j]) / ((double)g_iGesAtomCount) / ((double)g_iGesAtomCount) * ((CIsotope *)m_isotopeTypeList[i])->neutronFactor() * ((CIsotope *)m_isotopeTypeList[j])->neutronFactor(); xray->m_pBin[k] += sfacTemp->m_pBin[k] * ((i == j) ? 1.0 : 2.0) * ((double)m_isotopeTypeTotalCount[i]) * ((double)m_isotopeTypeTotalCount[j]) / ((double)g_iGesAtomCount) / ((double)g_iGesAtomCount) * ((CIsotope *)m_isotopeTypeList[i])->xrayFactor(q) * ((CIsotope *)m_isotopeTypeList[j])->xrayFactor(q); } if (saveIntermediate) { if (g_bBoxNonOrtho) sfacTemp->MultiplyBin(4.0 * Pi * g_iGesAtomCount / g_fBoxVolume / 1000000.0); else sfacTemp->MultiplyBin(4.0 * Pi * g_iGesAtomCount / (g_fBoxX * g_fBoxY * g_fBoxZ)); filename.sprintf("sfac_%s%s_sfac_%s_%s.csv", m_global ? "" : "self_", (const char *)m_name, (const char *)((CIsotope *)m_isotopeTypeList[i])->label(), (const char *)((CIsotope *)m_isotopeTypeList[j])->label()); mprintf(" Writing Structure Factor to %s...\n", (const char *)filename); sfacTemp->Write("", filename, "", false); } sfacTemp->ZeroBin(); } } delete sfacTemp; } void CStructureFactorGroup::finalizeIntra(CDF *sfac, CDF *xray, CDF *neutron, bool saveIntermediate) { int i, j, k, l; CxString filename; CDF *sfacTemp; try { sfacTemp = new CDF(); } catch(...) { sfacTemp = NULL; } if(sfacTemp == NULL) NewException((double)sizeof(CDF), __FILE__, __LINE__, __PRETTY_FUNCTION__); sfacTemp->m_fMinVal = sfac->m_fMinVal; sfacTemp->m_fMaxVal = sfac->m_fMaxVal; sfacTemp->m_iResolution = sfac->m_iResolution; sfacTemp->SetLabelX("Wave vector modulus / nm^-1"); sfacTemp->SetLabelY("Intensity"); sfacTemp->Create(); for (i = 0; i < m_isotopeTypeList.GetSize(); i++) { for (j = i; j < m_isotopeTypeList.GetSize(); j++) { mprintf(" Processing intramolecular partial structure factor %s-%s\n", ((CIsotope *)m_isotopeTypeList[i])->label(), ((CIsotope *)m_isotopeTypeList[j])->label()); CDF *df = (CDF *)m_rdfIntraList[(m_isotopeTypeList.GetSize()-1)*i - i*(i-1)/2 + j]; df->MultiplyBin(1.0 / g_iSteps * g_iStride); if(i == j) df->MultiplyBin(2.0); df->CorrectRadialDist(); if (g_bBoxNonOrtho) df->MultiplyBin(g_fBoxVolume * 1000000.0 / (4.0/3.0 * Pi) / ((double)m_isotopeTypeTotalCount[i]) / ((double)m_isotopeTypeTotalCount[j])); else df->MultiplyBin(g_fBoxX * g_fBoxY * g_fBoxZ / (4.0/3.0 * Pi) / ((double)m_isotopeTypeTotalCount[i]) / ((double)m_isotopeTypeTotalCount[j])); if (g_bDoubleBox) df->MultiplyBin(g_iDoubleBoxFactor); if (saveIntermediate) { filename.sprintf("sfac_self_%s_rdf_%s_%s_intra.csv", (const char *)m_name, (const char *)(((CIsotope *)m_isotopeTypeList[i])->label()), (const char *)(((CIsotope *)m_isotopeTypeList[j])->label())); mprintf(" Writing RDF to %s...\n", (const char *)filename); df->Write("", filename, "", false); } double shift = 0.0; for (k = 0; k < sfacTemp->m_iResolution; k++) { double q = (sfacTemp->m_fMinVal + (0.5 + k) / sfacTemp->m_fFac) / 1000.0; double f = 0; for (l = 0; l < df->m_iResolution; l++) { double r = (0.5 + l) / df->m_fFac; f += r * (df->m_pBin[l] - shift) / q * sin(r * q); } sfacTemp->m_pBin[k] = f / df->m_fFac; } for (k = 0; k < sfacTemp->m_iResolution; k++) { double q = (sfacTemp->m_fMinVal + (0.5 + k) / sfacTemp->m_fFac) / 1000.0; sfac->m_pBin[k] += sfacTemp->m_pBin[k] * ((i == j) ? 1.0 : 2.0) * ((double)m_isotopeTypeTotalCount[i]) * ((double)m_isotopeTypeTotalCount[j]) / ((double)g_iGesAtomCount) / ((double)g_iGesAtomCount); neutron->m_pBin[k] += sfacTemp->m_pBin[k] * ((i == j) ? 1.0 : 2.0) * ((double)m_isotopeTypeTotalCount[i]) * ((double)m_isotopeTypeTotalCount[j]) / ((double)g_iGesAtomCount) / ((double)g_iGesAtomCount) * ((CIsotope *)m_isotopeTypeList[i])->neutronFactor() * ((CIsotope *)m_isotopeTypeList[j])->neutronFactor(); xray->m_pBin[k] += sfacTemp->m_pBin[k] * ((i == j) ? 1.0 : 2.0) * ((double)m_isotopeTypeTotalCount[i]) * ((double)m_isotopeTypeTotalCount[j]) / ((double)g_iGesAtomCount) / ((double)g_iGesAtomCount) * ((CIsotope *)m_isotopeTypeList[i])->xrayFactor(q) * ((CIsotope *)m_isotopeTypeList[j])->xrayFactor(q); } if (saveIntermediate) { if (g_bBoxNonOrtho) sfacTemp->MultiplyBin(4.0 * Pi * g_iGesAtomCount / g_fBoxVolume / 1000000.0); else sfacTemp->MultiplyBin(4.0 * Pi * g_iGesAtomCount / (g_fBoxX * g_fBoxY * g_fBoxZ)); filename.sprintf("sfac_self_%s_sfac_%s_%s_intra.csv", (const char *)m_name, (const char *)((CIsotope *)m_isotopeTypeList[i])->label(), (const char *)((CIsotope *)m_isotopeTypeList[j])->label()); mprintf(" Writing Structure Factor to %s...\n", (const char *)filename); sfacTemp->Write("", filename, "", false); } sfacTemp->ZeroBin(); } } delete sfacTemp; } void CStructureFactorGroup::finalizeInter(CDF *sfac, CDF *xray, CDF *neutron, bool saveIntermediate) { int i, j, k, l; CxString filename; CDF *sfacTemp; try { sfacTemp = new CDF(); } catch(...) { sfacTemp = NULL; } if(sfacTemp == NULL) NewException((double)sizeof(CDF), __FILE__, __LINE__, __PRETTY_FUNCTION__); sfacTemp->m_fMinVal = sfac->m_fMinVal; sfacTemp->m_fMaxVal = sfac->m_fMaxVal; sfacTemp->m_iResolution = sfac->m_iResolution; sfacTemp->SetLabelX("Wave vector modulus / nm^-1"); sfacTemp->SetLabelY("Intensity"); sfacTemp->Create(); for (i = 0; i < m_isotopeTypeList.GetSize(); i++) { for (j = i; j < m_isotopeTypeList.GetSize(); j++) { mprintf(" Processing intermolecular partial structure factor %s-%s\n", ((CIsotope *)m_isotopeTypeList[i])->label(), ((CIsotope *)m_isotopeTypeList[j])->label()); CDF *df = (CDF *)m_rdfInterList[(m_isotopeTypeList.GetSize()-1)*i - i*(i-1)/2 + j]; df->MultiplyBin(1.0 / g_iSteps * g_iStride); if(i == j) df->MultiplyBin(2.0); df->CorrectRadialDist(); if (g_bBoxNonOrtho) df->MultiplyBin(g_fBoxVolume * 1000000.0 / (4.0/3.0 * Pi) / ((double)m_isotopeTypeTotalCount[i]) / ((double)m_isotopeTypeTotalCount[j])); else df->MultiplyBin(g_fBoxX * g_fBoxY * g_fBoxZ / (4.0/3.0 * Pi) / ((double)m_isotopeTypeTotalCount[i]) / ((double)m_isotopeTypeTotalCount[j])); if (g_bDoubleBox) df->MultiplyBin(g_iDoubleBoxFactor); if (saveIntermediate) { filename.sprintf("sfac_self_%s_rdf_%s_%s_inter.csv", (const char *)m_name, (const char *)(((CIsotope *)m_isotopeTypeList[i])->label()), (const char *)(((CIsotope *)m_isotopeTypeList[j])->label())); mprintf(" Writing RDF to %s...\n", (const char *)filename); df->Write("", filename, "", false); } //double shift = (double)m_isotopeTypeCount[i] * m_isotopeTypeCount[j] / (m_isotopeTypeTotalCount[i] * m_isotopeTypeTotalCount[j]); double shift = ((double)m_isotopeTypeCount[i]) * ((double)m_isotopeTypeCount[j]) / (((double)m_isotopeTypeTotalCount[i]) * ((double)m_isotopeTypeTotalCount[j])); for (k = 0; k < sfacTemp->m_iResolution; k++) { double q = (sfacTemp->m_fMinVal + (0.5 + k) / sfacTemp->m_fFac) / 1000.0; double f = 0; for (l = 0; l < df->m_iResolution; l++) { double r = (0.5 + l) / df->m_fFac; f += r * (df->m_pBin[l] - shift) / q * sin(r * q); } sfacTemp->m_pBin[k] = f / df->m_fFac; } for (k = 0; k < sfacTemp->m_iResolution; k++) { double q = (sfacTemp->m_fMinVal + (0.5 + k) / sfacTemp->m_fFac) / 1000.0; sfac->m_pBin[k] += sfacTemp->m_pBin[k] * ((i == j) ? 1.0 : 2.0) * ((double)m_isotopeTypeTotalCount[i]) * ((double)m_isotopeTypeTotalCount[j]) / ((double)g_iGesAtomCount) / ((double)g_iGesAtomCount); neutron->m_pBin[k] += sfacTemp->m_pBin[k] * ((i == j) ? 1.0 : 2.0) * ((double)m_isotopeTypeTotalCount[i]) * ((double)m_isotopeTypeTotalCount[j]) / ((double)g_iGesAtomCount) / ((double)g_iGesAtomCount) * ((CIsotope *)m_isotopeTypeList[i])->neutronFactor() * ((CIsotope *)m_isotopeTypeList[j])->neutronFactor(); xray->m_pBin[k] += sfacTemp->m_pBin[k] * ((i == j) ? 1.0 : 2.0) * ((double)m_isotopeTypeTotalCount[i]) * ((double)m_isotopeTypeTotalCount[j]) / ((double)g_iGesAtomCount) / ((double)g_iGesAtomCount) * ((CIsotope *)m_isotopeTypeList[i])->xrayFactor(q) * ((CIsotope *)m_isotopeTypeList[j])->xrayFactor(q); } if (saveIntermediate) { if (g_bBoxNonOrtho) sfacTemp->MultiplyBin(4.0 * Pi * g_iGesAtomCount / g_fBoxVolume / 1000000.0); else sfacTemp->MultiplyBin(4.0 * Pi * g_iGesAtomCount / (g_fBoxX * g_fBoxY * g_fBoxZ)); filename.sprintf("sfac_self_%s_sfac_%s_%s_inter.csv", (const char *)m_name, (const char *)((CIsotope *)m_isotopeTypeList[i])->label(), (const char *)((CIsotope *)m_isotopeTypeList[j])->label()); mprintf(" Writing Structure Factor to %s...\n", (const char *)filename); sfacTemp->Write("", filename, "", false); } sfacTemp->ZeroBin(); } } delete sfacTemp; } CStructureFactorCross::CStructureFactorCross(CStructureFactorGroup *sfacGroup1, CStructureFactorGroup *sfacGroup2) { m_sfacGroup1 = sfacGroup1; m_sfacGroup2 = sfacGroup2; m_name.sprintf("%s_%s", (const char *)sfacGroup1->getName(), (const char *)sfacGroup2->getName()); m_sepInterIntra = false; } CStructureFactorCross::~CStructureFactorCross() { int i; for (i = 0; i < m_rdfList.GetSize(); i++) delete (CDF *)m_rdfList[i]; for (i = 0; i < m_rdfIntraList.GetSize(); i++) delete (CDF *)m_rdfIntraList[i]; for (i = 0; i < m_rdfInterList.GetSize(); i++) delete (CDF *)m_rdfInterList[i]; } void CStructureFactorCross::initialize(double rdfMax, int rdfRes) { int i; mprintf(" Creating %d RDFs\n", m_sfacGroup1->m_isotopeTypeList.GetSize() * m_sfacGroup2->m_isotopeTypeList.GetSize()); for (i = 0; i < m_sfacGroup1->m_isotopeTypeList.GetSize() * m_sfacGroup2->m_isotopeTypeList.GetSize(); i++) { CDF *df; try { df = new CDF(); } catch(...) { df = NULL; } if (df == NULL) NewException((double)sizeof(CDF), __FILE__, __LINE__, __PRETTY_FUNCTION__); df->m_fMinVal = 0.0; df->m_fMaxVal = rdfMax; df->m_iResolution = rdfRes; df->SetLabelX("Distance / pm"); df->SetLabelY("g(r)"); df->Create(); m_rdfList.Add(df); } if (m_sepInterIntra) { mprintf(" Creating %d intramolecular RDFs\n", m_sfacGroup1->m_isotopeTypeList.GetSize() * m_sfacGroup2->m_isotopeTypeList.GetSize()); for (i = 0; i < m_sfacGroup1->m_isotopeTypeList.GetSize() * m_sfacGroup2->m_isotopeTypeList.GetSize(); i++) { CDF *df; try { df = new CDF(); } catch(...) { df = NULL; } if (df == NULL) NewException((double)sizeof(CDF), __FILE__, __LINE__, __PRETTY_FUNCTION__); df->m_fMinVal = 0.0; df->m_fMaxVal = rdfMax; df->m_iResolution = rdfRes; df->SetLabelX("Distance / pm"); df->SetLabelY("g(r)"); df->Create(); m_rdfIntraList.Add(df); } mprintf(" Creating %d intermolecular RDFs\n", m_sfacGroup1->m_isotopeTypeList.GetSize() * m_sfacGroup2->m_isotopeTypeList.GetSize()); for (i = 0; i < m_sfacGroup1->m_isotopeTypeList.GetSize() * m_sfacGroup2->m_isotopeTypeList.GetSize(); i++) { CDF *df; try { df = new CDF(); } catch(...) { df = NULL; } if (df == NULL) NewException((double)sizeof(CDF), __FILE__, __LINE__, __PRETTY_FUNCTION__); df->m_fMinVal = 0.0; df->m_fMaxVal = rdfMax; df->m_iResolution = rdfRes; df->SetLabelX("Distance / pm"); df->SetLabelY("g(r)"); df->Create(); m_rdfInterList.Add(df); } } } void CStructureFactorCross::process(CTimeStep* ts) { int i, j; for(i = 0; i < m_sfacGroup1->m_atomIndexList.GetSize(); i++) { //if ((i%100) == 0) // mprintf("\n@Cross i=%d",i); for(j = 0; j < m_sfacGroup2->m_atomIndexList.GetSize(); j++) { double dist = FoldedLength(ts->m_vaCoords[m_sfacGroup1->m_atomIndexList[i]] - ts->m_vaCoords[m_sfacGroup2->m_atomIndexList[j]]); int a = m_sfacGroup1->m_isotopeList[i]; int b = m_sfacGroup2->m_isotopeList[j]; ((CDF *)m_rdfList[a * m_sfacGroup2->m_isotopeTypeList.GetSize() + b])->AddToBin(dist); if (m_sepInterIntra) { if (m_sfacGroup1->m_singleMolList[i] == m_sfacGroup2->m_singleMolList[j]) ((CDF *)m_rdfIntraList[a * m_sfacGroup2->m_isotopeTypeList.GetSize() + b])->AddToBin(dist); else ((CDF *)m_rdfInterList[a * m_sfacGroup2->m_isotopeTypeList.GetSize() + b])->AddToBin(dist); } } } } void CStructureFactorCross::finalize(CDF *sfac, CDF *xray, CDF *neutron, bool saveIntermediate) { int i, j, k, l; CxString filename; CDF *sfacTemp; try { sfacTemp = new CDF(); } catch(...) { sfacTemp = NULL; } if(sfacTemp == NULL) NewException((double)sizeof(CDF), __FILE__, __LINE__, __PRETTY_FUNCTION__); sfacTemp->m_fMinVal = sfac->m_fMinVal; sfacTemp->m_fMaxVal = sfac->m_fMaxVal; sfacTemp->m_iResolution = sfac->m_iResolution; sfacTemp->SetLabelX("Wave vector modulus / nm^-1"); sfacTemp->SetLabelY("Intensity"); sfacTemp->Create(); for (i = 0; i < m_sfacGroup1->m_isotopeTypeList.GetSize(); i++) { for (j = 0; j < m_sfacGroup2->m_isotopeTypeList.GetSize(); j++) { mprintf(" Processing partial structure factor %s-%s\n", ((CIsotope *)m_sfacGroup1->m_isotopeTypeList[i])->label(), ((CIsotope *)m_sfacGroup2->m_isotopeTypeList[j])->label()); CDF *df = (CDF *)m_rdfList[i * m_sfacGroup2->m_isotopeTypeList.GetSize() + j]; df->MultiplyBin(1.0 / g_iSteps * g_iStride); if ((CIsotope *)m_sfacGroup1->m_isotopeTypeList[i] == (CIsotope *)m_sfacGroup2->m_isotopeTypeList[j]) df->MultiplyBin(2.0); df->CorrectRadialDist(); if (g_bBoxNonOrtho) df->MultiplyBin(g_fBoxVolume * 1000000.0 / (4.0/3.0 * Pi) / ((double)m_sfacGroup1->m_isotopeTypeTotalCount[i]) / ((double)m_sfacGroup2->m_isotopeTypeTotalCount[j])); else df->MultiplyBin(g_fBoxX * g_fBoxY * g_fBoxZ / (4.0/3.0 * Pi) / ((double)m_sfacGroup1->m_isotopeTypeTotalCount[i]) / ((double)m_sfacGroup2->m_isotopeTypeTotalCount[j])); if (g_bDoubleBox) df->MultiplyBin(g_iDoubleBoxFactor); if (saveIntermediate) { filename.sprintf("sfac_cross_%s_rdf_%s_%s.csv", (const char *)m_name, (const char *)(((CIsotope *)m_sfacGroup1->m_isotopeTypeList[i])->label()), (const char *)(((CIsotope *)m_sfacGroup2->m_isotopeTypeList[j])->label())); mprintf(" Writing RDF to %s...\n", (const char *)filename); df->Write("", filename, "", false); } double shift = ((double)m_sfacGroup1->m_isotopeTypeCount[i]) * ((double)m_sfacGroup2->m_isotopeTypeCount[j]) / (((double)m_sfacGroup1->m_isotopeTypeTotalCount[i]) * ((double)m_sfacGroup2->m_isotopeTypeTotalCount[j])); if ((CIsotope *)m_sfacGroup1->m_isotopeTypeList[i] == (CIsotope *)m_sfacGroup2->m_isotopeTypeList[j]) shift *= 2.0; for (k = 0; k < sfacTemp->m_iResolution; k++) { double q = (sfacTemp->m_fMinVal + (0.5 + k) / sfacTemp->m_fFac) / 1000.0; double f = 0; for (l = 0; l < df->m_iResolution; l++) { double r = (0.5 + l) / df->m_fFac; f += r * (df->m_pBin[l] - shift) / q * sin(r * q); } sfacTemp->m_pBin[k] = f / df->m_fFac; } for (k = 0; k < sfacTemp->m_iResolution; k++) { double q = (sfacTemp->m_fMinVal + (0.5 + k) / sfacTemp->m_fFac) / 1000.0; double f = (CIsotope *)m_sfacGroup1->m_isotopeTypeList[i] == (CIsotope *)m_sfacGroup2->m_isotopeTypeList[j] ? 1.0 : 2.0; sfac->m_pBin[k] += sfacTemp->m_pBin[k] * f * ((double)m_sfacGroup1->m_isotopeTypeTotalCount[i]) * ((double)m_sfacGroup2->m_isotopeTypeTotalCount[j]) / ((double)g_iGesAtomCount) / ((double)g_iGesAtomCount); neutron->m_pBin[k] += sfacTemp->m_pBin[k] * f * ((double)m_sfacGroup1->m_isotopeTypeTotalCount[i]) * ((double)m_sfacGroup2->m_isotopeTypeTotalCount[j]) / ((double)g_iGesAtomCount) / ((double)g_iGesAtomCount) * ((CIsotope *)m_sfacGroup1->m_isotopeTypeList[i])->neutronFactor() * ((CIsotope *)m_sfacGroup2->m_isotopeTypeList[j])->neutronFactor(); xray->m_pBin[k] += sfacTemp->m_pBin[k] * f * ((double)m_sfacGroup1->m_isotopeTypeTotalCount[i]) * ((double)m_sfacGroup2->m_isotopeTypeTotalCount[j]) / ((double)g_iGesAtomCount) / ((double)g_iGesAtomCount) * ((CIsotope *)m_sfacGroup1->m_isotopeTypeList[i])->xrayFactor(q) * ((CIsotope *)m_sfacGroup2->m_isotopeTypeList[j])->xrayFactor(q); } if (saveIntermediate) { if (g_bBoxNonOrtho) sfacTemp->MultiplyBin(4.0 * Pi * g_iGesAtomCount / g_fBoxVolume / 1000000.0); else sfacTemp->MultiplyBin(4.0 * Pi * g_iGesAtomCount / (g_fBoxX * g_fBoxY * g_fBoxZ)); filename.sprintf("sfac_cross_%s_sfac_%s_%s.csv", (const char *)m_name, (const char *)((CIsotope *)m_sfacGroup1->m_isotopeTypeList[i])->label(), (const char *)((CIsotope *)m_sfacGroup2->m_isotopeTypeList[j])->label()); mprintf(" Writing Structure Factor to %s...\n", (const char *)filename); sfacTemp->Write("", filename, "", false); } sfacTemp->ZeroBin(); } } delete sfacTemp; } void CStructureFactorCross::finalizeIntra(CDF *sfac, CDF *xray, CDF *neutron, bool saveIntermediate) { int i, j, k, l; CxString filename; CDF *sfacTemp; try { sfacTemp = new CDF(); } catch(...) { sfacTemp = NULL; } if(sfacTemp == NULL) NewException((double)sizeof(CDF), __FILE__, __LINE__, __PRETTY_FUNCTION__); sfacTemp->m_fMinVal = sfac->m_fMinVal; sfacTemp->m_fMaxVal = sfac->m_fMaxVal; sfacTemp->m_iResolution = sfac->m_iResolution; sfacTemp->SetLabelX("Wave vector modulus / nm^-1"); sfacTemp->SetLabelY("Intensity"); sfacTemp->Create(); for (i = 0; i < m_sfacGroup1->m_isotopeTypeList.GetSize(); i++) { for (j = 0; j < m_sfacGroup2->m_isotopeTypeList.GetSize(); j++) { mprintf(" Processing intramolecular partial structure factor %s-%s\n", ((CIsotope *)m_sfacGroup1->m_isotopeTypeList[i])->label(), ((CIsotope *)m_sfacGroup2->m_isotopeTypeList[j])->label()); CDF *df = (CDF *)m_rdfIntraList[i * m_sfacGroup2->m_isotopeTypeList.GetSize() + j]; df->MultiplyBin(1.0 / g_iSteps * g_iStride); if ((CIsotope *)m_sfacGroup1->m_isotopeTypeList[i] == (CIsotope *)m_sfacGroup2->m_isotopeTypeList[j]) df->MultiplyBin(2.0); df->CorrectRadialDist(); if (g_bBoxNonOrtho) df->MultiplyBin(g_fBoxVolume * 1000000.0 / (4.0/3.0 * Pi) / ((double)m_sfacGroup1->m_isotopeTypeTotalCount[i]) / ((double)m_sfacGroup2->m_isotopeTypeTotalCount[j])); else df->MultiplyBin(g_fBoxX * g_fBoxY * g_fBoxZ / (4.0/3.0 * Pi) / ((double)m_sfacGroup1->m_isotopeTypeTotalCount[i]) / ((double)m_sfacGroup2->m_isotopeTypeTotalCount[j])); if (g_bDoubleBox) df->MultiplyBin(g_iDoubleBoxFactor); if (saveIntermediate) { filename.sprintf("sfac_cross_%s_rdf_%s_%s_intra.csv", (const char *)m_name, (const char *)(((CIsotope *)m_sfacGroup1->m_isotopeTypeList[i])->label()), (const char *)(((CIsotope *)m_sfacGroup2->m_isotopeTypeList[j])->label())); mprintf(" Writing RDF to %s...\n", (const char *)filename); df->Write("", filename, "", false); } double shift = 0.0; if ((CIsotope *)m_sfacGroup1->m_isotopeTypeList[i] == (CIsotope *)m_sfacGroup2->m_isotopeTypeList[j]) shift *= 2.0; for (k = 0; k < sfacTemp->m_iResolution; k++) { double q = (sfacTemp->m_fMinVal + (0.5 + k) / sfacTemp->m_fFac) / 1000.0; double f = 0; for (l = 0; l < df->m_iResolution; l++) { double r = (0.5 + l) / df->m_fFac; f += r * (df->m_pBin[l] - shift) / q * sin(r * q); } sfacTemp->m_pBin[k] = f / df->m_fFac; } for (k = 0; k < sfacTemp->m_iResolution; k++) { double q = (sfacTemp->m_fMinVal + (0.5 + k) / sfacTemp->m_fFac) / 1000.0; double f = (CIsotope *)m_sfacGroup1->m_isotopeTypeList[i] == (CIsotope *)m_sfacGroup2->m_isotopeTypeList[j] ? 1.0 : 2.0; sfac->m_pBin[k] += sfacTemp->m_pBin[k] * f * ((double)m_sfacGroup1->m_isotopeTypeTotalCount[i]) * ((double)m_sfacGroup2->m_isotopeTypeTotalCount[j]) / ((double)g_iGesAtomCount) / ((double)g_iGesAtomCount); neutron->m_pBin[k] += sfacTemp->m_pBin[k] * f * ((double)m_sfacGroup1->m_isotopeTypeTotalCount[i]) * ((double)m_sfacGroup2->m_isotopeTypeTotalCount[j]) / ((double)g_iGesAtomCount) / ((double)g_iGesAtomCount) * ((CIsotope *)m_sfacGroup1->m_isotopeTypeList[i])->neutronFactor() * ((CIsotope *)m_sfacGroup2->m_isotopeTypeList[j])->neutronFactor(); xray->m_pBin[k] += sfacTemp->m_pBin[k] * f * ((double)m_sfacGroup1->m_isotopeTypeTotalCount[i]) * ((double)m_sfacGroup2->m_isotopeTypeTotalCount[j]) / ((double)g_iGesAtomCount) / ((double)g_iGesAtomCount) * ((CIsotope *)m_sfacGroup1->m_isotopeTypeList[i])->xrayFactor(q) * ((CIsotope *)m_sfacGroup2->m_isotopeTypeList[j])->xrayFactor(q); } if (saveIntermediate) { if (g_bBoxNonOrtho) sfacTemp->MultiplyBin(4.0 * Pi * g_iGesAtomCount / g_fBoxVolume / 1000000.0); else sfacTemp->MultiplyBin(4.0 * Pi * g_iGesAtomCount / (g_fBoxX * g_fBoxY * g_fBoxZ)); filename.sprintf("sfac_cross_%s_sfac_%s_%s_intra.csv", (const char *)m_name, (const char *)((CIsotope *)m_sfacGroup1->m_isotopeTypeList[i])->label(), (const char *)((CIsotope *)m_sfacGroup2->m_isotopeTypeList[j])->label()); mprintf(" Writing Structure Factor to %s...\n", (const char *)filename); sfacTemp->Write("", filename, "", false); } sfacTemp->ZeroBin(); } } delete sfacTemp; } void CStructureFactorCross::finalizeInter(CDF *sfac, CDF *xray, CDF *neutron, bool saveIntermediate) { int i, j, k, l; CxString filename; CDF *sfacTemp; try { sfacTemp = new CDF(); } catch(...) { sfacTemp = NULL; } if(sfacTemp == NULL) NewException((double)sizeof(CDF), __FILE__, __LINE__, __PRETTY_FUNCTION__); sfacTemp->m_fMinVal = sfac->m_fMinVal; sfacTemp->m_fMaxVal = sfac->m_fMaxVal; sfacTemp->m_iResolution = sfac->m_iResolution; sfacTemp->SetLabelX("Wave vector modulus / nm^-1"); sfacTemp->SetLabelY("Intensity"); sfacTemp->Create(); for (i = 0; i < m_sfacGroup1->m_isotopeTypeList.GetSize(); i++) { for (j = 0; j < m_sfacGroup2->m_isotopeTypeList.GetSize(); j++) { mprintf(" Processing intermolecular partial structure factor %s-%s\n", ((CIsotope *)m_sfacGroup1->m_isotopeTypeList[i])->label(), ((CIsotope *)m_sfacGroup2->m_isotopeTypeList[j])->label()); CDF *df = (CDF *)m_rdfInterList[i * m_sfacGroup2->m_isotopeTypeList.GetSize() + j]; df->MultiplyBin(1.0 / g_iSteps * g_iStride); if ((CIsotope *)m_sfacGroup1->m_isotopeTypeList[i] == (CIsotope *)m_sfacGroup2->m_isotopeTypeList[j]) df->MultiplyBin(2.0); df->CorrectRadialDist(); if (g_bBoxNonOrtho) df->MultiplyBin(g_fBoxVolume * 1000000.0 / (4.0/3.0 * Pi) / ((double)m_sfacGroup1->m_isotopeTypeTotalCount[i]) / ((double)m_sfacGroup2->m_isotopeTypeTotalCount[j])); else df->MultiplyBin(g_fBoxX * g_fBoxY * g_fBoxZ / (4.0/3.0 * Pi) / ((double)m_sfacGroup1->m_isotopeTypeTotalCount[i]) / ((double)m_sfacGroup2->m_isotopeTypeTotalCount[j])); if (g_bDoubleBox) df->MultiplyBin(g_iDoubleBoxFactor); if (saveIntermediate) { filename.sprintf("sfac_cross_%s_rdf_%s_%s_inter.csv", (const char *)m_name, (const char *)(((CIsotope *)m_sfacGroup1->m_isotopeTypeList[i])->label()), (const char *)(((CIsotope *)m_sfacGroup2->m_isotopeTypeList[j])->label())); mprintf(" Writing RDF to %s...\n", (const char *)filename); df->Write("", filename, "", false); } double shift = ((double)m_sfacGroup1->m_isotopeTypeCount[i]) * ((double)m_sfacGroup2->m_isotopeTypeCount[j]) / (((double)m_sfacGroup1->m_isotopeTypeTotalCount[i]) * ((double)m_sfacGroup2->m_isotopeTypeTotalCount[j])); if ((CIsotope *)m_sfacGroup1->m_isotopeTypeList[i] == (CIsotope *)m_sfacGroup2->m_isotopeTypeList[j]) shift *= 2.0; for (k = 0; k < sfacTemp->m_iResolution; k++) { double q = (sfacTemp->m_fMinVal + (0.5 + k) / sfacTemp->m_fFac) / 1000.0; double f = 0; for (l = 0; l < df->m_iResolution; l++) { double r = (0.5 + l) / df->m_fFac; f += r * (df->m_pBin[l] - shift) / q * sin(r * q); } sfacTemp->m_pBin[k] = f / df->m_fFac; } for (k = 0; k < sfacTemp->m_iResolution; k++) { double q = (sfacTemp->m_fMinVal + (0.5 + k) / sfacTemp->m_fFac) / 1000.0; double f = (CIsotope *)m_sfacGroup1->m_isotopeTypeList[i] == (CIsotope *)m_sfacGroup2->m_isotopeTypeList[j] ? 1.0 : 2.0; sfac->m_pBin[k] += sfacTemp->m_pBin[k] * f * ((double)m_sfacGroup1->m_isotopeTypeTotalCount[i]) * ((double)m_sfacGroup2->m_isotopeTypeTotalCount[j]) / ((double)g_iGesAtomCount) / ((double)g_iGesAtomCount); neutron->m_pBin[k] += sfacTemp->m_pBin[k] * f * ((double)m_sfacGroup1->m_isotopeTypeTotalCount[i]) * ((double)m_sfacGroup2->m_isotopeTypeTotalCount[j]) / ((double)g_iGesAtomCount) / ((double)g_iGesAtomCount) * ((CIsotope *)m_sfacGroup1->m_isotopeTypeList[i])->neutronFactor() * ((CIsotope *)m_sfacGroup2->m_isotopeTypeList[j])->neutronFactor(); xray->m_pBin[k] += sfacTemp->m_pBin[k] * f * ((double)m_sfacGroup1->m_isotopeTypeTotalCount[i]) * ((double)m_sfacGroup2->m_isotopeTypeTotalCount[j]) / ((double)g_iGesAtomCount) / ((double)g_iGesAtomCount) * ((CIsotope *)m_sfacGroup1->m_isotopeTypeList[i])->xrayFactor(q) * ((CIsotope *)m_sfacGroup2->m_isotopeTypeList[j])->xrayFactor(q); } if (saveIntermediate) { if (g_bBoxNonOrtho) sfacTemp->MultiplyBin(4.0 * Pi * g_iGesAtomCount / g_fBoxVolume / 1000000.0); else sfacTemp->MultiplyBin(4.0 * Pi * g_iGesAtomCount / (g_fBoxX * g_fBoxY * g_fBoxZ)); filename.sprintf("sfac_cross_%s_sfac_%s_%s_inter.csv", (const char *)m_name, (const char *)((CIsotope *)m_sfacGroup1->m_isotopeTypeList[i])->label(), (const char *)((CIsotope *)m_sfacGroup2->m_isotopeTypeList[j])->label()); mprintf(" Writing Structure Factor to %s...\n", (const char *)filename); sfacTemp->Write("", filename, "", false); } sfacTemp->ZeroBin(); } } delete sfacTemp; } CStructureFactor::CStructureFactor() { int i, j, k; CxString buf, buf2, temp; CxObArray isotopeAssignList; for (i = 0; i < g_oaMolecules.GetSize(); i++) { CMolecule *mol = (CMolecule *)g_oaMolecules[i]; StructureFactorMolecule *smol; try { smol = new StructureFactorMolecule; } catch(...) { smol = NULL; } if (smol == NULL) NewException((double)sizeof(StructureFactorMolecule), __FILE__, __LINE__, __PRETTY_FUNCTION__); smol->moleculeType = i; for (j = 0; j < mol->m_baAtomIndex.GetSize(); j++) { if (mol->m_baAtomIndex[j] == g_iVirtAtomType) continue; StructureFactorAtomKind *satom; try { satom = new StructureFactorAtomKind; } catch(...) { satom = NULL; } if (satom == NULL) NewException((double)sizeof(StructureFactorAtomKind), __FILE__, __LINE__, __PRETTY_FUNCTION__); satom->atomType = mol->m_baAtomIndex[j]; CIsotope *isotope = NULL; for (k = 0; k < g_isotopes.GetSize(); k++) { if (mystricmp(((CAtom *)g_oaAtoms[mol->m_baAtomIndex[j]])->m_sName, ((CIsotope *)g_isotopes[k])->label()) == 0) { isotope = (CIsotope *)g_isotopes[k]; break; } } if (isotope == NULL) { mprintf(RED, "Warning: no isotope data for \"%s\" found. Setting all scattering factors to 0.\n", (const char*)((CAtom *)g_oaAtoms[mol->m_baAtomIndex[j]])->m_sName); try { isotope = new CIsotope(((CAtom *)g_oaAtoms[mol->m_baAtomIndex[j]])->m_sName, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0); } catch(...) { isotope = NULL; } if (isotope == NULL) NewException((double)sizeof(CIsotope), __FILE__, __LINE__, __PRETTY_FUNCTION__); g_isotopes.Add(isotope); } for (k = 0; k < mol->m_waAtomCount[j]; k++) { satom->isotopeList.Add(isotope); } smol->atomKinds.Add(satom); } isotopeAssignList.Add(smol); } if (g_bAdvanced2) { if (!AskYesNo(" Use standard atom data (y) or specify isotopes (n)? [yes] ", true)) { while (true) { buf.sprintf("\n Change isotopes in which molecule ("); for(i = 0; i < g_oaMolecules.GetSize(); i++) { buf2.sprintf("%s=%d", ((CMolecule *)g_oaMolecules[i])->m_sName, i+1); buf.strcat(buf2); if(i < g_oaMolecules.GetSize() - 1) buf.strcat(", "); } buf.strcat(")? "); int mol = AskRangeInteger_ND("%s", 1, g_oaMolecules.GetSize(),(const char*)buf) - 1; CMolecule *m = (CMolecule *)g_oaMolecules[mol]; while (true) { mprintf("\n The following isotopes are set up:\n"); for (i = 0; i < m->m_baAtomIndex.GetSize(); i++) { if (m->m_baAtomIndex[i] == g_iVirtAtomType) continue; for (j = 0; j < m->m_waAtomCount[i]; j++) { mprintf(" %s%d: %-4s", (const char*)((CAtom *)g_oaAtoms[m->m_baAtomIndex[i]])->m_sName, j+1, ((CIsotope *)((StructureFactorAtomKind *)((StructureFactorMolecule *)isotopeAssignList[mol])->atomKinds[i])->isotopeList[j])->label()); } } mprintf("\n\n"); int ca, cb, cc; ca = 0; cc = 0; do { AskString(" Change isotope for which atom? [done] ", &buf, ""); if (buf.GetLength() == 0) break; } while (!ParseAtom(buf, mol, ca, cb, cc)); if (buf.GetLength() == 0) break; while (true) { AskString_ND(" Which isotope to set for %s (e.g. \"13C\")? ", &buf2, (const char *)buf); int isotopeIndex = -1; for (i = 0; i < g_isotopes.GetSize(); i++) { if(mystricmp(((CIsotope *)g_isotopes[i])->label(), buf2) == 0) { isotopeIndex = i; break; } } if (isotopeIndex != -1) { ((StructureFactorAtomKind *)((StructureFactorMolecule *)isotopeAssignList[mol])->atomKinds[ca])->isotopeList[cc] = (CIsotope *)g_isotopes[isotopeIndex]; break; } mprintf("\n No isotope data for \"%s\" found.\n", (const char *)buf2); if (AskYesNo(" Enter data for \"%s\" (y/n)? [yes] ", true, (const char *)buf2)) { double nf = AskFloat_ND(" Enter neutron scattering factor: "); double cma1 = AskFloat_ND(" Enter Cromer-Mann coefficient a1: "); double cma2 = AskFloat_ND(" Enter Cromer-Mann coefficient a2: "); double cma3 = AskFloat_ND(" Enter Cromer-Mann coefficient a3: "); double cma4 = AskFloat_ND(" Enter Cromer-Mann coefficient a4: "); double cmb1 = AskFloat_ND(" Enter Cromer-Mann coefficient b1: "); double cmb2 = AskFloat_ND(" Enter Cromer-Mann coefficient b2: "); double cmb3 = AskFloat_ND(" Enter Cromer-Mann coefficient b3: "); double cmb4 = AskFloat_ND(" Enter Cromer-Mann coefficient b4: "); double cmc = AskFloat_ND(" Enter Cromer-Mann coefficient c: "); CIsotope *isotope; try { isotope = new CIsotope(buf2, nf, cma1, cma2, cma3, cma4, cmb1, cmb2, cmb3, cmb4, cmc); } catch(...) { isotope = NULL; } if (isotope == NULL) NewException((double)sizeof(CIsotope), __FILE__, __LINE__, __PRETTY_FUNCTION__); g_isotopes.Add(isotope); ((StructureFactorAtomKind *)((StructureFactorMolecule *)isotopeAssignList[mol])->atomKinds[ca])->isotopeList[cc] = isotope; break; } else { mprintf("\n"); } } } if (!AskYesNo("\n Change isotopes in another molecule (y/n)? [no] ", false)) break; } mprintf("\n"); } else { mprintf("\n"); } if (AskYesNo(" Change the predefined scattering factors (y/n)? [no] ", false)) { CxObArray isotopeTypeList; for (i = 0; i < isotopeAssignList.GetSize(); i++) { StructureFactorMolecule *smol = (StructureFactorMolecule *)isotopeAssignList[i]; for (j = 0; j < smol->atomKinds.GetSize(); j++) { StructureFactorAtomKind *satom = (StructureFactorAtomKind *)smol->atomKinds[j]; for (k = 0; k < satom->isotopeList.GetSize(); k++) { CIsotope *isotope = (CIsotope *)satom->isotopeList[k]; bool found = false; int l; for (l = 0; l < isotopeTypeList.GetSize(); l++) { if ((CIsotope *)isotopeTypeList[l] == isotope) { found = true; break; } } if (!found) { isotopeTypeList.Add(isotope); } } } } while (true) { mprintf("\n The following scattering factors are set up:\n\n"); mprintf(" Name neutron a1 a2 a3 a4 b1 b2 b3 b4 c\n"); for (i = 0; i < isotopeTypeList.GetSize(); i++) { CIsotope *isotope = (CIsotope *)isotopeTypeList[i]; mprintf(" %-6s %8.3f %8.3f %8.3f %8.3f %8.3f %8.3f %8.3f %8.3f %8.3f %8.3f\n", isotope->_label, isotope->_neutronFactor, isotope->_cma[0], isotope->_cma[1], isotope->_cma[2], isotope->_cma[3], isotope->_cmb[0], isotope->_cmb[1], isotope->_cmb[2], isotope->_cmb[3], isotope->_cmc); } mprintf("\n"); CIsotope *isotope = NULL; while (true) { AskString(" Change scattering factors of which isotope? [done] ", &buf, ""); if (buf.GetLength() == 0) break; for (i = 0; i < isotopeTypeList.GetSize(); i++) { if (mystricmp(((CIsotope *)isotopeTypeList[i])->label(), buf) == 0) { isotope = (CIsotope *)isotopeTypeList[i]; break; } } if (isotope != NULL) break; eprintf("The system does not contain isotope \"%s\".\n", (const char *)buf); } if (buf.GetLength() == 0) break; isotope->_neutronFactor = AskFloat_ND(" Enter neutron scattering factor: "); isotope->_cma[0] = AskFloat_ND(" Enter Cromer-Mann coefficient a1: "); isotope->_cma[1] = AskFloat_ND(" Enter Cromer-Mann coefficient a2: "); isotope->_cma[2] = AskFloat_ND(" Enter Cromer-Mann coefficient a3: "); isotope->_cma[3] = AskFloat_ND(" Enter Cromer-Mann coefficient a4: "); isotope->_cmb[0] = AskFloat_ND(" Enter Cromer-Mann coefficient b1: "); isotope->_cmb[1] = AskFloat_ND(" Enter Cromer-Mann coefficient b2: "); isotope->_cmb[2] = AskFloat_ND(" Enter Cromer-Mann coefficient b3: "); isotope->_cmb[3] = AskFloat_ND(" Enter Cromer-Mann coefficient b4: "); isotope->_cmc = AskFloat_ND(" Enter Cromer-Mann coefficient c: "); } mprintf("\n"); } else { mprintf("\n"); } } try { m_globalSFac = new CStructureFactorGroup(true, isotopeAssignList); } catch(...) { m_globalSFac = NULL; } if (m_globalSFac == NULL) NewException((double)sizeof(CStructureFactorGroup), __FILE__, __LINE__, __PRETTY_FUNCTION__); if (AskYesNo(" Compute structure factor of specific atom groups (y/n)? [no] ", false)) { while (true) { mprintf(WHITE, "\n > Group %d >\n\n", m_sFacGroups.GetSize() + 1); CStructureFactorGroup *sfac; try { sfac = new CStructureFactorGroup(false, isotopeAssignList); } catch(...) { sfac = NULL; } if (sfac == NULL) NewException((double)sizeof(CStructureFactorGroup), __FILE__, __LINE__, __PRETTY_FUNCTION__); m_sFacGroups.Add(sfac); mprintf(WHITE, " < End of Group %d <\n\n", m_sFacGroups.GetSize()); if (!AskYesNo(" Add another group (y/n)? [no] ", false)) break; } } mprintf("\n"); if (m_sFacGroups.GetSize() > 1) { if (AskYesNo(" Compute all cross terms of the defined atom groups (y) or select certain combinations (n)? [yes] ", true)) { mprintf("\n"); int count = 0; for (i = 0; i < m_sFacGroups.GetSize(); i++) { for (j = i + 1; j < m_sFacGroups.GetSize(); j++) { CStructureFactorCross *sfac; try { sfac = new CStructureFactorCross((CStructureFactorGroup *)m_sFacGroups[i], (CStructureFactorGroup *)m_sFacGroups[j]); } catch(...) { sfac = NULL; } if (sfac == NULL) NewException((double)sizeof(CStructureFactorGroup), __FILE__, __LINE__, __PRETTY_FUNCTION__); m_sFacCrosses.Add(sfac); mprintf(" Cross term %d: Group %d - Group %d\n", ++count, i + 1, j + 1); } } } else { mprintf(" The following groups are defined:\n\n"); for (i = 0; i < m_sFacGroups.GetSize(); i++) { mprintf(" %3d - %s\n", i + 1, (const char *)((CStructureFactorGroup *)m_sFacGroups[i])->getName()); } mprintf("\n Enter each combination as a comma-separated pair of numbers (e.g. 1,1)\n\n"); CxWordArray wa; while (true) { wa.RemoveAll_KeepSize(); AskString(" Enter combination (return=finished): ", &buf, ""); if (buf.GetLength() == 0) break; ParseIntList(buf, &wa); if (wa.GetSize() != 2) { eprintf("Invalid input. Please enter exactly two numbers separated by a comma.\n"); continue; } if ((wa[0] < 1) || (wa[1] < 1)) { eprintf("Invalid input. Please enter positive numbers.\n"); continue; } if ((wa[0] > m_sFacGroups.GetSize()) || (wa[1] > m_sFacGroups.GetSize())) { eprintf("Invalid input. There are only %d groups.\n", m_sFacGroups.GetSize()); continue; } if (wa[0] == wa[1]) { eprintf("Invalid input. Please enter two different numbers.\n"); continue; } CStructureFactorCross *sfac; try { sfac = new CStructureFactorCross((CStructureFactorGroup *)m_sFacGroups[wa[0] - 1], (CStructureFactorGroup *)m_sFacGroups[wa[1] - 1]); } catch(...) { sfac = NULL; } if (sfac == NULL) NewException((double)sizeof(CStructureFactorGroup), __FILE__, __LINE__, __PRETTY_FUNCTION__); m_sFacCrosses.Add(sfac); } } mprintf("\n"); } if (m_sFacCrosses.GetSize() > 0) { if (AskYesNo(" Separate intramolecular and intermolecular contributions in the cross terms (y/n)? [no] ", false)) { for (i = 0; i < m_sFacCrosses.GetSize(); i++) { ((CStructureFactorCross *)m_sFacCrosses[i])->setSepInterIntra(true); } } mprintf("\n"); } m_rdfMax = AskFloat(" Enter maximum RDF distance to observe (pm): [%d] ", (double)HalfBox(), HalfBox()); m_rdfRes = AskUnsignedInteger(" Enter RDF binning resolution: [%d] ", 2 * HalfBox(), 2 * HalfBox()); m_sfacMax = AskFloat(" Enter maximum wave vector modulus (nm^-1): [100] ", 100.0); m_sfacRes = AskUnsignedInteger(" Enter Structure Factor resolution: [1000] ", 1000); mprintf("\n The following normalization factors are available:\n"); mprintf(" (1) [Sum_i x_i*f_i(q)]^2\n"); mprintf(" (2) Sum_i x_i*[f_i(q)]^2\n"); mprintf(" (3) 1 (no normalization)\n\n"); m_normalization = AskRangeInteger(" Which factor to use? [1] ", 1, 3, 1); mprintf("\n"); if (g_bAdvanced2) { m_saveIntermediate = AskYesNo(" Save all intermediate data (y/n)? [no] ", false); mprintf("\n"); } else { m_saveIntermediate = false; } if (g_bAdvanced2) { m_sharpening = AskYesNo(" Apply sharpening factor (y/n)? [no] ", false); if (m_sharpening) { while (true) { AskString_ND(" Which isotope to use as sharpening atom (e.g. \"N\" or \"14N\")? ", &buf); int isotopeIndex = -1; for (i = 0; i < g_isotopes.GetSize(); i++) { if(mystricmp(((CIsotope *)g_isotopes[i])->label(), buf) == 0) { isotopeIndex = i; break; } } if(isotopeIndex != -1) { m_sharpeningIsotope = (CIsotope *)g_isotopes[isotopeIndex]; break; } eprintf("Isotope data for \"%s\" not found.\n", (const char *)buf); } } else { m_sharpeningIsotope = NULL; } mprintf("\n"); } else { m_sharpening = false; m_sharpeningIsotope = NULL; } } CStructureFactor::~CStructureFactor() { int i; delete m_globalSFac; for (i = 0; i < m_sFacGroups.GetSize(); i++) delete (CStructureFactorGroup *)m_sFacGroups[i]; for (i = 0; i < m_sFacCrosses.GetSize(); i++) delete (CStructureFactorCross *)m_sFacCrosses[i]; } void CStructureFactor::initialize() { int i; mprintf(" Initializing structure factor\n"); mprintf(WHITE, "\n > Total >\n\n"); m_globalSFac->initialize(m_rdfMax, m_rdfRes); mprintf(WHITE, "\n < End of Total <\n"); for (i = 0; i < m_sFacGroups.GetSize(); i++) { mprintf(WHITE, "\n > Group %d >\n\n", i + 1); ((CStructureFactorGroup *)m_sFacGroups[i])->initialize(m_rdfMax, m_rdfRes); mprintf(WHITE, "\n < End of Group %d <\n", i + 1); } for (i = 0; i < m_sFacCrosses.GetSize(); i++) { mprintf(WHITE, "\n > Cross Term %d >\n\n", i + 1); ((CStructureFactorCross *)m_sFacCrosses[i])->initialize(m_rdfMax, m_rdfRes); mprintf(WHITE, "\n < End of Cross Term %d <\n", i + 1); } } void CStructureFactor::process(CTimeStep *ts) { int i; m_globalSFac->process(ts); for (i = 0; i < m_sFacGroups.GetSize(); i++) { ((CStructureFactorGroup *)m_sFacGroups[i])->process(ts); } for (i = 0; i < m_sFacCrosses.GetSize(); i++) { ((CStructureFactorCross *)m_sFacCrosses[i])->process(ts); } } void CStructureFactor::finalize() { int i; CxString filename; CDF *sfac, *xray, *neutron; try { sfac = new CDF(); } catch(...) { sfac = NULL; } if (sfac == NULL) NewException((double)sizeof(CDF), __FILE__, __LINE__, __PRETTY_FUNCTION__); sfac->m_fMinVal = 2.0 * Pi / m_rdfMax * 1000.0; sfac->m_fMaxVal = m_sfacMax; sfac->m_iResolution = m_sfacRes; sfac->SetLabelX("Wave vector modulus / nm^-1"); sfac->SetLabelY("Intensity"); sfac->Create(); try { xray = new CDF(); } catch(...) { xray = NULL; } if (xray == NULL) NewException((double)sizeof(CDF), __FILE__, __LINE__, __PRETTY_FUNCTION__); xray->m_fMinVal = 2.0 * Pi / m_rdfMax * 1000.0; xray->m_fMaxVal = m_sfacMax; xray->m_iResolution = m_sfacRes; xray->SetLabelX("Wave vector modulus / nm^-1"); xray->SetLabelY("Intensity"); xray->Create(); try { neutron = new CDF(); } catch(...) { neutron = NULL; } if (neutron == NULL) NewException((double)sizeof(CDF), __FILE__, __LINE__, __PRETTY_FUNCTION__); neutron->m_fMinVal = 2.0 * Pi / m_rdfMax * 1000.0; neutron->m_fMaxVal = m_sfacMax; neutron->m_iResolution = m_sfacRes; neutron->SetLabelX("Wave vector modulus / nm^-1"); neutron->SetLabelY("Intensity"); neutron->Create(); mprintf(" Finalizing structure factor\n"); mprintf(WHITE, "\n > Total >\n\n"); m_globalSFac->finalize(sfac, xray, neutron, m_saveIntermediate); if (g_bBoxNonOrtho) { double f = 4.0 * Pi * g_iGesAtomCount / (g_fBoxVolume * 1000000.0); sfac->MultiplyBin(f); xray->MultiplyBin(f); neutron->MultiplyBin(f); } else { double f = 4.0 * Pi * g_iGesAtomCount / (g_fBoxX * g_fBoxY * g_fBoxZ); sfac->MultiplyBin(f); xray->MultiplyBin(f); neutron->MultiplyBin(f); } if (m_normalization == 1) { double sf = 0.0; for (i = 0; i < m_globalSFac->getIsotopeTypeList().GetSize(); i++) { sf += ((double)m_globalSFac->getIsotopeTypeTotalCount().GetAt(i)) / ((double)g_iGesAtomCount); } sfac->MultiplyBin(1.0 / (sf * sf)); for (i = 0; i < xray->m_iResolution; i++) { double q = (xray->m_fMinVal + (0.5 + i) / xray->m_fFac) / 1000.0; double xf = 0.0; int j; for (j = 0; j < m_globalSFac->getIsotopeTypeList().GetSize(); j++) { xf += ((double)m_globalSFac->getIsotopeTypeTotalCount().GetAt(j)) / ((double)g_iGesAtomCount) * ((CIsotope *)m_globalSFac->getIsotopeTypeList().GetAt(j))->xrayFactor(q); } xray->m_pBin[i] /= xf * xf; } double nf = 0.0; for (i = 0; i < m_globalSFac->getIsotopeTypeList().GetSize(); i++) { nf += ((double)m_globalSFac->getIsotopeTypeTotalCount().GetAt(i)) / ((double)g_iGesAtomCount) * ((CIsotope *)m_globalSFac->getIsotopeTypeList().GetAt(i))->neutronFactor(); } neutron->MultiplyBin(1.0 / (nf * nf)); } else if (m_normalization == 2) { double sf = 0.0; for (i = 0; i < m_globalSFac->getIsotopeTypeList().GetSize(); i++) { sf += ((double)m_globalSFac->getIsotopeTypeTotalCount().GetAt(i)) / ((double)g_iGesAtomCount); } sfac->MultiplyBin(1.0 / sf); for (i = 0; i < xray->m_iResolution; i++) { double q = (xray->m_fMinVal + (0.5 + i) / xray->m_fFac) / 1000.0; double xf = 0.0; int j; for (j = 0; j < m_globalSFac->getIsotopeTypeList().GetSize(); j++) { xf += ((double)m_globalSFac->getIsotopeTypeTotalCount().GetAt(j)) / ((double)g_iGesAtomCount) * ((CIsotope *)m_globalSFac->getIsotopeTypeList().GetAt(j))->xrayFactor(q) * ((CIsotope *)m_globalSFac->getIsotopeTypeList().GetAt(j))->xrayFactor(q); } xray->m_pBin[i] /= xf; } double nf = 0.0; for (i = 0; i < m_globalSFac->getIsotopeTypeList().GetSize(); i++) { nf += ((double)m_globalSFac->getIsotopeTypeTotalCount().GetAt(i)) / ((double)g_iGesAtomCount) * ((CIsotope *)m_globalSFac->getIsotopeTypeList().GetAt(i))->neutronFactor() * ((CIsotope *)m_globalSFac->getIsotopeTypeList().GetAt(i))->neutronFactor(); } neutron->MultiplyBin(1.0 / nf); } else if (m_normalization != 3) { eprintf("CStructureFactor::finalize(): Internal error. Unknown normalization factor.\n"); abort(); } mprintf("\n"); filename.sprintf("sfac_total_unweighted.csv"); mprintf(" Writing unweighted structure factor to %s...\n", (const char *)filename); sfac->Write("", filename, "", false); filename.sprintf("sfac_total_xray.csv"); mprintf(" Writing X-ray scattering function to %s...\n", (const char *)filename); xray->Write("", filename, "", false); filename.sprintf("sfac_total_neutron.csv"); mprintf(" Writing neutron scattering function to %s...\n", (const char *)filename); neutron->Write("", filename, "", false); if (m_sharpening) { for (i = 0; i < xray->m_iResolution; i++) { double q = (xray->m_fMinVal + (0.5 + i) / xray->m_fFac) / 1000.0; double nf = q * exp(-0.01 * q * q); double xf = q * exp(-0.01 * q * q) * m_sharpeningIsotope->xrayFactor(0.0) * m_sharpeningIsotope->xrayFactor(0.0) / m_sharpeningIsotope->xrayFactor(q) / m_sharpeningIsotope->xrayFactor(q); neutron->m_pBin[i] *= nf; xray->m_pBin[i] *= xf; } filename.sprintf("sfac_total_neutron_sharpened.csv"); mprintf(" Writing sharpened neutron scattering function to %s...\n", (const char *)filename); neutron->Write("", filename, "", false); filename.sprintf("sfac_total_xray_sharpened.csv"); mprintf(" Writing sharpened X-ray scattering function to %s...\n", (const char *)filename); xray->Write("", filename, "", false); } mprintf(WHITE, "\n < End of Total <\n"); for (i = 0; i < m_sFacGroups.GetSize(); i++) { mprintf(WHITE, "\n > Group %d >\n\n", i + 1); sfac->ZeroBin(); xray->ZeroBin(); neutron->ZeroBin(); ((CStructureFactorGroup *)m_sFacGroups[i])->finalize(sfac, xray, neutron, m_saveIntermediate); if (g_bBoxNonOrtho) { double f = 4.0 * Pi * g_iGesAtomCount / (g_fBoxVolume * 1000000.0); sfac->MultiplyBin(f); xray->MultiplyBin(f); neutron->MultiplyBin(f); } else { double f = 4.0 * Pi * g_iGesAtomCount / (g_fBoxX * g_fBoxY * g_fBoxZ); sfac->MultiplyBin(f); xray->MultiplyBin(f); neutron->MultiplyBin(f); } if (m_normalization == 1) { double sf = 0.0; int j; for (j = 0; j < m_globalSFac->getIsotopeTypeList().GetSize(); j++) { sf += ((double)m_globalSFac->getIsotopeTypeTotalCount().GetAt(j)) / ((double)g_iGesAtomCount); } sfac->MultiplyBin(1.0 / (sf * sf)); for (j = 0; j < xray->m_iResolution; j++) { double q = (xray->m_fMinVal + (0.5 + j) / xray->m_fFac) / 1000.0; double xf = 0.0; int k; for (k = 0; k < m_globalSFac->getIsotopeTypeList().GetSize(); k++) { xf += ((double)m_globalSFac->getIsotopeTypeTotalCount().GetAt(k)) / ((double)g_iGesAtomCount) * ((CIsotope *)m_globalSFac->getIsotopeTypeList().GetAt(k))->xrayFactor(q); } xray->m_pBin[j] /= xf * xf; } double nf = 0.0; for (j = 0; j < m_globalSFac->getIsotopeTypeList().GetSize(); j++) { nf += ((double)m_globalSFac->getIsotopeTypeTotalCount().GetAt(j)) / ((double)g_iGesAtomCount) * ((CIsotope *)m_globalSFac->getIsotopeTypeList().GetAt(j))->neutronFactor(); } neutron->MultiplyBin(1.0 / (nf * nf)); } else if (m_normalization == 2) { double sf = 0.0; int j; for (j = 0; j < m_globalSFac->getIsotopeTypeList().GetSize(); j++) { sf += ((double)m_globalSFac->getIsotopeTypeTotalCount().GetAt(j)) / ((double)g_iGesAtomCount); } sfac->MultiplyBin(1.0 / sf); for (j = 0; j < xray->m_iResolution; j++) { double q = (xray->m_fMinVal + (0.5 + j) / xray->m_fFac) / 1000.0; double xf = 0.0; int k; for (k = 0; k < m_globalSFac->getIsotopeTypeList().GetSize(); k++) { xf += ((double)m_globalSFac->getIsotopeTypeTotalCount().GetAt(k)) / ((double)g_iGesAtomCount) * ((CIsotope *)m_globalSFac->getIsotopeTypeList().GetAt(k))->xrayFactor(q) * ((CIsotope *)m_globalSFac->getIsotopeTypeList().GetAt(k))->xrayFactor(q); } xray->m_pBin[j] /= xf; } double nf = 0.0; for (j = 0; j < m_globalSFac->getIsotopeTypeList().GetSize(); j++) { nf += ((double)m_globalSFac->getIsotopeTypeTotalCount().GetAt(j)) / ((double)g_iGesAtomCount) * ((CIsotope *)m_globalSFac->getIsotopeTypeList().GetAt(j))->neutronFactor() * ((CIsotope *)m_globalSFac->getIsotopeTypeList().GetAt(j))->neutronFactor(); } neutron->MultiplyBin(1.0 / nf); } else if (m_normalization != 3) { eprintf("CStructureFactor::finalize(): Internal error. Unknown normalization factor.\n"); abort(); } mprintf("\n"); filename.sprintf("sfac_self_%s_unweighted.csv", (const char *)((CStructureFactorGroup *)m_sFacGroups[i])->getName()); mprintf(" Writing unweighted structure factor to %s...\n", (const char *)filename); sfac->Write("", filename, "", false); filename.sprintf("sfac_self_%s_xray.csv", (const char *)((CStructureFactorGroup *)m_sFacGroups[i])->getName()); mprintf(" Writing X-ray scattering function to %s...\n", (const char *)filename); xray->Write("", filename, "", false); filename.sprintf("sfac_self_%s_neutron.csv", (const char *)((CStructureFactorGroup *)m_sFacGroups[i])->getName()); mprintf(" Writing neutron scattering function to %s...\n", (const char *)filename); neutron->Write("", filename, "", false); if (m_sharpening) { int j; for (j = 0; j < xray->m_iResolution; j++) { double q = (xray->m_fMinVal + (0.5 + j) / xray->m_fFac) / 1000.0; double nf = q * exp(-0.01 * q * q); double xf = q * exp(-0.01 * q * q) * m_sharpeningIsotope->xrayFactor(0.0) * m_sharpeningIsotope->xrayFactor(0.0) / m_sharpeningIsotope->xrayFactor(q) / m_sharpeningIsotope->xrayFactor(q); neutron->m_pBin[j] *= nf; xray->m_pBin[j] *= xf; } filename.sprintf("sfac_self_%s_neutron_sharpened.csv", (const char *)((CStructureFactorGroup *)m_sFacGroups[i])->getName()); mprintf(" Writing sharpened neutron scattering function to %s...\n", (const char *)filename); neutron->Write("", filename, "", false); filename.sprintf("sfac_self_%s_xray_sharpened.csv", (const char *)((CStructureFactorGroup *)m_sFacGroups[i])->getName()); mprintf(" Writing sharpened X-ray scattering function to %s...\n", (const char *)filename); xray->Write("", filename, "", false); } if (((CStructureFactorGroup *)m_sFacGroups[i])->sepInterIntra()) { sfac->ZeroBin(); xray->ZeroBin(); neutron->ZeroBin(); mprintf("\n"); ((CStructureFactorGroup *)m_sFacGroups[i])->finalizeIntra(sfac, xray, neutron, m_saveIntermediate); if (g_bBoxNonOrtho) { double f = 4.0 * Pi * g_iGesAtomCount / (g_fBoxVolume * 1000000.0); sfac->MultiplyBin(f); xray->MultiplyBin(f); neutron->MultiplyBin(f); } else { double f = 4.0 * Pi * g_iGesAtomCount / (g_fBoxX * g_fBoxY * g_fBoxZ); sfac->MultiplyBin(f); xray->MultiplyBin(f); neutron->MultiplyBin(f); } if (m_normalization == 1) { double sf = 0.0; int j; for (j = 0; j < m_globalSFac->getIsotopeTypeList().GetSize(); j++) { sf += ((double)m_globalSFac->getIsotopeTypeTotalCount().GetAt(j)) / ((double)g_iGesAtomCount); } sfac->MultiplyBin(1.0 / (sf * sf)); for (j = 0; j < xray->m_iResolution; j++) { double q = (xray->m_fMinVal + (0.5 + j) / xray->m_fFac) / 1000.0; double xf = 0.0; int k; for (k = 0; k < m_globalSFac->getIsotopeTypeList().GetSize(); k++) { xf += ((double)m_globalSFac->getIsotopeTypeTotalCount().GetAt(k)) / ((double)g_iGesAtomCount) * ((CIsotope *)m_globalSFac->getIsotopeTypeList().GetAt(k))->xrayFactor(q); } xray->m_pBin[j] /= xf * xf; } double nf = 0.0; for (j = 0; j < m_globalSFac->getIsotopeTypeList().GetSize(); j++) { nf += ((double)m_globalSFac->getIsotopeTypeTotalCount().GetAt(j)) / ((double)g_iGesAtomCount) * ((CIsotope *)m_globalSFac->getIsotopeTypeList().GetAt(j))->neutronFactor(); } neutron->MultiplyBin(1.0 / (nf * nf)); } else if (m_normalization == 2) { double sf = 0.0; int j; for (j = 0; j < m_globalSFac->getIsotopeTypeList().GetSize(); j++) { sf += ((double)m_globalSFac->getIsotopeTypeTotalCount().GetAt(j)) / ((double)g_iGesAtomCount); } sfac->MultiplyBin(1.0 / sf); for (j = 0; j < xray->m_iResolution; j++) { double q = (xray->m_fMinVal + (0.5 + j) / xray->m_fFac) / 1000.0; double xf = 0.0; int k; for (k = 0; k < m_globalSFac->getIsotopeTypeList().GetSize(); k++) { xf += ((double)m_globalSFac->getIsotopeTypeTotalCount().GetAt(k)) / ((double)g_iGesAtomCount) * ((CIsotope *)m_globalSFac->getIsotopeTypeList().GetAt(k))->xrayFactor(q) * ((CIsotope *)m_globalSFac->getIsotopeTypeList().GetAt(k))->xrayFactor(q); } xray->m_pBin[j] /= xf; } double nf = 0.0; for (j = 0; j < m_globalSFac->getIsotopeTypeList().GetSize(); j++) { nf += ((double)m_globalSFac->getIsotopeTypeTotalCount().GetAt(j)) / ((double)g_iGesAtomCount) * ((CIsotope *)m_globalSFac->getIsotopeTypeList().GetAt(j))->neutronFactor() * ((CIsotope *)m_globalSFac->getIsotopeTypeList().GetAt(j))->neutronFactor(); } neutron->MultiplyBin(1.0 / nf); } else if (m_normalization != 3) { eprintf("CStructureFactor::finalize(): Internal error. Unknown normalization factor.\n"); abort(); } mprintf("\n"); filename.sprintf("sfac_self_%s_unweighted_intra.csv", (const char *)((CStructureFactorGroup *)m_sFacGroups[i])->getName()); mprintf(" Writing unweighted intramolecular structure factor to %s...\n", (const char *)filename); sfac->Write("", filename, "", false); filename.sprintf("sfac_self_%s_xray_intra.csv", (const char *)((CStructureFactorGroup *)m_sFacGroups[i])->getName()); mprintf(" Writing intramolecular X-ray scattering function to %s...\n", (const char *)filename); xray->Write("", filename, "", false); filename.sprintf("sfac_self_%s_neutron_intra.csv", (const char *)((CStructureFactorGroup *)m_sFacGroups[i])->getName()); mprintf(" Writing intramolecular neutron scattering function to %s...\n", (const char *)filename); neutron->Write("", filename, "", false); if (m_sharpening) { int j; for (j = 0; j < xray->m_iResolution; j++) { double q = (xray->m_fMinVal + (0.5 + j) / xray->m_fFac) / 1000.0; double nf = q * exp(-0.01 * q * q); double xf = q * exp(-0.01 * q * q) * m_sharpeningIsotope->xrayFactor(0.0) * m_sharpeningIsotope->xrayFactor(0.0) / m_sharpeningIsotope->xrayFactor(q) / m_sharpeningIsotope->xrayFactor(q); neutron->m_pBin[j] *= nf; xray->m_pBin[j] *= xf; } filename.sprintf("sfac_self_%s_neutron_intra_sharpened.csv", (const char *)((CStructureFactorGroup *)m_sFacGroups[i])->getName()); mprintf(" Writing intramolecular sharpened neutron scattering function to %s...\n", (const char *)filename); neutron->Write("", filename, "", false); filename.sprintf("sfac_self_%s_xray_intra_sharpened.csv", (const char *)((CStructureFactorGroup *)m_sFacGroups[i])->getName()); mprintf(" Writing intramolecular sharpened X-ray scattering function to %s...\n", (const char *)filename); xray->Write("", filename, "", false); } sfac->ZeroBin(); xray->ZeroBin(); neutron->ZeroBin(); mprintf("\n"); ((CStructureFactorGroup *)m_sFacGroups[i])->finalizeInter(sfac, xray, neutron, m_saveIntermediate); if (g_bBoxNonOrtho) { double f = 4.0 * Pi * g_iGesAtomCount / (g_fBoxVolume * 1000000.0); sfac->MultiplyBin(f); xray->MultiplyBin(f); neutron->MultiplyBin(f); } else { double f = 4.0 * Pi * g_iGesAtomCount / (g_fBoxX * g_fBoxY * g_fBoxZ); sfac->MultiplyBin(f); xray->MultiplyBin(f); neutron->MultiplyBin(f); } if (m_normalization == 1) { double sf = 0.0; int j; for (j = 0; j < m_globalSFac->getIsotopeTypeList().GetSize(); j++) { sf += ((double)m_globalSFac->getIsotopeTypeTotalCount().GetAt(j)) / ((double)g_iGesAtomCount); } sfac->MultiplyBin(1.0 / (sf * sf)); for (j = 0; j < xray->m_iResolution; j++) { double q = (xray->m_fMinVal + (0.5 + j) / xray->m_fFac) / 1000.0; double xf = 0.0; int k; for (k = 0; k < m_globalSFac->getIsotopeTypeList().GetSize(); k++) { xf += ((double)m_globalSFac->getIsotopeTypeTotalCount().GetAt(k)) / ((double)g_iGesAtomCount) * ((CIsotope *)m_globalSFac->getIsotopeTypeList().GetAt(k))->xrayFactor(q); } xray->m_pBin[j] /= xf * xf; } double nf = 0.0; for (j = 0; j < m_globalSFac->getIsotopeTypeList().GetSize(); j++) { nf += ((double)m_globalSFac->getIsotopeTypeTotalCount().GetAt(j)) / ((double)g_iGesAtomCount) * ((CIsotope *)m_globalSFac->getIsotopeTypeList().GetAt(j))->neutronFactor(); } neutron->MultiplyBin(1.0 / (nf * nf)); } else if (m_normalization == 2) { double sf = 0.0; int j; for (j = 0; j < m_globalSFac->getIsotopeTypeList().GetSize(); j++) { sf += ((double)m_globalSFac->getIsotopeTypeTotalCount().GetAt(j)) / ((double)g_iGesAtomCount); } sfac->MultiplyBin(1.0 / sf); for (j = 0; j < xray->m_iResolution; j++) { double q = (xray->m_fMinVal + (0.5 + j) / xray->m_fFac) / 1000.0; double xf = 0.0; int k; for (k = 0; k < m_globalSFac->getIsotopeTypeList().GetSize(); k++) { xf += ((double)m_globalSFac->getIsotopeTypeTotalCount().GetAt(k)) / ((double)g_iGesAtomCount) * ((CIsotope *)m_globalSFac->getIsotopeTypeList().GetAt(k))->xrayFactor(q) * ((CIsotope *)m_globalSFac->getIsotopeTypeList().GetAt(k))->xrayFactor(q); } xray->m_pBin[j] /= xf; } double nf = 0.0; for (j = 0; j < m_globalSFac->getIsotopeTypeList().GetSize(); j++) { nf += ((double)m_globalSFac->getIsotopeTypeTotalCount().GetAt(j)) / ((double)g_iGesAtomCount) * ((CIsotope *)m_globalSFac->getIsotopeTypeList().GetAt(j))->neutronFactor() * ((CIsotope *)m_globalSFac->getIsotopeTypeList().GetAt(j))->neutronFactor(); } neutron->MultiplyBin(1.0 / nf); } else if (m_normalization != 3) { eprintf("CStructureFactor::finalize(): Internal error. Unknown normalization factor.\n"); abort(); } mprintf("\n"); filename.sprintf("sfac_self_%s_unweighted_inter.csv", (const char *)((CStructureFactorGroup *)m_sFacGroups[i])->getName()); mprintf(" Writing unweighted intermolecular structure factor to %s...\n", (const char *)filename); sfac->Write("", filename, "", false); filename.sprintf("sfac_self_%s_xray_inter.csv", (const char *)((CStructureFactorGroup *)m_sFacGroups[i])->getName()); mprintf(" Writing intermolecular X-ray scattering function to %s...\n", (const char *)filename); xray->Write("", filename, "", false); filename.sprintf("sfac_self_%s_neutron_inter.csv", (const char *)((CStructureFactorGroup *)m_sFacGroups[i])->getName()); mprintf(" Writing intermolecular neutron scattering function to %s...\n", (const char *)filename); neutron->Write("", filename, "", false); if (m_sharpening) { int j; for (j = 0; j < xray->m_iResolution; j++) { double q = (xray->m_fMinVal + (0.5 + j) / xray->m_fFac) / 1000.0; double nf = q * exp(-0.01 * q * q); double xf = q * exp(-0.01 * q * q) * m_sharpeningIsotope->xrayFactor(0.0) * m_sharpeningIsotope->xrayFactor(0.0) / m_sharpeningIsotope->xrayFactor(q) / m_sharpeningIsotope->xrayFactor(q); neutron->m_pBin[j] *= nf; xray->m_pBin[j] *= xf; } filename.sprintf("sfac_self_%s_neutron_inter_sharpened.csv", (const char *)((CStructureFactorGroup *)m_sFacGroups[i])->getName()); mprintf(" Writing intermolecular sharpened neutron scattering function to %s...\n", (const char *)filename); neutron->Write("", filename, "", false); filename.sprintf("sfac_self_%s_xray_inter_sharpened.csv", (const char *)((CStructureFactorGroup *)m_sFacGroups[i])->getName()); mprintf(" Writing intermolecular sharpened X-ray scattering function to %s...\n", (const char *)filename); xray->Write("", filename, "", false); } } mprintf(WHITE, "\n < End of Group %d <\n", i + 1); } for (i = 0; i < m_sFacCrosses.GetSize(); i++) { mprintf(WHITE, "\n > Cross Term %d >\n\n", i + 1); sfac->ZeroBin(); xray->ZeroBin(); neutron->ZeroBin(); ((CStructureFactorCross *)m_sFacCrosses[i])->finalize(sfac, xray, neutron, m_saveIntermediate); if (g_bBoxNonOrtho) { double f = 4.0 * Pi * g_iGesAtomCount / (g_fBoxVolume * 1000000.0); sfac->MultiplyBin(f); xray->MultiplyBin(f); neutron->MultiplyBin(f); } else { double f = 4.0 * Pi * g_iGesAtomCount / (g_fBoxX * g_fBoxY * g_fBoxZ); sfac->MultiplyBin(f); xray->MultiplyBin(f); neutron->MultiplyBin(f); } if (m_normalization == 1) { double sf = 0.0; int j; for (j = 0; j < m_globalSFac->getIsotopeTypeList().GetSize(); j++) { sf += ((double)m_globalSFac->getIsotopeTypeTotalCount().GetAt(j)) / ((double)g_iGesAtomCount); } sfac->MultiplyBin(1.0 / (sf * sf)); for (j = 0; j < xray->m_iResolution; j++) { double q = (xray->m_fMinVal + (0.5 + j) / xray->m_fFac) / 1000.0; double xf = 0.0; int k; for (k = 0; k < m_globalSFac->getIsotopeTypeList().GetSize(); k++) { xf += ((double)m_globalSFac->getIsotopeTypeTotalCount().GetAt(k)) / ((double)g_iGesAtomCount) * ((CIsotope *)m_globalSFac->getIsotopeTypeList().GetAt(k))->xrayFactor(q); } xray->m_pBin[j] /= xf * xf; } double nf = 0.0; for (j = 0; j < m_globalSFac->getIsotopeTypeList().GetSize(); j++) { nf += ((double)m_globalSFac->getIsotopeTypeTotalCount().GetAt(j)) / ((double)g_iGesAtomCount) * ((CIsotope *)m_globalSFac->getIsotopeTypeList().GetAt(j))->neutronFactor(); } neutron->MultiplyBin(1.0 / (nf * nf)); } else if (m_normalization == 2) { double sf = 0.0; int j; for (j = 0; j < m_globalSFac->getIsotopeTypeList().GetSize(); j++) { sf += ((double)m_globalSFac->getIsotopeTypeTotalCount().GetAt(j)) / ((double)g_iGesAtomCount); } sfac->MultiplyBin(1.0 / sf); for (j = 0; j < xray->m_iResolution; j++) { double q = (xray->m_fMinVal + (0.5 + j) / xray->m_fFac) / 1000.0; double xf = 0.0; int k; for (k = 0; k < m_globalSFac->getIsotopeTypeList().GetSize(); k++) { xf += ((double)m_globalSFac->getIsotopeTypeTotalCount().GetAt(k)) / ((double)g_iGesAtomCount) * ((CIsotope *)m_globalSFac->getIsotopeTypeList().GetAt(k))->xrayFactor(q) * ((CIsotope *)m_globalSFac->getIsotopeTypeList().GetAt(k))->xrayFactor(q); } xray->m_pBin[j] /= xf; } double nf = 0.0; for (j = 0; j < m_globalSFac->getIsotopeTypeList().GetSize(); j++) { nf += ((double)m_globalSFac->getIsotopeTypeTotalCount().GetAt(j)) / ((double)g_iGesAtomCount) * ((CIsotope *)m_globalSFac->getIsotopeTypeList().GetAt(j))->neutronFactor() * ((CIsotope *)m_globalSFac->getIsotopeTypeList().GetAt(j))->neutronFactor(); } neutron->MultiplyBin(1.0 / nf); } else if (m_normalization != 3) { eprintf("CStructureFactor::finalize(): Internal error. Unknown normalization factor.\n"); abort(); } mprintf("\n"); filename.sprintf("sfac_cross_%s_unweighted.csv", (const char *)((CStructureFactorCross *)m_sFacCrosses[i])->getName()); mprintf(" Writing unweighted structure factor to %s...\n", (const char *)filename); sfac->Write("", filename, "", false); filename.sprintf("sfac_cross_%s_xray.csv", (const char *)((CStructureFactorCross *)m_sFacCrosses[i])->getName()); mprintf(" Writing X-ray scattering function to %s...\n", (const char *)filename); xray->Write("", filename, "", false); filename.sprintf("sfac_cross_%s_neutron.csv", (const char *)((CStructureFactorCross *)m_sFacCrosses[i])->getName()); mprintf(" Writing neutron scattering function to %s...\n", (const char *)filename); neutron->Write("", filename, "", false); if (m_sharpening) { int j; for (j = 0; j < xray->m_iResolution; j++) { double q = (xray->m_fMinVal + (0.5 + j) / xray->m_fFac) / 1000.0; double nf = q * exp(-0.01 * q * q); double xf = q * exp(-0.01 * q * q) * m_sharpeningIsotope->xrayFactor(0.0) * m_sharpeningIsotope->xrayFactor(0.0) / m_sharpeningIsotope->xrayFactor(q) / m_sharpeningIsotope->xrayFactor(q); neutron->m_pBin[j] *= nf; xray->m_pBin[j] *= xf; } filename.sprintf("sfac_cross_%s_neutron_sharpened.csv", (const char *)((CStructureFactorCross *)m_sFacCrosses[i])->getName()); mprintf(" Writing sharpened neutron scattering function to %s...\n", (const char *)filename); neutron->Write("", filename, "", false); filename.sprintf("sfac_cross_%s_xray_sharpened.csv", (const char *)((CStructureFactorCross *)m_sFacCrosses[i])->getName()); mprintf(" Writing sharpened X-ray scattering function to %s...\n", (const char *)filename); xray->Write("", filename, "", false); } if (((CStructureFactorCross *)m_sFacCrosses[i])->sepInterIntra()) { sfac->ZeroBin(); xray->ZeroBin(); neutron->ZeroBin(); mprintf("\n"); ((CStructureFactorCross *)m_sFacCrosses[i])->finalizeIntra(sfac, xray, neutron, m_saveIntermediate); if (g_bBoxNonOrtho) { double f = 4.0 * Pi * g_iGesAtomCount / (g_fBoxVolume * 1000000.0); sfac->MultiplyBin(f); xray->MultiplyBin(f); neutron->MultiplyBin(f); } else { double f = 4.0 * Pi * g_iGesAtomCount / (g_fBoxX * g_fBoxY * g_fBoxZ); sfac->MultiplyBin(f); xray->MultiplyBin(f); neutron->MultiplyBin(f); } if (m_normalization == 1) { double sf = 0.0; int j; for (j = 0; j < m_globalSFac->getIsotopeTypeList().GetSize(); j++) { sf += ((double)m_globalSFac->getIsotopeTypeTotalCount().GetAt(j)) / ((double)g_iGesAtomCount); } sfac->MultiplyBin(1.0 / (sf * sf)); for (j = 0; j < xray->m_iResolution; j++) { double q = (xray->m_fMinVal + (0.5 + j) / xray->m_fFac) / 1000.0; double xf = 0.0; int k; for (k = 0; k < m_globalSFac->getIsotopeTypeList().GetSize(); k++) { xf += ((double)m_globalSFac->getIsotopeTypeTotalCount().GetAt(k)) / ((double)g_iGesAtomCount) * ((CIsotope *)m_globalSFac->getIsotopeTypeList().GetAt(k))->xrayFactor(q); } xray->m_pBin[j] /= xf * xf; } double nf = 0.0; for (j = 0; j < m_globalSFac->getIsotopeTypeList().GetSize(); j++) { nf += ((double)m_globalSFac->getIsotopeTypeTotalCount().GetAt(j)) / ((double)g_iGesAtomCount) * ((CIsotope *)m_globalSFac->getIsotopeTypeList().GetAt(j))->neutronFactor(); } neutron->MultiplyBin(1.0 / (nf * nf)); } else if (m_normalization == 2) { double sf = 0.0; int j; for (j = 0; j < m_globalSFac->getIsotopeTypeList().GetSize(); j++) { sf += ((double)m_globalSFac->getIsotopeTypeTotalCount().GetAt(j)) / ((double)g_iGesAtomCount); } sfac->MultiplyBin(1.0 / sf); for (j = 0; j < xray->m_iResolution; j++) { double q = (xray->m_fMinVal + (0.5 + j) / xray->m_fFac) / 1000.0; double xf = 0.0; int k; for (k = 0; k < m_globalSFac->getIsotopeTypeList().GetSize(); k++) { xf += ((double)m_globalSFac->getIsotopeTypeTotalCount().GetAt(k)) / ((double)g_iGesAtomCount) * ((CIsotope *)m_globalSFac->getIsotopeTypeList().GetAt(k))->xrayFactor(q) * ((CIsotope *)m_globalSFac->getIsotopeTypeList().GetAt(k))->xrayFactor(q); } xray->m_pBin[j] /= xf; } double nf = 0.0; for (j = 0; j < m_globalSFac->getIsotopeTypeList().GetSize(); j++) { nf += ((double)m_globalSFac->getIsotopeTypeTotalCount().GetAt(j)) / ((double)g_iGesAtomCount) * ((CIsotope *)m_globalSFac->getIsotopeTypeList().GetAt(j))->neutronFactor() * ((CIsotope *)m_globalSFac->getIsotopeTypeList().GetAt(j))->neutronFactor(); } neutron->MultiplyBin(1.0 / nf); } else if (m_normalization != 3) { eprintf("CStructureFactor::finalize(): Internal error. Unknown normalization factor.\n"); abort(); } mprintf("\n"); filename.sprintf("sfac_cross_%s_unweighted_intra.csv", (const char *)((CStructureFactorCross *)m_sFacCrosses[i])->getName()); mprintf(" Writing unweighted intramolecular structure factor to %s...\n", (const char *)filename); sfac->Write("", filename, "", false); filename.sprintf("sfac_cross_%s_xray_intra.csv", (const char *)((CStructureFactorCross *)m_sFacCrosses[i])->getName()); mprintf(" Writing intramolecular X-ray scattering function to %s...\n", (const char *)filename); xray->Write("", filename, "", false); filename.sprintf("sfac_cross_%s_neutron_intra.csv", (const char *)((CStructureFactorCross *)m_sFacCrosses[i])->getName()); mprintf(" Writing intramolecular neutron scattering function to %s...\n", (const char *)filename); neutron->Write("", filename, "", false); if (m_sharpening) { int j; for (j = 0; j < xray->m_iResolution; j++) { double q = (xray->m_fMinVal + (0.5 + j) / xray->m_fFac) / 1000.0; double nf = q * exp(-0.01 * q * q); double xf = q * exp(-0.01 * q * q) * m_sharpeningIsotope->xrayFactor(0.0) * m_sharpeningIsotope->xrayFactor(0.0) / m_sharpeningIsotope->xrayFactor(q) / m_sharpeningIsotope->xrayFactor(q); neutron->m_pBin[j] *= nf; xray->m_pBin[j] *= xf; } filename.sprintf("sfac_cross_%s_neutron_intra_sharpened.csv", (const char *)((CStructureFactorCross *)m_sFacCrosses[i])->getName()); mprintf(" Writing sharpened intramolecular neutron scattering function to %s...\n", (const char *)filename); neutron->Write("", filename, "", false); filename.sprintf("sfac_cross_%s_xray_intra_sharpened.csv", (const char *)((CStructureFactorCross *)m_sFacCrosses[i])->getName()); mprintf(" Writing sharpened intramolcular X-ray scattering function to %s...\n", (const char *)filename); xray->Write("", filename, "", false); } sfac->ZeroBin(); xray->ZeroBin(); neutron->ZeroBin(); mprintf("\n"); ((CStructureFactorCross *)m_sFacCrosses[i])->finalizeInter(sfac, xray, neutron, m_saveIntermediate); if (g_bBoxNonOrtho) { double f = 4.0 * Pi * g_iGesAtomCount / (g_fBoxVolume * 1000000.0); sfac->MultiplyBin(f); xray->MultiplyBin(f); neutron->MultiplyBin(f); } else { double f = 4.0 * Pi * g_iGesAtomCount / (g_fBoxX * g_fBoxY * g_fBoxZ); sfac->MultiplyBin(f); xray->MultiplyBin(f); neutron->MultiplyBin(f); } if (m_normalization == 1) { double sf = 0.0; int j; for (j = 0; j < m_globalSFac->getIsotopeTypeList().GetSize(); j++) { sf += ((double)m_globalSFac->getIsotopeTypeTotalCount().GetAt(j)) / ((double)g_iGesAtomCount); } sfac->MultiplyBin(1.0 / (sf * sf)); for (j = 0; j < xray->m_iResolution; j++) { double q = (xray->m_fMinVal + (0.5 + j) / xray->m_fFac) / 1000.0; double xf = 0.0; int k; for (k = 0; k < m_globalSFac->getIsotopeTypeList().GetSize(); k++) { xf += ((double)m_globalSFac->getIsotopeTypeTotalCount().GetAt(k)) / ((double)g_iGesAtomCount) * ((CIsotope *)m_globalSFac->getIsotopeTypeList().GetAt(k))->xrayFactor(q); } xray->m_pBin[j] /= xf * xf; } double nf = 0.0; for (j = 0; j < m_globalSFac->getIsotopeTypeList().GetSize(); j++) { nf += ((double)m_globalSFac->getIsotopeTypeTotalCount().GetAt(j)) / ((double)g_iGesAtomCount) * ((CIsotope *)m_globalSFac->getIsotopeTypeList().GetAt(j))->neutronFactor(); } neutron->MultiplyBin(1.0 / (nf * nf)); } else if (m_normalization == 2) { double sf = 0.0; int j; for (j = 0; j < m_globalSFac->getIsotopeTypeList().GetSize(); j++) { sf += ((double)m_globalSFac->getIsotopeTypeTotalCount().GetAt(j)) / ((double)g_iGesAtomCount); } sfac->MultiplyBin(1.0 / sf); for (j = 0; j < xray->m_iResolution; j++) { double q = (xray->m_fMinVal + (0.5 + j) / xray->m_fFac) / 1000.0; double xf = 0.0; int k; for (k = 0; k < m_globalSFac->getIsotopeTypeList().GetSize(); k++) { xf += ((double)m_globalSFac->getIsotopeTypeTotalCount().GetAt(k)) / ((double)g_iGesAtomCount) * ((CIsotope *)m_globalSFac->getIsotopeTypeList().GetAt(k))->xrayFactor(q) * ((CIsotope *)m_globalSFac->getIsotopeTypeList().GetAt(k))->xrayFactor(q); } xray->m_pBin[j] /= xf; } double nf = 0.0; for (j = 0; j < m_globalSFac->getIsotopeTypeList().GetSize(); j++) { nf += ((double)m_globalSFac->getIsotopeTypeTotalCount().GetAt(j)) / ((double)g_iGesAtomCount) * ((CIsotope *)m_globalSFac->getIsotopeTypeList().GetAt(j))->neutronFactor() * ((CIsotope *)m_globalSFac->getIsotopeTypeList().GetAt(j))->neutronFactor(); } neutron->MultiplyBin(1.0 / nf); } else if (m_normalization != 3) { eprintf("CStructureFactor::finalize(): Internal error. Unknown normalization factor.\n"); abort(); } mprintf("\n"); filename.sprintf("sfac_cross_%s_unweighted_inter.csv", (const char *)((CStructureFactorCross *)m_sFacCrosses[i])->getName()); mprintf(" Writing unweighted intermolecular structure factor to %s...\n", (const char *)filename); sfac->Write("", filename, "", false); filename.sprintf("sfac_cross_%s_xray_inter.csv", (const char *)((CStructureFactorCross *)m_sFacCrosses[i])->getName()); mprintf(" Writing intermolecular X-ray scattering function to %s...\n", (const char *)filename); xray->Write("", filename, "", false); filename.sprintf("sfac_cross_%s_neutron_inter.csv", (const char *)((CStructureFactorCross *)m_sFacCrosses[i])->getName()); mprintf(" Writing intermolecular neutron scattering function to %s...\n", (const char *)filename); neutron->Write("", filename, "", false); if (m_sharpening) { int j; for (j = 0; j < xray->m_iResolution; j++) { double q = (xray->m_fMinVal + (0.5 + j) / xray->m_fFac) / 1000.0; double nf = q * exp(-0.01 * q * q); double xf = q * exp(-0.01 * q * q) * m_sharpeningIsotope->xrayFactor(0.0) * m_sharpeningIsotope->xrayFactor(0.0) / m_sharpeningIsotope->xrayFactor(q) / m_sharpeningIsotope->xrayFactor(q); neutron->m_pBin[j] *= nf; xray->m_pBin[j] *= xf; } filename.sprintf("sfac_cross_%s_neutron_inter_sharpened.csv", (const char *)((CStructureFactorCross *)m_sFacCrosses[i])->getName()); mprintf(" Writing sharpened intermolecular neutron scattering function to %s...\n", (const char *)filename); neutron->Write("", filename, "", false); filename.sprintf("sfac_cross_%s_xray_inter_sharpened.csv", (const char *)((CStructureFactorCross *)m_sFacCrosses[i])->getName()); mprintf(" Writing sharpened intermolcular X-ray scattering function to %s...\n", (const char *)filename); xray->Write("", filename, "", false); } } mprintf(WHITE, "\n < End of Cross Term %d <\n", i + 1); } delete sfac; delete xray; delete neutron; } bool gatherStructureFactor() { createIsotopeList(); try { g_structureFactor = new CStructureFactor(); } catch(...) { g_structureFactor = NULL; } if (g_structureFactor == NULL) NewException((double)sizeof(CStructureFactor), __FILE__, __LINE__, __PRETTY_FUNCTION__); return true; } bool initializeStructureFactor() { g_structureFactor->initialize(); return true; } void processStructureFactor(CTimeStep *ts) { g_structureFactor->process(ts); } void finalizeStructureFactor() { g_structureFactor->finalize(); delete g_structureFactor; deleteIsotopeList(); } travis-src-190101/src/structurefactor.h0100777000000000000000000001261413412725662015055 0ustar00/***************************************************************************** TRAVIS - Trajectory Analyzer and Visualizer http://www.travis-analyzer.de/ Copyright (c) 2009-2019 Martin Brehm 2012-2019 Martin Thomas 2016-2019 Sascha Gehrke This file was written by Martin Thomas. --------------------------------------------------------------------------- This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . *****************************************************************************/ #ifndef STRUCTUREFACTOR_H #define STRUCTUREFACTOR_H // This must always be the first include directive #include "config.h" #include "xintarray.h" #include "xobarray.h" #include "xobject.h" #include "xstring.h" class CDF; class CTimeStep; class CIsotope: public CxObject { public: friend class CStructureFactor; CIsotope(const char *label, double neutronFactor, double cma1, double cma2, double cma3, double cma4, double cmb1, double cmb2, double cmb3, double cmb4, double cmc); ~CIsotope(); const char *label() { return _label; } double neutronFactor() { return _neutronFactor; } double xrayFactor(double q); private: char *_label; double _neutronFactor; double _cma[4]; double _cmb[4]; double _cmc; }; // class CSFacObservation: public CxObject // { // public: // CSFacObservation(bool global = false); // ~CSFacObservation(); // // void initialize(); // void process(CTimeStep *ts); // void finalize(); // // private: // bool _global; // char *_name; // // CxObArray _agList; // CxIntArray _atomIndex; // CxIntArray _isotopeList; // CxObArray _isotopeTypeList; // CxIntArray _isotopeTypeCount; // // double _rdfMax; // int _rdfRes; // double _sfacMax; // int _sfacRes; // CxObArray _rdfList; // // bool _normFFac; // int _normFFacFormula; // bool _sharpening; // CIsotope *_sharpeningIsotope; // }; class CStructureFactorGroup: public CxObject { public: friend class CStructureFactorCross; CStructureFactorGroup(bool global, CxObArray &isotopeAssignList); ~CStructureFactorGroup(); void initialize(double rdfMax, int rdfRes); void process(CTimeStep *ts); void finalize(CDF *sfac, CDF *xray, CDF *neutron, bool saveIntermediate); void finalizeIntra(CDF *sfac, CDF *xray, CDF *neutron, bool saveIntermediate); void finalizeInter(CDF *sfac, CDF *xray, CDF *neutron, bool saveIntermediate); CxString &getName() { return m_name; } bool sepInterIntra() const { return m_sepInterIntra; } CxObArray &getIsotopeTypeList() { return m_isotopeTypeList; } CxIntArray &getIsotopeTypeTotalCount() { return m_isotopeTypeTotalCount; } private: CxString m_name; bool m_sepInterIntra; bool m_global; CxObArray m_atomGroupList; CxIntArray m_atomIndexList; CxIntArray m_singleMolList; CxIntArray m_isotopeList; CxObArray m_isotopeTypeList; CxIntArray m_isotopeTypeCount; CxIntArray m_isotopeTypeTotalCount; CxObArray m_rdfList; CxObArray m_rdfIntraList; CxObArray m_rdfInterList; }; class CStructureFactorCross: public CxObject { public: CStructureFactorCross(CStructureFactorGroup *sfacGroup1, CStructureFactorGroup *sfacGroup2); ~CStructureFactorCross(); void initialize(double rdfMax, int rdfRes); void process(CTimeStep *ts); void finalize(CDF *sfac, CDF *xray, CDF *neutron, bool saveIntermediate); void finalizeIntra(CDF *sfac, CDF *xray, CDF *neutron, bool saveIntermediate); void finalizeInter(CDF *sfac, CDF *xray, CDF *neutron, bool saveIntermediate); CxString &getName() { return m_name; } bool sepInterIntra() const { return m_sepInterIntra; } void setSepInterIntra(bool sep) { m_sepInterIntra = sep; } private: CxString m_name; bool m_sepInterIntra; CStructureFactorGroup *m_sfacGroup1; CStructureFactorGroup *m_sfacGroup2; CxObArray m_rdfList; CxObArray m_rdfIntraList; CxObArray m_rdfInterList; }; class CStructureFactor: public CxObject { public: CStructureFactor(); ~CStructureFactor(); void initialize(); void process(CTimeStep *ts); void finalize(); private: double m_rdfMax; int m_rdfRes; double m_sfacMax; int m_sfacRes; int m_normalization; bool m_sharpening; CIsotope *m_sharpeningIsotope; bool m_saveIntermediate; CStructureFactorGroup *m_globalSFac; CxObArray m_sFacGroups; CxObArray m_sFacCrosses; }; bool gatherStructureFactor(); bool initializeStructureFactor(); void processStructureFactor(CTimeStep *ts); void finalizeStructureFactor(); // class CStructureFactor : public CxObject // { // public: // void TransformRDF(CDF *pin, CDF *pout); // void Finish(); // void ProcessStep(CTimeStep *ts); // void Parse(); // void Create(); // CStructureFactor(); // ~CStructureFactor(); // // bool m_bDumpTotalRDF; // bool m_bDumpElementRDFs; // bool m_bDumpElementSFac; // CxObArray m_oaRDFs; // CxObArray m_oaSFacs; // int m_iRDFRes, m_iSQRes; // double m_fRDFRange; // double m_fSQRange; // }; #endif travis-src-190101/src/tensor.cpp0100777000000000000000000000270713412725625013464 0ustar00/***************************************************************************** TRAVIS - Trajectory Analyzer and Visualizer http://www.travis-analyzer.de/ Copyright (c) 2009-2019 Martin Brehm 2012-2019 Martin Thomas 2016-2019 Sascha Gehrke This file was written by Martin Brehm. --------------------------------------------------------------------------- This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . *****************************************************************************/ // This must always be the first include directive #include "config.h" #include "tensor.h" const char *GetRevisionInfo_tensor(unsigned int len) { static char buf[256]; GET_REVISION_INFO( buf, len ); return buf; } const char *GetSourceVersion_tensor() { static char buf[256]; GET_SOURCE_VERSION( buf ); return buf; } travis-src-190101/src/tensor.h0100777000000000000000000006661213412725670013136 0ustar00/***************************************************************************** TRAVIS - Trajectory Analyzer and Visualizer http://www.travis-analyzer.de/ Copyright (c) 2009-2019 Martin Brehm 2012-2019 Martin Thomas 2016-2019 Sascha Gehrke This file was written by Martin Brehm. --------------------------------------------------------------------------- This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . *****************************************************************************/ #ifndef TENSOR_H #define TENSOR_H // This must always be the first include directive #include "config.h" #include #include #include #include "tools.h" #define TENSOR_BOUND_CHECK /***************************************************************************** *** CDTensor1 ************************************************************ *****************************************************************************/ class CDTensor1 { public: CDTensor1() { } explicit CDTensor1(int i) { m_pData.resize(i,0); } ~CDTensor1() { } CDTensor1(const CDTensor1 &t) : m_pData(t.m_pData) { } CDTensor1& operator=(const CDTensor1& t) { m_pData = t.m_pData; return *this; } double& operator[] (int i) { #ifdef TENSOR_BOUND_CHECK if ((i < 0) || (i >= (int)m_pData.size())) { eprintf("CDTensor1 &operator [] boundary error (%d/%lu).\n",i,m_pData.size()); abort(); } #endif return m_pData[i]; } double operator[] (int i) const { #ifdef TENSOR_BOUND_CHECK if ((i < 0) || (i >= (int)m_pData.size())) { eprintf("CDTensor1 &operator [] boundary error (%d/%lu).\n",i,m_pData.size()); abort(); } #endif return m_pData[i]; } double& operator() (int i) { #ifdef TENSOR_BOUND_CHECK if ((i < 0) || (i >= (int)m_pData.size())) { eprintf("CDTensor1 &operator () boundary error (%d/%lu).\n",i,m_pData.size()); abort(); } #endif return m_pData[i]; } double operator() (int i) const { #ifdef TENSOR_BOUND_CHECK if ((i < 0) || (i >= (int)m_pData.size())) { eprintf("CDTensor1 operator () boundary error (%d/%lu).\n",i,m_pData.size()); abort(); } #endif return m_pData[i]; } CDTensor1& operator += (const CDTensor1 &t) { #ifdef TENSOR_BOUND_CHECK if (!DimensionsMatch(t)) { eprintf("CDTensor1 &operator += dimension mismatch.\n"); abort(); } #endif std::transform(m_pData.begin(),m_pData.end(),t.m_pData.begin(),m_pData.begin(),std::plus()); return *this; } CDTensor1& operator -= (const CDTensor1 &t) { #ifdef TENSOR_BOUND_CHECK if (!DimensionsMatch(t)) { eprintf("CDTensor1 &operator -= dimension mismatch.\n"); abort(); } #endif if (!DimensionsMatch(t)) abort(); std::transform(m_pData.begin(),m_pData.end(),t.m_pData.begin(),m_pData.begin(),std::minus()); return *this; } CDTensor1& operator *= (double f) { std::transform(m_pData.begin(),m_pData.end(),m_pData.begin(),std::bind1st(std::multiplies(), f)); return *this; } CDTensor1& operator /= (double f) { std::transform(m_pData.begin(),m_pData.end(),m_pData.begin(),std::bind1st(std::divides(), f)); return *this; } void setZero() { std::fill(m_pData.begin(),m_pData.end(),0); } int getDimension() const { return (int)m_pData.size(); } bool DimensionsMatch(const CDTensor1 &t) const { if (m_pData.size() != t.m_pData.size()) { eprintf("Dimension mismatch %lu <--> %lu.\n",m_pData.size(),t.m_pData.size()); return false; } return true; } private: std::vector m_pData; }; inline CDTensor1 operator+( CDTensor1 lhs, CDTensor1 const & rhs ) { lhs += rhs; return lhs; } inline CDTensor1 operator-( CDTensor1 lhs, CDTensor1 const & rhs ) { lhs -= rhs; return lhs; } inline CDTensor1 operator*( CDTensor1 lhs, double f ) { lhs *= f; return lhs; } inline CDTensor1 operator/( CDTensor1 lhs, double f ) { lhs /= f; return lhs; } inline CDTensor1 operator*( double f, CDTensor1 lhs ) { lhs *= f; return lhs; } inline CDTensor1 operator/( double f, CDTensor1 lhs ) { lhs /= f; return lhs; } /***************************************************************************** *** CDTensor2 ************************************************************ *****************************************************************************/ class CDTensor2 { public: CDTensor2() { m_iDimensions[0] = 0; m_iDimensions[1] = 0; } CDTensor2(int i, int j) { m_iDimensions[0] = i; m_iDimensions[1] = j; m_pData.resize(i*j,0); } ~CDTensor2() { } CDTensor2(const CDTensor2 &t) : m_pData(t.m_pData) { m_iDimensions[0] = t.m_iDimensions[0]; m_iDimensions[1] = t.m_iDimensions[1]; } CDTensor2& operator=(const CDTensor2& t) { m_pData = t.m_pData; m_iDimensions[0] = t.m_iDimensions[0]; m_iDimensions[1] = t.m_iDimensions[1]; return *this; } double& operator[] (int i) { #ifdef TENSOR_BOUND_CHECK if ((i < 0) || (i >= m_iDimensions[0]*m_iDimensions[1])) { eprintf("CDTensor2 &operator [] boundary error (%d/%d).\n",i,m_iDimensions[0]*m_iDimensions[1]); abort(); } #endif return m_pData[i]; } double operator[] (int i) const { #ifdef TENSOR_BOUND_CHECK if ((i < 0) || (i >= m_iDimensions[0]*m_iDimensions[1])) { eprintf("CDTensor2 &operator [] boundary error (%d/%d).\n",i,m_iDimensions[0]*m_iDimensions[1]); abort(); } #endif return m_pData[i]; } double& operator() (int i, int j) { #ifdef TENSOR_BOUND_CHECK if ((i < 0) || (j < 0) || (i >= m_iDimensions[0]) || (j >= m_iDimensions[1])) { eprintf("CDTensor2 &operator () boundary error (%d/%d, %d/%d).\n",i,m_iDimensions[0],j,m_iDimensions[1]); abort(); } #endif return m_pData[i*m_iDimensions[1]+j]; } double operator() (int i, int j) const { #ifdef TENSOR_BOUND_CHECK if ((i < 0) || (j < 0) || (i >= m_iDimensions[0]) || (j >= m_iDimensions[1])) { eprintf("CDTensor2 operator () boundary error (%d/%d, %d/%d).\n",i,m_iDimensions[0],j,m_iDimensions[1]); abort(); } #endif return m_pData[i*m_iDimensions[1]+j]; } CDTensor2& operator += (const CDTensor2 &t) { #ifdef TENSOR_BOUND_CHECK if (!DimensionsMatch(t)) { eprintf("CDTensor2 &operator += dimension mismatch.\n"); abort(); } #endif std::transform(m_pData.begin(),m_pData.end(),t.m_pData.begin(),m_pData.begin(),std::plus()); return *this; } CDTensor2& operator -= (const CDTensor2 &t) { #ifdef TENSOR_BOUND_CHECK if (!DimensionsMatch(t)) { eprintf("CDTensor2 &operator -= dimension mismatch.\n"); abort(); } #endif std::transform(m_pData.begin(),m_pData.end(),t.m_pData.begin(),m_pData.begin(),std::minus()); return *this; } CDTensor2& operator *= (double f) { std::transform(m_pData.begin(),m_pData.end(),m_pData.begin(),std::bind1st(std::multiplies(), f)); return *this; } CDTensor2& operator /= (double f) { std::transform(m_pData.begin(),m_pData.end(),m_pData.begin(),std::bind1st(std::divides(), f)); return *this; } CDTensor1 Reduce1(int i) const { #ifdef TENSOR_BOUND_CHECK if ((i < 0) || (i >= m_iDimensions[0])) { eprintf("CDTensor2 Reduce1() boundary error (%d/%d).\n",i,m_iDimensions[0]); abort(); } #endif CDTensor1 t(m_iDimensions[1]); for (int z=0;z= m_iDimensions[1])) { eprintf("CDTensor2 Reduce2() boundary error (%d/%d).\n",i,m_iDimensions[1]); abort(); } #endif CDTensor1 t(m_iDimensions[0]); for (int z=0;z ( %d, %d ).\n",m_iDimensions[0],m_iDimensions[1],t.m_iDimensions[0],t.m_iDimensions[1]); return false; } return true; } private: std::vector m_pData; int m_iDimensions[2]; }; inline CDTensor2 operator+( CDTensor2 lhs, CDTensor2 const & rhs ) { lhs += rhs; return lhs; } inline CDTensor2 operator-( CDTensor2 lhs, CDTensor2 const & rhs ) { lhs -= rhs; return lhs; } inline CDTensor2 operator*( CDTensor2 lhs, double f ) { lhs *= f; return lhs; } inline CDTensor2 operator/( CDTensor2 lhs, double f ) { lhs /= f; return lhs; } inline CDTensor2 operator*( double f, CDTensor2 lhs ) { lhs *= f; return lhs; } inline CDTensor2 operator/( double f, CDTensor2 lhs ) { lhs /= f; return lhs; } /***************************************************************************** *** CDTensor3 ************************************************************ *****************************************************************************/ class CDTensor3 { public: CDTensor3() { m_iDimensions[0] = 0; m_iDimensions[1] = 0; m_iDimensions[2] = 0; } CDTensor3(int i, int j, int k) { m_iDimensions[0] = i; m_iDimensions[1] = j; m_iDimensions[2] = k; m_pData.resize(i*j*k,0); } ~CDTensor3() { } CDTensor3(const CDTensor3 &t) : m_pData(t.m_pData) { m_iDimensions[0] = t.m_iDimensions[0]; m_iDimensions[1] = t.m_iDimensions[1]; m_iDimensions[2] = t.m_iDimensions[2]; } CDTensor3& operator=(const CDTensor3& t) { m_pData = t.m_pData; m_iDimensions[0] = t.m_iDimensions[0]; m_iDimensions[1] = t.m_iDimensions[1]; m_iDimensions[2] = t.m_iDimensions[2]; return *this; } double& operator[] (int i) { #ifdef TENSOR_BOUND_CHECK if ((i < 0) || (i >= m_iDimensions[0]*m_iDimensions[1]*m_iDimensions[2])) { eprintf("CDTensor3 &operator [] boundary error (%d/%d).\n",i,m_iDimensions[0]*m_iDimensions[1]*m_iDimensions[2]); abort(); } #endif return m_pData[i]; } double operator[] (int i) const { #ifdef TENSOR_BOUND_CHECK if ((i < 0) || (i >= m_iDimensions[0]*m_iDimensions[1]*m_iDimensions[2])) { eprintf("CDTensor3 &operator [] boundary error (%d/%d).\n",i,m_iDimensions[0]*m_iDimensions[1]*m_iDimensions[2]); abort(); } #endif return m_pData[i]; } double& operator() (int i, int j, int k) { #ifdef TENSOR_BOUND_CHECK if ((i < 0) || (j < 0) || (k < 0) || (i >= m_iDimensions[0]) || (j >= m_iDimensions[1]) || (k >= m_iDimensions[2])) { eprintf("CDTensor3 &operator () boundary error (%d/%d, %d/%d, %d/%d).\n",i,m_iDimensions[0],j,m_iDimensions[1],k,m_iDimensions[2]); abort(); } #endif return m_pData[i*m_iDimensions[1]*m_iDimensions[2]+j*m_iDimensions[2]+k]; } double operator() (int i, int j, int k) const { #ifdef TENSOR_BOUND_CHECK if ((i < 0) || (j < 0) || (k < 0) || (i >= m_iDimensions[0]) || (j >= m_iDimensions[1]) || (k >= m_iDimensions[2])) { eprintf("CDTensor3 operator () boundary error (%d/%d, %d/%d, %d/%d).\n",i,m_iDimensions[0],j,m_iDimensions[1],k,m_iDimensions[2]); abort(); } #endif return m_pData[i*m_iDimensions[1]*m_iDimensions[2]+j*m_iDimensions[2]+k]; } CDTensor3& operator += (const CDTensor3 &t) { #ifdef TENSOR_BOUND_CHECK if (!DimensionsMatch(t)) { eprintf("CDTensor3 &operator += dimension mismatch.\n"); abort(); } #endif std::transform(m_pData.begin(),m_pData.end(),t.m_pData.begin(),m_pData.begin(),std::plus()); return *this; } CDTensor3& operator -= (const CDTensor3 &t) { #ifdef TENSOR_BOUND_CHECK if (!DimensionsMatch(t)) { eprintf("CDTensor3 &operator -= dimension mismatch.\n"); abort(); } #endif std::transform(m_pData.begin(),m_pData.end(),t.m_pData.begin(),m_pData.begin(),std::minus()); return *this; } CDTensor3& operator *= (double f) { std::transform(m_pData.begin(),m_pData.end(),m_pData.begin(),std::bind1st(std::multiplies(), f)); return *this; } CDTensor3& operator /= (double f) { std::transform(m_pData.begin(),m_pData.end(),m_pData.begin(),std::bind1st(std::divides(), f)); return *this; } CDTensor2 Reduce1(int i) const { #ifdef TENSOR_BOUND_CHECK if ((i < 0) || (i >= m_iDimensions[0])) { eprintf("CDTensor3 Reduce1() boundary error (%d/%d).\n",i,m_iDimensions[0]); abort(); } #endif CDTensor2 t(m_iDimensions[1],m_iDimensions[2]); for (int z=0;z= m_iDimensions[1])) { eprintf("CDTensor3 Reduce2() boundary error (%d/%d).\n",i,m_iDimensions[1]); abort(); } #endif CDTensor2 t(m_iDimensions[0],m_iDimensions[2]); for (int z=0;z= m_iDimensions[2])) { eprintf("CDTensor3 Reduce3() boundary error (%d/%d).\n",i,m_iDimensions[2]); abort(); } #endif CDTensor2 t(m_iDimensions[0],m_iDimensions[1]); for (int z=0;z= m_iDimensions[0]) || (j >= m_iDimensions[1])) { eprintf("CDTensor3 Reduce12() boundary error (%d/%d, %d/%d).\n",i,m_iDimensions[0],j,m_iDimensions[1]); abort(); } #endif CDTensor1 t(m_iDimensions[2]); for (int z=0;z= m_iDimensions[0]) || (j >= m_iDimensions[2])) { eprintf("CDTensor3 Reduce13() boundary error (%d/%d, %d/%d).\n",i,m_iDimensions[0],j,m_iDimensions[2]); abort(); } #endif CDTensor1 t(m_iDimensions[1]); for (int z=0;z= m_iDimensions[1]) || (j >= m_iDimensions[2])) { eprintf("CDTensor3 Reduce23() boundary error (%d/%d, %d/%d).\n",i,m_iDimensions[1],j,m_iDimensions[2]); abort(); } #endif CDTensor1 t(m_iDimensions[0]); for (int z=0;z ( %d, %d, %d ).\n",m_iDimensions[0],m_iDimensions[1],m_iDimensions[2],t.m_iDimensions[0],t.m_iDimensions[1],t.m_iDimensions[2]); return false; } return true; } private: std::vector m_pData; int m_iDimensions[3]; }; inline CDTensor3 operator+( CDTensor3 lhs, CDTensor3 const & rhs ) { lhs += rhs; return lhs; } inline CDTensor3 operator-( CDTensor3 lhs, CDTensor3 const & rhs ) { lhs -= rhs; return lhs; } inline CDTensor3 operator*( CDTensor3 lhs, double f ) { lhs *= f; return lhs; } inline CDTensor3 operator/( CDTensor3 lhs, double f ) { lhs /= f; return lhs; } inline CDTensor3 operator*( double f, CDTensor3 lhs ) { lhs *= f; return lhs; } inline CDTensor3 operator/( double f, CDTensor3 lhs ) { lhs /= f; return lhs; } /***************************************************************************** *** CDTensor4 ************************************************************ *****************************************************************************/ class CDTensor4 { public: CDTensor4() { m_iDimensions[0] = 0; m_iDimensions[1] = 0; m_iDimensions[2] = 0; m_iDimensions[3] = 0; } CDTensor4(int i, int j, int k, int l) { m_iDimensions[0] = i; m_iDimensions[1] = j; m_iDimensions[2] = k; m_iDimensions[3] = l; m_pData.resize(i*j*k*l,0); } ~CDTensor4() { } CDTensor4(const CDTensor4 &t) : m_pData(t.m_pData) { m_iDimensions[0] = t.m_iDimensions[0]; m_iDimensions[1] = t.m_iDimensions[1]; m_iDimensions[2] = t.m_iDimensions[2]; m_iDimensions[3] = t.m_iDimensions[3]; } CDTensor4& operator=(const CDTensor4& t) { m_pData = t.m_pData; m_iDimensions[0] = t.m_iDimensions[0]; m_iDimensions[1] = t.m_iDimensions[1]; m_iDimensions[2] = t.m_iDimensions[2]; m_iDimensions[3] = t.m_iDimensions[3]; return *this; } double& operator[] (int i) { #ifdef TENSOR_BOUND_CHECK if ((i < 0) || (i >= m_iDimensions[0]*m_iDimensions[1]*m_iDimensions[2]*m_iDimensions[3])) { eprintf("CDTensor4 &operator [] boundary error (%d/%d).\n",i,m_iDimensions[0]*m_iDimensions[1]*m_iDimensions[2]*m_iDimensions[3]); abort(); } #endif return m_pData[i]; } double operator[] (int i) const { #ifdef TENSOR_BOUND_CHECK if ((i < 0) || (i >= m_iDimensions[0]*m_iDimensions[1]*m_iDimensions[2]*m_iDimensions[3])) { eprintf("CDTensor4 &operator [] boundary error (%d/%d).\n",i,m_iDimensions[0]*m_iDimensions[1]*m_iDimensions[2]*m_iDimensions[3]); abort(); } #endif return m_pData[i]; } double& operator() (int i, int j, int k, int l) { #ifdef TENSOR_BOUND_CHECK if ((i < 0) || (j < 0) || (k < 0) || (l < 0) || (i >= m_iDimensions[0]) || (j >= m_iDimensions[1]) || (k >= m_iDimensions[2]) || (l >= m_iDimensions[3])) { eprintf("CDTensor4 &operator () boundary error (%d/%d, %d/%d, %d/%d, %d/%d).\n",i,m_iDimensions[0],j,m_iDimensions[1],k,m_iDimensions[2],l,m_iDimensions[3]); abort(); } #endif return m_pData[i*m_iDimensions[1]*m_iDimensions[2]*m_iDimensions[3]+j*m_iDimensions[2]*m_iDimensions[3]+k*m_iDimensions[3]+l]; } double operator() (int i, int j, int k, int l) const { #ifdef TENSOR_BOUND_CHECK if ((i < 0) || (j < 0) || (k < 0) || (l < 0) || (i >= m_iDimensions[0]) || (j >= m_iDimensions[1]) || (k >= m_iDimensions[2]) || (l >= m_iDimensions[3])) { eprintf("CDTensor4 operator () boundary error (%d/%d, %d/%d, %d/%d, %d/%d).\n",i,m_iDimensions[0],j,m_iDimensions[1],k,m_iDimensions[2],l,m_iDimensions[3]); abort(); } #endif return m_pData[i*m_iDimensions[1]*m_iDimensions[2]*m_iDimensions[3]+j*m_iDimensions[2]*m_iDimensions[3]+k*m_iDimensions[3]+l]; } CDTensor4& operator += (const CDTensor4 &t) { #ifdef TENSOR_BOUND_CHECK if (!DimensionsMatch(t)) { eprintf("CDTensor4 &operator += dimension mismatch.\n"); abort(); } #endif std::transform(m_pData.begin(),m_pData.end(),t.m_pData.begin(),m_pData.begin(),std::plus()); return *this; } CDTensor4& operator -= (const CDTensor4 &t) { #ifdef TENSOR_BOUND_CHECK if (!DimensionsMatch(t)) { eprintf("CDTensor4 &operator -= dimension mismatch.\n"); abort(); } #endif std::transform(m_pData.begin(),m_pData.end(),t.m_pData.begin(),m_pData.begin(),std::minus()); return *this; } CDTensor4& operator *= (double f) { std::transform(m_pData.begin(),m_pData.end(),m_pData.begin(),std::bind1st(std::multiplies(), f)); return *this; } CDTensor4& operator /= (double f) { std::transform(m_pData.begin(),m_pData.end(),m_pData.begin(),std::bind1st(std::divides(), f)); return *this; } CDTensor3 Reduce1(int i) const { #ifdef TENSOR_BOUND_CHECK if ((i < 0) || (i >= m_iDimensions[0])) { eprintf("CDTensor4 Reduce1() boundary error (%d/%d).\n",i,m_iDimensions[0]); abort(); } #endif CDTensor3 t(m_iDimensions[1],m_iDimensions[2],m_iDimensions[3]); for (int z=0;z= m_iDimensions[1])) { eprintf("CDTensor4 Reduce2() boundary error (%d/%d).\n",i,m_iDimensions[1]); abort(); } #endif CDTensor3 t(m_iDimensions[0],m_iDimensions[2],m_iDimensions[3]); for (int z=0;z= m_iDimensions[2])) { eprintf("CDTensor4 Reduce3() boundary error (%d/%d).\n",i,m_iDimensions[2]); abort(); } #endif CDTensor3 t(m_iDimensions[0],m_iDimensions[1],m_iDimensions[3]); for (int z=0;z= m_iDimensions[3])) { eprintf("CDTensor4 Reduce4() boundary error (%d/%d).\n",i,m_iDimensions[3]); abort(); } #endif CDTensor3 t(m_iDimensions[0],m_iDimensions[1],m_iDimensions[2]); for (int z=0;z= m_iDimensions[0]) || (j >= m_iDimensions[1])) { eprintf("CDTensor4 Reduce12() boundary error (%d/%d, %d/%d).\n",i,m_iDimensions[0],j,m_iDimensions[1]); abort(); } #endif CDTensor2 t(m_iDimensions[2],m_iDimensions[3]); for (int z=0;z= m_iDimensions[0]) || (j >= m_iDimensions[2])) { eprintf("CDTensor4 Reduce13() boundary error (%d/%d, %d/%d).\n",i,m_iDimensions[0],j,m_iDimensions[2]); abort(); } #endif CDTensor2 t(m_iDimensions[1],m_iDimensions[3]); for (int z=0;z= m_iDimensions[0]) || (j >= m_iDimensions[3])) { eprintf("CDTensor4 Reduce14() boundary error (%d/%d, %d/%d).\n",i,m_iDimensions[0],j,m_iDimensions[3]); abort(); } #endif CDTensor2 t(m_iDimensions[1],m_iDimensions[2]); for (int z=0;z= m_iDimensions[1]) || (j >= m_iDimensions[2])) { eprintf("CDTensor4 Reduce23() boundary error (%d/%d, %d/%d).\n",i,m_iDimensions[1],j,m_iDimensions[2]); abort(); } #endif CDTensor2 t(m_iDimensions[0],m_iDimensions[3]); for (int z=0;z= m_iDimensions[1]) || (j >= m_iDimensions[3])) { eprintf("CDTensor4 Reduce24() boundary error (%d/%d, %d/%d).\n",i,m_iDimensions[1],j,m_iDimensions[3]); abort(); } #endif CDTensor2 t(m_iDimensions[0],m_iDimensions[2]); for (int z=0;z= m_iDimensions[2]) || (j >= m_iDimensions[3])) { eprintf("CDTensor4 Reduce34() boundary error (%d/%d, %d/%d).\n",i,m_iDimensions[2],j,m_iDimensions[3]); abort(); } #endif CDTensor2 t(m_iDimensions[0],m_iDimensions[1]); for (int z=0;z= m_iDimensions[0]) || (j >= m_iDimensions[1]) || (k >= m_iDimensions[2])) { eprintf("CDTensor4 Reduce123() boundary error (%d/%d, %d/%d, %d/%d).\n",i,m_iDimensions[0],j,m_iDimensions[1],k,m_iDimensions[2]); abort(); } #endif CDTensor1 t(m_iDimensions[3]); for (int z=0;z= m_iDimensions[0]) || (j >= m_iDimensions[1]) || (k >= m_iDimensions[3])) { eprintf("CDTensor4 Reduce124() boundary error (%d/%d, %d/%d, %d/%d).\n",i,m_iDimensions[0],j,m_iDimensions[1],k,m_iDimensions[3]); abort(); } #endif CDTensor1 t(m_iDimensions[2]); for (int z=0;z= m_iDimensions[0]) || (j >= m_iDimensions[2]) || (k >= m_iDimensions[3])) { eprintf("CDTensor4 Reduce134() boundary error (%d/%d, %d/%d, %d/%d).\n",i,m_iDimensions[0],j,m_iDimensions[2],k,m_iDimensions[3]); abort(); } #endif CDTensor1 t(m_iDimensions[1]); for (int z=0;z= m_iDimensions[1]) || (j >= m_iDimensions[2]) || (k >= m_iDimensions[3])) { eprintf("CDTensor4 Reduce234() boundary error (%d/%d, %d/%d, %d/%d).\n",i,m_iDimensions[1],j,m_iDimensions[2],k,m_iDimensions[3]); abort(); } #endif CDTensor1 t(m_iDimensions[0]); for (int z=0;z ( %d, %d, %d, %d ).\n",m_iDimensions[0],m_iDimensions[1],m_iDimensions[2],m_iDimensions[3],t.m_iDimensions[0],t.m_iDimensions[1],t.m_iDimensions[2],t.m_iDimensions[3]); return false; } return true; } private: std::vector m_pData; int m_iDimensions[4]; }; inline CDTensor4 operator+( CDTensor4 lhs, CDTensor4 const & rhs ) { lhs += rhs; return lhs; } inline CDTensor4 operator-( CDTensor4 lhs, CDTensor4 const & rhs ) { lhs -= rhs; return lhs; } inline CDTensor4 operator*( CDTensor4 lhs, double f ) { lhs *= f; return lhs; } inline CDTensor4 operator/( CDTensor4 lhs, double f ) { lhs /= f; return lhs; } inline CDTensor4 operator*( double f, CDTensor4 lhs ) { lhs *= f; return lhs; } inline CDTensor4 operator/( double f, CDTensor4 lhs ) { lhs /= f; return lhs; } #endif travis-src-190101/src/tetrapak.cpp0100777000000000000000000031460213412725622013762 0ustar00/***************************************************************************** TRAVIS - Trajectory Analyzer and Visualizer http://www.travis-analyzer.de/ Copyright (c) 2009-2019 Martin Brehm 2012-2019 Martin Thomas 2016-2019 Sascha Gehrke This file was written by Martin Brehm and Martin Thomas. --------------------------------------------------------------------------- This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . *****************************************************************************/ // This must always be the first include directive #include "config.h" #include "tetrapak.h" #include "maintools.h" #include "tools.h" #include "globalvar.h" #include "conversion.h" const char *GetRevisionInfo_tetrapak(unsigned int len) { static char buf[256]; GET_REVISION_INFO( buf, len ); return buf; } const char *GetSourceVersion_tetrapak() { static char buf[256]; GET_SOURCE_VERSION( buf ); return buf; } static char *g_cubeMemFileNameFixed = NULL; static int g_cubeMemFileIndex = 1; static int g_cubeMemFileStride = 1; CTetraPak::CTetraPak() { // m_atomChargeFile = NULL; // m_molChargeFile = NULL; } CTetraPak::~CTetraPak() { // if (m_atomChargeFile != NULL) // fclose(m_atomChargeFile); // if (m_molChargeFile != NULL) // fclose(m_molChargeFile); if (g_cubeMemFileNameFixed != NULL) delete[] g_cubeMemFileNameFixed; } void CTetraPak::Parse() { CTimeStep *t; int z, i, rx, ry, rz; double fs; bool sanityall; // char buf[256]; CxString buf; FILE *a; mprintf(WHITE,"\n>>> Voronoi Integration Functions >>>\n\n"); if (!g_bVolumetricData) { eprintf(" Error: This requires volumetric electron density data in each step of the trajectory (.cube or .bqb).\n\n"); abort(); } mprintf(" Initializing Voronoi tesselation...\n"); g_pVoroWrapper->Init(); mprintf("\n"); mprintf("*** Voro: Box density is %f particles / Angstrom^3.\n",g_pVoroWrapper->m_fBoxDens); mprintf("*** Voro: Using %d x %d x %d blocks.\n",g_pVoroWrapper->m_iBlocksX,g_pVoroWrapper->m_iBlocksY,g_pVoroWrapper->m_iBlocksZ); try { t = new CTimeStep(); } catch(...) { t = NULL; } if (t == NULL) NewException((double)sizeof(CTimeStep),__FILE__,__LINE__,__PRETTY_FUNCTION__); t->CopyFrom(&g_TimeStep); t->FoldAtomsPositive(); g_pVoroWrapper->Dump("voro.txt",t); mprintf("\n"); mprintf(" Voro++: Using cell memory for %d particles.\n\n",g_iVoroMemory); // Removed: Did not work. // g_bVoroIntEquitable = AskYesNo(" Use equitable binning for Voronoi integration (y/n)? [no] ",false); if (g_TimeStep.m_pVolumetricData != NULL) { m_bInterpolation = AskYesNo(" Use on-the-fly interpolation of volumetric data (y/n)? [no] ",false); if (m_bInterpolation) { mprintf("\n Interpolation currently only works for charges, not for moments.\n\n"); // m_bInterpolationLinear = AskYesNo(" Use linear interpolation (y) or constant interpolation (n)? [yes] ",true); m_iInterpolationFactor = AskUnsignedInteger(" Enter interpolation factor: [2] ",2); m_iInterpolationFactorCube = m_iInterpolationFactor * m_iInterpolationFactor * m_iInterpolationFactor; rx = g_TimeStep.m_pVolumetricData->m_iRes[0]; ry = g_TimeStep.m_pVolumetricData->m_iRes[1]; rz = g_TimeStep.m_pVolumetricData->m_iRes[2]; mprintf("\n Original grid of %d x %d x %d will be interpolated to %d x %d x %d.\n",rx,ry,rz,rx*m_iInterpolationFactor,ry*m_iInterpolationFactor,rz*m_iInterpolationFactor); } else { m_iInterpolationFactor = 1; m_iInterpolationFactorCube = 1; } } else { m_bInterpolation = false; m_iInterpolationFactor = 1; m_iInterpolationFactorCube = 1; } mprintf("\n Performing sanity check...\n\n"); m_p3DF = new C3DF(); if (g_TimeStep.m_pVolumetricData != NULL) { rx = g_TimeStep.m_pVolumetricData->m_iRes[0]; ry = g_TimeStep.m_pVolumetricData->m_iRes[1]; rz = g_TimeStep.m_pVolumetricData->m_iRes[2]; m_p3DF->m_fMaxVal[0] = g_TimeStep.m_pVolumetricData->m_fMaxVal[0]; m_p3DF->m_fMaxVal[1] = g_TimeStep.m_pVolumetricData->m_fMaxVal[1]; m_p3DF->m_fMaxVal[2] = g_TimeStep.m_pVolumetricData->m_fMaxVal[2]; mprintf(" Input trajectory contains volumetric data. Using grid of %d x %d x %d.\n",rx,ry,rz); } else { rx = 100; ry = 100; rz = 100; m_p3DF->m_fMaxVal[0] = g_fBoxX; m_p3DF->m_fMaxVal[1] = g_fBoxY; m_p3DF->m_fMaxVal[2] = g_fBoxZ; mprintf(" Input trajectory does not contain volumetric data. Using grid of 100 x 100 x 100.\n"); } m_p3DF->m_iRes[0] = rx; m_p3DF->m_iRes[1] = ry; m_p3DF->m_iRes[2] = rz; m_p3DF->m_fMinVal[0] = 0; m_p3DF->m_fMinVal[1] = 0; m_p3DF->m_fMinVal[2] = 0; // m_p3DF->m_fMaxVal[0] = g_fBoxX; // m_p3DF->m_fMaxVal[1] = g_fBoxY; // m_p3DF->m_fMaxVal[2] = g_fBoxZ; // m_p3DF->m_fMaxVal[0] = g_fCubeXStep * LEN_AU2PM * (rx * g_iCubeXStride - g_iCubeXMismatch); // m_p3DF->m_fMaxVal[1] = g_fCubeYStep * LEN_AU2PM * (ry * g_iCubeYStride - g_iCubeYMismatch); // m_p3DF->m_fMaxVal[2] = g_fCubeZStep * LEN_AU2PM * (rz * g_iCubeZStride - g_iCubeZMismatch); // m_p3DF->m_fMaxVal[0] = g_fCubeXStep * LEN_AU2PM * rx; // m_p3DF->m_fMaxVal[1] = g_fCubeYStep * LEN_AU2PM * ry; // m_p3DF->m_fMaxVal[2] = g_fCubeZStep * LEN_AU2PM * rz; m_p3DF->Create(); try { m_hitCount = new int[rx * ry * rz * m_iInterpolationFactorCube]; } catch (...) { m_hitCount = NULL; } if (m_hitCount == NULL) NewException((double)sizeof(int) * rx * ry * rz * m_iInterpolationFactorCube, __FILE__, __LINE__, __PRETTY_FUNCTION__); memset(m_hitCount, 0, rx * ry * rz * m_iInterpolationFactorCube * sizeof(int)); if (g_bAdvanced2) { mprintf("\n"); sanityall = AskYesNo(" Perform sanity check for first time step (n) or for all steps in trajectory (y)? [no] ",false); } else sanityall = false; if (sanityall) { mprintf("\n"); // g_fPos = fopen(g_sInputTraj,"rt"); OpenInputTrajectory(); /* if (g_fPos == NULL) { eprintf("Error. Could not open \"%s\".\n",g_sInputTraj); abort(); }*/ i = 0; while (true) { mprintf(YELLOW,"Step %5d: ",i+1); i++; if (!g_TimeStep.ReadTimestep(g_fPos,false)) break; g_TimeStep.CalcCenters(); t->CopyFrom(&g_TimeStep); t->FoldAtomsPositive(); for (z=0;zm_pBin[z] = 0; for (z = 0; z < rx * ry * rz * m_iInterpolationFactorCube; z++) m_hitCount[z] = 0; if (!BuildVoronoi(t,true,true,true)) { eprintf("\n Sanity check failed.\n\n"); if (!AskYesNo(" This should not have happened. Continue anyway (y/n)? [yes] ",true)) abort(); mprintf("\n"); } } mprintf("\n All done. Leaving.\n"); exit(0); } else { if (!BuildVoronoi(t,true,true)) { eprintf("\n Sanity check failed.\n\n"); if (!AskYesNo(" This should not have happened. Continue anyway (y/n)? [yes] ",true)) abort(); mprintf("\n"); } else { mprintf("\n Sanity check done.\n\n"); } } // m_p3DF->WritePLT("test.plt","","",true); delete m_p3DF; delete[] m_hitCount; if (g_bAdvanced2) { if (AskYesNo(" Compute Voronoi charges from a single electron density cube file (y/n)? [no] ",false)) { mprintf("\n"); _n2: AskString_ND(" Enter file name of the cube file: ",&buf); a = fopen(buf,"rt"); if (a == NULL) { eprintf(" Could not open \"%s\" for reading.\n",(const char*)buf); goto _n2; } mprintf("\n"); m_p3DF = new C3DF(); m_p3DF->ReadCube(a,true,true); fclose(a); mprintf("\n Calculating Voronoi partial charges...\n"); m_faCharge.SetSize(g_iGesAtomCount); for (z=0;zm_iRes[0])*(g_fBoxY/100.0/0.529177249/m_p3DF->m_iRes[1])*(g_fBoxZ/100.0/0.529177249/m_p3DF->m_iRes[2]); m_faCharge[z] *= g_fCubeXStep*g_fCubeYStep*g_fCubeZStep; if (mystricmp(((CAtom*)g_oaAtoms[g_waAtomRealElement[z]])->m_sName,"H") == 0) m_faCharge[z] += 1.0; else if (mystricmp(((CAtom*)g_oaAtoms[g_waAtomRealElement[z]])->m_sName,"C") == 0) m_faCharge[z] += 4.0; else if (mystricmp(((CAtom*)g_oaAtoms[g_waAtomRealElement[z]])->m_sName,"N") == 0) m_faCharge[z] += 5.0; else if (mystricmp(((CAtom*)g_oaAtoms[g_waAtomRealElement[z]])->m_sName,"O") == 0) m_faCharge[z] += 6.0; else eprintf("Unknown atom type \"%s\".\n",(const char*)((CAtom*)g_oaAtoms[g_waAtomRealElement[z]])->m_sName); mprintf(" Atom %4d (%-2s): Charge %10.6f.\n",z+1,(const char*)((CAtom*)g_oaAtoms[g_waAtomRealElement[z]])->m_sName,m_faCharge[z]); fs += m_faCharge[z]; } mprintf("\n Sum of charges: %10.6f.\n",fs); } mprintf("\n"); } delete t; if ((g_iTrajFormat == 5) || (g_iTrajFormat == 7)) m_bVoronoiCharges = AskYesNo(" Perform Voronoi integration (for charges/moments) in each step for electron density in cube trajectory (y/n)? [yes] ",true); else m_bVoronoiCharges = AskYesNo(" Perform Voronoi integration (for charges/moments) in each step for a stream of electron density cube files (y/n)? [no] ",false); if (m_bVoronoiCharges) { mprintf("\n"); if ((g_iTrajFormat == 5) || (g_iTrajFormat == 7)) { g_bCubeStream = AskYesNo(" Use streaming mode (y/n)? [no] ", false); if (g_bCubeStream) { try { g_fCubeMemFile = new CxMemFile(); } catch (...) { g_fCubeMemFile = NULL; } if (g_fCubeMemFile == NULL) NewException((double)sizeof(g_fCubeMemFile), __FILE__, __LINE__, __PRETTY_FUNCTION__); //CxString buf; AskString_ND(" Enter file base name: ", &buf); if (g_cubeMemFileNameFixed != NULL) delete[] g_cubeMemFileNameFixed; try { g_cubeMemFileNameFixed = new char[strlen(buf) + 1]; } catch (...) { g_cubeMemFileNameFixed = NULL; } if (g_cubeMemFileNameFixed == NULL) NewException((double)sizeof(char) * (strlen(buf) + 1), __FILE__, __LINE__, __PRETTY_FUNCTION__); strcpy(g_cubeMemFileNameFixed, buf); g_cubeMemFileIndex = AskUnsignedInteger(" First index to process: [1] ", 1); g_cubeMemFileStride = AskUnsignedInteger(" Stride of cube files: [1] ", 1); g_iCubeMemFileSteps = AskUnsignedInteger_ND(" Number of cube files to read: "); mprintf("\n Expecting files \"%s%d.cube\", \"%s%d.cube\", ..., \"%s%d.cube\" to appear\n", g_cubeMemFileNameFixed, g_cubeMemFileIndex, g_cubeMemFileNameFixed, g_cubeMemFileIndex + g_cubeMemFileStride, g_cubeMemFileNameFixed, g_cubeMemFileIndex + (g_iCubeMemFileSteps - 1) * g_cubeMemFileStride); g_cubeMemFileIndex -= g_cubeMemFileStride; g_iCubeMemFileLines = (g_TimeStep.m_pVolumetricData->m_iRes[2] + g_iCubeZMismatch) / g_iCubeZStride / 6; if (g_TimeStep.m_pVolumetricData->m_iRes[2] % 6 > 0) g_iCubeMemFileLines++; g_iCubeMemFileLines *= (g_TimeStep.m_pVolumetricData->m_iRes[1] + g_iCubeYMismatch) / g_iCubeYStride * (g_TimeStep.m_pVolumetricData->m_iRes[0] + g_iCubeZMismatch) / g_iCubeZStride; g_iCubeMemFileLines += g_iGesAtomCount + 6; } else { mprintf(" Taking electron density from input cube trajectory.\n"); } } else { _nameagain: AskString_ND(" Enter name of the cube file for the volumetric electron density data: ",&buf); m_fCubePipe = fopen(buf,"rt"); if (m_fCubePipe == NULL) { eprintf(" Could not open \"%s\" for reading.\n",(const char*)buf); goto _nameagain; } } if (g_bVoroIntegrateCharge) m_faCharge.SetSize(g_iGesAtomCount); if (g_bVoroIntegrateDipoleMoment) m_moments.SetSize(g_iGesAtomCount); if (g_bVoroIntegrateTotalCurrent) m_totalCurrent.SetSize(g_iGesAtomCount); if (g_bVoroIntegrateMagneticMoment) m_magneticMoments.SetSize(g_iGesAtomCount); m_p3DF = NULL; if (g_bAdvanced2) { m_saveTotalIntegrals = AskYesNo("\n Save total cube integrals in each step (y/n)? [no] ", false); m_bSaveAtomIntegrals = AskYesNo(" Save atomar/molecular integrals in each step (y/n)? [no] ",false); } else { m_saveTotalIntegrals = false; m_bSaveAtomIntegrals = false; } if (m_saveTotalIntegrals) m_totalIntegralFile = OpenFileWrite("vori_integrals.csv", false); if (m_bSaveAtomIntegrals) { m_fAtomIntegralFile = OpenFileWrite("vori_atomar_integrals.csv", true); mfprintf(m_fAtomIntegralFile,"#Step; AtomID; Label; Charge; ElDipX; ElDipY; ElDipZ; ElQuadXX; ElQuadXY; ElQuadXZ; ElQuadYX; ElQuadYY; ElQuadYZ; ElQuadZX; ElQuadZY; ElQuadZZ; ElCurrX; ElCurrY; ElCurrZ; MagDipX; MagDipY; MagDipZ\n"); g_fMolIntegralFile = OpenFileWrite("vori_molecular_integrals.csv", true); mfprintf(g_fMolIntegralFile,"#Step; Molecule; SingleMolecule; Charge; ElDipX; ElDipY; ElDipZ; ElQuadXX; ElQuadXY; ElQuadXZ; ElQuadYX; ElQuadYY; ElQuadYZ; ElQuadZX; ElQuadZY; ElQuadZZ; ElCurrX; ElCurrY; ElCurrZ; MagDipX; MagDipY; MagDipZ\n"); } } // m_saveAtomCharges = AskYesNo("\n Save atomic Voronoi charges (y/n)? [no] ", false); // if (m_saveAtomCharges) { // m_atomChargeFile = OpenFileWrite("vori_charge_atoms.csv", false); // fprintf(m_atomChargeFile, "#Time (fs);"); // int i, j, k, l; // for (i = 0; i < g_oaMolecules.GetSize(); i++) { // CMolecule *m = (CMolecule *)g_oaMolecules[i]; // for (j = 0; j < m->m_laSingleMolIndex.GetSize(); j++) { // CSingleMolecule *sm = (CSingleMolecule *)g_oaSingleMolecules[m->m_laSingleMolIndex[j]]; // for (k = 0; k < m->m_baAtomIndex.GetSize(); k++) { // if (m->m_baAtomIndex[k] == g_iVirtAtomType) // continue; // for (l = 0; l < ((CxIntArray *)sm->m_oaAtomOffset[k])->GetSize(); l++) { // fprintf(m_atomChargeFile, " %s[%d]-%s%d;", m->m_sName, j + 1, ((CAtom *)g_oaAtoms[m->m_baAtomIndex[k]])->m_sName, l + 1); // } // } // } // } // fprintf(m_atomChargeFile, "\n"); // } // // m_saveMolCharges = AskYesNo(" Save molecular Voronoi charges (y/n)? [no] ", false); // if (m_saveMolCharges) { // m_molChargeFile = OpenFileWrite("vori_charge_molecules.csv", false); // fprintf(m_molChargeFile, "#Time (fs);"); // int i, j; // for (i = 0; i < g_oaMolecules.GetSize(); i++) { // CMolecule *m = (CMolecule *)g_oaMolecules[i]; // for (j = 0; j < m->m_laSingleMolIndex.GetSize(); j++) { // fprintf(m_molChargeFile, " %s[%d];", m->m_sName, j + 1); // } // } // fprintf(m_molChargeFile, "\n"); // } mprintf(WHITE,"\n<<< End of Voronoi Integration Functions <<<\n\n"); // if (g_bVCD || g_bMagneticDipoleRestart) { // g_bDipole = true; // g_bUseVelocities = true; // g_bCubeTimeDev = true; // // g_fTimestepLength = 0.1f; // } } bool CTetraPak::ParseSilent(CTimeStep *ts) { CTimeStep *t; int rx, ry, rz; CxString buf; mprintf(WHITE,"\n>>> Voronoi Integration Functions >>>\n\n"); mprintf(" Initializing Voronoi tesselation...\n"); g_pVoroWrapper->Init(); mprintf("\n"); mprintf("*** Voro: Box density is %f particles / Angstrom^3.\n",g_pVoroWrapper->m_fBoxDens); mprintf("*** Voro: Using %d x %d x %d blocks.\n",g_pVoroWrapper->m_iBlocksX,g_pVoroWrapper->m_iBlocksY,g_pVoroWrapper->m_iBlocksZ); try { t = new CTimeStep(); } catch(...) { t = NULL; } if (t == NULL) NewException((double)sizeof(CTimeStep),__FILE__,__LINE__,__PRETTY_FUNCTION__); t->CopyFrom(ts); t->FoldAtomsPositive(); g_pVoroWrapper->Dump("voro.txt",t); mprintf("\n"); mprintf(" Voro++: Using cell memory for %d particles.\n\n",g_iVoroMemory); m_bInterpolation = false; m_iInterpolationFactor = 1; m_iInterpolationFactorCube = 1; mprintf("\n Performing sanity check...\n\n"); m_p3DF = new C3DF(); if (ts->m_pVolumetricData != NULL) { rx = ts->m_pVolumetricData->m_iRes[0]; ry = ts->m_pVolumetricData->m_iRes[1]; rz = ts->m_pVolumetricData->m_iRes[2]; m_p3DF->m_fMaxVal[0] = ts->m_pVolumetricData->m_fMaxVal[0]; m_p3DF->m_fMaxVal[1] = ts->m_pVolumetricData->m_fMaxVal[1]; m_p3DF->m_fMaxVal[2] = ts->m_pVolumetricData->m_fMaxVal[2]; mprintf(" Input trajectory contains volumetric data. Using grid of %d x %d x %d.\n",rx,ry,rz); } else { eprintf("Error: Input trajectory does not contain volumetric data.\n"); return false; } m_p3DF->m_iRes[0] = rx; m_p3DF->m_iRes[1] = ry; m_p3DF->m_iRes[2] = rz; m_p3DF->m_fMinVal[0] = 0; m_p3DF->m_fMinVal[1] = 0; m_p3DF->m_fMinVal[2] = 0; m_p3DF->Create(); try { m_hitCount = new int[rx * ry * rz * m_iInterpolationFactorCube]; } catch (...) { m_hitCount = NULL; } if (m_hitCount == NULL) NewException((double)sizeof(int) * rx * ry * rz * m_iInterpolationFactorCube, __FILE__, __LINE__, __PRETTY_FUNCTION__); memset(m_hitCount, 0, rx * ry * rz * m_iInterpolationFactorCube * sizeof(int)); if (!BuildVoronoi(t,true,true)) { eprintf("\n Sanity check failed.\n\n"); if (!AskYesNo(" This should not have happened. Continue anyway (y/n)? [yes] ",true)) abort(); mprintf("\n"); } else mprintf("\n Sanity check done.\n\n"); delete m_p3DF; delete[] m_hitCount; m_bVoronoiCharges = true; m_totalIntegralFile = NULL; m_fAtomIntegralFile = NULL; if (g_bVoroIntegrateCharge) m_faCharge.SetSize(g_iGesAtomCount); if (g_bVoroIntegrateDipoleMoment) m_moments.SetSize(g_iGesAtomCount); if (g_bVoroIntegrateQuadrupoleMoment) m_maQuadTensor.resize(g_iGesAtomCount); if (g_bVoroIntegrateTotalCurrent) m_totalCurrent.SetSize(g_iGesAtomCount); if (g_bVoroIntegrateMagneticMoment) m_magneticMoments.SetSize(g_iGesAtomCount); m_p3DF = NULL; //m_saveTotalIntegrals = true; if (g_bAdvanced2) { m_saveTotalIntegrals = AskYesNo("\n Save total cube integrals in each step (y/n)? [no] ", false); m_bSaveAtomIntegrals = AskYesNo(" Save atomar/molecular integrals in each step (y/n)? [no] ",false); } else { m_saveTotalIntegrals = false; m_bSaveAtomIntegrals = false; } if (m_saveTotalIntegrals) m_totalIntegralFile = OpenFileWrite("vori_integrals.csv", false); if (m_bSaveAtomIntegrals) { m_fAtomIntegralFile = OpenFileWrite("vori_atomar_integrals.csv", true); mfprintf(m_fAtomIntegralFile,"#Step; AtomID; Label; Charge; ElDipX; ElDipY; ElDipZ; ElQuadXX; ElQuadXY; ElQuadXZ; ElQuadYX; ElQuadYY; ElQuadYZ; ElQuadZX; ElQuadZY; ElQuadZZ; ElCurrX; ElCurrY; ElCurrZ; MagDipX; MagDipY; MagDipZ\n"); g_fMolIntegralFile = OpenFileWrite("vori_molecular_integrals.csv", true); mfprintf(g_fMolIntegralFile,"#Step; Molecule; SingleMolecule; Charge; ElDipX; ElDipY; ElDipZ; ElQuadXX; ElQuadXY; ElQuadXZ; ElQuadYX; ElQuadYY; ElQuadYZ; ElQuadZX; ElQuadZY; ElQuadZZ; ElCurrX; ElCurrY; ElCurrZ; MagDipX; MagDipY; MagDipZ\n"); } delete t; mprintf(WHITE,"\n<<< End of Voronoi Integration Functions <<<\n\n"); return true; } void CTetraPak::ProcessStep(CTimeStep *ts, bool verbose) { int z; double su; CTimeStep temp; double integralFactor; if (g_bBoxNonOrtho) { integralFactor = g_fCubeXVector[0] * g_fCubeYVector[1] * g_fCubeZVector[2] + g_fCubeXVector[1] * g_fCubeYVector[2] * g_fCubeZVector[0] + g_fCubeXVector[2] * g_fCubeYVector[0] * g_fCubeZVector[1] - g_fCubeXVector[0] * g_fCubeYVector[2] * g_fCubeZVector[1] - g_fCubeXVector[1] * g_fCubeYVector[0] * g_fCubeZVector[2] - g_fCubeXVector[2] * g_fCubeYVector[1] * g_fCubeZVector[0]; } else { integralFactor = g_fCubeXStep * g_fCubeYStep * g_fCubeZStep; } if (m_bVoronoiCharges) { temp.CopyFrom(ts); temp.FoldAtomsPositive(); if (g_bVoroIntegrateCharge) { m_faCharge.SetSize(g_iGesAtomCount); ts->m_faCharge.SetSize(g_iGesAtomCount); } if (g_bVoroIntegrateDipoleMoment) { m_moments.SetSize(g_iGesAtomCount); ts->m_dipoleMoments.SetSize(g_iGesAtomCount); } if (g_bVoroIntegrateQuadrupoleMoment) { m_maQuadTensor.resize(g_iGesAtomCount); ts->m_maQuadTensor.resize(g_iGesAtomCount); } if (g_bVoroIntegrateTotalCurrent) { m_totalCurrent.SetSize(g_iGesAtomCount); ts->m_totalCurrents.SetSize(g_iGesAtomCount); } if (g_bVoroIntegrateMagneticMoment) { m_magneticMoments.SetSize(g_iGesAtomCount); ts->m_magneticDipoleMoments.SetSize(g_iGesAtomCount); } // fseek(m_fCubePipe,0,SEEK_SET); if ((g_iTrajFormat == 5) || (g_iTrajFormat == 7)) { m_p3DF = ts->m_pVolumetricData; if (m_saveTotalIntegrals || verbose) { su = 0; for (z=0;zm_iRes[0]*m_p3DF->m_iRes[1]*m_p3DF->m_iRes[2];z++) su += m_p3DF->m_pBin[z]; // double totCharge = -su * g_fCubeXStep*g_fCubeYStep*g_fCubeZStep; m_totCharge = -su * integralFactor; m_totChargeElec = m_totCharge; m_totChargeCore = 0; if (g_bVoroIntegrateCharge) { int i; for (i = 0; i < g_iGesAtomCount; i++) { m_totCharge += ((CAtom *)g_oaAtoms[g_waAtomRealElement[i]])->m_fCharge; m_totChargeCore += ((CAtom *)g_oaAtoms[g_waAtomRealElement[i]])->m_fCharge; } } double totCharge = -su * integralFactor; m_totDip[0] = 0; m_totDip[1] = 0; m_totDip[2] = 0; if (g_bVoroIntegrateDipoleMoment) { int i, j, k; for (i = 0; i < m_p3DF->m_iRes[0]; i++) { for (j = 0; j < m_p3DF->m_iRes[1]; j++) { for (k = 0; k < m_p3DF->m_iRes[2]; k++) { double x, y, fz; if (g_bBoxNonOrtho) { x = ((double)i * g_fCubeXVector[0] + (double)j * g_fCubeYVector[0] + (double)k * g_fCubeZVector[0]) * LEN_AU2PM; y = ((double)i * g_fCubeXVector[1] + (double)j * g_fCubeYVector[1] + (double)k * g_fCubeZVector[1]) * LEN_AU2PM; fz = ((double)i * g_fCubeXVector[2] + (double)j * g_fCubeYVector[2] + (double)k * g_fCubeZVector[2]) * LEN_AU2PM; } else { x = (double)i * g_fCubeXStep * LEN_AU2PM; y = (double)j * g_fCubeYStep * LEN_AU2PM; fz = (double)k * g_fCubeZStep * LEN_AU2PM; } m_totDip[0] -= x * m_p3DF->m_pBin[i + j * m_p3DF->m_iRes[0] + k * m_p3DF->m_iRes[1] * m_p3DF->m_iRes[0]]; m_totDip[1] -= y * m_p3DF->m_pBin[i + j * m_p3DF->m_iRes[0] + k * m_p3DF->m_iRes[1] * m_p3DF->m_iRes[0]]; m_totDip[2] -= fz * m_p3DF->m_pBin[i + j * m_p3DF->m_iRes[0] + k * m_p3DF->m_iRes[1] * m_p3DF->m_iRes[0]]; } } } for (i = 0; i < 3; i++) { m_totDip[i] *= integralFactor; m_totDipElec[i] = m_totDip[i]; m_totDipCore[i] = 0; } for (i = 0; i < g_iGesAtomCount; i++) { for (j = 0; j < 3; j++) { m_totDip[j] += ((CAtom *)g_oaAtoms[g_waAtomRealElement[i]])->m_fCharge * temp.m_vaCoords[i][j]; m_totDipCore[j] += ((CAtom *)g_oaAtoms[g_waAtomRealElement[i]])->m_fCharge * temp.m_vaCoords[i][j]; } } for (i = 0; i < 3; i++) { m_totDip[i] *= DIP_EPM2DEBYE; m_totDipElec[i] *= DIP_EPM2DEBYE; m_totDipCore[i] *= DIP_EPM2DEBYE; } } // double qref[3] = { 768.891, 834.292, 823.993 }; for (int i=0;i<9;i++) m_totQuad[i] = 0; m_qRef[0] = 0; m_qRef[1] = 0; m_qRef[2] = 0; if (g_bVoroIntegrateQuadrupoleMoment) { int i, j, k, za, zb; double pos[3], tf[9]/*, lensqr*/; for (i = 0; i < m_p3DF->m_iRes[0]; i++) { for (j = 0; j < m_p3DF->m_iRes[1]; j++) { for (k = 0; k < m_p3DF->m_iRes[2]; k++) { if (g_bBoxNonOrtho) { pos[0] = ((double)i * g_fCubeXVector[0] + (double)j * g_fCubeYVector[0] + (double)k * g_fCubeZVector[0]) * LEN_AU2PM - m_qRef[0]; pos[1] = ((double)i * g_fCubeXVector[1] + (double)j * g_fCubeYVector[1] + (double)k * g_fCubeZVector[1]) * LEN_AU2PM - m_qRef[1]; pos[2] = ((double)i * g_fCubeXVector[2] + (double)j * g_fCubeYVector[2] + (double)k * g_fCubeZVector[2]) * LEN_AU2PM - m_qRef[2]; } else { pos[0] = (double)i * g_fCubeXStep * LEN_AU2PM - m_qRef[0]; pos[1] = (double)j * g_fCubeYStep * LEN_AU2PM - m_qRef[1]; pos[2] = (double)k * g_fCubeZStep * LEN_AU2PM - m_qRef[2]; } // lensqr = pos[0]*pos[0] + pos[1]*pos[1] + pos[2]*pos[2]; for (za=0;za<3;za++) for (zb=0;zb<3;zb++) tf[za*3+zb] = 1.0*pos[za]*pos[zb]; /* tf[za*3+zb] = 3.0*pos[za]*pos[zb]; tf[0] -= lensqr; tf[4] -= lensqr; tf[8] -= lensqr;*/ for (za=0;za<9;za++) m_totQuad[za] -= tf[za] * m_p3DF->m_pBin[i + j * m_p3DF->m_iRes[0] + k * m_p3DF->m_iRes[1] * m_p3DF->m_iRes[0]]; } } } for (i = 0; i < 9; i++) { m_totQuad[i] *= integralFactor; m_totQuadElec[i] = m_totQuad[i]; m_totQuadCore[i] = 0; } for (i = 0; i < g_iGesAtomCount; i++) { pos[0] = temp.m_vaCoords[i][0] - m_qRef[0]; pos[1] = temp.m_vaCoords[i][1] - m_qRef[1]; pos[2] = temp.m_vaCoords[i][2] - m_qRef[2]; // lensqr = pos[0]*pos[0] + pos[1]*pos[1] + pos[2]*pos[2]; for (za=0;za<3;za++) for (zb=0;zb<3;zb++) tf[za*3+zb] = 1.0*pos[za]*pos[zb]; /* tf[za*3+zb] = 3.0*pos[za]*pos[zb]; tf[0] -= lensqr; tf[4] -= lensqr; tf[8] -= lensqr;*/ for (za=0;za<9;za++) { m_totQuad[za] += tf[za] * ((CAtom *)g_oaAtoms[g_waAtomRealElement[i]])->m_fCharge; m_totQuadCore[za] += tf[za] * ((CAtom *)g_oaAtoms[g_waAtomRealElement[i]])->m_fCharge; } } for (i = 0; i < 9; i++) { m_totQuad[i] *= DIP_EPM2DEBYE/100.0; m_totQuadElec[i] *= DIP_EPM2DEBYE/100.0; m_totQuadCore[i] *= DIP_EPM2DEBYE/100.0; } } m_totCurrent[0] = 0; m_totCurrent[1] = 0; m_totCurrent[2] = 0; if (g_bVoroIntegrateTotalCurrent && ts->m_pCurrentDensity != NULL) { int i, j, k; for (i = 0; i < m_p3DF->m_iRes[0]; i++) { for (j = 0; j < m_p3DF->m_iRes[1]; j++) { for (k = 0; k < m_p3DF->m_iRes[2]; k++) { m_totCurrent[0] += ts->m_pCurrentDensity->GetAt(i * 3 + j * m_p3DF->m_iRes[0] * 3 + k * m_p3DF->m_iRes[1] * m_p3DF->m_iRes[0] * 3); m_totCurrent[1] += ts->m_pCurrentDensity->GetAt(i * 3 + j * m_p3DF->m_iRes[0] * 3 + k * m_p3DF->m_iRes[1] * m_p3DF->m_iRes[0] * 3 + 1); m_totCurrent[2] += ts->m_pCurrentDensity->GetAt(i * 3 + j * m_p3DF->m_iRes[0] * 3 + k * m_p3DF->m_iRes[1] * m_p3DF->m_iRes[0] * 3 + 2); } } } for (i = 0; i < 3; i++) { m_totCurrent[i] *= integralFactor * CURR_AUFS2MBPM; m_totCurrentElec[i] = m_totCurrent[i]; m_totCurrentCore[i] = 0; } for (i = 0; i < g_iGesAtomCount; i++) { for (j = 0; j < 3; j++) { m_totCurrent[j] += ((CAtom *)g_oaAtoms[g_waAtomRealElement[i]])->m_fCharge * temp.m_vaVelocities[i][j] * CURR_EMS2MBPM; m_totCurrentCore[j] += ((CAtom *)g_oaAtoms[g_waAtomRealElement[i]])->m_fCharge * temp.m_vaVelocities[i][j] * CURR_EMS2MBPM; } } } m_totMagMom[0] = 0; m_totMagMom[1] = 0; m_totMagMom[2] = 0; if (g_bVoroIntegrateMagneticMoment && ts->m_pCurrentDensity != NULL) { int i, j, k; for (i = 0; i < m_p3DF->m_iRes[0]; i++) { // double x = (double)i * g_fCubeXStep * LEN_AU2PM; for (j = 0; j < m_p3DF->m_iRes[1]; j++) { // double y = (double)j * g_fCubeYStep * LEN_AU2PM; for (k = 0; k < m_p3DF->m_iRes[2]; k++) { double x, y, fz; if (g_bBoxNonOrtho) { x = ((double)i * g_fCubeXVector[0] + (double)j * g_fCubeYVector[0] + (double)k * g_fCubeZVector[0]) * LEN_AU2PM; y = ((double)i * g_fCubeXVector[1] + (double)j * g_fCubeYVector[1] + (double)k * g_fCubeZVector[1]) * LEN_AU2PM; fz = ((double)i * g_fCubeXVector[2] + (double)j * g_fCubeYVector[2] + (double)k * g_fCubeZVector[2]) * LEN_AU2PM; } else { x = (double)i * g_fCubeXStep * LEN_AU2PM; y = (double)j * g_fCubeYStep * LEN_AU2PM; fz = (double)k * g_fCubeZStep * LEN_AU2PM; } // double z = (double)k * g_fCubeZStep * LEN_AU2PM; m_totMagMom[0] += y * ts->m_pCurrentDensity->GetAt(i * 3 + j * m_p3DF->m_iRes[0] * 3 + k * m_p3DF->m_iRes[1] * m_p3DF->m_iRes[0] * 3 + 2); m_totMagMom[0] -= fz * ts->m_pCurrentDensity->GetAt(i * 3 + j * m_p3DF->m_iRes[0] * 3 + k * m_p3DF->m_iRes[1] * m_p3DF->m_iRes[0] * 3 + 1); m_totMagMom[1] += fz * ts->m_pCurrentDensity->GetAt(i * 3 + j * m_p3DF->m_iRes[0] * 3 + k * m_p3DF->m_iRes[1] * m_p3DF->m_iRes[0] * 3); m_totMagMom[1] -= x * ts->m_pCurrentDensity->GetAt(i * 3 + j * m_p3DF->m_iRes[0] * 3 + k * m_p3DF->m_iRes[1] * m_p3DF->m_iRes[0] * 3 + 2); m_totMagMom[2] += x * ts->m_pCurrentDensity->GetAt(i * 3 + j * m_p3DF->m_iRes[0] * 3 + k * m_p3DF->m_iRes[1] * m_p3DF->m_iRes[0] * 3 + 1); m_totMagMom[2] -= y * ts->m_pCurrentDensity->GetAt(i * 3 + j * m_p3DF->m_iRes[0] * 3 + k * m_p3DF->m_iRes[1] * m_p3DF->m_iRes[0] * 3); } } } for (i = 0; i < 3; i++) { m_totMagMom[i] *= 0.5 * integralFactor * MAG_AUPMFS2MB; m_totMagMomElec[i] = m_totMagMom[i]; m_totMagMomCore[i] = 0; } for (i = 0; i < g_iGesAtomCount; i++) { m_totMagMom[0] += 0.5 * ((CAtom *)g_oaAtoms[g_waAtomRealElement[i]])->m_fCharge * temp.m_vaCoords[i][1] * temp.m_vaVelocities[i][2] * MAG_EPMMS2MB; m_totMagMom[0] -= 0.5 * ((CAtom *)g_oaAtoms[g_waAtomRealElement[i]])->m_fCharge * temp.m_vaCoords[i][2] * temp.m_vaVelocities[i][1] * MAG_EPMMS2MB; m_totMagMom[1] += 0.5 * ((CAtom *)g_oaAtoms[g_waAtomRealElement[i]])->m_fCharge * temp.m_vaCoords[i][2] * temp.m_vaVelocities[i][0] * MAG_EPMMS2MB; m_totMagMom[1] -= 0.5 * ((CAtom *)g_oaAtoms[g_waAtomRealElement[i]])->m_fCharge * temp.m_vaCoords[i][0] * temp.m_vaVelocities[i][2] * MAG_EPMMS2MB; m_totMagMom[2] += 0.5 * ((CAtom *)g_oaAtoms[g_waAtomRealElement[i]])->m_fCharge * temp.m_vaCoords[i][0] * temp.m_vaVelocities[i][1] * MAG_EPMMS2MB; m_totMagMom[2] -= 0.5 * ((CAtom *)g_oaAtoms[g_waAtomRealElement[i]])->m_fCharge * temp.m_vaCoords[i][1] * temp.m_vaVelocities[i][0] * MAG_EPMMS2MB; m_totMagMomCore[0] += 0.5 * ((CAtom *)g_oaAtoms[g_waAtomRealElement[i]])->m_fCharge * temp.m_vaCoords[i][1] * temp.m_vaVelocities[i][2] * MAG_EPMMS2MB; m_totMagMomCore[0] -= 0.5 * ((CAtom *)g_oaAtoms[g_waAtomRealElement[i]])->m_fCharge * temp.m_vaCoords[i][2] * temp.m_vaVelocities[i][1] * MAG_EPMMS2MB; m_totMagMomCore[1] += 0.5 * ((CAtom *)g_oaAtoms[g_waAtomRealElement[i]])->m_fCharge * temp.m_vaCoords[i][2] * temp.m_vaVelocities[i][0] * MAG_EPMMS2MB; m_totMagMomCore[1] -= 0.5 * ((CAtom *)g_oaAtoms[g_waAtomRealElement[i]])->m_fCharge * temp.m_vaCoords[i][0] * temp.m_vaVelocities[i][2] * MAG_EPMMS2MB; m_totMagMomCore[2] += 0.5 * ((CAtom *)g_oaAtoms[g_waAtomRealElement[i]])->m_fCharge * temp.m_vaCoords[i][0] * temp.m_vaVelocities[i][1] * MAG_EPMMS2MB; m_totMagMomCore[2] -= 0.5 * ((CAtom *)g_oaAtoms[g_waAtomRealElement[i]])->m_fCharge * temp.m_vaCoords[i][1] * temp.m_vaVelocities[i][0] * MAG_EPMMS2MB; } } if (verbose) { mprintf(" Volumetric electron density data read from cube file:\n"); mprintf(" Cube file has %d x %d x %d grid points.\n",m_p3DF->m_iRes[0],m_p3DF->m_iRes[1],m_p3DF->m_iRes[2]); // mprintf(" Sum is %.3f, equals %.6f electrons.\n",su,su*(g_fBoxX/100.0/0.529177249/m_p3DF->m_iRes[0])*(g_fBoxY/100.0/0.529177249/m_p3DF->m_iRes[1])*(g_fBoxZ/100.0/0.529177249/m_p3DF->m_iRes[2])); // mprintf(" Sum is %.3f, equals %.6f electrons.\n",su,su*g_fCubeXStep*g_fCubeYStep*g_fCubeZStep); mprintf(" Sum is %.3f, equals %.6f electrons.\n",su,su*integralFactor); if (g_bVoroIntegrateCharge) mprintf(" Total charge is %.6f.\n", m_totCharge); if (g_bVoroIntegrateDipoleMoment) mprintf(" Total dipole moment is ( %.6f | %.6f | %.6f ) Debye (absolute value %.6f).\n", m_totDip[0], m_totDip[1], m_totDip[2],sqrt(m_totDip[0]*m_totDip[0]+m_totDip[1]*m_totDip[1]+m_totDip[2]*m_totDip[2])); if (g_bVoroIntegrateQuadrupoleMoment) { mprintf(" Total quadrupole tensor is\n"); mprintf(" %12.6f %12.6f %12.6f\n",m_totQuad[0],m_totQuad[1],m_totQuad[2]); mprintf(" %12.6f %12.6f %12.6f\n",m_totQuad[3],m_totQuad[4],m_totQuad[5]); mprintf(" %12.6f %12.6f %12.6f\n",m_totQuad[6],m_totQuad[7],m_totQuad[8]); mprintf(" Trace: %12.6f\n",m_totQuad[0]+m_totQuad[4]+m_totQuad[8]); mprintf(" Reference point: %12.6f %12.6f %12.6f\n",m_qRef[0],m_qRef[1],m_qRef[2]); } if (g_bVoroIntegrateTotalCurrent && ts->m_pCurrentDensity != NULL) mprintf(" Total current is ( %.6f | %.6f | %.6f ) Bohr magneton * pm^-1.\n", m_totCurrent[0], m_totCurrent[1], m_totCurrent[2]); if (g_bVoroIntegrateMagneticMoment && ts->m_pCurrentDensity != NULL) mprintf(" Total magnetic moment is ( %.6f | %.6f | %.6f ) Bohr magneton.\n", m_totMagMom[0], m_totMagMom[1], m_totMagMom[2]); } if (m_saveTotalIntegrals && (m_totalIntegralFile != NULL)) { fprintf(m_totalIntegralFile, "%lu", g_iSteps); if (g_bVoroIntegrateCharge) fprintf(m_totalIntegralFile, "; %.8G", totCharge); if (g_bVoroIntegrateDipoleMoment) fprintf(m_totalIntegralFile, "; %.8G; %.8G; %.8G", m_totDip[0], m_totDip[1], m_totDip[2]); if (g_bVoroIntegrateTotalCurrent) fprintf(m_totalIntegralFile, "; %.8G; %.8G; %.8G", m_totCurrent[0], m_totCurrent[1], m_totCurrent[2]); if (g_bVoroIntegrateMagneticMoment) fprintf(m_totalIntegralFile, "; %.8G; %.8G; %.8G", m_totMagMom[0], m_totMagMom[1], m_totMagMom[2]); fprintf(m_totalIntegralFile, "\n"); } } } else { if (m_p3DF == NULL) { m_p3DF = new C3DF(); m_p3DF->ReadCube(m_fCubePipe,verbose,true); } else m_p3DF->ReadCube(m_fCubePipe,verbose,false); } for (z=0;zm_iRes[0])*(g_fBoxY/100.0/0.529177249/m_p3DF->m_iRes[1])*(g_fBoxZ/100.0/0.529177249/m_p3DF->m_iRes[2]); // m_faCharge[z] *= g_fCubeXStep*g_fCubeYStep*g_fCubeZStep; m_faCharge[z] *= integralFactor; m_faCharge[z] += ((CAtom *)g_oaAtoms[g_waAtomRealElement[z]])->m_fCharge; if (g_bVoroIntegrateCharge) ts->m_faCharge[z] = m_faCharge[z]; // ts->m_dipoleMoments[z] = m_moments[z] * 1000.0 * (g_fBoxX/100.0/0.529177249/m_p3DF->m_iRes[0])*(g_fBoxY/100.0/0.529177249/m_p3DF->m_iRes[1])*(g_fBoxZ/100.0/0.529177249/m_p3DF->m_iRes[2]); if (g_bVoroIntegrateDipoleMoment) // ts->m_dipoleMoments[z] = m_moments[z] * 1000.0 * g_fCubeXStep*g_fCubeYStep*g_fCubeZStep; // Conversion to e*pm ts->m_dipoleMoments[z] = m_moments[z] * 1000.0 * integralFactor; // Conversion to e*pm if (g_bVoroIntegrateQuadrupoleMoment) ts->m_maQuadTensor[z] = m_maQuadTensor[z] * integralFactor; // Unit is e*nm^2 if (g_bVoroIntegrateTotalCurrent) // ts->m_totalCurrents[z] = m_totalCurrent[z] * g_fCubeXStep * g_fCubeYStep * g_fCubeZStep * CURR_AUFS2MBPM; // Conversion to Bohr magnetons*pm^-1 ts->m_totalCurrents[z] = m_totalCurrent[z] * integralFactor * CURR_AUFS2MBPM; // Conversion to Bohr magnetons*pm^-1 if (g_bVoroIntegrateMagneticMoment) // ts->m_magneticDipoleMoments[z] = m_magneticMoments[z] * 0.5 * g_fCubeXStep * g_fCubeYStep * g_fCubeZStep * 1000.0 * MAG_AUPMFS2MB; // Conversion to Bohr magnetons ts->m_magneticDipoleMoments[z] = m_magneticMoments[z] * 0.5 * integralFactor * 1000.0 * MAG_AUPMFS2MB; // Conversion to Bohr magnetons // mprintf("%s %f\n", ((CAtom*)g_oaAtoms[g_waAtomRealElement[z]])->m_sName, m_faCharge[z]); if (m_bSaveAtomIntegrals && !verbose) { mfprintf(m_fAtomIntegralFile,"%5lu; %6d; %-3s",g_iSteps+1,z+1,(const char*)((CAtom*)g_oaAtoms[g_waAtomRealElement[z]])->m_sName); if (g_bVoroIntegrateCharge) mfprintf(m_fAtomIntegralFile,"; %16.10f",ts->m_faCharge[z]); else mfprintf(m_fAtomIntegralFile,"; "); if (g_bVoroIntegrateDipoleMoment) mfprintf(m_fAtomIntegralFile,"; %16.10f; %16.10f; %16.10f",ts->m_dipoleMoments[z][0],ts->m_dipoleMoments[z][1],ts->m_dipoleMoments[z][2]); else mfprintf(m_fAtomIntegralFile,"; ; ; "); if (g_bVoroIntegrateQuadrupoleMoment) mfprintf(m_fAtomIntegralFile,"; %17.10f; %17.10f; %17.10f; %17.10f; %17.10f; %17.10f; %17.10f; %17.10f; %17.10f",ts->m_maQuadTensor[z][0],ts->m_maQuadTensor[z][1],ts->m_maQuadTensor[z][2],ts->m_maQuadTensor[z][3],ts->m_maQuadTensor[z][4],ts->m_maQuadTensor[z][5],ts->m_maQuadTensor[z][6],ts->m_maQuadTensor[z][7],ts->m_maQuadTensor[z][8]); else mfprintf(m_fAtomIntegralFile,"; ; ; ; ; ; ; ; ; "); if (g_bVoroIntegrateTotalCurrent) mfprintf(m_fAtomIntegralFile,"; %16.10f; %16.10f; %16.10f",ts->m_totalCurrents[z][0],ts->m_totalCurrents[z][1],ts->m_totalCurrents[z][2]); else mfprintf(m_fAtomIntegralFile,"; ; ; "); if (g_bVoroIntegrateMagneticMoment) mfprintf(m_fAtomIntegralFile,"; %16.10f; %16.10f; %16.10f",ts->m_magneticDipoleMoments[z][0],ts->m_magneticDipoleMoments[z][1],ts->m_magneticDipoleMoments[z][2]); else mfprintf(m_fAtomIntegralFile,"; ; ; "); mfprintf(m_fAtomIntegralFile,"\n"); } } // if (m_saveAtomCharges || m_saveMolCharges) { // if (m_saveAtomCharges) // fprintf(m_atomChargeFile, "%.2f;", g_iSteps * g_fTimestepLength * g_iStride); // if (m_saveMolCharges) // fprintf(m_molChargeFile, "%.2f;", g_iSteps * g_fTimestepLength * g_iStride); // // int i, j, k, l; // for (i = 0; i < g_oaMolecules.GetSize(); i++) { // CMolecule *m = (CMolecule *)g_oaMolecules[i]; // for (j = 0; j < m->m_laSingleMolIndex.GetSize(); j++) { // CSingleMolecule *sm = (CSingleMolecule *)g_oaSingleMolecules[m->m_laSingleMolIndex[j]]; // double sum = 0.0f; // for (k = 0; k < m->m_baAtomIndex.GetSize(); k++) { // if (m->m_baAtomIndex[k] == g_iVirtAtomType) // continue; // for (l = 0; l < ((CxIntArray *)sm->m_oaAtomOffset[k])->GetSize(); l++) { // if (m_saveAtomCharges) { // fprintf(m_atomChargeFile, " %.6f;", m_faCharge[((CxIntArray *)sm->m_oaAtomOffset[k])->GetAt(l)]); // } // sum += m_faCharge[((CxIntArray *)sm->m_oaAtomOffset[k])->GetAt(l)]; // } // } // if (m_saveMolCharges) { // fprintf(m_molChargeFile, " %.6f;", sum); // } // } // } // // if (m_saveAtomCharges) // fprintf(m_atomChargeFile, "\n"); // if (m_saveMolCharges) // fprintf(m_molChargeFile, "\n"); // } } } bool CTetraPak::BuildVoronoi(CTimeStep *ts, bool verbose, bool sanity, bool sanityall) { voronoicell_neighbor c; container_periodic_poly *con; int ijk, q, z, z2, fc, id, ti, cc; double *pp, tx, ty, tz; CxDVector3 vec1; vector nb; vector fv; vector fo; vector fare; CTetraFace *fa; double tfx, tfy, tfz, lastvert[2]; double mi[2], ma[2]; bool b; b = true; // mprintf("Container Size: %f | %f | %f.\n",g_fBoxX/1000.0,0,g_fBoxY/1000.0,0,0,g_fBoxZ/1000.0); // try { con = new container_periodic_poly(g_fBoxX/1000.0,0,g_fBoxY/1000.0,0,0,g_fBoxZ/1000.0,g_pVoroWrapper->m_iBlocksX,g_pVoroWrapper->m_iBlocksY,g_pVoroWrapper->m_iBlocksZ,g_iVoroMemory); } catch(...) { con = NULL; } // mprintf(GREEN, "%.20g %.20g %.20g\n", m_p3DF->m_fMaxVal[0]/1000.0, m_p3DF->m_fMaxVal[1]/1000.0, m_p3DF->m_fMaxVal[2]/1000.0); if (g_bBoxNonOrtho) { if (g_mCubeCell(0, 1) != 0 || g_mCubeCell(0, 2) != 0 || g_mCubeCell(1, 2) != 0) { eprintf("This cell matrix cannot be handled by the Voro++ library.\nThe first cell vector has to be parallel to the x axis and the second cell vector has to be in the xy plane.\n"); abort(); } if (sanity) { mprintf("\n Using the following cell matrix for Voronoi tessellation:\n"); mprintf(" A ( %12.6f | %12.6f | %12.6f )\n",g_mCubeCell(0,0),g_mCubeCell(0,1),g_mCubeCell(0,2)); mprintf(" B ( %12.6f | %12.6f | %12.6f )\n",g_mCubeCell(1,0),g_mCubeCell(1,1),g_mCubeCell(1,2)); mprintf(" C ( %12.6f | %12.6f | %12.6f )\n\n",g_mCubeCell(2,0),g_mCubeCell(2,1),g_mCubeCell(2,2)); } try { con = new container_periodic_poly(g_mCubeCell(0, 0) / 1000.0, g_mCubeCell(1, 0) / 1000.0, g_mCubeCell(1, 1) / 1000.0, g_mCubeCell(2, 0) / 1000.0, g_mCubeCell(2, 1) / 1000.0, g_mCubeCell(2, 2) / 1000.0, g_pVoroWrapper->m_iBlocksX, g_pVoroWrapper->m_iBlocksY, g_pVoroWrapper->m_iBlocksZ, g_iVoroMemory); } catch(...) { con = NULL; } // mprintf(GREEN, "%.20g %.20g %.20g %.20g %.20g %.20g\n", g_mCubeCell(0, 0) / 1000.0, g_mCubeCell(1, 0) / 1000.0, g_mCubeCell(1, 1) / 1000.0, g_mCubeCell(2, 0) / 1000.0, g_mCubeCell(2, 1) / 1000.0, g_mCubeCell(2, 2) / 1000.0); } else { if (sanity) { mprintf("\n Using the following orthorhombic cell dimensions for Voronoi tessellation:\n"); mprintf(" ( %12.6f | %12.6f | %12.6f )\n\n",m_p3DF->m_fMaxVal[0],m_p3DF->m_fMaxVal[1],m_p3DF->m_fMaxVal[2]); } try { con = new container_periodic_poly(m_p3DF->m_fMaxVal[0]/1000.0,0,m_p3DF->m_fMaxVal[1]/1000.0,0,0,m_p3DF->m_fMaxVal[2]/1000.0,g_pVoroWrapper->m_iBlocksX,g_pVoroWrapper->m_iBlocksY,g_pVoroWrapper->m_iBlocksZ,g_iVoroMemory); } catch(...) { con = NULL; } // mprintf(GREEN, "%.20g %.20g %.20g\n", m_p3DF->m_fMaxVal[0]/1000.0, m_p3DF->m_fMaxVal[1]/1000.0, m_p3DF->m_fMaxVal[2]/1000.0); // mprintf(GREEN, "%.20g %.20g %.20g\n", g_fCubeXStep, g_fCubeYStep, g_fCubeZStep); } if (con == NULL) NewException((double)sizeof(container_periodic_poly),__FILE__,__LINE__,__PRETTY_FUNCTION__); for (z=0;zput(z,ts->m_vaCoords[z][0]/1000.0,ts->m_vaCoords[z][1]/1000.0,ts->m_vaCoords[z][2]/1000.0,g_faVoronoiRadii[z]/1000.0); //mprintf(GREEN, "%d %.20g %.20g %.20g %.20g\n", z+1, ts->m_vaCoords[z][0]/1000.0, ts->m_vaCoords[z][1]/1000.0, ts->m_vaCoords[z][2]/1000.0, g_faVoronoiRadii[z]/1000.0); } c_loop_all_periodic vl(*con); tfx = 0; tfy = 0; if (sanity) { if (sanityall) mprintf(" Sanity check:"); else mprintf("\n Voronoi decomposition and integration over grid:\n"); } if (verbose) mprintf(WHITE," ["); m_fRayCount = 0; m_fRayHisto[0] = 0; m_fRayHisto[1] = 0; m_fRayHisto[2] = 0; m_fRayHisto[3] = 0; cc = 0; if (vl.start()) { do { if (verbose) if (fmod(cc,g_iGesAtomCount/60.0) < 1.0) mprintf(WHITE,"#"); if (con->compute_cell(c,vl)) { ijk = vl.ijk; q = vl.q; pp = con->p[ijk]+con->ps*q; id = con->id[ijk][q]; // if (id == 103) { // mprintf("\n****************************************************************************************************\n"); // mprintf("*** Cell %3d *************************************************************************************\n",id); // mprintf("****************************************************************************************************\n"); // mprintf("Center: ( %.20G | %.20G | %.20G ).\n", pp[0], pp[1], pp[2]); // CxDVector3 v(pp[0], pp[1], pp[2]); // v *= 1000.0; // v = g_mBoxToOrtho * v; // mprintf("Center2: ( %.20G | %.20G | %.20G ).\n", v[0], v[1], v[2]); // } m_iFaces = c.number_of_faces(); c.face_vertices(fv); c.neighbors(nb); c.face_areas(fare); c.face_orders(fo); // mprintf("Found %d faces.\n",m_iFaces); for (z=m_oaFaces.GetSize();zm_fMin[0] = 1.0E20; fa->m_fMin[1] = 1.0E20; fa->m_fMax[0] = -1.0E20; fa->m_fMax[1] = -1.0E20; tx = 0; ty = 0; tz = 0; for (z2=0;z2m_fMin[0] > coord[1]) fa->m_fMin[0] = coord[1]; if (fa->m_fMax[0] < coord[1]) fa->m_fMax[0] = coord[1]; if (fa->m_fMin[1] > coord[2]) fa->m_fMin[1] = coord[2]; if (fa->m_fMax[1] < coord[2]) fa->m_fMax[1] = coord[2]; } else { if (fa->m_fMin[0] > tfy) fa->m_fMin[0] = tfy; if (fa->m_fMax[0] < tfy) fa->m_fMax[0] = tfy; if (fa->m_fMin[1] > tfz) fa->m_fMin[1] = tfz; if (fa->m_fMax[1] < tfz) fa->m_fMax[1] = tfz; } } // mprintf("Sum t: ( %20G | %20G | %20G ).\n",tx,ty,tz); /* if ((tx != 0) && (fabs(tx) < 1.0E-14)) tx = 0; if ((ty != 0) && (fabs(ty) < 1.0E-14)) ty = 0; if ((tz != 0) && (fabs(tz) < 1.0E-14)) tz = 0;*/ // mprintf("Chopped t: ( %20G | %20G | %20G ).\n",tx,ty,tz); tx /= fc; ty /= fc; tz /= fc; // mprintf("Divided t: ( %20G | %20G | %20G ).\n",tx,ty,tz); if (fa->m_fMin[0] < mi[0]) mi[0] = fa->m_fMin[0]; if (fa->m_fMax[0] > ma[0]) ma[0] = fa->m_fMax[0]; if (fa->m_fMin[1] < mi[1]) mi[1] = fa->m_fMin[1]; if (fa->m_fMax[1] > ma[1]) ma[1] = fa->m_fMax[1]; fa->m_vCenter[0] = tx; fa->m_vCenter[1] = ty; fa->m_vCenter[2] = tz; fa->m_vSpan1[0] = *pp+c.pts[fv[ti+1]*3]*0.5; fa->m_vSpan1[1] = pp[1]+c.pts[fv[ti+1]*3+1]*0.5; fa->m_vSpan1[2] = pp[2]+c.pts[fv[ti+1]*3+2]*0.5; vec1[0] = *pp+c.pts[fv[ti+2]*3]*0.5; vec1[1] = pp[1]+c.pts[fv[ti+2]*3+1]*0.5; vec1[2] = pp[2]+c.pts[fv[ti+2]*3+2]*0.5; // if (id == 103) // mprintf("m_vSpan1: ( %20G | %20G | %20G ).\n",fa->m_vSpan1[0],fa->m_vSpan1[1],fa->m_vSpan1[2]); // mprintf("vec1: ( %20G | %20G | %20G ).\n",vec1[0],vec1[1],vec1[2]); fa->m_vSpan1 -= fa->m_vCenter; vec1 -= fa->m_vCenter; // if (id == 103) // mprintf("m_vSpan1: ( %20G | %20G | %20G ).\n",fa->m_vSpan1[0],fa->m_vSpan1[1],fa->m_vSpan1[2]); fa->m_vSpan1.Normalize(); fa->m_vSpan1.Chop(1.0E-14); // if (id == 103) // mprintf("m_vSpan1: ( %20G | %20G | %20G ).\n",fa->m_vSpan1[0],fa->m_vSpan1[1],fa->m_vSpan1[2]); /* if ((fa->m_vSpan1[0] != 0) && (fabs(fa->m_vSpan1[0]) < 1.0E-14)) fa->m_vSpan1[0] = 0; if ((fa->m_vSpan1[1] != 0) && (fabs(fa->m_vSpan1[1]) < 1.0E-14)) fa->m_vSpan1[1] = 0; if ((fa->m_vSpan1[2] != 0) && (fabs(fa->m_vSpan1[2]) < 1.0E-14)) fa->m_vSpan1[2] = 0;*/ // mprintf("m_vCenter: ( %20G | %20G | %20G ).\n",fa->m_vCenter[0],fa->m_vCenter[1],fa->m_vCenter[2]); // mprintf("(*) m_vSpan1: ( %20G | %20G | %20G ).\n",fa->m_vSpan1[0],fa->m_vSpan1[1],fa->m_vSpan1[2]); // mprintf("(*) vec1: ( %20G | %20G | %20G ).\n",vec1[0],vec1[1],vec1[2]); fa->m_vNormal = CrossP(fa->m_vSpan1,vec1); // if (id == 103) // mprintf("m_vNormal: ( %20G | %20G | %20G ).\n",fa->m_vNormal[0],fa->m_vNormal[1],fa->m_vNormal[2]); fa->m_vNormal.Normalize(); fa->m_vNormal.Chop(1.0E-14); // if (id == 103) // mprintf("m_vNormal: ( %20G | %20G | %20G ).\n",fa->m_vNormal[0],fa->m_vNormal[1],fa->m_vNormal[2]); // mprintf("Normal is ( %20G | %20G | %20G ).\n",fa->m_vNormal[0],fa->m_vNormal[1],fa->m_vNormal[2]); /* if ((fa->m_vNormal[0] != 0) && (fabs(fa->m_vNormal[0]) < 1.0E-14)) fa->m_vNormal[0] = 0; if ((fa->m_vNormal[1] != 0) && (fabs(fa->m_vNormal[1]) < 1.0E-14)) fa->m_vNormal[1] = 0; if ((fa->m_vNormal[2] != 0) && (fabs(fa->m_vNormal[2]) < 1.0E-14)) fa->m_vNormal[2] = 0;*/ // mprintf("Chopped normal is ( %20G | %20G | %20G ).\n",fa->m_vNormal[0],fa->m_vNormal[1],fa->m_vNormal[2]); fa->m_vSpan2 = CrossP(fa->m_vSpan1,fa->m_vNormal); // if (id == 103) // mprintf(GREEN, "span2: %.20g %.20g %.20g\n", fa->m_vSpan2[0], fa->m_vSpan2[1], fa->m_vSpan2[2]); fa->m_vSpan2.Normalize(); fa->m_vSpan2.Chop(1.0E-14); // if (id == 103) // mprintf(GREEN, "span2: %.20g %.20g %.20g\n", fa->m_vSpan2[0], fa->m_vSpan2[1], fa->m_vSpan2[2]); /* if ((fa->m_vSpan2[0] != 0) && (fabs(fa->m_vSpan2[0]) < 1.0E-14)) fa->m_vSpan2[0] = 0; if ((fa->m_vSpan2[1] != 0) && (fabs(fa->m_vSpan2[1]) < 1.0E-14)) fa->m_vSpan2[1] = 0; if ((fa->m_vSpan2[2] != 0) && (fabs(fa->m_vSpan2[2]) < 1.0E-14)) fa->m_vSpan2[2] = 0;*/ /* if (fabs(DotP(CxDVector3(1.0,0,0),fa->m_vNormal)) < 1.0e-10) { mprintf("## Error: Normal vector in Y-Z plane: %.20G.\n",DotP(CxDVector3(1.0,0,0),fa->m_vNormal)); mprintf(" Span1: %.20G %.20G %.20G\n",fa->m_vSpan1[0],fa->m_vSpan1[1],fa->m_vSpan1[2]); mprintf(" vec1: %.20G %.20G %.20G\n",vec1[0],vec1[1],vec1[2]); mprintf(" Normal: %.20G %.20G %.20G\n",fa->m_vNormal[0],fa->m_vNormal[1],fa->m_vNormal[2]); mprintf(" Span2: %.20G %.20G %.20G\n",fa->m_vSpan2[0],fa->m_vSpan2[1],fa->m_vSpan2[2]); } */ // fa->m_vSpan1.Normalize(); // fa->m_vSpan2.Normalize(); // fa->m_vNormal.Normalize(); // if (id == 103) { // mprintf(GREEN, "span1: %.20g %.20g %.20g\n", fa->m_vSpan1[0], fa->m_vSpan1[1], fa->m_vSpan1[2]); // mprintf(GREEN, "span2: %.20g %.20g %.20g\n", fa->m_vSpan2[0], fa->m_vSpan2[1], fa->m_vSpan2[2]); // mprintf(GREEN, "normal: %.20g %.20g %.20g\n", fa->m_vNormal[0], fa->m_vNormal[1], fa->m_vNormal[2]); // } fa->m_vaEdges.RemoveAll_KeepSize(); fa->m_faEdgesLength.RemoveAll_KeepSize(); #define vec1x (fa->m_vSpan1[0]) #define vec1y (fa->m_vSpan1[1]) #define vec1z (fa->m_vSpan1[2]) #define vec2x (fa->m_vSpan2[0]) #define vec2y (fa->m_vSpan2[1]) #define vec2z (fa->m_vSpan2[2]) #define vecnx (fa->m_vNormal[0]) #define vecny (fa->m_vNormal[1]) #define vecnz (fa->m_vNormal[2]) // tf = -vec1z*vec2y*vecnx + vec1y*vec2z*vecnx + vec1z*vec2x*vecny - vec1x*vec2z*vecny - vec1y*vec2x*vecnz + vec1x*vec2y*vecnz; // if (cc < 2) // mprintf(" tf=%10.6f\n",tf); for (z2=0;z2m_vCenter[0]; ty = (pp[1]+c.pts[fv[ti+(z2%fc)+1]*3+1]*0.5)-fa->m_vCenter[1]; tz = (pp[2]+c.pts[fv[ti+(z2%fc)+1]*3+2]*0.5)-fa->m_vCenter[2]; lastvert[0] = tfx; lastvert[1] = tfy; tfx = - (-tz*vec2y*vecnx + ty*vec2z*vecnx + tz*vec2x*vecny - tx*vec2z*vecny - ty*vec2x*vecnz + tx*vec2y*vecnz) /*/ tf*/; tfy = - ( tz*vec1y*vecnx - ty*vec1z*vecnx - tz*vec1x*vecny + tx*vec1z*vecny + ty*vec1x*vecnz - tx*vec1y*vecnz) /*/ tf*/; // tfn = - (-tz*vec1y*vec2x + ty*vec1z*vec2x + tz*vec1x*vec2y - tx*vec1z*vec2y - ty*vec1x*vec2z + tx*vec1y*vec2z) /*/ tf*/; // if (cc < 2) // mprintf(" Vertex %d: a=%10.6f, b=%10.6f, c=%10.6f\n",z2+1,tfx,tfy,tfn); if (z2 > 0) { fa->m_vaEdges.Add(CxDVector3(tfy-lastvert[1],-tfx+lastvert[0],-(tfy-lastvert[1])*tfx + (tfx-lastvert[0])*tfy)); fa->m_faEdgesLength.Add(sqrt((tfx-lastvert[0])*(tfx-lastvert[0]) + (tfy-lastvert[1])*(tfy-lastvert[1]))); // mprintf(GREEN, "%.10g %.10g %.10g %.10g %.10g\n", tfx, tfy, lastvert[0], lastvert[1], sqrt((tfx-lastvert[0])*(tfx-lastvert[0]) + (tfy-lastvert[1])*(tfy-lastvert[1]))); // mprintf(GREEN, "%.20g %.20g %.20g\n", tfy-lastvert[1],-tfx+lastvert[0],-(tfy-lastvert[1])*tfx + (tfx-lastvert[0])*tfy); // if (cc < 2) // mprintf(" da=%10.6f, db=%10.6f, cv=%1.06f\n",fa->m_vaEdges[fa->m_vaEdges.GetSize()-1][0],fa->m_vaEdges[fa->m_vaEdges.GetSize()-1][1],fa->m_vaEdges[fa->m_vaEdges.GetSize()-1][2]); } } /* if (cc < 2) { mprintf("\n"); for (z2=0;z2<30;z2++) { tfy = fa->m_fMin[0] + (double)z2*(fa->m_fMax[0]-fa->m_fMin[0])/29.0f; for (z3=0;z3<60;z3++) { tfn = fa->m_fMin[1] + (double)z3*(fa->m_fMax[1]-fa->m_fMin[1])/59.0f; for (z4=0;z4m_vCenter[1]-fa->m_fMin[0])/(fa->m_fMax[0]-fa->m_fMin[0])*29.0+0.5) == z2) && ((int)((fa->m_vCenter[2]-fa->m_fMin[1])/(fa->m_fMax[1]-fa->m_fMin[1])*59.0+0.5) == z3)) { mprintf("*"); goto _done; } if (((int)((ty-fa->m_fMin[0])/(fa->m_fMax[0]-fa->m_fMin[0])*29.0+0.5) == z2) && ((int)((tz-fa->m_fMin[1])/(fa->m_fMax[1]-fa->m_fMin[1])*59.0+0.5) == z3)) { mprintf("+"); goto _done; } } if (fa->XRay_Hit(tfy,tfn,tfx)) mprintf("#"); else mprintf("."); _done:; } mprintf("\n"); } mprintf("\n"); }*/ ti += fv[ti]+1; } // if (magnetic) { // m_totalCurrent[id] = integrateTotalCurrent(m_p3DF, ts->m_pCurrentDensity, mi, ma); // m_magneticMoments[id] = integrateMagneticMoment(m_p3DF, ts->m_pCurrentDensity, mi, ma, pp); // } else { // if (sanity) { // Integrate_Verbose(m_p3DF,mi,ma); // } else { // if (m_bInterpolation) // m_faCharge[id] -= Integrate_Refine(m_p3DF,mi,ma); // else // m_faCharge[id] -= Integrate(m_p3DF,mi,ma); // if (g_bVoronoiMoments) // m_moments[id] = integrateMoment(m_p3DF, mi, ma, pp); // } // } // double charge; CxDVector3 dipoleMoment, totalCurrent, magneticMoment; CxDMatrix3 quadrupoleMoment; if (sanity) { // Integrate_Verbose(m_p3DF,mi,ma); integrateCell(m_p3DF, ts->m_pCurrentDensity, mi, ma, pp, &charge, &dipoleMoment, &quadrupoleMoment, &totalCurrent, &magneticMoment, true/*, id*/); } else { // if (m_bInterpolation) { // m_faCharge[id] -= Integrate_Refine(m_p3DF,mi,ma); // } else { integrateCell(m_p3DF, ts->m_pCurrentDensity, mi, ma, pp, &charge, &dipoleMoment, &quadrupoleMoment, &totalCurrent, &magneticMoment); if (g_bVoroIntegrateCharge) m_faCharge[id] -= charge; if (g_bVoroIntegrateDipoleMoment) m_moments[id] = dipoleMoment; if (g_bVoroIntegrateQuadrupoleMoment) m_maQuadTensor[id] = quadrupoleMoment; if (g_bVoroIntegrateTotalCurrent) m_totalCurrent[id] = totalCurrent; if (g_bVoroIntegrateMagneticMoment) m_magneticMoments[id] = magneticMoment; // } } /* // mprintf("\n"); for (z2=0;z2<30;z2++) { tfy = mi[0] + (double)z2*(ma[0]-mi[0])/29.0f; for (z3=0;z3<60;z3++) { tfn = mi[1] + (double)z3*(ma[1]-mi[1])/59.0f; ti = 0; for (z4=0;z4XRay_Hit(tfy,tfn,tfx)) ti++; } if (ti == 0) rhi[0]++; else if (ti == 1) rhi[1]++; else if (ti == 2) rhi[2]++; else rhi[3]++; rc++; // if ((ti != 0) && (ti != 2)) // mprintf("\nError: Voronoi cell %d: %d ",id+1,ti); // if (ti == 0) // mprintf("."); // else mprintf("%d",ti); } // mprintf("\n"); } // mprintf("\n");*/ } cc++; } while (vl.inc()); } if (verbose) { mprintf(WHITE,"]"); mprintf(" done.\n"); } if (sanity) { if (sanityall) { if ((m_fRayHisto[1] != 0) || (m_fRayHisto[3] != 0)) b = false; for (z2=0;z2m_iRes[0]*m_p3DF->m_iRes[1]*m_p3DF->m_iRes[2]*m_iInterpolationFactorCube;z2++) { if (m_hitCount[z2] != 1) { b = false; break; } // if (m_p3DF->m_pBin[z2] == 0) // { // b = false; // break; // } // else if (m_p3DF->m_pBin[z2] == 1) // m_fRayHisto[1]++; // else // { // b = false; // break; // } } if (!b) { mprintf(" %d Voronoi cells processed.\n",cc); mprintf("\n %10d rays cast. Intersection histogram:\n",m_fRayCount); mprintf(" %10d rays hit 0 times (%10.6f%c).\n",m_fRayHisto[0],(double)m_fRayHisto[0]/m_fRayCount*100.0,'%'); mprintf(" %10d rays hit 1 times (%10.6f%c).\n",m_fRayHisto[1],(double)m_fRayHisto[1]/m_fRayCount*100.0,'%'); mprintf(" %10d rays hit 2 times (%10.6f%c).\n",m_fRayHisto[2],(double)m_fRayHisto[2]/m_fRayCount*100.0,'%'); mprintf(" %10d rays hit > 2 times (%10.6f%c).\n",m_fRayHisto[3],(double)m_fRayHisto[3]/m_fRayCount*100.0,'%'); mprintf("\n Grid analysis:\n"); m_fRayHisto[0] = 0; m_fRayHisto[1] = 0; m_fRayHisto[2] = 0; int z2a, z2b, z2c, z2d, z2e, z2f; for (z2a = 0; z2a < m_p3DF->m_iRes[0]; z2a++) { for (z2b = 0; z2b < m_p3DF->m_iRes[1]; z2b++) { for (z2c = 0; z2c < m_p3DF->m_iRes[2]; z2c++) { for (z2d = 0; z2d < m_iInterpolationFactor; z2d++) { for (z2e = 0; z2e < m_iInterpolationFactor; z2e++) { for (z2f = 0; z2f < m_iInterpolationFactor; z2f++) { if (m_hitCount[(z2d + z2e * m_iInterpolationFactor + z2f * m_iInterpolationFactor * m_iInterpolationFactor) * m_p3DF->m_iRes[0] * m_p3DF->m_iRes[1] * m_p3DF->m_iRes[2] + z2a + z2b * m_p3DF->m_iRes[0] + z2c * m_p3DF->m_iResXY] == 0) { m_fRayHisto[0]++; b = false; mprintf(" Missed: ( %d.%d | %d.%d | %d.%d ).\n", z2a, z2d, z2b, z2e, z2c, z2f); } else if (m_hitCount[(z2d + z2e * m_iInterpolationFactor + z2f * m_iInterpolationFactor * m_iInterpolationFactor) * m_p3DF->m_iRes[0] * m_p3DF->m_iRes[1] * m_p3DF->m_iRes[2] + z2a + z2b * m_p3DF->m_iRes[0] + z2c * m_p3DF->m_iResXY] == 1) { m_fRayHisto[1]++; } else { m_fRayHisto[2]++; b = false; mprintf(" Multiple: ( %d.%d | %d.%d | %d.%d ).\n", z2a, z2d, z2b, z2e, z2c, z2f); } } } } } } } // for (z2=0;z2m_iRes[0]*m_p3DF->m_iRes[1]*m_p3DF->m_iRes[2]*m_iInterpolationFactorCube;z2++) // { // if (m_hitCount[z2] == 0) { // m_fRayHisto[0]++; // // mprintf(" Missed: ( %d | %d | %d ).\n", z2%m_p3DF->m_iRes[0], (z2 / m_p3DF->m_iRes[0]) % m_p3DF->m_iRes[1], (z2 / m_p3DF->m_iResXY)); // } else if (m_hitCount[z2] == 1) { // m_fRayHisto[1]++; // } else { // m_fRayHisto[2]++; // // mprintf(" Multiple: ( %d | %d | %d ).\n", z2%m_p3DF->m_iRes[0], (z2 / m_p3DF->m_iRes[0]) % m_p3DF->m_iRes[1], (z2 / m_p3DF->m_iResXY)); // } // // if (m_p3DF->m_pBin[z2] == 0) // // { // // m_fRayHisto[0]++; // // b = false; // // // mprintf(" Missed: ( %d | %d | %d ).\n",z2%100,(z2/100)%100,(z2/10000)); // // } // // else if (m_p3DF->m_pBin[z2] == 1) // // m_fRayHisto[1]++; // // else // // { // // m_fRayHisto[2]++; // // b = false; // // // mprintf(" Multiple: ( %d | %d | %d ).\n",z2%100,(z2/100)%100,(z2/10000)); // // } // } mprintf(" %10d points missed (%10.6f%c).\n",m_fRayHisto[0],(double)m_fRayHisto[0]/(m_p3DF->m_iRes[0]*m_p3DF->m_iRes[1]*m_p3DF->m_iRes[2]*m_iInterpolationFactorCube)*100.0,'%'); mprintf(" %10d points hit (%10.6f%c).\n",m_fRayHisto[1],(double)m_fRayHisto[1]/(m_p3DF->m_iRes[0]*m_p3DF->m_iRes[1]*m_p3DF->m_iRes[2]*m_iInterpolationFactorCube)*100.0,'%'); mprintf(" %10d points hit multiple times (%10.6f%c).\n",m_fRayHisto[2],(double)m_fRayHisto[2]/(m_p3DF->m_iRes[0]*m_p3DF->m_iRes[1]*m_p3DF->m_iRes[2]*m_iInterpolationFactorCube)*100.0,'%'); } } else { mprintf(" %d Voronoi cells processed.\n",cc); mprintf("\n %10d rays cast. Intersection histogram:\n",m_fRayCount); mprintf(" %10d rays hit 0 times (%10.6f%c).\n",m_fRayHisto[0],(double)m_fRayHisto[0]/m_fRayCount*100.0,'%'); mprintf(" %10d rays hit 1 times (%10.6f%c).\n",m_fRayHisto[1],(double)m_fRayHisto[1]/m_fRayCount*100.0,'%'); mprintf(" %10d rays hit 2 times (%10.6f%c).\n",m_fRayHisto[2],(double)m_fRayHisto[2]/m_fRayCount*100.0,'%'); mprintf(" %10d rays hit > 2 times (%10.6f%c).\n",m_fRayHisto[3],(double)m_fRayHisto[3]/m_fRayCount*100.0,'%'); if ((m_fRayHisto[1] != 0) || (m_fRayHisto[3] != 0)) b = false; mprintf("\n Grid analysis:\n"); m_fRayHisto[0] = 0; m_fRayHisto[1] = 0; m_fRayHisto[2] = 0; int z2a, z2b, z2c, z2d, z2e, z2f; for (z2a = 0; z2a < m_p3DF->m_iRes[0]; z2a++) { for (z2b = 0; z2b < m_p3DF->m_iRes[1]; z2b++) { for (z2c = 0; z2c < m_p3DF->m_iRes[2]; z2c++) { for (z2d = 0; z2d < m_iInterpolationFactor; z2d++) { for (z2e = 0; z2e < m_iInterpolationFactor; z2e++) { for (z2f = 0; z2f < m_iInterpolationFactor; z2f++) { if (m_hitCount[(z2d + z2e * m_iInterpolationFactor + z2f * m_iInterpolationFactor * m_iInterpolationFactor) * m_p3DF->m_iRes[0] * m_p3DF->m_iRes[1] * m_p3DF->m_iRes[2] + z2a + z2b * m_p3DF->m_iRes[0] + z2c * m_p3DF->m_iResXY] == 0) { m_fRayHisto[0]++; b = false; mprintf(" Missed: ( %d.%d | %d.%d | %d.%d ).\n", z2a, z2d, z2b, z2e, z2c, z2f); } else if (m_hitCount[(z2d + z2e * m_iInterpolationFactor + z2f * m_iInterpolationFactor * m_iInterpolationFactor) * m_p3DF->m_iRes[0] * m_p3DF->m_iRes[1] * m_p3DF->m_iRes[2] + z2a + z2b * m_p3DF->m_iRes[0] + z2c * m_p3DF->m_iResXY] == 1) { m_fRayHisto[1]++; } else { m_fRayHisto[2]++; b = false; mprintf(" Multiple: ( %d.%d | %d.%d | %d.%d ).\n", z2a, z2d, z2b, z2e, z2c, z2f); } } } } } } } // for (z2=0;z2m_iRes[0]*m_p3DF->m_iRes[1]*m_p3DF->m_iRes[2]*m_iInterpolationFactorCube;z2++) // { // // if (m_p3DF->m_pBin[z2] == 0) // if (m_hitCount[z2] == 0) // { // m_fRayHisto[0]++; // b = false; // mprintf(" Missed: ( %d.%d | %d.%d | %d.%d ).\n", (z2 % m_iInterpolationFactorCube) % m_p3DF->m_iRes[0], (z2 / (m_p3DF->m_iRes[0] * m_p3DF->m_iRes[1] * m_p3DF->m_iRes[2])) % m_iInterpolationFactor, ((z2 % m_iInterpolationFactorCube) / m_p3DF->m_iRes[0]) % m_p3DF->m_iRes[1], ((z2 / (m_p3DF->m_iRes[0] * m_p3DF->m_iRes[1] * m_p3DF->m_iRes[2])) / m_iInterpolationFactor) % m_iInterpolationFactor, ((z2 % m_iInterpolationFactorCube) / m_p3DF->m_iResXY), ((z2 / (m_p3DF->m_iRes[0] * m_p3DF->m_iRes[1] * m_p3DF->m_iRes[2])) / m_iInterpolationFactor * m_iInterpolationFactor)); // } // // else if (m_p3DF->m_pBin[z2] == 1) // else if (m_hitCount[z2] == 1) // m_fRayHisto[1]++; // else // { // m_fRayHisto[2]++; // b = false; // mprintf(" Multiple: ( %d.%d | %d.%d | %d.%d ).\n", (z2 % m_iInterpolationFactorCube) % m_p3DF->m_iRes[0], (z2 / (m_p3DF->m_iRes[0] * m_p3DF->m_iRes[1] * m_p3DF->m_iRes[2])) % m_iInterpolationFactor, ((z2 % m_iInterpolationFactorCube) / m_p3DF->m_iRes[0]) % m_p3DF->m_iRes[1], ((z2 / (m_p3DF->m_iRes[0] * m_p3DF->m_iRes[1] * m_p3DF->m_iRes[2])) / m_iInterpolationFactor) % m_iInterpolationFactor, ((z2 % m_iInterpolationFactorCube) / m_p3DF->m_iResXY), ((z2 / (m_p3DF->m_iRes[0] * m_p3DF->m_iRes[1] * m_p3DF->m_iRes[2])) / m_iInterpolationFactor * m_iInterpolationFactor)); // } // } mprintf(" %10d points missed (%10.6f%c).\n",m_fRayHisto[0],(double)m_fRayHisto[0]/(m_p3DF->m_iRes[0]*m_p3DF->m_iRes[1]*m_p3DF->m_iRes[2]*m_iInterpolationFactorCube)*100.0,'%'); mprintf(" %10d points hit (%10.6f%c).\n",m_fRayHisto[1],(double)m_fRayHisto[1]/(m_p3DF->m_iRes[0]*m_p3DF->m_iRes[1]*m_p3DF->m_iRes[2]*m_iInterpolationFactorCube)*100.0,'%'); mprintf(" %10d points hit multiple times (%10.6f%c).\n",m_fRayHisto[2],(double)m_fRayHisto[2]/(m_p3DF->m_iRes[0]*m_p3DF->m_iRes[1]*m_p3DF->m_iRes[2]*m_iInterpolationFactorCube)*100.0,'%'); } } delete con; for (z=0;z fv; CTetraCellBuffer *cbu; CTetraFaceBuffer *fbu; try { con = new container_periodic_poly(g_fBoxX/1000.0,0,g_fBoxY/1000.0,0,0,g_fBoxZ/1000.0,g_pVoroWrapper->m_iBlocksX,g_pVoroWrapper->m_iBlocksY,g_pVoroWrapper->m_iBlocksZ,g_iVoroMemory); } catch(...) { con = NULL; } if (con == NULL) NewException((double)sizeof(container_periodic_poly),__FILE__,__LINE__,__PRETTY_FUNCTION__); for (z=0;zput(z,ts->m_vaCoords[z][0]/1000.0,ts->m_vaCoords[z][1]/1000.0,ts->m_vaCoords[z][2]/1000.0,g_faVoronoiRadii[z]/1000.0); c_loop_all_periodic vl(*con); for (z=m_oaVoroBuffer.GetSize();zcompute_cell(c,vl)) { ijk = vl.ijk; q = vl.q; pp = con->p[ijk]+con->ps*q; id = con->id[ijk][q]; c.face_vertices(fv); cbu = (CTetraCellBuffer*)m_oaVoroBuffer[id]; for (z=cbu->m_oaFaces.GetSize();zm_oaFaces.Add(fbu); } cbu->m_iFaces = c.number_of_faces(); cbu->m_vCenter = CxDVector3(pp[0]*1000.0,pp[1]*1000.0,pp[2]*1000.0); ti = 0; for (z=0;zm_oaFaces[z]; fbu->m_vaVertices.RemoveAll_KeepSize(); for (z2=0;z2m_vaVertices.Add( CxDVector3( (*pp+c.pts[fv[ti+z2+1]*3]*0.5)*1000.0, (pp[1]+c.pts[fv[ti+z2+1]*3+1]*0.5)*1000.0, (pp[2]+c.pts[fv[ti+z2+1]*3+2]*0.5)*1000.0 ) ); ti += fv[ti]+1; } } } while (vl.inc()); } delete con; } void CTetraPak::Integrate_Verbose(C3DF *df, double mi[2], double ma[2]) { int z2, z2b, z3, z3b, z4, z4b, ti, ixa, ixb, iya, iyb, iza, izb; double xv[10], tfy, tfz, tf; double EPS = 1.0E-20; // int xi[10]; iya = (int)floor(mi[0]/(df->m_fMaxVal[1]/1000.0)*df->m_iRes[1]+EPS); iyb = (int)ceil(ma[0]/(df->m_fMaxVal[1]/1000.0)*df->m_iRes[1]-EPS); // mprintf("Y: %f becomes %d, %f becomes %d.\n",mi[0]/(df->m_fMaxVal[1]/1000.0)*df->m_iRes[1]+EPS,iya,ma[0]/(df->m_fMaxVal[1]/1000.0)*df->m_iRes[1]-EPS,iyb); // mprintf(" MaxVal %f\n",df->m_fMaxVal[1]); iza = (int)floor(mi[1]/(df->m_fMaxVal[2]/1000.0)*df->m_iRes[2]+EPS); izb = (int)ceil(ma[1]/(df->m_fMaxVal[2]/1000.0)*df->m_iRes[2]-EPS); // mprintf(BLUE,"Integrating Y %d..%d, Z %d..%d.\n",iya,iyb,iza,izb); // mprintf(BLUE," (range Y %f..%f, Z %f..%f).\n",mi[0],ma[0],mi[1],ma[1]); if (iyb-iya >= df->m_iRes[1]) { // mprintf(YELLOW,"\n Averted calamity (y = %d..%d).",iya,iyb); // iyb = iya + df->m_iRes[1] - 1; // mprintf(YELLOW," Now %d .. %d. ",iya,iyb); } if (izb-iza >= df->m_iRes[2]) { // mprintf(YELLOW,"\n Averted calamity (z = %d..%d).",iza,izb); // izb = iza + df->m_iRes[2] - 1; // mprintf(YELLOW," Now %d .. %d. ",iza,izb); } /* mprintf("BoxX=%.20f, BoxY=%.20f, BoxZ=%.20f\n",g_fBoxX,g_fBoxY,g_fBoxZ); mprintf("Res0=%d, Res1=%d, Res2=%d.\n",df->m_iRes[0],df->m_iRes[1],df->m_iRes[2]); mprintf("mi0=%.20f, ma0=%.20f, mi1=%.20f, ma1=%.20f\n",mi[0],ma[0],mi[1],ma[1]); mprintf("iya=%d, iyb=%d, iza=%d, izb=%d\n",iya,iyb,iza,izb);*/ for (z2=iya;z2<=iyb;z2++) { // tfy = (double)(z2+0.0)*(g_fBoxY/1000.0)/df->m_iRes[1]; tfy = (double)z2*(df->m_fMaxVal[1]/1000.0)/df->m_iRes[1]; z2b = z2%df->m_iRes[1]; if (z2b < 0) z2b += df->m_iRes[1]; z2b *= df->m_iRes[0]; for (z3=iza;z3<=izb;z3++) { // tfz = (double)(z3+0.0)*(g_fBoxZ/1000.0)/df->m_iRes[2]; tfz = (double)z3*(df->m_fMaxVal[2]/1000.0)/df->m_iRes[2]; z3b = z3%df->m_iRes[2]; if (z3b < 0) z3b += df->m_iRes[2]; z3b *= df->m_iResXY; z3b += z2b; ti = 0; for (z4=0;z4XRay_Hit(tfy,tfz,xv[ti]/*,(z3==50)?true:false*/)) { // mprintf(" %3d | %3d [%2d]: Hit at (%d) %.6f\n",z2,z3,z4,ti,xv[ti]); // xi[ti] = z4; ti++; } // else // { // mprintf(" %3d | %3d | %3d: Missed at (%d)\n",z2,z3,z4,ti); // } } /* if (ti != 2) { mprintf("*** %3d | %3d: Hit %d times (",z2,z3,ti); for (z4=0;z4 xv[1]) { tf = xv[0]; xv[0] = xv[1]; xv[1] = tf; } ixa = (int)ceil(xv[0] / (df->m_fMaxVal[1]/1000.0) * df->m_iRes[1]); ixb = (int)floor(xv[1] / (df->m_fMaxVal[1]/1000.0) * df->m_iRes[1]); // if ((z2==23) && (z3==50)) // mprintf(YELLOW,"Hit 23|50: Range %d - %d\n",ixa,ixb); // if (ixa != ((int)ceil(xv[0] / (g_fBoxX / 1000.0) * df->m_iRes[0]))) // mprintf("\n ixa %d <--> %d. ",ixa,(int)ceil(xv[0] / (g_fBoxX / 1000.0) * df->m_iRes[0])); // if ((z2==67) && (z3==51)) // mprintf("\nixa=%3d (%8f) ixb=%3d (%8f):",ixa,xv[0],ixb,xv[1]); for (z4=ixa;z4<=ixb;z4++) { z4b = z4%df->m_iRes[0]; if (z4b < 0) z4b += df->m_iRes[0]; // if ((z2==67) && (z3==51)) // mprintf(" %3d",z4b); df->m_pBin[z3b+z4b]++; // if ((z2==23) && (z3==50)) // mprintf("%d... %f (%d)\n",z4b,df->m_pBin[z3b+z4b],z3b+z4b); // if (z3b+z4b == 502300) // mprintf(GREEN,"%d + %d = %d (z2=%d, z3=%d, z4=%d).\n",z3b,z4b,z3b+z4b,z2,z3,z4); } } } } } // VORI_FLOAT CTetraPak::Integrate(C3DF *df, double mi[2], double ma[2]) // { // int z2, z2b, z3, z3b, z4, z4b, ti, ixa, ixb, iya, iyb, iza, izb; // double xv[4], tfy, tfz, tf, rv; // // iya = (int)floor(mi[0]/(df->m_fMaxVal[1]/1000.0)*df->m_iRes[1]); // iyb = (int)ceil(ma[0]/(df->m_fMaxVal[1]/1000.0)*df->m_iRes[1]); // // iza = (int)floor(mi[1]/(df->m_fMaxVal[2]/1000.0)*df->m_iRes[2]); // izb = (int)ceil(ma[1]/(df->m_fMaxVal[2]/1000.0)*df->m_iRes[2]); // // // if (iyb-iya >= df->m_iRes[1]) // // iyb = iya + df->m_iRes[1] - 1; // // // if (izb-iza >= df->m_iRes[2]) // // izb = iza + df->m_iRes[2] - 1; // // rv = 0; // for (z2=iya;z2<=iyb;z2++) // { // tfy = (double)z2*(df->m_fMaxVal[1]/1000.0)/df->m_iRes[1]; // // z2b = z2%df->m_iRes[1]; // if (z2b < 0) // z2b += df->m_iRes[1]; // z2b *= df->m_iRes[0]; // // for (z3=iza;z3<=izb;z3++) // { // tfz = (double)z3*(df->m_fMaxVal[2]/1000.0)/df->m_iRes[2]; // // z3b = z3%df->m_iRes[2]; // if (z3b < 0) // z3b += df->m_iRes[2]; // z3b *= df->m_iResXY; // z3b += z2b; // // ti = 0; // for (z4=0;z4XRay_Hit(tfy,tfz,xv[ti])) // ti++; // // if (ti == 2) // { // if (xv[0] > xv[1]) // { // tf = xv[0]; // xv[0] = xv[1]; // xv[1] = tf; // } // // ixa = (int)ceil(xv[0] / (df->m_fMaxVal[0] / 1000.0) * df->m_iRes[0]); // // ixb = (int)floor(xv[1] / (df->m_fMaxVal[0] / 1000.0) * df->m_iRes[0]); // // /* if (g_bVoroIntEquitable) // { // tf = 0.5 * ((double)ixa - (xv[0] / (df->m_fMaxVal[0] / 1000.0) * df->m_iRes[0])); // // z4b = (ixa-1)%df->m_iRes[0]; // if (z4b < 0) // z4b += df->m_iRes[0]; // // rv += tf * df->m_pBin[z3b+z4b]; // // z4b = ixa%df->m_iRes[0]; // if (z4b < 0) // z4b += df->m_iRes[0]; // // rv += (0.5 + tf) * df->m_pBin[z3b+z4b]; // // ixa++; // // tf = 0.5 * ((xv[1] / (df->m_fMaxVal[0] / 1000.0) * df->m_iRes[0]) - (double)ixb); // // z4b = ixb%df->m_iRes[0]; // if (z4b < 0) // z4b += df->m_iRes[0]; // // rv += (0.5 + tf) * df->m_pBin[z3b+z4b]; // // z4b = (ixb+1)%df->m_iRes[0]; // if (z4b < 0) // z4b += df->m_iRes[0]; // // rv += tf * df->m_pBin[z3b+z4b]; // // ixb--; // }*/ // // for (z4=ixa;z4<=ixb;z4++) // { // z4b = z4%df->m_iRes[0]; // if (z4b < 0) // z4b += df->m_iRes[0]; // // rv += df->m_pBin[z3b+z4b]; // } // } // } // } // // return rv; // } VORI_FLOAT CTetraPak::Integrate_Refine(C3DF *df, double mi[2], double ma[2]) { int z2, z2i, z3, z3i, z4, ti, ixa, ixb, iya, iyb, iza, izb; double xv[4], tfy, tfz, tf; int iz1, iz2, iy1, iy2, ix1, ix2; VORI_FLOAT rv; VORI_FLOAT cz1, cz2, cy1, cy2, cx1, cx2; VORI_FLOAT c11, c12, c21, c22; iya = (int)floor(mi[0]/(df->m_fMaxVal[1]/1000.0)*df->m_iRes[1]); iyb = (int)ceil(ma[0]/(df->m_fMaxVal[1]/1000.0)*df->m_iRes[1]); iza = (int)floor(mi[1]/(df->m_fMaxVal[2]/1000.0)*df->m_iRes[2]); izb = (int)ceil(ma[1]/(df->m_fMaxVal[2]/1000.0)*df->m_iRes[2]); // if (iyb-iya >= df->m_iRes[1]) // iyb = iya + df->m_iRes[1] - 1; // if (izb-iza >= df->m_iRes[2]) // izb = iza + df->m_iRes[2] - 1; rv = 0; for (z2=iya;z2<=iyb;z2++) { iy1 = z2%df->m_iRes[1]; if (iy1 < 0) iy1 += df->m_iRes[1]; iy1 *= df->m_iRes[0]; iy2 = (z2+1)%df->m_iRes[1]; if (iy2 < 0) iy2 += df->m_iRes[1]; iy2 *= df->m_iRes[0]; for (z3=iza;z3<=izb;z3++) { iz1 = z3%df->m_iRes[2]; if (iz1 < 0) iz1 += df->m_iRes[2]; iz1 *= df->m_iResXY; iz2 = (z3+1)%df->m_iRes[2]; if (iz2 < 0) iz2 += df->m_iRes[2]; iz2 *= df->m_iResXY; for (z2i=0;z2im_iRes[1]*df->m_fMaxVal[1]/1000.0; tfy = (z2+z2i/(double)m_iInterpolationFactor)/df->m_iRes[1]*df->m_fMaxVal[1]/1000.0; cy2 = z2i/(VORI_FLOAT)m_iInterpolationFactor; cy1 = (VORI_FLOAT)(1.0 - cy2); for (z3i=0;z3im_iRes[2]*df->m_fMaxVal[2]/1000.0; tfz = (z3+z3i/(double)m_iInterpolationFactor)/df->m_iRes[2]*df->m_fMaxVal[2]/1000.0; cz2 = z3i/(VORI_FLOAT)m_iInterpolationFactor; cz1 = (VORI_FLOAT)(1.0 - cz2); c11 = cy1*cz1; c12 = cy1*cz2; c21 = cy2*cz1; c22 = cy2*cz2; ti = 0; for (z4=0;z4XRay_Hit(tfy,tfz,xv[ti])) ti++; if (ti == 2) { if (xv[0] > xv[1]) { tf = xv[0]; xv[0] = xv[1]; xv[1] = tf; } ixa = (int)ceil(xv[0] / (df->m_fMaxVal[0] / 1000.0) * df->m_iRes[0] * m_iInterpolationFactor); ixb = (int)floor(xv[1] / (df->m_fMaxVal[0] / 1000.0) * df->m_iRes[0] * m_iInterpolationFactor); for (z4=ixa;z4<=ixb;z4++) { ix1 = (z4/m_iInterpolationFactor)%df->m_iRes[0]; if (ix1 < 0) ix1 += df->m_iRes[0]; ix2 = (ix1+1)%df->m_iRes[0]; cx2 = (z4%m_iInterpolationFactor)/(VORI_FLOAT)m_iInterpolationFactor; cx1 = (VORI_FLOAT)(1.0 - cx2); rv += cx1*(c11*df->m_pBin[ix1+iy1+iz1] + c12*df->m_pBin[ix1+iy1+iz2] + c21*df->m_pBin[ix1+iy2+iz1] + c22*df->m_pBin[ix1+iy2+iz2]); rv += cx2*(c11*df->m_pBin[ix2+iy1+iz1] + c12*df->m_pBin[ix2+iy1+iz2] + c21*df->m_pBin[ix2+iy2+iz1] + c22*df->m_pBin[ix2+iy2+iz2]); } } } } } } return rv / (VORI_FLOAT)(m_iInterpolationFactorCube); } void CTetraPak::integrateCell(C3DF *electronDensity, CxDoubleArray *currentDensity, double mi[2], double ma[2], double refPoint[3], double *charge, CxDVector3 *dipoleMoment, CxDMatrix3 *quadrupoleMoment, CxDVector3 *totalCurrent, CxDVector3 *magneticMoment, bool sanity/*, int debug*/) { int z2, z3, z4, ti, ixa, ixb, iya, iyb, iza, izb; int ix1, ix2, iy1, iy2, iz1, iz2, z2i, z3i, z4a; double xv[4], tfy, tfz, tf; VORI_FLOAT cx1, cx2, cy1, cy2, cz1, cz2, c11, c12, c21, c22; *charge = 0.0; *dipoleMoment = CxDVector3(0.0, 0.0, 0.0); *totalCurrent = CxDVector3(0.0, 0.0, 0.0); *magneticMoment = CxDVector3(0.0, 0.0, 0.0); *quadrupoleMoment = CxDMatrix3(0.0); if (g_bBoxNonOrtho) { iya = (int)floor(mi[0] * electronDensity->m_iRes[1]); iyb = (int)ceil(ma[0] * electronDensity->m_iRes[1]); iza = (int)floor(mi[1] * electronDensity->m_iRes[2]); izb = (int)ceil(ma[1] * electronDensity->m_iRes[2]); } else { iya = (int)floor(mi[0] / (electronDensity->m_fMaxVal[1] / 1000.0) * electronDensity->m_iRes[1]); iyb = (int)ceil(ma[0] / (electronDensity->m_fMaxVal[1] / 1000.0) * electronDensity->m_iRes[1]); iza = (int)floor(mi[1] / (electronDensity->m_fMaxVal[2] / 1000.0) * electronDensity->m_iRes[2]); izb = (int)ceil(ma[1] / (electronDensity->m_fMaxVal[2] / 1000.0) * electronDensity->m_iRes[2]); } for (z2 = iya; z2 <= iyb; z2++) { // tfy = (double)z2 * (electronDensity->m_fMaxVal[1] / 1000.0) / electronDensity->m_iRes[1]; // z2b = z2 % electronDensity->m_iRes[1]; // if (z2b < 0) // z2b += electronDensity->m_iRes[1]; // z2b *= electronDensity->m_iRes[0]; iy1 = z2 % electronDensity->m_iRes[1]; if (iy1 < 0) iy1 += electronDensity->m_iRes[1]; iy1 *= electronDensity->m_iRes[0]; iy2 = (z2 + 1) % electronDensity->m_iRes[1]; if (iy2 < 0) iy2 += electronDensity->m_iRes[1]; iy2 *= electronDensity->m_iRes[0]; for (z3 = iza; z3 <= izb; z3++) { // tfz = (double)z3 * (electronDensity->m_fMaxVal[2] / 1000.0) / electronDensity->m_iRes[2]; // z3b = z3 % electronDensity->m_iRes[2]; // if (z3b < 0) // z3b += electronDensity->m_iRes[2]; // z3b *= electronDensity->m_iResXY; // z3b += z2b; iz1 = z3 % electronDensity->m_iRes[2]; if (iz1 < 0) iz1 += electronDensity->m_iRes[2]; iz1 *= electronDensity->m_iResXY; iz2 = (z3 + 1) % electronDensity->m_iRes[2]; if (iz2 < 0) iz2 += electronDensity->m_iRes[2]; iz2 *= electronDensity->m_iResXY; // mprintf(GREEN, "Hallo %d\n", m_iInterpolationFactor); for (z2i = 0; z2i < m_iInterpolationFactor; z2i++) { // for (z2i = 0; z2i < 1; z2i++) { if (g_bBoxNonOrtho) { tfy = ((double)z2 + (double)z2i / m_iInterpolationFactor) / electronDensity->m_iRes[1]; } else { tfy = ((double)z2 + (double)z2i / m_iInterpolationFactor) * (electronDensity->m_fMaxVal[1] / 1000.0) / electronDensity->m_iRes[1]; } cy2 = (VORI_FLOAT)z2i / m_iInterpolationFactor; cy1 = 1.0 - cy2; for (z3i = 0; z3i < m_iInterpolationFactor; z3i++) { // for (z3i = 0; z3i < 1; z3i++) { if (g_bBoxNonOrtho) { tfz = ((double)z3 + (double)z3i / m_iInterpolationFactor) / electronDensity->m_iRes[2]; } else { tfz = ((double)z3 + (double)z3i / m_iInterpolationFactor) * (electronDensity->m_fMaxVal[2] / 1000.0) / electronDensity->m_iRes[2]; } cz2 = (VORI_FLOAT)z3i / m_iInterpolationFactor; cz1 = 1.0 - cz2; c11 = cy1 * cz1; c12 = cy1 * cz2; c21 = cy2 * cz1; c22 = cy2 * cz2; ti = 0; for (z4 = 0; z4 < m_iFaces; z4++) { if (((CTetraFace *)m_oaFaces[z4])->XRay_Hit(tfy, tfz, xv[ti]/*, debug == 103 && fabs(tfy - 0.16666666666666665741) < 1.0e-8 && fabs(tfz - 0.46239999999999997771) < 1.0e-8*/)) { // if (debug == 103 && fabs(tfy - 0.16666666666666665741) < 1.0e-8 && fabs(tfz - 0.46239999999999997771) < 1.0e-8) // mprintf(GREEN, "Hit %d: %.20g\n", z4+1, xv[ti]); ti++; } } if (sanity) { if (ti == 0) m_fRayHisto[0]++; else if (ti == 1) m_fRayHisto[1]++; else if (ti == 2) m_fRayHisto[2]++; else m_fRayHisto[3]++; m_fRayCount++; } if (ti == 2) { if (xv[0] > xv[1]) { tf = xv[0]; xv[0] = xv[1]; xv[1] = tf; } // while (fabs(xv[0] / (electronDensity->m_fMaxVal[0] / 1000.0) * electronDensity->m_iRes[0] - ceil(xv[0] / (electronDensity->m_fMaxVal[0] / 1000.0) * electronDensity->m_iRes[0])) < VORI_EPS) // xv[0] += VORI_EPS * (electronDensity->m_fMaxVal[0] / 1000.0) * electronDensity->m_iRes[0]; // while (fabs(xv[1] / (electronDensity->m_fMaxVal[0] / 1000.0) * electronDensity->m_iRes[0] - ceil(xv[1] / (electronDensity->m_fMaxVal[0] / 1000.0) * electronDensity->m_iRes[0])) < VORI_EPS) // xv[1] += VORI_EPS * (electronDensity->m_fMaxVal[0] / 1000.0) * electronDensity->m_iRes[0]; if (g_bBoxNonOrtho) { while (fabs(xv[0] * electronDensity->m_iRes[0] * m_iInterpolationFactor - ceil(xv[0] * electronDensity->m_iRes[0] * m_iInterpolationFactor)) < VORI_EPS) xv[0] += VORI_EPS/* * electronDensity->m_iRes[0] * m_iInterpolationFactor*/; while (fabs(xv[1] * electronDensity->m_iRes[0] * m_iInterpolationFactor - ceil(xv[1] * electronDensity->m_iRes[0] * m_iInterpolationFactor)) < VORI_EPS) xv[1] += VORI_EPS/* * electronDensity->m_iRes[0] * m_iInterpolationFactor*/; ixa = (int)ceil(xv[0] * electronDensity->m_iRes[0] * m_iInterpolationFactor); ixb = (int)floor(xv[1] * electronDensity->m_iRes[0] * m_iInterpolationFactor); } else { while (fabs(xv[0] / (electronDensity->m_fMaxVal[0] / 1000.0) * electronDensity->m_iRes[0] * m_iInterpolationFactor - ceil(xv[0] / (electronDensity->m_fMaxVal[0] / 1000.0) * electronDensity->m_iRes[0] * m_iInterpolationFactor)) < VORI_EPS) xv[0] += VORI_EPS * (electronDensity->m_fMaxVal[0] / 1000.0) * electronDensity->m_iRes[0] * m_iInterpolationFactor; while (fabs(xv[1] / (electronDensity->m_fMaxVal[0] / 1000.0) * electronDensity->m_iRes[0] * m_iInterpolationFactor - ceil(xv[1] / (electronDensity->m_fMaxVal[0] / 1000.0) * electronDensity->m_iRes[0] * m_iInterpolationFactor)) < VORI_EPS) xv[1] += VORI_EPS * (electronDensity->m_fMaxVal[0] / 1000.0) * electronDensity->m_iRes[0] * m_iInterpolationFactor; ixa = (int)ceil(xv[0] / (electronDensity->m_fMaxVal[0] / 1000.0) * electronDensity->m_iRes[0] * m_iInterpolationFactor); ixb = (int)floor(xv[1] / (electronDensity->m_fMaxVal[0] / 1000.0) * electronDensity->m_iRes[0] * m_iInterpolationFactor); } for (z4 = ixa; z4 <= ixb; z4++) { // z4b = z4 % electronDensity->m_iRes[0]; // if (z4b < 0) // z4b += electronDensity->m_iRes[0]; ix1 = floori(z4, m_iInterpolationFactor) % electronDensity->m_iRes[0]; if (ix1 < 0) ix1 += electronDensity->m_iRes[0]; ix2 = (ix1 + 1) % electronDensity->m_iRes[0]; z4a = z4 % m_iInterpolationFactor; if (z4a < 0) z4a += m_iInterpolationFactor; cx2 = (VORI_FLOAT)z4a / m_iInterpolationFactor; cx1 = 1.0 - cx2; double x, y, z; if (g_bBoxNonOrtho) { x = (((double)z4 / m_iInterpolationFactor) / electronDensity->m_iRes[0] * g_mCubeCell(0,0) + tfy * g_mCubeCell(1,0) + tfz * g_mCubeCell(2,0)) / 1000.0; y = (((double)z4 / m_iInterpolationFactor) / electronDensity->m_iRes[0] * g_mCubeCell(0,1) + tfy * g_mCubeCell(1,1) + tfz * g_mCubeCell(2,1)) / 1000.0; z = (((double)z4 / m_iInterpolationFactor) / electronDensity->m_iRes[0] * g_mCubeCell(0,2) + tfy * g_mCubeCell(1,2) + tfz * g_mCubeCell(2,2)) / 1000.0; } else { x = ((double)z4 / m_iInterpolationFactor) * (electronDensity->m_fMaxVal[0] / 1000.0) / electronDensity->m_iRes[0]; y = tfy; z = tfz; } // if (ix1 == 0 && iy1 == 0 && iz1 == 0) { // mprintf(GREEN, "%d %d %d\n", z4, z2, z3); // mprintf(GREEN, "%.10g %.10g %.10g\n", x, y, z); // mprintf(GREEN, "%d %d %d\n", z4a, z2i, z3i); // mprintf(GREEN, "%d %d\n", (z4a + z2i * m_iInterpolationFactor + z3i * m_iInterpolationFactor * m_iInterpolationFactor) * electronDensity->m_iRes[0] * electronDensity->m_iRes[1] * electronDensity->m_iRes[2] + ix1 + iy1 + iz1, m_hitCount[(z4a + z2i * m_iInterpolationFactor + z3i * m_iInterpolationFactor * m_iInterpolationFactor) * electronDensity->m_iRes[0] * electronDensity->m_iRes[1] * electronDensity->m_iRes[2] + ix1 + iy1 + iz1]); // } if (sanity) { // mprintf(GREEN, "%d\n", (z4a + z2i * m_iInterpolationFactor + z3i * m_iInterpolationFactor * m_iInterpolationFactor) * electronDensity->m_iRes[0] * electronDensity->m_iRes[1] * electronDensity->m_iRes[2] + ix1 + iy1 + iz1); m_hitCount[(z4a + z2i * m_iInterpolationFactor + z3i * m_iInterpolationFactor * m_iInterpolationFactor) * electronDensity->m_iRes[0] * electronDensity->m_iRes[1] * electronDensity->m_iRes[2] + ix1 + iy1 + iz1] += 1; } else { double ed = (cx1 * (c11 * electronDensity->m_pBin[ix1+iy1+iz1] + c12 * electronDensity->m_pBin[ix1+iy1+iz2] + c21 * electronDensity->m_pBin[ix1+iy2+iz1] + c22 * electronDensity->m_pBin[ix1+iy2+iz2]) + cx2 * (c11 * electronDensity->m_pBin[ix2+iy1+iz1] + c12 * electronDensity->m_pBin[ix2+iy1+iz2] + c21 * electronDensity->m_pBin[ix2+iy2+iz1] + c22 * electronDensity->m_pBin[ix2+iy2+iz2])) / m_iInterpolationFactorCube; if (g_bVoroIntegrateCharge) { // *charge += electronDensity->m_pBin[z3b+z4b]; *charge += ed; } if (g_bVoroIntegrateDipoleMoment) { // (*dipoleMoment)[0] += -(x - refPoint[0]) * electronDensity->m_pBin[z3b+z4b]; // (*dipoleMoment)[1] += -(tfy - refPoint[1]) * electronDensity->m_pBin[z3b+z4b]; // (*dipoleMoment)[2] += -(tfz - refPoint[2]) * electronDensity->m_pBin[z3b+z4b]; (*dipoleMoment)[0] += -(x - refPoint[0]) * ed; (*dipoleMoment)[1] += -(y - refPoint[1]) * ed; (*dipoleMoment)[2] += -(z - refPoint[2]) * ed; } if (g_bVoroIntegrateQuadrupoleMoment) { (*quadrupoleMoment)(0,0) -= ed * (x - refPoint[0]) * (x - refPoint[0]); (*quadrupoleMoment)(0,1) -= ed * (x - refPoint[0]) * (y - refPoint[1]); (*quadrupoleMoment)(0,2) -= ed * (x - refPoint[0]) * (z - refPoint[2]); (*quadrupoleMoment)(1,0) -= ed * (y - refPoint[1]) * (x - refPoint[0]); (*quadrupoleMoment)(1,1) -= ed * (y - refPoint[1]) * (y - refPoint[1]); (*quadrupoleMoment)(1,2) -= ed * (y - refPoint[1]) * (z - refPoint[2]); (*quadrupoleMoment)(2,0) -= ed * (z - refPoint[2]) * (x - refPoint[0]); (*quadrupoleMoment)(2,1) -= ed * (z - refPoint[2]) * (y - refPoint[1]); (*quadrupoleMoment)(2,2) -= ed * (z - refPoint[2]) * (z - refPoint[2]); } if ((currentDensity != NULL) && (g_bVoroIntegrateTotalCurrent || g_bVoroIntegrateMagneticMoment)) { double cdx = (cx1 * (c11 * currentDensity->GetAt((ix1+iy1+iz1)*3) + c12 * currentDensity->GetAt((ix1+iy1+iz2)*3) + c21 * currentDensity->GetAt((ix1+iy2+iz1)*3) + c22 * currentDensity->GetAt((ix1+iy2+iz2)*3)) + cx2 * (c11 * currentDensity->GetAt((ix2+iy1+iz1)*3) + c12 * currentDensity->GetAt((ix2+iy1+iz2)*3) + c21 * currentDensity->GetAt((ix2+iy2+iz1)*3) + c22 * currentDensity->GetAt((ix2+iy2+iz2)*3))) / m_iInterpolationFactorCube; double cdy = (cx1 * (c11 * currentDensity->GetAt((ix1+iy1+iz1)*3 + 1) + c12 * currentDensity->GetAt((ix1+iy1+iz2)*3 + 1) + c21 * currentDensity->GetAt((ix1+iy2+iz1)*3 + 1) + c22 * currentDensity->GetAt((ix1+iy2+iz2)*3 + 1)) + cx2 * (c11 * currentDensity->GetAt((ix2+iy1+iz1)*3 + 1) + c12 * currentDensity->GetAt((ix2+iy1+iz2)*3 + 1) + c21 * currentDensity->GetAt((ix2+iy2+iz1)*3 + 1) + c22 * currentDensity->GetAt((ix2+iy2+iz2)*3 + 1))) / m_iInterpolationFactorCube; double cdz = (cx1 * (c11 * currentDensity->GetAt((ix1+iy1+iz1)*3 + 2) + c12 * currentDensity->GetAt((ix1+iy1+iz2)*3 + 2) + c21 * currentDensity->GetAt((ix1+iy2+iz1)*3 + 2) + c22 * currentDensity->GetAt((ix1+iy2+iz2)*3 + 2)) + cx2 * (c11 * currentDensity->GetAt((ix2+iy1+iz1)*3 + 2) + c12 * currentDensity->GetAt((ix2+iy1+iz2)*3 + 2) + c21 * currentDensity->GetAt((ix2+iy2+iz1)*3 + 2) + c22 * currentDensity->GetAt((ix2+iy2+iz2)*3 + 2))) / m_iInterpolationFactorCube; if (g_bVoroIntegrateTotalCurrent) { // (*totalCurrent)[0] += currentDensity->GetAt((z3b+z4b)*3); // (*totalCurrent)[1] += currentDensity->GetAt((z3b+z4b)*3 + 1); // (*totalCurrent)[2] += currentDensity->GetAt((z3b+z4b)*3 + 2); (*totalCurrent)[0] += cdx; (*totalCurrent)[1] += cdy; (*totalCurrent)[2] += cdz; } if (g_bVoroIntegrateMagneticMoment) { // (*magneticMoment)[0] += (tfy - refPoint[1]) * currentDensity->GetAt((z3b+z4b)*3 + 2); // (*magneticMoment)[0] -= (tfz - refPoint[2]) * currentDensity->GetAt((z3b+z4b)*3 + 1); // (*magneticMoment)[1] += (tfz - refPoint[2]) * currentDensity->GetAt((z3b+z4b)*3); // (*magneticMoment)[1] -= (x - refPoint[0]) * currentDensity->GetAt((z3b+z4b)*3 + 2); // (*magneticMoment)[2] += (x - refPoint[0]) * currentDensity->GetAt((z3b+z4b)*3 + 1); // (*magneticMoment)[2] -= (tfy - refPoint[1]) * currentDensity->GetAt((z3b+z4b)*3); (*magneticMoment)[0] += (y - refPoint[1]) * cdz; (*magneticMoment)[0] -= (z - refPoint[2]) * cdy; (*magneticMoment)[1] += (z - refPoint[2]) * cdx; (*magneticMoment)[1] -= (x - refPoint[0]) * cdz; (*magneticMoment)[2] += (x - refPoint[0]) * cdy; (*magneticMoment)[2] -= (y - refPoint[1]) * cdx; } } } } } } } } } } // CxDVector3 CTetraPak::integrateMoment(C3DF* df, double mi[2], double ma[2], double refPoint[3]) { // int z2, z2b, z3, z3b, z4, z4b, ti, ixa, ixb, iya, iyb, iza, izb; // double xv[4], tfy, tfz, tf; // CxDVector3 rv(0.0, 0.0, 0.0); // // // iya = (int)(mi[0]/(g_fBoxY/1000.0)*df->m_iRes[1] - 0.5); // // iya = (int)floor(mi[0]/(g_fBoxY/1000.0)*df->m_iRes[1]); // iya = (int)floor(mi[0]/(df->m_fMaxVal[1]/1000.0)*df->m_iRes[1]); // // iyb = (int)(ma[0]/(g_fBoxY/1000.0)*df->m_iRes[1] + 0.5); // // iyb = (int)ceil(ma[0]/(g_fBoxY/1000.0)*df->m_iRes[1]); // iyb = (int)ceil(ma[0]/(df->m_fMaxVal[1]/1000.0)*df->m_iRes[1]); // // // iza = (int)(mi[1]/(g_fBoxZ/1000.0)*df->m_iRes[2] - 0.5); // // iza = (int)floor(mi[1]/(g_fBoxZ/1000.0)*df->m_iRes[2]); // iza = (int)floor(mi[1]/(df->m_fMaxVal[2]/1000.0)*df->m_iRes[2]); // // izb = (int)(ma[1]/(g_fBoxZ/1000.0)*df->m_iRes[2] + 0.5); // // izb = (int)ceil(ma[1]/(g_fBoxZ/1000.0)*df->m_iRes[2]); // izb = (int)ceil(ma[1]/(df->m_fMaxVal[2]/1000.0)*df->m_iRes[2]); // // // if (iyb-iya >= df->m_iRes[1]) // // iyb = iya + df->m_iRes[1] - 1; // // // if (izb-iza >= df->m_iRes[2]) // // izb = iza + df->m_iRes[2] - 1; // // for (z2=iya;z2<=iyb;z2++) // { // // tfy = (double)z2 * (g_fBoxY / 1000.0) / df->m_iRes[1]; // tfy = (double)z2 * (df->m_fMaxVal[1] / 1000.0) / df->m_iRes[1]; // // z2b = z2%df->m_iRes[1]; // if (z2b < 0) // z2b += df->m_iRes[1]; // z2b *= df->m_iRes[0]; // // for (z3=iza;z3<=izb;z3++) // { // // tfz = (double)z3 * (g_fBoxZ / 1000.0) / df->m_iRes[2]; // tfz = (double)z3 * (df->m_fMaxVal[2] / 1000.0) / df->m_iRes[2]; // // z3b = z3%df->m_iRes[2]; // if (z3b < 0) // z3b += df->m_iRes[2]; // z3b *= df->m_iResXY; // z3b += z2b; // // ti = 0; // for (z4=0;z4XRay_Hit(tfy,tfz,xv[ti])) // ti++; // // if (ti == 2) // { // if (xv[0] > xv[1]) // { // tf = xv[0]; // xv[0] = xv[1]; // xv[1] = tf; // } // // // if ((xv[0]/(g_fBoxX/1000.0)*df->m_iRes[0]+0.5) < 0) // // ixa = (int)((xv[0]+g_fBoxX/1000.0)/(g_fBoxX/1000.0)*df->m_iRes[0] + 0.5) - df->m_iRes[0]; // // else ixa = (int)(xv[0]/(g_fBoxX/1000.0)*df->m_iRes[0] + 0.5); // // ixa = (int)ceil(xv[0] / (g_fBoxX / 1000.0) * df->m_iRes[0]); // ixa = (int)ceil(xv[0] / (df->m_fMaxVal[0] / 1000.0) * df->m_iRes[0]); // // // if ((xv[1]/(g_fBoxX/1000.0)*df->m_iRes[0] - 0.5) < 0) // // ixb = (int)((xv[1]+g_fBoxX/1000.0)/(g_fBoxX/1000.0)*df->m_iRes[0] - 0.5) - df->m_iRes[0]; // // else ixb = (int)(xv[1]/(g_fBoxX/1000.0)*df->m_iRes[0] - 0.5); // // ixb = (int)floor(xv[1] / (g_fBoxX / 1000.0) * df->m_iRes[0]); // ixb = (int)floor(xv[1] / (df->m_fMaxVal[0] / 1000.0) * df->m_iRes[0]); // // for (z4=ixa;z4<=ixb;z4++) // { // z4b = z4%df->m_iRes[0]; // if (z4b < 0) // z4b += df->m_iRes[0]; // double x = (double)z4 * (df->m_fMaxVal[0] / 1000.0) / df->m_iRes[0]; // // rv[0] += -(x - refPoint[0]) * df->m_pBin[z3b+z4b]; // rv[1] += -(tfy - refPoint[1]) * df->m_pBin[z3b+z4b]; // rv[2] += -(tfz - refPoint[2]) * df->m_pBin[z3b+z4b]; // } // } // } // } // // return rv; // } // CxDVector3 CTetraPak::integrateTotalCurrent(C3DF *df, CxFloatArray *currentDensity, double mi[2], double ma[2]) { // int z2, z2b, z3, z3b, z4, z4b, ti, ixa, ixb, iya, iyb, iza, izb; // double xv[4], tfy, tfz, tf; // CxDVector3 rv(0.0, 0.0, 0.0); // // iya = (int)floor(mi[0]/(df->m_fMaxVal[1]/1000.0)*df->m_iRes[1]); // iyb = (int)ceil(ma[0]/(df->m_fMaxVal[1]/1000.0)*df->m_iRes[1]); // // iza = (int)floor(mi[1]/(df->m_fMaxVal[2]/1000.0)*df->m_iRes[2]); // izb = (int)ceil(ma[1]/(df->m_fMaxVal[2]/1000.0)*df->m_iRes[2]); // // for (z2=iya;z2<=iyb;z2++) // { // tfy = (double)z2 * (df->m_fMaxVal[1] / 1000.0) / df->m_iRes[1]; // // z2b = z2%df->m_iRes[1]; // if (z2b < 0) // z2b += df->m_iRes[1]; // z2b *= df->m_iRes[0]; // // for (z3=iza;z3<=izb;z3++) // { // tfz = (double)z3 * (df->m_fMaxVal[2] / 1000.0) / df->m_iRes[2]; // // z3b = z3%df->m_iRes[2]; // if (z3b < 0) // z3b += df->m_iRes[2]; // z3b *= df->m_iResXY; // z3b += z2b; // // ti = 0; // for (z4=0;z4XRay_Hit(tfy,tfz,xv[ti])) // ti++; // // if (ti == 2) // { // if (xv[0] > xv[1]) // { // tf = xv[0]; // xv[0] = xv[1]; // xv[1] = tf; // } // // ixa = (int)ceil(xv[0] / (df->m_fMaxVal[0] / 1000.0) * df->m_iRes[0]); // ixb = (int)floor(xv[1] / (df->m_fMaxVal[0] / 1000.0) * df->m_iRes[0]); // // for (z4=ixa;z4<=ixb;z4++) // { // z4b = z4%df->m_iRes[0]; // if (z4b < 0) // z4b += df->m_iRes[0]; // // rv[0] += currentDensity->GetAt((z3b+z4b)*3); // rv[1] += currentDensity->GetAt((z3b+z4b)*3 + 1); // rv[2] += currentDensity->GetAt((z3b+z4b)*3 + 2); // } // } // } // } // // return rv; // } // // CxDVector3 CTetraPak::integrateMagneticMoment(C3DF *df, CxFloatArray *currentDensity, double mi[2], double ma[2], double refPoint[3]) { // int z2, z2b, z3, z3b, z4, z4b, ti, ixa, ixb, iya, iyb, iza, izb; // double xv[4], tfy, tfz, tf; // CxDVector3 rv(0.0, 0.0, 0.0); // // iya = (int)floor(mi[0]/(df->m_fMaxVal[1]/1000.0)*df->m_iRes[1]); // iyb = (int)ceil(ma[0]/(df->m_fMaxVal[1]/1000.0)*df->m_iRes[1]); // // iza = (int)floor(mi[1]/(df->m_fMaxVal[2]/1000.0)*df->m_iRes[2]); // izb = (int)ceil(ma[1]/(df->m_fMaxVal[2]/1000.0)*df->m_iRes[2]); // // for (z2=iya;z2<=iyb;z2++) // { // tfy = (double)z2 * (df->m_fMaxVal[1] / 1000.0) / df->m_iRes[1]; // // z2b = z2%df->m_iRes[1]; // if (z2b < 0) // z2b += df->m_iRes[1]; // z2b *= df->m_iRes[0]; // // for (z3=iza;z3<=izb;z3++) // { // tfz = (double)z3 * (df->m_fMaxVal[2] / 1000.0) / df->m_iRes[2]; // // z3b = z3%df->m_iRes[2]; // if (z3b < 0) // z3b += df->m_iRes[2]; // z3b *= df->m_iResXY; // z3b += z2b; // // ti = 0; // for (z4=0;z4XRay_Hit(tfy,tfz,xv[ti])) // ti++; // // if (ti == 2) // { // if (xv[0] > xv[1]) // { // tf = xv[0]; // xv[0] = xv[1]; // xv[1] = tf; // } // // ixa = (int)ceil(xv[0] / (df->m_fMaxVal[0] / 1000.0) * df->m_iRes[0]); // ixb = (int)floor(xv[1] / (df->m_fMaxVal[0] / 1000.0) * df->m_iRes[0]); // // for (z4=ixa;z4<=ixb;z4++) // { // z4b = z4%df->m_iRes[0]; // if (z4b < 0) // z4b += df->m_iRes[0]; // double x = (double)z4 * (df->m_fMaxVal[0] / 1000.0) / df->m_iRes[0]; // // rv[0] += (tfy - refPoint[1]) * currentDensity->GetAt((z3b+z4b)*3 + 2); // rv[0] -= (tfz - refPoint[2]) * currentDensity->GetAt((z3b+z4b)*3 + 1); // rv[1] += (tfz - refPoint[2]) * currentDensity->GetAt((z3b+z4b)*3); // rv[1] -= (x - refPoint[0]) * currentDensity->GetAt((z3b+z4b)*3 + 2); // rv[2] += (x - refPoint[0]) * currentDensity->GetAt((z3b+z4b)*3 + 1); // rv[2] += (tfy - refPoint[1]) * currentDensity->GetAt((z3b+z4b)*3); // } // } // } // } // // return rv; // } inline bool CTetraFace::XRay_Hit(double py, double pz, double &px/*, bool verbose*/) { double tf, a, b, ty, tz; int z; #define lvec1x (m_vSpan1[0]) #define lvec1y (m_vSpan1[1]) #define lvec1z (m_vSpan1[2]) #define lvec2x (m_vSpan2[0]) #define lvec2y (m_vSpan2[1]) #define lvec2z (m_vSpan2[2]) if (g_bBoxNonOrtho) { CxDVector3 veca = CxDVector3(g_mCubeCell(0,0) / 1000.0, g_mCubeCell(0,1) / 1000.0, g_mCubeCell(0,2) / 1000.0); CxDVector3 vecb = CxDVector3(g_mCubeCell(1,0) / 1000.0, g_mCubeCell(1,1) / 1000.0, g_mCubeCell(1,2) / 1000.0); CxDVector3 vecc = CxDVector3(g_mCubeCell(2,0) / 1000.0, g_mCubeCell(2,1) / 1000.0, g_mCubeCell(2,2) / 1000.0); double coorda; CxDVector3 intersection; bool run; do { run = false; coorda = DotP(m_vNormal, m_vCenter - py * vecb - pz * vecc) / DotP(m_vNormal, veca); intersection = coorda * veca + py * vecb + pz * vecc - m_vCenter; // if (verbose) { // mprintf(GREEN, "%26.20g %26.20g %26.20g %26.20g\n", coorda, intersection[0], intersection[1], intersection[2]); // } a = DotP(intersection, m_vSpan1); b = DotP(intersection, m_vSpan2); // if (verbose) { // CxDVector3 v(m_vSpan1); // v *= 1e-5; // v += m_vCenter; // v *= 1000.0; // v = g_mBoxToOrtho * v; // mprintf(GREEN, "Span1: %26.20g %26.20g %26.20g\n", v[0], v[1], v[2]); // v = m_vSpan2; // v *= 1e-5; // v += m_vCenter; // v *= 1000.0; // v = g_mBoxToOrtho * v; // mprintf(GREEN, "Span2: %26.20g %26.20g %26.20g\n", v[0], v[1], v[2]); // v = m_vCenter; // v *= 1000.0; // v = g_mBoxToOrtho * v; // mprintf(GREEN, "Center: %26.20g %26.20g %26.20g\n", v[0], v[1], v[2]); // mprintf(GREEN, "%26.20g %26.20g\n", a, b); // } #ifdef TARGET_WINDOWS if (!_finite(a) || !_finite(b)) return false; #else if (!isfinite(a) || !isfinite(b)) return false; #endif for (z=0;zm_laSingleMolIndex.GetSize();z2++) { sm = (CSingleMolecule*)g_oaSingleMolecules[m->m_laSingleMolIndex[z2]]; mfprintf(g_fMolIntegralFile,"%5lu; %-8s; %3d",g_iSteps+1,m->m_sName,z2+1); if (g_bVoroIntegrateCharge) mfprintf(g_fMolIntegralFile,"; %17.10f",sm->m_fCharge); else mfprintf(g_fMolIntegralFile,"; "); if (g_bVoroIntegrateDipoleMoment) mfprintf(g_fMolIntegralFile,"; %17.10f; %17.10f; %17.10f",sm->m_vDipole[0],sm->m_vDipole[1],sm->m_vDipole[2]); else mfprintf(g_fMolIntegralFile,"; ; ; "); if (g_bVoroIntegrateQuadrupoleMoment) mfprintf(g_fMolIntegralFile,"; %17.10f; %17.10f; %17.10f; %17.10f; %17.10f; %17.10f; %17.10f; %17.10f; %17.10f",sm->m_mQuadrupole[0],sm->m_mQuadrupole[1],sm->m_mQuadrupole[2],sm->m_mQuadrupole[3],sm->m_mQuadrupole[4],sm->m_mQuadrupole[5],sm->m_mQuadrupole[6],sm->m_mQuadrupole[7],sm->m_mQuadrupole[8]); else mfprintf(g_fMolIntegralFile,"; ; ; ; ; ; ; ; ; "); if (g_bVoroIntegrateTotalCurrent) mfprintf(g_fMolIntegralFile,"; %17.10f; %17.10f; %17.10f",sm->m_vCurrent[0],sm->m_vCurrent[1],sm->m_vCurrent[2]); else mfprintf(g_fMolIntegralFile,"; ; ; "); if (g_bVoroIntegrateMagneticMoment) mfprintf(g_fMolIntegralFile,"; %17.10f; %17.10f; %17.10f",sm->m_vMagneticDipole[0],sm->m_vMagneticDipole[1],sm->m_vMagneticDipole[2]); else mfprintf(g_fMolIntegralFile,"; ; ; "); mfprintf(g_fMolIntegralFile,"\n"); } } } void printCubeMemFileName(char *name, int length, bool nextFile) { if (nextFile) g_cubeMemFileIndex += g_cubeMemFileStride; #ifdef TARGET_WINDOWS _snprintf(name, length, "%s%d.cube", g_cubeMemFileNameFixed, g_cubeMemFileIndex); #elif defined TARGET_LINUX snprintf(name, length, "%s%d.cube", g_cubeMemFileNameFixed, g_cubeMemFileIndex); #else sprintf(name, "%s%d.cube", g_cubeMemFileNameFixed, g_cubeMemFileIndex); #endif } travis-src-190101/src/tetrapak.h0100777000000000000000000001644113412725653013433 0ustar00/***************************************************************************** TRAVIS - Trajectory Analyzer and Visualizer http://www.travis-analyzer.de/ Copyright (c) 2009-2019 Martin Brehm 2012-2019 Martin Thomas 2016-2019 Sascha Gehrke This file was written by Martin Brehm and Martin Thomas. --------------------------------------------------------------------------- This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . *****************************************************************************/ #ifndef TETRAPAK_H #define TETRAPAK_H // This must always be the first include directive #include "config.h" #include "xobject.h" #include "xobarray.h" #include "xdvec3array.h" #include "timestep.h" #include "3df.h" #define VORI_EPS 1.0E-11 void DumpMolecularProps(); class CTetraPak : public CxObject { public: CTetraPak(); ~CTetraPak(); void Parse(); bool ParseSilent(CTimeStep *ts); bool BuildVoronoi(CTimeStep *ts, bool verbose, bool sanity, bool sanityall=false); void BuildVoronoiBuffer(CTimeStep *ts); // VORI_FLOAT Integrate(C3DF *df, double mi[2], double ma[2]); VORI_FLOAT Integrate_Refine(C3DF *df, double mi[2], double ma[2]); void Integrate_Verbose(C3DF *df, double mi[2], double ma[2]); void ProcessStep(CTimeStep *ts, bool verbose); CxObArray m_oaFaces; CxObArray m_oaVoroBuffer; C3DF *m_p3DF; int m_fRayCount; int m_fRayHisto[4]; int *m_hitCount; int m_iFaces; CxDoubleArray m_faCharge; bool m_bVoronoiCharges; FILE *m_fCubePipe; bool m_bInterpolation; int m_iInterpolationFactor; // bool m_bInterpolationLinear; int m_iInterpolationFactorCube; double m_totCharge; double m_totChargeElec; double m_totChargeCore; double m_totDip[3]; double m_totDipElec[3]; double m_totDipCore[3]; double m_totQuad[9]; double m_totQuadElec[9]; double m_totQuadCore[9]; double m_totCurrent[3]; double m_totCurrentElec[3]; double m_totCurrentCore[3]; double m_totMagMom[3]; double m_totMagMomElec[3]; double m_totMagMomCore[3]; double m_qRef[3]; bool m_bSaveAtomIntegrals; private: void integrateCell(C3DF *electronDensity, CxDoubleArray *currentDensity, double mi[2], double ma[2], double refPoint[3], double *charge, CxDVector3 *dipoleMoment, CxDMatrix3 *quadrupoleMoment, CxDVector3 *totalCurrent, CxDVector3 *magneticMoment, bool sanity = false/*, int debug = 0*/); // CxDVector3 integrateMoment(C3DF *df, double mi[2], double ma[2], double refPoint[3]); // CxDVector3 integrateTotalCurrent(C3DF *df, CxFloatArray *currentDensity, double mi[2], double ma[2]); // CxDVector3 integrateMagneticMoment(C3DF *df, CxFloatArray *currentDensity, double mi[2], double ma[2], double refPoint[3]); CxDVec3Array m_moments; std::vector m_maQuadTensor; CxDVec3Array m_totalCurrent; CxDVec3Array m_magneticMoments; bool m_saveTotalIntegrals; FILE *m_totalIntegralFile; FILE *m_fAtomIntegralFile; // bool m_saveAtomCharges; // FILE *m_atomChargeFile; // bool m_saveMolCharges; // FILE *m_molChargeFile; }; class CTetraFace : public CxObject { public: CTetraFace() { } ~CTetraFace() { } bool XRay_Hit(double py, double pz, double &px/*, bool verbose=false*/); // { // double tf, a, b, ty, tz; // int z; // // #define lvec1x (m_vSpan1[0]) // #define lvec1y (m_vSpan1[1]) // #define lvec1z (m_vSpan1[2]) // #define lvec2x (m_vSpan2[0]) // #define lvec2y (m_vSpan2[1]) // #define lvec2z (m_vSpan2[2]) // // // Hack from 09.10.2014: Ray cannot hit walls which are almost parallel... // // if (fabs(m_vNormal[0]) < 1.0E-14) // // return false; // // ty = py - m_vCenter[1]; // tz = pz - m_vCenter[2]; // if (verbose) // mprintf(GREEN, "%.20g %.20g\n", ty, tz); // // tf = -lvec1z*lvec2y + lvec1y*lvec2z; // // bool run; // do { // run = false; // // a = (-tz*lvec2y + ty*lvec2z)/tf; // b = ( tz*lvec1y - ty*lvec1z)/tf; // // // if (verbose) // // mprintf(GREEN, "%.20g %.20g\n", a, b); // // #ifdef TARGET_WINDOWS // if (!_finite(a) || !_finite(b)) // return false; // #else // if (!isfinite(a) || !isfinite(b)) // return false; // #endif // // for (z=0;z. *****************************************************************************/ // This must always be the first include directive #include "config.h" #include "timestep.h" #include "travis.h" #include "tools.h" #include "maintools.h" #include "conversion.h" const char *GetRevisionInfo_timestep(unsigned int len) { static char buf[256]; GET_REVISION_INFO( buf, len ); return buf; } const char *GetSourceVersion_timestep() { static char buf[256]; GET_SOURCE_VERSION( buf ); return buf; } bool CTimeStep::m_bFirst = true; void CTimeStep::CalcCenters() { BTIN; int z, z2, z3, z4, c; CxDVector3 tv; CMolecule *m; CVirtualAtom *v; CSingleMolecule *sm; tv = CxDVector3(0); // mprintf("** CalcCenters **"); if (m_vaCoords.GetSize() < g_iGesVirtAtomCount) m_vaCoords.SetSize(g_iGesVirtAtomCount); // mprintf("CalcCenters(): Size is now %d.\n",m_vaCoords.GetSize()); if (g_bUseVelocities) if (m_vaVelocities.GetSize() < g_iGesVirtAtomCount) m_vaVelocities.SetSize(g_iGesVirtAtomCount); if (g_bUseForces) if (m_vaForces.GetSize() < g_iGesVirtAtomCount) m_vaForces.SetSize(g_iGesVirtAtomCount); for (z=0;zm_iMolecule]; for (z2=0;z2m_laSingleMolIndex.GetSize();z2++) { sm = (CSingleMolecule*)g_oaSingleMolecules[m->m_laSingleMolIndex[z2]]; if (v->m_iMode == 0) // Mittel aus Atompositionen { tv = CxDVector3(0); c = 0; for (z3=0;z3m_oCenterAtoms.m_baAtomType.GetSize();z3++) { for (z4=0;z4<((CxIntArray*)v->m_oCenterAtoms.m_oaAtoms[z3])->GetSize();z4++) { // mprintf("{%d:(%G|%G|%G) }\n",((CxIntArray*)sm->m_oaAtomOffset[v->m_oCenterAtoms.m_baAtomType[z3]])->GetAt(((CxIntArray*)v->m_oCenterAtoms.m_oaAtoms[z3])->GetAt(z4)),m_vaCoords[((CxIntArray*)sm->m_oaAtomOffset[v->m_oCenterAtoms.m_baAtomType[z3]])->GetAt(((CxIntArray*)v->m_oCenterAtoms.m_oaAtoms[z3])->GetAt(z4))][0],m_vaCoords[((CxIntArray*)sm->m_oaAtomOffset[v->m_oCenterAtoms.m_baAtomType[z3]])->GetAt(((CxIntArray*)v->m_oCenterAtoms.m_oaAtoms[z3])->GetAt(z4))][1],m_vaCoords[((CxIntArray*)sm->m_oaAtomOffset[v->m_oCenterAtoms.m_baAtomType[z3]])->GetAt(((CxIntArray*)v->m_oCenterAtoms.m_oaAtoms[z3])->GetAt(z4))][2]); tv += m_vaCoords[((CxIntArray*)sm->m_oaAtomOffset[v->m_oCenterAtoms.m_baAtomType[z3]])->GetAt(((CxIntArray*)v->m_oCenterAtoms.m_oaAtoms[z3])->GetAt(z4))] * v->m_faWeight[c]; c++; } } tv /= v->m_fGesWeight; } else if (v->m_iMode == 1) // Abstand, Winkel, Dihedralwinkel { tv = PointFromRAD(m_vaCoords[((CxIntArray*)sm->m_oaAtomOffset[v->m_iAtomType[0]])->GetAt(v->m_iAtom[0])],m_vaCoords[((CxIntArray*)sm->m_oaAtomOffset[v->m_iAtomType[1]])->GetAt(v->m_iAtom[1])],m_vaCoords[((CxIntArray*)sm->m_oaAtomOffset[v->m_iAtomType[2]])->GetAt(v->m_iAtom[2])],v->m_fValues[0],v->m_fValues[1],v->m_fValues[2]); } else if (v->m_iMode == 2) // Dipolvektor { /* if (!g_bDipole) { eprintf("Cannot use dipole vectors.\n"); BTOUT; return; } tv = sm->m_vDipole + m_vaCoords[((CxIntArray*)sm->m_oaAtomOffset[sm->m_baAtomIndex.GetSize()-1])->GetAt(0)];*/ tv = CxDVector3(0,0,0); // Dipolmoment wird erst spaeter ausgerechnet } else if (v->m_iMode == 3) // Geschwindigkeitsvektor { } else if (v->m_iMode == 4) // Kraftvektor { } // mprintf("%d:(%G|%G|%G), ",((CxIntArray*)sm->m_oaAtomOffset[sm->m_baAtomIndex.GetSize()-1])->GetAt(v->m_iMolVirtAtom),tv[0],tv[1],tv[2]); m_vaCoords[((CxIntArray*)sm->m_oaAtomOffset[sm->m_baAtomIndex.GetSize()-1])->GetAt(v->m_iMolVirtAtom)] = tv; } } BTOUT; } void CTimeStep::CalcCenterVelocities() { int z, z2, z3, z4, c; CxDVector3 tv; CMolecule *m; CVirtualAtom *v; CSingleMolecule *sm; if (g_bUseVelocities) if (m_vaVelocities.GetSize() < g_iGesVirtAtomCount) m_vaVelocities.SetSize(g_iGesVirtAtomCount); for (z=0;zm_iMolecule]; for (z2=0;z2m_laSingleMolIndex.GetSize();z2++) { // mprintf("\nCenter %d.%d: ",z+1,z2+1); sm = (CSingleMolecule*)g_oaSingleMolecules[m->m_laSingleMolIndex[z2]]; if (v->m_iMode == 0) { // Mittel aus Atompositionen tv = CxDVector3(0); c = 0; for (z3=0;z3m_oCenterAtoms.m_baAtomType.GetSize();z3++) { for (z4=0;z4<((CxIntArray*)v->m_oCenterAtoms.m_oaAtoms[z3])->GetSize();z4++) { /* mprintf(" + %5g * (%10g|%10g|%10g)", v->m_faWeight[c], m_vaVelocities[((CxIntArray*)sm->m_oaAtomOffset[v->m_oCenterAtoms.m_baAtomType[z3]])->GetAt(((CxIntArray*)v->m_oCenterAtoms.m_oaAtoms[z3])->GetAt(z4))][0], m_vaVelocities[((CxIntArray*)sm->m_oaAtomOffset[v->m_oCenterAtoms.m_baAtomType[z3]])->GetAt(((CxIntArray*)v->m_oCenterAtoms.m_oaAtoms[z3])->GetAt(z4))][1], m_vaVelocities[((CxIntArray*)sm->m_oaAtomOffset[v->m_oCenterAtoms.m_baAtomType[z3]])->GetAt(((CxIntArray*)v->m_oCenterAtoms.m_oaAtoms[z3])->GetAt(z4))][2] );*/ tv += m_vaVelocities[((CxIntArray*)sm->m_oaAtomOffset[v->m_oCenterAtoms.m_baAtomType[z3]])->GetAt(((CxIntArray*)v->m_oCenterAtoms.m_oaAtoms[z3])->GetAt(z4))] * v->m_faWeight[c]; c++; } } tv /= v->m_fGesWeight; /* mprintf("\n"); mprintf(" --> (%10g|%10g|%10g)",tv[0],tv[1],tv[2]);*/ m_vaVelocities[((CxIntArray*)sm->m_oaAtomOffset[sm->m_baAtomIndex.GetSize()-1])->GetAt(v->m_iMolVirtAtom)] = tv; } else m_vaVelocities[((CxIntArray*)sm->m_oaAtomOffset[sm->m_baAtomIndex.GetSize()-1])->GetAt(v->m_iMolVirtAtom)] = CxDVector3(0); } } } bool CTimeStep::BondRange(int i1, int i2, double *f) { BTIN; int a, b; double d; CxDVector3 v; if (g_iScanMolStep == -1) return false; v = FoldVector(m_vaCoords[i1] - m_vaCoords[i2]); d = v.GetLength(); if (f != NULL) *f = d; a = g_baAtomIndex[i1]; b = g_baAtomIndex[i2]; if ((a >= g_oaAtoms.GetSize()) || (b >= g_oaAtoms.GetSize())) { BTOUT; return false; } if (((CAtom*)g_oaAtoms[a])->m_pElement->m_fRadius == 0) { BTOUT; return false; } if (((CAtom*)g_oaAtoms[b])->m_pElement->m_fRadius == 0) { BTOUT; return false; } if (d < (((CAtom*)g_oaAtoms[a])->m_pElement->m_fRadius+((CAtom*)g_oaAtoms[b])->m_pElement->m_fRadius)*g_fBondFactor) { // printf(" \"%s\" br=%f, \"%s\" br=%f Hat Nachbarn %s%d im Abstand von %.3f.\n",m_pLabels[i1],c1,m_pLabels[i2],c2,m_pLabels[i2],i2+1,d); BTOUT; return true; } else { BTOUT; return false; } } bool CTimeStep::MirrorBond(int i1, int i2) { BTIN; bool changed; changed = false; if (g_bBoxNonOrtho) { CxDVector3 w1, w2; w1 = g_mBoxToOrtho * m_vaCoords[i1]; w2 = g_mBoxToOrtho * m_vaCoords[i2]; while (w1[0]-w2[0] > 0.5) { w2[0] += 1.0; changed = true; } while (w1[0]-w2[0] <= -0.5) { w2[0] -= 1.0; changed = true; } while (w1[1]-w2[1] > 0.5) { w2[1] += 1.0; changed = true; } while (w1[1]-w2[1] <= -0.5) { w2[1] -= 1.0; changed = true; } while (w1[2]-w2[2] > 0.5) { w2[2] += 1.0; changed = true; } while (w1[2]-w2[2] <= -0.5) { w2[2] -= 1.0; changed = true; } if (changed) m_vaCoords[i2] = g_mBoxFromOrtho * w2; } else { if (g_bPeriodicX) { while (m_vaCoords[i1][0]-m_vaCoords[i2][0] > g_fBoxX/2) { m_vaCoords[i2][0] += g_fBoxX; changed = true; } while (m_vaCoords[i2][0]-m_vaCoords[i1][0] > g_fBoxX/2) { m_vaCoords[i2][0] -= g_fBoxX; changed = true; } } if (g_bPeriodicY) { while (m_vaCoords[i1][1]-m_vaCoords[i2][1] > g_fBoxY/2) { m_vaCoords[i2][1] += g_fBoxY; changed = true; } while (m_vaCoords[i2][1]-m_vaCoords[i1][1] > g_fBoxY/2) { m_vaCoords[i2][1] -= g_fBoxY; changed = true; } } if (g_bPeriodicZ) { while (m_vaCoords[i1][2]-m_vaCoords[i2][2] > g_fBoxZ/2) { m_vaCoords[i2][2] += g_fBoxZ; changed = true; } while (m_vaCoords[i2][2]-m_vaCoords[i1][2] > g_fBoxZ/2) { m_vaCoords[i2][2] -= g_fBoxZ; changed = true; } } } if (changed) { BTOUT; return true; } BTOUT; return false; } void CTimeStep::RECURSION_ScanMolecules(int i, CxByteArray *ta, CSingleMolecule *sm, int depth, int *stack, unsigned long bmask, bool w) { BTIN; int z, z2, z0; int nblist[64], nbs; double f; CxIntArray *wa; CMolAtom *ma; std::vector vnb; // mprintf(" Rekursion fuer Atom %d.\n",i+1); // mprintf("Depth=%d, i=%d.\n",depth,i); if (g_bVerbose) { mprintf(" "); for (z=1;zm_sName); mprintf("(%d)",i+1); } stack[depth] = i; g_laAtomSMIndex[i] = (unsigned long)g_oaSingleMolecules.GetSize()-1; (*ta)[i] = 1; // mprintf(" sm->m_baAtomIndex.GetSize()=%d\n",sm->m_baAtomIndex.GetSize()); for (z=0;zm_baAtomIndex.GetSize();z++) { if (sm->m_baAtomIndex[z] == g_baAtomIndex[i]) { try { ma = new CMolAtom(); } catch(...) { ma = NULL; } if (ma == NULL) NewException((double)sizeof(CMolAtom),__FILE__,__LINE__,__PRETTY_FUNCTION__); g_oaMolAtoms[i] = ma; ma->m_iOffset = i; ma->m_iType = z; sm->m_oaMolAtoms.Add(ma); goto _ok; } } try { ma = new CMolAtom(); } catch(...) { ma = NULL; } if (ma == NULL) NewException((double)sizeof(CMolAtom),__FILE__,__LINE__,__PRETTY_FUNCTION__); g_oaMolAtoms[i] = ma; ma->m_iOffset = i; ma->m_iType = sm->m_baAtomIndex.GetSize(); ma->m_iNumber = 0; sm->m_oaMolAtoms.Add(ma); sm->m_baAtomIndex.Add(g_baAtomIndex[i]); _ok: m_iConnectedAtoms++; if (!g_bVerbose) if ((m_iConnectedAtoms % m_iGesAtomModulo)==0) mprintf(WHITE,"#"); nbs = 0; // for (z=0;z<(long)m_iGesAtomCount;z++) // Schon mal alle Nachbarn raussuchen m_pPosDomainEngine->FindNeighbors(i,vnb); for (z0=0;z0<(int)vnb.size();z0++) { z = vnb[z0]; if (z == i) continue; if (((CAtom*)g_oaAtoms[g_baAtomIndex[z]])->m_bExclude) continue; if (BondRange(i,z,&f)) { if ((*ta)[z] != 0) { if ((depth > 0) && (z != stack[depth-1])) { if (sm->m_oaRings.GetSize() < 100) { if (g_bVerbose) { mprintf(GREEN," <-- Ring closure: "); mprintf("%s(%d)",(const char*)((CAtom*)g_oaAtoms[g_baAtomIndex[stack[depth]]])->m_sName,stack[depth]+1); } try { wa = new CxIntArray("CTimeStep::RECURSION_ScanMolecules():wa"); } catch(...) { wa = NULL; } if (wa == NULL) NewException((double)sizeof(CxIntArray),__FILE__,__LINE__,__PRETTY_FUNCTION__); sm->m_oaRings.Add(wa); wa->Add(stack[depth]); z2 = depth-1; while ((stack[z2] != z) && (z2 >= 0)) { wa->Add(stack[z2]); if (g_bVerbose) mprintf(" - %s(%d)",(const char*)((CAtom*)g_oaAtoms[g_baAtomIndex[stack[z2]]])->m_sName,stack[z2]+1); z2--; } wa->Add(z); if (g_bVerbose) mprintf(" - %s(%d)",(const char*)((CAtom*)g_oaAtoms[g_baAtomIndex[z]])->m_sName,z+1); } else if (!m_bAbortRing) { m_bAbortRing = true; eprintf("\n### More than 100 rings, aborting ring system scan for molecule %d.",sm->m_iIndex+1); } } continue; } /* for (z2=0;z2m_sName,z+1); mprintf(GREEN," <-- This bond has been broken, skipping.\n"); } g_iBondBlackListUsed++; goto _nextnb; }*/ if (f < 50.0) { if (g_iCloseAtomCounter < 25) eprintf("\n### The atoms %s(%d) and %s(%d) are VERY close to each other. (Distance=%.4f pm)",(const char*)((CAtom*)g_oaAtoms[g_baAtomIndex[i]])->m_sName,i+1,(const char*)((CAtom*)g_oaAtoms[g_baAtomIndex[z]])->m_sName,z+1,f); else if (g_iCloseAtomCounter == 25) eprintf("\n### Suppressing further \"atoms close to each other\" warnings."); g_iCloseAtomCounter++; } nblist[nbs] = z; nbs++; if (nbs >= MAX_BONDS) { eprintf("\n### Atom %s(%d) has more than %d bonds. Ignoring further bonds (defined via MAX_BONDS in config.h).",(const char*)((CAtom*)g_oaAtoms[g_baAtomIndex[i]])->m_sName,i+1,MAX_BONDS); goto _nbdone; } } } _nbdone: if (g_bVerbose) mprintf("\n"); for (z=0;zm_sName); mprintf("(%d)",nblist[z]+1); mprintf(GREEN," <-- This bond shall be broken, skipping.\n"); } g_iBondBlackListUsed++; goto _nextnb; } } sm->m_laBonds.Add(i); sm->m_laBonds.Add(nblist[z]); if ((*ta)[nblist[z]] == 0) // Der Nachbar ist noch immer frei { if (z+1 == nbs) bmask -= (int)mypow(2.0,depth+1); RECURSION_ScanMolecules(nblist[z],ta,sm,depth+1,stack,bmask,(z+1==nbs)?false:true); } else // Ringschluss { if (g_bVerbose) { mprintf(" "); for (z2=1;z2m_sName); mprintf("(%d)",nblist[z]+1); mprintf(GREEN," <-- Ring closure\n"); } } _nextnb:; } BTOUT; } void CTimeStep::BuildAtomIndex() { BTIN; int z, z2; CAtom *at; // char buf[64]; CxString buf; g_baAtomIndex.SetSize(m_iGesAtomCount); for (z=0;z<(long)m_iGesAtomCount;z++) { // strcpy(buf,(char*)m_paLabels[z]); buf.strcpy((char*)m_paLabels[z]); ReplaceDigits(&buf); for (z2=0;z2m_sName)==0) { at = (CAtom*)g_oaAtoms[z2]; // mprintf("Atom %d: Type %d (%s).\n",z,z2,at->m_sName); while (at->m_pMergedTo != NULL) { at = at->m_pMergedTo; // mprintf(" ...was merged to %s.\n",at->m_sName); } // mprintf(" Index is %d.\n",at->m_iIndex); g_baAtomIndex[z] = (unsigned char)at->m_iIndex; goto _e; } } g_baAtomIndex[z] = 255; eprintf("Error: CTimeStep::BuildAtomIndex(): Atom type \"%s\" not known.\n",(const char*)buf); _e:; } BTOUT; } bool CTimeStep::ScanMolecules() { BTIN; int z, z2, z3, z4, z5, i, i2, ti, ti2, i1; CxByteArray ta; CSingleMolecule *sm, *sm2; CxIntArray *wa, *waz2, *waz3, *waneu; CMolecule *m; CMolAtom *ma, *ma2, *ma3; CMolBond *bond, *bond2; CMolBondGroup *bg; CMolAngle *angle, *angle2; CMolAngleGroup *ag; CAtom *at; double f; bool b; double tfs; int *stack; BuildAtomIndex(); // CalcRadii(); try { stack = new int[g_iGesAtomCount]; } catch(...) { stack = NULL; } if (stack == NULL) NewException((double)g_iGesAtomCount*sizeof(int),__FILE__,__LINE__,__PRETTY_FUNCTION__); b = false; for (z=0;zm_pMergedTo != NULL) continue; if (at->m_pElement->m_fRadius == 0) { if (!b) { b = true; mprintf("\n"); } //at->m_bExclude = AskYesNo(" Atom type \"%s\" has bond radius 0. Exclude it from the system (y/n)? [yes] ",true,(const char*)at->m_sName); // at->m_bExclude = false; // if (!at->m_bExclude) // at->m_pElement->m_fRadius = AskFloat_ND(" Please enter covalent bond radius for %s (in pm): ",at->m_sName); } } ta.SetSize(g_iGesAtomCount); g_laAtomSMIndex.SetSize(g_iGesAtomCount); g_oaMolAtoms.SetSize(g_iGesAtomCount); for (z=0;zm_bExclude) continue; try { sm = new CSingleMolecule(); } catch(...) { sm = NULL; } if (sm == NULL) NewException((double)sizeof(CSingleMolecule),__FILE__,__LINE__,__PRETTY_FUNCTION__); sm->m_iIndex = g_oaSingleMolecules.GetSize(); g_oaSingleMolecules.Add(sm); g_laAtomSMIndex[z] = (unsigned long)g_oaSingleMolecules.GetSize()-1; try { ma = new CMolAtom(); } catch(...) { ma = NULL; } if (ma == NULL) NewException((double)sizeof(CMolAtom),__FILE__,__LINE__,__PRETTY_FUNCTION__); ma->m_iOffset = z; ma->m_iType = sm->m_baAtomIndex.GetSize(); ma->m_iNumber = 0; sm->m_oaMolAtoms.Add(ma); sm->m_baAtomIndex.Add(g_baAtomIndex[z]); } mprintf(" %d molecules found.\n\n",g_oaSingleMolecules.GetSize()); } else { // fflush(stdout); m_pPosDomainEngine = new CPosDomainEngine(); f = 0; for (z=0;zm_pElement->m_fRadius > f) f = ((CAtom*)g_oaAtoms[z])->m_pElement->m_fRadius; f *= 2 * g_fBondFactor; if (g_bPeriodicX && g_bPeriodicY && g_bPeriodicZ) m_pPosDomainEngine->Create( m_vaCoords, g_mBoxFromOrtho, f ); else m_pPosDomainEngine->CreateTrivial( m_vaCoords ); if (g_bAdvanced1 && !m_pPosDomainEngine->m_bTrivial) { if (!AskYesNo(" Use spatial domain decomposition for faster mol. rec. (disable if there are problems) (y/n)? [yes] ",true)) { delete m_pPosDomainEngine; m_pPosDomainEngine = new CPosDomainEngine(); m_pPosDomainEngine->CreateTrivial( m_vaCoords ); } } if (m_pPosDomainEngine->m_bTrivial) mprintf("\n Not using spatial domain engine (min. diameter = %.0f pm).\n",f); else mprintf("\n Initialized spatial domain engine with %d x %d x %d cells, min. diameter = %.0f pm.\n",m_pPosDomainEngine->m_iRes[0],m_pPosDomainEngine->m_iRes[1],m_pPosDomainEngine->m_iRes[2],f); if (g_bVerbose) { mprintf(WHITE,"\n Molecule recognition...\n\n"); mprintf(WHITE,">>> Output of the molecule tree >>>\n"); } else mprintf("\n Molecule recognition ["); for (z=0;z<(long)m_iGesAtomCount;z++) { if (ta[z] != 0) // Dieses Atom wurde bereits in irgendein Molekuel eingebaut { // mprintf("> Atom %d: Schon vergeben.\n",z+1); continue; } // mprintf("# Atom %d: Starte Rekursion.\n",z+1); if (((CAtom*)g_oaAtoms[g_baAtomIndex[z]])->m_bExclude) continue; try { sm = new CSingleMolecule(); } catch(...) { sm = NULL; } if (sm == NULL) NewException((double)sizeof(CSingleMolecule),__FILE__,__LINE__,__PRETTY_FUNCTION__); sm->m_iIndex = g_oaSingleMolecules.GetSize(); g_oaSingleMolecules.Add(sm); // sm->m_iAtomGes = 0; /* for (z2=0;z2<16;z2++) sm->m_iAtomCount[z2] = 0; sm->m_iElements = 0;*/ if (g_bVerbose) mprintf(YELLOW,"\nThe next molecule starts with %s(%d):\n",(const char*)m_paLabels[z],z+1); m_bAbortRing = false; RECURSION_ScanMolecules(z,&ta,sm,0,stack,0xFFFFFFFF,true); // printf("%d Atome in diesem Molekuel.\n",g_pSingleMolecules[g_oaSingleMolecules.GetSize()].AtomGes); // g_oaSingleMolecules.GetSize()++; } delete m_pPosDomainEngine; if (g_bVerbose) { mprintf(WHITE,"\n<<< Output of the molecule tree <<<\n\n"); mprintf("%d molecules found.\n\n",g_oaSingleMolecules.GetSize()); } else mprintf("]\n\n %d molecules found.\n\n",g_oaSingleMolecules.GetSize()); } if (g_iCloseAtomCounter != 0) { mprintf(RED,"\n*** Warning: "); mprintf("Some of the atoms were found to be very close to each other (distance < 50 pm).\n"); mprintf(" This usually indicates a problem, e.g. an incorrect cell vector.\n\n"); if (!AskYesNo(" Continue with molecule recognition anyways (y/n)? [yes] ",true)) return false; mprintf("\n"); } mprintf(" Sorting atom types...\n"); SortSingleMolAtomTypes(); delete[] stack; /* mprintf("\n"); for (z=0;zDump(); } mprintf("$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$\n");*/ /* mprintf("\n"); for (z=0;zDump(); } mprintf("$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$\n");*/ if (g_iBondBlackListUsed != 0) mprintf(" %d bonds have been broken.\n",g_iBondBlackListUsed); /* if (g_oaSingleMolecules.GetSize() >= 4096) { mprintf("\n>>> Mehr als 4096 Molekuele! Dies wird nicht unterstuetzt. <<<\n\n"); // g_oaSingleMolecules.GetSize() = 4096; }*/ mprintf(" Setting up bond lists...\n"); // Die Bindungen in m_oaMolAtoms aufbauen for (z=0;zm_laBonds.GetSize()/2;z2++) { i = sm->m_laBonds[z2*2]; i2 = sm->m_laBonds[z2*2+1]; ti = -1; for (z3=0;z3m_oaMolAtoms.GetSize();z3++) { if (((CMolAtom*)sm->m_oaMolAtoms[z3])->m_iOffset == i) { ti = z3; break; } } if (ti == -1) { eprintf("CTimeStep::ScanMolecules(): Atom 1 of bond (%d) not found.\n",i); return false; } ti2 = -1; for (z3=0;z3m_oaMolAtoms.GetSize();z3++) { if (((CMolAtom*)sm->m_oaMolAtoms[z3])->m_iOffset == i2) { ti2 = z3; break; } } if (ti2 == -1) { eprintf("CTimeStep::ScanMolecules(): Atom 2 of bond (%d) not found.\n",i2); return false; } ((CMolAtom*)sm->m_oaMolAtoms[ti])->m_oaBonds.Add((CMolAtom*)sm->m_oaMolAtoms[ti2]); ((CMolAtom*)sm->m_oaMolAtoms[ti2])->m_oaBonds.Add((CMolAtom*)sm->m_oaMolAtoms[ti]); } } // Die AtomCodes berechnen mprintf(" Building atom codes...\n"); for (z=0;zBuildAtomCodes(); } mprintf(" Creating topological atom order...\n"); for (z=0;zm_baAtomIndex.GetSize();z2++) { try { wa = new CxIntArray("CTimeStep::ScanMolecules():wa"); } catch(...) { wa = NULL; } if (wa == NULL) NewException((double)sizeof(CxIntArray),__FILE__,__LINE__,__PRETTY_FUNCTION__); sm->m_oaAtomOffset.Add(wa); for (z3=0;z3m_oaMolAtoms.GetSize();z3++) { ma = (CMolAtom*)sm->m_oaMolAtoms[z3]; if (ma->m_iType != z2) continue; ma->m_iNumber = wa->GetSize(); wa->Add(ma->m_iOffset); } } } mprintf(" Creating bond list...\n"); for (z=0;zm_oaMolAtoms.GetSize();z2++) { ma = (CMolAtom*)sm->m_oaMolAtoms[z2]; for (z3=0;z3m_oaBonds.GetSize();z3++) { ma2 = (CMolAtom*)ma->m_oaBonds[z3]; if (ma2->m_iMolAtomNumber < z2 /* == ma->m_iMolAtomNumber*/) continue; // mprintf(" %s%2d <--> %s%2d\n",((CAtom*)g_oaAtoms[sm->m_baAtomIndex[ma->m_iType]])->m_sName,ma->m_iNumber+1,((CAtom*)g_oaAtoms[sm->m_baAtomIndex[ma2->m_iType]])->m_sName,ma2->m_iNumber+1); try { bond = new CMolBond(); } catch(...) { bond = NULL; } if (bond == NULL) NewException((double)sizeof(CMolBond),__FILE__,__LINE__,__PRETTY_FUNCTION__); bond->m_iAtom[0] = ma->m_iNumber; bond->m_iAtom[1] = ma2->m_iNumber; //mprintf("@ %d-%d\n",ma->m_iNumber,ma2->m_iNumber); bond->m_iAtomType[0] = ma->m_iType; bond->m_iAtomType[1] = ma2->m_iType; bond->m_iMolAtom[0] = z2; bond->m_iMolAtom[1] = ma2->m_iMolAtomNumber; bond->m_iAtomOffset[0] = ma->m_iOffset; bond->m_iAtomOffset[1] = ma2->m_iOffset; sm->m_oaBonds.Add(bond); } } /* if (z == 0) mprintf(" %d Bonds added.\n",oatemp.GetSize());*/ for (z2=0;z2m_oaBonds.GetSize();z2++) { bond = (CMolBond*)sm->m_oaBonds[z2]; for (z3=0;z3m_oaBondGroups.GetSize();z3++) { bg = (CMolBondGroup*)sm->m_oaBondGroups[z3]; for (z4=0;z4m_oaBonds.GetSize();z4++) { bond2 = (CMolBond*)bg->m_oaBonds[z4]; /* if (((((CMolAtom*)sm->m_oaMolAtoms[bond->m_iMolAtom[0]])->m_fAtomCode == ((CMolAtom*)sm->m_oaMolAtoms[bond2->m_iMolAtom[0]])->m_fAtomCode) && (((CMolAtom*)sm->m_oaMolAtoms[bond->m_iMolAtom[1]])->m_fAtomCode == ((CMolAtom*)sm->m_oaMolAtoms[bond2->m_iMolAtom[1]])->m_fAtomCode)) || ((((CMolAtom*)sm->m_oaMolAtoms[bond->m_iMolAtom[0]])->m_fAtomCode == ((CMolAtom*)sm->m_oaMolAtoms[bond2->m_iMolAtom[1]])->m_fAtomCode) && (((CMolAtom*)sm->m_oaMolAtoms[bond->m_iMolAtom[1]])->m_fAtomCode == ((CMolAtom*)sm->m_oaMolAtoms[bond2->m_iMolAtom[0]])->m_fAtomCode))) */ if (((((CMolAtom*)sm->m_oaMolAtoms[bond->m_iMolAtom[0]])->m_liAtomCode == ((CMolAtom*)sm->m_oaMolAtoms[bond2->m_iMolAtom[0]])->m_liAtomCode) && (((CMolAtom*)sm->m_oaMolAtoms[bond->m_iMolAtom[1]])->m_liAtomCode == ((CMolAtom*)sm->m_oaMolAtoms[bond2->m_iMolAtom[1]])->m_liAtomCode)) || ((((CMolAtom*)sm->m_oaMolAtoms[bond->m_iMolAtom[0]])->m_liAtomCode == ((CMolAtom*)sm->m_oaMolAtoms[bond2->m_iMolAtom[1]])->m_liAtomCode) && (((CMolAtom*)sm->m_oaMolAtoms[bond->m_iMolAtom[1]])->m_liAtomCode == ((CMolAtom*)sm->m_oaMolAtoms[bond2->m_iMolAtom[0]])->m_liAtomCode))) { bg->m_oaBonds.Add(bond); goto _bonddone; } } } try { bg = new CMolBondGroup(); } catch(...) { bg = NULL; } if (bg == NULL) NewException((double)sizeof(CMolBondGroup),__FILE__,__LINE__,__PRETTY_FUNCTION__); bg->m_oaBonds.Add(bond); sm->m_oaBondGroups.Add(bg); _bonddone:; } /* if (z == 0) { mprintf(" %d Bond groups found:\n",sm->m_oaBondGroups.GetSize()); for (z2=0;z2m_oaBondGroups.GetSize();z2++) { mprintf(" - "); bg = (CMolBondGroup*)sm->m_oaBondGroups[z2]; for (z3=0;z3m_oaBonds.GetSize();z3++) { bond = (CMolBond*)bg->m_oaBonds[z3]; mprintf("%s%2d <--> %s%2d",((CAtom*)g_oaAtoms[sm->m_baAtomIndex[bond->m_iAtomType[0]]])->m_sName,bond->m_iAtom[0]+1,((CAtom*)g_oaAtoms[sm->m_baAtomIndex[bond->m_iAtomType[1]]])->m_sName,bond->m_iAtom[1]+1); if (z3 < bg->m_oaBonds.GetSize()-1) mprintf(", "); } mprintf("\n"); } }*/ } mprintf(" Creating angle list...\n"); for (z=0;zm_oaMolAtoms.GetSize();z2++) { ma = (CMolAtom*)sm->m_oaMolAtoms[z2]; for (z3=0;z3m_oaBonds.GetSize();z3++) { ma2 = (CMolAtom*)ma->m_oaBonds[z3]; for (z4=z3+1;z4m_oaBonds.GetSize();z4++) { ma3 = (CMolAtom*)ma->m_oaBonds[z4]; // mprintf(" (%s%2d, %s%2d, %s%2d)\n",((CAtom*)g_oaAtoms[sm->m_baAtomIndex[ma2->m_iType]])->m_sName,ma2->m_iNumber+1,((CAtom*)g_oaAtoms[sm->m_baAtomIndex[ma->m_iType]])->m_sName,ma->m_iNumber+1,((CAtom*)g_oaAtoms[sm->m_baAtomIndex[ma3->m_iType]])->m_sName,ma3->m_iNumber+1); try { angle = new CMolAngle(); } catch(...) { angle = NULL; } if (angle == NULL) NewException((double)sizeof(CMolAngle),__FILE__,__LINE__,__PRETTY_FUNCTION__); angle->m_iAtom[0] = ma2->m_iNumber; angle->m_iAtom[1] = ma->m_iNumber; angle->m_iAtom[2] = ma3->m_iNumber; angle->m_iAtomType[0] = ma2->m_iType; angle->m_iAtomType[1] = ma->m_iType; angle->m_iAtomType[2] = ma3->m_iType; angle->m_iMolAtom[0] = ma2->m_iMolAtomNumber; angle->m_iMolAtom[1] = z2; angle->m_iMolAtom[2] = ma3->m_iMolAtomNumber; angle->m_iAtomOffset[0] = ma2->m_iOffset; angle->m_iAtomOffset[1] = ma->m_iOffset; angle->m_iAtomOffset[2] = ma3->m_iOffset; sm->m_oaAngles.Add(angle); } } } /* if (z == 0) mprintf(" %d Angles added.\n",oatemp.GetSize());*/ if (sm->m_oaAngles.GetSize() > 1000) mprintf(WHITE," ["); tfs = sm->m_oaAngles.GetSize() / 50.0; for (z2=0;z2m_oaAngles.GetSize();z2++) { if (sm->m_oaAngles.GetSize() > 1000) if (fmod(z2,tfs) < 1) mprintf(WHITE,"#"); angle = (CMolAngle*)sm->m_oaAngles[z2]; for (z3=0;z3m_oaAngleGroups.GetSize();z3++) { ag = (CMolAngleGroup*)sm->m_oaAngleGroups[z3]; for (z4=0;z4m_oaAngles.GetSize();z4++) { angle2 = (CMolAngle*)ag->m_oaAngles[z4]; /* if (( ((CMolAtom*)sm->m_oaMolAtoms[angle->m_iMolAtom[1]])->m_fAtomCode == ((CMolAtom*)sm->m_oaMolAtoms[angle2->m_iMolAtom[1]])->m_fAtomCode) && (((( ((CMolAtom*)sm->m_oaMolAtoms[angle->m_iMolAtom[0]])->m_fAtomCode == ((CMolAtom*)sm->m_oaMolAtoms[angle2->m_iMolAtom[0]])->m_fAtomCode) && ( ((CMolAtom*)sm->m_oaMolAtoms[angle->m_iMolAtom[2]])->m_fAtomCode == ((CMolAtom*)sm->m_oaMolAtoms[angle2->m_iMolAtom[2]])->m_fAtomCode))) || (( ((CMolAtom*)sm->m_oaMolAtoms[angle->m_iMolAtom[0]])->m_fAtomCode == ((CMolAtom*)sm->m_oaMolAtoms[angle2->m_iMolAtom[2]])->m_fAtomCode) && ( ((CMolAtom*)sm->m_oaMolAtoms[angle->m_iMolAtom[2]])->m_fAtomCode == ((CMolAtom*)sm->m_oaMolAtoms[angle2->m_iMolAtom[0]])->m_fAtomCode)))) */ if (( ((CMolAtom*)sm->m_oaMolAtoms[angle->m_iMolAtom[1]])->m_liAtomCode == ((CMolAtom*)sm->m_oaMolAtoms[angle2->m_iMolAtom[1]])->m_liAtomCode) && (((( ((CMolAtom*)sm->m_oaMolAtoms[angle->m_iMolAtom[0]])->m_liAtomCode == ((CMolAtom*)sm->m_oaMolAtoms[angle2->m_iMolAtom[0]])->m_liAtomCode) && ( ((CMolAtom*)sm->m_oaMolAtoms[angle->m_iMolAtom[2]])->m_liAtomCode == ((CMolAtom*)sm->m_oaMolAtoms[angle2->m_iMolAtom[2]])->m_liAtomCode))) || (( ((CMolAtom*)sm->m_oaMolAtoms[angle->m_iMolAtom[0]])->m_liAtomCode == ((CMolAtom*)sm->m_oaMolAtoms[angle2->m_iMolAtom[2]])->m_liAtomCode) && ( ((CMolAtom*)sm->m_oaMolAtoms[angle->m_iMolAtom[2]])->m_liAtomCode == ((CMolAtom*)sm->m_oaMolAtoms[angle2->m_iMolAtom[0]])->m_liAtomCode)))) { ag->m_oaAngles.Add(angle); goto _angledone; } } } try { ag = new CMolAngleGroup(); } catch(...) { ag = NULL; } if (ag == NULL) NewException((double)sizeof(CMolAngleGroup),__FILE__,__LINE__,__PRETTY_FUNCTION__); ag->m_oaAngles.Add(angle); sm->m_oaAngleGroups.Add(ag); _angledone:; } if (sm->m_oaAngles.GetSize() > 1000) mprintf(WHITE,"]\n"); /* if (z == 0) { mprintf(" %d Angle groups found:\n",sm->m_oaAngleGroups.GetSize()); for (z2=0;z2m_oaAngleGroups.GetSize();z2++) { mprintf(" - "); ag = (CMolAngleGroup*)sm->m_oaAngleGroups[z2]; for (z3=0;z3m_oaAngles.GetSize();z3++) { angle = (CMolAngle*)ag->m_oaAngles[z3]; mprintf(" (%s%2d, %s%2d, %s%2d)",((CAtom*)g_oaAtoms[sm->m_baAtomIndex[angle->m_iAtomType[0]]])->m_sName,angle->m_iAtom[0]+1,((CAtom*)g_oaAtoms[sm->m_baAtomIndex[angle->m_iAtomType[1]]])->m_sName,angle->m_iAtom[1]+1,((CAtom*)g_oaAtoms[sm->m_baAtomIndex[angle->m_iAtomType[2]]])->m_sName,angle->m_iAtom[2]+1); if (z3 < ag->m_oaAngles.GetSize()-1) mprintf(", "); } mprintf("\n"); } }*/ } mprintf(" Grouping together equivalent molecules...\n"); for (z=0;zm_laSingleMolIndex[0]]; /* if (m->m_baAtomIndex.GetSize() != sm->m_baAtomIndex.GetSize()) goto _cont; // Nich die Gleiche Anzahl verschiedener Elemente -> Keine Uebereinstimmung for (z3=0;z3m_baAtomIndex.GetSize();z3++) { if (m->m_baAtomIndex[z3] != sm->m_baAtomIndex[z3]) goto _cont; // Elemente an Position z3 unterscheiden sich -> keine Uebereinstimmung if (m->m_waAtomCount[z3] != ((CxIntArray*)sm->m_oaAtomOffset[z3])->GetSize()) goto _cont; // Anzahl an Atomen dieser Elementsorte unterscheidet sich -> Keine Uebereinstimmung*/ // mprintf(" Stimmt mit M%d ueberein.\n",z2); // ((CMolecule*)g_oaMolecules[z2])->Count++; // g_pSingleMolecules[z].m_iMoleculeOffset = z2; // } if (sm->m_oaMolAtoms.GetSize() != sm2->m_oaMolAtoms.GetSize()) goto _cont; for (z3=0;z3m_oaMolAtoms.GetSize();z3++) // if (((CMolAtom*)sm->m_oaMolAtoms[z3])->m_fAtomCode != ((CMolAtom*)sm2->m_oaMolAtoms[z3])->m_fAtomCode) if (((CMolAtom*)sm->m_oaMolAtoms[z3])->m_liAtomCode != ((CMolAtom*)sm2->m_oaMolAtoms[z3])->m_liAtomCode) goto _cont; sm->m_iMolSMIndex = m->m_laSingleMolIndex.GetSize(); m->m_laSingleMolIndex.Add(z); // sm->m_iMolType = z2; goto _fert; _cont:; } try { m = new CMolecule(); } catch(...) { m = NULL; } if (m == NULL) NewException((double)sizeof(CMolecule),__FILE__,__LINE__,__PRETTY_FUNCTION__); g_oaMolecules.Add(m); // m->Count = 1; // Neues Molekueltemplate hinzufuegen // m->Elements = ((CSingleMolecule*)g_oaSingleMolecules[z])->m_iElements; m->m_iAtomGes = 0; f = 0; for (z2=0;z2m_oaAtomOffset.GetSize();z2++) { m->m_iAtomGes += ((CxIntArray*)sm->m_oaAtomOffset[z2])->GetSize(); f += ((CAtom*)g_oaAtoms[sm->m_baAtomIndex[z2]])->m_pElement->m_fMass * ((CxIntArray*)sm->m_oaAtomOffset[z2])->GetSize(); } m->m_iAtomGesNoVirt = m->m_iAtomGes; m->m_fMass = f; ((CSingleMolecule*)g_oaSingleMolecules[z])->m_iMolType = g_oaMolecules.GetSize()-1; for (z2=0;z2<((CSingleMolecule*)g_oaSingleMolecules[z])->m_baAtomIndex.GetSize();z2++) { m->m_baAtomIndex.Add(((CSingleMolecule*)g_oaSingleMolecules[z])->m_baAtomIndex[z2]); m->m_waAtomCount.Add((unsigned short)((CxIntArray*)((CSingleMolecule*)g_oaSingleMolecules[z])->m_oaAtomOffset[z2])->GetSize()); // m->AtomCount[z2] = ((CSingleMolecule*)g_oaSingleMolecules[z])->m_iAtomCount[z2]; } sm->m_iMolSMIndex = m->m_laSingleMolIndex.GetSize(); m->m_laSingleMolIndex.Add(z); // g_pSingleMolecules[z].m_iMoleculeOffset = g_oaMolecules.GetSize(); m->BuildName(); // Standardmaessig geom. Zentrum als Dipolzentrum m->m_iDipoleCenterType = m->m_baAtomIndex.GetSize(); m->m_iDipoleCenterIndex = 0; // mprintf("### Erzeuge neues Molekuel %d \"%s\".\n",g_oaMolecules.GetSize(),m->Name); // g_oaMolecules.GetSize()++; _fert:; } mprintf(" Found %d unique molecule types.\n",g_oaMolecules.GetSize()); // Sort by molecular mass mprintf(" Sorting molecule types by molecular mass...\n"); for (z=0;zm_fMass > f) { // mprintf("@ %f > %f --> z3 = %d\n",((CMolecule*)g_oaMolecules[z2])->m_fMass,f,z2); f = ((CMolecule*)g_oaMolecules[z2])->m_fMass; z3 = z2; } } if (z3 == -1) { eprintf("CTimeStep::ScanMolecules(): Internal error.\n"); abort(); } if (f > 0) { // mprintf("@ Swapping %d with %d.\n",z,z3); m = (CMolecule*)g_oaMolecules[z3]; g_oaMolecules[z3] = g_oaMolecules[z]; g_oaMolecules[z] = m; } } for (z=0;zm_iIndex = z; for (z2=0;z2<((CMolecule*)g_oaMolecules[z])->m_laSingleMolIndex.GetSize();z2++) ((CSingleMolecule*)g_oaSingleMolecules[((CMolecule*)g_oaMolecules[z])->m_laSingleMolIndex[z2]])->m_iMolType = z; } /* for (z=0;zm_laSingleMolIndex[0]]; mprintf("Molecule %d Ring systems:\n",z+1); for (z2=0;z2m_oaRings.GetSize();z2++) { wa = (CxIntArray*)sm->m_oaRings[z2]; mprintf(" - Ring %d: ",z2+1); for (z3=0;z3GetSize();z3++) { mprintf("%d",(*wa)[z3]); if (z3+1 < wa->GetSize()) mprintf(", "); } mprintf("\n"); } mprintf("\n"); }*/ ti = 0; for (z=0;zm_laSingleMolIndex[0]]; ti += sm->m_oaRings.GetSize(); } mprintf(" Found %d rings.\n",ti); if (ti != 0) { mprintf(" Refining ring systems...\n"); try { wa = new CxIntArray("CTimeStep::ScanMolecules():wa"); } catch(...) { wa = NULL; } if (wa == NULL) NewException((double)sizeof(CxIntArray),__FILE__,__LINE__,__PRETTY_FUNCTION__); // Process ring systems for (z=0;zm_laSingleMolIndex[0]]; if (sm->m_oaRings.GetSize() > 100) { eprintf(" More than 100 rings in molecule %d, skipping refinement. Ring system may be improper.\n",z+1); continue; } ti2 = 0; _again: ti2++; if (ti2 > 1000) { eprintf(" Too many iterations in molecule %d, aborting refinement. Ring system may be improper.\n",z+1); continue; } // mprintf("### again\n"); for (z2=0;z2m_oaRings.GetSize();z2++) { waz2 = (CxIntArray*)sm->m_oaRings[z2]; for (z3=z2+1;z3m_oaRings.GetSize();z3++) { waz3 = (CxIntArray*)sm->m_oaRings[z3]; // mprintf("*A* Checking if %d(%d) contains %d(%d)...\n",z2+1,waz2->GetSize(),z3+1,waz3->GetSize()); // Check if waz2 contains waz3 wa->SetSize(waz2->GetSize()); for (z4=0;z4GetSize();z4++) (*wa)[z4] = 0; for (z4=0;z4GetSize();z4++) { for (z5=0;z5GetSize();z5++) { if ((*waz3)[z4] == (*waz2)[z5]) { (*wa)[z5] = 1; goto _found2; } } goto _notfound2; _found2:; } // mprintf(" Yes!\n"); try { waneu = new CxIntArray("CTimeStep::ScanMolecules():waneu"); } catch(...) { waneu = NULL; } if (waneu == NULL) NewException((double)sizeof(CxIntArray),__FILE__,__LINE__,__PRETTY_FUNCTION__); for (z4=0;z4GetSize();z4++) { if (z4 == 0) { if (((*wa)[z4] == 0) || ((*wa)[z4+1] == 0) || ((*wa)[waz2->GetSize()-1] == 0)) waneu->Add((*waz2)[z4]); } else if (z4 == waz2->GetSize()-1) { if (((*wa)[z4] == 0) || ((*wa)[z4-1] == 0) || ((*wa)[0] == 0)) waneu->Add((*waz2)[z4]); } else { if (((*wa)[z4] == 0) || ((*wa)[z4+1] == 0) || ((*wa)[z4-1] == 0)) waneu->Add((*waz2)[z4]); } } // mprintf(" Took %d from %d atoms from waz2.\n",waneu->GetSize(),waz2->GetSize()); i1 = waz2->GetSize(); delete waz2; sm->m_oaRings[z2] = waneu; if (waneu->GetSize() != i1) goto _again; _notfound2: // mprintf("*B* Checking if %d contains %d...\n",z3+1,z2+1); // Check if waz3 contains waz2 wa->SetSize(waz3->GetSize()); for (z4=0;z4GetSize();z4++) (*wa)[z4] = 0; for (z4=0;z4GetSize();z4++) { for (z5=0;z5GetSize();z5++) { if ((*waz2)[z4] == (*waz3)[z5]) { (*wa)[z5] = 1; goto _found3; } } goto _notfound3; _found3:; } // mprintf(" Yes!\n"); try { waneu = new CxIntArray("CTimeStep::ScanMolecules():waneu"); } catch(...) { waneu = NULL; } if (waneu == NULL) NewException((double)sizeof(CxIntArray),__FILE__,__LINE__,__PRETTY_FUNCTION__); for (z4=0;z4GetSize();z4++) { if (z4 == 0) { if (((*wa)[z4] == 0) || ((*wa)[z4+1] == 0) || ((*wa)[waz3->GetSize()-1] == 0)) waneu->Add((*waz3)[z4]); } else if (z4 == waz3->GetSize()-1) { if (((*wa)[z4] == 0) || ((*wa)[z4-1] == 0) || ((*wa)[0] == 0)) waneu->Add((*waz3)[z4]); } else { if (((*wa)[z4] == 0) || ((*wa)[z4+1] == 0) || ((*wa)[z4-1] == 0)) waneu->Add((*waz3)[z4]); } } // mprintf(" Took %d from %d atoms from waz3.\n",waneu->GetSize(),waz3->GetSize()); i1 = waz3->GetSize(); delete waz3; sm->m_oaRings[z3] = waneu; if (waneu->GetSize() != i1) goto _again; _notfound3:; } } } delete wa; mprintf(" Assigning ring systems to molecule types...\n"); for (z=0;zm_laSingleMolIndex[0]]; for (z2=0;z2m_oaRings.GetSize();z2++) { wa = (CxIntArray*)sm->m_oaRings[z2]; try { waz2 = new CxIntArray("CTimeStep::ScanMolecules():waz2"); } catch(...) { waz2 = NULL; } if (waz2 == NULL) NewException((double)sizeof(CxIntArray),__FILE__,__LINE__,__PRETTY_FUNCTION__); try { waz3 = new CxIntArray("CTimeStep::ScanMolecules():waz3"); } catch(...) { waz3 = NULL; } if (waz3 == NULL) NewException((double)sizeof(CxIntArray),__FILE__,__LINE__,__PRETTY_FUNCTION__); m->m_oaRingAtomTypes.Add(waz2); m->m_oaRingAtoms.Add(waz3); for (z3=0;z3GetSize();z3++) { for (z4=0;z4m_baAtomIndex.GetSize();z4++) { for (z5=0;z5<((CxIntArray*)sm->m_oaAtomOffset[z4])->GetSize();z5++) { if (((CxIntArray*)sm->m_oaAtomOffset[z4])->GetAt(z5) == wa->GetAt(z3)) { waz2->Add(z4); waz3->Add(z5); goto _done; } } } _done:; } } } mprintf(" Sorting rings by size...\n"); for (z=0;zm_oaRingAtoms.GetSize();z2++) { i1 = 0; ti = -1; for (z3=z2;z3m_oaRingAtoms.GetSize();z3++) { if (((CxIntArray*)m->m_oaRingAtoms[z3])->GetSize() > i1) { i1 = ((CxIntArray*)m->m_oaRingAtoms[z3])->GetSize(); ti = z3; } } if ((ti != -1) && (ti != z2)) { wa = (CxIntArray*)m->m_oaRingAtoms[z2]; m->m_oaRingAtoms[z2] = m->m_oaRingAtoms[ti]; m->m_oaRingAtoms[ti] = wa; wa = (CxIntArray*)m->m_oaRingAtomTypes[z2]; m->m_oaRingAtomTypes[z2] = m->m_oaRingAtomTypes[ti]; m->m_oaRingAtomTypes[ti] = wa; } } } } /* for (z=0;zm_laSingleMolIndex[0]]; mprintf("Molecule %d Ring systems:\n",z+1); for (z2=0;z2m_oaRings.GetSize();z2++) { wa = (CxIntArray*)sm->m_oaRings[z2]; mprintf(" - Ring %d: ",z2+1); for (z3=0;z3GetSize();z3++) { mprintf("%d",(*wa)[z3]); if (z3+1 < wa->GetSize()) mprintf(", "); } mprintf("\n"); } mprintf("\n"); }*/ /* mprintf("\n%d Molekuelsorten gefunden.\n",g_oaMolecules.GetSize()); for (z=0;zDump(); }*/ mprintf(" Molecule recognition finished.\n"); BTOUT; return true; } void CTimeStep::RECURSION_MegaTree(int i, char *ta, int depth, unsigned long bmask, bool w, int *stack) { BTIN; int z, z2; int nblist[20], nbs; stack[depth] = i; ta[i] = 1; for (z=1;zm_sName,i+1); nbs = 0; for (z=0;z<(long)m_iGesAtomCount;z++) // Schon mal alle Nachbarn raussuchen { if (z == i) continue; if (BondRange(i,z,NULL)) { if (ta[z] != 0) { if ((depth > 0) && (z != stack[depth-1])) { mprintf(GREEN," <-- Ring closure: "); mprintf("%s(%d)",(const char*)((CAtom*)g_oaAtoms[g_baAtomIndex[stack[depth]]])->m_sName,stack[depth]+1); z2 = depth-1; while ((stack[z2] != z) && (z2 >= 0)) { mprintf(" - %s(%d)",(const char*)((CAtom*)g_oaAtoms[g_baAtomIndex[stack[z2]]])->m_sName,stack[z2]+1); z2--; } mprintf(" - %s(%d)",(const char*)((CAtom*)g_oaAtoms[g_baAtomIndex[z]])->m_sName,z+1); // mprintf("Ringschluss! [d-1=%d,d=%d,i=%d] %s(%d)\n",stack[depth-1]+1,stack[depth]+1,i+1,((CAtom*)g_oaAtoms[g_baAtomIndex[z]])->m_sName,z+1); } continue; } nblist[nbs] = z; nbs++; } } mprintf("\n"); for (z=0;z Ringschluss { for (z2=1;z2m_sName,nblist[z]+1); mprintf(GREEN," <-- Ring closure\n"); } else { if (z+1 == nbs) bmask -= (int)mypow(2.0,depth+1); RECURSION_MegaTree(nblist[z],ta,/*sm,*/depth+1,bmask,(z+1==nbs)?false:true,stack); } } BTOUT; } void CTimeStep::PrintMegaTree() { BTIN; int z; // char ta[16384]; // int stack[16384]; char *ta; int *stack; try { ta = new char[m_iGesAtomCount]; } catch(...) { ta = NULL; } if (ta == NULL) NewException((double)m_iGesAtomCount*sizeof(char),__FILE__,__LINE__,__PRETTY_FUNCTION__); try { stack = new int[m_iGesAtomCount]; } catch(...) { stack = NULL; } if (stack == NULL) NewException((double)m_iGesAtomCount*sizeof(int),__FILE__,__LINE__,__PRETTY_FUNCTION__); for (z=0;z<(int)m_iGesAtomCount;z++) ta[z] = 0; for (z=0;z<(int)m_iGesAtomCount;z++) { if (ta[z] != 0) // Dieses Atom wurde bereits in irgendein Molekuel eingebaut continue; mprintf(YELLOW,"\nThe next molecule starts with %s(%d):\n",(const char*)m_paLabels[z],z+1); RECURSION_MegaTree(z,ta,0,0xFFFFFFFF,true,stack); } delete[] stack; delete[] ta; mprintf("\n"); BTOUT; } void CTimeStep::PrintMatrix(bool onlyfirst, bool onlybind) { BTIN; int z, z2, z3, z4, z5, z6, z7, z8, ti, ti2, hc; double tf; bool b, c, noh, hex, log; CxDVector3 vec1, vec2; CSingleMolecule *sm; CMolecule *m; CMolAtom *ma, *ma0; CxIntArray *wa, *wat; for (z=0;zm_laSingleMolIndex.GetSize());z6++) { mprintf(YELLOW,"\n*** Molecule %d: %s; Representant %d; Distances in pm ***\n",z+1,m->m_sName,z6+1); if ((m->m_baAtomIndex.GetSize() == 1) && (m->m_waAtomCount[0] == 1)) { mprintf("[only 1 Atom]\n"); continue; } hex = false; noh = false; hc = 0; for (z2=0;z2m_baAtomIndex.GetSize();z2++) { if (mystricmp(((CAtom*)g_oaAtoms[m->m_baAtomIndex[z2]])->m_sName,"H") == 0) { hex = true; hc += m->m_waAtomCount[z2]; } } _matagain: log = false; if (noh) { if (m->m_iAtomGes-hc > 55) { mprintf(WHITE,"\n This molecule has many atoms (even without H). Output would flood the screen. Only writing to log file.\n"); log = true; } } else { if (m->m_iAtomGes > 55) { mprintf(WHITE,"\n This molecule has many atoms. Output would flood the screen. Only writing to log file.\n"); log = true; } } if (!log && (m->m_oaRingAtoms.GetSize() != 0)) mprintf(GREEN," (ring bonds are shown in green)\n"); if (log) mprintf_nos("\n "); else mprintf("\n "); for (z2=0;z2m_baAtomIndex.GetSize();z2++) { if (noh) // Skip H atoms if (mystricmp(((CAtom*)g_oaAtoms[m->m_baAtomIndex[z2]])->m_sName,"H") == 0) continue; for (z3=0;z3m_waAtomCount[z2];z3++) { if (((CAtom*)g_oaAtoms[m->m_baAtomIndex[z2]])->m_sName[1] == 0) { if (log) mprintf_nos(" "); else mprintf(" "); } if (log) mprintf_nos("%s%d",(const char*)((CAtom*)g_oaAtoms[m->m_baAtomIndex[z2]])->m_sName,z3+1); else mprintf(WHITE,"%s%d",(const char*)((CAtom*)g_oaAtoms[m->m_baAtomIndex[z2]])->m_sName,z3+1); if (z3+1 < 10) { if (log) mprintf_nos(" "); else mprintf(" "); } } } if (log) mprintf_nos("\n"); else mprintf("\n"); for (z2=0;z2m_baAtomIndex.GetSize();z2++) { if (noh) // Skip H atoms if (mystricmp(((CAtom*)g_oaAtoms[m->m_baAtomIndex[z2]])->m_sName,"H") == 0) continue; for (z3=0;z3m_waAtomCount[z2];z3++) { if (log) mprintf_nos("%s%d",(const char*)((CAtom*)g_oaAtoms[m->m_baAtomIndex[z2]])->m_sName,z3+1); else mprintf(WHITE,"%s%d",(const char*)((CAtom*)g_oaAtoms[m->m_baAtomIndex[z2]])->m_sName,z3+1); if (((CAtom*)g_oaAtoms[m->m_baAtomIndex[z2]])->m_sName[1] == 0) { if (log) mprintf_nos(" "); else mprintf(" "); } if (z3+1 < 10) { if (log) mprintf_nos(" "); else mprintf(" "); } for (z4=0;z4m_baAtomIndex.GetSize();z4++) { if (noh) // Skip H atoms if (mystricmp(((CAtom*)g_oaAtoms[m->m_baAtomIndex[z4]])->m_sName,"H") == 0) continue; for (z5=0;z5m_waAtomCount[z4];z5++) { if ((z2 == z4) && (z3 == z5)) { if (log) mprintf_nos("*** "); else mprintf(BLUE,"*** "); continue; } ti = ((CxIntArray*)((CSingleMolecule*)g_oaSingleMolecules[m->m_laSingleMolIndex[z6]])->m_oaAtomOffset[z2])->GetAt(z3); //vec1 = g_TimeStep.m_vaCoords[ti]; ti2 = ((CxIntArray*)((CSingleMolecule*)g_oaSingleMolecules[m->m_laSingleMolIndex[z6]])->m_oaAtomOffset[z4])->GetAt(z5); //vec2 = g_TimeStep.m_vaCoords[ti2]; //vec1 -= vec2; vec1 = FoldVector(g_TimeStep.m_vaCoords[ti] - g_TimeStep.m_vaCoords[ti2]); tf = vec1.GetLength(); if ((g_TimeStep.BondRange(ti,ti2,NULL)) || (!onlybind)) { for (z8=0;z8m_oaRingAtomTypes.GetSize();z8++) { wat = (CxIntArray*)m->m_oaRingAtomTypes[z8]; wa = (CxIntArray*)m->m_oaRingAtoms[z8]; for (z7=0;z7GetSize();z7++) { if (((*wat)[z7] == z2) && ((*wa)[z7] == z3)) { if (z7 == 0) { if (((*wat)[z7+1] == z4) && ((*wa)[z7+1] == z5)) goto _green; if (((*wat)[wa->GetSize()-1] == z4) && ((*wa)[wa->GetSize()-1] == z5)) goto _green; } else if (z7 == wa->GetSize()-1) { if (((*wat)[0] == z4) && ((*wa)[0] == z5)) goto _green; if (((*wat)[z7-1] == z4) && ((*wa)[z7-1] == z5)) goto _green; } else { if (((*wat)[z7+1] == z4) && ((*wa)[z7+1] == z5)) goto _green; if (((*wat)[z7-1] == z4) && ((*wa)[z7-1] == z5)) goto _green; } } } } if (log) mprintf_nos("%3.0f ",tf); else mprintf("%3.0f ",tf); continue; _green: if (log) mprintf_nos("%3.0f ",tf); else mprintf(GREEN,"%3.0f ",tf); } else { if (log) mprintf_nos(" - "); else mprintf(" - "); } } } if (log) mprintf_nos("\n"); else mprintf("\n"); } } if (hex && (hc > 10) && (!noh) && (m->m_iAtomGes > 30)) { mprintf(WHITE,"\n This was a very large molecule.\n Printing the matrix again without H atoms.\n"); noh = true; goto _matagain; } // if (((!onlyfirst) && ((z2 < ((CMolecule*)g_oaMolecules[z])->Elements-1) || (g_oaMolecules.GetSize()-1))) || (z < g_oaMolecules.GetSize()-1)) // mprintf(">>>"); } if (m->m_oaRingAtoms.GetSize() != 0) { mprintf("\n"); for (z2=0;z2m_oaRingAtoms.GetSize();z2++) { mprintf(" %d-ring: ",((CxIntArray*)m->m_oaRingAtoms[z2])->GetSize()); if (((CxIntArray*)m->m_oaRingAtoms[z2])->GetSize() > 20) { for (z3=0;z3<5;z3++) { mprintf("%s%d",(const char*)((CAtom*)g_oaAtoms[m->m_baAtomIndex[((CxIntArray*)m->m_oaRingAtomTypes[z2])->GetAt(z3)]])->m_sName,((CxIntArray*)m->m_oaRingAtoms[z2])->GetAt(z3)+1); if (z3+1 < ((CxIntArray*)m->m_oaRingAtoms[z2])->GetSize()) mprintf(" - "); } mprintf(RED,"..."); mprintf(" - "); for (z3=((CxIntArray*)m->m_oaRingAtoms[z2])->GetSize()-5;z3<((CxIntArray*)m->m_oaRingAtoms[z2])->GetSize();z3++) { mprintf("%s%d",(const char*)((CAtom*)g_oaAtoms[m->m_baAtomIndex[((CxIntArray*)m->m_oaRingAtomTypes[z2])->GetAt(z3)]])->m_sName,((CxIntArray*)m->m_oaRingAtoms[z2])->GetAt(z3)+1); if (z3+1 < ((CxIntArray*)m->m_oaRingAtoms[z2])->GetSize()) mprintf(" - "); } } else { for (z3=0;z3<((CxIntArray*)m->m_oaRingAtoms[z2])->GetSize();z3++) { mprintf("%s%d",(const char*)((CAtom*)g_oaAtoms[m->m_baAtomIndex[((CxIntArray*)m->m_oaRingAtomTypes[z2])->GetAt(z3)]])->m_sName,((CxIntArray*)m->m_oaRingAtoms[z2])->GetAt(z3)+1); if (z3+1 < ((CxIntArray*)m->m_oaRingAtoms[z2])->GetSize()) mprintf(" - "); } } mprintf("\n"); if (z2 >= 99) { mprintf(RED,"\n Only showing the first 100 rings.\n"); break; } } } c = false; sm = (CSingleMolecule*)g_oaSingleMolecules[m->m_laSingleMolIndex[0]]; for (z2=0;z2m_baAtomIndex.GetSize();z2++) { b = false; ma = NULL; for (z3=0;z3m_oaMolAtoms.GetSize();z3++) { if (((CMolAtom*)sm->m_oaMolAtoms[z3])->m_iType != z2) continue; ma0 = ma; ma = (CMolAtom*)sm->m_oaMolAtoms[z3]; if (ma0 == NULL) continue; z4 = ma0->m_iNumber; // if (ma->m_fAtomCode == ma0->m_fAtomCode) if (ma->m_liAtomCode == ma0->m_liAtomCode) { if (b) { mprintf(", %s%d",(const char*)((CAtom*)g_oaAtoms[m->m_baAtomIndex[z2]])->m_sName,ma->m_iNumber+1); } else { if (!c) { c = true; mprintf("\n"); } mprintf(" Atoms %s%d, %s%d",(const char*)((CAtom*)g_oaAtoms[m->m_baAtomIndex[z2]])->m_sName,z4+1,(const char*)((CAtom*)g_oaAtoms[m->m_baAtomIndex[z2]])->m_sName,ma->m_iNumber+1); b = true; } } else if (b) { mprintf(" are equivalent.\n"); b = false; } } if (b) mprintf(" are equivalent.\n"); } } // Tabelle Ende BTOUT; } /*void CTimeStep::Transform(const CxDMatrix3 &mat) { BTIN; int z; // CxDVector3 v; for (z=0;z ",z,m_vaCoords[z][0],m_vaCoords[z][1],m_vaCoords[z][2]); m_vaCoords[z] = mat * m_vaCoords[z]; // if (z < g_iGesAtomCount) // mprintf("( %g | %g | %g )\n",m_vaCoords[z][0],m_vaCoords[z][1],m_vaCoords[z][2]); } if (g_bUseVelocities) for (z=0;zm_bPseudo) continue; if (m->m_bPolymer) // Polymers need to be wrapped atom-wise { for (z2=0;z2m_laSingleMolIndex.GetSize();z2++) { sm = (CSingleMolecule*)g_oaSingleMolecules[m->m_laSingleMolIndex[z2]]; for (z3=0;z3m_baAtomIndex.GetSize();z3++) { for (z4=0;z4m_waAtomCount[z3];z4++) { if (g_bBoxNonOrtho) { v = g_mBoxToOrtho * m_vaCoords[((CxIntArray*)sm->m_oaAtomOffset[z3])->GetAt(z4)]; while (v[0] > 0.5) v[0] -= 1.0; while (v[0] <= -0.5) v[0] += 1.0; while (v[1] > 0.5) v[1] -= 1.0; while (v[1] <= -0.5) v[1] += 1.0; while (v[2] > 0.5) v[2] -= 1.0; while (v[2] <= -0.5) v[2] += 1.0; m_vaCoords[((CxIntArray*)sm->m_oaAtomOffset[z3])->GetAt(z4)] = g_mBoxFromOrtho * v; } else { v = m_vaCoords[((CxIntArray*)sm->m_oaAtomOffset[z3])->GetAt(z4)]; if (g_bPeriodicX) { while (v[0] < -g_fBoxX/2) { v[0] += g_fBoxX; vc[0] += g_fBoxX; } while (v[0] >= g_fBoxX/2) { v[0] -= g_fBoxX; vc[0] -= g_fBoxX; } } if (g_bPeriodicY) { while (v[1] < -g_fBoxY/2) { v[1] += g_fBoxY; vc[1] += g_fBoxY; } while (v[1] >= g_fBoxY/2) { v[1] -= g_fBoxY; vc[1] -= g_fBoxY; } } if (g_bPeriodicZ) { while (v[2] < -g_fBoxZ/2) { v[2] += g_fBoxZ; vc[2] += g_fBoxZ; } while (v[2] >= g_fBoxZ/2) { v[2] -= g_fBoxZ; vc[2] -= g_fBoxZ; } } m_vaCoords[((CxIntArray*)sm->m_oaAtomOffset[z3])->GetAt(z4)] = v; } } } } } else { for (z2=0;z2m_laSingleMolIndex.GetSize();z2++) { sm = (CSingleMolecule*)g_oaSingleMolecules[m->m_laSingleMolIndex[z2]]; // mprintf("\n%d, %d",m->m_baAtomIndex.GetSize(),((CxIntArray*)sm->m_oaAtomOffset[m->m_baAtomIndex.GetSize()-1])->GetAt(1)); // Massenzentrum /* mprintf(" .Mol "); v.Dump(); mprintf("\n"); */ vc = CxDVector3(0,0,0); if (g_bBoxNonOrtho) { v = g_mBoxToOrtho * m_vaCoords[((CxIntArray*)sm->m_oaAtomOffset[m->m_baAtomIndex.GetSize()-1])->GetAt(1)]; while (v[0] > 0.5) { v[0] -= 1.0; vc[0] -= 1.0; } while (v[0] <= -0.5) { v[0] += 1.0; vc[0] += 1.0; } while (v[1] > 0.5) { v[1] -= 1.0; vc[1] -= 1.0; } while (v[1] <= -0.5) { v[1] += 1.0; vc[1] += 1.0; } while (v[2] > 0.5) { v[2] -= 1.0; vc[2] -= 1.0; } while (v[2] <= -0.5) { v[2] += 1.0; vc[2] += 1.0; } vc = g_mBoxFromOrtho * vc; } else { v = m_vaCoords[((CxIntArray*)sm->m_oaAtomOffset[m->m_baAtomIndex.GetSize()-1])->GetAt(1)]; if (g_bPeriodicX) { while (v[0] < -g_fBoxX/2) { v[0] += g_fBoxX; vc[0] += g_fBoxX; } while (v[0] >= g_fBoxX/2) { v[0] -= g_fBoxX; vc[0] -= g_fBoxX; } } if (g_bPeriodicY) { while (v[1] < -g_fBoxY/2) { v[1] += g_fBoxY; vc[1] += g_fBoxY; } while (v[1] >= g_fBoxY/2) { v[1] -= g_fBoxY; vc[1] -= g_fBoxY; } } if (g_bPeriodicZ) { while (v[2] < -g_fBoxZ/2) { v[2] += g_fBoxZ; vc[2] += g_fBoxZ; } while (v[2] >= g_fBoxZ/2) { v[2] -= g_fBoxZ; vc[2] -= g_fBoxZ; } } } if ((vc[0] == 0) && (vc[1] == 0) && (vc[2] == 0)) continue; for (z3=0;z3m_baAtomIndex.GetSize();z3++) for (z4=0;z4m_waAtomCount[z3];z4++) m_vaCoords[((CxIntArray*)sm->m_oaAtomOffset[z3])->GetAt(z4)] += vc; if (g_bWannier) for (z3=0;z3m_laWannier.GetSize();z3++) m_vaCoords[sm->m_laWannier[z3]] += vc; } } } // mprintf(" Fold Done\n"); BTOUT; } void CTimeStep::FoldAtoms() { BTIN; CxDVector3 v; int z; if (!g_bPeriodic) return; for (z=0;z 0.5) v[0] -= 1.0; while (v[0] <= -0.5) v[0] += 1.0; while (v[1] > 0.5) v[1] -= 1.0; while (v[1] <= -0.5) v[1] += 1.0; while (v[2] > 0.5) v[2] -= 1.0; while (v[2] <= -0.5) v[2] += 1.0; m_vaCoords[z] = g_mBoxFromOrtho * v; } else { if (g_bPeriodicX) { while (m_vaCoords[z][0] < -g_fBoxX/2) m_vaCoords[z][0] += g_fBoxX; while (m_vaCoords[z][0] >= g_fBoxX/2) m_vaCoords[z][0] -= g_fBoxX; } if (g_bPeriodicY) { while (m_vaCoords[z][1] < -g_fBoxY/2) m_vaCoords[z][1] += g_fBoxY; while (m_vaCoords[z][1] >= g_fBoxY/2) m_vaCoords[z][1] -= g_fBoxY; } if (g_bPeriodicZ) { while (m_vaCoords[z][2] < -g_fBoxZ/2) m_vaCoords[z][2] += g_fBoxZ; while (m_vaCoords[z][2] >= g_fBoxZ/2) m_vaCoords[z][2] -= g_fBoxZ; } } } BTOUT; } void CTimeStep::CenterPos(const CxDVector3 &vec) { BTIN; int z/*, z2, z3, z4*/; /* for (z=0;zCount;z2++) for (z3=0;z3<((CMolecule*)g_oaMolecules[z])->Elements;z3++) for (z4=0;z4<((CMolecule*)g_oaMolecules[z])->AtomCount[z3];z4++) m_vaCoords[((CSingleMolecule*)g_oaSingleMolecules[((CMolecule*)g_oaMolecules[z])->SingleMolIndex[z2]])->m_iAtomOffset[z3][z4]] -= vec;*/ for (z=0;z= '0') && (*q <= '9')) { if (!labeledatoms) { mprintf(">>>\n>>> The atoms in the input file are numbered.\n>>> Ignoring this, using own numbers ;-)\n>>>\n"); labeledatoms = true; } *q = 0; q--; }*/ // printf("AddAtoms: \"%s\"\n",q); xAddAtom((char*)m_paLabels[z],false); } BTOUT; } void CTimeStep::WriteTimestep(FILE *a) { BTIN; int z, z2, z3, z4, z0; CMolecule *m; CSingleMolecule *sm; if (g_bSaveVirtAtoms) mfprintf(a," %d\n",g_iGesVirtAtomCount); else mfprintf(a," %d\n",g_iGesAtomCount); if (m_pComment != NULL) mfprintf(a,"%s\n",m_pComment); else mfprintf(a,"\n"); if (g_bWriteAtomwise) { for (z0=0;z0m_bPseudo) continue; for (z3=0;z3m_baAtomIndex.GetSize();z3++) { if (m->m_baAtomIndex[z3] != z0) continue; if ((!g_bSaveVirtAtoms) && (m->m_baAtomIndex[z3] == g_iVirtAtomType)) continue; for (z2=0;z2m_laSingleMolIndex.GetSize();z2++) { sm = (CSingleMolecule*)g_oaSingleMolecules[m->m_laSingleMolIndex[z2]]; for (z4=0;z4<((CxIntArray*)sm->m_oaAtomOffset[z3])->GetSize();z4++) mfprintf(a," %s %8.5f %8.5f %8.5f\n",(const char*)((CAtom*)g_oaAtoms[m->m_baAtomIndex[z3]])->m_sName,m_vaCoords[((CxIntArray*)sm->m_oaAtomOffset[z3])->GetAt(z4)][0]/100.0,m_vaCoords[((CxIntArray*)sm->m_oaAtomOffset[z3])->GetAt(z4)][1]/100.0,m_vaCoords[((CxIntArray*)sm->m_oaAtomOffset[z3])->GetAt(z4)][2]/100.0); } } } } } else { for (z=0;zm_bPseudo) continue; for (z2=0;z2m_laSingleMolIndex.GetSize();z2++) { sm = (CSingleMolecule*)g_oaSingleMolecules[m->m_laSingleMolIndex[z2]]; for (z3=0;z3m_baAtomIndex.GetSize();z3++) { if ((!g_bSaveVirtAtoms) && (m->m_baAtomIndex[z3] == g_iVirtAtomType)) continue; for (z4=0;z4<((CxIntArray*)sm->m_oaAtomOffset[z3])->GetSize();z4++) mfprintf(a," %s %8.5f %8.5f %8.5f\n",(const char*)((CAtom*)g_oaAtoms[m->m_baAtomIndex[z3]])->m_sName,m_vaCoords[((CxIntArray*)sm->m_oaAtomOffset[z3])->GetAt(z4)][0]/100.0,m_vaCoords[((CxIntArray*)sm->m_oaAtomOffset[z3])->GetAt(z4)][1]/100.0,m_vaCoords[((CxIntArray*)sm->m_oaAtomOffset[z3])->GetAt(z4)][2]/100.0); } } } } BTOUT; } void CTimeStep::ExportSingleMolecule_PDB(CSingleMolecule *sm, const char *s) { FILE *a; CMolecule *m; std::vector > iaa; int z, z2, z3, z4, z5, ti, ti2, o, o2; CMolBond *mb; a = OpenFileWrite(s,true); mfprintf(a,"COMPND UNNAMED\n"); mfprintf(a,"AUTHOR GENERATED BY TRAVIS\n"); m = (CMolecule*)g_oaMolecules[sm->m_iMolType]; iaa.resize(m->m_iAtomGesNoVirt); ti = 0; for (z=0;zm_baAtomIndex.GetSize();z++) { if (m->m_baAtomIndex[z] == g_iVirtAtomType) continue; for (z2=0;z2<((CxIntArray*)sm->m_oaAtomOffset[z])->GetSize();z2++) { o = ((CxIntArray*)sm->m_oaAtomOffset[z])->GetAt(z2); mfprintf( a, "HETATM%5d %4s LIG 1 %8.3f%8.3f%8.3f 1.00 0.00 %2s \n", ti+1, (const char*)((CAtom*)g_oaAtoms[m->m_baAtomIndex[z]])->m_sName, m_vaCoords[o][0]/100.0, m_vaCoords[o][1]/100.0, m_vaCoords[o][2]/100.0, (const char*)((CAtom*)g_oaAtoms[m->m_baAtomIndex[z]])->m_sName ); ti2 = 0; for (z3=0;z3m_baAtomIndex.GetSize();z3++) { if (m->m_baAtomIndex[z3] == g_iVirtAtomType) continue; for (z4=0;z4<((CxIntArray*)sm->m_oaAtomOffset[z3])->GetSize();z4++) { o2 = ((CxIntArray*)sm->m_oaAtomOffset[z3])->GetAt(z4); for (z5=0;z5m_oaBonds.GetSize();z5++) { mb = (CMolBond*)sm->m_oaBonds[z5]; if (((mb->m_iAtomOffset[0] == o) && (mb->m_iAtomOffset[1] == o2)) || ((mb->m_iAtomOffset[1] == o) && (mb->m_iAtomOffset[0] == o2))) { iaa[ti].push_back(ti2); break; } } ti2++; } } ti++; } } for (z=0;zm_iAtomGesNoVirt;z++) { ti2 = 0; _next: mfprintf(a,"CONECT%5d",z+1); for (z2=0;z2<4;z2++) { if (ti2 < (int)iaa[z].size()) mfprintf(a,"%5d",iaa[z][ti2]+1); else mfprintf(a," "); ti2++; } mfprintf(a," \n"); if (ti2 < (int)iaa[z].size()) goto _next; } mfprintf(a,"END\n"); fclose(a); } void CTimeStep::WriteTimestepNb(FILE *a, CNbSet *nbs, int singlemol) { BTIN; int z, z2, z3, z4, z0, n, ti; CMolecule *m; CSingleMolecule *sm; CConditionGroup *cg; CConditionSubGroup *cs; CNbSearch *nb; n = 0; for (z=0;zm_oaConditionGroups[z] == NULL) continue; m = (CMolecule*)g_oaMolecules[z]; for (z2=0;z2m_laSingleMolIndex.GetSize();z2++) { if (((CConditionGroup*)nbs->m_oaConditionGroups[z])->Contains(z2)) { n += m->m_iAtomGes; if (!g_bSaveVirtAtoms) n -= m->m_laVirtualAtoms.GetSize(); } } } mfprintf(a," %d\n",n); mfprintf(a,"# Step %d",((int)g_iSteps)); if (singlemol >= 0) { sm = (CSingleMolecule*)g_oaSingleMolecules[singlemol]; m = (CMolecule*)g_oaMolecules[sm->m_iMolType]; if (!g_bSaveVirtAtoms) { if (g_bWriteAtomwise) mfprintf(a,", RM=%s[%d]",m->m_sName,sm->m_iMolSMIndex+1); else mfprintf(a,", RM=%s[%d] (%d atoms)",m->m_sName,sm->m_iMolSMIndex+1,m->m_iAtomGes-m->m_laVirtualAtoms.GetSize()); } else { if (g_bWriteAtomwise) mfprintf(a,", RM=%s[%d]",m->m_sName,sm->m_iMolSMIndex+1); else mfprintf(a,", RM=%s[%d] (%d atoms)",m->m_sName,sm->m_iMolSMIndex+1,m->m_iAtomGes); } } if (g_bEnvWriteDetailedInfo) { for (z=0;zm_oaConditionGroups[z] == NULL) continue; m = (CMolecule*)g_oaMolecules[z]; cg = (CConditionGroup*)nbs->m_oaConditionGroups[z]; if (g_bEnvSortNb) { nb = NULL; if (cg->m_oaConditionSubGroups.GetSize() == 1) { cs = (CConditionSubGroup*)cg->m_oaConditionSubGroups[0]; if (cs->m_oaConditions.GetSize() == 1) nb = (CNbSearch*)cs->m_oaConditions[0]; } if (nb == NULL) goto _nosortinfo; if (nb->m_iNbCountMin <= -1) goto _nosortinfo; for (z2=nb->m_iNbCountMin;z2<=nb->m_iNbCountMax;z2++) { ti = nb->m_pNbSort[z2].m_iOM; if (!g_bSaveVirtAtoms) { if (m->m_laSingleMolIndex[ti] != singlemol) { if (g_bWriteAtomwise) mfprintf(a,", %s[%d] d=%.3fpm",m->m_sName,z2+1,nb->m_pNbSort[z2].m_fMinDist); else mfprintf(a,", %s[%d] d=%.3fpm (%d atoms)",m->m_sName,ti+1,nb->m_pNbSort[z2].m_fMinDist,m->m_iAtomGes-m->m_laVirtualAtoms.GetSize()); } } else { if (m->m_laSingleMolIndex[ti] != singlemol) { if (g_bWriteAtomwise) mfprintf(a,", %s[%d] d=%.3fpm",m->m_sName,z2+1,nb->m_pNbSort[z2].m_fMinDist); else mfprintf(a,", %s[%d] d=%.3fpm (%d atoms)",m->m_sName,ti+1,nb->m_pNbSort[z2].m_fMinDist,m->m_iAtomGes); } } } } else { _nosortinfo: for (z2=0;z2m_laSingleMolIndex.GetSize();z2++) { if (cg->Contains(z2)) { if (!g_bSaveVirtAtoms) { if (m->m_laSingleMolIndex[z2] != singlemol) { if (g_bWriteAtomwise) mfprintf(a,", %s[%d]",m->m_sName,z2+1); else mfprintf(a,", %s[%d] (%d atoms)",m->m_sName,z2+1,m->m_iAtomGes-m->m_laVirtualAtoms.GetSize()); } } else { if (m->m_laSingleMolIndex[z2] != singlemol) { if (g_bWriteAtomwise) mfprintf(a,", %s[%d]",m->m_sName,z2+1); else mfprintf(a,", %s[%d] (%d atoms)",m->m_sName,z2+1,m->m_iAtomGes); } } } } } } } mfprintf(a,"\n"); if (g_bWriteAtomwise) { for (z0=0;z0m_oaConditionGroups[z] == NULL) continue; m = (CMolecule*)g_oaMolecules[z]; for (z3=0;z3m_baAtomIndex.GetSize();z3++) { if (m->m_baAtomIndex[z3] != z0) continue; if ((!g_bSaveVirtAtoms) && (m->m_baAtomIndex[z3] == g_iVirtAtomType)) continue; for (z2=0;z2m_laSingleMolIndex.GetSize();z2++) { if (((CConditionGroup*)nbs->m_oaConditionGroups[z])->Contains(z2)) { sm = (CSingleMolecule*)g_oaSingleMolecules[m->m_laSingleMolIndex[z2]]; for (z4=0;z4<((CxIntArray*)sm->m_oaAtomOffset[z3])->GetSize();z4++) mfprintf(a," %s %8.5f %8.5f %8.5f\n",(const char*)((CAtom*)g_oaAtoms[m->m_baAtomIndex[z3]])->m_sName,m_vaCoords[((CxIntArray*)sm->m_oaAtomOffset[z3])->GetAt(z4)][0]/100.0f,m_vaCoords[((CxIntArray*)sm->m_oaAtomOffset[z3])->GetAt(z4)][1]/100.0f,m_vaCoords[((CxIntArray*)sm->m_oaAtomOffset[z3])->GetAt(z4)][2]/100.0f); } } } } } } else { if (singlemol >= 0) { sm = (CSingleMolecule*)g_oaSingleMolecules[singlemol]; m = (CMolecule*)g_oaMolecules[sm->m_iMolType]; for (z3=0;z3m_baAtomIndex.GetSize();z3++) { if ((!g_bSaveVirtAtoms) && (m->m_baAtomIndex[z3] == g_iVirtAtomType)) continue; for (z4=0;z4<((CxIntArray*)sm->m_oaAtomOffset[z3])->GetSize();z4++) mfprintf(a," %s %8.5f %8.5f %8.5f\n",(const char*)((CAtom*)g_oaAtoms[m->m_baAtomIndex[z3]])->m_sName,m_vaCoords[((CxIntArray*)sm->m_oaAtomOffset[z3])->GetAt(z4)][0]/100.0f,m_vaCoords[((CxIntArray*)sm->m_oaAtomOffset[z3])->GetAt(z4)][1]/100.0f,m_vaCoords[((CxIntArray*)sm->m_oaAtomOffset[z3])->GetAt(z4)][2]/100.0f); } } for (z=0;zm_oaConditionGroups[z] == NULL) continue; m = (CMolecule*)g_oaMolecules[z]; cg = (CConditionGroup*)nbs->m_oaConditionGroups[z]; if (g_bEnvSortNb) { nb = NULL; if (cg->m_oaConditionSubGroups.GetSize() == 1) { cs = (CConditionSubGroup*)cg->m_oaConditionSubGroups[0]; if (cs->m_oaConditions.GetSize() == 1) nb = (CNbSearch*)cs->m_oaConditions[0]; } if (nb == NULL) goto _nosort; if (nb->m_iNbCountMin <= -1) goto _nosort; for (z2=nb->m_iNbCountMin;z2<=nb->m_iNbCountMax;z2++) { ti = nb->m_pNbSort[z2].m_iOM; if (m->m_laSingleMolIndex[ti] == singlemol) continue; sm = (CSingleMolecule*)g_oaSingleMolecules[m->m_laSingleMolIndex[ti]]; for (z3=0;z3m_baAtomIndex.GetSize();z3++) { if ((!g_bSaveVirtAtoms) && (m->m_baAtomIndex[z3] == g_iVirtAtomType)) continue; for (z4=0;z4<((CxIntArray*)sm->m_oaAtomOffset[z3])->GetSize();z4++) mfprintf(a," %s %8.5f %8.5f %8.5f\n",(const char*)((CAtom*)g_oaAtoms[m->m_baAtomIndex[z3]])->m_sName,m_vaCoords[((CxIntArray*)sm->m_oaAtomOffset[z3])->GetAt(z4)][0]/100.0f,m_vaCoords[((CxIntArray*)sm->m_oaAtomOffset[z3])->GetAt(z4)][1]/100.0f,m_vaCoords[((CxIntArray*)sm->m_oaAtomOffset[z3])->GetAt(z4)][2]/100.0f); } } } else { _nosort: for (z2=0;z2m_laSingleMolIndex.GetSize();z2++) { if (((CConditionGroup*)nbs->m_oaConditionGroups[z])->Contains(z2)) { if (m->m_laSingleMolIndex[z2] == singlemol) continue; sm = (CSingleMolecule*)g_oaSingleMolecules[m->m_laSingleMolIndex[z2]]; for (z3=0;z3m_baAtomIndex.GetSize();z3++) { if ((!g_bSaveVirtAtoms) && (m->m_baAtomIndex[z3] == g_iVirtAtomType)) continue; for (z4=0;z4<((CxIntArray*)sm->m_oaAtomOffset[z3])->GetSize();z4++) mfprintf(a," %s %8.5f %8.5f %8.5f\n",(const char*)((CAtom*)g_oaAtoms[m->m_baAtomIndex[z3]])->m_sName,m_vaCoords[((CxIntArray*)sm->m_oaAtomOffset[z3])->GetAt(z4)][0]/100.0f,m_vaCoords[((CxIntArray*)sm->m_oaAtomOffset[z3])->GetAt(z4)][1]/100.0f,m_vaCoords[((CxIntArray*)sm->m_oaAtomOffset[z3])->GetAt(z4)][2]/100.0f); } } } } } } BTOUT; } /*void CTimeStep::WriteTimestepNb(int refmol, FILE *a) { BTIN; int z, c, z2, z3, z4, z0; int ti; CMolecule *m, *m2; m = (CMolecule*)g_oaMolecules[g_iFixMol]; c = 0; if (g_bRefEnvVirt) { for (z=0;zm_waScanNeighborCount[z]*((CMolecule*)g_oaMolecules[z])->m_iAtomGes; if (g_bSaveRefWithEnv) c += m->m_iAtomGes; } else { for (z=0;zm_waScanNeighborCount[z]*(((CMolecule*)g_oaMolecules[z])->m_iAtomGes-((CMolecule*)g_oaMolecules[z])->m_waVirtualAtoms.GetSize()); if (g_bSaveRefWithEnv) c += m->m_iAtomGes - m->m_waVirtualAtoms.GetSize(); } mfprintf(a," %d\n\n",c); if (g_bRefEnvAtomwise) { for (z0=0;z0m_baAtomIndex.GetSize();z3++) { if (m->m_baAtomIndex[z3] != z0) continue; if (!g_bRefEnvVirt) if (m->m_baAtomIndex[z3] == g_iVirtAtomType) continue; for (z4=0;z4m_waAtomCount[z3];z4++) { ti = ((CxIntArray*)((CSingleMolecule*)g_oaSingleMolecules[m->m_laSingleMolIndex[refmol]])->m_oaAtomOffset[z3])->GetAt(z4); mfprintf(a," %s %f %f %f\n",((CAtom*)g_oaAtoms[m->m_baAtomIndex[z3]])->m_sName,m_vaCoords[ti][0]/100.0f,m_vaCoords[ti][1]/100.0f,m_vaCoords[ti][2]/100.0f); } } } for (z=0;zm_waScanNeighborCount[z];z2++) { for (z3=0;z3m_baAtomIndex.GetSize();z3++) { if (m2->m_baAtomIndex[z3] != z0) continue; if (!g_bRefEnvVirt) if (m2->m_baAtomIndex[z3] == g_iVirtAtomType) continue; for (z4=0;z4m_waAtomCount[z3];z4++) { ti = ((CxIntArray*)((CSingleMolecule*)g_oaSingleMolecules[m2->m_laSingleMolIndex[((CxIntArray*)g_pNbAll->m_oaScanNeighbors[z])->GetAt(z2)]])->m_oaAtomOffset[z3])->GetAt(z4); mfprintf(a," %s %f %f %f\n",((CAtom*)g_oaAtoms[m2->m_baAtomIndex[z3]])->m_sName,m_vaCoords[ti][0]/100.0f,m_vaCoords[ti][1]/100.0f,m_vaCoords[ti][2]/100.0f); } } } } } } else { if (g_bSaveRefWithEnv) { for (z3=0;z3m_baAtomIndex.GetSize();z3++) { if (!g_bRefEnvVirt) if (m->m_baAtomIndex[z3] == g_iVirtAtomType) continue; for (z4=0;z4m_waAtomCount[z3];z4++) { ti = ((CxIntArray*)((CSingleMolecule*)g_oaSingleMolecules[m->m_laSingleMolIndex[refmol]])->m_oaAtomOffset[z3])->GetAt(z4); mfprintf(a," %s %f %f %f\n",((CAtom*)g_oaAtoms[m->m_baAtomIndex[z3]])->m_sName,m_vaCoords[ti][0]/100.0,m_vaCoords[ti][1]/100.0,m_vaCoords[ti][2]/100.0); } } } for (z=0;zm_waScanNeighborCount[z];z2++) { for (z3=0;z3m_baAtomIndex.GetSize();z3++) { if (!g_bRefEnvVirt) if (m2->m_baAtomIndex[z3] == g_iVirtAtomType) continue; for (z4=0;z4m_waAtomCount[z3];z4++) { ti = ((CxIntArray*)((CSingleMolecule*)g_oaSingleMolecules[m2->m_laSingleMolIndex[((CxIntArray*)g_pNbAll->m_oaScanNeighbors[z])->GetAt(z2)]])->m_oaAtomOffset[z3])->GetAt(z4); mfprintf(a," %s %f %f %f\n",((CAtom*)g_oaAtoms[m2->m_baAtomIndex[z3]])->m_sName,m_vaCoords[ti][0]/100.0,m_vaCoords[ti][1]/100.0,m_vaCoords[ti][2]/100.0); } } } } } BTOUT; }*/ /*double CTimeStep::MolDist(CSingleMolecule *ref, CSingleMolecule *sm2, CNbSearch *nb) { BXIN; int z3, z4; double d; CxDVector3 vec; d = 99999.0f; for (z3=0;z3m_waRefElements.GetSize();z3++) for (z4=0;z4<((CxIntArray*)nb->m_oaNbElements[sm2->m_iMolType])->GetSize();z4++) { vec = m_vaCoords[((CxIntArray*)ref->m_oaAtomOffset[nb->m_waRefElements[z3]])->GetAt(nb->m_waRefAtoms[z3])] - m_vaCoords[((CxIntArray*)sm2->m_oaAtomOffset[((CxIntArray*)nb->m_oaNbElements[sm2->m_iMolType])->GetAt(z4)])->GetAt(((CxIntArray*)nb->m_oaNbAtoms[sm2->m_iMolType])->GetAt(z4))]; if (g_bFold) { while (vec[0] >= g_fBoxX/2) vec[0] -= g_fBoxX; while (vec[0] < -g_fBoxX/2) vec[0] += g_fBoxX; while (vec[1] >= g_fBoxY/2) vec[1] -= g_fBoxY; while (vec[1] < -g_fBoxY/2) vec[1] += g_fBoxY; while (vec[2] >= g_fBoxZ/2) vec[2] -= g_fBoxZ; while (vec[2] < -g_fBoxZ/2) vec[2] += g_fBoxZ; } if (vec.GetLength() < d) d = vec.GetLength(); } BXOUT; if (d < 90000.0f) return d; else return -1.0f; }*/ /*void CTimeStep::ScanNeighborhood(int fixmol, int refmol, CNbSearch *nb, CNbSearch *prev) { BTIN; double *del, d; int *best, b; int z, z2, z3, c; CMolecule *m, *m2; CSingleMolecule *sm, *sm2; CxDVector3 vec; m = (CMolecule*)g_oaMolecules[fixmol]; sm = (CSingleMolecule*)g_oaSingleMolecules[m->m_laSingleMolIndex[refmol]]; del = new double[g_oaSingleMolecules.GetSize()]; best = new int[g_oaSingleMolecules.GetSize()]; // printf("Suche Nachbarschaft von Molekuel %d...\n",refmol+1); for (z=0;zm_bDistMode) && (nb->m_waMolCount[z] == 0)) || (nb->m_bDistMode && (nb->m_faMolDist[z] == 0))) { nb->m_waScanNeighborCount[z] = 0; continue; } m2 = (CMolecule*)g_oaMolecules[z]; // printf("*** Molekuel %d: %s\n",z+1,m2->Name); for (z2=0;z2<((CMolecule*)g_oaMolecules[z])->m_laSingleMolIndex.GetSize();z2++) { del[z2] = 99999.0f; if ((z == fixmol) && (z2 == refmol)) continue; if (prev != NULL) if (!prev->Contains(z,z2)) continue; // printf(" - Vertreter %d\n",z2+1); sm2 = (CSingleMolecule*)g_oaSingleMolecules[m2->m_laSingleMolIndex[z2]]; del[z2] = MolDist(sm,sm2,nb); // printf(" - Finaler Abstand: %f\n",del[z2]); } if (nb->m_bDistMode) { // printf("**DistMode**\n"); // mprintf("Die Nachbarn: "); c = 0; for (z3=0;z3<((CMolecule*)g_oaMolecules[z])->m_laSingleMolIndex.GetSize();z3++) if ((del[z3] <= nb->m_faMolDist[z]) && (del[z3] >= nb->m_faMolMinDist[z])) { // mprintf("%d (%f), ",z3+1,del[z3]); best[c] = z3; c++; } // mprintf("\n"); // printf(" # Die naechsten Nachbarn: "); for (z2=0;z2m_iNeighbourCount++; for (z3=0;z3m_waScanNeighborCount[z];z3++) if (((CxIntArray*)nb->m_oaScanNeighbors[z])->GetAt(z3) == best[z2]) { ((CxIntArray*)nb->m_oaScanNeighborHits[z])->GetAt(z3)++; goto _enddist; } ((CxIntArray*)nb->m_oaScanNeighbors[z])->Add(best[z2]); ((CxIntArray*)nb->m_oaScanNeighborHits[z])->Add(1); nb->m_waScanNeighborCount[z]++; _enddist:; } // printf("\n"); } else { // printf("**CountMode**\n"); for (z2=0;z2m_waMolCount[z];z2++) { d = 999999.0f; b = -1; for (z3=0;z3<((CMolecule*)g_oaMolecules[z])->m_laSingleMolIndex.GetSize();z3++) { if (del[z3] < d) { d = del[z3]; b = z3; } } best[z2] = b; del[b] = 1000000.0f; } // printf(" # Die naechsten Nachbarn: "); for (z2=nb->m_waMolCountMin[z]-1;z2m_waMolCount[z];z2++) { // printf("%d, ",best[z2]); nb->m_iNeighbourCount++; for (z3=0;z3m_waScanNeighborCount[z];z3++) if (((CxIntArray*)nb->m_oaScanNeighbors[z])->GetAt(z3) == best[z2]) { ((CxIntArray*)nb->m_oaScanNeighborHits[z])->GetAt(z3)++; goto _end; } ((CxIntArray*)nb->m_oaScanNeighbors[z])->Add(best[z2]); ((CxIntArray*)nb->m_oaScanNeighborHits[z])->Add(1); nb->m_waScanNeighborCount[z]++; _end:; } // printf("\n"); } } delete del; delete best; BTOUT; }*/ /*void CTimeStep::ScanAngle(int fixmol, int refmol, CCondition *co, CNbSearch *prev) { BTIN; int z2, z3, z4; double tf; CMolecule *m, *m2; CSingleMolecule *sm, *sm2; CxDVector3 vec0, vec1, vec2, vec3, vec4, vec5; CxIntArray tempwa; CNbSearch *nb; // mprintf("*** ScanAngle ***\n"); // mprintf(" FixMol = %d, RefMol = %d\n",fixmol,refmol); m = (CMolecule*)g_oaMolecules[fixmol]; // mprintf(" m->m_laSingleMolIndex[refmol] = %d\n",m->m_laSingleMolIndex[refmol]); nb = co->m_pTempNbS; sm = (CSingleMolecule*)g_oaSingleMolecules[m->m_laSingleMolIndex[refmol]]; // printf("Suche Nachbarschaft von Molekuel %d...\n",refmol+1); // mprintf(" SecondMol = %d\n",co->m_iSecondMol); m2 = (CMolecule*)g_oaMolecules[co->m_iSecondMol]; // printf("*** Molekuel %d: %s\n",z+1,m2->Name); for (z2=0;z2m_laSingleMolIndex.GetSize();z2++) { if ((co->m_iSecondMol == fixmol) && (z2 == refmol)) continue; if (prev != NULL) if (!prev->Contains(co->m_iSecondMol,z2)) continue; // printf(" - Vertreter %d\n",z2+1); sm2 = (CSingleMolecule*)g_oaSingleMolecules[m2->m_laSingleMolIndex[z2]]; co->m_pADF->BuildAtomList(sm,sm2,NULL,&tempwa); for (z4=0;z4m_pADF->m_bOrtho[0]) { vec0 = m_vaCoords[tempwa[z4]]; vec2 = m_vaCoords[tempwa[z4+1]]; vec3 = m_vaCoords[tempwa[z4+2]]; vec1 = CrossP(vec2-vec0,vec3-vec0); } else { vec0 = m_vaCoords[tempwa[z4]]; vec2 = m_vaCoords[tempwa[z4+1]]; vec1 = vec2-vec0; } if (co->m_pADF->m_bOrtho[1]) { vec4 = m_vaCoords[tempwa[z4+3]]; vec3 = m_vaCoords[tempwa[z4+4]]; vec5 = m_vaCoords[tempwa[z4+5]]; vec2 = CrossP(vec3-vec4,vec5-vec4); } else { vec4 = m_vaCoords[tempwa[z4+3]]; vec3 = m_vaCoords[tempwa[z4+4]]; vec2 = vec3-vec4; } tf = Angle_Deg(vec1,vec2); if ((tf >= co->m_pADF->m_fMinAngle) && (tf <= co->m_pADF->m_fMaxAngle)) { nb->m_iNeighbourCount++; for (z3=0;z3m_waScanNeighborCount[co->m_iSecondMol];z3++) if (((CxIntArray*)nb->m_oaScanNeighbors[co->m_iSecondMol])->GetAt(z3) == z2) { ((CxIntArray*)nb->m_oaScanNeighborHits[co->m_iSecondMol])->GetAt(z3)++; goto _endang; } ((CxIntArray*)nb->m_oaScanNeighbors[co->m_iSecondMol])->Add(z2); ((CxIntArray*)nb->m_oaScanNeighborHits[co->m_iSecondMol])->Add(1); nb->m_waScanNeighborCount[co->m_iSecondMol]++; _endang:; break; } } } BTOUT; }*/ /*void CTimeStep::GatherNbDiagram(int refmol, CNbSearch *nb) { BTIN; double *del, d; int *best, b; bool *done; int z, z2, z3, z4, c, z0; CMolecule *m, *m2; CSingleMolecule *sm, *sm2; CxDVector3 vec; // FILE *a; m = (CMolecule*)g_oaMolecules[g_iFixMol]; sm = (CSingleMolecule*)g_oaSingleMolecules[m->m_laSingleMolIndex[refmol]]; del = new double[g_oaSingleMolecules.GetSize()]; best = new int[g_oaSingleMolecules.GetSize()]; done = new bool[g_oaSingleMolecules.GetSize()]; // printf("Suche Nachbarschaft von Molekuel %d...\n",refmol+1); for (z=0;zm_bDistMode && (nb->m_faMolDist[z] == 0)) { nb->m_waScanNeighborCount[z] = 0; continue; } m2 = (CMolecule*)g_oaMolecules[z]; // printf("*** Molekuel %d: %s\n",z+1,m2->Name); // for (z2=0;z2<=((CMolecule*)g_oaMolecules[z])->m_laSingleMolIndex.GetSize();z2++) // del[z2] = 99999.0f; for (z2=0;z2<((CMolecule*)g_oaMolecules[z])->m_laSingleMolIndex.GetSize();z2++) { del[z2] = 99999.0f; if ((z == g_iFixMol) && (z2 == refmol)) continue; // printf(" - Vertreter %d\n",z2+1); sm2 = (CSingleMolecule*)g_oaSingleMolecules[m2->m_laSingleMolIndex[z2]]; for (z3=0;z3m_waRefElements.GetSize();z3++) for (z4=0;z4<((CxIntArray*)nb->m_oaNbElements[z])->GetSize();z4++) { vec = m_vaCoords[((CxIntArray*)sm->m_oaAtomOffset[nb->m_waRefElements[z3]])->GetAt(nb->m_waRefAtoms[z3])] - m_vaCoords[((CxIntArray*)sm2->m_oaAtomOffset[((CxIntArray*)nb->m_oaNbElements[z])->GetAt(z4)])->GetAt(((CxIntArray*)nb->m_oaNbAtoms[z])->GetAt(z4))]; if (g_bFold) { while (vec[0] >= g_fBoxX/2) vec[0] -= g_fBoxX; while (vec[0] < -g_fBoxX/2) vec[0] += g_fBoxX; while (vec[1] >= g_fBoxY/2) vec[1] -= g_fBoxY; while (vec[1] < -g_fBoxY/2) vec[1] += g_fBoxY; while (vec[2] >= g_fBoxZ/2) vec[2] -= g_fBoxZ; while (vec[2] < -g_fBoxZ/2) vec[2] += g_fBoxZ; } d = vec.GetLength(); // printf(" = m1 %d (%d|%d); m2 %d (%d|%d); Dist = %f\n",z3+1,m->m_waNbElements[z3]+1,m->m_waNbAtoms[z3]+1,z4+1,m2->m_waNbElements[z4]+1,m2->m_waNbAtoms[z4]+1,d); if (d < del[z2]) del[z2] = d; } // printf(" - Finaler Abstand: %f\n",del[z2]); } for (z0=0;z0m_pAF->m_iResolution;z0++) { c = 0; for (z2=0;z2<((CMolecule*)g_oaMolecules[z])->m_laSingleMolIndex.GetSize();z2++) done[z2] = false; while (true) { d = 999999.0f; b = -1; for (z3=0;z3<((CMolecule*)g_oaMolecules[z])->m_laSingleMolIndex.GetSize();z3++) { if (done[z3]) continue; if (del[z3] < d) { d = del[z3]; b = z3; } } if (d > nb->m_pAF->m_fMaxVal*z0/nb->m_pAF->m_iResolution) break; best[c] = b; done[b] = true; c++; // if (c >= ((CMolecule*)g_oaMolecules[z])->m_laSingleMolIndex.GetSize()) // break; } nb->m_pAF->AddToBin(nb->m_pAF->m_fMaxVal*z0/nb->m_pAF->m_iResolution,(double)c); // if (g_iSteps == 1) // mfprintf(a,"%f;%f\n",nb->m_pAF->m_fMaxVal*z0/nb->m_pAF->m_iResolution,(double)c); } // if (g_iSteps == 1) // fclose(a); } delete del; delete best; BTOUT; }*/ int CTimeStep::REC_UniteMolecules(CSingleMolecule *sm, int i0, int depth) { int z, z2, n; CMolAtom *m; n = 0; m = (CMolAtom*)sm->m_oaMolAtoms[i0]; /* if (g_bVerbose) { mprintf("# "); for (z2=0;z2>> REC_UniteMolecules MolAtom=%d, Offset=%d.\n",i0,m->m_iOffset); }*/ g_pUniteTemp[m->m_iOffset] = true; for (z=0;zm_oaBonds.GetSize();z++) { if (!g_pUniteTemp[((CMolAtom*)m->m_oaBonds[z])->m_iOffset]) { if (MirrorBond(m->m_iOffset,((CMolAtom*)m->m_oaBonds[z])->m_iOffset)) { if (g_bVerbose) { mprintf("# "); for (z2=0;z2 %s(%d) unwrapped.\n",(const char*)((CAtom*)g_oaAtoms[g_baAtomIndex[m->m_iOffset]])->m_sName,m->m_iOffset+1,(const char*)((CAtom*)g_oaAtoms[g_baAtomIndex[((CMolAtom*)m->m_oaBonds[z])->m_iOffset]])->m_sName,((CMolAtom*)m->m_oaBonds[z])->m_iOffset+1); } n++; } n += REC_UniteMolecules(sm,((CMolAtom*)m->m_oaBonds[z])->m_iMolAtomNumber,depth+1); } } /* if (g_bVerbose) { mprintf("# "); for (z2=0;z2m_iOffset); }*/ return n; } void CTimeStep::UniteMolecules(bool verbose) { BTIN; int z, z2, n; CMolecule *m; CSingleMolecule *sm; for (z=0;zm_bPseudo) continue; if (m->m_bPolymer) { if (verbose) mprintf(" Skipping molecule %s: Is a polymer of infinite extent.\n",m->m_sName); continue; } for (z2=0;z2m_laSingleMolIndex.GetSize();z2++) { sm = (CSingleMolecule*)g_oaSingleMolecules[m->m_laSingleMolIndex[z2]]; // if (g_bVerbose) // mprintf(" # UniteMolecules molecule %s (%d)\n",m->m_sName,z2+1); n = REC_UniteMolecules(sm,0,0); if ((n != 0) && verbose) mprintf(" - Molecule %s[%d] united, %d bonds unwrapped.\n",m->m_sName,z2+1,n); if ((n != 0) && (!verbose) && g_bVerbose) mprintf("\n # UniteMolecules: Molecule %s[%d] united, %d bonds unwrapped.",m->m_sName,z2+1,n); } } BTOUT; } bool CTimeStep::ReadTimestep(FILE *a, bool needinfo) { BTIN; switch(g_iTrajFormat) { case 0: if (!ReadXYZ(a,needinfo,&m_vaCoords)) return false; break; case 1: if (!ReadPDB(a,needinfo,&m_vaCoords)) return false; break; case 2: if (!ReadMol2(a,needinfo)) return false; break; case 3: if (!ReadLAMMPS(a,needinfo)) return false; break; case 4: if (!ReadDLPOLY(a,needinfo)) return false; break; case 5: if (!ReadCube(a,needinfo)) return false; break; case 6: if (!ReadAmber(a,needinfo)) return false; break; case 7: if (!ReadBQB(g_pBQBFile,needinfo)) return false; break; } if (g_bDoubleBox) DoubleBox(); BTOUT; return true; } bool CTimeStep::ReadTimestep(CxMemFile *file) { if (!ReadCube(file)) return false; if (g_bDoubleBox) DoubleBox(); return true; } bool CTimeStep::SkipTimestep(FILE *a) { BTIN; switch(g_iTrajFormat) { case 0: if (!SkipXYZ(a)) return false; break; case 1: if (!SkipPDB(a)) return false; break; case 2: if (!SkipMol2(a)) return false; break; case 3: if (!SkipLAMMPS(a)) return false; break; case 4: if (!SkipDLPOLY(a)) return false; break; case 5: if (!SkipCube(a)) return false; break; case 6: if (!SkipAmber(a)) return false; break; case 7: if (!SkipBQB()) return false; break; } BTOUT; return true; } bool CTimeStep::ReadTimestepVel(FILE *a) { BTIN; char buf[256], *p, *q; int z, tc; buf[0] = 0; (void)fgets(buf,256,a); if (feof(a)) { BTOUT; return false; } if (strlen(buf) > 0) buf[strlen(buf)-1] = 0; tc = atoi(buf); if (tc == 0) { BTOUT; return false; } m_vaVelocities.SetSize(tc); buf[0] = 0; (void)fgets(buf,256,a); // Zeitschritt - egal hier if (strlen(buf) > 0) buf[strlen(buf)-1] = 0; for (z=0;z 0) buf[strlen(buf)-1] = 0; q = buf; while (*q == ' ') q++; p = strchr(q,' '); if (p == NULL) { eprintf("CTimeStep::ReadTimestepVel(): Error 1. %d, \"%s\"\n",z+1,buf); continue; } while (isdigit(*(p-1)) && (p > buf)) p--; if (p == buf) { eprintf("CTimeStep::ReadTimestepVel(): No Atom laben found. %d, \"%s\"\n",z+1,buf); continue; } *p = 0; p++; q = strchr(p,' '); if (q == NULL) { eprintf("CTimeStep::ReadTimestepVel(): Error 2. %d, \"%s\"\n",z+1,p); continue; } while (*q == ' ') q++; p = strchr(q,' '); if (p == NULL) { eprintf("CTimeStep::ReadTimestepVel(): Error 3. %d, \"%s\"\n",z+1,q); continue; } *p = 0; // Convert to pm/ps = m/s as used in TRAVIS m_vaVelocities[z][0] = atof(q) * g_fVelocityConversion; q = p+1; while (*q == ' ') q++; p = strchr(q,' '); if (p == NULL) { eprintf("CTimeStep::ReadTimestepVel(): Error 4. %d, \"%s\"\n",z+1,q); continue; } *p = 0; m_vaVelocities[z][1] = atof(q) * g_fVelocityConversion; q = p+1; while (*q == ' ') q++; p = strchr(q,' '); if (p != NULL) *p = 0; m_vaVelocities[z][2] = atof(q) * g_fVelocityConversion; } if (g_bDoubleBox) DoubleBoxVelocity(); BTOUT; return true; } bool CTimeStep::ReadTimestepForce(FILE *a) { BTIN; char buf[256], *p, *q; int z, tc; buf[0] = 0; (void)fgets(buf,256,a); if (feof(a)) { BTOUT; return false; } if (strlen(buf) > 0) buf[strlen(buf)-1] = 0; tc = atoi(buf); if (tc == 0) { BTOUT; return false; } m_vaForces.SetSize(tc); buf[0] = 0; (void)fgets(buf,256,a); // Zeitschritt - egal hier if (strlen(buf) > 0) buf[strlen(buf)-1] = 0; for (z=0;z 0) buf[strlen(buf)-1] = 0; q = buf; while (*q == ' ') q++; p = strchr(q,' '); if (p == NULL) { eprintf("CTimeStep::ReadTimestepForce(): Error 1. %d, \"%s\"\n",z+1,buf); continue; } while (isdigit(*(p-1)) && (p > buf)) p--; if (p == buf) { eprintf("CTimeStep::ReadTimestepForce(): No Atom laben found. %d, \"%s\"\n",z+1,buf); continue; } *p = 0; p++; q = strchr(p,' '); if (q == NULL) { eprintf("CTimeStep::ReadTimestepForce(): Error 2. %d, \"%s\"\n",z+1,p); continue; } while (*q == ' ') q++; p = strchr(q,' '); if (p == NULL) { eprintf("CTimeStep::ReadTimestepForce(): Error 3. %d, \"%s\"\n",z+1,q); continue; } *p = 0; m_vaForces[z][0] = atof(q); q = p+1; while (*q == ' ') q++; p = strchr(q,' '); if (p == NULL) { eprintf("CTimeStep::ReadTimestepForce(): Error 4. %d, \"%s\"\n",z+1,q); continue; } *p = 0; m_vaForces[z][1] = atof(q); q = p+1; while (*q == ' ') q++; p = strchr(q,' '); if (p != NULL) *p = 0; m_vaForces[z][2] = atof(q); } if (g_bDoubleBox) DoubleBoxForce(); BTOUT; return true; } bool CTimeStep::SkipXYZ(FILE *a) { BTIN; char buf[256]; int z, tc; // mprintf("*** Skip Anfang ***\n"); buf[0] = 0; (void)fgets_bin(buf,256,a); if (feof(a)) { BTOUT; return false; } if (strlen(buf)==0) { BTOUT; return false; } buf[strlen(buf)-1] = 0; tc = atoi(buf); // mprintf("SkipA: \"%s\".\n",buf); if (tc == 0) { BTOUT; return false; } // buf[0] = 0; (void)fgets_bin(buf,256,a); // Zeitschritt - egal hier // mprintf("SkipB: \"%s\".\n",buf); for (z=0;zm_iGesAtomCount; m_vaCoords.CopyFrom(&t->m_vaCoords); if (g_bKeepUnfoldedCoords) m_vaCoords_Unfolded.CopyFrom(&t->m_vaCoords_Unfolded); m_vaForces.CopyFrom(&t->m_vaForces); m_vaVelocities.CopyFrom(&t->m_vaVelocities); if (t->m_paLabels.GetSize() != 0) { for (z=0;zm_paLabels.GetSize();z++) { try { p = new char[strlen((char*)t->m_paLabels[z])+1]; } catch(...) { p = NULL; } if (p == NULL) NewException((double)(strlen((char*)t->m_paLabels[z])+1)*sizeof(char),__FILE__,__LINE__,__PRETTY_FUNCTION__); strcpy(p,(char*)t->m_paLabels[z]); m_paLabels.Add(p); } } if (t->m_pComment != NULL) { if (m_pComment == NULL) { try { m_pComment = new char[256]; } catch(...) { m_pComment = NULL; } if (m_pComment == NULL) NewException((double)256*sizeof(char),__FILE__,__LINE__,__PRETTY_FUNCTION__); } strcpy(m_pComment,t->m_pComment); } if (t->m_pVolumetricData != NULL) { if (m_pVolumetricData != NULL) delete m_pVolumetricData; m_pVolumetricData = new C3DF(); m_pVolumetricData->CopyFrom(t->m_pVolumetricData); } if (t->m_pVolumetricDataTimeDev != NULL) { if (m_pVolumetricDataTimeDev != NULL) delete m_pVolumetricDataTimeDev; m_pVolumetricDataTimeDev = new C3DF(); m_pVolumetricDataTimeDev->CopyFrom(t->m_pVolumetricDataTimeDev); } if (t->m_pCurrentDensity != NULL) { if (m_pCurrentDensity != NULL) delete m_pCurrentDensity; m_pCurrentDensity = new CxDoubleArray(); m_pCurrentDensity->CopyFrom(t->m_pCurrentDensity); } BTOUT; } long CTimeStep::ExtractNumber(int i) { BXIN; char *p, *q, buf[20]; int z; long l; if (m_pComment == NULL) return -1; p = m_pComment; for (z=0;z= 256) { eprintf("Internal Error in ExtractNumber(): %ld >= 256.\n",q-p); return 0; } memcpy(buf,p,q-p); buf[q-p] = 0; l = atoi(buf); BXOUT; return l; } int CTimeStep::GetCommentNumberCount() { BXIN; char *p, *q; int z; if (m_pComment == NULL) return 0; p = m_pComment; z = 0; while (true) { while ((!isdigit(*p)) && (*p != 0)) p++; if (*p == 0) { // mprintf("GetCommentNumberCount 1: %d (p=\"%s\", q=\"%s\")\n",z,p,q); BXOUT; return z; } q = p; while ((isdigit(*q)) && (*q != 0)) q++; if (q == p) { // mprintf("GetCommentNumberCount 2: %d (p=\"%s\", q=\"%s\")\n",z,p,q); BXOUT; return z; } z++; if (*q == 0) { // mprintf("GetCommentNumberCount 3: %d (p=\"%s\", q=\"%s\")\n",z,p,q); BXOUT; return z; } p = q+1; } return 0; // Never happens } bool CTimeStep::ScanWannier(bool verbose) { BTIN; int z, z2, z3; double td, d, dx, dy, dz; CMolecule *m; if (g_bVerbose) { mprintf(WHITE,"\n*** ScanWannier ***\n\n"); verbose = true; } for (z=0;zm_laWannier.RemoveAll_KeepSize(); for (z=0;z 0.5) v[0] -= 1.0; while (v[0] <= -0.5) v[0] += 1.0; while (v[1] > 0.5) v[1] -= 1.0; while (v[1] <= -0.5) v[1] += 1.0; while (v[2] > 0.5) v[2] -= 1.0; while (v[2] <= -0.5) v[2] += 1.0; v = g_mBoxFromOrtho * v; dx = v[0]; dy = v[1]; dz = v[2]; } else { if (g_bPeriodicX) { while (dx > g_fBoxX/2.0) dx -= g_fBoxX; while (dx < -g_fBoxX/2.0) dx += g_fBoxX; } if (g_bPeriodicY) { while (dy > g_fBoxY/2.0) dy -= g_fBoxY; while (dy < -g_fBoxY/2.0) dy += g_fBoxY; } if (g_bPeriodicZ) { while (dz > g_fBoxZ/2.0) dz -= g_fBoxZ; while (dz < -g_fBoxZ/2.0) dz += g_fBoxZ; } } td = sqrt(dx*dx+dy*dy+dz*dz); if (td < d) { d = td; z3 = z2; } } if (z3 == -1) { eprintf("CTimeStep::ScanWannier(): Internal error.\n"); abort(); } if (g_bBoxNonOrtho) { CxDVector3 v = g_mBoxToOrtho * (m_vaCoords[z] - m_vaCoords[z3]); while (v[0] > 0.5) v[0] -= 1.0; while (v[0] <= -0.5) v[0] += 1.0; while (v[1] > 0.5) v[1] -= 1.0; while (v[1] <= -0.5) v[1] += 1.0; while (v[2] > 0.5) v[2] -= 1.0; while (v[2] <= -0.5) v[2] += 1.0; v = g_mBoxFromOrtho * v; m_vaCoords[z] = v + m_vaCoords[z3]; } else { if (g_bPeriodicX) { while (m_vaCoords[z][0]-m_vaCoords[z3][0] > g_fBoxX/2.0) m_vaCoords[z][0] -= g_fBoxX; while (m_vaCoords[z][0]-m_vaCoords[z3][0] < -g_fBoxX/2.0) m_vaCoords[z][0] += g_fBoxX; } if (g_bPeriodicY) { while (m_vaCoords[z][1]-m_vaCoords[z3][1] > g_fBoxY/2.0) m_vaCoords[z][1] -= g_fBoxY; while (m_vaCoords[z][1]-m_vaCoords[z3][1] < -g_fBoxY/2.0) m_vaCoords[z][1] += g_fBoxY; } if (g_bPeriodicZ) { while (m_vaCoords[z][2]-m_vaCoords[z3][2] > g_fBoxZ/2.0) m_vaCoords[z][2] -= g_fBoxZ; while (m_vaCoords[z][2]-m_vaCoords[z3][2] < -g_fBoxZ/2.0) m_vaCoords[z][2] += g_fBoxZ; } } z2 = g_laAtomSMIndex[z3]; if (d > 105.0) { eprintf("Step %lu: Wannier center at offset %d too far away from any atom (closest atom is %s[%d] %s%d, %.0f pm).\n",g_iSteps,z+1,((CMolecule*)g_oaMolecules[((CSingleMolecule*)g_oaSingleMolecules[z2])->m_iMolType])->m_sName,((CSingleMolecule*)g_oaSingleMolecules[z2])->m_iMolSMIndex+1,(const char*)((CAtom*)g_oaAtoms[g_waAtomRealElement[z3]])->m_sName,g_waAtomMolNumber[z3]+1,d); } else if (verbose) mprintf(" - Wannier center %d belongs to %s[%d] %s%d (%.0f pm).\n",z+1,((CMolecule*)g_oaMolecules[((CSingleMolecule*)g_oaSingleMolecules[z2])->m_iMolType])->m_sName,((CSingleMolecule*)g_oaSingleMolecules[z2])->m_iMolSMIndex+1,(const char*)((CAtom*)g_oaAtoms[g_waAtomRealElement[z3]])->m_sName,g_waAtomMolNumber[z3]+1,d); /* if (z2 == -1) { eprintf("Wannier center %d: Atom %d does not belong to any molecule.\n",z+1,z3+1); continue; }*/ // mprintf("Wannier Center %d hat Abstand %.2f zu Atom %d in SM %d.\n",z+1,d,z3+1,z2+1); ((CSingleMolecule*)g_oaSingleMolecules[z2])->m_laWannier.Add(z); } if (verbose) mprintf("\n\n"); for (z=0;zm_iWannierCount == 0 && !m->m_bPseudo) { m->m_iWannierCount = ((CSingleMolecule*)g_oaSingleMolecules[m->m_laSingleMolIndex[0]])->m_laWannier.GetSize(); td = 0; for (z2=0;z2m_baAtomIndex.GetSize();z2++) { if (m->m_baAtomIndex[z2] == g_iWannierAtomType) continue; if (m->m_baAtomIndex[z2] == g_iVirtAtomType) continue; td += ((CAtom*)g_oaAtoms[m->m_baAtomIndex[z2]])->m_fCharge * m->m_waAtomCount[z2]; } m->m_fCharge = td-m->m_iWannierCount*g_fWannierCharge; mprintf(" - Molecule %s contains %d wannier centers. Total charge is %.2f - %.2f = %.2f\n",m->m_sName,m->m_iWannierCount,td,m->m_iWannierCount*g_fWannierCharge,m->m_fCharge); if (m->m_fCharge > 5.0) { eprintf("\n This molecular charge seems to be too high.\n\n"); if (!AskYesNo(" Do you want to continue (y/n)? [yes] ",true)) return false; } } for (z2=0;z2m_laSingleMolIndex.GetSize();z2++) { if (m->m_iWannierCount != ((CSingleMolecule*)g_oaSingleMolecules[m->m_laSingleMolIndex[z2]])->m_laWannier.GetSize()) eprintf("Step %lu: Molecule %s[%d] contains %d instead of %d wannier centers.\n",g_iSteps,m->m_sName,z2+1,((CSingleMolecule*)g_oaSingleMolecules[m->m_laSingleMolIndex[z2]])->m_laWannier.GetSize(),m->m_iWannierCount); } } BTOUT; return true; } void CTimeStep::CalcMagneticDipoles() { const int BUF_SIZE = 1024; int i; for (i = 0; i < g_oaSingleMolecules.GetSize(); i++) { CSingleMolecule *sm = (CSingleMolecule *)g_oaSingleMolecules[i]; if (g_bLoadMagneticDipoleRestart) { int j; for (j = 0; j < 3; j++) { double val; if (fread(&val, sizeof(double), 1, g_fMagneticDipoleRestartFile) < 1) { eprintf("Could not read from magnetic moment restart file. Setting value to 0.0.\n"); val = 0.0; } sm->m_vMagneticDipole[j] = val; } } else { sm->m_vMagneticDipole = CxDVector3(0.0, 0.0, 0.0); sm->m_vCurrent = CxDVector3(0.0, 0.0, 0.0); } } for (i = 0; i < g_oaMolecules.GetSize(); i++) { CMolecule *m = (CMolecule *)g_oaMolecules[i]; int j; for (j = 0; j < m->m_laSingleMolIndex.GetSize(); j++) { CSingleMolecule *sm = (CSingleMolecule *)g_oaSingleMolecules[m->m_laSingleMolIndex[j]]; if (m->m_iMagneticDipoleMode == 0) { sm->m_vMagneticDipole = CxDVector3(0.0, 0.0, 0.0); } else if (m->m_iMagneticDipoleMode == 1) { CxDVector3 ref(0.0, 0.0, 0.0); ref = m_vaCoords[((CxIntArray *)sm->m_oaAtomOffset[m->m_iDipoleCenterType])->GetAt(m->m_iDipoleCenterIndex)]; int k; for (k = 0; k < m->m_baAtomIndex.GetSize(); k++) { if (m->m_baAtomIndex[k] == g_iVirtAtomType) continue; if (m->m_baAtomIndex[k] == g_iWannierAtomType) continue; CAtom *a = (CAtom *)g_oaAtoms[m->m_baAtomIndex[k]]; int l; for (l = 0; l < m->m_waAtomCount[k]; l++) { sm->m_vMagneticDipole += 0.5 * a->m_fCharge * CrossP(m_vaCoords[((CxIntArray *)sm->m_oaAtomOffset[k])->GetAt(l)] - ref, m_vaVelocities[((CxIntArray *)sm->m_oaAtomOffset[k])->GetAt(l)]); // mprintf(RED, "c2: ( %14.10G | %14.10G | %14.10G )\n", (m_vaCoords[((CxIntArray *)sm->m_oaAtomOffset[k])->GetAt(l)] - ref)[0], (m_vaCoords[((CxIntArray *)sm->m_oaAtomOffset[k])->GetAt(l)] - ref)[1], (m_vaCoords[((CxIntArray *)sm->m_oaAtomOffset[k])->GetAt(l)] - ref)[2]); // mprintf(RED, "v2: ( %14.10G | %14.10G | %14.10G )\n", m_vaVelocities[((CxIntArray *)sm->m_oaAtomOffset[k])->GetAt(l)][0], m_vaVelocities[((CxIntArray *)sm->m_oaAtomOffset[k])->GetAt(l)][1], m_vaVelocities[((CxIntArray *)sm->m_oaAtomOffset[k])->GetAt(l)][2]); } } for (k = 0; k < sm->m_laWannier.GetSize(); k++) { sm->m_vMagneticDipole -= g_fWannierCharge * CrossP(m_vaCoords[sm->m_laWannier[k]] - ref, m_vaVelocities[sm->m_laWannier[k]]); // mprintf(RED, "c2: ( %14.10G | %14.10G | %14.10G )\n", (m_vaCoords[sm->m_laWannier[k]] - ref)[0], (m_vaCoords[sm->m_laWannier[k]] - ref)[1], (m_vaCoords[sm->m_laWannier[k]] - ref)[2]); // mprintf(RED, "v2: ( %14.10G | %14.10G | %14.10G )\n", m_vaVelocities[sm->m_laWannier[k]][0], m_vaVelocities[sm->m_laWannier[k]][1], m_vaVelocities[sm->m_laWannier[k]][2]); } sm->m_vMagneticDipole *= MAG_EPMMS2MB; // mprintf(RED, "M: ( %14.10G | %14.10G | %14.10G )\n", sm->m_vMagneticDipole[0], sm->m_vMagneticDipole[1], sm->m_vMagneticDipole[2]); } else if (m->m_iMagneticDipoleMode == 2) { if (j == 0) { char buf[BUF_SIZE]; double dipole[3]; if (fgets(buf, BUF_SIZE, m->m_pMagneticDipoleFile) == NULL || sscanf(buf, "%lf %lf %lf", &dipole[0], &dipole[1], &dipole[2]) < 3) eprintf("Could not read from dipole file. Setting magnetic moment to ( 0.0 | 0.0 | 0.0 ).\n"); else sm->m_vMagneticDipole = CxDVector3(dipole[0], dipole[1], dipole[2]); } else { sm->m_vMagneticDipole = ((CSingleMolecule *)g_oaSingleMolecules[m->m_laSingleMolIndex[0]])->m_vMagneticDipole; } } else if (m->m_iMagneticDipoleMode == 3) { if (j == 0) { char comment[BUF_SIZE]; strncpy(comment, m_pComment, BUF_SIZE); comment[BUF_SIZE-1] = '\0'; const char delim[] = "\t "; char *tok = strtok(comment, delim); int num = 0; bool ok[3] = { false, false, false }; while (tok != NULL) { double f; if (sscanf(tok, "%lf", &f) == 1) { if (num == m->m_iMagneticDipoleCommentIndex[0]) { sm->m_vMagneticDipole[0] = f; ok[0] = true; } if (num == m->m_iMagneticDipoleCommentIndex[1]) { sm->m_vMagneticDipole[1] = f; ok[1] = true; } if (num == m->m_iMagneticDipoleCommentIndex[2]) { sm->m_vMagneticDipole[2] = f; ok[2] = true; } num++; } tok = strtok(NULL, delim); } if (!(ok[0] && ok[1] && ok[2])) { eprintf("Could not read from comment line. Setting magnetic moment to ( 0.0 | 0.0 | 0.0 ).\n"); sm->m_vMagneticDipole = CxDVector3(0.0, 0.0, 0.0); } } else { sm->m_vMagneticDipole = ((CSingleMolecule *)g_oaSingleMolecules[m->m_laSingleMolIndex[0]])->m_vMagneticDipole; } } else if (m->m_iMagneticDipoleMode == 4) { CxDVector3 ref(0.0, 0.0, 0.0); ref = m_vaCoords[((CxIntArray *)sm->m_oaAtomOffset[m->m_iDipoleCenterType])->GetAt(m->m_iDipoleCenterIndex)]; int k; for (k = 0; k < m->m_baAtomIndex.GetSize(); k++) { if (m->m_baAtomIndex[k] == g_iVirtAtomType) continue; int l; for (l = 0; l < m->m_waAtomCount[k]; l++) { sm->m_vMagneticDipole += ((CxDoubleArray *)m->m_oaCharges[k])->GetAt(l) * CrossP(m_vaCoords[((CxIntArray *)sm->m_oaAtomOffset[k])->GetAt(l)] - ref, m_vaVelocities[((CxIntArray *)sm->m_oaAtomOffset[k])->GetAt(l)]); } sm->m_vMagneticDipole *= MAG_EPMMS2MB; } } else if (m->m_iMagneticDipoleMode == 5) { CxDVector3 ref(0.0, 0.0, 0.0); ref = m_vaCoords[((CxIntArray *)sm->m_oaAtomOffset[m->m_iDipoleCenterType])->GetAt(m->m_iDipoleCenterIndex)]; int k; for (k = 0; k < m->m_baAtomIndex.GetSize(); k++) { if (m->m_baAtomIndex[k] == g_iVirtAtomType) continue; int l; for (l = 0; l < m->m_waAtomCount[k]; l++) { sm->m_vMagneticDipole += m_faCharge[((CxIntArray *)sm->m_oaAtomOffset[k])->GetAt(l)] * CrossP(m_vaCoords[((CxIntArray *)sm->m_oaAtomOffset[k])->GetAt(l)] - ref, m_vaVelocities[((CxIntArray *)sm->m_oaAtomOffset[k])->GetAt(l)]); } sm->m_vMagneticDipole *= MAG_EPMMS2MB; } } else if (m->m_iMagneticDipoleMode == 6) { CxDVector3 ref(0.0, 0.0, 0.0); ref = m_vaCoords[((CxIntArray *)sm->m_oaAtomOffset[m->m_iDipoleCenterType])->GetAt(m->m_iDipoleCenterIndex)]; int k; for (k = 0; k < m->m_baAtomIndex.GetSize(); k++) { if (m->m_baAtomIndex[k] == g_iVirtAtomType) continue; int l; for (l = 0; l < m->m_waAtomCount[k]; l++) { sm->m_vMagneticDipole += m_faCharge[((CxIntArray *)sm->m_oaAtomOffset[k])->GetAt(l)] * CrossP(m_vaCoords[((CxIntArray *)sm->m_oaAtomOffset[k])->GetAt(l)] - ref, m_vaVelocities[((CxIntArray *)sm->m_oaAtomOffset[k])->GetAt(l)]); } sm->m_vMagneticDipole *= MAG_EPMMS2MB; } } else if (m->m_iMagneticDipoleMode == 7) { CxDVector3 ref(0.0, 0.0, 0.0); if (!g_bDipoleRefFixed) ref = m_vaCoords[((CxIntArray *)sm->m_oaAtomOffset[m->m_iDipoleCenterType])->GetAt(m->m_iDipoleCenterIndex)]; int k; // double totalCharge = 0.0f; for (k = 0; k < m->m_baAtomIndex.GetSize(); k++) { if (m->m_baAtomIndex[k] == g_iVirtAtomType) continue; CAtom *a = (CAtom *)g_oaAtoms[m->m_baAtomIndex[k]]; int l; for (l = 0; l < m->m_waAtomCount[k]; l++) { /* if (j == 1) mprintf("\n#%d.%d: += (%10g|%10g|%10g) + 0.5*CrossP[ (%10g|%10g|%10g)-(%10g|%10g|%10g), (%10g|%10g|%10g) ] + 0.5*%10g*CrossP[ (%10g|%10g|%10g)-(%10g|%10g|%10g), (%10g|%10g|%10g) ]", k+1, l+1, m_magneticDipoleMoments[((CxIntArray *)sm->m_oaAtomOffset[k])->GetAt(l)][0], m_magneticDipoleMoments[((CxIntArray *)sm->m_oaAtomOffset[k])->GetAt(l)][1], m_magneticDipoleMoments[((CxIntArray *)sm->m_oaAtomOffset[k])->GetAt(l)][2], m_vaCoords[((CxIntArray *)sm->m_oaAtomOffset[k])->GetAt(l)][0], m_vaCoords[((CxIntArray *)sm->m_oaAtomOffset[k])->GetAt(l)][1], m_vaCoords[((CxIntArray *)sm->m_oaAtomOffset[k])->GetAt(l)][2], ref[0], ref[1], ref[2], m_totalCurrents[((CxIntArray *)sm->m_oaAtomOffset[k])->GetAt(l)][0], m_totalCurrents[((CxIntArray *)sm->m_oaAtomOffset[k])->GetAt(l)][1], m_totalCurrents[((CxIntArray *)sm->m_oaAtomOffset[k])->GetAt(l)][2], a->m_fCharge, m_vaCoords[((CxIntArray *)sm->m_oaAtomOffset[k])->GetAt(l)][0], m_vaCoords[((CxIntArray *)sm->m_oaAtomOffset[k])->GetAt(l)][1], m_vaCoords[((CxIntArray *)sm->m_oaAtomOffset[k])->GetAt(l)][2], ref[0], ref[1], ref[2], m_vaVelocities[((CxIntArray *)sm->m_oaAtomOffset[k])->GetAt(l)][0], m_vaVelocities[((CxIntArray *)sm->m_oaAtomOffset[k])->GetAt(l)][1], m_vaVelocities[((CxIntArray *)sm->m_oaAtomOffset[k])->GetAt(l)][2]);*/ sm->m_vMagneticDipole += m_magneticDipoleMoments[((CxIntArray *)sm->m_oaAtomOffset[k])->GetAt(l)] + 0.5 * CrossP(m_vaCoords[((CxIntArray *)sm->m_oaAtomOffset[k])->GetAt(l)] - ref, m_totalCurrents[((CxIntArray *)sm->m_oaAtomOffset[k])->GetAt(l)]) + 0.5 * a->m_fCharge * CrossP(m_vaCoords[((CxIntArray *)sm->m_oaAtomOffset[k])->GetAt(l)] - ref, m_vaVelocities[((CxIntArray *)sm->m_oaAtomOffset[k])->GetAt(l)]) * MAG_EPMMS2MB; sm->m_vCurrent += m_totalCurrents[((CxIntArray *)sm->m_oaAtomOffset[k])->GetAt(l)]; // totalCharge += m_faCharge[((CxIntArray *)sm->m_oaAtomOffset[k])->GetAt(l)]; // sm->m_vMagneticDipole += 0.5f * a->m_fCharge * CrossP(m_vaCoords[((CxIntArray *)sm->m_oaAtomOffset[k])->GetAt(l)] - ref, m_vaVelocities[((CxIntArray *)sm->m_oaAtomOffset[k])->GetAt(l)]) * 1.727599e-8f; // sm->m_vMagneticDipole += m_magneticDipoleMoments[((CxIntArray *)sm->m_oaAtomOffset[k])->GetAt(l)] - 0.5f * CrossP(m_vaCoords[((CxIntArray *)sm->m_oaAtomOffset[k])->GetAt(l)] - ref, m_totalCurrents[((CxIntArray *)sm->m_oaAtomOffset[k])->GetAt(l)]); // sm->m_vMagneticDipole += m_magneticDipoleMoments[((CxIntArray *)sm->m_oaAtomOffset[k])->GetAt(l)]; } } if (!g_bDipoleRefFixed) sm->m_vMagneticDipole -= 0.5 * CrossP(sm->m_vDipole, m_vaVelocities[((CxIntArray *)sm->m_oaAtomOffset[m->m_iDipoleCenterType])->GetAt(m->m_iDipoleCenterIndex)]) * MAG_EPMMS2MB / DIP_EPM2DEBYE; /* if (j == 1) { mprintf("\n-= CrossP[ (%10g|%10g|%10g), (%10g|%10g|%10g) ]", sm->m_vDipole[0], sm->m_vDipole[1], sm->m_vDipole[2], m_vaVelocities[((CxIntArray *)sm->m_oaAtomOffset[m->m_iDipoleCenterType])->GetAt(m->m_iDipoleCenterIndex)][0], m_vaVelocities[((CxIntArray *)sm->m_oaAtomOffset[m->m_iDipoleCenterType])->GetAt(m->m_iDipoleCenterIndex)][1], m_vaVelocities[((CxIntArray *)sm->m_oaAtomOffset[m->m_iDipoleCenterType])->GetAt(m->m_iDipoleCenterIndex)][2]); mprintf("\n--> (%10g|%10g|%10g).",sm->m_vMagneticDipole[0],sm->m_vMagneticDipole[1],sm->m_vMagneticDipole[2]); }*/ // sm->m_vMagneticDipole += 0.5f * totalCharge * CrossP(ref, m_vaVelocities[((CxIntArray *)sm->m_oaAtomOffset[m->m_iDipoleCenterType])->GetAt(m->m_iDipoleCenterIndex)]) * (double)MAG_EPMMS2MB; // mprintf(GREEN, "%f %f %f\n", sm->m_vDipole[0], sm->m_vDipole[1], sm->m_vDipole[2]); // mprintf(GREEN, "%f %f %f\n", m_vaVelocities[((CxIntArray *)sm->m_oaAtomOffset[m->m_iDipoleCenterType])->GetAt(m->m_iDipoleCenterIndex)][0], m_vaVelocities[((CxIntArray *)sm->m_oaAtomOffset[m->m_iDipoleCenterType])->GetAt(m->m_iDipoleCenterIndex)][1], m_vaVelocities[((CxIntArray *)sm->m_oaAtomOffset[m->m_iDipoleCenterType])->GetAt(m->m_iDipoleCenterIndex)][2]); // mprintf(GREEN, "%f %f %f\n", (0.5f * CrossP(sm->m_vDipole, m_vaVelocities[((CxIntArray *)sm->m_oaAtomOffset[m->m_iDipoleCenterType])->GetAt(m->m_iDipoleCenterIndex)]) * 3.596761e-7f)[0], (0.5f * CrossP(sm->m_vDipole, m_vaVelocities[((CxIntArray *)sm->m_oaAtomOffset[m->m_iDipoleCenterType])->GetAt(m->m_iDipoleCenterIndex)]) * 3.596761e-7f)[1], (0.5f * CrossP(sm->m_vDipole, m_vaVelocities[((CxIntArray *)sm->m_oaAtomOffset[m->m_iDipoleCenterType])->GetAt(m->m_iDipoleCenterIndex)]) * 3.596761e-7f)[2]); } else if (m->m_iMagneticDipoleMode == 8) { eprintf("CTimeStep::CalcMagneticDipoles(): Mode 8 not implemented.\n"); abort(); } else { eprintf("CTimeStep::CalcMagneticDipoles(): Internal error.\n"); abort(); } } } } void CTimeStep::CalcDipoles(bool verbose) { const int BUF_SIZE = 1024; int i; int z, z2; double tf; UNUSED(verbose); for (i = 0; i < g_oaSingleMolecules.GetSize(); i++) { CSingleMolecule *sm = (CSingleMolecule *)g_oaSingleMolecules[i]; if (g_bLoadDipoleRestart) { int j; for (j = 0; j < 3; j++) { double val; if (fread(&val, sizeof(double), 1, g_fDipoleRestartFile) < 1) { eprintf("Could not read from dipole restart file. Setting value to 0.0.\n"); val = 0.0; } sm->m_vDipole[j] = val; } } else { sm->m_fCharge = 0; sm->m_vDipole = CxDVector3(0.0, 0.0, 0.0); if (g_bVoroIntegrateQuadrupoleMoment) for (z=0;z<9;z++) sm->m_mQuadrupole[z] = 0.0; } } // if (g_bTegri) // { // if (g_pTetraPak->m_bVoronoiCharges) // g_pTetraPak->ProcessStep(this,verbose); // // if (verbose) // mprintf("\n"); // } for(i = 0; i < g_oaMolecules.GetSize(); i++) { CMolecule *m = (CMolecule *)g_oaMolecules[i]; int j; for(j = 0; j < m->m_laSingleMolIndex.GetSize(); j++) { CSingleMolecule *sm = (CSingleMolecule *)g_oaSingleMolecules[m->m_laSingleMolIndex[j]]; CxDVector3 ref(0.0, 0.0, 0.0); if (!g_bDipoleRefFixed) ref = m_vaCoords[((CxIntArray *)sm->m_oaAtomOffset[m->m_iDipoleCenterType])->GetAt(m->m_iDipoleCenterIndex)]; if(m->m_iDipoleMode == 0) { sm->m_vDipole = CxDVector3(0.0, 0.0, 0.0); } else if(m->m_iDipoleMode == 1) { int k; for(k = 0; k < m->m_baAtomIndex.GetSize(); k++) { if(m->m_baAtomIndex[k] == g_iVirtAtomType) continue; if(m->m_baAtomIndex[k] == g_iWannierAtomType) continue; CAtom *a = (CAtom *)g_oaAtoms[m->m_baAtomIndex[k]]; int l; for(l = 0; l < m->m_waAtomCount[k]; l++) { sm->m_vDipole += a->m_fCharge * (m_vaCoords[((CxIntArray *)sm->m_oaAtomOffset[k])->GetAt(l)] - ref); } } for(k = 0; k < sm->m_laWannier.GetSize(); k++) { sm->m_vDipole -= g_fWannierCharge * (m_vaCoords[sm->m_laWannier[k]] - ref); } sm->m_vDipole *= DIP_EPM2DEBYE; } else if(m->m_iDipoleMode == 2) { if(j == 0) { char buf[BUF_SIZE]; double dipole[3]; if(fgets(buf, BUF_SIZE, m->m_pDipoleFile) == NULL || sscanf(buf, "%lf %lf %lf", &dipole[0], &dipole[1], &dipole[2]) < 3) eprintf("Could not read from dipole file. Setting dipole moment to ( 0.0 | 0.0 | 0.0 ).\n"); else sm->m_vDipole = CxDVector3(dipole[0], dipole[1], dipole[2]); } else { sm->m_vDipole = ((CSingleMolecule *)g_oaSingleMolecules[m->m_laSingleMolIndex[0]])->m_vDipole; } } else if(m->m_iDipoleMode == 3) { if(j == 0) { char comment[BUF_SIZE]; strncpy(comment, m_pComment, BUF_SIZE); comment[BUF_SIZE-1] = '\0'; const char delim[] = "\t "; char *tok = strtok(comment, delim); int num = 0; bool ok[3] = { false, false, false }; while(tok != NULL) { double f; if(sscanf(tok, "%lf", &f) == 1) { if(num == m->m_iDipoleCommentIndex[0]) { sm->m_vDipole[0] = f; ok[0] = true; } if(num == m->m_iDipoleCommentIndex[1]) { sm->m_vDipole[1] = f; ok[1] = true; } if(num == m->m_iDipoleCommentIndex[2]) { sm->m_vDipole[2] = f; ok[2] = true; } num++; } tok = strtok(NULL, delim); } if(!(ok[0] && ok[1] && ok[2])) { eprintf("Could not read from comment line. Setting dipole moment to ( 0.0 | 0.0 | 0.0 ).\n"); sm->m_vDipole = CxDVector3(0.0, 0.0, 0.0); } } else { sm->m_vDipole = ((CSingleMolecule *)g_oaSingleMolecules[m->m_laSingleMolIndex[0]])->m_vDipole; } } else if(m->m_iDipoleMode == 4) { int k; for(k = 0; k < m->m_baAtomIndex.GetSize(); k++) { if(m->m_baAtomIndex[k] == g_iVirtAtomType) continue; int l; for(l = 0; l < m->m_waAtomCount[k]; l++) { sm->m_vDipole += ((CxDoubleArray *)m->m_oaCharges[k])->GetAt(l) * (m_vaCoords[((CxIntArray *)sm->m_oaAtomOffset[k])->GetAt(l)] - ref); } } sm->m_vDipole *= DIP_EPM2DEBYE; } else if(m->m_iDipoleMode == 5) { int k; for(k = 0; k < m->m_baAtomIndex.GetSize(); k++) { if(m->m_baAtomIndex[k] == g_iVirtAtomType) continue; int l; for(l = 0; l < m->m_waAtomCount[k]; l++) { sm->m_vDipole += m_faCharge[((CxIntArray *)sm->m_oaAtomOffset[k])->GetAt(l)] * (m_vaCoords[((CxIntArray *)sm->m_oaAtomOffset[k])->GetAt(l)] - ref); } } sm->m_vDipole *= DIP_EPM2DEBYE; } else if(m->m_iDipoleMode == 6) { int k; for(k = 0; k < m->m_baAtomIndex.GetSize(); k++) { if(m->m_baAtomIndex[k] == g_iVirtAtomType) continue; int l; for(l = 0; l < m->m_waAtomCount[k]; l++) { sm->m_vDipole += m_faCharge[((CxIntArray *)sm->m_oaAtomOffset[k])->GetAt(l)] * (m_vaCoords[((CxIntArray *)sm->m_oaAtomOffset[k])->GetAt(l)] - ref); } } sm->m_vDipole *= DIP_EPM2DEBYE; } else if(m->m_iDipoleMode == 7) { int k; for(k = 0; k < m->m_baAtomIndex.GetSize(); k++) { if(m->m_baAtomIndex[k] == g_iVirtAtomType) continue; int l; for(l = 0; l < m->m_waAtomCount[k]; l++) { int ti = ((CxIntArray *)sm->m_oaAtomOffset[k])->GetAt(l); sm->m_fCharge += m_faCharge[ti]; sm->m_vDipole += m_dipoleMoments[ti] + m_faCharge[ti] * (m_vaCoords[ti] - ref); if (g_bVoroIntegrateQuadrupoleMoment) { for (z=0;z<3;z++) for (z2=0;z2<3;z2++) sm->m_mQuadrupole(z,z2) += (m_maQuadTensor[ti](z,z2) * 1.0E6) // e*nm^2 to e*pm^2 + (m_dipoleMoments[ti][z] * (m_vaCoords[ti][z2] - ref[z2]) ) + (m_dipoleMoments[ti][z2] * (m_vaCoords[ti][z] - ref[z] ) ) + (m_faCharge[ti] * (m_vaCoords[ti][z] - ref[z]) * (m_vaCoords[ti][z2] - ref[z2]) ); /* sm->m_mQuadrupole(z,z2) += (m_maQuadTensor[ti](z,z2) * 1.0E6) // e*nm^2 to e*pm^2 - (m_dipoleMoments[ti][z] * (m_vaCoords[ti][z2] - ref[z2]) ) - (m_dipoleMoments[ti][z2] * (m_vaCoords[ti][z] - ref[z] ) ) + (m_faCharge[ti] * (m_vaCoords[ti][z] - ref[z]) * (m_vaCoords[ti][z2] - ref[z2]) ); */ } // mprintf(GREEN, "Dip: %12.6f %12.6f %12.6f\n", m_dipoleMoments[((CxIntArray *)sm->m_oaAtomOffset[k])->GetAt(l)][0], m_dipoleMoments[((CxIntArray *)sm->m_oaAtomOffset[k])->GetAt(l)][1], m_dipoleMoments[((CxIntArray *)sm->m_oaAtomOffset[k])->GetAt(l)][2]); // mprintf(GREEN, "Crd: %12.6f %12.6f %12.6f\n", m_vaCoords[((CxIntArray *)sm->m_oaAtomOffset[k])->GetAt(l)][0], m_vaCoords[((CxIntArray *)sm->m_oaAtomOffset[k])->GetAt(l)][1], m_vaCoords[((CxIntArray *)sm->m_oaAtomOffset[k])->GetAt(l)][2]); // mprintf(GREEN, "Chg: %12.6f %12.6f %12.6f %12.6f\n", m_faCharge[((CxIntArray *)sm->m_oaAtomOffset[k])->GetAt(l)], m_faCharge[((CxIntArray *)sm->m_oaAtomOffset[k])->GetAt(l)] * (m_vaCoords[((CxIntArray *)sm->m_oaAtomOffset[k])->GetAt(l)] - ref)[0], m_faCharge[((CxIntArray *)sm->m_oaAtomOffset[k])->GetAt(l)] * (m_vaCoords[((CxIntArray *)sm->m_oaAtomOffset[k])->GetAt(l)] - ref)[1], m_faCharge[((CxIntArray *)sm->m_oaAtomOffset[k])->GetAt(l)] * (m_vaCoords[((CxIntArray *)sm->m_oaAtomOffset[k])->GetAt(l)] - ref)[2]); // mprintf(GREEN, "%.20g %.20g %.20g %.20g\n", m_faCharge[((CxIntArray *)sm->m_oaAtomOffset[k])->GetAt(l)], ref[0], ref[1], ref[2]); // mprintf(GREEN, "%g %g %g\n", m_vaCoords[((CxIntArray *)sm->m_oaAtomOffset[k])->GetAt(l)][0], m_vaCoords[((CxIntArray *)sm->m_oaAtomOffset[k])->GetAt(l)][1], m_vaCoords[((CxIntArray *)sm->m_oaAtomOffset[k])->GetAt(l)][2]); } } sm->m_vDipole *= DIP_EPM2DEBYE; if (g_bVoroIntegrateQuadrupoleMoment) { sm->m_mQuadrupole *= DIP_EPM2DEBYE; // e*pm^2 to Debye*pm if (!g_bQuadrupoleKeepTrace) { tf = 0.5 * (sm->m_mQuadrupole(0,0) + sm->m_mQuadrupole(1,1) + sm->m_mQuadrupole(2,2) ); sm->m_mQuadrupole *= 1.5; sm->m_mQuadrupole(0,0) -= tf; sm->m_mQuadrupole(1,1) -= tf; sm->m_mQuadrupole(2,2) -= tf; } } // mprintf(GREEN, "%g %g %g\n", sm->m_vDipole[0], sm->m_vDipole[1], sm->m_vDipole[2]); } else if(m->m_iDipoleMode == 8) { eprintf("CTimeStep::CalcDipoles(): Dipole mode 8 not implemented.\n"); abort(); } else { eprintf("CTimeStep::CalcDipoles(): Internal error.\n"); abort(); } // Last virtual atom of each molecule is defined as tip of molecular diople vector starting in #2 int k; for(k = 0; k < m->m_baAtomIndex.GetSize(); k++) if(m->m_baAtomIndex[k] == g_iVirtAtomType) break; m_vaCoords[((CxIntArray*)sm->m_oaAtomOffset[k])->GetAt(m->m_laVirtualAtoms.GetSize()-1)] = 100.0*sm->m_vDipole + m_vaCoords[((CxIntArray*)sm->m_oaAtomOffset[k])->GetAt(1)]; } } //----------------- OLD ----------------------- // BTIN; // int z, z2, z3, z4; // CMolecule *m; // CSingleMolecule *sm; // CAtom *a; // CxDVector3 dc; // // // mprintf("\n*** CalcDipoles ***"); // // for (z=0;zm_laSingleMolIndex.GetSize();z2++) // { // if (g_bVerbose) // mprintf("\nCalcDipoles %s (%d):\n",m->m_sName,z2+1); // // sm = (CSingleMolecule*)g_oaSingleMolecules[m->m_laSingleMolIndex[z2]]; // // sm->m_vDipole = CxDVector3(0,0,0); // // if ((!g_bWannier) && (!m->m_bChargesAssigned)) // continue; // // if (g_bDipoleRefFixed) // dc = CxDVector3(0,0,0); // else dc = m_vaCoords[((CxIntArray*)sm->m_oaAtomOffset[m->m_iDipoleCenterType])->GetAt(m->m_iDipoleCenterIndex)]; // // if (g_bVerbose) // mprintf(" Ref. point is ( %f | %f | %f )\n",dc[0],dc[1],dc[2]); // // for (z3=0;z3m_baAtomIndex.GetSize();z3++) // { // if (m->m_baAtomIndex[z3] == g_iVirtAtomType) // continue; // // if (g_bWannier) // if (m->m_baAtomIndex[z3] == g_iWannierAtomType) // continue; // // a = (CAtom*)g_oaAtoms[m->m_baAtomIndex[z3]]; // for (z4=0;z4m_waAtomCount[z3];z4++) // { // // mprintf(" %s%d %.2f x ",a->m_sName,z4+1,a->m_fCharge); // // (m_vaCoords[sm->m_iAtomOffset[z3][z4]]-m_vaCoords[sm->m_iAtomOffset[m->Elements-1][0]]).Dump(); // // mprintf("\n"); // // mprintf(" %s%d %.2f (%d)\n",a->m_sName,z4+1,a->m_fCharge,((CxIntArray*)sm->m_oaAtomOffset[z3])->GetAt(z4)); // // if (g_bWannier) // { // sm->m_vDipole += a->m_fCharge * (m_vaCoords[((CxIntArray*)sm->m_oaAtomOffset[z3])->GetAt(z4)] - dc); // // if (g_bVerbose) // mprintf(" %.2f: ( %f | %f | %f )\n",a->m_fCharge,m_vaCoords[((CxIntArray*)sm->m_oaAtomOffset[z3])->GetAt(z4)][0],m_vaCoords[((CxIntArray*)sm->m_oaAtomOffset[z3])->GetAt(z4)][1],m_vaCoords[((CxIntArray*)sm->m_oaAtomOffset[z3])->GetAt(z4)][2]); // } else // { // if (g_bReadChargesFrom4thXYZ) // { // // mprintf("Moep. z3=%d, z4=%d, c=%f.\n",z3,z4,m_faCharge[((CxIntArray*)sm->m_oaAtomOffset[z3])->GetAt(z4)]); // sm->m_vDipole += m_faCharge[((CxIntArray*)sm->m_oaAtomOffset[z3])->GetAt(z4)] * (m_vaCoords[((CxIntArray*)sm->m_oaAtomOffset[z3])->GetAt(z4)] - dc); // if (g_bVerbose) // mprintf(" %.2f: ( %f | %f | %f )\n",m_faCharge[((CxIntArray*)sm->m_oaAtomOffset[z3])->GetAt(z4)],m_vaCoords[((CxIntArray*)sm->m_oaAtomOffset[z3])->GetAt(z4)][0],m_vaCoords[((CxIntArray*)sm->m_oaAtomOffset[z3])->GetAt(z4)][1],m_vaCoords[((CxIntArray*)sm->m_oaAtomOffset[z3])->GetAt(z4)][2]); // } else // { // sm->m_vDipole += ((CxFloatArray*)m->m_oaCharges[z3])->GetAt(z4) * (m_vaCoords[((CxIntArray*)sm->m_oaAtomOffset[z3])->GetAt(z4)] - dc); // if (g_bVerbose) // mprintf(" %.2f: ( %f | %f | %f )\n",((CxFloatArray*)m->m_oaCharges[z3])->GetAt(z4),m_vaCoords[((CxIntArray*)sm->m_oaAtomOffset[z3])->GetAt(z4)][0],m_vaCoords[((CxIntArray*)sm->m_oaAtomOffset[z3])->GetAt(z4)][1],m_vaCoords[((CxIntArray*)sm->m_oaAtomOffset[z3])->GetAt(z4)][2]); // } // } // } // } // for (z3=0;z3m_laWannier.GetSize();z3++) // { // // mprintf(" - %.2f x ",g_fWannierCharge); // // (m_vaCoords[sm->m_waWannier[z3]] - m_vaCoords[sm->m_iAtomOffset[m->Elements-1][0]]).Dump(); // // mprintf("\n"); // sm->m_vDipole -= g_fWannierCharge * (m_vaCoords[sm->m_laWannier[z3]] - dc); // // if (g_bVerbose) // mprintf(" %.2f: ( %f | %f | %f )\n",-g_fWannierCharge,m_vaCoords[sm->m_laWannier[z3]][0],m_vaCoords[sm->m_laWannier[z3]][1],m_vaCoords[sm->m_laWannier[z3]][2]); // } // // mprintf(" = "); // // sm->m_vDipole.Dump(); // // mprintf("\n"); // sm->m_vDipole *= 0.048008f; // Conversion e*pm --> Debye // // if (g_bVerbose) // mprintf(" Result: %f.\n",sm->m_vDipole.GetLength()); // // // mprintf("Molecule %s - Dipole %.3f\n",m->Name,sm->m_vDipole.GetLength()); // } // } // BTOUT; } void CTimeStep::CalcPolarizabilities() { int i; int j; if (g_iPolarizabilityMode == 1) { eprintf("CTimeStep::CalcPolarizabilities(): This is not implemented yet.\n"); abort(); } else if (g_iPolarizabilityMode == 2) { char fieldChar[4] = "xyz"; for (i = 0; i < 3; i++) { if (g_iPolarizabilityConf[i] > 0) { CTimeStep tempTs1; CxDVec3Array tempDipole1; tempDipole1.SetMaxSize(g_oaSingleMolecules.GetSize()); if (!tempTs1.ReadXYZ(g_fPolarizabilityFile[2 * i], false, &tempTs1.m_vaCoords)) { eprintf("CTimeStep::CalcPolarizabilities(): Error while reading Wannier centers with field along positive %c axis.\n", fieldChar[i]); abort(); } if (g_bDoubleBox) tempTs1.DoubleBox(); if (!g_bSaveCoordsUnchanged) { tempTs1.UniteMolecules(false); if (g_bRemoveCOM) tempTs1.CenterCOM(); } tempTs1.CalcCenters(); tempTs1.ScanWannier(false); for (j = 0; j < g_oaMolecules.GetSize(); j++) { CMolecule *m = (CMolecule *)g_oaMolecules[j]; int k; for (k = 0; k < m->m_laSingleMolIndex.GetSize(); k++) { CSingleMolecule *sm = (CSingleMolecule *)g_oaSingleMolecules[m->m_laSingleMolIndex[k]]; CxDVector3 ref(0.0, 0.0, 0.0); if (!g_bDipoleRefFixed) { ref = tempTs1.m_vaCoords[((CxIntArray *)sm->m_oaAtomOffset[m->m_iDipoleCenterType])->GetAt(m->m_iDipoleCenterIndex)]; } else { CxDVector3 v = tempTs1.m_vaCoords[((CxIntArray *)sm->m_oaAtomOffset[m->m_baAtomIndex.GetSize()-1])->GetAt(1)]; int shift[3] = { 0, 0, 0 }; if (g_bPeriodicX) { while (v[0] < -g_fBoxX / 2.0) { v[0] += g_fBoxX; shift[0]--; } while (v[0] > g_fBoxX / 2.0) { v[0] -= g_fBoxX; shift[0]++; } } if (g_bPeriodicY) { while (v[1] < -g_fBoxY / 2.0) { v[1] += g_fBoxY; shift[1]--; } while (v[1] > g_fBoxY / 2.0) { v[1] -= g_fBoxY; shift[1]++; } } if (g_bPeriodicZ) { while (v[2] < -g_fBoxZ / 2.0) { v[2] += g_fBoxZ; shift[2]--; } while (v[2] > g_fBoxZ / 2.0) { v[2] -= g_fBoxZ; shift[2]++; } } ref[0] = g_fBoxX * shift[0]; ref[1] = g_fBoxY * shift[1]; ref[2] = g_fBoxZ * shift[2]; } CxDVector3 dip(0.0, 0.0, 0.0); int l; for (l = 0; l < m->m_baAtomIndex.GetSize(); l++) { if (m->m_baAtomIndex[l] == g_iVirtAtomType) continue; if (m->m_baAtomIndex[l] == g_iWannierAtomType) continue; CAtom *a = (CAtom *)g_oaAtoms[m->m_baAtomIndex[l]]; int n; for (n = 0; n < m->m_waAtomCount[l]; n++) { dip += a->m_fCharge * (tempTs1.m_vaCoords[((CxIntArray *)sm->m_oaAtomOffset[l])->GetAt(n)] - ref); } } for (l = 0; l < sm->m_laWannier.GetSize(); l++) { dip -= g_fWannierCharge * (tempTs1.m_vaCoords[sm->m_laWannier[l]] - ref); } dip *= DIP_EPM2DEBYE; tempDipole1.Add(dip); } } if (g_iPolarizabilityConf[i] > 1) { CTimeStep tempTs2; if (!tempTs2.ReadXYZ(g_fPolarizabilityFile[2 * i + 1], false, &tempTs2.m_vaCoords)) { eprintf("CTimeStep::CalcPolarizabilities(): Error while reading Wannier centers with field along negative %c axis.\n", fieldChar[i]); abort(); } if (g_bDoubleBox) tempTs2.DoubleBox(); if (!g_bSaveCoordsUnchanged) { tempTs2.UniteMolecules(false); if (g_bRemoveCOM) tempTs2.CenterCOM(); } tempTs2.CalcCenters(); tempTs2.ScanWannier(false); int z = 0; for (j = 0; j < g_oaMolecules.GetSize(); j++) { CMolecule *m = (CMolecule *)g_oaMolecules[j]; int k; for (k = 0; k < m->m_laSingleMolIndex.GetSize(); k++) { CSingleMolecule *sm = (CSingleMolecule *)g_oaSingleMolecules[m->m_laSingleMolIndex[k]]; CxDVector3 ref(0.0, 0.0, 0.0); if (!g_bDipoleRefFixed) { ref = tempTs2.m_vaCoords[((CxIntArray *)sm->m_oaAtomOffset[m->m_iDipoleCenterType])->GetAt(m->m_iDipoleCenterIndex)]; } else { CxDVector3 v = tempTs2.m_vaCoords[((CxIntArray *)sm->m_oaAtomOffset[m->m_baAtomIndex.GetSize()-1])->GetAt(1)]; int shift[3] = { 0, 0, 0 }; if (g_bPeriodicX) { while (v[0] < -g_fBoxX / 2.0) { v[0] += g_fBoxX; shift[0]--; } while (v[0] > g_fBoxX / 2.0) { v[0] -= g_fBoxX; shift[0]++; } } if (g_bPeriodicY) { while (v[1] < -g_fBoxY / 2.0) { v[1] += g_fBoxY; shift[1]--; } while (v[1] > g_fBoxY / 2.0) { v[1] -= g_fBoxY; shift[1]++; } } if (g_bPeriodicZ) { while (v[2] < -g_fBoxZ / 2.0) { v[2] += g_fBoxZ; shift[2]--; } while (v[2] > g_fBoxZ / 2.0) { v[2] -= g_fBoxZ; shift[2]++; } } ref[0] = g_fBoxX * shift[0]; ref[1] = g_fBoxY * shift[1]; ref[2] = g_fBoxZ * shift[2]; } CxDVector3 dip(0.0, 0.0, 0.0); int l; for (l = 0; l < m->m_baAtomIndex.GetSize(); l++) { if (m->m_baAtomIndex[l] == g_iVirtAtomType) continue; if (m->m_baAtomIndex[l] == g_iWannierAtomType) continue; CAtom *a = (CAtom *)g_oaAtoms[m->m_baAtomIndex[l]]; int n; for (n = 0; n < m->m_waAtomCount[l]; n++) { dip += a->m_fCharge * (tempTs2.m_vaCoords[((CxIntArray *)sm->m_oaAtomOffset[l])->GetAt(n)] - ref); } } for (l = 0; l < sm->m_laWannier.GetSize(); l++) { dip -= g_fWannierCharge * (tempTs2.m_vaCoords[sm->m_laWannier[l]] - ref); } dip *= DIP_EPM2DEBYE; dip = tempDipole1[z] - dip; for (l = 0; l < 3; l++) { sm->m_polarizability[3 * l + i] = -1.0 * 0.5 * dip[l] / g_fPolarizabilityFieldStrength * 0.393430; // Multiply by -1.0f to work with CP2K field definition } z++; } } } else { int z = 0; for (j = 0; j < g_oaMolecules.GetSize(); j++) { CMolecule *m = (CMolecule *)g_oaMolecules[j]; int k; for (k = 0; k < m->m_laSingleMolIndex.GetSize(); k++) { CSingleMolecule *sm = (CSingleMolecule *)g_oaSingleMolecules[m->m_laSingleMolIndex[k]]; int l; CxDVector3 dip = tempDipole1[z] - sm->m_vDipole; for (l = 0; l < 3; l++) { sm->m_polarizability[3 * l + i] = -1.0 * dip[l] / g_fPolarizabilityFieldStrength * 0.393430; } z++; } } } } else { for (j = 0; j < g_oaMolecules.GetSize(); j++) { CMolecule *m = (CMolecule *)g_oaMolecules[j]; int k; for (k = 0; k < m->m_laSingleMolIndex.GetSize(); k++) { CSingleMolecule *sm = (CSingleMolecule *)g_oaSingleMolecules[m->m_laSingleMolIndex[k]]; int l; for (l = 0; l < 3; l++) { sm->m_polarizability[3 * l + i] = 0.0; } } } } } } else if (g_iPolarizabilityMode == 3) { char fieldChar[4] = "xyz"; for (i = 0; i < 3; i++) { if (g_iPolarizabilityConf[i] > 0) { CTimeStep tempTs1; CxDVec3Array tempDipole1; tempDipole1.SetMaxSize(g_oaSingleMolecules.GetSize()); if (!tempTs1.ReadCube(g_fPolarizabilityFile[2 * i], false)) { eprintf("CTimeStep::CalcPolarizabilities(): Error while reading electron density with field along positive %c axis.\n", fieldChar[i]); abort(); } if (g_bDoubleBox) tempTs1.DoubleBox(); if (!g_bSaveCoordsUnchanged) { tempTs1.UniteMolecules(false); if (g_bRemoveCOM) tempTs1.CenterCOM(); } tempTs1.CalcCenters(); g_pTetraPak->ProcessStep(&tempTs1, false); for (j = 0; j < g_oaMolecules.GetSize(); j++) { CMolecule *m = (CMolecule *)g_oaMolecules[j]; int k; for (k = 0; k < m->m_laSingleMolIndex.GetSize(); k++) { CSingleMolecule *sm = (CSingleMolecule *)g_oaSingleMolecules[m->m_laSingleMolIndex[k]]; CxDVector3 ref(0.0, 0.0, 0.0); if (!g_bDipoleRefFixed) { ref = tempTs1.m_vaCoords[((CxIntArray *)sm->m_oaAtomOffset[m->m_iDipoleCenterType])->GetAt(m->m_iDipoleCenterIndex)]; } else { CxDVector3 v = tempTs1.m_vaCoords[((CxIntArray *)sm->m_oaAtomOffset[m->m_baAtomIndex.GetSize()-1])->GetAt(1)]; int shift[3] = { 0, 0, 0 }; if (g_bPeriodicX) { while (v[0] < -g_fBoxX / 2.0) { v[0] += g_fBoxX; shift[0]--; } while (v[0] > g_fBoxX / 2.0) { v[0] -= g_fBoxX; shift[0]++; } } if (g_bPeriodicY) { while (v[1] < -g_fBoxY / 2.0) { v[1] += g_fBoxY; shift[1]--; } while (v[1] > g_fBoxY / 2.0) { v[1] -= g_fBoxY; shift[1]++; } } if (g_bPeriodicZ) { while (v[2] < -g_fBoxZ / 2.0) { v[2] += g_fBoxZ; shift[2]--; } while (v[2] > g_fBoxZ / 2.0) { v[2] -= g_fBoxZ; shift[2]++; } } ref[0] = g_fBoxX * shift[0]; ref[1] = g_fBoxY * shift[1]; ref[2] = g_fBoxZ * shift[2]; } CxDVector3 dip(0.0, 0.0, 0.0); int l; for (l = 0; l < m->m_baAtomIndex.GetSize(); l++) { if (m->m_baAtomIndex[l] == g_iVirtAtomType) continue; int n; for (n = 0; n < m->m_waAtomCount[l]; n++) { dip += tempTs1.m_dipoleMoments[((CxIntArray *)sm->m_oaAtomOffset[l])->GetAt(n)] + tempTs1.m_faCharge[((CxIntArray *)sm->m_oaAtomOffset[l])->GetAt(n)] * (tempTs1.m_vaCoords[((CxIntArray *)sm->m_oaAtomOffset[l])->GetAt(n)] - ref); } } dip *= DIP_EPM2DEBYE; tempDipole1.Add(dip); } } if (g_iPolarizabilityConf[i] > 1) { CTimeStep tempTs2; if (!tempTs2.ReadCube(g_fPolarizabilityFile[2 * i + 1], false)) { eprintf("CTimeStep::CalcPolarizabilities(): Error while reading electron density with field along negative %c axis.\n", fieldChar[i]); abort(); } if (g_bDoubleBox) tempTs2.DoubleBox(); if (!g_bSaveCoordsUnchanged) { tempTs2.UniteMolecules(false); if (g_bRemoveCOM) tempTs2.CenterCOM(); } tempTs2.CalcCenters(); g_pTetraPak->ProcessStep(&tempTs2, false); int z = 0; for (j = 0; j < g_oaMolecules.GetSize(); j++) { CMolecule *m = (CMolecule *)g_oaMolecules[j]; int k; for (k = 0; k < m->m_laSingleMolIndex.GetSize(); k++) { CSingleMolecule *sm = (CSingleMolecule *)g_oaSingleMolecules[m->m_laSingleMolIndex[k]]; CxDVector3 ref(0.0, 0.0, 0.0); if (!g_bDipoleRefFixed) { ref = tempTs2.m_vaCoords[((CxIntArray *)sm->m_oaAtomOffset[m->m_iDipoleCenterType])->GetAt(m->m_iDipoleCenterIndex)]; } else { CxDVector3 v = tempTs2.m_vaCoords[((CxIntArray *)sm->m_oaAtomOffset[m->m_baAtomIndex.GetSize()-1])->GetAt(1)]; int shift[3] = { 0, 0, 0 }; if (g_bPeriodicX) { while (v[0] < -g_fBoxX / 2.0) { v[0] += g_fBoxX; shift[0]--; } while (v[0] > g_fBoxX / 2.0) { v[0] -= g_fBoxX; shift[0]++; } } if (g_bPeriodicY) { while (v[1] < -g_fBoxY / 2.0) { v[1] += g_fBoxY; shift[1]--; } while (v[1] > g_fBoxY / 2.0) { v[1] -= g_fBoxY; shift[1]++; } } if (g_bPeriodicZ) { while (v[2] < -g_fBoxZ / 2.0) { v[2] += g_fBoxZ; shift[2]--; } while (v[2] > g_fBoxZ / 2.0) { v[2] -= g_fBoxZ; shift[2]++; } } ref[0] = g_fBoxX * shift[0]; ref[1] = g_fBoxY * shift[1]; ref[2] = g_fBoxZ * shift[2]; } CxDVector3 dip(0.0, 0.0, 0.0); int l; for (l = 0; l < m->m_baAtomIndex.GetSize(); l++) { if (m->m_baAtomIndex[l] == g_iVirtAtomType) continue; int n; for (n = 0; n < m->m_waAtomCount[l]; n++) { dip += tempTs2.m_dipoleMoments[((CxIntArray *)sm->m_oaAtomOffset[l])->GetAt(n)] + tempTs2.m_faCharge[((CxIntArray *)sm->m_oaAtomOffset[l])->GetAt(n)] * (tempTs2.m_vaCoords[((CxIntArray *)sm->m_oaAtomOffset[l])->GetAt(n)] - ref); } } dip *= DIP_EPM2DEBYE; dip = tempDipole1[z] - dip; for (l = 0; l < 3; l++) { sm->m_polarizability[3 * l + i] = -1.0 * 0.5 * dip[l] / g_fPolarizabilityFieldStrength * 0.393430; // Multiply by -1.0f to work with CP2K field definition } z++; } } } else { int z = 0; for (j = 0; j < g_oaMolecules.GetSize(); j++) { CMolecule *m = (CMolecule *)g_oaMolecules[j]; int k; for (k = 0; k < m->m_laSingleMolIndex.GetSize(); k++) { CSingleMolecule *sm = (CSingleMolecule *)g_oaSingleMolecules[m->m_laSingleMolIndex[k]]; int l; CxDVector3 dip = tempDipole1[z] - sm->m_vDipole; for (l = 0; l < 3; l++) { sm->m_polarizability[3 * l + i] = -1.0 * dip[l] / g_fPolarizabilityFieldStrength * 0.393430; } z++; } } } } else { for (j = 0; j < g_oaMolecules.GetSize(); j++) { CMolecule *m = (CMolecule *)g_oaMolecules[j]; int k; for (k = 0; k < m->m_laSingleMolIndex.GetSize(); k++) { CSingleMolecule *sm = (CSingleMolecule *)g_oaSingleMolecules[m->m_laSingleMolIndex[k]]; int l; for (l = 0; l < 3; l++) { sm->m_polarizability[3 * l + i] = 0.0; } } } } } } else if (g_iPolarizabilityMode == 4) { char fieldChar[4] = "xyz"; for (i = 0; i < 3; i++) { if (g_iPolarizabilityConf[i] > 0) { CxDVec3Array tempDipole1; tempDipole1.SetMaxSize(g_oaSingleMolecules.GetSize()); for (j = 0; j < g_oaSingleMolecules.GetSize(); j++) { CxDVector3 dip; int k; for (k = 0; k < 3; k++) { double val; if (fread(&val, sizeof(double), 1, g_fPolarizabilityFile[2 * i]) < 1) { eprintf("CTimeStep::CalcPolarizabilities(): Error while reading dipole restart file with field along positive %c axis.\n", fieldChar[i]); abort(); } dip[k] = val; } tempDipole1.Add(dip); } if (g_iPolarizabilityConf[i] > 1) { for (j = 0; j < g_oaSingleMolecules.GetSize(); j++) { CSingleMolecule *sm = (CSingleMolecule *)g_oaSingleMolecules[j]; CxDVector3 dip; int k; for (k = 0; k < 3; k++) { double val; if (fread(&val, sizeof(double), 1, g_fPolarizabilityFile[2 * i + 1]) < 1) { eprintf("CTimeStep::CalcPolarizabilities(): Error while reading dipole restart file with field along negative %c axis.\n", fieldChar[i]); abort(); } dip[k] = val; } dip = tempDipole1[j] - dip; for (k = 0; k < 3; k++) { sm->m_polarizability[3 * k + i] = -1.0 * 0.5 * dip[k] / g_fPolarizabilityFieldStrength * 0.393430; // Multiply by -1.0f to work with CP2K field definition } } } else { for (j = 0; j < g_oaSingleMolecules.GetSize(); j++) { CSingleMolecule *sm = (CSingleMolecule *)g_oaSingleMolecules[j]; CxDVector3 dip; dip = tempDipole1[j] - sm->m_vDipole; int k; for (k = 0; k < 3; k++) { sm->m_polarizability[3 * k + i] = -1.0 * dip[k] / g_fPolarizabilityFieldStrength * 0.393430; } } } } else { for (j = 0; j < g_oaMolecules.GetSize(); j++) { CMolecule *m = (CMolecule *)g_oaMolecules[j]; int k; for (k = 0; k < m->m_laSingleMolIndex.GetSize(); k++) { CSingleMolecule *sm = (CSingleMolecule *)g_oaSingleMolecules[m->m_laSingleMolIndex[k]]; int l; for (l = 0; l < 3; l++) { sm->m_polarizability[3 * l + i] = 0.0; } } } } } } else { eprintf("CTimeStep::CalcPolarizabilities(): Internal error.\n"); abort(); } } void CTimeStep::DoubleBox() { int px, py, pz, z; char *p; CxDVector3 vec; if (m_vaCoords.GetSize() < g_iGesAtomCount) m_vaCoords.SetSize(g_iGesAtomCount); if (m_paLabels.GetSize() != 0) m_paLabels.SetSize(g_iGesAtomCount); /* if (g_bBoxNonOrtho) { for (z=0;z= 1.0/g_iDoubleBoxX) vec[0] -= 1.0/g_iDoubleBoxX; while (vec[0] < 0) vec[0] += 1.0/g_iDoubleBoxX; while (vec[1] >= 1.0/g_iDoubleBoxY) vec[1] -= 1.0/g_iDoubleBoxY; while (vec[1] < 0) vec[1] += 1.0/g_iDoubleBoxY; while (vec[2] >= 1.0/g_iDoubleBoxZ) vec[2] -= 1.0/g_iDoubleBoxZ; while (vec[2] < 0) vec[2] += 1.0/g_iDoubleBoxZ; m_vaCoords[z] = g_mBoxFromOrtho * vec; } }*/ for (pz=0;pz= 1.0/g_iDoubleBoxX) vec[0] -= 1.0/g_iDoubleBoxX; while (vec[0] < 0) vec[0] += 1.0/g_iDoubleBoxX; while (vec[1] >= 1.0/g_iDoubleBoxY) vec[1] -= 1.0/g_iDoubleBoxY; while (vec[1] < 0) vec[1] += 1.0/g_iDoubleBoxY; while (vec[2] >= 1.0/g_iDoubleBoxZ) vec[2] -= 1.0/g_iDoubleBoxZ; while (vec[2] < 0) vec[2] += 1.0/g_iDoubleBoxZ;*/ // mprintf(" gefaltet ( %f | %f | %f )\n",vec[0],vec[1],vec[2]); vec += CxDVector3((double)px/g_iDoubleBoxX,(double)py/g_iDoubleBoxY,(double)pz/g_iDoubleBoxZ); // mprintf(" geshiftet ( %f | %f | %f )\n",vec[0],vec[1],vec[2]); m_vaCoords[(pz*g_iDoubleBoxX*g_iDoubleBoxY+py*g_iDoubleBoxX+px)*g_iGesAtomCount/g_iDoubleBoxFactor+z] = g_mBoxFromOrtho * vec; // mprintf(" Ergebnis ( %f | %f | %f )\n",m_vaCoords[(pz*g_iDoubleBoxX*g_iDoubleBoxY+py*g_iDoubleBoxX+px)*g_iGesAtomCount/g_iDoubleBoxFactor+z][0],m_vaCoords[(pz*g_iDoubleBoxX*g_iDoubleBoxY+py*g_iDoubleBoxX+px)*g_iGesAtomCount/g_iDoubleBoxFactor+z][1],m_vaCoords[(pz*g_iDoubleBoxX*g_iDoubleBoxY+py*g_iDoubleBoxX+px)*g_iGesAtomCount/g_iDoubleBoxFactor+z][2]); } else { m_vaCoords[(pz*g_iDoubleBoxX*g_iDoubleBoxY+py*g_iDoubleBoxX+px)*g_iGesAtomCount/g_iDoubleBoxFactor+z] = m_vaCoords[z] + CxDVector3(px*g_fBoxX/g_iDoubleBoxX,py*g_fBoxY/g_iDoubleBoxY,pz*g_fBoxZ/g_iDoubleBoxZ); } if (m_paLabels.GetSize() != 0) { try { p = new char[strlen((char*)m_paLabels[z])+1]; } catch(...) { p = NULL; } if (p == NULL) NewException((double)(strlen((char*)m_paLabels[z])+1)*sizeof(char),__FILE__,__LINE__,__PRETTY_FUNCTION__); strcpy(p,(char*)m_paLabels[z]); m_paLabels[(pz*g_iDoubleBoxX*g_iDoubleBoxY+py*g_iDoubleBoxX+px)*g_iGesAtomCount/g_iDoubleBoxFactor+z] = p; } } } } } m_iGesAtomCount = g_iGesAtomCount; } void CTimeStep::DoubleBoxVelocity() { int px, py, pz, z; if (m_vaVelocities.GetSize() < g_iGesAtomCount) m_vaVelocities.SetSize(g_iGesAtomCount); for (pz=0;pz 0) buf[strlen(buf)-1] = 0; // mprintf("Read1: \"%s\".\n",buf); goto _firsttry; _again: eprintf("\nTrajectory file seems to be damaged. Searching for next time step..."); _firsttry: if (feof(a)) { // mprintf("CTimeStep::ReadTimestep(): Unexpected End of File (1).\n"); BTOUT; return false; } if (strchr(buf,'.') != NULL) { if (j < 10) eprintf("x"); // mprintf("x: %d - \"%s\"\n",j,buf); j++; goto _readagain; } if (m_pComment == NULL) { try { m_pComment = new char[256]; } catch(...) { m_pComment = NULL; } if (m_pComment == NULL) NewException((double)256*sizeof(char),__FILE__,__LINE__,__PRETTY_FUNCTION__); } m_pComment[0] = 0; (void)fgets_bin(m_pComment,255,a); if (feof(a)) return false; if (strlen(m_pComment) >= 254) eprintf("\nCTimeStep::ReadXYZ(): Warning: Comment line longer than 254 characters. "); m_iGesAtomCount = atoi(buf); if (atoi(buf) < 0) { eprintf("\nCTimeStep::ReadXYZ(): Error: Atom count = %d < 0. \"%s\"",atoi(buf),buf); m_iGesAtomCount = 0; return false; } if (m_iGesAtomCount == 0) { eprintf("\nCTimeStep::ReadXYZ(): Error: Atom count = 0. \"%s\"",buf); goto _readagain; } if (needinfo) { for (z=0;zGetSize() < (long)m_iGesAtomCount) v->SetSize(m_iGesAtomCount); if (g_bKeepOriginalCoords) { if (m_vaCoords_Original.GetSize() < (long)m_iGesAtomCount) m_vaCoords_Original.SetSize(m_iGesAtomCount); } // if (strlen(m_pComment) > 0) // m_pComment[strlen(m_pComment)-1] = 0; p = m_pComment; while (*p != 0) { if ((*p == 10) || (*p == 13)) *p = 0; p++; } // mprintf("# Comment: \"%s\".\n",m_pComment); if (g_bNPT && g_bXYZComment6Numbers) ExtractXYZCellGeometry(m_pComment); if (g_bNPT && g_bXYZComment3Numbers) ExtractXYZCellGeometry3(m_pComment); if (needinfo) { z = 0; p = m_pComment; while (*p != 0) { // mprintf("# (A) \"%s\".\n",p); // while (strchr(" \t,",*p) != NULL) // p++; while (strchr("0123456789+-.Ee",*p) == NULL) p++; q = p; // mprintf("# (B) \"%s\".\n",p); // while (strchr("0123456789+-.Ee",*q) != NULL) while ((strchr("0123456789+-.Ee",*q) != NULL) && (*q != 0)) q++; if (*(q-1) == 0) q--; // mprintf("# (C) \"%s\".\n",q); if (q > p) { memcpy(buf,p,q-p); buf[q-p] = 0; if (atof(buf) != 0) { // mprintf("\n## \"%s\" --> %f.",buf,atof(buf)); z++; } } if (*q == 0) break; p = q; // mprintf("\nNow p=%d (%c).",*p,*p); } if (z == 6) g_bXYZComment6Numbers = true; else if (z == 3) { if (strspn(m_pComment,"0123456789+-.Ee \r\n\t") == strlen(m_pComment)) g_bXYZComment3Numbers = true; } } // mprintf("Comment: \"%s\".\n",m_pComment); // m_iSizeBytes += strlen(m_pComment); if (g_bReadChargesFrom4thXYZ) m_faCharge.SetSize(m_iGesAtomCount); for (z=0;z<(long)m_iGesAtomCount;z++) // den ersten Zeitschritt einlesen { buf[0] = 0; (void)fgets_bin(buf,256,a); if (feof(a)) { eprintf("\nCTimeStep::ReadXYZ(): Unexpected end of file (2). \"%s\"\n",buf); BTOUT; return false; } // m_iSizeBytes += strlen(buf); buf[strlen(buf)-1] = 0; // mprintf(" %d: \"%s\".\n",z,buf); strcpy(obuf,buf); // i = 0; p = &buf[0]; while (strchr(separators,*p) != NULL) p++; q = p+1; while ((strchr(separators,*q) == NULL) && (*q != 0)) q++; if (*q == 0) { eprintf("\nCTimeStep::ReadXYZ(): %d: Incomplete line (1): \"%s\"\n",z+1,obuf); BTOUT; return false; } *q = 0; if (needinfo) { // if (strlen(p) > 7) // { // eprintf("\nCTimeStep::ReadXYZ(): \"%s\" - Maximum length of atom labels is 7 chars; truncating.\n",p); // p[7] = 0; // } try { r = new char[strlen(p)+1]; } catch(...) { r = NULL; } if (r == NULL) NewException((double)(strlen(p)+1)*sizeof(char),__FILE__,__LINE__,__PRETTY_FUNCTION__); strcpy(r,p); m_paLabels[z] = r; } q++; while (strchr(separators,*q) != NULL) q++; p = q; while ((strchr(separators,*p) == NULL) && (*p != 0)) p++; if (*p == 0) { eprintf("\nCTimeStep::ReadXYZ(): %d: Incomplete line (2): \"%s\"",z+1,obuf); goto _again; } *p = 0; #ifdef FAST_ATOF (*v)[z][0] = fast_atof(q) * 100.0; #else (*v)[z][0] = atof(q) * 100.0; #endif // if (g_bKeepOriginalCoords) // m_vaCoords_Original[z][0] = (*v)[z][0]; q = p+1; while (strchr(separators,*q) != NULL) q++; p = q; while ((strchr(separators,*p) == NULL) && (*p != 0)) p++; if (*p == 0) { eprintf("\nCTimeStep::ReadXYZ(): %d: Incomplete line (3) \"%s\"",z+1,obuf); goto _again; } *p = 0; #ifdef FAST_ATOF (*v)[z][1] = fast_atof(q) * 100.0; #else (*v)[z][1] = atof(q) * 100.0; #endif // if (g_bKeepOriginalCoords) // m_vaCoords_Original[z][1] = (*v)[z][1]; q = p+1; while (strchr(separators,*q) != NULL) q++; p = q; while ((strchr(separators,*p) == NULL) && (*p != 0)) p++; if (g_bReadChargesFrom4thXYZ) { if (*p == 0) { eprintf("\nCTimeStep::ReadXYZ(): %d: Incomplete line (4) \"%s\"",z+1,obuf); goto _again; } *p = 0; } else { if (*p != 0) { *p = 0; if (needinfo && (z==0)) p++; } } #ifdef FAST_ATOF (*v)[z][2] = fast_atof(q) * 100.0; #else (*v)[z][2] = atof(q) * 100.0; #endif // mprintf("\n Have %f %f %f.",(*v)[z][0],(*v)[z][1],(*v)[z][2]); // if (g_bKeepOriginalCoords) // m_vaCoords_Original[z][2] = (*v)[z][2]; if (g_bKeepOriginalCoords) m_vaCoords_Original[z] = (*v)[z]; if (g_bReadChargesFrom4thXYZ) { q = p+1; while (strchr(separators,*q) != NULL) q++; p = q; while ((strchr(separators,*p) == NULL) && (*p != 0)) p++; if (*p != 0) *p = 0; #ifdef FAST_ATOF m_faCharge[z] = fast_atof(q); #else m_faCharge[z] = atof(q); #endif } else if (needinfo && (z==0)) { if (*p == 0) goto _no4; q = p+1; if (*q == 0) goto _no4; while (strchr(separators,*q) != NULL) q++; p = q; while ((strchr(separators,*p) == NULL) && (*p != 0)) p++; if ((p-q) > 2) { for (;q= '0') && (*q <= '9')) || (*q == '-') || (*q == '.'))) goto _no4; g_bXYZ4thCol = true; _no4:; } } /* q = strchr(buf,'.'); if (q != NULL) { i++; q = strchr(q+1,'.'); } if (q != NULL) { i++; q = strchr(q+1,'.'); } if (q==NULL) { eprintf("\nCTimeStep::ReadXYZ(): Error - only %d/3 dots. %d, \"%s\"",i,z+1,buf); goto _again; } q = buf; while (*q == ' ') q++; p = strchr(q,' '); if (p == NULL) { eprintf("\nCTimeStep::ReadXYZ(): Error 1. %d, \"%s\"",z+1,buf); goto _again; } while (isdigit(*(p-1)) && (p > buf)) p--; if (p == buf) { eprintf("\nCTimeStep::ReadXYZ(): No Atom label found. %d, \"%s\"",z+1,buf); goto _again; } *p = 0; if (needinfo) { r = new char[strlen(q)+1]; strcpy(r,q); m_paLabels[z] = r; } q = p+1; while (*q == ' ') q++; p = strchr(q,' '); if (p == NULL) { eprintf("\nCTimeStep::ReadXYZ(): Error 3. %d, \"%s\"",z+1,q); goto _again; } *p = 0; (*v)[z][0] = (double)atof(q) * 100.0f; q = p+1; while (*q == ' ') q++; p = strchr(q,' '); if (p == NULL) { eprintf("\nCTimeStep::ReadXYZ(): Error 4. %d, \"%s\"",z+1,q); goto _again; } *p = 0; (*v)[z][1] = (double)atof(q) * 100.0f; q = p+1; while (*q == ' ') q++; p = strchr(q,' '); if (p != NULL) *p = 0; (*v)[z][2] = (double)atof(q) * 100.0f;*/ } // mprintf("*** Read Ende.\n"); BTOUT; return true; } bool CTimeStep::ReadCube(FILE *a, bool needinfo) { int rx, ry, rz, ac, z, z2, k, i; char buf[256], *p, *r; const char *q; double fx, fy, fz, tf; (void)fgets(buf,256,a); (void)fgets(buf,256,a); if (feof(a)) { eprintf("\nCTimeStep::ReadCube(): Error: End of file reached while reading cube file.\n"); return false; } (void)fgets(buf,256,a); if (feof(a)) { eprintf("CTimeStep::ReadCube(): Error: Unexpected end of file reached while reading cube file.\n"); return false; } p = buf; while (*p == ' ') p++; while (*p != ' ') p++; *p = 0; ac = atoi(buf); m_iGesAtomCount = ac; if (ac <= 0) { eprintf("CTimeStep::ReadCube(): Error: Encountered atom count of %d while reading cube file.\n",ac); return false; } (void)fgets(buf,256,a); if (feof(a)) { eprintf("CTimeStep::ReadCube(): Error: Unexpected end of file reached while reading cube file.\n"); return false; } p = buf; while (*p == ' ') p++; while (*p != ' ') p++; *p = 0; rx = atoi(buf); g_iCubeRes[0] = rx; //static bool first = true; // replaced by m_bFirst for (k = 0; k < 3; k++) { p++; while (*p == ' ') p++; q = p; while ((*p != ' ') && (*p != 0)) p++; *p = 0; tf = atof(q); if (g_bFlipCellVectorX && (k == 0) && (tf != 0)) tf *= -1.0; if (g_bFlipCellVectorY && (k == 1) && (tf != 0)) tf *= -1.0; if (g_bFlipCellVectorZ && (k == 2) && (tf != 0)) tf *= -1.0; if (m_bFirst) { g_fCubeXVector[k] = tf; } else { g_fCubeXVector[k] = g_mCubeCell(0, k) / (rx * g_iCubeXStride - g_iCubeXMismatch) / LEN_AU2PM; if (fabs(g_fCubeXVector[k] - tf / g_iCubeXStride) > 0.1) { eprintf("CTimeStep::ReadCube(): Error: Grid point distance in the cube file changed from %.3f pm to %.3f pm!\n", g_fCubeXVector[k] * LEN_AU2PM, tf / g_iCubeXStride * LEN_AU2PM); return false; } } } g_fCubeXStep = g_fCubeXVector[0]; // p++; // while (*p == ' ') // p++; // q = p; // while ((*p != ' ') && (*p != 0)) // p++; // // if (*p == 0) // // { // // eprintf("Incomplete line while reading grid data from cube file.\n"); // // return false; // // } // *p = 0; // // if (first) { // g_fCubeXStep = atof(q); // } else { // g_fCubeXStep = g_fBoxX / (rx * g_iCubeXStride - g_iCubeXMismatch) / LEN_AU2PM; // if (fabs(g_fCubeXStep - atof(q) / g_iCubeXStride) > 0.1f) { // eprintf("Grid point distance in the cube file changed from %.3f pm to %.3f pm!\n", g_fCubeXStep * LEN_AU2PM, atof(q) / g_iCubeXStride * LEN_AU2PM); // return false; // } // } (void)fgets(buf,256,a); if (feof(a)) { eprintf("CTimeStep::ReadCube(): Error: Unexpected end of file reached while reading cube file.\n"); return false; } p = buf; while (*p == ' ') p++; while (*p != ' ') p++; *p = 0; ry = atoi(buf); g_iCubeRes[1] = ry; for (k = 0; k < 3; k++) { p++; while (*p == ' ') p++; q = p; while ((*p != ' ') && (*p != 0)) p++; *p = 0; tf = atof(q); if (g_bFlipCellVectorX && (k == 0) && (tf != 0)) tf *= -1.0; if (g_bFlipCellVectorY && (k == 1) && (tf != 0)) tf *= -1.0; if (g_bFlipCellVectorZ && (k == 2) && (tf != 0)) tf *= -1.0; if (m_bFirst) { g_fCubeYVector[k] = tf; } else { g_fCubeYVector[k] = g_mCubeCell(1, k) / (ry * g_iCubeYStride - g_iCubeYMismatch) / LEN_AU2PM; if (fabs(g_fCubeYVector[k] - tf / g_iCubeYStride) > 0.1) { eprintf("CTimeStep::ReadCube(): Error: Grid point distance in the cube file changed from %.3f pm to %.3f pm!\n", g_fCubeYVector[k] * LEN_AU2PM, tf / g_iCubeYStride * LEN_AU2PM); return false; } } } g_fCubeYStep = g_fCubeYVector[1]; // for (z = 0; z < 2; z++) { // p++; // while (*p == ' ') // p++; // q = p; // while ((*p != ' ') && (*p != 0)) // p++; // // if (*p == 0) // // { // // eprintf("Incomplete line while reading grid data from cube file.\n"); // // return false; // // } // *p = 0; // } // // if (first) { // g_fCubeYStep = atof(q); // } else { // g_fCubeYStep = g_fBoxY / (ry * g_iCubeYStride - g_iCubeYMismatch) / LEN_AU2PM; // if (fabs(g_fCubeYStep - atof(q) / g_iCubeYStride) > 0.1f) { // eprintf("Grid point distance in the cube file changed from %.3f pm to %.3f pm!\n", g_fCubeYStep * LEN_AU2PM, atof(q) / g_iCubeYStride * LEN_AU2PM); // return false; // } // } (void)fgets(buf,256,a); if (feof(a)) { eprintf("CTimeStep::ReadCube(): Error: Unexpected end of file reached while reading cube file.\n"); return false; } p = buf; while (*p == ' ') p++; while (*p != ' ') p++; *p = 0; rz = atoi(buf); g_iCubeRes[2] = rz; for (k = 0; k < 3; k++) { p++; while (*p == ' ') p++; q = p; while ((*p != ' ') && (*p != 0)) p++; *p = 0; tf = atof(q); if (g_bFlipCellVectorX && (k == 0) && (tf != 0)) tf *= -1.0; if (g_bFlipCellVectorY && (k == 1) && (tf != 0)) tf *= -1.0; if (g_bFlipCellVectorZ && (k == 2) && (tf != 0)) tf *= -1.0; if (m_bFirst) { g_fCubeZVector[k] = tf; } else { g_fCubeZVector[k] = g_mCubeCell(2, k) / (rz * g_iCubeZStride - g_iCubeZMismatch) / LEN_AU2PM; if (fabs(g_fCubeZVector[k] - tf / g_iCubeZStride) > 0.1) { eprintf("CTimeStep::ReadCube(): Error: Grid point distance in the cube file changed from %.3f pm to %.3f pm!\n", g_fCubeZVector[k] * LEN_AU2PM, tf / g_iCubeZStride * LEN_AU2PM); return false; } } } g_fCubeZStep = g_fCubeZVector[2]; m_bFirst = false; // for (z = 0; z < 3; z++) { // p++; // while (*p == ' ') // p++; // q = p; // while ((*p != ' ') && (*p != 0)) // p++; // // if (*p == 0) // // { // // eprintf("Incomplete line while reading grid data from cube file.\n"); // // return false; // // } // *p = 0; // } // // if (first) { // g_fCubeZStep = atof(q); // first = false; // } else { // g_fCubeZStep = g_fBoxZ / (rz * g_iCubeZStride - g_iCubeZMismatch) / LEN_AU2PM; // if (fabs(g_fCubeZStep - atof(q) / g_iCubeZStride) > 0.1f) { // eprintf("Grid point distance in the cube file changed from %.3f pm to %.3f pm!\n", g_fCubeZStep * LEN_AU2PM, atof(q) / g_iCubeZStride * LEN_AU2PM); // return false; // } // } if (needinfo) { for (z=0;zm_iOrd == i) { q = ((CElement*)g_oaElements[z2])->m_sLabel; goto _found; } } eprintf("CTimeStep::ReadCube(): Error: Encountered unknown atom type %d while reading cube file.\n",i); return false; _found: try { r = new char[strlen(q)+1]; } catch(...) { r = NULL; } if (r == NULL) NewException((double)(strlen(q)+1)*sizeof(char),__FILE__,__LINE__,__PRETTY_FUNCTION__); strcpy(r,q); m_paLabels[z] = r; } p++; // Column is always zero while (*p == ' ') p++; q = p; while ((*p != ' ') && (*p != 0)) p++; if (*p == 0) { eprintf("CTimeStep::ReadCube(): Error: Incomplete line while reading coordinates from cube file (A).\n"); return false; } *p = 0; p++; while (*p == ' ') p++; q = p; while ((*p != ' ') && (*p != 0)) p++; if (*p == 0) { eprintf("CTimeStep::ReadCube(): Error: Incomplete line while reading coordinates from cube file (B).\n"); return false; } *p = 0; fx = atof(q); p++; while (*p == ' ') p++; q = p; while ((*p != ' ') && (*p != 0)) p++; if (*p == 0) { eprintf("CTimeStep::ReadCube(): Error: Incomplete line while reading coordinates from cube file (C).\n"); return false; } fy = atof(q); p++; while (*p == ' ') p++; q = p; while ((*p != ' ') && (*p != 0)) p++; *p = 0; fz = atof(q); // m_vaCoords.Add(CxDVector3(fx*0.529177249f*100.0f,fy*0.529177249f*100.0f,fz*0.529177249f*100.0f)); m_vaCoords.Add(CxDVector3(fx*LEN_AU2PM,fy*LEN_AU2PM,fz*LEN_AU2PM)); } if (feof(a)) { eprintf("CTimeStep::ReadCube(): Error: Unexpected end of file reached while reading cube file.\n"); return false; } if (m_pVolumetricData == NULL) { m_pVolumetricData = new C3DF(); } if (m_pVolumetricDataTimeDev == NULL && g_bCubeTimeDev) { m_pVolumetricDataTimeDev = new C3DF(); } if (m_pCurrentDensity == NULL && g_bCubeTimeDev) { m_pCurrentDensity = new CxDoubleArray(); } if (g_bVerbose) { mprintf("\n"); mprintf(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n"); mprintf(">>> CTimeStep::ReadCube() >>>\n"); mprintf(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n"); mprintf(" Resolution %d x %d x %d\n",g_iCubeRes[0],g_iCubeRes[1],g_iCubeRes[2]); mprintf(" Stride %d x %d x %d\n",g_iCubeXStride,g_iCubeYStride,g_iCubeZStride); mprintf(" Mismatch %d x %d x %d\n",g_iCubeXMismatch,g_iCubeYMismatch,g_iCubeZMismatch); mprintf(" Resulting Resolution %d x %d x %d\n",rx * g_iCubeXStride - g_iCubeXMismatch,ry * g_iCubeYStride - g_iCubeYMismatch,rz * g_iCubeZStride - g_iCubeZMismatch); mprintf(" Cell Vector A ( %12.6f | %12.6f | %12.6f ) pm\n", g_fCubeXVector[0] * LEN_AU2PM * (rx * g_iCubeXStride - g_iCubeXMismatch), g_fCubeXVector[1] * LEN_AU2PM * (rx * g_iCubeXStride - g_iCubeXMismatch), g_fCubeXVector[2] * LEN_AU2PM * (rx * g_iCubeXStride - g_iCubeXMismatch)); mprintf(" Cell Vector B ( %12.6f | %12.6f | %12.6f ) pm\n", g_fCubeYVector[0] * LEN_AU2PM * (ry * g_iCubeYStride - g_iCubeYMismatch), g_fCubeYVector[1] * LEN_AU2PM * (ry * g_iCubeYStride - g_iCubeYMismatch), g_fCubeYVector[2] * LEN_AU2PM * (ry * g_iCubeYStride - g_iCubeYMismatch)); mprintf(" Cell Vector C ( %12.6f | %12.6f | %12.6f ) pm\n", g_fCubeZVector[0] * LEN_AU2PM * (rz * g_iCubeZStride - g_iCubeZMismatch), g_fCubeZVector[1] * LEN_AU2PM * (rz * g_iCubeZStride - g_iCubeZMismatch), g_fCubeZVector[2] * LEN_AU2PM * (rz * g_iCubeZStride - g_iCubeZMismatch)); mprintf(" First 10 atoms:\n"); for (z=0;z<((ac<10)?ac:10);z++) mprintf(" %3d %12.6f %12.6f %12.6f\n",atomNumbers[z],m_vaCoords[z][0],m_vaCoords[z][1],m_vaCoords[z][2]); } static bool second = false; if (m_pVolumetricData->m_pBin == NULL) { m_pVolumetricData->m_iRes[0] = rx * g_iCubeXStride - g_iCubeXMismatch; m_pVolumetricData->m_iRes[1] = ry * g_iCubeYStride - g_iCubeYMismatch; m_pVolumetricData->m_iRes[2] = rz * g_iCubeZStride - g_iCubeZMismatch; m_pVolumetricData->m_fMinVal[0] = 0.0; m_pVolumetricData->m_fMinVal[1] = 0.0; m_pVolumetricData->m_fMinVal[2] = 0.0; g_mCubeCell(0, 0) = g_fCubeXVector[0] * LEN_AU2PM * (rx * g_iCubeXStride - g_iCubeXMismatch); g_mCubeCell(0, 1) = g_fCubeXVector[1] * LEN_AU2PM * (rx * g_iCubeXStride - g_iCubeXMismatch); g_mCubeCell(0, 2) = g_fCubeXVector[2] * LEN_AU2PM * (rx * g_iCubeXStride - g_iCubeXMismatch); g_mCubeCell(1, 0) = g_fCubeYVector[0] * LEN_AU2PM * (ry * g_iCubeYStride - g_iCubeYMismatch); g_mCubeCell(1, 1) = g_fCubeYVector[1] * LEN_AU2PM * (ry * g_iCubeYStride - g_iCubeYMismatch); g_mCubeCell(1, 2) = g_fCubeYVector[2] * LEN_AU2PM * (ry * g_iCubeYStride - g_iCubeYMismatch); g_mCubeCell(2, 0) = g_fCubeZVector[0] * LEN_AU2PM * (rz * g_iCubeZStride - g_iCubeZMismatch); g_mCubeCell(2, 1) = g_fCubeZVector[1] * LEN_AU2PM * (rz * g_iCubeZStride - g_iCubeZMismatch); g_mCubeCell(2, 2) = g_fCubeZVector[2] * LEN_AU2PM * (rz * g_iCubeZStride - g_iCubeZMismatch); m_pVolumetricData->m_fMaxVal[0] = sqrt(g_mCubeCell(0, 0) * g_mCubeCell(0, 0) + g_mCubeCell(0, 1) * g_mCubeCell(0, 1) + g_mCubeCell(0, 2) * g_mCubeCell(0, 2)); m_pVolumetricData->m_fMaxVal[1] = sqrt(g_mCubeCell(1, 0) * g_mCubeCell(1, 0) + g_mCubeCell(1, 1) * g_mCubeCell(1, 1) + g_mCubeCell(1, 2) * g_mCubeCell(1, 2)); m_pVolumetricData->m_fMaxVal[2] = sqrt(g_mCubeCell(2, 0) * g_mCubeCell(2, 0) + g_mCubeCell(2, 1) * g_mCubeCell(2, 1) + g_mCubeCell(2, 2) * g_mCubeCell(2, 2)); // // m_pVolumetricData->m_fMaxVal[0] = g_fBoxX; // m_pVolumetricData->m_fMaxVal[0] = g_fCubeXStep * LEN_AU2PM * (rx * g_iCubeXStride - g_iCubeXMismatch); // // m_pVolumetricData->m_fMaxVal[1] = g_fBoxY; // m_pVolumetricData->m_fMaxVal[1] = g_fCubeYStep * LEN_AU2PM * (ry * g_iCubeYStride - g_iCubeYMismatch); // // m_pVolumetricData->m_fMaxVal[2] = g_fBoxZ; // m_pVolumetricData->m_fMaxVal[2] = g_fCubeZStep * LEN_AU2PM * (rz * g_iCubeZStride - g_iCubeZMismatch); m_pVolumetricData->Create(); if (m_pVolumetricDataTimeDev != NULL) { // m_pVolumetricDataTimeDev->m_iRes[0] = rx * g_iCubeXStride - g_iCubeXMismatch; // m_pVolumetricDataTimeDev->m_iRes[1] = ry * g_iCubeYStride - g_iCubeYMismatch; // m_pVolumetricDataTimeDev->m_iRes[2] = rz * g_iCubeZStride - g_iCubeZMismatch; // m_pVolumetricDataTimeDev->m_fMinVal[0] = 0; // m_pVolumetricDataTimeDev->m_fMaxVal[0] = g_fCubeXStep * LEN_AU2PM * (rx * g_iCubeXStride - g_iCubeXMismatch); // m_pVolumetricDataTimeDev->m_fMinVal[1] = 0; // m_pVolumetricDataTimeDev->m_fMaxVal[1] = g_fCubeYStep * LEN_AU2PM * (ry * g_iCubeYStride - g_iCubeYMismatch); // m_pVolumetricDataTimeDev->m_fMinVal[2] = 0; // m_pVolumetricDataTimeDev->m_fMaxVal[2] = g_fCubeZStep * LEN_AU2PM * (rz * g_iCubeZStride - g_iCubeZMismatch); m_pVolumetricDataTimeDev->m_iRes[0] = m_pVolumetricData->m_iRes[0]; m_pVolumetricDataTimeDev->m_iRes[1] = m_pVolumetricData->m_iRes[1]; m_pVolumetricDataTimeDev->m_iRes[2] = m_pVolumetricData->m_iRes[2]; m_pVolumetricDataTimeDev->m_fMinVal[0] = m_pVolumetricData->m_fMinVal[0]; m_pVolumetricDataTimeDev->m_fMinVal[1] = m_pVolumetricData->m_fMinVal[1]; m_pVolumetricDataTimeDev->m_fMinVal[2] = m_pVolumetricData->m_fMinVal[2]; m_pVolumetricDataTimeDev->m_fMaxVal[0] = m_pVolumetricData->m_fMaxVal[0]; m_pVolumetricDataTimeDev->m_fMaxVal[1] = m_pVolumetricData->m_fMaxVal[1]; m_pVolumetricDataTimeDev->m_fMaxVal[2] = m_pVolumetricData->m_fMaxVal[2]; m_pVolumetricDataTimeDev->Create(); } if (m_pCurrentDensity != NULL) { m_pCurrentDensity->SetSize(3 * m_pVolumetricDataTimeDev->m_iRes[0] * m_pVolumetricDataTimeDev->m_iRes[1] * m_pVolumetricDataTimeDev->m_iRes[2]); } second = true; } else { if ((rx * g_iCubeXStride - g_iCubeXMismatch != m_pVolumetricData->m_iRes[0]) || (ry * g_iCubeYStride - g_iCubeYMismatch!= m_pVolumetricData->m_iRes[1]) || (rz * g_iCubeZStride - g_iCubeZMismatch != m_pVolumetricData->m_iRes[2])) { if (second) { second = false; m_pVolumetricData->m_iRes[0] = rx * g_iCubeXStride - g_iCubeXMismatch; m_pVolumetricData->m_iRes[1] = ry * g_iCubeYStride - g_iCubeYMismatch; m_pVolumetricData->m_iRes[2] = rz * g_iCubeZStride - g_iCubeZMismatch; m_pVolumetricData->m_fMinVal[0] = 0.0; m_pVolumetricData->m_fMinVal[1] = 0.0; m_pVolumetricData->m_fMinVal[2] = 0.0; g_mCubeCell(0, 0) = g_fCubeXVector[0] * LEN_AU2PM * (rx * g_iCubeXStride - g_iCubeXMismatch); g_mCubeCell(0, 1) = g_fCubeXVector[1] * LEN_AU2PM * (rx * g_iCubeXStride - g_iCubeXMismatch); g_mCubeCell(0, 2) = g_fCubeXVector[2] * LEN_AU2PM * (rx * g_iCubeXStride - g_iCubeXMismatch); g_mCubeCell(1, 0) = g_fCubeYVector[0] * LEN_AU2PM * (ry * g_iCubeYStride - g_iCubeYMismatch); g_mCubeCell(1, 1) = g_fCubeYVector[1] * LEN_AU2PM * (ry * g_iCubeYStride - g_iCubeYMismatch); g_mCubeCell(1, 2) = g_fCubeYVector[2] * LEN_AU2PM * (ry * g_iCubeYStride - g_iCubeYMismatch); g_mCubeCell(2, 0) = g_fCubeZVector[0] * LEN_AU2PM * (rz * g_iCubeZStride - g_iCubeZMismatch); g_mCubeCell(2, 1) = g_fCubeZVector[1] * LEN_AU2PM * (rz * g_iCubeZStride - g_iCubeZMismatch); g_mCubeCell(2, 2) = g_fCubeZVector[2] * LEN_AU2PM * (rz * g_iCubeZStride - g_iCubeZMismatch); m_pVolumetricData->m_fMaxVal[0] = sqrt(g_mCubeCell(0, 0) * g_mCubeCell(0, 0) + g_mCubeCell(0, 1) * g_mCubeCell(0, 1) + g_mCubeCell(0, 2) * g_mCubeCell(0, 2)); m_pVolumetricData->m_fMaxVal[1] = sqrt(g_mCubeCell(1, 0) * g_mCubeCell(1, 0) + g_mCubeCell(1, 1) * g_mCubeCell(1, 1) + g_mCubeCell(1, 2) * g_mCubeCell(1, 2)); m_pVolumetricData->m_fMaxVal[2] = sqrt(g_mCubeCell(2, 0) * g_mCubeCell(2, 0) + g_mCubeCell(2, 1) * g_mCubeCell(2, 1) + g_mCubeCell(2, 2) * g_mCubeCell(2, 2)); // // m_pVolumetricData->m_fMaxVal[0] = g_fBoxX; // m_pVolumetricData->m_fMaxVal[0] = g_fCubeXStep * LEN_AU2PM * (rx * g_iCubeXStride - g_iCubeXMismatch); // // m_pVolumetricData->m_fMaxVal[1] = g_fBoxY; // m_pVolumetricData->m_fMaxVal[1] = g_fCubeYStep * LEN_AU2PM * (ry * g_iCubeYStride - g_iCubeYMismatch); // // m_pVolumetricData->m_fMaxVal[2] = g_fBoxZ; // m_pVolumetricData->m_fMaxVal[2] = g_fCubeZStep * LEN_AU2PM * (rz * g_iCubeZStride - g_iCubeZMismatch); m_pVolumetricData->Create(); if (m_pVolumetricDataTimeDev != NULL) { // m_pVolumetricDataTimeDev->m_iRes[0] = rx * g_iCubeXStride - g_iCubeXMismatch; // m_pVolumetricDataTimeDev->m_iRes[1] = ry * g_iCubeYStride - g_iCubeYMismatch; // m_pVolumetricDataTimeDev->m_iRes[2] = rz * g_iCubeZStride - g_iCubeZMismatch; // m_pVolumetricDataTimeDev->m_fMinVal[0] = 0; // m_pVolumetricDataTimeDev->m_fMaxVal[0] = g_fCubeXStep * LEN_AU2PM * (rx * g_iCubeXStride - g_iCubeXMismatch); // m_pVolumetricDataTimeDev->m_fMinVal[1] = 0; // m_pVolumetricDataTimeDev->m_fMaxVal[1] = g_fCubeYStep * LEN_AU2PM * (ry * g_iCubeYStride - g_iCubeYMismatch); // m_pVolumetricDataTimeDev->m_fMinVal[2] = 0; // m_pVolumetricDataTimeDev->m_fMaxVal[2] = g_fCubeZStep * LEN_AU2PM * (rz * g_iCubeZStride - g_iCubeZMismatch); m_pVolumetricDataTimeDev->m_iRes[0] = m_pVolumetricData->m_iRes[0]; m_pVolumetricDataTimeDev->m_iRes[1] = m_pVolumetricData->m_iRes[1]; m_pVolumetricDataTimeDev->m_iRes[2] = m_pVolumetricData->m_iRes[2]; m_pVolumetricDataTimeDev->m_fMinVal[0] = m_pVolumetricData->m_fMinVal[0]; m_pVolumetricDataTimeDev->m_fMinVal[1] = m_pVolumetricData->m_fMinVal[1]; m_pVolumetricDataTimeDev->m_fMinVal[2] = m_pVolumetricData->m_fMinVal[2]; m_pVolumetricDataTimeDev->m_fMaxVal[0] = m_pVolumetricData->m_fMaxVal[0]; m_pVolumetricDataTimeDev->m_fMaxVal[1] = m_pVolumetricData->m_fMaxVal[1]; m_pVolumetricDataTimeDev->m_fMaxVal[2] = m_pVolumetricData->m_fMaxVal[2]; m_pVolumetricDataTimeDev->Create(); } if (m_pCurrentDensity != NULL) { m_pCurrentDensity->SetSize(3 * m_pVolumetricDataTimeDev->m_iRes[0] * m_pVolumetricDataTimeDev->m_iRes[1] * m_pVolumetricDataTimeDev->m_iRes[2]); } } else { eprintf("\nCTimeStep::ReadCube(): Error: Cube file dimension mismatch (%d-%d, %d-%d, %d-%d).\n",rx * g_iCubeXStride - g_iCubeXMismatch,m_pVolumetricData->m_iRes[0],ry * g_iCubeYStride - g_iCubeYMismatch,m_pVolumetricData->m_iRes[1],rz * g_iCubeZStride - g_iCubeZMismatch,m_pVolumetricData->m_iRes[2]); return false; } } for (z=0;zm_iRes[0]*m_pVolumetricData->m_iRes[1]*m_pVolumetricData->m_iRes[2];z++) m_pVolumetricData->m_pBin[z] = 0; } m_pVolumetricData->ReadCubeData(a,false); if (g_bVerbose) { mprintf(" First 100 volumetric data elements:"); for (z=0;z<((m_pVolumetricData->m_iRes[0]*m_pVolumetricData->m_iRes[1]*m_pVolumetricData->m_iRes[2]<100)?m_pVolumetricData->m_iRes[0]*m_pVolumetricData->m_iRes[1]*m_pVolumetricData->m_iRes[2]:100);z++) { if ((z%10) == 0) mprintf("\n "); mprintf(" %10G",m_pVolumetricData->m_pBin[z]); } mprintf("\n"); mprintf("<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n\n"); } /* FILE *cubeFile = fopen("test.cube", "w"); if (cubeFile == NULL) { printf("Could not open output file!\n"); return 1; } fprintf(cubeFile, "\n\n"); fprintf(cubeFile, "%5lu %12.6f %12.6f %12.6f\n", m_iGesAtomCount, 0.0f, 0.0f, 0.0f); fprintf(cubeFile, "%5d %12.6f %12.6f %12.6f\n", m_pVolumetricData->m_iRes[0], g_fCubeXStep, 0.0f, 0.0f); fprintf(cubeFile, "%5d %12.6f %12.6f %12.6f\n", m_pVolumetricData->m_iRes[1], 0.0f, g_fCubeYStep, 0.0f); fprintf(cubeFile, "%5d %12.6f %12.6f %12.6f\n", m_pVolumetricData->m_iRes[2], 0.0f, 0.0f, g_fCubeZStep); for (int i = 0; i < (int)m_iGesAtomCount; i++) { fprintf(cubeFile, "%5d %12.6f %12.6f %12.6f %12.6f\n", 1, 0.0f, m_vaCoords[i][0] / 0.529177249f / 100.0f, m_vaCoords[i][1] / 0.529177249f / 100.0f, m_vaCoords[i][2] / 0.529177249f / 100.0f); } for (int i = 0; i < m_pVolumetricData->m_iRes[0]; i++) { for (int j = 0; j < m_pVolumetricData->m_iRes[1]; j++) { for (int k = 0; k < m_pVolumetricData->m_iRes[2] / 6; k++) { for (int l = 0; l < 6; l++) { fprintf(cubeFile, "%13.5E", m_pVolumetricData->m_pBin[i + j * m_pVolumetricData->m_iRes[0] + (k * 6 + l) * m_pVolumetricData->m_iRes[0] * m_pVolumetricData->m_iRes[1]]); } fprintf(cubeFile, "\n"); } if (m_pVolumetricData->m_iRes[2] % 6 != 0) { for (int l = 0; l < m_pVolumetricData->m_iRes[2] % 6; l++) { fprintf(cubeFile, "%13.5E", m_pVolumetricData->m_pBin[i + j * m_pVolumetricData->m_iRes[0] + ((m_pVolumetricData->m_iRes[2] / 6) * 6 + l) * m_pVolumetricData->m_iRes[0] * m_pVolumetricData->m_iRes[1]]); } fprintf(cubeFile, "\n"); } } } fclose(cubeFile);*/ return true; } bool CTimeStep::ReadBQBCubeStep(bool needinfo) { int rx, ry, rz, ac, z, z2; char *r, i; const char *q; double fx, fy, fz, tf; CBQBCubeFrame *cfr; CBQBAtomSet *afr; if (g_bVerbose) mprintf(">>> CTimeStep::ReadBQBCubeStep() >>>\n"); cfr = g_pBQBFile->GetEngine()->GetOutputCubeFrame(0); afr = g_pBQBFile->GetEngine()->GetOutputAtomFrame(0); ac = (int)afr->m_oaAtoms.size(); m_iGesAtomCount = ac; if (ac <= 0) { eprintf("CTimeStep::ReadBQBCubeStep(): Error: Encountered atom count of %d while reading cube file.\n",ac); return false; } rx = cfr->m_iRes[0]; g_iCubeRes[0] = rx; //static bool first = true; // replaced by m_bFirst int k; for (k = 0; k < 3; k++) { tf = cfr->m_fStrideA[k]; if (g_bFlipCellVectorX && (k == 0) && (tf != 0)) tf *= -1.0; if (g_bFlipCellVectorY && (k == 1) && (tf != 0)) tf *= -1.0; if (g_bFlipCellVectorZ && (k == 2) && (tf != 0)) tf *= -1.0; if (m_bFirst) g_fCubeXVector[k] = tf; else { g_fCubeXVector[k] = g_mCubeCell(0, k) / (rx * g_iCubeXStride - g_iCubeXMismatch) / LEN_AU2PM; if (fabs(g_fCubeXVector[k] - tf / g_iCubeXStride) > 0.1) { eprintf("CTimeStep::ReadBQBCubeStep(): Error: Grid point distance in the cube file changed from %.3f pm to %.3f pm!\n", g_fCubeXVector[k] * LEN_AU2PM, tf / g_iCubeXStride * LEN_AU2PM); return false; } } } g_fCubeXStep = g_fCubeXVector[0]; ry = cfr->m_iRes[1]; g_iCubeRes[1] = ry; for (k = 0; k < 3; k++) { tf = cfr->m_fStrideB[k]; if (g_bFlipCellVectorX && (k == 0) && (tf != 0)) tf *= -1.0; if (g_bFlipCellVectorY && (k == 1) && (tf != 0)) tf *= -1.0; if (g_bFlipCellVectorZ && (k == 2) && (tf != 0)) tf *= -1.0; if (m_bFirst) g_fCubeYVector[k] = tf; else { g_fCubeYVector[k] = g_mCubeCell(1, k) / (ry * g_iCubeYStride - g_iCubeYMismatch) / LEN_AU2PM; if (fabs(g_fCubeYVector[k] - tf / g_iCubeYStride) > 0.1) { eprintf("CTimeStep::ReadBQBCubeStep(): Error: Grid point distance in the cube file changed from %.3f pm to %.3f pm!\n", g_fCubeYVector[k] * LEN_AU2PM, tf / g_iCubeYStride * LEN_AU2PM); return false; } } } g_fCubeYStep = g_fCubeYVector[1]; rz = cfr->m_iRes[2]; g_iCubeRes[2] = rz; for (k = 0; k < 3; k++) { tf = cfr->m_fStrideC[k]; if (g_bFlipCellVectorX && (k == 0) && (tf != 0)) tf *= -1.0; if (g_bFlipCellVectorY && (k == 1) && (tf != 0)) tf *= -1.0; if (g_bFlipCellVectorZ && (k == 2) && (tf != 0)) tf *= -1.0; if (m_bFirst) g_fCubeZVector[k] = tf; else { g_fCubeZVector[k] = g_mCubeCell(2, k) / (rz * g_iCubeZStride - g_iCubeZMismatch) / LEN_AU2PM; if (fabs(g_fCubeZVector[k] - tf / g_iCubeZStride) > 0.1) { eprintf("CTimeStep::ReadBQBCubeStep(): Error: Grid point distance in the cube file changed from %.3f pm to %.3f pm!\n", g_fCubeZVector[k] * LEN_AU2PM, tf / g_iCubeZStride * LEN_AU2PM); return false; } } } g_fCubeZStep = g_fCubeZVector[2]; m_bFirst = false; if (needinfo) { for (z=0;zm_oaAtoms[z]->m_iOrd; if (needinfo) { i = (char)afr->m_oaAtoms[z]->m_iOrd; for (z2=0;z2m_iOrd == i) { q = ((CElement*)g_oaElements[z2])->m_sLabel; goto _found; } } eprintf("CTimeStep::ReadBQBCubeStep(): Error: Encountered unknown atom type %d while reading cube file.\n",i); return false; _found: try { r = new char[strlen(q)+1]; } catch(...) { r = NULL; } if (r == NULL) NewException((double)(strlen(q)+1)*sizeof(char),__FILE__,__LINE__,__PRETTY_FUNCTION__); strcpy(r,q); m_paLabels[z] = r; } fx = afr->m_oaAtoms[z]->m_fCoord[0]; fy = afr->m_oaAtoms[z]->m_fCoord[1]; fz = afr->m_oaAtoms[z]->m_fCoord[2]; // if (z < 10) // mprintf("@%d: %f | %f | %f --> %f | %f | %f\n",z,fx,fy,fz,fx*LEN_AU2PM,fy*LEN_AU2PM,fz*LEN_AU2PM); m_vaCoords.Add(CxDVector3(fx*LEN_AU2PM,fy*LEN_AU2PM,fz*LEN_AU2PM)); } if (m_pVolumetricData == NULL) m_pVolumetricData = new C3DF(); if (m_pVolumetricDataTimeDev == NULL && g_bCubeTimeDev) m_pVolumetricDataTimeDev = new C3DF(); if (m_pCurrentDensity == NULL && g_bCubeTimeDev) m_pCurrentDensity = new CxDoubleArray(); if (g_bVerbose) { mprintf("\n"); mprintf(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n"); mprintf(">>> CTimeStep::ReadBQBCubeStep() >>>\n"); mprintf(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n"); mprintf(" Resolution %d x %d x %d\n",g_iCubeRes[0],g_iCubeRes[1],g_iCubeRes[2]); mprintf(" Stride %d x %d x %d\n",g_iCubeXStride,g_iCubeYStride,g_iCubeZStride); mprintf(" Mismatch %d x %d x %d\n",g_iCubeXMismatch,g_iCubeYMismatch,g_iCubeZMismatch); mprintf(" Resulting Resolution %d x %d x %d\n",rx * g_iCubeXStride - g_iCubeXMismatch,ry * g_iCubeYStride - g_iCubeYMismatch,rz * g_iCubeZStride - g_iCubeZMismatch); mprintf(" Cell Vector A ( %12.6f | %12.6f | %12.6f ) pm\n", g_fCubeXVector[0] * LEN_AU2PM * (rx * g_iCubeXStride - g_iCubeXMismatch), g_fCubeXVector[1] * LEN_AU2PM * (rx * g_iCubeXStride - g_iCubeXMismatch), g_fCubeXVector[2] * LEN_AU2PM * (rx * g_iCubeXStride - g_iCubeXMismatch)); mprintf(" Cell Vector B ( %12.6f | %12.6f | %12.6f ) pm\n", g_fCubeYVector[0] * LEN_AU2PM * (ry * g_iCubeYStride - g_iCubeYMismatch), g_fCubeYVector[1] * LEN_AU2PM * (ry * g_iCubeYStride - g_iCubeYMismatch), g_fCubeYVector[2] * LEN_AU2PM * (ry * g_iCubeYStride - g_iCubeYMismatch)); mprintf(" Cell Vector C ( %12.6f | %12.6f | %12.6f ) pm\n", g_fCubeZVector[0] * LEN_AU2PM * (rz * g_iCubeZStride - g_iCubeZMismatch), g_fCubeZVector[1] * LEN_AU2PM * (rz * g_iCubeZStride - g_iCubeZMismatch), g_fCubeZVector[2] * LEN_AU2PM * (rz * g_iCubeZStride - g_iCubeZMismatch)); mprintf(" First 10 atoms:\n"); for (z=0;z<((ac<10)?ac:10);z++) mprintf(" %3d %12.6f %12.6f %12.6f\n",atomNumbers[z],m_vaCoords[z][0],m_vaCoords[z][1],m_vaCoords[z][2]); } static bool second = false; if (m_pVolumetricData->m_pBin == NULL) { m_pVolumetricData->m_iRes[0] = rx * g_iCubeXStride - g_iCubeXMismatch; m_pVolumetricData->m_iRes[1] = ry * g_iCubeYStride - g_iCubeYMismatch; m_pVolumetricData->m_iRes[2] = rz * g_iCubeZStride - g_iCubeZMismatch; m_pVolumetricData->m_fMinVal[0] = 0.0; m_pVolumetricData->m_fMinVal[1] = 0.0; m_pVolumetricData->m_fMinVal[2] = 0.0; g_mCubeCell(0, 0) = g_fCubeXVector[0] * LEN_AU2PM * (rx * g_iCubeXStride - g_iCubeXMismatch); g_mCubeCell(0, 1) = g_fCubeXVector[1] * LEN_AU2PM * (rx * g_iCubeXStride - g_iCubeXMismatch); g_mCubeCell(0, 2) = g_fCubeXVector[2] * LEN_AU2PM * (rx * g_iCubeXStride - g_iCubeXMismatch); g_mCubeCell(1, 0) = g_fCubeYVector[0] * LEN_AU2PM * (ry * g_iCubeYStride - g_iCubeYMismatch); g_mCubeCell(1, 1) = g_fCubeYVector[1] * LEN_AU2PM * (ry * g_iCubeYStride - g_iCubeYMismatch); g_mCubeCell(1, 2) = g_fCubeYVector[2] * LEN_AU2PM * (ry * g_iCubeYStride - g_iCubeYMismatch); g_mCubeCell(2, 0) = g_fCubeZVector[0] * LEN_AU2PM * (rz * g_iCubeZStride - g_iCubeZMismatch); g_mCubeCell(2, 1) = g_fCubeZVector[1] * LEN_AU2PM * (rz * g_iCubeZStride - g_iCubeZMismatch); g_mCubeCell(2, 2) = g_fCubeZVector[2] * LEN_AU2PM * (rz * g_iCubeZStride - g_iCubeZMismatch); m_pVolumetricData->m_fMaxVal[0] = sqrt(g_mCubeCell(0, 0) * g_mCubeCell(0, 0) + g_mCubeCell(0, 1) * g_mCubeCell(0, 1) + g_mCubeCell(0, 2) * g_mCubeCell(0, 2)); m_pVolumetricData->m_fMaxVal[1] = sqrt(g_mCubeCell(1, 0) * g_mCubeCell(1, 0) + g_mCubeCell(1, 1) * g_mCubeCell(1, 1) + g_mCubeCell(1, 2) * g_mCubeCell(1, 2)); m_pVolumetricData->m_fMaxVal[2] = sqrt(g_mCubeCell(2, 0) * g_mCubeCell(2, 0) + g_mCubeCell(2, 1) * g_mCubeCell(2, 1) + g_mCubeCell(2, 2) * g_mCubeCell(2, 2)); m_pVolumetricData->Create(); if (m_pVolumetricDataTimeDev != NULL) { m_pVolumetricDataTimeDev->m_iRes[0] = m_pVolumetricData->m_iRes[0]; m_pVolumetricDataTimeDev->m_iRes[1] = m_pVolumetricData->m_iRes[1]; m_pVolumetricDataTimeDev->m_iRes[2] = m_pVolumetricData->m_iRes[2]; m_pVolumetricDataTimeDev->m_fMinVal[0] = m_pVolumetricData->m_fMinVal[0]; m_pVolumetricDataTimeDev->m_fMinVal[1] = m_pVolumetricData->m_fMinVal[1]; m_pVolumetricDataTimeDev->m_fMinVal[2] = m_pVolumetricData->m_fMinVal[2]; m_pVolumetricDataTimeDev->m_fMaxVal[0] = m_pVolumetricData->m_fMaxVal[0]; m_pVolumetricDataTimeDev->m_fMaxVal[1] = m_pVolumetricData->m_fMaxVal[1]; m_pVolumetricDataTimeDev->m_fMaxVal[2] = m_pVolumetricData->m_fMaxVal[2]; m_pVolumetricDataTimeDev->Create(); } if (m_pCurrentDensity != NULL) { m_pCurrentDensity->SetSize(3 * m_pVolumetricDataTimeDev->m_iRes[0] * m_pVolumetricDataTimeDev->m_iRes[1] * m_pVolumetricDataTimeDev->m_iRes[2]); } second = true; } else { if ((rx * g_iCubeXStride - g_iCubeXMismatch != m_pVolumetricData->m_iRes[0]) || (ry * g_iCubeYStride - g_iCubeYMismatch!= m_pVolumetricData->m_iRes[1]) || (rz * g_iCubeZStride - g_iCubeZMismatch != m_pVolumetricData->m_iRes[2])) { if (second) { second = false; m_pVolumetricData->m_iRes[0] = rx * g_iCubeXStride - g_iCubeXMismatch; m_pVolumetricData->m_iRes[1] = ry * g_iCubeYStride - g_iCubeYMismatch; m_pVolumetricData->m_iRes[2] = rz * g_iCubeZStride - g_iCubeZMismatch; m_pVolumetricData->m_fMinVal[0] = 0.0; m_pVolumetricData->m_fMinVal[1] = 0.0; m_pVolumetricData->m_fMinVal[2] = 0.0; g_mCubeCell(0, 0) = g_fCubeXVector[0] * LEN_AU2PM * (rx * g_iCubeXStride - g_iCubeXMismatch); g_mCubeCell(0, 1) = g_fCubeXVector[1] * LEN_AU2PM * (rx * g_iCubeXStride - g_iCubeXMismatch); g_mCubeCell(0, 2) = g_fCubeXVector[2] * LEN_AU2PM * (rx * g_iCubeXStride - g_iCubeXMismatch); g_mCubeCell(1, 0) = g_fCubeYVector[0] * LEN_AU2PM * (ry * g_iCubeYStride - g_iCubeYMismatch); g_mCubeCell(1, 1) = g_fCubeYVector[1] * LEN_AU2PM * (ry * g_iCubeYStride - g_iCubeYMismatch); g_mCubeCell(1, 2) = g_fCubeYVector[2] * LEN_AU2PM * (ry * g_iCubeYStride - g_iCubeYMismatch); g_mCubeCell(2, 0) = g_fCubeZVector[0] * LEN_AU2PM * (rz * g_iCubeZStride - g_iCubeZMismatch); g_mCubeCell(2, 1) = g_fCubeZVector[1] * LEN_AU2PM * (rz * g_iCubeZStride - g_iCubeZMismatch); g_mCubeCell(2, 2) = g_fCubeZVector[2] * LEN_AU2PM * (rz * g_iCubeZStride - g_iCubeZMismatch); m_pVolumetricData->m_fMaxVal[0] = sqrt(g_mCubeCell(0, 0) * g_mCubeCell(0, 0) + g_mCubeCell(0, 1) * g_mCubeCell(0, 1) + g_mCubeCell(0, 2) * g_mCubeCell(0, 2)); m_pVolumetricData->m_fMaxVal[1] = sqrt(g_mCubeCell(1, 0) * g_mCubeCell(1, 0) + g_mCubeCell(1, 1) * g_mCubeCell(1, 1) + g_mCubeCell(1, 2) * g_mCubeCell(1, 2)); m_pVolumetricData->m_fMaxVal[2] = sqrt(g_mCubeCell(2, 0) * g_mCubeCell(2, 0) + g_mCubeCell(2, 1) * g_mCubeCell(2, 1) + g_mCubeCell(2, 2) * g_mCubeCell(2, 2)); m_pVolumetricData->Create(); if (m_pVolumetricDataTimeDev != NULL) { m_pVolumetricDataTimeDev->m_iRes[0] = m_pVolumetricData->m_iRes[0]; m_pVolumetricDataTimeDev->m_iRes[1] = m_pVolumetricData->m_iRes[1]; m_pVolumetricDataTimeDev->m_iRes[2] = m_pVolumetricData->m_iRes[2]; m_pVolumetricDataTimeDev->m_fMinVal[0] = m_pVolumetricData->m_fMinVal[0]; m_pVolumetricDataTimeDev->m_fMinVal[1] = m_pVolumetricData->m_fMinVal[1]; m_pVolumetricDataTimeDev->m_fMinVal[2] = m_pVolumetricData->m_fMinVal[2]; m_pVolumetricDataTimeDev->m_fMaxVal[0] = m_pVolumetricData->m_fMaxVal[0]; m_pVolumetricDataTimeDev->m_fMaxVal[1] = m_pVolumetricData->m_fMaxVal[1]; m_pVolumetricDataTimeDev->m_fMaxVal[2] = m_pVolumetricData->m_fMaxVal[2]; m_pVolumetricDataTimeDev->Create(); } if (m_pCurrentDensity != NULL) { m_pCurrentDensity->SetSize(3 * m_pVolumetricDataTimeDev->m_iRes[0] * m_pVolumetricDataTimeDev->m_iRes[1] * m_pVolumetricDataTimeDev->m_iRes[2]); } } else { eprintf("\nCTimeStep::ReadBQBCubeStep(): Error: Cube file dimension mismatch (%d-%d, %d-%d, %d-%d).\n",rx * g_iCubeXStride - g_iCubeXMismatch,m_pVolumetricData->m_iRes[0],ry * g_iCubeYStride - g_iCubeYMismatch,m_pVolumetricData->m_iRes[1],rz * g_iCubeZStride - g_iCubeZMismatch,m_pVolumetricData->m_iRes[2]); return false; } } for (z=0;zm_iRes[0]*m_pVolumetricData->m_iRes[1]*m_pVolumetricData->m_iRes[2];z++) m_pVolumetricData->m_pBin[z] = 0; } m_pVolumetricData->ReadCubeData(cfr,g_bVerbose); if (g_bVerbose) { mprintf(" First 100 volumetric data elements:"); for (z=0;z<((m_pVolumetricData->m_iRes[0]*m_pVolumetricData->m_iRes[1]*m_pVolumetricData->m_iRes[2]<100)?m_pVolumetricData->m_iRes[0]*m_pVolumetricData->m_iRes[1]*m_pVolumetricData->m_iRes[2]:100);z++) { if ((z%10) == 0) mprintf("\n "); mprintf(" %10G",m_pVolumetricData->m_pBin[z]); } mprintf("\n"); mprintf("<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n\n"); } // for (z=0;z<10;z++) // mprintf("@%d: %10G\n",z,m_pVolumetricData->m_pBin[z]); /* FILE *cubeFile = fopen("test.cube", "w"); if (cubeFile == NULL) { printf("Could not open output file!\n"); return 1; } fprintf(cubeFile, "\n\n"); fprintf(cubeFile, "%5lu %12.6f %12.6f %12.6f\n", m_iGesAtomCount, 0.0f, 0.0f, 0.0f); fprintf(cubeFile, "%5d %12.6f %12.6f %12.6f\n", m_pVolumetricData->m_iRes[0], g_fCubeXStep, 0.0f, 0.0f); fprintf(cubeFile, "%5d %12.6f %12.6f %12.6f\n", m_pVolumetricData->m_iRes[1], 0.0f, g_fCubeYStep, 0.0f); fprintf(cubeFile, "%5d %12.6f %12.6f %12.6f\n", m_pVolumetricData->m_iRes[2], 0.0f, 0.0f, g_fCubeZStep); for (int i = 0; i < (int)m_iGesAtomCount; i++) { fprintf(cubeFile, "%5d %12.6f %12.6f %12.6f %12.6f\n", 1, 0.0f, m_vaCoords[i][0] / 0.529177249f / 100.0f, m_vaCoords[i][1] / 0.529177249f / 100.0f, m_vaCoords[i][2] / 0.529177249f / 100.0f); } for (int i = 0; i < m_pVolumetricData->m_iRes[0]; i++) { for (int j = 0; j < m_pVolumetricData->m_iRes[1]; j++) { for (int k = 0; k < m_pVolumetricData->m_iRes[2] / 6; k++) { for (int l = 0; l < 6; l++) { fprintf(cubeFile, "%13.5E", m_pVolumetricData->m_pBin[i + j * m_pVolumetricData->m_iRes[0] + (k * 6 + l) * m_pVolumetricData->m_iRes[0] * m_pVolumetricData->m_iRes[1]]); } fprintf(cubeFile, "\n"); } if (m_pVolumetricData->m_iRes[2] % 6 != 0) { for (int l = 0; l < m_pVolumetricData->m_iRes[2] % 6; l++) { fprintf(cubeFile, "%13.5E", m_pVolumetricData->m_pBin[i + j * m_pVolumetricData->m_iRes[0] + ((m_pVolumetricData->m_iRes[2] / 6) * 6 + l) * m_pVolumetricData->m_iRes[0] * m_pVolumetricData->m_iRes[1]]); } fprintf(cubeFile, "\n"); } } } fclose(cubeFile);*/ if (g_bVerbose) mprintf("<<< CTimeStep::ReadBQBCubeStep() <<<\n"); return true; } bool CTimeStep::ReadBQBTrajStep(const std::vector *data, bool needinfo) { int z; char *p; CBQBTrajectoryFrame btf(*g_pBQBInterface); CBQBTrajectoryFrameColumn *btfc, *btfcx, *btfcy, *btfcz, *btfcxx, *btfcxy, *btfcxz, *btfcyx, *btfcyy, *btfcyz, *btfczx, *btfczy, *btfczz, *velx, *vely, *velz; CxDVector3 veca, vecb, vecc; if (g_bVerbose) mprintf(">>> CTimeStep::ReadBQBTrajStep() >>>\n"); if (!btf.ReadFrame(data)) { eprintf("CTimeStep::ReadBQBTrajStep(): Error: Could not read trajectory frame.\n"); return false; } m_iGesAtomCount = btf.m_iAtomCount; /*if (m_iGesAtomCount < 0) { eprintf("\nCTimeStep::ReadBQBTrajStep(): Error: Atom count = %d < 0.\n",m_iGesAtomCount); m_iGesAtomCount = 0; return false; }*/ if (m_iGesAtomCount == 0) { eprintf("\nCTimeStep::ReadBQBTrajStep(): Error: Atom count = 0.\n"); return false; } if ((btfcx = btf.GetColumn("PosX")) == NULL) { eprintf("\nCTimeStep::ReadBQBTrajStep(): Error: Column \"PosX\" does not exist in input trajectory.\n"); return false; } if ((btfcx->m_iType != BQB_TYPE_FLOAT) && (btfcx->m_iType != BQB_TYPE_DOUBLE)) { eprintf("\nCTimeStep::ReadBQBTrajStep(): Error: Column \"PosX\" is of type %d, which is neither FLOAT nor DOUBLE.\n",btfcx->m_iType); return false; } if ((btfcy = btf.GetColumn("PosY")) == NULL) { eprintf("\nCTimeStep::ReadBQBTrajStep(): Error: Column \"PosY\" does not exist in input trajectory.\n"); return false; } if ((btfcy->m_iType != BQB_TYPE_FLOAT) && (btfcy->m_iType != BQB_TYPE_DOUBLE)) { eprintf("\nCTimeStep::ReadBQBTrajStep(): Error: Column \"PosY\" is of type %d, which is neither FLOAT nor DOUBLE.\n",btfcy->m_iType); return false; } if ((btfcz = btf.GetColumn("PosZ")) == NULL) { eprintf("\nCTimeStep::ReadBQBTrajStep(): Error: Column \"PosZ\" does not exist in input trajectory.\n"); return false; } if ((btfcz->m_iType != BQB_TYPE_FLOAT) && (btfcz->m_iType != BQB_TYPE_DOUBLE)) { eprintf("\nCTimeStep::ReadBQBTrajStep(): Error: Column \"PosZ\" is of type %d, which is neither FLOAT nor DOUBLE.\n",btfcz->m_iType); return false; } if (m_vaCoords.GetSize() < (long)m_iGesAtomCount) m_vaCoords.SetSize(m_iGesAtomCount); if (g_bKeepOriginalCoords) if (m_vaCoords_Original.GetSize() < (long)m_iGesAtomCount) m_vaCoords_Original.SetSize(m_iGesAtomCount); for (z=0;z<(int)m_iGesAtomCount;z++) { m_vaCoords[z] = CxDVector3(btfcx->m_aReal[z],btfcy->m_aReal[z],btfcz->m_aReal[z]); if (g_bKeepOriginalCoords) m_vaCoords_Original[z] = m_vaCoords[z]; } if (needinfo) { if ((btfc = btf.GetColumn("Label")) == NULL) { eprintf("\nCTimeStep::ReadBQBTrajStep(): Error: Column \"Label\" does not exist in input trajectory.\n"); return false; } if (btfc->m_iType != BQB_TYPE_STRING) { eprintf("\nCTimeStep::ReadBQBTrajStep(): Error: Column \"Label\" is of type %d, which is not STRING.\n",btfc->m_iType); return false; } for (z=0;zm_aString[z].length()+1]; } catch(...) { p = NULL; } if (p == NULL) NewException((double)(btfc->m_aString[z].length()+1)*sizeof(char),__FILE__,__LINE__,__PRETTY_FUNCTION__); strcpy(p,(const char*)btfc->m_aString[z].c_str()); m_paLabels[z] = p; } } if (g_bNPT) { if (btf.m_pCellMatrix != NULL) { if ((btf.m_pCellMatrix->GetAt(0,1) != 0) || (btf.m_pCellMatrix->GetAt(0,2) != 0) || (btf.m_pCellMatrix->GetAt(1,2) != 0) || (btf.m_pCellMatrix->GetAt(1,0) != 0) || (btf.m_pCellMatrix->GetAt(2,0) != 0) || (btf.m_pCellMatrix->GetAt(2,1) != 0)) { g_bFoundNonOrtho = true; g_mBoxFromOrtho = *btf.m_pCellMatrix; if (g_bDoubleBox) { g_mBoxFromOrtho(0,0) *= g_iDoubleBoxX; g_mBoxFromOrtho(1,0) *= g_iDoubleBoxX; g_mBoxFromOrtho(2,0) *= g_iDoubleBoxX; g_mBoxFromOrtho(0,1) *= g_iDoubleBoxY; g_mBoxFromOrtho(1,1) *= g_iDoubleBoxY; g_mBoxFromOrtho(2,1) *= g_iDoubleBoxY; g_mBoxFromOrtho(0,2) *= g_iDoubleBoxZ; g_mBoxFromOrtho(1,2) *= g_iDoubleBoxZ; g_mBoxFromOrtho(2,2) *= g_iDoubleBoxZ; } // Backward transformation matrix g_mBoxToOrtho = CxDMatrix3(g_mBoxFromOrtho); if (!g_mBoxToOrtho.Invert()) { eprintf("CTimeStep::ReadBQBTrajStep(): Error: Encountered singular cell matrix (cell volume is zero).\n"); abort(); } veca = CxDVector3(g_mBoxFromOrtho(0,0),g_mBoxFromOrtho(0,1),g_mBoxFromOrtho(0,2)); vecb = CxDVector3(g_mBoxFromOrtho(1,0),g_mBoxFromOrtho(1,1),g_mBoxFromOrtho(1,2)); vecc = CxDVector3(g_mBoxFromOrtho(2,0),g_mBoxFromOrtho(2,1),g_mBoxFromOrtho(2,2)); // Cell angles g_fBoxAngleA = acos(DotP(vecb,vecc) / vecb.GetLength() / vecc.GetLength()) * 180.0 / Pi; g_fBoxAngleB = acos(DotP(veca,vecc) / veca.GetLength() / vecc.GetLength()) * 180.0 / Pi; g_fBoxAngleC = acos(DotP(veca,vecb) / veca.GetLength() / vecb.GetLength()) * 180.0 / Pi; // Orthogonal bounding box g_fBoxX = fabs(g_mBoxFromOrtho(0,0)) + fabs(g_mBoxFromOrtho(1,0)) + fabs(g_mBoxFromOrtho(2,0)); g_fBoxY = fabs(g_mBoxFromOrtho(0,1)) + fabs(g_mBoxFromOrtho(1,1)) + fabs(g_mBoxFromOrtho(2,1)); g_fBoxZ = fabs(g_mBoxFromOrtho(0,2)) + fabs(g_mBoxFromOrtho(1,2)) + fabs(g_mBoxFromOrtho(2,2)); // Minimal diameters g_fBoxMinDiamA = fabs(DotP(veca,Normalize(CrossP(vecb,vecc)))); g_fBoxMinDiamB = fabs(DotP(vecb,Normalize(CrossP(veca,vecc)))); g_fBoxMinDiamC = fabs(DotP(vecc,Normalize(CrossP(veca,vecb)))); g_fBoxMinDiam = MIN3(g_fBoxMinDiamA,g_fBoxMinDiamB,g_fBoxMinDiamC); } else { g_fBoxX = btf.m_pCellMatrix->GetAt(0,0); g_fBoxY = btf.m_pCellMatrix->GetAt(1,1); g_fBoxZ = btf.m_pCellMatrix->GetAt(2,2); } } } /* if (g_bUseVelocities && ((btfcx = btf.GetColumn("VelX")) != NULL) && ((btfcy = btf.GetColumn("VelY")) != NULL) && ((btfcz = btf.GetColumn("VelZ")) != NULL)) { if ((btfcx->m_iType != BQB_TYPE_FLOAT) && (btfcx->m_iType != BQB_TYPE_DOUBLE)) { eprintf("\nCTimeStep::ReadBQBTrajStep(): Error: Column \"VelX\" is of type %d, which is neither FLOAT nor DOUBLE.\n",btfcx->m_iType); return false; } if ((btfcy->m_iType != BQB_TYPE_FLOAT) && (btfcy->m_iType != BQB_TYPE_DOUBLE)) { eprintf("\nCTimeStep::ReadBQBTrajStep(): Error: Column \"VelY\" is of type %d, which is neither FLOAT nor DOUBLE.\n",btfcy->m_iType); return false; } if ((btfcz->m_iType != BQB_TYPE_FLOAT) && (btfcz->m_iType != BQB_TYPE_DOUBLE)) { eprintf("\nCTimeStep::ReadBQBTrajStep(): Error: Column \"VelZ\" is of type %d, which is neither FLOAT nor DOUBLE.\n",btfcz->m_iType); return false; } if (m_vaVelocities.GetSize() < (int)m_iGesAtomCount) m_vaVelocities.SetSize(m_iGesAtomCount); for (z=0;z<(int)m_iGesAtomCount;z++) m_vaVelocities[z] = CxDVector3(btfcx->m_aReal[z],btfcy->m_aReal[z],btfcz->m_aReal[z]); }*/ if (g_bVoroIntegrateCharge) { if ((btfc = btf.GetColumn("EChg")) == NULL) { eprintf("\nCTimeStep::ReadBQBTrajStep(): Error: Column \"EChg\" does not exist in input trajectory, but g_bVoroIntegrateCharge==true.\n"); return false; } if ((btfc->m_iType != BQB_TYPE_FLOAT) && (btfc->m_iType != BQB_TYPE_DOUBLE)) { eprintf("\nCTimeStep::ReadBQBTrajStep(): Error: Column \"EChg\" is of type %d, which is neither FLOAT nor DOUBLE.\n",btfc->m_iType); return false; } if (m_faCharge.GetSize() < (int)m_iGesAtomCount) m_faCharge.SetSize(m_iGesAtomCount); for (z=0;z<(int)m_iGesAtomCount;z++) m_faCharge[z] = btfc->m_aReal[z]; } if (g_bVoroIntegrateDipoleMoment) { if ((btfcx = btf.GetColumn("EDipX")) == NULL) { eprintf("\nCTimeStep::ReadBQBTrajStep(): Error: Column \"EDipX\" does not exist in input trajectory, but g_bVoroIntegrateDipoleMoment==true.\n"); return false; } if ((btfcx->m_iType != BQB_TYPE_FLOAT) && (btfcx->m_iType != BQB_TYPE_DOUBLE)) { eprintf("\nCTimeStep::ReadBQBTrajStep(): Error: Column \"EDipX\" is of type %d, which is neither FLOAT nor DOUBLE.\n",btfcx->m_iType); return false; } if ((btfcy = btf.GetColumn("EDipY")) == NULL) { eprintf("\nCTimeStep::ReadBQBTrajStep(): Error: Column \"EDipY\" does not exist in input trajectory, but g_bVoroIntegrateDipoleMoment==true.\n"); return false; } if ((btfcy->m_iType != BQB_TYPE_FLOAT) && (btfcy->m_iType != BQB_TYPE_DOUBLE)) { eprintf("\nCTimeStep::ReadBQBTrajStep(): Error: Column \"EDipY\" is of type %d, which is neither FLOAT nor DOUBLE.\n",btfcy->m_iType); return false; } if ((btfcz = btf.GetColumn("EDipZ")) == NULL) { eprintf("\nCTimeStep::ReadBQBTrajStep(): Error: Column \"EDipZ\" does not exist in input trajectory, but g_bVoroIntegrateDipoleMoment==true.\n"); return false; } if ((btfcz->m_iType != BQB_TYPE_FLOAT) && (btfcz->m_iType != BQB_TYPE_DOUBLE)) { eprintf("\nCTimeStep::ReadBQBTrajStep(): Error: Column \"EDipZ\" is of type %d, which is neither FLOAT nor DOUBLE.\n",btfcz->m_iType); return false; } if (m_dipoleMoments.GetSize() < (int)m_iGesAtomCount) m_dipoleMoments.SetSize(m_iGesAtomCount); for (z=0;z<(int)m_iGesAtomCount;z++) m_dipoleMoments[z] = CxDVector3(btfcx->m_aReal[z],btfcy->m_aReal[z],btfcz->m_aReal[z]); } if (g_bVoroIntegrateQuadrupoleMoment) { if ((btfcxx = btf.GetColumn("EQXX")) == NULL) { eprintf("\nCTimeStep::ReadBQBTrajStep(): Error: Column \"EQXX\" does not exist in input trajectory, but g_bVoroIntegrateQuadrupoleMoment==true.\n"); return false; } if ((btfcxx->m_iType != BQB_TYPE_FLOAT) && (btfcxx->m_iType != BQB_TYPE_DOUBLE)) { eprintf("\nCTimeStep::ReadBQBTrajStep(): Error: Column \"EQXX\" is of type %d, which is neither FLOAT nor DOUBLE.\n",btfcxx->m_iType); return false; } if ((btfcxy = btf.GetColumn("EQXY")) == NULL) { eprintf("\nCTimeStep::ReadBQBTrajStep(): Error: Column \"EQXY\" does not exist in input trajectory, but g_bVoroIntegrateQuadrupoleMoment==true.\n"); return false; } if ((btfcxy->m_iType != BQB_TYPE_FLOAT) && (btfcxy->m_iType != BQB_TYPE_DOUBLE)) { eprintf("\nCTimeStep::ReadBQBTrajStep(): Error: Column \"EQXY\" is of type %d, which is neither FLOAT nor DOUBLE.\n",btfcxy->m_iType); return false; } if ((btfcxz = btf.GetColumn("EQXZ")) == NULL) { eprintf("\nCTimeStep::ReadBQBTrajStep(): Error: Column \"EQXZ\" does not exist in input trajectory, but g_bVoroIntegrateQuadrupoleMoment==true.\n"); return false; } if ((btfcxz->m_iType != BQB_TYPE_FLOAT) && (btfcxz->m_iType != BQB_TYPE_DOUBLE)) { eprintf("\nCTimeStep::ReadBQBTrajStep(): Error: Column \"EQXZ\" is of type %d, which is neither FLOAT nor DOUBLE.\n",btfcxz->m_iType); return false; } if ((btfcyx = btf.GetColumn("EQYX")) == NULL) { eprintf("\nCTimeStep::ReadBQBTrajStep(): Error: Column \"EQYX\" does not exist in input trajectory, but g_bVoroIntegrateQuadrupoleMoment==true.\n"); return false; } if ((btfcyx->m_iType != BQB_TYPE_FLOAT) && (btfcyx->m_iType != BQB_TYPE_DOUBLE)) { eprintf("\nCTimeStep::ReadBQBTrajStep(): Error: Column \"EQYX\" is of type %d, which is neither FLOAT nor DOUBLE.\n",btfcyx->m_iType); return false; } if ((btfcyy = btf.GetColumn("EQYY")) == NULL) { eprintf("\nCTimeStep::ReadBQBTrajStep(): Error: Column \"EQYY\" does not exist in input trajectory, but g_bVoroIntegrateQuadrupoleMoment==true.\n"); return false; } if ((btfcyy->m_iType != BQB_TYPE_FLOAT) && (btfcyy->m_iType != BQB_TYPE_DOUBLE)) { eprintf("\nCTimeStep::ReadBQBTrajStep(): Error: Column \"EQYY\" is of type %d, which is neither FLOAT nor DOUBLE.\n",btfcyy->m_iType); return false; } if ((btfcyz = btf.GetColumn("EQYZ")) == NULL) { eprintf("\nCTimeStep::ReadBQBTrajStep(): Error: Column \"EQYZ\" does not exist in input trajectory, but g_bVoroIntegrateQuadrupoleMoment==true.\n"); return false; } if ((btfcyz->m_iType != BQB_TYPE_FLOAT) && (btfcyz->m_iType != BQB_TYPE_DOUBLE)) { eprintf("\nCTimeStep::ReadBQBTrajStep(): Error: Column \"EQYZ\" is of type %d, which is neither FLOAT nor DOUBLE.\n",btfcyz->m_iType); return false; } if ((btfczx = btf.GetColumn("EQZX")) == NULL) { eprintf("\nCTimeStep::ReadBQBTrajStep(): Error: Column \"EQZX\" does not exist in input trajectory, but g_bVoroIntegrateQuadrupoleMoment==true.\n"); return false; } if ((btfczx->m_iType != BQB_TYPE_FLOAT) && (btfczx->m_iType != BQB_TYPE_DOUBLE)) { eprintf("\nCTimeStep::ReadBQBTrajStep(): Error: Column \"EQZX\" is of type %d, which is neither FLOAT nor DOUBLE.\n",btfczx->m_iType); return false; } if ((btfczy = btf.GetColumn("EQZY")) == NULL) { eprintf("\nCTimeStep::ReadBQBTrajStep(): Error: Column \"EQZY\" does not exist in input trajectory, but g_bVoroIntegrateQuadrupoleMoment==true.\n"); return false; } if ((btfczy->m_iType != BQB_TYPE_FLOAT) && (btfczy->m_iType != BQB_TYPE_DOUBLE)) { eprintf("\nCTimeStep::ReadBQBTrajStep(): Error: Column \"EQZY\" is of type %d, which is neither FLOAT nor DOUBLE.\n",btfczy->m_iType); return false; } if ((btfczz = btf.GetColumn("EQZZ")) == NULL) { eprintf("\nCTimeStep::ReadBQBTrajStep(): Error: Column \"EQZZ\" does not exist in input trajectory, but g_bVoroIntegrateQuadrupoleMoment==true.\n"); return false; } if ((btfczz->m_iType != BQB_TYPE_FLOAT) && (btfczz->m_iType != BQB_TYPE_DOUBLE)) { eprintf("\nCTimeStep::ReadBQBTrajStep(): Error: Column \"EQZZ\" is of type %d, which is neither FLOAT nor DOUBLE.\n",btfczz->m_iType); return false; } if (m_maQuadTensor.size() < m_iGesAtomCount) m_maQuadTensor.resize(m_iGesAtomCount); for (z=0;z<(int)m_iGesAtomCount;z++) m_maQuadTensor[z] = CxDMatrix3(btfcxx->m_aReal[z],btfcxy->m_aReal[z],btfcxz->m_aReal[z],btfcyx->m_aReal[z],btfcyy->m_aReal[z],btfcyz->m_aReal[z],btfczx->m_aReal[z],btfczy->m_aReal[z],btfczz->m_aReal[z]); } if (g_bVoroIntegrateTotalCurrent) { if ((btfcx = btf.GetColumn("ECurX")) == NULL) { eprintf("\nCTimeStep::ReadBQBTrajStep(): Error: Column \"ECurX\" does not exist in input trajectory, but g_bVoroIntegrateDipoleMoment==true.\n"); return false; } if ((btfcx->m_iType != BQB_TYPE_FLOAT) && (btfcx->m_iType != BQB_TYPE_DOUBLE)) { eprintf("\nCTimeStep::ReadBQBTrajStep(): Error: Column \"ECurX\" is of type %d, which is neither FLOAT nor DOUBLE.\n",btfcx->m_iType); return false; } if ((btfcy = btf.GetColumn("ECurY")) == NULL) { eprintf("\nCTimeStep::ReadBQBTrajStep(): Error: Column \"ECurY\" does not exist in input trajectory, but g_bVoroIntegrateDipoleMoment==true.\n"); return false; } if ((btfcy->m_iType != BQB_TYPE_FLOAT) && (btfcy->m_iType != BQB_TYPE_DOUBLE)) { eprintf("\nCTimeStep::ReadBQBTrajStep(): Error: Column \"ECurY\" is of type %d, which is neither FLOAT nor DOUBLE.\n",btfcy->m_iType); return false; } if ((btfcz = btf.GetColumn("ECurZ")) == NULL) { eprintf("\nCTimeStep::ReadBQBTrajStep(): Error: Column \"ECurZ\" does not exist in input trajectory, but g_bVoroIntegrateDipoleMoment==true.\n"); return false; } if ((btfcz->m_iType != BQB_TYPE_FLOAT) && (btfcz->m_iType != BQB_TYPE_DOUBLE)) { eprintf("\nCTimeStep::ReadBQBTrajStep(): Error: Column \"ECurZ\" is of type %d, which is neither FLOAT nor DOUBLE.\n",btfcz->m_iType); return false; } if (m_totalCurrents.GetSize() < (int)m_iGesAtomCount) m_totalCurrents.SetSize(m_iGesAtomCount); for (z=0;z<(int)m_iGesAtomCount;z++) m_totalCurrents[z] = CxDVector3(btfcx->m_aReal[z],btfcy->m_aReal[z],btfcz->m_aReal[z]); } if (g_bVoroIntegrateMagneticMoment) { if ((btfcx = btf.GetColumn("MDipX")) == NULL) { eprintf("\nCTimeStep::ReadBQBTrajStep(): Error: Column \"MDipX\" does not exist in input trajectory, but g_bVoroIntegrateDipoleMoment==true.\n"); return false; } if ((btfcx->m_iType != BQB_TYPE_FLOAT) && (btfcx->m_iType != BQB_TYPE_DOUBLE)) { eprintf("\nCTimeStep::ReadBQBTrajStep(): Error: Column \"MDipX\" is of type %d, which is neither FLOAT nor DOUBLE.\n",btfcx->m_iType); return false; } if ((btfcy = btf.GetColumn("MDipY")) == NULL) { eprintf("\nCTimeStep::ReadBQBTrajStep(): Error: Column \"MDipY\" does not exist in input trajectory, but g_bVoroIntegrateDipoleMoment==true.\n"); return false; } if ((btfcy->m_iType != BQB_TYPE_FLOAT) && (btfcy->m_iType != BQB_TYPE_DOUBLE)) { eprintf("\nCTimeStep::ReadBQBTrajStep(): Error: Column \"MDipY\" is of type %d, which is neither FLOAT nor DOUBLE.\n",btfcy->m_iType); return false; } if ((btfcz = btf.GetColumn("MDipZ")) == NULL) { eprintf("\nCTimeStep::ReadBQBTrajStep(): Error: Column \"MDipZ\" does not exist in input trajectory, but g_bVoroIntegrateDipoleMoment==true.\n"); return false; } if ((btfcz->m_iType != BQB_TYPE_FLOAT) && (btfcz->m_iType != BQB_TYPE_DOUBLE)) { eprintf("\nCTimeStep::ReadBQBTrajStep(): Error: Column \"MDipZ\" is of type %d, which is neither FLOAT nor DOUBLE.\n",btfcz->m_iType); return false; } if (m_magneticDipoleMoments.GetSize() < (int)m_iGesAtomCount) m_magneticDipoleMoments.SetSize(m_iGesAtomCount); for (z=0;z<(int)m_iGesAtomCount;z++) m_magneticDipoleMoments[z] = CxDVector3(btfcx->m_aReal[z],btfcy->m_aReal[z],btfcz->m_aReal[z]); } if (g_bUseVelocities) { if ((velx = btf.GetColumn("VelX")) == NULL) { eprintf("\nCTimeStep::ReadBQBTrajStep(): Error: Column \"VelX\" does not exist in input trajectory, but g_bUseVelocities==true.\n"); return false; } if ((velx->m_iType != BQB_TYPE_FLOAT) && (velx->m_iType != BQB_TYPE_DOUBLE)) { eprintf("\nCTimeStep::ReadBQBTrajStep(): Error: Column \"VelX\" is of type %d, which is neither FLOAT nor DOUBLE.\n",velx->m_iType); return false; } if ((vely = btf.GetColumn("VelY")) == NULL) { eprintf("\nCTimeStep::ReadBQBTrajStep(): Error: Column \"VelY\" does not exist in input trajectory, but g_bUseVelocities==true.\n"); return false; } if ((vely->m_iType != BQB_TYPE_FLOAT) && (vely->m_iType != BQB_TYPE_DOUBLE)) { eprintf("\nCTimeStep::ReadBQBTrajStep(): Error: Column \"VelY\" is of type %d, which is neither FLOAT nor DOUBLE.\n",vely->m_iType); return false; } if ((velz = btf.GetColumn("VelZ")) == NULL) { eprintf("\nCTimeStep::ReadBQBTrajStep(): Error: Column \"VelZ\" does not exist in input trajectory, but g_bUseVelocities==true.\n"); return false; } if ((velz->m_iType != BQB_TYPE_FLOAT) && (velz->m_iType != BQB_TYPE_DOUBLE)) { eprintf("\nCTimeStep::ReadBQBTrajStep(): Error: Column \"VelZ\" is of type %d, which is neither FLOAT nor DOUBLE.\n",velz->m_iType); return false; } if (m_vaVelocities.GetSize() < (int)m_iGesAtomCount) m_vaVelocities.SetSize(m_iGesAtomCount); for (z=0;z<(int)m_iGesAtomCount;z++) m_vaVelocities[z] = CxDVector3(velx->m_aReal[z],vely->m_aReal[z],velz->m_aReal[z]); } if (g_bVerbose) mprintf("<<< CTimeStep::ReadBQBTrajStep() <<<\n"); return true; } bool CTimeStep::ReadBQB(CBQBFile *source, bool needinfo) { int ty, ver; if (g_bVerbose) mprintf(">>> CTimeStep::ReadBQB() >>>\n"); if (source == NULL) { eprintf("CTimeStep::ReadBQB(): Error: source == NULL.\n"); abort(); } _again: if (!source->ReadFrame()) { if (g_bVerbose) mprintf("CTimeStep::ReadBQB(): Error while reading BQB frame.\n"); return false; } ty = source->GetFrameType(); ver = source->GetFrameTypeVersion(); if (g_bVerbose) mprintf("CTimeStep::ReadBQB(): Frame type is %d v%d.\n",ty,ver); if (((ty == BQB_FRAMETYPE_COMPCUBESTART) || (ty == BQB_FRAMETYPE_COMPCUBE) || (ty == BQB_FRAMETYPE_COMPCUBEKEY)) && (ver < 3)) { if (g_bVerbose) mprintf(" --> Processing compressed cube frame.\n"); if (!g_pBQBFile->GetEngine()->DecompressCubeStep( source->GetFramePayload(), ver, &source->m_oParmSetCube, NULL, // ahistused NULL, // chistused false // skipvol )) return false; if (!ReadBQBCubeStep(needinfo)) return false; } else if (((ty == BQB_FRAMETYPE_COMPTRAJSTART) || (ty == BQB_FRAMETYPE_COMPTRAJ) || (ty == BQB_FRAMETYPE_COMPTRAJKEY)) && (ver < 3)) { if (g_bVerbose) mprintf(" --> Processing compressed trajectory frame.\n"); if (!g_pBQBFile->GetEngine()->DecompressAtomStep( source->GetFramePayload(), ver, &source->m_oParmSetPos, NULL, // histused false, // second false // check )) return false; if (!FetchBQBCompTrajFrame(needinfo)) return false; } else if ((ty == 4) && (ver == 0)) { if (g_bVerbose) mprintf(" --> Processing uncompressed trajectory frame.\n"); if (!ReadBQBTrajStep(source->GetFramePayload(),needinfo)) return false; } else if ((ty == 2) || (ty == 3)) { if (g_bVerbose) mprintf("CTimeStep::ReadBQB(): Skipping index frame.\n"); goto _again; } else { eprintf("CTimeStep::ReadBQB(): Error: Frame type %d v%d not yet implemented.\n", source->GetFrameType(),source->GetFrameTypeVersion()); return false; } if (g_bVerbose) mprintf("<<< CTimeStep::ReadBQB() <<<\n"); return true; } bool CTimeStep::FetchBQBCompTrajFrame(bool needinfo) { CBQBAtomSet *as; CBQBAtom *at; int z; char *p; if (m_pComment == NULL) { try { m_pComment = new char[256]; } catch(...) { m_pComment = NULL; } if (m_pComment == NULL) NewException((double)256*sizeof(char),__FILE__,__LINE__,__PRETTY_FUNCTION__); } m_pComment[0] = 0; as = g_pBQBFile->GetEngine()->GetOutputAtomFrame(0); strcpy(m_pComment,as->m_sComment); m_iGesAtomCount = (unsigned long)as->m_oaAtoms.size(); if (m_iGesAtomCount == 0) { eprintf("\nCTimeStep::FetchBQBCompTrajFrame(): Error: Atom count = 0."); return false; } if (needinfo) { for (z=0;zm_oaAtoms[z]; if (needinfo) { try { p = new char[at->m_sLabel.length()+1]; } catch(...) { p = NULL; } if (p == NULL) NewException((double)(at->m_sLabel.length()+1)*sizeof(char),__FILE__,__LINE__,__PRETTY_FUNCTION__); strcpy(p,at->m_sLabel.c_str()); m_paLabels[z] = p; } m_vaCoords[z][0] = at->m_fCoord[0] * 100.0; m_vaCoords[z][1] = at->m_fCoord[1] * 100.0; m_vaCoords[z][2] = at->m_fCoord[2] * 100.0; if (g_bKeepOriginalCoords) m_vaCoords_Original[z] = m_vaCoords[z]; } return true; } bool CTimeStep::SkipBQB() { int ty, ver; if (g_bVerbose) mprintf(">>> CTimeStep::SkipBQB() >>>\n"); if (g_pBQBFile == NULL) { eprintf("CTimeStep::SkipBQB(): Error: g_pBQBFile == NULL.\n"); abort(); } _again: if (!g_pBQBFile->ReadFrame()) { if (g_bVerbose) mprintf("CTimeStep::SkipBQB(): Error while reading BQB frame.\n"); return false; } ty = g_pBQBFile->GetFrameType(); ver = g_pBQBFile->GetFrameTypeVersion(); if (g_bVerbose) mprintf("CTimeStep::SkipBQB(): Frame type is %d v%d.\n",ty,ver); if (((ty == BQB_FRAMETYPE_COMPCUBESTART) || (ty == BQB_FRAMETYPE_COMPCUBE) || (ty == BQB_FRAMETYPE_COMPCUBEKEY)) && (ver < 3)) { if (g_bVerbose) mprintf(" --> Skipping compressed cube frame.\n"); if (!g_pBQBFile->GetEngine()->DecompressCubeStep( g_pBQBFile->GetFramePayload(), ver, &g_pBQBFile->m_oParmSetCube, NULL, // ahistused NULL, // chistused false // skipvol )) return false; } else if (((ty == BQB_FRAMETYPE_COMPTRAJSTART) || (ty == BQB_FRAMETYPE_COMPTRAJ) || (ty == BQB_FRAMETYPE_COMPTRAJKEY)) && (ver < 3)) { if (g_bVerbose) mprintf(" --> Skipping compressed trajectory frame.\n"); if (!g_pBQBFile->GetEngine()->DecompressAtomStep( g_pBQBFile->GetFramePayload(), ver, &g_pBQBFile->m_oParmSetPos, NULL, // histused false, // second false // check )) return false; } else if ((ty == 4) && (ver == 0)) { if (g_bVerbose) mprintf(" --> Skipping uncompressed trajectory frame.\n"); } else if ((ty == 2) || (ty == 3)) { if (g_bVerbose) mprintf(" Skipping index frame.\n"); goto _again; } else { eprintf("CTimeStep::SkipBQB(): Error: Frame type %d v%d not yet implemented.\n",ty,ver); return false; } if (g_bVerbose) mprintf("<<< CTimeStep::SkipBQB() <<<\n"); return true; } bool CTimeStep::SkipBQB(CBQBFile *source) { int ty, ver; if (g_bVerbose) mprintf(">>> CTimeStep::SkipBQB() >>>\n"); if (source == NULL) { eprintf("CTimeStep::SkipBQB(): Error: source == NULL.\n"); abort(); } _again: if (!source->ReadFrame()) { if (g_bVerbose) mprintf("CTimeStep::SkipBQB(): Error while reading BQB frame.\n"); return false; } ty = source->GetFrameType(); ver = source->GetFrameTypeVersion(); if (g_bVerbose) mprintf("CTimeStep::SkipBQB(): Frame type is %d v%d.\n",ty,ver); if (((ty == BQB_FRAMETYPE_COMPCUBESTART) || (ty == BQB_FRAMETYPE_COMPCUBE) || (ty == BQB_FRAMETYPE_COMPCUBEKEY)) && (ver < 3)) { if (g_bVerbose) mprintf(" --> Skipping compressed cube frame.\n"); if (!g_pBQBFile->GetEngine()->DecompressCubeStep( source->GetFramePayload(), ver, &source->m_oParmSetCube, NULL, // ahistused NULL, // chistused false // skipvol )) return false; } else if (((ty == BQB_FRAMETYPE_COMPTRAJSTART) || (ty == BQB_FRAMETYPE_COMPTRAJ) || (ty == BQB_FRAMETYPE_COMPTRAJKEY)) && (ver < 3)) { if (g_bVerbose) mprintf(" --> Skipping compressed trajectory frame.\n"); if (!g_pBQBFile->GetEngine()->DecompressAtomStep( source->GetFramePayload(), ver, &source->m_oParmSetPos, NULL, // histused false, // second false // check )) return false; } else if ((ty == 4) && (ty == 0)) { if (g_bVerbose) mprintf(" --> Skipping uncompressed trajectory frame.\n"); } else if ((ty == 2) || (ty == 3)) { if (g_bVerbose) mprintf(" Skipping index frame.\n"); goto _again; } else { eprintf("CTimeStep::SkipBQB(): Error: Frame type %d v%d not yet implemented.\n",ty,ver); return false; } if (g_bVerbose) mprintf("<<< CTimeStep::SkipBQB() <<<\n"); return true; } bool CTimeStep::ReadCube(CxMemFile *file) { int rx, ry, rz, ac, z, k; char buf[256], *p; const char *q; double fx, fy, fz, tf; file->Seek(0); (void)file->fgets(buf, 256); (void)file->fgets(buf, 256); if (file->Eof()) { eprintf("\nEnd of file reached while reading cube file.\n"); return false; } (void)file->fgets(buf, 256); p = buf; while (*p == ' ') p++; while (*p != ' ') p++; *p = 0; if (file->Eof()) { eprintf("Unexpected end of file reached while reading cube file.\n"); return false; } ac = atoi(buf); m_iGesAtomCount = ac; if (ac <= 0) { eprintf("Encountered atom count of %d while reading cube file.\n",ac); return false; } (void)file->fgets(buf, 256); p = buf; while (*p == ' ') p++; while (*p != ' ') p++; *p = 0; rx = atoi(buf); /* p++; while (*p == ' ') p++; q = p; while ((*p != ' ') && (*p != 0)) p++; *p = 0; g_fCubeXStep = atof(q) / g_iCubeXStride;*/ for (k = 0; k < 3; k++) { p++; while (*p == ' ') p++; q = p; while ((*p != ' ') && (*p != 0)) p++; *p = 0; tf = atof(q); if (g_bFlipCellVectorX && (k == 0) && (tf != 0)) tf *= -1.0; if (g_bFlipCellVectorY && (k == 1) && (tf != 0)) tf *= -1.0; if (g_bFlipCellVectorZ && (k == 2) && (tf != 0)) tf *= -1.0; if (m_bFirst) { g_fCubeXVector[k] = tf; } else { g_fCubeXVector[k] = g_mCubeCell(0, k) / (rx * g_iCubeXStride - g_iCubeXMismatch) / LEN_AU2PM; if (fabs(g_fCubeXVector[k] - tf / g_iCubeXStride) > 0.1) { eprintf("CTimeStep::ReadCube(): Error: Grid point distance in the cube file changed from %.3f pm to %.3f pm!\n", g_fCubeXVector[k] * LEN_AU2PM, tf / g_iCubeXStride * LEN_AU2PM); return false; } } } g_fCubeXStep = g_fCubeXVector[0]; (void)file->fgets(buf, 256); p = buf; while (*p == ' ') p++; while (*p != ' ') p++; *p = 0; ry = atoi(buf); /* for (z = 0; z < 2; z++) { p++; while (*p == ' ') p++; q = p; while ((*p != ' ') && (*p != 0)) p++; *p = 0; } g_fCubeYStep = atof(q) / g_iCubeYStride;*/ for (k = 0; k < 3; k++) { p++; while (*p == ' ') p++; q = p; while ((*p != ' ') && (*p != 0)) p++; *p = 0; tf = atof(q); if (g_bFlipCellVectorX && (k == 0) && (tf != 0)) tf *= -1.0; if (g_bFlipCellVectorY && (k == 1) && (tf != 0)) tf *= -1.0; if (g_bFlipCellVectorZ && (k == 2) && (tf != 0)) tf *= -1.0; if (m_bFirst) { g_fCubeYVector[k] = tf; } else { g_fCubeYVector[k] = g_mCubeCell(1, k) / (ry * g_iCubeYStride - g_iCubeYMismatch) / LEN_AU2PM; if (fabs(g_fCubeYVector[k] - tf / g_iCubeYStride) > 0.1) { eprintf("CTimeStep::ReadCube(): Error: Grid point distance in the cube file changed from %.3f pm to %.3f pm!\n", g_fCubeYVector[k] * LEN_AU2PM, tf / g_iCubeYStride * LEN_AU2PM); return false; } } } g_fCubeYStep = g_fCubeYVector[1]; (void)file->fgets(buf, 256); p = buf; while (*p == ' ') p++; while (*p != ' ') p++; *p = 0; rz = atoi(buf); /* for (z = 0; z < 3; z++) { p++; while (*p == ' ') p++; q = p; while ((*p != ' ') && (*p != 0)) p++; *p = 0; } g_fCubeZStep = atof(q) / g_iCubeZStride;*/ for (k = 0; k < 3; k++) { p++; while (*p == ' ') p++; q = p; while ((*p != ' ') && (*p != 0)) p++; *p = 0; tf = atof(q); if (g_bFlipCellVectorX && (k == 0) && (tf != 0)) tf *= -1.0; if (g_bFlipCellVectorY && (k == 1) && (tf != 0)) tf *= -1.0; if (g_bFlipCellVectorZ && (k == 2) && (tf != 0)) tf *= -1.0; if (m_bFirst) { g_fCubeZVector[k] = tf; } else { g_fCubeZVector[k] = g_mCubeCell(2, k) / (rz * g_iCubeZStride - g_iCubeZMismatch) / LEN_AU2PM; if (fabs(g_fCubeZVector[k] - tf / g_iCubeZStride) > 0.1) { eprintf("CTimeStep::ReadCube(): Error: Grid point distance in the cube file changed from %.3f pm to %.3f pm!\n", g_fCubeZVector[k] * LEN_AU2PM, tf / g_iCubeZStride * LEN_AU2PM); return false; } } } g_fCubeZStep = g_fCubeZVector[2]; m_vaCoords.RemoveAll_KeepSize(); CxIntArray atomNumbers; atomNumbers.SetSize(ac); for (z=0;zfgets(buf, 256); buf[strlen(buf)-1] = 0; if (file->Eof()) { eprintf("Unexpected end of cube file while reading coordinates (%d/%d).\n",z+1,ac); return false; } p = buf; while (*p == ' ') p++; while (*p != ' ') p++; *p = 0; atomNumbers[z] = atoi(buf); p++; // Column is always zero while (*p == ' ') p++; q = p; while ((*p != ' ') && (*p != 0)) p++; if (*p == 0) { eprintf("Incomplete line while reading coordinates from cube file (A).\n"); return false; } *p = 0; p++; while (*p == ' ') p++; q = p; while ((*p != ' ') && (*p != 0)) p++; if (*p == 0) { eprintf("Incomplete line while reading coordinates from cube file (B).\n"); return false; } *p = 0; fx = atof(q); p++; while (*p == ' ') p++; q = p; while ((*p != ' ') && (*p != 0)) p++; if (*p == 0) { eprintf("Incomplete line while reading coordinates from cube file (C).\n"); return false; } fy = atof(q); p++; while (*p == ' ') p++; q = p; while ((*p != ' ') && (*p != 0)) p++; *p = 0; fz = atof(q); m_vaCoords.Add(CxDVector3(fx*LEN_AU2PM,fy*LEN_AU2PM,fz*LEN_AU2PM)); } if (file->Eof()) { eprintf("Unexpected end of file while reading cube file.\n"); return false; } if (m_pVolumetricData == NULL) { m_pVolumetricData = new C3DF(); } if (m_pVolumetricDataTimeDev == NULL && g_bCubeTimeDev) { m_pVolumetricDataTimeDev = new C3DF(); } if (m_pCurrentDensity == NULL && g_bCubeTimeDev) { m_pCurrentDensity = new CxDoubleArray(); } static bool second = false; if (m_pVolumetricData->m_pBin == NULL) { m_pVolumetricData->m_iRes[0] = rx * g_iCubeXStride - g_iCubeXMismatch; m_pVolumetricData->m_iRes[1] = ry * g_iCubeYStride - g_iCubeYMismatch; m_pVolumetricData->m_iRes[2] = rz * g_iCubeZStride - g_iCubeZMismatch; m_pVolumetricData->m_fMinVal[0] = 0; m_pVolumetricData->m_fMaxVal[0] = g_fCubeXStep * LEN_AU2PM * (rx * g_iCubeXStride - g_iCubeXMismatch); m_pVolumetricData->m_fMinVal[1] = 0; m_pVolumetricData->m_fMaxVal[1] = g_fCubeYStep * LEN_AU2PM * (ry * g_iCubeYStride - g_iCubeYMismatch); m_pVolumetricData->m_fMinVal[2] = 0; m_pVolumetricData->m_fMaxVal[2] = g_fCubeZStep * LEN_AU2PM * (rz * g_iCubeZStride - g_iCubeZMismatch); m_pVolumetricData->Create(); if (m_pVolumetricDataTimeDev != NULL) { m_pVolumetricDataTimeDev->m_iRes[0] = rx * g_iCubeXStride - g_iCubeXMismatch; m_pVolumetricDataTimeDev->m_iRes[1] = ry * g_iCubeYStride - g_iCubeYMismatch; m_pVolumetricDataTimeDev->m_iRes[2] = rz * g_iCubeZStride - g_iCubeZMismatch; m_pVolumetricDataTimeDev->m_fMinVal[0] = 0; m_pVolumetricDataTimeDev->m_fMaxVal[0] = g_fCubeXStep * LEN_AU2PM * (rx * g_iCubeXStride - g_iCubeXMismatch); m_pVolumetricDataTimeDev->m_fMinVal[1] = 0; m_pVolumetricDataTimeDev->m_fMaxVal[1] = g_fCubeYStep * LEN_AU2PM * (ry * g_iCubeYStride - g_iCubeYMismatch); m_pVolumetricDataTimeDev->m_fMinVal[2] = 0; m_pVolumetricDataTimeDev->m_fMaxVal[2] = g_fCubeZStep * LEN_AU2PM * (rz * g_iCubeZStride - g_iCubeZMismatch); m_pVolumetricDataTimeDev->Create(); } if (m_pCurrentDensity != NULL) { m_pCurrentDensity->SetSize(3 * m_pVolumetricDataTimeDev->m_iRes[0] * m_pVolumetricDataTimeDev->m_iRes[1] * m_pVolumetricDataTimeDev->m_iRes[2]); } second = true; } else { if ((rx * g_iCubeXStride - g_iCubeXMismatch != m_pVolumetricData->m_iRes[0]) || (ry * g_iCubeYStride - g_iCubeYMismatch!= m_pVolumetricData->m_iRes[1]) || (rz * g_iCubeZStride - g_iCubeZMismatch != m_pVolumetricData->m_iRes[2])) { if (second) { second = false; m_pVolumetricData->m_iRes[0] = rx * g_iCubeXStride - g_iCubeXMismatch; m_pVolumetricData->m_iRes[1] = ry * g_iCubeYStride - g_iCubeYMismatch; m_pVolumetricData->m_iRes[2] = rz * g_iCubeZStride - g_iCubeZMismatch; m_pVolumetricData->m_fMinVal[0] = 0; m_pVolumetricData->m_fMaxVal[0] = g_fCubeXStep * LEN_AU2PM * (rx * g_iCubeXStride - g_iCubeXMismatch); m_pVolumetricData->m_fMinVal[1] = 0; m_pVolumetricData->m_fMaxVal[1] = g_fCubeYStep * LEN_AU2PM * (ry * g_iCubeYStride - g_iCubeYMismatch); m_pVolumetricData->m_fMinVal[2] = 0; m_pVolumetricData->m_fMaxVal[2] = g_fCubeZStep * LEN_AU2PM * (rz * g_iCubeZStride - g_iCubeZMismatch); m_pVolumetricData->Create(); if (m_pVolumetricDataTimeDev != NULL) { m_pVolumetricDataTimeDev->m_iRes[0] = rx * g_iCubeXStride - g_iCubeXMismatch; m_pVolumetricDataTimeDev->m_iRes[1] = ry * g_iCubeYStride - g_iCubeYMismatch; m_pVolumetricDataTimeDev->m_iRes[2] = rz * g_iCubeZStride - g_iCubeZMismatch; m_pVolumetricDataTimeDev->m_fMinVal[0] = 0; m_pVolumetricDataTimeDev->m_fMaxVal[0] = g_fCubeXStep * LEN_AU2PM * (rx * g_iCubeXStride - g_iCubeXMismatch); m_pVolumetricDataTimeDev->m_fMinVal[1] = 0; m_pVolumetricDataTimeDev->m_fMaxVal[1] = g_fCubeYStep * LEN_AU2PM * (ry * g_iCubeYStride - g_iCubeYMismatch); m_pVolumetricDataTimeDev->m_fMinVal[2] = 0; m_pVolumetricDataTimeDev->m_fMaxVal[2] = g_fCubeZStep * LEN_AU2PM * (rz * g_iCubeZStride - g_iCubeZMismatch); m_pVolumetricDataTimeDev->Create(); } if (m_pCurrentDensity != NULL) { m_pCurrentDensity->SetSize(3 * m_pVolumetricDataTimeDev->m_iRes[0] * m_pVolumetricDataTimeDev->m_iRes[1] * m_pVolumetricDataTimeDev->m_iRes[2]); } } else { eprintf("\nCube file dimension mismatch (%d-%d, %d-%d, %d-%d).\n",rx * g_iCubeXStride - g_iCubeXMismatch,m_pVolumetricData->m_iRes[0],ry * g_iCubeYStride - g_iCubeYMismatch,m_pVolumetricData->m_iRes[1],rz * g_iCubeZStride - g_iCubeZMismatch,m_pVolumetricData->m_iRes[2]); return false; } } for (z=0;zm_iRes[0]*m_pVolumetricData->m_iRes[1]*m_pVolumetricData->m_iRes[2];z++) m_pVolumetricData->m_pBin[z] = 0; } m_pVolumetricData->ReadCubeData(file, false); /* FILE *cubeFile = fopen("test.cube", "w"); if (cubeFile == NULL) { printf("Could not open output file!\n"); return 1; } fprintf(cubeFile, "\n\n"); fprintf(cubeFile, "%5lu %12.6f %12.6f %12.6f\n", m_iGesAtomCount, 0.0f, 0.0f, 0.0f); fprintf(cubeFile, "%5d %12.6f %12.6f %12.6f\n", m_pVolumetricData->m_iRes[0], g_fCubeXStep, 0.0f, 0.0f); fprintf(cubeFile, "%5d %12.6f %12.6f %12.6f\n", m_pVolumetricData->m_iRes[1], 0.0f, g_fCubeYStep, 0.0f); fprintf(cubeFile, "%5d %12.6f %12.6f %12.6f\n", m_pVolumetricData->m_iRes[2], 0.0f, 0.0f, g_fCubeZStep); for (int i = 0; i < (int)m_iGesAtomCount; i++) { fprintf(cubeFile, "%5d %12.6f %12.6f %12.6f %12.6f\n", 1, 0.0f, m_vaCoords[i][0] / 0.529177249f / 100.0f, m_vaCoords[i][1] / 0.529177249f / 100.0f, m_vaCoords[i][2] / 0.529177249f / 100.0f); } for (int i = 0; i < m_pVolumetricData->m_iRes[0]; i++) { for (int j = 0; j < m_pVolumetricData->m_iRes[1]; j++) { for (int k = 0; k < m_pVolumetricData->m_iRes[2] / 6; k++) { for (int l = 0; l < 6; l++) { fprintf(cubeFile, "%13.5E", m_pVolumetricData->m_pBin[i + j * m_pVolumetricData->m_iRes[0] + (k * 6 + l) * m_pVolumetricData->m_iRes[0] * m_pVolumetricData->m_iRes[1]]); } fprintf(cubeFile, "\n"); } if (m_pVolumetricData->m_iRes[2] % 6 != 0) { for (int l = 0; l < m_pVolumetricData->m_iRes[2] % 6; l++) { fprintf(cubeFile, "%13.5E", m_pVolumetricData->m_pBin[i + j * m_pVolumetricData->m_iRes[0] + ((m_pVolumetricData->m_iRes[2] / 6) * 6 + l) * m_pVolumetricData->m_iRes[0] * m_pVolumetricData->m_iRes[1]]); } fprintf(cubeFile, "\n"); } } } fclose(cubeFile);*/ return true; } bool CTimeStep::SkipCube(FILE *a) { int rx, ry, rz, ac, z, ix, iy, iz; char buf[256], *p, *q; (void)fgets(buf,256,a); (void)fgets(buf,256,a); (void)fgets(buf,256,a); if (feof(a)) return false; p = buf; while (*p == ' ') p++; while (*p != ' ') p++; *p = 0; ac = atoi(buf); (void)fgets(buf,256,a); if (feof(a)) { eprintf("\nCTimeStep::SkipCube(): Unexpected end of file while skipping in cube file.\n"); return false; } p = buf; while (*p == ' ') p++; while (*p != ' ') p++; *p = 0; rx = atoi(buf); (void)fgets(buf,256,a); if (feof(a)) { eprintf("\nCTimeStep::SkipCube(): Unexpected end of file while skipping in cube file.\n"); return false; } p = buf; while (*p == ' ') p++; while (*p != ' ') p++; *p = 0; ry = atoi(buf); (void)fgets(buf,256,a); if (feof(a)) { eprintf("\nCTimeStep::SkipCube(): Unexpected end of file while skipping in cube file.\n"); return false; } p = buf; while (*p == ' ') p++; while (*p != ' ') p++; *p = 0; rz = atoi(buf); for (z=0;z= rz) { iz = 0; iy++; if (iy >= ry) { iy = 0; ix++; } } if (ix == rx) return true; p++; goto _next; } return false; } bool CTimeStep::ReadPDB(FILE *a, bool needinfo, CxDVec3Array *v) { int i; static char buf[256], obuf[256], buf2[64]; char *p, *q, *r; double x, y, z; bool b; v->RemoveAll_KeepSize(); for (i=0;i %f %f %f\n",g_fBoxX,g_fBoxY,g_fBoxZ); if (g_bDoubleBox) { g_fBoxX *= g_iDoubleBoxX; g_fBoxY *= g_iDoubleBoxY; g_fBoxZ *= g_iDoubleBoxZ; } g_mBoxFromOrtho(0,0) = g_fBoxX; g_mBoxFromOrtho(0,1) = 0; g_mBoxFromOrtho(0,2) = 0; g_mBoxFromOrtho(1,0) = 0; g_mBoxFromOrtho(1,1) = g_fBoxY; g_mBoxFromOrtho(1,2) = 0; g_mBoxFromOrtho(2,0) = 0; g_mBoxFromOrtho(2,1) = 0; g_mBoxFromOrtho(2,2) = g_fBoxZ; g_fBoxAngleA = 90.0; g_fBoxAngleB = 90.0; g_fBoxAngleC = 90.0; g_mBoxToOrtho = CxDMatrix3(g_mBoxFromOrtho); if (!g_mBoxToOrtho.Invert()) { eprintf("CTimeStep::ReadPDB(): Error: Encountered singular cell matrix (cell volume is zero).\n"); abort(); } } } if (strstr(buf,"END") == buf) break; if ((strstr(buf,"ATOM")==0) && (strstr(buf,"HETATM")==0)) continue; p = &buf[7]; while (!(isalpha(*p) || (*p == '_')) && (*p != 0)) p++; if (*p == 0) { eprintf("Error 4 reading PDB line: \"%s\".\n",obuf); return false; } q = p; while (isalpha(*q) || (*q == '_')) q++; if (needinfo) { *q = 0; // if (strlen(p) > 7) // { // eprintf("\nCTimeStep::ReadPDB(): \"%s\" - maximum length for atom labels is 7 chars; truncating.\n",p); // p[7] = 0; // } try { r = new char[strlen(p)+1]; } catch(...) { r = NULL; } if (r == NULL) NewException((double)(strlen(p)+1)*sizeof(char),__FILE__,__LINE__,__PRETTY_FUNCTION__); strcpy(r,p); m_paLabels.Add(r); } p = q+1; while ((*p != '.') && (*p != 0)) p++; while (*p != ' ') p--; p++; q = p; b = false; while (*q != 0) { if (b) { if ((*q == ' ') || (*q == '-')) break; } if (*q == 0) break; if ((*q == '-') || (*q == '.') || ((*q >= '0') && (*q <= '9'))) b = true; q++; } // q = strchr(p,' '); if (*q == 0) { eprintf("\nCTimeStep::ReadPDB(): Error 1. \"%s\".",obuf); return false; } memcpy(buf2,p,q-p); buf2[q-p] = 0; // x = (double)atof(buf2) * 100.0; #ifdef FAST_ATOF x = fast_atof(buf2) * 100.0; #else x = atof(buf2) * 100.0; #endif // mprintf("\n \"%s\".",buf2); p = q; b = false; while (*q != 0) { if (b) { if ((*q == ' ') || (*q == '-')) break; } if (*q == 0) break; if ((*q == '-') || (*q == '.') || ((*q >= '0') && (*q <= '9'))) b = true; q++; } // q = strchr(p,' '); if (*q == 0) { eprintf("\nCTimeStep::ReadPDB(): Error 2. \"%s\".",obuf); return false; } memcpy(buf2,p,q-p); buf2[q-p] = 0; //y = (double)atof(buf2) * 100.0; #ifdef FAST_ATOF y = fast_atof(buf2) * 100.0; #else y = atof(buf2) * 100.0; #endif // mprintf("\n \"%s\".",buf2); //z = (double)atof(q) * 100.0; #ifdef FAST_ATOF z = fast_atof(q) * 100.0; #else z = atof(q) * 100.0; #endif // mprintf("\n \"%s\".",q); // mprintf("\n%f, %f, %f",x,y,z); m_vaCoords.Add(CxDVector3(x,y,z)); if (g_bKeepOriginalCoords) m_vaCoords_Original.Add(CxDVector3(x,y,z)); } _ende: m_iGesAtomCount = m_vaCoords.GetSize(); return true; } bool CTimeStep::SkipPDB(FILE *a) { char buf[256]; // bool b; while (true) { (void)fgets_bin(buf,256,a); if (feof(a)) return false; if (strlen(buf) == 0) continue; buf[strlen(buf)-1] = 0; if (strstr(buf,"END") == buf) break; } return true; } bool CTimeStep::ReadLAMMPS(FILE *a, bool needinfo) { int i, z2; char buf[256], obuf[256], *p, *q, *r; double x, y, z; double lowbound[3], highbound[3], skew[3]; CxDVector3 veca, vecb, vecc; m_vaCoords.RemoveAll_KeepSize(); for (i=0;i 7) // { // eprintf("\nCTimeStep::ReadLAMMPS(): \"%s\" - maximum length for atom labels is 7 chars; truncating.\n",p); // p[7] = 0; // } try { r = new char[strlen(p)+1]; } catch(...) { r = NULL; } if (r == NULL) NewException((double)(strlen(p)+1)*sizeof(char),__FILE__,__LINE__,__PRETTY_FUNCTION__); strcpy(r,p); m_paLabels[i] = r; } q++; while (strchr(" ",*q) != NULL) q++; p = q; while ((strchr(" ",*p) == NULL) && (*p != 0)) p++; if (*p == 0) { eprintf("\nCTimeStep::ReadLAMMPS(): %d: Incomplete line (2nd column missing): \"%s\"",i+1,obuf); return false; } *p = 0; //x = (double)atof(q) * 100.0; #ifdef FAST_ATOF x = fast_atof(q) * 100.0; #else x = atof(q) * 100.0; #endif q = p+1; while (strchr(" ",*q) != NULL) q++; p = q; while ((strchr(" ",*p) == NULL) && (*p != 0)) p++; if (*p == 0) { eprintf("\nCTimeStep::ReadLAMMPS(): %d: Incomplete line (3rd column missing) \"%s\"",i+1,obuf); return false; } *p = 0; //y = (double)atof(q) * 100.0; #ifdef FAST_ATOF y = fast_atof(q) * 100.0; #else y = atof(q) * 100.0; #endif q = p+1; while (strchr(" ",*q) != NULL) q++; p = q; while ((strchr(" ",*p) == NULL) && (*p != 0)) p++; if (g_bReadLAMMPSCharges && (*p == 0)) { eprintf("\nCTimeStep::ReadLAMMPS(): %d: Incomplete line (4th column missing) \"%s\"",i+1,obuf); return false; } if (*p != 0) *p = 0; //z = (double)atof(q) * 100.0; #ifdef FAST_ATOF z = fast_atof(q) * 100.0; #else z = atof(q) * 100.0; #endif m_vaCoords[i] = CxDVector3(x,y,z); if (g_bKeepOriginalCoords) m_vaCoords_Original[i] = CxDVector3(x,y,z); if (g_bLAMMPSForce) { for (z2=0;z2<3;z2++) { q = p+1; while (strchr(" ",*q) != NULL) q++; p = q; while ((strchr(" ",*p) == NULL) && (*p != 0)) p++; if ((z2 < 2) && (*p == 0)) { eprintf("\nCTimeStep::ReadLAMMPS(): %d: Incomplete line while reading forces (%dth column missing) \"%s\"",i+1,z2+5,obuf); return false; } if (*p != 0) *p = 0; //z = (double)atof(q) * 100.0; #ifdef FAST_ATOF m_vaForces[i][z2] = fast_atof(q); #else m_vaForces[i][z2] = atof(q); #endif } } if (g_bReadLAMMPSCharges) { q = p+1; while (strchr(" ",*q) != NULL) q++; p = q; while ((strchr(" ",*p) == NULL) && (*p != 0)) p++; if (*p != 0) *p = 0; //x = (double)atof(q); //m_faCharge[i] = x; #ifdef FAST_ATOF m_faCharge[i] = fast_atof(q); #else m_faCharge[i] = atof(q); #endif } } break; } } return true; } bool CTimeStep::SkipLAMMPS(FILE *a) { int i, j; char buf[256]; j = 0; while (true) { (void)fgets_bin(buf,256,a); if (feof(a)) return false; if (strlen(buf) == 0) continue; buf[strlen(buf)-1] = 0; if (strstr(buf,"ITEM: NUMBER OF ATOMS") != 0) { (void)fgets_bin(buf,256,a); if (feof(a)) return false; buf[strlen(buf)-1] = 0; j = atoi(buf); continue; } if (strstr(buf,"ITEM: ATOMS") != 0) { if (j == 0) { eprintf("CTimeStep::SkipLAMMPS(): \"ITEM: ATOMS\" before \"ITEM: NUMBER OF ATOMS\".\n"); return false; } for (i=0;i= '0') && (*p <= '9'))) goto _readagain; while ((*q != ' ') && (*q != 0)) q++; if (*q == 0) { eprintf("\nCTimeStep::ReadDLPOLY(): %d: Incomplete line F: \"%s\"\n",i+1,obuf); return false; } *q = 0; if (needinfo) { // if (strlen(p) > 7) // { // eprintf("\nCTimeStep::ReadDLPOLY(): \"%s\" - maximum length for atom labels is 7 chars; truncating.\n",p); // p[7] = 0; // } try { r = new char[strlen(p)+1]; } catch(...) { r = NULL; } if (r == NULL) NewException((double)(strlen(p)+1)*sizeof(char),__FILE__,__LINE__,__PRETTY_FUNCTION__); strcpy(r,p); m_paLabels[i] = r; } (void)fgets_bin(buf,256,a); if (feof(a)) return false; p = &buf[0]; while (*p == ' ') p++; q = p; while ((*q != ' ') && (*q != 0)) q++; if (*q == 0) { eprintf("\nCTimeStep::ReadDLPOLY(): %d: Incomplete line G: \"%s\"\n",i+1,obuf); return false; } *q = 0; //x = atof(p)*100.0; #ifdef FAST_ATOF x = fast_atof(p)*100.0; #else x = atof(p)*100.0; #endif p = q+1; while (*p == ' ') p++; q = p; while ((*q != ' ') && (*q != 0)) q++; if (*q == 0) { eprintf("\nCTimeStep::ReadDLPOLY(): %d: Incomplete line H: \"%s\"\n",i+1,obuf); return false; } *q = 0; //y = atof(p)*100.0; #ifdef FAST_ATOF y = fast_atof(p)*100.0; #else y = atof(p)*100.0; #endif p = q+1; while (*p == ' ') p++; q = p; while ((*q != ' ') && (*q != 0)) q++; *q = 0; //z = atof(p)*100.0; #ifdef FAST_ATOF z = fast_atof(p)*100.0; #else z = atof(p)*100.0; #endif m_vaCoords.Add(CxDVector3(x,y,z)); if (g_bKeepOriginalCoords) m_vaCoords_Original.Add(CxDVector3(x,y,z)); } break; } } return true; } bool CTimeStep::SkipDLPOLY(FILE *a) { int i, j; char buf[256], obuf[256], *p, *q; while (true) { (void)fgets_bin(buf,256,a); if (feof(a)) return false; if (strlen(buf) == 0) continue; buf[strlen(buf)-1] = 0; strcpy(obuf,buf); if (strstr(buf,"timestep") != 0) { p = &buf[0]; while (*p == ' ') p++; q = p; while ((*q != ' ') && (*q != 0)) q++; if (*q == 0) { eprintf("\nCTimeStep::ReadDLPOLY(): Incomplete line A: \"%s\"\n",obuf); return false; } *q = 0; p=q+1; while (*p == ' ') p++; q = p; while ((*q != ' ') && (*q != 0)) q++; if (*q == 0) { eprintf("\nCTimeStep::ReadDLPOLY(): Incomplete line B: \"%s\"\n",obuf); return false; } *q = 0; p=q+1; while (*p == ' ') p++; q = p; while ((*q != ' ') && (*q != 0)) q++; if (*q == 0) { eprintf("\nCTimeStep::ReadDLPOLY(): Incomplete line C: \"%s\"\n",obuf); return false; } *q = 0; j = atoi(p); (void)fgets_bin(buf,256,a); (void)fgets_bin(buf,256,a); (void)fgets_bin(buf,256,a); if (j == 0) { eprintf("CTimeStep::ReadDLPOLY(): Error: Atom count is 0.\n"); return false; } for (i=0;i 2) z = 0; break; } else { *p = 0; p++; //tf = atof(q)*100.0; #ifdef FAST_ATOF tf = fast_atof(q)*100.0; #else tf = atof(q)*100.0; #endif switch(z) { case 0: m_vaCoords.Add(CxDVector3(tf,0,0)); break; // X case 1: m_vaCoords[m_vaCoords.GetSize()-1][1] = tf; break; // Y case 2: m_vaCoords[m_vaCoords.GetSize()-1][2] = tf; break; // Z } z++; if (z > 2) z = 0; } } if ((m_vaCoords.GetSize() == (int)m_iGesAtomCount) && (z == 0)) break; } /* mprintf("Found %d atoms:\n",m_paLabels.GetSize()); for (z=0;z 2) z = 0; break; } else { *p = 0; p++; if (z == 0) i++; z++; if (z > 2) z = 0; } } if ((i == (int)m_iGesAtomCount) && (z == 0)) break; } (void)fgets_bin(buf,1024,a); // Box size if (feof(a)) { mprintf("ReadAmber(): End of trajectory reached.\n"); return false; } return true; } bool CTimeStep::ReadMol2(FILE *a, bool needinfo) { int i; char buf[256], obuf[256], *p, *q, *r; double x, y, z; (void)fgets_bin(buf,256,a); (void)fgets_bin(buf,256,a); (void)fgets_bin(buf,256,a); p = buf; while (*p == ' ') p++; q = p; while ((*q != ' ') && (*q != 0)) q++; *q = 0; m_iGesAtomCount = atoi(p); if (needinfo) { m_vaCoords.RemoveAll_KeepSize(); for (i=0;i 7) // { // eprintf("\nCTimeStep::ReadMol2(): \"%s\" - maximum length for atom labels is 7 chars; truncating.\n",p); // p[7] = 0; // } try { r = new char[strlen(p)+1]; } catch(...) { r = NULL; } if (r == NULL) NewException((double)(strlen(p)+1)*sizeof(char),__FILE__,__LINE__,__PRETTY_FUNCTION__); strcpy(r,p); m_paLabels[i] = r; } p = q+1; while ((*p != ' ') && (*p != 0)) p++; while (*p == ' ') p++; q = strchr(p,' '); if (q == NULL) { eprintf("\nCTimeStep::ReadMol2(): Error 1. %d. \"%s\".",i+1,obuf); return false; } *q = 0; x = atof(p) * 100.0; p = q+1; while (*p == ' ') p++; q = strchr(p,' '); if (q == NULL) { eprintf("\nCTimeStep::ReadMol2(): Error 2. %d. \"%s\".",i+1,obuf); return false; } *q = 0; y = atof(p) * 100.0; p = q+1; while (*p == ' ') p++; q = strchr(p,' '); if (q == NULL) { eprintf("\nCTimeStep::ReadMol2(): Error 3. %d. \"%s\".",i+1,obuf); return false; } *q = 0; z = atof(p) * 100.0; m_vaCoords.Add(CxDVector3(x,y,z)); p = q+1; while (*p == ' ') p++; q = p; while ((*q != ' ') && (*q != 0)) q++; if (needinfo) { *q = 0; try { r = new char[strlen(p)+1]; } catch(...) { r = NULL; } if (r == NULL) NewException((double)(strlen(p)+1)*sizeof(char),__FILE__,__LINE__,__PRETTY_FUNCTION__); strcpy(r,p); m_paMol2Types[i] = r; } /* mprintf(" X=%f, Y=%f, Z=%f",x,y,z); if (needinfo) mprintf(", A=%s, B=%s",(char*)m_paLabels[i],(char*)m_paMol2Types[i]); mprintf("\n");*/ } m_iGesAtomCount = m_vaCoords.GetSize(); return true; } bool CTimeStep::SkipMol2(FILE *a) { int i; char buf[256]; (void)fgets_bin(buf,256,a); (void)fgets_bin(buf,256,a); (void)fgets_bin(buf,256,a); (void)fgets_bin(buf,256,a); (void)fgets_bin(buf,256,a); (void)fgets_bin(buf,256,a); (void)fgets_bin(buf,256,a); (void)fgets_bin(buf,256,a); for (i=0;i<(long)m_iGesAtomCount;i++) { (void)fgets_bin(buf,256,a); if (feof(a)) return false; } return true; } void CTimeStep::CalcMinMax() { int z; m_vMin[0] = 1E20; m_vMin[1] = 1E20; m_vMin[2] = 1E20; m_vMax[0] = -1E20; m_vMax[1] = -1E20; m_vMax[2] = -1E20; for (z=0;z<(long)m_iGesAtomCount;z++) { if (m_vMin[0] > m_vaCoords[z][0]) m_vMin[0] = m_vaCoords[z][0]; if (m_vMin[1] > m_vaCoords[z][1]) m_vMin[1] = m_vaCoords[z][1]; if (m_vMin[2] > m_vaCoords[z][2]) m_vMin[2] = m_vaCoords[z][2]; if (m_vMax[0] < m_vaCoords[z][0]) m_vMax[0] = m_vaCoords[z][0]; if (m_vMax[1] < m_vaCoords[z][1]) m_vMax[1] = m_vaCoords[z][1]; if (m_vMax[2] < m_vaCoords[z][2]) m_vMax[2] = m_vaCoords[z][2]; } } void CTimeStep::WriteMol2(FILE *a) { int z, z2, z3, z4, ti, c, mc; CMolecule *m; CSingleMolecule *sm; int bonds; int *tpi; const char *cc; bonds = 0; for (z=0;zm_oaBonds.GetSize(); try { tpi = new int[g_iGesAtomCount]; } catch(...) { tpi = NULL; } if (tpi == NULL) NewException((double)g_iGesAtomCount*sizeof(int),__FILE__,__LINE__,__PRETTY_FUNCTION__); mfprintf(a," @MOLECULE\n"); mfprintf(a,"MOL\n"); mfprintf(a," %d %d %d 0 0\n",g_iGesAtomCount,bonds,g_oaSingleMolecules.GetSize()); mfprintf(a," SMALL\n"); mfprintf(a,"resp\n\n\n"); mfprintf(a," @ATOM\n"); c = 0; mc = 0; if (m_faCharge.GetSize() != g_iGesAtomCount) { m_faCharge.SetSize(g_iGesAtomCount); for (z=0;zm_laSingleMolIndex.GetSize();z2++) { sm = (CSingleMolecule*)g_oaSingleMolecules[m->m_laSingleMolIndex[z2]]; mc++; for (z3=0;z3m_baAtomIndex.GetSize();z3++) { if (m->m_baAtomIndex[z3] == g_iVirtAtomType) continue; for (z4=0;z4<((CxIntArray*)sm->m_oaAtomOffset[z3])->GetSize();z4++) { ti = ((CxIntArray*)sm->m_oaAtomOffset[z3])->GetAt(z4); if (m_paMol2Types.GetSize() != 0) cc = (char*)m_paMol2Types[ti]; else cc = (const char*)((CAtom*)g_oaAtoms[m->m_baAtomIndex[z3]])->m_sName; tpi[ti] = c++; mfprintf(a," %6d %2s % 11.4f % 11.4f % 11.4f %2s %4d MOL % 8.4f\n",c,(const char*)((CAtom*)g_oaAtoms[m->m_baAtomIndex[z3]])->m_sName,m_vaCoords[ti][0]/100.0,m_vaCoords[ti][1]/100.0,m_vaCoords[ti][2]/100.0,cc,mc,m_faCharge[ti]); } } } } mfprintf(a," @BOND\n"); c = 0; for (z=0;zm_laSingleMolIndex.GetSize();z2++) { sm = (CSingleMolecule*)g_oaSingleMolecules[m->m_laSingleMolIndex[z2]]; for (z3=0;z3m_oaBonds.GetSize();z3++) mfprintf(a," %6d %6d %6d 1\n",++c,tpi[((CMolBond*)sm->m_oaBonds[z3])->m_iAtomOffset[0]]+1,tpi[((CMolBond*)sm->m_oaBonds[z3])->m_iAtomOffset[1]]+1); } } mfprintf(a," @SUBSTRUCTURE\n"); c = 0; for (z=0;zm_laSingleMolIndex.GetSize();z2++) { mfprintf(a," %4d MOL %4d TEMP 0 **** **** 0 ROOT\n",c+1,c+1); c++; } } delete[] tpi; } void CTimeStep::ReadCellVector(FILE *a) { char buf[256], obuf[256]; char *p, *q; double tf; (void)fgets(buf,256,a); if (feof(a)) { eprintf("\nReadCellVector: End of file.\n"); eprintf("Your cell vector text file is too short.\n"); return; } if (strlen(buf) == 0) { eprintf("\nReadCellVector: Empty line.\n"); return; } buf[strlen(buf)-1] = 0; strcpy(obuf,buf); // mprintf(GREY,"\nReadCellVector: \"%s\".\n",buf); p = buf; while ((!isnumeric(*p)) && (*p != 0)) p++; if (*p == 0) { eprintf("\nReadCellVector: Incomplete line (1) \"%s\".\n",obuf); return; } q = p; while (isnumeric(*q)) q++; if (*q == 0) { eprintf("\nReadCellVector: Incomplete line (2) \"%s\".\n",obuf); return; } *q = 0; tf = atof(p)*100.0; if (tf <= 0) { eprintf("\nReadCellVector: Cell vectors need to be > 0 (X) \"%s\".\n",obuf); return; } g_fBoxX = tf; p = q+1; while ((!isnumeric(*p)) && (*p != 0)) p++; if (*p == 0) { eprintf("\nReadCellVector: Incomplete line (3) \"%s\".\n",obuf); return; } q = p; while (isnumeric(*q)) q++; if (*q == 0) { eprintf("\nReadCellVector: Incomplete line (4) \"%s\".\n",obuf); return; } *q = 0; tf = atof(p)*100.0; if (tf <= 0) { eprintf("\nReadCellVector: Cell vectors need to be > 0 (Y) \"%s\".\n",obuf); return; } g_fBoxY = tf; p = q+1; while ((!isnumeric(*p)) && (*p != 0)) p++; if (*p == 0) { eprintf("\nReadCellVector: Incomplete line (5) \"%s\".\n",obuf); return; } q = p; while (isnumeric(*q)) q++; if (*q != 0) *q = 0; tf = atof(p)*100.0; if (tf <= 0) { eprintf("\nReadCellVector: Cell vectors need to be > 0 (Z) \"%s\".\n",obuf); return; } g_fBoxZ = tf; g_mBoxFromOrtho(0,0) = g_fBoxX; g_mBoxFromOrtho(0,1) = 0; g_mBoxFromOrtho(0,2) = 0; g_mBoxFromOrtho(1,0) = 0; g_mBoxFromOrtho(1,1) = g_fBoxY; g_mBoxFromOrtho(1,2) = 0; g_mBoxFromOrtho(2,0) = 0; g_mBoxFromOrtho(2,1) = 0; g_mBoxFromOrtho(2,2) = g_fBoxZ; g_fBoxAngleA = 90.0; g_fBoxAngleB = 90.0; g_fBoxAngleC = 90.0; g_mBoxToOrtho = CxDMatrix3(g_mBoxFromOrtho); if (!g_mBoxToOrtho.Invert()) { eprintf("CTimeStep::ReadCellVector(): Error: Encountered singular cell matrix (cell volume is zero).\n"); abort(); } // mprintf(GREY," --> %f %f %f\n",g_fBoxX,g_fBoxY,g_fBoxZ); } void CTimeStep::CenterCOM() { CxDVector3 vc; double m; int z; if (g_iRemoveCOMFixAtom != -1) { CalcCenters(); vc = m_vaCoords[g_iRemoveCOMFixAtom]; } else { vc = CxDVector3(0,0,0); m = 0; for (z=0;zm_pElement->m_fMass; m += ((CAtom*)g_oaAtoms[g_baAtomIndex[z]])->m_pElement->m_fMass; } vc /= m; } for (z=0;z= g_fBoxX/2) t[0] -= g_fBoxX; } if (g_bPeriodicY) { while (t[1] < -g_fBoxY/2) t[1] += g_fBoxY; while (t[1] >= g_fBoxY/2) t[1] -= g_fBoxY; } if (g_bPeriodicZ) { while (t[2] < -g_fBoxZ/2) t[2] += g_fBoxZ; while (t[2] >= g_fBoxZ/2) t[2] -= g_fBoxZ; } return t.GetLength(); } void CTimeStep::FoldAtomsPositive() { BTIN; int z; if (!g_bPeriodic) return; for (z=0;z= 1.0) coord[0] -= 1.0; } if (g_bPeriodicY) { while (coord[1] < 0.0) coord[1] += 1.0f; while (coord[1] >= 1.0) coord[1] -= 1.0f; } if (g_bPeriodicZ) { while (coord[2] < 0.0) coord[2] += 1.0; while (coord[2] >= 1.0) coord[2] -= 1.0; } m_vaCoords[z] = g_mBoxFromOrtho * coord; } else { if (g_bPeriodicX) { while (m_vaCoords[z][0] < 0) m_vaCoords[z][0] += g_fBoxX; while (m_vaCoords[z][0] >= g_fBoxX) m_vaCoords[z][0] -= g_fBoxX; } if (g_bPeriodicX) { while (m_vaCoords[z][1] < 0) m_vaCoords[z][1] += g_fBoxY; while (m_vaCoords[z][1] >= g_fBoxY) m_vaCoords[z][1] -= g_fBoxY; } if (g_bPeriodicX) { while (m_vaCoords[z][2] < 0) m_vaCoords[z][2] += g_fBoxZ; while (m_vaCoords[z][2] >= g_fBoxZ) m_vaCoords[z][2] -= g_fBoxZ; } } } BTOUT; } void CTimeStep::WritePOV(const char *s) { FILE *b; CMolecule *m; CSingleMolecule *sm; CElement *el, *el2; int z, z2, z3, z4, o, o2; CxDVector3 vec1, vec2, vec3, vec1b, vec2b, vec3b, vecA, vecB, vecC, vecD; CMolBond *mb; CxDVector3 cam; // double cr, cg, cb; b = OpenFileWrite(s,true); mfprintf(b,"// Written by TRAVIS\n"); mfprintf(b,"// See http://www.travis-analyzer.de\n\n"); mfprintf(b,"#version 3.6;\n"); mfprintf(b,"\n"); mfprintf(b,"/**** Atoms ****/\n"); mfprintf(b,"#declare atom_draw = true;\n"); mfprintf(b,"#declare atom_r = 0.65;\n"); mfprintf(b,"#declare atom_specular = 0.7;\n"); mfprintf(b,"#declare atom_reflect = 0;\n"); mfprintf(b,"#declare atom_ambient = 0.2;\n"); mfprintf(b,"#declare atom_diffuse = 0.7;\n"); mfprintf(b,"//#declare atom_color = < 1.0, 1.0, 1.0, 0, 0 >;\n"); mfprintf(b,"//#declare atom_trans = 0.7;\n"); mfprintf(b,"\n"); mfprintf(b,"#declare atom_draw_halo1 = true;\n"); mfprintf(b,"#declare atom_r_halo1 = 0.008;\n"); mfprintf(b,"#declare atom_d_halo1 = 0.0125;\n"); mfprintf(b,"#declare atom_color_halo1 = < 0, 0, 0, 0, 0 >;\n"); mfprintf(b,"#declare atom_specular_halo1 = 0;\n"); mfprintf(b,"#declare atom_reflect_halo1 = 0;\n"); mfprintf(b,"#declare atom_ambient_halo1 = 1.0;\n"); mfprintf(b,"#declare atom_diffuse_halo1 = 0;\n"); mfprintf(b,"\n"); mfprintf(b,"#declare atom_draw_halo2 = true;\n"); mfprintf(b,"#declare atom_r_halo2 = 0.003;\n"); mfprintf(b,"#declare atom_d_halo2 = 0.01875;\n"); mfprintf(b,"#declare atom_color_halo2 = < 1, 1, 1, 0, 0 >;\n"); mfprintf(b,"#declare atom_specular_halo2 = 0;\n"); mfprintf(b,"#declare atom_reflect_halo2 = 0;\n"); mfprintf(b,"#declare atom_ambient_halo2 = 1.0;\n"); mfprintf(b,"#declare atom_diffuse_halo2 = 0;\n"); mfprintf(b,"\n"); mfprintf(b,"#declare atom_draw_halo3 = true;\n"); mfprintf(b,"#declare atom_r_halo3 = 0.003;\n"); mfprintf(b,"#declare atom_d_halo3 = 0.025;\n"); mfprintf(b,"#declare atom_color_halo3 = < 1, 1, 1, 0, 0.5 >;\n"); mfprintf(b,"#declare atom_specular_halo3 = 0;\n"); mfprintf(b,"#declare atom_reflect_halo3 = 0;\n"); mfprintf(b,"#declare atom_ambient_halo3 = 1.0;\n"); mfprintf(b,"#declare atom_diffuse_halo3 = 0;\n"); mfprintf(b,"\n"); mfprintf(b,"/**** Bonds ****/\n"); mfprintf(b,"#declare bond_draw = true;\n"); mfprintf(b,"#declare bond_r = 0.015;\n"); mfprintf(b,"#declare bond_specular = 0.7;\n"); mfprintf(b,"#declare bond_reflect = 0;\n"); mfprintf(b,"#declare bond_ambient = 0.2;\n"); mfprintf(b,"#declare bond_diffuse = 0.7;\n"); mfprintf(b,"\n"); mfprintf(b,"#declare bond_draw_halo1 = true;\n"); mfprintf(b,"#declare bond_r_halo1 = 0.008;\n"); mfprintf(b,"#declare bond_d_halo1 = 0;\n"); mfprintf(b,"#declare bond_color_halo1 = < 0, 0, 0, 0, 0 >;\n"); mfprintf(b,"#declare bond_specular_halo1 = 0;\n"); mfprintf(b,"#declare bond_reflect_halo1 = 0;\n"); mfprintf(b,"#declare bond_ambient_halo1 = 1.0;\n"); mfprintf(b,"#declare bond_diffuse_halo1 = 0;\n"); mfprintf(b,"\n"); mfprintf(b,"#declare bond_draw_halo2 = true;\n"); mfprintf(b,"#declare bond_r_halo2 = 0.003;\n"); mfprintf(b,"#declare bond_d_halo2 = 0.0286;\n"); mfprintf(b,"#declare bond_color_halo2 = < 1, 1, 1, 0, 0 >;\n"); mfprintf(b,"#declare bond_specular_halo2 = 0;\n"); mfprintf(b,"#declare bond_reflect_halo2 = 0;\n"); mfprintf(b,"#declare bond_ambient_halo2 = 1.0;\n"); mfprintf(b,"#declare bond_diffuse_halo2 = 0;\n"); mfprintf(b,"\n"); mfprintf(b,"#declare bond_draw_halo3 = true;\n"); mfprintf(b,"#declare bond_r_halo3 = 0.003;\n"); mfprintf(b,"#declare bond_d_halo3 = 0.0333;\n"); mfprintf(b,"#declare bond_color_halo3 = < 1, 1, 1, 0, 0.5 >;\n"); mfprintf(b,"#declare bond_specular_halo3 = 0;\n"); mfprintf(b,"#declare bond_reflect_halo3 = 0;\n"); mfprintf(b,"#declare bond_ambient_halo3 = 1.0;\n"); mfprintf(b,"#declare bond_diffuse_halo3 = 0;\n"); mfprintf(b,"\n"); mfprintf(b,"#declare bond_draw_stub = true;\n"); mfprintf(b,"#declare bond_r_stub = 0.004;\n"); mfprintf(b,"#declare bond_l_stub = 0.004;\n"); mfprintf(b,"#declare bond_color_stub = < 0, 0, 0, 0, 0 >;\n"); mfprintf(b,"#declare bond_specular_stub = 0;\n"); mfprintf(b,"#declare bond_reflect_stub = 0;\n"); mfprintf(b,"#declare bond_ambient_stub = 1.0;\n"); mfprintf(b,"#declare bond_diffuse_stub = 0;\n"); mfprintf(b,"\n"); mfprintf(b,"/**** Element Colors ****/\n"); for (z=0;zm_pElement; mfprintf(b,"#declare elem_%s_col = < %f, %f, %f, 0, 0 >;\n",el->m_sLabel,el->m_iColorR/255.0,el->m_iColorG/255.0,el->m_iColorB/255.0); } mfprintf(b,"\n/**** Element Radii ****/\n"); for (z=0;zm_pElement; mfprintf(b,"#declare elem_%s_r = %f;\n",el->m_sLabel,el->m_fRadius/1000.0); } mfprintf(b,"\n"); cam[0] = 0; cam[1] = 0; cam[2] = 40.0; mfprintf(b,"global_settings {\n"); mfprintf(b," assumed_gamma 1\n"); mfprintf(b,"/* radiosity {\n"); mfprintf(b," pretrace_start 0.08\n"); mfprintf(b," pretrace_end 0.04\n"); mfprintf(b," count 100\n\n"); mfprintf(b," nearest_count 5\n"); mfprintf(b," error_bound 0.4\n"); mfprintf(b," recursion_limit 1\n\n"); mfprintf(b," low_error_factor .5\n"); mfprintf(b," gray_threshold 0.0\n"); mfprintf(b," minimum_reuse 0.015\n"); mfprintf(b," brightness 1\n\n"); mfprintf(b," adc_bailout 0.01/2\n"); mfprintf(b," }*/\n"); mfprintf(b,"}\n"); mfprintf(b,"\ncamera {\n"); mfprintf(b," location <%f, %f, %f>\n",cam[0],cam[1],cam[2]); mfprintf(b," sky y\n"); mfprintf(b," right -0.06*x*image_width/image_height\n"); mfprintf(b," up 0.06*y\n"); mfprintf(b," look_at <0, 0, 0>\n"); mfprintf(b,"}\n"); mfprintf(b,"\n"); mfprintf(b,"// Solid background\n"); mfprintf(b,"background { rgb < 0.15, 0.1, 0.3 > }\n"); mfprintf(b,"\n"); mfprintf(b,"// Gradient background\n"); mfprintf(b,"sky_sphere {\n"); mfprintf(b," pigment {\n"); mfprintf(b," gradient y\n"); mfprintf(b," color_map {\n"); mfprintf(b," [ 0 color rgb < 0.05, 0.05, 0.05 > ]\n"); mfprintf(b," [ 1 color rgb < 0.20, 0.16, 0.50 > ]\n"); mfprintf(b," }\n"); mfprintf(b," scale 0.1\n"); mfprintf(b," translate -0.05\n"); mfprintf(b," }\n"); mfprintf(b,"}\n\n"); mfprintf(b,"/**** Invisible, only for Radiosity ****/\n"); mfprintf(b,"sphere {\n"); mfprintf(b," <0, 0, 0>, 1\n"); mfprintf(b," texture {\n"); mfprintf(b," pigment {color rgb < 1.0, 1.0, 1.0 > }\n"); mfprintf(b," finish { diffuse 0 ambient 1 }\n"); mfprintf(b," }\n"); mfprintf(b," hollow on\n"); mfprintf(b," no_shadow\n"); mfprintf(b," no_image\n"); mfprintf(b," scale 30000\n"); mfprintf(b,"}\n\n"); mfprintf(b,"light_source { < -8, 20, 20 > color rgb 0.8 }\n"); mfprintf(b,"//light_source { < 25, 12, 20 > color rgb 0.5 }\n\n"); mfprintf(b,"#macro m_atom_color(col)\n"); mfprintf(b," #ifdef(atom_color)\n"); mfprintf(b," atom_color\n"); mfprintf(b," #else #if (defined(atom_trans))\n"); mfprintf(b," col + < 0, 0, 0, 0, atom_trans >\n"); mfprintf(b," #else\n"); mfprintf(b," col\n"); mfprintf(b," #end #end\n"); mfprintf(b,"#end\n"); mfprintf(b,"\nunion {\n"); for (z=0;zm_laSingleMolIndex.GetSize();z2++) { sm = (CSingleMolecule*)g_oaSingleMolecules[m->m_laSingleMolIndex[z2]]; for (z3=0;z3m_baAtomIndex.GetSize();z3++) { if (m->m_baAtomIndex[z3] == g_iVirtAtomType) continue; el = ((CAtom*)g_oaAtoms[m->m_baAtomIndex[z3]])->m_pElement; for (z4=0;z4<((CxIntArray*)sm->m_oaAtomOffset[z3])->GetSize();z4++) { o = ((CxIntArray*)sm->m_oaAtomOffset[z3])->GetAt(z4); vec1 = m_vaCoords[o]; vec1 /= 1000.0; mfprintf(b,"#if (atom_draw)\n"); mfprintf(b," sphere { <%g, %g, %g>, elem_%s_r*atom_r\n",vec1[0],vec1[1],vec1[2],el->m_sLabel); mfprintf(b," pigment { rgbft m_atom_color(elem_%s_col) } finish { reflection atom_reflect specular atom_specular ambient atom_ambient diffuse atom_diffuse } }\n",el->m_sLabel); mfprintf(b,"#end\n"); vec2 = cam - vec1; vec2.Normalize(); // if (shadow) { mfprintf(b,"#if (atom_draw_halo1)\n"); mfprintf(b," disc { < %g - (%g) * atom_d_halo1, %g - (%g) * atom_d_halo1, %g - (%g) * atom_d_halo1 >,\n",vec1[0],vec2[0],vec1[1],vec2[1],vec1[2],vec2[2]); mfprintf(b," < %g, %g, %g >, (elem_%s_r * atom_r) + atom_r_halo1, elem_%s_r * atom_r\n",vec2[0],vec2[1],vec2[2],el->m_sLabel,el->m_sLabel); mfprintf(b," pigment { rgbft atom_color_halo1 } finish { reflection atom_reflect_halo1 specular atom_specular_halo1 ambient atom_ambient_halo1 diffuse atom_diffuse_halo1 } no_reflection no_radiosity }\n"); mfprintf(b,"#end\n"); } // if (halo) { mfprintf(b,"#if (atom_draw_halo2)\n"); mfprintf(b," disc { < %g - (%g) * atom_d_halo2, %g - (%g) * atom_d_halo2, %g - (%g) * atom_d_halo2 >,\n",vec1[0],vec2[0],vec1[1],vec2[1],vec1[2],vec2[2]); mfprintf(b," < %g, %g, %g >, (elem_%s_r * atom_r) + atom_r_halo1 + atom_r_halo2, elem_%s_r * atom_r\n",vec2[0],vec2[1],vec2[2],el->m_sLabel,el->m_sLabel); mfprintf(b," pigment { rgbft atom_color_halo2 } finish { reflection atom_reflect_halo2 specular atom_specular_halo2 ambient atom_ambient_halo2 diffuse atom_diffuse_halo2 } no_reflection no_radiosity }\n"); mfprintf(b,"#end\n"); mfprintf(b,"#if (atom_draw_halo3)\n"); mfprintf(b," disc { < %g - (%g) * atom_d_halo3, %g - (%g) * atom_d_halo3, %g - (%g) * atom_d_halo3 >,\n",vec1[0],vec2[0],vec1[1],vec2[1],vec1[2],vec2[2]); mfprintf(b," < %g, %g, %g >, (elem_%s_r * atom_r) + atom_r_halo1 + atom_r_halo2 + atom_r_halo3, elem_%s_r * atom_r\n",vec2[0],vec2[1],vec2[2],el->m_sLabel,el->m_sLabel); mfprintf(b," pigment { rgbft atom_color_halo3 } finish { reflection atom_reflect_halo3 specular atom_specular_halo3 ambient atom_ambient_halo3 diffuse atom_diffuse_halo3 } no_reflection no_radiosity }\n"); mfprintf(b,"#end\n"); } } } for (z3=0;z3m_oaBonds.GetSize();z3++) { mb = (CMolBond*)sm->m_oaBonds[z3]; o = mb->m_iAtomOffset[0]; o2 = mb->m_iAtomOffset[1]; el = ((CAtom*)g_oaAtoms[g_waAtomRealElement[o]])->m_pElement; el2 = ((CAtom*)g_oaAtoms[g_waAtomRealElement[o2]])->m_pElement; vec1 = m_vaCoords[o]; vec1 /= 1000.0; vec2 = m_vaCoords[o2]; vec2 /= 1000.0; if ((vec1-vec2).GetLength() > 0.3) continue; vec3 = (vec1/el->m_fRadius + vec2/el2->m_fRadius) / (1.0/el->m_fRadius+1.0/el2->m_fRadius); vec3b = vec2 - vec1; vec3b.Normalize(); mfprintf(b,"#local vec1c = < %g + (%g) * ( elem_%s_r*atom_r - ( elem_%s_r*atom_r - 0.5*sqrt(4*elem_%s_r*elem_%s_r*atom_r*atom_r - 4*bond_r*bond_r ) ) ),\n",vec1[0],vec3b[0],el->m_sLabel,el->m_sLabel,el->m_sLabel,el->m_sLabel); mfprintf(b," %g + (%g) * ( elem_%s_r*atom_r - ( elem_%s_r*atom_r - 0.5*sqrt(4*elem_%s_r*elem_%s_r*atom_r*atom_r - 4*bond_r*bond_r ) ) ),\n",vec1[1],vec3b[1],el->m_sLabel,el->m_sLabel,el->m_sLabel,el->m_sLabel); mfprintf(b," %g + (%g) * ( elem_%s_r*atom_r - ( elem_%s_r*atom_r - 0.5*sqrt(4*elem_%s_r*elem_%s_r*atom_r*atom_r - 4*bond_r*bond_r ) ) ) >;\n",vec1[2],vec3b[2],el->m_sLabel,el->m_sLabel,el->m_sLabel,el->m_sLabel); mfprintf(b,"#local vec2c = < %g - (%g) * ( elem_%s_r*atom_r - ( elem_%s_r*atom_r - 0.5*sqrt(4*elem_%s_r*elem_%s_r*atom_r*atom_r - 4*bond_r*bond_r ) ) ),\n",vec2[0],vec3b[0],el2->m_sLabel,el2->m_sLabel,el2->m_sLabel,el2->m_sLabel); mfprintf(b," %g - (%g) * ( elem_%s_r*atom_r - ( elem_%s_r*atom_r - 0.5*sqrt(4*elem_%s_r*elem_%s_r*atom_r*atom_r - 4*bond_r*bond_r ) ) ),\n",vec2[1],vec3b[1],el2->m_sLabel,el2->m_sLabel,el2->m_sLabel,el2->m_sLabel); mfprintf(b," %g - (%g) * ( elem_%s_r*atom_r - ( elem_%s_r*atom_r - 0.5*sqrt(4*elem_%s_r*elem_%s_r*atom_r*atom_r - 4*bond_r*bond_r ) ) ) >;\n",vec2[2],vec3b[2],el2->m_sLabel,el2->m_sLabel,el2->m_sLabel,el2->m_sLabel); mfprintf(b,"#if (bond_draw)\n"); mfprintf(b," cylinder { < %g, %g, %g >, vec1c, bond_r open\n",vec3[0],vec3[1],vec3[2]); mfprintf(b," pigment { rgbft m_atom_color(elem_%s_col) } finish { reflection bond_reflect specular bond_specular ambient bond_ambient diffuse bond_diffuse } }\n",el->m_sLabel); mfprintf(b," cylinder { < %g, %g, %g >, vec2c, bond_r open\n",vec3[0],vec3[1],vec3[2]); mfprintf(b," pigment { rgbft m_atom_color(elem_%s_col) } finish { reflection bond_reflect specular bond_specular ambient bond_ambient diffuse bond_diffuse } }\n",el2->m_sLabel); mfprintf(b,"#end\n"); vec3 = cam - (vec1 + vec2) / 2.0; vec3.Normalize(); vec2b = vec2-vec1; vec1b = CrossP(vec3,vec2b); vec1b.Normalize(); mfprintf(b,"#local vec3 = < %g, %g, %g >;\n",vec3[0],vec3[1],vec3[2]); mfprintf(b,"#local vec1b = < %g, %g, %g >;\n",vec1b[0],vec1b[1],vec1b[2]); // if (shadow) { mfprintf(b,"#if (bond_draw_halo1)\n"); mfprintf(b," #local vecA = vec1c + vec1b * (bond_r + bond_r_halo1) - vec3 * bond_d_halo1;\n"); mfprintf(b," #local vecB = vec2c + vec1b * (bond_r + bond_r_halo1) - vec3 * bond_d_halo1;\n"); mfprintf(b," #local vecC = vec2c + vec1b * (bond_r) - vec3 * bond_d_halo1;\n"); mfprintf(b," #local vecD = vec1c + vec1b * (bond_r) - vec3 * bond_d_halo1;\n"); mfprintf(b," triangle { vecA, vecB, vecC\n"); mfprintf(b," pigment { rgbft bond_color_halo1 } finish { reflection bond_reflect_halo1 specular bond_specular_halo1 ambient bond_ambient_halo1 diffuse bond_diffuse_halo1 } no_reflection no_radiosity }\n"); mfprintf(b," triangle { vecA, vecD, vecC\n"); mfprintf(b," pigment { rgbft bond_color_halo1 } finish { reflection bond_reflect_halo1 specular bond_specular_halo1 ambient bond_ambient_halo1 diffuse bond_diffuse_halo1 } no_reflection no_radiosity }\n"); mfprintf(b," #local vecA = vec1c - vec1b * (bond_r + bond_r_halo1) - vec3 * bond_d_halo1;\n"); mfprintf(b," #local vecB = vec2c - vec1b * (bond_r + bond_r_halo1) - vec3 * bond_d_halo1;\n"); mfprintf(b," #local vecC = vec2c - vec1b * (bond_r) - vec3 * bond_d_halo1;\n"); mfprintf(b," #local vecD = vec1c - vec1b * (bond_r) - vec3 * bond_d_halo1;\n"); mfprintf(b," triangle { vecA, vecB, vecC\n"); mfprintf(b," pigment { rgbft bond_color_halo1 } finish { reflection bond_reflect_halo1 specular bond_specular_halo1 ambient bond_ambient_halo1 diffuse bond_diffuse_halo1 } no_reflection no_radiosity }\n"); mfprintf(b," triangle { vecA, vecD, vecC\n"); mfprintf(b," pigment { rgbft bond_color_halo1 } finish { reflection bond_reflect_halo1 specular bond_specular_halo1 ambient bond_ambient_halo1 diffuse bond_diffuse_halo1 } no_reflection no_radiosity }\n"); mfprintf(b,"#end\n"); } // if (halo) { mfprintf(b,"#if (bond_draw_halo2)\n"); mfprintf(b," #local vecA = vec1c + vec1b * (bond_r + bond_r_halo1 + bond_r_halo2) - vec3 * bond_d_halo2;\n"); mfprintf(b," #local vecB = vec2c + vec1b * (bond_r + bond_r_halo1 + bond_r_halo2) - vec3 * bond_d_halo2;\n"); mfprintf(b," #local vecC = vec2c + vec1b * (bond_r + bond_r_halo1) - vec3 * bond_d_halo2;\n"); mfprintf(b," #local vecD = vec1c + vec1b * (bond_r + bond_r_halo1) - vec3 * bond_d_halo2;\n"); mfprintf(b," triangle { vecA, vecB, vecC\n"); mfprintf(b," pigment { rgbft bond_color_halo2 } finish { reflection bond_reflect_halo2 specular bond_specular_halo2 ambient bond_ambient_halo2 diffuse bond_diffuse_halo2 } no_reflection no_radiosity }\n"); mfprintf(b," triangle { vecA, vecD, vecC\n"); mfprintf(b," pigment { rgbft bond_color_halo2 } finish { reflection bond_reflect_halo2 specular bond_specular_halo2 ambient bond_ambient_halo2 diffuse bond_diffuse_halo2 } no_reflection no_radiosity }\n"); mfprintf(b," #local vecA = vec1c - vec1b * (bond_r + bond_r_halo1 + bond_r_halo2) - vec3 * bond_d_halo2;\n"); mfprintf(b," #local vecB = vec2c - vec1b * (bond_r + bond_r_halo1 + bond_r_halo2) - vec3 * bond_d_halo2;\n"); mfprintf(b," #local vecC = vec2c - vec1b * (bond_r + bond_r_halo1) - vec3 * bond_d_halo2;\n"); mfprintf(b," #local vecD = vec1c - vec1b * (bond_r + bond_r_halo1) - vec3 * bond_d_halo2;\n"); mfprintf(b," triangle { vecA, vecB, vecC\n"); mfprintf(b," pigment { rgbft bond_color_halo2 } finish { reflection bond_reflect_halo2 specular bond_specular_halo2 ambient bond_ambient_halo2 diffuse bond_diffuse_halo2 } no_reflection no_radiosity }\n"); mfprintf(b," triangle { vecA, vecD, vecC\n"); mfprintf(b," pigment { rgbft bond_color_halo2 } finish { reflection bond_reflect_halo2 specular bond_specular_halo2 ambient bond_ambient_halo2 diffuse bond_diffuse_halo2 } no_reflection no_radiosity }\n"); mfprintf(b,"#end\n"); mfprintf(b,"#if (bond_draw_halo3)\n"); mfprintf(b," #local vecA = vec1c + vec1b * (bond_r + bond_r_halo1 + bond_r_halo2 + bond_r_halo3) - vec3 * bond_d_halo2;\n"); mfprintf(b," #local vecB = vec2c + vec1b * (bond_r + bond_r_halo1 + bond_r_halo2 + bond_r_halo3) - vec3 * bond_d_halo2;\n"); mfprintf(b," #local vecC = vec2c + vec1b * (bond_r + bond_r_halo1 + bond_r_halo2) - vec3 * bond_d_halo2;\n"); mfprintf(b," #local vecD = vec1c + vec1b * (bond_r + bond_r_halo1 + bond_r_halo2) - vec3 * bond_d_halo2;\n"); mfprintf(b," triangle { vecA, vecB, vecC\n"); mfprintf(b," pigment { rgbft bond_color_halo3 } finish { reflection bond_reflect_halo3 specular bond_specular_halo3 ambient bond_ambient_halo3 diffuse bond_diffuse_halo3 } no_reflection no_radiosity }\n"); mfprintf(b," triangle { vecA, vecD, vecC\n"); mfprintf(b," pigment { rgbft bond_color_halo3 } finish { reflection bond_reflect_halo3 specular bond_specular_halo3 ambient bond_ambient_halo3 diffuse bond_diffuse_halo3 } no_reflection no_radiosity }\n"); mfprintf(b," #local vecA = vec1c - vec1b * (bond_r + bond_r_halo1 + bond_r_halo2 + bond_r_halo3) - vec3 * bond_d_halo2;\n"); mfprintf(b," #local vecB = vec2c - vec1b * (bond_r + bond_r_halo1 + bond_r_halo2 + bond_r_halo3) - vec3 * bond_d_halo2;\n"); mfprintf(b," #local vecC = vec2c - vec1b * (bond_r + bond_r_halo1 + bond_r_halo2) - vec3 * bond_d_halo2;\n"); mfprintf(b," #local vecD = vec1c - vec1b * (bond_r + bond_r_halo1 + bond_r_halo2) - vec3 * bond_d_halo2;\n"); mfprintf(b," triangle { vecA, vecB, vecC\n"); mfprintf(b," pigment { rgbft bond_color_halo3 } finish { reflection bond_reflect_halo3 specular bond_specular_halo3 ambient bond_ambient_halo3 diffuse bond_diffuse_halo3 } no_reflection no_radiosity }\n"); mfprintf(b," triangle { vecA, vecD, vecC\n"); mfprintf(b," pigment { rgbft bond_color_halo3 } finish { reflection bond_reflect_halo3 specular bond_specular_halo3 ambient bond_ambient_halo3 diffuse bond_diffuse_halo3 } no_reflection no_radiosity }\n"); mfprintf(b,"#end\n"); } // if (shadow) { vec3 = vec2 - vec1; vec3.Normalize(); mfprintf(b,"#if (bond_draw_stub)\n"); mfprintf(b," #local vec3 = < %g, %g, %g >;\n",vec3[0],vec3[1],vec3[2]); mfprintf(b," difference {\n"); mfprintf(b," cylinder { vec1c, vec1c + vec3 * bond_l_stub, bond_r + bond_r_stub }\n"); mfprintf(b," cylinder { vec1c - vec3 * (bond_l_stub+0.001), vec1c + vec3 * (bond_l_stub+0.001), bond_r }\n"); mfprintf(b," pigment { rgbft bond_color_stub } finish { reflection bond_reflect_stub specular bond_specular_stub ambient bond_ambient_stub diffuse bond_diffuse_stub } }\n"); mfprintf(b," difference {\n"); mfprintf(b," cylinder { vec2c, vec2c - vec3 * bond_l_stub, bond_r + bond_r_stub }\n"); mfprintf(b," cylinder { vec2c + vec3 * (bond_l_stub+0.001), vec2c - vec3 * (bond_l_stub+0.001), bond_r }\n"); mfprintf(b," pigment { rgbft bond_color_stub } finish { reflection bond_reflect_stub specular bond_specular_stub ambient bond_ambient_stub diffuse bond_diffuse_stub } }\n"); mfprintf(b,"#end\n"); } } } } mfprintf(b,"\n no_shadow\n}\n\n"); fclose(b); } void CTimeStep::DumpDipoles() { int z, z2, z3, z4, ti; CMolecule *m; CSingleMolecule *sm; CxDVector3 dc; if (!(g_bDipole && g_bDumpDipoleVector)) return; fprintf(g_fDumpDipole,"%lu",g_iSteps); for (z=0;zGetSize();z2++) { sm = (CSingleMolecule*)g_oaSingleMolecules[m->m_laSingleMolIndex[((CxIntArray*)g_oaDumpDipoleVector[z])->GetAt(z2)]]; fprintf(g_fDumpDipole,"; %.10G; %.10G; %.10G",sm->m_vDipole[0],sm->m_vDipole[1],sm->m_vDipole[2]); if (g_bDumpDipoleAbs) fprintf(g_fDumpDipole,"; %.10G",sm->m_vDipole.GetLength()); } } fprintf(g_fDumpDipole,"\n"); if (g_bDumpDipoleXYZ) { fprintf(g_fDumpDipoleXYZ,"%d\n\n",g_iDumpDipoleXYZAtoms); fprintf(g_fDumpDipolePURE,"%d\n\n",g_iDumpDipoleSMCount); for (z=0;zGetSize();z2++) { sm = (CSingleMolecule*)g_oaSingleMolecules[m->m_laSingleMolIndex[((CxIntArray*)g_oaDumpDipoleVector[z])->GetAt(z2)]]; for (z3=0;z3m_baAtomIndex.GetSize();z3++) { if (m->m_baAtomIndex[z3] == g_iVirtAtomType) continue; for (z4=0;z4<((CxIntArray*)sm->m_oaAtomOffset[z3])->GetSize();z4++) { ti = ((CxIntArray*)sm->m_oaAtomOffset[z3])->GetAt(z4); fprintf(g_fDumpDipoleXYZ,"%s %12f %12f %12f\n",(const char*)((CAtom*)g_oaAtoms[m->m_baAtomIndex[z3]])->m_sName,m_vaCoords[ti][0]/100.0,m_vaCoords[ti][1]/100.0,m_vaCoords[ti][2]/100.0); } } } } for (z=0;zGetSize();z2++) { sm = (CSingleMolecule*)g_oaSingleMolecules[m->m_laSingleMolIndex[((CxIntArray*)g_oaDumpDipoleVector[z])->GetAt(z2)]]; dc = m_vaCoords[((CxIntArray*)sm->m_oaAtomOffset[m->m_iDipoleCenterType])->GetAt(m->m_iDipoleCenterIndex)]; fprintf(g_fDumpDipoleXYZ,"B %12f %12f %12f\n",dc[0]/100.0,dc[1]/100.0,dc[2]/100.0); fprintf(g_fDumpDipoleXYZ,"B %12f %12f %12f\n",dc[0]/100.0+sm->m_vDipole[0]*g_fDumpDipoleScale,dc[1]/100.0+sm->m_vDipole[1]*g_fDumpDipoleScale,dc[2]/100.0+sm->m_vDipole[2]*g_fDumpDipoleScale); fprintf(g_fDumpDipolePURE,"%s %12f %12f %12f\n",(const char*)((CMolecule*)g_oaMolecules[sm->m_iMolType])->m_sName,sm->m_vDipole[0]*g_fDumpDipoleScale,sm->m_vDipole[1]*g_fDumpDipoleScale,sm->m_vDipole[2]*g_fDumpDipoleScale); } } } } CTimeStep::CTimeStep() { m_pComment = NULL; m_pVolumetricData = NULL; m_pVolumetricDataTimeDev = NULL; m_pCurrentDensity = NULL; m_pPosDomainEngine = NULL; m_vaCoords.SetName("CTimeStep::m_vaCoords"); m_vaCoords_Unfolded.SetName("CTimeStep::m_vaCoords_Unfolded"); m_vaCoords_Original.SetName("CTimeStep::m_vaCoords_Original"); m_vaVelocities.SetName("CTimeStep::m_vaVelocities"); m_vaForces.SetName("CTimeStep::m_vaForces"); m_paLabels.SetName("CTimeStep::m_paLabels"); m_paMol2Types.SetName("CTimeStep::m_paMol2Types"); m_faCharge.SetName("CTimeStep::m_faCharge"); } CTimeStep::~CTimeStep() { /* if (m_pLabels != NULL) delete[] m_pLabels;*/ if (m_pComment != NULL) { delete[] m_pComment; m_pComment = NULL; } if (m_pVolumetricData != NULL) { delete m_pVolumetricData; m_pVolumetricData = NULL; } if (m_pVolumetricDataTimeDev != NULL) { delete m_pVolumetricDataTimeDev; m_pVolumetricDataTimeDev = NULL; } if (m_pCurrentDensity != NULL) { delete m_pCurrentDensity; m_pCurrentDensity = NULL; } } travis-src-190101/src/timestep.h0100777000000000000000000001310013412725651013435 0ustar00/***************************************************************************** TRAVIS - Trajectory Analyzer and Visualizer http://www.travis-analyzer.de/ Copyright (c) 2009-2019 Martin Brehm 2012-2019 Martin Thomas 2016-2019 Sascha Gehrke This file was written by Martin Brehm. --------------------------------------------------------------------------- This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . *****************************************************************************/ #ifndef TIMESTEP_H #define TIMESTEP_H // This must always be the first include directive #include "config.h" #include #include #include "xobject.h" #include "xobarray.h" #include "xdoublearray.h" #include "xwordarray.h" #include "xdvector3.h" #include "xdmatrix3.h" #include "nbsearch.h" #include "backtrace.h" #include "statistics.h" #include "xbytearray.h" #include "atomgroup.h" #include "moltools.h" #include "internalcoord.h" #include "xptrarray.h" #include "xquaternion.h" #include "xdvec3array.h" #include "3df.h" #include "bqb.h" #include "posdomain.h" class CTimeStep : public CxObject { public: void DumpDipoles(); void WritePOV(const char *s); void FoldAtomsPositive(); double FoldedDistance(int i1, int i2); void CenterCOM(); int REC_UniteMolecules(CSingleMolecule *sm, int i0, int depth); void ReadCellVector(FILE *a); void WriteMol2(FILE *a); void CalcMinMax(); bool SkipTimestep(FILE *a); bool ReadTimestep(FILE *a, bool needinfo); bool ReadTimestep(CxMemFile *file); bool ReadMol2(FILE *a, bool needinfo); bool SkipMol2(FILE *a); bool ReadPDB(FILE *a, bool needinfo, CxDVec3Array *v); bool SkipPDB(FILE *a); bool ReadLAMMPS(FILE *a, bool needinfo); bool SkipLAMMPS(FILE *a); bool ReadDLPOLY(FILE *a, bool needinfo); bool SkipDLPOLY(FILE *a); bool ReadAmber(FILE *a, bool needinfo); bool SkipAmber(FILE *a); bool ReadXYZ(FILE *a, bool needinfo, CxDVec3Array *v); bool SkipXYZ(FILE *a); bool ReadCube(FILE *a, bool needinfo); bool ReadCube(CxMemFile *file); bool SkipCube(FILE *a); bool ReadBQB(CBQBFile *source, bool needinfo); bool ReadBQBCubeStep(bool needinfo); bool ReadBQBTrajStep(const std::vector *data, bool needinfo); bool SkipBQB(); bool SkipBQB(CBQBFile *source); bool FetchBQBCompTrajFrame(bool needinfo); void DoubleBox(); void DoubleBoxVelocity(); void DoubleBoxForce(); CTimeStep(); ~CTimeStep(); bool ScanWannier(bool verbose); void CalcMagneticDipoles(); void CalcDipoles(bool verbose); void CalcPolarizabilities(); long ExtractNumber(int i); int GetCommentNumberCount(); // double MolDist(CSingleMolecule *ref, CSingleMolecule *sm2, CNbSearch *nb); // bool CheckIfOrdered(); bool ScanMolecules(); void CalcCenters(); void CalcCenterVelocities(); void RECURSION_ScanMolecules(int i, CxByteArray *ta, CSingleMolecule *sm, int depth, int *stack, unsigned long bmask, bool w); void PrintMegaTree(); void PrintMatrix(bool onlyfirst, bool onlybind); void RECURSION_MegaTree(int i, char* ta, int depth, unsigned long bmask, bool w, int *stack); bool BondRange(int i1, int i2, double *f); bool MirrorBond(int i1, int i2); void FoldMolecules(); void FoldAtoms(); void UniteMolecules(bool verbose); void CenterPos(const CxDVector3 &vec); // void Transform(const CxDMatrix3 &mat); void Transform(const CxDMatrix3 &mat); void Transform(const CxQuaternion &q); void SubVelocities(const CxDVector3 &vec); bool ReadTimestepVel(FILE *a); bool ReadTimestepForce(FILE *a); void WriteTimestep(FILE *a); void WriteTimestepNb(FILE *a, CNbSet *nbs, int singlemol = -1); void ExportSingleMolecule_PDB(CSingleMolecule *sm, const char *s); // void WriteTimestepNb(int refmol, FILE *a); // void GatherNbDiagram(int refmol, CNbSearch *nb); void AddAtoms(); void BuildAtomIndex(); void CopyFrom(CTimeStep *t); // void ScanNeighborhood(int fixmol, int refmol, CNbSearch *nb, CNbSearch *prev); /* void ScanAngle(int fixmol, int refmol, CCondition *co, CNbSearch *prev); void ScanNewNeighborhood(int fixmol, int refmol, CNbSearch *nb, CNbSearch *prev);*/ bool m_bAbortRing; CxDVector3 m_vMin, m_vMax; CxDVec3Array m_vaCoords; CxDVec3Array m_vaCoords_Unfolded; CxDVec3Array m_vaCoords_Original; CxDVec3Array m_vaVelocities; CxDVec3Array m_vaForces; unsigned long m_iConnectedAtoms; unsigned long m_iGesAtomCount; unsigned long m_iGesAtomModulo; char *m_pComment; // char *m_pLabels; CxPtrArray m_paLabels; CxPtrArray m_paMol2Types; CxDoubleArray m_faCharge; // Unit: e CxDVec3Array m_dipoleMoments; // Ref: Atom, Unit: e*pm CxDVec3Array m_totalCurrents; // Unit: MB/pm CxDVec3Array m_magneticDipoleMoments; // Ref: Atom, Unit: MB std::vector m_maQuadTensor; // Ref: Atom, Unit: e*nm^2 (!!!) // int m_iSizeBytes; C3DF *m_pVolumetricData; C3DF *m_pVolumetricDataTimeDev; CxDoubleArray *m_pCurrentDensity; CPosDomainEngine *m_pPosDomainEngine; private: static bool m_bFirst; }; #endif travis-src-190101/src/tools.cpp0100777000000000000000000015464213412725634013320 0ustar00/***************************************************************************** TRAVIS - Trajectory Analyzer and Visualizer http://www.travis-analyzer.de/ Copyright (c) 2009-2019 Martin Brehm 2012-2019 Martin Thomas 2016-2019 Sascha Gehrke This file was written by Martin Brehm. --------------------------------------------------------------------------- This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . *****************************************************************************/ // This must always be the first include directive #include "config.h" #include "tools.h" #include "backtrace.h" #include "xwordarray.h" #include "travis.h" #include "xintarray.h" #ifdef TARGET_WINDOWS #include #include #include HANDLE g_hConsole; #endif #ifdef TARGET_LINUX #include #endif const char *GetRevisionInfo_tools(unsigned int len) { static char buf[256]; GET_REVISION_INFO( buf, len ); return buf; } const char *GetSourceVersion_tools() { static char buf[256]; GET_SOURCE_VERSION( buf ); return buf; } FILE *g_pLogFile; jmp_buf g_JumpBuf; /********* Beginn Quellcode *****************/ #ifdef TARGET_WINDOWS void InitColor() { BTIN; #ifdef USE_COLOR if (g_bNoColor) return; g_hConsole = GetStdHandle(STD_OUTPUT_HANDLE); #endif BTOUT; } void TextColor(int c) { // BTIN; #ifdef USE_COLOR int flag; if (g_bNoColor) return; flag = 0; if ((c & 1) != 0) flag |= FOREGROUND_BLUE; if ((c & 2) != 0) flag |= FOREGROUND_GREEN; if ((c & 4) != 0) flag |= FOREGROUND_RED; if ((c & 8) != 0) flag |= FOREGROUND_INTENSITY; SetConsoleTextAttribute(g_hConsole, (WORD)flag); #endif // BTOUT; } void TextNormal() { // BTIN; #ifdef USE_COLOR if (g_bNoColor) return; SetConsoleTextAttribute(g_hConsole, FOREGROUND_RED|FOREGROUND_GREEN|FOREGROUND_BLUE); #endif // BTOUT; } #elif defined(TARGET_LINUX) void InitColor() { BTIN; #ifdef USE_COLOR #endif BTOUT; } void TextColor(int c) { // BTIN; #ifdef USE_COLOR if (g_bNoColor) return; char command[32]; // sprintf(command, "%c[%d;%d;40m", 0x1B, g_iColorIntensity, c + 30); sprintf(command, "%c[%d;%dm", 0x1B, g_iColorIntensity, c + 30); printf("%s", command); #endif // BTOUT; } void TextNormal() { // BTIN; #ifdef USE_COLOR if (g_bNoColor) return; char command[13]; // sprintf(command, "%c[0;37;40m", 0x1B); sprintf(command, "%c[0;0;0m", 0x1B); printf("%s", command); #endif // BTOUT; } #else void InitColor() { } void TextColor(int c) { UNUSED(c); } void TextNormal() { } #endif char* fgets_bin(char *buf, int n, FILE *a) { char *p; char *r; r = fgets(buf,n,a); if (r == NULL) { buf[0] = 0; return buf; } p = &buf[strlen(buf)-1]; while (((*p == '\r') || (*p == '\n')) && (p > buf)) p--; p += 2; *p = 0; return r; } void LoadPosition() { longjmp(g_JumpBuf,1); } bool AskYesNo(const char *s, bool def, ...) { BTIN; // static char buf[256], obuf[4096]; CxString buf, obuf; const char *p; // va_list args; // va_start (args, def); // vsprintf (obuf,s, args); // obuf.vsprintf(s,args); // va_end (args); #ifdef TARGET_LINUX XVSPRINTF_LINUX(obuf,s,def); #else XVSPRINTF_WINDOWS(obuf,s,def); #endif _again: mprintf("%s",(const char*)obuf); p = obuf; while ((*p == ' ') || (*p == '\n')) p++; inpprintf("! %s\n",p); myget(&buf); /* if (strcmp(buf,"$")==0) { BTOUT; LoadPosition(); }*/ if (strlen(buf)==0) { BTOUT; return def; } if ((mystricmp(buf,"y")==0) || (mystricmp(buf,"yes")==0)) { BTOUT; return true; } if ((mystricmp(buf,"n")==0) || (mystricmp(buf,"no")==0)) { BTOUT; return false; } eprintf("Invalid input. Enter \"y\" or \"n\".\n"); inpprintf("! Invalid input. Enter \"y\" or \"n\".\n"); goto _again; return false; // Never happens ^^ } bool AskYesNo_ND(const char *s, ...) { BTIN; // static char buf[256], obuf[4096]; CxString buf, obuf; const char *p; // va_list args; // va_start (args, s); // vsprintf (obuf,s, args); // obuf.vsprintf(s,args); // va_end (args); #ifdef TARGET_LINUX XVSPRINTF_LINUX(obuf,s,s); #else XVSPRINTF_WINDOWS(obuf,s,s); #endif _again: mprintf("%s",(const char*)obuf); p = obuf; while ((*p == ' ') || (*p == '\n')) p++; inpprintf("! %s\n",p); myget(&buf); /* if (strcmp(buf,"$")==0) { BTOUT; LoadPosition(); }*/ if (strlen(buf)==0) { eprintf("There is no default value. Enter \"y\" or \"n\".\n"); inpprintf("! There is no default value. Enter \"y\" or \"n\".\n"); goto _again; } if ((mystricmp(buf,"y")==0) || (mystricmp(buf,"yes")==0)) { BTOUT; return true; } if ((mystricmp(buf,"n")==0) || (mystricmp(buf,"no")==0)) { BTOUT; return false; } eprintf("Invalid input. Enter \"y\" or \"n\".\n"); inpprintf("! Invalid input. Enter \"y\" or \"n\".\n"); goto _again; return false; // Never happens ^^ } int AskUnsignedInteger(const char *s, int def, ...) { BTIN; int i; // static char buf[256], obuf[4096]; CxString buf, obuf; const char *p; // va_list args; // va_start (args, def); // vsprintf (obuf,s, args); // obuf.vsprintf(s,args); // va_end (args); #ifdef TARGET_LINUX XVSPRINTF_LINUX(obuf,s,def); #else XVSPRINTF_WINDOWS(obuf,s,def); #endif _again: mprintf("%s",(const char*)obuf); p = obuf; while ((*p == ' ') || (*p == '\n')) p++; inpprintf("! %s\n",p); myget(&buf); if (strlen(buf)==0) return def; if (strlen(buf) > 9) goto _invalid; for (i=0;i<(int)strlen(buf);i++) if (strchr("0123456789",buf[i]) == NULL) goto _invalid; i = atoi(buf); if (i != 0) return i; if (strcmp(buf,"0") == 0) return 0; _invalid: eprintf("Invalid input. Enter a non-negative integer number.\n"); inpprintf("! Invalid input. Enter a non-negative integer number.\n"); goto _again; return 0; // Never happens ^^ } int AskInteger(const char *s, int def, ...) { BTIN; int i; // static char buf[256], obuf[4096]; CxString buf, obuf; const char *p; // va_list args; // va_start (args, def); // vsprintf (obuf,s, args); // obuf.vsprintf(s,args); // va_end (args); #ifdef TARGET_LINUX XVSPRINTF_LINUX(obuf,s,def); #else XVSPRINTF_WINDOWS(obuf,s,def); #endif _again: mprintf("%s",(const char*)obuf); p = obuf; while ((*p == ' ') || (*p == '\n')) p++; inpprintf("! %s\n",p); myget(&buf); if (strlen(buf)==0) return def; if (strlen(buf) > 9) goto _invalid; for (i=0;i<(int)strlen(buf);i++) if (strchr("-0123456789",buf[i]) == NULL) goto _invalid; i = atoi(buf); if (i != 0) return i; if (strcmp(buf,"0") == 0) return 0; _invalid: eprintf("Invalid input. Enter an integer number.\n"); inpprintf("! Invalid input. Enter an integer number.\n"); goto _again; return 0; // Never happens ^^ } int AskUnsignedInteger_ND(const char *s, ...) { BTIN; int i; // static char buf[256], obuf[4096]; CxString buf, obuf; const char *p; // va_list args; // va_start (args, s); // vsprintf (obuf,s, args); // obuf.vsprintf(s,args); // va_end (args); #ifdef TARGET_LINUX XVSPRINTF_LINUX(obuf,s,s); #else XVSPRINTF_WINDOWS(obuf,s,s); #endif _again: mprintf("%s",(const char*)obuf); p = obuf; while ((*p == ' ') || (*p == '\n')) p++; inpprintf("! %s\n",p); myget(&buf); if (strlen(buf) == 0) { eprintf("There is no default value. Enter a positive integer number.\n"); inpprintf("! There is no default value. Enter a positive integer number.\n"); goto _again; } if (strlen(buf) > 9) goto _invalid; for (i=0;i<(int)strlen(buf);i++) if (strchr("0123456789",buf[i]) == NULL) goto _invalid; i = atoi(buf); if (i != 0) return i; if (strcmp(buf,"0") == 0) return 0; _invalid: eprintf("Invalid input. Enter a positive integer number.\n"); inpprintf("! Invalid input. Enter a positive integer number.\n"); goto _again; return 0; // Never happens ^^ } int AskRangeInteger(const char *s, int mini, int maxi, int def, ...) { BTIN; int i; // static char buf[256], obuf[4096]; CxString buf, obuf; const char *p; // va_list args; // va_start (args, def); // vsprintf (obuf,s, args); // obuf.vsprintf(s,args); // va_end (args); #ifdef TARGET_LINUX XVSPRINTF_LINUX(obuf,s,def); #else XVSPRINTF_WINDOWS(obuf,s,def); #endif _again: mprintf("%s",(const char*)obuf); p = obuf; while ((*p == ' ') || (*p == '\n')) p++; inpprintf("! %s\n",p); myget(&buf); if (strlen(buf)==0) return def; if (strlen(buf) > 9) goto _invalid; for (i=0;i<(int)strlen(buf);i++) if (strchr("-0123456789",buf[i]) == NULL) goto _invalid; i = atoi(buf); if ((i != 0) && (i >= mini) && (i <= maxi)) return i; if ((strcmp(buf,"0") == 0) && (mini <= 0) && (maxi >= 0)) return 0; _invalid: eprintf("Invalid input. Enter an integer number between %d and %d.\n",mini,maxi); inpprintf("! Invalid input. Enter an integer number between %d and %d.\n",mini,maxi); goto _again; return 0; // Never happens ^^ } double AskRangeFloat(const char *s, double mini, double maxi, double def, ...) { BTIN; int i; double f; // static char buf[256], obuf[4096]; CxString buf, obuf; const char *p; // va_list args; // va_start (args, def); // vsprintf (obuf,s, args); // obuf.vsprintf(s,args); // va_end (args); #ifdef TARGET_LINUX XVSPRINTF_LINUX(obuf,s,def); #else XVSPRINTF_WINDOWS(obuf,s,def); #endif _again: mprintf("%s",(const char*)obuf); p = obuf; while ((*p == ' ') || (*p == '\n')) p++; inpprintf("! %s\n",p); myget(&buf); if (strlen(buf)==0) return def; if (strlen(buf) > 15) goto _invalid; for (i=0;i<(int)strlen(buf);i++) if (strchr("+-0123456789.eE",buf[i]) == NULL) goto _invalid; f = atof(buf); if ((f > 0) && (f >= mini) && (f <= maxi)) return f; if (((strcmp(buf,"0")==0) || (strcmp(buf,"0.0")==0)) && (mini <= 0.0) && (maxi >= 0.0)) return 0; _invalid: eprintf("Invalid input. Enter a real number between %f and %f.\n",mini,maxi); inpprintf("! Invalid input. Enter a real number between %f and %f.\n",mini,maxi); goto _again; return 0; // Never happens ^^ } int AskRangeInteger_ND(const char *s, int mini, int maxi, ...) { BTIN; int i; // static char buf[256], obuf[4096]; CxString buf, obuf; const char *p; // va_list args; // va_start (args, maxi); // vsprintf (obuf,s, args); // obuf.vsprintf(s,args); // va_end (args); #ifdef TARGET_LINUX XVSPRINTF_LINUX(obuf,s,maxi); #else XVSPRINTF_WINDOWS(obuf,s,maxi); #endif _again: mprintf("%s",(const char*)obuf); p = obuf; while ((*p == ' ') || (*p == '\n')) p++; inpprintf("! %s\n",p); myget(&buf); if (strlen(buf) == 0) { eprintf("There is no default value. Enter an integer number between %d and %d.\n",mini,maxi); inpprintf("! Invalid input. Enter an integer number between %d and %d.\n",mini,maxi); goto _again; } if (strlen(buf) > 9) goto _invalid; for (i=0;i<(int)strlen(buf);i++) if (strchr("-0123456789",buf[i]) == NULL) goto _invalid; i = atoi(buf); if ((i > 0) && (i >= mini) && (i <= maxi)) return i; if ((strcmp(buf,"0")==0) && (mini <= 0) && (maxi >= 0)) return 0; _invalid: eprintf("Invalid input. Enter an integer number between %d and %d.\n",mini,maxi); inpprintf("! Invalid input. Enter an integer number between %d and %d.\n",mini,maxi); goto _again; return 0; // Never happens ^^ } void AskString_ND(const char *s, CxString *buf, ...) { BTIN; // static char obuf[4096]; CxString obuf; const char *p; // va_list args; // va_start (args, buf); // vsprintf (obuf,s, args); // obuf.vsprintf(s,args); // va_end (args); #ifdef TARGET_LINUX XVSPRINTF_LINUX(obuf,s,buf); #else XVSPRINTF_WINDOWS(obuf,s,buf); #endif _again: mprintf("%s",(const char*)obuf); p = obuf; while ((*p == ' ') || (*p == '\n')) p++; inpprintf("! %s\n",p); myget(buf); /* if (strcmp(buf,"$")==0) { BTOUT; LoadPosition(); }*/ if (strlen(*buf) == 0) { eprintf("There is no default value. Enter a character string.\n"); inpprintf("! There is no default value. Enter a character string.\n"); goto _again; } BTOUT; return; } void AskString(const char *s, CxString *buf, const char *def, ...) { BTIN; // static char obuf[4096]; CxString obuf; const char *p; // va_list args; // va_start (args, def); // vsprintf (obuf,s, args); // obuf.vsprintf(s,args); // va_end (args); #ifdef TARGET_LINUX XVSPRINTF_LINUX(obuf,s,def); #else XVSPRINTF_WINDOWS(obuf,s,def); #endif mprintf("%s",(const char*)obuf); p = obuf; while ((*p == ' ') || (*p == '\n')) p++; inpprintf("! %s\n",p); myget(buf); /* if (strcmp(buf,"$")==0) { BTOUT; LoadPosition(); }*/ if (strlen(*buf) == 0) { buf->strcpy(def); BTOUT; return; } BTOUT; return; } double AskFloat_ND(const char *s, ...) { BTIN; double d; // static char buf[256], obuf[4096]; CxString buf, obuf; const char *p; // va_list args; // va_start (args, s); // vsprintf (obuf,s, args); // obuf.vsprintf(s,args); // va_end (args); #ifdef TARGET_LINUX XVSPRINTF_LINUX(obuf,s,s); #else XVSPRINTF_WINDOWS(obuf,s,s); #endif _again: mprintf("%s",(const char*)obuf); p = obuf; while ((*p == ' ') || (*p == '\n')) p++; inpprintf("! %s\n",p); myget(&buf); /* if (strcmp(buf,"$")==0) { BTOUT; LoadPosition(); }*/ if (strlen(buf)==0) { eprintf("There is no default value. Enter a real number.\n"); inpprintf("! There is no default value. Enter a real number.\n"); goto _again; } d = atof(buf); if (d!=0) { BTOUT; return d; } if (strspn(buf,"0.") == strlen(buf)) // if (strcmp(buf,"0")==0) { BTOUT; return 0; } eprintf("Invalid input. Enter a real number.\n"); inpprintf("! Invalid input. Enter a real number.\n"); goto _again; return 0; // Never happens ^^ } double AskFloat(const char *s, double def, ...) { BTIN; double d; // static char buf[256], obuf[4096]; CxString buf, obuf; const char *p; // va_list args; // va_start (args, def); // vsprintf (obuf,s, args); // obuf.vsprintf(s,args); // va_end (args); #ifdef TARGET_LINUX XVSPRINTF_LINUX(obuf,s,def); #else XVSPRINTF_WINDOWS(obuf,s,def); #endif _again: mprintf("%s",(const char*)obuf); p = obuf; while ((*p == ' ') || (*p == '\n')) p++; inpprintf("! %s\n",p); myget(&buf); /* if (strcmp(buf,"$")==0) { BTOUT; LoadPosition(); }*/ if (strlen(buf)==0) { BTOUT; return def; } d = atof(buf); if (d!=0) { BTOUT; return d; } if (strspn(buf,"0.") == strlen(buf)) // if (strcmp(buf,"0")==0) { BTOUT; return 0; } eprintf("Invalid input. Enter a real number.\n"); inpprintf("! Invalid input. Enter a real number.\n"); goto _again; return 0; // Never happens ^^ } int AskMolecule(const char *s) { int z; // static char buf[4096], buf2[256]; CxString buf, buf2; // sprintf(buf,"%s (",s); buf.sprintf("%s (",s); for (z=0;zm_sName,z+1); // strcat(buf,buf2); // if (z < g_oaMolecules.GetSize()-1) // strcat(buf,", "); buf2.sprintf("%s=%d",((CMolecule*)g_oaMolecules[z])->m_sName,z+1); buf.strcat(buf2); if (z < g_oaMolecules.GetSize()-1) buf.strcat(", "); } // strcat(buf,")? "); buf.strcat(")? "); return AskRangeInteger_ND("%s",1,g_oaMolecules.GetSize(),(const char*)buf) - 1; } int HalfBox() { BTIN; int i; i = 999999; if (g_bPeriodic) { if (g_bBoxNonOrtho) { i = ((int)(g_fBoxMinDiam/200))*100; } else { if (g_bPeriodicX && (g_fBoxX/2.0 < i)) i = ((int)(g_fBoxX/200))*100; if (g_bPeriodicY && (g_fBoxY/2.0 < i)) i = ((int)(g_fBoxY/200))*100; if (g_bPeriodicZ && (g_fBoxZ/2.0 < i)) i = ((int)(g_fBoxZ/200))*100; } } else { if ((g_TimeStep.m_vMax[0]-g_TimeStep.m_vMin[0])/2.0 < i) i = ((int)((g_TimeStep.m_vMax[0]-g_TimeStep.m_vMin[0])/200))*100; if ((g_TimeStep.m_vMax[1]-g_TimeStep.m_vMin[1])/2.0 < i) i = ((int)((g_TimeStep.m_vMax[1]-g_TimeStep.m_vMin[1])/200))*100; if ((g_TimeStep.m_vMax[2]-g_TimeStep.m_vMin[2])/2.0 < i) i = ((int)((g_TimeStep.m_vMax[2]-g_TimeStep.m_vMin[2])/200))*100; } BTOUT; return i; } double HalfBox_Exact() { double f; f = 1.0e30; if (g_bPeriodic) { if (g_bBoxNonOrtho) { f = g_fBoxMinDiam; } else { if (g_bPeriodicX && (g_fBoxX/2.0 < f)) f = g_fBoxX; if (g_bPeriodicY && (g_fBoxY/2.0 < f)) f = g_fBoxY; if (g_bPeriodicZ && (g_fBoxZ/2.0 < f)) f = g_fBoxZ; } } return f; } int HalfBoxSq3() { BTIN; int i; i = 999999; if (g_bPeriodic) { if (g_bPeriodicX && (g_fBoxX/2.0*sqrt(3.0) < i)) i = ((int)(g_fBoxX/200*sqrt(3.0)))*100; if (g_bPeriodicY && (g_fBoxY/2.0*sqrt(3.0) < i)) i = ((int)(g_fBoxY/200*sqrt(3.0)))*100; if (g_bPeriodicZ && (g_fBoxZ/2.0*sqrt(3.0) < i)) i = ((int)(g_fBoxZ/200*sqrt(3.0)))*100; } else { if ((g_TimeStep.m_vMax[0]-g_TimeStep.m_vMin[0])/2.0*sqrt(3.0) < i) i = ((int)((g_TimeStep.m_vMax[0]-g_TimeStep.m_vMin[0])/200*sqrt(3.0)))*100; if ((g_TimeStep.m_vMax[1]-g_TimeStep.m_vMin[1])/2.0*sqrt(3.0) < i) i = ((int)((g_TimeStep.m_vMax[1]-g_TimeStep.m_vMin[1])/200*sqrt(3.0)))*100; if ((g_TimeStep.m_vMax[2]-g_TimeStep.m_vMin[2])/2.0*sqrt(3.0) < i) i = ((int)((g_TimeStep.m_vMax[2]-g_TimeStep.m_vMin[2])/200*sqrt(3.0)))*100; } BTOUT; return i; } void mprintf(const char *s, ...) { // static char buffer[32768]; CxString buffer; // va_list args; int z, z2, zold; // va_start (args, s); /*#ifdef TARGET_WINDOWS _vsnprintf(buffer,32767,s,args); #elif defined(TARGET_LINUX) vsnprintf(buffer,32767,s,args); #else vsprintf(buffer,s,args); #endif*/ // buffer.vsprintf(s,args); #ifdef TARGET_LINUX XVSPRINTF_LINUX(buffer,s,s); #else XVSPRINTF_WINDOWS(buffer,s,s); #endif // va_end (args); if (g_bSaxonize) { buffer.SetBufSize(buffer.GetLength()*2); saxonize(buffer.GetWritePointer()); } if (g_bGlobalPsycho) { zold = -1; for (z=0;z<(int)strlen(buffer);z++) { do { z2 = rand()%8+1; } while (zold == z2); zold = z2; switch(z2) { case 0: TextColor(GREY); break; case 1: TextColor(BLUE); break; case 2: TextColor(GREEN); break; case 3: TextColor(CYAN); break; case 4: TextColor(RED); break; case 5: TextColor(PINK); break; case 6: TextColor(YELLOW); break; case 7: TextColor(WHITE); break; case 8: TextNormal(); break; } printf("%c",buffer[z]); } TextNormal(); } else printf("%s",(const char*)buffer); fflush(stdout); if (g_pLogFile != NULL) { mfprintf(g_pLogFile,"%s",(const char*)buffer); fflush(g_pLogFile); } } void mprintf_nos(const char *s, ...) { CxString buffer; if (g_pLogFile == NULL) return; #ifdef TARGET_LINUX XVSPRINTF_LINUX(buffer,s,s); #else XVSPRINTF_WINDOWS(buffer,s,s); #endif if (g_bSaxonize) { buffer.SetBufSize(buffer.GetLength()*2); saxonize(buffer.GetWritePointer()); } mfprintf(g_pLogFile,"%s",(const char*)buffer); fflush(g_pLogFile); } void mfprintf(FILE *a, const char *s, ...) { va_list args; int i; va_start (args, s); i = vfprintf(a,s,args); if (g_bCheckWrite && ((i < 0) || (ferror(a) != 0))) { #ifdef TARGET_LINUX char buf[512], buf2[512]; snprintf(buf, sizeof(buf), "/proc/self/fd/%d", fileno(a)); memset(buf2,0,512); if (readlink(buf, buf2, sizeof(buf2)) > 0) { eprintf("\nError writing data to file \"%s\".\n",buf2); } else { eprintf("\nError writing data to file.\n"); } #else eprintf("\nError writing data to file.\n"); #endif eprintf("vfprintf returned %d. ferror returned %d. Errno=%d.\n",i,ferror(a),errno); eprintf("System error message: \"%s\".\n\n",strerror(errno)); abort(); } va_end (args); // fflush(a); } void inpprintf(const char *s, ...) { va_list args; if (g_fInput != NULL) { va_start(args, s); vfprintf(g_fInput,s,args); va_end(args); fflush(g_fInput); } } void saxonize(char *buf) { char tbuf[32768], *p, *q, *d; bool num, beg; int length; strcpy(tbuf,buf); p = tbuf; q = tbuf; d = buf; while (*q != 0) { while (*p == ' ') { p++; *d = ' '; d++; } q = p; num = false; while ((*q != ' ') && (*q != 0)) { if (isdigit(*q) || (*q == '[') || (*q == '\\') || (*q == '~')) num = true; q++; } if (num) { while (p != q) { *d = *p; d++; p++; } continue; } length = (int)(q-p); beg = true; while (p != q) { switch(*p) { case 'A': if (beg && (tolower(*(p+1)) != 'r')) *d = UML_AE; else *d = *p; break; case 'a': if (beg && (tolower(*(p+1)) != 'r')) *d = UML_ae; else *d = *p; break; case 'c': if (beg) { if ((tolower(*(p+1)) == 'e') || (tolower(*(p+1)) == 'i')) *d = 's'; else if (tolower(*(p+1)) == 'h') { *(d++) = 's'; *d = 'c'; } else *d = 'g'; } else if (p+1 == q) *d = 'g'; else if ((tolower(*(p+1)) == 'a') || (tolower(*(p+1)) == 'o') || (tolower(*(p+1)) == 'u')) *d = 'g'; else if ((tolower(*(p+1)) == 'e') || (tolower(*(p+1)) == 'i')) *d = 's'; else if (tolower(*(p+1)) != 'h') *d = 'g'; else *d = *p; break; case 'C': if (beg) { if ((tolower(*(p+1)) == 'e') || (tolower(*(p+1)) == 'i')) *d = 'S'; else if (tolower(*(p+1)) == 'h') { *(d++) = 'S'; *d = 'c'; } else *d = 'G'; } else if (p+1 == q) *d = 'G'; else if ((tolower(*(p+1)) == 'a') || (tolower(*(p+1)) == 'o') || (tolower(*(p+1)) == 'u')) *d = 'G'; else if ((tolower(*(p+1)) == 'e') || (tolower(*(p+1)) == 'i')) *d = 'S'; else if (tolower(*(p+1)) != 'h') *d = 'G'; else *d = *p; break; case 'E': if (beg) *d = UML_AE; else *d = *p; break; case 'e': if (beg) *d = UML_ae; else *d = *p; break; case 'i': if (tolower(*(p+1)) == 'g') { *(d++) = 'i'; *(d++) = 's'; *(d++) = 'c'; *d = 'h'; p++; } else if ((tolower(*(p+1)) == 'c') && (tolower(*(p+2)) == 'h')) { *(d++) = 'i'; *(d++) = 'd'; *(d++) = 's'; *(d++) = 'c'; *d = 'h'; p+=2; } else *d = *p; break; case 'I': if (tolower(*(p+1)) == 'g') { *(d++) = 'I'; *(d++) = 'S'; *(d++) = 'C'; *d = 'H'; p++; } else if ((tolower(*(p+1)) == 'c') && (tolower(*(p+2)) == 'h')) { *(d++) = 'I'; *(d++) = 'D'; *(d++) = 'S'; *(d++) = 'C'; *d = 'H'; p+=2; } else *d = *p; break; case 'k': *d = 'g'; break; case 'K': *d = 'G'; break; case 'p': *d = 'b'; break; case 'P': *d = 'B'; break; case 'q': if (tolower(*(p+1)) == 'u') { *(d++) = 'g'; *d = 'w'; p++; } else *d = *p; break; case 'Q': if (tolower(*(p+1)) == 'u') { *(d++) = 'G'; *d = 'w'; p++; } else *d = *p; break; case 's': if ((*(p+1) == 't') && beg) { *(d++) = 's'; *(d++) = 'c'; *(d++) = 'h'; *d = 'd'; p++; } else if ((*(p+1) == 'p') && beg) { *(d++) = 's'; *(d++) = 'c'; *(d++) = 'h'; *d = 'b'; p++; } else *d = *p; break; case 'S': if ((*(p+1) == 't') && beg) { *(d++) = 'S'; *(d++) = 'c'; *(d++) = 'h'; *d = 'd'; p++; } else if ((*(p+1) == 'p') && beg) { *(d++) = 'S'; *(d++) = 'c'; *(d++) = 'h'; *d = 'b'; p++; } else *d = *p; break; case 't': if ((tolower(*(p+1)) == 'i') && ((tolower(*(p+2)) == 'a') || (tolower(*(p+2)) == 'e') ||(tolower(*(p+2)) == 'i') || (tolower(*(p+2)) == 'o') || (tolower(*(p+2)) == 'u'))) { *(d++) = 's'; *(d++) = 'c'; *(d++) = 'h'; *d = 'i'; p++; } else if (beg && (tolower(*(p+1)) == 'h')) { *d = 'd'; p++; } else *d = 'd'; break; case 'T': if ((tolower(*(p+1)) == 'i') && ((tolower(*(p+2)) == 'a') || (tolower(*(p+2)) == 'e') ||(tolower(*(p+2)) == 'i') || (tolower(*(p+2)) == 'o') || (tolower(*(p+2)) == 'u'))) { *(d++) = 'S'; *(d++) = 'C'; *(d++) = 'H'; *d = 'I'; p++; } else if (beg && (tolower(*(p+1)) == 'h')) { *d = 'D'; p++; } else *d = 'D'; break; case 'u': if ((beg) && ((tolower(*(p+1)) == 's') || ((tolower(*(p+1)) == 'n') && (tolower(*(p+2)) == 'i')))) { *(d++) = 'j'; *(d++) = 'u'; *d = 'h'; } else *d = *p; break; case 'U': if ((beg) && ((tolower(*(p+1)) == 's') || ((tolower(*(p+1)) == 'n') && (tolower(*(p+2)) == 'i')))) { *(d++) = 'J'; *(d++) = 'u'; *d = 'h'; } else *d = *p; break; case 'x': if (length > 2) { *(d++) = 'g'; *d = 's'; } else *d = *p; break; case 'X': if (length > 2) { *(d++) = 'G'; *d = 'S'; } else *d = *p; break; case 'y': if ((p+1 == q) && (length > 2)) { *(d++) = 'i'; *(d++) = 'e'; *d = 'h'; } else *d = *p; break; case 'Y': if ((p+1 == q) && (length > 2)) { *(d++) = 'I'; *(d++) = 'E'; *d = 'H'; } else *d = *p; break; default: *d = *p; } d++; p++; beg = false; } } *d = 0; } void mprintf(int color, const char *s, ...) { // char buffer[32768]; CxString buffer; // va_list args; int z, z2, zold; // va_start (args, s); /*#ifdef TARGET_WINDOWS _vsnprintf(buffer,32768,s,args); #elif defined(TARGET_LINUX) vsnprintf(buffer,32768,s,args); #else vsprintf(buffer,s,args); #endif*/ // buffer.vsprintf(s,args); // va_end (args); #ifdef TARGET_LINUX XVSPRINTF_LINUX(buffer,s,s); #else XVSPRINTF_WINDOWS(buffer,s,s); #endif if (g_bSaxonize) { buffer.SetBufSize(buffer.GetLength()*2); saxonize(buffer.GetWritePointer()); } if (g_bGlobalPsycho) { zold = -1; for (z=0;z<(int)strlen(buffer);z++) { do { z2 = rand()%8+1; } while (zold == z2); zold = z2; switch(z2) { case 0: TextColor(GREY); break; case 1: TextColor(BLUE); break; case 2: TextColor(GREEN); break; case 3: TextColor(CYAN); break; case 4: TextColor(RED); break; case 5: TextColor(PINK); break; case 6: TextColor(YELLOW); break; case 7: TextColor(WHITE); break; case 8: TextNormal(); break; } printf("%c",buffer[z]); } } else { TextColor(color); printf("%s",(const char*)buffer); } TextNormal(); fflush(stdout); if (g_pLogFile != NULL) { mfprintf(g_pLogFile,"%s",(const char*)buffer); fflush(g_pLogFile); } } void bprintf(const char *s, ...) { // char buffer[32768]; CxString buffer; // va_list args; int z, z2, zold; // va_start (args, s); /*#ifdef TARGET_WINDOWS _vsnprintf(buffer,32768,s,args); #elif defined(TARGET_LINUX) vsnprintf(buffer,32768,s,args); #else vsprintf(buffer,s,args); #endif*/ // buffer.vsprintf(s,args); // va_end (args); #ifdef TARGET_LINUX XVSPRINTF_LINUX(buffer,s,s); #else XVSPRINTF_WINDOWS(buffer,s,s); #endif if (g_bSaxonize) { buffer.SetBufSize(buffer.GetLength()*2); saxonize(buffer.GetWritePointer()); } if (g_bGlobalPsycho) { zold = -1; for (z=0;z<(int)strlen(buffer);z++) { do { z2 = rand()%8+1; } while (zold == z2); zold = z2; switch(z2) { case 0: TextColor(GREY); break; case 1: TextColor(BLUE); break; case 2: TextColor(GREEN); break; case 3: TextColor(CYAN); break; case 4: TextColor(RED); break; case 5: TextColor(PINK); break; case 6: TextColor(YELLOW); break; case 7: TextColor(WHITE); break; case 8: TextNormal(); break; } printf("%c",buffer[z]); } } else { TextColor(WHITE); printf("%s",(const char*)buffer); } TextNormal(); fflush(stdout); if (g_pLogFile != NULL) { mfprintf(g_pLogFile,"%s",(const char*)buffer); fflush(g_pLogFile); } } void eprintf(const char *s, ...) { // char buffer[32768]; CxString buffer; // va_list args; // int z, z2, zold; // va_start (args, s); /*#ifdef TARGET_WINDOWS _vsnprintf(buffer,32768,s,args); #elif defined(TARGET_LINUX) vsnprintf(buffer,32768,s,args); #else vsprintf(buffer,s,args); #endif*/ // buffer.vsprintf(s,args); // va_end (args); #ifdef TARGET_LINUX XVSPRINTF_LINUX(buffer,s,s); #else XVSPRINTF_WINDOWS(buffer,s,s); #endif /* if (g_bGlobalPsycho) { zold = -1; for (z=0;z<(int)strlen(buffer);z++) { do { z2 = rand()%8+1; } while (zold == z2); zold = z2; switch(z2) { case 0: TextColor(GREY); break; case 1: TextColor(BLUE); break; case 2: TextColor(GREEN); break; case 3: TextColor(CYAN); break; case 4: TextColor(RED); break; case 5: TextColor(PINK); break; case 6: TextColor(YELLOW); break; case 7: TextColor(WHITE); break; case 8: TextNormal(); break; } printf("%c",buffer[z]); } } else*/ { TextColor(RED); // fprintf(stderr,buffer); printf("%s",(const char*)buffer); } TextNormal(); // fflush(stderr); fflush(stdout); if (g_pLogFile != NULL) { fprintf(g_pLogFile,"%s",(const char*)buffer); fflush(g_pLogFile); } } /* void myget(char *s) { BTIN; FILE *t; char buf[256]; _beg: if (g_fInputFile != NULL) { if (fgets(s,200,g_fInputFile) == NULL) { if (feof(g_fInputFile)) { eprintf("\nEnd of input file reached. Switching to keyboard input.\n\n"); fclose(g_fInputFile); g_fInputFile = NULL; g_bInputRedirected = false; if (AskYesNo(" Do you want to write an input file for this session (y/n)? [yes] ",true)) { mprintf(" Copying contents of old input file to input.txt ...\n"); FreeFileName("intmp.txt"); if (!FileExist(g_sInputFile)) { eprintf("Error: Input file \"%s\" is no longer available.\n\n",g_sInputFile); eprintf("*** Please note that the input file must not be named \"intmp.txt\". ***\n\n"); abort(); } rename(g_sInputFile,"intmp.txt"); t = fopen("intmp.txt","rt"); if (t == NULL) { eprintf("Error: Could not rename input file \"%s\" to \"intmp.txt\".\n\n",g_sInputFile); abort(); } g_fInput = OpenFileWrite("input.txt",true); while (!feof(t)) { fgets(buf,256,t); if (feof(t)) break; buf[strlen(buf)-1] = 0; fprintf(g_fInput,"%s\n",buf); } fclose(t); } mprintf("Please continue with answering the last question above.\n\n"); goto _beg; } else { eprintf("\nError while reading input file.\n\n"); mprintf("\"End Of File\" has not been signaled. Some other weird error ^^\n\n"); mprintf("TRAVIS has to stop here, sorry.\n\n"); exit(0); } } } else { if (fgets(s,200,stdin) == NULL) { eprintf("\nError while reading input from stdin (probably end of input file reached).\n\n"); mprintf("Your redirected input file seems to have not enough lines.\n"); mprintf("The Operating System does not allow console applications with redirected input\n"); mprintf("to access the keyboard, so you cannot enter the missing lines per hand.\n\n"); mprintf("TRAVIS has to stop here. I'm sorry. Use the -i flag instead for reading input files.\n\n"); exit(0); } } if (strlen(s) > 195) eprintf(" (Input line too long, truncated to 200 characters) "); if (strlen(s) != 0) s[strlen(s)-1] = 0; if (g_bInputRedirected) { if (strlen(s)==0) { mprintf(WHITE,"\n"); return; } if (s[0] == '!') goto _beg; // Kommentar im Input File mprintf(WHITE,"%s\n",s); } else { if (g_pLogFile != NULL) { fprintf(g_pLogFile,"%s\n",s); fflush(g_pLogFile); } if (g_fInput != NULL) { fprintf(g_fInput,"%s\n",s); fflush(g_fInput); } } BTOUT; } */ void myget(CxString *st) { BTIN; FILE *t; st->SetBufSize(4096); _beg: if (g_fInputFile != NULL) { // if (fgets(st,4095,g_fInputFile) == NULL) if (st->fgets(4095,g_fInputFile) == NULL) { if (feof(g_fInputFile)) { eprintf("\nEnd of input file reached. Switching to keyboard input.\n\n"); fclose(g_fInputFile); g_fInputFile = NULL; g_bInputRedirected = false; if (AskYesNo(" Do you want to write an input file for this session (y/n)? [yes] ",true)) { mprintf(" Copying contents of old input file to input.txt ...\n"); FreeFileName("intmp.txt"); if (!FileExist(g_sInputFile)) { eprintf("Error: Input file \"%s\" is no longer available.\n\n",g_sInputFile); eprintf("*** Please note that the input file must not be named \"intmp.txt\". ***\n\n"); abort(); } rename(g_sInputFile,"intmp.txt"); t = fopen("intmp.txt","rt"); if (t == NULL) { eprintf("Error: Could not rename input file \"%s\" to \"intmp.txt\".\n\n",g_sInputFile); abort(); } g_fInput = OpenFileWrite("input.txt",true); char buf[4096]; while (!feof(t)) { (void)fgets(buf,4095,t); if (feof(t)) break; buf[strlen(buf)-1] = 0; fprintf(g_fInput,"%s\n",buf); } fclose(t); } mprintf("Please continue with answering the last question above.\n\n"); goto _beg; } else { eprintf("\nError while reading input file.\n\n"); mprintf("\"End Of File\" has not been signaled. Some other weird error ^^\n\n"); mprintf("TRAVIS has to stop here, sorry.\n\n"); exit(0); } } } else { // if (fgets(st,4095,stdin) == NULL) if (st->fgets(4095,stdin) == NULL) { eprintf("\nError while reading input from stdin (probably end of input file reached).\n\n"); mprintf("Your redirected input file seems to have not enough lines.\n"); mprintf("The Operating System does not allow console applications with redirected input\n"); mprintf("to access the keyboard, so you cannot enter the missing lines per hand.\n\n"); mprintf("TRAVIS has to stop here. I'm sorry. Use the -i flag instead for reading input files.\n\n"); exit(0); } } if (st->GetLength() >= 4090) eprintf(" (Input line too long, truncated to 4090 characters) "); if (st->GetLength() != 0) (*st)(st->GetLength()-1) = 0; if (g_bInputRedirected) { if (st->GetLength() == 0) { mprintf(WHITE,"\n"); return; } if ((*st)[0] == '!') goto _beg; // Kommentar im Input File mprintf(WHITE,"%s\n",(const char*)(*st)); } else { if (g_pLogFile != NULL) { fprintf(g_pLogFile,"%s\n",(const char*)(*st)); fflush(g_pLogFile); } if (g_fInput != NULL) { fprintf(g_fInput,"%s\n",(const char*)(*st)); fflush(g_fInput); } } BTOUT; } bool FileExist(const char *s) { FILE *a; a = fopen(s,"rb"); if (a == NULL) return false; fclose(a); return true; } void FreeFileName(const char *s) { BTIN; // char tbuf[256], buf[256]; CxString tbuf, buf; const char *p, *q; int z; if (FileExist(s)) { p = strrchr(s,'\\'); if (p == NULL) p = strrchr(s,'/'); if (p != NULL) { p++; // memcpy(tbuf,s,p-s); // tbuf[p-s] = 0; tbuf.SetBufSize((int)(p-s+1)); tbuf.memcpy(s,(int)(p-s)); tbuf((int)(p-s)) = 0; } q = strrchr(s,'.'); z = 1; while (true) { if (p != NULL) // sprintf(buf,"%s#%d#%s",tbuf,z,p); buf.sprintf("%s#%d#%s",(const char*)tbuf,z,p); else // sprintf(buf,"#%d#%s",z,s); buf.sprintf("#%d#%s",z,s); if (!FileExist(buf)) { if (strlen(buf) > 20) { if (q != NULL) mprintf(GREY,"[Renaming existing File %s to #%d#[...]%s ...",s,z,q); else mprintf(GREY,"[Renaming existing File %s to #%d#[...] ...",s,z); } else mprintf(GREY,"[Renaming existing File %s to %s ...",s,(const char*)buf); if (rename(s,buf)!=0) { eprintf("Error.]\n"); eprintf("Could not rename file \"%s\".\n",s); eprintf("Make sure you have writing permission and the file is not opened by any external program.\n\n"); eprintf("Aborting Program Execution.\n"); BTOUT; abort(); } if (FileExist(s)) { eprintf("Error.]\n"); eprintf("File \"%s\" still existed after attempt to rename.\n",s); eprintf("Make sure you have writing permission and the file is not opened by any external program.\n\n"); eprintf("Aborting Program Execution.\n"); BTOUT; abort(); } mprintf(GREY,"OK.]\n"); BTOUT; return; } z++; if (z > 10000) { eprintf("Error.]\n"); eprintf("File %s has more than 10000 backups.\nHint: rm \\#* ;-)\n\nAborting Program Execution.\n",s); BTOUT; abort(); } } } BTOUT; } /*void FreeFileName(char *pre, char *s, char *post) { BTIN; char buf[256]; sprintf(buf,"%s%s%s",pre,s,post); FreeFileName(buf); BTOUT; }*/ int mystricmp(const char *s1, const char *s2) { BXIN; char *buf, *buf2; unsigned long z, i; try { buf = new char[strlen(s1)+1]; } catch(...) { buf = NULL; } if (buf == NULL) NewException((double)(strlen(s1)+1)*sizeof(char),__FILE__,__LINE__,__PRETTY_FUNCTION__); try { buf2 = new char[strlen(s2)+1]; } catch(...) { buf2 = NULL; } if (buf2 == NULL) NewException((double)(strlen(s2)+1)*sizeof(char),__FILE__,__LINE__,__PRETTY_FUNCTION__); for (z=0;z= 31) { eprintf("ParseIntList: Entry too long (%ld >= 31).\n",q-p); return false; } memcpy(buf,p,q-p); buf[q-p] = 0; if (m) i2 = atoi(buf); else i = atoi(buf); } else if (*q == '-') { if (i == -1) { eprintf("Error: \"-\" without preceding number.\n"); BTOUT; return false; } m = true; q++; } else if (*q == ',') { if (m) { if (i2 == -1) { eprintf("ParseIntList(): Internal error.\n"); abort(); } for (z=i;z<=i2;z++) la->Add(z); } else la->Add(i); m = false; i = -1; i2 = -1; q++; } else { eprintf("Error: Invalid character \"%c\" while parsing integer list.\n",*q); return false; } // _end: p = q; } if (m) { for (z=i;z<=i2;z++) la->Add(z); } else if (i != -1) la->Add(i); BTOUT; return true; } bool ParseIntList(const char *s, std::vector &la) { BTIN; const char *p, *q; char buf[32]; int i, i2, z; bool m; i2 = -1; p = s; i = -1; m = false; while (*p != 0) { while ((*p == ' ') && (*p != 0)) p++; q = p; if (isdigit(*q)) { while (isdigit(*q)) q++; if (q-p >= 31) { eprintf("ParseIntList: Entry too long (%ld >= 31).\n",q-p); return false; } memcpy(buf,p,q-p); buf[q-p] = 0; if (m) i2 = atoi(buf); else i = atoi(buf); } else if (*q == '-') { if (i == -1) { eprintf("Error: \"-\" without preceding number.\n"); BTOUT; return false; } m = true; q++; } else if (*q == ',') { if (m) { if (i2 == -1) { eprintf("ParseIntList(): Internal error.\n"); abort(); } for (z=i;z<=i2;z++) la.push_back(z); } else la.push_back(i); m = false; i = -1; i2 = -1; q++; } else { eprintf("Error: Invalid character \"%c\" while parsing integer list.\n",*q); return false; } // _end: p = q; } if (m) { for (z=i;z<=i2;z++) la.push_back(z); } else if (i != -1) la.push_back(i); BTOUT; return true; } bool ParseIntList(const char *s, CxWordArray *wa) { BTIN; const char *p, *q; char buf[32]; int i, i2, z; bool m; i2 = -1; p = s; i = -1; m = false; while (*p != 0) { while ((*p == ' ') && (*p != 0)) p++; q = p; if (isdigit(*q)) { while (isdigit(*q)) q++; if (q-p >= 31) { eprintf("ParseIntList: Entry too long (%ld >= 31).\n",q-p); return false; } memcpy(buf,p,q-p); buf[q-p] = 0; if (m) i2 = atoi(buf); else i = atoi(buf); } else if (*q == '-') { if (i == -1) { eprintf("Error: \"-\" without preceding number.\n"); BTOUT; return false; } m = true; q++; } else if (*q == ',') { if (m) { if (i2 == -1) { eprintf("ParseIntList(): Internal error.\n"); abort(); } for (z=i;z<=i2;z++) wa->Add((unsigned short)z); } else wa->Add((unsigned short)i); m = false; i = -1; i2 = -1; q++; } else { eprintf("Error: Invalid character \"%c\" while parsing integer list.\n",*q); return false; } // _end: p = q; } if (m) { for (z=i;z<=i2;z++) wa->Add((unsigned short)z); } else if (i != -1) wa->Add((unsigned short)i); BTOUT; return true; } void SortSingleMolAtomTypes() { BTIN; int z, z2, z3, z4, i, j; CSingleMolecule *s; for (z=0;zm_baAtomIndex.GetSize()-1;z2++) { // printf(" Element %d\n",z2+1); i = -1; j = 999; for (z3=z2;z3m_baAtomIndex.GetSize();z3++) { if (s->m_baAtomIndex[z3] < j) { j = s->m_baAtomIndex[z3]; i = z3; } } if ((i != -1) && (i != z2)) { // mprintf(" Vertausche Elemente %d <-> %d...\n",z2+1,i+1); j = s->m_baAtomIndex[i]; s->m_baAtomIndex[i] = s->m_baAtomIndex[z2]; s->m_baAtomIndex[z2] = (unsigned char)j; for (z4=0;z4m_oaMolAtoms.GetSize();z4++) { if (((CMolAtom*)s->m_oaMolAtoms[z4])->m_iType == z2) ((CMolAtom*)s->m_oaMolAtoms[z4])->m_iType = i; else if (((CMolAtom*)s->m_oaMolAtoms[z4])->m_iType == i) ((CMolAtom*)s->m_oaMolAtoms[z4])->m_iType = z2; } /* j = s->m_baAtomCount[i]; s->m_baAtomCount[i] = s->m_baAtomCount[z2]; s->m_baAtomCount[z2] = j;*/ // mprintf(" Vertausche %d Offsets...\n",max(s->m_iAtomCount[i],s->m_iAtomCount[z2])); /* wa = (CxIntArray*)s->m_oaAtomOffset[i]; s->m_oaAtomOffset[i] = (CxIntArray*)s->m_oaAtomOffset[z2]; s->m_oaAtomOffset[z2] = wa;*/ /* for (z3=0;z3GetSize(),((CxIntArray*)s->m_oaAtomOffset[z2])->GetSize());z3++) { // mprintf(" %d: Vertausche %d <-> %d...",z3+1,s->m_iAtomOffset[z2][z3]+1,s->m_iAtomOffset[i][z3]+1); j = ((CxIntArray*)s->m_oaAtomOffset[z2])->GetAt(z3); ((CxIntArray*)s->m_oaAtomOffset[z2])->SetAt(z3,((CxIntArray*)s->m_oaAtomOffset[i])->GetAt(z3)); ((CxIntArray*)s->m_oaAtomOffset[i])->SetAt(z3,j); // mprintf("Ok: %d <-> %d\n",s->m_iAtomOffset[z2][z3]+1,s->m_iAtomOffset[i][z3]+1); }*/ } } // mprintf("Molekuel zu Ende.\n"); } BTOUT; } FILE *OpenFileWrite(const char *buf, bool text, CxString *out) { BTIN; FILE *a; char tmpbuf[256]; if (strlen(buf) > 220) { memcpy(tmpbuf,buf,100); tmpbuf[100] = 0; strcat(tmpbuf,"..."); memcpy(&tmpbuf[103],&buf[strlen(buf)-100],100); tmpbuf[203] = 0; mprintf("["); mprintf(RED,"Warning:"); mprintf(" File name too long (%lu), shortening to \"%s\"]\n",(unsigned long)strlen(buf),tmpbuf); } else strcpy(tmpbuf,buf); FreeFileName(tmpbuf); if (text) a = fopen(tmpbuf,"wt"); else a = fopen(tmpbuf,"wb"); if (a == NULL) { eprintf("Could not open file \"%s\" for writing.\nBe sure to have writing permission for this directory.\n\nAborting execution.\n",tmpbuf); abort(); } if (out != NULL) out->strcpy(tmpbuf); BTOUT; return a; } bool IsTTY(FILE *f) { UNUSED(f); #ifdef TARGET_WINDOWS return (_isatty(_fileno(f))!=0); #elif defined(TARGET_LINUX) return (isatty(fileno(f))!=0); #else return true; #endif } double ZeroDivide(double a, double b) { if ((a != a) || (b != b)) return 0; if (b == 0) return 0; return a / b; } bool isdigit(char c) { if ((c >= '0') && (c <= '9')) return true; else return false; } bool isnumeric(char c) { if (((c >= '0') && (c <= '9')) || (c == '.') || (c == '+') || (c == '-') || (c == 'e') || (c == 'E')) return true; else return false; } char *FormatBytes(double i) { static char buf[64], buf2[64]; if (i < 0) { buf2[0] = '-'; buf2[1] = 0; i = fabs(i); } else buf2[0] = 0; if (i > 1024.0*1024.0*1024.0*2.0) sprintf(buf,"%.2f GiB",i/1024.0/1024.0/1024.0); else if (i > 1024.0*1024.0*2.0) sprintf(buf,"%.2f MiB",i/1024.0/1024.0); else if (i > 1024.0*2.0) sprintf(buf,"%.2f KiB",i/1024.0); else sprintf(buf,"%.0f Bytes",i); strcat(buf2,buf); return buf2; } const char* RemovePath(const char *s) { const char *p; p = strrchr(s,'/'); if (p == NULL) p = strrchr(s,'\\'); if (p == NULL) return s; return p+1; } double dec(double a, double dig) { if (a == 0) return 1; return mypow(10.0,floor(log10(mypow(10.0,dig)/a))); } void decomp(double &a, double &b, double &c) { c = 1/dec(a,1); b = a/c; } double maxbound(double a, double r) { return ceil(a*r)/r; } double minbound(double a, double r) { return floor(a*r)/r; } double majorticks(double lower, double upper) { double t1, t2, t3, r; t1 = (upper-lower)/6; decomp(t1,t2,t3); if (t2 <= 2) r = 2; else if (t2 <= 5) r = 5; else r = 10; return r * t3; } int GetSignificantDigit(double d, int sig) { int t; // printf("GetDigit %G, %d\n",d,sig); if (d == 0) return 0; d = fabs(d); // printf("A: %G\n",d); d /= mypow(10.0,floor(log10(d))); // printf("B: %G\n",d); d *= mypow(10.0,sig); // printf("C: %G\n",d); t = (int)floor(d+0.01); // printf("D: %d\n",t); t = t % 10; // printf("E: %d\n",t); return t; } //FILE *g_fTicks = NULL; void CreateTicks(double mi, double ma, int &major, int &minor, bool printinfo) { double t, tm, p, p2, px, l, t2, t3; int z, z2, z3, zm, z0, i, im, j; bool havezero; if (printinfo) mprintf(" CreateTicks(): Optimizing axis ticks for range %g - %g...\n",mi,ma); /* First the major ticks */ l = 1e30; i = -1; im = -1; for (z=4;z<9;z++) { for (zm=1;zm<6;zm++) { havezero = false; // printf("*** Checke %d / %d = %d:\n",z,zm,z-2+(z-1)*zm); t = 1.0; for (z2=0;z2 ",t3); t2 += t3; } // printf(" Ergebnis %G\n",t2); t += t2; if (p == 0) havezero = true; } t /= z; tm = 1.0; for (z2=0;z2 ",t3); t2 += t3; } // printf(" Ergebnis %G\n",t2); tm += t2; } } tm /= zm; t = 2*t + tm; switch(z) { case 4: t *= 3.0; break; case 5: t *= 2.0; break; case 6: t *= 1.0; break; case 7: t *= 2.0; break; case 8: t *= 6.0; break; } switch(z-2+(z-1)*zm) { case 1: t *= 2500.0; break; case 2: t *= 2500.0; break; case 3: t *= 2500.0; break; case 4: t *= 2500.0; break; case 5: t *= 750.0; break; case 6: t *= 750.0; break; case 7: t *= 250.0; break; case 8: t *= 250.0; break; case 9: t *= 100.0; break; case 10: t *= 100.0; break; case 11: t *= 10.0; break; case 12: t *= 10.0; break; case 13: t *= 10.0; break; case 14: t *= 8.0; break; case 15: t *= 5.0; break; case 16: t *= 1.0; break; case 17: t *= 1.0; break; case 18: t *= 1.0; break; case 19: t *= 1.0; break; case 20: t *= 1.0; break; case 21: t *= 1.0; break; case 22: t *= 1.0; break; case 23: t *= 2.0; break; case 24: t *= 2.0; break; case 25: t *= 5.0; break; case 26: t *= 5.0; break; case 27: t *= 5.0; break; case 28: t *= 10.0; break; case 29: t *= 10.0; break; case 30: t *= 10.0; break; case 31: t *= 10.0; break; case 32: t *= 50.0; break; case 33: t *= 50.0; break; case 34: t *= 50.0; break; } if (havezero) t -= 10000.0 / ((double)z-2+(z-1)*zm); // printf("## Summe %G\n",t); if (t < l) { l = t; i = z; im = zm; } } } // printf("--> Gewonnen hat %d / %d = %d Ticks mit %G.\n",i,im,i-2+(i-1)*im,l); major = i; minor = im; if (printinfo) mprintf(" Using %d major ticks: ",major); t = mi; for (z=0;z m) m = t; } } return m; } /*void ProtectCharacters(char *dest, const char *src, const char *rep, const char *prot) { const char *p, *r; char *q; p = src; q = dest; while (*p != 0) { if (strchr(rep,*p) != NULL) { r = prot; while (*r != 0) { *q = *r; q++; r++; } } *q = *p; p++; q++; } *q = 0; }*/ void ProtectCharacters(CxString *dest, const char *src, const char *rep, const char *prot) { const char *p, *r; char *q; int i, j; j = (int)strlen(prot); i = (int)strlen(src); p = src; while (*p != 0) { if (strchr(rep,*p) != NULL) i += j; p++; } dest->SetBufSize(i+1); p = src; q = dest->GetWritePointer(); while (*p != 0) { if (strchr(rep,*p) != NULL) { r = prot; while (*r != 0) { *q = *r; q++; r++; } } *q = *p; p++; q++; } *q = 0; } // Cumulative density function of a standard normal random variable // Taken from http://www.johndcook.com/cpp_phi.html // Original source: Handbook of Mathematical Functions by Abramowitz and Stegun, formula 7.1.26 double NormalDistIntegral(double x) { // constants double a1 = 0.254829592; double a2 = -0.284496736; double a3 = 1.421413741; double a4 = -1.453152027; double a5 = 1.061405429; double p = 0.3275911; // Save the sign of x int sign = 1; if (x < 0) sign = -1; x = fabs(x)/sqrt(2.0); // A&S formula 7.1.26 double t = 1.0/(1.0 + p*x); double y = 1.0 - (((((a5*t + a4)*t) + a3)*t + a2)*t + a1)*t*exp(-x*x); return 0.5*(1.0 + sign*y); } /* Returns the value of the Gamma function at argument xx. Source: Numerical Recipes in C, 2nd Ed., Page 214 */ double GammaLn(double xx) { double x, y, tmp, ser; static double cof[6] = { 76.18009172947146, -86.50532032941677, 24.01409824083091, -1.231739572450155, 0.1208650973866179e-2, -0.5395239384953e-5 }; int j; y = xx; x = xx; tmp = x + 5.5; tmp -= (x+0.5) * log(tmp); ser = 1.000000000190015; for (j=0;j<=5;j++) ser += cof[j] / ++y; return -tmp + log(2.5066282746310005 * ser / x); } /* Returns the natural logarithm of the factorial of n. Source: Numerical Recipes in C, 2nd Ed., Page 215 */ double FactorialLn(int n) { if (n < 0) return -1.0; if (n <= 1) return 0.0; return GammaLn(n+1.0); } /* Returns the binomial coefficient "n over k". Source: Numerical Recipes in C, 2nd Ed., Page 215 */ double BinomialCoeff(int n, int k) { return floor(0.5+exp(FactorialLn(n)-FactorialLn(k)-FactorialLn(n-k))); } void HSV2RGB(double h, double s, double v, double &r, double &g, double &b) { int hi; double f, p, q, t; h *= 360.0; hi = (int)floor(h / 60.0); f = (h / 60.0) - hi; p = v * (1.0 - s); q = v * (1.0 - s * f); t = v * (1.0 - s * (1.0 - f) ); switch(hi) { case 0: case 6: r = v; g = t; b = p; break; case 1: r = q; g = v; b = p; break; case 2: r = p; g = v; b = t; break; case 3: r = p; g = q; b = v; break; case 4: r = t; g = p; b = v; break; case 5: r = v; g = p; b = q; break; } return; } double Chop(double d, double t) { if (fabs(d) < t) return 0; return d; } bool isinteger(const char *s) { int z; z = 0; if (strlen(s) > 0) if (s[0] == '-') z++; for (;z<(int)strlen(s);z++) if ((s[z] < 0) || (s[z] > 9)) return false; return true; } travis-src-190101/src/tools.h0100777000000000000000000002141713412725662012757 0ustar00/***************************************************************************** TRAVIS - Trajectory Analyzer and Visualizer http://www.travis-analyzer.de/ Copyright (c) 2009-2019 Martin Brehm 2012-2019 Martin Thomas 2016-2019 Sascha Gehrke This file was written by Martin Brehm. --------------------------------------------------------------------------- This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . *****************************************************************************/ #ifndef TOOLS_H #define TOOLS_H // This must always be the first include directive #include "config.h" #include #include #include #include #include #include #include #include #include #include #include #include #include //#include //#include //#include class CxString; /*************************************************************/ #define UNUSED(a) (void)a #define Pi (3.1415926535897932385) #ifndef M_PI #define M_PI (3.1415926535897932385) #endif #define MIN(a,b) (((a)<=(b)) ? (a) : (b)) #define MAX(a,b) (((a)>=(b)) ? (a) : (b)) #define MIN3(a,b,c) MIN(MIN(a,b),c) #define MAX3(a,b,c) MAX(MAX(a,b),c) #define MIN4(a,b,c,d) MIN(MIN(a,b),MIN(c,d)) #define MAX4(a,b,c,d) MAX(MAX(a,b),MAX(c,d)) #define SQR(x) (x)*(x) #define RUNTYPE_ANALYZE 1 #define RUNTYPE_SCANMOL 2 #ifdef TARGET_WINDOWS inline double roundf(double f) { return floor(f+0.5); } inline double nextafter(double from, double to) { return _nextafter(from,to); } #endif #ifndef TARGET_LINUX #define __PRETTY_FUNCTION__ "" #endif #ifdef TARGET_WINDOWS #define isnan(X) _isnan(X) #define GREY 8 #define BLUE 9 #define GREEN 10 #define CYAN 11 #define RED 12 #define PINK 13 #define YELLOW 14 #define WHITE 15 #define UML_AE ((unsigned char)142) #define UML_ae ((unsigned char)132) #define UML_OE ((unsigned char)153) #define UML_oe ((unsigned char)148) #define UML_UE ((unsigned char)154) #define UML_ue ((unsigned char)129) #define UML_ss ((unsigned char)225) #define mypow(X,Y) pow(X,Y) #define iabs(X) abs(X) #else // Linux or generic #define GREY 0 #define BLUE 4 #define GREEN 2 #define CYAN 6 #define RED 1 #define PINK 5 #define YELLOW 3 #define WHITE 7 #define UML_AE ((unsigned char)196) #define UML_ae ((unsigned char)228) #define UML_OE ((unsigned char)214) #define UML_oe ((unsigned char)246) #define UML_UE ((unsigned char)220) #define UML_ue ((unsigned char)252) #define UML_ss ((unsigned char)223) #define mypow(X,Y) std::pow(X,Y) #define iabs(X) std::abs(X) #endif #include #include class CxWordArray; class CxIntArray; //#define max(a,b) (((a) > (b)) ? (a) : (b)) //#define SAVEPOS mprintf(GREEN,"You may jump back to here by entering \"$\" <---\n\n"); if (setjmp(g_JumpBuf)!=0) mprintf(GREEN,"\n<--- Going Back\n\n"); inline double pow2(double x) { return x*x; } inline double pow3(double x) { return x*x*x; } inline double pow4(double x) { return (x*x)*(x*x); } inline double pow5(double x) { return (x*x*x)*(x*x); } extern FILE *g_pLogFile; extern jmp_buf g_JumpBuf; char* fgets_bin(char *buf, int n, FILE *a); void SavePosition(); void LoadPosition(); //void AskString(const char *s, char *buf, const char *def, ...); //void AskString_ND(const char *s, char *buf, ...); #ifdef __GNUG__ // Variadic Argument Type Checking of GCC void AskString(const char *s, CxString *buf, const char *def, ...) __attribute__ ((format (printf, 1, 4))); void AskString_ND(const char *s, CxString *buf, ...) __attribute__ ((format (printf, 1, 3))); bool AskYesNo(const char *s, bool def, ...) __attribute__ ((format (printf, 1, 3))); int AskUnsignedInteger(const char *s, int def, ...) __attribute__ ((format (printf, 1, 3))); double AskFloat(const char *s, double def, ...) __attribute__ ((format (printf, 1, 3))); bool AskYesNo_ND(const char *s, ...) __attribute__ ((format (printf, 1, 2))); int AskUnsignedInteger_ND(const char *s, ...) __attribute__ ((format (printf, 1, 2))); double AskFloat_ND(const char *s, ...) __attribute__ ((format (printf, 1, 2))); int AskRangeInteger(const char *s, int mini, int maxi, int def, ...) __attribute__ ((format (printf, 1, 5))); int AskRangeInteger_ND(const char *s, int mini, int maxi, ...) __attribute__ ((format (printf, 1, 4))); double AskRangeFloat(const char *s, double mini, double maxi, double def, ...) __attribute__ ((format (printf, 1, 5))); int AskInteger(const char *s, int def, ...) __attribute__ ((format (printf, 1, 3))); #else void AskString(const char *s, CxString *buf, const char *def, ...); void AskString_ND(const char *s, CxString *buf, ...); bool AskYesNo(const char *s, bool def, ...); int AskUnsignedInteger(const char *s, int def, ...); double AskFloat(const char *s, double def, ...); bool AskYesNo_ND(const char *s, ...); int AskUnsignedInteger_ND(const char *s, ...); double AskFloat_ND(const char *s, ...); int AskRangeInteger(const char *s, int mini, int maxi, int def, ...); int AskRangeInteger_ND(const char *s, int mini, int maxi, ...); double AskRangeFloat(const char *s, double mini, double maxi, double def, ...); int AskInteger(const char *s, int def, ...); #endif int AskMolecule(const char *s); void InitColor(); void TextColor(int fg); void TextNormal(); int HalfBox(); double HalfBox_Exact(); int HalfBoxSq3(); bool FileExist(const char *s); void FreeFileName(const char *s); //void FreeFileName(char *pre, char *s, char *post); void saxonize(char *buf); #ifdef __GNUG__ // Variadic Argument Type Checking of GCC void mprintf(const char *s, ...) __attribute__ ((format (printf, 1, 2))); void mprintf_nos(const char *s, ...) __attribute__ ((format (printf, 1, 2))); void mfprintf(FILE *a, const char *s, ...) __attribute__ ((format (printf, 2, 3))); void mprintf(int color, const char *s, ...) __attribute__ ((format (printf, 2, 3))); void bprintf(const char *s, ...) __attribute__ ((format (printf, 1, 2))); void inpprintf(const char *s, ...) __attribute__ ((format (printf, 1, 2))); void eprintf(const char *s, ...) __attribute__ ((format (printf, 1, 2))); #else void mprintf(const char *s, ...); void mprintf_nos(const char *s, ...); void mfprintf(FILE *a, const char *s, ...); void mprintf(int color, const char *s, ...); void bprintf(const char *s, ...); void inpprintf(const char *s, ...); void eprintf(const char *s, ...); #endif //void myget(char *s); void myget(CxString *st); int mystricmp(const char *s1, const char *s2); void RemoveDoubleBackslash(char *buf); const char* TreeElement(const char *s); bool ParseIntList(const char *s, CxIntArray *la); bool ParseIntList(const char *s, std::vector &la); bool ParseIntList(const char *s, CxWordArray *wa); void SortSingleMolAtomTypes(); void xAddAtom(const char *s, bool virt); bool isinteger(const char *s); bool ContainsDigit(const char *s); bool ContainsDigitOrSpecial(const char *s); //void ReplaceDigits(char *s); void ReplaceDigits(CxString *s); const char* RemovePath(const char *s); FILE *OpenFileWrite(const char *buf, bool text, CxString *out = NULL); bool IsTTY(FILE *f); double ZeroDivide(double a, double b); bool isdigit(char c); bool isnumeric(char c); char *FormatBytes(double i); double dec(double a, double dig); void decomp(double &a, double &b, double &c); double maxbound(double a, double r); double minbound(double a, double r); double majorticks(double lower, double upper); int GetSignificantDigit(double d, int sig); void CreateTicks(double mi, double ma, int &major, int &minor, bool printinfo=true); double MaxDiff_DoubleArray(double *p, int n); //void ProtectCharacters(char *dest, const char *src, const char *rep, const char *prot); void ProtectCharacters(CxString *dest, const char *src, const char *rep, const char *prot); double NormalDistIntegral(double x); double GammaLn(double xx); double FactorialLn(int n); double BinomialCoeff(int n, int k); void HSV2RGB(double h, double s, double v, double &r, double &g, double &b); inline int floori(int a, int b) { if (0 < (a ^ b)) { return a / b; } else { if (a % b != 0) return a / b - 1; else return a / b; } } double Chop(double d, double t); #endif travis-src-190101/src/travis.cpp0100777000000000000000000164514613412725635013476 0ustar00/***************************************************************************** TRAVIS - Trajectory Analyzer and Visualizer http://www.travis-analyzer.de/ Copyright (c) 2009-2019 Martin Brehm 2012-2019 Martin Thomas 2016-2019 Sascha Gehrke This file was written by Martin Brehm and Martin Thomas. --------------------------------------------------------------------------- This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . *****************************************************************************/ // This must always be the first include directive #include "config.h" #include "travis.h" #include "tools.h" #include "database.h" #include "statistics.h" #include "maintools.h" #include #include "dacf.h" #include "lmwrapper.h" #include "conversion.h" #include "xdvector3.h" #include "xdmatrix3.h" #include "xquaternion.h" #include "interface.h" #include "random.h" #include "plproj.h" #include "sdfmap.h" #include "linalg.h" #include "fixplproj.h" #ifdef TARGET_WINDOWS #include #include #endif #ifdef TARGET_LINUX #include #endif #include #include "largeinteger.h" const char *GetRevisionInfo_travis(unsigned int len) { static char buf[256]; GET_REVISION_INFO( buf, len ); return buf; } const char *GetSourceVersion_travis() { static char buf[256]; GET_SOURCE_VERSION( buf ); return buf; } /*************************************************************************************************************** ********************** Beginn Quellcode *********************************************************************** ***************************************************************************************************************/ int main(int argc, const char *argv[]) { FILE *a, *tfi; CxString buf, buf2, buf3, procsplitbuf; char *p, *q; const char *cp, *pn, *upn; int ti=-1, ti2=-1, ti3, cc, cc2, ticomb, tic_r=-1, tic_o=-1; int z0, z, z2, z3, z4, z5, z6, z7, z8, zr, zs, zi, z2b, z3b; int z1a, z1t, z2a, z2t; int procsplitc, procspliti; CxIntArray *a1, *a2; CAtomGroup *g1, *g2; int tia[3]; CxDVector3 vec0, vec1, vec2, vec3, vec4, vec5, vecv, vecc; CxDMatrix3 mat; CxDMatrix3 dmat; double tf, tf2, tf3, tf4, tfs, tfx, tfy, tfz; double c0, c1, r; double *pd; double *pf; CMolecule *m, *m2; CSingleMolecule *sm, *smfix, *sm2; char tc; unsigned long t0, t1, eta; int showinterval; CObservation *o; CTimeStep rot_ts; C3DF *tempSDF; C3DF *temp3DF; CDF *tdf; int sic; CxIntArray templa, *tla; CxDoubleArray **apfa; // "A"rray von "P"ointern auf "F"loat-"A"rrays double *tda; // "T"emporaeres "D"ouble-"Array" CxByteArray **apba; CxDVec3Array tempvel; CAtomGroup *atgr, *ag; struct tm *today; time_t ltime; bool secondmolrun, tb, tbs; int multicounter; char multibuf[64]; long fpos, fpos2; CMolBondGroup *bg; CMolBond *bond; CxDoubleArray tempfa, tempfa2, *ptfa, *ptfab; CxDoubleArray *ptfa2, *ptfa3, *ptfa2b; CGrace *gc, *gc2; CFFT *fft; C2DF *temp2df, *tempc2df, **temp2dfa; CConditionGroup *cg; int *tpi; CAutoCorrelation *ac; CCrossCorrelation *ccr; CDACFSub *dacfsub; unsigned int *pSwapMatrix; CxDMatrix3 tdmat, tdmat2; CxDVector3 dvec0, dvec1, dvec2, dvec3, dvec4; CxQuaternion tq, tq2; CReorDyn *trdyn; char obuf[64]; #ifdef TARGET_WINDOWS unsigned long tul; #endif InitGlobalVars(); /**** Initialize Local Variables ***/ procsplitc = 0; procspliti = 0; tdmat2.Unity(); tq2.Unity(); multicounter = 0; pSwapMatrix = NULL; apfa = NULL; tda = NULL; /***********************************/ AddElementData(); SortElementsLabel(); try { g_sExeName = new char[strlen(argv[0])+1]; } catch(...) { g_sExeName = NULL; } if (g_sExeName == NULL) NewException((double)(strlen(argv[0])+1)*sizeof(char),__FILE__,__LINE__,__PRETTY_FUNCTION__); strcpy(g_sExeName,argv[0]); GetTravisPath(); InstallSignalHandler(); InitColor(); g_pLogFile = OpenFileWrite("travis.log",true); fprintf(g_pLogFile,"Command line:\n\""); for (z=0;z 1) { if ((strcmp(argv[1],"compress") == 0) || (strcmp(argv[1],"decompress") == 0) || (strcmp(argv[1],"check") == 0) || (strcmp(argv[1],"compare") == 0) || (strcmp(argv[1],"merge") == 0) || (strcmp(argv[1],"split") == 0)) { g_bUseBQB = true; bqbtool_main(argc,argv); goto _ende; } } CheckSourceVersion(); if (g_bControlRun) { mprintf("\n"); mprintf(WHITE," #####################################\n"); mprintf(WHITE," #### This is a Control Run ####\n"); mprintf(WHITE," #####################################\n\n\n"); mprintf(" Control runs are a way for direct interfacing between TRAVIS and other program packages.\n"); mprintf(" This is an experimental feature; there is no support and no documentation on control runs.\n"); mprintf(" If you are a software developer and would like to have a direct interface to TRAVIS, please\n"); mprintf(" contact the developers.\n\n\n"); g_bInputRedirected = true; mprintf(" Trying to read database file from \"%s\"...\n",g_sControlFile); try { g_pControlDB = new CDatabase(); } catch(...) { g_pControlDB = NULL; } if (g_pControlDB == NULL) NewException((double)sizeof(CDatabase),__FILE__,__LINE__,__PRETTY_FUNCTION__); g_pControlDB->ParseInputFile(g_sControlFile); mprintf("\n Done. Dump of database tree:\n\n"); g_pControlDB->DumpTree(); mprintf(" Trying to determine runtype...\n\n"); if (!g_pControlDB->ExistNode("/CONTROL")) { eprintf("Error: Node \"/CONTROL\" is missing in control file.\n"); goto _ende; } cp = g_pControlDB->GetString("/CONTROL/RUNTYPE"); if (cp == NULL) { eprintf("Error: Value \"/CONTROL/RUNTYPE\" is missing or not of string type (%d).\n",g_pControlDB->GetElementType("/CONTROL/RUNTYPE")); goto _ende; } mprintf(" The runtype is \"%s\".\n\n",cp); if (mystricmp(cp,"ANALYZE") == 0) g_iControlRT = RUNTYPE_ANALYZE; else if (mystricmp(cp,"SCANMOL") == 0) g_iControlRT = RUNTYPE_SCANMOL; else { eprintf("Error: Invalid runtype in control file.\n"); goto _ende; } mprintf("\n"); mprintf(WHITE," ###################################################\n"); mprintf(WHITE," #### Control Run Initialization finished ####\n"); mprintf(WHITE," ###################################################\n\n\n"); } if (!g_bControlRun) { g_bInputRedirected = false; if (g_sInputFile != NULL) { g_fInputFile = fopen(g_sInputFile,"rt"); if (g_fInputFile == NULL) { eprintf("Could not open input file \"%s\".\n",g_sInputFile); goto _ende; } g_bInputRedirected = true; } if (IsTTY(stdin) && (!g_bInputRedirected)) { g_fInput = OpenFileWrite("input.txt",true); g_bInputRedirected = false; inpprintf("! TRAVIS input file\n"); inpprintf("! Created with TRAVIS version compiled at %s %s\n",__DATE__,__TIME__); inpprintf("! Source code version: %s\n",SOURCE_VERSION); time(<ime); today = localtime(<ime); // strcpy(buf,asctime(today)); buf.strcpy(asctime(today)); buf((int)(strlen(buf)-1)) = 0; inpprintf("! Input file written at %s.\n",(const char*)buf); } else g_bInputRedirected = true; } if (g_bDipolGrimme) { if (argc < 3) DipolGrimme(NULL); else DipolGrimme(argv[2]); return 0; } if (!ParseArgs(argc,argv)) goto _ende; SortElementsMass(); if (g_sInputTraj == NULL) { eprintf(" No trajectory file specified.\n"); mprintf(" Please use the \"-p\" flag to specify an input trajectory in the command line.\n\n"); if ((argc == 1) && !g_bControlRun) { mprintf(" Enter the file name of the trajectory file to open: [Quit] "); myget(&buf); mprintf("\n"); if (strlen(buf)==0) { CommandLineHelp(); goto _ende; } try { g_sInputTraj = new char[strlen(buf)+1]; } catch(...) { g_sInputTraj = NULL; } if (g_sInputTraj == NULL) NewException((double)(strlen(buf)+1)*sizeof(char),__FILE__,__LINE__,__PRETTY_FUNCTION__); strcpy(g_sInputTraj,buf); } else { CommandLineHelp(); goto _ende; } } if (!DetermineTrajFormat()) goto _ende; if (g_iTrajFormat == 6) // Amber { // sprintf(buf,"%sprmtop",g_sInputTraj); buf.sprintf("%sprmtop",g_sInputTraj); if (!FileExist(buf)) { eprintf("\n Error: File \"%s\" does not exist.\n",(const char*)buf); printf(" When opening Amber trajectories, both .prmtop and .mdcrd files need to have the same base file name.\n\n"); goto _ende; } // strcpy(g_sAmberParmFile,buf); g_sAmberParmFile.strcpy(buf); // sprintf(buf,"%smdcrd",g_sInputTraj); buf.sprintf("%smdcrd",g_sInputTraj); if (!FileExist(buf)) { eprintf("\n Error: File \"%s\" does not exist.\n",(const char*)buf); printf(" When opening Amber trajectories, both .prmtop and .mdcrd files need to have the same base file name.\n\n"); goto _ende; } try { g_sInputTraj = new char[strlen(buf)+1]; } catch(...) { g_sInputTraj = NULL; } if (g_sInputTraj == NULL) NewException((double)(strlen(buf)+1)*sizeof(char),__FILE__,__LINE__,__PRETTY_FUNCTION__); strcpy(g_sInputTraj,buf); } if (g_sInputTraj[0] != 0) { mprintf(" Opening position trajectory %s ...",g_sInputTraj); if (!FileExist(g_sInputTraj)) { eprintf("\nError. File does not exist or cannot be read.\n"); goto _ende; } mprintf("\n"); } else { eprintf("Error: No trajectory file specified.\n"); goto _ende; } if (g_bReadVelocity) { mprintf(" Opening velocity trajectory %s ...",(const char*)g_sInputVel); if (!FileExist(g_sInputVel)) { eprintf("\nError. File does not exist or cannot be read.\n"); goto _ende; } if (mystricmp(GetFileExtension((const char*)g_sInputVel),"xyz") != 0) { eprintf("\nError. File is not in .xyz format. Only xyz files are currently supported for velocities.\n"); goto _ende; } mprintf("\n"); mprintf("\n"); mprintf(" You have to enter the unit of the velocities in the data file.\n\n"); mprintf(" Note: CP2k prints velocities in a.u. = 2.187691*10^6 m/s\n"); mprintf(" LAMMPS (\"units real\") prints velocities in Angstrom/fs = 1.0*10^5 m/s\n\n"); g_fVelocityConversion = AskFloat(" One velocity unit in the file corresponds to how many m/s? [2.187691e6] ",2.187691E6); } if (g_sInputForce[0] != 0) { mprintf(" Opening force trajectory %s ...",(const char*)g_sInputForce); if (!FileExist(g_sInputForce)) { eprintf("\nError. File does not exist or cannot be read.\n"); goto _ende; } mprintf("\n"); } if (!OpenInputTrajectory()) goto _ende; /* g_fPos = fopen(g_sInputTraj,"rt"); if (g_fPos == NULL) { eprintf("Error. Could not open \"%s\".\n",g_sInputTraj); goto _ende; }*/ if (!g_TimeStep.ReadTimestep(g_fPos,true)) { eprintf("\nError reading first time step from trajectory. Leaving.\n"); goto _ende; } if (g_iTrajFormat == 7) { g_bUseBQB = true; if (g_pBQBFile->GetFrameType() == 4) { mprintf("\n This is an uncompressed BQB trajectory (%dv%d) and contains the following fields:\n",g_pBQBFile->GetFrameType(),g_pBQBFile->GetFrameTypeVersion()); CBQBTrajectoryFrame btf(*g_pBQBInterface); if (!btf.ReadFrame(g_pBQBFile->GetFramePayload())) { eprintf("Error: Could not read trajectory frame from BQB payload.\n"); goto _ende; } tb = false; mprintf(" "); if (btf.GetColumn("Label") != NULL) { if (tb) mprintf(", "); mprintf("Labels"); tb=true; } if (btf.GetColumn("PosX") != NULL) { if (tb) mprintf(", "); mprintf("Positions"); tb=true; } if (btf.GetColumn("VelX") != NULL) { if (tb) mprintf(", "); mprintf("Velocities"); tb=true; } if (btf.GetColumn("EChg") != NULL) { if (tb) mprintf(", "); mprintf("El.Charges"); tb=true; } if (btf.GetColumn("EDipX") != NULL) { if (tb) mprintf(", "); mprintf("El.Dipoles"); tb=true; g_bElMagProperties = true; } if (btf.GetColumn("EQXX") != NULL) { if (tb) mprintf(", "); mprintf("El.Quadrupoles"); tb=true; g_bElMagProperties = true; } if (btf.GetColumn("ECurX") != NULL) { if (tb) mprintf(", "); mprintf("El.Currents"); tb=true; g_bElMagProperties = true; } if (btf.GetColumn("MDipX") != NULL) { if (tb) mprintf(", "); mprintf("Mag.Dipoles"); g_bElMagProperties = true; } mprintf("\n"); } else if ((g_pBQBFile->GetFrameType() == 5) || (g_pBQBFile->GetFrameType() == 6)) { mprintf("\n This is a compressed BQB trajectory (%dv%d).\n",g_pBQBFile->GetFrameType(),g_pBQBFile->GetFrameTypeVersion()); } else if (g_pBQBFile->GetFrameType() == 7) { mprintf("\n This is an uncompressed volumetric BQB trajectory (%dv%d).\n",g_pBQBFile->GetFrameType(),g_pBQBFile->GetFrameTypeVersion()); g_bVolumetricData = true; } else if ((g_pBQBFile->GetFrameType() == 8) || (g_pBQBFile->GetFrameType() == 9)) { mprintf("\n This is a compressed volumetric BQB trajectory (%dv%d).\n",g_pBQBFile->GetFrameType(),g_pBQBFile->GetFrameTypeVersion()); g_bVolumetricData = true; } else { mprintf("\n"); eprintf(" Warning: "); mprintf("This is a BQB trajectory of unknown format (%dv%d).\n",g_pBQBFile->GetFrameType(),g_pBQBFile->GetFrameTypeVersion()); } } if (g_bXYZ4thCol) mprintf("\n Found 4th column of numbers in XYZ file.\n"); if (g_bLAMMPSCharge) mprintf("\n Found atomic partial charges in LAMMPS file.\n"); if (g_bLAMMPSForce) mprintf("\n Found atomic forces in LAMMPS trajectory.\n"); if (g_bXYZComment6Numbers) mprintf("\n Found 6 numeric values in comment line of XYZ file.\n"); if (g_bXYZComment3Numbers) mprintf("\n Found 3 numeric values in comment line of XYZ file.\n"); if (g_bFoundNonOrtho) mprintf("\n Found non-orthorhombic cell geometry in LAMMPS trajectory.\n"); g_TimeStep.CalcMinMax(); if (g_iTrajFormat == 7) { g_iTrajSteps = g_pBQBFile->GetTotalFrameCount(); if (g_iTrajSteps == -1) mprintf("\n Could not determine trajectory step count (no index).\n\n"); else mprintf("\n Trajectory contains %d time steps (indexed).\n\n",g_iTrajSteps); } else { if (!g_bStreamInput) { // fgetpos(g_fPos,&fpos); fpos = ftell(g_fPos); fseek(g_fPos,0,SEEK_END); fpos2 = ftell(g_fPos); // fgetpos(g_fPos,&fpos2); fclose(g_fPos); } else fpos2 = -1; if (fpos2 < 0) { mprintf("\n Could not determine trajectory file size.\n\n"); g_iTrajSteps = -1; } else { g_iTrajSteps = fpos2/fpos; mprintf("\n Trajectory contains approximately %d time steps (file size %s).\n\n",g_iTrajSteps,FormatBytes(fpos2)); } } g_iGesAtomCount = g_TimeStep.m_iGesAtomCount; if (g_iGesAtomCount == 0) { eprintf("\n\nNo atoms found. This is probably not what you want. Leaving.\n"); goto _ende; } g_iGesVirtAtomCount = g_iGesAtomCount; g_TimeStep.AddAtoms(); if (g_bUnknownElements) mprintf("\n"); SortAtoms(); mprintf(WHITE," %d atoms in the system: ",g_iGesAtomCount); for (z=0;zm_iCount,(const char*)((CAtom*)g_oaAtoms[z])->m_sName); if (z < (int)g_oaAtoms.GetSize()-1) mprintf(", "); } mprintf("\n\n"); mprintf(" System extent: X = { %+6.0f .. %+6.0f pm }, dX = %.0f pm\n",g_TimeStep.m_vMin[0],g_TimeStep.m_vMax[0],g_TimeStep.m_vMax[0]-g_TimeStep.m_vMin[0]); mprintf(" (in step 1) Y = { %+6.0f .. %+6.0f pm }, dY = %.0f pm\n",g_TimeStep.m_vMin[1],g_TimeStep.m_vMax[1],g_TimeStep.m_vMax[1]-g_TimeStep.m_vMin[1]); mprintf(" Z = { %+6.0f .. %+6.0f pm }, dZ = %.0f pm\n",g_TimeStep.m_vMin[2],g_TimeStep.m_vMax[2],g_TimeStep.m_vMax[2]-g_TimeStep.m_vMin[2]); g_iVirtAtomType = (unsigned char)g_oaAtoms.GetSize(); xAddAtom("#",true); if (g_iTrajFormat == 3) { mprintf(YELLOW,"\n*** Important note: "); mprintf(" Trajectory file is in LAMMPS format.\n\n"); mprintf(" TRAVIS requires that the atom ordering (sorting) is identical in each time step of the trajectory.\n"); mprintf(" However, LAMMPS' defaults may order the atoms randomly in each step when dumping a trajectory.\n"); mprintf(" To read a LAMMPS trajectory in TRAVIS, you *need* to make sure the atom ordering stays constant.\n"); mprintf(" This can be achieved by specifying \"dump modify ... sort id\" to your trajectory dump command.\n\n"); while (!AskYesNo(" I have acknowledged this note (y/n). [yes] ",true)) { } } if ((g_iTrajFormat == 7) && (mystricmp(&g_sInputTraj[strlen(g_sInputTraj)-4],".bbq") == 0)) PrintBMode(); /****************************/ if (!GatherInfos()) goto _ende; /************** Beginn Analyse **************/ if (g_bStreamInput) { if (g_bScanVelocities) { eprintf("\nError: Velocity pre-analysis not compatible with stream input.\n\n"); goto _ende; } if ((g_bSaveRefEnv) && (g_iNbhMode == 3)) { eprintf("\nError: Neighborhood pre-analysis not compatible with stream input.\n\n"); goto _ende; } } g_iStartTime = time(NULL); if (g_iMaxStep != -1) { g_iTrajSteps = g_iMaxStep; } else { if (g_iTrajSteps != -1) { g_iTrajSteps -= g_iBeginStep; if (g_iTrajSteps < 1) g_iTrajSteps = 1; } } if (g_bROA) { g_pROAEngine->MainLoop(); goto _ende; } if (((g_iTrajFormat == 5) || (g_iTrajFormat == 7)) && !g_bCubeTimeDev) g_iStepHistory = 1; else g_iStepHistory = 3; multicounter = 0; _multiintervalstart: if (g_bMultiInterval) { g_iBeginStep = g_laMultiIntervalStart[multicounter]; g_iScanNbhStart = g_iBeginStep; g_iMaxStep = g_laMultiIntervalEnd[multicounter] - g_laMultiIntervalStart[multicounter] + 1; g_iScanNbhSteps = g_iMaxStep; mprintf(YELLOW,"***********************************************\n"); mprintf(YELLOW,"*** Interval %2d (%6d - %6d) starting. ***\n",multicounter+1,g_laMultiIntervalStart[multicounter]+1,g_laMultiIntervalEnd[multicounter]+1); mprintf(YELLOW,"***********************************************\n\n"); sprintf(multibuf,"_I%d_%d-%d",multicounter+1,g_laMultiIntervalStart[multicounter],g_laMultiIntervalEnd[multicounter]); } else multibuf[0] = 0; mprintf(WHITE,">>> Initialization >>>\n\n"); g_bAbortAnalysis = false; if (!g_bStreamInput) { if (!OpenInputTrajectory()) goto _ende; /* g_fPos = fopen(g_sInputTraj,"rb"); // Eingabedatei erneut oeffnen if (g_fPos == NULL) { eprintf("\nError. Input Trajectory suddenly vanished ^^\n"); goto _ende; }*/ if ((g_bNPT) && (g_sNPTFile[0] != 0)) { g_fNPTFile = fopen(g_sNPTFile,"rt"); if (g_fNPTFile == NULL) { eprintf("\nCould not open cell vector file.\n"); goto _ende; } } } if (g_iBeginStep != 0) { mprintf("Fast-forwarding to step %d...\n",g_iBeginStep+1); /* if (g_iTrajFormat == 7) { if (!SeekInputTrajectory(g_iBeginStep)) goto _ende; }*/ if ((g_iBeginStep != g_iScanMolStep) || (g_iTrajFormat == 7)) { if (g_iTrajFormat == 7) mprintf("Warning: Index-based seeking for bqb files not yet implemented.\n"); mprintf(WHITE," ["); for (z=0;z>> Pre-Analysis for velocity distribution >>>\n\n"); /* g_fPos = fopen(g_sInputTraj,"rt"); // Eingabedatei erneut Oeffnen if (g_fPos == NULL) { eprintf("Error. Input Trajectory suddenly vanished ^^\n"); return 0; }*/ if (!OpenInputTrajectory()) goto _ende; g_iSteps = 0; // Der Zaehler der Zeitschritte if (g_iScanVelStart != 0) { mprintf("Fast-forwarding to step %d...\n",g_iScanVelStart+1); if (g_iTrajFormat == 7) mprintf("Warning: Index-based seeking for bqb files not yet implemented.\n"); mprintf(WHITE," ["); for (z=0;z 0) && ((int)g_iSteps >= g_iScanVelSteps)) break; } _endvel: // fclose(g_fPos); if (!CloseInputTrajectory()) goto _ende; mprintf(WHITE,"\n<<< End of Pre-Analysis for velocity distribution <<<\n\n"); } // END IF g_bScanVelocities if (g_bSaveRefEnv && (g_iNbhMode == 1)) { mprintf("Creating statical neighborhood...\n"); g_pNbSet->Scan((CSingleMolecule*)g_oaSingleMolecules[((CMolecule*)g_oaMolecules[g_iFixMol])->m_laSingleMolIndex[g_iSaveRefMol]],&g_TimeStep); if (g_bSaveRefWithEnv) { mprintf("Adding reference molecule to neighborhood...\n"); g_pNbSet->AddMolecule(g_iFixMol,g_iSaveRefMol); } mprintf("\n"); g_pNbSet->Dump(); mprintf("\n"); } if (g_bVACF && g_bGlobalVACF) { mprintf("Initializing Global Velocity Autocorrelation Function...\n"); g_pGlobalVACF->Create(); if (!g_bVACFCacheMode) { if (g_pGlobalVACF->m_iSize > g_iStepHistory) g_iStepHistory = g_pGlobalVACF->m_iSize; } else { mprintf(" VACF Cache: Trying to allocate %s of memory...\n",FormatBytes((double)g_iGesAtomCount*g_iTrajSteps*3.1*sizeof(double))); for (z=0;zm_pElement->m_sLabel,((CAtom*)g_oaAtoms[g_waAtomRealElement[z]])->m_pElement->m_fRadius); if (g_pGlobalVACF->m_bExcludeR0 && (g_waAtomRealElement[z] > 1000)) continue; // mprintf(" --> Ok\n"); try { ptfa = new CxDoubleArray("main():ptfa"); } catch(...) { ptfa = NULL; } if (ptfa == NULL) NewException((double)sizeof(CxDoubleArray),__FILE__,__LINE__,__PRETTY_FUNCTION__); if (g_iTrajSteps != -1) { ptfa->SetMaxSize((long)(g_iTrajSteps*3.1)); ptfa->SetGrow((long)(g_iTrajSteps*0.1)); } else ptfa->SetGrow(1000); g_pGlobalVACF->m_oaCache.Add(ptfa); } } } if (g_bIRSpec && g_bGlobalIR) { mprintf(" Creating global IR spectrum...\n"); g_pGlobalIR->m_pRDyn->m_fMinVal = 0; g_pGlobalIR->m_pRDyn->m_fMaxVal = g_pGlobalIR->m_iDepth * g_fTimestepLength / 1000.0; g_pGlobalIR->m_pRDyn->m_iResolution = g_pGlobalIR->m_iDepth/g_pGlobalIR->m_iStride; g_pGlobalIR->m_pRDyn->SetLabelX("Tau [ps]"); g_pGlobalIR->m_pRDyn->SetLabelY("Dipole autocorrelation"); g_pGlobalIR->m_pRDyn->Create(); if (g_bRDynCacheMode) { if (g_iTrajSteps != -1) mprintf(" RDyn Cache: Trying to allocate %s of memory...\n",FormatBytes((double)g_oaSingleMolecules.GetSize()*g_iTrajSteps/g_iStride*3.1*sizeof(double))); else mprintf(" RDyn Cache: Trying to allocate %s of memory...\n",FormatBytes((double)g_oaSingleMolecules.GetSize()*10000/g_iStride*3.1*sizeof(double))); for (z2=0;z2SetMaxSize((long)(g_iTrajSteps/g_iStride*3.3)); ptfa->SetGrow((long)(g_iTrajSteps/g_iStride*0.3)); } else ptfa->SetGrow(10000); g_pGlobalIR->m_oaCache.Add(ptfa); } } else { try { g_pGlobalIR->m_pCount = new double[g_pGlobalIR->m_pRDyn->m_iResolution]; } catch(...) { g_pGlobalIR->m_pCount = NULL; } if (g_pGlobalIR->m_pCount == NULL) NewException((double)g_pGlobalIR->m_pRDyn->m_iResolution*sizeof(double),__FILE__,__LINE__,__PRETTY_FUNCTION__); for (z2=0;z2m_pRDyn->m_iResolution;z2++) g_pGlobalIR->m_pCount[z2] = 0; if (!g_bRDynCacheMode) { if (g_pGlobalIR->m_iDepth > g_iStepHistory) g_iStepHistory = g_pGlobalIR->m_iDepth; } } } /* if (g_bSFac) { mprintf(" Creating Structure Factor Analysis...\n"); g_pSFac->Create(); }*/ if (g_bSaveCondSnapshot) g_fSaveCondFile = OpenFileWrite("savecondition.xyz",true); for (z=0;zm_pDACF->m_oaSubDACFs.GetSize()); for (z2=0;z2m_pDACF->m_oaSubDACFs.GetSize();z2++) { dacfsub = (CDACFSub*)o->m_pDACF->m_oaSubDACFs[z2]; if (g_bDLDisp) { try { dacfsub->m_pDLDisp = new C2DF(); } catch(...) { dacfsub->m_pDLDisp = NULL; } if (dacfsub->m_pDLDisp == NULL) NewException((double)sizeof(C2DF),__FILE__,__LINE__,__PRETTY_FUNCTION__); dacfsub->m_pDLDisp->m_iRes[0] = o->m_pDACF->m_iLifetimeRes; dacfsub->m_pDLDisp->m_fMinVal[0] = 0.0; dacfsub->m_pDLDisp->m_fMaxVal[0] = o->m_pDACF->m_fLargestLifetime; dacfsub->m_pDLDisp->m_iRes[1] = o->m_pDACF->m_iDisplacementRes; dacfsub->m_pDLDisp->m_fMinVal[1] = 0.0; dacfsub->m_pDLDisp->m_fMaxVal[1] = o->m_pDACF->m_fLargestDisplacement; dacfsub->m_pDLDisp->Create(); dacfsub->m_pDLDisp->SetLabelX("Lifetime [ps]"); dacfsub->m_pDLDisp->SetLabelY("Displacement [pm]"); } if (g_bPairMSD) { try { dacfsub->m_pPairMSD = new CAF(); } catch(...) { dacfsub->m_pPairMSD = NULL; } if (dacfsub->m_pPairMSD == NULL) NewException((double)sizeof(CAF),__FILE__,__LINE__,__PRETTY_FUNCTION__); dacfsub->m_pPairMSD->m_iResolution = o->m_pDACF->m_iDACFRes; dacfsub->m_pPairMSD->m_fMinVal = 0.0; dacfsub->m_pPairMSD->m_fMaxVal = o->m_pDACF->m_fLargestLifetime; dacfsub->m_pPairMSD->Create(); } if (g_bDDisp) { try { dacfsub->m_pDDisp = new CDF(); } catch(...) { dacfsub->m_pDDisp = NULL; } if (dacfsub->m_pDDisp == NULL) NewException((double)sizeof(CDF),__FILE__,__LINE__,__PRETTY_FUNCTION__); dacfsub->m_pDDisp->m_iResolution = o->m_pDACF->m_iDisplacementRes; dacfsub->m_pDDisp->m_fMinVal = 0.0; dacfsub->m_pDDisp->m_fMaxVal = o->m_pDACF->m_fLargestDisplacement; dacfsub->m_pDDisp->SetLabelX("Dimer displacement [pm]"); dacfsub->m_pDDisp->SetLabelY("Occurrence"); dacfsub->m_pDDisp->Create(); } if (g_bDLDF) { try { dacfsub->m_pDLDF = new CDF(); } catch(...) { dacfsub->m_pDLDF = NULL; } if (dacfsub->m_pDLDF == NULL) NewException((double)sizeof(CDF),__FILE__,__LINE__,__PRETTY_FUNCTION__); dacfsub->m_pDLDF->m_bLeft = true; dacfsub->m_pDLDF->m_iResolution = o->m_pDACF->m_iLifetimeRes; dacfsub->m_pDLDF->m_fMinVal = 0.0; dacfsub->m_pDLDF->m_fMaxVal = o->m_pDACF->m_fLargestLifetime; dacfsub->m_pDLDF->SetLabelX("Tau [ps]"); dacfsub->m_pDLDF->SetLabelY("Occurrence"); dacfsub->m_pDLDF->Create(); } if (g_bDACF) { try { dacfsub->m_pDACF = new CDF(); } catch(...) { dacfsub->m_pDACF = NULL; } if (dacfsub->m_pDACF == NULL) NewException((double)sizeof(CDF),__FILE__,__LINE__,__PRETTY_FUNCTION__); dacfsub->m_pDACF->m_bLeft = true; dacfsub->m_pDACF->m_iResolution = o->m_pDACF->m_iDACFRes; dacfsub->m_pDACF->m_fMinVal = 0; dacfsub->m_pDACF->m_fMaxVal = o->m_pDACF->m_iDACFRes * g_fTimestepLength / 1000.0; dacfsub->m_pDACF->SetLabelX("Tau [ps]"); dacfsub->m_pDACF->SetLabelY("Occurrence"); dacfsub->m_pDACF->Create(); if (dacfsub->m_bNewMode) { // mprintf("Create: %d*%d=%d\n",((CMolecule*)g_oaMolecules[dacfsub->m_iRefMol])->m_laSingleMolIndex.GetSize(),((CMolecule*)g_oaMolecules[dacfsub->m_iShowMol])->m_laSingleMolIndex.GetSize(),((CMolecule*)g_oaMolecules[dacfsub->m_iRefMol])->m_laSingleMolIndex.GetSize()*((CMolecule*)g_oaMolecules[dacfsub->m_iShowMol])->m_laSingleMolIndex.GetSize()); try { dacfsub->m_piaIntervals = new CxIntArray[((CMolecule*)g_oaMolecules[dacfsub->m_iRefMol])->m_laSingleMolIndex.GetSize()*((CMolecule*)g_oaMolecules[dacfsub->m_iShowMol])->m_laSingleMolIndex.GetSize()]; } catch(...) { dacfsub->m_piaIntervals = NULL; } if (dacfsub->m_piaIntervals == NULL) NewException((double)((CMolecule*)g_oaMolecules[dacfsub->m_iRefMol])->m_laSingleMolIndex.GetSize()*((CMolecule*)g_oaMolecules[dacfsub->m_iShowMol])->m_laSingleMolIndex.GetSize()*sizeof(CxIntArray),__FILE__,__LINE__,__PRETTY_FUNCTION__); } } try { dacfsub->m_pNDF = new CDF(); } catch(...) { dacfsub->m_pNDF = NULL; } if (dacfsub->m_pNDF == NULL) NewException((double)sizeof(CDF),__FILE__,__LINE__,__PRETTY_FUNCTION__); dacfsub->m_pNDF->m_iResolution = ((CMolecule*)g_oaMolecules[o->m_pDACF->m_iSecondMol])->m_laSingleMolIndex.GetSize()+1; dacfsub->m_pNDF->m_fMinVal = 0.0; dacfsub->m_pNDF->m_fMaxVal = ((CMolecule*)g_oaMolecules[o->m_pDACF->m_iSecondMol])->m_laSingleMolIndex.GetSize()+1; dacfsub->m_pNDF->Create(); } } if (g_bSDF) { mprintf(" Creating SDF...\n"); o->m_pSDF->m_pSDF->m_fMinVal[0] = -o->m_pSDF->m_fRadius; o->m_pSDF->m_pSDF->m_fMaxVal[0] = o->m_pSDF->m_fRadius; o->m_pSDF->m_pSDF->m_fMinVal[1] = -o->m_pSDF->m_fRadius; o->m_pSDF->m_pSDF->m_fMaxVal[1] = o->m_pSDF->m_fRadius; o->m_pSDF->m_pSDF->m_fMinVal[2] = -o->m_pSDF->m_fRadius; o->m_pSDF->m_pSDF->m_fMaxVal[2] = o->m_pSDF->m_fRadius; o->m_pSDF->m_pSDF->m_iRes[0] = o->m_pSDF->m_iResolution; o->m_pSDF->m_pSDF->m_iRes[1] = o->m_pSDF->m_iResolution; o->m_pSDF->m_pSDF->m_iRes[2] = o->m_pSDF->m_iResolution; o->m_pSDF->m_pSDF->m_iHistogramRes = o->m_pSDF->m_iHistogramRes; o->m_pSDF->m_pSDF->Create(); // mprintf("Observation %d: Creating %d VecArrays.\n",z+1,o->m_iShowMolCount); try { o->m_pSDF->m_vaData = new CxDVec3Array[o->m_iShowMolCount]; } catch(...) { o->m_pSDF->m_vaData = NULL; } if (o->m_pSDF->m_vaData == NULL) NewException((double)o->m_iShowMolCount*sizeof(CxDVec3Array),__FILE__,__LINE__,__PRETTY_FUNCTION__); if (o->m_pSDF->m_bVdWSpheres) { try { o->m_pSDF->m_faRadius = new CxDoubleArray[o->m_iShowMolCount]; } catch(...) { o->m_pSDF->m_faRadius = NULL; } if (o->m_pSDF->m_faRadius == NULL) NewException((double)o->m_iShowMolCount*sizeof(CxDoubleArray),__FILE__,__LINE__,__PRETTY_FUNCTION__); } if (o->m_bBinOnlyPassedAtoms || o->m_bBinOnlyNotPassedAtoms) { try { o->m_pSDF->m_baDataEnabled = new CxByteArray[o->m_iShowMolCount]; } catch(...) { o->m_pSDF->m_baDataEnabled = NULL; } if (o->m_pSDF->m_baDataEnabled == NULL) NewException((double)o->m_iShowMolCount*sizeof(CxByteArray),__FILE__,__LINE__,__PRETTY_FUNCTION__); } } if (g_bPlProj) { mprintf(" Creating plane projection DF...\n"); o->m_pPlProj->m_p2DF->m_fMinVal[0] = o->m_pPlProj->m_fMinVal[0]; o->m_pPlProj->m_p2DF->m_fMaxVal[0] = o->m_pPlProj->m_fMaxVal[0]; o->m_pPlProj->m_p2DF->m_fMinVal[1] = o->m_pPlProj->m_fMinVal[1]; o->m_pPlProj->m_p2DF->m_fMaxVal[1] = o->m_pPlProj->m_fMaxVal[1]; o->m_pPlProj->m_p2DF->m_iRes[0] = o->m_pPlProj->m_iResolution[0]; o->m_pPlProj->m_p2DF->m_iRes[1] = o->m_pPlProj->m_iResolution[1]; o->m_pPlProj->m_p2DF->m_iHistogramRes = o->m_pPlProj->m_iHistogramRes; o->m_pPlProj->m_p2DF->SetLabelX("X [pm]"); o->m_pPlProj->m_p2DF->SetLabelY("Y [pm]"); o->m_pPlProj->m_p2DF->Create(); // mprintf("Observation %d: Creating %d VecArrays.\n",z+1,o->m_iShowMolCount); try { o->m_pPlProj->m_vaData = new CxDVec3Array[o->m_iShowMolCount]; } catch(...) { o->m_pPlProj->m_vaData = NULL; } if (o->m_pPlProj->m_vaData == NULL) NewException((double)o->m_iShowMolCount*sizeof(CxDVec3Array),__FILE__,__LINE__,__PRETTY_FUNCTION__); if (o->m_bBinOnlyPassedAtoms || o->m_bBinOnlyNotPassedAtoms) { try { o->m_pPlProj->m_baDataEnabled = new CxByteArray[o->m_iShowMolCount]; } catch(...) { o->m_pPlProj->m_baDataEnabled = NULL; } if (o->m_pPlProj->m_baDataEnabled == NULL) NewException((double)o->m_iShowMolCount*sizeof(CxByteArray),__FILE__,__LINE__,__PRETTY_FUNCTION__); } } if (g_bRDyn) { mprintf(" Creating reorientation dynamics...\n"); o->m_pRDyn->m_pRDyn->m_fMinVal = 0; o->m_pRDyn->m_pRDyn->m_fMaxVal = o->m_pRDyn->m_iDepth * g_fTimestepLength / 1000.0; o->m_pRDyn->m_pRDyn->m_iResolution = o->m_pRDyn->m_iDepth/o->m_pRDyn->m_iStride; o->m_pRDyn->m_pRDyn->SetLabelX("Tau [ps]"); o->m_pRDyn->m_pRDyn->SetLabelY("Vector autocorrelation"); o->m_pRDyn->m_pRDyn->Create(); if (g_bRDynCacheMode) { if (g_iTrajSteps != -1) mprintf(" RDyn Cache: Trying to allocate %s of memory...\n",FormatBytes((double)((CMolecule*)g_oaMolecules[o->m_iShowMol])->m_laSingleMolIndex.GetSize()*o->m_pRDyn->m_iCombinations*g_iTrajSteps/g_iStride*3.1*sizeof(double))); else mprintf(" RDyn Cache: Trying to allocate %s of memory...\n",FormatBytes((double)((CMolecule*)g_oaMolecules[o->m_iShowMol])->m_laSingleMolIndex.GetSize()*o->m_pRDyn->m_iCombinations*10000/g_iStride*3.1*sizeof(double))); for (z2=0;z2<((CMolecule*)g_oaMolecules[o->m_iShowMol])->m_laSingleMolIndex.GetSize()*o->m_pRDyn->m_iCombinations;z2++) { try { ptfa = new CxDoubleArray("main():ptfa"); } catch(...) { ptfa = NULL; } if (ptfa == NULL) NewException((double)sizeof(CxDoubleArray),__FILE__,__LINE__,__PRETTY_FUNCTION__); if (g_iTrajSteps != -1) { ptfa->SetMaxSize((long)(g_iTrajSteps/g_iStride*3.3)); ptfa->SetGrow((long)(g_iTrajSteps/g_iStride*0.3)); } else ptfa->SetGrow(10000); o->m_pRDyn->m_oaCache.Add(ptfa); } } else { try { o->m_pRDyn->m_pCount = new double[o->m_pRDyn->m_pRDyn->m_iResolution]; } catch(...) { o->m_pRDyn->m_pCount = NULL; } if (o->m_pRDyn->m_pCount == NULL) NewException((double)o->m_pRDyn->m_pRDyn->m_iResolution*sizeof(double),__FILE__,__LINE__,__PRETTY_FUNCTION__); for (z2=0;z2m_pRDyn->m_pRDyn->m_iResolution;z2++) o->m_pRDyn->m_pCount[z2] = 0; if (!g_bRDynCacheMode) { if (o->m_pRDyn->m_iDepth > g_iStepHistory) g_iStepHistory = o->m_pRDyn->m_iDepth; } } } if (g_bIRSpec) { mprintf(" Creating IR spectrum...\n"); o->m_pIRSpec->m_pRDyn->m_fMinVal = 0; o->m_pIRSpec->m_pRDyn->m_fMaxVal = o->m_pIRSpec->m_iDepth * g_fTimestepLength / 1000.0; o->m_pIRSpec->m_pRDyn->m_iResolution = o->m_pIRSpec->m_iDepth/o->m_pIRSpec->m_iStride; o->m_pIRSpec->m_pRDyn->SetLabelX("Tau [ps]"); o->m_pIRSpec->m_pRDyn->SetLabelY("Dipole autocorrelation"); o->m_pIRSpec->m_pRDyn->Create(); if (g_bRDynCacheMode) { if (g_iTrajSteps != -1) mprintf(" RDyn Cache: Trying to allocate %s of memory...\n",FormatBytes((double)((CMolecule*)g_oaMolecules[o->m_iShowMol])->m_laSingleMolIndex.GetSize()*o->m_pIRSpec->m_iCombinations*g_iTrajSteps/g_iStride*3.1*sizeof(double))); else mprintf(" RDyn Cache: Trying to allocate %s of memory...\n",FormatBytes((double)((CMolecule*)g_oaMolecules[o->m_iShowMol])->m_laSingleMolIndex.GetSize()*o->m_pIRSpec->m_iCombinations*10000/g_iStride*3.1*sizeof(double))); for (z2=0;z2<((CMolecule*)g_oaMolecules[o->m_iShowMol])->m_laSingleMolIndex.GetSize()*o->m_pIRSpec->m_iCombinations;z2++) { try { ptfa = new CxDoubleArray("main():ptfa"); } catch(...) { ptfa = NULL; } if (ptfa == NULL) NewException((double)sizeof(CxDoubleArray),__FILE__,__LINE__,__PRETTY_FUNCTION__); if (g_iTrajSteps != -1) { ptfa->SetMaxSize((long)(g_iTrajSteps/g_iStride*3.3)); ptfa->SetGrow((long)(g_iTrajSteps/g_iStride*0.3)); } else ptfa->SetGrow(10000); o->m_pIRSpec->m_oaCache.Add(ptfa); } } else { try { o->m_pIRSpec->m_pCount = new double[o->m_pIRSpec->m_pRDyn->m_iResolution]; } catch(...) { o->m_pIRSpec->m_pCount = NULL; } if (o->m_pIRSpec->m_pCount == NULL) NewException((double)o->m_pIRSpec->m_pRDyn->m_iResolution*sizeof(double),__FILE__,__LINE__,__PRETTY_FUNCTION__); for (z2=0;z2m_pIRSpec->m_pRDyn->m_iResolution;z2++) o->m_pIRSpec->m_pCount[z2] = 0; if (!g_bRDynCacheMode) { if (o->m_pIRSpec->m_iDepth > g_iStepHistory) g_iStepHistory = o->m_pIRSpec->m_iDepth; } } } if (g_bDens) { mprintf(" Creating density distribution function...\n"); o->m_pDensityDF->m_pDensDF->m_fMinVal = o->m_pDensityDF->m_fMinDist; o->m_pDensityDF->m_pDensDF->m_fMaxVal = o->m_pDensityDF->m_fMaxDist; o->m_pDensityDF->m_pDensDF->m_iResolution = o->m_pDensityDF->m_iResolution; o->m_pDensityDF->m_pDensDF->m_iHistogramRes = o->m_pDensityDF->m_iHistogramRes; o->m_pDensityDF->m_pDensDF->SetLabelX("Distance [pm]"); if (o->m_pDensityDF->m_bDensityMass) o->m_pDensityDF->m_pDensDF->SetLabelY("Mass Density [g/cm^3]"); else o->m_pDensityDF->m_pDensDF->SetLabelY("Particle Density [1/nm^3]"); o->m_pDensityDF->m_pDensDF->Create(); } if (g_bVHDF) { mprintf(" Creating VHCF...\n"); o->m_pVHDF->m_pVHDF->m_fMinVal[1] = o->m_pVHDF->m_fMinDist; o->m_pVHDF->m_pVHDF->m_fMaxVal[1] = o->m_pVHDF->m_fMaxDist; o->m_pVHDF->m_pVHDF->m_iRes[1] = o->m_pVHDF->m_iResolution; o->m_pVHDF->m_pVHDF->m_fMinVal[0] = 0.0; o->m_pVHDF->m_pVHDF->m_fMaxVal[0] = o->m_pVHDF->m_iDepth * g_fTimestepLength / 1000.0; o->m_pVHDF->m_pVHDF->m_iRes[0] = o->m_pVHDF->m_iDepth / o->m_pVHDF->m_iStride; o->m_pVHDF->m_pVHDF->Create(); try { o->m_pVHDF->m_pCount = new double[o->m_pVHDF->m_pVHDF->m_iRes[0]]; } catch(...) { o->m_pVHDF->m_pCount = NULL; } if (o->m_pVHDF->m_pCount == NULL) NewException((double)o->m_pVHDF->m_pVHDF->m_iRes[0]*sizeof(double),__FILE__,__LINE__,__PRETTY_FUNCTION__); for (z0=0;z0m_pVHDF->m_pVHDF->m_iRes[0];z0++) o->m_pVHDF->m_pCount[z0] = 0; o->m_pVHDF->m_pVHDF->SetLabelY("Distance [pm]"); o->m_pVHDF->m_pVHDF->SetLabelX("Tau [ps]"); // o->m_pVHDF->m_pVHDF->m_fPlotExp = 1.0; if (o->m_pVHDF->m_iDepth > g_iStepHistory) g_iStepHistory = o->m_pVHDF->m_iDepth; mprintf(" Setting trajectory ring buffer to %s...\n",FormatBytes((double)(g_iStepHistory*g_iGesVirtAtomCount*sizeof(double)*3))); } if (g_bNbAnalysis) { mprintf(" Creating neighborhood analysis...\n"); try { o->m_pNbAnalysis->m_pNPFCount = new CDF(); } catch(...) { o->m_pNbAnalysis->m_pNPFCount = NULL; } if (o->m_pNbAnalysis->m_pNPFCount == NULL) NewException((double)sizeof(CDF),__FILE__,__LINE__,__PRETTY_FUNCTION__); o->m_pNbAnalysis->m_pNPFCount->m_fMinVal = o->m_pNbAnalysis->m_fMinDist; o->m_pNbAnalysis->m_pNPFCount->m_fMaxVal = o->m_pNbAnalysis->m_fMaxDist; o->m_pNbAnalysis->m_pNPFCount->m_iResolution = o->m_pNbAnalysis->m_iResolution; o->m_pNbAnalysis->m_pNPFCount->Create(); try { tdf = new CDF(); } catch(...) { tdf = NULL; } if (tdf == NULL) NewException((double)sizeof(CDF),__FILE__,__LINE__,__PRETTY_FUNCTION__); tdf->m_fMinVal = o->m_pNbAnalysis->m_fMinDist; tdf->m_fMaxVal = o->m_pNbAnalysis->m_fMaxDist; tdf->m_iResolution = o->m_pNbAnalysis->m_iResolution; tdf->SetLabelX("Distance [pm]"); tdf->SetLabelY("Occurrence"); tdf->Create(); o->m_pNbAnalysis->m_oaNPF.Add(tdf); for (z2=0;z2<=o->m_pNbAnalysis->m_iNbCount;z2++) { try { tdf = new CDF(); } catch(...) { tdf = NULL; } if (tdf == NULL) NewException((double)sizeof(CDF),__FILE__,__LINE__,__PRETTY_FUNCTION__); tdf->m_fMinVal = o->m_pNbAnalysis->m_fMinDist; tdf->m_fMaxVal = o->m_pNbAnalysis->m_fMaxDist; tdf->m_iResolution = o->m_pNbAnalysis->m_iResolution; tdf->SetLabelX("Distance [pm]"); tdf->SetLabelY("Occurrence"); tdf->Create(); o->m_pNbAnalysis->m_oaDF.Add(tdf); try { tdf = new CDF(); } catch(...) { tdf = NULL; } if (tdf == NULL) NewException((double)sizeof(CDF),__FILE__,__LINE__,__PRETTY_FUNCTION__); tdf->m_fMinVal = o->m_pNbAnalysis->m_fMinDist; tdf->m_fMaxVal = o->m_pNbAnalysis->m_fMaxDist; tdf->m_iResolution = o->m_pNbAnalysis->m_iResolution; tdf->SetLabelX("Distance [pm]"); tdf->SetLabelY("Occurrence"); tdf->Create(); o->m_pNbAnalysis->m_oaNPF.Add(tdf); } } for (z0=0;z0m_pRDF[z0] != NULL)) { mprintf(" Creating RDF...\n"); o->m_pRDF[z0]->m_pRDF->m_fMinVal = o->m_pRDF[z0]->m_fMinDist; o->m_pRDF[z0]->m_pRDF->m_fMaxVal = o->m_pRDF[z0]->m_fMaxDist; o->m_pRDF[z0]->m_pRDF->m_iResolution = o->m_pRDF[z0]->m_iResolution; o->m_pRDF[z0]->m_pRDF->m_iHistogramRes = o->m_pRDF[z0]->m_iHistogramRes; o->m_pRDF[z0]->m_pRDF->SetLabelX("Distance [pm]"); if (o->m_pRDF[z0]->m_bProbDens) o->m_pRDF[z0]->m_pRDF->SetLabelY("g(r) [nm^(-3)]"); else o->m_pRDF[z0]->m_pRDF->SetLabelY("g(r)"); if (o->m_bObsCertain && o->m_bDecompDist) { o->m_pRDF[z0]->m_pRDF->CreateMulti(o->m_waObsRefList.GetSize()*o->m_waObsShowList.GetSize()); /* try { o->m_pRDF[z0]->m_pRDF->m_sLabelMulti = new char*[o->m_waObsRefList.GetSize()*o->m_waObsShowList.GetSize()]; } catch(...) { o->m_pRDF[z0]->m_pRDF->m_sLabelMulti = NULL; } if (o->m_pRDF[z0]->m_pRDF->m_sLabelMulti == NULL) NewException((double)o->m_waObsRefList.GetSize()*o->m_waObsShowList.GetSize()*sizeof(char*),__FILE__,__LINE__,__PRETTY_FUNCTION__); for (z=0;zm_waObsRefList.GetSize()*o->m_waObsShowList.GetSize();z++) { try { o->m_pRDF[z0]->m_pRDF->m_sLabelMulti[z] = new char[128]; } catch(...) { o->m_pRDF[z0]->m_pRDF->m_sLabelMulti[z] = NULL; } if (o->m_pRDF[z0]->m_pRDF->m_sLabelMulti[z] == NULL) NewException((double)128*sizeof(char),__FILE__,__LINE__,__PRETTY_FUNCTION__); } */ for (z3=0;z3m_waObsRefList.GetSize();z3++) { for (z2=0;z2m_waObsShowList.GetSize();z2++) { if ((o->m_waObsRefList.GetSize() > 1) && (o->m_waObsShowList.GetSize() > 1)) // sprintf(buf,"RM%d-OM%d",o->m_waObsRefList[z3]+1,o->m_waObsShowList[z2]+1); buf.sprintf("RM%d-OM%d",o->m_waObsRefList[z3]+1,o->m_waObsShowList[z2]+1); else if (o->m_waObsRefList.GetSize() > 1) // sprintf(buf,"RM%d",o->m_waObsRefList[z3]+1); buf.sprintf("RM%d",o->m_waObsRefList[z3]+1); else // sprintf(buf,"OM%d",o->m_waObsShowList[z2]+1); buf.sprintf("OM%d",o->m_waObsShowList[z2]+1); o->m_pRDF[z0]->m_pRDF->SetLabelMulti(z3*o->m_waObsShowList.GetSize()+z2,buf); } } } else if (o->m_bDecompType) { m = (CMolecule*)g_oaMolecules[g_iFixMol]; o->m_waDecompTypeRefOffs.SetSize(g_iGesVirtAtomCount); for (z3=0;z3m_pRDF[z0]->m_oaVectors.GetSize()/2;z3++) { ag = (CAtomGroup*)o->m_pRDF[z0]->m_oaVectors[z3*2]; for (z2=0;z2m_baRealAtomType.GetSize();z2++) { for (z3=0;z3m_waDecompTypeRefList.GetSize();z3++) if (o->m_waDecompTypeRefList[z3] == ag->m_baRealAtomType[z2]) goto _decomptype1; z3 = o->m_waDecompTypeRefList.GetSize(); o->m_waDecompTypeRefList.Add(ag->m_baRealAtomType[z2]); _decomptype1: for (z4=0;z4m_laSingleMolIndex.GetSize();z4++) { sm = (CSingleMolecule*)g_oaSingleMolecules[m->m_laSingleMolIndex[z4]]; for (z5=0;z5<((CxIntArray*)ag->m_oaAtoms[z2])->GetSize();z5++) o->m_waDecompTypeRefOffs[((CxIntArray*)sm->m_oaAtomOffset[ag->m_baAtomType[z2]])->GetAt(((CxIntArray*)ag->m_oaAtoms[z2])->GetAt(z5))] = (unsigned short)z3; } } } if (o->m_bOthers) m = (CMolecule*)g_oaMolecules[o->m_iShowMol]; else m = (CMolecule*)g_oaMolecules[g_iFixMol]; o->m_waDecompTypeObsOffs.SetSize(g_iGesVirtAtomCount); for (z6=0;z6m_pRDF[z0]->m_oaVectors.GetSize()/2;z6++) { ag = (CAtomGroup*)o->m_pRDF[z0]->m_oaVectors[z6*2+1]; for (z2=0;z2m_baRealAtomType.GetSize();z2++) { for (z3=0;z3m_waDecompTypeObsList.GetSize();z3++) if (o->m_waDecompTypeObsList[z3] == ag->m_baRealAtomType[z2]) goto _decomptype2; z3 = o->m_waDecompTypeObsList.GetSize(); o->m_waDecompTypeObsList.Add(ag->m_baRealAtomType[z2]); _decomptype2: for (z4=0;z4m_laSingleMolIndex.GetSize();z4++) { sm = (CSingleMolecule*)g_oaSingleMolecules[m->m_laSingleMolIndex[z4]]; for (z5=0;z5<((CxIntArray*)ag->m_oaAtoms[z2])->GetSize();z5++) o->m_waDecompTypeObsOffs[((CxIntArray*)sm->m_oaAtomOffset[ag->m_baAtomType[z2]])->GetAt(((CxIntArray*)ag->m_oaAtoms[z2])->GetAt(z5))] = (unsigned short)z3; } } } o->m_pRDF[z0]->m_pRDF->CreateMulti(o->m_waDecompTypeRefList.GetSize()*o->m_waDecompTypeObsList.GetSize()); /* try { o->m_pRDF[z0]->m_pRDF->m_sLabelMulti = new char*[o->m_waDecompTypeRefList.GetSize()*o->m_waDecompTypeObsList.GetSize()]; } catch(...) { o->m_pRDF[z0]->m_pRDF->m_sLabelMulti = NULL; } if (o->m_pRDF[z0]->m_pRDF->m_sLabelMulti == NULL) NewException((double)o->m_waDecompTypeRefList.GetSize()*o->m_waDecompTypeObsList.GetSize()*sizeof(char*),__FILE__,__LINE__,__PRETTY_FUNCTION__); for (z=0;zm_waDecompTypeRefList.GetSize()*o->m_waDecompTypeObsList.GetSize();z++) { try { o->m_pRDF[z0]->m_pRDF->m_sLabelMulti[z] = new char[128]; } catch(...) { o->m_pRDF[z0]->m_pRDF->m_sLabelMulti[z] = NULL; } if (o->m_pRDF[z0]->m_pRDF->m_sLabelMulti[z] == NULL) NewException((double)128*sizeof(char),__FILE__,__LINE__,__PRETTY_FUNCTION__); }*/ for (z3=0;z3m_waDecompTypeRefList.GetSize();z3++) { for (z2=0;z2m_waDecompTypeObsList.GetSize();z2++) { // sprintf(buf,"%s-%s",((CAtom*)g_oaAtoms[o->m_waDecompTypeRefList[z3]])->m_sName,((CAtom*)g_oaAtoms[o->m_waDecompTypeObsList[z2]])->m_sName); buf.sprintf("%s-%s",(const char*)((CAtom*)g_oaAtoms[o->m_waDecompTypeRefList[z3]])->m_sName,(const char*)((CAtom*)g_oaAtoms[o->m_waDecompTypeObsList[z2]])->m_sName); o->m_pRDF[z0]->m_pRDF->SetLabelMulti(z*o->m_waDecompTypeObsList.GetSize()+z2,buf); } } } else o->m_pRDF[z0]->m_pRDF->Create(); if (o->m_bSecondShowMol && (z0 == 1)) { try { o->m_pRDF[z0]->m_faData = new CxDoubleArray[o->m_iShowMol2Count]; } catch(...) { o->m_pRDF[z0]->m_faData = NULL; } if (o->m_pRDF[z0]->m_faData == NULL) NewException((double)o->m_iShowMol2Count*sizeof(CxDoubleArray),__FILE__,__LINE__,__PRETTY_FUNCTION__); if (o->m_bBinOnlyPassedAtoms || o->m_bBinOnlyNotPassedAtoms) { try { o->m_pRDF[z0]->m_baDataEnabled = new CxByteArray[o->m_iShowMol2Count]; } catch(...) { o->m_pRDF[z0]->m_baDataEnabled = NULL; } if (o->m_pRDF[z0]->m_baDataEnabled == NULL) NewException((double)o->m_iShowMol2Count*sizeof(CxByteArray),__FILE__,__LINE__,__PRETTY_FUNCTION__); } } else { try { o->m_pRDF[z0]->m_faData = new CxDoubleArray[o->m_iShowMolCount]; } catch(...) { o->m_pRDF[z0]->m_faData = NULL; } if (o->m_pRDF[z0]->m_faData == NULL) NewException((double)o->m_iShowMolCount*sizeof(CxDoubleArray),__FILE__,__LINE__,__PRETTY_FUNCTION__); if (o->m_bBinOnlyPassedAtoms || o->m_bBinOnlyNotPassedAtoms) { try { o->m_pRDF[z0]->m_baDataEnabled = new CxByteArray[o->m_iShowMolCount]; } catch(...) { o->m_pRDF[z0]->m_baDataEnabled = NULL; } if (o->m_pRDF[z0]->m_baDataEnabled == NULL) NewException((double)o->m_iShowMolCount*sizeof(CxByteArray),__FILE__,__LINE__,__PRETTY_FUNCTION__); } } if (o->m_bTimeDev) { if ((o->m_waSaveRefList.GetSize() == 1) || (!o->m_bSaveSeparateFiles)) { try { o->m_pRDF[z0]->m_fDist = new FILE*[1]; } catch(...) { o->m_pRDF[z0]->m_fDist = NULL; } if (o->m_pRDF[z0]->m_fDist == NULL) NewException((double)sizeof(FILE*),__FILE__,__LINE__,__PRETTY_FUNCTION__); // sprintf(buf,"rdf_timedev_%s%s.csv",o->m_pRDF[z0]->m_sName,multibuf); buf.sprintf("rdf_timedev_%s%s.csv",o->m_pRDF[z0]->m_sName,multibuf); o->m_pRDF[z0]->m_fDist[0] = OpenFileWrite(buf,true); } else { try { o->m_pRDF[z0]->m_fDist = new FILE*[o->m_waSaveRefList.GetSize()]; } catch(...) { o->m_pRDF[z0]->m_fDist = NULL; } if (o->m_pRDF[z0]->m_fDist == NULL) NewException((double)o->m_waSaveRefList.GetSize()*sizeof(FILE*),__FILE__,__LINE__,__PRETTY_FUNCTION__); for (z2=0;z2m_waSaveRefList.GetSize();z2++) { // sprintf(buf,"rdf_timedev_%s_ref%d%s.csv",o->m_pRDF[z0]->m_sName,o->m_waSaveRefList[z2]+1,multibuf); buf.sprintf("rdf_timedev_%s_ref%d%s.csv",o->m_pRDF[z0]->m_sName,o->m_waSaveRefList[z2]+1,multibuf); o->m_pRDF[z0]->m_fDist[z2] = OpenFileWrite(buf,true); } } if (o->m_bCombinedPlot) { // mprintf("Combined: Reflist %d, Showlist %d, Combinations %d, Steps %d.\n",o->m_waSaveRefList.GetSize(),o->m_waSaveShowList.GetSize(),o->m_pRDF[z0]->m_iCombinations,g_iTrajSteps); try { o->m_pRDF[z0]->m_pRDF->m_pCombinedPlot = new CGrace(); } catch(...) { o->m_pRDF[z0]->m_pRDF->m_pCombinedPlot = NULL; } if (o->m_pRDF[z0]->m_pRDF->m_pCombinedPlot == NULL) NewException((double)sizeof(CGrace),__FILE__,__LINE__,__PRETTY_FUNCTION__); o->m_pRDF[z0]->m_pRDF->m_pCombinedPlot->SetTitle("Combined distance time development/histogram"); o->m_pRDF[z0]->m_pRDF->m_pCombinedPlot->SetSubTitle(o->m_pRDF[z0]->m_sShortName); // smfix = (CSingleMolecule*)g_oaSingleMolecules[((CMolecule*)g_oaMolecules[g_iFixMol])->m_laSingleMolIndex[0]]; // sm = (CSingleMolecule*)g_oaSingleMolecules[((CMolecule*)g_oaMolecules[o->m_iShowMol])->m_laSingleMolIndex[0]]; // o->m_pRDF[z0]->BuildAtomList(smfix,sm,sm,&templa); mprintf(" Trying to reserve %s of memory for combined plot...\n",FormatBytes((double)sizeof(double)*o->m_waSaveRefList.GetSize()*o->m_waSaveShowList.GetSize()*o->m_pRDF[z0]->m_iCombinations*g_iTrajSteps/g_iStride)); for (z2=0;z2m_waSaveRefList.GetSize();z2++) { for (z3=0;z3m_waSaveShowList.GetSize();z3++) { /* for (z4=0;z4m_pRDF[z0]->m_pRDF->m_pCombinedPlot->AddDataset(); sprintf(buf,"%s[%d] %s%d - %s[%d] %s%d",((CMolecule*)g_oaMolecules[g_iFixMol])->m_sName,o->m_waSaveRefList[z2]+1,((CAtom*)g_oaAtoms[((CMolecule*)g_oaMolecules[g_iFixMol])->m_baAtomIndex[g_waAtomElement[templa[z4*2]]]])->m_sName,g_waAtomMolNumber[templa[z4*2]]+1,((CMolecule*)g_oaMolecules[o->m_iShowMol])->m_sName,o->m_waSaveShowList[z3]+1,((CAtom*)g_oaAtoms[((CMolecule*)g_oaMolecules[o->m_iShowMol])->m_baAtomIndex[g_waAtomElement[templa[z4*2+1]]]])->m_sName,g_waAtomMolNumber[templa[z4*2+1]]+1); o->m_pRDF[z0]->m_pRDF->m_pCombinedPlot->SetDatasetName(buf); if (g_iTrajSteps != -1) o->m_pRDF[z0]->m_pRDF->m_pCombinedPlot->LastDataset()->m_faValues.SetMaxSize(o->m_waSaveRefList.GetSize()*o->m_waSaveShowList.GetSize() *g_iTrajSteps); o->m_pRDF[z0]->m_pRDF->m_pCombinedPlot->LastDataset()->m_faValues.SetGrow(o->m_waSaveRefList.GetSize()*o->m_waSaveShowList.GetSize() *100); if (o->m_bCombinedGreyMode) { ti = o->m_iCombinedGreyMin + ((z4+z3*o->m_pRDF[z0]->m_iCombinations+z2*o->m_pRDF[z0]->m_iCombinations*o->m_waSaveShowList.GetSize())%o->m_iCombinedGreyShades)*(o->m_iCombinedGreyMax-o->m_iCombinedGreyMin)/o->m_iCombinedGreyShades; o->m_pRDF[z0]->m_pRDF->m_pCombinedPlot->LastDataset()->m_iLineColor = ti*0x10000 + ti*0x100 + ti; } }*/ ti2 = 0; for (z4=0;z4m_pRDF[z0]->m_oaVectors.GetSize()/2;z4++) { g1 = (CAtomGroup*)o->m_pRDF[z0]->m_oaVectors[z4*2]; for (z1t=0;z1tm_baAtomType.GetSize();z1t++) { a1 = (CxIntArray*)g1->m_oaAtoms[z1t]; for (z1a=0;z1aGetSize();z1a++) { g2 = (CAtomGroup*)o->m_pRDF[z0]->m_oaVectors[z4*2+1]; for (z2t=0;z2tm_baAtomType.GetSize();z2t++) { a2 = (CxIntArray*)g2->m_oaAtoms[z2t]; for (z2a=0;z2aGetSize();z2a++) { o->m_pRDF[z0]->m_pRDF->m_pCombinedPlot->AddDataset(); if (o->m_bOthers) // sprintf(buf,"%s[%d] %s%d - %s[%d] %s%d",((CMolecule*)g_oaMolecules[g_iFixMol])->m_sName,o->m_waSaveRefList[z2]+1,((CAtom*)g_oaAtoms[g1->m_baRealAtomType[z1t]])->m_sName,a1->GetAt(z1a)+1,((CMolecule*)g_oaMolecules[o->m_iShowMol])->m_sName,o->m_waSaveShowList[z3]+1,((CAtom*)g_oaAtoms[g2->m_baRealAtomType[z2t]])->m_sName,a2->GetAt(z2a)+1); buf.sprintf("%s[%d] %s%d - %s[%d] %s%d",((CMolecule*)g_oaMolecules[g_iFixMol])->m_sName,o->m_waSaveRefList[z2]+1,(const char*)((CAtom*)g_oaAtoms[g1->m_baRealAtomType[z1t]])->m_sName,a1->GetAt(z1a)+1,((CMolecule*)g_oaMolecules[o->m_iShowMol])->m_sName,o->m_waSaveShowList[z3]+1,(const char*)((CAtom*)g_oaAtoms[g2->m_baRealAtomType[z2t]])->m_sName,a2->GetAt(z2a)+1); else // sprintf(buf,"%s[%d] %s%d - %s%d",((CMolecule*)g_oaMolecules[g_iFixMol])->m_sName,o->m_waSaveRefList[z2]+1,((CAtom*)g_oaAtoms[g1->m_baRealAtomType[z1t]])->m_sName,a1->GetAt(z1a)+1,((CAtom*)g_oaAtoms[g2->m_baRealAtomType[z2t]])->m_sName,a2->GetAt(z2a)+1); buf.sprintf("%s[%d] %s%d - %s%d",((CMolecule*)g_oaMolecules[g_iFixMol])->m_sName,o->m_waSaveRefList[z2]+1,(const char*)((CAtom*)g_oaAtoms[g1->m_baRealAtomType[z1t]])->m_sName,a1->GetAt(z1a)+1,(const char*)((CAtom*)g_oaAtoms[g2->m_baRealAtomType[z2t]])->m_sName,a2->GetAt(z2a)+1); o->m_pRDF[z0]->m_pRDF->m_pCombinedPlot->SetDatasetName(buf); if (g_iTrajSteps != -1) o->m_pRDF[z0]->m_pRDF->m_pCombinedPlot->LastDataset()->m_faValues.SetMaxSize(o->m_waSaveRefList.GetSize()*o->m_waSaveShowList.GetSize()/**o->m_pRDF[z0]->m_iCombinations*/ *g_iTrajSteps/g_iStride); o->m_pRDF[z0]->m_pRDF->m_pCombinedPlot->LastDataset()->m_faValues.SetGrow(o->m_waSaveRefList.GetSize()*o->m_waSaveShowList.GetSize()/**o->m_pRDF[z0]->m_iCombinations*/ *100); if (o->m_bCombinedGreyMode) { ti = o->m_iCombinedGreyMin + ((ti2+z3*o->m_pRDF[z0]->m_iCombinations+z2*o->m_pRDF[z0]->m_iCombinations*o->m_waSaveShowList.GetSize())%o->m_iCombinedGreyShades)*(o->m_iCombinedGreyMax-o->m_iCombinedGreyMin)/o->m_iCombinedGreyShades; o->m_pRDF[z0]->m_pRDF->m_pCombinedPlot->SetSetLineColor((unsigned char)ti,(unsigned char)ti,(unsigned char)ti); } ti2++; /* if (o->m_pRDF[z0]->m_iRefOrSec[0]) vec->Add(((CxIntArray*)obs->m_oaAtomOffset[g1->m_baAtomType[z1t]])->GetAt(a1->GetAt(z1a))); else vec->Add(((CxIntArray*)ref->m_oaAtomOffset[g1->m_baAtomType[z1t]])->GetAt(a1->GetAt(z1a))); if (o->m_pRDF[z0]->m_iRefOrSec[1]) vec->Add(((CxIntArray*)obs->m_oaAtomOffset[g2->m_baAtomType[z2t]])->GetAt(a2->GetAt(z2a))); else vec->Add(((CxIntArray*)ref->m_oaAtomOffset[g2->m_baAtomType[z2t]])->GetAt(a2->GetAt(z2a))); */ // mprintf("Vector z=%d, z1t=%d, z1a=%d, z2t=%d, z2a=%d.\n",z,z1t,z1a,z2t,z2a); } } } } } } } o->m_pRDF[z0]->m_pRDF->m_pCombinedPlot->SetLabelX("Time [ps] / g(r)"); o->m_pRDF[z0]->m_pRDF->m_pCombinedPlot->SetLabelY("Distance [pm]"); } } // END IF TIMEDEV if (o->m_bTimeDiff) o->CreateTimeDiff(o->m_pRDF[z0]->m_pRDF,o->m_pRDF[z0]->m_iCombinations); if (g_bDeriv) o->m_pRDF[z0]->InitDeriv(); } // END IF RDF if (g_bADF && (o->m_pADF[z0] != NULL)) { mprintf(" Creating ADF...\n"); o->m_pADF[z0]->m_pADF->m_fMinVal = o->m_pADF[z0]->m_fMinAngle; o->m_pADF[z0]->m_pADF->m_fMaxVal = o->m_pADF[z0]->m_fMaxAngle; o->m_pADF[z0]->m_pADF->m_iResolution = o->m_pADF[z0]->m_iResolution; o->m_pADF[z0]->m_pADF->m_iHistogramRes = o->m_pADF[z0]->m_iHistogramRes; if (o->m_pADF[z0]->m_bCosine) o->m_pADF[z0]->m_pADF->SetLabelX("Cos(angle)"); else o->m_pADF[z0]->m_pADF->SetLabelX("Angle (degree)"); o->m_pADF[z0]->m_pADF->SetLabelY("Occurrence"); if (o->m_bObsCertain && o->m_bDecompDist) o->m_pADF[z0]->m_pADF->CreateMulti(o->m_waObsRefList.GetSize()*o->m_waObsShowList.GetSize()); else o->m_pADF[z0]->m_pADF->Create(); if (o->m_bSecondShowMol && (z0 == 1)) { try { o->m_pADF[z0]->m_faData = new CxDoubleArray[o->m_iShowMol2Count]; } catch(...) { o->m_pADF[z0]->m_faData = NULL; } if (o->m_pADF[z0]->m_faData == NULL) NewException((double)o->m_iShowMol2Count*sizeof(CxDoubleArray),__FILE__,__LINE__,__PRETTY_FUNCTION__); if (o->m_bBinOnlyPassedAtoms || o->m_bBinOnlyNotPassedAtoms) { try { o->m_pADF[z0]->m_baDataEnabled = new CxByteArray[o->m_iShowMol2Count]; } catch(...) { o->m_pADF[z0]->m_baDataEnabled = NULL; } if (o->m_pADF[z0]->m_baDataEnabled == NULL) NewException((double)o->m_iShowMol2Count*sizeof(CxByteArray),__FILE__,__LINE__,__PRETTY_FUNCTION__); } } else { try { o->m_pADF[z0]->m_faData = new CxDoubleArray[o->m_iShowMolCount]; } catch(...) { o->m_pADF[z0]->m_faData = NULL; } if (o->m_pADF[z0]->m_faData == NULL) NewException((double)o->m_iShowMolCount*sizeof(CxDoubleArray),__FILE__,__LINE__,__PRETTY_FUNCTION__); if (o->m_bBinOnlyPassedAtoms || o->m_bBinOnlyNotPassedAtoms) { try { o->m_pADF[z0]->m_baDataEnabled = new CxByteArray[o->m_iShowMolCount]; } catch(...) { o->m_pADF[z0]->m_baDataEnabled = NULL; } if (o->m_pADF[z0]->m_baDataEnabled == NULL) NewException((double)o->m_iShowMolCount*sizeof(CxByteArray),__FILE__,__LINE__,__PRETTY_FUNCTION__); } } if (o->m_bTimeDev) { if ((o->m_waSaveRefList.GetSize() == 1) || (!o->m_bSaveSeparateFiles)) { try { o->m_pADF[z0]->m_fAngle = new FILE*[1]; } catch(...) { o->m_pADF[z0]->m_fAngle = NULL; } if (o->m_pADF[z0]->m_fAngle == NULL) NewException((double)sizeof(FILE*),__FILE__,__LINE__,__PRETTY_FUNCTION__); // sprintf(buf,"adf_timedev_%s%s.csv",o->m_pADF[z0]->m_sName,multibuf); buf.sprintf("adf_timedev_%s%s.csv",o->m_pADF[z0]->m_sName,multibuf); o->m_pADF[z0]->m_fAngle[0] = OpenFileWrite(buf,true); } else { try { o->m_pADF[z0]->m_fAngle = new FILE*[o->m_waSaveRefList.GetSize()]; } catch(...) { o->m_pADF[z0]->m_fAngle = NULL; } if (o->m_pADF[z0]->m_fAngle == NULL) NewException((double)o->m_waSaveRefList.GetSize()*sizeof(FILE*),__FILE__,__LINE__,__PRETTY_FUNCTION__); for (z2=0;z2m_waSaveRefList.GetSize();z2++) { // sprintf(buf,"adf_timedev_%s_ref%d%s.csv",o->m_pADF[z0]->m_sName,o->m_waSaveRefList[z2]+1,multibuf); buf.sprintf("adf_timedev_%s_ref%d%s.csv",o->m_pADF[z0]->m_sName,o->m_waSaveRefList[z2]+1,multibuf); o->m_pADF[z0]->m_fAngle[z2] = OpenFileWrite(buf,true); } } if (o->m_bCombinedPlot) { try { o->m_pADF[z0]->m_pADF->m_pCombinedPlot = new CGrace(); } catch(...) { o->m_pADF[z0]->m_pADF->m_pCombinedPlot = NULL; } if (o->m_pADF[z0]->m_pADF->m_pCombinedPlot == NULL) NewException((double)sizeof(CGrace),__FILE__,__LINE__,__PRETTY_FUNCTION__); o->m_pADF[z0]->m_pADF->m_pCombinedPlot->SetTitle("Combined angle time development/histogram"); o->m_pADF[z0]->m_pADF->m_pCombinedPlot->SetSubTitle(o->m_pADF[z0]->m_sShortName); for (z2=0;z2m_waSaveRefList.GetSize();z2++) { for (z3=0;z3m_waSaveShowList.GetSize();z3++) { for (z4=0;z4m_pADF[z0]->m_iCombinations;z4++) { o->m_pADF[z0]->m_pADF->m_pCombinedPlot->AddDataset(); if (g_iTrajSteps != -1) o->m_pADF[z0]->m_pADF->m_pCombinedPlot->LastDataset()->m_faValues.SetMaxSize(o->m_waSaveRefList.GetSize()*o->m_waSaveShowList.GetSize()*o->m_pADF[z0]->m_iCombinations*g_iTrajSteps); o->m_pADF[z0]->m_pADF->m_pCombinedPlot->LastDataset()->m_faValues.SetGrow(o->m_waSaveRefList.GetSize()*o->m_waSaveShowList.GetSize()*o->m_pADF[z0]->m_iCombinations*100); if (o->m_bCombinedGreyMode) { ti = o->m_iCombinedGreyMin + ((z4+z3*o->m_pADF[z0]->m_iCombinations+z2*o->m_pADF[z0]->m_iCombinations*o->m_waSaveShowList.GetSize())%o->m_iCombinedGreyShades)*(o->m_iCombinedGreyMax-o->m_iCombinedGreyMin)/o->m_iCombinedGreyShades; o->m_pADF[z0]->m_pADF->m_pCombinedPlot->SetSetLineColor((unsigned char)ti,(unsigned char)ti,(unsigned char)ti); } // o->m_pADF[z0]->m_pADF->m_pCombinedPlot->SetSetLineWidth((z2*o->m_waSaveRefList.GetSize()+z3)*o->m_pADF[z0]->m_iCombinations+z4,2.0f); } } } o->m_pADF[z0]->m_pADF->m_pCombinedPlot->SetLabelX("Time [ps] / ADF(r)"); o->m_pADF[z0]->m_pADF->m_pCombinedPlot->SetLabelY("Angle [Degree]"); } } // END IF TIMEDEV if (o->m_bTimeDiff) o->CreateTimeDiff(o->m_pADF[z0]->m_pADF,o->m_pADF[z0]->m_iCombinations); if (g_bDeriv) o->m_pADF[z0]->InitDeriv(); } // END IF ADF if (g_bDipDF && (o->m_pDipDF[z0] != NULL)) { mprintf(" Creating DipDF...\n"); o->m_pDipDF[z0]->m_pDipoleDF->m_fMinVal = o->m_pDipDF[z0]->m_fDipoleMin; o->m_pDipDF[z0]->m_pDipoleDF->m_fMaxVal = o->m_pDipDF[z0]->m_fDipoleMax; o->m_pDipDF[z0]->m_pDipoleDF->m_iResolution = o->m_pDipDF[z0]->m_iResolution; o->m_pDipDF[z0]->m_pDipoleDF->m_iHistogramRes = o->m_pDipDF[z0]->m_iHistogramRes; o->m_pDipDF[z0]->m_pDipoleDF->SetLabelX("Dipole moment (Debye)"); o->m_pDipDF[z0]->m_pDipoleDF->SetLabelY("Occurrence"); if (o->m_bObsCertain && o->m_bDecompDist) o->m_pDipDF[z0]->m_pDipoleDF->CreateMulti(o->m_waObsRefList.GetSize()*o->m_waObsShowList.GetSize()); else o->m_pDipDF[z0]->m_pDipoleDF->Create(); if (o->m_bSecondShowMol && (z0 == 1)) { try { o->m_pDipDF[z0]->m_faData = new CxDoubleArray[o->m_iShowMol2Count]; } catch(...) { o->m_pDipDF[z0]->m_faData = NULL; } if (o->m_pDipDF[z0]->m_faData == NULL) NewException((double)o->m_iShowMol2Count*sizeof(CxDoubleArray),__FILE__,__LINE__,__PRETTY_FUNCTION__); if (o->m_bBinOnlyPassedAtoms || o->m_bBinOnlyNotPassedAtoms) { try { o->m_pDipDF[z0]->m_baDataEnabled = new CxByteArray[o->m_iShowMol2Count]; } catch(...) { o->m_pDipDF[z0]->m_baDataEnabled = NULL; } if (o->m_pDipDF[z0]->m_baDataEnabled == NULL) NewException((double)o->m_iShowMol2Count*sizeof(CxByteArray),__FILE__,__LINE__,__PRETTY_FUNCTION__); } } else { try { o->m_pDipDF[z0]->m_faData = new CxDoubleArray[o->m_iShowMolCount]; } catch(...) { o->m_pDipDF[z0]->m_faData = NULL; } if (o->m_pDipDF[z0]->m_faData == NULL) NewException((double)o->m_iShowMolCount*sizeof(CxDoubleArray),__FILE__,__LINE__,__PRETTY_FUNCTION__); if (o->m_bBinOnlyPassedAtoms || o->m_bBinOnlyNotPassedAtoms) { try { o->m_pDipDF[z0]->m_baDataEnabled = new CxByteArray[o->m_iShowMolCount]; } catch(...) { o->m_pDipDF[z0]->m_baDataEnabled = NULL; } if (o->m_pDipDF[z0]->m_baDataEnabled == NULL) NewException((double)o->m_iShowMolCount*sizeof(CxByteArray),__FILE__,__LINE__,__PRETTY_FUNCTION__); } } if (o->m_bTimeDev) { if ((o->m_waSaveRefList.GetSize() == 1) || (!o->m_bSaveSeparateFiles)) { try { o->m_pDipDF[z0]->m_fDipole = new FILE*[1]; } catch(...) { o->m_pDipDF[z0]->m_fDipole = NULL; } if (o->m_pDipDF[z0]->m_fDipole == NULL) NewException((double)sizeof(FILE*),__FILE__,__LINE__,__PRETTY_FUNCTION__); // sprintf(buf,"dipole_timedev_%s%s.csv",o->m_pDipDF[z0]->m_sName,multibuf); buf.sprintf("dipole_timedev_%s%s.csv",o->m_pDipDF[z0]->m_sName,multibuf); o->m_pDipDF[z0]->m_fDipole[0] = OpenFileWrite(buf,true); } else { try { o->m_pDipDF[z0]->m_fDipole = new FILE*[o->m_waSaveRefList.GetSize()]; } catch(...) { o->m_pDipDF[z0]->m_fDipole = NULL; } if (o->m_pDipDF[z0]->m_fDipole == NULL) NewException((double)o->m_waSaveRefList.GetSize()*sizeof(FILE*),__FILE__,__LINE__,__PRETTY_FUNCTION__); for (z2=0;z2m_waSaveRefList.GetSize();z2++) { // sprintf(buf,"dipole_timedev_%s_ref%d%s.csv",o->m_pDipDF[z0]->m_sName,o->m_waSaveRefList[z2]+1,multibuf); buf.sprintf("dipole_timedev_%s_ref%d%s.csv",o->m_pDipDF[z0]->m_sName,o->m_waSaveRefList[z2]+1,multibuf); o->m_pDipDF[z0]->m_fDipole[z2] = OpenFileWrite(buf,true); } } if (o->m_bCombinedPlot) { try { o->m_pDipDF[z0]->m_pDipoleDF->m_pCombinedPlot = new CGrace(); } catch(...) { o->m_pDipDF[z0]->m_pDipoleDF->m_pCombinedPlot = NULL; } if (o->m_pDipDF[z0]->m_pDipoleDF->m_pCombinedPlot == NULL) NewException((double)sizeof(CGrace),__FILE__,__LINE__,__PRETTY_FUNCTION__); o->m_pDipDF[z0]->m_pDipoleDF->m_pCombinedPlot->SetTitle("Combined dipole moment time development/histogram"); o->m_pDipDF[z0]->m_pDipoleDF->m_pCombinedPlot->SetSubTitle(o->m_pDipDF[z0]->m_sShortName); for (z2=0;z2m_waSaveRefList.GetSize();z2++) for (z3=0;z3m_waSaveShowList.GetSize();z3++) { o->m_pDipDF[z0]->m_pDipoleDF->m_pCombinedPlot->AddDataset(); if (g_iTrajSteps != -1) o->m_pDipDF[z0]->m_pDipoleDF->m_pCombinedPlot->LastDataset()->m_faValues.SetMaxSize(o->m_waSaveRefList.GetSize()*o->m_waSaveShowList.GetSize()*g_iTrajSteps); o->m_pDipDF[z0]->m_pDipoleDF->m_pCombinedPlot->LastDataset()->m_faValues.SetGrow(o->m_waSaveRefList.GetSize()*o->m_waSaveShowList.GetSize()*100); if (o->m_bCombinedGreyMode) { ti = o->m_iCombinedGreyMin + ((z3+z2*o->m_waSaveShowList.GetSize())%o->m_iCombinedGreyShades)*(o->m_iCombinedGreyMax-o->m_iCombinedGreyMin)/o->m_iCombinedGreyShades; o->m_pDipDF[z0]->m_pDipoleDF->m_pCombinedPlot->SetSetLineColor((unsigned char)ti,(unsigned char)ti,(unsigned char)ti); } } o->m_pDipDF[z0]->m_pDipoleDF->m_pCombinedPlot->SetLabelX("Time [ps] / DipDF(r)"); o->m_pDipDF[z0]->m_pDipoleDF->m_pCombinedPlot->SetLabelY("Dipole moment [Debye]"); } } // END IF TIMEDEV if (o->m_bTimeDiff) o->CreateTimeDiff(o->m_pDipDF[z0]->m_pDipoleDF,1); if (g_bDeriv) o->m_pDipDF[z0]->InitDeriv(); } // END IF DIPOLE if (g_bVDF && (o->m_pVDF[z0] != NULL)) { mprintf(" Creating VDF...\n"); o->m_pVDF[z0]->m_pVDF->m_fMinVal = o->m_pVDF[z0]->m_fMinSpeed; o->m_pVDF[z0]->m_pVDF->m_fMaxVal = o->m_pVDF[z0]->m_fMaxSpeed; o->m_pVDF[z0]->m_pVDF->m_iResolution = o->m_pVDF[z0]->m_iResolution; o->m_pVDF[z0]->m_pVDF->m_iHistogramRes = o->m_pVDF[z0]->m_iHistogramRes; o->m_pVDF[z0]->m_pVDF->SetLabelX("Velocity [pm/ps]"); o->m_pVDF[z0]->m_pVDF->SetLabelY("Occurrence"); if (o->m_bObsCertain && o->m_bDecompDist) o->m_pVDF[z0]->m_pVDF->CreateMulti(o->m_waObsRefList.GetSize()*o->m_waObsShowList.GetSize()); else o->m_pVDF[z0]->m_pVDF->Create(); if (o->m_pVDF[z0]->m_bSplitCart) { for (z2=0;z2<6;z2++) { o->m_pVDF[z0]->m_pVDFSplit[z2] = new CDF(); o->m_pVDF[z0]->m_pVDFSplit[z2]->m_fMinVal = o->m_pVDF[z0]->m_fMinSpeed; o->m_pVDF[z0]->m_pVDFSplit[z2]->m_fMaxVal = o->m_pVDF[z0]->m_fMaxSpeed; o->m_pVDF[z0]->m_pVDFSplit[z2]->m_iResolution = o->m_pVDF[z0]->m_iResolution; o->m_pVDF[z0]->m_pVDFSplit[z2]->m_iHistogramRes = o->m_pVDF[z0]->m_iHistogramRes; switch(z2) { case 0: o->m_pVDF[z0]->m_pVDFSplit[z2]->SetLabelX("Velocity X Projection [pm/ps]"); break; case 1: o->m_pVDF[z0]->m_pVDFSplit[z2]->SetLabelX("Velocity Y Projection [pm/ps]"); break; case 2: o->m_pVDF[z0]->m_pVDFSplit[z2]->SetLabelX("Velocity Z Projection [pm/ps]"); break; case 3: o->m_pVDF[z0]->m_pVDFSplit[z2]->SetLabelX("Velocity XY Projection [pm/ps]"); break; case 4: o->m_pVDF[z0]->m_pVDFSplit[z2]->SetLabelX("Velocity XZ Projection [pm/ps]"); break; case 5: o->m_pVDF[z0]->m_pVDFSplit[z2]->SetLabelX("Velocity YZ Projection [pm/ps]"); break; } o->m_pVDF[z0]->m_pVDFSplit[z2]->SetLabelY("Occurrence"); o->m_pVDF[z0]->m_pVDFSplit[z2]->Create(); } } if (o->m_bSecondShowMol && (z0 == 1)) { try { o->m_pVDF[z0]->m_faData = new CxDoubleArray[o->m_iShowMol2Count]; } catch(...) { o->m_pVDF[z0]->m_faData = NULL; } if (o->m_pVDF[z0]->m_faData == NULL) NewException((double)o->m_iShowMol2Count*sizeof(CxDoubleArray),__FILE__,__LINE__,__PRETTY_FUNCTION__); if (o->m_bBinOnlyPassedAtoms || o->m_bBinOnlyNotPassedAtoms) { try { o->m_pVDF[z0]->m_baDataEnabled = new CxByteArray[o->m_iShowMol2Count]; } catch(...) { o->m_pVDF[z0]->m_baDataEnabled = NULL; } if (o->m_pVDF[z0]->m_baDataEnabled == NULL) NewException((double)o->m_iShowMol2Count*sizeof(CxByteArray),__FILE__,__LINE__,__PRETTY_FUNCTION__); } } else { try { o->m_pVDF[z0]->m_faData = new CxDoubleArray[o->m_iShowMolCount]; } catch(...) { o->m_pVDF[z0]->m_faData = NULL; } if (o->m_pVDF[z0]->m_faData == NULL) NewException((double)o->m_iShowMolCount*sizeof(CxDoubleArray),__FILE__,__LINE__,__PRETTY_FUNCTION__); if (o->m_bBinOnlyPassedAtoms || o->m_bBinOnlyNotPassedAtoms) { try { o->m_pVDF[z0]->m_baDataEnabled = new CxByteArray[o->m_iShowMolCount]; } catch(...) { o->m_pVDF[z0]->m_baDataEnabled = NULL; } if (o->m_pVDF[z0]->m_baDataEnabled == NULL) NewException((double)o->m_iShowMolCount*sizeof(CxByteArray),__FILE__,__LINE__,__PRETTY_FUNCTION__); } } if (o->m_bTimeDev) { if ((o->m_waSaveRefList.GetSize() == 1) || (!o->m_bSaveSeparateFiles)) { try { o->m_pVDF[z0]->m_fSpeed = new FILE*[1]; } catch(...) { o->m_pVDF[z0]->m_fSpeed = NULL; } if (o->m_pVDF[z0]->m_fSpeed == NULL) NewException((double)sizeof(FILE*),__FILE__,__LINE__,__PRETTY_FUNCTION__); // sprintf(buf,"vdf_timedev_%s%s.csv",o->m_pVDF[z0]->m_sName,multibuf); buf.sprintf("vdf_timedev_%s%s.csv",o->m_pVDF[z0]->m_sName,multibuf); o->m_pVDF[z0]->m_fSpeed[0] = OpenFileWrite(buf,true); } else { try { o->m_pVDF[z0]->m_fSpeed = new FILE*[o->m_waSaveRefList.GetSize()]; } catch(...) { o->m_pVDF[z0]->m_fSpeed = NULL; } if (o->m_pVDF[z0]->m_fSpeed == NULL) NewException((double)o->m_waSaveRefList.GetSize()*sizeof(FILE*),__FILE__,__LINE__,__PRETTY_FUNCTION__); for (z2=0;z2m_waSaveRefList.GetSize();z2++) { // sprintf(buf,"vdf_timedev_%s_ref%d%s.csv",o->m_pVDF[z0]->m_sName,o->m_waSaveRefList[z2]+1,multibuf); buf.sprintf("vdf_timedev_%s_ref%d%s.csv",o->m_pVDF[z0]->m_sName,o->m_waSaveRefList[z2]+1,multibuf); o->m_pVDF[z0]->m_fSpeed[z2] = OpenFileWrite(buf,true); } } if (o->m_bCombinedPlot) { try { o->m_pVDF[z0]->m_pVDF->m_pCombinedPlot = new CGrace(); } catch(...) { o->m_pVDF[z0]->m_pVDF->m_pCombinedPlot = NULL; } if (o->m_pVDF[z0]->m_pVDF->m_pCombinedPlot == NULL) NewException((double)sizeof(CGrace),__FILE__,__LINE__,__PRETTY_FUNCTION__); o->m_pVDF[z0]->m_pVDF->m_pCombinedPlot->SetTitle("Combined velocity time development/histogram"); o->m_pVDF[z0]->m_pVDF->m_pCombinedPlot->SetSubTitle(o->m_pVDF[z0]->m_sShortName); for (z2=0;z2m_waSaveRefList.GetSize();z2++) for (z3=0;z3m_waSaveShowList.GetSize();z3++) for (z4=0;z4m_pVDF[z0]->m_iCombinations;z4++) { o->m_pVDF[z0]->m_pVDF->m_pCombinedPlot->AddDataset(); if (g_iTrajSteps != -1) o->m_pVDF[z0]->m_pVDF->m_pCombinedPlot->LastDataset()->m_faValues.SetMaxSize(o->m_waSaveRefList.GetSize()*o->m_waSaveShowList.GetSize()*o->m_pVDF[z0]->m_iCombinations*g_iTrajSteps); o->m_pVDF[z0]->m_pVDF->m_pCombinedPlot->LastDataset()->m_faValues.SetGrow(o->m_waSaveRefList.GetSize()*o->m_waSaveShowList.GetSize()*o->m_pVDF[z0]->m_iCombinations*100); if (o->m_bCombinedGreyMode) { ti = o->m_iCombinedGreyMin + ((z4+z3*o->m_pVDF[z0]->m_iCombinations+z2*o->m_pVDF[z0]->m_iCombinations*o->m_waSaveShowList.GetSize())%o->m_iCombinedGreyShades)*(o->m_iCombinedGreyMax-o->m_iCombinedGreyMin)/o->m_iCombinedGreyShades; o->m_pVDF[z0]->m_pVDF->m_pCombinedPlot->SetSetLineColor((unsigned char)ti,(unsigned char)ti,(unsigned char)ti); } // o->m_pVDF[z0]->m_pVDF->m_pCombinedPlot->SetSetLineWidth(z2*o->m_waSaveRefList.GetSize()+z3,3.0f); } o->m_pVDF[z0]->m_pVDF->m_pCombinedPlot->SetLabelX("Time [ps] / VDF(r)"); o->m_pVDF[z0]->m_pVDF->m_pCombinedPlot->SetLabelY("Velocity [pm/ps]"); } } // END IF TIMEDEV if (o->m_bTimeDiff) o->CreateTimeDiff(o->m_pVDF[z0]->m_pVDF,o->m_pVDF[z0]->m_iCombinations); if (g_bDeriv) o->m_pVDF[z0]->InitDeriv(); } // END IF VDF if (g_bDDF && (o->m_pDDF[z0] != NULL)) { mprintf(" Creating DDF...\n"); o->m_pDDF[z0]->m_pDDF->m_fMinVal = o->m_pDDF[z0]->m_fMinAngle; o->m_pDDF[z0]->m_pDDF->m_fMaxVal = o->m_pDDF[z0]->m_fMaxAngle; o->m_pDDF[z0]->m_pDDF->m_iResolution = o->m_pDDF[z0]->m_iResolution; o->m_pDDF[z0]->m_pDDF->m_iHistogramRes = o->m_pDDF[z0]->m_iHistogramRes; if (o->m_pDDF[z0]->m_bCosine) o->m_pDDF[z0]->m_pDDF->SetLabelX("Cos(Dihedral Angle)"); else o->m_pDDF[z0]->m_pDDF->SetLabelX("Dihedral Angle (Degree)"); o->m_pDDF[z0]->m_pDDF->SetLabelY("Occurrence"); if (o->m_bObsCertain && o->m_bDecompDist) o->m_pDDF[z0]->m_pDDF->CreateMulti(o->m_waObsRefList.GetSize()*o->m_waObsShowList.GetSize()); else o->m_pDDF[z0]->m_pDDF->Create(); if (o->m_bSecondShowMol && (z0 == 1)) { try { o->m_pDDF[z0]->m_faData = new CxDoubleArray[o->m_iShowMol2Count]; } catch(...) { o->m_pDDF[z0]->m_faData = NULL; } if (o->m_pDDF[z0]->m_faData == NULL) NewException((double)o->m_iShowMol2Count*sizeof(CxDoubleArray),__FILE__,__LINE__,__PRETTY_FUNCTION__); if (o->m_bBinOnlyPassedAtoms || o->m_bBinOnlyNotPassedAtoms) { try { o->m_pDDF[z0]->m_baDataEnabled = new CxByteArray[o->m_iShowMol2Count]; } catch(...) { o->m_pDDF[z0]->m_baDataEnabled = NULL; } if (o->m_pDDF[z0]->m_baDataEnabled == NULL) NewException((double)o->m_iShowMol2Count*sizeof(CxByteArray),__FILE__,__LINE__,__PRETTY_FUNCTION__); } } else { try { o->m_pDDF[z0]->m_faData = new CxDoubleArray[o->m_iShowMolCount]; } catch(...) { o->m_pDDF[z0]->m_faData = NULL; } if (o->m_pDDF[z0]->m_faData == NULL) NewException((double)o->m_iShowMolCount*sizeof(CxDoubleArray),__FILE__,__LINE__,__PRETTY_FUNCTION__); if (o->m_bBinOnlyPassedAtoms || o->m_bBinOnlyNotPassedAtoms) { try { o->m_pDDF[z0]->m_baDataEnabled = new CxByteArray[o->m_iShowMolCount]; } catch(...) { o->m_pDDF[z0]->m_baDataEnabled = NULL; } if (o->m_pDDF[z0]->m_baDataEnabled == NULL) NewException((double)o->m_iShowMolCount*sizeof(CxByteArray),__FILE__,__LINE__,__PRETTY_FUNCTION__); } if (o->m_pDDF[z0]->m_bRotate) { for (z2=0;z2m_iShowMolCount * ((CMolecule*)g_oaMolecules[g_iFixMol])->m_laSingleMolIndex.GetSize() * o->m_pDDF[z0]->m_iCombinations;z2++) { o->m_pDDF[z0]->m_faLastData.Add(0); o->m_pDDF[z0]->m_laRotation.Add(0); } } } if (o->m_bTimeDev) { if ((o->m_waSaveRefList.GetSize() == 1) || (!o->m_bSaveSeparateFiles)) { try { o->m_pDDF[z0]->m_fAngle = new FILE*[1]; } catch(...) { o->m_pDDF[z0]->m_fAngle = NULL; } if (o->m_pDDF[z0]->m_fAngle == NULL) NewException((double)sizeof(FILE*),__FILE__,__LINE__,__PRETTY_FUNCTION__); // sprintf(buf,"ddf_timedev_%s%s.csv",o->m_pDDF[z0]->m_sName,multibuf); buf.sprintf("ddf_timedev_%s%s.csv",o->m_pDDF[z0]->m_sName,multibuf); o->m_pDDF[z0]->m_fAngle[0] = OpenFileWrite(buf,true); } else { try { o->m_pDDF[z0]->m_fAngle = new FILE*[o->m_waSaveRefList.GetSize()]; } catch(...) { o->m_pDDF[z0]->m_fAngle = NULL; } if (o->m_pDDF[z0]->m_fAngle == NULL) NewException((double)o->m_waSaveRefList.GetSize()*sizeof(FILE*),__FILE__,__LINE__,__PRETTY_FUNCTION__); for (z2=0;z2m_waSaveRefList.GetSize();z2++) { // sprintf(buf,"ddf_timedev_%s_ref%d%s.csv",o->m_pDDF[z0]->m_sName,o->m_waSaveRefList[z2]+1,multibuf); buf.sprintf("ddf_timedev_%s_ref%d%s.csv",o->m_pDDF[z0]->m_sName,o->m_waSaveRefList[z2]+1,multibuf); o->m_pDDF[z0]->m_fAngle[z2] = OpenFileWrite(buf,true); } } if (o->m_bCombinedPlot) { try { o->m_pDDF[z0]->m_pDDF->m_pCombinedPlot = new CGrace(); } catch(...) { o->m_pDDF[z0]->m_pDDF->m_pCombinedPlot = NULL; } if (o->m_pDDF[z0]->m_pDDF->m_pCombinedPlot == NULL) NewException((double)sizeof(CGrace),__FILE__,__LINE__,__PRETTY_FUNCTION__); o->m_pDDF[z0]->m_pDDF->m_pCombinedPlot->SetTitle("Combined dihedral time development/histogram"); o->m_pDDF[z0]->m_pDDF->m_pCombinedPlot->SetSubTitle(o->m_pDDF[z0]->m_sShortName); for (z2=0;z2m_waSaveRefList.GetSize();z2++) for (z3=0;z3m_waSaveShowList.GetSize();z3++) for (z4=0;z4m_pDDF[z0]->m_iCombinations;z4++) { o->m_pDDF[z0]->m_pDDF->m_pCombinedPlot->AddDataset(); if (g_iTrajSteps != -1) o->m_pDDF[z0]->m_pDDF->m_pCombinedPlot->LastDataset()->m_faValues.SetMaxSize(o->m_waSaveRefList.GetSize()*o->m_waSaveShowList.GetSize()*o->m_pDDF[z0]->m_iCombinations*g_iTrajSteps); o->m_pDDF[z0]->m_pDDF->m_pCombinedPlot->LastDataset()->m_faValues.SetGrow(o->m_waSaveRefList.GetSize()*o->m_waSaveShowList.GetSize()*o->m_pDDF[z0]->m_iCombinations*100); if (o->m_bCombinedGreyMode) { ti = o->m_iCombinedGreyMin + ((z4+z3*o->m_pDDF[z0]->m_iCombinations+z2*o->m_pDDF[z0]->m_iCombinations*o->m_waSaveShowList.GetSize())%o->m_iCombinedGreyShades)*(o->m_iCombinedGreyMax-o->m_iCombinedGreyMin)/o->m_iCombinedGreyShades; o->m_pDDF[z0]->m_pDDF->m_pCombinedPlot->SetSetLineColor((unsigned char)ti,(unsigned char)ti,(unsigned char)ti); } // o->m_pDDF[z0]->m_pDDF->m_pCombinedPlot->SetSetLineWidth((z2*o->m_waSaveRefList.GetSize()+z3)*o->m_pDDF[z0]->m_iCombinations+z4,2.0f); } o->m_pDDF[z0]->m_pDDF->m_pCombinedPlot->SetLabelX("Time [ps] / DDF(r)"); o->m_pDDF[z0]->m_pDDF->m_pCombinedPlot->SetLabelY("Dihedral [Degree]"); } } // END IF TIMEDEV if (o->m_bTimeDiff) o->CreateTimeDiff(o->m_pDDF[z0]->m_pDDF,o->m_pDDF[z0]->m_iCombinations); if (g_bDeriv) o->m_pDDF[z0]->InitDeriv(); } // END IF DDF if (g_bPlDF && (o->m_pPlDF[z0] != NULL)) { mprintf(" Creating PlDF...\n"); o->m_pPlDF[z0]->m_pPlDF->m_fMinVal = o->m_pPlDF[z0]->m_fMinDist; o->m_pPlDF[z0]->m_pPlDF->m_fMaxVal = o->m_pPlDF[z0]->m_fMaxDist; o->m_pPlDF[z0]->m_pPlDF->m_iResolution = o->m_pPlDF[z0]->m_iResolution; o->m_pPlDF[z0]->m_pPlDF->m_iHistogramRes = o->m_pPlDF[z0]->m_iHistogramRes; o->m_pPlDF[z0]->m_pPlDF->SetLabelX("Distance from plane [pm]"); o->m_pPlDF[z0]->m_pPlDF->SetLabelY("Occurrence"); o->m_pPlDF[z0]->m_pPlDF->Create(); if (o->m_bSecondShowMol && (z0 == 1)) { try { o->m_pPlDF[z0]->m_faData = new CxDoubleArray[o->m_iShowMol2Count]; } catch(...) { o->m_pPlDF[z0]->m_faData = NULL; } if (o->m_pPlDF[z0]->m_faData == NULL) NewException((double)o->m_iShowMol2Count*sizeof(CxDoubleArray),__FILE__,__LINE__,__PRETTY_FUNCTION__); if (o->m_bBinOnlyPassedAtoms || o->m_bBinOnlyNotPassedAtoms) { try { o->m_pPlDF[z0]->m_baDataEnabled = new CxByteArray[o->m_iShowMol2Count]; } catch(...) { o->m_pPlDF[z0]->m_baDataEnabled = NULL; } if (o->m_pPlDF[z0]->m_baDataEnabled == NULL) NewException((double)o->m_iShowMol2Count*sizeof(CxByteArray),__FILE__,__LINE__,__PRETTY_FUNCTION__); } } else { try { o->m_pPlDF[z0]->m_faData = new CxDoubleArray[o->m_iShowMolCount]; } catch(...) { o->m_pPlDF[z0]->m_faData = NULL; } if (o->m_pPlDF[z0]->m_faData == NULL) NewException((double)o->m_iShowMolCount*sizeof(CxDoubleArray),__FILE__,__LINE__,__PRETTY_FUNCTION__); if (o->m_bBinOnlyPassedAtoms || o->m_bBinOnlyNotPassedAtoms) { try { o->m_pPlDF[z0]->m_baDataEnabled = new CxByteArray[o->m_iShowMolCount]; } catch(...) { o->m_pPlDF[z0]->m_baDataEnabled = NULL; } if (o->m_pPlDF[z0]->m_baDataEnabled == NULL) NewException((double)o->m_iShowMolCount*sizeof(CxByteArray),__FILE__,__LINE__,__PRETTY_FUNCTION__); } } } // END IF PlDF if (g_bLiDF && (o->m_pLiDF[z0] != NULL)) { mprintf(" Creating LiDF...\n"); o->m_pLiDF[z0]->m_pLiDF->m_fMinVal = o->m_pLiDF[z0]->m_fMinDist; o->m_pLiDF[z0]->m_pLiDF->m_fMaxVal = o->m_pLiDF[z0]->m_fMaxDist; o->m_pLiDF[z0]->m_pLiDF->m_iResolution = o->m_pLiDF[z0]->m_iResolution; o->m_pLiDF[z0]->m_pLiDF->m_iHistogramRes = o->m_pLiDF[z0]->m_iHistogramRes; o->m_pLiDF[z0]->m_pLiDF->SetLabelX("Distance from line [pm]"); o->m_pLiDF[z0]->m_pLiDF->SetLabelY("Occurrence"); o->m_pLiDF[z0]->m_pLiDF->Create(); if (o->m_bSecondShowMol && (z0 == 1)) { try { o->m_pLiDF[z0]->m_faData = new CxDoubleArray[o->m_iShowMol2Count]; } catch(...) { o->m_pLiDF[z0]->m_faData = NULL; } if (o->m_pLiDF[z0]->m_faData == NULL) NewException((double)o->m_iShowMol2Count*sizeof(CxDoubleArray),__FILE__,__LINE__,__PRETTY_FUNCTION__); if (o->m_bBinOnlyPassedAtoms || o->m_bBinOnlyNotPassedAtoms) { try { o->m_pLiDF[z0]->m_baDataEnabled = new CxByteArray[o->m_iShowMol2Count]; } catch(...) { o->m_pLiDF[z0]->m_baDataEnabled = NULL; } if (o->m_pLiDF[z0]->m_baDataEnabled == NULL) NewException((double)o->m_iShowMol2Count*sizeof(CxByteArray),__FILE__,__LINE__,__PRETTY_FUNCTION__); } } else { try { o->m_pLiDF[z0]->m_faData = new CxDoubleArray[o->m_iShowMolCount]; } catch(...) { o->m_pLiDF[z0]->m_faData = NULL; } if (o->m_pLiDF[z0]->m_faData == NULL) NewException((double)o->m_iShowMolCount*sizeof(CxDoubleArray),__FILE__,__LINE__,__PRETTY_FUNCTION__); if (o->m_bBinOnlyPassedAtoms || o->m_bBinOnlyNotPassedAtoms) { try { o->m_pLiDF[z0]->m_baDataEnabled = new CxByteArray[o->m_iShowMolCount]; } catch(...) { o->m_pLiDF[z0]->m_baDataEnabled = NULL; } if (o->m_pLiDF[z0]->m_baDataEnabled == NULL) NewException((double)o->m_iShowMolCount*sizeof(CxByteArray),__FILE__,__LINE__,__PRETTY_FUNCTION__); } } } // END IF LiDF } // END FOR z0 if (g_bCDF) { mprintf(" Creating CDF...\n"); if (g_iCDFChannels == 2) { try { o->m_pCDF->m_p2DF = new C2DF(); } catch(...) { o->m_pCDF->m_p2DF = NULL; } if (o->m_pCDF->m_p2DF == NULL) NewException((double)sizeof(C2DF),__FILE__,__LINE__,__PRETTY_FUNCTION__); // buf[0] = 0; buf = ""; for (z2=0;z2<2;z2++) { o->m_pCDF->m_p2DF->m_iRes[z2] = o->m_pCDF->m_iResolution[z2]; switch(g_iObsChannel[z2]) { case 0: // strcat(buf,"_rdf"); // strcat(buf,o->m_pRDF[z2]->m_sShortName); buf.strcat("_rdf"); buf.strcat(o->m_pRDF[z2]->m_sShortName); o->m_pCDF->m_p2DF->m_fMinVal[z2] = o->m_pRDF[z2]->m_fMinDist; o->m_pCDF->m_p2DF->m_fMaxVal[z2] = o->m_pRDF[z2]->m_fMaxDist; o->m_pCDF->m_p2DF->m_pChannels[z2] = o->m_pRDF[z2]->m_pRDF; break; case 1: // strcat(buf,"_adf"); // strcat(buf,o->m_pADF[z2]->m_sShortName); buf.strcat("_adf"); buf.strcat(o->m_pADF[z2]->m_sShortName); o->m_pCDF->m_p2DF->m_fMinVal[z2] = o->m_pADF[z2]->m_fMinAngle; o->m_pCDF->m_p2DF->m_fMaxVal[z2] = o->m_pADF[z2]->m_fMaxAngle; o->m_pCDF->m_p2DF->m_pChannels[z2] = o->m_pADF[z2]->m_pADF; break; case 2: // strcat(buf,"_ddf"); // strcat(buf,o->m_pDDF[z2]->m_sShortName); buf.strcat("_ddf"); buf.strcat(o->m_pDDF[z2]->m_sShortName); o->m_pCDF->m_p2DF->m_fMinVal[z2] = o->m_pDDF[z2]->m_fMinAngle; o->m_pCDF->m_p2DF->m_fMaxVal[z2] = o->m_pDDF[z2]->m_fMaxAngle; o->m_pCDF->m_p2DF->m_pChannels[z2] = o->m_pDDF[z2]->m_pDDF; break; case 3: // strcat(buf,"_dipole"); // strcat(buf,o->m_pDipDF[z2]->m_sShortName); buf.strcat("_dipole"); buf.strcat(o->m_pDipDF[z2]->m_sShortName); o->m_pCDF->m_p2DF->m_fMinVal[z2] = o->m_pDipDF[z2]->m_fDipoleMin; o->m_pCDF->m_p2DF->m_fMaxVal[z2] = o->m_pDipDF[z2]->m_fDipoleMax; o->m_pCDF->m_p2DF->m_pChannels[z2] = o->m_pDipDF[z2]->m_pDipoleDF; break; case 4: // strcat(buf,"_vdf"); // strcat(buf,o->m_pVDF[z2]->m_sShortName); buf.strcat("_vdf"); buf.strcat(o->m_pVDF[z2]->m_sShortName); o->m_pCDF->m_p2DF->m_fMinVal[z2] = o->m_pVDF[z2]->m_fMinSpeed; o->m_pCDF->m_p2DF->m_fMaxVal[z2] = o->m_pVDF[z2]->m_fMaxSpeed; o->m_pCDF->m_p2DF->m_pChannels[z2] = o->m_pVDF[z2]->m_pVDF; break; case 5: // strcat(buf,"_pldf"); // strcat(buf,o->m_pPlDF[z2]->m_sShortName); buf.strcat("_pldf"); buf.strcat(o->m_pPlDF[z2]->m_sShortName); o->m_pCDF->m_p2DF->m_fMinVal[z2] = o->m_pPlDF[z2]->m_fMinDist; o->m_pCDF->m_p2DF->m_fMaxVal[z2] = o->m_pPlDF[z2]->m_fMaxDist; o->m_pCDF->m_p2DF->m_pChannels[z2] = o->m_pPlDF[z2]->m_pPlDF; break; case 6: // strcat(buf,"_lidf"); // strcat(buf,o->m_pLiDF[z2]->m_sShortName); buf.strcat("_lidf"); buf.strcat(o->m_pLiDF[z2]->m_sShortName); o->m_pCDF->m_p2DF->m_fMinVal[z2] = o->m_pLiDF[z2]->m_fMinDist; o->m_pCDF->m_p2DF->m_fMaxVal[z2] = o->m_pLiDF[z2]->m_fMaxDist; o->m_pCDF->m_p2DF->m_pChannels[z2] = o->m_pLiDF[z2]->m_pLiDF; break; } } o->m_pCDF->m_p2DF->m_iHistogramRes = o->m_pCDF->m_iHistogramRes; o->m_pCDF->m_p2DF->Create(); switch(g_iObsChannel[0]) { case 0: // sprintf(buf2,"%s Distance [pm]",o->m_pRDF[0]->m_sShortName); buf2.sprintf("%s Distance [pm]",o->m_pRDF[0]->m_sLabelName); o->m_pCDF->m_p2DF->SetLabelX(buf2); break; case 1: // sprintf(buf2,"%s Angle [Degree]",o->m_pADF[0]->m_sShortName); buf2.sprintf("%s Angle [Degree]",o->m_pADF[0]->m_sLabelName); o->m_pCDF->m_p2DF->SetLabelX(buf2); break; case 2: // sprintf(buf2,"%s Dihedral [Degree]",o->m_pDDF[0]->m_sShortName); buf2.sprintf("%s Dihedral [Degree]",o->m_pDDF[0]->m_sLabelName); o->m_pCDF->m_p2DF->SetLabelX(buf2); break; case 3: // sprintf(buf2,"%s Dipole moment [Debye]",o->m_pDipDF[0]->m_sShortName); buf2.sprintf("%s Dipole moment [Debye]",o->m_pDipDF[0]->m_sLabelName); o->m_pCDF->m_p2DF->SetLabelX(buf2); break; case 4: // sprintf(buf2,"%s Velocity [pm/ps]",o->m_pVDF[0]->m_sShortName); buf2.sprintf("%s Velocity [pm/ps]",o->m_pVDF[0]->m_sLabelName); o->m_pCDF->m_p2DF->SetLabelX(buf2); break; case 5: // sprintf(buf2,"%s Distance from Plane [pm]",o->m_pPlDF[0]->m_sShortName); buf2.sprintf("%s Distance from Plane [pm]",o->m_pPlDF[0]->m_sLabelName); o->m_pCDF->m_p2DF->SetLabelX(buf2); break; case 6: // sprintf(buf2,"%s Distance from Line [pm]",o->m_pLiDF[0]->m_sShortName); buf2.sprintf("%s Distance from Line [pm]",o->m_pLiDF[0]->m_sLabelName); o->m_pCDF->m_p2DF->SetLabelX(buf2); break; } switch(g_iObsChannel[1]) { case 0: // sprintf(buf2,"%s Distance [pm]",o->m_pRDF[1]->m_sShortName); buf2.sprintf("%s Distance [pm]",o->m_pRDF[1]->m_sLabelName); o->m_pCDF->m_p2DF->SetLabelY(buf2); break; case 1: // sprintf(buf2,"%s Angle [Degree]",o->m_pADF[1]->m_sShortName); buf2.sprintf("%s Angle [Degree]",o->m_pADF[1]->m_sLabelName); o->m_pCDF->m_p2DF->SetLabelY(buf2); break; case 2: // sprintf(buf2,"%s Dihedral [Degree]",o->m_pDDF[1]->m_sShortName); buf2.sprintf("%s Dihedral [Degree]",o->m_pDDF[1]->m_sLabelName); o->m_pCDF->m_p2DF->SetLabelY(buf2); break; case 3: // sprintf(buf2,"%s Dipole moment [Debye]",o->m_pDipDF[1]->m_sShortName); buf2.sprintf("%s Dipole moment [Debye]",o->m_pDipDF[1]->m_sLabelName); o->m_pCDF->m_p2DF->SetLabelY(buf2); break; case 4: // sprintf(buf2,"%s Velocity [pm/ps]",o->m_pVDF[1]->m_sShortName); buf2.sprintf("%s Velocity [pm/ps]",o->m_pVDF[1]->m_sLabelName); o->m_pCDF->m_p2DF->SetLabelY(buf2); break; case 5: // sprintf(buf2,"%s Distance from Plane [pm]",o->m_pPlDF[1]->m_sShortName); buf2.sprintf("%s Distance from Plane [pm]",o->m_pPlDF[1]->m_sLabelName); o->m_pCDF->m_p2DF->SetLabelY(buf2); break; case 6: // sprintf(buf2,"%s Distance from Line [pm]",o->m_pLiDF[1]->m_sShortName); buf2.sprintf("%s Distance from Line [pm]",o->m_pLiDF[1]->m_sLabelName); o->m_pCDF->m_p2DF->SetLabelY(buf2); break; } } // END IF CHANNELS == 2 if (g_iCDFChannels == 3) { try { o->m_pCDF->m_p3DF = new C3DF(); } catch(...) { o->m_pCDF->m_p3DF = NULL; } if (o->m_pCDF->m_p3DF == NULL) NewException((double)sizeof(C3DF),__FILE__,__LINE__,__PRETTY_FUNCTION__); // buf[0] = 0; buf = ""; for (z2=0;z2m_pCDF->m_p3DF->m_iRes[z2] = o->m_pCDF->m_iResolution[z2]; switch(g_iObsChannel[z2]) { case 0: // strcat(buf,"_rdf"); // strcat(buf,o->m_pRDF[z2]->m_sShortName); buf.strcat("_rdf"); buf.strcat(o->m_pRDF[z2]->m_sShortName); o->m_pCDF->m_p3DF->m_fMinVal[z2] = o->m_pRDF[z2]->m_fMinDist; o->m_pCDF->m_p3DF->m_fMaxVal[z2] = o->m_pRDF[z2]->m_fMaxDist; o->m_pCDF->m_p3DF->m_pChannels[z2] = o->m_pRDF[z2]->m_pRDF; break; case 1: // strcat(buf,"_adf"); // strcat(buf,o->m_pADF[z2]->m_sShortName); buf.strcat("_adf"); buf.strcat(o->m_pADF[z2]->m_sShortName); o->m_pCDF->m_p3DF->m_fMinVal[z2] = o->m_pADF[z2]->m_fMinAngle; o->m_pCDF->m_p3DF->m_fMaxVal[z2] = o->m_pADF[z2]->m_fMaxAngle; o->m_pCDF->m_p3DF->m_pChannels[z2] = o->m_pADF[z2]->m_pADF; break; case 2: // strcat(buf,"_ddf"); // strcat(buf,o->m_pDDF[z2]->m_sShortName); buf.strcat("_ddf"); buf.strcat(o->m_pDDF[z2]->m_sShortName); o->m_pCDF->m_p3DF->m_fMinVal[z2] = o->m_pDDF[z2]->m_fMinAngle; o->m_pCDF->m_p3DF->m_fMaxVal[z2] = o->m_pDDF[z2]->m_fMaxAngle; o->m_pCDF->m_p3DF->m_pChannels[z2] = o->m_pDDF[z2]->m_pDDF; break; case 3: // strcat(buf,"_dipole"); // strcat(buf,o->m_pDipDF[z2]->m_sShortName); buf.strcat("_dipole"); buf.strcat(o->m_pDipDF[z2]->m_sShortName); o->m_pCDF->m_p3DF->m_fMinVal[z2] = o->m_pDipDF[z2]->m_fDipoleMin; o->m_pCDF->m_p3DF->m_fMaxVal[z2] = o->m_pDipDF[z2]->m_fDipoleMax; o->m_pCDF->m_p3DF->m_pChannels[z2] = o->m_pDipDF[z2]->m_pDipoleDF; break; case 4: // strcat(buf,"_vdf"); // strcat(buf,o->m_pVDF[z2]->m_sShortName); buf.strcat("_vdf"); buf.strcat(o->m_pVDF[z2]->m_sShortName); o->m_pCDF->m_p3DF->m_fMinVal[z2] = o->m_pVDF[z2]->m_fMinSpeed; o->m_pCDF->m_p3DF->m_fMaxVal[z2] = o->m_pVDF[z2]->m_fMaxSpeed; o->m_pCDF->m_p3DF->m_pChannels[z2] = o->m_pVDF[z2]->m_pVDF; break; case 5: // strcat(buf,"_pldf"); // strcat(buf,o->m_pPlDF[z2]->m_sShortName); buf.strcat("_pldf"); buf.strcat(o->m_pPlDF[z2]->m_sShortName); o->m_pCDF->m_p3DF->m_fMinVal[z2] = o->m_pPlDF[z2]->m_fMinDist; o->m_pCDF->m_p3DF->m_fMaxVal[z2] = o->m_pPlDF[z2]->m_fMaxDist; o->m_pCDF->m_p3DF->m_pChannels[z2] = o->m_pPlDF[z2]->m_pPlDF; break; case 6: // strcat(buf,"_lidf"); // strcat(buf,o->m_pLiDF[z2]->m_sShortName); buf.strcat("_lidf"); buf.strcat(o->m_pLiDF[z2]->m_sShortName); o->m_pCDF->m_p3DF->m_fMinVal[z2] = o->m_pLiDF[z2]->m_fMinDist; o->m_pCDF->m_p3DF->m_fMaxVal[z2] = o->m_pLiDF[z2]->m_fMaxDist; o->m_pCDF->m_p3DF->m_pChannels[z2] = o->m_pLiDF[z2]->m_pLiDF; break; } } o->m_pCDF->m_p3DF->m_iHistogramRes = o->m_pCDF->m_iHistogramRes; o->m_pCDF->m_p3DF->Create(); switch(g_iObsChannel[0]) { case 0: // sprintf(buf2,"%s Distance [pm]",o->m_pRDF[0]->m_sShortName); buf2.sprintf("%s Distance [pm]",o->m_pRDF[0]->m_sLabelName); o->m_pCDF->m_p3DF->SetLabelX(buf2); break; case 1: // sprintf(buf2,"%s Angle [Degree]",o->m_pADF[0]->m_sShortName); buf2.sprintf("%s Angle [Degree]",o->m_pADF[0]->m_sLabelName); o->m_pCDF->m_p3DF->SetLabelX(buf2); break; case 2: // sprintf(buf2,"%s Dihedral [Degree]",o->m_pDDF[0]->m_sShortName); buf2.sprintf("%s Dihedral [Degree]",o->m_pDDF[0]->m_sLabelName); o->m_pCDF->m_p3DF->SetLabelX(buf2); break; case 3: // sprintf(buf2,"%s Dipole moment [Debye]",o->m_pDipDF[0]->m_sShortName); buf2.sprintf("%s Dipole moment [Debye]",o->m_pDipDF[0]->m_sLabelName); o->m_pCDF->m_p3DF->SetLabelX(buf2); break; case 4: // sprintf(buf2,"%s Velocity [pm/ps]",o->m_pVDF[0]->m_sShortName); buf2.sprintf("%s Velocity [pm/ps]",o->m_pVDF[0]->m_sLabelName); o->m_pCDF->m_p3DF->SetLabelX(buf2); break; case 5: // sprintf(buf2,"%s Distance from Plane [pm]",o->m_pPlDF[0]->m_sShortName); buf2.sprintf("%s Distance from Plane [pm]",o->m_pPlDF[0]->m_sLabelName); o->m_pCDF->m_p3DF->SetLabelX(buf2); break; case 6: // sprintf(buf2,"%s Distance from Line [pm]",o->m_pLiDF[0]->m_sShortName); buf2.sprintf("%s Distance from Line [pm]",o->m_pLiDF[0]->m_sLabelName); o->m_pCDF->m_p3DF->SetLabelX(buf2); break; } switch(g_iObsChannel[1]) { case 0: // sprintf(buf2,"%s Distance [pm]",o->m_pRDF[1]->m_sShortName); buf2.sprintf("%s Distance [pm]",o->m_pRDF[1]->m_sLabelName); o->m_pCDF->m_p3DF->SetLabelY(buf2); break; case 1: // sprintf(buf2,"%s Angle [Degree]",o->m_pADF[1]->m_sShortName); buf2.sprintf("%s Angle [Degree]",o->m_pADF[1]->m_sLabelName); o->m_pCDF->m_p3DF->SetLabelY(buf2); break; case 2: // sprintf(buf2,"%s Dihedral [Degree]",o->m_pDDF[1]->m_sShortName); buf2.sprintf("%s Dihedral [Degree]",o->m_pDDF[1]->m_sLabelName); o->m_pCDF->m_p3DF->SetLabelY(buf2); break; case 3: // sprintf(buf2,"%s Dipole moment [Debye]",o->m_pDipDF[1]->m_sShortName); buf2.sprintf("%s Dipole moment [Debye]",o->m_pDipDF[1]->m_sLabelName); o->m_pCDF->m_p3DF->SetLabelY(buf2); break; case 4: // sprintf(buf2,"%s Velocity [pm/ps]",o->m_pVDF[1]->m_sShortName); buf2.sprintf("%s Velocity [pm/ps]",o->m_pVDF[1]->m_sLabelName); o->m_pCDF->m_p3DF->SetLabelY(buf2); break; case 5: // sprintf(buf2,"%s Distance from Plane [pm]",o->m_pPlDF[1]->m_sShortName); buf2.sprintf("%s Distance from Plane [pm]",o->m_pPlDF[1]->m_sLabelName); o->m_pCDF->m_p3DF->SetLabelY(buf2); break; case 6: // sprintf(buf2,"%s Distance from Line [pm]",o->m_pLiDF[1]->m_sShortName); buf2.sprintf("%s Distance from Line [pm]",o->m_pLiDF[1]->m_sLabelName); o->m_pCDF->m_p3DF->SetLabelY(buf2); break; } switch(g_iObsChannel[2]) { case 0: // sprintf(buf2,"%s Distance [pm]",o->m_pRDF[2]->m_sShortName); buf2.sprintf("%s Distance [pm]",o->m_pRDF[2]->m_sLabelName); o->m_pCDF->m_p3DF->SetLabelZ(buf2); break; case 1: // sprintf(buf2,"%s Angle [Degree]",o->m_pADF[2]->m_sShortName); buf2.sprintf("%s Angle [Degree]",o->m_pADF[2]->m_sLabelName); o->m_pCDF->m_p3DF->SetLabelZ(buf2); break; case 2: // sprintf(buf2,"%s Dihedral [Degree]",o->m_pDDF[2]->m_sShortName); buf2.sprintf("%s Dihedral [Degree]",o->m_pDDF[2]->m_sLabelName); o->m_pCDF->m_p3DF->SetLabelZ(buf2); break; case 3: // sprintf(buf2,"%s Dipole moment [Debye]",o->m_pDipDF[2]->m_sShortName); buf2.sprintf("%s Dipole moment [Debye]",o->m_pDipDF[2]->m_sLabelName); o->m_pCDF->m_p3DF->SetLabelZ(buf2); break; case 4: // sprintf(buf2,"%s Velocity [pm/ps]",o->m_pVDF[2]->m_sShortName); buf2.sprintf("%s Velocity [pm/ps]",o->m_pVDF[2]->m_sLabelName); o->m_pCDF->m_p3DF->SetLabelZ(buf2); break; case 5: // sprintf(buf2,"%s Distance from Plane [pm]",o->m_pPlDF[2]->m_sShortName); buf2.sprintf("%s Distance from Plane [pm]",o->m_pPlDF[2]->m_sLabelName); o->m_pCDF->m_p3DF->SetLabelZ(buf2); break; case 6: // sprintf(buf2,"%s Distance from Line [pm]",o->m_pLiDF[2]->m_sShortName); buf2.sprintf("%s Distance from Line [pm]",o->m_pLiDF[2]->m_sLabelName); o->m_pCDF->m_p3DF->SetLabelZ(buf2); break; } // Fuer jede C3DF noch die 3 C2DFs erzeugen for (z3=0;z3<3;z3++) { try { o->m_pCDF->m_p3DF->m_p2DF[z3] = new C2DF(); } catch(...) { o->m_pCDF->m_p3DF->m_p2DF[z3] = NULL; } if (o->m_pCDF->m_p3DF->m_p2DF[z3] == NULL) NewException((double)sizeof(C2DF),__FILE__,__LINE__,__PRETTY_FUNCTION__); // buf3[0] = 0; buf3 = ""; switch(z3) { case 0: tia[0] = 0; tia[1] = 1; break; case 1: tia[0] = 0; tia[1] = 2; break; case 2: tia[0] = 1; tia[1] = 2; break; } for (z2=0;z2<2;z2++) { o->m_pCDF->m_p3DF->m_p2DF[z3]->m_iRes[z2] = o->m_pCDF->m_iResolution[tia[z2]]; switch(g_iObsChannel[tia[z2]]) { case 0: // strcat(buf3,"_rdf"); // strcat(buf3,o->m_pRDF[tia[z2]]->m_sShortName); buf3.strcat("_rdf"); buf3.strcat(o->m_pRDF[tia[z2]]->m_sShortName); o->m_pCDF->m_p3DF->m_p2DF[z3]->m_fMinVal[z2] = o->m_pRDF[tia[z2]]->m_fMinDist; o->m_pCDF->m_p3DF->m_p2DF[z3]->m_fMaxVal[z2] = o->m_pRDF[tia[z2]]->m_fMaxDist; o->m_pCDF->m_p3DF->m_p2DF[z3]->m_pChannels[z2] = o->m_pRDF[tia[z2]]->m_pRDF; break; case 1: // strcat(buf3,"_adf"); // strcat(buf3,o->m_pADF[tia[z2]]->m_sShortName); buf3.strcat("_adf"); buf3.strcat(o->m_pADF[tia[z2]]->m_sShortName); o->m_pCDF->m_p3DF->m_p2DF[z3]->m_fMinVal[z2] = o->m_pADF[tia[z2]]->m_fMinAngle; o->m_pCDF->m_p3DF->m_p2DF[z3]->m_fMaxVal[z2] = o->m_pADF[tia[z2]]->m_fMaxAngle; o->m_pCDF->m_p3DF->m_p2DF[z3]->m_pChannels[z2] = o->m_pADF[tia[z2]]->m_pADF; break; case 2: // strcat(buf3,"_ddf"); // strcat(buf3,o->m_pDDF[tia[z2]]->m_sShortName); buf3.strcat("_ddf"); buf3.strcat(o->m_pDDF[tia[z2]]->m_sShortName); o->m_pCDF->m_p3DF->m_p2DF[z3]->m_fMinVal[z2] = o->m_pDDF[tia[z2]]->m_fMinAngle; o->m_pCDF->m_p3DF->m_p2DF[z3]->m_fMaxVal[z2] = o->m_pDDF[tia[z2]]->m_fMaxAngle; o->m_pCDF->m_p3DF->m_p2DF[z3]->m_pChannels[z2] = o->m_pDDF[tia[z2]]->m_pDDF; break; case 3: // strcat(buf3,"_dipole"); // strcat(buf3,o->m_pDipDF[tia[z2]]->m_sShortName); buf3.strcat("_dipole"); buf3.strcat(o->m_pDipDF[tia[z2]]->m_sShortName); o->m_pCDF->m_p3DF->m_p2DF[z3]->m_fMinVal[z2] = o->m_pDipDF[tia[z2]]->m_fDipoleMin; o->m_pCDF->m_p3DF->m_p2DF[z3]->m_fMaxVal[z2] = o->m_pDipDF[tia[z2]]->m_fDipoleMax; o->m_pCDF->m_p3DF->m_p2DF[z3]->m_pChannels[z2] = o->m_pDipDF[tia[z2]]->m_pDipoleDF; break; case 4: // strcat(buf3,"_vdf"); // strcat(buf3,o->m_pVDF[tia[z2]]->m_sShortName); buf3.strcat("_vdf"); buf3.strcat(o->m_pVDF[tia[z2]]->m_sShortName); o->m_pCDF->m_p3DF->m_p2DF[z3]->m_fMinVal[z2] = o->m_pVDF[tia[z2]]->m_fMinSpeed; o->m_pCDF->m_p3DF->m_p2DF[z3]->m_fMaxVal[z2] = o->m_pVDF[tia[z2]]->m_fMaxSpeed; o->m_pCDF->m_p3DF->m_p2DF[z3]->m_pChannels[z2] = o->m_pVDF[tia[z2]]->m_pVDF; break; case 5: // strcat(buf3,"_pldf"); // strcat(buf3,o->m_pPlDF[tia[z2]]->m_sShortName); buf3.strcat("_pldf"); buf3.strcat(o->m_pPlDF[tia[z2]]->m_sShortName); o->m_pCDF->m_p3DF->m_p2DF[z3]->m_fMinVal[z2] = o->m_pPlDF[tia[z2]]->m_fMinDist; o->m_pCDF->m_p3DF->m_p2DF[z3]->m_fMaxVal[z2] = o->m_pPlDF[tia[z2]]->m_fMaxDist; o->m_pCDF->m_p3DF->m_p2DF[z3]->m_pChannels[z2] = o->m_pPlDF[tia[z2]]->m_pPlDF; break; case 6: // strcat(buf3,"_lidf"); // strcat(buf3,o->m_pLiDF[tia[z2]]->m_sShortName); buf3.strcat("_lidf"); buf3.strcat(o->m_pLiDF[tia[z2]]->m_sShortName); o->m_pCDF->m_p3DF->m_p2DF[z3]->m_fMinVal[z2] = o->m_pLiDF[tia[z2]]->m_fMinDist; o->m_pCDF->m_p3DF->m_p2DF[z3]->m_fMaxVal[z2] = o->m_pLiDF[tia[z2]]->m_fMaxDist; o->m_pCDF->m_p3DF->m_p2DF[z3]->m_pChannels[z2] = o->m_pLiDF[tia[z2]]->m_pLiDF; break; } } o->m_pCDF->m_p3DF->m_p2DF[z3]->m_iHistogramRes = o->m_pCDF->m_iHistogramRes; o->m_pCDF->m_p3DF->m_p2DF[z3]->Create(); switch(g_iObsChannel[tia[0]]) { case 0: // sprintf(buf2,"%s Distance [pm]",o->m_pRDF[tia[0]]->m_sShortName); buf2.sprintf("%s Distance [pm]",o->m_pRDF[tia[0]]->m_sLabelName); o->m_pCDF->m_p3DF->m_p2DF[z3]->SetLabelX(buf2); break; case 1: // sprintf(buf2,"%s Angle [Degree]",o->m_pADF[tia[0]]->m_sShortName); buf2.sprintf("%s Angle [Degree]",o->m_pADF[tia[0]]->m_sLabelName); o->m_pCDF->m_p3DF->m_p2DF[z3]->SetLabelX(buf2); break; case 2: // sprintf(buf2,"%s Dihedral [Degree]",o->m_pDDF[tia[0]]->m_sShortName); buf2.sprintf("%s Dihedral [Degree]",o->m_pDDF[tia[0]]->m_sLabelName); o->m_pCDF->m_p3DF->m_p2DF[z3]->SetLabelX(buf2); break; case 3: // sprintf(buf2,"%s Dipole moment [Debye]",o->m_pDipDF[tia[0]]->m_sShortName); buf2.sprintf("%s Dipole moment [Debye]",o->m_pDipDF[tia[0]]->m_sLabelName); o->m_pCDF->m_p3DF->m_p2DF[z3]->SetLabelX(buf2); break; case 4: // sprintf(buf2,"%s Velocity [pm/ps]",o->m_pVDF[tia[0]]->m_sShortName); buf2.sprintf("%s Velocity [pm/ps]",o->m_pVDF[tia[0]]->m_sLabelName); o->m_pCDF->m_p3DF->m_p2DF[z3]->SetLabelX(buf2); break; case 5: // sprintf(buf2,"%s Distance from Plane [pm]",o->m_pPlDF[tia[0]]->m_sShortName); buf2.sprintf("%s Distance from Plane [pm]",o->m_pPlDF[tia[0]]->m_sLabelName); o->m_pCDF->m_p3DF->m_p2DF[z3]->SetLabelX(buf2); break; case 6: // sprintf(buf2,"%s Distance from Line [pm]",o->m_pLiDF[tia[0]]->m_sShortName); buf2.sprintf("%s Distance from Line [pm]",o->m_pLiDF[tia[0]]->m_sLabelName); o->m_pCDF->m_p3DF->m_p2DF[z3]->SetLabelX(buf2); break; } switch(g_iObsChannel[tia[1]]) { case 0: // sprintf(buf2,"%s Distance [pm]",o->m_pRDF[tia[1]]->m_sShortName); buf2.sprintf("%s Distance [pm]",o->m_pRDF[tia[1]]->m_sLabelName); o->m_pCDF->m_p3DF->m_p2DF[z3]->SetLabelY(buf2); break; case 1: // sprintf(buf2,"%s Angle [Degree]",o->m_pADF[tia[1]]->m_sShortName); buf2.sprintf("%s Angle [Degree]",o->m_pADF[tia[1]]->m_sLabelName); o->m_pCDF->m_p3DF->m_p2DF[z3]->SetLabelY(buf2); break; case 2: // sprintf(buf2,"%s Dihedral [Degree]",o->m_pDDF[tia[1]]->m_sShortName); buf2.sprintf("%s Dihedral [Degree]",o->m_pDDF[tia[1]]->m_sLabelName); o->m_pCDF->m_p3DF->m_p2DF[z3]->SetLabelY(buf2); break; case 3: // sprintf(buf2,"%s Dipole moment [Debye]",o->m_pDipDF[tia[1]]->m_sShortName); buf2.sprintf("%s Dipole moment [Debye]",o->m_pDipDF[tia[1]]->m_sLabelName); o->m_pCDF->m_p3DF->m_p2DF[z3]->SetLabelY(buf2); break; case 4: // sprintf(buf2,"%s Velocity [pm/ps]",o->m_pVDF[tia[1]]->m_sShortName); buf2.sprintf("%s Velocity [pm/ps]",o->m_pVDF[tia[1]]->m_sLabelName); o->m_pCDF->m_p3DF->m_p2DF[z3]->SetLabelY(buf2); break; case 5: // sprintf(buf2,"%s Distance from Plane [pm]",o->m_pPlDF[tia[1]]->m_sShortName); buf2.sprintf("%s Distance from Plane [pm]",o->m_pPlDF[tia[1]]->m_sLabelName); o->m_pCDF->m_p3DF->m_p2DF[z3]->SetLabelY(buf2); break; case 6: // sprintf(buf2,"%s Distance from Line [pm]",o->m_pLiDF[tia[1]]->m_sShortName); buf2.sprintf("%s Distance from Line [pm]",o->m_pLiDF[tia[1]]->m_sLabelName); o->m_pCDF->m_p3DF->m_p2DF[z3]->SetLabelY(buf2); break; } try { o->m_pCDF->m_p3DF->m_p2DF[z3]->m_sShortName = new char[strlen(buf3)+1]; } catch(...) { o->m_pCDF->m_p3DF->m_p2DF[z3]->m_sShortName = NULL; } if (o->m_pCDF->m_p3DF->m_p2DF[z3]->m_sShortName == NULL) NewException((double)(strlen(buf3)+1)*sizeof(char),__FILE__,__LINE__,__PRETTY_FUNCTION__); strcpy(o->m_pCDF->m_p3DF->m_p2DF[z3]->m_sShortName,buf3); // sprintf(buf3,"cdf_2"); // strcat(buf3,o->m_pCDF->m_p3DF->m_p2DF[z3]->m_sShortName); buf3.sprintf("cdf_2"); buf3.strcat(o->m_pCDF->m_p3DF->m_p2DF[z3]->m_sShortName); try { o->m_pCDF->m_p3DF->m_p2DF[z3]->m_sName = new char[strlen(buf3)+1]; } catch(...) { o->m_pCDF->m_p3DF->m_p2DF[z3]->m_sName = NULL; } if (o->m_pCDF->m_p3DF->m_p2DF[z3]->m_sName == NULL) NewException((double)(strlen(buf3)+1)*sizeof(char),__FILE__,__LINE__,__PRETTY_FUNCTION__); strcpy(o->m_pCDF->m_p3DF->m_p2DF[z3]->m_sName,buf3); } // END FOR z3 } // END IF CHANNELS == 3 try { o->m_pCDF->m_sShortName = new char[strlen(buf)+1]; } catch(...) { o->m_pCDF->m_sShortName = NULL; } if (o->m_pCDF->m_sShortName == NULL) NewException((double)(strlen(buf)+1)*sizeof(char),__FILE__,__LINE__,__PRETTY_FUNCTION__); strcpy(o->m_pCDF->m_sShortName,buf); // sprintf(buf,"cdf_%d",g_iCDFChannels); // strcat(buf,o->m_pCDF->m_sShortName); buf.sprintf("cdf_%d",g_iCDFChannels); buf.strcat(o->m_pCDF->m_sShortName); try { o->m_pCDF->m_sName = new char[strlen(buf)+1]; } catch(...) { o->m_pCDF->m_sName = NULL; } if (o->m_pCDF->m_sName == NULL) NewException((double)(strlen(buf)+1)*sizeof(char),__FILE__,__LINE__,__PRETTY_FUNCTION__); strcpy(o->m_pCDF->m_sName,buf); if (o->m_pCDF->m_bDumpDat) { // sprintf(buf,"cdfdump_%dd%s%s.csv",g_iCDFChannels,o->m_pCDF->m_sShortName,multibuf); buf.sprintf("cdfdump_%dd%s%s.csv",g_iCDFChannels,o->m_pCDF->m_sShortName,multibuf); o->m_pCDF->m_fDump = OpenFileWrite(buf,true); mfprintf(o->m_pCDF->m_fDump,"# step; RM; OM1; OM2; channels\n"); } if (o->m_bTimeDev) { if ((o->m_waSaveRefList.GetSize() == 1) || (!o->m_bSaveSeparateFiles)) { try { o->m_pCDF->m_fTimeDev = new FILE*[1]; } catch(...) { o->m_pCDF->m_fTimeDev = NULL; } if (o->m_pCDF->m_fTimeDev == NULL) NewException((double)sizeof(FILE*),__FILE__,__LINE__,__PRETTY_FUNCTION__); // sprintf(buf,"cdf_timedev_%dd%s%s.csv",g_iCDFChannels,o->m_pCDF->m_sShortName,multibuf); buf.sprintf("cdf_timedev_%dd%s%s.csv",g_iCDFChannels,o->m_pCDF->m_sShortName,multibuf); o->m_pCDF->m_fTimeDev[0] = OpenFileWrite(buf,true); } else { try { o->m_pCDF->m_fTimeDev = new FILE*[o->m_waSaveRefList.GetSize()]; } catch(...) { o->m_pCDF->m_fTimeDev = NULL; } if (o->m_pCDF->m_fTimeDev == NULL) NewException((double)o->m_waSaveRefList.GetSize()*sizeof(FILE*),__FILE__,__LINE__,__PRETTY_FUNCTION__); for (z2=0;z2m_waSaveRefList.GetSize();z2++) { // sprintf(buf,"cdf_timedev_%dd%s_ref%d%s.csv",g_iCDFChannels,o->m_pCDF->m_sShortName,z2+1,multibuf); buf.sprintf("cdf_timedev_%dd%s_ref%d%s.csv",g_iCDFChannels,o->m_pCDF->m_sShortName,z2+1,multibuf); o->m_pCDF->m_fTimeDev[z2] = OpenFileWrite(buf,true); } } if (o->m_pCDF->m_bTDAnimation) { try { o->m_pCDF->m_pTDAPlot = new CGrace(); } catch(...) { o->m_pCDF->m_pTDAPlot = NULL; } if (o->m_pCDF->m_pTDAPlot == NULL) NewException((double)sizeof(CGrace),__FILE__,__LINE__,__PRETTY_FUNCTION__); o->m_pCDF->m_pTDAPlot->SetTitle("CDF Time Development"); o->m_pCDF->m_pTDAPlot->SetSubTitle(&o->m_pCDF->m_sShortName[1]); for (z2=0;z2m_waSaveRefList.GetSize();z2++) { for (z3=0;z3m_waSaveShowList.GetSize();z3++) { for (z4=0;z4m_pCDF->m_iCombinationsEnabled;z4++) { o->m_pCDF->m_pTDAPlot->AddDataset(); if (g_iTrajSteps != -1) o->m_pCDF->m_pTDAPlot->LastDataset()->m_faValues.SetMaxSize(o->m_waSaveRefList.GetSize()*o->m_waSaveShowList.GetSize()*o->m_pCDF->m_iCombinationsEnabled*g_iTrajSteps); o->m_pCDF->m_pTDAPlot->LastDataset()->m_faValues.SetGrow(o->m_waSaveRefList.GetSize()*o->m_waSaveShowList.GetSize()*o->m_pCDF->m_iCombinationsEnabled*100); } } } o->m_pCDF->m_pTDAPlot->SetRangeX(o->m_pCDF->m_p2DF->m_fMinVal[0],o->m_pCDF->m_p2DF->m_fMaxVal[0]); o->m_pCDF->m_pTDAPlot->SetRangeY(o->m_pCDF->m_p2DF->m_fMinVal[1],o->m_pCDF->m_p2DF->m_fMaxVal[1]); o->m_pCDF->m_pTDAPlot->MakeTicks(); o->m_pCDF->m_pTDAPlot->SetLabelX(o->m_pCDF->m_p2DF->m_sLabelX); o->m_pCDF->m_pTDAPlot->SetLabelY(o->m_pCDF->m_p2DF->m_sLabelY); } } } // END IF CDF if (g_bVACF) { mprintf(" Creating VACF...\n"); o->m_pVACF->Create(); if (g_bVACFCacheMode) { mprintf(" VACF Cache: Trying to allocate %s of memory...\n",FormatBytes((double)((CMolecule*)g_oaMolecules[o->m_iShowMol])->m_laSingleMolIndex.GetSize()*o->m_pVACF->m_iShowAtomGes*g_iTrajSteps*3.1*sizeof(double))); for (z2=0;z2<((CMolecule*)g_oaMolecules[o->m_iShowMol])->m_laSingleMolIndex.GetSize()*o->m_pVACF->m_iShowAtomGes;z2++) { try { ptfa = new CxDoubleArray("main():ptfa"); } catch(...) { ptfa = NULL; } if (ptfa == NULL) NewException((double)sizeof(CxDoubleArray),__FILE__,__LINE__,__PRETTY_FUNCTION__); if (g_iTrajSteps != -1) { ptfa->SetMaxSize((long)(g_iTrajSteps*3.1)); ptfa->SetGrow((long)(g_iTrajSteps*0.1)); } else ptfa->SetGrow(1000); o->m_pVACF->m_oaCache.Add(ptfa); } } else { if (o->m_pVACF->m_iSize > g_iStepHistory) g_iStepHistory = o->m_pVACF->m_iSize; } } /* if (g_bDipACF) { mprintf(" Creating DipACF...\n"); o->m_pDipACF->Create(); }*/ if (g_bMSD) { mprintf(" Creating MSD...\n"); o->m_pMSD->m_pMSD->m_fMinVal = 0.0; o->m_pMSD->m_pMSD->m_fMaxVal = o->m_pMSD->m_iResolution*g_fTimestepLength*g_iStride/1000.0; o->m_pMSD->m_pMSD->m_iResolution = o->m_pMSD->m_iResolution/o->m_pMSD->m_iStride; o->m_pMSD->m_pMSD->Create(); if (g_bMSDCacheMode) { mprintf(" MSD Cache: Trying to reserve %s of memory...\n",FormatBytes((double)((CMolecule*)g_oaMolecules[o->m_iShowMol])->m_laSingleMolIndex.GetSize()*o->m_pMSD->m_iShowAtoms*g_iTrajSteps/g_iStride*3.1*sizeof(double))); for (z2=0;z2<((CMolecule*)g_oaMolecules[o->m_iShowMol])->m_laSingleMolIndex.GetSize()*o->m_pMSD->m_iShowAtoms;z2++) { try { ptfa = new CxDoubleArray("main():ptfa"); } catch(...) { ptfa = NULL; } if (ptfa == NULL) NewException((double)sizeof(CxDoubleArray),__FILE__,__LINE__,__PRETTY_FUNCTION__); if (g_iTrajSteps != -1) { ptfa->SetMaxSize((long)(g_iTrajSteps/g_iStride*3.1)); ptfa->SetGrow((long)(g_iTrajSteps/g_iStride*0.1)); } else ptfa->SetGrow(1000); o->m_pMSD->m_oaCache.Add(ptfa); } if (o->m_pMSD->m_bSplit) { mprintf(" MSD Split: Trying to reserve %s of memory...\n",FormatBytes((double)((CMolecule*)g_oaMolecules[o->m_iShowMol])->m_laSingleMolIndex.GetSize()*o->m_pMSD->m_iShowAtoms*o->m_pMSD->m_iResolution/o->m_pMSD->m_iStride*sizeof(double))); try { o->m_pMSD->m_pSplitMSD = new CAF*[((CMolecule*)g_oaMolecules[o->m_iShowMol])->m_laSingleMolIndex.GetSize()*o->m_pMSD->m_iShowAtoms]; } catch(...) { o->m_pMSD->m_pSplitMSD = NULL; } if (o->m_pMSD->m_pSplitMSD == NULL) NewException((double)((CMolecule*)g_oaMolecules[o->m_iShowMol])->m_laSingleMolIndex.GetSize()*o->m_pMSD->m_iShowAtoms*sizeof(CAF*),__FILE__,__LINE__,__PRETTY_FUNCTION__); for (z2=0;z2<((CMolecule*)g_oaMolecules[o->m_iShowMol])->m_laSingleMolIndex.GetSize()*o->m_pMSD->m_iShowAtoms;z2++) { try { o->m_pMSD->m_pSplitMSD[z2] = new CAF(); } catch(...) { o->m_pMSD->m_pSplitMSD[z2] = NULL; } if (o->m_pMSD->m_pSplitMSD[z2] == NULL) NewException((double)sizeof(CAF),__FILE__,__LINE__,__PRETTY_FUNCTION__); o->m_pMSD->m_pSplitMSD[z2]->m_fMinVal = 0.0; o->m_pMSD->m_pSplitMSD[z2]->m_fMaxVal = o->m_pMSD->m_iResolution*g_fTimestepLength/1000.0; o->m_pMSD->m_pSplitMSD[z2]->m_iResolution = o->m_pMSD->m_iResolution/o->m_pMSD->m_iStride; o->m_pMSD->m_pSplitMSD[z2]->Create(); } } } else { if (!g_bMSDCacheMode) { if (o->m_pMSD->m_iResolution > g_iStepHistory) g_iStepHistory = o->m_pMSD->m_iResolution; } } } if (g_bRevSDF) { mprintf(" Creating Pseudo SDF...\n"); o->m_pRevSDF->m_p2DF->m_fMinVal[0] = -o->m_pRevSDF->m_fRadius; o->m_pRevSDF->m_p2DF->m_fMaxVal[0] = o->m_pRevSDF->m_fRadius; o->m_pRevSDF->m_p2DF->m_fMinVal[1] = -o->m_pRevSDF->m_fRadius; o->m_pRevSDF->m_p2DF->m_fMaxVal[1] = o->m_pRevSDF->m_fRadius; o->m_pRevSDF->m_p2DF->m_iRes[0] = o->m_pRevSDF->m_iResolution; o->m_pRevSDF->m_p2DF->m_iRes[1] = o->m_pRevSDF->m_iResolution; o->m_pRevSDF->m_p2DF->SetLabelX("X [pm]"); o->m_pRevSDF->m_p2DF->SetLabelY("Y [pm]"); o->m_pRevSDF->m_p2DF->m_iHistogramRes = o->m_pRevSDF->m_iHistogramRes; o->m_pRevSDF->m_p2DF->Create(); try { o->m_pRevSDF->m_vaData = new CxDVec3Array[o->m_iShowMolCount]; } catch(...) { o->m_pRevSDF->m_vaData = NULL; } if (o->m_pRevSDF->m_vaData == NULL) NewException((double)o->m_iShowMolCount*sizeof(CxDVec3Array),__FILE__,__LINE__,__PRETTY_FUNCTION__); } if (g_bCond && o->m_bCondDevelopment) { buf.sprintf("cond_%d_%s_%s.csv",z+1,((CMolecule*)g_oaMolecules[g_iFixMol])->m_sName,((CMolecule*)g_oaMolecules[o->m_iShowMol])->m_sName); mprintf(" Creating Condition Temporal Development File \"%s\"...\n",(const char*)buf); o->m_pCondDevelopment = OpenFileWrite((const char*)buf,true); mfprintf(o->m_pCondDevelopment,"Step; Passed RM Count; Passed RM Percentage; Avg. Passed OM Count"); for (z2=1;z2<=o->m_iCondDevelopmentMax;z2++) mfprintf(o->m_pCondDevelopment,"; %d OM Count; %d OM Percentage",z2,z2); mfprintf(o->m_pCondDevelopment,"\n"); o->m_iaCondDevelopmentCounter.resize(o->m_iCondDevelopmentMax+1); } } if (g_bSDF && g_bSDFMap) { mprintf(" Creating SDF surface maps...\n"); for (z=0;zCreate(); } if (g_bBondACF) { mprintf(" Creating BondACF...\n"); for (z=0;zm_oaBondGroups.GetSize();z2++) { bg = (CMolBondGroup*)sm->m_oaBondGroups[z2]; for (z3=0;z3m_oaBonds.GetSize();z3++) { if (g_iTrajSteps != -1) { ((CMolBond*)bg->m_oaBonds[z3])->m_faData.SetMaxSize(g_iTrajSteps); ((CMolBond*)bg->m_oaBonds[z3])->m_faData.SetGrow(g_iTrajSteps/10); } else ((CMolBond*)bg->m_oaBonds[z3])->m_faData.SetGrow(10000); } } } } if (g_iRefSystemDim == 3) g_pRefMol.SetSize(((CMolecule*)g_oaMolecules[g_iFixMol])->m_iAtomGes); if ((g_iRefSystemDim == 3) && !g_bMiddleAvg) // Einfach das erstbeste Molekuel als Referenz nehmen { mprintf("Creating reference molecule from first time step..."); g_TimeStep.CalcCenters(); smfix = (CSingleMolecule*)g_oaSingleMolecules[((CMolecule*)g_oaMolecules[g_iFixMol])->m_laSingleMolIndex[g_iRefMolNum]]; vec1 = g_TimeStep.m_vaCoords[((CxIntArray*)smfix->m_oaAtomOffset[g_iFixAtomType[0]])->GetAt(g_iFixAtom[0])]; g_TimeStep.CenterPos(vec1); vec2 = g_TimeStep.m_vaCoords[((CxIntArray*)smfix->m_oaAtomOffset[g_iFixAtomType[1]])->GetAt(g_iFixAtom[1])]; vec3 = g_TimeStep.m_vaCoords[((CxIntArray*)smfix->m_oaAtomOffset[g_iFixAtomType[2]])->GetAt(g_iFixAtom[2])]; // vec2 -= vec1; // vec3 -= vec1; mat.MatUltra(vec2,vec3); cc = 0; // Jeden Atomtyp des Zielmolekuels durchgehen for (z3=0;z3<((CMolecule*)g_oaMolecules[g_iFixMol])->m_baAtomIndex.GetSize();z3++) { for (z4=0;z4<((CMolecule*)g_oaMolecules[g_iFixMol])->m_waAtomCount[z3];z4++) { vec2 = g_TimeStep.m_vaCoords[((CxIntArray*)smfix->m_oaAtomOffset[z3])->GetAt(z4)]; // vec2 -= vec1; g_pRefMol[cc] = mat * vec2; cc++; } } if (g_bPlProj) { g_TimeStep.FoldAtoms(); g_TimeStep.Transform(mat); for (z3=0;z3m_pPlProj->m_bAverageAtomPos) { ti = 0; for (z3=0;z3m_pPlProj->m_oDrawAtoms.m_oaAtoms.GetSize();z3++) { for (z4=0;z4<((CxIntArray*)o->m_pPlProj->m_oDrawAtoms.m_oaAtoms[z3])->GetSize();z4++) { o->m_pPlProj->m_vaAtomPos[ti] = g_TimeStep.m_vaCoords[((CxIntArray*)smfix->m_oaAtomOffset[o->m_pPlProj->m_oDrawAtoms.m_baAtomType[z3]])->GetAt(((CxIntArray*)o->m_pPlProj->m_oDrawAtoms.m_oaAtoms[z3])->GetAt(z4))]; ti++; } } } } } mprintf("Done.\n"); } // Ende Referenzbestimmung if (g_iSwapAtoms) { mprintf("Creating Reference Molecule Swap Matrix...\n"); try { pSwapMatrix = new unsigned int[((CMolecule*)g_oaMolecules[g_iFixMol])->m_iAtomGes*((CMolecule*)g_oaMolecules[g_iFixMol])->m_iAtomGes]; } catch(...) { pSwapMatrix = NULL; } if (pSwapMatrix == NULL) NewException((double)((CMolecule*)g_oaMolecules[g_iFixMol])->m_iAtomGes*((CMolecule*)g_oaMolecules[g_iFixMol])->m_iAtomGes*sizeof(unsigned int),__FILE__,__LINE__,__PRETTY_FUNCTION__); for (z=0;z<((CMolecule*)g_oaMolecules[g_iFixMol])->m_iAtomGes*((CMolecule*)g_oaMolecules[g_iFixMol])->m_iAtomGes;z++) pSwapMatrix[z] = 0; } g_iCurrentTimeStep = -1; g_iNextTimeStep = -1; g_iLastTimeStep = -1; try { g_pTempTimestep = new CTimeStep(); } catch(...) { g_pTempTimestep = NULL; } if (g_pTempTimestep == NULL) NewException((double)sizeof(CTimeStep),__FILE__,__LINE__,__PRETTY_FUNCTION__); if ((g_bSaveRefEnv) && (g_iNbhMode == 3) && (!g_bStreamInput)) { mprintf(WHITE,"\n>>> Pre-analysis for neighborhood search >>>\n"); /* g_fPos = fopen(g_sInputTraj,"rt"); // Eingabedatei erneut Oeffnen if (g_fPos == NULL) { eprintf("\nError. Input Trajectory suddenly vanished ^^\n"); return 0; }*/ if (!OpenInputTrajectory()) goto _ende; g_iSteps = 0; // Der Zaehler der Zeitschritte if (g_iScanNbhStart != 0) { mprintf("\nFast-forwarding to step %d...\n",g_iScanNbhStart+1); if (g_iTrajFormat == 7) mprintf("Warning: Index-based seeking for bqb files not yet implemented.\n"); mprintf(WHITE," ["); for (z=0;zm_laSingleMolIndex[g_iSaveRefMol]])->m_oaAtomOffset[g_iFixAtomType[0]])->GetAt(g_iFixAtom[0])]; // g_TimeStep.CenterPos(vec1); // if (g_bFold) // g_TimeStep.FoldMolecules(); // for (z=0;zScan((CSingleMolecule*)g_oaSingleMolecules[((CMolecule*)g_oaMolecules[g_iFixMol])->m_laSingleMolIndex[g_iSaveRefMol]],&g_TimeStep); if ((g_iScanNbhSteps > 0) && ((int)g_iSteps >= g_iScanNbhSteps)) break; } _endnbs: // fclose(g_fPos); if (!CloseInputTrajectory()) goto _ende; mprintf(WHITE,"\n\n<<< Neighborhood search done <<<\n"); // for (z0=0;z0m_oaConditionGroups.GetSize();z++) { if (g_pNbSet->m_oaConditionGroups[z] == NULL) continue; cg = (CConditionGroup*)g_pNbSet->m_oaConditionGroups[z]; try { tpi = new int[((CMolecule*)g_oaMolecules[z])->m_laSingleMolIndex.GetSize()]; } catch(...) { tpi = NULL; } if (tpi == NULL) NewException((double)((CMolecule*)g_oaMolecules[z])->m_laSingleMolIndex.GetSize()*sizeof(int),__FILE__,__LINE__,__PRETTY_FUNCTION__); for (z2=0;z2<((CMolecule*)g_oaMolecules[z])->m_laSingleMolIndex.GetSize();z2++) { cg->m_bAlwaysTrue[z2] = false; tpi[z2] = -1; } ti3 = 0; for (z2=0;z2<((CMolecule*)g_oaMolecules[z])->m_laSingleMolIndex.GetSize();z2++) { ti = 0; for (z3=z2;z3<((CMolecule*)g_oaMolecules[z])->m_laSingleMolIndex.GetSize();z3++) { for (z4=0;z4m_iPassCounter[z3] > ti) { ti = cg->m_iPassCounter[z3]; ti2 = z3; } _nbhave:; } if (ti == 0) break; ti3++; tpi[z2] = ti2; } mprintf(WHITE,"\n Molecule type %s. %d neighbors found in total:\n",((CMolecule*)g_oaMolecules[z])->m_sName,ti3); for (z2=0;z2m_iPassCounter[tpi[z2]])*g_iScanNbhStride/g_iSteps*100.0,cg->m_iPassCounter[tpi[z2]]); if (ti3 != 0) { z3 = AskUnsignedInteger("\nUse how many of the frequentiest neighbors for molecule %s? [%d] ",ti3,((CMolecule*)g_oaMolecules[z])->m_sName,ti3); for (z2=0;z2m_bAlwaysTrue[tpi[z2]] = true; } delete[] tpi; cg->m_bInactive = true; } } mprintf("\n"); // for (z0=0;z0AddMolecule(g_iFixMol,g_iSaveRefMol); } g_pNbSet->Reset(); g_pNbSet->Dump(); } if (g_bVFDF) { g_iVFCorrCount = 0; for (z=0;zm_baAtomIndex.GetSize();z2++) { // sprintf(buf,"vfcorr_%s_%s%s.dat",((CMolecule*)g_oaMolecules[z])->m_sName,((CAtom*)g_oaAtoms[((CMolecule*)g_oaMolecules[z])->m_baAtomIndex[z2]])->m_sName,multibuf); buf.sprintf("vfcorr_%s_%s%s.dat",((CMolecule*)g_oaMolecules[z])->m_sName,(const char*)((CAtom*)g_oaAtoms[((CMolecule*)g_oaMolecules[z])->m_baAtomIndex[z2]])->m_sName,multibuf); // FreeFileName(buf); g_fVFCorr[g_iVFCorrCount] = OpenFileWrite(buf,true); g_iVFCorrCount++; } } } if (g_bSaveRefEnv) { mprintf("\n"); // sprintf(g_sRefEnv,"refenv_%s.%d.",((CMolecule*)g_oaMolecules[g_iFixMol])->m_sName,g_iSaveRefMol+1); g_sRefEnv.sprintf("refenv_%s.%d.",((CMolecule*)g_oaMolecules[g_iFixMol])->m_sName,g_iSaveRefMol+1); /* for (z=0;zm_waMolCount[z] != 0) { sprintf(buf2,"%dx%s.",g_pNbAll->m_waMolCount[z],((CMolecule*)g_oaMolecules[z])->m_sName); strcat(g_sRefEnv,buf2); }*/ /* if (!g_bDynamicNeighbor) strcat(g_sRefEnv,"static."); if (g_bRefEnvCenter) strcat(g_sRefEnv,"center."); if (g_bRefEnvFix) strcat(g_sRefEnv,"fix."); if (g_bScanNeighbors) strcat(g_sRefEnv,"scannb.");*/ // strcat(g_sRefEnv,multibuf); // strcat(g_sRefEnv,"xyz"); g_sRefEnv.strcat(multibuf); g_sRefEnv.strcat("xyz"); mprintf(">>> Saving reference environment as %s\n",(const char*)g_sRefEnv); // FreeFileName(g_sRefEnv); g_fRefEnv = OpenFileWrite(g_sRefEnv,true); mprintf("\n"); } if (g_bCutCluster) { mprintf("\n"); // sprintf(g_sRefEnv,"cluster_%s.",((CMolecule*)g_oaMolecules[g_iFixMol])->m_sName); g_sRefEnv.sprintf("cluster_%s.",((CMolecule*)g_oaMolecules[g_iFixMol])->m_sName); /* for (z=0;zm_waMolCount[z] != 0) { sprintf(buf2,"%dx%s.",g_pNbAll->m_waMolCount[z],((CMolecule*)g_oaMolecules[z])->m_sName); strcat(g_sRefEnv,buf2); }*/ /* if (g_bRefEnvCenter) strcat(g_sRefEnv,"center."); if (g_bRefEnvFix) strcat(g_sRefEnv,"fix.");*/ // strcat(g_sRefEnv,multibuf); // strcat(g_sRefEnv,"xyz"); g_sRefEnv.strcat(multibuf); g_sRefEnv.strcat("xyz"); mprintf(">>> Saving cluster list as %s\n",(const char*)g_sRefEnv); // FreeFileName(g_sRefEnv); g_fRefEnv = OpenFileWrite(g_sRefEnv,true); mprintf("\n"); } if (g_bSaveJustTraj) { // strcpy(buf,g_sInputTraj); buf.strcpy(g_sInputTraj); p = strrchr(buf.GetWritePointer(),'/'); q = strrchr(buf.GetWritePointer(),'\\'); if (q > p) p = q; if (p == NULL) p = buf.GetWritePointer(); else p++; // strcpy(buf2,p); buf2.strcpy(p); p = strrchr(buf2.GetWritePointer(),'.'); if (p != NULL) *p = 0; // strcat(buf2,multibuf); // strcat(buf2,"_out.xyz"); buf2.strcat(multibuf); if (g_bProcSplit) { procsplitbuf = buf2; buf2.strcat("_out.001.xyz"); procspliti = 0; procsplitc = 0; } else buf2.strcat("_out.xyz"); // FreeFileName(buf); // sprintf(buf,"traj_out.xyz"); mprintf("Saving processed trajectory as %s ...\n",(const char*)buf2); g_fSaveJustTraj = OpenFileWrite(buf2,true); if (g_bProcDumpAwkScript) { buf = ""; for (z=0;zm_iCount == 0) continue; buf2.sprintf("%s%d",(const char*)((CAtom*)g_oaAtoms[z])->m_sName,((CAtom*)g_oaAtoms[z])->m_iCount); buf.strcat(buf2); } buf2.sprintf("%s",(const char*)buf); buf.sprintf("resort_%s.sh",(const char*)buf2); mprintf("Saving resorting shell script as %s ...\n",(const char*)buf); a = OpenFileWrite(buf,true); mfprintf(a,"#!/usr/bin/gawk -f\n"); mfprintf(a,"\n"); mfprintf(a,"BEGIN {\n"); mfprintf(a," order=\""); if (g_bWriteInputOrder) { // This implies that all non-virtual atoms are to be written for (z7=0;z7m_pMolecule->m_laSingleMolIndex.GetSize();z6++) { for (z4=0;z4m_baAtomType.GetSize();z4++) { if (atgr->m_baRealAtomType[z4] != z7) continue; tla = (CxIntArray*)atgr->m_oaAtoms[z4]; for (z5=0;z5GetSize();z5++) { if (atgr->m_baRealAtomType[z4] == g_iVirtAtomType) continue; mfprintf(a,"%d ",((CxIntArray*)((CSingleMolecule*)g_oaSingleMolecules[atgr->m_pMolecule->m_laSingleMolIndex[z6]])->m_oaAtomOffset[atgr->m_baAtomType[z4]])->GetAt(tla->GetAt(z5))+1); } } } } } } else { for (z3=0;z3m_pMolecule->m_laSingleMolIndex.GetSize();z6++) { for (z4=0;z4m_baAtomType.GetSize();z4++) { tla = (CxIntArray*)atgr->m_oaAtoms[z4]; for (z5=0;z5GetSize();z5++) { if (atgr->m_baRealAtomType[z4] == g_iVirtAtomType) continue; mfprintf(a,"%d ",((CxIntArray*)((CSingleMolecule*)g_oaSingleMolecules[atgr->m_pMolecule->m_laSingleMolIndex[z6]])->m_oaAtomOffset[atgr->m_baAtomType[z4]])->GetAt(tla->GetAt(z5))+1); } } } } } } mfprintf(a,"\";\n"); mfprintf(a," labels=\""); if (g_bWriteInputOrder) { // This implies that all non-virtual atoms are to be written for (z7=0;z7m_sName; if (g_bProcAlternativeLabels) if (((CxString*)g_oaProcAlternativeLabels[z7])->GetLength() != 0) cp = (const char*)*((CxString*)g_oaProcAlternativeLabels[z7]); mfprintf(a,"%s ",cp); } } else { if (g_bWriteAtomwise) { for (z7=0;z7m_pMolecule->m_laSingleMolIndex.GetSize();z6++) { for (z4=0;z4m_baAtomType.GetSize();z4++) { if (atgr->m_baRealAtomType[z4] != z7) continue; tla = (CxIntArray*)atgr->m_oaAtoms[z4]; for (z5=0;z5GetSize();z5++) { if (atgr->m_baRealAtomType[z4] == g_iVirtAtomType) continue; cp = ((CAtom*)g_oaAtoms[atgr->m_baRealAtomType[z4]])->m_sName; if (g_bProcAlternativeLabels) if (((CxString*)g_oaProcAlternativeLabels[((CxIntArray*)((CSingleMolecule*)g_oaSingleMolecules[atgr->m_pMolecule->m_laSingleMolIndex[z6]])->m_oaAtomOffset[atgr->m_baAtomType[z4]])->GetAt(tla->GetAt(z5))])->GetLength() != 0) cp = (const char*)*((CxString*)g_oaProcAlternativeLabels[((CxIntArray*)((CSingleMolecule*)g_oaSingleMolecules[atgr->m_pMolecule->m_laSingleMolIndex[z6]])->m_oaAtomOffset[atgr->m_baAtomType[z4]])->GetAt(tla->GetAt(z5))]); mfprintf(a,"%s ",cp); } } } } } } else { for (z3=0;z3m_pMolecule->m_laSingleMolIndex.GetSize();z6++) { for (z4=0;z4m_baAtomType.GetSize();z4++) { tla = (CxIntArray*)atgr->m_oaAtoms[z4]; for (z5=0;z5GetSize();z5++) { if (atgr->m_baRealAtomType[z4] == g_iVirtAtomType) continue; cp = ((CAtom*)g_oaAtoms[atgr->m_baRealAtomType[z4]])->m_sName; if (g_bProcAlternativeLabels) if (((CxString*)g_oaProcAlternativeLabels[((CxIntArray*)((CSingleMolecule*)g_oaSingleMolecules[atgr->m_pMolecule->m_laSingleMolIndex[z6]])->m_oaAtomOffset[atgr->m_baAtomType[z4]])->GetAt(tla->GetAt(z5))])->GetLength() != 0) cp = (const char*)*((CxString*)g_oaProcAlternativeLabels[((CxIntArray*)((CSingleMolecule*)g_oaSingleMolecules[atgr->m_pMolecule->m_laSingleMolIndex[z6]])->m_oaAtomOffset[atgr->m_baAtomType[z4]])->GetAt(tla->GetAt(z5))]); mfprintf(a,"%s ",cp); } } } } } } mfprintf(a,"\";\n"); mfprintf(a," no=split(order,aorder);\n"); mfprintf(a," nl=split(labels,alabels);\n"); mfprintf(a," qn = 0;\n"); mfprintf(a," i = 0;\n"); mfprintf(a," s = 0;\n"); mfprintf(a," print \"************************************************************\" > \"/dev/stderr\"\n"); mfprintf(a," print \"*** Automatically generated trajectory reordering script ***\" > \"/dev/stderr\"\n"); mfprintf(a," print \"*** Written by TRAVIS, Licensed under GNU GPL v3 ***\" > \"/dev/stderr\"\n"); mfprintf(a," print \"*** (c) Martin Brehm, 2017 ***\" > \"/dev/stderr\"\n"); mfprintf(a," print \"*** See http://www.travis-analyzer.de/ ***\" > \"/dev/stderr\"\n"); mfprintf(a," print \"************************************************************\" > \"/dev/stderr\"\n"); mfprintf(a," print \"\" > \"/dev/stderr\"\n"); time(<ime); today = localtime(<ime); strcpy(obuf,asctime(today)); obuf[strlen(obuf)-1] = 0; mfprintf(a," print \"Script created by TRAVIS on %s\" > \"/dev/stderr\"\n",(const char*)obuf); mfprintf(a," print \"Suitable for system %s\" > \"/dev/stderr\"\n",(const char*)buf2); mfprintf(a," print \"\" > \"/dev/stderr\"\n"); mfprintf(a," print \"Usage: cat inputfile.xyz | ./%s > outputfile.xyz\" > \"/dev/stderr\"\n",(const char*)buf); mfprintf(a," print \"\" > \"/dev/stderr\"\n"); mfprintf(a," if (no != nl) {\n"); mfprintf(a," print \"*** Internal error:\",no,\"= no != nl =\",nl,\".\" > \"/dev/stderr\"\n"); mfprintf(a," print \"Leaving.\" > \"/dev/stderr\"\n"); mfprintf(a," exit 1\n"); mfprintf(a," }\n"); mfprintf(a,"}\n"); mfprintf(a,"\n"); mfprintf(a,"{\n"); mfprintf(a," if (qn == 0) {\n"); mfprintf(a," n = $1;\n"); mfprintf(a," qn = 1;\n"); mfprintf(a," print \"Trajectory contains\",n,\"atoms.\" > \"/dev/stderr\"\n"); mfprintf(a," if (n != %d) {\n",g_iGesAtomCount); mfprintf(a," print \"*** Error ***\" > \"/dev/stderr\"\n"); mfprintf(a," print \"This script was created for system %s with %d atoms.\" > \"/dev/stderr\"\n",(const char*)buf2,g_iGesAtomCount); mfprintf(a," print \"It can only be used for this system.\" > \"/dev/stderr\"\n"); mfprintf(a," print \"Leaving.\" > \"/dev/stderr\"\n"); mfprintf(a," exit 1\n"); mfprintf(a," }\n"); mfprintf(a," print \"Will output\",no,\"atoms.\" > \"/dev/stderr\"\n"); mfprintf(a," }\n"); mfprintf(a," if (i == 0) {\n"); mfprintf(a," } else if (i == 1)\n"); mfprintf(a," comm = $0;\n"); mfprintf(a," else {\n"); mfprintf(a," f1[i-1] = $1;\n"); mfprintf(a," f2[i-1] = $2;\n"); mfprintf(a," f3[i-1] = $3;\n"); mfprintf(a," f4[i-1] = $4;\n"); mfprintf(a," if (NF > 4)\n"); mfprintf(a," fr[i-1] = \" \" substr($0, index($0,$5));\n"); mfprintf(a," else\n"); mfprintf(a," fr[i-1] = \" \";\n"); mfprintf(a," }\n"); mfprintf(a," i++;\n"); mfprintf(a," if (i >= n+2) {\n"); mfprintf(a," printf(\"%%d\\n\",no);\n"); mfprintf(a," printf(\"%%s\\n\",comm);\n"); mfprintf(a," for (z=1;z<=no;z++)\n"); mfprintf(a," printf(\"%%-4s %%12.8f %%12.8f %%12.8f%%s\\n\",alabels[z],f2[aorder[z]],f3[aorder[z]],f4[aorder[z]],fr[aorder[z]]);\n"); mfprintf(a," i = 0;\n"); mfprintf(a," s++;\n"); mfprintf(a," if ((s %% 100) == 0)\n"); mfprintf(a," print \"Processing step\",s,\"...\" > \"/dev/stderr\"\n"); mfprintf(a," }\n"); mfprintf(a,"}\n"); mfprintf(a,"\n"); mfprintf(a,"END {\n"); mfprintf(a," if (i != 0) {\n"); mfprintf(a," print \"\"\n"); mfprintf(a," print \"Warning: Last frame of input trajectory only contained\",i-2,\"instead of\",n,\"atoms.\" > \"/dev/stderr\"\n"); mfprintf(a," print \" The incomplete frame has been skipped.\" > \"/dev/stderr\"\n"); mfprintf(a," print \"\"\n"); mfprintf(a," }\n"); mfprintf(a," print \"Finished. Processed\",s,\"steps.\" > \"/dev/stderr\"\n"); mfprintf(a,"}\n"); fclose(a); #ifdef TARGET_LINUX buf2.sprintf("chmod +x %s",(const char*)buf); mprintf("Executing \"%s\"...\n",(const char*)buf2); (void)system(buf2); #endif mprintf("Finished writing script.\n\n"); mprintf("Usage: cat inputfile.xyz | ./%s > outputfile.xyz\n\n",(const char*)buf); } } /******* Interface *******************/ if (!Interface_Initialization()) goto _ende; mprintf(WHITE,"\n<<< End of Initialization <<<\n\n"); mprintf(WHITE,"\n### Starting Main Analysis ###\n"); if (g_bVHDF) mprintf("\n Please note: The VHCF analysis will become slower while it proceeds.\n"); #ifdef TARGET_LINUX if (!g_bMultiInterval || (multicounter == 0)) { mprintf(WHITE,"\nHint: "); mprintf("Press CTRL+C once to softly interrupt analysis and still write the results.\n"); mprintf(" Creating an empty file named EXIT (\"touch EXIT\") has the same effect.\n"); } #endif if (!g_bStreamInput) { /* g_fPos = fopen(g_sInputTraj,"rb"); if (g_fPos == NULL) { eprintf("\nCould not open position trajectory.\n"); goto _ende; }*/ if (!OpenInputTrajectory()) goto _ende; } if ((g_bNPT) && (g_sNPTFile[0] != 0)) { g_fNPTFile = fopen(g_sNPTFile,"rt"); if (g_fNPTFile == NULL) { eprintf("\nCould not open cell vector file.\n"); goto _ende; } } if (g_bUseVelocities && g_bReadVelocity) { g_fVel = fopen((const char*)g_sInputVel,"rt"); if (g_fVel == NULL) { eprintf("\nCould not open velocity trajectory.\n"); goto _ende; } } if (g_bUseForces && (g_sInputForce[0] != 0)) { g_fForce = fopen(g_sInputForce,"rt"); if (g_fForce == NULL) { eprintf("\nCould not open force trajectory.\n"); goto _ende; } } // fff = fopen("dipole.txt","wt"); if (g_iBeginStep != 0) { mprintf("\nFast-forwarding to step %d...\n",g_iBeginStep+1); if (g_iTrajFormat == 7) mprintf("Warning: Index-based seeking for bqb files not yet implemented.\n"); // mprintf("Seek: %d.\n",g_iFastForwardPos); // fseek(g_fPos,g_iFastForwardPos,SEEK_SET); if (g_iTrajFormat == 7) { mprintf(WHITE," ["); for (z=0;zGetSize();z2++) { fprintf(g_fDumpDipole,"; %s[%d]_X; Y; Z",((CMolecule*)g_oaMolecules[z])->m_sName,((CxIntArray*)g_oaDumpDipoleVector[z])->GetAt(z2)+1); if (g_bDumpDipoleAbs) fprintf(g_fDumpDipole,"; Abs"); } } fprintf(g_fDumpDipole,"\n"); if (g_bDumpDipoleXYZ) { g_fDumpDipoleXYZ = OpenFileWrite("dipole_vectors.xyz",true); g_fDumpDipolePURE = OpenFileWrite("dipoles.xyz",true); fprintf(g_fDumpDipoleXYZ,"%d\n\n",g_iDumpDipoleXYZAtoms); for (z=0;zGetSize();z2++) { sm = (CSingleMolecule*)g_oaSingleMolecules[m->m_laSingleMolIndex[((CxIntArray*)g_oaDumpDipoleVector[z])->GetAt(z2)]]; for (z3=0;z3m_baAtomIndex.GetSize();z3++) { if (m->m_baAtomIndex[z3] == g_iVirtAtomType) continue; for (z4=0;z4<((CxIntArray*)sm->m_oaAtomOffset[z3])->GetSize();z4++) { ti = ((CxIntArray*)sm->m_oaAtomOffset[z3])->GetAt(z4); fprintf(g_fDumpDipoleXYZ,"%s %12f %12f %12f\n",(const char*)((CAtom*)g_oaAtoms[m->m_baAtomIndex[z3]])->m_sName,g_TimeStep.m_vaCoords[ti][0]/100.0,g_TimeStep.m_vaCoords[ti][1]/100.0,g_TimeStep.m_vaCoords[ti][2]/100.0); } } } } ti2 = 0; for (z=0;zGetSize();z2++) { fprintf(g_fDumpDipoleXYZ,"B %12f 0 0\n",100.0+ti2*3.0); fprintf(g_fDumpDipoleXYZ,"B %12f 0.5 0\n",100.0+ti2*3.0); ti2++; } } } } /***************************************************************************** *************** Beginn Hauptschleife ***************************************** *****************************************************************************/ g_iLastTimeStep = -1; g_iDotCounter = 0; g_bStepSkipped = false; g_iFirstStepSkipped = -1; tbs = false; t0 = (unsigned long)time(NULL); while (true) // Zeitschritt fuer Zeitschritt die Trajektorie durchgehen { if (g_bCubeStream) { char filename[1024]; if (g_iSteps > 0) { printCubeMemFileName(filename, 1024, false); if (remove(filename) != 0) { eprintf("Could not remove \"%s\": %s\n", filename, strerror(errno)); } } if (g_iSteps >= (unsigned int)g_iCubeMemFileSteps) { mprintf("\n\n%lu cube files read.\n", g_iSteps); break; } printCubeMemFileName(filename, 1024, true); g_fCubeMemFile->ReadFileSuccessive(filename, g_iCubeMemFileLines, false); } // if (feof(g_fPos)) if (InputTrajectoryEOF()) { mprintf("\nEnd of trajectory file reached.\n"); break; } if (g_bAbortAnalysis) { mprintf("\nAnalysis aborted by user.\n"); break; } g_iCurrentTimeStep++; if (g_iCurrentTimeStep >= g_iStepHistory) g_iCurrentTimeStep = 0; if (g_bDeriv) { g_iDerivNext++; if (g_iDerivNext > 2) g_iDerivNext = 0; g_iDerivCurr++; if (g_iDerivCurr > 2) g_iDerivCurr = 0; g_iDerivLast++; if (g_iDerivLast > 2) g_iDerivLast = 0; } for (z=0;z<(g_iStride-1);z++) { if (!g_TimeStep.SkipTimestep(g_fPos)) { // if (!feof(g_fPos)) if (!InputTrajectoryEOF()) eprintf("\nError while skipping time step %lu.\n",g_iSteps+z+1); goto _endmainloop; } if (((g_bNPT) && (g_sNPTFile[0] != 0))) // fgets(buf,256,g_fNPTFile); (void)buf.fgets(256,g_fNPTFile); if (g_fVel != NULL) { if (!g_TimeStep.SkipTimestep(g_fVel)) { eprintf("\nError while skipping velocity time step %lu.\n",g_iSteps+z+1); goto _endmainloop; } } if (g_fForce != NULL) { if (!g_TimeStep.SkipTimestep(g_fForce)) { eprintf("\nError while skipping force time step %lu.\n",g_iSteps+z+1); goto _endmainloop; } } } _readagain: if (g_bUseVelocities || g_bUseForces) { if (GetTimeStep(-1) == NULL) { try { *GetTimeStepAddress(-1) = new CTimeStep(); } catch(...) { *GetTimeStepAddress(-1) = NULL; } if (*GetTimeStepAddress(-1) == NULL) NewException((double)sizeof(CTimeStep),__FILE__,__LINE__,__PRETTY_FUNCTION__); } bool ok = false; if (g_bCubeStream) ok = GetTimeStep(-1)->ReadTimestep(g_fCubeMemFile); else ok = GetTimeStep(-1)->ReadTimestep(g_fPos,false); if (!ok) { // if (feof(g_fPos)) if (InputTrajectoryEOF()) { mprintf("\nEnd of Trajectory File reached.\n"); break; } eprintf("\nError while reading time step %lu.\n",g_iSteps+1); goto _endmainloop; } if (((g_bNPT) && (g_sNPTFile[0] != 0))) GetTimeStep(-1)->ReadCellVector(g_fNPTFile); if (g_bSkipDoubleSteps) { if (GetTimeStep(-1)->ExtractNumber(g_iNumberPos) <= g_iLastTimeStep) { if (!g_bStepSkipped) { g_bStepSkipped = true; g_iFirstStepSkipped = GetTimeStep(-1)->ExtractNumber(g_iNumberPos); mprintf("\nSkipping:"); } mprintf("*"); goto _readagain; } else if (g_iFirstStepSkipped != -1) { if (g_iFirstStepSkipped == GetTimeStep(-1)->ExtractNumber(g_iNumberPos)) mprintf("\nRepeated step %d skipped.",g_iFirstStepSkipped); else mprintf("\nRepeated steps %d-%ld skipped.",g_iFirstStepSkipped,GetTimeStep(-1)->ExtractNumber(g_iNumberPos)); g_iDotCounter = 0; g_iFirstStepSkipped = -1; } if (g_iLastTimeStep != -1) { if (g_iStrideDetect == -1) { g_iStrideDetect = GetTimeStep(-1)->ExtractNumber(g_iNumberPos) - g_iLastTimeStep; } else { if (g_iStrideDetect != (GetTimeStep(-1)->ExtractNumber(g_iNumberPos) - g_iLastTimeStep)) { if (!tbs) eprintf("\n"); eprintf("Warning: Two successive steps %lu (%d) and %lu (%ld) have different distance than seen before: %d.\n",g_iSteps-1,g_iLastTimeStep,g_iSteps,GetTimeStep(-1)->ExtractNumber(g_iNumberPos),g_iStrideDetect); tbs = true; } else tbs = false; } } if (GetTimeStep(-1)->ExtractNumber(g_iNumberPos) > g_iLastTimeStep) g_iLastTimeStep = GetTimeStep(-1)->ExtractNumber(g_iNumberPos); } if (GetTimeStep(-1)->m_iGesAtomCount == 0) { eprintf("\nError: Atom count = 0 at time step %lu.\n",g_iSteps+1); goto _endmainloop; } GetTimeStep(-1)->UniteMolecules(false); if (g_bRemoveCOM) GetTimeStep(-1)->CenterCOM(); GetTimeStep(-1)->CalcCenters(); if (g_bDipole) { if (g_bWannier) GetTimeStep(-1)->ScanWannier(false); // GetTimeStep(-1)->CalcDipoles(false); // if (g_bDumpDipoleVector) // GetTimeStep(-1)->DumpDipoles(); } } else { if (GetTimeStep(0) == NULL) { try { *GetTimeStepAddress(0) = new CTimeStep(); } catch(...) { *GetTimeStepAddress(0) = NULL; } if (*GetTimeStepAddress(0) == NULL) NewException((double)sizeof(CTimeStep),__FILE__,__LINE__,__PRETTY_FUNCTION__); } bool ok = false; if (g_bCubeStream) ok = GetTimeStep(0)->ReadTimestep(g_fCubeMemFile); else ok = GetTimeStep(0)->ReadTimestep(g_fPos,false); if (!ok) { // if (feof(g_fPos)) if (InputTrajectoryEOF()) { mprintf("\nEnd of trajectory file reached.\n"); // Thix fix allows to use GetTimeStep(0) after the end of the main loop, like the Raman module does g_iCurrentTimeStep--; if (g_iCurrentTimeStep < 0) g_iCurrentTimeStep += g_iStepHistory; // End of Fix break; } eprintf("\nError while reading time step %lu.\n",g_iSteps+1); goto _endmainloop; } if (((g_bNPT) && (g_sNPTFile[0] != 0))) GetTimeStep(0)->ReadCellVector(g_fNPTFile); if (g_bSkipDoubleSteps) { if (GetTimeStep(0)->ExtractNumber(g_iNumberPos) <= g_iLastTimeStep) { // mprintf("\n[Skip %d/%d]",GetTimeStep(0)->ExtractNumber(),g_iLastTimeStep); if (!g_bStepSkipped) { g_bStepSkipped = true; g_iFirstStepSkipped = GetTimeStep(0)->ExtractNumber(g_iNumberPos); mprintf("\nSkipping:"); } mprintf("*"); goto _readagain; } else if (g_iFirstStepSkipped != -1) { if (g_iFirstStepSkipped == GetTimeStep(0)->ExtractNumber(g_iNumberPos)) mprintf("\nRepeated step %d skipped.",g_iFirstStepSkipped); else mprintf("\nRepeated steps %d-%ld skipped.",g_iFirstStepSkipped,GetTimeStep(0)->ExtractNumber(g_iNumberPos)); g_iDotCounter = 0; g_iFirstStepSkipped = -1; } // mprintf("\nNumber %d.",GetTimeStep(0)->ExtractNumber()); if (g_iLastTimeStep != -1) { if (g_iStrideDetect == -1) { g_iStrideDetect = GetTimeStep(0)->ExtractNumber(g_iNumberPos) - g_iLastTimeStep; } else { if (g_iStrideDetect != (GetTimeStep(0)->ExtractNumber(g_iNumberPos) - g_iLastTimeStep)) { if (!tbs) eprintf("\n"); eprintf("Warning: Successive steps %lu (%d) and %lu (%ld) have different distance than seen before: %d.\n",g_iSteps-1,g_iLastTimeStep,g_iSteps,GetTimeStep(0)->ExtractNumber(g_iNumberPos),g_iStrideDetect); tbs = true; } else tbs = false; } } if (GetTimeStep(0)->ExtractNumber(g_iNumberPos) > g_iLastTimeStep) g_iLastTimeStep = GetTimeStep(0)->ExtractNumber(g_iNumberPos); } if (GetTimeStep(0)->m_iGesAtomCount == 0) { eprintf("\nError: Atom count = 0 at time step %lu.\n",g_iSteps+1); goto _endmainloop; } if (!g_bSaveCoordsUnchanged) { GetTimeStep(0)->UniteMolecules(false); if (g_bRemoveCOM) GetTimeStep(0)->CenterCOM(); } GetTimeStep(0)->CalcCenters(); if (g_bDipole) { if (g_bWannier) GetTimeStep(0)->ScanWannier(false); // GetTimeStep(0)->CalcDipoles(false); // if (g_bDumpDipoleVector) // GetTimeStep(0)->DumpDipoles(); } } g_bWarnUnsteady = false; if (((g_iSteps-(sic*g_iStride*50)) % (showinterval*g_iStride)) == 0) { if ((g_iSteps == 0) || g_bStepSkipped) { g_bStepSkipped = false; if (!g_bSilentProgress) mprintf("\nStep %6lu ",g_iSteps); } if (g_bAsciiArt && (!g_bSilentProgress)) { tc = g_oAsciiArt.GetChar(); if (tc == 0) { if ((g_iSteps != 0) && (g_iTrajSteps != -1)) { if ((time(NULL) - t0) > 5) { eta = (unsigned long)(((double)time(NULL) - t0) / g_iSteps * ((double)max(long(0),(((g_iMaxStep > 0)?g_iMaxStep:g_iTrajSteps) - ((long)g_iSteps))))); FormatTime(eta,&buf); mprintf(" ETA %s",(const char*)buf); } } mprintf("\nStep %6lu ",g_iSteps); if (g_iSteps != 0) g_oAsciiArt.NewLine(); } else mprintf("%c",tc); } else { if (g_iDotCounter >= 50) { g_iDotCounter = 0; if (!g_bSilentProgress) { if ((g_iSteps != 0) && (g_iTrajSteps != -1)) { if ((time(NULL) - t0) > 5) { eta = (unsigned long)(((double)time(NULL) - t0) / g_iSteps * ((double)max(long(0),g_iTrajSteps - ((long)g_iSteps)))); FormatTime(eta,&buf); mprintf(" ETA %s",(const char*)buf); } } mprintf("\nStep %6lu ",g_iSteps); } } g_iDotCounter++; if (!g_bSilentProgress) mprintf("."); } if (FileExist("EXIT")) { mprintf("\n\n*** File \"EXIT\" detected. Aborting analysis. ***\n\n"); remove("EXIT"); break; } } if ((int)g_iSteps == /*showinterval**/g_iStride*50) { t1 = (unsigned long)time(NULL); if (t1 == t0) showinterval = 20; else showinterval = (int)(20.0/(t1-t0)); if (showinterval == 0) showinterval = 1; sic = 1; } g_iSteps += g_iStride; if (GetTimeStep(0)==NULL) continue; if (((g_bUseVelocities && !g_bReadVelocity) || g_bUseForces) && (GetTimeStep(1)==NULL)) continue; if (g_bUseVelocities) { if (g_fVel == NULL) { CalcVelocities(); } else if (!GetTimeStep(-1)->ReadTimestepVel(g_fVel)) { eprintf("\nError reading velocity time step %lu.\n",g_iSteps+1); goto _endmainloop; } } if (g_bUseForces) { if (g_fForce == NULL) { CalcForces(); } else if (!GetTimeStep(-1)->ReadTimestepForce(g_fForce)) { eprintf("\nError reading force time step %lu.\n",g_iSteps+1); goto _endmainloop; } } if (g_bCubeTimeDev) { CalcVolumetricDataTimeDev(); CalcCurrentDensity(); } if (g_bTegri) { g_pTetraPak->ProcessStep(GetTimeStep(0), false); } if (g_bDipole) { GetTimeStep(0)->CalcDipoles(false); if (g_bDumpDipoleVector) GetTimeStep(0)->DumpDipoles(); } if (g_bMagneticDipoleRestart || g_bVCD) { GetTimeStep(0)->CalcMagneticDipoles(); } if (g_bTegri) if (g_pTetraPak->m_bSaveAtomIntegrals) DumpMolecularProps(); if (g_bCutCluster) { if (((int)g_iSteps/g_iStride) >= g_iClusterSteps) break; if (g_iClusterPos >= g_iClusterCount) break; if (g_iaClusterSteps[g_iClusterPos] != ((int)g_iSteps/g_iStride)) continue; } // mprintf("\nStep %d for clusters.",((int)g_iSteps/g_iStride)); if (g_bUnwrap && ((int)g_iSteps > g_iStride)) // Nicht im ersten Schritt { for (z=0;zm_baAtomIndex.GetSize();z3++) { if (m->m_baAtomIndex[z3] != g_iVirtAtomType) continue; for (z2=0;z2m_laSingleMolIndex.GetSize();z2++) { sm = (CSingleMolecule*)g_oaSingleMolecules[m->m_laSingleMolIndex[z2]]; if (GetTimeStep(0)->m_vaCoords[((CxIntArray*)sm->m_oaAtomOffset[z3])->GetAt(0)][0] - GetTimeStep(1)->m_vaCoords[((CxIntArray*)sm->m_oaAtomOffset[z3])->GetAt(0)][0] > g_fBoxX/2.0) g_vaUnwrapArray[m->m_laSingleMolIndex[z2]][0] -= g_fBoxX; if (GetTimeStep(0)->m_vaCoords[((CxIntArray*)sm->m_oaAtomOffset[z3])->GetAt(0)][0] - GetTimeStep(1)->m_vaCoords[((CxIntArray*)sm->m_oaAtomOffset[z3])->GetAt(0)][0] < -g_fBoxX/2.0) g_vaUnwrapArray[m->m_laSingleMolIndex[z2]][0] += g_fBoxX; if (GetTimeStep(0)->m_vaCoords[((CxIntArray*)sm->m_oaAtomOffset[z3])->GetAt(0)][1] - GetTimeStep(1)->m_vaCoords[((CxIntArray*)sm->m_oaAtomOffset[z3])->GetAt(0)][1] > g_fBoxY/2.0) g_vaUnwrapArray[m->m_laSingleMolIndex[z2]][1] -= g_fBoxY; if (GetTimeStep(0)->m_vaCoords[((CxIntArray*)sm->m_oaAtomOffset[z3])->GetAt(0)][1] - GetTimeStep(1)->m_vaCoords[((CxIntArray*)sm->m_oaAtomOffset[z3])->GetAt(0)][1] < -g_fBoxY/2.0) g_vaUnwrapArray[m->m_laSingleMolIndex[z2]][1] += g_fBoxY; if (GetTimeStep(0)->m_vaCoords[((CxIntArray*)sm->m_oaAtomOffset[z3])->GetAt(0)][2] - GetTimeStep(1)->m_vaCoords[((CxIntArray*)sm->m_oaAtomOffset[z3])->GetAt(0)][2] > g_fBoxZ/2.0) g_vaUnwrapArray[m->m_laSingleMolIndex[z2]][2] -= g_fBoxZ; if (GetTimeStep(0)->m_vaCoords[((CxIntArray*)sm->m_oaAtomOffset[z3])->GetAt(0)][2] - GetTimeStep(1)->m_vaCoords[((CxIntArray*)sm->m_oaAtomOffset[z3])->GetAt(0)][2] < -g_fBoxZ/2.0) g_vaUnwrapArray[m->m_laSingleMolIndex[z2]][2] += g_fBoxZ; // mprintf("\n%2d.%2d: %f, %f, %f",z,z2,g_vaUnwrapArray[m->m_laSingleMolIndex[z2]][0],g_vaUnwrapArray[m->m_laSingleMolIndex[z2]][1],g_vaUnwrapArray[m->m_laSingleMolIndex[z2]][2]); } } } } if (g_bKeepUnfoldedCoords) GetTimeStep(0)->m_vaCoords_Unfolded.CopyFrom(&GetTimeStep(0)->m_vaCoords); if (g_bFixedPlProj) g_pFixedPlProj->Process(GetTimeStep(0)); /******* Interface *********/ Interface_ProcessStep(GetTimeStep(0)); if (g_bMSD) { g_pT2Timestep = GetTimeStep(0); for (z0=0;z0m_pMSD->m_pAtomGroup->m_oaAtoms.GetSize();z2++) { for (z3=0;z3<((CxIntArray*)o->m_pMSD->m_pAtomGroup->m_oaAtoms[z2])->GetSize();z3++) { for (z4=0;z4<((CMolecule*)g_oaMolecules[o->m_iShowMol])->m_laSingleMolIndex.GetSize();z4++) { ti = ((CxIntArray*)((CSingleMolecule*)g_oaSingleMolecules[((CMolecule*)g_oaMolecules[o->m_iShowMol])->m_laSingleMolIndex[z4]])->m_oaAtomOffset[o->m_pMSD->m_pAtomGroup->m_baAtomType[z2]])->GetAt(((CxIntArray*)o->m_pMSD->m_pAtomGroup->m_oaAtoms[z2])->GetAt(z3)); ptfa = (CxDoubleArray*)o->m_pMSD->m_oaCache[ti2]; if (g_bPeriodic && (ptfa->GetSize() > 0)) { ti3 = ptfa->GetSize()-3; vec1[0] = ptfa->GetAt(ti3++); vec1[1] = ptfa->GetAt(ti3++); vec1[2] = ptfa->GetAt(ti3); tf = (g_pT2Timestep->m_vaCoords[ti]-vec1).GetLength(); if (tf > g_fMinPeriodic/2.0) eprintf("\nDiscontinuity in step %lu: %s[%d] %s%d moved %.2f pm. Can't compute MSD from wrapped trajectory - unwrap first.",g_iSteps,((CMolecule*)g_oaMolecules[g_waAtomMolIndex[ti]])->m_sName,g_laAtomSMLocalIndex[ti]+1,(const char*)((CAtom*)g_oaAtoms[g_waAtomRealElement[ti]])->m_sName,g_waAtomMolNumber[ti]+1,tf); } ptfa->Add(g_pT2Timestep->m_vaCoords[ti][0]); ptfa->Add(g_pT2Timestep->m_vaCoords[ti][1]); ptfa->Add(g_pT2Timestep->m_vaCoords[ti][2]); ti2++; } } } } else { for (z=0;zm_pMSD->m_iResolution/o->m_pMSD->m_iStride;z++) { g_pTempTimestep = GetTimeStep(z*o->m_pMSD->m_iStride); if (g_pTempTimestep == NULL) continue; for (z2=0;z2m_pMSD->m_pAtomGroup->m_oaAtoms.GetSize();z2++) { for (z3=0;z3<((CxIntArray*)o->m_pMSD->m_pAtomGroup->m_oaAtoms[z2])->GetSize();z3++) { for (z4=0;z4<((CMolecule*)g_oaMolecules[o->m_iShowMol])->m_laSingleMolIndex.GetSize();z4++) { ti = ((CxIntArray*)((CSingleMolecule*)g_oaSingleMolecules[((CMolecule*)g_oaMolecules[o->m_iShowMol])->m_laSingleMolIndex[z4]])->m_oaAtomOffset[o->m_pMSD->m_pAtomGroup->m_baAtomType[z2]])->GetAt(((CxIntArray*)o->m_pMSD->m_pAtomGroup->m_oaAtoms[z2])->GetAt(z3)); o->m_pMSD->m_pMSD->AddToBin_Index(z,(double)(pow2(g_pTempTimestep->m_vaCoords[ti][0]-g_pT2Timestep->m_vaCoords[ti][0])+pow2(g_pTempTimestep->m_vaCoords[ti][1]-g_pT2Timestep->m_vaCoords[ti][1])+pow2(g_pTempTimestep->m_vaCoords[ti][2]-g_pT2Timestep->m_vaCoords[ti][2]))); } } } } } } } // END IF MSD if (g_bSaveJustTraj) { g_pTempTimestep->CopyFrom(GetTimeStep(0)); if (g_bSaveJustCenter && (!g_bSaveCoordsUnchanged)) { vec0 = g_pTempTimestep->m_vaCoords[((CxIntArray*)((CSingleMolecule*)g_oaSingleMolecules[((CMolecule*)g_oaMolecules[g_iSaveJustMol])->m_laSingleMolIndex[g_iSaveJustSM]])->m_oaAtomOffset[g_iSaveJustAtomType])->GetAt(g_iSaveJustAtom)]; g_pTempTimestep->CenterPos(vec0); } if (g_bSaveTrajNoRot) { g_pTempTimestep->CenterCOM(); // mfprintf(g_fSaveJustTraj," %d\n\n",(int)g_iSaveGesAtoms*3); // for (z=0;zm_sName,g_pTempTimestep->m_vaCoords[z][0]/100.0,g_pTempTimestep->m_vaCoords[z][1]/100.0,g_pTempTimestep->m_vaCoords[z][2]/100.0); // g_pTempTimestep->Transform(tdmat2); g_pTempTimestep->Transform(tq2); // for (z=0;zm_sName,g_pTempTimestep->m_vaCoords[z][0]/100.0+10.0,g_pTempTimestep->m_vaCoords[z][1]/100.0,g_pTempTimestep->m_vaCoords[z][2]/100.0); if ((int)g_iSteps > g_iStride) { dvec1 = CxDVector3(0); for (z=0;zm_vaCoords[z] - rot_ts.m_vaCoords[z]); dvec4 = (g_pTempTimestep->m_vaCoords[z] + rot_ts.m_vaCoords[z]) / 2.0; // tf3 = dvec4.GetLength(); // tf2 = dvec2.GetLength(); // if (4*tf3*tf3 > 0.25*tf2*tf2) // { // dvec4 *= (1.0 + 1.0 - 0.5 / tf3 * sqrt(4*tf3*tf3 - 0.25*tf2*tf2) ); // mprintf("\n%.10g",1.0 + 1.0 - 0.5 / tf3 * sqrt(4*tf3*tf3 - 0.25*tf2*tf2)); // } dvec3 = CrossP(dvec4,dvec2); dvec1 += dvec3 * ((CAtom*)g_oaAtoms[g_waAtomRealElement[z]])->m_pElement->m_fMass; // mprintf(" %2d: ( %g, %g, %g ) x ( %g, %g, %g ) = ( %g, %g, %g ), m = %.2f\n",z,dvec2[0],dvec2[1],dvec2[2],rot_ts.m_vaCoords[z][0],rot_ts.m_vaCoords[z][1],rot_ts.m_vaCoords[z][2],dvec3[0],dvec3[1],dvec3[2],((CAtom*)g_oaAtoms[g_waAtomRealElement[z]])->m_pElement->m_fMass); } // mprintf("Drehimpuls: %g ( %g, %g, %g )\n",dvec1.GetLength(),dvec1[0],dvec1[1],dvec1[2]); dvec3 = dvec1; dvec3.Normalize(); // mprintf(" ( %g, %g, %g )\n",vec3[0],vec3[1],vec3[2]); tf = 0; for (z=0;zm_vaCoords[z] + rot_ts.m_vaCoords[z]) / 2.0; // tf3 = dvec4.GetLength(); // tf2 = dvec2.GetLength(); // dvec4 *= (1.0 + 1.0 - 0.5 / tf3 * sqrt(4*tf3*tf3 - 0.25*tf2*tf2) ); dvec0 = CrossP(dvec4,dvec3); // mprintf("# ( %g, %g, %g ) x ( %g, %g, %g ) = %g\n",g_pTempTimestep->m_vaCoords[z][0],g_pTempTimestep->m_vaCoords[z][1],g_pTempTimestep->m_vaCoords[z][2],vec3[0],vec3[1],vec3[2],vec0.GetLength()); tf += ((CAtom*)g_oaAtoms[g_waAtomRealElement[z]])->m_pElement->m_fMass * dvec0.GetLengthSqr(); // mprintf("\n %2d: ( %g, %g, %g ) x ( %g, %g, %g ) = ( %g, %g, %g ), m = %.2f",z,vec2[0],vec2[1],vec2[2],rot_ts.m_vaCoords[z][0],rot_ts.m_vaCoords[z][1],rot_ts.m_vaCoords[z][2],vec3[0],vec3[1],vec3[2],((CAtom*)g_oaAtoms[g_waAtomRealElement[z]])->m_pElement->m_fMass); } // mprintf(" Traegheitsmoment: %g\n",tf); dvec1 /= tf; // mprintf("Angular momentum vector: ( %g, %g, %g ) (l = %g)\n",dvec1[0],dvec1[1],dvec1[2],dvec1.GetLength()); // mprintf(" Winkelgeschw.: %g\n",dvec1.GetLength()); // dvec3 = dvec1; // dvec3.Normalize(); // mprintf(" Baue Matrix: ( %g | %g | %g ), %g\n",dvec3[0],dvec3[1],dvec3[2],-dvec1.GetLength()); // tdmat.RotMat(dvec3,-dvec1.GetLength()); tq.BuildRotation(dvec3,dvec1.GetLength()); // mprintf(" Die Matrix:\n"); // tdmat.Dump(); // tdmat2 = tdmat2 * tdmat; tq2 = tq2 * tq; if (fabs(tq2.GetLength()-1.0) > 0.000001) { eprintf("\nRenormalizing rotation quaternion.\n"); tq2.Normalize(); } // g_pTempTimestep->Transform(tdmat); g_pTempTimestep->Transform(tq); } rot_ts.CopyFrom(g_pTempTimestep); // for (z=0;zm_sName,g_pTempTimestep->m_vaCoords[z][0]/100.0+20.0,g_pTempTimestep->m_vaCoords[z][1]/100.0,g_pTempTimestep->m_vaCoords[z][2]/100.0); } else { if (g_bFold && (!g_bSaveCoordsUnchanged)) { if (g_bFoldAtomwise) g_pTempTimestep->FoldAtoms(); else g_pTempTimestep->FoldMolecules(); } } if (!g_bCenterZero && (!g_bSaveCoordsUnchanged) && g_bPeriodic) { if (g_bBoxNonOrtho) { vec1 = g_mBoxFromOrtho * CxDVector3(-0.5,-0.5,-0.5); g_pTempTimestep->CenterPos(vec1); } else { g_pTempTimestep->CenterPos(CxDVector3(-g_fBoxX/2,-g_fBoxY/2,-g_fBoxZ/2)); } } ti = g_iSaveGesAtoms; if (g_bUnwrapWannier) { g_pTempTimestep->ScanWannier(false); for (z3=0;z3m_pMolecule->m_laSingleMolIndex.GetSize();z6++) ti += ((CSingleMolecule*)g_oaSingleMolecules[atgr->m_pMolecule->m_laSingleMolIndex[z6]])->m_laWannier.GetSize(); } } if (g_bProcAddMesh) { if (g_bProcAddMeshX) ti += (g_iProcAddMeshGrid-1)*(g_iProcAddMeshGrid-1); if (g_bProcAddMeshY) ti += (g_iProcAddMeshGrid-1)*(g_iProcAddMeshGrid-1); if (g_bProcAddMeshZ) ti += (g_iProcAddMeshGrid-1)*(g_iProcAddMeshGrid-1); if (g_bProcAddMeshX || g_bProcAddMeshY) ti += (g_iProcAddMeshGrid-1); if (g_bProcAddMeshX || g_bProcAddMeshZ) ti += (g_iProcAddMeshGrid-1); if (g_bProcAddMeshY || g_bProcAddMeshZ) ti += (g_iProcAddMeshGrid-1); if (g_bProcAddMeshX || g_bProcAddMeshY || g_bProcAddMeshZ) ti++; } mfprintf(g_fSaveJustTraj," %d\n",ti); if (g_bProcCellComment) { if (g_bProcCellCommentAngles) mfprintf( g_fSaveJustTraj, " %.6f %.6f %.6f %.6f %.6f %.6f\n", g_fBoxX/100.0, g_fBoxY/100.0, g_fBoxZ/100.0, g_fBoxAngleA, g_fBoxAngleB, g_fBoxAngleC ); else mfprintf( g_fSaveJustTraj, " %.6f %.6f %.6f\n", g_fBoxX/100.0, g_fBoxY/100.0, g_fBoxZ/100.0 ); } else if (g_pTempTimestep->m_pComment != NULL) mfprintf(g_fSaveJustTraj,"%s\n",g_pTempTimestep->m_pComment); else mfprintf(g_fSaveJustTraj,"No Comment\n"); if (g_bBoxNonOrtho && g_bWriteOrtho) { for (z7=0;z7m_vaCoords[z7]; vec1 = g_mBoxToOrtho * vec0; while (vec1[0] < 0) vec1[0] += 1.0; while (vec1[0] >= 1.0) vec1[0] -= 1.0; while (vec1[1] < 0) vec1[1] += 1.0; while (vec1[1] >= 1.0) vec1[1] -= 1.0; while (vec1[2] < 0) vec1[2] += 1.0; while (vec1[2] >= 1.0) vec1[2] -= 1.0; vec1 *= g_fWriteOrthoFac; cp = ((CAtom*)g_oaAtoms[g_waAtomRealElement[z7]])->m_sName; if (g_bProcAlternativeLabels) if (((CxString*)g_oaProcAlternativeLabels[z7])->GetLength() != 0) cp = (const char*)*((CxString*)g_oaProcAlternativeLabels[z7]); mfprintf(g_fSaveJustTraj,"%-4s %12.8f %12.8f %12.8f\n",cp,vec1[0]/100.0,vec1[1]/100.0,vec1[2]/100.0); } } else { if (g_bWriteInputOrder) // This implies that all non-virtual atoms are to be written { for (z7=0;z7m_vaCoords[z7]; if (g_bUnwrap) { vec0 += g_vaUnwrapArray[m->m_laSingleMolIndex[z6]]; // mprintf("\nUnwrap: (%G|%G|%G) <-- (%G|%G|%G)",vec0[0],vec0[1],vec0[2],g_vaUnwrapArray[atgr->m_pMolecule->m_laSingleMolIndex[z6]][0],g_vaUnwrapArray[atgr->m_pMolecule->m_laSingleMolIndex[z6]][1],g_vaUnwrapArray[atgr->m_pMolecule->m_laSingleMolIndex[z6]][2]); } cp = ((CAtom*)g_oaAtoms[g_waAtomRealElement[z7]])->m_sName; if (g_bProcAlternativeLabels) if (((CxString*)g_oaProcAlternativeLabels[z7])->GetLength() != 0) cp = (const char*)*((CxString*)g_oaProcAlternativeLabels[z7]); mfprintf(g_fSaveJustTraj,"%-4s %12.8f %12.8f %12.8f",cp,vec0[0]/100.0,vec0[1]/100.0,vec0[2]/100.0); if (g_bProcWriteComments) mfprintf(g_fSaveJustTraj," # %s[%d] %s%d",m->m_sName,z6+1,(const char*)((CAtom*)g_oaAtoms[g_waAtomRealElement[z7]])->m_sName,z5+1); mfprintf(g_fSaveJustTraj,"\n"); } } else { if (g_bWriteAtomwise) { for (z7=0;z7m_pMolecule->m_laSingleMolIndex.GetSize();z6++) { for (z4=0;z4m_baAtomType.GetSize();z4++) { if (atgr->m_baRealAtomType[z4] != z7) continue; tla = (CxIntArray*)atgr->m_oaAtoms[z4]; for (z5=0;z5GetSize();z5++) { vec0 = g_pTempTimestep->m_vaCoords[((CxIntArray*)((CSingleMolecule*)g_oaSingleMolecules[atgr->m_pMolecule->m_laSingleMolIndex[z6]])->m_oaAtomOffset[atgr->m_baAtomType[z4]])->GetAt(tla->GetAt(z5))]; if (g_bUnwrap) { vec0 += g_vaUnwrapArray[atgr->m_pMolecule->m_laSingleMolIndex[z6]]; // mprintf("\nUnwrap: (%G|%G|%G) <-- (%G|%G|%G)",vec0[0],vec0[1],vec0[2],g_vaUnwrapArray[atgr->m_pMolecule->m_laSingleMolIndex[z6]][0],g_vaUnwrapArray[atgr->m_pMolecule->m_laSingleMolIndex[z6]][1],g_vaUnwrapArray[atgr->m_pMolecule->m_laSingleMolIndex[z6]][2]); } if (atgr->m_baRealAtomType[z4] == g_iVirtAtomType) { if (g_bSaveVirtAtoms) mfprintf(g_fSaveJustTraj,"%-4s %12.8f %12.8f %12.8f",((CVirtualAtom*)g_oaVirtualAtoms[atgr->m_pMolecule->m_laVirtualAtoms[tla->GetAt(z5)]])->m_sLabel,vec0[0]/100.0,vec0[1]/100.0,vec0[2]/100.0); } else { cp = ((CAtom*)g_oaAtoms[atgr->m_baRealAtomType[z4]])->m_sName; if (g_bProcAlternativeLabels) if (((CxString*)g_oaProcAlternativeLabels[((CxIntArray*)((CSingleMolecule*)g_oaSingleMolecules[atgr->m_pMolecule->m_laSingleMolIndex[z6]])->m_oaAtomOffset[atgr->m_baAtomType[z4]])->GetAt(tla->GetAt(z5))])->GetLength() != 0) cp = (const char*)*((CxString*)g_oaProcAlternativeLabels[((CxIntArray*)((CSingleMolecule*)g_oaSingleMolecules[atgr->m_pMolecule->m_laSingleMolIndex[z6]])->m_oaAtomOffset[atgr->m_baAtomType[z4]])->GetAt(tla->GetAt(z5))]); mfprintf(g_fSaveJustTraj,"%-4s %12.8f %12.8f %12.8f",cp,vec0[0]/100.0,vec0[1]/100.0,vec0[2]/100.0); } if (g_bProcWriteComments) mfprintf(g_fSaveJustTraj," # %s[%d] %s%d",atgr->m_pMolecule->m_sName,z6+1,(const char*)((CAtom*)g_oaAtoms[atgr->m_baRealAtomType[z4]])->m_sName,tla->GetAt(z5)+1); mfprintf(g_fSaveJustTraj,"\n"); } } } } } } else { for (z3=0;z3m_pMolecule->m_laSingleMolIndex.GetSize();z6++) { for (z4=0;z4m_baAtomType.GetSize();z4++) { tla = (CxIntArray*)atgr->m_oaAtoms[z4]; for (z5=0;z5GetSize();z5++) { vec0 = g_pTempTimestep->m_vaCoords[((CxIntArray*)((CSingleMolecule*)g_oaSingleMolecules[atgr->m_pMolecule->m_laSingleMolIndex[z6]])->m_oaAtomOffset[atgr->m_baAtomType[z4]])->GetAt(tla->GetAt(z5))]; if (g_bUnwrap) { vec0 += g_vaUnwrapArray[atgr->m_pMolecule->m_laSingleMolIndex[z6]]; // mprintf("\nUnwrap: (%G|%G|%G) <-- (%G|%G|%G)",vec0[0],vec0[1],vec0[2],g_vaUnwrapArray[atgr->m_pMolecule->m_laSingleMolIndex[z6]][0],g_vaUnwrapArray[atgr->m_pMolecule->m_laSingleMolIndex[z6]][1],g_vaUnwrapArray[atgr->m_pMolecule->m_laSingleMolIndex[z6]][2]); } if (atgr->m_baRealAtomType[z4] == g_iVirtAtomType) { if (g_bSaveVirtAtoms) mfprintf(g_fSaveJustTraj,"%-4s %12.8f %12.8f %12.8f",((CVirtualAtom*)g_oaVirtualAtoms[atgr->m_pMolecule->m_laVirtualAtoms[tla->GetAt(z5)]])->m_sLabel,vec0[0]/100.0,vec0[1]/100.0,vec0[2]/100.0); } else { cp = ((CAtom*)g_oaAtoms[atgr->m_baRealAtomType[z4]])->m_sName; if (g_bProcAlternativeLabels) if (((CxString*)g_oaProcAlternativeLabels[((CxIntArray*)((CSingleMolecule*)g_oaSingleMolecules[atgr->m_pMolecule->m_laSingleMolIndex[z6]])->m_oaAtomOffset[atgr->m_baAtomType[z4]])->GetAt(tla->GetAt(z5))])->GetLength() != 0) cp = (const char*)*((CxString*)g_oaProcAlternativeLabels[((CxIntArray*)((CSingleMolecule*)g_oaSingleMolecules[atgr->m_pMolecule->m_laSingleMolIndex[z6]])->m_oaAtomOffset[atgr->m_baAtomType[z4]])->GetAt(tla->GetAt(z5))]); mfprintf(g_fSaveJustTraj,"%-4s %12.8f %12.8f %12.8f",cp,vec0[0]/100.0,vec0[1]/100.0,vec0[2]/100.0); } if (g_bProcWriteComments) mfprintf(g_fSaveJustTraj," # %s[%d] %s%d",atgr->m_pMolecule->m_sName,z6+1,(const char*)((CAtom*)g_oaAtoms[atgr->m_baRealAtomType[z4]])->m_sName,tla->GetAt(z5)+1); mfprintf(g_fSaveJustTraj,"\n"); } } } } } } } if (g_bUnwrapWannier) { for (z3=0;z3m_pMolecule->m_laSingleMolIndex.GetSize();z6++) { for (z4=0;z4<((CSingleMolecule*)g_oaSingleMolecules[atgr->m_pMolecule->m_laSingleMolIndex[z6]])->m_laWannier.GetSize();z4++) { vec0 = g_pTempTimestep->m_vaCoords[((CSingleMolecule*)g_oaSingleMolecules[atgr->m_pMolecule->m_laSingleMolIndex[z6]])->m_laWannier[z4]]; if (g_bUnwrap) vec0 += g_vaUnwrapArray[atgr->m_pMolecule->m_laSingleMolIndex[z6]]; mfprintf(g_fSaveJustTraj,"X %12.8f %12.8f %12.8f\n",vec0[0]/100.0,vec0[1]/100.0,vec0[2]/100.0); } } } } if (g_bProcAddMesh) { if (g_bCenterZero) { tfx = -g_fBoxX/200.0; tfy = -g_fBoxY/200.0; tfz = -g_fBoxZ/200.0; } else { tfx = 0; tfy = 0; tfz = 0; } if (g_bProcAddMeshX || g_bProcAddMeshY || g_bProcAddMeshZ) mfprintf(g_fSaveJustTraj,"%-4s %12.8f %12.8f %12.8f\n",(const char*)g_sProcAddMeshLabel,tfx+MeshRandom(),tfy+MeshRandom(),tfz+MeshRandom()); if (g_bProcAddMeshX || g_bProcAddMeshY) for (z3=1;z3= g_iProcSplitLength) { procsplitc = 0; procspliti++; fclose(g_fSaveJustTraj); buf2.sprintf("%s_out.%03d.xyz",(const char*)procsplitbuf,procspliti+1); g_fSaveJustTraj = OpenFileWrite(buf2,true); } } } // END IF g_bSaveJustTraj if (g_bBondACF) { g_pTempTimestep->CopyFrom(GetTimeStep(0)); for (z2=0;z2m_oaBonds.GetSize();z3++) { bond = (CMolBond*)sm->m_oaBonds[z3]; bond->m_faData.Add(VecDist(g_pTempTimestep->m_vaCoords[bond->m_iAtomOffset[0]],g_pTempTimestep->m_vaCoords[bond->m_iAtomOffset[1]])); } } } if (g_bAggregation || g_bNbExchange) { g_pTempTimestep->CopyFrom(GetTimeStep(0)); for (z0=0;z0m_pDACF->m_oaSubDACFs.GetSize();zs++) { dacfsub = (CDACFSub*)o->m_pDACF->m_oaSubDACFs[zs]; for (z2=0;z2<((CMolecule*)g_oaMolecules[o->m_pDACF->m_iSecondMol])->m_laSingleMolIndex.GetSize();z2++) dacfsub->m_pCondition->m_iPassCounter[z2] = 0; } } for (z0=0;z0m_pDACF->m_iFirstMol])->m_laSingleMolIndex.GetSize();z2++) { smfix = (CSingleMolecule*)g_oaSingleMolecules[((CMolecule*)g_oaMolecules[o->m_pDACF->m_iFirstMol])->m_laSingleMolIndex[z2]]; o->m_pDACF->m_pCondition->PreScanNeighborhoodAllOM(g_pTempTimestep,smfix); for (zs=0;zsm_pDACF->m_oaSubDACFs.GetSize();zs++) { dacfsub = (CDACFSub*)o->m_pDACF->m_oaSubDACFs[zs]; dacfsub->m_pCondition->CopyResults(o->m_pDACF->m_pCondition); dacfsub->m_pCondition->m_bAnyPassed = false; dacfsub->m_pCondition->m_iTempPassed = 0; dacfsub->m_pCondition->ReScan(smfix); if (dacfsub->m_pCondition->m_bAnyPassed) dacfsub->m_pCondition->m_iRMPassCounter[z2]++; if (g_bDACF) o->m_pDACF->UpdateDACFSub(z2,g_pTempTimestep,dacfsub); if (g_bNbExchange) o->m_pDACF->UpdateNbEx(z2,dacfsub); } // END FOR ZS } // END FOR Z2 } // END FOR Z0 for (z0=0;z0m_pDACF->m_oaSubDACFs.GetSize();zs++) { dacfsub = (CDACFSub*)o->m_pDACF->m_oaSubDACFs[zs]; for (z2=0;z2<((CMolecule*)g_oaMolecules[o->m_pDACF->m_iSecondMol])->m_laSingleMolIndex.GetSize();z2++) if (dacfsub->m_pCondition->m_iPassCounter[z2] != 0) dacfsub->m_pCondition->m_iOMPassCounter[z2]++; } } } // END IF AGGREGATION OR NBEX if (g_bDens) { g_pTempTimestep->CopyFrom(GetTimeStep(0)); for (z0=0;z0m_iShowMol]; for (z3=0;z3m_laSingleMolIndex.GetSize();z3++) { if (g_bRegionAnalysis) if ((!o->m_iaRMRegions.Contains(0)) && (!o->m_iaRMRegions.Contains(g_iaSMRegion[m->m_laSingleMolIndex[z3]]))) continue; sm = (CSingleMolecule*)g_oaSingleMolecules[m->m_laSingleMolIndex[z3]]; ti = ((CxIntArray*)sm->m_oaAtomOffset[o->m_pDensityDF->m_iCenterAtomType])->GetAt(o->m_pDensityDF->m_iCenterAtom); vec0 = g_pTempTimestep->m_vaCoords[ti]; g_pTempTimestep->CenterPos(vec0); g_pTempTimestep->FoldAtoms(); for (z4=0;z4m_pDensityDF->m_pDensityMolSelect[z4]) continue; m2 = (CMolecule*)g_oaMolecules[z4]; ag = o->m_pDensityDF->m_pDensityMolAG[z4]; for (z5=0;z5m_laSingleMolIndex.GetSize();z5++) { if (g_bRegionAnalysis) if ((!o->m_iaOM1Regions.Contains(0)) && (!o->m_iaOM1Regions.Contains(g_iaSMRegion[m2->m_laSingleMolIndex[z5]]))) continue; sm2 = (CSingleMolecule*)g_oaSingleMolecules[m2->m_laSingleMolIndex[z5]]; for (z6=0;z6m_baAtomType.GetSize();z6++) { if (ag->m_baRealAtomType[z6] == g_iVirtAtomType) continue; if (o->m_pDensityDF->m_bDensityMass) { tf2 = ((CAtom*)g_oaAtoms[ag->m_baRealAtomType[z6]])->m_pElement->m_fMass; for (z7=0;z7<((CxIntArray*)ag->m_oaAtoms[z6])->GetSize();z7++) { tf = g_pTempTimestep->m_vaCoords[((CxIntArray*)sm2->m_oaAtomOffset[ag->m_baAtomType[z6]])->GetAt(((CxIntArray*)ag->m_oaAtoms[z6])->GetAt(z7))].GetLength(); o->m_pDensityDF->m_pDensDF->AddToBin(tf,tf2); } } else { for (z7=0;z7<((CxIntArray*)ag->m_oaAtoms[z6])->GetSize();z7++) { tf = g_pTempTimestep->m_vaCoords[((CxIntArray*)sm2->m_oaAtomOffset[ag->m_baAtomType[z6]])->GetAt(((CxIntArray*)ag->m_oaAtoms[z6])->GetAt(z7))].GetLength(); o->m_pDensityDF->m_pDensDF->AddToBin(tf); } } } } } } } } // END IF g_bDens if (g_bRDyn || g_bIRSpec) { g_pTempTimestep->CopyFrom(GetTimeStep(0)); for (z6=0;z6m_pIRSpec; else trdyn = o->m_pRDyn; ti = 0; for (z3=0;z3m_iShowMolCount;z3++) // Alle anderen Molekuele durchgehen { sm = (CSingleMolecule*)g_oaSingleMolecules[((CMolecule*)g_oaMolecules[o->m_iShowMol])->m_laSingleMolIndex[z3]]; if (trdyn->m_iVecType == 0) { trdyn->BuildAtomList(sm,&templa); for (z4=0;z4m_bOrtho) { vec0 = g_pTempTimestep->m_vaCoords[templa[z4]]; vec2 = g_pTempTimestep->m_vaCoords[templa[z4+1]]; vec3 = g_pTempTimestep->m_vaCoords[templa[z4+2]]; vec1 = CrossP(vec2-vec0,vec3-vec0); } else { vec0 = g_pTempTimestep->m_vaCoords[templa[z4]]; vec2 = g_pTempTimestep->m_vaCoords[templa[z4+1]]; vec1 = vec2-vec0; } vec1.Normalize(); if (g_bRDynCacheMode) { ((CxDoubleArray*)trdyn->m_oaCache[ti])->Add(vec1[0]); ((CxDoubleArray*)trdyn->m_oaCache[ti])->Add(vec1[1]); ((CxDoubleArray*)trdyn->m_oaCache[ti])->Add(vec1[2]); ti++; } else { for (z=0;zm_iDepth/trdyn->m_iStride;z++) { g_pT2Timestep = GetTimeStep(z*trdyn->m_iStride); if (g_pT2Timestep == NULL) continue; if (trdyn->m_bOrtho) { vec4 = g_pT2Timestep->m_vaCoords[templa[z4]]; vec3 = g_pT2Timestep->m_vaCoords[templa[z4+1]]; vec5 = g_pT2Timestep->m_vaCoords[templa[z4+2]]; vec2 = CrossP(vec3-vec4,vec5-vec4); } else { vec4 = g_pT2Timestep->m_vaCoords[templa[z4]]; vec3 = g_pT2Timestep->m_vaCoords[templa[z4+1]]; vec2 = vec3-vec4; } vec2.Normalize(); trdyn->m_pRDyn->AddToBin_Int(z,DotP(vec1,vec2)); trdyn->m_pCount[z]++; } } } } else if (trdyn->m_iVecType == 1) { vec1 = sm->m_vDipole; ((CxDoubleArray*)trdyn->m_oaCache[ti])->Add(vec1[0]); ((CxDoubleArray*)trdyn->m_oaCache[ti])->Add(vec1[1]); ((CxDoubleArray*)trdyn->m_oaCache[ti])->Add(vec1[2]); // if (z3 == 0) // mfprintf(fff,"%f, %f, %f\n",vec1[0],vec1[1],vec1[2]); ti++; } // END VECTYPE } } } // END IF RDYN if (g_bVACF) { g_pT2Timestep = GetTimeStep(0); // mprintf("\nStep=%d, adding.",g_iSteps); if (g_bGlobalVACF) { if (g_bVACFCacheMode) { ti = 0; for (z2=0;z2m_bExcludeR0 && (g_waAtomRealElement[z2] > 1000)) continue; // mprintf("Global: Step %d, Atom %d: %.4ff | %.4ff | %.4ff\n",g_iSteps,z2+1,g_pT2Timestep->m_vaVelocities[z2][0],g_pT2Timestep->m_vaVelocities[z2][1],g_pT2Timestep->m_vaVelocities[z2][2]); ((CxDoubleArray*)g_pGlobalVACF->m_oaCache[ti])->Add(g_pT2Timestep->m_vaVelocities[z2][0]); ((CxDoubleArray*)g_pGlobalVACF->m_oaCache[ti])->Add(g_pT2Timestep->m_vaVelocities[z2][1]); ((CxDoubleArray*)g_pGlobalVACF->m_oaCache[ti])->Add(g_pT2Timestep->m_vaVelocities[z2][2]); ti++; } } else { for (z=0;zm_iSize;z++) { g_pTempTimestep = GetTimeStep(z); if (g_pTempTimestep == NULL) continue; if (g_pTempTimestep->m_vaVelocities.GetSize() == 0) continue; pd = &g_pGlobalVACF->m_pData[z]; g_pGlobalVACF->m_pCounter[z] += g_iGesAtomCount; for (z2=0;z2m_vaVelocities[z2],g_pT2Timestep->m_vaVelocities[z2]); } } } for (z6=0;z6m_iShowMolCount;z3++) // Alle anderen Molekuele durchgehen { sm = (CSingleMolecule*)g_oaSingleMolecules[((CMolecule*)g_oaMolecules[o->m_iShowMol])->m_laSingleMolIndex[z3]]; o->m_pVACF->BuildAtomList(sm,&templa); for (z4=0;z4m_pVACF->m_oaCache[z3*o->m_pVACF->m_iShowAtomGes+z4])->Add(g_pT2Timestep->m_vaVelocities[ti][0]); ((CxDoubleArray*)o->m_pVACF->m_oaCache[z3*o->m_pVACF->m_iShowAtomGes+z4])->Add(g_pT2Timestep->m_vaVelocities[ti][1]); ((CxDoubleArray*)o->m_pVACF->m_oaCache[z3*o->m_pVACF->m_iShowAtomGes+z4])->Add(g_pT2Timestep->m_vaVelocities[ti][2]); // mprintf("%d*%d+%d=%d\n",z3,o->m_pVACF->m_iShowAtomGes,z4,z3*o->m_pVACF->m_iShowAtomGes+z4); // mprintf("Lokal: Step %d, Atom %d: %.4ff | %.4ff | %.4ff\n",g_iSteps,ti+1,g_pT2Timestep->m_vaVelocities[ti][0],g_pT2Timestep->m_vaVelocities[ti][1],g_pT2Timestep->m_vaVelocities[ti][2]); // mprintf("Step %d: Obs %d, Mol %d, Atom %d: Index %d.\n",g_iStepHistory,z6+1,z3+1,z4+1,ti+1); } else { for (z5=0;z5m_pVACF->m_iSize;z5++) { o->m_pVACF->m_pCounter[z5]++; g_pTempTimestep = GetTimeStep(z5); if (g_pTempTimestep == NULL) continue; if (g_pTempTimestep->m_vaVelocities.GetSize() == 0) continue; o->m_pVACF->m_pData[z5] += DotP(g_pTempTimestep->m_vaVelocities[templa[z4]],g_pT2Timestep->m_vaVelocities[templa[z4]]); } } } } } } // END IF VACF if (g_bIRSpec && g_bGlobalIR) { for (z3=0;z3m_vDipole; ((CxDoubleArray*)g_pGlobalIR->m_oaCache[z3])->Add(vec1[0]); ((CxDoubleArray*)g_pGlobalIR->m_oaCache[z3])->Add(vec1[1]); ((CxDoubleArray*)g_pGlobalIR->m_oaCache[z3])->Add(vec1[2]); } } // END IF g_bGlobalIR if (g_bNbAnalysis) { g_pTempTimestep->CopyFrom(GetTimeStep(0)); for (z2=0;z2<((CMolecule*)g_oaMolecules[g_iFixMol])->m_laSingleMolIndex.GetSize();z2++) { smfix = (CSingleMolecule*)g_oaSingleMolecules[((CMolecule*)g_oaMolecules[g_iFixMol])->m_laSingleMolIndex[z2]]; for (z6=0;z6m_pNbAnalysis->m_pNbSearch->ScanAllOM(smfix,g_pTempTimestep); o->m_pNbAnalysis->AnalyzeStep(); } } } if (g_bNbExchange) { } if (g_bOrder) g_pOrderEngine->ProcessStep(GetTimeStep(0)); // if (g_bVoro) { g_pTempTimestep->CopyFrom(GetTimeStep(0)); if (g_pVoroWrapper->m_bVoroStat) { g_pTempTimestep->FoldAtomsPositive(); g_pVoroWrapper->Build(g_pTempTimestep); } if (g_pVoroWrapper->m_bSurfCover) g_pVoroWrapper->ProcessSurfCover(g_pTempTimestep); } if (g_bDomA) { g_pTempTimestep->CopyFrom(GetTimeStep(0)); g_pTempTimestep->FoldAtomsPositive(); g_pDomainEngine->ProcessStep(g_pTempTimestep); } if (g_bVDF && (g_iFixMol == -1)) { g_pTempTimestep->CopyFrom(GetTimeStep(0)); for (z6=0;z6m_iShowMolCount;z3++) // Alle anderen Molekuele durchgehen { sm = (CSingleMolecule*)g_oaSingleMolecules[((CMolecule*)g_oaMolecules[o->m_iShowMol])->m_laSingleMolIndex[z3]]; o->m_pVDF[0]->BuildAtomList(NULL,sm,&templa); for (z4=0;z4m_pVDF[0]->m_pVDF->AddToBin(g_pTempTimestep->m_vaVelocities[templa[z4]].GetLength()); if (o->m_pVDF[0]->m_bSplitCart) { for (z4=0;z4m_pVDF[0]->m_pVDFSplit[0]->AddToBin( fabs(g_pTempTimestep->m_vaVelocities[templa[z4]][0]) ); o->m_pVDF[0]->m_pVDFSplit[1]->AddToBin( fabs(g_pTempTimestep->m_vaVelocities[templa[z4]][1]) ); o->m_pVDF[0]->m_pVDFSplit[2]->AddToBin( fabs(g_pTempTimestep->m_vaVelocities[templa[z4]][2]) ); o->m_pVDF[0]->m_pVDFSplit[3]->AddToBin( sqrt(pow2(g_pTempTimestep->m_vaVelocities[templa[z4]][0])+pow2(g_pTempTimestep->m_vaVelocities[templa[z4]][1])) ); o->m_pVDF[0]->m_pVDFSplit[4]->AddToBin( sqrt(pow2(g_pTempTimestep->m_vaVelocities[templa[z4]][0])+pow2(g_pTempTimestep->m_vaVelocities[templa[z4]][2])) ); o->m_pVDF[0]->m_pVDFSplit[5]->AddToBin( sqrt(pow2(g_pTempTimestep->m_vaVelocities[templa[z4]][1])+pow2(g_pTempTimestep->m_vaVelocities[templa[z4]][2])) ); } } } } } if ((!g_bCDF) && (!g_bRDF) && (!g_bSDF) && (!g_bPlProj) && (!g_bPlDF) && (!g_bLiDF) && (!g_bADF) && (!g_bDDF) && (!g_bVDF) && (!g_bDipDF) && (!g_bCutCluster) && (!g_bSaveRefEnv) && (!g_bVHDF) && (!g_bRevSDF) && (!g_bCond)) goto _endstep; // tfr = 9999.0; if (g_iFixMol == -1) goto _norefmol; for (z6=0;z6m_pConditions != NULL) for (z2=0;z2<((CMolecule*)g_oaMolecules[o->m_iShowMol])->m_laSingleMolIndex.GetSize();z2++) o->m_pConditions->m_iPassCounter[z2] = 0; if (o->m_pConditionsOM2 != NULL) for (z2=0;z2<((CMolecule*)g_oaMolecules[o->m_iShowMol])->m_laSingleMolIndex.GetSize();z2++) o->m_pConditionsOM2->m_iPassCounter[z2] = 0; if (g_bCond) { if (o->m_bCondDevelopment) { for (z2=0;z2<=o->m_iCondDevelopmentMax;z2++) o->m_iaCondDevelopmentCounter[z2] = 0; o->m_iCondDevelopmentAvg = 0; } } } // Jedes Festhalte-Molekuel mal im Ursprung liegen lassen for (z2=0;z2<((CMolecule*)g_oaMolecules[g_iFixMol])->m_laSingleMolIndex.GetSize();z2++) { if (g_bDoubleBox && (z2 >= ((CMolecule*)g_oaMolecules[g_iFixMol])->m_laSingleMolIndex.GetSize()/g_iDoubleBoxFactor)) continue; smfix = (CSingleMolecule*)g_oaSingleMolecules[((CMolecule*)g_oaMolecules[g_iFixMol])->m_laSingleMolIndex[z2]]; if (g_bCutCluster) { if (g_iClusterPos >= g_iClusterCount) break; if (((int)g_iSteps/g_iStride) >= g_iClusterSteps) break; if (g_iaClusterMol[g_iClusterPos] != z2) continue; if (g_iaClusterSteps[g_iClusterPos] != ((int)g_iSteps/g_iStride)) break; g_iClusterPos++; } g_pTempTimestep->CopyFrom(GetTimeStep(0)); // Zentrieren/Falten der ganzen Box nur noch noetig bei den folgenden Analysen if (g_bPlProj || g_bSDF || g_bRevSDF || g_bCutCluster || g_bSaveRefEnv || g_bSaveJustTraj || g_bMiddleAvg) { vecc = g_pTempTimestep->m_vaCoords[((CxIntArray*)smfix->m_oaAtomOffset[g_iFixAtomType[0]])->GetAt(g_iFixAtom[0])]; if ((g_bCutCluster && !g_bRefEnvCenter) || (g_bSaveRefEnv && (!g_bRefEnvCenter) && (z2==g_iSaveRefMol))) { if (g_bFold) { g_pTempTimestep->CenterPos(vecc); if (g_bFoldAtomwise) g_pTempTimestep->FoldAtoms(); else g_pTempTimestep->FoldMolecules(); vec2 = -1.0 * vecc; g_pTempTimestep->CenterPos(vec2); } if (g_bCutCluster || (g_iNbhMode == 2)) { g_pNbSet->Reset(); if (g_bCutCluster) g_pNbSet->ResetAlwaysTrue(); g_pNbSet->Scan(smfix,g_pTempTimestep); if (g_bSaveRefWithEnv) g_pNbSet->AddMolecule(g_iFixMol,z2); } g_pTempTimestep->WriteTimestepNb(g_fRefEnv,g_pNbSet); if (g_bTDO) { if (g_laTDOSteps.Contains(g_iSteps-1)) { // sprintf(buf,"tdo_%s_%d_%06lu%s.xyz",((CMolecule*)g_oaMolecules[g_iFixMol])->m_sName,g_iSaveRefMol+1,g_iSteps-1,multibuf); buf.sprintf("tdo_%s_%d_%06lu%s.xyz",((CMolecule*)g_oaMolecules[g_iFixMol])->m_sName,g_iSaveRefMol+1,g_iSteps-1,multibuf); mprintf("\nSaving TDO step as %s.\n",(const char*)buf); tfi = OpenFileWrite(buf,true); g_pTempTimestep->WriteTimestepNb(tfi,g_pNbSet); fclose(tfi); } } } // Legt vecc genau in den Ursprung des Koordinatensystems g_pTempTimestep->CenterPos(vecc); if ((g_bCutCluster && g_bRefEnvCenter && (!g_bRefEnvFix)) || (g_bSaveRefEnv && g_bRefEnvCenter && (!g_bRefEnvFix) && (z2==g_iSaveRefMol))) { if (g_bFold) { if (g_bFoldAtomwise) g_pTempTimestep->FoldAtoms(); else g_pTempTimestep->FoldMolecules(); } if (g_bCutCluster || (g_iNbhMode == 2)) { g_pNbSet->Reset(); if (g_bCutCluster) g_pNbSet->ResetAlwaysTrue(); g_pNbSet->Scan(smfix,g_pTempTimestep); if (g_bSaveRefWithEnv) g_pNbSet->AddMolecule(g_iFixMol,z2); } if (!g_bCenterZero && g_bPeriodic) g_pTempTimestep->CenterPos(CxDVector3(-g_fBoxX/2,-g_fBoxY/2,-g_fBoxZ/2)); g_pTempTimestep->WriteTimestepNb(g_fRefEnv,g_pNbSet,((CMolecule*)g_oaMolecules[g_iFixMol])->m_laSingleMolIndex[z2]); if (g_bTDO) { if (g_laTDOSteps.Contains(g_iSteps-1)) { // sprintf(buf,"tdo_%s_%d_%06lu%s.xyz",((CMolecule*)g_oaMolecules[g_iFixMol])->m_sName,g_iSaveRefMol+1,g_iSteps-1,multibuf); buf.sprintf("tdo_%s_%d_%06lu%s.xyz",((CMolecule*)g_oaMolecules[g_iFixMol])->m_sName,g_iSaveRefMol+1,g_iSteps-1,multibuf); mprintf("\nSaving TDO step as %s.\n",(const char*)buf); tfi = OpenFileWrite(buf,true); g_pTempTimestep->WriteTimestepNb(tfi,g_pNbSet); fclose(tfi); } } } /* Fixed very bad SDF bug: Moved this block before the application of the transformation matrix */ if (g_bFold) { if (g_bFoldAtomwise) g_pTempTimestep->FoldAtoms(); else g_pTempTimestep->FoldMolecules(); } /* End "this block" */ if (g_bPlProj || g_bSDF || g_bAvg || ((g_bSaveRefEnv || g_bCutCluster) && g_bRefEnvCenter && g_bRefEnvFix)) // Wir brauchen ein neues Koordinatensystem und eine Drehmatrix { vec2 = g_pTempTimestep->m_vaCoords[((CxIntArray*)smfix->m_oaAtomOffset[g_iFixAtomType[1]])->GetAt(g_iFixAtom[1])]; vec3 = g_pTempTimestep->m_vaCoords[((CxIntArray*)smfix->m_oaAtomOffset[g_iFixAtomType[2]])->GetAt(g_iFixAtom[2])]; mat.MatUltra(vec2,vec3); // Dies erstellt uns die Drehmatrix if (g_bSDFVoro) dmat.MatUltra((CxDVector3)vec2,(CxDVector3)vec3); // Nochmal in Double Precision g_pTempTimestep->Transform(mat); if (g_bPlProj) { for (z6=0;z6m_pPlProj->m_bAverageAtomPos) { o->m_pPlProj->m_iAverageCounter++; ti = 0; for (z3=0;z3m_pPlProj->m_oDrawAtoms.m_oaAtoms.GetSize();z3++) { for (z4=0;z4<((CxIntArray*)o->m_pPlProj->m_oDrawAtoms.m_oaAtoms[z3])->GetSize();z4++) { o->m_pPlProj->m_vaAtomPos[ti] += g_pTempTimestep->m_vaCoords[((CxIntArray*)smfix->m_oaAtomOffset[o->m_pPlProj->m_oDrawAtoms.m_baAtomType[z3]])->GetAt(((CxIntArray*)o->m_pPlProj->m_oDrawAtoms.m_oaAtoms[z3])->GetAt(z4))]; ti++; } } } } } } if ((g_bCutCluster && g_bRefEnvCenter && g_bRefEnvFix) || (g_bSaveRefEnv && g_bRefEnvCenter && g_bRefEnvFix && (z2==g_iSaveRefMol))) { if (g_bCutCluster || (g_iNbhMode == 2)) { g_pNbSet->Reset(); if (g_bCutCluster) g_pNbSet->ResetAlwaysTrue(); g_pNbSet->Scan(smfix,g_pTempTimestep); if (g_bSaveRefWithEnv) g_pNbSet->AddMolecule(g_iFixMol,z2); } if (!g_bCenterZero && g_bPeriodic) g_pTempTimestep->CenterPos(CxDVector3(-g_fBoxX/2,-g_fBoxY/2,-g_fBoxZ/2)); g_pTempTimestep->WriteTimestepNb(g_fRefEnv,g_pNbSet,((CMolecule*)g_oaMolecules[g_iFixMol])->m_laSingleMolIndex[z2]); if (g_bTDO) { if (g_laTDOSteps.Contains(g_iSteps-1)) { // sprintf(buf,"tdo_%s_%d_%06lu%s.xyz",((CMolecule*)g_oaMolecules[g_iFixMol])->m_sName,g_iSaveRefMol+1,g_iSteps-1,multibuf); buf.sprintf("tdo_%s_%d_%06lu%s.xyz",((CMolecule*)g_oaMolecules[g_iFixMol])->m_sName,g_iSaveRefMol+1,g_iSteps-1,multibuf); mprintf("\nSaving TDO step as %s.\n",(const char*)buf); tfi = OpenFileWrite(buf,true); g_pTempTimestep->WriteTimestepNb(tfi,g_pNbSet); fclose(tfi); } } } } // END IF SDF, RevEnv, ... /***************************************************************************************************************************/ if (g_bSDF && g_bSDFMap) { for (z3=0;z3Process(z2,g_pTempTimestep); } } if (g_bPlProj || g_bDipDF || g_bRevSDF || g_bVHDF || g_bRDF || g_bPlDF || g_bLiDF || g_bSDF || g_bADF || g_bDDF || g_bVDF || g_bCond) { for (z6=0;z6m_laSingleMolIndex[z2]],o->m_iaRMRegions[0]); if (g_bRegionAnalysis) if ((!o->m_iaRMRegions.Contains(0)) && (!o->m_iaRMRegions.Contains(g_iaSMRegion[((CMolecule*)g_oaMolecules[g_iFixMol])->m_laSingleMolIndex[z2]]))) continue; // mprintf("\n ...RM ist in Region."); ti2 = o->m_waSaveRefList.GetPosition((unsigned short)z2); if (o->m_bObsCertain) { // mprintf("\n RefList: "); // for (z7=0;z7m_waObsRefList.GetSize();z7++) // mprintf("%d, ",o->m_waObsRefList[z7]); if (!o->m_waObsRefList.Contains((unsigned short)z2)) continue; // mprintf("\n ...RM ist auch in RefList."); tic_r = o->m_waObsRefList.GetPosition((unsigned short)z2); } if (g_bUseVelocities) { tempvel.CopyFrom(&g_pTempTimestep->m_vaVelocities); if (o->m_bVelocityRelToRef) { vecv = g_pTempTimestep->m_vaVelocities[((CxIntArray*)smfix->m_oaAtomOffset[g_iFixAtomType[0]])->GetAt(g_iFixAtom[0])]; for (z3=0;z3m_bTimeDev) && (ti2 != -1)) { if (o->m_bSaveSeparateFiles) mfprintf(o->m_pCDF->m_fTimeDev[ti2],"%d",(int)g_iSteps); else if (ti2 == 0) mfprintf(o->m_pCDF->m_fTimeDev[0],"%d",(int)g_iSteps); } for (zr=0;zrm_pRDF[zr] != NULL)) { for (z3=0;z3<((o->m_bSecondShowMol && (zr == 1))?o->m_iShowMol2Count:o->m_iShowMolCount);z3++) o->m_pRDF[zr]->m_faData[z3].RemoveAll_KeepSize(); if (o->m_bBinOnlyPassedAtoms || o->m_bBinOnlyNotPassedAtoms) for (z3=0;z3<((o->m_bSecondShowMol && (zr == 1))?o->m_iShowMol2Count:o->m_iShowMolCount);z3++) o->m_pRDF[zr]->m_baDataEnabled[z3].RemoveAll_KeepSize(); if ((o->m_bTimeDev) && (ti2 != -1) && (!g_bDeriv || (g_iSteps > 2))) { if (o->m_bSaveSeparateFiles) mfprintf(o->m_pRDF[zr]->m_fDist[ti2],"%d",(int)g_iSteps); else if (ti2 == 0) mfprintf(o->m_pRDF[zr]->m_fDist[0],"%d",(int)g_iSteps); } } if (g_bADF && (o->m_pADF[zr] != NULL)) { for (z3=0;z3<((o->m_bSecondShowMol && (zr == 1))?o->m_iShowMol2Count:o->m_iShowMolCount);z3++) o->m_pADF[zr]->m_faData[z3].RemoveAll_KeepSize(); if (o->m_bBinOnlyPassedAtoms || o->m_bBinOnlyNotPassedAtoms) for (z3=0;z3<((o->m_bSecondShowMol && (zr == 1))?o->m_iShowMol2Count:o->m_iShowMolCount);z3++) o->m_pADF[zr]->m_baDataEnabled[z3].RemoveAll_KeepSize(); if ((o->m_bTimeDev) && (ti2 != -1) && (!g_bDeriv || (g_iSteps > 2))) { if (o->m_bSaveSeparateFiles) mfprintf(o->m_pADF[zr]->m_fAngle[ti2],"%d",(int)g_iSteps); else if (ti2 == 0) mfprintf(o->m_pADF[zr]->m_fAngle[0],"%d",(int)g_iSteps); } } if (g_bDDF && (o->m_pDDF[zr] != NULL)) { for (z3=0;z3<((o->m_bSecondShowMol && (zr == 1))?o->m_iShowMol2Count:o->m_iShowMolCount);z3++) o->m_pDDF[zr]->m_faData[z3].RemoveAll_KeepSize(); if (o->m_bBinOnlyPassedAtoms || o->m_bBinOnlyNotPassedAtoms) for (z3=0;z3<((o->m_bSecondShowMol && (zr == 1))?o->m_iShowMol2Count:o->m_iShowMolCount);z3++) o->m_pDDF[zr]->m_baDataEnabled[z3].RemoveAll_KeepSize(); if ((o->m_bTimeDev) && (ti2 != -1) && (!g_bDeriv || (g_iSteps > 2))) { if (o->m_bSaveSeparateFiles) mfprintf(o->m_pDDF[zr]->m_fAngle[ti2],"%d",(int)g_iSteps); else if (ti2 == 0) mfprintf(o->m_pDDF[zr]->m_fAngle[0],"%d",(int)g_iSteps); } } if (g_bPlDF && (o->m_pPlDF[zr] != NULL)) { for (z3=0;z3<((o->m_bSecondShowMol && (zr == 1))?o->m_iShowMol2Count:o->m_iShowMolCount);z3++) o->m_pPlDF[zr]->m_faData[z3].RemoveAll_KeepSize(); if (o->m_bBinOnlyPassedAtoms || o->m_bBinOnlyNotPassedAtoms) for (z3=0;z3<((o->m_bSecondShowMol && (zr == 1))?o->m_iShowMol2Count:o->m_iShowMolCount);z3++) o->m_pPlDF[zr]->m_baDataEnabled[z3].RemoveAll_KeepSize(); /* if ((o->m_bTimeDev) && (ti2 != -1) && (!g_bDeriv || (g_iSteps > 2))) { if (o->m_bSaveSeparateFiles) mfprintf(o->m_pPlDF[zr]->m_fAngle[ti2],"%d",(int)g_iSteps); else if (ti2 == 0) mfprintf(o->m_pDDF[zr]->m_fAngle[0],"%d",(int)g_iSteps); }*/ } if (g_bLiDF && (o->m_pLiDF[zr] != NULL)) { for (z3=0;z3<((o->m_bSecondShowMol && (zr == 1))?o->m_iShowMol2Count:o->m_iShowMolCount);z3++) o->m_pLiDF[zr]->m_faData[z3].RemoveAll_KeepSize(); if (o->m_bBinOnlyPassedAtoms || o->m_bBinOnlyNotPassedAtoms) for (z3=0;z3<((o->m_bSecondShowMol && (zr == 1))?o->m_iShowMol2Count:o->m_iShowMolCount);z3++) o->m_pLiDF[zr]->m_baDataEnabled[z3].RemoveAll_KeepSize(); /* if ((o->m_bTimeDev) && (ti2 != -1) && (!g_bDeriv || (g_iSteps > 2))) { if (o->m_bSaveSeparateFiles) mfprintf(o->m_pPlDF[zr]->m_fAngle[ti2],"%d",(int)g_iSteps); else if (ti2 == 0) mfprintf(o->m_pDDF[zr]->m_fAngle[0],"%d",(int)g_iSteps); }*/ } if (g_bDipDF && (o->m_pDipDF[zr] != NULL)) { for (z3=0;z3<((o->m_bSecondShowMol && (zr == 1))?o->m_iShowMol2Count:o->m_iShowMolCount);z3++) o->m_pDipDF[zr]->m_faData[z3].RemoveAll_KeepSize(); if (o->m_bBinOnlyPassedAtoms || o->m_bBinOnlyNotPassedAtoms) for (z3=0;z3<((o->m_bSecondShowMol && (zr == 1))?o->m_iShowMol2Count:o->m_iShowMolCount);z3++) o->m_pDipDF[zr]->m_baDataEnabled[z3].RemoveAll_KeepSize(); if ((o->m_bTimeDev) && (ti2 != -1) && (!g_bDeriv || (g_iSteps > 2))) { if (o->m_bSaveSeparateFiles) mfprintf(o->m_pDipDF[zr]->m_fDipole[ti2],"%d",(int)g_iSteps); else if (ti2 == 0) mfprintf(o->m_pDipDF[zr]->m_fDipole[0],"%d",(int)g_iSteps); } } if (g_bVDF && (o->m_pVDF[zr] != NULL)) { for (z3=0;z3<((o->m_bSecondShowMol && (zr == 1))?o->m_iShowMol2Count:o->m_iShowMolCount);z3++) o->m_pVDF[zr]->m_faData[z3].RemoveAll_KeepSize(); if (o->m_bBinOnlyPassedAtoms || o->m_bBinOnlyNotPassedAtoms) for (z3=0;z3<((o->m_bSecondShowMol && (zr == 1))?o->m_iShowMol2Count:o->m_iShowMolCount);z3++) o->m_pVDF[zr]->m_baDataEnabled[z3].RemoveAll_KeepSize(); if ((o->m_bTimeDev) && (ti2 != -1) && (!g_bDeriv || (g_iSteps > 2))) { if (o->m_bSaveSeparateFiles) mfprintf(o->m_pVDF[zr]->m_fSpeed[ti2],"%d",(int)g_iSteps); else if (ti2 == 0) mfprintf(o->m_pVDF[zr]->m_fSpeed[0],"%d",(int)g_iSteps); } } } // END FOR zr if (g_bSDF) { for (z3=0;z3m_iShowMolCount;z3++) { o->m_pSDF->m_vaData[z3].RemoveAll_KeepSize(); if (o->m_bBinOnlyPassedAtoms || o->m_bBinOnlyNotPassedAtoms) o->m_pSDF->m_baDataEnabled[z3].RemoveAll_KeepSize(); } } if (g_bPlProj) { for (z3=0;z3m_iShowMolCount;z3++) { o->m_pPlProj->m_vaData[z3].RemoveAll_KeepSize(); if (o->m_bBinOnlyPassedAtoms || o->m_bBinOnlyNotPassedAtoms) o->m_pPlProj->m_baDataEnabled[z3].RemoveAll_KeepSize(); } } if (g_bRevSDF) { for (z3=0;z3m_iShowMolCount;z3++) { o->m_pRevSDF->m_vaData[z3].RemoveAll_KeepSize(); if (o->m_bBinOnlyPassedAtoms || o->m_bBinOnlyNotPassedAtoms) o->m_pRevSDF->m_baDataEnabled[z3].RemoveAll_KeepSize(); } } if (o->m_bSelf) { if (g_bADF) { for (zr=0;zrm_pADF[zr] == NULL) continue; o->m_pADF[zr]->BuildAtomList(smfix,NULL,&templa); for (z4=0;z4m_pADF[zr]->m_bOrtho[0]) { vec0 = g_pTempTimestep->m_vaCoords[templa[z4]]; vec2 = g_pTempTimestep->m_vaCoords[templa[z4+1]]; vec3 = g_pTempTimestep->m_vaCoords[templa[z4+2]]; vec1 = CrossP(FoldVector(vec2-vec0),FoldVector(vec3-vec0)); } else { vec0 = g_pTempTimestep->m_vaCoords[templa[z4]]; vec2 = g_pTempTimestep->m_vaCoords[templa[z4+1]]; vec1 = FoldVector(vec2-vec0); } if (o->m_pADF[zr]->m_bOrtho[1]) { vec4 = g_pTempTimestep->m_vaCoords[templa[z4+3]]; vec3 = g_pTempTimestep->m_vaCoords[templa[z4+4]]; vec5 = g_pTempTimestep->m_vaCoords[templa[z4+5]]; vec2 = CrossP(FoldVector(vec3-vec4),FoldVector(vec5-vec4)); } else { vec4 = g_pTempTimestep->m_vaCoords[templa[z4+3]]; vec3 = g_pTempTimestep->m_vaCoords[templa[z4+4]]; vec2 = FoldVector(vec3-vec4); } tf = Angle_Deg(vec1,vec2); if ((tf > 90.0) && (o->m_pADF[zr]->m_bFoldAngle)) tf = 180.0-tf; if (o->m_pADF[zr]->m_bCosine) tf = cos(tf/180.0*Pi); if (g_bDeriv) { o->m_pADF[zr]->m_pfaDerivBuffer[g_iDerivNext]->GetAt(z2*o->m_pADF[zr]->m_iCombinations+z4/6) = tf; switch(o->m_pADF[zr]->m_iDeriv) { case 0: tf = o->m_pADF[zr]->m_pfaDerivBuffer[g_iDerivCurr]->GetAt(z2*o->m_pADF[zr]->m_iCombinations+z4/6); break; case 1: tf = (o->m_pADF[zr]->m_pfaDerivBuffer[g_iDerivNext]->GetAt(z2*o->m_pADF[zr]->m_iCombinations+z4/6) - o->m_pADF[zr]->m_pfaDerivBuffer[g_iDerivLast]->GetAt(z2*o->m_pADF[zr]->m_iCombinations+z4/6)) / (2*g_fTimestepLength); break; case 2: tf = (o->m_pADF[zr]->m_pfaDerivBuffer[g_iDerivLast]->GetAt(z2*o->m_pADF[zr]->m_iCombinations+z4/6) + o->m_pADF[zr]->m_pfaDerivBuffer[g_iDerivNext]->GetAt(z2*o->m_pADF[zr]->m_iCombinations+z4/6) - 2*o->m_pADF[zr]->m_pfaDerivBuffer[g_iDerivCurr]->GetAt(z2*o->m_pADF[zr]->m_iCombinations+z4/6)) / (g_fTimestepLength * g_fTimestepLength); break; } } if (!g_bDeriv || (g_iSteps > 2)) { if (o->m_bObsCertain && o->m_bDecompDist) o->m_pADF[zr]->m_pADF->AddToBin_Multi(tic_r,tf); o->m_pADF[zr]->m_faData[0].Add(tf); if (o->m_pADF[zr]->m_bACF) o->m_pADF[zr]->m_pfaACFBuffer[z2*o->m_pADF[zr]->m_iCombinations+z4/6]->Add((double)tf); /* if (o->m_pADF[zr]->m_bMirror) { if (o->m_bObsCertain && o->m_bDecompDist) o->m_pADF[zr]->m_pADF->AddToBin_Multi(tic_r,180.0-tf); o->m_pADF[zr]->m_faData[0].Add(180.0-tf); }*/ if (o->m_bTimeDev && (ti2 != -1)) { if (o->m_bSaveSeparateFiles) mfprintf(o->m_pADF[zr]->m_fAngle[ti2],"; %8.3f",tf); else mfprintf(o->m_pADF[zr]->m_fAngle[0],"; %8.3f",tf); if (o->m_bCombinedPlot) o->m_pADF[zr]->m_pADF->m_pCombinedPlot->AddXYTupel(ti2*o->m_pADF[zr]->m_iCombinations+z4/6,g_iSteps*g_fTimestepLength/1000.0,tf); } if (o->m_bTimeDiff) ((CxDoubleArray*)o->m_pADF[zr]->m_pADF->m_oaTimeDiffBuf[z2*o->m_pADF[zr]->m_iCombinations+z4/6])->Add((double)tf); } } // END FOR z4 } // END FOR zr } // Ende IF ADF if (g_bDDF) { for (zr=0;zrm_pDDF[zr] == NULL) continue; o->m_pDDF[zr]->BuildAtomList(smfix,smfix,&templa); for (z4=0;z4m_pDDF[zr]->m_bOrtho[0]) { vec0 = g_pTempTimestep->m_vaCoords[templa[z4]]; vec2 = g_pTempTimestep->m_vaCoords[templa[z4+1]]; vec3 = g_pTempTimestep->m_vaCoords[templa[z4+2]]; vec1 = CrossP(FoldVector(vec2-vec0),FoldVector(vec3-vec0)); } else { vec0 = g_pTempTimestep->m_vaCoords[templa[z4]]; vec2 = g_pTempTimestep->m_vaCoords[templa[z4+1]]; vec1 = FoldVector(vec2-vec0); } if (o->m_pDDF[zr]->m_bOrtho[1]) { vec4 = g_pTempTimestep->m_vaCoords[templa[z4+3]]; vec3 = g_pTempTimestep->m_vaCoords[templa[z4+4]]; vec5 = g_pTempTimestep->m_vaCoords[templa[z4+5]]; vec2 = CrossP(FoldVector(vec3-vec4),FoldVector(vec5-vec4)); } else { vec4 = g_pTempTimestep->m_vaCoords[templa[z4+3]]; vec3 = g_pTempTimestep->m_vaCoords[templa[z4+4]]; vec2 = FoldVector(vec3-vec4); } if (o->m_pDDF[zr]->m_bOrtho[2]) { vec4 = g_pTempTimestep->m_vaCoords[templa[z4+6]]; vec3 = g_pTempTimestep->m_vaCoords[templa[z4+7]]; vec5 = g_pTempTimestep->m_vaCoords[templa[z4+8]]; vec3 = CrossP(FoldVector(vec3-vec4),FoldVector(vec5-vec4)); } else { vec4 = g_pTempTimestep->m_vaCoords[templa[z4+6]]; vec3 = g_pTempTimestep->m_vaCoords[templa[z4+7]]; vec3 = FoldVector(vec3-vec4); } tf = Dihedral(vec1,vec2,vec3,o->m_pDDF[zr]->m_bAbs); if (o->m_pDDF[zr]->m_bCosine) tf = cos(tf/180.0*Pi); else if (o->m_pDDF[zr]->m_bPositive) if (tf < 0) tf += 360.0; if (g_bDeriv) { o->m_pDDF[zr]->m_pfaDerivBuffer[g_iDerivNext]->GetAt(z2*o->m_pDDF[zr]->m_iCombinations+z4/9) = tf; switch(o->m_pDDF[zr]->m_iDeriv) { case 0: tf = o->m_pDDF[zr]->m_pfaDerivBuffer[g_iDerivCurr]->GetAt(z2*o->m_pDDF[zr]->m_iCombinations+z4/9); break; case 1: tf = (o->m_pDDF[zr]->m_pfaDerivBuffer[g_iDerivNext]->GetAt(z2*o->m_pDDF[zr]->m_iCombinations+z4/9) - o->m_pDDF[zr]->m_pfaDerivBuffer[g_iDerivLast]->GetAt(z2*o->m_pDDF[zr]->m_iCombinations+z4/9)) / (2*g_fTimestepLength); break; case 2: tf = (o->m_pDDF[zr]->m_pfaDerivBuffer[g_iDerivLast]->GetAt(z2*o->m_pDDF[zr]->m_iCombinations+z4/9) + o->m_pDDF[zr]->m_pfaDerivBuffer[g_iDerivNext]->GetAt(z2*o->m_pDDF[zr]->m_iCombinations+z4/9) - 2*o->m_pDDF[zr]->m_pfaDerivBuffer[g_iDerivCurr]->GetAt(z2*o->m_pDDF[zr]->m_iCombinations+z4/9)) / (g_fTimestepLength * g_fTimestepLength); break; } } if (!g_bDeriv || (g_iSteps > 2)) { if (o->m_bObsCertain && o->m_bDecompDist) o->m_pDDF[zr]->m_pDDF->AddToBin_Multi(tic_r,tf); o->m_pDDF[zr]->m_faData[0].Add(tf); if (o->m_pDDF[zr]->m_bACF) o->m_pDDF[zr]->m_pfaACFBuffer[z2*o->m_pDDF[zr]->m_iCombinations+z4/9]->Add((double)tf); if (/*(!o->m_pDDF[zr]->m_bAbs) && */o->m_pDDF[zr]->m_bSymm) { o->m_pDDF[zr]->m_faData[0].Add(-tf); if (o->m_bObsCertain && o->m_bDecompDist) o->m_pDDF[zr]->m_pDDF->AddToBin_Multi(tic_r,-tf); } if (o->m_bTimeDiff) ((CxDoubleArray*)o->m_pDDF[zr]->m_pDDF->m_oaTimeDiffBuf[z2*o->m_pDDF[zr]->m_iCombinations+z4/9])->Add((double)tf); if (o->m_bTimeDev && (ti2 != -1)) { if (o->m_pDDF[zr]->m_bRotate) { if (g_iSteps > 1) { if ((tf - o->m_pDDF[zr]->m_faLastData[z2*o->m_pDDF[zr]->m_iCombinations+z4/9]) > 180.0) o->m_pDDF[zr]->m_laRotation[z2*o->m_pDDF[zr]->m_iCombinations+z4/9]--; if ((tf - o->m_pDDF[zr]->m_faLastData[z2*o->m_pDDF[zr]->m_iCombinations+z4/9]) < -180.0) o->m_pDDF[zr]->m_laRotation[z2*o->m_pDDF[zr]->m_iCombinations+z4/9]++; } o->m_pDDF[zr]->m_faLastData[z2*o->m_pDDF[zr]->m_iCombinations+z4/9] = tf; tf2 = tf + o->m_pDDF[zr]->m_laRotation[z2*o->m_pDDF[zr]->m_iCombinations+z4/9] * 360.0; } else tf2 = tf; if (o->m_bSaveSeparateFiles) mfprintf(o->m_pDDF[zr]->m_fAngle[ti2],"; %8.3f",tf2); else mfprintf(o->m_pDDF[zr]->m_fAngle[0],"; %8.3f",tf2); if (o->m_bCombinedPlot) o->m_pDDF[zr]->m_pDDF->m_pCombinedPlot->AddXYTupel(ti2*o->m_pDDF[zr]->m_iCombinations+z4/9,g_iSteps*g_fTimestepLength/1000.0,tf); } } } } } // END IF DDF if (g_bVHDF) { o->m_pVHDF->BuildAtomList(smfix,smfix,&templa); for (z4=0;z4m_vaCoords[templa[z4]];// + vecc; for (z0=0;z0m_pVHDF->m_iDepth/o->m_pVHDF->m_iStride;z0++) { g_pT2Timestep = GetTimeStep(z0*o->m_pVHDF->m_iStride); if (g_pT2Timestep == NULL) continue; vec1 = g_pT2Timestep->m_vaCoords[templa[z4+1]]; tf = FoldedLength(vec0-vec1); o->m_pVHDF->m_pVHDF->AddToBin_IntX_fast(z0,tf); o->m_pVHDF->m_pCount[z0]++; } } } // Ende IF VHDF if (g_bRDF) { for (zr=0;zrm_pRDF[zr] == NULL) continue; o->m_pRDF[zr]->BuildAtomList(smfix,smfix,&templa); for (z4=0;z4m_vaCoords[templa[z4]]; vec1 = g_pTempTimestep->m_vaCoords[templa[z4+1]]; tf = FoldedLength(vec0-vec1); if (g_bDeriv) { o->m_pRDF[zr]->m_pfaDerivBuffer[g_iDerivNext]->GetAt(z2*o->m_pRDF[zr]->m_iCombinations+z4/2) = tf; switch(o->m_pRDF[zr]->m_iDeriv) { case 0: tf = o->m_pRDF[zr]->m_pfaDerivBuffer[g_iDerivCurr]->GetAt(z2*o->m_pRDF[zr]->m_iCombinations+z4/2); break; case 1: tf = (o->m_pRDF[zr]->m_pfaDerivBuffer[g_iDerivNext]->GetAt(z2*o->m_pRDF[zr]->m_iCombinations+z4/2) - o->m_pRDF[zr]->m_pfaDerivBuffer[g_iDerivLast]->GetAt(z2*o->m_pRDF[zr]->m_iCombinations+z4/2)) / (2*g_fTimestepLength); break; case 2: tf = (o->m_pRDF[zr]->m_pfaDerivBuffer[g_iDerivLast]->GetAt(z2*o->m_pRDF[zr]->m_iCombinations+z4/2) + o->m_pRDF[zr]->m_pfaDerivBuffer[g_iDerivNext]->GetAt(z2*o->m_pRDF[zr]->m_iCombinations+z4/2) - 2*o->m_pRDF[zr]->m_pfaDerivBuffer[g_iDerivCurr]->GetAt(z2*o->m_pRDF[zr]->m_iCombinations+z4/2)) / (g_fTimestepLength * g_fTimestepLength); break; } } if (!g_bDeriv || (g_iSteps > 2)) { if (o->m_bObsCertain && o->m_bDecompDist) o->m_pRDF[zr]->m_pRDF->AddToBin_Multi(tic_r,tf); if (o->m_bDecompType) o->m_pRDF[zr]->m_pRDF->AddToBin_Multi(o->m_waDecompTypeRefOffs[templa[z4]]*o->m_waDecompTypeObsOffs.GetSize()+o->m_waDecompTypeObsOffs[templa[z4+1]],tf); o->m_pRDF[zr]->m_faData[0].Add(tf); if (o->m_pRDF[zr]->m_bACF) o->m_pRDF[zr]->m_pfaACFBuffer[z2*o->m_pRDF[zr]->m_iCombinations+z4/2]->Add((double)tf); if (o->m_bTimeDev && (ti2 != -1)) { if (o->m_bSaveSeparateFiles) mfprintf(o->m_pRDF[zr]->m_fDist[ti2],"; %10.3f",tf); else mfprintf(o->m_pRDF[zr]->m_fDist[0],"; %10.3f",tf); if (o->m_bCombinedPlot) o->m_pRDF[zr]->m_pRDF->m_pCombinedPlot->AddXYTupel(ti2*o->m_pRDF[zr]->m_iCombinations+z4/2,g_iSteps*g_fTimestepLength/1000.0,tf); } if (o->m_bTimeDiff) ((CxDoubleArray*)o->m_pRDF[zr]->m_pRDF->m_oaTimeDiffBuf[z2*o->m_pRDF[zr]->m_iCombinations+z4/2])->Add((double)tf); } } } } // Ende IF RDF if (g_bPlDF) { for (zr=0;zrm_pPlDF[zr] == NULL) continue; o->m_pPlDF[zr]->BuildAtomList(smfix,smfix,&templa); for (z4=0;z4m_pPlDF[zr]->m_bNormal) { vec0 = FoldVector(g_pTempTimestep->m_vaCoords[templa[z4+1]] - g_pTempTimestep->m_vaCoords[templa[z4]]); vec0.Normalize(); vec1 = FoldVector(g_pTempTimestep->m_vaCoords[templa[z4+3]] - g_pTempTimestep->m_vaCoords[templa[z4]]); tf = DotP(vec0,vec1); } else { vec0 = FoldVector(g_pTempTimestep->m_vaCoords[templa[z4+1]] - g_pTempTimestep->m_vaCoords[templa[z4]]); vec1 = FoldVector(g_pTempTimestep->m_vaCoords[templa[z4+2]] - g_pTempTimestep->m_vaCoords[templa[z4]]); vec3 = CrossP(vec0,vec1); vec3.Normalize(); vec2 = FoldVector(g_pTempTimestep->m_vaCoords[templa[z4+3]] - g_pTempTimestep->m_vaCoords[templa[z4]]); tf = DotP(vec2,vec3); } if (!g_bDeriv || (g_iSteps > 2)) { if (o->m_bObsCertain && o->m_bDecompDist) o->m_pPlDF[zr]->m_pPlDF->AddToBin_Multi(tic_r,tf); o->m_pPlDF[zr]->m_faData[0].Add(tf); } } } } // END IF PlDF if (g_bLiDF) { for (zr=0;zrm_pLiDF[zr] == NULL) continue; o->m_pLiDF[zr]->BuildAtomList(smfix,smfix,&templa); for (z4=0;z4m_pLiDF[zr]->m_bNormal) { vec2 = FoldVector(g_pTempTimestep->m_vaCoords[templa[z4+1]] - g_pTempTimestep->m_vaCoords[templa[z4]]); vec3 = FoldVector(g_pTempTimestep->m_vaCoords[templa[z4+2]] - g_pTempTimestep->m_vaCoords[templa[z4]]); vec0 = CrossP(vec2,vec3); vec0.Normalize(); vec1 = FoldVector(g_pTempTimestep->m_vaCoords[templa[z4+3]] - g_pTempTimestep->m_vaCoords[templa[z4]]); vec0 *= DotP(vec0,vec1); tf = (vec1 - vec0).GetLength(); } else { vec0 = FoldVector(g_pTempTimestep->m_vaCoords[templa[z4+1]] - g_pTempTimestep->m_vaCoords[templa[z4]]); vec0.Normalize(); vec1 = FoldVector(g_pTempTimestep->m_vaCoords[templa[z4+3]] - g_pTempTimestep->m_vaCoords[templa[z4]]); vec0 *= DotP(vec0,vec1); tf = (vec1 - vec0).GetLength(); } if (!g_bDeriv || (g_iSteps > 2)) { if (o->m_bObsCertain && o->m_bDecompDist) o->m_pLiDF[zr]->m_pLiDF->AddToBin_Multi(tic_r,tf); o->m_pLiDF[zr]->m_faData[0].Add(tf); } } } } // END IF LiDF if (g_bDipDF) { for (zr=0;zrm_pDipDF[zr] == NULL) continue; tf = smfix->m_vDipole.GetLength(); if (g_bDeriv) { o->m_pDipDF[zr]->m_pfaDerivBuffer[g_iDerivNext]->GetAt(z2) = tf; switch(o->m_pDipDF[zr]->m_iDeriv) { case 0: tf = o->m_pDipDF[zr]->m_pfaDerivBuffer[g_iDerivCurr]->GetAt(z2); break; case 1: tf = (o->m_pDipDF[zr]->m_pfaDerivBuffer[g_iDerivNext]->GetAt(z2) - o->m_pDipDF[zr]->m_pfaDerivBuffer[g_iDerivLast]->GetAt(z2)) / (2*g_fTimestepLength); break; case 2: tf = (o->m_pDipDF[zr]->m_pfaDerivBuffer[g_iDerivLast]->GetAt(z2) + o->m_pDipDF[zr]->m_pfaDerivBuffer[g_iDerivNext]->GetAt(z2) - 2*o->m_pDipDF[zr]->m_pfaDerivBuffer[g_iDerivCurr]->GetAt(z2)) / (g_fTimestepLength * g_fTimestepLength); break; } } if (!g_bDeriv || (g_iSteps > 2)) { if (o->m_bObsCertain && o->m_bDecompDist) o->m_pDipDF[zr]->m_pDipoleDF->AddToBin_Multi(tic_r,tf); o->m_pDipDF[zr]->m_faData[0].Add(tf); if (o->m_pDipDF[zr]->m_bACF) o->m_pDipDF[zr]->m_pfaACFBuffer[z2]->Add((double)tf); if (o->m_bTimeDev && (ti2 != -1)) { if (o->m_bSaveSeparateFiles) mfprintf(o->m_pDipDF[zr]->m_fDipole[ti2],"; %8.3f",tf); else mfprintf(o->m_pDipDF[zr]->m_fDipole[0],"; %8.3f",tf); if (o->m_bCombinedPlot) o->m_pDipDF[zr]->m_pDipoleDF->m_pCombinedPlot->AddXYTupel(ti2,g_iSteps*g_fTimestepLength/1000.0,tf); } if (o->m_bTimeDiff) ((CxDoubleArray*)o->m_pDipDF[zr]->m_pDipoleDF->m_oaTimeDiffBuf[z2])->Add((double)tf); } } } // Ende IF DIPDF if (g_bVDF) { for (zr=0;zrm_pVDF[zr] == NULL) continue; o->m_pVDF[zr]->BuildAtomList(smfix,smfix,&templa); for (z4=0;z4m_pVDF[zr]->m_pfaDerivBuffer[g_iDerivNext]->GetAt(z2*o->m_pVDF[zr]->m_iCombinations+z4/2) = tf; switch(o->m_pVDF[zr]->m_iDeriv) { case 0: tf = o->m_pVDF[zr]->m_pfaDerivBuffer[g_iDerivCurr]->GetAt(z2*o->m_pVDF[zr]->m_iCombinations+z4/2); break; case 1: tf = (o->m_pVDF[zr]->m_pfaDerivBuffer[g_iDerivNext]->GetAt(z2*o->m_pVDF[zr]->m_iCombinations+z4/2) - o->m_pVDF[zr]->m_pfaDerivBuffer[g_iDerivLast]->GetAt(z2*o->m_pVDF[zr]->m_iCombinations+z4/2)) / (2*g_fTimestepLength); break; case 2: tf = (o->m_pVDF[zr]->m_pfaDerivBuffer[g_iDerivLast]->GetAt(z2*o->m_pVDF[zr]->m_iCombinations+z4/2) + o->m_pVDF[zr]->m_pfaDerivBuffer[g_iDerivNext]->GetAt(z2*o->m_pVDF[zr]->m_iCombinations+z4/2) - 2*o->m_pVDF[zr]->m_pfaDerivBuffer[g_iDerivCurr]->GetAt(z2*o->m_pVDF[zr]->m_iCombinations+z4/2)) / (g_fTimestepLength * g_fTimestepLength); break; } } if (!g_bDeriv || (g_iSteps > 2)) { if (o->m_bObsCertain && o->m_bDecompDist) o->m_pVDF[zr]->m_pVDF->AddToBin_Multi(tic_r,tf); o->m_pVDF[zr]->m_faData[0].Add(tf); if (o->m_pVDF[zr]->m_bACF) o->m_pVDF[zr]->m_pfaACFBuffer[z2*o->m_pVDF[zr]->m_iCombinations+z4]->Add((double)tf); if (o->m_bTimeDev && (ti2 != -1)) { if (o->m_bSaveSeparateFiles) mfprintf(o->m_pVDF[zr]->m_fSpeed[ti2],"; %8.3f",tf); else mfprintf(o->m_pVDF[zr]->m_fSpeed[0],"; %8.3f",tf); if (o->m_bCombinedPlot) o->m_pVDF[zr]->m_pVDF->m_pCombinedPlot->AddXYTupel(ti2*o->m_pVDF[zr]->m_iCombinations+z4,g_iSteps*g_fTimestepLength/1000.0,tf); } if (o->m_bTimeDiff) ((CxDoubleArray*)o->m_pVDF[zr]->m_pVDF->m_oaTimeDiffBuf[z2*o->m_pVDF[zr]->m_iCombinations+z4])->Add((double)tf); } } } } // Ende IF VDF if (g_bSDF) { o->m_pSDF->BuildAtomList(smfix,smfix,&templa); for (z4=0;z4m_pSDF->m_vaData[0].Add(g_pTempTimestep->m_vaCoords[templa[z4]]); if (o->m_pSDF->m_bVdWSpheres) o->m_pSDF->m_faRadius[0].Add(g_faVdWRadius[templa[z4]]); } } } // Ende IF SDF if (g_bPlProj) { o->m_pPlProj->BuildAtomList(smfix,smfix,&templa); for (z4=0;z4m_pPlProj->m_vaData[0].Add(g_pTempTimestep->m_vaCoords[templa[z4]]); } // Ende IF PlProj if (g_bRevSDF) { o->m_pRevSDF->BuildAtomList(smfix,smfix,&templa); for (z4=0;z4m_pRevSDF->m_vaData[0].Add(g_pTempTimestep->m_vaCoords[templa[z4]]); } // Ende IF RevSDF } // Ende IF m_bSelf if (o->m_bOthers) { secondmolrun = false; _secondmolstart: if ((!secondmolrun) && (o->m_pConditions != NULL)) { o->m_pConditions->m_bAnyPassed = false; o->m_pConditions->m_iTempPassed = 0; o->m_pConditions->ScanNeighborhoodAllOM(g_pTempTimestep,smfix); if (o->m_pConditions->m_bAnyPassed) o->m_pConditions->m_iRMPassCounter[z2]++; } if ((secondmolrun) && (o->m_pConditionsOM2 != NULL)) { o->m_pConditionsOM2->m_bAnyPassed = false; o->m_pConditionsOM2->m_iTempPassed = 0; o->m_pConditionsOM2->ScanNeighborhoodAllOM(g_pTempTimestep,smfix); if (o->m_pConditionsOM2->m_bAnyPassed) o->m_pConditionsOM2->m_iRMPassCounter[z2]++; } for (z3=0;z3<(secondmolrun?o->m_iShowMol2Count:o->m_iShowMolCount);z3++) // Alle anderen Molekuele durchgehen { if (secondmolrun) { if ((g_iFixMol == o->m_iShowMol2) && (z3 == z2)) // Wir wollen nicht das Referenzmolekuel mitzaehlen continue; if (o->m_bObsCertain) { if (!o->m_waObsShow2List.Contains((unsigned short)z3)) continue; tic_o = o->m_waObsShow2List.GetPosition((unsigned short)z3); } } else { if ((g_iFixMol == o->m_iShowMol) && (z3 == z2)) // Wir wollen nicht das Referenzmolekuel mitzaehlen continue; if (o->m_bObsCertain) { if (!o->m_waObsShowList.Contains((unsigned short)z3)) continue; tic_o = o->m_waObsShowList.GetPosition((unsigned short)z3); } } if (g_bRegionAnalysis) { if (secondmolrun) { if ((!o->m_iaOM2Regions.Contains(0)) && (!o->m_iaOM2Regions.Contains(g_iaSMRegion[((CMolecule*)g_oaMolecules[o->m_iShowMol2])->m_laSingleMolIndex[z3]]))) continue; } else { if ((!o->m_iaOM1Regions.Contains(0)) && (!o->m_iaOM1Regions.Contains(g_iaSMRegion[((CMolecule*)g_oaMolecules[o->m_iShowMol])->m_laSingleMolIndex[z3]]))) continue; } } // mprintf("\n ... OM %d ist drin!",z3); if (secondmolrun) { ti = -1; sm = (CSingleMolecule*)g_oaSingleMolecules[((CMolecule*)g_oaMolecules[o->m_iShowMol2])->m_laSingleMolIndex[z3]]; } else { ti = o->m_waSaveShowList.GetPosition((unsigned short)z3); sm = (CSingleMolecule*)g_oaSingleMolecules[((CMolecule*)g_oaMolecules[o->m_iShowMol])->m_laSingleMolIndex[z3]]; } if (o->m_bTimeDev && (o->m_pConditions != NULL)) { if (!o->m_pConditions->Contains(z3) && (!g_bDeriv || (g_iSteps > 2))) { for (zr=0;zrm_pADF[zr] != NULL)) { if ((ti2 != -1) && (ti != -1)) { if (o->m_bSaveSeparateFiles) mfprintf(o->m_pADF[zr]->m_fAngle[ti2],"; - "); else mfprintf(o->m_pADF[zr]->m_fAngle[0],"; - "); } } if (g_bDDF && (o->m_pDDF[zr] != NULL)) { if ((ti2 != -1) && (ti != -1)) { if (o->m_bSaveSeparateFiles) mfprintf(o->m_pADF[zr]->m_fAngle[ti2],"; - "); else mfprintf(o->m_pDDF[zr]->m_fAngle[0],"; - "); } } if (g_bDipDF && (o->m_pDipDF[zr] != NULL)) { if ((ti2 != -1) && (ti != -1)) { if (o->m_bSaveSeparateFiles) mfprintf(o->m_pDipDF[zr]->m_fDipole[ti2],"; - "); else mfprintf(o->m_pDipDF[zr]->m_fDipole[0],"; - "); } } if (g_bVDF && (o->m_pVDF[zr] != NULL)) { if ((ti2 != -1) && (ti != -1)) { if (o->m_bSaveSeparateFiles) mfprintf(o->m_pVDF[zr]->m_fSpeed[ti2],"; - "); else mfprintf(o->m_pVDF[zr]->m_fSpeed[0],"; - "); } } if (g_bRDF && (o->m_pRDF[zr] != NULL)) { if ((ti2 != -1) && (ti != -1)) { if (o->m_bSaveSeparateFiles) mfprintf(o->m_pRDF[zr]->m_fDist[ti2],"; - "); else mfprintf(o->m_pRDF[zr]->m_fDist[0],"; - "); } } } continue; } } if ((!secondmolrun) && (o->m_pConditions != NULL)) { if (!o->m_pConditions->Contains(z3)) continue; if (o->m_bBinOnlyPassedAtoms) o->m_pConditions->MarkPassedAtoms(z3,true); if (o->m_bBinOnlyNotPassedAtoms) o->m_pConditions->MarkPassedAtoms(z3,false); if (g_bSaveCondSnapshot) { g_iSaveCondCount++; if (g_bSaveCondWholeBox) { g_pTempTimestep->WriteTimestep(g_fSaveCondFile); } else { mfprintf(g_fSaveCondFile,"%d\nTimestep %lu, RM %d, OM %d\n",((CMolecule*)g_oaMolecules[g_iFixMol])->m_iAtomGes - ((CMolecule*)g_oaMolecules[g_iFixMol])->m_laVirtualAtoms.GetSize() + ((CMolecule*)g_oaMolecules[o->m_iShowMol])->m_iAtomGes - ((CMolecule*)g_oaMolecules[o->m_iShowMol])->m_laVirtualAtoms.GetSize(),g_iSteps,z2+1,z3+1); for (z4=0;z4<((CMolecule*)g_oaMolecules[g_iFixMol])->m_baAtomIndex.GetSize();z4++) { if ((!g_bSaveVirtAtoms) && (((CMolecule*)g_oaMolecules[g_iFixMol])->m_baAtomIndex[z4] == g_iVirtAtomType)) continue; for (z5=0;z5<((CxIntArray*)smfix->m_oaAtomOffset[z4])->GetSize();z5++) mfprintf(g_fSaveCondFile,"%s %f %f %f\n",(const char*)((CAtom*)g_oaAtoms[((CMolecule*)g_oaMolecules[g_iFixMol])->m_baAtomIndex[z4]])->m_sName,g_pTempTimestep->m_vaCoords[((CxIntArray*)smfix->m_oaAtomOffset[z4])->GetAt(z5)][0]/100.0,g_pTempTimestep->m_vaCoords[((CxIntArray*)smfix->m_oaAtomOffset[z4])->GetAt(z5)][1]/100.0,g_pTempTimestep->m_vaCoords[((CxIntArray*)smfix->m_oaAtomOffset[z4])->GetAt(z5)][2]/100.0); } for (z4=0;z4<((CMolecule*)g_oaMolecules[o->m_iShowMol])->m_baAtomIndex.GetSize();z4++) { if ((!g_bSaveVirtAtoms) && (((CMolecule*)g_oaMolecules[o->m_iShowMol])->m_baAtomIndex[z4] == g_iVirtAtomType)) continue; for (z5=0;z5<((CxIntArray*)sm->m_oaAtomOffset[z4])->GetSize();z5++) mfprintf(g_fSaveCondFile,"%s %f %f %f\n",(const char*)((CAtom*)g_oaAtoms[((CMolecule*)g_oaMolecules[o->m_iShowMol])->m_baAtomIndex[z4]])->m_sName,g_pTempTimestep->m_vaCoords[((CxIntArray*)sm->m_oaAtomOffset[z4])->GetAt(z5)][0]/100.0,g_pTempTimestep->m_vaCoords[((CxIntArray*)sm->m_oaAtomOffset[z4])->GetAt(z5)][1]/100.0,g_pTempTimestep->m_vaCoords[((CxIntArray*)sm->m_oaAtomOffset[z4])->GetAt(z5)][2]/100.0); } } } } if (secondmolrun && (o->m_pConditionsOM2 != NULL)) { if (!o->m_pConditionsOM2->Contains(z3)) continue; // mprintf("\nStep %d: z2=%d, z3=%d passed.",g_iSteps,z2,z3); if (o->m_bBinOnlyPassedAtoms) o->m_pConditionsOM2->MarkPassedAtoms(z3,true); if (o->m_bBinOnlyNotPassedAtoms) o->m_pConditionsOM2->MarkPassedAtoms(z3,false); /* if (g_bSaveCondSnapshot) { g_iSaveCondCount++; if (g_bSaveCondWholeBox) { g_pTempTimestep->WriteTimestep(g_fSaveCondFile); } else { mfprintf(g_fSaveCondFile,"%d\nTimestep %lu, RM %d, OM %d\n",((CMolecule*)g_oaMolecules[g_iFixMol])->m_iAtomGes - ((CMolecule*)g_oaMolecules[g_iFixMol])->m_laVirtualAtoms.GetSize() + ((CMolecule*)g_oaMolecules[o->m_iShowMol])->m_iAtomGes - ((CMolecule*)g_oaMolecules[o->m_iShowMol])->m_laVirtualAtoms.GetSize(),g_iSteps,z2+1,z3+1); for (z4=0;z4<((CMolecule*)g_oaMolecules[g_iFixMol])->m_baAtomIndex.GetSize();z4++) { if ((!g_bSaveVirtAtoms) && (((CMolecule*)g_oaMolecules[g_iFixMol])->m_baAtomIndex[z4] == g_iVirtAtomType)) continue; for (z5=0;z5<((CxIntArray*)smfix->m_oaAtomOffset[z4])->GetSize();z5++) mfprintf(g_fSaveCondFile,"%s %f %f %f\n",((CAtom*)g_oaAtoms[((CMolecule*)g_oaMolecules[g_iFixMol])->m_baAtomIndex[z4]])->m_sName,g_pTempTimestep->m_vaCoords[((CxIntArray*)smfix->m_oaAtomOffset[z4])->GetAt(z5)][0]/100.0,g_pTempTimestep->m_vaCoords[((CxIntArray*)smfix->m_oaAtomOffset[z4])->GetAt(z5)][1]/100.0,g_pTempTimestep->m_vaCoords[((CxIntArray*)smfix->m_oaAtomOffset[z4])->GetAt(z5)][2]/100.0); } for (z4=0;z4<((CMolecule*)g_oaMolecules[o->m_iShowMol])->m_baAtomIndex.GetSize();z4++) { if ((!g_bSaveVirtAtoms) && (((CMolecule*)g_oaMolecules[o->m_iShowMol])->m_baAtomIndex[z4] == g_iVirtAtomType)) continue; for (z5=0;z5<((CxIntArray*)sm->m_oaAtomOffset[z4])->GetSize();z5++) mfprintf(g_fSaveCondFile,"%s %f %f %f\n",((CAtom*)g_oaAtoms[((CMolecule*)g_oaMolecules[o->m_iShowMol])->m_baAtomIndex[z4]])->m_sName,g_pTempTimestep->m_vaCoords[((CxIntArray*)sm->m_oaAtomOffset[z4])->GetAt(z5)][0]/100.0,g_pTempTimestep->m_vaCoords[((CxIntArray*)sm->m_oaAtomOffset[z4])->GetAt(z5)][1]/100.0,g_pTempTimestep->m_vaCoords[((CxIntArray*)sm->m_oaAtomOffset[z4])->GetAt(z5)][2]/100.0); } } }*/ } if (g_bVHDF) { o->m_pVHDF->BuildAtomList(smfix,sm,&templa); for (z4=0;z4m_vaCoords[templa[z4]];// + vecc; for (z0=0;z0m_pVHDF->m_iDepth/o->m_pVHDF->m_iStride;z0++) { g_pT2Timestep = GetTimeStep(z0*o->m_pVHDF->m_iStride); if (g_pT2Timestep == NULL) continue; vec1 = g_pT2Timestep->m_vaCoords[templa[z4+1]]; tf = FoldedLength(vec0-vec1); o->m_pVHDF->m_pVHDF->AddToBin_IntX_fast(z0,tf); o->m_pVHDF->m_pCount[z0]++; } } } // Ende IF VHDF if (g_bADF) { for (zr=0;zrm_pADF[zr] == NULL) continue; if (o->m_bSecondShowMol) { if (secondmolrun && (zr == 0)) continue; if (!secondmolrun && (zr == 1)) continue; } o->m_pADF[zr]->BuildAtomList(smfix,sm,&templa); for (z4=0;z4m_bBinOnlyPassedAtoms || o->m_bBinOnlyNotPassedAtoms) { tb = true; if (g_baAtomPassedCondition[templa[z4]] == 0) tb = false; if (g_baAtomPassedCondition[templa[z4+1]] == 0) tb = false; if (o->m_pADF[zr]->m_bOrtho[0]) if (g_baAtomPassedCondition[templa[z4+2]] == 0) tb = false; if (g_baAtomPassedCondition[templa[z4+3]] == 0) tb = false; if (g_baAtomPassedCondition[templa[z4+4]] == 0) tb = false; if (o->m_pADF[zr]->m_bOrtho[1]) if (g_baAtomPassedCondition[templa[z4+5]] == 0) tb = false; if (tb) { o->m_pADF[zr]->m_baDataEnabled[z3].Add(1); } else { // mprintf("Nicht bestanden; z2=%d, z3=%d; (%d,%d,%d) (%d,%d,%d).\n",z2,z3,g_baAtomPassedCondition[tempwa[z4]],g_baAtomPassedCondition[tempwa[z4+1]],g_baAtomPassedCondition[tempwa[z4+2]],g_baAtomPassedCondition[tempwa[z4+3]],g_baAtomPassedCondition[tempwa[z4+4]],g_baAtomPassedCondition[tempwa[z4+5]]); o->m_pADF[zr]->m_baDataEnabled[z3].Add(0); } } if (o->m_pADF[zr]->m_bOrtho[0]) { vec0 = g_pTempTimestep->m_vaCoords[templa[z4]]; vec2 = g_pTempTimestep->m_vaCoords[templa[z4+1]]; vec3 = g_pTempTimestep->m_vaCoords[templa[z4+2]]; vec1 = CrossP(FoldVector(vec2-vec0),FoldVector(vec3-vec0)); } else { vec0 = g_pTempTimestep->m_vaCoords[templa[z4]]; vec2 = g_pTempTimestep->m_vaCoords[templa[z4+1]]; vec1 = FoldVector(vec2-vec0); } if (o->m_pADF[zr]->m_bOrtho[1]) { vec4 = g_pTempTimestep->m_vaCoords[templa[z4+3]]; vec3 = g_pTempTimestep->m_vaCoords[templa[z4+4]]; vec5 = g_pTempTimestep->m_vaCoords[templa[z4+5]]; vec2 = CrossP(FoldVector(vec3-vec4),FoldVector(vec5-vec4)); } else { vec4 = g_pTempTimestep->m_vaCoords[templa[z4+3]]; vec3 = g_pTempTimestep->m_vaCoords[templa[z4+4]]; vec2 = FoldVector(vec3-vec4); } tf = Angle_Deg(vec1,vec2); if ((tf > 90.0) && (o->m_pADF[zr]->m_bFoldAngle)) tf = 180.0-tf; if (o->m_pADF[zr]->m_bCosine) tf = cos(tf/180.0*Pi); // mprintf("z4=%d, templa=%d,%d,%d,%d,%d,%d. vec1=%f|%f|%f, vec2=%f|%f|%f. tf=%f\n",z4,templa[z4],templa[z4+1],templa[z4+2],templa[z4+3],templa[z4+4],templa[z4+5],vec1[0],vec1[1],vec1[2],vec2[0],vec2[1],vec2[2],tf); if (g_bDeriv) { zi = (z2*o->m_iShowMolCount+z3)*o->m_pADF[zr]->m_iCombinations+z4/6; o->m_pADF[zr]->m_pfaDerivBuffer[g_iDerivNext]->GetAt(zi) = tf; switch(o->m_pADF[zr]->m_iDeriv) { case 0: tf = o->m_pADF[zr]->m_pfaDerivBuffer[g_iDerivCurr]->GetAt(zi); break; case 1: tf = (o->m_pADF[zr]->m_pfaDerivBuffer[g_iDerivNext]->GetAt(zi) - o->m_pADF[zr]->m_pfaDerivBuffer[g_iDerivLast]->GetAt(zi)) / (2*g_fTimestepLength); break; case 2: tf = (o->m_pADF[zr]->m_pfaDerivBuffer[g_iDerivLast]->GetAt(zi) + o->m_pADF[zr]->m_pfaDerivBuffer[g_iDerivNext]->GetAt(zi) - 2*o->m_pADF[zr]->m_pfaDerivBuffer[g_iDerivCurr]->GetAt(zi)) / (g_fTimestepLength * g_fTimestepLength); break; } } if (!g_bDeriv || (g_iSteps > 2)) { if (o->m_bObsCertain && o->m_bDecompDist) o->m_pADF[zr]->m_pADF->AddToBin_Multi(tic_r*o->m_waObsShowList.GetSize()+tic_o,tf); o->m_pADF[zr]->m_faData[z3].Add(tf); if (o->m_pADF[zr]->m_bACF) o->m_pADF[zr]->m_pfaACFBuffer[(z2*o->m_iShowMolCount+z3)*o->m_pADF[zr]->m_iCombinations+z4/6]->Add((double)tf); /* if (o->m_pADF[zr]->m_bMirror) { if (o->m_bObsCertain && o->m_bDecompDist) o->m_pADF[zr]->m_pADF->AddToBin_Multi(tic_r*o->m_waObsShowList.GetSize()+tic_o,180.0-tf); o->m_pADF[zr]->m_faData[z3].Add(180.0-tf); }*/ if (o->m_bTimeDev && (ti2 != -1) && (ti != -1)) { // o->m_pAngleStat->AddValue(ti2,ti,tf); if (o->m_bSaveSeparateFiles) mfprintf(o->m_pADF[zr]->m_fAngle[ti2],"; %8.3f",tf); else mfprintf(o->m_pADF[zr]->m_fAngle[0],"; %8.3f",tf); if (o->m_bCombinedPlot) o->m_pADF[zr]->m_pADF->m_pCombinedPlot->AddXYTupel((ti2*o->m_waSaveShowList.GetSize()+ti)*o->m_pADF[zr]->m_iCombinations+z4/6,g_iSteps*g_fTimestepLength/1000.0,tf); } if (o->m_bTimeDiff) ((CxDoubleArray*)o->m_pADF[zr]->m_pADF->m_oaTimeDiffBuf[(z2*o->m_iShowMolCount+z3)*o->m_pADF[zr]->m_iCombinations+z4/6])->Add((double)tf); } } } } // Ende IF ADF if (g_bDDF) { for (zr=0;zrm_pDDF[zr] == NULL) continue; if (o->m_bSecondShowMol) { if (secondmolrun && (zr == 0)) continue; if (!secondmolrun && (zr == 1)) continue; } o->m_pDDF[zr]->BuildAtomList(smfix,sm,&templa); for (z4=0;z4m_bBinOnlyPassedAtoms || o->m_bBinOnlyNotPassedAtoms) { tb = true; for (z5=z4;z5m_pDDF[zr]->m_baDataEnabled[z3].Add(1); else o->m_pDDF[zr]->m_baDataEnabled[z3].Add(0); } if (o->m_pDDF[zr]->m_bOrtho[0]) { vec0 = g_pTempTimestep->m_vaCoords[templa[z4]]; vec2 = g_pTempTimestep->m_vaCoords[templa[z4+1]]; vec3 = g_pTempTimestep->m_vaCoords[templa[z4+2]]; vec1 = CrossP(FoldVector(vec2-vec0),FoldVector(vec3-vec0)); } else { vec0 = g_pTempTimestep->m_vaCoords[templa[z4]]; vec2 = g_pTempTimestep->m_vaCoords[templa[z4+1]]; vec1 = FoldVector(vec2-vec0); } if (o->m_pDDF[zr]->m_bOrtho[1]) { vec4 = g_pTempTimestep->m_vaCoords[templa[z4+3]]; vec3 = g_pTempTimestep->m_vaCoords[templa[z4+4]]; vec5 = g_pTempTimestep->m_vaCoords[templa[z4+5]]; vec2 = CrossP(FoldVector(vec3-vec4),FoldVector(vec5-vec4)); } else { vec4 = g_pTempTimestep->m_vaCoords[templa[z4+3]]; vec3 = g_pTempTimestep->m_vaCoords[templa[z4+4]]; vec2 = FoldVector(vec3-vec4); } if (o->m_pDDF[zr]->m_bOrtho[2]) { vec4 = g_pTempTimestep->m_vaCoords[templa[z4+6]]; vec3 = g_pTempTimestep->m_vaCoords[templa[z4+7]]; vec5 = g_pTempTimestep->m_vaCoords[templa[z4+8]]; vec3 = CrossP(FoldVector(vec3-vec4),FoldVector(vec5-vec4)); } else { vec4 = g_pTempTimestep->m_vaCoords[templa[z4+6]]; vec3 = g_pTempTimestep->m_vaCoords[templa[z4+7]]; vec3 = FoldVector(vec3-vec4); } tf = Dihedral(vec1,vec2,vec3,o->m_pDDF[zr]->m_bAbs); if (o->m_pDDF[zr]->m_bCosine) tf = cos(tf/180.0*Pi); else if (o->m_pDDF[zr]->m_bPositive) if (tf < 0) tf += 360.0; if (g_bDeriv) { zi = (z2*o->m_iShowMolCount+z3)*o->m_pDDF[zr]->m_iCombinations+z4/9; o->m_pDDF[zr]->m_pfaDerivBuffer[g_iDerivNext]->GetAt(zi) = tf; switch(o->m_pDDF[zr]->m_iDeriv) { case 0: tf = o->m_pDDF[zr]->m_pfaDerivBuffer[g_iDerivCurr]->GetAt(zi); break; case 1: tf = (o->m_pDDF[zr]->m_pfaDerivBuffer[g_iDerivNext]->GetAt(zi) - o->m_pDDF[zr]->m_pfaDerivBuffer[g_iDerivLast]->GetAt(zi)) / (2*g_fTimestepLength); break; case 2: tf = (o->m_pDDF[zr]->m_pfaDerivBuffer[g_iDerivLast]->GetAt(zi) + o->m_pDDF[zr]->m_pfaDerivBuffer[g_iDerivNext]->GetAt(zi) - 2*o->m_pDDF[zr]->m_pfaDerivBuffer[g_iDerivCurr]->GetAt(zi)) / (g_fTimestepLength * g_fTimestepLength); break; } } if (!g_bDeriv || (g_iSteps > 2)) { if (o->m_bObsCertain && o->m_bDecompDist) o->m_pDDF[zr]->m_pDDF->AddToBin_Multi(tic_r*o->m_waObsShowList.GetSize()+tic_o,tf); o->m_pDDF[zr]->m_faData[z3].Add(tf); if (o->m_pDDF[zr]->m_bACF) o->m_pDDF[zr]->m_pfaACFBuffer[(z2*o->m_iShowMolCount+z3)*o->m_pDDF[zr]->m_iCombinations+z4/9]->Add((double)tf); if (/*(!o->m_pDDF[zr]->m_bAbs) && */o->m_pDDF[zr]->m_bSymm) { o->m_pDDF[zr]->m_faData[z3].Add(-tf); if (o->m_bObsCertain && o->m_bDecompDist) o->m_pDDF[zr]->m_pDDF->AddToBin_Multi(tic_r*o->m_waObsShowList.GetSize()+tic_o,-tf); } if (o->m_bTimeDiff) ((CxDoubleArray*)o->m_pDDF[zr]->m_pDDF->m_oaTimeDiffBuf[(z2*o->m_iShowMolCount+z3)*o->m_pDDF[zr]->m_iCombinations+z4/9])->Add((double)tf); if (o->m_bTimeDev && (ti2 != -1) && (ti != -1)) { if (o->m_pDDF[zr]->m_bRotate) { if (g_iSteps > 1) { if ((tf - o->m_pDDF[zr]->m_faLastData[(z2*o->m_iShowMolCount+z3)*o->m_pDDF[zr]->m_iCombinations+z4/9]) > 180.0) o->m_pDDF[zr]->m_laRotation[(z2*o->m_iShowMolCount+z3)*o->m_pDDF[zr]->m_iCombinations+z4/9]--; if ((tf - o->m_pDDF[zr]->m_faLastData[(z2*o->m_iShowMolCount+z3)*o->m_pDDF[zr]->m_iCombinations+z4/9]) < -180.0) o->m_pDDF[zr]->m_laRotation[(z2*o->m_iShowMolCount+z3)*o->m_pDDF[zr]->m_iCombinations+z4/9]++; } o->m_pDDF[zr]->m_faLastData[(z2*o->m_iShowMolCount+z3)*o->m_pDDF[zr]->m_iCombinations+z4/9] = tf; tf2 = tf + o->m_pDDF[zr]->m_laRotation[(z2*o->m_iShowMolCount+z3)*o->m_pDDF[zr]->m_iCombinations+z4/9] * 360.0; } else tf2 = tf; if (o->m_bSaveSeparateFiles) mfprintf(o->m_pDDF[zr]->m_fAngle[ti2],"; %8.3f",tf2); else mfprintf(o->m_pDDF[zr]->m_fAngle[0],"; %8.3f",tf2); if (o->m_bCombinedPlot) o->m_pDDF[zr]->m_pDDF->m_pCombinedPlot->AddXYTupel((ti2*o->m_waSaveShowList.GetSize()+ti)*o->m_pDDF[zr]->m_iCombinations+z4/9,g_iSteps*g_fTimestepLength/1000.0,tf); } } } } } // Ende IF DDF if (g_bPlDF) { for (zr=0;zrm_pPlDF[zr] == NULL) continue; if (o->m_bSecondShowMol) { if (secondmolrun && (zr == 0)) continue; if (!secondmolrun && (zr == 1)) continue; } o->m_pPlDF[zr]->BuildAtomList(smfix,sm,&templa); for (z4=0;z4m_bBinOnlyPassedAtoms || o->m_bBinOnlyNotPassedAtoms) { tb = true; for (z5=z4;z5m_pPlDF[zr]->m_baDataEnabled[z3].Add(1); else o->m_pPlDF[zr]->m_baDataEnabled[z3].Add(0); } if (o->m_pPlDF[zr]->m_bNormal) { vec0 = FoldVector(g_pTempTimestep->m_vaCoords[templa[z4+1]] - g_pTempTimestep->m_vaCoords[templa[z4]]); vec0.Normalize(); vec1 = FoldVector(g_pTempTimestep->m_vaCoords[templa[z4+3]] - g_pTempTimestep->m_vaCoords[templa[z4]]); tf = DotP(vec0,vec1); } else { vec0 = FoldVector(g_pTempTimestep->m_vaCoords[templa[z4+1]] - g_pTempTimestep->m_vaCoords[templa[z4]]); vec1 = FoldVector(g_pTempTimestep->m_vaCoords[templa[z4+2]] - g_pTempTimestep->m_vaCoords[templa[z4]]); vec3 = CrossP(vec0,vec1); vec3.Normalize(); vec2 = FoldVector(g_pTempTimestep->m_vaCoords[templa[z4+3]] - g_pTempTimestep->m_vaCoords[templa[z4]]); tf = DotP(vec2,vec3); } if (!g_bDeriv || (g_iSteps > 2)) { if (o->m_bObsCertain && o->m_bDecompDist) o->m_pPlDF[zr]->m_pPlDF->AddToBin_Multi(tic_r*o->m_waObsShowList.GetSize()+tic_o,tf); o->m_pPlDF[zr]->m_faData[z3].Add(tf); } } } } // Ende IF PlDF if (g_bLiDF) { for (zr=0;zrm_pLiDF[zr] == NULL) continue; if (o->m_bSecondShowMol) { if (secondmolrun && (zr == 0)) continue; if (!secondmolrun && (zr == 1)) continue; } o->m_pLiDF[zr]->BuildAtomList(smfix,sm,&templa); for (z4=0;z4m_bBinOnlyPassedAtoms || o->m_bBinOnlyNotPassedAtoms) { tb = true; for (z5=z4;z5m_pLiDF[zr]->m_baDataEnabled[z3].Add(1); else o->m_pLiDF[zr]->m_baDataEnabled[z3].Add(0); } if (o->m_pLiDF[zr]->m_bNormal) { vec2 = FoldVector(g_pTempTimestep->m_vaCoords[templa[z4+1]] - g_pTempTimestep->m_vaCoords[templa[z4]]); vec3 = FoldVector(g_pTempTimestep->m_vaCoords[templa[z4+2]] - g_pTempTimestep->m_vaCoords[templa[z4]]); vec0 = CrossP(vec2,vec3); vec0.Normalize(); vec1 = FoldVector(g_pTempTimestep->m_vaCoords[templa[z4+3]] - g_pTempTimestep->m_vaCoords[templa[z4]]); vec0 *= DotP(vec0,vec1); tf = (vec1 - vec0).GetLength(); } else { vec0 = FoldVector(g_pTempTimestep->m_vaCoords[templa[z4+1]] - g_pTempTimestep->m_vaCoords[templa[z4]]); vec0.Normalize(); vec1 = FoldVector(g_pTempTimestep->m_vaCoords[templa[z4+3]] - g_pTempTimestep->m_vaCoords[templa[z4]]); vec0 *= DotP(vec0,vec1); tf = (vec1 - vec0).GetLength(); } if (!g_bDeriv || (g_iSteps > 2)) { if (o->m_bObsCertain && o->m_bDecompDist) o->m_pLiDF[zr]->m_pLiDF->AddToBin_Multi(tic_r*o->m_waObsShowList.GetSize()+tic_o,tf); o->m_pLiDF[zr]->m_faData[z3].Add(tf); } } } } // Ende IF LiDF if (g_bDipDF) { for (zr=0;zrm_pDipDF[zr] == NULL) continue; if (o->m_bSecondShowMol) { if (secondmolrun && (zr == 0)) continue; if (!secondmolrun && (zr == 1)) continue; } if (o->m_pDipDF[zr]->m_iRefOrSec == 0) tf = smfix->m_vDipole.GetLength(); else tf = sm->m_vDipole.GetLength(); if (g_bDeriv) { zi = z2*o->m_iShowMolCount+z3; o->m_pDipDF[zr]->m_pfaDerivBuffer[g_iDerivNext]->GetAt(zi) = tf; switch(o->m_pDipDF[zr]->m_iDeriv) { case 0: tf = o->m_pDipDF[zr]->m_pfaDerivBuffer[g_iDerivCurr]->GetAt(zi); break; case 1: tf = (o->m_pDipDF[zr]->m_pfaDerivBuffer[g_iDerivNext]->GetAt(zi) - o->m_pDipDF[zr]->m_pfaDerivBuffer[g_iDerivLast]->GetAt(zi)) / (2*g_fTimestepLength); break; case 2: tf = (o->m_pDipDF[zr]->m_pfaDerivBuffer[g_iDerivLast]->GetAt(zi) + o->m_pDipDF[zr]->m_pfaDerivBuffer[g_iDerivNext]->GetAt(zi) - 2*o->m_pDipDF[zr]->m_pfaDerivBuffer[g_iDerivCurr]->GetAt(zi)) / (g_fTimestepLength * g_fTimestepLength); break; } } if (!g_bDeriv || (g_iSteps > 2)) { if (o->m_bObsCertain && o->m_bDecompDist) o->m_pDipDF[zr]->m_pDipoleDF->AddToBin_Multi(tic_r*o->m_waObsShowList.GetSize()+tic_o,tf); o->m_pDipDF[zr]->m_faData[z3].Add(tf); if (o->m_pDipDF[zr]->m_bACF) o->m_pDipDF[zr]->m_pfaACFBuffer[z2*o->m_iShowMolCount+z3]->Add((double)tf); if (o->m_bTimeDev && (ti2 != -1) && (ti != -1)) { if (o->m_bSaveSeparateFiles) mfprintf(o->m_pDipDF[zr]->m_fDipole[ti2],"; %8.3f",tf); else mfprintf(o->m_pDipDF[zr]->m_fDipole[0],"; %8.3f",tf); if (o->m_bCombinedPlot) o->m_pDipDF[zr]->m_pDipoleDF->m_pCombinedPlot->AddXYTupel(ti2*o->m_waSaveShowList.GetSize()+ti,g_iSteps*g_fTimestepLength/1000.0,tf); } if (o->m_bTimeDiff) ((CxDoubleArray*)o->m_pDipDF[zr]->m_pDipoleDF->m_oaTimeDiffBuf[z2*o->m_iShowMolCount+z3])->Add((double)tf); } } } // Ende IF DIPOLE if (g_bVDF) { for (zr=0;zrm_pVDF[zr] == NULL) continue; if (o->m_bSecondShowMol) { if (secondmolrun && (zr == 0)) continue; if (!secondmolrun && (zr == 1)) continue; } o->m_pVDF[zr]->BuildAtomList(smfix,sm,&templa); for (z4=0;z4m_bBinOnlyPassedAtoms || o->m_bBinOnlyNotPassedAtoms) { tb = true; for (z5=z4;z5m_pVDF[zr]->m_baDataEnabled[z3].Add(1); else o->m_pVDF[zr]->m_baDataEnabled[z3].Add(0); } tf = tempvel[templa[z4]].GetLength(); if (g_bDeriv) { zi = (z2*o->m_iShowMolCount+z3)*o->m_pVDF[zr]->m_iCombinations+z4/2; o->m_pVDF[zr]->m_pfaDerivBuffer[g_iDerivNext]->GetAt(zi) = tf; switch(o->m_pVDF[zr]->m_iDeriv) { case 0: tf = o->m_pVDF[zr]->m_pfaDerivBuffer[g_iDerivCurr]->GetAt(zi); break; case 1: tf = (o->m_pVDF[zr]->m_pfaDerivBuffer[g_iDerivNext]->GetAt(zi) - o->m_pVDF[zr]->m_pfaDerivBuffer[g_iDerivLast]->GetAt(zi)) / (2*g_fTimestepLength); break; case 2: tf = (o->m_pVDF[zr]->m_pfaDerivBuffer[g_iDerivLast]->GetAt(zi) + o->m_pVDF[zr]->m_pfaDerivBuffer[g_iDerivNext]->GetAt(zi) - 2*o->m_pVDF[zr]->m_pfaDerivBuffer[g_iDerivCurr]->GetAt(zi)) / (g_fTimestepLength * g_fTimestepLength); break; } } if (!g_bDeriv || (g_iSteps > 2)) { if (o->m_bObsCertain && o->m_bDecompDist) o->m_pVDF[zr]->m_pVDF->AddToBin_Multi(tic_r*o->m_waObsShowList.GetSize()+tic_o,tf); o->m_pVDF[zr]->m_faData[z3].Add(tf); if (o->m_pVDF[zr]->m_bACF) o->m_pVDF[zr]->m_pfaACFBuffer[(z2*o->m_iShowMolCount+z3)*o->m_pVDF[zr]->m_iCombinations+z4/2]->Add((double)tf); if (o->m_bTimeDev && (ti2 != -1) && (ti != -1)) { if (o->m_bSaveSeparateFiles) mfprintf(o->m_pVDF[zr]->m_fSpeed[ti2],"; %8.3f",tf); else mfprintf(o->m_pVDF[zr]->m_fSpeed[0],"; %8.3f",tf); if (o->m_bCombinedPlot) o->m_pVDF[zr]->m_pVDF->m_pCombinedPlot->AddXYTupel((ti2*o->m_waSaveShowList.GetSize()+ti)*o->m_pVDF[zr]->m_iCombinations+z4/2,g_iSteps*g_fTimestepLength/1000.0,tf); } if (o->m_bTimeDiff) ((CxDoubleArray*)o->m_pVDF[zr]->m_pVDF->m_oaTimeDiffBuf[(z2*o->m_iShowMolCount+z3)*o->m_pVDF[zr]->m_iCombinations+z4/2])->Add((double)tf); } } } } // Ende IF VDF if (g_bRDF) { for (zr=0;zrm_pRDF[zr] == NULL) continue; if (o->m_bSecondShowMol) { if (secondmolrun && (zr == 0)) continue; if (!secondmolrun && (zr == 1)) continue; } o->m_pRDF[zr]->BuildAtomList(smfix,sm,&templa); for (z4=0;z4m_bBinOnlyPassedAtoms || o->m_bBinOnlyNotPassedAtoms) { tb = true; for (z5=z4;z5m_pRDF[zr]->m_baDataEnabled[z3].Add(1); else o->m_pRDF[zr]->m_baDataEnabled[z3].Add(0); } vec0 = g_pTempTimestep->m_vaCoords[templa[z4]]; vec1 = g_pTempTimestep->m_vaCoords[templa[z4+1]]; tf = FoldedLength(vec0-vec1); /* if (tf > 2000) { mprintf("\n@ z2=%d, z3=%d, z4=%d, templa[z4]=%d, templa[z4+1]=%d, dist=%f ",z2,z3,z4,templa[z4],templa[z4+1],tf); mprintf("\n vec0: "); vec0.Dump(); mprintf(", vec1: "); vec1.Dump(); mprintf(", vec2: "); vec2.Dump(); } */ // mprintf("\n@ z2=%d, z3=%d, z4=%d, templa[z4]=%d, templa[z4+1]=%d, dist=%f ",z2,z3,z4,templa[z4],templa[z4+1],tf); // mprintf("\n vec0: "); vec0.Dump(); mprintf(", vec1: "); vec1.Dump(); mprintf(", vec2: "); vec2.Dump(); if (g_bDeriv) { zi = (z2*o->m_iShowMolCount+z3)*o->m_pRDF[zr]->m_iCombinations+z4/2; o->m_pRDF[zr]->m_pfaDerivBuffer[g_iDerivNext]->GetAt(zi) = tf; switch(o->m_pRDF[zr]->m_iDeriv) { case 0: tf = o->m_pRDF[zr]->m_pfaDerivBuffer[g_iDerivCurr]->GetAt(zi); break; case 1: tf = (o->m_pRDF[zr]->m_pfaDerivBuffer[g_iDerivNext]->GetAt(zi) - o->m_pRDF[zr]->m_pfaDerivBuffer[g_iDerivLast]->GetAt(zi)) / (2*g_fTimestepLength); break; case 2: tf = (o->m_pRDF[zr]->m_pfaDerivBuffer[g_iDerivLast]->GetAt(zi) + o->m_pRDF[zr]->m_pfaDerivBuffer[g_iDerivNext]->GetAt(zi) - 2*o->m_pRDF[zr]->m_pfaDerivBuffer[g_iDerivCurr]->GetAt(zi)) / (g_fTimestepLength * g_fTimestepLength); break; } } if (!g_bDeriv || (g_iSteps > 2)) { if (o->m_bObsCertain && o->m_bDecompDist) o->m_pRDF[zr]->m_pRDF->AddToBin_Multi(tic_r*o->m_waObsShowList.GetSize()+tic_o,tf); if (o->m_bDecompType) o->m_pRDF[zr]->m_pRDF->AddToBin_Multi(o->m_waDecompTypeRefOffs[templa[z4]]*o->m_waDecompTypeObsOffs.GetSize()+o->m_waDecompTypeObsOffs[templa[z4+1]],tf); o->m_pRDF[zr]->m_faData[z3].Add(tf); if (o->m_pRDF[zr]->m_bACF) o->m_pRDF[zr]->m_pfaACFBuffer[(z2*o->m_iShowMolCount+z3)*o->m_pRDF[zr]->m_iCombinations+z4/2]->Add((double)tf); if (o->m_bTimeDev && (ti2 != -1) && (ti != -1)) { if (o->m_bSaveSeparateFiles) mfprintf(o->m_pRDF[zr]->m_fDist[ti2],"; %10.3f",tf); else mfprintf(o->m_pRDF[zr]->m_fDist[0],"; %10.3f",tf); if (o->m_bCombinedPlot) o->m_pRDF[zr]->m_pRDF->m_pCombinedPlot->AddXYTupel((ti2*o->m_waSaveShowList.GetSize()+ti)*o->m_pRDF[zr]->m_iCombinations+z4/2,g_iSteps*g_fTimestepLength/1000.0,tf); } if (o->m_bTimeDiff) ((CxDoubleArray*)o->m_pRDF[zr]->m_pRDF->m_oaTimeDiffBuf[(z2*o->m_iShowMolCount+z3)*o->m_pRDF[zr]->m_iCombinations+z4/2])->Add((double)tf); } } } } // Ende IF RDF if (g_bSDF) { o->m_pSDF->BuildAtomList(smfix,sm,&templa); for (z4=0;z4m_pSDF->m_vaData[z3].Add(g_pTempTimestep->m_vaCoords[templa[z4]]); if (o->m_pSDF->m_bVdWSpheres) o->m_pSDF->m_faRadius[z3].Add(g_faVdWRadius[templa[z4]]); } } } // Ende IF SDF if (g_bPlProj) { o->m_pPlProj->BuildAtomList(smfix,sm,&templa); for (z4=0;z4m_pPlProj->m_vaData[z3].Add(g_pTempTimestep->m_vaCoords[templa[z4]]); } // Ende IF PlProj if (g_bRevSDF) { o->m_pRevSDF->BuildAtomList(smfix,sm,&templa); for (z4=0;z4m_pRevSDF->m_vaData[z3].Add(g_pTempTimestep->m_vaCoords[templa[z4]]); } // Ende IF RevSDF } // Ende FOR Alle anderen Molekuele durchgehen if (o->m_bSecondShowMol && (!secondmolrun)) { secondmolrun = true; goto _secondmolstart; } } // Ende IF m_bOthers if (g_bSDF && !g_bSDFVoro) { if (o->m_pSDF->m_bSDFMirrorBisect) { vec2 = g_pTempTimestep->m_vaCoords[((CxIntArray*)smfix->m_oaAtomOffset[g_iFixAtomType[1]])->GetAt(g_iFixAtom[1])]; vec3 = g_pTempTimestep->m_vaCoords[((CxIntArray*)smfix->m_oaAtomOffset[g_iFixAtomType[2]])->GetAt(g_iFixAtom[2])]; vec1 = CrossP(vec2,vec3); vec2 += vec3; } if (o->m_pSDF->m_bCutPlane) { o->m_pSDF->m_fAtom2PosX += g_pTempTimestep->m_vaCoords[((CxIntArray*)smfix->m_oaAtomOffset[g_iFixAtomType[1]])->GetAt(g_iFixAtom[1])][0]; o->m_pSDF->m_fAtom3PosX += g_pTempTimestep->m_vaCoords[((CxIntArray*)smfix->m_oaAtomOffset[g_iFixAtomType[2]])->GetAt(g_iFixAtom[2])][0]; o->m_pSDF->m_fAtom3PosY += g_pTempTimestep->m_vaCoords[((CxIntArray*)smfix->m_oaAtomOffset[g_iFixAtomType[2]])->GetAt(g_iFixAtom[2])][1]; o->m_pSDF->m_fPosCounter++; } if (o->m_bSelf) { for (z5=0;z5m_pSDF->m_vaData[0].GetSize();z5++) { vec0 = o->m_pSDF->m_vaData[0][z5]; if (o->m_pSDF->m_bVdWSpheres) o->m_pSDF->m_pSDF->AddToBin_Sphere(vec0,o->m_pSDF->m_faRadius[0][z5]); else o->m_pSDF->m_pSDF->AddToBin(vec0); if (o->m_pSDF->m_bSDFMirrorXY) { vec0[2] = -vec0[2]; o->m_pSDF->m_pSDF->AddToBin(vec0); } if (o->m_pSDF->m_bSDFMirrorBisect) { vec3.PointRoot(vec1,vec2,vec0); vec3 -= vec0; vec3 *= 2.0; vec0 += vec3; o->m_pSDF->m_pSDF->AddToBin(vec0); if (o->m_pSDF->m_bSDFMirrorXY) { vec0[2] = -vec0[2]; o->m_pSDF->m_pSDF->AddToBin(vec0); } } } } else { for (z4=0;z4m_iShowMolCount;z4++) { for (z5=0;z5m_pSDF->m_vaData[z4].GetSize();z5++) { vec0 = o->m_pSDF->m_vaData[z4][z5]; if (o->m_pSDF->m_bVdWSpheres) o->m_pSDF->m_pSDF->AddToBin_Sphere(vec0,o->m_pSDF->m_faRadius[z4][z5]); else o->m_pSDF->m_pSDF->AddToBin(vec0); if (o->m_pSDF->m_bSDFMirrorXY) { vec0[2] = -vec0[2]; o->m_pSDF->m_pSDF->AddToBin(vec0); } if (o->m_pSDF->m_bSDFMirrorBisect) { vec3.PointRoot(vec1,vec2,vec0); vec3 -= vec0; vec3 *= 2.0; vec0 += vec3; o->m_pSDF->m_pSDF->AddToBin(vec0); if (o->m_pSDF->m_bSDFMirrorXY) { vec0[2] = -vec0[2]; o->m_pSDF->m_pSDF->AddToBin(vec0); } } } } } } // END IF SDF if (g_bPlProj) { if (o->m_bSelf) { for (z5=0;z5m_pPlProj->m_vaData[0].GetSize();z5++) { vec0 = o->m_pPlProj->m_vaData[0][z5]; if ((vec0[2] >= o->m_pPlProj->m_fSliceBorder[0]) && (vec0[2] <= o->m_pPlProj->m_fSliceBorder[1])) o->m_pPlProj->m_p2DF->AddToBin(vec0[0],vec0[1]); } } else { for (z4=0;z4m_iShowMolCount;z4++) { for (z5=0;z5m_pPlProj->m_vaData[z4].GetSize();z5++) { vec0 = o->m_pPlProj->m_vaData[z4][z5]; if ((vec0[2] >= o->m_pPlProj->m_fSliceBorder[0]) && (vec0[2] <= o->m_pPlProj->m_fSliceBorder[1])) o->m_pPlProj->m_p2DF->AddToBin(vec0[0],vec0[1]); } } } } // END IF PlProj if (g_bRevSDF) { vec2 = g_pTempTimestep->m_vaCoords[((CxIntArray*)smfix->m_oaAtomOffset[g_iFixAtomType[1]])->GetAt(g_iFixAtom[1])]; tf4 = g_pTempTimestep->m_vaCoords[((CxIntArray*)smfix->m_oaAtomOffset[g_iFixAtomType[1]])->GetAt(g_iFixAtom[1])].GetLength(); o->m_pRevSDF->m_fSecondAtomPosX += tf4; o->m_pRevSDF->m_fSecondAtomCount++; if (o->m_bSelf) { for (z5=0;z5m_pRevSDF->m_vaData[0].GetSize();z5++) { vec0 = o->m_pRevSDF->m_vaData[0][z5]; tf = fabs(Angle(vec2,vec0)); tf2 = vec0.GetLength(); tf3 = 1.0; if (o->m_pRevSDF->m_bCorrectAngle) { if ((tf < 0.001) || (tf > Pi-0.001)) tf3 /= 0.001; else tf3 /= sin(tf); } if (o->m_pRevSDF->m_bCorrectRadial) tf3 /= tf2; // Erste Potenz, da 2D-Grid (SDF hat "nullte Potenz" ^^) o->m_pRevSDF->m_p2DF->AddToBin(sin(tf)*tf2,cos(tf)*tf2,tf3); o->m_pRevSDF->m_p2DF->AddToBin(-sin(tf)*tf2,cos(tf)*tf2,tf3); if (o->m_pRevSDF->m_bMirrorY) { if (o->m_pRevSDF->m_bMirrorBond) { o->m_pRevSDF->m_p2DF->AddToBin(sin(tf)*tf2,tf4-cos(tf)*tf2,tf3); o->m_pRevSDF->m_p2DF->AddToBin(-sin(tf)*tf2,tf4-cos(tf)*tf2,tf3); } else { o->m_pRevSDF->m_p2DF->AddToBin(sin(tf)*tf2,-cos(tf)*tf2,tf3); o->m_pRevSDF->m_p2DF->AddToBin(-sin(tf)*tf2,-cos(tf)*tf2,tf3); } } } } else { for (z4=0;z4m_iShowMolCount;z4++) { for (z5=0;z5m_pRevSDF->m_vaData[z4].GetSize();z5++) { vec0 = o->m_pRevSDF->m_vaData[z4][z5]; tf = fabs(Angle(vec2,vec0)); tf2 = vec0.GetLength(); tf3 = 1.0; if (o->m_pRevSDF->m_bCorrectAngle) { if ((tf < 0.001) || (tf > Pi-0.001)) tf3 /= 0.001; else tf3 /= sin(tf); } if (o->m_pRevSDF->m_bCorrectRadial) tf3 /= tf2; // Erste Potenz, da 2D-Grid (SDF hat "nullte Potenz" ^^) o->m_pRevSDF->m_p2DF->AddToBin(sin(tf)*tf2,cos(tf)*tf2,tf3); o->m_pRevSDF->m_p2DF->AddToBin(-sin(tf)*tf2,cos(tf)*tf2,tf3); if (o->m_pRevSDF->m_bMirrorY) { if (o->m_pRevSDF->m_bMirrorBond) { o->m_pRevSDF->m_p2DF->AddToBin(sin(tf)*tf2,tf4-cos(tf)*tf2,tf3); o->m_pRevSDF->m_p2DF->AddToBin(-sin(tf)*tf2,tf4-cos(tf)*tf2,tf3); } else { o->m_pRevSDF->m_p2DF->AddToBin(sin(tf)*tf2,-cos(tf)*tf2,tf3); o->m_pRevSDF->m_p2DF->AddToBin(-sin(tf)*tf2,-cos(tf)*tf2,tf3); } } } } } } // END IF REVSDF if (g_bCDF && (!g_bDeriv || (g_iSteps > 2))) { if (o->m_bSecondShowMol) { for (zr=0;zrm_pRDF[zr]->m_faData; apba[zr] = o->m_pRDF[zr]->m_baDataEnabled; break; case 1: apfa[zr] = o->m_pADF[zr]->m_faData; apba[zr] = o->m_pADF[zr]->m_baDataEnabled; break; case 2: apfa[zr] = o->m_pDDF[zr]->m_faData; apba[zr] = o->m_pDDF[zr]->m_baDataEnabled; break; case 3: apfa[zr] = o->m_pDipDF[zr]->m_faData; apba[zr] = o->m_pDipDF[zr]->m_baDataEnabled; break; case 4: apfa[zr] = o->m_pVDF[zr]->m_faData; apba[zr] = o->m_pVDF[zr]->m_baDataEnabled; break; case 5: apfa[zr] = o->m_pPlDF[zr]->m_faData; apba[zr] = o->m_pPlDF[zr]->m_baDataEnabled; break; case 6: apfa[zr] = o->m_pLiDF[zr]->m_faData; apba[zr] = o->m_pLiDF[zr]->m_baDataEnabled; break; } } if (g_iCDFChannels == 2) { for (z4=0;z4m_iShowMolCount;z4++) { for (z5=0;z5m_iShowMol2Count;z8++) { if (o->m_bExclude1eq2 && (z4 == z8)) continue; for (z7=0;z7m_bBinOnlyPassedAtoms) { if ((apba[0][z4][z5] == 0) || (apba[1][z8][z7] == 0)) goto _nocdfbin2; } if (o->m_bBinOnlyNotPassedAtoms) { if ((apba[0][z4][z5] != 0) && (apba[1][z8][z7] != 0)) goto _nocdfbin2; } o->m_pCDF->m_p2DF->AddToBin(apfa[0][z4][z5],apfa[1][z8][z7]); _nocdfbin2: if (o->m_pCDF->m_bDumpDat) mfprintf(o->m_pCDF->m_fDump,"%d; %d; %d; %d; %10.3f; %10.3f\n",(int)g_iSteps,z2+1,z4+1,z5+1,apfa[0][z4][z5],apfa[1][z8][z7]); } } } } } } else // IF NOT SECOND_OM { for (zr=0;zrm_pRDF[zr]->m_faData; apba[zr] = o->m_pRDF[zr]->m_baDataEnabled; break; case 1: apfa[zr] = o->m_pADF[zr]->m_faData; apba[zr] = o->m_pADF[zr]->m_baDataEnabled; break; case 2: apfa[zr] = o->m_pDDF[zr]->m_faData; apba[zr] = o->m_pDDF[zr]->m_baDataEnabled; break; case 3: apfa[zr] = o->m_pDipDF[zr]->m_faData; apba[zr] = o->m_pDipDF[zr]->m_baDataEnabled; break; case 4: apfa[zr] = o->m_pVDF[zr]->m_faData; apba[zr] = o->m_pVDF[zr]->m_baDataEnabled; break; case 5: apfa[zr] = o->m_pPlDF[zr]->m_faData; apba[zr] = o->m_pPlDF[zr]->m_baDataEnabled; break; case 6: apfa[zr] = o->m_pLiDF[zr]->m_faData; apba[zr] = o->m_pLiDF[zr]->m_baDataEnabled; break; } } if (g_iCDFChannels == 2) { for (z4=0;z4m_iShowMolCount;z4++) { ticomb = 0; for (z5=0;z5m_pDDF[0]->m_bSymm) { if (g_iObsChannel[1] == 2) { if (o->m_pDDF[1]->m_bSymm) { if (o->m_pCDF->m_pCombineList[(z5/2)*o->m_pCDF->m_iCombinations[1]+(z7/2)] == 0) continue; goto _ddfsymmdone; } } } if (o->m_pCDF->m_pCombineList[(z5/2)*o->m_pCDF->m_iCombinations[1]+z7] == 0) continue; } else { if (g_iObsChannel[1] == 2) { if (o->m_pDDF[1]->m_bSymm) { if (o->m_pCDF->m_pCombineList[z5*o->m_pCDF->m_iCombinations[1]+(z7/2)] == 0) continue; goto _ddfsymmdone; } } if (o->m_pCDF->m_pCombineList[z5*o->m_pCDF->m_iCombinations[1]+z7] == 0) continue; } _ddfsymmdone: if (o->m_bBinOnlyPassedAtoms) { if ((apba[0][z4][z5] == 0) || (apba[1][z4][z7] == 0)) goto _nocdfbin; } if (o->m_bBinOnlyNotPassedAtoms) { if ((apba[0][z4][z5] != 0) && (apba[1][z4][z7] != 0)) goto _nocdfbin; } o->m_pCDF->m_p2DF->AddToBin(apfa[0][z4][z5],apfa[1][z4][z7]); _nocdfbin:; if (o->m_pCDF->m_bDumpDat) mfprintf(o->m_pCDF->m_fDump,"%d; %d; %d; ; %10.3f; %10.3f\n",(int)g_iSteps,z2+1,z4+1,apfa[0][z4][z5],apfa[1][z4][z7]); if (o->m_bTimeDev) { ti = o->m_waSaveShowList.GetPosition((unsigned short)z4); if ((ti2 != -1) && (ti != -1)) { if (o->m_bSaveSeparateFiles) mfprintf(o->m_pCDF->m_fTimeDev[ti2],"; %10.3f; %10.3f",apfa[0][z4][z5],apfa[1][z4][z7]); else mfprintf(o->m_pCDF->m_fTimeDev[0],"; %10.3f; %10.3f",apfa[0][z4][z5],apfa[1][z4][z7]); if (o->m_pCDF->m_bTDAnimation) o->m_pCDF->m_pTDAPlot->AddXYTupel((ti2*o->m_waSaveShowList.GetSize()+ti)*o->m_pCDF->m_iCombinationsEnabled+ticomb,apfa[0][z4][z5],apfa[1][z4][z7]); } ticomb++; } } } } if (o->m_bTimeDev && (ti2 != -1)) { if (o->m_bSaveSeparateFiles) mfprintf(o->m_pCDF->m_fTimeDev[ti2],"\n"); else if (ti2 == (int)o->m_waSaveRefList.GetSize()-1) mfprintf(o->m_pCDF->m_fTimeDev[0],"\n"); } } // END IF CHANNELS == 2 if (g_iCDFChannels == 3) { for (z4=0;z4m_iShowMolCount;z4++) { ticomb = 0; for (z5=0;z5m_pCDF->m_pCombineList[z5*o->m_pCDF->m_iCombinations[1]*o->m_pCDF->m_iCombinations[2]+z8*o->m_pCDF->m_iCombinations[1]+z7] == 0) continue; if (o->m_bBinOnlyPassedAtoms) { if ((apba[0][z4][z5] == 0) || (apba[1][z4][z8] == 0) || (apba[2][z4][z7] == 0)) goto _3nocdfbin; } if (o->m_bBinOnlyNotPassedAtoms) { if ((apba[0][z4][z5] != 0) && (apba[1][z4][z8] != 0) && (apba[2][z4][z7] != 0)) goto _3nocdfbin; } o->m_pCDF->m_p3DF->AddToBin(apfa[0][z4][z5],apfa[1][z4][z8],apfa[2][z4][z7]); o->m_pCDF->m_p3DF->m_p2DF[0]->AddToBin(apfa[0][z4][z5],apfa[1][z4][z8]); o->m_pCDF->m_p3DF->m_p2DF[1]->AddToBin(apfa[0][z4][z5],apfa[2][z4][z7]); o->m_pCDF->m_p3DF->m_p2DF[2]->AddToBin(apfa[1][z4][z8],apfa[2][z4][z7]); _3nocdfbin:; if (o->m_pCDF->m_bDumpDat) mfprintf(o->m_pCDF->m_fDump,"%d; %d; %d; ; %10.3f; %10.3f; %10.3f\n",(int)g_iSteps,z2+1,z4+1,apfa[0][z4][z5],apfa[1][z4][z8],apfa[2][z4][z7]); } } } } } // END IF CHANNELS == 3 } // IF NOT SECOND_OM } // IF CDF for (zr=0;zrm_bObsCertain && o->m_bDecompDist) && (!o->m_bDecompType) && (o->m_pRDF[zr] != NULL) && (!g_bDeriv || (g_iSteps > 2))) { if (o->m_bOthers) { if (o->m_bSecondShowMol && (zr == 1)) { for (z4=0;z4m_iShowMol2Count;z4++) { for (z5=0;z5m_pRDF[zr]->m_faData[z4].GetSize();z5++) { if (o->m_bBinOnlyPassedAtoms) if (o->m_pRDF[zr]->m_baDataEnabled[z4][z5] == 0) continue; if (o->m_bBinOnlyNotPassedAtoms) if (o->m_pRDF[zr]->m_baDataEnabled[z4][z5] != 0) continue; o->m_pRDF[zr]->m_pRDF->AddToBin(o->m_pRDF[zr]->m_faData[z4][z5]); } } } else { for (z4=0;z4m_iShowMolCount;z4++) { for (z5=0;z5m_pRDF[zr]->m_faData[z4].GetSize();z5++) { if (o->m_bBinOnlyPassedAtoms) if (o->m_pRDF[zr]->m_baDataEnabled[z4][z5] == 0) continue; if (o->m_bBinOnlyNotPassedAtoms) if (o->m_pRDF[zr]->m_baDataEnabled[z4][z5] != 0) continue; o->m_pRDF[zr]->m_pRDF->AddToBin(o->m_pRDF[zr]->m_faData[z4][z5]); } } } } else { for (z5=0;z5m_pRDF[zr]->m_faData[0].GetSize();z5++) o->m_pRDF[zr]->m_pRDF->AddToBin(o->m_pRDF[zr]->m_faData[0][z5]); } if (o->m_bTimeDev && (ti2 != -1)) { if (o->m_bSaveSeparateFiles) mfprintf(o->m_pRDF[zr]->m_fDist[ti2],"\n"); else if (ti2 == (int)o->m_waSaveRefList.GetSize()-1) mfprintf(o->m_pRDF[zr]->m_fDist[0],"\n"); } } if (g_bVDF && !(o->m_bObsCertain && o->m_bDecompDist) && (o->m_pVDF[zr] != NULL) && (!g_bDeriv || (g_iSteps > 2))) { if (o->m_bOthers) { if (o->m_bSecondShowMol && (zr == 1)) { for (z4=0;z4m_iShowMol2Count;z4++) for (z5=0;z5m_pVDF[zr]->m_faData[z4].GetSize();z5++) o->m_pVDF[zr]->m_pVDF->AddToBin(o->m_pVDF[zr]->m_faData[z4][z5]); } else { for (z4=0;z4m_iShowMolCount;z4++) { for (z5=0;z5m_pVDF[zr]->m_faData[z4].GetSize();z5++) { if (o->m_bBinOnlyPassedAtoms) if (o->m_pVDF[zr]->m_baDataEnabled[z4][z5] == 0) continue; if (o->m_bBinOnlyNotPassedAtoms) if (o->m_pVDF[zr]->m_baDataEnabled[z4][z5] != 0) continue; o->m_pVDF[zr]->m_pVDF->AddToBin(o->m_pVDF[zr]->m_faData[z4][z5]); } } } } else { for (z5=0;z5m_pVDF[zr]->m_faData[0].GetSize();z5++) o->m_pVDF[zr]->m_pVDF->AddToBin(o->m_pVDF[zr]->m_faData[0][z5]); } if (o->m_bTimeDev && (ti2 != -1)) { if (o->m_bSaveSeparateFiles) mfprintf(o->m_pVDF[zr]->m_fSpeed[ti2],"\n"); else if (ti2 == (int)o->m_waSaveRefList.GetSize()-1) mfprintf(o->m_pVDF[zr]->m_fSpeed[0],"\n"); } } if (g_bDipDF && !(o->m_bObsCertain && o->m_bDecompDist) && (o->m_pDipDF[zr] != NULL) && (!g_bDeriv || (g_iSteps > 2))) { if (o->m_bOthers) { if (o->m_bSecondShowMol && (zr == 1)) { for (z4=0;z4m_iShowMol2Count;z4++) for (z5=0;z5m_pDipDF[zr]->m_faData[z4].GetSize();z5++) o->m_pDipDF[zr]->m_pDipoleDF->AddToBin(o->m_pDipDF[zr]->m_faData[z4][z5]); } else { for (z4=0;z4m_iShowMolCount;z4++) { for (z5=0;z5m_pDipDF[zr]->m_faData[z4].GetSize();z5++) { if (o->m_bBinOnlyPassedAtoms) if (o->m_pDipDF[zr]->m_baDataEnabled[z4][z5] == 0) continue; if (o->m_bBinOnlyNotPassedAtoms) if (o->m_pDipDF[zr]->m_baDataEnabled[z4][z5] != 0) continue; o->m_pDipDF[zr]->m_pDipoleDF->AddToBin(o->m_pDipDF[zr]->m_faData[z4][z5]); } } } } else { for (z5=0;z5m_pDipDF[zr]->m_faData[0].GetSize();z5++) o->m_pDipDF[zr]->m_pDipoleDF->AddToBin(o->m_pDipDF[zr]->m_faData[0][z5]); } if (o->m_bTimeDev && (ti2 != -1)) { if (o->m_bSaveSeparateFiles) mfprintf(o->m_pDipDF[zr]->m_fDipole[ti2],"\n"); else if (ti2 == (int)o->m_waSaveRefList.GetSize()-1) mfprintf(o->m_pDipDF[zr]->m_fDipole[0],"\n"); } } if (g_bADF && !(o->m_bObsCertain && o->m_bDecompDist) && (o->m_pADF[zr] != NULL) && (!g_bDeriv || (g_iSteps > 2))) { if (o->m_bOthers) { if (o->m_bSecondShowMol && (zr == 1)) { for (z4=0;z4m_iShowMol2Count;z4++) for (z5=0;z5m_pADF[zr]->m_faData[z4].GetSize();z5++) o->m_pADF[zr]->m_pADF->AddToBin(o->m_pADF[zr]->m_faData[z4][z5]); } else { for (z4=0;z4m_iShowMolCount;z4++) { for (z5=0;z5m_pADF[zr]->m_faData[z4].GetSize();z5++) { if (o->m_bBinOnlyPassedAtoms) if (o->m_pADF[zr]->m_baDataEnabled[z4][z5] == 0) continue; if (o->m_bBinOnlyNotPassedAtoms) if (o->m_pADF[zr]->m_baDataEnabled[z4][z5] != 0) continue; o->m_pADF[zr]->m_pADF->AddToBin(o->m_pADF[zr]->m_faData[z4][z5]); } } } } else { for (z5=0;z5m_pADF[zr]->m_faData[0].GetSize();z5++) o->m_pADF[zr]->m_pADF->AddToBin(o->m_pADF[zr]->m_faData[0][z5]); } if (o->m_bTimeDev && (ti2 != -1)) { if (o->m_bSaveSeparateFiles) mfprintf(o->m_pADF[zr]->m_fAngle[ti2],"\n"); else if (ti2 == (int)o->m_waSaveRefList.GetSize()-1) mfprintf(o->m_pADF[zr]->m_fAngle[0],"\n"); } } if (g_bDDF && !(o->m_bObsCertain && o->m_bDecompDist) && (o->m_pDDF[zr] != NULL) && (!g_bDeriv || (g_iSteps > 2))) { if (o->m_bOthers) { if (o->m_bSecondShowMol && (zr == 1)) { for (z4=0;z4m_iShowMol2Count;z4++) for (z5=0;z5m_pDDF[zr]->m_faData[z4].GetSize();z5++) o->m_pDDF[zr]->m_pDDF->AddToBin(o->m_pDDF[zr]->m_faData[z4][z5]); } else { for (z4=0;z4m_iShowMolCount;z4++) { for (z5=0;z5m_pDDF[zr]->m_faData[z4].GetSize();z5++) { if (o->m_bBinOnlyPassedAtoms) if (o->m_pDDF[zr]->m_baDataEnabled[z4][z5] == 0) continue; if (o->m_bBinOnlyNotPassedAtoms) if (o->m_pDDF[zr]->m_baDataEnabled[z4][z5] != 0) continue; o->m_pDDF[zr]->m_pDDF->AddToBin(o->m_pDDF[zr]->m_faData[z4][z5]); } } } } else { for (z5=0;z5m_pDDF[zr]->m_faData[0].GetSize();z5++) o->m_pDDF[zr]->m_pDDF->AddToBin(o->m_pDDF[zr]->m_faData[0][z5]); } if (o->m_bTimeDev && (ti2 != -1)) { if (o->m_bSaveSeparateFiles) mfprintf(o->m_pDDF[zr]->m_fAngle[ti2],"\n"); else if (ti2 == (int)o->m_waSaveRefList.GetSize()-1) mfprintf(o->m_pDDF[zr]->m_fAngle[0],"\n"); } } // End IF DDF if (g_bPlDF && !(o->m_bObsCertain && o->m_bDecompDist) && (o->m_pPlDF[zr] != NULL) && (!g_bDeriv || (g_iSteps > 2))) { if (o->m_bOthers) { if (o->m_bSecondShowMol && (zr == 1)) { for (z4=0;z4m_iShowMol2Count;z4++) for (z5=0;z5m_pPlDF[zr]->m_faData[z4].GetSize();z5++) o->m_pPlDF[zr]->m_pPlDF->AddToBin(o->m_pPlDF[zr]->m_faData[z4][z5]); } else { for (z4=0;z4m_iShowMolCount;z4++) { for (z5=0;z5m_pPlDF[zr]->m_faData[z4].GetSize();z5++) { if (o->m_bBinOnlyPassedAtoms) if (o->m_pPlDF[zr]->m_baDataEnabled[z4][z5] == 0) continue; if (o->m_bBinOnlyNotPassedAtoms) if (o->m_pPlDF[zr]->m_baDataEnabled[z4][z5] != 0) continue; o->m_pPlDF[zr]->m_pPlDF->AddToBin(o->m_pPlDF[zr]->m_faData[z4][z5]); } } } } else { for (z5=0;z5m_pPlDF[zr]->m_faData[0].GetSize();z5++) o->m_pPlDF[zr]->m_pPlDF->AddToBin(o->m_pPlDF[zr]->m_faData[0][z5]); } } // End IF PlDF if (g_bLiDF && !(o->m_bObsCertain && o->m_bDecompDist) && (o->m_pLiDF[zr] != NULL) && (!g_bDeriv || (g_iSteps > 2))) { if (o->m_bOthers) { if (o->m_bSecondShowMol && (zr == 1)) { for (z4=0;z4m_iShowMol2Count;z4++) for (z5=0;z5m_pLiDF[zr]->m_faData[z4].GetSize();z5++) o->m_pLiDF[zr]->m_pLiDF->AddToBin(o->m_pLiDF[zr]->m_faData[z4][z5]); } else { for (z4=0;z4m_iShowMolCount;z4++) { for (z5=0;z5m_pLiDF[zr]->m_faData[z4].GetSize();z5++) { if (o->m_bBinOnlyPassedAtoms) if (o->m_pLiDF[zr]->m_baDataEnabled[z4][z5] == 0) continue; if (o->m_bBinOnlyNotPassedAtoms) if (o->m_pLiDF[zr]->m_baDataEnabled[z4][z5] != 0) continue; o->m_pLiDF[zr]->m_pLiDF->AddToBin(o->m_pLiDF[zr]->m_faData[z4][z5]); } } } } else { for (z5=0;z5m_pLiDF[zr]->m_faData[0].GetSize();z5++) o->m_pLiDF[zr]->m_pLiDF->AddToBin(o->m_pLiDF[zr]->m_faData[0][z5]); } } // End IF LiDF } // FOR CDFChannels if (g_bCond && o->m_bCondDevelopment) { if (o->m_pConditions->m_bAnyPassed) o->m_iaCondDevelopmentCounter[0]++; for (z4=1;z4<=o->m_iCondDevelopmentMax;z4++) if (o->m_pConditions->m_iTempPassed == z4) o->m_iaCondDevelopmentCounter[z4]++; o->m_iCondDevelopmentAvg += o->m_pConditions->m_iTempPassed; } } // Ende FOR g_oaObserv.GetSize } // Ende IF [blabla] if (g_bMiddleAvg) // Referenzmolekuel mitteln { cc = 0; ti2 = (g_iSteps-2)*((CMolecule*)g_oaMolecules[g_iFixMol])->m_laSingleMolIndex.GetSize()+z2; // Jeden Atomtyp des Zielmolekuels durchgehen for (z3=0;z3<((CMolecule*)g_oaMolecules[g_iFixMol])->m_baAtomIndex.GetSize();z3++) { for (z4=0;z4<((CMolecule*)g_oaMolecules[g_iFixMol])->m_waAtomCount[z3];z4++) { // Atome vertauschen, aber nicht im allerersten Durchgang hier, und nur wenn mehr als 1 Atom dieser Sorte if ((g_iSwapAtoms) && (ti2 != 0) && (((CMolecule*)g_oaMolecules[g_iFixMol])->m_waAtomCount[z3]>1)) { vec4 = g_pRefMol[cc]; vec4 /= (double)ti2; // der bisherige Mittelwert des Referenzmolekuels tf = VecDist(g_pTempTimestep->m_vaCoords[((CxIntArray*)((CSingleMolecule*)g_oaSingleMolecules[((CMolecule*)g_oaMolecules[g_iFixMol])->m_laSingleMolIndex[z2]])->m_oaAtomOffset[z3])->GetAt(z4)],vec4); // der Abstand dieses Atoms von seinem Aequivalent im Referenzmolekuel ti3 = -1; for (z5=z4+1;z5<((CMolecule*)g_oaMolecules[g_iFixMol])->m_waAtomCount[z3];z5++) // Alle folgenden Atome dieser Sorte durchgehen { tf2 = VecDist(g_pTempTimestep->m_vaCoords[((CxIntArray*)((CSingleMolecule*)g_oaSingleMolecules[((CMolecule*)g_oaMolecules[g_iFixMol])->m_laSingleMolIndex[z2]])->m_oaAtomOffset[z3])->GetAt(z5)],vec4); if (tf2 < tf) // Das andere Atom ist naeher am Platz im Referenzmolekuel als das eigentlich vorgesehene { ti3 = z5; tf = tf2; } } if (ti3 != -1) // Ein Anderes ist naeher dran als unseres: Vertausche diese beiden { Swap(g_pTempTimestep->m_vaCoords[((CxIntArray*)((CSingleMolecule*)g_oaSingleMolecules[((CMolecule*)g_oaMolecules[g_iFixMol])->m_laSingleMolIndex[z2]])->m_oaAtomOffset[z3])->GetAt(z4)],g_pTempTimestep->m_vaCoords[((CxIntArray*)((CSingleMolecule*)g_oaSingleMolecules[((CMolecule*)g_oaMolecules[g_iFixMol])->m_laSingleMolIndex[z2]])->m_oaAtomOffset[z3])->GetAt(ti3)]); pSwapMatrix[cc*((CMolecule*)g_oaMolecules[g_iFixMol])->m_iAtomGes+(cc-z4+ti3)] += 1; pSwapMatrix[(cc-z4+ti3)*((CMolecule*)g_oaMolecules[g_iFixMol])->m_iAtomGes+cc] += 1; } } // Ende IF SwapAtoms g_pRefMol[cc] += g_pTempTimestep->m_vaCoords[((CxIntArray*)((CSingleMolecule*)g_oaSingleMolecules[((CMolecule*)g_oaMolecules[g_iFixMol])->m_laSingleMolIndex[z2]])->m_oaAtomOffset[z3])->GetAt(z4)]; cc++; } // Ende FOR Atom des Referenzmolekuels } // Ende FOR Atomtyp des Referenzmolekuels } // Ende IF Referenzmolekuel mitteln } // Ende FOR RefMol (z2) if (g_bCond) { for (z6=0;z6m_bCondDevelopment) { mfprintf(o->m_pCondDevelopment,"%lu; %d; %.6f; %.6f", g_iSteps, o->m_iaCondDevelopmentCounter[0], (double)o->m_iaCondDevelopmentCounter[0]/((CMolecule*)g_oaMolecules[g_iFixMol])->m_laSingleMolIndex.GetSize()*100.0, (double)o->m_iCondDevelopmentAvg/((CMolecule*)g_oaMolecules[g_iFixMol])->m_laSingleMolIndex.GetSize() ); for (z2=1;z2<=o->m_iCondDevelopmentMax;z2++) mfprintf(o->m_pCondDevelopment,"; %d; %.6f", o->m_iaCondDevelopmentCounter[z2], (double)o->m_iaCondDevelopmentCounter[z2]/((CMolecule*)g_oaMolecules[g_iFixMol])->m_laSingleMolIndex.GetSize()*100.0 ); mfprintf(o->m_pCondDevelopment,"\n"); } } } for (z6=0;z6m_pConditions != NULL) for (z2=0;z2<((CMolecule*)g_oaMolecules[o->m_iShowMol])->m_laSingleMolIndex.GetSize();z2++) if (o->m_pConditions->m_iPassCounter[z2] != 0) o->m_pConditions->m_iOMPassCounter[z2]++; if (o->m_pConditionsOM2 != NULL) for (z2=0;z2<((CMolecule*)g_oaMolecules[o->m_iShowMol])->m_laSingleMolIndex.GetSize();z2++) if (o->m_pConditionsOM2->m_iPassCounter[z2] != 0) o->m_pConditionsOM2->m_iOMPassCounter[z2]++; } //_end:; _endstep: _norefmol: if ((g_iMaxStep > 0) && ((int)g_iSteps >= g_iMaxStep)) { mprintf("\n\nMaximum step count of %d reached, stopping.",g_iMaxStep); break; } } // Ende while /************************************************************************* *************** Ende Hauptschleife *************************************** *************************************************************************/ // fclose(fff); _endmainloop: if (g_bUseVelocities || g_bUseForces) g_iSteps -= 2; mprintf(WHITE,"\n\n########## Analysis finished ##########\n"); if (g_iStride != 1) { if (g_iStride == 2) mprintf("\n%lu time steps processed (every %dnd from %lu).\n\n",g_iSteps/g_iStride,g_iStride,g_iSteps); else if (g_iStride == 3) mprintf("\n%lu time steps processed (every %drd from %lu).\n\n",g_iSteps/g_iStride,g_iStride,g_iSteps); else mprintf("\n%lu time steps processed (every %dth from %lu).\n\n",g_iSteps/g_iStride,g_iStride,g_iSteps); } else mprintf("\n%lu time steps processed.\n\n",g_iSteps); // fclose(g_fPos); CloseInputTrajectory(); if (g_fVel != NULL) fclose(g_fVel); if (g_fForce != NULL) fclose(g_fForce); if ((g_bNPT) && (g_sNPTFile[0] != 0)) fclose(g_fNPTFile); if (g_bDipole && g_bDumpDipoleVector) { fclose(g_fDumpDipole); mprintf(" Dipole vectors written to file \"dipole_vectors.csv\".\n"); if (g_bDumpDipoleXYZ) { fclose(g_fDumpDipoleXYZ); mprintf(" Dipole XYZ trajectory written to file \"dipole_vectors.xyz\".\n"); } mprintf("\n"); } /************ Interface **************/ Interface_AfterAnalysis(); if (g_bFixedPlProj) g_pFixedPlProj->Finish(); if (g_bDomA) g_pDomainEngine->Finish(); if (g_bVoro) g_pVoroWrapper->Finish(); g_bAbortAnalysis = true; if (g_bSaveCondSnapshot) { fclose(g_fSaveCondFile); mprintf("%d condition snapshots saved as savecondition.xyz\n\n",g_iSaveCondCount); } if (g_bOrder) g_pOrderEngine->Finish(); if (g_bBondACF) { mprintf(WHITE,"*** Bond autocorrelation function\n"); if (g_bBondACFDebug) { mprintf(" Writing \"bondacf.agr\"...\n"); try { gc = new CGrace(); } catch(...) { gc = NULL; } if (gc == NULL) NewException((double)sizeof(CGrace),__FILE__,__LINE__,__PRETTY_FUNCTION__); gc->SetRangeX(0,g_iSteps*g_fTimestepLength/1000.0); gc->SetRangeY(0,250); gc->MakeTicks(); gc->SetLabelX("Time [ps]"); gc->SetLabelY("Bond length [pm]"); for (z2=0;z2m_oaBonds.GetSize();z3++) { bond = (CMolBond*)sm->m_oaBonds[z3]; gc->AddDataset(); for (z4=0;z4m_faData.GetSize();z4++) gc->AddXYTupel(z4*g_fTimestepLength/1000.0,bond->m_faData[z4]); } } gc->WriteAgr("bondacf.agr",false); delete gc; } mprintf(" Differentiating bond length developments...\n"); for (z2=0;z2m_oaBonds.GetSize();z3++) { bond = (CMolBond*)sm->m_oaBonds[z3]; for (z4=0;z4m_faData.GetSize()-1;z4++) bond->m_faData[z4] = bond->m_faData[z4+1] - bond->m_faData[z4]; } } if (g_bBondACFDebug) { mprintf(" Writing \"bondacf_diff.agr\"...\n"); try { gc = new CGrace(); } catch(...) { gc = NULL; } if (gc == NULL) NewException((double)sizeof(CGrace),__FILE__,__LINE__,__PRETTY_FUNCTION__); gc->SetRangeX(0,g_iSteps*g_fTimestepLength/1000.0); gc->SetRangeY(-15,15); gc->MakeTicks(); gc->SetLabelX("Time [ps]"); gc->SetLabelY("Bond length change rate"); for (z2=0;z2m_oaBonds.GetSize();z3++) { bond = (CMolBond*)sm->m_oaBonds[z3]; gc->AddDataset(); for (z4=0;z4m_faData.GetSize();z4++) gc->AddXYTupel(z4*g_fTimestepLength/1000.0,bond->m_faData[z4]); } } gc->WriteAgr("bondacf_diff.agr",false); delete gc; } mprintf(" Autocorrelating bond length developments...\n"); mprintf(WHITE," ["); tfs = 0; for (z2=0;z2m_oaBonds.GetSize(); } tfs /= 60.0; ti2 = 0; /* fft = new CFFT(); fft->PrepareFFT_C2C(g_iSteps*2); fft2 = new CFFT(); fft2->PrepareInverseFFT_C2C(g_iSteps*2);*/ try { ac = new CAutoCorrelation(); } catch(...) { ac = NULL; } if (ac == NULL) NewException((double)sizeof(CAutoCorrelation),__FILE__,__LINE__,__PRETTY_FUNCTION__); ac->Init(g_iSteps,g_iBondACFDepth,g_bACFFFT); for (z2=0;z2m_oaBonds.GetSize();z3++) { if (fmod(ti2,tfs) < 1.0) mprintf(WHITE,"#"); bond = (CMolBond*)sm->m_oaBonds[z3]; ac->AutoCorrelate(&bond->m_faData,&tempfa); bond->m_faData.CopyFrom(&tempfa); ti2++; } } delete ac; mprintf(WHITE,"]\n"); if (g_bBondACFDebug) { mprintf(" Writing \"bondacf_autocorr.agr\"...\n"); try { gc = new CGrace(); } catch(...) { gc = NULL; } if (gc == NULL) NewException((double)sizeof(CGrace),__FILE__,__LINE__,__PRETTY_FUNCTION__); gc->SetRangeX(0,g_iBondACFDepth*g_fTimestepLength/1000.0); gc->SetRangeY(-25,25); gc->MakeTicks(); gc->SetLabelX("Time [ps]"); gc->SetLabelY("ACF(Bond length change rate)"); for (z2=0;z2m_oaBonds.GetSize();z3++) { bond = (CMolBond*)sm->m_oaBonds[z3]; gc->AddDataset(); for (z4=0;z4AddXYTupel(z4*g_fTimestepLength/1000.0,bond->m_faData[z4]); } } gc->WriteAgr("bondacf_autocorr.agr",false); delete gc; } mprintf(" Merging equivalent Bonds...\n"); for (z0=0;z0m_laSingleMolIndex[0]]; for (z2=0;z2m_laSingleMolIndex.GetSize();z2++) { sm = (CSingleMolecule*)g_oaSingleMolecules[m->m_laSingleMolIndex[z2]]; for (z3=0;z3m_oaBondGroups.GetSize();z3++) { bg = (CMolBondGroup*)sm->m_oaBondGroups[z3]; for (z4=1;z4m_oaBonds.GetSize();z4++) { bond = (CMolBond*)bg->m_oaBonds[z4]; for (z5=0;z5m_oaBondGroups[z3])->m_oaBonds[0])->m_faData[z5] += bond->m_faData[z5]; } } } } if (g_bBondACFSymmetrize) { mprintf(" Symmetrizing bond ACFs...\n"); for (z0=0;z0m_laSingleMolIndex[0]]; for (z3=0;z3m_oaBondGroups.GetSize();z3++) { bond = (CMolBond*)((CMolBondGroup*)sm->m_oaBondGroups[z3])->m_oaBonds[0]; bond->m_faData.SetSize(2*g_iBondACFDepth); for (z4=0;z4m_faData[z4+g_iBondACFDepth] = bond->m_faData[z4]; for (z4=0;z4m_faData[z4] = bond->m_faData[2*g_iBondACFDepth-z4-1]; } } g_iBondACFDepth *= 2; } if (g_bBondACFWindow) { mprintf(" Applying Window Function...\n"); for (z0=0;z0m_laSingleMolIndex[0]]; for (z3=0;z3m_oaBondGroups.GetSize();z3++) { bond = (CMolBond*)((CMolBondGroup*)sm->m_oaBondGroups[z3])->m_oaBonds[0]; for (z4=0;z4m_faData[z4] *= (double)pow2(sin(z4*Pi/(bond->m_faData.GetSize()-1))); } } } if (g_bBondACFNormalize) { mprintf(" Normalizing bond ACFs...\n"); for (z0=0;z0m_laSingleMolIndex[0]]; for (z3=0;z3m_oaBondGroups.GetSize();z3++) { bond = (CMolBond*)((CMolBondGroup*)sm->m_oaBondGroups[z3])->m_oaBonds[0]; tf = 0; for (z4=0;z4m_faData[z4]) tf = bond->m_faData[z4]; for (z4=0;z4m_faData[z4] /= (double)tf; } } } mprintf(" Writing \"bondacf_ac_merged.agr\"...\n"); try { gc = new CGrace(); } catch(...) { gc = NULL; } if (gc == NULL) NewException((double)sizeof(CGrace),__FILE__,__LINE__,__PRETTY_FUNCTION__); gc->SetRangeX(0,g_iBondACFDepth*g_fTimestepLength/1000.0); gc->SetRangeY(-200,200); gc->MakeTicks(); gc->SetLabelX("Time [ps]"); gc->SetLabelY("Sum ACF(Bond length change rate)"); gc->CurrentGraph()->m_bLegend = true; for (z0=0;z0m_laSingleMolIndex[0]]; for (z3=0;z3m_oaBondGroups.GetSize();z3++) { bond = (CMolBond*)((CMolBondGroup*)sm->m_oaBondGroups[z3])->m_oaBonds[0]; gc->AddDataset(); // sprintf(buf,"%s %s%d - %s%d",m->m_sName,((CAtom*)g_oaAtoms[sm->m_baAtomIndex[bond->m_iAtomType[0]]])->m_sName,bond->m_iAtom[0]+1,((CAtom*)g_oaAtoms[sm->m_baAtomIndex[bond->m_iAtomType[1]]])->m_sName,bond->m_iAtom[1]+1); buf.sprintf("%s %s%d - %s%d",m->m_sName,(const char*)((CAtom*)g_oaAtoms[sm->m_baAtomIndex[bond->m_iAtomType[0]]])->m_sName,bond->m_iAtom[0]+1,(const char*)((CAtom*)g_oaAtoms[sm->m_baAtomIndex[bond->m_iAtomType[1]]])->m_sName,bond->m_iAtom[1]+1); gc->SetDatasetName(buf); ((CGraceDataset*)gc->CurrentGraph()->m_oaDatasets[gc->CurrentGraph()->m_oaDatasets.GetSize()-1])->m_faValues.SetMaxSize(g_iBondACFDepth*2); for (z4=0;z4AddXYTupel(z4*g_fTimestepLength/1000.0,bond->m_faData[z4]); } } gc->WriteAgr("bondacf_ac_merged.agr",false); delete gc; mprintf(" Applying Fourier Transformation...\n"); try { fft = new CFFT(); } catch(...) { fft = NULL; } if (fft == NULL) NewException((double)sizeof(CFFT),__FILE__,__LINE__,__PRETTY_FUNCTION__); fft->PrepareFFT_C2C(g_iBondACFDepth); tf3 = 0; for (z0=0;z0m_laSingleMolIndex[0]]; for (z3=0;z3m_oaBondGroups.GetSize();z3++) { bond = (CMolBond*)((CMolBondGroup*)sm->m_oaBondGroups[z3])->m_oaBonds[0]; for (z4=0;z4m_pInput[z4*2] = bond->m_faData[z4]; fft->m_pInput[z4*2+1] = 0; } fft->DoFFT(); for (z4=0;z4m_faData[z4] = (double)(pow2(fft->m_pOutput[z4*2]) + pow2(fft->m_pOutput[z4*2+1])) / g_iBondACFDepth; if (bond->m_faData[z4] > tf3) tf3 = bond->m_faData[z4]; } } } delete fft; mprintf(" Writing \"bond_spectrum.agr\"...\n"); try { gc = new CGrace(); } catch(...) { gc = NULL; } if (gc == NULL) NewException((double)sizeof(CGrace),__FILE__,__LINE__,__PRETTY_FUNCTION__); gc->SetRangeX(0,4000.0); gc->SetRangeY(0,tf3*1.1); gc->MakeTicks(); gc->SetLabelX("Wave number [1/cm]"); gc->SetLabelY("Intensity"); gc->CurrentGraph()->m_bInvertXAxis = true; gc->CurrentGraph()->m_bLegend = true; for (z0=0;z0m_laSingleMolIndex[0]]; for (z3=0;z3m_oaBondGroups.GetSize();z3++) { bond = (CMolBond*)((CMolBondGroup*)sm->m_oaBondGroups[z3])->m_oaBonds[0]; gc->AddDataset(); // sprintf(buf,"%s %s%d - %s%d",m->m_sName,((CAtom*)g_oaAtoms[sm->m_baAtomIndex[bond->m_iAtomType[0]]])->m_sName,bond->m_iAtom[0]+1,((CAtom*)g_oaAtoms[sm->m_baAtomIndex[bond->m_iAtomType[1]]])->m_sName,bond->m_iAtom[1]+1); buf.sprintf("%s %s%d - %s%d",m->m_sName,(const char*)((CAtom*)g_oaAtoms[sm->m_baAtomIndex[bond->m_iAtomType[0]]])->m_sName,bond->m_iAtom[0]+1,(const char*)((CAtom*)g_oaAtoms[sm->m_baAtomIndex[bond->m_iAtomType[1]]])->m_sName,bond->m_iAtom[1]+1); gc->SetDatasetName(buf); ((CGraceDataset*)gc->CurrentGraph()->m_oaDatasets[gc->CurrentGraph()->m_oaDatasets.GetSize()-1])->m_faValues.SetMaxSize(g_iBondACFDepth*2); for (z4=0;z4AddXYTupel(z4*2.0/g_iBondACFDepth*1E7/299.792/2.0/g_fTimestepLength/g_iStride,bond->m_faData[z4]); } } gc->WriteAgr("bond_spectrum.agr",false); delete gc; for (z5=1;z5<5;z5++) { mprintf(" Smoothing spectrum, degree %d...\n",z5); mprintf(" Writing \"bond_spectrum_s%d.agr\"...\n",z5); try { gc = new CGrace(); } catch(...) { gc = NULL; } if (gc == NULL) NewException((double)sizeof(CGrace),__FILE__,__LINE__,__PRETTY_FUNCTION__); gc->SetRangeX(0,4000.0); gc->SetRangeY(0,tf3*1.1); gc->MakeTicks(); gc->SetLabelX("Wave number [1/cm]"); gc->SetLabelY("Intensity"); gc->CurrentGraph()->m_bInvertXAxis = true; gc->CurrentGraph()->m_bLegend = true; try { gc2 = new CGrace(); } catch(...) { gc2 = NULL; } if (gc2 == NULL) NewException((double)sizeof(CGrace),__FILE__,__LINE__,__PRETTY_FUNCTION__); gc2->SetRangeX(0,4000.0); gc2->SetRangeY(0,tf3*1.1); gc2->MakeTicks(); gc2->SetLabelX("Wave number [1/cm]"); gc2->SetLabelY("Intensity"); gc2->CurrentGraph()->m_bInvertXAxis = true; gc2->CurrentGraph()->m_bLegend = true; tempfa.SetSize(g_iBondACFDepth/2); tempfa2.SetSize(g_iBondACFDepth/2); for (z4=0;z4m_laSingleMolIndex[0]]; for (z3=0;z3m_oaBondGroups.GetSize();z3++) { bond = (CMolBond*)((CMolBondGroup*)sm->m_oaBondGroups[z3])->m_oaBonds[0]; for (z4=0;z4= g_iBondACFDepth/2)) continue; tf += bond->m_faData[z4+z6] / (pow2((double)z6)+1.0); tf2 += 1.0 / (pow2((double)z6)+1.0); } tempfa[z4] = (double)(tf / tf2); tempfa2[z4] += tempfa[z4]; } gc->AddDataset(); gc2->AddDataset(); // sprintf(buf,"%s %s%d - %s%d",m->m_sName,((CAtom*)g_oaAtoms[sm->m_baAtomIndex[bond->m_iAtomType[0]]])->m_sName,bond->m_iAtom[0]+1,((CAtom*)g_oaAtoms[sm->m_baAtomIndex[bond->m_iAtomType[1]]])->m_sName,bond->m_iAtom[1]+1); buf.sprintf("%s %s%d - %s%d",m->m_sName,(const char*)((CAtom*)g_oaAtoms[sm->m_baAtomIndex[bond->m_iAtomType[0]]])->m_sName,bond->m_iAtom[0]+1,(const char*)((CAtom*)g_oaAtoms[sm->m_baAtomIndex[bond->m_iAtomType[1]]])->m_sName,bond->m_iAtom[1]+1); gc->SetDatasetName(buf); gc2->SetDatasetName(buf); ((CGraceDataset*)gc->CurrentGraph()->m_oaDatasets[gc->CurrentGraph()->m_oaDatasets.GetSize()-1])->m_faValues.SetMaxSize(g_iBondACFDepth); ((CGraceDataset*)gc2->CurrentGraph()->m_oaDatasets[gc2->CurrentGraph()->m_oaDatasets.GetSize()-1])->m_faValues.SetMaxSize(g_iBondACFDepth); for (z4=0;z4AddXYTupel(z4*2.0/g_iBondACFDepth*1E7/299.792/2.0/g_fTimestepLength/g_iStride,tempfa[z4]); for (z4=0;z4AddXYTupel(z4*2.0/g_iBondACFDepth*1E7/299.792/2.0/g_fTimestepLength/g_iStride,tempfa2[z4]); } } // sprintf(buf,"bond_spectrum_s%d.agr",z5); buf.sprintf("bond_spectrum_s%d.agr",z5); gc->WriteAgr(buf,false); delete gc; mprintf(" Writing \"bond_spectrum_cumulative_s%d.agr\"...\n",z5); // sprintf(buf,"bond_spectrum_cumulative_s%d.agr",z5); buf.sprintf("bond_spectrum_cumulative_s%d.agr",z5); gc2->WriteAgr(buf,false); delete gc2; } } if (g_bSaveRefEnv) { fclose(g_fRefEnv); mprintf("\nTrajectory of reference molecule was saved as %s.\n",(const char*)g_sRefEnv); if (g_bTDO) { #ifdef TARGET_WINDOWS // sprintf(buf,"tdo_pymol_%s_%d%s.bat",((CMolecule*)g_oaMolecules[g_iFixMol])->m_sName,g_iSaveRefMol+1,multibuf); buf.sprintf("tdo_pymol_%s_%d%s.bat",((CMolecule*)g_oaMolecules[g_iFixMol])->m_sName,g_iSaveRefMol+1,multibuf); #else // sprintf(buf,"tdo_pymol_%s_%d%s.sh",((CMolecule*)g_oaMolecules[g_iFixMol])->m_sName,g_iSaveRefMol+1,multibuf); buf.sprintf("tdo_pymol_%s_%d%s.sh",((CMolecule*)g_oaMolecules[g_iFixMol])->m_sName,g_iSaveRefMol+1,multibuf); #endif mprintf("Saving TDO PyMol script as %s.\n",(const char*)buf); tfi = OpenFileWrite(buf,true); #ifdef TARGET_WINDOWS mfprintf(tfi,"pymolwin "); #else mfprintf(tfi,"pymol "); #endif for (z=0;zm_sName,g_iSaveRefMol+1,g_laTDOSteps[z],multibuf); mfprintf(tfi,"-d \"set sphere_scale,0.25\" "); mfprintf(tfi,"-d \"set stick_radius,0.17\" "); mfprintf(tfi,"-d \"set ray_trace_mode,1\" "); mfprintf(tfi,"-d \"set fog,0\" "); mfprintf(tfi,"-d \"set ray_trace_fog,0\" "); mfprintf(tfi,"-d \"set bg_rgb,(1,1,1)\" "); mfprintf(tfi,"-d \"set ray_shadow,0\" "); mfprintf(tfi,"-d \"set ray_shadows,0\" "); mfprintf(tfi,"-d \"set ray_interior_shadows,0\" "); mfprintf(tfi,"-d \"show sticks; show spheres\" "); for (z=0;zm_sName,z+1,((CAtom*)g_oaAtoms[z2])->m_pElement->ColorR((double)z/(g_laTDOSteps.GetSize()-1)*g_fTDOBleaching),((CAtom*)g_oaAtoms[z2])->m_pElement->ColorG((double)z/(g_laTDOSteps.GetSize()-1)*g_fTDOBleaching),((CAtom*)g_oaAtoms[z2])->m_pElement->ColorB((double)z/(g_laTDOSteps.GetSize()-1)*g_fTDOBleaching)); } } for (z=0;zm_sName,z+1,((CMolecule*)g_oaMolecules[g_iFixMol])->m_sName,g_iSaveRefMol+1,g_laTDOSteps[z],(const char*)((CAtom*)g_oaAtoms[z2])->m_sName); } } mfprintf(tfi,"\n"); fclose(tfi); #ifdef TARGET_LINUX buf.sprintf("chmod 755 tdo_pymol_%s_%d%s.sh",((CMolecule*)g_oaMolecules[g_iFixMol])->m_sName,g_iSaveRefMol+1,multibuf); mprintf("Executing \"%s\"...\n",(const char*)buf); (void)system(buf); #endif } } if (g_bCutCluster) { fclose(g_fRefEnv); mprintf("\nCluster trajectory was saved as %s.\n",(const char*)g_sRefEnv); } if (g_bSaveJustTraj) { fclose(g_fSaveJustTraj); /* strcpy(buf,g_sInputTraj); p = strrchr(buf,'.'); *p = 0; strcat(buf,multibuf); strcat(buf,".out.xyz");*/ // mprintf("\nProcessed output trajectory was saved as traj_out.xyz\n",buf); } if (g_bIRSpec && g_bGlobalIR) { mprintf(WHITE,"\n*** Global IR Spectrum\n"); g_pGlobalIR->Finish(multibuf); } if (g_bVACF && g_bGlobalVACF) { mprintf(WHITE,"\n*** Global velocity autocorrelation function\n"); if (g_pGlobalVACF->m_bDerivative) { mprintf(" Deriving velocities...\n"); mprintf(WHITE," ["); tfs = g_iGesAtomCount/60.0; ti = 0; for (z2=0;z2m_bExcludeR0 && (g_waAtomRealElement[z2] > 1000)) continue; ptfa = (CxDoubleArray*)g_pGlobalVACF->m_oaCache[ti]; for (z3=0;z3<(int)g_iSteps*3-3;z3++) (*ptfa)[z3] = (*ptfa)[z3+3] - (*ptfa)[z3]; ti++; } mprintf(WHITE,"]\n"); } if (g_bVACFCacheMode) { tfs = g_iGesAtomCount/60.0; /* if (g_bACFFFT) {*/ mprintf(" Autocorrelating cached vectors...\n"); mprintf(WHITE," ["); /* fft = new CFFT(); fft->PrepareFFT_C2C(2*g_iSteps); fft2 = new CFFT(); fft2->PrepareInverseFFT_C2C(2*g_iSteps);*/ try { ptfa2 = new CxDoubleArray("main():ptfa2"); } catch(...) { ptfa2 = NULL; } if (ptfa2 == NULL) NewException((double)sizeof(CxDoubleArray),__FILE__,__LINE__,__PRETTY_FUNCTION__); ptfa2->SetSize(g_iSteps); try { ptfa3 = new CxDoubleArray("main():ptfa3"); } catch(...) { ptfa3 = NULL; } if (ptfa3 == NULL) NewException((double)sizeof(CxDoubleArray),__FILE__,__LINE__,__PRETTY_FUNCTION__); ptfa3->SetSize(g_iSteps); try { ac = new CAutoCorrelation(); } catch(...) { ac = NULL; } if (ac == NULL) NewException((double)sizeof(CAutoCorrelation),__FILE__,__LINE__,__PRETTY_FUNCTION__); ac->Init(g_iSteps,g_pGlobalVACF->m_iSize,g_bACFFFT); ti = 0; for (z2=0;z2m_bExcludeR0 && (g_waAtomRealElement[z2] > 1000)) continue; ptfa = (CxDoubleArray*)g_pGlobalVACF->m_oaCache[ti]; if (g_pGlobalVACF->m_bMassWeight) tf = ((CAtom*)g_oaAtoms[g_waAtomRealElement[z2]])->m_pElement->m_fMass; else tf = 1.0; /* X */ for (z3=0;z3<(int)g_iSteps;z3++) (*ptfa2)[z3] = (*ptfa)[z3*3]; ac->AutoCorrelate(ptfa2,ptfa3); // mprintf("Global Atom %d X: %f + %f = %f.\n",z2+1,g_pGlobalVACF->m_pData[0],(*ptfa3)[0]*tf,g_pGlobalVACF->m_pData[0]+(*ptfa3)[0]*tf); for (z3=0;z3<(int)g_pGlobalVACF->m_iSize;z3++) g_pGlobalVACF->m_pData[z3] += (*ptfa3)[z3] * tf; /* Y */ for (z3=0;z3<(int)g_iSteps;z3++) (*ptfa2)[z3] = (*ptfa)[z3*3+1]; ac->AutoCorrelate(ptfa2,ptfa3); // mprintf("Global Atom %d Y: %f + %f = %f.\n",z2+1,g_pGlobalVACF->m_pData[0],(*ptfa3)[0]*tf,g_pGlobalVACF->m_pData[0]+(*ptfa3)[0]*tf); for (z3=0;z3<(int)g_pGlobalVACF->m_iSize;z3++) g_pGlobalVACF->m_pData[z3] += (*ptfa3)[z3] * tf; /* Z */ for (z3=0;z3<(int)g_iSteps;z3++) (*ptfa2)[z3] = (*ptfa)[z3*3+2]; ac->AutoCorrelate(ptfa2,ptfa3); // mprintf("Global Atom %d Z: %f + %f = %f.\n",z2+1,g_pGlobalVACF->m_pData[0],(*ptfa3)[0]*tf,g_pGlobalVACF->m_pData[0]+(*ptfa3)[0]*tf); for (z3=0;z3<(int)g_pGlobalVACF->m_iSize;z3++) g_pGlobalVACF->m_pData[z3] += (*ptfa3)[z3] * tf; ti++; } delete ac; delete ptfa2; delete ptfa3; /* delete fft2; delete fft;*/ /* } else { mprintf(" Autocorrelating cached vectors...\n"); mprintf(WHITE," ["); for (z2=0;z2m_oaCache[z2]; for (z3=0;z3m_iSize;z3+=g_pGlobalVACF->m_iStride) // Das ist das Tau { tf = 0; for (z4=0;z4<(int)g_iSteps-z3;z4++) // Das ist der Startpunkt tf += (*ptfa)[z4*3]*(*ptfa)[(z4+z3)*3] + (*ptfa)[z4*3+1]*(*ptfa)[(z4+z3)*3+1] + (*ptfa)[z4*3+2]*(*ptfa)[(z4+z3)*3+2]; g_pGlobalVACF->m_pData[z3/g_pGlobalVACF->m_iStride] += tf/(g_iSteps-z3); } } }*/ mprintf(WHITE,"]\n"); mprintf(" %d atoms, %lu time steps and %d correlation depths processed.\n",g_pGlobalVACF->m_oaCache.GetSize(),g_iSteps,g_pGlobalVACF->m_iSize); g_pGlobalVACF->MultiplyCached(1.0/g_iGesAtomCount); if (g_pGlobalVACF->m_bDecomposeModes) { tfs = g_iGesAtomCount*g_iGesAtomCount*3/60.0; mprintf(" Allocating cross-correlation matrix (%s)...\n",FormatBytes((double)sizeof(double)*g_pGlobalVACF->m_iSize*g_pGlobalVACF->m_iParticles*3*g_pGlobalVACF->m_iParticles*3)); g_pGlobalVACF->m_oaCCRMatrix.SetMaxSize(g_pGlobalVACF->m_iParticles*3*g_pGlobalVACF->m_iParticles*3); for (z2=0;z2m_iParticles*3;z2++) { for (z3=0;z3m_iParticles*3;z3++) { // mprintf("X: %X\n",g_pGlobalVACF); // mprintf("%d - %d -->\n",z2,z3); try { ptfa = new CxDoubleArray("main():ptfa"); } catch(...) { ptfa = NULL; } if (ptfa == NULL) NewException((double)sizeof(CxDoubleArray),__FILE__,__LINE__,__PRETTY_FUNCTION__); // mprintf("A\n"); ptfa->SetSize(g_pGlobalVACF->m_iSize); // mprintf("B\n"); // mprintf("X2: %X\n",g_pGlobalVACF); g_pGlobalVACF->m_oaCCRMatrix.Add(ptfa); // mprintf("%d - %d <--\n",z2,z3); } } mprintf(" Computing %d cross-correlations...\n",g_pGlobalVACF->m_iParticles*3*g_pGlobalVACF->m_iParticles*3); mprintf(WHITE," ["); try { ptfa2 = new CxDoubleArray("main():ptfa2"); } catch(...) { ptfa2 = NULL; } if (ptfa2 == NULL) NewException((double)sizeof(CxDoubleArray),__FILE__,__LINE__,__PRETTY_FUNCTION__); ptfa2->SetSize(g_iSteps); try { ptfa2b = new CxDoubleArray("main():ptfa2b"); } catch(...) { ptfa2b = NULL; } if (ptfa2b == NULL) NewException((double)sizeof(CxDoubleArray),__FILE__,__LINE__,__PRETTY_FUNCTION__); ptfa2b->SetSize(g_iSteps); try { ccr = new CCrossCorrelation(); } catch(...) { ccr = NULL; } if (ccr == NULL) NewException((double)sizeof(CCrossCorrelation),__FILE__,__LINE__,__PRETTY_FUNCTION__); ccr->Init(g_iSteps,g_pGlobalVACF->m_iSize,g_bACFFFT); ti = 0; for (z2=0;z2m_bExcludeR0 && (g_waAtomRealElement[z2] > 1000)) continue; ptfa = (CxDoubleArray*)g_pGlobalVACF->m_oaCache[ti]; for (z2b=0;z2b<3;z2b++) { ti2 = 0; for (z3=0;z3m_bExcludeR0 && (g_waAtomRealElement[z3] > 1000)) continue; ptfab = (CxDoubleArray*)g_pGlobalVACF->m_oaCache[ti2]; if (g_pGlobalVACF->m_bMassWeight) tf = ((CAtom*)g_oaAtoms[g_waAtomRealElement[z2]])->m_pElement->m_fMass; else tf = 1.0; for (z3b=0;z3b<3;z3b++) { for (z4=0;z4<(int)g_iSteps;z4++) { (*ptfa2)[z4] = (*ptfa)[z4*3+z2b]; (*ptfa2b)[z4] = (*ptfab)[z4*3+z3b]; } ccr->CrossCorrelate(ptfa2,ptfa2b,(CxDoubleArray*)g_pGlobalVACF->m_oaCCRMatrix[ti*g_pGlobalVACF->m_iParticles*9 + z2b*g_pGlobalVACF->m_iParticles*3 + ti2*3 + z3b]); // mprintf("z2=%d, z2b=%d, z3=%d, z3b=%d, I=%d\n",z2,z2b,z3,z3b,ti*g_pGlobalVACF->m_iParticles*9 + z2b*g_pGlobalVACF->m_iParticles*3 + ti2*3 + z3b); } ti2++; } } ti++; } delete ccr; delete ptfa2; delete ptfa2b; mprintf(WHITE,"]\n"); /* for (z2=0;z2m_iParticles*3;z2++) { for (z3=0;z3m_iParticles*3;z3++) mprintf("%6G ",((CxFloatArray*)g_pGlobalVACF->m_oaCCRMatrix[z2*g_pGlobalVACF->m_iParticles*3+z3])->GetAt(0)); mprintf("\n"); }*/ Interface_DecomposeModes(g_pGlobalVACF->m_iParticles*3, &g_pGlobalVACF->m_oaCCRMatrix); } // END IF m_bDecomposeModes } else g_pGlobalVACF->Multiply(1.0/g_iGesAtomCount); mprintf(" Saving global VACF as acf_global%s.csv ...\n",multibuf); g_pGlobalVACF->WriteACF("acf_global",multibuf,".csv"); if (g_pGlobalVACF->m_iMirror != 0) { mprintf(" Mirroring global VACF...\n"); g_pGlobalVACF->Mirror(g_pGlobalVACF->m_iMirror); mprintf(" Saving mirrored global VACF as acf_global.m%s.csv ...\n",multibuf); g_pGlobalVACF->WriteACF("acf_global.m",multibuf,".csv"); } if (g_pGlobalVACF->m_bWindowFunction) { mprintf(" Applying window function...\n"); g_pGlobalVACF->Window(); mprintf(" Saving windowed global VACF as acf_global.w%s.csv ...\n",multibuf); g_pGlobalVACF->WriteACF("acf_global.w",multibuf,".csv"); } if (g_pGlobalVACF->m_bSpectrum) { mprintf(" Performing Fourier transformation...\n"); try { g_pFFT = new CFFT(); } catch(...) { g_pFFT = NULL; } if (g_pFFT == NULL) NewException((double)sizeof(CFFT),__FILE__,__LINE__,__PRETTY_FUNCTION__); g_pFFT->PrepareFFT_C2C(g_pGlobalVACF->m_iSize+g_pGlobalVACF->m_iZeroPadding); g_pGlobalVACF->Transform(g_pFFT); delete g_pFFT; g_pGlobalVACF->m_pSpectrum->SetMaxRWL(1E7/299.792/g_fTimestepLength/g_iStride); if (g_pGlobalVACF->m_bACF_DB) { mprintf(" Normalising spectrum to decibel...\n"); g_pGlobalVACF->m_pSpectrum->MakeDB(); }/* else { mprintf(" Normalising integral of spectrum...\n"); g_pGlobalVACF->m_pSpectrum->SetIntegral(1000000.0f); }*/ if (g_pGlobalVACF->m_bWindowFunction) { mprintf(" Saving spectrum as power_global_w%s.csv ...\n",multibuf); g_pGlobalVACF->m_pSpectrum->Write("power_global_w",multibuf,".csv"); } else { mprintf(" Saving spectrum as power_global%s.csv ...\n",multibuf); g_pGlobalVACF->m_pSpectrum->Write("power_global",multibuf,".csv"); } } mprintf("\n"); } if (g_bVFDF) { for (z=0;z>> Observation %d >>>\n",z+1); if (o->m_pConditions != NULL) { if (o->m_bSecondShowMol) mprintf(WHITE,"\n#### Condition between RM and 1st OM ####\n"); o->m_pConditions->PrintData(); if (o->m_pConditions->m_oaConditionSubGroups.GetSize()==2) o->m_pConditions->PrintTable(); } if ((o->m_bSecondShowMol) && (o->m_pConditionsOM2 != NULL)) { mprintf(WHITE,"\n\n#### Condition between RM and 2nd OM ####\n"); o->m_pConditionsOM2->PrintData(); if (o->m_pConditionsOM2->m_oaConditionSubGroups.GetSize()==2) o->m_pConditionsOM2->PrintTable(); } if (g_bCond && o->m_bCondDevelopment) { buf.sprintf("cond_%d_%s_%s.csv",z+1,((CMolecule*)g_oaMolecules[g_iFixMol])->m_sName,((CMolecule*)g_oaMolecules[o->m_iShowMol])->m_sName); mprintf("\n Closing Condition Temporal Development File \"%s\"...\n",(const char*)buf); fclose(o->m_pCondDevelopment); } if (g_bAggregation) { mprintf(WHITE,"\n* Aggregation Functions\n"); if ((g_iMaxStep > 0) && (((int)g_iSteps*g_iStride) >= g_iMaxStep)) g_pTempTimestep->CopyFrom(GetTimeStep(0)); // Max. Schrittzahl else g_pTempTimestep->CopyFrom(GetTimeStep(1)); // End Of File if (g_bDACF) { if (o->m_pDACF->m_iDACFRes >= (int)g_iSteps) { mprintf("\n"); mprintf(RED," Warning: "); mprintf("Requested ACF depth (%d) is larger than number of processed time steps (%lu).\n",o->m_pDACF->m_iDACFRes,g_iSteps); mprintf(" Reducing ACF depth to %lu.\n\n",g_iSteps-1); o->m_pDACF->m_iDACFRes = (int)g_iSteps-1; for (z2=0;z2m_pDACF->m_oaSubDACFs.GetSize();z2++) { ((CDACFSub*)o->m_pDACF->m_oaSubDACFs[z2])->m_pDACF->m_iResolution = o->m_pDACF->m_iDACFRes; ((CDACFSub*)o->m_pDACF->m_oaSubDACFs[z2])->m_pDACF->m_fMaxVal = o->m_pDACF->m_iDACFRes * g_fTimestepLength / 1000.0; } } } for (zs=0;zsm_pDACF->m_oaSubDACFs.GetSize();zs++) { dacfsub = (CDACFSub*)o->m_pDACF->m_oaSubDACFs[zs]; mprintf(WHITE,"\n > Value Set %d: %s\n",zs+1,dacfsub->m_sName); o->m_pDACF->FinishDACFSub(g_pTempTimestep,dacfsub); // sprintf(buf,"cond_%s.txt",dacfsub->m_sName); buf.sprintf("cond_%s.txt",dacfsub->m_sName); dacfsub->m_pCondition->PrintData(buf); mprintf(WHITE,"Neighbour Count Distribution\n"); mprintf(" %.0f Bin entries have been made.\n",dacfsub->m_pNDF->m_fBinEntries); // sprintf(buf,"ncd_%s%s.csv",dacfsub->m_sName,multibuf); buf.sprintf("ncd_%s%s.csv",dacfsub->m_sName,multibuf); mprintf(" Writing Neighbor Count Distribution File \"%s\"...\n",(const char*)buf); dacfsub->m_pNDF->Write_Int("",buf,""); if (g_bDDisp) { mprintf(WHITE,"\nDimer Displacement Distribution Function\n"); mprintf(" %.0f Bin entries have been made (%.0f skipped, %.0f total).\n",dacfsub->m_pDDisp->m_fBinEntries,dacfsub->m_pDDisp->m_fSkipEntries,dacfsub->m_pDDisp->m_fBinEntries+dacfsub->m_pDDisp->m_fSkipEntries); // sprintf(buf,"ddisp_%s%s.csv",dacfsub->m_sName,multibuf); buf.sprintf("ddisp_%s%s.csv",dacfsub->m_sName,multibuf); mprintf(" Saving DDisp File as \"%s\"...\n",(const char*)buf); dacfsub->m_pDDisp->Write("",buf,"",false); // sprintf(buf,"ddisp_%s%s.agr",dacfsub->m_sName,multibuf); buf.sprintf("ddisp_%s%s.agr",dacfsub->m_sName,multibuf); mprintf(" Saving DDisp Agr File as \"%s\"...\n",(const char*)buf); dacfsub->m_pDDisp->WriteAgr("",buf,"","",false); } if (g_bDACF) { mprintf(WHITE,"\nDimer Existence Autocorrelation Function\n"); // mprintf(" %.0f Bin entries have been made (%.0f skipped, %.0f total).\n",dacfsub->m_pDACF->m_fBinEntries,dacfsub->m_pDACF->m_fSkipEntries,dacfsub->m_pDACF->m_fBinEntries+dacfsub->m_pDACF->m_fSkipEntries); /* if (dacfsub->m_bBorderMode) { mprintf(" *** New Border Mode ***\n"); for (z2=0;z2m_pDACF->m_iDACFRes;z2++) dacfsub->m_pDACF->m_pBin[z2] /= g_iSteps-z2; } else { for (z2=0;z2m_pDACF->m_iDACFRes;z2++) dacfsub->m_pDACF->m_pBin[z2] /= g_iSteps; }*/ if (dacfsub->m_bIntermittend) { mprintf(" Autocorrelating reconstructed time series...\n"); mprintf(WHITE," ["); tfs = ((CMolecule*)g_oaMolecules[o->m_pDACF->m_iFirstMol])->m_laSingleMolIndex.GetSize() * ((CMolecule*)g_oaMolecules[o->m_pDACF->m_iSecondMol])->m_laSingleMolIndex.GetSize() / 60.0; ptfa = new CxDoubleArray(); ptfa2 = new CxDoubleArray(); ac = new CAutoCorrelation(); ac->Init(g_iSteps,o->m_pDACF->m_iDACFRes,true); ptfa->SetSize(g_iSteps); ptfa2->SetSize(o->m_pDACF->m_iDACFRes); for (z2=0;z2m_pDACF->m_iDACFRes;z2++) dacfsub->m_pDACF->m_pBin[z2] = 0; ti = 0; ti2 = 0; for (z2=0;z2<((CMolecule*)g_oaMolecules[o->m_pDACF->m_iFirstMol])->m_laSingleMolIndex.GetSize();z2++) { for (z3=0;z3<((CMolecule*)g_oaMolecules[o->m_pDACF->m_iSecondMol])->m_laSingleMolIndex.GetSize();z3++) { if (fmod(z2*((CMolecule*)g_oaMolecules[o->m_pDACF->m_iSecondMol])->m_laSingleMolIndex.GetSize()+z3,tfs) < 1.0) mprintf(WHITE,"#"); if (dacfsub->m_piaIntervals[z2*((CMolecule*)g_oaMolecules[o->m_pDACF->m_iSecondMol])->m_laSingleMolIndex.GetSize()+z3].GetSize() == 0) continue; // mprintf("*** %d <-> %d ***\n",z2,z3); for (z5=0;z5<(int)g_iSteps;z5++) (*ptfa)[z5] = 0; ti++; for (z4=0;z4m_piaIntervals[z2*((CMolecule*)g_oaMolecules[o->m_pDACF->m_iSecondMol])->m_laSingleMolIndex.GetSize()+z3].GetSize();z4+=2) { ti2++; for (z5=dacfsub->m_piaIntervals[z2*((CMolecule*)g_oaMolecules[o->m_pDACF->m_iSecondMol])->m_laSingleMolIndex.GetSize()+z3].GetAt(z4);z5<=dacfsub->m_piaIntervals[z2*((CMolecule*)g_oaMolecules[o->m_pDACF->m_iSecondMol])->m_laSingleMolIndex.GetSize()+z3].GetAt(z4+1);z5++) (*ptfa)[z5-1] = 1; } // if (dacfsub->m_piaIntervals[z2*((CMolecule*)g_oaMolecules[o->m_pDACF->m_iSecondMol])->m_laSingleMolIndex.GetSize()+z3].GetSize() != 0) // mprintf("\n%d-%d: %d ",z2,z3,dacfsub->m_piaIntervals[z2*((CMolecule*)g_oaMolecules[o->m_pDACF->m_iSecondMol])->m_laSingleMolIndex.GetSize()+z3].GetSize()/2); ac->AutoCorrelate(ptfa,ptfa2); /* if ((z2==0) && (z3==28)) { FILE *tfia; sprintf(buf,"condfunc_%d_%d.csv",z2,z3); tfia = fopen(buf,"wt"); for (z4=0;z4<(int)g_iSteps;z4++) fprintf(tfia,"%d; %f\n",z4,(*ptfa)[z4]); fclose(tfia); sprintf(buf,"condacf_%d_%d.csv",z2,z3); tfia = fopen(buf,"wt"); for (z4=0;z4m_pDACF->m_iDACFRes;z4++) fprintf(tfia,"%d; %f\n",z4,(*ptfa2)[z4]); fclose(tfia); }*/ for (z4=0;z4m_pDACF->m_iDACFRes;z4++) dacfsub->m_pDACF->m_pBin[z4] += (*ptfa2)[z4]; } } mprintf(WHITE,"]\n"); mprintf(" %d pairs and %d intervals processed.\n",ti,ti2); } if (dacfsub->m_bCorrectEq) { if (dacfsub->m_iRefMol == dacfsub->m_iShowMol) { tf = 100.0*dacfsub->m_fEqCounter/g_iSteps/(((CMolecule*)g_oaMolecules[dacfsub->m_iRefMol])->m_laSingleMolIndex.GetSize()-1)/((CMolecule*)g_oaMolecules[dacfsub->m_iRefMol])->m_laSingleMolIndex.GetSize(); mprintf(" Finite-size ensemble average is %.6f%c.\n",tf,'%'); tf = 1.0/(((CMolecule*)g_oaMolecules[dacfsub->m_iRefMol])->m_laSingleMolIndex.GetSize()-1)/((CMolecule*)g_oaMolecules[dacfsub->m_iRefMol])->m_laSingleMolIndex.GetSize(); dacfsub->m_pDACF->MultiplyBin(tf); tf = dacfsub->m_fEqCounter/g_iSteps/(((CMolecule*)g_oaMolecules[dacfsub->m_iRefMol])->m_laSingleMolIndex.GetSize()-1)/((CMolecule*)g_oaMolecules[dacfsub->m_iRefMol])->m_laSingleMolIndex.GetSize(); tf = tf*tf; mprintf(" Subtracting squared average value (%G - %G)...\n",dacfsub->m_pDACF->m_pBin[0],tf); dacfsub->m_pDACF->SubtractBin(tf); } else { tf = 100.0*dacfsub->m_fEqCounter/g_iSteps/((CMolecule*)g_oaMolecules[dacfsub->m_iRefMol])->m_laSingleMolIndex.GetSize()/((CMolecule*)g_oaMolecules[dacfsub->m_iShowMol])->m_laSingleMolIndex.GetSize(); mprintf(" Finite-size ensemble average is %.6f%c.\n",tf,'%'); tf = 1.0/((CMolecule*)g_oaMolecules[dacfsub->m_iRefMol])->m_laSingleMolIndex.GetSize()/((CMolecule*)g_oaMolecules[dacfsub->m_iShowMol])->m_laSingleMolIndex.GetSize(); dacfsub->m_pDACF->MultiplyBin(tf); tf = dacfsub->m_fEqCounter/g_iSteps/((CMolecule*)g_oaMolecules[dacfsub->m_iRefMol])->m_laSingleMolIndex.GetSize()/((CMolecule*)g_oaMolecules[dacfsub->m_iShowMol])->m_laSingleMolIndex.GetSize(); tf = tf*tf; mprintf(" Subtracting squared average value (%G - %G)...\n",dacfsub->m_pDACF->m_pBin[0],tf); dacfsub->m_pDACF->SubtractBin(tf); } } if (dacfsub->m_pDACF->m_pBin[0] != 0) { mprintf(" Normalizing ACF with factor %G ...\n",1.0/dacfsub->m_pDACF->m_pBin[0]); dacfsub->m_pDACF->MultiplyBin(1.0/dacfsub->m_pDACF->m_pBin[0]); } else mprintf(" Warning: Not normalizing this DACF, first entry is 0.\n"); if (o->m_pDACF->m_bFitDACF) { mprintf("\n"); try { dacfsub->m_pDACF->m_pParameters = new double*[o->m_pDACF->m_iFitDegreeMax+1]; } catch(...) { dacfsub->m_pDACF->m_pParameters = NULL; } if (dacfsub->m_pDACF->m_pParameters == NULL) NewException((double)(o->m_pDACF->m_iFitDegreeMax+1)*sizeof(double*),__FILE__,__LINE__,__PRETTY_FUNCTION__); try { dacfsub->m_pDACF->m_pFitIntegral = new double[o->m_pDACF->m_iFitDegreeMax+1]; } catch(...) { dacfsub->m_pDACF->m_pFitIntegral = NULL; } if (dacfsub->m_pDACF->m_pFitIntegral == NULL) NewException((double)(o->m_pDACF->m_iFitDegreeMax+1)*sizeof(double),__FILE__,__LINE__,__PRETTY_FUNCTION__); try { dacfsub->m_pDACF->m_pCorrCoeff = new double[o->m_pDACF->m_iFitDegreeMax+1]; } catch(...) { dacfsub->m_pDACF->m_pCorrCoeff = NULL; } if (dacfsub->m_pDACF->m_pCorrCoeff == NULL) NewException((double)(o->m_pDACF->m_iFitDegreeMax+1)*sizeof(double),__FILE__,__LINE__,__PRETTY_FUNCTION__); try { dacfsub->m_pDACF->m_pAdditionalSets = new double*[o->m_pDACF->m_iFitDegreeMax+1]; } catch(...) { dacfsub->m_pDACF->m_pAdditionalSets = NULL; } if (dacfsub->m_pDACF->m_pAdditionalSets == NULL) NewException((double)(o->m_pDACF->m_iFitDegreeMax+1)*sizeof(double*),__FILE__,__LINE__,__PRETTY_FUNCTION__); try { dacfsub->m_pDACF->m_pAdditionalSetLabels = new char*[o->m_pDACF->m_iFitDegreeMax+1]; } catch(...) { dacfsub->m_pDACF->m_pAdditionalSetLabels = NULL; } if (dacfsub->m_pDACF->m_pAdditionalSetLabels == NULL) NewException((double)(o->m_pDACF->m_iFitDegreeMax+1)*sizeof(char*),__FILE__,__LINE__,__PRETTY_FUNCTION__); dacfsub->m_pDACF->m_iAdditionalSets = o->m_pDACF->m_iFitDegreeMax+1; for (z2=0;z2<=o->m_pDACF->m_iFitDegreeMax;z2++) { dacfsub->m_pDACF->m_pAdditionalSets[z2] = NULL; dacfsub->m_pDACF->m_pAdditionalSetLabels[z2] = NULL; } mprintf(YELLOW," Please note: "); mprintf("The lifetime is two times the integral value!\n\n"); for (z2=o->m_pDACF->m_iFitDegreeMin;z2<=o->m_pDACF->m_iFitDegreeMax;z2++) dacfsub->m_pDACF->Fit_PolyExp(z2,100); if (o->m_pDACF->m_iFitDegreeMin != o->m_pDACF->m_iFitDegreeMax) { mprintf(YELLOW," DACF fit integral overview:\n"); mprintf(" (use the row with the highest R value)\n\n"); mprintf(WHITE," Degree R Integral [ps] Lifetime [ps]\n"); for (z2=o->m_pDACF->m_iFitDegreeMin;z2<=o->m_pDACF->m_iFitDegreeMax;z2++) { if (dacfsub->m_pDACF->m_pFitIntegral[z2] >= 0) mprintf(" %d %10.8f %-10G %-10G\n",z2,dacfsub->m_pDACF->m_pCorrCoeff[z2],dacfsub->m_pDACF->m_pFitIntegral[z2],dacfsub->m_pDACF->m_pFitIntegral[z2]*2.0); else mprintf(" %d %10.8f - -\n",z2,dacfsub->m_pDACF->m_pCorrCoeff[z2]); } mprintf("\n"); } } // sprintf(buf,"dacf_%s%s.csv",dacfsub->m_sName,multibuf); buf.sprintf("dacf_%s%s.csv",dacfsub->m_sName,multibuf); mprintf(" Saving DACF File as \"%s\"...\n",(const char*)buf); dacfsub->m_pDACF->Write("",buf,"",false); // sprintf(buf,"dacf_%s%s.agr",dacfsub->m_sName,multibuf); buf.sprintf("dacf_%s%s.agr",dacfsub->m_sName,multibuf); mprintf(" Saving DACF Agr File as \"%s\"...\n",(const char*)buf); dacfsub->m_pDACF->WriteAgr("",buf,"","",false); } if (g_bDLDF) { mprintf(WHITE,"\nDimer Lifetime Distribution Function\n"); mprintf(" %.0f Bin entries have been made (%.0f skipped, %.0f total).\n",dacfsub->m_pDLDF->m_fBinEntries,dacfsub->m_pDLDF->m_fSkipEntries,dacfsub->m_pDLDF->m_fBinEntries+dacfsub->m_pDLDF->m_fSkipEntries); // sprintf(buf,"dldf_%s%s.csv",dacfsub->m_sName,multibuf); buf.sprintf("dldf_%s%s.csv",dacfsub->m_sName,multibuf); mprintf(" Saving DLDF File as \"%s\"...\n",(const char*)buf); dacfsub->m_pDLDF->Write("",buf,"",false); // sprintf(buf,"dldf_%s%s.agr",dacfsub->m_sName,multibuf); buf.sprintf("dldf_%s%s.agr",dacfsub->m_sName,multibuf); mprintf(" Saving DLDF Agr File as \"%s\"...\n",(const char*)buf); dacfsub->m_pDLDF->WriteAgr("",buf,"","",false); } if (g_bDLDisp) { mprintf(WHITE,"\nDimer Lifetime Displacement Distribution Function\n"); mprintf(" %.0f Bin entries have been made (%.0f skipped, %.0f total).\n",dacfsub->m_pDLDisp->m_fBinEntries,dacfsub->m_pDLDisp->m_fSkipEntries,dacfsub->m_pDLDisp->m_fBinEntries+dacfsub->m_pDLDisp->m_fSkipEntries); mprintf(" Normalizing bin integral to 1000000...\n"); dacfsub->m_pDLDisp->NormalizeBinIntegral(1000000.0); // sprintf(buf,"dldisp_%s%s",dacfsub->m_sName,multibuf); buf.sprintf("dldisp_%s%s",dacfsub->m_sName,multibuf); mprintf(" Saving DLDisp triples as \"%s_triples.csv\"...\n",(const char*)buf); dacfsub->m_pDLDisp->Write("",buf,"_triples.csv"); mprintf(" Saving DLDisp matrix as \"%s_matrix.csv\"...\n",(const char*)buf); dacfsub->m_pDLDisp->WriteCSV("",buf,"_matrix.csv"); mprintf(" Saving DLDisp Mathematica Notebook \"%s.nb\"...\n",(const char*)buf); dacfsub->m_pDLDisp->WriteMathematicaNb("",buf,".nb",false); mprintf(" Saving DLDisp Gnuplot Input \"%s.gp\"...\n",(const char*)buf); dacfsub->m_pDLDisp->WriteGnuplotInput("",buf,"",false); } if (g_bPairMSD) { mprintf(WHITE,"\nPair Mean Square Displacement\n"); mprintf(" %.0f Bin entries have been made.\n",dacfsub->m_pPairMSD->m_fBinEntries); mprintf(" Calculating average values...\n"); dacfsub->m_pPairMSD->BuildAverage(); // sprintf(buf,"pairmsd_%s%s",dacfsub->m_sName,multibuf); buf.sprintf("pairmsd_%s%s",dacfsub->m_sName,multibuf); mprintf(" Saving Pair MSD as \"%s.csv\"...\n",(const char*)buf); dacfsub->m_pPairMSD->Write("",buf,".csv"); } } if (o->m_pDACF->m_bDACFGrid && o->m_pDACF->m_bFitDACF) { mprintf(WHITE,"\n*** Condition Grid fitting overview:\n\n"); mprintf(" Degree R(min) R(avg) R(max)\n"); o->m_pDACF->CalcGridFitParms(); for (z2=o->m_pDACF->m_iFitDegreeMin;z2<=o->m_pDACF->m_iFitDegreeMax;z2++) mprintf(" %d %10.8f %10.8f %10.8f\n",z2,o->m_pDACF->m_pFitRMin[z2],o->m_pDACF->m_pFitRAvg[z2],o->m_pDACF->m_pFitRMax[z2]); mprintf("\n"); for (z2=o->m_pDACF->m_iFitDegreeMin;z2<=o->m_pDACF->m_iFitDegreeMax;z2++) { if ((o->m_pDACF->m_iGridMode == 3) || (o->m_pDACF->m_iGridMode == 5)) { if (o->m_pDACF->m_bGridCon) { try { temp2df = new C2DF(); } catch(...) { temp2df = NULL; } if (temp2df == NULL) NewException((double)sizeof(C2DF),__FILE__,__LINE__,__PRETTY_FUNCTION__); o->m_pDACF->CreateGridFit2DF(temp2df,z2,false); // sprintf(buf,"dacf_gridint_%s%s_%dexp",o->m_pDACF->m_sName,multibuf,z2); buf.sprintf("dacf_gridint_%s%s_%dexp",o->m_pDACF->m_sName,multibuf,z2); mprintf(" Saving Grid Integral triples as \"%s_triples.csv\"...\n",(const char*)buf); temp2df->Write("",buf,"_triples.csv"); mprintf(" Saving Grid Integral matrix as \"%s_matrix.csv\"...\n",(const char*)buf); temp2df->WriteCSV("",buf,"_matrix.csv"); mprintf(" Saving Grid Integral Mathematica Notebook \"%s.nb\"...\n",(const char*)buf); temp2df->WriteMathematicaNb("",buf,".nb",false); mprintf(" Saving Grid Integral Gnuplot Input \"%s.gp\"...\n",(const char*)buf); temp2df->WriteGnuplotInput("",buf,"",false); delete temp2df; } if (o->m_pDACF->m_bGridInt) { try { temp2df = new C2DF(); } catch(...) { temp2df = NULL; } if (temp2df == NULL) NewException((double)sizeof(C2DF),__FILE__,__LINE__,__PRETTY_FUNCTION__); o->m_pDACF->CreateGridFit2DF(temp2df,z2,true); // sprintf(buf,"dacf_gridint_%s%s_%dexp_int%.2f",o->m_pDACF->m_sName,multibuf,z2,o->m_pDACF->m_fGridIntGap); buf.sprintf("dacf_gridint_%s%s_%dexp_int%.2f",o->m_pDACF->m_sName,multibuf,z2,o->m_pDACF->m_fGridIntGap); mprintf(" Saving Grid Integral triples as \"%s_triples.csv\"...\n",(const char*)buf); temp2df->Write("",buf,"_triples.csv"); mprintf(" Saving Grid Integral matrix as \"%s_matrix.csv\"...\n",(const char*)buf); temp2df->WriteCSV("",buf,"_matrix.csv"); mprintf(" Saving Grid Integral Mathematica Notebook \"%s.nb\"...\n",(const char*)buf); temp2df->WriteMathematicaNb("",buf,".nb",false); mprintf(" Saving Grid Integral Gnuplot Input \"%s.gp\"...\n",(const char*)buf); temp2df->WriteGnuplotInput("",buf,"",false); delete temp2df; } } else { if (o->m_pDACF->m_bGridCon) { try { tdf = new CDF(); } catch(...) { tdf = NULL; } if (tdf == NULL) NewException((double)sizeof(CDF),__FILE__,__LINE__,__PRETTY_FUNCTION__); // o->m_pDACF->CreateGridFitDF(tdf,z2,false); eprintf("Internal abort call.\n"); delete tdf; abort(); } } } } } // END IF AGGREGATION if (g_bDens) { mprintf(WHITE,"\n* Density Distribution Function\n"); mprintf(" %.0f bin entries, %.0f out of bin range (%.2f percent).\n",o->m_pDensityDF->m_pDensDF->m_fBinEntries,o->m_pDensityDF->m_pDensDF->m_fSkipEntries,ZeroDivide(o->m_pDensityDF->m_pDensDF->m_fSkipEntries,o->m_pDensityDF->m_pDensDF->m_fBinEntries+o->m_pDensityDF->m_pDensDF->m_fSkipEntries)*100.0); mprintf(" Correcting radial distribution...\n"); o->m_pDensityDF->m_pDensDF->CorrectRadialDist(); mprintf(" Scaling values to match final density...\n"); if (o->m_pDensityDF->m_bDensityMass) { o->m_pDensityDF->m_pDensDF->Integrate(true,1.0 / g_iSteps / (double)((CMolecule*)g_oaMolecules[o->m_iShowMol])->m_laSingleMolIndex.GetSize()); o->m_pDensityDF->m_pDensDF->MultiplyBin(1.66054e6 / (4.0/3.0*Pi) / g_iSteps / ((CMolecule*)g_oaMolecules[o->m_iShowMol])->m_laSingleMolIndex.GetSize()); } else { o->m_pDensityDF->m_pDensDF->Integrate(true,1.0 / g_iSteps / (double)((CMolecule*)g_oaMolecules[o->m_iShowMol])->m_laSingleMolIndex.GetSize()); o->m_pDensityDF->m_pDensDF->MultiplyBin(1.0e9 / (4.0/3.0*Pi) / g_iSteps / ((CMolecule*)g_oaMolecules[o->m_iShowMol])->m_laSingleMolIndex.GetSize()); } /* if (g_bDoubleBox) { o->m_pDensityDF->m_pDensDF->MultiplyBin(g_iDoubleBoxFactor); o->m_pDensityDF->m_pDensDF->MultiplyIntegral(g_iDoubleBoxFactor); }*/ // sprintf(buf,"density_df_%s%s.csv",o->m_pDensityDF->m_sName,multibuf); buf.sprintf("density_df_%s%s.csv",o->m_pDensityDF->m_sName,multibuf); mprintf(" Saving Density DF as \"%s\"...\n",(const char*)buf); o->m_pDensityDF->m_pDensDF->Write("",buf,"",true); // sprintf(buf,"density_df_%s%s.agr",o->m_pDensityDF->m_sName,multibuf); buf.sprintf("density_df_%s%s.agr",o->m_pDensityDF->m_sName,multibuf); mprintf(" Saving Density DF AGR file as \"%s\"...\n",(const char*)buf); o->m_pDensityDF->m_pDensDF->WriteAgr("",buf,"",o->m_pDensityDF->m_sName,true); if (o->m_pDensityDF->m_iHistogramRes != 0) { mprintf(" Calculating Histogram...\n"); o->m_pDensityDF->m_pDensDF->CalcHistogram(); // sprintf(buf,"his_density_df_%s%s.csv",o->m_pDensityDF->m_sName,multibuf); buf.sprintf("his_density_df_%s%s.csv",o->m_pDensityDF->m_sName,multibuf); mprintf(" Saving Histogram as \"%s\"...\n",(const char*)buf); o->m_pDensityDF->m_pDensDF->WriteHistogram("",buf,""); } } // END IF g_bDens if (g_bRDyn) { mprintf(WHITE,"\n* Vector Reorientation Dynamics\n"); o->m_pRDyn->Finish(multibuf); } if (g_bIRSpec) { mprintf(WHITE,"\n* IR Spectrum\n"); o->m_pIRSpec->Finish(multibuf); } if (g_bVACF) { mprintf(WHITE,"\n* Velocity Autocorrelation Function\n"); if (o->m_pVACF->m_bDerivative) { mprintf(" Deriving velocities...\n"); mprintf(WHITE," ["); tfs = (((CMolecule*)g_oaMolecules[o->m_iShowMol])->m_laSingleMolIndex.GetSize()*o->m_pVACF->m_iShowAtomGes)/60.0; for (z2=0;z2<((CMolecule*)g_oaMolecules[o->m_iShowMol])->m_laSingleMolIndex.GetSize()*o->m_pVACF->m_iShowAtomGes;z2++) { if (fmod(z2,tfs) < 1) mprintf(WHITE,"#"); ptfa = (CxDoubleArray*)o->m_pVACF->m_oaCache[z2]; for (z3=0;z3<(int)g_iSteps*3-3;z3++) (*ptfa)[z3] = (*ptfa)[z3+3] - (*ptfa)[z3]; } mprintf(WHITE,"]\n"); } if (g_bVACFCacheMode) { mprintf(" Autocorrelating cached vectors...\n"); mprintf(WHITE," ["); tfs = (((CMolecule*)g_oaMolecules[o->m_iShowMol])->m_laSingleMolIndex.GetSize()*o->m_pVACF->m_iShowAtomGes)/60.0; try { ptfa2 = new CxDoubleArray("main():ptfa2"); } catch(...) { ptfa2 = NULL; } if (ptfa2 == NULL) NewException((double)sizeof(CxDoubleArray),__FILE__,__LINE__,__PRETTY_FUNCTION__); ptfa2->SetSize(g_iSteps); try { ptfa3 = new CxDoubleArray("main():ptfa3"); } catch(...) { ptfa3 = NULL; } if (ptfa3 == NULL) NewException((double)sizeof(CxDoubleArray),__FILE__,__LINE__,__PRETTY_FUNCTION__); ptfa3->SetSize(g_iSteps); try { ac = new CAutoCorrelation(); } catch(...) { ac = NULL; } if (ac == NULL) NewException((double)sizeof(CAutoCorrelation),__FILE__,__LINE__,__PRETTY_FUNCTION__); ac->Init(g_iSteps,o->m_pVACF->m_iSize,g_bACFFFT); ti = 0; for (z2=0;z2<((CMolecule*)g_oaMolecules[o->m_iShowMol])->m_laSingleMolIndex.GetSize();z2++) { for (z3=0;z3m_pVACF->m_oAtoms.m_baAtomType.GetSize();z3++) { if (o->m_pVACF->m_bMassWeight) tf = ((CAtom*)g_oaAtoms[o->m_pVACF->m_oAtoms.m_baRealAtomType[z3]])->m_pElement->m_fMass; else tf = 1.0; for (z4=0;z4<((CxIntArray*)o->m_pVACF->m_oAtoms.m_oaAtoms[z3])->GetSize();z4++) { if (fmod(ti,tfs) < 1) mprintf(WHITE,"#"); ptfa = (CxDoubleArray*)o->m_pVACF->m_oaCache[ti]; /* X */ for (z5=0;z5<(int)g_iSteps;z5++) (*ptfa2)[z5] = (*ptfa)[z5*3]; ac->AutoCorrelate(ptfa2,ptfa3); // mprintf("Lokal Atom %d X: %f + %f = %f.\n",ti+1,o->m_pVACF->m_pData[0],(*ptfa3)[0]*tf,o->m_pVACF->m_pData[0]+(*ptfa3)[0]*tf); for (z5=0;z5<(int)o->m_pVACF->m_iSize;z5++) o->m_pVACF->m_pData[z5] += (*ptfa3)[z5]*tf; /* Y */ for (z5=0;z5<(int)g_iSteps;z5++) (*ptfa2)[z5] = (*ptfa)[z5*3+1]; ac->AutoCorrelate(ptfa2,ptfa3); // mprintf("Lokal Atom %d Y: %f + %f = %f.\n",ti+1,o->m_pVACF->m_pData[0],(*ptfa3)[0]*tf,o->m_pVACF->m_pData[0]+(*ptfa3)[0]*tf); for (z5=0;z5<(int)o->m_pVACF->m_iSize;z5++) o->m_pVACF->m_pData[z5] += (*ptfa3)[z5]*tf; /* Z */ for (z5=0;z5<(int)g_iSteps;z5++) (*ptfa2)[z5] = (*ptfa)[z5*3+2]; ac->AutoCorrelate(ptfa2,ptfa3); // mprintf("Lokal Atom %d Z: %f + %f = %f.\n",ti+1,o->m_pVACF->m_pData[0],(*ptfa3)[0]*tf,o->m_pVACF->m_pData[0]+(*ptfa3)[0]*tf); for (z5=0;z5<(int)o->m_pVACF->m_iSize;z5++) o->m_pVACF->m_pData[z5] += (*ptfa3)[z5]*tf; ti++; } } } delete ac; delete ptfa2; delete ptfa3; /* } else { for (z2=0;z2<((CMolecule*)g_oaMolecules[o->m_iShowMol])->m_laSingleMolIndex.GetSize()*o->m_pVACF->m_iShowAtomGes;z2++) { if (fmod(z2,tfs) < 1) mprintf(WHITE,"#"); ptfa = (CxFloatArray*)o->m_pVACF->m_oaCache[z2]; for (z3=0;z3m_pVACF->m_iSize;z3+=o->m_pVACF->m_iStride) // Das ist das Tau { tf = 0; for (z4=0;z4<(int)g_iSteps-z3;z4++) // Das ist der Startpunkt tf += (*ptfa)[z4*3]*(*ptfa)[(z4+z3)*3] + (*ptfa)[z4*3+1]*(*ptfa)[(z4+z3)*3+1] + (*ptfa)[z4*3+2]*(*ptfa)[(z4+z3)*3+2]; o->m_pVACF->m_pData[z3/o->m_pVACF->m_iStride] += tf/(g_iSteps-z3); } } }*/ mprintf(WHITE,"]\n"); // mprintf(" %d atoms, %d time steps and %d correlation depths processed.\n",g_pGlobalVACF->m_oaCache.GetSize(),g_iSteps,g_pGlobalVACF->m_iSize); mprintf(" %d atoms, %lu time steps and %d correlation depths processed.\n",ti,g_iSteps,o->m_pVACF->m_iSize); o->m_pVACF->MultiplyCached(1.0/g_iGesAtomCount); } else o->m_pVACF->Multiply(1.0/g_iGesAtomCount); /* sprintf(buf,"acf_%s%s.csv",o->m_pVACF->m_sName,multibuf); mprintf(" Saving ACF as %s ...\n",buf); o->m_pVACF->WriteACF("",buf,"");*/ // sprintf(buf,"acf_%s%s.csv",o->m_pVACF->m_sName,multibuf); buf.sprintf("acf_%s%s.csv",o->m_pVACF->m_sName,multibuf); mprintf(" Saving ACF as %s ...\n",(const char*)buf); o->m_pVACF->WriteACF("",buf,""); if (o->m_pVACF->m_iMirror != 0) { mprintf(" Mirroring ACF...\n"); o->m_pVACF->Mirror(o->m_pVACF->m_iMirror); // sprintf(buf,"acf_%s%s.m.csv",o->m_pVACF->m_sName,multibuf); buf.sprintf("acf_%s%s.m.csv",o->m_pVACF->m_sName,multibuf); mprintf(" Saving mirrored ACF as %s ...\n",(const char*)buf); o->m_pVACF->WriteACF("",buf,""); } if (o->m_pVACF->m_bWindowFunction) { mprintf(" Applying window function to ACF...\n"); o->m_pVACF->Window(); // sprintf(buf,"acf_%s%s.w.csv",o->m_pVACF->m_sName,multibuf); buf.sprintf("acf_%s%s.w.csv",o->m_pVACF->m_sName,multibuf); mprintf(" Saving windowed ACF as %s ...\n",(const char*)buf); o->m_pVACF->WriteACF("",buf,""); } if (o->m_pVACF->m_bSpectrum) { mprintf(" Performing fourier transformation...\n"); try { g_pFFT = new CFFT(); } catch(...) { g_pFFT = NULL; } if (g_pFFT == NULL) NewException((double)sizeof(CFFT),__FILE__,__LINE__,__PRETTY_FUNCTION__); /* if (o->m_pVACF->m_bMirror) g_pFFT->PrepareFFT_C2C((o->m_pVACF->m_iSize+o->m_pVACF->m_iZeroPadding)*2); else */g_pFFT->PrepareFFT_C2C(o->m_pVACF->m_iSize+o->m_pVACF->m_iZeroPadding); o->m_pVACF->Transform(g_pFFT); delete g_pFFT; o->m_pVACF->m_pSpectrum->SetMaxRWL(1E7/299.792/g_fTimestepLength/g_iStride); if (o->m_pVACF->m_bACF_DB) { mprintf(" Normalising spectrum to decibel...\n"); o->m_pVACF->m_pSpectrum->MakeDB(); }/* else { mprintf(" Normalising integral of spectrum...\n"); o->m_pVACF->m_pSpectrum->SetIntegral(1000000.0f); }*/ /* if (o->m_pVACF->m_bWindowFunction) { sprintf(buf,"power_%s_w%s.csv",o->m_pVACF->m_sName,multibuf); mprintf(" Saving spectrum as %s ...\n",buf); o->m_pVACF->m_pSpectrum->Write("",buf,""); } else {*/ // sprintf(buf,"power_%s%s.csv",o->m_pVACF->m_sName,multibuf); buf.sprintf("power_%s%s.csv",o->m_pVACF->m_sName,multibuf); mprintf(" Saving spectrum as %s ...\n",(const char*)buf); o->m_pVACF->m_pSpectrum->Write("",buf,""); // } } } // End IF VACF if (g_bMSD) { mprintf(WHITE,"\n* Mean Square Displacement\n"); if (g_bMSDCacheMode) { mprintf(" Computing square displacement of cached vectors...\n"); // mprintf(WHITE," ["); // tfs = (((CMolecule*)g_oaMolecules[o->m_iShowMol])->m_laSingleMolIndex.GetSize()*o->m_pMSD->m_iShowAtoms)/60.0; for (z2=0;z2<((CMolecule*)g_oaMolecules[o->m_iShowMol])->m_laSingleMolIndex.GetSize()*o->m_pMSD->m_iShowAtoms;z2++) { // if (fmod(z2,tfs) < 1.0) // mprintf(WHITE,"#"); mprintf(" %4d/%d: [",z2+1,((CMolecule*)g_oaMolecules[o->m_iShowMol])->m_laSingleMolIndex.GetSize()*o->m_pMSD->m_iShowAtoms); tfs = o->m_pMSD->m_iResolution/50.0; ptfa = (CxDoubleArray*)o->m_pMSD->m_oaCache[z2]; for (z3=0;z3m_pMSD->m_iResolution;z3+=o->m_pMSD->m_iStride) // Das ist das Tau { if (fmod(z3,tfs) < 1.0) mprintf(WHITE,"#"); tf = 0; if (o->m_pMSD->m_bTakeX && o->m_pMSD->m_bTakeY && o->m_pMSD->m_bTakeZ) { for (z4=0;z4<(int)g_iSteps/g_iStride-z3-1;z4+=o->m_pMSD->m_iStride2) // Das ist der Startpunkt tf += pow2((*ptfa)[(z3+z4)*3]-(*ptfa)[z4*3]) + pow2((*ptfa)[(z3+z4)*3+1]-(*ptfa)[z4*3+1]) + pow2((*ptfa)[(z3+z4)*3+2]-(*ptfa)[z4*3+2]); } else { for (z4=0;z4<(int)g_iSteps/g_iStride-z3-1;z4+=o->m_pMSD->m_iStride2) // Das ist der Startpunkt { if (o->m_pMSD->m_bTakeX) tf += pow2((*ptfa)[(z3+z4)*3]-(*ptfa)[z4*3]); if (o->m_pMSD->m_bTakeY) tf += pow2((*ptfa)[(z3+z4)*3+1]-(*ptfa)[z4*3+1]); if (o->m_pMSD->m_bTakeZ) tf += pow2((*ptfa)[(z3+z4)*3+2]-(*ptfa)[z4*3+2]); } } o->m_pMSD->m_pMSD->AddToBin_Index(z3/o->m_pMSD->m_iStride,tf/(g_iSteps/g_iStride-z3-1)*o->m_pMSD->m_iStride2); o->m_pMSD->m_pMSD->m_fBinEntries += (g_iSteps/g_iStride-z3-1)/o->m_pMSD->m_iStride2; if (o->m_pMSD->m_bSplit) { o->m_pMSD->m_pSplitMSD[z2]->AddToBin_Index(z3/o->m_pMSD->m_iStride,tf/(g_iSteps/g_iStride-z3-1)*o->m_pMSD->m_iStride2); o->m_pMSD->m_pSplitMSD[z2]->m_fBinEntries += (g_iSteps/g_iStride-z3-1)/o->m_pMSD->m_iStride2; } } mprintf("]\n"); } for (z3=0;z3m_pMSD->m_iResolution;z3+=o->m_pMSD->m_iStride) // Das ist das Tau o->m_pMSD->m_pMSD->m_pBin[z3/o->m_pMSD->m_iStride] /= ((CMolecule*)g_oaMolecules[o->m_iShowMol])->m_laSingleMolIndex.GetSize()*o->m_pMSD->m_iShowAtoms; // mprintf(WHITE,"]\n"); } else { o->m_pMSD->m_pMSD->BuildAverage(); } mprintf(" %.0f bin entries.\n",o->m_pMSD->m_pMSD->m_fBinEntries); o->m_pMSD->m_pMSD->CalcDeriv(1.0); // sprintf(buf,"msd_%s%s.csv",o->m_pMSD->m_sName,multibuf); buf.sprintf("msd_%s%s.csv",o->m_pMSD->m_sName,multibuf); mprintf(" Saving result as %s ...\n",(const char*)buf); if (o->m_pMSD->m_bSplit) { o->m_pMSD->WriteSplit(buf); } else o->m_pMSD->m_pMSD->Write("",buf,""); mprintf(WHITE,"\n Performing linear regression on interval %.2f - %.2f ps...\n",o->m_pMSD->m_pMSD->m_fMinVal+0.5*(o->m_pMSD->m_pMSD->m_fMaxVal-o->m_pMSD->m_pMSD->m_fMinVal),o->m_pMSD->m_pMSD->m_fMaxVal); o->m_pMSD->m_pMSD->LinReg(o->m_pMSD->m_pMSD->m_iResolution/2,o->m_pMSD->m_pMSD->m_iResolution-1,&c0,&c1,&r); mprintf(" MSD(t) = %.6f + %.6f * t (units: [MSD] = pm^2, [t] = ps).\n",c0,c1); mprintf(" R = %.6f\n",r); ti = 0; if (o->m_pMSD->m_bTakeX) ti++; if (o->m_pMSD->m_bTakeY) ti++; if (o->m_pMSD->m_bTakeZ) ti++; if (ti != 3) mprintf(" Please note: Dimensionality of the system is %d here.\n",ti); mprintf(" Diffusion coefficient D = %.6f pm^2/ps = %G m^2/s.\n",c1/2.0/ti,c1/2.0e12/ti); mprintf(" (assuming = %d * D * t)\n\n",2*ti); } // END IF MSD if (g_bNbAnalysis) { mprintf(WHITE,"\n* Neighborhood Analysis\n"); mprintf(" %.0f bin entries.\n",o->m_pNbAnalysis->m_fBinEntries); /* for (z2=0;z2m_pNbAnalysis->m_iMaxNbCount-o->m_pNbAnalysis->m_iMinNbCount;z2++) mprintf(" - %d: %.0f bin entries, %.0f skipped.\n",z2+1,((CDF*)o->m_pNbAnalysis->m_oaDF[z2])->m_fBinEntries,((CDF*)o->m_pNbAnalysis->m_oaDF[z2])->m_fSkipEntries); */ try { pf = new double[o->m_pNbAnalysis->m_iNbCount]; } catch(...) { pf = NULL; } if (pf == NULL) NewException((double)o->m_pNbAnalysis->m_iNbCount*sizeof(double),__FILE__,__LINE__,__PRETTY_FUNCTION__); for (z3=0;z3m_pNbAnalysis->m_iNbCount;z3++) pf[z3] = (double)((CDF*)o->m_pNbAnalysis->m_oaDF[z3])->NormBinIntegral(); // sprintf(buf,"nbh_ncf_%s%s.csv",o->m_pNbAnalysis->m_sName,multibuf); buf.sprintf("nbh_ncf_%s%s.csv",o->m_pNbAnalysis->m_sName,multibuf); mprintf(" Saving neighbor count function as %s ...\n",(const char*)buf); a = OpenFileWrite(buf,true); mfprintf(a,"# distance [pm]; "); for (z3=0;z3m_pNbAnalysis->m_iNbCount+1;z3++) { mfprintf(a,"%d neighbors",z3); if (z3 < o->m_pNbAnalysis->m_iNbCount) mfprintf(a,"; "); } mfprintf(a,"\n"); for (z2=0;z2m_pNbAnalysis->m_iResolution;z2++) { mfprintf(a,"%.4f; ",o->m_pNbAnalysis->m_fMinDist+(z2+0.5)*(o->m_pNbAnalysis->m_fMaxDist-o->m_pNbAnalysis->m_fMinDist)/o->m_pNbAnalysis->m_iResolution); for (z3=0;z3m_pNbAnalysis->m_iNbCount+1;z3++) { mfprintf(a,"%.6f",((CDF*)o->m_pNbAnalysis->m_oaNPF[z3])->m_pBin[z2]/o->m_pNbAnalysis->m_pNPFCount->m_pBin[z2]*100.0); if (z3 < o->m_pNbAnalysis->m_iNbCount) mfprintf(a,"; "); } mfprintf(a,"\n"); } fclose(a); // sprintf(buf,"nbh_dist_%s%s.csv",o->m_pNbAnalysis->m_sName,multibuf); buf.sprintf("nbh_dist_%s%s.csv",o->m_pNbAnalysis->m_sName,multibuf); mprintf(" Calculating mean values and standard deviation...\n"); for (z3=0;z3m_pNbAnalysis->m_iNbCount;z3++) ((CDF*)o->m_pNbAnalysis->m_oaDF[z3])->CalcMeanSD(); mprintf(" Saving neighborhood distribution as %s ...\n",(const char*)buf); a = OpenFileWrite(buf,true); mfprintf(a,"# distance [pm]; "); for (z3=0;z3m_pNbAnalysis->m_iNbCount;z3++) { mfprintf(a,"%d. neighbor",z3+1); if (z3 < o->m_pNbAnalysis->m_iNbCount-1) mfprintf(a,"; "); } mfprintf(a,"\n"); for (z2=0;z2m_pNbAnalysis->m_iResolution;z2++) { mfprintf(a,"%.4f; ",o->m_pNbAnalysis->m_fMinDist+(z2+0.5)*(o->m_pNbAnalysis->m_fMaxDist-o->m_pNbAnalysis->m_fMinDist)/o->m_pNbAnalysis->m_iResolution); for (z3=0;z3m_pNbAnalysis->m_iNbCount;z3++) { mfprintf(a,"%.6f",((CDF*)o->m_pNbAnalysis->m_oaDF[z3])->m_pBin[z2]); if (z3 < o->m_pNbAnalysis->m_iNbCount-1) mfprintf(a,"; "); } mfprintf(a,"\n"); } fclose(a); // sprintf(buf,"nbh_minmaxavgsd_%s%s.csv",o->m_pNbAnalysis->m_sName,multibuf); buf.sprintf("nbh_minmaxavgsd_%s%s.csv",o->m_pNbAnalysis->m_sName,multibuf); mprintf(" Saving neighborhood min/max/avg/sd as %s ...\n",(const char*)buf); a = OpenFileWrite(buf,true); mfprintf(a,"# n-th neighbor; min. dist [pm]; max. dist [pm]; avg. dist [pm]; standard deviation [pm]\n"); for (z2=0;z2m_pNbAnalysis->m_iNbCount;z2++) { mfprintf(a,"%d; %.4f; %.4f; %.4f; %.4f",z2+1,o->m_pNbAnalysis->m_pDistMin[z2],o->m_pNbAnalysis->m_pDistMax[z2],((CDF*)o->m_pNbAnalysis->m_oaDF[z2])->m_fMean,((CDF*)o->m_pNbAnalysis->m_oaDF[z3])->m_fSD); mfprintf(a,"\n"); } fclose(a); // sprintf(buf,"nbh_rdf_decomp_%s%s.csv",o->m_pNbAnalysis->m_sName,multibuf); buf.sprintf("nbh_rdf_decomp_%s%s.csv",o->m_pNbAnalysis->m_sName,multibuf); mprintf(" Saving neighborhood RDF decomposition as %s ...\n",(const char*)buf); a = OpenFileWrite(buf,true); mfprintf(a,"# distance [pm]; "); for (z3=0;z3m_pNbAnalysis->m_iNbCount;z3++) { mfprintf(a,"%d. neighbor",z3+1); if (z3 < o->m_pNbAnalysis->m_iNbCount-1) mfprintf(a,"; "); } mfprintf(a,"\n"); for (z3=0;z3m_pNbAnalysis->m_iNbCount;z3++) { ((CDF*)o->m_pNbAnalysis->m_oaDF[z3])->MultiplyBin(pf[z3]); ((CDF*)o->m_pNbAnalysis->m_oaDF[z3])->CorrectRadialDist(); } for (z3=0;z3m_pNbAnalysis->m_iNbCount;z3++) { ((CDF*)o->m_pNbAnalysis->m_oaDF[z3])->MultiplyBin(g_fBoxX*g_fBoxY*g_fBoxZ / (4.0/3.0*Pi) / g_iSteps / ((CMolecule*)g_oaMolecules[g_iFixMol])->m_laSingleMolIndex.GetSize() / ((CMolecule*)g_oaMolecules[o->m_iShowMol])->m_laSingleMolIndex.GetSize()); if (g_bDoubleBox) ((CDF*)o->m_pNbAnalysis->m_oaDF[z3])->MultiplyBin(g_iDoubleBoxFactor); } for (z2=0;z2m_pNbAnalysis->m_iResolution;z2++) { mfprintf(a,"%.4f; ",o->m_pNbAnalysis->m_fMinDist+(z2+0.5)*(o->m_pNbAnalysis->m_fMaxDist-o->m_pNbAnalysis->m_fMinDist)/o->m_pNbAnalysis->m_iResolution); for (z3=0;z3m_pNbAnalysis->m_iNbCount;z3++) { mfprintf(a,"%.6f",((CDF*)o->m_pNbAnalysis->m_oaDF[z3])->m_pBin[z2]); if (z3 < o->m_pNbAnalysis->m_iNbCount-1) mfprintf(a,"; "); } mfprintf(a,"\n"); } fclose(a); // sprintf(buf,"nbh_rdf_decomp_cumulative_%s%s.csv",o->m_pNbAnalysis->m_sName,multibuf); buf.sprintf("nbh_rdf_decomp_cumulative_%s%s.csv",o->m_pNbAnalysis->m_sName,multibuf); mprintf(" Saving cumulative neighborhood RDF decomposition as %s ...\n",(const char*)buf); a = OpenFileWrite(buf,true); mfprintf(a,"# distance [pm]; "); for (z3=0;z3m_pNbAnalysis->m_iNbCount;z3++) { mfprintf(a,"%d. neighbor",z3+1); if (z3 < o->m_pNbAnalysis->m_iNbCount-1) mfprintf(a,"; "); } mfprintf(a,"\n"); for (z2=0;z2m_pNbAnalysis->m_iResolution;z2++) for (z3=1;z3m_pNbAnalysis->m_iNbCount;z3++) ((CDF*)o->m_pNbAnalysis->m_oaDF[z3])->m_pBin[z2] += ((CDF*)o->m_pNbAnalysis->m_oaDF[z3-1])->m_pBin[z2]; for (z2=0;z2m_pNbAnalysis->m_iResolution;z2++) { mfprintf(a,"%.4f; ",o->m_pNbAnalysis->m_fMinDist+(z2+0.5)*(o->m_pNbAnalysis->m_fMaxDist-o->m_pNbAnalysis->m_fMinDist)/o->m_pNbAnalysis->m_iResolution); for (z3=0;z3m_pNbAnalysis->m_iNbCount;z3++) { mfprintf(a,"%.6f",((CDF*)o->m_pNbAnalysis->m_oaDF[z3])->m_pBin[z2]); if (z3 < o->m_pNbAnalysis->m_iNbCount-1) mfprintf(a,"; "); } mfprintf(a,"\n"); } fclose(a); delete[] pf; } if (g_bDipDF) { for (zr=0;zrm_pDipDF[zr] == NULL) continue; mprintf(WHITE,"\n* Dipole Distribution Function\n"); mprintf(" %.0f bin entries, %.0f out of bin range (%.2f percent).\n",o->m_pDipDF[zr]->m_pDipoleDF->m_fBinEntries,o->m_pDipDF[zr]->m_pDipoleDF->m_fSkipEntries,ZeroDivide(o->m_pDipDF[zr]->m_pDipoleDF->m_fSkipEntries,o->m_pDipDF[zr]->m_pDipoleDF->m_fSkipEntries+o->m_pDipDF[zr]->m_pDipoleDF->m_fBinEntries)*100.0); o->m_pDipDF[zr]->m_pDipoleDF->CalcMinMax(); mprintf(" Max. bin entry: %.6E --> EPS: %.6E\n",o->m_pDipDF[zr]->m_pDipoleDF->m_fMaxEntry,o->m_pDipDF[zr]->m_pDipoleDF->m_fEps); if (o->m_pDipDF[zr]->m_pDipoleDF->m_fEps > 1.0E-4) { eprintf("\n Warning: Very large bin entries - probably loss of accuracy occured.\n"); mprintf(" Please reduce the bin counts (e.g. by analyzing only every 10th step).\n\n"); } o->m_pDipDF[zr]->m_pDipoleDF->CalcMeanSD(); mprintf(" Mean value: %10G Debye Standard deviation: %10G Debye\n",o->m_pDipDF[zr]->m_pDipoleDF->m_fMean,o->m_pDipDF[zr]->m_pDipoleDF->m_fSD); mprintf(" Min. value: %10G Debye Max. value: %10G Debye\n",o->m_pDipDF[zr]->m_pDipoleDF->m_fMinInput,o->m_pDipDF[zr]->m_pDipoleDF->m_fMaxInput); o->m_pDipDF[zr]->m_pDipoleDF->NormBinIntegral(); // sprintf(buf,"dipole_%s%s.csv",o->m_pDipDF[zr]->m_sName,multibuf); buf.sprintf("dipole_%s%s.csv",o->m_pDipDF[zr]->m_sName,multibuf); mprintf(" Saving dipole distribution as %s ...\n",(const char*)buf); o->m_pDipDF[zr]->m_pDipoleDF->Write("",buf,"",false); // sprintf(buf,"dipole_%s%s.agr",o->m_pDipDF[zr]->m_sName,multibuf); buf.sprintf("dipole_%s%s.agr",o->m_pDipDF[zr]->m_sName,multibuf); mprintf(" Saving dipole distribution AGR file as \"%s\"...\n",(const char*)buf); o->m_pDipDF[zr]->m_pDipoleDF->WriteAgr("",buf,"",o->m_pDipDF[zr]->m_sName,false); if (o->m_pDipDF[zr]->m_iHistogramRes != 0) { mprintf(" Calculating Histogram...\n"); o->m_pDipDF[zr]->m_pDipoleDF->CalcHistogram(); // sprintf(buf,"his_dipdf_%s%s.csv",o->m_pDipDF[zr]->m_sName,multibuf); buf.sprintf("his_dipdf_%s%s.csv",o->m_pDipDF[zr]->m_sName,multibuf); mprintf(" Saving Histogram as \"%s\"...\n",(const char*)buf); o->m_pDipDF[zr]->m_pDipoleDF->WriteHistogram("",buf,""); } if (o->m_bTimeDev) { if ((o->m_waSaveRefList.GetSize() == 1) || (!o->m_bSaveSeparateFiles)) { fclose(o->m_pDipDF[zr]->m_fDipole[0]); mprintf(" Saving temporal development as dipole_timedev_%s%s.csv\n",o->m_pDipDF[zr]->m_sName,multibuf); } else { for (z2=0;z2m_waSaveRefList.GetSize();z2++) { fclose(o->m_pDipDF[zr]->m_fDipole[z2]); mprintf(" Saving temporal development as dipole_timedev_%s_ref%d%s.csv\n",o->m_pDipDF[zr]->m_sName,o->m_waSaveRefList[z2]+1,multibuf); } } if (o->m_bCombinedPlot) { // sprintf(buf,"combined_%s%s.agr",o->m_pDipDF[zr]->m_sName,multibuf); buf.sprintf("combined_%s%s.agr",o->m_pDipDF[zr]->m_sName,multibuf); mprintf(" Saving combined plot as \"%s\"...\n",(const char*)buf); o->m_pDipDF[zr]->m_pDipoleDF->CreateCombinedPlot(false); o->m_pDipDF[zr]->m_pDipoleDF->m_pCombinedPlot->WriteAgr(buf,false); } } // END IF TIMEDEV if (o->m_bObsCertain && o->m_bDecompDist) { // sprintf(buf,"dipdf_decomp_%s%s.csv",o->m_pDipDF[zr]->m_sName,multibuf); buf.sprintf("dipdf_decomp_%s%s.csv",o->m_pDipDF[zr]->m_sName,multibuf); mprintf(" Saving DipDF decomposition as \"%s\"...\n",(const char*)buf); o->m_pDipDF[zr]->m_pDipoleDF->WriteMulti("",buf,""); // sprintf(buf,"dipdf_decomp_%s%s_cumulative.csv",o->m_pDipDF[zr]->m_sName,multibuf); buf.sprintf("dipdf_decomp_%s%s_cumulative.csv",o->m_pDipDF[zr]->m_sName,multibuf); mprintf(" Saving cumulative DipoleDF decomposition as \"%s\"...\n",(const char*)buf); o->m_pDipDF[zr]->m_pDipoleDF->WriteMulti_Cumulative("",buf,""); } if (o->m_bTimeDiff) o->WriteTimeDiff(o->m_pDipDF[zr]->m_pDipoleDF,"DipDF","dipdf",o->m_pDipDF[zr]->m_sName,multibuf,false); } } // END IF DIPOLE if (g_bVDF) { for (zr=0;zrm_pVDF[zr] == NULL) continue; mprintf(WHITE,"\n* Velocity Distribution Function\n"); mprintf(" %.0f bin entries, %.0f out of bin range (%.2f percent).\n",o->m_pVDF[zr]->m_pVDF->m_fBinEntries,o->m_pVDF[zr]->m_pVDF->m_fSkipEntries,ZeroDivide(o->m_pVDF[zr]->m_pVDF->m_fSkipEntries,o->m_pVDF[zr]->m_pVDF->m_fBinEntries+o->m_pVDF[zr]->m_pVDF->m_fSkipEntries)*100.0); o->m_pVDF[zr]->m_pVDF->CalcMinMax(); mprintf(" Max. bin entry: %.6E --> EPS: %.6E\n",o->m_pVDF[zr]->m_pVDF->m_fMaxEntry,o->m_pVDF[zr]->m_pVDF->m_fEps); if (o->m_pVDF[zr]->m_pVDF->m_fEps > 1.0E-4) { eprintf("\n Warning: Very large bin entries - probably loss of accuracy occured.\n"); mprintf(" Please reduce the bin counts (e.g. by analyzing only every 10th step).\n\n"); } o->m_pVDF[zr]->m_pVDF->CalcMeanSD(); mprintf(" Mean value: %10G pm/ps Standard deviation: %10G pm/ps\n",o->m_pVDF[zr]->m_pVDF->m_fMean,o->m_pVDF[zr]->m_pVDF->m_fSD); mprintf(" Min. value: %10G pm/ps Max. value: %10G pm/ps\n",o->m_pVDF[zr]->m_pVDF->m_fMinInput,o->m_pVDF[zr]->m_pVDF->m_fMaxInput); o->m_pVDF[zr]->m_pVDF->NormBinIntegral(); // sprintf(buf,"vdf_%s%s.csv",o->m_pVDF[zr]->m_sName,multibuf); buf.sprintf("vdf_%s%s.csv",o->m_pVDF[zr]->m_sName,multibuf); mprintf(" Saving velocity distribution as %s ...\n",(const char*)buf); o->m_pVDF[zr]->m_pVDF->Write("",buf,"",false); // sprintf(buf,"vdf_%s%s.agr",o->m_pVDF[zr]->m_sName,multibuf); buf.sprintf("vdf_%s%s.agr",o->m_pVDF[zr]->m_sName,multibuf); mprintf(" Saving velocity distribution AGR file as \"%s\"...\n",(const char*)buf); o->m_pVDF[zr]->m_pVDF->WriteAgr("",buf,"",o->m_pVDF[zr]->m_sName,false); if (o->m_pVDF[zr]->m_iHistogramRes != 0) { mprintf(" Calculating Histogram...\n"); o->m_pVDF[zr]->m_pVDF->CalcHistogram(); // sprintf(buf,"his_vdf_%s%s.agr",o->m_pVDF[zr]->m_sName,multibuf); buf.sprintf("his_vdf_%s%s.csv",o->m_pVDF[zr]->m_sName,multibuf); mprintf(" Saving Histogram as \"%s\"...\n",(const char*)buf); o->m_pVDF[zr]->m_pVDF->WriteHistogram("",buf,""); } if (o->m_bTimeDev) { if ((o->m_waSaveRefList.GetSize() == 1) || (!o->m_bSaveSeparateFiles)) { fclose(o->m_pVDF[zr]->m_fSpeed[0]); mprintf(" Saving temporal development as vdf_timedev_%s%s.csv\n",o->m_pVDF[zr]->m_sName,multibuf); } else { for (z2=0;z2m_waSaveRefList.GetSize();z2++) { fclose(o->m_pVDF[zr]->m_fSpeed[z2]); mprintf(" Saving temporal development as vdf_timedev_%s_ref%d%s.csv\n",o->m_pVDF[zr]->m_sName,o->m_waSaveRefList[z2]+1,multibuf); } } if (o->m_bCombinedPlot) { // sprintf(buf,"combined_%s%s.csv",o->m_pVDF[zr]->m_sName,multibuf); buf.sprintf("combined_%s%s.csv",o->m_pVDF[zr]->m_sName,multibuf); mprintf(" Saving combined plot as \"%s\"...\n",(const char*)buf); o->m_pVDF[zr]->m_pVDF->CreateCombinedPlot(false); o->m_pVDF[zr]->m_pVDF->m_pCombinedPlot->WriteAgr(buf,false); } } // END IF TIMEDEV if (o->m_bObsCertain && o->m_bDecompDist) { // sprintf(buf,"vdf_decomp_%s%s.csv",o->m_pVDF[zr]->m_sName,multibuf); buf.sprintf("vdf_decomp_%s%s.csv",o->m_pVDF[zr]->m_sName,multibuf); mprintf(" Saving VDF decomposition as \"%s\"...\n",(const char*)buf); o->m_pVDF[zr]->m_pVDF->WriteMulti("",buf,""); // sprintf(buf,"vdf_decomp_%s%s_cumulative.csv",o->m_pVDF[zr]->m_sName,multibuf); buf.sprintf("vdf_decomp_%s%s_cumulative.csv",o->m_pVDF[zr]->m_sName,multibuf); mprintf(" Saving cumulative VDF decomposition as \"%s\"...\n",(const char*)buf); o->m_pVDF[zr]->m_pVDF->WriteMulti_Cumulative("",buf,""); } if (o->m_bTimeDiff) o->WriteTimeDiff(o->m_pVDF[zr]->m_pVDF,"VDF","vdf",o->m_pVDF[zr]->m_sName,multibuf,false); if (o->m_pVDF[zr]->m_bSplitCart) { upn = "?"; pn = "?"; for (z2=0;z2<6;z2++) { switch(z2) { case 0: pn = "x"; upn = "X"; break; case 1: pn = "y"; upn = "Y"; break; case 2: pn = "z"; upn = "Z"; break; case 3: pn = "xy"; upn = "XY"; break; case 4: pn = "xz"; upn = "XZ"; break; case 5: pn = "yz"; upn = "YZ"; break; } mprintf(WHITE," * Velocity Distribution %s Projection\n",upn); mprintf(" %.0f bin entries, %.0f out of bin range (%.2f percent).\n", o->m_pVDF[zr]->m_pVDFSplit[z2]->m_fBinEntries, o->m_pVDF[zr]->m_pVDFSplit[z2]->m_fSkipEntries, ZeroDivide( o->m_pVDF[zr]->m_pVDFSplit[z2]->m_fSkipEntries, o->m_pVDF[zr]->m_pVDFSplit[z2]->m_fBinEntries+o->m_pVDF[zr]->m_pVDFSplit[z2]->m_fSkipEntries )*100.0 ); o->m_pVDF[zr]->m_pVDFSplit[z2]->CalcMinMax(); mprintf(" Max. bin entry: %.6E --> EPS: %.6E\n", o->m_pVDF[zr]->m_pVDFSplit[z2]->m_fMaxEntry, o->m_pVDF[zr]->m_pVDFSplit[z2]->m_fEps ); if (o->m_pVDF[zr]->m_pVDFSplit[z2]->m_fEps > 1.0E-4) { eprintf("\n Warning: Very large bin entries - probably loss of accuracy occured.\n"); mprintf(" Please reduce the bin counts (e.g. by analyzing only every 10th step).\n\n"); } o->m_pVDF[zr]->m_pVDFSplit[z2]->CalcMeanSD(); mprintf(" Mean value: %10G pm/ps Standard deviation: %10G pm/ps\n", o->m_pVDF[zr]->m_pVDFSplit[z2]->m_fMean, o->m_pVDF[zr]->m_pVDFSplit[z2]->m_fSD ); mprintf(" Min. value: %10G pm/ps Max. value: %10G pm/ps\n", o->m_pVDF[zr]->m_pVDFSplit[z2]->m_fMinInput, o->m_pVDF[zr]->m_pVDFSplit[z2]->m_fMaxInput ); o->m_pVDF[zr]->m_pVDFSplit[z2]->NormBinIntegral(); buf.sprintf("vdf_%s%s_%s.csv",o->m_pVDF[zr]->m_sName,multibuf,pn); mprintf(" Saving velocity distribution as \"%s\"...\n",(const char*)buf); o->m_pVDF[zr]->m_pVDFSplit[z2]->Write("",buf,"",false); buf.sprintf("vdf_%s%s_%s.agr",o->m_pVDF[zr]->m_sName,multibuf,pn); mprintf(" Saving velocity distribution AGR file as \"%s\"...\n",(const char*)buf); o->m_pVDF[zr]->m_pVDFSplit[z2]->WriteAgr("",buf,"",o->m_pVDF[zr]->m_sName,false); if (o->m_pVDF[zr]->m_iHistogramRes != 0) { mprintf(" Calculating Histogram...\n"); o->m_pVDF[zr]->m_pVDFSplit[z2]->CalcHistogram(); buf.sprintf("his_vdf_%s%s_%s.csv",o->m_pVDF[zr]->m_sName,multibuf,pn); mprintf(" Saving Histogram as \"%s\"...\n",(const char*)buf); o->m_pVDF[zr]->m_pVDFSplit[z2]->WriteHistogram("",buf,""); } } } } } // END IF VDF if (g_bPlDF) { for (zr=0;zrm_pPlDF[zr] == NULL) continue; mprintf(WHITE,"\n* Plane Distance Distribution Function\n"); mprintf(" %.0f bin entries, %.0f out of bin range (%.2f percent).\n",o->m_pPlDF[zr]->m_pPlDF->m_fBinEntries,o->m_pPlDF[zr]->m_pPlDF->m_fSkipEntries,ZeroDivide(o->m_pPlDF[zr]->m_pPlDF->m_fSkipEntries,o->m_pPlDF[zr]->m_pPlDF->m_fBinEntries+o->m_pPlDF[zr]->m_pPlDF->m_fSkipEntries)*100.0); o->m_pPlDF[zr]->m_pPlDF->CalcMinMax(); mprintf(" Max. bin entry: %.6E --> EPS: %.6E\n",o->m_pPlDF[zr]->m_pPlDF->m_fMaxEntry,o->m_pPlDF[zr]->m_pPlDF->m_fEps); if (o->m_pPlDF[zr]->m_pPlDF->m_fEps > 1.0E-4) { eprintf("\n Warning: Very large bin entries - probably loss of accuracy occured.\n"); mprintf(" Please reduce the bin counts (e.g. by analyzing only every 10th step).\n\n"); } o->m_pPlDF[zr]->m_pPlDF->CalcMeanSD(); mprintf(" Mean value: %10G pm Standard deviation: %10G pm\n",o->m_pPlDF[zr]->m_pPlDF->m_fMean,o->m_pPlDF[zr]->m_pPlDF->m_fSD); mprintf(" Min. value: %10G pm Max. value: %10G pm\n",o->m_pPlDF[zr]->m_pPlDF->m_fMinInput,o->m_pPlDF[zr]->m_pPlDF->m_fMaxInput); o->m_pPlDF[zr]->m_pPlDF->NormBinIntegral(); // sprintf(buf,"pldf_%s%s.csv",o->m_pPlDF[zr]->m_sName,multibuf); buf.sprintf("pldf_%s%s.csv",o->m_pPlDF[zr]->m_sName,multibuf); mprintf(" Saving plane distance distribution as %s ...\n",(const char*)buf); o->m_pPlDF[zr]->m_pPlDF->Write("",buf,"",false); // sprintf(buf,"pldf_%s%s.agr",o->m_pPlDF[zr]->m_sName,multibuf); buf.sprintf("pldf_%s%s.agr",o->m_pPlDF[zr]->m_sName,multibuf); mprintf(" Saving plane distance distribution AGR file as \"%s\"...\n",(const char*)buf); o->m_pPlDF[zr]->m_pPlDF->WriteAgr("",buf,"",o->m_pPlDF[zr]->m_sName,false); if (o->m_pPlDF[zr]->m_iHistogramRes != 0) { mprintf(" Calculating Histogram...\n"); o->m_pPlDF[zr]->m_pPlDF->CalcHistogram(); // sprintf(buf,"his_pldf_%s%s.agr",o->m_pPlDF[zr]->m_sName,multibuf); buf.sprintf("his_pldf_%s%s.csv",o->m_pPlDF[zr]->m_sName,multibuf); mprintf(" Saving Histogram as \"%s\"...\n",(const char*)buf); o->m_pPlDF[zr]->m_pPlDF->WriteHistogram("",buf,""); } } } // END IF PlDF if (g_bLiDF) { for (zr=0;zrm_pLiDF[zr] == NULL) continue; mprintf(WHITE,"\n* Line Distance Distribution Function\n"); mprintf(" %.0f bin entries, %.0f out of bin range (%.2f percent).\n",o->m_pLiDF[zr]->m_pLiDF->m_fBinEntries,o->m_pLiDF[zr]->m_pLiDF->m_fSkipEntries,ZeroDivide(o->m_pLiDF[zr]->m_pLiDF->m_fSkipEntries,o->m_pLiDF[zr]->m_pLiDF->m_fBinEntries+o->m_pLiDF[zr]->m_pLiDF->m_fSkipEntries)*100.0); o->m_pLiDF[zr]->m_pLiDF->CalcMinMax(); mprintf(" Max. bin entry: %.6E --> EPS: %.6E\n",o->m_pLiDF[zr]->m_pLiDF->m_fMaxEntry,o->m_pLiDF[zr]->m_pLiDF->m_fEps); if (o->m_pLiDF[zr]->m_pLiDF->m_fEps > 1.0E-4) { eprintf("\n Warning: Very large bin entries - probably loss of accuracy occured.\n"); mprintf(" Please reduce the bin counts (e.g. by analyzing only every 10th step).\n\n"); } o->m_pLiDF[zr]->m_pLiDF->CalcMeanSD(); mprintf(" Mean value: %10G pm Standard deviation: %10G pm\n",o->m_pLiDF[zr]->m_pLiDF->m_fMean,o->m_pLiDF[zr]->m_pLiDF->m_fSD); mprintf(" Min. value: %10G pm Max. value: %10G pm\n",o->m_pLiDF[zr]->m_pLiDF->m_fMinInput,o->m_pLiDF[zr]->m_pLiDF->m_fMaxInput); if (o->m_pLiDF[zr]->m_bRadialCorrect) { mprintf(" Correcting radial distribution...\n"); o->m_pLiDF[zr]->m_pLiDF->CorrectLiRadialDist(); } if (o->m_bOthers && o->m_pLiDF[zr]->m_bRadialCorrect) { mprintf(" Scaling LiDF to uniform density...\n"); if (g_bPeriodicX && g_bPeriodicY && g_bPeriodicZ) { if (o->m_bObsCertain) { o->m_pLiDF[zr]->m_pLiDF->Integrate(true,1.0 / g_iSteps / o->m_waObsRefList.GetSize()); o->m_pLiDF[zr]->m_pLiDF->MultiplyBin(g_fBoxX*g_fBoxY*g_fBoxZ / (4.0/3.0*Pi) / g_iSteps / o->m_waObsRefList.GetSize() / o->m_pLiDF[zr]->m_iShowAtomGes / o->m_waObsShowList.GetSize() / o->m_pLiDF[zr]->m_iRefAtomGes); } else { if (g_bBoxNonOrtho) { o->m_pLiDF[zr]->m_pLiDF->Integrate(true,1.0 / g_iSteps / (double)((CMolecule*)g_oaMolecules[g_iFixMol])->m_laSingleMolIndex.GetSize()); o->m_pLiDF[zr]->m_pLiDF->MultiplyBin(g_fBoxVolume / (4.0/3.0*Pi) / g_iSteps / ((CMolecule*)g_oaMolecules[g_iFixMol])->m_laSingleMolIndex.GetSize() / o->m_pLiDF[zr]->m_iShowAtomGes / ((CMolecule*)g_oaMolecules[o->m_iShowMol])->m_laSingleMolIndex.GetSize() / o->m_pLiDF[zr]->m_iRefAtomGes); } else { o->m_pLiDF[zr]->m_pLiDF->Integrate(true,1.0 / g_iSteps / (double)((CMolecule*)g_oaMolecules[g_iFixMol])->m_laSingleMolIndex.GetSize()); o->m_pLiDF[zr]->m_pLiDF->MultiplyBin(g_fBoxX*g_fBoxY*g_fBoxZ / (4.0/3.0*Pi) / g_iSteps / ((CMolecule*)g_oaMolecules[g_iFixMol])->m_laSingleMolIndex.GetSize() / o->m_pLiDF[zr]->m_iShowAtomGes / ((CMolecule*)g_oaMolecules[o->m_iShowMol])->m_laSingleMolIndex.GetSize() / o->m_pLiDF[zr]->m_iRefAtomGes); } } if (g_bDoubleBox) { o->m_pLiDF[zr]->m_pLiDF->MultiplyBin(g_iDoubleBoxFactor); o->m_pLiDF[zr]->m_pLiDF->MultiplyIntegral(g_iDoubleBoxFactor); } } else { eprintf(" Uniform density not defined if box is not XYZ-periodic!\n"); goto _lidfint1; } } else { _lidfint1: mprintf(" Scaling LiDF to integral value 1000 ...\n"); o->m_pLiDF[zr]->m_pLiDF->NormBinIntegral(1000.0); o->m_pLiDF[zr]->m_pLiDF->Integrate(false,1000.0); } // o->m_pLiDF[zr]->m_pLiDF->NormBinIntegral(); // sprintf(buf,"lidf_%s%s.csv",o->m_pLiDF[zr]->m_sName,multibuf); buf.sprintf("lidf_%s%s.csv",o->m_pLiDF[zr]->m_sName,multibuf); mprintf(" Saving line distance distribution as %s ...\n",(const char*)buf); o->m_pLiDF[zr]->m_pLiDF->Write("",buf,"",false); // sprintf(buf,"lidf_%s%s.agr",o->m_pLiDF[zr]->m_sName,multibuf); buf.sprintf("lidf_%s%s.agr",o->m_pLiDF[zr]->m_sName,multibuf); mprintf(" Saving line distance distribution AGR file as \"%s\"...\n",(const char*)buf); o->m_pLiDF[zr]->m_pLiDF->WriteAgr("",buf,"",o->m_pLiDF[zr]->m_sName,false); if (o->m_pLiDF[zr]->m_iHistogramRes != 0) { mprintf(" Calculating Histogram...\n"); o->m_pLiDF[zr]->m_pLiDF->CalcHistogram(); // sprintf(buf,"his_lidf_%s%s.agr",o->m_pLiDF[zr]->m_sName,multibuf); buf.sprintf("his_lidf_%s%s.csv",o->m_pLiDF[zr]->m_sName,multibuf); mprintf(" Saving Histogram as \"%s\"...\n",(const char*)buf); o->m_pLiDF[zr]->m_pLiDF->WriteHistogram("",buf,""); } } } // END IF LiDF if (g_bADF) { for (zr=0;zrm_pADF[zr] == NULL) continue; mprintf(WHITE,"\n* Angular Distribution Function\n"); mprintf(" %.0f bin entries, %.0f out of bin range (%.2f percent).\n",o->m_pADF[zr]->m_pADF->m_fBinEntries,o->m_pADF[zr]->m_pADF->m_fSkipEntries,ZeroDivide(o->m_pADF[zr]->m_pADF->m_fSkipEntries,o->m_pADF[zr]->m_pADF->m_fBinEntries+o->m_pADF[zr]->m_pADF->m_fSkipEntries)*100.0); o->m_pADF[zr]->m_pADF->CalcMinMax(); mprintf(" Max. bin entry: %.6E --> EPS: %.6E\n",o->m_pADF[zr]->m_pADF->m_fMaxEntry,o->m_pADF[zr]->m_pADF->m_fEps); if (o->m_pADF[zr]->m_pADF->m_fEps > 1.0E-4) { eprintf("\n Warning: Very large bin entries - probably loss of accuracy occured.\n"); mprintf(" Please reduce the bin counts (e.g. by analyzing only every 10th step).\n\n"); } o->m_pADF[zr]->m_pADF->CalcMeanSD(); if (o->m_pADF[zr]->m_bCosine) { mprintf(" Mean value: %10G Standard deviation: %10G\n",o->m_pADF[zr]->m_pADF->m_fMean,o->m_pADF[zr]->m_pADF->m_fSD); mprintf(" Min. value: %10G Max. value: %10G\n",o->m_pADF[zr]->m_pADF->m_fMinInput,o->m_pADF[zr]->m_pADF->m_fMaxInput); } else { mprintf(" Mean value: %10G degree Standard deviation: %10G degree\n",o->m_pADF[zr]->m_pADF->m_fMean,o->m_pADF[zr]->m_pADF->m_fSD); mprintf(" Min. value: %10G degree Max. value: %10G degree\n",o->m_pADF[zr]->m_pADF->m_fMinInput,o->m_pADF[zr]->m_pADF->m_fMaxInput); } if (o->m_pADF[zr]->m_bStat) { mprintf(" Applying cone correction...\n"); o->m_pADF[zr]->m_pADF->AngleCorrect(); } if (o->m_pADF[zr]->m_bMirror) { mprintf(" Making ADF mirror-symmetric...\n"); if (o->m_pADF[zr]->m_bCosine) o->m_pADF[zr]->m_pADF->Mirror(0.0); else o->m_pADF[zr]->m_pADF->Mirror(90.0); } o->m_pADF[zr]->m_pADF->NormBinIntegral(); if (o->m_bTimeDev) { if ((o->m_waSaveRefList.GetSize() == 1) || (!o->m_bSaveSeparateFiles)) { fclose(o->m_pADF[zr]->m_fAngle[0]); mprintf(" Saving temporal development as adf_timedev_%s%s.csv\n",o->m_pADF[zr]->m_sName,multibuf); } else { for (z2=0;z2m_waSaveRefList.GetSize();z2++) { fclose(o->m_pADF[zr]->m_fAngle[z2]); // sprintf(buf,"adf_timedev_%s_ref%d%s.csv",o->m_pADF[zr]->m_sName,o->m_waSaveRefList[z2]+1,multibuf); buf.sprintf("adf_timedev_%s_ref%d%s.csv",o->m_pADF[zr]->m_sName,o->m_waSaveRefList[z2]+1,multibuf); mprintf(" Saving temporal development as %s\n",(const char*)buf); } } // mprintf(" Speichere Winkel-Statistik als %s_angle_stat.txt\n",o->m_pADF->m_sName); // FreeFileName("",o->m_pADF->m_sName,"_angle_stat.txt"); // o->m_pADF->m_pAngleStat->Evaluate(); // o->m_pADF->m_pAngleStat->Write("",o->m_pADF->m_sName,"_angle_stat.txt"); // delete o->m_pAngleStat; delete[] o->m_pADF[zr]->m_fAngle; o->m_pADF[zr]->m_fAngle = NULL; if (o->m_bCombinedPlot) { // sprintf(buf,"combined_%s%s.agr",o->m_pADF[zr]->m_sName,multibuf); buf.sprintf("combined_%s%s.agr",o->m_pADF[zr]->m_sName,multibuf); mprintf(" Saving combined plot as \"%s\"...\n",(const char*)buf); o->m_pADF[zr]->m_pADF->CreateCombinedPlot(false); o->m_pADF[zr]->m_pADF->m_pCombinedPlot->WriteAgr(buf,false); } } // END IF TIMEDEV // sprintf(buf,"adf_%s%s.csv",o->m_pADF[zr]->m_sName,multibuf); buf.sprintf("adf_%s%s.csv",o->m_pADF[zr]->m_sName,multibuf); mprintf(" Saving ADF as %s ...\n",(const char*)buf); o->m_pADF[zr]->m_pADF->NormBinIntegral(); o->m_pADF[zr]->m_pADF->Write("",buf,"",false); // sprintf(buf,"adf_%s%s.agr",o->m_pADF[zr]->m_sName,multibuf); buf.sprintf("adf_%s%s.agr",o->m_pADF[zr]->m_sName,multibuf); mprintf(" Saving ADF AGR file as \"%s\"...\n",(const char*)buf); if (o->m_pADF[zr]->m_bCosine) o->m_pADF[zr]->m_pADF->WriteAgr("",buf,"",o->m_pADF[zr]->m_sName,false); else o->m_pADF[zr]->m_pADF->WriteAgr("",buf,"",o->m_pADF[zr]->m_sName,false); if (o->m_pADF[zr]->m_iHistogramRes != 0) { mprintf(" Calculating Histogram...\n"); o->m_pADF[zr]->m_pADF->CalcHistogram(); // sprintf(buf,"his_adf_%s%s.csv",o->m_pADF[zr]->m_sName,multibuf); buf.sprintf("his_adf_%s%s.csv",o->m_pADF[zr]->m_sName,multibuf); mprintf(" Saving Histogram as \"%s\"...\n",(const char*)buf); o->m_pADF[zr]->m_pADF->WriteHistogram("",buf,""); } if (o->m_bObsCertain && o->m_bDecompDist) { // sprintf(buf,"adf_decomp_%s%s.csv",o->m_pADF[zr]->m_sName,multibuf); buf.sprintf("adf_decomp_%s%s.csv",o->m_pADF[zr]->m_sName,multibuf); mprintf(" Saving ADF decomposition as \"%s\"...\n",(const char*)buf); o->m_pADF[zr]->m_pADF->WriteMulti("",buf,""); // sprintf(buf,"adf_decomp_%s%s_cumulative.csv",o->m_pADF[zr]->m_sName,multibuf); buf.sprintf("adf_decomp_%s%s_cumulative.csv",o->m_pADF[zr]->m_sName,multibuf); mprintf(" Saving cumulative ADF decomposition as \"%s\"...\n",(const char*)buf); o->m_pADF[zr]->m_pADF->WriteMulti_Cumulative("",buf,""); } if (o->m_bTimeDiff) o->WriteTimeDiff(o->m_pADF[zr]->m_pADF,"ADF","adf",o->m_pADF[zr]->m_sName,multibuf,false); } } // END IF ADF if (g_bDDF) { for (zr=0;zrm_pDDF[zr] == NULL) continue; mprintf(WHITE,"\n* Dihedral Distribution Function\n"); mprintf(" %.0f bin entries, %.0f out of bin range (%.2f percent).\n",o->m_pDDF[zr]->m_pDDF->m_fBinEntries,o->m_pDDF[zr]->m_pDDF->m_fSkipEntries,ZeroDivide(o->m_pDDF[zr]->m_pDDF->m_fSkipEntries,o->m_pDDF[zr]->m_pDDF->m_fBinEntries+o->m_pDDF[zr]->m_pDDF->m_fSkipEntries)*100.0); o->m_pDDF[zr]->m_pDDF->CalcMinMax(); mprintf(" Max. bin entry: %.6E --> EPS: %.6E\n",o->m_pDDF[zr]->m_pDDF->m_fMaxEntry,o->m_pDDF[zr]->m_pDDF->m_fEps); if (o->m_pDDF[zr]->m_pDDF->m_fEps > 1.0E-4) { eprintf("\n Warning: Very large bin entries - probably loss of accuracy occured.\n"); mprintf(" Please reduce the bin counts (e.g. by analyzing only every 10th step).\n\n"); } o->m_pDDF[zr]->m_pDDF->CalcMeanSD(); if (o->m_pDDF[zr]->m_bCosine) { mprintf(" Mean value: %10G Standard deviation: %10G\n",o->m_pDDF[zr]->m_pDDF->m_fMean,o->m_pDDF[zr]->m_pDDF->m_fSD); mprintf(" Min. value: %10G Max.value: %10G\n",o->m_pDDF[zr]->m_pDDF->m_fMinInput,o->m_pDDF[zr]->m_pDDF->m_fMaxInput); } else { mprintf(" Mean value: %10G degree Standard deviation: %10G degree\n",o->m_pDDF[zr]->m_pDDF->m_fMean,o->m_pDDF[zr]->m_pDDF->m_fSD); mprintf(" Min. value: %10G degree Max.value: %10G degree\n",o->m_pDDF[zr]->m_pDDF->m_fMinInput,o->m_pDDF[zr]->m_pDDF->m_fMaxInput); } if (o->m_bTimeDev) { if ((o->m_waSaveRefList.GetSize() == 1) || (!o->m_bSaveSeparateFiles)) { fclose(o->m_pDDF[zr]->m_fAngle[0]); mprintf(" Saving temporal development as ddf_timedev_%s%s.csv\n",o->m_pDDF[zr]->m_sName,multibuf); } else { for (z2=0;z2m_waSaveRefList.GetSize();z2++) { fclose(o->m_pDDF[zr]->m_fAngle[z2]); // sprintf(buf,"ddf_timedev_%s_ref%d%s.csv",o->m_pDDF[zr]->m_sName,o->m_waSaveRefList[z2]+1,multibuf); buf.sprintf("ddf_timedev_%s_ref%d%s.csv",o->m_pDDF[zr]->m_sName,o->m_waSaveRefList[z2]+1,multibuf); mprintf(" Saving temporal development as %s\n",(const char*)buf); } } /* mprintf(" Speichere Winkel-Statistik als %s_angle_stat.txt\n",o->m_sName); FreeFileName("",o->m_sName,"_angle_stat.txt"); o->m_pAngleStat->Evaluate(); o->m_pAngleStat->Write("",o->m_sName,"_angle_stat.txt"); // delete o->m_pAngleStat;*/ delete[] o->m_pDDF[zr]->m_fAngle; o->m_pDDF[zr]->m_fAngle = NULL; if (o->m_bCombinedPlot) { // sprintf(buf,"combined_%s%s.agr",o->m_pDDF[zr]->m_sName,multibuf); buf.sprintf("combined_%s%s.agr",o->m_pDDF[zr]->m_sName,multibuf); mprintf(" Saving combined plot as \"%s\"...\n",(const char*)buf); o->m_pDDF[zr]->m_pDDF->CreateCombinedPlot(false); o->m_pDDF[zr]->m_pDDF->m_pCombinedPlot->WriteAgr(buf,false); } } // END IF TIMEDEV /* if (o->m_pDDF->m_iStat != 0) { mprintf(" Korrigiere statistische Verteilung...\n"); o->m_pDDF->m_pDDF->AngleCorrect(); }*/ // sprintf(buf,"ddf_%s%s.csv",o->m_pDDF[zr]->m_sName,multibuf); buf.sprintf("ddf_%s%s.csv",o->m_pDDF[zr]->m_sName,multibuf); mprintf(" Saving DDF as %s ...\n",(const char*)buf); o->m_pDDF[zr]->m_pDDF->NormBinIntegral(); o->m_pDDF[zr]->m_pDDF->Write("",buf,"",false); // sprintf(buf,"ddf_%s%s.agr",o->m_pDDF[zr]->m_sName,multibuf); buf.sprintf("ddf_%s%s.agr",o->m_pDDF[zr]->m_sName,multibuf); mprintf(" Saving DDF AGR file as \"%s\"...\n",(const char*)buf); if (o->m_pDDF[zr]->m_bCosine) o->m_pDDF[zr]->m_pDDF->WriteAgr("",buf,"",o->m_pDDF[zr]->m_sName,false); else o->m_pDDF[zr]->m_pDDF->WriteAgr("",buf,"",o->m_pDDF[zr]->m_sName,false); if (o->m_pDDF[zr]->m_iHistogramRes != 0) { mprintf(" Calculating Histogram...\n"); o->m_pDDF[zr]->m_pDDF->CalcHistogram(); // sprintf(buf,"his_ddf_%s%s.csv",o->m_pDDF[zr]->m_sName,multibuf); buf.sprintf("his_ddf_%s%s.csv",o->m_pDDF[zr]->m_sName,multibuf); mprintf(" Saving Histogram as \"%s\"...\n",(const char*)buf); o->m_pDDF[zr]->m_pDDF->WriteHistogram("",buf,""); } if (o->m_bObsCertain && o->m_bDecompDist) { // sprintf(buf,"ddf_decomp_%s%s.csv",o->m_pDDF[zr]->m_sName,multibuf); buf.sprintf("ddf_decomp_%s%s.csv",o->m_pDDF[zr]->m_sName,multibuf); mprintf(" Saving DDF decomposition as \"%s\"...\n",(const char*)buf); o->m_pDDF[zr]->m_pDDF->WriteMulti("",buf,""); // sprintf(buf,"ddf_decomp_%s%s_cumulative.csv",o->m_pDDF[zr]->m_sName,multibuf); buf.sprintf("ddf_decomp_%s%s_cumulative.csv",o->m_pDDF[zr]->m_sName,multibuf); mprintf(" Saving cumulative DDF decomposition as \"%s\"...\n",(const char*)buf); o->m_pDDF[zr]->m_pDDF->WriteMulti_Cumulative("",buf,""); } if (o->m_bTimeDiff) o->WriteTimeDiff(o->m_pDDF[zr]->m_pDDF,"DDF","ddf",o->m_pDDF[zr]->m_sName,multibuf,true); } } // END IF DDF if (g_bSDF) { mprintf(WHITE,"\n* Spatial Distribution Function\n"); mprintf(" %.0f bin entries, %.0f out of bin range (%.2f percent).\n",o->m_pSDF->m_pSDF->m_fBinEntries,o->m_pSDF->m_pSDF->m_fSkipEntries,ZeroDivide(o->m_pSDF->m_pSDF->m_fSkipEntries,o->m_pSDF->m_pSDF->m_fBinEntries+o->m_pSDF->m_pSDF->m_fSkipEntries)*100.0); o->m_pSDF->m_pSDF->CalcMaxEntry(); mprintf(" Raw data range from %.0f to %.0f hits.\n",o->m_pSDF->m_pSDF->m_fMinEntry,o->m_pSDF->m_pSDF->m_fMaxEntry); mprintf(" The volume of one bin is %.3f pm^3.\n",pow3(o->m_pSDF->m_fRadius*2.0/o->m_pSDF->m_iResolution)); o->m_pSDF->m_pSDF->CalcMaxEntry(); mprintf(" Max. bin entry: %.6E --> EPS: %.6E\n",o->m_pSDF->m_pSDF->m_fMaxEntry,o->m_pSDF->m_pSDF->m_fEps); if (o->m_pSDF->m_pSDF->m_fEps > 1.0E-4) { eprintf("\n Warning: Very large bin entries - probably loss of accuracy occured.\n"); mprintf(" Please reduce the bin counts (e.g. by analyzing only every 10th step).\n\n"); } if (g_bPeriodicX && g_bPeriodicY && g_bPeriodicZ) mprintf(" The uniform particle density of this observation is %.6f nm^-3.\n",o->m_pSDF->m_fParticleDensity); else mprintf(" The uniform particle density of non-periodic boxes is not defined.\n"); /* switch(g_iSDFScale) { case 0: mprintf(" Scaling values to ppm...\n"); o->m_pSDF->m_pSDF->MultiplyBin(1000000.0 / (double)g_iSteps / ((CMolecule*)g_oaMolecules[g_iFixMol])->m_laSingleMolIndex.GetSize() / o->m_pSDF->m_iShowAtomGes * (g_bDoubleBox?g_iDoubleBoxFactor:1)); break; case 1: mprintf(" Scaling values to pm^-3...\n"); o->m_pSDF->m_pSDF->MultiplyBin(pow(o->m_pSDF->m_iResolution/o->m_pSDF->m_fRadius,3) / (double)g_iSteps / ((CMolecule*)g_oaMolecules[g_iFixMol])->m_laSingleMolIndex.GetSize() / o->m_pSDF->m_iShowAtomGes * (g_bDoubleBox?g_iDoubleBoxFactor:1)); break; case 2: mprintf(" Scaling values to nm^-3...\n");*/ /* break; case 3: mprintf(" Scaling values relative to average particle density...\n"); o->m_pSDF->m_pSDF->MultiplyBin(pow(o->m_pSDF->m_iResolution/o->m_pSDF->m_fRadius*1000.0,3) / (double)g_iSteps / ((CMolecule*)g_oaMolecules[g_iFixMol])->m_laSingleMolIndex.GetSize() / o->m_pSDF->m_iShowAtomGes / o->m_pSDF->m_fParticleDensity * (g_bDoubleBox?g_iDoubleBoxFactor:1)); break; }*/ o->m_pSDF->m_pSDF->MultiplyBin(pow3(o->m_pSDF->m_iResolution/o->m_pSDF->m_fRadius/2.0*1000.0) / (double)g_iSteps * g_iStride / ((CMolecule*)g_oaMolecules[g_iFixMol])->m_laSingleMolIndex.GetSize() / o->m_pSDF->m_iShowAtomGes * (g_bDoubleBox?g_iDoubleBoxFactor:1)); if (g_bSDFUniform) { if ((!g_bPeriodicX) || (!g_bPeriodicY) || (!g_bPeriodicZ)) goto _sdf_nm; o->m_pSDF->m_pSDF->MultiplyBin(1.0/o->m_pSDF->m_fParticleDensity); mprintf(WHITE," Bin values are given relative to this uniform particle density.\n"); } else { _sdf_nm: mprintf(WHITE," Bin values are given in nm^-3 (particle density).\n"); } o->m_pSDF->m_pSDF->CalcMaxEntry(); mprintf(" Data range from %.6f to %.6f%s.\n",o->m_pSDF->m_pSDF->m_fMinEntry,o->m_pSDF->m_pSDF->m_fMaxEntry,g_bSDFUniform?"":" nm^-3"); if (o->m_pSDF->m_bInvert) { mprintf(" Inverting SDF...\n"); o->m_pSDF->m_pSDF->Invert(); } if (o->m_pSDF->m_bCutPlane) { mprintf(" Creating Cut Plane...\n"); o->m_pSDF->CreateCutPlane(); // sprintf(buf,"sdf_cut_%s%s",o->m_pSDF->m_sName,multibuf); buf.sprintf("sdf_cut_%s%s",o->m_pSDF->m_sName,multibuf); mprintf(" Saving SDF Cut Plane triples as \"%s_triples.csv\"...\n",(const char*)buf); o->m_pSDF->m_pCutPlane->Write("",buf,"_triples.csv"); mprintf(" Saving SDF Cut Plane matrix as \"%s_matrix.csv\"...\n",(const char*)buf); o->m_pSDF->m_pCutPlane->WriteCSV("",buf,"_matrix.csv"); mprintf(" Saving CDF Mathematica Notebook as \"%s.nb\"...\n",(const char*)buf); o->m_pSDF->m_pCutPlane->WriteMathematicaNb("",buf,".nb",false); mprintf(" Saving CDF Gnuplot Input as \"%s.gp\"...\n",(const char*)buf); o->m_pSDF->m_pCutPlane->WriteGnuplotInput("",buf,"",false); } for (z2=0;z2<=g_iSDFSmoothGrade;z2++) { try { tempSDF = new C3DF(); } catch(...) { tempSDF = NULL; } if (tempSDF == NULL) NewException((double)sizeof(C3DF),__FILE__,__LINE__,__PRETTY_FUNCTION__); tempSDF->CopyFrom(o->m_pSDF->m_pSDF); if (z2 != 0) tempSDF->Smooth(z2); tempSDF->CalcMaxEntry(); mprintf(" Data range from %.6f to %.6f%s.\n",tempSDF->m_fMinEntry,tempSDF->m_fMaxEntry,g_bSDFUniform?"":" nm^-3"); if (o->m_pSDF->m_bClipPlane) { mprintf(" Creating Clip Plane in %c direction with value %.3f...\n",(o->m_pSDF->m_iClipDirection==0)?'X':((o->m_pSDF->m_iClipDirection==1)?'Y':'Z'),o->m_pSDF->m_fClipValue); o->m_pSDF->m_pSDF->ClipPlane(o->m_pSDF->m_iClipDirection,o->m_pSDF->m_fClipValue); } if (g_pDatabase->GetBool("/PLOT3D/FORMATS/WRITE_PLT")) { if (z2 != 0) // sprintf(buf,".s%d%s.plt",z2,multibuf); buf.sprintf(".s%d%s.plt",z2,multibuf); else // sprintf(buf,"%s.plt",multibuf); buf.sprintf("%s.plt",multibuf); mprintf(" Saving SDF as \"sdf_%s%s\"...\n",o->m_pSDF->m_sName,(const char*)buf); tempSDF->WritePLT("sdf_",o->m_pSDF->m_sName,buf,true); } if (g_pDatabase->GetBool("/PLOT3D/FORMATS/WRITE_CUBE")) { if (z2 != 0) // sprintf(buf,".s%d%s.cube",z2,multibuf); buf.sprintf(".s%d%s.cube",z2,multibuf); else // sprintf(buf,"%s.cube",multibuf); buf.sprintf("%s.cube",multibuf); mprintf(" Saving SDF as \"sdf_%s%s\"...\n",o->m_pSDF->m_sName,(const char*)buf); tempSDF->WriteCube("sdf_",o->m_pSDF->m_sName,buf,true); } if (o->m_pSDF->m_iHistogramRes != 0) { if (z2 != 0) // sprintf(buf,".s%d%s.csv",z2,multibuf); buf.sprintf(".s%d%s.csv",z2,multibuf); else // sprintf(buf,"%s.csv",multibuf); buf.sprintf("%s.csv",multibuf); mprintf(" Saving SDF Histogram as \"his_sdf_%s%s\"...\n",o->m_pSDF->m_sName,(const char*)buf); tempSDF->CalcHistogram(); tempSDF->WriteHistogram("his_sdf_",o->m_pSDF->m_sName,buf); } } mprintf(YELLOW,"\n Important: "); mprintf(WHITE,"The PLT/CUBE files only contain the volumetric data.\n"); mprintf(WHITE," The atoms of the reference molecule are saved in the ref_*.xyz file!\n"); mprintf(WHITE," You need to load *both files* into the visualization program (e.g. VMD).\n"); } // END IF SDF if (g_bPlProj) { mprintf(WHITE,"\n* Plane Projection Distribution Function\n"); mprintf(" %.0f bin entries, %.0f out of bin range (%.2f percent).\n",o->m_pPlProj->m_p2DF->m_fBinEntries,o->m_pPlProj->m_p2DF->m_fSkipEntries,ZeroDivide(o->m_pPlProj->m_p2DF->m_fSkipEntries,o->m_pPlProj->m_p2DF->m_fBinEntries+o->m_pPlProj->m_p2DF->m_fSkipEntries)*100.0); if (o->m_pPlProj->m_p2DF->m_fBinEntries == 0) { eprintf(" There were no bin entries. Check your function definition. Skipping this Plane Projection DF.\n\n"); goto _skipplproj; } o->m_pPlProj->m_p2DF->CalcMaxEntry(); mprintf(" Raw data range from %.0f to %.0f hits.\n",o->m_pPlProj->m_p2DF->m_fMinEntry,o->m_pPlProj->m_p2DF->m_fMaxEntry); mprintf(" The volume of one bin is %.3f pm^3.\n",(o->m_pPlProj->m_fMaxVal[0]-o->m_pPlProj->m_fMinVal[0])*(o->m_pPlProj->m_fMaxVal[1]-o->m_pPlProj->m_fMinVal[1])*(o->m_pPlProj->m_fSliceBorder[1]-o->m_pPlProj->m_fSliceBorder[0])/o->m_pPlProj->m_iResolution[0]/o->m_pPlProj->m_iResolution[1]); o->m_pPlProj->m_p2DF->CalcMaxEntry(); mprintf(" Max. bin entry: %.6E --> EPS: %.6E\n",o->m_pPlProj->m_p2DF->m_fMaxEntry,o->m_pPlProj->m_p2DF->m_fEps); if (o->m_pPlProj->m_p2DF->m_fEps > 1.0E-4) { eprintf("\n Warning: Very large bin entries - probably loss of accuracy occured.\n"); mprintf(" Please reduce the bin counts (e.g. by analyzing only every 10th step).\n\n"); } if ((g_bPeriodicX) && (g_bPeriodicY) && (g_bPeriodicZ)) { mprintf(" System is periodic, normalizing values to uniform density.\n"); mprintf(" The uniform particle density of this observation is %.6f nm^-3.\n",o->m_pPlProj->m_fParticleDensity); // mprintf(" (%f)\n",(double)o->m_pPlProj->m_iResolution[0]*o->m_pPlProj->m_iResolution[1]/(o->m_pPlProj->m_fMaxVal[0]-o->m_pPlProj->m_fMinVal[0])/(o->m_pPlProj->m_fMaxVal[1]-o->m_pPlProj->m_fMinVal[1])/(o->m_pPlProj->m_fSliceBorder[1]-o->m_pPlProj->m_fSliceBorder[0])*1.0e9 / (double)g_iSteps / ((CMolecule*)g_oaMolecules[g_iFixMol])->m_laSingleMolIndex.GetSize() / o->m_pPlProj->m_iShowAtomGes * (g_bDoubleBox?g_iDoubleBoxFactor:1)); // mprintf(" o->m_pPlProj->m_iShowAtomGes = %d\n",o->m_pPlProj->m_iShowAtomGes); // mprintf(" 1/Vol = %f\n",(double)o->m_pPlProj->m_iResolution[0]*o->m_pPlProj->m_iResolution[1]/(o->m_pPlProj->m_fMaxVal[0]-o->m_pPlProj->m_fMinVal[0])/(o->m_pPlProj->m_fMaxVal[1]-o->m_pPlProj->m_fMinVal[1])/(o->m_pPlProj->m_fSliceBorder[1]-o->m_pPlProj->m_fSliceBorder[0])*1.0e9); o->m_pPlProj->m_p2DF->MultiplyBin((double)o->m_pPlProj->m_iResolution[0]*o->m_pPlProj->m_iResolution[1]/(o->m_pPlProj->m_fMaxVal[0]-o->m_pPlProj->m_fMinVal[0])/(o->m_pPlProj->m_fMaxVal[1]-o->m_pPlProj->m_fMinVal[1])/(o->m_pPlProj->m_fSliceBorder[1]-o->m_pPlProj->m_fSliceBorder[0])*1.0e9 / (double)g_iSteps * g_iStride / ((CMolecule*)g_oaMolecules[g_iFixMol])->m_laSingleMolIndex.GetSize() /* / o->m_pPlProj->m_iShowAtomGes*/ * (g_bDoubleBox?g_iDoubleBoxFactor:1)); // mprintf(" (%f)\n",1.0/o->m_pPlProj->m_fParticleDensity); o->m_pPlProj->m_p2DF->MultiplyBin(1.0/o->m_pPlProj->m_fParticleDensity); } else { mprintf(" System is non-periodic, normalizing integral value to %.2f.\n",1000000.0); o->m_pPlProj->m_p2DF->NormalizeBinIntegral(1000000.0); } o->m_pPlProj->m_p2DF->CalcMaxEntry(); mprintf(" Resulting data range from %.6f to %.6f.\n",o->m_pPlProj->m_p2DF->m_fMinEntry,o->m_pPlProj->m_p2DF->m_fMaxEntry); if (o->m_pPlProj->m_bDrawAtoms) { mprintf(" Inserting reference atoms into the Plane Projection DF plot...\n"); ti = 0; for (z3=0;z3m_pPlProj->m_oDrawAtoms.m_oaAtoms.GetSize();z3++) { ti2 = o->m_pPlProj->m_oDrawAtoms.m_baRealAtomType[z3]; for (z4=0;z4<((CxIntArray*)o->m_pPlProj->m_oDrawAtoms.m_oaAtoms[z3])->GetSize();z4++) { if (o->m_pPlProj->m_bAverageAtomPos) o->m_pPlProj->m_vaAtomPos[ti] /= o->m_pPlProj->m_iAverageCounter; if (((CAtom*)g_oaAtoms[ti2])->m_pElement->m_fRadius == 0) o->m_pPlProj->m_p2DF->AddCircle(o->m_pPlProj->m_vaAtomPos[ti][0],o->m_pPlProj->m_vaAtomPos[ti][1],25.0,0.4,0.4,0.4); else o->m_pPlProj->m_p2DF->AddCircle(o->m_pPlProj->m_vaAtomPos[ti][0],o->m_pPlProj->m_vaAtomPos[ti][1],((CAtom*)g_oaAtoms[ti2])->m_pElement->m_fRadius*0.6,((CAtom*)g_oaAtoms[ti2])->m_pElement->m_iColorR/255.0,((CAtom*)g_oaAtoms[ti2])->m_pElement->m_iColorG/255.0,((CAtom*)g_oaAtoms[ti2])->m_pElement->m_iColorB/255.0); ti++; } } } mprintf(" Saving Plane Projection DF triples as \"%s%s_triples.csv\"...\n",o->m_pPlProj->m_sName,multibuf); o->m_pPlProj->m_p2DF->Write(o->m_pPlProj->m_sName,multibuf,"_triples.csv"); mprintf(" Saving Plane Projection DF matrix as \"%s%s_matrix.csv\"...\n",o->m_pPlProj->m_sName,multibuf); o->m_pPlProj->m_p2DF->WriteCSV(o->m_pPlProj->m_sName,multibuf,"_matrix.csv"); mprintf(" Saving Plane Projection DF Mathematica Notebook as \"%s%s.nb\"...\n",o->m_pPlProj->m_sName,multibuf); o->m_pPlProj->m_p2DF->WriteMathematicaNb(o->m_pPlProj->m_sName,multibuf,".nb",false); mprintf(" Saving Plane Projection DF Gnuplot Input as \"%s%s.gp\"...\n",o->m_pPlProj->m_sName,multibuf); o->m_pPlProj->m_p2DF->WriteGnuplotInput(o->m_pPlProj->m_sName,multibuf,"",false); if (o->m_pPlProj->m_iHistogramRes != 0) { mprintf(" Calculating Histogram...\n"); o->m_pPlProj->m_p2DF->CalcHistogram(); // sprintf(buf,"his_%s",o->m_pPlProj->m_sName); buf.sprintf("his_%s",o->m_pPlProj->m_sName); mprintf(" Saving Histogram as \"%s%s.csv\"...\n",(const char*)buf,multibuf); o->m_pPlProj->m_p2DF->WriteHistogram(buf,multibuf,".csv"); } mprintf(WHITE,"\n Note: "); mprintf("The atoms of the ref. molecule are only drawn in the Mathematica Notebook (.nb)!\n\n"); _skipplproj:; } // END IF PlProj if (g_bRDF) { for (zr=0;zrm_pRDF[zr] == NULL) continue; mprintf(WHITE,"\n* Radial Distribution Function\n"); mprintf(" %.0f bin entries, %.0f out of bin range (%.2f percent).\n",o->m_pRDF[zr]->m_pRDF->m_fBinEntries,o->m_pRDF[zr]->m_pRDF->m_fSkipEntries,ZeroDivide(o->m_pRDF[zr]->m_pRDF->m_fSkipEntries,o->m_pRDF[zr]->m_pRDF->m_fBinEntries+o->m_pRDF[zr]->m_pRDF->m_fSkipEntries)*100.0); o->m_pRDF[zr]->m_pRDF->CalcMinMax(); mprintf(" Max. bin entry: %.6E --> EPS: %.6E\n",o->m_pRDF[zr]->m_pRDF->m_fMaxEntry,o->m_pRDF[zr]->m_pRDF->m_fEps); if (o->m_pRDF[zr]->m_pRDF->m_fEps > 1.0E-4) { eprintf("\n Warning: Very large bin entries - probably loss of accuracy occured.\n"); mprintf(" Please reduce the bin counts (e.g. by analyzing only every 10th step).\n\n"); } o->m_pRDF[zr]->m_pRDF->CalcMeanSD(); mprintf(" Mean value: %10G pm Standard deviation: %10G pm\n",o->m_pRDF[zr]->m_pRDF->m_fMean,o->m_pRDF[zr]->m_pRDF->m_fSD); mprintf(" Min. value: %10G pm Max.value: %10G pm\n",o->m_pRDF[zr]->m_pRDF->m_fMinInput,o->m_pRDF[zr]->m_pRDF->m_fMaxInput); o->m_pRDF[zr]->m_pRDF->MultiplyBin(1.0 / g_iSteps * g_iStride); if (o->m_pRDF[zr]->m_bAdaptive) { // o->m_pRDF[zr]->m_pRDF->WriteHenry("rdf_",o->m_pRDF[zr]->m_sName,".csv"); o->m_pRDF[zr]->m_pRDF->PrepareAdapt(); o->m_pRDF[zr]->m_pRDF->BinTree_RadialDist(); if (o->m_iShowMol == g_iFixMol) o->m_pRDF[zr]->m_pRDF->BinTree_MultiplyBin(3.0/4.0/Pi/g_iSteps*g_fBoxX*g_fBoxY*g_fBoxZ/(((CMolecule*)g_oaMolecules[g_iFixMol])->m_laSingleMolIndex.GetSize()-1.0)/o->m_pRDF[zr]->m_iShowAtomGes/((CMolecule*)g_oaMolecules[g_iFixMol])->m_laSingleMolIndex.GetSize()/o->m_pRDF[zr]->m_iRefAtomGes); else o->m_pRDF[zr]->m_pRDF->BinTree_MultiplyBin(3.0/4.0/Pi/g_iSteps*g_fBoxX*g_fBoxY*g_fBoxZ/((CMolecule*)g_oaMolecules[g_iFixMol])->m_laSingleMolIndex.GetSize() /o->m_pRDF[zr]->m_iShowAtomGes/((CMolecule*)g_oaMolecules[o->m_iShowMol])->m_laSingleMolIndex.GetSize()/o->m_pRDF[zr]->m_iRefAtomGes); mprintf(" Saving RDF as \"rdf_%s.csv\"...\n",o->m_pRDF[zr]->m_sName); o->m_pRDF[zr]->m_pRDF->WriteAdapted("rdf_",o->m_pRDF[zr]->m_sName,".001.csv",5,10,0.001,true); o->m_pRDF[zr]->m_pRDF->WriteAdapted("rdf_",o->m_pRDF[zr]->m_sName,".002.csv",5,10,0.002,true); o->m_pRDF[zr]->m_pRDF->WriteAdapted("rdf_",o->m_pRDF[zr]->m_sName,".005.csv",5,10,0.005,true); o->m_pRDF[zr]->m_pRDF->WriteAdapted("rdf_",o->m_pRDF[zr]->m_sName,".010.csv",5,10,0.01,true); o->m_pRDF[zr]->m_pRDF->WriteAdapted("rdf_",o->m_pRDF[zr]->m_sName,".020.csv",5,10,0.02,true); o->m_pRDF[zr]->m_pRDF->WriteAdapted("rdf_",o->m_pRDF[zr]->m_sName,".050.csv",5,10,0.05,true); o->m_pRDF[zr]->m_pRDF->WriteAdapted("rdf_",o->m_pRDF[zr]->m_sName,".100.csv",5,10,0.1,true); /* o->m_pRDF[zr]->m_pRDF->WriteAdapted("rdf_",o->m_pRDF[zr]->m_sName,".50.csv",16,0,50,true); o->m_pRDF[zr]->m_pRDF->WriteAdapted("rdf_",o->m_pRDF[zr]->m_sName,".100.csv",16,0,100,true); o->m_pRDF[zr]->m_pRDF->WriteAdapted("rdf_",o->m_pRDF[zr]->m_sName,".500.csv",16,0,500,true); o->m_pRDF[zr]->m_pRDF->WriteAdapted("rdf_",o->m_pRDF[zr]->m_sName,".1000.csv",16,0,1000,true);*/ } else { if (o->m_pRDF[zr]->m_bRadialCorrect) { mprintf(" Correcting radial distribution...\n"); if (o->m_pRDF[zr]->m_bLongMode) { o->m_pRDF[zr]->m_pRDF->CorrectRadialDistLong(); } else { o->m_pRDF[zr]->m_pRDF->CorrectRadialDist(); } } if (o->m_bOthers && o->m_pRDF[zr]->m_bRadialCorrect) { if (o->m_pRDF[zr]->m_bProbDens) { mprintf(" Scaling RDF to nm^(-3) ...\n"); if (o->m_bObsCertain) { o->m_pRDF[zr]->m_pRDF->Integrate(true,1.0 / o->m_waObsRefList.GetSize()); o->m_pRDF[zr]->m_pRDF->MultiplyBin(1e9 / (4.0/3.0*Pi) / o->m_waObsRefList.GetSize() / o->m_pRDF[zr]->m_iRefAtomGes); } else { o->m_pRDF[zr]->m_pRDF->Integrate(true,1.0 / (double)((CMolecule*)g_oaMolecules[g_iFixMol])->m_laSingleMolIndex.GetSize() / o->m_pRDF[zr]->m_iRefAtomGes); o->m_pRDF[zr]->m_pRDF->MultiplyBin(1e9 / (4.0/3.0*Pi) / ((CMolecule*)g_oaMolecules[g_iFixMol])->m_laSingleMolIndex.GetSize() / o->m_pRDF[zr]->m_iRefAtomGes); } if (g_bDoubleBox) { o->m_pRDF[zr]->m_pRDF->MultiplyBin(g_iDoubleBoxFactor); o->m_pRDF[zr]->m_pRDF->MultiplyIntegral(g_iDoubleBoxFactor); } } else { mprintf(" Scaling RDF to uniform density ...\n"); if (g_bPeriodicX && g_bPeriodicY && g_bPeriodicZ) { // Bugfix MB 15.04.2018 --> reverted on 21.12.2018 //if (g_iFixMol == o->m_iShowMol) // ti = ((CMolecule*)g_oaMolecules[o->m_iShowMol])->m_laSingleMolIndex.GetSize() - 1; //else // ti = ((CMolecule*)g_oaMolecules[o->m_iShowMol])->m_laSingleMolIndex.GetSize(); ti = ((CMolecule*)g_oaMolecules[o->m_iShowMol])->m_laSingleMolIndex.GetSize(); if (o->m_bObsCertain) { o->m_pRDF[zr]->m_pRDF->Integrate(true,1.0 / o->m_waObsRefList.GetSize()); o->m_pRDF[zr]->m_pRDF->MultiplyBin(g_fBoxX*g_fBoxY*g_fBoxZ / (4.0/3.0*Pi) / o->m_waObsRefList.GetSize() / o->m_pRDF[zr]->m_iShowAtomGes / o->m_waObsShowList.GetSize() / o->m_pRDF[zr]->m_iRefAtomGes); } else { if (g_bRegionAnalysis) { o->m_pRDF[zr]->m_pRDF->Integrate(true,1.0 * g_iSteps / (o->m_pRDF[zr]->m_pRDF->m_fBinEntries + o->m_pRDF[zr]->m_pRDF-> m_fSkipEntries) * o->m_pRDF[zr]->m_iShowAtomGes * ((CMolecule*)g_oaMolecules[o->m_iShowMol])->m_laSingleMolIndex.GetSize() * o->m_pRDF[zr]->m_iRefAtomGes); o->m_pRDF[zr]->m_pRDF->MultiplyBin(g_fBoxX*g_fBoxY*g_fBoxZ * g_iSteps / (4.0/3.0*Pi) / (o->m_pRDF[zr]->m_pRDF->m_fBinEntries + o->m_pRDF[zr]->m_pRDF-> m_fSkipEntries) ); } else { if (g_bBoxNonOrtho) { o->m_pRDF[zr]->m_pRDF->Integrate(true,1.0 / (double)((CMolecule*)g_oaMolecules[g_iFixMol])->m_laSingleMolIndex.GetSize() / o->m_pRDF[zr]->m_iRefAtomGes); o->m_pRDF[zr]->m_pRDF->MultiplyBin(g_fBoxVolume*1000000.0 / (4.0/3.0*Pi) / ((CMolecule*)g_oaMolecules[g_iFixMol])->m_laSingleMolIndex.GetSize() / o->m_pRDF[zr]->m_iShowAtomGes / ti / o->m_pRDF[zr]->m_iRefAtomGes); } else { o->m_pRDF[zr]->m_pRDF->Integrate(true,1.0 / (double)((CMolecule*)g_oaMolecules[g_iFixMol])->m_laSingleMolIndex.GetSize() / o->m_pRDF[zr]->m_iRefAtomGes); o->m_pRDF[zr]->m_pRDF->MultiplyBin(g_fBoxX*g_fBoxY*g_fBoxZ / (4.0/3.0*Pi) / ((CMolecule*)g_oaMolecules[g_iFixMol])->m_laSingleMolIndex.GetSize() / o->m_pRDF[zr]->m_iShowAtomGes / ti / o->m_pRDF[zr]->m_iRefAtomGes); } } } if (g_bDoubleBox) { o->m_pRDF[zr]->m_pRDF->MultiplyBin(g_iDoubleBoxFactor); o->m_pRDF[zr]->m_pRDF->MultiplyIntegral(g_iDoubleBoxFactor); } } else { eprintf(" Uniform density not defined if box is not XYZ-periodic!\n"); goto _rdfint1; } } } else { _rdfint1: mprintf(" Scaling RDF to integral value 1000 ...\n"); o->m_pRDF[zr]->m_pRDF->NormBinIntegral(1000.0); o->m_pRDF[zr]->m_pRDF->Integrate(false,1000.0); } // sprintf(buf,"rdf_%s%s.csv",o->m_pRDF[zr]->m_sName,multibuf); buf.sprintf("rdf_%s%s.csv",o->m_pRDF[zr]->m_sName,multibuf); mprintf(" Saving RDF as \"%s\"...\n",(const char*)buf); o->m_pRDF[zr]->m_pRDF->Write("",buf,"",true); // sprintf(buf,"rdf_%s%s.agr",o->m_pRDF[zr]->m_sName,multibuf); buf.sprintf("rdf_%s%s.agr",o->m_pRDF[zr]->m_sName,multibuf); mprintf(" Saving RDF AGR file as \"%s\"...\n",(const char*)buf); o->m_pRDF[zr]->m_pRDF->WriteAgr("",buf,"",o->m_pRDF[zr]->m_sName,o->m_pRDF[zr]->m_bLine); if (o->m_pRDF[zr]->m_iHistogramRes != 0) { mprintf(" Calculating Histogram...\n"); o->m_pRDF[zr]->m_pRDF->CalcHistogram(); // sprintf(buf,"his_rdf_%s%s.csv",o->m_pRDF[zr]->m_sName,multibuf); buf.sprintf("his_rdf_%s%s.csv",o->m_pRDF[zr]->m_sName,multibuf); mprintf(" Saving Histogram as \"%s\"...\n",(const char*)buf); o->m_pRDF[zr]->m_pRDF->WriteHistogram("",buf,""); } if (o->m_bObsCertain && o->m_bDecompDist) { // sprintf(buf,"rdf_decomp_mol_%s%s",o->m_pRDF[zr]->m_sName,multibuf); buf.sprintf("rdf_decomp_mol_%s%s",o->m_pRDF[zr]->m_sName,multibuf); mprintf(" Saving RDF molecule decomposition as \"%s.csv\"...\n",(const char*)buf); o->m_pRDF[zr]->m_pRDF->WriteMulti("",buf,".csv"); mprintf(" Saving RDF molecule decomposition as \"%s.agr\"...\n",(const char*)buf); o->m_pRDF[zr]->m_pRDF->WriteMultiAgr("",buf,".agr",buf,true); // sprintf(buf,"rdf_decomp_nb_%s%s_cumulative",o->m_pRDF[zr]->m_sName,multibuf); buf.sprintf("rdf_decomp_nb_%s%s_cumulative",o->m_pRDF[zr]->m_sName,multibuf); mprintf(" Saving cumulative RDF molecule decomposition as \"%s.csv\"...\n",(const char*)buf); o->m_pRDF[zr]->m_pRDF->WriteMulti_Cumulative("",buf,".csv"); mprintf(" Saving cumulative RDF molecule decomposition as \"%s.agr\"...\n",(const char*)buf); o->m_pRDF[zr]->m_pRDF->WriteMultiAgr_Cumulative("",buf,".agr",buf,true); } if (o->m_bDecompType) { // sprintf(buf,"rdf_decomp_type_%s%s",o->m_pRDF[zr]->m_sName,multibuf); buf.sprintf("rdf_decomp_type_%s%s",o->m_pRDF[zr]->m_sName,multibuf); mprintf(" Saving RDF type decomposition as \"%s.csv\"...\n",(const char*)buf); o->m_pRDF[zr]->m_pRDF->WriteMulti("",buf,".csv"); mprintf(" Saving RDF type decomposition as \"%s.agr\"...\n",(const char*)buf); o->m_pRDF[zr]->m_pRDF->WriteMultiAgr("",buf,".agr",buf,true); // sprintf(buf,"rdf_decomp_type_%s%s_cumulative",o->m_pRDF[zr]->m_sName,multibuf); buf.sprintf("rdf_decomp_type_%s%s_cumulative",o->m_pRDF[zr]->m_sName,multibuf); mprintf(" Saving cumulative RDF type decomposition as \"%s.csv\"...\n",(const char*)buf); o->m_pRDF[zr]->m_pRDF->WriteMulti_Cumulative("",buf,".csv"); mprintf(" Saving cumulative RDF type decomposition as \"%s.agr\"...\n",(const char*)buf); o->m_pRDF[zr]->m_pRDF->WriteMultiAgr_Cumulative("",buf,".agr",buf,true); } if (o->m_bTimeDiff) o->WriteTimeDiff(o->m_pRDF[zr]->m_pRDF,"RDF","rdf",o->m_pRDF[zr]->m_sName,multibuf,false); if (o->m_pRDF[zr]->m_bACF) { o->m_pRDF[zr]->Autocorrelate(); } } if (o->m_bTimeDev) { if ((o->m_waSaveRefList.GetSize() == 1) || (!o->m_bSaveSeparateFiles)) { fclose(o->m_pRDF[zr]->m_fDist[0]); mprintf(" Saving temporal development as \"rdf_timedev_%s%s.csv\"...\n",o->m_pRDF[zr]->m_sName,multibuf); } else { for (z2=0;z2m_waSaveRefList.GetSize();z2++) { fclose(o->m_pRDF[zr]->m_fDist[z2]); // sprintf(buf,"rdf_timedev_%s_ref%d%s.csv",o->m_pRDF[zr]->m_sName,o->m_waSaveRefList[z2]+1,multibuf); buf.sprintf("rdf_timedev_%s_ref%d%s.csv",o->m_pRDF[zr]->m_sName,o->m_waSaveRefList[z2]+1,multibuf); mprintf(" Saving temporal development as \"%s\"...\n",(const char*)buf); } } delete[] o->m_pRDF[zr]->m_fDist; o->m_pRDF[zr]->m_fDist = NULL; if (o->m_bCombinedPlot) { // sprintf(buf,"combined_%s%s.agr",o->m_pRDF[zr]->m_sName,multibuf); buf.sprintf("combined_%s%s.agr",o->m_pRDF[zr]->m_sName,multibuf); mprintf(" Saving combined plot as \"%s\"...\n",(const char*)buf); o->m_pRDF[zr]->m_pRDF->CreateCombinedPlot(true); o->m_pRDF[zr]->m_pRDF->m_pCombinedPlot->WriteAgr(buf,false); } } } } // END IF RDF if (g_bVHDF) { mprintf(WHITE,"\n* Van Hove Correlation Function\n"); mprintf(" %.0f bin entries, %.0f out of bin range (%.2f percent).\n",o->m_pVHDF->m_pVHDF->m_fBinEntries,o->m_pVHDF->m_pVHDF->m_fSkipEntries,ZeroDivide(o->m_pVHDF->m_pVHDF->m_fSkipEntries,o->m_pVHDF->m_pVHDF->m_fBinEntries+o->m_pVHDF->m_pVHDF->m_fSkipEntries)*100.0); o->m_pVHDF->CorrectCount(); if (o->m_pVHDF->m_bRadialCorrect) { mprintf(" Correcting radial distribution...\n"); o->m_pVHDF->m_pVHDF->CorrectRadialDist(1); if (g_bPeriodicX && g_bPeriodicY && g_bPeriodicZ) { mprintf(" Normalizing bin to uniform density...\n"); o->m_pVHDF->m_pVHDF->MultiplyBin(3.0/4.0/Pi*g_fBoxX*g_fBoxY*g_fBoxZ); } if (g_bDoubleBox) o->m_pVHDF->m_pVHDF->MultiplyBin(g_iDoubleBoxFactor); } else { mprintf(" Normalizing bin integral to 1000000...\n"); o->m_pVHDF->m_pVHDF->NormalizeBinIntegral(1000000.0); } // sprintf(buf,"vhcf_%s%s",o->m_pVHDF->m_sName,multibuf); buf.sprintf("vhcf_%s%s",o->m_pVHDF->m_sName,multibuf); if (g_pDatabase->GetBool("/PLOT2D/FORMATS/WRITE_TRIPLES")) { mprintf(" Saving VHCF triples as \"%s_triples.csv\"...\n",(const char*)buf); o->m_pVHDF->m_pVHDF->Write("",buf,"_triples.csv"); } if (g_pDatabase->GetBool("/PLOT2D/FORMATS/WRITE_MATRIX")) { mprintf(" Saving VHCF matrix as \"%s_matrix.csv\"...\n",(const char*)buf); o->m_pVHDF->m_pVHDF->WriteCSV("",buf,"_matrix.csv"); } if (o->m_pVHDF->m_iGraceBunchDist > 0) { // sprintf(buf,"vhcf_dist_%s%s.agr",o->m_pVHDF->m_sName,multibuf); buf.sprintf("vhcf_dist_%s%s.agr",o->m_pVHDF->m_sName,multibuf); mprintf(" Saving VHCF distance Grace Stack as \"%s\"...\n",(const char*)buf); o->m_pVHDF->m_pVHDF->WriteGraceBunch(0,o->m_pVHDF->m_iGraceBunchDist,1.0,"",buf,""); } if (o->m_pVHDF->m_iGraceBunchTime > 0) { // sprintf(buf,"vhcf_time_%s%s.agr",o->m_pVHDF->m_sName,multibuf); buf.sprintf("vhcf_time_%s%s.agr",o->m_pVHDF->m_sName,multibuf); mprintf(" Saving VHCF time Grace Stack as \"%s\"...\n",(const char*)buf); o->m_pVHDF->m_pVHDF->WriteGraceBunch(1,o->m_pVHDF->m_iGraceBunchTime,1.0,"",buf,""); } if (o->m_pVHDF->m_bSwapAxes) { mprintf(" Transposing 2D histogram...\n"); o->m_pVHDF->m_pVHDF->SwapAxes(); } if (g_pDatabase->GetBool("/PLOT2D/FORMATS/WRITE_MATHEMATICA")) { // sprintf(buf,"vhcf_%s%s.nb",o->m_pVHDF->m_sName,multibuf); buf.sprintf("vhcf_%s%s.nb",o->m_pVHDF->m_sName,multibuf); mprintf(" Saving VHCF Mathematica Notebook as \"%s\"...\n",(const char*)buf); o->m_pVHDF->m_pVHDF->WriteMathematicaNb("",buf,"",false); } if (g_pDatabase->GetBool("/PLOT2D/FORMATS/WRITE_GNUPLOT")) { // sprintf(buf,"vhcf_%s%s",o->m_pVHDF->m_sName,multibuf); buf.sprintf("vhcf_%s%s",o->m_pVHDF->m_sName,multibuf); mprintf(" Saving VHCF Gnuplot Input as \"%s.gp\"...\n",(const char*)buf); o->m_pVHDF->m_pVHDF->WriteGnuplotInput("",buf,"",false); } } // END IF VHDF if (g_bCDF) { if (g_iCDFChannels == 2) { mprintf(WHITE,"\n* Combined Distribution Function (2D)\n"); /* if (o->m_pConditions != NULL) { mprintf(" Conditions: %.2f percent of the molecules passed.\n",o->m_pConditions->m_fPassed/(o->m_pConditions->m_fPassed+o->m_pConditions->m_fFailed)*100.0); mprintf(" After conditions: "); } else mprintf(" ");*/ mprintf(" %.0f bin entries, %.0f out of bin range (%.2f percent).\n",o->m_pCDF->m_p2DF->m_fBinEntries,o->m_pCDF->m_p2DF->m_fSkipEntries,ZeroDivide(o->m_pCDF->m_p2DF->m_fSkipEntries,o->m_pCDF->m_p2DF->m_fSkipEntries+o->m_pCDF->m_p2DF->m_fBinEntries)*100.0); if (o->m_pCDF->m_p2DF->m_fBinEntries == 0) { eprintf(" There were no bin entries. Check your CDF definition. Skipping this CDF.\n\n"); goto _skipsdf; } o->m_pCDF->m_p2DF->CalcMaxEntry(); mprintf(" Max. bin entry: %.6E --> EPS: %.6E\n",o->m_pCDF->m_p2DF->m_fMaxEntry,o->m_pCDF->m_p2DF->m_fEps); if (o->m_pCDF->m_p2DF->m_fEps > 1.0E-4) { eprintf("\n Warning: Very large bin entries - probably loss of accuracy occured.\n"); mprintf(" Please reduce the bin counts (e.g. by analyzing only every 10th step).\n\n"); } for (z2=0;z2<2;z2++) { if (g_iObsChannel[z2] == 0) { if ((o->m_pRDF[z2]->m_bRadialCorrect) && (o->m_pCDF->m_iNormalize != 3)) { mprintf(" Correcting radial distribution for CDF channel %d...\n",z2+1); o->m_pCDF->m_p2DF->CorrectRadialDist(z2); } } if (g_iObsChannel[z2] == 1) { if (o->m_pADF[z2]->m_bStat && (!o->m_pADF[z2]->m_bCosine) && (o->m_pCDF->m_iNormalize != 3)) { mprintf(" Correcting angular distribution for CDF channel %d...\n",z2+1); o->m_pCDF->m_p2DF->CorrectAngle(z2); } if (o->m_pADF[z2]->m_bMirror) { mprintf(" Making channel %d mirror-symmetric...\n",z2+1); if (o->m_pADF[z2]->m_bCosine) o->m_pCDF->m_p2DF->Mirror(0.0,z2); else o->m_pCDF->m_p2DF->Mirror(90.0,z2); } } if (g_iObsChannel[z2] == 6) { if (o->m_pLiDF[z2]->m_bRadialCorrect) { mprintf(" Correcting radial distribution for CDF channel %d...\n",z2+1); o->m_pCDF->m_p2DF->CorrectLiRadialDist(z2); } } } o->m_pCDF->m_fFactor = 1.0; switch(o->m_pCDF->m_iNormalize) { case 3: mprintf(" Normalizing CDF to uniform density.\n"); o->m_pCDF->m_p2DF->NormalizeUniform(g_fBoxX*g_fBoxY*g_fBoxZ/g_iSteps / ((CMolecule*)g_oaMolecules[g_iFixMol])->m_laSingleMolIndex.GetSize() / ((CMolecule*)g_oaMolecules[o->m_iShowMol])->m_laSingleMolIndex.GetSize() / o->m_pCDF->m_iCombinationsEnabled); break; case 2: mprintf(" Normalizing maximum value to %.2f.\n",o->m_pCDF->m_fNormValue); o->m_pCDF->m_p2DF->NormalizeBin(0.0,o->m_pCDF->m_fNormValue); break; case 1: mprintf(" Normalizing integral value to %.2f.\n",o->m_pCDF->m_fNormValue); o->m_pCDF->m_fFactor = o->m_pCDF->m_p2DF->NormalizeBinIntegral(o->m_pCDF->m_fNormValue); break; case 0: mprintf(" Not normalizing this CDF.\n"); break; } if (g_pDatabase->GetBool("/PLOT2D/FORMATS/WRITE_TRIPLES")) { mprintf(" Saving CDF triples as \"%s%s_triples.csv\"...\n",o->m_pCDF->m_sName,multibuf); o->m_pCDF->m_p2DF->Write(o->m_pCDF->m_sName,multibuf,"_triples.csv"); } if (g_pDatabase->GetBool("/PLOT2D/FORMATS/WRITE_MATRIX")) { mprintf(" Saving CDF matrix as \"%s%s_matrix.csv\"...\n",o->m_pCDF->m_sName,multibuf); o->m_pCDF->m_p2DF->WriteCSV(o->m_pCDF->m_sName,multibuf,"_matrix.csv"); } if (g_pDatabase->GetBool("/PLOT2D/FORMATS/WRITE_MATHEMATICA")) { mprintf(" Saving CDF Mathematica Notebook as \"%s%s.nb\"...\n",o->m_pCDF->m_sName,multibuf); o->m_pCDF->m_p2DF->WriteMathematicaNb(o->m_pCDF->m_sName,multibuf,".nb",false); } if (g_pDatabase->GetBool("/PLOT2D/FORMATS/WRITE_GNUPLOT")) { mprintf(" Saving CDF Gnuplot Input as \"%s%s.gp\"...\n",o->m_pCDF->m_sName,multibuf); o->m_pCDF->m_p2DF->WriteGnuplotInput(o->m_pCDF->m_sName,multibuf,"",false); } mprintf(" Saving combined plot AGR file as \"%s%s_combined.agr\"...\n",o->m_pCDF->m_sName,multibuf); o->m_pCDF->m_p2DF->WriteCombinedPlot(o->m_pCDF->m_sName,multibuf,"_combined.agr"); if (o->m_pCDF->m_iHistogramRes != 0) { mprintf(" Calculating Histogram...\n"); o->m_pCDF->m_p2DF->CalcHistogram(); // sprintf(buf,"his_%s",o->m_pCDF->m_sName); buf.sprintf("his_%s",o->m_pCDF->m_sName); mprintf(" Saving Histogram as \"%s%s.csv\"...\n",(const char*)buf,multibuf); o->m_pCDF->m_p2DF->WriteHistogram(buf,multibuf,".csv"); } if (o->m_pCDF->m_bGraceBunch) { if (o->m_pCDF->m_iGraceBunchC1 > 0) { if ((g_iObsChannel[1] == 0) && (o->m_bOthers)) tf = 1.0 / o->m_pCDF->m_fFactor * 3.0/4.0/Pi/g_iSteps*g_fBoxX*g_fBoxY*g_fBoxZ/((CMolecule*)g_oaMolecules[g_iFixMol])->m_laSingleMolIndex.GetSize() /o->m_pRDF[1]->m_iShowAtomGes/((CMolecule*)g_oaMolecules[o->m_iShowMol])->m_laSingleMolIndex.GetSize()/o->m_pRDF[1]->m_iRefAtomGes; else tf = 1; // sprintf(buf,"cdf_c1_%s%s.agr",o->m_pCDF->m_sName,multibuf); buf.sprintf("cdf_c1_%s%s.agr",o->m_pCDF->m_sName,multibuf); mprintf(" Saving CDF Channel 1 Grace Stack as \"%s\"...\n",(const char*)buf); o->m_pCDF->m_p2DF->WriteGraceBunch(0,o->m_pCDF->m_iGraceBunchC1,(double)tf,"",buf,""); } if (o->m_pCDF->m_iGraceBunchC2 > 0) { if ((g_iObsChannel[0] == 0) && (o->m_bOthers)) tf = 1.0 / o->m_pCDF->m_fFactor * 3.0/4.0/Pi/g_iSteps*g_fBoxX*g_fBoxY*g_fBoxZ/((CMolecule*)g_oaMolecules[g_iFixMol])->m_laSingleMolIndex.GetSize() /o->m_pRDF[0]->m_iShowAtomGes/((CMolecule*)g_oaMolecules[o->m_iShowMol])->m_laSingleMolIndex.GetSize()/o->m_pRDF[0]->m_iRefAtomGes; else tf = 1; // sprintf(buf,"cdf_c2_%s%s.agr",o->m_pCDF->m_sName,multibuf); buf.sprintf("cdf_c2_%s%s.agr",o->m_pCDF->m_sName,multibuf); mprintf(" Saving CDF Channel 2 Grace Stack as \"%s\"...\n",(const char*)buf); o->m_pCDF->m_p2DF->WriteGraceBunch(1,o->m_pCDF->m_iGraceBunchC2,(double)tf,"",buf,""); } } if (o->m_pCDF->m_bAxisDivide) { mprintf(" Correlation coefficient: %f\n",o->m_pCDF->m_p2DF->CalcCorrelationFactor()); if (o->m_pCDF->m_bAxisDivideAll) { mprintf(" Saving CDF X projection as \"%s%s_pX.csv\"...\n",o->m_pCDF->m_sName,multibuf); o->m_pCDF->m_p2DF->WriteXProjection(o->m_pCDF->m_sName,multibuf,"_pX.csv"); mprintf(" Saving CDF Y projection as \"%s%s_pY.csv\"...\n",o->m_pCDF->m_sName,multibuf); o->m_pCDF->m_p2DF->WriteYProjection(o->m_pCDF->m_sName,multibuf,"_pY.csv"); mprintf(" Saving X-normalized CDF Mathematica Notebook as \"%s%s_nX.nb\"...\n",o->m_pCDF->m_sName,multibuf); try { tempc2df = new C2DF(); } catch(...) { tempc2df = NULL; } if (tempc2df == NULL) NewException((double)sizeof(C2DF),__FILE__,__LINE__,__PRETTY_FUNCTION__); tempc2df->CopyFrom(o->m_pCDF->m_p2DF); if (g_iObsChannel[0] == 0) if (o->m_pRDF[0]->m_bRadialCorrect) tempc2df->UnCorrectRadialDist(0); if (g_iObsChannel[0] == 1) if (o->m_pADF[0]->m_bStat && (!o->m_pADF[0]->m_bCosine)) tempc2df->UnCorrectAngle(0); tempc2df->NormalizeXCount(); switch(o->m_pCDF->m_iNormalize) { case 2: tempc2df->NormalizeBin(0.0,o->m_pCDF->m_fNormValue); break; case 1: tempc2df->NormalizeBinIntegral(o->m_pCDF->m_fNormValue); break; case 0: break; } tempc2df->WriteMathematicaNb(o->m_pCDF->m_sName,multibuf,"_nX.nb",false); tempc2df->WriteGnuplotInput(o->m_pCDF->m_sName,multibuf,"_nX",false); delete tempc2df; mprintf(" Saving Y-normalized CDF Mathematica Notebook as \"%s%s_nY.nb\"...\n",o->m_pCDF->m_sName,multibuf); try { tempc2df = new C2DF(); } catch(...) { tempc2df = NULL; } if (tempc2df == NULL) NewException((double)sizeof(C2DF),__FILE__,__LINE__,__PRETTY_FUNCTION__); tempc2df->CopyFrom(o->m_pCDF->m_p2DF); if (g_iObsChannel[1] == 0) if (o->m_pRDF[1]->m_bRadialCorrect) tempc2df->UnCorrectRadialDist(1); if (g_iObsChannel[1] == 1) if (o->m_pADF[1]->m_bStat && (!o->m_pADF[1]->m_bCosine)) tempc2df->UnCorrectAngle(1); tempc2df->NormalizeYCount(); switch(o->m_pCDF->m_iNormalize) { case 2: tempc2df->NormalizeBin(0.0,o->m_pCDF->m_fNormValue); break; case 1: tempc2df->NormalizeBinIntegral(o->m_pCDF->m_fNormValue); break; case 0: break; } tempc2df->WriteMathematicaNb(o->m_pCDF->m_sName,multibuf,"_nY.nb",false); tempc2df->WriteGnuplotInput(o->m_pCDF->m_sName,multibuf,"_nY",false); delete tempc2df; mprintf(" Saving XY-normalized CDF Mathematica Notebook as \"%s%s_nXY.nb\"...\n",o->m_pCDF->m_sName,multibuf); try { tempc2df = new C2DF(); } catch(...) { tempc2df = NULL; } if (tempc2df == NULL) NewException((double)sizeof(C2DF),__FILE__,__LINE__,__PRETTY_FUNCTION__); tempc2df->CopyFrom(o->m_pCDF->m_p2DF); for (z2=0;z2<2;z2++) { if (g_iObsChannel[z2] == 0) if (o->m_pRDF[z2]->m_bRadialCorrect) tempc2df->UnCorrectRadialDist(z2); if (g_iObsChannel[z2] == 1) if (o->m_pADF[z2]->m_bStat && (!o->m_pADF[z2]->m_bCosine)) tempc2df->UnCorrectAngle(z2); } tempc2df->NormalizeXCount(); tempc2df->NormalizeYCount(); switch(o->m_pCDF->m_iNormalize) { case 2: tempc2df->NormalizeBin(0.0,o->m_pCDF->m_fNormValue); break; case 1: tempc2df->NormalizeBinIntegral(o->m_pCDF->m_fNormValue); break; case 0: break; } tempc2df->WriteMathematicaNb(o->m_pCDF->m_sName,multibuf,"_nXY.nb",false); tempc2df->WriteGnuplotInput(o->m_pCDF->m_sName,multibuf,"_nXY",false); delete tempc2df; } mprintf(" Calculating tensor product of CDF projections...\n"); try { o->m_pCDF->m_pTensorProduct = new C2DF(); } catch(...) { o->m_pCDF->m_pTensorProduct = NULL; } if (o->m_pCDF->m_pTensorProduct == NULL) NewException((double)sizeof(C2DF),__FILE__,__LINE__,__PRETTY_FUNCTION__); o->m_pCDF->m_pTensorProduct->CopyFrom(o->m_pCDF->m_p2DF); o->m_pCDF->m_pTensorProduct->MakeTensorProduct(o->m_pCDF->m_p2DF); switch(o->m_pCDF->m_iNormalize) { case 2: o->m_pCDF->m_pTensorProduct->NormalizeBin(0.0,o->m_pCDF->m_fNormValue); break; case 1: o->m_pCDF->m_pTensorProduct->NormalizeBinIntegral(o->m_pCDF->m_fNormValue); break; case 0: break; } if (o->m_pCDF->m_bAxisDivideAll) { mprintf(" Saving tensor product as \"%s%s_tensor.dat\"...\n",o->m_pCDF->m_sName,multibuf); o->m_pCDF->m_pTensorProduct->Write(o->m_pCDF->m_sName,multibuf,"_tensor.dat"); mprintf(" Saving tensor product Mathematica Notebook as \"%s%s_tensor.nb\"...\n",o->m_pCDF->m_sName,multibuf); o->m_pCDF->m_pTensorProduct->WriteMathematicaNb(o->m_pCDF->m_sName,multibuf,"_tensor.nb",false); mprintf(" Saving tensor product Gnuplot Input as \"%s%s_tensor.gp\"...\n",o->m_pCDF->m_sName,multibuf); o->m_pCDF->m_pTensorProduct->WriteGnuplotInput(o->m_pCDF->m_sName,multibuf,"_tensor",false); mprintf(" Calculating difference between CDF and tensor product...\n"); } o->m_pCDF->m_p2DF->Subtract(o->m_pCDF->m_pTensorProduct); o->m_pCDF->m_p2DF->CalcMaxEntry(); o->m_pCDF->m_p2DF->m_iColorScale = 4; // PlusMinus Scale o->m_pCDF->m_p2DF->m_fPlotExp = 1.0; // o->m_pCDF->m_p2DF->m_fMathematicaColorOffset = max(fabs(o->m_pCDF->m_p2DF->m_fMinEntry),fabs(o->m_pCDF->m_p2DF->m_fMaxEntry)) / 3.0; // o->m_pCDF->m_p2DF->m_fMathematicaColorScale = o->m_pCDF->m_p2DF->m_fMathematicaColorOffset * 2.0; mprintf(" Saving +/- correlation plot as \"%s%s_correlation.dat\"...\n",o->m_pCDF->m_sName,multibuf); o->m_pCDF->m_p2DF->Write(o->m_pCDF->m_sName,multibuf,"_correlation.dat"); mprintf(" Saving +/- correlation plot Mathematica Notebook as \"%s%s_correlation.nb\"...\n",o->m_pCDF->m_sName,multibuf); o->m_pCDF->m_p2DF->WriteMathematicaNb(o->m_pCDF->m_sName,multibuf,"_correlation.nb",false); mprintf(" Saving +/- correlation plot Gnuplot Input as \"%s%s_correlation.gp\"...\n",o->m_pCDF->m_sName,multibuf); o->m_pCDF->m_p2DF->WriteGnuplotInput(o->m_pCDF->m_sName,multibuf,"_correlation",false); } // END IF AXISDIVIDE if (o->m_pCDF->m_bDumpDat) { fclose(o->m_pCDF->m_fDump); mprintf(" CDF raw data saved as cdfdump_%dd_%s%s.csv.\n",g_iCDFChannels,o->m_pCDF->m_sShortName,multibuf); } if (o->m_bTimeDev) { if ((o->m_waSaveRefList.GetSize() == 1) || (!o->m_bSaveSeparateFiles)) { fclose(o->m_pCDF->m_fTimeDev[0]); // sprintf(buf,"cdf_timedev_%dd_%s_ref%d%s.csv",g_iCDFChannels,o->m_pCDF->m_sShortName,z2+1,multibuf); mprintf(" Temporal development saved as cdf_timedev_%dd%s%s.csv\n",g_iCDFChannels,o->m_pCDF->m_sShortName,multibuf); } else { for (z2=0;z2m_waSaveRefList.GetSize();z2++) { fclose(o->m_pCDF->m_fTimeDev[z2]); mprintf(" Temporal development saved as cdf_timedev_%dd%s_ref%d%s.csv\n",g_iCDFChannels,o->m_pCDF->m_sShortName,z2+1,multibuf); } } if (o->m_pCDF->m_bTDAnimation) { mprintf(WHITE," * Time dependent animation *\n"); // sprintf(buf,"animation_complete_%s%s.agr",o->m_pCDF->m_sName,multibuf); buf.sprintf("animation_complete_%s%s.agr",o->m_pCDF->m_sName,multibuf); mprintf(" Saving complete Plot as \"%s\"...\n",(const char*)buf); for (z2=0;z2m_waSaveRefList.GetSize()*o->m_waSaveShowList.GetSize()*o->m_pCDF->m_iCombinationsEnabled;z2++) { o->m_pCDF->m_pTDAPlot->SetSetLineWidth(z2,2.0); o->m_pCDF->m_pTDAPlot->SetSetLineColorLong(z2,GraceColor(z2,0.0)); } o->m_pCDF->m_pTDAPlot->WriteAgr(buf,false); // sprintf(buf,"render_%s%s",o->m_pCDF->m_sName,multibuf); buf.sprintf("render_%s%s",o->m_pCDF->m_sName,multibuf); mprintf(" Saving xmgrace render script for animation as \"%s\"...\n",(const char*)buf); a = OpenFileWrite("gracebatch",true); mfprintf(a,"PRINT TO \"output.png\"\n"); mfprintf(a,"HARDCOPY DEVICE \"PNG\"\n"); mfprintf(a,"PAGE SIZE %d, %d\n",o->m_pCDF->m_iTDAResX,o->m_pCDF->m_iTDAResY); mfprintf(a,"DEVICE \"PNG\" FONT ANTIALIASING on\n"); mfprintf(a,"DEVICE \"PNG\" OP \"compression:9\"\n"); mfprintf(a,"PRINT\n"); fclose(a); a = OpenFileWrite(buf,true); if (o->m_pCDF->m_bTDATrace) { for (z2=0;z2m_waSaveRefList.GetSize()*o->m_waSaveShowList.GetSize()*o->m_pCDF->m_iCombinationsEnabled;z2++) { o->m_pCDF->m_pTDAPlot->DuplicateSet(z2); o->m_pCDF->m_pTDAPlot->SetSetLineWidth(z2,2.0); o->m_pCDF->m_pTDAPlot->SetSetLineColorLong(z2,GraceColor(z2,0.7)); o->m_pCDF->m_pTDAPlot->SetSetLineWidth(o->m_waSaveRefList.GetSize()*o->m_waSaveShowList.GetSize()*o->m_pCDF->m_iCombinationsEnabled+z2,3.0); o->m_pCDF->m_pTDAPlot->SetSetLineColorLong(o->m_waSaveRefList.GetSize()*o->m_waSaveShowList.GetSize()*o->m_pCDF->m_iCombinationsEnabled+z2,GraceColor(z2,0.0)); } } for (z2=0;z2m_pCDF->m_iTDASteps;z2++) { if (o->m_pCDF->m_bTDATrace) { for (z3=0;z3m_waSaveRefList.GetSize()*o->m_waSaveShowList.GetSize()*o->m_pCDF->m_iCombinationsEnabled;z3++) { o->m_pCDF->m_pTDAPlot->SetSetRange(z3+o->m_waSaveRefList.GetSize()*o->m_waSaveShowList.GetSize()*o->m_pCDF->m_iCombinationsEnabled,z2*o->m_pCDF->m_iTDAStride,z2*o->m_pCDF->m_iTDAStride+o->m_pCDF->m_iTDATail); o->m_pCDF->m_pTDAPlot->SetSetRange(z3,0,z2*o->m_pCDF->m_iTDAStride); } } else { for (z3=0;z3m_waSaveRefList.GetSize()*o->m_waSaveShowList.GetSize()*o->m_pCDF->m_iCombinationsEnabled;z3++) o->m_pCDF->m_pTDAPlot->SetSetRange(z3,z2*o->m_pCDF->m_iTDAStride,z2*o->m_pCDF->m_iTDAStride+o->m_pCDF->m_iTDATail); } // sprintf(buf,"animation_%05d_%s%s.agr",z2+1,o->m_pCDF->m_sName,multibuf); buf.sprintf("animation_%05d_%s%s.agr",z2+1,o->m_pCDF->m_sName,multibuf); mprintf(" Saving frame \"%s\"...\n",(const char*)buf); o->m_pCDF->m_pTDAPlot->WriteAgr(buf,false); mfprintf(a,"echo 'Printing frame %d of %d'\n",z2+1,o->m_pCDF->m_iTDASteps); mfprintf(a,"xmgrace %s -batch gracebatch -nosafe -hardcopy\n",(const char*)buf); mfprintf(a,"mv output.png frame%04d.png\n",z2+1); } fclose(a); } } } // END IF CHANNELS == 2 if (g_iCDFChannels == 3) { mprintf(WHITE,"\n* Combined Distribution Function (3D)\n"); mprintf(" %.0f bin entries, %.0f out of bin range (%.2f percent).\n",o->m_pCDF->m_p3DF->m_fBinEntries,o->m_pCDF->m_p3DF->m_fSkipEntries,ZeroDivide(o->m_pCDF->m_p3DF->m_fSkipEntries,o->m_pCDF->m_p3DF->m_fSkipEntries+o->m_pCDF->m_p3DF->m_fBinEntries)*100.0); if (o->m_pCDF->m_p3DF->m_fBinEntries == 0) { eprintf(" There were no bin entries. Check your CDF definition. Skipping this CDF.\n\n"); goto _skipsdf; } o->m_pCDF->m_p3DF->CalcMaxEntry(); mprintf(" Data range from %G to %G.\n",o->m_pCDF->m_p3DF->m_fMinEntry,o->m_pCDF->m_p3DF->m_fMaxEntry); mprintf(" Max. bin entry: %.6E --> EPS: %.6E\n",o->m_pCDF->m_p3DF->m_fMaxEntry,o->m_pCDF->m_p3DF->m_fEps); if (o->m_pCDF->m_p3DF->m_fEps > 1.0E-4) { eprintf("\n Warning: Very large bin entries - probably loss of accuracy occured.\n"); mprintf(" Please reduce the bin counts (e.g. by analyzing only every 10th step).\n\n"); } for (z2=0;z2m_pRDF[z2]->m_bRadialCorrect) { mprintf(" Correcting radial distribution for CDF channel %d...\n",z2+1); o->m_pCDF->m_p3DF->CorrectRadialDist(z2); o->m_pCDF->m_p3DF->CalcMaxEntry(); mprintf(" Data range from %G to %G.\n",o->m_pCDF->m_p3DF->m_fMinEntry,o->m_pCDF->m_p3DF->m_fMaxEntry); } } if (g_iObsChannel[z2] == 1) { if (o->m_pADF[z2]->m_bStat && (!o->m_pADF[z2]->m_bCosine)) { mprintf(" Correcting angular distribution for CDF channel %d...\n",z2+1); o->m_pCDF->m_p3DF->CorrectAngle(z2); o->m_pCDF->m_p3DF->CalcMaxEntry(); mprintf(" Data range from %G to %G.\n",o->m_pCDF->m_p3DF->m_fMinEntry,o->m_pCDF->m_p3DF->m_fMaxEntry); } if (o->m_pADF[z2]->m_bMirror) { mprintf(" Making channel %d mirror-symmetric...\n",z2+1); if (o->m_pADF[z2]->m_bCosine) o->m_pCDF->m_p2DF->Mirror(0.0,z2); else o->m_pCDF->m_p2DF->Mirror(90.0,z2); o->m_pCDF->m_p3DF->CalcMaxEntry(); mprintf(" Data range from %G to %G.\n",o->m_pCDF->m_p3DF->m_fMinEntry,o->m_pCDF->m_p3DF->m_fMaxEntry); } } } // o->m_pCDF->m_p3DF->CalcMaxEntry(); // mprintf(" Data range now from %G to %G.\n",o->m_pCDF->m_p3DF->m_fMinEntry,o->m_pCDF->m_p3DF->m_fMaxEntry); o->m_pCDF->m_fFactor = 1.0; switch(o->m_pCDF->m_iNormalize) { case 2: mprintf(" Normalizing maximum value to %.2f.\n",o->m_pCDF->m_fNormValue); o->m_pCDF->m_p3DF->NormalizeBin(0.0,o->m_pCDF->m_fNormValue); o->m_pCDF->m_p3DF->CalcMaxEntry(); mprintf(" Data range now from %G to %G.\n",o->m_pCDF->m_p3DF->m_fMinEntry,o->m_pCDF->m_p3DF->m_fMaxEntry); break; case 1: mprintf(" Normalizing integral value to %.2f.\n",o->m_pCDF->m_fNormValue); o->m_pCDF->m_fFactor = o->m_pCDF->m_p3DF->NormalizeBinIntegral(o->m_pCDF->m_fNormValue); mprintf(" Factor was %G.\n",o->m_pCDF->m_fFactor); o->m_pCDF->m_p3DF->CalcMaxEntry(); mprintf(" Data range now from %G to %G.\n",o->m_pCDF->m_p3DF->m_fMinEntry,o->m_pCDF->m_p3DF->m_fMaxEntry); break; case 0: mprintf(" Not normalizing this CDF.\n"); break; } for (z2=0;z2<=g_iSDFSmoothGrade;z2++) { try { temp3DF = new C3DF(); } catch(...) { temp3DF = NULL; } if (temp3DF == NULL) NewException((double)sizeof(C3DF),__FILE__,__LINE__,__PRETTY_FUNCTION__); temp3DF->CopyFrom(o->m_pCDF->m_p3DF); if (z2 != 0) { temp3DF->Smooth(z2); // sprintf(buf,".s%d%s.plt",z2,multibuf); buf.sprintf(".s%d%s.plt",z2,multibuf); } else // sprintf(buf,"%s.plt",multibuf); buf.sprintf("%s.plt",multibuf); mprintf(" Saving 3D CDF as \"%s%s\"...\n",o->m_pCDF->m_sName,(const char*)buf); temp3DF->WritePLT("",o->m_pCDF->m_sName,buf,false); if (z2 != 0) // sprintf(buf,".s%d%s.cube",z2,multibuf); buf.sprintf(".s%d%s.cube",z2,multibuf); else // sprintf(buf,"%s.cube",multibuf); buf.sprintf("%s.cube",multibuf); mprintf(" Saving 3D CDF as \"%s%s\"...\n",o->m_pCDF->m_sName,(const char*)buf); temp3DF->WriteCube("",o->m_pCDF->m_sName,buf,false); if (o->m_pCDF->m_iHistogramRes != 0) { mprintf(" Calculating Histogram...\n"); temp3DF->CalcHistogram(); if (z2 != 0) // sprintf(buf,"his_%s.s%d",o->m_pCDF->m_sName,z2); buf.sprintf("his_%s.s%d",o->m_pCDF->m_sName,z2); else // sprintf(buf,"his_%s",o->m_pCDF->m_sName); buf.sprintf("his_%s",o->m_pCDF->m_sName); mprintf(" Saving Histogram as \"%s%s.csv\"...\n",(const char*)buf,multibuf); temp3DF->WriteHistogram(buf,multibuf,".csv"); } if (o->m_pCDF->m_b3DSlices) { for (z3=0;z3<3;z3++) { if (o->m_pCDF->m_i3DSliceIntervals[z3] != 0) { if (z2 != 0) mprintf(WHITE," * Creating channel %d smooth grade %d slices...\n",z3+1,z2); else mprintf(WHITE," * Creating channel %d slices...\n",z3+1); try { temp2dfa = new C2DF*[o->m_pCDF->m_i3DSliceIntervals[z3]]; } catch(...) { temp2dfa = NULL; } if (temp2dfa == NULL) NewException((double)o->m_pCDF->m_i3DSliceIntervals[z3]*sizeof(C2DF*),__FILE__,__LINE__,__PRETTY_FUNCTION__); tf = 0; for (z4=0;z4m_pCDF->m_i3DSliceIntervals[z3];z4++) { try { temp2dfa[z4] = new C2DF(); } catch(...) { temp2dfa[z4] = NULL; } if (temp2dfa[z4] == NULL) NewException((double)sizeof(C2DF),__FILE__,__LINE__,__PRETTY_FUNCTION__); temp3DF->CreateSlice(z3,(int)((double)z4/o->m_pCDF->m_i3DSliceIntervals[z3]*o->m_pCDF->m_p3DF->m_iRes[z3]),(int)((z4+1.0)/o->m_pCDF->m_i3DSliceIntervals[z3]*o->m_pCDF->m_p3DF->m_iRes[z3]-1),temp2dfa[z4]); mprintf(" - %2d: %9.4f - %9.4f (%3d - %3d), Intensity range %.3f ... %.3f\n",z4+1,o->m_pCDF->m_p3DF->m_fMinVal[z3]+(double)z4/o->m_pCDF->m_i3DSliceIntervals[z3]*(o->m_pCDF->m_p3DF->m_fMaxVal[z3]-o->m_pCDF->m_p3DF->m_fMinVal[z3]),o->m_pCDF->m_p3DF->m_fMinVal[z3]+(z4+1.0)/o->m_pCDF->m_i3DSliceIntervals[z3]*(o->m_pCDF->m_p3DF->m_fMaxVal[z3]-o->m_pCDF->m_p3DF->m_fMinVal[z3]),int((double)z4/o->m_pCDF->m_i3DSliceIntervals[z3]*o->m_pCDF->m_p3DF->m_iRes[z3]),int((z4+1.0)/o->m_pCDF->m_i3DSliceIntervals[z3]*o->m_pCDF->m_p3DF->m_iRes[z3]-1),temp2dfa[z4]->m_fMinEntry,temp2dfa[z4]->m_fMaxEntry); if (temp2dfa[z4]->m_fMaxEntry > tf) tf = temp2dfa[z4]->m_fMaxEntry; } mprintf(" Setting common intensity range to 0 ... %.3f.\n",tf); mprintf(" Writing out slice files (%d/3)...\n",z3+1); for (z4=0;z4m_pCDF->m_i3DSliceIntervals[z3];z4++) { temp2dfa[z4]->m_fMinEntry = 0; temp2dfa[z4]->m_fMaxEntry = tf; if (z2 != 0) // sprintf(buf,"%s_slice_ch%d_%d_%.3f-%.3f.s%d.nb",o->m_pCDF->m_sName,z3+1,z4+1,o->m_pCDF->m_p3DF->m_fMinVal[z3]+(double)z4/o->m_pCDF->m_i3DSliceIntervals[z3]*(o->m_pCDF->m_p3DF->m_fMaxVal[z3]-o->m_pCDF->m_p3DF->m_fMinVal[z3]),o->m_pCDF->m_p3DF->m_fMinVal[z3]+(z4+1.0)/o->m_pCDF->m_i3DSliceIntervals[z3]*(o->m_pCDF->m_p3DF->m_fMaxVal[z3]-o->m_pCDF->m_p3DF->m_fMinVal[z3]),z2); buf.sprintf("%s_slice_ch%d_%d_%.3f-%.3f.s%d.nb",o->m_pCDF->m_sName,z3+1,z4+1,o->m_pCDF->m_p3DF->m_fMinVal[z3]+(double)z4/o->m_pCDF->m_i3DSliceIntervals[z3]*(o->m_pCDF->m_p3DF->m_fMaxVal[z3]-o->m_pCDF->m_p3DF->m_fMinVal[z3]),o->m_pCDF->m_p3DF->m_fMinVal[z3]+(z4+1.0)/o->m_pCDF->m_i3DSliceIntervals[z3]*(o->m_pCDF->m_p3DF->m_fMaxVal[z3]-o->m_pCDF->m_p3DF->m_fMinVal[z3]),z2); else // sprintf(buf,"%s_slice_ch%d_%d_%.3f-%.3f.nb",o->m_pCDF->m_sName,z3+1,z4+1,o->m_pCDF->m_p3DF->m_fMinVal[z3]+(double)z4/o->m_pCDF->m_i3DSliceIntervals[z3]*(o->m_pCDF->m_p3DF->m_fMaxVal[z3]-o->m_pCDF->m_p3DF->m_fMinVal[z3]),o->m_pCDF->m_p3DF->m_fMinVal[z3]+(z4+1.0)/o->m_pCDF->m_i3DSliceIntervals[z3]*(o->m_pCDF->m_p3DF->m_fMaxVal[z3]-o->m_pCDF->m_p3DF->m_fMinVal[z3])); buf.sprintf("%s_slice_ch%d_%d_%.3f-%.3f.nb",o->m_pCDF->m_sName,z3+1,z4+1,o->m_pCDF->m_p3DF->m_fMinVal[z3]+(double)z4/o->m_pCDF->m_i3DSliceIntervals[z3]*(o->m_pCDF->m_p3DF->m_fMaxVal[z3]-o->m_pCDF->m_p3DF->m_fMinVal[z3]),o->m_pCDF->m_p3DF->m_fMinVal[z3]+(z4+1.0)/o->m_pCDF->m_i3DSliceIntervals[z3]*(o->m_pCDF->m_p3DF->m_fMaxVal[z3]-o->m_pCDF->m_p3DF->m_fMinVal[z3])); mprintf(" %s ...\n",(const char*)buf); temp2dfa[z4]->WriteMathematicaNb("",buf,"",true); if (z2 != 0) // sprintf(buf,"%s_slice_ch%d_%d_%.3f-%.3f.s%d",o->m_pCDF->m_sName,z3+1,z4+1,o->m_pCDF->m_p3DF->m_fMinVal[z3]+(double)z4/o->m_pCDF->m_i3DSliceIntervals[z3]*(o->m_pCDF->m_p3DF->m_fMaxVal[z3]-o->m_pCDF->m_p3DF->m_fMinVal[z3]),o->m_pCDF->m_p3DF->m_fMinVal[z3]+(z4+1.0)/o->m_pCDF->m_i3DSliceIntervals[z3]*(o->m_pCDF->m_p3DF->m_fMaxVal[z3]-o->m_pCDF->m_p3DF->m_fMinVal[z3]),z2); buf.sprintf("%s_slice_ch%d_%d_%.3f-%.3f.s%d",o->m_pCDF->m_sName,z3+1,z4+1,o->m_pCDF->m_p3DF->m_fMinVal[z3]+(double)z4/o->m_pCDF->m_i3DSliceIntervals[z3]*(o->m_pCDF->m_p3DF->m_fMaxVal[z3]-o->m_pCDF->m_p3DF->m_fMinVal[z3]),o->m_pCDF->m_p3DF->m_fMinVal[z3]+(z4+1.0)/o->m_pCDF->m_i3DSliceIntervals[z3]*(o->m_pCDF->m_p3DF->m_fMaxVal[z3]-o->m_pCDF->m_p3DF->m_fMinVal[z3]),z2); else // sprintf(buf,"%s_slice_ch%d_%d_%.3f-%.3f",o->m_pCDF->m_sName,z3+1,z4+1,o->m_pCDF->m_p3DF->m_fMinVal[z3]+(double)z4/o->m_pCDF->m_i3DSliceIntervals[z3]*(o->m_pCDF->m_p3DF->m_fMaxVal[z3]-o->m_pCDF->m_p3DF->m_fMinVal[z3]),o->m_pCDF->m_p3DF->m_fMinVal[z3]+(z4+1.0)/o->m_pCDF->m_i3DSliceIntervals[z3]*(o->m_pCDF->m_p3DF->m_fMaxVal[z3]-o->m_pCDF->m_p3DF->m_fMinVal[z3])); buf.sprintf("%s_slice_ch%d_%d_%.3f-%.3f",o->m_pCDF->m_sName,z3+1,z4+1,o->m_pCDF->m_p3DF->m_fMinVal[z3]+(double)z4/o->m_pCDF->m_i3DSliceIntervals[z3]*(o->m_pCDF->m_p3DF->m_fMaxVal[z3]-o->m_pCDF->m_p3DF->m_fMinVal[z3]),o->m_pCDF->m_p3DF->m_fMinVal[z3]+(z4+1.0)/o->m_pCDF->m_i3DSliceIntervals[z3]*(o->m_pCDF->m_p3DF->m_fMaxVal[z3]-o->m_pCDF->m_p3DF->m_fMinVal[z3])); mprintf(" %s.gp ...\n",(const char*)buf); temp2dfa[z4]->WriteGnuplotInput("",buf,"",true); } for (z4=0;z4m_pCDF->m_i3DSliceIntervals[z3];z4++) delete temp2dfa[z4]; delete[] temp2dfa; } } } } mprintf(" Writing out 2D projections...\n"); for (z3=0;z3<3;z3++) { mprintf(WHITE," * CDF 2D projection on channel %d\n",z3+1); mprintf(" %.0f bin entries, %.0f out of bin range (%.2f percent).\n",o->m_pCDF->m_p3DF->m_p2DF[z3]->m_fBinEntries,o->m_pCDF->m_p3DF->m_p2DF[z3]->m_fSkipEntries,ZeroDivide(o->m_pCDF->m_p3DF->m_p2DF[z3]->m_fSkipEntries,o->m_pCDF->m_p3DF->m_p2DF[z3]->m_fSkipEntries+o->m_pCDF->m_p3DF->m_p2DF[z3]->m_fBinEntries)*100.0); switch(z3) { case 0: tia[0] = 0; tia[1] = 1; break; case 1: tia[0] = 0; tia[1] = 2; break; case 2: tia[0] = 1; tia[1] = 2; break; } for (z2=0;z2<2;z2++) { if (g_iObsChannel[tia[z2]] == 0) { if (o->m_pRDF[tia[z2]]->m_bRadialCorrect) { mprintf(" Correcting radial distribution for CDF channel %d...\n",z2+1); o->m_pCDF->m_p3DF->m_p2DF[z3]->CorrectRadialDist(z2); } } if (g_iObsChannel[tia[z2]] == 1) { if (o->m_pADF[tia[z2]]->m_bStat && (!o->m_pADF[tia[z2]]->m_bCosine)) { mprintf(" Correcting angular distribution for CDF channel %d...\n",z2+1); o->m_pCDF->m_p3DF->m_p2DF[z3]->CorrectAngle(z2); } /* if (o->m_pADF[z2]->m_bMirror) { mprintf(" Making channel %d mirror-symmetric...\n",z2+1); if (o->m_pADF[z2]->m_bCosine) o->m_pCDF->m_p2DF->Mirror(0.0f,z2); else o->m_pCDF->m_p2DF->Mirror(90.0f,z2); }*/ } } o->m_pCDF->m_fFactor = 1.0; switch(o->m_pCDF->m_iNormalize) { case 2: mprintf(" Normalizing maximum value to %.2f.\n",o->m_pCDF->m_fNormValue); o->m_pCDF->m_p3DF->m_p2DF[z3]->NormalizeBin(0.0,o->m_pCDF->m_fNormValue); break; case 1: mprintf(" Normalizing integral value to %.2f.\n",o->m_pCDF->m_fNormValue); o->m_pCDF->m_p3DF->m_p2DF[z3]->NormalizeBinIntegral(o->m_pCDF->m_fNormValue); break; case 0: mprintf(" Not normalizing this CDF.\n"); break; } mprintf(" Saving CDF triples as \"%s%s_triples.csv\"...\n",o->m_pCDF->m_p3DF->m_p2DF[z3]->m_sName,multibuf); o->m_pCDF->m_p3DF->m_p2DF[z3]->Write(o->m_pCDF->m_p3DF->m_p2DF[z3]->m_sName,multibuf,"_triples.csv"); mprintf(" Saving CDF matrix as \"%s%s_matrix.csv\"...\n",o->m_pCDF->m_p3DF->m_p2DF[z3]->m_sName,multibuf); o->m_pCDF->m_p3DF->m_p2DF[z3]->WriteCSV(o->m_pCDF->m_p3DF->m_p2DF[z3]->m_sName,multibuf,"_matrix.csv"); mprintf(" Saving CDF Mathematica Notebook as \"%s%s.nb\"...\n",o->m_pCDF->m_p3DF->m_p2DF[z3]->m_sName,multibuf); o->m_pCDF->m_p3DF->m_p2DF[z3]->WriteMathematicaNb(o->m_pCDF->m_p3DF->m_p2DF[z3]->m_sName,multibuf,".nb",false); mprintf(" Saving CDF Gnuplot Input as \"%s%s.gp\"...\n",o->m_pCDF->m_p3DF->m_p2DF[z3]->m_sName,multibuf); o->m_pCDF->m_p3DF->m_p2DF[z3]->WriteGnuplotInput(o->m_pCDF->m_p3DF->m_p2DF[z3]->m_sName,multibuf,"",false); mprintf(" Saving combined plot AGR file as \"%s%s_combined.agr\"...\n",o->m_pCDF->m_p3DF->m_p2DF[z3]->m_sName,multibuf); o->m_pCDF->m_p3DF->m_p2DF[z3]->WriteCombinedPlot(o->m_pCDF->m_p3DF->m_p2DF[z3]->m_sName,multibuf,"_combined.agr"); if (o->m_pCDF->m_iHistogramRes != 0) { mprintf(" Calculating Histogram...\n"); o->m_pCDF->m_p3DF->m_p2DF[z3]->CalcHistogram(); // sprintf(buf,"his_%s",o->m_pCDF->m_p3DF->m_p2DF[z3]->m_sName); buf.sprintf("his_%s",o->m_pCDF->m_p3DF->m_p2DF[z3]->m_sName); mprintf(" Saving Histogram as \"%s%s.csv\"...\n",(const char*)buf,multibuf); o->m_pCDF->m_p3DF->m_p2DF[z3]->WriteHistogram(buf,multibuf,".csv"); } } } // END IF CHANNELS == 3 _skipsdf:; } // END IF CDF if (g_bRevSDF) { mprintf(WHITE,"\n* Pseudo SDF\n"); mprintf(" %.0f bin entries, %.0f out of bin range (%.2f percent).\n",o->m_pRevSDF->m_p2DF->m_fBinEntries,o->m_pRevSDF->m_p2DF->m_fSkipEntries,ZeroDivide(o->m_pRevSDF->m_p2DF->m_fSkipEntries,o->m_pRevSDF->m_p2DF->m_fSkipEntries+o->m_pRevSDF->m_p2DF->m_fBinEntries)*100.0); if (o->m_pRevSDF->m_p2DF->m_fBinEntries == 0) { eprintf(" There were no bin entries. Check your function definition. Skipping this PseudoSDF.\n\n"); goto _skiprevsdf; } o->m_pRevSDF->m_p2DF->CalcMaxEntry(); mprintf(" Max. bin entry: %.6E --> EPS: %.6E\n",o->m_pRevSDF->m_p2DF->m_fMaxEntry,o->m_pRevSDF->m_p2DF->m_fEps); if (o->m_pRevSDF->m_p2DF->m_fEps > 1.0E-4) { eprintf("\n Warning: Very large bin entries - probably loss of accuracy occured.\n"); mprintf(" Please reduce the bin counts (e.g. by analyzing only every 10th step).\n\n"); } mprintf(" Normalizing integral value to %.2f.\n",1000000.0); o->m_pRevSDF->m_p2DF->NormalizeBinIntegral(1000000.0); if (o->m_pRevSDF->m_bDrawAtoms) { mprintf(" Inserting reference atoms into the Pseudo SDF plot...\n"); if (((CAtom*)g_oaAtoms[g_iFixRealAtomType[0]])->m_pElement->m_fRadius == 0) o->m_pRevSDF->m_p2DF->AddCircle(0,0,50.0,0.4,0.4,0.4); else o->m_pRevSDF->m_p2DF->AddCircle(0,0,((CAtom*)g_oaAtoms[g_iFixRealAtomType[0]])->m_pElement->m_fRadius*0.75,((CAtom*)g_oaAtoms[g_iFixRealAtomType[0]])->m_pElement->m_iColorR/255.0,((CAtom*)g_oaAtoms[g_iFixRealAtomType[0]])->m_pElement->m_iColorG/255.0,((CAtom*)g_oaAtoms[g_iFixRealAtomType[0]])->m_pElement->m_iColorB/255.0); if (((CAtom*)g_oaAtoms[g_iFixRealAtomType[1]])->m_pElement->m_fRadius == 0) o->m_pRevSDF->m_p2DF->AddCircle(0,o->m_pRevSDF->m_fSecondAtomPosX/o->m_pRevSDF->m_fSecondAtomCount,50.0,0.4,0.4,0.4); else o->m_pRevSDF->m_p2DF->AddCircle(0,o->m_pRevSDF->m_fSecondAtomPosX/o->m_pRevSDF->m_fSecondAtomCount,((CAtom*)g_oaAtoms[g_iFixRealAtomType[1]])->m_pElement->m_fRadius*0.75,((CAtom*)g_oaAtoms[g_iFixRealAtomType[1]])->m_pElement->m_iColorR/255.0,((CAtom*)g_oaAtoms[g_iFixRealAtomType[1]])->m_pElement->m_iColorG/255.0,((CAtom*)g_oaAtoms[g_iFixRealAtomType[1]])->m_pElement->m_iColorB/255.0); } mprintf(" Saving PseudoSDF triples as \"%s%s_triples.csv\"...\n",o->m_pRevSDF->m_sName,multibuf); o->m_pRevSDF->m_p2DF->Write(o->m_pRevSDF->m_sName,multibuf,"_triples.csv"); mprintf(" Saving PseudoSDF matrix as \"%s%s_matrix.csv\"...\n",o->m_pRevSDF->m_sName,multibuf); o->m_pRevSDF->m_p2DF->WriteCSV(o->m_pRevSDF->m_sName,multibuf,"_matrix.csv"); mprintf(" Saving PseudoSDF Mathematica Notebook as \"%s%s.nb\"...\n",o->m_pRevSDF->m_sName,multibuf); o->m_pRevSDF->m_p2DF->WriteMathematicaNb(o->m_pRevSDF->m_sName,multibuf,".nb",false); mprintf(" Saving PseudoSDF Gnuplot Input as \"%s%s.gp\"...\n",o->m_pRevSDF->m_sName,multibuf); o->m_pRevSDF->m_p2DF->WriteGnuplotInput(o->m_pRevSDF->m_sName,multibuf,"",false); if (o->m_pRevSDF->m_iHistogramRes != 0) { mprintf(" Calculating Histogram...\n"); o->m_pRevSDF->m_p2DF->CalcHistogram(); // sprintf(buf,"his_%s",o->m_pRevSDF->m_sName); buf.sprintf("his_%s",o->m_pRevSDF->m_sName); mprintf(" Saving Histogram as \"%s%s.csv\"...\n",(const char*)buf,multibuf); o->m_pRevSDF->m_p2DF->WriteHistogram(buf,multibuf,".csv"); } if (o->m_pRevSDF->m_bCreateRevSDF) { mprintf(" Creating volumetric Revolution SDF...\n"); o->m_pRevSDF->CreateRevSDF(); // sprintf(buf,"revsdf_ref_%s.xyz",o->m_pRevSDF->m_sName); buf.sprintf("revsdf_ref_%s.xyz",o->m_pRevSDF->m_sName); mprintf(" Saving Revolution SDF reference structure as \"%s\"...\n",(const char*)buf); a = OpenFileWrite(buf,true); mfprintf(a,"2\n\n%s 0.0 0.0 0.0\n%s 0.0 %f 0.0\n",(const char*)((CAtom*)g_oaAtoms[g_iFixRealAtomType[0]])->m_sName,(const char*)((CAtom*)g_oaAtoms[g_iFixRealAtomType[1]])->m_sName,o->m_pRevSDF->m_fSecondAtomPosX/o->m_pRevSDF->m_fSecondAtomCount/100.0); fclose(a); for (z2=0;z2<=g_iSDFSmoothGrade;z2++) { try { tempSDF = new C3DF(); } catch(...) { tempSDF = NULL; } if (tempSDF == NULL) NewException((double)sizeof(C3DF),__FILE__,__LINE__,__PRETTY_FUNCTION__); tempSDF->CopyFrom(o->m_pRevSDF->m_pRevSDF); if (z2 != 0) { tempSDF->Smooth(z2); // sprintf(buf,".s%d%s.plt",z2,multibuf); buf.sprintf(".s%d%s.plt",z2,multibuf); } else // sprintf(buf,"%s.plt",multibuf); buf.sprintf("%s.plt",multibuf); mprintf(" Saving Revolution SDF as \"revsdf_%s%s\"...\n",o->m_pRevSDF->m_sName,(const char*)buf); tempSDF->WritePLT("revsdf_",o->m_pRevSDF->m_sName,buf,true); if (z2 != 0) // sprintf(buf,".s%d%s.cube",z2,multibuf); buf.sprintf(".s%d%s.cube",z2,multibuf); else // sprintf(buf,"%s.cube",multibuf); buf.sprintf("%s.cube",multibuf); mprintf(" Saving Revolution SDF as \"revsdf_%s%s\"...\n",o->m_pRevSDF->m_sName,(const char*)buf); tempSDF->WriteCube("revsdf_",o->m_pRevSDF->m_sName,buf,true); if (z2 != 0) // sprintf(buf,".s%d%s.his",z2,multibuf); buf.sprintf(".s%d%s.his",z2,multibuf); else // sprintf(buf,"%s.his",multibuf); buf.sprintf("%s.his",multibuf); mprintf(" Saving Revolution SDF Histogram as \"revsdf_%s%s\"...\n",o->m_pRevSDF->m_sName,(const char*)buf); tempSDF->CalcHistogram(); tempSDF->WriteHistogram("revsdf_",o->m_pRevSDF->m_sName,buf); if (o->m_pRevSDF->m_iHistogramRes != 0) { mprintf(" Calculating Histogram...\n"); tempSDF->CalcHistogram(); // sprintf(buf2,"his_revsdf_%s",o->m_pRevSDF->m_sName); buf2.sprintf("his_revsdf_%s",o->m_pRevSDF->m_sName); mprintf(" Saving Histogram as \"%s%s.csv\"...\n",(const char*)buf2,(const char*)buf); tempSDF->WriteHistogram(buf2,buf,".csv"); } } } _skiprevsdf:; } // END IF REVSDF } if (g_bSDF && g_bSDFMap) { mprintf(WHITE," ### Finishing SDF surface maps ###\n\n"); for (z=0;zFinish(); mprintf("\n"); } if (g_bSDF || g_bAvg ) { // sprintf(buf,"ref_%s_%s%d_%s%d_%s%d%s.xyz",((CMolecule*)g_oaMolecules[g_iFixMol])->m_sName,((CAtom*)g_oaAtoms[g_iFixRealAtomType[0]])->m_sName,g_iFixAtom[0]+1,((CAtom*)g_oaAtoms[g_iFixRealAtomType[1]])->m_sName,g_iFixAtom[1]+1,((CAtom*)g_oaAtoms[g_iFixRealAtomType[2]])->m_sName,g_iFixAtom[2]+1,multibuf); buf.sprintf("ref_%s_%s%d_%s%d_%s%d%s.xyz",((CMolecule*)g_oaMolecules[g_iFixMol])->m_sName,(const char*)((CAtom*)g_oaAtoms[g_iFixRealAtomType[0]])->m_sName,g_iFixAtom[0]+1,(const char*)((CAtom*)g_oaAtoms[g_iFixRealAtomType[1]])->m_sName,g_iFixAtom[1]+1,(const char*)((CAtom*)g_oaAtoms[g_iFixRealAtomType[2]])->m_sName,g_iFixAtom[2]+1,multibuf); // strtolower(buf); buf.ToLowercase(); mprintf("\n*** Reference molecule ***\n"); FreeFileName(buf); mprintf("Saving reference molecule as \"%s\"...",(const char*)buf); a = OpenFileWrite(buf,true); if (a == NULL) { eprintf("\nError: Could not open %s for writing.\n",(const char*)buf); return 0; } if (!g_bSaveVirtAtoms) mfprintf(a," %d \n\n",(int)(((CMolecule*)g_oaMolecules[g_iFixMol])->m_iAtomGes-((CMolecule*)g_oaMolecules[g_iFixMol])->m_laVirtualAtoms.GetSize())); else mfprintf(a," %d \n\n",((CMolecule*)g_oaMolecules[g_iFixMol])->m_iAtomGes); cc = 0; for (z=0;z<((CMolecule*)g_oaMolecules[g_iFixMol])->m_baAtomIndex.GetSize();z++) { if ((!g_bSaveVirtAtoms) && (((CMolecule*)g_oaMolecules[g_iFixMol])->m_baAtomIndex[z] == g_iVirtAtomType)) continue; for (z2=0;z2<((CMolecule*)g_oaMolecules[g_iFixMol])->m_waAtomCount[z];z2++) { if (g_bMiddleAvg) { g_pRefMol[cc][0] /= ((double)g_iSteps * ((CMolecule*)g_oaMolecules[g_iFixMol])->m_laSingleMolIndex.GetSize()); g_pRefMol[cc][1] /= ((double)g_iSteps * ((CMolecule*)g_oaMolecules[g_iFixMol])->m_laSingleMolIndex.GetSize()); g_pRefMol[cc][2] /= ((double)g_iSteps * ((CMolecule*)g_oaMolecules[g_iFixMol])->m_laSingleMolIndex.GetSize()); } if (((CMolecule*)g_oaMolecules[g_iFixMol])->m_baAtomIndex[z] == g_iVirtAtomType) mfprintf(a," %s %9.6f %9.6f %9.6f\n",((CVirtualAtom*)g_oaVirtualAtoms[((CMolecule*)g_oaMolecules[g_iFixMol])->m_laVirtualAtoms[z2]])->m_sLabel,g_pRefMol[cc][0]/100.0,g_pRefMol[cc][1]/100.0,g_pRefMol[cc][2]/100.0); else mfprintf(a," %s %9.6f %9.6f %9.6f\n",(const char*)((CAtom*)g_oaAtoms[((CMolecule*)g_oaMolecules[g_iFixMol])->m_baAtomIndex[z]])->m_sName,g_pRefMol[cc][0]/100.0,g_pRefMol[cc][1]/100.0,g_pRefMol[cc][2]/100.0); cc++; } } fclose(a); mprintf("Done.\n"); if (g_iSwapAtoms) { mprintf("\n*** This is the swap matrix of reference molecule %s:\n (It shows how often the atoms\n have been swapped with each other)\n\n ",((CMolecule*)g_oaMolecules[g_iFixMol])->m_sName); for (z2=0;z2<((CMolecule*)g_oaMolecules[g_iFixMol])->m_baAtomIndex.GetSize();z2++) { for (z3=0;z3<((CMolecule*)g_oaMolecules[g_iFixMol])->m_waAtomCount[z2];z3++) { if (((CAtom*)g_oaAtoms[((CMolecule*)g_oaMolecules[g_iFixMol])->m_baAtomIndex[z2]])->m_sName[1] == 0) mprintf(" "); mprintf("%s%d ",(const char*)((CAtom*)g_oaAtoms[((CMolecule*)g_oaMolecules[g_iFixMol])->m_baAtomIndex[z2]])->m_sName,z3+1); if (z3 < 10) mprintf(" "); } } mprintf("\n"); cc = 0; for (z2=0;z2<((CMolecule*)g_oaMolecules[g_iFixMol])->m_baAtomIndex.GetSize();z2++) { for (z3=0;z3<((CMolecule*)g_oaMolecules[g_iFixMol])->m_waAtomCount[z2];z3++) { mprintf("%s%d ",(const char*)((CAtom*)g_oaAtoms[((CMolecule*)g_oaMolecules[g_iFixMol])->m_baAtomIndex[z2]])->m_sName,z3+1); if (((CAtom*)g_oaAtoms[((CMolecule*)g_oaMolecules[g_iFixMol])->m_baAtomIndex[z2]])->m_sName[1] == 0) mprintf(" "); if (z3 < 9) mprintf(" "); cc2 = 0; for (z4=0;z4<((CMolecule*)g_oaMolecules[g_iFixMol])->m_baAtomIndex.GetSize();z4++) { for (z5=0;z5<((CMolecule*)g_oaMolecules[g_iFixMol])->m_waAtomCount[z4];z5++) { if ((z2 == z4) && (z3 == z5)) { mprintf(" *** "); goto _swm; } if (pSwapMatrix[cc*((CMolecule*)g_oaMolecules[g_iFixMol])->m_iAtomGes+cc2] != 0) mprintf("%3.0f%c ",(double)pSwapMatrix[cc*((CMolecule*)g_oaMolecules[g_iFixMol])->m_iAtomGes+cc2] * 100.0 / g_iSteps / ((CMolecule*)g_oaMolecules[g_iFixMol])->m_laSingleMolIndex.GetSize(),'%'); else mprintf(" - "); _swm: cc2++; } } mprintf("\n"); cc++; } } } } _ende: if (g_bMultiInterval) { mprintf("\n"); mprintf(YELLOW,"***********************************************\n"); mprintf(YELLOW,"*** Interval %2d (%6d - %6d) finished. ***\n",multicounter+1,g_laMultiIntervalStart[multicounter]+1,g_laMultiIntervalEnd[multicounter]+1); mprintf(YELLOW,"***********************************************\n\n"); multicounter++; if (multicounter < g_laMultiIntervalStart.GetSize()) goto _multiintervalstart; } g_iEndTime = time(NULL); if (((g_iEndTime-g_iStartTime) > 5) && (g_iStartTime != 0)) { mprintf(WHITE,"\nAnalysis was running for %luh %lum %lus.\n",(unsigned long)((g_iEndTime-g_iStartTime)/3600),(unsigned long)(((g_iEndTime-g_iStartTime)/60)%60),(unsigned long)((g_iEndTime-g_iStartTime)%60)); mprintf(WHITE," (%.3f steps per second)\n\n",g_iSteps/g_iStride/((double)g_iEndTime-g_iStartTime)); } else mprintf("\n"); WriteCredits(); if (g_bSMode) { PrintSMode(); } else { mprintf(WHITE,"*** The End ***\n\n"); } UninstallSignalHandler(); if (g_bROA) { delete g_pROAEngine; g_pROAEngine = NULL; } if (g_fInput != NULL) { fclose(g_fInput); g_fInput = NULL; } if (g_pDatabase != NULL) { delete g_pDatabase; g_pDatabase = NULL; } if (g_pTempTimestep != NULL) { delete g_pTempTimestep; g_pTempTimestep = NULL; } if (apfa != NULL) { delete[] apfa; apfa = NULL; } if (tda != NULL) { delete[] tda; tda = NULL; } if (g_pBQBFile != NULL) { delete g_pBQBFile; g_pBQBFile = NULL; } RemoveAllAnalyses(); RemoveAllElements(); RemoveAllAtoms(); RemoveAllMolecules(); RemoveAllObservations(); BTOUT; return 0; } travis-src-190101/src/travis.h0100777000000000000000000000465113412725662013130 0ustar00/***************************************************************************** TRAVIS - Trajectory Analyzer and Visualizer http://www.travis-analyzer.de/ Copyright (c) 2009-2019 Martin Brehm 2012-2019 Martin Thomas 2016-2019 Sascha Gehrke This file was written by Martin Brehm. --------------------------------------------------------------------------- This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . *****************************************************************************/ #ifndef TRAVIS_H #define TRAVIS_H // This must always be the first include directive #include "config.h" #include #include #include #include #include "bintools.h" #include "moltools.h" #include "xobject.h" #include "xobarray.h" #include "asciiart.h" #include "backtrace.h" #include "grace.h" #include "acf.h" #include "fft.h" #include "spectrum.h" #include "analysis.h" #include "analysisgroup.h" #include "timestep.h" #include "database.h" #include "xintarray.h" #include "globalvar.h" void mprintf(const char *s, ...); void strtolower(char *s); /*double AtomMass(char *s); double AtomRadius(char *s); int AtomOrd(char *s);*/ //double AtomVDWRadius(char *s); bool GatherInfos(); bool ParseAtom(const char *s, int refmol, int &ty, int &rty, int &atom); void DumpAnalyses(); bool ParseFunctions(const char *s); bool ParseRefSystem(int refmol, const char *s, int points); bool ParsePeriodic(const char *s); double GuessBoxSize(); void AddElement(const char *s, int ord, double mass, double radius, double vdw); void AddElement(const char *s, int ord, double mass, double radius, double vdw, double ncs); void AddElementData(); void SetElementColor(const char *s, unsigned char r, unsigned char g, unsigned char b, unsigned char br, unsigned char bb, unsigned char bg); #endif travis-src-190101/src/voro++.h0100777000000000000000000005100313412725652012723 0ustar00/***************************************************************************** TRAVIS - Trajectory Analyzer and Visualizer http://www.travis-analyzer.de/ Copyright (c) 2009-2019 Martin Brehm 2012-2019 Martin Thomas 2016-2019 Sascha Gehrke --------------------------------------------------------------------------- This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . *****************************************************************************/ // Voro++, a 3D cell-based Voronoi library // // Author : Chris H. Rycroft (LBL / UC Berkeley) // Email : chr@alum.mit.edu // Date : August 30th 2011 /** \file voro++.hh * \brief A file that loads all of the Voro++ header files. */ /** \mainpage Voro++ class reference manual * \section intro Introduction * Voro++ is a software library for carrying out three-dimensional computations * of the Voronoi tessellation. A distinguishing feature of the Voro++ library * is that it carries out cell-based calculations, computing the Voronoi cell * for each particle individually, rather than computing the Voronoi * tessellation as a global network of vertices and edges. It is particularly * well-suited for applications that rely on cell-based statistics, where * features of Voronoi cells (eg. volume, centroid, number of faces) can be * used to analyze a system of particles. * * Voro++ is written in C++ and can be built as a static library that can be * linked to. This manual provides a reference for every function in the class * structure. For a general overview of the program, see the Voro++ website at * http://math.lbl.gov/voro++/ and in particular the example programs at * http://math.lbl.gov/voro++/examples/ that demonstrate many of the library's * features. * * \section class C++ class structure * The code is structured around several C++ classes. The voronoicell_base * class contains all of the routines for constructing a single Voronoi cell. * It represents the cell as a collection of vertices that are connected by * edges, and there are routines for initializing, making, and outputting the * cell. The voronoicell_base class form the base of the voronoicell and * voronoicell_neighbor classes, which add specialized routines depending on * whether neighboring particle ID information for each face must be tracked or * not. Collectively, these classes are referred to as "voronoicell classes" * within the documentation. * * There is a hierarchy of classes that represent three-dimensional particle * systems. All of these are derived from the voro_base class, which contains * constants that divide a three-dimensional system into a rectangular grid of * equally-sized rectangular blocks; this grid is used for computational * efficiency during the Voronoi calculations. * * The container_base, container, and container_poly are then derived from the * voro_base class to represent a particle system in a specific * three-dimensional rectangular box using both periodic and non-periodic * boundary conditions. In addition, the container_periodic_base, * container_periodic, and container_periodic_poly classes represent * a particle system in a three-dimensional non-orthogonal periodic domain, * defined by three periodicity vectors that represent a parallelepiped. * Collectively, these classes are referred to as "container classes" within * the documentation. * * The voro_compute template encapsulates all of the routines for computing * Voronoi cells. Each container class has a voro_compute template within * it, that accesses the container's particle system, and computes the Voronoi * cells. * * There are several wall classes that can be used to apply certain boundary * conditions using additional plane cuts during the Voronoi cell compution. * The code also contains a number of small loop classes, c_loop_all, * c_loop_subset, c_loop_all_periodic, and c_loop_order that can be used to * iterate over a certain subset of particles in a container. The latter class * makes use of a special particle_order class that stores a specific order of * particles within the container. The library also contains the classes * pre_container_base, pre_container, and pre_container_poly, that can be used * as temporary storage when importing data of unknown size. * * \section voronoicell The voronoicell classes * The voronoicell class represents a single Voronoi cell as a convex * polyhedron, with a set of vertices that are connected by edges. The class * contains a variety of functions that can be used to compute and output the * Voronoi cell corresponding to a particular particle. The command init() * can be used to initialize a cell as a large rectangular box. The Voronoi cell * can then be computed by repeatedly cutting it with planes that correspond to * the perpendicular bisectors between that particle and its neighbors. * * This is achieved by using the plane() routine, which will recompute the * cell's vertices and edges after cutting it with a single plane. This is the * key routine in voronoicell class. It begins by exploiting the convexity * of the underlying cell, tracing between edges to work out if the cell * intersects the cutting plane. If it does not intersect, then the routine * immediately exits. Otherwise, it finds an edge or vertex that intersects * the plane, and from there, traces out a new face on the cell, recomputing * the edge and vertex structure accordingly. * * Once the cell is computed, there are many routines for computing features of * the the Voronoi cell, such as its volume, surface area, or centroid. There * are also many routines for outputting features of the Voronoi cell, or * writing its shape in formats that can be read by Gnuplot or POV-Ray. * * \subsection internal Internal data representation * The voronoicell class has a public member p representing the * number of vertices. The polyhedral structure of the cell is stored * in the following arrays: * * - pts: a one-dimensional array of floating point numbers, that represent the * position vectors x_0, x_1, ..., x_{p-1} of the polyhedron vertices. * - nu: the order of each vertex n_0, n_1, ..., n_{p-1}, corresponding to * the number of other vertices to which each is connected. * - ed: a two-dimensional table of edges and relations. For the ith vertex, * ed[i] has 2n_i+1 elements. The first n_i elements are the edges e(j,i), * where e(j,i) is the jth neighbor of vertex i. The edges are ordered * according to a right-hand rule with respect to an outward-pointing normal. * The next n_i elements are the relations l(j,i) which satisfy the property * e(l(j,i),e(j,i)) = i. The final element of the ed[i] list is a back * pointer used in memory allocation. * * In a very large number of cases, the values of n_i will be 3. This is because * the only way that a higher-order vertex can be created in the plane() * routine is if the cutting plane perfectly intersects an existing vertex. For * random particle arrangements with position vectors specified to double * precision this should happen very rarely. A preliminary version of this code * was quite successful with only making use of vertices of order 3. However, * when calculating millions of cells, it was found that this approach is not * robust, since a single floating point error can invalidate the computation. * This can also be a problem for cases featuring crystalline arrangements of * particles where the corresponding Voronoi cells may have high-order vertices * by construction. * * Because of this, Voro++ takes the approach that it if an existing vertex is * within a small numerical tolerance of the cutting plane, it is treated as * being exactly on the plane, and the polyhedral topology is recomputed * accordingly. However, while this improves robustness, it also adds the * complexity that n_i may no longer always be 3. This causes memory management * to be significantly more complicated, as different vertices require a * different number of elements in the ed[][] array. To accommodate this, the * voronoicell class allocated edge memory in a different array called mep[][], * in such a way that all vertices of order k are held in mep[k]. If vertex * i has order k, then ed[i] points to memory within mep[k]. The array ed[][] * is never directly initialized as a two-dimensional array itself, but points * at allocations within mep[][]. To the user, it appears as though each row of * ed[][] has a different number of elements. When vertices are added or * deleted, care must be taken to reorder and reassign elements in these * arrays. * * During the plane() routine, the code traces around the vertices of the cell, * and adds new vertices along edges which intersect the cutting plane to * create a new face. The values of l(j,i) are used in this computation, as * when the code is traversing from one vertex on the cell to another, this * information allows the code to immediately work out which edge of a vertex * points back to the one it came from. As new vertices are created, the l(j,i) * are also updated to ensure consistency. To ensure robustness, the plane * cutting algorithm should work with any possible combination of vertices * which are inside, outside, or exactly on the cutting plane. * * Vertices exactly on the cutting plane create some additional computational * difficulties. If there are two marginal vertices connected by an existing * edge, then it would be possible for duplicate edges to be created between * those two vertices, if the plane routine traces along both sides of this * edge while constructing the new face. The code recognizes these cases and * prevents the double edge from being formed. Another possibility is the * formation of vertices of order two or one. At the end of the plane cutting * routine, the code checks to see if any of these are present, removing the * order one vertices by just deleting them, and removing the order two * vertices by connecting the two neighbors of each vertex together. It is * possible that the removal of a single low-order vertex could result in the * creation of additional low-order vertices, so the process is applied * recursively until no more are left. * * \section container The container classes * There are four container classes available for general usage: container, * container_poly, container_periodic, and container_periodic_poly. Each of * these represent a system of particles in a specific three-dimensional * geometry. They contain routines for importing particles from a text file, * and adding particles individually. They also contain a large number of * analyzing and outputting the particle system. Internally, the routines that * compute Voronoi cells do so by making use of the voro_compute template. * Each container class contains routines that tell the voro_compute template * about the specific geometry of this container. * * \section voro_compute The voro_compute template * The voro_compute template encapsulates the routines for carrying out the * Voronoi cell computations. It contains data structures suchs as a mask and a * queue that are used in the computations. The voro_compute template is * associated with a specific container class, and during the computation, it * calls routines in the container class to access the particle positions that * are stored there. * * The key routine in this class is compute_cell(), which makes use of a * voronoicell class to construct a Voronoi cell for a specific particle in the * container. The basic approach that this function takes is to repeatedly cut * the Voronoi cell by planes corresponding neighboring particles, and stop * when it recognizes that all the remaining particles in the container are too * far away to possibly influence cell's shape. The code makes use of two * possible methods for working out when a cell computation is complete: * * - Radius test: if the maximum distance of a Voronoi cell * vertex from the cell center is R, then no particles more than a distance * 2R away can possibly influence the cell. This a very fast computation to * do, but it has no directionality: if the cell extends a long way in one * direction then particles a long distance in other directions will still * need to be tested. * - Region test: it is possible to test whether a specific region can * possibly influence the cell by applying a series of plane tests at the * point on the region which is closest to the Voronoi cell center. This is a * slower computation to do, but it has directionality. * * Another useful observation is that the regions that need to be tested are * simply connected, meaning that if a particular region does not need to be * tested, then neighboring regions which are further away do not need to be * tested. * * For maximum efficiency, it was found that a hybrid approach making use of * both of the above tests worked well in practice. Radius tests work well for * the first few blocks, but switching to region tests after then prevent the * code from becoming extremely slow, due to testing over very large spherical * shells of particles. The compute_cell() routine therefore takes the * following approach: * * - Initialize the voronoicell class to fill the entire computational domain. * - Cut the cell by any wall objects that have been added to the container. * - Apply plane cuts to the cell corresponding to the other particles which * are within the current particle's region. * - Test over a pre-computed worklist of neighboring regions, that have been * ordered according to the minimum distance away from the particle's * position. Apply radius tests after every few regions to see if the * calculation can terminate. * - If the code reaches the end of the worklist, add all the neighboring * regions to a new list. * - Carry out a region test on the first item of the list. If the region needs * to be tested, apply the plane() routine for all of its particles, and then * add any neighboring regions to the end of the list that need to be tested. * Continue until the list has no elements left. * * The compute_cell() routine forms the basis of many other routines, such as * store_cell_volumes() and draw_cells_gnuplot() that can be used to calculate * and draw the cells in a container. * * \section walls Wall computation * Wall computations are handled by making use of a pure virtual wall class. * Specific wall types are derived from this class, and require the * specification of two routines: point_inside() that tests to see if a point * is inside a wall or not, and cut_cell() that cuts a cell according to the * wall's position. The walls can be added to the container using the * add_wall() command, and these are called each time a compute_cell() command * is carried out. At present, wall types for planes, spheres, cylinders, and * cones are provided, although custom walls can be added by creating new * classes derived from the pure virtual class. Currently all wall types * approximate the wall surface with a single plane, which produces some small * errors, but generally gives good results for dense particle packings in * direct contact with a wall surface. It would be possible to create more * accurate walls by making cut_cell() routines that approximate the curved * surface with multiple plane cuts. * * The wall objects can used for periodic calculations, although to obtain * valid results, the walls should also be periodic as well. For example, in a * domain that is periodic in the x direction, a cylinder aligned along the x * axis could be added. At present, the interior of all wall objects are convex * domains, and consequently any superposition of them will be a convex domain * also. Carrying out computations in non-convex domains poses some problems, * since this could theoretically lead to non-convex Voronoi cells, which the * internal data representation of the voronoicell class does not support. For * non-convex cases where the wall surfaces feature just a small amount of * negative curvature (eg. a torus) approximating the curved surface with a * single plane cut may give an acceptable level of accuracy. For non-convex * cases that feature internal angles, the best strategy may be to decompose * the domain into several convex subdomains, carry out a calculation in each, * and then add the results together. The voronoicell class cannot be easily * modified to handle non-convex cells as this would fundamentally alter the * algorithms that it uses, and cases could arise where a single plane cut * could create several new faces as opposed to just one. * * \section loops Loop classes * The container classes have a number of simple routines for calculating * Voronoi cells for all particles within them. However, in some situations it * is desirable to iterate over a specific subset of particles. This can be * achieved with the c_loop classes that are all derived from the c_loop_base * class. Each class can iterate over a specific subset of particles in a * container. There are three loop classes for use with the container and * container_poly classes: * * - c_loop_all will loop over all of the particles in a container. * - c_loop_subset will loop over a subset of particles in a container that lie * within some geometrical region. It can loop over particles in a * rectangular box, particles in a sphere, or particles that lie within * specific internal computational blocks. * - c_loop_order will loop over a specific list of particles that were * previously stored in a particle_order class. * * Several of the key routines within the container classes (such as * draw_cells_gnuplot and print_custom) have versions where they can be passed * a loop class to use. Loop classes can also be used directly and there are * some examples on the library website that demonstrate this. It is also * possible to write custom loop classes. * * In addition to the loop classes mentioned above, there is also a * c_loop_all_periodic class, that is specifically for use with the * container_periodic and container_periodic_poly classes. Since the data * structures of these containers differ considerably, it requires a different * loop class that is not interoperable with the others. * * \section pre_container The pre_container classes * Voro++ makes use of internal computational grid of blocks that are used to * configure the code for maximum efficiency. As discussed on the library * website, the best performance is achieved for around 5 particles per block, * with anything in the range from 3 to 12 giving good performance. Usually * the size of the grid can be chosen by ensuring that the number of blocks is * equal to the number of particles divided by 5. * * However, this can be difficult to choose in cases when the number of * particles is not known a priori, and in thes cases the pre_container classes * can be used. They can import an arbitrary number of particle positions from * a file, dynamically allocating memory in chunks as necessary. Once particles * are imported, they can guess an optimal block arrangement to use for the * container class, and then transfer the particles to the container. By * default, this procedure is used by the command-line utility to enable it to * work well with arbitrary sizes of input data. * * The pre_container class can be used when no particle radius information is * available, and the pre_container_poly class can be used when radius * information is available. At present, the pre_container classes can only be * used with the container and container_poly classes. They do not support * the container_periodic and container_periodic_poly classes. */ #ifndef VOROPP_HH #define VOROPP_HH // This must always be the first include directive #include "config.h" #include "v_config.h" #include "v_common.h" #include "v_cell.h" #include "v_base.h" #include "v_container.h" #include "v_unitcell.h" #include "v_container_prd.h" #include "v_pre_container.h" #include "v_compute.h" #include "v_c_loops.h" #include "v_wall.h" #endif travis-src-190101/src/vorowrapper.cpp0100777000000000000000000023114013412725622014530 0ustar00/***************************************************************************** TRAVIS - Trajectory Analyzer and Visualizer http://www.travis-analyzer.de/ Copyright (c) 2009-2019 Martin Brehm 2012-2019 Martin Thomas 2016-2019 Sascha Gehrke This file was written by Martin Brehm. --------------------------------------------------------------------------- This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . *****************************************************************************/ // This must always be the first include directive #include "config.h" #include "vorowrapper.h" #include "voro++.h" #include "tools.h" #include "globalvar.h" #include "maintools.h" const char *GetRevisionInfo_vorowrapper(unsigned int len) { static char buf[256]; GET_REVISION_INFO( buf, len ); return buf; } const char *GetSourceVersion_vorowrapper() { static char buf[256]; GET_SOURCE_VERSION( buf ); return buf; } CVoroWrapper::CVoroWrapper() { m_pContainer = NULL; m_oaVoroAtoms.SetName("CVoroWrapper::m_oaVoroAtoms"); m_oaVoroMolecules.SetName("CVoroWrapper::m_oaVoroMolecules"); m_faPOVFaceColor.SetName("CVoroWrapper::m_faPOVFaceColor"); m_waPOVFaceColorMol.SetName("CVoroWrapper::m_waPOVFaceColorMol"); m_waPOVFaceColorElem.SetName("CVoroWrapper::m_waPOVFaceColorElem"); m_waPOVFaceColorAtom.SetName("CVoroWrapper::m_waPOVFaceColorAtom"); m_waSurfCoverSM.SetName("CVoroWrapper::m_waSurfCoverSM"); m_oaSurfCoverData.SetName("CVoroWrapper::m_oaSurfCoverData"); m_waSurfCoverMol.SetName("CVoroWrapper::m_waSurfCoverMol"); m_waSurfCoverElem.SetName("CVoroWrapper::m_waSurfCoverElem"); m_waSurfCoverAtom.SetName("CVoroWrapper::m_waSurfCoverAtom"); m_fPOVAngle = 90.0; m_sPOVText[0] = 0; m_iPOVFrameCounter = 0; m_fPOVZoom = 1.0f; m_fPOVBoxOuterOpacity = 1.0; m_vPOVBoxClipLow[0] = -1.0; m_vPOVBoxClipLow[1] = -1.0; m_vPOVBoxClipLow[2] = -1.0; m_vPOVBoxClipHigh[0] = 1.0; m_vPOVBoxClipHigh[1] = 1.0; m_vPOVBoxClipHigh[2] = 1.0; m_fPOVAtomCenter = 0.0; m_fPOVScale = 0.95; m_bPOVMolecules = false; m_fPOVExplode = 1.0; m_fPOVClip = 1.0; m_fPOVRayTrans = 0.0; m_fPOVNbTrans = 0.0; m_fPOVFaceTrans = 0.0; m_fPOVEdgeTrans = 0.0; m_fPOVNbHighlightFac = 1.3; m_fPOVFaceBleach = 0.5; m_vPOVFaceBleach[0] = 0.5; m_vPOVFaceBleach[1] = 0.5; m_vPOVFaceBleach[2] = 1.0; m_bIncludeWritten = false; m_bVoroStat = false; m_bSurfCover = false; m_bWritePOV = false; strcpy(m_sPOVText,"ABCabc"); } CVoroWrapper::~CVoroWrapper() { } void CVoroWrapper::Build(CTimeStep *ts) { int ijk, q, z, z2, z3, id, i, faces, co; CVoroAtom *va; CVoroMolecule *vm; double /**pp,*/ ta, surf, volume, vg; voronoicell_neighbor c; vector nb; vector fo; vector fa; int *nbtemp; std::vector tsvol, tssurf, tsavr, tsrad; std::vector tsface; try { nbtemp = new int[m_oaVoroAtoms.GetSize()]; } catch(...) { nbtemp = NULL; } if (nbtemp == NULL) NewException((double)m_oaVoroAtoms.GetSize()*sizeof(int),__FILE__,__LINE__,__PRETTY_FUNCTION__); try { m_pContainer = new container_periodic_poly(g_fBoxX/1000.0,0,g_fBoxY/1000.0,0,0,g_fBoxZ/1000.0,m_iBlocksX,m_iBlocksY,m_iBlocksZ,g_iVoroMemory); } catch(...) { m_pContainer = NULL; } if (m_pContainer == NULL) NewException((double)sizeof(container_periodic_poly),__FILE__,__LINE__,__PRETTY_FUNCTION__); for (z=0;zput(z,ts->m_vaCoords[z][0]/1000.0,ts->m_vaCoords[z][1]/1000.0,ts->m_vaCoords[z][2]/1000.0,g_faVoronoiRadii[z]/1000.0); c_loop_all_periodic vl(*m_pContainer); for (z=0;ztempfaces = 0; vm->tempsurf = 0; vm->tempvol = 0; for (z2=0;z2m_pNbhTempMol[z2] = 0; for (z2=0;z2m_pNbhTempArea[z2] = 0.0; for (z2=0;z2m_pNbhTempAtoms[z2] = 0; } for (z=0;zcompute_cell(c,vl)) { co++; ijk=vl.ijk; q=vl.q; // pp=m_pContainer->p[ijk]+m_pContainer->ps*q; id = m_pContainer->id[ijk][q]; c.face_areas(fa); c.face_orders(fo); c.neighbors(nb); m_pAtomTouched[id] = true; va = (CVoroAtom*)m_oaVoroAtoms[m_pAssignAtoms[id]]; vm = (CVoroMolecule*)m_oaVoroMolecules[m_pAssignMolecules[id]]; surf = c.surface_area(); faces = c.number_of_faces(); volume = c.volume(); vg += volume; va->m_pVolume->AddToBin(volume*1000.0); va->m_pSurfaceArea->AddToBin(surf*100.0); va->m_pFaces->AddToBin_Int(faces); va->m_pMaxRadius->AddToBin(sqrt(c.max_radius_squared())*1000.0); va->m_pAVRatio->AddToBin(10.6347231054330961*volume/mypow(surf,1.5)); if (m_bVoroStat && m_bVoroTimeSeries) { tsvol[id] = volume*1000.0; tssurf[id] = surf*100.0; tsface[id] = faces; tsavr[id] = 10.6347231054330961*volume/mypow(surf,1.5); tsrad[id] = sqrt(c.max_radius_squared())*1000.0; } vm->tempvol += volume*1000.0; for (z2=0;z2m_pNbhTempMol[z2] = 0; } ta = 0; for (z2=0;z2m_pFaceOrders->AddToBin_Int(fo[z2]); if (m_pAssignMolecules[id] != m_pAssignMolecules[nb[z2]]) { nbtemp[m_pAssignAtoms[nb[z2]]]++; va->m_pNbhDistAtoms[m_pAssignAtoms[nb[z2]]]->AddToBin(ts->FoldedDistance(id,nb[z2])); ((CVoroMolecule*)m_oaVoroMolecules[m_pAssignMolecules[nb[z2]]])->m_pNbhDistAtoms[m_pAssignAtoms[id]]->AddToBin(ts->FoldedDistance(id,((CVoroMolecule*)m_oaVoroMolecules[m_pAssignMolecules[nb[z2]]])->m_iCenterOffset)); if (vm->m_pNbhTempAtoms[nb[z2]] == 0) { vm->m_pNbhTempAtoms[nb[z2]]++; vm->m_pNbhDistAtoms[m_pAssignAtoms[nb[z2]]]->AddToBin(ts->FoldedDistance(id,((CVoroMolecule*)m_oaVoroMolecules[m_pAssignMolecules[nb[z2]]])->m_iCenterOffset)); } if (vm->m_pNbhTempMol[m_pAssignMolecules[nb[z2]]] == 0) { vm->m_pNbhTempMol[m_pAssignMolecules[nb[z2]]]++; vm->m_pNbhDistMolecules[m_pAssignMoleculeTypes[nb[z2]]]->AddToBin(ts->FoldedDistance(((CVoroMolecule*)m_oaVoroMolecules[m_pAssignMolecules[id]])->m_iCenterOffset,((CVoroMolecule*)m_oaVoroMolecules[m_pAssignMolecules[nb[z2]]])->m_iCenterOffset)); } vm->m_pNbhTempArea[m_pAssignMoleculeTypes[nb[z2]]] += fa[z2] * 100.0; if (va->m_pNbhTempMol[m_pAssignMolecules[nb[z2]]] == 0) va->m_pNbhDistMolecules[m_pAssignMoleculeTypes[nb[z2]]]->AddToBin(ts->FoldedDistance(id,((CVoroMolecule*)m_oaVoroMolecules[m_pAssignMolecules[nb[z2]]])->m_iCenterOffset)); va->m_pNbhTempMol[m_pAssignMolecules[nb[z2]]]++; vm->tempsurf += fa[z2]*100.0; vm->tempfaces++; ta += fa[z2]*100.0; } } va->m_pExposedSurface->AddToBin(ta); va->m_pExposedSurfacePerc->AddToBin(ta/surf); for (z2=0;z2m_pNbhAtoms[z2]->AddToBin_Int(nbtemp[z2]); } for (z2=0;z2m_iMolecule != z2) continue; if (va->m_pNbhTempMol[z3] != 0) i++; } va->m_pNbhMolecules[z2]->AddToBin_Int(i); } } else { mprintf("\nWarning: Compute_Cell failed."); } } while (vl.inc()); } for (z=0;zm_sName,g_laAtomSMIndex[z]+1,(const char*)((CAtom*)g_oaAtoms[g_waAtomRealElement[z]])->m_sName,g_waAtomMolNumber[z]+1); } if ((co != g_iGesAtomCount) || (fabs(vg*1000.0-g_fBoxX*g_fBoxY*g_fBoxZ/1000000.0)/(g_fBoxX*g_fBoxY*g_fBoxZ/1000000.0) > 0.001)) { mprintf("\nVoro++: Problem. %d/%d atoms touched. V=%f/%f A^3.",co,g_iGesAtomCount,vg*1000.0,g_fBoxX*g_fBoxY*g_fBoxZ/1000000.0); } for (z=0;zm_pVolume->AddToBin(vm->tempvol); vm->m_pSurfaceArea->AddToBin(vm->tempsurf); vm->m_pFaces->AddToBin_Int(vm->tempfaces); vm->m_pAVRatio->AddToBin(10.6347231054330961*vm->tempvol/mypow(vm->tempsurf,1.5)); for (z2=0;z2m_pNbhTempAtoms[z3] != 0) i++; } vm->m_pNbhAtoms[z2]->AddToBin_Int(i); } for (z2=0;z2m_iMolecule != z2) continue; if (vm->m_pNbhTempMol[z3] != 0) i++; } vm->m_pNbhMolecules[z2]->AddToBin_Int(i); } for (z2=0;z2m_pNbhAreaMolecules[z2]->AddToBin(vm->m_pNbhTempArea[z2]); } } if (m_bVoroStat && m_bVoroTimeSeries) { fprintf(m_fTSVolume,"%lu",g_iSteps); fprintf(m_fTSSurface,"%lu",g_iSteps); fprintf(m_fTSFaces,"%lu",g_iSteps); fprintf(m_fTSAVRatio,"%lu",g_iSteps); fprintf(m_fTSMaxRadius,"%lu",g_iSteps); for (z=0;z<(int)m_iaVoroTS.size();z++) { fprintf(m_fTSVolume,"; %f",tsvol[m_iaVoroTS[z]]); fprintf(m_fTSSurface,"; %f",tssurf[m_iaVoroTS[z]]); fprintf(m_fTSFaces,"; %d",tsface[m_iaVoroTS[z]]); fprintf(m_fTSAVRatio,"; %f",tsavr[m_iaVoroTS[z]]); fprintf(m_fTSMaxRadius,"; %f",tsrad[m_iaVoroTS[z]]); } fprintf(m_fTSVolume,"\n"); fprintf(m_fTSSurface,"\n"); fprintf(m_fTSFaces,"\n"); fprintf(m_fTSAVRatio,"\n"); fprintf(m_fTSMaxRadius,"\n"); fflush(m_fTSVolume); fflush(m_fTSSurface); fflush(m_fTSFaces); fflush(m_fTSAVRatio); fflush(m_fTSMaxRadius); } delete[] nbtemp; delete m_pContainer; } void CVoroWrapper::Init() { int z, z2, z3, z4, i; CVoroAtom *va; CVoroMolecule *vm; CMolecule *m; CSingleMolecule *sm; ParseVoronoiRadii(); m_iBlocksX = (int)(mypow(g_iGesAtomCount/optimal_particles/g_fBoxX/g_fBoxY/g_fBoxZ,1/3.0)*g_fBoxX)+1; m_iBlocksY = (int)(mypow(g_iGesAtomCount/optimal_particles/g_fBoxX/g_fBoxY/g_fBoxZ,1/3.0)*g_fBoxY)+1; m_iBlocksZ = (int)(mypow(g_iGesAtomCount/optimal_particles/g_fBoxX/g_fBoxY/g_fBoxZ,1/3.0)*g_fBoxZ)+1; m_fBoxDens = g_iGesAtomCount / g_fBoxX / g_fBoxY / g_fBoxZ * 1000000.0; // Particles / Angstrom^3 if (m_bVoroStat || m_bSurfCover || m_bWritePOV || g_bVoid || g_bTegri || g_bDomA ) { try { m_pAssignAtoms = new long[g_iGesAtomCount]; } catch(...) { m_pAssignAtoms = NULL; } if (m_pAssignAtoms == NULL) NewException((double)g_iGesAtomCount*sizeof(long),__FILE__,__LINE__,__PRETTY_FUNCTION__); try { m_pAssignMolecules = new long[g_iGesAtomCount]; } catch(...) { m_pAssignMolecules = NULL; } if (m_pAssignMolecules == NULL) NewException((double)g_iGesAtomCount*sizeof(long),__FILE__,__LINE__,__PRETTY_FUNCTION__); try { m_pAssignMoleculeTypes = new long[g_iGesAtomCount]; } catch(...) { m_pAssignMoleculeTypes = NULL; } if (m_pAssignMoleculeTypes == NULL) NewException((double)g_iGesAtomCount*sizeof(long),__FILE__,__LINE__,__PRETTY_FUNCTION__); try { m_pAtomTouched = new bool[g_iGesAtomCount]; } catch(...) { m_pAtomTouched = NULL; } if (m_pAtomTouched == NULL) NewException((double)g_iGesAtomCount*sizeof(bool),__FILE__,__LINE__,__PRETTY_FUNCTION__); i = 0; for (z=0;zm_waAtomCount.GetSize()-1;z2++) { for (z3=0;z3m_waAtomCount[z2];z3++) { try { va = new CVoroAtom(); } catch(...) { va = NULL; } if (va == NULL) NewException((double)sizeof(CVoroAtom),__FILE__,__LINE__,__PRETTY_FUNCTION__); va->m_pParent = this; va->m_iAtomType = z2; va->m_iAtom = z3; va->m_iRealAtomType = m->m_baAtomIndex[z2]; va->m_iMolecule = z; m_oaVoroAtoms.Add(va); for (z4=0;z4m_laSingleMolIndex.GetSize();z4++) { sm = (CSingleMolecule*)g_oaSingleMolecules[m->m_laSingleMolIndex[z4]]; // mprintf("Mol %d, AT %d, A %d, Sm %d, Offset %f, i=%d.\n",z+1,z2+1,z3+1,z4+1,((CxIntArray*)sm->m_oaAtomOffset[z2])->GetAt(z3),i); m_pAssignAtoms[((CxIntArray*)sm->m_oaAtomOffset[z2])->GetAt(z3)] = i; } i++; } } } i = 0; for (z=0;zm_laSingleMolIndex.GetSize();z4++) { sm = (CSingleMolecule*)g_oaSingleMolecules[m->m_laSingleMolIndex[z4]]; try { vm = new CVoroMolecule(); } catch(...) { vm = NULL; } if (vm == NULL) NewException((double)sizeof(CVoroMolecule),__FILE__,__LINE__,__PRETTY_FUNCTION__); vm->m_pParent = this; vm->m_iMolecule = z; vm->m_iSingleMol = z4; vm->m_iCenterOffset = ((CxIntArray*)sm->m_oaAtomOffset[sm->m_oaAtomOffset.GetSize()-1])->GetAt(1); // 1 is #2, which is Center of Mass m_oaVoroMolecules.Add(vm); for (z2=0;z2m_waAtomCount.GetSize()-1;z2++) { for (z3=0;z3m_waAtomCount[z2];z3++) { m_pAssignMolecules[((CxIntArray*)sm->m_oaAtomOffset[z2])->GetAt(z3)] = i; m_pAssignMoleculeTypes[((CxIntArray*)sm->m_oaAtomOffset[z2])->GetAt(z3)] = z; } } i++; } } } g_iVoroMemory = 16; } void CVoroWrapper::Init2() { int z; if (m_bVoroStat) { for (z=0;zInitAnalyses(); try { ((CVoroAtom*)m_oaVoroAtoms[z])->m_pNbhTempMol = new int[m_oaVoroMolecules.GetSize()]; } catch(...) { ((CVoroAtom*)m_oaVoroAtoms[z])->m_pNbhTempMol = NULL; } if (((CVoroAtom*)m_oaVoroAtoms[z])->m_pNbhTempMol == NULL) NewException((double)m_oaVoroMolecules.GetSize()*sizeof(int),__FILE__,__LINE__,__PRETTY_FUNCTION__); } for (z=0;zInitAnalyses(); try { ((CVoroMolecule*)m_oaVoroMolecules[z])->m_pNbhTempMol = new int[m_oaVoroMolecules.GetSize()]; } catch(...) { ((CVoroMolecule*)m_oaVoroMolecules[z])->m_pNbhTempMol = NULL; } if (((CVoroMolecule*)m_oaVoroMolecules[z])->m_pNbhTempMol == NULL) NewException((double)m_oaVoroMolecules.GetSize()*sizeof(int),__FILE__,__LINE__,__PRETTY_FUNCTION__); try { ((CVoroMolecule*)m_oaVoroMolecules[z])->m_pNbhTempArea = new double[m_oaVoroMolecules.GetSize()]; } catch(...) { ((CVoroMolecule*)m_oaVoroMolecules[z])->m_pNbhTempArea = NULL; } if (((CVoroMolecule*)m_oaVoroMolecules[z])->m_pNbhTempArea == NULL) NewException((double)m_oaVoroMolecules.GetSize()*sizeof(double),__FILE__,__LINE__,__PRETTY_FUNCTION__); try { ((CVoroMolecule*)m_oaVoroMolecules[z])->m_pNbhTempAtoms = new int[g_iGesAtomCount]; } catch(...) { ((CVoroMolecule*)m_oaVoroMolecules[z])->m_pNbhTempAtoms = NULL; } if (((CVoroMolecule*)m_oaVoroMolecules[z])->m_pNbhTempAtoms == NULL) NewException((double)g_iGesAtomCount*sizeof(int),__FILE__,__LINE__,__PRETTY_FUNCTION__); } if (m_bVoroTimeSeries) { #ifdef TARGET_WINDOWS m_fTSVolume = OpenFileWrite("voronoi\\timeseries_volume.csv",true); m_fTSSurface = OpenFileWrite("voronoi\\timeseries_surface.csv",true); m_fTSFaces = OpenFileWrite("voronoi\\timeseries_faces.csv",true); m_fTSAVRatio = OpenFileWrite("voronoi\\timeseries_avratio.csv",true); m_fTSMaxRadius = OpenFileWrite("voronoi\\timeseries_maxradius.csv",true); #else m_fTSVolume = OpenFileWrite("voronoi/timeseries_volume.csv",true); m_fTSSurface = OpenFileWrite("voronoi/timeseries_surface.csv",true); m_fTSFaces = OpenFileWrite("voronoi/timeseries_faces.csv",true); m_fTSAVRatio = OpenFileWrite("voronoi/timeseries_avratio.csv",true); m_fTSMaxRadius = OpenFileWrite("voronoi/timeseries_maxradius.csv",true); #endif fprintf(m_fTSVolume,"%s\n",m_sVoroTSHead.c_str()); fprintf(m_fTSSurface,"%s\n",m_sVoroTSHead.c_str()); fprintf(m_fTSFaces,"%s\n",m_sVoroTSHead.c_str()); fprintf(m_fTSAVRatio,"%s\n",m_sVoroTSHead.c_str()); fprintf(m_fTSMaxRadius,"%s\n",m_sVoroTSHead.c_str()); } } } void CVoroWrapper::Parse() { CTimeStep *t; CMolecule *m; CSingleMolecule *sm; // unsigned long col; // char buf[256]; CxString buf; int z, z2, z3, z4; CxIntArray tia, tia2; CxDoubleArray *fa; std::vector ml; CAtomGroup ag; mprintf(WHITE,">>> Voronoi Analysis >>>\n\n"); m_bVoroStat = AskYesNo(" Compute Voronoi statistics (y/n)? [yes] ",true); if (m_bVoroStat) { mprintf("\n Please choose the print detail level of the Voronoi statistics:\n"); mprintf(" 0 - Only write min. / max. / average / std.dev. of basic quantities per atom / molecule type\n"); mprintf(" 1 - Write some additional info (e.g., time series, neighborhood probabilities) per atom / molecule type\n"); mprintf(" 2 - Write the histograms of these quantities to additional files\n"); mprintf(" 3 - Also write neighborhood histograms for all pairs of atom / molecule types\n\n"); mprintf(" Values >= 1 will create a \"voronoi\" subdirectory to host the detailed result files.\n\n"); g_iVoroPrintLevel = AskRangeInteger(" Enter print detail level of Voronoi statistics (0-3): [0] ",0,3,0); mprintf("\n"); } if (m_bVoroStat && (g_iVoroPrintLevel >= 1)) { mprintf(" Creating the sub-directory \"voronoi\"...\n"); (void)system("mkdir voronoi"); mprintf("\n"); m_bVoroTimeSeries = AskYesNo(" Write time series of Voronoi data (cell volumes, etc.) for some atoms (y/n)? [no] ",false); if (m_bVoroTimeSeries) { mprintf(WHITE,"\n >>> Voronoi Time Series >>>\n\n"); m_sVoroTSHead = "#Step"; for (z=0;zm_sName)) continue; if (m->m_iAtomGesNoVirt == 1) { mprintf(" %s is only one atom, there is no choice.\n",m->m_sName); ag.Reset(); ag.m_pMolecule = m; ag.AddAtom(0,0,false); ag.SortAtoms(); ag.BuildName(); } else { _as: ag.Reset(); AskString(" Which atom(s) to observe from %s (e.g. \"C1,C3-5,H\", \"*\"=all)? [*] ", &buf, "*", m->m_sName ); if (!ag.ParseAtoms(m,buf)) goto _as; } _ms: ml.clear(); if (m->m_laSingleMolIndex.GetSize() > 1) { AskString(" Which molecules of %s to use (1-%d, e.g. \"1,3-7\")? [all] ",&buf,"",m->m_sName,m->m_laSingleMolIndex.GetSize()); if (buf.GetLength() == 0) { for (z2=1;z2<=m->m_laSingleMolIndex.GetSize();z2++) ml.push_back(z2); } else if (!ParseIntList((const char*)buf,ml)) { eprintf("Invalid input.\n"); goto _ms; } for (z2=0;z2<(int)ml.size();z2++) { if ((ml[z2] < 1) || (ml[z2] > m->m_laSingleMolIndex.GetSize())) { eprintf("Error: Molecule index %d out of range (allowed: 1 ... %d).\n",ml[z2],m->m_laSingleMolIndex.GetSize()); goto _ms; } ml[z2]--; } } else ml.push_back(0); for (z2=0;z2GetSize();z3++) { for (z4=0;z4<(int)ml.size();z4++) { sm = (CSingleMolecule*)g_oaSingleMolecules[m->m_laSingleMolIndex[ml[z4]]]; m_iaVoroTS.push_back(((CxIntArray*)sm->m_oaAtomOffset[ag.m_baAtomType[z2]])->GetAt(((CxIntArray*)ag.m_oaAtoms[z2])->GetAt(z3))); buf.sprintf( "; %s[%d]_%s%d", m->m_sName, ml[z4]+1, (const char*)((CAtom*)g_oaAtoms[m->m_baAtomIndex[ag.m_baAtomType[z2]]])->m_sName, ((CxIntArray*)ag.m_oaAtoms[z2])->GetAt(z3)+1 ); m_sVoroTSHead += (const char*)buf; } } } } mprintf("\n Observing %lu atoms.\n\n",m_iaVoroTS.size()); mprintf(WHITE,"\n <<< Voronoi Time Series <<<\n\n"); } else mprintf("\n"); } else m_bVoroTimeSeries = false; m_bSurfCover = AskYesNo(" Calculate surface coverage of one molecule (y/n)? [no] ",false); if (m_bSurfCover) { if (g_oaMolecules.GetSize() > 1) { m_iSurfCoverMol = AskRangeInteger_ND(" Use Voronoi cell of which molecule type (1-%d)? ",1,g_oaMolecules.GetSize(),g_oaMolecules.GetSize())-1; } else m_iSurfCoverMol = 0; m = (CMolecule*)g_oaMolecules[m_iSurfCoverMol]; if (m->m_laSingleMolIndex.GetSize() > 1) /* m_iSurfCoverSM = AskInteger_ND(" Which representants of %s to use (1-%d)? ",m->m_sName,m->m_laSingleMolIndex.GetSize())-1; else m_iSurfCoverSM = 0;*/ { _surfsmagain: AskString(" Which representants of %s to use (allowed 1-%d, eg. 5-7,9)? [all] ",&buf,"",m->m_sName,m->m_laSingleMolIndex.GetSize()); if (strlen(buf) == 0) { for (z=0;zm_laSingleMolIndex.GetSize();z++) m_waSurfCoverSM.Add((unsigned short)z+1); } else ParseIntList(buf,&m_waSurfCoverSM); for (z=0;z m->m_laSingleMolIndex.GetSize())) { eprintf("Error: %d is not within the allowed range.\n",m_waSurfCoverSM[z]); goto _surfsmagain; } m_waSurfCoverSM[z]--; } } else m_waSurfCoverSM.Add(0); mprintf("\n Observing voronoi cells of %d molecules.\n\n",m_waSurfCoverSM.GetSize()); g_iFixMol = (char)m_iSurfCoverMol; for (z=0;zm_waAtomCount.GetSize()-1;z2++) { // at = (CAtom*)g_oaAtoms[m->m_baAtomIndex[z2]]; for (z3=0;z3m_waAtomCount[z2];z3++) { try { fa = new CxDoubleArray("CVoroWrapper::Parse():fa"); } catch(...) { fa = NULL; } if (fa == NULL) NewException((double)sizeof(CxDoubleArray),__FILE__,__LINE__,__PRETTY_FUNCTION__); fa->SetGrow(1000); m_oaSurfCoverData.Add(fa); m_waSurfCoverMol.Add((unsigned short)z); m_waSurfCoverElem.Add((unsigned short)z2); m_waSurfCoverAtom.Add((unsigned short)z3); } } } } /***************************************************************************************************************************/ m_bWritePOV = false; /******************************************************************************************************************************/ m_bPOVBox = false; /***************************************************************************************************************************/ m_bVoroMetric = false; mprintf("\n"); mprintf(" Initializing Voronoi data structures...\n"); g_pVoroWrapper->Init(); mprintf("\n"); mprintf("*** Voro: Box density is %f particles / Angstrom^3.\n",m_fBoxDens); mprintf("*** Voro: Using %d x %d x %d blocks.\n",m_iBlocksX,m_iBlocksY,m_iBlocksZ); mprintf("*** Voro: Using cell memory for %d particles.\n",g_iVoroMemory); if (m_bVoroStat || m_bSurfCover || m_bWritePOV) { mprintf(WHITE,"*** Dumping Voronoi Infos to \"voro.txt\".\n"); try { t = new CTimeStep(); } catch(...) { t = NULL; } if (t == NULL) NewException((double)sizeof(CTimeStep),__FILE__,__LINE__,__PRETTY_FUNCTION__); t->CopyFrom(&g_TimeStep); m = (CMolecule*)g_oaMolecules[0]; sm = (CSingleMolecule*)g_oaSingleMolecules[m->m_laSingleMolIndex[0]]; t->CenterPos(t->m_vaCoords[((CxIntArray*)sm->m_oaAtomOffset[sm->m_baAtomIndex.GetSize()-1])->GetAt(1)]); t->CenterPos(CxDVector3(-g_fBoxX/2.0,-g_fBoxY/2.0,-g_fBoxZ/2.0)); t->FoldAtomsPositive(); g_pVoroWrapper->Dump("voro.txt",t); // g_pVoroWrapper->WritePOV(t,"voro.pov",0,0); delete t; g_pVoroWrapper->Init2(); } // AskYesNo(" This is hard-coded for Ulrikes Bmim-Br ^^ [accept] ",false); mprintf(WHITE,"\n<<< End of Voronoi Analysis <<<\n\n"); } void CVoroWrapper::Dump(const char *s, CTimeStep *ts) { int ijk, q, z, z2, ci, id; double *pp, cv; FILE *a; voronoicell_neighbor c; vector nb; vector fo; vector fa; CVoroAtom *va, *va2; CVoroMolecule *vm, *vm2; a = OpenFileWrite(s,true); mfprintf(a,"*** Voro: Box density is %f particles / Angstrom^3.\n",m_fBoxDens); mfprintf(a,"*** Voro: Using %d x %d x %d blocks.\n",m_iBlocksX,m_iBlocksY,m_iBlocksZ); // d0 = g_iGesAtomCount / g_fBoxX / g_fBoxY / g_fBoxZ * 1000000.0; // d = 2.35 / pow(d0,1/3.0); mfprintf(a,"*** Voro: Creating Container...\n"); fflush(a); // m_pContainer = new container_periodic_poly(1.0,0,1.0,0,0,1.0,m_iBlocksX,m_iBlocksY,m_iBlocksZ,g_iVoroMemory); try { m_pContainer = new container_periodic_poly(g_fBoxX/1000.0,0,g_fBoxY/1000.0,0,0,g_fBoxZ/1000.0,m_iBlocksX,m_iBlocksY,m_iBlocksZ,g_iVoroMemory); } catch(...) { m_pContainer = NULL; } if (m_pContainer == NULL) NewException((double)sizeof(container_periodic_poly),__FILE__,__LINE__,__PRETTY_FUNCTION__); mfprintf(a,"*** Voro: Adding %d particles...\n",g_iGesAtomCount); fflush(a); for (z=0;zput(z,ts->m_vaCoords[z][0]/1000.0,ts->m_vaCoords[z][1]/1000.0,ts->m_vaCoords[z][2]/1000.0,g_faVoronoiRadii[z]/1000.0); m_fMaxVol = 0; m_fMaxSurf = 0; c_loop_all_periodic vl(*m_pContainer); ci = 0; cv = 0; if (vl.start()) { do { if (m_pContainer->compute_cell(c,vl)) { ci++; ijk=vl.ijk; q=vl.q; pp=m_pContainer->p[ijk]+m_pContainer->ps*q; id = m_pContainer->id[ijk][q]; va = (CVoroAtom*)m_oaVoroAtoms[m_pAssignAtoms[id]]; vm = (CVoroMolecule*)m_oaVoroMolecules[m_pAssignMolecules[id]]; mfprintf(a,"Cell %5d (%s[%d] %s%d); p=(%.2f | %.2f | %.2f); r=%.2f pm; %d Faces; Vol=%.4f A^3, Surface=%.4f A^2; Max.Radius=%.3f pm\n",id,((CMolecule*)g_oaMolecules[va->m_iMolecule])->m_sName,vm->m_iSingleMol+1,(const char*)((CAtom*)g_oaAtoms[va->m_iRealAtomType])->m_sName,va->m_iAtom+1,pp[0]*1000.0,pp[1]*1000.0,pp[2]*1000.0,pp[3]*1000.0,c.number_of_faces(),c.volume()*1000.0,c.surface_area()*100.0,sqrt(c.max_radius_squared())*1000.0); if (c.volume()*1000.0 > m_fMaxVol) m_fMaxVol = c.volume()*1000.0; cv += c.volume()*1000.0; if (c.surface_area()*100.0 > m_fMaxSurf) m_fMaxSurf = c.surface_area()*100.0; c.face_areas(fa); c.face_orders(fo); c.neighbors(nb); for (z2=0;z2m_iMolecule])->m_sName,vm2->m_iSingleMol+1,(const char*)((CAtom*)g_oaAtoms[va2->m_iRealAtomType])->m_sName,va2->m_iAtom+1); } } } while (vl.inc()); } mprintf(" %d/%d Particles touched.\n",ci,g_iGesAtomCount); mprintf(" Volume %f/%f Angstrom^3.\n",cv,g_fBoxX*g_fBoxY*g_fBoxZ/1000000.0); m_fMaxVol *= 3.0; m_fMaxSurf *= 3.0; delete m_pContainer; mfprintf(a,"*** The End ***\n"); fclose(a); } void CVoroWrapper::Finish() { int z, z2; // char buf[256]; CxString buf; CVoroAtom *va; CVoroMolecule *vm, *vmbase; if (m_bPOVBox || m_bWritePOV) { if (m_bWritePOVMovie) { for (z=0;zWriteMathematicaNb("","vorometric.nb","",false); m_pVoroMetricCDF2->WriteMathematicaNb("","vorometric2.nb","",false); } } // if (m_bWritePOV) // fclose(m_fPOVScript); if (m_bSurfCover) { mprintf(WHITE,"*** Voronoi Surface Coverage\n\n"); mprintf(" Writing Surface data to voro_surfcover.csv\n"); FinishSurfCover("voro_surfcover.csv"); mprintf("\n"); } if (m_bVoroStat) { mprintf(WHITE,"*** Voronoi Functions\n\n"); if (g_iVoroPrintLevel >= 1) { mprintf(" Atom Information:\n"); for (z=0;zm_iMolecule])->m_sName,((CAtom*)g_oaAtoms[va->m_iRealAtomType])->m_sName,va->m_iAtom+1); buf.sprintf("voronoi/voro_atom_%s_%s%d",((CMolecule*)g_oaMolecules[va->m_iMolecule])->m_sName,(const char*)((CAtom*)g_oaAtoms[va->m_iRealAtomType])->m_sName,va->m_iAtom+1); mprintf(" - Writing %s ...\n",(const char*)buf); va->Dump(buf); } mprintf("\n Molecule Information:\n"); for (z=0;zm_iMolecule != z) continue; if (vmbase == NULL) { vmbase = vm; } else { vmbase->Add(vm); delete vm; m_oaVoroMolecules[z2] = NULL; } } // sprintf(buf,"voronoi/voro_molecule_%s",((CMolecule*)g_oaMolecules[vmbase->m_iMolecule])->m_sName); buf.sprintf("voronoi/voro_molecule_%s",((CMolecule*)g_oaMolecules[vmbase->m_iMolecule])->m_sName); mprintf(" - Writing %s ...\n",(const char*)buf); vmbase->Dump(buf); } mprintf("\n"); } mprintf(" Mean Atom Neighbor Count Matrix:\n"); mprintf(" Writing voro_atom_nbcount.csv ...\n"); WriteNbAtomCountMatrix("voro_atom_nbcount.csv"); mprintf("\n Mean Atom Neighbor Distance Matrix:\n"); mprintf(" Writing voro_atom_nbdist.csv ...\n"); WriteNbAtomDistMatrix("voro_atom_nbdist.csv"); mprintf("\n Mean Molecule Neighbor Count Matrix:\n"); mprintf(" Writing voro_molecule_nbcount.csv ...\n"); WriteNbMoleculeCountMatrix("voro_molecule_nbcount.csv"); mprintf("\n Mean Molecule Neighbor Distance Matrix:\n"); mprintf(" Writing voro_molecule_nbdist.csv ...\n"); WriteNbMoleculeDistMatrix("voro_molecule_nbdist.csv"); mprintf("\n Mean Molecule Neighbor Area Matrix:\n"); mprintf(" Writing voro_molecule_nbarea.csv ...\n"); WriteNbMoleculeAreaMatrix("voro_molecule_nbarea.csv"); mprintf("\n Atom information table:\n"); mprintf(" Writing voro_atoms.csv ...\n"); WriteAtomInfo("voro_atoms.csv"); mprintf("\n Molecule information table:\n"); mprintf(" Writing voro_molecules.csv ...\n"); WriteMoleculeInfo("voro_molecules.csv"); mprintf("\n"); if (m_bVoroTimeSeries) { fclose(m_fTSVolume); fclose(m_fTSSurface); fclose(m_fTSFaces); fclose(m_fTSAVRatio); fclose(m_fTSMaxRadius); mprintf(" Wrote time series to the following files:\n"); mprintf(" Cell volume to \"voronoi/timeseries_volume.csv\" (unit: Angstrom^3)\n"); mprintf(" Cell surface area to \"voronoi/timeseries_surface.csv\" (unit: Angstrom^2)\n"); mprintf(" Cell face count to \"voronoi/timeseries_faces.csv\"\n"); mprintf(" Cell A/V ratio to \"voronoi/timeseries_avratio.csv\" (1 = spherical)\n"); mprintf(" Cell max. radius to \"voronoi/timeseries_maxradius.csv\" (unit: Angstrom)\n"); mprintf("\n"); } } } CVoroAtom::CVoroAtom() { } CVoroAtom::~CVoroAtom() { } void CVoroAtom::InitAnalyses() { int z; try { m_pSurfaceArea = new CDF(); } catch(...) { m_pSurfaceArea = NULL; } if (m_pSurfaceArea == NULL) NewException((double)sizeof(CDF),__FILE__,__LINE__,__PRETTY_FUNCTION__); m_pSurfaceArea->m_fMinVal = 0; m_pSurfaceArea->m_fMaxVal = m_pParent->m_fMaxSurf; m_pSurfaceArea->m_iResolution = 10000; m_pSurfaceArea->SetLabelX("Surface Area [A^2]"); m_pSurfaceArea->SetLabelY("Occurrence"); m_pSurfaceArea->Create(); try { m_pExposedSurface = new CDF(); } catch(...) { m_pExposedSurface = NULL; } if (m_pExposedSurface == NULL) NewException((double)sizeof(CDF),__FILE__,__LINE__,__PRETTY_FUNCTION__); m_pExposedSurface->m_fMinVal = 0; m_pExposedSurface->m_fMaxVal = m_pParent->m_fMaxSurf; m_pExposedSurface->m_iResolution = 10000; m_pExposedSurface->SetLabelX("Exposed Surface Area [A^2]"); m_pExposedSurface->SetLabelY("Occurrence"); m_pExposedSurface->Create(); try { m_pExposedSurfacePerc = new CDF(); } catch(...) { m_pExposedSurfacePerc = NULL; } if (m_pExposedSurfacePerc == NULL) NewException((double)sizeof(CDF),__FILE__,__LINE__,__PRETTY_FUNCTION__); m_pExposedSurfacePerc->m_fMinVal = 0; m_pExposedSurfacePerc->m_fMaxVal = 100.0; m_pExposedSurfacePerc->m_iResolution = 10000; m_pExposedSurfacePerc->SetLabelX("Exposed Surface Percentage"); m_pExposedSurfacePerc->SetLabelY("Occurrence"); m_pExposedSurfacePerc->Create(); try { m_pVolume = new CDF(); } catch(...) { m_pVolume = NULL; } if (m_pVolume == NULL) NewException((double)sizeof(CDF),__FILE__,__LINE__,__PRETTY_FUNCTION__); m_pVolume->m_fMinVal = 0; m_pVolume->m_fMaxVal = m_pParent->m_fMaxVol; m_pVolume->m_iResolution = 10000; m_pVolume->SetLabelX("Volume [A^3]"); m_pVolume->SetLabelY("Occurrence"); m_pVolume->Create(); try { m_pMaxRadius = new CDF(); } catch(...) { m_pMaxRadius = NULL; } if (m_pMaxRadius == NULL) NewException((double)sizeof(CDF),__FILE__,__LINE__,__PRETTY_FUNCTION__); m_pMaxRadius->m_fMinVal = 0; m_pMaxRadius->m_fMaxVal = g_fBoxX/4.0; m_pMaxRadius->m_iResolution = int(g_fBoxX*0.2); m_pMaxRadius->SetLabelX("Max. Radius [pm]"); m_pMaxRadius->SetLabelY("Occurrence"); m_pMaxRadius->Create(); try { m_pAVRatio = new CDF(); } catch(...) { m_pAVRatio = NULL; } if (m_pAVRatio == NULL) NewException((double)sizeof(CDF),__FILE__,__LINE__,__PRETTY_FUNCTION__); m_pAVRatio->m_fMinVal = 0; m_pAVRatio->m_fMaxVal = 1.0; m_pAVRatio->m_iResolution = 1000; m_pAVRatio->SetLabelX("A/V Ratio"); m_pAVRatio->SetLabelY("Occurrence"); m_pAVRatio->Create(); try { m_pFaces = new CDF(); } catch(...) { m_pFaces = NULL; } if (m_pFaces == NULL) NewException((double)sizeof(CDF),__FILE__,__LINE__,__PRETTY_FUNCTION__); m_pFaces->m_fMinVal = 0; m_pFaces->m_fMaxVal = 100; m_pFaces->m_iResolution = 101; m_pFaces->SetLabelX("Face Count"); m_pFaces->SetLabelY("Occurrence"); m_pFaces->Create(); try { m_pFaceOrders = new CDF(); } catch(...) { m_pFaceOrders = NULL; } if (m_pFaceOrders == NULL) NewException((double)sizeof(CDF),__FILE__,__LINE__,__PRETTY_FUNCTION__); m_pFaceOrders->m_fMinVal = 0; m_pFaceOrders->m_fMaxVal = 50; m_pFaceOrders->m_iResolution = 51; m_pFaceOrders->SetLabelX("Face Order"); m_pFaceOrders->SetLabelY("Occurrence"); m_pFaceOrders->Create(); try { m_pNbhAtoms = new CDF*[m_pParent->m_oaVoroAtoms.GetSize()]; } catch(...) { m_pNbhAtoms = NULL; } if (m_pNbhAtoms == NULL) NewException((double)m_pParent->m_oaVoroAtoms.GetSize()*sizeof(CDF*),__FILE__,__LINE__,__PRETTY_FUNCTION__); for (z=0;zm_oaVoroAtoms.GetSize();z++) { try { m_pNbhAtoms[z] = new CDF(); } catch(...) { m_pNbhAtoms[z] = NULL; } if (m_pNbhAtoms[z] == NULL) NewException((double)sizeof(CDF),__FILE__,__LINE__,__PRETTY_FUNCTION__); m_pNbhAtoms[z]->m_fMinVal = 0; m_pNbhAtoms[z]->m_fMaxVal = 50; m_pNbhAtoms[z]->m_iResolution = 51; m_pNbhAtoms[z]->SetLabelX("Neighbor Count"); m_pNbhAtoms[z]->SetLabelY("Occurrence"); m_pNbhAtoms[z]->Create(); } try { m_pNbhDistAtoms = new CDF*[m_pParent->m_oaVoroAtoms.GetSize()]; } catch(...) { m_pNbhDistAtoms = NULL; } if (m_pNbhDistAtoms == NULL) NewException((double)m_pParent->m_oaVoroAtoms.GetSize()*sizeof(CDF*),__FILE__,__LINE__,__PRETTY_FUNCTION__); for (z=0;zm_oaVoroAtoms.GetSize();z++) { try { m_pNbhDistAtoms[z] = new CDF(); } catch(...) { m_pNbhDistAtoms[z] = NULL; } if (m_pNbhDistAtoms[z] == NULL) NewException((double)sizeof(CDF),__FILE__,__LINE__,__PRETTY_FUNCTION__); m_pNbhDistAtoms[z]->m_fMinVal = 0; m_pNbhDistAtoms[z]->m_fMaxVal = g_fBoxX*2.0; m_pNbhDistAtoms[z]->m_iResolution = int(g_fBoxX*0.5); m_pNbhDistAtoms[z]->SetLabelX("Neighbor Distance [pm]"); m_pNbhDistAtoms[z]->SetLabelY("Occurrence"); m_pNbhDistAtoms[z]->Create(); } try { m_pNbhDistMolecules = new CDF*[g_oaMolecules.GetSize()]; } catch(...) { m_pNbhDistMolecules = NULL; } if (m_pNbhDistMolecules == NULL) NewException((double)g_oaMolecules.GetSize()*sizeof(CDF*),__FILE__,__LINE__,__PRETTY_FUNCTION__); for (z=0;zm_fMinVal = 0; m_pNbhDistMolecules[z]->m_fMaxVal = g_fBoxX*2.0; m_pNbhDistMolecules[z]->m_iResolution = int(g_fBoxX*0.5); m_pNbhDistMolecules[z]->SetLabelX("Neighbor Distance [pm]"); m_pNbhDistMolecules[z]->SetLabelY("Occurrence"); m_pNbhDistMolecules[z]->Create(); } try { m_pNbhMolecules = new CDF*[g_oaMolecules.GetSize()]; } catch(...) { m_pNbhMolecules = NULL; } if (m_pNbhMolecules == NULL) NewException((double)g_oaMolecules.GetSize()*sizeof(CDF*),__FILE__,__LINE__,__PRETTY_FUNCTION__); for (z=0;zm_fMinVal = 0; m_pNbhMolecules[z]->m_fMaxVal = 50; m_pNbhMolecules[z]->m_iResolution = 51; m_pNbhMolecules[z]->SetLabelX("Neighbor Count"); m_pNbhMolecules[z]->SetLabelY("Occurrence"); m_pNbhMolecules[z]->Create(); } } CVoroMolecule::CVoroMolecule() { } CVoroMolecule::~CVoroMolecule() { } void CVoroMolecule::InitAnalyses() { int z; try { m_pSurfaceArea = new CDF(); } catch(...) { m_pSurfaceArea = NULL; } if (m_pSurfaceArea == NULL) NewException((double)sizeof(CDF),__FILE__,__LINE__,__PRETTY_FUNCTION__); m_pSurfaceArea->m_fMinVal = 0; m_pSurfaceArea->m_fMaxVal = m_pParent->m_fMaxSurf*((CMolecule*)g_oaMolecules[m_iMolecule])->m_iAtomGes; m_pSurfaceArea->m_iResolution = 1000; m_pSurfaceArea->SetLabelX("Surface Area [A^2]"); m_pSurfaceArea->SetLabelY("Occurrence"); m_pSurfaceArea->Create(); try { m_pVolume = new CDF(); } catch(...) { m_pVolume = NULL; } if (m_pVolume == NULL) NewException((double)sizeof(CDF),__FILE__,__LINE__,__PRETTY_FUNCTION__); m_pVolume->m_fMinVal = 0; m_pVolume->m_fMaxVal = m_pParent->m_fMaxVol*((CMolecule*)g_oaMolecules[m_iMolecule])->m_iAtomGes; m_pVolume->m_iResolution = 1000; m_pVolume->SetLabelX("Volume [A^3]"); m_pVolume->SetLabelY("Occurrence"); m_pVolume->Create(); try { m_pAVRatio = new CDF(); } catch(...) { m_pAVRatio = NULL; } if (m_pAVRatio == NULL) NewException((double)sizeof(CDF),__FILE__,__LINE__,__PRETTY_FUNCTION__); m_pAVRatio->m_fMinVal = 0; m_pAVRatio->m_fMaxVal = 1.0; m_pAVRatio->m_iResolution = 1000; m_pAVRatio->SetLabelX("A/V Ratio"); m_pAVRatio->SetLabelY("Occurrence"); m_pAVRatio->Create(); try { m_pFaces = new CDF(); } catch(...) { m_pFaces = NULL; } if (m_pFaces == NULL) NewException((double)sizeof(CDF),__FILE__,__LINE__,__PRETTY_FUNCTION__); m_pFaces->m_fMinVal = 0; m_pFaces->m_fMaxVal = 100*((CMolecule*)g_oaMolecules[m_iMolecule])->m_iAtomGes; m_pFaces->m_iResolution = int(100*((CMolecule*)g_oaMolecules[m_iMolecule])->m_iAtomGes)+1; m_pFaces->SetLabelX("Face count"); m_pFaces->SetLabelY("Occurrence"); m_pFaces->Create(); try { m_pNbhAtoms = new CDF*[m_pParent->m_oaVoroAtoms.GetSize()]; } catch(...) { m_pNbhAtoms = NULL; } if (m_pNbhAtoms == NULL) NewException((double)m_pParent->m_oaVoroAtoms.GetSize()*sizeof(CDF*),__FILE__,__LINE__,__PRETTY_FUNCTION__); for (z=0;zm_oaVoroAtoms.GetSize();z++) { try { m_pNbhAtoms[z] = new CDF(); } catch(...) { m_pNbhAtoms[z] = NULL; } if (m_pNbhAtoms[z] == NULL) NewException((double)sizeof(CDF),__FILE__,__LINE__,__PRETTY_FUNCTION__); m_pNbhAtoms[z]->m_fMinVal = 0; m_pNbhAtoms[z]->m_fMaxVal = 50; m_pNbhAtoms[z]->m_iResolution = 51; m_pNbhAtoms[z]->SetLabelX("Neighbor count"); m_pNbhAtoms[z]->SetLabelY("Occurrence"); m_pNbhAtoms[z]->Create(); } try { m_pNbhDistAtoms = new CDF*[m_pParent->m_oaVoroAtoms.GetSize()]; } catch(...) { m_pNbhDistAtoms = NULL; } if (m_pNbhDistAtoms == NULL) NewException((double)m_pParent->m_oaVoroAtoms.GetSize()*sizeof(CDF*),__FILE__,__LINE__,__PRETTY_FUNCTION__); for (z=0;zm_oaVoroAtoms.GetSize();z++) { try { m_pNbhDistAtoms[z] = new CDF(); } catch(...) { m_pNbhDistAtoms[z] = NULL; } if (m_pNbhDistAtoms[z] == NULL) NewException((double)sizeof(CDF),__FILE__,__LINE__,__PRETTY_FUNCTION__); m_pNbhDistAtoms[z]->m_fMinVal = 0; m_pNbhDistAtoms[z]->m_fMaxVal = g_fBoxX*2.0; m_pNbhDistAtoms[z]->m_iResolution = int(g_fBoxX*0.5); m_pNbhDistAtoms[z]->SetLabelX("Neighbor distance [pm]"); m_pNbhDistAtoms[z]->SetLabelY("Occurrence"); m_pNbhDistAtoms[z]->Create(); } try { m_pNbhDistMolecules = new CDF*[g_oaMolecules.GetSize()]; } catch(...) { m_pNbhDistMolecules = NULL; } if (m_pNbhDistMolecules == NULL) NewException((double)g_oaMolecules.GetSize()*sizeof(CDF*),__FILE__,__LINE__,__PRETTY_FUNCTION__); for (z=0;zm_fMinVal = 0; m_pNbhDistMolecules[z]->m_fMaxVal = g_fBoxX*2.0; m_pNbhDistMolecules[z]->m_iResolution = int(g_fBoxX*0.5); m_pNbhDistMolecules[z]->SetLabelX("Neighbor distance [pm]"); m_pNbhDistMolecules[z]->SetLabelY("Occurrence"); m_pNbhDistMolecules[z]->Create(); } try { m_pNbhAreaMolecules = new CDF*[g_oaMolecules.GetSize()]; } catch(...) { m_pNbhAreaMolecules = NULL; } if (m_pNbhAreaMolecules == NULL) NewException((double)g_oaMolecules.GetSize()*sizeof(CDF*),__FILE__,__LINE__,__PRETTY_FUNCTION__); for (z=0;zm_fMinVal = 0; m_pNbhAreaMolecules[z]->m_fMaxVal = g_fBoxX*g_fBoxX / 10000.0; m_pNbhAreaMolecules[z]->m_iResolution = int(g_fBoxX*g_fBoxX*0.25 / 10000.0); m_pNbhAreaMolecules[z]->SetLabelX("Neighbor area [A^2]"); m_pNbhAreaMolecules[z]->SetLabelY("Occurrence"); m_pNbhAreaMolecules[z]->Create(); } try { m_pNbhMolecules = new CDF*[g_oaMolecules.GetSize()]; } catch(...) { m_pNbhMolecules = NULL; } if (m_pNbhMolecules == NULL) NewException((double)g_oaMolecules.GetSize()*sizeof(CDF*),__FILE__,__LINE__,__PRETTY_FUNCTION__); for (z=0;zm_fMinVal = 0; m_pNbhMolecules[z]->m_fMaxVal = 50; m_pNbhMolecules[z]->m_iResolution = 51; m_pNbhMolecules[z]->SetLabelX("Neighbor count"); m_pNbhMolecules[z]->SetLabelY("Occurrence"); m_pNbhMolecules[z]->Create(); } } void CVoroAtom::Dump(const char *s) { FILE *a; // char buf[256]; CxString buf; int z, z2; // sprintf(buf,"%s.txt",s); buf.sprintf("%s.txt",s); a = OpenFileWrite(buf,true); mfprintf(a,"*** Voronoi Analysis for %s %s%d ***\n\n",((CMolecule*)g_oaMolecules[m_iMolecule])->m_sName,(const char*)((CAtom*)g_oaAtoms[m_iRealAtomType])->m_sName,m_iAtom+1); m_pVolume->CalcMeanSD(); mfprintf(a," * Volume:\n"); mfprintf(a," Avg. %10G Angstrom^3\n",m_pVolume->m_fMean); mfprintf(a," Min. %10G Angstrom^3\n",m_pVolume->m_fMinInput); mfprintf(a," Max. %10G Angstrom^3\n",m_pVolume->m_fMaxInput); mfprintf(a," SD %10G Angstrom^3\n",m_pVolume->m_fSD); if (g_iVoroPrintLevel >= 2) { mfprintf(a," Saving Histogram as %s_volume.csv.\n",s); mfprintf(a," (%.0f bin entries, %.0f skipped)\n\n",m_pVolume->m_fBinEntries,m_pVolume->m_fSkipEntries); m_pVolume->NormBinSum(100.0); m_pVolume->Write("",s,"_volume.csv",true); } m_pSurfaceArea->CalcMeanSD(); mfprintf(a," * Surface Area:\n"); mfprintf(a," Avg. %10G Angstrom^2\n",m_pSurfaceArea->m_fMean); mfprintf(a," Min. %10G Angstrom^2\n",m_pSurfaceArea->m_fMinInput); mfprintf(a," Max. %10G Angstrom^2\n",m_pSurfaceArea->m_fMaxInput); mfprintf(a," SD %10G Angstrom^2\n",m_pSurfaceArea->m_fSD); if (g_iVoroPrintLevel >= 2) { mfprintf(a," Saving Histogram as %s_surface.csv.\n",s); mfprintf(a," (%.0f bin entries, %.0f skipped)\n\n",m_pSurfaceArea->m_fBinEntries,m_pSurfaceArea->m_fSkipEntries); m_pSurfaceArea->NormBinSum(100.0); m_pSurfaceArea->Write("",s,"_surface.csv",true); } m_pExposedSurface->CalcMeanSD(); mfprintf(a," * Exposed Surface Area:\n"); mfprintf(a," Avg. %10G Angstrom^2\n",m_pExposedSurface->m_fMean); mfprintf(a," Min. %10G Angstrom^2\n",m_pExposedSurface->m_fMinInput); mfprintf(a," Max. %10G Angstrom^2\n",m_pExposedSurface->m_fMaxInput); mfprintf(a," SD %10G Angstrom^2\n",m_pExposedSurface->m_fSD); if (g_iVoroPrintLevel >= 2) { mfprintf(a," Saving Histogram as %s_exposed_surface.csv.\n",s); mfprintf(a," (%.0f bin entries, %.0f skipped)\n\n",m_pExposedSurface->m_fBinEntries,m_pExposedSurface->m_fSkipEntries); m_pExposedSurface->NormBinSum(100.0); m_pExposedSurface->Write("",s,"_exposed_surface.csv",true); } m_pExposedSurfacePerc->CalcMeanSD(); mfprintf(a," * Exposed Surface Area Percentage:\n"); mfprintf(a," Avg. %10G percent\n",m_pExposedSurfacePerc->m_fMean); mfprintf(a," Min. %10G percent\n",m_pExposedSurfacePerc->m_fMinInput); mfprintf(a," Max. %10G percent\n",m_pExposedSurfacePerc->m_fMaxInput); mfprintf(a," SD %10G percent\n",m_pExposedSurfacePerc->m_fSD); if (g_iVoroPrintLevel >= 2) { mfprintf(a," Saving Histogram as %s_exposed_surface_perc.csv.\n",s); mfprintf(a," (%.0f bin entries, %.0f skipped)\n\n",m_pExposedSurfacePerc->m_fBinEntries,m_pExposedSurfacePerc->m_fSkipEntries); m_pExposedSurfacePerc->NormBinSum(100.0); m_pExposedSurfacePerc->Write("",s,"_exposed_surface_perc.csv",true); } m_pMaxRadius->CalcMeanSD(); mfprintf(a," * Maximum Radius:\n"); mfprintf(a," Avg. %.4f pm\n",m_pMaxRadius->m_fMean); mfprintf(a," Min. %.4f pm\n",m_pMaxRadius->m_fMinInput); mfprintf(a," Max. %.4f pm\n",m_pMaxRadius->m_fMaxInput); mfprintf(a," SD %.4f pm\n\n",m_pMaxRadius->m_fSD); if (g_iVoroPrintLevel >= 2) { mfprintf(a," Saving Histogram as %s_maxradius.csv.\n",s); mfprintf(a," (%.0f bin entries, %.0f skipped)\n\n",m_pMaxRadius->m_fBinEntries,m_pMaxRadius->m_fSkipEntries); m_pMaxRadius->NormBinSum(100.0); m_pMaxRadius->Write("",s,"_maxradius.csv",true); } m_pFaceOrders->CalcMeanSD(); mfprintf(a," * Face Orders:\n"); mfprintf(a," Avg. %.6f Edges\n",m_pFaceOrders->m_fMean); mfprintf(a," Min. %.0f Edges\n",m_pFaceOrders->m_fMinInput); mfprintf(a," Max. %.0f Edges\n",m_pFaceOrders->m_fMaxInput); mfprintf(a," SD %.6f Edges\n\n",m_pFaceOrders->m_fSD); m_pFaceOrders->NormBinSum(100.0); for (z=0;zm_iResolution;z++) if (m_pFaceOrders->m_pBin[z] != 0) mfprintf(a," - %2d Edges: %10.6f percent\n",z,m_pFaceOrders->m_pBin[z]); if (g_iVoroPrintLevel >= 2) { mfprintf(a," Saving Histogram as %s_faceorders.csv.\n",s); mfprintf(a," (%.0f bin entries, %.0f skipped)\n\n",m_pFaceOrders->m_fBinEntries,m_pFaceOrders->m_fSkipEntries); m_pFaceOrders->Write_Int("",s,"_faceorders.csv"); } m_pFaces->CalcMeanSD(); mfprintf(a," * Faces:\n"); mfprintf(a," Avg. %.6f\n",m_pFaces->m_fMean); mfprintf(a," Min. %.0f\n",m_pFaces->m_fMinInput); mfprintf(a," Max. %.0f\n",m_pFaces->m_fMaxInput); mfprintf(a," SD %.6f\n\n",m_pFaces->m_fSD); m_pFaces->NormBinSum(100.0); for (z=0;zm_iResolution;z++) if (m_pFaces->m_pBin[z] != 0) mfprintf(a," - %2d Faces: %10.6f percent\n",z,m_pFaces->m_pBin[z]); if (g_iVoroPrintLevel >= 2) { mfprintf(a," Saving Histogram as %s_faces.csv.\n",s); mfprintf(a," (%.0f bin entries, %.0f skipped)\n\n",m_pFaces->m_fBinEntries,m_pFaces->m_fSkipEntries); m_pFaces->Write_Int("",s,"_faces.csv"); } m_pAVRatio->CalcMeanSD(); mfprintf(a," * A/V Ratio:\n"); mfprintf(a," Avg. %.6f\n",m_pAVRatio->m_fMean); mfprintf(a," Min. %.6f\n",m_pAVRatio->m_fMinInput); mfprintf(a," Max. %.6f\n",m_pAVRatio->m_fMaxInput); mfprintf(a," SD %.6f\n\n",m_pAVRatio->m_fSD); if (g_iVoroPrintLevel >= 2) { m_pAVRatio->NormBinSum(100.0); mfprintf(a," Saving Histogram as %s_avratio.csv.\n",s); mfprintf(a," (%.0f bin entries, %.0f skipped)\n\n",m_pAVRatio->m_fBinEntries,m_pAVRatio->m_fSkipEntries); m_pAVRatio->Write("",s,"_avratio.csv",false); } mfprintf(a,"\n\n###### Neighboring Molecules ######\n\n"); for (z=0;zCalcMeanSD(); mfprintf(a," * Neighboring %s molecules:\n",((CMolecule*)g_oaMolecules[z])->m_sName); mfprintf(a," Avg. %.6f\n",m_pNbhMolecules[z]->m_fMean); mfprintf(a," Min. %.0f\n",m_pNbhMolecules[z]->m_fMinInput); mfprintf(a," Max. %.0f\n",m_pNbhMolecules[z]->m_fMaxInput); mfprintf(a," SD %.6f\n",m_pNbhMolecules[z]->m_fSD); m_pNbhMolecules[z]->NormBinSum(100.0); for (z2=0;z2m_iResolution;z2++) if (m_pNbhMolecules[z]->m_pBin[z2] != 0) mfprintf(a," - %2d Molecules: %10.6f percent\n",z2,m_pNbhMolecules[z]->m_pBin[z2]); if (g_iVoroPrintLevel >= 3) { // sprintf(buf,"_nbcount_mol_%s.csv",((CMolecule*)g_oaMolecules[z])->m_sName); buf.sprintf("_nbcount_mol_%s.csv",((CMolecule*)g_oaMolecules[z])->m_sName); mfprintf(a," Saving Histogram as %s%s.\n",s,(const char*)buf); mfprintf(a," (%.0f bin entries, %.0f skipped)\n\n",m_pNbhMolecules[z]->m_fBinEntries,m_pNbhMolecules[z]->m_fSkipEntries); m_pNbhMolecules[z]->Write_Int("",s,buf); } } mfprintf(a,"\n\n###### Neighboring Molecule Distances ######\n\n"); for (z=0;zCalcMeanSD(); mfprintf(a," * Neighboring %s molecule distances:\n",((CMolecule*)g_oaMolecules[z])->m_sName); mfprintf(a," Avg. %.4f pm\n",m_pNbhDistMolecules[z]->m_fMean); mfprintf(a," Min. %.4f pm\n",m_pNbhDistMolecules[z]->m_fMinInput); mfprintf(a," Max. %.4f pm\n",m_pNbhDistMolecules[z]->m_fMaxInput); mfprintf(a," SD %.4f pm\n",m_pNbhDistMolecules[z]->m_fSD); if (g_iVoroPrintLevel >= 3) { m_pNbhDistMolecules[z]->NormBinSum(100.0); // sprintf(buf,"_nbdist_mol_%s.csv",((CMolecule*)g_oaMolecules[z])->m_sName); buf.sprintf("_nbdist_mol_%s.csv",((CMolecule*)g_oaMolecules[z])->m_sName); mfprintf(a," Saving Histogram as %s%s.\n",s,(const char*)buf); mfprintf(a," (%.0f bin entries, %.0f skipped)\n\n",m_pNbhDistMolecules[z]->m_fBinEntries,m_pNbhDistMolecules[z]->m_fSkipEntries); m_pNbhDistMolecules[z]->Write("",s,buf,true); } } mfprintf(a,"\n\n###### Neighboring Atoms ######\n\n"); for (z=0;zm_oaVoroAtoms.GetSize();z++) { // sprintf(buf,"%s %s%d",((CMolecule*)g_oaMolecules[((CVoroAtom*)m_pParent->m_oaVoroAtoms[z])->m_iMolecule])->m_sName,((CAtom*)g_oaAtoms[((CVoroAtom*)m_pParent->m_oaVoroAtoms[z])->m_iRealAtomType])->m_sName,((CVoroAtom*)m_pParent->m_oaVoroAtoms[z])->m_iAtom+1); buf.sprintf("%s %s%d",((CMolecule*)g_oaMolecules[((CVoroAtom*)m_pParent->m_oaVoroAtoms[z])->m_iMolecule])->m_sName,(const char*)((CAtom*)g_oaAtoms[((CVoroAtom*)m_pParent->m_oaVoroAtoms[z])->m_iRealAtomType])->m_sName,((CVoroAtom*)m_pParent->m_oaVoroAtoms[z])->m_iAtom+1); m_pNbhAtoms[z]->CalcMeanSD(); mfprintf(a," * Neighboring %s atoms:\n",(const char*)buf); mfprintf(a," Avg. %.6f\n",m_pNbhAtoms[z]->m_fMean); mfprintf(a," Min. %.0f\n",m_pNbhAtoms[z]->m_fMinInput); mfprintf(a," Max. %.0f\n",m_pNbhAtoms[z]->m_fMaxInput); mfprintf(a," SD %.6f\n",m_pNbhAtoms[z]->m_fSD); m_pNbhAtoms[z]->NormBinSum(100.0); for (z2=0;z2m_iResolution;z2++) if (m_pNbhAtoms[z]->m_pBin[z2] != 0) mfprintf(a," - %2d Atoms: %10.6f percent\n",z2,m_pNbhAtoms[z]->m_pBin[z2]); if (g_iVoroPrintLevel >= 3) { // sprintf(buf,"_nbcount_atom_%s_%s%d.csv",((CMolecule*)g_oaMolecules[((CVoroAtom*)m_pParent->m_oaVoroAtoms[z])->m_iMolecule])->m_sName,((CAtom*)g_oaAtoms[((CVoroAtom*)m_pParent->m_oaVoroAtoms[z])->m_iRealAtomType])->m_sName,((CVoroAtom*)m_pParent->m_oaVoroAtoms[z])->m_iAtom+1); buf.sprintf("_nbcount_atom_%s_%s%d.csv",((CMolecule*)g_oaMolecules[((CVoroAtom*)m_pParent->m_oaVoroAtoms[z])->m_iMolecule])->m_sName,(const char*)((CAtom*)g_oaAtoms[((CVoroAtom*)m_pParent->m_oaVoroAtoms[z])->m_iRealAtomType])->m_sName,((CVoroAtom*)m_pParent->m_oaVoroAtoms[z])->m_iAtom+1); mfprintf(a," Saving Histogram as %s%s.\n",s,(const char*)buf); mfprintf(a," (%.0f bin entries, %.0f skipped)\n\n",m_pNbhAtoms[z]->m_fBinEntries,m_pNbhAtoms[z]->m_fSkipEntries); m_pNbhAtoms[z]->Write_Int("",s,buf); } } mfprintf(a,"\n\n###### Neighboring Atom Distances ######\n\n"); for (z=0;zm_oaVoroAtoms.GetSize();z++) { // sprintf(buf,"%s %s%d",((CMolecule*)g_oaMolecules[((CVoroAtom*)m_pParent->m_oaVoroAtoms[z])->m_iMolecule])->m_sName,((CAtom*)g_oaAtoms[((CVoroAtom*)m_pParent->m_oaVoroAtoms[z])->m_iRealAtomType])->m_sName,((CVoroAtom*)m_pParent->m_oaVoroAtoms[z])->m_iAtom+1); buf.sprintf("%s %s%d",((CMolecule*)g_oaMolecules[((CVoroAtom*)m_pParent->m_oaVoroAtoms[z])->m_iMolecule])->m_sName,(const char*)((CAtom*)g_oaAtoms[((CVoroAtom*)m_pParent->m_oaVoroAtoms[z])->m_iRealAtomType])->m_sName,((CVoroAtom*)m_pParent->m_oaVoroAtoms[z])->m_iAtom+1); m_pNbhDistAtoms[z]->CalcMeanSD(); mfprintf(a," * Neighboring %s atom distances:\n",(const char*)buf); mfprintf(a," Avg. %.4f pm\n",m_pNbhDistAtoms[z]->m_fMean); mfprintf(a," Min. %.4f pm\n",m_pNbhDistAtoms[z]->m_fMinInput); mfprintf(a," Max. %.4f pm\n",m_pNbhDistAtoms[z]->m_fMaxInput); mfprintf(a," SD %.4f pm\n",m_pNbhDistAtoms[z]->m_fSD); if (g_iVoroPrintLevel >= 3) { m_pNbhDistAtoms[z]->NormBinSum(100.0); // sprintf(buf,"_nbdist_atom_%s_%s%d.csv",((CMolecule*)g_oaMolecules[((CVoroAtom*)m_pParent->m_oaVoroAtoms[z])->m_iMolecule])->m_sName,((CAtom*)g_oaAtoms[((CVoroAtom*)m_pParent->m_oaVoroAtoms[z])->m_iRealAtomType])->m_sName,((CVoroAtom*)m_pParent->m_oaVoroAtoms[z])->m_iAtom+1); buf.sprintf("_nbdist_atom_%s_%s%d.csv",((CMolecule*)g_oaMolecules[((CVoroAtom*)m_pParent->m_oaVoroAtoms[z])->m_iMolecule])->m_sName,(const char*)((CAtom*)g_oaAtoms[((CVoroAtom*)m_pParent->m_oaVoroAtoms[z])->m_iRealAtomType])->m_sName,((CVoroAtom*)m_pParent->m_oaVoroAtoms[z])->m_iAtom+1); mfprintf(a," Saving Histogram as %s%s.\n",s,(const char*)buf); mfprintf(a," (%.0f bin entries, %.0f skipped)\n\n",m_pNbhDistAtoms[z]->m_fBinEntries,m_pNbhDistAtoms[z]->m_fSkipEntries); m_pNbhDistAtoms[z]->Write("",s,buf,true); } } fclose(a); } void CVoroMolecule::Dump(const char *s) { FILE *a; // char buf[256]; CxString buf; int z, z2; // sprintf(buf,"%s.txt",s); buf.sprintf("%s.txt",s); a = OpenFileWrite(buf,true); mfprintf(a,"*** Voronoi Analysis for Molecule %s ***\n\n",((CMolecule*)g_oaMolecules[m_iMolecule])->m_sName); m_pVolume->CalcMeanSD(); mfprintf(a," * Volume:\n"); mfprintf(a," Avg. %10G Angstrom^3\n",m_pVolume->m_fMean); mfprintf(a," Min. %10G Angstrom^3\n",m_pVolume->m_fMinInput); mfprintf(a," Max. %10G Angstrom^3\n",m_pVolume->m_fMaxInput); mfprintf(a," SD %10G Angstrom^3\n",m_pVolume->m_fSD); if (g_iVoroPrintLevel >= 2) { mfprintf(a," Saving Histogram as %s_volume.csv.\n",s); mfprintf(a," (%.0f bin entries, %.0f skipped)\n\n",m_pVolume->m_fBinEntries,m_pVolume->m_fSkipEntries); m_pVolume->NormBinSum(100.0); m_pVolume->Write("",s,"_volume.csv",true); } m_pSurfaceArea->CalcMeanSD(); mfprintf(a," * Surface Area:\n"); mfprintf(a," Avg. %10G Angstrom^2\n",m_pSurfaceArea->m_fMean); mfprintf(a," Min. %10G Angstrom^2\n",m_pSurfaceArea->m_fMinInput); mfprintf(a," Max. %10G Angstrom^2\n",m_pSurfaceArea->m_fMaxInput); mfprintf(a," SD %10G Angstrom^2\n",m_pSurfaceArea->m_fSD); if (g_iVoroPrintLevel >= 2) { mfprintf(a," Saving Histogram as %s_surface.csv.\n",s); mfprintf(a," (%.0f bin entries, %.0f skipped)\n\n",m_pSurfaceArea->m_fBinEntries,m_pSurfaceArea->m_fSkipEntries); m_pSurfaceArea->NormBinSum(100.0); m_pSurfaceArea->Write("",s,"_surface.csv",true); } m_pAVRatio->CalcMeanSD(); mfprintf(a," * A/V Ratio:\n"); mfprintf(a," Avg. %10G Angstrom^2\n",m_pAVRatio->m_fMean); mfprintf(a," Min. %10G Angstrom^2\n",m_pAVRatio->m_fMinInput); mfprintf(a," Max. %10G Angstrom^2\n",m_pAVRatio->m_fMaxInput); mfprintf(a," SD %10G Angstrom^2\n",m_pAVRatio->m_fSD); if (g_iVoroPrintLevel >= 2) { mfprintf(a," Saving Histogram as %s_avratio.csv.\n",s); mfprintf(a," (%.0f bin entries, %.0f skipped)\n\n",m_pAVRatio->m_fBinEntries,m_pAVRatio->m_fSkipEntries); m_pAVRatio->NormBinSum(100.0); m_pAVRatio->Write("",s,"_avratio.csv",true); } m_pFaces->CalcMeanSD(); mfprintf(a," * Faces:\n"); mfprintf(a," Avg. %.6f\n",m_pFaces->m_fMean); mfprintf(a," Min. %.0f\n",m_pFaces->m_fMinInput); mfprintf(a," Max. %.0f\n",m_pFaces->m_fMaxInput); mfprintf(a," SD %.6f\n\n",m_pFaces->m_fSD); m_pFaces->NormBinSum(100.0); for (z=0;zm_iResolution;z++) if (m_pFaces->m_pBin[z] != 0) mfprintf(a," - %2d Faces: %10.6f percent\n",z,m_pFaces->m_pBin[z]); if (g_iVoroPrintLevel >= 2) { mfprintf(a," Saving Histogram as %s_faces.csv.\n",s); mfprintf(a," (%.0f bin entries, %.0f skipped)\n\n",m_pFaces->m_fBinEntries,m_pFaces->m_fSkipEntries); m_pFaces->Write_Int("",s,"_faces.csv"); } mfprintf(a,"\n\n###### Neighboring Molecules ######\n\n"); for (z=0;zCalcMeanSD(); mfprintf(a," * Neighboring %s molecules:\n",((CMolecule*)g_oaMolecules[z])->m_sName); mfprintf(a," Avg. %.6f\n",m_pNbhMolecules[z]->m_fMean); mfprintf(a," Min. %.0f\n",m_pNbhMolecules[z]->m_fMinInput); mfprintf(a," Max. %.0f\n",m_pNbhMolecules[z]->m_fMaxInput); mfprintf(a," SD %.6f\n",m_pNbhMolecules[z]->m_fSD); m_pNbhMolecules[z]->NormBinSum(100.0); for (z2=0;z2m_iResolution;z2++) if (m_pNbhMolecules[z]->m_pBin[z2] != 0) mfprintf(a," - %2d Molecules: %10.6f percent\n",z2,m_pNbhMolecules[z]->m_pBin[z2]); // sprintf(buf,"_nbcount_mol_%s.csv",((CMolecule*)g_oaMolecules[z])->m_sName); if (g_iVoroPrintLevel >= 3) { buf.sprintf("_nbcount_mol_%s.csv",((CMolecule*)g_oaMolecules[z])->m_sName); mfprintf(a," Saving Histogram as %s%s.\n",s,(const char*)buf); mfprintf(a," (%.0f bin entries, %.0f skipped)\n\n",m_pNbhMolecules[z]->m_fBinEntries,m_pNbhMolecules[z]->m_fSkipEntries); m_pNbhMolecules[z]->Write_Int("",s,buf); } } mfprintf(a,"\n\n###### Neighboring Molecule Areas ######\n\n"); for (z=0;zCalcMeanSD(); mfprintf(a," * Neighboring %s molecule areas:\n",((CMolecule*)g_oaMolecules[z])->m_sName); mfprintf(a," Avg. %.4f\n",m_pNbhAreaMolecules[z]->m_fMean); mfprintf(a," Min. %.4f\n",m_pNbhAreaMolecules[z]->m_fMinInput); mfprintf(a," Max. %.4f\n",m_pNbhAreaMolecules[z]->m_fMaxInput); mfprintf(a," SD %.4f\n",m_pNbhAreaMolecules[z]->m_fSD); if (g_iVoroPrintLevel >= 3) { m_pNbhAreaMolecules[z]->NormBinSum(100.0); buf.sprintf("_nbarea_mol_%s.csv",((CMolecule*)g_oaMolecules[z])->m_sName); mfprintf(a," Saving Histogram as %s%s.\n",s,(const char*)buf); mfprintf(a," (%.0f bin entries, %.0f skipped)\n\n",m_pNbhAreaMolecules[z]->m_fBinEntries,m_pNbhAreaMolecules[z]->m_fSkipEntries); m_pNbhAreaMolecules[z]->Write("",s,buf,true); } } mfprintf(a,"\n\n###### Neighboring Molecule Distances ######\n\n"); for (z=0;zCalcMeanSD(); mfprintf(a," * Neighboring %s molecule distances:\n",((CMolecule*)g_oaMolecules[z])->m_sName); mfprintf(a," Avg. %.4f pm\n",m_pNbhDistMolecules[z]->m_fMean); mfprintf(a," Min. %.4f pm\n",m_pNbhDistMolecules[z]->m_fMinInput); mfprintf(a," Max. %.4f pm\n",m_pNbhDistMolecules[z]->m_fMaxInput); mfprintf(a," SD %.4f pm\n",m_pNbhDistMolecules[z]->m_fSD); if (g_iVoroPrintLevel >= 3) { m_pNbhDistMolecules[z]->NormBinSum(100.0); // sprintf(buf,"_nbdist_mol_%s.csv",((CMolecule*)g_oaMolecules[z])->m_sName); buf.sprintf("_nbdist_mol_%s.csv",((CMolecule*)g_oaMolecules[z])->m_sName); mfprintf(a," Saving Histogram as %s%s.\n",s,(const char*)buf); mfprintf(a," (%.0f bin entries, %.0f skipped)\n\n",m_pNbhDistMolecules[z]->m_fBinEntries,m_pNbhDistMolecules[z]->m_fSkipEntries); m_pNbhDistMolecules[z]->Write("",s,buf,true); } } mfprintf(a,"\n\n###### Neighboring Atoms ######\n\n"); for (z=0;zm_oaVoroAtoms.GetSize();z++) { // sprintf(buf,"%s %s%d",((CMolecule*)g_oaMolecules[((CVoroAtom*)m_pParent->m_oaVoroAtoms[z])->m_iMolecule])->m_sName,((CAtom*)g_oaAtoms[((CVoroAtom*)m_pParent->m_oaVoroAtoms[z])->m_iRealAtomType])->m_sName,((CVoroAtom*)m_pParent->m_oaVoroAtoms[z])->m_iAtom+1); buf.sprintf("%s %s%d",((CMolecule*)g_oaMolecules[((CVoroAtom*)m_pParent->m_oaVoroAtoms[z])->m_iMolecule])->m_sName,(const char*)((CAtom*)g_oaAtoms[((CVoroAtom*)m_pParent->m_oaVoroAtoms[z])->m_iRealAtomType])->m_sName,((CVoroAtom*)m_pParent->m_oaVoroAtoms[z])->m_iAtom+1); m_pNbhAtoms[z]->CalcMeanSD(); mfprintf(a," * Neighboring %s atoms:\n",(const char *)buf); mfprintf(a," Avg. %.6f\n",m_pNbhAtoms[z]->m_fMean); mfprintf(a," Min. %.0f\n",m_pNbhAtoms[z]->m_fMinInput); mfprintf(a," Max. %.0f\n",m_pNbhAtoms[z]->m_fMaxInput); mfprintf(a," SD %.6f\n",m_pNbhAtoms[z]->m_fSD); m_pNbhAtoms[z]->NormBinSum(100.0); for (z2=0;z2m_iResolution;z2++) if (m_pNbhAtoms[z]->m_pBin[z2] != 0) mfprintf(a," - %2d Atoms: %10.6f percent\n",z2,m_pNbhAtoms[z]->m_pBin[z2]); // sprintf(buf,"_nbcount_atom_%s_%s%d.csv",((CMolecule*)g_oaMolecules[((CVoroAtom*)m_pParent->m_oaVoroAtoms[z])->m_iMolecule])->m_sName,((CAtom*)g_oaAtoms[((CVoroAtom*)m_pParent->m_oaVoroAtoms[z])->m_iRealAtomType])->m_sName,((CVoroAtom*)m_pParent->m_oaVoroAtoms[z])->m_iAtom+1); if (g_iVoroPrintLevel >= 3) { buf.sprintf("_nbcount_atom_%s_%s%d.csv",((CMolecule*)g_oaMolecules[((CVoroAtom*)m_pParent->m_oaVoroAtoms[z])->m_iMolecule])->m_sName,(const char*)((CAtom*)g_oaAtoms[((CVoroAtom*)m_pParent->m_oaVoroAtoms[z])->m_iRealAtomType])->m_sName,((CVoroAtom*)m_pParent->m_oaVoroAtoms[z])->m_iAtom+1); mfprintf(a," Saving Histogram as %s%s.\n",s,(const char*)buf); mfprintf(a," (%.0f bin entries, %.0f skipped)\n\n",m_pNbhAtoms[z]->m_fBinEntries,m_pNbhAtoms[z]->m_fSkipEntries); m_pNbhAtoms[z]->Write_Int("",s,buf); } } mfprintf(a,"\n\n###### Neighboring Atom Distances ######\n\n"); for (z=0;zm_oaVoroAtoms.GetSize();z++) { // sprintf(buf,"%s %s%d",((CMolecule*)g_oaMolecules[((CVoroAtom*)m_pParent->m_oaVoroAtoms[z])->m_iMolecule])->m_sName,((CAtom*)g_oaAtoms[((CVoroAtom*)m_pParent->m_oaVoroAtoms[z])->m_iRealAtomType])->m_sName,((CVoroAtom*)m_pParent->m_oaVoroAtoms[z])->m_iAtom+1); buf.sprintf("%s %s%d",((CMolecule*)g_oaMolecules[((CVoroAtom*)m_pParent->m_oaVoroAtoms[z])->m_iMolecule])->m_sName,(const char*)((CAtom*)g_oaAtoms[((CVoroAtom*)m_pParent->m_oaVoroAtoms[z])->m_iRealAtomType])->m_sName,((CVoroAtom*)m_pParent->m_oaVoroAtoms[z])->m_iAtom+1); m_pNbhDistAtoms[z]->CalcMeanSD(); mfprintf(a," * Neighboring %s atom distances:\n",(const char*)buf); mfprintf(a," Avg. %.4f pm\n",m_pNbhDistAtoms[z]->m_fMean); mfprintf(a," Min. %.4f pm\n",m_pNbhDistAtoms[z]->m_fMinInput); mfprintf(a," Max. %.4f pm\n",m_pNbhDistAtoms[z]->m_fMaxInput); mfprintf(a," SD %.4f pm\n",m_pNbhDistAtoms[z]->m_fSD); if (g_iVoroPrintLevel >= 3) { m_pNbhDistAtoms[z]->NormBinSum(100.0); // sprintf(buf,"_nbdist_atom_%s_%s%d.csv",((CMolecule*)g_oaMolecules[((CVoroAtom*)m_pParent->m_oaVoroAtoms[z])->m_iMolecule])->m_sName,((CAtom*)g_oaAtoms[((CVoroAtom*)m_pParent->m_oaVoroAtoms[z])->m_iRealAtomType])->m_sName,((CVoroAtom*)m_pParent->m_oaVoroAtoms[z])->m_iAtom+1); buf.sprintf("_nbdist_atom_%s_%s%d.csv",((CMolecule*)g_oaMolecules[((CVoroAtom*)m_pParent->m_oaVoroAtoms[z])->m_iMolecule])->m_sName,(const char*)((CAtom*)g_oaAtoms[((CVoroAtom*)m_pParent->m_oaVoroAtoms[z])->m_iRealAtomType])->m_sName,((CVoroAtom*)m_pParent->m_oaVoroAtoms[z])->m_iAtom+1); mfprintf(a," Saving Histogram as %s%s.\n",s,(const char*)buf); mfprintf(a," (%.0f bin entries, %.0f skipped)\n\n",m_pNbhDistAtoms[z]->m_fBinEntries,m_pNbhDistAtoms[z]->m_fSkipEntries); m_pNbhDistAtoms[z]->Write("",s,buf,true); } } fclose(a); } void CVoroMolecule::Add(CVoroMolecule *m) { int z; for (z=0;zm_oaVoroAtoms.GetSize();z++) { m_pNbhAtoms[z]->AddFrom(m->m_pNbhAtoms[z]); m_pNbhDistAtoms[z]->AddFrom(m->m_pNbhDistAtoms[z]); } for (z=0;zAddFrom(m->m_pNbhMolecules[z]); m_pNbhDistMolecules[z]->AddFrom(m->m_pNbhDistMolecules[z]); m_pNbhAreaMolecules[z]->AddFrom(m->m_pNbhAreaMolecules[z]); } m_pVolume->AddFrom(m->m_pVolume); m_pSurfaceArea->AddFrom(m->m_pSurfaceArea); m_pAVRatio->AddFrom(m->m_pAVRatio); } void CVoroWrapper::WriteNbAtomCountMatrix(const char *s) { FILE *a; int z, z2; CVoroAtom *va; a = OpenFileWrite(s,true); mfprintf(a,"Row=From, Column=To\n"); mfprintf(a,"*"); for (z=0;zm_iMolecule])->m_sName,(const char*)((CAtom*)g_oaAtoms[va->m_iRealAtomType])->m_sName,va->m_iAtom+1); } mfprintf(a,"\n"); for (z=0;zm_iMolecule])->m_sName,(const char*)((CAtom*)g_oaAtoms[va->m_iRealAtomType])->m_sName,va->m_iAtom+1); for (z2=0;z2m_pNbhAtoms[z2]->m_fMean); mfprintf(a,"\n"); } fclose(a); } void CVoroWrapper::WriteNbAtomDistMatrix(const char *s) { FILE *a; int z, z2; CVoroAtom *va; a = OpenFileWrite(s,true); mfprintf(a,"Row=From, Column=To, all numbers in pm\n"); mfprintf(a,"*"); for (z=0;zm_iMolecule])->m_sName,(const char*)((CAtom*)g_oaAtoms[va->m_iRealAtomType])->m_sName,va->m_iAtom+1); } mfprintf(a,"\n"); for (z=0;zm_iMolecule])->m_sName,(const char*)((CAtom*)g_oaAtoms[va->m_iRealAtomType])->m_sName,va->m_iAtom+1); for (z2=0;z2m_pNbhDistAtoms[z2]->m_fMean); mfprintf(a,"\n"); } fclose(a); } void CVoroWrapper::WriteNbMoleculeCountMatrix(const char *s) { FILE *a; int z, z2; CVoroMolecule *vm; a = OpenFileWrite(s,true); mfprintf(a,"Row=From, Column=To\n"); mfprintf(a,"*"); for (z=0;zm_iMolecule])->m_sName); } mfprintf(a,"\n"); for (z=0;zm_iMolecule])->m_sName); for (z2=0;z2m_pNbhMolecules[((CVoroMolecule*)m_oaVoroMolecules[z2])->m_iMolecule]->m_fMean); } mfprintf(a,"\n"); } fclose(a); } void CVoroWrapper::WriteNbMoleculeDistMatrix(const char *s) { FILE *a; int z, z2; CVoroMolecule *vm; a = OpenFileWrite(s,true); mfprintf(a,"Row=From, Column=To, all numbers in pm\n"); mfprintf(a,"*"); for (z=0;zm_iMolecule])->m_sName); } mfprintf(a,"\n"); for (z=0;zm_iMolecule])->m_sName); for (z2=0;z2m_pNbhDistMolecules[((CVoroMolecule*)m_oaVoroMolecules[z2])->m_iMolecule]->m_fMean); } mfprintf(a,"\n"); } fclose(a); } void CVoroWrapper::WriteNbMoleculeAreaMatrix(const char *s) { FILE *a; int z, z2; CVoroMolecule *vm; a = OpenFileWrite(s,true); mfprintf(a,"Row=From, Column=To, all numbers in A^2\n"); mfprintf(a,"*"); for (z=0;zm_iMolecule])->m_sName); } mfprintf(a,"\n"); for (z=0;zm_iMolecule])->m_sName); for (z2=0;z2m_pNbhAreaMolecules[((CVoroMolecule*)m_oaVoroMolecules[z2])->m_iMolecule]->m_fMean); } mfprintf(a,"\n"); } fclose(a); } void CVoroWrapper::WriteAtomInfo(const char *s) { FILE *a; int z; CVoroAtom *va; a = OpenFileWrite(s,true); mfprintf(a,"Molecule; Atom; Mean Volume [A^3]; Mean Surface [A^2]; Mean Exposed Surface [A^2]; Mean Exposed Surface Percentage; Mean Faces; Mean Face Orders; Mean Max Radius [pm]; Mean A/V Ratio\n"); for (z=0;zm_iMolecule])->m_sName,(const char*)((CAtom*)g_oaAtoms[va->m_iRealAtomType])->m_sName,va->m_iAtom+1); mfprintf(a,"%f; ",va->m_pVolume->m_fMean); mfprintf(a,"%f; ",va->m_pSurfaceArea->m_fMean); mfprintf(a,"%f; ",va->m_pExposedSurface->m_fMean); mfprintf(a,"%f; ",va->m_pExposedSurfacePerc->m_fMean); mfprintf(a,"%f; ",va->m_pFaces->m_fMean); mfprintf(a,"%f; ",va->m_pFaceOrders->m_fMean); mfprintf(a,"%f; ",va->m_pMaxRadius->m_fMean); mfprintf(a,"%f\n",va->m_pAVRatio->m_fMean); } fclose(a); } void CVoroWrapper::WriteMoleculeInfo(const char *s) { FILE *a; int z; CVoroMolecule *vm; a = OpenFileWrite(s,true); mfprintf(a,"Molecule; Mean Volume [A^3]; Mean Surface [A^2]; Mean Faces; Mean A/V Ratio\n"); for (z=0;zm_iMolecule])->m_sName); mfprintf(a,"%f; ",vm->m_pVolume->m_fMean); mfprintf(a,"%f; ",vm->m_pSurfaceArea->m_fMean); mfprintf(a,"%f; ",vm->m_pFaces->m_fMean); mfprintf(a,"%f\n",vm->m_pAVRatio->m_fMean); } fclose(a); } void CVoroWrapper::ProcessSurfCover(CTimeStep *ts) { int ijk, q, z, z3, id, faces; // CVoroAtom *va; CVoroMolecule *vm; // CMolecule *m; // CSingleMolecule *sm; voronoicell_neighbor c; vector nb; vector fo; vector fa; CxDVector3 vec; double atot; bool *tb; CxDoubleArray *tfa; // m = (CMolecule*)g_oaMolecules[m_iSurfCoverMol]; /* sm = (CSingleMolecule*)g_oaSingleMolecules[m->m_laSingleMolIndex[m_iSurfCoverSM]]; vec = ts->m_vaCoords[((CxIntArray*)sm->m_oaAtomOffset[g_iFixAtomType[0]])->GetAt(g_iFixAtom[0])] - CxDVector3(g_fBoxX/2.0,g_fBoxY/2.0,g_fBoxZ/2.0); ts->CenterPos(vec);*/ ts->FoldAtomsPositive(); try { m_pContainer = new container_periodic_poly(g_fBoxX/1000.0,0,g_fBoxY/1000.0,0,0,g_fBoxZ/1000.0,m_iBlocksX,m_iBlocksY,m_iBlocksZ,g_iVoroMemory); } catch(...) { m_pContainer = NULL; } if (m_pContainer == NULL) NewException((double)sizeof(container_periodic_poly),__FILE__,__LINE__,__PRETTY_FUNCTION__); for (z=0;zput(z,ts->m_vaCoords[z][0]/1000.0,ts->m_vaCoords[z][1]/1000.0,ts->m_vaCoords[z][2]/1000.0,g_faVoronoiRadii[z]/1000.0); c_loop_all_periodic vl(*m_pContainer); atot = 0; try { tb = new bool[m_waSurfCoverAtom.GetSize()]; } catch(...) { tb = NULL; } if (tb == NULL) NewException((double)m_waSurfCoverAtom.GetSize()*sizeof(bool),__FILE__,__LINE__,__PRETTY_FUNCTION__); for (z=0;zcompute_cell(c,vl)) { ijk=vl.ijk; q=vl.q; id = m_pContainer->id[ijk][q]; // va = (CVoroAtom*)m_oaVoroAtoms[m_pAssignAtoms[id]]; vm = (CVoroMolecule*)m_oaVoroMolecules[m_pAssignMolecules[id]]; if ((vm->m_iMolecule == m_iSurfCoverMol) && (/*vm->m_iSingleMol == m_iSurfCoverSM*/m_waSurfCoverSM.Contains((unsigned short)vm->m_iSingleMol))) { c.neighbors(nb); faces = c.number_of_faces(); c.face_areas(fa); for (z=0;zAdd(fa[z]); } else (*tfa)[tfa->GetSize()-1] += fa[z]; atot += fa[z]; goto _done; } } eprintf("Error.\n"); _done:; } } } } } while (vl.inc()); } for (z=0;zAdd(0); if (atot > 0) ((CxDoubleArray*)m_oaSurfCoverData[z])->GetAt(((CxDoubleArray*)m_oaSurfCoverData[z])->GetSize()-1) /= atot; } delete m_pContainer; delete[] tb; } void CVoroWrapper::FinishSurfCover(const char *s) { FILE *a; int z, z2; CMolecule *m; double t; a = OpenFileWrite(s,true); mfprintf(a,"# Step; "); for (z=0;zm_sName,(const char*)((CAtom*)g_oaAtoms[m->m_baAtomIndex[m_waSurfCoverElem[z]]])->m_sName,m_waSurfCoverAtom[z]+1); if (z < m_waSurfCoverMol.GetSize()-1) mfprintf(a,"; "); } mfprintf(a,"\n"); mfprintf(a,"# Averages; "); for (z2=0;z2GetSize();z++) t += ((CxDoubleArray*)m_oaSurfCoverData[z2])->GetAt(z); if (t > 0) t /= ((CxDoubleArray*)m_oaSurfCoverData[z2])->GetSize(); mfprintf(a,"%f",t*100.0f); if (z2 < m_waSurfCoverMol.GetSize()-1) mfprintf(a,"; "); } mfprintf(a,"\n"); for (z=0;z<((CxDoubleArray*)m_oaSurfCoverData[0])->GetSize();z++) { mfprintf(a,"%d; ",z); for (z2=0;z2GetAt(z)*100.0f); if (z2 < m_waSurfCoverMol.GetSize()-1) mfprintf(a,"; "); } mfprintf(a,"\n"); } fclose(a); } travis-src-190101/src/vorowrapper.h0100777000000000000000000001316713412725653014210 0ustar00/***************************************************************************** TRAVIS - Trajectory Analyzer and Visualizer http://www.travis-analyzer.de/ Copyright (c) 2009-2019 Martin Brehm 2012-2019 Martin Thomas 2016-2019 Sascha Gehrke This file was written by Martin Brehm. --------------------------------------------------------------------------- This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . *****************************************************************************/ #ifndef VOROWRAPPER_H #define VOROWRAPPER_H // This must always be the first include directive #include "config.h" #include "tools.h" #include "xobject.h" #include "voro++.h" #include "xobarray.h" #include "df.h" #include "xdmatrix3.h" #include "xwordarray.h" #include "xdoublearray.h" #include "xintarray.h" #include "xstring.h" #include "xlongarray.h" #include class CTimeStep; class CVoroWrapper; class CVoroAtom : public CxObject { public: void Dump(const char *s); void InitAnalyses(); CVoroAtom(); ~CVoroAtom(); CVoroWrapper *m_pParent; int m_iMolecule; int m_iAtomType; int m_iRealAtomType; int m_iAtom; int *m_pNbhTempMol; CDF *m_pVolume; CDF *m_pSurfaceArea; CDF *m_pExposedSurface; CDF *m_pExposedSurfacePerc; CDF *m_pAVRatio; CDF *m_pFaces; CDF *m_pFaceOrders; CDF *m_pMaxRadius; CDF **m_pNbhAtoms; CDF **m_pNbhMolecules; CDF **m_pNbhDistAtoms; CDF **m_pNbhDistMolecules; }; class CVoroMolecule : public CxObject { public: void Add(CVoroMolecule *m); void Dump(const char *s); void InitAnalyses(); CVoroMolecule(); ~CVoroMolecule(); CVoroWrapper *m_pParent; int m_iMolecule; int m_iSingleMol; int m_iCenterOffset; int *m_pNbhTempMol; int *m_pNbhTempAtoms; double tempvol; double tempsurf; int tempfaces; double *m_pNbhTempArea; CDF *m_pVolume; CDF *m_pSurfaceArea; CDF *m_pAVRatio; CDF *m_pFaces; CDF **m_pNbhAtoms; CDF **m_pNbhMolecules; CDF **m_pNbhDistAtoms; CDF **m_pNbhDistMolecules; CDF **m_pNbhAreaMolecules; }; class CVoroWrapper : public CxObject { public: bool m_bIncludeWritten; bool m_bWritePOVMovie; CxDVector3 m_vPOVFaceBleach; double m_fPOVFaceBleach; double m_fPOVNbHighlightFac; double m_fPOVRayTrans; double m_fPOVNbTrans; double m_fPOVFaceTrans; double m_fPOVEdgeTrans; CxDoubleArray m_faVoroMetric; bool m_bVoroMetricCDF; bool m_bVoroMetric; C2DF *m_pVoroMetricCDF2; C2DF *m_pVoroMetricCDF; int m_iPOVThreads; int m_iPOVThreadPos; FILE *m_fPOVCT; double m_fPOVAtomCenter; double m_fPOVScale; bool m_bPOVMolecules; double m_fPOVExplode; double m_fPOVClip; CxDVector3 m_vPOVBoxClipLow; CxDVector3 m_vPOVBoxClipHigh; int m_iPOVBoxTotalSteps; int m_iPOVBoxTotalFrames; int m_iPOVCurrentChoreographyPart; double m_fPOV_FPS; CxObArray m_oaBoxChoreography; double m_fPOVBoxOuterOpacity; double m_fPOVZoom; int m_iPOVFrameCounter; char m_sPOVText[256]; double m_fPOVAngle; CxLongArray m_iaPOVBoxAtomColors; FILE **m_fPOVBoxScript; bool m_bPOVBox; void FinishSurfCover(const char *s); void ProcessSurfCover(CTimeStep *ts); // void WriteXYZCell(CTimeStep *ts, int mol, int smol); // void WriteXYZCell_Start(CTimeStep *ts, const char *s, int mol, int smol); void WriteMoleculeInfo(const char *s); void WriteAtomInfo(const char *s); void WriteNbAtomDistMatrix(const char *s); void WriteNbAtomCountMatrix(const char *s); void WriteNbMoleculeDistMatrix(const char *s); void WriteNbMoleculeAreaMatrix(const char *s); void WriteNbMoleculeCountMatrix(const char *s); double m_fBoxDens; void Finish(); void Dump(const char *s, CTimeStep *ts); void Parse(); void Init(); void Init2(); void Build(CTimeStep *ts); CVoroWrapper(); ~CVoroWrapper(); int m_iBlocksX; int m_iBlocksY; int m_iBlocksZ; container_periodic_poly *m_pContainer; CxObArray m_oaVoroAtoms; CxObArray m_oaVoroMolecules; long *m_pAssignAtoms; long *m_pAssignMolecules; long *m_pAssignMoleculeTypes; double m_fMaxVol; double m_fMaxSurf; bool *m_pAtomTouched; bool m_bVoroStat; bool m_bVoroTimeSeries; std::vector m_iaVoroTS; std::string m_sVoroTSHead; FILE *m_fTSVolume; FILE *m_fTSSurface; FILE *m_fTSFaces; FILE *m_fTSAVRatio; FILE *m_fTSMaxRadius; CxDoubleArray m_faPOVBoxAtomVisible; bool m_bWritePOV; int m_iPOVMol; int m_iPOVSM; bool m_bPOVEdges; bool m_bPOVFaces; // double m_fPOVFaceOpac; bool m_bPOVFaceColor; bool m_bPOVAtoms; bool m_bPOVRot; CxDMatrix3 m_mPOVMat; bool m_bPOVVertices; CxString m_sPOVExe; CxDoubleArray m_faPOVFaceColor; CxWordArray m_waPOVFaceColorMol; CxWordArray m_waPOVFaceColorElem; CxWordArray m_waPOVFaceColorAtom; FILE *m_fPOVScript; CxDVector3 m_vPOVRotInc; CxDVector3 m_vPOVRotPos; bool m_bPOVAtomGrey; double m_fPOVCameraDist; int m_iPOVResX; int m_iPOVResY; bool m_bPOVFaceColorRef; bool m_bPOVDrawNeighbors; bool m_bPOVNbColorFace; bool m_bPOVHighlightNbAtoms; bool m_bSurfCover; int m_iSurfCoverMol; // int m_iSurfCoverSM; CxWordArray m_waSurfCoverSM; CxObArray m_oaSurfCoverData; CxWordArray m_waSurfCoverMol; CxWordArray m_waSurfCoverElem; CxWordArray m_waSurfCoverAtom; }; #endif travis-src-190101/src/v_base.cpp0100777000000000000000000001340413412725617013406 0ustar00/***************************************************************************** TRAVIS - Trajectory Analyzer and Visualizer http://www.travis-analyzer.de/ Copyright (c) 2009-2019 Martin Brehm 2012-2019 Martin Thomas 2016-2019 Sascha Gehrke --------------------------------------------------------------------------- This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . *****************************************************************************/ // Voro++, a 3D cell-based Voronoi library // // Author : Chris H. Rycroft (LBL / UC Berkeley) // Email : chr@alum.mit.edu // Date : August 30th 2011 /** \file v_base.cc * \brief Function implementations for the base Voronoi container class. */ // This must always be the first include directive #include "config.h" #include "v_base.h" #include "v_config.h" const char *GetRevisionInfo_v_base(unsigned int len) { static char buf[256]; GET_REVISION_INFO( buf, len ); return buf; } const char *GetSourceVersion_v_base() { static char buf[256]; GET_SOURCE_VERSION( buf ); return buf; } /** This function is called during container construction. The routine scans * all of the worklists in the wl[] array. For a given worklist of blocks * labeled \f$w_1\f$ to \f$w_n\f$, it computes a sequence \f$r_0\f$ to * \f$r_n\f$ so that $r_i$ is the minimum distance to all the blocks * \f$w_{j}\f$ where \f$j>i\f$ and all blocks outside the worklist. The values * of \f$r_n\f$ is calculated first, as the minimum distance to any block in * the shell surrounding the worklist. The \f$r_i\f$ are then computed in * reverse order by considering the distance to \f$w_{i+1}\f$. */ voro_base::voro_base(int nx_,int ny_,int nz_,double boxx_,double boxy_,double boxz_) : nx(nx_), ny(ny_), nz(nz_), nxy(nx_*ny_), nxyz(nxy*nz_), boxx(boxx_), boxy(boxy_), boxz(boxz_), xsp(1/boxx_), ysp(1/boxy_), zsp(1/boxz_), mrad(new double[wl_hgridcu*wl_seq_length]) { const unsigned int b1=1<<21,b2=1<<22,b3=1<<24,b4=1<<25,b5=1<<27,b6=1<<28; const double xstep=boxx/wl_fgrid,ystep=boxy/wl_fgrid,zstep=boxz/wl_fgrid; int i,j,k,lx,ly,lz,q; unsigned int f,*e=const_cast (wl); double xlo,ylo,zlo,xhi,yhi,zhi,minr,*radp=mrad; for(zlo=0,zhi=zstep,lz=0;lz>7&127)-64; k=(f>>14&127)-64; if((f&b2)==b2) { compute_minimum(minr,xlo,xhi,ylo,yhi,zlo,zhi,i-1,j,k); if((f&b1)==0) compute_minimum(minr,xlo,xhi,ylo,yhi,zlo,zhi,i+1,j,k); } else if((f&b1)==b1) compute_minimum(minr,xlo,xhi,ylo,yhi,zlo,zhi,i+1,j,k); if((f&b4)==b4) { compute_minimum(minr,xlo,xhi,ylo,yhi,zlo,zhi,i,j-1,k); if((f&b3)==0) compute_minimum(minr,xlo,xhi,ylo,yhi,zlo,zhi,i,j+1,k); } else if((f&b3)==b3) compute_minimum(minr,xlo,xhi,ylo,yhi,zlo,zhi,i,j+1,k); if((f&b6)==b6) { compute_minimum(minr,xlo,xhi,ylo,yhi,zlo,zhi,i,j,k-1); if((f&b5)==0) compute_minimum(minr,xlo,xhi,ylo,yhi,zlo,zhi,i,j,k+1); } else if((f&b5)==b5) compute_minimum(minr,xlo,xhi,ylo,yhi,zlo,zhi,i,j,k+1); } q--; while(q>0) { radp[q]=minr; f=e[q]; i=(f&127)-64; j=(f>>7&127)-64; k=(f>>14&127)-64; compute_minimum(minr,xlo,xhi,ylo,yhi,zlo,zhi,i,j,k); q--; } *radp=minr; e+=wl_seq_length; radp+=wl_seq_length; } } } } /** Computes the minimum distance from a subregion to a given block. If this distance * is smaller than the value of minr, then it passes * \param[in,out] minr a pointer to the current minimum distance. If the distance * computed in this function is smaller, then this distance is * set to the new one. * \param[out] (xlo,ylo,zlo) the lower coordinates of the subregion being * considered. * \param[out] (xhi,yhi,zhi) the upper coordinates of the subregion being * considered. * \param[in] (ti,tj,tk) the coordinates of the block. */ void voro_base::compute_minimum(double &minr,double &xlo,double &xhi,double &ylo,double &yhi,double &zlo,double &zhi,int ti,int tj,int tk) { double radsq,temp; if(ti>0) {temp=boxx*ti-xhi;radsq=temp*temp;} else if(ti<0) {temp=xlo-boxx*(1+ti);radsq=temp*temp;} else radsq=0; if(tj>0) {temp=boxy*tj-yhi;radsq+=temp*temp;} else if(tj<0) {temp=ylo-boxy*(1+tj);radsq+=temp*temp;} if(tk>0) {temp=boxz*tk-zhi;radsq+=temp*temp;} else if(tk<0) {temp=zlo-boxz*(1+tk);radsq+=temp*temp;} if(radsq(format)); // Check to see if "%n" appears in the format sequence while(*fmp!=0) { if(*fmp=='%') { fmp++; if(*fmp=='n') return true; else if(*fmp==0) return false; } fmp++; } return false; } //#include "v_base_wl.cpp" travis-src-190101/src/v_base.h0100777000000000000000000001077713412725663013066 0ustar00/***************************************************************************** TRAVIS - Trajectory Analyzer and Visualizer http://www.travis-analyzer.de/ Copyright (c) 2009-2019 Martin Brehm 2012-2019 Martin Thomas 2016-2019 Sascha Gehrke --------------------------------------------------------------------------- This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . *****************************************************************************/ // Voro++, a 3D cell-based Voronoi library // // Author : Chris H. Rycroft (LBL / UC Berkeley) // Email : chr@alum.mit.edu // Date : August 30th 2011 /** \file v_base.hh * \brief Header file for the base Voronoi container class. */ #ifndef VOROPP_V_BASE_HH #define VOROPP_V_BASE_HH // This must always be the first include directive #include "config.h" #include "v_worklist.h" /** \brief Class containing data structures common across all particle container classes. * * This class contains constants and data structures that are common across all * particle container classes. It contains constants setting the size of the * underlying subgrid of blocks that forms the basis of the Voronoi cell * computations. It also constructs bound tables that are used in the Voronoi * cell computation, and contains a number of routines that are common across * all container classes. */ class voro_base { public: /** The number of blocks in the x direction. */ const int nx; /** The number of blocks in the y direction. */ const int ny; /** The number of blocks in the z direction. */ const int nz; /** A constant, set to the value of nx multiplied by ny, which * is used in the routines that step through blocks in * sequence. */ const int nxy; /** A constant, set to the value of nx*ny*nz, which is used in * the routines that step through blocks in sequence. */ const int nxyz; /** The size of a computational block in the x direction. */ const double boxx; /** The size of a computational block in the y direction. */ const double boxy; /** The size of a computational block in the z direction. */ const double boxz; /** The inverse box length in the x direction. */ const double xsp; /** The inverse box length in the y direction. */ const double ysp; /** The inverse box length in the z direction. */ const double zsp; /** An array to hold the minimum distances associated with the * worklists. This array is initialized during container * construction, by the initialize_radii() routine. */ double *mrad; /** The pre-computed block worklists. */ static const unsigned int wl[wl_seq_length*wl_hgridcu]; bool contains_neighbor(const char* format); voro_base(int nx_,int ny_,int nz_,double boxx_,double boxy_,double boxz_); ~voro_base() {delete [] mrad;} protected: /** A custom int function that returns consistent stepping * for negative numbers, so that (-1.5, -0.5, 0.5, 1.5) maps * to (-2,-1,0,1). * \param[in] a the number to consider. * \return The value of the custom int operation. */ inline int step_int(double a) {return a<0?int(a)-1:int(a);} /** A custom modulo function that returns consistent stepping * for negative numbers. For example, (-2,-1,0,1,2) step_mod 2 * is (0,1,0,1,0). * \param[in] (a,b) the input integers. * \return The value of a modulo b, consistent for negative * numbers. */ inline int step_mod(int a,int b) {return a>=0?a%b:b-1-(b-1-a)%b;} /** A custom integer division function that returns consistent * stepping for negative numbers. For example, (-2,-1,0,1,2) * step_div 2 is (-1,-1,0,0,1). * \param[in] (a,b) the input integers. * \return The value of a div b, consistent for negative * numbers. */ inline int step_div(int a,int b) {return a>=0?a/b:-1+(a+1)/b;} private: void compute_minimum(double &minr,double &xlo,double &xhi,double &ylo,double &yhi,double &zlo,double &zhi,int ti,int tj,int tk); }; #endif travis-src-190101/src/v_base_wl.cpp0100777000000000000000000012124013412725617014106 0ustar00/***************************************************************************** TRAVIS - Trajectory Analyzer and Visualizer http://www.travis-analyzer.de/ Copyright (c) 2009-2019 Martin Brehm 2012-2019 Martin Thomas 2016-2019 Sascha Gehrke --------------------------------------------------------------------------- This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . *****************************************************************************/ // Voro++, a 3D cell-based Voronoi library // // Author : Chris H. Rycroft (LBL / UC Berkeley) // Email : chr@alum.mit.edu // Date : August 30th 2011 /** \file v_base_wl.cc * \brief The table of block worklists that are used during the cell * computation. * * This file is automatically generated by worklist_gen.pl and it is not * intended to be edited by hand. */ // This must always be the first include directive #include "config.h" #include "v_base.h" const char *GetRevisionInfo_v_base_wl(unsigned int len) { static char buf[256]; GET_REVISION_INFO( buf, len ); return buf; } const char *GetSourceVersion_v_base_wl() { static char buf[256]; GET_SOURCE_VERSION( buf ); return buf; } const unsigned int voro_base::wl[wl_seq_length*wl_hgridcu]={ 7,0x10203f,0x101fc0,0xfe040,0xfe03f,0x101fbf,0xfdfc0,0xfdfbf,0x10fe0bf,0x11020bf,0x11020c0,0x10fe0c0,0x2fe041,0x302041,0x301fc1,0x2fdfc1,0x8105fc0,0x8106040,0x810603f,0x8105fbf,0x701fbe,0x70203e,0x6fe03e,0x6fdfbe,0x30fdf3f,0x3101f3f,0x3101f40,0x30fdf40,0x180f9fc0,0x180fa040,0x180fa03f,0x180f9fbf,0x12fe0c1,0x13020c1,0x91060c0,0x91060bf,0x8306041,0x8305fc1,0x3301f41,0x32fdf41,0x182f9fc1,0x182fa041,0x190fa0c0,0x190fa0bf,0x16fe0be,0x17020be,0x870603e,0x8705fbe,0xb105f3f,0xb105f40,0x3701f3e,0x36fdf3e,0x186f9fbe,0x186fa03e,0x1b0f9f3f,0x1b0f9f40,0x93060c1,0x192fa0c1,0x97060be,0xb305f41,0x1b2f9f41,0x196fa0be,0xb705f3e,0x1b6f9f3e, 11,0x101fc0,0xfe040,0xfdfc0,0x10203f,0x101fbf,0xfe03f,0xfdfbf,0xfdfc1,0x101fc1,0x102041,0xfe041,0x10fe0c0,0x11020c0,0x8106040,0x8105fc0,0x8105fbf,0x810603f,0x11020bf,0x10fe0bf,0x180fa040,0x180f9fc0,0x30fdf40,0x3101f40,0x3101f3f,0x30fdf3f,0x180f9fbf,0x180fa03f,0x6fe03e,0x70203e,0x701fbe,0x6fdfbe,0x8105fc1,0x8106041,0x11020c1,0x10fe0c1,0x180fa041,0x180f9fc1,0x30fdf41,0x3101f41,0x91060c0,0x91060bf,0x190fa0c0,0x190fa0bf,0xb105f40,0xb105f3f,0x8705fbe,0x870603e,0x97020be,0x16fe0be,0x1b0f9f40,0x1b0f9f3f,0x36fdf3e,0xb701f3e,0x1b6f9fbe,0x196fa03e,0x93060c1,0xb305f41,0x192fa0c1,0x1b2f9f41,0x1b2fdfc2,0xb301fc2,0x9302042,0x192fe042, 11,0x101fc0,0xfe040,0xfdfc0,0xfdfbf,0x101fbf,0x10203f,0xfe03f,0xfe041,0x102041,0x101fc1,0xfdfc1,0x8105fc0,0x8106040,0x11020c0,0x10fe0c0,0x10fe0bf,0x11020bf,0x810603f,0x8105fbf,0x3101f40,0x30fdf40,0x180f9fc0,0x180fa040,0x180fa03f,0x180f9fbf,0x30fdf3f,0x3101f3f,0x8105fc1,0x8106041,0x11020c1,0x10fe0c1,0x180fa041,0x180f9fc1,0x30fdf41,0x3101f41,0x701fbe,0x70203e,0x6fe03e,0x6fdfbe,0x91060c0,0x91060bf,0xb105f40,0xb105f3f,0x190fa0c0,0x190fa0bf,0x93060c1,0x1b0f9f40,0x1b0f9f3f,0xb305f41,0x192fa0c1,0x16fe0be,0x17020be,0x970603e,0x8705fbe,0xb701f3e,0x36fdf3e,0x1b2f9f41,0x1b2fdfc2,0x192fe042,0x9302042,0xb301fc2,0x1b6f9fbe,0x196fa03e, 11,0x101fc0,0xfe040,0xfdfc0,0xfdfbf,0x101fbf,0x10203f,0xfe03f,0xfe041,0x102041,0x101fc1,0xfdfc1,0x8105fc0,0x8106040,0x11020c0,0x10fe0c0,0x10fe0bf,0x11020bf,0x810603f,0x8105fbf,0x3101f40,0x30fdf40,0x180f9fc0,0x180fa040,0x10fe0c1,0x11020c1,0x8106041,0x8105fc1,0x3101f3f,0x30fdf3f,0x180f9fbf,0x180fa03f,0x180fa041,0x180f9fc1,0x30fdf41,0x3101f41,0x91060c0,0x91060bf,0x70203e,0x701fbe,0x6fdfbe,0x6fe03e,0x190fa0c0,0xb105f40,0xb105f3f,0x93060c1,0x190fa0bf,0x192fa0c1,0x1b0f9f40,0x1b0f9f3f,0xb305f41,0xb301fc2,0x9302042,0x192fe042,0x1b2fdfc2,0x1b2f9f41,0x16fe0be,0x17020be,0x970603e,0x8705fbe,0xb701f3e,0x36fdf3e,0x1b6f9fbe,0x196fa03e, 11,0x10203f,0xfe040,0xfe03f,0x101fc0,0x101fbf,0xfdfc0,0xfdfbf,0xfe0bf,0x1020bf,0x1020c0,0xfe0c0,0x2fe041,0x302041,0x8106040,0x810603f,0x8105fbf,0x8105fc0,0x301fc1,0x2fdfc1,0x180fa040,0x180fa03f,0x6fe03e,0x70203e,0x701fbe,0x6fdfbe,0x180f9fbf,0x180f9fc0,0x30fdf40,0x3101f40,0x3101f3f,0x30fdf3f,0x81060bf,0x81060c0,0x3020c1,0x2fe0c1,0x180fa0c0,0x180fa0bf,0x6fe0be,0x7020be,0x8306041,0x8305fc1,0x182fa041,0x182f9fc1,0x870603e,0x8705fbe,0xb105f3f,0xb105f40,0xb301f41,0x32fdf41,0x186fa03e,0x186f9fbe,0x36fdf3e,0xb701f3e,0x1b6f9f3f,0x1b2f9f40,0x93060c1,0x97060be,0x192fa0c1,0x196fa0be,0x196fe13f,0x970213f,0x9302140,0x192fe140, 9,0xfe040,0x10203f,0x101fc0,0xfdfc0,0xfe03f,0xfdfbf,0x101fbf,0x102041,0xfe041,0x10fe0c0,0x11020c0,0x11020bf,0x10fe0bf,0xfdfc1,0x101fc1,0x8106040,0x810603f,0x8105fc0,0x8105fbf,0x180fa040,0x180f9fc0,0x180fa03f,0x180f9fbf,0x10fe0c1,0x11020c1,0x70203e,0x6fe03e,0x6fdfbe,0x701fbe,0x3101f3f,0x3101f40,0x30fdf40,0x30fdf3f,0x8106041,0x91060c0,0x91060bf,0x8305fc1,0x180fa041,0x190fa0c0,0x190fa0bf,0x180f9fc1,0x30fdf41,0x3301f41,0x17020be,0x16fe0be,0x93060c1,0x870603e,0x8705fbe,0xb105f3f,0xb105f40,0x192fa0c1,0x1b0f9f40,0x1b0f9f3f,0x186f9fbe,0x196fa03e,0x1b6fdf3e,0xb701f3e,0x97060be,0xb305f41,0x1b2f9f41,0x1b2fdfc2,0x192fe042,0xa302042, 11,0xfe040,0x101fc0,0xfdfc0,0xfe03f,0x10203f,0x101fbf,0xfdfbf,0xfe041,0x102041,0x101fc1,0xfdfc1,0x10fe0c0,0x11020c0,0x11020bf,0x10fe0bf,0x8106040,0x8105fc0,0x810603f,0x8105fbf,0x11020c1,0x10fe0c1,0x180fa040,0x180f9fc0,0x180fa03f,0x180f9fbf,0x30fdf40,0x3101f40,0x8106041,0x8105fc1,0x3101f3f,0x30fdf3f,0x91060c0,0x91060bf,0x180fa041,0x180f9fc1,0x6fe03e,0x70203e,0x701fbe,0x6fdfbe,0x190fa0c0,0x190fa0bf,0x30fdf41,0x3101f41,0x93060c1,0x192fa0c1,0xb105f40,0xb105f3f,0x17020be,0x16fe0be,0x970603e,0x8705fbe,0x1b0f9f40,0x1b0f9f3f,0x186f9fbe,0x196fa03e,0xb305f41,0xb301fc2,0x9302042,0x192fe042,0x1b2fdfc2,0x1b2f9f41,0x1b6fdf3e,0xb701f3e, 11,0xfe040,0x101fc0,0xfdfc0,0xfe03f,0x10203f,0x101fbf,0xfdfbf,0xfe041,0x102041,0x101fc1,0xfdfc1,0x10fe0c0,0x11020c0,0x11020bf,0x10fe0bf,0x8106040,0x8105fc0,0x11020c1,0x10fe0c1,0x810603f,0x8105fbf,0x180fa040,0x180f9fc0,0x8106041,0x8105fc1,0x3101f40,0x180fa03f,0x180f9fbf,0x30fdf40,0x180fa041,0x180f9fc1,0x91060c0,0x3101f3f,0x30fdf3f,0x30fdf41,0x3101f41,0x91060bf,0x190fa0c0,0x91060c1,0x190fa0bf,0x186fe03e,0x70203e,0x3701fbe,0x1b6fdfbe,0x190fa0c1,0x182fe042,0xb105f40,0xb105f3f,0x302042,0x3301fc2,0x1b2fdfc2,0x1b0f9f40,0x1b6f9f3f,0xb105f41,0x17020be,0x196fe0be,0x970603e,0xb705fbe,0x1b2f9f41,0x192fe0c2,0x13020c2,0x9306042,0xb305fc2, 11,0x10203f,0xfe040,0xfe03f,0xfdfbf,0x101fbf,0x101fc0,0xfdfc0,0xfe0c0,0x1020c0,0x1020bf,0xfe0bf,0x810603f,0x8106040,0x302041,0x2fe041,0x2fdfc1,0x301fc1,0x8105fc0,0x8105fbf,0x70203e,0x6fe03e,0x180fa03f,0x180fa040,0x180f9fc0,0x180f9fbf,0x6fdfbe,0x701fbe,0x81060bf,0x81060c0,0x3020c1,0x2fe0c1,0x180fa0c0,0x180fa0bf,0x6fe0be,0x7020be,0x3101f3f,0x3101f40,0x30fdf40,0x30fdf3f,0x8306041,0x8305fc1,0x870603e,0x8705fbe,0x182fa041,0x182f9fc1,0x93060c1,0x186fa03e,0x186f9fbe,0x97060be,0x192fa0c1,0x32fdf41,0x3301f41,0xb305f40,0xb105f3f,0xb701f3e,0x36fdf3e,0x196fa0be,0x196fe13f,0x192fe140,0x9302140,0x970213f,0x1b6f9f3f,0x1b2f9f40, 11,0xfe040,0x10203f,0xfe03f,0xfdfc0,0x101fc0,0x101fbf,0xfdfbf,0xfe0c0,0x1020c0,0x1020bf,0xfe0bf,0x2fe041,0x302041,0x301fc1,0x2fdfc1,0x8106040,0x810603f,0x8105fc0,0x8105fbf,0x3020c1,0x2fe0c1,0x180fa040,0x180fa03f,0x180f9fc0,0x180f9fbf,0x6fe03e,0x70203e,0x81060c0,0x81060bf,0x701fbe,0x6fdfbe,0x8306041,0x8305fc1,0x180fa0c0,0x180fa0bf,0x30fdf40,0x3101f40,0x3101f3f,0x30fdf3f,0x182fa041,0x182f9fc1,0x6fe0be,0x7020be,0x93060c1,0x192fa0c1,0x870603e,0x8705fbe,0x3301f41,0x32fdf41,0xb305f40,0xb105f3f,0x186fa03e,0x186f9fbe,0x1b0f9f3f,0x1b2f9f40,0x97060be,0x970213f,0x9302140,0x192fe140,0x196fe13f,0x196fa0be,0x1b6fdf3e,0xb701f3e, 15,0xfe040,0xfe03f,0x10203f,0x101fc0,0xfdfc0,0xfdfbf,0x101fbf,0x102041,0xfe041,0xfe0c0,0x1020c0,0x1020bf,0xfe0bf,0xfdfc1,0x101fc1,0x8106040,0x1020c1,0xfe0c1,0x810603f,0x8105fc0,0x8105fbf,0x180fa040,0x180fa03f,0x180f9fc0,0x180f9fbf,0x8106041,0x81060c0,0x81060bf,0x8105fc1,0x180fa041,0x180fa0c0,0x180fa0bf,0x6fe03e,0x70203e,0x3101f40,0x30fdf40,0x180f9fc1,0x30fdf3f,0x3101f3f,0x3701fbe,0x36fdfbe,0x93060c1,0x192fa0c1,0x6fe0be,0x7020be,0x3101f41,0x30fdf41,0xb305f40,0xb105f3f,0x970603e,0xb705fbe,0x196fa03e,0x186f9fbe,0x1b2f9f40,0x1b6f9f3f,0x192fe042,0x9302042,0xb301fc2,0x1b2fdfc2,0x192fe140,0x9302140,0x970213f,0x196fe13f, 15,0xfe040,0xfdfc0,0x101fc0,0x10203f,0xfe03f,0xfdfbf,0x101fbf,0x102041,0xfe041,0xfdfc1,0x101fc1,0x1020c0,0xfe0c0,0xfe0bf,0x1020bf,0x1020c1,0xfe0c1,0x8106040,0x8105fc0,0x810603f,0x8105fbf,0x180fa040,0x180f9fc0,0x8106041,0x8105fc1,0x81060c0,0x180fa03f,0x180f9fbf,0x180fa041,0x180f9fc1,0x180fa0c0,0x81060bf,0x91060c1,0x3101f40,0x30fdf40,0x30fdf3f,0x180fa0bf,0x190fa0c1,0x3101f3f,0x3101f41,0x30fdf41,0x186fe03e,0x70203e,0x3701fbe,0x1b6fdfbe,0x186fe0be,0x7020be,0x8302042,0x182fe042,0x1b2fdfc2,0xb301fc2,0xb105f40,0xb705f3f,0xb305f41,0x1b2f9f40,0x1b6f9f3f,0x192fe140,0x9302140,0x93020c2,0x192fe0c2,0x196fe13f,0x970213f,0xa70603e, 11,0x10203f,0xfe040,0xfe03f,0xfdfbf,0x101fbf,0x101fc0,0xfdfc0,0xfe0c0,0x1020c0,0x1020bf,0xfe0bf,0x810603f,0x8106040,0x302041,0x2fe041,0x2fdfc1,0x301fc1,0x8105fc0,0x8105fbf,0x70203e,0x6fe03e,0x180fa03f,0x180fa040,0x2fe0c1,0x3020c1,0x81060c0,0x81060bf,0x701fbe,0x6fdfbe,0x180f9fbf,0x180f9fc0,0x180fa0c0,0x180fa0bf,0x6fe0be,0x7020be,0x8306041,0x8305fc1,0x3101f40,0x3101f3f,0x30fdf3f,0x30fdf40,0x182fa041,0x870603e,0x8705fbe,0x93060c1,0x182f9fc1,0x192fa0c1,0x186fa03e,0x186f9fbe,0x97060be,0x970213f,0x9302140,0x192fe140,0x196fe13f,0x196fa0be,0x32fdf41,0x3301f41,0xb305f40,0xb105f3f,0xb701f3e,0x36fdf3e,0x1b6f9f3f,0x1b2f9f40, 11,0xfe040,0x10203f,0xfe03f,0xfdfc0,0x101fc0,0x101fbf,0xfdfbf,0xfe0c0,0x1020c0,0x1020bf,0xfe0bf,0x2fe041,0x302041,0x301fc1,0x2fdfc1,0x8106040,0x810603f,0x3020c1,0x2fe0c1,0x8105fc0,0x8105fbf,0x180fa040,0x180fa03f,0x81060c0,0x81060bf,0x70203e,0x180f9fc0,0x180f9fbf,0x6fe03e,0x180fa0c0,0x180fa0bf,0x8306041,0x701fbe,0x6fdfbe,0x6fe0be,0x7020be,0x8305fc1,0x182fa041,0x83060c1,0x182f9fc1,0x1b0fdf40,0x3101f40,0x3701f3f,0x1b6fdf3f,0x182fa0c1,0x190fe140,0x870603e,0x8705fbe,0x1102140,0x170213f,0x196fe13f,0x186fa03e,0x1b6f9fbe,0x87060be,0x3301f41,0x1b2fdf41,0xb305f40,0xb705f3f,0x196fa0be,0x192fe141,0x1302141,0x9306140,0x970613f, 15,0xfe040,0xfe03f,0x10203f,0x101fc0,0xfdfc0,0xfdfbf,0x101fbf,0x1020c0,0xfe0c0,0xfe0bf,0x1020bf,0x102041,0xfe041,0xfdfc1,0x101fc1,0x1020c1,0xfe0c1,0x8106040,0x810603f,0x8105fc0,0x8105fbf,0x180fa040,0x180fa03f,0x81060c0,0x81060bf,0x8106041,0x180f9fc0,0x180f9fbf,0x180fa0c0,0x180fa0bf,0x180fa041,0x8105fc1,0x83060c1,0x70203e,0x6fe03e,0x6fdfbe,0x180f9fc1,0x182fa0c1,0x701fbe,0x7020be,0x6fe0be,0x1b0fdf40,0x3101f40,0x3701f3f,0x1b6fdf3f,0x1b0fdf41,0x3101f41,0x9102140,0x190fe140,0x196fe13f,0x970213f,0x870603e,0xb705fbe,0x97060be,0x196fa03e,0x1b6f9fbe,0x192fe042,0x9302042,0x9302141,0x192fe141,0x1b2fdfc2,0xb301fc2,0xb505f40, 17,0xfe040,0xfe03f,0x10203f,0x101fc0,0xfdfc0,0xfe041,0x102041,0x1020c0,0xfe0c0,0xfdfbf,0x101fbf,0x1020bf,0xfe0bf,0xfdfc1,0x101fc1,0x1020c1,0xfe0c1,0x8106040,0x810603f,0x8105fc0,0x8106041,0x81060c0,0x180fa040,0x180fa03f,0x180f9fc0,0x8105fbf,0x81060bf,0x8105fc1,0x180fa041,0x180fa0c0,0x180f9fbf,0x81060c1,0x180fa0bf,0x180f9fc1,0x180fa0c1,0x186fe03e,0x70203e,0x3101f40,0x1b0fdf40,0x1b0fdf3f,0x3101f3f,0x3701fbe,0x1b6fdfbe,0x186fe0be,0x7020be,0x9102140,0x190fe140,0x182fe042,0x8302042,0x3101f41,0x1b0fdf41,0x1b2fdfc2,0xb301fc2,0x83020c2,0x182fe0c2,0x196fe13f,0x970213f,0x9302141,0x192fe141,0x970603e,0xb305f40,0xb105f3f,0xb705fbe, 11,0x10203f,0x101fc0,0x101fbf,0xfe040,0xfe03f,0xfdfc0,0xfdfbf,0x105fbf,0x10603f,0x106040,0x105fc0,0x301fc1,0x302041,0x11020c0,0x11020bf,0x10fe0bf,0x10fe0c0,0x2fe041,0x2fdfc1,0x3101f40,0x3101f3f,0x701fbe,0x70203e,0x6fe03e,0x6fdfbe,0x30fdf3f,0x30fdf40,0x180f9fc0,0x180fa040,0x180fa03f,0x180f9fbf,0x11060bf,0x11060c0,0x306041,0x305fc1,0x3105f40,0x3105f3f,0x705fbe,0x70603e,0x13020c1,0x12fe0c1,0x3301f41,0x32fdf41,0x17020be,0x16fe0be,0x190fa0bf,0x190fa0c0,0x192fa041,0x182f9fc1,0x3701f3e,0x36fdf3e,0x186f9fbe,0x196fa03e,0x1b6f9f3f,0x1b2f9f40,0x93060c1,0x97060be,0xb305f41,0xb705f3e,0xb709fbf,0x970a03f,0x930a040,0xb309fc0, 9,0x101fc0,0x10203f,0xfe040,0xfdfc0,0x101fbf,0xfdfbf,0xfe03f,0x102041,0x101fc1,0x8105fc0,0x8106040,0x810603f,0x8105fbf,0xfdfc1,0xfe041,0x11020c0,0x11020bf,0x10fe0c0,0x10fe0bf,0x3101f40,0x30fdf40,0x3101f3f,0x30fdf3f,0x8105fc1,0x8106041,0x70203e,0x701fbe,0x6fdfbe,0x6fe03e,0x180fa03f,0x180fa040,0x180f9fc0,0x180f9fbf,0x11020c1,0x91060c0,0x91060bf,0x12fe0c1,0x3101f41,0xb105f40,0xb105f3f,0x30fdf41,0x180f9fc1,0x182fa041,0x870603e,0x8705fbe,0x93060c1,0x17020be,0x16fe0be,0x190fa0bf,0x190fa0c0,0xb305f41,0x1b0f9f40,0x1b0f9f3f,0x36fdf3e,0xb701f3e,0x1b6f9fbe,0x196fa03e,0x97060be,0x192fa0c1,0x1b2f9f41,0x1b2fdfc2,0xb301fc2,0x11302042, 11,0x101fc0,0xfe040,0xfdfc0,0x101fbf,0x10203f,0xfe03f,0xfdfbf,0x101fc1,0x102041,0xfe041,0xfdfc1,0x8105fc0,0x8106040,0x810603f,0x8105fbf,0x11020c0,0x10fe0c0,0x11020bf,0x10fe0bf,0x8106041,0x8105fc1,0x3101f40,0x30fdf40,0x3101f3f,0x30fdf3f,0x180f9fc0,0x180fa040,0x11020c1,0x10fe0c1,0x180fa03f,0x180f9fbf,0x91060c0,0x91060bf,0x3101f41,0x30fdf41,0x701fbe,0x70203e,0x6fe03e,0x6fdfbe,0xb105f40,0xb105f3f,0x180f9fc1,0x180fa041,0x93060c1,0xb305f41,0x190fa0c0,0x190fa0bf,0x870603e,0x8705fbe,0x97020be,0x16fe0be,0x1b0f9f40,0x1b0f9f3f,0x36fdf3e,0xb701f3e,0x192fa0c1,0x192fe042,0x9302042,0xb301fc2,0x1b2fdfc2,0x1b2f9f41,0x1b6f9fbe,0x196fa03e, 11,0x101fc0,0xfe040,0xfdfc0,0x101fbf,0x10203f,0xfe03f,0xfdfbf,0x101fc1,0x102041,0xfe041,0xfdfc1,0x8105fc0,0x8106040,0x810603f,0x8105fbf,0x11020c0,0x10fe0c0,0x8106041,0x8105fc1,0x11020bf,0x10fe0bf,0x3101f40,0x30fdf40,0x11020c1,0x10fe0c1,0x180fa040,0x3101f3f,0x30fdf3f,0x180f9fc0,0x3101f41,0x30fdf41,0x91060c0,0x180fa03f,0x180f9fbf,0x180f9fc1,0x180fa041,0x91060bf,0xb105f40,0x91060c1,0xb105f3f,0x3701fbe,0x70203e,0x186fe03e,0x1b6fdfbe,0xb105f41,0x3301fc2,0x190fa0c0,0x190fa0bf,0x302042,0x182fe042,0x1b2fdfc2,0x1b0f9f40,0x1b6f9f3f,0x190fa0c1,0x870603e,0xb705fbe,0x97020be,0x196fe0be,0x1b2f9f41,0xb305fc2,0x8306042,0x93020c2,0x192fe0c2, 9,0x10203f,0x101fc0,0xfe040,0xfe03f,0x101fbf,0xfdfbf,0xfdfc0,0x1020c0,0x1020bf,0x810603f,0x8106040,0x8105fc0,0x8105fbf,0xfe0bf,0xfe0c0,0x302041,0x301fc1,0x2fe041,0x2fdfc1,0x70203e,0x6fe03e,0x701fbe,0x6fdfbe,0x81060bf,0x81060c0,0x3101f40,0x3101f3f,0x30fdf3f,0x30fdf40,0x180f9fc0,0x180fa040,0x180fa03f,0x180f9fbf,0x3020c1,0x8306041,0x8305fc1,0x12fe0c1,0x7020be,0x870603e,0x8705fbe,0x6fe0be,0x180fa0bf,0x190fa0c0,0xb105f40,0xb105f3f,0x93060c1,0x3301f41,0x32fdf41,0x182f9fc1,0x182fa041,0x97060be,0x186fa03e,0x186f9fbe,0x36fdf3e,0xb701f3e,0x1b6f9f3f,0x1b2f9f40,0xb305f41,0x192fa0c1,0x196fa0be,0x196fe13f,0x970213f,0x11302140, 7,0x10203f,0x101fc0,0xfe040,0xfe03f,0x101fbf,0xfdfc0,0xfdfbf,0x302041,0x1020c0,0x8106040,0x810603f,0x1020bf,0xfe0c0,0x2fe041,0x301fc1,0x8105fc0,0x8105fbf,0xfe0bf,0x2fdfc1,0x3020c1,0x8306041,0x81060c0,0x81060bf,0x2fe0c1,0x8305fc1,0x3101f40,0x3101f3f,0x701fbe,0x70203e,0x6fe03e,0x180fa03f,0x180fa040,0x180f9fc0,0x30fdf40,0x30fdf3f,0x6fdfbe,0x180f9fbf,0x180fa0c0,0x182fa041,0x93060c1,0x870603e,0x7020be,0x6fe0be,0x180fa0bf,0x182f9fc1,0x32fdf41,0x3301f41,0xb105f40,0xb105f3f,0x8705fbe,0x97060be,0x192fa0c1,0xb305f41,0xb701f3e,0x36fdf3e,0x1b0f9f3f,0x1b2f9f40,0x1b6f9fbe,0x196fa03e,0x196fe13f,0x9302140,0x970213f,0x192fe140, 11,0x101fc0,0xfe040,0xfdfc0,0x10203f,0x101fbf,0xfe03f,0xfdfbf,0x102041,0x101fc1,0xfe041,0xfdfc1,0x11020c0,0x8106040,0x8105fc0,0x10fe0c0,0x11020bf,0x810603f,0x8105fbf,0x10fe0bf,0x11020c1,0x8106041,0x8105fc1,0x10fe0c1,0x91060c0,0x91060bf,0x3101f40,0x30fdf40,0x180f9fc0,0x180fa040,0x180fa03f,0x180f9fbf,0x30fdf3f,0x3101f3f,0x701fbe,0x70203e,0x6fe03e,0x6fdfbe,0x93060c1,0x3101f41,0x30fdf41,0x180f9fc1,0x180fa041,0x190fa0c0,0x190fa0bf,0xb105f40,0xb105f3f,0x8705fbe,0x870603e,0x17020be,0x16fe0be,0x192fa0c1,0xb305f41,0xb301fc2,0x9302042,0x192fe042,0x1b2fdfc2,0x1b2f9f40,0x1b0f9f3f,0x186f9fbe,0x196fa03e,0x97060be,0xb701f3e,0x1b6fdf3e, 11,0x101fc0,0xfe040,0xfdfc0,0x10203f,0x101fbf,0xfe03f,0xfdfbf,0x102041,0x101fc1,0xfe041,0xfdfc1,0x11020c0,0x8106040,0x8105fc0,0x10fe0c0,0x11020bf,0x810603f,0x8105fbf,0x10fe0bf,0x11020c1,0x8106041,0x8105fc1,0x10fe0c1,0x91060c0,0x91060bf,0x3101f40,0x30fdf40,0x180f9fc0,0x180fa040,0x180fa03f,0x180f9fbf,0x30fdf3f,0x3101f3f,0x3101f41,0x91060c1,0x180fa041,0x180f9fc1,0x30fdf41,0xb105f40,0x70203e,0x3701fbe,0x186fe03e,0x1b6fdfbe,0x190fa0c0,0x190fa0bf,0x190fa0c1,0xb105f3f,0xb105f41,0x3301fc2,0x302042,0x182fe042,0x1b2fdfc2,0x1b0f9f40,0x17020be,0x970603e,0xb705fbe,0x196fe0be,0x1b6f9f3f,0x1b2f9f41,0x13020c2,0x9306042,0xb305fc2,0x192fe0c2, 11,0x10203f,0xfe040,0xfe03f,0x101fbf,0x101fc0,0xfdfc0,0xfdfbf,0x1020bf,0x1020c0,0xfe0c0,0xfe0bf,0x810603f,0x8106040,0x8105fc0,0x8105fbf,0x302041,0x2fe041,0x301fc1,0x2fdfc1,0x81060c0,0x81060bf,0x70203e,0x6fe03e,0x701fbe,0x6fdfbe,0x180fa03f,0x180fa040,0x3020c1,0x2fe0c1,0x180f9fc0,0x180f9fbf,0x8306041,0x8305fc1,0x7020be,0x6fe0be,0x3101f3f,0x3101f40,0x30fdf40,0x30fdf3f,0x870603e,0x8705fbe,0x180fa0bf,0x180fa0c0,0x93060c1,0x97060be,0x182fa041,0x182f9fc1,0xb105f40,0xb105f3f,0xb301f41,0x32fdf41,0x186fa03e,0x186f9fbe,0x36fdf3e,0xb701f3e,0x192fa0c1,0x192fe140,0x9302140,0x970213f,0x196fe13f,0x196fa0be,0x1b6f9f3f,0x1b2f9f40, 11,0x10203f,0xfe040,0xfe03f,0x101fc0,0x101fbf,0xfdfc0,0xfdfbf,0x1020c0,0x1020bf,0xfe0c0,0xfe0bf,0x302041,0x8106040,0x810603f,0x2fe041,0x301fc1,0x8105fc0,0x8105fbf,0x2fdfc1,0x3020c1,0x81060c0,0x81060bf,0x2fe0c1,0x8306041,0x8305fc1,0x70203e,0x6fe03e,0x180fa03f,0x180fa040,0x180f9fc0,0x180f9fbf,0x6fdfbe,0x701fbe,0x3101f3f,0x3101f40,0x30fdf40,0x30fdf3f,0x93060c1,0x7020be,0x6fe0be,0x180fa0bf,0x180fa0c0,0x182fa041,0x182f9fc1,0x870603e,0x8705fbe,0xb105f3f,0xb105f40,0x3301f41,0x32fdf41,0x192fa0c1,0x97060be,0x970213f,0x9302140,0x192fe140,0x196fe13f,0x196fa03e,0x186f9fbe,0x1b0f9f3f,0x1b2f9f40,0xb305f41,0xb701f3e,0x1b6fdf3e, 15,0xfe040,0x10203f,0x101fc0,0xfdfc0,0xfe03f,0x101fbf,0xfdfbf,0x102041,0x1020c0,0xfe0c0,0xfe041,0x101fc1,0xfdfc1,0x1020bf,0xfe0bf,0x8106040,0x810603f,0x8105fc0,0x8105fbf,0x1020c1,0xfe0c1,0x8106041,0x81060c0,0x81060bf,0x8105fc1,0x180fa040,0x180f9fc0,0x180fa03f,0x180f9fbf,0x93060c1,0x70203e,0x6fe03e,0x3101f40,0x1b0fdf40,0x3101f3f,0x3701fbe,0x6fdfbe,0x1b6fdf3f,0x180fa041,0x180fa0c0,0x180fa0bf,0x180f9fc1,0x1b0fdf41,0x3101f41,0x7020be,0x6fe0be,0x870603e,0x8705fbe,0xb105f40,0xb705f3f,0x192fa0c1,0x192fe140,0x9302140,0x970213f,0x97060be,0x9302042,0x192fe042,0xb301fc2,0xb305f41,0x1b2fdfc2,0x196fe13f,0x196fa03e,0x1b6f9fbe, 14,0xfe040,0x101fc0,0xfdfc0,0x10203f,0xfe03f,0x101fbf,0xfdfbf,0x102041,0xfe041,0x101fc1,0xfdfc1,0x1020c0,0xfe0c0,0x1020bf,0x8106040,0xfe0bf,0x8105fc0,0x1020c1,0xfe0c1,0x810603f,0x8105fbf,0x8106041,0x8105fc1,0x81060c0,0x81060bf,0x91060c1,0x180fa040,0x180f9fc0,0x180fa03f,0x180f9fbf,0x180fa041,0x180f9fc1,0x1b0fdf40,0x3101f40,0x3101f3f,0x1b0fdf3f,0x180fa0c0,0x190fa0bf,0x186fe03e,0x70203e,0x3701fbe,0x3101f41,0x1b0fdf41,0x1b6fdfbe,0x190fa0c1,0x182fe042,0x302042,0xb105f40,0xb105f3f,0x3301fc2,0x1b2fdfc2,0x7020be,0x196fe0be,0x970603e,0xb705fbe,0xb105f41,0x9302140,0x192fe140,0x13020c2,0x192fe0c2,0x9306042,0xb305fc2,0x1170213f, 11,0x10203f,0xfe040,0xfe03f,0x101fbf,0x101fc0,0xfdfc0,0xfdfbf,0x1020bf,0x1020c0,0xfe0c0,0xfe0bf,0x810603f,0x8106040,0x8105fc0,0x8105fbf,0x302041,0x2fe041,0x81060c0,0x81060bf,0x301fc1,0x2fdfc1,0x70203e,0x6fe03e,0x3020c1,0x2fe0c1,0x180fa040,0x701fbe,0x6fdfbe,0x180fa03f,0x7020be,0x6fe0be,0x8306041,0x180f9fc0,0x180f9fbf,0x180fa0bf,0x180fa0c0,0x8305fc1,0x870603e,0x83060c1,0x8705fbe,0x3701f3f,0x3101f40,0x1b0fdf40,0x1b6fdf3f,0x87060be,0x170213f,0x182fa041,0x182f9fc1,0x1102140,0x190fe140,0x196fe13f,0x186fa03e,0x1b6f9fbe,0x182fa0c1,0xb105f40,0xb705f3f,0xb301f41,0x1b2fdf41,0x196fa0be,0x970613f,0x9106140,0x9302141,0x192fe141, 11,0x10203f,0xfe040,0xfe03f,0x101fc0,0x101fbf,0xfdfc0,0xfdfbf,0x1020c0,0x1020bf,0xfe0c0,0xfe0bf,0x302041,0x8106040,0x810603f,0x2fe041,0x301fc1,0x8105fc0,0x8105fbf,0x2fdfc1,0x3020c1,0x81060c0,0x81060bf,0x2fe0c1,0x8306041,0x8305fc1,0x70203e,0x6fe03e,0x180fa03f,0x180fa040,0x180f9fc0,0x180f9fbf,0x6fdfbe,0x701fbe,0x7020be,0x83060c1,0x180fa0c0,0x180fa0bf,0x6fe0be,0x870603e,0x3101f40,0x3701f3f,0x1b0fdf40,0x1b6fdf3f,0x182fa041,0x182f9fc1,0x182fa0c1,0x8705fbe,0x87060be,0x170213f,0x1102140,0x190fe140,0x196fe13f,0x186fa03e,0x3301f41,0xb305f40,0xb705f3f,0x1b2fdf41,0x1b6f9fbe,0x196fa0be,0x1302141,0x9306140,0x970613f,0x192fe141, 14,0xfe040,0x10203f,0xfe03f,0x101fc0,0xfdfc0,0x101fbf,0xfdfbf,0x1020c0,0xfe0c0,0x1020bf,0xfe0bf,0x102041,0xfe041,0x101fc1,0x8106040,0xfdfc1,0x810603f,0x1020c1,0xfe0c1,0x8105fc0,0x8105fbf,0x81060c0,0x81060bf,0x8106041,0x8105fc1,0x83060c1,0x180fa040,0x180fa03f,0x180f9fc0,0x180f9fbf,0x180fa0c0,0x180fa0bf,0x186fe03e,0x70203e,0x701fbe,0x186fdfbe,0x180fa041,0x182f9fc1,0x1b0fdf40,0x3101f40,0x3701f3f,0x7020be,0x186fe0be,0x1b6fdf3f,0x182fa0c1,0x190fe140,0x1102140,0x870603e,0x8705fbe,0x170213f,0x196fe13f,0x3101f41,0x1b2fdf41,0xb305f40,0xb705f3f,0x87060be,0x9302042,0x192fe042,0x1302141,0x192fe141,0x9306140,0x970613f,0x13301fc2, 17,0xfe040,0x10203f,0x101fc0,0xfdfc0,0xfe03f,0x1020c0,0x102041,0xfe041,0xfe0c0,0x101fbf,0xfdfbf,0x1020bf,0xfe0bf,0x101fc1,0xfdfc1,0x1020c1,0xfe0c1,0x8106040,0x810603f,0x8105fc0,0x8106041,0x81060c0,0x8105fbf,0x81060bf,0x8105fc1,0x81060c1,0x180fa040,0x180f9fc0,0x180fa03f,0x180fa0c0,0x180fa041,0x180f9fbf,0x180fa0bf,0x180f9fc1,0x180fa0c1,0x70203e,0x186fe03e,0x3101f40,0x1b0fdf40,0x3101f3f,0x3701fbe,0x186fdfbe,0x1b6fdf3f,0x3101f41,0x1b0fdf41,0x8302042,0x182fe042,0x9102140,0x7020be,0x186fe0be,0x190fe140,0x970213f,0x196fe13f,0x9102141,0xb301fc2,0x1b2fdfc2,0x93020c2,0x182fe0c2,0x192fe141,0x970603e,0xb305f40,0xb105f3f,0xb705fbe, 11,0x10203f,0x101fc0,0x101fbf,0xfdfbf,0xfe03f,0xfe040,0xfdfc0,0x105fc0,0x106040,0x10603f,0x105fbf,0x11020bf,0x11020c0,0x302041,0x301fc1,0x2fdfc1,0x2fe041,0x10fe0c0,0x10fe0bf,0x70203e,0x701fbe,0x3101f3f,0x3101f40,0x30fdf40,0x30fdf3f,0x6fdfbe,0x6fe03e,0x11060bf,0x11060c0,0x306041,0x305fc1,0x3105f40,0x3105f3f,0x705fbe,0x70603e,0x180fa03f,0x180fa040,0x180f9fc0,0x180f9fbf,0x13020c1,0x12fe0c1,0x17020be,0x16fe0be,0x3301f41,0x32fdf41,0x93060c1,0x3701f3e,0x36fdf3e,0x97060be,0xb305f41,0x182f9fc1,0x182fa041,0x192fa0c0,0x190fa0bf,0x196fa03e,0x186f9fbe,0xb705f3e,0xb709fbf,0xb309fc0,0x930a040,0x970a03f,0x1b6f9f3f,0x1b2f9f40, 11,0x101fc0,0x10203f,0x101fbf,0xfdfc0,0xfe040,0xfe03f,0xfdfbf,0x105fc0,0x106040,0x10603f,0x105fbf,0x301fc1,0x302041,0x2fe041,0x2fdfc1,0x11020c0,0x11020bf,0x10fe0c0,0x10fe0bf,0x306041,0x305fc1,0x3101f40,0x3101f3f,0x30fdf40,0x30fdf3f,0x701fbe,0x70203e,0x11060c0,0x11060bf,0x6fe03e,0x6fdfbe,0x13020c1,0x12fe0c1,0x3105f40,0x3105f3f,0x180f9fc0,0x180fa040,0x180fa03f,0x180f9fbf,0x3301f41,0x32fdf41,0x705fbe,0x70603e,0x93060c1,0xb305f41,0x17020be,0x16fe0be,0x182fa041,0x182f9fc1,0x192fa0c0,0x190fa0bf,0x3701f3e,0x36fdf3e,0x1b0f9f3f,0x1b2f9f40,0x97060be,0x970a03f,0x930a040,0xb309fc0,0xb709fbf,0xb705f3e,0x1b6f9fbe,0x196fa03e, 15,0x101fc0,0x101fbf,0x10203f,0xfe040,0xfdfc0,0xfdfbf,0xfe03f,0x102041,0x101fc1,0x105fc0,0x106040,0x10603f,0x105fbf,0xfdfc1,0xfe041,0x11020c0,0x106041,0x105fc1,0x11020bf,0x10fe0c0,0x10fe0bf,0x3101f40,0x3101f3f,0x30fdf40,0x30fdf3f,0x11020c1,0x11060c0,0x11060bf,0x10fe0c1,0x3101f41,0x3105f40,0x3105f3f,0x701fbe,0x70203e,0x180fa040,0x180f9fc0,0x30fdf41,0x180f9fbf,0x180fa03f,0x186fe03e,0x186fdfbe,0x93060c1,0xb305f41,0x705fbe,0x70603e,0x180fa041,0x180f9fc1,0x192fa0c0,0x190fa0bf,0x97020be,0x196fe0be,0xb701f3e,0x36fdf3e,0x1b2f9f40,0x1b6f9f3f,0xb301fc2,0x9302042,0x192fe042,0x1b2fdfc2,0xb309fc0,0x930a040,0x970a03f,0xb709fbf, 15,0x101fc0,0xfdfc0,0xfe040,0x10203f,0x101fbf,0xfdfbf,0xfe03f,0x102041,0x101fc1,0xfdfc1,0xfe041,0x106040,0x105fc0,0x105fbf,0x10603f,0x106041,0x105fc1,0x11020c0,0x10fe0c0,0x11020bf,0x10fe0bf,0x3101f40,0x30fdf40,0x11020c1,0x10fe0c1,0x11060c0,0x3101f3f,0x30fdf3f,0x3101f41,0x30fdf41,0x3105f40,0x11060bf,0x91060c1,0x180fa040,0x180f9fc0,0x180f9fbf,0x3105f3f,0xb105f41,0x180fa03f,0x180fa041,0x180f9fc1,0x3701fbe,0x70203e,0x186fe03e,0x1b6fdfbe,0x3705fbe,0x70603e,0x1302042,0x3301fc2,0x1b2fdfc2,0x192fe042,0x190fa0c0,0x196fa0bf,0x192fa0c1,0x1b2f9f40,0x1b6f9f3f,0xb309fc0,0x930a040,0x9306042,0xb305fc2,0xb709fbf,0x970a03f,0x117020be, 11,0x10203f,0x101fc0,0x101fbf,0xfe03f,0xfe040,0xfdfc0,0xfdfbf,0x10603f,0x106040,0x105fc0,0x105fbf,0x11020bf,0x11020c0,0x10fe0c0,0x10fe0bf,0x302041,0x301fc1,0x2fe041,0x2fdfc1,0x11060c0,0x11060bf,0x70203e,0x701fbe,0x6fe03e,0x6fdfbe,0x3101f3f,0x3101f40,0x306041,0x305fc1,0x30fdf40,0x30fdf3f,0x13020c1,0x12fe0c1,0x70603e,0x705fbe,0x180fa03f,0x180fa040,0x180f9fc0,0x180f9fbf,0x17020be,0x16fe0be,0x3105f3f,0x3105f40,0x93060c1,0x97060be,0x3301f41,0x32fdf41,0x190fa0c0,0x190fa0bf,0x192fa041,0x182f9fc1,0x3701f3e,0x36fdf3e,0x186f9fbe,0x196fa03e,0xb305f41,0xb309fc0,0x930a040,0x970a03f,0xb709fbf,0xb705f3e,0x1b6f9f3f,0x1b2f9f40, 11,0x10203f,0x101fc0,0x101fbf,0xfe040,0xfe03f,0xfdfc0,0xfdfbf,0x106040,0x10603f,0x105fc0,0x105fbf,0x302041,0x11020c0,0x11020bf,0x301fc1,0x2fe041,0x10fe0c0,0x10fe0bf,0x2fdfc1,0x306041,0x11060c0,0x11060bf,0x305fc1,0x13020c1,0x12fe0c1,0x70203e,0x701fbe,0x3101f3f,0x3101f40,0x30fdf40,0x30fdf3f,0x6fdfbe,0x6fe03e,0x180fa03f,0x180fa040,0x180f9fc0,0x180f9fbf,0x93060c1,0x70603e,0x705fbe,0x3105f3f,0x3105f40,0x3301f41,0x32fdf41,0x17020be,0x16fe0be,0x190fa0bf,0x190fa0c0,0x182fa041,0x182f9fc1,0xb305f41,0x97060be,0x970a03f,0x930a040,0xb309fc0,0xb709fbf,0xb701f3e,0x36fdf3e,0x1b0f9f3f,0x1b2f9f40,0x192fa0c1,0x196fa03e,0x1b6f9fbe, 15,0x101fc0,0x10203f,0xfe040,0xfdfc0,0x101fbf,0xfe03f,0xfdfbf,0x102041,0x106040,0x105fc0,0x101fc1,0xfe041,0xfdfc1,0x10603f,0x105fbf,0x11020c0,0x11020bf,0x10fe0c0,0x10fe0bf,0x106041,0x105fc1,0x11020c1,0x11060c0,0x11060bf,0x10fe0c1,0x3101f40,0x30fdf40,0x3101f3f,0x30fdf3f,0x93060c1,0x70203e,0x701fbe,0x180fa040,0x1b0f9fc0,0x180fa03f,0x186fe03e,0x6fdfbe,0x1b6f9fbf,0x3101f41,0x3105f40,0x3105f3f,0x30fdf41,0x1b0f9fc1,0x180fa041,0x70603e,0x705fbe,0x17020be,0x16fe0be,0x190fa0c0,0x196fa0bf,0xb305f41,0xb309fc0,0x930a040,0x970a03f,0x97060be,0x9302042,0xb301fc2,0x192fe042,0x192fa0c1,0x1b2fdfc2,0xb709fbf,0xb701f3e,0x1b6fdf3e, 14,0x101fc0,0xfe040,0xfdfc0,0x10203f,0x101fbf,0xfe03f,0xfdfbf,0x102041,0x101fc1,0xfe041,0xfdfc1,0x106040,0x105fc0,0x10603f,0x11020c0,0x105fbf,0x10fe0c0,0x106041,0x105fc1,0x11020bf,0x10fe0bf,0x11020c1,0x10fe0c1,0x11060c0,0x11060bf,0x91060c1,0x3101f40,0x30fdf40,0x3101f3f,0x30fdf3f,0x3101f41,0x30fdf41,0x1b0f9fc0,0x180fa040,0x180fa03f,0x1b0f9fbf,0x3105f40,0xb105f3f,0x3701fbe,0x70203e,0x186fe03e,0x180fa041,0x1b0f9fc1,0x1b6fdfbe,0xb105f41,0x3301fc2,0x302042,0x190fa0c0,0x190fa0bf,0x182fe042,0x1b2fdfc2,0x70603e,0xb705fbe,0x97020be,0x196fe0be,0x190fa0c1,0x930a040,0xb309fc0,0x8306042,0xb305fc2,0x93020c2,0x192fe0c2,0xa70a03f, 15,0x10203f,0x101fbf,0x101fc0,0xfe040,0xfe03f,0xfdfbf,0xfdfc0,0x1020c0,0x1020bf,0x10603f,0x106040,0x105fc0,0x105fbf,0xfe0bf,0xfe0c0,0x302041,0x1060c0,0x1060bf,0x301fc1,0x2fe041,0x2fdfc1,0x70203e,0x701fbe,0x6fe03e,0x6fdfbe,0x3020c1,0x306041,0x305fc1,0x2fe0c1,0x7020be,0x70603e,0x705fbe,0x3101f3f,0x3101f40,0x180fa040,0x180fa03f,0x6fe0be,0x180f9fbf,0x180f9fc0,0x1b0fdf40,0x1b0fdf3f,0x93060c1,0x97060be,0x3105f3f,0x3105f40,0x180fa0c0,0x180fa0bf,0x192fa041,0x182f9fc1,0xb301f41,0x1b2fdf41,0xb701f3e,0x36fdf3e,0x196fa03e,0x1b6f9fbe,0x970213f,0x9302140,0x192fe140,0x196fe13f,0x970a03f,0x930a040,0xb309fc0,0xb709fbf, 15,0x10203f,0x101fc0,0xfe040,0xfe03f,0x101fbf,0xfdfc0,0xfdfbf,0x1020c0,0x106040,0x10603f,0x1020bf,0xfe0c0,0xfe0bf,0x105fc0,0x105fbf,0x302041,0x301fc1,0x2fe041,0x2fdfc1,0x1060c0,0x1060bf,0x3020c1,0x306041,0x305fc1,0x2fe0c1,0x70203e,0x6fe03e,0x701fbe,0x6fdfbe,0x93060c1,0x3101f40,0x3101f3f,0x180fa040,0x186fa03f,0x180f9fc0,0x1b0fdf40,0x30fdf3f,0x1b6f9fbf,0x7020be,0x70603e,0x705fbe,0x6fe0be,0x186fa0bf,0x180fa0c0,0x3105f40,0x3105f3f,0x3301f41,0x32fdf41,0x182fa041,0x1b2f9fc1,0x97060be,0x970a03f,0x930a040,0xb309fc0,0xb305f41,0x9302140,0x970213f,0x192fe140,0x192fa0c1,0x196fe13f,0xb709fbf,0xb701f3e,0x1b6fdf3e, 16,0x10203f,0x101fc0,0xfe040,0xfe03f,0x101fbf,0xfdfc0,0xfdfbf,0x102041,0x1020c0,0x106040,0x10603f,0x1020bf,0xfe0c0,0xfe041,0x101fc1,0x105fc0,0x105fbf,0xfe0bf,0xfdfc1,0x1020c1,0x106041,0x1060c0,0x1060bf,0xfe0c1,0x105fc1,0x93060c1,0x70203e,0x3101f40,0x180fa040,0x180fa03f,0x186fe03e,0x701fbe,0x3701f3f,0x30fdf40,0x1b0f9fc0,0x180f9fbf,0x186fdfbe,0x1b6fdf3f,0x3101f41,0x3105f40,0xb105f3f,0x70603e,0x7020be,0x6fe0be,0x180fa0c0,0x180fa041,0x182f9fc1,0x1b2fdf41,0xb705fbe,0x186fa0bf,0x192fa0c1,0x97060be,0xb305f41,0x9302042,0x192fe042,0x13301fc2,0x930a040,0x970a03f,0xb509fc0,0x9302140,0x970213f,0x192fe140,0x196fe13f, 15,0x101fc0,0xfe040,0xfdfc0,0x10203f,0x101fbf,0xfe03f,0x102041,0x101fc1,0xfdfbf,0xfe041,0x1020c0,0x106040,0xfdfc1,0x105fc0,0xfe0c0,0x1020bf,0x10603f,0x105fbf,0xfe0bf,0x1020c1,0x106041,0x105fc1,0xfe0c1,0x1060c0,0x11060bf,0x91060c1,0x3101f40,0x180fa040,0x180f9fc0,0x1b0fdf40,0x3101f3f,0x30fdf3f,0x180fa03f,0x1b0f9fbf,0x180fa041,0x180f9fc1,0x3101f41,0x1b0fdf41,0x70203e,0x3701fbe,0x186fe03e,0x1b6fdfbe,0x3105f40,0xb105f3f,0x180fa0c0,0x190fa0bf,0x192fa0c1,0x302042,0x3301fc2,0xb305f41,0x182fe042,0x1b2fdfc2,0x17020be,0x170603e,0xb705fbe,0x196fe0be,0x9502140,0x194fe140,0x193020c2,0xa306042,0x930a040,0xb309fc0,0xa70a03f, 15,0x10203f,0xfe03f,0xfe040,0x101fc0,0x101fbf,0xfdfbf,0xfdfc0,0x1020c0,0x1020bf,0xfe0bf,0xfe0c0,0x106040,0x10603f,0x105fbf,0x105fc0,0x1060c0,0x1060bf,0x302041,0x2fe041,0x301fc1,0x2fdfc1,0x70203e,0x6fe03e,0x3020c1,0x2fe0c1,0x306041,0x701fbe,0x6fdfbe,0x7020be,0x6fe0be,0x70603e,0x305fc1,0x83060c1,0x180fa040,0x180fa03f,0x180f9fbf,0x705fbe,0x87060be,0x180f9fc0,0x180fa0c0,0x180fa0bf,0x3701f3f,0x3101f40,0x1b0fdf40,0x1b6fdf3f,0x3705f3f,0x3105f40,0x1302140,0x170213f,0x196fe13f,0x192fe140,0x182fa041,0x1b2f9fc1,0x192fa0c1,0x196fa03e,0x1b6f9fbe,0x970a03f,0x930a040,0x9306140,0x970613f,0xb709fbf,0xb309fc0,0x13301f41, 14,0x10203f,0xfe040,0xfe03f,0x101fc0,0x101fbf,0xfdfc0,0xfdfbf,0x1020c0,0x1020bf,0xfe0c0,0xfe0bf,0x106040,0x10603f,0x105fc0,0x302041,0x105fbf,0x2fe041,0x1060c0,0x1060bf,0x301fc1,0x2fdfc1,0x3020c1,0x2fe0c1,0x306041,0x305fc1,0x83060c1,0x70203e,0x6fe03e,0x701fbe,0x6fdfbe,0x7020be,0x6fe0be,0x186fa03f,0x180fa040,0x180f9fc0,0x186f9fbf,0x70603e,0x8705fbe,0x3701f3f,0x3101f40,0x1b0fdf40,0x180fa0c0,0x186fa0bf,0x1b6fdf3f,0x87060be,0x170213f,0x1102140,0x182fa041,0x182f9fc1,0x190fe140,0x196fe13f,0x3105f40,0xb705f3f,0xb301f41,0x1b2fdf41,0x182fa0c1,0x930a040,0x970a03f,0x9106140,0x970613f,0x9302141,0x192fe141,0xb509fc0, 15,0x10203f,0xfe040,0xfe03f,0x101fc0,0x101fbf,0xfdfc0,0x1020c0,0x1020bf,0xfdfbf,0xfe0c0,0x102041,0x106040,0xfe0bf,0x10603f,0xfe041,0x101fc1,0x105fc0,0x105fbf,0xfdfc1,0x1020c1,0x1060c0,0x1060bf,0xfe0c1,0x106041,0x305fc1,0x83060c1,0x70203e,0x180fa040,0x180fa03f,0x186fe03e,0x701fbe,0x6fdfbe,0x180f9fc0,0x186f9fbf,0x180fa0c0,0x180fa0bf,0x7020be,0x186fe0be,0x3101f40,0x3701f3f,0x1b0fdf40,0x1b6fdf3f,0x70603e,0x8705fbe,0x180fa041,0x182f9fc1,0x192fa0c1,0x1102140,0x170213f,0x97060be,0x190fe140,0x196fe13f,0x3301f41,0x3305f40,0xb705f3f,0x1b2fdf41,0xa302042,0x1a2fe042,0x19302141,0x9506140,0x930a040,0x970a03f,0xb509fc0, 17,0xfe040,0x10203f,0x101fc0,0xfdfc0,0xfe03f,0x1020c0,0x102041,0x101fbf,0xfe041,0xfe0c0,0x106040,0xfdfbf,0x1020bf,0x101fc1,0xfdfc1,0xfe0bf,0x1020c1,0x10603f,0x105fc0,0xfe0c1,0x1060c0,0x106041,0x8105fbf,0x81060bf,0x8105fc1,0x81060c1,0x180fa040,0x180f9fc0,0x180fa03f,0x180fa0c0,0x180fa041,0x180f9fbf,0x70203e,0x186fe03e,0x3101f40,0x1b0fdf40,0x180f9fc1,0x180fa0bf,0x701fbe,0x3701f3f,0x1b0fdf3f,0x1b6fdfbe,0x7020be,0x186fe0be,0x192fa0c1,0x9102140,0x190fe140,0x8302042,0x3101f41,0x1b0fdf41,0x182fe042,0xb301fc2,0xb305f40,0x870603e,0x970213f,0x196fe13f,0x11102141,0x113020c2,0x1b2fdfc2,0xb105f3f,0xb705fbe,0x97060be,0xa50a040, 11,0x10203f,0x101fc0,0x101fbf,0xfdfbf,0xfe03f,0xfe040,0xfdfc0,0x105fc0,0x106040,0x10603f,0x105fbf,0x11020bf,0x11020c0,0x302041,0x301fc1,0x2fdfc1,0x2fe041,0x10fe0c0,0x10fe0bf,0x70203e,0x701fbe,0x3101f3f,0x3101f40,0x305fc1,0x306041,0x11060c0,0x11060bf,0x6fe03e,0x6fdfbe,0x30fdf3f,0x30fdf40,0x3105f40,0x3105f3f,0x705fbe,0x70603e,0x13020c1,0x12fe0c1,0x180fa040,0x180fa03f,0x180f9fbf,0x180f9fc0,0x3301f41,0x17020be,0x16fe0be,0x93060c1,0x32fdf41,0xb305f41,0x3701f3e,0x36fdf3e,0x97060be,0x970a03f,0x930a040,0xb309fc0,0xb709fbf,0xb705f3e,0x182f9fc1,0x182fa041,0x192fa0c0,0x190fa0bf,0x196fa03e,0x186f9fbe,0x1b6f9f3f,0x1b2f9f40, 11,0x101fc0,0x10203f,0x101fbf,0xfdfc0,0xfe040,0xfe03f,0xfdfbf,0x105fc0,0x106040,0x10603f,0x105fbf,0x301fc1,0x302041,0x2fe041,0x2fdfc1,0x11020c0,0x11020bf,0x306041,0x305fc1,0x10fe0c0,0x10fe0bf,0x3101f40,0x3101f3f,0x11060c0,0x11060bf,0x70203e,0x30fdf40,0x30fdf3f,0x701fbe,0x3105f40,0x3105f3f,0x13020c1,0x6fe03e,0x6fdfbe,0x705fbe,0x70603e,0x12fe0c1,0x3301f41,0x13060c1,0x32fdf41,0x1b0f9fc0,0x180fa040,0x186fa03f,0x1b6f9fbf,0x3305f41,0xb109fc0,0x17020be,0x16fe0be,0x810a040,0x870a03f,0xb709fbf,0x3701f3e,0x1b6fdf3e,0x17060be,0x182fa041,0x1b2f9fc1,0x192fa0c0,0x196fa0bf,0xb705f3e,0xb309fc1,0x830a041,0x930a0c0,0x970a0bf, 15,0x101fc0,0x101fbf,0x10203f,0xfe040,0xfdfc0,0xfdfbf,0xfe03f,0x106040,0x105fc0,0x105fbf,0x10603f,0x102041,0x101fc1,0xfdfc1,0xfe041,0x106041,0x105fc1,0x11020c0,0x11020bf,0x10fe0c0,0x10fe0bf,0x3101f40,0x3101f3f,0x11060c0,0x11060bf,0x11020c1,0x30fdf40,0x30fdf3f,0x3105f40,0x3105f3f,0x3101f41,0x10fe0c1,0x13060c1,0x70203e,0x701fbe,0x6fdfbe,0x30fdf41,0x3305f41,0x6fe03e,0x70603e,0x705fbe,0x1b0f9fc0,0x180fa040,0x186fa03f,0x1b6f9fbf,0x1b0f9fc1,0x180fa041,0x910a040,0xb109fc0,0xb709fbf,0x970a03f,0x17020be,0x196fe0be,0x97060be,0xb701f3e,0x1b6fdf3e,0xb301fc2,0x9302042,0x930a041,0xb309fc1,0x1b2fdfc2,0x192fe042,0x194fa0c0, 17,0x101fc0,0x101fbf,0x10203f,0xfe040,0xfdfc0,0x101fc1,0x102041,0x106040,0x105fc0,0xfdfbf,0xfe03f,0x10603f,0x105fbf,0xfdfc1,0xfe041,0x106041,0x105fc1,0x11020c0,0x11020bf,0x10fe0c0,0x11020c1,0x11060c0,0x3101f40,0x3101f3f,0x30fdf40,0x10fe0bf,0x11060bf,0x10fe0c1,0x3101f41,0x3105f40,0x30fdf3f,0x11060c1,0x3105f3f,0x30fdf41,0x3105f41,0x3701fbe,0x70203e,0x180fa040,0x1b0f9fc0,0x1b0f9fbf,0x180fa03f,0x186fe03e,0x1b6fdfbe,0x3705fbe,0x70603e,0x910a040,0xb109fc0,0x3301fc2,0x1302042,0x180fa041,0x1b0f9fc1,0x1b2fdfc2,0x192fe042,0x1306042,0x3305fc2,0xb709fbf,0x970a03f,0x930a041,0xb309fc1,0x97020be,0x192fa0c0,0x190fa0bf,0x196fe0be, 11,0x10203f,0x101fc0,0x101fbf,0xfe03f,0xfe040,0xfdfc0,0xfdfbf,0x10603f,0x106040,0x105fc0,0x105fbf,0x11020bf,0x11020c0,0x10fe0c0,0x10fe0bf,0x302041,0x301fc1,0x11060c0,0x11060bf,0x2fe041,0x2fdfc1,0x70203e,0x701fbe,0x306041,0x305fc1,0x3101f40,0x6fe03e,0x6fdfbe,0x3101f3f,0x70603e,0x705fbe,0x13020c1,0x30fdf40,0x30fdf3f,0x3105f3f,0x3105f40,0x12fe0c1,0x17020be,0x13060c1,0x16fe0be,0x186fa03f,0x180fa040,0x1b0f9fc0,0x1b6f9fbf,0x17060be,0x870a03f,0x3301f41,0x32fdf41,0x810a040,0xb109fc0,0xb709fbf,0x3701f3e,0x1b6fdf3e,0x3305f41,0x190fa0c0,0x196fa0bf,0x192fa041,0x1b2f9fc1,0xb705f3e,0x970a0bf,0x910a0c0,0x930a041,0xb309fc1, 11,0x10203f,0x101fc0,0x101fbf,0xfe040,0xfe03f,0xfdfc0,0xfdfbf,0x106040,0x10603f,0x105fc0,0x105fbf,0x302041,0x11020c0,0x11020bf,0x301fc1,0x2fe041,0x10fe0c0,0x10fe0bf,0x2fdfc1,0x306041,0x11060c0,0x11060bf,0x305fc1,0x13020c1,0x12fe0c1,0x70203e,0x701fbe,0x3101f3f,0x3101f40,0x30fdf40,0x30fdf3f,0x6fdfbe,0x6fe03e,0x70603e,0x13060c1,0x3105f40,0x3105f3f,0x705fbe,0x17020be,0x180fa040,0x186fa03f,0x1b0f9fc0,0x1b6f9fbf,0x3301f41,0x32fdf41,0x3305f41,0x16fe0be,0x17060be,0x870a03f,0x810a040,0xb109fc0,0xb709fbf,0x3701f3e,0x182fa041,0x192fa0c0,0x196fa0bf,0x1b2f9fc1,0x1b6fdf3e,0xb705f3e,0x830a041,0x930a0c0,0x970a0bf,0xb309fc1, 14,0x101fc0,0x10203f,0x101fbf,0xfe040,0xfdfc0,0xfe03f,0xfdfbf,0x106040,0x105fc0,0x10603f,0x105fbf,0x102041,0x101fc1,0xfe041,0x11020c0,0xfdfc1,0x11020bf,0x106041,0x105fc1,0x10fe0c0,0x10fe0bf,0x11060c0,0x11060bf,0x11020c1,0x10fe0c1,0x13060c1,0x3101f40,0x3101f3f,0x30fdf40,0x30fdf3f,0x3105f40,0x3105f3f,0x3701fbe,0x70203e,0x6fe03e,0x36fdfbe,0x3101f41,0x32fdf41,0x1b0f9fc0,0x180fa040,0x186fa03f,0x70603e,0x3705fbe,0x1b6f9fbf,0x3305f41,0xb109fc0,0x810a040,0x17020be,0x16fe0be,0x870a03f,0xb709fbf,0x180fa041,0x1b2f9fc1,0x192fa0c0,0x196fa0bf,0x17060be,0x9302042,0xb301fc2,0x830a041,0xb309fc1,0x930a0c0,0x970a0bf,0x1a2fe042, 17,0x101fc0,0x10203f,0xfe040,0xfdfc0,0x101fbf,0x106040,0x102041,0x101fc1,0x105fc0,0xfe03f,0xfdfbf,0x10603f,0x105fbf,0xfe041,0xfdfc1,0x106041,0x105fc1,0x11020c0,0x11020bf,0x10fe0c0,0x11020c1,0x11060c0,0x10fe0bf,0x11060bf,0x10fe0c1,0x11060c1,0x3101f40,0x30fdf40,0x3101f3f,0x3105f40,0x3101f41,0x30fdf3f,0x3105f3f,0x30fdf41,0x3105f41,0x70203e,0x3701fbe,0x180fa040,0x1b0f9fc0,0x180fa03f,0x186fe03e,0x36fdfbe,0x1b6f9fbf,0x180fa041,0x1b0f9fc1,0x1302042,0x3301fc2,0x910a040,0x70603e,0x3705fbe,0xb109fc0,0x970a03f,0xb709fbf,0x910a041,0x192fe042,0x1b2fdfc2,0x9306042,0x3305fc2,0xb309fc1,0x97020be,0x192fa0c0,0x190fa0bf,0x196fe0be, 15,0x10203f,0x101fbf,0x101fc0,0xfe040,0xfe03f,0xfdfbf,0xfdfc0,0x106040,0x10603f,0x105fbf,0x105fc0,0x1020c0,0x1020bf,0xfe0bf,0xfe0c0,0x1060c0,0x1060bf,0x302041,0x301fc1,0x2fe041,0x2fdfc1,0x70203e,0x701fbe,0x306041,0x305fc1,0x3020c1,0x6fe03e,0x6fdfbe,0x70603e,0x705fbe,0x7020be,0x2fe0c1,0x13060c1,0x3101f40,0x3101f3f,0x30fdf3f,0x6fe0be,0x17060be,0x30fdf40,0x3105f40,0x3105f3f,0x186fa03f,0x180fa040,0x1b0f9fc0,0x1b6f9fbf,0x186fa0bf,0x180fa0c0,0x830a040,0x870a03f,0xb709fbf,0xb309fc0,0x3301f41,0x1b2fdf41,0xb305f41,0xb701f3e,0x1b6fdf3e,0x970213f,0x9302140,0x930a0c0,0x970a0bf,0x196fe13f,0x192fe140,0x1a2fa041, 14,0x10203f,0x101fc0,0x101fbf,0xfe040,0xfe03f,0xfdfc0,0xfdfbf,0x106040,0x10603f,0x105fc0,0x105fbf,0x1020c0,0x1020bf,0xfe0c0,0x302041,0xfe0bf,0x301fc1,0x1060c0,0x1060bf,0x2fe041,0x2fdfc1,0x306041,0x305fc1,0x3020c1,0x2fe0c1,0x13060c1,0x70203e,0x701fbe,0x6fe03e,0x6fdfbe,0x70603e,0x705fbe,0x3701f3f,0x3101f40,0x30fdf40,0x36fdf3f,0x7020be,0x16fe0be,0x186fa03f,0x180fa040,0x1b0f9fc0,0x3105f40,0x3705f3f,0x1b6f9fbf,0x17060be,0x870a03f,0x810a040,0x3301f41,0x32fdf41,0xb109fc0,0xb709fbf,0x180fa0c0,0x196fa0bf,0x192fa041,0x1b2f9fc1,0x3305f41,0x9302140,0x970213f,0x910a0c0,0x970a0bf,0x930a041,0xb309fc1,0x194fe140, 15,0x10203f,0x101fc0,0x101fbf,0xfe040,0xfe03f,0xfdfc0,0x106040,0x10603f,0xfdfbf,0x105fc0,0x102041,0x1020c0,0x105fbf,0x1020bf,0x101fc1,0xfe041,0xfe0c0,0xfe0bf,0xfdfc1,0x106041,0x1060c0,0x1060bf,0x105fc1,0x1020c1,0x2fe0c1,0x13060c1,0x70203e,0x3101f40,0x3101f3f,0x3701fbe,0x6fe03e,0x6fdfbe,0x30fdf40,0x36fdf3f,0x3105f40,0x3105f3f,0x70603e,0x3705fbe,0x180fa040,0x186fa03f,0x1b0f9fc0,0x1b6f9fbf,0x7020be,0x16fe0be,0x3101f41,0x32fdf41,0xb305f41,0x810a040,0x870a03f,0x97060be,0xb109fc0,0xb709fbf,0x182fa041,0x182fa0c0,0x196fa0bf,0x1b2f9fc1,0x11302042,0x13301fc2,0xb30a041,0x950a0c0,0x9302140,0x970213f,0x194fe140, 17,0x101fc0,0x10203f,0xfe040,0xfdfc0,0x101fbf,0x106040,0x102041,0xfe03f,0x101fc1,0x105fc0,0x1020c0,0xfdfbf,0x10603f,0xfe041,0xfdfc1,0x105fbf,0x106041,0x1020bf,0xfe0c0,0x105fc1,0x1060c0,0x1020c1,0x10fe0bf,0x11060bf,0x10fe0c1,0x11060c1,0x3101f40,0x30fdf40,0x3101f3f,0x3105f40,0x3101f41,0x30fdf3f,0x70203e,0x3701fbe,0x180fa040,0x1b0f9fc0,0x30fdf41,0x3105f3f,0x6fe03e,0x186fa03f,0x1b0f9fbf,0x1b6fdfbe,0x70603e,0x3705fbe,0xb305f41,0x910a040,0xb109fc0,0x1302042,0x180fa041,0x1b0f9fc1,0x3301fc2,0x192fe042,0x192fa0c0,0x17020be,0x970a03f,0xb709fbf,0xa10a041,0xa306042,0x1b2fdfc2,0x190fa0bf,0x196fe0be,0x97060be,0x11502140, 17,0x10203f,0x101fbf,0x101fc0,0xfe040,0xfe03f,0x1020bf,0x1020c0,0x106040,0x10603f,0xfdfbf,0xfdfc0,0x105fc0,0x105fbf,0xfe0bf,0xfe0c0,0x1060c0,0x1060bf,0x302041,0x301fc1,0x2fe041,0x3020c1,0x306041,0x70203e,0x701fbe,0x6fe03e,0x2fdfc1,0x305fc1,0x2fe0c1,0x7020be,0x70603e,0x6fdfbe,0x3060c1,0x705fbe,0x6fe0be,0x7060be,0x3701f3f,0x3101f40,0x180fa040,0x186fa03f,0x186f9fbf,0x180f9fc0,0x1b0fdf40,0x1b6fdf3f,0x3705f3f,0x3105f40,0x830a040,0x870a03f,0x170213f,0x1302140,0x180fa0c0,0x186fa0bf,0x196fe13f,0x192fe140,0x1306140,0x170613f,0xb709fbf,0xb309fc0,0x930a0c0,0x970a0bf,0xb301f41,0x192fa041,0x182f9fc1,0x1b2fdf41, 17,0x10203f,0x101fc0,0xfe040,0xfe03f,0x101fbf,0x106040,0x1020c0,0x1020bf,0x10603f,0xfdfc0,0xfdfbf,0x105fc0,0x105fbf,0xfe0c0,0xfe0bf,0x1060c0,0x1060bf,0x302041,0x301fc1,0x2fe041,0x3020c1,0x306041,0x2fdfc1,0x305fc1,0x2fe0c1,0x3060c1,0x70203e,0x6fe03e,0x701fbe,0x70603e,0x7020be,0x6fdfbe,0x705fbe,0x6fe0be,0x7060be,0x3101f40,0x3701f3f,0x180fa040,0x186fa03f,0x180f9fc0,0x1b0fdf40,0x36fdf3f,0x1b6f9fbf,0x180fa0c0,0x186fa0bf,0x1302140,0x170213f,0x830a040,0x3105f40,0x3705f3f,0x870a03f,0xb309fc0,0xb709fbf,0x830a0c0,0x192fe140,0x196fe13f,0x9306140,0x170613f,0x970a0bf,0xb301f41,0x192fa041,0x182f9fc1,0x1b2fdf41, 17,0x10203f,0x101fc0,0xfe040,0xfe03f,0x101fbf,0x106040,0x1020c0,0xfdfc0,0x1020bf,0x10603f,0x102041,0xfdfbf,0x105fc0,0xfe0c0,0xfe0bf,0x105fbf,0x1060c0,0x101fc1,0xfe041,0x1060bf,0x106041,0x1020c1,0x2fdfc1,0x305fc1,0x2fe0c1,0x3060c1,0x70203e,0x6fe03e,0x701fbe,0x70603e,0x7020be,0x6fdfbe,0x3101f40,0x3701f3f,0x180fa040,0x186fa03f,0x6fe0be,0x705fbe,0x30fdf40,0x1b0f9fc0,0x186f9fbf,0x1b6fdf3f,0x3105f40,0x3705f3f,0x97060be,0x830a040,0x870a03f,0x1302140,0x180fa0c0,0x186fa0bf,0x170213f,0x192fe140,0x192fa041,0x3301f41,0xb309fc0,0xb709fbf,0x850a0c0,0x9506140,0x196fe13f,0x182f9fc1,0x1b2fdf41,0xb305f41,0x12302042, 16,0x10203f,0x101fc0,0xfe040,0x102041,0x1020c0,0x106040,0x101fbf,0xfe03f,0xfdfc0,0x101fc1,0x105fc0,0x10603f,0x1020bf,0xfe0c0,0xfe041,0xfdfbf,0x1020c1,0x106041,0x1060c0,0x105fbf,0xfe0bf,0xfdfc1,0x105fc1,0x1060bf,0xfe0c1,0x83060c1,0x70203e,0x3101f40,0x180fa040,0x180fa03f,0x186fe03e,0x701fbe,0x3701f3f,0x30fdf40,0x1b0f9fc0,0x180fa041,0x180fa0c0,0x7020be,0x70603e,0x3105f40,0xb101f41,0x9302042,0x1102140,0x930a040,0x6fdfbe,0x36fdf3f,0x1b6f9fbf,0x190fa0bf,0x196fe0be,0x170213f,0x196fe140,0x182f9fc1,0x1b2fdf41,0xb301fc2,0x1a2fe042,0x192fa0c1,0x8705fbe,0xb705f3f,0xb309fc0,0xa70a03f,0x97060be,0x9706140,0x11302141 }; travis-src-190101/src/v_cell.cpp0100777000000000000000000021105513412725624013413 0ustar00/***************************************************************************** TRAVIS - Trajectory Analyzer and Visualizer http://www.travis-analyzer.de/ Copyright (c) 2009-2019 Martin Brehm 2012-2019 Martin Thomas 2016-2019 Sascha Gehrke --------------------------------------------------------------------------- This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . *****************************************************************************/ // Voro++, a 3D cell-based Voronoi library // // Author : Chris H. Rycroft (LBL / UC Berkeley) // Email : chr@alum.mit.edu // Date : August 30th 2011 /** \file cell.cc * \brief Function implementations for the voronoicell and related classes. */ // This must always be the first include directive #include "config.h" #include //using namespace std; #include "v_config.h" #include "v_common.h" #include "v_cell.h" #include "tools.h" #include "globalvar.h" const char *GetRevisionInfo_v_cell(unsigned int len) { static char buf[256]; GET_REVISION_INFO( buf, len ); return buf; } const char *GetSourceVersion_v_cell() { static char buf[256]; GET_SOURCE_VERSION( buf ); return buf; } /** Constructs a Voronoi cell and sets up the initial memory. */ voronoicell_base::voronoicell_base() : current_vertices(init_vertices), current_vertex_order(init_vertex_order), current_delete_size(init_delete_size), current_delete2_size(init_delete2_size), ed(new int*[current_vertices]), nu(new int[current_vertices]), pts(new double[3*current_vertices]), mem(new int[current_vertex_order]), mec(new int[current_vertex_order]), mep(new int*[current_vertex_order]), ds(new int[current_delete_size]), stacke(ds+current_delete_size), ds2(new int[current_delete2_size]), stacke2(ds2+current_delete_size), current_marginal(init_marginal), marg(new int[current_marginal]) { int i; for(i=0;i<3;i++) { mem[i]=init_n_vertices;mec[i]=0; mep[i]=new int[init_n_vertices*((i<<1)+1)]; } mem[3]=init_3_vertices;mec[3]=0; mep[3]=new int[init_3_vertices*7]; for(i=4;i=0;i--) if(mem[i]>0) delete [] mep[i]; delete [] marg; delete [] ds2;delete [] ds; delete [] mep;delete [] mec; delete [] mem;delete [] pts; delete [] nu;delete [] ed; } void voronoicell_base::check_memory_for_copy(voronoicell_neighbor &vc,voronoicell_base* vb) { while(current_vertex_ordercurrent_vertex_order) add_memory_vorder(vc); for(int i=0;imec[i]) add_memory(vc,i,ds2); while(current_verticesp) add_memory_vertices(vc); } /** Copies the vertex and edge information from another class. The routine * assumes that enough memory is available for the copy. * \param[in] vb a pointer to the class to copy. */ void voronoicell_base::copy(voronoicell_base* vb) { int i,j; p=vb->p;up=0; for(i=0;imec[i]; for(j=0;jmep[i][j]; for(j=0;jnu[i]; for(i=0;i<3*p;i++) pts[i]=vb->pts[i]; } /** Copies the information from another voronoicell class into this * class, extending memory allocation if necessary. * \param[in] c the class to copy. */ void voronoicell_neighbor::operator=(voronoicell_neighbor &c) { voronoicell_base *vb=((voronoicell_base*) &c); check_memory_for_copy(*this,vb);copy(vb); int i,j; for(i=0;i=2 fprintf(stderr,"Order %d vertex memory created\n",i); #endif } else { int j=0,k,*l; mem[i]<<=1; if(mem[i]>max_n_vertices) voro_fatal_error("Point memory allocation exceeded absolute maximum",VOROPP_MEMORY_ERROR); #if VOROPP_VERBOSE >=2 fprintf(stderr,"Order %d vertex memory scaled up to %d\n",i,mem[i]); #endif l=new int[s*mem[i]]; int m=0; vc.n_allocate_aux1(i); while(j=0) { ed[k]=l+j; vc.n_set_to_aux1_offset(k,m); } else { int *dsp; for(dsp=ds2;dsp=3 fputs("Relocated dangling pointer",stderr); #endif } for(k=0;kmax_vertices) voro_fatal_error("Vertex memory allocation exceeded absolute maximum",VOROPP_MEMORY_ERROR); #if VOROPP_VERBOSE >=2 fprintf(stderr,"Vertex memory scaled up to %d\n",i); #endif double *ppts; pp=new int*[i]; for(j=0;jmax_vertex_order) voro_fatal_error("Vertex order memory allocation exceeded absolute maximum",VOROPP_MEMORY_ERROR); #if VOROPP_VERBOSE >=2 fprintf(stderr,"Vertex order memory scaled up to %d\n",i); #endif p1=new int[i]; for(j=0;jmax_delete_size) voro_fatal_error("Delete stack 1 memory allocation exceeded absolute maximum",VOROPP_MEMORY_ERROR); #if VOROPP_VERBOSE >=2 fprintf(stderr,"Delete stack 1 memory scaled up to %d\n",current_delete_size); #endif int *dsn=new int[current_delete_size],*dsnp=dsn,*dsp=ds; while(dspmax_delete2_size) voro_fatal_error("Delete stack 2 memory allocation exceeded absolute maximum",VOROPP_MEMORY_ERROR); #if VOROPP_VERBOSE >=2 fprintf(stderr,"Delete stack 2 memory scaled up to %d\n",current_delete2_size); #endif int *dsn=new int[current_delete2_size],*dsnp=dsn,*dsp=ds2; while(dsp=p) { eprintf("voronoicell_base::nplane(): Internal error.\n"); throw true; } u=l;up=lp; for(us=0;us=p) { eprintf("voronoicell_base::nplane(): Internal error.\n"); throw true; } u=q;up=qp; for(us=0;us=1 eprintf("voro++: Bailed out of convex calculation\n"); #endif qw=1;lw=0; for(qp=0;qp=current_vertex_order) add_memory_vorder(vc); if(mec[nu[p]]==mem[nu[p]]) add_memory(vc,nu[p],stackp2); vc.n_set_pointer(p,nu[p]); ed[p]=mep[nu[p]]+((nu[p]<<1)+1)*mec[nu[p]]++; ed[p][nu[p]<<1]=p; // Copy the edges of the original vertex into the new // one. Delete the edges of the original vertex, and // update the relational table. us=cycle_down(i,up); while(i=current_vertex_order) add_memory_vorder(vc); if(mec[nu[p]]==mem[nu[p]]) add_memory(vc,nu[p],stackp2); // Copy the edges of the original vertex into the new // one. Delete the edges of the original vertex, and // update the relational table. vc.n_set_pointer(p,nu[p]); ed[p]=mep[nu[p]]+((nu[p]<<1)+1)*mec[nu[p]]++; ed[p][nu[p]<<1]=p; us=i++; while(i0) k+=nu[j]; } else { if(j>0) { // This vertex was visited before, so // count those vertices to the ones we // already have. k+=nu[j]; // The only time when we might make a // duplicate edge is if the point we're // going to move to next is also a // marginal point, so test for that // first. if(lw==0) { // Now see whether this marginal point // has been visited before. i=-ed[lp][nu[lp]<<1]; if(i>0) { // Now see if the last edge of that other // marginal point actually ends up here. if(ed[i][nu[i]-1]==j) { new_double_edge=true; k-=1; } else new_double_edge=false; } else { // That marginal point hasn't been visited // before, so we probably don't have to worry // about duplicate edges, except in the // case when that's the way into the end // of the facet, because that way always creates // an edge. if(j==rp&&lp==up&&ed[qp][nu[qp]+qs]==us) { new_double_edge=true; k-=1; } else new_double_edge=false; } } else new_double_edge=false; } else { // The vertex hasn't been visited // before, but let's see if it's // marginal if(lw==0) { // If it is, we need to check // for the case that it's a // small branch, and that we're // heading right back to where // we came from i=-ed[lp][nu[lp]<<1]; if(i==cp) { new_double_edge=true; k-=1; } else new_double_edge=false; } else new_double_edge=false; } } // k now holds the number of edges of the new vertex // we are forming. Add memory for it if it doesn't exist // already. while(k>=current_vertex_order) add_memory_vorder(vc); if(mec[k]==mem[k]) add_memory(vc,k,stackp2); // Now create a new vertex with order k, or augment // the existing one if(j>0) { // If we're augmenting a vertex but we don't // actually need any more edges, just skip this // routine to avoid memory confusion if(nu[j]!=k) { // Allocate memory and copy the edges // of the previous instance into it vc.n_set_aux1(k); edp=mep[k]+((k<<1)+1)*mec[k]++; i=0; while(ids) { --p; while(ed[p][nu[p]]==-1) { j=nu[p]; edp=ed[p];edd=(mep[j]+((j<<1)+1)*--mec[j]); while(edp0) voro_fatal_error("Zero order vertex formed",VOROPP_INTERNAL_ERROR); // Collapse any order 2 vertices and exit return collapse_order2(vc); } /** During the creation of a new facet in the plane routine, it is possible * that some order two vertices may arise. This routine removes them. * Suppose an order two vertex joins c and d. If there's a edge between * c and d already, then the order two vertex is just removed; otherwise, * the order two vertex is removed and c and d are joined together directly. * It is possible this process will create order two or order one vertices, * and the routine is continually run until all of them are removed. * \return False if the vertex removal was unsuccessful, indicative of the cell * reducing to zero volume and disappearing; true if the vertex removal * was successful. */ inline bool voronoicell_base::collapse_order2(voronoicell_neighbor &vc) { if(!collapse_order1(vc)) return false; int a,b,i,j,k,l; while(mec[2]>0) { // Pick a order 2 vertex and read in its edges i=--mec[2]; j=mep[2][5*i];k=mep[2][5*i+1]; if(j==k) { #if VOROPP_VERBOSE >=1 fputs("Order two vertex joins itself",stderr); #endif return false; } // Scan the edges of j to see if joins k for(l=0;l0) { up=0; #if VOROPP_VERBOSE >=1 fputs("Order one collapse\n",stderr); #endif i=--mec[1]; j=mep[1][3*i];k=mep[1][3*i+1]; i=mep[1][3*i+2]; if(!delete_connection(vc,j,k,false)) return false; --p; if(up==i) up=0; if(p!=i) { if(up==p) up=i; pts[3*i]=pts[3*p]; pts[3*i+1]=pts[3*p+1]; pts[3*i+2]=pts[3*p+2]; for(k=0;k=1 if(i<1) { fputs("Zero order vertex formed\n",stderr); return false; } #endif if(mec[i]==mem[i]) add_memory(vc,i,ds2); vc.n_set_aux1(i); for(l=0;l=0) { ed[i][j]=-1-k; l=cycle_up(ed[i][nu[i]+j],k); vx=pts[3*k]-*pts; vy=pts[3*k+1]-pts[1]; vz=pts[3*k+2]-pts[2]; m=ed[k][l];ed[k][l]=-1-m; while(m!=i) { n=cycle_up(ed[k][nu[k]+l],m); wx=pts[3*m]-*pts; wy=pts[3*m+1]-pts[1]; wz=pts[3*m+2]-pts[2]; vol+=ux*vy*wz+uy*vz*wx+uz*vx*wy-uz*vy*wx-uy*vx*wz-ux*vz*wy; k=m;l=n;vx=wx;vy=wy;vz=wz; m=ed[k][l];ed[k][l]=-1-m; } } } } reset_edges(); return vol*fe; } /** Calculates the areas of each face of the Voronoi cell and prints the * results to an output stream. * \param[out] v the vector to store the results in. */ void voronoicell_base::face_areas(vector &v) { double area; v.clear(); int i,j,k,l,m,n; double ux,uy,uz,vx,vy,vz,wx,wy,wz; for(i=1;i=0) { area=0; ed[i][j]=-1-k; l=cycle_up(ed[i][nu[i]+j],k); m=ed[k][l];ed[k][l]=-1-m; while(m!=i) { n=cycle_up(ed[k][nu[k]+l],m); ux=pts[3*k]-pts[3*i]; uy=pts[3*k+1]-pts[3*i+1]; uz=pts[3*k+2]-pts[3*i+2]; vx=pts[3*m]-pts[3*i]; vy=pts[3*m+1]-pts[3*i+1]; vz=pts[3*m+2]-pts[3*i+2]; wx=uy*vz-uz*vy; wy=uz*vx-ux*vz; wz=ux*vy-uy*vx; area+=sqrt(wx*wx+wy*wy+wz*wz); k=m;l=n; m=ed[k][l];ed[k][l]=-1-m; } v.push_back(0.125*area); } } reset_edges(); } /** Calculates the total surface area of the Voronoi cell. * \return The computed area. */ double voronoicell_base::surface_area() { double area=0; int i,j,k,l,m,n; double ux,uy,uz,vx,vy,vz,wx,wy,wz; for(i=1;i=0) { ed[i][j]=-1-k; l=cycle_up(ed[i][nu[i]+j],k); m=ed[k][l];ed[k][l]=-1-m; while(m!=i) { n=cycle_up(ed[k][nu[k]+l],m); ux=pts[3*k]-pts[3*i]; uy=pts[3*k+1]-pts[3*i+1]; uz=pts[3*k+2]-pts[3*i+2]; vx=pts[3*m]-pts[3*i]; vy=pts[3*m+1]-pts[3*i+1]; vz=pts[3*m+2]-pts[3*i+2]; wx=uy*vz-uz*vy; wy=uz*vx-ux*vz; wz=ux*vy-uy*vx; area+=sqrt(wx*wx+wy*wy+wz*wz); k=m;l=n; m=ed[k][l];ed[k][l]=-1-m; } } } reset_edges(); return 0.125*area; } /** Calculates the centroid of the Voronoi cell, by decomposing the cell into * tetrahedra extending outward from the zeroth vertex. * \param[out] (cx,cy,cz) references to floating point numbers in which to * pass back the centroid vector. */ void voronoicell_base::centroid(double &cx,double &cy,double &cz) { double tvol,vol=0;cx=cy=cz=0; int i,j,k,l,m,n; double ux,uy,uz,vx,vy,vz,wx,wy,wz; for(i=1;i=0) { ed[i][j]=-1-k; l=cycle_up(ed[i][nu[i]+j],k); vx=pts[3*k]-*pts; vy=pts[3*k+1]-pts[1]; vz=pts[3*k+2]-pts[2]; m=ed[k][l];ed[k][l]=-1-m; while(m!=i) { n=cycle_up(ed[k][nu[k]+l],m); wx=pts[3*m]-*pts; wy=pts[3*m+1]-pts[1]; wz=pts[3*m+2]-pts[2]; tvol=ux*vy*wz+uy*vz*wx+uz*vx*wy-uz*vy*wx-uy*vx*wz-ux*vz*wy; vol+=tvol; cx+=(wx+vx-ux)*tvol; cy+=(wy+vy-uy)*tvol; cz+=(wz+vz-uz)*tvol; k=m;l=n;vx=wx;vy=wy;vz=wz; m=ed[k][l];ed[k][l]=-1-m; } } } } reset_edges(); if(vol>tolerance_sq) { vol=0.125/vol; cx=cx*vol+0.5*(*pts); cy=cy*vol+0.5*pts[1]; cz=cz*vol+0.5*pts[2]; } else cx=cy=cz=0; } /** Computes the maximum radius squared of a vertex from the center of the * cell. It can be used to determine when enough particles have been testing an * all planes that could cut the cell have been considered. * \return The maximum radius squared of a vertex.*/ double voronoicell_base::max_radius_squared() { double r,s,*ptsp=pts+3,*ptse=pts+3*p; r=*pts*(*pts)+pts[1]*pts[1]+pts[2]*pts[2]; while(ptspr) r=s; } return r; } /** Calculates the total edge distance of the Voronoi cell. * \return A floating point number holding the calculated distance. */ double voronoicell_base::total_edge_distance() { int i,j,k; double dis=0,dx,dy,dz; for(i=0;ii) { dx=pts[3*k]-pts[3*i]; dy=pts[3*k+1]-pts[3*i+1]; dz=pts[3*k+2]-pts[3*i+2]; dis+=sqrt(dx*dx+dy*dy+dz*dz); } } return 0.5*dis; } /** Outputs the edges of the Voronoi cell in POV-Ray format to an open file * stream, displacing the cell by given vector. * \param[in] (x,y,z) a displacement vector to be added to the cell's position. * \param[in] fp a file handle to write to. */ void voronoicell_base::draw_pov(double x,double y,double z,FILE* fp) { int i,j,k;double *ptsp=pts,*pt2; char posbuf1[128],posbuf2[128]; for(i=0;i,r}\n",posbuf1); for(j=0;j,<%s>,r}\n",posbuf1,posbuf2); } } } } /** Outputs the edges of the Voronoi cell in gnuplot format to an output stream. * \param[in] (x,y,z) a displacement vector to be added to the cell's position. * \param[in] fp a file handle to write to. */ void voronoicell_base::draw_gnuplot(double x,double y,double z,FILE *fp) { int i,j,k,l,m; for(i=1;i=0) { fprintf(fp,"%g %g %g\n",x+0.5*pts[3*i],y+0.5*pts[3*i+1],z+0.5*pts[3*i+2]); l=i;m=j; do { ed[k][ed[l][nu[l]+m]]=-1-l; ed[l][m]=-1-k; l=k; fprintf(fp,"%g %g %g\n",x+0.5*pts[3*k],y+0.5*pts[3*k+1],z+0.5*pts[3*k+2]); } while (search_edge(l,m,k)); fputs("\n\n",fp); } } reset_edges(); } inline bool voronoicell_base::search_edge(int l,int &m,int &k) { for(m=0;m=0) return true; } return false; } /** Outputs the Voronoi cell in the POV mesh2 format, described in section * 1.3.2.2 of the POV-Ray documentation. The mesh2 output consists of a list of * vertex vectors, followed by a list of triangular faces. The routine also * makes use of the optional inside_vector specification, which makes the mesh * object solid, so the the POV-Ray Constructive Solid Geometry (CSG) can be * applied. * \param[in] (x,y,z) a displacement vector to be added to the cell's position. * \param[in] fp a file handle to write to. */ void voronoicell_base::draw_pov_mesh(double x,double y,double z,FILE *fp) { int i,j,k,l,m,n; double *ptsp=pts; fprintf(fp,"mesh2 {\nvertex_vectors {\n%d\n",p); for(i=0;i\n",x+*ptsp*0.5,y+ptsp[1]*0.5,z+ptsp[2]*0.5); fprintf(fp,"}\nface_indices {\n%d\n",(p-2)<<1); for(i=1;i=0) { ed[i][j]=-1-k; l=cycle_up(ed[i][nu[i]+j],k); m=ed[k][l];ed[k][l]=-1-m; while(m!=i) { n=cycle_up(ed[k][nu[k]+l],m); fprintf(fp,",<%d,%d,%d>\n",i,k,m); k=m;l=n; m=ed[k][l];ed[k][l]=-1-m; } } } fputs("}\ninside_vector <0,0,1>\n}\n",fp); reset_edges(); } /** Several routines in the class that gather cell-based statistics internally * track their progress by flipping edges to negative so that they know what * parts of the cell have already been tested. This function resets them back * to positive. When it is called, it assumes that every edge in the routine * should have already been flipped to negative, and it bails out with an * internal error if it encounters a positive edge. */ inline void voronoicell_base::reset_edges() { int i,j; for(i=0;i=0) voro_fatal_error("Edge reset routine found a previously untested edge",VOROPP_INTERNAL_ERROR); ed[i][j]=-1-ed[i][j]; } } /** Checks to see if a given vertex is inside, outside or within the test * plane. If the point is far away from the test plane, the routine immediately * returns whether it is inside or outside. If the routine is close the the * plane and within the specified tolerance, then the special check_marginal() * routine is called. * \param[in] n the vertex to test. * \param[out] ans the result of the scalar product used in evaluating the * location of the point. * \return -1 if the point is inside the plane, 1 if the point is outside the * plane, or 0 if the point is within the plane. */ inline int voronoicell_base::m_test(int n,double &ans) { double *pp=pts+n+(n<<1); ans=*(pp++)*px; ans+=*(pp++)*py; ans+=*pp*pz-prsq; if(ans<-tolerance2) { return -1; } else if(ans>tolerance2) { return 1; } return check_marginal(n,ans); } /** Checks to see if a given vertex is inside, outside or within the test * plane, for the case when the point has been detected to be very close to the * plane. The routine ensures that the returned results are always consistent * with previous tests, by keeping a table of any marginal results. The routine * first sees if the vertex is in the table, and if it finds a previously * computed result it uses that. Otherwise, it computes a result for this * vertex and adds it the table. * \param[in] n the vertex to test. * \param[in] ans the result of the scalar product used in evaluating * the location of the point. * \return -1 if the point is inside the plane, 1 if the point is outside the * plane, or 0 if the point is within the plane. */ int voronoicell_base::check_marginal(int n,double &ans) { int i; for(i=0;imax_marginal) voro_fatal_error("Marginal case buffer allocation exceeded absolute maximum",VOROPP_MEMORY_ERROR); #if VOROPP_VERBOSE >=2 fprintf(stderr,"Marginal cases buffer scaled up to %d\n",i); #endif int *pmarg=new int[current_marginal]; for(int j=0;jtolerance?1:(ans<-tolerance?-1:0); return marg[n_marg-1]; } /** For each face of the Voronoi cell, this routine prints the out the normal * vector of the face, and scales it to the distance from the cell center to * that plane. * \param[out] v the vector to store the results in. */ void voronoicell_base::normals(vector &v) { int i,j,k; v.clear(); for(i=1;i=0) normals_search(v,i,j,k); } reset_edges(); } /** This inline routine is called by normals(). It attempts to construct a * single normal vector that is associated with a particular face. It first * traces around the face, trying to find two vectors along the face edges * whose vector product is above the numerical tolerance. It then constructs * the normal vector using this product. If the face is too small, and none of * the vector products are large enough, the routine may return (0,0,0) as the * normal vector. * \param[in] v the vector to store the results in. * \param[in] i the initial vertex of the face to test. * \param[in] j the index of an edge of the vertex. * \param[in] k the neighboring vertex of i, set to ed[i][j]. */ inline void voronoicell_base::normals_search(vector &v,int i,int j,int k) { ed[i][j]=-1-k; int l=cycle_up(ed[i][nu[i]+j],k),m; double ux,uy,uz,vx,vy,vz,wx,wy,wz,wmag; do { m=ed[k][l];ed[k][l]=-1-m; ux=pts[3*m]-pts[3*k]; uy=pts[3*m+1]-pts[3*k+1]; uz=pts[3*m+2]-pts[3*k+2]; // Test to see if the length of this edge is above the tolerance if(ux*ux+uy*uy+uz*uz>tolerance_sq) { while(m!=i) { l=cycle_up(ed[k][nu[k]+l],m); k=m;m=ed[k][l];ed[k][l]=-1-m; vx=pts[3*m]-pts[3*k]; vy=pts[3*m+1]-pts[3*k+1]; vz=pts[3*m+2]-pts[3*k+2]; // Construct the vector product of this edge with // the previous one wx=uz*vy-uy*vz; wy=ux*vz-uz*vx; wz=uy*vx-ux*vy; wmag=wx*wx+wy*wy+wz*wz; // Test to see if this vector product of the // two edges is above the tolerance if(wmag>tolerance_sq) { // Construct the normal vector and print it wmag=1/sqrt(wmag); v.push_back(wx*wmag); v.push_back(wy*wmag); v.push_back(wz*wmag); // Mark all of the remaining edges of this // face and exit while(m!=i) { l=cycle_up(ed[k][nu[k]+l],m); k=m;m=ed[k][l];ed[k][l]=-1-m; } return; } } v.push_back(0); v.push_back(0); v.push_back(0); return; } l=cycle_up(ed[k][nu[k]+l],m); k=m; } while (k!=i); v.push_back(0); v.push_back(0); v.push_back(0); } /** Returns the number of faces of a computed Voronoi cell. * \return The number of faces. */ int voronoicell_base::number_of_faces() { int i,j,k,l,m,s=0; for(i=1;i=0) { s++; ed[i][j]=-1-k; l=cycle_up(ed[i][nu[i]+j],k); do { m=ed[k][l]; ed[k][l]=-1-m; l=cycle_up(ed[k][nu[k]+l],m); k=m; } while (k!=i); } } reset_edges(); return s; } /** Returns a vector of the vertex orders. * \param[out] v the vector to store the results in. */ void voronoicell_base::vertex_orders(vector &v) { v.resize(p); for(int i=0;i0) { fprintf(fp,"%d",*nu); for(int *nup=nu+1;nup &v) { v.resize(3*p); double *ptsp=pts; for(int i=0;i<3*p;i+=3) { v[i]=*(ptsp++)*0.5; v[i+1]=*(ptsp++)*0.5; v[i+2]=*(ptsp++)*0.5; } } /** Outputs the vertex vectors using the local coordinate system. * \param[out] fp the file handle to write to. */ void voronoicell_base::output_vertices(FILE *fp) { if(p>0) { fprintf(fp,"(%g,%g,%g)",*pts*0.5,pts[1]*0.5,pts[2]*0.5); for(double *ptsp=pts+3;ptsp &v) { v.resize(3*p); double *ptsp=pts; for(int i=0;i<3*p;i+=3) { v[i]=x+*(ptsp++)*0.5; v[i+1]=y+*(ptsp++)*0.5; v[i+2]=z+*(ptsp++)*0.5; } } /** Outputs the vertex vectors using the global coordinate system. * \param[out] fp the file handle to write to. * \param[in] (x,y,z) the position vector of the particle in the global * coordinate system. */ void voronoicell_base::output_vertices(double x,double y,double z,FILE *fp) { if(p>0) { fprintf(fp,"(%g,%g,%g)",x+*pts*0.5,y+pts[1]*0.5,z+pts[2]*0.5); for(double *ptsp=pts+3;ptsp &v) { v.clear(); int i,j,k,l,m; double dx,dy,dz,perim; for(i=1;i=0) { dx=pts[3*k]-pts[3*i]; dy=pts[3*k+1]-pts[3*i+1]; dz=pts[3*k+2]-pts[3*i+2]; perim=sqrt(dx*dx+dy*dy+dz*dz); ed[i][j]=-1-k; l=cycle_up(ed[i][nu[i]+j],k); do { m=ed[k][l]; dx=pts[3*m]-pts[3*k]; dy=pts[3*m+1]-pts[3*k+1]; dz=pts[3*m+2]-pts[3*k+2]; perim+=sqrt(dx*dx+dy*dy+dz*dz); ed[k][l]=-1-m; l=cycle_up(ed[k][nu[k]+l],m); k=m; } while (k!=i); v.push_back(0.5*perim); } } reset_edges(); } /** For each face, this routine outputs a bracketed sequence of numbers * containing a list of all the vertices that make up that face. * \param[out] v the vector to store the results in. */ void voronoicell_base::face_vertices(vector &v) { int i,j,k,l,m,vp(0),vn; v.clear(); for(i=1;i=0) { v.push_back(0); v.push_back(i); ed[i][j]=-1-k; l=cycle_up(ed[i][nu[i]+j],k); do { v.push_back(k); m=ed[k][l]; ed[k][l]=-1-m; l=cycle_up(ed[k][nu[k]+l],m); k=m; } while (k!=i); vn=(int)v.size(); v[vp]=vn-vp-1; vp=vn; } } reset_edges(); } /** Outputs a list of the number of edges in each face. * \param[out] v the vector to store the results in. */ void voronoicell_base::face_orders(vector &v) { int i,j,k,l,m,q; v.clear(); for(i=1;i=0) { q=1; ed[i][j]=-1-k; l=cycle_up(ed[i][nu[i]+j],k); do { q++; m=ed[k][l]; ed[k][l]=-1-m; l=cycle_up(ed[k][nu[k]+l],m); k=m; } while (k!=i); v.push_back(q);; } } reset_edges(); } /** Computes the number of edges that each face has and outputs a frequency * table of the results. * \param[out] v the vector to store the results in. */ void voronoicell_base::face_freq_table(vector &v) { int i,j,k,l,m,q; v.clear(); for(i=1;i=0) { q=1; ed[i][j]=-1-k; l=cycle_up(ed[i][nu[i]+j],k); do { q++; m=ed[k][l]; ed[k][l]=-1-m; l=cycle_up(ed[k][nu[k]+l],m); k=m; } while (k!=i); if((unsigned int) q>v.size()) v.resize(q+1,0); v[q]++; } } reset_edges(); } /** This routine tests to see whether the cell intersects a plane by starting * from the guess point up. If up intersects, then it immediately returns true. * Otherwise, it calls the plane_intersects_track() routine. * \param[in] (x,y,z) the normal vector to the plane. * \param[in] rsq the distance along this vector of the plane. * \return False if the plane does not intersect the plane, true if it does. */ bool voronoicell_base::plane_intersects(double x,double y,double z,double rsq) { double g=x*pts[3*up]+y*pts[3*up+1]+z*pts[3*up+2]; if(g>3,mp=1; double m; while(cag) { if(m>rsq) return true; g=m;up=mp; } ca+=mp++; } return plane_intersects_track(x,y,z,rsq,g); } return true; } /* This routine tests to see if a cell intersects a plane, by tracing over the cell from * vertex to vertex, starting at up. It is meant to be called either by plane_intersects() * or plane_intersects_track(), when those routines cannot immediately resolve the case. * \param[in] (x,y,z) the normal vector to the plane. * \param[in] rsq the distance along this vector of the plane. * \param[in] g the distance of up from the plane. * \return False if the plane does not intersect the plane, true if it does. */ inline bool voronoicell_base::plane_intersects_track(double x,double y,double z,double rsq,double g) { int count=0,ls,us,tp; double t; // The test point is outside of the cutting space for(us=0;usg) { ls=ed[up][nu[up]+us]; up=tp; while (t=p) { #if VOROPP_VERBOSE >=1 fputs("Bailed out of convex calculation",stderr); #endif for(tp=0;tprsq) return true; return false; } // Test all the neighbors of the current point // and find the one which is closest to the // plane for(us=0;ust) break; } if(us==ls) { us++; while(ust) break; us++; } if(us==nu[up]) return false; } ls=ed[up][nu[up]+us];up=tp;t=g; } return true; } } return false; } /** Counts the number of edges of the Voronoi cell. * \return the number of edges. */ int voronoicell_base::number_of_edges() { int edges=0,*nup=nu; while(nup>1; } /** Outputs a custom string of information about the Voronoi cell. The string * of information follows a similar style as the C printf command, and detailed * information about its format is available at * http://math.lbl.gov/voro++/doc/custom.html. * \param[in] format the custom string to print. * \param[in] i the ID of the particle associated with this Voronoi cell. * \param[in] (x,y,z) the position of the particle associated with this Voronoi * cell. * \param[in] r a radius associated with the particle. * \param[in] fp the file handle to write to. */ void voronoicell_base::output_custom(const char *format,int i,double x,double y,double z,double r,FILE *fp) { char *fmp=(const_cast(format)); vector vi; vector vd; while(*fmp!=0) { if(*fmp=='%') { fmp++; switch(*fmp) { // Particle-related output case 'i': fprintf(fp,"%d",i);break; case 'x': fprintf(fp,"%g",x);break; case 'y': fprintf(fp,"%g",y);break; case 'z': fprintf(fp,"%g",z);break; case 'q': fprintf(fp,"%g %g %g",x,y,z);break; case 'r': fprintf(fp,"%g",r);break; // Vertex-related output case 'w': fprintf(fp,"%d",p);break; case 'p': output_vertices(fp);break; case 'P': output_vertices(x,y,z,fp);break; case 'o': output_vertex_orders(fp);break; case 'm': fprintf(fp,"%g",0.25*max_radius_squared());break; // Edge-related output case 'g': fprintf(fp,"%d",number_of_edges());break; case 'E': fprintf(fp,"%g",total_edge_distance());break; case 'e': face_perimeters(vd);voro_print_vector(vd,fp);break; // Face-related output case 's': fprintf(fp,"%d",number_of_faces());break; case 'F': fprintf(fp,"%g",surface_area());break; case 'A': { face_freq_table(vi); voro_print_vector(vi,fp); } break; case 'a': face_orders(vi);voro_print_vector(vi,fp);break; case 'f': face_areas(vd);voro_print_vector(vd,fp);break; case 't': { face_vertices(vi); voro_print_face_vertices(vi,fp); } break; case 'l': normals(vd); voro_print_positions(vd,fp); break; case 'n': neighbors(vi); voro_print_vector(vi,fp); break; // Volume-related output case 'v': fprintf(fp,"%g",volume());break; case 'c': { double cx,cy,cz; centroid(cx,cy,cz); fprintf(fp,"%g %g %g",cx,cy,cz); } break; case 'C': { double cx,cy,cz; centroid(cx,cy,cz); fprintf(fp,"%g %g %g",x+cx,y+cy,z+cz); } break; // End-of-string reached case 0: fmp--;break; // The percent sign is not part of a // control sequence default: putc('%',fp);putc(*fmp,fp); } } else putc(*fmp,fp); fmp++; } fputs("\n",fp); } /** This initializes the class to be a rectangular box. It calls the base class * initialization routine to set up the edge and vertex information, and then * sets up the neighbor information, with initial faces being assigned ID * numbers from -1 to -6. * \param[in] (xmin,xmax) the minimum and maximum x coordinates. * \param[in] (ymin,ymax) the minimum and maximum y coordinates. * \param[in] (zmin,zmax) the minimum and maximum z coordinates. */ void voronoicell_neighbor::init(double xmin,double xmax,double ymin,double ymax,double zmin,double zmax) { init_base(xmin,xmax,ymin,ymax,zmin,zmax); int *q=mne[3]; *q=-5;q[1]=-3;q[2]=-1; q[3]=-5;q[4]=-2;q[5]=-3; q[6]=-5;q[7]=-1;q[8]=-4; q[9]=-5;q[10]=-4;q[11]=-2; q[12]=-6;q[13]=-1;q[14]=-3; q[15]=-6;q[16]=-3;q[17]=-2; q[18]=-6;q[19]=-4;q[20]=-1; q[21]=-6;q[22]=-2;q[23]=-4; *ne=q;ne[1]=q+3;ne[2]=q+6;ne[3]=q+9; ne[4]=q+12;ne[5]=q+15;ne[6]=q+18;ne[7]=q+21; } /** This initializes the class to be an octahedron. It calls the base class * initialization routine to set up the edge and vertex information, and then * sets up the neighbor information, with the initial faces being assigned ID * numbers from -1 to -8. * \param[in] l The distance from the octahedron center to a vertex. Six * vertices are initialized at (-l,0,0), (l,0,0), (0,-l,0), * (0,l,0), (0,0,-l), and (0,0,l). */ void voronoicell_neighbor::init_octahedron(double l) { init_octahedron_base(l); int *q=mne[4]; *q=-5;q[1]=-6;q[2]=-7;q[3]=-8; q[4]=-1;q[5]=-2;q[6]=-3;q[7]=-4; q[8]=-6;q[9]=-5;q[10]=-2;q[11]=-1; q[12]=-8;q[13]=-7;q[14]=-4;q[15]=-3; q[16]=-5;q[17]=-8;q[18]=-3;q[19]=-2; q[20]=-7;q[21]=-6;q[22]=-1;q[23]=-4; *ne=q;ne[1]=q+4;ne[2]=q+8;ne[3]=q+12;ne[4]=q+16;ne[5]=q+20; } /** This initializes the class to be a tetrahedron. It calls the base class * initialization routine to set up the edge and vertex information, and then * sets up the neighbor information, with the initial faces being assigned ID * numbers from -1 to -4. * \param (x0,y0,z0) a position vector for the first vertex. * \param (x1,y1,z1) a position vector for the second vertex. * \param (x2,y2,z2) a position vector for the third vertex. * \param (x3,y3,z3) a position vector for the fourth vertex. */ void voronoicell_neighbor::init_tetrahedron(double x0,double y0,double z0,double x1,double y1,double z1,double x2,double y2,double z2,double x3,double y3,double z3) { init_tetrahedron_base(x0,y0,z0,x1,y1,z1,x2,y2,z2,x3,y3,z3); int *q=mne[3]; *q=-4;q[1]=-3;q[2]=-2; q[3]=-3;q[4]=-4;q[5]=-1; q[6]=-4;q[7]=-2;q[8]=-1; q[9]=-2;q[10]=-3;q[11]=-1; *ne=q;ne[1]=q+3;ne[2]=q+6;ne[3]=q+9; } /** This routine checks to make sure the neighbor information of each face is * consistent. */ void voronoicell_neighbor::check_facets() { int i,j,k,l,m,q; for(i=1;i=0) { ed[i][j]=-1-k; q=ne[i][j]; l=cycle_up(ed[i][nu[i]+j],k); do { m=ed[k][l]; ed[k][l]=-1-m; fprintf(stderr,"Facet error at (%d,%d)=%d, started from (%d,%d)=%d\n",k,l,ne[k][l],i,j,q); l=cycle_up(ed[k][nu[k]+l],m); k=m; } while (k!=i); } } reset_edges(); } /** The class constructor allocates memory for storing neighbor information. */ voronoicell_neighbor::voronoicell_neighbor() { int i; mne=new int*[current_vertex_order]; ne=new int*[current_vertices]; for(i=0;i<3;i++) mne[i]=new int[init_n_vertices*i]; mne[3]=new int[init_3_vertices*3]; for(i=4;i=0;i--) if(mem[i]>0) delete [] mne[i]; delete [] mne; delete [] ne; } /** Computes a vector list of neighbors. */ void voronoicell_neighbor::neighbors(vector &v) { v.clear(); int i,j,k,l,m; for(i=1;i=0) { v.push_back(ne[i][j]); ed[i][j]=-1-k; l=cycle_up(ed[i][nu[i]+j],k); do { m=ed[k][l]; ed[k][l]=-1-m; l=cycle_up(ed[k][nu[k]+l],m); k=m; } while (k!=i); } } reset_edges(); } /** Prints the vertices, their edges, the relation table, and also notifies if * any memory errors are visible. */ void voronoicell_base::print_edges() { int j; double *ptsp=pts; for(int i=0;i=mep[nu[i]]+mec[nu[i]]*((nu[i]<<1)+1)) puts(" Memory error"); else puts(""); } } /** This prints out the neighbor information for vertex i. */ void voronoicell_neighbor::print_edges_neighbors(int i) { if(nu[i]>0) { int j=0; mprintf(" ("); while(j. *****************************************************************************/ // Voro++, a 3D cell-based Voronoi library // // Author : Chris H. Rycroft (LBL / UC Berkeley) // Email : chr@alum.mit.edu // Date : August 30th 2011 /** \file cell.hh * \brief Header file for the voronoicell and related classes. */ #ifndef VOROPP_CELL_HH #define VOROPP_CELL_HH // This must always be the first include directive #include "config.h" #include #include #include #include //using namespace std; #include "v_config.h" #include "v_common.h" class voronoicell_neighbor; /** \brief A class representing a single Voronoi cell. * * This class represents a single Voronoi cell, as a collection of vertices * that are connected by edges. The class contains routines for initializing * the Voronoi cell to be simple shapes such as a box, tetrahedron, or octahedron. * It the contains routines for recomputing the cell based on cutting it * by a plane, which forms the key routine for the Voronoi cell computation. * It contains numerous routine for computing statistics about the Voronoi cell, * and it can output the cell in several formats. * * This class is not intended for direct use, but forms the base of the * voronoicell and voronoicell_neighbor classes, which extend it based on * whether neighboring particle ID information needs to be tracked. */ class voronoicell_base { public: /** This holds the current size of the arrays ed and nu, which * hold the vertex information. If more vertices are created * than can fit in this array, then it is dynamically extended * using the add_memory_vertices routine. */ int current_vertices; /** This holds the current maximum allowed order of a vertex, * which sets the size of the mem, mep, and mec arrays. If a * vertex is created with more vertices than this, the arrays * are dynamically extended using the add_memory_vorder routine. */ int current_vertex_order; /** This sets the size of the main delete stack. */ int current_delete_size; /** This sets the size of the auxiliary delete stack. */ int current_delete2_size; /** This sets the total number of vertices in the current cell. */ int p; /** This is the index of particular point in the cell, which is * used to start the tracing routines for plane intersection * and cutting. These routines will work starting from any * point, but it's often most efficient to start from the last * point considered, since in many cases, the cell construction * algorithm may consider many planes with similar vectors * concurrently. */ int up; /** This is a two dimensional array that holds information * about the edge connections of the vertices that make up the * cell. The two dimensional array is not allocated in the * usual method. To account for the fact the different vertices * have different orders, and thus require different amounts of * storage, the elements of ed[i] point to one-dimensional * arrays in the mep[] array of different sizes. * * More specifically, if vertex i has order m, then ed[i] * points to a one-dimensional array in mep[m] that has 2*m+1 * entries. The first m elements hold the neighboring edges, so * that the jth edge of vertex i is held in ed[i][j]. The next * m elements hold a table of relations which is redundant but * helps speed up the computation. It satisfies the relation * ed[ed[i][j]][ed[i][m+j]]=i. The final entry holds a back * pointer, so that ed[i+2*m]=i. The back pointers are used * when rearranging the memory. */ int **ed; /** This array holds the order of the vertices in the Voronoi * cell. This array is dynamically allocated, with its current * size held by current_vertices. */ int *nu; /** This in an array with size 3*current_vertices for holding * the positions of the vertices. */ double *pts; voronoicell_base(); virtual ~voronoicell_base(); void init_base(double xmin,double xmax,double ymin,double ymax,double zmin,double zmax); void init_octahedron_base(double l); void init_tetrahedron_base(double x0,double y0,double z0,double x1,double y1,double z1,double x2,double y2,double z2,double x3,double y3,double z3); void translate(double x,double y,double z); void draw_pov(double x,double y,double z,FILE *fp=stdout); /** Outputs the cell in POV-Ray format, using cylinders for edges * and spheres for vertices, to a given file. * \param[in] (x,y,z) a displacement to add to the cell's * position. * \param[in] filename the name of the file to write to. */ inline void draw_pov(double x,double y,double z,const char *filename) { FILE *fp=safe_fopen(filename,"w"); draw_pov(x,y,z,fp); fclose(fp); }; void draw_pov_mesh(double x,double y,double z,FILE *fp=stdout); /** Outputs the cell in POV-Ray format as a mesh2 object to a * given file. * \param[in] (x,y,z) a displacement to add to the cell's * position. * \param[in] filename the name of the file to write to. */ inline void draw_pov_mesh(double x,double y,double z,const char *filename) { FILE *fp=safe_fopen(filename,"w"); draw_pov_mesh(x,y,z,fp); fclose(fp); } void draw_gnuplot(double x,double y,double z,FILE *fp=stdout); /** Outputs the cell in Gnuplot format a given file. * \param[in] (x,y,z) a displacement to add to the cell's * position. * \param[in] filename the name of the file to write to. */ inline void draw_gnuplot(double x,double y,double z,const char *filename) { FILE *fp=safe_fopen(filename,"w"); draw_gnuplot(x,y,z,fp); fclose(fp); } double volume(); double max_radius_squared(); double total_edge_distance(); double surface_area(); void centroid(double &cx,double &cy,double &cz); int number_of_faces(); int number_of_edges(); void vertex_orders(vector &v); void output_vertex_orders(FILE *fp=stdout); void vertices(vector &v); void output_vertices(FILE *fp=stdout); void vertices(double x,double y,double z,vector &v); void output_vertices(double x,double y,double z,FILE *fp=stdout); void face_areas(vector &v); /** Outputs the areas of the faces. * \param[in] fp the file handle to write to. */ inline void output_face_areas(FILE *fp=stdout) { vector v;face_areas(v); voro_print_vector(v,fp); } void face_orders(vector &v); /** Outputs a list of the number of sides of each face. * \param[in] fp the file handle to write to. */ inline void output_face_orders(FILE *fp=stdout) { vector v;face_orders(v); voro_print_vector(v,fp); } void face_freq_table(vector &v); /** Outputs a */ inline void output_face_freq_table(FILE *fp=stdout) { vector v;face_freq_table(v); voro_print_vector(v,fp); } void face_vertices(vector &v); /** Outputs the */ inline void output_face_vertices(FILE *fp=stdout) { vector v;face_vertices(v); voro_print_face_vertices(v,fp); } void face_perimeters(vector &v); /** Outputs a list of the perimeters of each face. * \param[in] fp the file handle to write to. */ inline void output_face_perimeters(FILE *fp=stdout) { vector v;face_perimeters(v); voro_print_vector(v,fp); } void normals(vector &v); /** Outputs a list of the perimeters of each face. * \param[in] fp the file handle to write to. */ inline void output_normals(FILE *fp=stdout) { vector v;normals(v); voro_print_positions(v,fp); } /** Outputs a custom string of information about the Voronoi * cell to a file. It assumes the cell is at (0,0,0) and has a * the default_radius associated with it. * \param[in] format the custom format string to use. * \param[in] fp the file handle to write to. */ inline void output_custom(const char *format,FILE *fp=stdout) {output_custom(format,0,0,0,0,default_radius,fp);} void output_custom(const char *format,int i,double x,double y,double z,double r,FILE *fp=stdout); bool nplane(voronoicell_neighbor &vc,double x,double y,double z,double rs,int p_id); bool plane_intersects(double x,double y,double z,double rs); bool plane_intersects_guess(double x,double y,double z,double rs); void construct_relations(); void check_relations(); void check_duplicates(); void print_edges(); /** Returns a list of IDs of neighboring particles * corresponding to each face. * \param[out] v a reference to a vector in which to return the * results. If no neighbor information is * available, a blank vector is returned. */ virtual void neighbors(vector &v) {v.clear();} /** This is a virtual function that is overridden by a routine * to print a list of IDs of neighboring particles * corresponding to each face. By default, when no neighbor * information is available, the routine does nothing. * \param[in] fp the file handle to write to. */ virtual void output_neighbors(FILE *fp=stdout) { UNUSED(fp); /* Suppress "unused parameter" warning */ } /** This a virtual function that is overridden by a routine to * print the neighboring particle IDs for a given vertex. By * default, when no neighbor information is available, the * routine does nothing. * \param[in] i the vertex to consider. */ virtual void print_edges_neighbors(int i) { UNUSED(i); /* Suppress "unused parameter" warning */ }; /** This is a simple inline function for picking out the index * of the next edge counterclockwise at the current vertex. * \param[in] a the index of an edge of the current vertex. * \param[in] p the number of the vertex. * \return 0 if a=nu[p]-1, or a+1 otherwise. */ inline int cycle_up(int a,int pparm) {return a==nu[pparm]-1?0:a+1;} /** This is a simple inline function for picking out the index * of the next edge clockwise from the current vertex. * \param[in] a the index of an edge of the current vertex. * \param[in] p the number of the vertex. * \return nu[p]-1 if a=0, or a-1 otherwise. */ inline int cycle_down(int a,int pparm) {return a==0?nu[pparm]-1:a-1;} protected: /** This a one dimensional array that holds the current sizes * of the memory allocations for them mep array.*/ int *mem; /** This is a one dimensional array that holds the current * number of vertices of order p that are stored in the mep[p] * array. */ int *mec; /** This is a two dimensional array for holding the information * about the edges of the Voronoi cell. mep[p] is a * one-dimensional array for holding the edge information about * all vertices of order p, with each vertex holding 2*p+1 * integers of information. The total number of vertices held * on mep[p] is stored in mem[p]. If the space runs out, the * code allocates more using the add_memory() routine. */ int **mep; inline void reset_edges(); void check_memory_for_copy(voronoicell_neighbor &vc,voronoicell_base* vb); void copy(voronoicell_base* vb); private: /** This is the delete stack, used to store the vertices which * are going to be deleted during the plane cutting procedure. */ int *ds,*stacke; /** This is the auxiliary delete stack, which has size set by * current_delete2_size. */ int *ds2,*stacke2; /** This stores the current memory allocation for the marginal * cases. */ int current_marginal; /** This stores the total number of marginal points which are * currently in the buffer. */ int n_marg; /** This array contains a list of the marginal points, and also * the outcomes of the marginal tests. */ int *marg; /** The x coordinate of the normal vector to the test plane. */ double px; /** The y coordinate of the normal vector to the test plane. */ double py; /** The z coordinate of the normal vector to the test plane. */ double pz; /** The magnitude of the normal vector to the test plane. */ double prsq; void add_memory(voronoicell_neighbor &vc,int i,int *stackp2); void add_memory_vertices(voronoicell_neighbor &vc); void add_memory_vorder(voronoicell_neighbor &vc); void add_memory_ds(int *&stackp); void add_memory_ds2(int *&stackp2); inline bool collapse_order1(voronoicell_neighbor &vc); inline bool collapse_order2(voronoicell_neighbor &vc); inline bool delete_connection(voronoicell_neighbor &vc,int j,int k,bool hand); inline bool search_for_outside_edge(voronoicell_neighbor &vc,int &up); inline void add_to_stack(voronoicell_neighbor &vc,int lp,int *&stackp2); inline bool plane_intersects_track(double x,double y,double z,double rs,double g); inline void normals_search(vector &v,int i,int j,int k); inline bool search_edge(int l,int &m,int &k); inline int m_test(int n,double &ans); int check_marginal(int n,double &ans); // friend class voronoicell; friend class voronoicell_neighbor; }; /** \brief Extension of the voronoicell_base class to represent a Voronoi cell * with neighbor information. * * This class is an extension of the voronoicell_base class, in cases when the * IDs of neighboring particles associated with each face of the Voronoi cell. * It contains additional data structures mne and ne for storing this * information. */ class voronoicell_neighbor : public voronoicell_base { public: using voronoicell_base::nplane; /** This two dimensional array holds the neighbor information * associated with each vertex. mne[p] is a one dimensional * array which holds all of the neighbor information for * vertices of order p. */ int **mne; /** This is a two dimensional array that holds the neighbor * information associated with each vertex. ne[i] points to a * one-dimensional array in mne[nu[i]]. ne[i][j] holds the * neighbor information associated with the jth edge of vertex * i. It is set to the ID number of the plane that made the * face that is clockwise from the jth edge. */ int **ne; voronoicell_neighbor(); virtual ~voronoicell_neighbor(); // void operator=(voronoicell &c); void operator=(voronoicell_neighbor &c); /** Cuts the Voronoi cell by a particle whose center is at a * separation of (x,y,z) from the cell center. The value of rsq * should be initially set to \f$x^2+y^2+z^2\f$. * \param[in] (x,y,z) the normal vector to the plane. * \param[in] rsq the distance along this vector of the plane. * \param[in] p_id the plane ID (for neighbor tracking only). * \return False if the plane cut deleted the cell entirely, * true otherwise. */ inline bool nplane(double x,double y,double z,double rsq,int p_id) { return nplane(*this,x,y,z,rsq,p_id); } /** This routine calculates the modulus squared of the vector * before passing it to the main nplane() routine with full * arguments. * \param[in] (x,y,z) the vector to cut the cell by. * \param[in] p_id the plane ID (for neighbor tracking only). * \return False if the plane cut deleted the cell entirely, * true otherwise. */ inline bool nplane(double x,double y,double z,int p_id) { double rsq=x*x+y*y+z*z; return nplane(*this,x,y,z,rsq,p_id); } /** This version of the plane routine just makes up the plane * ID to be zero. It will only be referenced if neighbor * tracking is enabled. * \param[in] (x,y,z) the vector to cut the cell by. * \param[in] rsq the modulus squared of the vector. * \return False if the plane cut deleted the cell entirely, * true otherwise. */ inline bool plane(double x,double y,double z,double rsq) { return nplane(*this,x,y,z,rsq,0); } /** Cuts a Voronoi cell using the influence of a particle at * (x,y,z), first calculating the modulus squared of this * vector before passing it to the main nplane() routine. Zero * is supplied as the plane ID, which will be ignored unless * neighbor tracking is enabled. * \param[in] (x,y,z) the vector to cut the cell by. * \return False if the plane cut deleted the cell entirely, * true otherwise. */ inline bool plane(double x,double y,double z) { double rsq=x*x+y*y+z*z; return nplane(*this,x,y,z,rsq,0); } void init(double xmin,double xmax,double ymin,double ymax,double zmin,double zmax); void init_octahedron(double l); void init_tetrahedron(double x0,double y0,double z0,double x1,double y1,double z1,double x2,double y2,double z2,double x3,double y3,double z3); void check_facets(); virtual void neighbors(vector &v); virtual void print_edges_neighbors(int i); virtual void output_neighbors(FILE *fp=stdout) { vector v;neighbors(v); voro_print_vector(v,fp); } private: int *paux1; int *paux2; inline void n_allocate(int i,int m) {mne[i]=new int[m*i];} inline void n_add_memory_vertices(int i) { int **pp = (new int*[i]); for(int j=0;j. *****************************************************************************/ // Voro++, a 3D cell-based Voronoi library // // Author : Chris H. Rycroft (LBL / UC Berkeley) // Email : chr@alum.mit.edu // Date : August 30th 2011 /** \file common.cc * \brief Implementations of the small helper functions. */ // This must always be the first include directive #include "config.h" #include "v_common.h" const char *GetRevisionInfo_v_common(unsigned int len) { static char buf[256]; GET_REVISION_INFO( buf, len ); return buf; } const char *GetSourceVersion_v_common() { static char buf[256]; GET_SOURCE_VERSION( buf ); return buf; } /** \brief Prints a vector of integers. * * Prints a vector of integers. * \param[in] v the vector to print. * \param[in] fp the file stream to print to. */ void voro_print_vector(vector &v,FILE *fp) { int k=0,s=(int)v.size(); while(k+4 &v,FILE *fp) { int k=0,s=(int)v.size(); while(k+4 &v,FILE *fp) { int j,k=0,l; if(v.size()>0) { l=v[k++]; if(l<=1) { if(l==1) fprintf(fp,"(%d)",v[k++]); else fputs("()",fp); } else { j=k+l; fprintf(fp,"(%d",v[k++]); while(k. *****************************************************************************/ // Voro++, a 3D cell-based Voronoi library // // Author : Chris H. Rycroft (LBL / UC Berkeley) // Email : chr@alum.mit.edu // Date : August 30th 2011 /** \file common.hh * \brief Header file for the small helper functions. */ #ifndef VOROPP_COMMON_HH #define VOROPP_COMMON_HH // This must always be the first include directive #include "config.h" #include #include #include #include "v_config.h" #include "tools.h" using namespace std; /** \brief Function for printing fatal error messages and exiting. * * Function for printing fatal error messages and exiting. * \param[in] p a pointer to the message to print. * \param[in] status the status code to return with. */ inline void voro_fatal_error(const char *p,int status) { eprintf("voro++ fatal: %s\n",p); exit(status); } /** \brief Prints a vector of positions. * * Prints a vector of positions as bracketed triplets. * \param[in] v the vector to print. * \param[in] fp the file stream to print to. */ inline void voro_print_positions(vector &v,FILE *fp=stdout) { if(v.size()>0) { fprintf(fp,"(%g,%g,%g)",v[0],v[1],v[2]); for(int k=3;(unsigned int) k &v,FILE *fp=stdout); void voro_print_vector(vector &v,FILE *fp=stdout); void voro_print_face_vertices(vector &v,FILE *fp=stdout); #endif travis-src-190101/src/v_compute.cpp0100777000000000000000000012133713412725633014153 0ustar00/***************************************************************************** TRAVIS - Trajectory Analyzer and Visualizer http://www.travis-analyzer.de/ Copyright (c) 2009-2019 Martin Brehm 2012-2019 Martin Thomas 2016-2019 Sascha Gehrke --------------------------------------------------------------------------- This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . *****************************************************************************/ // Voro++, a 3D cell-based Voronoi library // // Author : Chris H. Rycroft (LBL / UC Berkeley) // Email : chr@alum.mit.edu // Date : August 30th 2011 /** \file v_compute.cc * \brief Function implementantions for the voro_compute template. */ // This must always be the first include directive #include "config.h" #include "v_worklist.h" #include "v_compute.h" #include "v_container.h" #include "v_container_prd.h" #include "globalvar.h" const char *GetRevisionInfo_v_compute(unsigned int len) { static char buf[256]; GET_REVISION_INFO( buf, len ); return buf; } const char *GetSourceVersion_v_compute() { static char buf[256]; GET_SOURCE_VERSION( buf ); return buf; } /** The class constructor initializes constants from the container class, and * sets up the mask and queue used for Voronoi computations. * \param[in] con_ a reference to the container class to use. * \param[in] (hx_,hy_,hz_) the size of the mask to use. */ voro_compute::voro_compute(container_periodic_poly &con_,int hx_,int hy_,int hz_) : con(con_), boxx(con_.boxx), boxy(con_.boxy), boxz(con_.boxz), xsp(con_.xsp), ysp(con_.ysp), zsp(con_.zsp), hx(hx_), hy(hy_), hz(hz_), hxy(hx_*hy_), hxyz(hxy*hz_), ps(con_.ps), id(con_.id), p(con_.p), co(con_.co), bxsq(boxx*boxx+boxy*boxy+boxz*boxz), mv(0), qu_size(3*(3+hxy+hz*(hx+hy))), wl(con_.wl), mrad(con_.mrad), mask(new unsigned int[hxyz]), qu(new int[qu_size]), qu_l(qu+qu_size) { reset_mask(); } /** Scans all of the particles within a block to see if any of them have a * smaller distance to the given test vector. If one is found, the routine * updates the minimum distance and store information about this particle. * \param[in] ijk the index of the block. * \param[in] (x,y,z) the test vector to consider (which may have already had a * periodic displacement applied to it). * \param[in] (di,dj,dk) the coordinates of the current block, to store if the * particle record is updated. * \param[in,out] w a reference to a particle record in which to store * information about the particle whose Voronoi cell the * vector is within. * \param[in,out] mrs the current minimum distance, that may be updated if a * closer particle is found. */ inline void voro_compute::scan_all(int ijk,double x,double y,double z,int di,int dj,int dk,particle_record &w,double &mrs) { double x1,y1,z1,rs;bool in_block=false; for(int l=0;l=wl_hgrid) { mxs=boxx-fx; m1=127+(3<<21);m2=1+(1<<21);di=wl_fgrid-1-di;if(di<0) di=0; } else {m1=m2=0;mxs=fx;} if(dj>=wl_hgrid) { mys=boxy-fy; m1|=(127<<7)+(3<<24);m2|=(1<<7)+(1<<24);dj=wl_fgrid-1-dj;if(dj<0) dj=0; } else mys=fy; if(dk>=wl_hgrid) { mzs=boxz-fz; m1|=(127<<14)+(3<<27);m2|=(1<<14)+(1<<27);dk=wl_fgrid-1-dk;if(dk<0) dk=0; } else mzs=fz; // Do a quick test to account for the case when the minimum radius is // small enought that no other blocks need to be considered rs=con.r_max_add(mrs); if(mxs*mxs>rs&&mys*mys>rs&&mzs*mzs>rs) return; // Now compute which worklist we are going to use, and set radp and e to // point at the right offsets ijk=di+wl_hgrid*(dj+wl_hgrid*dk); radp=mrad+ijk*wl_seq_length; e=(const_cast (wl))+ijk*wl_seq_length; // Read in how many items in the worklist can be tested without having to // worry about writing to the mask f=e[0];g=0; do { // If mrs is less than the minimum distance to any untested // block, then we are done if(con.r_max_add(mrs)>7)&127;dj-=64; dk=(q>>14)&127;dk-=64; // Check that the worklist position is in range ei=di+i;if(ei<0||ei>=hx) continue; ej=dj+j;if(ej<0||ej>=hy) continue; ek=dk+k;if(ek<0||ek>=hz) continue; // Call the compute_min_max_radius() function. This returns // true if the minimum distance to the block is bigger than the // current mrs, in which case we skip this block and move on. // Otherwise, it computes the maximum distance to the block and // returns it in crs. if(compute_min_radius(di,dj,dk,fx,fy,fz,mrs)) continue; // Now compute which region we are going to loop over, adding a // displacement for the periodic cases ijk=con.region_index(ci,cj,ck,ei,ej,ek,qx,qy,qz,disp); // If mrs is bigger than the maximum distance to the block, // then we have to test all particles in the block for // intersections. Otherwise, we do additional checks and skip // those particles which can't possibly intersect the block. scan_all(ijk,x-qx,y-qy,z-qz,di,dj,dk,w,mrs); } while(g>7)&127;dj-=64; dk=(q>>14)&127;dk-=64; // Compute the position in the mask of the current block. If // this lies outside the mask, then skip it. Otherwise, mark // it. ei=di+i;if(ei<0||ei>=hx) continue; ej=dj+j;if(ej<0||ej>=hy) continue; ek=dk+k;if(ek<0||ek>=hz) continue; mijk=mask+ei+hx*(ej+hy*ek); *mijk=mv; // Skip this block if it is further away than the current // minimum radius if(compute_min_radius(di,dj,dk,fx,fy,fz,mrs)) continue; // Now compute which region we are going to loop over, adding a // displacement for the periodic cases ijk=con.region_index(ci,cj,ck,ei,ej,ek,qx,qy,qz,disp); scan_all(ijk,x-qx,y-qy,z-qz,di,dj,dk,w,mrs); if(qu_e>qu_l-18) add_list_memory(qu_s,qu_e); scan_bits_mask_add(q,mijk,ei,ej,ek,qu_e); } // Do a check to see if we've reached the radius cutoff if(con.r_max_add(mrs)0) if(*(mijk-hxy)!=mv) {if(qu_e==qu_l) qu_e=qu;*(mijk-hxy)=mv;*(qu_e++)=ei;*(qu_e++)=ej;*(qu_e++)=ek-1;} if(ej>0) if(*(mijk-hx)!=mv) {if(qu_e==qu_l) qu_e=qu;*(mijk-hx)=mv;*(qu_e++)=ei;*(qu_e++)=ej-1;*(qu_e++)=ek;} if(ei>0) if(*(mijk-1)!=mv) {if(qu_e==qu_l) qu_e=qu;*(mijk-1)=mv;*(qu_e++)=ei-1;*(qu_e++)=ej;*(qu_e++)=ek;} if(ei0) {*(mijk-1)=mv;*(qu_e++)=ei-1;*(qu_e++)=ej;*(qu_e++)=ek;} if((q&b1)==0&&ei0) {*(mijk-hx)=mv;*(qu_e++)=ei;*(qu_e++)=ej-1;*(qu_e++)=ek;} if((q&b3)==0&&ej0) {*(mijk-hxy)=mv;*(qu_e++)=ei;*(qu_e++)=ej;*(qu_e++)=ek-1;} if((q&b5)==0&&ek (count_list)); // Test all particles in the particle's local region first for(l=0;l=wl_hgrid) { gxs=fx; m1=127+(3<<21);m2=1+(1<<21);di=wl_fgrid-1-di;if(di<0) di=0; } else {m1=m2=0;gxs=boxx-fx;} if(dj>=wl_hgrid) { gys=fy; m1|=(127<<7)+(3<<24);m2|=(1<<7)+(1<<24);dj=wl_fgrid-1-dj;if(dj<0) dj=0; } else gys=boxy-fy; if(dk>=wl_hgrid) { gzs=fz; m1|=(127<<14)+(3<<27);m2|=(1<<14)+(1<<27);dk=wl_fgrid-1-dk;if(dk<0) dk=0; } else gzs=boxz-fz; gxs*=gxs;gys*=gys;gzs*=gzs; // Now compute which worklist we are going to use, and set radp and e to // point at the right offsets ijk=di+wl_hgrid*(dj+wl_hgrid*dk); radp=mrad+ijk*wl_seq_length; e=(const_cast (wl))+ijk*wl_seq_length; // Read in how many items in the worklist can be tested without having to // worry about writing to the mask f=e[0];g=0; do { // At the intervals specified by count_list, we recompute the // maximum radius squared if(g==next_count) { mrs=c.max_radius_squared(); if(count_p!=count_e) next_count=*(count_p++); } // If mrs is less than the minimum distance to any untested // block, then we are done if(con.r_ctest(radp[g],mrs)) return true; g++; // Load in a block off the worklist, permute it with the // symmetry mask, and decode its position. These are all // integer bit operations so they should run very fast. q=e[g];q^=m1;q+=m2; di=q&127;di-=64; dj=(q>>7)&127;dj-=64; dk=(q>>14)&127;dk-=64; // Check that the worklist position is in range ei=di+i;if(ei<0||ei>=hx) continue; ej=dj+j;if(ej<0||ej>=hy) continue; ek=dk+k;if(ek<0||ek>=hz) continue; // Call the compute_min_max_radius() function. This returns // true if the minimum distance to the block is bigger than the // current mrs, in which case we skip this block and move on. // Otherwise, it computes the maximum distance to the block and // returns it in crs. if(compute_min_max_radius(di,dj,dk,fx,fy,fz,gxs,gys,gzs,crs,mrs)) continue; // Now compute which region we are going to loop over, adding a // displacement for the periodic cases ijk=con.region_index(ci,cj,ck,ei,ej,ek,qx,qy,qz,disp); // If mrs is bigger than the maximum distance to the block, // then we have to test all particles in the block for // intersections. Otherwise, we do additional checks and skip // those particles which can't possibly intersect the block. if(co[ijk]>0) { l=0;x2=x-qx;y2=y-qy;z2=z-qz; if(!con.r_ctest(crs,mrs)) { do { x1=p[ijk][ps*l]-x2; y1=p[ijk][ps*l+1]-y2; z1=p[ijk][ps*l+2]-z2; rs=con.r_scale(x1*x1+y1*y1+z1*z1,ijk,l); if(!c.nplane(x1,y1,z1,rs,id[ijk][l])) { if (!g_bVoroSilent) mprintf("\nvoro_compute::compute_cell(): Error A4."); return false; } l++; } while (l>7)&127;dj-=64; dk=(q>>14)&127;dk-=64; // Compute the position in the mask of the current block. If // this lies outside the mask, then skip it. Otherwise, mark // it. ei=di+i;if(ei<0||ei>=hx) continue; ej=dj+j;if(ej<0||ej>=hy) continue; ek=dk+k;if(ek<0||ek>=hz) continue; mijk=mask+ei+hx*(ej+hy*ek); *mijk=mv; // Call the compute_min_max_radius() function. This returns // true if the minimum distance to the block is bigger than the // current mrs, in which case we skip this block and move on. // Otherwise, it computes the maximum distance to the block and // returns it in crs. if(compute_min_max_radius(di,dj,dk,fx,fy,fz,gxs,gys,gzs,crs,mrs)) continue; // Now compute which region we are going to loop over, adding a // displacement for the periodic cases ijk=con.region_index(ci,cj,ck,ei,ej,ek,qx,qy,qz,disp); // If mrs is bigger than the maximum distance to the block, // then we have to test all particles in the block for // intersections. Otherwise, we do additional checks and skip // those particles which can't possibly intersect the block. if(co[ijk]>0) { l=0;x2=x-qx;y2=y-qy;z2=z-qz; if(!con.r_ctest(crs,mrs)) { do { x1=p[ijk][ps*l]-x2; y1=p[ijk][ps*l+1]-y2; z1=p[ijk][ps*l+2]-z2; rs=con.r_scale(x1*x1+y1*y1+z1*z1,ijk,l); if(!c.nplane(x1,y1,z1,rs,id[ijk][l])) { if (!g_bVoroSilent) mprintf("\nvoro_compute::compute_cell(): Error A6."); return false; } l++; } while (lqu_l-18) add_list_memory(qu_s,qu_e); // Test the parts of the worklist element which tell us what // neighbors of this block are not on the worklist. Store them // on the block list, and mark the mask. scan_bits_mask_add(q,mijk,ei,ej,ek,qu_e); } // Do a check to see if we've reached the radius cutoff if(con.r_ctest(radp[g],mrs)) return true; // We were unable to completely compute the cell based on the blocks in // the worklist, so now we have to go block by block, reading in items // off the list while(qu_s!=qu_e) { // If we reached the end of the list memory loop back to the // start if(qu_s==qu_l) qu_s=qu; // Read in a block off the list, and compute the upper and lower // coordinates in each of the three dimensions ei=*(qu_s++);ej=*(qu_s++);ek=*(qu_s++); xlo=(ei-i)*boxx-fx;xhi=xlo+boxx; ylo=(ej-j)*boxy-fy;yhi=ylo+boxy; zlo=(ek-k)*boxz-fz;zhi=zlo+boxz; // Carry out plane tests to see if any particle in this block // could possibly intersect the cell if(ei>i) { if(ej>j) { if(ek>k) {if(corner_test(c,xlo,ylo,zlo,xhi,yhi,zhi)) continue;} else if(ekk) {if(corner_test(c,xlo,yhi,zlo,xhi,ylo,zhi)) continue;} else if(ekk) {if(edge_y_test(c,xlo,ylo,zlo,xhi,yhi,zhi)) continue;} else if(ekj) { if(ek>k) {if(corner_test(c,xhi,ylo,zlo,xlo,yhi,zhi)) continue;} else if(ekk) {if(corner_test(c,xhi,yhi,zlo,xlo,ylo,zhi)) continue;} else if(ekk) {if(edge_y_test(c,xhi,ylo,zlo,xlo,yhi,zhi)) continue;} else if(ekj) { if(ek>k) {if(edge_x_test(c,xlo,ylo,zlo,xhi,yhi,zhi)) continue;} else if(ekk) {if(edge_x_test(c,xlo,yhi,zlo,xhi,ylo,zhi)) continue;} else if(ekk) {if(face_z_test(c,xlo,ylo,zlo,xhi,yhi)) continue;} else if(ek0) { l=0;x2=x-qx;y2=y-qy;z2=z-qz; do { x1=p[ijk][ps*l]-x2; y1=p[ijk][ps*l+1]-y2; z1=p[ijk][ps*l+2]-z2; rs=con.r_scale(x1*x1+y1*y1+z1*z1,ijk,l); if(!c.nplane(x1,y1,z1,rs,id[ijk][l])) { if (!g_bVoroSilent) mprintf("\nvoro_compute::compute_cell(): Error A8."); return false; } l++; } while (l0) { xlo=di*boxx-fx; crs=xlo*xlo; if(dj>0) { ylo=dj*boxy-fy; crs+=ylo*ylo; if(dk>0) { zlo=dk*boxz-fz; crs+=zlo*zlo;if(con.r_ctest(crs,mrs)) return true; crs+=bxsq+2*(boxx*xlo+boxy*ylo+boxz*zlo); } else if(dk<0) { zlo=(dk+1)*boxz-fz; crs+=zlo*zlo;if(con.r_ctest(crs,mrs)) return true; crs+=bxsq+2*(boxx*xlo+boxy*ylo-boxz*zlo); } else { if(con.r_ctest(crs,mrs)) return true; crs+=boxx*(2*xlo+boxx)+boxy*(2*ylo+boxy)+gzs; } } else if(dj<0) { ylo=(dj+1)*boxy-fy; crs+=ylo*ylo; if(dk>0) { zlo=dk*boxz-fz; crs+=zlo*zlo;if(con.r_ctest(crs,mrs)) return true; crs+=bxsq+2*(boxx*xlo-boxy*ylo+boxz*zlo); } else if(dk<0) { zlo=(dk+1)*boxz-fz; crs+=zlo*zlo;if(con.r_ctest(crs,mrs)) return true; crs+=bxsq+2*(boxx*xlo-boxy*ylo-boxz*zlo); } else { if(con.r_ctest(crs,mrs)) return true; crs+=boxx*(2*xlo+boxx)+boxy*(-2*ylo+boxy)+gzs; } } else { if(dk>0) { zlo=dk*boxz-fz; crs+=zlo*zlo;if(con.r_ctest(crs,mrs)) return true; crs+=boxz*(2*zlo+boxz); } else if(dk<0) { zlo=(dk+1)*boxz-fz; crs+=zlo*zlo;if(con.r_ctest(crs,mrs)) return true; crs+=boxz*(-2*zlo+boxz); } else { if(con.r_ctest(crs,mrs)) return true; crs+=gzs; } crs+=gys+boxx*(2*xlo+boxx); } } else if(di<0) { xlo=(di+1)*boxx-fx; crs=xlo*xlo; if(dj>0) { ylo=dj*boxy-fy; crs+=ylo*ylo; if(dk>0) { zlo=dk*boxz-fz; crs+=zlo*zlo;if(con.r_ctest(crs,mrs)) return true; crs+=bxsq+2*(-boxx*xlo+boxy*ylo+boxz*zlo); } else if(dk<0) { zlo=(dk+1)*boxz-fz; crs+=zlo*zlo;if(con.r_ctest(crs,mrs)) return true; crs+=bxsq+2*(-boxx*xlo+boxy*ylo-boxz*zlo); } else { if(con.r_ctest(crs,mrs)) return true; crs+=boxx*(-2*xlo+boxx)+boxy*(2*ylo+boxy)+gzs; } } else if(dj<0) { ylo=(dj+1)*boxy-fy; crs+=ylo*ylo; if(dk>0) { zlo=dk*boxz-fz; crs+=zlo*zlo;if(con.r_ctest(crs,mrs)) return true; crs+=bxsq+2*(-boxx*xlo-boxy*ylo+boxz*zlo); } else if(dk<0) { zlo=(dk+1)*boxz-fz; crs+=zlo*zlo;if(con.r_ctest(crs,mrs)) return true; crs+=bxsq+2*(-boxx*xlo-boxy*ylo-boxz*zlo); } else { if(con.r_ctest(crs,mrs)) return true; crs+=boxx*(-2*xlo+boxx)+boxy*(-2*ylo+boxy)+gzs; } } else { if(dk>0) { zlo=dk*boxz-fz; crs+=zlo*zlo;if(con.r_ctest(crs,mrs)) return true; crs+=boxz*(2*zlo+boxz); } else if(dk<0) { zlo=(dk+1)*boxz-fz; crs+=zlo*zlo;if(con.r_ctest(crs,mrs)) return true; crs+=boxz*(-2*zlo+boxz); } else { if(con.r_ctest(crs,mrs)) return true; crs+=gzs; } crs+=gys+boxx*(-2*xlo+boxx); } } else { if(dj>0) { ylo=dj*boxy-fy; crs=ylo*ylo; if(dk>0) { zlo=dk*boxz-fz; crs+=zlo*zlo;if(con.r_ctest(crs,mrs)) return true; crs+=boxz*(2*zlo+boxz); } else if(dk<0) { zlo=(dk+1)*boxz-fz; crs+=zlo*zlo;if(con.r_ctest(crs,mrs)) return true; crs+=boxz*(-2*zlo+boxz); } else { if(con.r_ctest(crs,mrs)) return true; crs+=gzs; } crs+=boxy*(2*ylo+boxy); } else if(dj<0) { ylo=(dj+1)*boxy-fy; crs=ylo*ylo; if(dk>0) { zlo=dk*boxz-fz; crs+=zlo*zlo;if(con.r_ctest(crs,mrs)) return true; crs+=boxz*(2*zlo+boxz); } else if(dk<0) { zlo=(dk+1)*boxz-fz; crs+=zlo*zlo;if(con.r_ctest(crs,mrs)) return true; crs+=boxz*(-2*zlo+boxz); } else { if(con.r_ctest(crs,mrs)) return true; crs+=gzs; } crs+=boxy*(-2*ylo+boxy); } else { if(dk>0) { zlo=dk*boxz-fz;crs=zlo*zlo;if(con.r_ctest(crs,mrs)) return true; crs+=boxz*(2*zlo+boxz); } else if(dk<0) { zlo=(dk+1)*boxz-fz;crs=zlo*zlo;if(con.r_ctest(crs,mrs)) return true; crs+=boxz*(-2*zlo+boxz); } else { crs=0; voro_fatal_error("Min/max radius function called for central block, which should never\nhappen.",VOROPP_INTERNAL_ERROR); } crs+=gys; } crs+=gxs; } return false; } bool voro_compute::compute_min_radius(int di,int dj,int dk,double fx,double fy,double fz,double mrs) { double t,crs; if(di>0) {t=di*boxx-fx;crs=t*t;} else if(di<0) {t=(di+1)*boxx-fx;crs=t*t;} else crs=0; if(dj>0) {t=dj*boxy-fy;crs+=t*t;} else if(dj<0) {t=(dj+1)*boxy-fy;crs+=t*t;} if(dk>0) {t=dk*boxz-fz;crs+=t*t;} else if(dk<0) {t=(dk+1)*boxz-fz;crs+=t*t;} return crs>con.r_max_add(mrs); } /** Adds memory to the queue. * \param[in,out] qu_s a reference to the queue start pointer. * \param[in,out] qu_e a reference to the queue end pointer. */ inline void voro_compute::add_list_memory(int*& qu_s,int*& qu_e) { qu_size<<=1; int *qu_n=new int[qu_size],*qu_c=qu_n; #if VOROPP_VERBOSE >=2 fprintf(stderr,"List memory scaled up to %d\n",qu_size); #endif if(qu_s<=qu_e) { while(qu_s. *****************************************************************************/ // Voro++, a 3D cell-based Voronoi library // // Author : Chris H. Rycroft (LBL / UC Berkeley) // Email : chr@alum.mit.edu // Date : August 30th 2011 /** \file v_compute.hh * \brief Header file for the voro_compute template and related classes. */ #ifndef VOROPP_V_COMPUTE_HH #define VOROPP_V_COMPUTE_HH // This must always be the first include directive #include "config.h" #include #include #include #include #include "v_config.h" #include "v_worklist.h" #include "v_cell.h" class container_periodic_poly; /** \brief Structure for holding information about a particle. * * This small structure holds information about a single particle, and is used * by several of the routines in the voro_compute template for passing * information by reference between functions. */ struct particle_record { /** The index of the block that the particle is within. */ int ijk; /** The number of particle within its block. */ int l; /** The x-index of the block. */ int di; /** The y-index of the block. */ int dj; /** The z-index of the block. */ int dk; }; /** \brief Template for carrying out Voronoi cell computations. */ class voro_compute { public: /** A reference to the container class on which to carry out*/ container_periodic_poly &con; /** The size of an internal computational block in the x * direction. */ const double boxx; /** The size of an internal computational block in the y * direction. */ const double boxy; /** The size of an internal computational block in the z * direction. */ const double boxz; /** The inverse box length in the x direction, set to * nx/(bx-ax). */ const double xsp; /** The inverse box length in the y direction, set to * ny/(by-ay). */ const double ysp; /** The inverse box length in the z direction, set to * nz/(bz-az). */ const double zsp; /** The number of boxes in the x direction for the searching mask. */ const int hx; /** The number of boxes in the y direction for the searching mask. */ const int hy; /** The number of boxes in the z direction for the searching mask. */ const int hz; /** A constant, set to the value of hx multiplied by hy, which * is used in the routines which step through mask boxes in * sequence. */ const int hxy; /** A constant, set to the value of hx*hy*hz, which is used in * the routines which step through mask boxes in sequence. */ const int hxyz; /** The number of floating point entries to store for each * particle. */ const int ps; /** This array holds the numerical IDs of each particle in each * computational box. */ int **id; /** A two dimensional array holding particle positions. For the * derived container_poly class, this also holds particle * radii. */ double **p; /** An array holding the number of particles within each * computational box of the container. */ int *co; voro_compute(container_periodic_poly &con_,int hx_,int hy_,int hz_); /** The class destructor frees the dynamically allocated memory * for the mask and queue. */ ~voro_compute() { delete [] qu; delete [] mask; } bool compute_cell(voronoicell_neighbor &c,int ijk,int s,int ci,int cj,int ck); void find_voronoi_cell(double x,double y,double z,int ci,int cj,int ck,int ijk,particle_record &w,double &mrs); private: /** A constant set to boxx*boxx+boxy*boxy+boxz*boxz, which is * frequently used in the computation. */ const double bxsq; /** This sets the current value being used to mark tested blocks * in the mask. */ unsigned int mv; /** The current size of the search list. */ int qu_size; /** A pointer to the array of worklists. */ const unsigned int *wl; /** An pointer to the array holding the minimum distances * associated with the worklists. */ double *mrad; /** This array is used during the cell computation to determine * which blocks have been considered. */ unsigned int *mask; /** An array is used to store the queue of blocks to test * during the Voronoi cell computation. */ int *qu; /** A pointer to the end of the queue array, used to determine * when the queue is full. */ int *qu_l; bool corner_test(voronoicell_neighbor &c,double xl,double yl,double zl,double xh,double yh,double zh); inline bool edge_x_test(voronoicell_neighbor &c,double x0,double yl,double zl,double x1,double yh,double zh); inline bool edge_y_test(voronoicell_neighbor &c,double xl,double y0,double zl,double xh,double y1,double zh); inline bool edge_z_test(voronoicell_neighbor &c,double xl,double yl,double z0,double xh,double yh,double z1); inline bool face_x_test(voronoicell_neighbor &c,double xl,double y0,double z0,double y1,double z1); inline bool face_y_test(voronoicell_neighbor &c,double x0,double yl,double z0,double x1,double z1); inline bool face_z_test(voronoicell_neighbor &c,double x0,double y0,double zl,double x1,double y1); bool compute_min_max_radius(int di,int dj,int dk,double fx,double fy,double fz,double gx,double gy,double gz,double& crs,double mrs); bool compute_min_radius(int di,int dj,int dk,double fx,double fy,double fz,double mrs); inline void add_to_mask(int ei,int ej,int ek,int *&qu_e); inline void scan_bits_mask_add(unsigned int q,unsigned int *mijk,int ei,int ej,int ek,int *&qu_e); inline void scan_all(int ijk,double x,double y,double z,int di,int dj,int dk,particle_record &w,double &mrs); void add_list_memory(int*& qu_s,int*& qu_e); /** Resets the mask in cases where the mask counter wraps * around. */ inline void reset_mask() { for(unsigned int *mp = (mask);mp. *****************************************************************************/ // Voro++, a 3D cell-based Voronoi library // // Author : Chris H. Rycroft (LBL / UC Berkeley) // Email : chr@alum.mit.edu // Date : August 30th 2011 /** \file config.hh * \brief Master configuration file for setting various compile-time options. */ #ifndef VOROPP_CONFIG_HH #define VOROPP_CONFIG_HH // This must always be the first include directive #include "config.h" #define VOROPP_VERBOSE 3 // These constants set the initial memory allocation for the Voronoi cell /** The initial memory allocation for the number of vertices. */ const int init_vertices=256; /** The initial memory allocation for the maximum vertex order. */ const int init_vertex_order=64; /** The initial memory allocation for the number of regular vertices of order 3. */ const int init_3_vertices=256; /** The initial memory allocation for the number of vertices of higher order. */ const int init_n_vertices=8; /** The initial buffer size for marginal cases used by the suretest class. */ const int init_marginal=64; /** The initial size for the delete stack. */ const int init_delete_size=256; /** The initial size for the auxiliary delete stack. */ const int init_delete2_size=256; /** The initial size for the wall pointer array. */ const int init_wall_size=32; /** The default initial size for the ordering class. */ const int init_ordering_size=4096; /** The initial size of the pre_container chunk index. */ const int init_chunk_size=256; // If the initial memory is too small, the program dynamically allocates more. // However, if the limits below are reached, then the program bails out. /** The maximum memory allocation for the number of vertices. */ const int max_vertices=16777216; /** The maximum memory allocation for the maximum vertex order. */ const int max_vertex_order=2048; /** The maximum memory allocation for the any particular order of vertex. */ const int max_n_vertices=16777216; /** The maximum buffer size for marginal cases used by the suretest class. */ const int max_marginal=16777216; /** The maximum size for the delete stack. */ const int max_delete_size=16777216; /** The maximum size for the auxiliary delete stack. */ const int max_delete2_size=16777216; /** The maximum amount of particle memory allocated for a single region. */ const int max_particle_memory=16777216; /** The maximum size for the wall pointer array. */ const int max_wall_size=2048; /** The maximum size for the ordering class. */ const int max_ordering_size=67108864; /** The maximum size for the pre_container chunk index. */ const int max_chunk_size=65536; /** The chunk size in the pre_container classes. */ const int pre_container_chunk_size=1024; #ifndef VOROPP_VERBOSE /** Voro++ can print a number of different status and debugging messages to * notify the user of special behavior, and this macro sets the amount which * are displayed. At level 0, no messages are printed. At level 1, messages * about unusual cases during cell construction are printed, such as when the * plane routine bails out due to floating point problems. At level 2, general * messages about memory expansion are printed. At level 3, technical details * about memory management are printed. */ #define VOROPP_VERBOSE 0 #endif /** If a point is within this distance of a cutting plane, then the code * assumes that point exactly lies on the plane. */ const double tolerance=1e-11; /** If a point is within this distance of a cutting plane, then the code stores * whether this point is inside, outside, or exactly on the cutting plane in * the marginal cases buffer, to prevent the test giving a different result on * a subsequent evaluation due to floating point rounding errors. */ const double tolerance2=2e-11; /** The square of the tolerance, used when deciding whether some squared * quantities are large enough to be used. */ const double tolerance_sq=tolerance*tolerance; /** A large number that is used in the computation. */ const double large_number=1e30; /** A radius to use as a placeholder when no other information is available. */ const double default_radius=0.5; /** The maximum number of shells of periodic images to test over. */ const int max_unit_voro_shells=10; /** A guess for the optimal number of particles per block, used to set up the * container grid. */ const double optimal_particles=5.6; /** If this is set to 1, then the code reports any instances of particles being * put outside of the container geometry. */ #define VOROPP_REPORT_OUT_OF_BOUNDS 0 /** Voro++ returns this status code if there is a file-related error, such as * not being able to open file. */ #define VOROPP_FILE_ERROR 1 /** Voro++ returns this status code if there is a memory allocation error, if * one of the safe memory limits is exceeded. */ #define VOROPP_MEMORY_ERROR 2 /** Voro++ returns this status code if there is any type of internal error, if * it detects that representation of the Voronoi cell is inconsistent. This * status code will generally indicate a bug, and the developer should be * contacted. */ #define VOROPP_INTERNAL_ERROR 3 /** Voro++ returns this status code if it could not interpret the command line * arguments passed to the command line utility. */ #define VOROPP_CMD_LINE_ERROR 4 #endif travis-src-190101/src/v_container.cpp0100777000000000000000000002600213412725621014447 0ustar00/***************************************************************************** TRAVIS - Trajectory Analyzer and Visualizer http://www.travis-analyzer.de/ Copyright (c) 2009-2019 Martin Brehm 2012-2019 Martin Thomas 2016-2019 Sascha Gehrke --------------------------------------------------------------------------- This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . *****************************************************************************/ // Voro++, a 3D cell-based Voronoi library // // Author : Chris H. Rycroft (LBL / UC Berkeley) // Email : chr@alum.mit.edu // Date : August 30th 2011 /** \file container.cc * \brief Function implementations for the container and related classes. */ // This must always be the first include directive #include "config.h" #include "v_container.h" #include "tools.h" const char *GetRevisionInfo_v_container(unsigned int len) { static char buf[256]; GET_REVISION_INFO( buf, len ); return buf; } const char *GetSourceVersion_v_container() { static char buf[256]; GET_SOURCE_VERSION( buf ); return buf; } /** The class constructor sets up the geometry of container, initializing the * minimum and maximum coordinates in each direction, and setting whether each * direction is periodic or not. It divides the container into a rectangular * grid of blocks, and allocates memory for each of these for storing particle * positions and IDs. * \param[in] (ax_,bx_) the minimum and maximum x coordinates. * \param[in] (ay_,by_) the minimum and maximum y coordinates. * \param[in] (az_,bz_) the minimum and maximum z coordinates. * \param[in] (nx_,ny_,nz_) the number of grid blocks in each of the three * coordinate directions. * \param[in] (xperiodic_,yperiodic_,zperiodic_) flags setting whether the * container is periodic in each * coordinate direction. * \param[in] init_mem the initial memory allocation for each block. * \param[in] ps_ the number of floating point entries to store for each * particle. */ container_base::container_base(double ax_,double bx_,double ay_,double by_,double az_,double bz_, int nx_,int ny_,int nz_,bool xperiodic_,bool yperiodic_,bool zperiodic_,int init_mem,int ps_) : voro_base(nx_,ny_,nz_,(bx_-ax_)/nx_,(by_-ay_)/ny_,(bz_-az_)/nz_), ax(ax_), bx(bx_), ay(ay_), by(by_), az(az_), bz(bz_), xperiodic(xperiodic_), yperiodic(yperiodic_), zperiodic(zperiodic_), id(new int*[nxyz]), p(new double*[nxyz]), co(new int[nxyz]), mem(new int[nxyz]), ps(ps_) { int l; for(l=0;l=nx) return false; int j=step_int((y-ay)*ysp); if(yperiodic) {l=step_mod(j,ny);y+=boxy*(l-j);j=l;} else if(j<0||j>=ny) return false; int k=step_int((z-az)*zsp); if(zperiodic) {l=step_mod(k,nz);z+=boxz*(l-k);k=l;} else if(k<0||k>=nz) return false; ijk+=nx*j+nxy*k; return true; } /** Takes a position vector and attempts to remap it into the primary domain. * \param[out] (ai,aj,ak) the periodic image displacement that the vector is in, * with (0,0,0) corresponding to the primary domain. * \param[out] (ci,cj,ck) the index of the block that the position vector is * within, once it has been remapped. * \param[in,out] (x,y,z) the position vector to consider, which is remapped * into the primary domain during the routine. * \param[out] ijk the block index that the vector is within. * \return True if the particle is within the container or can be remapped into * it, false if it lies outside of the container bounds. */ inline bool container_base::remap(int &ai,int &aj,int &ak,int &ci,int &cj,int &ck,double &x,double &y,double &z,int &ijk) { ci=step_int((x-ax)*xsp); if(ci<0||ci>=nx) { if(xperiodic) {ai=step_div(ci,nx);x-=ai*(bx-ax);ci-=ai*nx;} else return false; } else ai=0; cj=step_int((y-ay)*ysp); if(cj<0||cj>=ny) { if(yperiodic) {aj=step_div(cj,ny);y-=aj*(by-ay);cj-=aj*ny;} else return false; } else aj=0; ck=step_int((z-az)*zsp); if(ck<0||ck>=nz) { if(zperiodic) {ak=step_div(ck,nz);z-=ak*(bz-az);ck-=ak*nz;} else return false; } else ak=0; ijk=ci+nx*cj+nxy*ck; return true; } /** Increase memory for a particular region. * \param[in] i the index of the region to reallocate. */ void container_base::add_particle_memory(int i) { int l,nmem=mem[i]<<1; // Carry out a check on the memory allocation size, and // print a status message if requested if(nmem>max_particle_memory) voro_fatal_error("Absolute maximum memory allocation exceeded",VOROPP_MEMORY_ERROR); #if VOROPP_VERBOSE >=3 fprintf(stderr,"Particle memory in region %d scaled up to %d\n",i,nmem); #endif // Allocate new memory and copy in the contents of the old arrays int *idp=new int[nmem]; for(l=0;lbx||yby||zbz) return false; return point_inside_walls(x,y,z); } /** Draws an outline of the domain in gnuplot format. * \param[in] fp the file handle to write to. */ void container_base::draw_domain_gnuplot(FILE *fp) { fprintf(fp,"%g %g %g\n%g %g %g\n%g %g %g\n%g %g %g\n",ax,ay,az,bx,ay,az,bx,by,az,ax,by,az); fprintf(fp,"%g %g %g\n%g %g %g\n%g %g %g\n%g %g %g\n",ax,by,bz,bx,by,bz,bx,ay,bz,ax,ay,bz); fprintf(fp,"%g %g %g\n\n%g %g %g\n%g %g %g\n\n",ax,by,bz,ax,ay,az,ax,ay,bz); fprintf(fp,"%g %g %g\n%g %g %g\n\n%g %g %g\n%g %g %g\n\n",bx,ay,az,bx,ay,bz,bx,by,az,bx,by,bz); } /** Draws an outline of the domain in POV-Ray format. * \param[in] fp the file handle to write to. */ void container_base::draw_domain_pov(FILE *fp) { fprintf(fp,"cylinder{<%g,%g,%g>,<%g,%g,%g>,rr}\n" "cylinder{<%g,%g,%g>,<%g,%g,%g>,rr}\n",ax,ay,az,bx,ay,az,ax,by,az,bx,by,az); fprintf(fp,"cylinder{<%g,%g,%g>,<%g,%g,%g>,rr}\n" "cylinder{<%g,%g,%g>,<%g,%g,%g>,rr}\n",ax,by,bz,bx,by,bz,ax,ay,bz,bx,ay,bz); fprintf(fp,"cylinder{<%g,%g,%g>,<%g,%g,%g>,rr}\n" "cylinder{<%g,%g,%g>,<%g,%g,%g>,rr}\n",ax,ay,az,ax,by,az,bx,ay,az,bx,by,az); fprintf(fp,"cylinder{<%g,%g,%g>,<%g,%g,%g>,rr}\n" "cylinder{<%g,%g,%g>,<%g,%g,%g>,rr}\n",bx,ay,bz,bx,by,bz,ax,ay,bz,ax,by,bz); fprintf(fp,"cylinder{<%g,%g,%g>,<%g,%g,%g>,rr}\n" "cylinder{<%g,%g,%g>,<%g,%g,%g>,rr}\n",ax,ay,az,ax,ay,bz,bx,ay,az,bx,ay,bz); fprintf(fp,"cylinder{<%g,%g,%g>,<%g,%g,%g>,rr}\n" "cylinder{<%g,%g,%g>,<%g,%g,%g>,rr}\n",bx,by,az,bx,by,bz,ax,by,az,ax,by,bz); fprintf(fp,"sphere{<%g,%g,%g>,rr}\nsphere{<%g,%g,%g>,rr}\n" "sphere{<%g,%g,%g>,rr}\nsphere{<%g,%g,%g>,rr}\n",ax,ay,az,bx,ay,az,ax,by,az,bx,by,az); fprintf(fp,"sphere{<%g,%g,%g>,rr}\nsphere{<%g,%g,%g>,rr}\n" "sphere{<%g,%g,%g>,rr}\nsphere{<%g,%g,%g>,rr}\n",ax,ay,bz,bx,ay,bz,ax,by,bz,bx,by,bz); } /** The wall_list constructor sets up an array of pointers to wall classes. */ wall_list::wall_list() : walls(new wall*[init_wall_size]), wep(walls), wel(walls+init_wall_size), current_wall_size(init_wall_size) {} /** The wall_list destructor frees the array of pointers to the wall classes. */ wall_list::~wall_list() { delete [] walls; } /** Adds all of the walls on another wall_list to this class. * \param[in] wl a reference to the wall class. */ void wall_list::add_wall(wall_list &wl) { for(wall **wp=wl.walls;wpmax_wall_size) voro_fatal_error("Wall memory allocation exceeded absolute maximum",VOROPP_MEMORY_ERROR); wall **nwalls=new wall*[current_wall_size],**nwp=nwalls,**wp=walls; while(wp. *****************************************************************************/ // Voro++, a 3D cell-based Voronoi library // // Author : Chris H. Rycroft (LBL / UC Berkeley) // Email : chr@alum.mit.edu // Date : August 30th 2011 /** \file container.hh * \brief Header file for the container_base and related classes. */ #ifndef VOROPP_CONTAINER_HH #define VOROPP_CONTAINER_HH // This must always be the first include directive #include "config.h" #include #include #include #include #include "v_config.h" #include "v_common.h" #include "v_base.h" #include "v_cell.h" #include "v_c_loops.h" #include "v_compute.h" #include "v_rad_option.h" /** \brief Pure virtual class from which wall objects are derived. * * This is a pure virtual class for a generic wall object. A wall object * can be specified by deriving a new class from this and specifying the * functions.*/ class wall { public: virtual ~wall() {} /** A pure virtual function for testing whether a point is * inside the wall object. */ virtual bool point_inside(double x,double y,double z) = 0; /** A pure virtual function for cutting a cell without * neighbor-tracking with a wall. */ // virtual bool cut_cell(voronoicell &c,double x,double y,double z) = 0; /** A pure virtual function for cutting a cell with * neighbor-tracking enabled with a wall. */ virtual bool cut_cell(voronoicell_neighbor &c,double x,double y,double z) = 0; }; /** \brief A class for storing a list of pointers to walls. * * This class stores a list of pointers to wall classes. It contains several * simple routines that make use of the wall classes (such as telling whether a * given position is inside all of the walls or not). It can be used by itself, * but also forms part of container_base, for associating walls with this * class. */ class wall_list { public: /** An array holding pointers to wall objects. */ wall **walls; /** A pointer to the next free position to add a wall pointer. */ wall **wep; wall_list(); ~wall_list(); /** Adds a wall to the list. * \param[in] w the wall to add. */ inline void add_wall(wall *w) { if(wep==wel) increase_wall_memory(); *(wep++)=w; } /** Adds a wall to the list. * \param[in] w a reference to the wall to add. */ inline void add_wall(wall &w) {add_wall(&w);} void add_wall(wall_list &wl); /** Determines whether a given position is inside all of the * walls on the list. * \param[in] (x,y,z) the position to test. * \return True if it is inside, false if it is outside. */ inline bool point_inside_walls(double x,double y,double z) { for(wall **wp=walls;wppoint_inside(x,y,z))) return false; return true; } /** Cuts a Voronoi cell by all of the walls currently on * the list. * \param[in] c a reference to the Voronoi cell class. * \param[in] (x,y,z) the position of the cell. * \return True if the cell still exists, false if the cell is * deleted. */ bool apply_walls(voronoicell_neighbor &c,double x,double y,double z) { for(wall **wp=walls;wpcut_cell(c,x,y,z))) return false; return true; } void deallocate(); protected: void increase_wall_memory(); /** A pointer to the limit of the walls array, used to * determine when array is full. */ wall **wel; /** The current amount of memory allocated for walls. */ int current_wall_size; }; /** \brief Class for representing a particle system in a three-dimensional * rectangular box. * * This class represents a system of particles in a three-dimensional * rectangular box. Any combination of non-periodic and periodic coordinates * can be used in the three coordinate directions. The class is not intended * for direct use, but instead forms the base of the container and * container_poly classes that add specialized routines for computing the * regular and radical Voronoi tessellations respectively. It contains routines * that are commonly between these two classes, such as those for drawing the * domain, and placing particles within the internal data structure. * * The class is derived from the wall_list class, which encapsulates routines * for associating walls with the container, and the voro_base class, which * encapsulates routines about the underlying computational grid. */ class container_base : public voro_base, public wall_list { public: /** The minimum x coordinate of the container. */ const double ax; /** The maximum x coordinate of the container. */ const double bx; /** The minimum y coordinate of the container. */ const double ay; /** The maximum y coordinate of the container. */ const double by; /** The minimum z coordinate of the container. */ const double az; /** The maximum z coordinate of the container. */ const double bz; /** A boolean value that determines if the x coordinate in * periodic or not. */ const bool xperiodic; /** A boolean value that determines if the y coordinate in * periodic or not. */ const bool yperiodic; /** A boolean value that determines if the z coordinate in * periodic or not. */ const bool zperiodic; /** This array holds the numerical IDs of each particle in each * computational box. */ int **id; /** A two dimensional array holding particle positions. For the * derived container_poly class, this also holds particle * radii. */ double **p; /** This array holds the number of particles within each * computational box of the container. */ int *co; /** This array holds the maximum amount of particle memory for * each computational box of the container. If the number of * particles in a particular box ever approaches this limit, * more is allocated using the add_particle_memory() function. */ int *mem; /** The amount of memory in the array structure for each * particle. This is set to 3 when the basic class is * initialized, so that the array holds (x,y,z) positions. If * the container class is initialized as part of the derived * class container_poly, then this is set to 4, to also hold * the particle radii. */ const int ps; container_base(double ax_,double bx_,double ay_,double by_,double az_,double bz_, int nx_,int ny_,int nz_,bool xperiodic_,bool yperiodic_,bool zperiodic_, int init_mem,int ps_); ~container_base(); bool point_inside(double x,double y,double z); void region_count(); /** Initializes the Voronoi cell prior to a compute_cell * operation for a specific particle being carried out by a * voro_compute class. The cell is initialized to fill the * entire container. For non-periodic coordinates, this is set * by the position of the walls. For periodic coordinates, the * space is equally divided in either direction from the * particle's initial position. Plane cuts made by any walls * that have been added are then applied to the cell. * \param[in,out] c a reference to a voronoicell object. * \param[in] ijk the block that the particle is within. * \param[in] q the index of the particle within its block. * \param[in] (ci,cj,ck) the coordinates of the block in the * container coordinate system. * \param[out] (i,j,k) the coordinates of the test block * relative to the voro_compute * coordinate system. * \param[out] (x,y,z) the position of the particle. * \param[out] disp a block displacement used internally by the * compute_cell routine. * \return False if the plane cuts applied by walls completely * removed the cell, true otherwise. */ inline bool initialize_voronoicell(voronoicell_neighbor &c,int ijk,int q,int ci,int cj,int ck, int &i,int &j,int &k,double &x,double &y,double &z,int &disp) { double x1,x2,y1,y2,z1,z2,*pp=p[ijk]+ps*q; x=*(pp++);y=*(pp++);z=*pp; if(xperiodic) {x1=-(x2=0.5*(bx-ax));i=nx;} else {x1=ax-x;x2=bx-x;i=ci;} if(yperiodic) {y1=-(y2=0.5*(by-ay));j=ny;} else {y1=ay-y;y2=by-y;j=cj;} if(zperiodic) {z1=-(z2=0.5*(bz-az));k=nz;} else {z1=az-z;z2=bz-z;k=ck;} c.init(x1,x2,y1,y2,z1,z2); if(!apply_walls(c,x,y,z)) return false; disp=ijk-i-nx*(j+ny*k); return true; } /** Initializes parameters for a find_voronoi_cell call within * the voro_compute template. * \param[in] (ci,cj,ck) the coordinates of the test block in * the container coordinate system. * \param[in] ijk the index of the test block * \param[out] (i,j,k) the coordinates of the test block * relative to the voro_compute * coordinate system. * \param[out] disp a block displacement used internally by the * find_voronoi_cell routine. */ inline void initialize_search(int ci,int cj,int ck,int ijk,int &i,int &j,int &k,int &disp) { i=xperiodic?nx:ci; j=yperiodic?ny:cj; k=zperiodic?nz:ck; disp=ijk-i-nx*(j+ny*k); } /** Returns the position of a particle currently being computed * relative to the computational block that it is within. It is * used to select the optimal worklist entry to use. * \param[in] (x,y,z) the position of the particle. * \param[in] (ci,cj,ck) the block that the particle is within. * \param[out] (fx,fy,fz) the position relative to the block. */ inline void frac_pos(double x,double y,double z,double ci,double cj,double ck, double &fx,double &fy,double &fz) { fx=x-ax-boxx*ci; fy=y-ay-boxy*cj; fz=z-az-boxz*ck; } /** Calculates the index of block in the container structure * corresponding to given coordinates. * \param[in] (ci,cj,ck) the coordinates of the original block * in the current computation, relative * to the container coordinate system. * \param[in] (ei,ej,ek) the displacement of the current block * from the original block. * \param[in,out] (qx,qy,qz) the periodic displacement that * must be added to the particles * within the computed block. * \param[in] disp a block displacement used internally by the * find_voronoi_cell and compute_cell routines. * \return The block index. */ inline int region_index(int ci,int cj,int ck,int ei,int ej,int ek,double &qx,double &qy,double &qz,int &disp) { if(xperiodic) {if(ci+ei=(nx<<1)) {ei-=nx;qx=bx-ax;} else qx=0;} if(yperiodic) {if(cj+ej=(ny<<1)) {ej-=ny;qy=by-ay;} else qy=0;} if(zperiodic) {if(ck+ek=(nz<<1)) {ek-=nz;qz=bz-az;} else qz=0;} return disp+ei+nx*(ej+ny*ek); } void draw_domain_gnuplot(FILE *fp=stdout); /** Draws an outline of the domain in Gnuplot format. * \param[in] filename the filename to write to. */ inline void draw_domain_gnuplot(const char* filename) { FILE *fp=safe_fopen(filename,"w"); draw_domain_gnuplot(fp); fclose(fp); } void draw_domain_pov(FILE *fp=stdout); /** Draws an outline of the domain in Gnuplot format. * \param[in] filename the filename to write to. */ inline void draw_domain_pov(const char* filename) { FILE *fp=safe_fopen(filename,"w"); draw_domain_pov(fp); fclose(fp); } /** Sums up the total number of stored particles. * \return The number of particles. */ inline int total_particles() { int tp=*co; for(int *cop=co+1;cop. *****************************************************************************/ // Voro++, a 3D cell-based Voronoi library // // Author : Chris H. Rycroft (LBL / UC Berkeley) // Email : chr@alum.mit.edu // Date : August 30th 2011 /** \file container_prd.cc * \brief Function implementations for the container_periodic_base and * related classes. */ // This must always be the first include directive #include "config.h" #include "v_container_prd.h" #include "globalvar.h" const char *GetRevisionInfo_v_container_prd(unsigned int len) { static char buf[256]; GET_REVISION_INFO( buf, len ); return buf; } const char *GetSourceVersion_v_container_prd() { static char buf[256]; GET_SOURCE_VERSION( buf ); return buf; } /** The class constructor sets up the geometry of container, initializing the * minimum and maximum coordinates in each direction, and setting whether each * direction is periodic or not. It divides the container into a rectangular * grid of blocks, and allocates memory for each of these for storing particle * positions and IDs. * \param[in] (bx_) The x coordinate of the first unit vector. * \param[in] (bxy_,by_) The x and y coordinates of the second unit vector. * \param[in] (bxz_,byz_,bz_) The x, y, and z coordinates of the third unit * vector. * \param[in] (nx_,ny_,nz_) the number of grid blocks in each of the three * coordinate directions. * \param[in] init_mem_ the initial memory allocation for each block. * \param[in] ps_ the number of floating point entries to store for each * particle. */ container_periodic_base::container_periodic_base(double bx_,double bxy_,double by_, double bxz_,double byz_,double bz_,int nx_,int ny_,int nz_,int init_mem_,int ps_) : unitcell(bx_,bxy_,by_,bxz_,byz_,bz_), voro_base(nx_,ny_,nz_,bx_/nx_,by_/ny_,bz_/nz_), ey(int(max_uv_y*ysp+1)), ez(int(max_uv_z*zsp+1)), wy(ny+ey), wz(nz+ez), oy(ny+2*ey), oz(nz+2*ez), oxyz(nx*oy*oz), id(new int*[oxyz]), p(new double*[oxyz]), co(new int[oxyz]), mem(new int[oxyz]), img(new char[oxyz]), init_mem(init_mem_), ps(ps_) { int i,j,k,l; // Clear the global arrays int *pp=co;while(pp0) delete [] p[l]; for(l=0;l0) delete [] id[l]; delete [] p; delete [] id; delete [] mem; delete [] co; } /** The class constructor sets up the geometry of container. * \param[in] (bx_) The x coordinate of the first unit vector. * \param[in] (bxy_,by_) The x and y coordinates of the second unit vector. * \param[in] (bxz_,byz_,bz_) The x, y, and z coordinates of the third unit * vector. * \param[in] (nx_,ny_,nz_) the number of grid blocks in each of the three * coordinate directions. * \param[in] init_mem_ the initial memory allocation for each block. */ container_periodic_poly::container_periodic_poly(double bx_,double bxy_,double by_,double bxz_,double byz_,double bz_, int nx_,int ny_,int nz_,int init_mem_) : container_periodic_base(bx_,bxy_,by_,bxz_,byz_,bz_,nx_,ny_,nz_,init_mem_,4), vc(*this,2*nx_+1,2*ey+1,2*ez+1) {ppr=p;} /** Put a particle into the correct region of the container. * \param[in] n the numerical ID of the inserted particle. * \param[in] (x,y,z) the position vector of the inserted particle. * \param[in] r the radius of the particle. */ void container_periodic_poly::put(int n,double x,double y,double z,double r) { int ijk; put_locate_block(ijk,x,y,z); id[ijk][co[ijk]]=n; double *pp=p[ijk]+4*co[ijk]++; *(pp++)=x;*(pp++)=y;*(pp++)=z;*pp=r; if(max_radius=nz) { int ak=step_div(k,nz); z-=ak*bz;y-=ak*byz;x-=ak*bxz;k-=ak*nz; } // Remap particle in the y direction if necessary int j=step_int(y*ysp); if(j<0||j>=ny) { int aj=step_div(j,ny); y-=aj*by;x-=aj*bxy;j-=aj*ny; } // Remap particle in the x direction if necessary ijk=step_int(x*xsp); if(ijk<0||ijk>=nx) { int ai=step_div(ijk,nx); x-=ai*bx;ijk-=ai*nx; } // Compute the block index and check memory allocation j+=ey;k+=ez; ijk+=nx*(j+oy*k); if(co[ijk]==mem[ijk]) add_particle_memory(ijk); } /** Takes a particle position vector and computes the region index into which * it should be stored. If the container is periodic, then the routine also * maps the particle position to ensure it is in the primary domain. If the * container is not periodic, the routine bails out. * \param[out] ijk the region index. * \param[in,out] (x,y,z) the particle position, remapped into the primary * domain if necessary. * \param[out] (ai,aj,ak) the periodic image displacement that the particle is * in, with (0,0,0) corresponding to the primary domain. * \return True if the particle can be successfully placed into the container, * false otherwise. */ void container_periodic_base::put_locate_block(int &ijk,double &x,double &y,double &z,int &ai,int &aj,int &ak) { // Remap particle in the z direction if necessary int k=step_int(z*zsp); if(k<0||k>=nz) { ak=step_div(k,nz); z-=ak*bz;y-=ak*byz;x-=ak*bxz;k-=ak*nz; } else ak=0; // Remap particle in the y direction if necessary int j=step_int(y*ysp); if(j<0||j>=ny) { aj=step_div(j,ny); y-=aj*by;x-=aj*bxy;j-=aj*ny; } else aj=0; // Remap particle in the x direction if necessary ijk=step_int(x*xsp); if(ijk<0||ijk>=nx) { ai=step_div(ijk,nx); x-=ai*bx;ijk-=ai*nx; } else ai=0; // Compute the block index and check memory allocation j+=ey;k+=ez; ijk+=nx*(j+oy*k); if(co[ijk]==mem[ijk]) add_particle_memory(ijk); } /** Takes a position vector and remaps it into the primary domain. * \param[out] (ai,aj,ak) the periodic image displacement that the vector is in, * with (0,0,0) corresponding to the primary domain. * \param[out] (ci,cj,ck) the index of the block that the position vector is * within, once it has been remapped. * \param[in,out] (x,y,z) the position vector to consider, which is remapped * into the primary domain during the routine. * \param[out] ijk the block index that the vector is within. */ inline void container_periodic_base::remap(int &ai,int &aj,int &ak,int &ci,int &cj,int &ck,double &x,double &y,double &z,int &ijk) { // Remap particle in the z direction if necessary ck=step_int(z*zsp); if(ck<0||ck>=nz) { ak=step_div(ck,nz); z-=ak*bz;y-=ak*byz;x-=ak*bxz;ck-=ak*nz; } else ak=0; // Remap particle in the y direction if necessary cj=step_int(y*ysp); if(cj<0||cj>=ny) { aj=step_div(cj,ny); y-=aj*by;x-=aj*bxy;cj-=aj*ny; } else aj=0; // Remap particle in the x direction if necessary ci=step_int(x*xsp); if(ci<0||ci>=nx) { ai=step_div(ci,nx); x-=ai*bx;ci-=ai*nx; } else ai=0; cj+=ey;ck+=ez; ijk=ci+nx*(cj+oy*ck); } /** Takes a vector and finds the particle whose Voronoi cell contains that * vector. Additional wall classes are not considered by this routine. * \param[in] (x,y,z) the vector to test. * \param[out] (rx,ry,rz) the position of the particle whose Voronoi cell * contains the vector. If the container is periodic, * this may point to a particle in a periodic image of * the primary domain. * \param[out] pid the ID of the particle. * \return True if a particle was found. If the container has no particles, * then the search will not find a Voronoi cell and false is returned. */ bool container_periodic_poly::find_voronoi_cell(double x,double y,double z,double &rx,double &ry,double &rz,int &pid) { int ai,aj,ak,ci,cj,ck,ijk; particle_record w; double mrs; // Remap the vector into the primary domain and then search for the // Voronoi cell that it is within remap(ai,aj,ak,ci,cj,ck,x,y,z,ijk); vc.find_voronoi_cell(x,y,z,ci,cj,ck,ijk,w,mrs); if(w.ijk!=-1) { // Assemble the position vector of the particle to be returned, // applying a periodic remapping if necessary ci+=w.di;if(ci<0||ci>=nx) ai+=step_div(ci,nx); rx=p[w.ijk][4*w.l]+ak*bxz+aj*bxy+ai*bx; ry=p[w.ijk][4*w.l+1]+ak*byz+aj*by; rz=p[w.ijk][4*w.l+2]+ak*bz; pid=id[w.ijk][w.l]; return true; } return false; } /** Increase memory for a particular region. * \param[in] i the index of the region to reallocate. */ void container_periodic_base::add_particle_memory(int i) { // Handle the case when no memory has been allocated for this block if(mem[i]==0) { mem[i]=init_mem; id[i]=new int[init_mem]; p[i]=new double[ps*init_mem]; return; } // Otherwise, double the memory allocation for this block. Carry out a // check on the memory allocation size, and print a status message if // requested. int l,nmem(mem[i]<<1); if(nmem>max_particle_memory) voro_fatal_error("Absolute maximum memory allocation exceeded",VOROPP_MEMORY_ERROR); #if VOROPP_VERBOSE >=3 if ( !g_bVoroSilent ) mprintf("Particle memory in region %d scaled up to %d\n",i,nmem); if (nmem > g_iVoroMemory) g_iVoroMemory = nmem; #endif // Allocate new memory and copy in the contents of the old arrays int *idp=new int[nmem]; for(l=0;l0) { // Compute the block's bounds, adding in a small tolerance mix=i*boxx-tolerance;max=mix+boxx+tolerance; miy=(j-ey)*boxy-tolerance;may=miy+boxy+tolerance; miz=(k-ez)*boxz-tolerance;maz=miz+boxz+tolerance; // Print entries for any particles that lie outside the block's // bounds for(pp=p[l],c=0;cmax||pp[1]may||pp[2]maz) mprintf("%d %d %d %d %f %f %f %f %f %f %f %f %f\n", id[l][c],i,j,k,*pp,pp[1],pp[2],mix,max,miy,may,miz,maz); } } /** Creates particles within an image block that is aligned with the primary * domain in the z axis. In this case, the image block may be comprised of * particles from two primary blocks. The routine considers these two primary * blocks, and adds the needed particles to the image. The remaining particles * from the primary blocks are also filled into the neighboring images. * \param[in] (di,dj,dk) the index of the block to consider. The z index must * satisfy ez<=dk0) { odijk=dijk-1;adis=dis; } else { odijk=dijk+nx-1;adis=dis+bx; } img[odijk]|=2; for(l=0;lswitchx) put_image(dijk,fijk,l,dis,by*ima,0); else put_image(odijk,fijk,l,adis,by*ima,0); } } // Right image computation if((img[dijk]&2)==0) { if(fi==nx-1) { fijk+=1-nx;switchx+=(1-nx)*boxx;dis+=bx; } else { fijk++;switchx+=boxx; } if(di==nx-1) { odijk=dijk-nx+1;adis=dis-bx; } else { odijk=dijk+1;adis=dis; } img[odijk]|=1; for(l=0;l=wz. */ void container_periodic_base::create_vertical_image(int di,int dj,int dk) { int l,dijk=di+nx*(dj+oy*dk),dijkl,dijkr,ima=step_div(dk-ez,nz); int qj=dj+step_int(-ima*byz*ysp),qjdiv=step_div(qj-ey,ny); int qi=di+step_int((-ima*bxz-qjdiv*bxy)*xsp),qidiv=step_div(qi,nx); int fi=qi-qidiv*nx,fj=qj-qjdiv*ny,fijk=fi+nx*(fj+oy*(dk-ima*nz)),fijk2; double disy=ima*byz+qjdiv*by,switchy=(dj-ey)*boxy-ima*byz-qjdiv*by; double disx=ima*bxz+qjdiv*bxy+qidiv*bx,switchx=di*boxx-ima*bxz-qjdiv*bxy-qidiv*bx; double switchx2,disxl,disxr,disx2,disxr2; if(di==0) {dijkl=dijk+nx-1;disxl=disx+bx;} else {dijkl=dijk-1;disxl=disx;} if(di==nx-1) {dijkr=dijk-nx+1;disxr=disx-bx;} else {dijkr=dijk+1;disxr=disx;} // Down-left image computation bool y_exist=dj!=0; if((img[dijk]&1)==0) { img[dijkl]|=2; if(y_exist) { img[dijkl-nx]|=8; img[dijk-nx]|=4; } for(l=0;lswitchy) { if(p[fijk][ps*l]>switchx) put_image(dijk,fijk,l,disx,disy,bz*ima); else put_image(dijkl,fijk,l,disxl,disy,bz*ima); } else { if(!y_exist) continue; if(p[fijk][ps*l]>switchx) put_image(dijk-nx,fijk,l,disx,disy,bz*ima); else put_image(dijkl-nx,fijk,l,disxl,disy,bz*ima); } } } // Down-right image computation if((img[dijk]&2)==0) { if(fi==nx-1) { fijk2=fijk+1-nx;switchx2=switchx+(1-nx)*boxx;disx2=disx+bx;disxr2=disxr+bx; } else { fijk2=fijk+1;switchx2=switchx+boxx;disx2=disx;disxr2=disxr; } img[dijkr]|=1; if(y_exist) { img[dijkr-nx]|=4; img[dijk-nx]|=8; } for(l=0;lswitchy) { if(p[fijk2][ps*l]>switchx2) put_image(dijkr,fijk2,l,disxr2,disy,bz*ima); else put_image(dijk,fijk2,l,disx2,disy,bz*ima); } else { if(!y_exist) continue; if(p[fijk2][ps*l]>switchx2) put_image(dijkr-nx,fijk2,l,disxr2,disy,bz*ima); else put_image(dijk-nx,fijk2,l,disx2,disy,bz*ima); } } } // Recomputation of some intermediate quantities for boundary cases if(fj==wy-1) { fijk+=nx*(1-ny)-fi; switchy+=(1-ny)*boxy; disy+=by; qi=di+step_int(-(ima*bxz+(qjdiv+1)*bxy)*xsp); int dqidiv=step_div(qi,nx)-qidiv;qidiv+=dqidiv; fi=qi-qidiv*nx; fijk+=fi; disx+=bxy+bx*dqidiv; disxl+=bxy+bx*dqidiv; disxr+=bxy+bx*dqidiv; switchx-=bxy+bx*dqidiv; } else { fijk+=nx;switchy+=boxy; } // Up-left image computation y_exist=dj!=oy-1; if((img[dijk]&4)==0) { img[dijkl]|=8; if(y_exist) { img[dijkl+nx]|=2; img[dijk+nx]|=1; } for(l=0;lswitchy) { if(!y_exist) continue; if(p[fijk][ps*l]>switchx) put_image(dijk+nx,fijk,l,disx,disy,bz*ima); else put_image(dijkl+nx,fijk,l,disxl,disy,bz*ima); } else { if(p[fijk][ps*l]>switchx) put_image(dijk,fijk,l,disx,disy,bz*ima); else put_image(dijkl,fijk,l,disxl,disy,bz*ima); } } } // Up-right image computation if((img[dijk]&8)==0) { if(fi==nx-1) { fijk2=fijk+1-nx;switchx2=switchx+(1-nx)*boxx;disx2=disx+bx;disxr2=disxr+bx; } else { fijk2=fijk+1;switchx2=switchx+boxx;disx2=disx;disxr2=disxr; } img[dijkr]|=4; if(y_exist) { img[dijkr+nx]|=1; img[dijk+nx]|=2; } for(l=0;lswitchy) { if(!y_exist) continue; if(p[fijk2][ps*l]>switchx2) put_image(dijkr+nx,fijk2,l,disxr2,disy,bz*ima); else put_image(dijk+nx,fijk2,l,disx2,disy,bz*ima); } else { if(p[fijk2][ps*l]>switchx2) put_image(dijkr,fijk2,l,disxr2,disy,bz*ima); else put_image(dijk,fijk2,l,disx2,disy,bz*ima); } } } // All contributions to the block now added, so set all four bits of // the image information img[dijk]=15; } /** Copies a particle position from the primary domain into an image block. * \param[in] reg the block index within the primary domain that the particle * is within. * \param[in] fijk the index of the image block. * \param[in] l the index of the particle entry within the primary block. * \param[in] (dx,dy,dz) the displacement vector to add to the particle. */ void container_periodic_base::put_image(int reg,int fijk,int l,double dx,double dy,double dz) { if(co[reg]==mem[reg]) add_particle_memory(reg); double *p1=p[reg]+ps*co[reg],*p2=p[fijk]+ps*l; *(p1++)=*(p2++)+dx; *(p1++)=*(p2++)+dy; *p1=*p2+dz; if(ps==4) *(++p1)=*(++p2); id[reg][co[reg]++]=id[fijk][l]; } travis-src-190101/src/v_container_prd.h0100777000000000000000000004230013412725666014771 0ustar00/***************************************************************************** TRAVIS - Trajectory Analyzer and Visualizer http://www.travis-analyzer.de/ Copyright (c) 2009-2019 Martin Brehm 2012-2019 Martin Thomas 2016-2019 Sascha Gehrke --------------------------------------------------------------------------- This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . *****************************************************************************/ // Voro++, a 3D cell-based Voronoi library // // Author : Chris H. Rycroft (LBL / UC Berkeley) // Email : chr@alum.mit.edu // Date : August 30th 2011 /** \file container_prd.hh * \brief Header file for the container_periodic_base and related classes. */ #ifndef VOROPP_CONTAINER_PRD_HH #define VOROPP_CONTAINER_PRD_HH // This must always be the first include directive #include "config.h" #include #include #include #include #include "v_config.h" #include "v_common.h" #include "v_base.h" #include "v_cell.h" #include "v_c_loops.h" #include "v_compute.h" #include "v_unitcell.h" #include "v_rad_option.h" #include "tools.h" /** \brief Class for representing a particle system in a 3D periodic * non-orthogonal periodic domain. * * This class represents a particle system in a three-dimensional * non-orthogonal periodic domain. The domain is defined by three periodicity * vectors (bx,0,0), (bxy,by,0), and (bxz,byz,bz) that represent a * parallelepiped. Internally, the class stores particles in the box 0=nx||dj<0||dj>=oy||dk<0||dk>=oz) voro_fatal_error("Constructing periodic image for nonexistent point",VOROPP_INTERNAL_ERROR); if(dk>=ez&&dk=wy) create_side_image(di,dj,dk); } else create_vertical_image(di,dj,dk); } void create_side_image(int di,int dj,int dk); void create_vertical_image(int di,int dj,int dk); void put_image(int reg,int fijk,int l,double dx,double dy,double dz); inline void remap(int &ai,int &aj,int &ak,int &ci,int &cj,int &ck,double &x,double &y,double &z,int &ijk); }; /** \brief Extension of the container_periodic_base class for computing radical * Voronoi tessellations. * * This class is an extension of container_periodic_base that has routines * specifically for computing the radical Voronoi tessellation that depends * on the particle radii. */ class container_periodic_poly : public container_periodic_base, public radius_poly { public: container_periodic_poly(double bx_,double bxy_,double by_,double bxz_,double byz_,double bz_, int nx_,int ny_,int nz_,int init_mem_); void clear(); void put(int n,double x,double y,double z,double r); void put(int n,double x,double y,double z,double r,int &ai,int &aj,int &ak); void import(FILE *fp=stdin); /** Imports a list of particles from an open file stream into * the container_poly class. Entries of five numbers (Particle * ID, x position, y position, z position, radius) are searched * for. If the file cannot be successfully read, then the * routine causes a fatal error. * \param[in] filename the name of the file to open and read * from. */ inline void import(const char* filename) { FILE *fp=safe_fopen(filename,"r"); import(fp); fclose(fp); } void compute_all_cells(); double sum_cell_volumes(); /** Dumps particle IDs, positions and radii to a file. * \param[in] vl the loop class to use. * \param[in] fp a file handle to write to. */ template void draw_particles(c_loop &vl,FILE *fp) { double *pp; if(vl.start()) do { pp=p[vl.ijk]+4*vl.q; fprintf(fp,"%d %g %g %g %g\n",id[vl.ijk][vl.q],*pp,pp[1],pp[2],pp[3]); } while(vl.inc()); } /** Dumps all of the particle IDs, positions and radii to a * file. * \param[in] fp a file handle to write to. */ inline void draw_particles(FILE *fp=stdout) { c_loop_all_periodic vl(*this); draw_particles(vl,fp); } /** Dumps all of the particle IDs, positions and radii to a * file. * \param[in] filename the name of the file to write to. */ inline void draw_particles(const char *filename) { FILE *fp=safe_fopen(filename,"w"); draw_particles(fp); fclose(fp); } /** Dumps particle positions in POV-Ray format. * \param[in] vl the loop class to use. * \param[in] fp a file handle to write to. */ template void draw_particles_pov(c_loop &vl,FILE *fp) { double *pp; if(vl.start()) do { pp=p[vl.ijk]+4*vl.q; fprintf(fp,"// id %d\nsphere{<%g,%g,%g>,%g}\n", id[vl.ijk][vl.q],*pp,pp[1],pp[2],pp[3]); } while(vl.inc()); } /** Dumps all the particle positions in POV-Ray format. * \param[in] fp a file handle to write to. */ inline void draw_particles_pov(FILE *fp=stdout) { c_loop_all_periodic vl(*this); draw_particles_pov(vl,fp); } /** Dumps all the particle positions in POV-Ray format. * \param[in] filename the name of the file to write to. */ inline void draw_particles_pov(const char *filename) { FILE *fp = (safe_fopen(filename,"w")); draw_particles_pov(fp); fclose(fp); } /** Computes Voronoi cells and saves the output in gnuplot * format. * \param[in] vl the loop class to use. * \param[in] fp a file handle to write to. */ template void draw_cells_gnuplot(c_loop &vl,FILE *fp) { voronoicell_neighbor c;double *pp; if(vl.start()) do if(compute_cell(c,vl)) { pp=p[vl.ijk]+ps*vl.q; c.draw_gnuplot(*pp,pp[1],pp[2],fp); } while(vl.inc()); } /** Compute all Voronoi cells and saves the output in gnuplot * format. * \param[in] fp a file handle to write to. */ inline void draw_cells_gnuplot(FILE *fp=stdout) { c_loop_all_periodic vl(*this); draw_cells_gnuplot(vl,fp); } /** Compute all Voronoi cells and saves the output in gnuplot * format. * \param[in] filename the name of the file to write to. */ inline void draw_cells_gnuplot(const char *filename) { FILE *fp = (safe_fopen(filename,"w")); draw_cells_gnuplot(fp); fclose(fp); } /** Computes Voronoi cells and saves the output in POV-Ray * format. * \param[in] vl the loop class to use. * \param[in] fp a file handle to write to. */ template void draw_cells_pov(c_loop &vl,FILE *fp) { voronoicell_neighbor c;double *pp; if(vl.start()) do if(compute_cell(c,vl)) { fprintf(fp,"// cell %d\n",id[vl.ijk][vl.q]); pp=p[vl.ijk]+ps*vl.q; c.draw_pov(*pp,pp[1],pp[2],fp); } while(vl.inc()); } /** Computes all Voronoi cells and saves the output in POV-Ray * format. * \param[in] fp a file handle to write to. */ inline void draw_cells_pov(FILE *fp=stdout) { c_loop_all_periodic vl(*this); draw_cells_pov(vl,fp); } /** Computes all Voronoi cells and saves the output in POV-Ray * format. * \param[in] filename the name of the file to write to. */ inline void draw_cells_pov(const char *filename) { FILE *fp = (safe_fopen(filename,"w")); draw_cells_pov(fp); fclose(fp); } /** Computes the Voronoi cells and saves customized information * about them. * \param[in] vl the loop class to use. * \param[in] format the custom output string to use. * \param[in] fp a file handle to write to. */ template void print_custom(c_loop &vl,const char *format,FILE *fp) { int ijk,q;double *pp; // if(contains_neighbor(format)) { voronoicell_neighbor c; if(vl.start()) do if(compute_cell(c,vl)) { ijk=vl.ijk;q=vl.q;pp=p[ijk]+ps*q; c.output_custom(format,id[ijk][q],*pp,pp[1],pp[2],pp[3],fp); } while(vl.inc()); /* } else { voronoicell c; if(vl.start()) do if(compute_cell(c,vl)) { ijk=vl.ijk;q=vl.q;pp=p[ijk]+ps*q; c.output_custom(format,id[ijk][q],*pp,pp[1],pp[2],pp[3],fp); } while(vl.inc()); }*/ } /** Computes the Voronoi cell for a particle currently being * referenced by a loop class. * \param[out] c a Voronoi cell class in which to store the * computed cell. * \param[in] vl the loop class to use. * \return True if the cell was computed. If the cell cannot be * computed because it was removed entirely for some reason, * then the routine returns false. */ template inline bool compute_cell(voronoicell_neighbor &c,c_loop &vl) { return vc.compute_cell(c,vl.ijk,vl.q,vl.i,vl.j,vl.k); } /** Computes the Voronoi cell for given particle. * \param[out] c a Voronoi cell class in which to store the * computed cell. * \param[in] ijk the block that the particle is within. * \param[in] q the index of the particle within the block. * \return True if the cell was computed. If the cell cannot be * computed because it was removed entirely for some reason, * then the routine returns false. */ inline bool compute_cell(voronoicell_neighbor &c,int ijk,int q) { int k(ijk/(nx*oy)),ijkt(ijk-(nx*oy)*k),j(ijkt/nx),i(ijkt-j*nx); return vc.compute_cell(c,ijk,q,i,j,k); } void print_custom(const char *format,FILE *fp=stdout); void print_custom(const char *format,const char *filename); bool find_voronoi_cell(double x,double y,double z,double &rx,double &ry,double &rz,int &pid); private: voro_compute vc; friend class voro_compute; }; #endif travis-src-190101/src/v_c_loops.h0100777000000000000000000001631713412725652013604 0ustar00/***************************************************************************** TRAVIS - Trajectory Analyzer and Visualizer http://www.travis-analyzer.de/ Copyright (c) 2009-2019 Martin Brehm 2012-2019 Martin Thomas 2016-2019 Sascha Gehrke --------------------------------------------------------------------------- This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . *****************************************************************************/ // Voro++, a 3D cell-based Voronoi library // // Author : Chris H. Rycroft (LBL / UC Berkeley) // Email : chr@alum.mit.edu // Date : August 30th 2011 /** \file c_loops.hh * \brief Header file for the loop classes. */ #ifndef VOROPP_C_LOOPS_HH #define VOROPP_C_LOOPS_HH // This must always be the first include directive #include "config.h" #include #include #include #include #include "v_config.h" /** \brief Base class for looping over particles in a container. * * This class forms the base of all classes that can loop over a subset of * particles in a contaner in some order. When initialized, it stores constants * about the corresponding container geometry. It also contains a number of * routines for interrogating which particle currently being considered by the * loop, which are common between all of the derived classes. */ class c_loop_base { public: /** The number of blocks in the x direction. */ const int nx; /** The number of blocks in the y direction. */ const int ny; /** The number of blocks in the z direction. */ const int nz; /** A constant, set to the value of nx multiplied by ny, which * is used in the routines that step through blocks in * sequence. */ const int nxy; /** A constant, set to the value of nx*ny*nz, which is used in * the routines that step through blocks in sequence. */ const int nxyz; /** The number of floating point numbers per particle in the * associated container data structure. */ const int ps; /** A pointer to the particle position information in the * associated container data structure. */ double **p; /** A pointer to the particle ID information in the associated * container data structure. */ int **id; /** A pointer to the particle counts in the associated * container data structure. */ int *co; /** The current x-index of the block under consideration by the * loop. */ int i; /** The current y-index of the block under consideration by the * loop. */ int j; /** The current z-index of the block under consideration by the * loop. */ int k; /** The current index of the block under consideration by the * loop. */ int ijk; /** The index of the particle under consideration within the current * block. */ int q; /** The constructor copies several necessary constants from the * base container class. * \param[in] con the container class to use. */ template c_loop_base(c_class &con) : nx(con.nx), ny(con.ny), nz(con.nz), nxy(con.nxy), nxyz(con.nxyz), ps(con.ps), p(con.p), id(con.id), co(con.co) {} /** Returns the position vector of the particle currently being * considered by the loop. * \param[out] (x,y,z) the position vector of the particle. */ inline void pos(double &x,double &y,double &z) { double *pp=p[ijk]+ps*q; x=*(pp++);y=*(pp++);z=*pp; } /** Returns the ID, position vector, and radius of the particle * currently being considered by the loop. * \param[out] pid the particle ID. * \param[out] (x,y,z) the position vector of the particle. * \param[out] r the radius of the particle. If no radius * information is available the default radius * value is returned. */ inline void pos(int &pid,double &x,double &y,double &z,double &r) { pid=id[ijk][q]; double *pp=p[ijk]+ps*q; x=*(pp++);y=*(pp++);z=*pp; r=ps==3?default_radius:*(++pp); } /** Returns the x position of the particle currently being * considered by the loop. */ inline double x() {return p[ijk][ps*q];} /** Returns the y position of the particle currently being * considered by the loop. */ inline double y() {return p[ijk][ps*q+1];} /** Returns the z position of the particle currently being * considered by the loop. */ inline double z() {return p[ijk][ps*q+2];} /** Returns the ID of the particle currently being considered * by the loop. */ inline int pid() {return id[ijk][q];} }; /** \brief A class for looping over all particles in a container_periodic or * container_periodic_poly class. * * Since the container_periodic and container_periodic_poly classes have a * fundamentally different memory organization, the regular loop classes cannot * be used with them. */ class c_loop_all_periodic : public c_loop_base { public: /** The constructor copies several necessary constants from the * base periodic container class. * \param[in] con the periodic container class to use. */ template c_loop_all_periodic(c_class &con) : c_loop_base(con), ey(con.ey), ez(con.ez), wy(con.wy), wz(con.wz), ijk0(nx*(ey+con.oy*ez)), inc2(2*nx*con.ey+1) {} /** Sets the class to consider the first particle. * \return True if there is any particle to consider, false * otherwise. */ inline bool start() { i=0; j=ey; k=ez; ijk=ijk0; q=0; while(co[ijk]==0) if(!next_block()) return false; return true; } /** Finds the next particle to test. * \return True if there is another particle, false if no more * particles are available. */ inline bool inc() { q++; if(q>=co[ijk]) { q=0; do { if(!next_block()) return false; } while(co[ijk]==0); } return true; } private: /** The lower y index (inclusive) of the primary domain within * the block structure. */ int ey; /** The lower y index (inclusive) of the primary domain within * the block structure. */ int ez; /** The upper y index (exclusive) of the primary domain within * the block structure. */ int wy; /** The upper z index (exclusive) of the primary domain within * the block structure. */ int wz; /** The index of the (0,0,0) block within the block structure. */ int ijk0; /** A value to increase ijk by when the z index is increased. */ int inc2; /** Updates the internal variables to find the next * computational block with any particles. * \return True if another block is found, false if there are * no more blocks. */ inline bool next_block() { i++; if(i==nx) { i=0;j++; if(j==wy) { j=ey;k++; if(k==wz) return false; ijk+=inc2; } else ijk++; } else ijk++; return true; } }; #endif travis-src-190101/src/v_pre_container.cpp0100777000000000000000000001464013412725625015326 0ustar00/***************************************************************************** TRAVIS - Trajectory Analyzer and Visualizer http://www.travis-analyzer.de/ Copyright (c) 2009-2019 Martin Brehm 2012-2019 Martin Thomas 2016-2019 Sascha Gehrke --------------------------------------------------------------------------- This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . *****************************************************************************/ // Voro++, a 3D cell-based Voronoi library // // Author : Chris H. Rycroft (LBL / UC Berkeley) // Email : chr@alum.mit.edu // Date : August 30th 2011 /** \file pre_container.cc * \brief Function implementations for the pre_container and related classes. */ // This must always be the first include directive #include "config.h" #include #include #include "v_config.h" #include "v_pre_container.h" #include "v_container_prd.h" const char *GetRevisionInfo_v_pre_container(unsigned int len) { static char buf[256]; GET_REVISION_INFO( buf, len ); return buf; } const char *GetSourceVersion_v_pre_container() { static char buf[256]; GET_SOURCE_VERSION( buf ); return buf; } class container_periodic_poly; /** The class constructor sets up the geometry of container, initializing the * minimum and maximum coordinates in each direction. It allocates an initial * chunk into which to store particle information. * \param[in] (ax_,bx_) the minimum and maximum x coordinates. * \param[in] (ay_,by_) the minimum and maximum y coordinates. * \param[in] (az_,bz_) the minimum and maximum z coordinates. * \param[in] (xperiodic_,yperiodic_,zperiodic_ ) flags setting whether the * container is periodic in each * coordinate direction. * \param[in] ps_ the number of floating point entries to store for each * particle. */ pre_container_base::pre_container_base(double ax_,double bx_,double ay_,double by_,double az_,double bz_, bool xperiodic_,bool yperiodic_,bool zperiodic_,int ps_) : ax(ax_), bx(bx_), ay(ay_), by(by_), az(az_), bz(bz_), xperiodic(xperiodic_), yperiodic(yperiodic_), zperiodic(zperiodic_), ps(ps_), index_sz(init_chunk_size), pre_id(new int*[index_sz]), end_id(pre_id), pre_p(new double*[index_sz]), end_p(pre_p) { ch_id=*end_id=new int[pre_container_chunk_size]; l_id=end_id+index_sz;e_id=ch_id+pre_container_chunk_size; ch_p=*end_p=new double[ps*pre_container_chunk_size]; } /** The destructor frees the dynamically allocated memory. */ pre_container_base::~pre_container_base() { delete [] *end_p; delete [] *end_id; while (end_id!=pre_id) { end_p--; delete [] *end_p; end_id--; delete [] *end_id; } delete [] pre_p; delete [] pre_id; } /** Makes a guess at the optimal grid of blocks to use, computing in * a way that * \param[out] (nx,ny,nz) the number of blocks to use. */ void pre_container_base::guess_optimal(int &nx,int &ny,int &nz) { double dx = (bx-ax),dy = (by-ay),dz = (bz-az); double ilscale = (mypow(total_particles()/(optimal_particles*dx*dy*dz),1/3.0)); nx=int(dx*ilscale+1); ny=int(dy*ilscale+1); nz=int(dz*ilscale+1); } /** Stores a particle ID and position, allocating a new memory chunk if necessary. * \param[in] n the numerical ID of the inserted particle. * \param[in] (x,y,z) the position vector of the inserted particle. * \param[in] r the radius of the particle. */ void pre_container_poly::put(int n,double x,double y,double z,double r) { if((xperiodic||(x>=ax&&x<=bx))&&(yperiodic||(y>=ay&&y<=by))&&(zperiodic||(z>=az&&z<=bz))) { if(ch_id==e_id) new_chunk(); *(ch_id++)=n; *(ch_p++)=x;*(ch_p++)=y;*(ch_p++)=z;*(ch_p++)=r; } #if VOROPP_REPORT_OUT_OF_BOUNDS ==1 else fprintf(stderr,"Out of bounds: (x,y,z)=(%g,%g,%g)\n",x,y,z); #endif } /** Transfers the particles stored within the class to a container_poly class. * \param[in] con the container_poly class to transfer to. */ void pre_container_poly::setup(container_periodic_poly &con) { int **c_id=pre_id,*idp,*ide,n; double **c_p=pre_p,*pp,x,y,z,r; while(c_idmax_chunk_size) voro_fatal_error("Absolute memory limit on chunk index reached",VOROPP_MEMORY_ERROR); #if VOROPP_VERBOSE >=2 fprintf(stderr,"Pre-container chunk index scaled up to %d\n",index_sz); #endif int **n_id=new int*[index_sz],**p_id=n_id,**c_id=pre_id; double **n_p=new double*[index_sz],**p_p=n_p,**c_p=pre_p; while(c_id. *****************************************************************************/ // Voro++, a 3D cell-based Voronoi library // // Author : Chris H. Rycroft (LBL / UC Berkeley) // Email : chr@alum.mit.edu // Date : August 30th 2011 /** \file pre_container.hh * \brief Header file for the pre_container and related classes. */ #ifndef VOROPP_PRE_CONTAINER_HH #define VOROPP_PRE_CONTAINER_HH // This must always be the first include directive #include "config.h" #include "v_c_loops.h" #include "v_container.h" /** \brief A class for storing an arbitrary number of particles, prior to setting * up a container geometry. * * The pre_container_base class can dynamically import and store an arbitrary * number of particles. Once the particles have been read in, an appropriate * container class can be set up with the optimal grid size, and the particles * can be transferred. * * The pre_container_base class is not intended for direct use, but forms the * base of the pre_container and pre_container_poly classes, that add routines * depending on whether particle radii need to be tracked or not. */ class pre_container_base { public: /** The minimum x coordinate of the container. */ const double ax; /** The maximum x coordinate of the container. */ const double bx; /** The minimum y coordinate of the container. */ const double ay; /** The maximum y coordinate of the container. */ const double by; /** The minimum z coordinate of the container. */ const double az; /** The maximum z coordinate of the container. */ const double bz; /** A boolean value that determines if the x coordinate in * periodic or not. */ const bool xperiodic; /** A boolean value that determines if the y coordinate in * periodic or not. */ const bool yperiodic; /** A boolean value that determines if the z coordinate in * periodic or not. */ const bool zperiodic; void guess_optimal(int &nx,int &ny,int &nz); pre_container_base(double ax_,double bx_,double ay_,double by_,double az_,double bz_,bool xperiodic_,bool yperiodic_,bool zperiodic_,int ps_); ~pre_container_base(); /** Calculates and returns the total number of particles stored * within the class. * \return The number of particles. */ inline int total_particles() { return (int)((end_id-pre_id)*pre_container_chunk_size+(ch_id-*end_id)); } protected: /** The number of doubles associated with a single particle * (three for the standard container, four when radius * information is stored). */ const int ps; void new_chunk(); void extend_chunk_index(); /** The size of the chunk index. */ int index_sz; /** A pointer to the chunk index to store the integer particle * IDs. */ int **pre_id; /** A pointer to the last allocated integer ID chunk. */ int **end_id; /** A pointer to the end of the integer ID chunk index, used to * determine when the chunk index is full. */ int **l_id; /** A pointer to the next available slot on the current * particle ID chunk. */ int *ch_id; /** A pointer to the end of the current integer chunk. */ int *e_id; /** A pointer to the chunk index to store the floating point * information associated with particles. */ double **pre_p; /** A pointer to the last allocated chunk of floating point * information. */ double **end_p; /** A pointer to the next available slot on the current * floating point chunk. */ double *ch_p; }; /** \brief A class for storing an arbitrary number of particles with radius * information, prior to setting up a container geometry. * * The pre_container_poly class is an extension of the pre_container_base class * for cases when particle radius information is available. */ class pre_container_poly : public pre_container_base { public: /** The class constructor sets up the geometry of container, * initializing the minimum and maximum coordinates in each * direction. * \param[in] (ax_,bx_) the minimum and maximum x coordinates. * \param[in] (ay_,by_) the minimum and maximum y coordinates. * \param[in] (az_,bz_) the minimum and maximum z coordinates. * \param[in] (xperiodic_,yperiodic_,zperiodic_ ) flags setting whether the * container is periodic in * each coordinate direction. */ pre_container_poly(double ax_,double bx_,double ay_,double by_,double az_,double bz_, bool xperiodic_,bool yperiodic_,bool zperiodic_) : pre_container_base(ax_,bx_,ay_,by_,az_,bz_,xperiodic_,yperiodic_,zperiodic_,4) {}; void put(int n,double x,double y,double z,double r); void import(FILE *fp=stdin); /** Imports particles from a file. * \param[in] filename the name of the file to read from. */ inline void import(const char* filename) { FILE *fp=safe_fopen(filename,"r"); import(fp); fclose(fp); } void setup(container_periodic_poly &con); // void setup(particle_order &vo,container_periodic_poly &con); }; #endif travis-src-190101/src/v_rad_option.h0100777000000000000000000002020213412725652014270 0ustar00/***************************************************************************** TRAVIS - Trajectory Analyzer and Visualizer http://www.travis-analyzer.de/ Copyright (c) 2009-2019 Martin Brehm 2012-2019 Martin Thomas 2016-2019 Sascha Gehrke --------------------------------------------------------------------------- This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . *****************************************************************************/ // Voro++, a 3D cell-based Voronoi library // // Author : Chris H. Rycroft (LBL / UC Berkeley) // Email : chr@alum.mit.edu // Date : August 30th 2011 /** \file rad_option.hh * \brief Header file for the classes encapsulating functionality for the * regular and radical Voronoi tessellations. */ #ifndef VOROPP_RAD_OPTION_HH #define VOROPP_RAD_OPTION_HH // This must always be the first include directive #include "config.h" /** \brief Class containing all of the routines that are specific to computing * the regular Voronoi tessellation. * * The container and container_periodic classes are derived from this class, * and during the Voronoi cell computation, these routines are used to create * the regular Voronoi tessellation. */ class radius_mono { protected: /** This is called prior to computing a Voronoi cell for a * given particle to initialize any required constants. * \param[in] ijk the block that the particle is within. * \param[in] s the index of the particle within the block. */ inline void r_init(int ijk,int s) { UNUSED(ijk); UNUSED(s); /* Suppress "unused parameter" warning */ } /** Sets a required constant to be used when carrying out a * plane bounds check. */ inline void r_prime(double rv) { UNUSED(rv); /* Suppress "unused parameter" warning */ } /** Carries out a radius bounds check. * \param[in] crs the radius squared to be tested. * \param[in] mrs the current maximum distance to a Voronoi * vertex multiplied by two. * \return True if particles at this radius could not possibly * cut the cell, false otherwise. */ inline bool r_ctest(double crs,double mrs) {return crs>mrs;} /** Scales a plane displacement during a plane bounds check. * \param[in] lrs the plane displacement. * \return The scaled value. */ inline double r_cutoff(double lrs) {return lrs;} /** Adds the maximum radius squared to a given value. * \param[in] rs the value to consider. * \return The value with the radius squared added. */ inline double r_max_add(double rs) {return rs;} /** Subtracts the radius squared of a particle from a given * value. * \param[in] rs the value to consider. * \param[in] ijk the block that the particle is within. * \param[in] q the index of the particle within the block. * \return The value with the radius squared subtracted. */ inline double r_current_sub(double rs,int ijk,int q) { UNUSED(ijk); UNUSED(q); /* Suppress "unused parameter" warning */ return rs;} /** Scales a plane displacement prior to use in the plane cutting * algorithm. * \param[in] rs the initial plane displacement. * \param[in] ijk the block that the particle is within. * \param[in] q the index of the particle within the block. * \return The scaled plane displacement. */ inline double r_scale(double rs,int ijk,int q) { UNUSED(ijk); UNUSED(q); /* Suppress "unused parameter" warning */ return rs;} /** Scales a plane displacement prior to use in the plane * cutting algorithm, and also checks if it could possibly cut * the cell. * \param[in,out] rs the plane displacement to be scaled. * \param[in] mrs the current maximum distance to a Voronoi * vertex multiplied by two. * \param[in] ijk the block that the particle is within. * \param[in] q the index of the particle within the block. * \return True if the cell could possibly cut the cell, false * otherwise. */ inline bool r_scale_check(double &rs,double mrs,int ijk,int q) { UNUSED(ijk); UNUSED(q); /* Suppress "unused parameter" warning */ return rssqrt(mrs*crs);} /** Scales a plane displacement during a plane bounds check. * \param[in] lrs the plane displacement. * \return The scaled value. */ inline double r_cutoff(double lrs) {return lrs*r_val;} /** Adds the maximum radius squared to a given value. * \param[in] rs the value to consider. * \return The value with the radius squared added. */ inline double r_max_add(double rs) {return rs+max_radius*max_radius;} /** Subtracts the radius squared of a particle from a given * value. * \param[in] rs the value to consider. * \param[in] ijk the block that the particle is within. * \param[in] q the index of the particle within the block. * \return The value with the radius squared subtracted. */ inline double r_current_sub(double rs,int ijk,int q) { return rs-ppr[ijk][4*q+3]*ppr[ijk][4*q+3]; } /** Scales a plane displacement prior to use in the plane cutting * algorithm. * \param[in] rs the initial plane displacement. * \param[in] ijk the block that the particle is within. * \param[in] q the index of the particle within the block. * \return The scaled plane displacement. */ inline double r_scale(double rs,int ijk,int q) { return rs+r_rad-ppr[ijk][4*q+3]*ppr[ijk][4*q+3]; } /** Scales a plane displacement prior to use in the plane * cutting algorithm, and also checks if it could possibly cut * the cell. * \param[in,out] rs the plane displacement to be scaled. * \param[in] mrs the current maximum distance to a Voronoi * vertex multiplied by two. * \param[in] ijk the block that the particle is within. * \param[in] q the index of the particle within the block. * \return True if the cell could possibly cut the cell, false * otherwise. */ inline bool r_scale_check(double &rs,double mrs,int ijk,int q) { double trs=rs; rs+=r_rad-ppr[ijk][4*q+3]*ppr[ijk][4*q+3]; return rs. *****************************************************************************/ // Voro++, a 3D cell-based Voronoi library // // Author : Chris H. Rycroft (LBL / UC Berkeley) // Email : chr@alum.mit.edu // Date : August 30th 2011 /** \file unitcell.cc * \brief Function implementations for the unitcell class. */ // This must always be the first include directive #include "config.h" #include #include "v_unitcell.h" #include "v_cell.h" const char *GetRevisionInfo_v_unitcell(unsigned int len) { static char buf[256]; GET_REVISION_INFO( buf, len ); return buf; } const char *GetSourceVersion_v_unitcell() { static char buf[256]; GET_SOURCE_VERSION( buf ); return buf; } /** Initializes the unit cell class for a particular non-orthogonal periodic * geometry, corresponding to a parallelepiped with sides given by three * vectors. The class constructs the unit Voronoi cell corresponding to this * geometry. * \param[in] (bx_) The x coordinate of the first unit vector. * \param[in] (bxy_,by_) The x and y coordinates of the second unit vector. * \param[in] (bxz_,byz_,bz_) The x, y, and z coordinates of the third unit * vector. */ unitcell::unitcell(double bx_,double bxy_,double by_,double bxz_,double byz_,double bz_) : bx(bx_), bxy(bxy_), by(by_), bxz(bxz_), byz(byz_), bz(bz_) { int i,j,l=1; // Initialize the Voronoi cell to be a very large rectangular box const double ucx=max_unit_voro_shells*bx,ucy=max_unit_voro_shells*by,ucz=max_unit_voro_shells*bz; unit_voro.init(-ucx,ucx,-ucy,ucy,-ucz,ucz); // Repeatedly cut the cell by shells of periodic image particles while(l<2*max_unit_voro_shells) { // Check to see if any of the planes from the current shell // will cut the cell if(unit_voro_intersect(l)) { // If they do, apply the plane cuts from the current // shell unit_voro_apply(l,0,0); for(i=1;il can't cut // a cell lying within the paraboloid // z<=(l*l-x*x-y*y)/(2*l). It is always a tighter bound // than the one based on computing the maximum radius // of a Voronoi cell vertex. max_uv_y=max_uv_z=0; double y,z,q,*pts=unit_voro.pts,*pp=pts; while(ppmax_uv_y) max_uv_y=y+q; if(z+q>max_uv_z) max_uv_z=z+q; } max_uv_z*=0.5; max_uv_y*=0.5; return; } l++; } // If the routine makes it here, then the unit cell still hasn't been // completely bounded by the plane cuts. Give the memory error code, // because this is mainly a case of hitting a safe limit, than any // inherent problem. voro_fatal_error("Periodic cell computation failed",VOROPP_MEMORY_ERROR); } /** Applies a pair of opposing plane cuts from a periodic image point * to the unit Voronoi cell. * \param[in] (i,j,k) the index of the periodic image to consider. */ inline void unitcell::unit_voro_apply(int i,int j,int k) { double x=i*bx+j*bxy+k*bxz,y=j*by+k*byz,z=k*bz; unit_voro.plane(x,y,z); unit_voro.plane(-x,-y,-z); } /** Calculates whether the unit Voronoi cell intersects a given periodic image * of the domain. * \param[in] (dx,dy,dz) the displacement of the periodic image. * \param[out] vol the proportion of the unit cell volume within this image, * only computed in the case that the two intersect. * \return True if they intersect, false otherwise. */ bool unitcell::intersects_image(double dx,double dy,double dz,double &vol) { const double bxinv=1/bx,byinv=1/by,bzinv=1/bz,ivol=bxinv*byinv*bzinv; voronoicell_neighbor c; c=unit_voro; dx*=2;dy*=2;dz*=2; if(!c.plane(0,0,bzinv,dz+1)) return false; if(!c.plane(0,0,-bzinv,-dz+1)) return false; if(!c.plane(0,byinv,-byz*byinv*bzinv,dy+1)) return false; if(!c.plane(0,-byinv,byz*byinv*bzinv,-dy+1)) return false; if(!c.plane(bxinv,-bxy*bxinv*byinv,(bxy*byz-by*bxz)*ivol,dx+1)) return false; if(!c.plane(-bxinv,bxy*bxinv*byinv,(-bxy*byz+by*bxz)*ivol,-dx+1)) return false; vol=c.volume()*ivol; return true; } /** Computes a list of periodic domain images that intersect the unit Voronoi cell. * \param[out] vi a vector containing triplets (i,j,k) corresponding to domain * images that intersect the unit Voronoi cell, when it is * centered in the middle of the primary domain. * \param[out] vd a vector containing the fraction of the Voronoi cell volume * within each corresponding image listed in vi. */ void unitcell::images(vector &vi,vector &vd) { const int ms2=max_unit_voro_shells*2+1,mss=ms2*ms2*ms2; bool *a=new bool[mss],*ac=a+max_unit_voro_shells*(1+ms2*(1+ms2)),*ap=a; int i,j,k; double vol; // Initialize mask while(ap q; q.push(0);q.push(0);q.push(0); while(!q.empty()) { // Read the next entry on the queue i=q.front();q.pop(); j=q.front();q.pop(); k=q.front();q.pop(); // Check intersection of this image if(intersects_image(i,j,k,vol)) { // Add this entry to the output vectors vi.push_back(i); vi.push_back(j); vi.push_back(k); vd.push_back(vol); // Add neighbors to the queue if they have not been // tested ap=ac+i+ms2*(j+ms2*k); if(k>-max_unit_voro_shells&&*(ap-ms2*ms2)) {q.push(i);q.push(j);q.push(k-1);*(ap-ms2*ms2)=false;} if(j>-max_unit_voro_shells&&*(ap-ms2)) {q.push(i);q.push(j-1);q.push(k);*(ap-ms2)=false;} if(i>-max_unit_voro_shells&&*(ap-1)) {q.push(i-1);q.push(j);q.push(k);*(ap-1)=false;} if(i,<%g,0,0>,rr}\n" "cylinder{<%g,%g,0>,<%g,%g,0>,rr}\n",bx,bxy,by,bx+bxy,by); fprintf(fp,"cylinder{<%g,%g,%g>,<%g,%g,%g>,rr}\n" "cylinder{<%g,%g,%g>,<%g,%g,%g>,rr}\n",bxz,byz,bz,bx+bxz,byz,bz,bxy+bxz,by+byz,bz,bx+bxy+bxz,by+byz,bz); fprintf(fp,"cylinder{<0,0,0>,<%g,%g,0>,rr}\n" "cylinder{<%g,0,0>,<%g,%g,0>,rr}\n",bxy,by,bx,bx+bxy,by); fprintf(fp,"cylinder{<%g,%g,%g>,<%g,%g,%g>,rr}\n" "cylinder{<%g,%g,%g>,<%g,%g,%g>,rr}\n",bxz,byz,bz,bxy+bxz,by+byz,bz,bx+bxz,byz,bz,bx+bxy+bxz,by+byz,bz); fprintf(fp,"cylinder{<0,0,0>,<%g,%g,%g>,rr}\n" "cylinder{<%g,0,0>,<%g,%g,%g>,rr}\n",bxz,byz,bz,bx,bx+bxz,byz,bz); fprintf(fp,"cylinder{<%g,%g,0>,<%g,%g,%g>,rr}\n" "cylinder{<%g,%g,0>,<%g,%g,%g>,rr}\n",bxy,by,bxy+bxz,by+byz,bz,bx+bxy,by,bx+bxy+bxz,by+byz,bz); fprintf(fp,"sphere{<0,0,0>,rr}\nsphere{<%g,0,0>,rr}\n" "sphere{<%g,%g,0>,rr}\nsphere{<%g,%g,0>,rr}\n",bx,bxy,by,bx+bxy,by); fprintf(fp,"sphere{<%g,%g,%g>,rr}\nsphere{<%g,%g,%g>,rr}\n" "sphere{<%g,%g,%g>,rr}\nsphere{<%g,%g,%g>,rr}\n",bxz,byz,bz,bx+bxz,byz,bz,bxy+bxz,by+byz,bz,bx+bxy+bxz,by+byz,bz); } travis-src-190101/src/v_unitcell.h0100777000000000000000000000704013412725647013762 0ustar00/***************************************************************************** TRAVIS - Trajectory Analyzer and Visualizer http://www.travis-analyzer.de/ Copyright (c) 2009-2019 Martin Brehm 2012-2019 Martin Thomas 2016-2019 Sascha Gehrke --------------------------------------------------------------------------- This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . *****************************************************************************/ // Voro++, a 3D cell-based Voronoi library // // Author : Chris H. Rycroft (LBL / UC Berkeley) // Email : chr@alum.mit.edu // Date : August 30th 2011 /** \file unitcell.hh * \brief Header file for the unitcell class. */ #ifndef VOROPP_UNITCELL_HH #define VOROPP_UNITCELL_HH // This must always be the first include directive #include "config.h" #include #include "v_config.h" #include "v_cell.h" /** \brief Class for computation of the unit Voronoi cell associated with * a 3D non-rectangular periodic domain. */ class unitcell { public: /** The x coordinate of the first vector defining the periodic * domain. */ const double bx; /** The x coordinate of the second vector defining the periodic * domain. */ const double bxy; /** The y coordinate of the second vector defining the periodic * domain. */ const double by; /** The x coordinate of the third vector defining the periodic * domain. */ const double bxz; /** The y coordinate of the third vector defining the periodic * domain. */ const double byz; /** The z coordinate of the third vector defining the periodic * domain. */ const double bz; /** The computed unit Voronoi cell corresponding the given * 3D non-rectangular periodic domain geometry. */ voronoicell_neighbor unit_voro; unitcell(double bx_,double bxy_,double by_,double bxz_,double byz_,double bz_); /** Draws an outline of the domain in Gnuplot format. * \param[in] filename the filename to write to. */ inline void draw_domain_gnuplot(const char* filename) { FILE *fp = (safe_fopen(filename,"w")); draw_domain_gnuplot(fp); fclose(fp); } void draw_domain_gnuplot(FILE *fp=stdout); /** Draws an outline of the domain in Gnuplot format. * \param[in] filename the filename to write to. */ inline void draw_domain_pov(const char* filename) { FILE *fp = (safe_fopen(filename,"w")); draw_domain_pov(fp); fclose(fp); } void draw_domain_pov(FILE *fp=stdout); bool intersects_image(double dx,double dy,double dz,double &vol); void images(vector &vi,vector &vd); protected: /** The maximum y-coordinate that could possibly cut the * computed unit Voronoi cell. */ double max_uv_y; /** The maximum z-coordinate that could possibly cut the * computed unit Voronoi cell. */ double max_uv_z; private: inline void unit_voro_apply(int i,int j,int k); bool unit_voro_intersect(int l); inline bool unit_voro_test(int i,int j,int k); }; #endif travis-src-190101/src/v_wall.cpp0100777000000000000000000001351513412725631013432 0ustar00/***************************************************************************** TRAVIS - Trajectory Analyzer and Visualizer http://www.travis-analyzer.de/ Copyright (c) 2009-2019 Martin Brehm 2012-2019 Martin Thomas 2016-2019 Sascha Gehrke --------------------------------------------------------------------------- This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . *****************************************************************************/ // Voro++, a 3D cell-based Voronoi library // // Author : Chris H. Rycroft (LBL / UC Berkeley) // Email : chr@alum.mit.edu // Date : August 30th 2011 /** \file wall.cc * \brief Function implementations for the derived wall classes. */ // This must always be the first include directive #include "config.h" #include "v_wall.h" const char *GetRevisionInfo_v_wall(unsigned int len) { static char buf[256]; GET_REVISION_INFO( buf, len ); return buf; } const char *GetSourceVersion_v_wall() { static char buf[256]; GET_SOURCE_VERSION( buf ); return buf; } /** Tests to see whether a point is inside the sphere wall object. * \param[in,out] (x,y,z) the vector to test. * \return True if the point is inside, false if the point is outside. */ bool wall_sphere::point_inside(double x,double y,double z) { return (x-xc)*(x-xc)+(y-yc)*(y-yc)+(z-zc)*(z-zc)1e-5) { dq=2*(sqrt(dq)*rc-dq); return c.nplane(xd,yd,zd,dq,w_id); } return true; } /** Tests to see whether a point is inside the plane wall object. * \param[in] (x,y,z) the vector to test. * \return True if the point is inside, false if the point is outside. */ bool wall_plane::point_inside(double x,double y,double z) { return x*xc+y*yc+z*zc1e-5) { pa=2*(sqrt(pa)*rc-pa); return c.nplane(xd,yd,zd,pa,w_id); } return true; } /** Tests to see whether a point is inside the cone wall object. * \param[in] (x,y,z) the vector to test. * \return True if the point is inside, false if the point is outside. */ bool wall_cone::point_inside(double x,double y,double z) { double xd=x-xc,yd=y-yc,zd=z-zc; double pa=(xd*xa+yd*ya+zd*za)*asi; xd-=xa*pa;yd-=ya*pa;zd-=za*pa; pa*=gra; if (pa<0) return false; pa*=pa; return xd*xd+yd*yd+zd*zd1e-5) { pa=1/sqrt(pa); imoda=sqrt(asi); xf=-sang*imoda*xa+cang*pa*xd; yf=-sang*imoda*ya+cang*pa*yd; zf=-sang*imoda*za+cang*pa*zd; pa=2*(xf*(xc-x)+yf*(yc-y)+zf*(zc-z)); return c.nplane(xf,yf,zf,pa,w_id); } return true; } travis-src-190101/src/v_wall.h0100777000000000000000000001230213412725667013101 0ustar00/***************************************************************************** TRAVIS - Trajectory Analyzer and Visualizer http://www.travis-analyzer.de/ Copyright (c) 2009-2019 Martin Brehm 2012-2019 Martin Thomas 2016-2019 Sascha Gehrke --------------------------------------------------------------------------- This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . *****************************************************************************/ // Voro++, a 3D cell-based Voronoi library // // Author : Chris H. Rycroft (LBL / UC Berkeley) // Email : chr@alum.mit.edu // Date : August 30th 2011 /** \file wall.hh * \brief Header file for the derived wall classes. */ #ifndef VOROPP_WALL_HH #define VOROPP_WALL_HH // This must always be the first include directive #include "config.h" #include "v_cell.h" #include "v_container.h" /** \brief A class representing a spherical wall object. * * This class represents a spherical wall object. */ struct wall_sphere : public wall { public: /** Constructs a spherical wall object. * \param[in] w_id_ an ID number to associate with the wall for * neighbor tracking. * \param[in] (xc_,yc_,zc_) a position vector for the sphere's * center. * \param[in] rc_ the radius of the sphere. */ wall_sphere(double xc_,double yc_,double zc_,double rc_,int w_id_=-99) : w_id(w_id_), xc(xc_), yc(yc_), zc(zc_), rc(rc_) {} bool point_inside(double x,double y,double z); bool cut_cell_base(voronoicell_neighbor &c,double x,double y,double z); bool cut_cell(voronoicell_neighbor &c,double x,double y,double z) {return cut_cell_base(c,x,y,z);} private: const int w_id; const double xc,yc,zc,rc; }; /** \brief A class representing a plane wall object. * * This class represents a single plane wall object. */ struct wall_plane : public wall { public: /** Constructs a plane wall object. * \param[in] (xc_,yc_,zc_) a normal vector to the plane. * \param[in] ac_ a displacement along the normal vector. * \param[in] w_id_ an ID number to associate with the wall for * neighbor tracking. */ wall_plane(double xc_,double yc_,double zc_,double ac_,int w_id_=-99) : w_id(w_id_), xc(xc_), yc(yc_), zc(zc_), ac(ac_) {} bool point_inside(double x,double y,double z); bool cut_cell_base(voronoicell_neighbor &c,double x,double y,double z); bool cut_cell(voronoicell_neighbor &c,double x,double y,double z) {return cut_cell_base(c,x,y,z);} private: const int w_id; const double xc,yc,zc,ac; }; /** \brief A class representing a cylindrical wall object. * * This class represents a open cylinder wall object. */ struct wall_cylinder : public wall { public: /** Constructs a cylinder wall object. * \param[in] (xc_,yc_,zc_) a point on the axis of the * cylinder. * \param[in] (xa_,ya_,za_) a vector pointing along the * direction of the cylinder. * \param[in] rc_ the radius of the cylinder * \param[in] w_id_ an ID number to associate with the wall for * neighbor tracking. */ wall_cylinder(double xc_,double yc_,double zc_,double xa_,double ya_,double za_,double rc_,int w_id_=-99) : w_id(w_id_), xc(xc_), yc(yc_), zc(zc_), xa(xa_), ya(ya_), za(za_), asi(1/(xa_*xa_+ya_*ya_+za_*za_)), rc(rc_) {} bool point_inside(double x,double y,double z); bool cut_cell_base(voronoicell_neighbor &c,double x,double y,double z); bool cut_cell(voronoicell_neighbor &c,double x,double y,double z) {return cut_cell_base(c,x,y,z);} private: const int w_id; const double xc,yc,zc,xa,ya,za,asi,rc; }; /** \brief A class representing a conical wall object. * * This class represents a cone wall object. */ struct wall_cone : public wall { public: /** Constructs a cone wall object. * \param[in] (xc_,yc_,zc_) the apex of the cone. * \param[in] (xa_,ya_,za_) a vector pointing along the axis of * the cone. * \param[in] ang the angle (in radians) of the cone, measured * from the axis. * \param[in] w_id_ an ID number to associate with the wall for * neighbor tracking. */ wall_cone(double xc_,double yc_,double zc_,double xa_,double ya_,double za_,double ang,int w_id_=-99) : w_id(w_id_), xc(xc_), yc(yc_), zc(zc_), xa(xa_), ya(ya_), za(za_), asi(1/(xa_*xa_+ya_*ya_+za_*za_)), gra(tan(ang)), sang(sin(ang)), cang(cos(ang)) {} bool point_inside(double x,double y,double z); bool cut_cell_base(voronoicell_neighbor &c,double x,double y,double z); bool cut_cell(voronoicell_neighbor &c,double x,double y,double z) {return cut_cell_base(c,x,y,z);} private: const int w_id; const double xc,yc,zc,xa,ya,za,asi,gra,sang,cang; }; #endif travis-src-190101/src/v_worklist.h0100777000000000000000000000415513412725655014024 0ustar00/***************************************************************************** TRAVIS - Trajectory Analyzer and Visualizer http://www.travis-analyzer.de/ Copyright (c) 2009-2019 Martin Brehm 2012-2019 Martin Thomas 2016-2019 Sascha Gehrke --------------------------------------------------------------------------- This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . *****************************************************************************/ // Voro++, a 3D cell-based Voronoi library // // Author : Chris H. Rycroft (LBL / UC Berkeley) // Email : chr@alum.mit.edu // Date : August 30th 2011 /** \file worklist.hh * \brief Header file for setting constants used in the block worklists that are * used during cell computation. * * This file is automatically generated by worklist_gen.pl and it is not * intended to be edited by hand. */ #ifndef VOROPP_WORKLIST_HH #define VOROPP_WORKLIST_HH // This must always be the first include directive #include "config.h" /** Each region is divided into a grid of subregions, and a worklist is # constructed for each. This parameter sets is set to half the number of # subregions that the block is divided into. */ const int wl_hgrid=4; /** The number of subregions that a block is subdivided into, which is twice the value of hgrid. */ const int wl_fgrid=8; /** The total number of worklists, set to the cube of hgrid. */ const int wl_hgridcu=64; /** The number of elements in each worklist. */ const int wl_seq_length=64; #endif travis-src-190101/src/xbytearray.cpp0100777000000000000000000002172713412725624014346 0ustar00/***************************************************************************** TRAVIS - Trajectory Analyzer and Visualizer http://www.travis-analyzer.de/ Copyright (c) 2009-2019 Martin Brehm 2012-2019 Martin Thomas 2016-2019 Sascha Gehrke This file was written by Martin Brehm. --------------------------------------------------------------------------- This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . *****************************************************************************/ // This must always be the first include directive #include "config.h" #include "xbytearray.h" const char *GetRevisionInfo_xbytearray(unsigned int len) { static char buf[256]; GET_REVISION_INFO( buf, len ); return buf; } const char *GetSourceVersion_xbytearray() { static char buf[256]; GET_SOURCE_VERSION( buf ); return buf; } #ifndef DEBUG_ARRAYS #define m_sName (NULL) #endif CxByteArray::CxByteArray() { BXIN; #ifdef DEBUG_CBYTEARRAY mprintf("@ CxByteArray::CxByteArray()\n"); #endif m_pData = NULL; m_iSize = 0; m_iMaxSize = 0; m_iGrow = 16; #ifdef DEBUG_ARRAYS m_sName = NULL; #endif BXOUT; } CxByteArray::CxByteArray(const char *name) { BXIN; #ifdef DEBUG_CBYTEARRAY mprintf("@ CxByteArray::CxByteArray(const char *s)\n"); #endif m_pData = NULL; m_iSize = 0; m_iMaxSize = 0; m_iGrow = 16; #ifdef DEBUG_ARRAYS m_sName = NULL; #endif SetName(name); BXOUT; } CxByteArray::~CxByteArray() { BXIN; #ifdef DEBUG_CBYTEARRAY mprintf("@ CxByteArray::~CxByteArray()\n"); #endif RemoveAll(); #ifdef DEBUG_ARRAYS if (m_sName != NULL) { delete[] m_sName; m_sName = NULL; } #endif BXOUT; } CxByteArray::CxByteArray(const CxByteArray &o) : CxObject() { BXIN; #ifdef DEBUG_CBYTEARRAY mprintf("@ CxByteArray::CxByteArray(CxByteArray &)..."); #endif unsigned long z; m_iGrow = o.m_iGrow; if ((o.m_iMaxSize != 0) && (o.m_pData != NULL)) { m_iSize = o.m_iSize; m_iMaxSize = o.m_iMaxSize; try { m_pData = new unsigned char[m_iMaxSize]; } catch(...) { m_pData = NULL; } if (m_pData == NULL) NewException((double)m_iMaxSize*sizeof(unsigned char),__FILE__,__LINE__,__PRETTY_FUNCTION__,m_sName); for (z=0;zm_iMaxSize) { m_iMaxSize = o->m_iMaxSize; if (m_pData != NULL) delete[] m_pData; try { m_pData = new unsigned char[m_iMaxSize]; } catch(...) { m_pData = NULL; } if (m_pData == NULL) NewException((double)m_iMaxSize*sizeof(unsigned char),__FILE__,__LINE__,__PRETTY_FUNCTION__,m_sName); } m_iSize = o->m_iSize; m_iGrow = o->m_iGrow; if (o->m_pData != NULL) memcpy(m_pData,o->m_pData,m_iSize*sizeof(unsigned char)); #ifdef DEBUG_CBYTEARRAY mprintf("done.\n"); #endif BXOUT; } void CxByteArray::Append(CxByteArray *o) { BXIN; #ifdef DEBUG_CBYTEARRAY mprintf("@ CxByteArray::Append(CxByteArray*)..."); #endif if (m_iMaxSize != o->m_iMaxSize) { m_iMaxSize = o->m_iMaxSize; if (m_pData != NULL) delete[] m_pData; try { m_pData = new unsigned char[m_iMaxSize]; } catch(...) { m_pData = NULL; } if (m_pData == NULL) NewException((double)m_iMaxSize*sizeof(unsigned char),__FILE__,__LINE__,__PRETTY_FUNCTION__,m_sName); } m_iGrow = o->m_iGrow; m_iSize = o->m_iSize; if (o->m_pData != NULL) memcpy(m_pData,o->m_pData,m_iSize*sizeof(unsigned char)); #ifdef DEBUG_CBYTEARRAY mprintf("done.\n"); #endif BXOUT; } void CxByteArray::SetAt(unsigned long pos, unsigned char f) { BXIN; unsigned long z; #ifdef DEBUG_CBYTEARRAY bool s = false; mprintf("@ CxByteArray::Add(unsigned short)..."); #endif if (pos >= m_iMaxSize) { #ifdef DEBUG_CBYTEARRAY s = true; mprintf("\n"); #endif SetMaxSize(pos+1); } m_pData[pos] = f; if (pos >= m_iSize) { for (z=m_iSize;z m_iMaxSize) { #ifdef DEBUG_CBYTEARRAY s = true; mprintf("\n"); #endif // SetMaxSize(m_iMaxSize + m_iGrow); if (m_iMaxSize == 0) SetMaxSize(m_iMaxSize + m_iGrow); else SetMaxSize(m_iMaxSize*2); } m_pData[m_iSize] = f; m_iSize++; #ifdef DEBUG_CBYTEARRAY if (s) mprintf("@ done.\n"); else mprintf("done.\n"); #endif BXOUT; } void CxByteArray::SetSize(unsigned long i) { BXIN; #ifdef DEBUG_CBYTEARRAY mprintf("@ CxByteArray::SetSize(int): %d...",i); #endif if (m_iSize == i) return; unsigned char *temp; try { temp = new unsigned char[i]; } catch(...) { temp = NULL; } if (temp == NULL) NewException((double)i*sizeof(unsigned char),__FILE__,__LINE__,__PRETTY_FUNCTION__,m_sName); if (m_pData != NULL) { if (m_iSize > i) memcpy(temp,m_pData,i*sizeof(unsigned char)); else memcpy(temp,m_pData,m_iSize*sizeof(unsigned char)); delete[] m_pData; } m_pData = temp; m_iMaxSize = i; m_iSize = i; #ifdef DEBUG_CBYTEARRAY mprintf("done.\n"); #endif BXOUT; } void CxByteArray::SetMaxSize(unsigned long i) { BXIN; #ifdef DEBUG_CBYTEARRAY mprintf("@ CxByteArray::SetMaxSize(int): %d...",i); #endif unsigned char *temp; try { temp = new unsigned char[i]; } catch(...) { temp = NULL; } if (temp == NULL) NewException((double)i*sizeof(unsigned char),__FILE__,__LINE__,__PRETTY_FUNCTION__,m_sName); if (m_pData != NULL) { memcpy(temp,m_pData,m_iSize*sizeof(unsigned char)); delete[] m_pData; } m_pData = temp; m_iMaxSize = i; #ifdef DEBUG_CBYTEARRAY mprintf("done.\n"); #endif BXOUT; } void CxByteArray::SetGrow(unsigned long i) { BXIN; #ifdef DEBUG_CBYTEARRAY mprintf("@ CxByteArray::SetGrow(int): %d\n",i); #endif m_iGrow = i; BXOUT; } void CxByteArray::RemoveAll() { BXIN; #ifdef DEBUG_CBYTEARRAY mprintf("@ CxByteArray::RemoveAll():..."); #endif if (m_pData != NULL) delete[] m_pData; m_pData = NULL; m_iSize = 0; m_iMaxSize = 0; #ifdef DEBUG_CBYTEARRAY mprintf("done.\n"); #endif BXOUT; } void CxByteArray::RemoveAll_KeepSize() { BXIN; #ifdef DEBUG_CBYTEARRAY mprintf("@ CxByteArray::RemoveAll_KeepSize():..."); #endif m_iSize = 0; #ifdef DEBUG_CBYTEARRAY mprintf("done.\n"); #endif BXOUT; } void CxByteArray::RemoveAt(unsigned long pos, unsigned long count) { BXIN; unsigned char *temp; #ifdef DEBUG_CBYTEARRAY mprintf("@ CxByteArray::RemoveAt(int, int): %d, %d...",pos,count); #endif try { temp = new unsigned char[m_iSize-count]; } catch(...) { temp = NULL; } if (temp == NULL) NewException((double)(m_iSize-count)*sizeof(unsigned char),__FILE__,__LINE__,__PRETTY_FUNCTION__,m_sName); if (m_pData != NULL) { memcpy(temp,m_pData,pos*sizeof(unsigned char)); memcpy(&temp[pos],&m_pData[pos+count],(m_iSize-pos-count)*sizeof(unsigned char)); delete[] m_pData; } m_pData = temp; m_iSize-=count; m_iMaxSize = m_iSize; #ifdef DEBUG_CBYTEARRAY mprintf("done.\n"); #endif BXOUT; } void CxByteArray::InsertAt(unsigned char f, unsigned long pos) { BXIN; unsigned char *temp; #ifdef DEBUG_CBYTEARRAY mprintf("@ CxByteArray::InsertAt(unsigned char, unsigned long): %d...",f); #endif try { temp = new unsigned char[m_iSize+1]; } catch(...) { temp = NULL; } if (temp == NULL) NewException((double)(m_iSize+1)*sizeof(unsigned char),__FILE__,__LINE__,__PRETTY_FUNCTION__,m_sName); if (m_pData != NULL) { memcpy(temp,m_pData,pos*sizeof(unsigned char)); memcpy(&temp[pos+1],&m_pData[pos],(m_iSize-pos)*sizeof(unsigned char)); delete[] m_pData; } temp[pos] = f; m_pData = temp; m_iSize++; m_iMaxSize = m_iSize; #ifdef DEBUG_CBYTEARRAY mprintf("done.\n"); #endif BXOUT; } void CxByteArray::SetName(const char *name) { UNUSED(name); #ifdef DEBUG_ARRAYS BXIN; #ifdef DEBUG_CBYTEARRAY mprintf("@ CxByteArray::SetName(const char *): \"%s\"...",s); #endif if (m_sName != NULL) delete[] m_sName; try { m_sName = new char[strlen(name)+1]; } catch(...) { m_sName = NULL; } if (m_sName == NULL) NewException((double)(strlen(name)+1)*sizeof(char),__FILE__,__LINE__,__PRETTY_FUNCTION__); strcpy(m_sName,name); #ifdef DEBUG_CBYTEARRAY mprintf("done.\n"); #endif BXOUT; #endif } travis-src-190101/src/xbytearray.h0100777000000000000000000000727213412725647014017 0ustar00/***************************************************************************** TRAVIS - Trajectory Analyzer and Visualizer http://www.travis-analyzer.de/ Copyright (c) 2009-2019 Martin Brehm 2012-2019 Martin Thomas 2016-2019 Sascha Gehrke This file was written by Martin Brehm. --------------------------------------------------------------------------- This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . *****************************************************************************/ #ifndef XBYTEARRAY_H #define XBYTEARRAY_H // This must always be the first include directive #include "config.h" #include "tools.h" #include "xobject.h" #include "backtrace.h" class CxByteArray : public CxObject { public: CxByteArray(); explicit CxByteArray(const char *name); void SetName(const char *name); ~CxByteArray(); CxByteArray(const CxByteArray &o); void CopyFrom(const CxByteArray *o); void Add(unsigned char f); void Append(CxByteArray *o); void SetAt(unsigned long pos, unsigned char f); void SetSize(unsigned long i); void SetMaxSize(unsigned long i); void SetGrow(unsigned long i); void RemoveAll(); void RemoveAll_KeepSize(); void RemoveAt(unsigned long pos, unsigned long count); void InsertAt(unsigned char f, unsigned long pos); bool Contains(unsigned char i) { BXIN; int z; for (z=0;z<(int)m_iSize;z++) if (m_pData[z] == i) return true; BXOUT; return false; } int GetPosition(unsigned char i) { BXIN; int z; for (z=0;z<(int)m_iSize;z++) if (m_pData[z] == i) return z; BXOUT; return -1; } unsigned char &GetAt(unsigned long i) { BXIN; #ifdef DEBUG_CBYTEARRAY mprintf("@ CxByteArray::GetAt(int): %d...",i); #endif #ifdef DEBUG_ARRAYS if (i >= m_iSize) { if (m_sName != NULL) eprintf("CxByteArray \"%s\" Boundary Error (%lu/%lu).\n",m_sName,i,m_iSize); else eprintf("CxByteArray Boundary Error (%lu/%lu).\n",i,m_iSize); abort(); } #endif #ifdef DEBUG_CBYTEARRAY mprintf("done.\n"); #endif BXOUT; return m_pData[i]; } unsigned char &operator [] (unsigned long i) { #ifdef DEBUG_CBYTEARRAY mprintf("@ CxByteArray::operator [] (int): %d\n",i); #endif return GetAt(i); } unsigned char GetAt(unsigned long i) const { BXIN; #ifdef DEBUG_CBYTEARRAY mprintf("@ CxByteArray::GetAt(int): %d...",i); #endif #ifdef DEBUG_ARRAYS if (i >= m_iSize) { if (m_sName != NULL) eprintf("CxByteArray \"%s\" Boundary Error (%lu/%lu).\n",m_sName,i,m_iSize); else eprintf("CxByteArray Boundary Error (%lu/%lu).\n",i,m_iSize); abort(); } #endif #ifdef DEBUG_CBYTEARRAY mprintf("done.\n"); #endif BXOUT; return m_pData[i]; } unsigned char operator [] (unsigned long i) const { #ifdef DEBUG_CBYTEARRAY mprintf("@ CxByteArray::operator [] (int): %d\n",i); #endif return GetAt(i); } int GetSize() { #ifdef DEBUG_CBYTEARRAY mprintf("@ CxByteArray::GetSize(): %d\n",m_iSize); #endif return m_iSize; } private: unsigned char *m_pData; unsigned long m_iSize; unsigned long m_iMaxSize; unsigned long m_iGrow; #ifdef DEBUG_ARRAYS char *m_sName; #endif }; #endif travis-src-190101/src/xdf.cpp0100777000000000000000000001725213412725620012727 0ustar00/***************************************************************************** TRAVIS - Trajectory Analyzer and Visualizer http://www.travis-analyzer.de/ Copyright (c) 2009-2019 Martin Brehm 2012-2019 Martin Thomas 2016-2019 Sascha Gehrke This file was written by Martin Brehm. --------------------------------------------------------------------------- This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . *****************************************************************************/ // This must always be the first include directive #include "config.h" #include "xdf.h" #include "globalvar.h" #include "maintools.h" const char *GetRevisionInfo_xdf(unsigned int len) { static char buf[256]; GET_REVISION_INFO( buf, len ); return buf; } const char *GetSourceVersion_xdf() { static char buf[256]; GET_SOURCE_VERSION( buf ); return buf; } CXDF::CXDF() { m_iDeriv = 0; m_bACF = false; m_bACFFFT = false; m_sName = NULL; m_sShortName = NULL; m_sLabelName = NULL; m_faData = NULL; m_baDataEnabled = NULL; } CXDF::~CXDF() { } void CXDF::ParseDeriv() { // int ti; if (!g_bAdvanced2) m_iDeriv = 0; else m_iDeriv = AskUnsignedInteger(" Use values (0), 1st time derivative (1), or 2nd time derivative (2) of the values? [0] ",0); if (m_iDeriv != 0) { g_bDeriv = true; m_bDerivAbs = AskYesNo(" Take the absolute values of the derivatives (y/n)? [no] ",false); m_bACF = AskYesNo(" Autocorrelate derived values (y/n)? [no] ",false); if (m_bACF) { eprintf("\n This feature is not working yet.\n\n"); m_bACF = false; } /* if (m_bACF) { m_iACFDepth = AskUnsignedInteger(" Enter depth of the autocorrelation in time steps: [10000] ",10000); ti = CalcFFTSize(m_iACFDepth,false); if (m_iACFDepth != ti) { mprintf(WHITE,"\nThe next \"fast\" size for autocorrelation is %d. Using this instead of %d as depth.\n",ti,m_iACFDepth); m_iACFDepth = ti; } m_bACFFFT = AskYesNo(" Calculate the fourier transform of the autocorrelation (y/n)? [yes] ",true); if (m_bACFFFT) { m_bWindowFunction = AskYesNo(" Apply window function (Cos^2) to Autocorrelation function (y/n)? [yes] ",true); m_fSpecWaveNumber = AskFloat(" Calculate spectrum up to which wave number (cm^-1) (0=full spectrum)? [4000cm^-1] ",4000.0); m_iMirror = AskUnsignedInteger(" No mirroring (0), short-time enhancing (1) or long-time enhancing (2)? [0] ",0); m_iZeroPadding = AskUnsignedInteger(" Zero Padding: How many zeros to insert? [%d] ",m_iACFDepth*3,m_iACFDepth*3); ti = CalcFFTSize(m_iACFDepth+m_iZeroPadding,false); if (m_iACFDepth+m_iZeroPadding != ti) { mprintf(WHITE,"\nThe next \"fast\" size for FFT is %d. Using %d zeros for zero padding.\n",ti,ti-m_iACFDepth); m_iZeroPadding = ti-m_iACFDepth; } m_bACF_DB = AskYesNo(" Convert intensity axis of spectrum to decibel (y/n)? [no] ",false); } }*/ } } void CXDF::InitDeriv() { int z2; CxDoubleArray *ptfa; try { m_pfaDerivBuffer = new CxDoubleArray*[3]; } catch(...) { m_pfaDerivBuffer = NULL; } if (m_pfaDerivBuffer == NULL) NewException((double)3*sizeof(CxDoubleArray*),__FILE__,__LINE__,__PRETTY_FUNCTION__); for (z2=0;z2<3;z2++) { try { m_pfaDerivBuffer[z2] = new CxDoubleArray("CXDF::m_pfaDerivBuffer[z2]"); } catch(...) { m_pfaDerivBuffer[z2] = NULL; } if (m_pfaDerivBuffer[z2] == NULL) NewException((double)sizeof(CxDoubleArray),__FILE__,__LINE__,__PRETTY_FUNCTION__); if (m_bSelf) m_pfaDerivBuffer[z2]->SetSize(((CMolecule*)g_oaMolecules[g_iFixMol])->m_laSingleMolIndex.GetSize()*m_iCombinations); else m_pfaDerivBuffer[z2]->SetSize(((CMolecule*)g_oaMolecules[g_iFixMol])->m_laSingleMolIndex.GetSize()*((CMolecule*)g_oaMolecules[m_iShowMol])->m_laSingleMolIndex.GetSize()*m_iCombinations); } if (m_bACF) { if (m_bSelf) { try { m_pfaACFBuffer = new CxDoubleArray*[((CMolecule*)g_oaMolecules[g_iFixMol])->m_laSingleMolIndex.GetSize()*m_iCombinations]; } catch(...) { m_pfaACFBuffer = NULL; } if (m_pfaACFBuffer == NULL) NewException((double)((CMolecule*)g_oaMolecules[g_iFixMol])->m_laSingleMolIndex.GetSize()*m_iCombinations*sizeof(CxDoubleArray*),__FILE__,__LINE__,__PRETTY_FUNCTION__); for (z2=0;z2<((CMolecule*)g_oaMolecules[g_iFixMol])->m_laSingleMolIndex.GetSize()*m_iCombinations;z2++) { try { ptfa = new CxDoubleArray("CXDF::InitDeriv():ptfa"); } catch(...) { ptfa = NULL; } if (ptfa == NULL) NewException((double)sizeof(CxDoubleArray),__FILE__,__LINE__,__PRETTY_FUNCTION__); if (g_iTrajSteps != -1) { ptfa->SetMaxSize((long)(g_iTrajSteps*1.1)); ptfa->SetGrow((long)(g_iTrajSteps*0.1)); } else ptfa->SetGrow(1000); m_pfaACFBuffer[z2] = ptfa; } } else { try { m_pfaACFBuffer = new CxDoubleArray*[((CMolecule*)g_oaMolecules[g_iFixMol])->m_laSingleMolIndex.GetSize()*((CMolecule*)g_oaMolecules[m_iShowMol])->m_laSingleMolIndex.GetSize()*m_iCombinations]; } catch(...) { m_pfaACFBuffer = NULL; } if (m_pfaACFBuffer == NULL) NewException((double)((CMolecule*)g_oaMolecules[g_iFixMol])->m_laSingleMolIndex.GetSize()*((CMolecule*)g_oaMolecules[m_iShowMol])->m_laSingleMolIndex.GetSize()*m_iCombinations*sizeof(CxDoubleArray*),__FILE__,__LINE__,__PRETTY_FUNCTION__); for (z2=0;z2<((CMolecule*)g_oaMolecules[g_iFixMol])->m_laSingleMolIndex.GetSize()*((CMolecule*)g_oaMolecules[m_iShowMol])->m_laSingleMolIndex.GetSize()*m_iCombinations;z2++) { try { ptfa = new CxDoubleArray("CXDF::InitDeriv():ptfa"); } catch(...) { ptfa = NULL; } if (ptfa == NULL) NewException((double)sizeof(CxDoubleArray),__FILE__,__LINE__,__PRETTY_FUNCTION__); if (g_iTrajSteps != -1) { ptfa->SetMaxSize((long)(g_iTrajSteps*1.1)); ptfa->SetGrow((long)(g_iTrajSteps*0.1)); } else ptfa->SetGrow(1000); m_pfaACFBuffer[z2] = ptfa; } } } } void CXDF::Autocorrelate() { int n, z, z2; double tfs; CAutoCorrelation *ac; CxDoubleArray *ptfa; if (m_bSelf) n = ((CMolecule*)g_oaMolecules[g_iFixMol])->m_laSingleMolIndex.GetSize()*m_iCombinations; else n = ((CMolecule*)g_oaMolecules[g_iFixMol])->m_laSingleMolIndex.GetSize()*((CMolecule*)g_oaMolecules[m_iShowMol])->m_laSingleMolIndex.GetSize()*m_iCombinations; tfs = n/60.0; mprintf(" Autocorrelating cached values...\n"); mprintf(WHITE," ["); try { ptfa = new CxDoubleArray("CXDF::Autocorrelate():ptfa"); } catch(...) { ptfa = NULL; } if (ptfa == NULL) NewException((double)sizeof(CxDoubleArray),__FILE__,__LINE__,__PRETTY_FUNCTION__); ptfa->SetSize(m_pfaACFBuffer[0]->GetSize()); try { ac = new CAutoCorrelation(); } catch(...) { ac = NULL; } if (ac == NULL) NewException((double)sizeof(CAutoCorrelation),__FILE__,__LINE__,__PRETTY_FUNCTION__); ac->Init(m_pfaACFBuffer[0]->GetSize(),m_iACFDepth,true); m_faACF.SetSize(m_iACFDepth); for (z=0;zAutoCorrelate(m_pfaACFBuffer[z],ptfa); for (z2=0;z2. *****************************************************************************/ #ifndef XDF_H #define XDF_H // This must always be the first include directive #include "config.h" #include "xobject.h" #include "xbytearray.h" #include "xdoublearray.h" #include "xdoublearray.h" class CXDF : public CxObject { public: void Autocorrelate(); void InitDeriv(); CXDF(); ~CXDF(); void ParseDeriv(); bool m_bSelf; int m_iShowMol; int m_iCombinations; int m_iDeriv; bool m_bDerivAbs; bool m_bACF; int m_iACFDepth; bool m_bACFFFT; bool m_bWindowFunction; double m_fSpecWaveNumber; int m_iMirror; int m_iZeroPadding; bool m_bACF_DB; CxDoubleArray **m_pfaACFBuffer; CxDoubleArray m_faACF; int m_iHistogramRes; int m_iResolution; CxDoubleArray *m_faData; CxByteArray *m_baDataEnabled; CxDoubleArray **m_pfaDerivBuffer; char *m_sName; char *m_sShortName; char *m_sLabelName; }; #endif travis-src-190101/src/xdmatrix3.cpp0100777000000000000000000001255713412725627014103 0ustar00/***************************************************************************** TRAVIS - Trajectory Analyzer and Visualizer http://www.travis-analyzer.de/ Copyright (c) 2009-2019 Martin Brehm 2012-2019 Martin Thomas 2016-2019 Sascha Gehrke This file was written by Martin Brehm. --------------------------------------------------------------------------- This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . *****************************************************************************/ // This must always be the first include directive #include "config.h" #include "xdmatrix3.h" #include "tools.h" const char *GetRevisionInfo_xdmatrix3(unsigned int len) { static char buf[256]; GET_REVISION_INFO( buf, len ); return buf; } const char *GetSourceVersion_xdmatrix3() { static char buf[256]; GET_SOURCE_VERSION( buf ); return buf; } void CxDMatrix3::Dump() const { BXIN; int z/*, z2*/; for (z=0;z<3;z++) { /* for (z2=0;z2<3;z2++) if ((GetAt(z2,z) < 0) && (GetAt(z2,z) > -0.000000001)) GetAt(z2,z) = 0;*/ mprintf("( %6.3f %6.3f %6.3f )\n",GetAt(0,z),GetAt(1,z),GetAt(2,z)); } BXOUT; } void CxDMatrix3::DumpSmall() const { BXIN; int z/*, z2*/; for (z=0;z<3;z++) { /* for (z2=0;z2<3;z2++) if ((GetAt(z2,z) < 0) && (GetAt(z2,z) > -0.000000001)) GetAt(z2,z) = 0;*/ mprintf("( %12.9f %12.9f %12.9f )\n",GetAt(0,z),GetAt(1,z),GetAt(2,z)); } BXOUT; } void CxDMatrix3::MatUltra(const CxDVector3 &vec1, const CxDVector3 &vec2) { BXIN; CxDMatrix3 mat, mat2; CxDVector3 vectemp, vecx, vecy, vec2n, vectemp2; /* double mat[3][3], mat2[3][3]; double vectemp[3], vecx[3], vecy[3], vec2n[3], vectemp2[3];*/ double a; #ifdef DEBUG_MATULTRA mprintf("\nLinAlg Checker\n\n"); mprintf("Vektor 1: "); vec1.Dump(); mprintf("\nVektor 2: "); vec2.Dump(); #endif vecx[0] = 1.0; vecx[1] = 0.0; vecx[2] = 0.0; vecy[0] = 0.0; vecy[1] = 1.0; vecy[2] = 0.0; #ifdef DEBUG_MATULTRA mprintf("\nVektor X: "); vecx.Dump(); mprintf("\nVektor Y: "); vecy.Dump(); #endif // Zu erst vec1 auf X drehen vectemp = CrossP(vec1,vecx); if (vectemp.GetLength() != 0) { #ifdef DEBUG_MATULTRA mprintf("\nDrehachse fuer Vektor1->X: "); vectemp.Dump(); #endif vectemp.Normalize(); #ifdef DEBUG_MATULTRA mprintf("\nNormalisiert: "); vectemp.Dump(); #endif a = Angle(vec1,vecx); #ifdef DEBUG_MATULTRA mprintf("\nDrehwinkel: %.1f Grad\n",a*180.0/Pi); #endif mat.RotMat(vectemp,a); } else { #ifdef DEBUG_MATULTRA mprintf("\nDer liegt schon auf der X-Achse!"); #endif mat.Unity(); } vec2n = mat*vec2; #ifdef DEBUG_MATULTRA mprintf("Drehmatrix dafuer:\n"); mat.Dump(); vectemp = mat*vec1; mprintf("\nDamit wird Vektor1 zu "); vectemp.Dump(); mprintf("\nUnd Vektor2 zu "); vec2n.Dump(); #endif if ((vec2-vec1).GetLength() < 0.0001) { *this = mat; BXOUT; return; } vectemp2[0] = 0; vectemp2[1] = vec2n[1]; vectemp2[2] = vec2n[2]; #ifdef DEBUG_MATULTRA mprintf("\nProjektion von Vektor2n auf YZ-Ebene: "); vectemp2.Dump(); #endif a = Angle(vectemp2,vecy); #ifdef DEBUG_MATULTRA mprintf("\n"); #endif if (vectemp2.GetLength()==0) { eprintf("\nMatUltra: Error caught.\n"); a = Pi/2.0; } if (vec2n[2] > 0) a = -a; #ifdef DEBUG_MATULTRA mprintf("\nDrehachse fuer Vektor2->XY: "); vecx.Dump(); mprintf("\nDrehwinkel: %.1f Grad\n",a*180.0/Pi); #endif mat2.RotMat(vecx,a); #ifdef DEBUG_MATULTRA mprintf("Drehmatrix dafuer:\n"); mat2.Dump(); vectemp = mat*vec1; vectemp2 = mat2*vectemp; mprintf("\nDamit wird Vektor1 zu "); vectemp2.Dump(); vectemp = mat2*vec2n; mprintf("\nUnd Vektor2n zu "); vectemp.Dump(); #endif *this = mat2*mat; #ifdef DEBUG_MATULTRA mprintf("\nMacht diese Gesamtmatrix:\n"); Dump(); vectemp = *this*vec1; mprintf("\nDamit wird Vektor 1 von "); vec1.Dump(); mprintf(" zu "); vectemp.Dump(); vectemp = *this*vec2; mprintf("\nUnd Vektor 2 wird von "); vec2.Dump(); mprintf(" zu "); vectemp.Dump(); mprintf("\n"); #endif BXOUT; } bool CxDMatrix3::Invert() { #define a11 GetAt(0,0) #define a12 GetAt(0,1) #define a13 GetAt(0,2) #define a21 GetAt(1,0) #define a22 GetAt(1,1) #define a23 GetAt(1,2) #define a31 GetAt(2,0) #define a32 GetAt(2,1) #define a33 GetAt(2,2) CxDMatrix3 t; double det; det = a11 * (a33*a22 - a32*a23) - a21 * (a33*a12 - a32*a13) + a31 * (a23*a12 - a22*a13); if (det == 0) { eprintf("CxDMatrix3::Invert(): Failed - matrix is singular.\n"); return false; } t.GetAt(0,0) = (a33*a22 - a32*a23); t.GetAt(0,1) = -(a33*a12 - a32*a13); t.GetAt(0,2) = (a23*a12 - a22*a13); t.GetAt(1,0) = -(a33*a21 - a31*a23); t.GetAt(1,1) = (a33*a11 - a31*a13); t.GetAt(1,2) = -(a23*a11 - a21*a13); t.GetAt(2,0) = (a32*a21 - a31*a22); t.GetAt(2,1) = -(a32*a11 - a31*a12); t.GetAt(2,2) = (a22*a11 - a21*a12); t *= 1.0/det; *this = t; return true; } travis-src-190101/src/xdmatrix3.h0100777000000000000000000001563513412725667013554 0ustar00/***************************************************************************** TRAVIS - Trajectory Analyzer and Visualizer http://www.travis-analyzer.de/ Copyright (c) 2009-2019 Martin Brehm 2012-2019 Martin Thomas 2016-2019 Sascha Gehrke This file was written by Martin Brehm. --------------------------------------------------------------------------- This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . *****************************************************************************/ #ifndef CXDMATRIX3_DEFINED #define CXDMATRIX3_DEFINED // This must always be the first include directive #include "config.h" #include "tools.h" #include "xobject.h" #include "xdvector3.h" #include "backtrace.h" class CxDMatrix3 : public CxObject { public: CxDMatrix3() { } ~CxDMatrix3() { } /* CxDMatrix3(CxDMatrix3 m) { m_pData[0] = m.m_pData[0]; m_pData[1] = m.m_pData[1]; m_pData[2] = m.m_pData[2]; m_pData[3] = m.m_pData[3]; m_pData[4] = m.m_pData[4]; m_pData[5] = m.m_pData[5]; m_pData[6] = m.m_pData[6]; m_pData[7] = m.m_pData[7]; m_pData[8] = m.m_pData[8]; }*/ CxDMatrix3(const CxDMatrix3 &m) : CxObject() { BXIN; m_pData[0] = m.m_pData[0]; m_pData[1] = m.m_pData[1]; m_pData[2] = m.m_pData[2]; m_pData[3] = m.m_pData[3]; m_pData[4] = m.m_pData[4]; m_pData[5] = m.m_pData[5]; m_pData[6] = m.m_pData[6]; m_pData[7] = m.m_pData[7]; m_pData[8] = m.m_pData[8]; BXOUT; } explicit CxDMatrix3(double f) { BXIN; m_pData[0] = f; m_pData[1] = f; m_pData[2] = f; m_pData[3] = f; m_pData[4] = f; m_pData[5] = f; m_pData[6] = f; m_pData[7] = f; m_pData[8] = f; BXOUT; } CxDMatrix3(double a, double b, double c, double d, double e, double f, double g, double h, double i) { BXIN; m_pData[0] = a; m_pData[1] = b; m_pData[2] = c; m_pData[3] = d; m_pData[4] = e; m_pData[5] = f; m_pData[6] = g; m_pData[7] = h; m_pData[8] = i; BXOUT; } double &GetAt(int i) { #ifdef DEBUG_CMATRIX3 mprintf("@ CxDMatrix3::GetAt(int): %d...",i); #endif return m_pData[i]; } double &GetAt(int i, int j) { #ifdef DEBUG_CMATRIX3 mprintf("@ CxDMatrix3::GetAt(int, int): %d, %d...",i,j); #endif return m_pData[i*3+j]; } double &operator [] (int i) { #ifdef DEBUG_CMATRIX3 mprintf("@ CxDMatrix3::operator [] (int): %d\n",i); #endif return GetAt(i); } double GetAt(int i) const { #ifdef DEBUG_CMATRIX3 mprintf("@ CxDMatrix3::GetAt(int): %d...",i); #endif return m_pData[i]; } double GetAt(int i, int j) const { #ifdef DEBUG_CMATRIX3 mprintf("@ CxDMatrix3::GetAt(int, int): %d, %d...",i,j); #endif return m_pData[i*3+j]; } double operator [] (int i) const { #ifdef DEBUG_CMATRIX3 mprintf("@ CxDMatrix3::operator [] (int): %d\n",i); #endif return GetAt(i); } double &operator () (int i, int j) { #ifdef DEBUG_CMATRIX3 mprintf("@ CxDMatrix3::operator () (int, int): %d, %d\n",i,j); #endif return GetAt(i,j); } double operator () (int i, int j) const { #ifdef DEBUG_CMATRIX3 mprintf("@ CxDMatrix3::operator () (int, int): %d, %d\n",i,j); #endif return GetAt(i,j); } void operator *= (double f) { BXIN; #ifdef DEBUG_CMATRIX3 mprintf("@ CxDMatrix3::operator *= (double)\n"); #endif m_pData[0] *= f; m_pData[1] *= f; m_pData[2] *= f; m_pData[3] *= f; m_pData[4] *= f; m_pData[5] *= f; m_pData[6] *= f; m_pData[7] *= f; m_pData[8] *= f; BXOUT; } CxDMatrix3 operator * (const CxDMatrix3 &m) const { #ifdef DEBUG_CMATRIX3 mprintf("@ CxDMatrix3::operator * (CxDMatrix3)\n"); #endif return CxDMatrix3( GetAt(0,0)*m.GetAt(0,0) + GetAt(1,0)*m.GetAt(0,1) + GetAt(2,0)*m.GetAt(0,2), GetAt(0,1)*m.GetAt(0,0) + GetAt(1,1)*m.GetAt(0,1) + GetAt(2,1)*m.GetAt(0,2), GetAt(0,2)*m.GetAt(0,0) + GetAt(1,2)*m.GetAt(0,1) + GetAt(2,2)*m.GetAt(0,2), GetAt(0,0)*m.GetAt(1,0) + GetAt(1,0)*m.GetAt(1,1) + GetAt(2,0)*m.GetAt(1,2), GetAt(0,1)*m.GetAt(1,0) + GetAt(1,1)*m.GetAt(1,1) + GetAt(2,1)*m.GetAt(1,2), GetAt(0,2)*m.GetAt(1,0) + GetAt(1,2)*m.GetAt(1,1) + GetAt(2,2)*m.GetAt(1,2), GetAt(0,0)*m.GetAt(2,0) + GetAt(1,0)*m.GetAt(2,1) + GetAt(2,0)*m.GetAt(2,2), GetAt(0,1)*m.GetAt(2,0) + GetAt(1,1)*m.GetAt(2,1) + GetAt(2,1)*m.GetAt(2,2), GetAt(0,2)*m.GetAt(2,0) + GetAt(1,2)*m.GetAt(2,1) + GetAt(2,2)*m.GetAt(2,2) ); } CxDVector3 operator * (const CxDVector3 &v) const { #ifdef DEBUG_CMATRIX3 mprintf("@ CxDMatrix3::operator * (CxDVector3)\n"); #endif return CxDVector3( GetAt(0,0)*v[0] + GetAt(1,0)*v[1] + GetAt(2,0)*v[2], GetAt(0,1)*v[0] + GetAt(1,1)*v[1] + GetAt(2,1)*v[2], GetAt(0,2)*v[0] + GetAt(1,2)*v[1] + GetAt(2,2)*v[2]); } CxDMatrix3 operator * (double f) const { #ifdef DEBUG_CMATRIX3 mprintf("@ CxDMatrix3::operator * (double)\n"); #endif return CxDMatrix3(m_pData[0]*f,m_pData[1]*f,m_pData[2]*f,m_pData[3]*f,m_pData[4]*f,m_pData[5]*f,m_pData[6]*f,m_pData[7]*f,m_pData[8]*f); } void RotMat(const CxDVector3 &vec, double a) { BXIN; double ca, sa; ca = cos(a); sa = sin(a); GetAt(0,0) = (vec[0]*vec[0]*(1.0-ca) + ca); GetAt(1,0) = (vec[0]*vec[1]*(1.0-ca) - vec[2]*sa); GetAt(2,0) = (vec[0]*vec[2]*(1.0-ca) + vec[1]*sa); GetAt(0,1) = (vec[1]*vec[0]*(1.0-ca) + vec[2]*sa); GetAt(1,1) = (vec[1]*vec[1]*(1.0-ca) + ca); GetAt(2,1) = (vec[1]*vec[2]*(1.0-ca) - vec[0]*sa); GetAt(0,2) = (vec[2]*vec[0]*(1.0-ca) - vec[1]*sa); GetAt(1,2) = (vec[2]*vec[1]*(1.0-ca) + vec[0]*sa); GetAt(2,2) = (vec[2]*vec[2]*(1.0-ca) + ca); BXOUT; } void Unity() { BXIN; GetAt(0,0) = 1; GetAt(1,0) = 0; GetAt(2,0) = 0; GetAt(0,1) = 0; GetAt(1,1) = 1; GetAt(2,1) = 0; GetAt(0,2) = 0; GetAt(1,2) = 0; GetAt(2,2) = 1; BXOUT; } CxDMatrix3 Transpose() { return CxDMatrix3( GetAt(0,0), GetAt(1,0), GetAt(2,0), GetAt(0,1), GetAt(1,1), GetAt(2,1), GetAt(0,2), GetAt(1,2), GetAt(2,2)); } double Det() { #define a11 GetAt(0,0) #define a12 GetAt(0,1) #define a13 GetAt(0,2) #define a21 GetAt(1,0) #define a22 GetAt(1,1) #define a23 GetAt(1,2) #define a31 GetAt(2,0) #define a32 GetAt(2,1) #define a33 GetAt(2,2) return a11 * (a33*a22 - a32*a23) - a21 * (a33*a12 - a32*a13) + a31 * (a23*a12 - a22*a13); } void Dump() const; void DumpSmall() const; bool Invert(); void MatUltra(const CxDVector3 &vec1, const CxDVector3 &vec2); private: double m_pData[9]; }; #endif travis-src-190101/src/xdmatrixmn.cpp0100777000000000000000000000477413412725617014354 0ustar00/***************************************************************************** TRAVIS - Trajectory Analyzer and Visualizer http://www.travis-analyzer.de/ Copyright (c) 2009-2019 Martin Brehm 2012-2019 Martin Thomas 2016-2019 Sascha Gehrke This file was written by Martin Brehm. --------------------------------------------------------------------------- This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . *****************************************************************************/ // This must always be the first include directive #include "config.h" #include "xdmatrixmn.h" #include "tools.h" const char *GetRevisionInfo_xdmatrixmn(unsigned int len) { static char buf[256]; GET_REVISION_INFO( buf, len ); return buf; } const char *GetSourceVersion_xdmatrixmn() { static char buf[256]; GET_SOURCE_VERSION( buf ); return buf; } void CxDMatrixMN::Dump() const { BXIN; int z, z2; for (z=0;z. *****************************************************************************/ #ifndef XDMATRIXMN_H #define XDMATRIXMN_H // This must always be the first include directive #include "config.h" #include "tools.h" #include "xdvectorn.h" #define BOUND_MATVEC class CxDMatrixMN : public CxObject { public: CxDMatrixMN() { m_iRows = 0; m_iCols = 0; m_pData = NULL; } ~CxDMatrixMN() { if (m_pData != NULL) { delete[] m_pData; m_pData = NULL; } } CxDMatrixMN(const CxDMatrixMN &m) { BXIN; m_iCols = m.m_iCols; m_iRows = m.m_iRows; m_pData = new double[m_iRows*m_iCols]; memcpy(m_pData,m.m_pData,sizeof(double)*m_iRows*m_iCols); BXOUT; } CxDMatrixMN & operator = (const CxDMatrixMN &m) { #ifdef DEBUG_CDMATRIXMN mprintf("@ CxDMatrixMN::operator = (const CxDMatrixMN &)\n"); #endif BXIN; if (m_pData != NULL) delete[] m_pData; m_iRows = m.m_iRows; m_iCols = m.m_iCols; m_pData = new double[m_iRows*m_iCols]; memcpy(m_pData,m.m_pData,sizeof(double)*m_iRows*m_iCols); BXOUT; return *this; } CxDMatrixMN(int m, int n, double f) { BXIN; int z; m_iRows = m; m_iCols = n; m_pData = new double[m_iRows*m_iCols]; for (z=0;z= m_iRows*m_iCols)) { eprintf("& CxDMatrixMN::GetAt(int): Boundary Error (%d/%d).\n",i,m_iRows*m_iCols); abort(); } #endif return m_pData[i]; } double &GetAt(int i, int j) { #ifdef DEBUG_CDMATRIXMN mprintf("@ CxDMatrixMN::GetAt(int, int): %d, %d.\n",i,j); #endif #ifdef BOUND_MATVEC if ((i < 0) || (i >= m_iRows) || (j < 0) || (j >= m_iCols)) { eprintf("& CxDMatrixMN::GetAt(int,int): Boundary Error (%d|%d / %d|%d).\n",i,j,m_iRows,m_iCols); abort(); } #endif return m_pData[i*m_iCols+j]; } double &operator [] (int i) { #ifdef DEBUG_CDMATRIXMN mprintf("@ CxDMatrixMN::operator [] (int): %d.\n",i); #endif return GetAt(i); } double &operator () (int i, int j) { #ifdef DEBUG_CDMATRIXMN mprintf("@ CxDMatrixMN::operator () (int,int): %d, %d.\n",i,j); #endif #ifdef BOUND_MATVEC if ((i < 0) || (i >= m_iRows) || (j < 0) || (j >= m_iCols)) { eprintf("& CxDMatrixMN::operator () (int,int): Boundary Error (%d|%d / %d|%d).\n",i,j,m_iRows,m_iCols); abort(); } #endif return m_pData[i*m_iCols+j]; } double GetAt(int i) const { #ifdef DEBUG_CDMATRIXMN mprintf("@ CxDMatrixMN::GetAt(int): %d.\n",i); #endif #ifdef BOUND_MATVEC if ((i < 0) || (i >= m_iRows*m_iCols)) { eprintf("CxDMatrixMN::GetAt(int): Boundary Error (%d/%d).\n",i,m_iRows*m_iCols); abort(); } #endif return m_pData[i]; } double GetAt(int i, int j) const { #ifdef DEBUG_CDMATRIXMN mprintf("@ CxDMatrixMN::GetAt(int,int): %d, %d.\n",i,j); #endif #ifdef BOUND_MATVEC if ((i < 0) || (i >= m_iRows) || (j < 0) || (j >= m_iCols)) { eprintf("CxDMatrixMN::GetAt(int,int): Boundary Error (%d|%d / %d|%d).\n",i,j,m_iRows,m_iCols); abort(); } #endif return m_pData[i*m_iCols+j]; } double operator [] (int i) const { #ifdef DEBUG_CDMATRIXMN mprintf("@ CxDMatrixMN::operator [] (int): %d.\n",i); #endif #ifdef BOUND_MATVEC if ((i < 0) || (i >= m_iRows*m_iCols)) { eprintf("CxDMatrixMN::operator [] (int): Boundary Error (%d/%d).\n",i,m_iRows*m_iCols); abort(); } #endif return m_pData[i]; } double operator () (int i, int j) const { #ifdef DEBUG_CDMATRIXMN mprintf("@ CxDMatrixMN::operator () (int,int): %d, %d.\n",i,j); #endif #ifdef BOUND_MATVEC if ((i < 0) || (i >= m_iRows) || (j < 0) || (j >= m_iCols)) { eprintf("CxDMatrixMN::operator () (int,int): Boundary Error (%d|%d / %d|%d).\n",i,j,m_iRows,m_iCols); abort(); } #endif return m_pData[i*m_iCols+j]; } void operator *= (double f) { BXIN; #ifdef DEBUG_CDMATRIXMN mprintf("@ CxDMatrixMN::operator *= (double)\n"); #endif int z; for (z=0;z. *****************************************************************************/ // This must always be the first include directive #include "config.h" #include "xdoublearray.h" const char *GetRevisionInfo_xdoublearray(unsigned int len) { static char buf[256]; GET_REVISION_INFO( buf, len ); return buf; } const char *GetSourceVersion_xdoublearray() { static char buf[256]; GET_SOURCE_VERSION( buf ); return buf; } #ifndef DEBUG_ARRAYS #define m_sName (NULL) #endif CxDoubleArray::CxDoubleArray() { BXIN; #ifdef DEBUG_CDOUBLEARRAY mprintf("@ CxDoubleArray::CxDoubleArray()\n"); #endif m_pData = NULL; #ifdef DEBUG_ARRAYS m_sName = NULL; #endif m_iSize = 0; m_iMaxSize = 0; m_iGrow = 16; BXOUT; } CxDoubleArray::CxDoubleArray(const char *name) { BXIN; #ifdef DEBUG_CDOUBLEARRAY mprintf("@ CxDoubleArray::CxDoubleArray(const char *)\n"); #endif m_pData = NULL; #ifdef DEBUG_ARRAYS m_sName = NULL; #endif m_iSize = 0; m_iMaxSize = 0; m_iGrow = 10; SetName(name); BXOUT; } CxDoubleArray::~CxDoubleArray() { BXIN; #ifdef DEBUG_CDOUBLEARRAY mprintf("@ CxDoubleArray::~CxDoubleArray()\n"); #endif RemoveAll(); #ifdef DEBUG_ARRAYS if (m_sName != NULL) { delete[] m_sName; m_sName = NULL; } #endif BXOUT; } CxDoubleArray::CxDoubleArray(const CxDoubleArray &o) : CxObject() { BXIN; #ifdef DEBUG_CDOUBLEARRAY mprintf("@ CxDoubleArray::CxDoubleArray(CxDoubleArray &)..."); #endif unsigned long z; m_iGrow = o.m_iGrow; if ((o.m_iMaxSize != 0) && (o.m_pData != NULL)) { m_iSize = o.m_iSize; m_iMaxSize = o.m_iMaxSize; try { m_pData = new double[m_iMaxSize]; } catch(...) { m_pData = NULL; } if (m_pData == NULL) NewException((double)m_iMaxSize*sizeof(double),__FILE__,__LINE__,__PRETTY_FUNCTION__,m_sName); for (z=0;z= m_iMaxSize) { #ifdef DEBUG_CDOUBLEARRAY s = true; mprintf("\n"); #endif SetMaxSize(pos+1); } m_pData[pos] = f; if (pos >= m_iSize) { for (z=m_iSize;z m_iMaxSize) { #ifdef DEBUG_CDOUBLEARRAY s = true; mprintf("\n"); #endif // SetMaxSize(m_iMaxSize + m_iGrow); if (m_iMaxSize == 0) SetMaxSize(m_iMaxSize + m_iGrow); else SetMaxSize(m_iMaxSize*2); } m_pData[m_iSize] = f; m_iSize++; #ifdef DEBUG_CDOUBLEARRAY if (s) mprintf("@ done.\n"); else mprintf("done.\n"); #endif BXOUT; } void CxDoubleArray::SetSize(unsigned long i) { BXIN; #ifdef DEBUG_CDOUBLEARRAY mprintf("@ CxDoubleArray::SetSize(int): %d...",i); #endif if (m_iSize == i) return; double *temp; try { temp = new double[i]; } catch(...) { temp = NULL; } if (temp == NULL) NewException((double)i*sizeof(double),__FILE__,__LINE__,__PRETTY_FUNCTION__,m_sName); if (m_pData != NULL) { if (m_iSize > i) memcpy(temp,m_pData,i*sizeof(double)); else memcpy(temp,m_pData,m_iSize*sizeof(double)); delete[] m_pData; } m_pData = temp; m_iMaxSize = i; m_iSize = i; #ifdef DEBUG_CDOUBLEARRAY mprintf("done.\n"); #endif BXOUT; } void CxDoubleArray::SetMaxSize(unsigned long i) { BXIN; #ifdef DEBUG_CDOUBLEARRAY mprintf("@ CxDoubleArray::SetMaxSize(int): %d...",i); #endif double *temp; try { temp = new double[i]; } catch(...) { temp = NULL; } if (temp == NULL) NewException((double)i*sizeof(double),__FILE__,__LINE__,__PRETTY_FUNCTION__,m_sName); if (m_pData != NULL) { memcpy(temp,m_pData,m_iSize*sizeof(double)); delete[] m_pData; } m_pData = temp; m_iMaxSize = i; #ifdef DEBUG_CDOUBLEARRAY mprintf("done.\n"); #endif BXOUT; } void CxDoubleArray::SetGrow(unsigned long i) { BXIN; #ifdef DEBUG_CDOUBLEARRAY mprintf("@ CxDoubleArray::SetGrow(int): %d\n",i); #endif m_iGrow = i; BXOUT; } void CxDoubleArray::RemoveAll() { BXIN; #ifdef DEBUG_CDOUBLEARRAY mprintf("@ CxDoubleArray::RemoveAll():..."); #endif if (m_pData != NULL) delete[] m_pData; m_pData = NULL; m_iSize = 0; m_iMaxSize = 0; #ifdef DEBUG_CDOUBLEARRAY mprintf("done.\n"); #endif BXOUT; } void CxDoubleArray::RemoveAll_KeepSize() { BXIN; #ifdef DEBUG_CDOUBLEARRAY mprintf("@ CxDoubleArray::RemoveAll_KeepSize():..."); #endif m_iSize = 0; #ifdef DEBUG_CDOUBLEARRAY mprintf("done.\n"); #endif BXOUT; } void CxDoubleArray::RemoveAt(unsigned long pos, unsigned long count) { BXIN; double *temp; #ifdef DEBUG_CDOUBLEARRAY mprintf("@ CxDoubleArray::RemoveAt(int, int): %d, %d...",pos,count); #endif try { temp = new double[m_iSize-count]; } catch(...) { temp = NULL; } if (temp == NULL) NewException((double)(m_iSize-count)*sizeof(double),__FILE__,__LINE__,__PRETTY_FUNCTION__,m_sName); if (m_pData != NULL) { memcpy(temp,m_pData,pos*sizeof(double)); memcpy(&temp[pos],&m_pData[pos+count],(m_iSize-pos-count)*sizeof(double)); delete[] m_pData; } m_pData = temp; m_iSize-=count; m_iMaxSize = m_iSize; #ifdef DEBUG_CDOUBLEARRAY mprintf("done.\n"); #endif BXOUT; } void CxDoubleArray::InsertAt(double f, unsigned long pos) { BXIN; double *temp; #ifdef DEBUG_CDOUBLEARRAY mprintf("@ CxDoubleArray::InsertAt(double, int): %d..."); #endif try { temp = new double[m_iSize+1]; } catch(...) { temp = NULL; } if (temp == NULL) NewException((double)(m_iSize+1)*sizeof(double),__FILE__,__LINE__,__PRETTY_FUNCTION__,m_sName); if (m_pData != NULL) { memcpy(temp,m_pData,pos*sizeof(double)); memcpy(&temp[pos+1],&m_pData[pos],(m_iSize-pos)*sizeof(double)); delete[] m_pData; } temp[pos] = f; m_pData = temp; m_iSize++; m_iMaxSize = m_iSize; #ifdef DEBUG_CDOUBLEARRAY mprintf("done.\n"); #endif BXOUT; } void CxDoubleArray::CopyFrom(CxDoubleArray *d) { BXIN; #ifdef DEBUG_CDOUBLEARRAY mprintf("@ CxDoubleArray::CopyFrom(CxDoubleArray *d): %X...",d); #endif if (m_iMaxSize != d->m_iMaxSize) { m_iMaxSize = d->m_iMaxSize; if (m_pData != NULL) delete[] m_pData; try { m_pData = new double[d->m_iMaxSize]; } catch(...) { m_pData = NULL; } if (m_pData == NULL) NewException((double)d->m_iMaxSize*sizeof(double),__FILE__,__LINE__,__PRETTY_FUNCTION__,m_sName); } m_iSize = d->m_iSize; m_iGrow = d->m_iGrow; if (d->m_pData != NULL) memcpy(m_pData,d->m_pData,m_iSize*sizeof(double)); #ifdef DEBUG_CDOUBLEARRAY mprintf("done.\n"); #endif BXOUT; } void CxDoubleArray::SetName(const char *name) { UNUSED(name); #ifdef DEBUG_ARRAYS BXIN; #ifdef DEBUG_CDOUBLEARRAY mprintf("@ CxDoubleArray::SetName(const char *): \"%s\"...",name); #endif if (m_sName != NULL) delete[] m_sName; try { m_sName = new char[strlen(name)+1]; } catch(...) { m_sName = NULL; } if (m_sName == NULL) NewException((double)(strlen(name)+1)*sizeof(char),__FILE__,__LINE__,__PRETTY_FUNCTION__); strcpy(m_sName,name); #ifdef DEBUG_CDOUBLEARRAY mprintf("done.\n"); #endif BXOUT; #endif } travis-src-190101/src/xdoublearray.h0100777000000000000000000000656313412725656014330 0ustar00/***************************************************************************** TRAVIS - Trajectory Analyzer and Visualizer http://www.travis-analyzer.de/ Copyright (c) 2009-2019 Martin Brehm 2012-2019 Martin Thomas 2016-2019 Sascha Gehrke This file was written by Martin Brehm. --------------------------------------------------------------------------- This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . *****************************************************************************/ #ifndef XDOUBLEARRAY_H #define XDOUBLEARRAY_H // This must always be the first include directive #include "config.h" #include "tools.h" #include "xobject.h" #include "backtrace.h" class CxDoubleArray : public CxObject { public: CxDoubleArray(); explicit CxDoubleArray(const char *name); void SetName(const char *name); ~CxDoubleArray(); CxDoubleArray(const CxDoubleArray &o); void Add(double f); void SetAt(unsigned long pos, double f); void SetSize(unsigned long i); void SetMaxSize(unsigned long i); void SetGrow(unsigned long i); void RemoveAll(); void RemoveAll_KeepSize(); void RemoveAt(unsigned long pos, unsigned long count); void InsertAt(double f, unsigned long pos); void CopyFrom(CxDoubleArray *d); double &GetAt(unsigned long i) { BXIN; #ifdef DEBUG_CDOUBLEARRAY mprintf("@ CxDoubleArray::GetAt(int): %d...",i); #endif #ifdef DEBUG_ARRAYS if (i >= m_iSize) { if (m_sName != NULL) eprintf("CxDoubleArray \"%s\" Boundary Error (%lu/%lu).\n",m_sName,i,m_iSize); else eprintf("CxDoubleArray Boundary Error (%lu/%lu).\n",i,m_iSize); abort(); } #endif #ifdef DEBUG_CDOUBLEARRAY mprintf("done.\n"); #endif BXOUT; return m_pData[i]; } double & operator [] (unsigned long i) { #ifdef DEBUG_CDOUBLEARRAY mprintf("@ CxDoubleArray::operator [] (int): %d\n",i); #endif return GetAt(i); } double GetAt(unsigned long i) const { BXIN; #ifdef DEBUG_CDOUBLEARRAY mprintf("@ CxDoubleArray::GetAt(int): %d...",i); #endif #ifdef DEBUG_ARRAYS if (i >= m_iSize) { if (m_sName != NULL) eprintf("CxDoubleArray \"%s\" Boundary Error (%lu/%lu).\n",m_sName,i,m_iSize); else eprintf("CxDoubleArray Boundary Error (%lu/%lu).\n",i,m_iSize); abort(); } #endif #ifdef DEBUG_CDOUBLEARRAY mprintf("done.\n"); #endif BXOUT; return m_pData[i]; } double operator [] (unsigned long i) const { #ifdef DEBUG_CDOUBLEARRAY mprintf("@ CxDoubleArray::operator [] (int): %d\n",i); #endif return GetAt(i); } int GetSize() { #ifdef DEBUG_CDOUBLEARRAY mprintf("@ CxDoubleArray::GetSize(): %d\n",m_iSize); #endif return m_iSize; } private: double *m_pData; unsigned long m_iSize; unsigned long m_iMaxSize; unsigned long m_iGrow; #ifdef DEBUG_ARRAYS char *m_sName; #endif }; #endif travis-src-190101/src/xdvec3array.cpp0100777000000000000000000002474713412725622014412 0ustar00/***************************************************************************** TRAVIS - Trajectory Analyzer and Visualizer http://www.travis-analyzer.de/ Copyright (c) 2009-2019 Martin Brehm 2012-2019 Martin Thomas 2016-2019 Sascha Gehrke This file was written by Martin Brehm. --------------------------------------------------------------------------- This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . *****************************************************************************/ // This must always be the first include directive #include "config.h" #include "xdvec3array.h" const char *GetRevisionInfo_xdvec3array(unsigned int len) { static char buf[256]; GET_REVISION_INFO( buf, len ); return buf; } const char *GetSourceVersion_xdvec3array() { static char buf[256]; GET_SOURCE_VERSION( buf ); return buf; } #ifndef DEBUG_ARRAYS #define m_sName (NULL) #endif CxDVec3Array::CxDVec3Array() { BXIN; #ifdef DEBUG_CDVEC3ARRAY mprintf("@ CxDVec3Array::CxDVec3Array()\n"); #endif m_pData = NULL; m_iSize = 0; m_iMaxSize = 0; m_iGrow = 16; #ifdef DEBUG_ARRAYS m_sName = NULL; #endif BXOUT; } CxDVec3Array::CxDVec3Array(const char *name) { BXIN; #ifdef DEBUG_CDVEC3ARRAY mprintf("@ CxDVec3Array::CxDVec3Array()\n"); #endif m_pData = NULL; m_iSize = 0; m_iMaxSize = 0; m_iGrow = 16; #ifdef DEBUG_ARRAYS m_sName = NULL; #endif SetName(name); BXOUT; } CxDVec3Array::~CxDVec3Array() { BXIN; #ifdef DEBUG_CDVEC3ARRAY mprintf("@ CxDVec3Array::~CxDVec3Array()\n"); #endif RemoveAll(); #ifdef DEBUG_ARRAYS if (m_sName != NULL) { delete[] m_sName; m_sName = NULL; } #endif BXOUT; } CxDVec3Array::CxDVec3Array(const CxDVec3Array &o) : CxObject() { BXIN; #ifdef DEBUG_CDVEC3ARRAY mprintf("@ CxDVec3Array::CxDVec3Array(CxDVec3Array &)..."); #endif // unsigned long z; int z; m_iGrow = o.m_iGrow; // m_pData = new CxDVector3*[m_iMaxSize]; if ((o.m_iMaxSize != 0) && (o.m_pData != NULL)) { m_iSize = o.m_iSize; m_iMaxSize = o.m_iMaxSize; try { m_pData = new CxDVector3[m_iMaxSize]; } catch(...) { m_pData = NULL; } if (m_pData == NULL) NewException((double)m_iMaxSize*sizeof(CxDVector3),__FILE__,__LINE__,__PRETTY_FUNCTION__,m_sName); if (o.m_pData != NULL) { //memcpy(m_pData,o.m_pData,sizeof(CxDVector3)*m_iSize); for (z=0;z<(int)m_iSize;z++) m_pData[z] = CxDVector3(o.m_pData[z]); } } else { m_iSize = 0; m_iMaxSize = 0; m_pData = NULL; } #ifdef DEBUG_ARRAYS if (o.m_sName != NULL) SetName(o.m_sName); else m_sName = NULL; #endif #ifdef DEBUG_CDVEC3ARRAY mprintf("done.\n"); #endif BXOUT; } void CxDVec3Array::SetAt(unsigned long pos, CxDVector3 o) { BXIN; #ifdef DEBUG_CDVEC3ARRAY bool s = false; mprintf("@ CxDVec3Array::Add(CxDVector3)..."); #endif if (pos >= m_iMaxSize) { #ifdef DEBUG_CDVEC3ARRAY s = true; mprintf("\n"); #endif SetMaxSize(pos+1); } // *m_pData[pos] = *o; m_pData[pos] = o; if (pos >= m_iSize) m_iSize = pos+1; #ifdef DEBUG_CDVEC3ARRAY if (s) mprintf("@ done.\n"); else mprintf("done.\n"); #endif BXOUT; } void CxDVec3Array::Add(CxDVector3 o) { BXIN; #ifdef DEBUG_CDVEC3ARRAY bool s = false; mprintf("@ CxDVec3Array::Add(CxDVector3)..."); #endif if (m_iSize+1 > m_iMaxSize) { #ifdef DEBUG_CDVEC3ARRAY s = true; mprintf("\n"); #endif // SetMaxSize(m_iMaxSize + m_iGrow); if (m_iMaxSize == 0) SetMaxSize(m_iMaxSize + m_iGrow); else SetMaxSize(m_iMaxSize*2); } // *m_pData[m_iSize] = *o; m_pData[m_iSize] = o; m_iSize++; #ifdef DEBUG_CDVEC3ARRAY if (s) mprintf("@ done.\n"); else mprintf("done.\n"); #endif BXOUT; } void CxDVec3Array::SetSize(unsigned long i) { BXIN; int z; #ifdef DEBUG_CDVEC3ARRAY mprintf("@ CxDVec3Array::SetSize(int): %d...",i); #endif if (m_iSize == i) return; // CxDVector3 **temp; CxDVector3 *temp; if (i == m_iSize) { BXOUT; return; } // temp = new CxDVector3*[i]; try { temp = new CxDVector3[i]; } catch(...) { temp = NULL; } if (temp == NULL) NewException((double)i*sizeof(CxDVector3),__FILE__,__LINE__,__PRETTY_FUNCTION__,m_sName); if (m_pData != NULL) { if (i > m_iSize) { /* for (z=0;z<(int)m_iSize;z++) { temp[z] = new CxDVector3(*m_pData[z]); delete m_pData[z]; } for (z=m_iSize;z<(int)i;z++) temp[z] = new CxDVector3();*/ //memcpy(temp,m_pData,sizeof(CxDVector3)*m_iSize); for (z=0;z<(int)m_iSize;z++) temp[z] = CxDVector3(m_pData[z]); } else { /* for (z=0;z<(int)i;z++) { temp[z] = new CxDVector3(*m_pData[z]); delete m_pData[z]; } for (z=i;z<(int)m_iSize;z++) delete m_pData[z];*/ //memcpy(temp,m_pData,sizeof(CxDVector3)*i); for (z=0;z<(int)i;z++) temp[z] = CxDVector3(m_pData[z]); } delete[] m_pData; } m_pData = temp; m_iMaxSize = i; m_iSize = i; #ifdef DEBUG_CDVEC3ARRAY mprintf("done.\n"); #endif BXOUT; } void CxDVec3Array::SetMaxSize(unsigned long i) { BXIN; int z; #ifdef DEBUG_CDVEC3ARRAY mprintf("@ CxDVec3Array::SetMaxSize(int): %d...",i); #endif // CxDVector3 **temp; CxDVector3 *temp; if (i <= m_iSize) { eprintf("CxDVec3Array::SetMaxSize(%lu): Size %lu > %lu.\n",i,m_iSize,i); return; } // temp = new CxDVector3*[i]; try { temp = new CxDVector3[i]; } catch(...) { temp = NULL; } if (temp == NULL) NewException((double)i*sizeof(CxDVector3),__FILE__,__LINE__,__PRETTY_FUNCTION__,m_sName); /* for (z=0;z<(int)m_iSize;z++) { temp[z] = new CxDVector3(*m_pData[z]); delete m_pData[z]; } for (z=m_iSize;z<(int)i;z++) temp[z] = new CxDVector3();*/ if (m_pData != NULL) { //memcpy(temp,m_pData,sizeof(CxDVector3)*m_iSize); for (z=0;z<(int)m_iSize;z++) temp[z] = CxDVector3(m_pData[z]); delete[] m_pData; } m_pData = temp; m_iMaxSize = i; #ifdef DEBUG_CDVEC3ARRAY mprintf("done.\n"); #endif BXOUT; } void CxDVec3Array::SetGrow(unsigned long i) { BXIN; #ifdef DEBUG_CDVEC3ARRAY mprintf("@ CxDVec3Array::SetGrow(int): %d\n",i); #endif m_iGrow = i; BXOUT; } void CxDVec3Array::RemoveAll() { BXIN; // int z; #ifdef DEBUG_CDVEC3ARRAY mprintf("@ CxDVec3Array::RemoveAll():..."); #endif /* for (z=0;z<(int)m_iMaxSize;z++) delete m_pData[z];*/ if (m_pData != NULL) delete[] m_pData; m_pData = NULL; m_iSize = 0; m_iMaxSize = 0; #ifdef DEBUG_CDVEC3ARRAY mprintf("done.\n"); #endif BXOUT; } void CxDVec3Array::RemoveAll_KeepSize() { BXIN; #ifdef DEBUG_CDVEC3ARRAY mprintf("@ CxDVec3Array::RemoveAll_KeepSize():..."); #endif m_iSize = 0; #ifdef DEBUG_CDVEC3ARRAY mprintf("done.\n"); #endif BXOUT; } void CxDVec3Array::RemoveAt(unsigned long pos, unsigned long count) { BXIN; // CxDVector3 **temp; CxDVector3 *temp; int z; #ifdef DEBUG_CDVEC3ARRAY mprintf("@ CxDVec3Array::RemoveAt(int, int): %d, %d...",pos,count); #endif // temp = new CxDVector3*[m_iSize-count]; try { temp = new CxDVector3[m_iSize-count]; } catch(...) { temp = NULL; } if (temp == NULL) NewException((double)(m_iSize-count)*sizeof(CxDVector3),__FILE__,__LINE__,__PRETTY_FUNCTION__,m_sName); /* for (z=0;z<(int)pos;z++) { temp[z] = new CxDVector3(*m_pData[z]); delete m_pData[z]; } for (z=pos;z<(int)(m_iSize-count);z++) { temp[z] = new CxDVector3(*m_pData[z+count]); delete m_pData[z+count]; }*/ if (m_pData != NULL) { //memcpy(temp,m_pData,sizeof(CxDVector3)*pos); //memcpy(&temp[pos],&m_pData[pos+count],sizeof(CxDVector3)*(m_iSize-count-pos)); for (z=0;z<(int)pos;z++) temp[z] = CxDVector3(m_pData[z]); for (;z<(int)m_iSize-(int)count;z++) temp[z] = CxDVector3(m_pData[z+count]); delete[] m_pData; } m_pData = temp; m_iSize -= count; m_iMaxSize = m_iSize; #ifdef DEBUG_CDVEC3ARRAY mprintf("done.\n"); #endif BXOUT; } void CxDVec3Array::InsertAt(CxDVector3 o, unsigned long pos) { BXIN; int z; // CxDVector3 **temp; CxDVector3 *temp; #ifdef DEBUG_CDVEC3ARRAY mprintf("@ CxDVec3Array::InsertAt(CxDVector3, int): %d..."); #endif // temp = new CxDVector3*[m_iSize+1]; try { temp = new CxDVector3[m_iSize+1]; } catch(...) { temp = NULL; } if (temp == NULL) NewException((double)(m_iSize+1)*sizeof(CxDVector3),__FILE__,__LINE__,__PRETTY_FUNCTION__,m_sName); /* for (z=0;z<(int)pos;z++) { temp[z] = new CxDVector3(*m_pData[z]); delete m_pData[z]; } for (z=pos;z<(int)m_iSize;z++) { temp[z+1] = new CxDVector3(*m_pData[z]); delete m_pData[z]; }*/ if (m_pData != NULL) { //memcpy(temp,m_pData,sizeof(CxDVector3)*pos); //memcpy(&temp[pos+1],&m_pData[pos],sizeof(CxDVector3)*(m_iSize-pos)); for (z=0;z<(int)pos;z++) temp[z] = CxDVector3(m_pData[z]); for (;z<(int)m_iSize;z++) temp[z+1] = CxDVector3(m_pData[z]); delete[] m_pData; } // *temp[pos] = *o; temp[pos] = o; m_pData = temp; m_iSize++; m_iMaxSize = m_iSize; #ifdef DEBUG_CDVEC3ARRAY mprintf("done.\n"); #endif BXOUT; } void CxDVec3Array::CopyFrom(CxDVec3Array *a) { BXIN; #ifdef DEBUG_CDVEC3ARRAY mprintf("@ CxDVec3Array::CopyFrom(CxDVec3Array*)..."); #endif unsigned long z; if (m_iMaxSize != a->m_iMaxSize) { if (m_pData != NULL) { /* for (z=0;zm_iMaxSize; // m_pData = new CxDVector3*[m_iMaxSize]; try { m_pData = new CxDVector3[m_iMaxSize]; } catch(...) { m_pData = NULL; } if (m_pData == NULL) NewException((double)m_iMaxSize*sizeof(CxDVector3),__FILE__,__LINE__,__PRETTY_FUNCTION__,m_sName); /* for (z=0;zm_iSize; m_iGrow = a->m_iGrow; for (z=0;zm_pData[z]; // *m_pData[z] = *a->m_pData[z]; #ifdef DEBUG_CDVEC3ARRAY mprintf("done.\n"); #endif BXOUT; } void CxDVec3Array::SetName(const char *name) { UNUSED(name); #ifdef DEBUG_ARRAYS BXIN; #ifdef DEBUG_CDVEC3ARRAY mprintf("@ CxDVec3Array::SetName(const char *s): \"%s\"...",name); #endif if (m_sName != NULL) delete[] m_sName; try { m_sName = new char[strlen(name)+1]; } catch(...) { m_sName = NULL; } if (m_sName == NULL) NewException((double)(strlen(name)+1)*sizeof(char),__FILE__,__LINE__,__PRETTY_FUNCTION__); strcpy(m_sName,name); #ifdef DEBUG_CDVEC3ARRAY mprintf("done.\n"); #endif BXOUT; #endif } travis-src-190101/src/xdvec3array.h0100777000000000000000000000674113412725665014060 0ustar00/***************************************************************************** TRAVIS - Trajectory Analyzer and Visualizer http://www.travis-analyzer.de/ Copyright (c) 2009-2019 Martin Brehm 2012-2019 Martin Thomas 2016-2019 Sascha Gehrke This file was written by Martin Brehm. --------------------------------------------------------------------------- This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . *****************************************************************************/ #ifndef XDVEC3ARRAY_H #define XDVEC3ARRAY_H // This must always be the first include directive #include "config.h" #include "tools.h" #include "xobject.h" #include "xdvector3.h" #include "backtrace.h" class CxDVec3Array : public CxObject { public: CxDVec3Array(); ~CxDVec3Array(); CxDVec3Array(const CxDVec3Array &o); explicit CxDVec3Array(const char *name); void SetName(const char *name); void Add(CxDVector3 o); void SetAt(unsigned long pos, CxDVector3 o); void CopyFrom(CxDVec3Array *a); CxDVector3 &GetAt(unsigned long i) { BXIN; #ifdef DEBUG_CDVEC3ARRAY mprintf("@ CxDVec3Array::GetAt(int): %d...",i); #endif #ifdef DEBUG_ARRAYS if (i >= m_iSize) { if (m_sName != NULL) eprintf("CxDVec3Array \"%s\" Boundary Error (%lu/%lu).\n",m_sName,i,m_iSize); else eprintf("CxDVec3Array Boundary Error (%lu/%lu).\n",i,m_iSize); abort(); } #endif #ifdef DEBUG_CDVEC3ARRAY mprintf("done.\n"); #endif BXOUT; // return *m_pData[i]; return m_pData[i]; } CxDVector3 &operator [] (unsigned long i) { #ifdef DEBUG_CDVEC3ARRAY mprintf("@ CxDVec3Array::operator [] (int): %d\n",i); #endif return GetAt(i); } CxDVector3 GetAt(unsigned long i) const { BXIN; #ifdef DEBUG_CDVEC3ARRAY mprintf("@ CxDVec3Array::GetAt(int): %d...",i); #endif #ifdef DEBUG_ARRAYS if (i >= m_iSize) { if (m_sName != NULL) eprintf("CxDVec3Array \"%s\" Boundary Error (%lu/%lu).\n",m_sName,i,m_iSize); else eprintf("CxDVec3Array Boundary Error (%lu/%lu).\n",i,m_iSize); abort(); } #endif #ifdef DEBUG_CDVEC3ARRAY mprintf("done.\n"); #endif BXOUT; // return *m_pData[i]; return m_pData[i]; } CxDVector3 operator [] (unsigned long i) const { #ifdef DEBUG_CDVEC3ARRAY mprintf("@ CxDVec3Array::operator [] (int): %d\n",i); #endif return GetAt(i); } int GetSize() const { #ifdef DEBUG_CDVEC3ARRAY mprintf("@ CxDVec3Array::GetSize(): %d\n",m_iSize); #endif return m_iSize; } void SetSize(unsigned long i); void SetMaxSize(unsigned long i); void SetGrow(unsigned long i); void RemoveAll(); void RemoveAll_KeepSize(); void RemoveAt(unsigned long pos, unsigned long count); void InsertAt(CxDVector3 o, unsigned long pos); private: // CxDVector3 **m_pData; CxDVector3 *m_pData; unsigned long m_iSize; unsigned long m_iMaxSize; unsigned long m_iGrow; #ifdef DEBUG_ARRAYS char *m_sName; #endif }; #endif travis-src-190101/src/xdvector3.cpp0100777000000000000000000001073313412725633014070 0ustar00/***************************************************************************** TRAVIS - Trajectory Analyzer and Visualizer http://www.travis-analyzer.de/ Copyright (c) 2009-2019 Martin Brehm 2012-2019 Martin Thomas 2016-2019 Sascha Gehrke This file was written by Martin Brehm. --------------------------------------------------------------------------- This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . *****************************************************************************/ // This must always be the first include directive #include "config.h" #include "xdvector3.h" #include "tools.h" const char *GetRevisionInfo_xdvector3(unsigned int len) { static char buf[256]; GET_REVISION_INFO( buf, len ); return buf; } const char *GetSourceVersion_xdvector3() { static char buf[256]; GET_SOURCE_VERSION( buf ); return buf; } /* CxDVector3::CxDVector3(const CxDVector3 &v) { BXIN; m_pData[0] = v.GetAt(0); m_pData[1] = v.GetAt(1); m_pData[2] = v.GetAt(2); BXOUT; } */ void CxDVector3::Dump() const { BXIN; /* int z; for (z=0;z<3;z++) if ((m_pData[z] < 0) && (m_pData[z] > -0.000000001)) m_pData[z] = 0;*/ mprintf("( %6.3f | %6.3f | %6.3f ) {%.2f}",m_pData[0],m_pData[1],m_pData[2],GetLength()); BXOUT; } void CxDVector3::PointRoot(const CxDVector3 &vec1, const CxDVector3 &vec2, const CxDVector3 &point) { BXIN; double a, b; CxDVector3 vn; vn = CrossP(vec1,vec2); #define ax vec1[0] #define ay vec1[1] #define az vec1[2] #define bx vec2[0] #define by vec2[1] #define bz vec2[2] #define nx vn[0] #define ny vn[1] #define nz vn[2] #define px point[0] #define py point[1] #define pz point[2] a = -((bz*ny*px - by*nz*px - bz*nx*py + bx*nz*py + by*nx*pz - bx*ny*pz)/(-az*by*nx + ay*bz*nx + az*bx*ny - ax*bz*ny - ay*bx*nz + ax*by*nz)); b = -((az*ny*px - ay*nz*px - az*nx*py + ax*nz*py + ay*nx*pz - ax*ny*pz)/( az*by*nx - ay*bz*nx - az*bx*ny + ax*bz*ny + ay*bx*nz - ax*by*nz)); /* vec1 *= a; vec2 *= b; vecadd(vec1,vec2,baseout);*/ *this = vec1*a + vec2*b; BXOUT; } double Dihedral(const CxDVector3 &vec1, const CxDVector3 &vec2, const CxDVector3 &norm, bool absolute) { BXIN; CxDVector3 p1, p2; CxDVector3 t1, t2; double f; p1 = CrossP(norm,vec1); p2 = CrossP(norm,p1); if ((p1.GetLength() == 0) || (p2.GetLength() == 0)) { eprintf("Error in Dihedral.\n"); return -1.0; } t1.PointRoot(p1,p2,vec1); t2.PointRoot(p1,p2,vec2); f = Angle_Deg(t1,t2); if (!absolute) { if (fabs(Angle_Deg(p1,t2)) > 90.0) f = -f; } BXOUT; return f; } CxDVector3 PointFromRAD(CxDVector3 r1, CxDVector3 r2, CxDVector3 r3, double r, double a, double d) { CxDVector3 res, d1, d2, d3; d1 = r2 - r1; // mprintf("d1 = "); d1.Dump(); mprintf("\n"); d2 = r3 - r2; // mprintf("d2 = "); d2.Dump(); mprintf("\n"); d3 = CrossP(d1,d2); // mprintf("d3 = "); d3.Dump(); mprintf("\n"); d1.Normalize(); // mprintf("d1n = "); d1.Dump(); mprintf("\n"); d2 = d2 - DotP(d2,d1)*d1; d2.Normalize(); // mprintf("d2n = "); d2.Dump(); mprintf("\n"); d3.Normalize(); // mprintf("d3n = "); d3.Dump(); mprintf("\n"); res = r1 + r * ( cos(a) * d1 + (sin(a) * cos(d)) * d2 + (sin(a) * sin(d)) * d3); // mprintf("res = "); res.Dump(); mprintf("\n"); return res; } void PointRootCoefficients(const CxDVector3 &vec1, const CxDVector3 &vec2, const CxDVector3 &point, double &a, double &b) { CxDVector3 vn; vn = CrossP(vec1,vec2); #define ax vec1[0] #define ay vec1[1] #define az vec1[2] #define bx vec2[0] #define by vec2[1] #define bz vec2[2] #define nx vn[0] #define ny vn[1] #define nz vn[2] #define px point[0] #define py point[1] #define pz point[2] a = -((bz*ny*px - by*nz*px - bz*nx*py + bx*nz*py + by*nx*pz - bx*ny*pz)/(-az*by*nx + ay*bz*nx + az*bx*ny - ax*bz*ny - ay*bx*nz + ax*by*nz)); b = -((az*ny*px - ay*nz*px - az*nx*py + ax*nz*py + ay*nx*pz - ax*ny*pz)/( az*by*nx - ay*bz*nx - az*bx*ny + ax*bz*ny + ay*bx*nz - ax*by*nz)); } travis-src-190101/src/xdvector3.h0100777000000000000000000001607713412725652013545 0ustar00/***************************************************************************** TRAVIS - Trajectory Analyzer and Visualizer http://www.travis-analyzer.de/ Copyright (c) 2009-2019 Martin Brehm 2012-2019 Martin Thomas 2016-2019 Sascha Gehrke This file was written by Martin Brehm. --------------------------------------------------------------------------- This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . *****************************************************************************/ #ifndef CXDVECTOR3_DEFINED #define CXDVECTOR3_DEFINED // This must always be the first include directive #include "config.h" #include "tools.h" #include "xobject.h" #include "backtrace.h" class CxDVector3 : public CxObject { public: CxDVector3() { } ~CxDVector3() { } CxDVector3(const CxDVector3 &v) : CxObject() { BXIN; m_pData[0] = v.m_pData[0]; m_pData[1] = v.m_pData[1]; m_pData[2] = v.m_pData[2]; BXOUT; } // CxDVector3(const CxVector3 &v); explicit CxDVector3(double f) { BXIN; m_pData[0] = f; m_pData[1] = f; m_pData[2] = f; BXOUT; } CxDVector3(double x, double y, double z) { BXIN; m_pData[0] = x; m_pData[1] = y; m_pData[2] = z; BXOUT; } double &GetAt(int i) { #ifdef DEBUG_CDVECTOR3 mprintf("@ CxDVector3::GetAt(int): %d...",i); #endif return m_pData[i]; } double &operator [] (int i) { #ifdef DEBUG_CDVECTOR3 mprintf("@ CxDVector3::operator [] (int): %d\n",i); #endif return GetAt(i); } double GetAt(int i) const { #ifdef DEBUG_CDVECTOR3 mprintf("@ CxDVector3::GetAt(int): %d...",i); #endif #ifdef DEBUG_ARRAYS if (i > 2) { mprintf("CxDVector3::GetAt(int): Boundary Error (%d/3)...",i); abort(); } #endif return m_pData[i]; } double operator [] (int i) const { #ifdef DEBUG_CDVECTOR3 mprintf("@ CxDVector3::operator [] (int): %d\n",i); #endif return GetAt(i); } CxDVector3 operator + (const CxDVector3 &v) const { #ifdef DEBUG_CDVECTOR3 mprintf("@ CxDVector3::operator + (CxDVector3&)\n"); #endif return CxDVector3(m_pData[0]+v.m_pData[0],m_pData[1]+v.m_pData[1],m_pData[2]+v.m_pData[2]); } CxDVector3 operator - (const CxDVector3 &v) const { #ifdef DEBUG_CDVECTOR3 mprintf("@ CxDVector3::operator - (CxDVector3&)\n"); #endif return CxDVector3(m_pData[0]-v.m_pData[0],m_pData[1]-v.m_pData[1],m_pData[2]-v.m_pData[2]); } CxDVector3 operator * (double f) const { #ifdef DEBUG_CDVECTOR3 mprintf("@ CxDVector3::operator * (double)\n"); #endif return CxDVector3(m_pData[0]*f,m_pData[1]*f,m_pData[2]*f); } CxDVector3 operator / (double f) const { #ifdef DEBUG_CDVECTOR3 mprintf("@ CxDVector3::operator / (double)\n"); #endif return CxDVector3(m_pData[0]/f,m_pData[1]/f,m_pData[2]/f); } void operator += (const CxDVector3 &v) { BXIN; #ifdef DEBUG_CDVECTOR3 mprintf("@ CxDVector3::operator += (CxDVector3&)\n"); #endif m_pData[0] += v.m_pData[0]; m_pData[1] += v.m_pData[1]; m_pData[2] += v.m_pData[2]; BXOUT; } void operator -= (const CxDVector3 &v) { BXIN; #ifdef DEBUG_CDVECTOR3 mprintf("@ CxDVector3::operator -= (CxDVector3&)\n"); #endif m_pData[0] -= v.m_pData[0]; m_pData[1] -= v.m_pData[1]; m_pData[2] -= v.m_pData[2]; BXOUT; } void operator *= (double f) { BXIN; #ifdef DEBUG_CDVECTOR3 mprintf("@ CxDVector3::operator *= (double)\n"); #endif m_pData[0] *= f; m_pData[1] *= f; m_pData[2] *= f; BXOUT; } void operator /= (double f) { BXIN; #ifdef DEBUG_CDVECTOR3 mprintf("@ CxDVector3::operator /= (double)\n"); #endif m_pData[0] /= f; m_pData[1] /= f; m_pData[2] /= f; BXOUT; } double GetLength() const { return sqrt(m_pData[0]*m_pData[0]+m_pData[1]*m_pData[1]+m_pData[2]*m_pData[2]); } double GetLengthSqr() const { return m_pData[0]*m_pData[0]+m_pData[1]*m_pData[1]+m_pData[2]*m_pData[2]; } void Normalize() { BXIN; double l; l = GetLength(); m_pData[0] /= l; m_pData[1] /= l; m_pData[2] /= l; BXOUT; } void Chop(double d) { if ((m_pData[0] != 0) && (fabs(m_pData[0]) < d)) m_pData[0] = 0; if ((m_pData[1] != 0) && (fabs(m_pData[1]) < d)) m_pData[1] = 0; if ((m_pData[2] != 0) && (fabs(m_pData[2]) < d)) m_pData[2] = 0; } void PointRoot(const CxDVector3 &vec1, const CxDVector3 &vec2, const CxDVector3 &point); void Dump() const; private: double m_pData[3]; }; double Dihedral(const CxDVector3 &vec1, const CxDVector3 &vec2, const CxDVector3 &norm, bool absolute); inline void Swap(CxDVector3 &vec1, CxDVector3 &vec2) { BXIN; CxDVector3 t; t = vec1; vec1 = vec2; vec2 = t; BXOUT; } inline CxDVector3 operator * (double f, const CxDVector3 &v) { return v*f; } inline CxDVector3 CrossP(const CxDVector3 &vec1, const CxDVector3 &vec2) { return CxDVector3(vec1[1]*vec2[2] - vec1[2]*vec2[1], vec1[2]*vec2[0] - vec1[0]*vec2[2], vec1[0]*vec2[1] - vec1[1]*vec2[0]); } inline double DotP(const CxDVector3 &vec1, const CxDVector3 &vec2) { return vec1[0]*vec2[0]+vec1[1]*vec2[1]+vec1[2]*vec2[2]; } inline double Angle(const CxDVector3 &vec1, const CxDVector3 &vec2) { BXIN; double t; if ((vec1.GetLength() == 0) || (vec2.GetLength() == 0)) { mprintf("\nAngle(): Warning: Indeterminate angle between ( %f | %f | %f ) and ( %f | %f | %f ). ",vec1[0],vec1[1],vec1[2],vec2[0],vec2[1],vec2[2]); return 0; } t = DotP(vec1,vec2) / vec1.GetLength() / vec2.GetLength(); if (t > 1.0) t = 1.0; if (t < -1.0) t = -1.0; BXOUT; return acos(t); } inline double Angle_Deg(const CxDVector3 &vec1, const CxDVector3 &vec2) { BXIN; double t; if ((vec1.GetLength() == 0) || (vec2.GetLength() == 0)) { mprintf("\nAngle_Deg(): Warning: Indeterminate angle between ( %f | %f | %f ) and ( %f | %f | %f ). ",vec1[0],vec1[1],vec1[2],vec2[0],vec2[1],vec2[2]); return 0; } t = DotP(vec1,vec2) / vec1.GetLength() / vec2.GetLength(); if (t > 1.0) t = 1.0; if (t < -1.0) t = -1.0; t = acos(t); BXOUT; return fabs(t*180.0 / Pi); } inline double VecDist(const CxDVector3 &vec1, const CxDVector3 &vec2) { return sqrt((vec1[0]-vec2[0])*(vec1[0]-vec2[0]) + (vec1[1]-vec2[1])*(vec1[1]-vec2[1]) + (vec1[2]-vec2[2])*(vec1[2]-vec2[2])); } inline CxDVector3 Normalize(const CxDVector3 &vec) { double tf; tf = vec.GetLength(); return CxDVector3(vec[0]/tf,vec[1]/tf,vec[2]/tf); } CxDVector3 PointFromRAD(CxDVector3 r1, CxDVector3 r2, CxDVector3 r3, double r, double a, double d); void PointRootCoefficients(const CxDVector3 &vec1, const CxDVector3 &vec2, const CxDVector3 &point, double &a, double &b); #endif travis-src-190101/src/xdvectorn.cpp0100777000000000000000000000320413412725617014160 0ustar00/***************************************************************************** TRAVIS - Trajectory Analyzer and Visualizer http://www.travis-analyzer.de/ Copyright (c) 2009-2019 Martin Brehm 2012-2019 Martin Thomas 2016-2019 Sascha Gehrke This file was written by Martin Brehm. --------------------------------------------------------------------------- This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . *****************************************************************************/ // This must always be the first include directive #include "config.h" #include "xdvectorn.h" #include "tools.h" const char *GetRevisionInfo_xdvectorn(unsigned int len) { static char buf[256]; GET_REVISION_INFO( buf, len ); return buf; } const char *GetSourceVersion_xdvectorn() { static char buf[256]; GET_SOURCE_VERSION( buf ); return buf; } void CxDVectorN::Dump() const { int z; mprintf("( %7G",m_pData[0]); for (z=1;z. *****************************************************************************/ #ifndef CXDVECTORN_DEFINED #define CXDVECTORN_DEFINED // This must always be the first include directive #include "config.h" #include "tools.h" #include "xobject.h" #include "backtrace.h" class CxDVectorN : public CxObject { public: CxDVectorN() { m_iDim = 0; m_pData = NULL; } ~CxDVectorN() { if (m_pData != NULL) { delete[] m_pData; m_pData = NULL; } } CxDVectorN(const CxDVectorN &v) : CxObject() { m_iDim = v.m_iDim; m_pData = new double[m_iDim]; memcpy(m_pData,v.m_pData,sizeof(double)*m_iDim); } CxDVectorN & operator = (const CxDVectorN &v) { #ifdef DEBUG_CDVECTORN mprintf("@ CxDVectorN::operator = (const CxDVectorN &)\n"); #endif if (m_pData != NULL) delete[] m_pData; m_iDim = v.m_iDim; m_pData = new double[m_iDim]; memcpy(m_pData,v.m_pData,sizeof(double)*m_iDim); return *this; } CxDVectorN(int i, double f) { int z; m_iDim = i; m_pData = new double[m_iDim]; for (z=0;z= m_iDim) { eprintf("& CxDVectorN::GetAt(int): Boundary Error (%d/%d).\n",i,m_iDim); abort(); } #endif return m_pData[i]; } double &operator [] (int i) { #ifdef DEBUG_CDVECTORN mprintf("@ CxDVectorN::operator [] (int): %d\n",i); #endif #ifdef DEBUG_ARRAYS if ((i < 0) || (i >= m_iDim)) { eprintf("& CxDVectorN::operator [] (int): Boundary Error (%d/%d).\n",i,m_iDim); abort(); } #endif return m_pData[i]; } double GetAt(int i) const { #ifdef DEBUG_CDVECTORN mprintf("@ CxDVectorN::GetAt(int): %d...",i); #endif #ifdef DEBUG_ARRAYS if (i >= m_iDim) { eprintf("CxDVectorN::GetAt(int): Boundary Error (%d/%d).\n",i,m_iDim); abort(); } #endif return m_pData[i]; } double operator [] (int i) const { #ifdef DEBUG_CDVECTORN mprintf("@ CxDVectorN::operator [] (int): %d\n",i); #endif #ifdef DEBUG_ARRAYS if ((i < 0) || (i >= m_iDim)) { eprintf("CxDVectorN::operator [] (int): Boundary Error (%d/%d).\n",i,m_iDim); abort(); } #endif return m_pData[i]; } CxDVectorN operator + (const CxDVectorN &v) const { #ifdef DEBUG_CDVECTORN mprintf("@ CxDVectorN::operator + (CxDVectorN&)\n"); #endif if (m_iDim != v.m_iDim) { eprintf("CxDVectorN::operator + (CxDVectorN&): Dimension mismatch (%d vs %d).\n",m_iDim,v.m_iDim); abort(); } CxDVectorN r(m_iDim); int z; for (z=0;z 1.0) t = 1.0; if (t < -1.0) t = -1.0; BXOUT; return acos(t); } inline double Angle_Deg(const CxDVectorN &vec1, const CxDVectorN &vec2) { BXIN; double t; t = DotP(vec1,vec2) / vec1.GetLength() / vec2.GetLength(); if (t > 1.0) t = 1.0; if (t < -1.0) t = -1.0; t = acos(t); BXOUT; return fabs(t*180.0 / Pi); } inline double VecDist(const CxDVectorN &vec1, const CxDVectorN &vec2) { return (vec1-vec2).GetLength(); } #endif travis-src-190101/src/xintarray.cpp0100777000000000000000000002246413412725631014172 0ustar00/***************************************************************************** TRAVIS - Trajectory Analyzer and Visualizer http://www.travis-analyzer.de/ Copyright (c) 2009-2019 Martin Brehm 2012-2019 Martin Thomas 2016-2019 Sascha Gehrke This file was written by Martin Brehm. --------------------------------------------------------------------------- This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . *****************************************************************************/ // This must always be the first include directive #include "config.h" #include "xintarray.h" const char *GetRevisionInfo_xintarray(unsigned int len) { static char buf[256]; GET_REVISION_INFO( buf, len ); return buf; } const char *GetSourceVersion_xintarray() { static char buf[256]; GET_SOURCE_VERSION( buf ); return buf; } #ifndef DEBUG_ARRAYS #define m_sName (NULL) #endif CxIntArray::CxIntArray() { BXIN; #ifdef DEBUG_CINTARRAY mprintf("@ CxIntArray::CxIntArray()\n"); #endif m_pData = NULL; m_iSize = 0; m_iMaxSize = 0; m_iGrow = 16; #ifdef DEBUG_ARRAYS m_sName = NULL; #endif BXOUT; } CxIntArray::CxIntArray(const char *name) { BXIN; #ifdef DEBUG_CINTARRAY mprintf("@ CxIntArray::CxIntArray(const char *)\n"); #endif m_pData = NULL; m_iSize = 0; m_iMaxSize = 0; m_iGrow = 16; #ifdef DEBUG_ARRAYS m_sName = NULL; #endif SetName(name); BXOUT; } CxIntArray::~CxIntArray() { BXIN; #ifdef DEBUG_CINTARRAY mprintf("@ CxIntArray::~CxIntArray()\n"); #endif RemoveAll(); #ifdef DEBUG_ARRAYS if (m_sName != NULL) { delete[] m_sName; m_sName = NULL; } #endif BXOUT; } CxIntArray::CxIntArray(const CxIntArray &o) : CxObject() { BXIN; #ifdef DEBUG_CINTARRAY mprintf("@ CxIntArray::CxIntArray(CxIntArray &)..."); #endif unsigned int z; m_iGrow = o.m_iGrow; if ((o.m_iMaxSize != 0) && (o.m_pData != NULL)) { m_iSize = o.m_iSize; m_iMaxSize = o.m_iMaxSize; try { m_pData = new int[m_iMaxSize]; } catch(...) { m_pData = NULL; } if (m_pData == NULL) NewException((double)m_iMaxSize*sizeof(int),__FILE__,__LINE__,__PRETTY_FUNCTION__,m_sName); for (z=0;zm_iSize; m_iMaxSize = o->m_iMaxSize; m_iGrow = o->m_iGrow; if (m_pData != NULL) delete[] m_pData; try { m_pData = new int[m_iMaxSize]; } catch(...) { m_pData = NULL; } if (m_pData == NULL) NewException((double)m_iMaxSize*sizeof(int),__FILE__,__LINE__,__PRETTY_FUNCTION__,m_sName); if (o->m_pData != NULL) memcpy(m_pData,o->m_pData,m_iSize*sizeof(int)); #ifdef DEBUG_CINTARRAY mprintf("done.\n"); #endif BXOUT; } void CxIntArray::Append(CxIntArray *o) { BXIN; #ifdef DEBUG_CINTARRAY mprintf("@ CxIntArray::Append(CxIntArray*)..."); #endif // unsigned int z; if (m_iSize+o->m_iSize > m_iMaxSize) SetMaxSize(m_iSize+o->m_iSize); // for (z=0;zm_iSize;z++) // m_pData[m_iSize+z] = o->m_pData[z]; if (o->m_pData != NULL) memcpy(&m_pData[m_iSize],o->m_pData,o->m_iSize*sizeof(int)); m_iSize += o->m_iSize; #ifdef DEBUG_CINTARRAY mprintf("done.\n"); #endif BXOUT; } void CxIntArray::SetAt(unsigned int pos, int f) { BXIN; // unsigned int z; #ifdef DEBUG_CINTARRAY bool s = false; mprintf("@ CxIntArray::Add(long)..."); #endif if (pos >= m_iMaxSize) { #ifdef DEBUG_CINTARRAY s = true; mprintf("\n"); #endif SetMaxSize(pos+1); } m_pData[pos] = f; if (pos >= m_iSize) // { // for (z=m_iSize;z m_iMaxSize) { #ifdef DEBUG_CINTARRAY s = true; mprintf("\n"); #endif // mprintf("Grow A.\n"); // SetMaxSize(m_iMaxSize + m_iGrow); if (m_iMaxSize == 0) SetMaxSize(m_iMaxSize + m_iGrow); else SetMaxSize(m_iMaxSize*2); // mprintf("Grow B.\n"); } // mprintf("B %X data=%X size=%d\n",this,m_pData,m_iSize); m_pData[m_iSize] = f; // mprintf("C %X\n",this); m_iSize++; #ifdef DEBUG_CINTARRAY if (s) mprintf("@ done.\n"); else mprintf("done.\n"); #endif // mprintf("Add Done %X.\n",this); BXOUT; } void CxIntArray::SetSize(unsigned int i) { BXIN; #ifdef DEBUG_CINTARRAY mprintf("@ CxIntArray::SetSize(int): %d...",i); #endif if (m_iSize == i) return; int *temp; try { temp = new int[i]; } catch(...) { temp = NULL; } if (temp == NULL) NewException((double)i*sizeof(int),__FILE__,__LINE__,__PRETTY_FUNCTION__,m_sName); if (m_pData != NULL) { if (m_iSize > i) memcpy(temp,m_pData,i*sizeof(int)); else memcpy(temp,m_pData,m_iSize*sizeof(int)); delete[] m_pData; } m_pData = temp; m_iMaxSize = i; m_iSize = i; #ifdef DEBUG_CINTARRAY mprintf("done.\n"); #endif BXOUT; } void CxIntArray::SetMaxSize(unsigned int i) { BXIN; #ifdef DEBUG_CINTARRAY mprintf("@ CxIntArray::SetMaxSize(int): %d...",i); #endif int *temp; try { temp = new int[i]; } catch(...) { temp = NULL; } if (temp == NULL) NewException((double)i*sizeof(int),__FILE__,__LINE__,__PRETTY_FUNCTION__,m_sName); if (m_pData != NULL) { memcpy(temp,m_pData,m_iSize*sizeof(int)); delete[] m_pData; } m_pData = temp; m_iMaxSize = i; #ifdef DEBUG_CINTARRAY mprintf("done.\n"); #endif BXOUT; } void CxIntArray::SetGrow(unsigned int i) { BXIN; #ifdef DEBUG_CINTARRAY mprintf("@ CxIntArray::SetGrow(int): %d\n",i); #endif m_iGrow = i; BXOUT; } void CxIntArray::RemoveAll() { BXIN; #ifdef DEBUG_CINTARRAY mprintf("@ CxIntArray::RemoveAll():..."); #endif if (m_pData != NULL) delete[] m_pData; m_pData = NULL; m_iSize = 0; m_iMaxSize = 0; #ifdef DEBUG_CINTARRAY mprintf("done.\n"); #endif BXOUT; } void CxIntArray::RemoveAll_KeepSize() { BXIN; #ifdef DEBUG_CINTARRAY mprintf("@ CxIntArray::RemoveAll_KeepSize():..."); #endif m_iSize = 0; #ifdef DEBUG_CINTARRAY mprintf("done.\n"); #endif BXOUT; } void CxIntArray::RemoveAt(unsigned int pos, unsigned int count) { BXIN; int *temp; #ifdef DEBUG_CINTARRAY mprintf("@ CxIntArray::RemoveAt(int, int): %d, %d...",pos,count); #endif try { temp = new int[m_iSize-count]; } catch(...) { temp = NULL; } if (temp == NULL) NewException((double)(m_iSize-count)*sizeof(int),__FILE__,__LINE__,__PRETTY_FUNCTION__,m_sName); if (m_pData != NULL) { memcpy(temp,m_pData,pos*sizeof(int)); memcpy(&temp[pos],&m_pData[pos+count],(m_iSize-pos-count)*sizeof(int)); delete[] m_pData; } m_pData = temp; m_iSize-=count; m_iMaxSize = m_iSize; #ifdef DEBUG_CINTARRAY mprintf("done.\n"); #endif BXOUT; } void CxIntArray::RemoveAt_KeepSize(unsigned int pos, unsigned int count) { BXIN; int *temp; #ifdef DEBUG_CINTARRAY mprintf("@ CxIntArray::RemoveAt_KeepSize(int, int): %d, %d...",pos,count); #endif try { temp = new int[m_iMaxSize]; } catch(...) { temp = NULL; } if (temp == NULL) NewException((double)m_iMaxSize*sizeof(int),__FILE__,__LINE__,__PRETTY_FUNCTION__,m_sName); if (m_pData != NULL) { memcpy(temp,m_pData,pos*sizeof(int)); memcpy(&temp[pos],&m_pData[pos+count],(m_iSize-pos-count)*sizeof(int)); delete[] m_pData; } m_pData = temp; m_iSize-=count; #ifdef DEBUG_CINTARRAY mprintf("done.\n"); #endif BXOUT; } int CxIntArray::Pop_KeepSize() { if (m_iSize > 0) { m_iSize--; return m_pData[m_iSize]; } else return 0; } void CxIntArray::InsertAt(int f, unsigned int pos) { BXIN; int *temp; #ifdef DEBUG_CINTARRAY mprintf("@ CxIntArray::InsertAt(long, int): %d..."); #endif try { temp = new int[m_iSize+1]; } catch(...) { temp = NULL; } if (temp == NULL) NewException((double)(m_iSize+1)*sizeof(int),__FILE__,__LINE__,__PRETTY_FUNCTION__,m_sName); if (m_pData != NULL) { memcpy(temp,m_pData,pos*sizeof(int)); memcpy(&temp[pos+1],&m_pData[pos],(m_iSize-pos)*sizeof(int)); delete[] m_pData; } temp[pos] = f; m_pData = temp; m_iSize++; m_iMaxSize = m_iSize; #ifdef DEBUG_CINTARRAY mprintf("done.\n"); #endif BXOUT; } void CxIntArray::SetName(const char *name) { UNUSED(name); #ifdef DEBUG_ARRAYS BXIN; #ifdef DEBUG_CINTARRAY mprintf("@ CxIntArray::SetName(const char *): \"%s\"...",name); #endif if (m_sName != NULL) delete[] m_sName; try { m_sName = new char[strlen(name)+1]; } catch(...) { m_sName = NULL; } if (m_sName == NULL) NewException((double)(strlen(name)+1)*sizeof(char),__FILE__,__LINE__,__PRETTY_FUNCTION__); strcpy(m_sName,name); #ifdef DEBUG_CINTARRAY mprintf("done.\n"); #endif BXOUT; #endif } travis-src-190101/src/xintarray.h0100777000000000000000000000767413412725662013651 0ustar00/***************************************************************************** TRAVIS - Trajectory Analyzer and Visualizer http://www.travis-analyzer.de/ Copyright (c) 2009-2019 Martin Brehm 2012-2019 Martin Thomas 2016-2019 Sascha Gehrke This file was written by Martin Brehm. --------------------------------------------------------------------------- This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . *****************************************************************************/ #ifndef XINTARRAY_H #define XINTARRAY_H // This must always be the first include directive #include "config.h" #include "tools.h" #include "xobject.h" #include "backtrace.h" class CxIntArray : public CxObject { public: CxIntArray(); ~CxIntArray(); explicit CxIntArray(const char *name); void SetName(const char *name); CxIntArray(const CxIntArray &o); void CopyFrom(CxIntArray *o); void Add(int f); void Append(CxIntArray *o); void SetAt(unsigned int pos, int f); void SetSize(unsigned int i); void SetMaxSize(unsigned int i); void SetGrow(unsigned int i); void RemoveAll(); void RemoveAll_KeepSize(); void RemoveAt(unsigned int pos, unsigned int count); void RemoveAt_KeepSize(unsigned int pos, unsigned int count); void InsertAt(int f, unsigned int pos); int Pop_KeepSize(); bool Contains(int i) { BXIN; int z; for (z=0;z<(int)m_iSize;z++) if (m_pData[z] == i) return true; BXOUT; return false; } int GetPosition(int i) { BXIN; int z; for (z=0;z<(int)m_iSize;z++) if (m_pData[z] == i) return z; BXOUT; return -1; } int &GetAt(unsigned int i) { BXIN; #ifdef DEBUG_CINTARRAY mprintf("@ CxIntArray::GetAt(int): %d...",i); #endif #ifdef DEBUG_ARRAYS if (i >= m_iSize) { if (m_sName != NULL) eprintf("CxIntArray \"%s\" Boundary Error (%d/%d).\n",m_sName,i,m_iSize); else eprintf("CxIntArray Boundary Error (%d/%d).\n",i,m_iSize); abort(); } #endif #ifdef DEBUG_CINTARRAY mprintf("done.\n"); #endif BXOUT; return m_pData[i]; } int &operator [] (unsigned int i) { #ifdef DEBUG_CINTARRAY mprintf("@ CxIntArray::operator [] (int): %d\n",i); #endif return GetAt(i); } int operator [] (unsigned int i) const { BXIN; #ifdef DEBUG_CINTARRAY mprintf("@ const CxIntArray::operator [] (int): %d...",i); #endif #ifdef DEBUG_ARRAYS if (i >= m_iSize) { if (m_sName != NULL) eprintf("CxIntArray \"%s\" Boundary Error (%d/%d).\n",m_sName,i,m_iSize); else eprintf("CxIntArray Boundary Error (%d/%d).\n",i,m_iSize); abort(); } #endif #ifdef DEBUG_CINTARRAY mprintf("done.\n"); #endif BXOUT; return m_pData[i]; } int GetAt(unsigned int i) const { BXIN; #ifdef DEBUG_CINTARRAY mprintf("@ const CxIntArray::GetAt(int): %d...",i); #endif #ifdef DEBUG_ARRAYS if (i >= m_iSize) { if (m_sName != NULL) eprintf("CxIntArray \"%s\" Boundary Error (%d/%d).\n",m_sName,i,m_iSize); else eprintf("CxIntArray Boundary Error (%d/%d).\n",i,m_iSize); abort(); } #endif #ifdef DEBUG_CINTARRAY mprintf("done.\n"); #endif BXOUT; return m_pData[i]; } int GetSize() const { #ifdef DEBUG_CINTARRAY mprintf("@ CxIntArray::GetSize(): %d\n",m_iSize); #endif return m_iSize; } private: int *m_pData; unsigned int m_iSize; unsigned int m_iMaxSize; unsigned int m_iGrow; #ifdef DEBUG_ARRAYS char *m_sName; #endif }; #endif travis-src-190101/src/xlongarray.cpp0100777000000000000000000002213513412725631014332 0ustar00/***************************************************************************** TRAVIS - Trajectory Analyzer and Visualizer http://www.travis-analyzer.de/ Copyright (c) 2009-2019 Martin Brehm 2012-2019 Martin Thomas 2016-2019 Sascha Gehrke This file was written by Martin Brehm. --------------------------------------------------------------------------- This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . *****************************************************************************/ // This must always be the first include directive #include "config.h" #include "xlongarray.h" const char *GetRevisionInfo_xlongarray(unsigned int len) { static char buf[256]; GET_REVISION_INFO( buf, len ); return buf; } const char *GetSourceVersion_xlongarray() { static char buf[256]; GET_SOURCE_VERSION( buf ); return buf; } #ifndef DEBUG_ARRAYS #define m_sName (NULL) #endif CxLongArray::CxLongArray() { BXIN; #ifdef DEBUG_CLONGARRAY mprintf("@ CxLongArray::CxLongArray()\n"); #endif m_pData = NULL; m_iSize = 0; m_iMaxSize = 0; m_iGrow = 16; #ifdef DEBUG_ARRAYS m_sName = NULL; #endif BXOUT; } CxLongArray::CxLongArray(const char *name) { BXIN; #ifdef DEBUG_CLONGARRAY mprintf("@ CxLongArray::CxLongArray(const char *)\n"); #endif m_pData = NULL; m_iSize = 0; m_iMaxSize = 0; m_iGrow = 16; #ifdef DEBUG_ARRAYS m_sName = NULL; #endif SetName(name); BXOUT; } CxLongArray::~CxLongArray() { BXIN; #ifdef DEBUG_CLONGARRAY mprintf("@ CxLongArray::~CxLongArray()\n"); #endif RemoveAll(); #ifdef DEBUG_ARRAYS if (m_sName != NULL) { delete[] m_sName; m_sName = NULL; } #endif BXOUT; } CxLongArray::CxLongArray(const CxLongArray &o) : CxObject() { BXIN; #ifdef DEBUG_CLONGARRAY mprintf("@ CxLongArray::CxLongArray(CxLongArray &)..."); #endif unsigned long z; m_iGrow = o.m_iGrow; if ((o.m_iMaxSize != 0) && (o.m_pData != NULL)) { m_iSize = o.m_iSize; m_iMaxSize = o.m_iMaxSize; try { m_pData = new long[m_iMaxSize]; } catch(...) { m_pData = NULL; } if (m_pData == NULL) NewException((double)m_iMaxSize*sizeof(long),__FILE__,__LINE__,__PRETTY_FUNCTION__,m_sName); for (z=0;zm_iSize; m_iMaxSize = o->m_iMaxSize; m_iGrow = o->m_iGrow; if (m_pData != NULL) delete[] m_pData; try { m_pData = new long[m_iMaxSize]; } catch(...) { m_pData = NULL; } if (m_pData == NULL) NewException((double)m_iMaxSize*sizeof(long),__FILE__,__LINE__,__PRETTY_FUNCTION__,m_sName); // for (z=0;zm_pData[z]; if (o->m_pData != NULL) memcpy(m_pData,o->m_pData,m_iSize*sizeof(long)); #ifdef DEBUG_CLONGARRAY mprintf("done.\n"); #endif BXOUT; } void CxLongArray::Append(CxLongArray *o) { BXIN; #ifdef DEBUG_CLONGARRAY mprintf("@ CxLongArray::Append(CxLongArray*)..."); #endif // unsigned long z; if (m_iSize+o->m_iSize > m_iMaxSize) SetMaxSize(m_iSize+o->m_iSize); // for (z=0;zm_iSize;z++) // m_pData[m_iSize+z] = o->m_pData[z]; if (o->m_pData != NULL) memcpy(&m_pData[m_iSize],o->m_pData,o->m_iSize*sizeof(long)); m_iSize += o->m_iSize; #ifdef DEBUG_CLONGARRAY mprintf("done.\n"); #endif BXOUT; } void CxLongArray::SetAt(unsigned long pos, long f) { BXIN; // unsigned long z; #ifdef DEBUG_CLONGARRAY bool s = false; mprintf("@ CxLongArray::Add(long)..."); #endif if (pos >= m_iMaxSize) { #ifdef DEBUG_CLONGARRAY s = true; mprintf("\n"); #endif SetMaxSize(pos+1); } m_pData[pos] = f; if (pos >= m_iSize) // { // for (z=m_iSize;z m_iMaxSize) { #ifdef DEBUG_CLONGARRAY s = true; mprintf("\n"); #endif SetMaxSize(m_iMaxSize + m_iGrow); } m_pData[m_iSize] = f; m_iSize++; #ifdef DEBUG_CLONGARRAY if (s) mprintf("@ done.\n"); else mprintf("done.\n"); #endif BXOUT; } void CxLongArray::SetSize(unsigned long i) { BXIN; #ifdef DEBUG_CLONGARRAY mprintf("@ CxLongArray::SetSize(int): %d...",i); #endif if (m_iSize == i) return; long *temp; try { temp = new long[i]; } catch(...) { temp = NULL; } if (temp == NULL) NewException((double)i*sizeof(long),__FILE__,__LINE__,__PRETTY_FUNCTION__,m_sName); if (m_pData != NULL) { if (m_iSize > i) memcpy(temp,m_pData,i*sizeof(long)); else memcpy(temp,m_pData,m_iSize*sizeof(long)); delete[] m_pData; } m_pData = temp; m_iMaxSize = i; m_iSize = i; #ifdef DEBUG_CLONGARRAY mprintf("done.\n"); #endif BXOUT; } void CxLongArray::SetMaxSize(unsigned long i) { BXIN; #ifdef DEBUG_CLONGARRAY mprintf("@ CxLongArray::SetMaxSize(int): %d...",i); #endif long *temp; try { temp = new long[i]; } catch(...) { temp = NULL; } if (temp == NULL) NewException((double)i*sizeof(long),__FILE__,__LINE__,__PRETTY_FUNCTION__,m_sName); if (m_pData != NULL) { memcpy(temp,m_pData,m_iSize*sizeof(long)); delete[] m_pData; } m_pData = temp; m_iMaxSize = i; #ifdef DEBUG_CLONGARRAY mprintf("done.\n"); #endif BXOUT; } void CxLongArray::SetGrow(unsigned long i) { BXIN; #ifdef DEBUG_CLONGARRAY mprintf("@ CxLongArray::SetGrow(int): %d\n",i); #endif m_iGrow = i; BXOUT; } void CxLongArray::RemoveAll() { BXIN; #ifdef DEBUG_CLONGARRAY mprintf("@ CxLongArray::RemoveAll():..."); #endif if (m_pData != NULL) delete[] m_pData; m_pData = NULL; m_iSize = 0; m_iMaxSize = 0; #ifdef DEBUG_CLONGARRAY mprintf("done.\n"); #endif BXOUT; } void CxLongArray::RemoveAll_KeepSize() { BXIN; #ifdef DEBUG_CLONGARRAY mprintf("@ CxLongArray::RemoveAll_KeepSize():..."); #endif m_iSize = 0; #ifdef DEBUG_CLONGARRAY mprintf("done.\n"); #endif BXOUT; } void CxLongArray::RemoveAt(unsigned long pos, unsigned long count) { BXIN; long *temp; #ifdef DEBUG_CLONGARRAY mprintf("@ CxLongArray::RemoveAt(int, int): %d, %d...",pos,count); #endif try { temp = new long[m_iSize-count]; } catch(...) { temp = NULL; } if (temp == NULL) NewException((double)(m_iSize-count)*sizeof(long),__FILE__,__LINE__,__PRETTY_FUNCTION__,m_sName); if (m_pData != NULL) { memcpy(temp,m_pData,pos*sizeof(long)); memcpy(&temp[pos],&m_pData[pos+count],(m_iSize-pos-count)*sizeof(long)); delete[] m_pData; } m_pData = temp; m_iSize-=count; m_iMaxSize = m_iSize; #ifdef DEBUG_CLONGARRAY mprintf("done.\n"); #endif BXOUT; } void CxLongArray::RemoveAt_KeepSize(unsigned long pos, unsigned long count) { BXIN; long *temp; #ifdef DEBUG_CLONGARRAY mprintf("@ CxLongArray::RemoveAt_KeepSize(int, int): %d, %d...",pos,count); #endif try { temp = new long[m_iMaxSize]; } catch(...) { temp = NULL; } if (temp == NULL) NewException((double)m_iMaxSize*sizeof(long),__FILE__,__LINE__,__PRETTY_FUNCTION__,m_sName); if (m_pData != NULL) { memcpy(temp,m_pData,pos*sizeof(long)); memcpy(&temp[pos],&m_pData[pos+count],(m_iSize-pos-count)*sizeof(long)); delete[] m_pData; } m_pData = temp; m_iSize-=count; #ifdef DEBUG_CLONGARRAY mprintf("done.\n"); #endif BXOUT; } void CxLongArray::InsertAt(long f, unsigned long pos) { BXIN; long *temp; #ifdef DEBUG_CLONGARRAY mprintf("@ CxLongArray::InsertAt(long, int): %d..."); #endif try { temp = new long[m_iSize+1]; } catch(...) { temp = NULL; } if (temp == NULL) NewException((double)(m_iSize+1)*sizeof(long),__FILE__,__LINE__,__PRETTY_FUNCTION__,m_sName); if (m_pData != NULL) { memcpy(temp,m_pData,pos*sizeof(long)); memcpy(&temp[pos+1],&m_pData[pos],(m_iSize-pos)*sizeof(long)); delete[] m_pData; } temp[pos] = f; m_pData = temp; m_iSize++; m_iMaxSize = m_iSize; #ifdef DEBUG_CLONGARRAY mprintf("done.\n"); #endif BXOUT; } void CxLongArray::SetName(const char *name) { UNUSED(name); #ifdef DEBUG_ARRAYS BXIN; #ifdef DEBUG_CLONGARRAY mprintf("@ CxLongArray::SetName(const char *): \"%s\"...",name); #endif if (m_sName != NULL) delete[] m_sName; try { m_sName = new char[strlen(name)+1]; } catch(...) { m_sName = NULL; } if (m_sName == NULL) NewException((double)(strlen(name)+1)*sizeof(char),__FILE__,__LINE__,__PRETTY_FUNCTION__); strcpy(m_sName,name); #ifdef DEBUG_CLONGARRAY mprintf("done.\n"); #endif BXOUT; #endif } travis-src-190101/src/xlongarray.h0100777000000000000000000000723313412725670014004 0ustar00/***************************************************************************** TRAVIS - Trajectory Analyzer and Visualizer http://www.travis-analyzer.de/ Copyright (c) 2009-2019 Martin Brehm 2012-2019 Martin Thomas 2016-2019 Sascha Gehrke This file was written by Martin Brehm. --------------------------------------------------------------------------- This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . *****************************************************************************/ #ifndef XLONGARRAY_H #define XLONGARRAY_H // This must always be the first include directive #include "config.h" #include "tools.h" #include "xobject.h" #include "backtrace.h" class CxLongArray : public CxObject { public: CxLongArray(); ~CxLongArray(); CxLongArray(const CxLongArray &o); explicit CxLongArray(const char *name); void SetName(const char *name); void CopyFrom(CxLongArray *o); void Add(long f); void Append(CxLongArray *o); void SetAt(unsigned long pos, long f); void SetSize(unsigned long i); void SetMaxSize(unsigned long i); void SetGrow(unsigned long i); void RemoveAll(); void RemoveAll_KeepSize(); void RemoveAt(unsigned long pos, unsigned long count); void RemoveAt_KeepSize(unsigned long pos, unsigned long count); void InsertAt(long f, unsigned long pos); bool Contains(long i) { BXIN; int z; for (z=0;z<(int)m_iSize;z++) if (m_pData[z] == i) return true; BXOUT; return false; } int GetPosition(long i) { BXIN; int z; for (z=0;z<(int)m_iSize;z++) if (m_pData[z] == i) return z; BXOUT; return -1; } long &GetAt(unsigned long i) { BXIN; #ifdef DEBUG_CLONGARRAY mprintf("@ CxLongArray::GetAt(int): %d...",i); #endif #ifdef DEBUG_ARRAYS if (i >= m_iSize) { if (m_sName != NULL) eprintf("CxLongArray \"%s\" Boundary Error (%lu/%lu).\n",m_sName,i,m_iSize); else eprintf("CxLongArray Boundary Error (%lu/%lu).\n",i,m_iSize); abort(); } #endif #ifdef DEBUG_CLONGARRAY mprintf("done.\n"); #endif BXOUT; return m_pData[i]; } long &operator [] (unsigned long i) { #ifdef DEBUG_CLONGARRAY mprintf("@ CxLongArray::operator [] (int): %d\n",i); #endif return GetAt(i); } long GetAt(unsigned long i) const { BXIN; #ifdef DEBUG_CLONGARRAY mprintf("@ CxLongArray::GetAt(int): %d...",i); #endif #ifdef DEBUG_ARRAYS if (i >= m_iSize) { if (m_sName != NULL) eprintf("CxLongArray \"%s\" Boundary Error (%lu/%lu).\n",m_sName,i,m_iSize); else eprintf("CxLongArray Boundary Error (%lu/%lu).\n",i,m_iSize); abort(); } #endif #ifdef DEBUG_CLONGARRAY mprintf("done.\n"); #endif BXOUT; return m_pData[i]; } long operator [] (unsigned long i) const { #ifdef DEBUG_CLONGARRAY mprintf("@ CxLongArray::operator [] (int): %d\n",i); #endif return GetAt(i); } int GetSize() { #ifdef DEBUG_CLONGARRAY mprintf("@ CxLongArray::GetSize(): %d\n",m_iSize); #endif return m_iSize; } private: long *m_pData; unsigned long m_iSize; unsigned long m_iMaxSize; unsigned long m_iGrow; #ifdef DEBUG_ARRAYS char *m_sName; #endif }; #endif travis-src-190101/src/xmemfile.cpp0100777000000000000000000002424513412725625013761 0ustar00/***************************************************************************** TRAVIS - Trajectory Analyzer and Visualizer http://www.travis-analyzer.de/ Copyright (c) 2009-2019 Martin Brehm 2012-2019 Martin Thomas 2016-2019 Sascha Gehrke This file was written by Martin Brehm. --------------------------------------------------------------------------- This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . *****************************************************************************/ // This must always be the first include directive #include "config.h" #include "xmemfile.h" #include "tools.h" #include "xstring.h" #ifdef TARGET_LINUX #include #endif const char *GetRevisionInfo_xmemfile(unsigned int len) { static char buf[256]; GET_REVISION_INFO( buf, len ); return buf; } const char *GetSourceVersion_xmemfile() { static char buf[256]; GET_SOURCE_VERSION( buf ); return buf; } CxMemFile::CxMemFile() { m_pBuffer = NULL; m_pPointer = NULL; m_iBufSize = 0; } CxMemFile::CxMemFile(CxMemFile *p) { if (p->m_pBuffer != NULL) { m_pBuffer = new unsigned char[p->m_iBufSize]; m_pPointer = p->m_pPointer; m_iBufSize = p->m_iBufSize; memcpy(m_pBuffer,p->m_pBuffer,m_iBufSize); } else { m_pBuffer = NULL; m_pPointer = NULL; m_iBufSize = 0; } } CxMemFile::~CxMemFile() { ReleaseBuffer(); } bool CxMemFile::SetSize(int i) { unsigned char *p; p = new unsigned char[i]; if (m_pBuffer != NULL) { if (i > m_iBufSize) { memcpy(p,m_pBuffer,m_iBufSize); } else { memcpy(p,m_pBuffer,i); } if (m_pPointer-m_pBuffer >= i) m_pPointer = &p[i-1]; else m_pPointer = &p[m_pPointer - m_pBuffer]; delete[] m_pBuffer; } m_iBufSize = i; m_pBuffer = p; return true; } void CxMemFile::ReleaseBuffer() { if (m_pBuffer != NULL) { delete[] m_pBuffer; m_pBuffer = NULL; } m_pPointer = NULL; m_iBufSize = 0; } bool CxMemFile::Eof() { if (m_pPointer >= &m_pBuffer[m_iBufSize-1]) return true; else return false; } bool CxMemFile::Match(const char*s) { SkipEmpty(); if (memcmp(m_pPointer,s,strlen(s)) == 0) { m_pPointer += strlen(s); return true; } else return false; } bool CxMemFile::ReadFile(const char *s, bool text) { FILE *a; int i, z; char buf[4096]; if (text) a = fopen(s,"rt"); else a = fopen(s,"rb"); if (a == NULL) { mprintf("CMemFile::ReadFile(): Could not read \"%s\".\n",s); return false; } fseek(a,0,SEEK_END); i = ftell(a); fseek(a,0,SEEK_SET); mprintf("Reading %d bytes from %s ...\n",i,s); m_iBufSize = i+1; m_pBuffer = new unsigned char[i+1]; m_pPointer = m_pBuffer; while (!feof(a)) { z = (int)fread(buf,1,4096,a); memcpy(m_pPointer,buf,z); m_pPointer += z; if (z < 4096) break; } m_pBuffer[m_iBufSize-1] = 0; m_pPointer = m_pBuffer; // mprintf("Done.\n"); fclose(a); return true; } void CxMemFile::SkipEmpty() { while ((m_pPointer < &m_pBuffer[m_iBufSize-1]) && ((*m_pPointer == ' ') || (*m_pPointer == '\r') || (*m_pPointer == '\n') || (*m_pPointer == '\t'))) m_pPointer++; } void CxMemFile::ReverseSkipEmpty() { while ((m_pPointer > m_pBuffer) && ((*m_pPointer == ' ') || (*m_pPointer == '\r') || (*m_pPointer == '\n') || (*m_pPointer == '\t'))) { // mprintf("ReverseSkipEmpty: Skipping %d...\n",*((char*)m_pPointer)); m_pPointer--; } } void CxMemFile::SkipEmpty(const char *sep) { while ((strchr(sep,*m_pPointer) != 0) && (m_pPointer < &m_pBuffer[m_iBufSize-1])) m_pPointer++; } void CxMemFile::SkipWord() { while ((m_pPointer < &m_pBuffer[m_iBufSize-1]) && (*m_pPointer != ' ') && (*m_pPointer != '\r') && (*m_pPointer != '\n') && (*m_pPointer != '\t')) m_pPointer++; } void CxMemFile::Seek(int pos) { m_pPointer = &m_pBuffer[pos]; } void CxMemFile::Create(int length) { m_pBuffer = new unsigned char[length]; m_iBufSize = length; Seek(0); } void CxMemFile::ReadWord(char *buf, int len) { char *p; SkipEmpty(); p = buf; while ((m_pPointer < &m_pBuffer[m_iBufSize-1]) && (*m_pPointer != ' ') && (*m_pPointer != '\r') && (*m_pPointer != '\n') && (*m_pPointer != '\t')) { *p = *m_pPointer; m_pPointer++; p++; if (p-buf+1 >= len) { mprintf("CxMemFile::ReadWord(): Warning: Buffer overflow prevented (%d).\n",len); *p = 0; return; } } *p = 0; } void CxMemFile::ReadWord(char *buf, int len, const char *sep) { char *p; SkipEmpty(sep); p = buf; while ((m_pPointer < &m_pBuffer[m_iBufSize-1]) && (strchr(sep,*m_pPointer) == 0)) { *p = *m_pPointer; m_pPointer++; p++; if (p-buf+1 >= len) { mprintf("CxMemFile::ReadWord(): Warning: Buffer overflow prevented (%d).\n",len); *p = 0; return; } } *p = 0; } int CxMemFile::scanf(const char *s, void* data) { int i; static char buf[4096]; unsigned char *p; while ((*m_pPointer == ' ') || (*m_pPointer == '\r') || (*m_pPointer == '\n')) { m_pPointer++; if (*m_pPointer == 0) { mprintf("CMemFile::scanf(): Unexpected end of file (1).\n"); abort(); } } p = m_pPointer; while ((*m_pPointer != ' ') && (*m_pPointer != '\r') && (*m_pPointer != '\n')) { m_pPointer++; if (*m_pPointer == 0) { mprintf("CMemFile::scanf(): Unexpected end of file (2).\n"); abort(); } } memcpy(buf,p,m_pPointer-p); buf[m_pPointer-p] = 0; // printf("Request: %s, Read \"%s\".\n",s,buf); i = sscanf(buf,s,data); return i; } int CxMemFile::fgets(char *buf, int len) { // unsigned char *p; // // mprintf(GREEN, "%p\n", m_pPointer); // p = m_pPointer; // // while ((*m_pPointer != ' ') && (*m_pPointer != '\r') && (*m_pPointer != '\n')) // { // m_pPointer++; // if (*m_pPointer == 0) // { // mprintf("CMemFile::scanf(): Unexpected end of file (2).\n"); // abort(); // } // } // // if (m_pPointer-p < len-1) // { // memcpy(buf,p,m_pPointer-p); // buf[m_pPointer-p] = 0; // } else // { // memcpy(buf,p,len-1); // buf[len-1] = 0; // } // // return m_pPointer-p; int count = 0; unsigned char *start = m_pPointer; while ((*m_pPointer != '\n') && (*m_pPointer != 0) && (count < len - 1)) { m_pPointer++; count++; } if ((*m_pPointer == '\n') && (count < len - 1)) { m_pPointer++; count++; } memcpy(buf, start, count); buf[count] = 0; return count; } void CxMemFile::printf(const char *s, ...) { // static char buf[4096]; CxString buf; int i, j; // va_list args; unsigned char *p; // va_start(args,s); // vsprintf(buf,s,args); // buf.vsprintf(s,args); // va_end(args); #ifdef TARGET_LINUX XVSPRINTF_LINUX(buf,s,s); #else XVSPRINTF_WINDOWS(buf,s,s); #endif i = (int)strlen(buf); if (m_pPointer-m_pBuffer+i+1 > m_iBufSize) { p = new unsigned char[m_iBufSize+1024*64]; if (m_iBufSize != 0) { j = (int)(m_pPointer-m_pBuffer); memcpy(p,m_pBuffer,m_pPointer-m_pBuffer+1); delete[] m_pBuffer; m_pBuffer = p; m_pPointer = m_pBuffer+j; m_iBufSize += 1024*64; } else { m_pBuffer = p; m_pPointer = m_pBuffer; m_iBufSize = 1024*64; } } memcpy(m_pPointer,(const char*)buf,i); m_pPointer += i; *m_pPointer = 0; } void CxMemFile::WriteFile(const char *s, bool text) { FILE *a; unsigned char *p; int i, k; if (text) a = fopen(s,"wt"); else a = fopen(s,"wb"); p = m_pBuffer; i = m_iBufSize; while (i > 0) { if (i >= 4096) { k = (int)fwrite(p,1,4096,a); p += k; i -= k; } else { k = (int)fwrite(p,1,i,a); p += k; i -= k; break; } } mprintf("WriteFile(): %ld Bytes written.\n",m_iBufSize); fclose(a); } bool CxMemFile::ReadFileSuccessive(const char *s, int lines, bool verbose) { FILE *a; int i, k, l, z; static char buf[4096]; unsigned char *tc; long t0; a = fopen(s,"rb"); while (a == NULL) { if (verbose) mprintf("ReadFileSuccessive(): Waiting for file \"%s\"...\n", s); #ifdef TARGET_LINUX usleep(1000000); // Wait 1 sec #else eprintf("I have no usleep(), I am slightly in a hurry ;-)\n"); #endif a = fopen(s, "rb"); } if (verbose) mprintf("ReadFileSuccessive(): Reading file \"%s\", expecting %d lines...\n",s,lines); // if (a == NULL) // { // eprintf("CxMemFile::ReadFileSuccessive(): Could not open %s for reading.\n",s); // return false; // } t0 = (long)time(NULL); if (m_pBuffer == NULL) // Create(16384); Create(lines * 80); Seek(0); i = 0; l = 0; // Total line count read while (l < lines) // Until all expected lines have been read { k = (int)fread(buf,1,4096,a); i += k; if (m_pPointer+k > m_pBuffer+m_iBufSize) { if (verbose) mprintf(" ReadFileSuccessive(): Increasing buffer size to %ld bytes.\n",m_iBufSize*2); tc = new unsigned char[m_iBufSize*2]; memcpy(tc,m_pBuffer,m_iBufSize); m_pPointer = tc + (m_pPointer - m_pBuffer); delete[] m_pBuffer; m_pBuffer = tc; m_iBufSize *= 2; } memcpy(m_pPointer,buf,k); m_pPointer += k; // Count line breaks in block just read for (z=0;z= lines) break; if (feof(a)) { if (time(NULL) > t0+180) { eprintf("CxMemFile::ReadFileSuccessive(): Timeout exceeded (180 sec) while waiting for more data in file.\n"); fclose(a); return false; } if (verbose) mprintf(" ReadFileSuccessive(): EOF after reading %d bytes. %d/%d lines in total.\n",i,l,lines); i = 0; #ifdef TARGET_LINUX usleep(1000000); // Wait 1 sec #else eprintf("I have no usleep(), I am slightly in a hurry ;-)\n"); #endif clearerr(a); // Reset EOF flag } } fclose(a); m_pPointer++; *m_pPointer = 0; // This is probably smaller than the allocated block, but don't care - size of valid data matters m_iBufSize = (long)(m_pPointer - m_pBuffer + 1); if (verbose) mprintf("ReadFileSuccessive(): Reading complete.\n"); Seek(0); return true; } travis-src-190101/src/xmemfile.h0100777000000000000000000000407113412725666013426 0ustar00/***************************************************************************** TRAVIS - Trajectory Analyzer and Visualizer http://www.travis-analyzer.de/ Copyright (c) 2009-2019 Martin Brehm 2012-2019 Martin Thomas 2016-2019 Sascha Gehrke This file was written by Martin Brehm. --------------------------------------------------------------------------- This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . *****************************************************************************/ #ifndef MEMFILE_H #define MEMFILE_H // This must always be the first include directive #include "config.h" #include #include #include "xobject.h" class CxMemFile : public CxObject { public: CxMemFile(); ~CxMemFile(); explicit CxMemFile(CxMemFile *p); int fgets(char *buf, int len); bool ReadFileSuccessive(const char *s, int lines, bool verbose); bool SetSize(int i); void ReleaseBuffer(); bool ReadFile(const char *s, bool text); int scanf(const char *s, void* data); void printf(const char *s, ...); void WriteFile(const char *s, bool text); void SkipEmpty(); void SkipWord(); void ReadWord(char *buf, int len); void SkipEmpty(const char *sep); void ReadWord(char *buf, int len, const char *sep); void ReverseSkipEmpty(); bool Match(const char*s); void Seek(int pos); bool Eof(); void Create(int length); unsigned char *m_pBuffer; unsigned char *m_pPointer; long m_iBufSize; }; #endif travis-src-190101/src/xobarray.cpp0100777000000000000000000002071413412725625013777 0ustar00/***************************************************************************** TRAVIS - Trajectory Analyzer and Visualizer http://www.travis-analyzer.de/ Copyright (c) 2009-2019 Martin Brehm 2012-2019 Martin Thomas 2016-2019 Sascha Gehrke This file was written by Martin Brehm. --------------------------------------------------------------------------- This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . *****************************************************************************/ // This must always be the first include directive #include "config.h" #include "xobarray.h" const char *GetRevisionInfo_xobarray(unsigned int len) { static char buf[256]; GET_REVISION_INFO( buf, len ); return buf; } const char *GetSourceVersion_xobarray() { static char buf[256]; GET_SOURCE_VERSION( buf ); return buf; } #ifndef DEBUG_ARRAYS #define m_sName (NULL) #endif CxObArray::CxObArray() { #ifdef DEBUG_COBARRAY mprintf("@ CxObArray::CxObArray()\n"); #endif m_pData = NULL; #ifdef DEBUG_ARRAYS m_sName = NULL; #endif m_iSize = 0; m_iMaxSize = 0; m_iGrow = 16; } CxObArray::CxObArray(const char *name) { #ifdef DEBUG_COBARRAY mprintf("@ CxObArray::CxObArray(char *name)\n"); #endif m_pData = NULL; #ifdef DEBUG_ARRAYS m_sName = NULL; #endif m_iSize = 0; m_iMaxSize = 0; m_iGrow = 16; SetName(name); } CxObArray::~CxObArray() { #ifdef DEBUG_COBARRAY mprintf("@ CxObArray::~CxObArray()\n"); #endif RemoveAll(); #ifdef DEBUG_ARRAYS if (m_sName != NULL) { delete[] m_sName; m_sName = NULL; } #endif } CxObArray::CxObArray(const CxObArray &o) : CxObject() { #ifdef DEBUG_COBARRAY mprintf("@ CxObArray::CxObArray(CxObArray &)..."); #endif unsigned long z; m_iGrow = o.m_iGrow; if ((o.m_iMaxSize != 0) && (o.m_pData != NULL)) { m_iSize = o.m_iSize; m_iMaxSize = o.m_iMaxSize; try { m_pData = new CxObject*[m_iMaxSize]; } catch(...) { m_pData = NULL; } if (m_pData == NULL) NewException((double)m_iMaxSize*sizeof(CxObject*),__FILE__,__LINE__,__PRETTY_FUNCTION__,m_sName); for (z=0;z= m_iMaxSize) { #ifdef DEBUG_COBARRAY s = true; mprintf("\n"); #endif SetMaxSize(pos+1); } m_pData[pos] = o; if (pos >= m_iSize) { for (z=m_iSize;z m_iMaxSize) { #ifdef DEBUG_COBARRAY s = true; mprintf("\n"); #endif if (m_iGrow < 1) m_iGrow = 1; // SetMaxSize(m_iMaxSize + m_iGrow); if (m_iMaxSize == 0) SetMaxSize(m_iMaxSize + m_iGrow); else SetMaxSize(m_iMaxSize*2); } m_pData[m_iSize] = o; m_iSize++; #ifdef DEBUG_COBARRAY if (s) mprintf("@ done.\n"); else mprintf("done.\n"); #endif } void CxObArray::SetSize(unsigned long i) { unsigned long z; #ifdef DEBUG_COBARRAY mprintf("@ CxObArray::SetSize(int): %d...",i); #endif if (i == m_iSize) return; CxObject **temp; try { temp = new CxObject*[i]; } catch(...) { temp = NULL; } if (temp == NULL) NewException((double)i*sizeof(CxObject*),__FILE__,__LINE__,__PRETTY_FUNCTION__,m_sName); if (m_pData != NULL) { if (m_iSize > i) memcpy(temp,m_pData,i*sizeof(CxObject*)); else memcpy(temp,m_pData,m_iSize*sizeof(CxObject*)); delete[] m_pData; } // Neu und heikel (Ballmer-Peak ^^) for (z=m_iSize;z. *****************************************************************************/ #ifndef XOBARRAY_H #define XOBARRAY_H // This must always be the first include directive #include "config.h" #include "tools.h" #include "xobject.h" #include "backtrace.h" class CxObArray : public CxObject { public: CxObArray(); CxObArray(const CxObArray &o); ~CxObArray(); explicit CxObArray(const char *name); void SetName(const char *name); void Add(CxObject *o); void SetAt(unsigned long pos, CxObject *o); CxObject* &GetAt(unsigned long i) { #ifdef DEBUG_COBARRAY mprintf("@ CxObArray::GetAt(int): %d...",i); #endif #ifdef DEBUG_ARRAYS if (i >= m_iSize) { if (m_sName != NULL) eprintf("CxObArray \"%s\" Boundary Error (%lu/%lu).\n",m_sName,i,m_iSize); else eprintf("CxObArray Boundary Error (%lu/%lu).\n",i,m_iSize); abort(); } #endif #ifdef DEBUG_COBARRAY mprintf("done.\n"); #endif return m_pData[i]; } CxObject* &operator [] (unsigned long i) { #ifdef DEBUG_COBARRAY mprintf("@ CxObArray::operator [] (int): %d\n",i); #endif return GetAt(i); } CxObject* GetAt(unsigned long i) const { #ifdef DEBUG_COBARRAY mprintf("@ CxObArray::GetAt(int): %d...",i); #endif #ifdef DEBUG_ARRAYS if (i >= m_iSize) { if (m_sName != NULL) eprintf("CxObArray \"%s\" Boundary Error (%lu/%lu).\n",m_sName,i,m_iSize); else eprintf("CxObArray Boundary Error (%lu/%lu).\n",i,m_iSize); abort(); } #endif #ifdef DEBUG_COBARRAY mprintf("done.\n"); #endif return m_pData[i]; } CxObject* operator [] (unsigned long i) const { #ifdef DEBUG_COBARRAY mprintf("@ CxObArray::operator [] (int): %d\n",i); #endif return GetAt(i); } /* inline const CxObject* &operator [] (unsigned long i) const { #ifdef DEBUG_COBARRAY mprintf("@ const CxObArray::operator [] (int): %d...",i); #endif #ifdef DEBUG_ARRAYS if (i >= m_iSize) { if (m_sName != NULL) eprintf("CxObArray \"%s\" Boundary Error (%lu/%lu).\n",m_sName,i,m_iSize); else eprintf("CxObArray Boundary Error (%lu/%lu).\n",i,m_iSize); abort(); } #endif #ifdef DEBUG_COBARRAY mprintf("done.\n"); #endif return m_pData[i]; }*/ int GetSize() const { #ifdef DEBUG_COBARRAY mprintf("@ CxObArray::GetSize(): %d\n",m_iSize); #endif return m_iSize; } void SetSize(unsigned long i); void SetSize_NoShrink(unsigned long i); void SetMaxSize(unsigned long i); void SetGrow(unsigned long i); void RemoveAll(); void RemoveAll_KeepSize(); void RemoveAt(unsigned long pos, unsigned long count); void RemoveAt_NoShrink(unsigned long pos, unsigned long count); void InsertAt(CxObject *o, unsigned long pos); private: CxObject **m_pData; unsigned long m_iSize; unsigned long m_iMaxSize; unsigned long m_iGrow; #ifdef DEBUG_ARRAYS char *m_sName; #endif }; #endif travis-src-190101/src/xobject.h0100777000000000000000000000243713412725657013262 0ustar00/***************************************************************************** TRAVIS - Trajectory Analyzer and Visualizer http://www.travis-analyzer.de/ Copyright (c) 2009-2019 Martin Brehm 2012-2019 Martin Thomas 2016-2019 Sascha Gehrke This file was written by Martin Brehm. --------------------------------------------------------------------------- This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . *****************************************************************************/ #ifndef CXOBJECT_DEFINED #define CXOBJECT_DEFINED // This must always be the first include directive #include "config.h" class CxObject { public: }; #endif travis-src-190101/src/xptrarray.cpp0100777000000000000000000001720713412725630014203 0ustar00/***************************************************************************** TRAVIS - Trajectory Analyzer and Visualizer http://www.travis-analyzer.de/ Copyright (c) 2009-2019 Martin Brehm 2012-2019 Martin Thomas 2016-2019 Sascha Gehrke This file was written by Martin Brehm. --------------------------------------------------------------------------- This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . *****************************************************************************/ // This must always be the first include directive #include "config.h" #include "xptrarray.h" const char *GetRevisionInfo_xptrarray(unsigned int len) { static char buf[256]; GET_REVISION_INFO( buf, len ); return buf; } const char *GetSourceVersion_xptrarray() { static char buf[256]; GET_SOURCE_VERSION( buf ); return buf; } #ifndef DEBUG_ARRAYS #define m_sName (NULL) #endif CxPtrArray::CxPtrArray() { BXIN; #ifdef DEBUG_CPTRARRAY mprintf("@ CxPtrArray::CxPtrArray()\n"); #endif m_pData = NULL; m_iSize = 0; m_iMaxSize = 0; m_iGrow = 16; #ifdef DEBUG_ARRAYS m_sName = NULL; #endif BXOUT; } CxPtrArray::CxPtrArray(const char *name) { BXIN; #ifdef DEBUG_CPTRARRAY mprintf("@ CxPtrArray::CxPtrArray(const char *)\n"); #endif m_pData = NULL; m_iSize = 0; m_iMaxSize = 0; m_iGrow = 16; #ifdef DEBUG_ARRAYS m_sName = NULL; #endif SetName(name); BXOUT; } CxPtrArray::~CxPtrArray() { BXIN; #ifdef DEBUG_CPTRARRAY mprintf("@ CxPtrArray::~CxPtrArray()\n"); #endif RemoveAll(); #ifdef DEBUG_ARRAYS if (m_sName != NULL) { delete[] m_sName; m_sName = NULL; } #endif BXOUT; } CxPtrArray::CxPtrArray(const CxPtrArray &o) : CxObject() { BXIN; #ifdef DEBUG_CPTRARRAY mprintf("@ CxPtrArray::CxPtrArray(CxPtrArray &)..."); #endif unsigned long z; m_iGrow = o.m_iGrow; if ((o.m_iMaxSize != 0) && (o.m_pData != NULL)) { m_iSize = o.m_iSize; m_iMaxSize = o.m_iMaxSize; try { m_pData = new void*[m_iMaxSize]; } catch(...) { m_pData = NULL; } if (m_pData == NULL) NewException((double)m_iMaxSize*sizeof(void*),__FILE__,__LINE__,__PRETTY_FUNCTION__,m_sName); for (z=0;z= m_iMaxSize) { #ifdef DEBUG_CPTRARRAY s = true; mprintf("\n"); #endif SetMaxSize(pos+1); } m_pData[pos] = o; if (pos >= m_iSize) { for (z=m_iSize;z m_iMaxSize) { #ifdef DEBUG_CPTRARRAY s = true; mprintf("\n"); #endif if (m_iGrow < 1) m_iGrow = 1; // SetMaxSize(m_iMaxSize + m_iGrow); if (m_iMaxSize == 0) SetMaxSize(m_iMaxSize + m_iGrow); else SetMaxSize(m_iMaxSize*2); } m_pData[m_iSize] = o; m_iSize++; #ifdef DEBUG_CPTRARRAY if (s) mprintf("@ done.\n"); else mprintf("done.\n"); #endif BXOUT; } void CxPtrArray::SetSize(unsigned long i) { BXIN; int z; #ifdef DEBUG_CPTRARRAY mprintf("@ CxPtrArray::SetSize(int): %d...",i); #endif if (i == m_iSize) return; void **temp; try { temp = new void*[i]; } catch(...) { temp = NULL; } if (temp == NULL) NewException((double)i*sizeof(void*),__FILE__,__LINE__,__PRETTY_FUNCTION__,m_sName); if (m_pData != NULL) { if (m_iSize > i) memcpy(temp,m_pData,i*sizeof(void*)); else memcpy(temp,m_pData,m_iSize*sizeof(void*)); delete[] m_pData; } // Neu und heikel (Ballmer-Peak ^^) for (z=m_iSize;z<(int)i;z++) temp[z] = NULL; // Ende neu m_pData = temp; m_iMaxSize = i; m_iSize = i; #ifdef DEBUG_CPTRARRAY mprintf("done.\n"); #endif BXOUT; } void CxPtrArray::SetMaxSize(unsigned long i) { BXIN; #ifdef DEBUG_CPTRARRAY mprintf("@ CxPtrArray::SetMaxSize(int): %d...",i); #endif if (i == m_iMaxSize) { BXOUT; return; } void **temp; try { temp = new void*[i]; } catch(...) { temp = NULL; } if (temp == NULL) NewException((double)i*sizeof(void*),__FILE__,__LINE__,__PRETTY_FUNCTION__,m_sName); if (m_pData != NULL) { memcpy(temp,m_pData,m_iSize*sizeof(void*)); delete[] m_pData; } m_pData = temp; m_iMaxSize = i; #ifdef DEBUG_CPTRARRAY mprintf("done.\n"); #endif BXOUT; } void CxPtrArray::SetGrow(unsigned long i) { BXIN; #ifdef DEBUG_CPTRARRAY mprintf("@ CxPtrArray::SetGrow(int): %d\n",i); #endif m_iGrow = i; BXOUT; } void CxPtrArray::RemoveAll() { BXIN; #ifdef DEBUG_CPTRARRAY mprintf("@ CxPtrArray::RemoveAll():..."); #endif if (m_pData != NULL) delete[] m_pData; m_pData = NULL; m_iSize = 0; m_iMaxSize = 0; #ifdef DEBUG_CPTRARRAY mprintf("done.\n"); #endif BXOUT; } void CxPtrArray::RemoveAll_KeepSize() { BXIN; #ifdef DEBUG_CPTRARRAY mprintf("@ CxPtrArray::RemoveAll_KeepSize():..."); #endif m_iSize = 0; #ifdef DEBUG_CPTRARRAY mprintf("done.\n"); #endif BXOUT; } void CxPtrArray::RemoveAt(unsigned long pos, unsigned long count) { BXIN; void **temp; #ifdef DEBUG_CPTRARRAY mprintf("@ CxPtrArray::RemoveAt(int, int): %d, %d...",pos,count); #endif try { temp = new void*[m_iSize-count]; } catch(...) { temp = NULL; } if (temp == NULL) NewException((double)(m_iSize-count)*sizeof(void*),__FILE__,__LINE__,__PRETTY_FUNCTION__,m_sName); // for (z=pos;z. *****************************************************************************/ #ifndef XPTRARRAY_H #define XPTRARRAY_H // This must always be the first include directive #include "config.h" #include "tools.h" #include "xobject.h" #include "backtrace.h" class CxPtrArray : public CxObject { public: CxPtrArray(); ~CxPtrArray(); CxPtrArray(const CxPtrArray &o); explicit CxPtrArray(const char *name); void SetName(const char *name); void Add(void *o); void SetAt(unsigned long pos, void *o); void* &GetAt(unsigned long i) { #ifdef DEBUG_CPTRARRAY mprintf("@ CxPtrArray::GetAt(int): %d...",i); #endif #ifdef DEBUG_ARRAYS if (i >= m_iSize) { if (m_sName != NULL) eprintf("CxPtrArray \"%s\" Boundary Error (%lu/%lu).\n",m_sName,i,m_iSize); else eprintf("CxPtrArray Boundary Error (%lu/%lu).\n",i,m_iSize); abort(); } #endif #ifdef DEBUG_CPTRARRAY mprintf("done.\n"); #endif return m_pData[i]; } void* &operator [] (unsigned long i) { #ifdef DEBUG_CPTRARRAY mprintf("@ CxPtrArray::operator [] (int): %d\n",i); #endif return GetAt(i); } void* GetAt(unsigned long i) const { #ifdef DEBUG_CPTRARRAY mprintf("@ CxPtrArray::GetAt(int): %d...",i); #endif #ifdef DEBUG_ARRAYS if (i >= m_iSize) { if (m_sName != NULL) eprintf("CxPtrArray \"%s\" Boundary Error (%lu/%lu).\n",m_sName,i,m_iSize); else eprintf("CxPtrArray Boundary Error (%lu/%lu).\n",i,m_iSize); abort(); } #endif #ifdef DEBUG_CPTRARRAY mprintf("done.\n"); #endif return m_pData[i]; } void* operator [] (unsigned long i) const { #ifdef DEBUG_CPTRARRAY mprintf("@ CxPtrArray::operator [] (int): %d\n",i); #endif return GetAt(i); } int GetSize() { #ifdef DEBUG_CPTRARRAY mprintf("@ CxPtrArray::GetSize(): %d\n",m_iSize); #endif return m_iSize; } void SetSize(unsigned long i); void SetMaxSize(unsigned long i); void SetGrow(unsigned long i); void RemoveAll(); void RemoveAll_KeepSize(); void RemoveAt(unsigned long pos, unsigned long count); void InsertAt(void *o, unsigned long pos); private: void **m_pData; unsigned long m_iSize; unsigned long m_iMaxSize; unsigned long m_iGrow; #ifdef DEBUG_ARRAYS char *m_sName; #endif }; #endif travis-src-190101/src/xquaternion.h0100777000000000000000000001457313412725663014202 0ustar00/***************************************************************************** TRAVIS - Trajectory Analyzer and Visualizer http://www.travis-analyzer.de/ Copyright (c) 2009-2019 Martin Brehm 2012-2019 Martin Thomas 2016-2019 Sascha Gehrke This file was written by Martin Brehm. --------------------------------------------------------------------------- This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . *****************************************************************************/ #ifndef CXQUATERNION_DEFINED #define CXQUATERNION_DEFINED // This must always be the first include directive #include "config.h" #include "tools.h" #include "xobject.h" #include "backtrace.h" class CxQuaternion : public CxObject { public: CxQuaternion() { } ~CxQuaternion() { } CxQuaternion(const CxQuaternion &v) : CxObject() { BXIN; m_pData[0] = v.m_pData[0]; m_pData[1] = v.m_pData[1]; m_pData[2] = v.m_pData[2]; m_pData[3] = v.m_pData[3]; BXOUT; } explicit CxQuaternion(double f) { BXIN; m_pData[0] = f; m_pData[1] = f; m_pData[2] = f; m_pData[3] = f; BXOUT; } CxQuaternion(double a, double b, double c, double d) { BXIN; m_pData[0] = a; m_pData[1] = b; m_pData[2] = c; m_pData[3] = d; BXOUT; } double &GetAt(int i) { #ifdef DEBUG_CVECTOR3 mprintf("@ CxQuaternion::GetAt(int): %d...",i); #endif return m_pData[i]; } double &operator [] (int i) { #ifdef DEBUG_CVECTOR3 mprintf("@ CxQuaternion::operator [] (int): %d\n",i); #endif return GetAt(i); } double GetAt(int i) const { #ifdef DEBUG_CVECTOR3 mprintf("@ CxQuaternion::GetAt(int): %d...",i); #endif #ifdef DEBUG_ARRAYS if (i > 3) { mprintf("CxQuaternion::GetAt(int): Boundary Error (%d/3)...",i); abort(); } #endif return m_pData[i]; } double operator [] (int i) const { #ifdef DEBUG_CVECTOR3 mprintf("@ CxQuaternion::operator [] (int): %d\n",i); #endif return GetAt(i); } CxQuaternion operator + (const CxQuaternion &v) const { #ifdef DEBUG_CVECTOR3 mprintf("@ CxQuaternion::operator + (CxQuaternion&)\n"); #endif return CxQuaternion(m_pData[0]+v.m_pData[0],m_pData[1]+v.m_pData[1],m_pData[2]+v.m_pData[2],m_pData[3]+v.m_pData[3]); } CxQuaternion operator - (const CxQuaternion &v) const { #ifdef DEBUG_CVECTOR3 mprintf("@ CxQuaternion::operator - (CxQuaternion&)\n"); #endif return CxQuaternion(m_pData[0]-v.m_pData[0],m_pData[1]-v.m_pData[1],m_pData[2]-v.m_pData[2],m_pData[3]-v.m_pData[3]); } CxQuaternion operator * (const CxQuaternion &v) const { #ifdef DEBUG_CVECTOR3 mprintf("@ CxQuaternion::operator + (CxQuaternion&)\n"); #endif return CxQuaternion( m_pData[0]*v.m_pData[0] - m_pData[1]*v.m_pData[1] - m_pData[2]*v.m_pData[2] - m_pData[3]*v.m_pData[3], m_pData[0]*v.m_pData[1] + m_pData[1]*v.m_pData[0] + m_pData[2]*v.m_pData[3] - m_pData[3]*v.m_pData[2], m_pData[0]*v.m_pData[2] - m_pData[1]*v.m_pData[3] + m_pData[2]*v.m_pData[0] + m_pData[3]*v.m_pData[1], m_pData[0]*v.m_pData[3] + m_pData[1]*v.m_pData[2] - m_pData[2]*v.m_pData[1] + m_pData[3]*v.m_pData[0] ); } CxQuaternion operator * (double f) const { #ifdef DEBUG_CVECTOR3 mprintf("@ CxQuaternion::operator * (double)\n"); #endif return CxQuaternion(m_pData[0]*f,m_pData[1]*f,m_pData[2]*f,m_pData[3]*f); } CxQuaternion operator / (double f) const { #ifdef DEBUG_CVECTOR3 mprintf("@ CxQuaternion::operator / (double)\n"); #endif return CxQuaternion(m_pData[0]/f,m_pData[1]/f,m_pData[2]/f,m_pData[3]/f); } void operator += (const CxQuaternion &v) { BXIN; #ifdef DEBUG_CVECTOR3 mprintf("@ CxQuaternion::operator += (CxQuaternion&)\n"); #endif m_pData[0] += v.m_pData[0]; m_pData[1] += v.m_pData[1]; m_pData[2] += v.m_pData[2]; m_pData[3] += v.m_pData[3]; BXOUT; } void operator -= (const CxQuaternion &v) { BXIN; #ifdef DEBUG_CVECTOR3 mprintf("@ CxQuaternion::operator -= (CxQuaternion&)\n"); #endif m_pData[0] -= v.m_pData[0]; m_pData[1] -= v.m_pData[1]; m_pData[2] -= v.m_pData[2]; m_pData[3] -= v.m_pData[3]; BXOUT; } void operator *= (double f) { BXIN; #ifdef DEBUG_CVECTOR3 mprintf("@ CxQuaternion::operator *= (double)\n"); #endif m_pData[0] *= f; m_pData[1] *= f; m_pData[2] *= f; m_pData[3] *= f; BXOUT; } void operator /= (double f) { BXIN; #ifdef DEBUG_CVECTOR3 mprintf("@ CxQuaternion::operator /= (double)\n"); #endif m_pData[0] /= f; m_pData[1] /= f; m_pData[2] /= f; m_pData[3] /= f; BXOUT; } double GetLength() const { return sqrt(m_pData[0]*m_pData[0]+m_pData[1]*m_pData[1]+m_pData[2]*m_pData[2]+m_pData[3]*m_pData[3]); } double GetLengthSqr() const { return m_pData[0]*m_pData[0]+m_pData[1]*m_pData[1]+m_pData[2]*m_pData[2]+m_pData[3]*m_pData[3]; } CxQuaternion Conjugate() const { return CxQuaternion(m_pData[0],-m_pData[1],-m_pData[2],-m_pData[3]); } void BuildRotation(CxDVector3 axis, double angle) { CxDVector3 tmp; tmp = axis; tmp.Normalize(); m_pData[0] = cos(angle/2.0); m_pData[1] = sin(angle/2.0) * axis[0]; m_pData[2] = sin(angle/2.0) * axis[1]; m_pData[3] = sin(angle/2.0) * axis[2]; } /* inline CxVector3 Transform(const CxDVector3 &v) const { CxQuaternion out; out = this->Conjugate() * CxQuaternion(0,v[0],v[1],v[2]) * (*this); return CxDVector3(out[1],out[2],out[3]); }*/ CxDVector3 Transform(const CxDVector3 &v) const { CxQuaternion out; out = this->Conjugate() * CxQuaternion(0,v[0],v[1],v[2]) * (*this); return CxDVector3(out[1],out[2],out[3]); } void Normalize() { BXIN; double l; l = GetLength(); m_pData[0] /= l; m_pData[1] /= l; m_pData[2] /= l; m_pData[3] /= l; BXOUT; } void Unity() { BXIN; m_pData[0] = 1.0; m_pData[1] = 0; m_pData[2] = 0; m_pData[3] = 0; BXOUT; } private: double m_pData[4]; }; #endif travis-src-190101/src/xstring.cpp0100777000000000000000000003216713412725624013652 0ustar00/***************************************************************************** TRAVIS - Trajectory Analyzer and Visualizer http://www.travis-analyzer.de/ Copyright (c) 2009-2019 Martin Brehm 2012-2019 Martin Thomas 2016-2019 Sascha Gehrke This file was written by Martin Brehm. --------------------------------------------------------------------------- This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . *****************************************************************************/ // This must always be the first include directive #include "config.h" #include "xstring.h" #include #include "maintools.h" const char *GetRevisionInfo_string(unsigned int len) { static char buf[256]; GET_REVISION_INFO( buf, len ); return buf; } const char *GetSourceVersion_string() { static char buf[256]; GET_SOURCE_VERSION( buf ); return buf; } // Don't worry, this is only the first attempt. If this buffer is too small, // larger buffers will be tried out. Strings of arbitrary length can be handled. #define TEMP_BUF_SIZE (1024) static char g_pTempBuf[TEMP_BUF_SIZE]; CxString operator + (const char *s1, const CxString& s2) { #ifdef DEBUG_CxString mprintf("@ operator + (const char *, const CxString &): \"%s\", \"%s\"...",s1,(const char*)s2); #endif return CxString(s1,s2); } CxString::CxString(const CxString &s1, const CxString &s2) { BXIN; #ifdef DEBUG_CxString mprintf("@ CxString::CxString(const CxString &, const CxString &): \"%s\", \"%s\"...",(const char*)s1,(const char*)s2); #endif int i; i = s1.GetLength()+s2.GetLength(); if (i != 0) { if (m_iBufLen < i+1) { if (m_pData != NULL) delete[] m_pData; try { m_pData = new char[i+1]; } catch(...) { m_pData = NULL; } if (m_pData == NULL) NewException((double)(i+1)*sizeof(char),__FILE__,__LINE__,__PRETTY_FUNCTION__); m_iBufLen = i+1; ::strcpy(m_pData,s1.m_pData); } ::strcat(m_pData,s2.m_pData); } else { // m_iBufLen = 0; // m_pData = NULL; try { m_pData = new char[1]; } catch(...) { m_pData = NULL; } if (m_pData == NULL) NewException((double)1*sizeof(char),__FILE__,__LINE__,__PRETTY_FUNCTION__); m_pData[0] = 0; m_iBufLen = 1; } #ifdef DEBUG_CxString mprintf("done.\n"); #endif BXOUT; } CxString CxString::operator + (const CxString &s) const { #ifdef DEBUG_CxString mprintf("@ CxString::operator + (const CxString &) const: \"%s\", \"%s\"\n",m_pData,(const char*)s); #endif return CxString(*this,s); } bool CxString::operator == (const CxString &s) const { BXIN; #ifdef DEBUG_CxString mprintf("@ CxString::operator == (const CxString &) const: \"%s\", \"%s\"\n",m_pData,(const char*)s); #endif if (strcmp(m_pData,s.m_pData) == 0) { BXOUT; return true; } else { BXOUT; return false; } } bool CxString::operator != (const CxString &s) const { BXIN; #ifdef DEBUG_CxString mprintf("@ CxString::operator != (const CxString &) const: \"%s\", \"%s\"\n",m_pData,(const char*)s); #endif if (strcmp(m_pData,s.m_pData) == 0) { BXOUT; return false; } else { BXOUT; return true; } } bool CxString::operator > (const CxString &s) const { BXIN; #ifdef DEBUG_CxString mprintf("@ CxString::operator > (const CxString &) const: \"%s\", \"%s\"\n",m_pData,(const char*)s); #endif if (strcmp(m_pData,s.m_pData) > 0) { BXOUT; return true; } else { BXOUT; return false; } } bool CxString::operator < (const CxString &s) const { BXIN; #ifdef DEBUG_CxString mprintf("@ CxString::operator < (const CxString &) const: \"%s\", \"%s\"\n",m_pData,(const char*)s); #endif if (strcmp(m_pData,s.m_pData) < 0) { BXOUT; return true; } else { BXOUT; return false; } } bool CxString::operator >= (const CxString &s) const { BXIN; #ifdef DEBUG_CxString mprintf("@ CxString::operator >= (const CxString &) const: \"%s\", \"%s\"\n",m_pData,(const char*)s); #endif if (strcmp(m_pData,s.m_pData) >= 0) { BXOUT; return true; } else { BXOUT; return false; } } bool CxString::operator <= (const CxString &s) const { BXIN; #ifdef DEBUG_CxString mprintf("@ CxString::operator <= (const CxString &) const: \"%s\", \"%s\"\n",m_pData,(const char*)s); #endif if (strcmp(m_pData,s.m_pData) <= 0) { BXOUT; return true; } else { BXOUT; return false; } } void CxString::operator += (const CxString &s) { BXIN; #ifdef DEBUG_CxString mprintf("@ CxString::operator += (const CxString &): \"%s\", \"%s\"...",m_pData,(const char*)s); #endif strcat((const char*)s); #ifdef DEBUG_CxString mprintf("done.\n"); #endif BXOUT; } /*char& CxString::operator [] (int i) { #ifdef DEBUG_CxString mprintf("@ CxString::operator [] (int i): \"%s\", %d\n",m_pData,i); #endif if ((i < 0) || (i >= m_iBufLen)) { eprintf("Error: CxString::operator []: Boundary Error (%d/%d).\n",i,m_iBufLen); abort(); } return m_pData[i]; }*/ int CxString::FindFirst(char c) const { BXIN; #ifdef DEBUG_CxString mprintf("@ CxString::FindFirst(char) const: \"%s\", '%c'\n",m_pData,c); #endif char *p; p = strchr(m_pData,c); if (p == NULL) { BXOUT; return -1; } BXOUT; return (int)(p-m_pData); } int CxString::FindNext(int i, char c) const { BXIN; #ifdef DEBUG_CxString mprintf("@ CxString::FindNext(int, char) const: \"%s\", %d, '%c'\n",m_pData,i,c); #endif char *p; p = strchr(&m_pData[i],c); if (p == NULL) { BXOUT; return -1; } BXOUT; return (int)(p-m_pData); } int CxString::FindLast(char c) const { BXIN; #ifdef DEBUG_CxString mprintf("@ CxString::FindLast(char) const: \"%s\", '%c'\n",m_pData,c); #endif char *p; p = strrchr(m_pData,c); if (p == NULL) { BXOUT; return -1; } BXOUT; return (int)(p-m_pData); } CxString CxString::Mid(int pos, int count) const { BXIN; char *buf; try { buf = new char[count+1]; } catch(...) { buf = NULL; } if (buf == NULL) NewException((double)(count+1)*sizeof(char),__FILE__,__LINE__,__PRETTY_FUNCTION__); #ifdef DEBUG_CxString mprintf("@ CxString::Mid(int, int) const: \"%s\", %d, %d...",m_pData,pos,count); #endif ::memcpy(buf,&m_pData[pos],count); buf[count] = 0; #ifdef DEBUG_CxString mprintf("done: \"%s\"\n",buf); #endif CxString s = CxString(buf); delete[] buf; BXOUT; return s; } CxString CxString::Mid(int pos) const { BXIN; char *buf; try { buf = new char[strlen(&m_pData[pos])+1]; } catch(...) { buf = NULL; } if (buf == NULL) NewException((double)(strlen(&m_pData[pos])+1)*sizeof(char),__FILE__,__LINE__,__PRETTY_FUNCTION__); #ifdef DEBUG_CxString mprintf("@ CxString::Mid(int) const: \"%s\", %d...",m_pData,pos); #endif ::memcpy(buf,&m_pData[pos],strlen(&m_pData[pos])+1); #ifdef DEBUG_CxString mprintf("done: \"%s\"\n",buf); #endif CxString s = CxString(buf); delete[] buf; BXOUT; return s; } CxString CxString::Left(int count) const { BXIN; char *buf; try { buf = new char[count+1]; } catch(...) { buf = NULL; } if (buf == NULL) NewException((double)(count+1)*sizeof(char),__FILE__,__LINE__,__PRETTY_FUNCTION__); #ifdef DEBUG_CxString mprintf("@ CxString::Left(int) const: \"%s\", %d...",m_pData,count); #endif ::memcpy(buf,m_pData,count); buf[count] = 0; #ifdef DEBUG_CxString mprintf("done: \"%s\"\n",buf); #endif CxString s = CxString(buf); delete[] buf; BXOUT; return s; } void CxString::Dump() { BXIN; mprintf("%s",m_pData); BXOUT; } int CxString::Format_Internal(const char *s, int length, va_list params) { BXIN; int i; #ifdef DEBUG_CxString mprintf("@ CxString::Format_Internal(const char *s): \"%s\"...",s); #endif if (s == NULL) return 0; #ifdef TARGET_LINUX // First attempt: Try if string fits into TEMP_BUF_SIZE if (length == 0) { // Return value is the number of bytes (not including the terminal NULL character) // that should have been written to buffer if it was large enough i = vsnprintf(g_pTempBuf,TEMP_BUF_SIZE-1,s,params); // It fits if (i+1 <= TEMP_BUF_SIZE) { if (i+1 > m_iBufLen) { if (m_pData != NULL) delete[] m_pData; try { m_pData = new char[i+1]; } catch(...) { m_pData = NULL; } if (m_pData == NULL) NewException((double)(i+1)*sizeof(char),__FILE__,__LINE__,__PRETTY_FUNCTION__); ::strcpy(m_pData,g_pTempBuf); m_iBufLen = i+1; } else ::strcpy(m_pData,g_pTempBuf); return 0; } else // It does not fit - return required buffer size return i+1; } else // 2nd attempt with known buffer size { if (m_pData != NULL) delete[] m_pData; try { m_pData = new char[length+1]; } catch(...) { m_pData = NULL; } if (m_pData == NULL) NewException((double)(length+1)*sizeof(char),__FILE__,__LINE__,__PRETTY_FUNCTION__); vsnprintf(m_pData,length,s,params); m_iBufLen = length+1; return 0; } #else // First attempt: Try if string fits into TEMP_BUF_SIZE if (length == 0) { // Accept two different implementations for maximum compatibility: // (1) If the buffer is too small, the return value is negative (absolute value without any meaning) // (2) Like above in the TARGET_LINUX case #ifdef TARGET_WINDOWS i = _vsnprintf(g_pTempBuf,TEMP_BUF_SIZE-1,s,params); #else i = vsnprintf(g_pTempBuf,TEMP_BUF_SIZE-1,s,params); #endif // It fits if ((i >= 0) && (i+1 <= TEMP_BUF_SIZE)) { if (i+1 > m_iBufLen) { if (m_pData != NULL) delete[] m_pData; try { m_pData = new char[i+1]; } catch(...) { m_pData = NULL; } if (m_pData == NULL) NewException((double)(i+1)*sizeof(char),__FILE__,__LINE__,__PRETTY_FUNCTION__); ::strcpy(m_pData,g_pTempBuf); m_iBufLen = i+1; } else ::strcpy(m_pData,g_pTempBuf); return 0; } else // It does not fit - return larger guess for buffer size return 2*TEMP_BUF_SIZE; } else // n-th attempt { if (m_pData != NULL) delete[] m_pData; try { m_pData = new char[length]; } catch(...) { m_pData = NULL; } if (m_pData == NULL) NewException((double)(length)*sizeof(char),__FILE__,__LINE__,__PRETTY_FUNCTION__); m_iBufLen = length; #ifdef TARGET_WINDOWS i = _vsnprintf(m_pData,length-1,s,params); #else i = vsnprintf(m_pData,length-1,s,params); #endif // It fits if ((i >= 0) && (i+1 <= length)) return 0; else // It does not fit - return larger guess for buffer size return 2*length; } #endif #ifdef DEBUG_CxString mprintf("done.\n"); #endif BXOUT; } void CxString::Format(const char *s, ...) { #ifdef TARGET_LINUX XVSPRINTF_LINUX((*this),s,s); #else XVSPRINTF_WINDOWS((*this),s,s); #endif /* va_list params; int i; #ifdef TARGET_LINUX va_start(params, s); i = Format_Internal(s,0,params); va_end(params); if (i != 0) { va_start(params, s); Format_Internal(s,i,params); va_end(params); } #else i = 0; do { va_start(params, s); printf("Trying buffer size %d...\n",i); i = Format_Internal(s,i,params); va_end(params); } while (i != 0); #endif*/ } void CxString::sprintf(const char *s, ...) { #ifdef TARGET_LINUX XVSPRINTF_LINUX((*this),s,s); #else XVSPRINTF_WINDOWS((*this),s,s); #endif /* va_list params; int i; #ifdef TARGET_LINUX va_start(params, s); i = Format_Internal(s,0,params); va_end(params); if (i != 0) { va_start(params, s); Format_Internal(s,i,params); va_end(params); } #else i = 0; do { va_start(params, s); printf("Trying buffer size %d...\n",i); i = Format_Internal(s,i,params); va_end(params); } while (i != 0); #endif*/ } void CxString::strcat(const char *s) { int i, j; char *tmp; if (s == NULL) return; j = (int)strlen(s); if (j == 0) return; if (m_pData == NULL) { *this = CxString(s); return; } i = GetLength() + j; if (m_iBufLen >= i+1) { ::strcat(m_pData,s); } else { try { tmp = new char[i+1]; } catch(...) { tmp = NULL; } if (tmp == NULL) NewException((double)(i+1)*sizeof(char),__FILE__,__LINE__,__PRETTY_FUNCTION__); ::strcpy(tmp,m_pData); ::strcat(tmp,s); m_iBufLen = i+1; delete[] m_pData; m_pData = tmp; } } void CxString::strcpy(const char *s) { *this = CxString(s); } void CxString::SetBufSize(int i) { char *tmp; if (m_iBufLen >= i) return; try { tmp = new char[i]; } catch(...) { tmp = NULL; } if (tmp == NULL) NewException((double)i*sizeof(char),__FILE__,__LINE__,__PRETTY_FUNCTION__); if (m_pData != NULL) { ::memcpy(tmp,m_pData,m_iBufLen); delete[] m_pData; } m_iBufLen = i; m_pData = tmp; } void CxString::memcpy(const char *s, int size) { if (size > m_iBufLen) SetBufSize(size); ::memcpy(m_pData,s,size); } const char* CxString::fgets(int len, FILE *a) { if (m_iBufLen <= len) SetBufSize(len+1); return ::fgets(m_pData,len,a); } void CxString::ToLowercase() { if (m_pData != NULL) strtolower(m_pData); } /* void CxString::ToUppercase() { if (m_pData != NULL) strtoupper(m_pData); } */ char* CxString::GetWritePointer() { return m_pData; } travis-src-190101/src/xstring.h0100777000000000000000000001666013412725662013321 0ustar00/***************************************************************************** TRAVIS - Trajectory Analyzer and Visualizer http://www.travis-analyzer.de/ Copyright (c) 2009-2019 Martin Brehm 2012-2019 Martin Thomas 2016-2019 Sascha Gehrke This file was written by Martin Brehm. --------------------------------------------------------------------------- This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . *****************************************************************************/ #ifndef XSTRING_H #define XSTRING_H // This must always be the first include directive #include "config.h" #include "tools.h" #include "xobject.h" #include "backtrace.h" #define XVSPRINTF_LINUX(obj, format, pre) \ { \ va_list XXXparams; \ int XXXi; \ \ va_start(XXXparams, pre); \ XXXi = obj.Format_Internal(format,0,XXXparams); \ va_end(XXXparams); \ \ if (XXXi != 0) \ { \ va_start(XXXparams, pre); \ obj.Format_Internal(format,XXXi,XXXparams); \ va_end(XXXparams); \ } \ } #define XVSPRINTF_WINDOWS(obj, format, pre) \ { \ va_list XXXparams; \ int XXXi; \ \ XXXi = 0; \ do { \ va_start(XXXparams, pre); \ XXXi = obj.Format_Internal(format,XXXi,XXXparams); \ va_end(XXXparams); \ } while (XXXi != 0); \ } class CxString : public CxObject { public: //CxString(); //~CxString(); //CxString(const char *s); //CxString(const CxString &s); CxString(const CxString &s1, const CxString &s2); //operator const char*() const; //CxString & operator = (const CxString &s); CxString operator + (const CxString &s) const; bool operator == (const CxString &s) const; bool operator != (const CxString &s) const; bool operator > (const CxString &s) const; bool operator < (const CxString &s) const; bool operator >= (const CxString &s) const; bool operator <= (const CxString &s) const; void operator += (const CxString &s); // char& operator [] (int i); //char& operator () (int i); //int GetLength() const; int FindFirst(char c) const; int FindNext(int i, char c) const; int FindLast(char c) const; CxString Mid(int pos, int count) const; CxString Mid(int pos) const; CxString Left(int count) const; #ifdef __GNUG__ // Variadic Argument Type Checking of GCC void Format(const char *s, ...) __attribute__ ((format (printf, 2, 3))); void sprintf(const char *s, ...) __attribute__ ((format (printf, 2, 3))); #else void Format(const char *s, ...); void sprintf(const char *s, ...); #endif // void vsprintf(const char *s, va_list params); void strcat(const char *s); void strcpy(const char *s); void memcpy(const char *s, int size); void Dump(); void SetBufSize(int i); const char* fgets(int len, FILE *a); void ToLowercase(); // void ToUppercase(); char* GetWritePointer(); int Format_Internal(const char *s, int length, va_list params); CxString() { BXIN; #ifdef DEBUG_CxString mprintf("@ CxString::CxString()\n"); #endif try { m_pData = new char[1]; } catch(...) { m_pData = NULL; } if (m_pData == NULL) NewException((double)1*sizeof(char),__FILE__,__LINE__,__PRETTY_FUNCTION__); m_pData[0] = 0; m_iBufLen = 1; BXOUT; } ~CxString() { BXIN; #ifdef DEBUG_CxString mprintf("@ CxString::~CxString(): \"%s\"...",m_pData); #endif if (m_pData != NULL) { delete[] m_pData; m_pData = NULL; } m_iBufLen = 0; #ifdef DEBUG_CxString mprintf("done.\n"); #endif BXOUT; } CxString(const char *s) { BXIN; #ifdef DEBUG_CxString mprintf("@ CxString::CxString(const char *): \"%s\"...",s); #endif int i; if (s == NULL) { eprintf("CxString::CxString(const char *): NULL pointer passed.\n"); abort(); } i = (int)strlen(s); try { m_pData = new char[i+1]; } catch(...) { m_pData = NULL; } if (m_pData == NULL) NewException((double)(i+1)*sizeof(char),__FILE__,__LINE__,__PRETTY_FUNCTION__); ::strcpy(m_pData,s); m_iBufLen = i+1; #ifdef DEBUG_CxString mprintf("done.\n"); #endif BXOUT; } CxString(const CxString &s) : CxObject() { BXIN; #ifdef DEBUG_CxString mprintf("@ CxString::CxString(const CxString &): \"%s\"...",(const char*)s); #endif int i; i = s.GetLength(); try { m_pData = new char[i+1]; } catch(...) { m_pData = NULL; } if (m_pData == NULL) NewException((double)(i+1)*sizeof(char),__FILE__,__LINE__,__PRETTY_FUNCTION__); ::strcpy(m_pData,s.m_pData); m_iBufLen = i+1; #ifdef DEBUG_CxString mprintf("done.\n"); #endif BXOUT; } CxString & operator = (const CxString &s) { int i; i = s.GetLength(); if (i+1 > m_iBufLen) { if (m_pData != NULL) delete[] m_pData; try { m_pData = new char[i+1]; } catch(...) { m_pData = NULL; } if (m_pData == NULL) NewException((double)(i+1)*sizeof(char),__FILE__,__LINE__,__PRETTY_FUNCTION__); ::strcpy(m_pData,s.m_pData); m_iBufLen = i+1; } else ::strcpy(m_pData,s.m_pData); return *this; } operator const char*() const { #ifdef DEBUG_CxString mprintf("@ CxString::operator const char* () const: \"%s\"\n",m_pData); #endif return m_pData; } char& operator () (int i) { #ifdef DEBUG_CxString mprintf("@ CxString::operator () (int i): \"%s\", %d\n",m_pData,i); #endif if ((i < 0) || (i >= m_iBufLen)) { eprintf("Error: CxString::operator (): Boundary Error (%d/%d).\n",i,m_iBufLen); abort(); } return m_pData[i]; } char operator () (int i) const { #ifdef DEBUG_CxString mprintf("@ CxString::operator () (int i): \"%s\", %d\n",m_pData,i); #endif if ((i < 0) || (i >= m_iBufLen)) { eprintf("Error: CxString::operator (): Boundary Error (%d/%d).\n",i,m_iBufLen); abort(); } return m_pData[i]; } int GetLength() const { #ifdef DEBUG_CxString mprintf("@ CxString::GetLength() const: \"%s\", %d\n",m_pData,strlen(m_pData)); #endif if (m_pData != NULL) return (int)strlen(m_pData); else return 0; } private: char *m_pData; int m_iBufLen; }; CxString operator + (const char *s1, const CxString& s2); #endif travis-src-190101/src/xwordarray.cpp0100777000000000000000000002413613412725617014355 0ustar00/***************************************************************************** TRAVIS - Trajectory Analyzer and Visualizer http://www.travis-analyzer.de/ Copyright (c) 2009-2019 Martin Brehm 2012-2019 Martin Thomas 2016-2019 Sascha Gehrke This file was written by Martin Brehm. --------------------------------------------------------------------------- This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . *****************************************************************************/ // This must always be the first include directive #include "config.h" #include "xwordarray.h" const char *GetRevisionInfo_xwordarray(unsigned int len) { static char buf[256]; GET_REVISION_INFO( buf, len ); return buf; } const char *GetSourceVersion_xwordarray() { static char buf[256]; GET_SOURCE_VERSION( buf ); return buf; } #ifndef DEBUG_ARRAYS #define m_sName (NULL) #endif CxWordArray::CxWordArray() { BXIN; #ifdef DEBUG_CWORDARRAY mprintf("@ CxWordArray::CxWordArray()\n"); #endif m_pData = NULL; m_iSize = 0; m_iMaxSize = 0; m_iGrow = 16; #ifdef DEBUG_ARRAYS m_sName = NULL; #endif BXOUT; } CxWordArray::CxWordArray(const char *name) { BXIN; #ifdef DEBUG_CWORDARRAY mprintf("@ CxWordArray::CxWordArray(const char *)\n"); #endif m_pData = NULL; m_iSize = 0; m_iMaxSize = 0; m_iGrow = 16; #ifdef DEBUG_ARRAYS m_sName = NULL; #endif SetName(name); BXOUT; } CxWordArray::~CxWordArray() { BXIN; #ifdef DEBUG_CWORDARRAY mprintf("@ CxWordArray::~CxWordArray()\n"); #endif RemoveAll(); #ifdef DEBUG_ARRAYS if (m_sName != NULL) { delete[] m_sName; m_sName = NULL; } #endif BXOUT; } CxWordArray::CxWordArray(const CxWordArray &o) : CxObject() { BXIN; #ifdef DEBUG_CWORDARRAY mprintf("@ CxWordArray::CxWordArray(CxWordArray &)..."); #endif unsigned long z; m_iGrow = o.m_iGrow; if ((o.m_iMaxSize != 0) && (o.m_pData != NULL)) { m_iSize = o.m_iSize; m_iMaxSize = o.m_iMaxSize; try { m_pData = new unsigned short[m_iMaxSize]; } catch(...) { m_pData = NULL; } if (m_pData == NULL) NewException((double)m_iMaxSize*sizeof(unsigned short),__FILE__,__LINE__,__PRETTY_FUNCTION__,m_sName); for (z=0;zm_iMaxSize) { m_iMaxSize = o->m_iMaxSize; if (m_pData != NULL) delete[] m_pData; try { m_pData = new unsigned short[m_iMaxSize]; } catch(...) { m_pData = NULL; } if (m_pData == NULL) NewException((double)m_iMaxSize*sizeof(unsigned short),__FILE__,__LINE__,__PRETTY_FUNCTION__,m_sName); } m_iSize = o->m_iSize; m_iGrow = o->m_iGrow; if (o->m_pData != NULL) memcpy(m_pData,o->m_pData,m_iSize*sizeof(unsigned short)); #ifdef DEBUG_CWORDARRAY mprintf("done.\n"); #endif BXOUT; } void CxWordArray::Append(CxWordArray *o) { BXIN; #ifdef DEBUG_CWORDARRAY mprintf("@ CxWordArray::Append(CxWordArray*)..."); #endif // unsigned long z; if (m_iSize+o->m_iSize > m_iMaxSize) SetMaxSize(m_iSize+o->m_iSize); // for (z=0;zm_iSize;z++) // m_pData[m_iSize+z] = o->m_pData[z]; if (o->m_pData != NULL) memcpy(&m_pData[m_iSize],o->m_pData,o->m_iSize*sizeof(unsigned short)); m_iSize += o->m_iSize; #ifdef DEBUG_CWORDARRAY mprintf("done.\n"); #endif BXOUT; } void CxWordArray::SetAt(unsigned long pos, unsigned short f) { BXIN; // unsigned long z; #ifdef DEBUG_CWORDARRAY bool s = false; mprintf("@ CxWordArray::Add(unsigned short)..."); #endif if (pos >= m_iMaxSize) { #ifdef DEBUG_CWORDARRAY s = true; mprintf("\n"); #endif SetMaxSize(pos+1); } m_pData[pos] = f; if (pos >= m_iSize) // { // for (z=m_iSize;z m_iMaxSize) { #ifdef DEBUG_CWORDARRAY s = true; mprintf("\n"); #endif // SetMaxSize(m_iMaxSize + m_iGrow); if (m_iMaxSize == 0) SetMaxSize(m_iMaxSize + m_iGrow); else SetMaxSize(m_iMaxSize*2); } m_pData[m_iSize] = f; m_iSize++; #ifdef DEBUG_CWORDARRAY if (s) mprintf("@ done.\n"); else mprintf("done.\n"); #endif BXOUT; } void CxWordArray::SetSize(unsigned long i) { BXIN; #ifdef DEBUG_CWORDARRAY mprintf("@ CxWordArray::SetSize(int): %d...",i); #endif if (m_iSize == i) return; unsigned short *temp; try { temp = new unsigned short[i]; } catch(...) { temp = NULL; } if (temp == NULL) NewException((double)i*sizeof(unsigned short),__FILE__,__LINE__,__PRETTY_FUNCTION__,m_sName); if (m_pData != NULL) { if (m_iSize > i) memcpy(temp,m_pData,i*sizeof(unsigned short)); else memcpy(temp,m_pData,m_iSize*sizeof(unsigned short)); delete[] m_pData; } m_pData = temp; m_iMaxSize = i; m_iSize = i; #ifdef DEBUG_CWORDARRAY mprintf("done.\n"); #endif BXOUT; } void CxWordArray::GrowBy(unsigned long i) { BXIN; #ifdef DEBUG_CWORDARRAY mprintf("@ CxWordArray::GrowBy(unsigned long): %d...",i); #endif if (i == 0) return; unsigned short *temp; try { temp = new unsigned short[m_iSize+i]; } catch(...) { temp = NULL; } if (temp == NULL) NewException((double)(m_iSize+i)*sizeof(unsigned short),__FILE__,__LINE__,__PRETTY_FUNCTION__,m_sName); if (m_pData != NULL) { memcpy(temp,m_pData,m_iSize*sizeof(unsigned short)); delete[] m_pData; } m_pData = temp; m_iMaxSize = i; m_iSize = i; #ifdef DEBUG_CWORDARRAY mprintf("done.\n"); #endif BXOUT; } void CxWordArray::SetMaxSize(unsigned long i) { BXIN; #ifdef DEBUG_CWORDARRAY mprintf("@ CxWordArray::SetMaxSize(int): %d...",i); #endif unsigned short *temp; try { temp = new unsigned short[i]; } catch(...) { temp = NULL; } if (temp == NULL) NewException((double)i*sizeof(unsigned short),__FILE__,__LINE__,__PRETTY_FUNCTION__,m_sName); if (m_pData != NULL) { memcpy(temp,m_pData,m_iSize*sizeof(unsigned short)); delete[] m_pData; } m_pData = temp; m_iMaxSize = i; #ifdef DEBUG_CWORDARRAY mprintf("done.\n"); #endif BXOUT; } void CxWordArray::SetGrow(unsigned long i) { BXIN; #ifdef DEBUG_CWORDARRAY mprintf("@ CxWordArray::SetGrow(int): %d\n",i); #endif m_iGrow = i; BXOUT; } void CxWordArray::RemoveAll() { BXIN; #ifdef DEBUG_CWORDARRAY mprintf("@ CxWordArray::RemoveAll():..."); #endif if (m_pData != NULL) delete[] m_pData; m_pData = NULL; m_iSize = 0; m_iMaxSize = 0; #ifdef DEBUG_CWORDARRAY mprintf("done.\n"); #endif BXOUT; } void CxWordArray::RemoveAll_KeepSize() { BXIN; #ifdef DEBUG_CWORDARRAY mprintf("@ CxWordArray::RemoveAll_KeepSize():..."); #endif m_iSize = 0; #ifdef DEBUG_CWORDARRAY mprintf("done.\n"); #endif BXOUT; } void CxWordArray::RemoveAt(unsigned long pos, unsigned long count) { BXIN; unsigned short *temp; #ifdef DEBUG_CWORDARRAY mprintf("@ CxWordArray::RemoveAt(int, int): %d, %d...",pos,count); #endif try { temp = new unsigned short[m_iSize-count]; } catch(...) { temp = NULL; } if (temp == NULL) NewException((double)(m_iSize-count)*sizeof(unsigned short),__FILE__,__LINE__,__PRETTY_FUNCTION__,m_sName); if (m_pData != NULL) { memcpy(temp,m_pData,pos*sizeof(unsigned short)); memcpy(&temp[pos],&m_pData[pos+count],(m_iSize-pos-count)*sizeof(unsigned short)); delete[] m_pData; } m_pData = temp; m_iSize-=count; m_iMaxSize = m_iSize; #ifdef DEBUG_CWORDARRAY mprintf("done.\n"); #endif BXOUT; } void CxWordArray::RemoveAt_KeepSize(unsigned long pos, unsigned long count) { BXIN; unsigned short *temp; #ifdef DEBUG_CWORDARRAY mprintf("@ CxWordArray::RemoveAt_KeepSize(int, int): %d, %d...",pos,count); #endif try { temp = new unsigned short[m_iMaxSize]; } catch(...) { temp = NULL; } if (temp == NULL) NewException((double)m_iMaxSize*sizeof(unsigned short),__FILE__,__LINE__,__PRETTY_FUNCTION__,m_sName); if (m_pData != NULL) { memcpy(temp,m_pData,pos*sizeof(unsigned short)); memcpy(&temp[pos],&m_pData[pos+count],(m_iSize-pos-count)*sizeof(unsigned short)); delete[] m_pData; } m_pData = temp; m_iSize-=count; #ifdef DEBUG_CWORDARRAY mprintf("done.\n"); #endif BXOUT; } void CxWordArray::InsertAt(unsigned short f, unsigned long pos) { BXIN; unsigned short *temp; #ifdef DEBUG_CWORDARRAY mprintf("@ CxWordArray::InsertAt(unsigned short, int): %d..."); #endif try { temp = new unsigned short[m_iSize+1]; } catch(...) { temp = NULL; } if (temp == NULL) NewException((double)(m_iSize+1)*sizeof(unsigned short),__FILE__,__LINE__,__PRETTY_FUNCTION__,m_sName); if (m_pData != NULL) { memcpy(temp,m_pData,pos*sizeof(unsigned short)); memcpy(&temp[pos+1],&m_pData[pos],(m_iSize-pos)*sizeof(unsigned short)); delete[] m_pData; } temp[pos] = f; m_pData = temp; m_iSize++; m_iMaxSize = m_iSize; #ifdef DEBUG_CWORDARRAY mprintf("done.\n"); #endif BXOUT; } void CxWordArray::SetName(const char *name) { UNUSED(name); #ifdef DEBUG_ARRAYS BXIN; #ifdef DEBUG_CWORDARRAY mprintf("@ CxWordArray::SetName(const char *): \"%s\"...",name); #endif if (m_sName != NULL) delete[] m_sName; try { m_sName = new char[strlen(name)+1]; } catch(...) { m_sName = NULL; } if (m_sName == NULL) NewException((double)(strlen(name)+1)*sizeof(char),__FILE__,__LINE__,__PRETTY_FUNCTION__); strcpy(m_sName,name); #ifdef DEBUG_CWORDARRAY mprintf("done.\n"); #endif BXOUT; #endif } travis-src-190101/src/xwordarray.h0100777000000000000000000000743713412725661014026 0ustar00/***************************************************************************** TRAVIS - Trajectory Analyzer and Visualizer http://www.travis-analyzer.de/ Copyright (c) 2009-2019 Martin Brehm 2012-2019 Martin Thomas 2016-2019 Sascha Gehrke This file was written by Martin Brehm. --------------------------------------------------------------------------- This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . *****************************************************************************/ #ifndef XWORDARRAY_H #define XWORDARRAY_H // This must always be the first include directive #include "config.h" #include "tools.h" #include "xobject.h" #include "backtrace.h" class CxWordArray : public CxObject { public: CxWordArray(); ~CxWordArray(); CxWordArray(const CxWordArray &o); explicit CxWordArray(const char *name); void SetName(const char *name); void CopyFrom(CxWordArray *o); void Add(unsigned short f); void Append(CxWordArray *o); void SetAt(unsigned long pos, unsigned short f); void GrowBy(unsigned long i); void SetSize(unsigned long i); void SetMaxSize(unsigned long i); void SetGrow(unsigned long i); void RemoveAll(); void RemoveAll_KeepSize(); void RemoveAt(unsigned long pos, unsigned long count); void RemoveAt_KeepSize(unsigned long pos, unsigned long count); void InsertAt(unsigned short f, unsigned long pos); bool Contains(unsigned short i) { BXIN; int z; for (z=0;z<(int)m_iSize;z++) if (m_pData[z] == i) return true; BXOUT; return false; } int GetPosition(unsigned short i) { BXIN; int z; for (z=0;z<(int)m_iSize;z++) if (m_pData[z] == i) return z; BXOUT; return -1; } unsigned short &GetAt(unsigned long i) { BXIN; #ifdef DEBUG_CWORDARRAY mprintf("@ CxWordArray::GetAt(int): %d...",i); #endif #ifdef DEBUG_ARRAYS if (i >= m_iSize) { if (m_sName != NULL) eprintf("CxWordArray \"%s\" Boundary Error (%lu/%lu).\n",m_sName,i,m_iSize); else eprintf("CxWordArray Boundary Error (%lu/%lu).\n",i,m_iSize); abort(); } #endif #ifdef DEBUG_CWORDARRAY mprintf("done.\n"); #endif BXOUT; return m_pData[i]; } unsigned short &operator [] (unsigned long i) { #ifdef DEBUG_CWORDARRAY mprintf("@ CxWordArray::operator [] (int): %d\n",i); #endif return GetAt(i); } unsigned short GetAt(unsigned long i) const { BXIN; #ifdef DEBUG_CWORDARRAY mprintf("@ CxWordArray::GetAt(int): %d...",i); #endif #ifdef DEBUG_ARRAYS if (i >= m_iSize) { if (m_sName != NULL) eprintf("CxWordArray \"%s\" Boundary Error (%lu/%lu).\n",m_sName,i,m_iSize); else eprintf("CxWordArray Boundary Error (%lu/%lu).\n",i,m_iSize); abort(); } #endif #ifdef DEBUG_CWORDARRAY mprintf("done.\n"); #endif BXOUT; return m_pData[i]; } unsigned short operator [] (unsigned long i) const { #ifdef DEBUG_CWORDARRAY mprintf("@ CxWordArray::operator [] (int): %d\n",i); #endif return GetAt(i); } int GetSize() { #ifdef DEBUG_CWORDARRAY mprintf("@ CxWordArray::GetSize(): %d\n",m_iSize); #endif return m_iSize; } private: unsigned short *m_pData; unsigned long m_iSize; unsigned long m_iMaxSize; unsigned long m_iGrow; #ifdef DEBUG_ARRAYS char *m_sName; #endif }; #endif travis-src-190101/src/ziggurat.cpp0100777000000000000000000002661313412725627014012 0ustar00/***************************************************************************** TRAVIS - Trajectory Analyzer and Visualizer http://www.travis-analyzer.de/ Copyright (c) 2009-2019 Martin Brehm 2012-2019 Martin Thomas 2016-2019 Sascha Gehrke --------------------------------------------------------------------------- This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . *****************************************************************************/ /******************************************************************************/ /* Licensing: This code is distributed under the GNU LGPL license. Modified: 09 December 20080 Author: John Burkardt Reference: George Marsaglia, Wai Wan Tsang, The Ziggurat Method for Generating Random Variables, Journal of Statistical Software, Volume 5, Number 8, October 2000, seven pages. */ // This must always be the first include directive #include "config.h" # include # include # include # include #include "ziggurat.h" #include "tools.h" const char *GetRevisionInfo_ziggurat(unsigned int len) { static char buf[256]; GET_REVISION_INFO( buf, len ); return buf; } const char *GetSourceVersion_ziggurat() { static char buf[256]; GET_SOURCE_VERSION( buf ); return buf; } /******************************************************************************/ double r4_exp ( unsigned long int *jsr, int ke[256], double fe[256], double we[256] ) /******************************************************************************/ /* Purpose: R4_EXP returns an exponentially distributed single precision real value. Discussion: The underlying algorithm is the ziggurat method. Before the first call to this function, the user must call R4_EXP_SETUP to determine the values of KE, FE and WE. Licensing: This code is distributed under the GNU LGPL license. Modified: 09 December 20080 Author: John Burkardt Reference: George Marsaglia, Wai Wan Tsang, The Ziggurat Method for Generating Random Variables, Journal of Statistical Software, Volume 5, Number 8, October 2000, seven pages. Parameters: Input/output, unsigned long int *JSR, the seed. Input, int KE[256], data computed by R4_EXP_SETUP. Input, double FE[256], WE[256], data computed by R4_EXP_SETUP. Output, double R4_EXP, an exponentially distributed random value. */ { int iz; int jz; double value; double x; jz = shr3 ( jsr ); iz = ( jz & 255 ); if ( abs ( jz ) < ke[iz] ) { value = ( double ) ( abs ( jz ) ) * we[iz]; } else { for ( ; ; ) { if ( iz == 0 ) { value = 7.69711 - log ( r4_uni ( jsr ) ); break; } x = ( double ) ( abs ( jz ) ) * we[iz]; if ( fe[iz] + r4_uni ( jsr ) * ( fe[iz-1] - fe[iz] ) < exp ( - x ) ) { value = x; break; } jz = shr3 ( jsr ); iz = ( jz & 255 ); if ( abs ( jz ) < ke[iz] ) { value = ( double ) ( abs ( jz ) ) * we[iz]; break; } } } return value; } /******************************************************************************/ void r4_exp_setup ( int ke[256], double fe[256], double we[256] ) /******************************************************************************/ /* Purpose: R4_EXP_SETUP sets data needed by R4_EXP. Licensing: This code is distributed under the GNU LGPL license. Modified: 09 December 2008 Author: John Burkardt Reference: George Marsaglia, Wai Wan Tsang, The Ziggurat Method for Generating Random Variables, Journal of Statistical Software, Volume 5, Number 8, October 2000, seven pages. Parameters: Output, int KE[256], data needed by R4_EXP. Output, double FE[256], WE[256], data needed by R4_EXP. */ { double de = 7.697117470131487; int i; const double m2 = 2147483648.0; double q; double te = 7.697117470131487; const double ve = 3.949659822581572E-03; q = ve / exp ( - de ); ke[0] = ( int ) ( ( de / q ) * m2 ); ke[1] = 0; we[0] = ( double ) ( q / m2 ); we[255] = ( double ) ( de / m2 ); fe[0] = 1.0; fe[255] = ( double ) ( exp ( - de ) ); for ( i = 254; 1 <= i; i-- ) { de = - log ( ve / de + exp ( - de ) ); ke[i+1] = ( int ) ( ( de / te ) * m2 ); te = de; fe[i] = ( double ) ( exp ( - de ) ); we[i] = ( double ) ( de / m2 ); } return; } /******************************************************************************/ double r4_nor ( unsigned long int *jsr, int kn[128], double fn[128], double wn[128] ) /******************************************************************************/ /* Purpose: R4_NOR returns a normally distributed single precision real value. Discussion: The value returned is generated from a distribution with mean 0 and variance 1. The underlying algorithm is the ziggurat method. Before the first call to this function, the user must call R4_NOR_SETUP to determine the values of KN, FN and WN. Licensing: This code is distributed under the GNU LGPL license. Modified: 09 December 2008 Author: John Burkardt Reference: George Marsaglia, Wai Wan Tsang, The Ziggurat Method for Generating Random Variables, Journal of Statistical Software, Volume 5, Number 8, October 2000, seven pages. Parameters: Input/output, unsigned long int *JSR, the seed. Input, int KN[128], data computed by R4_NOR_SETUP. Input, double FN[128], WN[128], data computed by R4_NOR_SETUP. Output, double R4_NOR, a normally distributed random value. */ { int hz; int iz; const double r = 3.442620; double value; double x; // double y; hz = shr3 ( jsr ); iz = ( hz & 127 ); if ( abs ( hz ) < kn[iz] ) { value = ( double ) ( hz ) * wn[iz]; } else { for ( ; ; ) { if ( iz == 0 ) { // for ( ; ; ) // { x = - 0.2904764 * log ( r4_uni ( jsr ) ); // y = - log ( r4_uni ( jsr ) ); // if ( x * x <= y + y ); // Martin B. doesn't understand this // { // break; // } // } if ( hz <= 0 ) { value = - r - x; } else { value = + r + x; } break; } x = ( double ) ( hz ) * wn[iz]; if ( fn[iz] + r4_uni ( jsr ) * ( fn[iz-1] - fn[iz] ) < exp ( - 0.5 * x * x ) ) { value = x; break; } hz = shr3 ( jsr ); iz = ( hz & 127 ); if ( abs ( hz ) < kn[iz] ) { value = ( double ) ( hz ) * wn[iz]; break; } } } return value; } /******************************************************************************/ void r4_nor_setup ( int kn[128], double fn[128], double wn[128] ) /******************************************************************************/ /* Purpose: R4_NOR_SETUP sets data needed by R4_NOR. Licensing: This code is distributed under the GNU LGPL license. Modified: 09 December 2008 Author: John Burkardt Reference: George Marsaglia, Wai Wan Tsang, The Ziggurat Method for Generating Random Variables, Journal of Statistical Software, Volume 5, Number 8, October 2000, seven pages. Parameters: Output, int KN[128], data needed by R4_NOR. Output, double FN[128], WN[128], data needed by R4_NOR. */ { double dn = 3.442619855899; int i; const double m1 = 2147483648.0; double q; double tn = 3.442619855899; const double vn = 9.91256303526217E-03; q = vn / exp ( - 0.5 * dn * dn ); kn[0] = ( int ) ( ( dn / q ) * m1 ); kn[1] = 0; wn[0] = ( double ) ( q / m1 ); wn[127] = ( double ) ( dn / m1 ); fn[0] = 1.0; fn[127] = ( double ) ( exp ( - 0.5 * dn * dn ) ); for ( i = 126; 1 <= i; i-- ) { dn = sqrt ( - 2.0 * log ( vn / dn + exp ( - 0.5 * dn * dn ) ) ); kn[i+1] = ( int ) ( ( dn / tn ) * m1 ); tn = dn; fn[i] = ( double ) ( exp ( - 0.5 * dn * dn ) ); wn[i] = ( double ) ( dn / m1 ); } return; } /******************************************************************************/ double r4_uni ( unsigned long int *jsr ) /******************************************************************************/ /* Purpose: R4_UNI returns a uniformly distributed real value. Licensing: This code is distributed under the GNU LGPL license. Modified: 09 December 2008 Author: John Burkardt Reference: George Marsaglia, Wai Wan Tsang, The Ziggurat Method for Generating Random Variables, Journal of Statistical Software, Volume 5, Number 8, October 2000, seven pages. Parameters: Input/output, unsigned long int *JSR, the seed. Output, double R4_UNI, a uniformly distributed random value in the range [0,1]. */ { unsigned long int jsr_input; double value; jsr_input = *jsr; *jsr = ( *jsr ^ ( *jsr << 13 ) ); *jsr = ( *jsr ^ ( *jsr >> 17 ) ); *jsr = ( *jsr ^ ( *jsr << 5 ) ); value = (double)fmod ( 0.5 + ( double ) ( jsr_input + *jsr ) / 65536.0 / 65536.0, 1.0 ); return value; } /******************************************************************************/ unsigned long int shr3 ( unsigned long int *jsr ) /******************************************************************************/ /* Purpose: SHR3 evaluates the SHR3 generator for integers. Licensing: This code is distributed under the GNU LGPL license. Modified: 09 December 2008 Author: John Burkardt Reference: George Marsaglia, Wai Wan Tsang, The Ziggurat Method for Generating Random Variables, Journal of Statistical Software, Volume 5, Number 8, October 2000, seven pages. Parameters: Input/output, unsigned long int *JSR, the seed, which is updated on each call. Output, unsigned long int SHR3, the new value. */ { unsigned long int value; value = *jsr; *jsr = ( *jsr ^ ( *jsr << 13 ) ); *jsr = ( *jsr ^ ( *jsr >> 17 ) ); *jsr = ( *jsr ^ ( *jsr << 5 ) ); value = value + *jsr; return value; } /******************************************************************************/ void timestamp ( void ) /******************************************************************************/ /* Purpose: TIMESTAMP prints the current YMDHMS date as a time stamp. Example: 31 May 2001 09:45:54 AM Licensing: This code is distributed under the GNU LGPL license. Modified: 24 September 2003 Author: John Burkardt Parameters: None */ { # define TIME_SIZE 40 static char time_buffer[TIME_SIZE]; const struct tm *tm; size_t len; time_t now; now = time ( NULL ); tm = localtime ( &now ); len = strftime ( time_buffer, TIME_SIZE, "%d %B %Y %I:%M:%S %p", tm ); UNUSED(len); // Avoid "unused parameter" warning mprintf ( "%s\n", time_buffer ); return; # undef TIME_SIZE } travis-src-190101/src/ziggurat.h0100777000000000000000000000405013412725655013447 0ustar00/***************************************************************************** TRAVIS - Trajectory Analyzer and Visualizer http://www.travis-analyzer.de/ Copyright (c) 2009-2019 Martin Brehm 2012-2019 Martin Thomas 2016-2019 Sascha Gehrke --------------------------------------------------------------------------- This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . *****************************************************************************/ /******************************************************************************/ /* Licensing: This code is distributed under the GNU LGPL license. Modified: 09 December 20080 Author: John Burkardt Reference: George Marsaglia, Wai Wan Tsang, The Ziggurat Method for Generating Random Variables, Journal of Statistical Software, Volume 5, Number 8, October 2000, seven pages. */ #ifndef ZIGGURAT_H #define ZIGGURAT_H // This must always be the first include directive #include "config.h" double r4_exp ( unsigned long int *jsr, int ke[256], double fe[256], double we[256] ); void r4_exp_setup ( int ke[256], double fe[256], double we[256] ); double r4_nor ( unsigned long int *jsr, int kn[128], double fn[128], double wn[128] ); void r4_nor_setup ( int kn[128], double fn[128], double wn[128] ); double r4_uni ( unsigned long int *jsr ); unsigned long int shr3 ( unsigned long int *jsr ); void timestamp ( void ); #endif travis-src-190101/travis-quickstart.pdf0100777000000000000000000026415111615317565015060 0ustar00%PDF-1.5 % 74 0 obj <> endobj 85 0 obj <>/Filter/FlateDecode/ID[<72A065978ADC8F8A791BDF4831C72D50><9B3220BBC5A5F9428B5A339FDEB4EF2A>]/Index[74 32]/Info 73 0 R/Length 69/Prev 91837/Root 75 0 R/Size 106/Type/XRef/W[1 2 1]>>stream hbbd``b`$C`R  $dAꪁW Tp6w  endstream endobj startxref 0 %%EOF 105 0 obj <>stream hb```f``Rr   '"ۙ3 3hlaʼYPөa aD ÄLN)R@v *j6VqRg`t 98!E0vY`K``pM+f`  S&Br2C+1 endstream endobj 75 0 obj <> endobj 76 0 obj <> endobj 77 0 obj <>stream hXRH~s^U`! KIH1<`%H2K~N`ynG,2,9"CbMI8D`#d\cAn\3!/6LhvDCLl'tJȤ CT8*).]dJj޾NewkTUzw]ouv[]'];Y56C'3h;1]׃^nITk/RS0;e76gk&sBG{m= ct֓ʞ1@LgIVYTvXHݵa+GŨ_]ڍܖ6Xp.Lj2-Ψʒj@lYP[ t^K:O/-U5ӊh:L@Ei>GD;K{O逺ԣCB_NOgwA )F, %TQMc+Ÿd'jy8K Zշy 1 u{^ jMLAR?!d18#8g r8{ @S 8,4 "-Xl :> PP@L#mЇ7aWT%׋FlEhxqyG7ai3՛;ͬ`qIױ -m~[+Ev懻uivrdk ڮ,euk;D/Q]t.6q9~.?xIӲlr)ig8gOk'%^q2lw'!}MAu4+ ^a1fZxfFM?7 &Ka墈uSH}FEp/]2TB292AEzHHJAW_3U Y"=|p"{+'dA[Fa߂/!$=;.#%%󺩕M40h`ge/mΔ<Ŝ>H4m 3'tAjmëg,H=5%n>stream h޴wiXTW.2r,SIq8G<2( 2T@QTQ# 5B1LRP" 8k58t6jt;m~~~p{ ^]k9;yfOu[|DE']x3;G㱟 8f<4ۏN.XkߝGmOHO'`Y.<>T#=)Y-.,>1!>P(|$Q(1ձ8oK%,>%.91J4o;DEj g'TYN;89rysV|pevQr~$vm2lfS-?G'~38vԱom7a w 7{w? 3וvͧtDO<3䍓/ݜ|ʍ~m3?!]`+8F qX39!(^ yl-gNGFGt h\s%tṼM^7W^rnO]px<@ghV 3a.،V sCyj}hm0ÌBn~ͅ;\Y˰rQҺmTyN)RfFe* KJ^tA๰ްepY~3="$NokWU{6 [ip;w3HKwɍW>ȚB'|&w2ʣ_Z+˩ҺFߥUHpay~7uBnAu0vG}?3☠^Ǽc1yOmR/eF\ɥJj@ RK ^DY3+Ț2AWk .?(#LU .7;t$ORBHf/k̥s73gr>3l7zvАm8tGy|G*EA՝ {w}O7,na[%Vre&ao]9'2\M/F *L&Y@jh́5 <}M OVt Wb;OoV^UP#q412#rnfC-;ؠҿfͪ- Ixɕʅ/ -![ ~bQR#H+n(h%~;n@wejAƪJ2+9GGBLh['>Rڧ9v~kC|8a6ŗ-*6N0~ 7 `\0h@L"܆~zsʅJ);*9YR!a{nIj(X0s+&;ɲ^SdYA&h)yϚa+/mOztZ*>ďI(0dSM^eL!+bx Hz1JIcc_]/&Q8T+v+֐ĈOOzrPAe!E{T5qZ-%ܦtgt-EKVD#l(QUMaq}>̰qK9b⾮& U^Ġ:rĕ 1ѭSU&QUi 4!d!FaF4s\{GR I:]<?{ [=5 qdva.;溰 {P:Uh- B4 㫏h60h0-S#yhk`*+. =p鮁i.]ջQ oK_')R_P&{/׀an%MU|ϕB^/(֗W݌@_y$"5XUDZvۍ$ oC^g(+6d%{|䉤h"ۊK>A:gET'jQ7?n Xx>g}^|@WzҖlOI8.ET:lIjRmzDe˽?2τ5‚̋ ߶ڔ17PdudE;֐m~*ҖW)/ͻB;;UC#3)rp2E¢⅒(!\[f W@&b}Y>>k!Cz@M]}0^-|v:Ÿ?;Fݔ o2SJդ|?esE#mK]݃y`XicÑ#l O{Sc^7De4 ~">N*L"r4uDii[yU^Viyo%fk9Pyl'1c=Mz2zd7 S Nh]ާR;&)SűŢ;V^"?%_ tqf\I4aݥk;}=g^Q{1 {}EG)8O8e82+x/K "wTz=a˵ muczs}lZ?p4PNn(Nvvw}T'2gT.m㮏? Le)qƊmB!  bMb*9C9Pc56ӱ+UbKX2Y:?ڝXnȲ)yiOY'Pd䈚ʖraRi[u<_2(q+!]ƒ2@,HCѿĒbvfhhhJdf5%Gy #6giɵ[n߉ZZ :H7)H{2/sX[taA+T]!@}H⭅)-@c M/J«$uɱ" E{.d){a|<57fHO"S| u<+ oVsp͕T]yvt !!C^kD> t=~yM^G a^673/4/'z{O;Ei0ZЮg}ytc\$Q,BN]%zƨ_gWj(:P$v}"hKLLJK~b[ּr5<$`&*=2f{p^u*NҦ0)$ \UL%x!ݵ#dxa]ݹݭ3b￘9tU"LKI؝'+NHUiݙpYR%PHSaSy WEo2e9x~~u*%]U_12y}5=ץO~B'kjU7 [T̮kV1Y`yYMq;QDs~'&MMH hp=(&27v8(ߗ 5 lyȠ3\di4wY-Dɝ9}jA4Em엒cX+v3xpl5]OF<geC-ϡOeƠFn{>(o!;N{'ӆeG߲h]Tr70ȟuIZɣd itCXd)ϲTucGwWMq;?0!Cp([l+P0EXcM'*JoX$Qrbɓ,y"%1,%1SrK~ O H(MznTb~' zVn0EsEm% _6÷.+Euq3rhXG_;Ü8ˇoӻK  86!+3E'=u'?.A.dR铱Uѣ.`#:rFb, RMcv[!$uRydY5"hlWmBVB4k_aczg48ը)v{~L$Rz@gx9~VYcPU 5h 1h:K=DèFmΡwu^u` [q 5^WzZ@>%0nߑP( ݰFKyIvt P |3RYwf 0C$'y*XڤW ЩAM5嵚z>Ll-bHW%M_;E5iByO]H>i ?QĠ8'[F5E__QU s6kN0m Ma}"܅qoYr yTo< I^&1)I}߽"9ϴI/Y=6_ڿ Z[}mC-ԷQE۠Ts\"\_`Ot3z[r$:^wD[-UڷlR~Q͡l}̩ B`#%eQV gvEMcl(?S**C" GTq4g)DJޱ6ChW]" ےF_h 6+]Q__h 4T@Kځ9-sF Uz:5~,=#}=_J¢ HQKZұXdj9*vfC?ƍmV5&=:LdcyK;g endstream endobj 79 0 obj <>stream hTQ=o 7M,/i*y4;k:޽q?4O+$z(H"'\ LDHnQQ.*b'!#A8UK)zWWh,qԱ`vͰ؏ͅk endstream endobj 80 0 obj <>stream hެMo@stf_޵BHPq-]lQ{3]I[DQ+gwv9yeAed@)DBU@a TCVM~%f6m;ɤ"$hSC9B ٗy+EZ%A%0#< M~S]a/j]Kc_muF.TULt Oy?yJd)UMW N)) *WK(7bSdLb?5bMλ`6җ* пԵUS!b+I1 GNۛYY«'l*8j>XT(׷}y41# ]ٴrZ3?Ni:攱*$Cv rS q 1+BJ"=-3]w&6 YWftdVF&39!Q "g[IV7/˿/K+q]ue=*3W©4nᶳ:v"nE`ïיQLt-9zTDhz7a1$ ;SW0}tqǜPLߞ{^Cok)p\nTO˗΅#=x%.bv!I#_{3'|%@ⶵ,mGeՎbr4ya1vVe㦜/2ۿh endstream endobj 81 0 obj <>stream htXTT׺q9ǒp,8:7ӧO>{β3{lp0[ Yh,=sMV0M^a^-S7O݀ mϜ;c\;L u BC*)ۊjM$UWZ#oۜ성wvWTu7e~@SecRu/gLǹu܇-=r{? 4yrcӧߵԱnDzL;}65*ǮsLplY9V΢ ga6,e`E4LOt@J&@0~# ѰfIQwvmhZʠѬqsEB | +1)b <7"O ( b1|鰰Z֫,>WPv4;H^xsksTl!zE❄%+AtMyY}MX޽a{}b۞o 0 t7f EQ=׿P Nh=`2|}VxI>U 0YAr+nI`ݟa+N$ĉ}#2ۘ^NSgn:kHzIŸ;tqwJ7/ -nJq;{2eMpn s4Hn ];\v>:TwUqya~YTSVpa4UmghݽD.l8r^re㲕ӂXCPWP/PoyOu=VeP4JuBBj>Efb^=qLr6݅9WfC&&cHj >>AEơSRɚY 0U ɺbq_""7/~9%( K9zuDxr'HƠ?N0= v]ϱf/6[tdbʡ6 Ҵ~ܝQ?v?}LD}]cwKeD0 r#_iǵ 0%6VT"Iud+KKP,F3Bg [X[q7=򛠥GJ4L8bS0$0{샶c/a0Ʒ7fDIPtsFvAj2Z$7AGG;ˠY޿>4!^fwî**˅9tG_ H\|Dѹ lxa|VShUV5C EEw*ՑylnDVɽJ7"fӻIDˈjc w 1_eT$LkIO8jMPo$.^k`z׊2+YVUVXz9?e*Vp$$+KƊ$2ҫmKU6/RePWՃ7Yɍs42~Sa9B!O&F$hXc7Gr֢RU׵SIayV\a=)Ϳj*SknR {|,|o=8(O&@i18OQw DmLN$檴}X;SvαXzM?1H_YT >>sKtOX~!1j0cfbP`#> s妭]!> ]fMʲH RˈҔcڴ Vp* GhHxex`Ֆ-#4&tWBTXεZdMāWOz0K?ϩ`.3j5=Nwl9->p,muY5Ɉos[/sMLqi6%=)??GaHшZLť<'.Y#kWZ_r:}R@YJ ]h0fKAN2tkn3NwJŷI(9qmk/솁֌JpYL0+3 ~j#dIzUƽm.srh,!cdn[;ɾ Ⓐ@U {n5A=G?454U'?InS˹ԃmc;!gw`ul# 3mE;vOotc O|UyZ~9`a}4ׁG ˮU?5;LoOI>xԍaYUpٺ->qU/UJF\d'Zy~jzG@`RΠL 1M2!1 7 2jSin.o,MDDNQ!ړnWh<$sɤeW:*7&$ 8PZ\Ȗd()&ŷM]')D uq;4 xMqdz!O'a`?` mb|:.1Z$Oo9 ".nX)&Mq&v߄Tn;nSY52RtҒSB6!IyƮj1c{w\qTJq5/kL^nwQ \izo;S;poUqdqGKq`b4A4 ϴT˚j-$4#Yc`ܳcMc}Yq0 i7vs7O+C 0*Ayց 0Sg,f;_bnw&]WhѾ[vƺ#HuDrPAQiq/}:or"O[eLTumz>%?Qܤ^P/J=jz_qָ#bAGsɸmHu(z+cˍoH$7Câ=d\2*ٴ}5pofWR}R}$ L쾂”Wgאx0"^+MVh"}q…S^>lniezi*%Rc]],x\U\"^X?.f]Vɋ.%ಆ ::BT->,$<cq\פk2!J^+M YA5\c\_ci*j8ǎE*FBBcmvEuRAUఈ03Ku€ZLѫ7#Y2CAJf'Qbdr{?r-±ܲJ,w<@_QW1șA&"q *2.ER0a<)h__,:ي!pvIت"m,M}Z6/xC+=$ߧɯ~< W*,hn,!+ė6C% 􌈈NԐ^3aSv-v]:0j5í@(1:ɤeϯ3)Fi{k n%Vab#p٦"j)+"}!]zӈ7U7Bz~,D) ݪK%Ɔq'0*":2|L;'VháYc jj_HT1(Cve,Z :Zḯ*ۈ}9ҚՊ]YX`;\1v^yj[ B2)u44&"NG>¦PlWb%SLsjW@z f`$7w\V}RyGQ˱אZ&n = [ _l:w4M_/w:9Ί#u%< /gm^uA3-c7"vDmq+}^gk/XdP3LJ%ax9 z @MNEW.tE*(`ŝ}/pCxXi~ q=J{:yEKB:.!Y#Qjg& ]'D_G!ux-B4X,FpVesg05!exU~Xr/^T.Վ)T.푻*2%;EEK3XŹKUBiMYRcvƔ#L n~6JqF_}t;",'~,cOWfdw]h>xi\ᱨӒGpnXzUQ~in:YﱡH*F#f+\_hYO ?f!D!TEbŧv$tD㪩 t@*~Ym?>s埤eBt/dY Ie%mk&~^qp+ AeL;qPySR"<Bcn9ĻFe@Zg9PVXv\N5B*HWa4Hjj/͊HnAL0D]TG;w^!b[Ӎ dr%Ω겍y d=\U*2֛m}ڻh*ͥzjͨ п2$*"׺!sDB.ۍթJEB"}LZ6.9AK 'cX&*̒+KΕ^:ӊMƳZ+tP „K$ET`'05yB#r )Unqk*#*,wj$vF>n<*8L=hGs^ai6vrj\sڻU_tcQ4Y}PIsd;Jod'47WNt\gBͅ@<] 5y+`SYʹNS wRY!«7fy׶5Kq`D&GHQ|);pJE(|_H]X3kD C 0/  endstream endobj 82 0 obj <>stream hT=o0w0HR~IH {gT_?ɝnX@p~p6 n ,B#?vxZx8{m0hwBhTBSc RDכ/D2H*tu5],/ZA,oTQ5;(:Eb`i]t p2'] J!%ذVGaڮ SK<^uM;n098.Oǟ`ۖ endstream endobj 83 0 obj <>stream hޜwTTϽwz0z.0. Qf Ml@DEHb!(`HPb0dFJ|yyǽgs{.$O./ 'z8WGбx0Y驾A@$/7z HeOOҬT_lN:K"N3"$F/JPrb[䥟}Qd[Sl1x{#bG\NoX3I[ql2$ 8xtrp/8 pCfq.Knjm͠{r28?.)ɩL^6g,qm"[Z[Z~Q7%" 3R`̊j[~: w!$E}kyhyRm333: }=#vʉe tqX)I)B>== <8Xȉ9yP:8p΍Lg kk Ѐ$t!0V87`ɀ2A. @JPA#h'@8 .: ``a!2D!UH 2 dA>P ECqB**Z:]B=h~L2  5pN:|ó@ QC !H,G6 H9R ]H/r Aw( Q(OTJCm@*QGQ-(j MF+ 6h/*t:].G7Зw7 Xa<1:L1s3bXyeb~19 vGĩp+5qy^ oó|= ?'Htv`Ba3BDxHxE$Չ"XAP44077&9$An0;T2421t.54ld+s;# V]=iY9FgM֚k&=%Ō:nc1gcbcfX.}lGv{c)LŖN퉛w/p+/<j$.$%&㒣OdxTԂԑ4i3|o~C:&S@L u[Uo3C3OfIgwdO|;W-wsz 17jl8c͉̈́3+{%lKWr[ $ llGmnacOkE&EEY׾2⫅;K,KhtiN=e²{^-_V^Oo§s]?TWީrjVQ=w}`嚢zԶiו8>k׍ E  [ly邟~_Y53rW򯎼^{7so}x>|쇊z>yz endstream endobj 84 0 obj <>stream Adobed     $$''$$53335;;;;;;;;;;  %% ## ((%%((22022;;;;;;;;;;{"?   3!1AQa"q2B#$Rb34rC%Scs5&DTdE£t6UeuF'Vfv7GWgw5!1AQaq"2B#R3$brCScs4%&5DTdEU6teuFVfv'7GWgw ?TI%)$IJI$RI$I%)$IJI$RI$I%)$IJI$RI$I%)$IJIEcĘ@=GòiM@ySe%\u 7 {c}{OC܇GUIKH#j=JI$RI$I%)$IJI$RI$I%)$IJI$RI$I%)$IJI$RI$I%)$IJI$RI$I%)$IJI$RI$I%)$IJI$RI$I%)$IJI$RI$LNMf઺c5k✯,xg>)=RфnEƳuWu|Q[V}8qj@ ,\񇙙#Zc(:hv;@tw.rFXu&NB#=u}jbʟ_p Yx7cI?q\?yRgUT3q?胎= =K\+2>1>l;sD+y C G$eG26Pワzu.ss>c}Ecks:mFSr,OvG>Gs׻#c?q}W-ecOWD +s2FXn yLi2Nlg%W.ȭAwQhPv艴:k%Ŧ?"z_FTIksV0g江Dԣ\2j?~֖?Q1U;︮UuV>j汐2>:K 8{4'1HfZVV!;-Fnr\?=ӻCu$WV$IJI$RI$I%)$IJI$RI$I%)$IJI$RI$I%)$IJI$RI$I%)$IJI$RI$I%)$IJI$RI$I%)$IJI%_37 VmFj%!e"Tk^։.:FGP4pw< ꏛ %NL!#GRxyRc41ֲыYy5.;0QnTe~M+<{-1˲&Z [ 9 \F!j: +}`CI.wda}`: Ssxh~DG=:`:P-\3O(&y*>q5_X-my\Wi $6{|< ~ee?e2wQqo,Fq~83S;G=uu\\)aDv\Z|*'oQq}5{w#in\djb<)u9cOk\ZDu/#@w߹ce׌~:7*v۬|BfѸ8e}_dގ?nFu оG6lC |n>Eeuo??$2ݐTVr:V9W8wV,V`*y6`u -mCG h}tUД #Ju,asF״⮯=}e9M4mo {,c^Zir<׿4+%> I%qjI$I%)$IJI$RI$I%)$IJI$RI$I%)$IJI$RI$I%)$IJI$RI$I%)$IJI$RI$CȾj_} \%_ұEmU^\ 9=K1ٙ'}'<AԎCmc?[]pK@l깏|@柳3cjRftmR8^WS,}U:g(Y>ߓm&I?Zl${|(B=9 >.vduw~0M|^zA>)ͩ u#upX\slcmo]nΰDN~_A$z?X~(?!>%WdXڪis_Ac[y7OE׎,vʄ4y6IR9xA4v] =waMF&*.geD4cJyWW*d쓵2Z`ZCe-uN1gQ^Cj~ Pǀw?rO`gF%naѭ2>;[Jw!<9GwTc@=Դe;ԹcZ¦nq6W@1m}C80ǂ?% U@( s$7iGҳC5wBdpsE?o:?Hxrb`s?6p湱M Oi h j:x,l\1rֽ̲ГMBKcavI#& AF 6hdP+MW-wT^8hӯ#F¤I%)fpEvSPϏ;[]>\]m/{I%yV[f3fx]ʯ2HSes:Sr s2|Z +j9r>v*S% JES I U0 l@u+X*,2YC 'U}j1jvM_Y ˺Q6cχKҬ벭uiV:?Q̃UD4snaJ*|[XN>c( 5sS*yQiI<12ȑEy1ܽ ab4 )h=uqpF!c%X9W2u u=فg~g|']W][ŏ^K,?q)g&toe"22 >n0QxPw칅QfX5!cWs]%i< -:S,8~*Zl?(i/>SR9ShO鐝Tb.8w3Tl&t>e7#5R^{|ao}z%#=!I%a IASYx ~T"Ō?8FCRDwgM͑DlnƻAM|R<1 @$R!I$JRI$I$$I)I$JRI$I$$I)I$JRI$I$$I)I$JRI$I$$I)K+[`vEf=g~ k}2\hI^[:şX:ZV̟|ʯq~&"LV_q-۞%uج`;&lYpq ef v5.n_cz7ޝ޽+{- jY^ 뾲}d[gkN۴_AqhkfI$RI.WwteQP?ș$qFP{κx6csk%bpU$t2I'V5As6rH4cM[Qn"rdlv*v3f2}v\O sG0zf3/Q k`<-}Gx?F,cr4sr[`v|Ci6T:RֆlQ0[<=P 4!/L 4-z{jX=KU^v )2? de+uERe;':aDi6>VS#Cr x{swPNIWcFF5Czø*M܅뒤ۏq!%PYv>]f ]Gb\YwWk(4->;8_wb\^I3RX8emt?ŧB4(ԸV2N5=\q,L%z5BA=? c{4s͕bwnHNP40'v9L$FX`EO q)'O{[ef[|z[30g0:< |-_WfI]>}%Pct :"{˜%ē;ӡu({,\$Ϝ.Lh9^dsHR^kI(ˠ.oP0PV:x-;j|/9NJS29-jd'Фo{kfKk$IJI$RI$I%)$IJI$RI$I%)$IJI$RI$I%)$IJI$RIB뫢k+q5IIO2z뢞,&ItoE/{г3m]g#M?XWksWQV_Ԁ|683j=5!x~̂쾾ֺs~:>oOm?| =TeGW@'2leu#뼞E|T߻_XVִp%ĤUq~NE /{a{$+g&tLѐsr%<^|.i.{8IXao %AʈcN@}XҴkB!$o +JxkRʭL{Zu 2X&3ܿYZFTV5mB1cu/ k|z&4ZIZY':+Jlc)HV.$!)HV?64.ef +"$^_?6MK4<yЪε䪦Z[LJpC'&˵q],: IЬ̯@\_Xpt&rHСvW=K}mxs70>!yX2[aUX\^\ +( Q4qқz$韃~U/ κ!Ը<|Zd/iǹ{~kWW/b#/u`"$Jd)$IJI$RI$I%)$IJI$RI$I%)$IJI$RI$I%)$IJ\gcKOq]kAsxSv_l|R<+oPs981Deߚ:_D}03t:m\@CY0am-uO9Ś[uf~k u&:}ggfkPR▛'^)k%@g*q+qD0rI)})##?7]'Ob}ls[8/]$O>*9pn;DuKx weX<mƂPtScʄsv@ SU< l3gssEẆs^)iL8 kVckĞtĬr֍HZ|!~ܝOHKo֢bVMXӠKg-5$z!YqK:&Jܫ*O`a}\mxσ`isj'#>Zy~yl:wD"%!r=y8?{ si*߸䍑[;&ylp|BZꖘa(aV9Dm, Fh*bl2kTSQ1,I᩶صPpClAּ?de߅AdDG#p>ՌBK> vP:ZbaDDڍDiL`4P~s\KOkIZPqm^CN1XG%k  eo[Zf/Yg1z'vKn>tߨ?Tstꬱ>~ xr_oTr P[F~DW]e.`^-sjkk5 ȦΫeGݕ`c{M+pz_Sz=7/h|׼`0xUS% ǭUXh>Lx.jI$RI$I$$I)I$JRI$I$$I)I$JRI$I$$I)I$JRI$caC]nvs3#v/0!t7 ONx,K`,l g?R;/z],;'y֬fu6d4#=ݩ^|-uԸʯ>痔WLK^W3 Xc[_FonZ^Tu^Һ}NM |In:my;F͵%I9p˲guLzIv;@hiDY2OVPEH,@-JD+R`@SҠDgUvzse:tcuk: 11r: цu/>\LZ&4Y?/pV8[NsqqMОJ㆑O92 c鏐(srًIh>p_dfd \`l\Yڱ̕stsA~ofz###f<~OO`ȳ)j>+>K`Gfx|]Dzq[KĎq_s-;%?ːxvOn\合F!x79*LoRXVJxY,?>?dqcW͆l^BăVEQpE!AȂE*)fKu |tqY w_ʗW{%ſ&-/}$c[Y9Gܜkk~Wa۬~E;ɲWr Y[!}H{9qF$쾯KѺuvGP*iYYw*_zǞye^쾱`9?a:Q -nv6/iw⒝I%)$IJI$RI$I%)$l|[Fj I:/W&[CY{*9knM>o }̀p{$9l=ޤr٫omޣJ'KoUˣ?X6K6s ia ܘi*]O5n䭫qGpI$*RI$I$$I)Jʫ}Jpg=s=HȔ Oe>KԯϳeZ`:j6#}X@c!b>(]4F$BuX\t+XV 1c@=<G2ǰEv =*:n-89GLwdUfE kD/+zUvV+oɫ?ƧZ8&KG"}/yhK@EQ ^U@$+ JG@1-Ju[ej]FfrWMK( jUhUӯVʹ@ӭu;r1$/.*1{Z˜{[{<A9z1/@DG:?wA}S n c>az >zR ;W̥cyχ6azHw9 zuUELkZ;yĨ2>C2d1AЏh/˒cy5}8cT11{o@w\kc}K&^'ī@qiB#1=^ˊiV1vΤBBb}])r% GQ1cF75-!"~E%1 8ŊY)Nf$u:k୪$#/$ "HE!@EU{V TyO39t2>i};`}P7)_}t>fI@"Aڵ{5HډhctkD 9NnxC{'ֵ̯Jqb46[{Bj)76:D<Χ佂ML n3rY:]7d1uLIF΋Mc}WYz{aǪ.Onc@uWٗyvCes8RU@y @cgnz^}s9?Y hd}e̗zM:g]T$x{B2`(\:W_[Sv>Em?=rۣ3-lduzΞE|T>wur$w&@ 6RI$I$$I)I$JRb@tr}{[sv f#7>>)rLhnOjE:i w+6_3$ 5EvhSG N@繯q`f8?D-!C<;Ks A ԭ㐂꼑U9:ZRFhh:44jЅҺX1VqxQ kg@: ڂ<rV70cJ<xktAXDDR$ I$RI$[ޑ@:[1ۯ<2ߦtycF6VOX{(ܹ`69+?ˎJ\Z52 +=~ΪY70$^;졒H`:ͦ+ ? <䟼8%I꺅ju=aC  Xzph @ V L2f-VXl5YcU)J١^h{ZNCJ5:G9K;5ظ-W 7k\b= DN̗.5b;]WIWEo0{~+4kOy]/XnO }hg2"s5sQG2%Ojwsau\~5!d__*1c#Rmk%rFksL ܰk;]Iቜ.RX0=ZZƀзN W@ {Bӹ`i<)gWz}u*jǼ*{U\$t199cFƨf&K?tOee*ǭּh+}7a-gB&@H/TǟKpk@QHYpj7ƻ \c͂"#kŁ KSApS+K  ,S6/BeBT:!ݷ80ҳ [oENw1*Ð铫qHK򴟌"BmpV.CQZ\hIS@Ub_2~8շy!ס/*v>fE|ZZꫠbR?ƇU-՟vKk|tHNrg'uY5oa]~g'3Ï nF5r*ۅ .o8▘aH%#}Oym'X1ŀXGfs2JgJr3:ݭѿc}֑D}#`s8b@uU]52mu1)rI$$I)I$JRI(VXq))::~)p]dxX?2 Loe;*ϢLTթT%{,#I1ZW1-AΩ>/ZIX{eVS,ar 8MDzM.ahna_[XI"$I)K#3~~bsݏ8( $=DﴸVlqT Dk[b9*,tO.fqyYoO1ޮcfOUqGG'$(K7 c 4JrЃXs++d1ۏeQ7(Ms:Vxj [l>'Ft 3q*)ۉ|0114ݿEnEqN2c>#q ψv~-rخ T㋌guc68AGf$oQ6E_KSCc>%^sYc`1ЪW?2$u%8G }Xv?BAn᪩ӫk8)q C!6=\*|8 xWмCr>MPUg\)㙆HJ&NL4 h>H*#Qm?w1c\r󖿃9]G*۷7(s[ Rmk ]|gZY`ekaWˑdGԭr wlUϐc8 6:HlpgS=*xXxk?9 i{_{zKb̙w?3VNUlK(f;W>ft_qi`8 Z mo Yk8˞$2Vc!]z3b/VOH\:Vk訜 2u19mV߈߉UKY_7r`U4W B2HWݰ0 Jn5a4/!WJfZzD_ߎ̆8W*;.Gq60sJj}Ά4k|z,ז;Vʧճu€GWo*Aˮ?0<1ϓ1czP?{{, :#ms^AeYnvت@hWEr"d<ȃ!tRP䃈ɯ;X|7?#23G!},hNjl]<=WtWH`UP^yN^s>Hєܹ[cZ q I:_}a.6q[3=~Tէπs|NCNcR?3z2~io{JO{~L~\C\u :5# 5 \GR(9),Šx.QK%yAkpEc^u\V.@pӳvU^c^f5ڂ Jɯ'x{{9K,a]O*М AJܰe\Xri8v0(fMkH>aq;6ޅoxWb5ik5y|[Hi8.W3 a-a.tIY`RI$I$Un '{4}@q$y$Q\4D MVA(V ",1*:`>_9c|?kkZud|Se.%ة(v=VTK?z˸ >]8\Jg?T_eߍM[lK?N^(2-dҼI/yZ2q'V:gPmmǶ* rznOHSks up;y tCu.?fc68HZ70iz0{*]5첷By3agVO 6Uߘ~rk *v5>jtVKM;l?輳/ع!5gcl+sG+J־}dn'{F#Y {q_Szd`O6()\ 4-׏؃s\\mVV!GX ~BѪAYv\-:4U^Imm:S;/CUK:"!":S:=eœLs.Cםτj[S lv g慹bǪuoS6:f&dik\$~+/k.cO%-J *\R5g,?'U:I~;XحGI}\+?W>.q?µ]5Tݕ1hLģ)_4ͮL)x;Z?ɾpKⵜ';E&)&wؼk丟 VPq6 w%e9v2B DbC$r(A3\ *a{60*E=4e5<%,yNJ_珘ɊB h﮽ gh[7x7y;qCuX>;?Ir\w-Ycxÿgi[y*{I$?F7kTws=^*Xa2}F ;.G0yb7*]>S>Vܐ;9_f\ *m+,~F?,N~^`}3쟳tq ,Ow#9C1Nܻ<,L vbz+}1FJ[W윓:}{p/p7?f+ƿ j2`YciЅY~}Z;Xsx,qQ?GW q[YnZAtX9s uN<2ūzT}YX:Na4yg.c|Sӯ>0Þ~#1؇EghkV?g,y\2 kcos8a'݌MO.S꘍=F-o⺵w> ,Y h I$IRI$cۺۛ3j< !\nbb ˞ӵ[̀1qg3C`tQ(fSI.Щ]txxP9DW P޳.hٓU.(~p4p HԶ`!ff5@?eT U侱>616/2/fUݶpӮֵX_Y_c|)dT>.:k N#zvXLᨙWX=43sݫI+MkDt~ q3.IYS!Zy|I4Ng1O k>ŝVS4nHd~5[Aʵ+ŲGP*z[u 4Պ%ܶ hԒ".E췈"K5r}oc#<9c GO>癖k[+h?P+b^V4Y\5T}5+_Aê\c\t]V]x Ưlrq%Ї ~UKB3Qp%MgPO9-:)t+\6煺OTx/]*ofofѰ! DcLp}JEО"#LCsjzE0f [phP 4r}-><&^M[ɚb1lruU!ӍlW7m,wY>CUlHb\\?tz|W=_8Z`^?ŏBGRɰ>Em'_~l_òx>mCϏNU3G&.۳'&PV(`%trmE#I// VZ}iX!Լ%Do}Z׾=ƫˁmTp$։'@$][D'AgϋV?Askfx.  3ef2ӗоt~Gh9s?:DURI%)f`XwY u6Ƶ>I-6N._Jϻfe9kT3Մ|wE|=ÿzߪ_s0oTa]ǨMD -}ouv4%kFW%'.@$aGNNybc#z/R}Z5\0cvs;=Cbd ߫VӎVH/h3UIH+Q͝vs䅥q#]LR /*%kt2 qVB8CۣeW^2qiZƿ+nuUo% 5V|alsuI%I$JRI$I$>Z:h!b4?Zz?ݯ3xt)+ $hcU WfݲQYJє1GaE:u3% -*~GnB>T0G!Xpd2?Pvk̦aEnVEFeE87Z0PZ-Q%V]zG[^U, ܯQ7?[|p;ۮZƴI0~Oen1ŧ[VzTDH.֓>ߚt xd+v/*3m֝L7ùG?u+7N~E.<^+~1u;l H# LxpÇx{xOⱃnO 7Qǎ~ נcc|jM5el0S^`I]mGD&Ϋma*efA9.+;+SOX7F3g8\|c1ض[kY\^9|צ sxMQ(T0_acs\sN)KD[\]t_cub4j?ɨV|(Ft8$a]|{ߏht6OXB(8m+G?gNbc݈Y!cBc>gv1lwO?W/Ǚu8tMp<(}mua8]L k[LO|(l5Sv2qwl :}rJ~1#]kd=[7fmYc>aSPHxw>]mO{nkH0}кN5$~+%|G `_ѵp#ಯHWBϞ#1E>k7[Yh8Y/B}PJt2Tѫzx-N?8/?kക\?*y" S*F0d~[gWSpiLLy/tC}[ۊW*=|ǁC[C|(հ|C!{IGPwwW`5.r^Lw1ԼCv4&T=t!'Q\>+Z?Rw[R<r9Ï7I$$I)I$JRI$U?\,X>u0, t_cax{O ~Uf:QtY=_!P0Չ˝"t}Nu^clʳcߤ'r-8Jp|yտ^qwKȧ:ѯ>2K埲w# 1] ?I6[үv²ⲟQ-+-Ap#!0ba<2mqДf*gSOM9n3_s5.?P1aM,k|z=l %yHf4. p sY_StmUj[5V~7Pk$E~H#vm!ꭖd:|U'XJw$.L\^^ L!U܏7;syHhoS2[ EsYS_q>scuBXwn,ǒ2_UU3 >Sʦ{kZֈkD;k:wN2XpCD'SK]n)FP!my77bt͎`ŋk0d/t_OlOk[xM{0#B P{ !XU*ܬʄ6k Q_w,;XA Zd+_Q?[pHO)9X/ $cRg5:I%9/f̯57_2"842SFhhR{[e cs%suխ,>`eK`T5reܞ"&Fgcc?cuw7wXϑZ{dh^{x{ 'W9\O%]k\9cń X奏b:K@E NF&0<&*-Z(*$rDĠYv)LAWT]jK7@:YxPˉI d2LΫcGQ{pX윻L2OlkZ!aO+ >+we1Qb髍-onճy؎u,#Zh>/"OyC;/@~5y||FkdW؏o۔c:v9u,'f?U~tݺA9o_D/4gc]ǧk?p+@Ak<xtIc2)$IJI$RI$I%)r?7vS+=Qiw|J뗃~k-ͩ۱0'2 i#)\>XR.е0`5 5eie,Ytvk|a"Zr1z^;`8@ N|6+?3*,2GSlpf@i,Ku.UY«p0rfT/`| CxcC"QOyS8CGS0UC6Xpj] f+L[ d=c"z:qp|wCOX ͏ _sCCp{*۟KKd xEրht(̰>\6I\a-rw,N^qǪ(%AP}rPNKL\"ЫC}S2S[nG ̍y@,4jSӾ$fP,ɀru|U]gf||E)di\aL~O5W~tnC鲟-K5<ޘ哳O*z9 @4u$x]I-@11sx'KkqicCKUu=c>YW3*T_$,̧)kR%:m5>xv q(qempWa^~W?ǯh C2$Lص>'`|Ij9I$RI$I%)$IO;nUx_W.j}`n?;%Y{[ aF2yU;+8QrBDZIZ X/TWcv<< `|Wϫ~[}?t|{yy8FfI$J/c^199PA줒Jx_I8'ҰzcoDGcڱu`p?IDzY0#~ dz*!3˔ \sKNcɪVZaj6GP٦*@k'WbgNµkCt$qڭ9=1 -+ǰdcA!s=^(`jV4>%_lj`v pv1$yrKD&}XǫҫA&]tv?ൿWZӏ8#ǂg1vb]_gZ1e6f[Kǀߡ>`^)23?nS>+v#O:3%ְ11YE&[ZIxrD 89L1u_2̒^}sz[8?nyY9߫d0jt=M>q#7Ĺ=Խ}%%F2#ʮOa \ iUB!/#o;(:H]$NZI%)$IMj''٨c~n!xN"2n;{J?wY7)w&?|Ѵ5b$ׄtorx=]Dǀլeց=Xywnq*/h*; s?Ωh?QtO"HoOܸm}k1{ǪW^E5MtThc8 h 玲N# bzHI)TI$$I)I$JamU[C ΍oI6pl>sw]ꅵWunևk(HO%1hu==#:IjkNLH!x6(NX$"RuZۀֳO(xjY[^ \%Gq Xr`J쮟NtTs$s4c4]Gĩ Jrs^kn̝^Ӱ@'u(\S'z. fd%t?Qz)k)bke\/YhwzZִ55W;]$V$IJI$RI$I%)$IJI$RI$I%)$IJI$RI$I%)$IJI$RI$I%)$IJI$RL[s01x~N8yZg龸}kb4{Ov=G$}-=IqԒU^k0LDfLxeq0ju+qmuOx$v {u(n&l9I25ƕܗF3S}u[rNJ+rgl< ~j>Ƈ~:h!duvʹ6Ap*hs|6#W.W~OsGf6GZ4unMn'w~qcJiV!lekx)G}G~GN; X/wp:/ ׍ׯo2{Tp|`сN;vS[|!lpG&F=ԒI"$I)I$JRI$I$.}Osqv5ͽKI6QHZ9SiQ5Շ}{R 8H:xXS>Y/c-uF[* 'S ܻKI>c\; [}G"wAByYOp_n}5%" ulh~uA}XG+?q>׊ih4I'.-mfKzwOlbPA.?Ug-ju+LE86`$!I$JRI$I$$I)I$JRI$I$$I)I$JRI$I$$I)I$JRI$I$$I)I$JRI$}c8!6Kqx[8}GF]c=džxT꙽k=َF0}4pօ|l8L͟"vfe}s IL9J14n&Hi~ѵŮЅKuȡ^us q'h:u`u. c,Jqw⑯G'6-4ݑl>$xז\Cx:?i`5f$JAI$JRI$I$$I)I$JRI$I$$I)I$JRI$I$$I)I$JRI$I$$I)I$JRI$I$$I)I$JRI$I$$I)I$JRI$3~ӖuTaKrs0 UW,X8DvYQ7F~S?9W)$g5iksNH!c}NGM{JxM~8wda+=gUkNCvֺ$qCb_Ϯ82lϵsm찗~ &b;f]6c-a_B[MW46Z>⣗-9洍 .&Q{woӪczj?jC}Yֳ̱<%O~C$[}2(u:FYc'E 1lYMvhq Btm!X MYm&8d^Bȫ+kC|*CEhTI$$I)I$JRI$I$$I)I$JRI$I$$I)I$JRI$I$$I)I$JRI$I$$I)I$JRI$I$$I)I$JRI$I$$I)o}\M;*ůd #碗Ow\@ [ [0:=XaVa`|T^cXl]Ăj={qn$aYJ#XY9av$A!SϤ][o*}rgG*W8N8eE! @ׂ幘s㆝%-iDlt{܏F6ϬYiˑqCz|?xzA=oG^x➉q+m4,Zc>NGr85ܟ iUU[jXƈ )bI$I%)$IJI$R>(3#2[=yk$˻ $mr{+Og?רo*;<ѻ._!ch:ksM\ H~c+rEE0Ɵre#@Ǡ9Ð Hh}Miu:s_3RH;UZXa247G'93Ǵ:VI%aI$JRI$I$$I)I$JRI$I$$I)I$JRI$I$$I)I$JRI$I$$I)I$JRI$I$$I)I$JRI$I$$I)I$Jy߯﫶/{roWhX8pꙘĻY}nWa/9ls-Ʒ |߉zWwWlOVEU J=@'!FyqsŦJ{= C@7/V:y,#_vQulxcJ' |F@ґt +OՎ``_y,ca&gNejhU| /3Eg9Z3&Rg+$)߂^Vbz[6O2Kk`'+x (-%I$zI$$I)I$JRI$I$,!.ޟma)n}䅸:ǝ`.q=ԯ4}AGۘᣎڇm#40Btce/uMVmozWWѬg5iX,kiW3/3~}Cg~FkGurkeWXèmcTv^{Hm7~ 0R=)5\ݶ׏SliƂ>u$)bI$I%)$IJI$RI$I%)$IJI$RI$I%)$IJI$RI$I%)$IJI$RI$I%)$IJI$RI$I%)$IJI$RI$I%)$IJI$RI$I%)$IJI$RI$I%5:fV_S'?"? uN;.a!BЯ{^OTٗ G[ns#p0B6)qթnO2:k\3ۗ{>k:ĕN7ɹ:\+ u{Ihh0++SvJ>e-V]/\$}﬘m} ~«a[Ophc!hRV+I$JD)$IJI$RI$I%)$IJI$RI$I%)$IJI$RI$I%)$IJI$RI$I%)$IJI$RI$I%)$IJI$RI$I%)$IJI$RI$I%)$IJI$RI$I%)$IJI$RI$=O  xOl;\wT_s.q1\>$Xő^f?HƘʺ~'z.zEBѩU?0\^JCCq*eCk$I$$I)I$JRI$I$$I)I$JRI$I$$I)I$JRI$ endstream endobj 1 0 obj <> endobj 2 0 obj <>stream htVv6+dEX0>4ۦMc $e/h%NOQDsg\Sūrq] (e?aIC[DY,IE9Eo0Pks,,?/RV8l 2h X$J;UU/Uh "aEd$S(8؆"6/} 7ç  /1,/ܱz՝耷5 z1 _i3)þS`ϫGCZ\sl7 dIh1]ъRKAj9N׼kf(%talj jD544Z Ml 4!ь):0f]j5t qI ]t1x LDE C[#V@/63%X$DFxDbk$.'20'#E^*Ģ.D˔YYZ:Is6{p;ZnN .[ [u^9"Dy 7Xè?JmZ Wxw"8UFM@EXxŎ>8JˌL&TlD9pFl] G!uэ R@uVQr9aX!vqA4d6[2r=O)C4oQt+@TUCS~hK[Җ۩Z U@dW 6B4 FߝeJԀYV>kץ@L S;6qpj [[CED1 ƈk=d,[SR50 a82D+۪jww![U$W ʼ-lx8y͌ԅ?{Y5 lj"{չ :pl`{>ˉ}ʻ-9>~S. 6&H^IvI_ ~n2}֧vsv5K95/<^߉3;f2>b]Ƴ8Ћ,ne#[3Ś x-2u61&]c+v~YQ 0*mZ7p{a F#SJghB~ ; fͬAfX~nkQd䞇SmAfn@WR\U=唆8Nf\ؙzhz4޵S;?Q"B]o/ 2ܭᤆlCsDIyu^|RуK:δm$F=f ; b~gVLֺh9HAgk6]̐YYCFW`,=l~mdhrUnH-E'Yq"]0ظ5y&ڕ0~2ΗNJONߗgT{ endstream endobj 3 0 obj <>stream htVyTSOs{{}l&c|+ho/ W(IU/C-^ȦY63Q7]J} 㟴(-%U]zu캎;$~B2B,Isw"_/INZݚ=Ss&E23bաUpZG]bO6vXzݪ}榉id7+JNI%'q%xQȓnKōC)>OZIKyQZxa+`nRA:)L =c G&c%v#5׏qȏd12]_&1]9\MMG&b< ;=|k >X@ghY̲^ Q?cs~esbe6 B.>be-Ut̿%is+o槉)Ax\V- nvΪ# M9`L-4=_O !&3ij\ׁdvro+҄tAahg]h~Q{]r?SG85B\F`lq!.$F8kd-ܩ3{掾IG/*-sS?2|?j;lhFuGZs*qfCg:ݧ(tLzS8gPsʝke ~vNKT9gTSGqĻ2cl^G}P;YiƊʺ'>'l-fIX?@fUdNuIgZPs4i6@#mlJ[Y0j ^NEеa_\3% `gX9pJo<ߒsrz8R:jRo߀#u-p'քbD] })hM]NpNh|jXu)*j_ [`;p=ãa[dɶemɠdPxUӆMݻkਨ/9%5A,?Nj+s9!3KkE!Z_&@m{Y_Y gn6AGZo q00TVV[Mal$Ʈۛy" 8-oc?98.^a`'' |[0 dVr/r3_O?mݹBzg8]Qi6cj -<La+Uii'jU-G9pQuNfLC`;:*OS^d+Wk/O퉌mޟ@`콆.he{Ԙ~2Yrb*Ge 3>L6NoJ78Y.u _;Amcg!a^t)9Z%jsH|Th\Z()=%3zu-MJ=w[َ@{޳=ә'uZbUzЕJ$!OD~FuUQɁW:5x J O %&Oh. .~PHt*!yB5r|OEܦRvXs$ q0¬ h+#lusG"RMHZՋ$kUF2Tq|Tyğ un'< 3L*TKx*CH8LVKVBz T׃+;IXul`>`L<dN/ I\$47 .le%,ML>w!*^d˳xRaHmXW5jEn`vqv$g-`!]ǎ'횲N) ߳dʦW g# g B /2yL}DZ@SyHܥȐIOP4w] Y5>vϝT=tWˉleJDƉ޹Ƃ46K@ȳuy2^#C䩳GHS"HSKFK )"!Ɖ2Gk؍%N)R.IcX}vze&jM9:0 UZ\zGX9YpƏSRdBWjuqEvv[^~tB2^Utο" E$?<%<WJ -)~Yp2LڀBGkGG0<9EDmY:u-X*p_v޸B@?g=~ L ww?yr/O_D}g>vd`:J:n,/Q,o ?7N'vptm۵C"B7Q.Aڼ4hd6r-K67oV_wa~}hvتBu_,YMVfԔ9tv@Y$p{b,xuڣ~Q~~سLi㹺O>6)Q2: r5[Ie&kV;j]rwXpy<\w T*m:MRB *ҖuXƔ#4~ X$F.7 &<QD@$ CK˱ >!˒dH#Ve- ҁ&CqrA$l"3M^eحu / |%$)GvR Q*&yɽ ]YXO w5?`>>iBf,d0hhHMoҗgg> c`Yɚr'hʲf%{$d\y +h"[+*%K陶ԫmTdĞn{1>+iN%E#i.hIl%m~ M f-60f5BUu& 4rnS^_@y-'9 endstream endobj 4 0 obj <>stream hTRn0 St#2&Htj% EyGN $a2{\ 8O`Nxd9,[>stream hTn0_e.[бD邖j"v%ą Jb61wHjn|<| ?&)(zAsBmTeu[MiurY]/6H˭/3WbZWss4H*d+C+z[m?VIGU endstream endobj 6 0 obj <> endobj 7 0 obj <>stream hބWMoFW̥Y[krIT7mSI0M\)Re[oR,70@K훙7oFW?siΞdz8Rr"}ǣx3sh=3qB^%Ż&Y ^cvivk" `K&\ }]כmQ՚*U%z}w[uv:М3S4B?Xq^Ԋ+öLQWZtЮn${Ѵ/3[qHȊfC*z#h%oD{I lɅ3t Z6VQu0H5T2m^eFM^%n;"~s jyQ١%˓1Cyh 1, GQsu}qAh*VosRszST՝!Rܷb՗c,\P@74QJ`@5z-K~c+;`50m6+:ʊuٷXj鞏Qh} 0r)nE҈LBk.΄ID m͓ѿ Z=gKK!U5Ua%`qb(CTZk:C` y{JLR-Xȸx$X`i ֮f%yV~-Du_4uA0|B W_AP^(~'=DCO7Ju*sV4 gRңM.Q-?։8TϚi|#-CJm'͓neQ4׀JbS S!!wOϡXqWn@~o+m>2Җ;?tә^`(k(˯޿zQ<$ys]g2l'igҕVEk;{B^Ҿ/]UIRr44w[WMҾi˩ J&g̝sȝ,tsCXymvy)Śe꟮IAȃ=0R8PPC(M'.

T$ umfH`(;TLB;vFb0P4Ux4{_5 ^q[B5 c4wu?o endstream endobj 8 0 obj <>stream h25T0Pw(q.I,I݃ ,,Avvny%@17CK }7#K0+$ȴ2 zSK\CR+Jb _ endstream endobj 9 0 obj <> endobj 10 0 obj <>stream hބWے}W#`/g1#~8Q\vE,RXyh٧BRKVeF4Nv\|ZܯV1IZm2?(bJJQB"b)(*h,!hu\?[E) >~_-e.r)b"`d#Z"3Ɓ0ݐzT4~KAT;vJ+wܭI}R<6"P*SSi߱vzL(qη>O~l'ꆦԚTNbD"_Al+(EAZO4VfIj׎aִ_޾#I✒ǥ8Ўa!( qڡqGZs ۰1qlCnhif8P,r4€xbpMnhE%olBPc8e>%y"(sJ&jϣhT3:cTY$:b zAӾ>1;w E<"H$"4]nUPsMA5M<*!c&K ɢ1ɔ"/rw.N]* Mtq1D¥!`ϢJ(/r7=K8sKEVd/';=lU?c[C 4W•ۮ#5 fʀc١tvz>t`lj M&"<^*-:sӃ'pIE^J7M\WDe2`w Y+V| lhXKʱ ,}5Ǥ@pqi:x>stream h25R0Pw(q.I,I݃ ,,Avvny%@17CKC dZ@f FP=E%.n!%vv`7 endstream endobj 12 0 obj <> endobj 13 0 obj <>stream hޔU]8}ϯҾ v> }vjV쪓UUU&1QQ߼jW<$${<`FohRq R2Oh :ƄR:Pb)!ˆS4y,#Y #5 |şw 8-TT@iUK(>yFãҕٷ#~)~8֕XdL4mveue#E'AhMw<89<)xon #6ZSXЭ$} lRw N5F29aґ,5@2  tpJx EFT@ZD*+9kDٹ r]0HS{DdEcnhʕYJ9&$5C_Ǿ:QY8ij 7dq8 3hNFe^Aʹ_hJ5Lsb7y'/,.dWrQ޳V=m_X畓YveM,X1NrףS| ԕKpj?}|ƪEO,-'G7 ޏ`-sN=΍{P^x]<=ГuO/j5{`ތv` %;͐t߸4zdpTVXmBo%d3h @l_Nnje^6:'ɵ'_*,|xwCO/#YdvŇ B3Im')yY`@(pf$9i/eg-8 >stream h25V0Pw(q.I,I݃ ,,Avvny%@17#K~Hie)AU'D釤VY endstream endobj 15 0 obj <> endobj 16 0 obj <>stream hތX]s|ت{S `rq*r89aCtuU'c=3==`fjvZI&j3/2 y*Yq[f!{-x)[3|Kz?%бGe.Zl)Y$|Q AlF8ٔ[t?[uWeCM҅␇ICUC ] CD1>C=9tq.ķQP"4ش^; rJ?K y˩MoESa.D9w/iiX:[욵fyh5[7ڰKշ3.qᚎuQ g8ߖt0/:nB߰cfv.$в#u:{C6mcvP< 4+4tlYRتiBv+4wyYumȯ6ENx4kOF 2Eik.ѷbY8<|Oa#+B}D8[jw6b+JΊCRuQ/m'퇧jAlQ=/" O&6u/e6t:"o}mp^ u:ܖG[IG($68=1s&gASub`z?'pj^veKvm |ZvZmP =ڦww\ NB$t*+RXCݗn|qrd'|/Wp F)e/ۛDnuϜ^cEdw-ǰV F\آaK_K{<eDYUWd\RE (SDg_p\Nn>M=w@DXi6z'LM/IjcySQ4xXQ ?ŰcS"^~9D8%=gS cй)rh尮3[eh*+a .xm 6YP[ֵyk)|/% w;@_'=?&hx}j`[>EH"|KMAekwln,VWZQz >stream h25Q0Pw(q.I,I݃ ,,Avvny%@17CKC dZ@f FP=E%.n!%vva endstream endobj 18 0 obj <> endobj 19 0 obj <>stream hWnF}W#k(K#aӇؐ\KYVH]%maCٙ3gΌ^|r ( eai@RaFX7AB^N CxŚC b̦W֛OĐP=ho^ӛPvyW~aU\:'acP:ZWW7PKᰩ^F57'Sz X\+LyVw0u-wN50Cr>gPsJ-xԹ'sD3XfmL»eJ2sf8B(Mc x?!kJj5{Y"Zl K%@eEYLRHSql4܁bќ &p[Ӕ,~ԏԿt!".dXly9~@^lk*^ZΠ>OKdMP,% GP#ð%kUvbȓSb˧3x_cuԬ18Ǭs*vEQM,"%4=/{ҹ17`'7icFSW-a($Fv% FImIm/jQ~ֱR>M,SFt:Yx:} eO' b#9:1%G*7XV)nE۫W'&W93sg9'\yӗL8_nF]Y2wrwjTH',g5e/KxĬwSc6_*n#Z^Mt*QFnݼq_ lkyֵjV%A/nz#\K9/>v]C:jlw׻&P#Dz1![TXrrǗl'072 endstream endobj 20 0 obj <>stream h4̱ W7N4 ĩttׂ >7:p1E1\'K  Aʙߒmcԩf+5ב 8sy0 endstream endobj 21 0 obj <> endobj 22 0 obj <>stream h|W˶D+j)zXkapZ4 Y***{%l>}ʌLr,crb.qM D>ֆxQ7i+=*1pInH\< <\ivJSw(S$.%Z|7pDul;>c_UǮqA~ۺ(OeǾҦǷ AQr8hh6%jo G>JʳIe4&wu.U7"؎qu 5>kq'o[}84k5Cp$@.)/7ihX뿖s֕x6dS+!SbeQϡ6m9<흨LXc0@==2pK/D# ,6DOhJBk{RvvF5ipe* v, $2'IVqE4?6vo- j/-ysJgTP0~ |/Χۖ쑺G:2pGIUT!M̟q V: w@`uݞ?x)=NAIJݯ1OIFnQJ6qϋ)<*IUA]k[N]gih1v ;U/(U`O+!.E-䏘c]B%@4;q(C *v+kbē6^=#e}KpTGIg 1&‰?">Ќi+ gZ^Ld\Qsp7yVu~Ƕؠ38lnz'$AM a{ >HIu|aX.ywx۾]g+ _Zp2ڳ;n̒L|DfrK^sd'zq0?әc\Rc/:qڝ:ݘgbՎ2v} x'`~~i$ D+7Oq c~#z+-T=[H{iQ3"gH [&}: ?'Y*S͍=;1q~'k8g 77eg'>v5#NКj(IښA*Ng}cP(:Z0..dOhWxjvġ07ĩ&Xl痉||E~|}'/5LĵX[EjeE vt2>&[hߝٜFcXyZien`4(5$Ja^&_AsCp8|*`G' &;b ;-qgS٤S"d!*L3 ~DP֭ ^ؾGɖwa>{|i6Z0Zwޭر <􋝩AJ ooV&a4OÇm%0/⺓˂&Qۏn\%X6 endstream endobj 23 0 obj <>stream h25S0Pw(q.I,I݃ ,,Avvny%@17CKC dZ@f FP=E%.n!%vva endstream endobj 24 0 obj <> endobj 25 0 obj <>stream hބVMo8Warf$R_~ŢhCF-r\hΐ8 Do̼y37%즪8$Pg YAj;a3[8 >TY^nyiv[2,Bg^U1 <H0nd?l5Vu f9j3OY0C>I`  `qvS<I*stF%nyǁCPٸ.fc80v_פ2 ,y=ϣsa qyp]>u|,-?i `8D\ҴdelP >]"bvTmM+gm:c>㆛&xm4y-s.x9+]:t)ګ0Qcܗ"g\r7-^"7{p,51&cy ^(L =>B͟"4}g۠w d<Awv4)8L.O< |*IBKܒ(tM_!Pp C>ĽA3PnwO "ei ,ɟp^3n[B (Xk ϊViG0 )j3B_\ mNy^9jS74xpzԵ+M+ BMsL=GQiO|_ g_ endstream endobj 26 0 obj <>stream h25W0Pw(q.I,I݃ ,,Avvny%@17CKC dZ@f FP=E%.n!%vvb? endstream endobj 27 0 obj <> endobj 28 0 obj <>stream hޜWM6W(kH}EG~m++(z1͝!)Y]@װތn}ެڮn[NVO3saD*$Նam7 ^$,$zW0;d!-8Ҕ b)vzk9hjT񢔲pB c/ ɆӐK{+jY?yRd/DsC9D)ɱp֐d˗zCZ~ p|T$f$i \tE8[Y8-I"GhC$ܽr#kY1'C+|$7d8R^:,ZI% !#+zCВn946'2Q M_kd4Y8u$tTK]F}"'pn_t"mPv€!*qwDCQjȃz@p hSҩ#az&;@6ڱ ] Di!@},vPVI(Sb9͋ f'nhvNVF ұrOF< tZY)=d\Φ$x{qʵIvauMIR.q$b>wu̜F.)uQ$%q?u.hWB-*`,ZW0 dW7+.`(hPAY` nkƌr~Vʯ[x x[t9(9لx[9OCŘx]~ڈ0k/\viWB> ³Jcob)\řB)HR7Q7)Ӕ\Cz7?ad^HgQM 9*w,CO"jrO22 s=lD4vÄ$ yvO4)㞕##LmIK9ʲޝYx'f)x5w6J[z8'Ni|Œ)õחK%u![\-h/O9~ HYCJAgs̉fq0+% f@l_Kc!3^nJԵcҒ8c( ҇B]wY̡<3G$k6?v;u`*\; M4z OL>stream h2P0Pw(q.I,I݃ ,@Avvny%@17CKC bh`c-L3C#Ԓh7ԊX;;oC endstream endobj 30 0 obj <> endobj 31 0 obj <>stream hބUM6WQִH}YAAhŦDL%ҐuCA;$(|`j޼yf}Kuk]D$+J1HeI %Ek$&@) [ͯ4m=ʄT ʢ U@@9AFIX 4YX!F]PkFQ)OQ_woANL-̪##aB,IaRıԇnn#~~D38kfIea;^Stt\M ?n?Vg2_ s5o+9z X|^QIM y =WFVai&إkdF8̢N$<ጸim`yqZY?y7[Zuy#<3 I_sUr;{PLM}nzn_FaX JŠDAXxlU҅ (;+|6Ɂڃ(Zi/0`d.d C5rKdt֧/4v0)=FAèg#%ՂplK1e# bu|)-K3yF._}5#=G$,Ar'Q\lE`s[j'sqd/pGm0vJ.{tώ'n"u+Ͻ Rk9ޘx$ ԋtgf]_5 jF|0KC+z1Z鲈gu I}D4j%^{G/"IMq:"J{!eGZdF$'ky4#HXxOח|TM?5eQO` A endstream endobj 32 0 obj <>stream h2T0Pw(q.I,I݃ ,,Avvny%@17CKC dZ@f FP=E%.n!%vvc endstream endobj 33 0 obj <> endobj 34 0 obj <>stream h޴[o6)#UT /H ÀnҴ,PA[-Ԣ;)_49<Eg]t^Fge)Cyq MHME$2J(cLC9p~M4Πwctv7iPT"xss4LGW9,pFYg\'RN$d'JR0o,o_W@Oni=,8ܧt~K 9M‰ǧVZ'."1וέYmarBÙ'͉ȺcOtМͳc?"f"•鼲w=Ej vj0 j^tB˽#@$øM% I89)S?"VM1f9Lי5#XT*K!%\ʂT­Rz23w2NR*2rT"XoVnaQdfua:wo7p1=-8ULvy4f!@!|ֶTpٮOA*N9C.-r(iLgr (ޢݕ(̪6k,Sc~;uB}37锹 HL֌gn'3T)Dm]m}<9?Ķ"jj#b ~,V%h5Lh5Zd[‰<5ͱG?̎ygpʞ~X|2Cm3¼Rg{_u&BwoMcNGM[ї^WFrJ5>}#Ծ>>Z'_"k"lCg<~cTd{勰xSF 0 j endstream endobj 35 0 obj <>stream hj`@m endstream endobj 36 0 obj <>stream hX pSו>_` .&!H$)-+ەo ,tNIpڐ3&-M LIIڦnNnOhwߓ=6i;;sϽ'#!J764pkSwtɉD,HYܱsw]eD򎝭{&"ʀDÑ oC29?OZvw]SWíMlv1Qf!Ƹ;|wt#h ߈潋h>hho!]I!]~I~ )dQ׆ ﯌_M *ʘCץAX˷CWja ܫqg˲oDp|M`f`}D_<AZa Q`;{% hc!glȳ k[*XCL&ך=Zb.@.YYl`9% Ya>M+15S]" #S EHjgd6y5Xu!_BrK2dLݪ=ȭJ Ƞ<U0&9Bw^KZ~ =N'ho12Aau f ~v;CG{{j[ZQ=a~/%QꔎI'ZL5KCimvP森BUKPTSڵaz2Fu@&U3? ,vNvtEO'qv !7%qywCN?@ jL2lz'![ۤҐtYʷV~QNrEReJHҦWzp' 5ZLuJ=UGl-G[)ʴUNj[)ZGwI*_>m~ZB eJi2ijSVGi l1v:"mnVQJޡS=%Ӻ9)$MHǔ2k=>S-`JypĬU`Qɪ<&y*ʹ+aLԬa(ztj F<S :OnxnQ({rKtT28K=5=A1ZfU>/7ff"q07fz "iQa QULRDvQOXBwSiIf-HyZZ5.O0\}p%65=EJMK*sf*iYBìyjpDLL J4@ Êư~DJJ^H\!;-EKBBe?%hUZ̬j/+*6<Y%:W`n˽^jD5N hdo)t lSϟKKϙkYiqGm?1,+y@~8%?D1P"<:1=ẺD/4U^ 0,^ s^U@rq,"1*?S&_vilzS]jiSOs4$ )ѐ#-6R}4_!7iH"Vn.7KT"AnoA`RoC7)?Ez^R`{4X0g6سXbE.[C>,i|6V>L#:,cz^pbf-w!]5ε8jO"n|f KO.AOX5CAox[qp8־iI$6i> ׂg@LMR65(M%5df(r)MmM_qTczTiצ VtMMMM̻:p}3׀!p*px xM+C6IMTmZniMMM&zc Eu 0< _Y,QhZ߬G۵ZPh7tC^N_9zsTݩ뺪:qFyRkdu&k45xFsvST23T+ L~zeÌ}>x8KMwĕ`r >xj9G rp_:-& [~at=ׅ{CX{1_L[֩2Xu#<ʼnzB.w2'*n;w9;߽xWڢ…o,+ܮ+ ,%~WMg"=4&¾B$O2)e?#*:>Ak~{Y wF;#=2=.br*re}_UbMH0y:T] E\{S9QR(-[&uzcRp"dZCRgd$uNs.Q)K2sI]NRp;adl5;ۛxG{<ko+6ֶc;[:h;)n)k:6Gwi4h?3ѝήh<1Htw8hk3BpWEJx,Yl /R Qũ:fꂭ Z:{6*g-B NjjEQDwAj! $wZ=v]F?]W`Mܣ.-j5kEO~XZ`kh7 knFr6mE+fA-l:1`-IΠ}FMhQ̊l??as Kv3;e B4;V_]zoUjMzO 0ie endstream endobj 37 0 obj <>stream hTP=k0 +4t!+AvJjFqir${<6 i1B2N~fp%Xgٌ֭:Lv" Jȏ4"/puEynAEv4$JH;p)^ hrM[6ȚJz/H|g{Y'uxEW]9y\O_d CV!~k endstream endobj 38 0 obj <>stream htQ]k0+yl%ZPZg`]2Y/b Ʈ r99smF9 /抬v Ŝ8GîU\C44kMUpث <Cnyc3*F[ѿ@U^a4;kapFZ&2qn.]㞦P4U=Ҫ- >stream h8ktSǙ+]?1r][~ U[%,0DH1 Rp&I7Дe|v!/ O`C/58K F7 P#[?ZB& 8BpUJ4  0IrǨzx` 埑R Qx?¿BX H>j9aX#ǂ? qx #y}^ a>,uЂS{*gZC{NO_W0 "5$@a_hXDf4B/<%öʴƓY`lM샃8<WI5 4:@ωMFccܹ?h fnG#p=~ŤTe>ıКk+Ytz聭v)XT9l?El*|{N9ƓlU+i ɽl% $JΒW:]D26vC{i4BK1r`[I2={SA 6QA \ " b/{j9N*vk|&p>MhÝӃ/cX;^ oïo x'x>ϱ8|~3XzlkqN2@X9m\Y P/ѝ =LtJh̀+ꙓֱ{X/;cŞdGX T(-!,<%g ɠ%h- z> oYƷF@?9ێo5pNHꮮneEyY钻-\0^IqQ ;y9s;rsfgefJ:#%ٔ4}ZbB|d4 JOVs},]Zyŏm*n*t3y-۾fiNZ\ EC%kWy>hWNi!Wg!c6H*#qHB|R/*H| HUEtrG(H0+5S; SPYߪ68YfP%EFM&PQ Q#w~9R8:5Aϒت{TkWg}RW,Ryvm 9;eΆBU۵f{8Ҝ:_C*:]2F{Ő2 K|e5NQ:B}6!Camt!G1YoIPs 1UST1%O62=)F$NNtJ7申yg,3(8RK!(E3|V\N52s9W">ʇLcCS$'{ hbQ 1bU:WQa_ڔMX[o6B 2*/CKXK,^ffjt)OTɿ$S GGJҾE;]sZbupI]RgzXQ4Zܔ'9IT3蛺5jpW"ש&҉o675bi喩|~Jz! ^ O(dߪs j V]J'9NvJ*k 0k](]&ݒD̤)R8ޥ5'oKWU9+_y|gD\O_Za`)s#a~i!"d/rha?VrApZ|R5p'=.B! AAY._(&B#9.H5>Ur#a+ /B)V{! sG]5"8D;@X&<up2wSP؁,yK"DFi\'q '1ģhH3zJ>V`0@! ᆴp k7XMѿ /`cXe<-@;s pwA{d7֪QCGW"iz fp0f-Xn7P7!X:.Ee)#,n /9#[*ÖKsWW}ޗ dgGiQ #kMx'3{~^JvegY+>ɼ*dA(AC%˜,Y SR㖄䜵1|n7[ọ:cx1\l [cx1UJLt)Q$ @Jjo[-L :m'_Hn3:]5ĩ"7\JOTj&]-8FY]bqƦu!^tܞ(Ѹhod !ރY1BZ_uzuJUrY:_|[nM/B6 SG\BiX4K稇.zbW] m"}@,Ggb\_KcP=UێoPjba ڇlVC۽HZ"S=t+0:b! xo8Ս< 8#6ZNM5^Mǵe5i*}a*dR$ Vd*0\5_Ac*Y$T&'+5`fڳ?sL:0 ~ov1Y1D! qF!@ C/M4Wl4ݨ\aʱJ-L6'瘓ܔM_gDp0#㌐9͐8c3xtW|8I5(w޵hiÏ>vx&u\y5/0( Z@m@{!(< Al1trof(h=6 (AyE^ɵ[z{;7=]bKnl*7[V4,M-]+΂І?e8^ÿzcV2"iQީ[(Bb?Ɇ#u!nFI;zV "mxJFMЂ#ta$nېǷo]3D}P0A F#ңȶ{*?HgK_2Qƫ+R_؎O endstream endobj 40 0 obj <>stream hTP=o0 +>stream hj`@ 0@ endstream endobj 42 0 obj <>stream hެTێ0?B8BtSX-< qRGWjㄥ\ڪ[U"fg̜ )xH' (dIQJ=I"SX}ZQ m b?{DP/8Um'ǤBawk}Kk*6sr6+xem(xS{7C0ӽ_=5̝`v9C/BHaO<3@Q 9b`,~<bi_z%Zr;i<M3lFT&uz`۳pj C.Cf9\(!ӥPY7I'G)EFCeɡF ;#nx m]Qu%>stream h2P0P0T0T+- bB.vv endstream endobj 44 0 obj <>stream application/pdf Microsoft Word - TRAVIS Quick Start Guide.doc Brehministrator 2011-07-31T20:31:16+02:00 PScript5.dll Version 5.2.2 2011-07-31T20:31:16+02:00 Acrobat Distiller 9.0.0 (Windows) uuid:0ee7ab56-a084-4e0d-bd9d-57b4934e4d9c uuid:0321fff5-eed4-48f1-9274-7a744efeb977 endstream endobj 45 0 obj <>stream h27P0P07T01Q07R045Uw/+Q04L)(T~HeA~@bzjBTX-Dm 1PLA@(sE@#A. ne`% Ƅ4%X9 endstream endobj 46 0 obj <>stream h|J1@enM,(  -D:wdv=xmZ@nn+yr&,yx?7zwa0$o]\+L k\͞pS%/Tkw.Lcbms$ia'P8d[wzu FQx)9WIu endstream endobj 47 0 obj <>/Filter/FlateDecode/ID[<72A065978ADC8F8A791BDF4831C72D50><9B3220BBC5A5F9428B5A339FDEB4EF2A>]/Info 73 0 R/Length 172/Root 75 0 R/Size 74/Type/XRef/W[1 3 1]>>stream hbb&F L@Vd7U L!^"`w`=`H2peE80.!Dا 0Enb[fBa,"y_J`_|"5L`6ا|`6L9`A2 lCA& L1d3# endstream endobj startxref 116 %%EOF