diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..fe41843
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,8 @@
+build/
+dist/
+docSRC/_build/
+
+*.c
+*.cpp
+*.so
+*.pyc
diff --git a/COPYING b/COPYING
new file mode 100644
index 0000000..94a9ed0
--- /dev/null
+++ b/COPYING
@@ -0,0 +1,674 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc.
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The GNU General Public License is a free, copyleft license for
+software and other kinds of works.
+
+ The licenses for most software and other practical works are designed
+to take away your freedom to share and change the works. By contrast,
+the GNU General Public License is intended to guarantee your freedom to
+share and change all versions of a program--to make sure it remains free
+software for all its users. We, the Free Software Foundation, use the
+GNU General Public License for most of our software; it applies also to
+any other work released this way by its authors. You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+them if you wish), that you receive source code or can get it if you
+want it, that you can change the software or use pieces of it in new
+free programs, and that you know you can do these things.
+
+ To protect your rights, we need to prevent others from denying you
+these rights or asking you to surrender the rights. Therefore, you have
+certain responsibilities if you distribute copies of the software, or if
+you modify it: responsibilities to respect the freedom of others.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must pass on to the recipients the same
+freedoms that you received. You must make sure that they, too, receive
+or can get the source code. And you must show them these terms so they
+know their rights.
+
+ Developers that use the GNU GPL protect your rights with two steps:
+(1) assert copyright on the software, and (2) offer you this License
+giving you legal permission to copy, distribute and/or modify it.
+
+ For the developers' and authors' protection, the GPL clearly explains
+that there is no warranty for this free software. For both users' and
+authors' sake, the GPL requires that modified versions be marked as
+changed, so that their problems will not be attributed erroneously to
+authors of previous versions.
+
+ Some devices are designed to deny users access to install or run
+modified versions of the software inside them, although the manufacturer
+can do so. This is fundamentally incompatible with the aim of
+protecting users' freedom to change the software. The systematic
+pattern of such abuse occurs in the area of products for individuals to
+use, which is precisely where it is most unacceptable. Therefore, we
+have designed this version of the GPL to prohibit the practice for those
+products. If such problems arise substantially in other domains, we
+stand ready to extend this provision to those domains in future versions
+of the GPL, as needed to protect the freedom of users.
+
+ Finally, every program is threatened constantly by software patents.
+States should not allow patents to restrict development and use of
+software on general-purpose computers, but in those that do, we wish to
+avoid the special danger that patents applied to a free program could
+make it effectively proprietary. To prevent this, the GPL assures that
+patents cannot be used to render the program non-free.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ TERMS AND CONDITIONS
+
+ 0. Definitions.
+
+ "This License" refers to version 3 of the GNU General Public License.
+
+ "Copyright" also means copyright-like laws that apply to other kinds of
+works, such as semiconductor masks.
+
+ "The Program" refers to any copyrightable work licensed under this
+License. Each licensee is addressed as "you". "Licensees" and
+"recipients" may be individuals or organizations.
+
+ To "modify" a work means to copy from or adapt all or part of the work
+in a fashion requiring copyright permission, other than the making of an
+exact copy. The resulting work is called a "modified version" of the
+earlier work or a work "based on" the earlier work.
+
+ A "covered work" means either the unmodified Program or a work based
+on the Program.
+
+ To "propagate" a work means to do anything with it that, without
+permission, would make you directly or secondarily liable for
+infringement under applicable copyright law, except executing it on a
+computer or modifying a private copy. Propagation includes copying,
+distribution (with or without modification), making available to the
+public, and in some countries other activities as well.
+
+ To "convey" a work means any kind of propagation that enables other
+parties to make or receive copies. Mere interaction with a user through
+a computer network, with no transfer of a copy, is not conveying.
+
+ An interactive user interface displays "Appropriate Legal Notices"
+to the extent that it includes a convenient and prominently visible
+feature that (1) displays an appropriate copyright notice, and (2)
+tells the user that there is no warranty for the work (except to the
+extent that warranties are provided), that licensees may convey the
+work under this License, and how to view a copy of this License. If
+the interface presents a list of user commands or options, such as a
+menu, a prominent item in the list meets this criterion.
+
+ 1. Source Code.
+
+ The "source code" for a work means the preferred form of the work
+for making modifications to it. "Object code" means any non-source
+form of a work.
+
+ A "Standard Interface" means an interface that either is an official
+standard defined by a recognized standards body, or, in the case of
+interfaces specified for a particular programming language, one that
+is widely used among developers working in that language.
+
+ The "System Libraries" of an executable work include anything, other
+than the work as a whole, that (a) is included in the normal form of
+packaging a Major Component, but which is not part of that Major
+Component, and (b) serves only to enable use of the work with that
+Major Component, or to implement a Standard Interface for which an
+implementation is available to the public in source code form. A
+"Major Component", in this context, means a major essential component
+(kernel, window system, and so on) of the specific operating system
+(if any) on which the executable work runs, or a compiler used to
+produce the work, or an object code interpreter used to run it.
+
+ The "Corresponding Source" for a work in object code form means all
+the source code needed to generate, install, and (for an executable
+work) run the object code and to modify the work, including scripts to
+control those activities. However, it does not include the work's
+System Libraries, or general-purpose tools or generally available free
+programs which are used unmodified in performing those activities but
+which are not part of the work. For example, Corresponding Source
+includes interface definition files associated with source files for
+the work, and the source code for shared libraries and dynamically
+linked subprograms that the work is specifically designed to require,
+such as by intimate data communication or control flow between those
+subprograms and other parts of the work.
+
+ The Corresponding Source need not include anything that users
+can regenerate automatically from other parts of the Corresponding
+Source.
+
+ The Corresponding Source for a work in source code form is that
+same work.
+
+ 2. Basic Permissions.
+
+ All rights granted under this License are granted for the term of
+copyright on the Program, and are irrevocable provided the stated
+conditions are met. This License explicitly affirms your unlimited
+permission to run the unmodified Program. The output from running a
+covered work is covered by this License only if the output, given its
+content, constitutes a covered work. This License acknowledges your
+rights of fair use or other equivalent, as provided by copyright law.
+
+ You may make, run and propagate covered works that you do not
+convey, without conditions so long as your license otherwise remains
+in force. You may convey covered works to others for the sole purpose
+of having them make modifications exclusively for you, or provide you
+with facilities for running those works, provided that you comply with
+the terms of this License in conveying all material for which you do
+not control copyright. Those thus making or running the covered works
+for you must do so exclusively on your behalf, under your direction
+and control, on terms that prohibit them from making any copies of
+your copyrighted material outside their relationship with you.
+
+ Conveying under any other circumstances is permitted solely under
+the conditions stated below. Sublicensing is not allowed; section 10
+makes it unnecessary.
+
+ 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
+
+ No covered work shall be deemed part of an effective technological
+measure under any applicable law fulfilling obligations under article
+11 of the WIPO copyright treaty adopted on 20 December 1996, or
+similar laws prohibiting or restricting circumvention of such
+measures.
+
+ When you convey a covered work, you waive any legal power to forbid
+circumvention of technological measures to the extent such circumvention
+is effected by exercising rights under this License with respect to
+the covered work, and you disclaim any intention to limit operation or
+modification of the work as a means of enforcing, against the work's
+users, your or third parties' legal rights to forbid circumvention of
+technological measures.
+
+ 4. Conveying Verbatim Copies.
+
+ You may convey verbatim copies of the Program's source code as you
+receive it, in any medium, provided that you conspicuously and
+appropriately publish on each copy an appropriate copyright notice;
+keep intact all notices stating that this License and any
+non-permissive terms added in accord with section 7 apply to the code;
+keep intact all notices of the absence of any warranty; and give all
+recipients a copy of this License along with the Program.
+
+ You may charge any price or no price for each copy that you convey,
+and you may offer support or warranty protection for a fee.
+
+ 5. Conveying Modified Source Versions.
+
+ You may convey a work based on the Program, or the modifications to
+produce it from the Program, in the form of source code under the
+terms of section 4, provided that you also meet all of these conditions:
+
+ a) The work must carry prominent notices stating that you modified
+ it, and giving a relevant date.
+
+ b) The work must carry prominent notices stating that it is
+ released under this License and any conditions added under section
+ 7. This requirement modifies the requirement in section 4 to
+ "keep intact all notices".
+
+ c) You must license the entire work, as a whole, under this
+ License to anyone who comes into possession of a copy. This
+ License will therefore apply, along with any applicable section 7
+ additional terms, to the whole of the work, and all its parts,
+ regardless of how they are packaged. This License gives no
+ permission to license the work in any other way, but it does not
+ invalidate such permission if you have separately received it.
+
+ d) If the work has interactive user interfaces, each must display
+ Appropriate Legal Notices; however, if the Program has interactive
+ interfaces that do not display Appropriate Legal Notices, your
+ work need not make them do so.
+
+ A compilation of a covered work with other separate and independent
+works, which are not by their nature extensions of the covered work,
+and which are not combined with it such as to form a larger program,
+in or on a volume of a storage or distribution medium, is called an
+"aggregate" if the compilation and its resulting copyright are not
+used to limit the access or legal rights of the compilation's users
+beyond what the individual works permit. Inclusion of a covered work
+in an aggregate does not cause this License to apply to the other
+parts of the aggregate.
+
+ 6. Conveying Non-Source Forms.
+
+ You may convey a covered work in object code form under the terms
+of sections 4 and 5, provided that you also convey the
+machine-readable Corresponding Source under the terms of this License,
+in one of these ways:
+
+ a) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by the
+ Corresponding Source fixed on a durable physical medium
+ customarily used for software interchange.
+
+ b) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by a
+ written offer, valid for at least three years and valid for as
+ long as you offer spare parts or customer support for that product
+ model, to give anyone who possesses the object code either (1) a
+ copy of the Corresponding Source for all the software in the
+ product that is covered by this License, on a durable physical
+ medium customarily used for software interchange, for a price no
+ more than your reasonable cost of physically performing this
+ conveying of source, or (2) access to copy the
+ Corresponding Source from a network server at no charge.
+
+ c) Convey individual copies of the object code with a copy of the
+ written offer to provide the Corresponding Source. This
+ alternative is allowed only occasionally and noncommercially, and
+ only if you received the object code with such an offer, in accord
+ with subsection 6b.
+
+ d) Convey the object code by offering access from a designated
+ place (gratis or for a charge), and offer equivalent access to the
+ Corresponding Source in the same way through the same place at no
+ further charge. You need not require recipients to copy the
+ Corresponding Source along with the object code. If the place to
+ copy the object code is a network server, the Corresponding Source
+ may be on a different server (operated by you or a third party)
+ that supports equivalent copying facilities, provided you maintain
+ clear directions next to the object code saying where to find the
+ Corresponding Source. Regardless of what server hosts the
+ Corresponding Source, you remain obligated to ensure that it is
+ available for as long as needed to satisfy these requirements.
+
+ e) Convey the object code using peer-to-peer transmission, provided
+ you inform other peers where the object code and Corresponding
+ Source of the work are being offered to the general public at no
+ charge under subsection 6d.
+
+ A separable portion of the object code, whose source code is excluded
+from the Corresponding Source as a System Library, need not be
+included in conveying the object code work.
+
+ A "User Product" is either (1) a "consumer product", which means any
+tangible personal property which is normally used for personal, family,
+or household purposes, or (2) anything designed or sold for incorporation
+into a dwelling. In determining whether a product is a consumer product,
+doubtful cases shall be resolved in favor of coverage. For a particular
+product received by a particular user, "normally used" refers to a
+typical or common use of that class of product, regardless of the status
+of the particular user or of the way in which the particular user
+actually uses, or expects or is expected to use, the product. A product
+is a consumer product regardless of whether the product has substantial
+commercial, industrial or non-consumer uses, unless such uses represent
+the only significant mode of use of the product.
+
+ "Installation Information" for a User Product means any methods,
+procedures, authorization keys, or other information required to install
+and execute modified versions of a covered work in that User Product from
+a modified version of its Corresponding Source. The information must
+suffice to ensure that the continued functioning of the modified object
+code is in no case prevented or interfered with solely because
+modification has been made.
+
+ If you convey an object code work under this section in, or with, or
+specifically for use in, a User Product, and the conveying occurs as
+part of a transaction in which the right of possession and use of the
+User Product is transferred to the recipient in perpetuity or for a
+fixed term (regardless of how the transaction is characterized), the
+Corresponding Source conveyed under this section must be accompanied
+by the Installation Information. But this requirement does not apply
+if neither you nor any third party retains the ability to install
+modified object code on the User Product (for example, the work has
+been installed in ROM).
+
+ The requirement to provide Installation Information does not include a
+requirement to continue to provide support service, warranty, or updates
+for a work that has been modified or installed by the recipient, or for
+the User Product in which it has been modified or installed. Access to a
+network may be denied when the modification itself materially and
+adversely affects the operation of the network or violates the rules and
+protocols for communication across the network.
+
+ Corresponding Source conveyed, and Installation Information provided,
+in accord with this section must be in a format that is publicly
+documented (and with an implementation available to the public in
+source code form), and must require no special password or key for
+unpacking, reading or copying.
+
+ 7. Additional Terms.
+
+ "Additional permissions" are terms that supplement the terms of this
+License by making exceptions from one or more of its conditions.
+Additional permissions that are applicable to the entire Program shall
+be treated as though they were included in this License, to the extent
+that they are valid under applicable law. If additional permissions
+apply only to part of the Program, that part may be used separately
+under those permissions, but the entire Program remains governed by
+this License without regard to the additional permissions.
+
+ When you convey a copy of a covered work, you may at your option
+remove any additional permissions from that copy, or from any part of
+it. (Additional permissions may be written to require their own
+removal in certain cases when you modify the work.) You may place
+additional permissions on material, added by you to a covered work,
+for which you have or can give appropriate copyright permission.
+
+ Notwithstanding any other provision of this License, for material you
+add to a covered work, you may (if authorized by the copyright holders of
+that material) supplement the terms of this License with terms:
+
+ a) Disclaiming warranty or limiting liability differently from the
+ terms of sections 15 and 16 of this License; or
+
+ b) Requiring preservation of specified reasonable legal notices or
+ author attributions in that material or in the Appropriate Legal
+ Notices displayed by works containing it; or
+
+ c) Prohibiting misrepresentation of the origin of that material, or
+ requiring that modified versions of such material be marked in
+ reasonable ways as different from the original version; or
+
+ d) Limiting the use for publicity purposes of names of licensors or
+ authors of the material; or
+
+ e) Declining to grant rights under trademark law for use of some
+ trade names, trademarks, or service marks; or
+
+ f) Requiring indemnification of licensors and authors of that
+ material by anyone who conveys the material (or modified versions of
+ it) with contractual assumptions of liability to the recipient, for
+ any liability that these contractual assumptions directly impose on
+ those licensors and authors.
+
+ All other non-permissive additional terms are considered "further
+restrictions" within the meaning of section 10. If the Program as you
+received it, or any part of it, contains a notice stating that it is
+governed by this License along with a term that is a further
+restriction, you may remove that term. If a license document contains
+a further restriction but permits relicensing or conveying under this
+License, you may add to a covered work material governed by the terms
+of that license document, provided that the further restriction does
+not survive such relicensing or conveying.
+
+ If you add terms to a covered work in accord with this section, you
+must place, in the relevant source files, a statement of the
+additional terms that apply to those files, or a notice indicating
+where to find the applicable terms.
+
+ Additional terms, permissive or non-permissive, may be stated in the
+form of a separately written license, or stated as exceptions;
+the above requirements apply either way.
+
+ 8. Termination.
+
+ You may not propagate or modify a covered work except as expressly
+provided under this License. Any attempt otherwise to propagate or
+modify it is void, and will automatically terminate your rights under
+this License (including any patent licenses granted under the third
+paragraph of section 11).
+
+ However, if you cease all violation of this License, then your
+license from a particular copyright holder is reinstated (a)
+provisionally, unless and until the copyright holder explicitly and
+finally terminates your license, and (b) permanently, if the copyright
+holder fails to notify you of the violation by some reasonable means
+prior to 60 days after the cessation.
+
+ Moreover, your license from a particular copyright holder is
+reinstated permanently if the copyright holder notifies you of the
+violation by some reasonable means, this is the first time you have
+received notice of violation of this License (for any work) from that
+copyright holder, and you cure the violation prior to 30 days after
+your receipt of the notice.
+
+ Termination of your rights under this section does not terminate the
+licenses of parties who have received copies or rights from you under
+this License. If your rights have been terminated and not permanently
+reinstated, you do not qualify to receive new licenses for the same
+material under section 10.
+
+ 9. Acceptance Not Required for Having Copies.
+
+ You are not required to accept this License in order to receive or
+run a copy of the Program. Ancillary propagation of a covered work
+occurring solely as a consequence of using peer-to-peer transmission
+to receive a copy likewise does not require acceptance. However,
+nothing other than this License grants you permission to propagate or
+modify any covered work. These actions infringe copyright if you do
+not accept this License. Therefore, by modifying or propagating a
+covered work, you indicate your acceptance of this License to do so.
+
+ 10. Automatic Licensing of Downstream Recipients.
+
+ Each time you convey a covered work, the recipient automatically
+receives a license from the original licensors, to run, modify and
+propagate that work, subject to this License. You are not responsible
+for enforcing compliance by third parties with this License.
+
+ An "entity transaction" is a transaction transferring control of an
+organization, or substantially all assets of one, or subdividing an
+organization, or merging organizations. If propagation of a covered
+work results from an entity transaction, each party to that
+transaction who receives a copy of the work also receives whatever
+licenses to the work the party's predecessor in interest had or could
+give under the previous paragraph, plus a right to possession of the
+Corresponding Source of the work from the predecessor in interest, if
+the predecessor has it or can get it with reasonable efforts.
+
+ You may not impose any further restrictions on the exercise of the
+rights granted or affirmed under this License. For example, you may
+not impose a license fee, royalty, or other charge for exercise of
+rights granted under this License, and you may not initiate litigation
+(including a cross-claim or counterclaim in a lawsuit) alleging that
+any patent claim is infringed by making, using, selling, offering for
+sale, or importing the Program or any portion of it.
+
+ 11. Patents.
+
+ A "contributor" is a copyright holder who authorizes use under this
+License of the Program or a work on which the Program is based. The
+work thus licensed is called the contributor's "contributor version".
+
+ A contributor's "essential patent claims" are all patent claims
+owned or controlled by the contributor, whether already acquired or
+hereafter acquired, that would be infringed by some manner, permitted
+by this License, of making, using, or selling its contributor version,
+but do not include claims that would be infringed only as a
+consequence of further modification of the contributor version. For
+purposes of this definition, "control" includes the right to grant
+patent sublicenses in a manner consistent with the requirements of
+this License.
+
+ Each contributor grants you a non-exclusive, worldwide, royalty-free
+patent license under the contributor's essential patent claims, to
+make, use, sell, offer for sale, import and otherwise run, modify and
+propagate the contents of its contributor version.
+
+ In the following three paragraphs, a "patent license" is any express
+agreement or commitment, however denominated, not to enforce a patent
+(such as an express permission to practice a patent or covenant not to
+sue for patent infringement). To "grant" such a patent license to a
+party means to make such an agreement or commitment not to enforce a
+patent against the party.
+
+ If you convey a covered work, knowingly relying on a patent license,
+and the Corresponding Source of the work is not available for anyone
+to copy, free of charge and under the terms of this License, through a
+publicly available network server or other readily accessible means,
+then you must either (1) cause the Corresponding Source to be so
+available, or (2) arrange to deprive yourself of the benefit of the
+patent license for this particular work, or (3) arrange, in a manner
+consistent with the requirements of this License, to extend the patent
+license to downstream recipients. "Knowingly relying" means you have
+actual knowledge that, but for the patent license, your conveying the
+covered work in a country, or your recipient's use of the covered work
+in a country, would infringe one or more identifiable patents in that
+country that you have reason to believe are valid.
+
+ If, pursuant to or in connection with a single transaction or
+arrangement, you convey, or propagate by procuring conveyance of, a
+covered work, and grant a patent license to some of the parties
+receiving the covered work authorizing them to use, propagate, modify
+or convey a specific copy of the covered work, then the patent license
+you grant is automatically extended to all recipients of the covered
+work and works based on it.
+
+ A patent license is "discriminatory" if it does not include within
+the scope of its coverage, prohibits the exercise of, or is
+conditioned on the non-exercise of one or more of the rights that are
+specifically granted under this License. You may not convey a covered
+work if you are a party to an arrangement with a third party that is
+in the business of distributing software, under which you make payment
+to the third party based on the extent of your activity of conveying
+the work, and under which the third party grants, to any of the
+parties who would receive the covered work from you, a discriminatory
+patent license (a) in connection with copies of the covered work
+conveyed by you (or copies made from those copies), or (b) primarily
+for and in connection with specific products or compilations that
+contain the covered work, unless you entered into that arrangement,
+or that patent license was granted, prior to 28 March 2007.
+
+ Nothing in this License shall be construed as excluding or limiting
+any implied license or other defenses to infringement that may
+otherwise be available to you under applicable patent law.
+
+ 12. No Surrender of Others' Freedom.
+
+ If conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot convey a
+covered work so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you may
+not convey it at all. For example, if you agree to terms that obligate you
+to collect a royalty for further conveying from those to whom you convey
+the Program, the only way you could satisfy both those terms and this
+License would be to refrain entirely from conveying the Program.
+
+ 13. Use with the GNU Affero General Public License.
+
+ Notwithstanding any other provision of this License, you have
+permission to link or combine any covered work with a work licensed
+under version 3 of the GNU Affero General Public License into a single
+combined work, and to convey the resulting work. The terms of this
+License will continue to apply to the part which is the covered work,
+but the special requirements of the GNU Affero General Public License,
+section 13, concerning interaction through a network will apply to the
+combination as such.
+
+ 14. Revised Versions of this License.
+
+ The Free Software Foundation may publish revised and/or new versions of
+the GNU General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+ Each version is given a distinguishing version number. If the
+Program specifies that a certain numbered version of the GNU General
+Public License "or any later version" applies to it, you have the
+option of following the terms and conditions either of that numbered
+version or of any later version published by the Free Software
+Foundation. If the Program does not specify a version number of the
+GNU General Public License, you may choose any version ever published
+by the Free Software Foundation.
+
+ If the Program specifies that a proxy can decide which future
+versions of the GNU General Public License can be used, that proxy's
+public statement of acceptance of a version permanently authorizes you
+to choose that version for the Program.
+
+ Later license versions may give you additional or different
+permissions. However, no additional obligations are imposed on any
+author or copyright holder as a result of your choosing to follow a
+later version.
+
+ 15. Disclaimer of Warranty.
+
+ THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
+APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
+HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
+OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
+THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
+IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
+ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+ 16. Limitation of Liability.
+
+ IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
+THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
+GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
+USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
+DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
+PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
+EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGES.
+
+ 17. Interpretation of Sections 15 and 16.
+
+ If the disclaimer of warranty and limitation of liability provided
+above cannot be given local legal effect according to their terms,
+reviewing courts shall apply local law that most closely approximates
+an absolute waiver of all civil liability in connection with the
+Program, unless a warranty or assumption of liability accompanies a
+copy of the Program in return for a fee.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+state the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+
+ Copyright (C)
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+
+Also add information on how to contact you by electronic and paper mail.
+
+ If the program does terminal interaction, make it output a short
+notice like this when it starts in an interactive mode:
+
+ Copyright (C)
+ This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, your program's commands
+might be different; for a GUI interface, you would use an "about box".
+
+ You should also get your employer (if you work as a programmer) or school,
+if any, to sign a "copyright disclaimer" for the program, if necessary.
+For more information on this, and how to apply and follow the GNU GPL, see
+.
+
+ The GNU General Public License does not permit incorporating your program
+into proprietary programs. If your program is a subroutine library, you
+may consider it more useful to permit linking proprietary applications with
+the library. If this is what you want to do, use the GNU Lesser General
+Public License instead of this License. But first, please read
+.
diff --git a/INSTALL b/INSTALL
new file mode 100644
index 0000000..5231a89
--- /dev/null
+++ b/INSTALL
@@ -0,0 +1,50 @@
+#-----------------------------------------------------------------------
+#Copyright 2013 Centrum Wiskunde & Informatica, Amsterdam
+#
+#Author: Daniel M. Pelt
+#Contact: D.M.Pelt@cwi.nl
+#Website: http://dmpelt.github.io/pyastratoolbox/
+#
+#
+#This file is part of the Python interface to the
+#All Scale Tomographic Reconstruction Antwerp Toolbox ("ASTRA Toolbox").
+#
+#The Python interface to the ASTRA Toolbox 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.
+#
+#The Python interface to the ASTRA Toolbox 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 the Python interface to the ASTRA Toolbox. If not, see .
+#
+#-----------------------------------------------------------------------
+
+To use the Python interface, you need the All Scale Tomographic Reconstruction Antwerp Toolbox:
+https://code.google.com/p/astra-toolbox/
+Please install the ASTRA toolbox first.
+
+Other requirements: Cython (version >= 0.13), NumPy
+
+Use install.sh to install the Python interface to the ASTRA toolbox.
+Only run install.sh as ./install.sh in the base directory of the interface code.
+You need write permission to the $PYTHON_PATH directory.
+We recommend using a Python virtualenv if root access is impossible.
+The Python interface to the ASTRA Toolbox uses Python version 2.
+
+Usage: ./install.sh [-i astra_include_path] [-l astra_library_path] [-p python_executable_path] [-c cuda_path]
+
+ -i astra_include_path: specify path to astra header files (without trailing astra/) (Optional)
+ -l astra_library_path: specify parent path of astra library file (Optional)
+ -p python_executable_path: specify path to python executable (Optional)
+ -c cuda_path: path to CUDA (Optional)
+ -h: print this help (Optional)
+
+Note that the paths only have to be specified if they are not already in your $LD_LIBRARY_PATH, etcetera.
+
+When compiling with CUDA, the astra_include_path should be set to the 'include' directory of the ASTRA toolbox
+source.
diff --git a/LICENSE b/LICENSE
new file mode 120000
index 0000000..d24842f
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1 @@
+COPYING
\ No newline at end of file
diff --git a/MANIFEST b/MANIFEST
new file mode 100644
index 0000000..1a6ba04
--- /dev/null
+++ b/MANIFEST
@@ -0,0 +1,116 @@
+# file GENERATED by distutils, do NOT edit
+COPYING
+INSTALL
+README
+builder.py
+install.sh
+astra/ASTRAProjector.py
+astra/PyAlgorithmFactory.pxd
+astra/PyAlgorithmManager.pxd
+astra/PyData2DManager.pxd
+astra/PyData3DManager.pxd
+astra/PyIncludes.pxd
+astra/PyMatrixManager.pxd
+astra/PyProjector2DFactory.pxd
+astra/PyProjector2DManager.pxd
+astra/PyXMLDocument.pxd
+astra/__init__.py
+astra/algorithm.py
+astra/algorithm_c.cpp
+astra/algorithm_c.pyx
+astra/astra.py
+astra/astra_c.cpp
+astra/astra_c.pyx
+astra/creators.py
+astra/data2d.py
+astra/data2d_c.cpp
+astra/data2d_c.pyx
+astra/data3d.py
+astra/data3d_c.cpp
+astra/data3d_c.pyx
+astra/extrautils.c
+astra/extrautils.pyx
+astra/functions.py
+astra/matlab.py
+astra/matrix.py
+astra/matrix_c.cpp
+astra/matrix_c.pyx
+astra/projector.py
+astra/projector_c.cpp
+astra/projector_c.pyx
+astra/utils.cpp
+astra/utils.pxd
+astra/utils.pyx
+doc/.buildinfo
+doc/ASTRAProjector.html
+doc/algorithm.html
+doc/creators.html
+doc/data2d.html
+doc/data3d.html
+doc/functions.html
+doc/genindex.html
+doc/index.html
+doc/matlab.html
+doc/matrix.html
+doc/objects.inv
+doc/projector.html
+doc/py-modindex.html
+doc/search.html
+doc/searchindex.js
+doc/_modules/index.html
+doc/_modules/astra/ASTRAProjector.html
+doc/_modules/astra/algorithm.html
+doc/_modules/astra/creators.html
+doc/_modules/astra/data2d.html
+doc/_modules/astra/data3d.html
+doc/_modules/astra/functions.html
+doc/_modules/astra/matlab.html
+doc/_modules/astra/matrix.html
+doc/_modules/astra/projector.html
+doc/_sources/ASTRAProjector.txt
+doc/_sources/algorithm.txt
+doc/_sources/creators.txt
+doc/_sources/data2d.txt
+doc/_sources/data3d.txt
+doc/_sources/functions.txt
+doc/_sources/index.txt
+doc/_sources/matlab.txt
+doc/_sources/matrix.txt
+doc/_sources/projector.txt
+doc/_static/ajax-loader.gif
+doc/_static/basic.css
+doc/_static/comment-bright.png
+doc/_static/comment-close.png
+doc/_static/comment.png
+doc/_static/default.css
+doc/_static/doctools.js
+doc/_static/down-pressed.png
+doc/_static/down.png
+doc/_static/file.png
+doc/_static/jquery.js
+doc/_static/minus.png
+doc/_static/plus.png
+doc/_static/pygments.css
+doc/_static/searchtools.js
+doc/_static/sidebar.js
+doc/_static/underscore.js
+doc/_static/up-pressed.png
+doc/_static/up.png
+doc/_static/websupport.js
+examples/phantom.mat
+examples/s001_sinogram_par2d.py
+examples/s002_data2d.py
+examples/s003_gpu_reconstruction.py
+examples/s004_cpu_reconstruction.py
+examples/s005_3d_geometry.py
+examples/s006_3d_data.py
+examples/s007_3d_reconstruction.py
+examples/s008_gpu_selection.py
+examples/s009_projection_matrix.py
+examples/s010_supersampling.py
+examples/s011_object_info.py
+examples/s012_masks.py
+examples/s013_constraints.py
+examples/s014_FBP.py
+examples/s015_fp_bp.py
+examples/s016_plots.py
diff --git a/MANIFEST.in b/MANIFEST.in
new file mode 100644
index 0000000..a0cdf3a
--- /dev/null
+++ b/MANIFEST.in
@@ -0,0 +1,7 @@
+include INSTALL
+include COPYING
+include install.sh
+recursive-include examples *.py *.mat
+recursive-include astra *.pyx *.pxd
+recursive-include doc *
+
diff --git a/README b/README
new file mode 120000
index 0000000..842bf0e
--- /dev/null
+++ b/README
@@ -0,0 +1 @@
+INSTALL
\ No newline at end of file
diff --git a/astra/ASTRAProjector.py b/astra/ASTRAProjector.py
new file mode 100644
index 0000000..7553a7c
--- /dev/null
+++ b/astra/ASTRAProjector.py
@@ -0,0 +1,139 @@
+#-----------------------------------------------------------------------
+#Copyright 2013 Centrum Wiskunde & Informatica, Amsterdam
+#
+#Author: Daniel M. Pelt
+#Contact: D.M.Pelt@cwi.nl
+#Website: http://dmpelt.github.io/pyastratoolbox/
+#
+#
+#This file is part of the Python interface to the
+#All Scale Tomographic Reconstruction Antwerp Toolbox ("ASTRA Toolbox").
+#
+#The Python interface to the ASTRA Toolbox 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.
+#
+#The Python interface to the ASTRA Toolbox 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 the Python interface to the ASTRA Toolbox. If not, see .
+#
+#-----------------------------------------------------------------------
+
+
+import creators as ac
+import math
+import data2d
+
+
+class ASTRAProjector2DTranspose():
+ """Implements the ``proj.T`` functionality.
+
+ Do not use directly, since it can be accessed as member ``.T`` of
+ an :class:`ASTRAProjector2D` object.
+
+ """
+ def __init__(self, parentProj):
+ self.parentProj = parentProj
+
+ def __mul__(self, data):
+ return self.parentProj.backProject(data)
+
+
+class ASTRAProjector2D(object):
+ """Helps with various common ASTRA Toolbox 2D operations.
+
+ This class can perform several often used toolbox operations, such as:
+
+ * Forward projecting
+ * Back projecting
+ * Reconstructing
+
+ Note that this class has a some computational overhead, because it
+ copies a lot of data. If you use many repeated operations, directly
+ using the PyAstraToolbox methods directly is faster.
+
+ You can use this class as an abstracted weight matrix :math:`W`: multiplying an instance
+ ``proj`` of this class by an image results in a forward projection of the image, and multiplying
+ ``proj.T`` by a sinogram results in a backprojection of the sinogram::
+
+ proj = ASTRAProjector2D(...)
+ fp = proj*image
+ bp = proj.T*sinogram
+
+ :param proj_geom: The projection geometry.
+ :type proj_geom: :class:`dict`
+ :param vol_geom: The volume geometry.
+ :type vol_geom: :class:`dict`
+ :param proj_type: Projector type, such as ``'line'``, ``'linear'``, ...
+ :type proj_type: :class:`string`
+ :param useCUDA: If ``True``, use CUDA for calculations, when possible.
+ :type useCUDA: :class:`bool`
+ """
+
+ def __init__(self, proj_geom, vol_geom, proj_type, useCUDA=False):
+ self.vol_geom = vol_geom
+ self.recSize = vol_geom['GridColCount']
+ self.angles = proj_geom['ProjectionAngles']
+ self.nDet = proj_geom['DetectorCount']
+ nexpow = int(pow(2, math.ceil(math.log(2 * self.nDet, 2))))
+ self.filterSize = nexpow / 2 + 1
+ self.nProj = self.angles.shape[0]
+ self.proj_geom = proj_geom
+ self.proj_id = ac.create_projector(proj_type, proj_geom, vol_geom)
+ self.useCUDA = useCUDA
+ self.T = ASTRAProjector2DTranspose(self)
+
+ def backProject(self, data):
+ """Backproject a sinogram.
+
+ :param data: The sinogram data or ID.
+ :type data: :class:`numpy.ndarray` or :class:`int`
+ :returns: :class:`numpy.ndarray` -- The backprojection.
+
+ """
+ vol_id, vol = ac.create_backprojection(
+ data, self.proj_id, self.useCUDA, True)
+ data2d.delete(vol_id)
+ return vol
+
+ def forwardProject(self, data):
+ """Forward project an image.
+
+ :param data: The image data or ID.
+ :type data: :class:`numpy.ndarray` or :class:`int`
+ :returns: :class:`numpy.ndarray` -- The forward projection.
+
+ """
+ sin_id, sino = ac.create_sino(data, self.proj_id, self.useCUDA, True)
+ data2d.delete(sin_id)
+ return sino
+
+ def reconstruct(self, data, method, **kwargs):
+ """Reconstruct an image from a sinogram.
+
+ :param data: The sinogram data or ID.
+ :type data: :class:`numpy.ndarray` or :class:`int`
+ :param method: Name of the reconstruction algorithm.
+ :type method: :class:`string`
+ :param kwargs: Additional named parameters to pass to :func:`astra.creators.create_reconstruction`.
+ :returns: :class:`numpy.ndarray` -- The reconstruction.
+
+ Example of a SIRT reconstruction using CUDA::
+
+ proj = ASTRAProjector2D(...)
+ rec = proj.reconstruct(sinogram,'SIRT_CUDA',iterations=1000)
+
+ """
+ kwargs['returnData'] = True
+ rec_id, rec = ac.create_reconstruction(
+ method, self.proj_id, data, **kwargs)
+ data2d.delete(rec_id)
+ return rec
+
+ def __mul__(self, data):
+ return self.forwardProject(data)
diff --git a/astra/PyAlgorithmFactory.pxd b/astra/PyAlgorithmFactory.pxd
new file mode 100644
index 0000000..e235f00
--- /dev/null
+++ b/astra/PyAlgorithmFactory.pxd
@@ -0,0 +1,36 @@
+#-----------------------------------------------------------------------
+#Copyright 2013 Centrum Wiskunde & Informatica, Amsterdam
+#
+#Author: Daniel M. Pelt
+#Contact: D.M.Pelt@cwi.nl
+#Website: http://dmpelt.github.io/pyastratoolbox/
+#
+#
+#This file is part of the Python interface to the
+#All Scale Tomographic Reconstruction Antwerp Toolbox ("ASTRA Toolbox").
+#
+#The Python interface to the ASTRA Toolbox 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.
+#
+#The Python interface to the ASTRA Toolbox 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 the Python interface to the ASTRA Toolbox. If not, see .
+#
+#-----------------------------------------------------------------------
+from libcpp.string cimport string
+from libcpp cimport bool
+from PyIncludes cimport *
+
+cdef extern from "astra/AstraObjectFactory.h" namespace "astra":
+ cdef cppclass CAlgorithmFactory:
+ CAlgorithmFactory()
+ CAlgorithm *create(string)
+
+cdef extern from "astra/AstraObjectFactory.h" namespace "astra::CAlgorithmFactory":
+ cdef CAlgorithmFactory* getSingletonPtr()
diff --git a/astra/PyAlgorithmManager.pxd b/astra/PyAlgorithmManager.pxd
new file mode 100644
index 0000000..9a1bc17
--- /dev/null
+++ b/astra/PyAlgorithmManager.pxd
@@ -0,0 +1,40 @@
+#-----------------------------------------------------------------------
+#Copyright 2013 Centrum Wiskunde & Informatica, Amsterdam
+#
+#Author: Daniel M. Pelt
+#Contact: D.M.Pelt@cwi.nl
+#Website: http://dmpelt.github.io/pyastratoolbox/
+#
+#
+#This file is part of the Python interface to the
+#All Scale Tomographic Reconstruction Antwerp Toolbox ("ASTRA Toolbox").
+#
+#The Python interface to the ASTRA Toolbox 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.
+#
+#The Python interface to the ASTRA Toolbox 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 the Python interface to the ASTRA Toolbox. If not, see .
+#
+#-----------------------------------------------------------------------
+from libcpp.string cimport string
+from libcpp cimport bool
+from PyIncludes cimport *
+
+cdef extern from "astra/AstraObjectManager.h" namespace "astra":
+ cdef cppclass CAlgorithmManager:
+ int store(CAlgorithm *)
+ CAlgorithm * get(int)
+ void remove(int)
+ void clear()
+ string info()
+
+cdef extern from "astra/AstraObjectManager.h" namespace "astra::CAlgorithmManager":
+ cdef CAlgorithmManager* getSingletonPtr()
+
diff --git a/astra/PyData2DManager.pxd b/astra/PyData2DManager.pxd
new file mode 100644
index 0000000..3ea4e3b
--- /dev/null
+++ b/astra/PyData2DManager.pxd
@@ -0,0 +1,39 @@
+#-----------------------------------------------------------------------
+#Copyright 2013 Centrum Wiskunde & Informatica, Amsterdam
+#
+#Author: Daniel M. Pelt
+#Contact: D.M.Pelt@cwi.nl
+#Website: http://dmpelt.github.io/pyastratoolbox/
+#
+#
+#This file is part of the Python interface to the
+#All Scale Tomographic Reconstruction Antwerp Toolbox ("ASTRA Toolbox").
+#
+#The Python interface to the ASTRA Toolbox 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.
+#
+#The Python interface to the ASTRA Toolbox 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 the Python interface to the ASTRA Toolbox. If not, see .
+#
+#-----------------------------------------------------------------------
+from libcpp.string cimport string
+
+from PyIncludes cimport *
+
+cdef extern from "astra/AstraObjectManager.h" namespace "astra":
+ cdef cppclass CData2DManager:
+ string info()
+ void clear()
+ void remove(int i)
+ int store(CFloat32Data2D *)
+ CFloat32Data2D * get(int i)
+
+cdef extern from "astra/AstraObjectManager.h" namespace "astra::CData2DManager":
+ cdef CData2DManager* getSingletonPtr()
diff --git a/astra/PyData3DManager.pxd b/astra/PyData3DManager.pxd
new file mode 100644
index 0000000..048b0c5
--- /dev/null
+++ b/astra/PyData3DManager.pxd
@@ -0,0 +1,39 @@
+#-----------------------------------------------------------------------
+#Copyright 2013 Centrum Wiskunde & Informatica, Amsterdam
+#
+#Author: Daniel M. Pelt
+#Contact: D.M.Pelt@cwi.nl
+#Website: http://dmpelt.github.io/pyastratoolbox/
+#
+#
+#This file is part of the Python interface to the
+#All Scale Tomographic Reconstruction Antwerp Toolbox ("ASTRA Toolbox").
+#
+#The Python interface to the ASTRA Toolbox 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.
+#
+#The Python interface to the ASTRA Toolbox 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 the Python interface to the ASTRA Toolbox. If not, see .
+#
+#-----------------------------------------------------------------------
+from libcpp.string cimport string
+
+from PyIncludes cimport *
+
+cdef extern from "astra/AstraObjectManager.h" namespace "astra":
+ cdef cppclass CData3DManager:
+ string info()
+ void clear()
+ void remove(int i)
+ int store(CFloat32Data3D *)
+ CFloat32Data3D * get(int i)
+
+cdef extern from "astra/AstraObjectManager.h" namespace "astra::CData3DManager":
+ cdef CData3DManager* getSingletonPtr()
diff --git a/astra/PyIncludes.pxd b/astra/PyIncludes.pxd
new file mode 100644
index 0000000..154495c
--- /dev/null
+++ b/astra/PyIncludes.pxd
@@ -0,0 +1,215 @@
+#-----------------------------------------------------------------------
+#Copyright 2013 Centrum Wiskunde & Informatica, Amsterdam
+#
+#Author: Daniel M. Pelt
+#Contact: D.M.Pelt@cwi.nl
+#Website: http://dmpelt.github.io/pyastratoolbox/
+#
+#
+#This file is part of the Python interface to the
+#All Scale Tomographic Reconstruction Antwerp Toolbox ("ASTRA Toolbox").
+#
+#The Python interface to the ASTRA Toolbox 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.
+#
+#The Python interface to the ASTRA Toolbox 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 the Python interface to the ASTRA Toolbox. If not, see .
+#
+#-----------------------------------------------------------------------
+from libcpp cimport bool
+from libcpp.string cimport string
+from PyXMLDocument cimport XMLNode
+
+cdef extern from "astra/Globals.h" namespace "astra":
+ ctypedef float float32
+ ctypedef double float64
+ ctypedef unsigned short int uint16
+ ctypedef signed short int sint16
+ ctypedef unsigned char uchar8
+ ctypedef signed char schar8
+ ctypedef int int32
+ ctypedef short int int16
+
+cdef extern from "astra/Config.h" namespace "astra":
+ cdef cppclass Config:
+ Config()
+ XMLNode *self
+
+cdef extern from "astra/VolumeGeometry2D.h" namespace "astra":
+ cdef cppclass CVolumeGeometry2D:
+ bool initialize(Config)
+ int getGridColCount()
+ int getGridRowCount()
+ int getGridTotCount()
+ float32 getWindowLengthX()
+ float32 getWindowLengthY()
+ float32 getWindowArea()
+ float32 getPixelLengthX()
+ float32 getPixelLengthY()
+ float32 getPixelArea()
+ float32 getWindowMinX()
+ float32 getWindowMinY()
+ float32 getWindowMaxX()
+ float32 getWindowMaxY()
+
+
+cdef extern from "astra/Float32VolumeData2D.h" namespace "astra":
+ cdef cppclass CFloat32VolumeData2D:
+ CFloat32VolumeData2D(CVolumeGeometry2D*)
+ CVolumeGeometry2D * getGeometry()
+ int getWidth()
+ int getHeight()
+ void changeGeometry(CVolumeGeometry2D*)
+
+
+
+cdef extern from "astra/ProjectionGeometry2D.h" namespace "astra":
+ cdef cppclass CProjectionGeometry2D:
+ CProjectionGeometry2D()
+ bool initialize(Config)
+ int getDetectorCount()
+ int getProjectionAngleCount()
+ bool isOfType(string)
+ float32 getProjectionAngle(int)
+ float32 getDetectorWidth()
+
+cdef extern from "astra/Float32Data2D.h" namespace "astra::CFloat32Data2D":
+ cdef enum EDataType:
+ BASE,PROJECTION,VOLUME
+
+cdef extern from "astra/Float32Data2D.h" namespace "astra":
+ cdef cppclass CFloat32Data2D:
+ bool isInitialized()
+ int getSize()
+ float32 *getData()
+ float32 **getData2D()
+ int getWidth()
+ int getHeight()
+ EDataType getType()
+
+
+
+
+cdef extern from "astra/SparseMatrixProjectionGeometry2D.h" namespace "astra":
+ cdef cppclass CSparseMatrixProjectionGeometry2D:
+ CSparseMatrixProjectionGeometry2D()
+
+cdef extern from "astra/FanFlatProjectionGeometry2D.h" namespace "astra":
+ cdef cppclass CFanFlatProjectionGeometry2D:
+ CFanFlatProjectionGeometry2D()
+
+cdef extern from "astra/FanFlatVecProjectionGeometry2D.h" namespace "astra":
+ cdef cppclass CFanFlatVecProjectionGeometry2D:
+ CFanFlatVecProjectionGeometry2D()
+
+cdef extern from "astra/ParallelProjectionGeometry2D.h" namespace "astra":
+ cdef cppclass CParallelProjectionGeometry2D:
+ CParallelProjectionGeometry2D()
+
+
+cdef extern from "astra/Float32ProjectionData2D.h" namespace "astra":
+ cdef cppclass CFloat32ProjectionData2D:
+ CFloat32ProjectionData2D(CProjectionGeometry2D*)
+ CProjectionGeometry2D * getGeometry()
+ void changeGeometry(CProjectionGeometry2D*)
+ int getDetectorCount()
+ int getAngleCount()
+
+cdef extern from "astra/Algorithm.h" namespace "astra":
+ cdef cppclass CAlgorithm:
+ bool initialize(Config)
+ void run(int)
+ bool isInitialized()
+
+cdef extern from "astra/ReconstructionAlgorithm2D.h" namespace "astra":
+ cdef cppclass CReconstructionAlgorithm2D:
+ bool getResidualNorm(float32&)
+
+cdef extern from "astra/Projector2D.h" namespace "astra":
+ cdef cppclass CProjector2D:
+ bool isInitialized()
+ CProjectionGeometry2D* getProjectionGeometry()
+ CVolumeGeometry2D* getVolumeGeometry()
+ CSparseMatrix* getMatrix()
+
+cdef extern from "astra/SparseMatrix.h" namespace "astra":
+ cdef cppclass CSparseMatrix:
+ CSparseMatrix(unsigned int,unsigned int,unsigned long)
+ unsigned int m_iWidth
+ unsigned int m_iHeight
+ unsigned long m_lSize
+ bool isInitialized()
+ float32* m_pfValues
+ unsigned int* m_piColIndices
+ unsigned long* m_plRowStarts
+
+cdef extern from "astra/Float32Data3DMemory.h" namespace "astra":
+ cdef cppclass CFloat32Data3DMemory:
+ CFloat32Data3DMemory()
+ bool isInitialized()
+ int getSize()
+ int getWidth()
+ int getHeight()
+ int getDepth()
+ void updateStatistics()
+ float32 *getData()
+ float32 ***getData3D()
+
+
+cdef extern from "astra/VolumeGeometry3D.h" namespace "astra":
+ cdef cppclass CVolumeGeometry3D:
+ CVolumeGeometry3D()
+ bool initialize(Config)
+
+cdef extern from "astra/ProjectionGeometry3D.h" namespace "astra":
+ cdef cppclass CProjectionGeometry3D:
+ CProjectionGeometry3D()
+ bool initialize(Config)
+
+
+cdef extern from "astra/Float32VolumeData3DMemory.h" namespace "astra":
+ cdef cppclass CFloat32VolumeData3DMemory:
+ CFloat32VolumeData3DMemory(CVolumeGeometry3D*)
+
+
+cdef extern from "astra/ParallelProjectionGeometry3D.h" namespace "astra":
+ cdef cppclass CParallelProjectionGeometry3D:
+ CParallelProjectionGeometry3D()
+
+cdef extern from "astra/ParallelVecProjectionGeometry3D.h" namespace "astra":
+ cdef cppclass CParallelVecProjectionGeometry3D:
+ CParallelVecProjectionGeometry3D()
+
+cdef extern from "astra/ConeProjectionGeometry3D.h" namespace "astra":
+ cdef cppclass CConeProjectionGeometry3D:
+ CConeProjectionGeometry3D()
+ bool initialize(Config)
+
+cdef extern from "astra/ConeVecProjectionGeometry3D.h" namespace "astra":
+ cdef cppclass CConeVecProjectionGeometry3D:
+ CConeVecProjectionGeometry3D()
+
+cdef extern from "astra/Float32ProjectionData3DMemory.h" namespace "astra":
+ cdef cppclass CFloat32ProjectionData3DMemory:
+ CFloat32ProjectionData3DMemory(CProjectionGeometry3D*)
+ CFloat32ProjectionData3DMemory(CConeProjectionGeometry3D*)
+
+cdef extern from "astra/Float32Data3D.h" namespace "astra":
+ cdef cppclass CFloat32Data3D:
+ CFloat32Data3D()
+ bool isInitialized()
+ int getSize()
+ int getWidth()
+ int getHeight()
+ int getDepth()
+ void updateStatistics()
+
+
+
diff --git a/astra/PyMatrixManager.pxd b/astra/PyMatrixManager.pxd
new file mode 100644
index 0000000..e14325e
--- /dev/null
+++ b/astra/PyMatrixManager.pxd
@@ -0,0 +1,39 @@
+#-----------------------------------------------------------------------
+#Copyright 2013 Centrum Wiskunde & Informatica, Amsterdam
+#
+#Author: Daniel M. Pelt
+#Contact: D.M.Pelt@cwi.nl
+#Website: http://dmpelt.github.io/pyastratoolbox/
+#
+#
+#This file is part of the Python interface to the
+#All Scale Tomographic Reconstruction Antwerp Toolbox ("ASTRA Toolbox").
+#
+#The Python interface to the ASTRA Toolbox 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.
+#
+#The Python interface to the ASTRA Toolbox 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 the Python interface to the ASTRA Toolbox. If not, see .
+#
+#-----------------------------------------------------------------------
+from libcpp.string cimport string
+
+from PyIncludes cimport *
+
+cdef extern from "astra/AstraObjectManager.h" namespace "astra":
+ cdef cppclass CMatrixManager:
+ string info()
+ void clear()
+ void remove(int i)
+ int store(CSparseMatrix *)
+ CSparseMatrix * get(int i)
+
+cdef extern from "astra/AstraObjectManager.h" namespace "astra::CMatrixManager":
+ cdef CMatrixManager* getSingletonPtr()
diff --git a/astra/PyProjector2DFactory.pxd b/astra/PyProjector2DFactory.pxd
new file mode 100644
index 0000000..7e30142
--- /dev/null
+++ b/astra/PyProjector2DFactory.pxd
@@ -0,0 +1,35 @@
+#-----------------------------------------------------------------------
+#Copyright 2013 Centrum Wiskunde & Informatica, Amsterdam
+#
+#Author: Daniel M. Pelt
+#Contact: D.M.Pelt@cwi.nl
+#Website: http://dmpelt.github.io/pyastratoolbox/
+#
+#
+#This file is part of the Python interface to the
+#All Scale Tomographic Reconstruction Antwerp Toolbox ("ASTRA Toolbox").
+#
+#The Python interface to the ASTRA Toolbox 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.
+#
+#The Python interface to the ASTRA Toolbox 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 the Python interface to the ASTRA Toolbox. If not, see .
+#
+#-----------------------------------------------------------------------
+from libcpp.string cimport string
+from libcpp cimport bool
+from PyIncludes cimport *
+
+cdef extern from "astra/AstraObjectFactory.h" namespace "astra":
+ cdef cppclass CProjector2DFactory:
+ CProjector2D *create(Config)
+
+cdef extern from "astra/AstraObjectFactory.h" namespace "astra::CProjector2DFactory":
+ cdef CProjector2DFactory* getSingletonPtr()
diff --git a/astra/PyProjector2DManager.pxd b/astra/PyProjector2DManager.pxd
new file mode 100644
index 0000000..ad6a23c
--- /dev/null
+++ b/astra/PyProjector2DManager.pxd
@@ -0,0 +1,39 @@
+#-----------------------------------------------------------------------
+#Copyright 2013 Centrum Wiskunde & Informatica, Amsterdam
+#
+#Author: Daniel M. Pelt
+#Contact: D.M.Pelt@cwi.nl
+#Website: http://dmpelt.github.io/pyastratoolbox/
+#
+#
+#This file is part of the Python interface to the
+#All Scale Tomographic Reconstruction Antwerp Toolbox ("ASTRA Toolbox").
+#
+#The Python interface to the ASTRA Toolbox 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.
+#
+#The Python interface to the ASTRA Toolbox 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 the Python interface to the ASTRA Toolbox. If not, see .
+#
+#-----------------------------------------------------------------------
+from libcpp.string cimport string
+
+from PyIncludes cimport *
+
+cdef extern from "astra/AstraObjectManager.h" namespace "astra":
+ cdef cppclass CProjector2DManager:
+ string info()
+ void clear()
+ void remove(int i)
+ int store(CProjector2D *)
+ CProjector2D * get(int i)
+
+cdef extern from "astra/AstraObjectManager.h" namespace "astra::CProjector2DManager":
+ cdef CProjector2DManager* getSingletonPtr()
diff --git a/astra/PyXMLDocument.pxd b/astra/PyXMLDocument.pxd
new file mode 100644
index 0000000..69781f1
--- /dev/null
+++ b/astra/PyXMLDocument.pxd
@@ -0,0 +1,65 @@
+#-----------------------------------------------------------------------
+#Copyright 2013 Centrum Wiskunde & Informatica, Amsterdam
+#
+#Author: Daniel M. Pelt
+#Contact: D.M.Pelt@cwi.nl
+#Website: http://dmpelt.github.io/pyastratoolbox/
+#
+#
+#This file is part of the Python interface to the
+#All Scale Tomographic Reconstruction Antwerp Toolbox ("ASTRA Toolbox").
+#
+#The Python interface to the ASTRA Toolbox 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.
+#
+#The Python interface to the ASTRA Toolbox 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 the Python interface to the ASTRA Toolbox. If not, see .
+#
+#-----------------------------------------------------------------------
+# distutils: language = c++
+# distutils: libraries = astra
+
+from libcpp.string cimport string
+from libcpp cimport bool
+from libcpp.list cimport list
+from libcpp.vector cimport vector
+
+cdef extern from "astra/Globals.h" namespace "astra":
+ ctypedef float float32
+ ctypedef double float64
+ ctypedef unsigned short int uint16
+ ctypedef signed short int sint16
+ ctypedef unsigned char uchar8
+ ctypedef signed char schar8
+ ctypedef int int32
+ ctypedef short int int16
+
+cdef extern from "astra/XMLNode.h" namespace "astra":
+ cdef cppclass XMLNode:
+ string getName()
+ XMLNode *addChildNode(string name)
+ XMLNode *addChildNode(string, string)
+ void addAttribute(string, string)
+ void addAttribute(string, float32)
+ void addOption(string, string)
+ bool hasOption(string)
+ string getAttribute(string)
+ list[XMLNode *] getNodes()
+ vector[float32] getContentNumericalArray()
+ string getContent()
+ bool hasAttribute(string)
+
+cdef extern from "astra/XMLDocument.h" namespace "astra":
+ cdef cppclass XMLDocument:
+ void saveToFile(string sFilename)
+ XMLNode *getRootNode()
+
+cdef extern from "astra/XMLDocument.h" namespace "astra::XMLDocument":
+ cdef XMLDocument *createDocument(string rootname)
diff --git a/astra/__init__.py b/astra/__init__.py
new file mode 100644
index 0000000..bdf9bc5
--- /dev/null
+++ b/astra/__init__.py
@@ -0,0 +1,37 @@
+#-----------------------------------------------------------------------
+#Copyright 2013 Centrum Wiskunde & Informatica, Amsterdam
+#
+#Author: Daniel M. Pelt
+#Contact: D.M.Pelt@cwi.nl
+#Website: http://dmpelt.github.io/pyastratoolbox/
+#
+#
+#This file is part of the Python interface to the
+#All Scale Tomographic Reconstruction Antwerp Toolbox ("ASTRA Toolbox").
+#
+#The Python interface to the ASTRA Toolbox 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.
+#
+#The Python interface to the ASTRA Toolbox 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 the Python interface to the ASTRA Toolbox. If not, see .
+#
+#-----------------------------------------------------------------------
+import matlab as m
+from creators import astra_dict,create_vol_geom, create_proj_geom, create_backprojection, create_sino, create_reconstruction, create_projector,create_sino3d_gpu
+from functions import data_op, add_noise_to_sino,clear
+from extrautils import clipCircle
+from ASTRAProjector import ASTRAProjector2D
+import data2d
+import astra
+import data3d
+import algorithm
+import projector
+import matrix
+
diff --git a/astra/algorithm.py b/astra/algorithm.py
new file mode 100644
index 0000000..4998d7e
--- /dev/null
+++ b/astra/algorithm.py
@@ -0,0 +1,76 @@
+#-----------------------------------------------------------------------
+#Copyright 2013 Centrum Wiskunde & Informatica, Amsterdam
+#
+#Author: Daniel M. Pelt
+#Contact: D.M.Pelt@cwi.nl
+#Website: http://dmpelt.github.io/pyastratoolbox/
+#
+#
+#This file is part of the Python interface to the
+#All Scale Tomographic Reconstruction Antwerp Toolbox ("ASTRA Toolbox").
+#
+#The Python interface to the ASTRA Toolbox 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.
+#
+#The Python interface to the ASTRA Toolbox 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 the Python interface to the ASTRA Toolbox. If not, see .
+#
+#-----------------------------------------------------------------------
+
+import algorithm_c as a
+
+def create(config):
+ """Create algorithm object.
+
+ :param config: Algorithm options.
+ :type config: :class:`dict`
+ :returns: :class:`int` -- the ID of the constructed object.
+
+ """
+ return a.create(config)
+
+def run(i, iterations=0):
+ """Run an algorithm.
+
+ :param i: ID of object.
+ :type i: :class:`int`
+ :param iterations: Number of iterations to run.
+ :type iterations: :class:`int`
+
+ """
+ return a.run(i,iterations)
+
+def get_res_norm(i):
+ """Get residual norm of algorithm.
+
+ :param i: ID of object.
+ :type i: :class:`int`
+ :returns: :class:`float` -- The residual norm.
+
+ """
+
+ return a.get_res_norm(i)
+
+def delete(ids):
+ """Delete a matrix object.
+
+ :param ids: ID or list of ID's to delete.
+ :type ids: :class:`int` or :class:`list`
+
+ """
+ return a.delete(ids)
+
+def clear():
+ """Clear all matrix objects."""
+ return a.clear()
+
+def info():
+ """Print info on matrix objects in memory."""
+ return a.info()
diff --git a/astra/algorithm_c.pyx b/astra/algorithm_c.pyx
new file mode 100644
index 0000000..b945fac
--- /dev/null
+++ b/astra/algorithm_c.pyx
@@ -0,0 +1,105 @@
+#-----------------------------------------------------------------------
+#Copyright 2013 Centrum Wiskunde & Informatica, Amsterdam
+#
+#Author: Daniel M. Pelt
+#Contact: D.M.Pelt@cwi.nl
+#Website: http://dmpelt.github.io/pyastratoolbox/
+#
+#
+#This file is part of the Python interface to the
+#All Scale Tomographic Reconstruction Antwerp Toolbox ("ASTRA Toolbox").
+#
+#The Python interface to the ASTRA Toolbox 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.
+#
+#The Python interface to the ASTRA Toolbox 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 the Python interface to the ASTRA Toolbox. If not, see .
+#
+#-----------------------------------------------------------------------
+
+# distutils: language = c++
+# distutils: libraries = astra
+
+from PyIncludes cimport *
+
+cimport PyAlgorithmManager
+from PyAlgorithmManager cimport CAlgorithmManager
+
+cimport PyAlgorithmFactory
+from PyAlgorithmFactory cimport CAlgorithmFactory
+
+cimport PyXMLDocument
+from PyXMLDocument cimport XMLDocument
+
+cimport utils
+
+cdef CAlgorithmManager * manAlg = PyAlgorithmManager.getSingletonPtr()
+
+cdef extern from *:
+ CReconstructionAlgorithm2D * dynamic_cast_recAlg "dynamic_cast" (CAlgorithm * ) except NULL
+
+
+def create(config):
+ cdef XMLDocument * xml = utils.dict2XML('Algorithm', config)
+ cdef Config cfg
+ cdef CAlgorithm * alg
+ cfg.self = xml.getRootNode()
+ alg = PyAlgorithmFactory.getSingletonPtr(
+ ).create(cfg.self.getAttribute("type"))
+ if alg == NULL:
+ del xml
+ raise Exception("Unknown algorithm.")
+ if not alg.initialize(cfg):
+ del xml
+ del alg
+ raise Exception("Algorithm not initialized.")
+ del xml
+ return manAlg.store(alg)
+
+cdef CAlgorithm * getAlg(i) except NULL:
+ cdef CAlgorithm * alg = manAlg.get(i)
+ if alg == NULL:
+ raise Exception("Unknown algorithm.")
+ if not alg.isInitialized():
+ raise Exception("Algorithm not initialized.")
+ return alg
+
+
+def run(i, iterations=0):
+ cdef CAlgorithm * alg = getAlg(i)
+ alg.run(iterations)
+
+
+def get_res_norm(i):
+ cdef CReconstructionAlgorithm2D * pAlg2D
+ cdef CAlgorithm * alg = getAlg(i)
+ cdef float32 res = 0.0
+ pAlg2D = dynamic_cast_recAlg(alg)
+ if pAlg2D == NULL:
+ raise Exception("Operation not supported.")
+ if not pAlg2D.getResidualNorm(res):
+ raise Exception("Operation not supported.")
+ return res
+
+
+def delete(ids):
+ try:
+ for i in ids:
+ manAlg.remove(i)
+ except TypeError:
+ manAlg.remove(ids)
+
+
+def clear():
+ manAlg.clear()
+
+
+def info():
+ print manAlg.info()
diff --git a/astra/astra.py b/astra/astra.py
new file mode 100644
index 0000000..edfb6a4
--- /dev/null
+++ b/astra/astra.py
@@ -0,0 +1,51 @@
+#-----------------------------------------------------------------------
+#Copyright 2013 Centrum Wiskunde & Informatica, Amsterdam
+#
+#Author: Daniel M. Pelt
+#Contact: D.M.Pelt@cwi.nl
+#Website: http://dmpelt.github.io/pyastratoolbox/
+#
+#
+#This file is part of the Python interface to the
+#All Scale Tomographic Reconstruction Antwerp Toolbox ("ASTRA Toolbox").
+#
+#The Python interface to the ASTRA Toolbox 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.
+#
+#The Python interface to the ASTRA Toolbox 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 the Python interface to the ASTRA Toolbox. If not, see .
+#
+#-----------------------------------------------------------------------
+
+import astra_c as a
+
+def credits():
+ """Print credits of the ASTRA Toolbox."""
+ return a.credits()
+
+
+def use_cuda():
+ """Test if CUDA is enabled.
+
+ :returns: :class:`bool` -- ``True`` if CUDA is enabled.
+ """
+ return a.use_cuda()
+
+
+def version(printToScreen=False):
+ """Check version of the ASTRA Toolbox.
+
+ :param printToScreen: If ``True``, print version string. If ``False``, return version integer.
+ :type printToScreen: :class:`bool`
+ :returns: :class:`string` or :class:`int` -- The version string or integer.
+
+ """
+
+ return a.version(printToScreen)
diff --git a/astra/astra_c.pyx b/astra/astra_c.pyx
new file mode 100644
index 0000000..b944f96
--- /dev/null
+++ b/astra/astra_c.pyx
@@ -0,0 +1,61 @@
+#-----------------------------------------------------------------------
+#Copyright 2013 Centrum Wiskunde & Informatica, Amsterdam
+#
+#Author: Daniel M. Pelt
+#Contact: D.M.Pelt@cwi.nl
+#Website: http://dmpelt.github.io/pyastratoolbox/
+#
+#
+#This file is part of the Python interface to the
+#All Scale Tomographic Reconstruction Antwerp Toolbox ("ASTRA Toolbox").
+#
+#The Python interface to the ASTRA Toolbox 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.
+#
+#The Python interface to the ASTRA Toolbox 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 the Python interface to the ASTRA Toolbox. If not, see .
+#
+#-----------------------------------------------------------------------
+# distutils: language = c++
+# distutils: libraries = astra
+
+from libcpp.string cimport string
+from libcpp cimport bool
+cdef extern from "astra/Globals.h" namespace "astra":
+ int getVersion()
+ string getVersionString()
+ bool cudaEnabled()
+
+
+def credits():
+ print "All Scale Tomographic Reconstruction Antwerp Toolbox (ASTRA-Toolbox) was developed at the University of Antwerp by"
+ print " * Prof. dr. Joost Batenburg"
+ print " * Andrei Dabravolski"
+ print " * Gert Merckx"
+ print " * Willem Jan Palenstijn"
+ print " * Tom Roelandts"
+ print " * Prof. dr. Jan Sijbers"
+ print " * dr. Wim van Aarle"
+ print " * Sander van der Maar"
+ print " * dr. Gert Van Gompel"
+ print ""
+ print "Python interface written by"
+ print " * Daniel M. Pelt (CWI, Amsterdam)"
+
+
+def use_cuda():
+ return cudaEnabled()
+
+
+def version(printToScreen=False):
+ if printToScreen:
+ print getVersionString()
+ else:
+ return getVersion()
diff --git a/astra/creators.py b/astra/creators.py
new file mode 100644
index 0000000..f9ec91d
--- /dev/null
+++ b/astra/creators.py
@@ -0,0 +1,500 @@
+#-----------------------------------------------------------------------
+#Copyright 2013 Centrum Wiskunde & Informatica, Amsterdam
+#
+#Author: Daniel M. Pelt
+#Contact: D.M.Pelt@cwi.nl
+#Website: http://dmpelt.github.io/pyastratoolbox/
+#
+#
+#This file is part of the Python interface to the
+#All Scale Tomographic Reconstruction Antwerp Toolbox ("ASTRA Toolbox").
+#
+#The Python interface to the ASTRA Toolbox 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.
+#
+#The Python interface to the ASTRA Toolbox 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 the Python interface to the ASTRA Toolbox. If not, see .
+#
+#-----------------------------------------------------------------------
+
+import numpy as np
+import math
+import data2d
+import data3d
+import projector
+import algorithm
+
+def astra_dict(intype):
+ """Creates a dict to use with the ASTRA Toolbox.
+
+ :param intype: Type of the ASTRA object.
+ :type intype: :class:`string`
+ :returns: :class:`dict` -- An ASTRA dict of type ``intype``.
+
+ """
+ if intype == 'SIRT_CUDA2':
+ intype = 'SIRT_CUDA'
+ print 'SIRT_CUDA2 has been deprecated. Use SIRT_CUDA instead.'
+ elif intype == 'FP_CUDA2':
+ intype = 'FP_CUDA'
+ print 'FP_CUDA2 has been deprecated. Use FP_CUDA instead.'
+ return {'type': intype}
+
+def create_vol_geom(*varargin):
+ """Create a volume geometry structure.
+
+This method can be called in a number of ways:
+
+``create_vol_geom(N)``:
+ :returns: A 2D volume geometry of size :math:`N \\times N`.
+
+``create_vol_geom((M, N))``:
+ :returns: A 2D volume geometry of size :math:`M \\times N`.
+
+``create_vol_geom(M, N)``:
+ :returns: A 2D volume geometry of size :math:`M \\times N`.
+
+``create_vol_geom(M, N, minx, maxx, miny, maxy)``:
+ :returns: A 2D volume geometry of size :math:`M \\times N`, windowed as :math:`minx \\leq x \\leq maxx` and :math:`miny \\leq y \\leq maxy`.
+
+``create_vol_geom((M, N, Z))``:
+ :returns: A 3D volume geometry of size :math:`M \\times N \\times Z`.
+
+``create_vol_geom(M, N, Z)``:
+ :returns: A 3D volume geometry of size :math:`M \\times N \\times Z`.
+
+"""
+ vol_geom = {'option': {}}
+ # astra_create_vol_geom(row_count)
+ if len(varargin) == 1 and isinstance(varargin[0], int) == 1:
+ vol_geom['GridRowCount'] = varargin[0]
+ vol_geom['GridColCount'] = varargin[0]
+ vol_geom['option']['WindowMinX'] = -varargin[0] / 2
+ vol_geom['option']['WindowMaxX'] = varargin[0] / 2
+ vol_geom['option']['WindowMinY'] = -varargin[0] / 2
+ vol_geom['option']['WindowMaxY'] = varargin[0] / 2
+ # astra_create_vol_geom([row_count col_count])
+ elif len(varargin) == 1 and len(varargin[0]) == 2:
+ vol_geom['GridRowCount'] = varargin[0][0]
+ vol_geom['GridColCount'] = varargin[0][1]
+ vol_geom['option']['WindowMinX'] = -varargin[0][1] / 2
+ vol_geom['option']['WindowMaxX'] = varargin[0][1] / 2
+ vol_geom['option']['WindowMinY'] = -varargin[0][0] / 2
+ vol_geom['option']['WindowMaxY'] = varargin[0][0] / 2
+ # astra_create_vol_geom([row_count col_count slice_count])
+ elif len(varargin) == 1 and len(varargin[0]) == 3:
+ vol_geom['GridRowCount'] = varargin[0][0]
+ vol_geom['GridColCount'] = varargin[0][1]
+ vol_geom['GridSliceCount'] = varargin[0][2]
+ vol_geom['option']['WindowMinX'] = -varargin[0][1] / 2
+ vol_geom['option']['WindowMaxX'] = varargin[0][1] / 2
+ vol_geom['option']['WindowMinY'] = -varargin[0][0] / 2
+ vol_geom['option']['WindowMaxY'] = varargin[0][0] / 2
+ vol_geom['option']['WindowMinZ'] = -varargin[0][2] / 2
+ vol_geom['option']['WindowMaxZ'] = varargin[0][2] / 2
+ # astra_create_vol_geom(row_count, col_count)
+ elif len(varargin) == 2:
+ vol_geom['GridRowCount'] = varargin[0]
+ vol_geom['GridColCount'] = varargin[1]
+ vol_geom['option']['WindowMinX'] = -varargin[1] / 2
+ vol_geom['option']['WindowMaxX'] = varargin[1] / 2
+ vol_geom['option']['WindowMinY'] = -varargin[0] / 2
+ vol_geom['option']['WindowMaxY'] = varargin[0] / 2
+ # astra_create_vol_geom(row_count, col_count, min_x, max_x, min_y, max_y)
+ elif len(varargin) == 6:
+ vol_geom['GridRowCount'] = varargin[0]
+ vol_geom['GridColCount'] = varargin[1]
+ vol_geom['option']['WindowMinX'] = varargin[2]
+ vol_geom['option']['WindowMaxX'] = varargin[3]
+ vol_geom['option']['WindowMinY'] = varargin[4]
+ vol_geom['option']['WindowMaxY'] = varargin[5]
+ # astra_create_vol_geom(row_count, col_count, slice_count)
+ elif len(varargin) == 3:
+ vol_geom['GridRowCount'] = varargin[0]
+ vol_geom['GridColCount'] = varargin[1]
+ vol_geom['GridSliceCount'] = varargin[2]
+ return vol_geom
+
+
+def create_proj_geom(intype, *args):
+ """Create a projection geometry.
+
+This method can be called in a number of ways:
+
+``create_proj_geom('parallel', detector_spacing, det_count, angles)``:
+
+:param detector_spacing: Distance between two adjacent detector pixels.
+:type detector_spacing: :class:`float`
+:param det_count: Number of detector pixels.
+:type det_count: :class:`int`
+:param angles: Array of angles in radians.
+:type angles: :class:`numpy.ndarray`
+:returns: A parallel projection geometry.
+
+
+``create_proj_geom('fanflat', det_width, det_count, angles, source_origin, source_det)``:
+
+:param det_width: Size of a detector pixel.
+:type det_width: :class:`float`
+:param det_count: Number of detector pixels.
+:type det_count: :class:`int`
+:param angles: Array of angles in radians.
+:type angles: :class:`numpy.ndarray`
+:param source_origin: Position of the source.
+:param source_det: Position of the detector
+:returns: A fan-beam projection geometry.
+
+``create_proj_geom('fanflat_vec', det_count, V)``:
+
+:param det_count: Number of detector pixels.
+:type det_count: :class:`int`
+:param V: Vector array.
+:type V: :class:`numpy.ndarray`
+:returns: A fan-beam projection geometry.
+
+``create_proj_geom('parallel3d', detector_spacing_x, detector_spacing_y, det_row_count, det_col_count, angles)``:
+
+:param detector_spacing_*: Distance between two adjacent detector pixels.
+:type detector_spacing_*: :class:`float`
+:param det_row_count: Number of detector pixel rows.
+:type det_row_count: :class:`int`
+:param det_col_count: Number of detector pixel columns.
+:type det_col_count: :class:`int`
+:param angles: Array of angles in radians.
+:type angles: :class:`numpy.ndarray`
+:returns: A parallel projection geometry.
+
+``create_proj_geom('cone', detector_spacing_x, detector_spacing_y, det_row_count, det_col_count, angles, source_origin, source_det)``:
+
+:param detector_spacing_*: Distance between two adjacent detector pixels.
+:type detector_spacing_*: :class:`float`
+:param det_row_count: Number of detector pixel rows.
+:type det_row_count: :class:`int`
+:param det_col_count: Number of detector pixel columns.
+:type det_col_count: :class:`int`
+:param angles: Array of angles in radians.
+:type angles: :class:`numpy.ndarray`
+:param source_origin: Distance between point source and origin.
+:type source_origin: :class:`float`
+:param source_det: Distance between the detector and origin.
+:type source_det: :class:`float`
+:returns: A cone-beam projection geometry.
+
+``create_proj_geom('cone_vec', det_row_count, det_col_count, V)``:
+
+:param det_row_count: Number of detector pixel rows.
+:type det_row_count: :class:`int`
+:param det_col_count: Number of detector pixel columns.
+:type det_col_count: :class:`int`
+:param V: Vector array.
+:type V: :class:`numpy.ndarray`
+:returns: A cone-beam projection geometry.
+
+``create_proj_geom('parallel3d_vec', det_row_count, det_col_count, V)``:
+
+:param det_row_count: Number of detector pixel rows.
+:type det_row_count: :class:`int`
+:param det_col_count: Number of detector pixel columns.
+:type det_col_count: :class:`int`
+:param V: Vector array.
+:type V: :class:`numpy.ndarray`
+:returns: A parallel projection geometry.
+
+``create_proj_geom('sparse_matrix', det_width, det_count, angles, matrix_id)``:
+
+:param det_width: Size of a detector pixel.
+:type det_width: :class:`float`
+:param det_count: Number of detector pixels.
+:type det_count: :class:`int`
+:param angles: Array of angles in radians.
+:type angles: :class:`numpy.ndarray`
+:param matrix_id: ID of the sparse matrix.
+:type matrix_id: :class:`int`
+:returns: A projection geometry based on a sparse matrix.
+
+"""
+ if intype == 'parallel':
+ if len(args) < 3:
+ raise Exception(
+ 'not enough variables: astra_create_proj_geom(parallel, detector_spacing, det_count, angles)')
+ return {'type': 'parallel', 'DetectorWidth': args[0], 'DetectorCount': args[1], 'ProjectionAngles': args[2]}
+ elif intype == 'fanflat':
+ if len(args) < 5:
+ raise Exception('not enough variables: astra_create_proj_geom(fanflat, det_width, det_count, angles, source_origin, source_det)')
+ return {'type': 'fanflat', 'DetectorWidth': args[0], 'DetectorCount': args[1], 'ProjectionAngles': args[2], 'DistanceOriginSource': args[3], 'DistanceOriginDetector': args[4]}
+ elif intype == 'fanflat_vec':
+ if len(args) < 2:
+ raise Exception('not enough variables: astra_create_proj_geom(fanflat_vec, det_count, V)')
+ if not args[1].shape[1] == 6:
+ raise Exception('V should be a Nx6 matrix, with N the number of projections')
+ return {'type':'fanflat_vec', 'DetectorCount':args[0], 'Vectors':args[1]}
+ elif intype == 'parallel3d':
+ if len(args) < 5:
+ raise Exception('not enough variables: astra_create_proj_geom(parallel3d, detector_spacing_x, detector_spacing_y, det_row_count, det_col_count, angles)')
+ return {'type':'parallel3d', 'DetectorSpacingX':args[0], 'DetectorSpacingY':args[1], 'DetectorRowCount':args[2], 'DetectorColCount':args[3],'ProjectionAngles':args[4]}
+ elif intype == 'cone':
+ if len(args) < 7:
+ raise Exception('not enough variables: astra_create_proj_geom(cone, detector_spacing_x, detector_spacing_y, det_row_count, det_col_count, angles, source_origin, source_det)')
+ return {'type': 'cone','DetectorSpacingX':args[0], 'DetectorSpacingY':args[1], 'DetectorRowCount':args[2],'DetectorColCount':args[3],'ProjectionAngles':args[4],'DistanceOriginSource': args[5],'DistanceOriginDetector':args[6]}
+ elif intype == 'cone_vec':
+ if len(args) < 3:
+ raise Exception('not enough variables: astra_create_proj_geom(cone_vec, det_row_count, det_col_count, V)')
+ if not args[2].shape[1] == 12:
+ raise Exception('V should be a Nx12 matrix, with N the number of projections')
+ return {'type': 'cone_vec','DetectorRowCount':args[0],'DetectorColCount':args[1],'Vectors':args[2]}
+ elif intype == 'parallel3d_vec':
+ if len(args) < 3:
+ raise Exception('not enough variables: astra_create_proj_geom(parallel3d_vec, det_row_count, det_col_count, V)')
+ if not args[2].shape[1] == 12:
+ raise Exception('V should be a Nx12 matrix, with N the number of projections')
+ return {'type': 'parallel3d_vec','DetectorRowCount':args[0],'DetectorColCount':args[1],'Vectors':args[2]}
+ elif intype == 'sparse_matrix':
+ if len(args) < 4:
+ raise Exception(
+ 'not enough variables: astra_create_proj_geom(sparse_matrix, det_width, det_count, angles, matrix_id)')
+ return {'type': 'sparse_matrix', 'DetectorWidth': args[0], 'DetectorCount': args[1], 'ProjectionAngles': args[2], 'MatrixID': args[3]}
+ else:
+ raise Exception('Error: unknown type ' + intype)
+
+
+def create_backprojection(data, proj_id, useCUDA=False, returnData=True):
+ """Create a backprojection of a sinogram (2D).
+
+:param data: Sinogram data or ID.
+:type data: :class:`numpy.ndarray` or :class:`int`
+:param proj_id: ID of the projector to use.
+:type proj_id: :class:`int`
+:param useCUDA: If ``True``, use CUDA for the calculation.
+:type useCUDA: :class:`bool`
+:param returnData: If False, only return the ID of the backprojection.
+:type returnData: :class:`bool`
+:returns: :class:`int` or (:class:`int`, :class:`numpy.ndarray`) -- If ``returnData=False``, returns the ID of the backprojection. Otherwise, returns a tuple containing the ID of the backprojection and the backprojection itself, in that order.
+
+"""
+ proj_geom = projector.projection_geometry(proj_id)
+ vol_geom = projector.volume_geometry(proj_id)
+ if isinstance(data, np.ndarray):
+ sino_id = data2d.create('-sino', proj_geom, data)
+ else:
+ sino_id = data
+ vol_id = data2d.create('-vol', vol_geom, 0)
+
+ algString = 'BP'
+ if useCUDA:
+ algString = algString + '_CUDA'
+
+ cfg = astra_dict(algString)
+ if not useCUDA:
+ cfg['ProjectorId'] = proj_id
+ cfg['ProjectionDataId'] = sino_id
+ cfg['ReconstructionDataId'] = vol_id
+ alg_id = algorithm.create(cfg)
+ algorithm.run(alg_id)
+ algorithm.delete(alg_id)
+
+ if isinstance(data, np.ndarray):
+ data2d.delete(sino_id)
+
+ if returnData:
+ return vol_id, data2d.get(vol_id)
+ else:
+ return vol_id
+
+
+def create_sino(data, proj_id, useCUDA=False, returnData=True, gpuIndex=None):
+ """Create a forward projection of an image (2D).
+
+:param data: Image data or ID.
+:type data: :class:`numpy.ndarray` or :class:`int`
+:param proj_id: ID of the projector to use.
+:type proj_id: :class:`int`
+:param useCUDA: If ``True``, use CUDA for the calculation.
+:type useCUDA: :class:`bool`
+:param returnData: If False, only return the ID of the forward projection.
+:type returnData: :class:`bool`
+:param gpuIndex: Optional GPU index.
+:type gpuIndex: :class:`int`
+:returns: :class:`int` or (:class:`int`, :class:`numpy.ndarray`) -- If ``returnData=False``, returns the ID of the forward projection. Otherwise, returns a tuple containing the ID of the forward projection and the forward projection itself, in that order.
+
+"""
+
+ proj_geom = projector.projection_geometry(proj_id)
+ vol_geom = projector.volume_geometry(proj_id)
+ if isinstance(data, np.ndarray):
+ volume_id = data2d.create('-vol', vol_geom, data)
+ else:
+ volume_id = data
+ sino_id = data2d.create('-sino', proj_geom, 0)
+ algString = 'FP'
+ if useCUDA:
+ algString = algString + '_CUDA'
+ cfg = astra_dict(algString)
+ if not useCUDA:
+ cfg['ProjectorId'] = proj_id
+ if not gpuIndex==None:
+ cfg['option']={'GPUindex':gpuIndex}
+ cfg['ProjectionDataId'] = sino_id
+ cfg['VolumeDataId'] = volume_id
+ alg_id = algorithm.create(cfg)
+ algorithm.run(alg_id)
+ algorithm.delete(alg_id)
+
+ if isinstance(data, np.ndarray):
+ data2d.delete(volume_id)
+ if returnData:
+ return sino_id, data2d.get(sino_id)
+ else:
+ return sino_id
+
+def create_sino3d_gpu(data, proj_geom, vol_geom, returnData=True, gpuIndex=None):
+ """Create a forward projection of an image (3D).
+
+:param data: Image data or ID.
+:type data: :class:`numpy.ndarray` or :class:`int`
+:param proj_geom: Projection geometry.
+:type proj_geom: :class:`dict`
+:param vol_geom: Volume geometry.
+:type vol_geom: :class:`dict`
+:param returnData: If False, only return the ID of the forward projection.
+:type returnData: :class:`bool`
+:param gpuIndex: Optional GPU index.
+:type gpuIndex: :class:`int`
+:returns: :class:`int` or (:class:`int`, :class:`numpy.ndarray`) -- If ``returnData=False``, returns the ID of the forward projection. Otherwise, returns a tuple containing the ID of the forward projection and the forward projection itself, in that order.
+
+"""
+
+ if isinstance(data, np.ndarray):
+ volume_id = data3d.create('-vol', vol_geom, data)
+ else:
+ volume_id = data
+ sino_id = data3d.create('-sino', proj_geom, 0)
+ algString = 'FP3D_CUDA'
+ cfg = astra_dict(algString)
+ if not gpuIndex==None:
+ cfg['option']={'GPUindex':gpuIndex}
+ cfg['ProjectionDataId'] = sino_id
+ cfg['VolumeDataId'] = volume_id
+ alg_id = algorithm.create(cfg)
+ algorithm.run(alg_id)
+ algorithm.delete(alg_id)
+
+ if isinstance(data, np.ndarray):
+ data3d.delete(volume_id)
+ if returnData:
+ return sino_id, data3d.get(sino_id)
+ else:
+ return sino_id
+
+
+def create_reconstruction(rec_type, proj_id, sinogram, iterations=1, use_mask='no', mask=np.array([]), use_minc='no', minc=0, use_maxc='no', maxc=255, returnData=True, filterType=None, filterData=None):
+ """Create a reconstruction of a sinogram (2D).
+
+:param rec_type: Name of the reconstruction algorithm.
+:type rec_type: :class:`string`
+:param proj_id: ID of the projector to use.
+:type proj_id: :class:`int`
+:param sinogram: Sinogram data or ID.
+:type sinogram: :class:`numpy.ndarray` or :class:`int`
+:param iterations: Number of iterations to run.
+:type iterations: :class:`int`
+:param use_mask: Whether to use a mask.
+:type use_mask: ``'yes'`` or ``'no'``
+:param mask: Mask data or ID
+:type mask: :class:`numpy.ndarray` or :class:`int`
+:param use_minc: Whether to force a minimum value on the reconstruction pixels.
+:type use_minc: ``'yes'`` or ``'no'``
+:param minc: Minimum value to use.
+:type minc: :class:`float`
+:param use_maxc: Whether to force a maximum value on the reconstruction pixels.
+:type use_maxc: ``'yes'`` or ``'no'``
+:param maxc: Maximum value to use.
+:type maxc: :class:`float`
+:param returnData: If False, only return the ID of the reconstruction.
+:type returnData: :class:`bool`
+:param filterType: Which type of filter to use for filter-based methods.
+:type filterType: :class:`string`
+:param filterData: Optional filter data for filter-based methods.
+:type filterData: :class:`numpy.ndarray`
+:returns: :class:`int` or (:class:`int`, :class:`numpy.ndarray`) -- If ``returnData=False``, returns the ID of the reconstruction. Otherwise, returns a tuple containing the ID of the reconstruction and reconstruction itself, in that order.
+
+"""
+ proj_geom = projector.projection_geometry(proj_id)
+ if isinstance(sinogram, np.ndarray):
+ sino_id = data2d.create('-sino', proj_geom, sinogram)
+ else:
+ sino_id = sinogram
+ vol_geom = projector.volume_geometry(proj_id)
+ recon_id = data2d.create('-vol', vol_geom, 0)
+ cfg = astra_dict(rec_type)
+ if not 'CUDA' in rec_type:
+ cfg['ProjectorId'] = proj_id
+ cfg['ProjectionDataId'] = sino_id
+ cfg['ReconstructionDataId'] = recon_id
+ cfg['options'] = {}
+ if use_mask == 'yes':
+ if isinstance(mask, np.ndarray):
+ mask_id = data2d.create('-vol', vol_geom, mask)
+ else:
+ mask_id = mask
+ cfg['options']['ReconstructionMaskId'] = mask_id
+ if not filterType == None:
+ cfg['FilterType'] = filterType
+ if not filterData == None:
+ if isinstance(filterData, np.ndarray):
+ nexpow = int(
+ pow(2, math.ceil(math.log(2 * proj_geom['DetectorCount'], 2))))
+ filtSize = nexpow / 2 + 1
+ filt_proj_geom = create_proj_geom(
+ 'parallel', 1.0, filtSize, proj_geom['ProjectionAngles'])
+ filt_id = data2d.create('-sino', filt_proj_geom, filterData)
+ else:
+ filt_id = filterData
+ cfg['FilterSinogramId'] = filt_id
+ cfg['options']['UseMinConstraint'] = use_minc
+ cfg['options']['MinConstraintValue'] = minc
+ cfg['options']['UseMaxConstraint'] = use_maxc
+ cfg['options']['MaxConstraintValue'] = maxc
+ cfg['options']['ProjectionOrder'] = 'random'
+ alg_id = algorithm.create(cfg)
+ algorithm.run(alg_id, iterations)
+
+ algorithm.delete(alg_id)
+
+ if isinstance(sinogram, np.ndarray):
+ data2d.delete(sino_id)
+ if use_mask == 'yes' and isinstance(mask, np.ndarray):
+ data2d.delete(mask_id)
+ if not filterData == None:
+ if isinstance(filterData, np.ndarray):
+ data2d.delete(filt_id)
+ if returnData:
+ return recon_id, data2d.get(recon_id)
+ else:
+ return recon_id
+
+
+def create_projector(proj_type, proj_geom, vol_geom):
+ """Create a 2D projector.
+
+:param proj_type: Projector type, such as ``'line'``, ``'linear'``, ...
+:type proj_type: :class:`string`
+:param proj_geom: Projection geometry.
+:type proj_geom: :class:`dict`
+:param vol_geom: Volume geometry.
+:type vol_geom: :class:`dict`
+:returns: :class:`int` -- The ID of the projector.
+
+"""
+ if proj_type == 'blob':
+ raise Exception('Blob type not yet implemented')
+ cfg = astra_dict(proj_type)
+ cfg['ProjectionGeometry'] = proj_geom
+ cfg['VolumeGeometry'] = vol_geom
+ return projector.create(cfg)
diff --git a/astra/data2d.py b/astra/data2d.py
new file mode 100644
index 0000000..f768f02
--- /dev/null
+++ b/astra/data2d.py
@@ -0,0 +1,109 @@
+#-----------------------------------------------------------------------
+#Copyright 2013 Centrum Wiskunde & Informatica, Amsterdam
+#
+#Author: Daniel M. Pelt
+#Contact: D.M.Pelt@cwi.nl
+#Website: http://dmpelt.github.io/pyastratoolbox/
+#
+#
+#This file is part of the Python interface to the
+#All Scale Tomographic Reconstruction Antwerp Toolbox ("ASTRA Toolbox").
+#
+#The Python interface to the ASTRA Toolbox 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.
+#
+#The Python interface to the ASTRA Toolbox 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 the Python interface to the ASTRA Toolbox. If not, see .
+#
+#-----------------------------------------------------------------------
+import data2d_c as d
+
+def clear():
+ """Clear all 2D data objects."""
+ return d.clear()
+
+def delete(ids):
+ """Delete a 2D object.
+
+ :param ids: ID or list of ID's to delete.
+ :type ids: :class:`int` or :class:`list`
+
+ """
+ return d.delete(ids)
+
+def create(datatype, geometry, data=None):
+ """Create a 2D object.
+
+ :param datatype: Data object type, '-vol' or '-sino'.
+ :type datatype: :class:`string`
+ :param geometry: Volume or projection geometry.
+ :type geometry: :class:`dict`
+ :param data: Data to fill the constructed object with, either a scalar or array.
+ :type data: :class:`float` or :class:`numpy.ndarray`
+ :returns: :class:`int` -- the ID of the constructed object.
+
+ """
+ return d.create(datatype,geometry,data)
+
+def store(i, data):
+ """Fill existing 2D object with data.
+
+ :param i: ID of object to fill.
+ :type i: :class:`int`
+ :param data: Data to fill the object with, either a scalar or array.
+ :type data: :class:`float` or :class:`numpy.ndarray`
+
+ """
+ return d.store(i, data)
+
+def get_geometry(i):
+ """Get the geometry of a 2D object.
+
+ :param i: ID of object.
+ :type i: :class:`int`
+ :returns: :class:`dict` -- The geometry of object with ID ``i``.
+
+ """
+ return d.get_geometry(i)
+
+def change_geometry(i, geom):
+ """Change the geometry of a 2D object.
+
+ :param i: ID of object.
+ :type i: :class:`int`
+ :param geom: new geometry.
+ :type geom: :class:`dict`
+
+ """
+ return d.change_geometry(i, geom)
+
+def get(i):
+ """Get a 2D object.
+
+ :param i: ID of object to get.
+ :type i: :class:`int`
+ :returns: :class:`numpy.ndarray` -- The object data.
+
+ """
+ return d.get(i)
+
+def get_single(i):
+ """Get a 2D object in single precision.
+
+ :param i: ID of object to get.
+ :type i: :class:`int`
+ :returns: :class:`numpy.ndarray` -- The object data.
+
+ """
+ return d.get_single(i)
+
+def info():
+ """Print info on 2D objects in memory."""
+ return d.info()
diff --git a/astra/data2d_c.pyx b/astra/data2d_c.pyx
new file mode 100644
index 0000000..0ce13c5
--- /dev/null
+++ b/astra/data2d_c.pyx
@@ -0,0 +1,224 @@
+#-----------------------------------------------------------------------
+#Copyright 2013 Centrum Wiskunde & Informatica, Amsterdam
+#
+#Author: Daniel M. Pelt
+#Contact: D.M.Pelt@cwi.nl
+#Website: http://dmpelt.github.io/pyastratoolbox/
+#
+#
+#This file is part of the Python interface to the
+#All Scale Tomographic Reconstruction Antwerp Toolbox ("ASTRA Toolbox").
+#
+#The Python interface to the ASTRA Toolbox 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.
+#
+#The Python interface to the ASTRA Toolbox 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 the Python interface to the ASTRA Toolbox. If not, see .
+#
+#-----------------------------------------------------------------------
+# distutils: language = c++
+# distutils: libraries = astra
+
+cimport PyData2DManager
+from PyData2DManager cimport CData2DManager
+
+cimport PyXMLDocument
+from PyXMLDocument cimport XMLDocument
+
+import numpy as np
+
+from PyIncludes cimport *
+
+cimport utils
+
+cdef CData2DManager * man2d = PyData2DManager.getSingletonPtr()
+
+
+def clear():
+ man2d.clear()
+
+
+def delete(ids):
+ try:
+ for i in ids:
+ man2d.remove(i)
+ except TypeError:
+ man2d.remove(ids)
+
+
+def create(datatype, geometry, data=None):
+ cdef XMLDocument * xml
+ cdef Config cfg
+ cdef CVolumeGeometry2D * pGeometry
+ cdef CProjectionGeometry2D * ppGeometry
+ cdef CFloat32Data2D * pDataObject2D
+ if datatype == '-vol':
+ xml = utils.dict2XML('VolumeGeometry', geometry)
+ cfg.self = xml.getRootNode()
+ pGeometry = new CVolumeGeometry2D()
+ if not pGeometry.initialize(cfg):
+ del xml
+ del pGeometry
+ raise Exception('Geometry class not initialized.')
+ pDataObject2D = new CFloat32VolumeData2D(pGeometry)
+ del xml
+ del pGeometry
+ elif datatype == '-sino':
+ xml = utils.dict2XML('ProjectionGeometry', geometry)
+ cfg.self = xml.getRootNode()
+ tpe = str(cfg.self.getAttribute('type'))
+ if (tpe == 'sparse_matrix'):
+ ppGeometry = new CSparseMatrixProjectionGeometry2D()
+ elif (tpe == 'fanflat'):
+ ppGeometry = new CFanFlatProjectionGeometry2D()
+ elif (tpe == 'fanflat_vec'):
+ ppGeometry = new CFanFlatVecProjectionGeometry2D()
+ else:
+ ppGeometry = new CParallelProjectionGeometry2D()
+ if not ppGeometry.initialize(cfg):
+ del xml
+ del ppGeometry
+ raise Exception('Geometry class not initialized.')
+ pDataObject2D = new CFloat32ProjectionData2D(ppGeometry)
+ del ppGeometry
+ del xml
+ else:
+ raise Exception("Invalid datatype. Please specify '-vol' or '-sino'.")
+
+ if not pDataObject2D.isInitialized():
+ del pDataObject2D
+ raise Exception("Couldn't initialize data object.")
+
+ fillDataObject(pDataObject2D, data)
+
+ return man2d.store(pDataObject2D)
+
+cdef fillDataObject(CFloat32Data2D * obj, data):
+ if data == None:
+ fillDataObjectScalar(obj, 0)
+ else:
+ if isinstance(data, np.ndarray):
+ fillDataObjectArray(obj, data)
+ else:
+ fillDataObjectScalar(obj, data)
+
+cdef fillDataObjectScalar(CFloat32Data2D * obj, s):
+ cdef int i
+ for i in range(obj.getSize()):
+ obj.getData()[i] = s
+
+cdef fillDataObjectArray(CFloat32Data2D * obj, data):
+ cdef int i, row, col
+ if (not data.shape[0] == obj.getHeight()) or (not data.shape[1] == obj.getWidth()):
+ raise Exception(
+ "The dimensions of the data do not match those specified in the geometry.")
+ for col in range(data.shape[1]):
+ for row in range(data.shape[0]):
+ obj.getData2D()[row][col] = data[row][col]
+
+cdef CFloat32Data2D * getObject(i) except NULL:
+ cdef CFloat32Data2D * pDataObject = man2d.get(i)
+ if pDataObject == NULL:
+ raise Exception("Data object not found")
+ if not pDataObject.isInitialized():
+ raise Exception("Data object not initialized properly.")
+ return pDataObject
+
+
+def store(i, data):
+ cdef CFloat32Data2D * pDataObject = getObject(i)
+ fillDataObject(pDataObject, data)
+
+
+def get_geometry(i):
+ cdef CFloat32Data2D * pDataObject = getObject(i)
+ cdef CFloat32ProjectionData2D * pDataObject2
+ cdef CFloat32VolumeData2D * pDataObject3
+ if pDataObject.getType() == PROJECTION:
+ pDataObject2 = pDataObject
+ geom = utils.createProjectionGeometryStruct(pDataObject2.getGeometry())
+ elif pDataObject.getType() == VOLUME:
+ pDataObject3 = pDataObject
+ geom = utils.createVolumeGeometryStruct(pDataObject3.getGeometry())
+ else:
+ raise Exception("Not a known data object")
+ return geom
+
+
+def change_geometry(i, geom):
+ cdef XMLDocument * xml
+ cdef Config cfg
+ cdef CVolumeGeometry2D * pGeometry
+ cdef CProjectionGeometry2D * ppGeometry
+ cdef CFloat32Data2D * pDataObject = getObject(i)
+ cdef CFloat32ProjectionData2D * pDataObject2
+ cdef CFloat32VolumeData2D * pDataObject3
+ if pDataObject.getType() == PROJECTION:
+ pDataObject2 = pDataObject
+ xml = utils.dict2XML('ProjectionGeometry', geom)
+ cfg.self = xml.getRootNode()
+ tpe = str(cfg.self.getAttribute('type'))
+ if (tpe == 'sparse_matrix'):
+ ppGeometry = new CSparseMatrixProjectionGeometry2D()
+ elif (tpe == 'fanflat'):
+ ppGeometry = new CFanFlatProjectionGeometry2D()
+ elif (tpe == 'fanflat_vec'):
+ ppGeometry = new CFanFlatVecProjectionGeometry2D()
+ else:
+ ppGeometry = new CParallelProjectionGeometry2D()
+ if not ppGeometry.initialize(cfg):
+ del xml
+ del ppGeometry
+ raise Exception('Geometry class not initialized.')
+ if (ppGeometry.getDetectorCount() != pDataObject2.getDetectorCount() or ppGeometry.getProjectionAngleCount() != pDataObject2.getAngleCount()):
+ del ppGeometry
+ del xml
+ raise Exception(
+ "The dimensions of the data do not match those specified in the geometry.")
+ pDataObject2.changeGeometry(ppGeometry)
+ del ppGeometry
+ del xml
+ elif pDataObject.getType() == VOLUME:
+ pDataObject3 = pDataObject
+ xml = utils.dict2XML('VolumeGeometry', geom)
+ cfg.self = xml.getRootNode()
+ pGeometry = new CVolumeGeometry2D()
+ if not pGeometry.initialize(cfg):
+ del xml
+ del pGeometry
+ raise Exception('Geometry class not initialized.')
+ if (pGeometry.getGridColCount() != pDataObject3.getWidth() or pGeometry.getGridRowCount() != pDataObject3.getHeight()):
+ del xml
+ del pGeometry
+ raise Exception(
+ 'The dimensions of the data do not match those specified in the geometry.')
+ pDataObject3.changeGeometry(pGeometry)
+ del xml
+ del pGeometry
+ else:
+ raise Exception("Not a known data object")
+
+
+def get(i):
+ cdef row, col
+ cdef CFloat32Data2D * pDataObject = getObject(i)
+ outArr = np.empty((pDataObject.getHeight(), pDataObject.getWidth()))
+ for row in range(outArr.shape[0]):
+ for col in range(outArr.shape[1]):
+ outArr[row][col] = pDataObject.getData2D()[row][col]
+ return outArr
+
+
+def get_single(i):
+ raise Exception("Not yet implemented")
+
+
+def info():
+ print man2d.info()
diff --git a/astra/data3d.py b/astra/data3d.py
new file mode 100644
index 0000000..5545a74
--- /dev/null
+++ b/astra/data3d.py
@@ -0,0 +1,98 @@
+#-----------------------------------------------------------------------
+#Copyright 2013 Centrum Wiskunde & Informatica, Amsterdam
+#
+#Author: Daniel M. Pelt
+#Contact: D.M.Pelt@cwi.nl
+#Website: http://dmpelt.github.io/pyastratoolbox/
+#
+#
+#This file is part of the Python interface to the
+#All Scale Tomographic Reconstruction Antwerp Toolbox ("ASTRA Toolbox").
+#
+#The Python interface to the ASTRA Toolbox 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.
+#
+#The Python interface to the ASTRA Toolbox 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 the Python interface to the ASTRA Toolbox. If not, see .
+#
+#-----------------------------------------------------------------------
+import data3d_c as d
+
+def create(datatype,geometry,data=None):
+ """Create a 3D object.
+
+ :param datatype: Data object type, '-vol' or '-sino'.
+ :type datatype: :class:`string`
+ :param geometry: Volume or projection geometry.
+ :type geometry: :class:`dict`
+ :param data: Data to fill the constructed object with, either a scalar or array.
+ :type data: :class:`float` or :class:`numpy.ndarray`
+ :returns: :class:`int` -- the ID of the constructed object.
+
+ """
+ return d.create(datatype,geometry,data)
+
+def get(i):
+ """Get a 3D object.
+
+ :param i: ID of object to get.
+ :type i: :class:`int`
+ :returns: :class:`numpy.ndarray` -- The object data.
+
+ """
+ return d.get(i)
+
+def get_single(i):
+ """Get a 3D object in single precision.
+
+ :param i: ID of object to get.
+ :type i: :class:`int`
+ :returns: :class:`numpy.ndarray` -- The object data.
+
+ """
+ return g.get_single(i)
+
+def store(i,data):
+ """Fill existing 3D object with data.
+
+ :param i: ID of object to fill.
+ :type i: :class:`int`
+ :param data: Data to fill the object with, either a scalar or array.
+ :type data: :class:`float` or :class:`numpy.ndarray`
+
+ """
+ return d.store(i,data)
+
+def dimensions(i):
+ """Get dimensions of a 3D object.
+
+ :param i: ID of object.
+ :type i: :class:`int`
+ :returns: :class:`tuple` -- dimensions of object with ID ``i``.
+
+ """
+ return d.dimensions(i)
+
+def delete(ids):
+ """Delete a 2D object.
+
+ :param ids: ID or list of ID's to delete.
+ :type ids: :class:`int` or :class:`list`
+
+ """
+ return d.delete(ids)
+
+def clear():
+ """Clear all 3D data objects."""
+ return d.clear()
+
+def info():
+ """Print info on 3D objects in memory."""
+ return d.info()
diff --git a/astra/data3d_c.pyx b/astra/data3d_c.pyx
new file mode 100644
index 0000000..aae0791
--- /dev/null
+++ b/astra/data3d_c.pyx
@@ -0,0 +1,172 @@
+#-----------------------------------------------------------------------
+#Copyright 2013 Centrum Wiskunde & Informatica, Amsterdam
+#
+#Author: Daniel M. Pelt
+#Contact: D.M.Pelt@cwi.nl
+#Website: http://dmpelt.github.io/pyastratoolbox/
+#
+#
+#This file is part of the Python interface to the
+#All Scale Tomographic Reconstruction Antwerp Toolbox ("ASTRA Toolbox").
+#
+#The Python interface to the ASTRA Toolbox 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.
+#
+#The Python interface to the ASTRA Toolbox 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 the Python interface to the ASTRA Toolbox. If not, see .
+#
+#-----------------------------------------------------------------------
+# distutils: language = c++
+# distutils: libraries = astra
+
+cimport PyData3DManager
+from PyData3DManager cimport CData3DManager
+
+from PyIncludes cimport *
+import numpy as np
+
+cimport PyXMLDocument
+from PyXMLDocument cimport XMLDocument
+
+cimport utils
+
+cdef CData3DManager * man3d = PyData3DManager.getSingletonPtr()
+
+cdef extern from *:
+ CFloat32Data3DMemory * dynamic_cast_mem "dynamic_cast" (CFloat32Data3D * ) except NULL
+
+def create(datatype,geometry,data=None):
+ cdef XMLDocument * xml
+ cdef Config cfg
+ cdef CVolumeGeometry3D * pGeometry
+ cdef CProjectionGeometry3D * ppGeometry
+ cdef CFloat32Data3DMemory * pDataObject3D
+ cdef CConeProjectionGeometry3D* pppGeometry
+ if datatype == '-vol':
+ xml = utils.dict2XML('VolumeGeometry', geometry)
+ cfg.self = xml.getRootNode()
+ pGeometry = new CVolumeGeometry3D()
+ if not pGeometry.initialize(cfg):
+ del xml
+ del pGeometry
+ raise Exception('Geometry class not initialized.')
+ pDataObject3D = new CFloat32VolumeData3DMemory(pGeometry)
+ del xml
+ del pGeometry
+ elif datatype == '-sino' or datatype == '-proj3d':
+ xml = utils.dict2XML('ProjectionGeometry', geometry)
+ cfg.self = xml.getRootNode()
+ tpe = str(cfg.self.getAttribute('type'))
+ if (tpe == "parallel3d"):
+ ppGeometry = new CParallelProjectionGeometry3D();
+ elif (tpe == "parallel3d_vec"):
+ ppGeometry = new CParallelVecProjectionGeometry3D();
+ elif (tpe == "cone"):
+ ppGeometry = new CConeProjectionGeometry3D();
+ elif (tpe == "cone_vec"):
+ ppGeometry = new CConeVecProjectionGeometry3D();
+ else:
+ raise Exception("Invalid geometry type.")
+
+ if not ppGeometry.initialize(cfg):
+ del xml
+ del ppGeometry
+ raise Exception('Geometry class not initialized.')
+ pDataObject3D = new CFloat32ProjectionData3DMemory(ppGeometry)
+ del ppGeometry
+ del xml
+ elif datatype == "-sinocone":
+ xml = utils.dict2XML('ProjectionGeometry', geometry)
+ cfg.self = xml.getRootNode()
+ pppGeometry = new CConeProjectionGeometry3D()
+ if not pppGeometry.initialize(cfg):
+ del xml
+ del pppGeometry
+ raise Exception('Geometry class not initialized.')
+ pDataObject3D = new CFloat32ProjectionData3DMemory(pppGeometry)
+ else:
+ raise Exception("Invalid datatype. Please specify '-vol' or '-proj3d'.")
+
+ if not pDataObject3D.isInitialized():
+ del pDataObject3D
+ raise Exception("Couldn't initialize data object.")
+
+ fillDataObject(pDataObject3D, data)
+
+ pDataObject3D.updateStatistics()
+
+ return man3d.store(pDataObject3D)
+
+
+cdef fillDataObject(CFloat32Data3DMemory * obj, data):
+ if data == None:
+ fillDataObjectScalar(obj, 0)
+ else:
+ if isinstance(data, np.ndarray):
+ fillDataObjectArray(obj, data)
+ else:
+ fillDataObjectScalar(obj, data)
+
+cdef fillDataObjectScalar(CFloat32Data3DMemory * obj, s):
+ cdef int i
+ for i in range(obj.getSize()):
+ obj.getData()[i] = s
+
+cdef fillDataObjectArray(CFloat32Data3DMemory * obj, data):
+ cdef int i, row, col,slc
+ if (not data.shape[0] == obj.getWidth()) or (not data.shape[1] == obj.getHeight()) or (not data.shape[2] == obj.getDepth()):
+ raise Exception(
+ "The dimensions of the data do not match those specified in the geometry.")
+ for row in range(data.shape[0]):
+ for col in range(data.shape[1]):
+ for slc in range(data.shape[2]):
+ obj.getData3D()[slc][col][row] = data[row][col][slc]
+
+cdef CFloat32Data3D * getObject(i) except NULL:
+ cdef CFloat32Data3D * pDataObject = man3d.get(i)
+ if pDataObject == NULL:
+ raise Exception("Data object not found")
+ if not pDataObject.isInitialized():
+ raise Exception("Data object not initialized properly.")
+ return pDataObject
+
+def get(i):
+ cdef row, col,slc
+ cdef CFloat32Data3DMemory * pDataObject = dynamic_cast_mem(getObject(i))
+ outArr = np.empty((pDataObject.getDepth(),pDataObject.getHeight(), pDataObject.getWidth()))
+ for slc in range(outArr.shape[0]):
+ for col in range(outArr.shape[2]):
+ for row in range(outArr.shape[1]):
+ outArr[slc][row][col] = pDataObject.getData3D()[slc][row][col]
+ return outArr
+
+def get_single(i):
+ raise Exception("Not yet implemented")
+
+def store(i,data):
+ cdef CFloat32Data3D * pDataObject = getObject(i)
+ fillDataObject(dynamic_cast_mem(pDataObject), data)
+
+def dimensions(i):
+ cdef CFloat32Data3D * pDataObject = getObject(i)
+ return (pDataObject.getWidth(),pDataObject.getHeight(),pDataObject.getDepth())
+
+def delete(ids):
+ try:
+ for i in ids:
+ man3d.remove(i)
+ except TypeError:
+ man3d.remove(ids)
+
+def clear():
+ man3d.clear()
+
+def info():
+ print man3d.info()
diff --git a/astra/extrautils.pyx b/astra/extrautils.pyx
new file mode 100644
index 0000000..09a0d61
--- /dev/null
+++ b/astra/extrautils.pyx
@@ -0,0 +1,44 @@
+#-----------------------------------------------------------------------
+#Copyright 2013 Centrum Wiskunde & Informatica, Amsterdam
+#
+#Author: Daniel M. Pelt
+#Contact: D.M.Pelt@cwi.nl
+#Website: http://dmpelt.github.io/pyastratoolbox/
+#
+#
+#This file is part of the Python interface to the
+#All Scale Tomographic Reconstruction Antwerp Toolbox ("ASTRA Toolbox").
+#
+#The Python interface to the ASTRA Toolbox 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.
+#
+#The Python interface to the ASTRA Toolbox 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 the Python interface to the ASTRA Toolbox. If not, see .
+#
+#-----------------------------------------------------------------------
+def clipCircle(img):
+ cdef int i,j
+ cdef double x2,y2,mid,bnd
+ cdef long sz,sz2
+ sz = img.shape[0]
+ sz2 = sz*sz
+ bnd = sz2/4.
+ mid = (sz-1.)/2.
+ nDel=0
+ for i in range(sz):
+ for j in range(sz):
+ x2 = (i-mid)*(i-mid)
+ y2 = (j-mid)*(j-mid)
+ if x2+y2>bnd:
+ img[i,j]=0
+ nDel=nDel+1
+ return nDel
+
+
diff --git a/astra/functions.py b/astra/functions.py
new file mode 100644
index 0000000..dfcd0e4
--- /dev/null
+++ b/astra/functions.py
@@ -0,0 +1,109 @@
+#-----------------------------------------------------------------------
+#Copyright 2013 Centrum Wiskunde & Informatica, Amsterdam
+#
+#Author: Daniel M. Pelt
+#Contact: D.M.Pelt@cwi.nl
+#Website: http://dmpelt.github.io/pyastratoolbox/
+#
+#
+#This file is part of the Python interface to the
+#All Scale Tomographic Reconstruction Antwerp Toolbox ("ASTRA Toolbox").
+#
+#The Python interface to the ASTRA Toolbox 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.
+#
+#The Python interface to the ASTRA Toolbox 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 the Python interface to the ASTRA Toolbox. If not, see .
+#
+#-----------------------------------------------------------------------
+"""Additional functions for PyAstraToolbox.
+
+.. moduleauthor:: Daniel M. Pelt
+
+
+"""
+
+import creators as ac
+import numpy as np
+import scipy.weave
+
+import data2d
+import data3d
+import projector
+import algorithm
+
+
+
+def clear():
+ """Clears all used memory of the ASTRA Toolbox.
+
+ .. note::
+ This is irreversible.
+
+ """
+ data2d.clear()
+ data3d.clear()
+ projector.clear()
+ algorithm.clear()
+
+
+def data_op(op, data, scalar, gpu_core, mask=None):
+ """Perform data operation on data.
+
+ :param op: Operation to perform.
+ :param data: Data to perform operation on.
+ :param scalar: Scalar argument to data operation.
+ :param gpu_core: GPU core to perform operation on.
+ :param mask: Optional mask.
+
+ """
+
+ cfg = ac.astra_dict('DataOperation_CUDA')
+ cfg['Operation'] = op
+ cfg['Scalar'] = scalar
+ cfg['DataId'] = data
+ if not mask == None:
+ cfg['MaskId'] = mask
+ cfg['option']['GPUindex'] = gpu_core
+ alg_id = at.algorithm('create', cfg)
+ at.algorithm('run', alg_id)
+ at.algorithm('delete', alg_id)
+
+
+def add_noise_to_sino(sinogram_in, I0):
+ """Adds Poisson noise to a sinogram.
+
+ :param sinogram_in: Sinogram to add noise to.
+ :type sinogram_in: :class:`numpy.ndarray`
+ :param I0: Background intensity. Lower values lead to higher noise.
+ :type I0: :class:`float`
+ :returns: :class:`numpy.ndarray` -- the sinogram with added noise.
+
+ """
+ if isinstance(sinogram_in, np.ndarray):
+ sinogramRaw = sinogram_in
+ else:
+ sinogramRaw = at.data2d('get', sinogram_in)
+ max_sinogramRaw = sinogramRaw.max()
+ sinogramRawScaled = sinogramRaw / max_sinogramRaw
+ # to detector count
+ sinogramCT = I0 * np.exp(-sinogramRawScaled)
+ # add poison noise
+ sinogramCT_C = np.zeros_like(sinogramCT)
+ for i in xrange(sinogramCT_C.shape[0]):
+ for j in xrange(sinogramCT_C.shape[1]):
+ sinogramCT_C[i, j] = np.random.poisson(sinogramCT[i, j])
+ # to density
+ sinogramCT_D = sinogramCT_C / I0
+ sinogram_out = -max_sinogramRaw * np.log(sinogramCT_D)
+
+ if not isinstance(sinogram_in, np.ndarray):
+ at.data2d('store', sinogram_in, sinogram_out)
+ return sinogram_out
diff --git a/astra/matlab.py b/astra/matlab.py
new file mode 100644
index 0000000..9291d82
--- /dev/null
+++ b/astra/matlab.py
@@ -0,0 +1,112 @@
+#-----------------------------------------------------------------------
+#Copyright 2013 Centrum Wiskunde & Informatica, Amsterdam
+#
+#Author: Daniel M. Pelt
+#Contact: D.M.Pelt@cwi.nl
+#Website: http://dmpelt.github.io/pyastratoolbox/
+#
+#
+#This file is part of the Python interface to the
+#All Scale Tomographic Reconstruction Antwerp Toolbox ("ASTRA Toolbox").
+#
+#The Python interface to the ASTRA Toolbox 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.
+#
+#The Python interface to the ASTRA Toolbox 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 the Python interface to the ASTRA Toolbox. If not, see .
+#
+#-----------------------------------------------------------------------
+"""This module implements a MATLAB-like interface to the ASTRA Toolbox.
+
+Note that all functions are called with a :class:`string` as the first
+argument, specifying the operation to perform. This un-pythonic way
+is used to make transitioning from MATLAB code to Python code easier, as
+the MATLAB interface uses the same type of method calling.
+
+After an initial ``import astra``, these functions can be accessed in the
+``astra.m`` module.
+
+"""
+
+import astra_c
+import data2d_c
+import data3d_c
+import projector_c
+import algorithm_c
+import matrix_c
+import numpy as np
+
+
+def astra(command, *args):
+ """MATLAB-like interface to the :mod:`astra.astra` module
+
+ For example:
+
+ ``astra.m.astra('use_cuda')`` -- Check if CUDA is enabled.
+
+ """
+ return getattr(astra_c, command)(*args)
+
+
+def data2d(command, *args):
+ """MATLAB-like interface to the :mod:`astra.data2d` module
+
+ For example:
+
+ ``astra.m.data2d('create',type,geometry,data)`` -- Create a 2D object.
+
+ """
+ return getattr(data2d_c, command)(*args)
+
+
+def data3d(command, *args):
+ """MATLAB-like interface to the :mod:`astra.data3d` module
+
+ For example:
+
+ ``astra.m.data3d('get',i)`` -- Get 3D object data.
+
+ """
+ return getattr(data3d_c, command)(*args)
+
+
+def projector(command, *args):
+ """MATLAB-like interface to the :mod:`astra.projector` module
+
+ For example:
+
+ ``astra.m.projector('volume_geometry',i)`` -- Get volume geometry.
+
+ """
+ return getattr(projector_c, command)(*args)
+
+
+def matrix(command, *args):
+ """MATLAB-like interface to the :mod:`astra.matrix` module
+
+ For example:
+
+ ``astra.m.matrix('delete',i)`` -- Delete a matrix.
+
+ """
+ return getattr(matrix_c, command)(*args)
+
+
+def algorithm(command, *args):
+ """MATLAB-like interface to the :mod:`astra.algorithm` module
+
+ For example:
+
+ ``astra.m.algorithm('run',i,1000)`` -- Run an algorithm with 1000 iterations.
+
+ """
+ if command == 'iterate':
+ command = 'run'
+ return getattr(algorithm_c, command)(*args)
diff --git a/astra/matrix.py b/astra/matrix.py
new file mode 100644
index 0000000..5beb62d
--- /dev/null
+++ b/astra/matrix.py
@@ -0,0 +1,86 @@
+#-----------------------------------------------------------------------
+#Copyright 2013 Centrum Wiskunde & Informatica, Amsterdam
+#
+#Author: Daniel M. Pelt
+#Contact: D.M.Pelt@cwi.nl
+#Website: http://dmpelt.github.io/pyastratoolbox/
+#
+#
+#This file is part of the Python interface to the
+#All Scale Tomographic Reconstruction Antwerp Toolbox ("ASTRA Toolbox").
+#
+#The Python interface to the ASTRA Toolbox 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.
+#
+#The Python interface to the ASTRA Toolbox 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 the Python interface to the ASTRA Toolbox. If not, see .
+#
+#-----------------------------------------------------------------------
+import matrix_c as m
+
+def delete(ids):
+ """Delete a matrix object.
+
+ :param ids: ID or list of ID's to delete.
+ :type ids: :class:`int` or :class:`list`
+
+ """
+ return m.delete(ids)
+
+def clear():
+ """Clear all matrix objects."""
+ return m.clear()
+
+def create(data):
+ """Create matrix object with data.
+
+ :param data: Data to fill the created object with.
+ :type data: :class:`scipy.sparse.csr_matrix`
+ :returns: :class:`int` -- the ID of the constructed object.
+
+ """
+ return m.create(data)
+
+
+def store(i,data):
+ """Fill existing matrix object with data.
+
+ :param i: ID of object to fill.
+ :type i: :class:`int`
+ :param data: Data to fill the object with.
+ :type data: :class:`scipy.sparse.csr_matrix`
+
+ """
+ return m.store(i,data)
+
+def get_size(i):
+ """Get matrix dimensions.
+
+ :param i: ID of object.
+ :type i: :class:`int`
+ :returns: :class:`tuple` -- matrix dimensions.
+ """
+ return m.get_size(i)
+
+def get(i):
+ """Get a matrix object.
+
+ :param i: ID of object to get.
+ :type i: :class:`int`
+ :returns: :class:`scipy.sparse.csr_matrix` -- The object data.
+
+ """
+ return m.get(i)
+
+def info():
+ """Print info on matrix objects in memory."""
+ return m.info()
+
+
diff --git a/astra/matrix_c.pyx b/astra/matrix_c.pyx
new file mode 100644
index 0000000..264cb48
--- /dev/null
+++ b/astra/matrix_c.pyx
@@ -0,0 +1,115 @@
+#-----------------------------------------------------------------------
+#Copyright 2013 Centrum Wiskunde & Informatica, Amsterdam
+#
+#Author: Daniel M. Pelt
+#Contact: D.M.Pelt@cwi.nl
+#Website: http://dmpelt.github.io/pyastratoolbox/
+#
+#
+#This file is part of the Python interface to the
+#All Scale Tomographic Reconstruction Antwerp Toolbox ("ASTRA Toolbox").
+#
+#The Python interface to the ASTRA Toolbox 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.
+#
+#The Python interface to the ASTRA Toolbox 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 the Python interface to the ASTRA Toolbox. If not, see .
+#
+#-----------------------------------------------------------------------
+# distutils: language = c++
+# distutils: libraries = astra
+
+import numpy as np
+import scipy.sparse as ss
+
+cimport PyMatrixManager
+from PyMatrixManager cimport CMatrixManager
+
+from PyIncludes cimport *
+
+cdef CMatrixManager * manM = PyMatrixManager.getSingletonPtr()
+
+from libcpp cimport bool
+
+def delete(ids):
+ try:
+ for i in ids:
+ manM.remove(i)
+ except TypeError:
+ manM.remove(ids)
+
+def clear():
+ manM.clear()
+
+cdef int csr_matrix_to_astra(data,CSparseMatrix *mat) except -1:
+ if isinstance(data,ss.csr_matrix):
+ csrD = data
+ else:
+ csrD = data.tocsr()
+ if not mat.isInitialized():
+ raise Exception("Couldn't initialize data object.")
+ if csrD.nnz > mat.m_lSize or csrD.shape[0] > mat.m_iHeight:
+ raise Exception("Matrix too large to store in this object.")
+ for i in xrange(len(csrD.indptr)):
+ mat.m_plRowStarts[i] = csrD.indptr[i]
+ for i in xrange(csrD.nnz):
+ mat.m_piColIndices[i] = csrD.indices[i]
+ mat.m_pfValues[i] = csrD.data[i]
+
+cdef astra_to_csr_matrix(CSparseMatrix *mat):
+ indptr = np.zeros(mat.m_iHeight+1,dtype=np.int)
+ indices = np.zeros(mat.m_plRowStarts[mat.m_iHeight],dtype=np.int)
+ data = np.zeros(mat.m_plRowStarts[mat.m_iHeight])
+ for i in xrange(mat.m_iHeight+1):
+ indptr[i] = mat.m_plRowStarts[i]
+ for i in xrange(mat.m_plRowStarts[mat.m_iHeight]):
+ indices[i] = mat.m_piColIndices[i]
+ data[i] = mat.m_pfValues[i]
+ return ss.csr_matrix((data,indices,indptr),shape=(mat.m_iHeight,mat.m_iWidth))
+
+def create(data):
+ cdef CSparseMatrix* pMatrix
+ pMatrix = new CSparseMatrix(data.shape[0], data.shape[1], data.nnz)
+ if not pMatrix.isInitialized():
+ del pMatrix
+ raise Exception("Couldn't initialize data object.")
+ try:
+ csr_matrix_to_astra(data,pMatrix)
+ except:
+ del pMatrix
+ raise Exception("Failed to create data object.")
+
+ return manM.store(pMatrix)
+
+cdef CSparseMatrix * getObject(i) except NULL:
+ cdef CSparseMatrix * pDataObject = manM.get(i)
+ if pDataObject == NULL:
+ raise Exception("Data object not found")
+ if not pDataObject.isInitialized():
+ raise Exception("Data object not initialized properly.")
+ return pDataObject
+
+
+def store(i,data):
+ cdef CSparseMatrix * pDataObject = getObject(i)
+ csr_matrix_to_astra(data,pDataObject)
+
+def get_size(i):
+ cdef CSparseMatrix * pDataObject = getObject(i)
+ return (pDataObject.m_iHeight,pDataObject.m_iWidth)
+
+def get(i):
+ cdef CSparseMatrix * pDataObject = getObject(i)
+ return astra_to_csr_matrix(pDataObject)
+
+def info():
+ print manM.info()
+
+
diff --git a/astra/projector.py b/astra/projector.py
new file mode 100644
index 0000000..a222097
--- /dev/null
+++ b/astra/projector.py
@@ -0,0 +1,100 @@
+#-----------------------------------------------------------------------
+#Copyright 2013 Centrum Wiskunde & Informatica, Amsterdam
+#
+#Author: Daniel M. Pelt
+#Contact: D.M.Pelt@cwi.nl
+#Website: http://dmpelt.github.io/pyastratoolbox/
+#
+#
+#This file is part of the Python interface to the
+#All Scale Tomographic Reconstruction Antwerp Toolbox ("ASTRA Toolbox").
+#
+#The Python interface to the ASTRA Toolbox 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.
+#
+#The Python interface to the ASTRA Toolbox 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 the Python interface to the ASTRA Toolbox. If not, see .
+#
+#-----------------------------------------------------------------------
+import projector_c as p
+
+def create(config):
+ """Create projector object.
+
+ :param config: Projector options.
+ :type config: :class:`dict`
+ :returns: :class:`int` -- the ID of the constructed object.
+
+ """
+ return p.create(config)
+
+
+def delete(ids):
+ """Delete a projector object.
+
+ :param ids: ID or list of ID's to delete.
+ :type ids: :class:`int` or :class:`list`
+
+ """
+ return p.delete(ids)
+
+
+def clear():
+ """Clear all projector objects."""
+ return p.clear()
+
+
+def info():
+ """Print info on projector objects in memory."""
+ return p.info()
+
+def projection_geometry(i):
+ """Get projection geometry of a projector.
+
+ :param i: ID of projector.
+ :type i: :class:`int`
+ :returns: :class:`dict` -- projection geometry
+
+ """
+ return p.projection_geometry(i)
+
+
+def volume_geometry(i):
+ """Get volume geometry of a projector.
+
+ :param i: ID of projector.
+ :type i: :class:`int`
+ :returns: :class:`dict` -- volume geometry
+
+ """
+ return p.volume_geometry(i)
+
+
+def weights_single_ray(i, projection_index, detector_index):
+ return p.weights_single_ray(i, projection_index, detector_index)
+
+
+def weights_projection(i, projection_index):
+ return p.weights_projection(i, projection_index)
+
+
+def splat(i, row, col):
+ return p.splat(i, row, col)
+
+
+def matrix(i):
+ """Get sparse matrix of a projector.
+
+ :param i: ID of projector.
+ :type i: :class:`int`
+ :returns: :class:`int` -- ID of sparse matrix.
+
+ """
+ return p.matrix(i)
diff --git a/astra/projector_c.pyx b/astra/projector_c.pyx
new file mode 100644
index 0000000..87fedd1
--- /dev/null
+++ b/astra/projector_c.pyx
@@ -0,0 +1,117 @@
+#-----------------------------------------------------------------------
+#Copyright 2013 Centrum Wiskunde & Informatica, Amsterdam
+#
+#Author: Daniel M. Pelt
+#Contact: D.M.Pelt@cwi.nl
+#Website: http://dmpelt.github.io/pyastratoolbox/
+#
+#
+#This file is part of the Python interface to the
+#All Scale Tomographic Reconstruction Antwerp Toolbox ("ASTRA Toolbox").
+#
+#The Python interface to the ASTRA Toolbox 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.
+#
+#The Python interface to the ASTRA Toolbox 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 the Python interface to the ASTRA Toolbox. If not, see .
+#
+#-----------------------------------------------------------------------
+# distutils: language = c++
+# distutils: libraries = astra
+
+from PyIncludes cimport *
+
+cimport utils
+
+cimport PyProjector2DFactory
+from PyProjector2DFactory cimport CProjector2DFactory
+
+cimport PyProjector2DManager
+from PyProjector2DManager cimport CProjector2DManager
+
+cimport PyXMLDocument
+from PyXMLDocument cimport XMLDocument
+
+cimport PyMatrixManager
+from PyMatrixManager cimport CMatrixManager
+
+cdef CProjector2DManager * manProj = PyProjector2DManager.getSingletonPtr()
+cdef CMatrixManager * manM = PyMatrixManager.getSingletonPtr()
+
+
+def create(config):
+ cdef XMLDocument * xml = utils.dict2XML('Projector2D', config)
+ cdef Config cfg
+ cdef CProjector2D * proj
+ cfg.self = xml.getRootNode()
+ proj = PyProjector2DFactory.getSingletonPtr().create(cfg)
+ if proj == NULL:
+ del xml
+ raise Exception("Error creating projector.")
+ del xml
+ return manProj.store(proj)
+
+
+def delete(ids):
+ try:
+ for i in ids:
+ manProj.remove(i)
+ except TypeError:
+ manProj.remove(ids)
+
+
+def clear():
+ manProj.clear()
+
+
+def info():
+ print manProj.info()
+
+cdef CProjector2D * getObject(i) except NULL:
+ cdef CProjector2D * proj = manProj.get(i)
+ if proj == NULL:
+ raise Exception("Projector not initialized.")
+ if not proj.isInitialized():
+ raise Exception("Projector not initialized.")
+ return proj
+
+
+def projection_geometry(i):
+ cdef CProjector2D * proj = getObject(i)
+ return utils.createProjectionGeometryStruct(proj.getProjectionGeometry())
+
+
+def volume_geometry(i):
+ cdef CProjector2D * proj = getObject(i)
+ return utils.createVolumeGeometryStruct(proj.getVolumeGeometry())
+
+
+def weights_single_ray(i, projection_index, detector_index):
+ raise Exception("Not yet implemented")
+
+
+def weights_projection(i, projection_index):
+ raise Exception("Not yet implemented")
+
+
+def splat(i, row, col):
+ raise Exception("Not yet implemented")
+
+
+def matrix(i):
+ cdef CProjector2D * proj = getObject(i)
+ cdef CSparseMatrix * mat = proj.getMatrix()
+ if mat == NULL:
+ del mat
+ raise Exception("Data object not found")
+ if not mat.isInitialized():
+ del mat
+ raise Exception("Data object not initialized properly.")
+ return manM.store(mat)
diff --git a/astra/utils.pxd b/astra/utils.pxd
new file mode 100644
index 0000000..b1986f2
--- /dev/null
+++ b/astra/utils.pxd
@@ -0,0 +1,37 @@
+#-----------------------------------------------------------------------
+#Copyright 2013 Centrum Wiskunde & Informatica, Amsterdam
+#
+#Author: Daniel M. Pelt
+#Contact: D.M.Pelt@cwi.nl
+#Website: http://dmpelt.github.io/pyastratoolbox/
+#
+#
+#This file is part of the Python interface to the
+#All Scale Tomographic Reconstruction Antwerp Toolbox ("ASTRA Toolbox").
+#
+#The Python interface to the ASTRA Toolbox 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.
+#
+#The Python interface to the ASTRA Toolbox 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 the Python interface to the ASTRA Toolbox. If not, see .
+#
+#-----------------------------------------------------------------------
+from libcpp.string cimport string
+
+cimport PyXMLDocument
+from PyXMLDocument cimport XMLDocument
+from PyXMLDocument cimport XMLNode
+
+from PyIncludes cimport *
+
+cdef XMLDocument *dict2XML(string rootname, dc)
+cdef XML2dict(XMLDocument *)
+cdef createVolumeGeometryStruct(CVolumeGeometry2D* geom)
+cdef createProjectionGeometryStruct(CProjectionGeometry2D* geom)
diff --git a/astra/utils.pyx b/astra/utils.pyx
new file mode 100644
index 0000000..5a51ca3
--- /dev/null
+++ b/astra/utils.pyx
@@ -0,0 +1,228 @@
+#-----------------------------------------------------------------------
+#Copyright 2013 Centrum Wiskunde & Informatica, Amsterdam
+#
+#Author: Daniel M. Pelt
+#Contact: D.M.Pelt@cwi.nl
+#Website: http://dmpelt.github.io/pyastratoolbox/
+#
+#
+#This file is part of the Python interface to the
+#All Scale Tomographic Reconstruction Antwerp Toolbox ("ASTRA Toolbox").
+#
+#The Python interface to the ASTRA Toolbox 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.
+#
+#The Python interface to the ASTRA Toolbox 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 the Python interface to the ASTRA Toolbox. If not, see .
+#
+#-----------------------------------------------------------------------
+# distutils: language = c++
+# distutils: libraries = astra
+
+from libcpp.string cimport string
+from libcpp.list cimport list
+from libcpp.vector cimport vector
+
+cimport PyXMLDocument
+from PyXMLDocument cimport XMLDocument
+from PyXMLDocument cimport XMLNode
+from cython.operator cimport dereference as deref
+
+from PyIncludes cimport *
+
+import numpy as np
+
+cdef XMLDocument * dict2XML(string rootname, dc):
+ cdef XMLDocument * doc = PyXMLDocument.createDocument(rootname)
+ cdef XMLNode * node = doc.getRootNode()
+ try:
+ readDict(node, dc)
+ except:
+ print 'Error reading XML'
+ del doc
+ doc = NULL
+ finally:
+ del node
+ return doc
+
+cdef void readDict(XMLNode * root, dc):
+ cdef XMLNode * listbase
+ cdef XMLNode * itm
+ cdef int i
+ cdef int j
+ for item in dc:
+ val = dc[item]
+ if isinstance(val, np.ndarray):
+ if val.size == 0:
+ break
+ listbase = root.addChildNode(item)
+ listbase.addAttribute(< string > 'listsize', < float32 > val.size)
+ index = 0
+ if val.ndim == 2:
+ for i in range(val.shape[0]):
+ for j in range(val.shape[1]):
+ itm = listbase.addChildNode('ListItem')
+ itm.addAttribute(< string > 'index', < float32 > index)
+ itm.addAttribute( < string > 'value', < float32 > val[i, j])
+ index += 1
+ del itm
+ elif val.ndim == 1:
+ for i in range(val.shape[0]):
+ itm = listbase.addChildNode('ListItem')
+ itm.addAttribute(< string > 'index', < float32 > index)
+ itm.addAttribute(< string > 'value', < float32 > val[i])
+ index += 1
+ del itm
+ else:
+ raise Exception("Only 1 or 2 dimensions are allowed")
+ del listbase
+ elif isinstance(val, dict):
+ if item == 'option' or item == 'options' or item == 'Option' or item == 'Options':
+ readOptions(root, val)
+ else:
+ itm = root.addChildNode(item)
+ readDict(itm, val)
+ del itm
+ else:
+ if item == 'type':
+ root.addAttribute(< string > 'type', < string > str(val))
+ else:
+ itm = root.addChildNode(item, str(val))
+ del itm
+
+cdef void readOptions(XMLNode * node, dc):
+ cdef XMLNode * listbase
+ cdef XMLNode * itm
+ cdef int i
+ cdef int j
+ for item in dc:
+ val = dc[item]
+ if node.hasOption(item):
+ raise Exception('Duplicate Option: %s' % item)
+ if isinstance(val, np.ndarray):
+ if val.size == 0:
+ break
+ listbase = node.addChildNode('Option')
+ listbase.addAttribute(< string > 'key', < string > val)
+ listbase.addAttribute(< string > 'listsize', < float32 > val.size)
+ index = 0
+ if val.ndim == 2:
+ for i in range(val.shape[0]):
+ for j in range(val.shape[1]):
+ itm = listbase.addChildNode('ListItem')
+ itm.addAttribute(< string > 'index', < float32 > index)
+ itm.addAttribute( < string > 'value', < float32 > val[i, j])
+ index += 1
+ del itm
+ elif val.ndim == 1:
+ for i in range(val.shape[0]):
+ itm = listbase.addChildNode('ListItem')
+ itm.addAttribute(< string > 'index', < float32 > index)
+ itm.addAttribute(< string > 'value', < float32 > val[i])
+ index += 1
+ del itm
+ else:
+ raise Exception("Only 1 or 2 dimensions are allowed")
+ del listbase
+ else:
+ node.addOption(item, str(val))
+
+cdef vectorToNumpy(vector[float32] inp):
+ cdef int i
+ cdef int sz = inp.size()
+ ret = np.empty(sz)
+ for i in range(sz):
+ ret[i] = inp[i]
+ return ret
+
+cdef XMLNode2dict(XMLNode * node):
+ cdef XMLNode * subnode
+ cdef list[XMLNode * ] nodes
+ cdef list[XMLNode * ].iterator it
+ dct = {}
+ if node.hasAttribute('type'):
+ dct['type'] = node.getAttribute('type')
+ nodes = node.getNodes()
+ it = nodes.begin()
+ while it != nodes.end():
+ subnode = deref(it)
+ if subnode.hasAttribute('listsize'):
+ dct[subnode.getName(
+ )] = vectorToNumpy(subnode.getContentNumericalArray())
+ else:
+ dct[subnode.getName()] = subnode.getContent()
+ del subnode
+ return dct
+
+cdef XML2dict(XMLDocument * xml):
+ cdef XMLNode * node = xml.getRootNode()
+ dct = XMLNode2dict(node)
+ del node;
+ return dct;
+
+cdef createProjectionGeometryStruct(CProjectionGeometry2D * geom):
+ cdef int i
+ cdef CFanFlatVecProjectionGeometry2D * fanvecGeom
+ # cdef SFanProjection* p
+ dct = {}
+ dct['DetectorCount'] = geom.getDetectorCount()
+ if not geom.isOfType(< string > 'fanflat_vec'):
+ dct['DetectorWidth'] = geom.getDetectorWidth()
+ angles = np.empty(geom.getProjectionAngleCount())
+ for i in range(geom.getProjectionAngleCount()):
+ angles[i] = geom.getProjectionAngle(i)
+ dct['ProjectionAngles'] = angles
+ else:
+ raise Exception("Not yet implemented")
+ # fanvecGeom = geom
+ # vecs = np.empty(fanvecGeom.getProjectionAngleCount()*6)
+ # iDetCount = pVecGeom.getDetectorCount()
+ # for i in range(fanvecGeom.getProjectionAngleCount()):
+ # p = &fanvecGeom.getProjectionVectors()[i];
+ # out[6*i + 0] = p.fSrcX
+ # out[6*i + 1] = p.fSrcY
+ # out[6*i + 2] = p.fDetSX + 0.5f*iDetCount*p.fDetUX
+ # out[6*i + 3] = p.fDetSY + 0.5f*iDetCount*p.fDetUY
+ # out[6*i + 4] = p.fDetUX
+ # out[6*i + 5] = p.fDetUY
+ # dct['Vectors'] = vecs
+ if (geom.isOfType(< string > 'parallel')):
+ dct["type"] = "parallel"
+ elif (geom.isOfType(< string > 'fanflat')):
+ raise Exception("Not yet implemented")
+ # astra::CFanFlatProjectionGeometry2D* pFanFlatGeom = dynamic_cast(_pProjGeom)
+ # mGeometryInfo["DistanceOriginSource"] = mxCreateDoubleScalar(pFanFlatGeom->getOriginSourceDistance())
+ # mGeometryInfo["DistanceOriginDetector"] =
+ # mxCreateDoubleScalar(pFanFlatGeom->getOriginDetectorDistance())
+ dct["type"] = "fanflat"
+ elif (geom.isOfType(< string > 'sparse_matrix')):
+ raise Exception("Not yet implemented")
+ # astra::CSparseMatrixProjectionGeometry2D* pSparseMatrixGeom =
+ # dynamic_cast(_pProjGeom);
+ dct["type"] = "sparse_matrix"
+ # dct["MatrixID"] =
+ # mxCreateDoubleScalar(CMatrixManager::getSingleton().getIndex(pSparseMatrixGeom->getMatrix()))
+ elif(geom.isOfType(< string > 'fanflat_vec')):
+ dct["type"] = "fanflat_vec"
+ return dct
+
+cdef createVolumeGeometryStruct(CVolumeGeometry2D * geom):
+ mGeometryInfo = {}
+ mGeometryInfo["GridColCount"] = geom.getGridColCount()
+ mGeometryInfo["GridRowCount"] = geom.getGridRowCount()
+
+ mGeometryOptions = {}
+ mGeometryOptions["WindowMinX"] = geom.getWindowMinX()
+ mGeometryOptions["WindowMaxX"] = geom.getWindowMaxX()
+ mGeometryOptions["WindowMinY"] = geom.getWindowMinY()
+ mGeometryOptions["WindowMaxY"] = geom.getWindowMaxY()
+
+ mGeometryInfo["option"] = mGeometryOptions
+ return mGeometryInfo
diff --git a/builder.py b/builder.py
new file mode 100644
index 0000000..617b2b1
--- /dev/null
+++ b/builder.py
@@ -0,0 +1,81 @@
+#-----------------------------------------------------------------------
+#Copyright 2013 Centrum Wiskunde & Informatica, Amsterdam
+#
+#Author: Daniel M. Pelt
+#Contact: D.M.Pelt@cwi.nl
+#Website: http://dmpelt.github.io/pyastratoolbox/
+#
+#
+#This file is part of the Python interface to the
+#All Scale Tomographic Reconstruction Antwerp Toolbox ("ASTRA Toolbox").
+#
+#The Python interface to the ASTRA Toolbox 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.
+#
+#The Python interface to the ASTRA Toolbox 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 the Python interface to the ASTRA Toolbox. If not, see .
+#
+#-----------------------------------------------------------------------
+import sys
+
+if sys.version_info[0]>2:
+ raise Exception("Only Python version 2 is supported.")
+
+from distutils.version import StrictVersion
+from distutils.core import setup
+from distutils.extension import Extension
+
+use_cython=False
+try:
+ from Cython.Distutils import build_ext
+ from Cython.Build import cythonize
+ import Cython
+ if StrictVersion(Cython.__version__)>=StrictVersion('0.13'):
+ use_cython = True
+except ImportError:
+ use_cython = False
+
+cmdclass = { }
+ext_modules = [ ]
+
+if use_cython:
+ ext_modules = cythonize("astra/*.pyx")
+ cmdclass = { 'build_ext': build_ext }
+else:
+ ext_modules += [
+ Extension("astra.algorithm_c", [ "astra/algorithm_c.cpp" ],libraries = ['astra']),
+ Extension("astra.astra_c", [ "astra/astra_c.cpp" ],libraries = ['astra']),
+ Extension("astra.data2d_c", [ "astra/data2d_c.cpp" ],libraries = ['astra']),
+ Extension("astra.data3d_c", [ "astra/data3d_c.cpp" ],libraries = ['astra']),
+ Extension("astra.matrix_c", [ "astra/matrix_c.cpp" ],libraries = ['astra']),
+ Extension("astra.projector_c", [ "astra/projector_c.cpp" ],libraries = ['astra']),
+ Extension("astra.utils", [ "astra/utils.cpp" ],libraries = ['astra']),
+ Extension("astra.extrautils", [ "astra/extrautils.c" ],libraries = ['astra']),
+ ]
+
+
+
+
+
+setup (name = 'PyASTRAToolbox',
+ version = '1.0',
+ description = 'Python interface to the ASTRA-Toolbox',
+ author='D.M. Pelt',
+ author_email='D.M.Pelt@cwi.nl',
+ url='http://dmpelt.github.io/pyastratoolbox/',
+ #ext_package='astra',
+ #ext_modules = cythonize(Extension("astra/*.pyx",extra_compile_args=extra_compile_args,extra_linker_args=extra_compile_args)),
+ license='GPLv3',
+ ext_modules = ext_modules,
+ cmdclass = cmdclass,
+ #ext_modules = [Extension("astra","astra/astra.pyx")],
+ packages=['astra'],
+ requires=['numpy'],
+ )
diff --git a/doc b/doc
new file mode 120000
index 0000000..3705b55
--- /dev/null
+++ b/doc
@@ -0,0 +1 @@
+docSRC/_build/html
\ No newline at end of file
diff --git a/docSRC/ASTRAProjector.rst b/docSRC/ASTRAProjector.rst
new file mode 100644
index 0000000..1c267e3
--- /dev/null
+++ b/docSRC/ASTRAProjector.rst
@@ -0,0 +1,8 @@
+Helper class: the :mod:`ASTRAProjector` module
+==============================================
+
+.. automodule:: astra.ASTRAProjector
+ :members:
+ :undoc-members:
+ :show-inheritance:
+
diff --git a/docSRC/Makefile b/docSRC/Makefile
new file mode 100644
index 0000000..a005bab
--- /dev/null
+++ b/docSRC/Makefile
@@ -0,0 +1,153 @@
+# Makefile for Sphinx documentation
+#
+
+# You can set these variables from the command line.
+SPHINXOPTS =
+SPHINXBUILD = sphinx-build
+PAPER =
+BUILDDIR = _build
+
+# Internal variables.
+PAPEROPT_a4 = -D latex_paper_size=a4
+PAPEROPT_letter = -D latex_paper_size=letter
+ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
+# the i18n builder cannot share the environment and doctrees with the others
+I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
+
+.PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest gettext
+
+help:
+ @echo "Please use \`make ' where is one of"
+ @echo " html to make standalone HTML files"
+ @echo " dirhtml to make HTML files named index.html in directories"
+ @echo " singlehtml to make a single large HTML file"
+ @echo " pickle to make pickle files"
+ @echo " json to make JSON files"
+ @echo " htmlhelp to make HTML files and a HTML help project"
+ @echo " qthelp to make HTML files and a qthelp project"
+ @echo " devhelp to make HTML files and a Devhelp project"
+ @echo " epub to make an epub"
+ @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter"
+ @echo " latexpdf to make LaTeX files and run them through pdflatex"
+ @echo " text to make text files"
+ @echo " man to make manual pages"
+ @echo " texinfo to make Texinfo files"
+ @echo " info to make Texinfo files and run them through makeinfo"
+ @echo " gettext to make PO message catalogs"
+ @echo " changes to make an overview of all changed/added/deprecated items"
+ @echo " linkcheck to check all external links for integrity"
+ @echo " doctest to run all doctests embedded in the documentation (if enabled)"
+
+clean:
+ -rm -rf $(BUILDDIR)/*
+
+html:
+ $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html
+ @echo
+ @echo "Build finished. The HTML pages are in $(BUILDDIR)/html."
+
+dirhtml:
+ $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml
+ @echo
+ @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml."
+
+singlehtml:
+ $(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml
+ @echo
+ @echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml."
+
+pickle:
+ $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle
+ @echo
+ @echo "Build finished; now you can process the pickle files."
+
+json:
+ $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json
+ @echo
+ @echo "Build finished; now you can process the JSON files."
+
+htmlhelp:
+ $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp
+ @echo
+ @echo "Build finished; now you can run HTML Help Workshop with the" \
+ ".hhp project file in $(BUILDDIR)/htmlhelp."
+
+qthelp:
+ $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp
+ @echo
+ @echo "Build finished; now you can run "qcollectiongenerator" with the" \
+ ".qhcp project file in $(BUILDDIR)/qthelp, like this:"
+ @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/.qhcp"
+ @echo "To view the help file:"
+ @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/.qhc"
+
+devhelp:
+ $(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp
+ @echo
+ @echo "Build finished."
+ @echo "To view the help file:"
+ @echo "# mkdir -p $$HOME/.local/share/devhelp/"
+ @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/"
+ @echo "# devhelp"
+
+epub:
+ $(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub
+ @echo
+ @echo "Build finished. The epub file is in $(BUILDDIR)/epub."
+
+latex:
+ $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
+ @echo
+ @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex."
+ @echo "Run \`make' in that directory to run these through (pdf)latex" \
+ "(use \`make latexpdf' here to do that automatically)."
+
+latexpdf:
+ $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
+ @echo "Running LaTeX files through pdflatex..."
+ $(MAKE) -C $(BUILDDIR)/latex all-pdf
+ @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex."
+
+text:
+ $(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text
+ @echo
+ @echo "Build finished. The text files are in $(BUILDDIR)/text."
+
+man:
+ $(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man
+ @echo
+ @echo "Build finished. The manual pages are in $(BUILDDIR)/man."
+
+texinfo:
+ $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
+ @echo
+ @echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo."
+ @echo "Run \`make' in that directory to run these through makeinfo" \
+ "(use \`make info' here to do that automatically)."
+
+info:
+ $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
+ @echo "Running Texinfo files through makeinfo..."
+ make -C $(BUILDDIR)/texinfo info
+ @echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo."
+
+gettext:
+ $(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale
+ @echo
+ @echo "Build finished. The message catalogs are in $(BUILDDIR)/locale."
+
+changes:
+ $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes
+ @echo
+ @echo "The overview file is in $(BUILDDIR)/changes."
+
+linkcheck:
+ $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck
+ @echo
+ @echo "Link check complete; look for any errors in the above output " \
+ "or in $(BUILDDIR)/linkcheck/output.txt."
+
+doctest:
+ $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest
+ @echo "Testing of doctests in the sources finished, look at the " \
+ "results in $(BUILDDIR)/doctest/output.txt."
diff --git a/docSRC/algorithm.rst b/docSRC/algorithm.rst
new file mode 100644
index 0000000..83752bd
--- /dev/null
+++ b/docSRC/algorithm.rst
@@ -0,0 +1,8 @@
+Algorithms: the :mod:`algorithm` module
+=======================================
+
+.. automodule:: astra.algorithm
+ :members:
+ :undoc-members:
+ :show-inheritance:
+
diff --git a/docSRC/conf.py b/docSRC/conf.py
new file mode 100644
index 0000000..389f8ae
--- /dev/null
+++ b/docSRC/conf.py
@@ -0,0 +1,287 @@
+# -*- coding: utf-8 -*-
+#
+# .. documentation build configuration file, created by
+# sphinx-quickstart on Wed Mar 13 16:36:32 2013.
+#
+# This file is execfile()d with the current directory set to its containing dir.
+#
+# Note that not all possible configuration values are present in this
+# autogenerated file.
+#
+# All configuration values have a default; values that are commented out
+# serve to show the default.
+
+import sys, os
+
+# If extensions (or modules to document with autodoc) are in another directory,
+# add these directories to sys.path here. If the directory is relative to the
+# documentation root, use os.path.abspath to make it absolute, like shown here.
+#sys.path.insert(0, os.path.abspath('.'))
+
+# -- General configuration -----------------------------------------------------
+
+# If your documentation needs a minimal Sphinx version, state it here.
+#needs_sphinx = '1.0'
+
+# Add any Sphinx extension module names here, as strings. They can be extensions
+# coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
+extensions = ['sphinx.ext.autodoc', 'sphinx.ext.viewcode','sphinx.ext.mathjax','sphinx.ext.intersphinx']
+
+# Add any paths that contain templates here, relative to this directory.
+templates_path = ['_templates']
+
+# The suffix of source filenames.
+source_suffix = '.rst'
+
+# The encoding of source files.
+#source_encoding = 'utf-8-sig'
+
+# The master toctree document.
+master_doc = 'index'
+
+# General information about the project.
+project = u'PyASTRAToolbox'
+copyright = u'2013, Centrum Wiskunde & Informatica, Amsterdam'
+
+# The version info for the project you're documenting, acts as replacement for
+# |version| and |release|, also used in various other places throughout the
+# built documents.
+#
+# The short X.Y version.
+version = '1.0'
+# The full version, including alpha/beta/rc tags.
+release = '1.0'
+
+# The language for content autogenerated by Sphinx. Refer to documentation
+# for a list of supported languages.
+#language = None
+
+# There are two options for replacing |today|: either, you set today to some
+# non-false value, then it is used:
+#today = ''
+# Else, today_fmt is used as the format for a strftime call.
+#today_fmt = '%B %d, %Y'
+
+# List of patterns, relative to source directory, that match files and
+# directories to ignore when looking for source files.
+exclude_patterns = ['_build']
+
+# The reST default role (used for this markup: `text`) to use for all documents.
+#default_role = None
+
+# If true, '()' will be appended to :func: etc. cross-reference text.
+#add_function_parentheses = True
+
+# If true, the current module name will be prepended to all description
+# unit titles (such as .. function::).
+#add_module_names = True
+
+# If true, sectionauthor and moduleauthor directives will be shown in the
+# output. They are ignored by default.
+#show_authors = False
+
+# The name of the Pygments (syntax highlighting) style to use.
+pygments_style = 'sphinx'
+
+# A list of ignored prefixes for module index sorting.
+#modindex_common_prefix = []
+
+
+# -- Options for HTML output ---------------------------------------------------
+
+# The theme to use for HTML and HTML Help pages. See the documentation for
+# a list of builtin themes.
+html_theme = 'default'
+
+# Theme options are theme-specific and customize the look and feel of a theme
+# further. For a list of options available for each theme, see the
+# documentation.
+#html_theme_options = {}
+
+# Add any paths that contain custom themes here, relative to this directory.
+#html_theme_path = []
+
+# The name for this set of Sphinx documents. If None, it defaults to
+# " v documentation".
+#html_title = None
+
+# A shorter title for the navigation bar. Default is the same as html_title.
+#html_short_title = None
+
+# The name of an image file (relative to this directory) to place at the top
+# of the sidebar.
+#html_logo = None
+
+# The name of an image file (within the static path) to use as favicon of the
+# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32
+# pixels large.
+#html_favicon = None
+
+# Add any paths that contain custom static files (such as style sheets) here,
+# relative to this directory. They are copied after the builtin static files,
+# so a file named "default.css" will overwrite the builtin "default.css".
+html_static_path = ['_static']
+
+# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
+# using the given strftime format.
+#html_last_updated_fmt = '%b %d, %Y'
+
+# If true, SmartyPants will be used to convert quotes and dashes to
+# typographically correct entities.
+#html_use_smartypants = True
+
+# Custom sidebar templates, maps document names to template names.
+#html_sidebars = {}
+
+# Additional templates that should be rendered to pages, maps page names to
+# template names.
+#html_additional_pages = {}
+
+# If false, no module index is generated.
+#html_domain_indices = True
+
+# If false, no index is generated.
+#html_use_index = True
+
+# If true, the index is split into individual pages for each letter.
+#html_split_index = False
+
+# If true, links to the reST sources are added to the pages.
+#html_show_sourcelink = True
+
+# If true, "Created using Sphinx" is shown in the HTML footer. Default is True.
+#html_show_sphinx = True
+
+# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True.
+#html_show_copyright = True
+
+# If true, an OpenSearch description file will be output, and all pages will
+# contain a tag referring to it. The value of this option must be the
+# base URL from which the finished HTML is served.
+#html_use_opensearch = ''
+
+# This is the file name suffix for HTML files (e.g. ".xhtml").
+#html_file_suffix = None
+
+# Output file base name for HTML help builder.
+htmlhelp_basename = 'doc'
+
+
+# -- Options for LaTeX output --------------------------------------------------
+
+latex_elements = {
+# The paper size ('letterpaper' or 'a4paper').
+#'papersize': 'letterpaper',
+
+# The font size ('10pt', '11pt' or '12pt').
+#'pointsize': '10pt',
+
+# Additional stuff for the LaTeX preamble.
+#'preamble': '',
+}
+
+# Grouping the document tree into LaTeX files. List of tuples
+# (source start file, target name, title, author, documentclass [howto/manual]).
+latex_documents = [
+ ('index', '.tex', u'.. Documentation',
+ u'Author', 'manual'),
+]
+
+# The name of an image file (relative to this directory) to place at the top of
+# the title page.
+#latex_logo = None
+
+# For "manual" documents, if this is true, then toplevel headings are parts,
+# not chapters.
+#latex_use_parts = False
+
+# If true, show page references after internal links.
+#latex_show_pagerefs = False
+
+# If true, show URL addresses after external links.
+#latex_show_urls = False
+
+# Documents to append as an appendix to all manuals.
+#latex_appendices = []
+
+# If false, no module index is generated.
+#latex_domain_indices = True
+
+
+# -- Options for manual page output --------------------------------------------
+
+# One entry per manual page. List of tuples
+# (source start file, name, description, authors, manual section).
+man_pages = [
+ ('index', '', u'.. Documentation',
+ [u'Author'], 1)
+]
+
+# If true, show URL addresses after external links.
+#man_show_urls = False
+
+
+# -- Options for Texinfo output ------------------------------------------------
+
+# Grouping the document tree into Texinfo files. List of tuples
+# (source start file, target name, title, author,
+# dir menu entry, description, category)
+texinfo_documents = [
+ ('index', '', u'.. Documentation',
+ u'Author', '', 'One line description of project.',
+ 'Miscellaneous'),
+]
+
+# Documents to append as an appendix to all manuals.
+#texinfo_appendices = []
+
+# If false, no module index is generated.
+#texinfo_domain_indices = True
+
+# How to display URL addresses: 'footnote', 'no', or 'inline'.
+#texinfo_show_urls = 'footnote'
+
+
+# -- Options for Epub output ---------------------------------------------------
+
+# Bibliographic Dublin Core info.
+epub_title = u'..'
+epub_author = u'Author'
+epub_publisher = u'Author'
+epub_copyright = u'2013, Author'
+
+# The language of the text. It defaults to the language option
+# or en if the language is not set.
+#epub_language = ''
+
+# The scheme of the identifier. Typical schemes are ISBN or URL.
+#epub_scheme = ''
+
+# The unique identifier of the text. This can be a ISBN number
+# or the project homepage.
+#epub_identifier = ''
+
+# A unique identification for the text.
+#epub_uid = ''
+
+# A tuple containing the cover image and cover page html template filenames.
+#epub_cover = ()
+
+# HTML files that should be inserted before the pages created by sphinx.
+# The format is a list of tuples containing the path and title.
+#epub_pre_files = []
+
+# HTML files shat should be inserted after the pages created by sphinx.
+# The format is a list of tuples containing the path and title.
+#epub_post_files = []
+
+# A list of files that should not be packed into the epub file.
+#epub_exclude_files = []
+
+# The depth of the table of contents in toc.ncx.
+#epub_tocdepth = 3
+
+# Allow duplicate toc entries.
+#epub_tocdup = True
+
+intersphinx_mapping = {'python': ('http://docs.python.org/2.7', None), 'numpy':('http://docs.scipy.org/doc/numpy/',None)}
diff --git a/docSRC/creators.rst b/docSRC/creators.rst
new file mode 100644
index 0000000..d6249c3
--- /dev/null
+++ b/docSRC/creators.rst
@@ -0,0 +1,8 @@
+Creation of objects: the :mod:`creators` module
+===============================================
+
+.. automodule:: astra.creators
+ :members:
+ :undoc-members:
+ :show-inheritance:
+
diff --git a/docSRC/data2d.rst b/docSRC/data2d.rst
new file mode 100644
index 0000000..342cbec
--- /dev/null
+++ b/docSRC/data2d.rst
@@ -0,0 +1,8 @@
+2D data objects: the :mod:`data2d` module
+=========================================
+
+.. automodule:: astra.data2d
+ :members:
+ :undoc-members:
+ :show-inheritance:
+
diff --git a/docSRC/data3d.rst b/docSRC/data3d.rst
new file mode 100644
index 0000000..5b7de23
--- /dev/null
+++ b/docSRC/data3d.rst
@@ -0,0 +1,8 @@
+3D data objects: the :mod:`data3d` module
+=========================================
+
+.. automodule:: astra.data3d
+ :members:
+ :undoc-members:
+ :show-inheritance:
+
diff --git a/docSRC/functions.rst b/docSRC/functions.rst
new file mode 100644
index 0000000..749eb27
--- /dev/null
+++ b/docSRC/functions.rst
@@ -0,0 +1,8 @@
+Additional functions: the :mod:`functions` module
+=================================================
+
+.. automodule:: astra.functions
+ :members:
+ :undoc-members:
+ :show-inheritance:
+
diff --git a/docSRC/index.rst b/docSRC/index.rst
new file mode 100644
index 0000000..0170e9a
--- /dev/null
+++ b/docSRC/index.rst
@@ -0,0 +1,33 @@
+.. .. documentation master file, created by
+ sphinx-quickstart on Wed Mar 13 16:36:32 2013.
+ You can adapt this file completely to your liking, but it should at least
+ contain the root `toctree` directive.
+
+Welcome to PyASTRAToolbox's documentation!
+==========================================
+
+Contents:
+
+.. toctree::
+ :maxdepth: 4
+
+ data2d
+ data3d
+ projector
+ algorithm
+ matrix
+ creators
+ functions
+ ASTRAProjector
+ matlab
+.. astra
+.. builder
+
+
+Indices and tables
+==================
+
+* :ref:`genindex`
+* :ref:`modindex`
+* :ref:`search`
+
diff --git a/docSRC/make.bat b/docSRC/make.bat
new file mode 100644
index 0000000..d70c604
--- /dev/null
+++ b/docSRC/make.bat
@@ -0,0 +1,190 @@
+@ECHO OFF
+
+REM Command file for Sphinx documentation
+
+if "%SPHINXBUILD%" == "" (
+ set SPHINXBUILD=sphinx-build
+)
+set BUILDDIR=_build
+set ALLSPHINXOPTS=-d %BUILDDIR%/doctrees %SPHINXOPTS% .
+set I18NSPHINXOPTS=%SPHINXOPTS% .
+if NOT "%PAPER%" == "" (
+ set ALLSPHINXOPTS=-D latex_paper_size=%PAPER% %ALLSPHINXOPTS%
+ set I18NSPHINXOPTS=-D latex_paper_size=%PAPER% %I18NSPHINXOPTS%
+)
+
+if "%1" == "" goto help
+
+if "%1" == "help" (
+ :help
+ echo.Please use `make ^` where ^ is one of
+ echo. html to make standalone HTML files
+ echo. dirhtml to make HTML files named index.html in directories
+ echo. singlehtml to make a single large HTML file
+ echo. pickle to make pickle files
+ echo. json to make JSON files
+ echo. htmlhelp to make HTML files and a HTML help project
+ echo. qthelp to make HTML files and a qthelp project
+ echo. devhelp to make HTML files and a Devhelp project
+ echo. epub to make an epub
+ echo. latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter
+ echo. text to make text files
+ echo. man to make manual pages
+ echo. texinfo to make Texinfo files
+ echo. gettext to make PO message catalogs
+ echo. changes to make an overview over all changed/added/deprecated items
+ echo. linkcheck to check all external links for integrity
+ echo. doctest to run all doctests embedded in the documentation if enabled
+ goto end
+)
+
+if "%1" == "clean" (
+ for /d %%i in (%BUILDDIR%\*) do rmdir /q /s %%i
+ del /q /s %BUILDDIR%\*
+ goto end
+)
+
+if "%1" == "html" (
+ %SPHINXBUILD% -b html %ALLSPHINXOPTS% %BUILDDIR%/html
+ if errorlevel 1 exit /b 1
+ echo.
+ echo.Build finished. The HTML pages are in %BUILDDIR%/html.
+ goto end
+)
+
+if "%1" == "dirhtml" (
+ %SPHINXBUILD% -b dirhtml %ALLSPHINXOPTS% %BUILDDIR%/dirhtml
+ if errorlevel 1 exit /b 1
+ echo.
+ echo.Build finished. The HTML pages are in %BUILDDIR%/dirhtml.
+ goto end
+)
+
+if "%1" == "singlehtml" (
+ %SPHINXBUILD% -b singlehtml %ALLSPHINXOPTS% %BUILDDIR%/singlehtml
+ if errorlevel 1 exit /b 1
+ echo.
+ echo.Build finished. The HTML pages are in %BUILDDIR%/singlehtml.
+ goto end
+)
+
+if "%1" == "pickle" (
+ %SPHINXBUILD% -b pickle %ALLSPHINXOPTS% %BUILDDIR%/pickle
+ if errorlevel 1 exit /b 1
+ echo.
+ echo.Build finished; now you can process the pickle files.
+ goto end
+)
+
+if "%1" == "json" (
+ %SPHINXBUILD% -b json %ALLSPHINXOPTS% %BUILDDIR%/json
+ if errorlevel 1 exit /b 1
+ echo.
+ echo.Build finished; now you can process the JSON files.
+ goto end
+)
+
+if "%1" == "htmlhelp" (
+ %SPHINXBUILD% -b htmlhelp %ALLSPHINXOPTS% %BUILDDIR%/htmlhelp
+ if errorlevel 1 exit /b 1
+ echo.
+ echo.Build finished; now you can run HTML Help Workshop with the ^
+.hhp project file in %BUILDDIR%/htmlhelp.
+ goto end
+)
+
+if "%1" == "qthelp" (
+ %SPHINXBUILD% -b qthelp %ALLSPHINXOPTS% %BUILDDIR%/qthelp
+ if errorlevel 1 exit /b 1
+ echo.
+ echo.Build finished; now you can run "qcollectiongenerator" with the ^
+.qhcp project file in %BUILDDIR%/qthelp, like this:
+ echo.^> qcollectiongenerator %BUILDDIR%\qthelp\.qhcp
+ echo.To view the help file:
+ echo.^> assistant -collectionFile %BUILDDIR%\qthelp\.ghc
+ goto end
+)
+
+if "%1" == "devhelp" (
+ %SPHINXBUILD% -b devhelp %ALLSPHINXOPTS% %BUILDDIR%/devhelp
+ if errorlevel 1 exit /b 1
+ echo.
+ echo.Build finished.
+ goto end
+)
+
+if "%1" == "epub" (
+ %SPHINXBUILD% -b epub %ALLSPHINXOPTS% %BUILDDIR%/epub
+ if errorlevel 1 exit /b 1
+ echo.
+ echo.Build finished. The epub file is in %BUILDDIR%/epub.
+ goto end
+)
+
+if "%1" == "latex" (
+ %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex
+ if errorlevel 1 exit /b 1
+ echo.
+ echo.Build finished; the LaTeX files are in %BUILDDIR%/latex.
+ goto end
+)
+
+if "%1" == "text" (
+ %SPHINXBUILD% -b text %ALLSPHINXOPTS% %BUILDDIR%/text
+ if errorlevel 1 exit /b 1
+ echo.
+ echo.Build finished. The text files are in %BUILDDIR%/text.
+ goto end
+)
+
+if "%1" == "man" (
+ %SPHINXBUILD% -b man %ALLSPHINXOPTS% %BUILDDIR%/man
+ if errorlevel 1 exit /b 1
+ echo.
+ echo.Build finished. The manual pages are in %BUILDDIR%/man.
+ goto end
+)
+
+if "%1" == "texinfo" (
+ %SPHINXBUILD% -b texinfo %ALLSPHINXOPTS% %BUILDDIR%/texinfo
+ if errorlevel 1 exit /b 1
+ echo.
+ echo.Build finished. The Texinfo files are in %BUILDDIR%/texinfo.
+ goto end
+)
+
+if "%1" == "gettext" (
+ %SPHINXBUILD% -b gettext %I18NSPHINXOPTS% %BUILDDIR%/locale
+ if errorlevel 1 exit /b 1
+ echo.
+ echo.Build finished. The message catalogs are in %BUILDDIR%/locale.
+ goto end
+)
+
+if "%1" == "changes" (
+ %SPHINXBUILD% -b changes %ALLSPHINXOPTS% %BUILDDIR%/changes
+ if errorlevel 1 exit /b 1
+ echo.
+ echo.The overview file is in %BUILDDIR%/changes.
+ goto end
+)
+
+if "%1" == "linkcheck" (
+ %SPHINXBUILD% -b linkcheck %ALLSPHINXOPTS% %BUILDDIR%/linkcheck
+ if errorlevel 1 exit /b 1
+ echo.
+ echo.Link check complete; look for any errors in the above output ^
+or in %BUILDDIR%/linkcheck/output.txt.
+ goto end
+)
+
+if "%1" == "doctest" (
+ %SPHINXBUILD% -b doctest %ALLSPHINXOPTS% %BUILDDIR%/doctest
+ if errorlevel 1 exit /b 1
+ echo.
+ echo.Testing of doctests in the sources finished, look at the ^
+results in %BUILDDIR%/doctest/output.txt.
+ goto end
+)
+
+:end
diff --git a/docSRC/matlab.rst b/docSRC/matlab.rst
new file mode 100644
index 0000000..fb7033e
--- /dev/null
+++ b/docSRC/matlab.rst
@@ -0,0 +1,8 @@
+MATLAB compatibility interface: the :mod:`matlab` module
+========================================================
+
+.. automodule:: astra.matlab
+ :members:
+ :undoc-members:
+ :show-inheritance:
+
diff --git a/docSRC/matrix.rst b/docSRC/matrix.rst
new file mode 100644
index 0000000..6f11d8a
--- /dev/null
+++ b/docSRC/matrix.rst
@@ -0,0 +1,8 @@
+Sparse matrices: the :mod:`matrix` module
+=========================================
+
+.. automodule:: astra.matrix
+ :members:
+ :undoc-members:
+ :show-inheritance:
+
diff --git a/docSRC/projector.rst b/docSRC/projector.rst
new file mode 100644
index 0000000..b0854e8
--- /dev/null
+++ b/docSRC/projector.rst
@@ -0,0 +1,8 @@
+Projector object: the :mod:`projector` module
+=============================================
+
+.. automodule:: astra.projector
+ :members:
+ :undoc-members:
+ :show-inheritance:
+
diff --git a/examples/phantom.mat b/examples/phantom.mat
new file mode 100644
index 0000000..c465bbe
Binary files /dev/null and b/examples/phantom.mat differ
diff --git a/examples/s001_sinogram_par2d.py b/examples/s001_sinogram_par2d.py
new file mode 100644
index 0000000..009d9b3
--- /dev/null
+++ b/examples/s001_sinogram_par2d.py
@@ -0,0 +1,60 @@
+#-----------------------------------------------------------------------
+#Copyright 2013 Centrum Wiskunde & Informatica, Amsterdam
+#
+#Author: Daniel M. Pelt
+#Contact: D.M.Pelt@cwi.nl
+#Website: http://dmpelt.github.io/pyastratoolbox/
+#
+#
+#This file is part of the Python interface to the
+#All Scale Tomographic Reconstruction Antwerp Toolbox ("ASTRA Toolbox").
+#
+#The Python interface to the ASTRA Toolbox 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.
+#
+#The Python interface to the ASTRA Toolbox 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 the Python interface to the ASTRA Toolbox. If not, see .
+#
+#-----------------------------------------------------------------------
+
+import astra
+import numpy as np
+
+# Create a basic 256x256 square volume geometry
+vol_geom = astra.create_vol_geom(256, 256)
+
+# Create a parallel beam geometry with 180 angles between 0 and pi, and
+# 384 detector pixels of width 1.
+# For more details on available geometries, see the online help of the
+# function astra_create_proj_geom .
+proj_geom = astra.create_proj_geom('parallel', 1.0, 384, np.linspace(0,np.pi,180,False))
+
+# Load a 256x256 phantom image
+import scipy.io
+P = scipy.io.loadmat('phantom.mat')['phantom256']
+
+# Create a sinogram using the GPU.
+# Note that the first time the GPU is accessed, there may be a delay
+# of up to 10 seconds for initialization.
+proj_id = astra.create_projector('line',proj_geom,vol_geom)
+sinogram_id, sinogram = astra.create_sino(P, proj_id,useCUDA=True)
+
+import pylab
+pylab.gray()
+pylab.figure(1)
+pylab.imshow(P)
+pylab.figure(2)
+pylab.imshow(sinogram)
+pylab.show()
+
+
+# Free memory
+astra.data2d.delete(sinogram_id)
+astra.projector.delete(proj_id)
diff --git a/examples/s002_data2d.py b/examples/s002_data2d.py
new file mode 100644
index 0000000..35fb91f
--- /dev/null
+++ b/examples/s002_data2d.py
@@ -0,0 +1,77 @@
+#-----------------------------------------------------------------------
+#Copyright 2013 Centrum Wiskunde & Informatica, Amsterdam
+#
+#Author: Daniel M. Pelt
+#Contact: D.M.Pelt@cwi.nl
+#Website: http://dmpelt.github.io/pyastratoolbox/
+#
+#
+#This file is part of the Python interface to the
+#All Scale Tomographic Reconstruction Antwerp Toolbox ("ASTRA Toolbox").
+#
+#The Python interface to the ASTRA Toolbox 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.
+#
+#The Python interface to the ASTRA Toolbox 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 the Python interface to the ASTRA Toolbox. If not, see .
+#
+#-----------------------------------------------------------------------
+
+import astra
+import numpy as np
+
+vol_geom = astra.create_vol_geom(256, 256)
+
+proj_geom = astra.create_proj_geom('parallel', 1.0, 384, np.linspace(0,np.pi,180,False))
+
+
+# Create volumes
+
+# initialized to zero
+v0 = astra.data2d.create('-vol', vol_geom)
+
+# initialized to 3.0
+v1 = astra.data2d.create('-vol', vol_geom, 3.0)
+
+# initialized to a matrix. A may be a single, double or logical (0/1) array.
+import scipy.io
+A = scipy.io.loadmat('phantom.mat')['phantom256']
+v2 = astra.data2d.create('-vol', vol_geom, A)
+
+
+# Projection data
+s0 = astra.data2d.create('-sino', proj_geom)
+# Initialization to a scalar or a matrix also works, exactly as with a volume.
+
+
+# Update data
+
+# set to zero
+astra.data2d.store(v0, 0)
+
+# set to a matrix
+astra.data2d.store(v2, A)
+
+
+
+# Retrieve data
+
+R = astra.data2d.get(v2)
+import pylab
+pylab.gray()
+pylab.imshow(R)
+pylab.show()
+
+
+# Free memory
+astra.data2d.delete(v0)
+astra.data2d.delete(v1)
+astra.data2d.delete(v2)
+astra.data2d.delete(s0)
diff --git a/examples/s003_gpu_reconstruction.py b/examples/s003_gpu_reconstruction.py
new file mode 100644
index 0000000..4f6ec1f
--- /dev/null
+++ b/examples/s003_gpu_reconstruction.py
@@ -0,0 +1,75 @@
+#-----------------------------------------------------------------------
+#Copyright 2013 Centrum Wiskunde & Informatica, Amsterdam
+#
+#Author: Daniel M. Pelt
+#Contact: D.M.Pelt@cwi.nl
+#Website: http://dmpelt.github.io/pyastratoolbox/
+#
+#
+#This file is part of the Python interface to the
+#All Scale Tomographic Reconstruction Antwerp Toolbox ("ASTRA Toolbox").
+#
+#The Python interface to the ASTRA Toolbox 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.
+#
+#The Python interface to the ASTRA Toolbox 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 the Python interface to the ASTRA Toolbox. If not, see .
+#
+#-----------------------------------------------------------------------
+
+import astra
+import numpy as np
+
+vol_geom = astra.create_vol_geom(256, 256)
+proj_geom = astra.create_proj_geom('parallel', 1.0, 384, np.linspace(0,np.pi,180,False))
+
+# As before, create a sinogram from a phantom
+import scipy.io
+P = scipy.io.loadmat('phantom.mat')['phantom256']
+proj_id = astra.create_projector('line',proj_geom,vol_geom)
+sinogram_id, sinogram = astra.create_sino(P, proj_id,useCUDA=True)
+
+import pylab
+pylab.gray()
+pylab.figure(1)
+pylab.imshow(P)
+pylab.figure(2)
+pylab.imshow(sinogram)
+
+# Create a data object for the reconstruction
+rec_id = astra.data2d.create('-vol', vol_geom)
+
+# Set up the parameters for a reconstruction algorithm using the GPU
+cfg = astra.astra_dict('SIRT_CUDA')
+cfg['ReconstructionDataId'] = rec_id
+cfg['ProjectionDataId'] = sinogram_id
+
+# Available algorithms:
+# SIRT_CUDA, SART_CUDA, EM_CUDA, FBP_CUDA (see the FBP sample)
+
+
+# Create the algorithm object from the configuration structure
+alg_id = astra.algorithm.create(cfg)
+
+# Run 150 iterations of the algorithm
+astra.algorithm.run(alg_id, 150)
+
+# Get the result
+rec = astra.data2d.get(rec_id)
+pylab.figure(3)
+pylab.imshow(rec)
+pylab.show()
+
+# Clean up. Note that GPU memory is tied up in the algorithm object,
+# and main RAM in the data objects.
+astra.algorithm.delete(alg_id)
+astra.data2d.delete(rec_id)
+astra.data2d.delete(sinogram_id)
+astra.projector.delete(proj_id)
diff --git a/examples/s004_cpu_reconstruction.py b/examples/s004_cpu_reconstruction.py
new file mode 100644
index 0000000..8385cf8
--- /dev/null
+++ b/examples/s004_cpu_reconstruction.py
@@ -0,0 +1,81 @@
+#-----------------------------------------------------------------------
+#Copyright 2013 Centrum Wiskunde & Informatica, Amsterdam
+#
+#Author: Daniel M. Pelt
+#Contact: D.M.Pelt@cwi.nl
+#Website: http://dmpelt.github.io/pyastratoolbox/
+#
+#
+#This file is part of the Python interface to the
+#All Scale Tomographic Reconstruction Antwerp Toolbox ("ASTRA Toolbox").
+#
+#The Python interface to the ASTRA Toolbox 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.
+#
+#The Python interface to the ASTRA Toolbox 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 the Python interface to the ASTRA Toolbox. If not, see .
+#
+#-----------------------------------------------------------------------
+
+import astra
+import numpy as np
+
+vol_geom = astra.create_vol_geom(256, 256)
+proj_geom = astra.create_proj_geom('parallel', 1.0, 384, np.linspace(0,np.pi,180,False))
+
+# For CPU-based algorithms, a "projector" object specifies the projection
+# model used. In this case, we use the "strip" model.
+proj_id = astra.create_projector('strip', proj_geom, vol_geom)
+
+# Create a sinogram from a phantom
+import scipy.io
+P = scipy.io.loadmat('phantom.mat')['phantom256']
+sinogram_id, sinogram = astra.create_sino(P, proj_id)
+
+import pylab
+pylab.gray()
+pylab.figure(1)
+pylab.imshow(P)
+pylab.figure(2)
+pylab.imshow(sinogram)
+
+# Create a data object for the reconstruction
+rec_id = astra.data2d.create('-vol', vol_geom)
+
+# Set up the parameters for a reconstruction algorithm using the CPU
+# The main difference with the configuration of a GPU algorithm is the
+# extra ProjectorId setting.
+cfg = astra.astra_dict('SIRT')
+cfg['ReconstructionDataId'] = rec_id
+cfg['ProjectionDataId'] = sinogram_id
+cfg['ProjectorId'] = proj_id
+
+# Available algorithms:
+# ART, SART, SIRT, CGLS, FBP
+
+
+# Create the algorithm object from the configuration structure
+alg_id = astra.algorithm.create(cfg)
+
+# Run 20 iterations of the algorithm
+# This will have a runtime in the order of 10 seconds.
+astra.algorithm.run(alg_id, 20)
+
+# Get the result
+rec = astra.data2d.get(rec_id)
+pylab.figure(3)
+pylab.imshow(rec)
+pylab.show()
+
+# Clean up.
+astra.algorithm.delete(alg_id)
+astra.data2d.delete(rec_id)
+astra.data2d.delete(sinogram_id)
+astra.projector.delete(proj_id)
diff --git a/examples/s005_3d_geometry.py b/examples/s005_3d_geometry.py
new file mode 100644
index 0000000..5ed6061
--- /dev/null
+++ b/examples/s005_3d_geometry.py
@@ -0,0 +1,113 @@
+#-----------------------------------------------------------------------
+#Copyright 2013 Centrum Wiskunde & Informatica, Amsterdam
+#
+#Author: Daniel M. Pelt
+#Contact: D.M.Pelt@cwi.nl
+#Website: http://dmpelt.github.io/pyastratoolbox/
+#
+#
+#This file is part of the Python interface to the
+#All Scale Tomographic Reconstruction Antwerp Toolbox ("ASTRA Toolbox").
+#
+#The Python interface to the ASTRA Toolbox 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.
+#
+#The Python interface to the ASTRA Toolbox 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 the Python interface to the ASTRA Toolbox. If not, see .
+#
+#-----------------------------------------------------------------------
+
+import astra
+import numpy as np
+
+vol_geom = astra.create_vol_geom(64, 64, 64)
+
+
+# There are two main 3d projection geometry types: cone beam and parallel beam.
+# Each has a regular variant, and a 'vec' variant.
+# The 'vec' variants are completely free in the placement of source/detector,
+# while the regular variants assume circular trajectories around the z-axis.
+
+
+# -------------
+# Parallel beam
+# -------------
+
+
+# Circular
+
+# Parameters: width of detector column, height of detector row, #rows, #columns
+angles = np.linspace(0, 2*np.pi, 48,False)
+proj_geom = astra.create_proj_geom('parallel3d', 1.0, 1.0, 32, 64, angles)
+
+
+# Free
+
+# We generate the same geometry as the circular one above.
+vectors = np.zeros((len(angles), 12))
+for i in xrange(len(angles)):
+ # ray direction
+ vectors[i,0] = np.sin(angles[i])
+ vectors[i,1] = -np.cos(angles[i])
+ vectors[i,2] = 0
+
+ # center of detector
+ vectors[i,3:6] = 0
+
+ # vector from detector pixel (0,0) to (0,1)
+ vectors[i,6] = np.cos(angles[i])
+ vectors[i,7] = np.sin(angles[i])
+ vectors[i,8] = 0;
+
+ # vector from detector pixel (0,0) to (1,0)
+ vectors[i,9] = 0
+ vectors[i,10] = 0
+ vectors[i,11] = 1
+
+# Parameters: #rows, #columns, vectors
+proj_geom = astra.create_proj_geom('parallel3d_vec', 32, 64, vectors)
+
+# ----------
+# Cone beam
+# ----------
+
+
+# Circular
+
+# Parameters: width of detector column, height of detector row, #rows, #columns,
+# angles, distance source-origin, distance origin-detector
+angles = np.linspace(0, 2*np.pi, 48,False)
+proj_geom = astra.create_proj_geom('cone', 1.0, 1.0, 32, 64, angles, 1000, 0)
+
+# Free
+
+vectors = np.zeros((len(angles), 12))
+for i in xrange(len(angles)):
+ # source
+ vectors[i,0] = np.sin(angles[i]) * 1000
+ vectors[i,1] = -np.cos(angles[i]) * 1000
+ vectors[i,2] = 0
+
+ # center of detector
+ vectors[i,3:6] = 0
+
+ # vector from detector pixel (0,0) to (0,1)
+ vectors[i,6] = np.cos(angles[i])
+ vectors[i,7] = np.sin(angles[i])
+ vectors[i,8] = 0
+
+ # vector from detector pixel (0,0) to (1,0)
+ vectors[i,9] = 0
+ vectors[i,10] = 0
+ vectors[i,11] = 1
+
+# Parameters: #rows, #columns, vectors
+proj_geom = astra.create_proj_geom('cone_vec', 32, 64, vectors)
+
diff --git a/examples/s006_3d_data.py b/examples/s006_3d_data.py
new file mode 100644
index 0000000..8794b12
--- /dev/null
+++ b/examples/s006_3d_data.py
@@ -0,0 +1,76 @@
+#-----------------------------------------------------------------------
+#Copyright 2013 Centrum Wiskunde & Informatica, Amsterdam
+#
+#Author: Daniel M. Pelt
+#Contact: D.M.Pelt@cwi.nl
+#Website: http://dmpelt.github.io/pyastratoolbox/
+#
+#
+#This file is part of the Python interface to the
+#All Scale Tomographic Reconstruction Antwerp Toolbox ("ASTRA Toolbox").
+#
+#The Python interface to the ASTRA Toolbox 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.
+#
+#The Python interface to the ASTRA Toolbox 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 the Python interface to the ASTRA Toolbox. If not, see .
+#
+#-----------------------------------------------------------------------
+
+import astra
+import numpy as np
+
+# Create a 3D volume geometry.
+# Parameter order: rows, colums, slices (y, x, z)
+vol_geom = astra.create_vol_geom(64, 48, 32)
+
+
+# Create volumes
+
+# initialized to zero
+v0 = astra.data3d.create('-vol', vol_geom)
+
+# initialized to 3.0
+v1 = astra.data3d.create('-vol', vol_geom, 3.0)
+
+# initialized to a matrix. A may be a single or double array.
+# Coordinate order: column, row, slice (x, y, z)
+A = np.zeros((48, 64, 32))
+v2 = astra.data3d.create('-vol', vol_geom, A)
+
+
+# Projection data
+
+# 2 projection directions, along x and y axis resp.
+V = np.array([[ 1,0,0, 0,0,0, 0,1,0, 0,0,1],
+ [0,1,0, 0,0,0, -1,0,0, 0,0,1]],dtype=np.float)
+# 32 rows (v), 64 columns (u)
+proj_geom = astra.create_proj_geom('parallel3d_vec', 32, 64, V)
+
+s0 = astra.data3d.create('-proj3d', proj_geom)
+
+# Initialization to a scalar or zero works exactly as with a volume.
+
+# Initialized to a matrix:
+# Coordinate order: column (u), angle, row (v)
+A = np.zeros((64, 2, 32))
+s1 = astra.data3d.create('-proj3d', proj_geom, A)
+
+
+# Retrieve data:
+R = astra.data3d.get(v1)
+
+
+# Delete all created data objects
+astra.data3d.delete(v0)
+astra.data3d.delete(v1)
+astra.data3d.delete(v2)
+astra.data3d.delete(s0)
+astra.data3d.delete(s1)
diff --git a/examples/s007_3d_reconstruction.py b/examples/s007_3d_reconstruction.py
new file mode 100644
index 0000000..40e9556
--- /dev/null
+++ b/examples/s007_3d_reconstruction.py
@@ -0,0 +1,77 @@
+#-----------------------------------------------------------------------
+#Copyright 2013 Centrum Wiskunde & Informatica, Amsterdam
+#
+#Author: Daniel M. Pelt
+#Contact: D.M.Pelt@cwi.nl
+#Website: http://dmpelt.github.io/pyastratoolbox/
+#
+#
+#This file is part of the Python interface to the
+#All Scale Tomographic Reconstruction Antwerp Toolbox ("ASTRA Toolbox").
+#
+#The Python interface to the ASTRA Toolbox 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.
+#
+#The Python interface to the ASTRA Toolbox 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 the Python interface to the ASTRA Toolbox. If not, see .
+#
+#-----------------------------------------------------------------------
+
+import astra
+import numpy as np
+
+vol_geom = astra.create_vol_geom(128, 128, 128)
+
+angles = np.linspace(0, np.pi, 180,False)
+proj_geom = astra.create_proj_geom('parallel3d', 1.0, 1.0, 128, 192, angles)
+
+# Create a simple hollow cube phantom
+cube = np.zeros((128,128,128))
+cube[17:113,17:113,17:113] = 1
+cube[33:97,33:97,33:97] = 0
+
+# Create projection data from this
+proj_id, proj_data = astra.create_sino3d_gpu(cube, proj_geom, vol_geom)
+
+# Display a single projection image
+import pylab
+pylab.gray()
+pylab.figure(1)
+pylab.imshow(proj_data[:,20,:])
+
+# Create a data object for the reconstruction
+rec_id = astra.data3d.create('-vol', vol_geom)
+
+# Set up the parameters for a reconstruction algorithm using the GPU
+cfg = astra.astra_dict('SIRT3D_CUDA')
+cfg['ReconstructionDataId'] = rec_id
+cfg['ProjectionDataId'] = proj_id
+
+
+# Create the algorithm object from the configuration structure
+alg_id = astra.algorithm.create(cfg)
+
+# Run 150 iterations of the algorithm
+# Note that this requires about 750MB of GPU memory, and has a runtime
+# in the order of 10 seconds.
+astra.algorithm.run(alg_id, 150)
+
+# Get the result
+rec = astra.data3d.get(rec_id)
+pylab.figure(2)
+pylab.imshow(rec[:,:,65])
+pylab.show()
+
+
+# Clean up. Note that GPU memory is tied up in the algorithm object,
+# and main RAM in the data objects.
+astra.algorithm.delete(alg_id)
+astra.data3d.delete(rec_id)
+astra.data3d.delete(proj_id)
diff --git a/examples/s008_gpu_selection.py b/examples/s008_gpu_selection.py
new file mode 100644
index 0000000..c42e53b
--- /dev/null
+++ b/examples/s008_gpu_selection.py
@@ -0,0 +1,61 @@
+#-----------------------------------------------------------------------
+#Copyright 2013 Centrum Wiskunde & Informatica, Amsterdam
+#
+#Author: Daniel M. Pelt
+#Contact: D.M.Pelt@cwi.nl
+#Website: http://dmpelt.github.io/pyastratoolbox/
+#
+#
+#This file is part of the Python interface to the
+#All Scale Tomographic Reconstruction Antwerp Toolbox ("ASTRA Toolbox").
+#
+#The Python interface to the ASTRA Toolbox 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.
+#
+#The Python interface to the ASTRA Toolbox 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 the Python interface to the ASTRA Toolbox. If not, see .
+#
+#-----------------------------------------------------------------------
+
+import astra
+import numpy as np
+
+vol_geom = astra.create_vol_geom(256, 256)
+proj_geom = astra.create_proj_geom('parallel', 1.0, 384, np.linspace(0,np.pi,180,False))
+import scipy.io
+P = scipy.io.loadmat('phantom.mat')['phantom256']
+
+proj_id = astra.create_projector('line',proj_geom,vol_geom)
+
+# Create a sinogram from a phantom, using GPU #1. (The default is #0)
+sinogram_id, sinogram = astra.create_sino(P, proj_id, useCUDA=True, gpuIndex=1)
+
+
+# Set up the parameters for a reconstruction algorithm using the GPU
+rec_id = astra.data2d.create('-vol', vol_geom)
+cfg = astra.astra_dict('SIRT_CUDA')
+cfg['ReconstructionDataId'] = rec_id
+cfg['ProjectionDataId'] = sinogram_id
+
+# Use GPU #1 for the reconstruction. (The default is #0.)
+cfg['option'] = {}
+cfg['option']['GPUindex'] = 1
+
+# Run 150 iterations of the algorithm
+alg_id = astra.algorithm.create(cfg)
+astra.algorithm.run(alg_id, 150)
+rec = astra.data2d.get(rec_id)
+
+
+# Clean up.
+astra.algorithm.delete(alg_id)
+astra.data2d.delete(rec_id)
+astra.data2d.delete(sinogram_id)
+astra.projector.delete(proj_id)
diff --git a/examples/s009_projection_matrix.py b/examples/s009_projection_matrix.py
new file mode 100644
index 0000000..2ff0280
--- /dev/null
+++ b/examples/s009_projection_matrix.py
@@ -0,0 +1,65 @@
+#-----------------------------------------------------------------------
+#Copyright 2013 Centrum Wiskunde & Informatica, Amsterdam
+#
+#Author: Daniel M. Pelt
+#Contact: D.M.Pelt@cwi.nl
+#Website: http://dmpelt.github.io/pyastratoolbox/
+#
+#
+#This file is part of the Python interface to the
+#All Scale Tomographic Reconstruction Antwerp Toolbox ("ASTRA Toolbox").
+#
+#The Python interface to the ASTRA Toolbox 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.
+#
+#The Python interface to the ASTRA Toolbox 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 the Python interface to the ASTRA Toolbox. If not, see .
+#
+#-----------------------------------------------------------------------
+
+import astra
+import numpy as np
+
+vol_geom = astra.create_vol_geom(256, 256)
+proj_geom = astra.create_proj_geom('parallel', 1.0, 384, np.linspace(0,np.pi,180,False))
+
+# For CPU-based algorithms, a "projector" object specifies the projection
+# model used. In this case, we use the "line" model.
+proj_id = astra.create_projector('line', proj_geom, vol_geom)
+
+# Generate the projection matrix for this projection model.
+# This creates a matrix W where entry w_{i,j} corresponds to the
+# contribution of volume element j to detector element i.
+matrix_id = astra.projector.matrix(proj_id)
+
+# Get the projection matrix as a Matlab sparse matrix.
+W = astra.matrix.get(matrix_id)
+
+
+# Manually use this projection matrix to do a projection:
+import scipy.io
+P = scipy.io.loadmat('phantom.mat')['phantom256']
+s = W.dot(P.flatten())
+s = np.reshape(s, (len(proj_geom['ProjectionAngles']),proj_geom['DetectorCount']))
+
+import pylab
+pylab.gray()
+pylab.figure(1)
+pylab.imshow(s)
+pylab.show()
+
+# Each row of the projection matrix corresponds to a detector element.
+# Detector t for angle p is for row 1 + t + p*proj_geom.DetectorCount.
+# Each column corresponds to a volume pixel.
+# Pixel (x,y) corresponds to column 1 + x + y*vol_geom.GridColCount.
+
+
+astra.projector.delete(proj_id)
+astra.matrix.delete(matrix_id)
diff --git a/examples/s010_supersampling.py b/examples/s010_supersampling.py
new file mode 100644
index 0000000..1a337bc
--- /dev/null
+++ b/examples/s010_supersampling.py
@@ -0,0 +1,85 @@
+#-----------------------------------------------------------------------
+#Copyright 2013 Centrum Wiskunde & Informatica, Amsterdam
+#
+#Author: Daniel M. Pelt
+#Contact: D.M.Pelt@cwi.nl
+#Website: http://dmpelt.github.io/pyastratoolbox/
+#
+#
+#This file is part of the Python interface to the
+#All Scale Tomographic Reconstruction Antwerp Toolbox ("ASTRA Toolbox").
+#
+#The Python interface to the ASTRA Toolbox 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.
+#
+#The Python interface to the ASTRA Toolbox 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 the Python interface to the ASTRA Toolbox. If not, see .
+#
+#-----------------------------------------------------------------------
+
+import astra
+import numpy as np
+
+vol_geom = astra.create_vol_geom(256, 256)
+proj_geom = astra.create_proj_geom('parallel', 3.0, 128, np.linspace(0,np.pi,180,False))
+import scipy.io
+P = scipy.io.loadmat('phantom.mat')['phantom256']
+
+# Because the astra.create_sino method does not have support for
+# all possible algorithm options, we manually create a sinogram
+phantom_id = astra.data2d.create('-vol', vol_geom, P)
+sinogram_id = astra.data2d.create('-sino', proj_geom)
+cfg = astra.astra_dict('FP_CUDA')
+cfg['VolumeDataId'] = phantom_id
+cfg['ProjectionDataId'] = sinogram_id
+
+# Set up 3 rays per detector element
+cfg['option'] = {}
+cfg['option']['DetectorSuperSampling'] = 3
+
+alg_id = astra.algorithm.create(cfg)
+astra.algorithm.run(alg_id)
+astra.algorithm.delete(alg_id)
+astra.data2d.delete(phantom_id)
+
+sinogram3 = astra.data2d.get(sinogram_id)
+
+import pylab
+pylab.gray()
+pylab.figure(1)
+pylab.imshow(P)
+pylab.figure(2)
+pylab.imshow(sinogram3)
+
+# Create a reconstruction, also using supersampling
+rec_id = astra.data2d.create('-vol', vol_geom)
+cfg = astra.astra_dict('SIRT_CUDA')
+cfg['ReconstructionDataId'] = rec_id
+cfg['ProjectionDataId'] = sinogram_id
+# Set up 3 rays per detector element
+cfg['option'] = {}
+cfg['option']['DetectorSuperSampling'] = 3
+
+# There is also an option for supersampling during the backprojection step.
+# This should be used if your detector pixels are smaller than the voxels.
+
+# Set up 2 rays per image pixel dimension, for 4 rays total per image pixel.
+# cfg['option']['PixelSuperSampling'] = 2
+
+
+alg_id = astra.algorithm.create(cfg)
+astra.algorithm.run(alg_id, 150)
+astra.algorithm.delete(alg_id)
+
+rec = astra.data2d.get(rec_id)
+pylab.figure(3)
+pylab.imshow(rec)
+pylab.show()
+
diff --git a/examples/s011_object_info.py b/examples/s011_object_info.py
new file mode 100644
index 0000000..02f387a
--- /dev/null
+++ b/examples/s011_object_info.py
@@ -0,0 +1,54 @@
+#-----------------------------------------------------------------------
+#Copyright 2013 Centrum Wiskunde & Informatica, Amsterdam
+#
+#Author: Daniel M. Pelt
+#Contact: D.M.Pelt@cwi.nl
+#Website: http://dmpelt.github.io/pyastratoolbox/
+#
+#
+#This file is part of the Python interface to the
+#All Scale Tomographic Reconstruction Antwerp Toolbox ("ASTRA Toolbox").
+#
+#The Python interface to the ASTRA Toolbox 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.
+#
+#The Python interface to the ASTRA Toolbox 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 the Python interface to the ASTRA Toolbox. If not, see .
+#
+#-----------------------------------------------------------------------
+
+import astra
+
+# Create two volume geometries
+vol_geom1 = astra.create_vol_geom(256, 256)
+vol_geom2 = astra.create_vol_geom(512, 256)
+
+# Create volumes
+v0 = astra.data2d.create('-vol', vol_geom1)
+v1 = astra.data2d.create('-vol', vol_geom2)
+v2 = astra.data2d.create('-vol', vol_geom2)
+
+# Show the currently allocated volumes
+astra.data2d.info()
+
+
+astra.data2d.delete(v2)
+astra.data2d.info()
+
+astra.data2d.clear()
+astra.data2d.info()
+
+
+
+# The same clear and info command also work for other object types:
+astra.algorithm.info()
+astra.data3d.info()
+astra.projector.info()
+astra.matrix.info()
diff --git a/examples/s012_masks.py b/examples/s012_masks.py
new file mode 100644
index 0000000..441d11b
--- /dev/null
+++ b/examples/s012_masks.py
@@ -0,0 +1,92 @@
+#-----------------------------------------------------------------------
+#Copyright 2013 Centrum Wiskunde & Informatica, Amsterdam
+#
+#Author: Daniel M. Pelt
+#Contact: D.M.Pelt@cwi.nl
+#Website: http://dmpelt.github.io/pyastratoolbox/
+#
+#
+#This file is part of the Python interface to the
+#All Scale Tomographic Reconstruction Antwerp Toolbox ("ASTRA Toolbox").
+#
+#The Python interface to the ASTRA Toolbox 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.
+#
+#The Python interface to the ASTRA Toolbox 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 the Python interface to the ASTRA Toolbox. If not, see .
+#
+#-----------------------------------------------------------------------
+
+
+import astra
+import numpy as np
+
+# In this example we will create a reconstruction in a circular region,
+# instead of the usual rectangle.
+
+# This is done by placing a circular mask on the square reconstruction volume:
+
+c = np.linspace(-127.5,127.5,256)
+x, y = np.meshgrid(c,c)
+mask = np.array((x**2 + y**2 < 127.5**2),dtype=np.float)
+
+import pylab
+pylab.gray()
+pylab.figure(1)
+pylab.imshow(mask)
+
+vol_geom = astra.create_vol_geom(256, 256)
+proj_geom = astra.create_proj_geom('parallel', 1.0, 384, np.linspace(0,np.pi,50,False))
+
+# As before, create a sinogram from a phantom
+import scipy.io
+P = scipy.io.loadmat('phantom.mat')['phantom256']
+proj_id = astra.create_projector('line',proj_geom,vol_geom)
+sinogram_id, sinogram = astra.create_sino(P, proj_id,useCUDA=True)
+
+pylab.figure(2)
+pylab.imshow(P)
+pylab.figure(3)
+pylab.imshow(sinogram)
+
+# Create a data object for the reconstruction
+rec_id = astra.data2d.create('-vol', vol_geom)
+
+# Create a data object for the mask
+mask_id = astra.data2d.create('-vol', vol_geom, mask)
+
+# Set up the parameters for a reconstruction algorithm using the GPU
+cfg = astra.astra_dict('SIRT_CUDA')
+cfg['ReconstructionDataId'] = rec_id
+cfg['ProjectionDataId'] = sinogram_id
+cfg['option'] = {}
+cfg['option']['ReconstructionMaskId'] = mask_id
+
+# Create the algorithm object from the configuration structure
+alg_id = astra.algorithm.create(cfg)
+
+# Run 150 iterations of the algorithm
+astra.algorithm.run(alg_id, 150)
+
+# Get the result
+rec = astra.data2d.get(rec_id)
+
+pylab.figure(4)
+pylab.imshow(rec)
+
+pylab.show()
+
+# Clean up. Note that GPU memory is tied up in the algorithm object,
+# and main RAM in the data objects.
+astra.algorithm.delete(alg_id)
+astra.data2d.delete(mask_id)
+astra.data2d.delete(rec_id)
+astra.data2d.delete(sinogram_id)
+astra.projector.delete(proj_id)
diff --git a/examples/s013_constraints.py b/examples/s013_constraints.py
new file mode 100644
index 0000000..009360e
--- /dev/null
+++ b/examples/s013_constraints.py
@@ -0,0 +1,77 @@
+#-----------------------------------------------------------------------
+#Copyright 2013 Centrum Wiskunde & Informatica, Amsterdam
+#
+#Author: Daniel M. Pelt
+#Contact: D.M.Pelt@cwi.nl
+#Website: http://dmpelt.github.io/pyastratoolbox/
+#
+#
+#This file is part of the Python interface to the
+#All Scale Tomographic Reconstruction Antwerp Toolbox ("ASTRA Toolbox").
+#
+#The Python interface to the ASTRA Toolbox 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.
+#
+#The Python interface to the ASTRA Toolbox 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 the Python interface to the ASTRA Toolbox. If not, see .
+#
+#-----------------------------------------------------------------------
+
+import astra
+import numpy as np
+
+# In this example we will create a reconstruction constrained to
+# greyvalues between 0 and 1
+
+vol_geom = astra.create_vol_geom(256, 256)
+proj_geom = astra.create_proj_geom('parallel', 1.0, 384, np.linspace(0,np.pi,50,False))
+
+# As before, create a sinogram from a phantom
+import scipy.io
+P = scipy.io.loadmat('phantom.mat')['phantom256']
+proj_id = astra.create_projector('line',proj_geom,vol_geom)
+sinogram_id, sinogram = astra.create_sino(P, proj_id,useCUDA=True)
+
+import pylab
+pylab.gray()
+pylab.figure(1)
+pylab.imshow(P)
+pylab.figure(2)
+pylab.imshow(sinogram)
+
+# Create a data object for the reconstruction
+rec_id = astra.data2d.create('-vol', vol_geom)
+
+# Set up the parameters for a reconstruction algorithm using the GPU
+cfg = astra.astra_dict('SIRT_CUDA')
+cfg['ReconstructionDataId'] = rec_id
+cfg['ProjectionDataId'] = sinogram_id
+cfg['option']={}
+cfg['option']['MinConstraint'] = 0
+cfg['option']['MaxConstraint'] = 1
+
+# Create the algorithm object from the configuration structure
+alg_id = astra.algorithm.create(cfg)
+
+# Run 150 iterations of the algorithm
+astra.algorithm.run(alg_id, 150)
+
+# Get the result
+rec = astra.data2d.get(rec_id)
+pylab.figure(3)
+pylab.imshow(rec)
+pylab.show()
+
+# Clean up. Note that GPU memory is tied up in the algorithm object,
+# and main RAM in the data objects.
+astra.algorithm.delete(alg_id)
+astra.data2d.delete(rec_id)
+astra.data2d.delete(sinogram_id)
+astra.projector.delete(proj_id)
diff --git a/examples/s014_FBP.py b/examples/s014_FBP.py
new file mode 100644
index 0000000..ef4afc2
--- /dev/null
+++ b/examples/s014_FBP.py
@@ -0,0 +1,76 @@
+#-----------------------------------------------------------------------
+#Copyright 2013 Centrum Wiskunde & Informatica, Amsterdam
+#
+#Author: Daniel M. Pelt
+#Contact: D.M.Pelt@cwi.nl
+#Website: http://dmpelt.github.io/pyastratoolbox/
+#
+#
+#This file is part of the Python interface to the
+#All Scale Tomographic Reconstruction Antwerp Toolbox ("ASTRA Toolbox").
+#
+#The Python interface to the ASTRA Toolbox 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.
+#
+#The Python interface to the ASTRA Toolbox 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 the Python interface to the ASTRA Toolbox. If not, see .
+#
+#-----------------------------------------------------------------------
+
+import astra
+import numpy as np
+
+vol_geom = astra.create_vol_geom(256, 256)
+proj_geom = astra.create_proj_geom('parallel', 1.0, 384, np.linspace(0,np.pi,180,False))
+
+# As before, create a sinogram from a phantom
+import scipy.io
+P = scipy.io.loadmat('phantom.mat')['phantom256']
+proj_id = astra.create_projector('line',proj_geom,vol_geom)
+sinogram_id, sinogram = astra.create_sino(P, proj_id,useCUDA=True)
+
+import pylab
+pylab.gray()
+pylab.figure(1)
+pylab.imshow(P)
+pylab.figure(2)
+pylab.imshow(sinogram)
+
+# Create a data object for the reconstruction
+rec_id = astra.data2d.create('-vol', vol_geom)
+
+# create configuration
+cfg = astra.astra_dict('FBP_CUDA')
+cfg['ReconstructionDataId'] = rec_id
+cfg['ProjectionDataId'] = sinogram_id
+cfg['FilterType'] = 'Ram-Lak'
+
+# possible values for FilterType:
+# none, ram-lak, shepp-logan, cosine, hamming, hann, tukey, lanczos,
+# triangular, gaussian, barlett-hann, blackman, nuttall, blackman-harris,
+# blackman-nuttall, flat-top, kaiser, parzen
+
+
+# Create and run the algorithm object from the configuration structure
+alg_id = astra.algorithm.create(cfg)
+astra.algorithm.run(alg_id)
+
+# Get the result
+rec = astra.data2d.get(rec_id)
+pylab.figure(3)
+pylab.imshow(rec)
+pylab.show()
+
+# Clean up. Note that GPU memory is tied up in the algorithm object,
+# and main RAM in the data objects.
+astra.algorithm.delete(alg_id)
+astra.data2d.delete(rec_id)
+astra.data2d.delete(sinogram_id)
+astra.projector.delete(proj_id)
diff --git a/examples/s015_fp_bp.py b/examples/s015_fp_bp.py
new file mode 100644
index 0000000..10c238d
--- /dev/null
+++ b/examples/s015_fp_bp.py
@@ -0,0 +1,86 @@
+#-----------------------------------------------------------------------
+#Copyright 2013 Centrum Wiskunde & Informatica, Amsterdam
+#
+#Author: Daniel M. Pelt
+#Contact: D.M.Pelt@cwi.nl
+#Website: http://dmpelt.github.io/pyastratoolbox/
+#
+#
+#This file is part of the Python interface to the
+#All Scale Tomographic Reconstruction Antwerp Toolbox ("ASTRA Toolbox").
+#
+#The Python interface to the ASTRA Toolbox 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.
+#
+#The Python interface to the ASTRA Toolbox 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 the Python interface to the ASTRA Toolbox. If not, see .
+#
+#-----------------------------------------------------------------------
+
+
+# This example demonstrates using the FP and BP primitives with Matlab's lsqr
+# solver. Calls to FP (astra_create_sino_cuda) and
+# BP (astra_create_backprojection_cuda) are wrapped in a function astra_wrap,
+# and a handle to this function is passed to lsqr.
+
+# Because in this case the inputs/outputs of FP and BP have to be vectors
+# instead of images (matrices), the calls require reshaping to and from vectors.
+
+import astra
+import numpy as np
+
+# FP/BP wrapper class
+class astra_wrap(object):
+ def __init__(self,proj_geom,vol_geom):
+ self.proj_id = astra.create_projector('line',proj_geom,vol_geom)
+ self.shape = (proj_geom['DetectorCount']*len(proj_geom['ProjectionAngles']),vol_geom['GridColCount']*vol_geom['GridRowCount'])
+ self.dtype = np.float
+
+ def matvec(self,v):
+ sid, s = astra.create_sino(np.reshape(v,(vol_geom['GridRowCount'],vol_geom['GridColCount'])),self.proj_id,useCUDA=True)
+ astra.data2d.delete(sid)
+ return s.flatten()
+
+ def rmatvec(self,v):
+ bid, b = astra.create_backprojection(np.reshape(v,(len(proj_geom['ProjectionAngles']),proj_geom['DetectorCount'],)),self.proj_id,useCUDA=True)
+ astra.data2d.delete(bid)
+ return b.flatten()
+
+vol_geom = astra.create_vol_geom(256, 256)
+proj_geom = astra.create_proj_geom('parallel', 1.0, 384, np.linspace(0,np.pi,180,False))
+
+# Create a 256x256 phantom image
+import scipy.io
+P = scipy.io.loadmat('phantom.mat')['phantom256']
+
+# Create a sinogram using the GPU.
+proj_id = astra.create_projector('line',proj_geom,vol_geom)
+sinogram_id, sinogram = astra.create_sino(P, proj_id,useCUDA=True)
+
+# Reshape the sinogram into a vector
+b = sinogram.flatten()
+
+# Call lsqr with ASTRA FP and BP
+import scipy.sparse.linalg
+wrapper = astra_wrap(proj_geom,vol_geom)
+result = scipy.sparse.linalg.lsqr(wrapper,b,atol=1e-4,btol=1e-4,iter_lim=25)
+
+# Reshape the result into an image
+Y = np.reshape(result[0],(vol_geom['GridRowCount'], vol_geom['GridColCount']));
+
+import pylab
+pylab.gray()
+pylab.imshow(Y)
+pylab.show()
+
+astra.data2d.delete(sinogram_id)
+astra.projector.delete(proj_id)
+astra.projector.delete(wrapper.proj_id)
+
diff --git a/examples/s016_plots.py b/examples/s016_plots.py
new file mode 100644
index 0000000..8ded525
--- /dev/null
+++ b/examples/s016_plots.py
@@ -0,0 +1,85 @@
+#-----------------------------------------------------------------------
+#Copyright 2013 Centrum Wiskunde & Informatica, Amsterdam
+#
+#Author: Daniel M. Pelt
+#Contact: D.M.Pelt@cwi.nl
+#Website: http://dmpelt.github.io/pyastratoolbox/
+#
+#
+#This file is part of the Python interface to the
+#All Scale Tomographic Reconstruction Antwerp Toolbox ("ASTRA Toolbox").
+#
+#The Python interface to the ASTRA Toolbox 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.
+#
+#The Python interface to the ASTRA Toolbox 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 the Python interface to the ASTRA Toolbox. If not, see .
+#
+#-----------------------------------------------------------------------
+
+import astra
+import numpy as np
+
+
+vol_geom = astra.create_vol_geom(256, 256)
+proj_geom = astra.create_proj_geom('parallel', 1.0, 384, np.linspace(0,np.pi,180,False))
+
+# As before, create a sinogram from a phantom
+import scipy.io
+P = scipy.io.loadmat('phantom.mat')['phantom256']
+proj_id = astra.create_projector('line',proj_geom,vol_geom)
+sinogram_id, sinogram = astra.create_sino(P, proj_id,useCUDA=True)
+
+import pylab
+pylab.gray()
+pylab.figure(1)
+pylab.imshow(P)
+pylab.figure(2)
+pylab.imshow(sinogram)
+
+# Create a data object for the reconstruction
+rec_id = astra.data2d.create('-vol', vol_geom)
+
+# Set up the parameters for a reconstruction algorithm using the GPU
+cfg = astra.astra_dict('SIRT_CUDA')
+cfg['ReconstructionDataId'] = rec_id
+cfg['ProjectionDataId'] = sinogram_id
+
+# Create the algorithm object from the configuration structure
+alg_id = astra.algorithm.create(cfg)
+
+# Run 1500 iterations of the algorithm one at a time, keeping track of errors
+nIters = 1500
+phantom_error = np.zeros(nIters)
+residual_error = np.zeros(nIters)
+for i in xrange(nIters):
+ # Run a single iteration
+ astra.algorithm.run(alg_id, 1)
+ residual_error[i] = astra.algorithm.get_res_norm(alg_id)
+ rec = astra.data2d.get(rec_id)
+ phantom_error[i] = np.sqrt(((rec - P)**2).sum())
+
+# Get the result
+rec = astra.data2d.get(rec_id)
+pylab.figure(3)
+pylab.imshow(rec)
+
+pylab.figure(4)
+pylab.plot(residual_error)
+pylab.figure(5)
+pylab.plot(phantom_error)
+
+pylab.show()
+
+# Clean up.
+astra.algorithm.delete(alg_id)
+astra.data2d.delete(rec_id)
+astra.data2d.delete(sinogram_id)
+astra.projector.delete(proj_id)
diff --git a/install.sh b/install.sh
new file mode 100755
index 0000000..fd58c1a
--- /dev/null
+++ b/install.sh
@@ -0,0 +1,95 @@
+#! /bin/bash
+
+#-----------------------------------------------------------------------
+#Copyright 2013 Centrum Wiskunde & Informatica, Amsterdam
+#
+#Author: Daniel M. Pelt
+#Contact: D.M.Pelt@cwi.nl
+#Website: http://dmpelt.github.io/pyastratoolbox/
+#
+#
+#This file is part of the Python interface to the
+#All Scale Tomographic Reconstruction Antwerp Toolbox ("ASTRA Toolbox").
+#
+#The Python interface to the ASTRA Toolbox 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.
+#
+#The Python interface to the ASTRA Toolbox 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 the Python interface to the ASTRA Toolbox. If not, see .
+#
+#-----------------------------------------------------------------------
+
+function printHelp {
+ echo "install.sh: Installs Python interface to the ASTRA-toolbox"
+ echo
+ echo "Usage: ./install.sh [-i astra_include_path] [-l astra_library_path] [-p python_executable_path] [-c cuda_path]"
+ echo
+ echo -e "\t-i astra_include_path:\t\tspecify path to astra header files (without trailing astra/) (Optional)"
+ echo -e "\t-l astra_library_path:\t\tspecify parent path of astra library file (Optional)"
+ echo -e "\t-p python_executable_path:\tspecify path to python executable (Optional)"
+ echo -e "\t-c cuda_path:\t\t\tpath to CUDA (Optional)"
+ echo -e "\t-h:\t\t\t\tprint this help (Optional)"
+ exit 1
+}
+
+
+CINFLAGS=""
+LINFLAGS=""
+PEX=python
+while getopts ":i:l:p:c:" opt; do
+ case $opt in
+ h)
+ printHelp
+ ;;
+ i)
+ CINFLAGS="${CINFLAGS} -I${OPTARG}"
+ ;;
+ l)
+ LINFLAGS="${LINFLAGS} -L${OPTARG}"
+ ;;
+ c)
+ LINFLAGS="${LINFLAGS} -DASTRA_CUDA -L${OPTARG}/lib"
+ CINFLAGS="${CINFLAGS} -DASTRA_CUDA -I${OPTARG}/include"
+ ;;
+ p)
+ PEX=${OPTARG}
+ ;;
+ \?)
+ echo "Invalid option: -$OPTARG" >&2
+ printHelp
+ ;;
+ esac
+done
+
+if [ -d build ]
+then
+ echo "Previous build found!"
+ echo "Remove it before rebuilding (recommended)?"
+ pushd build > /dev/null
+ BUILDPATH=`pwd`
+ popd > /dev/null
+ read -p "Remove $BUILDPATH (y/n/q)?" choice
+ case "$choice" in
+ q|Q )
+ exit 1
+ ;;
+ y|Y )
+ rm -r build
+ ;;
+ n|N )
+ ;;
+ * )
+ echo "Invalid choice, quitting..."
+ exit 1
+ ;;
+ esac
+fi
+
+CPPFLAGS=${CINFLAGS} LDFLAGS=${LINFLAGS} $PEX builder.py install
diff --git a/license-header.txt b/license-header.txt
new file mode 100644
index 0000000..e356190
--- /dev/null
+++ b/license-header.txt
@@ -0,0 +1,25 @@
+#-----------------------------------------------------------------------
+#Copyright 2013 Centrum Wiskunde & Informatica, Amsterdam
+#
+#Author: Daniel M. Pelt
+#Contact: D.M.Pelt@cwi.nl
+#Website: http://dmpelt.github.io/pyastratoolbox/
+#
+#
+#This file is part of the Python interface to the
+#All Scale Tomographic Reconstruction Antwerp Toolbox ("ASTRA Toolbox").
+#
+#The Python interface to the ASTRA Toolbox 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.
+#
+#The Python interface to the ASTRA Toolbox 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 the Python interface to the ASTRA Toolbox. If not, see .
+#
+#-----------------------------------------------------------------------