CCP4: Add library to save MTZs
Some checks failed
Build Packages / build:rpm (ubuntu2404_nocuda) (push) Failing after 8m35s
Build Packages / build:rpm (rocky8_nocuda) (push) Failing after 10m40s
Build Packages / build:rpm (rocky9_nocuda) (push) Failing after 10m50s
Build Packages / Generate python client (push) Successful in 34s
Build Packages / build:rpm (ubuntu2204_nocuda) (push) Failing after 11m16s
Build Packages / Create release (push) Has been skipped
Build Packages / build:rpm (rocky8_sls9) (push) Failing after 11m25s
Build Packages / build:rpm (rocky8) (push) Failing after 11m29s
Build Packages / Build documentation (push) Successful in 53s
Build Packages / build:rpm (rocky9) (push) Failing after 11m45s
Build Packages / build:rpm (ubuntu2204) (push) Failing after 11m54s
Build Packages / Unit tests (push) Failing after 3m37s
Build Packages / build:rpm (ubuntu2404) (push) Failing after 6m40s

This commit is contained in:
2026-02-08 19:55:48 +01:00
parent 58f29409e6
commit d4d1f6cd9c
70 changed files with 50833 additions and 5 deletions

View File

@@ -138,6 +138,7 @@ ADD_SUBDIRECTORY(detector_control)
ADD_SUBDIRECTORY(image_puller)
ADD_SUBDIRECTORY(preview)
ADD_SUBDIRECTORY(symmetry)
ADD_SUBDIRECTORY(ccp4c)
IF (JFJOCH_WRITER_ONLY)
MESSAGE(STATUS "Compiling HDF5 writer only")

57
ccp4c/CMakeLists.txt Normal file
View File

@@ -0,0 +1,57 @@
set(ccp4c_SOURCES
ccp4/ccp4_array.c
ccp4/cmap_data.c
ccp4/cmtzlib.c
ccp4/ccp4_general.c
ccp4/cmap_header.c
ccp4/csymlib.c
ccp4/ccp4_parser.c
ccp4/cmap_labels.c
ccp4/cvecmat.c
ccp4/ccp4_program.c
ccp4/cmap_open.c
ccp4/library_err.c
ccp4/ccp4_unitcell.c
ccp4/cmap_skew.c
ccp4/library_file.c
ccp4/cmap_accessor.c
ccp4/cmap_stats.c
ccp4/library_utils.c
ccp4/cmap_close.c
ccp4/cmap_symop.c
ccp4/pack_c.c
)
set(ccp4c_HEADERS
ccp4/ccp4_file_err.h
ccp4/ccp4_program.h
ccp4/ccp4_unitcell.h
ccp4/cmap_errno.h
ccp4/cmap_stats.h
ccp4/csymlib.h
ccp4/library_file.h
ccp4/w32mvs.h
ccp4/ccp4_fortran.h
ccp4/ccp4_spg.h
ccp4/ccp4_utils.h
ccp4/cmap_header.h
ccp4/cmaplib.h
ccp4/cvecmat.h
ccp4/mtzdata.h
ccp4/ccp4_array.h
ccp4/ccp4_general.h
ccp4/ccp4_vars.h
ccp4/cmap_labels.h
ccp4/cmaplib_f.h
ccp4/overview.h
ccp4/ccp4_errno.h
ccp4/ccp4_parser.h
ccp4/ccp4_types.h
ccp4/cmap_data.h
ccp4/cmap_skew.h
ccp4/cmtzlib.h
ccp4/pack_c.h
ccp4/ccp4_sysdep.h
)
ADD_LIBRARY(ccp4c STATIC ${ccp4c_SOURCES} ${ccp4c_HEADERS})

685
ccp4c/COPYING Normal file
View File

@@ -0,0 +1,685 @@
GNU GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
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.
Section 15 has been amended in accordance with Section 7a) above to
address the requirements of UK law.
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 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.
Section 16 has been replaced in accordance with Section 7a) above to
address the requirements of UK law.
THE LICENSOR OR ANY THIRD PARTIES FROM WHOM IT HAS LICENSED ANY CODE
WILL NOT BE LIABLE FOR: ANY LOSS OF PROFITS, LOSS OF REVENUE, LOSS OR
CORRUPTION OF DATA, LOSS OF CONTRACTS OR OPPORTUNITY, LOSS OF SAVINGS
OR THIRD PARTY CLAIMS (IN EACH CASE WHETHER DIRECT OR INDIRECT), ANY
DIRECT OR INDIRECT LOSS OR DAMAGE ARISING OUT OF OR IN CONNECTION WITH
THE PROGRAM, IN EACH CASE, WHETHER THAT LOSS ARISES AS A RESULT OF
LICENSOR"S NEGLIGENCE, OR IN ANY OTHER WAY, EVEN IF LICENSOR HAS BEEN
ADVISED OF THE POSSIBILITY OF THAT LOSS ARISING, OR IF IT WAS WITHIN
LICENSOR'S CONTEMPLATION.
NONE OF THESE PROVISION LIMITS OR EXCLUDES THE LICENSOR"S LIABILITY
FOR DEATH OR PERSONAL INJURY CAUSED BY ITS NEGLIGENCE OR FOR ANY
FRAUD, OR FOR ANY SORT OF LIABILITY THAT, BY LAW, CANNOT BE LIMITED OR
EXCLUDED
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.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
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 <http://www.gnu.org/licenses/>.
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:
<program> Copyright (C) <year> <name of author>
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
<http://www.gnu.org/licenses/>.
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
<http://www.gnu.org/philosophy/why-not-lgpl.html>.

165
ccp4c/COPYING.LESSER Normal file
View File

@@ -0,0 +1,165 @@
GNU LESSER GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
This version of the GNU Lesser General Public License incorporates
the terms and conditions of version 3 of the GNU General Public
License, supplemented by the additional permissions listed below.
0. Additional Definitions.
As used herein, "this License" refers to version 3 of the GNU Lesser
General Public License, and the "GNU GPL" refers to version 3 of the GNU
General Public License.
"The Library" refers to a covered work governed by this License,
other than an Application or a Combined Work as defined below.
An "Application" is any work that makes use of an interface provided
by the Library, but which is not otherwise based on the Library.
Defining a subclass of a class defined by the Library is deemed a mode
of using an interface provided by the Library.
A "Combined Work" is a work produced by combining or linking an
Application with the Library. The particular version of the Library
with which the Combined Work was made is also called the "Linked
Version".
The "Minimal Corresponding Source" for a Combined Work means the
Corresponding Source for the Combined Work, excluding any source code
for portions of the Combined Work that, considered in isolation, are
based on the Application, and not on the Linked Version.
The "Corresponding Application Code" for a Combined Work means the
object code and/or source code for the Application, including any data
and utility programs needed for reproducing the Combined Work from the
Application, but excluding the System Libraries of the Combined Work.
1. Exception to Section 3 of the GNU GPL.
You may convey a covered work under sections 3 and 4 of this License
without being bound by section 3 of the GNU GPL.
2. Conveying Modified Versions.
If you modify a copy of the Library, and, in your modifications, a
facility refers to a function or data to be supplied by an Application
that uses the facility (other than as an argument passed when the
facility is invoked), then you may convey a copy of the modified
version:
a) under this License, provided that you make a good faith effort to
ensure that, in the event an Application does not supply the
function or data, the facility still operates, and performs
whatever part of its purpose remains meaningful, or
b) under the GNU GPL, with none of the additional permissions of
this License applicable to that copy.
3. Object Code Incorporating Material from Library Header Files.
The object code form of an Application may incorporate material from
a header file that is part of the Library. You may convey such object
code under terms of your choice, provided that, if the incorporated
material is not limited to numerical parameters, data structure
layouts and accessors, or small macros, inline functions and templates
(ten or fewer lines in length), you do both of the following:
a) Give prominent notice with each copy of the object code that the
Library is used in it and that the Library and its use are
covered by this License.
b) Accompany the object code with a copy of the GNU GPL and this license
document.
4. Combined Works.
You may convey a Combined Work under terms of your choice that,
taken together, effectively do not restrict modification of the
portions of the Library contained in the Combined Work and reverse
engineering for debugging such modifications, if you also do each of
the following:
a) Give prominent notice with each copy of the Combined Work that
the Library is used in it and that the Library and its use are
covered by this License.
b) Accompany the Combined Work with a copy of the GNU GPL and this license
document.
c) For a Combined Work that displays copyright notices during
execution, include the copyright notice for the Library among
these notices, as well as a reference directing the user to the
copies of the GNU GPL and this license document.
d) Do one of the following:
0) Convey the Minimal Corresponding Source under the terms of this
License, and the Corresponding Application Code in a form
suitable for, and under terms that permit, the user to
recombine or relink the Application with a modified version of
the Linked Version to produce a modified Combined Work, in the
manner specified by section 6 of the GNU GPL for conveying
Corresponding Source.
1) Use a suitable shared library mechanism for linking with the
Library. A suitable mechanism is one that (a) uses at run time
a copy of the Library already present on the user's computer
system, and (b) will operate properly with a modified version
of the Library that is interface-compatible with the Linked
Version.
e) Provide Installation Information, but only if you would otherwise
be required to provide such information under section 6 of the
GNU GPL, and only to the extent that such information is
necessary to install and execute a modified version of the
Combined Work produced by recombining or relinking the
Application with a modified version of the Linked Version. (If
you use option 4d0, the Installation Information must accompany
the Minimal Corresponding Source and Corresponding Application
Code. If you use option 4d1, you must provide the Installation
Information in the manner specified by section 6 of the GNU GPL
for conveying Corresponding Source.)
5. Combined Libraries.
You may place library facilities that are a work based on the
Library side by side in a single library together with other library
facilities that are not Applications and are not covered by this
License, and convey such a combined library under terms of your
choice, if you do both of the following:
a) Accompany the combined library with a copy of the same work based
on the Library, uncombined with any other library facilities,
conveyed under the terms of this License.
b) Give prominent notice with the combined library that part of it
is a work based on the Library, and explaining where to find the
accompanying uncombined form of the same work.
6. Revised Versions of the GNU Lesser General Public License.
The Free Software Foundation may publish revised and/or new versions
of the GNU Lesser 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
Library as you received it specifies that a certain numbered version
of the GNU Lesser General Public License "or any later version"
applies to it, you have the option of following the terms and
conditions either of that published version or of any later version
published by the Free Software Foundation. If the Library as you
received it does not specify a version number of the GNU Lesser
General Public License, you may choose any version of the GNU Lesser
General Public License ever published by the Free Software Foundation.
If the Library as you received it specifies that a proxy can decide
whether future versions of the GNU Lesser General Public License shall
apply, that proxy's public statement of acceptance of any version is
permanent authorization for you to choose that version for the
Library.

155
ccp4c/ccp4/ccp4_array.c Normal file
View File

@@ -0,0 +1,155 @@
/*
ccp4_array.c: implementation file for resizable array implementation.
Copyright (C) 2002 Kevin Cowtan
This library is free software: you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public License
version 3, modified in accordance with the provisions of the
license to address the requirements of UK law.
You should have received a copy of the modified GNU Lesser General
Public License along with this library. If not, copies may be
downloaded from http://www.ccp4.ac.uk/ccp4license.php
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.
*/
/** @file ccp4_array.c
* implementation file for resizable array implementation.
* Kevin Cowtan
*/
#include "ccp4_array.h"
/* rcsid[] = "$Id$" */
ccp4_ptr ccp4array_new_(ccp4_ptr *p)
{
ccp4array_base *v;
v = (ccp4array_base *)malloc(sizeof(ccp4array_base));
v->size = v->capacity = 0;
*p = (ccp4_ptr *)((ccp4_byteptr)(v)+sizeof(ccp4array_base));
return *p;
}
ccp4_ptr ccp4array_new_size_(ccp4_ptr *p, const int size, const size_t reclen)
{
ccp4array_base *v;
int capacity = (size * 12) / 10 + 2;
v = (ccp4array_base *)malloc(sizeof(ccp4array_base) + capacity * reclen);
v->size = size;
v->capacity = capacity;
*p = (ccp4_ptr *)((ccp4_byteptr)(v)+sizeof(ccp4array_base));
return *p;
}
void ccp4array_resize_(ccp4_ptr *p, const int size, const size_t reclen)
{
ccp4array_base *v;
v = (ccp4array_base *)((ccp4_byteptr)(*p)-sizeof(ccp4array_base));
if (size > v->capacity) {
v->capacity = (size * 12) / 10 + 2;
v = (ccp4array_base *)realloc(v, sizeof(ccp4array_base) + v->capacity * reclen);
*p = (ccp4_ptr *)((ccp4_byteptr)(v)+sizeof(ccp4array_base));
}
v->size = size;
}
void ccp4array_reserve_(ccp4_ptr *p, const int size, const size_t reclen)
{
ccp4array_base *v;
v = (ccp4array_base *)((ccp4_byteptr)(*p)-sizeof(ccp4array_base));
v->capacity = size;
if ( v->size > size ) v->size = size;
v = (ccp4array_base *)realloc(v, sizeof(ccp4array_base) + v->capacity * reclen);
*p = (ccp4_ptr *)((ccp4_byteptr)(v)+sizeof(ccp4array_base));
}
void ccp4array_append_(ccp4_ptr *p, ccp4_constptr data, const size_t reclen)
{
ccp4array_base *v;
int osize;
v = (ccp4array_base *)((ccp4_byteptr)(*p)-sizeof(ccp4array_base));
osize = v->size;
ccp4array_resize_(p, osize+1, reclen);
memcpy((ccp4_byteptr)(*p)+osize*reclen, data, reclen);
}
void ccp4array_append_n_(ccp4_ptr *p, ccp4_constptr data, const int n, const size_t reclen)
{
ccp4array_base *v;
ccp4_byteptr newdata;
int osize, i;
v = (ccp4array_base *)((ccp4_byteptr)(*p)-sizeof(ccp4array_base));
osize = v->size;
ccp4array_resize_(p, osize+n, reclen);
newdata = (ccp4_byteptr)(*p)+osize*reclen;
for ( i = 0; i < n; i++ ) {
memcpy(newdata, data, reclen);
newdata += reclen;
}
}
void ccp4array_append_list_(ccp4_ptr *p, ccp4_constptr data, const int n, const size_t reclen)
{
ccp4array_base *v;
int osize;
v = (ccp4array_base *)((ccp4_byteptr)(*p)-sizeof(ccp4array_base));
osize = v->size;
ccp4array_resize_(p, osize+n, reclen);
memcpy((ccp4_byteptr)(*p)+osize*reclen, data, n * reclen);
}
void ccp4array_insert_(ccp4_ptr *p, const int i, ccp4_constptr data, const size_t reclen)
{
ccp4array_base *v;
int osize;
v = (ccp4array_base *)((ccp4_byteptr)(*p)-sizeof(ccp4array_base));
osize = v->size;
ccp4array_resize_(p, osize+1, reclen);
memmove((ccp4_byteptr)(*p)+(i+1)*reclen, (ccp4_byteptr)(*p)+i*reclen, (osize-i)*reclen);
memcpy((ccp4_byteptr)(*p)+i*reclen, data, reclen);
}
void ccp4array_delete_ordered_(ccp4_ptr *p, const int i, const size_t reclen)
{
ccp4array_base *v;
int nsize;
v = (ccp4array_base *)((ccp4_byteptr)(*p)-sizeof(ccp4array_base));
nsize = v->size - 1;
memmove((ccp4_byteptr)(*p)+i*reclen, (ccp4_byteptr)(*p)+(i+1)*reclen, (nsize-i)*reclen);
v->size--; /* ccp4array_resize_(p, nsize, reclen); */
}
void ccp4array_delete_(ccp4_ptr *p, const int i, const size_t reclen)
{
ccp4array_base *v;
int nsize;
v = (ccp4array_base *)((ccp4_byteptr)(*p)-sizeof(ccp4array_base));
nsize = v->size - 1;
memcpy((ccp4_byteptr)(*p)+i*reclen, (ccp4_byteptr)(*p)+nsize*reclen, reclen);
v->size--; /* ccp4array_resize_(p, size, reclen); */
}
void ccp4array_delete_last_(ccp4_ptr *p, const size_t reclen)
{
ccp4array_base *v;
v = (ccp4array_base *)((ccp4_byteptr)(*p)-sizeof(ccp4array_base));
v->size--; /* ccp4array_resize_(p, v->size-1, reclen); */
}
int ccp4array_size_(ccp4_constptr *p)
{
ccp4array_base *v;
v = (ccp4array_base *)((ccp4_byteptr)(*p)-sizeof(ccp4array_base));
return v->size;
}
void ccp4array_free_(ccp4_ptr *p)
{
ccp4array_base *v;
v = (ccp4array_base *)((ccp4_byteptr)(*p)-sizeof(ccp4array_base));
free(v);
}

251
ccp4c/ccp4/ccp4_array.h Normal file
View File

@@ -0,0 +1,251 @@
/*
ccp4_array.h: header file for resizable array implementation.
Copyright (C) 2002 Kevin Cowtan
This library is free software: you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public License
version 3, modified in accordance with the provisions of the
license to address the requirements of UK law.
You should have received a copy of the modified GNU Lesser General
Public License along with this library. If not, copies may be
downloaded from http://www.ccp4.ac.uk/ccp4license.php
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.
*/
/** @file ccp4_array.h
* header file for resizable array implementation.
* Kevin Cowtan
*/
/*
CCP4 resizable array implementation.
This defines an object and methods which looks just like a simple C
array, but can be resized at will without incurring excessive
overheads.
A pointer to the desired type is created. Array elements are accessed
from this pointer as normal. Other operations depend on macros which
extract the stored type from the type of the pointer.
The array is managed with a header, which is positioned before the
beginning of the array. The malloc'ed memory area starts at the
beginning of this header. However the pointer to the header is not
stored, but rather derived from the array pointer whenever it is
required.
Arrays have a size and a capacity. The size is the number of elements
in use, and the capacity is the number of elements available before a
new memory allocation is required. When new memory is required, an
excess is reqested to allow the array to grow further before
performing another malloc.
If the precise amount of memory is known, the capacity can be
controlled directly using the 'reserve' macro.
Example: to handle an array of type mytype:
\code
int i;
mytype x,y;
mytype *array;
ccp4array_new(array);
ccp4array_append_n(array, x, 3);
for ( i = 0; i < 3; i++ ) y = array[i];
ccp4array_free(array);
\endcode
*/
#ifndef __CCP4_ARRAY_INC
#define __CCP4_ARRAY_INC
#ifdef __cplusplus
extern "C" {
#endif
#include <stdlib.h>
#include <string.h>
/* rcsidha[] = "$Id$" */
/*! constant pointer type */
typedef const void *ccp4_constptr;
/*! byte pointer type */
typedef char *ccp4_byteptr;
/*! pointer type */
typedef void *ccp4_ptr;
/*! struct definition for the array pre-header */
typedef struct ccp4array_base_ {
int size, capacity;
} ccp4array_base;
/*! Macro to allocate a new array.
The array is allocated with a size and capacity of 0
\param v The array pointer
\return The new array pointer (redundent)
*/
#define ccp4array_new(v) ccp4array_new_((ccp4_ptr*)(&v))
/*! Macro to allocate a new array with non-zero size.
The array is allocated with a size of s and capacity of at least s
\param v The array pointer
\param s The new size
\return The new array pointer (redundent)
*/
#define ccp4array_new_size(v,s) ccp4array_new_size_((ccp4_ptr*)(&v),s,sizeof(*v))
/*! Macro to resize an array.
This changes the size. Memory allocation only takes place if the new
size is greater than the capacity. If that occurs, the new capacity
will be slightly greater than the requested size, to allow room for
expansion.
\param v The array pointer
\param s The new size
*/
#define ccp4array_resize(v,s) ccp4array_resize_((ccp4_ptr*)(&v),s,sizeof(*v))
/*! Macro to reserve space for an array.
This forces a memory reallocation. The size of the array is
unchanged, unless the new capacity is less than the current size, in
which case the size is set to the new capacity. Unlike resize, the
new allocation will be exactly the size of the array.
\param v The array pointer
\param s The new capacity
*/
#define ccp4array_reserve(v,s) ccp4array_reserve_((ccp4_ptr*)(&v),s,sizeof(*v))
/*! Macro to append an element to an array.
This increments the size. Memory allocation only takes place if the new
size is greater than the capacity.
\param v The array pointer
\param d The new element (may not be a literal)
*/
#define ccp4array_append(v,d) ccp4array_append_((ccp4_ptr*)(&v),(ccp4_constptr)(&d),sizeof(*v))
/*! Macro to append n copies of an element to an array.
This increments the size by n. Memory allocation only takes place if the new
size is greater than the capacity.
\param v The array pointer
\param d The new element (may not be a literal)
\param n The number of copies to append
*/
#define ccp4array_append_n(v,d,n) ccp4array_append_n_((ccp4_ptr*)(&v),(ccp4_constptr)(&d),n,sizeof(*v))
/*! Macro to append n elements from another list to an array.
This increment the size by n. Memory allocation only takes place if the new
size is greater than the capacity.
\param v The array pointer
\param l Pointer to the list
\param n The number of copies to append
*/
#define ccp4array_append_list(v,l,n) ccp4array_append_list_((ccp4_ptr*)(&v),(ccp4_constptr)l,n,sizeof(*v))
/*! Macro to insert an element before the element[i] of an array.
This increments the size. All subsequent elements are moved up. As a
result this method is slow.
\param v The array pointer
\param d The new element (may not be a literal)
\param i The element before which the insertion is to be made.
*/
#define ccp4array_insert(v,i,d) ccp4array_insert_((ccp4_ptr*)(&v),i,(ccp4_constptr)(&d),sizeof(*v))
/*! Macro to delete element[i] of an array, preserving order.
This decrements the size. All subsequent elements are moved down. As a
result this method is slow.
\param v The array pointer
\param i The element to be deleted
*/
#define ccp4array_delete_ordered(v,i) ccp4array_delete_ordered_((ccp4_ptr*)(&v),i,sizeof(*v))
/*! Macro to delete element[i] of an array without preserving order. The
last element is moved into the gap, and the size is decremented.
\param v The array pointer
\param i The element to be deleted
*/
#define ccp4array_delete(v,i) ccp4array_delete_((ccp4_ptr*)(&v),i,sizeof(*v))
/*! Macro to delete the last element of an array.
This decrements the size.
\param v The array pointer
*/
#define ccp4array_delete_last(v) ccp4array_delete_last_((ccp4_ptr*)(&v),sizeof(*v))
/*! Macro to return the size of the array.
\param v The array pointer
\return The size (int)
*/
#define ccp4array_size(v) ccp4array_size_((ccp4_constptr*)(&v))
/*! Macro free the array.
All memory, including the header, is freed.
\param v The array pointer
*/
#define ccp4array_free(v) ccp4array_free_((ccp4_ptr*)(&v))
/**
* See macro ccp4array_new
*/
ccp4_ptr ccp4array_new_(ccp4_ptr *p);
/**
* See macro ccp4array_new_size
*/
ccp4_ptr ccp4array_new_size_(ccp4_ptr *p, const int size, const size_t reclen);
/**
* See macro ccp4array_resize
*/
void ccp4array_resize_(ccp4_ptr *p, const int size, const size_t reclen);
/**
* See macro ccp4array_reserve
*/
void ccp4array_reserve_(ccp4_ptr *p, const int size, const size_t reclen);
/**
* See macro ccp4array_append
*/
void ccp4array_append_(ccp4_ptr *p, ccp4_constptr data, const size_t reclen);
/**
* See macro ccp4array_append_n
*/
void ccp4array_append_n_(ccp4_ptr *p, ccp4_constptr data, const int n, const size_t reclen);
/**
* See macro ccp4array_append_list
*/
void ccp4array_append_list_(ccp4_ptr *p, ccp4_constptr data, const int n, const size_t reclen);
/**
* See macro ccp4array_insert
*/
void ccp4array_insert_(ccp4_ptr *p, const int i, ccp4_constptr data, const size_t reclen);
/**
* See macro ccp4array_delete_ordered
*/
void ccp4array_delete_ordered_(ccp4_ptr *p, const int i, const size_t reclen);
/**
* See macro ccp4array_delete
*/
void ccp4array_delete_(ccp4_ptr *p, const int i, const size_t reclen);
/**
* See macro ccp4array_delete_last
*/
void ccp4array_delete_last_(ccp4_ptr *p, const size_t reclen);
/**
* See macro ccp4array_size
*/
int ccp4array_size_(ccp4_constptr *p);
/**
* See macro ccp4array_free
*/
void ccp4array_free_(ccp4_ptr *p);
#ifdef __cplusplus
}
#endif
#endif /* __CCP4_ARRAY_INC */

166
ccp4c/ccp4/ccp4_errno.h Normal file
View File

@@ -0,0 +1,166 @@
/*
ccp4_errno.h: Header file for error handling routines
Copyright (C) 2001 CCLRC, Charles Ballard and Martyn Winn
This library is free software: you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public License
version 3, modified in accordance with the provisions of the
license to address the requirements of UK law.
You should have received a copy of the modified GNU Lesser General
Public License along with this library. If not, copies may be
downloaded from http://www.ccp4.ac.uk/ccp4license.php
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.
*/
/** @file ccp4_errno.h
* Header file for error handling routines
* base error codes on system errors.
*/
#ifndef __CCP4_ERROR_GUARD
#define __CCP4_ERROR_GUARD
#include <errno.h>
#include "ccp4_sysdep.h"
/* rcsidhe[] = "$Id$" */
#ifndef CCP4_ERRSYSTEM
#define CCP4_ERRSYSTEM(x) (((x)&0xfff)<<24)
#endif
#ifndef CCP4_ERRLEVEL
#define CCP4_ERRLEVEL(x) (((x)&0xf)<<16)
#endif
#ifndef CCP4_ERRSETLEVEL
#define CCP4_ERRSETLEVEL(y,x) ((y) & (~CCP4_ERRLEVEL(0xf)) | CCP4_ERRLEVEL(x)))
#endif
#ifndef CCP4_ERRGETSYS
#define CCP4_ERRGETSYS(x) (((x)>>24)&0xfff)
#endif
#ifndef CCP4_ERRGETLEVEL
#define CCP4_ERRGETLEVEL(x) (((x)>>16)&0xf)
#endif
#ifndef CCP4_ERRGETCODE
#define CCP4_ERRGETCODE(x) ((x)&0xffff)
#endif
#define CCP4_ERR_SYS CCP4_ERRSYSTEM(0x0)
#define CCP4_ERR_FILE CCP4_ERRSYSTEM(0x1)
#define CCP4_ERR_COORD CCP4_ERRSYSTEM(0x2)
#define CCP4_ERR_MTZ CCP4_ERRSYSTEM(0x3)
#define CCP4_ERR_MAP CCP4_ERRSYSTEM(0x4)
#define CCP4_ERR_UTILS CCP4_ERRSYSTEM(0x5)
#define CCP4_ERR_PARS CCP4_ERRSYSTEM(0x6)
#define CCP4_ERR_SYM CCP4_ERRSYSTEM(0x7)
#define CCP4_ERR_GEN CCP4_ERRSYSTEM(0x8)
#define CCP4_COUNT(x) sizeof(x)/sizeof(x[0])
/** @global ccp4_errno: global variable that stores the error last error
* code from the ccp4 libraries
* | 12 bits - library | 4 bits - level | 16 bits - code |
*
* associated macros
* CCP4_ERR_SYS 0 OS error
* CCP4_ERR_FILE 1 io library
* CCP4_ERR_COORD 2 mmdb
* CCP4_ERR_MTZ 3 cmtz
* CCP4_ERR_MAP 4 map io
* CCP4_ERR_UTILS 5 utility routines
* CCP4_ERR_PARS 6 parser routines
* CCP4_ERR_SYM 7 csymlib
*
* and bit manipulation
* CCP4_ERRSYSTEM system mask for setting
* CCP4_ERRLEVEL error level mask
* CCP4_ERRSETLEVEL error level mask for setting error level
* CCP4_ERRGETSYS mask for returning system
* CCP4_ERRGETLEVEL mask for returning level
* CCP4_ERRGETCODE mask for returning the code
*
* error levels
* 0 Success
* 1 Informational
* 2 Warning
* 3 Error
* 4 Fatal
*/
#ifdef __cplusplus
extern "C" {
#endif
extern CCP4_DL_IMPORT(int) ccp4_errno;
#ifdef __cplusplus
}
#endif
#ifdef __cplusplus
namespace CCP4 {
extern "C" {
#endif
/** Print out passed message and internal message based upon
* ccp4_errno
* "message : error message "
* @param message (const char *)
* @return void
*/
void ccp4_error( const char *);
/** Obtain character string based upon error code.
* Typical use ccp4_strerror(ccp4_errno)
* The returned string is statically allocated in the
* library_err.c file and should not be freed.
* @param error code (int)
* @return const pointer to error message (const char *)
*/
const char *ccp4_strerror( int);
/** Wrapper for ccp4_error which also calls exit(1)
* @param message (const char *)
* @return void
*/
void ccp4_fatal(const char *);
/** Function to set verbosity level for messages from
* ccp4_signal. Currently just off (0) and on (1).
* It should be generalised to be able to switch
* individual components on and off, i.e. replace 1 by
* a mask.
* cf. ccp4VerbosityLevel which sets the verbosity level
* for ccp4printf These are separate as they may be used
* differently.
* @param iverb If >= 0 then set the verbosity level to the
* value of iverb. If < 0 (by convention -1) then report
* current level.
* @return current verbosity level
*/
int ccp4_liberr_verbosity(int iverb);
/** Routine to set ccp4_errno and print out message for
* error tracing. This should be the only way in
* which ccp4_errno is set.
* See error codes above for levels and systems.
* A callback with prototype void function(void)
* may also be passed to the routine.
* Note: FATAL calls exit(1).
* If ccp4_liberr_verbosity returns 0, then ccp4_signal sets
* ccp4_errno and returns without doing anything else.
* @param error code (int)
* @param message (const char * const)
* @param callback (point to routine void (*)(void) )
* @return void
*/
void ccp4_signal(const int, const char *const, void (*)());
int cfile_perror(const char *);
#ifdef __cplusplus
}
}
#endif
#endif /*!CCP4_ERROR_GUARD */

View File

@@ -0,0 +1,38 @@
/*
ccp4_file_err.h: header file with file handling error codes
Copyright (C) 2001 CCLRC, Charles Ballard
This library is free software: you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public License
version 3, modified in accordance with the provisions of the
license to address the requirements of UK law.
You should have received a copy of the modified GNU Lesser General
Public License along with this library. If not, copies may be
downloaded from http://www.ccp4.ac.uk/ccp4license.php
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.
*/
#ifndef _GUARD_FILE_ERR
#define _GUARD_FILE_ERR
#define CCP4_ERRNO(y) (CCP4_ERR_FILE | (y))
#define CIO_Ok 0
#define CIO_BadMode 1
#define CIO_CantOpenFile 2
#define CIO_MaxFile 3
#define CIO_ReadFail 4
#define CIO_WriteFail 5
#define CIO_CloseFail 6
#define CIO_SeekFail 7
#define CIO_NullPtr 8
#define CIO_EOF 9
#define CIO_NoFile 10
#define CIO_NotOpen 11
#define CIO_UnlinkFail 12
#endif

393
ccp4c/ccp4/ccp4_fortran.h Normal file
View File

@@ -0,0 +1,393 @@
/*
ccp4_fortran.h: header file for Fortran APIs
Copyright (C) 2001 Eugene Krissinel
This library is free software: you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public License
version 3, modified in accordance with the provisions of the
license to address the requirements of UK law.
You should have received a copy of the modified GNU Lesser General
Public License along with this library. If not, copies may be
downloaded from http://www.ccp4.ac.uk/ccp4license.php
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.
*/
/** @file ccp4_fortran.h
* header file for Fortran APIs
* Eugene Krissinel
*/
#ifndef __CCP4_FORTRAN
#define __CCP4_FORTRAN
#include "ccp4_types.h"
/* rcsidhh[] = "$Id$" */
/* stardent is now obsolete, but we retain this category in case it is useful later */
#ifdef CALL_LIKE_STARDENT
/* SStrParam is used in Ardent-like machines' fortran calls */
/* for passing a string parameter */
DefineStructure(SStrPar)
struct SStrPar {
pstr S;
int len;
int id;
};
#endif
#define _LVTOB(l) ((long) ((l) == 0 ? 0 : 1))
#define _BTOLV(l) ((int) ((l) == 0 ? 0 : 1))
#if defined (__OSF1__) || defined (__osf__)
#undef _BTOLV
#define _BTOLV(l) ((int) ((l) == 0 ? 0 : -1))
#endif
/*
Macro FORTRAN_SUBR(NAME,name,p_send,p_sstruct,p_sflw)
makes function header statements that allow for linking with
programs written in FORTRAN.
Parameters:
NAME name of the FORTRAN subroutine in capital letters
name name of the FORTRAN subroutine in small letters
p_send parameter list (in brackets) with string lengths
attached to the end of it (see below)
p_sstruct parameter list (in brackets) with strings passed
as complex parameters, or structures
p_sflw parameter list (in brackets) with string lengths
following immediately the string parameters
(see below)
All non-string parameters must be passed as pointers, in
the same order as they enter the FORTRAN call. Rules for
the string parameters are as follows.
1. All strings should be specified as of 'fpstr' type.
The 'fpstr' type is defined below and depends on the
platform:
a) whenever length of string is passed as a separate
parameter ( CALL_LIKE_SUN, CALL_LIKE_HPUX,
CALL_LIKE_MVS ) 'fpstr' is identical to 'pstr'.
You may choose arbitrary name for the string,
but you MUST use the same name, appended with
suffix '_len', for its length (see example below).
b) whenever string and its length are passed as
complex parameter, 'fpstr' is identical to the
pointer on the corresponding structure:
CALL_LIKE_STARDENT :
'fpstr' is identical to 'PSStrPar'
CALL_LIKE_VMS :
'fpstr' is identical to 'dsc$descriptor_s *'
With 'fpstr' type, two important macro definition come:
i) FTN_STR(s) - returns pointer to fortran-passed
string s. This pointer is always
of 'pstr' type
ii) FTN_LEN(s) - returns integer length of fortran-
passed string s. For this macro to
work properly with SUN- and MVS-like
machines, always use suffix '_len'
for the string length parameters as
described in a) above.
2. Three parameter lists, each enclosed in brackets, should
be given. These lists retain the general order of
parameters in the corresponding fortran call. Non-string
parameters are passed as pointers. String parameters
and their lengths are passed differently in different
lists:
p_send strings enter their place in the list as in
the corresponding FORTRAN call, having 'fpstr'
parameter type. Their lengths are appended as
'int' to the end of the list. They should
retain the order in which the strings appear
in the list.
p_sstruct strings enter their place in the list as in
the corresponding FORTRAN call, having 'fpstr'
parameter type.
p_sflw strings enter their place in the list as in
the corresponding FORTRAN call, having 'fpstr'
type and being immediately followed by their
lengths as 'int' parameters.
Example:
FORTRAN statement
subroutine SomeSub ( k,s1,a,s2,m )
integer k,m
real a
character*(*) s1,s2
is translated to
FORTRAN_SUBR ( SOMESUB, somesub,
( int * k, fpstr s1, float * a, fpstr s2, int * m,
int s1_len, int s2_len ),
( int * k, fpstr s1, float * a, fpstr s2, int * m ),
( int * k, fpstr s1, int s1_len, float * a,
fpstr s2, int s2_len, int * m ) )
The macro should replace ordinary function header
statements to assure compatibility with FORTRAN links.
In header files, do not forget to add semicolumn:
FORTRAN_SUBR ( .... );
while in source files use simply
FORTRAN_SUBR ( .... ) {
<source body, operators>
}
Macro FORTRAN_CALL(NAME,name,p_send,p_sstruct,p_sflw)
calls function defined with macro FORTRAN_SUBR(...), from
a C/C++ application. Its parameters and their meaning are
exactly identical to those of FORTRAN_SUBR(...).
FORTRAN_CALL(...) should be followed by semicolon. */
#if defined(CALL_LIKE_SUN)
typedef pstr fpstr;
#if __GNUC__ > 7 || __clang_major__ > 10
typedef size_t fpstr_size_t;
#else
typedef int fpstr_size_t;
#endif
#define FTN_STR(s) s
#define FTN_LEN(s) s##_len
#define char_struct(s) \
pstr s; \
int s##_len;
#define fill_char_struct(s,str) \
s = str; \
s##_len = strlen(str);
#define init_char_struct(s,str,size) \
s = str; \
s##_len = size;
#define FORTRAN_SUBR(NAME,name,p_sun,p_stardent,p_mvs) \
void name##_ p_sun
#define FORTRAN_CALL(NAME,name,p_sun,p_stardent,p_mvs) \
name##_ p_sun
#define FORTRAN_FUN(val,NAME,name,p_sun,p_stardent,p_mvs) \
val name##_ p_sun
#elif defined(CALL_LIKE_HPUX)
typedef pstr fpstr;
typedef int fpstr_size_t;
# define FTN_STR(s) s
# define FTN_LEN(s) s##_len
# define char_struct(s) \
pstr s; \
int s##_len;
# define fill_char_struct(s,str) \
s = str; \
s##_len = strlen(str);
# define init_char_struct(s,str,size) \
s = str; \
s##_len = size;
# define FORTRAN_SUBR(NAME,name,p_sun,p_stardent,p_mvs) \
void name p_sun
# define FORTRAN_CALL(NAME,name,p_sun,p_stardent,p_mvs) \
name p_sun
# define FORTRAN_FUN(val,NAME,name,p_sun,p_stardent,p_mvs) \
val name p_sun
#elif defined(CALL_LIKE_STARDENT)
typedef PStrPar fpstr;
typedef int fpstr_size_t;
# define FTN_STR(s) s->Str_pointer
# define FTN_LEN(s) s->Str_length
# define char_struct(s) \
SStrPar s;
# define fill_char_struct(s,str) \
s.S = str; \
s.len = strlen(FName); \
s.id = 0;
# define init_char_struct(s,str,size) \
s.S = str; \
s.len = size; \
s.id = 0;
# define FORTRAN_SUBR(NAME,name,p_send,p_sstruct,p_sflw) \
void NAME p_stardent
# define FORTRAN_CALL(NAME,name,p_send,p_sstruct,p_sflw) \
NAME p_stardent
# define FORTRAN_FUN(val,NAME,name,p_send,p_sstruct,p_sflw) \
val NAME p_stardent
#elif defined(CALL_LIKE_VMS)
typedef dsc$descriptor_s * fpstr;
# define FTN_STR(s) s->dsc$a_pointer;
# define FTN_LEN(s) s->dsc$w_length;
# define char_struct(s) \
dsc$descriptor_s s;
# define fill_char_struct(s,str) \
s.dsc$a_pointer = str; \
s.dsc$w_length = strlen(str); \
s.dsc$b_dtype = DSC$K_DTYPE_T; \
s.dsc$b_class = DSC$K_CLASS_S;
# define init_char_struct(s,str,size) \
s.dsc$a_pointer = str; \
s.dsc$w_length = size; \
s.dsc$b_dtype = DSC$K_DTYPE_T; \
s.dsc$b_class = DSC$K_CLASS_S;
# define FORTRAN_SUBR(NAME,name,p_sun,p_stardent,p_mvs) \
void NAME p_stardent
# define FORTRAN_CALL(NAME,name,p_sun,p_stardent,p_mvs) \
NAME p_stardent
# define FORTRAN_FUN(val,NAME,name,p_sun,p_stardent,p_mvs) \
val NAME p_stardent
#elif defined(CALL_LIKE_MVS)
#if (CALL_LIKE_MVS == 2)
typedef pstr fpstr;
typedef int fpstr_size_t;
#define FTN_STR(s) s
#define FTN_LEN(s) s##_len
#define char_struct(s) \
pstr s; \
int s##_len;
#define fill_char_struct(s,str) \
s = str; \
s##_len = strlen(str);
#define init_char_struct(s,str,size) \
s = str; \
s##_len = size;
#define FORTRAN_SUBR(NAME,name,p_sun,p_stardent,p_mvs) \
void NAME p_sun
#define FORTRAN_CALL(NAME,name,p_sun,p_stardent,p_mvs) \
NAME p_sun
#define FORTRAN_FUN(val,NAME,name,p_sun,p_stardent,p_mvs) \
val NAME p_sun
#else
typedef pstr fpstr;
typedef int fpstr_size_t;
# define FTN_STR(s) s
# define FTN_LEN(s) s##_len
# define char_struct(s) \
pstr s; \
int s##_len;
# define fill_char_struct(s,str) \
s = str; \
s##_len = strlen(str);
# define init_char_struct(s,str,size) \
s = str; \
s##_len = size;
# define FORTRAN_SUBR(NAME,name,p_sun,p_stardent,p_mvs) \
void __stdcall NAME p_mvs
# define FORTRAN_CALL(NAME,name,p_sun,p_stardent,p_mvs) \
NAME p_mvs
# define FORTRAN_FUN(val,NAME,name,p_sun,p_stardent,p_mvs) \
val __stdcall NAME p_mvs
# endif
#else
# error Unknown machine!!!
typedef pstr fpstr;
typedef int fpstr_size_t;
# define FTN_STR(s) s
# define FTN_LEN(s) s##_len
# define char_struct(s) \
pstr s; \
int s##_len;
# define fill_char_struct(s,str) \
s = str; \
s##_len = strlen(str);
# define init_char_struct(s,str,size) \
s = str; \
s##_len = size;
/** Macro to define a function such that it is callable as
* a Fortran subroutine.
* @param NAME Subroutine name in upper case
* @param name Subroutine name in lower case
* @param p_sun Argument list in Sun style
* @param p_stardent Argument list in Stardent style
* @param p_mvs Argument list in MVS style
*/
# define FORTRAN_SUBR(NAME,name,p_sun,p_stardent,p_mvs) \
void name##_ p_sun
/** Macro to call a Fortran subroutine from a C function.
* @param NAME Subroutine name in upper case
* @param name Subroutine name in lower case
* @param p_sun Argument list in Sun style
* @param p_stardent Argument list in Stardent style
* @param p_mvs Argument list in MVS style
*/
# define FORTRAN_CALL(NAME,name,p_sun,p_stardent,p_mvs) \
name##_ p_sun
/** Macro to define a function such that it is callable as
* a Fortran function.
* @param val Data type of return value.
* @param NAME Function name in upper case
* @param name Function name in lower case
* @param p_sun Argument list in Sun style
* @param p_stardent Argument list in Stardent style
* @param p_mvs Argument list in MVS style
*/
# define FORTRAN_FUN(val,NAME,name,p_sun,p_stardent,p_mvs) \
val name##_ p_sun
#endif
/* Define Fortran logical */
typedef unsigned int ftn_logical;
#define FORTRAN_LOGICAL_TRUE 1
#define FORTRAN_LOGICAL_FALSE 0
#if defined (__OSF1__) || defined (__osf__)
# undef FORTRAN_LOGICAL_TRUE
# define FORTRAN_LOGICAL_TRUE -1
#endif
char *ccp4_FtoCString(fpstr str1, int str1_len);
void ccp4_CtoFString(fpstr str1, int str1_len, const char *cstring);
#endif /* __CCP4_FORTRAN */

1436
ccp4c/ccp4/ccp4_general.c Normal file

File diff suppressed because it is too large Load Diff

124
ccp4c/ccp4/ccp4_general.h Normal file
View File

@@ -0,0 +1,124 @@
/*
ccp4_general.h: header for general library functions and utilities.
Copyright (C) 2001 CCLRC, Peter Briggs et al
This library is free software: you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public License
version 3, modified in accordance with the provisions of the
license to address the requirements of UK law.
You should have received a copy of the modified GNU Lesser General
Public License along with this library. If not, copies may be
downloaded from http://www.ccp4.ac.uk/ccp4license.php
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.
*/
/* ccp4_general.c
Header file for CCP4 library clones
Peter Briggs et al CCP4 April 2001
*/
/*------------------------------------------------------------------*/
/* Macro definitions */
/*------------------------------------------------------------------*/
#ifndef __CCPGeneral__
#define __CCPGeneral__
/* rcsidhl[] = "$Id$" */
/* note order: this must be outside CCP4 namespace */
#include "ccp4_parser.h"
#ifdef __cplusplus
namespace CCP4 {
extern "C" {
#endif
/* MAXLINE = maximum number of characters in lines read
from environ.def and default.def files (ccp4fyp)
MAXTOKS = maximum number of tokens in lines read from
environ.def and default.def files (ccp4fyp)
MAXNAMES = maximum number of logical names that can be
read and stored from environ.def (ccp4fyp)
*/
#define CCP4_MAXLINE 200
#define CCP4_MAXTOKS 3
#define CCP4_MAXNAMES 150
#define CCP4_MODULO 100000
/* stuff for error reporting */
#define CGEN_ERRNO(n) (CCP4_ERR_GEN | (n))
/* error defs */
#define CGENERR_Ok 0
#define CGENERR_AllocFail 1
#define CGENERR_CantSetEnvironment 2
#define CGENERR_MaxNamesExceeded 3
#define CGENERR_EOptionUseError 4
#define CGENERR_DOptionUseError 5
#define CGENERR_LogicalNameUseError 6
#define CGENERR_CantOpenEnvFile 7
#define CGENERR_CantOpenDefFile 8
#define CGENERR_ParseEnvFail 9
#define CGENERR_ParseDefFail 10
#define CGENERR_CantFindInFile 11
#define CGENERR_EnvPathFail 12
#define CGENERR_DefPathFail 13
#define CGENERR_CantGetClibd 14
#define CGENERR_CantGetCcp4Scr 15
/*------------------------------------------------------------------*/
/* Structures and typedefs */
/*------------------------------------------------------------------*/
/* <None declared> */
/*------------------------------------------------------------------*/
/* Function Prototypes */
/*------------------------------------------------------------------*/
void ccp4f_mem_tidy(void);
int ccperror(int ierr, const char *message);
int ccperror_noexit(int ierr, const char *message);
int ccp4printf(int level, char *format, ...);
int ccp4fyp(int argc, char **argv);
int ccp4fyp_cleanup(int ienv, char **envname, char **envtype, char **envext,
char *logical_name, char *file_name, char *file_type,
char *file_ext, char *env_file, char *def_file,
char *dir, CCP4PARSERARRAY *parser);
int ccp4setenv(char *logical_name, char* value, char **envname,
char **envtype, char **envext, int *ienv, int no_overwrt);
int ccp4setenv_cleanup(char *file_ext, char *file_root, char *file_path,
char *file_name);
int ccpexists(char *filename);
int ccpputenv(char *logical_name, char *file_name);
void ccp4_banner(void);
#ifdef __cplusplus
}
}
#endif
#endif /* __CCPGeneral__ */

1738
ccp4c/ccp4/ccp4_parser.c Normal file

File diff suppressed because it is too large Load Diff

308
ccp4c/ccp4/ccp4_parser.h Normal file
View File

@@ -0,0 +1,308 @@
/*
ccp4_parser.h: Headers for functions to read in and "parse" CCP4 keyworded input.
Copyright (C) 2001 CCLRC, Peter Briggs
This library is free software: you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public License
version 3, modified in accordance with the provisions of the
license to address the requirements of UK law.
You should have received a copy of the modified GNU Lesser General
Public License along with this library. If not, copies may be
downloaded from http://www.ccp4.ac.uk/ccp4license.php
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.
*/
/** @page cparser_page CParser library
*
* @verbatim
<!-- ::INDEX_INFO::CParser library::Library::::C Software Library for CCP4-style parsing:::::::: -->
@endverbatim
*
* @section cparser_file_list File list
<ul>
<li>ccp4_parser.h - contains details of the C/C++ API
</ul>
* @section cparser_overview Overview
These functions do CCP4-style parsing, as used for processing keywords
of CCP4 programs, MTZ header records, etc.
* @section cparser_usage Usage
The following code snippets illustrate how the functions might be used
to read from stdin:
<pre>
int ntok=0;
char line[201],*key;
CCP4PARSERTOKEN * token=NULL;
CCP4PARSERARRAY * parser;
parser = (CCP4PARSERARRAY *) ccp4_parse_start(20);
key = parser->keyword;
token = parser->token;
RC = 0;
while (!RC) {
line[0] = '\0';
ntok = ccp4_parser(line,200,parser,1);
if (ntok < 1) {
RC = 111;
} else {
if (ccp4_keymatch("MINDIST",key)) {
if (ntok != 2) {
ccperror ( 1,"MINDIST requires a single numerical argument" );
RC = -100;
} else {
minDist = token[1].value;
}
} else {
printf ( "Unrecognised keyword \"%s\"\n",token[0].fullstring );
RC = -118;
}
}
}
ccp4_parse_end ( parser );
</pre>
* @section cparser_examples Examples
See the distributed programs <a href="../ncont.html">NCONT</a> and
<a href="../pdbcur.html">PDBCUR</a>.
*/
/** @file ccp4_parser.h
*
* @brief Functions to read in and "parse" CCP4-style keyworded input.
*
* @author Peter Briggs
* @date April 2001
*/
/*------------------------------------------------------------------*/
/* Macro definitions */
/*------------------------------------------------------------------*/
#ifndef __CCP4_Parser__
#define __CCP4_Parser__
/* rcsidhhh[] = "$Id$" */
/* note order: these must be outside CCP4 namespace */
#include <stdio.h>
#include"ccp4_utils.h"
#include"ccp4_spg.h"
/* Macro to make C functions callable from C++ */
#ifdef __cplusplus
namespace CCP4 {
extern "C" {
typedef CSym::ccp4_symop ccp4_symop;
#endif
/*------------------------------------------------------------------*/
/* Structures and typedefs */
/*------------------------------------------------------------------*/
/* CCP4 Parser token
Construct to hold the information about a single token */
typedef struct {
char *fullstring; /* Full string containing all of token */
char word[5]; /* First four characters of token */
double value; /* Equivalent numerical value */
int isstring; /* Flag: true if token is character string */
int strlength; /* Number of characters in whole token (strings only) */
int isnumber; /* Flag: true if token is number */
int intdigits; /* Number of 'digits' preceeding the decimal point
(numbers only) */
int frcdigits; /* Number of 'digits' after the decimal point (numbers
only) */
int isquoted; /* Flag: true if token is contained in quotes */
int isnull; /* Flag: true if token is null field */
int ibeg,iend; /* Begin and end character positions of token
in input line */
} CCP4PARSERTOKEN;
/* CCP4 Parser array
Construct to hold the information about a parsed line */
typedef struct {
/* "Public" members */
char keyword[5]; /* Keyword (=token[1].token, uppercased) */
int ntokens; /* Number of tokens */
CCP4PARSERTOKEN *token; /* Array of tokens */
/* "Private" members */
FILE *fp; /* Pointer to an external command file */
int maxtokens; /* Maximum number of tokens allowed */
char *delim; /* List of delimiter characters */
char *nulldelim; /* List of null delimiter characters */
char *comment; /* List of comment characters */
double max_exponent; /* Largest allowed exponent for numerical tokens */
double min_exponent; /* Smallest allowed exponent for numerical tokens */
} CCP4PARSERARRAY;
/*------------------------------------------------------------------*/
/* Function Prototypes */
/*------------------------------------------------------------------*/
/* Core cparser functions */
/** Initialise a CCP4PARSERARRAY to be used in subsequent calls to
* ccp4_parser routines. The calling function must supply the maximum
* number of tokens on a line (including continuation lines).
* @param maxtokens maximum number of tokens on a line
* @return pointer to a new CCP4PARSERARRAY structure
*/
CCP4PARSERARRAY* ccp4_parse_start(const int maxtokens);
/** Cleans up a CCP4PARSEARRAY after being used by ccp4_parse/
ccp4_parser functions.
* @param parsePtr pointer to a CCP4PARSERARRAY structure
* @return 0 on completion
*/
int ccp4_parse_end(CCP4PARSERARRAY *parsePtr);
int ccp4_parse_init_token(const CCP4PARSERARRAY *parsePtr, const int itok);
int ccp4_parse_delimiters(CCP4PARSERARRAY *parsePtr, const char *delim,
const char *nulldelim);
int ccp4_parse_comments(CCP4PARSERARRAY *parsePtr, const char *comment_chars);
int ccp4_parse_maxmin(CCP4PARSERARRAY *parsePtr, const double max_exponent,
const double min_exponent);
int ccp4_parse_reset(CCP4PARSERARRAY *parsePtr);
int ccp4_parse(const char *line, CCP4PARSERARRAY *parser);
/** The main function for parsing lines, either supplied or read
* from stdin.
* @param line pointer to a null-terminated string of characters,
* forming the input to be processed. On input can either be an empty
* string ("") which forces reading from stdin, or contain characters
* to be processed. On output "line" will be overwritten with the actual
* input line.
* @param n maximum number of characters that can be read into
* "line" i.e. the size of "line" in memory.
* @param parser pointer to a CCP4PARSERARRAY structure which will
* be used to hold the results of processing the input line.
* @param print flag controlling echoing of input lines to stdout.
* print=0: suppress echoing of lines to stdout. Otherwise echoing is
* turned on.
* @return Number of tokens found.
*/
int ccp4_parser(char *line, const int n, CCP4PARSERARRAY *parser,
const int print);
/* External utility functions */
/** Test whether two keywords are identical. Keywords are identical if
* they are the same up to the first four characters, independent of case.
* @param keyin1 keyword 1.
* @param keyin2 keyword 2.
* @return 1 if keywords keyin1 and keyin2 are "identical", 0 otherwise.
*/
int ccp4_keymatch(const char *keyin1, const char *keyin2);
/* Internal utility functions */
/** Convert string to uppercase.
* @param str1 On exit str1 will contain uppercased copy of str2
* @param str2 Input string
* @return str1
*/
char *strtoupper (char *str1, const char *str2);
/** Convert string to lowercase.
* @param str1 On exit str1 will contain lowercased copy of str2
* @param str2 Input string
* @return str1
*/
char *strtolower (char *str1, const char *str2);
int strmatch (const char *str1, const char *str2);
int charmatch(const char character, const char *charlist);
int doublefromstr(const char *str, const double max_exp, const double min_exp,
double *valuePtr, double *intvaluePtr, int *intdigitsPtr,
double *frcvaluePtr, int *frcdigitsPtr,
double *expvaluePtr, int *expdigitsPtr);
/** Convert symmetry operator as string to ccp4_symop struct.
* @param symchs_begin pointer to beginning of string
* @param symchs_end pointer to end of string (i.e. last character
* is *(symchs_end-1) )
* @return pointer to ccp4_symop struct
*/
ccp4_symop symop_to_rotandtrn(const char *symchs_begin, const char *symchs_end);
/** Convert symmetry operator as string to matrix.
* This is Charles' version of symfr. Note that translations
* are held in elements [*][3] and [3][3] is set to 1.0
* @param symchs_begin pointer to beginning of string
* @param symchs_end pointer to end of string (i.e. last character
* is *(symchs_end-1) )
* @param rot 4 x 4 matrix operator
* @return NULL on error, final position pointer on success
*/
const char * symop_to_mat4(const char *symchs_begin, const char *symchs_end, float *rot);
int symop_to_mat4_err(const char *symop);
ccp4_symop mat4_to_rotandtrn(const float rsm[4][4]);
/* This is Charles' version of symtr */
char *rotandtrn_to_symop(char *symchs_begin, char *symchs_end, const ccp4_symop symop);
void rotandtrn_to_mat4(float rsm[4][4], const ccp4_symop symop);
/** Convert symmetry operator as matrix to string.
* This is Charles' version of symtr. Note that translations
* are held in elements [*][3] and [3][3] is set to 1.0
* @param symchs_begin pointer to beginning of string
* @param symchs_end pointer to end of string (i.e. last character
* is *(symchs_end-1) )
* @param rsm 4 x 4 matrix operator
* @return pointer to beginning of string
*/
char *mat4_to_symop(char *symchs_begin, char *symchs_end, const float rsm[4][4]);
/** Convert symmetry operator as matrix to string in reciprocal space notation.
* This is Charles' version of symtr. Note that translations
* are held in elements [*][3] and [3][3] is set to 1.0
* @param symchs_begin pointer to beginning of string
* @param symchs_end pointer to end of string (i.e. last character
* is *(symchs_end-1) )
* @param rsm 4 x 4 matrix operator
* @return pointer to beginning of string
*/
char *mat4_to_recip_symop(char *symchs_begin, char *symchs_end, const float rsm[4][4]);
#ifdef __cplusplus
}
}
#endif
#endif /* __CCP4_Parser__ */

353
ccp4c/ccp4/ccp4_program.c Normal file
View File

@@ -0,0 +1,353 @@
/*
ccp4_program.c: Utilies to set and fetch program information.
Copyright (C) 2001 CCLRC, Peter Briggs
This library is free software: you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public License
version 3, modified in accordance with the provisions of the
license to address the requirements of UK law.
You should have received a copy of the modified GNU Lesser General
Public License along with this library. If not, copies may be
downloaded from http://www.ccp4.ac.uk/ccp4license.php
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.
*/
/** @file ccp4_program.c
* Utilies to set and fetch program information.
* Peter Briggs CCP4 May 2001
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include "ccp4_program.h"
#include "ccp4_parser.h"
#include "ccp4_utils.h"
#include "ccp4_general.h"
/* rcsid[] = "$Id$" */
static char ccp4version[MAXLEN_PROGVERSION];
char *ccp4_prog_vers(const char *progvers)
{
static char programversion[MAXLEN_PROGVERSION]="";
if (progvers) {
strncpy(programversion, progvers, MAXLEN_PROGVERSION);
programversion[MAXLEN_PROGVERSION-1] = '\0';
}
return programversion;
}
char *ccp4_vers_no(void)
{
static int init=0;
char *filepath=NULL, *filename=NULL;
char *vfile="/lib/ccp4/MAJOR_MINOR";
FILE *cfile;
int i;
if (!init) {
strcpy(ccp4version,CCP4_VERSION_NO);
filepath = (char *) getenv("CCP4");
if (filepath) {
filename = (char *) ccp4_utils_malloc(sizeof(char)*(strlen(filepath)+strlen(vfile))+1);
strcpy(filename,filepath);
strcat(filename,vfile);
if (ccpexists(filename)) {
cfile=fopen(filename,"r");
if (cfile) {
fgets(ccp4version,MAXLEN_PROGVERSION,cfile);
i = strlen(ccp4version)-1;
while (isspace(ccp4version[i]) ) {
ccp4version[i--]='\0';
}
}
}
/* Make sure that we clean up */
if (filename) free(filename);
}
init=1;
}
return ccp4version;
}
/*------------------------------------------------------------------*/
/* ccp4ProgramName
Set or return program name
Always returns a pointer to the program name
If progname is not NULL then set the program name to
progname.
NB Default program name will be returned as "CCP4",
until reset by the calling subprogram.
*/
char *ccp4ProgramName(const char *progname)
{
static char programname[MAXLEN_PROGNAME]="CCP4";
int i;
if (progname) {
i = 0;
while (progname[i] != '\0' && i < MAXLEN_PROGNAME) {
programname[i] = progname[i];
++i;
}
if (i == MAXLEN_PROGNAME) {
programname[MAXLEN_PROGNAME-1] = '\0';
} else {
programname[i] = '\0';
}
}
return programname;
}
/* ccp4_prog_info
Print program info for -i option.
*/
void ccp4_prog_info(void)
{
printf("CCP4 software suite: library version %s\n",ccp4_vers_no());
printf("CCP4 software suite: patch level %s\n",ccp4_vers_no());
printf("Program: %s",ccp4ProgramName(NULL));
if (ccp4_prog_vers(NULL) && strlen(ccp4_prog_vers(NULL)))
printf("; version %s",ccp4_prog_vers(NULL));
printf("\n");
}
/* ccp4RCSDate
Set or return program RCS date
If the input string is not a NULL pointer then
it is assumed to be an RCS string
This is processed to extract a date string in
the form "DD/MM/YY" (day/month/year), which is
then stored.
ccp4RCSDate always returns the currently
stored date string.
*/
char *ccp4RCSDate(const char *rcs_string)
{
static char RCSDate[MAXLEN_RCSDATE]="";
char tmpstr1[8],tmpstr2[3];
/* Deconstruct the RCS string passed to this
function */
if (rcs_string) {
/* Extract useful data from RCS string for examination */
strncpy(tmpstr1,rcs_string,7);
tmpstr1[7] = '\0';
strncpy(tmpstr2,rcs_string,2);
tmpstr2[2] = '\0';
if (strncmp(tmpstr1,"$Date: ",7) == 0) {
/* Raw form of RCS string (not exported) i.e.:
"$Date$"
*/
/* Build the date string in the form DD/MM/YY */
strncpy(RCSDate,rcs_string+15,2);
strncat(RCSDate,"/",1);
strncat(RCSDate,rcs_string+12,2);
strncat(RCSDate,"/",1);
strncat(RCSDate,rcs_string+9,2);
} else if (strlen(rcs_string) > 10 &&
(strncmp(tmpstr2,"19",2) == 0 || strncmp(tmpstr2,"20",2)) ) {
/* RCS string after export i.e.:
"2003/05/14 11:45:13 ..." */
/* Build the date string in the form DD/MM/YY */
strncpy(RCSDate,rcs_string+8,2);
strncat(RCSDate,"/",1);
strncat(RCSDate,rcs_string+5,2);
strncat(RCSDate,"/",1);
strncat(RCSDate,rcs_string+2,2);
} else {
/* Fallback */
strncpy(RCSDate,"",1);
}
}
/* Always return the stored date */
return RCSDate;
}
/* ccp4ProgramTime
Set or print program time information
*/
void ccp4ProgramTime(int init)
{
static int elaps0=0;
static float tarray0[2];
int elaps;
float tarray[2];
if (init || !elaps0 ) {
elaps0 = time(NULL);
ccp4_utils_etime(tarray0);
} else {
elaps = time(NULL) - elaps0;
ccp4_utils_etime(tarray);
printf("Times: User: %9.1fs System: %6.1fs Elapsed: %5d:%2.2d \n",
tarray[0]-tarray0[0],tarray[1]-tarray0[1],elaps/60,elaps%60);
}
}
/* ccp4VerbosityLevel
Set or return the reference verbosity level
Always return the verbosity level - if verboselevel is
between 0 and 9 then reset the verbosity level to
verboselevel
*/
int ccp4VerbosityLevel(int level)
{
/* The default level is 1 */
static int verbositylevel=1;
if (level > -1 && level < 10)
verbositylevel = level;
return verbositylevel;
}
/*------------------------------------------------------------------*/
/*
Callback functionality
*/
/* ccp4Callback
Set or invoke a user-defined callback function.
Internal function: applications should use the API functions
ccp4SetCallback and ccp4InvokeCallback
*/
int ccp4Callback(CCP4INTFUNCPTR mycallback, char *mode, int ierr,
const char *message)
{
static CCP4INTFUNCPTR callback=ccp4NullCallback;
if (strncmp(mode,"set",3) == 0) {
/* Set callback
Store the pointer to the callback function */
callback=mycallback;
return 1;
} else if (strncmp(mode,"invoke",3) == 0) {
/* Invoke callback
Execute the callback function */
return callback(ierr,message);
}
/* Unrecognised mode */
return 0;
}
/* ccp4SetCallback
Store a pointer to a user-defined callback function of
the form "int func(int, char *)"
This is a wrapper to ccp4Callback in "set" mode.
*/
int ccp4SetCallback(CCP4INTFUNCPTR mycallback)
{
return ccp4Callback(mycallback,"set",-1,"No message");
}
/* ccp4InvokeCallback
Execute the user-defined callback function (previously
set up using ccp4SetCallback) with the supplied
arguments.
This is a wrapper to ccp4Callback in "invoke" mode.
*/
int ccp4InvokeCallback(int ierr, const char *message)
{
return ccp4Callback(ccp4NullCallback,"invoke",ierr,message);
}
/* Default null callback function
Internal function: this is the default callback function
used by ccp4Callback if no user-defined function has been
specified.
*/
int ccp4NullCallback(int level, const char *message)
{
/* This is the default callback function which takes no
action */
return 1;
}
/*------------------------------------------------------------------*/
/* check existence of licence agreement */
int ccp4_licence_exists(const char *name)
{
int sue=1,lpath;
char *filepath=NULL,*filename=NULL,tmp_string[20];
strtoupper(tmp_string,name);
if (strmatch(tmp_string,"CCP4")) {
filepath = (char *) getenv("CCP4");
if (filepath) {
lpath = strlen(filepath);
filename = (char *) ccp4_utils_malloc(sizeof(char)*(lpath+12));
strcpy(filename,filepath);
strcpy(filename+lpath,"/.agree2ccp4");
if (ccpexists(filename)) sue = 0;
/* Make sure that we clean up */
if (filename) free(filename);
}
if (sue == 1) {
filepath = (char *) getenv("HOME");
if (filepath) {
lpath = strlen(filepath);
filename = (char *) ccp4_utils_malloc(sizeof(char)*(lpath+12));
strcpy(filename,filepath);
strcpy(filename+lpath,"/.agree2ccp4");
if (ccpexists(filename)) sue = 0;
/* Make sure that we clean up */
if (filename) free(filename);
}
}
if (sue == 1) {
ccperror(1,"Cannot find required license agreements!");
return 0;
}
}
return 1;
}
/* html_log_output and summary_output currently only used by ccperror to
tidy up Fortran program output. Defaults are 0 for C programs. */
int html_log_output(int ihtml_in) {
static int ihtml=0;
if (ihtml_in >= 0)
ihtml = ihtml_in;
return ihtml;
}
int summary_output(int isumm_in) {
static int isumm=0;
if (isumm_in >= 0)
isumm = isumm_in;
return isumm;
}

171
ccp4c/ccp4/ccp4_program.h Normal file
View File

@@ -0,0 +1,171 @@
/*
ccp4_program.h: Headers to utilies to set and fetch program information.
Copyright (C) 2001 CCLRC, Peter Briggs
This library is free software: you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public License
version 3, modified in accordance with the provisions of the
license to address the requirements of UK law.
You should have received a copy of the modified GNU Lesser General
Public License along with this library. If not, copies may be
downloaded from http://www.ccp4.ac.uk/ccp4license.php
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.
*/
/** @file ccp4_program.h
* Utilies to set and fetch program information.
* Peter Briggs CCP4 May 2001
*/
/*------------------------------------------------------------------*/
/* Macro definitions */
/*------------------------------------------------------------------*/
#ifndef __CCP4Program__
#define __CCP4Program__
/* rcsidhp[] = "$Id$" */
#ifdef __cplusplus
namespace CCP4 {
extern "C" {
#endif
#define CCP4_VERSION_NO "8.0"
#define CCP4_PATCH_LEVEL "8.0.0"
/* Maximum lengths of strings holding program names and versions */
#define MAXLEN_PROGNAME 80
#define MAXLEN_PROGVERSION 80
#define MAXLEN_RCSDATE 80
/*------------------------------------------------------------------*/
/* Type Definitions */
/*------------------------------------------------------------------*/
/* Define a type which is a pointer to a function taking an integer
and a pointer to character, and returning an integer */
typedef int (*CCP4INTFUNCPTR)(int, const char *);
/*------------------------------------------------------------------*/
/* Function Prototypes */
/*------------------------------------------------------------------*/
/** Register or query program version.
* @param progvers Program version string, or NULL to query existing value.
* @return Program version string.
*/
char *ccp4_prog_vers(const char *progvers);
/** Query ccp4 version.
* @return CCP4 version string.
*/
char *ccp4_vers_no(void);
/** Set or return program name.
* @param progname Program name, or NULL to query existing value.
* @return Program name
*/
char *ccp4ProgramName(const char *progname);
/** Print program info for -i option.
*/
void ccp4_prog_info(void);
/** Set or return program RCS date
* @param rcs_string Date string, or NULL to query existing value.
* @return Date string
*/
char *ccp4RCSDate(const char *rcs_string);
/** Set or print program time information
* @param init
*/
void ccp4ProgramTime(int init);
/** Set or return the reference verbosity level
* Always return the verbosity level - if verboselevel is
* between 0 and 9 then reset the verbosity level to
* verboselevel
* @param level Verbosity level, or -1 to query existing value.
* @return Verbosity level
*/
int ccp4VerbosityLevel(int level);
/** Set or invoke a user-defined callback function
* The callback must be of the form "function(const int, const char *)"
* This is essentially an internal function which operates in one of two
* modes - in "set" mode the named function is stored and the remaining
* arguments are discarded; in "invoke" mode the stored function is
* executed with the supplied values (the supplied name is discarded).
* @param mycallback Callback function (discarded in "invoke" mode)
* @param mode Either "set" or "invoke"
* @param ierr An error level equivalent to that used in ccperror
* @param message A message string equivalent to that used in ccperror
* @return Result of the executed function (invoke mode)
*/
int ccp4Callback(CCP4INTFUNCPTR mycallback, char *mode, int ierr,
const char *message);
/** Set a user-defined callback function
* This is a wrapper to ccp4Callback - it stores a user-defined
* callback function which must be of the form
* "function(const int, const char *)"
* @param mycallback Callback function
* @return 1 (if the function is stored), 0 (if it is not)
*/
int ccp4SetCallback(CCP4INTFUNCPTR mycallback);
/** Invoke the user-defined callback function
* This is a wrapper to ccp4Callback - it executes the user-defined
* callback function previously stored.
* @param ierr An error level equivalent to that used in ccperror
* @param message A message string equivalent to that used in ccperror
* @return Result of the executed function
*/
int ccp4InvokeCallback(int ierr, const char *message);
/** A dummy callback function used by default in ccp4CallOnExit
* Internal function. This function does nothing.
* @param level Severity level supplied from ccperror
* @param message Message text supplied from ccperror
* @return Always returns 1
*/
int ccp4NullCallback(int level, const char *message);
/** Check existence of licence agreement
* @param name Name of licence, e.g. "CCP4".
* @return 1 for licence exists, else 0.
*/
int ccp4_licence_exists(const char *name);
/** Register or query html output level.
* @param ihtml_in 0 = turn off html output, 1 = turn on html output, -1 = query existing value
* @return 0 = no html output, 1 = html output
*/
int html_log_output(int ihtml_in);
/** Register or query summary output level.
* @param isumm_in 0 = turn off summary output, 1 = turn on summary output, -1 = query existing value
* @return 0 = no summary output, 1 = summary output
*/
int summary_output(int isumm_in);
#ifdef __cplusplus
}
}
#endif
#endif /* __CCP4Program__ */

96
ccp4c/ccp4/ccp4_spg.h Normal file
View File

@@ -0,0 +1,96 @@
/*
ccp4_spg.h: Data structure for symmetry information
Copyright (C) 2001 CCLRC, Martyn Winn
This library is free software: you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public License
version 3, modified in accordance with the provisions of the
license to address the requirements of UK law.
You should have received a copy of the modified GNU Lesser General
Public License along with this library. If not, copies may be
downloaded from http://www.ccp4.ac.uk/ccp4license.php
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.
*/
/** @file ccp4_spg.h
*
* @brief Data structure for symmetry information.
*
* A data structure for spacegroup information and related
* quantities. Some items are loaded from syminfo.lib while
* others are calculated on the fly.
*
* There is also a struct for symop rotation matrices and translation
* vectors. This can be converted to other representations using
* functions in ccp4_parser.
*
* @author Martyn Winn
*/
#ifndef __CCP4_SPG__
#define __CCP4_SPG__
/* rcsidhsp[] = "$Id$" */
#ifdef __cplusplus
namespace CSym {
extern "C" {
#endif
/* Kevin's symmetry operator */
typedef struct ccp4_symop_
{
float rot[3][3];
float trn[3];
} ccp4_symop;
typedef struct ccp4_spacegroup_
{
int spg_num; /* true spacegroup number */
int spg_ccp4_num; /* CCP4 spacegroup number */
char symbol_Hall[40]; /* Hall symbol */
char symbol_xHM[20]; /* Extended Hermann Mauguin symbol */
char symbol_old[20]; /* old spacegroup name */
char point_group[20]; /* point group name */
char crystal[20]; /* crystal system e.g. MONOCLINIC */
int nlaue; /* CCP4 Laue class number, inferred from asu_descr */
char laue_name[20]; /* Laue class name */
int laue_sampling[3]; /* sampling factors for FFT */
int npatt; /* Patterson spacegroup number, inferred from asu_descr */
char patt_name[40]; /* Patterson spacegroup name */
int nsymop; /* total number of symmetry operations */
int nsymop_prim; /* number of primitive symmetry operations */
ccp4_symop *symop; /* symmetry matrices */
ccp4_symop *invsymop; /* inverse symmetry matrices */
float chb[3][3]; /* change of basis matrix from file */
char asu_descr[80]; /* asu description from file */
int (*asufn)(const int, const int, const int); /* pointer to ASU function */
int centrics[12]; /* symop which generates centric zone, 0 if none */
int epsilon[13]; /* flag which epsilon zones are applicable */
char mapasu_zero_descr[80]; /* origin-based map asu: description from file */
float mapasu_zero[3]; /* origin-based map asu: upper limits */
char mapasu_ccp4_descr[80]; /* CCP4 map asu: defaults to mapasu_zero */
float mapasu_ccp4[3]; /* CCP4 map asu: upper limits */
} CCP4SPG;
#ifdef __cplusplus
} }
#endif
#endif /*!__CCP4_SPG__ */

273
ccp4c/ccp4/ccp4_sysdep.h Normal file
View File

@@ -0,0 +1,273 @@
/*
ccp4_sysdep.h: System-dependent definitions
Copyright (C) 2001 CCLRC
This library is free software: you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public License
version 3, modified in accordance with the provisions of the
license to address the requirements of UK law.
You should have received a copy of the modified GNU Lesser General
Public License along with this library. If not, copies may be
downloaded from http://www.ccp4.ac.uk/ccp4license.php
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.
*/
/** @file ccp4_sysdep.h
*
* @brief System-dependent definitions.
*
* @author Charles Ballard, based in part on earlier versions
*/
#ifndef __CCP4_BITS
#define __CCP4_BITS
#ifdef __sgi /* in ANSI mode */
# ifndef sgi
# define sgi
# endif
#endif
#ifndef VMS
# if defined (vms) || defined (__vms) || defined (__VMS)
# define VMS
# endif
#endif
#if defined (sun) || defined (__sun)
# if !defined(__STDC__) || defined(__GNUC__)
# if !defined(G77)
extern char *sys_errlist [];
# define strerror(i) sys_errlist[i] /* k&r compiler doesn't have it */
# endif
# endif
#endif
#if defined (_AIX) || defined(___AIX) || defined (__hpux)
# define CALL_LIKE_HPUX 1
#elif defined (VMS)
# define CALL_LIKE_VMS 1
#elif defined (_MSC_VER) && (_MSC_VER >= 800)
# define CALL_LIKE_MVS 2
#elif defined (_MSC_VER) || (defined (_WIN32) && !defined(__MINGW32__))
# define CALL_LIKE_MVS 1
#else
# define CALL_LIKE_SUN 1
#endif
#ifndef _POSIX_SOURCE
#define _POSIX_SOURCE
#endif
#include <stdio.h>
#if defined (VMS)
# include <descrip.h> /* non-POSIX */
# define NOUNISTD
#else
# include <sys/types.h>
# include <sys/stat.h>
# if !defined (_WIN32) && !defined (_MSC_VER)
# include <sys/times.h>
# endif
# ifdef _MSC_VER
# define NOUNISTD
# endif
#endif
#include <stddef.h>
#include <string.h>
#ifndef NOUNISTD
# include <unistd.h>
#else
# ifndef VMS
# ifndef _MSC_VER
# include <sys/file.h> /* ESV, old Concentrix */ /* non-POSIX */
# endif
# endif
#endif
#ifndef NOSTDLIB /* for TitanOS 4.2, at least? */
# include <stdlib.h>
#endif
#include <errno.h>
#include <ctype.h>
#if defined(_AIX) || defined (__hpux) || defined(F2C) ||\
defined(G77) || defined(_WIN32) || defined (sun) /* would do no harm on others, though */
# include <time.h>
#endif
#include <limits.h>
#include <float.h>
#if defined (F2C)
# define Skip_f2c_Undefs
# include "f2c.h"
#endif
#if defined (G77)
# define Skip_f2c_Undefs /* g2c.h infelicity... */
# if defined (HAVE_G2C_H)
# include "g2c.h"
# endif
#endif
/* Using MSVC need __declspec */
#if defined(__WIN32__) || defined(_WIN32)
# if defined(_MSC_VER) && defined(DLL_EXPORT)
# define CCP4_DL_IMPORT(type) __declspec(dllexport) type
# define CCP4_DL_EXPORT __declspec(dllexport)
# elif defined(_MSC_VER)
# define CCP4_DL_IMPORT(type) __declspec(dllimport) type
# define CCP4_DL_EXPORT
# else
# define CCP4_DL_IMPORT(type) type
# define CCP4_DL_EXPORT
# endif
#else
# define CCP4_DL_IMPORT(type) type
# define CCP4_DL_EXPORT
#endif
/* defined in library_utils.c */
#if defined (_MSC_VER) && _MSC_VER < 1800
double rint(double x);
#endif
#ifdef _MSC_VER
#define M_PI 3.14159265358979323846
#endif
#ifdef _WIN32
# define PATH_SEPARATOR '\\'
# define EXT_SEPARATOR '.'
#else
# define PATH_SEPARATOR '/'
# define EXT_SEPARATOR '.'
#endif
#define MAXFLEN 512 /**< the maximum length of a filename in CCP4 */
#define MAXFILES 16 /**< maximum number of files open symultaneously */
#define DEFMODE 2 /**< default mode access for random access files */
#define IRRELEVANT_OP 0
#define READ_OP 1
#define WRITE_OP 2
#include<fcntl.h>
#ifndef SEEK_SET
# define SEEK_SET 0
# define SEEK_CUR 1
# define SEEK_END 2
#endif /* ! SEEK_SET */
#ifndef O_WRONLY
#define O_RDONLY 0x0000 /**< i/o mode: read-only */
#define O_WRONLY 0x0001 /**< i/o mode: write-only */
#define O_RDWR 0x0002 /**< i/o mode: read and write */
#define O_APPEND 0x0008 /**< i/o mode: append to existing file */
#define O_CREAT 0x0200 /**< i/o mode: create file */
#define O_TRUNC 0x0400 /**< i/o mode: truncate existing file */
#endif
#define O_TMP 0x0010 /**< i/o mode: scratch file */
/* Before version 6.3 we defined BYTE, INT16 and INT32 (without the CCP4_
* prefix). The prefix has been added to avoid name conflicts.
*/
#define CCP4_BYTE 0
#define CCP4_INT16 1
#define CCP4_INT32 6
#define CCP4_INT64 5
#define FLOAT32 2
#define COMP32 3
#define COMP64 4
#define DFNTI_MBO 1 /**< Motorola byte order 2's compl */
#define DFNTI_IBO 4 /**< Intel byte order 2's compl */
#define DFNTF_BEIEEE 1 /**< big endian IEEE (canonical) */
#define DFNTF_VAX 2 /**< Vax format */
#define DFNTF_CONVEXNATIVE 5 /**< Convex native floats */
#define DFNTF_LEIEEE 4 /**< little-endian IEEE format */
#if defined (VAX) || defined (vax) /* gcc seems to use vax */
# define NATIVEFT DFNTF_VAX
# define NATIVEIT DFNTI_IBO
#endif
#if defined(MIPSEL) || defined(i386) || defined(i860) || defined(__ia64__) || defined(__amd64__) || defined(__x86_64__) || defined(_M_AMD64)
# define NATIVEIT DFNTI_IBO
# define NATIVEFT DFNTF_LEIEEE
#endif
#if defined (powerpc) || defined (__powerpc__) || defined (__ppc__) || \
defined __PPC || defined (__s390__) || defined (__s390x__) || \
defined (__hppa__)
# define NATIVEIT DFNTI_MBO
# define NATIVEFT DFNTF_BEIEEE
#endif
#ifdef __alpha
# ifdef VMS
# if __IEEE_FLOAT == 1
# define NATIVEFT DFNTF_LEIEEE
# else
# define NATIVEFT DFNTF_VAX
# endif
# else /* assume OSF/1 */
# define NATIVEFT DFNTF_LEIEEE
# endif
# define NATIVEIT DFNTI_IBO
#endif
#if defined(MIPSEB) || defined(__hpux) || defined(_AIX) || defined(m68k) || defined(mc68000) || defined(sparc) || defined (__sparc__)
# define NATIVEIT DFNTI_MBO
# define NATIVEFT DFNTF_BEIEEE
#endif
#if defined(__ARM__) || defined(__arm__) || defined(__aarch64__)
# if defined(__ARMEB__) || defined (__AARCH64EB__)
# define NATIVEIT DFNTI_MBO
# define NATIVEFT DFNTF_BEIEEE
# elif defined(__ARMEL__) || defined (__AARCH64EL__)
# define NATIVEIT DFNTI_IBO
# define NATIVEFT DFNTF_LEIEEE
# endif
#endif
/* From time to time new architectures are added here, often because Linux
* packagers want to build it on all platforms supported by their distro.
* Here we try to catch machines not listed explicitely above, under
* assumption that endianness is the same for floating point numbers
* as for integers. Which is safe assumption on modern standard computers
* (not embedded systems), according to
* http://en.wikipedia.org/wiki/Endianness#Floating-point_and_endianness
*/
#if !defined(NATIVEIT) && !defined(NATIVEFT) && defined(__BYTE_ORDER)
# if __BYTE_ORDER == __LITTLE_ENDIAN
# define NATIVEIT DFNTI_IBO
# define NATIVEFT DFNTF_LEIEEE
# elif __BYTE_ORDER == __BIG_ENDIAN
# define NATIVEIT DFNTI_MBO
# define NATIVEFT DFNTF_BEIEEE
# endif
#endif
#ifndef NATIVEFT
# error "Can't determine machine number format"
#endif
#define DFNT_UINT 0 /**< unsigned int */
#define DFNT_SINT 1 /**< short int */
#define DFNT_INT 2 /**< int */
#define DFNT_UCHAR 3 /**< unsigned char */
#define DFNT_CHAR 4 /**< char */
#define DFNT_FLOAT 5 /**< float */
#define DFNT_DOUBLE 6 /**< double */
#endif /* __CCP4_BITS */

74
ccp4c/ccp4/ccp4_types.h Normal file
View File

@@ -0,0 +1,74 @@
/*
ccp4_types.h: CCP4 library.c macro definitions etc
Copyright (C) 2001 CCLRC
This library is free software: you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public License
version 3, modified in accordance with the provisions of the
license to address the requirements of UK law.
You should have received a copy of the modified GNU Lesser General
Public License along with this library. If not, copies may be
downloaded from http://www.ccp4.ac.uk/ccp4license.php
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.
*/
#ifndef __CCP4_TYPES
#define __CCP4_TYPES
#include "ccp4_sysdep.h"
typedef unsigned short uint16;
#ifdef SIXTEENBIT
typedef unsigned long uint32;
#else
typedef unsigned int uint32;
#endif
typedef float float32;
typedef unsigned char uint8;
union float_uint_uchar {
float32 f;
uint32 i;
uint8 c[4];
};
typedef char * pstr;
/* CCP4 library.c macro definitions */
#ifndef FALSE
#define FALSE 0
#define TRUE 1
#endif
typedef struct { double r; /* radial and */
double phi; /* angular component of */
} POLAR; /* a complex number */
/* some simple macros, which may exist anyway */
#ifndef SQR
#define SQR(x) ((x)*(x))
#endif
#ifndef DEGREE
#define DEGREE(x) ((((x < 0)?(x)+2*M_PI:(x))*360)/(2*M_PI))
#endif
#ifndef RADIAN
#define RADIAN(x) ((((x<0)?(x)+360:(x))*2*M_PI)/360)
#endif
#ifndef MAX
#define MAX(x, y) (((x)>(y))?(x):(y))
#endif
#ifndef MIN
#define MIN(x, y) (((x)<(y))?(x):(y))
#endif
#ifndef ABS
#define ABS(x) (((x)<0)?-(x):(x))
#endif
#ifndef SIGN
#define SIGN(x) (((x)<0)?-1:1)
#endif
#endif /* __CCP4_TYPES */

328
ccp4c/ccp4/ccp4_unitcell.c Normal file
View File

@@ -0,0 +1,328 @@
/*
ccp4_unitcell.c: C library for manipulations based on cell parameters.
Copyright (C) 2001 CCLRC, Martyn Winn
This library is free software: you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public License
version 3, modified in accordance with the provisions of the
license to address the requirements of UK law.
You should have received a copy of the modified GNU Lesser General
Public License along with this library. If not, copies may be
downloaded from http://www.ccp4.ac.uk/ccp4license.php
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.
*/
/** @file ccp4_unitcell.c
* C library for manipulations based on cell parameters.
* Martyn Winn
*/
#include <stdio.h>
#include "ccp4_unitcell.h"
#include "cvecmat.h"
#include "ccp4_errno.h"
/* rcsid[] = "$Id$" */
/* from input cell and orthogonalisation code, find orthogonalisation
and fractionalisation matrices. Returns cell volume. */
double ccp4uc_frac_orth_mat(const double cell[6], const int ncode,
double ro[3][3], double rf[3][3])
{
int i,j;
double conv,alph,bet,gamm,sina,cosa,sinb,cosb,sing,cosg,
sinas,cosas,sinbs,cosbs,sings,cosgs,a,b,c;
conv = atan(1.0)*4.0/180.0;
alph = cell[3]*conv;
bet = cell[4]*conv;
gamm = cell[5]*conv;
sina = sin(alph);
cosa = cos(alph);
sinb = sin(bet);
cosb = cos(bet);
sing = sin(gamm);
cosg = cos(gamm);
cosas = (cosg*cosb-cosa)/ (sinb*sing);
sinas = sqrt(1.0-cosas*cosas);
cosbs = (cosa*cosg-cosb)/ (sina*sing);
sinbs = sqrt(1.0-cosbs*cosbs);
cosgs = (cosa*cosb-cosg)/ (sina*sinb);
sings = sqrt(1.0-cosgs*cosgs);
a = cell[0];
b = cell[1];
c = cell[2];
/* calculate ro */
for ( i = 0; i < 3; i++ )
for ( j = 0; j < 3; j++ )
ro[i][j] = 0.0;
/* ncode 1 - xo along a zo along c* */
switch (ncode) {
case 1:
ro[0][0] = a;
ro[0][1] = b*cosg;
ro[0][2] = c*cosb;
ro[1][1] = b*sing;
ro[1][2] = -c*sinb*cosas;
ro[2][2] = c*sinb*sinas;
break;
/* ncode 2 - xo along b zo along a* */
case 2:
ro[0][0] = a*cosg;
ro[0][1] = b;
ro[0][2] = c*cosa;
ro[1][0] = -a*sing*cosbs;
ro[1][2] = c*sina;
ro[2][0] = a*sing*sinbs;
break;
/* ncode 3 - xo along c zo along b* */
case 3:
ro[0][0] = a*cosb;
ro[0][1] = b*cosa;
ro[0][2] = c;
ro[1][0] = a*sinb;
ro[1][1] = -b*sina*cosgs;
ro[2][1] = b*sina*sings;
break;
/* ncode 4 - trigonal only - xo along a+b yo alon a-b zo along c* */
case 4:
ro[0][0] = a/2.0;
ro[0][1] = a/2.0;
ro[1][0] = -a*sing;
ro[1][1] = a*sing;
ro[2][2] = c;
break;
/* ncode 5 - xo along a* zo along c */
case 5:
ro[0][0] = a*sinb*sings;
ro[1][0] = -a*sinb*cosgs;
ro[1][1] = b*sina;
ro[2][0] = a*cosb;
ro[2][1] = b*cosa;
ro[2][2] = c;
break;
/* ncode 6 - grr*! to gerard bricogne - his setting for p1 in skew.
xo along a yo along b* */
case 6:
ro[0][0] = a;
ro[0][1] = b*cosg;
ro[0][2] = c*cosb;
ro[1][1] = b*sing*sinas;
ro[2][1] = -b*sing*cosas;
ro[2][2] = c*sinb;
break;
}
/* now calculate rf from ro, determinant gives cell volume */
return invert3matrix((const double (*)[3]) ro, rf);
}
/* from input cell, find dimensions of reciprocal cell.
Returns reciprocal cell volume. */
double ccp4uc_calc_rcell(const double cell[6], double rcell[6])
{
double conv,alph,bet,gamm,vol,sina,cosa,sinb,cosb,sing,cosg,
sinas,cosas,sinbs,cosbs,sings,cosgs,a,b,c;
conv = 3.14159/180.0;
alph = cell[3]*conv;
bet = cell[4]*conv;
gamm = cell[5]*conv;
vol = ccp4uc_calc_cell_volume(cell);
sina = sin(alph);
cosa = cos(alph);
sinb = sin(bet);
cosb = cos(bet);
sing = sin(gamm);
cosg = cos(gamm);
cosas = (cosg*cosb-cosa)/ (sinb*sing);
sinas = sqrt(1.0-cosas*cosas);
cosbs = (cosa*cosg-cosb)/ (sina*sing);
sinbs = sqrt(1.0-cosbs*cosbs);
cosgs = (cosa*cosb-cosg)/ (sina*sinb);
sings = sqrt(1.0-cosgs*cosgs);
a = cell[0];
b = cell[1];
c = cell[2];
rcell[0] = b*c*sina/vol;
rcell[1] = c*a*sinb/vol;
rcell[2] = a*b*sing/vol;
rcell[3] = atan2(sinas,cosas)/conv;
rcell[4] = atan2(sinbs,cosbs)/conv;
rcell[5] = atan2(sings,cosgs)/conv;
return (1.0 / vol);
}
/* Convert orthogonal to fractional coordinates. Translation only if
deliberate origin shift - does this ever happen? Leave it to the
application. */
void ccp4uc_orth_to_frac(const double rf[3][3], const double xo[3], double xf[3])
{
xf[0] = rf[0][0]*xo[0] + rf[0][1]*xo[1] + rf[0][2]*xo[2];
xf[1] = rf[1][0]*xo[0] + rf[1][1]*xo[1] + rf[1][2]*xo[2];
xf[2] = rf[2][0]*xo[0] + rf[2][1]*xo[1] + rf[2][2]*xo[2];
}
/* Convert fractional to orthogonal coordinates. */
void ccp4uc_frac_to_orth(const double ro[3][3], const double xf[3], double xo[3])
{
xo[0] = ro[0][0]*xf[0] + ro[0][1]*xf[1] + ro[0][2]*xf[2];
xo[1] = ro[1][0]*xf[0] + ro[1][1]*xf[1] + ro[1][2]*xf[2];
xo[2] = ro[2][0]*xf[0] + ro[2][1]*xf[1] + ro[2][2]*xf[2];
}
/* Convert orthogonal to fractional u matrix. */
void ccp4uc_orthu_to_fracu(const double rf[3][3], const double uo[6], double uf[6])
{
int i,j;
double uomat[3][3], ufmat[3][3], rft[3][3], temp[3][3];
uomat[0][0] = uo[0]; uomat[0][1] = uo[3]; uomat[0][2] = uo[4];
uomat[1][0] = uo[3]; uomat[1][1] = uo[1]; uomat[1][2] = uo[5];
uomat[2][0] = uo[4]; uomat[2][1] = uo[5]; uomat[2][2] = uo[2];
for ( i = 0; i < 3; i++ )
for ( j = 0; j < 3; j++ )
rft[i][j] = rf[j][i];
ccp4_3matmul(temp,(const double (*)[3]) uomat,(const double (*)[3]) rft);
ccp4_3matmul(ufmat,rf,(const double (*)[3]) temp);
uf[0] = ufmat[0][0]; uf[1] = ufmat[1][1]; uf[2] = ufmat[2][2];
uf[3] = ufmat[0][1]; uf[4] = ufmat[0][2]; uf[5] = ufmat[1][2];
}
/* Convert fractional to orthogonal u matrix. */
void ccp4uc_fracu_to_orthu(const double ro[3][3], const double uf[6], double uo[6])
{
int i,j;
double uomat[3][3], ufmat[3][3], rot[3][3], temp[3][3];
ufmat[0][0] = uf[0]; ufmat[0][1] = uf[3]; ufmat[0][2] = uf[4];
ufmat[1][0] = uf[3]; ufmat[1][1] = uf[1]; ufmat[1][2] = uf[5];
ufmat[2][0] = uf[4]; ufmat[2][1] = uf[5]; ufmat[2][2] = uf[2];
for ( i = 0; i < 3; i++ )
for ( j = 0; j < 3; j++ )
rot[i][j] = ro[j][i];
ccp4_3matmul(temp,(const double (*)[3]) ufmat,(const double (*)[3]) rot);
ccp4_3matmul(uomat,ro,(const double (*)[3]) temp);
uo[0] = uomat[0][0]; uo[1] = uomat[1][1]; uo[2] = uomat[2][2];
uo[3] = uomat[0][1]; uo[4] = uomat[0][2]; uo[5] = uomat[1][2];
}
/* Calculate cell volume from cell parameters */
double ccp4uc_calc_cell_volume(const double cell[6])
{
double conv,alph,bet,gamm,sum,v;
conv = 3.14159/180.0;
alph = cell[3]*conv;
bet = cell[4]*conv;
gamm = cell[5]*conv;
sum = (alph+bet+gamm)*0.5;
v = sqrt(sin(sum-alph)*sin(sum-bet)*sin(sum-gamm)*sin(sum));
return (2.0*cell[0]*cell[1]*cell[2]*v);
}
/* Check cells agree within tolerance */
int ccp4uc_cells_differ(const double cell1[6], const double cell2[6], const double tolerance)
{
int i;
double vol1, vol2, acheck;
vol1 = ccp4uc_calc_cell_volume(cell1);
vol2 = ccp4uc_calc_cell_volume(cell2);
/* check cell volumes */
acheck = fabs(0.5*(vol1 - vol2))/(vol1 + vol2);
if (acheck > tolerance) {
if (ccp4_liberr_verbosity(-1)) {
printf("Difference in cell volumes detected.\n");
printf(" vol1 = %lf vol2 = %lf \n",vol1,vol2);
}
return 1;
}
/* check cell parameters */
acheck = 0.0;
for ( i = 0; i < 6; i++ )
acheck += fabs(0.5*(cell2[i]-cell1[i]))/(cell2[i]+cell1[i]);
if (acheck > 3.0*tolerance) {
if (ccp4_liberr_verbosity(-1)) {
printf("Large difference in cell parameters detected.\n");
printf(" cell1 = %lf %lf %lf %lf %lf %lf \n",
cell1[0],cell1[1],cell1[2],cell1[3],cell1[4],cell1[5]);
printf(" cell2 = %lf %lf %lf %lf %lf %lf \n",
cell2[0],cell2[1],cell2[2],cell2[3],cell2[4],cell2[5]);
}
return 1;
} else if (acheck > tolerance) {
if (ccp4_liberr_verbosity(-1)) {
printf("Small difference in cell parameters detected.\n");
printf(" cell1 = %lf %lf %lf %lf %lf %lf \n",
cell1[0],cell1[1],cell1[2],cell1[3],cell1[4],cell1[5]);
printf(" cell2 = %lf %lf %lf %lf %lf %lf \n",
cell2[0],cell2[1],cell2[2],cell2[3],cell2[4],cell2[5]);
}
return 1;
}
return 0;
}
int ccp4uc_is_rhombohedral(const float cell[6], const float tolerance) {
double acheck;
acheck = fabs(cell[0]-cell[1]);
acheck += fabs(cell[1]-cell[2]);
acheck += fabs(cell[0]-cell[2]);
acheck += fabs(cell[3]-cell[4]);
acheck += fabs(cell[3]-cell[5]);
acheck += fabs(cell[4]-cell[5]);
if (acheck > (double) tolerance) return 0;
return 1;
}
int ccp4uc_is_hexagonal(const float cell[6], const float tolerance) {
double acheck;
acheck = fabs(cell[0]-cell[1]);
acheck += fabs(cell[3]-90.0);
acheck += fabs(cell[4]-90.0);
acheck += fabs(cell[5]-120.0);
if (acheck > (double) tolerance) return 0;
return 1;
}

119
ccp4c/ccp4/ccp4_unitcell.h Normal file
View File

@@ -0,0 +1,119 @@
/*
ccp4_unitcell.h: headers for C library for ccp4_unitcell.c
Copyright (C) 2001 CCLRC, Martyn Winn
This library is free software: you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public License
version 3, modified in accordance with the provisions of the
license to address the requirements of UK law.
You should have received a copy of the modified GNU Lesser General
Public License along with this library. If not, copies may be
downloaded from http://www.ccp4.ac.uk/ccp4license.php
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.
*/
/** @file ccp4_unitcell.h
* C library for manipulations based on cell parameters.
* Martyn Winn
*/
#ifndef __CCP4_UNITCELL
#define __CCP4_UNITCELL
#ifdef __cplusplus
namespace CCP4uc {
extern "C" {
#endif
#include <math.h>
/** From input cell and orthogonalisation code, find orthogonalisation
and fractionalisation matrices.
* @param cell
* @param ncode
* @param ro
* @param rf
* @return Cell volume
*/
double ccp4uc_frac_orth_mat(const double cell[6], const int ncode,
double ro[3][3], double rf[3][3]);
/** From input cell, find dimensions of reciprocal cell.
* @param cell
* @param rcell
* @return Reciprocal cell volume
*/
double ccp4uc_calc_rcell(const double cell[6], double rcell[6]);
/** Convert orthogonal to fractional coordinates. Translation only if
deliberate origin shift - does this ever happen? Leave it to the
application.
* @param rf
* @param xo
* @param xf
* @return void
*/
void ccp4uc_orth_to_frac(const double rf[3][3], const double xo[3], double xf[3]);
/** Convert fractional to orthogonal coordinates.
* @param ro
* @param xf
* @param xo
* @return void
*/
void ccp4uc_frac_to_orth(const double ro[3][3], const double xf[3], double xo[3]);
/** Convert orthogonal to fractional u matrix.
* @param rf
* @param uo
* @param uf
* @return void
*/
void ccp4uc_orthu_to_fracu(const double rf[3][3], const double uo[6], double uf[6]);
/** Convert fractional to orthogonal u matrix.
* @param ro
* @param uf
* @param uo
* @return void
*/
void ccp4uc_fracu_to_orthu(const double ro[3][3], const double uf[6], double uo[6]);
/** Calculate cell volume from cell parameters.
* @param cell
* @return Cell volume.
*/
double ccp4uc_calc_cell_volume(const double cell[6]);
/** Check cells agree within tolerance.
* @param cell1 First cell.
* @param cell2 Second cell.
* @param tolerance A tolerance for agreement.
* @return 1 if cells differ by more than tolerance, 0 otherwise.
*/
int ccp4uc_cells_differ(const double cell1[6], const double cell2[6], const double tolerance);
/** Check if cell parameters conform to a rhombohedral setting.
* @param cell Cell parameters. Angles are assumed to be in degrees.
* @param tolerance A tolerance for agreement.
* @return 1 if cell parameters conform, 0 otherwise.
*/
int ccp4uc_is_rhombohedral(const float cell[6], const float tolerance);
/** Check if cell parameters conform to a hexagonal setting.
* @param cell Cell parameters. Angles are assumed to be in degrees.
* @param tolerance A tolerance for agreement.
* @return 1 if cell parameters conform, 0 otherwise.
*/
int ccp4uc_is_hexagonal(const float cell[6], const float tolerance);
#ifdef __cplusplus
} }
#endif
#endif /*!CCP4_UNITCELL */

112
ccp4c/ccp4/ccp4_utils.h Normal file
View File

@@ -0,0 +1,112 @@
/*
ccp4_utils.h: headers for utility functions.
Copyright (C) 2001 CCLRC, Charles Ballard
This library is free software: you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public License
version 3, modified in accordance with the provisions of the
license to address the requirements of UK law.
You should have received a copy of the modified GNU Lesser General
Public License along with this library. If not, copies may be
downloaded from http://www.ccp4.ac.uk/ccp4license.php
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.
*/
/** @file ccp4_utils.h
* @brief Utility functions.
* @author Charles Ballard
*/
#ifndef __CCP4_UTILS
#define __CCP4_UTILS
#include <string.h>
#include "ccp4_types.h"
#include "library_file.h"
/* rcsidh[] = "$Id$" */
#ifdef __cplusplus
namespace CCP4 {
extern "C" {
#endif
/****************************************************************************
* Function prototypes *
****************************************************************************/
size_t ccp4_utils_flength (char *, int);
int ccp4_utils_translate_mode_float(float *, const void *, int, int);
void ccp4_utils_fatal (const char *);
void ccp4_utils_print (const char *message);
int ccp4_utils_setenv (char *);
/* turn on line buffering for stdout */
int ccp4_utils_outbuf (void);
/* turn off any buffering on stdin */
int ccp4_utils_noinpbuf (void);
union float_uint_uchar ccp4_nan ();
int ccp4_utils_isnan (const union float_uint_uchar *);
void ccp4_utils_bml (int, union float_uint_uchar *);
void ccp4_utils_wrg (int, union float_uint_uchar *, float *);
void ccp4_utils_hgetlimits (int *, float *);
int ccp4_utils_mkdir (const char *, const char *);
int ccp4_utils_chmod (const char *, const char *);
void *ccp4_utils_malloc(size_t);
void *ccp4_utils_realloc(void *, size_t);
void *ccp4_utils_calloc(size_t, size_t);
int ccp4_file_size(const char *);
char *ccp4_utils_username(void);
char *ccp4_utils_basename(const char *filename);
char *ccp4_utils_pathname(const char *filename);
char *ccp4_utils_extension(const char *filename);
char *ccp4_utils_joinfilenames(const char *dir, const char *file);
void ccp4_utils_idate (int *);
char *ccp4_utils_date(char *);
void ccp4_utils_itime (int *);
char *ccp4_utils_time(char *);
float ccp4_utils_etime (float *);
#if defined (_MSC_VER)
double ccp4_erfc( double x );
#endif
/****************************************************************************
* End of prototypes *
*****************************************************************************/
#ifdef __cplusplus
}
}
#endif
#endif /* __CCP4_UTILS */

46
ccp4c/ccp4/ccp4_vars.h Normal file
View File

@@ -0,0 +1,46 @@
/*
ccp4_vars.h: Standard strings for certain quantites
Copyright (C) 2002 CCLRC, Martyn Winn
This library is free software: you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public License
version 3, modified in accordance with the provisions of the
license to address the requirements of UK law.
You should have received a copy of the modified GNU Lesser General
Public License along with this library. If not, copies may be
downloaded from http://www.ccp4.ac.uk/ccp4license.php
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.
*/
/*
*/
/* Author: Martyn Winn */
/* Standard strings for certain quantites - for future use */
#ifndef __CCP4_VARS__
#define __CCP4_VARS__
#define MTZFILENAME "data::mtzfile::filename"
#define MTZTITLE "data::mtzfile::title"
#define MTZSPACEGROUP "data::mtzfile::spacegroup_num"
#define MTZNUMREFLS "data::mtzfile::num_reflections"
#define MTZMNF "data::mtzfile::missing_number_flag"
#define MTZSORTORDER "data::mtzfile::sort_order"
#define CRYSTALXTALNAME "data::crystal::crystal_name"
#define CRYSTALPNAME "data::crystal::project_name"
#define CRYSTALCELL "data::crystal::cell"
#define DATASETDNAME "data::crystal::dataset::dataset_name"
#define DATASETWAVELENGTH "data::crystal::dataset::wavelength"
#define COLUMNLABEL "data::crystal_i::dataset_i::column_i::label"
#define COLUMNTYPE "data::crystal_i::dataset_i::column_i::type"
#endif /*!__CCP4_VARS__ */

261
ccp4c/ccp4/cmap_accessor.c Normal file
View File

@@ -0,0 +1,261 @@
/*
cmap_accessor.c: get and set map header information
Copyright (C) 2001 CCLRC, Charles Ballard
This library is free software: you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public License
version 3, modified in accordance with the provisions of the
license to address the requirements of UK law.
You should have received a copy of the modified GNU Lesser General
Public License along with this library. If not, copies may be
downloaded from http://www.ccp4.ac.uk/ccp4license.php
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.
*/
#include <math.h>
#include "cmaplib.h"
#include "cmap_errno.h"
/* accessors */
/*! Get the cell parameters
\param mfile (const CMMFile *)
\param cell (float *) contains the cell parameter on exit (dim 6) */
void ccp4_cmap_get_cell(const CMMFile *mfile, float *cell)
{
cell[0] = mfile->cell[0];
cell[1] = mfile->cell[1];
cell[2] = mfile->cell[2];
cell[3] = mfile->cell[3];
cell[4] = mfile->cell[4];
cell[5] = mfile->cell[5];
}
/*! Set the cell parameters.
Only allowed when file is opened in write mode.
\param mfile (CMMFile *)
\param cell (const float *) the cell parameters */
void ccp4_cmap_set_cell(CMMFile *mfile, const float *cell)
{
if (ccp4_file_is_write(mfile->stream)) {
mfile->cell[0] = cell[0];
mfile->cell[1] = cell[1];
mfile->cell[2] = cell[2];
mfile->cell[3] = cell[3];
mfile->cell[4] = cell[4];
mfile->cell[5] = cell[5];
}
}
/*! Get the grid for the complete cell (X,Y,Z) ordering
\param mfile (const CMMFile *)
\param grid (int *) contains the grid dimension on exit (dim 3) */
void ccp4_cmap_get_grid(const CMMFile *mfile, int *grid)
{
grid[0] = mfile->cell_grid[0];
grid[1] = mfile->cell_grid[1];
grid[2] = mfile->cell_grid[2];
}
/*! Set the cell grid dimension.
Only allowed when file is opened in write mode.
\param mfile (CMMFile *)
\param grid (const int *) the cell grid dimension (X,Y,Z) */
void ccp4_cmap_set_grid(CMMFile *mfile, const int *grid)
{
if (ccp4_file_is_write(mfile->stream)) {
mfile->cell_grid[0] = grid[0];
mfile->cell_grid[1] = grid[1];
mfile->cell_grid[2] = grid[2];
}
}
/*! Get the stored map origin (rows,sections,columns)
\param mfile (const CMMFile *)
\param origin (int *) contains the origin on exit (dim 3) */
void ccp4_cmap_get_origin(const CMMFile *mfile, int *origin)
{
origin[0] = mfile->origin[0];
origin[1] = mfile->origin[1];
origin[2] = mfile->origin[2];
}
/*! Set the stored map origin (rows,sections,columns)
Only allowed when file is opened in write mode.
\param mfile (CMMFile *)
\param origin (const int *) the origin */
void ccp4_cmap_set_origin(CMMFile *mfile, const int *origin)
{
if (ccp4_file_is_write(mfile->stream)) {
mfile->origin[0] = origin[0];
mfile->origin[1] = origin[1];
mfile->origin[2] = origin[2];
}
}
/*! Get the stored map axes order (rows,sections,columns)
where 1=X, 2=Y, 3=Z
\param mfile (const CMMFile *)
\param axes_order (float *) contains the ordering on exit (dim 3) */
void ccp4_cmap_get_order(const CMMFile *mfile, int *axes_order)
{
axes_order[0] = mfile->axes_order[0];
axes_order[1] = mfile->axes_order[1];
axes_order[2] = mfile->axes_order[2];
}
/*! Set the stored map axes order (rows,sections,columns)
where 1=X, 2=Y, 3=Z.
Only allowed when file is opened in write mode.
\param mfile (CMMFile *)
\param axes_order (const float *) the axes ordering */
void ccp4_cmap_set_order(CMMFile *mfile, const int *axes_order)
{
if (ccp4_file_is_write(mfile->stream)) {
mfile->axes_order[0] = axes_order[0];
mfile->axes_order[1] = axes_order[1];
mfile->axes_order[2] = axes_order[2];
}
}
/*! Get the stored map dimension (rows,sections,columns)
\param mfile (const CMMFile *)
\param map_dim (int *) contains the map dimension on exit (dim 3) */
void ccp4_cmap_get_dim(const CMMFile *mfile, int *map_dim)
{
map_dim[0] = mfile->map_dim[0];
map_dim[1] = mfile->map_dim[1];
map_dim[2] = mfile->map_dim[2];
}
/*! Set the stored map dimension (rows,sections,columns)
Only allowed when file is opened in write mode before any data
is written.
Note: the row dimension will be overridden during writing
\param mfile (CMMFile *)
\param map_dim (const int *) the map dimension */
void ccp4_cmap_set_dim(CMMFile *mfile, const int *map_dim)
{
if (ccp4_file_is_write(mfile->stream) && !mfile->data.number) {
mfile->map_dim[0] = map_dim[0];
mfile->map_dim[1] = map_dim[1];
mfile->map_dim[2] = map_dim[2];
mfile->data.section_size = map_dim[0]*map_dim[1]*
ccp4_file_itemsize(mfile->stream);
mfile->data.block_size = mfile->data.section_size +
mfile->data.header_size;
}
}
/*! Return the spacegroup listed in the map header.
This is overriden by the symops.
\param mfile (CMMFile *)
\return spacegroup number */
int ccp4_cmap_get_spacegroup(const CMMFile *mfile)
{
return mfile->spacegroup;
}
/*! Set the spacegroup listed in the map header.
Only allowed when file is opened in write mode.
\param mfile (CMMFile *)
\param spacegroup (int) spacegroup number */
void ccp4_cmap_set_spacegroup(CMMFile *mfile, int spacegroup)
{
if (ccp4_file_is_write(mfile->stream))
mfile->spacegroup = spacegroup;
}
/*! Return the datamode
\param mfile (const CMMFile *)
\return datamode */
unsigned int ccp4_cmap_get_datamode(const CMMFile *mfile)
{
return mfile->data_mode;
}
/*! Set the datamode.
This is only allowed if the file is opened in write mode, and
no data has been written.
\param mfile (CMMFile *)
\param datamode (unsigned int) major mode of map */
void ccp4_cmap_set_datamode(CMMFile *mfile, unsigned int datamode)
{
if (ccp4_file_is_write(mfile->stream) && !mfile->data.number &&
datamode <= 6 && datamode != 5) {
mfile->data_mode = datamode;
ccp4_file_setmode(mfile->stream, datamode);
mfile->data.section_size = mfile->map_dim[0]*mfile->map_dim[1]*
ccp4_file_itemsize(mfile->stream);
mfile->data.block_size = mfile->data.section_size +
mfile->data.header_size;
}
}
/*! Get the map statistics, including maximum, minimum, mean and standard
deviation. This is only meaningful for datamode FLOAT32.
\param mfile (const CMMFile *)
\param min (float *)
\param max (float *)
\param mean (double *)
\param rms (double *) */
void ccp4_cmap_get_mapstats(const CMMFile *mfile, float *min, float* max,
double *mean, double *rms)
{
double f1,f2,f3;
*min = mfile->stats.min;
*max = mfile->stats.max;
if (ccp4_file_is_write(mfile->stream) && mfile->close_mode == 0) {
f1 = (mfile->stats.total != 0) ? mfile->stats.mean / mfile->stats.total : 0;
f2 = (mfile->stats.total != 0) ? mfile->stats.rms / mfile->stats.total : 0;
f3 = f2 - f1*f1;
*rms = (f3 > 0) ? sqrt(f3) : 0;
*mean = f1 - (double) mfile->stats.offset;
} else {
*mean = mfile->stats.mean;
*rms = mfile->stats.rms;
}
}
/*! Set the map statistics, including maximum, minimum, mean and standard
deviation. This is only meaningful for datamode FLOAT32 and the file
open in write mode.
\param mfile (CMMFile *)
\param min (float)
\param max (float)
\param mean (double)
\param rms (double) */
void ccp4_cmap_set_mapstats(CMMFile *mfile, const float min, const float max,
const double mean, const double rms)
{
if (ccp4_file_is_write(mfile->stream)) {
mfile->stats.min = min;
mfile->stats.max = max;
mfile->stats.mean = mean;
mfile->stats.rms = rms;
}
}
/*! Set the local header size (in bytes)
\param mfile (CMMFile *)
\param size (size_t) header size associated with each section (in bytes) */
void ccp4_cmap_set_local_header(CMMFile *mfile, size_t size)
{
if (ccp4_file_is_write(mfile->stream) && mfile->data.number == 0) {
mfile->data.header_size = size;
mfile->data.block_size = mfile->data.section_size + mfile->data.header_size;
}
return;
}
/*! Return the local header size
\param mfile (CMMFile *)
\return header size associated with each section (in bytes) */
size_t ccp4_cmap_get_local_header(CMMFile *mfile)
{
return mfile->data.header_size;
}

80
ccp4c/ccp4/cmap_close.c Normal file
View File

@@ -0,0 +1,80 @@
/*
cmap_close.c: close map file
Copyright (C) 2001 CCLRC, Charles Ballard
This library is free software: you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public License
version 3, modified in accordance with the provisions of the
license to address the requirements of UK law.
You should have received a copy of the modified GNU Lesser General
Public License along with this library. If not, copies may be
downloaded from http://www.ccp4.ac.uk/ccp4license.php
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.
*/
#include <string.h>
#include <math.h>
#include <stdarg.h>
#include "cmaplib.h"
#include "cmap_header.h"
#include "cmap_labels.h"
#include "cmap_errno.h"
/*! Close the file.
In write mode the header is output, along with the machine
stamp. In read mode the file is just closed.
Write mode supports ways of updating the map statistics (
only active for FLOAT32).
/param mfile (CMMFile *)
/return void */
void ccp4_cmap_close(CMMFile *mfile)
{
int i;
if ( mfile == NULL)
return;
if (ccp4_file_is_write(mfile->stream) ) {
if ( mfile->data_mode == FLOAT32) {
switch (mfile->close_mode) {
case 1:
break;
case 2:
mfile->stats.offset = 0.0f;
case 0:
default:
if (mfile->stats.total != 0) {
mfile->stats.mean /= mfile->stats.total;
mfile->stats.rms /= mfile->stats.total;
mfile->stats.rms -= mfile->stats.mean*mfile->stats.mean;
mfile->stats.rms = (mfile->stats.rms > 0) ? sqrt(mfile->stats.rms) : 0;
mfile->stats.mean += (double) mfile->stats.offset;
}
break;
}
}
write_mapheader(mfile);
write_maplabels(mfile);
ccp4_file_warch(mfile->stream);
}
ccp4_file_close(mfile->stream);
for (i=0 ; i != mfile->labels.number ; i++)
if (mfile->labels.labels[i] != NULL)
free(mfile->labels.labels[i]);
free(mfile);
}
/*! Set the close mode:
0: calculate based on stored values (default)
1: just dump the current values
/param mfile (CMMFile *)
/param mask (unsigned int) close mode
/return void */
void ccp4_cmap_closemode(CMMFile *mfile, unsigned int mask)
{
mfile->close_mode = mask;
}

476
ccp4c/ccp4/cmap_data.c Normal file
View File

@@ -0,0 +1,476 @@
/*
cmap_data.c: read and write map sections.
Copyright (C) 2001 CCLRC, Charles Ballard
This library is free software: you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public License
version 3, modified in accordance with the provisions of the
license to address the requirements of UK law.
You should have received a copy of the modified GNU Lesser General
Public License along with this library. If not, copies may be
downloaded from http://www.ccp4.ac.uk/ccp4license.php
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.
*/
#include <math.h>
#include <string.h>
#include <stdlib.h>
#include "cmaplib.h"
#include "cmap_data.h"
#include "cmap_stats.h"
#include "cmap_errno.h"
/*! Internal: return the an estimate of the number of sections in the map
file based upon the length.
Update mfile->data.number as a side effect.
\param mfile (CMMFile *)
\return number of sections according to length-data/section_size */
int number_sections(CMMFile *mfile)
{
div_t sections;
sections = div(ccp4_file_length(mfile->stream)-mfile->data.offset,
mfile->data.block_size);
return mfile->data.number = sections.quot;
}
/*! seek among the map sections. The units are of size block_size.
\param mfile (CMMFile *)
\param sec (int) section number
\param whence (unsigned int) SEEK_SET, SEEK_CUR or SEEK_END
\return offset in file, or EOF */
int ccp4_cmap_seek_section(CMMFile *mfile, int sec, unsigned int whence)
{
size_t curr_posn;
div_t secs;
int result = EOF;
if ( mfile == NULL ) {
ccp4_signal( CCP4_ERRLEVEL(3) | CMAP_ERRNO(CMERR_NoChannel),
"ccp4_cmap_seekdata",NULL);
return EOF; }
switch (whence) {
case SEEK_SET:
if ( ccp4_file_is_read(mfile->stream) &&
( sec < 0 || sec > mfile->data.number) )
ccp4_signal( CCP4_ERRLEVEL(2) | CMAP_ERRNO(CMERR_ParamError),
"ccp4_cmap_seek_section",NULL);
else
result = ccp4_file_raw_seek(mfile->stream, mfile->data.offset +
sec * mfile->data.block_size, SEEK_SET);
break;
case SEEK_END:
if ( ccp4_file_is_read(mfile->stream) &&
( sec > 0 || abs(sec) > mfile->data.number) )
ccp4_signal( CCP4_ERRLEVEL(2) | CMAP_ERRNO(CMERR_ParamError),
"ccp4_cmap_seek_section",NULL);
else
result = ccp4_file_raw_seek(mfile->stream, sec * mfile->data.block_size,
SEEK_END);
break;
case SEEK_CUR:
curr_posn = ccp4_file_tell(mfile->stream);
secs = div(curr_posn - mfile->data.offset,mfile->data.block_size);
if ( ccp4_file_is_read(mfile->stream) &&
( (secs.quot + sec) < 0 || (secs.quot + sec) >= mfile->data.number) )
ccp4_signal( CCP4_ERRLEVEL(2) | CMAP_ERRNO(CMERR_ParamError),
"ccp4_cmap_seek_section",NULL);
else
result = ccp4_file_raw_seek(mfile->stream,
(sec > 0) ? (mfile->data.block_size - secs.rem +
(sec - 1)*mfile->data.block_size) :
(sec*mfile->data.block_size - secs.rem),
SEEK_CUR);
}
return (result == EOF) ? EOF :
((result - mfile->data.offset)/mfile->data.block_size);
}
/*! write map section to file.
Note: this wraps a raw write, with no location checking. It is
therefore the responsibility of the calling program to ensure that
everything is correct. Effectively assume appending to file.
\param mfile (CMMFile *)
\param section (const void *)
\return 1 on success, 0 on failure */
int ccp4_cmap_write_section(CMMFile *mfile, const void *section)
{
int result=0;
size_t write_dim;
if (mfile == NULL || section == NULL) {
ccp4_signal( CCP4_ERRLEVEL(2) | CMAP_ERRNO(CMERR_NoChannel),
"ccp4_cmap_write_section",NULL);
return 0; }
if (!ccp4_file_is_write(mfile->stream)) {
ccp4_signal( CCP4_ERRLEVEL(3) | CMAP_ERRNO(CMERR_WriteFail),
"ccp4_cmap_write_section",NULL);
return 0; }
write_dim = mfile->map_dim[0] * mfile->map_dim[1];
result = ccp4_file_write(mfile->stream, section, write_dim);
/* note that we have started writing */
mfile->data.number++;
if (result != write_dim)
ccp4_signal( CCP4_ERRLEVEL(3) | CMAP_ERRNO(CMERR_WriteFail),
"ccp4_cmap_write_section",NULL);
else
if (mfile->data_mode == FLOAT32)
stats_update(&mfile->stats, (float *)section,
(float *)section+write_dim);
return (result == write_dim) ? 1 : 0;
}
/*! read current map section from file to section.
Some checking is performed to ensure we are at the start of a
legitimate map section.
\param mfile (CMMFile *)
\param section (void *) array large enough to hold the map section
\return 1 on success, 0 on failure */
int ccp4_cmap_read_section(CMMFile *mfile, void *section)
{
int result = 0;
div_t secs;
off_t curr_posn;
const off_t data_offset = 0;
size_t read_dim;
if (mfile == NULL ) {
ccp4_signal( CCP4_ERRLEVEL(2) | CMAP_ERRNO(CMERR_NoChannel),
"ccp4_cmap_read_section",NULL);
return 0; }
if (!ccp4_file_is_read(mfile->stream)) {
ccp4_signal( CCP4_ERRLEVEL(2) | CMAP_ERRNO(CMERR_ReadFail),
"ccp4_cmap_read_section",NULL);
return 0; }
curr_posn = ccp4_file_tell(mfile->stream);
secs = div(curr_posn - mfile->data.offset,
mfile->data.block_size);
/* ensure legit section (although rely upon EOF ) */
if (secs.quot < 0 || secs.rem < 0) {
ccp4_file_raw_seek(mfile->stream, mfile->data.offset, SEEK_SET);
secs.quot = 0;
} else if( secs.rem > data_offset && secs.rem < mfile->data.section_size )
ccp4_file_raw_seek(mfile->stream, - secs.rem, SEEK_CUR);
else if ( secs.rem >= mfile->data.section_size ) {
ccp4_file_raw_seek(mfile->stream, (mfile->data.block_size-secs.rem), SEEK_CUR);
secs.quot++; }
read_dim = mfile->map_dim[0] * mfile->map_dim[1];
/* do not read if at end */
if (secs.quot < 0 || secs.quot < mfile->data.number)
result = ccp4_file_read(mfile->stream, section, read_dim);
if (result != read_dim)
ccp4_signal( CCP4_ERRLEVEL(3) | CMAP_ERRNO(CMERR_ReadFail),
"ccp4_cmap_read_section",NULL);
return (result == read_dim) ? 1 : 0;
}
/*! read current section header (character array)
After reading we are at the end of the local header
\param mfile (CMMFile *)
\param header (char *) character array large enough to hold
the local header (raw read so not string)
\return 1 on success, 0 on failure */
int ccp4_cmap_read_section_header(const CMMFile *mfile, char *header)
{
int result;
div_t secs;
if (mfile == NULL || header == NULL) {
ccp4_signal( CCP4_ERRLEVEL(3) | CMAP_ERRNO(CMERR_NoChannel),
"ccp4_cmap_read_section_header",NULL);
return EOF; }
if (!ccp4_file_is_read(mfile->stream)) {
ccp4_signal( CCP4_ERRLEVEL(3) | CMAP_ERRNO(CMERR_ReadFail),
"ccp4_cmap_read_section header",NULL);
return EOF; }
if ( mfile->data.header_size == 0) return (0);
result = ccp4_file_tell(mfile->stream);
secs = div(result - mfile->data.offset, mfile->data.block_size);
if ( secs.quot < 0 || secs.quot >= mfile->data.number ) return (0);
/* navigate to nearest header */
if ( secs.rem != mfile->data.section_size)
ccp4_file_raw_seek(mfile->stream,(mfile->data.section_size
- secs.rem), SEEK_CUR);
if ( (result = ccp4_file_readchar( mfile->stream, (uint8 *) header,
mfile->data.header_size)) != mfile->data.header_size)
ccp4_signal(ccp4_errno,
"ccp4_cmap_read_section_header",
NULL);
return (result == mfile->data.header_size) ? 1 : 0;
}
/*! write the local section header to the file. This must be of
size mfile->data.header.size.
Note: no checking is done so it is up to the calling program
to ensure that the file is in the correct location. As seeking
is turned off, this assumes we are appending to the file.
\param mfile (CMMFile *)
\param header (const char *) the local header character array
(not necessarily a string)
\return number of bytes written or EOF */
int ccp4_cmap_write_section_header(CMMFile *mfile, const char *header)
{
char *output;
int result;
if (mfile == NULL ) {
ccp4_signal( CCP4_ERRLEVEL(3) | CMAP_ERRNO(CMERR_NoChannel),
"ccp4_cmap_write_section_header",NULL);
return EOF; }
if (!ccp4_file_is_write(mfile->stream)) {
ccp4_signal( CCP4_ERRLEVEL(3) | CMAP_ERRNO(CMERR_NoChannel),
"ccp4_cmap_write_section_header",NULL);
return EOF; }
if ( mfile->data.header_size == 0) return (0);
output = (char *) malloc(mfile->data.header_size);
memset(output,' ', mfile->data.header_size);
if (header) memcpy(output, header,mfile->data.header_size);
if ( (result = ccp4_file_writechar( mfile->stream, (uint8 *) output,
mfile->data.header_size))
!= mfile->data.header_size)
ccp4_signal(ccp4_errno,
"ccp4_cmap_write_section_header",
NULL);
return (result == mfile->data.header_size) ? 1 : 0;
}
/*! seek a row within a map section
\param mfile (CMMFile *)
\param row (int)
\param whence (unsigned int) SEEK_SET, SEEK_END, SEEK_CUR
\return offset in file or EOF */
int ccp4_cmap_seek_row(CMMFile *mfile, int row, unsigned int whence)
{
size_t curr_posn;
div_t secs, rows;
int result = EOF;
size_t item_size;
if ( mfile == NULL ) {
ccp4_signal( CCP4_ERRLEVEL(2) | CMAP_ERRNO(CMERR_NoChannel),
"ccp4_cmap_seek_row",NULL);
return EOF; }
item_size = ccp4_file_itemsize(mfile->stream);
curr_posn = ccp4_file_tell(mfile->stream);
secs = div(curr_posn - mfile->data.offset,mfile->data.block_size);
switch (whence) {
case SEEK_SET:
if ( row < 0 || row >= mfile->map_dim[1])
ccp4_signal( CCP4_ERRLEVEL(2) | CMAP_ERRNO(CMERR_ParamError),
"ccp4_cmap_seek_row",NULL);
else
result = ccp4_file_raw_seek(mfile->stream, mfile->data.offset +
(secs.quot * mfile->data.block_size +
row * mfile->map_dim[0]*item_size),
SEEK_SET);
break;
case SEEK_END:
if ( row >= 0 || abs(row) > mfile->map_dim[1])
ccp4_signal( CCP4_ERRLEVEL(2) | CMAP_ERRNO(CMERR_ParamError),
"ccp4_cmap_seek_row",NULL);
else
result = ccp4_file_raw_seek(mfile->stream, mfile->data.offset +
(secs.quot * mfile->data.block_size +
mfile->data.section_size +
row * mfile->map_dim[0]*item_size),
SEEK_SET);
break;
case SEEK_CUR:
rows = div(secs.rem,mfile->map_dim[0]*item_size);
if ( (rows.quot + row) < 0 || (rows.quot + row) >= mfile->data.number)
ccp4_signal( CCP4_ERRLEVEL(2) | CMAP_ERRNO(CMERR_ParamError),
"ccp4_cmap_seek_row",NULL);
else
result = ccp4_file_raw_seek(mfile->stream,
( row > 0) ? (mfile->map_dim[0]*item_size - rows.rem
+ (row-1)*mfile->map_dim[0]*item_size) :
( row*mfile->map_dim[0]*item_size - rows.rem),
SEEK_CUR);
}
return (result);
}
/*! write map row to file.
Note: this wraps a raw write, with no location checking. It is
therefore the responsibility of the calling program to ensure that
everything is correct. Effectively assume appending to file.
\param mfile (CMMFile *)
\param row (const void *) data to be written
\return 1 on success, 0 on failure */
int ccp4_cmap_write_row(CMMFile *mfile, const void *row)
{
int result=0;
if (mfile == NULL || row == NULL) {
ccp4_signal( CCP4_ERRLEVEL(2) | CMAP_ERRNO(CMERR_NoChannel),
"ccp4_cmap_write_row",NULL);
return EOF; }
if (!ccp4_file_is_write(mfile->stream)) {
ccp4_signal( CCP4_ERRLEVEL(3) | CMAP_ERRNO(CMERR_WriteFail),
"ccp4_cmap_write_row",NULL);
return EOF; }
result = ccp4_file_write(mfile->stream, row, mfile->map_dim[0]);
/* note that we have started writing */
mfile->data.number++;
if (result != mfile->map_dim[0])
ccp4_signal( CCP4_ERRLEVEL(3) | CMAP_ERRNO(CMERR_WriteFail),
"ccp4_cmap_write_row",NULL);
else
if (mfile->data_mode == FLOAT32)
stats_update(&mfile->stats, (float *)row, (float *)row+mfile->map_dim[0]);
return (result == mfile->map_dim[0]) ? 1 : 0;
}
/*! read current map section from file to section.
Some checking is performed to ensure we are at the start of a
legitimate map row.
\param mfile (CMMFile *)
\param row (void *) array large enough to hold the map row
\return 1 on success, 0 on failure */
int ccp4_cmap_read_row(CMMFile *mfile, void *row)
{
int result = 0, item_size;
div_t secs, rows;
off_t curr_posn;
if (mfile == NULL) {
ccp4_signal( CCP4_ERRLEVEL(2) | CMAP_ERRNO(CMERR_NoChannel),
"ccp4_cmap_read_row",NULL);
return EOF; }
if (!ccp4_file_is_read(mfile->stream) || row == NULL) {
ccp4_signal( CCP4_ERRLEVEL(2) | CMAP_ERRNO(CMERR_ReadFail),
"ccp4_cmap_read_row",NULL);
return EOF; }
item_size = ccp4_file_itemsize(mfile->stream);
curr_posn = ccp4_file_tell(mfile->stream);
secs = div(curr_posn - mfile->data.offset,
mfile->data.block_size);
rows = div(secs.rem, mfile->map_dim[0]*item_size);
if (secs.quot < 0 || secs.rem < 0)
ccp4_file_raw_seek(mfile->stream, mfile->data.offset, SEEK_SET);
else if(rows.quot >= mfile->map_dim[1] )
ccp4_file_raw_seek(mfile->stream, (mfile->data.block_size
- secs.rem), SEEK_CUR);
else if( rows.rem != 0)
ccp4_file_raw_seek(mfile->stream, ( - secs.rem), SEEK_CUR);
result = ccp4_file_read(mfile->stream, row, mfile->map_dim[0]);
if (result != mfile->map_dim[0])
ccp4_signal( CCP4_ERRLEVEL(3) | CMAP_ERRNO(CMERR_ReadFail),
"ccp4_cmap_read_row",NULL);
return (result == mfile->map_dim[0]) ? 1 : 0;
}
/*! raw seek in items
\param mfile (CMMFile *)
\param offset (int) number of items
\param whence (unsigned int) SEEK_SET, SEEK_CUR, SEEK_END;
\return 0 on success, EOF on failure */
int ccp4_cmap_seek_data(CMMFile *mfile, int offset, unsigned int whence)
{
int result = EOF;
if ( mfile == NULL ) {
ccp4_signal( CCP4_ERRLEVEL(2) | CMAP_ERRNO(CMERR_NoChannel),
"ccp4_cmap_seekdata",NULL);
return (result); }
if ((result = ccp4_file_seek( mfile->stream, offset, whence)) == -1)
ccp4_signal(ccp4_errno, "ccp4_cmap_seek_data",NULL);
return (result);
}
/*! raw write of nelements items to file, according to the datamode,
at current location
\param mfile (const CMMFile *)
\param section (void *) values written, should contain at least
nelements items
\param n_items (int) number of items to be written
\return number of items written or EOF */
int ccp4_cmap_write_data(CMMFile *mfile, const void *items, int n_items)
{
int result=0;
if (mfile == NULL || items == NULL) {
ccp4_signal( CCP4_ERRLEVEL(2) | CMAP_ERRNO(CMERR_NoChannel),
"ccp4_cmap_write_data",NULL);
return EOF; }
if (ccp4_file_is_write(mfile->stream)) {
result = ccp4_file_write(mfile->stream, (uint8 *) items, n_items);
if (result != n_items)
ccp4_signal( CCP4_ERRLEVEL(3) | CMAP_ERRNO(CMERR_WriteFail),
"ccp4_cmap_write_data",NULL);
else if (mfile->data_mode == FLOAT32)
stats_update(&mfile->stats, (float *)items, (float *)items+result);
}
return (result);
}
/*! raw read of nelements items from file according to the datamode
at current location
\param mfile (const CMMFile *)
\param items (void *) values read to here, so should have enough space
for nelements items
\param n_items (int) number of items to be read
\return number of items read or EOF */
int ccp4_cmap_read_data(const CMMFile *mfile, void *items, int n_items)
{
int result=0;
if (mfile == NULL || items == NULL) {
ccp4_signal( CCP4_ERRLEVEL(2) | CMAP_ERRNO(CMERR_NoChannel),
"ccp4_cmap_read_data",NULL);
return EOF; }
if (ccp4_file_is_read(mfile->stream))
result = ccp4_file_read(mfile->stream, (uint8 *) items, n_items);
return (result);
}

32
ccp4c/ccp4/cmap_data.h Normal file
View File

@@ -0,0 +1,32 @@
/*
cmap_data.h: header for cmap_data.c
Copyright (C) 2001 CCLRC, Charles Ballard
This library is free software: you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public License
version 3, modified in accordance with the provisions of the
license to address the requirements of UK law.
You should have received a copy of the modified GNU Lesser General
Public License along with this library. If not, copies may be
downloaded from http://www.ccp4.ac.uk/ccp4license.php
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.
*/
#ifndef __GUARD_MAPLIB_DATA
#define __GUARD_MAPLIB_DATA
#ifdef __cplusplus
extern "C" {
#endif
int number_sections(CMMFile *mfile);
#ifdef __cplusplus
}
#endif
#endif /* __GUARD_MAPLIB_DATA */

52
ccp4c/ccp4/cmap_errno.h Normal file
View File

@@ -0,0 +1,52 @@
/*
cmap_errno.h: error codes for map handling functions
Copyright (C) 2001 CCLRC, Charles Ballard
This library is free software: you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public License
version 3, modified in accordance with the provisions of the
license to address the requirements of UK law.
You should have received a copy of the modified GNU Lesser General
Public License along with this library. If not, copies may be
downloaded from http://www.ccp4.ac.uk/ccp4license.php
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.
*/
#ifndef __GUARD_MAPLIB_ERR
#define __GUARD_MAPLIB_ERR
#include "ccp4_errno.h"
#ifdef __cplusplus
extern "C" {
#endif
#define CMAP_ERRNO(n) (CCP4_ERR_MAP | (n))
/* error defs */
#define CMERR_Ok 0
#define CMERR_NoChannel 1
#define CMERR_NoFile 2
#define CMERR_NoLogicalName 3
#define CMERR_CantOpenFile 4
#define CMERR_NoHeader 5
#define CMERR_ReadFail 6
#define CMERR_WriteFail 7
#define CMERR_ParamError 8
#define CMERR_UnrecognK 9
#define CMERR_FileStamp 10
#define CMERR_SymErr 11
#define CMERR_AllocFail 12
#define CMERR_MaxFile 13
#define CMERR_SeekFail 14
#ifdef __cplusplus
}
#endif
#endif /* __GUARD_MAPLIB_ERR */

182
ccp4c/ccp4/cmap_header.c Normal file
View File

@@ -0,0 +1,182 @@
/*
cmap_header.c: read and write map file headers
Copyright (C) 2001 CCLRC, Charles Ballard
This library is free software: you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public License
version 3, modified in accordance with the provisions of the
license to address the requirements of UK law.
You should have received a copy of the modified GNU Lesser General
Public License along with this library. If not, copies may be
downloaded from http://www.ccp4.ac.uk/ccp4license.php
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.
*/
#include <string.h>
#include <math.h>
#include <stdarg.h>
#include "cmaplib.h"
#include "cmap_errno.h"
#include "cmap_skew.h"
/*! Internal: read header from file and fill CMMFile struct.
Called after file is opened for read.
\param mfile (CMMFile *)
\return 1 on success, EOF on failure*/
int parse_mapheader(CMMFile *mfile)
{
const int read_total = 77;
const size_t header_size = 1024U, n_byt_symop = 80U;
unsigned char buffer[224];
int result;
float fmean,frms;
ccp4_file_rewind(mfile->stream);
memset(buffer,'\0',224);
result = ccp4_file_readint(mfile->stream, &buffer[0], 10) ;
result += ccp4_file_readfloat(mfile->stream, &buffer[40], 6);
result += ccp4_file_readint(mfile->stream, &buffer[64], 3);
result += ccp4_file_readfloat(mfile->stream, &buffer[76], 3);
result += ccp4_file_readint(mfile->stream, &buffer[88], 3);
/* skew matrix and translation */
result += ccp4_file_readfloat(mfile->stream, &buffer[100], 12);
/* reserved */
result += ccp4_file_readint(mfile->stream, &buffer[148], 8);
/* user access */
result += ccp4_file_readchar(mfile->stream, &buffer[180], 28);
/* map and machine stamp */
result += ccp4_file_readint(mfile->stream, &buffer[208], 2);
/* ARMS */
result += ccp4_file_readfloat(mfile->stream, &buffer[216], 1);
result += ccp4_file_readint(mfile->stream, &buffer[220], 1);
if (result != read_total) {
ccp4_signal( CCP4_ERRLEVEL(3) | CMAP_ERRNO(CMERR_ReadFail),
"parse_header",
NULL);
return EOF; }
memcpy(&mfile->map_dim[0],&buffer[0],sizeof(mfile->map_dim));
memcpy(&mfile->data_mode,&buffer[12],sizeof(int));
memcpy(&mfile->origin[0],&buffer[16],sizeof(mfile->origin));
memcpy(&mfile->cell_grid[0],&buffer[28],sizeof(mfile->cell_grid));
memcpy(&mfile->cell[0],&buffer[40],sizeof(mfile->cell));
memcpy(&mfile->axes_order[0],&buffer[64],sizeof(mfile->axes_order));
memcpy(&mfile->stats.min,&buffer[76],sizeof(float));
memcpy(&mfile->stats.max,&buffer[80],sizeof(float));
memcpy(&fmean,&buffer[84],sizeof(float));
mfile->stats.mean = (double) fmean;
memcpy(&mfile->spacegroup,&buffer[88],sizeof(int));
/* Additions for EM support.
Define contents as image, image stack, volume or volume stack.
In latter case, allows for 400+ispg convention. */
mfile->EM_spacegroup = mfile->spacegroup;
strncpy(mfile->EM_contents,"VOLU",4);
if (mfile->spacegroup > 400 && mfile->spacegroup < 631) {
mfile->spacegroup = mfile->spacegroup - 400;
strncpy(mfile->EM_contents,"VLST",4);
}
if (mfile->spacegroup == 0) {
if (mfile->map_dim[2] == 1) strncpy(mfile->EM_contents,"IMAG",4);
if (mfile->map_dim[2] > 1) strncpy(mfile->EM_contents,"IMST",4);
}
memcpy(&mfile->symop.size,&buffer[92],sizeof(int));
memcpy(&mfile->user_access,&buffer[180],sizeof(mfile->user_access));
/* memcpy(&mfile->data.header_size,&buffer[204],sizeof(int)); */
memcpy(&frms,&buffer[216],sizeof(float));
mfile->stats.rms = (double) frms;
memcpy(&mfile->labels.number,&buffer[220],sizeof(int));
memcpy(&result,&buffer[96],sizeof(int));
if (result !=0) {
memcpy(&mfile->skew.rotation[0][0],&buffer[100],sizeof(mfile->skew.rotation));
memcpy(&mfile->skew.translation[0],&buffer[136],sizeof(mfile->skew.translation));
}
ccp4_file_setmode(mfile->stream, mfile->data_mode);
/* may go to seperate function */
mfile->symop.offset = header_size;
mfile->data.offset = mfile->symop.offset + mfile->symop.size;
mfile->data.section_size = mfile->map_dim[0]*mfile->map_dim[1]
*ccp4_file_itemsize(mfile->stream);
mfile->data.block_size = mfile->data.section_size + mfile->data.header_size;
mfile->data.number = mfile->map_dim[2];
mfile->symop.number = mfile->symop.size / n_byt_symop;
return 1;
}
/*! Internal: write summary of current CMMFile struct to file.
Called when file is opened write, and closed write.
\param mfile (CMMFile *)
\return 1 on success, EOF on failure */
int write_mapheader(CMMFile *mfile)
{
const int write_total = 77;
unsigned char buffer[224];
int result;
float fmean,frms;
memset(buffer,'\0',224);
memcpy(&buffer[0],&mfile->map_dim[0],sizeof(mfile->map_dim));
memcpy(&buffer[12],&mfile->data_mode,sizeof(int));
memcpy(&buffer[16],&mfile->origin[0],sizeof(mfile->origin));
memcpy(&buffer[28],&mfile->cell_grid[0],sizeof(mfile->cell_grid));
memcpy(&buffer[40],&mfile->cell[0],sizeof(mfile->cell));
memcpy(&buffer[64],&mfile->axes_order[0],sizeof(mfile->axes_order));
memcpy(&buffer[76],&mfile->stats.min,sizeof(float));
memcpy(&buffer[80],&mfile->stats.max,sizeof(float));
fmean = (float) mfile->stats.mean;
memcpy(&buffer[84],&fmean,sizeof(float));
/* additions for EM support */
if (!strncmp(mfile->EM_contents,"VLST",4)) {
memcpy(&buffer[88],&mfile->EM_spacegroup,sizeof(int));
} else {
memcpy(&buffer[88],&mfile->spacegroup,sizeof(int));
}
memcpy(&buffer[92],&mfile->symop.size,sizeof(int));
memcpy(&buffer[180],&mfile->user_access,sizeof(mfile->user_access));
/* memcpy(&buffer[204],&mfile->data.header_size,sizeof(int)); */
memcpy(&buffer[208],"MAP ",4U);
frms = (float) mfile->stats.rms;
memcpy(&buffer[216],&frms,sizeof(float));
memcpy(&buffer[220],&mfile->labels.number,sizeof(int));
if (skew_set(&mfile->skew) == TRUE) {
result = 1;
memcpy(&buffer[96],&result, sizeof(int));
memcpy(&buffer[100],&mfile->skew.rotation[0][0],sizeof(mfile->skew.rotation));
memcpy(&buffer[148],&mfile->skew.translation[0],sizeof(mfile->skew.translation));
}
ccp4_file_seek(mfile->stream, 0L, SEEK_SET);
result = ccp4_file_writeint(mfile->stream, &buffer[0], 10);
result += ccp4_file_writefloat(mfile->stream, &buffer[40], 6);
result += ccp4_file_writeint(mfile->stream, &buffer[64], 3);
result += ccp4_file_writefloat(mfile->stream, &buffer[76], 3);
result += ccp4_file_writeint(mfile->stream, &buffer[88], 3);
result += ccp4_file_writefloat(mfile->stream, &buffer[100], 12);
result += ccp4_file_writeint(mfile->stream, &buffer[148], 8);
result += ccp4_file_writechar(mfile->stream, &buffer[180], 28);
result += ccp4_file_writeint(mfile->stream, &buffer[208], 2);
result += ccp4_file_writefloat(mfile->stream, &buffer[216], 1);
result += ccp4_file_writeint(mfile->stream, &buffer[220], 1);
if (result != write_total)
ccp4_signal( CCP4_ERRLEVEL(3) | CMAP_ERRNO(CMERR_WriteFail),
"write_header",
NULL);
return ( (result == write_total) ? 1 : EOF);
}

34
ccp4c/ccp4/cmap_header.h Normal file
View File

@@ -0,0 +1,34 @@
/*
cmap_header.h: header file for cmap_header.c
Copyright (C) 2001 CCLRC, Charles Ballard
This library is free software: you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public License
version 3, modified in accordance with the provisions of the
license to address the requirements of UK law.
You should have received a copy of the modified GNU Lesser General
Public License along with this library. If not, copies may be
downloaded from http://www.ccp4.ac.uk/ccp4license.php
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.
*/
#ifndef __GUARD_MAPLIB_HEADER
#define __GUARD_MAPLIB_HEADER
#ifdef __cplusplus
extern "C" {
#endif
int parse_mapheader(CMMFile *mfile);
int write_mapheader(CMMFile *mfile);
#ifdef __cplusplus
}
#endif
#endif /* __GUARD_MAPLIB_HEADER */

179
ccp4c/ccp4/cmap_labels.c Normal file
View File

@@ -0,0 +1,179 @@
/*
cmap_labels.c: read and write map header labels
Copyright (C) 2001 CCLRC, Charles Ballard
This library is free software: you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public License
version 3, modified in accordance with the provisions of the
license to address the requirements of UK law.
You should have received a copy of the modified GNU Lesser General
Public License along with this library. If not, copies may be
downloaded from http://www.ccp4.ac.uk/ccp4license.php
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.
*/
#include <string.h>
#include "cmaplib.h"
#include "cmap_labels.h"
#include "cmap_errno.h"
/*! Internal: read the labels from file header and copy into char * array
Called when the file is opened in read mode.
\param mfile (CMMFile *)
\return 1 on succes */
int parse_maplabels(CMMFile *mfile)
{
char buffer[81], *cptr;
const unsigned int n_byt_label = 80U, max_label = 10U;
/* const unsigned int labels_offset = 224U; */
int i;
/* ccp4_file_seek(mfile->stream,labels_offset,SEEK_SET); */
for (i=0 ; i!=mfile->labels.number ; i++) {
ccp4_file_readchar(mfile->stream,(uint8 *) buffer,n_byt_label);
cptr = buffer+n_byt_label;
while (cptr> buffer && *--cptr == ' ');
*(++cptr) = '\0';
mfile->labels.labels[i] = strdup(buffer);
}
ccp4_file_raw_seek(mfile->stream,(max_label-mfile->labels.number)
*n_byt_label,
SEEK_CUR);
return 1;
}
/*! Internal: dump the labels char * array to file, offset at 224 bytes.
Called when the file is opened or closed in write mode, immediately after the
header is written.
\param mfile (const CMMFile *)
\return 1 on success, 0 on failure */
int write_maplabels(const CMMFile *mfile)
{
char buffer[80];
/* const unsigned int labels_offset = 224U; */
int i, result = 0;
size_t slen;
/* ccp4_file_seek(mfile->stream,labels_offset,SEEK_SET); */
for (i=0 ; i != mfile->labels.number ; i++) {
memset(buffer,' ',80U);
slen = strlen(mfile->labels.labels[i]);
if (slen > 80U) slen = 80U;
strncpy(buffer,mfile->labels.labels[i],slen);
result += ccp4_file_writechar(mfile->stream,(uint8 *) buffer,80U);
}
memset(buffer,' ',80U);
while(i != 10) {
result += ccp4_file_writechar(mfile->stream,(uint8 *) buffer,80U);
i++;
}
return (result == 800) ? 1 : 0 ;
}
/*! Set the label in the map header. Headers are 80 characters long.
The labels are written to the file when it is closed. Therefore,
the file must be in write mode.
If label == NULL the element corresponding to posn is removed.
The number of labels is recalculated on each call.
\param mfile (CMMFile *)
\param label (const char *) the C-style character array
\param posn (int) the label number (C-style, 0 -> 9)
\return number of label effected, or EOF */
int ccp4_cmap_set_label(CMMFile *mfile, const char *label, int posn)
{
int i,j;
if (mfile == NULL) {
ccp4_signal( CCP4_ERRLEVEL(3) | CMAP_ERRNO(CMERR_NoChannel),
"ccp4_cmap_set_label",NULL);
return (EOF);}
if (ccp4_file_is_write(mfile->stream) == 0) {
ccp4_signal( CCP4_ERRLEVEL(3) | CMAP_ERRNO(CMERR_WriteFail),
"ccp4_cmap_label_set",NULL);
return (EOF);}
/*posn must be between 0 and 9 */
if (posn < 0) {
posn = 0;
} else if (posn > mfile->labels.number) {
posn = mfile->labels.number;
}
if (mfile->labels.labels[posn] != NULL)
free(mfile->labels.labels[posn]);
/* if label == NULL reset the value and compress set */
if (label == NULL) {
mfile->labels.labels[posn] = NULL;
for ( i=posn ; i!=10 ; i++)
if (mfile->labels.labels[i] == NULL)
for ( j=i+1 ; j!=10; j++)
if (mfile->labels.labels[j] != NULL) {
mfile->labels.labels[i] = mfile->labels.labels[j];
mfile->labels.labels[j] = NULL;
break;
}
}
else
mfile->labels.labels[posn] = strdup(label);
/* recalculate number */
for ( i=0 ; i!=10 ; i++)
if (mfile->labels.labels[i] == NULL)
break;
mfile->labels.number = i;
return posn;
}
/*! Get the label corresponding to position posn
\param mfile (const CMMFile *)
\param posn (int) desired label number
\return pointer to label posn */
char *ccp4_cmap_get_label(const CMMFile *mfile, int posn)
{
char *label;
if (mfile == NULL) {
ccp4_signal( CCP4_ERRLEVEL(3) | CMAP_ERRNO(CMERR_NoChannel),
"ccp4_cmap_get_label",NULL);
return (NULL);}
if (posn < 0 || posn >= mfile->labels.number)
label = NULL;
else
label = mfile->labels.labels[posn];
return label;
}
/*! Return the number of labels.
\param mfile (CMMFile *)
\return the number of labels */
int ccp4_cmap_number_label(const CMMFile *mfile)
{
return mfile->labels.number;
}
/*! Get the label corresponding to the title
wrapping ccp4_cmap_get_label.
\param mfile (const CMMFile *)
\return pointer to label 0, or NULL */
char *ccp4_cmap_get_title(const CMMFile *mfile)
{
return ccp4_cmap_get_label(mfile, 0);
}
/*! Set the label corresponding to the title,
wrapping ccp4_cmap_set_label
\param mfile (CMMFile *)
\param label
\return 0 or EOF on failure */
int ccp4_cmap_set_title(CMMFile *mfile, const char *title)
{
return ccp4_cmap_set_label(mfile, title, 0);
}

34
ccp4c/ccp4/cmap_labels.h Normal file
View File

@@ -0,0 +1,34 @@
/*
cmap_labels.h: header for cmap_labels.c
Copyright (C) 2001 CCLRC, Charles Ballard
This library is free software: you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public License
version 3, modified in accordance with the provisions of the
license to address the requirements of UK law.
You should have received a copy of the modified GNU Lesser General
Public License along with this library. If not, copies may be
downloaded from http://www.ccp4.ac.uk/ccp4license.php
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.
*/
#ifndef __GUARD_MAPLIB_LABEL
#define __GUARD_MAPLIB_LABEL
#ifdef __cplusplus
extern "C" {
#endif
int parse_maplabels(CMMFile *mfile);
int write_maplabels(const CMMFile *mfile);
#ifdef __cplusplus
}
#endif
#endif /* __GUARD_MAPLIB_LABEL */

117
ccp4c/ccp4/cmap_open.c Normal file
View File

@@ -0,0 +1,117 @@
/*
cmap_open.c: Opening CCP4-format map files.
Copyright (C) 2001 CCLRC, Charles Ballard
This library is free software: you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public License
version 3, modified in accordance with the provisions of the
license to address the requirements of UK law.
You should have received a copy of the modified GNU Lesser General
Public License along with this library. If not, copies may be
downloaded from http://www.ccp4.ac.uk/ccp4license.php
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.
*/
/** @file cmap_open.c
*
* @brief Opening CCP4-format map files.
*
* @author Charles Ballard
*/
#include <string.h>
#include <math.h>
#include <stdarg.h>
#include <fcntl.h>
#include "cmaplib.h"
#include "cmap_header.h"
#include "cmap_labels.h"
#include "cmap_errno.h"
/*! Internal: malloc CMMFile struct for reading into
\return CMMFile */
CMMFile *init_cmap_read(void)
{
CMMFile *mfile = (CMMFile *) malloc(sizeof(CMMFile));
if (mfile)
memset(mfile,'\0',sizeof(CMMFile));
return mfile;
}
/*! Internal: malloc CMMFile struct for writing
\return CMMFile */
CMMFile *init_cmap_write(void)
{
CMMFile *mfile = (CMMFile *) malloc(sizeof(CMMFile));
if (mfile) {
memset(mfile,'\0',sizeof(CMMFile));
mfile->data_mode = DEFMODE;
mfile->symop.offset = 1024U;
mfile->data.offset = 1024U; }
return mfile;
}
/*! Internal: Identify file as a ccp4 format map
\param file The (CCP4File *) struct representing the file.
\return non-zero on true, 0 on false */
int is_cmap(CCP4File *file)
{
char buffer[4];
const unsigned int map_offset = 208U;
if (file == NULL)
return 0;
if ( ccp4_file_raw_seek(file,map_offset,SEEK_SET) == EOF)
return 0;
if (ccp4_file_readchar(file,(uint8 *) buffer,4U) != 4U)
return 0;
ccp4_file_rewind(file);
return !strncmp(buffer,"MAP ",4);
}
/*! The file is opened.
\param filename (char *) the filename
\param mode (int) the i/o mode , possible values are O_RDONLY, O_WRONLY,
O_RDWR, O_APPEND, O_TMP, O_CREAT, O_TRUNC - see ccp4_sysdep.h
\return (void *) CMMFile structure */
void *ccp4_cmap_open(const char *filename, int mode)
{
CMMFile *mfile;
CCP4File *cfile;
const size_t stamp_offset = 212U;
if ((cfile = ccp4_file_open(filename, mode)) == NULL) {
ccp4_signal( CCP4_ERRLEVEL(3) | CMAP_ERRNO(CMERR_CantOpenFile),
"ccp4_cmap_open",NULL);
return (NULL); }
ccp4_file_raw_setstamp(cfile, stamp_offset);
/* read or write only */
if (cfile->read) {
if (!is_cmap(cfile) || cfile->length < 1025) {
ccp4_signal( CCP4_ERRLEVEL(3) | CMAP_ERRNO(CMERR_NoHeader),
"ccp4_cmap_open",NULL);
ccp4_file_close(cfile);
return NULL; }
ccp4_file_rarch(cfile);
mfile = init_cmap_read();
mfile->stream = cfile;
mfile->file_name = cfile->name;
parse_mapheader(mfile);
parse_maplabels(mfile);
} else if (cfile->write) {
mfile = init_cmap_write();
mfile->stream = cfile;
mfile->file_name = cfile->name;
write_mapheader(mfile);
write_maplabels(mfile);
} else {
ccp4_signal( CCP4_ERRLEVEL(3) | CMAP_ERRNO(CMERR_CantOpenFile),
"ccp4_cmap_open",NULL);
return (NULL); }
return (mfile);
}

104
ccp4c/ccp4/cmap_skew.c Normal file
View File

@@ -0,0 +1,104 @@
/*
cmap_skew.c: set and fetch the skew matrix
Copyright (C) 2001 CCLRC, Charles Ballard
This library is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License version 3,
modified in accordance with the provisions of the license to address
the requirements of UK law.
You should have received a copy of the modified GNU Lesser General
Public License along with this library. If not, copies may be downloaded
from http://www.ccp4.ac.uk/ccp4license.php
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.
*/
#include <math.h>
#include "cmaplib.h"
#include "cmap_skew.h"
#include "cmap_errno.h"
/*! Set the values of the translation and rotation elements of the skew matrix.
Note: the stored file is in FORTRAN order mat[fastest][slowest]
\param mfile (CMMFile *)
\param skew_mat (const float *) the skew translation vestor
\param skew_trans (const float *) the skew rotation matrix (C ordering)
\return 1 if either skew_trans or skew_mat is non-NULL */
int ccp4_cmap_set_mask(CMMFile *mfile, const float *skew_mat, const float *skew_trans)
{
int ictr, jctr;
if (!mfile) {
ccp4_signal( CCP4_ERRLEVEL(3) | CMAP_ERRNO(CMERR_NoChannel),
"ccp4_cmap_set_mask",NULL);
return (EOF);}
if (skew_trans)
for(ictr = 0; ictr < 3 ; ++ictr)
mfile->skew.translation[ictr] = *(skew_trans + ictr);
else
for(ictr = 0; ictr < 3 ; ++ictr)
mfile->skew.translation[ictr] = 0.0F;
if (skew_mat)
for(ictr = 0; ictr < 3 ; ++ictr)
for (jctr = 0 ; jctr < 3 ; ++jctr)
mfile->skew.rotation[jctr][ictr] = *(skew_mat + (3*ictr) + jctr);
else
for(ictr = 0; ictr < 3 ; ++ictr)
for (jctr = 0 ; jctr < 3 ; ++jctr)
mfile->skew.rotation[jctr][ictr] = 0.0F;
return (skew_trans != NULL || skew_mat != NULL );
}
/*! Get the values of the translation and rotation elements of the skew matrix.
Note: the stored file is in FORTRAN order mat[fastest][slowest], the returned
values are in C mat[slowest][fastest] ordering
\param mfile (CMMFile *)
\param skew_mat (const float *) the skew translation vestor
\param skew_trans (const float *) the skew rotation matrix (C ordering)
\return 1 if mask is set */
int ccp4_cmap_get_mask(const CMMFile *mfile, float *skew_mat, float *skew_trans)
{
int ictr, jctr;
if (!mfile || !skew_mat || !skew_trans) {
ccp4_signal( CCP4_ERRLEVEL(3) | CMAP_ERRNO(CMERR_NoChannel),
"ccp4_cmap_get_mask",NULL);
return (EOF);}
for(ictr = 0; ictr < 3 ; ++ictr)
*(skew_trans + ictr) = mfile->skew.translation[ictr];
for(ictr = 0; ictr < 3 ; ++ictr)
for (jctr = 0 ; jctr < 3 ; ++jctr)
*(skew_mat + (3*ictr) + jctr) = mfile->skew.rotation[jctr][ictr];
return skew_set(&mfile->skew);
}
/*! Internal: test whether values are set in the skew matrices
\param skew (CMMFile_Skew *)
\return TRUE or FALSE */
int skew_set(const CMMFile_Skew *skew)
{
return
skew->translation[0] != 0.0F ||
skew->translation[1] != 0.0F ||
skew->translation[2] != 0.0F ||
skew->rotation[0][0] != 0.0F ||
skew->rotation[0][1] != 0.0F ||
skew->rotation[0][2] != 0.0F ||
skew->rotation[1][0] != 0.0F ||
skew->rotation[1][1] != 0.0F ||
skew->rotation[1][2] != 0.0F ||
skew->rotation[2][0] != 0.0F ||
skew->rotation[2][1] != 0.0F ||
skew->rotation[2][2] != 0.0F;
}

32
ccp4c/ccp4/cmap_skew.h Normal file
View File

@@ -0,0 +1,32 @@
/*
cmap_skew.h: header file for cmap_skew.c
Copyright (C) 2001 CCLRC, Charles Ballard
This library is free software: you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public License
version 3, modified in accordance with the provisions of the
license to address the requirements of UK law.
You should have received a copy of the modified GNU Lesser General
Public License along with this library. If not, copies may be
downloaded from http://www.ccp4.ac.uk/ccp4license.php
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.
*/
#ifndef __GUARD_MAPLIB_SKEW
#define __GUARD_MAPLIB_SKEW
#ifdef __cplusplus
extern "C" {
#endif
int skew_set(const CMMFile_Skew *skew);
#ifdef __cplusplus
}
#endif
#endif /* __GUARD_MAPLIB_SKEW */

53
ccp4c/ccp4/cmap_stats.c Normal file
View File

@@ -0,0 +1,53 @@
/*
cmap_stats.c: deal with map statistics.
Copyright (C) 2001 CCLRC, Charles Ballard
This library is free software: you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public License
version 3, modified in accordance with the provisions of the
license to address the requirements of UK law.
You should have received a copy of the modified GNU Lesser General
Public License along with this library. If not, copies may be
downloaded from http://www.ccp4.ac.uk/ccp4license.php
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.
*/
#include <math.h>
#include "cmaplib.h"
#include "cmap_stats.h"
#include "cmap_errno.h"
/*! Internal: use floats in range section_begin to section_end
to update the map statistics.
\param stats (CMMFile_Stats *)
\param section_begin (void *) start of section
\param section_end (void *) one past end-of-section
\return total of map elements so far */
int stats_update(CMMFile_Stats *stats, void *section_begin,
void *section_end)
{
float *ufp = (float *) section_begin;
double val;
if (stats->total == 0 && *ufp < -1.0e10 ) {
stats->offset = *ufp;
}
while (ufp < (float *) section_end) {
val = (double) (*ufp - stats->offset);
stats->mean += val;
stats->rms += val * val;
stats->min = MIN( stats->min, *ufp);
stats->max = MAX( stats->max, *ufp);
ufp++;
}
stats->total += (float *)section_end - (float *)section_begin;
return (stats->total);
}

33
ccp4c/ccp4/cmap_stats.h Normal file
View File

@@ -0,0 +1,33 @@
/*
cmap_stats.h: header file for cmap_stats.c
Copyright (C) 2001 CCLRC, Charles Ballard
This library is free software: you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public License
version 3, modified in accordance with the provisions of the
license to address the requirements of UK law.
You should have received a copy of the modified GNU Lesser General
Public License along with this library. If not, copies may be
downloaded from http://www.ccp4.ac.uk/ccp4license.php
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.
*/
#ifndef __GUARD_MAPLIB_STATS
#define __GUARD_MAPLIB_STATS
#ifdef __cplusplus
extern "C" {
#endif
int stats_update(CMMFile_Stats *stats, void *section_begin,
void *section_end);
#ifdef __cplusplus
}
#endif
#endif /* __GUARD_MAPLIB_STATS */

141
ccp4c/ccp4/cmap_symop.c Normal file
View File

@@ -0,0 +1,141 @@
/*
cmap_symop.c: set and fetch symmetry operations in map header
Copyright (C) 2001 CCLRC, Charles Ballard
This library is free software: you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public License
version 3, modified in accordance with the provisions of the
license to address the requirements of UK law.
You should have received a copy of the modified GNU Lesser General
Public License along with this library. If not, copies may be
downloaded from http://www.ccp4.ac.uk/ccp4license.php
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.
*/
#include <stdlib.h>
#include "cmaplib.h"
#include "cmap_errno.h"
/*! Return the number of symops (estimated as the size/80)
\param mfile (const CMMFile *)
\return number of symops */
int ccp4_cmap_num_symop(const CMMFile *mfile)
{
if (mfile == NULL)
return 0;
return (mfile->symop.number);
}
/*! navigate around the symops, seeking in 80 byte units
The result must lie within the symop strings in the file.
\param mfile (CMMFile *)
\param isymop (int) the number of the symop "string" of interest
\param whence (unsigned int) mode of seek
\return symop string number or EOF */
int ccp4_cmap_seek_symop(CMMFile *mfile, int isymop, unsigned int whence)
{
const int n_byt_symop = 80;
div_t symops;
int result = EOF;
if (ccp4_file_is_read(mfile->stream) == 0)
return EOF;
switch (whence) {
case SEEK_SET:
if (isymop < 0 || isymop > mfile->symop.number)
ccp4_signal( CCP4_ERRLEVEL(2) | CMAP_ERRNO(CMERR_ParamError),
"ccp4_cmap_seek_symop",
NULL);
else
result = ccp4_file_raw_seek(mfile->stream, mfile->symop.offset +
isymop*n_byt_symop, whence);
break;
case SEEK_END:
if (isymop > 0 || abs(isymop) > mfile->symop.number )
ccp4_signal( CCP4_ERRLEVEL(2) | CMAP_ERRNO(CMERR_ParamError),
"ccp4_cmap_seek_symop",
NULL);
else
result = ccp4_file_raw_seek(mfile->stream, mfile->symop.offset +
mfile->symop.size + isymop*n_byt_symop,
SEEK_SET);
break;
case SEEK_CUR:
symops = div(ccp4_file_tell(mfile->stream) - mfile->symop.offset,n_byt_symop);
if (symops.quot < 0 || symops.quot >= mfile->symop.number ||
symops.quot + isymop < 0 || symops.quot + isymop >= mfile->symop.number)
ccp4_signal( CCP4_ERRLEVEL(2) | CMAP_ERRNO(CMERR_ParamError),
"ccp4_cmap_seek_symop",
NULL);
else
result = ccp4_file_raw_seek(mfile->stream,(isymop > 0) ?
(n_byt_symop - symops.rem + n_byt_symop * (isymop-1)) :
(n_byt_symop * isymop -symops.rem), SEEK_CUR);
}
return (result == EOF) ? EOF : (result - mfile->symop.offset)/n_byt_symop;
}
/*! get a symop string of 80 characters
\param mfile (CMMFile *)
\param buffer (char *) array of bytes which will contain the symop string.
This must be at least 81 characters long (including space for null terminator).
\return 1 on success, 0 if no symops, EOF on failure */
int ccp4_cmap_get_symop(CMMFile *mfile, char *buffer)
{
const int n_byt_symop = 80;
off_t file_posn;
if ( mfile->symop.size == 0) {
ccp4_signal( CCP4_ERRLEVEL(2) | CMAP_ERRNO(CMERR_SymErr),
"cmap_get_symop",NULL);
return (0);}
file_posn = ccp4_file_tell(mfile->stream);
if (file_posn < mfile->symop.offset ||
file_posn > mfile->symop.offset + mfile->symop.size) {
ccp4_signal( CCP4_ERRLEVEL(2) | CMAP_ERRNO(CMERR_SymErr),
"cmap_get_symop",NULL);
return (EOF);}
if (ccp4_file_readchar(mfile->stream, (uint8 *) buffer, n_byt_symop) != n_byt_symop) {
ccp4_signal( CCP4_ERRLEVEL(3) | CMAP_ERRNO(CMERR_ReadFail),
"cmap_get_symop",NULL);
return (EOF);
}
buffer[n_byt_symop] = '\0';
return (1);
}
/*! write symops to file.
This wraps a raw write. It is up to the calling program to
ensure the positioning (effectively assume appends). Writing
is blocked if data has alread been written to the file. 80
bytes of continuous memory is written to the file.
\param mfile (CMMFile *)
\param symop (const char *) character array containing the
symop string (at least 80 characters in length
\return 1 on success, EOF on failure */
int ccp4_cmap_set_symop(CMMFile *mfile, const char *symop)
{
const int n_byt_symop = 80;
char buffer[80];
memset(buffer,' ',80U);
memcpy(buffer, symop, (strlen(symop) > n_byt_symop) ?
n_byt_symop : strlen(symop) );
if (ccp4_file_is_write(mfile->stream) && mfile->data.number == 0) {
if (ccp4_file_writechar(mfile->stream, (uint8 *) buffer, n_byt_symop) != n_byt_symop) {
ccp4_signal( CCP4_ERRLEVEL(3) | CMAP_ERRNO(CMERR_WriteFail),
"cmap_set_symop",NULL);
return (EOF);
}
mfile->symop.number++;
mfile->symop.size += n_byt_symop;
mfile->data.offset = mfile->symop.offset + mfile->symop.size;
}
return (1);
}

241
ccp4c/ccp4/cmaplib.h Normal file
View File

@@ -0,0 +1,241 @@
/*
cmaplib.h: C/C++ level API for accessing CCP4 map files
Copyright (C) 2001 CCLRC, Charles Ballard
This library is free software: you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public License
version 3, modified in accordance with the provisions of the
license to address the requirements of UK law.
You should have received a copy of the modified GNU Lesser General
Public License along with this library. If not, copies may be
downloaded from http://www.ccp4.ac.uk/ccp4license.php
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.
*/
/** @page cmap_page CMAP library
*
* @verbatim
<!-- ::INDEX_INFO::CMAP library::Library::::C/C++ Software Library for CCP4 map files:::::::: -->
@endverbatim
*
* @section cmap_file_list File list
<ul>
<li>cmaplib.h - contains details of the C/C++ API
<li>cmap_data.h
<li>cmap_header.h
<li>cmap_skew.h
<li>cmap_errno.h
<li>cmap_labels.h
<li>cmap_stats.h
</ul>
* @section cmap_overview Overview
Functions defining the C-level API for accessing CCP4 map files.
*/
/** @file cmaplib.h
*
* @brief ccp4 map i/o user-level library header file
*
* Functions defining the C-level API for accessing CCP4 map files.
*
* @author Charles Ballard
*/
#ifndef __GUARD_MAPLIB
#define __GUARD_MAPLIB
#include "ccp4_utils.h"
#ifdef __cplusplus
namespace CMap_io {
typedef CCP4::CCP4File CCP4File;
extern "C" {
#endif
typedef struct _CMMFile_Skew CMMFile_Skew;
typedef struct _CMMFile_Labels CMMFile_Labels;
typedef struct _CMMFile_Symop CMMFile_Symop;
typedef struct _CMMFile_Data CMMFile_Data;
typedef struct _CMMFile_Stats CMMFile_Stats;
typedef struct _CMMFile CMMFile;
struct _CMMFile_Labels {
unsigned int number;
char *labels[10];
};
struct _CMMFile_Skew {
float rotation[3][3];
float translation[3];
};
struct _CMMFile_Symop {
unsigned int offset;
unsigned int size;
unsigned int number;
};
struct _CMMFile_Data {
size_t offset;
size_t section_size;
size_t header_size;
size_t block_size;
unsigned int number;
};
struct _CMMFile_Stats {
float offset; /* pseudo zero value */
float min; /* minimum density value */
float max; /* maximum density value */
double mean; /* sum of densities (less offset) */
double rms; /* sum of square of densities (less offset) */
int total; /* number of summed densities */
};
struct _CMMFile {
CCP4File *stream;
char *file_name;
unsigned int data_mode;
unsigned int close_mode;
float cell[6];
int spacegroup;
int EM_spacegroup;
char EM_exthead_type[5];
char EM_contents[5];
int map_dim[3];
int origin[3];
int cell_grid[3];
int axes_order[3];
CMMFile_Symop symop;
CMMFile_Data data;
CMMFile_Stats stats;
CMMFile_Labels labels;
CMMFile_Skew skew;
int reserved[8];
char user_access[28];
};
/* open a file for read/write */
void *ccp4_cmap_open(const char *filename, int mode);
/* close a file for read/write (dumping the header if write) */
void ccp4_cmap_close(CMMFile *mfile);
/* set the close mode (calculation of map statistics) */
void ccp4_cmap_closemode(CMMFile *mfile, unsigned int closemode);
/* seek to a section in the map (read mode only)*/
int ccp4_cmap_seek_section(CMMFile *mfile, int offset, unsigned int seek_mode);
/* seek to a row in a section (read mode only)*/
int ccp4_cmap_seek_row(CMMFile *, int offset, unsigned int seek_mode);
/* raw seek (read mode only)*/
int ccp4_cmap_seek_data(CMMFile *, int offset, unsigned int seek_mode);
/* read a map section from file to memory */
int ccp4_cmap_read_section(CMMFile *mfile, void *section);
/* read a row from file to memory */
int ccp4_cmap_read_row(CMMFile *mfile, void *row);
/* read n_items from file to memory (item determined by data mode) */
int ccp4_cmap_read_data(const CMMFile *mfile, void *items, int n_items);
/* write a map section from memory to file */
int ccp4_cmap_write_section(CMMFile *mfile, const void *section);
/* write a map row from memory to file */
int ccp4_cmap_write_row(CMMFile *mfile, const void *row);
/* write n_items from memory to file (item determined by data mode) */
int ccp4_cmap_write_data(CMMFile *mfile, const void *items, int n_items);
/* read the section header corresponding to the current section */
int ccp4_cmap_read_section_header(const CMMFile *mfile, char *header);
/* write the section header corresponding to the current section */
int ccp4_cmap_write_section_header(CMMFile *mfile, const char *header);
/* get the header parameters */
void ccp4_cmap_get_cell(const CMMFile *mfile, float *cell);
void ccp4_cmap_get_grid(const CMMFile *mfile, int *grid);
void ccp4_cmap_get_origin(const CMMFile *mfile, int *origin);
void ccp4_cmap_get_order(const CMMFile *mfile, int *axes_order);
void ccp4_cmap_get_dim(const CMMFile *mfile, int *map_dim);
int ccp4_cmap_get_spacegroup(const CMMFile *mfile);
void ccp4_cmap_get_mapstats(const CMMFile *mfile, float *min, float* max,
double *mean, double *rms);
/* set the header parameters */
void ccp4_cmap_set_cell(CMMFile *mfile, const float *cell);
void ccp4_cmap_set_grid(CMMFile *mfile, const int *grid);
void ccp4_cmap_set_origin(CMMFile *mfile, const int *origin);
void ccp4_cmap_set_order(CMMFile *mfile, const int *axes_order);
void ccp4_cmap_set_dim(CMMFile *mfile, const int *map_dim);
void ccp4_cmap_set_spacegroup(CMMFile *mfile, int spacegroup);
void ccp4_cmap_set_mapstats(CMMFile *mfile, const float min, const float max,
const double mean, const double rms);
/* get map file datamode */
unsigned int ccp4_cmap_get_datamode(const CMMFile *mfile);
/* set map file datamode */
void ccp4_cmap_set_datamode(CMMFile *mfile, unsigned int datamode);
/* get the local header size */
size_t ccp4_cmap_get_local_header(CMMFile *mfile);
/* set the local header size (before data writing begins) */
void ccp4_cmap_set_local_header(CMMFile *mfile, size_t size);
/* get the number of symops in the file */
int ccp4_cmap_num_symop(const CMMFile *mfile);
/* seek among the symops strings */
int ccp4_cmap_seek_symop(CMMFile *mfile, int isymop, unsigned int whence);
/* read a symop string of 80 characters */
int ccp4_cmap_get_symop(CMMFile *mfile, char *buffer);
/* write a symop string of 80 characters */
int ccp4_cmap_set_symop(CMMFile *mfile, const char *buffer);
/* get the mask */
int ccp4_cmap_get_mask(const CMMFile *mfile, float *skew_mat, float *skew_trans);
/* set the mask */
int ccp4_cmap_set_mask(CMMFile *mfile, const float *skew_mat, const float *skew_trans);
/* the number of labels used */
int ccp4_cmap_number_label(const CMMFile *mfile);
/* set label at posn from C-string */
int ccp4_cmap_set_label(CMMFile *mfile, const char *label, int posn);
/* return label at posn as C-string */
char *ccp4_cmap_get_label(const CMMFile *mfile, int posn);
/* set title (label=0) */
int ccp4_cmap_set_title(CMMFile *mfile, const char *label);
/* get title (label=0) */
char *ccp4_cmap_get_title(const CMMFile *mfile);
#ifdef __cplusplus
}
}
#endif
#endif /* __GUARD_MAPLIB */

34
ccp4c/ccp4/cmaplib_f.h Normal file
View File

@@ -0,0 +1,34 @@
/*
cmaplib_f.h: header files for cmaplib_f.c
Copyright (C) 2001 CCLRC, Charles Ballard
This library is free software: you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public License
version 3, modified in accordance with the provisions of the
license to address the requirements of UK law.
You should have received a copy of the modified GNU Lesser General
Public License along with this library. If not, copies may be
downloaded from http://www.ccp4.ac.uk/ccp4license.php
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.
*/
#ifndef __GUARD_MAPLIB_FORTRAN
#define __GUARD_MAPLIB_FORTRAN
#include "cmaplib.h"
#define MAXMAP MAXFILES
typedef struct _IOConvMap IOConvMap;
struct _IOConvMap {
int ipc;
char *logname;
CMMFile *mapfile;
};
#endif /* __GUARD_MAPLIB_FORTRAN */

3964
ccp4c/ccp4/cmtzlib.c Normal file

File diff suppressed because it is too large Load Diff

1054
ccp4c/ccp4/cmtzlib.h Normal file

File diff suppressed because it is too large Load Diff

2086
ccp4c/ccp4/csymlib.c Normal file

File diff suppressed because it is too large Load Diff

645
ccp4c/ccp4/csymlib.h Normal file
View File

@@ -0,0 +1,645 @@
/*
csymlib.h: header file for csymlib.c
Copyright (C) 2001 CCLRC, Martyn Winn
This library is free software: you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public License
version 3, modified in accordance with the provisions of the
license to address the requirements of UK law.
You should have received a copy of the modified GNU Lesser General
Public License along with this library. If not, copies may be
downloaded from http://www.ccp4.ac.uk/ccp4license.php
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.
*/
/** @page csym_page CSYM library
*
* @verbatim
<!-- ::INDEX_INFO::CSYM library::Library::::C/C++ Software Library for symmetry information:::::::: -->
@endverbatim
*
* @section csym_file_list File list
<ul>
<li>csymlib.h - contains details of the C/C++ API
<li>ccp4_spg.h - contains details of the spacegroup data structure
</ul>
*
* @section csym_overview Overview
The CSYM library is centred around a data file <tt>syminfo.lib</tt> which is
auto-generated from sgtbx (the Space Group Toolbox of
<a href="http://cctbx.sourceforge.net/">cctbx</a>). A description of
the contents of this file is given in the <a href="../symlib.html">
documentation</a> of the Fortran API.
<p>A particular spacegroup in a particular setting
is loaded into an in-memory data structure by requesting a particular
spacegroup name, number, or set of operators. See the functions
<tt>ccp4spg_load_by_standard_num</tt>, <tt>ccp4spg_load_by_ccp4_num</tt>,
<tt>ccp4spg_load_by_spgname</tt>, <tt>ccp4spg_load_by_ccp4_spgname</tt>
and <tt>ccp4_spgrp_reverse_lookup</tt>. Information on the in-memory
data structure is given in ccp4_spg.h The memory can be freed by the
function <tt>ccp4spg_free</tt>.
<p>Functions are provided to:
<ul>
<li>Query the data structure, e.g. <tt>ccp4spg_symbol_Hall</tt>, etc. (members
of the structure can of course be obtained directly)
<li>Check reciprocal space indices for a particular spacegroup,
e.g. <tt>ccp4spg_is_in_asu</tt>, <tt>ccp4spg_is_centric</tt>,
<tt>ccp4spg_get_multiplicity</tt>, <tt>ccp4spg_is_sysabs</tt>, etc.
<li>Set appropriate grids for FFT, e.g. <tt>set_fft_grid</tt>
</ul>
*
* @section csym_operators Symmetry operators
Symmetry operators are expressed in a variety of ways:
<ul>
<li>Using the struct <tt>ccp4_symop</tt>, which consists of a 3 x 3 rotation
matrix and a translation vector.
<li>As a 4 x 4 matrix, in which the rotation matrix is in the top-left-hand
corner and the translation vector is in elements [*][3]. Element [3][3] is
set to 1.0
<li>As a string, such as "-x+1/2,-y,z+1/2"
</ul>
Check the function description for which form is expected. Often, there
are alternative functions if you wish to supply the operators in a
different form. There are also the following conversion functions:
<ul>
<li>rotandtrn_to_mat4
<li>rotandtrn_to_symop
<li>mat4_to_rotandtrn
<li>mat4_to_symop
<li>mat4_to_recip_symop
<li>symop_to_rotandtrn
<li>symop_to_mat4
</ul>
Note that the order of symmetry operators may be important in some cases, for
example in MTZ files with a M/ISYM column where ISYM encodes the symmetry operation
used.
* @section csym_examples Examples
See examples on <a href="ftp://ftp.ccp4.ac.uk/mdw/csym">ftp area</a>
*/
/** @file csymlib.h
*
* @brief C-level library for symmetry information.
*
* Functions defining the C-level API for accessing spacegroup properties.
* The primary spacegroup information comes from the data file syminfo.lib
*
* @author Martyn Winn
*/
#ifndef __CSymLib__
#define __CSymLib__
/* rcsidhs[] = "$Id$" */
/* note that definitions in ccp4_spg.h are within the CSym namespace */
#include "ccp4_spg.h"
#ifdef __cplusplus
namespace CSym {
extern "C" {
#endif
/** Look up spacegroup in standard setting by number, and load properties.
* Allocates memory for the spacegroup structure. This can be freed
* later by ccp4spg_free().
* @param numspg spacegroup number
* @return pointer to spacegroup
*/
CCP4SPG *ccp4spg_load_by_standard_num(const int numspg);
/** Look up spacegroup by CCP4 number, and load properties.
* Allocates memory for the spacegroup structure. This can be freed
* later by ccp4spg_free().
* @param ccp4numspg CCP4 spacegroup number
* @return pointer to spacegroup
*/
CCP4SPG *ccp4spg_load_by_ccp4_num(const int ccp4numspg);
/** Look up spacegroup by the extended Hermann Mauguin symbol.
* Allocates memory for the spacegroup structure. This can be freed
* later by ccp4spg_free().
* @param spgname Spacegroup name in form of extended Hermann Mauguin symbol.
* @return pointer to spacegroup
*/
CCP4SPG *ccp4spg_load_by_spgname(const char *spgname);
/** Look up spacegroup by name. This is for use by CCP4 programs
* and is more complicated than ccp4spg_load_by_spgname. For each
* spacegroup in syminfo.lib it checks the CCP4 spacegroup name
* first, and then the extended Hermann Mauguin symbol.
* Allocates memory for the spacegroup structure. This can be freed
* later by ccp4spg_free().
* @param ccp4spgname Spacegroup name.
* @return pointer to spacegroup
*/
CCP4SPG *ccp4spg_load_by_ccp4_spgname(const char *ccp4spgname);
/** Look up spacegroup by symmetry operators and load properties.
* Allocates memory for the spacegroup structure. This can be freed
* later by ccp4spg_free().
* @param nsym1 number of operators (including non-primitive)
* @param op1 pointer to array of operators
* @return pointer to spacegroup
*/
CCP4SPG * ccp4_spgrp_reverse_lookup(const int nsym1, const ccp4_symop *op1);
/** Look up spacegroup from SYMOP.
* This would not normally be called directly, but via one of
* the wrapping functions.
* Allocates memory for the spacegroup structure. This can be freed
* later by ccp4spg_free().
* @param numspg spacegroup number
* @param ccp4numspg CCP4 spacegroup number
* @param spgname Spacegroup name.
* @param ccp4spgname Spacegroup name.
* @param nsym1 number of operators (including non-primitive)
* @param op1 pointer to array of operators
* @return pointer to spacegroup
*/
CCP4SPG *ccp4spg_load_spacegroup(const int numspg, const int ccp4numspg,
const char *spgname, const char *ccp4spgname,
const int nsym1, const ccp4_symop *op1);
/** Free all memory malloc'd from static pointers.
* To be called before program exit. The function can be
* registered with atexit.
*/
void ccp4spg_mem_tidy(void);
/** Generate symop matrices from description strings
* This would not normally be called directly, but via one of
* the wrapping functions SYMFR2 and SYMFR3 in the Fortran API.
* @param line null-terminated string containing symop descriptions
* @param rot array of 4x4 matrices
* @return number of symops read, or -1 on failure
*/
int symfr_driver (const char *line, float rot[][4][4]);
/** Free memory associated with spacegroup.
* @param sp pointer to spacegroup
*/
void ccp4spg_free(CCP4SPG **sp);
/** Look up spacegroup in standard setting by number and load into
* static storage of csymlib_f.
* @param numspg spacegroup number
* @return void
*/
void ccp4spg_register_by_ccp4_num(int numspg);
/** Look up spacegroup by set of symmetry operators and load into
* static storage of csymlib_f.
* @param nops number of symops
* @param rsm symmetry operators
* @return void
*/
void ccp4spg_register_by_symops(int nops, float rsm[][4][4]);
/** Derive centering operators from Hall symbol (deprecated).
* Centering operators are now read from syminfo.lib
* @param symbol_Hall Hall symbol for spacegroup
* @param cent_ops centering operators
* @return number of centering operators (0 if none found)
*/
int ccp4_spg_get_centering(const char *symbol_Hall, float cent_ops[4][3]);
/** Load Laue data into spacegroup structure.
* @param nlaue CCP4 code for Laue group
* @param spacegroup Pointer to CCP4 spacegroup structure
* @return 0 on success, 1 on failure to load Laue data
*/
int ccp4spg_load_laue(CCP4SPG* spacegroup, const int nlaue);
/** Test if reflection is in asu of Laue group 1bar.
* @return 1 if in asu else 0
*/
int ASU_1b (const int h, const int k, const int l);
/** Test if reflection is in asu of Laue group 2/m.
* @return 1 if in asu else 0
*/
int ASU_2_m (const int h, const int k, const int l);
/** Test if reflection is in asu of Laue group mmm.
* @return 1 if in asu else 0
*/
int ASU_mmm (const int h, const int k, const int l);
/** Test if reflection is in asu of Laue group 4/m.
* @return 1 if in asu else 0
*/
int ASU_4_m (const int h, const int k, const int l);
/** Test if reflection is in asu of Laue group 4/mmm.
* @return 1 if in asu else 0
*/
int ASU_4_mmm(const int h, const int k, const int l);
/** Test if reflection is in asu of Laue group 3bar.
* @return 1 if in asu else 0
*/
int ASU_3b (const int h, const int k, const int l);
/** Test if reflection is in asu of Laue group 3bar1m.
* @return 1 if in asu else 0
*/
int ASU_3bm (const int h, const int k, const int l);
/** Test if reflection is in asu of Laue group 3barm.
* @return 1 if in asu else 0
*/
int ASU_3bmx (const int h, const int k, const int l);
/** Test if reflection is in asu of Laue group 6/m.
* @return 1 if in asu else 0
*/
int ASU_6_m (const int h, const int k, const int l);
/** Test if reflection is in asu of Laue group 6/mmm.
* @return 1 if in asu else 0
*/
int ASU_6_mmm(const int h, const int k, const int l);
/** Test if reflection is in asu of Laue group m3bar.
* @return 1 if in asu else 0
*/
int ASU_m3b (const int h, const int k, const int l);
/** Test if reflection is in asu of Laue group m3barm.
* @return 1 if in asu else 0
*/
int ASU_m3bm (const int h, const int k, const int l);
/** Function to return Hall symbol for spacegroup.
* @param sp pointer to spacegroup
* @return pointer to Hall symbol for spacegroup
*/
char *ccp4spg_symbol_Hall(CCP4SPG* sp);
/** inverts a symmetry operator. The input operator is
* converted to a 4 x 4 matrix, inverted, and converted back.
* @param ccp4_symop input symmetry operator
* @return inverted symmetry operator
*/
ccp4_symop ccp4_symop_invert( const ccp4_symop op1 );
/** Compare two spacegroup names. Strings are converted to upper
* case before making the comparison, but otherwise match must be
* exact.
* @param spgname1 First spacegroup name.
* @param spgname2 Second spacegroup name.
* @return 1 if they are equal else 0.
*/
int ccp4spg_name_equal(const char *spgname1, const char *spgname2);
/** Try to match a spacegroup name to one from SYMINFO. Blanks are
* removed when making the comparison. Strings are converted to upper
* case before making the comparison. If spgname_lib has " 1 " and
* spgname_match doesn't, then strip out " 1" to do "short" comparison.
* @param spgname1 First spacegroup name, assumed to be a standard one
* obtained at some point from SYMINFO
* @param spgname2 Second spacegroup name that you are trying to match
* to a standard SYMINFO one. E.g. it might have been provided by the
* user.
* @return 1 if they are equal else 0.
*/
int ccp4spg_name_equal_to_lib(const char *spgname_lib, const char *spgname_match);
/** Function to create "short" name of spacegroup. Blanks
* are removed, as are " 1" elements (except for the special case
* of "P 1").
* @param shortname String long enough to hold short name.
* @param longname Long version of spacegroup name.
* @return Pointer to shortname.
*/
char *ccp4spg_to_shortname(char *shortname, const char *longname);
/** Function to deal with colon-specified spacegroup settings.
* E.g. 'R 3 :H' is converted to 'H 3 '. Note that spaces are
* returned and should be dealt with by the calling function.
* @param name Spacegroup name.
* @return void
*/
void ccp4spg_name_de_colon(char *name);
/** Compare two point group names. Blanks are removed when
* making the comparison. Strings are converted to upper
* case before making the comparison. Any initial "PG" is ignored.
* @param pgname1 First point group name.
* @param pgname2 Second point group name.
* @return 1 if they are equal else 0.
*/
int ccp4spg_pgname_equal(const char *pgname1, const char *pgname2);
/** Function to normalise translations of a symmetry operator,
* i.e. to ensure 0.0 <= op.trn[i] < 1.0.
* @param op pointer to symmetry operator.
* @return Pointer to normalised symmetry operator.
*/
ccp4_symop *ccp4spg_norm_trans(ccp4_symop *op);
/** Sort and compare two symmetry operator lists.
* Kevin's code. The lists are coded as ints, which are then sorted and compared.
* Note that no changes are made to the input operators, so that operators
* differing by an integral number of unit cell translations are considered
* unequal. If this is not what you want, normalise the operators with
* ccp4spg_norm_trans first.
* @param nsym1 number of symmetry operators in first list
* @param op1 first list of symmetry operators
* @param nsym2 number of symmetry operators in second list
* @param op2 second list of symmetry operators
* @return 1 if they are equal else 0.
*/
int ccp4_spgrp_equal( int nsym1, const ccp4_symop *op1, int nsym2, const ccp4_symop *op2);
/** Compare two symmetry operator lists.
* Kevin's code. The lists are coded as ints, which are compared.
* Unlike ccp4_spgrp_equal, the lists are not sorted, so the same operators
* in a different order will be considered unequal.
* @param nsym1 number of symmetry operators in first list
* @param op1 first list of symmetry operators
* @param nsym2 number of symmetry operators in second list
* @param op2 second list of symmetry operators
* @return 1 if they are equal else 0.
*/
int ccp4_spgrp_equal_order( int nsym1, const ccp4_symop *op1, int nsym2, const ccp4_symop *op2);
/** Make an integer coding of a symmetry operator.
* The coding takes 30 bits: 18 for the rotation and 12 for the translation.
* @param op symmetry operator
* @return int code.
*/
int ccp4_symop_code(ccp4_symop op);
/** Comparison of symmetry operators encoded as integers.
* In ccp4_spgrp_equal, this is passed to the stdlib qsort.
* @param p1 pointer to first integer
* @param p1 pointer to second integer
* @return difference between integers
*/
int ccp4_int_compare( const void *p1, const void *p2 );
/** Test whether reflection or it's Friedel mate is in asu.
* @param sp pointer to spacegroup
* @param h reflection index
* @param k reflection index
* @param l reflection index
* @return 1 if in asu, -1 if -h -k -l is in asu, 0 otherwise
*/
int ccp4spg_is_in_pm_asu(const CCP4SPG* sp, const int h, const int k, const int l);
/** Test whether reflection is in asu.
* @param sp pointer to spacegroup
* @param h reflection index
* @param k reflection index
* @param l reflection index
* @return 1 if in asu, 0 otherwise
*/
int ccp4spg_is_in_asu(const CCP4SPG* sp, const int h, const int k, const int l);
/** Place reflection (hin,kin,lin) in the asymmetric unit of spacegroup "sp".
* Resultant indices are placed in (hout,kout,lout).
* @param sp pointer to spacegroup
* @param hin input reflection index
* @param kin input reflection index
* @param lin input reflection index
* @param hout output reflection index
* @param kout output reflection index
* @param lout output reflection index
* @return "isym" if successful, 0 otherwise. "isym" = 2*isymop - 1 for
* reflections placed in the positive asu, i.e. I+ of a Friedel pair, and
* "isym" = 2*isymop for reflections placed in the negative asu, i.e. I- of
* a Friedel pair. Here "isymop" is the number of the symmetry operator used.
*/
int ccp4spg_put_in_asu(const CCP4SPG* sp, const int hin, const int kin, const int lin,
int *hout, int *kout, int *lout );
/** Transform reflection (hin,kin,lin) according to spacegroup "sp" and
* operation "isym". Resultant indices are placed in (hout,kout,lout).
* @param sp pointer to spacegroup
* @param isym required operation, see ccp4spg_put_in_asu
* @param hin input reflection index
* @param kin input reflection index
* @param lin input reflection index
* @param hout output reflection index
* @param kout output reflection index
* @param lout output reflection index
* @return void
*/
void ccp4spg_generate_indices(const CCP4SPG* sp, const int isym,
const int hin, const int kin, const int lin,
int *hout, int *kout, int *lout );
/** Shift phase value associated with hin,kin,lin according to translation
and optional sign change. Return in range 0,360.
* @param hin reflection index
* @param kin reflection index
* @param lin reflection index
* @param phasin Input phase.
* @param trans Requested translation
* @param isign If -1, change sign of phase
* @return shifted phase
*/
float ccp4spg_phase_shift(const int hin, const int kin, const int lin,
const float phasin, const float trans[3], const int isign);
/** Check whether change of basis is necessary, i.e. whether the
* change of basis matrix is not the identity.
* @param chb change of basis matrix
* @return 1 if change of basis is necessary, 0 otherwise
*/
int ccp4spg_do_chb(const float chb[3][3]);
/** Set up centric zones for a given spacegroup. This is called
* upon loading a spacegroup.
* @param sp pointer to spacegroup
* @return void
*/
void ccp4spg_set_centric_zones(CCP4SPG* sp);
/** Function to determine whether or not h,k,l is a centric reflection
* in spacegroup "sp".
* @param sp pointer to spacegroup
* @param h input reflection index
* @param k input reflection index
* @param l input reflection index
* @return 1 if h,k,l is centric, 0 if not centric, and -1 if there is
* an error.
*/
int ccp4spg_is_centric(const CCP4SPG* sp, const int h, const int k, const int l);
/** Check indices against a centric zone for a given spacegroup.
* @param nzone index of centric zone
* @param h reflection index
* @param k reflection index
* @param l reflection index
* @return 0 if in zone "nzone", non-zero otherwise
*/
int ccp4spg_check_centric_zone(const int nzone, const int h, const int k, const int l);
/** Return phase of a centric reflection in the range 0.0 <= phase < 180.0.
* You should first check that reflection really is centric.
* @param sp pointer to spacegroup
* @param h reflection index
* @param k reflection index
* @param l reflection index
* @return phase of a centric reflection
*/
float ccp4spg_centric_phase(const CCP4SPG* sp, const int h, const int k, const int l);
/** Print a summary of the centric zones of a spacegroup.
* @param sp pointer to spacegroup
* @return void
*/
void ccp4spg_print_centric_zones(const CCP4SPG* sp);
/** Obtain string description of centric zone.
* @param nzone index of centric zone
* @param centric_zone string description of centric zone
* @return string description of centric zone
*/
char *ccp4spg_describe_centric_zone(const int nzone, char *centric_zone);
/** Set up epsilon zones for a given spacegroup. This is called
* upon loading a spacegroup.
* @param sp pointer to spacegroup
* @return void
*/
void ccp4spg_set_epsilon_zones(CCP4SPG* sp);
/** Return reflection multiplicity factor for a given hkl in a given
* spacegroup.
* @param sp pointer to spacegroup
* @param h reflection index
* @param k reflection index
* @param l reflection index
* @return reflection multiplicity factor
*/
int ccp4spg_get_multiplicity(const CCP4SPG* sp, const int h, const int k, const int l);
/** Check indices against an epsilon zone for a given spacegroup.
* @param nzone index of epsilon zone (runs from 1 to 13)
* @param h reflection index
* @param k reflection index
* @param l reflection index
* @return 0 if in zone "nzone", non-zero otherwise
*/
int ccp4spg_check_epsilon_zone(const int nzone, const int h, const int k, const int l);
/** Print a summary of the epsilon zones of a spacegroup.
* @param sp pointer to spacegroup
* @return void
*/
void ccp4spg_print_epsilon_zones(const CCP4SPG* sp);
/** Obtain string description of epsilon zone.
* @param nzone index of epsilon zone
* @param epsilon_zone string description of epsilon zone
* @return string description of epsilon zone
*/
char *ccp4spg_describe_epsilon_zone(const int nzone, char *epsilon_zone);
/** Check if reflection is a systematic absence.
* @param sp pointer to spacegroup
* @param h reflection index
* @param k reflection index
* @param l reflection index
* @return 1 if reflection is a systematic absence, 0 otherwise.
*/
int ccp4spg_is_sysabs(const CCP4SPG* sp, const int h, const int k, const int l);
/** Translated from Alexei Vagin's CALC_ORIG_PS.
* @param namspg Spacegroup name for printing only.
* @param nsym Input number of symmetry operators.
* @param rsym Input symmetry operators.
* @param origins Array containing alternative origins on output.
* @param polarx Return whether polar along x axis.
* @param polary Return whether polar along y axis.
* @param polarz Return whether polar along z axis.
* @param iprint If true, print out list of alternative origins.
* @return Number of alternate origins for spacegroup.
*/
int ccp4spg_generate_origins(const char *namspg, const int nsym, const float rsym[][4][4],
float origins[][3], int *polarx, int *polary, int *polarz,
const int iprint);
/** Print details on reciprocal spacegroup.
* @param sp pointer to spacegroup
* @return void
*/
void ccp4spg_print_recip_spgrp(const CCP4SPG* sp);
/** Print reciprocal symops.
* @param sp pointer to spacegroup
* @return void
*/
void ccp4spg_print_recip_ops(const CCP4SPG* sp);
/** Convert string of type 0<=y<=1/4 to 0.0-delta, 0.25+delta, where
* delta is set to 0.00001 Makes many assumptions about string.
* @param range input string.
* @param limits output range limits.
* @return 0 on success
*/
int range_to_limits(const char *range, float limits[2]);
/** Sets an FFT grid for a spacegroup.
* @param sp pointer to spacegroup
* @param nxmin minimum sampling on x
* @param nymin minimum sampling on y
* @param nzmin minimum sampling on z
* @param sample default fineness of sample
* @param nx returns sampling intervals along x
* @param ny returns sampling intervals along y
* @param nz returns sampling intervals along z
* @return void
*/
void set_fft_grid(CCP4SPG* sp, const int nxmin, const int nymin, const int nzmin,
const float sample, int *nx, int *ny, int *nz);
/** Checks whether all factors of a number n are less than or
* equal to 19.
* @param n Number to be tested.
* @return 1 on success, O on failure.
*/
int all_factors_le_19(const int n);
/** Sets a grid sample greater than minsmp, which has no prime
* factors greater than 19, and contains the factor nmul.
* @param minsmp
* @param nmul
* @param sample
* @return Grid sample or -1 on failure.
*/
int get_grid_sample(const int minsmp, const int nmul, const float sample);
/** Check for consistency between cell dimensions and spacegroup. Latter
* is identified from symmetry operators.
* @param nsym No. of symmetry operators.
* @param rsym Symmetry operators.
* @param cell Cell dimensions.
* @return 1 if they are consistent, 0 if there is a problem.
*/
int ccp4spg_check_symm_cell(int nsym, float rsym[][4][4], float cell[6]);
#ifdef __cplusplus
} }
#endif
#endif

162
ccp4c/ccp4/cvecmat.c Normal file
View File

@@ -0,0 +1,162 @@
/*
cvecmat.c: C library for vector and matrix manipulations
Copyright (C) 2001 CCLRC, Martyn Winn
This library is free software: you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public License
version 3, modified in accordance with the provisions of the
license to address the requirements of UK law.
You should have received a copy of the modified GNU Lesser General
Public License along with this library. If not, copies may be
downloaded from http://www.ccp4.ac.uk/ccp4license.php
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.
*/
/** @file cvecmat.c
* C library for vector and matrix manipulations.
* Martyn Winn
*/
#include <math.h>
#include "cvecmat.h"
/* rcsid[] = "$Id$" */
/* c = a X b */
void ccp4_dcross(const double a[3], const double b[3], double c[3])
{
c[0] = a[1]*b[2] - b[1]*a[2];
c[1] = a[2]*b[0] - b[2]*a[0];
c[2] = a[0]*b[1] - b[0]*a[1];
}
void ccp4_3matmul(double c[3][3], const double a[3][3], const double b[3][3])
{
int i,j,k;
for ( i = 0; i < 3; i++ )
for ( j = 0; j < 3; j++ ) {
c[i][j] = 0.0;
for ( k = 0; k < 3; k++ )
c[i][j] += a[i][k]*b[k][j];
}
}
void ccp4_4matmul( float c[4][4], const float a[4][4], const float b[4][4])
{
int i,j,k;
for ( i = 0; i < 4; i++ )
for ( j = 0; j < 4; j++ ) {
c[i][j] = 0.0;
for ( k = 0; k < 4; k++ )
c[i][j] += a[i][k]*b[k][j];
}
}
/* A (I) 3*3 matrix to be inverted */
/* AI (O) inverse matrix */
/* returns determinant */
double invert3matrix(const double a[3][3], double ai[3][3])
{ int i,j;
double c[3][3],d;
ccp4_dcross(a[1],a[2],c[0]);
ccp4_dcross(a[2],a[0],c[1]);
ccp4_dcross(a[0],a[1],c[2]);
d = a[0][0]*c[0][0] + a[0][1]*c[0][1] + a[0][2]*c[0][2];
if (fabs(d) > 1.0e-30) {
for ( i = 0; i < 3; i++ )
for ( j = 0; j < 3; j++ )
ai[i][j] = c[j][i] / d;
} else {
return 0.0;
}
return d;
}
/* A (I) 4*4 matrix to be inverted */
/* AI (O) inverse matrix */
/* returns determinant */
float invert4matrix(const float a[4][4], float ai[4][4])
{
double c[4][4], d;
int i, j;
double x[3][3];
int i1, j1, i2 ;
double am, q;
int ii, jj;
/* Function Body */
for (ii = 0; ii < 4; ++ii) {
for (jj = 0; jj < 4; ++jj) {
ai[ii][jj] = 0.0;
i = -1;
for (i1 = 0; i1 < 4; ++i1) {
if (i1 != ii) {
++i;
j = -1;
for (j1 = 0; j1 < 4; ++j1) {
if (j1 != jj) {
++j;
x[i][j] = a[i1][j1];
}
}
}
}
am = x[0][0]*x[1][1]*x[2][2] - x[0][0]*x[1][2]*x[2][1] +
x[0][1]*x[1][2]*x[2][0] - x[0][1]*x[1][0]*x[2][2] +
x[0][2]*x[1][0]*x[2][1] - x[0][2]*x[1][1]*x[2][0];
i2 = ii + jj;
c[ii][jj] = ccp4_pow_ii(-1.0, i2) * am;
}
}
/* ---- Calculate determinant */
d = 0.0;
for (i = 0; i < 4; ++i) {
d = a[i][0] * c[i][0] + d;
}
/* ---- Get inverse matrix */
if (fabs(d) > 1.0e-30) {
q = 1.0/d;
for (i = 0; i < 4; ++i) {
for (j = 0; j < 4; ++j) {
ai[i][j] = (float) (c[j][i] * q);
}
}
} else {
return 0.0;
}
return ((float) d);
}
float ccp4_pow_ii(const float base, const int power) {
int i = 0;
float pow = 1;
while (++i <= power)
pow *= base;
return pow;
}

39
ccp4c/ccp4/cvecmat.h Normal file
View File

@@ -0,0 +1,39 @@
/*
cvecmat.h: header file for cvecmat.c
Copyright (C) 2001 CCLRC, Martyn Winn
This library is free software: you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public License
version 3, modified in accordance with the provisions of the
license to address the requirements of UK law.
You should have received a copy of the modified GNU Lesser General
Public License along with this library. If not, copies may be
downloaded from http://www.ccp4.ac.uk/ccp4license.php
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.
*/
#ifndef __CCP4_VECMAT
#define __CCP4_VECMAT
#ifdef __cplusplus
extern "C" {
#endif
/* rcsidhv[] = "$Id$" */
void ccp4_dcross(const double a[3], const double b[3], double c[3]);
void ccp4_3matmul(double c[3][3], const double a[3][3], const double b[3][3]);
void ccp4_4matmul( float c[4][4], const float a[4][4], const float b[4][4]);
double invert3matrix(const double a[3][3], double ai[3][3]);
float invert4matrix(const float a[4][4], float ai[4][4]);
float ccp4_pow_ii(const float base, const int power);
#ifdef __cplusplus
}
#endif
#endif /*!CCP4_VECMAT */

324
ccp4c/ccp4/library_err.c Normal file
View File

@@ -0,0 +1,324 @@
/*
library_err.c: Error handling library
Copyright (C) 2001 CCLRC, Charles Ballard
This library is free software: you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public License
version 3, modified in accordance with the provisions of the
license to address the requirements of UK law.
You should have received a copy of the modified GNU Lesser General
Public License along with this library. If not, copies may be
downloaded from http://www.ccp4.ac.uk/ccp4license.php
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.
*/
/** @file library_err.c
* Error handling library.
* Charles Ballard
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "ccp4_errno.h"
/* rcsid[] = "$Id$" */
/** @global ccp4_errno: global to store data
*/
int ccp4_errno = 0;
/* error_levels: error level descriptions */
static const char * const error_levels[] =
{
"Success", /* 0 */
"Informational", /* 1 */
"Warning", /* 2 */
"Error", /* 3 */
"FATAL ERROR" /* 4 */
};
/* file io errors */
static const char *const cfile_errlist[] =
{
"Error 0", /* 0 = CIO_Ok */
"Bad mode", /* 1 = CIO_BadMode */
"Cannot open file", /* 2 = CIO_CantOpenFile */
"Too many open files", /* 3 = CIO_MaxFile */
"Read failed", /* 4 = CIO_ReadFail */
"Write failed", /* 5 = CIO_WriteFail */
"Close fail", /* 6 = CIO_CloseFail */
"Seek fail", /* 7 = CIO_SeekFail */
"Null pointer passed", /* 8 = CIO_NullPtr */
"End of File", /* 9 = CIO_EOF */
"No file" /* 10 = CIO_NoFile */
"File not open", /* 11 = CIO_NotOpen */
"Unlink failed" /* 12 = CIO_UnlinkFail */
};
/* map library errors */
static const char *const cmap_errlist[] =
{
"Error 0", /* 0 = CMERR_Ok */
"Unassigned unit", /* 1 = CMERR_NoChannel */
"Unassigned unit or disposed file", /* 2 = CMERR_NoFile */
"Logical name does not exist", /* 3 = CMERR_NoLogicalName */
"Cannot open file", /* 4 = CMERR_CantOpenFile */
"No associated header", /* 5 = CMERR_NoHeader */
"Read failed", /* 6 = CMERR_ReadFail */
"Write failed", /* 7 = CMERR_WriteFail */
"Parameter or dimension is incorrect ", /* 8 = CMERR_ParamError */
"Unrecognised keyword", /* 9 = CMERR_UnrecognK */
"File stamp error", /* 10 = CMERR_FileStamp */
"Symmetry", /* 11 = CMERR_SymErr */
"Cannot allocate memory", /* 12 = CMERR_AllocFail */
"Too many open files", /* 13 = CMERR_MaxFile */
};
/* mtz library errrors */
static const char *const cmtz_errlist[] =
{
"Error 0", /* 0 = CMTZERR_Ok */
"Unassigned unit", /* 1 = CMTZERR_NoChannel */
"Null file handle, file not opened", /* 2 = CMTZERR_NoFile */
"Logical name does not exist", /* 3 = CMTZERR_NoLogicalName */
"Cannot open file", /* 4 = CMTZERR_CantOpenFile */
"No associated header", /* 5 = CMTZERR_NoHeader */
"Read failed", /* 6 = CMTZERR_ReadFail */
"Write failed", /* 7 = CMTZERR_WriteFail */
"Function parameter is incorrect", /* 8 = CMTZERR_ParamError */
"Invalid cell dimensions", /* 9 = CMTZERR_Cellerr */
"File stamp error", /* 10 = CMTZERR_FileStamp */
"Symmetry", /* 11 = CMTZERR_SymErr */
"Cannot allocate memory", /* 12 = CMTZERR_AllocFail */
"Too many open files", /* 13 = CMTZERR_MaxFile */
"Failed to initialise parser", /* 14 = CMTZERR_ParserFail */
"File not identified as MTZ", /* 15 = CMTZERR_NotMTZ */
"Missing or incomplete dataset information in input file.", /* 16 = CMTZERR_DatasetIncomplete */
"No architecture information in file.", /* 17 = CMTZERR_NoArch */
"Attempt to access unallocated dataset", /* 18 = CMTZERR_NullDataset */
"Input MTZ file has incorrect major version for current library", /* 19 = CMTZERR_BadVersion */
"MTZ header is corrupted: missing tokens in SYMINF record", /* 20 = CMTZERR_SYMINFIncomplete */
"MTZ header is corrupted: missing tokens in COLUMN record", /* 21 = CMTZERR_COLUMNIncomplete */
"Batch headers corrupted", /* 22 = CMTZERR_BadBatchHeader */
"Input MTZ file has different minor version to that supported by current library", /* 23 = CMTZERR_DifferentVersion */
"File column type different from type expected by program", /* 24 = CMTZERR_ColTypeMismatch */
"MTZ header: error in column group specification", /* 25 = CMTZERR_ColGroupError */
"MTZ header: error in column source specification", /* 26 = CMTZERR_ColSourceError */
};
/* parser library errors */
static const char *const cpars_errlist[] =
{
"Error 0", /* 0 = CPARSERR_Ok */
"Maximum number of tokens exceeded", /* 1 = CPARSERR_MaxTokExceeded */
"Cannot allocate memory", /* 2 = CPARSERR_AllocFail */
"Null pointer", /* 3 = CPARSERR_NullPointer */
"Line is longer than allocated length, so truncated", /* 4 = CPARSERR_LongLine */
"Failed to open external command file", /* 5 = CPARSERR_CantOpenFile */
"Failed to get name for external file", /* 6 = CPARSERR_NoName */
"Overflow - exponent is too big to be evaluated", /* 7 = CPARSERR_ExpOverflow */
"Underflow - exponent is too small to be evaluated", /* 8 = CPARSERR_ExpUnderflow */
"Problem in mat4_to_symop", /* 9 = CPARSERR_MatToSymop */
"Failed to interpret symop string", /* 10 = CPARSERR_SymopToMat */
};
/* symmetry library errors */
static const char *const csym_errlist[] =
{
"Error 0", /* 0 = CSYMERR_Ok */
"Failed to initialise parser", /* 1 = CSYMERR_ParserFail */
"Cannot find SYMINFO file - no symmetry information", /* 2 = CSYMERR_NoSyminfoFile */
"Pointer to spacegroup structure is NULL", /* 3 = CSYMERR_NullSpacegroup */
"ASU definition not found for this spacegroup", /* 4 = CSYMERR_NoAsuDefined */
"Undefined Laue code for this spacegroup", /* 5 = CSYMERR_NoLaueCodeDefined */
"Not enough tokens on SYMINFO line", /* 6 = CSYMERR_SyminfoTokensMissing */
};
static const char *const cgen_errlist[] =
{
"Error 0", /* 0 = CGENERR_Ok */
"Cannot allocate memory", /* 1 = CGENERR_AllocFail */
"Cannot set environment variable", /* 2 = CGENERR_CantSetEnvironment */
"Maximum number of logical names exceeded", /* 3 = CGENERR_MaxNamesExceeded */
"Use: -e filename", /* 4 = CGENERR_EOptionUseError */
"Use: -d filename", /* 5 = CGENERR_DOptionUseError */
"Use: <logical name> <file name>", /* 6 = CGENERR_LogicalNameUseError */
"Cannot open environ.def", /* 7 = CGENERR_CantOpenEnvFile */
"Cannot open default.def", /* 8 = CGENERR_CantOpenDefFile */
"Cannot parse environ.def file", /* 9 = CGENERR_ParseEnvFail */
"Cannot parse default.def file", /* 10= CGENERR_ParseDefFail */
"Cannot find input file", /* 11= CGENERR_CantFindInFile */
"Failed to set path for environ.def file", /* 12= CGENERR_EnvPathFail */
"Failed to set path for default.def file", /* 13= CGENERR_DefPathFail */
"Cannot get CLIBD from environment", /* 14= CGENERR_CantGetClibd */
"Cannot get CCP4_SCR from environment", /* 15= CGENERR_CantGetCcp4Scr */
};
struct error_system {
char system[32];
int system_nerr;
const char * const *error_list;
};
/* construct error list */
static const struct error_system ccp4_errlist[] = {
{"system", 0, 0, },
{"library_file", CCP4_COUNT(cfile_errlist), cfile_errlist,},
{"mmdb", 0, 0,},
{"mtz", CCP4_COUNT(cmtz_errlist), cmtz_errlist,},
{"ccp4_map", CCP4_COUNT(cmap_errlist), cmap_errlist,},
{"utils", 0, 0},
{"ccp4_parser", CCP4_COUNT(cpars_errlist), cpars_errlist,},
{"csym", CCP4_COUNT(csym_errlist), csym_errlist,},
{"ccp4_general", CCP4_COUNT(cgen_errlist), cgen_errlist,}
};
static const int ccp4_system_nerr = CCP4_COUNT(ccp4_errlist);
/* Obtain character string based upon error code.
Typical use ccp4_strerror(ccp4_errno)
The returned string is statically allocated in the
library_err.c file and should not be freed.
param error code (int)
returns const pointer to error message.
*/
const char *ccp4_strerror(int error)
{
int system = CCP4_ERRGETSYS(error);
/* int level = CCP4_ERRGETLEVEL(error); */
int code = CCP4_ERRGETCODE(error);
if (error == -1 || system == 0)
return strerror(errno);
if (system >= ccp4_system_nerr)
return ("bad system error");
if (code >= ccp4_errlist[system].system_nerr)
return ("bad error code");
return (ccp4_errlist[system].error_list[code]);
}
/* Print out passed message and internal message based upon
ccp4_errno
"message : error message "
param message (const char *)
return void
*/
void ccp4_error (const char *msg)
{
const char *colon;
if (msg == 0 || *msg == '\0')
colon = "";
else
colon = ": ";
fprintf (stderr, "%s%s%s\n",
msg, colon, ccp4_strerror(ccp4_errno));
if(ccp4_errno != -1 && CCP4_ERRGETSYS(ccp4_errno)) {
fprintf (stderr, "System: %s\nLevel: %d\n",
ccp4_errlist[CCP4_ERRGETSYS(ccp4_errno)].system,
CCP4_ERRGETLEVEL(ccp4_errno));
if (errno)
fprintf (stderr, "%s%s\n",
"Last system message: ",strerror(errno)); }
}
/* Wrapper for ccp4_error which also calls exit(1)
param message (const char *)
*/
void ccp4_fatal (const char *message)
{
ccp4_error(message);
exit(1);
}
int CFile_Perror(const char *msg)
{
const char * colon;
int error = CCP4_ERRGETCODE(ccp4_errno);
int cfile_nerr = ccp4_errlist[4].system_nerr;
if (msg == NULL || msg == '\0') colon = "";
else colon = ": ";
if (error > 0 && error <= cfile_nerr) {
fprintf(stderr,"%s%s%s \n",
msg,colon,cfile_errlist[error]);
return error; }
fprintf(stderr,"Unknown error code");
return -1;
}
int ccp4_liberr_verbosity(int iverb) {
static int verbosity_level=1;
if (iverb >= 0)
verbosity_level = iverb;
return verbosity_level;
}
/* Routine to set ccp4_errno and print out message for
error tracing. This should be the only way in
which ccp4_errno is set.
See error codes above for levels and systems.
A callback with prototype void function(void)
may also be passed to the routine.
Note: FATAL calls exit(1).
param error code (int)
param message (const char * const)
param callback (point to routine)
*/
void ccp4_signal(const int code, const char * const msg,
void (*callback) ())
{
int severity = CCP4_ERRGETLEVEL(code),
system = CCP4_ERRGETSYS(code),
msg_no = CCP4_ERRGETCODE(code),
fatal_err = (severity == 4);
static const char msg_fmt[] = ">>>>>> CCP4 library signal %s:%s (%s)\n\t raised in %s <<<<<<\n";
static const char sys_fmt[] = ">>>>>> System signal %d:%s (%s)\n\t raised in %s <<<<<<\n";
ccp4_errno = code;
/* use this function to control whether error messages are printed */
if (!ccp4_liberr_verbosity(-1)) return;
if (system == 0) {
if (msg)
printf(sys_fmt,
errno,
strerror(errno),
error_levels[severity],
msg);
else
printf(">>>>>> System signal %d:%s (%s) <<<<<<",
errno,
strerror(errno),
error_levels[severity]);
ccp4_errno = errno; }
else
if (msg)
printf(msg_fmt,
ccp4_errlist[system].system,
ccp4_errlist[system].error_list[msg_no],
error_levels[severity],
msg);
else
printf(">>>>>> CCP4 library signal %s:%s (%s) <<<<<<\n",
ccp4_errlist[system].system,
ccp4_errlist[system].error_list[msg_no],
error_levels[severity]);
if (callback)
(*callback)();
if (fatal_err) exit(1);
}

2375
ccp4c/ccp4/library_file.c Normal file

File diff suppressed because it is too large Load Diff

167
ccp4c/ccp4/library_file.h Normal file
View File

@@ -0,0 +1,167 @@
/*
library_file.h: header file for library_file.c
Copyright (C) 2001 CCLRC, Charles Ballard
This library is free software: you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public License
version 3, modified in accordance with the provisions of the
license to address the requirements of UK law.
You should have received a copy of the modified GNU Lesser General
Public License along with this library. If not, copies may be
downloaded from http://www.ccp4.ac.uk/ccp4license.php
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.
*/
/** @file library_file.h
* Functions for file i/o.
* Charles Ballard
*/
#ifndef __CCP4_LIB_FILE
#define __CCP4_LIB_FILE
#include "ccp4_sysdep.h"
#include "ccp4_types.h"
#ifdef __cplusplus
namespace CCP4 {
extern "C" {
#endif
/** Generic CCP4 file. */
typedef struct _CFileStruct CCP4File;
struct _CFileStruct {
char *name;
FILE *stream;
int fd;
unsigned int read : 1;
unsigned int write : 1;
unsigned int append : 1;
unsigned int binary : 1;
unsigned int scratch : 1 , : 3;
unsigned int buffered : 1;
unsigned int sync : 1, : 6;
unsigned int direct : 1, : 7;
unsigned int open : 1;
unsigned int own : 1;
unsigned int last_op : 2;
unsigned int getbuff : 1, : 4;
int iostat;
unsigned int mode : 8;
unsigned int itemsize : 8;
unsigned int iconvert : 8;
unsigned int fconvert: 8;
off_t length;
off_t loc;
size_t stamp_loc;
int (*_read) (CCP4File *, uint8 *, size_t);
int (*_write) (CCP4File *, const uint8 *, size_t);
char buff[8];
void *priv;
};
CCP4File *ccp4_file_open (const char *, const int);
CCP4File *ccp4_file_open_file (const FILE *, const int);
CCP4File *ccp4_file_open_fd (const int, const int);
int ccp4_file_rarch ( CCP4File*);
int ccp4_file_warch ( CCP4File*);
int ccp4_file_close ( CCP4File*);
int ccp4_file_mode ( const CCP4File*);
int ccp4_file_setmode ( CCP4File*, const int);
int ccp4_file_setstamp( CCP4File *, const size_t);
int ccp4_file_itemsize( const CCP4File*);
int ccp4_file_setbyte( CCP4File *, const int);
int ccp4_file_byteorder( CCP4File *);
int ccp4_file_is_write(const CCP4File *);
int ccp4_file_is_read(const CCP4File *);
int ccp4_file_is_append(const CCP4File *);
int ccp4_file_is_scratch(const CCP4File *);
int ccp4_file_is_buffered(const CCP4File *);
int ccp4_file_status(const CCP4File *);
char *ccp4_file_name( CCP4File *);
int ccp4_file_read ( CCP4File*, uint8 *, size_t);
int ccp4_file_readcomp ( CCP4File*, uint8 *, size_t);
int ccp4_file_readshortcomp ( CCP4File*, uint8 *, size_t);
int ccp4_file_readfloat ( CCP4File*, uint8 *, size_t);
int ccp4_file_readint64 ( CCP4File*, uint8 *, size_t);
int ccp4_file_readint ( CCP4File*, uint8 *, size_t);
int ccp4_file_readshort ( CCP4File*, uint8 *, size_t);
int ccp4_file_readchar ( CCP4File*, uint8 *, size_t);
int ccp4_file_write ( CCP4File*, const uint8 *, size_t);
int ccp4_file_writecomp ( CCP4File*, const uint8 *, size_t);
int ccp4_file_writeshortcomp ( CCP4File*, const uint8 *, size_t);
int ccp4_file_writefloat ( CCP4File*, const uint8 *, size_t);
int ccp4_file_writeint ( CCP4File*, const uint8 *, size_t);
int ccp4_file_writeint64 ( CCP4File*, const uint8 *, size_t);
int ccp4_file_writeshort ( CCP4File*, const uint8 *, size_t);
int ccp4_file_writechar ( CCP4File*, const uint8 *, size_t);
int ccp4_file_seek ( CCP4File*, long, int);
void ccp4_file_rewind ( CCP4File*);
void ccp4_file_flush (CCP4File *);
long ccp4_file_length ( CCP4File*);
long ccp4_file_tell ( CCP4File*);
int ccp4_file_feof(CCP4File *);
void ccp4_file_clearerr(CCP4File *);
void ccp4_file_fatal (CCP4File *, char *);
char *ccp4_file_print(CCP4File *, char *, char *);
int ccp4_file_raw_seek( CCP4File *, long, int);
int ccp4_file_raw_read ( CCP4File*, char *, size_t);
int ccp4_file_raw_write ( CCP4File*, const char *, size_t);
int ccp4_file_raw_setstamp( CCP4File *, const size_t);
#ifdef __cplusplus
}
}
#endif
#endif /* __CCP4_LIB_FILE */

674
ccp4c/ccp4/library_utils.c Normal file
View File

@@ -0,0 +1,674 @@
/*
library_utils.c: CCP4 Library Utilities
Copyright (C) 2001 CCLRC, Charles Ballard
This library is free software: you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public License
version 3, modified in accordance with the provisions of the
license to address the requirements of UK law.
You should have received a copy of the modified GNU Lesser General
Public License along with this library. If not, copies may be
downloaded from http://www.ccp4.ac.uk/ccp4license.php
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.
*/
/** @page utilities_page CCP4 Library Utilities
*
* @section utilities_list File list
<ul>
<li>library_utils.c
<li>ccp4_general.c
<li>ccp4_parser.c
<li>ccp4_program.c
</ul>
* @section utilities_overview Overview
The CCP4 C-library provides many utility functions which either give
specific CCP4 functionality (e.g. traditional keyword parsing) or
are just generally useful (platform independent date).
*/
/** @file library_utils.c
* @brief Utility functions.
* @author Charles Ballard
*/
#include "ccp4_sysdep.h"
#include <time.h>
#include <math.h>
#include "ccp4_utils.h"
#include "ccp4_errno.h"
#if defined (_WIN32)
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#endif
#define CCP4_ERRNO(y) (CCP4_ERR_UTILS | (y))
/* rcsid[] = "$Id$" */
/* static uint16 nativeIT = NATIVEIT; */ /* machine integer type - currently unused here */
static uint16 nativeFT = NATIVEFT; /* machine float type */
/** .
*
* @return
*/
int ccp4_utils_translate_mode_float(float *out, const void *buffer, int dim, int mode)
{
unsigned char *ucp;
unsigned short *usp;
float *fp = out, *ufp, tmp1, tmp2;
register int ctr=0;
switch(mode) {
case 0:
ucp = (unsigned char *)buffer;
for(ctr = 0; ctr < dim ; ++ctr)
*fp++ = (float) *ucp++;
break;
case 1:
usp = (unsigned short *)buffer;
for(ctr = 0; ctr < dim ; ++ctr)
*fp++ = (float) *usp++;
break;
case 3:
/* complex short (define type ?) */
usp = (unsigned short *)buffer;
for(ctr = 0; ctr < dim ; ++ctr) {
tmp1 = (float) *usp++;
tmp2 = (float) *usp++;
*fp++ = (float) sqrt(tmp1*tmp1 + tmp2*tmp2);
}
break;
case 4:
/* complex real (define type ?) */
ufp = (float *)buffer;
for(ctr = 0; ctr < dim ; ++ctr) {
tmp1 = *ufp++;
tmp2 = *ufp++;
*fp++ = (float) sqrt(tmp1*tmp1 + tmp2*tmp2);
}
break;
case 2:
default:
break;
}
return (ctr);
}
/** Gets the length of a Fortran string with trailing blanks removed.
*
* @return length of string
*/
size_t ccp4_utils_flength (char *s, int len)
{
if (len <= 0 ) return 0;
while (s[--len] == ' ')
if (len == 0) return 0;
return (++len);
}
/** .
*
* @return
*/
void ccp4_utils_print (const char *message)
{
printf ("%s\n",message);
}
#if ! defined (VMS)
/** .
*
* @return
*/
int ccp4_utils_setenv (char *str)
{
#if defined (sgi) || defined (sun) || defined (__hpux) || \
defined(_AIX) || defined (__OSF1__) || \
defined (__osf__) || defined (__FreeBSD__) || defined (linux) || \
defined (_WIN32) || defined __linux__
/* putenv is the POSIX.1, draft 3 proposed mechanism */
#if !(defined(__hpux) && defined(__HP_cc))
int putenv ();
#endif
char *param;
if ( (param = (char *) ccp4_utils_malloc( (strlen(str)+1)*sizeof(char) )) == NULL) {
ccp4_errno = CCP4_ERRNO(errno);
return -1; }
strcpy(param,str);
return (putenv (param));
/* note the necessary lack of free() */
#else
/* setenv is not POSIX, BSD might have to use `index' */
int setenv ();
char *param1,*param2;
if ( (param1 = (char *) ccp4_utils_malloc( (strlen(str)+1)*sizeof(char) )) == NULL) {
ccp4_errno = CCP4_ERRNO(errno);
return -1; }
strcpy(param1,str);
if ((param2 = (char *) strchr(param1, '=')) == NULL) {
ccp4_errno = CCP4_ERRNO(errno);
return -1; }
*param2++ = '\0';
return (setenv (param1, param2, 1));
#endif
}
#endif
#if ! defined (VMS)
/** .
*
* @return
*/
int ccp4_utils_outbuf(void)
{
#if defined (sgi) || defined (sun) || \
defined (__OSF1__) || \
defined (__FreeBSD__)
return setlinebuf(stdout);
#else
#if defined(_MSC_VER)
return setvbuf(stdout, NULL, _IONBF, 80);
#else
# if defined (_AIX)
return -1;
# else
/* Windows requires size argument, though 0 works on unix */
return setvbuf(stdout, NULL, _IOLBF, 80);
# endif
#endif
#endif
}
/** .
*
* @return
*/
int ccp4_utils_noinpbuf(void)
{
return setvbuf(stdin, NULL, _IONBF, 0);
}
#endif
union float_uint_uchar ccp4_nan ()
#if NATIVEFT == DFNTF_BEIEEE || NATIVEFT == DFNTF_LEIEEE
# define CCP4_NAN 0xfffa5a5a
#endif
/* For \idx{Convex} native mode and \idx{VAX} use a \idx{Rop} value: */
/* */
/* <magic numbers>= */
#if NATIVEFT == DFNTF_CONVEXNATIVE
# define CCP4_NAN 0x80000000
#endif
#if NATIVEFT == DFNTF_VAX
# define CCP4_NAN 0x00008000
#endif
#ifndef CCP4_NAN
# error "CCP4_NAN isn't defined (needs NATIVEFT)"
#endif
{
union float_uint_uchar realnum;
realnum.i = CCP4_NAN;
return (realnum);
}
/** .
*
* @return
*/
int ccp4_utils_isnan (const union float_uint_uchar *realnum)
{
switch (nativeFT) {
case DFNTF_BEIEEE :
case DFNTF_LEIEEE :
return ((realnum->i & 0x7f800000) == 0x7f800000); /* exponent all 1s */
case DFNTF_CONVEXNATIVE :
return ((realnum->i & 0xff800000) == 0x80000000);
case DFNTF_VAX :
return ((realnum->i & 0x0000ff80) == 0x00008000);
default :
ccp4_fatal("CCP4_UTILS_ISNAN: bad nativeFT");
return 0; /* avoid compiler warning */
}
}
#define MDFBIG -1.0E10 /* BIOMOL absence flag value */
/** .
*
* @return
*/
void ccp4_utils_bml (int ncols, union float_uint_uchar cols[])
{
int i;
for (i=0; i<ncols; i++)
if (cols[i].i != CCP4_NAN)
if (cols[i].f <= MDFBIG) cols[i].f = 0.0;
}
/** .
*
* @return
*/
void ccp4_utils_wrg (int ncols, union float_uint_uchar cols[], float wminmax[])
{
int i;
for (i=0; i<ncols; i++)
if (cols[i].i != CCP4_NAN)
if (cols[i].f > MDFBIG) {
if (cols[i].f < wminmax[2*i]) wminmax[2*i] = cols[i].f;
if (cols[i].f > wminmax[1+2*i]) wminmax[1+2*i] = cols[i].f; }
}
/** .
*
* @return
*/
void ccp4_utils_hgetlimits (int *IValueNotDet, float *ValueNotDet)
{
*IValueNotDet = INT_MAX;
*ValueNotDet = FLT_MAX;
}
#ifndef _WIN32
static unsigned parse_mode(const char *cmode)
{
unsigned mode = 0;
#if defined (__APPLE__)
static const unsigned TBM = 0x07;
switch (strlen(cmode)) {
case 4:
mode |= (*cmode & TBM) << 9 ;
mode |= (*(cmode+1) & TBM) << 6 ;
mode |= (*(cmode+2) & TBM) << 3 ;
mode |= (*(cmode+3) & TBM) ;
break;
case 3:
mode |= (*cmode & TBM) << 6 ;
mode |= (*(cmode+1) & TBM) << 3 ;
mode |= (*(cmode+2) & TBM) ;
break;
case 2:
mode |= (*cmode & TBM) << 3 ;
mode |= (*(cmode+1) & TBM) ;
break;
case 1:
mode |= (*cmode & TBM) ;
break;
default:
mode = 0x0fff ;
}
#else
/* Possible modes (see stat.h)
Currently pass 3-character string and interpret as octal.
Try also S_IRWXU, S_IRWXG, etc. */
sscanf(cmode,"%o",&mode);
#endif
return mode;
}
#endif
/** .
*
* @return
*/
int ccp4_utils_mkdir (const char *path, const char *cmode)
{
int result;
#if defined(_WIN32)
result = mkdir(path);
#else
unsigned mode = parse_mode(cmode);
result = mkdir(path, (mode_t) mode);
#endif
if (result == -1) {
if (errno == EEXIST) {
result = 1;
}
}
return (result);
}
/** .
*
* @return
*/
int ccp4_utils_chmod (const char *path, const char *cmode)
{
#if defined(_WIN32)
return (chmod(path,0x0fff));
#else
unsigned mode = parse_mode(cmode);
return (chmod(path, (mode_t) mode));
#endif
}
/** This is a wrapper for the malloc function, which adds some
* error trapping.
*
* @return void
*/
void *ccp4_utils_malloc(size_t size)
{ void *val;
val = malloc (size);
if (!val && size)
{
perror ("Failure in ccp4_utils_malloc");
abort ();
}
return val;}
/** This is a wrapper for the realloc function, which adds some
* error trapping.
*
* @return
*/
void *ccp4_utils_realloc(void *ptr, size_t size)
{ void *val;
val = realloc (ptr, size);
if (!val && size)
{
perror ("Failure in ccp4_utils_realloc");
abort ();
}
return val;}
/** This is a wrapper for the calloc function, which adds some
* error trapping.
*
* @return
*/
void *ccp4_utils_calloc(size_t nelem , size_t elsize)
{ void *val;
val = calloc (nelem, elsize);
if (!val && elsize)
{
perror ("Failure in ccp4_utils_calloc");
abort ();
}
return val;}
/** Return the user's login name.
* Note that getlogin only works for processes attached to
* a terminal (and hence won't work from the GUI).
* @return pointer to character string containing login name.
*/
char *ccp4_utils_username(void)
{
static char userid_unknown[] = "unknown";
char *userid = NULL;
#if defined(_WIN32)
static char windows_username[512];
DWORD bufsize = sizeof(windows_username);
if (GetUserName(windows_username, &bufsize))
userid = windows_username;
#else
userid = getlogin();
#endif
return userid ? userid : userid_unknown;
}
static int is_sep(char c)
{
#ifdef _WIN32
/* allow alternative separator for Windows (for MSYS, Cygwin, Wine) */
return c == PATH_SEPARATOR || c == '/';
#else
return c == PATH_SEPARATOR;
#endif
}
/** Extracts the basename from a full file name.
* Separators for directories and extensions are OS-specific.
* @param filename full file name string.
* @return pointer to basename
*/
char *ccp4_utils_basename(const char *filename)
{
int i, indx1=-1, length;
char *basename;
for ( i = strlen(filename)-1; i >= 0; i-- ) {
if (is_sep(filename[i])) {
indx1 = i;
break;
}
}
length = strlen(filename) - indx1;
/* Search for extension separators must be performed backwards
in case filename has multiple extension separators */
for ( i = strlen(filename)-1; i >= (indx1 < 0 ? 0 : indx1) ; i-- ) {
if (filename[i] == EXT_SEPARATOR) {
length = i - indx1;
break;
}
}
basename = ccp4_utils_malloc(length*sizeof(char));
strncpy(basename,filename+indx1+1,length-1);
basename[length-1]='\0';
return basename;
}
/** Extracts the pathname from a full file name.
* Separators for directories and extensions are OS-specific.
* @param filename full file name string.
* @return pointer to pathname with trailing separator.
*/
char *ccp4_utils_pathname(const char *filename)
{
int i, indx1=-1, length;
char *pathname;
for ( i = strlen(filename)-1; i >= 0; i-- ) {
if (is_sep(filename[i])) {
indx1 = i;
break;
}
}
length = indx1+2;
pathname = ccp4_utils_malloc(length*sizeof(char));
strncpy(pathname,filename,length-1);
pathname[length-1]='\0';
return pathname;
}
/** Extracts the extension from a full file name.
* Separators for directories and extensions are OS-specific.
* @param filename full file name string.
* @return pointer to extension
*/
char *ccp4_utils_extension(const char *filename)
{
int i, indx1=-1, length=1;
char *extension;
for ( i = strlen(filename)-1; i >= 0; i-- ) {
if (filename[i] == EXT_SEPARATOR) {
indx1 = i;
length = strlen(filename) - indx1;
break;
} else if (is_sep(filename[i])) {
indx1 = i;
length = 1;
break;
}
}
extension = ccp4_utils_malloc(length*sizeof(char));
strncpy(extension,filename+indx1+1,length-1);
extension[length-1]='\0';
return extension;
}
/** Joins a leading directory with a filename.
* Separators for directories and extensions are OS-specific.
* @param dir directory path.
* @param file file name string.
* @return pointer to joined directory-filename path.
*/
char *ccp4_utils_joinfilenames(const char *dir, const char *file)
{
char *join=NULL;
int lendir,lenfile,lenjoin;
lendir = strlen(dir);
lenfile = strlen(file);
lenjoin = lendir + lenfile + 2;
join = (char *) ccp4_utils_malloc(sizeof(char)*lenjoin);
if (!join) {
return NULL;
}
strncpy(join,dir,lendir);
join[lendir] = PATH_SEPARATOR;
join[lendir+1] = '\0';
strncat(join,file,lenfile);
join[lenjoin-1] = '\0';
return join;
}
/** .
*
* @return
*/
void ccp4_utils_idate (int iarray[3])
{
struct tm *lt=NULL;
time_t tim;
tim = time(NULL);
lt = localtime(&tim);
iarray[0] = lt->tm_mday;
iarray[1] = lt->tm_mon+1; /* need range 1-12 */
iarray[2] = lt->tm_year + 1900;
}
/** .
*
* @return
*/
char *ccp4_utils_date(char *date)
{
int iarray[3];
ccp4_utils_idate(iarray);
sprintf(date,"%2d/%2d/%4d",iarray[0],iarray[1],iarray[2]);
date[10] = '\0';
return (date);
}
/** Function to obtain current time.
* @param iarray Array containing hours, minutes and seconds.
* @return void.
*/
void ccp4_utils_itime (int iarray[3])
{
struct tm *lt;
time_t tim;
tim = time(NULL);
lt = localtime(&tim);
iarray[0] = lt->tm_hour;
iarray[1] = lt->tm_min;
iarray[2] = lt->tm_sec;
}
/** Alternative to ccp4_utils_itime with time as character string.
* @param time Character string of form HH:MM:SS
* @return pointer to character string.
*/
char *ccp4_utils_time(char *time)
{
int iarray[3];
ccp4_utils_itime(iarray);
sprintf(time,"%2.2d:%2.2d:%2.2d",iarray[0],iarray[1],iarray[2]);
time[8] = '\0';
return (time);
}
/** Function to obtain User and System times.
* @param tarray Array containing User and System times.
* @return Sum of User and System times.
*/
float ccp4_utils_etime (float tarray[2])
{
#ifdef _WIN32
tarray[0] = tarray[1] = 0.;
#else
static long clk_tck = 0;
struct tms buffer;
if (! clk_tck) clk_tck = sysconf(_SC_CLK_TCK);
(void) times(&buffer);
tarray[0] = (float) buffer.tms_utime / (float)clk_tck;
tarray[1] = (float) buffer.tms_stime / (float)clk_tck;
#endif
return (tarray[0]+tarray[1]);
}
#if defined(_MSC_VER)
double ccp4_erfc( double x )
{
double t,z,ans;
z=fabs(x);
t=1.0/(1.0+0.5*z);
ans=t*exp(-z*z-1.26551223+t*(1.00002368+t*(0.37409196+t*(0.09678418+
t*(-0.18628806+t*(0.27886807+t*(-1.13520398+t*(1.48851587+
t*(-0.82215223+t*0.17087277)))))))));
return x >= 0.0 ? ans : 2.0-ans;
}
#endif
#if defined (__APPLE__) && defined (__GNUC__) && ( __GNUC__ < 3 )
void _carbon_init(int argc, char **argv) {}
void _objcInit(void) {}
#endif
#if defined (__APPLE__) && defined (__GNUC__) && ( __GNUC__ == 3 ) && (__GNUC_MINOR__ == 1)
float acosf(float x) {
return (float) acos( (double) x);
}
float atanf(float x) {
return (float) atan( (double) x);
}
float asinf(float x) {
return (float) asin( (double) x);
}
#endif
#if defined(_MSC_VER) && _MSC_VER < 1800
double rint(double x) {
if (x >= 0.) {
return (double)(int)(x+.5);
}
return (double)(int)(x-.5);
}
#endif

199
ccp4c/ccp4/mtzdata.h Normal file
View File

@@ -0,0 +1,199 @@
/*
mtzdata.h: Definition of MTZ data structure.
Copyright (C) 2001 CCLRC, Martyn Winn
This library is free software: you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public License
version 3, modified in accordance with the provisions of the
license to address the requirements of UK law.
You should have received a copy of the modified GNU Lesser General
Public License along with this library. If not, copies may be
downloaded from http://www.ccp4.ac.uk/ccp4license.php
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.
*/
/** @file mtzdata.h
*
* @brief Definition of MTZ data structure.
*
* The file defines a hierarchy of structs which hold the
* MTZ data structure.
*
* @author Martyn Winn
*/
#ifndef __CMTZData__
#define __CMTZData__
#define MTZVERSN "MTZ:V1.1" /**< traditional version number! */
#define MTZ_MAJOR_VERSN 1 /**< MTZ file major version - keep to single digit */
#define MTZ_MINOR_VERSN 1 /**< MTZ file minor version - keep to single digit */
#define CCP4_MTZDATA 20100630 /**< Date stamp for the cmtz data structure
(update if there are changes to the structs in this file) */
/** defines for sizes in MTZ structure */
#define SIZE1 20 /**< size of pre-reflection block */
#define MTZRECORDLENGTH 80 /**< length of records */
#define MAXSPGNAMELENGTH 20 /**< max length of a spacegroup name */
#define MAXPGNAMELENGTH 10 /**< max length of a pointgroup name */
#define NBATCHWORDS 185 /**< total size of batch header buffer */
#define NBATCHINTEGERS 29 /**< size of integer section of batch header buffer */
#define NBATCHREALS 156 /**< size of float section of batch header buffer */
/* cctbx uses smaller values for these three */
#ifndef MXTALS
#define MXTALS 100 /**< maximum number of crystals (for a few arrays - to be removed!) */
#endif
#ifndef MSETS
#define MSETS 1000 /**< maximum number of datasets (for a few arrays - to be removed!) */
#endif
#ifndef MCOLUMNS
#define MCOLUMNS 10000 /**< maximum number of columns (for a few arrays - to be removed!) */
#endif
/** MTZ column struct. */
typedef struct { char label[31]; /**< column name as given by user */
char type[3]; /**< column type */
int active; /**< whether column in active list */
unsigned int source; /**< column index in input file */
float min; /**< minimum data element */
float max; /**< maximum data element */
float *ref; /**< data array */
char colsource[37]; /**< column source - originating job */
char grpname[31]; /**< column group name */
char grptype[5]; /**< column group type */
int grpposn; /**< column group position in group */
} MTZCOL;
/** MTZ dataset struct. */
typedef struct { int setid; /**< Dataset id */
char dname[65]; /**< Dataset name */
float wavelength; /**< Dataset wavelength */
int ncol; /**< number of columns */
MTZCOL **col; /**< columns */
} MTZSET;
/** MTZ crystal struct. */
typedef struct { int xtalid; /**< Crystal id */
char xname[65]; /**< Crystal name */
char pname[65]; /**< Project name */
float cell[6]; /**< Crystal cell */
float resmin; /**< Low resolution limit */
float resmax; /**< High resolution limit */
int nset; /**< number of datasets */
MTZSET **set; /**< datasets */
} MTZXTAL;
/** MTZ batch struct. */
typedef struct bathead { int num; /**< batch number */
char title[71]; /**< batch title */
char gonlab[3][9]; /**< names of the three axes */
int iortyp; /**< type of orientation block (for
possible future use, now = 0) */
int lbcell[6]; /**< refinement flags for cell */
int misflg; /**< number of phixyz used (0, 1, or 2) */
int jumpax; /**< reciprocal axis closest to rotation
axis */
int ncryst; /**< crystal number */
int lcrflg; /**< mosaicity model: 0 = isotropic,
1 = anisotropic */
int ldtype; /**< type of data: 2D (1), 3D (2), or
Laue (3) */
int jsaxs; /**< goniostat scan axis number */
int nbscal; /**< number of batch scales & Bfactors
(0 if unset) */
int ngonax; /**< number of goniostat axes */
int lbmflg; /**< flag for type of beam info:
= 0 for alambd, delamb
= 1 also delcor, divhd, divvd */
int ndet; /**< number of detectors (current maximum
2) */
int nbsetid; /**< dataset id - should be pointer? */
float cell[6]; /**< cell dimensions */
float umat[9]; /**< orientation matrix U in Fortranic order,
i.e. U(1,1), U(2,1) ... */
float phixyz[2][3]; /**< missetting angles at beginning and
end of oscillation */
float crydat[12]; /**< mosaicity */
float datum[3]; /**< datum values of goniostat axes */
float phistt; /**< start of phi relative to datum */
float phiend; /**< end of phi relative to datum */
float scanax[3]; /**< rotation axis in lab frame */
float time1; /**< start time */
float time2; /**< stop time */
float bscale; /**< batch scale */
float bbfac; /**< batch temperature factor */
float sdbscale; /**< sd bscale */
float sdbfac; /**< sd bbfac */
float phirange; /**< phi range */
float e1[3]; /**< vector 1 ("Cambridge" laboratory axes)
defining ngonax goniostat axes */
float e2[3]; /**< vector 2 ("Cambridge" laboratory axes)
defining ngonax goniostat axes */
float e3[3]; /**< vector 3 ("Cambridge" laboratory axes)
defining ngonax goniostat axes */
float source[3]; /**< idealised source vector */
float so[3]; /**< source vector */
float alambd; /**< wavelength (A) */
float delamb; /**< dispersion (deltalambda / lambda) */
float delcor; /**< correlated component */
float divhd; /**< horizontal beam divergence */
float divvd; /**< vertical beam divergence */
float dx[2]; /**< xtal to detector distance */
float theta[2]; /**< detector tilt angle */
float detlm[2][2][2]; /**< min & max values of detector coords
(pixels) */
struct bathead *next; /**< next batch in list */
} MTZBAT;
/** MTZ symmetry struct. */
typedef struct { int spcgrp; /**< spacegroup number */
char spcgrpname[MAXSPGNAMELENGTH+1]; /**< spacegroup name */
int nsym; /**< number of symmetry operations */
float sym[192][4][4]; /**< symmetry operations
(translations in [*][3]) */
int nsymp; /**< number of primitive symmetry ops. */
char symtyp; /**< lattice type (P,A,B,C,I,F,R) */
char pgname[MAXPGNAMELENGTH+1]; /**< pointgroup name */
char spg_confidence; /**< L => Bravais lattice correct
P => pointgroup correct
E => spacegroup or enantiomorph
S => spacegroup is correct
X => flag not set */
} SYMGRP;
typedef union { char amnf[4];
float fmnf;
} MNF;
/** Top level of MTZ struct. */
typedef struct { CCP4File *filein; /**< file for reading */
CCP4File *fileout; /**< file for writing */
char title[71]; /**< title of mtz structure */
char *hist; /**< history of mtz file */
int histlines; /**< number of lines in hist */
int nxtal; /**< number of crystals */
int ncol_read; /**< number of columns from file */
int nref; /**< total number of reflections */
int nref_filein; /**< number of reflections from input file */
int refs_in_memory; /**< whether reflections are held in memory */
int n_orig_bat; /**< original number of batches */
float resmax_out; /**< output file max res */
float resmin_out; /**< output file min res */
MNF mnf; /**< value of missing number flag */
SYMGRP mtzsymm; /**< symmetry information */
MTZXTAL **xtal; /**< crystals */
MTZBAT *batch; /**< first batch header */
MTZCOL *order[5]; /**< sort order */
char *xml; /**< xml data block */
char *unknown_headers;/**< unknown header data */
int n_unknown_headers;/**< unknown header data */
} MTZ;
#endif

88
ccp4c/ccp4/overview.h Normal file
View File

@@ -0,0 +1,88 @@
/*
overview.h: overview of CINCH - Crystallography IN C Headers
Copyright (C) 2003 CCLRC, Martyn Winn
This library is free software: you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public License
version 3, modified in accordance with the provisions of the
license to address the requirements of UK law.
You should have received a copy of the modified GNU Lesser General
Public License along with this library. If not, copies may be
downloaded from http://www.ccp4.ac.uk/ccp4license.php
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.
*/
/** @mainpage CINCH - Crystallography IN C Headers
*
* @note I'm fed up of the uninspiring "new library" and here's
* my first attempt at a funky name. Alternatives welcome!
*
* @verbatim
<!-- ::INDEX_INFO::C libraries::Library::::CCP4 C/C++ Software Library:::::::: -->
@endverbatim
*
* @section aims Aims
The CCP4 software suite is based around a library of routines which
cover common tasks, such as file opening, parsing keyworded input,
reading and writing of standard data formats, applying symmetry
operations, etc. Programs in the suite call these routines which, as
well as saving the programmer some effort, ensure that the varied
programs in the suite have a similar look-and-feel.
<p>
Since 2002, there has been a major effort to re-write
much of the CCP4 library into C/C++. The aims are:
<ul>
<li>To implement a better representation of the underlying data model.
For example, Eugene Krissinel's MMDB library acts on a data structure
which represents the various levels of structure of a protein model.
The new MTZ library encapsulates the crystal/dataset hierarchy that
is increasingly being used by programs.
<li>To maintain support for existing programs. In particular, the
existing Fortran APIs will be maintained, although they will now often
be only wrappers to functions in the new library. It is hoped that many
existing programs will be migrated to using the new library directly.
<li>To provide support for scripting. It is possible to generate APIs
for Python, Tcl and Perl automatically from the core C code. Thus, much
of the standard CCP4 functionality wil be available to scripts used
e.g. in ccp4i or the molecular graphics project.
</ul>
This incremental approach, maintaining the existing suite while
improving the underlying code, puts constraints on what is possible, but
is considered more appropriate for a collaborative project like CCP4.
* @section start This documentation
<p>
This documentation is generated automatically by
<a href="http://www.doxygen.org/">Doxygen</a> from
comment sections in the code. It is therefore detailed and extensive.
The library divides roughly into the following sections:
<dl>
<dt>CMTZ library
<dd>See the @ref cmtz_page page for C/C++ programmers, and the
@ref cmtz_f_page page for Fortran programmers.
<dt>CMAP library
<dd>See the @ref cmap_page page for C/C++ programmers, and the
@ref cmap_f_page page for Fortran programmers.
<dt>MMDB library
<dd>See Eugene's <a href="http://www.ebi.ac.uk/~keb/cldoc">documentation</a>.
<dt>CSYM library
<dd>See the @ref csym_page page for C/C++ programmers, and the
@ref csym_f_page page for Fortran programmers.
<dt>CCP4 utility library
<dd>See the @ref utilities_page page for C/C++ programmers.
<dt>Low level disk i/o
<dd>See the @ref diskio_f_page page for Fortran programmers.
</dl>
*/

1521
ccp4c/ccp4/pack_c.c Normal file

File diff suppressed because it is too large Load Diff

129
ccp4c/ccp4/pack_c.h Normal file
View File

@@ -0,0 +1,129 @@
/* Some general defines: */
#define PACKIDENTIFIER "\nCCP4 packed image, X: %04d, Y: %04d\n"
/* This string defines the start of a packed image. An image file is scanned
until this string is encountered, the size of the unpacked image is
determined from the values of X and Y (which are written out as formatted
ascii numbers), and the packed image is expected to start immediately after
the null-character ending the string. */
#define V2IDENTIFIER "\nCCP4 packed image V2, X: %04d, Y: %04d\n"
/* This string defines the start of a packed image. An image file is scanned
until this string is encountered, the size of the unpacked image is
determined from the values of X and Y (which are written out as formatted
ascii numbers), and the packed image is expected to start immediately after
the null-character ending the string. */
#define PACKBUFSIZ BUFSIZ
/* Size of internal buffer in which the packed array is stored during transit
form an unpacked image to a packed image on disk. It is set to the size
used by the buffered io-routines given in <stdio.h>, but it could be
anything. */
#define DIFFBUFSIZ 16384L
/* Size of the internal buffer in which the differences between neighbouring
pixels are stored prior to compression. The image is therefore compressed
in DIFFBUFSIZ chunks. Decompression does not need to know what DIFFBUFSIZ
was when the image was compressed. By increasing this value, the image
can be compressed into a packed image which is a few bytes smaller. Do
not decrease the value of DIFFBUFSIZ below 128L. */
#define BYTE char
/* BYTE is a one byte integer. */
#define WORD short int
/* WORD is a two-byte integer. */
#define LONG int
/* LONG is a four byte integer. */
/* Dave Love 5/7/94: using `int' gets you 4 bytes on the 32-bit Unix
(and VAX) systems I know of and also on (64-bit) OSF/1 Alphas which
have 64-bit longs. (This definition previously used `long'.) */
/******************************************************************************/
/* Some usefull macros used in the code of this sourcefile: */
#define max(x, y) (((x) > (y)) ? (x) : (y))
/* Returns maximum of x and y. */
#define min(x, y) (((x) < (y)) ? (x) : (y))
/* Returns minimum of x and y. */
#undef abs /* avoid complaint from DEC C, at least */
#define abs(x) (((x) < 0) ? (-(x)) : (x))
/* Returns the absolute value of x. */
/* Used to be 'static const LONG' but const declaration gives trouble on HPs */
#ifndef SKIP_SETBITS
static LONG setbits[33] =
{0x00000000L, 0x00000001L, 0x00000003L, 0x00000007L,
0x0000000FL, 0x0000001FL, 0x0000003FL, 0x0000007FL,
0x000000FFL, 0x000001FFL, 0x000003FFL, 0x000007FFL,
0x00000FFFL, 0x00001FFFL, 0x00003FFFL, 0x00007FFFL,
0x0000FFFFL, 0x0001FFFFL, 0x0003FFFFL, 0x0007FFFFL,
0x000FFFFFL, 0x001FFFFFL, 0x003FFFFFL, 0x007FFFFFL,
0x00FFFFFFL, 0x01FFFFFFL, 0x03FFFFFFL, 0x07FFFFFFL,
0x0FFFFFFFL, 0x1FFFFFFFL, 0x3FFFFFFFL, 0x7FFFFFFFL,
0xFFFFFFFFL};
/* This is not a macro really, but I've included it here anyway. Upon indexing,
it returns a LONG with the lower (index) number of bits set. It is equivalent
to the following macro:
#define setbits(n) (((n) == 32) : ((1L << (n)) - 1) : (-1L))
Indexing the const array should usually be slightly faster. */
#endif
#define shift_left(x, n) (((x) & setbits[32 - (n)]) << (n))
/* This macro is included because the C standard does not properly define a
left shift: on some machines the bits which are pushed out at the left are
popped back in at the right. By masking, the macro prevents this behaviour.
If you are sure that your machine does not pops bits back in, you can speed
up the code insignificantly by taking out the masking. */
#define shift_right(x, n) (((x) >> (n)) & setbits[32 - (n)])
/* See comment on left shift. */
/******************************************************************************/
#if __STDC__ && !defined(PROTOTYPE)
#define PROTOTYPE 1
#endif
/* Functions required for packing: */
#if defined (PROTOTYPE)
void v2pack_wordimage_c(WORD *img, int x, int y, char *filename);
/* Pack image 'img', containing 'x * y' WORD-sized pixels into 'filename'.
This function generates Version 2 images! */
void v2pack_longimage_c(LONG *img, int x, int y, char *filename);
/* Pack image 'img', containing 'x * y' LONG-sized pixels into 'filename'.
This function generates Version 2 images! */
/* Functions required for unpacking: */
void readpack_word_c(WORD *img, char *filename);
/* Unpacks packed image from 'filename' into the WORD-array 'img'. Scans the
file defined by 'filename' until the PACKIDENTIFIER is found, then unpacks
starting from there. */
void readpack_long_c(LONG *img, char *filename);
/* Unpacks packed image from 'filename' into the LONG-array 'img'. Scans the
file defined by 'filename' until the PACKIDENTIFIER is found, then unpacks
starting from there. */
void imsiz_c(char *filename, LONG *x, LONG *y);
/* Determines the size of the the packed image "filename" after unpacking. The
dimensions are returned in x and y. */
#endif /* (PROTOTYPE) */

99
ccp4c/ccp4/vmslibrary.c Normal file
View File

@@ -0,0 +1,99 @@
/*
vmslibrary.c
Copyright (C) 1999 Martyn Winn
This library is free software: you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public License
version 3, modified in accordance with the provisions of the
license to address the requirements of UK law.
You should have received a copy of the modified GNU Lesser General
Public License along with this library. If not, copies may be
downloaded from http://www.ccp4.ac.uk/ccp4license.php
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.
*/
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <ctype.h>
#include <limits.h>
#include <float.h>
#include <types.h>
#include <descrip.h>
#include <stat.h>
#define MAXFLEN 500 /* the maximum length of a filename in CCP4 */
/* prototype definitions */
void HGETLIMITS (int *IValueNotDet, float *ValueNotDet);
static size_t flength (char *s, int len);
void CMKDIR (struct dsc$descriptor_s *path, struct dsc$descriptor_s *cmode,
int *result);
void CCHMOD (struct dsc$descriptor_s *path, struct dsc$descriptor_s *cmode,
int *result);
void HGETLIMITS (int *IValueNotDet, float *ValueNotDet)
{
*IValueNotDet = INT_MAX;
*ValueNotDet = FLT_MAX;
}
static size_t flength (char *s, int len)
{
while (s[--len] == ' ');
return (++len);
}
/* Wrap-around for mkdir function. Returns 0 if successful, 1 if directory already exists, */
/* and -1 if other error. */
void CMKDIR (struct dsc$descriptor_s *path, struct dsc$descriptor_s *cmode,
int *result)
{ size_t Length;
char name[MAXFLEN];
mode_t mode;
/* truncate path to MAXFLEN - 1 characters, MAXFLEN defined in library.h */
Length = flength (path->dsc$a_pointer, path->dsc$w_length);
if (Length > (size_t) MAXFLEN) Length = (size_t) MAXFLEN - 1;
(void) strncpy (name, path->dsc$a_pointer, Length);
name[Length] = '\0';
/* Possible modes (see stat.h)
Currently pass 3-character string and interpret as octal.
Try also S_IRWXU, S_IRWXG, etc. */
sscanf(cmode->dsc$a_pointer,"%o",&mode);
*result = mkdir(name,mode);
if (*result == -1) {
/* Distinguish directory-exists error from others, since usually not a problem. */
if (errno == EEXIST) {
*result = 1;
}
}
}
void CCHMOD (struct dsc$descriptor_s *path, struct dsc$descriptor_s *cmode,
int *result)
{ size_t Length;
char name[MAXFLEN];
mode_t mode;
/* truncate path to MAXFLEN - 1 characters, MAXFLEN defined in library.h */
Length = flength (path->dsc$a_pointer, path->dsc$w_length);
if (Length > (size_t) MAXFLEN) Length = (size_t) MAXFLEN - 1;
(void) strncpy (name, path->dsc$a_pointer, Length);
name[Length] = '\0';
/* Possible modes (see stat.h)
Currently pass 3-character string and interpret as octal.
Try also S_IRWXU, S_IRWXG, etc. */
sscanf(cmode->dsc$a_pointer,"%o",&mode);
*result = chmod(name,mode);
}

265
ccp4c/ccp4/w32mvs.c Normal file
View File

@@ -0,0 +1,265 @@
/*
w32mvs.c: functions required by MVS
Copyright (C) 2003 Alun Ashton
This library is free software: you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public License
version 3, modified in accordance with the provisions of the
license to address the requirements of UK law.
You should have received a copy of the modified GNU Lesser General
Public License along with this library. If not, copies may be
downloaded from http://www.ccp4.ac.uk/ccp4license.php
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.
*/
#ifdef _MSC_VER
#include "w32mvs.h"
/* For communication from `getopt' to the caller.
When `getopt' finds an option that takes an argument,
the argument value is returned here.
Also, when `ordering' is RETURN_IN_ORDER,
each non-option ARGV-element is returned here. */
char *optarg = 0;
/* Index in ARGV of the next element to be scanned.
This is used for communication to and from the caller
and for communication between successive calls to `getopt'.
On entry to `getopt', zero means this is the first call; initialize.
When `getopt' returns EOF, this is the index of the first of the
non-option elements that the caller should itself scan.
Otherwise, `optind' communicates from one call to the next
how much of ARGV has been scanned so far. */
int optind = 0;
/* The next char to be scanned in the option-element
in which the last option character we returned was found.
This allows us to pick up the scan where we left off.
If this is zero, or a null string, it means resume the scan
by advancing to the next ARGV-element. */
static char *nextchar;
/* Callers store zero here to inhibit the error message
for unrecognized options. */
int opterr = 1;
/* Describe how to deal with options that follow non-option ARGV-elements.
UNSPECIFIED means the caller did not specify anything;
the default is then REQUIRE_ORDER if the environment variable
_OPTIONS_FIRST is defined, PERMUTE otherwise.
REQUIRE_ORDER means don't recognize them as options.
Stop option processing when the first non-option is seen.
This is what Unix does.
PERMUTE is the default. We permute the contents of `argv' as we scan,
so that eventually all the options are at the end. This allows options
to be given in any order, even with programs that were not written to
expect this.
RETURN_IN_ORDER is an option available to programs that were written
to expect options and other ARGV-elements in any order and that care about
the ordering of the two. We describe each non-option ARGV-element
as if it were the argument of an option with character code zero.
Using `-' as the first character of the list of option characters
requests this mode of operation.
The special argument `--' forces an end of option-scanning regardless
of the value of `ordering'. In the case of RETURN_IN_ORDER, only
`--' can cause `getopt' to return EOF with `optind' != ARGC. */
static enum { REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER } ordering;
static void exchange (char **argv)
{
int nonopts_size
= (last_nonopt - first_nonopt) * sizeof (char *);
char **temp = (char **) alloca (nonopts_size);
/* Interchange the two blocks of data in argv. */
bcopy (&argv[first_nonopt], temp, nonopts_size);
bcopy (&argv[last_nonopt], &argv[first_nonopt],
(optind - last_nonopt) * sizeof (char *));
bcopy (temp, &argv[first_nonopt + optind - last_nonopt],
nonopts_size);
/* Update records for the slots the non-options now occupy. */
first_nonopt += (optind - last_nonopt);
last_nonopt = optind;
}
int getopt (int argc,char **argv,char *optstring)
{
/* Initialize the internal data when the first call is made.
Start processing options with ARGV-element 1 (since ARGV-element 0
is the program name); the sequence of previously skipped
non-option ARGV-elements is empty. */
if (optind == 0)
{
first_nonopt = last_nonopt = optind = 1;
nextchar = 0;
/* Determine how to handle the ordering of options and nonoptions. */
if (optstring[0] == '-')
ordering = RETURN_IN_ORDER;
else if (getenv ("_POSIX_OPTION_ORDER") != 0)
ordering = REQUIRE_ORDER;
else
ordering = PERMUTE;
}
if (nextchar == 0 || *nextchar == 0)
{
if (ordering == PERMUTE)
{
/* If we have just processed some options following some non-options,
exchange them so that the options come first. */
if (first_nonopt != last_nonopt && last_nonopt != optind)
exchange (argv);
else if (last_nonopt != optind)
first_nonopt = optind;
/* Now skip any additional non-options
and extend the range of non-options previously skipped. */
while (optind < argc
&& (argv[optind][0] != '-'
|| argv[optind][1] == 0))
optind++;
last_nonopt = optind;
}
/* Special ARGV-element `--' means premature end of options.
Skip it like a null option,
then exchange with previous non-options as if it were an option,
then skip everything else like a non-option. */
if (optind != argc && !strcmp (argv[optind], "--"))
{
optind++;
if (first_nonopt != last_nonopt && last_nonopt != optind)
exchange (argv);
else if (first_nonopt == last_nonopt)
first_nonopt = optind;
last_nonopt = argc;
optind = argc;
}
/* If we have done all the ARGV-elements, stop the scan
and back over any non-options that we skipped and permuted. */
if (optind == argc)
{
/* Set the next-arg-index to point at the non-options
that we previously skipped, so the caller will digest them. */
if (first_nonopt != last_nonopt)
optind = first_nonopt;
return EOF;
}
/* If we have come to a non-option and did not permute it,
either stop the scan or describe it to the caller and pass it by. */
if (argv[optind][0] != '-' || argv[optind][1] == 0)
{
if (ordering == REQUIRE_ORDER)
return EOF;
optarg = argv[optind++];
return 0;
}
/* We have found another option-ARGV-element.
Start decoding its characters. */
nextchar = argv[optind] + 1;
}
/* Look at and handle the next option-character. */
{
char c = *nextchar++;
char *temp = (char *) strchr (optstring, c);
/* Increment `optind' when we start to process its last character. */
if (*nextchar == 0)
optind++;
if (temp == 0 || c == ':')
{
if (opterr != 0)
{
if (c < 040 || c >= 0177)
fprintf (stderr, "%s: unrecognized option, character code 0%o\n",
argv[0], c);
else
fprintf (stderr, "%s: unrecognized option `-%c'\n",
argv[0], c);
}
return '?';
}
if (temp[1] == ':')
{
if (temp[2] == ':')
{
/* This is an option that accepts an argument optionally. */
if (*nextchar != 0)
{
optarg = nextchar;
optind++;
}
else
optarg = 0;
nextchar = 0;
}
else
{
/* This is an option that requires an argument. */
if (*nextchar != 0)
{
optarg = nextchar;
/* If we end this ARGV-element by taking the rest as an arg,
we must advance to the next element now. */
optind++;
}
else if (optind == argc)
{
if (opterr != 0)
fprintf (stderr, "%s: no argument for `-%c' option\n",
argv[0], c);
optarg = 0;
}
else
/* We already incremented `optind' once;
increment it again when taking next ARGV-elt as argument. */
optarg = argv[optind++];
nextchar = 0;
}
}
return c;
}
}
#endif

200
ccp4c/ccp4/w32mvs.h Normal file
View File

@@ -0,0 +1,200 @@
/*
w32mvs.h: function prototypes for w32mvs.c functions
Copyright (C) 2003 Alun Ashton
This library is free software: you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public License
version 3, modified in accordance with the provisions of the
license to address the requirements of UK law.
You should have received a copy of the modified GNU Lesser General
Public License along with this library. If not, copies may be
downloaded from http://www.ccp4.ac.uk/ccp4license.php
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.
*/
#ifdef _MSC_VER
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <stdio.h>
#include <time.h>
/* Getopt for GNU.
Copyright (C) 1987 Free Software Foundation, Inc.
NO WARRANTY
BECAUSE THIS PROGRAM IS LICENSED FREE OF CHARGE, WE PROVIDE ABSOLUTELY
NO WARRANTY, TO THE EXTENT PERMITTED BY APPLICABLE STATE LAW. EXCEPT
WHEN OTHERWISE STATED IN WRITING, FREE SOFTWARE FOUNDATION, INC,
RICHARD M. STALLMAN AND/OR OTHER PARTIES PROVIDE THIS 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.
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW WILL RICHARD M.
STALLMAN, THE FREE SOFTWARE FOUNDATION, INC., AND/OR ANY OTHER PARTY
WHO MAY MODIFY AND REDISTRIBUTE THIS PROGRAM AS PERMITTED BELOW, BE
LIABLE TO YOU FOR DAMAGES, INCLUDING ANY LOST PROFITS, LOST MONIES, OR
OTHER SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
USE OR INABILITY TO USE (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR
DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY THIRD PARTIES OR
A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS) THIS
PROGRAM, EVEN IF YOU HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH
DAMAGES, OR FOR ANY CLAIM BY ANY OTHER PARTY.
GENERAL PUBLIC LICENSE TO COPY
1. You may copy and distribute verbatim copies of this source file
as you receive it, in any medium, provided that you conspicuously and
appropriately publish on each copy a valid copyright notice "Copyright
(C) 1987 Free Software Foundation, Inc."; and include following the
copyright notice a verbatim copy of the above disclaimer of warranty
and of this License. You may charge a distribution fee for the
physical act of transferring a copy.
2. You may modify your copy or copies of this source file or
any portion of it, and copy and distribute such modifications under
the terms of Paragraph 1 above, provided that you also do the following:
a) cause the modified files to carry prominent notices stating
that you changed the files and the date of any change; and
b) cause the whole of any work that you distribute or publish,
that in whole or in part contains or is a derivative of this
program or any part thereof, to be licensed at no charge to all
third parties on terms identical to those contained in this
License Agreement (except that you may choose to grant more
extensive warranty protection to third parties, at your option).
c) You may charge a distribution fee for the physical act of
transferring a copy, and you may at your option offer warranty
protection in exchange for a fee.
3. You may copy and distribute this program or any portion of it in
compiled, executable or object code form under the terms of Paragraphs
1 and 2 above provided that you do the following:
a) cause each such copy to be accompanied by the
corresponding machine-readable source code, which must
be distributed under the terms of Paragraphs 1 and 2 above; or,
b) cause each such copy to be accompanied by a
written offer, with no time limit, to give any third party
free (except for a nominal shipping charge) a machine readable
copy of the corresponding source code, to be distributed
under the terms of Paragraphs 1 and 2 above; or,
c) in the case of a recipient of this program in compiled, executable
or object code form (without the corresponding source code) you
shall cause copies you distribute to be accompanied by a copy
of the written offer of source code which you received along
with the copy you received.
4. You may not copy, sublicense, distribute or transfer this program
except as expressly provided under this License Agreement. Any attempt
otherwise to copy, sublicense, distribute or transfer this program is void and
your rights to use the program under this License agreement shall be
automatically terminated. However, parties who have received computer
software programs from you with this License Agreement will not have
their licenses terminated so long as such parties remain in full compliance.
5. If you wish to incorporate parts of this program into other free
programs whose distribution conditions are different, write to the Free
Software Foundation at 675 Mass Ave, Cambridge, MA 02139. We have not yet
worked out a simple rule that can be stated here, but we will often permit
this. We will be guided by the two goals of preserving the free status of
all derivatives of our free software and of promoting the sharing and reuse of
software.
In other words, you are welcome to use, share and improve this program.
You are forbidden to forbid anyone else to use, share and improve
what you give them. Help stamp out software-hoarding! */
/* This version of `getopt' appears to the caller like standard Unix `getopt'
but it behaves differently for the user, since it allows the user
to intersperse the options with the other arguments.
As `getopt' works, it permutes the elements of `argv' so that,
when it is done, all the options precede everything else. Thus
all application programs are extended to handle flexible argument order.
Setting the environment variable _POSIX_OPTION_ORDER disables permutation.
Then the behavior is completely standard.
GNU application programs can use a third alternative mode in which
they can distinguish the relative order of options and other arguments. */
#include <malloc.h>
#include <stdlib.h>
#include <string.h>
#define bcopy memmove
/* Handle permutation of arguments. */
/* Describe the part of ARGV that contains non-options that have
been skipped. `first_nonopt' is the index in ARGV of the first of them;
`last_nonopt' is the index after the last of them. */
static int first_nonopt;
static int last_nonopt;
/* Exchange two adjacent subsequences of ARGV.
One subsequence is elements [first_nonopt,last_nonopt)
which contains all the non-options that have been skipped so far.
The other is elements [last_nonopt,optind), which contains all
the options processed since those non-options were skipped.
`first_nonopt' and `last_nonopt' are relocated so that they describe
the new indices of the non-options in ARGV after they are moved. */
static void exchange (char **argv);
/* Scan elements of ARGV (whose length is ARGC) for option characters
given in OPTSTRING.
If an element of ARGV starts with '-', and is not exactly "-" or "--",
then it is an option element. The characters of this element
(aside from the initial '-') are option characters. If `getopt'
is called repeatedly, it returns successively each of theoption characters
from each of the option elements.
If `getopt' finds another option character, it returns that character,
updating `optind' and `nextchar' so that the next call to `getopt' can
resume the scan with the following option character or ARGV-element.
If there are no more option characters, `getopt' returns `EOF'.
Then `optind' is the index in ARGV of the first ARGV-element
that is not an option. (The ARGV-elements have been permuted
so that those that are not options now come last.)
OPTSTRING is a string containing the legitimate option characters.
A colon in OPTSTRING means that the previous character is an option
that wants an argument. The argument is taken from the rest of the
current ARGV-element, or from the following ARGV-element,
and returned in `optarg'.
If an option character is seen that is not listed in OPTSTRING,
return '?' after printing an error message. If you set `opterr' to
zero, the error message is suppressed but we still return '?'.
If a char in OPTSTRING is followed by a colon, that means it wants an arg,
so the following text in the same ARGV-element, or the text of the following
ARGV-element, is returned in `optarg. Two colons mean an option that
wants an optional arg; if there is text in the current ARGV-element,
it is returned in `optarg'.
If OPTSTRING starts with `-', it requests a different method of handling the
non-option ARGV-elements. See the comments about RETURN_IN_ORDER, above. */
int getopt (int argc,char **argv,char *optstring);
#endif

39
ccp4c/data/README Normal file
View File

@@ -0,0 +1,39 @@
* symop.lib: symmetry operators -- see symlib code. Contains symmetry
operators for the 230 spacegroups listed in (and following the conventions
of) the International Tables Vol A and non-standard settings used by various
CCP4 programs. Each space group has a header line comprising
space-separated values of:
* SG number
* number of lines of symmetry equivalents (`positions' in Int Tab) (N)
* number of lines of primitive equivalents (P)
* SG `short' name; subscripts are typed as-is and a prefix `-' represents
an overbar e.g. P21/m, P-1
* point group name; the Int. Tab. name is prefixed by `PG'; contrary to the
SG name, an overbar is represented by a trailing `bar' e.g. PG4bar3m
* crystal system
* possible comments about non-standard settings
Following are N lines of symmetry equivalents, of which the first P are the
primitive ones.
* Layout:
* The symmetry operator lines are limited to 80 characters
* The elements of operator triplets are separated by commas, and triplets
are separated by `*' or newline; the translations may be before or
after the coordinate e.g. `1/2+X' or `X+1/2'
* The header lines should start in the first column and the other lines be
indented (for ease of locating the headers)
* font84.ascii: Used directly by plot84lib.f. Previously: data for creating
the binary plot84 font file in $CCP4/lib with fontpack.
* atomsf.lib, atomsf_neutron.lib: formfactors for every known atom (for SFALL,
MLPHARE, VECREF). The format of the atomsf.lib file is as follows.
1) atom type
2) atomic number, number of electrons, `c' constant for the scattering
factor
3) a(1) ... a(4)
4) b(1) ... b(4)
5) f'(Cu) f"(Cu) f'(Mo) f"(Mo)
See the sfall documentation for the equations containing the as, bs and c.

1121
ccp4c/data/atomsf.lib Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,514 @@
AD - This file contains the following information:
AD - BEWARE: This file has a FIXED FORMAT!
AD This contains for each element:
AD ID
AD IWT IELEC C
AD A(5)
AD B(5)
AD CU(2) MO(2)
AD
AD
AD Formfactor: a1*exp(-b1*s*s) + a2*exp(-b2*s*s) + a3*exp(-b3*s*s)
AD + a4*exp(-b4*s*s) + a5*exp(-b4*s*s)
AD
AD This is the 5 Gaussian approximation
AD Ref: Int.Tab. vol C pp. 282-283 (Table 4.3.2.2) for values a1-a5, b1-b5
AD
AD ID atom identifier
AD IWT atomic weight
AD IELEC number of electrons
AD C it is 0
AD A(5) coefficient for structure factor calculation
AD B(5) coefficient for structure factor calculation
AD CU(2) these are 0-s
AD MO(2) these are 0-s
H
1 1 0.000000
0.034900 0.120100 0.197000 0.057300 0.119500
0.534700 3.586700 12.347100 18.952499 38.626900
0.000000 0.000000 0.000000 0.000000
He
2 2 0.000000
0.031700 0.083800 0.152600 0.133400 0.016400
0.250700 1.475100 4.493800 12.664600 31.165300
0.000000 0.000000 0.000000 0.000000
Li
3 3 0.000000
0.075000 0.224900 0.554800 1.495400 0.935400
0.386400 2.938300 15.382900 53.554501 138.733704
0.000000 0.000000 0.000000 0.000000
Be
4 4 0.000000
0.078000 0.221000 0.674000 1.386700 0.692500
0.313100 2.238100 10.151700 30.906099 78.327301
0.000000 0.000000 0.000000 0.000000
B
5 5 0.000000
0.090900 0.255100 0.773800 1.213600 0.460600
0.299500 2.115500 8.381600 24.129200 63.131401
0.000000 0.000000 0.000000 0.000000
C
6 6 0.000000
0.089300 0.256300 0.757000 1.048700 0.357500
0.246500 1.710000 6.409400 18.611300 50.252300
0.000000 0.000000 0.000000 0.000000
N
7 7 0.000000
0.102200 0.321900 0.798200 0.819700 0.171500
0.245100 1.748100 6.192500 17.389400 48.143101
0.000000 0.000000 0.000000 0.000000
O
8 8 0.000000
0.097400 0.292100 0.691000 0.699000 0.203900
0.206700 1.381500 4.694300 12.710500 32.472599
0.000000 0.000000 0.000000 0.000000
F
9 9 0.000000
0.108300 0.317500 0.648700 0.584600 0.142100
0.205700 1.343900 4.278800 11.393200 28.788099
0.000000 0.000000 0.000000 0.000000
Ne
10 10 0.000000
0.126900 0.353500 0.558200 0.467400 0.146000
0.220000 1.377900 4.020300 9.493400 23.127800
0.000000 0.000000 0.000000 0.000000
Na
11 11 0.000000
0.214200 0.685300 0.769200 1.658900 1.448200
0.333400 2.344600 10.083000 48.303699 138.270004
0.000000 0.000000 0.000000 0.000000
Mg
12 12 0.000000
0.231400 0.686600 0.967700 2.188200 1.133900
0.327800 2.272000 10.924100 39.289799 101.974800
0.000000 0.000000 0.000000 0.000000
Al
13 13 0.000000
0.239000 0.657300 1.201100 2.558600 1.231200
0.313800 2.106300 10.416300 34.455200 98.534401
0.000000 0.000000 0.000000 0.000000
Si
14 14 0.000000
0.251900 0.637200 1.379500 2.508200 1.050000
0.307500 2.017400 9.674600 29.374399 80.473198
0.000000 0.000000 0.000000 0.000000
P
15 15 0.000000
0.254800 0.610600 1.454100 2.320400 0.847700
0.290800 1.874000 8.517600 24.343399 63.299599
0.000000 0.000000 0.000000 0.000000
S
16 16 0.000000
0.249700 0.562800 1.389900 2.186500 0.771500
0.268100 1.671100 7.026700 19.537701 50.388802
0.000000 0.000000 0.000000 0.000000
Cl
17 17 0.000000
0.244300 0.539700 1.391900 2.019700 0.662100
0.246800 1.524200 6.153700 16.668699 42.308601
0.000000 0.000000 0.000000 0.000000
Ar
18 18 0.000000
0.238500 0.501700 1.342800 1.889900 0.607900
0.228900 1.369400 5.256100 14.092800 35.536098
0.000000 0.000000 0.000000 0.000000
K
19 19 0.000000
0.411500 1.403100 2.278400 2.674200 2.216200
0.370300 3.387400 13.102900 68.959198 194.432907
0.000000 0.000000 0.000000 0.000000
Ca
20 20 0.000000
0.405400 1.388000 2.160200 3.753200 2.206300
0.349900 3.099100 11.960800 53.935299 142.389206
0.000000 0.000000 0.000000 0.000000
Sc
21 21 0.000000
0.378700 1.218100 2.059400 3.261800 2.387000
0.313300 2.585600 9.581300 41.768799 116.728203
0.000000 0.000000 0.000000 0.000000
Ti
22 22 0.000000
0.382500 1.259800 2.000800 3.061700 2.069400
0.304000 2.486300 9.278300 39.075100 109.458298
0.000000 0.000000 0.000000 0.000000
V
23 23 0.000000
0.387600 1.275000 1.910900 2.831400 1.897900
0.296700 2.378000 8.798100 35.952801 101.720100
0.000000 0.000000 0.000000 0.000000
Cr
24 24 0.000000
0.404600 1.369600 1.894100 2.080000 1.219600
0.298600 2.395800 9.140600 37.470100 113.712097
0.000000 0.000000 0.000000 0.000000
Mn
25 25 0.000000
0.379600 1.209400 1.781500 2.542000 1.593700
0.269900 2.045500 7.472600 31.060400 91.562202
0.000000 0.000000 0.000000 0.000000
Fe
26 26 0.000000
0.394600 1.272500 1.703100 2.314000 1.479500
0.271700 2.044300 7.600700 29.971399 86.226501
0.000000 0.000000 0.000000 0.000000
Co
27 27 0.000000
0.411800 1.316100 1.649300 2.193000 1.283000
0.274200 2.037200 7.720500 29.968000 84.938301
0.000000 0.000000 0.000000 0.000000
Ni
28 28 0.000000
0.386000 1.176500 1.545100 2.073000 1.381400
0.247800 1.766000 6.310700 25.220400 74.314598
0.000000 0.000000 0.000000 0.000000
Cu
29 29 0.000000
0.431400 1.320800 1.523600 1.467100 0.856200
0.269400 1.922300 7.347400 28.989201 90.624603
0.000000 0.000000 0.000000 0.000000
Zn
30 30 0.000000
0.428800 1.264600 1.447200 1.829400 1.093400
0.259300 1.799800 6.750000 25.586000 73.528397
0.000000 0.000000 0.000000 0.000000
Ga
31 31 0.000000
0.481800 1.403200 1.656100 2.460500 1.105400
0.282500 1.978500 8.754600 32.523800 98.552299
0.000000 0.000000 0.000000 0.000000
Ge
32 32 0.000000
0.465500 1.301400 1.608800 2.699800 1.300300
0.264700 1.792600 7.607100 26.554100 77.523804
0.000000 0.000000 0.000000 0.000000
As
33 33 0.000000
0.451700 1.222900 1.585200 2.795800 1.263800
0.249300 1.643600 6.815400 22.368099 62.039001
0.000000 0.000000 0.000000 0.000000
Se
34 34 0.000000
0.447700 1.167800 1.584300 2.808700 1.195600
0.240500 1.544200 6.323100 19.461000 52.023300
0.000000 0.000000 0.000000 0.000000
Br
35 35 0.000000
0.479800 1.194800 1.869500 2.695300 0.820300
0.250400 1.596300 6.965300 19.849199 50.323299
0.000000 0.000000 0.000000 0.000000
Kr
36 36 0.000000
0.454600 1.099300 1.769600 2.706800 0.867200
0.230900 1.427900 5.944900 16.675200 42.224300
0.000000 0.000000 0.000000 0.000000
Rb
37 37 0.000000
1.016000 2.852800 3.546600 -7.780400 12.114800
0.485300 5.092500 25.785101 130.451508 138.677505
0.000000 0.000000 0.000000 0.000000
Sr
38 38 0.000000
0.670300 1.492600 3.336800 4.460000 3.150100
0.319000 2.228700 10.350400 52.329102 151.221603
0.000000 0.000000 0.000000 0.000000
Y
39 39 0.000000
0.689400 1.547400 3.245000 4.212600 2.976400
0.318900 2.290400 10.006200 44.077099 125.012001
0.000000 0.000000 0.000000 0.000000
Zr
40 40 0.000000
0.671900 1.468400 3.166800 3.955700 2.892000
0.303600 2.124900 8.923600 36.845798 108.204903
0.000000 0.000000 0.000000 0.000000
Nb
41 41 0.000000
0.612300 1.267700 3.034800 3.384100 2.368300
0.270900 1.768300 7.248900 27.946501 98.562401
0.000000 0.000000 0.000000 0.000000
Mo
42 42 0.000000
0.677300 1.479800 3.178800 3.082400 1.838400
0.292000 2.060600 8.112900 30.533600 100.065804
0.000000 0.000000 0.000000 0.000000
Tc
43 43 0.000000
0.708200 1.639200 3.199300 3.432700 1.871100
0.297600 2.210600 8.524600 33.145599 96.637703
0.000000 0.000000 0.000000 0.000000
Ru
44 44 0.000000
0.673500 1.493400 3.096600 2.725400 1.559700
0.277300 1.971600 7.324900 26.689100 90.558098
0.000000 0.000000 0.000000 0.000000
Rh
45 45 0.000000
0.641300 1.369000 2.985400 2.695200 1.543300
0.258000 1.772100 6.385400 23.254900 85.151703
0.000000 0.000000 0.000000 0.000000
Pd
46 46 0.000000
0.590400 1.177500 2.651900 2.287500 0.868900
0.232400 1.501900 5.159100 15.542800 46.821301
0.000000 0.000000 0.000000 0.000000
Ag
47 47 0.000000
0.637700 1.379000 2.829400 2.363100 1.455300
0.246600 1.697400 5.765600 20.094299 76.737198
0.000000 0.000000 0.000000 0.000000
Cd
48 48 0.000000
0.636400 1.424700 2.780200 2.597300 1.788600
0.240700 1.682300 5.658800 20.721901 69.110901
0.000000 0.000000 0.000000 0.000000
In
49 49 0.000000
0.676800 1.658900 2.774000 3.183500 2.132600
0.252200 1.854500 6.293600 25.145700 84.544800
0.000000 0.000000 0.000000 0.000000
Sn
50 50 0.000000
0.722400 1.961000 2.716100 3.560300 1.897200
0.265100 2.060400 7.301100 27.549299 81.334900
0.000000 0.000000 0.000000 0.000000
Sb
51 51 0.000000
0.710600 1.924700 2.614900 3.832200 1.889900
0.256200 1.964600 6.885200 24.764799 68.916801
0.000000 0.000000 0.000000 0.000000
Te
52 52 0.000000
0.694700 1.869000 2.535600 4.001300 1.895500
0.245900 1.854200 6.441100 22.173000 59.220600
0.000000 0.000000 0.000000 0.000000
I
53 53 0.000000
0.704700 1.948400 2.594000 4.152600 1.505700
0.245500 1.863800 6.763900 21.800699 56.439499
0.000000 0.000000 0.000000 0.000000
Xe
54 54 0.000000
0.673700 1.790800 2.412900 4.210000 1.705800
0.230500 1.689000 5.821800 18.392799 47.249599
0.000000 0.000000 0.000000 0.000000
Cs
55 55 0.000000
1.270400 3.801800 5.661800 0.920500 4.810500
0.435600 4.205800 23.434200 136.778305 171.756104
0.000000 0.000000 0.000000 0.000000
Ba
56 56 0.000000
0.904900 2.607600 4.849800 5.160300 4.738800
0.306600 2.436300 12.182100 54.613499 161.997803
0.000000 0.000000 0.000000 0.000000
La
57 57 0.000000
0.840500 2.386300 4.613900 5.151400 4.794900
0.279100 2.141000 10.340000 41.914799 132.020401
0.000000 0.000000 0.000000 0.000000
Ce
58 58 0.000000
0.855100 2.391500 4.577200 5.027800 4.511800
0.280500 2.120000 10.180800 42.063301 130.989304
0.000000 0.000000 0.000000 0.000000
Pr
59 59 0.000000
0.909600 2.531300 4.526600 4.637600 4.369000
0.293900 2.247100 10.826600 48.884201 147.602005
0.000000 0.000000 0.000000 0.000000
Nd
60 60 0.000000
0.880700 2.418300 4.444800 4.685800 4.172500
0.280200 2.083600 10.035700 47.450600 146.997604
0.000000 0.000000 0.000000 0.000000
Pm
61 61 0.000000
0.947100 2.546300 4.352300 4.478900 3.908000
0.297700 2.227600 10.576200 49.361900 145.358002
0.000000 0.000000 0.000000 0.000000
Sm
62 62 0.000000
0.969900 2.583700 4.277800 4.457500 3.598500
0.300300 2.244700 10.648700 50.799400 146.417892
0.000000 0.000000 0.000000 0.000000
Eu
63 63 0.000000
0.869400 2.241300 3.919600 3.969400 4.549800
0.265300 1.859000 8.399800 36.739700 125.708900
0.000000 0.000000 0.000000 0.000000
Gd
64 64 0.000000
0.967300 2.470200 4.114800 4.497200 3.209900
0.290900 2.101400 9.706700 43.426998 125.947403
0.000000 0.000000 0.000000 0.000000
Tb
65 65 0.000000
0.932500 2.367300 3.879100 3.967400 3.799600
0.276100 1.951100 8.929600 41.593700 131.012207
0.000000 0.000000 0.000000 0.000000
Dy
66 66 0.000000
0.950500 2.370500 3.821800 4.047100 3.445100
0.277300 1.946900 8.886200 43.093800 133.139603
0.000000 0.000000 0.000000 0.000000
Ho
67 67 0.000000
0.924800 2.242800 3.618200 3.791000 3.791200
0.266000 1.818300 7.965500 33.112900 101.813904
0.000000 0.000000 0.000000 0.000000
Er
68 68 0.000000
1.037300 2.482400 3.655800 3.892500 3.005600
0.294400 2.079700 9.415600 45.805599 132.772003
0.000000 0.000000 0.000000 0.000000
Tm
69 69 0.000000
1.007500 2.378700 3.544000 3.693200 3.175900
0.281600 1.948600 8.716200 41.841999 125.031998
0.000000 0.000000 0.000000 0.000000
Yb
70 70 0.000000
1.034700 2.391100 3.461900 3.655600 3.005200
0.285500 1.967900 8.761900 42.330399 125.649902
0.000000 0.000000 0.000000 0.000000
Lu
71 71 0.000000
0.992700 2.243600 3.355400 3.781300 3.099400
0.270100 1.807300 7.811200 34.484901 103.352600
0.000000 0.000000 0.000000 0.000000
Hf
72 72 0.000000
1.029500 2.291100 3.411000 3.949700 2.492500
0.276100 1.862500 8.096100 34.271198 98.529503
0.000000 0.000000 0.000000 0.000000
Ta
73 73 0.000000
1.019000 2.229100 3.409700 3.925200 2.267900
0.269400 1.796200 7.694400 31.094200 91.108902
0.000000 0.000000 0.000000 0.000000
W
74 74 0.000000
0.985300 2.116700 3.357000 3.798100 2.279800
0.256900 1.674500 7.009800 26.923401 81.390999
0.000000 0.000000 0.000000 0.000000
Re
75 75 0.000000
0.991400 2.085800 3.453100 3.881200 1.852600
0.254800 1.651800 6.884500 26.723400 81.721497
0.000000 0.000000 0.000000 0.000000
Os
76 76 0.000000
0.981300 2.032200 3.366500 3.623500 1.974100
0.248700 1.597300 6.473700 23.281700 70.925400
0.000000 0.000000 0.000000 0.000000
Ir
77 77 0.000000
1.019400 2.064500 3.442500 3.491400 1.697600
0.255400 1.647500 6.596600 23.226900 70.027199
0.000000 0.000000 0.000000 0.000000
Pt
78 78 0.000000
0.914800 1.809600 3.213400 3.295300 1.575400
0.226300 1.381300 5.324300 17.598700 60.017101
0.000000 0.000000 0.000000 0.000000
Au
79 79 0.000000
0.967400 1.891600 3.399300 3.052400 1.260700
0.235800 1.471200 5.675800 18.711901 61.528599
0.000000 0.000000 0.000000 0.000000
Hg
80 80 0.000000
1.003300 1.946900 3.439600 3.154800 1.418000
0.241300 1.529800 5.800900 19.452000 60.575298
0.000000 0.000000 0.000000 0.000000
Tl
81 81 0.000000
1.068900 2.103800 3.603900 3.492700 1.828300
0.254000 1.671500 6.350900 23.153099 78.709900
0.000000 0.000000 0.000000 0.000000
Pb
82 82 0.000000
1.089100 2.186700 3.616000 3.803100 1.899400
0.255200 1.717400 6.513100 23.917000 74.703903
0.000000 0.000000 0.000000 0.000000
Bi
83 83 0.000000
1.100700 2.230600 3.568900 4.154900 2.038200
0.254600 1.735100 6.494800 23.646400 70.377998
0.000000 0.000000 0.000000 0.000000
Po
84 84 0.000000
1.156800 2.435300 3.645900 4.406400 1.717900
0.264800 1.878600 7.174900 25.176600 69.282097
0.000000 0.000000 0.000000 0.000000
At
85 85 0.000000
1.090900 2.197600 3.383100 4.670000 2.127700
0.246600 1.670700 6.019700 20.765699 57.266300
0.000000 0.000000 0.000000 0.000000
Rn
86 86 0.000000
1.075600 2.163000 3.317800 4.885200 2.048900
0.240200 1.616900 5.764400 19.456800 52.500900
0.000000 0.000000 0.000000 0.000000
Fr
87 87 0.000000
1.428200 3.508100 5.676700 4.196400 3.894600
0.318300 2.688900 13.481600 54.386600 200.832108
0.000000 0.000000 0.000000 0.000000
Ra
88 88 0.000000
1.312700 3.124300 5.298800 5.389100 5.413300
0.288700 2.289700 10.827600 43.538898 145.610901
0.000000 0.000000 0.000000 0.000000
Ac
89 89 0.000000
1.312800 3.102100 5.338500 5.961100 4.756200
0.286100 2.250900 10.528700 41.779598 128.297302
0.000000 0.000000 0.000000 0.000000
Th
90 90 0.000000
1.255300 2.917800 5.086200 6.120600 4.712200
0.270100 2.063600 9.305100 34.597698 107.919998
0.000000 0.000000 0.000000 0.000000
Pa
91 91 0.000000
1.321800 3.144400 5.437100 5.644400 4.010700
0.282700 2.225000 10.245400 41.116199 124.444901
0.000000 0.000000 0.000000 0.000000
U
92 92 0.000000
1.338200 3.204300 5.455800 5.483900 3.634200
0.283800 2.245200 10.251900 41.725101 124.902298
0.000000 0.000000 0.000000 0.000000
Np
93 93 0.000000
1.519300 4.005300 6.532700 -0.140200 6.748900
0.321300 2.820600 14.887800 68.910301 81.725700
0.000000 0.000000 0.000000 0.000000
Pu
94 94 0.000000
1.351700 3.293700 5.321300 4.646600 3.571400
0.281300 2.241800 9.995200 42.793900 132.173904
0.000000 0.000000 0.000000 0.000000
Am
95 95 0.000000
1.213500 2.796200 4.754500 4.573100 4.478600
0.248300 1.843700 7.542100 29.384100 112.457901
0.000000 0.000000 0.000000 0.000000
Cm
96 96 0.000000
1.293700 3.110000 5.039300 4.754600 3.503100
0.263800 2.034100 8.710100 35.299198 109.497200
0.000000 0.000000 0.000000 0.000000
Bk
97 97 0.000000
1.291500 3.102300 4.930900 4.600900 3.466100
0.261100 2.002300 8.437700 34.155899 105.891098
0.000000 0.000000 0.000000 0.000000
Cf
98 98 0.000000
1.208900 2.739100 4.348200 4.004700 4.649700
0.242100 1.748700 6.726200 23.215300 80.310799
0.000000 0.000000 0.000000 0.000000

File diff suppressed because it is too large Load Diff

5160
ccp4c/data/font84.ascii Normal file

File diff suppressed because it is too large Load Diff

16
ccp4c/data/fontpack.f Normal file
View File

@@ -0,0 +1,16 @@
INTEGER*2 IFHT(150,4),IFSTRT(150,4),IFWID(150,4),IFX0(150,4),
+ IFY0(150,4),LENGF(150,4)
INTEGER*1 NFONTS(4,3000,4)
INTEGER IUNITF
DATA IUNITF/11/
C
C
IFAIL = 0
ITEROP = -IUNITF
CALL CCPDPN (-10,'font84.ascii','OLD','F',0,IFAIL)
CALL CCPDPN (ITEROP,'font84.dat','NEW','U',80,IFAIL)
READ(10,2000) IFSTRT,LENGF,IFX0,IFY0,IFWID,IFHT,NFONTS
2000 FORMAT(10I5)
WRITE (IUNITF) IFSTRT,LENGF,IFX0,IFY0,IFWID,IFHT,NFONTS
CLOSE (UNIT=IUNITF)
END

23
ccp4c/data/fontunpack.for Normal file
View File

@@ -0,0 +1,23 @@
INTEGER*2 IFHT,IFSTRT,IFWID,IFX0,IFY0,LENGF
BYTE NFONTS
INTEGER IUNITF
COMMON /PINOUT/LUNIN,LUNOUT
COMMON /PLT$FNT/IFSTRT(150,4),LENGF(150,4),IFX0(150,4),
+ IFY0(150,4),IFWID(150,4),IFHT(150,4),NFONTS(4,3000,4)
DATA IUNITF/89/
C
C
IFAIL = 0
ITEROP = -IUNITF
OPEN(UNIT=10,FILE='font84.ascii',STATUS='NEW')
CALL CCPDPN (ITEROP,'font84.dat','OLD','U',80,IFAIL)
IF (IFAIL.NE.0) THEN
WRITE (6,FMT=6000)
6000 FORMAT (' Unable to read fonts - FILE=PUBLIC_FONT84')
ELSE
READ (IUNITF) IFSTRT,LENGF,IFX0,IFY0,IFWID,IFHT,NFONTS
WRITE(10,2000) IFSTRT,LENGF,IFX0,IFY0,IFWID,IFHT,NFONTS
2000 FORMAT(10I10)
CLOSE (UNIT=IUNITF)
ENDIF
END

14552
ccp4c/data/syminfo.lib Normal file

File diff suppressed because it is too large Load Diff

4920
ccp4c/data/symop.lib Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -47,7 +47,8 @@ Directly included in the repository:
* Cpp-http library for HTTP - see [github.com/yhirose/cpp-httplib](https://github.com/yhirose/cpp-httplib)
* Base64 decoder/encoder - see [gist.github.com/tomykaira](https://gist.github.com/tomykaira/f0fd86b6c73063283afe550bc5d77594)
* GEMMI library by Global Phasing - see [github.com/project-gemmi/gemmi](https://github.com/project-gemmi/gemmi)
* CCP4c library 8.0.0 by CCP4 - see [ccp4.ac.uk](https://www.ccp4.ac.uk/)
For license check LICENSE file in respective directory

View File

@@ -1,2 +1,2 @@
ADD_LIBRARY(JFJochScaleMerge ScaleAndMerge.cpp ScaleAndMerge.h FrenchWilson.cpp FrenchWilson.h)
TARGET_LINK_LIBRARIES(JFJochScaleMerge Ceres::ceres Eigen3::Eigen JFJochCommon)
ADD_LIBRARY(JFJochScaleMerge ScaleAndMerge.cpp ScaleAndMerge.h FrenchWilson.cpp FrenchWilson.h MtzWriter.h MtzWriter.cpp)
TARGET_LINK_LIBRARIES(JFJochScaleMerge Ceres::ceres Eigen3::Eigen JFJochCommon ccp4c)

View File

@@ -0,0 +1,234 @@
// SPDX-FileCopyrightText: 2025 Paul Scherrer Institute
// SPDX-License-Identifier: GPL-3.0-only
#include "MtzWriter.h"
#include <cstring>
#include <cmath>
#include <vector>
#include <stdexcept>
// CCP4 C library — lives inside the CMtz namespace when included from C++
#include "../../ccp4c/ccp4/cmtzlib.h"
#include "../../ccp4c/ccp4/csymlib.h"
#include "../../ccp4c/ccp4/mtzdata.h"
MtzWriteOptions::MtzWriteOptions(const DiffractionExperiment& experiment,
const std::optional<UnitCell>& cell_override) {
// Unit cell: prefer explicit override, then experiment setting, else default
if (cell_override.has_value()) {
cell = cell_override.value();
} else if (experiment.GetUnitCell().has_value()) {
cell = experiment.GetUnitCell().value();
}
// Space group
auto sg = experiment.GetGemmiSpaceGroup();
if (sg) {
spacegroup_number = sg->ccp4;
spacegroup_name = sg->xhm();
}
// Wavelength
wavelength = experiment.GetWavelength_A();
// Sample name → crystal name
auto sample = experiment.GetSampleName();
if (!sample.empty())
crystal_name = sample;
// File prefix → project name
auto prefix = experiment.GetFilePrefix();
if (!prefix.empty())
project_name = prefix;
}
namespace {
/// Helper: create a fresh in-memory MTZ structure, set up symmetry,
/// crystal, dataset, and the requested columns.
/// Returns {mtz, columns} or throws on failure.
struct MtzSetup {
CMtz::MTZ* mtz = nullptr;
std::vector<CMtz::MTZCOL*> cols;
};
MtzSetup CreateMtzSkeleton(const MtzWriteOptions& opts,
const char labels[][31],
const char types[][3],
int ncol) {
using namespace CMtz;
// Allocate empty MTZ (0 crystals initially)
int nset_zero = 0;
MTZ* mtz = MtzMalloc(0, &nset_zero);
if (!mtz)
throw std::runtime_error("MtzMalloc failed");
mtz->refs_in_memory = 1; // we build everything in memory, then write
// Title
ccp4_lwtitl(mtz, opts.title.c_str(), 0);
// Symmetry: use CCP4 spacegroup lookup
CCP4SPG* spg = ccp4spg_load_by_ccp4_num(opts.spacegroup_number);
if (!spg) {
// Fallback to P1
spg = ccp4spg_load_by_ccp4_num(1);
}
if (spg) {
const int nsym = spg->nsymop;
const int nsymp = spg->nsymop_prim;
float rsymx[192][4][4];
std::memset(rsymx, 0, sizeof(rsymx));
for (int i = 0; i < nsym && i < 192; ++i) {
for (int r = 0; r < 3; ++r) {
for (int c = 0; c < 3; ++c)
rsymx[i][r][c] = static_cast<float>(spg->symop[i].rot[r][c]);
rsymx[i][r][3] = static_cast<float>(spg->symop[i].trn[r]);
}
rsymx[i][3][3] = 1.0f;
}
char ltypex[2] = {spg->symbol_old[0], '\0'};
char spgrnx[MAXSPGNAMELENGTH + 1];
std::strncpy(spgrnx, spg->symbol_xHM, MAXSPGNAMELENGTH);
spgrnx[MAXSPGNAMELENGTH] = '\0';
char pgnamx[MAXPGNAMELENGTH + 1];
std::strncpy(pgnamx, spg->pgname, MAXPGNAMELENGTH);
pgnamx[MAXPGNAMELENGTH] = '\0';
ccp4_lwsymm(mtz, nsym, nsymp, rsymx,
ltypex, spg->spg_ccp4_num, spgrnx, pgnamx);
ccp4spg_free(&spg);
}
// Crystal + dataset
float cell[6] = {
static_cast<float>(opts.cell.a),
static_cast<float>(opts.cell.b),
static_cast<float>(opts.cell.c),
static_cast<float>(opts.cell.alpha),
static_cast<float>(opts.cell.beta),
static_cast<float>(opts.cell.gamma)
};
MTZXTAL* xtal = MtzAddXtal(mtz,
opts.crystal_name.c_str(),
opts.project_name.c_str(),
cell);
if (!xtal) {
MtzFree(mtz);
throw std::runtime_error("MtzAddXtal failed");
}
MTZSET* set = MtzAddDataset(mtz, xtal,
opts.dataset_name.c_str(),
opts.wavelength);
if (!set) {
MtzFree(mtz);
throw std::runtime_error("MtzAddDataset failed");
}
// Add columns
MtzSetup result;
result.mtz = mtz;
result.cols.resize(ncol, nullptr);
for (int i = 0; i < ncol; ++i) {
result.cols[i] = MtzAddColumn(mtz, set, labels[i], types[i]);
if (!result.cols[i]) {
MtzFree(mtz);
throw std::runtime_error(std::string("MtzAddColumn failed for ") + labels[i]);
}
}
return result;
}
} // namespace
bool WriteMtzIntensities(const std::string& filename,
const std::vector<MergedReflection>& merged,
const MtzWriteOptions& opts) {
using namespace CMtz;
if (merged.empty())
return false;
constexpr int NCOL = 5;
const char labels[NCOL][31] = {"H", "K", "L", "IMEAN", "SIGIMEAN"};
const char types[NCOL][3] = {"H", "H", "H", "J", "Q"};
MtzSetup setup;
try {
setup = CreateMtzSkeleton(opts, labels, types, NCOL);
} catch (...) {
return false;
}
// Write reflections (1-indexed)
const int nref = static_cast<int>(merged.size());
for (int i = 0; i < nref; ++i) {
float adata[NCOL];
adata[0] = static_cast<float>(merged[i].h);
adata[1] = static_cast<float>(merged[i].k);
adata[2] = static_cast<float>(merged[i].l);
adata[3] = static_cast<float>(merged[i].I);
adata[4] = std::isfinite(static_cast<float>(merged[i].sigma))
? static_cast<float>(merged[i].sigma)
: 0.0f;
ccp4_lwrefl(setup.mtz, adata, setup.cols.data(), NCOL, i + 1);
}
// Write to disk
setup.mtz->nref = nref;
int ok = MtzPut(setup.mtz, filename.c_str());
MtzFree(setup.mtz);
return ok != 0;
}
bool WriteMtzAmplitudes(const std::string& filename,
const std::vector<FrenchWilsonReflection>& fw,
const MtzWriteOptions& opts) {
using namespace CMtz;
if (fw.empty())
return false;
constexpr int NCOL = 7;
const char labels[NCOL][31] = {"H", "K", "L", "FP", "SIGFP", "IMEAN", "SIGIMEAN"};
const char types[NCOL][3] = {"H", "H", "H", "F", "Q", "J", "Q"};
MtzSetup setup;
try {
setup = CreateMtzSkeleton(opts, labels, types, NCOL);
} catch (...) {
return false;
}
const int nref = static_cast<int>(fw.size());
for (int i = 0; i < nref; ++i) {
float adata[NCOL];
adata[0] = static_cast<float>(fw[i].h);
adata[1] = static_cast<float>(fw[i].k);
adata[2] = static_cast<float>(fw[i].l);
adata[3] = static_cast<float>(fw[i].F);
adata[4] = static_cast<float>(fw[i].sigmaF);
adata[5] = static_cast<float>(fw[i].I);
adata[6] = std::isfinite(static_cast<float>(fw[i].sigmaI))
? static_cast<float>(fw[i].sigmaI)
: 0.0f;
ccp4_lwrefl(setup.mtz, adata, setup.cols.data(), NCOL, i + 1);
}
setup.mtz->nref = nref;
int ok = MtzPut(setup.mtz, filename.c_str());
MtzFree(setup.mtz);
return ok != 0;
}

View File

@@ -0,0 +1,57 @@
// SPDX-FileCopyrightText: 2025 Paul Scherrer Institute
// SPDX-License-Identifier: GPL-3.0-only
#pragma once
#include <string>
#include <optional>
#include "ScaleAndMerge.h"
#include "FrenchWilson.h"
#include "../../common/UnitCell.h"
#include "../../common/DiffractionExperiment.h"
/// Options controlling what goes into the MTZ file
struct MtzWriteOptions {
/// Unit cell parameters (required for a valid MTZ)
UnitCell cell = {50.0, 50.0, 50.0, 90.0, 90.0, 90.0};
/// Space group number (1 = P1 if unknown)
int spacegroup_number = 1;
/// Space group name (e.g. "P 21 21 21")
std::string spacegroup_name = "P 1";
/// Dataset metadata
std::string project_name = "JFJoch";
std::string crystal_name = "crystal";
std::string dataset_name = "dataset";
/// Wavelength in Angstroms
float wavelength = 1.0f;
/// Title line
std::string title = "JFJoch scaled data";
/// Construct default options
MtzWriteOptions() = default;
/// Construct from a DiffractionExperiment, optionally overriding the
/// unit cell (e.g. with the lattice found by the rotation indexer).
explicit MtzWriteOptions(const DiffractionExperiment& experiment,
const std::optional<UnitCell>& cell_override = std::nullopt);
};
/// Write merged intensities (ScaleMergeResult) to an MTZ file.
/// Columns: H K L IMEAN SIGIMEAN
/// Returns true on success.
bool WriteMtzIntensities(const std::string& filename,
const std::vector<MergedReflection>& merged,
const MtzWriteOptions& opts);
/// Write French-Wilson amplitudes to an MTZ file.
/// Columns: H K L FP SIGFP IMEAN SIGIMEAN
/// Returns true on success.
bool WriteMtzAmplitudes(const std::string& filename,
const std::vector<FrenchWilsonReflection>& fw,
const MtzWriteOptions& opts);

View File

@@ -25,6 +25,7 @@
#include "../receiver/JFJochReceiverPlots.h"
#include "../compression/JFJochCompressor.h"
#include "../image_analysis/scale_merge/FrenchWilson.h"
#include "../image_analysis/scale_merge/MtzWriter.h"
void print_usage(Logger &logger) {
logger.Info("Usage ./jfjoch_analysis {<options>} <input.h5>");
@@ -426,10 +427,9 @@ int main(int argc, char **argv) {
}
}
// --- French-Wilson: convert I → F ---
{
FrenchWilsonOptions fw_opts;
fw_opts.acentric = true; // typical for MX
fw_opts.acentric = true;
fw_opts.num_shells = 20;
auto fw = FrenchWilson(scale_result->merged, fw_opts);
@@ -448,6 +448,30 @@ int main(int argc, char **argv) {
fw_file.close();
logger.Info("French-Wilson: wrote {} amplitudes to {}", fw.size(), fw_path);
}
// --- Write MTZ files ---
MtzWriteOptions mtz_opts(experiment,
rotation_indexer_ret.has_value()
? std::optional<UnitCell>(rotation_indexer_ret->lattice.GetUnitCell())
: std::nullopt);
// Intensities MTZ
{
const std::string mtz_i_path = output_prefix + "_scaled.mtz";
if (WriteMtzIntensities(mtz_i_path, scale_result->merged, mtz_opts))
logger.Info("Wrote {} reflections to {}", scale_result->merged.size(), mtz_i_path);
else
logger.Error("Failed to write {}", mtz_i_path);
}
// Amplitudes MTZ (French-Wilson)
{
const std::string mtz_f_path = output_prefix + "_amplitudes.mtz";
if (WriteMtzAmplitudes(mtz_f_path, fw, mtz_opts))
logger.Info("Wrote {} reflections to {}", fw.size(), mtz_f_path);
else
logger.Error("Failed to write {}", mtz_f_path);
}
}
} else {
logger.Warning("Scaling skipped — too few reflections accumulated (need >= 20)");